From len.baker at gmx.com  Sun Aug  1 01:47:31 2021
From: len.baker at gmx.com (Len Baker)
Date: Sun, 1 Aug 2021 10:47:31 +0200
Subject: [PATCH v2] drivers/soc: Remove all strcpy() uses
In-Reply-To: <20210731171825.12865-1-len.baker@gmx.com>
References: <20210731171825.12865-1-len.baker@gmx.com>
Message-ID: <20210801084731.GA2588@titan>

On Sat, Jul 31, 2021 at 07:18:25PM +0200, Len Baker wrote:
> strcpy() performs no bounds checking on the destination buffer. This
> could result in linear overflows beyond the end of the buffer, leading
> to all kinds of misbehaviors. The safe replacement is strscpy().
>
> Moreover, when the size of the destination buffer cannot be obtained
> using "sizeof", use the memcpy function instead of strscpy.
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
> Signed-off-by: Len Baker <len.baker at gmx.com>

Drop this patch. It has errors. Sorry for the noise.

Apologies,
Len


From bert at biot.com  Sun Aug  1 02:07:48 2021
From: bert at biot.com (Bert Vermeulen)
Date: Sun, 1 Aug 2021 11:07:48 +0200
Subject: [PATCH 3/5] ARM: dts: Add basic support for EcoNet EN7523
In-Reply-To: <87y29n26po.wl-maz@kernel.org>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-4-bert@biot.com>
 <CACRpkdYvMtE8b-Xiy6=Aiz20jvY0M0Bz9XmcEQDHhqeS+LErEA@mail.gmail.com>
 <87y29n26po.wl-maz@kernel.org>
Message-ID: <0fe113c6-4160-fd3c-488d-53d40b6043ee@biot.com>

On 7/30/21 4:53 PM, Marc Zyngier wrote:
> On Fri, 30 Jul 2021 15:31:36 +0100,
> Linus Walleij <linus.walleij at linaro.org> wrote:
>> 
>> Paging Marc Z and Catalin just so they can see this:
>> 
>> On Fri, Jul 30, 2021 at 3:49 PM Bert Vermeulen <bert at biot.com> wrote:
>> 
>> > From: John Crispin <john at phrozen.org>
>> >
>> > Add basic support for EcoNet EN7523, enough for booting to console.
>> >
>> > The UART is basically 8250-compatible, except for the clock selection.
>> > A clock-frequency value is synthesized to get this to run at 115200 bps.
>> >
>> > Signed-off-by: John Crispin <john at phrozen.org>
>> > Signed-off-by: Bert Vermeulen <bert at biot.com>
>> (...)
>> > +       gic: interrupt-controller at 09000000 {
>> > +               compatible = "arm,gic-v3";
>> > +               interrupt-controller;
>> > +               #interrupt-cells = <3>;
>> > +               #address-cells = <1>;
>> > +               #size-cells = <1>;
>> > +               reg = <0x09000000 0x20000>,
>> > +                         <0x09080000 0x80000>;
>> > +               interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
>> > +
>> > +               its: gic-its at 09020000 {
>> > +                       compatible = "arm,gic-v3-its";
>> > +                       msi-controller;
>> > +                       #msi-cell = <1>;
>> > +                       reg = <0x090200000 0x20000>;
>> > +               };
>> > +       };
>> 
>> Yup GICv3 on ARM32-only silicon.
> 
> Hey, why not. But that's very unlikely, as Cortex-A7 doesn't have a
> GICv3 CPU interface built in (it only has the memory mapped version),
> and A53/57 were the first CPUs to ever support GICv3. I don't believe
> the description of the CPU in the DT is accurate.
> 
> Bert, please send a kernel boot log.

At the bottom of this mail.

>> > +       timer {
>> > +               compatible = "arm,armv8-timer";
>> > +               interrupt-parent = <&gic>;
>> > +               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> > +                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> > +                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> > +                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> 
> Copy paste bug. These are not valid intspecs for GICv3.

FWIW all these were taken verbatim from the vendor's SDK. Not that this 
makes them necessarily correct :)

>> > +               clock-frequency = <25000000>;
>> > +       };
>> 
>> Also arm,armv8-timer on ARM32-only silicon.
> 
> Probably because that's not what it actually is. My bet is on A53 with
> a crippled firmware.

kernel boot log:

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.14.0-rc3-00042-g3af70c6f8e95-dirty 
(bert at sumner) (arm-linux-gnueabi-gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0, 
GNU ld (GNU Binutils for Ubuntu) 2.34) #392 SMP Sun Aug 1 10:28:13 CEST 2021
[    0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing 
instruction cache
[    0.000000] OF: fdt: Machine model: econet,en7523
[    0.000000] earlycon: uart8250 at MMIO32 0x1fbf0000 (options '')
[    0.000000] printk: bootconsole [uart8250] enabled
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000080000000-0x000000009fffffff]
[    0.000000]   HighMem  empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080000000-0x0000000083ffffff]
[    0.000000]   node   0: [mem 0x0000000084000000-0x00000000849fffff]
[    0.000000]   node   0: [mem 0x0000000084a00000-0x0000000084afffff]
[    0.000000]   node   0: [mem 0x0000000084b00000-0x0000000084bfffff]
[    0.000000]   node   0: [mem 0x0000000084c00000-0x0000000084ffffff]
[    0.000000]   node   0: [mem 0x0000000085000000-0x00000000869fffff]
[    0.000000]   node   0: [mem 0x0000000086a00000-0x0000000086afffff]
[    0.000000]   node   0: [mem 0x0000000086b00000-0x0000000086bfffff]
[    0.000000]   node   0: [mem 0x0000000086c00000-0x0000000086cfffff]
[    0.000000]   node   0: [mem 0x0000000086d00000-0x0000000086dfffff]
[    0.000000]   node   0: [mem 0x0000000086e00000-0x000000009fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
[    0.000000] percpu: Embedded 15 pages/cpu s30604 r8192 d22644 u61440
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 129920
[    0.000000] Kernel command line: earlycon=uart8250,mmio32,0x1fbf0000 
console=ttyS0,115200
[    0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 
bytes, linear)
[    0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 
bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 461316K/524288K available (7168K kernel code, 312K 
rwdata, 1488K rodata, 8192K init, 142K bss, 62972K reserved, 0K 
cma-reserved, 0K highmem)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 
jiffies.
[    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[    0.000000] GICv3: 256 SPIs implemented
[    0.000000] GICv3: 0 Extended SPIs implemented
[    0.000000] GICv3: Distributor has no Range Selector support
[    0.000000] GICv3: 16 PPIs implemented
[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x09080000
[    0.000000] random: get_random_bytes called from start_kernel+0x484/0x628 
with crng_init=0
[    0.000000] arch_timer: cp15 timer(s) running at 25.00MHz (virt).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff 
max_cycles: 0x5c40939b5, max_idle_ns: 440795202646 ns
[    0.000000] sched_clock: 56 bits at 25MHz, resolution 40ns, wraps every 
4398046511100ns
[    0.008791] Switching to timer-based delay loop, resolution 40ns
[    0.015454] Calibrating delay loop (skipped), value calculated using 
timer frequency.. 50.00 BogoMIPS (lpj=250000)
[    0.026833] pid_max: default: 32768 minimum: 301
[    0.032013] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, 
linear)
[    0.040047] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 
bytes, linear)
[    0.049172] CPU: Testing write buffer coherency: ok
[    0.054780] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.061362] Setting up static identity map for 0x80100000 - 0x80100060
[    0.068667] rcu: Hierarchical SRCU implementation.
[    0.074290] gic-its at 09020000: unable to locate ITS domain
[    0.080461] smp: Bringing up secondary CPUs ...
[    0.085769] smp: Brought up 1 node, 1 CPU
[    0.090179] SMP: Total of 1 processors activated (50.00 BogoMIPS).
[    0.097013] CPU: All CPU(s) started in SVC mode.
[    0.103634] clocksource: jiffies: mask: 0xffffffff max_cycles: 
0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.114499] futex hash table entries: 512 (order: 3, 32768 bytes, linear)
[    0.122380] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.129153] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.137265] thermal_sys: Registered thermal governor 'step_wise'
[    0.137333] No ATAGs?
[    0.153205] iommu: Default domain type: Translated
[    0.158713] usbcore: registered new interface driver usbfs
[    0.164769] usbcore: registered new interface driver hub
[    0.170660] usbcore: registered new device driver usb
[    0.176704] NET: Registered PF_ATMPVC protocol family
[    0.182296] NET: Registered PF_ATMSVC protocol family
[    0.188055] clocksource: Switched to clocksource arch_sys_counter
[    0.195462] NET: Registered PF_INET protocol family
[    0.200971] IP idents hash table entries: 8192 (order: 4, 65536 bytes, 
linear)
[    0.209452] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 
6144 bytes, linear)
[    0.218713] TCP established hash table entries: 4096 (order: 2, 16384 
bytes, linear)
[    0.227251] TCP bind hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.235158] TCP: Hash tables configured (established 4096 bind 4096)
[    0.242212] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[    0.249416] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[    0.257205] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    0.263464] PCI: CLS 0 bytes, default 64
[    0.348846] workingset: timestamp_bits=14 max_order=17 bucket_order=3
[    0.360684] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.367197] ntfs: driver 2.1.32 [Flags: R/W DEBUG].
[    0.372785] jffs2: version 2.2. (NAND) ? 2001-2006 Red Hat, Inc.
[    0.598557] io scheduler mq-deadline registered
[    0.603555] io scheduler kyber registered
[    0.619475] Serial: 8250/16550 driver, 2 ports, IRQ sharing enabled
[    0.626838] printk: console [ttyS0] disabled
[    0.631671] 1fbf0000.serial: ttyS0 at MMIO 0x1fbf0000 (irq = 28, 
base_baud = 115200) is a 8250
[    0.641169] printk: console [ttyS0] enabled
[    0.641169] printk: console [ttyS0] enabled
[    0.649943] printk: bootconsole [uart8250] disabled
[    0.649943] printk: bootconsole [uart8250] disabled
[    0.706413] brd: module loaded
[    0.709758] PPP generic driver version 2.4.2
[    0.714097] PPP BSD Compression module registered
[    0.718832] PPP Deflate Compression module registered
[    0.723877] NET: Registered PF_PPPOX protocol family
[    0.728989] usbcore: registered new interface driver cdc_acm
[    0.734648] cdc_acm: USB Abstract Control Model driver for USB modems and 
ISDN adapters
[    0.742712] usbcore: registered new interface driver usbserial_generic
[    0.749278] usbserial: USB Serial support registered for generic
[    0.755299] usbcore: registered new interface driver cypress_m8
[    0.761234] usbserial: USB Serial support registered for DeLorme 
Earthmate USB
[    0.768476] usbserial: USB Serial support registered for HID->COM RS232 
Adapter
[    0.775790] usbserial: USB Serial support registered for Nokia CA-42 V2 
Adapter
[    0.783121] usbcore: registered new interface driver ftdi_sio
[    0.788889] usbserial: USB Serial support registered for FTDI USB Serial 
Device
[    0.796272] hid: raw HID events driver (C) Jiri Kosina
[    0.801492] usbcore: registered new interface driver usbhid
[    0.807061] usbhid: USB HID core driver
[    0.811617] IPv4 over IPsec tunneling driver
[    0.816458] ipt_CLUSTERIP: ClusterIP Version 0.8 loaded successfully
[    0.822866] Initializing XFRM netlink socket
[    0.827522] NET: Registered PF_INET6 protocol family
[    0.955712] Segment Routing with IPv6
[    0.959637] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    0.966526] NET: Registered PF_PACKET protocol family
[    0.971663] NET: Registered PF_KEY protocol family
[    0.976464] 8021q: 802.1Q VLAN Support v1.8
[    0.980675] lib80211: common routines for IEEE802.11 drivers
[    0.986398] Registering SWP/SWPB emulation handler
[    0.999840] Freeing unused kernel image (initmem) memory: 8192K
[    1.006133] Run /init as init process



-- 
Bert Vermeulen
bert at biot.com


From maz at kernel.org  Sun Aug  1 02:31:18 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Aug 2021 10:31:18 +0100
Subject: [PATCH v3 1/2] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <20210726231848.GA1025245@robh.at.kernel.org>
References: <20210726083204.93196-1-mark.kettenis@xs4all.nl>
 <20210726083204.93196-2-mark.kettenis@xs4all.nl>
 <20210726231848.GA1025245@robh.at.kernel.org>
Message-ID: <87sfzt1pg9.wl-maz@kernel.org>

On Tue, 27 Jul 2021 00:18:48 +0100,
Rob Herring <robh at kernel.org> wrote:
> 
> On Mon, Jul 26, 2021 at 10:32:00AM +0200, Mark Kettenis wrote:
> > From: Mark Kettenis <kettenis at openbsd.org>
> > 
> > The Apple PCIe host controller is a PCIe host controller with
> > multiple root ports present in Apple ARM SoC platforms, including
> > various iPhone and iPad devices and the "Apple Silicon" Macs.
> > 
> > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > ---
> >  .../devicetree/bindings/pci/apple,pcie.yaml   | 166 ++++++++++++++++++
> >  MAINTAINERS                                   |   1 +
> >  2 files changed, 167 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > new file mode 100644
> > index 000000000000..bfcbdee79c64
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > @@ -0,0 +1,166 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Apple PCIe host controller
> > +
> > +maintainers:
> > +  - Mark Kettenis <kettenis at openbsd.org>
> > +
> > +description: |
> > +  The Apple PCIe host controller is a PCIe host controller with
> > +  multiple root ports present in Apple ARM SoC platforms, including
> > +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> > +  The controller incorporates Synopsys DesigWare PCIe logic to
> > +  implements its root ports.  But the ATU found on most DesignWare
> > +  PCIe host bridges is absent.
> 
> blank line
> 
> > +  All root ports share a single ECAM space, but separate GPIOs are
> > +  used to take the PCI devices on those ports out of reset.  Therefore
> > +  the standard "reset-gpio" and "max-link-speed" properties appear on
> 
> reset-gpios
> 
> > +  the child nodes that represent the PCI bridges that correspond to
> > +  the individual root ports.
> 
> blank line
> 
> > +  MSIs are handled by the PCIe controller and translated into regular
> > +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> > +  distributed over the root ports as the OS sees fit by programming
> > +  the PCIe controller's port registers.
> > +
> > +allOf:
> > +  - $ref: /schemas/pci/pci-bus.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - const: apple,t8103-pcie
> > +      - const: apple,pcie
> > +
> > +  reg:
> > +    minItems: 3
> > +    maxItems: 5
> > +
> > +  reg-names:
> > +    minItems: 3
> > +    maxItems: 5
> > +    items:
> > +      - const: config
> > +      - const: rc
> > +      - const: port0
> > +      - const: port1
> > +      - const: port2
> > +
> > +  ranges:
> > +    minItems: 2
> > +    maxItems: 2
> > +
> > +  interrupts:
> > +    description:
> > +      Interrupt specifiers, one for each root port.
> > +    minItems: 1
> > +    maxItems: 3
> > +
> > +  msi-controller: true
> > +  msi-parent: true
> > +
> > +  msi-ranges:
> > +    description:
> > +      A list of pairs <intid span>, where "intid" is the first
> > +      interrupt number that can be used as an MSI, and "span" the size
> > +      of that range.
> > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > +    items:
> > +      minItems: 2
> > +      maxItems: 2
> 
> I still have issues I raised on v1 with this property. It's genericish 
> looking, but not generic. 'intid' as a single cell can't specify any 
> parent interrupt such as a GIC which uses 3 cells. You could put in all 
> the cells, but you'd still be assuming which cell you can increment.

The GIC bindings already use similar abstractions, see what we do for
both GICv2m and GICv3 MBIs. Other MSI controllers use similar
properties (alpine and loongson, for example).

> I think you should just list all these under 'interrupts' using 
> interrupt-names to make your life easier:
> 
> interrupt-names:
>   items:
>     - const: port0
>     - const: port1
>     - const: port2
>     - const: msi0
>     - const: msi1
>     - const: msi2
>     - const: msi3
>     ...
> 
> Yeah, it's kind of verbose, but if the h/w block handles N interrupts, 
> you should list N interrupts. The worst case for the above is N entries 
> too if not contiguous.

And that's where I beg to differ, again.

Specifying interrupts like this gives the false impression that these
interrupts are generated by the device that owns them (the RC). Which
for MSIs is not the case. This is not only verbose, this is
semantically dubious. And what should we do when the number of
possible interrupt is ridiculously large, as it is for the GICv3 ITS?

I wish we had a standard way to express these constraints. Until we
do, I don't think enumerating individual interrupts is a practical
thing to do, nor that it actually represents the topology of the
system.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From arnd at arndb.de  Sun Aug  1 02:40:53 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Sun, 1 Aug 2021 11:40:53 +0200
Subject: [PATCH 3/5] ARM: dts: Add basic support for EcoNet EN7523
In-Reply-To: <0fe113c6-4160-fd3c-488d-53d40b6043ee@biot.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-4-bert@biot.com>
 <CACRpkdYvMtE8b-Xiy6=Aiz20jvY0M0Bz9XmcEQDHhqeS+LErEA@mail.gmail.com>
 <87y29n26po.wl-maz@kernel.org> <0fe113c6-4160-fd3c-488d-53d40b6043ee@biot.com>
Message-ID: <CAK8P3a3HrzAYtCnLuThO=9LuwyF8KduNjx-ZrJkXG=Y-i6RNbw@mail.gmail.com>

On Sun, Aug 1, 2021 at 11:07 AM Bert Vermeulen <bert at biot.com> wrote:
> On 7/30/21 4:53 PM, Marc Zyngier wrote: On Fri, 30 Jul 2021 15:31:36 +0100,
> > Probably because that's not what it actually is. My bet is on A53 with
> > a crippled firmware.
>
> [    0.000000] Booting Linux on physical CPU 0x0
> [    0.000000] Linux version 5.14.0-rc3-00042-g3af70c6f8e95-dirty
> (bert at sumner) (arm-linux-gnueabi-gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0,
> GNU ld (GNU Binutils for Ubuntu) 2.34) #392 SMP Sun Aug 1 10:28:13 CEST 2021
> [    0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d
> [    0.000000] CPU: div instructions available: patching division code
> [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache

Good guess! CPUID 410fd034 is a Cortex-53 (d03) indeed. I wish we
would just print
cleartext names for the CPUs that the kernel already knows about here, I think
the fact that we just print 'ARMv7 processor' (which is wrong) and
spell out the revision
but not implementer/part/variant numbers is rather silly.

Is there a way in the boot loader to boot up a 64-bit kernel?

       Arnd


From fengzheng923 at gmail.com  Sun Aug  1 02:47:46 2021
From: fengzheng923 at gmail.com (=?UTF-8?B?54+t5rab?=)
Date: Sun, 1 Aug 2021 17:47:46 +0800
Subject: [PATCH v6 1/2] ASoC: sunxi: Add Allwinner H6 Digital MIC driver
In-Reply-To: <20210715074750.ewbggulc5kast6ez@gilmour>
References: <20210711122055.4529-1-fengzheng923@gmail.com>
 <20210715074750.ewbggulc5kast6ez@gilmour>
Message-ID: <CAE=m61_=XfhtG9Q1r34McWWCUXt1KP67cjZ0ER62+YaGrG+b4w@mail.gmail.com>

Hi, Dear:


Maxime Ripard <maxime at cerno.tech> ?2021?7?15??? ??3:47???

>
> Hi
>
> On Sun, Jul 11, 2021 at 08:20:55AM -0400, fengzheng923 at gmail.com wrote:
> > From: Ban Tao <fengzheng923 at gmail.com>
> >
> > The Allwinner H6 and later SoCs have an DMIC block
> > which is capable of capture.
> >
> > Signed-off-by: Ban Tao <fengzheng923 at gmail.com>
> >
> > ---
> > v1->v2:
> > 1.Fix some compilation errors.
> > 2.Modify some code styles.
> > ---
> > v2->v3:
> > None.
> > ---
> > v3->v4:
> > 1.add sig_bits.
> > ---
> > v4->v5:
> > None.
> > ---
> > v5->v6:
> > 1.Modify RXFIFO_CTL_MODE to mode 1.
> > ---
> >  MAINTAINERS                   |   7 +
> >  sound/soc/sunxi/Kconfig       |   8 +
> >  sound/soc/sunxi/Makefile      |   1 +
> >  sound/soc/sunxi/sun50i-dmic.c | 403 ++++++++++++++++++++++++++++++++++
> >  4 files changed, 419 insertions(+)
> >  create mode 100644 sound/soc/sunxi/sun50i-dmic.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index e924f9e5df97..8d700baaa3ca 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -760,6 +760,13 @@ L:       linux-media at vger.kernel.org
> >  S:   Maintained
> >  F:   drivers/staging/media/sunxi/cedrus/
> >
> > +ALLWINNER DMIC DRIVERS
> > +M:   Ban Tao <fengzheng923 at gmail.com>
> > +L:   alsa-devel at alsa-project.org (moderated for non-subscribers)
> > +S:   Maintained
> > +F:   Documentation/devicetree/bindings/sound/allwinner,sun50i-h6-dmic.yaml
> > +F:   sound/soc/sunxi/sun50i-dmic.c
> > +
> >  ALPHA PORT
> >  M:   Richard Henderson <rth at twiddle.net>
> >  M:   Ivan Kokshaysky <ink at jurassic.park.msu.ru>
> > diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> > index ddcaaa98d3cb..2a3bf7722e11 100644
> > --- a/sound/soc/sunxi/Kconfig
> > +++ b/sound/soc/sunxi/Kconfig
> > @@ -56,6 +56,14 @@ config SND_SUN4I_SPDIF
> >         Say Y or M to add support for the S/PDIF audio block in the Allwinner
> >         A10 and affiliated SoCs.
> >
> > +config SND_SUN50I_DMIC
> > +     tristate "Allwinner H6 DMIC Support"
> > +     depends on (OF && ARCH_SUNXI) || COMPILE_TEST
> > +     select SND_SOC_GENERIC_DMAENGINE_PCM
> > +     help
> > +       Say Y or M to add support for the DMIC audio block in the Allwinner
> > +       H6 and affiliated SoCs.
> > +
> >  config SND_SUN8I_ADDA_PR_REGMAP
> >       tristate
> >       select REGMAP
> > diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> > index a86be340a076..4483fe9c94ef 100644
> > --- a/sound/soc/sunxi/Makefile
> > +++ b/sound/soc/sunxi/Makefile
> > @@ -6,3 +6,4 @@ obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> >  obj-$(CONFIG_SND_SUN50I_CODEC_ANALOG) += sun50i-codec-analog.o
> >  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
> >  obj-$(CONFIG_SND_SUN8I_ADDA_PR_REGMAP) += sun8i-adda-pr-regmap.o
> > +obj-$(CONFIG_SND_SUN50I_DMIC) += sun50i-dmic.o
> > diff --git a/sound/soc/sunxi/sun50i-dmic.c b/sound/soc/sunxi/sun50i-dmic.c
> > new file mode 100644
> > index 000000000000..bbac836ba4de
> > --- /dev/null
> > +++ b/sound/soc/sunxi/sun50i-dmic.c
> > @@ -0,0 +1,403 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +//
> > +// This driver supports the DMIC in Allwinner's H6 SoCs.
> > +//
> > +// Copyright 2021 Ban Tao <fengzheng923 at gmail.com>
> > +
> > +#include <linux/clk.h>
> > +#include <linux/device.h>
> > +#include <linux/of_device.h>
> > +#include <linux/module.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/reset.h>
> > +#include <sound/dmaengine_pcm.h>
> > +#include <sound/pcm_params.h>
> > +#include <sound/soc.h>
> > +
> > +#define SUN50I_DMIC_EN_CTL           (0x00)
> > +     #define SUN50I_DMIC_EN_CTL_GLOBE                        BIT(8)
> > +     #define SUN50I_DMIC_EN_CTL_CHAN(v)              ((v) << 0)
> > +     #define SUN50I_DMIC_EN_CTL_CHAN_MASK            GENMASK(7, 0)
> > +#define SUN50I_DMIC_SR                       (0x04)
> > +     #define SUN50I_DMIC_SR_SAMPLE_RATE(v)           ((v) << 0)
> > +     #define SUN50I_DMIC_SR_SAMPLE_RATE_MASK         GENMASK(2, 0)
> > +#define SUN50I_DMIC_CTL                      (0x08)
> > +     #define SUN50I_DMIC_CTL_OVERSAMPLE_RATE         BIT(0)
> > +#define SUN50I_DMIC_DATA                     (0x10)
> > +#define SUN50I_DMIC_INTC                     (0x14)
> > +     #define SUN50I_DMIC_FIFO_DRQ_EN                 BIT(2)
> > +#define SUN50I_DMIC_INT_STA          (0x18)
> > +     #define SUN50I_DMIC_INT_STA_OVERRUN_IRQ_PENDING BIT(1)
> > +     #define SUN50I_DMIC_INT_STA_DATA_IRQ_PENDING    BIT(0)
> > +#define SUN50I_DMIC_RXFIFO_CTL               (0x1c)
> > +     #define SUN50I_DMIC_RXFIFO_CTL_FLUSH            BIT(31)
> > +     #define SUN50I_DMIC_RXFIFO_CTL_MODE             BIT(9)
> > +     #define SUN50I_DMIC_RXFIFO_CTL_RESOLUTION       BIT(8)
> > +#define SUN50I_DMIC_CH_NUM           (0x24)
> > +     #define SUN50I_DMIC_CH_NUM_N(v)                 ((v) << 0)
> > +     #define SUN50I_DMIC_CH_NUM_N_MASK               GENMASK(2, 0)
> > +#define SUN50I_DMIC_CNT                      (0x2c)
> > +     #define SUN50I_DMIC_CNT_N                       BIT(0)
> > +#define SUN50I_DMIC_HPF_CTRL         (0x38)
> > +#define SUN50I_DMIC_VERSION          (0x50)
> > +
> > +
>
> There's multiple blank lines here
>
> > +struct sun50i_dmic_dev {
> > +     struct clk *dmic_clk;
> > +     struct clk *bus_clk;
> > +     struct reset_control *rst;
> > +     struct regmap *regmap;
> > +     struct snd_dmaengine_dai_dma_data dma_params_rx;
> > +     unsigned int chan_en;
> > +};
> > +
> > +struct dmic_rate {
> > +     unsigned int samplerate;
> > +     unsigned int rate_bit;
> > +};
> > +
> > +static int sun50i_dmic_startup(struct snd_pcm_substream *substream,
> > +                            struct snd_soc_dai *cpu_dai)
> > +{
> > +     struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > +     struct sun50i_dmic_dev *host = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
> > +
> > +     /* only support capture */
> > +     if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
> > +             return -EINVAL;
> > +
> > +     regmap_update_bits(host->regmap, SUN50I_DMIC_RXFIFO_CTL,
> > +                        SUN50I_DMIC_RXFIFO_CTL_FLUSH,
> > +                        SUN50I_DMIC_RXFIFO_CTL_FLUSH);
> > +     regmap_write(host->regmap, SUN50I_DMIC_CNT, SUN50I_DMIC_CNT_N);
> > +
> > +     return 0;
> > +}
> > +
> > +static int sun50i_dmic_hw_params(struct snd_pcm_substream *substream,
> > +                              struct snd_pcm_hw_params *params,
> > +                              struct snd_soc_dai *cpu_dai)
> > +{
> > +     int i = 0;
> > +     unsigned long rate = params_rate(params);
> > +     unsigned int mclk = 0;
> > +     unsigned int channels = params_channels(params);
> > +     struct sun50i_dmic_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
> > +     static struct dmic_rate dmic_rate_s[] = {
> > +             {44100, 0x0},
> > +             {48000, 0x0},
> > +             {22050, 0x2},
> > +             {24000, 0x2},
> > +             {11025, 0x4},
> > +             {12000, 0x4},
> > +             {32000, 0x1},
> > +             {16000, 0x3},
> > +             {8000,  0x5},
> > +     };
>
> We should order these items. It looks like descending rate makes the
> most sense?
>
> Also, I'm not sure why we need to make that array local, can't this be a
> global variable?
>
> > +     /* DMIC num is N+1 */
> > +     regmap_update_bits(host->regmap, SUN50I_DMIC_CH_NUM,
> > +                        SUN50I_DMIC_CH_NUM_N_MASK,
> > +                        SUN50I_DMIC_CH_NUM_N(channels - 1));
> > +     host->chan_en = (1 << channels) - 1;
> > +     regmap_write(host->regmap, SUN50I_DMIC_HPF_CTRL, host->chan_en);
>
> Do we need to store the channels bitmask in the main structure? It looks
> fairly easy to generate, so I guess we could just use a macro

I need to store channels bitmask and use it in sun50i_dmic_trigger function.

>
> > +     switch (params_format(params)) {
> > +     case SNDRV_PCM_FORMAT_S16_LE:
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_RXFIFO_CTL,
> > +                                SUN50I_DMIC_RXFIFO_CTL_RESOLUTION, 0);
> > +             break;
> > +     case SNDRV_PCM_FORMAT_S24_LE:
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_RXFIFO_CTL,
> > +                                SUN50I_DMIC_RXFIFO_CTL_RESOLUTION,
> > +                                SUN50I_DMIC_RXFIFO_CTL_RESOLUTION);
> > +             break;
>
> These two defines could be named a bit better, it's not really clear
> what SUN50I_DMIC_RXFIFO_CTL_RESOLUTION means, exactly, as opposed to 0
> (while it's actually the sample width).
>
> What about something like SUN50I_DMIC_RXFIFO_CTL_SAMPLE_16 (for 0) and
> _24 (for 1), while changing SUN50I_DMIC_RXFIFO_CTL_RESOLUTION for
> SUN50I_DMIC_RXFIFO_CTL_SAMPLE_MASK ?
>
> > +     default:
> > +             dev_err(cpu_dai->dev, "Invalid format!\n");
> > +             return -EINVAL;
> > +     }
> > +     regmap_update_bits(host->regmap, SUN50I_DMIC_RXFIFO_CTL,
> > +                        SUN50I_DMIC_RXFIFO_CTL_MODE,
> > +                        SUN50I_DMIC_RXFIFO_CTL_MODE);
>
> Same thing here, MODE doesn't really explain what this does, and why
> we'd want to always set it.
>
> I guess 0 is LSB_ZERO and 1 is MSB_SIGN?

Yes.

>
> > +     switch (rate) {
> > +     case 11025:
> > +     case 22050:
> > +     case 44100:
> > +             mclk = 22579200;
> > +             break;
> > +     case 8000:
> > +     case 12000:
> > +     case 16000:
> > +     case 24000:
> > +     case 32000:
> > +     case 48000:
> > +             mclk = 24576000;
> > +             break;
> > +     default:
> > +             dev_err(cpu_dai->dev, "Invalid rate!\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     if (clk_set_rate(host->dmic_clk, mclk)) {
> > +             dev_err(cpu_dai->dev, "mclk : %u not support\n", mclk);
> > +             return -EINVAL;
> > +     }
> > +
> > +     for (i = 0; i < ARRAY_SIZE(dmic_rate_s); i++) {
> > +             if (dmic_rate_s[i].samplerate == rate) {
> > +                     regmap_update_bits(host->regmap, SUN50I_DMIC_SR,
> > +                                        SUN50I_DMIC_SR_SAMPLE_RATE_MASK,
> > +                                        SUN50I_DMIC_SR_SAMPLE_RATE(dmic_rate_s[i].rate_bit));
> > +                     break;
> > +             }
> > +     }
> > +
> > +     switch (params_physical_width(params)) {
> > +     case 16:
> > +             host->dma_params_rx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
> > +             break;
> > +     case 32:
> > +             host->dma_params_rx.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> > +             break;
> > +     default:
> > +             dev_err(cpu_dai->dev, "Unsupported physical sample width: %d\n",
> > +                     params_physical_width(params));
> > +             return -EINVAL;
> > +     }
> > +
> > +     /* oversamplerate adjust */
> > +     if (params_rate(params) >= 24000)
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_CTL,
> > +                                SUN50I_DMIC_CTL_OVERSAMPLE_RATE,
> > +                                SUN50I_DMIC_CTL_OVERSAMPLE_RATE);
> > +     else
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_CTL,
> > +                                SUN50I_DMIC_CTL_OVERSAMPLE_RATE, 0);
> > +
> > +     return 0;
> > +}
> > +
> > +static int sun50i_dmic_trigger(struct snd_pcm_substream *substream, int cmd,
> > +                            struct snd_soc_dai *dai)
> > +{
> > +     int ret = 0;
> > +     struct sun50i_dmic_dev *host = snd_soc_dai_get_drvdata(dai);
> > +
> > +     if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
> > +             return -EINVAL;
> > +
> > +     switch (cmd) {
> > +     case SNDRV_PCM_TRIGGER_START:
> > +     case SNDRV_PCM_TRIGGER_RESUME:
> > +     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> > +             /* DRQ ENABLE */
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_INTC,
> > +                                SUN50I_DMIC_FIFO_DRQ_EN,
> > +                                SUN50I_DMIC_FIFO_DRQ_EN);
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_EN_CTL,
> > +                                SUN50I_DMIC_EN_CTL_CHAN_MASK,
> > +                                SUN50I_DMIC_EN_CTL_CHAN(host->chan_en));
> > +             /* Global enable */
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_EN_CTL,
> > +                                SUN50I_DMIC_EN_CTL_GLOBE,
> > +                                SUN50I_DMIC_EN_CTL_GLOBE);
> > +             break;
>
> Do we really need to clear the channel and global enable bits? and DRQ?

Why not? I think we should clear them when not in use......

>
> > +     case SNDRV_PCM_TRIGGER_STOP:
> > +     case SNDRV_PCM_TRIGGER_SUSPEND:
> > +     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> > +             /* DRQ DISABLE */
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_INTC,
> > +                                SUN50I_DMIC_FIFO_DRQ_EN, 0);
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_EN_CTL,
> > +                                SUN50I_DMIC_EN_CTL_CHAN_MASK,
> > +                                SUN50I_DMIC_EN_CTL_CHAN(0));
> > +             /* Global disable */
> > +             regmap_update_bits(host->regmap, SUN50I_DMIC_EN_CTL,
> > +                                SUN50I_DMIC_EN_CTL_GLOBE, 0);
> > +             break;
> > +
> > +     default:
> > +             ret = -EINVAL;
> > +             break;
> > +     }
> > +     return ret;
> > +}
> > +
> > +static int sun50i_dmic_soc_dai_probe(struct snd_soc_dai *dai)
> > +{
> > +     struct sun50i_dmic_dev *host = snd_soc_dai_get_drvdata(dai);
> > +
> > +     snd_soc_dai_init_dma_data(dai, NULL, &host->dma_params_rx);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct snd_soc_dai_ops sun50i_dmic_dai_ops = {
> > +     .startup        = sun50i_dmic_startup,
> > +     .trigger        = sun50i_dmic_trigger,
> > +     .hw_params      = sun50i_dmic_hw_params,
> > +};
> > +
> > +static const struct regmap_config sun50i_dmic_regmap_config = {
> > +     .reg_bits = 32,
> > +     .reg_stride = 4,
> > +     .val_bits = 32,
> > +     .max_register = SUN50I_DMIC_VERSION,
> > +     .cache_type = REGCACHE_NONE,
> > +};
> > +
> > +#define      SUN50I_DMIC_RATES (SNDRV_PCM_RATE_8000_48000)
> > +#define SUN50I_FORMATS       (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
>
> SUN50I_DMIC_RATES has a tab between the define and its name, while
> SUN50I_FORMATS has the tab after the name. We should be consistent.
> Similarly, we should name both with the SUN50I_DMIC prefix.
>
> > +static struct snd_soc_dai_driver sun50i_dmic_dai = {
> > +     .capture = {
> > +             .channels_min = 1,
> > +             .channels_max = 8,
> > +             .rates = SUN50I_DMIC_RATES,
> > +             .formats = SUN50I_FORMATS,
> > +             .sig_bits = 21,
> > +     },
> > +     .probe = sun50i_dmic_soc_dai_probe,
> > +     .ops = &sun50i_dmic_dai_ops,
> > +     .name = "dmic",
> > +};
> > +
> > +static const struct of_device_id sun50i_dmic_of_match[] = {
> > +     {
> > +             .compatible = "allwinner,sun50i-h6-dmic",
> > +     },
> > +     { /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, sun50i_dmic_of_match);
> > +
> > +static const struct snd_soc_component_driver sun50i_dmic_component = {
> > +     .name           = "sun50i-dmic",
> > +};
> > +
> > +static int sun50i_dmic_runtime_suspend(struct device *dev)
> > +{
> > +     struct sun50i_dmic_dev *host  = dev_get_drvdata(dev);
> > +
> > +     clk_disable_unprepare(host->dmic_clk);
> > +     clk_disable_unprepare(host->bus_clk);
> > +
> > +     return 0;
> > +}
> > +
> > +static int sun50i_dmic_runtime_resume(struct device *dev)
> > +{
> > +     struct sun50i_dmic_dev *host  = dev_get_drvdata(dev);
> > +     int ret;
> > +
> > +     ret = clk_prepare_enable(host->dmic_clk);
> > +     if (ret)
> > +             return ret;
>
> A new line here would be great.
>
> > +     ret = clk_prepare_enable(host->bus_clk);
> > +     if (ret)
> > +             clk_disable_unprepare(host->dmic_clk);
> > +
> > +     return ret;
>
> In general we prefer to treat the error path and the success path
> differently. In this case it would mean changing that part to
>
> ret = clk_prepare_enable(host->bus_clk);
> if (ret) {
>          clk_disable_unprepare(host->dmic_clk);
>          return ret;
> }
>
> return 0;
>
> > +}
> > +
> > +static int sun50i_dmic_probe(struct platform_device *pdev)
> > +{
> > +     struct sun50i_dmic_dev *host;
> > +     struct resource *res;
> > +     int ret;
> > +     void __iomem *base;
> > +
> > +     host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
> > +     if (!host)
> > +             return -ENOMEM;
> > +
> > +     /* Get the addresses */
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     base = devm_ioremap_resource(&pdev->dev, res);
> > +     if (IS_ERR(base))
> > +             return dev_err_probe(&pdev->dev, PTR_ERR(base),
> > +                                  "get resource failed.\n");
> > +
> > +     host->regmap = devm_regmap_init_mmio(&pdev->dev, base,
> > +                                             &sun50i_dmic_regmap_config);
>
> Your second line should be aligned on the opening parenthesis
>
> > +     /* Clocks */
> > +     host->bus_clk = devm_clk_get(&pdev->dev, "bus");
> > +     if (IS_ERR(host->bus_clk))
> > +             return dev_err_probe(&pdev->dev, PTR_ERR(host->bus_clk),
> > +                                  "failed to get bus clock.\n");
> > +
> > +     host->dmic_clk = devm_clk_get(&pdev->dev, "mod");
> > +     if (IS_ERR(host->dmic_clk))
> > +             return dev_err_probe(&pdev->dev, PTR_ERR(host->dmic_clk),
> > +                                  "failed to get dmic clock.\n");
> > +
> > +     host->dma_params_rx.addr = res->start + SUN50I_DMIC_DATA;
> > +     host->dma_params_rx.maxburst = 8;
> > +
> > +     platform_set_drvdata(pdev, host);
> > +
> > +     host->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
> > +     if (IS_ERR(host->rst))
> > +             return dev_err_probe(&pdev->dev, PTR_ERR(host->rst),
> > +                                  "Failed to get reset.\n");
>
> Your binding states that the reset is mandatory so you don't need the
> optional variant.
>
> > +     reset_control_deassert(host->rst);
>
> Can't this be moved to the runtime_pm hooks?

Is this necessary? I see that most of the driver files execute
reset_control_deassert in the probe function, and reset_control_assert
in the remove function.

>
> > +     ret = devm_snd_soc_register_component(&pdev->dev,
> > +                             &sun50i_dmic_component, &sun50i_dmic_dai, 1);
>
> Your second line should be aligned on the opening parenthesis
>
> > +     if (ret)
> > +             return dev_err_probe(&pdev->dev, ret,
> > +                                  "failed to register component.\n");
> > +
> > +     pm_runtime_enable(&pdev->dev);
> > +     if (!pm_runtime_enabled(&pdev->dev)) {
> > +             ret = sun50i_dmic_runtime_resume(&pdev->dev);
> > +             if (ret)
> > +                     goto err_unregister;
> > +     }
>
> We have a depends on PM on some drivers already, so I guess it would
> just make sense to add one more here instead of dealing with whether
> runtime_pm is compiled in or not.

I don't understand. I am referring to the sun4i-spdif.c file. Which
driver files should I refer to?

>
> Also, the name of the label is misleading: it's called err_unregister
> but you don't need to unregister anything and you actually disable
> runtime_pm for that device.
>
> err_disable_runtime_pm or something similar would be a better pick
>
> Thanks!
> Maxime


From maz at kernel.org  Sun Aug  1 02:50:00 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Aug 2021 10:50:00 +0100
Subject: [PATCH 3/5] ARM: dts: Add basic support for EcoNet EN7523
In-Reply-To: <0fe113c6-4160-fd3c-488d-53d40b6043ee@biot.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-4-bert@biot.com>
 <CACRpkdYvMtE8b-Xiy6=Aiz20jvY0M0Bz9XmcEQDHhqeS+LErEA@mail.gmail.com>
 <87y29n26po.wl-maz@kernel.org>
 <0fe113c6-4160-fd3c-488d-53d40b6043ee@biot.com>
Message-ID: <87r1fd1ol3.wl-maz@kernel.org>

On Sun, 01 Aug 2021 10:07:48 +0100,
Bert Vermeulen <bert at biot.com> wrote:
> 
> On 7/30/21 4:53 PM, Marc Zyngier wrote:
> > On Fri, 30 Jul 2021 15:31:36 +0100,
> > Linus Walleij <linus.walleij at linaro.org> wrote:
> >> 
> >> Paging Marc Z and Catalin just so they can see this:
> >> 
> >> On Fri, Jul 30, 2021 at 3:49 PM Bert Vermeulen <bert at biot.com> wrote:
> >> 
> >> > From: John Crispin <john at phrozen.org>
> >> >
> >> > Add basic support for EcoNet EN7523, enough for booting to console.
> >> >
> >> > The UART is basically 8250-compatible, except for the clock selection.
> >> > A clock-frequency value is synthesized to get this to run at 115200 bps.
> >> >
> >> > Signed-off-by: John Crispin <john at phrozen.org>
> >> > Signed-off-by: Bert Vermeulen <bert at biot.com>
> >> (...)
> >> > +       gic: interrupt-controller at 09000000 {
> >> > +               compatible = "arm,gic-v3";
> >> > +               interrupt-controller;
> >> > +               #interrupt-cells = <3>;
> >> > +               #address-cells = <1>;
> >> > +               #size-cells = <1>;
> >> > +               reg = <0x09000000 0x20000>,
> >> > +                         <0x09080000 0x80000>;
> >> > +               interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
> >> > +
> >> > +               its: gic-its at 09020000 {
> >> > +                       compatible = "arm,gic-v3-its";
> >> > +                       msi-controller;
> >> > +                       #msi-cell = <1>;
> >> > +                       reg = <0x090200000 0x20000>;
> >> > +               };
> >> > +       };
> >> 
> >> Yup GICv3 on ARM32-only silicon.
> > 
> > Hey, why not. But that's very unlikely, as Cortex-A7 doesn't have a
> > GICv3 CPU interface built in (it only has the memory mapped version),
> > and A53/57 were the first CPUs to ever support GICv3. I don't believe
> > the description of the CPU in the DT is accurate.
> > 
> > Bert, please send a kernel boot log.
> 
> At the bottom of this mail.
> 
> >> > +       timer {
> >> > +               compatible = "arm,armv8-timer";
> >> > +               interrupt-parent = <&gic>;
> >> > +               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> >> > +                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> >> > +                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> >> > +                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> > 
> > Copy paste bug. These are not valid intspecs for GICv3.
> 
> FWIW all these were taken verbatim from the vendor's SDK. Not that
> this makes them necessarily correct :)

Please, never copy anything verbatim from an existing DT, specially
not a vendor pile of crap.

Most integrators only cherry-picking DT random fragments without
trying to understand what they imply, beat them together until there
is a sign of life, and end-up with a monster that bears no resemblance
with reality.

Take an existing DT as a hint of what *could* be there, and work out
from first principles what actually makes sense. Yes, it is a lot of
work and involves reading specs, TRMs and whatnot. But at least it
will be correct, which is the standard that upstream is supposed to
uphold.

A shining example is what is below:

> 
> >> > +               clock-frequency = <25000000>;
> >> > +       };
> >> 
> >> Also arm,armv8-timer on ARM32-only silicon.
> > 
> > Probably because that's not what it actually is. My bet is on A53 with
> > a crippled firmware.
> 
> kernel boot log:
> 
> [    0.000000] Booting Linux on physical CPU 0x0
> [    0.000000] Linux version 5.14.0-rc3-00042-g3af70c6f8e95-dirty
> (bert at sumner) (arm-linux-gnueabi-gcc (Ubuntu 9.3.0-17ubuntu1~20.04)
> 9.3.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #392 SMP Sun Aug 1
> 10:28:13 CEST 2021
> [    0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d

As expected: 410fd034 = Cortex-A53 r0p4. Pretty far from a Cortex-A7,
isn't it?

> [    0.000000] CPU: div instructions available: patching division code
> [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing
> instruction cache
> [    0.000000] OF: fdt: Machine model: econet,en7523
> [    0.000000] earlycon: uart8250 at MMIO32 0x1fbf0000 (options '')
> [    0.000000] printk: bootconsole [uart8250] enabled
> [    0.000000] Memory policy: Data cache writealloc
> [    0.000000] Zone ranges:
> [    0.000000]   Normal   [mem 0x0000000080000000-0x000000009fffffff]
> [    0.000000]   HighMem  empty
> [    0.000000] Movable zone start for each node
> [    0.000000] Early memory node ranges
> [    0.000000]   node   0: [mem 0x0000000080000000-0x0000000083ffffff]
> [    0.000000]   node   0: [mem 0x0000000084000000-0x00000000849fffff]
> [    0.000000]   node   0: [mem 0x0000000084a00000-0x0000000084afffff]
> [    0.000000]   node   0: [mem 0x0000000084b00000-0x0000000084bfffff]
> [    0.000000]   node   0: [mem 0x0000000084c00000-0x0000000084ffffff]
> [    0.000000]   node   0: [mem 0x0000000085000000-0x00000000869fffff]
> [    0.000000]   node   0: [mem 0x0000000086a00000-0x0000000086afffff]
> [    0.000000]   node   0: [mem 0x0000000086b00000-0x0000000086bfffff]
> [    0.000000]   node   0: [mem 0x0000000086c00000-0x0000000086cfffff]
> [    0.000000]   node   0: [mem 0x0000000086d00000-0x0000000086dfffff]
> [    0.000000]   node   0: [mem 0x0000000086e00000-0x000000009fffffff]
> [    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> [    0.000000] percpu: Embedded 15 pages/cpu s30604 r8192 d22644 u61440
> [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 129920
> [    0.000000] Kernel command line:
> earlycon=uart8250,mmio32,0x1fbf0000 console=ttyS0,115200
> [    0.000000] Dentry cache hash table entries: 65536 (order: 6,
> 262144 bytes, linear)
> [    0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072
> bytes, linear)
> [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
> [    0.000000] Memory: 461316K/524288K available (7168K kernel code,
> 312K rwdata, 1488K rodata, 8192K init, 142K bss, 62972K reserved, 0K
> cma-reserved, 0K highmem)
> [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
> [    0.000000] rcu: Hierarchical RCU implementation.
> [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay
> is 10 jiffies.
> [    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
> [    0.000000] GICv3: 256 SPIs implemented
> [    0.000000] GICv3: 0 Extended SPIs implemented
> [    0.000000] GICv3: Distributor has no Range Selector support
> [    0.000000] GICv3: 16 PPIs implemented
> [    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x09080000

Interestingly, we don't program the property/pending tables for the
RD. Which means this SoC doesn't support LPIs, and thus *does not*
have an ITS, despite what you advertise.

> [    0.000000] random: get_random_bytes called from
> start_kernel+0x484/0x628 with crng_init=0
> [    0.000000] arch_timer: cp15 timer(s) running at 25.00MHz (virt).
> [    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff
> max_cycles: 0x5c40939b5, max_idle_ns: 440795202646 ns
> [    0.000000] sched_clock: 56 bits at 25MHz, resolution 40ns, wraps
> every 4398046511100ns
> [    0.008791] Switching to timer-based delay loop, resolution 40ns
> [    0.015454] Calibrating delay loop (skipped), value calculated
> using timer frequency.. 50.00 BogoMIPS (lpj=250000)
> [    0.026833] pid_max: default: 32768 minimum: 301
> [    0.032013] Mount-cache hash table entries: 1024 (order: 0, 4096
> bytes, linear)
> [    0.040047] Mountpoint-cache hash table entries: 1024 (order: 0,
> 4096 bytes, linear)
> [    0.049172] CPU: Testing write buffer coherency: ok
> [    0.054780] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
> [    0.061362] Setting up static identity map for 0x80100000 - 0x80100060
> [    0.068667] rcu: Hierarchical SRCU implementation.
> [    0.074290] gic-its at 09020000: unable to locate ITS domain

Confirmed. No LPI support, no ITS.

	M.

-- 
Without deviation from the norm, progress is not possible.


From lkp at intel.com  Sun Aug  1 02:56:42 2021
From: lkp at intel.com (kernel test robot)
Date: Sun, 1 Aug 2021 17:56:42 +0800
Subject: [xlnx:xlnx_rebase_v5.10 941/1758] rtc-zynqmp.c:undefined reference
 to `__divdi3'
Message-ID: <202108011739.NVyp8knf-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   cc84db65c53872c3beece8f401232232609b47de
commit: c2389b3a5c755a713dd15013c0d75cabbb9e12e5 [941/1758] rtc: zynqmp: Add calibration set and get support
config: h8300-randconfig-c004-20210728 (attached as .config)
compiler: h8300-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/c2389b3a5c755a713dd15013c0d75cabbb9e12e5
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout c2389b3a5c755a713dd15013c0d75cabbb9e12e5
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=h8300 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   h8300-linux-ld: section .init.text LMA [0000000000500960,0000000000543ceb] overlaps section .text LMA [000000000000025c,0000000000a8dccf]
   h8300-linux-ld: section .data VMA [0000000000400000,000000000050095f] overlaps section .text VMA [000000000000025c,0000000000a8dccf]
   h8300-linux-ld: arch/h8300/kernel/entry.o: in function `resume_kernel':
   (.text+0x280): undefined reference to `TI_PRE_COUNT'
   h8300-linux-ld: drivers/rtc/rtc-zynqmp.o: in function `xlnx_rtc_read_offset':
>> rtc-zynqmp.c:(.text+0x1b1): undefined reference to `__divdi3'
   h8300-linux-ld: drivers/rtc/rtc-zynqmp.o: in function `xlnx_rtc_set_offset':
   rtc-zynqmp.c:(.text+0x5a1): undefined reference to `__divdi3'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 28545 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210801/3626125e/attachment-0001.gz>

From maz at kernel.org  Sun Aug  1 04:20:47 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Aug 2021 12:20:47 +0100
Subject: [PATCH 07/16] KVM: arm64: Wire MMIO guard hypercalls
In-Reply-To: <20210730131103.GD23756@willie-the-truck>
References: <20210715163159.1480168-1-maz@kernel.org>
 <20210715163159.1480168-8-maz@kernel.org>
 <20210727181145.GF19173@willie-the-truck>
 <87v94ud8av.wl-maz@kernel.org>
 <20210730131103.GD23756@willie-the-truck>
Message-ID: <87v94p1kds.wl-maz@kernel.org>

On Fri, 30 Jul 2021 14:11:03 +0100,
Will Deacon <will at kernel.org> wrote:
> 
> On Wed, Jul 28, 2021 at 11:47:20AM +0100, Marc Zyngier wrote:
> > On Tue, 27 Jul 2021 19:11:46 +0100,
> > Will Deacon <will at kernel.org> wrote:
> > > 
> > > On Thu, Jul 15, 2021 at 05:31:50PM +0100, Marc Zyngier wrote:
> > > > Plumb in the hypercall interface to allow a guest to discover,
> > > > enroll, map and unmap MMIO regions.
> > > > 
> > > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > > ---
> > > >  arch/arm64/kvm/hypercalls.c | 20 ++++++++++++++++++++
> > > >  include/linux/arm-smccc.h   | 28 ++++++++++++++++++++++++++++
> > > >  2 files changed, 48 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
> > > > index 30da78f72b3b..a3deeb907fdd 100644
> > > > --- a/arch/arm64/kvm/hypercalls.c
> > > > +++ b/arch/arm64/kvm/hypercalls.c
> > > > @@ -5,6 +5,7 @@
> > > >  #include <linux/kvm_host.h>
> > > >  
> > > >  #include <asm/kvm_emulate.h>
> > > > +#include <asm/kvm_mmu.h>
> > > >  
> > > >  #include <kvm/arm_hypercalls.h>
> > > >  #include <kvm/arm_psci.h>
> > > > @@ -129,10 +130,29 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> > > >  	case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
> > > >  		val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
> > > >  		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP);
> > > > +		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_MMIO_GUARD_INFO);
> > > > +		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_MMIO_GUARD_ENROLL);
> > > > +		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_MMIO_GUARD_MAP);
> > > > +		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_MMIO_GUARD_UNMAP);
> > > >  		break;
> > > >  	case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
> > > >  		kvm_ptp_get_time(vcpu, val);
> > > >  		break;
> > > > +	case ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_INFO_FUNC_ID:
> > > > +		val[0] = PAGE_SIZE;
> > > > +		break;
> > > 
> > > I get the nagging feeling that querying the stage-2 page-size outside of
> > > MMIO guard is going to be useful once we start looking at memory sharing,
> > > so perhaps rename this to something more generic?
> > 
> > At this stage, why not follow the architecture and simply expose it as
> > ID_AA64MMFR0_EL1.TGran{4,64,16}_2? That's exactly what it is for, and
> > we already check for this in KVM itself.
> 
> Nice, I hadn't thought of that. On reflection, though, I don't agree that
> it's "exactly what it is for" -- the ID register talks about the supported
> stage-2 page-sizes, whereas we want to advertise the one page size that
> we're currently using. In other words, it's important that we only ever
> populate one of the fields and I wonder if that could bite us in future
> somehow?

Either that, or we expose all the page sizes >= to that of the host
(using the fact that larger page sizes are multiples of the base one),
and use the guest's page size to work out the granularity. Which is
what NV does already.

> Up to you, you've definitely got a better feel for this than me.

I'll have a look. The "one size" version is dead easy.

> 
> > > > +	case ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID:
> > > > +		set_bit(KVM_ARCH_FLAG_MMIO_GUARD, &vcpu->kvm->arch.flags);
> > > > +		val[0] = SMCCC_RET_SUCCESS;
> > > > +		break;
> > > > +	case ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID:
> > > > +		if (kvm_install_ioguard_page(vcpu, vcpu_get_reg(vcpu, 1)))
> > > > +			val[0] = SMCCC_RET_SUCCESS;
> > > > +		break;
> > > > +	case ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID:
> > > > +		if (kvm_remove_ioguard_page(vcpu, vcpu_get_reg(vcpu, 1)))
> > > > +			val[0] = SMCCC_RET_SUCCESS;
> > > > +		break;
> > > 
> > > I think there's a slight discrepancy between MAP and UNMAP here in that
> > > calling UNMAP on something that hasn't been mapped will fail, whereas
> > > calling MAP on something that's already been mapped will succeed. I think
> > > that might mean you can't reason about the final state of the page if two
> > > vCPUs race to call these functions in some cases (and both succeed).
> > 
> > I'm not sure that's the expected behaviour for ioremap(), for example
> > (you can ioremap two portions of the same page successfully).
> 
> Hmm, good point. Does that mean we should be refcounting the stage-2?
> Otherwise if we do something like:
> 
> 	foo = ioremap(page, 0x100);
> 	bar = ioremap(page+0x100, 0x100);
> 	iounmap(foo);
> 
> then bar will break. Or did I miss something in the series?

No, I don't think you have. But I don't think we should implement this
refcounting in the hypervisor side. We really should do it guest side.

I'll have a look.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From wens at csie.org  Sun Aug  1 05:15:22 2021
From: wens at csie.org (Chen-Yu Tsai)
Date: Sun, 1 Aug 2021 20:15:22 +0800
Subject: [linux-sunxi] Re: [PATCH 23/54] dt-bindings: mfd: Convert
 X-Powers AC100 binding to a schema
In-Reply-To: <20210723215426.GA2656991@robh.at.kernel.org>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-24-maxime@cerno.tech>
 <20210723215426.GA2656991@robh.at.kernel.org>
Message-ID: <CAGb2v64Fd2orpWpUdmmBGrRp+ExP5RVvosU89pEB_pzQ7UJ24A@mail.gmail.com>

On Sat, Jul 24, 2021 at 5:54 AM Rob Herring <robh at kernel.org> wrote:
>
> On Wed, Jul 21, 2021 at 04:03:53PM +0200, Maxime Ripard wrote:
> > The X-Powers AC100 hybrid devices are supported by Linux thanks to its
> > device tree binding.
> >
> > Now that we have the DT validation in place, let's convert the device
> > tree bindings for that driver over to a YAML schema.
> >
> > Cc: Chen-Yu Tsai <wens at csie.org>
> > Cc: Lee Jones <lee.jones at linaro.org>
> > Signed-off-by: Maxime Ripard <maxime at cerno.tech>

Acked-by: Chen-Yu Tsai <wens at csie.org>

once Rob's suggestions are added.


From wens at csie.org  Sun Aug  1 05:16:12 2021
From: wens at csie.org (Chen-Yu Tsai)
Date: Sun, 1 Aug 2021 20:16:12 +0800
Subject: [linux-sunxi] [PATCH 28/54] dt-bindings: power: supply: axp20x:
 Add AXP803 compatible
In-Reply-To: <20210721140424.725744-29-maxime@cerno.tech>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-29-maxime@cerno.tech>
Message-ID: <CAGb2v67QnD+nFG6QtLy332k_0W6kELTJEqtui_sf7Qf5nMxCmQ@mail.gmail.com>

On Wed, Jul 21, 2021 at 10:05 PM Maxime Ripard <maxime at cerno.tech> wrote:
>
> The AXP803 compatible was introduced recently with a fallback to the
> AXP813, but it was never documented.
>
> Cc: Chen-Yu Tsai <wens at csie.org>
> Cc: linux-pm at vger.kernel.org
> Cc: Sebastian Reichel <sre at kernel.org>
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>

Reviewed-by: Chen-Yu Tsai <wens at csie.org>


From wens at csie.org  Sun Aug  1 05:19:09 2021
From: wens at csie.org (Chen-Yu Tsai)
Date: Sun, 1 Aug 2021 20:19:09 +0800
Subject: [linux-sunxi] [PATCH 46/54] ARM: dts: cubieboard4: Remove the
 dumb-vga-dac compatible
In-Reply-To: <20210721140424.725744-47-maxime@cerno.tech>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-47-maxime@cerno.tech>
Message-ID: <CAGb2v67jQR9=4Ants6NX_YU9rEq0p5zjFdX9N3nLVph5z7rJrQ@mail.gmail.com>

On Wed, Jul 21, 2021 at 10:06 PM Maxime Ripard <maxime at cerno.tech> wrote:
>
> The dumb-vga-dac and adi,adv7123 compatibles are not supposed to be used
> together according to the binding.
>
> Since the corpro gm7123 is a drop-in replacement for the adv7123, let's
> remove dumb-vga-dac from our compatible list.
>
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>

Reviewed-by: Chen-Yu Tsai <wens at csie.org>


From stefan.wahren at i2se.com  Sun Aug  1 05:28:43 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:43 +0200
Subject: [PATCH 0/9] ARM: dts: Add Raspberry Pi CM4 & CM4 IO Board support
Message-ID: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>

This series add support for the Raspberry Pi Compute Module 4 and its
IO board.

Stefan Wahren (9):
  ARM: dts: bcm2711: fix emmc2bus node name
  ARM: dts: bcm2711: fix MDIO #address- and #size-cells
  ARM: dts: bcm2711-rpi-4-b: fix sd_io_1v8_reg regulator states
  dt-bindings: display: bcm2835: add optional property power-domains
  ARM: dts: bcm283x-rpi: Move Wifi/BT into separate dtsi
  dt-bindings: arm: bcm2835: Add Raspberry Pi Compute Module 4
  ARM: dts: Add Raspberry Pi Compute Module 4
  ARM: dts: Add Raspberry Pi Compute Module 4 IO Board
  arm64: dts: broadcom: Add reference to RPi CM4 IO Board

 .../devicetree/bindings/arm/bcm/bcm2835.yaml       |   1 +
 .../bindings/display/brcm,bcm2835-dsi0.yaml        |   3 +
 .../bindings/display/brcm,bcm2835-hdmi.yaml        |   3 +
 .../bindings/display/brcm,bcm2835-v3d.yaml         |   3 +
 .../bindings/display/brcm,bcm2835-vec.yaml         |   3 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts              |  42 ++-----
 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts           | 138 +++++++++++++++++++++
 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi             | 112 +++++++++++++++++
 arch/arm/boot/dts/bcm2711.dtsi                     |   6 +-
 arch/arm/boot/dts/bcm2835-rpi-zero-w.dts           |  31 ++---
 arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts         |  36 ++----
 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts         |  36 ++----
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts              |  36 ++----
 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi         |  34 +++++
 arch/arm64/boot/dts/broadcom/Makefile              |   1 +
 .../arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts |   2 +
 17 files changed, 346 insertions(+), 142 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
 create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi
 create mode 100644 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi
 create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts

-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:44 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:44 +0200
Subject: [PATCH 1/9] ARM: dts: bcm2711: fix emmc2bus node name
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-2-git-send-email-stefan.wahren@i2se.com>

Fix the node name to get the rid of the following DT schema warning:
'emmc2bus' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)
(@[0-9a-f]+)?$'

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
index b8a4096..afe0ef8 100644
--- a/arch/arm/boot/dts/bcm2711.dtsi
+++ b/arch/arm/boot/dts/bcm2711.dtsi
@@ -405,7 +405,7 @@
 	 * The firmware will find whether the emmc2bus alias is defined, and if
 	 * so, it'll edit the dma-ranges property below accordingly.
 	 */
-	emmc2bus: emmc2bus {
+	emmc2bus: emmc2-bus {
 		compatible = "simple-bus";
 		#address-cells = <2>;
 		#size-cells = <1>;
-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:50 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:50 +0200
Subject: [PATCH 7/9] ARM: dts: Add Raspberry Pi Compute Module 4
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-8-git-send-email-stefan.wahren@i2se.com>

The Raspberry Pi Compute Module 4 (CM4) are SoMs which contain the
following:
  * BCM2711 quad core processor
  * up to 8 GB RAM
  * up to 32 GB eMMC
  * a GPIO expander
  * Gigabit PHY BCM54210PE
  * Wifi/BT module with internal and external antenna

The eMMC and the Wifi/BT module are optional.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi | 112 +++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi

diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi b/arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi
new file mode 100644
index 0000000..2fa8704
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2711.dtsi"
+#include "bcm2711-rpi.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
+
+/ {
+	compatible = "raspberrypi,4-compute-module", "brcm,bcm2711";
+
+	chosen {
+		/* 8250 auxiliary UART instead of pl011 */
+		stdout-path = "serial1:115200n8";
+	};
+
+	sd_io_1v8_reg: sd_io_1v8_reg {
+		compatible = "regulator-gpio";
+		regulator-name = "vdd-sd-io";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-settling-time-us = <5000>;
+		gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x1>,
+			 <3300000 0x0>;
+		status = "okay";
+	};
+
+	sd_vcc_reg: sd_vcc_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&bt {
+	shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
+};
+
+/*
+ * EMMC2 is used to drive the eMMC
+ * Unfortunately the IP block seems to be limited to 100 MHz
+ */
+&emmc2 {
+	bus-width = <8>;
+	vqmmc-supply = <&sd_io_1v8_reg>;
+	vmmc-supply = <&sd_vcc_reg>;
+	broken-cd;
+	status = "okay";
+};
+
+&expgpio {
+	gpio-line-names = "BT_ON",
+			  "WL_ON",
+			  "PWR_LED_OFF",
+			  "ANT1",
+			  "VDD_SD_IO_SEL",
+			  "CAM_GPIO",
+			  "SD_PWR_ON",
+			  "ANT2";
+
+	ant1: ant1-hog {
+		/* internal antenna enabled */
+		gpio-hog;
+		gpios = <3 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "ant1";
+	};
+
+	ant2: ant2-hog {
+		/* external antenna disabled */
+		gpio-hog;
+		gpios = <7 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "ant2";
+	};
+};
+
+&genet {
+	phy-handle = <&phy1>;
+	phy-mode = "rgmii-rxid";
+	status = "okay";
+};
+
+&genet_mdio {
+	phy1: ethernet-phy at 0 {
+		/* No PHY interrupt */
+		reg = <0x0>;
+	};
+};
+
+/* uart0 communicates with the BT module */
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
+	uart-has-rtscts;
+};
+
+/* uart1 is mapped to the pin header */
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_gpio14>;
+	status = "okay";
+};
+
+&wifi_pwrseq {
+	reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:46 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:46 +0200
Subject: [PATCH 3/9] ARM: dts: bcm2711-rpi-4-b: fix sd_io_1v8_reg regulator
 states
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-4-git-send-email-stefan.wahren@i2se.com>

DT schema check complains at sd_io_1v8_reg about the following:

 [1800000, 1, 3300000, 0] is too long
 Additional items are not allowed (3300000, 0 were unexpected)

So fix the states definition.

Fixes: 7dbe8c62ceeb ("ARM: dts: Add minimal Raspberry Pi 4 support")
Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index f24bdd0..abf8298 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -40,8 +40,8 @@
 		regulator-always-on;
 		regulator-settling-time-us = <5000>;
 		gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
-		states = <1800000 0x1
-			  3300000 0x0>;
+		states = <1800000 0x1>,
+			 <3300000 0x0>;
 		status = "okay";
 	};
 
-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:49 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:49 +0200
Subject: [PATCH 6/9] dt-bindings: arm: bcm2835: Add Raspberry Pi Compute
 Module 4
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-7-git-send-email-stefan.wahren@i2se.com>

Add the Raspberry Pi Compute Module 4 to DT schema.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
index 230b80d..5dc4824 100644
--- a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
+++ b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
@@ -19,6 +19,7 @@ properties:
         items:
           - enum:
               - raspberrypi,400
+              - raspberrypi,4-compute-module
               - raspberrypi,4-model-b
           - const: brcm,bcm2711
 
-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:45 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:45 +0200
Subject: [PATCH 2/9] ARM: dts: bcm2711: fix MDIO #address- and #size-cells
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-3-git-send-email-stefan.wahren@i2se.com>

The values of #address-cells and #size-cells are swapped. Fix this
and avoid the following DT schema warnings for mdio at e14:

 #address-cells:0:0: 1 was expected
 #size-cells:0:0: 0 was expected

Fixes: be8af7a9e3cc ("ARM: dts: bcm2711-rpi-4: Enable GENET support")
Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
index afe0ef8..55022fc 100644
--- a/arch/arm/boot/dts/bcm2711.dtsi
+++ b/arch/arm/boot/dts/bcm2711.dtsi
@@ -532,8 +532,8 @@
 				compatible = "brcm,genet-mdio-v5";
 				reg = <0xe14 0x8>;
 				reg-names = "mdio";
-				#address-cells = <0x0>;
-				#size-cells = <0x1>;
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
 			};
 		};
 	};
-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:47 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:47 +0200
Subject: [PATCH 4/9] dt-bindings: display: bcm2835: add optional property
 power-domains
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-5-git-send-email-stefan.wahren@i2se.com>

The Raspberry Pi boards with BCM283x needs control of the power domains
to get display components running. So add this as an optional property
in order to avoid such DT schema warnings:

hdmi at 7e902000: 'power-domains' does not match any of the regexes: ...

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml | 3 +++
 Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml | 3 +++
 Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml  | 3 +++
 Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml  | 3 +++
 4 files changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml
index 3260857..c8b2459 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml
@@ -47,6 +47,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
 required:
   - "#clock-cells"
   - compatible
diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml
index 031e35e..48c8cad 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml
@@ -51,6 +51,9 @@ properties:
   dma-names:
     const: audio-rx
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml
index 8a73780..c55a821 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml
@@ -24,6 +24,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml
index 9b24081..5d921e3 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml
@@ -24,6 +24,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:52 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:52 +0200
Subject: [PATCH 9/9] arm64: dts: broadcom: Add reference to RPi CM4 IO Board
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-10-git-send-email-stefan.wahren@i2se.com>

This adds a reference to the dts of the Raspberry Pi Compute Module 4
IO Board, so we don't need to maintain the content in arm64.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm64/boot/dts/broadcom/Makefile               | 1 +
 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts | 2 ++
 2 files changed, 3 insertions(+)
 create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts

diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile
index 11eae3e..c688203 100644
--- a/arch/arm64/boot/dts/broadcom/Makefile
+++ b/arch/arm64/boot/dts/broadcom/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-400.dtb \
 			      bcm2711-rpi-4-b.dtb \
+			      bcm2711-rpi-cm4-io.dtb \
 			      bcm2837-rpi-3-a-plus.dtb \
 			      bcm2837-rpi-3-b.dtb \
 			      bcm2837-rpi-3-b-plus.dtb \
diff --git a/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
new file mode 100644
index 0000000..e36d395
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "arm/bcm2711-rpi-cm4-io.dts"
-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:51 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:51 +0200
Subject: [PATCH 8/9] ARM: dts: Add Raspberry Pi Compute Module 4 IO Board
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-9-git-send-email-stefan.wahren@i2se.com>

This adds the matching carrier for Raspberry Pi Compute Module 4.
Instead of xHCI USB host controller there is just a USB 2.0 interface
connected to the DWC2 controller from the BCM2711. As a result
there is a free PCIe Gen 2 socket. Also there are 2 full-size HDMI 2.0
connectors.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/Makefile               |   1 +
 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts | 138 +++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 863347b..d3f25b9 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -90,6 +90,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
 	bcm2837-rpi-cm3-io3.dtb \
 	bcm2711-rpi-400.dtb \
 	bcm2711-rpi-4-b.dtb \
+	bcm2711-rpi-cm4-io.dtb \
 	bcm2835-rpi-zero.dtb \
 	bcm2835-rpi-zero-w.dtb
 dtb-$(CONFIG_ARCH_BCM_5301X) += \
diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
new file mode 100644
index 0000000..19600b6
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2711-rpi-cm4.dtsi"
+#include "bcm283x-rpi-usb-host.dtsi"
+
+/ {
+	model = "Raspberry Pi Compute Module 4 IO Board";
+
+	leds {
+		led-act {
+			gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
+		};
+
+		led-pwr {
+			label = "PWR";
+			gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+			linux,default-trigger = "default-on";
+		};
+	};
+};
+
+&ddc0 {
+	status = "okay";
+};
+
+&ddc1 {
+	status = "okay";
+};
+
+&gpio {
+	/*
+	 * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and
+	 * the official GPU firmware DT blob.
+	 *
+	 * Legend:
+	 * "FOO" = GPIO line named "FOO" on the schematic
+	 * "FOO_N" = GPIO line named "FOO" on schematic, active low
+	 */
+	gpio-line-names = "ID_SDA",
+			  "ID_SCL",
+			  "SDA1",
+			  "SCL1",
+			  "GPIO_GCLK",
+			  "GPIO5",
+			  "GPIO6",
+			  "SPI_CE1_N",
+			  "SPI_CE0_N",
+			  "SPI_MISO",
+			  "SPI_MOSI",
+			  "SPI_SCLK",
+			  "GPIO12",
+			  "GPIO13",
+			  /* Serial port */
+			  "TXD1",
+			  "RXD1",
+			  "GPIO16",
+			  "GPIO17",
+			  "GPIO18",
+			  "GPIO19",
+			  "GPIO20",
+			  "GPIO21",
+			  "GPIO22",
+			  "GPIO23",
+			  "GPIO24",
+			  "GPIO25",
+			  "GPIO26",
+			  "GPIO27",
+			  "RGMII_MDIO",
+			  "RGMIO_MDC",
+			  /* Used by BT module */
+			  "CTS0",
+			  "RTS0",
+			  "TXD0",
+			  "RXD0",
+			  /* Used by Wifi */
+			  "SD1_CLK",
+			  "SD1_CMD",
+			  "SD1_DATA0",
+			  "SD1_DATA1",
+			  "SD1_DATA2",
+			  "SD1_DATA3",
+			  /* Shared with SPI flash */
+			  "PWM0_MISO",
+			  "PWM1_MOSI",
+			  "STATUS_LED_G_CLK",
+			  "SPIFLASH_CE_N",
+			  "SDA0",
+			  "SCL0",
+			  "RGMII_RXCLK",
+			  "RGMII_RXCTL",
+			  "RGMII_RXD0",
+			  "RGMII_RXD1",
+			  "RGMII_RXD2",
+			  "RGMII_RXD3",
+			  "RGMII_TXCLK",
+			  "RGMII_TXCTL",
+			  "RGMII_TXD0",
+			  "RGMII_TXD1",
+			  "RGMII_TXD2",
+			  "RGMII_TXD3";
+};
+
+&hdmi0 {
+	status = "okay";
+};
+
+&hdmi1 {
+	status = "okay";
+};
+
+&genet {
+	status = "okay";
+};
+
+&pixelvalve0 {
+	status = "okay";
+};
+
+&pixelvalve1 {
+	status = "okay";
+};
+
+&pixelvalve2 {
+	status = "okay";
+};
+
+&pixelvalve4 {
+	status = "okay";
+};
+
+&vc4 {
+	status = "okay";
+};
+
+&vec {
+	status = "disabled";
+};
-- 
2.7.4



From stefan.wahren at i2se.com  Sun Aug  1 05:28:48 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun,  1 Aug 2021 14:28:48 +0200
Subject: [PATCH 5/9] ARM: dts: bcm283x-rpi: Move Wifi/BT into separate dtsi
In-Reply-To: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1627820932-7247-6-git-send-email-stefan.wahren@i2se.com>

A Wifi/BT chip is quite common for the Raspberry Pi boards. So move those
definitions into a separate dtsi in order to avoid copy & paste. This
change was inspired by a vendor tree patch from Phil Elwell.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts      | 38 +++++++-----------------------
 arch/arm/boot/dts/bcm2835-rpi-zero-w.dts   | 31 +++++++-----------------
 arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 36 ++++++----------------------
 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 36 +++++++---------------------
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts      | 36 +++++++---------------------
 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi | 34 ++++++++++++++++++++++++++
 6 files changed, 74 insertions(+), 137 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi

diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index abf8298..c54ba5cf 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -3,6 +3,7 @@
 #include "bcm2711.dtsi"
 #include "bcm2711-rpi.dtsi"
 #include "bcm283x-rpi-usb-peripheral.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
@@ -26,11 +27,6 @@
 		};
 	};
 
-	wifi_pwrseq: wifi-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
-	};
-
 	sd_io_1v8_reg: sd_io_1v8_reg {
 		compatible = "regulator-gpio";
 		regulator-name = "vdd-sd-io";
@@ -56,6 +52,10 @@
 	};
 };
 
+&bt {
+	shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
+};
+
 &ddc0 {
 	status = "okay";
 };
@@ -178,23 +178,6 @@
 	status = "okay";
 };
 
-/* SDHCI is used to control the SDIO for wireless */
-&sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_gpio34>;
-	bus-width = <4>;
-	non-removable;
-	mmc-pwrseq = <&wifi_pwrseq>;
-	status = "okay";
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
 /* EMMC2 is used to drive the SD card */
 &emmc2 {
 	vqmmc-supply = <&sd_io_1v8_reg>;
@@ -236,13 +219,6 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
 	uart-has-rtscts;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-		shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
-	};
 };
 
 /* uart1 is mapped to the pin header */
@@ -259,3 +235,7 @@
 &vec {
 	status = "disabled";
 };
+
+&wifi_pwrseq {
+	reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
index 33b2b77..243236b 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
@@ -7,6 +7,7 @@
 #include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
 #include "bcm283x-rpi-usb-otg.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
@@ -27,11 +28,10 @@
 			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
 		};
 	};
+};
 
-	wifi_pwrseq: wifi-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
-	};
+&bt {
+	shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
 };
 
 &gpio {
@@ -110,19 +110,7 @@
 };
 
 &sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>;
-	bus-width = <4>;
-	mmc-pwrseq = <&wifi_pwrseq>;
-	non-removable;
-	status = "okay";
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
 };
 
 &sdhost {
@@ -135,13 +123,6 @@
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-		shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
-	};
 };
 
 &uart1 {
@@ -149,3 +130,7 @@
 	pinctrl-0 = <&uart1_gpio14>;
 	status = "okay";
 };
+
+&wifi_pwrseq {
+	reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
index 77099a7..d73daf5 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
@@ -3,6 +3,7 @@
 #include "bcm2837.dtsi"
 #include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,3-model-a-plus", "brcm,bcm2837";
@@ -130,28 +131,6 @@
 	status = "okay";
 };
 
-/*
- * SDHCI is used to control the SDIO for wireless
- *
- * WL_REG_ON and BT_REG_ON of the CYW43455 Wifi/BT module are driven
- * by a single GPIO. We can't give GPIO control to one of the drivers,
- * otherwise the other part would get unexpectedly disturbed.
- */
-&sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_gpio34>;
-	status = "okay";
-	bus-width = <4>;
-	non-removable;
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
 /* SDHOST is used to drive the SD card */
 &sdhost {
 	pinctrl-names = "default";
@@ -160,16 +139,15 @@
 	bus-width = <4>;
 };
 
-/* uart0 communicates with the BT module */
+/* uart0 communicates with the BT module
+ *
+ * WL_REG_ON and BT_REG_ON of the CYW43455 Wifi/BT module are driven
+ * by a single GPIO. We can't give GPIO control to one of the drivers,
+ * otherwise the other part would get unexpectedly disturbed.
+ */
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32 &gpclk2_gpio43>;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-	};
 };
 
 /* uart1 is mapped to the pin header */
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
index 6101026..e12938b 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
@@ -4,6 +4,7 @@
 #include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-lan7515.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837";
@@ -31,11 +32,10 @@
 			linux,default-trigger = "default-on";
 		};
 	};
+};
 
-	wifi_pwrseq: wifi-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
-	};
+&bt {
+	shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
 };
 
 &firmware {
@@ -137,23 +137,6 @@
 	status = "okay";
 };
 
-/* SDHCI is used to control the SDIO for wireless */
-&sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_gpio34>;
-	status = "okay";
-	bus-width = <4>;
-	non-removable;
-	mmc-pwrseq = <&wifi_pwrseq>;
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
 /* SDHOST is used to drive the SD card */
 &sdhost {
 	pinctrl-names = "default";
@@ -166,13 +149,6 @@
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32 &gpclk2_gpio43>;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-		shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
-	};
 };
 
 /* uart1 is mapped to the pin header */
@@ -181,3 +157,7 @@
 	pinctrl-0 = <&uart1_gpio14>;
 	status = "okay";
 };
+
+&wifi_pwrseq {
+	reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
index dd4a486..42b5383 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
@@ -4,6 +4,7 @@
 #include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-smsc9514.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
@@ -24,11 +25,10 @@
 			gpios = <&expgpio 2 GPIO_ACTIVE_HIGH>;
 		};
 	};
+};
 
-	wifi_pwrseq: wifi-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
-	};
+&bt {
+	shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
 };
 
 &firmware {
@@ -134,13 +134,6 @@
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_gpio32 &gpclk2_gpio43>;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-		shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
-	};
 };
 
 /* uart1 is mapped to the pin header */
@@ -150,23 +143,6 @@
 	status = "okay";
 };
 
-/* SDHCI is used to control the SDIO for wireless */
-&sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_gpio34>;
-	status = "okay";
-	bus-width = <4>;
-	non-removable;
-	mmc-pwrseq = <&wifi_pwrseq>;
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
 /* SDHOST is used to drive the SD card */
 &sdhost {
 	pinctrl-names = "default";
@@ -174,3 +150,7 @@
 	status = "okay";
 	bus-width = <4>;
 };
+
+&wifi_pwrseq {
+	reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi b/arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi
new file mode 100644
index 0000000..0b64cc1
--- /dev/null
+++ b/arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	wifi_pwrseq: wifi-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+	};
+};
+
+/* SDHCI is used to control the SDIO for wireless */
+&sdhci {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_gpio34>;
+	bus-width = <4>;
+	non-removable;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	status = "okay";
+
+	brcmf: wifi at 1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+	};
+};
+
+/* uart0 communicates with the BT module */
+&uart0 {
+	status = "okay";
+
+	bt: bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		max-speed = <2000000>;
+	};
+};
-- 
2.7.4



From len.baker at gmx.com  Sun Aug  1 06:19:58 2021
From: len.baker at gmx.com (Len Baker)
Date: Sun,  1 Aug 2021 15:19:58 +0200
Subject: [PATCH v3] drivers/soc: Remove all strcpy() uses
Message-ID: <20210801131958.6144-1-len.baker@gmx.com>

strcpy() performs no bounds checking on the destination buffer. This
could result in linear overflows beyond the end of the buffer, leading
to all kinds of misbehaviors. The safe replacement is strscpy().

Moreover, when the size of the destination buffer cannot be obtained
using "sizeof", use the memcpy function instead of strscpy.

Signed-off-by: Len Baker <len.baker at gmx.com>
---
This is a task of the KSPP [1]

[1] https://github.com/KSPP/linux/issues/88

Changelog v1 -> v2
- Change the "area_name_size" variable for a shorter name (Geert
  Uytterhoeven).
- Add the "Reviewed-by: Geert Uytterhoeven" tag.
- Use the memcpy function instead of strscpy function when the
  size of the destination buffer cannot be obtained with "sizeof"
  (David Laight, Robin Murphy).

Changelog v2 -> v3
- Remove the "Reviewed-by: Geert Uytterhoeven" tag since the code
  has changed after the v1 review (use of memcpy instead of
  strscpy).

 drivers/soc/qcom/pdr_interface.c    | 13 +++++++------
 drivers/soc/renesas/r8a779a0-sysc.c |  6 ++++--
 drivers/soc/renesas/rcar-sysc.c     |  6 ++++--
 drivers/soc/ti/knav_dma.c           |  2 +-
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c
index 915d5bc3d46e..cf119fde749d 100644
--- a/drivers/soc/qcom/pdr_interface.c
+++ b/drivers/soc/qcom/pdr_interface.c
@@ -131,7 +131,7 @@ static int pdr_register_listener(struct pdr_handle *pdr,
 		return ret;

 	req.enable = enable;
-	strcpy(req.service_path, pds->service_path);
+	strscpy(req.service_path, pds->service_path, sizeof(req.service_path));

 	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
 			       &txn, SERVREG_REGISTER_LISTENER_REQ,
@@ -257,7 +257,7 @@ static int pdr_send_indack_msg(struct pdr_handle *pdr, struct pdr_service *pds,
 		return ret;

 	req.transaction_id = tid;
-	strcpy(req.service_path, pds->service_path);
+	strscpy(req.service_path, pds->service_path, sizeof(req.service_path));

 	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
 			       &txn, SERVREG_SET_ACK_REQ,
@@ -406,7 +406,7 @@ static int pdr_locate_service(struct pdr_handle *pdr, struct pdr_service *pds)
 		return -ENOMEM;

 	/* Prepare req message */
-	strcpy(req.service_name, pds->service_name);
+	strscpy(req.service_name, pds->service_name, sizeof(req.service_name));
 	req.domain_offset_valid = true;
 	req.domain_offset = 0;

@@ -531,8 +531,8 @@ struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr,
 		return ERR_PTR(-ENOMEM);

 	pds->service = SERVREG_NOTIFIER_SERVICE;
-	strcpy(pds->service_name, service_name);
-	strcpy(pds->service_path, service_path);
+	strscpy(pds->service_name, service_name, sizeof(pds->service_name));
+	strscpy(pds->service_path, service_path, sizeof(pds->service_path));
 	pds->need_locator_lookup = true;

 	mutex_lock(&pdr->list_lock);
@@ -587,7 +587,8 @@ int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds)
 			break;

 		/* Prepare req message */
-		strcpy(req.service_path, pds->service_path);
+		strscpy(req.service_path, pds->service_path,
+			sizeof(req.service_path));
 		addr = pds->addr;
 		break;
 	}
diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
index d464ffa1be33..7410b9fa9846 100644
--- a/drivers/soc/renesas/r8a779a0-sysc.c
+++ b/drivers/soc/renesas/r8a779a0-sysc.c
@@ -404,19 +404,21 @@ static int __init r8a779a0_sysc_pd_init(void)
 	for (i = 0; i < info->num_areas; i++) {
 		const struct r8a779a0_sysc_area *area = &info->areas[i];
 		struct r8a779a0_sysc_pd *pd;
+		size_t n;

 		if (!area->name) {
 			/* Skip NULLified area */
 			continue;
 		}

-		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
+		n = strlen(area->name) + 1;
+		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
 		if (!pd) {
 			error = -ENOMEM;
 			goto out_put;
 		}

-		strcpy(pd->name, area->name);
+		memcpy(pd->name, area->name, n);
 		pd->genpd.name = pd->name;
 		pd->pdr = area->pdr;
 		pd->flags = area->flags;
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index 53387a72ca00..b0a80de34c98 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -396,19 +396,21 @@ static int __init rcar_sysc_pd_init(void)
 	for (i = 0; i < info->num_areas; i++) {
 		const struct rcar_sysc_area *area = &info->areas[i];
 		struct rcar_sysc_pd *pd;
+		size_t n;

 		if (!area->name) {
 			/* Skip NULLified area */
 			continue;
 		}

-		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
+		n = strlen(area->name) + 1;
+		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
 		if (!pd) {
 			error = -ENOMEM;
 			goto out_put;
 		}

-		strcpy(pd->name, area->name);
+		memcpy(pd->name, area->name, n);
 		pd->genpd.name = pd->name;
 		pd->ch.chan_offs = area->chan_offs;
 		pd->ch.chan_bit = area->chan_bit;
diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c
index 591d14ebcb11..5f9816d317a5 100644
--- a/drivers/soc/ti/knav_dma.c
+++ b/drivers/soc/ti/knav_dma.c
@@ -691,7 +691,7 @@ static int dma_init(struct device_node *cloud, struct device_node *dma_node)
 	dma->max_rx_flow = max_rx_flow;
 	dma->max_tx_chan = min(max_tx_chan, max_tx_sched);
 	atomic_set(&dma->ref_count, 0);
-	strcpy(dma->name, node->name);
+	strscpy(dma->name, node->name, sizeof(dma->name));
 	spin_lock_init(&dma->lock);

 	for (i = 0; i < dma->max_tx_chan; i++) {
--
2.25.1



From maz at kernel.org  Sun Aug  1 06:22:21 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Aug 2021 14:22:21 +0100
Subject: [PATCH] ARM: dts: ixp4xx: Add a devicetree for Freecom FSG-3
In-Reply-To: <20210729144128.2834328-1-linus.walleij@linaro.org>
References: <20210729144128.2834328-1-linus.walleij@linaro.org>
Message-ID: <87tuk91er6.wl-maz@kernel.org>

On Thu, 29 Jul 2021 15:41:28 +0100,
Linus Walleij <linus.walleij at linaro.org> wrote:
> 
> This adds a devicetree for the Freecom FSG-3, a combined router
> and NAS.

After a bit of soldering as well as fighting with the bootloader
(which is so broken that it makes the Vulcan's version of RedBoot look
pretty sane in comparison), I've managed to successfully boot the
machine to userspace.

Networking, PCI, USB, ATA (to some extent, see below), RTC and hwmon
all see to work correctly. The switch works *sometimes*, but I haven't
worked out whether it needs some special care or it is broken.

One thing that still puzzles me is that I can't manage to get the SCSI
layer to probe the disk. The original firmware finds it perfectly, but
I'm obviously failing to select the right config option that would
make the PATA controller (which gets probed) to register as a SCSI
target:

[the PCI device is seen correctly]

pci 0000:00:0c.0: [1106:3249] type 00 class 0x010400
pci 0000:00:0c.0: reg 0x10: [io  0x0af0-0x0aff]
pci 0000:00:0c.0: reg 0x14: [io  0x0a70-0x0a7f]
pci 0000:00:0c.0: reg 0x18: [io  0x01f0-0x01ff]
pci 0000:00:0c.0: reg 0x1c: [io  0x0170-0x017f]
pci 0000:00:0c.0: reg 0x20: [io  0xcc00-0xcc1f]
pci 0000:00:0c.0: reg 0x24: [io  0x8c00-0x8cff]

[and the driver picks it up, correctly seeing the 3 ports]

sata_via 0000:00:0c.0: version 2.6
sata_via 0000:00:0c.0: enabling device (0000 -> 0001)
sata_via 0000:00:0c.0: routed to hard irq line 8
scsi host0: sata_via
scsi host1: sata_via
scsi host2: sata_via
ata1: SATA max UDMA/133 port i16 at 0x1420 bmdma 0x1400 irq 24
ata2: SATA max UDMA/133 port i16 at 0x1430 bmdma 0x1408 irq 24
ata3: PATA max UDMA/133 port i16 at 0x1440 bmdma 0x1410 irq 24

[it then realises that there is nothing on the SATA ports]

ata1: failed to resume link (SControl 0)
ata1: SATA link down (SStatus 10 SControl 0)
ata2: failed to resume link (SControl 302)
ata2: SATA link down (SStatus 2A2F SControl 302)

but ata3, which has the internal disk, never gets scanned.

If feels that this is only a matter of plumbing, but I'm out of my
depth here. Any idea?

Anyway, FWIW:

Acked-by: Marc Zyngier <maz at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From andrew at lunn.ch  Sun Aug  1 06:55:28 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 1 Aug 2021 15:55:28 +0200
Subject: [PATCH] ARM: dts: ixp4xx: Add a devicetree for Freecom FSG-3
In-Reply-To: <87tuk91er6.wl-maz@kernel.org>
References: <20210729144128.2834328-1-linus.walleij@linaro.org>
 <87tuk91er6.wl-maz@kernel.org>
Message-ID: <YQan0ALPnn4aBM7y@lunn.ch>

On Sun, Aug 01, 2021 at 02:22:21PM +0100, Marc Zyngier wrote:

> The switch works *sometimes*, but I haven't
> worked out whether it needs some special care or it is broken.

Hi Marc

The driver exports the file "registers" in /sysfs. Do you see any sort
of application/driver running in userspace which might be talking to
the switch?

    Andrew


From catalin.marinas at arm.com  Sun Aug  1 07:56:25 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Sun, 1 Aug 2021 07:56:25 -0700
Subject: [PATCH v5 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <20210719164536.19143-1-broonie@kernel.org>
References: <20210719164536.19143-1-broonie@kernel.org>
Message-ID: <20210801145623.GA28489@arm.com>

On Mon, Jul 19, 2021 at 05:45:32PM +0100, Mark Brown wrote:
> Deployments of BTI on arm64 have run into issues interacting with
> systemd's MemoryDenyWriteExecute feature.  Currently for dynamically
> linked executables the kernel will only handle architecture specific
> properties like BTI for the interpreter, the expectation is that the
> interpreter will then handle any properties on the main executable.
> For BTI this means remapping the executable segments PROT_EXEC |
> PROT_BTI.
> 
> This interacts poorly with MemoryDenyWriteExecute since that is
> implemented using a seccomp filter which prevents setting PROT_EXEC on
> already mapped memory and lacks the context to be able to detect that
> memory is already mapped with PROT_EXEC.  This series resolves this by
> handling the BTI property for both the interpreter and the main
> executable.
> 
> This does mean that we may get more code with BTI enabled if running on
> a system without BTI support in the dynamic linker, this is expected to
> be a safe configuration and testing seems to confirm that. It also
> reduces the flexibility userspace has to disable BTI but it is expected
> that for cases where there are problems which require BTI to be disabled
> it is more likely that it will need to be disabled on a system level.

One last call on this series as I'd like to at least have it in -next
for a few weeks if we are to upstream it. Adding people that have been
involved on the previous longer discussion:

https://lore.kernel.org/r/8584c14f-5c28-9d70-c054-7c78127d84ea at arm.com

The glibc issue has been solved in the sense that if mprotect() fails,
the error is ignored and we end up with BTI disabled for the main
executable.

This series aims to change the responsibility for PROT_BTI on the main
(dynamic) executable from the dynamic linker to the kernel. It doesn't
come without risks though. Suppose that the dynamic linker in the future
decides that it's not safe to mix BTI/non-BTI for some objects, it won't
have a way to disable BTI on the main executable if MDWX is enabled.

It's a trade-off between the risks introduced by this series vs
the benefits of MDWX. If the risk is non-negligible, the next step is
assessing the importance of MDWX vs BTI on arm64 and whether we should
look for alternatives to MDWX in the future (ideally which don't involve
new flags to mprotect()).

Thanks.

-- 
Catalin


From dillonhua at gmail.com  Sun Aug  1 07:56:55 2021
From: dillonhua at gmail.com (Dillon Hua)
Date: Sun, 1 Aug 2021 22:56:55 +0800
Subject: [RESEND PATCH v4] clk: stm32f4: fix post divisor setup for
 I2S/SAI PLLs
In-Reply-To: <1926284813.753014.1627553002984@mail1.libero.it>
References: <20210725160725.10788-1-dariobin@libero.it>
 <CAPTRvHkf0cK_4ZidM17rPo99gWDmxgqFt4CDUjqFFwkOeQeFDg@mail.gmail.com>
 <1926284813.753014.1627553002984@mail1.libero.it>
Message-ID: <CAPTRvH=R822osk86tRJqJCPNYY85t8t90+HJWcz43iASbcg2Jw@mail.gmail.com>

Hi Dario

On Thu, Jul 29, 2021 at 6:03 PM Dario Binacchi <dariobin at libero.it> wrote:
>
> Hi Dillon,
>
> > Il 28/07/2021 12:03 Dillon Hua <dillonhua at gmail.com> ha scritto:
> >
> >
> > Hi Dario,
> >
> > I have a similar patch [1] submitted last year.
> > Unfortunately, it did not get accepted by the maintainer.
> >
> > Just a reminder here for you, should remove
> >
> > { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
>
> Thank you for your suggestion.
> While testing the patch on the stm32f469-disco board I didn't
> notice the white screen issue. I'll try to run the tests again.
> I will let you know.

Thanks, be sure clk_ignore_unused is not set from the kernel cmdline
at your test.

Best Regards
Dillon

>
> Thanks and regards,
> Dario
>
> >
> > from stm32{f429, f469, f746, f769}_gates[]; or else
> > run into white screen after the kernel enters the console.
> >
> > This patch was verified by Patrice Chotard, you can
> > find  the history from [2].
> >
> > Hope you can help to submit a patch to include [2], thanks.
> >
> > [1]
> > https://lore.kernel.org/linux-arm-kernel/1590564453-24499-7-git-send-email-dillon.minfei at gmail.com/
> > https://lore.kernel.org/linux-arm-kernel/1590564453-24499-6-git-send-email-dillon.minfei at gmail.com/
> >
> > resend this year:
> > https://lore.kernel.org/lkml/1590378348-8115-6-git-send-email-dillon.minfei at gmail.com/
> >
> > [2]
> > https://lore.kernel.org/lkml/6915fa2a-e211-476f-8317-6825e280c322 at foss.st.com/
> >
> > Thanks
> > Best Regards
> >
> > Dillon
> >
> > On Mon, Jul 26, 2021 at 12:08 AM Dario Binacchi <dariobin at libero.it> wrote:
> > >
> > > Enabling the framebuffer leads to a system hang. Running, as a debug
> > > hack, the store_pan() function in drivers/video/fbdev/core/fbsysfs.c
> > > without taking the console_lock, allows to see the crash backtrace on
> > > the serial line.
> > >
> > > ~ # echo 0 0 > /sys/class/graphics/fb0/pan
> > >
> > > [    9.719414] Unhandled exception: IPSR = 00000005 LR = fffffff1
> > > [    9.726937] CPU: 0 PID: 49 Comm: sh Not tainted 5.13.0-rc5 #9
> > > [    9.733008] Hardware name: STM32 (Device Tree Support)
> > > [    9.738296] PC is at clk_gate_is_enabled+0x0/0x28
> > > [    9.743426] LR is at stm32f4_pll_div_set_rate+0xf/0x38
> > > [    9.748857] pc : [<0011e4be>]    lr : [<0011f9e3>]    psr: 0100000b
> > > [    9.755373] sp : 00bc7be0  ip : 00000000  fp : 001f3ac4
> > > [    9.760812] r10: 002610d0  r9 : 01efe920  r8 : 00540560
> > > [    9.766269] r7 : 02e7ddb0  r6 : 0173eed8  r5 : 00000000  r4 : 004027c0
> > > [    9.773081] r3 : 0011e4bf  r2 : 02e7ddb0  r1 : 0173eed8  r0 : 1d3267b8
> > > [    9.779911] xPSR: 0100000b
> > > [    9.782719] CPU: 0 PID: 49 Comm: sh Not tainted 5.13.0-rc5 #9
> > > [    9.788791] Hardware name: STM32 (Device Tree Support)
> > > [    9.794120] [<0000afa1>] (unwind_backtrace) from [<0000a33f>] (show_stack+0xb/0xc)
> > > [    9.802421] [<0000a33f>] (show_stack) from [<0000a8df>] (__invalid_entry+0x4b/0x4c)
> > >
> > > The `pll_num' field in the post_div_data configuration contained a wrong
> > > value which also referenced an uninitialized hardware clock when
> > > clk_register_pll_div() was called.
> > >
> > > Fixes: 517633ef630e ("clk: stm32f4: Add post divisor for I2S & SAI PLLs")
> > > Signed-off-by: Dario Binacchi <dariobin at libero.it>
> > > Reviewed-by: Gabriel Fernandez <gabriel.fernandez at st.com>
> > >
> > > ---
> > > I added Gabriel Fernandez's 'Reviewed-by' tag as requested by himself
> > > 15 days ago at https://lore.kernel.org/patchwork/patch/1450964/.
> > >
> > > Changes in v4:
> > > - Really add Gabriel Fernandez 'Reviewed-by' tag. In version 3 I forgot
> > >   to add the tag.
> > >
> > > Changes in v3:
> > > - Add Gabriel Fernandez 'Reviewed-by' tag.
> > >
> > > Changes in v2:
> > > - Change  'u8 pll_num' from 'stm32f4_pll_post_div_data' structure into
> > >   'int pll_idx'.
> > >
> > >  drivers/clk/clk-stm32f4.c | 10 +++++-----
> > >  1 file changed, 5 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
> > > index 18117ce5ff85..5c75e3d906c2 100644
> > > --- a/drivers/clk/clk-stm32f4.c
> > > +++ b/drivers/clk/clk-stm32f4.c
> > > @@ -526,7 +526,7 @@ struct stm32f4_pll {
> > >
> > >  struct stm32f4_pll_post_div_data {
> > >         int idx;
> > > -       u8 pll_num;
> > > +       int pll_idx;
> > >         const char *name;
> > >         const char *parent;
> > >         u8 flag;
> > > @@ -557,13 +557,13 @@ static const struct clk_div_table post_divr_table[] = {
> > >
> > >  #define MAX_POST_DIV 3
> > >  static const struct stm32f4_pll_post_div_data  post_div_data[MAX_POST_DIV] = {
> > > -       { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q",
> > > +       { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q",
> > >                 CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL},
> > >
> > > -       { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q",
> > > +       { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q",
> > >                 CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL },
> > >
> > > -       { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
> > > +       { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
> > >                 STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table },
> > >  };
> > >
> > > @@ -1774,7 +1774,7 @@ static void __init stm32f4_rcc_init(struct device_node *np)
> > >                                 post_div->width,
> > >                                 post_div->flag_div,
> > >                                 post_div->div_table,
> > > -                               clks[post_div->pll_num],
> > > +                               clks[post_div->pll_idx],
> > >                                 &stm32f4_clk_lock);
> > >
> > >                 if (post_div->idx != NO_IDX)
> > > --
> > > 2.17.1
> > >


From catalin.marinas at arm.com  Sun Aug  1 08:23:12 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Sun, 1 Aug 2021 08:23:12 -0700
Subject: [PATCH v2 1/3] vmalloc: Choose a better start address in
 vm_area_register_early()
In-Reply-To: <20210720025105.103680-2-wangkefeng.wang@huawei.com>
References: <20210720025105.103680-1-wangkefeng.wang@huawei.com>
 <20210720025105.103680-2-wangkefeng.wang@huawei.com>
Message-ID: <20210801152311.GB28489@arm.com>

On Tue, Jul 20, 2021 at 10:51:03AM +0800, Kefeng Wang wrote:
> There are some fixed locations in the vmalloc area be reserved
> in ARM(see iotable_init()) and ARM64(see map_kernel()), but for
> pcpu_page_first_chunk(), it calls vm_area_register_early() and
> choose VMALLOC_START as the start address of vmap area which
> could be conflicted with above address, then could trigger a
> BUG_ON in vm_area_add_early().
> 
> Let's choose the end of existing address range in vmlist as the
> start address instead of VMALLOC_START to avoid the BUG_ON.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  mm/vmalloc.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index d5cd52805149..a98cf97f032f 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -2238,12 +2238,14 @@ void __init vm_area_add_early(struct vm_struct *vm)
>   */
>  void __init vm_area_register_early(struct vm_struct *vm, size_t align)
>  {
> -	static size_t vm_init_off __initdata;
> +	unsigned long vm_start = VMALLOC_START;
> +	struct vm_struct *tmp;
>  	unsigned long addr;
>  
> -	addr = ALIGN(VMALLOC_START + vm_init_off, align);
> -	vm_init_off = PFN_ALIGN(addr + vm->size) - VMALLOC_START;
> +	for (tmp = vmlist; tmp; tmp = tmp->next)
> +		vm_start = (unsigned long)tmp->addr + tmp->size;
>  
> +	addr = ALIGN(vm_start, align);
>  	vm->addr = (void *)addr;
>  
>  	vm_area_add_early(vm);

Is there a risk of breaking other architectures? It doesn't look like to
me but I thought I'd ask.

Also, instead of always picking the end, could we search for a range
that fits?

-- 
Catalin


From catalin.marinas at arm.com  Sun Aug  1 08:53:13 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Sun, 1 Aug 2021 08:53:13 -0700
Subject: [PATCH v2 2/3] arm64: Support page mapping percpu first chunk
 allocator
In-Reply-To: <20210720025105.103680-3-wangkefeng.wang@huawei.com>
References: <20210720025105.103680-1-wangkefeng.wang@huawei.com>
 <20210720025105.103680-3-wangkefeng.wang@huawei.com>
Message-ID: <20210801155302.GA29188@arm.com>

On Tue, Jul 20, 2021 at 10:51:04AM +0800, Kefeng Wang wrote:
> Percpu embedded first chunk allocator is the firstly option, but it
> could fails on ARM64, eg,
>   "percpu: max_distance=0x5fcfdc640000 too large for vmalloc space 0x781fefff0000"
>   "percpu: max_distance=0x600000540000 too large for vmalloc space 0x7dffb7ff0000"
>   "percpu: max_distance=0x5fff9adb0000 too large for vmalloc space 0x5dffb7ff0000"
> 
> then we could meet "WARNING: CPU: 15 PID: 461 at vmalloc.c:3087 pcpu_get_vm_areas+0x488/0x838",
> even the system could not boot successfully.
> 
> Let's implement page mapping percpu first chunk allocator as a fallback
> to the embedding allocator to increase the robustness of the system.

It looks like x86, powerpc and sparc implement their own
setup_per_cpu_areas(). I had a quick look on finding some commonalities
but I think it's a lot more hassle to make a generic version out of them
(powerpc looks the simplest though). I think we could add a generic
variant with the arm64 support and later migrate other architectures to
it if possible.

The patch looks ok to me otherwise but I'd need an ack from Greg as it
touches drivers/.

BTW, do we need something similar for the non-NUMA
setup_per_cpu_areas()? I can see this patch only enables
NEED_PER_CPU_PAGE_FIRST_CHUNK if NUMA.

Leaving the rest of the patch below for Greg.

> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  arch/arm64/Kconfig       |  4 ++
>  drivers/base/arch_numa.c | 82 +++++++++++++++++++++++++++++++++++-----
>  2 files changed, 76 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b5b13a932561..eacb5873ded1 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1045,6 +1045,10 @@ config NEED_PER_CPU_EMBED_FIRST_CHUNK
>  	def_bool y
>  	depends on NUMA
>  
> +config NEED_PER_CPU_PAGE_FIRST_CHUNK
> +	def_bool y
> +	depends on NUMA
> +
>  source "kernel/Kconfig.hz"
>  
>  config ARCH_SPARSEMEM_ENABLE
> diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
> index 4cc4e117727d..563b2013b75a 100644
> --- a/drivers/base/arch_numa.c
> +++ b/drivers/base/arch_numa.c
> @@ -14,6 +14,7 @@
>  #include <linux/of.h>
>  
>  #include <asm/sections.h>
> +#include <asm/pgalloc.h>
>  
>  struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
>  EXPORT_SYMBOL(node_data);
> @@ -168,22 +169,83 @@ static void __init pcpu_fc_free(void *ptr, size_t size)
>  	memblock_free_early(__pa(ptr), size);
>  }
>  
> +#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
> +static void __init pcpu_populate_pte(unsigned long addr)
> +{
> +	pgd_t *pgd = pgd_offset_k(addr);
> +	p4d_t *p4d;
> +	pud_t *pud;
> +	pmd_t *pmd;
> +
> +	p4d = p4d_offset(pgd, addr);
> +	if (p4d_none(*p4d)) {
> +		pud_t *new;
> +
> +		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
> +		if (!new)
> +			goto err_alloc;
> +		p4d_populate(&init_mm, p4d, new);
> +	}
> +
> +	pud = pud_offset(p4d, addr);
> +	if (pud_none(*pud)) {
> +		pmd_t *new;
> +
> +		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
> +		if (!new)
> +			goto err_alloc;
> +		pud_populate(&init_mm, pud, new);
> +	}
> +
> +	pmd = pmd_offset(pud, addr);
> +	if (!pmd_present(*pmd)) {
> +		pte_t *new;
> +
> +		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
> +		if (!new)
> +			goto err_alloc;
> +		pmd_populate_kernel(&init_mm, pmd, new);
> +	}
> +
> +	return;
> +
> +err_alloc:
> +	panic("%s: Failed to allocate %lu bytes align=%lx from=%lx\n",
> +	      __func__, PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
> +}
> +#endif
> +
>  void __init setup_per_cpu_areas(void)
>  {
>  	unsigned long delta;
>  	unsigned int cpu;
> -	int rc;
> +	int rc = -EINVAL;
> +
> +	if (pcpu_chosen_fc != PCPU_FC_PAGE) {
> +		/*
> +		 * Always reserve area for module percpu variables.  That's
> +		 * what the legacy allocator did.
> +		 */
> +		rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
> +					    PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
> +					    pcpu_cpu_distance,
> +					    pcpu_fc_alloc, pcpu_fc_free);
> +#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
> +		if (rc < 0)
> +			pr_warn("PERCPU: %s allocator failed (%d), falling back to page size\n",
> +				   pcpu_fc_names[pcpu_chosen_fc], rc);
> +#endif
> +	}
>  
> -	/*
> -	 * Always reserve area for module percpu variables.  That's
> -	 * what the legacy allocator did.
> -	 */
> -	rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
> -				    PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
> -				    pcpu_cpu_distance,
> -				    pcpu_fc_alloc, pcpu_fc_free);
> +#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
> +	if (rc < 0)
> +		rc = pcpu_page_first_chunk(PERCPU_MODULE_RESERVE,
> +					   pcpu_fc_alloc,
> +					   pcpu_fc_free,
> +					   pcpu_populate_pte);
> +#endif
>  	if (rc < 0)
> -		panic("Failed to initialize percpu areas.");
> +		panic("Failed to initialize percpu areas (err=%d).", rc);
>  
>  	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
>  	for_each_possible_cpu(cpu)
> -- 
> 2.26.2


From romain.perier at gmail.com  Sun Aug  1 09:09:18 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  1 Aug 2021 18:09:18 +0200
Subject: [PATCH v2 0/3] Add RTC for MStar SoCs
Message-ID: <20210801160921.233081-1-romain.perier@gmail.com>

This patches series adds a new driver for the RTC found in the Mstar
MSC313e SoCs and newer. It adds a basic rtc driver, the corresponding
devicetree bindings and its documentation.

The rtctest (from selftests) has been passed on this driver, with the
following output:
$ rtctest 
TAP version 13
1..7
# Starting 7 tests from 2 test cases.
#  RUN           rtc.date_read ...
# rtctest.c:47:date_read:Current RTC date/time is 01/01/1970 00:02:03.
#            OK  rtc.date_read
ok 1 rtc.date_read
#  RUN           rtc.uie_read ...
#            OK  rtc.uie_read
ok 2 rtc.uie_read
#  RUN           rtc.uie_select ...
#            OK  rtc.uie_select
ok 3 rtc.uie_select
#  RUN           rtc.alarm_alm_set ...
# rtctest.c:136:alarm_alm_set:Alarm time now set to 00:02:12.
# rtctest.c:156:alarm_alm_set:data: 1a0
#            OK  rtc.alarm_alm_set
ok 4 rtc.alarm_alm_set
#  RUN           rtc.alarm_wkalm_set ...
# rtctest.c:192:alarm_wkalm_set:Alarm time now set to 01/01/1970 00:02:15.
#            OK  rtc.alarm_wkalm_set
ok 5 rtc.alarm_wkalm_set
#  RUN           rtc.alarm_alm_set_minute ...
# rtctest.c:238:alarm_alm_set_minute:Alarm time now set to 00:03:00.
# rtctest.c:258:alarm_alm_set_minute:data: 1a0
#            OK  rtc.alarm_alm_set_minute
ok 6 [  180.545015] random: fast init done
rtc.alarm_alm_set_minute
#  RUN           rtc.alarm_wkalm_set_minute ...
# rtctest.c:294:alarm_wkalm_set_minute:Alarm time now set to 01/01/1970 00:04:00.
#            OK  rtc.alarm_wkalm_set_minute
ok 7 rtc.alarm_wkalm_set_minute
# PASSED: 7 / 7 tests passed.
# Totals: pass:7 fail:0 xfail:0 xpass:0 skip:0 error:0


Changes since v1:
- Fixed the DT bindings documentation and fixed dt_binding_check (an
  include was missing)
- Added || COMPILE_TEST to kconfig
- Removed rtc_valid_tm from msc313_rtc_read_time()
- Removed the last write of the msc313_rtc_set_time() function (not
  required) and improved comments
- Replaced the relaxed io by normal io in msc313_rtc_interrupt()
- Added checks to be sure that the alarm fired in msc313_rtc_interrupt()
- Removed msc313_rtc_remove() (replaced by devm_add_action_or_reset)
- Removed unnecessary software reset of the IP in the probe function
  (the soft reset is never executed, it is a mistake from the initial
  refactoring)
- Switched to devm_rtc_allocate_device() and devm_rtc_register_device(),
  and dropped the error message related to the rtc device allocation
- Added an RTC range by setting .range_min and .range_max
- Added the "start-year" property to the DT bindings documentation


Daniel Palmer (1):
  rtc: Add support for the MSTAR MSC313 RTC

Romain Perier (2):
  dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings
    documentation
  ARM: dts: mstar: Add rtc device node

 .../bindings/rtc/mstar,msc313-rtc.yaml        |  49 ++++
 MAINTAINERS                                   |   1 +
 arch/arm/boot/dts/mstar-v7.dtsi               |   7 +
 drivers/rtc/Kconfig                           |  10 +
 drivers/rtc/Makefile                          |   1 +
 drivers/rtc/rtc-msc313.c                      | 246 ++++++++++++++++++
 6 files changed, 314 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
 create mode 100644 drivers/rtc/rtc-msc313.c

-- 
2.30.2



From romain.perier at gmail.com  Sun Aug  1 09:09:19 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  1 Aug 2021 18:09:19 +0200
Subject: [PATCH v2 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree
 bindings documentation
In-Reply-To: <20210801160921.233081-1-romain.perier@gmail.com>
References: <20210801160921.233081-1-romain.perier@gmail.com>
Message-ID: <20210801160921.233081-2-romain.perier@gmail.com>

This adds the documentation for the devicetree bindings of the Mstar
MSC313e RTC driver, found from MSC313e SoCs and newer.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 .../bindings/rtc/mstar,msc313-rtc.yaml        | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml

diff --git a/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
new file mode 100644
index 000000000000..62bc12b1feb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/mstar,msc313-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mstar MSC313e RTC Device Tree Bindings
+
+allOf:
+  - $ref: "rtc.yaml#"
+
+maintainers:
+  - Daniel Palmer <daniel at 0x0f.com>
+  - Romain Perier <romain.perier at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mstar,msc313-rtc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  start-year: true
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    rtc at 2400 {
+        compatible = "mstar,msc313-rtc";
+        reg = <0x2400 0x40>;
+        clocks = <&xtal_div2>;
+        interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+    };
+...
-- 
2.30.2



From romain.perier at gmail.com  Sun Aug  1 09:09:20 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  1 Aug 2021 18:09:20 +0200
Subject: [PATCH v2 2/3] rtc: Add support for the MSTAR MSC313 RTC
In-Reply-To: <20210801160921.233081-1-romain.perier@gmail.com>
References: <20210801160921.233081-1-romain.perier@gmail.com>
Message-ID: <20210801160921.233081-3-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

This adds support for the RTC block on the Mstar MSC313e SoCs and newer.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Co-developed-by: Romain Perier <romain.perier at gmail.com>
Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 MAINTAINERS              |   1 +
 drivers/rtc/Kconfig      |  10 ++
 drivers/rtc/Makefile     |   1 +
 drivers/rtc/rtc-msc313.c | 246 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 258 insertions(+)
 create mode 100644 drivers/rtc/rtc-msc313.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c9467d2839f5..bff16c7bafb8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2220,6 +2220,7 @@ F:	arch/arm/boot/dts/mstar-*
 F:	arch/arm/mach-mstar/
 F:	drivers/clk/mstar/
 F:	drivers/gpio/gpio-msc313.c
+F:	drivers/rtc/rtc-msc313.c
 F:	drivers/watchdog/msc313e_wdt.c
 F:	include/dt-bindings/clock/mstar-*
 F:	include/dt-bindings/gpio/msc313-gpio.h
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 12153d5801ce..9ce4baab5fcf 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1925,4 +1925,14 @@ config RTC_DRV_WILCO_EC
 	  This can also be built as a module. If so, the module will
 	  be named "rtc_wilco_ec".
 
+config RTC_DRV_MSC313
+	tristate "MStar MSC313 RTC"
+        depends on ARCH_MSTARV7 || COMPILE_TEST
+	help
+	  If you say yes here you get support for the Mstar MSC313e On-Chip
+	  Real Time Clock.
+
+	  This driver can also be built as a module, if so, the module
+	  will be called "rtc-msc313".
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2dd0dd956b0e..5efda8a60cee 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_RTC_DRV_MCP795)	+= rtc-mcp795.o
 obj-$(CONFIG_RTC_DRV_MESON)	+= rtc-meson.o
 obj-$(CONFIG_RTC_DRV_MOXART)	+= rtc-moxart.o
 obj-$(CONFIG_RTC_DRV_MPC5121)	+= rtc-mpc5121.o
+obj-$(CONFIG_RTC_DRV_MSC313)	+= rtc-msc313.o
 obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
 obj-$(CONFIG_RTC_DRV_MT2712)	+= rtc-mt2712.o
 obj-$(CONFIG_RTC_DRV_MT6397)	+= rtc-mt6397.o
diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c
new file mode 100644
index 000000000000..f7b9fd2807cb
--- /dev/null
+++ b/drivers/rtc/rtc-msc313.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.
+ * Based on "Real Time Clock driver for msb252x." that was contained
+ * in various MStar kernels.
+ *
+ * (C) 2019 Daniel Palmer
+ * (C) 2021 Romain Perier
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* Registers */
+#define REG_RTC_CTRL		0x00
+#define REG_RTC_FREQ_CW_L	0x04
+#define REG_RTC_FREQ_CW_H	0x08
+#define REG_RTC_LOAD_VAL_L	0x0C
+#define REG_RTC_LOAD_VAL_H	0x10
+#define REG_RTC_MATCH_VAL_L	0x14
+#define REG_RTC_MATCH_VAL_H	0x18
+#define REG_RTC_STATUS_INT	0x1C
+#define REG_RTC_CNT_VAL_L	0x20
+#define REG_RTC_CNT_VAL_H	0x24
+
+/* Control bits for REG_RTC_CTRL */
+#define SOFT_RSTZ_BIT		BIT(0)
+#define CNT_EN_BIT		BIT(1)
+#define WRAP_EN_BIT		BIT(2)
+#define LOAD_EN_BIT		BIT(3)
+#define READ_EN_BIT		BIT(4)
+#define INT_MASK_BIT		BIT(5)
+#define INT_FORCE_BIT		BIT(6)
+#define INT_CLEAR_BIT		BIT(7)
+
+/* Control bits for REG_RTC_STATUS_INT */
+#define RAW_INT_BIT		BIT(0)
+#define ALM_INT_BIT		BIT(1)
+
+struct msc313_rtc {
+	struct rtc_device *rtc_dev;
+	void __iomem *rtc_base;
+	struct clk *clk;
+};
+
+static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+
+	seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)
+			| (readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);
+
+	rtc_time64_to_tm(seconds, &alarm->time);
+
+	if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))
+		alarm->enabled = 1;
+
+	return 0;
+}
+
+static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	if (enabled)
+		reg &= ~INT_MASK_BIT;
+	else
+		reg |= INT_MASK_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+	return 0;
+}
+
+static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+
+	seconds = rtc_tm_to_time64(&alarm->time);
+	writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);
+	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);
+
+	msc313_rtc_alarm_irq_enable(dev, alarm->enabled);
+
+	return 0;
+}
+
+static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	u32 seconds;
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
+
+	/* Wait for HW latch done */
+	while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)
+		udelay(1);
+
+	seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)
+			| (readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);
+
+	rtc_time64_to_tm(seconds, tm);
+
+	return 0;
+}
+
+static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+	u16 reg;
+
+	seconds = rtc_tm_to_time64(tm);
+	writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);
+	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);
+
+	/* Enable load for loading value into internal RTC counter */
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
+
+	/* Wait for HW latch done */
+	while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
+		udelay(1);
+	return 0;
+}
+
+static const struct rtc_class_ops msc313_rtc_ops = {
+	.read_time = msc313_rtc_read_time,
+	.set_time = msc313_rtc_set_time,
+	.read_alarm = msc313_rtc_read_alarm,
+	.set_alarm = msc313_rtc_set_alarm,
+	.alarm_irq_enable = msc313_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev_id);
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);
+	if (!(reg & ALM_INT_BIT))
+		return IRQ_NONE;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	reg |= INT_CLEAR_BIT;
+	reg &= ~INT_FORCE_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+
+	rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static int msc313_rtc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct msc313_rtc *priv;
+	int ret;
+	int irq;
+	unsigned long rate;
+	u16 reg;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->rtc_base))
+		return PTR_ERR(priv->rtc_base);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return -EINVAL;
+
+	priv->rtc_dev = devm_rtc_allocate_device(dev);
+	if (IS_ERR(priv->rtc_dev))
+		return PTR_ERR(priv->rtc_dev);
+
+	priv->rtc_dev->ops = &msc313_rtc_ops;
+	priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000;
+	priv->rtc_dev->range_max = U32_MAX - 1; /* 2106-02-07 06:28:14 */
+
+	ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
+			       dev_name(&pdev->dev), &pdev->dev);
+	if (ret) {
+		dev_err(dev, "Could not request IRQ\n");
+		return ret;
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "No input reference clock\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, priv->clk);
+	if (ret)
+		return ret;
+
+	rate = clk_get_rate(priv->clk);
+	writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
+	writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	reg |= CNT_EN_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_rtc_register_device(priv->rtc_dev);
+}
+
+static const struct of_device_id msc313_rtc_of_match_table[] = {
+	{ .compatible = "mstar,msc313-rtc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ms_rtc_of_match_table);
+
+static struct platform_driver msc313_rtc_driver = {
+	.probe = msc313_rtc_probe,
+	.driver = {
+		.name = "msc313-rtc",
+		.of_match_table = msc313_rtc_of_match_table,
+	},
+};
+
+module_platform_driver(msc313_rtc_driver);
+
+MODULE_AUTHOR("Daniel Palmer <daniel at thingy.jp>");
+MODULE_AUTHOR("Romain Perier <romain.perier at gmail.com>");
+MODULE_DESCRIPTION("MStar RTC Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.30.2



From romain.perier at gmail.com  Sun Aug  1 09:09:21 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  1 Aug 2021 18:09:21 +0200
Subject: [PATCH v2 3/3] ARM: dts: mstar: Add rtc device node
In-Reply-To: <20210801160921.233081-1-romain.perier@gmail.com>
References: <20210801160921.233081-1-romain.perier@gmail.com>
Message-ID: <20210801160921.233081-4-romain.perier@gmail.com>

This adds the definition of the rtc device node. The RTC being able to
work with the oscillator at 12Mhz for now, it shares the same xtal than
the watchdog.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 982dba9d28eb..1d4419aee67d 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -116,6 +116,13 @@ watchdog at 6000 {
 				clocks = <&xtal_div2>;
 			};
 
+			rtc at 2400 {
+				compatible = "mstar,msc313-rtc";
+				reg = <0x2400 0x40>;
+				clocks = <&xtal_div2>;
+				interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
 			intc_fiq: interrupt-controller at 201310 {
 				compatible = "mstar,mst-intc";
 				reg = <0x201310 0x40>;
-- 
2.30.2



From ardb at kernel.org  Sun Aug  1 09:26:06 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sun, 1 Aug 2021 18:26:06 +0200
Subject: [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver
In-Reply-To: <20210731204845.21196-1-andre.przywara@arm.com>
References: <20210731204845.21196-1-andre.przywara@arm.com>
Message-ID: <CAMj1kXHakwfDoAqBL_KbRHbKuF=sJ2ug-cCqYxRUQhCqzcXn9w@mail.gmail.com>

On Sat, 31 Jul 2021 at 22:49, Andre Przywara <andre.przywara at arm.com> wrote:
>
> The "Arm True Random Number Generator Firmware Interface"[1] provides
> an SMCCC based interface to a true hardware random number generator.
> So far we are using that in arch_get_random_seed(), but it might be
> useful to expose the entropy through the /dev/hwrng device as well. This
> allows to assess the quality of the implementation, by using "rngtest"
> from the rng-tools package, for example.
>
> Patch 1 creates a platform device, triggered by the previous discovery
> of the SMCCC TRNG service.
> Patch 2 implements a hw_random platform driver, which is instantiated
> through this said platform device.
>
> The driver can be loaded as module, or built into the kernel.
>
> [1] https://developer.arm.com/documentation/den0098/latest/
>
> Changelog v3 ... v4:
> - drop pointless driver loading message
> - drop unneeded init() routine
>
> Changelog v2 ... v3:
> - split platform device and driver
>
> Changelog v1 ... v2:
> - fix building as a module
> - de-register device upon exit
> - mention module name in Kconfig
>
> Andre Przywara (2):
>   firmware: smccc: Register smccc_trng platform device
>   hwrng: Add Arm SMCCC TRNG based driver
>

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>


>  drivers/char/hw_random/Kconfig          |  14 +++
>  drivers/char/hw_random/Makefile         |   1 +
>  drivers/char/hw_random/arm_smccc_trng.c | 123 ++++++++++++++++++++++++
>  drivers/firmware/smccc/smccc.c          |  17 ++++
>  4 files changed, 155 insertions(+)
>  create mode 100644 drivers/char/hw_random/arm_smccc_trng.c
>
> --
> 2.17.6
>


From ardb at kernel.org  Sun Aug  1 09:44:08 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sun, 1 Aug 2021 18:44:08 +0200
Subject: [PATCH 4/5] ARM: Add basic support for EcoNet EN7523 SoC
In-Reply-To: <CAK8P3a3OuJ3pMSdEA4Rt3aWvvuX2+_Bg5x7-kZ1++fvvJvgGxA@mail.gmail.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-5-bert@biot.com>
 <CAK8P3a3OuJ3pMSdEA4Rt3aWvvuX2+_Bg5x7-kZ1++fvvJvgGxA@mail.gmail.com>
Message-ID: <CAMj1kXFK+HoouMMBbHxEgm-zQqKa6QMS6keeZmhpXTc4FCy8fQ@mail.gmail.com>

On Fri, 30 Jul 2021 at 16:48, Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Fri, Jul 30, 2021 at 3:45 PM Bert Vermeulen <bert at biot.com> wrote:
> >
> > From: John Crispin <john at phrozen.org>
> >
> > EN7523 is an armv7 based silicon used inside broadband access type devices
> > such as xPON and xDSL. It shares various silicon blocks with MediaTek
> > silicon such as the MT7622.
> >
> > Signed-off-by: John Crispin <john at phrozen.org>
> > Signed-off-by: Bert Vermeulen <bert at biot.com>
>
> It's always nice to see a new SoC family.
>
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -580,6 +580,20 @@ config ARCH_VIRT
> >         select HAVE_ARM_ARCH_TIMER
> >         select ARCH_SUPPORTS_BIG_ENDIAN
> >
> > +config ARCH_ECONET
> > +       bool "Econet SoC Support"
> > +       depends on ARCH_MULTI_V7
> > +       select ARM_AMBA
> > +       select ARM_GIC
> > +       select ARM_GIC_V3
> > +       select ARM_DMA_USE_IOMMU
> > +       select ARM_PSCI
> > +       select HAVE_ARM_ARCH_TIMER
> > +       select IOMMU_DMA
> > +       select COMMON_CLK
> > +       help
> > +         Support for Econet EN7523 SoCs
>
> Given how closely related this probably is to MT7623/MT7622, should this
> perhaps just be part of arch/arm/mach-mediatek? According to
> https://wikidevi.wi-cat.ru/MediaTek#xPON, the older (mips based) MT752x
> chips are apparently just rebranded to EN752x after the business unit
> was spun off, but I guess they are still in the same family.
>
> > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > index 173da685a52e..1bff0aa29c07 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -152,6 +152,7 @@ textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
> >  textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
> >  textofs-$(CONFIG_ARCH_MESON) := 0x00208000
> >  textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
> > +textofs-$(CONFIG_ARCH_ECONET) := 0x00088000
>
> Why is this needed?
>
> Note also the comment directly above it exlaining
> # Text offset. This list is sorted numerically by address in order to
> # provide a means to avoid/resolve conflicts in multi-arch kernels.
>

Yes, please drop this - it is a horrible hack and it's already quite
disappointing that we are stuck with it for the foreseeable future.

So I assume the purpose of this is to protect the first 128k of DRAM
to be protected from being overwritten by the decompressor?

It would be best to move this reserved region elsewhere, but I can
understand that this is no longer an option. So the alternatives are
- omit this window from the /memory node, and rely on Geert's recent
decompressor changes which make it discover the usable memory from the
DT, or
- better would be to use a /memreserve/ here (which you may already
have?), and teach the newly added decompressor code to take those into
account when choosing the target window for decompressing the kernel.

--
Ard.


From maz at kernel.org  Sun Aug  1 11:59:24 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 01 Aug 2021 19:59:24 +0100
Subject: [PATCH] ARM: dts: ixp4xx: Add a devicetree for Freecom FSG-3
In-Reply-To: <YQan0ALPnn4aBM7y@lunn.ch>
References: <20210729144128.2834328-1-linus.walleij@linaro.org>
 <87tuk91er6.wl-maz@kernel.org> <YQan0ALPnn4aBM7y@lunn.ch>
Message-ID: <87sfzt0z5f.wl-maz@kernel.org>

Hi Andrew,

On Sun, 01 Aug 2021 14:55:28 +0100,
Andrew Lunn <andrew at lunn.ch> wrote:
> 
> On Sun, Aug 01, 2021 at 02:22:21PM +0100, Marc Zyngier wrote:
> 
> > The switch works *sometimes*, but I haven't
> > worked out whether it needs some special care or it is broken.
> 
> Hi Marc
> 
> The driver exports the file "registers" in /sysfs. Do you see any sort
> of application/driver running in userspace which might be talking to
> the switch?

Hmmm. Which driver? I don't see any switch-related driver, nor any
userspace (what I have is an extremely minimal OpenWRT userspace that
has hardly more than busybox).

This is all I see:

root at OpenWrt:/# find /sys -name registers
/sys/kernel/debug/usb/ohci/0000:00:0e.1/registers
/sys/kernel/debug/usb/ohci/0000:00:0e.0/registers
/sys/kernel/debug/regmap/dummy-bus at c4000000/registers

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From dariobin at libero.it  Sun Aug  1 12:37:10 2021
From: dariobin at libero.it (Dario Binacchi)
Date: Sun, 1 Aug 2021 21:37:10 +0200 (CEST)
Subject: [RESEND PATCH v4] clk: stm32f4: fix post divisor setup for
 I2S/SAI PLLs
In-Reply-To: <CAPTRvH=R822osk86tRJqJCPNYY85t8t90+HJWcz43iASbcg2Jw@mail.gmail.com>
References: <20210725160725.10788-1-dariobin@libero.it>
 <CAPTRvHkf0cK_4ZidM17rPo99gWDmxgqFt4CDUjqFFwkOeQeFDg@mail.gmail.com>
 <1926284813.753014.1627553002984@mail1.libero.it>
 <CAPTRvH=R822osk86tRJqJCPNYY85t8t90+HJWcz43iASbcg2Jw@mail.gmail.com>
Message-ID: <1371790418.70998.1627846630234@mail1.libero.it>

Hi Dillon and Stephen,

> Il 01/08/2021 16:56 Dillon Hua <dillonhua at gmail.com> ha scritto:
> 
>  
> Hi Dario
> 
> On Thu, Jul 29, 2021 at 6:03 PM Dario Binacchi <dariobin at libero.it> wrote:
> >
> > Hi Dillon,
> >
> > > Il 28/07/2021 12:03 Dillon Hua <dillonhua at gmail.com> ha scritto:
> > >
> > >
> > > Hi Dario,
> > >
> > > I have a similar patch [1] submitted last year.
> > > Unfortunately, it did not get accepted by the maintainer.
> > >
> > > Just a reminder here for you, should remove
> > >
> > > { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
> >
> > Thank you for your suggestion.
> > While testing the patch on the stm32f469-disco board I didn't
> > notice the white screen issue. I'll try to run the tests again.
> > I will let you know.
> 
> Thanks, be sure clk_ignore_unused is not set from the kernel cmdline
> at your test.

This is the kernel command line of my tests:
console=ttySTM0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext2 rootwait earlyprintk consoleblank=0 ignore_loglevel

In previous emails I forgot to mention that the patch was in turn applied to a buildroot patch [1] and
acked by Christophe Priouzeau of ST microelectronics. However, I rerun the tests and did not notice
anything strange.

I then enabled CONFIG_VT, CONFIG_FRAMEBUFFER_CONSOLE and CONFIG_LOGO, and indedd the command
'echo Dario >/dev/tty0' prints my name on the display only by removing
{STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div"}.

As said in a previous email to Stephen, the patch I submitted fixes commit 517633ef630e
("clk: stm32f4: Add post divisor for I2S & SAI PLLs"), so IMHO it should not be dropped from the tree.
What Dillon suggested should instead be fixed by another patch.

Waiting for your opinion,
Thanks and regards,
Dario

[1] https://patchwork.ozlabs.org/project/buildroot/patch/20210716164243.17988-1-dariobin at libero.it/


> 
> Best Regards
> Dillon
> 
> >
> > Thanks and regards,
> > Dario
> >
> > >
> > > from stm32{f429, f469, f746, f769}_gates[]; or else
> > > run into white screen after the kernel enters the console.
> > >
> > > This patch was verified by Patrice Chotard, you can
> > > find  the history from [2].
> > >
> > > Hope you can help to submit a patch to include [2], thanks.
> > >
> > > [1]
> > > https://lore.kernel.org/linux-arm-kernel/1590564453-24499-7-git-send-email-dillon.minfei at gmail.com/
> > > https://lore.kernel.org/linux-arm-kernel/1590564453-24499-6-git-send-email-dillon.minfei at gmail.com/
> > >
> > > resend this year:
> > > https://lore.kernel.org/lkml/1590378348-8115-6-git-send-email-dillon.minfei at gmail.com/
> > >
> > > [2]
> > > https://lore.kernel.org/lkml/6915fa2a-e211-476f-8317-6825e280c322 at foss.st.com/
> > >
> > > Thanks
> > > Best Regards
> > >
> > > Dillon
> > >
> > > On Mon, Jul 26, 2021 at 12:08 AM Dario Binacchi <dariobin at libero.it> wrote:
> > > >
> > > > Enabling the framebuffer leads to a system hang. Running, as a debug
> > > > hack, the store_pan() function in drivers/video/fbdev/core/fbsysfs.c
> > > > without taking the console_lock, allows to see the crash backtrace on
> > > > the serial line.
> > > >
> > > > ~ # echo 0 0 > /sys/class/graphics/fb0/pan
> > > >
> > > > [    9.719414] Unhandled exception: IPSR = 00000005 LR = fffffff1
> > > > [    9.726937] CPU: 0 PID: 49 Comm: sh Not tainted 5.13.0-rc5 #9
> > > > [    9.733008] Hardware name: STM32 (Device Tree Support)
> > > > [    9.738296] PC is at clk_gate_is_enabled+0x0/0x28
> > > > [    9.743426] LR is at stm32f4_pll_div_set_rate+0xf/0x38
> > > > [    9.748857] pc : [<0011e4be>]    lr : [<0011f9e3>]    psr: 0100000b
> > > > [    9.755373] sp : 00bc7be0  ip : 00000000  fp : 001f3ac4
> > > > [    9.760812] r10: 002610d0  r9 : 01efe920  r8 : 00540560
> > > > [    9.766269] r7 : 02e7ddb0  r6 : 0173eed8  r5 : 00000000  r4 : 004027c0
> > > > [    9.773081] r3 : 0011e4bf  r2 : 02e7ddb0  r1 : 0173eed8  r0 : 1d3267b8
> > > > [    9.779911] xPSR: 0100000b
> > > > [    9.782719] CPU: 0 PID: 49 Comm: sh Not tainted 5.13.0-rc5 #9
> > > > [    9.788791] Hardware name: STM32 (Device Tree Support)
> > > > [    9.794120] [<0000afa1>] (unwind_backtrace) from [<0000a33f>] (show_stack+0xb/0xc)
> > > > [    9.802421] [<0000a33f>] (show_stack) from [<0000a8df>] (__invalid_entry+0x4b/0x4c)
> > > >
> > > > The `pll_num' field in the post_div_data configuration contained a wrong
> > > > value which also referenced an uninitialized hardware clock when
> > > > clk_register_pll_div() was called.
> > > >
> > > > Fixes: 517633ef630e ("clk: stm32f4: Add post divisor for I2S & SAI PLLs")
> > > > Signed-off-by: Dario Binacchi <dariobin at libero.it>
> > > > Reviewed-by: Gabriel Fernandez <gabriel.fernandez at st.com>
> > > >
> > > > ---
> > > > I added Gabriel Fernandez's 'Reviewed-by' tag as requested by himself
> > > > 15 days ago at https://lore.kernel.org/patchwork/patch/1450964/.
> > > >
> > > > Changes in v4:
> > > > - Really add Gabriel Fernandez 'Reviewed-by' tag. In version 3 I forgot
> > > >   to add the tag.
> > > >
> > > > Changes in v3:
> > > > - Add Gabriel Fernandez 'Reviewed-by' tag.
> > > >
> > > > Changes in v2:
> > > > - Change  'u8 pll_num' from 'stm32f4_pll_post_div_data' structure into
> > > >   'int pll_idx'.
> > > >
> > > >  drivers/clk/clk-stm32f4.c | 10 +++++-----
> > > >  1 file changed, 5 insertions(+), 5 deletions(-)
> > > >
> > > > diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
> > > > index 18117ce5ff85..5c75e3d906c2 100644
> > > > --- a/drivers/clk/clk-stm32f4.c
> > > > +++ b/drivers/clk/clk-stm32f4.c
> > > > @@ -526,7 +526,7 @@ struct stm32f4_pll {
> > > >
> > > >  struct stm32f4_pll_post_div_data {
> > > >         int idx;
> > > > -       u8 pll_num;
> > > > +       int pll_idx;
> > > >         const char *name;
> > > >         const char *parent;
> > > >         u8 flag;
> > > > @@ -557,13 +557,13 @@ static const struct clk_div_table post_divr_table[] = {
> > > >
> > > >  #define MAX_POST_DIV 3
> > > >  static const struct stm32f4_pll_post_div_data  post_div_data[MAX_POST_DIV] = {
> > > > -       { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q",
> > > > +       { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q",
> > > >                 CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL},
> > > >
> > > > -       { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q",
> > > > +       { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q",
> > > >                 CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL },
> > > >
> > > > -       { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
> > > > +       { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
> > > >                 STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table },
> > > >  };
> > > >
> > > > @@ -1774,7 +1774,7 @@ static void __init stm32f4_rcc_init(struct device_node *np)
> > > >                                 post_div->width,
> > > >                                 post_div->flag_div,
> > > >                                 post_div->div_table,
> > > > -                               clks[post_div->pll_num],
> > > > +                               clks[post_div->pll_idx],
> > > >                                 &stm32f4_clk_lock);
> > > >
> > > >                 if (post_div->idx != NO_IDX)
> > > > --
> > > > 2.17.1
> > > >


From tzimmermann at suse.de  Sun Aug  1 12:56:17 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Sun, 1 Aug 2021 21:56:17 +0200
Subject: [PATCH 00/14] drm: Make DRM's IRQ helpers legacy
In-Reply-To: <YQWbWjV5TYzp+5C4@ravnborg.org>
References: <20210727182721.17981-1-tzimmermann@suse.de>
 <YQWbWjV5TYzp+5C4@ravnborg.org>
Message-ID: <d50b3199-20fe-0ecb-ab7d-7425ad1d0f21@suse.de>

Hi Sam

Am 31.07.21 um 20:50 schrieb Sam Ravnborg:
> Hi Thomas,
> 
> On Tue, Jul 27, 2021 at 08:27:07PM +0200, Thomas Zimmermann wrote:
>> DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
>> the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
>> IRQ interfaces.
>>
>> DRM provides IRQ helpers for setting up, receiving and removing IRQ
>> handlers. It's an abstraction over plain Linux functions. The code
>> is mid-layerish with several callbacks to hook into the rsp drivers.
>> Old UMS driver have their interrupts enabled via ioctl, so these
>> abstractions makes some sense. Modern KMS manage all their interrupts
>> internally. Using the DRM helpers adds indirection without benefits.
>>
>> Most KMs drivers already use Linux IRQ functions instead of DRM's
>> abstraction layer. Patches 1 to 12 convert the remaining ones.
>> The patches also resolve a bug for devices without assigned interrupt
>> number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
>> not detect if the device has no interrupt assigned.
>>
>> Patch 13 removes an unused function.
>>
>> Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
>> the old non-KMS drivers still use the functionality.
>>
>> Thomas Zimmermann (14):
>>    drm/amdgpu: Convert to Linux IRQ interfaces
>>    drm/arm/hdlcd: Convert to Linux IRQ interfaces
>>    drm/atmel-hlcdc: Convert to Linux IRQ interfaces
>>    drm/fsl-dcu: Convert to Linux IRQ interfaces
>>    drm/gma500: Convert to Linux IRQ interfaces
>>    drm/kmb: Convert to Linux IRQ interfaces
>>    drm/msm: Convert to Linux IRQ interfaces
>>    drm/mxsfb: Convert to Linux IRQ interfaces
>>    drm/radeon: Convert to Linux IRQ interfaces
>>    drm/tidss: Convert to Linux IRQ interfaces
>>    drm/tilcdc: Convert to Linux IRQ interfaces
>>    drm/vc4: Convert to Linux IRQ interfaces
>>    drm: Remove unused devm_drm_irq_install()
>>    drm: IRQ midlayer is now legacy
> 
> With the irq_enabled confusion out of the way I want to re-address two
> issues here that I know you have answered but I am just not convinced.
> 
> 1) IRQ_NOTCONNECTED
> 
> We do not have this check in drm_irq today and we should avoid spreading
> it all over. We are either carrying it forever or we wil lsee patches
> floating in to drop the check again.
> The current use in the kernel is minimal:
> https://elixir.bootlin.com/linux/latest/A/ident/IRQ_NOTCONNECTED
> 
> So as a minimum drop it from atmel_hlcdc and preferably from the rest as
> it is really not used. (Speaking as atmel_hlcdc maintainer)

I'll drop it from atmel_hlcdc then.

But saying that it's not used is not correct. At least radeon an gma500 
handle PCI-based devices and BIOSes often had the option of disabling 
the rsp graphics interrupts.

> 
> 
> 2) devm_request_irq()
> 
> We are moving towards managed allocation so we do not fail to free
> resources. And an irq has a lifetime equal the device itself - so an
> obvious cnadidate for devm_request_irq.
> If we do not introduce it now we will see a revisit of this later.
> I can be convinced to wait with this as we will have to do much more in
> each driver, but I cannot see any good arguments to avoid the more
> modern way to use devm_request_irq.

I'll change this in atmel_hdlcd and maybe I can find trivial cases where 
devm_request_irq() can be used. But drivers that had an uninstall 
callback before should not have the cleanup logic altered by a patch as 
this one. I suspect that most of the IRQ cleanup
is actually a vblank cleanup and should be done in response to 
drm_vblank_init(). But that's again not something for this patchset 
here. We cannot change multiple things at once and still expect any of 
it to work.

I welcome the use of devm_ et al. But these changes are better done in a 
per-driver patchset that changes all of the driver to managed release.

Best regards
Thomas

> 
> 	Sam
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Felix Imend?rffer

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210801/ba69831f/attachment.sig>

From bilbao at vt.edu  Sun Aug  1 13:12:03 2021
From: bilbao at vt.edu (Carlos Bilbao)
Date: Sun, 1 Aug 2021 16:12:03 -0400
Subject: [PATCH v4.1] include: linux: Reorganize timekeeping and ktime headers
In-Reply-To: <202108010312.8uIaWK0u-lkp@intel.com>
References: <202108010312.8uIaWK0u-lkp@intel.com>
Message-ID: <3bdd5b29-b6a1-54a8-ac99-adb59e8e91a7@vt.edu>

Reorganize and separate the headers by making ktime.h take care of the 
ktime_get() family of functions, and reserve timekeeping.h for the actual 
timekeeping. This also helps to avoid implicit function errors and strengthens
the header dependencies, since timekeeping.h was using ktime_to_ns(), a static 
function defined in a header it does no include, ktime.h. Include the header 
timekeeping.h wherever it is necessary for a successful compilation after the 
header code reorganization.

Signed-off-by: Carlos Bilbao <bilbao at vt.edu>
Reported-by: kernel test robot <lkp at intel.com>
---
Changelog:
- v2: Add three more files that also needed a header update for x86: 
  pps_kernel.h, posix-timers.c and hda_controller.c
- v3: Cover build tests for other architectures than x86. To compile arm64, 
  update arch/arm64/kvm/hypercalls.c, include/linux/stmmac.h, and 
  drivers/rtc/class.c. No other arch/ seems to need fixes but to be on the safe
  side compiled arm, mips, powerpc, sparc, s390, riscv and i386.
- v4: 4.0 Fix kernel test robot warnings for ia64 and x86.
      4.1 Fix kernel test robot warnings for m68k and powerpc.
---
 arch/arm64/kvm/hypercalls.c    |   1 +
 arch/ia64/kernel/time.c        |   1 +
 arch/m68k/atari/time.c         |   1 +
 arch/m68k/hp300/time.c         |   2 +
 arch/m68k/mac/via.c            |   1 +
 arch/m68k/mvme16x/config.c     |   1 +
 arch/m68k/sun3/sun3ints.c      |   1 +
 arch/powerpc/kernel/time.c     |   1 +
 arch/x86/kernel/rtc.c          |   1 +
 arch/x86/kernel/tsc.c          |   1 +
 drivers/rtc/class.c            |   1 +
 include/linux/ktime.h          | 196 +++++++++++++++++++++++++++++++-
 include/linux/pps_kernel.h     |   1 +
 include/linux/sched_clock.h    |   2 +
 include/linux/stmmac.h         |   1 +
 include/linux/timekeeping.h    | 197 +--------------------------------
 init/main.c                    |   1 +
 kernel/time/ntp.c              |   1 +
 kernel/time/posix-timers.c     |   1 +
 kernel/time/tick-legacy.c      |   1 +
 kernel/time/time.c             |   1 +
 kernel/time/timekeeping.c      |   1 +
 sound/pci/hda/hda_controller.c |   1 +
 23 files changed, 218 insertions(+), 198 deletions(-)

diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 30da78f72b3b..41499c1d7379 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -3,6 +3,7 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/kvm_host.h>
+#include <linux/timekeeping.h>
 
 #include <asm/kvm_emulate.h>
 
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index fa9c0ab8c6fc..85e79ff3c98e 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/efi.h>
 #include <linux/timex.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/platform_device.h>
 #include <linux/sched/cputime.h>
 
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 7e44d0e9d0f8..b09d3ff40b36 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -19,6 +19,7 @@
 #include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/timekeeping.h>
 
 #include <asm/atariints.h>
 #include <asm/machdep.h>
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index 1d1b7b3b5dd4..56c575096bcb 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -14,6 +14,8 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
+
 #include <asm/machdep.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 3d11d6219cdd..6dd8f85288e4 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/irq.h>
+#include <linux/timekeeping.h>
 
 #include <asm/macintosh.h>
 #include <asm/macints.h>
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index b59593c7cfb9..bb2ae926bb17 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -28,6 +28,7 @@
 #include <linux/rtc.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/timekeeping.h>
 
 #include <asm/bootinfo.h>
 #include <asm/bootinfo-vme.h>
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 41ae422119d3..3834a172be47 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
 #include <asm/segment.h>
 #include <asm/intersil.h>
 #include <asm/oplib.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index e45ce427bffb..4b6952165a0a 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -55,6 +55,7 @@
 #include <linux/sched/cputime.h>
 #include <linux/sched/clock.h>
 #include <linux/processor.h>
+#include <linux/timekeeping.h>
 #include <asm/trace.h>
 
 #include <asm/interrupt.h>
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 586f718b8e95..98ea05cc6aeb 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -9,6 +9,7 @@
 #include <linux/export.h>
 #include <linux/pnp.h>
 #include <linux/of.h>
+#include <linux/timekeeping.h>
 
 #include <asm/vsyscall.h>
 #include <asm/x86_init.h>
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 2e076a459a0c..b730cb20f5fd 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -15,6 +15,7 @@
 #include <linux/timex.h>
 #include <linux/static_key.h>
 #include <linux/static_call.h>
+#include <linux/timekeeping.h>
 
 #include <asm/hpet.h>
 #include <asm/timer.h>
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index f77bc089eb6b..1bdf1f790beb 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 #include <linux/workqueue.h>
 
 #include "rtc-core.h"
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 73f20deb497d..37955d6664dd 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -229,6 +229,198 @@ static inline ktime_t ms_to_ktime(u64 ms)
 	return ms * NSEC_PER_MSEC;
 }
 
-# include <linux/timekeeping.h>
+/*
+ * ktime_get() family: read the current time in a multitude of ways,
+ *
+ * The default time reference is CLOCK_MONOTONIC, starting at
+ * boot time but not counting the time spent in suspend.
+ * For other references, use the functions with "real", "clocktai",
+ * "boottime" and "raw" suffixes.
+ *
+ * To get the time in a different format, use the ones wit
+ * "ns", "ts64" and "seconds" suffix.
+ *
+ * See Documentation/core-api/timekeeping.rst for more details.
+ */
 
-#endif
+
+/*
+ * timespec64 based interfaces
+ */
+extern void ktime_get_raw_ts64(struct timespec64 *ts);
+extern void ktime_get_ts64(struct timespec64 *ts);
+extern void ktime_get_real_ts64(struct timespec64 *tv);
+extern void ktime_get_coarse_ts64(struct timespec64 *ts);
+extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
+
+void getboottime64(struct timespec64 *ts);
+
+/*
+ * time64_t base interfaces
+ */
+extern time64_t ktime_get_seconds(void);
+extern time64_t __ktime_get_real_seconds(void);
+extern time64_t ktime_get_real_seconds(void);
+
+/*
+ * ktime_t based interfaces
+ */
+
+enum tk_offsets {
+       TK_OFFS_REAL,
+       TK_OFFS_BOOT,
+       TK_OFFS_TAI,
+       TK_OFFS_MAX,
+};
+
+extern ktime_t ktime_get(void);
+extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
+extern ktime_t ktime_get_raw(void);
+extern u32 ktime_get_resolution_ns(void);
+
+/**
+ * ktime_get_real - get the real (wall-) time in ktime_t format
+ */
+static inline ktime_t ktime_get_real(void)
+{
+       return ktime_get_with_offset(TK_OFFS_REAL);
+}
+
+static inline ktime_t ktime_get_coarse_real(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_REAL);
+}
+
+/**
+ * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
+ *
+ * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
+ * time spent in suspend.
+ */
+static inline ktime_t ktime_get_boottime(void)
+{
+       return ktime_get_with_offset(TK_OFFS_BOOT);
+}
+
+static inline ktime_t ktime_get_coarse_boottime(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
+}
+
+/**
+ * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
+ */
+static inline ktime_t ktime_get_clocktai(void)
+{
+       return ktime_get_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse_clocktai(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse(void)
+{
+       struct timespec64 ts;
+
+       ktime_get_coarse_ts64(&ts);
+       return timespec64_to_ktime(ts);
+}
+
+static inline u64 ktime_get_coarse_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse());
+}
+
+static inline u64 ktime_get_coarse_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_real());
+}
+
+static inline u64 ktime_get_coarse_boottime_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_boottime());
+}
+
+static inline u64 ktime_get_coarse_clocktai_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_clocktai());
+}
+
+/**
+ * ktime_mono_to_real - Convert monotonic time to clock realtime
+ */
+static inline ktime_t ktime_mono_to_real(ktime_t mono)
+{
+       return ktime_mono_to_any(mono, TK_OFFS_REAL);
+}
+
+static inline u64 ktime_get_ns(void)
+{
+       return ktime_to_ns(ktime_get());
+}
+
+static inline u64 ktime_get_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_real());
+}
+
+static inline u64 ktime_get_boottime_ns(void)
+{
+       return ktime_to_ns(ktime_get_boottime());
+}
+
+static inline u64 ktime_get_clocktai_ns(void)
+{
+       return ktime_to_ns(ktime_get_clocktai());
+}
+
+static inline u64 ktime_get_raw_ns(void)
+{
+       return ktime_to_ns(ktime_get_raw());
+}
+
+extern u64 ktime_get_mono_fast_ns(void);
+extern u64 ktime_get_raw_fast_ns(void);
+extern u64 ktime_get_boot_fast_ns(void);
+extern u64 ktime_get_real_fast_ns(void);
+
+/*
+ * timespec64/time64_t interfaces utilizing the ktime based ones
+ * for API completeness, these could be implemented more efficiently
+ * if needed.
+ */
+static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_boottime());
+}
+
+static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_coarse_boottime());
+}
+
+static inline time64_t ktime_get_boottime_seconds(void)
+{
+       return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
+}
+
+static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_clocktai());
+}
+
+static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
+}
+
+static inline time64_t ktime_get_clocktai_seconds(void)
+{
+       return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
+}
+
+#endif /* _LINUX_KTIME_H */
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h
index 78c8ac4951b5..24970c202ac6 100644
--- a/include/linux/pps_kernel.h
+++ b/include/linux/pps_kernel.h
@@ -12,6 +12,7 @@
 #include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 
 /*
  * Global defines
diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h
index 835ee87ed792..f0fa287710da 100644
--- a/include/linux/sched_clock.h
+++ b/include/linux/sched_clock.h
@@ -5,6 +5,8 @@
 #ifndef LINUX_SCHED_CLOCK
 #define LINUX_SCHED_CLOCK
 
+#include <linux/timekeeping.h>
+
 #ifdef CONFIG_GENERIC_SCHED_CLOCK
 /**
  * struct clock_read_data - data required to read from sched_clock()
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..bf235ff101d5 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -14,6 +14,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/timekeeping.h>
 
 #define MTL_MAX_RX_QUEUES	8
 #define MTL_MAX_TX_QUEUES	8
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 78a98bdff76d..b1c54f5ff91e 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -19,201 +19,6 @@ extern void legacy_timer_tick(unsigned long ticks);
 extern int do_settimeofday64(const struct timespec64 *ts);
 extern int do_sys_settimeofday64(const struct timespec64 *tv,
 				 const struct timezone *tz);
-
-/*
- * ktime_get() family: read the current time in a multitude of ways,
- *
- * The default time reference is CLOCK_MONOTONIC, starting at
- * boot time but not counting the time spent in suspend.
- * For other references, use the functions with "real", "clocktai",
- * "boottime" and "raw" suffixes.
- *
- * To get the time in a different format, use the ones wit
- * "ns", "ts64" and "seconds" suffix.
- *
- * See Documentation/core-api/timekeeping.rst for more details.
- */
-
-
-/*
- * timespec64 based interfaces
- */
-extern void ktime_get_raw_ts64(struct timespec64 *ts);
-extern void ktime_get_ts64(struct timespec64 *ts);
-extern void ktime_get_real_ts64(struct timespec64 *tv);
-extern void ktime_get_coarse_ts64(struct timespec64 *ts);
-extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
-
-void getboottime64(struct timespec64 *ts);
-
-/*
- * time64_t base interfaces
- */
-extern time64_t ktime_get_seconds(void);
-extern time64_t __ktime_get_real_seconds(void);
-extern time64_t ktime_get_real_seconds(void);
-
-/*
- * ktime_t based interfaces
- */
-
-enum tk_offsets {
-	TK_OFFS_REAL,
-	TK_OFFS_BOOT,
-	TK_OFFS_TAI,
-	TK_OFFS_MAX,
-};
-
-extern ktime_t ktime_get(void);
-extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
-extern ktime_t ktime_get_raw(void);
-extern u32 ktime_get_resolution_ns(void);
-
-/**
- * ktime_get_real - get the real (wall-) time in ktime_t format
- */
-static inline ktime_t ktime_get_real(void)
-{
-	return ktime_get_with_offset(TK_OFFS_REAL);
-}
-
-static inline ktime_t ktime_get_coarse_real(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_REAL);
-}
-
-/**
- * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
- *
- * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
- * time spent in suspend.
- */
-static inline ktime_t ktime_get_boottime(void)
-{
-	return ktime_get_with_offset(TK_OFFS_BOOT);
-}
-
-static inline ktime_t ktime_get_coarse_boottime(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
-}
-
-/**
- * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
- */
-static inline ktime_t ktime_get_clocktai(void)
-{
-	return ktime_get_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse_clocktai(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse(void)
-{
-	struct timespec64 ts;
-
-	ktime_get_coarse_ts64(&ts);
-	return timespec64_to_ktime(ts);
-}
-
-static inline u64 ktime_get_coarse_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse());
-}
-
-static inline u64 ktime_get_coarse_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_real());
-}
-
-static inline u64 ktime_get_coarse_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_boottime());
-}
-
-static inline u64 ktime_get_coarse_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_clocktai());
-}
-
-/**
- * ktime_mono_to_real - Convert monotonic time to clock realtime
- */
-static inline ktime_t ktime_mono_to_real(ktime_t mono)
-{
-	return ktime_mono_to_any(mono, TK_OFFS_REAL);
-}
-
-static inline u64 ktime_get_ns(void)
-{
-	return ktime_to_ns(ktime_get());
-}
-
-static inline u64 ktime_get_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_real());
-}
-
-static inline u64 ktime_get_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_boottime());
-}
-
-static inline u64 ktime_get_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_clocktai());
-}
-
-static inline u64 ktime_get_raw_ns(void)
-{
-	return ktime_to_ns(ktime_get_raw());
-}
-
-extern u64 ktime_get_mono_fast_ns(void);
-extern u64 ktime_get_raw_fast_ns(void);
-extern u64 ktime_get_boot_fast_ns(void);
-extern u64 ktime_get_real_fast_ns(void);
-
-/*
- * timespec64/time64_t interfaces utilizing the ktime based ones
- * for API completeness, these could be implemented more efficiently
- * if needed.
- */
-static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_boottime());
-}
-
-static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_boottime());
-}
-
-static inline time64_t ktime_get_boottime_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
-}
-
-static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_clocktai());
-}
-
-static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
-}
-
-static inline time64_t ktime_get_clocktai_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
-}
-
 /*
  * RTC specific
  */
@@ -308,4 +113,4 @@ void read_persistent_wall_and_boot_offset(struct timespec64 *wall_clock,
 extern int update_persistent_clock64(struct timespec64 now);
 #endif
 
-#endif
+#endif /* _LINUX_TIMEKEEPING_H */
diff --git a/init/main.c b/init/main.c
index f5b8246e8aa1..a8db3a136d6a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -100,6 +100,7 @@
 #include <linux/kcsan.h>
 #include <linux/init_syscalls.h>
 #include <linux/stackdepot.h>
+#include <linux/timekeeping.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 406dccb79c2b..804f06801737 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "ntp_internal.h"
 #include "timekeeping_internal.h"
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index dd5697d7347b..14f82cd95d10 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 #include <linux/mutex.h>
 #include <linux/sched/task.h>
 
diff --git a/kernel/time/tick-legacy.c b/kernel/time/tick-legacy.c
index af225b32f5b3..9a534f716462 100644
--- a/kernel/time/tick-legacy.c
+++ b/kernel/time/tick-legacy.c
@@ -7,6 +7,7 @@
 #include <linux/irq.h>
 #include <linux/profile.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 29923b20e0e4..7292ed074742 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -29,6 +29,7 @@
 #include <linux/timex.h>
 #include <linux/capability.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/errno.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8a364aa9881a..4dfee925adc8 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -22,6 +22,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index ca2f2ecd1488..efbbe624d81d 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 
 #ifdef CONFIG_X86
 /* for art-tsc conversion */
-- 
2.25.1



From adobriyan at gmail.com  Sun Aug  1 13:13:36 2021
From: adobriyan at gmail.com (Alexey Dobriyan)
Date: Sun,  1 Aug 2021 23:13:36 +0300
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <20210801201336.2224111-1-adobriyan@gmail.com>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
Message-ID: <20210801201336.2224111-3-adobriyan@gmail.com>

In theory, it enables "leakage" of userspace headers into kernel which
may present licensing problem.

In practice, only stdarg.h was used, stdbool.h is trivial and SIMD
intrinsics are contained to a few architectures and aren't global
problem.

In general, kernel is very self contained code and -isystem removal
will further isolate it from Ring Threeland influence.

nds32 keeps -isystem globally due to intrisics used in entrenched header.

-isystem is selectively reenabled for some files.

Not compile tested on hexagon.

Compile tested on:

alpha-allmodconfig alpha-allnoconfig alpha-defconfig arm64-allmodconfig
arm64-allnoconfig arm64-defconfig arm-am200epdkit arm-aspeed_g4
arm-aspeed_g5 arm-assabet arm-at91_dt arm-axm55xx arm-badge4 arm-bcm2835
arm-cerfcube arm-clps711x arm-cm_x300 arm-cns3420vb arm-colibri_pxa270
arm-colibri_pxa300 arm-collie arm-corgi arm-davinci_all arm-dove
arm-ep93xx arm-eseries_pxa arm-exynos arm-ezx arm-footbridge arm-gemini
arm-h3600 arm-h5000 arm-hackkit arm-hisi arm-imote2 arm-imx_v4_v5
arm-imx_v6_v7 arm-integrator arm-iop32x arm-ixp4xx arm-jornada720
arm-keystone arm-lart arm-lpc18xx arm-lpc32xx arm-lpd270 arm-lubbock
arm-magician arm-mainstone arm-milbeaut_m10v arm-mini2440 arm-mmp2
arm-moxart arm-mps2 arm-multi_v4t arm-multi_v5 arm-multi_v7 arm-mv78xx0
arm-mvebu_v5 arm-mvebu_v7 arm-mxs arm-neponset arm-netwinder arm-nhk8815
arm-omap1 arm-omap2plus arm-orion5x arm-oxnas_v6 arm-palmz72 arm-pcm027
arm-pleb arm-pxa arm-pxa168 arm-pxa255-idp arm-pxa3xx arm-pxa910
arm-qcom arm-realview arm-rpc arm-s3c2410 arm-s3c6400 arm-s5pv210
arm-sama5 arm-shannon arm-shmobile arm-simpad arm-socfpga arm-spear13xx
arm-spear3xx arm-spear6xx arm-spitz arm-stm32 arm-sunxi arm-tct_hammer
arm-tegra arm-trizeps4 arm-u8500 arm-versatile arm-vexpress arm-vf610m4
arm-viper arm-vt8500_v6_v7 arm-xcep arm-zeus csky-allmodconfig
csky-allnoconfig csky-defconfig h8300-edosk2674 h8300-h8300h-sim
h8300-h8s-sim i386-allmodconfig i386-allnoconfig i386-defconfig
ia64-allmodconfig ia64-allnoconfig ia64-bigsur ia64-generic ia64-gensparse
ia64-tiger ia64-zx1 m68k-amcore m68k-amiga m68k-apollo m68k-atari
m68k-bvme6000 m68k-hp300 m68k-m5208evb m68k-m5249evb m68k-m5272c3
m68k-m5275evb m68k-m5307c3 m68k-m5407c3 m68k-m5475evb m68k-mac
m68k-multi m68k-mvme147 m68k-mvme16x m68k-q40 m68k-stmark2 m68k-sun3
m68k-sun3x microblaze-allmodconfig microblaze-allnoconfig microblaze-mmu
mips-ar7 mips-ath25 mips-ath79 mips-bcm47xx mips-bcm63xx mips-bigsur
mips-bmips_be mips-bmips_stb mips-capcella mips-cavium_octeon mips-ci20
mips-cobalt mips-cu1000-neo mips-cu1830-neo mips-db1xxx mips-decstation
mips-decstation_64 mips-decstation_r4k mips-e55 mips-fuloong2e
mips-gcw0 mips-generic mips-gpr mips-ip22 mips-ip27 mips-ip28 mips-ip32
mips-jazz mips-jmr3927 mips-lemote2f mips-loongson1b mips-loongson1c
mips-loongson2k mips-loongson3 mips-malta mips-maltaaprp mips-malta_kvm
mips-malta_qemu_32r6 mips-maltasmvp mips-maltasmvp_eva mips-maltaup
mips-maltaup_xpa mips-mpc30x mips-mtx1 mips-nlm_xlp mips-nlm_xlr
mips-omega2p mips-pic32mzda mips-pistachio mips-qi_lb60 mips-rb532
mips-rbtx49xx mips-rm200 mips-rs90 mips-rt305x mips-sb1250_swarm
mips-tb0219 mips-tb0226 mips-tb0287 mips-vocore2 mips-workpad mips-xway
nds32-allmodconfig nds32-allnoconfig nds32-defconfig nios2-10m50
nios2-3c120 nios2-allmodconfig nios2-allnoconfig openrisc-allmodconfig
openrisc-allnoconfig openrisc-or1klitex openrisc-or1ksim
openrisc-simple_smp parisc-allnoconfig parisc-generic-32bit
parisc-generic-64bit powerpc-acadia powerpc-adder875 powerpc-akebono
powerpc-amigaone powerpc-arches powerpc-asp8347 powerpc-bamboo
powerpc-bluestone powerpc-canyonlands powerpc-cell powerpc-chrp32
powerpc-cm5200 powerpc-currituck powerpc-ebony powerpc-eiger
powerpc-ep8248e powerpc-ep88xc powerpc-fsp2 powerpc-g5 powerpc-gamecube
powerpc-ge_imp3a powerpc-holly powerpc-icon powerpc-iss476-smp
powerpc-katmai powerpc-kilauea powerpc-klondike powerpc-kmeter1
powerpc-ksi8560 powerpc-linkstation powerpc-lite5200b powerpc-makalu
powerpc-maple powerpc-mgcoge powerpc-microwatt powerpc-motionpro
powerpc-mpc512x powerpc-mpc5200 powerpc-mpc7448_hpc2 powerpc-mpc8272_ads
powerpc-mpc8313_rdb powerpc-mpc8315_rdb powerpc-mpc832x_mds
powerpc-mpc832x_rdb powerpc-mpc834x_itx powerpc-mpc834x_itxgp
powerpc-mpc834x_mds powerpc-mpc836x_mds powerpc-mpc836x_rdk
powerpc-mpc837x_mds powerpc-mpc837x_rdb powerpc-mpc83xx
powerpc-mpc8540_ads powerpc-mpc8560_ads powerpc-mpc85xx_cds
powerpc-mpc866_ads powerpc-mpc885_ads powerpc-mvme5100 powerpc-obs600
powerpc-pasemi powerpc-pcm030 powerpc-pmac32 powerpc-powernv
powerpc-ppa8548 powerpc-ppc40x powerpc-ppc44x powerpc-ppc64
powerpc-ppc64e powerpc-ppc6xx powerpc-pq2fads powerpc-ps3
powerpc-pseries powerpc-rainier powerpc-redwood powerpc-sam440ep
powerpc-sbc8548 powerpc-sequoia powerpc-skiroot powerpc-socrates
powerpc-storcenter powerpc-stx_gp3 powerpc-taishan powerpc-tqm5200
powerpc-tqm8540 powerpc-tqm8541 powerpc-tqm8548 powerpc-tqm8555
powerpc-tqm8560 powerpc-tqm8xx powerpc-walnut powerpc-warp powerpc-wii
powerpc-xes_mpc85xx riscv-allmodconfig riscv-allnoconfig riscv-nommu_k210
riscv-nommu_k210_sdcard riscv-nommu_virt riscv-rv32 s390-allmodconfig
s390-allnoconfig s390-debug s390-zfcpdump sh-ap325rxa sh-apsh4a3a
sh-apsh4ad0a sh-dreamcast sh-ecovec24 sh-ecovec24-romimage sh-edosk7705
sh-edosk7760 sh-espt sh-hp6xx sh-j2 sh-kfr2r09 sh-kfr2r09-romimage
sh-landisk sh-lboxre2 sh-magicpanelr2 sh-microdev sh-migor sh-polaris
sh-r7780mp sh-r7785rp sh-rsk7201 sh-rsk7203 sh-rsk7264 sh-rsk7269
sh-rts7751r2d1 sh-rts7751r2dplus sh-sdk7780 sh-sdk7786 sh-se7206 sh-se7343
sh-se7619 sh-se7705 sh-se7712 sh-se7721 sh-se7722 sh-se7724 sh-se7750
sh-se7751 sh-se7780 sh-secureedge5410 sh-sh03 sh-sh2007 sh-sh7710voipgw
sh-sh7724_generic sh-sh7757lcr sh-sh7763rdp sh-sh7770_generic sh-sh7785lcr
sh-sh7785lcr_32bit sh-shmin sh-shx3 sh-titan sh-ul2 sh-urquell
sparc-allmodconfig sparc-allnoconfig sparc-sparc32 sparc-sparc64
um-i386-allmodconfig um-i386-allnoconfig um-i386-defconfig
um-x86_64-allmodconfig um-x86_64-allnoconfig x86_64-allmodconfig
x86_64-allnoconfig x86_64-defconfig xtensa-allmodconfig xtensa-allnoconfig
xtensa-audio_kc705 xtensa-cadence_csp xtensa-common xtensa-generic_kc705
xtensa-iss xtensa-nommu_kc705 xtensa-smp_lx200 xtensa-virt
xtensa-xip_kc705

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Cc: Paul Mackerras <paulus at samba.org>
Cc: linuxppc-dev at lists.ozlabs.org
Signed-off-by: Alexey Dobriyan <adobriyan at gmail.com>
---
 Makefile                  | 2 +-
 arch/arm64/lib/Makefile   | 2 ++
 arch/nds32/Makefile       | 2 ++
 arch/powerpc/lib/Makefile | 2 ++
 crypto/Makefile           | 2 ++
 lib/raid6/Makefile        | 4 ++++
 6 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 6b555f64df06..b59053ec457a 100644
--- a/Makefile
+++ b/Makefile
@@ -979,7 +979,7 @@ KBUILD_CFLAGS += -falign-functions=64
 endif
 
 # arch Makefile may override CC so keep this after arch Makefile is included
-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
+NOSTDINC_FLAGS += -nostdinc
 
 # warn about C99 declaration after statement
 KBUILD_CFLAGS += -Wdeclaration-after-statement
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 6dd56a49790a..dcad998f12d7 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -9,6 +9,8 @@ ifeq ($(CONFIG_KERNEL_MODE_NEON), y)
 obj-$(CONFIG_XOR_BLOCKS)	+= xor-neon.o
 CFLAGS_REMOVE_xor-neon.o	+= -mgeneral-regs-only
 CFLAGS_xor-neon.o		+= -ffreestanding
+# Enable <arm_neon.h>
+CFLAGS_xor-neon.o		+= -isystem $(shell $(CC) -print-file-name=include)
 endif
 
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
diff --git a/arch/nds32/Makefile b/arch/nds32/Makefile
index ccdca7142020..c17fc3a755c3 100644
--- a/arch/nds32/Makefile
+++ b/arch/nds32/Makefile
@@ -9,6 +9,8 @@ endif
 # Avoid generating FPU instructions
 arch-y  += -mno-ext-fpu-sp -mno-ext-fpu-dp -mfloat-abi=soft
 
+# Enable <nds32_intrinsic.h>
+KBUILD_CFLAGS	+= -isystem $(shell $(CC) -print-file-name=include)
 KBUILD_CFLAGS	+= $(call cc-option, -mno-sched-prolog-epilog)
 KBUILD_CFLAGS	+= -mcmodel=large
 
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 99a7c9132422..9e5d0f413b71 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -65,5 +65,7 @@ obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o
 
 obj-$(CONFIG_ALTIVEC)	+= xor_vmx.o xor_vmx_glue.o
 CFLAGS_xor_vmx.o += -maltivec $(call cc-option,-mabi=altivec)
+# Enable <altivec.h>
+CFLAGS_xor_vmx.o += -isystem $(shell $(CC) -print-file-name=include)
 
 obj-$(CONFIG_PPC64) += $(obj64-y)
diff --git a/crypto/Makefile b/crypto/Makefile
index 10526d4559b8..75ad9b040506 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -117,6 +117,8 @@ aegis128-cflags-$(CONFIG_CC_IS_GCC) += -ffixed-q16 -ffixed-q17 -ffixed-q18 \
 				       -ffixed-q28 -ffixed-q29 -ffixed-q30 \
 				       -ffixed-q31
 CFLAGS_aegis128-neon-inner.o += $(aegis128-cflags-y)
+# Enable <arm_neon.h>
+CFLAGS_aegis128-neon-inner.o += -isystem $(shell $(CC) -print-file-name=include)
 CFLAGS_REMOVE_aegis128-neon-inner.o += -mgeneral-regs-only
 aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o
 endif
diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile
index c770570bfe4f..45e17619422b 100644
--- a/lib/raid6/Makefile
+++ b/lib/raid6/Makefile
@@ -14,6 +14,8 @@ hostprogs	+= mktables
 
 ifeq ($(CONFIG_ALTIVEC),y)
 altivec_flags := -maltivec $(call cc-option,-mabi=altivec)
+# Enable <altivec.h>
+altivec_flags += -isystem $(shell $(CC) -print-file-name=include)
 
 ifdef CONFIG_CC_IS_CLANG
 # clang ppc port does not yet support -maltivec when -msoft-float is
@@ -34,6 +36,8 @@ endif
 # ARM/NEON intrinsics in a non C99-compliant environment (such as the kernel)
 ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
 NEON_FLAGS := -ffreestanding
+# Enable <arm_neon.h>
+NEON_FLAGS += -isystem $(shell $(CC) -print-file-name=include)
 ifeq ($(ARCH),arm)
 NEON_FLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon
 endif
-- 
2.31.1



From sam at ravnborg.org  Sun Aug  1 13:24:41 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Sun, 1 Aug 2021 22:24:41 +0200
Subject: [PATCH 00/14] drm: Make DRM's IRQ helpers legacy
In-Reply-To: <d50b3199-20fe-0ecb-ab7d-7425ad1d0f21@suse.de>
References: <20210727182721.17981-1-tzimmermann@suse.de>
 <YQWbWjV5TYzp+5C4@ravnborg.org>
 <d50b3199-20fe-0ecb-ab7d-7425ad1d0f21@suse.de>
Message-ID: <YQcDCVuSM2kLbQcI@ravnborg.org>

Hi Thomas,

> > 
> > 1) IRQ_NOTCONNECTED
> > 
> > We do not have this check in drm_irq today and we should avoid spreading
> > it all over. We are either carrying it forever or we wil lsee patches
> > floating in to drop the check again.
> > The current use in the kernel is minimal:
> > https://elixir.bootlin.com/linux/latest/A/ident/IRQ_NOTCONNECTED
> > 
> > So as a minimum drop it from atmel_hlcdc and preferably from the rest as
> > it is really not used. (Speaking as atmel_hlcdc maintainer)
> 
> I'll drop it from atmel_hlcdc then.
> 
> But saying that it's not used is not correct.
My point is the drm_irq do not check this - so adding this check add
something there was not needed/done before.

> > 2) devm_request_irq()
> > 
> > We are moving towards managed allocation so we do not fail to free
> > resources. And an irq has a lifetime equal the device itself - so an
> > obvious cnadidate for devm_request_irq.
> > If we do not introduce it now we will see a revisit of this later.
> > I can be convinced to wait with this as we will have to do much more in
> > each driver, but I cannot see any good arguments to avoid the more
> > modern way to use devm_request_irq.
> 
> I'll change this in atmel_hdlcd and maybe I can find trivial cases where
> devm_request_irq() can be used. But drivers that had an uninstall callback
> before should not have the cleanup logic altered by a patch as this one. I
> suspect that most of the IRQ cleanup
> is actually a vblank cleanup and should be done in response to
> drm_vblank_init(). But that's again not something for this patchset here. We
> cannot change multiple things at once and still expect any of it to work.
> 
> I welcome the use of devm_ et al. But these changes are better done in a
> per-driver patchset that changes all of the driver to managed release.
Fair enough, and fine with me.
I have yet to read through all patches - will do so in the coming week.

	Sam


From linux at roeck-us.net  Sun Aug  1 13:48:48 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Sun, 1 Aug 2021 13:48:48 -0700
Subject: [PATCH 10/12] dt-bindings: watchdog: Add compatible for Mediatek
 MT7986
In-Reply-To: <20210726071439.14248-11-sam.shih@mediatek.com>
References: <20210726071439.14248-1-sam.shih@mediatek.com>
 <20210726071439.14248-11-sam.shih@mediatek.com>
Message-ID: <20210801204848.GA2800586@roeck-us.net>

On Mon, Jul 26, 2021 at 03:14:37PM +0800, Sam Shih wrote:
> This commit adds dt-binding documentation of watchdog for Mediatek MT7986
> SoC Platform.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> Acked-by: Rob Herring <robh at kernel.org>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
>  Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
> index 416d716403f6..a4e31ce96e0e 100644
> --- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
> +++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
> @@ -13,6 +13,7 @@ Required properties:
>  	"mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
>  	"mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
>  	"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
> +	"mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986
>  	"mediatek,mt8183-wdt": for MT8183
>  	"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
>  	"mediatek,mt8192-wdt": for MT8192


From segher at kernel.crashing.org  Sun Aug  1 14:32:47 2021
From: segher at kernel.crashing.org (Segher Boessenkool)
Date: Sun, 1 Aug 2021 16:32:47 -0500
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <20210801201336.2224111-3-adobriyan@gmail.com>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
 <20210801201336.2224111-3-adobriyan@gmail.com>
Message-ID: <20210801213247.GM1583@gate.crashing.org>

On Sun, Aug 01, 2021 at 11:13:36PM +0300, Alexey Dobriyan wrote:
> In theory, it enables "leakage" of userspace headers into kernel which
> may present licensing problem.

> -NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
> +NOSTDINC_FLAGS += -nostdinc

This is removing the compiler's own include files.  These are required
for all kinds of basic features, and required to be compliant to the C
standard at all.  These are not "userspace headers", that is what
-nostdinc takes care of already.

In the case of GCC all these headers are GPL-with-runtime-exception, so
claiming this can cause licensing problems is fearmongering.

I strongly advise against doing this.


Segher


From linus.walleij at linaro.org  Sun Aug  1 16:37:22 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon,  2 Aug 2021 01:37:22 +0200
Subject: [PATCH] ARM: dts: ux500: Adjust operating points to reality
Message-ID: <20210801233722.3151047-1-linus.walleij@linaro.org>

The operating points should correspond to the actual frequencies
supported for the CPU. Other patches have fixed so these are
rounded and reported properly, this fixes the device trees to
match.

The Codina variant has a lower frequency than other devices so
indicate this in the device tree.

Cc: phone-devel at vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/ste-db8500.dtsi              |  7 +++----
 arch/arm/boot/dts/ste-db8520.dtsi              |  7 +++----
 arch/arm/boot/dts/ste-db9500.dtsi              |  9 ++++-----
 arch/arm/boot/dts/ste-ux500-samsung-codina.dts | 12 ++++++++++++
 4 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/arch/arm/boot/dts/ste-db8500.dtsi b/arch/arm/boot/dts/ste-db8500.dtsi
index 344d29853bf7..b5b8ba9be55e 100644
--- a/arch/arm/boot/dts/ste-db8500.dtsi
+++ b/arch/arm/boot/dts/ste-db8500.dtsi
@@ -5,11 +5,10 @@
 / {
 	cpus {
 		cpu at 300 {
-			/* cpufreq controls */
 			operating-points = <998400 0
-					    800000 0
-					    400000 0
-					    200000 0>;
+					    798720 0
+					    399360 0
+					    199680 0>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/ste-db8520.dtsi b/arch/arm/boot/dts/ste-db8520.dtsi
index 287804e9e183..0c277a6d1914 100644
--- a/arch/arm/boot/dts/ste-db8520.dtsi
+++ b/arch/arm/boot/dts/ste-db8520.dtsi
@@ -5,11 +5,10 @@
 / {
 	cpus {
 		cpu at 300 {
-			/* cpufreq controls */
 			operating-points = <1152000 0
-					    800000 0
-					    400000 0
-					    200000 0>;
+					    798720 0
+					    399360 0
+					    199680 0>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/ste-db9500.dtsi b/arch/arm/boot/dts/ste-db9500.dtsi
index 0afff703191c..4273d36e881d 100644
--- a/arch/arm/boot/dts/ste-db9500.dtsi
+++ b/arch/arm/boot/dts/ste-db9500.dtsi
@@ -5,11 +5,10 @@
 / {
 	cpus {
 		cpu at 300 {
-			/* cpufreq controls */
-			operating-points = <1152000 0
-					    800000 0
-					    400000 0
-					    200000 0>;
+			operating-points = <998400 0
+					    798720 0
+					    399360 0
+					    199680 0>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
index ba7986988e87..952606e607ed 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
@@ -27,6 +27,18 @@ / {
 	model = "Samsung Galaxy Ace 2 (GT-I8160)";
 	compatible = "samsung,codina", "st-ericsson,u8500";
 
+	cpus {
+		cpu at 300 {
+			/*
+			 * This has a frequency cap at ~800 MHz in the firmware.
+			 * (Changing this number here will not overclock it.)
+			 */
+			operating-points = <798720 0
+					    399360 0
+					    199680 0>;
+		};
+	};
+
 	chosen {
 		stdout-path = &serial2;
 	};
-- 
2.31.1



From chunkuang.hu at kernel.org  Sun Aug  1 16:59:50 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Mon, 2 Aug 2021 07:59:50 +0800
Subject: [PATCH v4 2/2] dt-bindings: mediatek: add
 force_dsi_end_without_null
In-Reply-To: <20210801040544.104135-2-jitao.shi@mediatek.com>
References: <20210801040544.104135-1-jitao.shi@mediatek.com>
 <20210801040544.104135-2-jitao.shi@mediatek.com>
Message-ID: <CAAOTY_-KORHyePSbDSmc6Tdk=GpbTWewYmg9Q1ebQ0PgKADSug@mail.gmail.com>

Hi, Jitao:

Jitao Shi <jitao.shi at mediatek.com> ? 2021?8?1? ?? ??12:06???

Move this patch before the patch "drm/mediatek: force hsa hbp hfp
packets multiple of lanenum to avoid screen shift",
and this patch's title should be "dt-bindings: drm/bridge: anx7625:
add force_dsi_end_without_null"

Regards,
Chun-Kuang.

>
> The force_dsi_end_without_null requires the dsi host ent at
> the same time in line.
>
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> ---
>  .../bindings/display/bridge/analogix,anx7625.yaml           | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> index ab48ab2f4240..8b868a6a3d60 100644
> --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> @@ -43,6 +43,11 @@ properties:
>    vdd33-supply:
>      description: Regulator that provides the supply 3.3V power.
>
> +  force_dsi_end_without_null:
> +    description: |
> +      Requires the dsi host send the dsi packets on all lanes aligned
> +      at the end.
> +
>    ports:
>      $ref: /schemas/graph.yaml#/properties/ports
>
> @@ -87,6 +92,7 @@ examples:
>              vdd10-supply = <&pp1000_mipibrdg>;
>              vdd18-supply = <&pp1800_mipibrdg>;
>              vdd33-supply = <&pp3300_mipibrdg>;
> +            force_dsi_end_without_null;
>
>              ports {
>                  #address-cells = <1>;
> --
> 2.25.1


From andre.przywara at arm.com  Sun Aug  1 17:38:51 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 2 Aug 2021 01:38:51 +0100
Subject: [PATCH v8 00/11] arm64: sunxi: Initial Allwinner H616 SoC support
In-Reply-To: <20210726145230.uevhinsrvo7gtuty@gilmour>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210726145230.uevhinsrvo7gtuty@gilmour>
Message-ID: <20210802013851.13375f0f@slackpad.fritz.box>

On Mon, 26 Jul 2021 16:52:30 +0200
Maxime Ripard <maxime at cerno.tech> wrote:

Hi,

> On Fri, Jul 23, 2021 at 04:38:27PM +0100, Andre Przywara wrote:
> > Hi,
> > 
> > another try on the basic Allwinner H616 support, now on top of 5.14-rc1.
> > 
> > This time I dropped the USB support from the basic series, to split off
> > the discussion, and simplify the core SoC support. I will post the USB
> > series soon, to be applied on top.
> > I kept the RTC support in, even though this is still under discussion,
> > because this is important to keep future DT files compatible with this
> > kernel.  
> 
> Honestly, I don't want to support something we don't guarantee if it's
> at the expense of making something we do guarantee more complicated.

I don't ask for or provide guarantees, but I think we can at least *try*
to keep this compatible. This version works at the moment, and should
also work with future DTs - within the limits of the current driver, so
only using the RC clock. It allows to later improve the accuracy by
adding better input clocks - and later DT/driver combinations can make
use of this.

> Delaying the clock tree description to sometime in the future will only
> further complicate the probe part of the driver, and there's far too
> many special cases already.

I don't see how this would complicate probing beyond what Allwinner
brought upon us already anyway: no LOSC crystal input in this package
version, but having this pin in some other SoC sharing this die
(according to some BSP) sources. We can't expect a super clean driver
with those HW design choices.

If we really cannot keep the DT compatible, fair enough: that's what
it is (there is no guarantee!), but at least we have tried.

Cheers,
Andre


From andre.przywara at arm.com  Sun Aug  1 17:39:02 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 2 Aug 2021 01:39:02 +0100
Subject: [PATCH v8 05/11] rtc: sun6i: Add support for broken-down alarm
 registers
In-Reply-To: <35374855.gLGPhMbAMS@kista>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210723153838.6785-6-andre.przywara@arm.com>
 <35374855.gLGPhMbAMS@kista>
Message-ID: <20210802013902.7164876f@slackpad.fritz.box>

On Sun, 25 Jul 2021 08:11:49 +0200
Jernej ?krabec <jernej.skrabec at gmail.com> wrote:

Hi Jernej,

> Dne petek, 23. julij 2021 ob 17:38:32 CEST je Andre Przywara napisal(a):
> > Newer versions of the Allwinner RTC, for instance as found in the H616
> > SoC, not only store the current day as a linear number, but also change
> > the way the alarm is handled: There are now two registers, that
> > explicitly store the wakeup time, in the same format as the current
> > time.
> > 
> > Add support for that variant by writing the requested wakeup time
> > directly into the registers, instead of programming the seconds left, as
> > the old SoCs required.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  drivers/rtc/rtc-sun6i.c | 60 +++++++++++++++++++++++++++++------------
> >  1 file changed, 43 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
> > index a02be8bca6f3..f0ee20bfdccb 100644
> > --- a/drivers/rtc/rtc-sun6i.c
> > +++ b/drivers/rtc/rtc-sun6i.c
> > @@ -48,7 +48,8 @@
> >  
> >  /* Alarm 0 (counter) */
> >  #define SUN6I_ALRM_COUNTER			0x0020
> > -#define SUN6I_ALRM_CUR_VAL			0x0024
> > +/* This holds the remaining alarm seconds on older SoCs (current value) */
> > +#define SUN6I_ALRM_COUNTER_HMS			0x0024
> >  #define SUN6I_ALRM_EN				0x0028
> >  #define SUN6I_ALRM_EN_CNT_EN			BIT(0)
> >  #define SUN6I_ALRM_IRQ_EN			0x002c
> > @@ -523,32 +524,57 @@ static int sun6i_rtc_setalarm(struct device *dev,   
> struct rtc_wkalrm *wkalrm)
> >  	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
> >  	struct rtc_time *alrm_tm = &wkalrm->time;
> >  	struct rtc_time tm_now;
> > -	time64_t time_now, time_set;
> > +	time64_t time_set;
> > +	u32 counter_val, counter_val_hms;
> >  	int ret;
> >  
> > -	ret = sun6i_rtc_gettime(dev, &tm_now);
> > -	if (ret < 0) {
> > -		dev_err(dev, "Error in getting time\n");
> > -		return -EINVAL;
> > -	}
> > -
> >  	time_set = rtc_tm_to_time64(alrm_tm);
> > -	time_now = rtc_tm_to_time64(&tm_now);
> > -	if (time_set <= time_now) {
> > -		dev_err(dev, "Date to set in the past\n");
> > -		return -EINVAL;
> > -	}
> >  
> > -	if ((time_set - time_now) > U32_MAX) {
> > -		dev_err(dev, "Date too far in the future\n");
> > -		return -EINVAL;
> > +	if (chip->flags & RTC_LINEAR_DAY) {
> > +		time64_t seconds;
> > +
> > +		/*
> > +		 * The alarm registers hold the actual alarm time,   
> encoded
> > +		 * in the same way (linear day + HMS) as the current   
> time.
> > +		 */
> > +		counter_val_hms = SUN6I_TIME_SET_SEC_VALUE(alrm_tm-
> >tm_sec)  |
> > +				    
> SUN6I_TIME_SET_MIN_VALUE(alrm_tm->tm_min)  |
> > +				    
> SUN6I_TIME_SET_HOUR_VALUE(alrm_tm->tm_hour);
> > +		seconds = mktime64(alrm_tm->tm_year + 1900, alrm_tm-
> >tm_mon,
> > +				   alrm_tm->tm_mday, 0, 0, 0);  
> 
> While above line should work, it's confusing why you're adding 1900 to years. 
> In my opinion it would be better to use same trick you used in patch 4 - 
> rtc_tm_to_time64() with hours, minutes and seconds set to 0.

IIRC setalarm does not want the time struct to be changed, but this is
OK in settime. But anyway ...

> Or maybe you 
> don't even need to do that, since division by SECS_PER_DAY will round down 
> anyway. In such way you hide RTC internal representation detail which doesn't 
> need to be exposed here.

That is indeed a very clever idea! I changed both settime and setalarm
accordingly now, adding a comment about this.

> 
> Once fixed:
> Reviewed by: Jernej Skrabec <jernej.skrabec at gmail.com>

Many thanks for the reviews!

Cheers,
Andre

> > +		counter_val = div_u64(seconds, SECS_PER_DAY);
> > +	} else {
> > +		/* The alarm register holds the number of seconds left.   
> */
> > +		time64_t time_now;
> > +
> > +		ret = sun6i_rtc_gettime(dev, &tm_now);
> > +		if (ret < 0) {
> > +			dev_err(dev, "Error in getting time\n");
> > +			return -EINVAL;
> > +		}
> > +
> > +		time_now = rtc_tm_to_time64(&tm_now);
> > +		if (time_set <= time_now) {
> > +			dev_err(dev, "Date to set in the past\n");
> > +			return -EINVAL;
> > +		}
> > +		if ((time_set - time_now) > U32_MAX) {
> > +			dev_err(dev, "Date too far in the future\n");
> > +			return -EINVAL;
> > +		}
> > +
> > +		counter_val = time_set - time_now;
> >  	}
> >  
> >  	sun6i_rtc_setaie(0, chip);
> >  	writel(0, chip->base + SUN6I_ALRM_COUNTER);
> > +	if (chip->flags & RTC_LINEAR_DAY)
> > +		writel(0, chip->base + SUN6I_ALRM_COUNTER_HMS);
> >  	usleep_range(100, 300);
> >  
> > -	writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
> > +	writel(counter_val, chip->base + SUN6I_ALRM_COUNTER);
> > +	if (chip->flags & RTC_LINEAR_DAY)
> > +		writel(counter_val_hms, chip->base +   
> SUN6I_ALRM_COUNTER_HMS);
> >  	chip->alarm = time_set;
> >  
> >  	sun6i_rtc_setaie(wkalrm->enabled, chip);
> > -- 
> > 2.17.6
> > 
> >   
> 
> 
> 



From andre.przywara at arm.com  Sun Aug  1 17:39:38 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 2 Aug 2021 01:39:38 +0100
Subject: [PATCH v8 02/11] dt-bindings: rtc: sun6i: Add H616 compatible
 string
In-Reply-To: <20210726144137.6dauuxdssu7yszox@gilmour>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210723153838.6785-3-andre.przywara@arm.com>
 <20210726144137.6dauuxdssu7yszox@gilmour>
Message-ID: <20210802013938.29fa18ed@slackpad.fritz.box>

On Mon, 26 Jul 2021 16:41:37 +0200
Maxime Ripard <maxime at cerno.tech> wrote:

> Hi,
> 
> On Fri, Jul 23, 2021 at 04:38:29PM +0100, Andre Przywara wrote:
> > Add the obvious compatible name to the existing RTC binding.
> > The actual RTC part of the device uses a different day/month/year
> > storage scheme, so it's not compatible with the previous devices.
> > Also the clock part is quite different, as there is no external 32K LOSC
> > oscillator input.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> >
> > ---
> >  .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml      | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > index beeb90e55727..d8a6500e5840 100644
> > --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > @@ -26,6 +26,7 @@ properties:
> >            - const: allwinner,sun50i-a64-rtc
> >            - const: allwinner,sun8i-h3-rtc
> >        - const: allwinner,sun50i-h6-rtc
> > +      - const: allwinner,sun50i-h616-rtc
> >  
> >    reg:
> >      maxItems: 1
> > @@ -104,6 +105,19 @@ allOf:
> >            minItems: 3
> >            maxItems: 3
> >  
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: allwinner,sun50i-h616-rtc
> > +
> > +    then:
> > +      properties:
> > +        clock-output-names:
> > +          minItems: 3
> > +          maxItems: 3  
> 
> You don't need both of them when they are equal
> 
> > +        clocks: false
> > +  
> 
> It's not entirely clear to me what those clocks are about though. If we
> look at the clock output in the user manual, it looks like there's only
> two clocks that are actually being output: the 32k "fanout" clock and
> the losc. What are the 3 you're talking about?]

I see three: the raw SYSTEM "CLK32K_LOSC", the RTC input + debounce
clock (/32), and the multiplexed PAD.

> Also, it looks like the 32k fanout clock needs at least the hosc or
> pll-periph in input, so we probably don't want to ask for no parent
> clock?

Well, we never seem to reference the HOSC this way, this was always
somewhat explicit. And yes, there is PLL-PERIPH as an input, but we
don't support this yet. So I went with 0 input clocks *for now*: the
driver can then ignore all clocks, so any clock referenced in the DT
later won't cause any harm. This will all be addressed by Samuel's RTC
clock patch, which will also touch the H6, IIRC. And it looks like we
will need to touch the binding anyway then, but can then just *extend*
this.

The point is that everything works(TM) as of now: The consumers
(pinctrl) get their LOSC clock, and can go ahead. This is in the
interest to get us moving now, and refine the actual implementation
later. In this case this will only change the accuracy of the LOSC
frequency (HOSC/x, PLL/y, calibrated RC), but won't change the
semantics.

Cheers,
Andre


From andre.przywara at arm.com  Sun Aug  1 17:39:41 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:41 +0100
Subject: [PATCH v9 00/11] arm64: sunxi: Initial Allwinner H616 SoC support
Message-ID: <20210802003952.19942-1-andre.przywara@arm.com>

Hi,

some minor update of the basic Allwinner H616 support, still on top
of 5.14-rc1.
The only change is some minor change in the date calculation, as per
Jernej's comment.

The USB support is still separate, to split off the discussion, and
simplify the core SoC support.

For a complete changelog, see below.

Based on 5.14-rc1. Let me know if you need a different base.
Relies on this pinctrl fix:
http://lists.infradead.org/pipermail/linux-arm-kernel/2021-July/672813.html

Also available here: https://github.com/apritzel/linux/commits/h616-v9

Thanks!
Andre

==================
This series gathers patches to support the Allwinner H616 SoC. This is
a rather uninspired SoC (Quad-A53 with the usual peripherals), but
allows for some cheap development boards and TV boxes, and supports
up to 4GB of DRAM.

Some DT binding patches are sprinkled throughout the series, to add
the new compatible names right before they are used.
Patch 3-7 add support for the new RTC: the date is now stored as a
linear number, not broken down into day-month-year. The benefit is that
this lifts the limit of the old date counter, which would have rolled
over around 2032. Also the alarm setting is using the same storage
format as the current time, compared to the number of seconds left used
in existing SoCs.
Eventually we get the .dtsi for the SoC in patch 8, and the .dts for
the OrangePi Zero2 board[1] in the penultimate patch, followed by
the .dts for the X96 Mate TV box[2] in the final commit.

U-Boot and Trusted Firmware support is now merged in released versions,
it allows booting via FEL or SD card, also you can TFTP kernels in on
the OrangePi Zero 2 board.

Many thanks to Jernej for his tremendous help on this, also for the
awesome input and help from the #linux-sunxi Freenode channel.

The whole series (including the pinctrl fix) can also be found here:
https://github.com/apritzel/linux/commits/h616-v8

Happy reviewing!

Cheers,
Andre

[1] https://linux-sunxi.org/Orange_Pi_Zero_2
[2] https://linux-sunxi.org/X96_Mate

Changelog v8 .. v9:
- RTC: Rely on the division to split of the H:M:S part from the day part
- Add Jernej's Review tags

Changelog v7 .. v8:
- Rebase on top of 5.14-rc1, which already includes the previous v7 02/19
- Drop USB and Ethernet patches (to keep series small)
- Use "clocks: false" in RTC DT binding (2/11)
- Include fix for RTC overflow check (3/11)
- Use div_64() to avoid linking error on some 32-bit platforms (4+5/11)
- Adjust to changed RTC overflow check (5/11)
- Drop USB nodes from .dtsi file
- Move mmc-ddr-1_8v property from .dtsi file into board .dts
- Fix DTC warnings (underscore in node name, soc at 0, #a-c in IRQ controllers)

Changelog v6 .. v7:
- Fix AXP305 binding documentation blunder (01/19)
- Improve new linear day support (use existing conversion functions) (04/19)
- Add support for changed RTC alarm registers (05/19)
- Add support for RTCs without a LOSC clock (06/19)
- Rework USB PHY2 SIDDQ quirk to use PHY clocks directly (14/19)
- Add X96 Mate compatible string to binding doc (17/19)
- Add Rob's ACKs

Changelog v5 .. v6:
- Drop already merged clock, pinctrl and MMC support from this series
- Properly fix AXP support by skipping power key initialisation
- Add patch to support new RTC date storage encoding
- Re-add USB HCI PHY refactoring
- Add patch to allow USB reset line sharing
- Add patch to introduce quirk for PHY2 SIDDQ clearing
- Re-add USB nodes to the .dtsi
- Add USB gadget support
- Add DT for X96 Mate TV box

Changelog v4 .. v5:
- Fix CCU binding to pass dtbs_check
- Add RSB compatible string to binding doc
- Rename IR pin name to pass dtbs_check
- Add EMAC compatible string to binding doc
- Drop USB PHY support and binding doc patches 
- Drop USB nodes from .dtsi and .dts
- Drop second EMAC node from .dtsi

Changelog v3 .. v4:
- Drop MMC and pinctrl matches (already in some -next trees)
- Add Maxime's Acks
- Add patch to update the AXP MFD DT bindings
- Add new patch (05/21) to fix axp20x-pek driver
- Change AXP IRQ fix to check for invalid IRQ line number
- Split joint DT bindings patch (v3 18/21) into subsystems
- move dwmac variable to keep christmas tree
- Use enums for USB PHY compatible strings in DT binding
- Enable watchdog (briefly verified to work)
- Add PHY2 to HCI1&3, this fixes USB
- limit r-ccu register frame length to not collide with NMI controller
- add interrupt-controller property to AXP DT node

Changelog v2 .. v3:
- Add Rob's Acks
- Drop redundant maxItems from pinctrl DT binding
- Rename h_i2s* to just i2s* in pinctrl names
- Use more declarative i2s0_d{in,out}{0,1} names
- Add RSB pins to pinctrl
- Include RSB clocks (sharing with newly added H6 versions)
- Fix CEC clock (add 2nd enable bit, also fix predivider flag)
- Rename PMU_UNK1 register in USB PHY
- Add USB and MUSB DT binding patches
- Add MMC/SD speed modes to .dtsi

Changelog v1 .. v2:
- pinctrl: adjust irq bank map to cover undocumented GPIO bank IRQs
- use differing h_i2s0 pin output names
- r-ccu: fix number of used clocks
- ccu: remove PLL-PERIPHy(4X)
- ccu: fix gpu1 divider range
- ccu: fix usb-phy3 parent
- ccu: add missing TV clocks
- ccu: rework to CLK_OF_DECLARE style
- ccu: enable output bit for PLL clocks
- ccu: renumber clocks
- .dtsi: drop sun50i-a64-system-control fallback
- .dtsi: drop unknown SRAM regions
- .dtsi: add more (undocumented) GPIO interrupts
- .dtsi: fix I2C3 pin names
- .dtsi: use a100-emmc fallback for MMC2
- .dtsi: add second EMAC controller
- .dtsi: use H3 MUSB controller fallback
- .dtsi: fix frame size for USB PHY PMU registers
- .dtsi: add USB0 PHY references
- .dtsi: fix IR controller clock source
- .dts: fix LED naming and swap pins
- .dts: use 5V supply parent for USB supply
- .dts: drop dummy IRQ for AXP
- .dts: enable 3V3 header pin power rail
- .dts: add SPI flash node
- .dts: make USB-C port peripheral only
- add IRQ-less AXP support
- add two patches to support more than one EMAC clock
- add patch to rework and extend USB PHY support
- add DT binding documentation patches

Andre Przywara (11):
  dt-bindings: mfd: axp20x: Add AXP305 compatible (plus optional IRQ)
  dt-bindings: rtc: sun6i: Add H616 compatible string
  rtc: sun6i: Fix time overflow handling
  rtc: sun6i: Add support for linear day storage
  rtc: sun6i: Add support for broken-down alarm registers
  rtc: sun6i: Add support for RTCs without external LOSCs
  rtc: sun6i: Add Allwinner H616 support
  arm64: dts: allwinner: Add Allwinner H616 .dtsi file
  dt-bindings: arm: sunxi: Add two H616 board compatible strings
  arm64: dts: allwinner: h616: Add OrangePi Zero 2 board support
  arm64: dts: allwinner: h616: Add X96 Mate TV box support

 .../devicetree/bindings/arm/sunxi.yaml        |  10 +
 .../devicetree/bindings/mfd/axp20x.txt        |   3 +-
 .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml |  14 +
 arch/arm64/boot/dts/allwinner/Makefile        |   2 +
 .../allwinner/sun50i-h616-orangepi-zero2.dts  | 204 +++++++
 .../dts/allwinner/sun50i-h616-x96-mate.dts    | 178 ++++++
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 575 ++++++++++++++++++
 drivers/rtc/rtc-sun6i.c                       | 169 +++--
 8 files changed, 1103 insertions(+), 52 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi

-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:42 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:42 +0100
Subject: [PATCH v9 01/11] dt-bindings: mfd: axp20x: Add AXP305 compatible
 (plus optional IRQ)
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-2-andre.przywara@arm.com>

The AXP305 PMIC used on many boards with the H616 SoC seems to be fully
compatible to the AXP805 PMIC, so add the proper chain of compatible
strings.

Also at least on one board (Orangepi Zero2) there is no interrupt line
connected to the CPU, so make the "interrupts" property optional.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/mfd/axp20x.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
index 4991a6415796..2b53dcc0ea61 100644
--- a/Documentation/devicetree/bindings/mfd/axp20x.txt
+++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
@@ -26,10 +26,10 @@ Required properties:
     * "x-powers,axp803"
     * "x-powers,axp806"
     * "x-powers,axp805", "x-powers,axp806"
+    * "x-powers,axp305", "x-powers,axp805", "x-powers,axp806"
     * "x-powers,axp809"
     * "x-powers,axp813"
 - reg: The I2C slave address or RSB hardware address for the AXP chip
-- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
 - interrupt-controller: The PMIC has its own internal IRQs
 - #interrupt-cells: Should be set to 1
 
@@ -43,6 +43,7 @@ more information:
 			AXP20x/LDO3: software-based implementation
 
 Optional properties:
+- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
 - x-powers,dcdc-freq: defines the work frequency of DC-DC in KHz
 		      AXP152/20X: range:  750-1875, Default: 1.5 MHz
 		      AXP22X/8XX: range: 1800-4050, Default: 3   MHz
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:43 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:43 +0100
Subject: [PATCH v9 02/11] dt-bindings: rtc: sun6i: Add H616 compatible string
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-3-andre.przywara@arm.com>

Add the obvious compatible name to the existing RTC binding.
The actual RTC part of the device uses a different day/month/year
storage scheme, so it's not compatible with the previous devices.
Also the clock part is quite different, as there is no external 32K LOSC
oscillator input.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml      | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
index beeb90e55727..d8a6500e5840 100644
--- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
@@ -26,6 +26,7 @@ properties:
           - const: allwinner,sun50i-a64-rtc
           - const: allwinner,sun8i-h3-rtc
       - const: allwinner,sun50i-h6-rtc
+      - const: allwinner,sun50i-h616-rtc
 
   reg:
     maxItems: 1
@@ -104,6 +105,19 @@ allOf:
           minItems: 3
           maxItems: 3
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: allwinner,sun50i-h616-rtc
+
+    then:
+      properties:
+        clock-output-names:
+          minItems: 3
+          maxItems: 3
+        clocks: false
+
   - if:
       properties:
         compatible:
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:45 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:45 +0100
Subject: [PATCH v9 04/11] rtc: sun6i: Add support for linear day storage
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-5-andre.przywara@arm.com>

Newer versions of the Allwinner RTC, as for instance found in the H616
SoC, no longer store a broken-down day/month/year representation in the
RTC_DAY_REG, but just a linear day number.
The user manual does not give any indication about the expected epoch
time of this day count, but the BSP kernel uses the UNIX epoch, which
allows easy support due to existing conversion functions in the kernel.

Allow tagging a compatible string with a flag, and use that to mark
those new RTCs. Then convert between a UNIX day number (converted into
seconds) and the broken-down day representation using mktime64() and
time64_to_tm() in the set_time/get_time functions.

That enables support for the RTC in those new chips.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 69 +++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 23 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c551ebf0ac00..a980d4e7408d 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -110,6 +110,8 @@
 #define SUN6I_YEAR_MIN				1970
 #define SUN6I_YEAR_OFF				(SUN6I_YEAR_MIN - 1900)
 
+#define SECS_PER_DAY				(24 * 3600ULL)
+
 /*
  * There are other differences between models, including:
  *
@@ -133,12 +135,15 @@ struct sun6i_rtc_clk_data {
 	unsigned int has_auto_swt : 1;
 };
 
+#define RTC_LINEAR_DAY	BIT(0)
+
 struct sun6i_rtc_dev {
 	struct rtc_device *rtc;
 	const struct sun6i_rtc_clk_data *data;
 	void __iomem *base;
 	int irq;
 	time64_t alarm;
+	unsigned long flags;
 
 	struct clk_hw hw;
 	struct clk_hw *int_osc;
@@ -467,22 +472,30 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 	} while ((date != readl(chip->base + SUN6I_RTC_YMD)) ||
 		 (time != readl(chip->base + SUN6I_RTC_HMS)));
 
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/*
+		 * Newer chips store a linear day number, the manual
+		 * does not mandate any epoch base. The BSP driver uses
+		 * the UNIX epoch, let's just copy that, as it's the
+		 * easiest anyway.
+		 */
+		rtc_time64_to_tm((date & 0xffff) * SECS_PER_DAY, rtc_tm);
+	} else {
+		rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date);
+		rtc_tm->tm_mon  = SUN6I_DATE_GET_MON_VALUE(date) - 1;
+		rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date);
+
+		/*
+		 * switch from (data_year->min)-relative offset to
+		 * a (1900)-relative one
+		 */
+		rtc_tm->tm_year += SUN6I_YEAR_OFF;
+	}
+
 	rtc_tm->tm_sec  = SUN6I_TIME_GET_SEC_VALUE(time);
 	rtc_tm->tm_min  = SUN6I_TIME_GET_MIN_VALUE(time);
 	rtc_tm->tm_hour = SUN6I_TIME_GET_HOUR_VALUE(time);
 
-	rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date);
-	rtc_tm->tm_mon  = SUN6I_DATE_GET_MON_VALUE(date);
-	rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date);
-
-	rtc_tm->tm_mon  -= 1;
-
-	/*
-	 * switch from (data_year->min)-relative offset to
-	 * a (1900)-relative one
-	 */
-	rtc_tm->tm_year += SUN6I_YEAR_OFF;
-
 	return 0;
 }
 
@@ -567,20 +580,25 @@ static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
 	u32 date = 0;
 	u32 time = 0;
 
-	rtc_tm->tm_year -= SUN6I_YEAR_OFF;
-	rtc_tm->tm_mon += 1;
-
-	date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
-		SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon)  |
-		SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
-
-	if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN))
-		date |= SUN6I_LEAP_SET_VALUE(1);
-
 	time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec)  |
 		SUN6I_TIME_SET_MIN_VALUE(rtc_tm->tm_min)  |
 		SUN6I_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour);
 
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/* The division will cut off the H:M:S part of rtc_tm. */
+		date = div_u64(rtc_tm_to_time64(rtc_tm), SECS_PER_DAY);
+	} else {
+		rtc_tm->tm_year -= SUN6I_YEAR_OFF;
+		rtc_tm->tm_mon += 1;
+
+		date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
+			SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon)  |
+			SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
+
+		if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN))
+			date |= SUN6I_LEAP_SET_VALUE(1);
+	}
+
 	/* Check whether registers are writable */
 	if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
 			   SUN6I_LOSC_CTRL_ACC_MASK, 50)) {
@@ -674,6 +692,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, chip);
 
+	chip->flags = (unsigned long)of_device_get_match_data(&pdev->dev);
+
 	chip->irq = platform_get_irq(pdev, 0);
 	if (chip->irq < 0)
 		return chip->irq;
@@ -720,7 +740,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 		return PTR_ERR(chip->rtc);
 
 	chip->rtc->ops = &sun6i_rtc_ops;
-	chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */
+	if (chip->flags & RTC_LINEAR_DAY)
+		chip->rtc->range_max = (65536 * SECS_PER_DAY) - 1;
+	else
+		chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */
 
 	ret = devm_rtc_register_device(chip->rtc);
 	if (ret)
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:44 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:44 +0100
Subject: [PATCH v9 03/11] rtc: sun6i: Fix time overflow handling
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-4-andre.przywara@arm.com>

Using "unsigned long" for UNIX timestamps is never a good idea, and
comparing the value of such a variable against U32_MAX does not do
anything useful on 32-bit systems.

Use the proper time64_t type when dealing with timestamps, and avoid
cutting down the time range unnecessarily. This also fixes the flawed
check for the alarm time being too far into the future.

The check for this condition is actually somewhat theoretical, as the
RTC counts till 2033 only anyways, and 2^32 seconds from now is not
before the year 2157 - at which point I hope nobody will be using this
hardware anymore.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index adec1b14a8de..c551ebf0ac00 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -138,7 +138,7 @@ struct sun6i_rtc_dev {
 	const struct sun6i_rtc_clk_data *data;
 	void __iomem *base;
 	int irq;
-	unsigned long alarm;
+	time64_t alarm;
 
 	struct clk_hw hw;
 	struct clk_hw *int_osc;
@@ -510,10 +510,8 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
 	struct rtc_time *alrm_tm = &wkalrm->time;
 	struct rtc_time tm_now;
-	unsigned long time_now = 0;
-	unsigned long time_set = 0;
-	unsigned long time_gap = 0;
-	int ret = 0;
+	time64_t time_now, time_set;
+	int ret;
 
 	ret = sun6i_rtc_gettime(dev, &tm_now);
 	if (ret < 0) {
@@ -528,9 +526,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 		return -EINVAL;
 	}
 
-	time_gap = time_set - time_now;
-
-	if (time_gap > U32_MAX) {
+	if ((time_set - time_now) > U32_MAX) {
 		dev_err(dev, "Date too far in the future\n");
 		return -EINVAL;
 	}
@@ -539,7 +535,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	writel(0, chip->base + SUN6I_ALRM_COUNTER);
 	usleep_range(100, 300);
 
-	writel(time_gap, chip->base + SUN6I_ALRM_COUNTER);
+	writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
 	chip->alarm = time_set;
 
 	sun6i_rtc_setaie(wkalrm->enabled, chip);
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:46 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:46 +0100
Subject: [PATCH v9 05/11] rtc: sun6i: Add support for broken-down alarm
 registers
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-6-andre.przywara@arm.com>

Newer versions of the Allwinner RTC, for instance as found in the H616
SoC, not only store the current day as a linear number, but also change
the way the alarm is handled: There are now two registers, that
explicitly store the wakeup time, in the same format as the current
time.

Add support for that variant by writing the requested wakeup time
directly into the registers, instead of programming the seconds left, as
the old SoCs required.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 57 +++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index a980d4e7408d..752bea949050 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -48,7 +48,8 @@
 
 /* Alarm 0 (counter) */
 #define SUN6I_ALRM_COUNTER			0x0020
-#define SUN6I_ALRM_CUR_VAL			0x0024
+/* This holds the remaining alarm seconds on older SoCs (current value) */
+#define SUN6I_ALRM_COUNTER_HMS			0x0024
 #define SUN6I_ALRM_EN				0x0028
 #define SUN6I_ALRM_EN_CNT_EN			BIT(0)
 #define SUN6I_ALRM_IRQ_EN			0x002c
@@ -523,32 +524,54 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
 	struct rtc_time *alrm_tm = &wkalrm->time;
 	struct rtc_time tm_now;
-	time64_t time_now, time_set;
+	time64_t time_set;
+	u32 counter_val, counter_val_hms;
 	int ret;
 
-	ret = sun6i_rtc_gettime(dev, &tm_now);
-	if (ret < 0) {
-		dev_err(dev, "Error in getting time\n");
-		return -EINVAL;
-	}
-
 	time_set = rtc_tm_to_time64(alrm_tm);
-	time_now = rtc_tm_to_time64(&tm_now);
-	if (time_set <= time_now) {
-		dev_err(dev, "Date to set in the past\n");
-		return -EINVAL;
-	}
 
-	if ((time_set - time_now) > U32_MAX) {
-		dev_err(dev, "Date too far in the future\n");
-		return -EINVAL;
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/*
+		 * The alarm registers hold the actual alarm time, encoded
+		 * in the same way (linear day + HMS) as the current time.
+		 */
+		counter_val_hms = SUN6I_TIME_SET_SEC_VALUE(alrm_tm->tm_sec)  |
+				  SUN6I_TIME_SET_MIN_VALUE(alrm_tm->tm_min)  |
+				  SUN6I_TIME_SET_HOUR_VALUE(alrm_tm->tm_hour);
+		/* The division will cut off the H:M:S part of alrm_tm. */
+		counter_val = div_u64(rtc_tm_to_time64(alrm_tm), SECS_PER_DAY);
+	} else {
+		/* The alarm register holds the number of seconds left. */
+		time64_t time_now;
+
+		ret = sun6i_rtc_gettime(dev, &tm_now);
+		if (ret < 0) {
+			dev_err(dev, "Error in getting time\n");
+			return -EINVAL;
+		}
+
+		time_now = rtc_tm_to_time64(&tm_now);
+		if (time_set <= time_now) {
+			dev_err(dev, "Date to set in the past\n");
+			return -EINVAL;
+		}
+		if ((time_set - time_now) > U32_MAX) {
+			dev_err(dev, "Date too far in the future\n");
+			return -EINVAL;
+		}
+
+		counter_val = time_set - time_now;
 	}
 
 	sun6i_rtc_setaie(0, chip);
 	writel(0, chip->base + SUN6I_ALRM_COUNTER);
+	if (chip->flags & RTC_LINEAR_DAY)
+		writel(0, chip->base + SUN6I_ALRM_COUNTER_HMS);
 	usleep_range(100, 300);
 
-	writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
+	writel(counter_val, chip->base + SUN6I_ALRM_COUNTER);
+	if (chip->flags & RTC_LINEAR_DAY)
+		writel(counter_val_hms, chip->base + SUN6I_ALRM_COUNTER_HMS);
 	chip->alarm = time_set;
 
 	sun6i_rtc_setaie(wkalrm->enabled, chip);
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:47 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:47 +0100
Subject: [PATCH v9 06/11] rtc: sun6i: Add support for RTCs without external
 LOSCs
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-7-andre.przywara@arm.com>

Some newer Allwinner RTCs (for instance the one in the H616 SoC) lack
a pin for an external 32768 Hz oscillator. As a consequence, this LOSC
can't be selected as the RTC clock source, and we must rely on the
internal RC oscillator.
To allow additions of clocks to the RTC node, add a feature bit to ignore
any provided clocks for now (the current code would think this is the
external LOSC). Later DTs and code can then for instance add the PLL
based clock input, and older kernel won't get confused.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 752bea949050..fe1bee3a4ec6 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -134,6 +134,7 @@ struct sun6i_rtc_clk_data {
 	unsigned int export_iosc : 1;
 	unsigned int has_losc_en : 1;
 	unsigned int has_auto_swt : 1;
+	unsigned int no_ext_losc : 1;
 };
 
 #define RTC_LINEAR_DAY	BIT(0)
@@ -256,7 +257,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
 	}
 
 	/* Switch to the external, more precise, oscillator, if present */
-	if (of_get_property(node, "clocks", NULL)) {
+	if (!rtc->data->no_ext_losc && of_get_property(node, "clocks", NULL)) {
 		reg |= SUN6I_LOSC_CTRL_EXT_OSC;
 		if (rtc->data->has_losc_en)
 			reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN;
@@ -282,14 +283,19 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
 	}
 
 	parents[0] = clk_hw_get_name(rtc->int_osc);
-	/* If there is no external oscillator, this will be NULL and ... */
-	parents[1] = of_clk_get_parent_name(node, 0);
+	if (rtc->data->no_ext_losc) {
+		parents[1] = NULL;
+		init.num_parents = 1;
+	} else {
+		/* If there is no external oscillator, this will be NULL and */
+		parents[1] = of_clk_get_parent_name(node, 0);
+		/* ... number of clock parents will be 1. */
+		init.num_parents = of_clk_get_parent_count(node) + 1;
+	}
 
 	rtc->hw.init = &init;
 
 	init.parent_names = parents;
-	/* ... number of clock parents will be 1. */
-	init.num_parents = of_clk_get_parent_count(node) + 1;
 	of_property_read_string_index(node, "clock-output-names", 0,
 				      &init.name);
 
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:48 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:48 +0100
Subject: [PATCH v9 07/11] rtc: sun6i: Add Allwinner H616 support
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-8-andre.przywara@arm.com>

The H616 RTC changes its day storage to the newly introduced linear day
scheme, so pair the new compatible string with this feature flag.
The clock part is missing an external 32768 Hz oscillator input pin,
for future expansion we must thus ignore any provided clock for now.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index fe1bee3a4ec6..77db4f0a042c 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -392,6 +392,23 @@ static void __init sun50i_h6_rtc_clk_init(struct device_node *node)
 CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc",
 		      sun50i_h6_rtc_clk_init);
 
+static const struct sun6i_rtc_clk_data sun50i_h616_rtc_data = {
+	.rc_osc_rate = 16000000,
+	.fixed_prescaler = 32,
+	.has_prescaler = 1,
+	.has_out_clk = 1,
+	.export_iosc = 1,
+	.no_ext_losc = 1,
+};
+
+static void __init sun50i_h616_rtc_clk_init(struct device_node *node)
+{
+	sun6i_rtc_clk_init(node, &sun50i_h616_rtc_data);
+}
+
+CLK_OF_DECLARE_DRIVER(sun50i_h616_rtc_clk, "allwinner,sun50i-h616-rtc",
+		      sun50i_h616_rtc_clk_init);
+
 /*
  * The R40 user manual is self-conflicting on whether the prescaler is
  * fixed or configurable. The clock diagram shows it as fixed, but there
@@ -797,6 +814,8 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
 	{ .compatible = "allwinner,sun8i-v3-rtc" },
 	{ .compatible = "allwinner,sun50i-h5-rtc" },
 	{ .compatible = "allwinner,sun50i-h6-rtc" },
+	{ .compatible = "allwinner,sun50i-h616-rtc",
+		.data = (void *)RTC_LINEAR_DAY },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:50 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:50 +0100
Subject: [PATCH v9 09/11] dt-bindings: arm: sunxi: Add two H616 board
 compatible strings
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-10-andre.przywara@arm.com>

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index 889128acf49a..1c557a736d86 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -848,6 +848,11 @@ properties:
           - const: yones-toptech,bs1078-v2
           - const: allwinner,sun6i-a31s
 
+      - description: X96 Mate TV box
+        items:
+          - const: hechuang,x96-mate
+          - const: allwinner,sun50i-h616
+
       - description: Xunlong OrangePi
         items:
           - const: xunlong,orangepi
@@ -948,4 +953,9 @@ properties:
           - const: xunlong,orangepi-zero-plus2-h3
           - const: allwinner,sun8i-h3
 
+      - description: Xunlong OrangePi Zero 2
+        items:
+          - const: xunlong,orangepi-zero2
+          - const: allwinner,sun50i-h616
+
 additionalProperties: true
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:49 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:49 +0100
Subject: [PATCH v9 08/11] arm64: dts: allwinner: Add Allwinner H616 .dtsi file
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-9-andre.przywara@arm.com>

This (relatively) new SoC is similar to the H6, but drops the (broken)
PCIe support and the USB 3.0 controller. It also gets the management
controller removed, which in turn removes *some*, but not all of the
devices formerly dedicated to the ARISC (CPUS).
And while there is still the extra sunxi interrupt controller, the
package lacks the corresponding NMI pin, so no interrupts for the PMIC.

The reserved memory node is actually handled by Trusted Firmware now,
but U-Boot fails to propagate this to a separately loaded DTB, so we
keep it in here for now, until U-Boot learns to do this properly.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 575 ++++++++++++++++++
 1 file changed, 575 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
new file mode 100644
index 000000000000..6a15ff2e7ebf
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -0,0 +1,575 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2020 Arm Ltd.
+// based on the H6 dtsi, which is:
+//   Copyright (C) 2017 Icenowy Zheng <icenowy at aosc.io>
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sun50i-h616-ccu.h>
+#include <dt-bindings/clock/sun50i-h6-r-ccu.h>
+#include <dt-bindings/reset/sun50i-h616-ccu.h>
+#include <dt-bindings/reset/sun50i-h6-r-ccu.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <0>;
+			enable-method = "psci";
+			clocks = <&ccu CLK_CPUX>;
+		};
+
+		cpu1: cpu at 1 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <1>;
+			enable-method = "psci";
+			clocks = <&ccu CLK_CPUX>;
+		};
+
+		cpu2: cpu at 2 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <2>;
+			enable-method = "psci";
+			clocks = <&ccu CLK_CPUX>;
+		};
+
+		cpu3: cpu at 3 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <3>;
+			enable-method = "psci";
+			clocks = <&ccu CLK_CPUX>;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* 512KiB reserved for ARM Trusted Firmware (BL31) */
+		secmon_reserved: secmon at 40000000 {
+			reg = <0x0 0x40000000 0x0 0x80000>;
+			no-map;
+		};
+	};
+
+	osc24M: osc24M-clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "osc24M";
+	};
+
+	pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		arm,no-tick-in-suspend;
+		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)>;
+	};
+
+	soc at 0 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x0 0x40000000>;
+
+		syscon: syscon at 3000000 {
+			compatible = "allwinner,sun50i-h616-system-control";
+			reg = <0x03000000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			sram_c: sram at 28000 {
+				compatible = "mmio-sram";
+				reg = <0x00028000 0x30000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x00028000 0x30000>;
+			};
+		};
+
+		ccu: clock at 3001000 {
+			compatible = "allwinner,sun50i-h616-ccu";
+			reg = <0x03001000 0x1000>;
+			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		watchdog: watchdog at 30090a0 {
+			compatible = "allwinner,sun50i-h616-wdt",
+				     "allwinner,sun6i-a31-wdt";
+			reg = <0x030090a0 0x20>;
+			interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&osc24M>;
+			status = "okay";
+		};
+
+		pio: pinctrl at 300b000 {
+			compatible = "allwinner,sun50i-h616-pinctrl";
+			reg = <0x0300b000 0x400>;
+			interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+
+			ext_rgmii_pins: rgmii-pins {
+				pins = "PI0", "PI1", "PI2", "PI3", "PI4",
+				       "PI5", "PI7", "PI8", "PI9", "PI10",
+				       "PI11", "PI12", "PI13", "PI14", "PI15",
+				       "PI16";
+				function = "emac0";
+				drive-strength = <40>;
+			};
+
+			i2c0_pins: i2c0-pins {
+				pins = "PI6", "PI7";
+				function = "i2c0";
+			};
+
+			i2c3_ph_pins: i2c3-ph-pins {
+				pins = "PH4", "PH5";
+				function = "i2c3";
+			};
+
+			ir_rx_pin: ir-rx-pin {
+				pins = "PH10";
+				function = "ir_rx";
+			};
+
+			mmc0_pins: mmc0-pins {
+				pins = "PF0", "PF1", "PF2", "PF3",
+				       "PF4", "PF5";
+				function = "mmc0";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+
+			mmc1_pins: mmc1-pins {
+				pins = "PG0", "PG1", "PG2", "PG3",
+				       "PG4", "PG5";
+				function = "mmc1";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+
+			mmc2_pins: mmc2-pins {
+				pins = "PC0", "PC1", "PC5", "PC6",
+				       "PC8", "PC9", "PC10", "PC11",
+				       "PC13", "PC14", "PC15", "PC16";
+				function = "mmc2";
+				drive-strength = <30>;
+				bias-pull-up;
+			};
+
+			spi0_pins: spi0-pins {
+				pins = "PC0", "PC2", "PC3", "PC4";
+				function = "spi0";
+			};
+
+			spi1_pins: spi1-pins {
+				pins = "PH6", "PH7", "PH8";
+				function = "spi1";
+			};
+
+			spi1_cs_pin: spi1-cs-pin {
+				pins = "PH5";
+				function = "spi1";
+			};
+
+			uart0_ph_pins: uart0-ph-pins {
+				pins = "PH0", "PH1";
+				function = "uart0";
+			};
+
+			uart1_pins: uart1-pins {
+				pins = "PG6", "PG7";
+				function = "uart1";
+			};
+
+			uart1_rts_cts_pins: uart1-rts-cts-pins {
+				pins = "PG8", "PG9";
+				function = "uart1";
+			};
+		};
+
+		gic: interrupt-controller at 3021000 {
+			compatible = "arm,gic-400";
+			reg = <0x03021000 0x1000>,
+			      <0x03022000 0x2000>,
+			      <0x03024000 0x2000>,
+			      <0x03026000 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+		};
+
+		mmc0: mmc at 4020000 {
+			compatible = "allwinner,sun50i-h616-mmc",
+				     "allwinner,sun50i-a100-mmc";
+			reg = <0x04020000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC0>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc0_pins>;
+			status = "disabled";
+			max-frequency = <150000000>;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			mmc-ddr-3_3v;
+			cap-sdio-irq;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc1: mmc at 4021000 {
+			compatible = "allwinner,sun50i-h616-mmc",
+				     "allwinner,sun50i-a100-mmc";
+			reg = <0x04021000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC1>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc1_pins>;
+			status = "disabled";
+			max-frequency = <150000000>;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			mmc-ddr-3_3v;
+			cap-sdio-irq;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc2: mmc at 4022000 {
+			compatible = "allwinner,sun50i-h616-emmc",
+				     "allwinner,sun50i-a100-emmc";
+			reg = <0x04022000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC2>, <&ccu CLK_MMC2>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC2>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc2_pins>;
+			status = "disabled";
+			max-frequency = <150000000>;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			mmc-ddr-3_3v;
+			cap-sdio-irq;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		uart0: serial at 5000000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05000000 0x400>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART0>;
+			resets = <&ccu RST_BUS_UART0>;
+			status = "disabled";
+		};
+
+		uart1: serial at 5000400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05000400 0x400>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART1>;
+			resets = <&ccu RST_BUS_UART1>;
+			status = "disabled";
+		};
+
+		uart2: serial at 5000800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05000800 0x400>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART2>;
+			resets = <&ccu RST_BUS_UART2>;
+			status = "disabled";
+		};
+
+		uart3: serial at 5000c00 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05000c00 0x400>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART3>;
+			resets = <&ccu RST_BUS_UART3>;
+			status = "disabled";
+		};
+
+		uart4: serial at 5001000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05001000 0x400>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART4>;
+			resets = <&ccu RST_BUS_UART4>;
+			status = "disabled";
+		};
+
+		uart5: serial at 5001400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x05001400 0x400>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART5>;
+			resets = <&ccu RST_BUS_UART5>;
+			status = "disabled";
+		};
+
+		i2c0: i2c at 5002000 {
+			compatible = "allwinner,sun50i-h616-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x05002000 0x400>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2C0>;
+			resets = <&ccu RST_BUS_I2C0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c1: i2c at 5002400 {
+			compatible = "allwinner,sun50i-h616-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x05002400 0x400>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2C1>;
+			resets = <&ccu RST_BUS_I2C1>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c2: i2c at 5002800 {
+			compatible = "allwinner,sun50i-h616-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x05002800 0x400>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2C2>;
+			resets = <&ccu RST_BUS_I2C2>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c3: i2c at 5002c00 {
+			compatible = "allwinner,sun50i-h616-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x05002c00 0x400>;
+			interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2C3>;
+			resets = <&ccu RST_BUS_I2C3>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c4: i2c at 5003000 {
+			compatible = "allwinner,sun50i-h616-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x05003000 0x400>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_I2C4>;
+			resets = <&ccu RST_BUS_I2C4>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		spi0: spi at 5010000 {
+			compatible = "allwinner,sun50i-h616-spi",
+				     "allwinner,sun8i-h3-spi";
+			reg = <0x05010000 0x1000>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
+			clock-names = "ahb", "mod";
+			resets = <&ccu RST_BUS_SPI0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi0_pins>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		spi1: spi at 5011000 {
+			compatible = "allwinner,sun50i-h616-spi",
+				     "allwinner,sun8i-h3-spi";
+			reg = <0x05011000 0x1000>;
+			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
+			clock-names = "ahb", "mod";
+			resets = <&ccu RST_BUS_SPI1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi1_pins>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		emac0: ethernet at 5020000 {
+			compatible = "allwinner,sun50i-h616-emac",
+				     "allwinner,sun50i-a64-emac";
+			syscon = <&syscon>;
+			reg = <0x05020000 0x10000>;
+			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+			resets = <&ccu RST_BUS_EMAC0>;
+			reset-names = "stmmaceth";
+			clocks = <&ccu CLK_BUS_EMAC0>;
+			clock-names = "stmmaceth";
+			status = "disabled";
+
+			mdio0: mdio {
+				compatible = "snps,dwmac-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		rtc: rtc at 7000000 {
+			compatible = "allwinner,sun50i-h616-rtc";
+			reg = <0x07000000 0x400>;
+			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+			clock-output-names = "osc32k", "osc32k-out", "iosc";
+			#clock-cells = <1>;
+		};
+
+		r_ccu: clock at 7010000 {
+			compatible = "allwinner,sun50i-h616-r-ccu";
+			reg = <0x07010000 0x210>;
+			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
+				 <&ccu CLK_PLL_PERIPH0>;
+			clock-names = "hosc", "losc", "iosc", "pll-periph";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		r_pio: pinctrl at 7022000 {
+			compatible = "allwinner,sun50i-h616-r-pinctrl";
+			reg = <0x07022000 0x400>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&rtc 0>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+
+			r_i2c_pins: r-i2c-pins {
+				pins = "PL0", "PL1";
+				function = "s_i2c";
+			};
+
+			r_rsb_pins: r-rsb-pins {
+				pins = "PL0", "PL1";
+				function = "s_rsb";
+			};
+		};
+
+		ir: ir at 7040000 {
+				compatible = "allwinner,sun50i-h616-ir",
+					     "allwinner,sun6i-a31-ir";
+				reg = <0x07040000 0x400>;
+				interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&r_ccu CLK_R_APB1_IR>,
+					 <&r_ccu CLK_IR>;
+				clock-names = "apb", "ir";
+				resets = <&r_ccu RST_R_APB1_IR>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&ir_rx_pin>;
+				status = "disabled";
+		};
+
+		r_i2c: i2c at 7081400 {
+			compatible = "allwinner,sun50i-h616-i2c",
+				     "allwinner,sun6i-a31-i2c";
+			reg = <0x07081400 0x400>;
+			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&r_ccu CLK_R_APB2_I2C>;
+			resets = <&r_ccu RST_R_APB2_I2C>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		r_rsb: rsb at 7083000 {
+			compatible = "allwinner,sun50i-h616-rsb",
+				     "allwinner,sun8i-a23-rsb";
+			reg = <0x07083000 0x400>;
+			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&r_ccu CLK_R_APB2_RSB>;
+			clock-frequency = <3000000>;
+			resets = <&r_ccu RST_R_APB2_RSB>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&r_rsb_pins>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+};
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:51 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:51 +0100
Subject: [PATCH v9 10/11] arm64: dts: allwinner: h616: Add OrangePi Zero 2
 board support
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-11-andre.przywara@arm.com>

The OrangePi Zero 2 is a development board with the new H616 SoC. It
comes with the following features:
  - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
  - 512MiB/1GiB DDR3 DRAM
  - AXP305 PMIC
  - Raspberry-Pi-1 compatible GPIO header
  - extra 13 pin expansion header, exposing pins for 2x USB 2.0 ports
  - 1 USB 2.0 host port
  - 1 USB 2.0 type C port (power supply + OTG)
  - MicroSD slot
  - on-board 2MiB bootable SPI NOR flash
  - 1Gbps Ethernet port (via RTL8211F PHY)
  - micro-HDMI port
  - unsupported Allwinner WiFi/BT chip

For more details see: https://linux-sunxi.org/Orange_Pi_Zero_2

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../allwinner/sun50i-h616-orangepi-zero2.dts  | 204 ++++++++++++++++++
 2 files changed, 205 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index a96d9d2d8dd8..62f8d43cf84d 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -37,3 +37,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-model-b.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
new file mode 100644
index 000000000000..0132c06be96a
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2020 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "OrangePi Zero2";
+	compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616";
+
+	aliases {
+		ethernet0 = &emac0;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			function = LED_FUNCTION_POWER;
+			color = <LED_COLOR_ID_RED>;
+			gpios = <&pio 2 12 GPIO_ACTIVE_HIGH>; /* PC12 */
+			default-state = "on";
+		};
+
+		led-1 {
+			function = LED_FUNCTION_STATUS;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */
+		};
+	};
+
+	reg_vcc5v: vcc5v {
+		/* board wide 5V supply directly from the USB-C socket */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+};
+
+&emac0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ext_rgmii_pins>;
+	phy-mode = "rgmii";
+	phy-handle = <&ext_rgmii_phy>;
+	phy-supply = <&reg_dcdce>;
+	allwinner,rx-delay-ps = <3100>;
+	allwinner,tx-delay-ps = <700>;
+	status = "okay";
+};
+
+&mdio0 {
+	ext_rgmii_phy: ethernet-phy at 1 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+	};
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_dcdce>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;	/* PF6 */
+	bus-width = <4>;
+	status = "okay";
+};
+
+&r_rsb {
+	status = "okay";
+
+	axp305: pmic at 745 {
+		compatible = "x-powers,axp305", "x-powers,axp805",
+			     "x-powers,axp806";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		#address-cells = <0>;
+		reg = <0x745>;
+
+		x-powers,self-working-mode;
+		vina-supply = <&reg_vcc5v>;
+		vinb-supply = <&reg_vcc5v>;
+		vinc-supply = <&reg_vcc5v>;
+		vind-supply = <&reg_vcc5v>;
+		vine-supply = <&reg_vcc5v>;
+		aldoin-supply = <&reg_vcc5v>;
+		bldoin-supply = <&reg_vcc5v>;
+		cldoin-supply = <&reg_vcc5v>;
+
+		regulators {
+			reg_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-sys";
+			};
+
+			reg_aldo2: aldo2 {	/* 3.3V on headers */
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc3v3-ext";
+			};
+
+			reg_aldo3: aldo3 {	/* 3.3V on headers */
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc3v3-ext2";
+			};
+
+			reg_bldo1: bldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc1v8";
+			};
+
+			bldo2 {
+				/* unused */
+			};
+
+			bldo3 {
+				/* unused */
+			};
+
+			bldo4 {
+				/* unused */
+			};
+
+			cldo1 {
+				/* reserved */
+			};
+
+			cldo2 {
+				/* unused */
+			};
+
+			cldo3 {
+				/* unused */
+			};
+
+			reg_dcdca: dcdca {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1080000>;
+				regulator-name = "vdd-cpu";
+			};
+
+			reg_dcdcc: dcdcc {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1080000>;
+				regulator-name = "vdd-gpu-sys";
+			};
+
+			reg_dcdcd: dcdcd {
+				regulator-always-on;
+				regulator-min-microvolt = <1500000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-name = "vdd-dram";
+			};
+
+			reg_dcdce: dcdce {
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-eth-mmc";
+			};
+
+			sw {
+				/* unused */
+			};
+		};
+	};
+};
+
+&spi0  {
+	status = "okay";
+
+	flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};
-- 
2.17.6



From andre.przywara at arm.com  Sun Aug  1 17:39:52 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon,  2 Aug 2021 01:39:52 +0100
Subject: [PATCH v9 11/11] arm64: dts: allwinner: h616: Add X96 Mate TV box
 support
In-Reply-To: <20210802003952.19942-1-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
Message-ID: <20210802003952.19942-12-andre.przywara@arm.com>

The X96 Mate is an Allwinner H616 based TV box, featuring:
  - Four ARM Cortex-A53 cores, Mali-G31 MP2 GPU
  - 2GiB/4GiB RAM (fully usable!)
  - 16/32/64GiB eMMC
  - 100Mbps Ethernet (via embedded AC200 EPHY, not yet supported)
  - Unsupported Allwinner WiFi chip
  - 2 x USB 2.0 host ports
  - HDMI port
  - IR receiver
  - 5V/2A DC power supply via barrel plug

For more information see: https://linux-sunxi.org/X96_Mate

Add a basic devicetree for it, with SD card and eMMC working, as
well as serial and the essential peripherals, like the AXP PMIC.

This DT is somewhat minimal, and should work on many other similar TV
boxes with the Allwinner H616 chip.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../dts/allwinner/sun50i-h616-x96-mate.dts    | 178 ++++++++++++++++++
 2 files changed, 179 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 62f8d43cf84d..14053c566601 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -38,3 +38,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-model-b.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
new file mode 100644
index 000000000000..6334f4e20fd0
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2021 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	model = "X96 Mate";
+	compatible = "hechuang,x96-mate", "allwinner,sun50i-h616";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	reg_vcc5v: vcc5v {
+		/* board wide 5V supply directly from the DC input */
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-5v";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+};
+
+&ir {
+	status = "okay";
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_dcdce>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;	/* PF6 */
+	bus-width = <4>;
+	status = "okay";
+};
+
+&mmc2 {
+	vmmc-supply = <&reg_dcdce>;
+	vqmmc-supply = <&reg_bldo1>;
+	bus-width = <8>;
+	non-removable;
+	cap-mmc-hw-reset;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	status = "okay";
+};
+
+&r_rsb {
+	status = "okay";
+
+	axp305: pmic at 745 {
+		compatible = "x-powers,axp305", "x-powers,axp805",
+			     "x-powers,axp806";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		#address-cells = <0>;
+		reg = <0x745>;
+
+		x-powers,self-working-mode;
+		vina-supply = <&reg_vcc5v>;
+		vinb-supply = <&reg_vcc5v>;
+		vinc-supply = <&reg_vcc5v>;
+		vind-supply = <&reg_vcc5v>;
+		vine-supply = <&reg_vcc5v>;
+		aldoin-supply = <&reg_vcc5v>;
+		bldoin-supply = <&reg_vcc5v>;
+		cldoin-supply = <&reg_vcc5v>;
+
+		regulators {
+			reg_aldo1: aldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-sys";
+			};
+
+			/* Enabled by the Android BSP */
+			reg_aldo2: aldo2 {
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc3v3-ext";
+				status = "disabled";
+			};
+
+			/* Enabled by the Android BSP */
+			reg_aldo3: aldo3 {
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc3v3-ext2";
+				status = "disabled";
+			};
+
+			reg_bldo1: bldo1 {
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc1v8";
+			};
+
+			/* Enabled by the Android BSP */
+			reg_bldo2: bldo2 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc1v8-2";
+				status = "disabled";
+			};
+
+			bldo3 {
+				/* unused */
+			};
+
+			bldo4 {
+				/* unused */
+			};
+
+			cldo1 {
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <2500000>;
+				regulator-name = "vcc2v5";
+			};
+
+			cldo2 {
+				/* unused */
+			};
+
+			cldo3 {
+				/* unused */
+			};
+
+			reg_dcdca: dcdca {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1080000>;
+				regulator-name = "vdd-cpu";
+			};
+
+			reg_dcdcc: dcdcc {
+				regulator-always-on;
+				regulator-min-microvolt = <810000>;
+				regulator-max-microvolt = <1080000>;
+				regulator-name = "vdd-gpu-sys";
+			};
+
+			reg_dcdcd: dcdcd {
+				regulator-always-on;
+				regulator-min-microvolt = <1360000>;
+				regulator-max-microvolt = <1360000>;
+				regulator-name = "vdd-dram";
+			};
+
+			reg_dcdce: dcdce {
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc-eth-mmc";
+			};
+
+			sw {
+				/* unused */
+			};
+		};
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ph_pins>;
+	status = "okay";
+};
-- 
2.17.6



From jitao.shi at mediatek.com  Sun Aug  1 18:07:10 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Mon, 2 Aug 2021 09:07:10 +0800
Subject: [PATCH v5 1/2] dt-bindings: drm/bridge: anx7625: add
 force_dsi_end_without_null
In-Reply-To: <20210802010711.169080-1-jitao.shi@mediatek.com>
References: <20210802010711.169080-1-jitao.shi@mediatek.com>
Message-ID: <20210802010711.169080-2-jitao.shi@mediatek.com>

The force_dsi_end_without_null requires the dsi host ent at
the same time in line.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 .../bindings/display/bridge/analogix,anx7625.yaml           | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
index ab48ab2f4240..8b868a6a3d60 100644
--- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
@@ -43,6 +43,11 @@ properties:
   vdd33-supply:
     description: Regulator that provides the supply 3.3V power.
 
+  force_dsi_end_without_null:
+    description: |
+      Requires the dsi host send the dsi packets on all lanes aligned
+      at the end.
+
   ports:
     $ref: /schemas/graph.yaml#/properties/ports
 
@@ -87,6 +92,7 @@ examples:
             vdd10-supply = <&pp1000_mipibrdg>;
             vdd18-supply = <&pp1800_mipibrdg>;
             vdd33-supply = <&pp3300_mipibrdg>;
+            force_dsi_end_without_null;
 
             ports {
                 #address-cells = <1>;
-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  1 18:07:09 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Mon, 2 Aug 2021 09:07:09 +0800
Subject: [PATCH v5 0/2] force hsa hbp hfp packets multiple of lanenum to avoid
 screen shift 
Message-ID: <20210802010711.169080-1-jitao.shi@mediatek.com>

Changes since v4:
 - Move "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null" before
   "drm/mediatek: force hsa hbp hfp packets multiple of lanenum to avoid".

 - Retitle "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null".


Jitao Shi (2):
  dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null
  drm/mediatek: force hsa hbp hfp packets multiple of lanenum to avoid
    screen shift

 .../bindings/display/bridge/analogix,anx7625.yaml   |  6 ++++++
 drivers/gpu/drm/mediatek/mtk_dsi.c                  | 13 +++++++++++++
 2 files changed, 19 insertions(+)

-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  1 18:07:11 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Mon, 2 Aug 2021 09:07:11 +0800
Subject: [PATCH v5 2/2] drm/mediatek: force hsa hbp hfp packets multiple of
 lanenum to avoid screen shift
In-Reply-To: <20210802010711.169080-1-jitao.shi@mediatek.com>
References: <20210802010711.169080-1-jitao.shi@mediatek.com>
Message-ID: <20210802010711.169080-3-jitao.shi@mediatek.com>

The bridge chip ANX7625 requires the packets on lanes aligned at the end,
or ANX7625 will shift the screen.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ae403c67cbd9..4735e0092ffe 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -194,6 +194,8 @@ struct mtk_dsi {
 	struct clk *hs_clk;
 
 	u32 data_rate;
+	/* force dsi line end without dsi_null data */
+	bool force_dsi_end_without_null;
 
 	unsigned long mode_flags;
 	enum mipi_dsi_pixel_format format;
@@ -499,6 +501,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 		DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
 	}
 
+	if (dsi->force_dsi_end_without_null) {
+		horizontal_sync_active_byte = roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
+		horizontal_frontporch_byte = roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte = roundup(horizontal_backporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte -= (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
+	}
+
 	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
 	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
 	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
@@ -1095,6 +1104,10 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->bridge.of_node = dev->of_node;
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
+	if (dsi->next_bridge)
+		dsi->force_dsi_end_without_null = of_property_read_bool(dsi->next_bridge->of_node,
+									"force_dsi_end_without_null");
+
 	drm_bridge_add(&dsi->bridge);
 
 	ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
-- 
2.25.1

From ck.hu at mediatek.com  Sun Aug  1 19:14:19 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Mon, 2 Aug 2021 10:14:19 +0800
Subject: [PATCH v5 2/3] dts: arm64: mt8183: Add Mediatek MDP3 nodes
In-Reply-To: <20210719074640.25058-3-moudy.ho@mediatek.com>
References: <20210719074640.25058-1-moudy.ho@mediatek.com>
 <20210719074640.25058-3-moudy.ho@mediatek.com>
Message-ID: <1627870459.4533.1.camel@mtksdaap41>

Hi, Moudy:

On Mon, 2021-07-19 at 15:46 +0800, Moudy Ho wrote:
> Add device nodes for Media Data Path 3 (MDP3) modules.
> 
> Signed-off-by: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
> Signed-off-by: daoyuan huang <daoyuan.huang at mediatek.com>
> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> ---
> Depend on:
>    [1] https://urldefense.com/v3/__https://lore.kernel.org/patchwork/patch/1164746/__;!!CTRNKA9wMg0ARbw!zIYDSC1kafxhfEfpyIjKYA5S2fo7ND5cvC3uL06yjladpA-22RCjaGcPPqpKhw$ 
>    [2] https://urldefense.com/v3/__https://patchwork.kernel.org/patch/11703299/__;!!CTRNKA9wMg0ARbw!zIYDSC1kafxhfEfpyIjKYA5S2fo7ND5cvC3uL06yjladpA-22RCjaGerzVNylA$ 
>    [3] https://urldefense.com/v3/__https://patchwork.kernel.org/patch/11283773/__;!!CTRNKA9wMg0ARbw!zIYDSC1kafxhfEfpyIjKYA5S2fo7ND5cvC3uL06yjladpA-22RCjaGe4IDGnpQ$ 
> ---
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi | 114 +++++++++++++++++++++++
>  1 file changed, 114 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> index c5e822b6b77a..30920d6ce7d2 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> @@ -1127,6 +1127,112 @@
>  			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
>  		};
>  
> +		mdp3_rdma0: mdp3_rdma0 at 14001000 {
> +			compatible = "mediatek,mt8183-mdp3",
> +				     "mediatek,mt8183-mdp3-rdma";
> +			mediatek,scp = <&scp>;
> +			mediatek,mdp3-id = <0>;
> +			mdp3-comps = "mediatek,mt8183-mdp3-dl", "mediatek,mt8183-mdp3-dl",
> +				     "mediatek,mt8183-mdp3-imgi", "mediatek,mt8183-mdp3-exto";
> +			mdp3-comp-ids = <0 1 0 1>;
> +			reg = <0 0x14001000 0 0x1000>,
> +			      <0 0x14000000 0 0x1000>,
> +			      <0 0x15020000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
> +						  <&gce SUBSYS_1400XXXX 0 0x1000>,
> +						  <&gce SUBSYS_1502XXXX 0 0x1000>;
> +			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +			clocks = <&mmsys CLK_MM_MDP_RDMA0>,
> +				 <&mmsys CLK_MM_MDP_RSZ1>,
> +				 <&mmsys CLK_MM_MDP_DL_TXCK>,
> +				 <&mmsys CLK_MM_MDP_DL_RX>,
> +				 <&mmsys CLK_MM_IPU_DL_TXCK>,
> +				 <&mmsys CLK_MM_IPU_DL_RX>;
> +			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
> +			mediatek,mmsys = <&mmsys>;
> +			mediatek,mm-mutex = <&mutex>;
> +			mediatek,mailbox-gce = <&gce>;
> +			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
> +				 <&gce 21 CMDQ_THR_PRIO_LOWEST 0>,
> +				 <&gce 22 CMDQ_THR_PRIO_LOWEST 0>,
> +				 <&gce 23 CMDQ_THR_PRIO_LOWEST 0>;
> +			mdp3-rsz0 = <&mdp3_rsz0>; /* debug only */
> +			mdp3-rsz1 = <&mdp3_rsz1>; /* debug only */
> +			mdp3-wrot0 = <&mdp3_wrot0>; /* debug only */
> +			mdp3-wdma0 = <&mdp3_wdma>; /* debug only */
> +			mdp3-ccorr0 = <&mdp3_ccorr>; /* debug only */
> +			gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
> +				     <&gce 0x14010000 SUBSYS_1401XXXX>,
> +				     <&gce 0x14020000 SUBSYS_1402XXXX>,
> +				     <&gce 0x15020000 SUBSYS_1502XXXX>;
> +			mediatek,gce-events = <CMDQ_EVENT_MDP_RDMA0_SOF>,
> +					      <CMDQ_EVENT_MDP_RDMA0_EOF>,
> +					      <CMDQ_EVENT_MDP_RSZ0_SOF>,
> +					      <CMDQ_EVENT_MDP_RSZ1_SOF>,

RSZ event is sent by rsz device, so move this event into rsz device.

> +					      <CMDQ_EVENT_MDP_TDSHP_SOF>,
> +					      <CMDQ_EVENT_MDP_WROT0_SOF>,
> +					      <CMDQ_EVENT_MDP_WROT0_EOF>,
> +					      <CMDQ_EVENT_MDP_WDMA0_SOF>,
> +					      <CMDQ_EVENT_MDP_WDMA0_EOF>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_0>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_1>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_2>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_3>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_4>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_5>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_6>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_7>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_8>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_9>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_10>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_11>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_12>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_13>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_14>,
> +					      <CMDQ_EVENT_WPE_A_DONE>,
> +					      <CMDQ_EVENT_SPE_B_DONE>;

Ditto for these event.

Regards,
CK.

> +		};
> +
> +		mdp3_rsz0: mdp3_rsz0 at 14003000 {
> +			compatible = "mediatek,mt8183-mdp3-rsz";
> +			mediatek,mdp3-id = <0>;
> +			reg = <0 0x14003000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
> +			clocks = <&mmsys CLK_MM_MDP_RSZ0>;
> +		};
> +
> +		mdp3_rsz1: mdp3_rsz1 at 14004000 {
> +			compatible = "mediatek,mt8183-mdp3-rsz";
> +			mediatek,mdp3-id = <1>;
> +			reg = <0 0x14004000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
> +			clocks = <&mmsys CLK_MM_MDP_RSZ1>;
> +		};
> +
> +		mdp3_wrot0: mdp3_wrot0 at 14005000 {
> +			compatible = "mediatek,mt8183-mdp3-wrot";
> +			mediatek,mdp3-id = <0>;
> +			mdp3-comps = "mediatek,mt8183-mdp3-path";
> +			mdp3-comp-ids = <0>;
> +			reg = <0 0x14005000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
> +			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +			clocks = <&mmsys CLK_MM_MDP_WROT0>;
> +			iommus = <&iommu M4U_PORT_MDP_WROT0>;
> +		};
> +
> +		mdp3_wdma: mdp3_wdma at 14006000 {
> +			compatible = "mediatek,mt8183-mdp3-wdma";
> +			mediatek,mdp3-id = <0>;
> +			mdp3-comps = "mediatek,mt8183-mdp3-path";
> +			mdp3-comp-ids = <1>;
> +			reg = <0 0x14006000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
> +			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +			clocks = <&mmsys CLK_MM_MDP_WDMA0>;
> +			iommus = <&iommu M4U_PORT_MDP_WDMA0>;
> +		};
> +
>  		ovl0: ovl at 14008000 {
>  			compatible = "mediatek,mt8183-disp-ovl";
>  			reg = <0 0x14008000 0 0x1000>;
> @@ -1272,6 +1378,14 @@
>  			clock-names = "apb", "smi", "gals0", "gals1";
>  		};
>  
> +		mdp3_ccorr: mdp3_ccorr at 1401c000 {
> +			compatible = "mediatek,mt8183-mdp3-ccorr";
> +			mediatek,mdp3-id = <0>;
> +			reg = <0 0x1401c000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
> +			clocks = <&mmsys CLK_MM_MDP_CCORR>;
> +		};
> +
>  		imgsys: syscon at 15020000 {
>  			compatible = "mediatek,mt8183-imgsys", "syscon";
>  			reg = <0 0x15020000 0 0x1000>;


From tangbin at cmss.chinamobile.com  Sun Aug  1 19:31:58 2021
From: tangbin at cmss.chinamobile.com (tangbin)
Date: Mon, 2 Aug 2021 10:31:58 +0800
Subject: [PATCH] iio: adc: fsl-imx25-gcq: fix the right check and simplify
 code
In-Reply-To: <20210731174551.188aee79@jic23-huawei>
References: <20210727125209.28248-1-tangbin@cmss.chinamobile.com>
 <20210731174551.188aee79@jic23-huawei>
Message-ID: <b84ea3e4-5650-d6ac-36f6-98067b286b45@cmss.chinamobile.com>

Hi Jonathan:

On 2021/8/1 0:45, Jonathan Cameron wrote:
> On Tue, 27 Jul 2021 20:52:09 +0800
> Tang Bin <tangbin at cmss.chinamobile.com> wrote:
>
>> For the function of platform_get_irq(), the example in platform.c is
>> *		int irq = platform_get_irq(pdev, 0);
>> *		if (irq < 0)
>> *			return irq;
>> So the return value of zero is unnecessary to check. And move it
>> up to a little bit can simplify the code jump.
>>
>> Co-developed-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
>> Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
>> Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
> Hi,
>
> Logically it is better to keep the irq handling all together, so
> I would prefer we didn't move it.
Got it in this place.
>
> Also, platform_get_irq() is documented as never returning 0, so the current
> code is not incorrect.  As such, this looks like noise unless there is
> some plan to make use of the 0 return value?  What benefit do we get from
> this change?

Thanks for your reply, I think the benefit of this change maybe just 
simplify the code.

Because the return value is never equal to 0, so the check in here is 
redundant.

We can make the patch like this:

>> ---
>>   drivers/iio/adc/fsl-imx25-gcq.c | 12 ++++--------
>>   1 file changed, 4 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
>> index 8cb51cf7a..d28976f21 100644
>> --- a/drivers/iio/adc/fsl-imx25-gcq.c
>> +++ b/drivers/iio/adc/fsl-imx25-gcq.c
>> @@ -320,6 +320,10 @@ static int mx25_gcq_probe(struct platform_device *pdev)
>>   	if (ret)
>>   		return ret;
>>   
>> +	priv->irq = platform_get_irq(pdev, 0);
>> +	if (priv->irq < 0)
>> +		return priv->irq;
>> +
>>   	for (i = 0; i != 4; ++i) {
>>   		if (!priv->vref[i])
>>   			continue;
>> @@ -336,14 +340,6 @@ static int mx25_gcq_probe(struct platform_device *pdev)
>>   		goto err_vref_disable;
>>   	}
>>   
>> -	priv->irq = platform_get_irq(pdev, 0);
>> -	if (priv->irq <= 0) {
>> -		ret = priv->irq;
>> -		if (!ret)
>> -			ret = -ENXIO;
>> -		goto err_clk_unprepare;
>> -	}
>> -

	priv->irq = platform_get_irq(pdev, 0);
	if (priv->irq < 0) {
		ret = priv->irq;
		goto err_clk_unprepare;
	}

 ??? If you think this is ok, I will send V2 for you. If you think these 
change is meaningless,

just dropped this.

Thanks

Tang Bin






From mpe at ellerman.id.au  Sun Aug  1 19:36:08 2021
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Mon, 02 Aug 2021 12:36:08 +1000
Subject: [PATCH v2] arch: vdso: remove if-conditionals of
 $(c-gettimeofday-y)
In-Reply-To: <20210731060020.12913-1-masahiroy@kernel.org>
References: <20210731060020.12913-1-masahiroy@kernel.org>
Message-ID: <87v94ozi7b.fsf@mpe.ellerman.id.au>

Masahiro Yamada <masahiroy at kernel.org> writes:
> arm, arm64, csky, mips, powerpc always select GENERIC_GETTIMEOFDAY,
> hence $(gettimeofday-y) never becomes empty.
>
> riscv conditionally selects GENERIC_GETTIMEOFDAY when MMU=y && 64BIT=y,
> but arch/riscv/kernel/vdso/vgettimeofday.o is built only under that
> condition. So, you can always define CFLAGS_vgettimeofday.o
>
> Remove all the meaningless conditionals.
>
> Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> ---
>
> Changes in v2:
>   - Fix csky as well
>
>  arch/arm/vdso/Makefile              |  4 ----
>  arch/arm64/kernel/vdso/Makefile     |  5 +----
>  arch/arm64/kernel/vdso32/Makefile   |  3 ---
>  arch/csky/kernel/vdso/Makefile      |  4 +---
>  arch/mips/vdso/Makefile             |  2 --
>  arch/powerpc/kernel/vdso32/Makefile | 14 ++++++--------
>  arch/powerpc/kernel/vdso64/Makefile | 14 ++++++--------

I noticed this the other day and was puzzled why we still needed
the conditional, thanks for cleaning it up.

Acked-by: Michael Ellerman <mpe at ellerman.id.au> (powerpc)

cheers


From wangkefeng.wang at huawei.com  Sun Aug  1 19:39:04 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 2 Aug 2021 10:39:04 +0800
Subject: [PATCH v2 1/3] vmalloc: Choose a better start address in
 vm_area_register_early()
In-Reply-To: <20210801152311.GB28489@arm.com>
References: <20210720025105.103680-1-wangkefeng.wang@huawei.com>
 <20210720025105.103680-2-wangkefeng.wang@huawei.com>
 <20210801152311.GB28489@arm.com>
Message-ID: <0de87be6-7041-c58b-a01f-3d6e3333c6f0@huawei.com>


On 2021/8/1 23:23, Catalin Marinas wrote:
> On Tue, Jul 20, 2021 at 10:51:03AM +0800, Kefeng Wang wrote:
>> There are some fixed locations in the vmalloc area be reserved
>> in ARM(see iotable_init()) and ARM64(see map_kernel()), but for
>> pcpu_page_first_chunk(), it calls vm_area_register_early() and
>> choose VMALLOC_START as the start address of vmap area which
>> could be conflicted with above address, then could trigger a
>> BUG_ON in vm_area_add_early().
>>
>> Let's choose the end of existing address range in vmlist as the
>> start address instead of VMALLOC_START to avoid the BUG_ON.
>>
>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>> ---
>>   mm/vmalloc.c | 8 +++++---
>>   1 file changed, 5 insertions(+), 3 deletions(-)
>>
>> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
>> index d5cd52805149..a98cf97f032f 100644
>> --- a/mm/vmalloc.c
>> +++ b/mm/vmalloc.c
>> @@ -2238,12 +2238,14 @@ void __init vm_area_add_early(struct vm_struct *vm)
>>    */
>>   void __init vm_area_register_early(struct vm_struct *vm, size_t align)
>>   {
>> -	static size_t vm_init_off __initdata;
>> +	unsigned long vm_start = VMALLOC_START;
>> +	struct vm_struct *tmp;
>>   	unsigned long addr;
>>   
>> -	addr = ALIGN(VMALLOC_START + vm_init_off, align);
>> -	vm_init_off = PFN_ALIGN(addr + vm->size) - VMALLOC_START;
>> +	for (tmp = vmlist; tmp; tmp = tmp->next)
>> +		vm_start = (unsigned long)tmp->addr + tmp->size;
>>   
>> +	addr = ALIGN(vm_start, align);
>>   	vm->addr = (void *)addr;
>>   
>>   	vm_area_add_early(vm);
> Is there a risk of breaking other architectures? It doesn't look like to
> me but I thought I'd ask.

Before this patch, vm_init_off is to record the offset from VMALLOC_START,

but it use VMALLOC_START as start address on the function 
vm_area_register_early()

called firstly,? this will cause the BUG_ON.

With this patch, the most important change is that we choose the start 
address via

dynamic calculate the 'start' address by traversing the list.

[wkf at localhost linux-next]$ git grep vm_area_register_early
arch/alpha/mm/init.c: vm_area_register_early(&console_remap_vm, PAGE_SIZE);
arch/x86/xen/p2m.c:???? vm_area_register_early(&vm, PMD_SIZE * 
PMDS_PER_MID_PAGE);
mm/percpu.c:??? vm_area_register_early(&vm, PAGE_SIZE);
[wkf at localhost linux-next]$ git grep vm_area_add_early
arch/arm/mm/ioremap.c:? vm_area_add_early(vm);
arch/arm64/mm/mmu.c:??? vm_area_add_early(vma);

x86/alpha won't call vm_area_add_early(), only arm64 could call both vm_area_add_early()
and  vm_area_register_early() when this patchset is merged. so it won't break other architectures.

>
> Also, instead of always picking the end, could we search for a range
> that fits?
We only need a space in vmalloc range,? using end or a range in the 
middle is not different.
>


From wangkefeng.wang at huawei.com  Sun Aug  1 19:47:04 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 2 Aug 2021 10:47:04 +0800
Subject: [PATCH v2 2/3] arm64: Support page mapping percpu first chunk
 allocator
In-Reply-To: <20210801155302.GA29188@arm.com>
References: <20210720025105.103680-1-wangkefeng.wang@huawei.com>
 <20210720025105.103680-3-wangkefeng.wang@huawei.com>
 <20210801155302.GA29188@arm.com>
Message-ID: <c98e372c-be3e-0440-f37c-0dd0bf8f79c3@huawei.com>


On 2021/8/1 23:53, Catalin Marinas wrote:
> On Tue, Jul 20, 2021 at 10:51:04AM +0800, Kefeng Wang wrote:
>> Percpu embedded first chunk allocator is the firstly option, but it
>> could fails on ARM64, eg,
>>    "percpu: max_distance=0x5fcfdc640000 too large for vmalloc space 0x781fefff0000"
>>    "percpu: max_distance=0x600000540000 too large for vmalloc space 0x7dffb7ff0000"
>>    "percpu: max_distance=0x5fff9adb0000 too large for vmalloc space 0x5dffb7ff0000"
>>
>> then we could meet "WARNING: CPU: 15 PID: 461 at vmalloc.c:3087 pcpu_get_vm_areas+0x488/0x838",
>> even the system could not boot successfully.
>>
>> Let's implement page mapping percpu first chunk allocator as a fallback
>> to the embedding allocator to increase the robustness of the system.
> It looks like x86, powerpc and sparc implement their own
> setup_per_cpu_areas(). I had a quick look on finding some commonalities
> but I think it's a lot more hassle to make a generic version out of them
> (powerpc looks the simplest though). I think we could add a generic
> variant with the arm64 support and later migrate other architectures to
> it if possible.
Ok, let's do it later, I could try to make some cleanup after the 
patchset is merged ;)
> The patch looks ok to me otherwise but I'd need an ack from Greg as it
> touches drivers/.

the arch_numa is only used ARM64 and riscv, the 
NEED_PER_CPU_PAGE_FIRST_CHUNK

is not enabled on RISCV, so it's no bad effect.

>
> BTW, do we need something similar for the non-NUMA
> setup_per_cpu_areas()? I can see this patch only enables
> NEED_PER_CPU_PAGE_FIRST_CHUNK if NUMA.
>
> Leaving the rest of the patch below for Greg.
>
>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>> ---
>>   arch/arm64/Kconfig       |  4 ++
>>   drivers/base/arch_numa.c | 82 +++++++++++++++++++++++++++++++++++-----
>>   2 files changed, 76 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b5b13a932561..eacb5873ded1 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -1045,6 +1045,10 @@ config NEED_PER_CPU_EMBED_FIRST_CHUNK
>>   	def_bool y
>>   	depends on NUMA
>>   
>> +config NEED_PER_CPU_PAGE_FIRST_CHUNK
>> +	def_bool y
>> +	depends on NUMA
>> +
>>   source "kernel/Kconfig.hz"
>>   
>>   config ARCH_SPARSEMEM_ENABLE
>> diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
>> index 4cc4e117727d..563b2013b75a 100644
>> --- a/drivers/base/arch_numa.c
>> +++ b/drivers/base/arch_numa.c
>> @@ -14,6 +14,7 @@
>>   #include <linux/of.h>
>>   
>>   #include <asm/sections.h>
>> +#include <asm/pgalloc.h>
>>   
>>   struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
>>   EXPORT_SYMBOL(node_data);
>> @@ -168,22 +169,83 @@ static void __init pcpu_fc_free(void *ptr, size_t size)
>>   	memblock_free_early(__pa(ptr), size);
>>   }
>>   
>> +#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
>> +static void __init pcpu_populate_pte(unsigned long addr)
>> +{
>> +	pgd_t *pgd = pgd_offset_k(addr);
>> +	p4d_t *p4d;
>> +	pud_t *pud;
>> +	pmd_t *pmd;
>> +
>> +	p4d = p4d_offset(pgd, addr);
>> +	if (p4d_none(*p4d)) {
>> +		pud_t *new;
>> +
>> +		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
>> +		if (!new)
>> +			goto err_alloc;
>> +		p4d_populate(&init_mm, p4d, new);
>> +	}
>> +
>> +	pud = pud_offset(p4d, addr);
>> +	if (pud_none(*pud)) {
>> +		pmd_t *new;
>> +
>> +		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
>> +		if (!new)
>> +			goto err_alloc;
>> +		pud_populate(&init_mm, pud, new);
>> +	}
>> +
>> +	pmd = pmd_offset(pud, addr);
>> +	if (!pmd_present(*pmd)) {
>> +		pte_t *new;
>> +
>> +		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
>> +		if (!new)
>> +			goto err_alloc;
>> +		pmd_populate_kernel(&init_mm, pmd, new);
>> +	}
>> +
>> +	return;
>> +
>> +err_alloc:
>> +	panic("%s: Failed to allocate %lu bytes align=%lx from=%lx\n",
>> +	      __func__, PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
>> +}
>> +#endif
>> +
>>   void __init setup_per_cpu_areas(void)
>>   {
>>   	unsigned long delta;
>>   	unsigned int cpu;
>> -	int rc;
>> +	int rc = -EINVAL;
>> +
>> +	if (pcpu_chosen_fc != PCPU_FC_PAGE) {
>> +		/*
>> +		 * Always reserve area for module percpu variables.  That's
>> +		 * what the legacy allocator did.
>> +		 */
>> +		rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
>> +					    PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
>> +					    pcpu_cpu_distance,
>> +					    pcpu_fc_alloc, pcpu_fc_free);
>> +#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
>> +		if (rc < 0)
>> +			pr_warn("PERCPU: %s allocator failed (%d), falling back to page size\n",
>> +				   pcpu_fc_names[pcpu_chosen_fc], rc);
>> +#endif
>> +	}
>>   
>> -	/*
>> -	 * Always reserve area for module percpu variables.  That's
>> -	 * what the legacy allocator did.
>> -	 */
>> -	rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
>> -				    PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
>> -				    pcpu_cpu_distance,
>> -				    pcpu_fc_alloc, pcpu_fc_free);
>> +#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
>> +	if (rc < 0)
>> +		rc = pcpu_page_first_chunk(PERCPU_MODULE_RESERVE,
>> +					   pcpu_fc_alloc,
>> +					   pcpu_fc_free,
>> +					   pcpu_populate_pte);
>> +#endif
>>   	if (rc < 0)
>> -		panic("Failed to initialize percpu areas.");
>> +		panic("Failed to initialize percpu areas (err=%d).", rc);
>>   
>>   	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
>>   	for_each_possible_cpu(cpu)
>> -- 
>> 2.26.2
> .
>


From chun-jie.chen at mediatek.com  Sun Aug  1 19:58:39 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 2 Aug 2021 10:58:39 +0800
Subject: [v15] dt-bindings: ARM: Mediatek: Add mmsys document binding for
 MT8192
Message-ID: <20210802025839.16763-1-chun-jie.chen@mediatek.com>

This patch adds the mmsys document binding for MT8192 SoC.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
This patch is based on 5.14-rc1 and [1].

Due to mmsys binding document has been converted to YAML format in [1],
so resend the patch in [2].

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=485165
[2] https://patchwork.kernel.org/project/linux-mediatek/patch/20210726105719.15793-3-chun-jie.chen at mediatek.com/
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml         | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 2d4ff0ce387b..f9ffa5b703a5 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -29,6 +29,7 @@ properties:
               - mediatek,mt8167-mmsys
               - mediatek,mt8173-mmsys
               - mediatek,mt8183-mmsys
+              - mediatek,mt8192-mmsys
               - mediatek,mt8365-mmsys
           - const: syscon
       - items:
-- 
2.18.0

From linux at roeck-us.net  Sun Aug  1 20:00:23 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Sun,  1 Aug 2021 20:00:23 -0700
Subject: [PATCH] spi: mediatek: Fix fifo transfer
Message-ID: <20210802030023.1748777-1-linux@roeck-us.net>

Commit 3a70dd2d0503 ("spi: mediatek: fix fifo rx mode") claims that
fifo RX mode was never handled, and adds the presumably missing code
to the FIFO transfer function. However, the claim that receive data
was not handled is incorrect. It was handled as part of interrupt
handling after the transfer was complete. The code added with the above
mentioned commit reads data from the receive FIFO before the transfer
is started, which is wrong. This results in an actual transfer error
on a Hayato Chromebook.

Remove the code trying to handle receive data before the transfer is
started to fix the problem.

Fixes: 3a70dd2d0503 ("spi: mediatek: fix fifo rx mode")
Cc: Peter Hess <peter.hess at ph-home.de>
Cc: Frank Wunderlich <frank-w at public-files.de>
Cc: Tzung-Bi Shih <tzungbi at google.com>
Cc: Hsin-Yi Wang <hsinyi at google.com>
Signed-off-by: Guenter Roeck <linux at roeck-us.net>
---
 drivers/spi/spi-mt65xx.c | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 68dca8ceb3ad..7914255521c3 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -426,24 +426,15 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
 	mtk_spi_prepare_transfer(master, xfer);
 	mtk_spi_setup_packet(master);
 
-	cnt = xfer->len / 4;
-	if (xfer->tx_buf)
+	if (xfer->tx_buf) {
+		cnt = xfer->len / 4;
 		iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt);
-
-	if (xfer->rx_buf)
-		ioread32_rep(mdata->base + SPI_RX_DATA_REG, xfer->rx_buf, cnt);
-
-	remainder = xfer->len % 4;
-	if (remainder > 0) {
-		reg_val = 0;
-		if (xfer->tx_buf) {
+		remainder = xfer->len % 4;
+		if (remainder > 0) {
+			reg_val = 0;
 			memcpy(&reg_val, xfer->tx_buf + (cnt * 4), remainder);
 			writel(reg_val, mdata->base + SPI_TX_DATA_REG);
 		}
-		if (xfer->rx_buf) {
-			reg_val = readl(mdata->base + SPI_RX_DATA_REG);
-			memcpy(xfer->rx_buf + (cnt * 4), &reg_val, remainder);
-		}
 	}
 
 	mtk_spi_enable_transfer(master);
-- 
2.25.1



From tzungbi at google.com  Sun Aug  1 20:27:05 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Mon, 2 Aug 2021 11:27:05 +0800
Subject: [PATCH] spi: mediatek: Fix fifo transfer
In-Reply-To: <20210802030023.1748777-1-linux@roeck-us.net>
References: <20210802030023.1748777-1-linux@roeck-us.net>
Message-ID: <YQdmCaySpW4Dpz0t@google.com>

On Sun, Aug 01, 2021 at 08:00:23PM -0700, Guenter Roeck wrote:
> Fixes: 3a70dd2d0503 ("spi: mediatek: fix fifo rx mode")
> Cc: Peter Hess <peter.hess at ph-home.de>
> Cc: Frank Wunderlich <frank-w at public-files.de>
> Cc: Tzung-Bi Shih <tzungbi at google.com>
> Cc: Hsin-Yi Wang <hsinyi at google.com>
> Signed-off-by: Guenter Roeck <linux at roeck-us.net>

Tested-by: Tzung-Bi Shih <tzungbi at google.com>


From ck.hu at mediatek.com  Sun Aug  1 20:34:40 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Mon, 2 Aug 2021 11:34:40 +0800
Subject: [PATCH v2 14/14] drm/mediatek: add mediatek-drm of vdosys1
 support for MT8195
In-Reply-To: <20210722094551.15255-15-nancy.lin@mediatek.com>
References: <20210722094551.15255-1-nancy.lin@mediatek.com>
 <20210722094551.15255-15-nancy.lin@mediatek.com>
Message-ID: <1627875280.15536.4.camel@mtksdaap41>

Hi, Nancy:

On Thu, 2021-07-22 at 17:45 +0800, Nancy.Lin wrote:
> Add driver data of mt8195 vdosys1 to mediatek-drm and modify drm for
> multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring
> up two drm drivers, only one drm driver register as the drm device.
> Each drm driver binds its own component. The first bind drm driver
> will allocate the drm device, and the last bind drm driver registers
> the drm device to drm core. Each crtc path is created with the
> corresponding drm driver data.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c   |   4 +
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |  18 +-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |   3 +-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  15 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 378 ++++++++++++++++----
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   8 +-
>  7 files changed, 356 insertions(+), 71 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> index 768c282d2d63..829570308761 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> @@ -4,6 +4,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/reset.h>
>  #include <linux/component.h>
>  #include <linux/of_device.h>
>  #include <linux/of_irq.h>
> @@ -106,6 +107,9 @@ void mtk_merge_stop(struct device *dev)
>  	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
>  
>  	mtk_ddp_write(NULL, 0x0, &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CTRL);
> +
> +	if (priv->async_clk)
> +		device_reset_optional(dev);

Move this to the merge patch [1].

[1]
https://patchwork.kernel.org/project/linux-mediatek/patch/20210729170737.21424-7-jason-jh.lin at mediatek.com/

>  }
>  
>  static int mtk_merge_check_params(struct mtk_merge_config_struct *merge_config)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 40df2c823187..3324fa1a9e8c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -737,21 +737,28 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
>  }
>  
>  int mtk_drm_crtc_create(struct drm_device *drm_dev,
> -			const enum mtk_ddp_comp_id *path, unsigned int path_len)
> +			const enum mtk_ddp_comp_id *path, unsigned int path_len,
> +			int priv_data_index)
>  {
>  	struct mtk_drm_private *priv = drm_dev->dev_private;
>  	struct device *dev = drm_dev->dev;
>  	struct mtk_drm_crtc *mtk_crtc;
>  	unsigned int num_comp_planes = 0;
> -	int pipe = priv->num_pipes;
>  	int ret;
>  	int i;
>  	bool has_ctm = false;
>  	uint gamma_lut_size = 0;
> +	struct drm_crtc *tmp;
> +	int crtc_i = 0;
>  
>  	if (!path)
>  		return 0;
>  
> +	priv = priv->all_drm_private[priv_data_index];
> +
> +	drm_for_each_crtc(tmp, drm_dev)
> +		crtc_i++;
> +
>  	for (i = 0; i < path_len; i++) {
>  		enum mtk_ddp_comp_id comp_id = path[i];
>  		struct device_node *node;
> @@ -760,7 +767,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  		if (!node) {
>  			dev_info(dev,
>  				 "Not creating crtc %d because component %d is disabled or missing\n",
> -				 pipe, comp_id);
> +				 crtc_i, comp_id);
>  			return 0;
>  		}
>  	}
> @@ -816,19 +823,18 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  
>  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
>  		ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
> -						    pipe);
> +						    crtc_i);
>  		if (ret)
>  			return ret;
>  	}
>  
> -	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
> +	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
>  	if (ret < 0)
>  		return ret;
>  
>  	if (gamma_lut_size)
>  		drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
>  	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
> -	priv->num_pipes++;
>  	mutex_init(&mtk_crtc->hw_lock);
>  
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> index 66d1cf03dfe8..0646fafffd8b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> @@ -31,7 +31,8 @@
>  void mtk_drm_crtc_commit(struct drm_crtc *crtc);
>  int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  			const enum mtk_ddp_comp_id *path,
> -			unsigned int path_len);
> +			unsigned int path_len,
> +			int priv_data_index);
>  int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
>  			     struct mtk_plane_state *state);
>  void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 9125d0f6352f..25f293542f79 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -355,6 +355,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
>  	.start = mtk_ufoe_start,
>  };
>  
> +static const struct mtk_ddp_comp_funcs ddp_pseudo_ovl = {
> +	.clk_enable = mtk_ethdr_clk_enable,
> +	.clk_disable = mtk_ethdr_clk_disable,
> +	.config = mtk_ethdr_config,
> +	.start = mtk_ethdr_start,
> +	.stop = mtk_ethdr_stop,
> +	.layer_nr = mtk_ethdr_layer_nr,
> +	.layer_config = mtk_ethdr_layer_config,
> +	.enable_vblank = mtk_ethdr_enable_vblank,
> +	.disable_vblank = mtk_ethdr_disable_vblank,
> +};

Move this to the pseudo ovl patch.

> +
>  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>  	[MTK_DISP_OVL] = "ovl",
>  	[MTK_DISP_OVL_2L] = "ovl-2l",
> @@ -368,6 +380,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>  	[MTK_DISP_UFOE] = "ufoe",
>  	[MTK_DSI] = "dsi",
>  	[MTK_DPI] = "dpi",
> +	[MTK_DISP_PSEUDO_OVL] = "pseudo_ovl",

ditto.

>  	[MTK_DISP_PWM] = "pwm",
>  	[MTK_DISP_MUTEX] = "mutex",
>  	[MTK_DISP_OD] = "od",
> @@ -412,6 +425,7 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>  	[DDP_COMPONENT_OVL1]	= { MTK_DISP_OVL,	1, &ddp_ovl },
>  	[DDP_COMPONENT_OVL_2L0]	= { MTK_DISP_OVL_2L,	0, &ddp_ovl },
>  	[DDP_COMPONENT_OVL_2L1]	= { MTK_DISP_OVL_2L,	1, &ddp_ovl },
> +	[DDP_COMPONENT_PSEUDO_OVL] = { MTK_DISP_PSEUDO_OVL,	0, &ddp_pseudo_ovl },

ditto.

>  	[DDP_COMPONENT_PWM0]	= { MTK_DISP_PWM,	0, NULL },
>  	[DDP_COMPONENT_PWM1]	= { MTK_DISP_PWM,	1, NULL },
>  	[DDP_COMPONENT_PWM2]	= { MTK_DISP_PWM,	2, NULL },
> @@ -540,6 +554,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>  	    type == MTK_DISP_MERGE ||
>  	    type == MTK_DISP_OVL ||
>  	    type == MTK_DISP_OVL_2L ||
> +	    type == MTK_DISP_PSEUDO_OVL ||

ditto.

>  	    type == MTK_DISP_PWM ||
>  	    type == MTK_DISP_RDMA ||
>  	    type == MTK_DPI ||
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 0afd78c0bc92..f2a184b1eceb 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -36,6 +36,7 @@ enum mtk_ddp_comp_type {
>  	MTK_DISP_BLS,
>  	MTK_DISP_DSC,
>  	MTK_DISP_MERGE,
> +	MTK_DISP_PSEUDO_OVL,

ditto.

>  	MTK_DDP_COMP_TYPE_MAX,
>  };
>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 58f9f9f06e94..94527fb040be 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -11,6 +11,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/reset-controller.h>
>  
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
> @@ -35,6 +36,16 @@
>  #define DRIVER_MAJOR 1
>  #define DRIVER_MINOR 0
>  
> +/* duplicate with mmsys private data */
> +struct mtk_mmsys_private {
> +	void __iomem *regs_reserved;
> +	struct cmdq_client_reg cmdq_base_reserved;
> +	void *data_reserved;
> +	spinlock_t lock_reserved; /* protects mmsys_sw_rst_b reg */
> +	struct reset_controller_dev rcdev_reserved;
> +	void *drm_private;
> +};
> +
>  static const struct drm_mode_config_helper_funcs mtk_drm_mode_config_helpers = {
>  	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
>  };
> @@ -160,12 +171,20 @@ static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
>  	DDP_COMPONENT_DP_INTF0,
>  };
>  
> +static const enum mtk_ddp_comp_id mt8195_mtk_ddp_ext[] = {
> +	DDP_COMPONENT_PSEUDO_OVL,
> +	DDP_COMPONENT_MERGE5,
> +	DDP_COMPONENT_DP_INTF1,
> +};
> +
>  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
>  	.main_path = mt2701_mtk_ddp_main,
>  	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
>  	.ext_path = mt2701_mtk_ddp_ext,
>  	.ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
>  	.shadow_register = true,
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
> @@ -174,6 +193,8 @@ static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
>  	.ext_path = mt7623_mtk_ddp_ext,
>  	.ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
>  	.shadow_register = true,
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
> @@ -183,6 +204,8 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
>  	.ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
>  	.third_path = mt2712_mtk_ddp_third,
>  	.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
> @@ -190,6 +213,8 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
>  	.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
>  	.ext_path = mt8173_mtk_ddp_ext,
>  	.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
> @@ -197,32 +222,219 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
>  	.main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
>  	.ext_path = mt8183_mtk_ddp_ext,
>  	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
>  	.main_path = mt8195_mtk_ddp_main,
>  	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 2,
> +};
> +
> +static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
> +	.ext_path = mt8195_mtk_ddp_ext,
> +	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
> +	.mmsys_id = 1,
> +	.mmsys_dev_num = 2,
> +};
> +
> +static const struct of_device_id mtk_drm_of_ids[] = {
> +	{ .compatible = "mediatek,mt2701-mmsys",
> +	  .data = &mt2701_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt7623-mmsys",
> +	  .data = &mt7623_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt2712-mmsys",
> +	  .data = &mt2712_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt8173-mmsys",
> +	  .data = &mt8173_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt8183-mmsys",
> +	  .data = &mt8183_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt8195-vdosys0",
> +	  .data = &mt8195_vdosys0_driver_data},
> +	{ .compatible = "mediatek,mt8195-vdosys1",
> +	  .data = &mt8195_vdosys1_driver_data},
> +	{ }
>  };
> +MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
> +
> +static int mtk_drm_get_mmsys_priv(struct device *dev,
> +				  struct mtk_drm_private **all_drm_priv,
> +				  int num)
> +{
> +	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
> +	struct device_node *phandle = dev->parent->of_node;
> +	const struct of_device_id *of_id;
> +	struct device_node *node;
> +	int cnt = 0;
> +
> +	for_each_child_of_node(phandle->parent, node) {
> +		struct platform_device *pdev;
> +		struct mtk_mmsys_private *mmsys_priv;
> +
> +		of_id = of_match_node(mtk_drm_of_ids, node);
> +		if (!of_id)
> +			continue;
> +
> +		pdev = of_find_device_by_node(node);
> +		if (!pdev)
> +			continue;
> +
> +		mmsys_priv = dev_get_drvdata(&pdev->dev);
> +		if (!mmsys_priv || !mmsys_priv->drm_private)
> +			continue;
> +
> +		all_drm_priv[cnt++] = mmsys_priv->drm_private;
> +		if (cnt == num)
> +			break;
> +	}
> +
> +	return 0;
> +}

Move "support multiple mmsys" related code to another patch, and left
only mt8195 part in this patch.

Regards,
CK

> +
> +static bool mtk_drm_check_last_drm_bind(struct device *dev)
> +{
> +	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
> +	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
> +	int cnt = 0;
> +	int i;
> +
> +	mtk_drm_get_mmsys_priv(dev, all_drm_priv, drm_priv->data->mmsys_dev_num);
> +
> +	for (i = 0; i < MAX_CRTC; i++)
> +		if (all_drm_priv[i] && all_drm_priv[i]->mtk_drm_bound)
> +			cnt++;
> +
> +	return (drm_priv->data->mmsys_dev_num == cnt);
> +}
> +
> +static bool mtk_drm_find_drm_dev(struct device *dev, struct drm_device **drm)
> +{
> +	struct device_node *phandle = dev->parent->of_node;
> +	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
> +	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
> +	int i;
> +
> +	if (!drm_priv->data->mmsys_dev_num)
> +		return false;
> +
> +	mtk_drm_get_mmsys_priv(dev, all_drm_priv, drm_priv->data->mmsys_dev_num);
> +
> +	for (i = 0; i < MAX_CRTC; i++) {
> +		if (all_drm_priv[i] && all_drm_priv[i]->mtk_drm_bound) {
> +			*drm = all_drm_priv[i]->drm;
> +			return true;
> +		}
> +	}
> +
> +	return false;
> +}
> +
> +static int mtk_drm_setup_all_drm_private(struct device *dev)
> +{
> +	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
> +	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
> +	int mmsys_dev_num = drm_priv->data->mmsys_dev_num;
> +	int i;
> +	int j;
> +
> +	mtk_drm_get_mmsys_priv(dev, all_drm_priv, mmsys_dev_num);
> +
> +	for (i = 0; i < mmsys_dev_num; i++)
> +		for (j = 0; j < mmsys_dev_num; j++)
> +			all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
> +
> +	return 0;
> +}
> +
> +static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
> +{
> +	const struct mtk_mmsys_driver_data *drv_data = private->data;
> +	int ret = false;
> +	int i;
> +
> +	if (drv_data->mmsys_dev_num == 1)
> +		return true;
> +
> +	if (drv_data->main_path) {
> +		for (i = 0; i < drv_data->main_len; i++)
> +			if (drv_data->main_path[i] == comp_id)
> +				ret |= true;
> +
> +		if (i == drv_data->main_len)
> +			ret |= false;
> +	}
> +
> +	if (drv_data->ext_path) {
> +		for (i = 0; i < drv_data->ext_len; i++)
> +			if (drv_data->ext_path[i] == comp_id)
> +				ret |= true;
> +
> +		if (i == drv_data->ext_len)
> +			ret |= false;
> +	}
> +
> +	if (drv_data->third_path) {
> +		for (i = 0; i < drv_data->third_len; i++)
> +			if (drv_data->third_path[i] == comp_id)
> +				ret |= true;
> +
> +		if (i == drv_data->third_len)
> +			ret |= false;
> +	}
> +
> +	return ret;
> +}
> +
> +static int mtk_drm_check_mutex_dev(struct mtk_drm_private *private)
> +{
> +	struct platform_device *pdev;
> +	struct mtk_drm_private *priv_i;
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < private->data->mmsys_dev_num; i++) {
> +		priv_i = private->all_drm_private[i];
> +
> +		pdev = of_find_device_by_node(priv_i->mutex_node);
> +		if (!pdev) {
> +			dev_err(priv_i->dev, "Waiting for disp-mutex device %pOF\n",
> +				priv_i->mutex_node);
> +			ret = -EPROBE_DEFER;
> +			goto err_put_mutex;
> +		}
> +		priv_i->mutex_dev = &pdev->dev;
> +	}
> +
> +	return 0;
> +
> +err_put_mutex:
> +	for (i = 0; i < private->data->mmsys_dev_num; i++) {
> +		priv_i = private->all_drm_private[i];
> +		of_node_put(priv_i->mutex_node);
> +	}
> +
> +	return ret;
> +}
>  
>  static int mtk_drm_kms_init(struct drm_device *drm)
>  {
>  	struct mtk_drm_private *private = drm->dev_private;
> +	struct mtk_drm_private *priv_n;
>  	struct platform_device *pdev;
> -	struct device_node *np;
> +	struct device_node *np = NULL;
>  	struct device *dma_dev;
>  	int ret;
> +	int i;
> +	int j;
>  
>  	if (!iommu_present(&platform_bus_type))
>  		return -EPROBE_DEFER;
>  
> -	pdev = of_find_device_by_node(private->mutex_node);
> -	if (!pdev) {
> -		dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
> -			private->mutex_node);
> -		of_node_put(private->mutex_node);
> -		return -EPROBE_DEFER;
> -	}
> -	private->mutex_dev = &pdev->dev;
> +	ret = mtk_drm_check_mutex_dev(private);
> +	if (ret)
> +		return ret;
>  
>  	ret = drmm_mode_config_init(drm);
>  	if (ret)
> @@ -241,33 +453,57 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  	drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
>  	drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
>  
> -	ret = component_bind_all(drm->dev, drm);
> +	for (i = 0; i < private->data->mmsys_dev_num; i++) {
> +		drm->dev_private = private->all_drm_private[i];
> +		ret = component_bind_all(private->all_drm_private[i]->dev, drm);
>  	if (ret)
>  		goto put_mutex_dev;
> +	}
>  
>  	/*
>  	 * We currently support two fixed data streams, each optional,
>  	 * and each statically assigned to a crtc:
>  	 * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
>  	 */
> -	ret = mtk_drm_crtc_create(drm, private->data->main_path,
> -				  private->data->main_len);
> -	if (ret < 0)
> -		goto err_component_unbind;
> -	/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
> -	ret = mtk_drm_crtc_create(drm, private->data->ext_path,
> -				  private->data->ext_len);
> -	if (ret < 0)
> -		goto err_component_unbind;
> -
> -	ret = mtk_drm_crtc_create(drm, private->data->third_path,
> -				  private->data->third_len);
> -	if (ret < 0)
> -		goto err_component_unbind;
> +	for (i = 0; i < MAX_CRTC; i++) {
> +		for (j = 0; j < private->data->mmsys_dev_num; j++) {
> +			priv_n = private->all_drm_private[j];
> +
> +			if (i == 0 && priv_n->data->main_len) {
> +				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
> +							  priv_n->data->main_len, j);
> +				if (ret)
> +					goto err_component_unbind;
> +
> +				if (!np)
> +					np = priv_n->comp_node[priv_n->data->main_path[0]];
> +
> +				continue;
> +			} else if (i == 1 && priv_n->data->ext_len) {
> +				ret = mtk_drm_crtc_create(drm, priv_n->data->ext_path,
> +							  priv_n->data->ext_len, j);
> +				if (ret)
> +					goto err_component_unbind;
> +
> +				if (!np)
> +					np = priv_n->comp_node[priv_n->data->ext_path[0]];
> +
> +				continue;
> +			} else if (i == 2 && priv_n->data->third_len) {
> +				ret = mtk_drm_crtc_create(drm, priv_n->data->third_path,
> +							  priv_n->data->third_len, j);
> +				if (ret)
> +					goto err_component_unbind;
> +
> +				if (!np)
> +					np = priv_n->comp_node[priv_n->data->third_path[0]];
> +
> +				continue;
> +			}
> +		}
> +	}
>  
>  	/* Use OVL device for all DMA memory allocations */
> -	np = private->comp_node[private->data->main_path[0]] ?:
> -	     private->comp_node[private->data->ext_path[0]];
>  	pdev = of_find_device_by_node(np);
>  	if (!pdev) {
>  		ret = -ENODEV;
> @@ -276,13 +512,15 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  	}
>  
>  	dma_dev = &pdev->dev;
> -	private->dma_dev = dma_dev;
> +	for (i = 0; i < private->data->mmsys_dev_num; i++)
> +		private->all_drm_private[i]->dma_dev = dma_dev;
>  
>  	/*
>  	 * Configure the DMA segment size to make sure we get contiguous IOVA
>  	 * when importing PRIME buffers.
>  	 */
>  	ret = dma_set_max_seg_size(dma_dev, UINT_MAX);
> +
>  	if (ret) {
>  		dev_err(dma_dev, "Failed to set DMA segment size\n");
>  		goto err_component_unbind;
> @@ -304,9 +542,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  	return 0;
>  
>  err_component_unbind:
> -	component_unbind_all(drm->dev, drm);
> +	for (i = 0; i < private->data->mmsys_dev_num; i++)
> +		component_unbind_all(private->all_drm_private[i]->dev, drm);
>  put_mutex_dev:
> -	put_device(private->mutex_dev);
> +	for (i = 0; i < private->data->mmsys_dev_num; i++)
> +		put_device(private->all_drm_private[i]->mutex_dev);
> +
>  	return ret;
>  }
>  
> @@ -371,12 +612,21 @@ static int mtk_drm_bind(struct device *dev)
>  	struct drm_device *drm;
>  	int ret;
>  
> -	drm = drm_dev_alloc(&mtk_drm_driver, dev);
> -	if (IS_ERR(drm))
> -		return PTR_ERR(drm);
> +	if (!mtk_drm_find_drm_dev(dev, &drm)) {
> +		drm = drm_dev_alloc(&mtk_drm_driver, dev);
> +		if (IS_ERR(drm))
> +			return PTR_ERR(drm);
> +		drm->dev_private = private;
> +	}
>  
> -	drm->dev_private = private;
> +	private->dev = dev;
>  	private->drm = drm;
> +	private->mtk_drm_bound = true;
> +
> +	if (!mtk_drm_check_last_drm_bind(dev))
> +		return 0;
> +
> +	mtk_drm_setup_all_drm_private(dev);
>  
>  	ret = mtk_drm_kms_init(drm);
>  	if (ret < 0)
> @@ -401,10 +651,13 @@ static void mtk_drm_unbind(struct device *dev)
>  {
>  	struct mtk_drm_private *private = dev_get_drvdata(dev);
>  
> -	drm_dev_unregister(private->drm);
> -	mtk_drm_kms_deinit(private->drm);
> -	drm_dev_put(private->drm);
> -	private->num_pipes = 0;
> +	/* for multi mmsys dev, unregister drm dev in mmsys master */
> +	if (private->data->mmsys_id == 0) {
> +		drm_dev_unregister(private->drm);
> +		mtk_drm_kms_deinit(private->drm);
> +		drm_dev_put(private->drm);
> +	}
> +	private->mtk_drm_bound = false;
>  	private->drm = NULL;
>  }
>  
> @@ -485,49 +738,42 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>  	{ }
>  };
>  
> -static const struct of_device_id mtk_drm_of_ids[] = {
> -	{ .compatible = "mediatek,mt2701-mmsys",
> -	  .data = &mt2701_mmsys_driver_data},
> -	{ .compatible = "mediatek,mt7623-mmsys",
> -	  .data = &mt7623_mmsys_driver_data},
> -	{ .compatible = "mediatek,mt2712-mmsys",
> -	  .data = &mt2712_mmsys_driver_data},
> -	{ .compatible = "mediatek,mt8173-mmsys",
> -	  .data = &mt8173_mmsys_driver_data},
> -	{ .compatible = "mediatek,mt8183-mmsys",
> -	  .data = &mt8183_mmsys_driver_data},
> -	{.compatible = "mediatek,mt8195-vdosys0",
> -	  .data = &mt8195_vdosys0_driver_data},
> -	{ }
> -};
> -MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
> -
>  static int mtk_drm_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
>  	struct device_node *phandle = dev->parent->of_node;
>  	const struct of_device_id *of_id;
> +	const struct mtk_mmsys_driver_data *drv_data;
>  	struct mtk_drm_private *private;
>  	struct device_node *node;
>  	struct component_match *match = NULL;
> +	struct mtk_mmsys_private *mmsys_priv;
>  	int ret;
>  	int i;
>  
> +	of_id = of_match_node(mtk_drm_of_ids, phandle);
> +	if (!of_id)
> +		return -ENODEV;
> +
> +	drv_data = of_id->data;
>  	private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
>  	if (!private)
>  		return -ENOMEM;
>  
> +	private->all_drm_private = devm_kmalloc_array(dev, drv_data->mmsys_dev_num,
> +						      sizeof(*private->all_drm_private),
> +						      GFP_KERNEL);
> +	if (!private->all_drm_private)
> +		return -ENOMEM;
> +
> +	private->data = drv_data;
>  	private->mmsys_dev = dev->parent;
>  	if (!private->mmsys_dev) {
>  		dev_err(dev, "Failed to get MMSYS device\n");
>  		return -ENODEV;
>  	}
> -
> -	of_id = of_match_node(mtk_drm_of_ids, phandle);
> -	if (!of_id)
> -		return -ENODEV;
> -
> -	private->data = of_id->data;
> +	mmsys_priv = dev_get_drvdata(private->mmsys_dev);
> +	mmsys_priv->drm_private = private;
>  
>  	/* Iterate over sibling DISP function blocks */
>  	for_each_child_of_node(phandle->parent, node) {
> @@ -548,7 +794,13 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  		comp_type = (enum mtk_ddp_comp_type)of_id->data;
>  
>  		if (comp_type == MTK_DISP_MUTEX) {
> -			private->mutex_node = of_node_get(node);
> +			int id;
> +
> +			id = of_alias_get_id(node, "mutex");
> +			if (id < 0 || id == drv_data->mmsys_id) {
> +				private->mutex_node = of_node_get(node);
> +				dev_dbg(dev, "get mutex for mmsys %d", drv_data->mmsys_id);
> +			}
>  			continue;
>  		}
>  
> @@ -559,6 +811,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  			continue;
>  		}
>  
> +		if (!mtk_drm_find_mmsys_comp(private, comp_id))
> +			continue;
> +
>  		private->comp_node[comp_id] = of_node_get(node);
>  
>  		/*
> @@ -573,6 +828,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  		    comp_type == MTK_DISP_MERGE ||
>  		    comp_type == MTK_DISP_OVL ||
>  		    comp_type == MTK_DISP_OVL_2L ||
> +		    comp_type == MTK_DISP_PSEUDO_OVL ||
>  		    comp_type == MTK_DISP_RDMA ||
>  		    comp_type == MTK_DPI ||
>  		    comp_type == MTK_DSI) {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> index c87ebb5309d0..212e4f87c35c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> @@ -29,14 +29,15 @@ struct mtk_mmsys_driver_data {
>  	unsigned int third_len;
>  
>  	bool shadow_register;
> +	unsigned int mmsys_id;
> +	unsigned int mmsys_dev_num;
>  };
>  
>  struct mtk_drm_private {
>  	struct drm_device *drm;
>  	struct device *dma_dev;
> -
> -	unsigned int num_pipes;
> -
> +	bool mtk_drm_bound;
> +	struct device *dev;
>  	struct device_node *mutex_node;
>  	struct device *mutex_dev;
>  	struct device *mmsys_dev;
> @@ -44,6 +45,7 @@ struct mtk_drm_private {
>  	struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_ID_MAX];
>  	const struct mtk_mmsys_driver_data *data;
>  	struct drm_atomic_state *suspend_state;
> +	struct mtk_drm_private **all_drm_private;
>  };
>  
>  extern struct platform_driver mtk_disp_ccorr_driver;


From hsinyi at chromium.org  Sun Aug  1 20:40:10 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Mon, 2 Aug 2021 11:40:10 +0800
Subject: [PATCH] spi: mediatek: Fix fifo transfer
In-Reply-To: <YQdmCaySpW4Dpz0t@google.com>
References: <20210802030023.1748777-1-linux@roeck-us.net>
 <YQdmCaySpW4Dpz0t@google.com>
Message-ID: <CAJMQK-jxYAUjT4g08Ctt0=NTdFoKMnHBqE9-Kgj94ymc8XOrCw@mail.gmail.com>

On Mon, Aug 2, 2021 at 11:27 AM Tzung-Bi Shih <tzungbi at google.com> wrote:
>
> On Sun, Aug 01, 2021 at 08:00:23PM -0700, Guenter Roeck wrote:
> > Fixes: 3a70dd2d0503 ("spi: mediatek: fix fifo rx mode")
> > Cc: Peter Hess <peter.hess at ph-home.de>
> > Cc: Frank Wunderlich <frank-w at public-files.de>
> > Cc: Tzung-Bi Shih <tzungbi at google.com>
> > Cc: Hsin-Yi Wang <hsinyi at google.com>
> > Signed-off-by: Guenter Roeck <linux at roeck-us.net>
>
> Tested-by: Tzung-Bi Shih <tzungbi at google.com>
Tested-by: Hsin-Yi Wang <hsinyi at google.com>

tested on a mt8183 device.
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From rocco.yue at mediatek.com  Sun Aug  1 20:19:24 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Mon, 2 Aug 2021 11:19:24 +0800
Subject: [PATCH net-next v2] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <5be90cf4-f603-c2f2-fd7e-3886854457ba@gmail.com>
References: <5be90cf4-f603-c2f2-fd7e-3886854457ba@gmail.com>
Message-ID: <20210802031924.3256-1-rocco.yue@mediatek.com>

On Sat, 2021-07-31 at 11:17 -0600, David Ahern wrote:
On 7/30/21 7:52 PM, Rocco Yue wrote:
>> In this way, if the MTU values that the device receives from
>> the network in the PCO IPv4 and the RA IPv6 procedures are
>> different, the user space process can read ra_mtu to get
>> the mtu value carried in the RA message without worrying
>> about the issue of ipv4 being stuck due to the late arrival
>> of RA message. After comparing the value of ra_mtu and ipv4
>> mtu, then the device can use the lower MTU value for both
>> IPv4 and IPv6.
> 
> you are storing the value and sending to userspace but never using it
> when sending a message. What's the pointing of processing the MTU in the
> RA if you are not going to use it to control message size?

Hi David,

In the requirement of mobile operator at&t in 2021:
AT&T <CDR-CDS-116> Prioritize Lower MTU value:
If the MTU values that the device receives from the network in the PCO
IPv4 <CDR-CDS-110> and the RA IPv6 <CDR-CDS-112> procedures are different,
then the device shall use the lower MTU value for both IPv4 and IPv6.

And in the 3GPP 23.060:
The PDP PDUs shall be routed and transferred between the MS and the GGSN
or P-GW as N-PDUs. In order to avoid IP layer fragmentation between the
MS and the GGSN or P-GW, the link MTU size in the MS should be set to the
value provided by the network as a part of the IP configuration. This
applies to both IPv6 and IPv4.

That means user needs to be able to correctly read the mtu value carried
in the RA message so that user can correctly compare PCO ipv4 mtu and
RA ipv6 mtu.

>> @@ -5761,6 +5765,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token,
>>  static const struct nla_policy inet6_af_policy[IFLA_INET6_MAX + 1] = {
>>  	[IFLA_INET6_ADDR_GEN_MODE]	= { .type = NLA_U8 },
>>  	[IFLA_INET6_TOKEN]		= { .len = sizeof(struct in6_addr) },
>> +	[IFLA_INET6_RA_MTU]		= { .type = NLA_U32 },
>>  };
>>  
>>  static int check_addr_gen_mode(int mode)
> 
> Its value is derived from an RA not set by userspace, so set the type to
> NLA_REJECT so that inet6_validate_link_af will reject messages that have
> IFLA_INET6_RA_MTU set. You can set "reject_message" in the policy to
> return a message that "IFLA_INET6_RA_MTU can not be set".

will do.

Thanks
Rocco

From liuqi115 at huawei.com  Sun Aug  1 20:52:00 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Mon, 2 Aug 2021 11:52:00 +0800
Subject: [PATCH] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <6a97dff6c33c4b84887223de2502bd3d@hisilicon.com>
References: <20210719122417.10355-1-liuqi115@huawei.com>
 <20210721174153.34c1898dc9eea135eb0b8be8@kernel.org>
 <332df5b7d7bb4bd096b6521ffefaabe6@hisilicon.com>
 <20210723000318.5594c86e7c454aed82d9465d@kernel.org>
 <e63531dc8b7040219761e72fb9b1e74a@hisilicon.com>
 <20210731101537.a64063d84e86d7910bd58a96@kernel.org>
 <6a97dff6c33c4b84887223de2502bd3d@hisilicon.com>
Message-ID: <2f32fff3-6b58-583f-8e85-06ec1553d3f4@huawei.com>



On 2021/7/31 20:21, Song Bao Hua (Barry Song) wrote:
> 
> 
>> -----Original Message-----
>> From: Masami Hiramatsu [mailto:mhiramat at kernel.org]
>> Sent: Saturday, July 31, 2021 1:16 PM
>> To: Song Bao Hua (Barry Song) <song.bao.hua at hisilicon.com>
>> Cc: liuqi (BA) <liuqi115 at huawei.com>; catalin.marinas at arm.com;
>> will at kernel.org; naveen.n.rao at linux.ibm.com; anil.s.keshavamurthy at intel.com;
>> davem at davemloft.net; linux-arm-kernel at lists.infradead.org; Zengtao (B)
>> <prime.zeng at hisilicon.com>; robin.murphy at arm.com; Linuxarm
>> <linuxarm at huawei.com>; linux-kernel at vger.kernel.org
>> Subject: Re: [PATCH] arm64: kprobe: Enable OPTPROBE for arm64
>>
>> On Fri, 30 Jul 2021 10:04:06 +0000
>> "Song Bao Hua (Barry Song)" <song.bao.hua at hisilicon.com> wrote:
>>
>>>>>>>
>>>>>>> Hi Qi,
>>>>>>>
>>>>>>> Thanks for your effort!
>>>>>>>
>>>>>>> On Mon, 19 Jul 2021 20:24:17 +0800
>>>>>>> Qi Liu <liuqi115 at huawei.com> wrote:
>>>>>>>
>>>>>>>> This patch introduce optprobe for ARM64. In optprobe, probed
>>>>>>>> instruction is replaced by a branch instruction to detour
>>>>>>>> buffer. Detour buffer contains trampoline code and a call to
>>>>>>>> optimized_callback(). optimized_callback() calls opt_pre_handler()
>>>>>>>> to execute kprobe handler.
>>>>>>>
>>>>>>> OK so this will replace only one instruction.
>>>>>>>
>>>>>>>>
>>>>>>>> Limitations:
>>>>>>>> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
>>>>>>>> guarantee the offset between probe point and kprobe pre_handler
>>>>>>>> is not larger than 128MiB.
>>>>>>>
>>>>>>> Hmm, shouldn't we depends on !CONFIG_ARM64_MODULE_PLTS? Or,
>>>>>>> allocate an intermediate trampoline area similar to arm optprobe
>>>>>>> does.
>>>>>>
>>>>>> Depending on !CONFIG_ARM64_MODULE_PLTS will totally disable
>>>>>> RANDOMIZE_BASE according to arch/arm64/Kconfig:
>>>>>> config RANDOMIZE_BASE
>>>>>> 	bool "Randomize the address of the kernel image"
>>>>>> 	select ARM64_MODULE_PLTS if MODULES
>>>>>> 	select RELOCATABLE
>>>>>
>>>>> Yes, but why it is required for "RANDOMIZE_BASE"?
>>>>> Does that imply the module call might need to use PLT in
>>>>> some cases?
>>>>>
>>>>>>
>>>>>> Depending on !RANDOMIZE_MODULE_REGION_FULL seems to be still
>>>>>> allowing RANDOMIZE_BASE via avoiding long jump according to:
>>>>>> arch/arm64/Kconfig:
>>>>>>
>>>>>> config RANDOMIZE_MODULE_REGION_FULL
>>>>>> 	bool "Randomize the module region over a 4 GB range"
>>>>>> 	depends on RANDOMIZE_BASE
>>>>>> 	default y
>>>>>> 	help
>>>>>> 	  Randomizes the location of the module region inside a 4 GB window
>>>>>> 	  covering the core kernel. This way, it is less likely for modules
>>>>>> 	  to leak information about the location of core kernel data structures
>>>>>> 	  but it does imply that function calls between modules and the core
>>>>>> 	  kernel will need to be resolved via veneers in the module PLT.
>>>>>>
>>>>>> 	  When this option is not set, the module region will be randomized
>> over
>>>>>> 	  a limited range that contains the [_stext, _etext] interval of the
>>>>>> 	  core kernel, so branch relocations are always in range.
>>>>>
>>>>> Hmm, this dependency looks strange. If it always in range, don't we need
>>>>> PLT for modules?
>>>>>
>>>>> Cataline, would you know why?
>>>>> Maybe it's a KASLR's Kconfig issue?
>>>>
>>>> I actually didn't see any problem after making this change:
>>>>
>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>> index e07e7de9ac49..6440671b72e0 100644
>>>> --- a/arch/arm64/Kconfig
>>>> +++ b/arch/arm64/Kconfig
>>>> @@ -1781,7 +1781,6 @@ config RELOCATABLE
>>>>
>>>>   config RANDOMIZE_BASE
>>>>          bool "Randomize the address of the kernel image"
>>>> -       select ARM64_MODULE_PLTS if MODULES
>>>>          select RELOCATABLE
>>>>          help
>>>>            Randomizes the virtual address at which the kernel image is
>>>> @@ -1801,6 +1800,7 @@ config RANDOMIZE_BASE
>>>>   config RANDOMIZE_MODULE_REGION_FULL
>>>>          bool "Randomize the module region over a 4 GB range"
>>>>          depends on RANDOMIZE_BASE
>>>> +       select ARM64_MODULE_PLTS if MODULES
>>>>          default y
>>>>          help
>>>>            Randomizes the location of the module region inside a 4 GB window
>>>>
>>>> and having this config:
>>>> # zcat /proc/config.gz | grep RANDOMIZE_BASE
>>>> CONFIG_RANDOMIZE_BASE=y
>>>>
>>>> # zcat /proc/config.gz | grep RANDOMIZE_MODULE_REGION_FULL
>>>> # CONFIG_RANDOMIZE_MODULE_REGION_FULL is not set
>>>>
>>>> # zcat /proc/config.gz | grep ARM64_MODULE_PLTS
>>>> # CONFIG_ARM64_MODULE_PLTS is not set
>>>>
>>>> Modules work all good:
>>>> # lsmod
>>>> Module                  Size  Used by
>>>> btrfs                1355776  0
>>>> blake2b_generic        20480  0
>>>> libcrc32c              16384  1 btrfs
>>>> xor                    20480  1 btrfs
>>>> xor_neon               16384  1 xor
>>>> zstd_compress         163840  1 btrfs
>>>> raid6_pq              110592  1 btrfs
>>>> ctr                    16384  0
>>>> md5                    16384  0
>>>> ip_tunnel              32768  0
>>>> ipv6                  442368  28
>>>>
>>>>
>>>> I am not quite sure if there is a corner case. If no,
>>>> I would think the kconfig might be some improper.
>>>
>>> The corner case is that even CONFIG_RANDOMIZE_MODULE_REGION_FULL
>>> is not enabled, but if CONFIG_ARM64_MODULE_PLTS is enabled, when
>>> we can't get memory from the 128MB area in case the area is exhausted,
>>> we will fall back in module_alloc() to a 2GB area as long as either
>>> of the below two conditions is met:
>>>
>>> 1. KASAN is not enabled
>>> 2. KASAN is enabled and CONFIG_KASAN_VMALLOC is also enabled.
>>>
>>> void *module_alloc(unsigned long size)
>>> {
>>> 	u64 module_alloc_end = module_alloc_base + MODULES_VSIZE;
>>> 	gfp_t gfp_mask = GFP_KERNEL;
>>> 	void *p;
>>>
>>> 	/* Silence the initial allocation */
>>> 	if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
>>> 		gfp_mask |= __GFP_NOWARN;
>>>
>>> 	if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
>>> 	    IS_ENABLED(CONFIG_KASAN_SW_TAGS))
>>> 		/* don't exceed the static module region - see below */
>>> 		module_alloc_end = MODULES_END;
>>>
>>> 	p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
>>> 				module_alloc_end, gfp_mask, PAGE_KERNEL, 0,
>>> 				NUMA_NO_NODE, __builtin_return_address(0));
>>>
>>> 	if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
>>> 	    (IS_ENABLED(CONFIG_KASAN_VMALLOC) ||
>>> 	     (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
>>> 	      !IS_ENABLED(CONFIG_KASAN_SW_TAGS))))
>>> 		/*
>>> 		 * KASAN without KASAN_VMALLOC can only deal with module
>>> 		 * allocations being served from the reserved module region,
>>> 		 * since the remainder of the vmalloc region is already
>>> 		 * backed by zero shadow pages, and punching holes into it
>>> 		 * is non-trivial. Since the module region is not randomized
>>> 		 * when KASAN is enabled without KASAN_VMALLOC, it is even
>>> 		 * less likely that the module region gets exhausted, so we
>>> 		 * can simply omit this fallback in that case.
>>> 		 */
>>> 		p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
>>> 				module_alloc_base + SZ_2G, GFP_KERNEL,
>>> 				PAGE_KERNEL, 0, NUMA_NO_NODE,
>>> 				__builtin_return_address(0));
>>>
>>> 	if (p && (kasan_module_alloc(p, size) < 0)) {
>>> 		vfree(p);
>>> 		return NULL;
>>> 	}
>>>
>>> 	return p;
>>> }
>>>
>>> This should be happening quite rarely. But maybe arm64's document
>>> needs some minor fixup, otherwise, it is quite confusing.
>>
>> OK, so CONFIG_KASAN_VLALLOC=y and CONFIG_ARM64_MODULE_PLTS=y, the
>> module_alloc()
>> basically returns the memory in 128MB region, but can return the memory in 2GB
>> region. (This is OK because optprobe can filter it out)
>> But CONFIG_RANDOMIZE_MODULE_REGION_FULL=y, there is almost no chance to get
>> the memory in 128MB region.
>>
>> Hmm, for the optprobe in kernel text, maybe we can define 'optinsn_alloc_start'
>> by 'module_alloc_base - (SZ_2G - MODULES_VADDR)' and use __vmalloc_node_range()
>> to avoid this issue. But that is only for the kernel. For the modules, we may
>> always out of 128MB region.
> 
> If we can have some separate PLT entries in each module for optprobe,
> we should be able to short-jump to the PLT entry and then PLT entry
> will further long-jump to detour out of the range. That is exactly
> the duty of PLT.
> 
> Right now, arm64 has support on dynamic_ftrace by adding a
> section in module for ftrace PLT.
> arch/arm64/include/asm/module.lds.h:
> SECTIONS {
> #ifdef CONFIG_ARM64_MODULE_PLTS
> 	.plt 0 (NOLOAD) : { BYTE(0) }
> 	.init.plt 0 (NOLOAD) : { BYTE(0) }
> 	.text.ftrace_trampoline 0 (NOLOAD) : { BYTE(0) }
> #endif
> ...
> }
> 
> arch/arm64/kernel/module.c will initialize some PLT entries
> for ftrace:
> 
> static int module_init_ftrace_plt(const Elf_Ehdr *hdr,
> 				  const Elf_Shdr *sechdrs,
> 				  struct module *mod)
> {
> #if defined(CONFIG_ARM64_MODULE_PLTS) && defined(CONFIG_DYNAMIC_FTRACE)
> 	const Elf_Shdr *s;
> 	struct plt_entry *plts;
> 
> 	s = find_section(hdr, sechdrs, ".text.ftrace_trampoline");
> 	if (!s)
> 		return -ENOEXEC;
> 
> 	plts = (void *)s->sh_addr;
> 
> 	__init_plt(&plts[FTRACE_PLT_IDX], FTRACE_ADDR);
> 
> 	if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS))
> 		__init_plt(&plts[FTRACE_REGS_PLT_IDX], FTRACE_REGS_ADDR);
> 
> 	mod->arch.ftrace_trampolines = plts;
> #endif
> 	return 0;
> }
> 
> Ftrace will then use those PLT entries in arch/arm64/kernel/ftrace.c:
> static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned long addr)
> {
> #ifdef CONFIG_ARM64_MODULE_PLTS
> 	struct plt_entry *plt = mod->arch.ftrace_trampolines;
> 
> 	if (addr == FTRACE_ADDR)
> 		return &plt[FTRACE_PLT_IDX];
> 	if (addr == FTRACE_REGS_ADDR &&
> 	    IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS))
> 		return &plt[FTRACE_REGS_PLT_IDX];
> #endif
> 	return NULL;
> }
> 
> /*
>   * Turn on the call to ftrace_caller() in instrumented function
>   */
> int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
> {
> 	unsigned long pc = rec->ip;
> 	u32 old, new;
> 	long offset = (long)pc - (long)addr;
> 
> 	if (offset < -SZ_128M || offset >= SZ_128M) {
> 		struct module *mod;
> 		struct plt_entry *plt;
> 
> 		if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
> 			return -EINVAL;
> 
> 		/*
> 		 * On kernels that support module PLTs, the offset between the
> 		 * branch instruction and its target may legally exceed the
> 		 * range of an ordinary relative 'bl' opcode. In this case, we
> 		 * need to branch via a trampoline in the module.
> 		 *
> 		 * NOTE: __module_text_address() must be called with preemption
> 		 * disabled, but we can rely on ftrace_lock to ensure that 'mod'
> 		 * retains its validity throughout the remainder of this code.
> 		 */
> 		preempt_disable();
> 		mod = __module_text_address(pc);
> 		preempt_enable();
> 
> 		if (WARN_ON(!mod))
> 			return -EINVAL;
> 
> 		plt = get_ftrace_plt(mod, addr);
> 		if (!plt) {
> 			pr_err("ftrace: no module PLT for %ps\n", (void *)addr);
> 			return -EINVAL;
> 		}
> 
> 		addr = (unsigned long)plt;
> 	}
> 
> 	old = aarch64_insn_gen_nop();
> 	new = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK);
> 
> 	return ftrace_modify_code(pc, old, new, true);
> }
> 
> This might be the direction to go later. Anyway, "Rome wasn't built
> in a day", for this stage, we might focus on optprobe for the case
> of non-randomized module region :-).
> 
> BTW, @liuqi, if users set "nokaslr" in bootargs, will your optprobe
> always work and not fall back to normal kprobe even we remove the
> dependency on RANDOMIZED_MODULE_REGION_FULL?
> 
Hi Barry,

I do some tests on Hip08 platform, using nokaslr in booting cmdline and 
remove dependency on RANDOMIZED_MODULE_REGION_FULL, optprobe seems work.
Here is the log:

estuary:/$ uname -a
Linux (none) 5.13.0-rc4+ #37 SMP PREEMPT Mon Aug 2 08:13:37 CST 2021 
aarch64 GNU/Linux
estuary:/$ zcat /proc/config.gz | grep RANDOMIZE_MODULE_REGION
CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
estuary:/$ zcat /proc/config.gz | grep OPTPROBE
CONFIG_OPTPROBES=y
CONFIG_HAVE_OPTPROBES=y
estuary:/$ cat /proc/cmdline
console=ttyAMA0,115200 earlycon=pl011,0x9000000 kpti=off nokaslr
estuary:/$ cat /sys/bus/platform/devices/hello_driver/kprobe_test
[   61.304143] do_empty returned 0 and took 200 ns to execute
[   61.304662] do_empty returned 0 and took 110 ns to execute
[   61.305196] do_empty returned 0 and took 100 ns to execute
[   61.305745] do_empty returned 0 and took 90 ns to execute
[   61.306262] do_empty returned 0 and took 90 ns to execute
[   61.306781] do_empty returned 0 and took 90 ns to execute
[   61.307286] do_empty returned 0 and took 90 ns to execute
[   61.307798] do_empty returned 0 and took 90 ns to execute
[   61.308314] do_empty returned 0 and took 90 ns to execute
[   61.308828] do_empty returned 0 and took 90 ns to execute
[   61.309323] do_empty returned 0 and took 80 ns to execute
[   61.309832] do_empty returned 0 and took 80 ns to execute
[   61.310357] do_empty returned 0 and took 80 ns to execute
[   61.310871] do_empty returned 0 and took 80 ns to execute
[   61.311361] do_empty returned 0 and took 80 ns to execute
[   61.311851] do_empty returned 0 and took 90 ns to execute
[   61.312358] do_empty returned 0 and took 90 ns to execute
[   61.312879] do_empty returned 0 and took 80 ns to execute

Thanks,
Qi

>>
>> Thank you,
>>
>> --
>> Masami Hiramatsu <mhiramat at kernel.org>
> 
> Thanks
> Barry
> .
> 



From liuqi115 at huawei.com  Sun Aug  1 20:59:51 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Mon, 2 Aug 2021 11:59:51 +0800
Subject: [PATCH] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <2f32fff3-6b58-583f-8e85-06ec1553d3f4@huawei.com>
References: <20210719122417.10355-1-liuqi115@huawei.com>
 <20210721174153.34c1898dc9eea135eb0b8be8@kernel.org>
 <332df5b7d7bb4bd096b6521ffefaabe6@hisilicon.com>
 <20210723000318.5594c86e7c454aed82d9465d@kernel.org>
 <e63531dc8b7040219761e72fb9b1e74a@hisilicon.com>
 <20210731101537.a64063d84e86d7910bd58a96@kernel.org>
 <6a97dff6c33c4b84887223de2502bd3d@hisilicon.com>
 <2f32fff3-6b58-583f-8e85-06ec1553d3f4@huawei.com>
Message-ID: <06bb0cfb-4773-4d36-080c-291a5c7d8bb1@huawei.com>



On 2021/8/2 11:52, liuqi (BA) wrote:
> 
> 
> On 2021/7/31 20:21, Song Bao Hua (Barry Song) wrote:
>>
>>
>>> -----Original Message-----
>>> From: Masami Hiramatsu [mailto:mhiramat at kernel.org]
>>> Sent: Saturday, July 31, 2021 1:16 PM
>>> To: Song Bao Hua (Barry Song) <song.bao.hua at hisilicon.com>
>>> Cc: liuqi (BA) <liuqi115 at huawei.com>; catalin.marinas at arm.com;
>>> will at kernel.org; naveen.n.rao at linux.ibm.com; 
>>> anil.s.keshavamurthy at intel.com;
>>> davem at davemloft.net; linux-arm-kernel at lists.infradead.org; Zengtao (B)
>>> <prime.zeng at hisilicon.com>; robin.murphy at arm.com; Linuxarm
>>> <linuxarm at huawei.com>; linux-kernel at vger.kernel.org
>>> Subject: Re: [PATCH] arm64: kprobe: Enable OPTPROBE for arm64
>>>
>>> On Fri, 30 Jul 2021 10:04:06 +0000
>>> "Song Bao Hua (Barry Song)" <song.bao.hua at hisilicon.com> wrote:
>>>
>>>>>>>>
>>>>>>>> Hi Qi,
>>>>>>>>
>>>>>>>> Thanks for your effort!
>>>>>>>>
>>>>>>>> On Mon, 19 Jul 2021 20:24:17 +0800
>>>>>>>> Qi Liu <liuqi115 at huawei.com> wrote:
>>>>>>>>
>>>>>>>>> This patch introduce optprobe for ARM64. In optprobe, probed
>>>>>>>>> instruction is replaced by a branch instruction to detour
>>>>>>>>> buffer. Detour buffer contains trampoline code and a call to
>>>>>>>>> optimized_callback(). optimized_callback() calls opt_pre_handler()
>>>>>>>>> to execute kprobe handler.
>>>>>>>>
>>>>>>>> OK so this will replace only one instruction.
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Limitations:
>>>>>>>>> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
>>>>>>>>> guarantee the offset between probe point and kprobe pre_handler
>>>>>>>>> is not larger than 128MiB.
>>>>>>>>
>>>>>>>> Hmm, shouldn't we depends on !CONFIG_ARM64_MODULE_PLTS? Or,
>>>>>>>> allocate an intermediate trampoline area similar to arm optprobe
>>>>>>>> does.
>>>>>>>
>>>>>>> Depending on !CONFIG_ARM64_MODULE_PLTS will totally disable
>>>>>>> RANDOMIZE_BASE according to arch/arm64/Kconfig:
>>>>>>> config RANDOMIZE_BASE
>>>>>>> ????bool "Randomize the address of the kernel image"
>>>>>>> ????select ARM64_MODULE_PLTS if MODULES
>>>>>>> ????select RELOCATABLE
>>>>>>
>>>>>> Yes, but why it is required for "RANDOMIZE_BASE"?
>>>>>> Does that imply the module call might need to use PLT in
>>>>>> some cases?
>>>>>>
>>>>>>>
>>>>>>> Depending on !RANDOMIZE_MODULE_REGION_FULL seems to be still
>>>>>>> allowing RANDOMIZE_BASE via avoiding long jump according to:
>>>>>>> arch/arm64/Kconfig:
>>>>>>>
>>>>>>> config RANDOMIZE_MODULE_REGION_FULL
>>>>>>> ????bool "Randomize the module region over a 4 GB range"
>>>>>>> ????depends on RANDOMIZE_BASE
>>>>>>> ????default y
>>>>>>> ????help
>>>>>>> ????? Randomizes the location of the module region inside a 4 GB 
>>>>>>> window
>>>>>>> ????? covering the core kernel. This way, it is less likely for 
>>>>>>> modules
>>>>>>> ????? to leak information about the location of core kernel data 
>>>>>>> structures
>>>>>>> ????? but it does imply that function calls between modules and 
>>>>>>> the core
>>>>>>> ????? kernel will need to be resolved via veneers in the module PLT.
>>>>>>>
>>>>>>> ????? When this option is not set, the module region will be 
>>>>>>> randomized
>>> over
>>>>>>> ????? a limited range that contains the [_stext, _etext] interval 
>>>>>>> of the
>>>>>>> ????? core kernel, so branch relocations are always in range.
>>>>>>
>>>>>> Hmm, this dependency looks strange. If it always in range, don't 
>>>>>> we need
>>>>>> PLT for modules?
>>>>>>
>>>>>> Cataline, would you know why?
>>>>>> Maybe it's a KASLR's Kconfig issue?
>>>>>
>>>>> I actually didn't see any problem after making this change:
>>>>>
>>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>>> index e07e7de9ac49..6440671b72e0 100644
>>>>> --- a/arch/arm64/Kconfig
>>>>> +++ b/arch/arm64/Kconfig
>>>>> @@ -1781,7 +1781,6 @@ config RELOCATABLE
>>>>>
>>>>> ? config RANDOMIZE_BASE
>>>>> ???????? bool "Randomize the address of the kernel image"
>>>>> -?????? select ARM64_MODULE_PLTS if MODULES
>>>>> ???????? select RELOCATABLE
>>>>> ???????? help
>>>>> ?????????? Randomizes the virtual address at which the kernel image is
>>>>> @@ -1801,6 +1800,7 @@ config RANDOMIZE_BASE
>>>>> ? config RANDOMIZE_MODULE_REGION_FULL
>>>>> ???????? bool "Randomize the module region over a 4 GB range"
>>>>> ???????? depends on RANDOMIZE_BASE
>>>>> +?????? select ARM64_MODULE_PLTS if MODULES
>>>>> ???????? default y
>>>>> ???????? help
>>>>> ?????????? Randomizes the location of the module region inside a 4 
>>>>> GB window
>>>>>
>>>>> and having this config:
>>>>> # zcat /proc/config.gz | grep RANDOMIZE_BASE
>>>>> CONFIG_RANDOMIZE_BASE=y
>>>>>
>>>>> # zcat /proc/config.gz | grep RANDOMIZE_MODULE_REGION_FULL
>>>>> # CONFIG_RANDOMIZE_MODULE_REGION_FULL is not set
>>>>>
>>>>> # zcat /proc/config.gz | grep ARM64_MODULE_PLTS
>>>>> # CONFIG_ARM64_MODULE_PLTS is not set
>>>>>
>>>>> Modules work all good:
>>>>> # lsmod
>>>>> Module????????????????? Size? Used by
>>>>> btrfs??????????????? 1355776? 0
>>>>> blake2b_generic??????? 20480? 0
>>>>> libcrc32c????????????? 16384? 1 btrfs
>>>>> xor??????????????????? 20480? 1 btrfs
>>>>> xor_neon?????????????? 16384? 1 xor
>>>>> zstd_compress???????? 163840? 1 btrfs
>>>>> raid6_pq????????????? 110592? 1 btrfs
>>>>> ctr??????????????????? 16384? 0
>>>>> md5??????????????????? 16384? 0
>>>>> ip_tunnel????????????? 32768? 0
>>>>> ipv6????????????????? 442368? 28
>>>>>
>>>>>
>>>>> I am not quite sure if there is a corner case. If no,
>>>>> I would think the kconfig might be some improper.
>>>>
>>>> The corner case is that even CONFIG_RANDOMIZE_MODULE_REGION_FULL
>>>> is not enabled, but if CONFIG_ARM64_MODULE_PLTS is enabled, when
>>>> we can't get memory from the 128MB area in case the area is exhausted,
>>>> we will fall back in module_alloc() to a 2GB area as long as either
>>>> of the below two conditions is met:
>>>>
>>>> 1. KASAN is not enabled
>>>> 2. KASAN is enabled and CONFIG_KASAN_VMALLOC is also enabled.
>>>>
>>>> void *module_alloc(unsigned long size)
>>>> {
>>>> ????u64 module_alloc_end = module_alloc_base + MODULES_VSIZE;
>>>> ????gfp_t gfp_mask = GFP_KERNEL;
>>>> ????void *p;
>>>>
>>>> ????/* Silence the initial allocation */
>>>> ????if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
>>>> ??????? gfp_mask |= __GFP_NOWARN;
>>>>
>>>> ????if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
>>>> ??????? IS_ENABLED(CONFIG_KASAN_SW_TAGS))
>>>> ??????? /* don't exceed the static module region - see below */
>>>> ??????? module_alloc_end = MODULES_END;
>>>>
>>>> ????p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
>>>> ??????????????? module_alloc_end, gfp_mask, PAGE_KERNEL, 0,
>>>> ??????????????? NUMA_NO_NODE, __builtin_return_address(0));
>>>>
>>>> ????if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
>>>> ??????? (IS_ENABLED(CONFIG_KASAN_VMALLOC) ||
>>>> ???????? (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
>>>> ????????? !IS_ENABLED(CONFIG_KASAN_SW_TAGS))))
>>>> ??????? /*
>>>> ???????? * KASAN without KASAN_VMALLOC can only deal with module
>>>> ???????? * allocations being served from the reserved module region,
>>>> ???????? * since the remainder of the vmalloc region is already
>>>> ???????? * backed by zero shadow pages, and punching holes into it
>>>> ???????? * is non-trivial. Since the module region is not randomized
>>>> ???????? * when KASAN is enabled without KASAN_VMALLOC, it is even
>>>> ???????? * less likely that the module region gets exhausted, so we
>>>> ???????? * can simply omit this fallback in that case.
>>>> ???????? */
>>>> ??????? p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
>>>> ??????????????? module_alloc_base + SZ_2G, GFP_KERNEL,
>>>> ??????????????? PAGE_KERNEL, 0, NUMA_NO_NODE,
>>>> ??????????????? __builtin_return_address(0));
>>>>
>>>> ????if (p && (kasan_module_alloc(p, size) < 0)) {
>>>> ??????? vfree(p);
>>>> ??????? return NULL;
>>>> ????}
>>>>
>>>> ????return p;
>>>> }
>>>>
>>>> This should be happening quite rarely. But maybe arm64's document
>>>> needs some minor fixup, otherwise, it is quite confusing.
>>>
>>> OK, so CONFIG_KASAN_VLALLOC=y and CONFIG_ARM64_MODULE_PLTS=y, the
>>> module_alloc()
>>> basically returns the memory in 128MB region, but can return the 
>>> memory in 2GB
>>> region. (This is OK because optprobe can filter it out)
>>> But CONFIG_RANDOMIZE_MODULE_REGION_FULL=y, there is almost no chance 
>>> to get
>>> the memory in 128MB region.
>>>
>>> Hmm, for the optprobe in kernel text, maybe we can define 
>>> 'optinsn_alloc_start'
>>> by 'module_alloc_base - (SZ_2G - MODULES_VADDR)' and use 
>>> __vmalloc_node_range()
>>> to avoid this issue. But that is only for the kernel. For the 
>>> modules, we may
>>> always out of 128MB region.
>>
>> If we can have some separate PLT entries in each module for optprobe,
>> we should be able to short-jump to the PLT entry and then PLT entry
>> will further long-jump to detour out of the range. That is exactly
>> the duty of PLT.
>>
>> Right now, arm64 has support on dynamic_ftrace by adding a
>> section in module for ftrace PLT.
>> arch/arm64/include/asm/module.lds.h:
>> SECTIONS {
>> #ifdef CONFIG_ARM64_MODULE_PLTS
>> ????.plt 0 (NOLOAD) : { BYTE(0) }
>> ????.init.plt 0 (NOLOAD) : { BYTE(0) }
>> ????.text.ftrace_trampoline 0 (NOLOAD) : { BYTE(0) }
>> #endif
>> ...
>> }
>>
>> arch/arm64/kernel/module.c will initialize some PLT entries
>> for ftrace:
>>
>> static int module_init_ftrace_plt(const Elf_Ehdr *hdr,
>> ????????????????? const Elf_Shdr *sechdrs,
>> ????????????????? struct module *mod)
>> {
>> #if defined(CONFIG_ARM64_MODULE_PLTS) && defined(CONFIG_DYNAMIC_FTRACE)
>> ????const Elf_Shdr *s;
>> ????struct plt_entry *plts;
>>
>> ????s = find_section(hdr, sechdrs, ".text.ftrace_trampoline");
>> ????if (!s)
>> ??????? return -ENOEXEC;
>>
>> ????plts = (void *)s->sh_addr;
>>
>> ????__init_plt(&plts[FTRACE_PLT_IDX], FTRACE_ADDR);
>>
>> ????if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS))
>> ??????? __init_plt(&plts[FTRACE_REGS_PLT_IDX], FTRACE_REGS_ADDR);
>>
>> ????mod->arch.ftrace_trampolines = plts;
>> #endif
>> ????return 0;
>> }
>>
>> Ftrace will then use those PLT entries in arch/arm64/kernel/ftrace.c:
>> static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned 
>> long addr)
>> {
>> #ifdef CONFIG_ARM64_MODULE_PLTS
>> ????struct plt_entry *plt = mod->arch.ftrace_trampolines;
>>
>> ????if (addr == FTRACE_ADDR)
>> ??????? return &plt[FTRACE_PLT_IDX];
>> ????if (addr == FTRACE_REGS_ADDR &&
>> ??????? IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS))
>> ??????? return &plt[FTRACE_REGS_PLT_IDX];
>> #endif
>> ????return NULL;
>> }
>>
>> /*
>> ? * Turn on the call to ftrace_caller() in instrumented function
>> ? */
>> int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
>> {
>> ????unsigned long pc = rec->ip;
>> ????u32 old, new;
>> ????long offset = (long)pc - (long)addr;
>>
>> ????if (offset < -SZ_128M || offset >= SZ_128M) {
>> ??????? struct module *mod;
>> ??????? struct plt_entry *plt;
>>
>> ??????? if (!IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
>> ??????????? return -EINVAL;
>>
>> ??????? /*
>> ???????? * On kernels that support module PLTs, the offset between the
>> ???????? * branch instruction and its target may legally exceed the
>> ???????? * range of an ordinary relative 'bl' opcode. In this case, we
>> ???????? * need to branch via a trampoline in the module.
>> ???????? *
>> ???????? * NOTE: __module_text_address() must be called with preemption
>> ???????? * disabled, but we can rely on ftrace_lock to ensure that 'mod'
>> ???????? * retains its validity throughout the remainder of this code.
>> ???????? */
>> ??????? preempt_disable();
>> ??????? mod = __module_text_address(pc);
>> ??????? preempt_enable();
>>
>> ??????? if (WARN_ON(!mod))
>> ??????????? return -EINVAL;
>>
>> ??????? plt = get_ftrace_plt(mod, addr);
>> ??????? if (!plt) {
>> ??????????? pr_err("ftrace: no module PLT for %ps\n", (void *)addr);
>> ??????????? return -EINVAL;
>> ??????? }
>>
>> ??????? addr = (unsigned long)plt;
>> ????}
>>
>> ????old = aarch64_insn_gen_nop();
>> ????new = aarch64_insn_gen_branch_imm(pc, addr, 
>> AARCH64_INSN_BRANCH_LINK);
>>
>> ????return ftrace_modify_code(pc, old, new, true);
>> }
>>
>> This might be the direction to go later. Anyway, "Rome wasn't built
>> in a day", for this stage, we might focus on optprobe for the case
>> of non-randomized module region :-).
>>
>> BTW, @liuqi, if users set "nokaslr" in bootargs, will your optprobe
>> always work and not fall back to normal kprobe even we remove the
>> dependency on RANDOMIZED_MODULE_REGION_FULL?
>>
> Hi Barry,
> 
> I do some tests on Hip08 platform, using nokaslr in booting cmdline and 
> remove dependency on RANDOMIZED_MODULE_REGION_FULL, optprobe seems work.
> Here is the log:
> 
> estuary:/$ uname -a
> Linux (none) 5.13.0-rc4+ #37 SMP PREEMPT Mon Aug 2 08:13:37 CST 2021 
> aarch64 GNU/Linux
> estuary:/$ zcat /proc/config.gz | grep RANDOMIZE_MODULE_REGION
> CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
> estuary:/$ zcat /proc/config.gz | grep OPTPROBE
> CONFIG_OPTPROBES=y
> CONFIG_HAVE_OPTPROBES=y
> estuary:/$ cat /proc/cmdline
> console=ttyAMA0,115200 earlycon=pl011,0x9000000 kpti=off nokaslr
> estuary:/$ cat /sys/bus/platform/devices/hello_driver/kprobe_test
> [?? 61.304143] do_empty returned 0 and took 200 ns to execute
> [?? 61.304662] do_empty returned 0 and took 110 ns to execute
> [?? 61.305196] do_empty returned 0 and took 100 ns to execute
> [?? 61.305745] do_empty returned 0 and took 90 ns to execute
> [?? 61.306262] do_empty returned 0 and took 90 ns to execute
> [?? 61.306781] do_empty returned 0 and took 90 ns to execute
> [?? 61.307286] do_empty returned 0 and took 90 ns to execute
> [?? 61.307798] do_empty returned 0 and took 90 ns to execute
> [?? 61.308314] do_empty returned 0 and took 90 ns to execute
> [?? 61.308828] do_empty returned 0 and took 90 ns to execute
> [?? 61.309323] do_empty returned 0 and took 80 ns to execute
> [?? 61.309832] do_empty returned 0 and took 80 ns to execute
> [?? 61.310357] do_empty returned 0 and took 80 ns to execute
> [?? 61.310871] do_empty returned 0 and took 80 ns to execute
> [?? 61.311361] do_empty returned 0 and took 80 ns to execute
> [?? 61.311851] do_empty returned 0 and took 90 ns to execute
> [?? 61.312358] do_empty returned 0 and took 90 ns to execute
> [?? 61.312879] do_empty returned 0 and took 80 ns to execute
> 
> Thanks,
> Qi
> 

This situation is: function to probe is builtin and pre_handler is build 
as module. I'll try to test the other three situation latter.

Thanks,
Qi
>>>
>>> Thank you,
>>>
>>> -- 
>>> Masami Hiramatsu <mhiramat at kernel.org>
>>
>> Thanks
>> Barry
>> .
>>
> 
> .



From anshuman.khandual at arm.com  Sun Aug  1 21:42:39 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon,  2 Aug 2021 10:12:39 +0530
Subject: [PATCH] arm64/mm: Fix idmap on [16K|36VA|48PA]
Message-ID: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com>

When creating the idmap, the kernel may add one extra level to idmap memory
outside the VA range. But for [16K|36VA|48PA], we need two levels to reach
48 bits. If the bootloader places the kernel in memory above (1 << 46), the
kernel will fail to enable the MMU. Although we are not aware of a platform
where this happens, it is worth to accommodate such scenarios and prevent a
possible kernel crash.

Lets fix the problem on the above configuration by creating two additional
idmap page table levels when 'idmap_text_end' is outside the VA range. This
reduces 'idmap_t0sz' to cover the entire PA range which would prevent table
misconfiguration (fault) when a given 'idmap_t0sz' value requires a single
additional page table level where as two have been built.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Fixes: 215399392fe4 ("arm64: 36 bit VA")
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.14-rc4

RFC: https://lore.kernel.org/lkml/1627019894-14819-1-git-send-email-anshuman.khandual at arm.com/

 arch/arm64/kernel/head.S | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c5c994a..da33bbc 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -329,7 +329,9 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
 
 #if (VA_BITS < 48)
 #define EXTRA_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
+#define EXTRA_SHIFT_1	(EXTRA_SHIFT + PAGE_SHIFT - 3)
 #define EXTRA_PTRS	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT))
+#define EXTRA_PTRS_1	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT_1))
 
 	/*
 	 * If VA_BITS < 48, we have to configure an additional table level.
@@ -342,8 +344,30 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
 #error "Mismatch between VA_BITS and page size/number of translation levels"
 #endif
 
+/*
+ * In this particular CONFIG_ARM64_16K_PAGES config, there might be a
+ * scenario where 'idmap_text_end' ends up high enough in the PA range
+ * requiring two additional idmap page table levels. Reduce idmap_t0sz
+ * to cover the entire PA range. This prevents table misconfiguration
+ * when a given idmap_t0sz value just requires single additional level
+ * where as two levels have been built.
+ */
+#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_PA_BITS_48)
+	mov	x4, EXTRA_PTRS_1
+	create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6
+
+	mov	x4, PTRS_PER_PTE
+	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
+
+	mov	x5, #64 - PHYS_MASK_SHIFT
+	adr_l	x6, idmap_t0sz
+	str	x5, [x6]
+	dmb	sy
+	dc	ivac, x6
+#else
 	mov	x4, EXTRA_PTRS
 	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
+#endif
 #else
 	/*
 	 * If VA_BITS == 48, we don't have to configure an additional
-- 
2.7.4



From icenowy at sipeed.com  Sun Aug  1 23:21:56 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:21:56 +0800
Subject: [PATCH 01/17] rtc: sun6i: Fix time overflow handling
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-2-icenowy@sipeed.com>

From: Andre Przywara <andre.przywara at arm.com>

Using "unsigned long" for UNIX timestamps is never a good idea, and
comparing the value of such a variable against U32_MAX does not do
anything useful on 32-bit systems.

Use the proper time64_t type when dealing with timestamps, and avoid
cutting down the time range unnecessarily. This also fixes the flawed
check for the alarm time being too far into the future.

The check for this condition is actually somewhat theoretical, as the
RTC counts till 2033 only anyways, and 2^32 seconds from now is not
before the year 2157 - at which point I hope nobody will be using this
hardware anymore.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index adec1b14a8de..c551ebf0ac00 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -138,7 +138,7 @@ struct sun6i_rtc_dev {
 	const struct sun6i_rtc_clk_data *data;
 	void __iomem *base;
 	int irq;
-	unsigned long alarm;
+	time64_t alarm;
 
 	struct clk_hw hw;
 	struct clk_hw *int_osc;
@@ -510,10 +510,8 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
 	struct rtc_time *alrm_tm = &wkalrm->time;
 	struct rtc_time tm_now;
-	unsigned long time_now = 0;
-	unsigned long time_set = 0;
-	unsigned long time_gap = 0;
-	int ret = 0;
+	time64_t time_now, time_set;
+	int ret;
 
 	ret = sun6i_rtc_gettime(dev, &tm_now);
 	if (ret < 0) {
@@ -528,9 +526,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 		return -EINVAL;
 	}
 
-	time_gap = time_set - time_now;
-
-	if (time_gap > U32_MAX) {
+	if ((time_set - time_now) > U32_MAX) {
 		dev_err(dev, "Date too far in the future\n");
 		return -EINVAL;
 	}
@@ -539,7 +535,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	writel(0, chip->base + SUN6I_ALRM_COUNTER);
 	usleep_range(100, 300);
 
-	writel(time_gap, chip->base + SUN6I_ALRM_COUNTER);
+	writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
 	chip->alarm = time_set;
 
 	sun6i_rtc_setaie(wkalrm->enabled, chip);
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:00 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:00 +0800
Subject: [PATCH 05/17] rtc: sun6i: add support for R329 RTC
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-6-icenowy@sipeed.com>

Allwinner R329 SoC has a RTC with similar clock control capability to
H6, but its day storage changed to be linear, similar to the one in H616
RTC.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 drivers/rtc/rtc-sun6i.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 752bea949050..06eca57e5215 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -386,6 +386,24 @@ static void __init sun50i_h6_rtc_clk_init(struct device_node *node)
 CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc",
 		      sun50i_h6_rtc_clk_init);
 
+static const struct sun6i_rtc_clk_data sun50i_r329_rtc_data = {
+	.rc_osc_rate = 16000000,
+	.fixed_prescaler = 32,
+	.has_prescaler = 1,
+	.has_out_clk = 1,
+	.export_iosc = 1,
+	.has_losc_en = 1,
+	.has_auto_swt = 1,
+};
+
+static void __init sun50i_r329_rtc_clk_init(struct device_node *node)
+{
+	sun6i_rtc_clk_init(node, &sun50i_r329_rtc_data);
+}
+
+CLK_OF_DECLARE_DRIVER(sun50i_r329_rtc_clk, "allwinner,sun50i-r329-rtc",
+		      sun50i_r329_rtc_clk_init);
+
 /*
  * The R40 user manual is self-conflicting on whether the prescaler is
  * fixed or configurable. The clock diagram shows it as fixed, but there
@@ -791,6 +809,8 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
 	{ .compatible = "allwinner,sun8i-v3-rtc" },
 	{ .compatible = "allwinner,sun50i-h5-rtc" },
 	{ .compatible = "allwinner,sun50i-h6-rtc" },
+	{ .compatible = "allwinner,sun50i-r329-rtc",
+		.data = (void *)RTC_LINEAR_DAY },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:04 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:04 +0800
Subject: [PATCH 09/17] dt-bindings: clock: sunxi-ng: add compatibles for R329
 CCUs
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-10-icenowy@sipeed.com>

R329 has a CPUX CCU and a R-CCU.

Add compatible strings for them.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 .../devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml    | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
index c4b7243ddcf2..4c9a50f263c8 100644
--- a/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
+++ b/Documentation/devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml
@@ -43,6 +43,8 @@ properties:
       - allwinner,sun50i-h6-r-ccu
       - allwinner,sun50i-h616-ccu
       - allwinner,sun50i-h616-r-ccu
+      - allwinner,sun50i-r329-ccu
+      - allwinner,sun50i-r329-r-ccu
       - allwinner,suniv-f1c100s-ccu
       - nextthing,gr8-ccu
 
@@ -102,6 +104,8 @@ else:
           - allwinner,sun50i-a100-ccu
           - allwinner,sun50i-h6-ccu
           - allwinner,sun50i-h616-ccu
+          - allwinner,sun50i-r329-ccu
+          - allwinner,sun50i-r329-r-ccu
 
   then:
     properties:
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:08 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:08 +0800
Subject: [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-14-icenowy@sipeed.com>

The two MMC controllers in Allwinner R329 have a mixed feature set
comparing to the previous SoCs' ordinary MMC and eMMC controllers.

Add support for them.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 drivers/mmc/host/sunxi-mmc.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 2702736a1c57..0c9f66785286 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -1199,6 +1199,15 @@ static const struct sunxi_mmc_cfg sun50i_a100_emmc_cfg = {
 	.needs_new_timings = true,
 };
 
+static const struct sunxi_mmc_cfg sun50i_r329_cfg = {
+	.idma_des_size_bits = 13,
+	.idma_des_shift = 2,
+	.clk_delays = NULL,
+	.can_calibrate = true,
+	.mask_data0 = true,
+	.needs_new_timings = true,
+};
+
 static const struct of_device_id sunxi_mmc_of_match[] = {
 	{ .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg },
 	{ .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg },
@@ -1209,6 +1218,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = {
 	{ .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
 	{ .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
 	{ .compatible = "allwinner,sun50i-a100-emmc", .data = &sun50i_a100_emmc_cfg },
+	{ .compatible = "allwinner,sun50i-r329-mmc", .data = &sun50i_r329_cfg },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:09 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:09 +0800
Subject: [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings for
 Sipeed MaixSense
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-15-icenowy@sipeed.com>

Sipeed MaixSense is an Allwinner R329 development kit based on Maix IIA
SoM.

Add compatible strings for it.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index 889128acf49a..bce306908eff 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -444,6 +444,12 @@ properties:
           - const: haoyu,a10-marsboard
           - const: allwinner,sun4i-a10
 
+      - description: Sipeed MaixSense
+        items:
+          - const: sipeed,maixsense
+          - const: sipeed,maix-iia
+          - const: allwinner,sun50i-r329
+
       - description: MapleBoard MP130
         items:
           - const: mapleboard,mp130
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:03 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:03 +0800
Subject: [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO pin
 controller
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-9-icenowy@sipeed.com>

Allwinner R320 SoC has a pin controller in the CPUS power domain.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 drivers/pinctrl/sunxi/Kconfig                 |   5 +
 drivers/pinctrl/sunxi/Makefile                |   1 +
 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c | 292 ++++++++++++++++++
 3 files changed, 298 insertions(+)
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index c662e8b1b351..abd60ff8daec 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -134,4 +134,9 @@ config PINCTRL_SUN50I_R329
 	default ARM64 && ARCH_SUNXI
 	select PINCTRL_SUNXI
 
+config PINCTRL_SUN50I_R329_R
+	bool "Support for the Allwinner R329 R-PIO"
+	default ARM64 && ARCH_SUNXI
+	select PINCTRL_SUNXI
+
 endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index e33f7c5f1ff9..245840a7959e 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
 obj-$(CONFIG_PINCTRL_SUN50I_H616)	+= pinctrl-sun50i-h616.o
 obj-$(CONFIG_PINCTRL_SUN50I_H616_R)	+= pinctrl-sun50i-h616-r.o
 obj-$(CONFIG_PINCTRL_SUN50I_R329)	+= pinctrl-sun50i-r329.o
+obj-$(CONFIG_PINCTRL_SUN50I_R329_R)	+= pinctrl-sun50i-r329-r.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
new file mode 100644
index 000000000000..dc4792c685ba
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner H616 R_PIO pin controller driver
+ *
+ * Copyright (C) 2020 Arm Ltd.
+ * Based on former work, which is:
+ *   Copyright (C) 2017 Icenowy Zheng <icenowy at aosc.io>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/reset.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin sun50i_r329_r_pins[] = {
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s"),		/* LRCK */
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* DATA3 */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PL_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s"),		/* BCLK */
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* DATA2 */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PL_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s_dout0"),
+		  SUNXI_FUNCTION(0x3, "s_i2s_din1"),
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* DATA1 */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PL_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s_dout1"),
+		  SUNXI_FUNCTION(0x3, "s_i2s_din0"),
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* DATA0 */
+		  SUNXI_FUNCTION(0x5, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PL_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2s"),		/* MCLK */
+		  SUNXI_FUNCTION(0x3, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "s_dmic"),	/* CLK */
+		  SUNXI_FUNCTION(0x5, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PL_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PL_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM4 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PL_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION(0x5, "s_pwm"),		/* PWM5 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PL_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* TX */
+		  SUNXI_FUNCTION(0x3, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION(0x4, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PL_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* RX */
+		  SUNXI_FUNCTION(0x3, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION(0x4, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)),	/* PL_EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)),	/* PL_EINT10 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* TX */
+		  SUNXI_FUNCTION(0x3, "s_jtag"),	/* MS */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),	/* PM_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* RX */
+		  SUNXI_FUNCTION(0x3, "s_jtag"),	/* CK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),	/* PM_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "s_jtag"),	/* DO */
+		  SUNXI_FUNCTION(0x4, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION(0x5, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),	/* PM_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),	/* PM_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),	/* PM_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION(0x3, "s_jtag"),	/* DI */
+		  SUNXI_FUNCTION(0x4, "s_i2c"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),	/* PM_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nmi"),
+		  SUNXI_FUNCTION(0x3, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)),	/* PM_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "s_ir"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "clock"),		/* X32KFOUT */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 7)),	/* PM_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 8)),	/* PM_EINT8 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)),	/* PN_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* MDC */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)),	/* PN_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* MDIO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)),	/* PN_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXD3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)),	/* PN_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)),	/* PN_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXD2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)),	/* PN_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXD0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)),	/* PN_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)),	/* PN_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXERR */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)),	/* PN_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXCTL/TXEN */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)),	/* PN_EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXD3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)),	/* PN_EINT10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXD1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)),	/* PN_EINT11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* RXCTL/CRS_DV */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)),	/* PN_EINT12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXD2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)),	/* PN_EINT13 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 14),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXD1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)),	/* PN_EINT14 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 15),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* TXD0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 15)),	/* PN_EINT15 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 16),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* EPHY-25M */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 16)),	/* PN_EINT16 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 17),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "emac"),		/* CLKIN */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 17)),	/* PN_EINT17 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 18),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 18)),	/* PN_EINT18 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 19),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 19)),	/* PN_EINT19 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 20),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 20)),	/* PN_EINT20 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 21),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 21)),	/* PN_EINT21 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 22),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 22)),	/* PN_EINT22 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(N, 23),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 23)),	/* PN_EINT23 */
+};
+
+static const struct sunxi_pinctrl_desc sun50i_r329_r_pinctrl_data = {
+	.pins = sun50i_r329_r_pins,
+	.npins = ARRAY_SIZE(sun50i_r329_r_pins),
+	.pin_base = PL_BASE,
+	.irq_banks = 3,
+	.io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
+};
+
+static int sun50i_r329_r_pinctrl_probe(struct platform_device *pdev)
+{
+	return sunxi_pinctrl_init(pdev,
+				  &sun50i_r329_r_pinctrl_data);
+}
+
+static const struct of_device_id sun50i_r329_r_pinctrl_match[] = {
+	{ .compatible = "allwinner,sun50i-r329-r-pinctrl", },
+	{}
+};
+
+static struct platform_driver sun50i_r329_r_pinctrl_driver = {
+	.probe	= sun50i_r329_r_pinctrl_probe,
+	.driver	= {
+		.name		= "sun50i-r329-r-pinctrl",
+		.of_match_table	= sun50i_r329_r_pinctrl_match,
+	},
+};
+builtin_platform_driver(sun50i_r329_r_pinctrl_driver);
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:10 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:10 +0800
Subject: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-16-icenowy@sipeed.com>

Allwinner R329 is a new SoC focused on smart audio devices.

Add a DTSI file for it.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
 1 file changed, 244 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
new file mode 100644
index 000000000000..bfefa2b734b0
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2021 Sipeed
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/sun50i-r329-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-ccu.h>
+#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <0>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu at 1 {
+			compatible = "arm,cortex-a53";
+			device_type = "cpu";
+			reg = <1>;
+			enable-method = "psci";
+		};
+	};
+
+	osc24M: osc24M_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "osc24M";
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		arm,no-tick-in-suspend;
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10
+			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		pio: pinctrl at 2000400 {
+			compatible = "allwinner,sun50i-r329-pinctrl";
+			reg = <0x02000400 0x400>;
+			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+
+			uart0_pb_pins: uart0-pb-pins {
+				pins = "PB4", "PB5";
+				function = "uart0";
+			};
+
+			mmc0_pf_pins: mmc0-pf-pins {
+				pins = "PF0", "PF1", "PF2",
+				       "PF3", "PF4", "PF5";
+				function = "mmc0";
+			};
+
+			mmc1_clk_pg0: mmc1-clk-pg0 {
+				pins = "PG0";
+				function = "mmc1_clk";
+			};
+
+			mmc1_cmd_pg1: mmc1-clk-pg1 {
+				pins = "PG1";
+				function = "mmc1_cmd";
+			};
+
+			mmc1_d0_pg2: mmc1-clk-pg2 {
+				pins = "PG2";
+				function = "mmc1_d0";
+			};
+
+			mmc1_d1_pg3: mmc1-clk-pg3 {
+				pins = "PG3";
+				function = "mmc1_d1";
+			};
+
+			mmc1_d2_pg4: mmc1-clk-pg4 {
+				pins = "PG4";
+				function = "mmc1_d2";
+			};
+
+			mmc1_d3_pg5: mmc1-clk-pg5 {
+				pins = "PG5";
+				function = "mmc1_d3";
+			};
+		};
+
+		ccu: clock at 2001000 {
+			compatible = "allwinner,sun50i-r329-ccu";
+			reg = <0x02001000 0x1000>;
+			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		uart0: serial at 2500000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x02500000 0x400>;
+			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART0>;
+			resets = <&ccu RST_BUS_UART0>;
+			status = "disabled";
+		};
+
+		uart1: serial at 2500400 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x02500400 0x400>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART1>;
+			resets = <&ccu RST_BUS_UART1>;
+			status = "disabled";
+		};
+
+		uart2: serial at 2500800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x02500800 0x400>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART2>;
+			resets = <&ccu RST_BUS_UART2>;
+			status = "disabled";
+		};
+
+		uart3: serial at 2500c00 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x02500c00 0x400>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&ccu CLK_BUS_UART3>;
+			resets = <&ccu RST_BUS_UART3>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller at 3021000 {
+			compatible = "arm,gic-400";
+			reg = <0x03021000 0x1000>,
+			      <0x03022000 0x2000>,
+			      <0x03024000 0x2000>,
+			      <0x03026000 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		mmc0: mmc at 4020000 {
+			compatible = "allwinner,sun50i-r329-mmc";
+			reg = <0x04020000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC0>, <&ccu CLK_MMC0>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC0>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+			max-frequency = <150000000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc1: mmc at 4021000 {
+			compatible = "allwinner,sun50i-r329-mmc";
+			reg = <0x04021000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>;
+			clock-names = "ahb", "mmc";
+			resets = <&ccu RST_BUS_MMC1>;
+			reset-names = "ahb";
+			interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			max-frequency = <150000000>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		r_ccu: clock at 7010000 {
+			compatible = "allwinner,sun50i-r329-r-ccu";
+			reg = <0x07010000 0x10000>;
+			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
+			clock-names = "hosc", "losc", "iosc";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		r_pio: pinctrl at 7022000 {
+			compatible = "allwinner,sun50i-r329-r-pinctrl";
+			reg = <0x07022000 0x400>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&rtc 0>;
+			clock-names = "apb", "hosc", "losc";
+			gpio-controller;
+			#gpio-cells = <3>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		rtc: rtc at 7090000 {
+			compatible = "allwinner,sun50i-r329-rtc";
+			reg = <0x07090000 0x400>;
+			interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+			clock-output-names = "osc32k", "osc32k-out", "iosc";
+			#clock-cells = <1>;
+		};
+	};
+};
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:02 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:02 +0800
Subject: [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin controller
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-8-icenowy@sipeed.com>

Allwinner R329 SoC has two pin controllers similar to ones on previous
SoCs, one in CPUX power domain and another in CPUS.

This patch adds support for the CPUX domain pin controller.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 drivers/pinctrl/sunxi/Kconfig               |   5 +
 drivers/pinctrl/sunxi/Makefile              |   1 +
 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c | 410 ++++++++++++++++++++
 3 files changed, 416 insertions(+)
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c

diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index 33751a6a0757..c662e8b1b351 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -129,4 +129,9 @@ config PINCTRL_SUN50I_H616_R
 	default ARM64 && ARCH_SUNXI
 	select PINCTRL_SUNXI
 
+config PINCTRL_SUN50I_R329
+	bool "Support for the Allwinner R329 PIO"
+	default ARM64 && ARCH_SUNXI
+	select PINCTRL_SUNXI
+
 endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index d3440c42b9d6..e33f7c5f1ff9 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -25,5 +25,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6)		+= pinctrl-sun50i-h6.o
 obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
 obj-$(CONFIG_PINCTRL_SUN50I_H616)	+= pinctrl-sun50i-h616.o
 obj-$(CONFIG_PINCTRL_SUN50I_H616_R)	+= pinctrl-sun50i-h616-r.o
+obj-$(CONFIG_PINCTRL_SUN50I_R329)	+= pinctrl-sun50i-r329.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
new file mode 100644
index 000000000000..742f437ec0b6
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Allwinner R329 SoC pinctrl driver.
+ *
+ * Copyright (C) 2021 Sipeed
+ * based on the H616 pinctrl driver
+ *   Copyright (C) 2020 Arm Ltd.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin r329_pins[] = {
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM0 */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS */
+		  SUNXI_FUNCTION(0x5, "ledc"),		/* DO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PB_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM1 */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK */
+		  SUNXI_FUNCTION(0x5, "i2s0"),		/* MCLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PB_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM2 */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO */
+		  SUNXI_FUNCTION(0x5, "i2s0"),		/* LRCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PB_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM3 */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI */
+		  SUNXI_FUNCTION(0x5, "i2s0"),		/* BCLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PB_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart0"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM4 */
+		  SUNXI_FUNCTION(0x4, "i2s0_dout0"),
+		  SUNXI_FUNCTION(0x5, "i2s0_din1"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PB_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart0"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM5 */
+		  SUNXI_FUNCTION(0x4, "i2s0_dout1"),
+		  SUNXI_FUNCTION(0x5, "i2s0_din0"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PB_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM6 */
+		  SUNXI_FUNCTION(0x4, "i2s0"),		/* DOUT2 */
+		  SUNXI_FUNCTION(0x5, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PB_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM7 */
+		  SUNXI_FUNCTION(0x4, "i2s0"),		/* DOUT3 */
+		  SUNXI_FUNCTION(0x5, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PB_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "ir_tx"),
+		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM8 */
+		  SUNXI_FUNCTION(0x4, "ir_rx"),
+		  SUNXI_FUNCTION(0x5, "ledc"),		/* DO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PB_EINT8 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* RB0 */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* CS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* RE */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* CMD */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* CE0 */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D2 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* WP */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* CLE */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* ALE */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D0 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* WE */
+		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* HOLD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ0 */
+		  SUNXI_FUNCTION(0x3, "mmc0")),		/* RST */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ1 */
+		  SUNXI_FUNCTION(0x5, "boot_sel")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ7 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* VPPEN */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),	/* PF_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ6 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* VPPPP */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),	/* PF_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ5 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* PWREN */
+		  SUNXI_FUNCTION(0x4, "uart"),		/* TX */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),	/* PF_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ4 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* CLK */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* CMD */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),	/* PF_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQS */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* DATA */
+		  SUNXI_FUNCTION(0x4, "uart"),		/* RX */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),	/* PF_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ2 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* RST */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK */
+		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),	/* PF_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ1 */
+		  SUNXI_FUNCTION(0x3, "sim0"),		/* DET */
+		  SUNXI_FUNCTION(0x4, "spdif_in"),
+		  SUNXI_FUNCTION(0x5, "spdif_out"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)),	/* PF_EINT6 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_clk"),
+		  SUNXI_FUNCTION(0x3, "mmc1_d2"),
+		  /* 0x4 is also mmc1_d2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)),	/* PG_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_cmd"),
+		  SUNXI_FUNCTION(0x3, "mmc1_d3"),
+		  SUNXI_FUNCTION(0x4, "mmc1_clk"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)),	/* PG_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_d0"),
+		  SUNXI_FUNCTION(0x3, "mmc1_cmd"),
+		  SUNXI_FUNCTION(0x4, "mmc1_d3"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)),	/* PG_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_d1"),
+		  SUNXI_FUNCTION(0x3, "mmc1_clk"),
+		  /* 0x4 is also mmc1_d1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)),	/* PG_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_d2"),
+		  SUNXI_FUNCTION(0x3, "mmc1_d0"),
+		  /* 0x4 is also mmc1_d0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)),	/* PG_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1_d3"),
+		  SUNXI_FUNCTION(0x3, "mmc1_d1"),
+		  SUNXI_FUNCTION(0x4, "mmc1_cmd"),
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)),	/* PG_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)),	/* PG_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)),	/* PG_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* RTS */
+		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* HOLD/DBI-DCX/DBI-WRX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)),	/* PG_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* WP/DBI-TE */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)),	/* PG_EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* MCLK */
+		  SUNXI_FUNCTION(0x3, "ledc"),		/* DO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)),	/* PG_EINT10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* LRCK */
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* CS/DBI-CSX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)),	/* PG_EINT11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* BCLK */
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* CLK/DBI-SCLK */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)),	/* PG_EINT12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION(0x3, "i2s1_dout0"),
+		  SUNXI_FUNCTION(0x4, "i2s1_din1"),
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* MOSI/DBI-SDO */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)),	/* PG_EINT13 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "i2s1_dout1"),
+		  SUNXI_FUNCTION(0x4, "i2s1_din0"),
+		  SUNXI_FUNCTION(0x5, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)),	/* PG_EINT14 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION(0x3, "uart0"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* CS/DBI-CSX */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM0 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)),	/* PH_EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "uart0"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* CLK/DBI-SCLK */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM1 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)),	/* PH_EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION(0x3, "ledc"),		/* DO */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* MOSI/DBI-SDO */
+		  SUNXI_FUNCTION(0x5, "ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)),	/* PH_EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "spdif"),		/* OUT */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+		  SUNXI_FUNCTION(0x5, "ir"),		/* TX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)),	/* PH_EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
+		  SUNXI_FUNCTION(0x3, "spi1_cs"),	/* CS/DBI-CSX */
+		  SUNXI_FUNCTION(0x4, "spi1_hold"),	/* HOLD/DBI-DCX/DBI-WRX */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM2 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)),	/* PH_EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
+		  SUNXI_FUNCTION(0x3, "spi1_clk"),	/* CLK/DBI-SCLK */
+		  SUNXI_FUNCTION(0x4, "spi1_wp"),	/* WP/DBI-TE */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM3 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)),	/* PH_EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* MOSI/SPI-DBO */
+		  SUNXI_FUNCTION(0x4, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM4 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)),	/* PH_EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
+		  SUNXI_FUNCTION(0x4, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM5 */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)),	/* PH_EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* WP/DBI-TE */
+		  SUNXI_FUNCTION(0x4, "ledc"),		/* DO */
+		  SUNXI_FUNCTION(0x5, "ir"),		/* TX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)),	/* PH_EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION(0x3, "spi1"),		/* HOLD/DBI-DCX/DBI-WRX */
+		  SUNXI_FUNCTION(0x4, "spdif"),		/* IN */
+		  SUNXI_FUNCTION(0x5, "ir"),		/* RX */
+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)),	/* PH_EINT9 */
+};
+static const unsigned int r329_irq_bank_map[] = { 1, 5, 6, 7 };
+
+static const struct sunxi_pinctrl_desc r329_pinctrl_data = {
+	.pins = r329_pins,
+	.npins = ARRAY_SIZE(r329_pins),
+	.irq_banks = ARRAY_SIZE(r329_irq_bank_map),
+	.irq_bank_map = r329_irq_bank_map,
+	.io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
+};
+
+static int r329_pinctrl_probe(struct platform_device *pdev)
+{
+	return sunxi_pinctrl_init(pdev, &r329_pinctrl_data);
+}
+
+static const struct of_device_id r329_pinctrl_match[] = {
+	{ .compatible = "allwinner,sun50i-r329-pinctrl", },
+	{}
+};
+
+static struct platform_driver r329_pinctrl_driver = {
+	.probe	= r329_pinctrl_probe,
+	.driver	= {
+		.name		= "sun50i-r329-pinctrl",
+		.of_match_table	= r329_pinctrl_match,
+	},
+};
+builtin_platform_driver(r329_pinctrl_driver);
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:21:55 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:21:55 +0800
Subject: [PATCH 00/17] Basical Allwinner R329 support
Message-ID: <20210802062212.73220-1-icenowy@sipeed.com>

This patchset tries to add basical support for Allwinner R329 SoC to the
Linux kernel, including clock/pintrl driver and MMC support.

Three patches from the H616 patchset, which are used to support the RTC
with linear day, are attached into this patchset. Other RTC-related
patches of that patchset is not included, because the binding of the
clock part there is still under discussion.

Then I added RTC binding and support (which is now only a struct
addition). I added RTC into this patchset, with the same reason that
H616 patchset contains RTC, which is to make the clock tree correct at
the first inclusion.

After RTC, main basical SoC-specific part, pinctrl and CCU, come. The
R329 CCU is something special because PLLs are in R-CCU, no main CCU.

MMC support is added here because it's also a simple struct addition
work, no main driver code change needed.

Finally it comes the DT part. The DT binding of MaixSense, the device
that I am working on now, is added. Then the DTSI for R329 SoC, the DTSI
file for Sipeed Maix IIA SoM (which is utilized on MaixSense) and the
main DT file for MaixSense are added.

Andre Przywara (3):
  rtc: sun6i: Fix time overflow handling
  rtc: sun6i: Add support for linear day storage
  rtc: sun6i: Add support for broken-down alarm registers

Icenowy Zheng (14):
  dt-bindings: rtc: sun6i: add compatible string for R329 RTC
  rtc: sun6i: add support for R329 RTC
  dt-bindings: pinctrl: document Allwinner R329 PIO and R-PIO
  pinctrl: sunxi: add support for R329 CPUX pin controller
  pinctrl: sunxi: add support for R329 R-PIO pin controller
  dt-bindings: clock: sunxi-ng: add compatibles for R329 CCUs
  clk: sunxi=ng: add support for R329 R-CCU
  clk: sunxi-ng: add support for Allwinner R329 CCU
  dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible string
  mmc: sunxi: add support for R329 MMC controllers
  dt-bindings: arm: sunxi: add compatible strings for Sipeed MaixSense
  arm64: allwinner: dts: add DTSI file for R329 SoC
  arm64: allwinner: dts: r329: add DTSI file for Sipeed Maix IIA
  arm64: allwinner: dts: r329: add support for Sipeed MaixSense

 .../devicetree/bindings/arm/sunxi.yaml        |   6 +
 .../clock/allwinner,sun4i-a10-ccu.yaml        |   4 +
 .../bindings/mmc/allwinner,sun4i-a10-mmc.yaml |   1 +
 .../pinctrl/allwinner,sun4i-a10-pinctrl.yaml  |   4 +
 .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml |   6 +-
 arch/arm64/boot/dts/allwinner/Makefile        |   1 +
 .../dts/allwinner/sun50i-r329-maix-iia.dtsi   |  34 ++
 .../dts/allwinner/sun50i-r329-maixsense.dts   |  37 ++
 .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++
 drivers/clk/sunxi-ng/Kconfig                  |  10 +
 drivers/clk/sunxi-ng/Makefile                 |   2 +
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 +++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
 drivers/clk/sunxi-ng/ccu-sun50i-r329.c        | 526 ++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329.h        |  32 ++
 drivers/mmc/host/sunxi-mmc.c                  |  10 +
 drivers/pinctrl/sunxi/Kconfig                 |  10 +
 drivers/pinctrl/sunxi/Makefile                |   2 +
 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c | 292 ++++++++++
 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c   | 410 ++++++++++++++
 drivers/rtc/rtc-sun6i.c                       | 154 +++--
 include/dt-bindings/clock/sun50i-r329-ccu.h   |  73 +++
 include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
 include/dt-bindings/reset/sun50i-r329-ccu.h   |  45 ++
 include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 +
 25 files changed, 2320 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
 create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
 create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
 create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
 create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h

-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:21:58 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:21:58 +0800
Subject: [PATCH 03/17] rtc: sun6i: Add support for broken-down alarm registers
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-4-icenowy@sipeed.com>

From: Andre Przywara <andre.przywara at arm.com>

Newer versions of the Allwinner RTC, for instance as found in the H616
SoC, not only store the current day as a linear number, but also change
the way the alarm is handled: There are now two registers, that
explicitly store the wakeup time, in the same format as the current
time.

Add support for that variant by writing the requested wakeup time
directly into the registers, instead of programming the seconds left, as
the old SoCs required.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 57 +++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index a980d4e7408d..752bea949050 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -48,7 +48,8 @@
 
 /* Alarm 0 (counter) */
 #define SUN6I_ALRM_COUNTER			0x0020
-#define SUN6I_ALRM_CUR_VAL			0x0024
+/* This holds the remaining alarm seconds on older SoCs (current value) */
+#define SUN6I_ALRM_COUNTER_HMS			0x0024
 #define SUN6I_ALRM_EN				0x0028
 #define SUN6I_ALRM_EN_CNT_EN			BIT(0)
 #define SUN6I_ALRM_IRQ_EN			0x002c
@@ -523,32 +524,54 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
 	struct rtc_time *alrm_tm = &wkalrm->time;
 	struct rtc_time tm_now;
-	time64_t time_now, time_set;
+	time64_t time_set;
+	u32 counter_val, counter_val_hms;
 	int ret;
 
-	ret = sun6i_rtc_gettime(dev, &tm_now);
-	if (ret < 0) {
-		dev_err(dev, "Error in getting time\n");
-		return -EINVAL;
-	}
-
 	time_set = rtc_tm_to_time64(alrm_tm);
-	time_now = rtc_tm_to_time64(&tm_now);
-	if (time_set <= time_now) {
-		dev_err(dev, "Date to set in the past\n");
-		return -EINVAL;
-	}
 
-	if ((time_set - time_now) > U32_MAX) {
-		dev_err(dev, "Date too far in the future\n");
-		return -EINVAL;
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/*
+		 * The alarm registers hold the actual alarm time, encoded
+		 * in the same way (linear day + HMS) as the current time.
+		 */
+		counter_val_hms = SUN6I_TIME_SET_SEC_VALUE(alrm_tm->tm_sec)  |
+				  SUN6I_TIME_SET_MIN_VALUE(alrm_tm->tm_min)  |
+				  SUN6I_TIME_SET_HOUR_VALUE(alrm_tm->tm_hour);
+		/* The division will cut off the H:M:S part of alrm_tm. */
+		counter_val = div_u64(rtc_tm_to_time64(alrm_tm), SECS_PER_DAY);
+	} else {
+		/* The alarm register holds the number of seconds left. */
+		time64_t time_now;
+
+		ret = sun6i_rtc_gettime(dev, &tm_now);
+		if (ret < 0) {
+			dev_err(dev, "Error in getting time\n");
+			return -EINVAL;
+		}
+
+		time_now = rtc_tm_to_time64(&tm_now);
+		if (time_set <= time_now) {
+			dev_err(dev, "Date to set in the past\n");
+			return -EINVAL;
+		}
+		if ((time_set - time_now) > U32_MAX) {
+			dev_err(dev, "Date too far in the future\n");
+			return -EINVAL;
+		}
+
+		counter_val = time_set - time_now;
 	}
 
 	sun6i_rtc_setaie(0, chip);
 	writel(0, chip->base + SUN6I_ALRM_COUNTER);
+	if (chip->flags & RTC_LINEAR_DAY)
+		writel(0, chip->base + SUN6I_ALRM_COUNTER_HMS);
 	usleep_range(100, 300);
 
-	writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
+	writel(counter_val, chip->base + SUN6I_ALRM_COUNTER);
+	if (chip->flags & RTC_LINEAR_DAY)
+		writel(counter_val_hms, chip->base + SUN6I_ALRM_COUNTER_HMS);
 	chip->alarm = time_set;
 
 	sun6i_rtc_setaie(wkalrm->enabled, chip);
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:21:59 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:21:59 +0800
Subject: [PATCH 04/17] dt-bindings: rtc: sun6i: add compatible string for R329
 RTC
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-5-icenowy@sipeed.com>

Allwinner R329 has a RTC similar to previous ones, capable of
controlling LOSC and IOSC and with only one alarm.

Add a compatible string for it.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 .../devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml    | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
index beeb90e55727..7fd1ad46496b 100644
--- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
@@ -26,6 +26,7 @@ properties:
           - const: allwinner,sun50i-a64-rtc
           - const: allwinner,sun8i-h3-rtc
       - const: allwinner,sun50i-h6-rtc
+      - const: allwinner,sun50i-r329-rtc
 
   reg:
     maxItems: 1
@@ -85,6 +86,7 @@ allOf:
             enum:
               - allwinner,sun8i-h3-rtc
               - allwinner,sun50i-h5-rtc
+              - allwinner,sun50i-r329-rtc
 
     then:
       properties:
@@ -108,7 +110,9 @@ allOf:
       properties:
         compatible:
           contains:
-            const: allwinner,sun8i-r40-rtc
+            enum:
+              - allwinner,sun8i-r40-rtc
+              - allwinner,sun50i-r329-rtc
 
     then:
       properties:
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:21:57 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:21:57 +0800
Subject: [PATCH 02/17] rtc: sun6i: Add support for linear day storage
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-3-icenowy@sipeed.com>

From: Andre Przywara <andre.przywara at arm.com>

Newer versions of the Allwinner RTC, as for instance found in the H616
SoC, no longer store a broken-down day/month/year representation in the
RTC_DAY_REG, but just a linear day number.
The user manual does not give any indication about the expected epoch
time of this day count, but the BSP kernel uses the UNIX epoch, which
allows easy support due to existing conversion functions in the kernel.

Allow tagging a compatible string with a flag, and use that to mark
those new RTCs. Then convert between a UNIX day number (converted into
seconds) and the broken-down day representation using mktime64() and
time64_to_tm() in the set_time/get_time functions.

That enables support for the RTC in those new chips.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/rtc/rtc-sun6i.c | 69 +++++++++++++++++++++++++++--------------
 1 file changed, 46 insertions(+), 23 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c551ebf0ac00..a980d4e7408d 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -110,6 +110,8 @@
 #define SUN6I_YEAR_MIN				1970
 #define SUN6I_YEAR_OFF				(SUN6I_YEAR_MIN - 1900)
 
+#define SECS_PER_DAY				(24 * 3600ULL)
+
 /*
  * There are other differences between models, including:
  *
@@ -133,12 +135,15 @@ struct sun6i_rtc_clk_data {
 	unsigned int has_auto_swt : 1;
 };
 
+#define RTC_LINEAR_DAY	BIT(0)
+
 struct sun6i_rtc_dev {
 	struct rtc_device *rtc;
 	const struct sun6i_rtc_clk_data *data;
 	void __iomem *base;
 	int irq;
 	time64_t alarm;
+	unsigned long flags;
 
 	struct clk_hw hw;
 	struct clk_hw *int_osc;
@@ -467,22 +472,30 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 	} while ((date != readl(chip->base + SUN6I_RTC_YMD)) ||
 		 (time != readl(chip->base + SUN6I_RTC_HMS)));
 
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/*
+		 * Newer chips store a linear day number, the manual
+		 * does not mandate any epoch base. The BSP driver uses
+		 * the UNIX epoch, let's just copy that, as it's the
+		 * easiest anyway.
+		 */
+		rtc_time64_to_tm((date & 0xffff) * SECS_PER_DAY, rtc_tm);
+	} else {
+		rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date);
+		rtc_tm->tm_mon  = SUN6I_DATE_GET_MON_VALUE(date) - 1;
+		rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date);
+
+		/*
+		 * switch from (data_year->min)-relative offset to
+		 * a (1900)-relative one
+		 */
+		rtc_tm->tm_year += SUN6I_YEAR_OFF;
+	}
+
 	rtc_tm->tm_sec  = SUN6I_TIME_GET_SEC_VALUE(time);
 	rtc_tm->tm_min  = SUN6I_TIME_GET_MIN_VALUE(time);
 	rtc_tm->tm_hour = SUN6I_TIME_GET_HOUR_VALUE(time);
 
-	rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date);
-	rtc_tm->tm_mon  = SUN6I_DATE_GET_MON_VALUE(date);
-	rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date);
-
-	rtc_tm->tm_mon  -= 1;
-
-	/*
-	 * switch from (data_year->min)-relative offset to
-	 * a (1900)-relative one
-	 */
-	rtc_tm->tm_year += SUN6I_YEAR_OFF;
-
 	return 0;
 }
 
@@ -567,20 +580,25 @@ static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
 	u32 date = 0;
 	u32 time = 0;
 
-	rtc_tm->tm_year -= SUN6I_YEAR_OFF;
-	rtc_tm->tm_mon += 1;
-
-	date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
-		SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon)  |
-		SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
-
-	if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN))
-		date |= SUN6I_LEAP_SET_VALUE(1);
-
 	time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec)  |
 		SUN6I_TIME_SET_MIN_VALUE(rtc_tm->tm_min)  |
 		SUN6I_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour);
 
+	if (chip->flags & RTC_LINEAR_DAY) {
+		/* The division will cut off the H:M:S part of rtc_tm. */
+		date = div_u64(rtc_tm_to_time64(rtc_tm), SECS_PER_DAY);
+	} else {
+		rtc_tm->tm_year -= SUN6I_YEAR_OFF;
+		rtc_tm->tm_mon += 1;
+
+		date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
+			SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon)  |
+			SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
+
+		if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN))
+			date |= SUN6I_LEAP_SET_VALUE(1);
+	}
+
 	/* Check whether registers are writable */
 	if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
 			   SUN6I_LOSC_CTRL_ACC_MASK, 50)) {
@@ -674,6 +692,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, chip);
 
+	chip->flags = (unsigned long)of_device_get_match_data(&pdev->dev);
+
 	chip->irq = platform_get_irq(pdev, 0);
 	if (chip->irq < 0)
 		return chip->irq;
@@ -720,7 +740,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 		return PTR_ERR(chip->rtc);
 
 	chip->rtc->ops = &sun6i_rtc_ops;
-	chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */
+	if (chip->flags & RTC_LINEAR_DAY)
+		chip->rtc->range_max = (65536 * SECS_PER_DAY) - 1;
+	else
+		chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */
 
 	ret = devm_rtc_register_device(chip->rtc);
 	if (ret)
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:01 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:01 +0800
Subject: [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO and
 R-PIO
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-7-icenowy@sipeed.com>

Allwinner R329 have two pin controllers similar to previous Allwinner
SoCs, PIO and R-PIO.

Add compatible strings for them.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 .../bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml         | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
index cce63c3cc463..802fba3fa34d 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
@@ -55,6 +55,8 @@ properties:
       - allwinner,sun50i-h6-r-pinctrl
       - allwinner,sun50i-h616-pinctrl
       - allwinner,sun50i-h616-r-pinctrl
+      - allwinner,sun50i-r329-pinctrl
+      - allwinner,sun50i-r329-r-pinctrl
       - allwinner,suniv-f1c100s-pinctrl
       - nextthing,gr8-pinctrl
 
@@ -189,6 +191,7 @@ allOf:
             - allwinner,sun6i-a31-pinctrl
             - allwinner,sun6i-a31s-pinctrl
             - allwinner,sun50i-h6-pinctrl
+            - allwinner,sun50i-r329-pinctrl
 
     then:
       properties:
@@ -204,6 +207,7 @@ allOf:
             - allwinner,sun8i-a83t-pinctrl
             - allwinner,sun50i-a64-pinctrl
             - allwinner,sun50i-h5-pinctrl
+            - allwinner,sun50i-r329-r-pinctrl
             - allwinner,suniv-f1c100s-pinctrl
 
     then:
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:07 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:07 +0800
Subject: [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC compatible
 string
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-13-icenowy@sipeed.com>

R329 SoC has two MMC controllers similar to ones in the previous
Allwinner SoCs. However, as R329 has no eMMC controller, the two MMC
controllers look like a mixture of previous SoCs' ordinary MMC
controller and eMMC controller.

Add a compatible string for R329 MMC controllers.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 .../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml         | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
index 4f62ad6ce50c..3e8c3c747a9b 100644
--- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
+++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
@@ -28,6 +28,7 @@ properties:
       - const: allwinner,sun50i-a64-mmc
       - const: allwinner,sun50i-a100-emmc
       - const: allwinner,sun50i-a100-mmc
+      - const: allwinner,sun50i-r329-mmc
       - items:
           - const: allwinner,sun8i-a83t-mmc
           - const: allwinner,sun7i-a20-mmc
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:06 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:06 +0800
Subject: [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-12-icenowy@sipeed.com>

Allwinner R329 has a CCU that is similar to the H616 one, but it's cut
down and have PLLs moved out.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 drivers/clk/sunxi-ng/Kconfig                |   5 +
 drivers/clk/sunxi-ng/Makefile               |   1 +
 drivers/clk/sunxi-ng/ccu-sun50i-r329.c      | 526 ++++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329.h      |  32 ++
 include/dt-bindings/clock/sun50i-r329-ccu.h |  73 +++
 include/dt-bindings/reset/sun50i-r329-ccu.h |  45 ++
 6 files changed, 682 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
 create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
 create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index e49b2c2fa5b7..4b32d5f81ea8 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
+config SUN50I_R329_CCU
+	bool "Support for the Allwinner R329 CCU"
+	default ARM64 && ARCH_SUNXI
+	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+
 config SUN50I_R329_R_CCU
 	bool "Support for the Allwinner R329 PRCM CCU"
 	default ARM64 && ARCH_SUNXI
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index db338a2188fd..62f3c5bf331c 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
 obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
 obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
 obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
+obj-$(CONFIG_SUN50I_R329_CCU)	+= ccu-sun50i-r329.o
 obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
 obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
 obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
new file mode 100644
index 000000000000..a0b4cfd6e1db
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
@@ -0,0 +1,526 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Based on the H616 CCU driver, which is:
+ *   Copyright (c) 2020 Arm Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun50i-r329.h"
+
+/*
+ * An external divider of PLL-CPUX is controlled here. As it's similar to
+ * the external divider of PLL-CPUX on previous SoCs (only usable under
+ * 288MHz}, ignore it.
+ */
+static const char * const cpux_parents[] = { "osc24M", "osc32k", "iosc",
+					     "pll-cpux", "pll-periph",
+					     "pll-periph-2x",
+					     "pll=periph-800m" };
+static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
+		     0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
+static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
+
+static const char * const ahb_parents[] = { "osc24M", "osc32k",
+					    "iosc", "pll-periph" };
+static SUNXI_CCU_MP_WITH_MUX(ahb_clk, "ahb",
+			     ahb_parents, 0x510,
+			     0, 2,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static const char * const apb_parents[] = { "osc24M", "osc32k",
+					    "ahb", "pll-periph" };
+static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb_parents, 0x520,
+			     0, 2,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb_parents, 0x524,
+			     0, 2,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static const char * const ce_parents[] = { "osc24M", "pll-periph-2x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 1,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb",
+		      0x68c, BIT(0), 0);
+
+static const char * const aipu_parents[] = { "pll-periph-2x", "pll-periph-800m",
+					     "pll-audio0-div2", "pll-audio0-div5",
+					     "pll-cpux" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(aipu_clk, "aipu", aipu_parents, 0x6f0,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_aipu_clk, "bus-aipu", "ahb",
+		      0x6fc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb",
+		      0x70c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb",
+		      0x71c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb",
+		      0x72c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb",
+		      0x73c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x740, BIT(31), 0);
+
+static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb",
+		      0x78c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
+
+static const char * const dram_parents[] = { "pll-periph-2x",
+					     "pll-periph-800m",
+					     "pll-audio0-div2",
+					     "pll-audio0-div5" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(dram_clk, "dram", dram_parents, 0x800,
+				  0, 2,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  CLK_IS_CRITICAL);
+
+
+static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "dram",
+		      0x804, BIT(0), 0);
+static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "dram",
+		      0x804, BIT(2), 0);
+static SUNXI_CCU_GATE(mbus_r_dma_clk, "mbus-r-dma", "dram",
+		      0x804, BIT(3), 0);
+static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "dram",
+		      0x804, BIT(5), 0);
+static SUNXI_CCU_GATE(mbus_aipu_clk, "mbus-aipu", "dram",
+		      0x804, BIT(16), 0);
+
+static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb",
+		      0x80c, BIT(0), CLK_IS_CRITICAL);
+
+static const char * const nand_parents[] = { "osc24M", "pll-periph",
+					     "pll-audio-div2",
+					     "pll-periph-2x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_parents, 0x810,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_parents, 0x814,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb", 0x82c, BIT(0), 0);
+
+static const char * const mmc_parents[] = { "osc24M", "pll-periph",
+					    "pll-periph-2x",
+					    "pll-audio0-div2" };
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
+					  0, 4,		/* M */
+					  8, 2,		/* P */
+					  24, 2,	/* mux */
+					  BIT(31),	/* gate */
+					  2,		/* post-div */
+					  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
+					  0, 4,		/* M */
+					  8, 2,		/* P */
+					  24, 2,	/* mux */
+					  BIT(31),	/* gate */
+					  2,		/* post-div */
+					  0);
+
+static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb", 0x84c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb", 0x84c, BIT(1), 0);
+
+static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0);
+static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0);
+
+static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0);
+
+static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", 0x93c, BIT(0), 0);
+
+static const char * const spi_parents[] = { "osc24M", "pll-periph",
+					    "pll-periph-2x",
+					    "pll-audio0-div2",
+					    "pll-audio0-div5" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb", 0x96c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb", 0x96c, BIT(1), 0);
+
+static CLK_FIXED_FACTOR(emac_25m_div_clk, "emac-25m-div", "pll-periph",
+			2, 1, 0);
+static SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "emac-25m-div", 0x970,
+		      BIT(31) | BIT(30), 0);
+
+static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb", 0x97c, BIT(0), 0);
+
+static const char * const ir_parents[] = { "osc32k", "iosc",
+					   "pll-periph", "pll-audio0-div2" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents, 0x990,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "apb1", 0x99c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents, 0x9c0,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0);
+
+static const char * const audio_parents[] = { "pll-audio1",
+					      "pll-audio1-4x",
+					      "pll-audio0-div2",
+					      "pll-audio0-div5" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(i2s0_clk, "i2s0", audio_parents, 0xa10,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(i2s1_clk, "i2s1", audio_parents, 0xa14,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spdif_clk, "spdif", audio_parents, 0xa20,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0);
+
+/*
+ * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports.
+ * We will force them to 0 (12M divided from 48M).
+ */
+#define SUN50I_R329_USB0_CLK_REG		0xa70
+#define SUN50I_R329_USB1_CLK_REG		0xa74
+
+static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
+static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0xa70, BIT(29), 0);
+
+static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0xa74, BIT(29), 0);
+
+static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb", 0xa8c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb", 0xa8c, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb", 0xa8c, BIT(4), 0);
+static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb", 0xa8c, BIT(8), 0);
+
+static const char * const ledc_parents[] = { "osc24M", "pll-periph" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(ledc_clk, "ledc", ledc_parents, 0xbf0,
+				  0, 4,		/* M */
+				  8, 2,		/* P */
+				  24, 1,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "apb1", 0xbfc, BIT(0), 0);
+
+/* Fixed factor clocks */
+static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
+
+static struct ccu_common *sun50i_r329_ccu_clks[] = {
+	&cpux_clk.common,
+	&axi_clk.common,
+	&cpux_apb_clk.common,
+	&ahb_clk.common,
+	&apb1_clk.common,
+	&apb2_clk.common,
+	&ce_clk.common,
+	&bus_ce_clk.common,
+	&aipu_clk.common,
+	&bus_aipu_clk.common,
+	&bus_dma_clk.common,
+	&bus_msgbox_clk.common,
+	&bus_spinlock_clk.common,
+	&bus_hstimer_clk.common,
+	&avs_clk.common,
+	&bus_dbg_clk.common,
+	&bus_pwm_clk.common,
+	&dram_clk.common,
+	&mbus_dma_clk.common,
+	&mbus_ce_clk.common,
+	&mbus_r_dma_clk.common,
+	&mbus_nand_clk.common,
+	&mbus_aipu_clk.common,
+	&bus_dram_clk.common,
+	&nand0_clk.common,
+	&nand1_clk.common,
+	&bus_nand_clk.common,
+	&mmc0_clk.common,
+	&mmc1_clk.common,
+	&bus_mmc0_clk.common,
+	&bus_mmc1_clk.common,
+	&bus_uart0_clk.common,
+	&bus_uart1_clk.common,
+	&bus_uart2_clk.common,
+	&bus_uart3_clk.common,
+	&bus_i2c0_clk.common,
+	&bus_i2c1_clk.common,
+	&bus_scr_clk.common,
+	&spi0_clk.common,
+	&spi1_clk.common,
+	&bus_spi0_clk.common,
+	&bus_spi1_clk.common,
+	&emac_25m_clk.common,
+	&bus_emac_clk.common,
+	&ir_rx_clk.common,
+	&bus_ir_rx_clk.common,
+	&ir_tx_clk.common,
+	&bus_ir_tx_clk.common,
+	&i2s0_clk.common,
+	&i2s1_clk.common,
+	&bus_i2s0_clk.common,
+	&bus_i2s1_clk.common,
+	&spdif_clk.common,
+	&bus_spdif_clk.common,
+	&usb_ohci0_clk.common,
+	&usb_phy0_clk.common,
+	&usb_ohci1_clk.common,
+	&usb_phy1_clk.common,
+	&bus_ohci0_clk.common,
+	&bus_ohci1_clk.common,
+	&bus_ehci0_clk.common,
+	&bus_otg_clk.common,
+	&ledc_clk.common,
+	&bus_ledc_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_r329_hw_clks = {
+	.hws	= {
+		[CLK_OSC12M]		= &osc12M_clk.hw,
+		[CLK_CPUX]		= &cpux_clk.common.hw,
+		[CLK_AXI]		= &axi_clk.common.hw,
+		[CLK_CPUX_APB]		= &cpux_apb_clk.common.hw,
+		[CLK_AHB]		= &ahb_clk.common.hw,
+		[CLK_APB1]		= &apb1_clk.common.hw,
+		[CLK_APB2]		= &apb2_clk.common.hw,
+		[CLK_CE]		= &ce_clk.common.hw,
+		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
+		[CLK_AIPU]		= &aipu_clk.common.hw,
+		[CLK_BUS_AIPU]		= &bus_aipu_clk.common.hw,
+		[CLK_BUS_DMA]		= &bus_dma_clk.common.hw,
+		[CLK_BUS_MSGBOX]	= &bus_msgbox_clk.common.hw,
+		[CLK_BUS_SPINLOCK]	= &bus_spinlock_clk.common.hw,
+		[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
+		[CLK_BUS_PWM]		= &bus_pwm_clk.common.hw,
+		[CLK_DRAM]		= &dram_clk.common.hw,
+		[CLK_MBUS_DMA]		= &mbus_dma_clk.common.hw,
+		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
+		[CLK_MBUS_R_DMA]	= &mbus_r_dma_clk.common.hw,
+		[CLK_MBUS_NAND]		= &mbus_nand_clk.common.hw,
+		[CLK_MBUS_AIPU]		= &mbus_aipu_clk.common.hw,
+		[CLK_BUS_DRAM]		= &bus_dram_clk.common.hw,
+		[CLK_NAND0]		= &nand0_clk.common.hw,
+		[CLK_NAND1]		= &nand1_clk.common.hw,
+		[CLK_BUS_NAND]		= &bus_nand_clk.common.hw,
+		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
+		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
+		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
+		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
+		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
+		[CLK_BUS_UART3]		= &bus_uart3_clk.common.hw,
+		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
+		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
+		[CLK_BUS_SCR]		= &bus_scr_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_SPI1]		= &spi1_clk.common.hw,
+		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
+		[CLK_BUS_SPI1]		= &bus_spi1_clk.common.hw,
+		[CLK_EMAC_25M_DIV]	= &emac_25m_div_clk.hw,
+		[CLK_EMAC_25M]		= &emac_25m_clk.common.hw,
+		[CLK_BUS_EMAC]		= &bus_emac_clk.common.hw,
+		[CLK_IR_RX]		= &ir_rx_clk.common.hw,
+		[CLK_BUS_IR_RX]		= &bus_ir_rx_clk.common.hw,
+		[CLK_IR_TX]		= &ir_tx_clk.common.hw,
+		[CLK_BUS_IR_TX]		= &bus_ir_tx_clk.common.hw,
+		[CLK_I2S0]		= &i2s0_clk.common.hw,
+		[CLK_I2S1]		= &i2s1_clk.common.hw,
+		[CLK_BUS_I2S0]		= &bus_i2s0_clk.common.hw,
+		[CLK_BUS_I2S1]		= &bus_i2s1_clk.common.hw,
+		[CLK_SPDIF]		= &spdif_clk.common.hw,
+		[CLK_BUS_SPDIF]		= &bus_spdif_clk.common.hw,
+		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
+		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
+		[CLK_USB_OHCI1]		= &usb_ohci1_clk.common.hw,
+		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
+		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
+		[CLK_BUS_OHCI1]		= &bus_ohci1_clk.common.hw,
+		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
+		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
+		[CLK_LEDC]		= &ledc_clk.common.hw,
+		[CLK_BUS_LEDC]		= &bus_ledc_clk.common.hw,
+	},
+	.num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun50i_r329_ccu_resets[] = {
+	[RST_MBUS]		= { 0x540, BIT(30) },
+
+	[RST_BUS_CE]		= { 0x68c, BIT(16) },
+	[RST_BUS_AIPU]		= { 0x6fc, BIT(16) },
+	[RST_BUS_DMA]		= { 0x70c, BIT(16) },
+	[RST_BUS_MSGBOX]	= { 0x71c, BIT(16) },
+	[RST_BUS_SPINLOCK]	= { 0x72c, BIT(16) },
+	[RST_BUS_HSTIMER]	= { 0x73c, BIT(16) },
+	[RST_BUS_DBG]		= { 0x78c, BIT(16) },
+	[RST_BUS_PWM]		= { 0x7ac, BIT(16) },
+	[RST_BUS_DRAM]		= { 0x80c, BIT(16) },
+	[RST_BUS_NAND]		= { 0x82c, BIT(16) },
+	[RST_BUS_MMC0]		= { 0x84c, BIT(16) },
+	[RST_BUS_MMC1]		= { 0x84c, BIT(17) },
+	[RST_BUS_UART0]		= { 0x90c, BIT(16) },
+	[RST_BUS_UART1]		= { 0x90c, BIT(17) },
+	[RST_BUS_UART2]		= { 0x90c, BIT(18) },
+	[RST_BUS_UART3]		= { 0x90c, BIT(19) },
+	[RST_BUS_I2C0]		= { 0x91c, BIT(16) },
+	[RST_BUS_I2C1]		= { 0x91c, BIT(17) },
+	[RST_BUS_SCR]		= { 0x93c, BIT(16) },
+	[RST_BUS_SPI0]		= { 0x96c, BIT(16) },
+	[RST_BUS_SPI1]		= { 0x96c, BIT(17) },
+	[RST_BUS_EMAC]		= { 0x97c, BIT(16) },
+	[RST_BUS_IR_RX]		= { 0x99c, BIT(16) },
+	[RST_BUS_IR_TX]		= { 0x9cc, BIT(16) },
+	[RST_BUS_I2S0]		= { 0xa1c, BIT(16) },
+	[RST_BUS_I2S1]		= { 0xa1c, BIT(17) },
+	[RST_BUS_SPDIF]		= { 0xa2c, BIT(16) },
+
+	[RST_USB_PHY0]		= { 0xa70, BIT(30) },
+	[RST_USB_PHY1]		= { 0xa74, BIT(30) },
+
+	[RST_BUS_OHCI0]		= { 0xa8c, BIT(16) },
+	[RST_BUS_OHCI1]		= { 0xa8c, BIT(17) },
+	[RST_BUS_EHCI0]		= { 0xa8c, BIT(20) },
+	[RST_BUS_OTG]		= { 0xa8c, BIT(24) },
+
+	[RST_BUS_LEDC]		= { 0xbfc, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun50i_r329_ccu_desc = {
+	.ccu_clks	= sun50i_r329_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_ccu_clks),
+
+	.hw_clks	= &sun50i_r329_hw_clks,
+
+	.resets		= sun50i_r329_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun50i_r329_ccu_resets),
+};
+
+static const u32 sun50i_r329_usb_clk_regs[] = {
+	SUN50I_R329_USB0_CLK_REG,
+	SUN50I_R329_USB1_CLK_REG,
+};
+
+static int sun50i_r329_ccu_probe(struct platform_device *pdev)
+{
+	void __iomem *reg;
+	u32 val;
+	int i;
+
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
+
+	/*
+	 * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
+	 *
+	 * This clock mux is still mysterious, and the code just enforces
+	 * it to have a valid clock parent.
+	 */
+	for (i = 0; i < ARRAY_SIZE(sun50i_r329_usb_clk_regs); i++) {
+		val = readl(reg + sun50i_r329_usb_clk_regs[i]);
+		val &= ~GENMASK(25, 24);
+		writel(val, reg + sun50i_r329_usb_clk_regs[i]);
+	}
+
+	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_r329_ccu_desc);
+}
+
+static const struct of_device_id sun50i_r329_ccu_ids[] = {
+	{ .compatible = "allwinner,sun50i-r329-ccu" },
+	{ }
+};
+
+static struct platform_driver sun50i_r329_ccu_driver = {
+	.probe	= sun50i_r329_ccu_probe,
+	.driver	= {
+		.name	= "sun50i-r329-ccu",
+		.of_match_table	= sun50i_r329_ccu_ids,
+	},
+};
+module_platform_driver(sun50i_r329_ccu_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
new file mode 100644
index 000000000000..144ac9954ef3
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _CCU_SUN50I_R329_H_
+#define _CCU_SUN50I_R329_H_
+
+#include <dt-bindings/clock/sun50i-r329-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-ccu.h>
+
+#define CLK_OSC12M		0
+
+/* CPUX exported for DVFS */
+
+#define CLK_AXI			2
+#define CLK_CPUX_APB		3
+#define CLK_AHB			4
+
+/* APB1 exported for PIO */
+
+#define CLK_APB2		6
+
+/* Peripheral module and gate clock exported except for DRAM ones */
+
+#define CLK_DRAM		18
+
+#define CLK_BUS_DRAM		24
+
+#define CLK_NUMBER		(CLK_BUS_LEDC + 1)
+
+#endif /* _CCU_SUN50I_R329_H_ */
diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h b/include/dt-bindings/clock/sun50i-r329-ccu.h
new file mode 100644
index 000000000000..116f8d13a9b3
--- /dev/null
+++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
+#define _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
+
+#define CLK_CPUX		1
+
+#define CLK_APB1		5
+
+#define CLK_CE			7
+#define CLK_BUS_CE		8
+#define CLK_AIPU		9
+#define CLK_BUS_AIPU		10
+#define CLK_BUS_DMA		11
+#define CLK_BUS_MSGBOX		12
+#define CLK_BUS_SPINLOCK	13
+#define CLK_BUS_HSTIMER		14
+#define CLK_AVS			15
+#define CLK_BUS_DBG		16
+#define CLK_BUS_PWM		17
+
+#define CLK_MBUS_DMA		19
+#define CLK_MBUS_CE		20
+#define CLK_MBUS_R_DMA		21
+#define CLK_MBUS_NAND		22
+#define CLK_MBUS_AIPU		23
+
+#define CLK_NAND0		25
+#define CLK_NAND1		26
+#define CLK_BUS_NAND		27
+#define CLK_MMC0		28
+#define CLK_MMC1		29
+#define CLK_BUS_MMC0		30
+#define CLK_BUS_MMC1		31
+#define CLK_BUS_UART0		32
+#define CLK_BUS_UART1		33
+#define CLK_BUS_UART2		34
+#define CLK_BUS_UART3		35
+#define CLK_BUS_I2C0		36
+#define CLK_BUS_I2C1		37
+#define CLK_BUS_SCR		38
+#define CLK_SPI0		39
+#define CLK_SPI1		40
+#define CLK_BUS_SPI0		41
+#define CLK_BUS_SPI1		42
+#define CLK_EMAC_25M_DIV	43
+#define CLK_EMAC_25M		44
+#define CLK_BUS_EMAC		45
+#define CLK_IR_RX		46
+#define CLK_BUS_IR_RX		47
+#define CLK_IR_TX		48
+#define CLK_BUS_IR_TX		49
+#define CLK_I2S0		50
+#define CLK_I2S1		51
+#define CLK_BUS_I2S0		52
+#define CLK_BUS_I2S1		53
+#define CLK_SPDIF		54
+#define CLK_BUS_SPDIF		55
+#define CLK_USB_OHCI0		56
+#define CLK_USB_PHY0		57
+#define CLK_USB_OHCI1		58
+#define CLK_USB_PHY1		59
+#define CLK_BUS_OHCI0		60
+#define CLK_BUS_OHCI1		61
+#define CLK_BUS_EHCI0		62
+#define CLK_BUS_OTG		63
+#define CLK_LEDC		64
+#define CLK_BUS_LEDC		65
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-bindings/reset/sun50i-r329-ccu.h
new file mode 100644
index 000000000000..bb704a82443f
--- /dev/null
+++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
+#define _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
+
+#define RST_MBUS		0
+#define RST_BUS_CE		1
+#define RST_BUS_AIPU		2
+#define RST_BUS_DMA		3
+#define RST_BUS_MSGBOX		4
+#define RST_BUS_SPINLOCK	5
+#define RST_BUS_HSTIMER		6
+#define RST_BUS_DBG		7
+#define RST_BUS_PWM		8
+#define RST_BUS_DRAM		9
+#define RST_BUS_NAND		10
+#define RST_BUS_MMC0		11
+#define RST_BUS_MMC1		12
+#define RST_BUS_UART0		13
+#define RST_BUS_UART1		14
+#define RST_BUS_UART2		15
+#define RST_BUS_UART3		16
+#define RST_BUS_I2C0		17
+#define RST_BUS_I2C1		18
+#define RST_BUS_SCR		19
+#define RST_BUS_SPI0		20
+#define RST_BUS_SPI1		21
+#define RST_BUS_EMAC		22
+#define RST_BUS_IR_RX		23
+#define RST_BUS_IR_TX		24
+#define RST_BUS_I2S0		25
+#define RST_BUS_I2S1		26
+#define RST_BUS_SPDIF		27
+#define RST_USB_PHY0		28
+#define RST_USB_PHY1		29
+#define RST_BUS_OHCI0		30
+#define RST_BUS_OHCI1		31
+#define RST_BUS_EHCI0		32
+#define RST_BUS_OTG		33
+#define RST_BUS_LEDC		34
+
+#endif /* _DT_BINDINGS_RST_SUN50I_R329_CCU_H_ */
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:05 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:05 +0800
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-11-icenowy@sipeed.com>

Allwinner R329 has clock controls in PRCM, like other new Allwinner
SoCs.

Add support for them.

This driver is added before the main CCU because PLLs are controlled by
R-CCU on R329.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 drivers/clk/sunxi-ng/Kconfig                  |   5 +
 drivers/clk/sunxi-ng/Makefile                 |   1 +
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 ++++++++++++++++++
 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
 include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
 include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 ++
 6 files changed, 470 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
 create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
 create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index cd46d8853876..e49b2c2fa5b7 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
+config SUN50I_R329_R_CCU
+	bool "Support for the Allwinner R329 PRCM CCU"
+	default ARM64 && ARCH_SUNXI
+	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+
 config SUN4I_A10_CCU
 	bool "Support for the Allwinner A10/A20 CCU"
 	default MACH_SUN4I
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 96c324306d97..db338a2188fd 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
 obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
 obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
 obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
+obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
 obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
 obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
 obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
new file mode 100644
index 000000000000..5413a701cb57
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Sipeed
+ * Based on the H616 CCU driver, which is:
+ *   Copyright (c) 2020 Arm Ltd.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+
+#include "ccu-sun50i-r329-r.h"
+
+/*
+ * The M factor is present in the register's description, but not in the
+ * frequency formula, and it's documented as "The bit is only for
+ * testing", so it's not modelled and then force to 0.
+ */
+#define SUN50I_R329_PLL_CPUX_REG	0x1000
+static struct ccu_mult pll_cpux_clk = {
+	.enable		= BIT(31),
+	.lock		= BIT(28),
+	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
+	.common		= {
+		.reg		= 0x1000,
+		.hw.init	= CLK_HW_INIT("pll-cpux", "osc24M",
+					      &ccu_mult_ops,
+					      CLK_SET_RATE_UNGATE),
+	},
+};
+
+#define SUN50I_R329_PLL_PERIPH_REG	0x1010
+static struct ccu_nm pll_periph_base_clk = {
+	.enable		= BIT(31),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
+	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
+	.common		= {
+		.reg		= 0x1010,
+		.hw.init	= CLK_HW_INIT("pll-periph-base", "osc24M",
+					      &ccu_nm_ops,
+					      CLK_SET_RATE_UNGATE),
+	},
+};
+
+static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-base",
+		   0x1010, 16, 3, 0);
+static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m", "pll-periph-base",
+		   0x1010, 20, 3, 0);
+static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
+			   &pll_periph_2x_clk.common.hw, 2, 1, 0);
+
+#define SUN50I_R329_PLL_AUDIO0_REG	0x1020
+static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
+	{ .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64 },
+};
+
+static struct ccu_nm pll_audio0_clk = {
+	.enable		= BIT(31),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
+	.m		= _SUNXI_CCU_DIV(1, 1),
+	.sdm		= _SUNXI_CCU_SDM(pll_audio0_sdm_table,
+					 BIT(24), 0x1120, BIT(31)),
+	.common		= {
+		.features	= CCU_FEATURE_SIGMA_DELTA_MOD,
+		.reg		= 0x1020,
+		.hw.init	= CLK_HW_INIT("pll-audio0", "osc24M",
+					      &ccu_nm_ops,
+					      CLK_SET_RATE_UNGATE),
+	},
+};
+
+static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-audio0",
+		   0x1020, 16, 3, 0);
+static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-audio0",
+		   0x1020, 20, 3, 0);
+
+/*
+ * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
+ * BSP driver always has M0 = 1 and M1 = 2 (this is also the
+ * reset value in the register).
+ *
+ * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
+ */
+#define SUN50I_R329_PLL_AUDIO1_REG	0x1030
+static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
+	{ .rate = 22579200, .pattern = 0xc001288d, .m = 12, .n = 22 },
+	{ .rate = 24576000, .pattern = 0xc00126e9, .m = 12, .n = 24 },
+	{ .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 },
+	{ .rate = 98304000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
+};
+static struct ccu_nm pll_audio1_4x_clk = {
+	.enable		= BIT(31),
+	.lock		= BIT(28),
+	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
+	.m		= _SUNXI_CCU_DIV(16, 6),
+	.fixed_post_div	= 2,
+	.sdm		= _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
+					 BIT(24), 0x1130, BIT(31)),
+	.common		= {
+		.features	= CCU_FEATURE_FIXED_POSTDIV |
+				  CCU_FEATURE_SIGMA_DELTA_MOD,
+		.reg		= 0x1030,
+		.hw.init	= CLK_HW_INIT("pll-audio1-4x", "osc24M",
+					      &ccu_nm_ops,
+					      CLK_SET_RATE_UNGATE),
+	},
+};
+
+static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
+			   &pll_audio1_4x_clk.common.hw, 2, 1,
+			   CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
+			   &pll_audio1_4x_clk.common.hw, 4, 1,
+			   CLK_SET_RATE_PARENT);
+
+static const char * const r_bus_parents[] = { "osc24M", "osc32k", "iosc",
+					      "pll-periph-2x",
+					      "pll-audio0-div2" };
+static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents, 0x000,
+			     0, 5,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static SUNXI_CCU_MP_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents, 0x00c,
+			     0, 5,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static SUNXI_CCU_MP_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents, 0x010,
+			     0, 5,	/* M */
+			     8, 2,	/* P */
+			     24, 3,	/* mux */
+			     0);
+
+static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
+		      0x0ec, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc, BIT(0), 0);
+
+static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c, BIT(0), 0);
+
+static const char * const r_pwm_parents[] = { "osc24M", "osc32k", "iosc" };
+static SUNXI_CCU_MUX_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents, 0x130,
+			       24, 3,	/* mux */
+			       BIT(31),	/* gate */
+			       0);
+
+static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c, BIT(0), 0);
+
+static const char * const r_audio_parents[] = { "pll-audio0-div5", "pll-audio0-div2",
+						"pll-audio1-1x", "pll-audio1-4x" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc", r_audio_parents, 0x140,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac", r_audio_parents, 0x144,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
+		      0x14c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic", r_audio_parents, 0x150,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc", "r-apb1",
+		      0x16c, BIT(0), 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s", r_audio_parents, 0x170,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
+				  r_audio_parents, 0x174,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart", "r-apb2", 0x18c, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_i2c_clk, "r-bus-i2c", "r-apb2", 0x19c, BIT(0), 0);
+
+static const char * const r_ir_parents[] = { "osc32k", "osc24M" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents, 0x1c0,
+				  0, 5,		/* M */
+				  8, 2,		/* P */
+				  24, 3,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
+		      0x1dc, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-apb1",
+		      0x1ec, BIT(0), 0);
+static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
+		      0x20c, BIT(0), CLK_IS_CRITICAL);
+
+static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
+	&pll_cpux_clk.common,
+	&pll_periph_base_clk.common,
+	&pll_periph_2x_clk.common,
+	&pll_periph_800m_clk.common,
+	&pll_audio0_clk.common,
+	&pll_audio0_div2_clk.common,
+	&pll_audio0_div5_clk.common,
+	&pll_audio1_4x_clk.common,
+	&r_ahb_clk.common,
+	&r_apb1_clk.common,
+	&r_apb2_clk.common,
+	&r_bus_gpadc_clk.common,
+	&r_bus_ths_clk.common,
+	&r_bus_dma_clk.common,
+	&r_pwm_clk.common,
+	&r_bus_pwm_clk.common,
+	&r_codec_adc_clk.common,
+	&r_codec_dac_clk.common,
+	&r_bus_codec_clk.common,
+	&r_dmic_clk.common,
+	&r_bus_dmic_clk.common,
+	&r_bus_lradc_clk.common,
+	&r_i2s_clk.common,
+	&r_i2s_asrc_clk.common,
+	&r_bus_i2s_clk.common,
+	&r_bus_uart_clk.common,
+	&r_bus_i2c_clk.common,
+	&r_ir_clk.common,
+	&r_bus_ir_clk.common,
+	&r_bus_msgbox_clk.common,
+	&r_bus_spinlock_clk.common,
+	&r_bus_rtc_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
+	.hws	= {
+		[CLK_PLL_CPUX]		= &pll_cpux_clk.common.hw,
+		[CLK_PLL_PERIPH_BASE]	= &pll_periph_base_clk.common.hw,
+		[CLK_PLL_PERIPH_2X]	= &pll_periph_2x_clk.common.hw,
+		[CLK_PLL_PERIPH_800M]	= &pll_periph_800m_clk.common.hw,
+		[CLK_PLL_PERIPH]	= &pll_periph_clk.hw,
+		[CLK_PLL_AUDIO0]	= &pll_audio0_clk.common.hw,
+		[CLK_PLL_AUDIO0_DIV2]	= &pll_audio0_div2_clk.common.hw,
+		[CLK_PLL_AUDIO0_DIV5]	= &pll_audio0_div5_clk.common.hw,
+		[CLK_PLL_AUDIO1_4X]	= &pll_audio1_4x_clk.common.hw,
+		[CLK_PLL_AUDIO1_2X]	= &pll_audio1_2x_clk.hw,
+		[CLK_PLL_AUDIO1]	= &pll_audio1_clk.hw,
+		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
+		[CLK_R_APB1]		= &r_apb1_clk.common.hw,
+		[CLK_R_APB2]		= &r_apb2_clk.common.hw,
+		[CLK_R_BUS_GPADC]	= &r_bus_gpadc_clk.common.hw,
+		[CLK_R_BUS_THS]		= &r_bus_ths_clk.common.hw,
+		[CLK_R_BUS_DMA]		= &r_bus_dma_clk.common.hw,
+		[CLK_R_PWM]		= &r_pwm_clk.common.hw,
+		[CLK_R_BUS_PWM]		= &r_bus_pwm_clk.common.hw,
+		[CLK_R_CODEC_ADC]	= &r_codec_adc_clk.common.hw,
+		[CLK_R_CODEC_DAC]	= &r_codec_dac_clk.common.hw,
+		[CLK_R_BUS_CODEC]	= &r_bus_codec_clk.common.hw,
+		[CLK_R_DMIC]		= &r_dmic_clk.common.hw,
+		[CLK_R_BUS_DMIC]	= &r_bus_dmic_clk.common.hw,
+		[CLK_R_BUS_LRADC]	= &r_bus_lradc_clk.common.hw,
+		[CLK_R_I2S]		= &r_i2s_clk.common.hw,
+		[CLK_R_I2S_ASRC]	= &r_i2s_asrc_clk.common.hw,
+		[CLK_R_BUS_I2S]		= &r_bus_i2s_clk.common.hw,
+		[CLK_R_BUS_UART]	= &r_bus_uart_clk.common.hw,
+		[CLK_R_BUS_I2C]		= &r_bus_i2c_clk.common.hw,
+		[CLK_R_IR]		= &r_ir_clk.common.hw,
+		[CLK_R_BUS_IR]		= &r_bus_ir_clk.common.hw,
+		[CLK_R_BUS_MSGBOX]	= &r_bus_msgbox_clk.common.hw,
+		[CLK_R_BUS_SPINLOCK]	= &r_bus_spinlock_clk.common.hw,
+		[CLK_R_BUS_RTC]		= &r_bus_rtc_clk.common.hw,
+	},
+	.num = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
+	[RST_R_BUS_GPADC]	= { 0x0ec, BIT(16) },
+	[RST_R_BUS_THS]		= { 0x0fc, BIT(16) },
+	[RST_R_BUS_DMA]		= { 0x10c, BIT(16) },
+	[RST_R_BUS_PWM]		= { 0x13c, BIT(16) },
+	[RST_R_BUS_CODEC]	= { 0x14c, BIT(16) },
+	[RST_R_BUS_DMIC]	= { 0x15c, BIT(16) },
+	[RST_R_BUS_LRADC]	= { 0x16c, BIT(16) },
+	[RST_R_BUS_I2S]		= { 0x17c, BIT(16) },
+	[RST_R_BUS_UART]	= { 0x18c, BIT(16) },
+	[RST_R_BUS_I2C]		= { 0x19c, BIT(16) },
+	[RST_R_BUS_IR]		= { 0x1cc, BIT(16) },
+	[RST_R_BUS_MSGBOX]	= { 0x1dc, BIT(16) },
+	[RST_R_BUS_SPINLOCK]	= { 0x1ec, BIT(16) },
+	[RST_R_BUS_RTC]		= { 0x20c, BIT(16) },
+};
+
+static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
+	.ccu_clks	= sun50i_r329_r_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_r_ccu_clks),
+
+	.hw_clks	= &sun50i_r329_r_hw_clks,
+
+	.resets		= sun50i_r329_r_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun50i_r329_r_ccu_resets),
+};
+
+static const u32 pll_regs[] = {
+	SUN50I_R329_PLL_CPUX_REG,
+	SUN50I_R329_PLL_PERIPH_REG,
+	SUN50I_R329_PLL_AUDIO0_REG,
+	SUN50I_R329_PLL_AUDIO1_REG,
+};
+
+static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
+{
+	void __iomem *reg;
+	u32 val;
+	int i;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("%pOF: Could not map clock registers\n", node);
+		return;
+	}
+
+	/* Enable the lock bits and the output enable bits on all PLLs */
+	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
+		val = readl(reg + pll_regs[i]);
+		val |= BIT(29) | BIT(27);
+		writel(val, reg + pll_regs[i]);
+	}
+
+	/*
+	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
+	 *
+	 * See the comment before pll-audio1 definition for the reason.
+	 */
+
+	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
+	val &= ~BIT(1);
+	val |= BIT(0);
+	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
+
+	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
+	if (i)
+		pr_err("%pOF: probing clocks fails: %d\n", node, i);
+}
+
+CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
+	       sun50i_r329_r_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
new file mode 100644
index 000000000000..62cf65322116
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _CCU_SUN50I_R329_R_H
+#define _CCU_SUN50I_R329_R_H
+
+#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
+#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
+
+#define CLK_PLL_CPUX		0
+#define CLK_PLL_PERIPH_BASE	1
+#define CLK_PLL_PERIPH_2X	2
+#define CLK_PLL_PERIPH_800M	3
+#define CLK_PLL_PERIPH		4
+#define CLK_PLL_AUDIO0		5
+#define CLK_PLL_AUDIO0_DIV2	6
+#define CLK_PLL_AUDIO0_DIV5	7
+#define CLK_PLL_AUDIO1_4X	8
+#define CLK_PLL_AUDIO1_2X	9
+#define CLK_PLL_AUDIO1		10
+#define CLK_R_AHB		11
+
+/* R_APB1 exported for PIO */
+
+#define CLK_R_APB2		13
+
+/* All module / bus gate clocks exported */
+
+#define CLK_NUMBER	(CLK_R_BUS_RTC + 1)
+
+#endif /* _CCU_SUN50I_R329_R_H */
diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
new file mode 100644
index 000000000000..df9bc58de5c4
--- /dev/null
+++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
+#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
+
+#define CLK_R_APB1		12
+
+#define CLK_R_BUS_GPADC		14
+#define CLK_R_BUS_THS		15
+#define CLK_R_BUS_DMA		16
+#define CLK_R_PWM		17
+#define CLK_R_BUS_PWM		18
+#define CLK_R_CODEC_ADC		19
+#define CLK_R_CODEC_DAC		20
+#define CLK_R_BUS_CODEC		21
+#define CLK_R_DMIC		22
+#define CLK_R_BUS_DMIC		23
+#define CLK_R_BUS_LRADC		24
+#define CLK_R_I2S		25
+#define CLK_R_I2S_ASRC		26
+#define CLK_R_BUS_I2S		27
+#define CLK_R_BUS_UART		28
+#define CLK_R_BUS_I2C		29
+#define CLK_R_IR		30
+#define CLK_R_BUS_IR		31
+#define CLK_R_BUS_MSGBOX	32
+#define CLK_R_BUS_SPINLOCK	33
+#define CLK_R_BUS_RTC		34
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
new file mode 100644
index 000000000000..40644f2f21c6
--- /dev/null
+++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2021 Sipeed
+ */
+
+#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
+#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
+
+#define RST_R_BUS_GPADC		0
+#define RST_R_BUS_THS		1
+#define RST_R_BUS_DMA		2
+#define RST_R_BUS_PWM		3
+#define RST_R_BUS_CODEC		4
+#define RST_R_BUS_DMIC		5
+#define RST_R_BUS_LRADC		6
+#define RST_R_BUS_I2S		7
+#define RST_R_BUS_UART		8
+#define RST_R_BUS_I2C		9
+#define RST_R_BUS_IR		10
+#define RST_R_BUS_MSGBOX	11
+#define RST_R_BUS_SPINLOCK	12
+#define RST_R_BUS_RTC		13
+
+#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:11 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:11 +0800
Subject: [PATCH 16/17] arm64: allwinner: dts: r329: add DTSI file for Sipeed
 Maix IIA
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-17-icenowy@sipeed.com>

Sipeed Maix IIA is a R329-N4 (AIPU available and 256MiB DRAM) based SoM,
with a Realtek SDIO Wi-Fi module on it.

Add a DTSI file for it.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 .../dts/allwinner/sun50i-r329-maix-iia.dtsi   | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
new file mode 100644
index 000000000000..15774f8a5445
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-r329-maix-iia.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2021 Sipeed
+
+#include "sun50i-r329.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	reg_vcc3v3: vcc3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&r_pio 1 0 GPIO_ACTIVE_LOW>; /* PM0 */
+		post-power-on-delay-ms = <200>;
+	};
+};
+
+&mmc1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc1_clk_pg0>, <&mmc1_cmd_pg1>, <&mmc1_d0_pg2>,
+		    <&mmc1_d1_pg3>, <&mmc1_d2_pg4>, <&mmc1_d3_pg5>;
+
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	bus-width = <4>;
+	non-removable;
+	status = "okay";
+};
-- 
2.30.2



From icenowy at sipeed.com  Sun Aug  1 23:22:12 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon,  2 Aug 2021 14:22:12 +0800
Subject: [PATCH 17/17] arm64: allwinner: dts: r329: add support for Sipeed
 MaixSense
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <20210802062212.73220-18-icenowy@sipeed.com>

Sipeed MaixSense is a R329 devkit based on Maix IIA SoM.

Add support for it.

Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
---
 arch/arm64/boot/dts/allwinner/Makefile        |  1 +
 .../dts/allwinner/sun50i-r329-maixsense.dts   | 37 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts

diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index a96d9d2d8dd8..80a336d480ac 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -37,3 +37,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-model-b.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-r329-maixsense.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts b/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
new file mode 100644
index 000000000000..1876b9d0b080
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-r329-maixsense.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2021 Sipeed
+
+/dts-v1/;
+
+#include "sun50i-r329-maix-iia.dtsi"
+
+/ {
+	model = "Sipeed MaixSense";
+	compatible = "sipeed,maixsense", "sipeed,maix-iia",
+		     "allwinner,sun50i-r329";
+
+	aliases {
+		serial0 = &uart0;
+		mmc0 = &mmc0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pf_pins>;
+
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pb_pins>;
+	status = "okay";
+};
-- 
2.30.2



From rppt at kernel.org  Sun Aug  1 23:37:37 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Mon,  2 Aug 2021 09:37:37 +0300
Subject: [PATCH v2] memblock: make memblock_find_in_range method private
Message-ID: <20210802063737.22733-1-rppt@kernel.org>

From: Mike Rapoport <rppt at linux.ibm.com>

There are a lot of uses of memblock_find_in_range() along with
memblock_reserve() from the times memblock allocation APIs did not exist.

memblock_find_in_range() is the very core of memblock allocations, so any
future changes to its internal behaviour would mandate updates of all the
users outside memblock.

Replace the calls to memblock_find_in_range() with an equivalent calls to
memblock_phys_alloc() and memblock_phys_alloc_range() and make
memblock_find_in_range() private method of memblock.

This simplifies the callers, ensures that (unlikely) errors in
memblock_reserve() are handled and improves maintainability of
memblock_find_in_range().

Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
---
v2: don't change error message in arm::reserve_crashkernel(), per Russell
v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org

 arch/arm/kernel/setup.c           | 18 +++++--------
 arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
 arch/arm64/mm/init.c              | 36 ++++++++-----------------
 arch/mips/kernel/setup.c          | 14 +++++-----
 arch/riscv/mm/init.c              | 44 ++++++++++---------------------
 arch/s390/kernel/setup.c          | 10 ++++---
 arch/x86/kernel/aperture_64.c     |  5 ++--
 arch/x86/mm/init.c                | 21 +++++++++------
 arch/x86/mm/numa.c                |  5 ++--
 arch/x86/mm/numa_emulation.c      |  5 ++--
 arch/x86/realmode/init.c          |  2 +-
 drivers/acpi/tables.c             |  5 ++--
 drivers/base/arch_numa.c          |  5 +---
 drivers/of/of_reserved_mem.c      | 12 ++++++---
 include/linux/memblock.h          |  2 --
 mm/memblock.c                     |  2 +-
 16 files changed, 78 insertions(+), 117 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index f97eb2371672..67f5421b2af7 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
 		unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
 		if (crash_max > lowmem_max)
 			crash_max = lowmem_max;
-		crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
-						    crash_size, CRASH_ALIGN);
+
+		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+						       CRASH_ALIGN, crash_max);
 		if (!crash_base) {
 			pr_err("crashkernel reservation failed - No suitable area found.\n");
 			return;
 		}
 	} else {
+		unsigned long long crash_max = crash_base + crash_size;
 		unsigned long long start;
 
-		start = memblock_find_in_range(crash_base,
-					       crash_base + crash_size,
-					       crash_size, SECTION_SIZE);
+		start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
+						  crash_base, crash_max);
 		if (start != crash_base) {
 			pr_err("crashkernel reservation failed - memory is in use.\n");
 			return;
 		}
 	}
 
-	ret = memblock_reserve(crash_base, crash_size);
-	if (ret < 0) {
-		pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
-			(unsigned long)crash_base);
-		return;
-	}
-
 	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
 		(unsigned long)(crash_size >> 20),
 		(unsigned long)(crash_base >> 20),
diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c
index d654921dd09b..578670e3f608 100644
--- a/arch/arm64/kvm/hyp/reserved_mem.c
+++ b/arch/arm64/kvm/hyp/reserved_mem.c
@@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
 	 * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
 	 */
 	hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
-	hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
-					      ALIGN(hyp_mem_size, PMD_SIZE),
-					      PMD_SIZE);
+	hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
+					   PMD_SIZE);
 	if (!hyp_mem_base)
-		hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
-						      hyp_mem_size, PAGE_SIZE);
+		hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
 	else
 		hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
 
@@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
 		kvm_err("Failed to reserve hyp memory\n");
 		return;
 	}
-	memblock_reserve(hyp_mem_base, hyp_mem_size);
 
 	kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
 		 hyp_mem_base);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2917ff..d566478a06dd 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
 	unsigned long long crash_base, crash_size;
+	unsigned long crash_max = arm64_dma_phys_limit;
 	int ret;
 
 	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
@@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
 
 	crash_size = PAGE_ALIGN(crash_size);
 
-	if (crash_base == 0) {
-		/* Current arm64 boot protocol requires 2MB alignment */
-		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
-				crash_size, SZ_2M);
-		if (crash_base == 0) {
-			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
-				crash_size);
-			return;
-		}
-	} else {
-		/* User specifies base address explicitly. */
-		if (!memblock_is_region_memory(crash_base, crash_size)) {
-			pr_warn("cannot reserve crashkernel: region is not memory\n");
-			return;
-		}
+	/* User specifies base address explicitly. */
+	if (crash_base)
+		crash_max = crash_base + crash_size;
 
-		if (memblock_is_region_reserved(crash_base, crash_size)) {
-			pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
-			return;
-		}
-
-		if (!IS_ALIGNED(crash_base, SZ_2M)) {
-			pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
-			return;
-		}
+	/* Current arm64 boot protocol requires 2MB alignment */
+	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
+					       crash_base, crash_max);
+	if (!crash_base) {
+		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
+			crash_size);
+		return;
 	}
-	memblock_reserve(crash_base, crash_size);
 
 	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 23a140327a0b..f979adfd4fc2 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -452,8 +452,9 @@ static void __init mips_parse_crashkernel(void)
 		return;
 
 	if (crash_base <= 0) {
-		crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX,
-							crash_size, CRASH_ALIGN);
+		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+						       CRASH_ALIGN,
+						       CRASH_ADDR_MAX);
 		if (!crash_base) {
 			pr_warn("crashkernel reservation failed - No suitable area found.\n");
 			return;
@@ -461,8 +462,9 @@ static void __init mips_parse_crashkernel(void)
 	} else {
 		unsigned long long start;
 
-		start = memblock_find_in_range(crash_base, crash_base + crash_size,
-						crash_size, 1);
+		start = memblock_phys_alloc_range(crash_size, 1,
+						  crash_base,
+						  crash_base + crash_size);
 		if (start != crash_base) {
 			pr_warn("Invalid memory region reserved for crash kernel\n");
 			return;
@@ -656,10 +658,6 @@ static void __init arch_mem_init(char **cmdline_p)
 	mips_reserve_vmcore();
 
 	mips_parse_crashkernel();
-#ifdef CONFIG_KEXEC
-	if (crashk_res.start != crashk_res.end)
-		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
-#endif
 	device_tree_init();
 
 	/*
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index a14bf3910eec..88649337c568 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -812,38 +812,22 @@ static void __init reserve_crashkernel(void)
 
 	crash_size = PAGE_ALIGN(crash_size);
 
-	if (crash_base == 0) {
-		/*
-		 * Current riscv boot protocol requires 2MB alignment for
-		 * RV64 and 4MB alignment for RV32 (hugepage size)
-		 */
-		crash_base = memblock_find_in_range(search_start, search_end,
-						    crash_size, PMD_SIZE);
-
-		if (crash_base == 0) {
-			pr_warn("crashkernel: couldn't allocate %lldKB\n",
-				crash_size >> 10);
-			return;
-		}
-	} else {
-		/* User specifies base address explicitly. */
-		if (!memblock_is_region_memory(crash_base, crash_size)) {
-			pr_warn("crashkernel: requested region is not memory\n");
-			return;
-		}
-
-		if (memblock_is_region_reserved(crash_base, crash_size)) {
-			pr_warn("crashkernel: requested region is reserved\n");
-			return;
-		}
-
+	if (crash_base) {
+		search_start = crash_base;
+		search_end = crash_base + crash_size;
+	}
 
-		if (!IS_ALIGNED(crash_base, PMD_SIZE)) {
-			pr_warn("crashkernel: requested region is misaligned\n");
-			return;
-		}
+	/*
+	 * Current riscv boot protocol requires 2MB alignment for
+	 * RV64 and 4MB alignment for RV32 (hugepage size)
+	 */
+	crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
+					       search_start, search_end);
+	if (crash_base == 0) {
+		pr_warn("crashkernel: couldn't allocate %lldKB\n",
+			crash_size >> 10);
+		return;
 	}
-	memblock_reserve(crash_base, crash_size);
 
 	pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index ff0f9e838916..3d9efee0f43c 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -626,8 +626,9 @@ static void __init reserve_crashkernel(void)
 			return;
 		}
 		low = crash_base ?: low;
-		crash_base = memblock_find_in_range(low, high, crash_size,
-						    KEXEC_CRASH_MEM_ALIGN);
+		crash_base = memblock_phys_alloc_range(crash_size,
+						       KEXEC_CRASH_MEM_ALIGN,
+						       low, high);
 	}
 
 	if (!crash_base) {
@@ -636,14 +637,15 @@ static void __init reserve_crashkernel(void)
 		return;
 	}
 
-	if (register_memory_notifier(&kdump_mem_nb))
+	if (register_memory_notifier(&kdump_mem_nb)) {
+		memblock_free(crash_base, crash_size);
 		return;
+	}
 
 	if (!OLDMEM_BASE && MACHINE_IS_VM)
 		diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
 	crashk_res.start = crash_base;
 	crashk_res.end = crash_base + crash_size - 1;
-	memblock_remove(crash_base, crash_size);
 	pr_info("Reserving %lluMB of memory at %lluMB "
 		"for crashkernel (System RAM: %luMB)\n",
 		crash_size >> 20, crash_base >> 20,
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 294ed4392a0e..10562885f5fc 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -109,14 +109,13 @@ static u32 __init allocate_aperture(void)
 	 * memory. Unfortunately we cannot move it up because that would
 	 * make the IOMMU useless.
 	 */
-	addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR,
-				      aper_size, aper_size);
+	addr = memblock_phys_alloc_range(aper_size, aper_size,
+					 GART_MIN_ADDR, GART_MAX_ADDR);
 	if (!addr) {
 		pr_err("Cannot allocate aperture memory hole [mem %#010lx-%#010lx] (%uKB)\n",
 		       addr, addr + aper_size - 1, aper_size >> 10);
 		return 0;
 	}
-	memblock_reserve(addr, aper_size);
 	pr_info("Mapping aperture over RAM [mem %#010lx-%#010lx] (%uKB)\n",
 		addr, addr + aper_size - 1, aper_size >> 10);
 	register_nosave_region(addr >> PAGE_SHIFT,
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 75ef19aa8903..1152a29ce109 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -26,6 +26,7 @@
 #include <asm/pti.h>
 #include <asm/text-patching.h>
 #include <asm/memtype.h>
+#include <xen/xen.h>
 
 /*
  * We need to define the tracepoints somewhere, and tlb.c
@@ -127,14 +128,12 @@ __ref void *alloc_low_pages(unsigned int num)
 		unsigned long ret = 0;
 
 		if (min_pfn_mapped < max_pfn_mapped) {
-			ret = memblock_find_in_range(
+			ret = memblock_phys_alloc_range(
+					PAGE_SIZE * num, PAGE_SIZE,
 					min_pfn_mapped << PAGE_SHIFT,
-					max_pfn_mapped << PAGE_SHIFT,
-					PAGE_SIZE * num , PAGE_SIZE);
+					max_pfn_mapped << PAGE_SHIFT);
 		}
-		if (ret)
-			memblock_reserve(ret, PAGE_SIZE * num);
-		else if (can_use_brk_pgt)
+		if (!ret && can_use_brk_pgt)
 			ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE));
 
 		if (!ret)
@@ -610,9 +609,15 @@ static void __init memory_map_top_down(unsigned long map_start,
 	unsigned long addr;
 	unsigned long mapped_ram_size = 0;
 
+	real_end = ALIGN_DOWN(map_end, PMD_SIZE);
+
 	/* xen has big range in reserved near end of ram, skip it at first.*/
-	addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE);
-	real_end = addr + PMD_SIZE;
+	if (xen_domain()) {
+		addr = memblock_phys_alloc_range(PMD_SIZE, PMD_SIZE,
+						 map_start, map_end);
+		memblock_free(addr, PMD_SIZE);
+		real_end = addr + PMD_SIZE;
+	}
 
 	/* step_size need to be small so pgt_buf from BRK could cover it */
 	step_size = PMD_SIZE;
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index e94da744386f..a1b5c71099e6 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -376,15 +376,14 @@ static int __init numa_alloc_distance(void)
 	cnt++;
 	size = cnt * cnt * sizeof(numa_distance[0]);
 
-	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
-				      size, PAGE_SIZE);
+	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0,
+					 PFN_PHYS(max_pfn_mapped));
 	if (!phys) {
 		pr_warn("Warning: can't allocate distance table!\n");
 		/* don't retry until explicitly reset */
 		numa_distance = (void *)1LU;
 		return -ENOMEM;
 	}
-	memblock_reserve(phys, size);
 
 	numa_distance = __va(phys);
 	numa_distance_cnt = cnt;
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
index 87d77cc52f86..737491b13728 100644
--- a/arch/x86/mm/numa_emulation.c
+++ b/arch/x86/mm/numa_emulation.c
@@ -447,13 +447,12 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
 	if (numa_dist_cnt) {
 		u64 phys;
 
-		phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
-					      phys_size, PAGE_SIZE);
+		phys = memblock_phys_alloc_range(phys_size, PAGE_SIZE, 0,
+						 PFN_PHYS(max_pfn_mapped));
 		if (!phys) {
 			pr_warn("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
 			goto no_emu;
 		}
-		memblock_reserve(phys, phys_size);
 		phys_dist = __va(phys);
 
 		for (i = 0; i < numa_dist_cnt; i++)
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 6534c92d0f83..31b5856010cb 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -28,7 +28,7 @@ void __init reserve_real_mode(void)
 	WARN_ON(slab_is_available());
 
 	/* Has to be under 1M so we can execute real-mode AP code. */
-	mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
+	mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
 	if (!mem)
 		pr_info("No sub-1M memory is available for the trampoline\n");
 	else
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index a37a1532a575..f9383736fa0f 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -583,8 +583,8 @@ void __init acpi_table_upgrade(void)
 	}
 
 	acpi_tables_addr =
-		memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
-				       all_tables_size, PAGE_SIZE);
+		memblock_phys_alloc_range(all_tables_size, PAGE_SIZE,
+					  0, ACPI_TABLE_UPGRADE_MAX_PHYS);
 	if (!acpi_tables_addr) {
 		WARN_ON(1);
 		return;
@@ -599,7 +599,6 @@ void __init acpi_table_upgrade(void)
 	 * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
 	 * works fine.
 	 */
-	memblock_reserve(acpi_tables_addr, all_tables_size);
 	arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
 
 	/*
diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index 4cc4e117727d..46c503486e96 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -279,13 +279,10 @@ static int __init numa_alloc_distance(void)
 	int i, j;
 
 	size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
-	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
-				      size, PAGE_SIZE);
+	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, PFN_PHYS(max_pfn));
 	if (WARN_ON(!phys))
 		return -ENOMEM;
 
-	memblock_reserve(phys, size);
-
 	numa_distance = __va(phys);
 	numa_distance_cnt = nr_node_ids;
 
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index fd3964d24224..59c1390cdf42 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -33,18 +33,22 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
 	phys_addr_t *res_base)
 {
 	phys_addr_t base;
+	int err = 0;
 
 	end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
 	align = !align ? SMP_CACHE_BYTES : align;
-	base = memblock_find_in_range(start, end, size, align);
+	base = memblock_phys_alloc_range(size, align, start, end);
 	if (!base)
 		return -ENOMEM;
 
 	*res_base = base;
-	if (nomap)
-		return memblock_mark_nomap(base, size);
+	if (nomap) {
+		err = memblock_mark_nomap(base, size);
+		if (err)
+			memblock_free(base, size);
+	}
 
-	return memblock_reserve(base, size);
+	return err;
 }
 
 /*
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 4a53c3ca86bd..b066024c62e3 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -99,8 +99,6 @@ void memblock_discard(void);
 static inline void memblock_discard(void) {}
 #endif
 
-phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
-				   phys_addr_t size, phys_addr_t align);
 void memblock_allow_resize(void);
 int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
 int memblock_add(phys_addr_t base, phys_addr_t size);
diff --git a/mm/memblock.c b/mm/memblock.c
index de7b553baa50..28a813d9e955 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -315,7 +315,7 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
  * Return:
  * Found address on success, 0 on failure.
  */
-phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
+static phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
 					phys_addr_t end, phys_addr_t size,
 					phys_addr_t align)
 {

base-commit: ff1176468d368232b684f75e82563369208bc371
-- 
2.28.0



From adobriyan at gmail.com  Sun Aug  1 23:42:45 2021
From: adobriyan at gmail.com (Alexey Dobriyan)
Date: Mon, 2 Aug 2021 09:42:45 +0300
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <20210801213247.GM1583@gate.crashing.org>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
 <20210801201336.2224111-3-adobriyan@gmail.com>
 <20210801213247.GM1583@gate.crashing.org>
Message-ID: <YQeT5QRXc3CzK9nL@localhost.localdomain>

On Sun, Aug 01, 2021 at 04:32:47PM -0500, Segher Boessenkool wrote:
> On Sun, Aug 01, 2021 at 11:13:36PM +0300, Alexey Dobriyan wrote:
> > In theory, it enables "leakage" of userspace headers into kernel which
> > may present licensing problem.
> 
> > -NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
> > +NOSTDINC_FLAGS += -nostdinc
> 
> This is removing the compiler's own include files.  These are required
> for all kinds of basic features, and required to be compliant to the C
> standard at all.

No they are not required. Kernel uses its own bool, uintptr_t and
static_assert, memset(), CHAR_BIT. noreturn, alignas newest C standard
are next.

This version changelog didn't mention but kernel would use
-ffreestanding too if not other problems with the flag.

> These are not "userspace headers", that is what
> -nostdinc takes care of already.

They are userspace headers in the sense they are external to the project
just like userspace programs are external to the kernel.

> In the case of GCC all these headers are GPL-with-runtime-exception, so
> claiming this can cause licensing problems is fearmongering.

I agree licensing problem doesn't really exist.
It would take gcc drop-in replacement with authors insane enough to not
license standard headers properly.

> I strongly advise against doing this.

Kernel chose to be self-contained. -isystem removal makes sense then.
It will be used for intrinsics where necessary.


From anshuman.khandual at arm.com  Sun Aug  1 23:43:45 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 2 Aug 2021 12:13:45 +0530
Subject: [PATCH 01/10] coresight: trbe: Add infrastructure for Errata
 handling
In-Reply-To: <20210728135217.591173-2-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-2-suzuki.poulose@arm.com>
Message-ID: <4c23e288-14bd-f4a5-2f92-6e3ad46324fa@arm.com>



On 7/28/21 7:22 PM, Suzuki K Poulose wrote:
> Add a minimal infrastructure to keep track of the errata
> affecting the given TRBE instance. Given that we have
> heterogeneous CPUs, we have to manage the list per-TRBE
> instance to be able to apply the work around as needed.
> 
> We rely on the arm64 errata framework for the actual
> description and the discovery of a given erratum, to
> keep the Erratum work around at a central place and
> benefit from the code and the advertisement from the
> kernel. We use a local mapping of the erratum to
> avoid bloating up the individual TRBE structures.

I guess there is no other way around apart from each TRBE instance
tracking applicable erratas locally per CPU, even though it sounds
bit redundant.

> i.e, each arm64 TRBE erratum bit is assigned a new number
> within the driver to track. Each trbe instance updates
> the list of affected erratum at probe time on the CPU.
> This makes sure that we can easily access the list of
> errata on a given TRBE instance without much overhead.

It also ensures that the generic errata framework is queried just
once during individual CPU probe.

> 
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Leo Yan <leo.yan at linaro.org>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-trbe.c | 48 ++++++++++++++++++++
>  1 file changed, 48 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index b8586c170889..0368bf405e35 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -16,6 +16,8 @@
>  #define pr_fmt(fmt) DRVNAME ": " fmt
>  
>  #include <asm/barrier.h>
> +#include <asm/cputype.h>
> +
>  #include "coresight-self-hosted-trace.h"
>  #include "coresight-trbe.h"
>  
> @@ -65,6 +67,35 @@ struct trbe_buf {
>  	struct trbe_cpudata *cpudata;
>  };
>  
> +/*
> + * TRBE erratum list
> + *
> + * We rely on the corresponding cpucaps to be defined for a given
> + * TRBE erratum. We map the given cpucap into a TRBE internal number
> + * to make the tracking of the errata lean.
> + *
> + * This helps in :
> + *   - Not duplicating the detection logic
> + *   - Streamlined detection of erratum across the system
> + *
> + * Since the erratum work arounds could be applied individually
> + * per TRBE instance, we keep track of the list of errata that
> + * affects the given instance of the TRBE.
> + */
> +#define TRBE_ERRATA_MAX			0
> +
> +static unsigned long trbe_errata_cpucaps[TRBE_ERRATA_MAX] = {
> +};

This needs to be tighten up. There should be build time guard rails in
arm64 errata cpucaps, so that only TRBE specific ones could be assigned
here as trbe_errata_cpucaps[].

> +
> +/*
> + * struct trbe_cpudata: TRBE instance specific data
> + * @trbe_flag		- TRBE dirty/access flag support
> + * @tbre_align		- Actual TRBE alignment required for TRBPTR_EL1.
> + * @cpu			- CPU this TRBE belongs to.
> + * @mode		- Mode of current operation. (perf/disabled)
> + * @drvdata		- TRBE specific drvdata
> + * @errata		- Bit map for the errata on this TRBE.
> + */
>  struct trbe_cpudata {
>  	bool trbe_flag;
>  	u64 trbe_align;
> @@ -72,6 +103,7 @@ struct trbe_cpudata {
>  	enum cs_mode mode;
>  	struct trbe_buf *buf;
>  	struct trbe_drvdata *drvdata;
> +	DECLARE_BITMAP(errata, TRBE_ERRATA_MAX);
>  };
>  
>  struct trbe_drvdata {
> @@ -84,6 +116,21 @@ struct trbe_drvdata {
>  	struct platform_device *pdev;
>  };
>  
> +static void trbe_check_errata(struct trbe_cpudata *cpudata)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(trbe_errata_cpucaps); i++) {

BUILD_BUG_ON() - if trbe_errata_cpucaps[i] is not inside TRBE specific
errata cpucap range ?

> +		if (this_cpu_has_cap(trbe_errata_cpucaps[i]))
> +			set_bit(i, cpudata->errata);
> +	}
> +}
> +
> +static inline bool trbe_has_erratum(int i, struct trbe_cpudata *cpudata)

Switch the argument positions here ? 'int i' should be the second one.

> +{
> +	return (i < TRBE_ERRATA_MAX) && test_bit(i, cpudata->errata);
> +}
> +
>  static int trbe_alloc_node(struct perf_event *event)
>  {
>  	if (event->cpu == -1)
> @@ -925,6 +972,7 @@ static void arm_trbe_probe_cpu(void *info)
>  		goto cpu_clear;
>  	}
>  
> +	trbe_check_errata(cpudata);

This should be called right at the end before arm_trbe_probe_cpu() exits
on the success path. Errata should not be evaluated if TRBE on the CPU
wont be used for some reason i.e cpumask_clear_cpu() path.

>  	cpudata->trbe_align = 1ULL << get_trbe_address_align(trbidr);
>  	if (cpudata->trbe_align > SZ_2K) {
>  		pr_err("Unsupported alignment on cpu %d\n", cpu);
> 

This patch should be moved after [PATCH 5/10] i.e just before adding the
first TRBE errata.


From vkoul at kernel.org  Mon Aug  2 00:03:44 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 2 Aug 2021 12:33:44 +0530
Subject: [PATCH] dma: imx-dma: configure the generic DMA type to make it
 work
In-Reply-To: <20210729071821.9857-1-jbe@pengutronix.de>
References: <20210729071821.9857-1-jbe@pengutronix.de>
Message-ID: <YQeY0E5oRHXkT+TO@matsya>

On 29-07-21, 09:18, Juergen Borleis wrote:
> Commit dea7a9f

you should use 12+ chars for sha1 
>   dmaengine: imx-dma: remove dma_slave_config direction usage

even with this is commit log, you made the patch tile dma: ....!
> 
> changes the method from a "configuration when called" to an "configuration
> when used". Due to this, only the cyclic DMA type gets configured
> correctly, while the generic DMA type is left non-configured.
> 
> Without this additional call, the struct imxdma_channel::word_size member
> is stuck at DMA_SLAVE_BUSWIDTH_UNDEFINED and imxdma_prep_slave_sg() always
> returns NULL.

I ahve fixed the subsystem name, updated commit in 12 chars and format
expected, added it as Fixes line and applied.

Please take care of these things!

> 
> Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
> ---
>  drivers/dma/imx-dma.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
> index 7f116bb..2ddc31e 100644
> --- a/drivers/dma/imx-dma.c
> +++ b/drivers/dma/imx-dma.c
> @@ -812,6 +812,8 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg(
>  		dma_length += sg_dma_len(sg);
>  	}
>  
> +	imxdma_config_write(chan, &imxdmac->config, direction);
> +
>  	switch (imxdmac->word_size) {
>  	case DMA_SLAVE_BUSWIDTH_4_BYTES:
>  		if (sg_dma_len(sgl) & 3 || sgl->dma_address & 3)
> -- 
> 2.20.1

-- 
~Vinod


From chuanjia.liu at mediatek.com  Mon Aug  2 00:07:22 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 2 Aug 2021 15:07:22 +0800
Subject: [PATCH v11 2/4] PCI: mediatek: Add new method to get shared
 pcie-cfg base address and parse node
In-Reply-To: <20210719073456.28666-3-chuanjia.liu@mediatek.com>
References: <20210719073456.28666-1-chuanjia.liu@mediatek.com>
 <20210719073456.28666-3-chuanjia.liu@mediatek.com>
Message-ID: <1627888042.1118.2.camel@mhfsdcap03>

On Mon, 2021-07-19 at 15:34 +0800, Chuanjia Liu wrote:

Gently ping...
> For the new dts format, add a new method to get
> shared pcie-cfg base address and parse node.
> 
> Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> ---
>  drivers/pci/controller/pcie-mediatek.c | 52 +++++++++++++++++++-------
>  1 file changed, 39 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> index 25bee693834f..928e0983a900 100644
> --- a/drivers/pci/controller/pcie-mediatek.c
> +++ b/drivers/pci/controller/pcie-mediatek.c
> @@ -14,6 +14,7 @@
>  #include <linux/irqchip/chained_irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/msi.h>
>  #include <linux/module.h>
>  #include <linux/of_address.h>
> @@ -23,6 +24,7 @@
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
>  #include <linux/reset.h>
>  
>  #include "../pci.h"
> @@ -207,6 +209,7 @@ struct mtk_pcie_port {
>   * struct mtk_pcie - PCIe host information
>   * @dev: pointer to PCIe device
>   * @base: IO mapped register base
> + * @cfg: IO mapped register map for PCIe config
>   * @free_ck: free-run reference clock
>   * @mem: non-prefetchable memory resource
>   * @ports: pointer to PCIe port information
> @@ -215,6 +218,7 @@ struct mtk_pcie_port {
>  struct mtk_pcie {
>  	struct device *dev;
>  	void __iomem *base;
> +	struct regmap *cfg;
>  	struct clk *free_ck;
>  
>  	struct list_head ports;
> @@ -650,7 +654,11 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
>  		return err;
>  	}
>  
> -	port->irq = platform_get_irq(pdev, port->slot);
> +	if (of_find_property(dev->of_node, "interrupt-names", NULL))
> +		port->irq = platform_get_irq_byname(pdev, "pcie_irq");
> +	else
> +		port->irq = platform_get_irq(pdev, port->slot);
> +
>  	if (port->irq < 0)
>  		return port->irq;
>  
> @@ -682,6 +690,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
>  		val |= PCIE_CSR_LTSSM_EN(port->slot) |
>  		       PCIE_CSR_ASPM_L1_EN(port->slot);
>  		writel(val, pcie->base + PCIE_SYS_CFG_V2);
> +	} else if (pcie->cfg) {
> +		val = PCIE_CSR_LTSSM_EN(port->slot) |
> +		      PCIE_CSR_ASPM_L1_EN(port->slot);
> +		regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
>  	}
>  
>  	/* Assert all reset signals */
> @@ -985,6 +997,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct resource *regs;
> +	struct device_node *cfg_node;
>  	int err;
>  
>  	/* get shared registers, which are optional */
> @@ -995,6 +1008,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
>  			return PTR_ERR(pcie->base);
>  	}
>  
> +	cfg_node = of_find_compatible_node(NULL, NULL,
> +					   "mediatek,generic-pciecfg");
> +	if (cfg_node) {
> +		pcie->cfg = syscon_node_to_regmap(cfg_node);
> +		if (IS_ERR(pcie->cfg))
> +			return PTR_ERR(pcie->cfg);
> +	}
> +
>  	pcie->free_ck = devm_clk_get(dev, "free_ck");
>  	if (IS_ERR(pcie->free_ck)) {
>  		if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
> @@ -1027,22 +1048,27 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct device_node *node = dev->of_node, *child;
>  	struct mtk_pcie_port *port, *tmp;
> -	int err;
> +	int err, slot;
> +
> +	slot = of_get_pci_domain_nr(dev->of_node);
> +	if (slot < 0) {
> +		for_each_available_child_of_node(node, child) {
> +			err = of_pci_get_devfn(child);
> +			if (err < 0) {
> +				dev_err(dev, "failed to get devfn: %d\n", err);
> +				goto error_put_node;
> +			}
>  
> -	for_each_available_child_of_node(node, child) {
> -		int slot;
> +			slot = PCI_SLOT(err);
>  
> -		err = of_pci_get_devfn(child);
> -		if (err < 0) {
> -			dev_err(dev, "failed to parse devfn: %d\n", err);
> -			goto error_put_node;
> +			err = mtk_pcie_parse_port(pcie, child, slot);
> +			if (err)
> +				goto error_put_node;
>  		}
> -
> -		slot = PCI_SLOT(err);
> -
> -		err = mtk_pcie_parse_port(pcie, child, slot);
> +	} else {
> +		err = mtk_pcie_parse_port(pcie, node, slot);
>  		if (err)
> -			goto error_put_node;
> +			return err;
>  	}
>  
>  	err = mtk_pcie_subsys_powerup(pcie);


From yongqiang.niu at mediatek.com  Mon Aug  2 00:10:26 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 15:10:26 +0800
Subject: [PATCH v3] drm/mediatek: clear pending flag when cmdq packet is done
Message-ID: <1627888227-5757-1-git-send-email-yongqiang.niu@mediatek.com>

Change since v2:
rebase
https://patchwork.kernel.org/project/linux-mediatek/cover/20210712235014.42673-1-chunkuang.hu at kernel.org/

Yongqiang Niu (1):
  drm/mediatek: clear pending flag when cmdq packet is done.

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 51 +++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 5 deletions(-)

-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Mon Aug  2 00:10:27 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 15:10:27 +0800
Subject: [PATCH v3] drm/mediatek: clear pending flag when cmdq packet is done.
In-Reply-To: <1627888227-5757-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1627888227-5757-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1627888227-5757-2-git-send-email-yongqiang.niu@mediatek.com>

In cmdq mode, packet may be flushed before it is executed, so
the pending flag should be cleared after cmdq packet is done.

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 51 +++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 4c25e33..2a2d43e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -267,6 +267,40 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 {
 	struct mtk_drm_crtc *mtk_crtc = container_of(cl, struct mtk_drm_crtc, cmdq_cl);
 	struct cmdq_cb_data *data = mssg;
+	struct mtk_crtc_state *state;
+	unsigned int i;
+
+	state = to_mtk_crtc_state(mtk_crtc->base.state);
+
+	if (state->pending_config) {
+		state->pending_config = false;
+	}
+
+	if (mtk_crtc->pending_planes) {
+		for (i = 0; i < mtk_crtc->layer_nr; i++) {
+			struct drm_plane *plane = &mtk_crtc->planes[i];
+			struct mtk_plane_state *plane_state;
+
+			plane_state = to_mtk_plane_state(plane->state);
+
+			if (plane_state->pending.config)
+				plane_state->pending.config = false;
+		}
+		mtk_crtc->pending_planes = false;
+	}
+
+	if (mtk_crtc->pending_async_planes) {
+		for (i = 0; i < mtk_crtc->layer_nr; i++) {
+			struct drm_plane *plane = &mtk_crtc->planes[i];
+			struct mtk_plane_state *plane_state;
+
+			plane_state = to_mtk_plane_state(plane->state);
+
+			if (plane_state->pending.async_config)
+				plane_state->pending.async_config = false;
+		}
+		mtk_crtc->pending_async_planes = false;
+	}
 
 	mtk_crtc->cmdq_vblank_cnt = 0;
 	mtk_drm_cmdq_pkt_destroy(mtk_crtc->cmdq_chan, data->pkt);
@@ -423,7 +457,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 				    state->pending_vrefresh, 0,
 				    cmdq_handle);
 
-		state->pending_config = false;
+		if (!cmdq_handle)
+			state->pending_config = false;
 	}
 
 	if (mtk_crtc->pending_planes) {
@@ -443,9 +478,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 				mtk_ddp_comp_layer_config(comp, local_layer,
 							  plane_state,
 							  cmdq_handle);
-			plane_state->pending.config = false;
+			if (!cmdq_handle)
+				plane_state->pending.config = false;
 		}
-		mtk_crtc->pending_planes = false;
+
+		if (!cmdq_handle)
+			mtk_crtc->pending_planes = false;
 	}
 
 	if (mtk_crtc->pending_async_planes) {
@@ -465,9 +503,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 				mtk_ddp_comp_layer_config(comp, local_layer,
 							  plane_state,
 							  cmdq_handle);
-			plane_state->pending.async_config = false;
+			if (!cmdq_handle)
+				plane_state->pending.async_config = false;
 		}
-		mtk_crtc->pending_async_planes = false;
+
+		if (!cmdq_handle)
+			mtk_crtc->pending_async_planes = false;
 	}
 }
 
-- 
1.8.1.1.dirty

From lee.jones at linaro.org  Mon Aug  2 00:40:26 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 2 Aug 2021 08:40:26 +0100
Subject: [PATCH v9 01/11] dt-bindings: mfd: axp20x: Add AXP305 compatible
 (plus optional IRQ)
In-Reply-To: <20210802003952.19942-2-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
 <20210802003952.19942-2-andre.przywara@arm.com>
Message-ID: <YQehakgWk/sp92to@google.com>

On Mon, 02 Aug 2021, Andre Przywara wrote:

> The AXP305 PMIC used on many boards with the H616 SoC seems to be fully
> compatible to the AXP805 PMIC, so add the proper chain of compatible
> strings.
> 
> Also at least on one board (Orangepi Zero2) there is no interrupt line
> connected to the CPU, so make the "interrupts" property optional.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/mfd/axp20x.txt | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Applied, thanks.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From anshuman.khandual at arm.com  Mon Aug  2 00:44:13 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 2 Aug 2021 13:14:13 +0530
Subject: [PATCH 07/10] arm64: Add erratum detection for TRBE overwrite in
 FILL mode
In-Reply-To: <20210728135217.591173-8-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-8-suzuki.poulose@arm.com>
Message-ID: <4011d566-1a5b-51a3-dcee-09f60af0a7bb@arm.com>



On 7/28/21 7:22 PM, Suzuki K Poulose wrote:
> Arm Neoverse-N2 and the Cortex-A710 cores are affected
> by a CPU erratum where the TRBE will overwrite the trace buffer
> in FILL mode. The TRBE doesn't stop (as expected in FILL mode)
> when it reaches the limit and wraps to the base to continue
> writing upto 3 cache lines. This will overwrite any trace that
> was written previously.
> 
> Add the Neoverse-N2 erratumi(#2139208) and Cortex-A710 erratum

Small nit. Stray 'i' here  ^^^^

> (#2119858) to the  detection logic.
> 
> This will be used by the TRBE driver in later patches to work
> around the issue. The detection has been kept with the core
> arm64 errata framework list to make sure :
>   - We don't duplicate the framework in TRBE driver
>   - The errata detection is advertised like the rest
>     of the CPU errata.
> 
> Note that the Kconfig entries will be added after we have added
> the work around in the TRBE driver, which depends on the cpucap
> from here.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> cc: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
>  arch/arm64/kernel/cpu_errata.c | 25 +++++++++++++++++++++++++
>  arch/arm64/tools/cpucaps       |  1 +
>  2 files changed, 26 insertions(+)
> 
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index e2c20c036442..ccd757373f36 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -340,6 +340,18 @@ static const struct midr_range erratum_1463225[] = {
>  };
>  #endif
>  
> +#ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
> +static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
> +#ifdef CONFIG_ARM64_ERRATUM_2139208
> +	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_2119858
> +	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> +#endif
> +	{},
> +};
> +#endif	/* CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE */
> +
>  const struct arm64_cpu_capabilities arm64_errata[] = {
>  #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
>  	{
> @@ -533,6 +545,19 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>  		.capability = ARM64_WORKAROUND_NVIDIA_CARMEL_CNP,
>  		ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL),
>  	},
> +#endif
> +#ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
> +	{
> +		/*
> +		 * The erratum work around is handled within the TRBE
> +		 * driver and can be applied per-cpu. So, we can allow
> +		 * a late CPU to come online with this erratum.
> +		 */
> +		.desc = "ARM erratum 2119858 or 2139208",
> +		.capability = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
> +		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
> +		CAP_MIDR_RANGE_LIST(trbe_overwrite_fill_mode_cpus),
> +	},
>  #endif
>  	{
>  	}
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 49305c2e6dfd..1ccb92165bd8 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -53,6 +53,7 @@ WORKAROUND_1418040
>  WORKAROUND_1463225
>  WORKAROUND_1508412
>  WORKAROUND_1542419
> +WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>  WORKAROUND_CAVIUM_23154
>  WORKAROUND_CAVIUM_27456
>  WORKAROUND_CAVIUM_30115
> 

Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>


From yongqiang.niu at mediatek.com  Mon Aug  2 00:46:02 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 15:46:02 +0800
Subject: [PATCH v6 0/3] support gce on mt8192 platform
Message-ID: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>

Change since v5:
-rebase on linux 5.14-rc1

Yongqiang Niu (3):
  dt-binding: gce: add gce header file for mt8192
  arm64: dts: mt8192: add gce node
  mailbox: cmdq: add mt8192 support

 .../devicetree/bindings/mailbox/mtk-gce.txt        |   7 +-
 arch/arm64/boot/dts/mediatek/mt8192.dtsi           |  10 +
 drivers/mailbox/mtk-cmdq-mailbox.c                 |  10 +
 include/dt-bindings/gce/mt8192-gce.h               | 335 +++++++++++++++++++++
 4 files changed, 359 insertions(+), 3 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt8192-gce.h

-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Mon Aug  2 00:46:04 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 15:46:04 +0800
Subject: [PATCH v6, 2/3] arm64: dts: mt8192: add gce node
In-Reply-To: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1627890365-22992-3-git-send-email-yongqiang.niu@mediatek.com>

add gce node for mt8192

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 6b22441..c8472c6 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include <dt-bindings/clock/mt8192-clk.h>
+#include <dt-bindings/gce/mt8192-gce.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/mt8192-pinfunc.h>
@@ -517,6 +518,15 @@
 			clock-names = "clk13m";
 		};
 
+		gce: mailbox at 10228000 {
+			compatible = "mediatek,mt8192-gce";
+			reg = <0 0x10228000 0 0x4000>;
+			interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <3>;
+			clocks = <&infracfg CLK_INFRA_GCE>;
+			clock-names = "gce";
+		};
+
 		scp_adsp: clock-controller at 10720000 {
 			compatible = "mediatek,mt8192-scp_adsp";
 			reg = <0 0x10720000 0 0x1000>;
-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Mon Aug  2 00:52:26 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 15:52:26 +0800
Subject: [PATCH v3] soc: mediatek: cmdq: add address shift in jump
Message-ID: <1627890746-23165-1-git-send-email-yongqiang.niu@mediatek.com>

Add address shift when compose jump instruction
to compatible with 35bit format.

Fixes: 0858fde496f8 ("mailbox: cmdq: variablize address shift in platform")

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Reviewed-by: Nicolas Boichat <drinkcat at chromium.org>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 8d39b98..d03bfaf 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -174,7 +174,8 @@ static void cmdq_task_insert_into_thread(struct cmdq_task *task)
 	dma_sync_single_for_cpu(dev, prev_task->pa_base,
 				prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
 	prev_task_base[CMDQ_NUM_CMD(prev_task->pkt) - 1] =
-		(u64)CMDQ_JUMP_BY_PA << 32 | task->pa_base;
+		(u64)CMDQ_JUMP_BY_PA << 32 |
+		(task->pa_base >> task->cmdq->shift_pa);
 	dma_sync_single_for_device(dev, prev_task->pa_base,
 				   prev_task->pkt->cmd_buf_size, DMA_TO_DEVICE);
 
-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Mon Aug  2 00:46:03 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 15:46:03 +0800
Subject: [PATCH v6, 1/3] dt-binding: gce: add gce header file for mt8192
In-Reply-To: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1627890365-22992-2-git-send-email-yongqiang.niu@mediatek.com>

Add documentation for the mt8192 gce.

Add gce header file defined the gce hardware event,
subsys number and constant for mt8192.

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 .../devicetree/bindings/mailbox/mtk-gce.txt        |   7 +-
 include/dt-bindings/gce/mt8192-gce.h               | 335 +++++++++++++++++++++
 2 files changed, 339 insertions(+), 3 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt8192-gce.h

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 7771eca..ac424505 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,8 +9,8 @@ CMDQ driver uses mailbox framework for communication. Please refer to
 mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
-- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce" or
-  "mediatek,mt6779-gce".
+- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce",
+  "mediatek,mt8192-gce" or "mediatek,mt6779-gce".
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -36,7 +36,8 @@ Optional properties for a client device:
   size: the total size of register address that GCE can access.
 
 Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h',
-'dt-binding/gce/mt8183-gce.h' or 'dt-bindings/gce/mt6779-gce.h'. Such as
+'dt-binding/gce/mt8183-gce.h', 'dt-binding/gce/mt8192-gce.h' or
+'dt-bindings/gce/mt6779-gce.h'. Such as
 sub-system ids, thread priority, event ids.
 
 Example:
diff --git a/include/dt-bindings/gce/mt8192-gce.h b/include/dt-bindings/gce/mt8192-gce.h
new file mode 100644
index 0000000..9e5a0eb
--- /dev/null
+++ b/include/dt-bindings/gce/mt8192-gce.h
@@ -0,0 +1,335 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ * Author: Yongqiang Niu <yongqiang.niu at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8192_H
+#define _DT_BINDINGS_GCE_MT8192_H
+
+/* assign timeout 0 also means default */
+#define CMDQ_NO_TIMEOUT		0xffffffff
+#define CMDQ_TIMEOUT_DEFAULT	1000
+
+/* GCE thread priority */
+#define CMDQ_THR_PRIO_LOWEST	0
+#define CMDQ_THR_PRIO_1		1
+#define CMDQ_THR_PRIO_2		2
+#define CMDQ_THR_PRIO_3		3
+#define CMDQ_THR_PRIO_4		4
+#define CMDQ_THR_PRIO_5		5
+#define CMDQ_THR_PRIO_6		6
+#define CMDQ_THR_PRIO_HIGHEST	7
+
+/* CPR count in 32bit register */
+#define GCE_CPR_COUNT		1312
+
+/* GCE subsys table */
+#define SUBSYS_1300XXXX		0
+#define SUBSYS_1400XXXX		1
+#define SUBSYS_1401XXXX		2
+#define SUBSYS_1402XXXX		3
+#define SUBSYS_1502XXXX		4
+#define SUBSYS_1880XXXX		5
+#define SUBSYS_1881XXXX		6
+#define SUBSYS_1882XXXX		7
+#define SUBSYS_1883XXXX		8
+#define SUBSYS_1884XXXX		9
+#define SUBSYS_1000XXXX		10
+#define SUBSYS_1001XXXX		11
+#define SUBSYS_1002XXXX		12
+#define SUBSYS_1003XXXX		13
+#define SUBSYS_1004XXXX		14
+#define SUBSYS_1005XXXX		15
+#define SUBSYS_1020XXXX		16
+#define SUBSYS_1028XXXX		17
+#define SUBSYS_1700XXXX		18
+#define SUBSYS_1701XXXX		19
+#define SUBSYS_1702XXXX		20
+#define SUBSYS_1703XXXX		21
+#define SUBSYS_1800XXXX		22
+#define SUBSYS_1801XXXX		23
+#define SUBSYS_1802XXXX		24
+#define SUBSYS_1804XXXX		25
+#define SUBSYS_1805XXXX		26
+#define SUBSYS_1808XXXX		27
+#define SUBSYS_180aXXXX		28
+#define SUBSYS_180bXXXX		29
+
+#define CMDQ_EVENT_VDEC_LAT_SOF_0			0
+#define CMDQ_EVENT_VDEC_LAT_FRAME_DONE_0		1
+#define CMDQ_EVENT_VDEC_LAT_FRAME_DONE_1		2
+#define CMDQ_EVENT_VDEC_LAT_FRAME_DONE_2		3
+#define CMDQ_EVENT_VDEC_LAT_FRAME_DONE_3		4
+#define CMDQ_EVENT_VDEC_LAT_FRAME_DONE_4		5
+#define CMDQ_EVENT_VDEC_LAT_FRAME_DONE_5		6
+#define CMDQ_EVENT_VDEC_LAT_FRAME_DONE_6		7
+#define CMDQ_EVENT_VDEC_LAT_ENG_EVENT_0			8
+#define CMDQ_EVENT_VDEC_LAT_ENG_EVENT_1			9
+#define CMDQ_EVENT_VDEC_LAT_ENG_EVENT_2			10
+#define CMDQ_EVENT_VDEC_LAT_ENG_EVENT_3			11
+#define CMDQ_EVENT_VDEC_LAT_ENG_EVENT_4			12
+#define CMDQ_EVENT_VDEC_LAT_ENG_EVENT_5			13
+#define CMDQ_EVENT_VDEC_LAT_ENG_EVENT_6			14
+#define CMDQ_EVENT_VDEC_LAT_ENG_EVENT_7			15
+
+#define CMDQ_EVENT_ISP_FRAME_DONE_A			65
+#define CMDQ_EVENT_ISP_FRAME_DONE_B			66
+#define CMDQ_EVENT_ISP_FRAME_DONE_C			67
+#define CMDQ_EVENT_CAMSV0_PASS1_DONE			68
+#define CMDQ_EVENT_CAMSV02_PASS1_DONE			69
+#define CMDQ_EVENT_CAMSV1_PASS1_DONE			70
+#define CMDQ_EVENT_CAMSV2_PASS1_DONE			71
+#define CMDQ_EVENT_CAMSV3_PASS1_DONE			72
+#define CMDQ_EVENT_MRAW_0_PASS1_DONE			73
+#define CMDQ_EVENT_MRAW_1_PASS1_DONE			74
+#define CMDQ_EVENT_SENINF_CAM0_FIFO_FULL		75
+#define CMDQ_EVENT_SENINF_CAM1_FIFO_FULL		76
+#define CMDQ_EVENT_SENINF_CAM2_FIFO_FULL		77
+#define CMDQ_EVENT_SENINF_CAM3_FIFO_FULL		78
+#define CMDQ_EVENT_SENINF_CAM4_FIFO_FULL		79
+#define CMDQ_EVENT_SENINF_CAM5_FIFO_FULL		80
+#define CMDQ_EVENT_SENINF_CAM6_FIFO_FULL		81
+#define CMDQ_EVENT_SENINF_CAM7_FIFO_FULL		82
+#define CMDQ_EVENT_SENINF_CAM8_FIFO_FULL		83
+#define CMDQ_EVENT_SENINF_CAM9_FIFO_FULL		84
+#define CMDQ_EVENT_SENINF_CAM10_FIFO_FULL		85
+#define CMDQ_EVENT_SENINF_CAM11_FIFO_FULL		86
+#define CMDQ_EVENT_SENINF_CAM12_FIFO_FULL		87
+#define CMDQ_EVENT_TG_OVRUN_A_INT			88
+#define CMDQ_EVENT_DMA_R1_ERROR_A_INT			89
+#define CMDQ_EVENT_TG_OVRUN_B_INT			90
+#define CMDQ_EVENT_DMA_R1_ERROR_B_INT			91
+#define CMDQ_EVENT_TG_OVRUN_C_INT			92
+#define CMDQ_EVENT_DMA_R1_ERROR_C_INT			93
+#define CMDQ_EVENT_TG_OVRUN_M0_INT			94
+#define CMDQ_EVENT_DMA_R1_ERROR_M0_INT			95
+#define CMDQ_EVENT_TG_GRABERR_M0_INT			96
+#define CMDQ_EVENT_TG_GRABERR_M1_INT			97
+#define CMDQ_EVENT_TG_GRABERR_A_INT			98
+#define CMDQ_EVENT_CQ_VR_SNAP_A_INT			99
+#define CMDQ_EVENT_TG_GRABERR_B_INT			100
+#define CMDQ_EVENT_CQ_VR_SNAP_B_INT			101
+#define CMDQ_EVENT_TG_GRABERR_C_INT			102
+#define CMDQ_EVENT_CQ_VR_SNAP_C_INT			103
+
+#define CMDQ_EVENT_VENC_CMDQ_FRAME_DONE			129
+#define CMDQ_EVENT_VENC_CMDQ_PAUSE_DONE			130
+#define CMDQ_EVENT_JPGENC_CMDQ_DONE			131
+#define CMDQ_EVENT_VENC_CMDQ_MB_DONE			132
+#define CMDQ_EVENT_VENC_CMDQ_128BYTE_CNT_DONE		133
+#define CMDQ_EVENT_VENC_C0_CMDQ_WP_2ND_STAGE_DONE	134
+#define CMDQ_EVENT_VENC_C0_CMDQ_WP_3RD_STAGE_DONE	135
+#define CMDQ_EVENT_VENC_CMDQ_PPS_DONE			136
+#define CMDQ_EVENT_VENC_CMDQ_SPS_DONE			137
+#define CMDQ_EVENT_VENC_CMDQ_VPS_DONE			138
+
+#define CMDQ_EVENT_VDEC_CORE0_SOF_0			160
+#define CMDQ_EVENT_VDEC_CORE0_FRAME_DONE_0		161
+#define CMDQ_EVENT_VDEC_CORE0_FRAME_DONE_1		162
+#define CMDQ_EVENT_VDEC_CORE0_FRAME_DONE_2		163
+#define CMDQ_EVENT_VDEC_CORE0_FRAME_DONE_3		164
+#define CMDQ_EVENT_VDEC_CORE0_FRAME_DONE_4		165
+#define CMDQ_EVENT_VDEC_CORE0_FRAME_DONE_5		166
+#define CMDQ_EVENT_VDEC_CORE0_FRAME_DONE_6		167
+#define CMDQ_EVENT_VDEC_CORE0_ENG_EVENT_0		168
+#define CMDQ_EVENT_VDEC_CORE0_ENG_EVENT_1		169
+#define CMDQ_EVENT_VDEC_CORE0_ENG_EVENT_2		170
+#define CMDQ_EVENT_VDEC_CORE0_ENG_EVENT_3		171
+#define CMDQ_EVENT_VDEC_CORE0_ENG_EVENT_4		172
+#define CMDQ_EVENT_VDEC_CORE0_ENG_EVENT_5		173
+#define CMDQ_EVENT_VDEC_CORE0_ENG_EVENT_6		174
+#define CMDQ_EVENT_VDEC_CORE0_ENG_EVENT_7		175
+#define CMDQ_EVENT_FDVT_DONE				177
+#define CMDQ_EVENT_FE_DONE				178
+#define CMDQ_EVENT_RSC_DONE				179
+#define CMDQ_EVENT_DVS_DONE_ASYNC_SHOT			180
+#define CMDQ_EVENT_DVP_DONE_ASYNC_SHOT			181
+
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_0		193
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_1		194
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_2		195
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_3		196
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_4		197
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_5		198
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_6		199
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_7		200
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_8		201
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_9		202
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_10		203
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_11		204
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_12		205
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_13		206
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_14		207
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_15		208
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_16		209
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_17		210
+#define CMDQ_EVENT_IMG2_DIP_FRAME_DONE_P2_18		211
+#define CMDQ_EVENT_IMG2_DIP_DMA_ERR_EVENT		212
+#define CMDQ_EVENT_IMG2_AMD_FRAME_DONE			213
+#define CMDQ_EVENT_IMG2_MFB_DONE_LINK_MISC		214
+#define CMDQ_EVENT_IMG2_WPE_A_DONE_LINK_MISC		215
+#define CMDQ_EVENT_IMG2_MSS_DONE_LINK_MISC		216
+
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_0		225
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_1		226
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_2		227
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_3		228
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_4		229
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_5		230
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_6		231
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_7		232
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_8		233
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_9		234
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_10		235
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_11		236
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_12		237
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_13		238
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_14		239
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_15		240
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_16		241
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_17		242
+#define CMDQ_EVENT_IMG1_DIP_FRAME_DONE_P2_18		243
+#define CMDQ_EVENT_IMG1_DIP_DMA_ERR_EVENT		244
+#define CMDQ_EVENT_IMG1_AMD_FRAME_DONE			245
+#define CMDQ_EVENT_IMG1_MFB_DONE_LINK_MISC		246
+#define CMDQ_EVENT_IMG1_WPE_A_DONE_LINK_MISC		247
+#define CMDQ_EVENT_IMG1_MSS_DONE_LINK_MISC		248
+
+#define CMDQ_EVENT_MDP_RDMA0_SOF			256
+#define CMDQ_EVENT_MDP_RDMA1_SOF			257
+#define CMDQ_EVENT_MDP_AAL0_SOF				258
+#define CMDQ_EVENT_MDP_AAL1_SOF				259
+#define CMDQ_EVENT_MDP_HDR0_SOF				260
+#define CMDQ_EVENT_MDP_HDR1_SOF				261
+#define CMDQ_EVENT_MDP_RSZ0_SOF				262
+#define CMDQ_EVENT_MDP_RSZ1_SOF				263
+#define CMDQ_EVENT_MDP_WROT0_SOF			264
+#define CMDQ_EVENT_MDP_WROT1_SOF			265
+#define CMDQ_EVENT_MDP_TDSHP0_SOF			266
+#define CMDQ_EVENT_MDP_TDSHP1_SOF			267
+#define CMDQ_EVENT_IMG_DL_RELAY0_SOF			268
+#define CMDQ_EVENT_IMG_DL_RELAY1_SOF			269
+#define CMDQ_EVENT_MDP_COLOR0_SOF			270
+#define CMDQ_EVENT_MDP_COLOR1_SOF			271
+#define CMDQ_EVENT_MDP_WROT1_FRAME_DONE			290
+#define CMDQ_EVENT_MDP_WROT0_FRAME_DONE			291
+#define CMDQ_EVENT_MDP_TDSHP1_FRAME_DONE		294
+#define CMDQ_EVENT_MDP_TDSHP0_FRAME_DONE		295
+#define CMDQ_EVENT_MDP_RSZ1_FRAME_DONE			302
+#define CMDQ_EVENT_MDP_RSZ0_FRAME_DONE			303
+#define CMDQ_EVENT_MDP_RDMA1_FRAME_DONE			306
+#define CMDQ_EVENT_MDP_RDMA0_FRAME_DONE			307
+#define CMDQ_EVENT_MDP_HDR1_FRAME_DONE			308
+#define CMDQ_EVENT_MDP_HDR0_FRAME_DONE			309
+#define CMDQ_EVENT_MDP_COLOR1_FRAME_DONE		312
+#define CMDQ_EVENT_MDP_COLOR0_FRAME_DONE		313
+#define CMDQ_EVENT_MDP_AAL1_FRAME_DONE			316
+#define CMDQ_EVENT_MDP_AAL0_FRAME_DONE			317
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_0		320
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_1		321
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_2		322
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_3		323
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_4		324
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_5		325
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_6		326
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_7		327
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_8		328
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_9		329
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_10		330
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_11		331
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_12		332
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_13		333
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_14		334
+#define CMDQ_EVENT_MDP_STREAM_DONE_ENG_EVENT_15		335
+#define CMDQ_EVENT_MDP_WROT1_SW_RST_DONE_ENG_EVENT	338
+#define CMDQ_EVENT_MDP_WROT0_SW_RST_DONE_ENG_EVENT	339
+#define CMDQ_EVENT_MDP_RDMA1_SW_RST_DONE_ENG_EVENT	342
+#define CMDQ_EVENT_MDP_RDMA0_SW_RST_DONE_ENG_EVENT	343
+
+#define CMDQ_EVENT_DISP_OVL0_SOF			384
+#define CMDQ_EVENT_DISP_OVL0_2L_SOF			385
+#define CMDQ_EVENT_DISP_RDMA0_SOF			386
+#define CMDQ_EVENT_DISP_RSZ0_SOF			387
+#define CMDQ_EVENT_DISP_COLOR0_SOF			388
+#define CMDQ_EVENT_DISP_CCORR0_SOF			389
+#define CMDQ_EVENT_DISP_AAL0_SOF			390
+#define CMDQ_EVENT_DISP_GAMMA0_SOF			391
+#define CMDQ_EVENT_DISP_POSTMASK0_SOF			392
+#define CMDQ_EVENT_DISP_DITHER0_SOF			393
+#define CMDQ_EVENT_DISP_DSC_WRAP0_CORE0_SOF		394
+#define CMDQ_EVENT_DISP_DSC_WRAP0_CORE1_SOF		395
+#define CMDQ_EVENT_DSI0_SOF				396
+#define CMDQ_EVENT_DISP_WDMA0_SOF			397
+#define CMDQ_EVENT_DISP_UFBC_WDMA0_SOF			398
+#define CMDQ_EVENT_DISP_PWM0_SOF			399
+#define CMDQ_EVENT_DISP_OVL2_2L_SOF			400
+#define CMDQ_EVENT_DISP_RDMA4_SOF			401
+#define CMDQ_EVENT_DISP_DPI0_SOF			402
+#define CMDQ_EVENT_MDP_RDMA4_SOF			403
+#define CMDQ_EVENT_MDP_HDR4_SOF				404
+#define CMDQ_EVENT_MDP_RSZ4_SOF				405
+#define CMDQ_EVENT_MDP_AAL4_SOF				406
+#define CMDQ_EVENT_MDP_TDSHP4_SOF			407
+#define CMDQ_EVENT_MDP_COLOR4_SOF			408
+#define CMDQ_EVENT_DISP_Y2R0_SOF			409
+#define CMDQ_EVENT_MDP_TDSHP4_FRAME_DONE		410
+#define CMDQ_EVENT_MDP_RSZ4_FRAME_DONE			411
+#define CMDQ_EVENT_MDP_RDMA4_FRAME_DONE			412
+#define CMDQ_EVENT_MDP_HDR4_FRAME_DONE			413
+#define CMDQ_EVENT_MDP_COLOR4_FRAME_DONE		414
+#define CMDQ_EVENT_MDP_AAL4_FRAME_DONE			415
+#define CMDQ_EVENT_DSI0_FRAME_DONE			416
+#define CMDQ_EVENT_DISP_WDMA0_FRAME_DONE		417
+#define CMDQ_EVENT_DISP_UFBC_WDMA0_FRAME_DONE		418
+#define CMDQ_EVENT_DISP_RSZ0_FRAME_DONE			419
+#define CMDQ_EVENT_DISP_RDMA4_FRAME_DONE		420
+#define CMDQ_EVENT_DISP_RDMA0_FRAME_DONE		421
+#define CMDQ_EVENT_DISP_POSTMASK0_FRAME_DONE		422
+#define CMDQ_EVENT_DISP_OVL2_2L_FRAME_DONE		423
+#define CMDQ_EVENT_DISP_OVL0_FRAME_DONE			424
+#define CMDQ_EVENT_DISP_OVL0_2L_FRAME_DONE		425
+#define CMDQ_EVENT_DISP_GAMMA0_FRAME_DONE		426
+#define CMDQ_EVENT_DISP_DSC_WRAP0_CORE1_FRAME_DONE	427
+#define CMDQ_EVENT_DISP_DSC_WRAP0_CORE0_FRAME_DONE	428
+#define CMDQ_EVENT_DISP_DPI0_FRAME_DONE			429
+#define CMDQ_EVENT_DISP_DITHER0_FRAME_DONE		430
+#define CMDQ_EVENT_DISP_COLOR0_FRAME_DONE		431
+#define CMDQ_EVENT_DISP_CCORR0_FRAME_DONE		432
+#define CMDQ_EVENT_DISP_AAL0_FRAME_DONE			433
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_0		434
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_1		435
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_2		436
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_3		437
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_4		438
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_5		439
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_6		440
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_7		441
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_8		442
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_9		443
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_10	444
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_11	445
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_12	446
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_13	447
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_14	448
+#define CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_15	449
+#define CMDQ_EVENT_DSI0_TE_ENG_EVENT			450
+#define CMDQ_EVENT_DSI0_IRQ_ENG_EVENT			451
+#define CMDQ_EVENT_DSI0_DONE_ENG_EVENT			452
+#define CMDQ_EVENT_DISP_WDMA0_SW_RST_DONE_ENG_EVENT	453
+#define CMDQ_EVENT_DISP_SMIASSERT_ENG_EVENT		454
+#define CMDQ_EVENT_DISP_POSTMASK0_RST_DONE_ENG_EVENT	455
+#define CMDQ_EVENT_DISP_OVL2_2L_RST_DONE_ENG_EVENT	456
+#define CMDQ_EVENT_DISP_OVL0_RST_DONE_ENG_EVENT		457
+#define CMDQ_EVENT_DISP_OVL0_2L_RST_DONE_ENG_EVENT	458
+#define CMDQ_EVENT_BUF_UNDERRUN_ENG_EVENT_0		459
+#define CMDQ_EVENT_BUF_UNDERRUN_ENG_EVENT_1		460
+#define CMDQ_EVENT_BUF_UNDERRUN_ENG_EVENT_2		461
+#define CMDQ_EVENT_BUF_UNDERRUN_ENG_EVENT_3		462
+#define CMDQ_EVENT_BUF_UNDERRUN_ENG_EVENT_4		463
+#define CMDQ_EVENT_BUF_UNDERRUN_ENG_EVENT_5		464
+#define CMDQ_EVENT_BUF_UNDERRUN_ENG_EVENT_6		465
+#define CMDQ_EVENT_BUF_UNDERRUN_ENG_EVENT_7		466
+#define CMDQ_MAX_HW_EVENT				512
+
+#endif
-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Mon Aug  2 00:46:05 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 15:46:05 +0800
Subject: [PATCH v6, 3/3] mailbox: cmdq: add mt8192 support
In-Reply-To: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1627890365-22992-4-git-send-email-yongqiang.niu@mediatek.com>

add mt8192 support

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 67a42b5..8d39b98 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -36,6 +36,8 @@
 #define CMDQ_THR_WAIT_TOKEN		0x30
 #define CMDQ_THR_PRIORITY		0x40
 
+#define GCE_GCTL_VALUE			0x48
+
 #define CMDQ_THR_ACTIVE_SLOT_CYCLES	0x3200
 #define CMDQ_THR_ENABLED		0x1
 #define CMDQ_THR_DISABLED		0x0
@@ -76,11 +78,13 @@ struct cmdq {
 	struct clk		*clock;
 	bool			suspended;
 	u8			shift_pa;
+	bool			control_by_sw;
 };
 
 struct gce_plat {
 	u32 thread_nr;
 	u8 shift;
+	bool control_by_sw;
 };
 
 u8 cmdq_get_shift_pa(struct mbox_chan *chan)
@@ -121,6 +125,8 @@ static void cmdq_init(struct cmdq *cmdq)
 	int i;
 
 	WARN_ON(clk_enable(cmdq->clock) < 0);
+	if (cmdq->control_by_sw)
+		writel(0x7, cmdq->base + GCE_GCTL_VALUE);
 	writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
 	for (i = 0; i <= CMDQ_MAX_EVENT; i++)
 		writel(i, cmdq->base + CMDQ_SYNC_TOKEN_UPDATE);
@@ -540,6 +546,7 @@ static int cmdq_probe(struct platform_device *pdev)
 
 	cmdq->thread_nr = plat_data->thread_nr;
 	cmdq->shift_pa = plat_data->shift;
+	cmdq->control_by_sw = plat_data->control_by_sw;
 	cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0);
 	err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
 			       "mtk_cmdq", cmdq);
@@ -605,11 +612,14 @@ static int cmdq_probe(struct platform_device *pdev)
 static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
 static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
 static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
+static const struct gce_plat gce_plat_v5 = {.thread_nr = 24, .shift = 3,
+					    .control_by_sw = true};
 
 static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
 	{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
 	{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
+	{.compatible = "mediatek,mt8192-gce", .data = (void *)&gce_plat_v5},
 	{}
 };
 
-- 
1.8.1.1.dirty

From boqun.feng at gmail.com  Mon Aug  2 01:13:11 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Mon, 2 Aug 2021 16:13:11 +0800
Subject: [PATCH v6 0/8] PCI: hv: Support host bridge probing on ARM64
In-Reply-To: <20210727161259.GA718226@bjorn-Precision-5520>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210727161259.GA718226@bjorn-Precision-5520>
Message-ID: <YQepFyKjDr4e5w8Y@boqun-archlinux>

On Tue, Jul 27, 2021 at 11:12:59AM -0500, Bjorn Helgaas wrote:
> On Tue, Jul 27, 2021 at 02:06:49AM +0800, Boqun Feng wrote:
> > Hi,
> > 
> > This is the v6 for the preparation of virtual PCI support on Hyper-V
> > ARM64, Previous versions:
> > 
> > v1:	https://lore.kernel.org/lkml/20210319161956.2838291-1-boqun.feng at gmail.com/
> > v2:	https://lore.kernel.org/lkml/20210503144635.2297386-1-boqun.feng at gmail.com/
> > v3:	https://lore.kernel.org/lkml/20210609163211.3467449-1-boqun.feng at gmail.com/
> > v4:	https://lore.kernel.org/lkml/20210714102737.198432-1-boqun.feng at gmail.com/
> > v5:	https://lore.kernel.org/lkml/20210720134429.511541-1-boqun.feng at gmail.com/
> 
> Thanks for these; they're very handy for archaeology later.
> 
> > Changes since last version:
> > 
> > *	Rebase to 5.14-rc3
> 
> Just FYI, it's not a problem that you rebased, but it's not necessary.
> These will be applied to a topic branch from v5.14-rc1 anyway.

Got it ;-)

Regards,
Boqun


From boqun.feng at gmail.com  Mon Aug  2 01:15:04 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Mon, 2 Aug 2021 16:15:04 +0800
Subject: [PATCH v6 0/8] PCI: hv: Support host bridge probing on ARM64
In-Reply-To: <20210726180657.142727-1-boqun.feng@gmail.com>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
Message-ID: <YQepiKkFoJHC0gsK@boqun-archlinux>

On Tue, Jul 27, 2021 at 02:06:49AM +0800, Boqun Feng wrote:
> Hi,
> 
> This is the v6 for the preparation of virtual PCI support on Hyper-V
> ARM64, Previous versions:
> 
> v1:	https://lore.kernel.org/lkml/20210319161956.2838291-1-boqun.feng at gmail.com/
> v2:	https://lore.kernel.org/lkml/20210503144635.2297386-1-boqun.feng at gmail.com/
> v3:	https://lore.kernel.org/lkml/20210609163211.3467449-1-boqun.feng at gmail.com/
> v4:	https://lore.kernel.org/lkml/20210714102737.198432-1-boqun.feng at gmail.com/
> v5:	https://lore.kernel.org/lkml/20210720134429.511541-1-boqun.feng at gmail.com/
> 
> Changes since last version:
> 
> *	Rebase to 5.14-rc3
> 
> *	Comment fixes as suggested by Bjorn.
> 
> The basic problem we need to resolve is that ARM64 is an arch with
> PCI_DOMAINS_GENERIC=y, so the bus sysdata is pci_config_window. However,
> Hyper-V PCI provides a paravirtualized PCI interface, so there is no
> actual pci_config_window for a PCI host bridge, so no information can be
> retrieve from the pci_config_window of a Hyper-V virtual PCI bus. Also
> there is no corresponding ACPI device for the Hyper-V PCI root bridge,
> which introduces a special case when trying to find the ACPI device from
> the sysdata (see patch #3).
> 
> With this patchset, we could enable the virtual PCI on Hyper-V ARM64
> guest with other code under development.
> 
> Comments and suggestions are welcome.
> 

Ping ;-)

Regards,
Boqun

> Regards,
> Boqun
> 
> Arnd Bergmann (1):
>   PCI: hv: Generify PCI probing
> 
> Boqun Feng (7):
>   PCI: Introduce domain_nr in pci_host_bridge
>   PCI: Support populating MSI domains of root buses via bridges
>   arm64: PCI: Restructure pcibios_root_bridge_prepare()
>   arm64: PCI: Support root bridge preparation for Hyper-V
>   PCI: hv: Set ->domain_nr of pci_host_bridge at probing time
>   PCI: hv: Set up MSI domain at bridge probing time
>   PCI: hv: Turn on the host bridge probing on ARM64
> 
>  arch/arm64/kernel/pci.c             | 29 +++++++---
>  drivers/pci/controller/pci-hyperv.c | 86 +++++++++++++++++------------
>  drivers/pci/probe.c                 | 12 +++-
>  include/linux/pci.h                 | 11 ++++
>  4 files changed, 93 insertions(+), 45 deletions(-)
> 
> -- 
> 2.32.0
> 


From kirill at shutemov.name  Mon Aug  2 01:26:21 2021
From: kirill at shutemov.name (Kirill A. Shutemov)
Date: Mon, 2 Aug 2021 11:26:21 +0300
Subject: [PATCH v2] memblock: make memblock_find_in_range method private
In-Reply-To: <20210802063737.22733-1-rppt@kernel.org>
References: <20210802063737.22733-1-rppt@kernel.org>
Message-ID: <20210802082621.xfbrdg2c6glwz3oq@box.shutemov.name>

On Mon, Aug 02, 2021 at 09:37:37AM +0300, Mike Rapoport wrote:
> From: Mike Rapoport <rppt at linux.ibm.com>
> 
> There are a lot of uses of memblock_find_in_range() along with
> memblock_reserve() from the times memblock allocation APIs did not exist.
> 
> memblock_find_in_range() is the very core of memblock allocations, so any
> future changes to its internal behaviour would mandate updates of all the
> users outside memblock.
> 
> Replace the calls to memblock_find_in_range() with an equivalent calls to
> memblock_phys_alloc() and memblock_phys_alloc_range() and make
> memblock_find_in_range() private method of memblock.
> 
> This simplifies the callers, ensures that (unlikely) errors in
> memblock_reserve() are handled and improves maintainability of
> memblock_find_in_range().
> 
> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>

Looks good to me:

Acked-by: Kirill A. Shutemov <kirill.shtuemov at linux.intel.com>

-- 
 Kirill A. Shutemov


From Claudiu.Beznea at microchip.com  Mon Aug  2 01:36:52 2021
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Mon, 2 Aug 2021 08:36:52 +0000
Subject: [PATCH v2 0/6] clk: at91: updates for power management and dvfs
In-Reply-To: <20210401122726.28528-1-claudiu.beznea@microchip.com>
References: <20210401122726.28528-1-claudiu.beznea@microchip.com>
Message-ID: <6ecc4822-8112-43d4-1259-cd7dfe79d71c@microchip.com>

On 01.04.2021 15:27, Claudiu Beznea wrote:
> Hi,
> 
> This series addresses the power management for SAMA7G5 and also updates
> the master clock prescaller and master clock divider drivers to accommodate
> the requests at [1].
> 
> The power management part is implemented by adding
> save_context()/restore_context() on each clock driver (patch 1/6). Since
> the PM part is necessary only for backup mode (supported on SAMA5D2 and
> SAMA7G5) the pmc.c has been adapted to call the
> save_context()/restore_context() only on switches to/from backup mode
> (patch 2/6).
> 
> Patch 3/6 adds the securam clock on SAMA7G5. This is necessary for
> backup mode of SAMA7G5.
> 
> Patch 4/6 adds registers definitions for the new master clocks (MCK1..4) of
> SAMA7G5 and adapt the clk-master.c. The defines exported in
> include/linux/clk/at91_pmc.h will be also used by platform specific PM
> code.
> 
> Patch 5/6 adpat the master clock divider and master clock prescaller
> to address the requests at [1].
> 
> Patch 6/6 clean up a bit the code in clk-master as suggested by Nicolas.
> 
> Thank you,
> Claudiu Beznea
> 
> [1] https://lore.kernel.org/lkml/20210105104426.4tmgc2l3vyicwedd at vireshk-i7/
> 
> Changes in v2:
> - addressed code review comments
> - collected tags
> 
> Claudiu Beznea (6):
>   clk: at91: re-factor clocks suspend/resume
>   clk: at91: pmc: execute suspend/resume only for backup mode
>   clk: at91: sama7g5: add securam's peripheral clock
>   clk: at91: clk-master: add register definition for sama7g5's master
>     clock
>   
Hi Stephen,

Please ignore the DVFS patch in this series
(clk: at91: clk-master: update for dvfs) as I have some updates to it. I'll
introduce them in the next version.

Thank you,
Claudiu Beznea

From tzimmermann at suse.de  Mon Aug  2 01:42:27 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Mon, 2 Aug 2021 10:42:27 +0200
Subject: [PATCH 00/14] drm: Make DRM's IRQ helpers legacy
In-Reply-To: <YQcDCVuSM2kLbQcI@ravnborg.org>
References: <20210727182721.17981-1-tzimmermann@suse.de>
 <YQWbWjV5TYzp+5C4@ravnborg.org>
 <d50b3199-20fe-0ecb-ab7d-7425ad1d0f21@suse.de>
 <YQcDCVuSM2kLbQcI@ravnborg.org>
Message-ID: <7cbd968e-caec-0fdb-8f23-f3fb11664ce3@suse.de>

Hi Sam

Am 01.08.21 um 22:24 schrieb Sam Ravnborg:
> Hi Thomas,
> 
>>>
>>> 1) IRQ_NOTCONNECTED
>>>
>>> We do not have this check in drm_irq today and we should avoid spreading
>>> it all over. We are either carrying it forever or we wil lsee patches
>>> floating in to drop the check again.
>>> The current use in the kernel is minimal:
>>> https://elixir.bootlin.com/linux/latest/A/ident/IRQ_NOTCONNECTED
>>>
>>> So as a minimum drop it from atmel_hlcdc and preferably from the rest as
>>> it is really not used. (Speaking as atmel_hlcdc maintainer)
>>
>> I'll drop it from atmel_hlcdc then.
>>
>> But saying that it's not used is not correct.
> My point is the drm_irq do not check this - so adding this check add
> something there was not needed/done before.

What is being done at [1] is actually a check for unassigned interrupts. 
It's just that both, test and errno code, are plain wrong. The patchset 
fixes this.

> 
>>> 2) devm_request_irq()
>>>
>>> We are moving towards managed allocation so we do not fail to free
>>> resources. And an irq has a lifetime equal the device itself - so an
>>> obvious cnadidate for devm_request_irq.
>>> If we do not introduce it now we will see a revisit of this later.
>>> I can be convinced to wait with this as we will have to do much more in
>>> each driver, but I cannot see any good arguments to avoid the more
>>> modern way to use devm_request_irq.
>>
>> I'll change this in atmel_hdlcd and maybe I can find trivial cases where
>> devm_request_irq() can be used. But drivers that had an uninstall callback
>> before should not have the cleanup logic altered by a patch as this one. I
>> suspect that most of the IRQ cleanup
>> is actually a vblank cleanup and should be done in response to
>> drm_vblank_init(). But that's again not something for this patchset here. We
>> cannot change multiple things at once and still expect any of it to work.
>>
>> I welcome the use of devm_ et al. But these changes are better done in a
>> per-driver patchset that changes all of the driver to managed release.
> Fair enough, and fine with me.
> I have yet to read through all patches - will do so in the coming week.

OK, thanks a lot. I'll send out a new revision soon, so maybe don't 
waste time with this one.

Best regards
Thomas


[1] 
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_irq.c#L111



> 
> 	Sam
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Felix Imend?rffer

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/732acdb3/attachment.sig>

From tzimmermann at suse.de  Mon Aug  2 01:43:24 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Mon, 2 Aug 2021 10:43:24 +0200
Subject: [PATCH 01/14] drm/amdgpu: Convert to Linux IRQ interfaces
In-Reply-To: <CADnq5_MmPu=k3cc7JCg1iemkCDnoxR1T8PTD_VJn=58f5DwUNQ@mail.gmail.com>
References: <20210727182721.17981-1-tzimmermann@suse.de>
 <20210727182721.17981-2-tzimmermann@suse.de>
 <24a8b2ab-ef38-219b-99d4-806a44fa6aba@amd.com>
 <CADnq5_MmPu=k3cc7JCg1iemkCDnoxR1T8PTD_VJn=58f5DwUNQ@mail.gmail.com>
Message-ID: <0c321c93-ea2f-d12a-7057-5724d2d855bd@suse.de>

Hi

Am 28.07.21 um 16:03 schrieb Alex Deucher:
> On Wed, Jul 28, 2021 at 6:27 AM Christian K?nig
> <christian.koenig at amd.com> wrote:
>>
>> Am 27.07.21 um 20:27 schrieb Thomas Zimmermann:
>>> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
>>> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
>>> don't benefit from using it.
>>>
>>> DRM IRQ callbacks are now being called directly or inlined.
>>>
>>> The interrupt number returned by pci_msi_vector() is now stored
>>> in struct amdgpu_irq. Calls to pci_msi_vector() can fail and return
>>> a negative errno code. Abort initlaizaton in thi case. The DRM IRQ
>>> midlayer does not handle this correctly.
>>>
>>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>>
>> Alex needs to take a look at this as well, but of hand the patch is
>> Acked-by: Christian K?nig <christian.koenig at amd.com>.
> 
> Looks good to me as well:
> Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

Thanks a lot. Do you have comments on the changes to radeon?

Best regards
Thomas

> 
>>
>> Thanks,
>> Christian.
>>
>>> ---
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  1 -
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 21 ++++++++++++++-------
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |  2 +-
>>>    3 files changed, 15 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>>> index 2bd13fc2541a..1e05b5aa94e7 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>>> @@ -1775,7 +1775,6 @@ static const struct drm_driver amdgpu_kms_driver = {
>>>        .open = amdgpu_driver_open_kms,
>>>        .postclose = amdgpu_driver_postclose_kms,
>>>        .lastclose = amdgpu_driver_lastclose_kms,
>>> -     .irq_handler = amdgpu_irq_handler,
>>>        .ioctls = amdgpu_ioctls_kms,
>>>        .num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms),
>>>        .dumb_create = amdgpu_mode_dumb_create,
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>> index 0d01cfaca77e..a36cdc7323f4 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
>>> @@ -46,7 +46,6 @@
>>>    #include <linux/pci.h>
>>>
>>>    #include <drm/drm_crtc_helper.h>
>>> -#include <drm/drm_irq.h>
>>>    #include <drm/drm_vblank.h>
>>>    #include <drm/amdgpu_drm.h>
>>>    #include <drm/drm_drv.h>
>>> @@ -184,7 +183,7 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
>>>     * Returns:
>>>     * result of handling the IRQ, as defined by &irqreturn_t
>>>     */
>>> -irqreturn_t amdgpu_irq_handler(int irq, void *arg)
>>> +static irqreturn_t amdgpu_irq_handler(int irq, void *arg)
>>>    {
>>>        struct drm_device *dev = (struct drm_device *) arg;
>>>        struct amdgpu_device *adev = drm_to_adev(dev);
>>> @@ -307,6 +306,7 @@ static void amdgpu_restore_msix(struct amdgpu_device *adev)
>>>    int amdgpu_irq_init(struct amdgpu_device *adev)
>>>    {
>>>        int r = 0;
>>> +     unsigned int irq;
>>>
>>>        spin_lock_init(&adev->irq.lock);
>>>
>>> @@ -349,15 +349,22 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
>>>        INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2);
>>>        INIT_WORK(&adev->irq.ih_soft_work, amdgpu_irq_handle_ih_soft);
>>>
>>> -     adev->irq.installed = true;
>>> -     /* Use vector 0 for MSI-X */
>>> -     r = drm_irq_install(adev_to_drm(adev), pci_irq_vector(adev->pdev, 0));
>>> +     /* Use vector 0 for MSI-X. */
>>> +     r = pci_irq_vector(adev->pdev, 0);
>>> +     if (r < 0)
>>> +             return r;
>>> +     irq = r;
>>> +
>>> +     /* PCI devices require shared interrupts. */
>>> +     r = request_irq(irq, amdgpu_irq_handler, IRQF_SHARED, adev_to_drm(adev)->driver->name,
>>> +                     adev_to_drm(adev));
>>>        if (r) {
>>> -             adev->irq.installed = false;
>>>                if (!amdgpu_device_has_dc_support(adev))
>>>                        flush_work(&adev->hotplug_work);
>>>                return r;
>>>        }
>>> +     adev->irq.installed = true;
>>> +     adev->irq.irq = irq;
>>>        adev_to_drm(adev)->max_vblank_count = 0x00ffffff;
>>>
>>>        DRM_DEBUG("amdgpu: irq initialized.\n");
>>> @@ -368,7 +375,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
>>>    void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
>>>    {
>>>        if (adev->irq.installed) {
>>> -             drm_irq_uninstall(&adev->ddev);
>>> +             free_irq(adev->irq.irq, adev_to_drm(adev));
>>>                adev->irq.installed = false;
>>>                if (adev->irq.msi_enabled)
>>>                        pci_free_irq_vectors(adev->pdev);
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
>>> index 78ad4784cc74..e9f2c11ea416 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
>>> @@ -80,6 +80,7 @@ struct amdgpu_irq_src_funcs {
>>>
>>>    struct amdgpu_irq {
>>>        bool                            installed;
>>> +     unsigned int                    irq;
>>>        spinlock_t                      lock;
>>>        /* interrupt sources */
>>>        struct amdgpu_irq_client        client[AMDGPU_IRQ_CLIENTID_MAX];
>>> @@ -100,7 +101,6 @@ struct amdgpu_irq {
>>>    };
>>>
>>>    void amdgpu_irq_disable_all(struct amdgpu_device *adev);
>>> -irqreturn_t amdgpu_irq_handler(int irq, void *arg);
>>>
>>>    int amdgpu_irq_init(struct amdgpu_device *adev);
>>>    void amdgpu_irq_fini_sw(struct amdgpu_device *adev);
>>

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Felix Imend?rffer

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/8302d2cb/attachment-0001.sig>

From dietmar.eggemann at arm.com  Mon Aug  2 01:43:43 2021
From: dietmar.eggemann at arm.com (Dietmar Eggemann)
Date: Mon, 2 Aug 2021 10:43:43 +0200
Subject: WARNING: CPU: 112 PID: 2041 at kernel/sched/sched.h:1453
In-Reply-To: <CA+QYu4q3k8d60u5BwLy+mhRFjBd0cukiSmWAXRiMN2SbZ1XavQ@mail.gmail.com>
References: <CA+QYu4oOgrb8n=Qyuky-M0dYPEo_HNMdbNuj2SF4a=aQTE_xvw@mail.gmail.com>
 <d86333e7-bcde-2adb-e566-21ec97cda8bf@arm.com>
 <CA+QYu4rCRR_pNQVxSwGpzcLWJKLUA3F7LAtBiU9hPzz3D0k0Cg@mail.gmail.com>
 <f5b4beb9-4e75-0f4e-da8b-b7ccc12fee68@arm.com>
 <1ea2fa5c-ae81-2389-7f02-2227636582e4@arm.com>
 <CA+QYu4q3k8d60u5BwLy+mhRFjBd0cukiSmWAXRiMN2SbZ1XavQ@mail.gmail.com>
Message-ID: <972ea6f3-a000-84ee-cde0-7dc0f83d59fd@arm.com>

On 30/07/2021 17:23, Bruno Goncalves wrote:
> On Fri, Jul 30, 2021 at 2:22 PM Dietmar Eggemann
> <dietmar.eggemann at arm.com> wrote:
>>
>> On 29/07/2021 16:38, Dietmar Eggemann wrote:
>>> On 29/07/2021 14:36, Bruno Goncalves wrote:
>>>> On Wed, Jul 28, 2021 at 5:55 PM Dietmar Eggemann
>>>> <dietmar.eggemann at arm.com> wrote:
>>>>>
>>>>> On 28/07/2021 15:11, Bruno Goncalves wrote:

[...]

>> The task causing this seem to be the new `cppc_fie` DL task introduced
>> by commit 1eb5dde674f5 "cpufreq: CPPC: Add support for frequency
>> invariance" in v5.14-rc1.
>>
>> With `CONFIG_ACPI_CPPC_CPUFREQ_FIE=y` and schedutil cpufreq governor on
>> slow-switching system:
>>
>> DL task curr=`sugov:X` makes p=`cppc_fie` migrate and since it is in
>> `non_contending` state, migrate_task_rq_dl() calls
>>
>>   sub_running_bw()->__sub_running_bw()->cpufreq_update_util()->
>>   rq_clock()->assert_clock_updated()
>>
>> on p.
>>
>> Can you try this snippet? It should fix it.
> 
> Thank you, I've tried the patch and it fixes the issue.

Thanks for testing! Let me send out a proper patch then.


From yongqiang.niu at mediatek.com  Mon Aug  2 01:59:33 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 16:59:33 +0800
Subject: [PATCH v8, 2/2] soc: mediatek: mmsys: Add mt8192 mmsys routing table
In-Reply-To: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1627894773-23872-3-git-send-email-yongqiang.niu@mediatek.com>

mt8192 has different routing registers than mt8183

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 drivers/soc/mediatek/mt8192-mmsys.h | 67 +++++++++++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c    | 11 ++++++
 2 files changed, 78 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8192-mmsys.h

diff --git a/drivers/soc/mediatek/mt8192-mmsys.h b/drivers/soc/mediatek/mt8192-mmsys.h
new file mode 100644
index 0000000..0e4b233
--- /dev/null
+++ b/drivers/soc/mediatek/mt8192-mmsys.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8192_MMSYS_H
+#define __SOC_MEDIATEK_MT8192_MMSYS_H
+
+#define MT8192_MMSYS_OVL_MOUT_EN		0xf04
+#define MT8192_DISP_OVL1_2L_MOUT_EN		0xf08
+#define MT8192_DISP_OVL0_2L_MOUT_EN		0xf18
+#define MT8192_DISP_OVL0_MOUT_EN		0xf1c
+#define MT8192_DISP_RDMA0_SEL_IN		0xf2c
+#define MT8192_DISP_RDMA0_SOUT_SEL		0xf30
+#define MT8192_DISP_CCORR0_SOUT_SEL		0xf34
+#define MT8192_DISP_AAL0_SEL_IN			0xf38
+#define MT8192_DISP_DITHER0_MOUT_EN		0xf3c
+#define MT8192_DISP_DSI0_SEL_IN			0xf40
+#define MT8192_DISP_OVL2_2L_MOUT_EN		0xf4c
+
+#define MT8192_DISP_OVL0_GO_BLEND			BIT(0)
+#define MT8192_DITHER0_MOUT_IN_DSI0			BIT(0)
+#define MT8192_OVL0_MOUT_EN_DISP_RDMA0			BIT(0)
+#define MT8192_OVL2_2L_MOUT_EN_RDMA4			BIT(0)
+#define MT8192_DISP_OVL0_GO_BG				BIT(1)
+#define MT8192_DISP_OVL0_2L_GO_BLEND			BIT(2)
+#define MT8192_DISP_OVL0_2L_GO_BG			BIT(3)
+#define MT8192_OVL1_2L_MOUT_EN_RDMA1			BIT(4)
+#define MT8192_OVL0_MOUT_EN_OVL0_2L			BIT(4)
+#define MT8192_RDMA0_SEL_IN_OVL0_2L			0x3
+#define MT8192_RDMA0_SOUT_COLOR0			0x1
+#define MT8192_CCORR0_SOUT_AAL0				0x1
+#define MT8192_AAL0_SEL_IN_CCORR0			0x1
+#define MT8192_DSI0_SEL_IN_DITHER0			0x1
+
+static const struct mtk_mmsys_routes mmsys_mt8192_routing_table[] = {
+	{
+		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
+		MT8192_DISP_OVL0_2L_MOUT_EN, MT8192_OVL0_MOUT_EN_DISP_RDMA0,
+	}, {
+		DDP_COMPONENT_OVL_2L2, DDP_COMPONENT_RDMA4,
+		MT8192_DISP_OVL2_2L_MOUT_EN, MT8192_OVL2_2L_MOUT_EN_RDMA4
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8192_DISP_DITHER0_MOUT_EN, MT8192_DITHER0_MOUT_IN_DSI0
+	}, {
+		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
+		MT8192_DISP_RDMA0_SEL_IN, MT8192_RDMA0_SEL_IN_OVL0_2L
+	}, {
+		DDP_COMPONENT_CCORR, DDP_COMPONENT_AAL0,
+		MT8192_DISP_AAL0_SEL_IN, MT8192_AAL0_SEL_IN_CCORR0
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8192_DISP_DSI0_SEL_IN, MT8192_DSI0_SEL_IN_DITHER0
+	}, {
+		DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
+		MT8192_DISP_RDMA0_SOUT_SEL, MT8192_RDMA0_SOUT_COLOR0
+	}, {
+		DDP_COMPONENT_CCORR, DDP_COMPONENT_AAL0,
+		MT8192_DISP_CCORR0_SOUT_SEL, MT8192_CCORR0_SOUT_AAL0
+	}, {
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL_2L0,
+		MT8192_MMSYS_OVL_MOUT_EN, MT8192_DISP_OVL0_GO_BG,
+	}, {
+		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
+		MT8192_MMSYS_OVL_MOUT_EN, MT8192_DISP_OVL0_2L_GO_BLEND,
+	}
+};
+
+#endif /* __SOC_MEDIATEK_MT8192_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 080660e..de7b122 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -13,6 +13,7 @@
 #include "mtk-mmsys.h"
 #include "mt8167-mmsys.h"
 #include "mt8183-mmsys.h"
+#include "mt8192-mmsys.h"
 
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.clk_driver = "clk-mt2701-mm",
@@ -52,6 +53,12 @@
 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
+	.clk_driver = "clk-mt8192-mm",
+	.routes = mmsys_mt8192_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8192_routing_table),
+};
+
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
@@ -157,6 +164,10 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		.compatible = "mediatek,mt8183-mmsys",
 		.data = &mt8183_mmsys_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8192-mmsys",
+		.data = &mt8192_mmsys_driver_data,
+	},
 	{ }
 };
 
-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Mon Aug  2 01:59:31 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 16:59:31 +0800
Subject: [PATCH v8, 0/2] soc: mediatek: mmsys: add mt8192 mmsys support
Message-ID: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>

base v5.14-rc1

Yongqiang Niu (2):
  soc: mediatek: mmsys: add comp OVL_2L2/POSTMASK/RDMA4
  soc: mediatek: mmsys: Add mt8192 mmsys routing table

 drivers/soc/mediatek/mt8192-mmsys.h    | 67 ++++++++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 11 ++++++
 include/linux/soc/mediatek/mtk-mmsys.h |  3 ++
 3 files changed, 81 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8192-mmsys.h

-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Mon Aug  2 01:59:32 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Mon, 2 Aug 2021 16:59:32 +0800
Subject: [PATCH v8, 1/2] soc: mediatek: mmsys: add comp OVL_2L2/POSTMASK/RDMA4
In-Reply-To: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1627894773-23872-2-git-send-email-yongqiang.niu@mediatek.com>

This patch add some more ddp component
OVL_2L2 is ovl which include 2 layers overlay
POSTMASK control round corner for display frame
RDMA4 read dma buffer

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 include/linux/soc/mediatek/mtk-mmsys.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 2228bf6..4bba275 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -29,13 +29,16 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_OVL0,
 	DDP_COMPONENT_OVL_2L0,
 	DDP_COMPONENT_OVL_2L1,
+	DDP_COMPONENT_OVL_2L2,
 	DDP_COMPONENT_OVL1,
+	DDP_COMPONENT_POSTMASK0,
 	DDP_COMPONENT_PWM0,
 	DDP_COMPONENT_PWM1,
 	DDP_COMPONENT_PWM2,
 	DDP_COMPONENT_RDMA0,
 	DDP_COMPONENT_RDMA1,
 	DDP_COMPONENT_RDMA2,
+	DDP_COMPONENT_RDMA4,
 	DDP_COMPONENT_UFOE,
 	DDP_COMPONENT_WDMA0,
 	DDP_COMPONENT_WDMA1,
-- 
1.8.1.1.dirty

From icenowy at sipeed.com  Mon Aug  2 02:03:32 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon, 02 Aug 2021 17:03:32 +0800
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <20210802062212.73220-11-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-11-icenowy@sipeed.com>
Message-ID: <d8d69c0c38b96f23bf52fb169625e64d278a3c56.camel@sipeed.com>+88AC50AA4723D6F3

? 2021-08-02???? 14:22 +0800?Icenowy Zheng???
> Allwinner R329 has clock controls in PRCM, like other new Allwinner
> SoCs.
> 
> Add support for them.
> 
> This driver is added before the main CCU because PLLs are controlled
> by
> R-CCU on R329.

Well, I forgot to mention that the R_DMA bus clock gates/resets are not
documented on the user manual, and the info here is get by experiment.

There seems to be another hidden bus clock gate/reset according to a
register dump of R_CCU done on BSP kernel, but I have no idea what it
is.

> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
> ?drivers/clk/sunxi-ng/Kconfig????????????????? |?? 5 +
> ?drivers/clk/sunxi-ng/Makefile???????????????? |?? 1 +
> ?drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c????? | 374
> ++++++++++++++++++
> ?drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h????? |? 33 ++
> ?include/dt-bindings/clock/sun50i-r329-r-ccu.h |? 33 ++
> ?include/dt-bindings/reset/sun50i-r329-r-ccu.h |? 24 ++
> ?6 files changed, 470 insertions(+)
> ?create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> ?create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> ?create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
> ?create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
> 
> diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-
> ng/Kconfig
> index cd46d8853876..e49b2c2fa5b7 100644
> --- a/drivers/clk/sunxi-ng/Kconfig
> +++ b/drivers/clk/sunxi-ng/Kconfig
> @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
> ????????default ARM64 && ARCH_SUNXI
> ????????depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> ?
> +config SUN50I_R329_R_CCU
> +???????bool "Support for the Allwinner R329 PRCM CCU"
> +???????default ARM64 && ARCH_SUNXI
> +???????depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> +
> ?config SUN4I_A10_CCU
> ????????bool "Support for the Allwinner A10/A20 CCU"
> ????????default MACH_SUN4I
> diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-
> ng/Makefile
> index 96c324306d97..db338a2188fd 100644
> --- a/drivers/clk/sunxi-ng/Makefile
> +++ b/drivers/clk/sunxi-ng/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)???????+= ccu-
> sun50i-a100-r.o
> ?obj-$(CONFIG_SUN50I_H6_CCU)????+= ccu-sun50i-h6.o
> ?obj-$(CONFIG_SUN50I_H616_CCU)??+= ccu-sun50i-h616.o
> ?obj-$(CONFIG_SUN50I_H6_R_CCU)??+= ccu-sun50i-h6-r.o
> +obj-$(CONFIG_SUN50I_R329_R_CCU)????????+= ccu-sun50i-r329-r.o
> ?obj-$(CONFIG_SUN4I_A10_CCU)????+= ccu-sun4i-a10.o
> ?obj-$(CONFIG_SUN5I_CCU)????????????????+= ccu-sun5i.o
> ?obj-$(CONFIG_SUN6I_A31_CCU)????+= ccu-sun6i-a31.o
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> new file mode 100644
> index 000000000000..5413a701cb57
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> @@ -0,0 +1,374 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 Sipeed
> + * Based on the H616 CCU driver, which is:
> + *?? Copyright (c) 2020 Arm Ltd.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +
> +#include "ccu_common.h"
> +#include "ccu_reset.h"
> +
> +#include "ccu_div.h"
> +#include "ccu_gate.h"
> +#include "ccu_mp.h"
> +#include "ccu_mult.h"
> +#include "ccu_nk.h"
> +#include "ccu_nkm.h"
> +#include "ccu_nkmp.h"
> +#include "ccu_nm.h"
> +
> +#include "ccu-sun50i-r329-r.h"
> +
> +/*
> + * The M factor is present in the register's description, but not in
> the
> + * frequency formula, and it's documented as "The bit is only for
> + * testing", so it's not modelled and then force to 0.
> + */
> +#define SUN50I_R329_PLL_CPUX_REG???????0x1000
> +static struct ccu_mult pll_cpux_clk = {
> +???????.enable?????????= BIT(31),
> +???????.lock???????????= BIT(28),
> +???????.mult???????????= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +???????.common?????????= {
> +???????????????.reg????????????= 0x1000,
> +???????????????.hw.init????????= CLK_HW_INIT("pll-cpux", "osc24M",
> +???????????????????????????????????????????? &ccu_mult_ops,
> +???????????????????????????????????????????? CLK_SET_RATE_UNGATE),
> +???????},
> +};
> +
> +#define SUN50I_R329_PLL_PERIPH_REG?????0x1010
> +static struct ccu_nm pll_periph_base_clk = {
> +???????.enable?????????= BIT(31),
> +???????.lock???????????= BIT(28),
> +???????.n??????????????= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +???????.m??????????????= _SUNXI_CCU_DIV(1, 1), /* input divider */
> +???????.common?????????= {
> +???????????????.reg????????????= 0x1010,
> +???????????????.hw.init????????= CLK_HW_INIT("pll-periph-base",
> "osc24M",
> +???????????????????????????????????????????? &ccu_nm_ops,
> +???????????????????????????????????????????? CLK_SET_RATE_UNGATE),
> +???????},
> +};
> +
> +static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-
> base",
> +????????????????? 0x1010, 16, 3, 0);
> +static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m", "pll-
> periph-base",
> +????????????????? 0x1010, 20, 3, 0);
> +static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
> +????????????????????????? &pll_periph_2x_clk.common.hw, 2, 1, 0);
> +
> +#define SUN50I_R329_PLL_AUDIO0_REG?????0x1020
> +static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
> +???????{ .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64
> },
> +};
> +
> +static struct ccu_nm pll_audio0_clk = {
> +???????.enable?????????= BIT(31),
> +???????.lock???????????= BIT(28),
> +???????.n??????????????= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +???????.m??????????????= _SUNXI_CCU_DIV(1, 1),
> +???????.sdm????????????= _SUNXI_CCU_SDM(pll_audio0_sdm_table,
> +??????????????????????????????????????? BIT(24), 0x1120, BIT(31)),
> +???????.common?????????= {
> +???????????????.features???????= CCU_FEATURE_SIGMA_DELTA_MOD,
> +???????????????.reg????????????= 0x1020,
> +???????????????.hw.init????????= CLK_HW_INIT("pll-audio0", "osc24M",
> +???????????????????????????????????????????? &ccu_nm_ops,
> +???????????????????????????????????????????? CLK_SET_RATE_UNGATE),
> +???????},
> +};
> +
> +static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-
> audio0",
> +????????????????? 0x1020, 16, 3, 0);
> +static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-
> audio0",
> +????????????????? 0x1020, 20, 3, 0);
> +
> +/*
> + * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
> + * BSP driver always has M0 = 1 and M1 = 2 (this is also the
> + * reset value in the register).
> + *
> + * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
> + */
> +#define SUN50I_R329_PLL_AUDIO1_REG?????0x1030
> +static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
> +???????{ .rate = 22579200, .pattern = 0xc001288d, .m = 12, .n = 22
> },
> +???????{ .rate = 24576000, .pattern = 0xc00126e9, .m = 12, .n = 24
> },
> +???????{ .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 },
> +???????{ .rate = 98304000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
> +};
> +static struct ccu_nm pll_audio1_4x_clk = {
> +???????.enable?????????= BIT(31),
> +???????.lock???????????= BIT(28),
> +???????.n??????????????= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +???????.m??????????????= _SUNXI_CCU_DIV(16, 6),
> +???????.fixed_post_div?= 2,
> +???????.sdm????????????= _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
> +??????????????????????????????????????? BIT(24), 0x1130, BIT(31)),
> +???????.common?????????= {
> +???????????????.features???????= CCU_FEATURE_FIXED_POSTDIV |
> +???????????????????????????????? CCU_FEATURE_SIGMA_DELTA_MOD,
> +???????????????.reg????????????= 0x1030,
> +???????????????.hw.init????????= CLK_HW_INIT("pll-audio1-4x",
> "osc24M",
> +???????????????????????????????????????????? &ccu_nm_ops,
> +???????????????????????????????????????????? CLK_SET_RATE_UNGATE),
> +???????},
> +};
> +
> +static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
> +????????????????????????? &pll_audio1_4x_clk.common.hw, 2, 1,
> +????????????????????????? CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
> +????????????????????????? &pll_audio1_4x_clk.common.hw, 4, 1,
> +????????????????????????? CLK_SET_RATE_PARENT);
> +
> +static const char * const r_bus_parents[] = { "osc24M", "osc32k",
> "iosc",
> +???????????????????????????????????????????? "pll-periph-2x",
> +???????????????????????????????????????????? "pll-audio0-div2" };
> +static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents,
> 0x000,
> +??????????????????????????? 0, 5,??????/* M */
> +??????????????????????????? 8, 2,??????/* P */
> +??????????????????????????? 24, 3,?????/* mux */
> +??????????????????????????? 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents,
> 0x00c,
> +??????????????????????????? 0, 5,??????/* M */
> +??????????????????????????? 8, 2,??????/* P */
> +??????????????????????????? 24, 3,?????/* mux */
> +??????????????????????????? 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents,
> 0x010,
> +??????????????????????????? 0, 5,??????/* M */
> +??????????????????????????? 8, 2,??????/* P */
> +??????????????????????????? 24, 3,?????/* mux */
> +??????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
> +???????????????????? 0x0ec, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc,
> BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c,
> BIT(0), 0);
> +
> +static const char * const r_pwm_parents[] = { "osc24M", "osc32k",
> "iosc" };
> +static SUNXI_CCU_MUX_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents,
> 0x130,
> +????????????????????????????? 24, 3,???/* mux */
> +????????????????????????????? BIT(31),?/* gate */
> +????????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c,
> BIT(0), 0);
> +
> +static const char * const r_audio_parents[] = { "pll-audio0-div5",
> "pll-audio0-div2",
> +???????????????????????????????????????????????"pll-audio1-1x",
> "pll-audio1-4x" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc",
> r_audio_parents, 0x140,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac",
> r_audio_parents, 0x144,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
> +???????????????????? 0x14c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic",
> r_audio_parents, 0x150,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c,
> BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc", "r-apb1",
> +???????????????????? 0x16c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s",
> r_audio_parents, 0x170,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
> +???????????????????????????????? r_audio_parents, 0x174,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c,
> BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart", "r-apb2", 0x18c,
> BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_i2c_clk, "r-bus-i2c", "r-apb2", 0x19c,
> BIT(0), 0);
> +
> +static const char * const r_ir_parents[] = { "osc32k", "osc24M" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents,
> 0x1c0,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc,
> BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
> +???????????????????? 0x1dc, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-
> apb1",
> +???????????????????? 0x1ec, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
> +???????????????????? 0x20c, BIT(0), CLK_IS_CRITICAL);
> +
> +static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
> +???????&pll_cpux_clk.common,
> +???????&pll_periph_base_clk.common,
> +???????&pll_periph_2x_clk.common,
> +???????&pll_periph_800m_clk.common,
> +???????&pll_audio0_clk.common,
> +???????&pll_audio0_div2_clk.common,
> +???????&pll_audio0_div5_clk.common,
> +???????&pll_audio1_4x_clk.common,
> +???????&r_ahb_clk.common,
> +???????&r_apb1_clk.common,
> +???????&r_apb2_clk.common,
> +???????&r_bus_gpadc_clk.common,
> +???????&r_bus_ths_clk.common,
> +???????&r_bus_dma_clk.common,
> +???????&r_pwm_clk.common,
> +???????&r_bus_pwm_clk.common,
> +???????&r_codec_adc_clk.common,
> +???????&r_codec_dac_clk.common,
> +???????&r_bus_codec_clk.common,
> +???????&r_dmic_clk.common,
> +???????&r_bus_dmic_clk.common,
> +???????&r_bus_lradc_clk.common,
> +???????&r_i2s_clk.common,
> +???????&r_i2s_asrc_clk.common,
> +???????&r_bus_i2s_clk.common,
> +???????&r_bus_uart_clk.common,
> +???????&r_bus_i2c_clk.common,
> +???????&r_ir_clk.common,
> +???????&r_bus_ir_clk.common,
> +???????&r_bus_msgbox_clk.common,
> +???????&r_bus_spinlock_clk.common,
> +???????&r_bus_rtc_clk.common,
> +};
> +
> +static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
> +???????.hws????= {
> +???????????????[CLK_PLL_CPUX]??????????= &pll_cpux_clk.common.hw,
> +???????????????[CLK_PLL_PERIPH_BASE]???=
> &pll_periph_base_clk.common.hw,
> +???????????????[CLK_PLL_PERIPH_2X]?????=
> &pll_periph_2x_clk.common.hw,
> +???????????????[CLK_PLL_PERIPH_800M]???=
> &pll_periph_800m_clk.common.hw,
> +???????????????[CLK_PLL_PERIPH]????????= &pll_periph_clk.hw,
> +???????????????[CLK_PLL_AUDIO0]????????= &pll_audio0_clk.common.hw,
> +???????????????[CLK_PLL_AUDIO0_DIV2]???=
> &pll_audio0_div2_clk.common.hw,
> +???????????????[CLK_PLL_AUDIO0_DIV5]???=
> &pll_audio0_div5_clk.common.hw,
> +???????????????[CLK_PLL_AUDIO1_4X]?????=
> &pll_audio1_4x_clk.common.hw,
> +???????????????[CLK_PLL_AUDIO1_2X]?????= &pll_audio1_2x_clk.hw,
> +???????????????[CLK_PLL_AUDIO1]????????= &pll_audio1_clk.hw,
> +???????????????[CLK_R_AHB]?????????????= &r_ahb_clk.common.hw,
> +???????????????[CLK_R_APB1]????????????= &r_apb1_clk.common.hw,
> +???????????????[CLK_R_APB2]????????????= &r_apb2_clk.common.hw,
> +???????????????[CLK_R_BUS_GPADC]???????= &r_bus_gpadc_clk.common.hw,
> +???????????????[CLK_R_BUS_THS]?????????= &r_bus_ths_clk.common.hw,
> +???????????????[CLK_R_BUS_DMA]?????????= &r_bus_dma_clk.common.hw,
> +???????????????[CLK_R_PWM]?????????????= &r_pwm_clk.common.hw,
> +???????????????[CLK_R_BUS_PWM]?????????= &r_bus_pwm_clk.common.hw,
> +???????????????[CLK_R_CODEC_ADC]???????= &r_codec_adc_clk.common.hw,
> +???????????????[CLK_R_CODEC_DAC]???????= &r_codec_dac_clk.common.hw,
> +???????????????[CLK_R_BUS_CODEC]???????= &r_bus_codec_clk.common.hw,
> +???????????????[CLK_R_DMIC]????????????= &r_dmic_clk.common.hw,
> +???????????????[CLK_R_BUS_DMIC]????????= &r_bus_dmic_clk.common.hw,
> +???????????????[CLK_R_BUS_LRADC]???????= &r_bus_lradc_clk.common.hw,
> +???????????????[CLK_R_I2S]?????????????= &r_i2s_clk.common.hw,
> +???????????????[CLK_R_I2S_ASRC]????????= &r_i2s_asrc_clk.common.hw,
> +???????????????[CLK_R_BUS_I2S]?????????= &r_bus_i2s_clk.common.hw,
> +???????????????[CLK_R_BUS_UART]????????= &r_bus_uart_clk.common.hw,
> +???????????????[CLK_R_BUS_I2C]?????????= &r_bus_i2c_clk.common.hw,
> +???????????????[CLK_R_IR]??????????????= &r_ir_clk.common.hw,
> +???????????????[CLK_R_BUS_IR]??????????= &r_bus_ir_clk.common.hw,
> +???????????????[CLK_R_BUS_MSGBOX]??????=
> &r_bus_msgbox_clk.common.hw,
> +???????????????[CLK_R_BUS_SPINLOCK]????=
> &r_bus_spinlock_clk.common.hw,
> +???????????????[CLK_R_BUS_RTC]?????????= &r_bus_rtc_clk.common.hw,
> +???????},
> +???????.num = CLK_NUMBER,
> +};
> +
> +static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
> +???????[RST_R_BUS_GPADC]???????= { 0x0ec, BIT(16) },
> +???????[RST_R_BUS_THS]?????????= { 0x0fc, BIT(16) },
> +???????[RST_R_BUS_DMA]?????????= { 0x10c, BIT(16) },
> +???????[RST_R_BUS_PWM]?????????= { 0x13c, BIT(16) },
> +???????[RST_R_BUS_CODEC]???????= { 0x14c, BIT(16) },
> +???????[RST_R_BUS_DMIC]????????= { 0x15c, BIT(16) },
> +???????[RST_R_BUS_LRADC]???????= { 0x16c, BIT(16) },
> +???????[RST_R_BUS_I2S]?????????= { 0x17c, BIT(16) },
> +???????[RST_R_BUS_UART]????????= { 0x18c, BIT(16) },
> +???????[RST_R_BUS_I2C]?????????= { 0x19c, BIT(16) },
> +???????[RST_R_BUS_IR]??????????= { 0x1cc, BIT(16) },
> +???????[RST_R_BUS_MSGBOX]??????= { 0x1dc, BIT(16) },
> +???????[RST_R_BUS_SPINLOCK]????= { 0x1ec, BIT(16) },
> +???????[RST_R_BUS_RTC]?????????= { 0x20c, BIT(16) },
> +};
> +
> +static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
> +???????.ccu_clks???????= sun50i_r329_r_ccu_clks,
> +???????.num_ccu_clks???= ARRAY_SIZE(sun50i_r329_r_ccu_clks),
> +
> +???????.hw_clks????????= &sun50i_r329_r_hw_clks,
> +
> +???????.resets?????????= sun50i_r329_r_ccu_resets,
> +???????.num_resets?????= ARRAY_SIZE(sun50i_r329_r_ccu_resets),
> +};
> +
> +static const u32 pll_regs[] = {
> +???????SUN50I_R329_PLL_CPUX_REG,
> +???????SUN50I_R329_PLL_PERIPH_REG,
> +???????SUN50I_R329_PLL_AUDIO0_REG,
> +???????SUN50I_R329_PLL_AUDIO1_REG,
> +};
> +
> +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> +{
> +???????void __iomem *reg;
> +???????u32 val;
> +???????int i;
> +
> +???????reg = of_io_request_and_map(node, 0,
> of_node_full_name(node));
> +???????if (IS_ERR(reg)) {
> +???????????????pr_err("%pOF: Could not map clock registers\n",
> node);
> +???????????????return;
> +???????}
> +
> +???????/* Enable the lock bits and the output enable bits on all
> PLLs */
> +???????for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> +???????????????val = readl(reg + pll_regs[i]);
> +???????????????val |= BIT(29) | BIT(27);
> +???????????????writel(val, reg + pll_regs[i]);
> +???????}
> +
> +???????/*
> +??????? * Force the I/O dividers of PLL-AUDIO1 to reset default
> value
> +??????? *
> +??????? * See the comment before pll-audio1 definition for the
> reason.
> +??????? */
> +
> +???????val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> +???????val &= ~BIT(1);
> +???????val |= BIT(0);
> +???????writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> +
> +???????i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> +???????if (i)
> +???????????????pr_err("%pOF: probing clocks fails: %d\n", node, i);
> +}
> +
> +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> +????????????? sun50i_r329_r_ccu_setup);
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> new file mode 100644
> index 000000000000..62cf65322116
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _CCU_SUN50I_R329_R_H
> +#define _CCU_SUN50I_R329_R_H
> +
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +#define CLK_PLL_CPUX???????????0
> +#define CLK_PLL_PERIPH_BASE????1
> +#define CLK_PLL_PERIPH_2X??????2
> +#define CLK_PLL_PERIPH_800M????3
> +#define CLK_PLL_PERIPH?????????4
> +#define CLK_PLL_AUDIO0?????????5
> +#define CLK_PLL_AUDIO0_DIV2????6
> +#define CLK_PLL_AUDIO0_DIV5????7
> +#define CLK_PLL_AUDIO1_4X??????8
> +#define CLK_PLL_AUDIO1_2X??????9
> +#define CLK_PLL_AUDIO1?????????10
> +#define CLK_R_AHB??????????????11
> +
> +/* R_APB1 exported for PIO */
> +
> +#define CLK_R_APB2?????????????13
> +
> +/* All module / bus gate clocks exported */
> +
> +#define CLK_NUMBER?????(CLK_R_BUS_RTC + 1)
> +
> +#endif /* _CCU_SUN50I_R329_R_H */
> diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..df9bc58de5c4
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +
> +#define CLK_R_APB1?????????????12
> +
> +#define CLK_R_BUS_GPADC????????????????14
> +#define CLK_R_BUS_THS??????????15
> +#define CLK_R_BUS_DMA??????????16
> +#define CLK_R_PWM??????????????17
> +#define CLK_R_BUS_PWM??????????18
> +#define CLK_R_CODEC_ADC????????????????19
> +#define CLK_R_CODEC_DAC????????????????20
> +#define CLK_R_BUS_CODEC????????????????21
> +#define CLK_R_DMIC?????????????22
> +#define CLK_R_BUS_DMIC?????????23
> +#define CLK_R_BUS_LRADC????????????????24
> +#define CLK_R_I2S??????????????25
> +#define CLK_R_I2S_ASRC?????????26
> +#define CLK_R_BUS_I2S??????????27
> +#define CLK_R_BUS_UART?????????28
> +#define CLK_R_BUS_I2C??????????29
> +#define CLK_R_IR???????????????30
> +#define CLK_R_BUS_IR???????????31
> +#define CLK_R_BUS_MSGBOX???????32
> +#define CLK_R_BUS_SPINLOCK?????33
> +#define CLK_R_BUS_RTC??????????34
> +
> +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
> diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..40644f2f21c6
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +
> +#define RST_R_BUS_GPADC????????????????0
> +#define RST_R_BUS_THS??????????1
> +#define RST_R_BUS_DMA??????????2
> +#define RST_R_BUS_PWM??????????3
> +#define RST_R_BUS_CODEC????????????????4
> +#define RST_R_BUS_DMIC?????????5
> +#define RST_R_BUS_LRADC????????????????6
> +#define RST_R_BUS_I2S??????????7
> +#define RST_R_BUS_UART?????????8
> +#define RST_R_BUS_I2C??????????9
> +#define RST_R_BUS_IR???????????10
> +#define RST_R_BUS_MSGBOX???????11
> +#define RST_R_BUS_SPINLOCK?????12
> +#define RST_R_BUS_RTC??????????13
> +
> +#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */




From anshuman.khandual at arm.com  Mon Aug  2 02:12:00 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 2 Aug 2021 14:42:00 +0530
Subject: [PATCH 10/10] arm64: errata: Add workaround for TSB flush failures
In-Reply-To: <c41330d9-c2a2-afbe-624f-77c1e94f0490@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-11-suzuki.poulose@arm.com>
 <87mtq5a1gs.wl-maz@kernel.org> <c41330d9-c2a2-afbe-624f-77c1e94f0490@arm.com>
Message-ID: <477c4943-7c35-8502-0291-4c0ed3a03905@arm.com>



On 7/29/21 4:11 PM, Suzuki K Poulose wrote:
> On 29/07/2021 10:55, Marc Zyngier wrote:
>> On Wed, 28 Jul 2021 14:52:17 +0100,
>> Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>>>
>>> Arm Neoverse-N2 (#2067961) and Cortex-A710 (#2054223) suffers
>>> from errata, where a TSB (trace synchronization barrier)
>>> fails to flush the trace data completely, when executed from
>>> a trace prohibited region. In Linux we always execute it
>>> after we have moved the PE to trace prohibited region. So,
>>> we can apply the workaround everytime a TSB is executed.
>>>
>>> The work around is to issue two TSB consecutively.
>>>
>>> NOTE: This errata is defined as LOCAL_CPU_ERRATUM, implying
>>> that a late CPU could be blocked from booting if it is the
>>> first CPU that requires the workaround. This is because we
>>> do not allow setting a cpu_hwcaps after the SMP boot. The
>>> other alternative is to use "this_cpu_has_cap()" instead
>>> of the faster system wide check, which may be a bit of an
>>> overhead, given we may have to do this in nvhe KVM host
>>> before a guest entry.
>>>
>>> Cc: Will Deacon <will at kernel.org>
>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>>> Cc: Mike Leach <mike.leach at linaro.org>
>>> Cc: Mark Rutland <mark.rutland at arm.com>
>>> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
>>> Cc: Marc Zyngier <maz at kernel.org>
>>> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
>>> ---
>>> ? Documentation/arm64/silicon-errata.rst |? 4 ++++
>>> ? arch/arm64/Kconfig???????????????????? | 31 ++++++++++++++++++++++++++
>>> ? arch/arm64/include/asm/barrier.h?????? | 17 +++++++++++++-
>>> ? arch/arm64/kernel/cpu_errata.c???????? | 19 ++++++++++++++++
>>> ? arch/arm64/tools/cpucaps?????????????? |? 1 +
>>> ? 5 files changed, 71 insertions(+), 1 deletion(-)
>>
>> [...]
>>
>>> diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
>>> index 451e11e5fd23..3bc1ed436e04 100644
>>> --- a/arch/arm64/include/asm/barrier.h
>>> +++ b/arch/arm64/include/asm/barrier.h
>>> @@ -23,7 +23,7 @@
>>> ? #define dsb(opt)??? asm volatile("dsb " #opt : : : "memory")
>>> ? ? #define psb_csync()??? asm volatile("hint #17" : : : "memory")
>>> -#define tsb_csync()??? asm volatile("hint #18" : : : "memory")
>>> +#define __tsb_csync()??? asm volatile("hint #18" : : : "memory")
>>> ? #define csdb()??????? asm volatile("hint #20" : : : "memory")
>>> ? ? #ifdef CONFIG_ARM64_PSEUDO_NMI
>>> @@ -46,6 +46,21 @@
>>> ? #define dma_rmb()??? dmb(oshld)
>>> ? #define dma_wmb()??? dmb(oshst)
>>> ? +
>>> +#define tsb_csync()??????????????????????????????? \
>>> +??? do {??????????????????????????????????? \
>>> +??????? /*??????????????????????????????? \
>>> +???????? * CPUs affected by Arm Erratum 2054223 or 2067961 needs??? \
>>> +???????? * another TSB to ensure the trace is flushed.??????????? \
>>> +???????? */??????????????????????????????? \
>>> +??????? if (cpus_have_const_cap(ARM64_WORKAROUND_TSB_FLUSH_FAILURE)) {??? \
>>
>> Could this be made a final cap instead? Or do you expect this to be
>> usable before caps have been finalised?
> 
> Good point. This can be final cap.
> 
>>
>>> +??????????? __tsb_csync();??????????????????????? \
>>> +??????????? __tsb_csync();??????????????????????? \
>>> +??????? } else {??????????????????????????? \
>>> +??????????? __tsb_csync();??????????????????????? \
>>> +??????? }??????????????????????????????? \
>>
>> nit: You could keep one unconditional __tsb_csync().
> 
> I thought about that, I was worried if the CPU expects them back to back
> without any other instructions in between them. Thinking about it a bit
> more, it doesn't look like that is the case. I will confirm this and
> change it accordingly.
But its a very subtle change which might be difficult to debug and blame
later on, if indeed both the instructions need to be back to back. Seems
like just better to leave this unchanged.


From o.rempel at pengutronix.de  Mon Aug  2 02:21:00 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Mon, 2 Aug 2021 11:21:00 +0200
Subject: [PATCH v2 4/4] ARM: dts: add SKOV imx6q and imx6dl based boards
In-Reply-To: <20210726012043.GC5901@dragon>
References: <20210714045349.10963-1-o.rempel@pengutronix.de>
 <20210714045349.10963-5-o.rempel@pengutronix.de>
 <20210726012043.GC5901@dragon>
Message-ID: <20210802092100.ctkncu6g4ka4rvtt@pengutronix.de>

[...]
> > +	reg_vcc_mmc_io: regulator-vcc-mmc-io {
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&pinctrl_vcc_mmc_io>;
> > +		compatible = "regulator-gpio";
> > +		vin-supply = <&reg_5v0>;
> > +		regulator-name = "mmc_io_supply";
> > +		regulator-type = "voltage";
> > +		regulator-min-microvolt = <1800000>;
> > +		regulator-max-microvolt = <3300000>;
> > +		gpios = <&gpio7 13 GPIO_ACTIVE_HIGH>;
> 
> enable-active-high?

right, thx!

> > +		states = <1800000 0x1>, <3300000 0x0>;
> 
> Hmm, I do not see this 'states' in fixed-regulator.yaml.

It is in gpio-regulator.yaml

Regards,
Oleksij
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From joro at 8bytes.org  Mon Aug  2 02:22:40 2021
From: joro at 8bytes.org (joro at 8bytes.org)
Date: Mon, 2 Aug 2021 11:22:40 +0200
Subject: [PATCH v6 0/9] ACPI/IORT: Support for IORT RMR node
In-Reply-To: <014a451d00304b80b3de700817d688de@huawei.com>
References: <20210716083442.1708-1-shameerali.kolothum.thodi@huawei.com>
 <35db3320-d6e2-721e-8d49-e5e2e80e2359@nxp.com>
 <014a451d00304b80b3de700817d688de@huawei.com>
Message-ID: <YQe5YOZPvOIucqng@8bytes.org>

On Tue, Jul 27, 2021 at 06:51:56AM +0000, Shameerali Kolothum Thodi wrote:
> A gentle ping on this...

This needs more reviews, and please add

	Will Deacon <will at kernel.org>

when you post the next version of this patch-set.

Regards,

	Joerg


From anshuman.khandual at arm.com  Mon Aug  2 02:34:42 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 2 Aug 2021 15:04:42 +0530
Subject: [PATCH 09/10] arm64: Enable workaround for TRBE overwrite in FILL
 mode
In-Reply-To: <20210728135217.591173-10-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-10-suzuki.poulose@arm.com>
Message-ID: <d07995fd-90a2-34d7-31c6-417ef1469a75@arm.com>



On 7/28/21 7:22 PM, Suzuki K Poulose wrote:
> Now that we have the work around implmented in the TRBE

				Typo ^^^^^

> driver, add the Kconfig entries and document the errata.
> 
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
>  Documentation/arm64/silicon-errata.rst |  4 +++
>  arch/arm64/Kconfig                     | 39 ++++++++++++++++++++++++++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index d410a47ffa57..2f99229d993c 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -92,12 +92,16 @@ stable kernels.
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A77      | #1508412        | ARM64_ERRATUM_1508412       |
>  +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
> ++----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Neoverse-N1     | #1188873,1418040| ARM64_ERRATUM_1418040       |
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Neoverse-N1     | #1349291        | N/A                         |
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Neoverse-N1     | #1542419        | ARM64_ERRATUM_1542419       |
>  +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Neoverse-N2     | #2139208        | ARM64_ERRATUM_2139208       |
> ++----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | MMU-500         | #841119,826419  | N/A                         |
>  +----------------+-----------------+-----------------+-----------------------------+
>  +----------------+-----------------+-----------------+-----------------------------+
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b5b13a932561..ad301045dafc 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -669,6 +669,45 @@ config ARM64_ERRATUM_1508412
>  
>  	  If unsure, say Y.
>  
> +config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
> +	bool

Should this be moved to the earlier patch (7/10) which detects the erratum ?
Might be better to add the definition in Kconfig (even though not selected)
when using it for the first time. 

> +
> +config ARM64_ERRATUM_2119858
> +	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
> +	default y
> +	depends on CORESIGHT_TRBE
> +	select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
> +	help
> +	  This option adds the workaround for ARM Cortex-A710 erratum 2119858.
> +
> +	  Affected Cortex-A710 cores could overwrite upto 3 cache lines of trace
> +	  data at the base of the buffer (ponited by TRBASER_EL1) in FILL mode in

				Typo	  ^^^^^^

> +	  the event of a WRAP event.
> +
> +	  Work around the issue by always making sure we move the TRBPTR_EL1 by
> +	  256bytes before enabling the buffer and filling the first 256bytes of

Nit:   space ^^							space ^^

> +	  the buffer with ETM ignore packets upon disabling.
> +
> +	  If unsure, say Y.
> +
> +config ARM64_ERRATUM_2139208
> +	bool "Neoverse-N2: 2139208: workaround TRBE overwriting trace data in FILL mode"
> +	default y
> +	depends on CORESIGHT_TRBE
> +	select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
> +	help
> +	  This option adds the workaround for ARM Neoverse-N2 erratum 2139208.
> +
> +	  Affected Neoverse-N2 cores could overwrite upto 3 cache lines of trace
> +	  data at the base of the buffer (ponited by TRBASER_EL1) in FILL mode in

				Typo	  ^^^^^^

> +	  the event of a WRAP event.
> +
> +	  Work around the issue by always making sure we move the TRBPTR_EL1 by
> +	  256bytes before enabling the buffer and filling the first 256bytes of

Nit:   space ^^							space ^^

> +	  the buffer with ETM ignore packets upon disabling.
> +
> +	  If unsure, say Y.
> +
>  config CAVIUM_ERRATUM_22375
>  	bool "Cavium erratum 22375, 24313"
>  	default y
> 

Otherwise LGTM.

Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>


From maz at kernel.org  Mon Aug  2 02:35:12 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Aug 2021 10:35:12 +0100
Subject: [PATCH 10/10] arm64: errata: Add workaround for TSB flush failures
In-Reply-To: <477c4943-7c35-8502-0291-4c0ed3a03905@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-11-suzuki.poulose@arm.com>
 <87mtq5a1gs.wl-maz@kernel.org>
 <c41330d9-c2a2-afbe-624f-77c1e94f0490@arm.com>
 <477c4943-7c35-8502-0291-4c0ed3a03905@arm.com>
Message-ID: <32f719c8f9f61b244b3fc29137f76a19@kernel.org>

On 2021-08-02 10:12, Anshuman Khandual wrote:
> On 7/29/21 4:11 PM, Suzuki K Poulose wrote:
>> On 29/07/2021 10:55, Marc Zyngier wrote:
>>> On Wed, 28 Jul 2021 14:52:17 +0100,
>>> Suzuki K Poulose <suzuki.poulose at arm.com>

[...]

>>>> +??????????? __tsb_csync();??????????????????????? \
>>>> +??????????? __tsb_csync();??????????????????????? \
>>>> +??????? } else {??????????????????????????? \
>>>> +??????????? __tsb_csync();??????????????????????? \
>>>> +??????? }??????????????????????????????? \
>>> 
>>> nit: You could keep one unconditional __tsb_csync().
>> 
>> I thought about that, I was worried if the CPU expects them back to 
>> back
>> without any other instructions in between them. Thinking about it a 
>> bit
>> more, it doesn't look like that is the case. I will confirm this and
>> change it accordingly.
> But its a very subtle change which might be difficult to debug and 
> blame
> later on, if indeed both the instructions need to be back to back. 
> Seems
> like just better to leave this unchanged.

Is that an actual requirement? Sounds like you want to find out
from the errata document.

And if they actually need to be back to back, what ensures that
this is always called with interrupt disabled?

You would also need to have them in the same asm block to avoid
the compiler reordering stuff.

         M.
-- 
Jazz is not dead. It just smells funny...


From Jonathan.Cameron at Huawei.com  Mon Aug  2 02:36:38 2021
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Mon, 2 Aug 2021 10:36:38 +0100
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
References: <20210722060654.nudpdtemosi64nlb@pengutronix.de>
 <YPkg0wtYIoHKpTUW@kunai>
 <20210722081817.2tsjzof4gvldq6ka@pengutronix.de>
 <YPlfcbkxiBmB+vw1@kunai>
 <CAHp75VfC=s12Unw3+Cn0ag71mM5i90=Jbwj4nYwB5cPKiUTRSA@mail.gmail.com>
 <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
Message-ID: <20210802103638.00000448@Huawei.com>

On Sat, 31 Jul 2021 14:00:04 +0200
Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de> wrote:

> Hi Russell, hi Stephen,
> 
> On Sat, Jul 31, 2021 at 12:41:19AM -0700, Stephen Boyd wrote:
> > Quoting Russell King (Oracle) (2021-07-28 13:40:34)  
> > > > I adapted the Subject in the hope to catch Stephen's and Michael's
> > > > attention. My impression is that this thread isn't on their radar yet,
> > > > but the topic here seems important enough to get a matching Subject.  
> > 
> > The thread is on my radar but...
> >   
> > > 
> > > Have you thought about sending your pull request to the clk API
> > > maintainer (iow, me) ?  
> 
> I wasn't really aware that Russell has the clk API hat (or that this
> separate hat actually exists and this isn't purely a CCF topic). I
> assume I only did
> 
> 	$ scripts/get_maintainer.pl -f drivers/clk/clk-devres.c
> 
> which is where the current and new code implementing devm_clk_get et al
> lives.
> 
> @Russell: What is your position here, do you like the approach of
> devm_clk_get_enabled? I can send a new pull request in your direction if
> you like it and are willing to take it.
> 
> > +1 This patch doesn't fall under CCF maintainer.  
> 
> Given that CCF is the only implementer of devm_clk_get at least an Ack
> from your side would still be good I guess?
> 
> > Finally, this sort of patch has been discussed for years and I didn't
> > see any mention of those previous attempts in the patch series. Has
> > something changed since that time? I think we've got a bunch of hand
> > rolled devm things in the meantime but not much else.   
> 
> I found a patch set adding devm variants of clk_enable (e.g.
> https://lore.kernel.org/patchwork/patch/755667/) but this approach is
> different as it also contains clk_get which IMHO makes more sense 
> The discussion considered wrapping get+enable at one point, but I didn't
> find a followup.
> 
> > I still wonder if it would be better if we had some sort of DT binding
> > that said "turn this clk on when the driver probes this device and keep
> > it on until the driver is unbound".  
> 
> This doesn't sound like a hardware property and so I don't think this
> belongs into DT and I would be surprised if the dt maintainers would be
> willing to accept an idea with this semantic.

Agreed. It's not unheard of to have a driver start out just enabing
clock at probe and dropping it at remove. When the driver gets more
sophisticated it will then manage the clock more frequently.
Whilst that's often tied to runtime_pm I'm not sure it always is.

Given the mess that would be involved in having a property that we
need to later ignore for particular drivers, I'd keep this management
explicit in the driver. This series makes that trivial to do for these
easy cases.

Jonathan

> 
> > That would probably work well for quite a few drivers that don't want
> > to ever call clk_get() or clk_prepare_enable() and could tie into the
> > assigned-clock-rates property in a way that let us keep the platform
> > details out of the drivers. We could also go one step further and make
> > a clk pm domain when this new property is present and then have the
> > clk be enabled based on runtime PM of the device (and if runtime PM is
> > disabled then just enable it at driver probe time).  
> 
> clk pm domain sounds good, but introducing devm_clk_get_enabled() is
> much easier and converting to it can be done without dt changes and more
> or less mechanically. So I consider the cost-usage-value of
> devm_clk_get_enabled() much better.
> 
> Best regards
> Uwe
> 



From tabba at google.com  Mon Aug  2 02:36:42 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 11:36:42 +0200
Subject: [PATCH v3 03/21] KVM: arm64: Provide the host_stage2_try() helper
 macro
In-Reply-To: <20210729132818.4091769-4-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-4-qperret@google.com>
Message-ID: <CA+EHjTzrqbyHQyo7X-=MeJXQ5bVcfUz0uiUKVAv_U+aqVNuhYw@mail.gmail.com>

Hi Quentin.

On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> We currently unmap all MMIO mappings from the host stage-2 to recycle
> the pages whenever we run out. In order to make this pattern easy to
> re-use from other places, factor the logic out into a dedicated macro.
> While at it, apply the macro for the kvm_pgtable_stage2_set_owner()
> calls. They're currently only called early on and are guaranteed to
> succeed, but making them robust to the -ENOMEM case doesn't hurt and
> will avoid painful debugging sessions later on.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 40 +++++++++++++++------------
>  1 file changed, 22 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index d938ce95d3bd..74280a753efb 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -208,6 +208,25 @@ static inline int __host_stage2_idmap(u64 start, u64 end,
>                                       prot, &host_s2_pool);
>  }
>
> +/*
> + * The pool has been provided with enough pages to cover all of memory with
> + * page granularity, but it is difficult to know how much of the MMIO range
> + * we will need to cover upfront, so we may need to 'recycle' the pages if we
> + * run out.
> + */

The comment you added in V2 about host_kvm.lock got dropped in favor
asserting that the lock is held.

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad




> +#define host_stage2_try(fn, ...)                                       \
> +       ({                                                              \
> +               int __ret;                                              \
> +               hyp_assert_lock_held(&host_kvm.lock);                   \
> +               __ret = fn(__VA_ARGS__);                                \
> +               if (__ret == -ENOMEM) {                                 \
> +                       __ret = host_stage2_unmap_dev_all();            \
> +                       if (!__ret)                                     \
> +                               __ret = fn(__VA_ARGS__);                \
> +               }                                                       \
> +               __ret;                                                  \
> +        })
> +
>  static int host_stage2_idmap(u64 addr)
>  {
>         enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
> @@ -223,22 +242,7 @@ static int host_stage2_idmap(u64 addr)
>         if (ret)
>                 goto unlock;
>
> -       ret = __host_stage2_idmap(range.start, range.end, prot);
> -       if (ret != -ENOMEM)
> -               goto unlock;
> -
> -       /*
> -        * The pool has been provided with enough pages to cover all of memory
> -        * with page granularity, but it is difficult to know how much of the
> -        * MMIO range we will need to cover upfront, so we may need to 'recycle'
> -        * the pages if we run out.
> -        */
> -       ret = host_stage2_unmap_dev_all();
> -       if (ret)
> -               goto unlock;
> -
> -       ret = __host_stage2_idmap(range.start, range.end, prot);
> -
> +       ret = host_stage2_try(__host_stage2_idmap, range.start, range.end, prot);
>  unlock:
>         hyp_spin_unlock(&host_kvm.lock);
>
> @@ -257,8 +261,8 @@ int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
>                 return -EINVAL;
>
>         hyp_spin_lock(&host_kvm.lock);
> -       ret = kvm_pgtable_stage2_set_owner(&host_kvm.pgt, start, end - start,
> -                                          &host_s2_pool, pkvm_hyp_id);
> +       ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
> +                             start, end - start, &host_s2_pool, pkvm_hyp_id);
>         hyp_spin_unlock(&host_kvm.lock);
>
>         return ret != -EAGAIN ? ret : 0;
> --
> 2.32.0.432.gabb21c7263-goog
>


From tabba at google.com  Mon Aug  2 02:37:01 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 11:37:01 +0200
Subject: [PATCH v3 06/21] KVM: arm64: Optimize host memory aborts
In-Reply-To: <20210729132818.4091769-7-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-7-qperret@google.com>
Message-ID: <CA+EHjTz20cf78XtAEgTZ4sqaL=N3fY0hd=_=rZge53nUv=vsjQ@mail.gmail.com>

Hi Quentin,

On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> The kvm_pgtable_stage2_find_range() function is used in the host memory
> abort path to try and look for the largest block mapping that can be
> used to map the faulting address. In order to do so, the function
> currently walks the stage-2 page-table and looks for existing
> incompatible mappings within the range of the largest possible block.
> If incompatible mappings are found, it tries the same procedure again,
> but using a smaller block range, and repeats until a matching range is
> found (potentially up to page granularity). While this approach has
> benefits (mostly in the fact that it proactively coalesces host stage-2
> mappings), it can be slow if the ranges are fragmented, and it isn't
> optimized to deal with CPUs faulting on the same IPA as all of them will
> do all the work every time.
>
> To avoid these issues, remove kvm_pgtable_stage2_find_range(), and walk
> the page-table only once in the host_mem_abort() path to find the
> closest leaf to the input address. With this, use the corresponding
> range if it is invalid and not owned by another entity. If a valid leaf
> is found, return -EAGAIN similar to what is done in the
> kvm_pgtable_stage2_map() path to optimize concurrent faults.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewing the code it seems to work as described, with the lock
assertion ensuring that the caller knows which lock to hold.

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad


> ---
>  arch/arm64/include/asm/kvm_pgtable.h  | 30 -----------
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 45 +++++++++++++++-
>  arch/arm64/kvm/hyp/pgtable.c          | 74 ---------------------------
>  3 files changed, 44 insertions(+), 105 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 6938eac72c1f..83c5c97d9eac 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -154,16 +154,6 @@ enum kvm_pgtable_prot {
>  #define PAGE_HYP_RO            (KVM_PGTABLE_PROT_R)
>  #define PAGE_HYP_DEVICE                (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE)
>
> -/**
> - * struct kvm_mem_range - Range of Intermediate Physical Addresses
> - * @start:     Start of the range.
> - * @end:       End of the range.
> - */
> -struct kvm_mem_range {
> -       u64 start;
> -       u64 end;
> -};
> -
>  /**
>   * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk.
>   * @KVM_PGTABLE_WALK_LEAF:             Visit leaf entries, including invalid
> @@ -490,24 +480,4 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
>   */
>  int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
>                          kvm_pte_t *ptep, u32 *level);
> -
> -/**
> - * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical
> - *                                  Addresses with compatible permission
> - *                                  attributes.
> - * @pgt:       Page-table structure initialised by kvm_pgtable_stage2_init*().
> - * @addr:      Address that must be covered by the range.
> - * @prot:      Protection attributes that the range must be compatible with.
> - * @range:     Range structure used to limit the search space at call time and
> - *             that will hold the result.
> - *
> - * The offset of @addr within a page is ignored. An IPA is compatible with @prot
> - * iff its corresponding stage-2 page-table entry has default ownership and, if
> - * valid, is mapped with protection attributes identical to @prot.
> - *
> - * Return: 0 on success, negative error code on failure.
> - */
> -int kvm_pgtable_stage2_find_range(struct kvm_pgtable *pgt, u64 addr,
> -                                 enum kvm_pgtable_prot prot,
> -                                 struct kvm_mem_range *range);
>  #endif /* __ARM64_KVM_PGTABLE_H__ */
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 74280a753efb..2148d3968aa5 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -159,6 +159,11 @@ static int host_stage2_unmap_dev_all(void)
>         return kvm_pgtable_stage2_unmap(pgt, addr, BIT(pgt->ia_bits) - addr);
>  }
>
> +struct kvm_mem_range {
> +       u64 start;
> +       u64 end;
> +};
> +
>  static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range)
>  {
>         int cur, left = 0, right = hyp_memblock_nr;
> @@ -227,6 +232,44 @@ static inline int __host_stage2_idmap(u64 start, u64 end,
>                 __ret;                                                  \
>          })
>
> +static inline bool range_included(struct kvm_mem_range *child,
> +                                 struct kvm_mem_range *parent)
> +{
> +       return parent->start <= child->start && child->end <= parent->end;
> +}
> +
> +static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
> +{
> +       struct kvm_mem_range cur;
> +       kvm_pte_t pte;
> +       u32 level;
> +       int ret;
> +
> +       hyp_assert_lock_held(&host_kvm.lock);
> +       ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, &level);
> +       if (ret)
> +               return ret;
> +
> +       if (kvm_pte_valid(pte))
> +               return -EAGAIN;
> +
> +       if (pte)
> +               return -EPERM;
> +
> +       do {
> +               u64 granule = kvm_granule_size(level);
> +               cur.start = ALIGN_DOWN(addr, granule);
> +               cur.end = cur.start + granule;
> +               level++;
> +       } while ((level < KVM_PGTABLE_MAX_LEVELS) &&
> +                       !(kvm_level_supports_block_mapping(level) &&
> +                         range_included(&cur, range)));
> +
> +       *range = cur;
> +
> +       return 0;
> +}
> +
>  static int host_stage2_idmap(u64 addr)
>  {
>         enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
> @@ -238,7 +281,7 @@ static int host_stage2_idmap(u64 addr)
>                 prot |= KVM_PGTABLE_PROT_X;
>
>         hyp_spin_lock(&host_kvm.lock);
> -       ret = kvm_pgtable_stage2_find_range(&host_kvm.pgt, addr, prot, &range);
> +       ret = host_stage2_adjust_range(addr, &range);
>         if (ret)
>                 goto unlock;
>
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 49d768b92997..4dff2ad39ee4 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -1102,77 +1102,3 @@ void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
>         pgt->mm_ops->free_pages_exact(pgt->pgd, pgd_sz);
>         pgt->pgd = NULL;
>  }
> -
> -#define KVM_PTE_LEAF_S2_COMPAT_MASK    (KVM_PTE_LEAF_ATTR_S2_PERMS | \
> -                                        KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR | \
> -                                        KVM_PTE_LEAF_ATTR_S2_IGNORED)
> -
> -static int stage2_check_permission_walker(u64 addr, u64 end, u32 level,
> -                                         kvm_pte_t *ptep,
> -                                         enum kvm_pgtable_walk_flags flag,
> -                                         void * const arg)
> -{
> -       kvm_pte_t old_attr, pte = *ptep, *new_attr = arg;
> -
> -       /*
> -        * Compatible mappings are either invalid and owned by the page-table
> -        * owner (whose id is 0), or valid with matching permission attributes.
> -        */
> -       if (kvm_pte_valid(pte)) {
> -               old_attr = pte & KVM_PTE_LEAF_S2_COMPAT_MASK;
> -               if (old_attr != *new_attr)
> -                       return -EEXIST;
> -       } else if (pte) {
> -               return -EEXIST;
> -       }
> -
> -       return 0;
> -}
> -
> -int kvm_pgtable_stage2_find_range(struct kvm_pgtable *pgt, u64 addr,
> -                                 enum kvm_pgtable_prot prot,
> -                                 struct kvm_mem_range *range)
> -{
> -       kvm_pte_t attr;
> -       struct kvm_pgtable_walker check_perm_walker = {
> -               .cb             = stage2_check_permission_walker,
> -               .flags          = KVM_PGTABLE_WALK_LEAF,
> -               .arg            = &attr,
> -       };
> -       u64 granule, start, end;
> -       u32 level;
> -       int ret;
> -
> -       ret = stage2_set_prot_attr(pgt, prot, &attr);
> -       if (ret)
> -               return ret;
> -       attr &= KVM_PTE_LEAF_S2_COMPAT_MASK;
> -
> -       for (level = pgt->start_level; level < KVM_PGTABLE_MAX_LEVELS; level++) {
> -               granule = kvm_granule_size(level);
> -               start = ALIGN_DOWN(addr, granule);
> -               end = start + granule;
> -
> -               if (!kvm_level_supports_block_mapping(level))
> -                       continue;
> -
> -               if (start < range->start || range->end < end)
> -                       continue;
> -
> -               /*
> -                * Check the presence of existing mappings with incompatible
> -                * permissions within the current block range, and try one level
> -                * deeper if one is found.
> -                */
> -               ret = kvm_pgtable_walk(pgt, start, granule, &check_perm_walker);
> -               if (ret != -EEXIST)
> -                       break;
> -       }
> -
> -       if (!ret) {
> -               range->start = start;
> -               range->end = end;
> -       }
> -
> -       return ret;
> -}
> --
> 2.32.0.432.gabb21c7263-goog
>


From tabba at google.com  Mon Aug  2 02:37:23 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 11:37:23 +0200
Subject: [PATCH v3 07/21] KVM: arm64: Rename KVM_PTE_LEAF_ATTR_S2_IGNORED
In-Reply-To: <20210729132818.4091769-8-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-8-qperret@google.com>
Message-ID: <CA+EHjTyvMdjTAt3Q7ypniF10Qj3_1m_dos=EzxSSCe3Jeo3z4A@mail.gmail.com>

Hi Quentin,

On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> The ignored bits for both stage-1 and stage-2 page and block
> descriptors are in [55:58], so rename KVM_PTE_LEAF_ATTR_S2_IGNORED to
> make it applicable to both. And while at it, since these bits are more
> commonly known as 'software' bits, rename accordingly.

As in the Armv8-A Address Translation spec.

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad



> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/pgtable.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 4dff2ad39ee4..59a394d82de3 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -36,6 +36,8 @@
>
>  #define KVM_PTE_LEAF_ATTR_HI           GENMASK(63, 51)
>
> +#define KVM_PTE_LEAF_ATTR_HI_SW                GENMASK(58, 55)
> +
>  #define KVM_PTE_LEAF_ATTR_HI_S1_XN     BIT(54)
>
>  #define KVM_PTE_LEAF_ATTR_HI_S2_XN     BIT(54)
> @@ -44,8 +46,6 @@
>                                          KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
>                                          KVM_PTE_LEAF_ATTR_HI_S2_XN)
>
> -#define KVM_PTE_LEAF_ATTR_S2_IGNORED   GENMASK(58, 55)
> -
>  #define KVM_INVALID_PTE_OWNER_MASK     GENMASK(63, 56)
>  #define KVM_MAX_OWNER_ID               1
>
> --
> 2.32.0.432.gabb21c7263-goog
>


From tabba at google.com  Mon Aug  2 02:38:31 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 11:38:31 +0200
Subject: [PATCH v3 08/21] KVM: arm64: Don't overwrite software bits with
 owner id
In-Reply-To: <20210729132818.4091769-9-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-9-qperret@google.com>
Message-ID: <CA+EHjTwSg8gZCoxkRu1HEiqhKQuAoascU208c19=-MYBuvf1nw@mail.gmail.com>

Hi Quentin,

On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> We will soon start annotating page-tables with new flags to track shared
> pages and such, and we will do so in valid mappings using software bits
> in the PTEs, as provided by the architecture. However, it is possible
> that we will need to use those flags to annotate invalid mappings as
> well in the future, similar to what we do to track page ownership in the
> host stage-2.
>
> In order to facilitate the annotation of invalid mappings with such
> flags, it would be preferable to re-use the same bits as for valid
> mappings (bits [58-55]), but these are currently used for ownership
> encoding. Since we have plenty of bits left to use in invalid
> mappings, move the ownership bits further down the PTE to avoid the
> conflict.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/pgtable.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 59a394d82de3..1ee1168ac32d 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -46,7 +46,7 @@
>                                          KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
>                                          KVM_PTE_LEAF_ATTR_HI_S2_XN)
>
> -#define KVM_INVALID_PTE_OWNER_MASK     GENMASK(63, 56)
> +#define KVM_INVALID_PTE_OWNER_MASK     GENMASK(9, 2)
>  #define KVM_MAX_OWNER_ID               1

This change makes sense so that the same bits can be used to track sharing.

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>
>  struct kvm_pgtable_walk_data {

> --
> 2.32.0.432.gabb21c7263-goog
>


From tabba at google.com  Mon Aug  2 02:49:28 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 11:49:28 +0200
Subject: [PATCH v3 10/21] KVM: arm64: Enable forcing page-level stage-2
 mappings
In-Reply-To: <20210729132818.4091769-11-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-11-qperret@google.com>
Message-ID: <CA+EHjTxCvqQ=jmBPJ1N6ShBf=f4J5cjT4pt9akfnqNjQUoqzWw@mail.gmail.com>

Hi Quentin,


On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> Much of the stage-2 manipulation logic relies on being able to destroy
> block mappings if e.g. installing a smaller mapping in the range. The
> rationale for this behaviour is that stage-2 mappings can always be
> re-created lazily. However, this gets more complicated when the stage-2
> page-table is used to store metadata about the underlying pages. In such
> cases, destroying a block mapping may lead to losing part of the state,
> and confuse the user of those metadata (such as the hypervisor in nVHE
> protected mode).
>
> To avoid this, introduce a callback function in the pgtable struct which
> is called during all map operations to determine whether the mappings
> can use blocks, or should be forced to page granularity. This is used by
> the hypervisor when creating the host stage-2 to force page-level
> mappings when using non-default protection attributes.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_pgtable.h  | 65 ++++++++++++++++-----------
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 30 +++++++++++--
>  arch/arm64/kvm/hyp/pgtable.c          | 29 +++++++++---
>  3 files changed, 91 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 83c5c97d9eac..ba7dcade2798 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -115,25 +115,6 @@ enum kvm_pgtable_stage2_flags {
>         KVM_PGTABLE_S2_IDMAP                    = BIT(1),
>  };
>
> -/**
> - * struct kvm_pgtable - KVM page-table.
> - * @ia_bits:           Maximum input address size, in bits.
> - * @start_level:       Level at which the page-table walk starts.
> - * @pgd:               Pointer to the first top-level entry of the page-table.
> - * @mm_ops:            Memory management callbacks.
> - * @mmu:               Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
> - */
> -struct kvm_pgtable {
> -       u32                                     ia_bits;
> -       u32                                     start_level;
> -       kvm_pte_t                               *pgd;
> -       struct kvm_pgtable_mm_ops               *mm_ops;
> -
> -       /* Stage-2 only */
> -       struct kvm_s2_mmu                       *mmu;
> -       enum kvm_pgtable_stage2_flags           flags;
> -};
> -
>  /**
>   * enum kvm_pgtable_prot - Page-table permissions and attributes.
>   * @KVM_PGTABLE_PROT_X:                Execute permission.
> @@ -149,11 +130,41 @@ enum kvm_pgtable_prot {
>         KVM_PGTABLE_PROT_DEVICE                 = BIT(3),
>  };
>
> -#define PAGE_HYP               (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
> +#define KVM_PGTABLE_PROT_RW    (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
> +#define KVM_PGTABLE_PROT_RWX   (KVM_PGTABLE_PROT_RW | KVM_PGTABLE_PROT_X)
> +
> +#define PAGE_HYP               KVM_PGTABLE_PROT_RW
>  #define PAGE_HYP_EXEC          (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X)
>  #define PAGE_HYP_RO            (KVM_PGTABLE_PROT_R)
>  #define PAGE_HYP_DEVICE                (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE)

I wonder if it would be useful to add a couple of other aliases for
default memory and default mmio protections, e.g.,

#define  KVM_PGTABLE_PROT_MEM KVM_PGTABLE_PROT_RWX
#define  KVM_PGTABLE_PROT_MMIO KVM_PGTABLE_PROT_RW

I think that using these below, e.g., host_stage2_force_pte_cb(),
might make it clearer and answer comments you had in earlier patches
about why "RWX" for memory.

>
> +typedef bool (*kvm_pgtable_force_pte_cb_t)(u64 addr, u64 end,
> +                                          enum kvm_pgtable_prot prot);
> +
> +/**
> + * struct kvm_pgtable - KVM page-table.
> + * @ia_bits:           Maximum input address size, in bits.
> + * @start_level:       Level at which the page-table walk starts.
> + * @pgd:               Pointer to the first top-level entry of the page-table.
> + * @mm_ops:            Memory management callbacks.
> + * @mmu:               Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
> + * @flags:             Stage-2 page-table flags.
> + * @force_pte_cb:      Callback function used during map operations to decide
> + *                     whether block mappings can be used to map the given IPA
> + *                     range.
> + */

nit: I think it might be clearer (and probably not longer) to rephrase
to describe in terms of the return value of the callback, e.g., "...
function that returns true if page level mappings must be used instead
of block mappings."

> +struct kvm_pgtable {
> +       u32                                     ia_bits;
> +       u32                                     start_level;
> +       kvm_pte_t                               *pgd;
> +       struct kvm_pgtable_mm_ops               *mm_ops;
> +
> +       /* Stage-2 only */
> +       struct kvm_s2_mmu                       *mmu;
> +       enum kvm_pgtable_stage2_flags           flags;
> +       kvm_pgtable_force_pte_cb_t              force_pte_cb;
> +};
> +
>  /**
>   * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk.
>   * @KVM_PGTABLE_WALK_LEAF:             Visit leaf entries, including invalid
> @@ -246,21 +257,25 @@ int kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
>  u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift);
>
>  /**
> - * kvm_pgtable_stage2_init_flags() - Initialise a guest stage-2 page-table.
> + * __kvm_pgtable_stage2_init() - Initialise a guest stage-2 page-table.
>   * @pgt:       Uninitialised page-table structure to initialise.
>   * @arch:      Arch-specific KVM structure representing the guest virtual
>   *             machine.
>   * @mm_ops:    Memory management callbacks.
>   * @flags:     Stage-2 configuration flags.
> + * @force_pte_cb: Callback function used during map operations to decide
> + *             whether block mappings can be used to map the given IPA
> + *             range.

nit: same nit as above with describing the callback in terms of its return value

>   *
>   * Return: 0 on success, negative error code on failure.
>   */
> -int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> -                                 struct kvm_pgtable_mm_ops *mm_ops,
> -                                 enum kvm_pgtable_stage2_flags flags);
> +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> +                             struct kvm_pgtable_mm_ops *mm_ops,
> +                             enum kvm_pgtable_stage2_flags flags,
> +                             kvm_pgtable_force_pte_cb_t force_pte_cb);
>
>  #define kvm_pgtable_stage2_init(pgt, arch, mm_ops) \
> -       kvm_pgtable_stage2_init_flags(pgt, arch, mm_ops, 0)
> +       __kvm_pgtable_stage2_init(pgt, arch, mm_ops, 0, NULL)
>
>  /**
>   * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 2148d3968aa5..70c57d2c3024 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -89,6 +89,7 @@ static void prepare_host_vtcr(void)
>                                           id_aa64mmfr1_el1_sys_val, phys_shift);
>  }
>
> +static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot);

nit: newline

>  int kvm_host_prepare_stage2(void *pgt_pool_base)
>  {
>         struct kvm_s2_mmu *mmu = &host_kvm.arch.mmu;
> @@ -101,8 +102,9 @@ int kvm_host_prepare_stage2(void *pgt_pool_base)
>         if (ret)
>                 return ret;
>
> -       ret = kvm_pgtable_stage2_init_flags(&host_kvm.pgt, &host_kvm.arch,
> -                                           &host_kvm.mm_ops, KVM_HOST_S2_FLAGS);
> +       ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, &host_kvm.arch,
> +                                       &host_kvm.mm_ops, KVM_HOST_S2_FLAGS,
> +                                       host_stage2_force_pte_cb);
>         if (ret)
>                 return ret;
>
> @@ -270,9 +272,31 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
>         return 0;
>  }
>
> +static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
> +{
> +       /*
> +        * Block mappings must be used with care in the host stage-2 as a
> +        * kvm_pgtable_stage2_map() operation targeting a page in the range of
> +        * an existing block will delete the block under the assumption that
> +        * mappings in the rest of the block range can always be rebuilt lazily.
> +        * That assumption is correct for the host stage-2 with RWX mappings
> +        * targeting memory or RW mappings targeting MMIO ranges (see
> +        * host_stage2_idmap() below which implements some of the host memory
> +        * abort logic). However, this is not safe for any other mappings where
> +        * the host stage-2 page-table is in fact the only place where this
> +        * state is stored. In all those cases, it is safer to use page-level
> +        * mappings, hence avoiding to lose the state because of side-effects in
> +        * kvm_pgtable_stage2_map().
> +        */
> +       if (range_is_memory(addr, end))
> +               return prot != KVM_PGTABLE_PROT_RWX;
> +       else
> +               return prot != KVM_PGTABLE_PROT_RW;
> +}

Just checking, I don't think that it's possible for the range to be
big enough to somehow include both memory and mmio, neither now nor in
future use cases, is it?

> +
>  static int host_stage2_idmap(u64 addr)
>  {
> -       enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
> +       enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_RW;
>         struct kvm_mem_range range;
>         bool is_memory = find_mem_range(addr, &range);
>         int ret;
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 2689fcb7901d..bcc02e6e0f62 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -452,6 +452,8 @@ int kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits,
>         pgt->start_level        = KVM_PGTABLE_MAX_LEVELS - levels;
>         pgt->mm_ops             = mm_ops;
>         pgt->mmu                = NULL;
> +       pgt->force_pte_cb       = NULL;
> +
>         return 0;
>  }
>
> @@ -489,6 +491,9 @@ struct stage2_map_data {
>         void                            *memcache;
>
>         struct kvm_pgtable_mm_ops       *mm_ops;
> +
> +       /* Force mappings to page granularity */
> +       bool                            force_pte;
>  };
>
>  u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
> @@ -602,6 +607,15 @@ static bool stage2_pte_executable(kvm_pte_t pte)
>         return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN);
>  }
>
> +static bool stage2_block_mapping_allowed(u64 addr, u64 end, u32 level,
> +                                        struct stage2_map_data *data)
> +{
> +       if (data->force_pte && (level < (KVM_PGTABLE_MAX_LEVELS - 1)))
> +               return false;

I'm not sure I understand why checking the level is necessary. Can
there be block mapping at the last possible level?

Thanks,
/fuad

> +
> +       return kvm_block_mapping_supported(addr, end, data->phys, level);
> +}
> +
>  static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level,
>                                       kvm_pte_t *ptep,
>                                       struct stage2_map_data *data)
> @@ -611,7 +625,7 @@ static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level,
>         struct kvm_pgtable *pgt = data->mmu->pgt;
>         struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops;
>
> -       if (!kvm_block_mapping_supported(addr, end, phys, level))
> +       if (!stage2_block_mapping_allowed(addr, end, level, data))
>                 return -E2BIG;
>
>         if (kvm_phys_is_valid(phys))
> @@ -655,7 +669,7 @@ static int stage2_map_walk_table_pre(u64 addr, u64 end, u32 level,
>         if (data->anchor)
>                 return 0;
>
> -       if (!kvm_block_mapping_supported(addr, end, data->phys, level))
> +       if (!stage2_block_mapping_allowed(addr, end, level, data))
>                 return 0;
>
>         data->childp = kvm_pte_follow(*ptep, data->mm_ops);
> @@ -785,6 +799,7 @@ int kvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
>                 .mmu            = pgt->mmu,
>                 .memcache       = mc,
>                 .mm_ops         = pgt->mm_ops,
> +               .force_pte      = pgt->force_pte_cb && pgt->force_pte_cb(addr, addr + size, prot),
>         };
>         struct kvm_pgtable_walker walker = {
>                 .cb             = stage2_map_walker,
> @@ -816,6 +831,7 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size,
>                 .memcache       = mc,
>                 .mm_ops         = pgt->mm_ops,
>                 .owner_id       = owner_id,
> +               .force_pte      = true,
>         };
>         struct kvm_pgtable_walker walker = {
>                 .cb             = stage2_map_walker,
> @@ -1057,9 +1073,11 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
>         return kvm_pgtable_walk(pgt, addr, size, &walker);
>  }
>
> -int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> -                                 struct kvm_pgtable_mm_ops *mm_ops,
> -                                 enum kvm_pgtable_stage2_flags flags)
> +
> +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> +                             struct kvm_pgtable_mm_ops *mm_ops,
> +                             enum kvm_pgtable_stage2_flags flags,
> +                             kvm_pgtable_force_pte_cb_t force_pte_cb)
>  {
>         size_t pgd_sz;
>         u64 vtcr = arch->vtcr;
> @@ -1077,6 +1095,7 @@ int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch
>         pgt->mm_ops             = mm_ops;
>         pgt->mmu                = &arch->mmu;
>         pgt->flags              = flags;
> +       pgt->force_pte_cb       = force_pte_cb;
>
>         /* Ensure zeroed PGD pages are visible to the hardware walker */
>         dsb(ishst);
> --
> 2.32.0.432.gabb21c7263-goog
>


From linux at armlinux.org.uk  Mon Aug  2 02:48:10 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 2 Aug 2021 10:48:10 +0100
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
References: <YPkg0wtYIoHKpTUW@kunai>
 <20210722081817.2tsjzof4gvldq6ka@pengutronix.de>
 <YPlfcbkxiBmB+vw1@kunai>
 <CAHp75VfC=s12Unw3+Cn0ag71mM5i90=Jbwj4nYwB5cPKiUTRSA@mail.gmail.com>
 <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
Message-ID: <20210802094810.GJ22278@shell.armlinux.org.uk>

On Sat, Jul 31, 2021 at 02:00:04PM +0200, Uwe Kleine-K?nig wrote:
> Hi Russell, hi Stephen,
> 
> On Sat, Jul 31, 2021 at 12:41:19AM -0700, Stephen Boyd wrote:
> > +1 This patch doesn't fall under CCF maintainer.
> 
> Given that CCF is the only implementer of devm_clk_get at least an Ack
> from your side would still be good I guess?

I think devm_clk_get() should not be part of CCF but should be
part of the interface level - it's silly to have devm_clk_get()
being CCF but not clk_get(). The same should go for the other
devm wrappers around the plain clk_* interfaces.

> I found a patch set adding devm variants of clk_enable (e.g.
> https://lore.kernel.org/patchwork/patch/755667/) but this approach is
> different as it also contains clk_get which IMHO makes more sense 
> The discussion considered wrapping get+enable at one point, but I didn't
> find a followup.

There have been several different approaches to wrapping things up,
but here's a question: should we make it easier to do the lazy thing
(get+enable) or should we make it easier to be power efficient?
Shouldn't we be encouraging people to write power efficient drivers?

> > I still wonder if it would be better if we had some sort of DT binding
> > that said "turn this clk on when the driver probes this device and keep
> > it on until the driver is unbound".
> 
> This doesn't sound like a hardware property and so I don't think this
> belongs into DT and I would be surprised if the dt maintainers would be
> willing to accept an idea with this semantic.

I really don't like that idea - enabling or disabling a clock is
an implementation decision, one which can change over time. Even
if a clock is required to be on for e.g. accessing device registers,
we may decide that, if we want maximum power savings, to disable
that clock when the device is not being used, but an initial driver
implementation may not do that. If we encourage people to throw a
property in DT, then the driver's runtime behaviour becomes a
combination of the DT being used and the driver implementation.
Let's keep that to a minimum.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From tabba at google.com  Mon Aug  2 02:50:13 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 11:50:13 +0200
Subject: [PATCH v3 09/21] KVM: arm64: Tolerate re-creating hyp mappings to
 set software bits
In-Reply-To: <20210729132818.4091769-10-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-10-qperret@google.com>
Message-ID: <CA+EHjTzYP3W4w3-EufkxWrFtGuCs6=SuO9XegAGAAp46EDF1VQ@mail.gmail.com>

Hi Quentin,

On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> The current hypervisor stage-1 mapping code doesn't allow changing an
> existing valid mapping. Relax this condition by allowing changes that
> only target software bits, as that will soon be needed to annotate shared
> pages.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/pgtable.c | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 1ee1168ac32d..2689fcb7901d 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -362,6 +362,21 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
>         return 0;
>  }
>
> +static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new)
> +{
> +       /*
> +        * Tolerate KVM recreating the exact same mapping, or changing software
> +        * bits if the existing mapping was valid.
> +        */
> +       if (old == new)
> +               return false;

The added comment clarifies the rationale here. Thanks.

Reviewed-by: Fuad Tabba <tabba at google.com>

/fuad



/fuad

> +       if (!kvm_pte_valid(old))
> +               return true;
> +
> +       return !WARN_ON((old ^ new) & ~KVM_PTE_LEAF_ATTR_HI_SW);
> +}
> +
>  static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level,
>                                     kvm_pte_t *ptep, struct hyp_map_data *data)
>  {
> @@ -371,9 +386,8 @@ static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level,
>         if (!kvm_block_mapping_supported(addr, end, phys, level))
>                 return false;
>
> -       /* Tolerate KVM recreating the exact same mapping */
>         new = kvm_init_valid_leaf_pte(phys, data->attr, level);
> -       if (old != new && !WARN_ON(kvm_pte_valid(old)))
> +       if (hyp_pte_needs_update(old, new))
>                 smp_store_release(ptep, new);
>
>         data->phys += granule;
> --
> 2.32.0.432.gabb21c7263-goog
>


From joro at 8bytes.org  Mon Aug  2 02:51:41 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Mon, 2 Aug 2021 11:51:41 +0200
Subject: [PATCH v7 00/12] Clean up "mediatek,larb"
In-Reply-To: <20210730025238.22456-1-yong.wu@mediatek.com>
References: <20210730025238.22456-1-yong.wu@mediatek.com>
Message-ID: <YQfALZNWyw8VKODp@8bytes.org>

On Fri, Jul 30, 2021 at 10:52:26AM +0800, Yong Wu wrote:
>  .../display/mediatek/mediatek,disp.txt        |  9 ----
>  .../bindings/media/mediatek-jpeg-decoder.yaml |  9 ----
>  .../bindings/media/mediatek-jpeg-encoder.yaml |  9 ----
>  .../bindings/media/mediatek-mdp.txt           |  8 ----
>  .../bindings/media/mediatek-vcodec.txt        |  4 --
>  arch/arm/boot/dts/mt2701.dtsi                 |  2 -
>  arch/arm/boot/dts/mt7623n.dtsi                |  5 --
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi      | 16 -------
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  6 ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c       |  9 +++-
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |  9 +++-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 15 +++---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   | 36 +--------------
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  1 -
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  5 +-
>  drivers/iommu/mtk_iommu.c                     | 24 +++++++++-
>  drivers/iommu/mtk_iommu_v1.c                  | 31 ++++++++++++-
>  .../media/platform/mtk-jpeg/mtk_jpeg_core.c   | 45 +-----------------
>  .../media/platform/mtk-jpeg/mtk_jpeg_core.h   |  2 -
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 46 +------------------
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 -
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  1 -
>  .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 37 ++-------------
>  .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  3 --
>  .../platform/mtk-vcodec/mtk_vcodec_enc.c      |  1 -
>  .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 44 ++----------------
>  drivers/memory/mtk-smi.c                      | 14 ------
>  include/soc/mediatek/smi.h                    | 20 --------
>  28 files changed, 92 insertions(+), 321 deletions(-)

So this is likely not going through the IOMMU tree, given Matthias has
reviewed the IOMMU changes you can add my Acked-by: Joerg Roedel <jroedel at suse.de>


From icenowy at sipeed.com  Mon Aug  2 02:52:52 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Mon, 02 Aug 2021 17:52:52 +0800
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <20210802062212.73220-11-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-11-icenowy@sipeed.com>
Message-ID: <d08fbaae055fc88246cd9f39ce5112f80fcc734c.camel@sipeed.com>+B00387BDD8D62B3B

? 2021-08-02???? 14:22 +0800?Icenowy Zheng???
> Allwinner R329 has clock controls in PRCM, like other new Allwinner
> SoCs.
> 
> Add support for them.
> 
> This driver is added before the main CCU because PLLs are controlled
> by
> R-CCU on R329.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
> ?drivers/clk/sunxi-ng/Kconfig????????????????? |?? 5 +
> ?drivers/clk/sunxi-ng/Makefile???????????????? |?? 1 +
> ?drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c????? | 374
> ++++++++++++++++++
> ?drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h????? |? 33 ++
> ?include/dt-bindings/clock/sun50i-r329-r-ccu.h |? 33 ++
> ?include/dt-bindings/reset/sun50i-r329-r-ccu.h |? 24 ++
> ?6 files changed, 470 insertions(+)
> ?create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> ?create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> ?create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
> ?create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
> 
> diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-
> ng/Kconfig
> index cd46d8853876..e49b2c2fa5b7 100644
> --- a/drivers/clk/sunxi-ng/Kconfig
> +++ b/drivers/clk/sunxi-ng/Kconfig
> @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
> ????????default ARM64 && ARCH_SUNXI
> ????????depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> ?
> +config SUN50I_R329_R_CCU
> +???????bool "Support for the Allwinner R329 PRCM CCU"
> +???????default ARM64 && ARCH_SUNXI
> +???????depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> +
> ?config SUN4I_A10_CCU
> ????????bool "Support for the Allwinner A10/A20 CCU"
> ????????default MACH_SUN4I
> diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-
> ng/Makefile
> index 96c324306d97..db338a2188fd 100644
> --- a/drivers/clk/sunxi-ng/Makefile
> +++ b/drivers/clk/sunxi-ng/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)???????+= ccu-
> sun50i-a100-r.o
> ?obj-$(CONFIG_SUN50I_H6_CCU)????+= ccu-sun50i-h6.o
> ?obj-$(CONFIG_SUN50I_H616_CCU)??+= ccu-sun50i-h616.o
> ?obj-$(CONFIG_SUN50I_H6_R_CCU)??+= ccu-sun50i-h6-r.o
> +obj-$(CONFIG_SUN50I_R329_R_CCU)????????+= ccu-sun50i-r329-r.o
> ?obj-$(CONFIG_SUN4I_A10_CCU)????+= ccu-sun4i-a10.o
> ?obj-$(CONFIG_SUN5I_CCU)????????????????+= ccu-sun5i.o
> ?obj-$(CONFIG_SUN6I_A31_CCU)????+= ccu-sun6i-a31.o
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> new file mode 100644
> index 000000000000..5413a701cb57
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> @@ -0,0 +1,374 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 Sipeed
> + * Based on the H616 CCU driver, which is:
> + *?? Copyright (c) 2020 Arm Ltd.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +
> +#include "ccu_common.h"
> +#include "ccu_reset.h"
> +
> +#include "ccu_div.h"
> +#include "ccu_gate.h"
> +#include "ccu_mp.h"
> +#include "ccu_mult.h"
> +#include "ccu_nk.h"
> +#include "ccu_nkm.h"
> +#include "ccu_nkmp.h"
> +#include "ccu_nm.h"
> +
> +#include "ccu-sun50i-r329-r.h"
> +
> +/*
> + * The M factor is present in the register's description, but not in
> the
> + * frequency formula, and it's documented as "The bit is only for
> + * testing", so it's not modelled and then force to 0.
> + */
> +#define SUN50I_R329_PLL_CPUX_REG???????0x1000
> +static struct ccu_mult pll_cpux_clk = {
> +???????.enable?????????= BIT(31),
> +???????.lock???????????= BIT(28),
> +???????.mult???????????= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +???????.common?????????= {
> +???????????????.reg????????????= 0x1000,
> +???????????????.hw.init????????= CLK_HW_INIT("pll-cpux", "osc24M",
> +???????????????????????????????????????????? &ccu_mult_ops,
> +???????????????????????????????????????????? CLK_SET_RATE_UNGATE),
> +???????},
> +};
> +
> +#define SUN50I_R329_PLL_PERIPH_REG?????0x1010
> +static struct ccu_nm pll_periph_base_clk = {
> +???????.enable?????????= BIT(31),
> +???????.lock???????????= BIT(28),
> +???????.n??????????????= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +???????.m??????????????= _SUNXI_CCU_DIV(1, 1), /* input divider */
> +???????.common?????????= {
> +???????????????.reg????????????= 0x1010,
> +???????????????.hw.init????????= CLK_HW_INIT("pll-periph-base",
> "osc24M",
> +???????????????????????????????????????????? &ccu_nm_ops,
> +???????????????????????????????????????????? CLK_SET_RATE_UNGATE),
> +???????},
> +};
> +
> +static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-
> base",
> +????????????????? 0x1010, 16, 3, 0);
> +static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m", "pll-
> periph-base",
> +????????????????? 0x1010, 20, 3, 0);
> +static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
> +????????????????????????? &pll_periph_2x_clk.common.hw, 2, 1, 0);
> +
> +#define SUN50I_R329_PLL_AUDIO0_REG?????0x1020
> +static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
> +???????{ .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64
> },
> +};
> +
> +static struct ccu_nm pll_audio0_clk = {
> +???????.enable?????????= BIT(31),
> +???????.lock???????????= BIT(28),
> +???????.n??????????????= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +???????.m??????????????= _SUNXI_CCU_DIV(1, 1),
> +???????.sdm????????????= _SUNXI_CCU_SDM(pll_audio0_sdm_table,
> +??????????????????????????????????????? BIT(24), 0x1120, BIT(31)),
> +???????.common?????????= {
> +???????????????.features???????= CCU_FEATURE_SIGMA_DELTA_MOD,
> +???????????????.reg????????????= 0x1020,
> +???????????????.hw.init????????= CLK_HW_INIT("pll-audio0", "osc24M",
> +???????????????????????????????????????????? &ccu_nm_ops,
> +???????????????????????????????????????????? CLK_SET_RATE_UNGATE),
> +???????},
> +};
> +
> +static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-
> audio0",
> +????????????????? 0x1020, 16, 3, 0);
> +static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-
> audio0",
> +????????????????? 0x1020, 20, 3, 0);
> +
> +/*
> + * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
> + * BSP driver always has M0 = 1 and M1 = 2 (this is also the
> + * reset value in the register).
> + *
> + * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
> + */
> +#define SUN50I_R329_PLL_AUDIO1_REG?????0x1030
> +static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
> +???????{ .rate = 22579200, .pattern = 0xc001288d, .m = 12, .n = 22
> },
> +???????{ .rate = 24576000, .pattern = 0xc00126e9, .m = 12, .n = 24
> },
> +???????{ .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 },
> +???????{ .rate = 98304000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
> +};

Sorry, the SDM table here is wrong -- all rate here should be *2
(because I wrongly assumed how postdiv works with sdm).

> +static struct ccu_nm pll_audio1_4x_clk = {
> +???????.enable?????????= BIT(31),
> +???????.lock???????????= BIT(28),
> +???????.n??????????????= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +???????.m??????????????= _SUNXI_CCU_DIV(16, 6),
> +???????.fixed_post_div?= 2,
> +???????.sdm????????????= _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
> +??????????????????????????????????????? BIT(24), 0x1130, BIT(31)),
> +???????.common?????????= {
> +???????????????.features???????= CCU_FEATURE_FIXED_POSTDIV |
> +???????????????????????????????? CCU_FEATURE_SIGMA_DELTA_MOD,
> +???????????????.reg????????????= 0x1030,
> +???????????????.hw.init????????= CLK_HW_INIT("pll-audio1-4x",
> "osc24M",
> +???????????????????????????????????????????? &ccu_nm_ops,
> +???????????????????????????????????????????? CLK_SET_RATE_UNGATE),
> +???????},
> +};
> +
> +static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
> +????????????????????????? &pll_audio1_4x_clk.common.hw, 2, 1,
> +????????????????????????? CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
> +????????????????????????? &pll_audio1_4x_clk.common.hw, 4, 1,
> +????????????????????????? CLK_SET_RATE_PARENT);
> +
> +static const char * const r_bus_parents[] = { "osc24M", "osc32k",
> "iosc",
> +???????????????????????????????????????????? "pll-periph-2x",
> +???????????????????????????????????????????? "pll-audio0-div2" };
> +static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents,
> 0x000,
> +??????????????????????????? 0, 5,??????/* M */
> +??????????????????????????? 8, 2,??????/* P */
> +??????????????????????????? 24, 3,?????/* mux */
> +??????????????????????????? 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents,
> 0x00c,
> +??????????????????????????? 0, 5,??????/* M */
> +??????????????????????????? 8, 2,??????/* P */
> +??????????????????????????? 24, 3,?????/* mux */
> +??????????????????????????? 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents,
> 0x010,
> +??????????????????????????? 0, 5,??????/* M */
> +??????????????????????????? 8, 2,??????/* P */
> +??????????????????????????? 24, 3,?????/* mux */
> +??????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
> +???????????????????? 0x0ec, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc,
> BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c,
> BIT(0), 0);
> +
> +static const char * const r_pwm_parents[] = { "osc24M", "osc32k",
> "iosc" };
> +static SUNXI_CCU_MUX_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents,
> 0x130,
> +????????????????????????????? 24, 3,???/* mux */
> +????????????????????????????? BIT(31),?/* gate */
> +????????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c,
> BIT(0), 0);
> +
> +static const char * const r_audio_parents[] = { "pll-audio0-div5",
> "pll-audio0-div2",
> +???????????????????????????????????????????????"pll-audio1-1x",
> "pll-audio1-4x" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc",
> r_audio_parents, 0x140,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac",
> r_audio_parents, 0x144,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
> +???????????????????? 0x14c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic",
> r_audio_parents, 0x150,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c,
> BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc", "r-apb1",
> +???????????????????? 0x16c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s",
> r_audio_parents, 0x170,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
> +???????????????????????????????? r_audio_parents, 0x174,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c,
> BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart", "r-apb2", 0x18c,
> BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_i2c_clk, "r-bus-i2c", "r-apb2", 0x19c,
> BIT(0), 0);
> +
> +static const char * const r_ir_parents[] = { "osc32k", "osc24M" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents,
> 0x1c0,
> +???????????????????????????????? 0, 5,?????????/* M */
> +???????????????????????????????? 8, 2,?????????/* P */
> +???????????????????????????????? 24, 3,????????/* mux */
> +???????????????????????????????? BIT(31),??????/* gate */
> +???????????????????????????????? 0);
> +
> +static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc,
> BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
> +???????????????????? 0x1dc, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-
> apb1",
> +???????????????????? 0x1ec, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
> +???????????????????? 0x20c, BIT(0), CLK_IS_CRITICAL);
> +
> +static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
> +???????&pll_cpux_clk.common,
> +???????&pll_periph_base_clk.common,
> +???????&pll_periph_2x_clk.common,
> +???????&pll_periph_800m_clk.common,
> +???????&pll_audio0_clk.common,
> +???????&pll_audio0_div2_clk.common,
> +???????&pll_audio0_div5_clk.common,
> +???????&pll_audio1_4x_clk.common,
> +???????&r_ahb_clk.common,
> +???????&r_apb1_clk.common,
> +???????&r_apb2_clk.common,
> +???????&r_bus_gpadc_clk.common,
> +???????&r_bus_ths_clk.common,
> +???????&r_bus_dma_clk.common,
> +???????&r_pwm_clk.common,
> +???????&r_bus_pwm_clk.common,
> +???????&r_codec_adc_clk.common,
> +???????&r_codec_dac_clk.common,
> +???????&r_bus_codec_clk.common,
> +???????&r_dmic_clk.common,
> +???????&r_bus_dmic_clk.common,
> +???????&r_bus_lradc_clk.common,
> +???????&r_i2s_clk.common,
> +???????&r_i2s_asrc_clk.common,
> +???????&r_bus_i2s_clk.common,
> +???????&r_bus_uart_clk.common,
> +???????&r_bus_i2c_clk.common,
> +???????&r_ir_clk.common,
> +???????&r_bus_ir_clk.common,
> +???????&r_bus_msgbox_clk.common,
> +???????&r_bus_spinlock_clk.common,
> +???????&r_bus_rtc_clk.common,
> +};
> +
> +static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
> +???????.hws????= {
> +???????????????[CLK_PLL_CPUX]??????????= &pll_cpux_clk.common.hw,
> +???????????????[CLK_PLL_PERIPH_BASE]???=
> &pll_periph_base_clk.common.hw,
> +???????????????[CLK_PLL_PERIPH_2X]?????=
> &pll_periph_2x_clk.common.hw,
> +???????????????[CLK_PLL_PERIPH_800M]???=
> &pll_periph_800m_clk.common.hw,
> +???????????????[CLK_PLL_PERIPH]????????= &pll_periph_clk.hw,
> +???????????????[CLK_PLL_AUDIO0]????????= &pll_audio0_clk.common.hw,
> +???????????????[CLK_PLL_AUDIO0_DIV2]???=
> &pll_audio0_div2_clk.common.hw,
> +???????????????[CLK_PLL_AUDIO0_DIV5]???=
> &pll_audio0_div5_clk.common.hw,
> +???????????????[CLK_PLL_AUDIO1_4X]?????=
> &pll_audio1_4x_clk.common.hw,
> +???????????????[CLK_PLL_AUDIO1_2X]?????= &pll_audio1_2x_clk.hw,
> +???????????????[CLK_PLL_AUDIO1]????????= &pll_audio1_clk.hw,
> +???????????????[CLK_R_AHB]?????????????= &r_ahb_clk.common.hw,
> +???????????????[CLK_R_APB1]????????????= &r_apb1_clk.common.hw,
> +???????????????[CLK_R_APB2]????????????= &r_apb2_clk.common.hw,
> +???????????????[CLK_R_BUS_GPADC]???????= &r_bus_gpadc_clk.common.hw,
> +???????????????[CLK_R_BUS_THS]?????????= &r_bus_ths_clk.common.hw,
> +???????????????[CLK_R_BUS_DMA]?????????= &r_bus_dma_clk.common.hw,
> +???????????????[CLK_R_PWM]?????????????= &r_pwm_clk.common.hw,
> +???????????????[CLK_R_BUS_PWM]?????????= &r_bus_pwm_clk.common.hw,
> +???????????????[CLK_R_CODEC_ADC]???????= &r_codec_adc_clk.common.hw,
> +???????????????[CLK_R_CODEC_DAC]???????= &r_codec_dac_clk.common.hw,
> +???????????????[CLK_R_BUS_CODEC]???????= &r_bus_codec_clk.common.hw,
> +???????????????[CLK_R_DMIC]????????????= &r_dmic_clk.common.hw,
> +???????????????[CLK_R_BUS_DMIC]????????= &r_bus_dmic_clk.common.hw,
> +???????????????[CLK_R_BUS_LRADC]???????= &r_bus_lradc_clk.common.hw,
> +???????????????[CLK_R_I2S]?????????????= &r_i2s_clk.common.hw,
> +???????????????[CLK_R_I2S_ASRC]????????= &r_i2s_asrc_clk.common.hw,
> +???????????????[CLK_R_BUS_I2S]?????????= &r_bus_i2s_clk.common.hw,
> +???????????????[CLK_R_BUS_UART]????????= &r_bus_uart_clk.common.hw,
> +???????????????[CLK_R_BUS_I2C]?????????= &r_bus_i2c_clk.common.hw,
> +???????????????[CLK_R_IR]??????????????= &r_ir_clk.common.hw,
> +???????????????[CLK_R_BUS_IR]??????????= &r_bus_ir_clk.common.hw,
> +???????????????[CLK_R_BUS_MSGBOX]??????=
> &r_bus_msgbox_clk.common.hw,
> +???????????????[CLK_R_BUS_SPINLOCK]????=
> &r_bus_spinlock_clk.common.hw,
> +???????????????[CLK_R_BUS_RTC]?????????= &r_bus_rtc_clk.common.hw,
> +???????},
> +???????.num = CLK_NUMBER,
> +};
> +
> +static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
> +???????[RST_R_BUS_GPADC]???????= { 0x0ec, BIT(16) },
> +???????[RST_R_BUS_THS]?????????= { 0x0fc, BIT(16) },
> +???????[RST_R_BUS_DMA]?????????= { 0x10c, BIT(16) },
> +???????[RST_R_BUS_PWM]?????????= { 0x13c, BIT(16) },
> +???????[RST_R_BUS_CODEC]???????= { 0x14c, BIT(16) },
> +???????[RST_R_BUS_DMIC]????????= { 0x15c, BIT(16) },
> +???????[RST_R_BUS_LRADC]???????= { 0x16c, BIT(16) },
> +???????[RST_R_BUS_I2S]?????????= { 0x17c, BIT(16) },
> +???????[RST_R_BUS_UART]????????= { 0x18c, BIT(16) },
> +???????[RST_R_BUS_I2C]?????????= { 0x19c, BIT(16) },
> +???????[RST_R_BUS_IR]??????????= { 0x1cc, BIT(16) },
> +???????[RST_R_BUS_MSGBOX]??????= { 0x1dc, BIT(16) },
> +???????[RST_R_BUS_SPINLOCK]????= { 0x1ec, BIT(16) },
> +???????[RST_R_BUS_RTC]?????????= { 0x20c, BIT(16) },
> +};
> +
> +static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
> +???????.ccu_clks???????= sun50i_r329_r_ccu_clks,
> +???????.num_ccu_clks???= ARRAY_SIZE(sun50i_r329_r_ccu_clks),
> +
> +???????.hw_clks????????= &sun50i_r329_r_hw_clks,
> +
> +???????.resets?????????= sun50i_r329_r_ccu_resets,
> +???????.num_resets?????= ARRAY_SIZE(sun50i_r329_r_ccu_resets),
> +};
> +
> +static const u32 pll_regs[] = {
> +???????SUN50I_R329_PLL_CPUX_REG,
> +???????SUN50I_R329_PLL_PERIPH_REG,
> +???????SUN50I_R329_PLL_AUDIO0_REG,
> +???????SUN50I_R329_PLL_AUDIO1_REG,
> +};
> +
> +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> +{
> +???????void __iomem *reg;
> +???????u32 val;
> +???????int i;
> +
> +???????reg = of_io_request_and_map(node, 0,
> of_node_full_name(node));
> +???????if (IS_ERR(reg)) {
> +???????????????pr_err("%pOF: Could not map clock registers\n",
> node);
> +???????????????return;
> +???????}
> +
> +???????/* Enable the lock bits and the output enable bits on all
> PLLs */
> +???????for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> +???????????????val = readl(reg + pll_regs[i]);
> +???????????????val |= BIT(29) | BIT(27);
> +???????????????writel(val, reg + pll_regs[i]);
> +???????}
> +
> +???????/*
> +??????? * Force the I/O dividers of PLL-AUDIO1 to reset default
> value
> +??????? *
> +??????? * See the comment before pll-audio1 definition for the
> reason.
> +??????? */
> +
> +???????val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> +???????val &= ~BIT(1);
> +???????val |= BIT(0);
> +???????writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> +
> +???????i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> +???????if (i)
> +???????????????pr_err("%pOF: probing clocks fails: %d\n", node, i);
> +}
> +
> +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> +????????????? sun50i_r329_r_ccu_setup);
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> new file mode 100644
> index 000000000000..62cf65322116
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _CCU_SUN50I_R329_R_H
> +#define _CCU_SUN50I_R329_R_H
> +
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +#define CLK_PLL_CPUX???????????0
> +#define CLK_PLL_PERIPH_BASE????1
> +#define CLK_PLL_PERIPH_2X??????2
> +#define CLK_PLL_PERIPH_800M????3
> +#define CLK_PLL_PERIPH?????????4
> +#define CLK_PLL_AUDIO0?????????5
> +#define CLK_PLL_AUDIO0_DIV2????6
> +#define CLK_PLL_AUDIO0_DIV5????7
> +#define CLK_PLL_AUDIO1_4X??????8
> +#define CLK_PLL_AUDIO1_2X??????9
> +#define CLK_PLL_AUDIO1?????????10
> +#define CLK_R_AHB??????????????11
> +
> +/* R_APB1 exported for PIO */
> +
> +#define CLK_R_APB2?????????????13
> +
> +/* All module / bus gate clocks exported */
> +
> +#define CLK_NUMBER?????(CLK_R_BUS_RTC + 1)
> +
> +#endif /* _CCU_SUN50I_R329_R_H */
> diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..df9bc58de5c4
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +
> +#define CLK_R_APB1?????????????12
> +
> +#define CLK_R_BUS_GPADC????????????????14
> +#define CLK_R_BUS_THS??????????15
> +#define CLK_R_BUS_DMA??????????16
> +#define CLK_R_PWM??????????????17
> +#define CLK_R_BUS_PWM??????????18
> +#define CLK_R_CODEC_ADC????????????????19
> +#define CLK_R_CODEC_DAC????????????????20
> +#define CLK_R_BUS_CODEC????????????????21
> +#define CLK_R_DMIC?????????????22
> +#define CLK_R_BUS_DMIC?????????23
> +#define CLK_R_BUS_LRADC????????????????24
> +#define CLK_R_I2S??????????????25
> +#define CLK_R_I2S_ASRC?????????26
> +#define CLK_R_BUS_I2S??????????27
> +#define CLK_R_BUS_UART?????????28
> +#define CLK_R_BUS_I2C??????????29
> +#define CLK_R_IR???????????????30
> +#define CLK_R_BUS_IR???????????31
> +#define CLK_R_BUS_MSGBOX???????32
> +#define CLK_R_BUS_SPINLOCK?????33
> +#define CLK_R_BUS_RTC??????????34
> +
> +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
> diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..40644f2f21c6
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +
> +#define RST_R_BUS_GPADC????????????????0
> +#define RST_R_BUS_THS??????????1
> +#define RST_R_BUS_DMA??????????2
> +#define RST_R_BUS_PWM??????????3
> +#define RST_R_BUS_CODEC????????????????4
> +#define RST_R_BUS_DMIC?????????5
> +#define RST_R_BUS_LRADC????????????????6
> +#define RST_R_BUS_I2S??????????7
> +#define RST_R_BUS_UART?????????8
> +#define RST_R_BUS_I2C??????????9
> +#define RST_R_BUS_IR???????????10
> +#define RST_R_BUS_MSGBOX???????11
> +#define RST_R_BUS_SPINLOCK?????12
> +#define RST_R_BUS_RTC??????????13
> +
> +#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */




From will at kernel.org  Mon Aug  2 03:03:43 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Aug 2021 11:03:43 +0100
Subject: [PATCH v8 2/2] drivers/perf: hisi: Add driver for HiSilicon PCIe
 PMU
In-Reply-To: <20210728080932.72515-3-liuqi115@huawei.com>
References: <20210728080932.72515-1-liuqi115@huawei.com>
 <20210728080932.72515-3-liuqi115@huawei.com>
Message-ID: <20210802100343.GA27282@willie-the-truck>

On Wed, Jul 28, 2021 at 04:09:32PM +0800, Qi Liu wrote:
> PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported
> to sample bandwidth, latency, buffer occupation etc.
> 
> Each PMU RCiEP device monitors multiple Root Ports, and each RCiEP is
> registered as a PMU in /sys/bus/event_source/devices, so users can
> select target PMU, and use filter to do further sets.
> 
> Filtering options contains:
> event        - select the event.
> subevent     - select the subevent.

Hmm, I was hoping that you would expose all the events as proper perf_events
and get rid of the subevents entirely.

Then userspace could do things like:

  // Count number of RX memory reads
  $ perf stat -e hisi_pcie0_0/rx_memory_read/

  // Count delay cycles
  $ perf stat -e hisi_pcie0_0/latency/

  // Count both of the above (events must be in the same group)
  $ perf stat -g -e hisi_pcie0_0/latency/ -e hisi_pcie0_0/rx_memory_read/

Note that in all three of these cases the hardware will be programmed in
the same way and both HISI_PCIE_CNT and HISI_PCIE_EXT_CNT are allocated!

So for example, doing this (i.e. without the '-g'):

  $ perf stat -e hisi_pcie0_0/latency/ -e hisi_pcie0_0/rx_memory_read/

would fail because the first event would allocate both of the counters.

All you need to do is check the counter scheduling constraints when
accepting an event group in the driver. No need for subevents at all.

Does that make sense?

Will


From sudeep.holla at arm.com  Mon Aug  2 03:10:32 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 2 Aug 2021 11:10:32 +0100
Subject: [PATCH v6 07/17] firmware: arm_scmi: Handle concurrent and
 out-of-order messages
In-Reply-To: <20210712141833.6628-8-cristian.marussi@arm.com>
References: <20210712141833.6628-1-cristian.marussi@arm.com>
 <20210712141833.6628-8-cristian.marussi@arm.com>
Message-ID: <20210802101032.ozlidylogmdt2zqu@bogus>

On Mon, Jul 12, 2021 at 03:18:23PM +0100, Cristian Marussi wrote:
> Even though in case of asynchronous commands an SCMI platform server is

Drop the term "server"

> constrained to emit the delayed response message only after the related
> message response has been sent, the configured underlying transport could
> still deliver such messages together or in inverted order, causing races
> due to the concurrent or out-of-order access to the underlying xfer.
> 
> Introduce a mechanism to grant exclusive access to an xfer in order to
> properly serialize concurrent accesses to the same xfer originating from
> multiple correlated messages.
> 
> Add additional state information to xfer descriptors so as to be able to
> identify out-of-order message deliveries and act accordingly:
> 
>  - when a delayed response is expected but delivered before the related
>    response, the synchronous response is considered as successfully
>    received and the delayed response processing is carried on as usual.
> 
>  - when/if the missing synchronous response is subsequently received, it
>    is discarded as not congruent with the current state of the xfer, or
>    simply, because the xfer has been already released and so, now, the
>    monotonically increasing sequence number carried by the late response
>    is stale.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> ---
> v5 --> v6
> - added spinlock comment
> ---
>  drivers/firmware/arm_scmi/common.h |  18 ++-
>  drivers/firmware/arm_scmi/driver.c | 229 ++++++++++++++++++++++++-----
>  2 files changed, 212 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
> index 2233d0a188fc..9efebe1406d2 100644
> --- a/drivers/firmware/arm_scmi/common.h
> +++ b/drivers/firmware/arm_scmi/common.h
> @@ -19,6 +19,7 @@
>  #include <linux/module.h>
>  #include <linux/refcount.h>
>  #include <linux/scmi_protocol.h>
> +#include <linux/spinlock.h>
>  #include <linux/types.h>
>  
>  #include <asm/unaligned.h>
> @@ -145,6 +146,13 @@ struct scmi_msg {
>   * @pending: True for xfers added to @pending_xfers hashtable
>   * @node: An hlist_node reference used to store this xfer, alternatively, on
>   *	  the free list @free_xfers or in the @pending_xfers hashtable
> + * @busy: An atomic flag to ensure exclusive write access to this xfer
> + * @state: The current state of this transfer, with states transitions deemed
> + *	   valid being:
> + *	    - SCMI_XFER_SENT_OK -> SCMI_XFER_RESP_OK [ -> SCMI_XFER_DRESP_OK ]
> + *	    - SCMI_XFER_SENT_OK -> SCMI_XFER_DRESP_OK
> + *	      (Missing synchronous response is assumed OK and ignored)
> + * @lock: A spinlock to protect state and busy fields.
>   */
>  struct scmi_xfer {
>  	int transfer_id;
> @@ -156,6 +164,15 @@ struct scmi_xfer {
>  	refcount_t users;
>  	bool pending;
>  	struct hlist_node node;
> +#define SCMI_XFER_FREE		0
> +#define SCMI_XFER_BUSY		1
> +	atomic_t busy;
> +#define SCMI_XFER_SENT_OK	0
> +#define SCMI_XFER_RESP_OK	1
> +#define SCMI_XFER_DRESP_OK	2
> +	int state;
> +	/* A lock to protect state and busy fields */
> +	spinlock_t lock;
>  };
>  
>  /*
> @@ -392,5 +409,4 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
>  void scmi_notification_instance_data_set(const struct scmi_handle *handle,
>  					 void *priv);
>  void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
> -
>  #endif /* _SCMI_COMMON_H */
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 245ede223302..5ef33d692670 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -369,6 +369,7 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
>  
>  	if (!IS_ERR(xfer)) {
>  		refcount_set(&xfer->users, 1);
> +		atomic_set(&xfer->busy, SCMI_XFER_FREE);
>  		xfer->transfer_id = atomic_inc_return(&transfer_last_id);
>  	}
>  	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
> @@ -430,6 +431,168 @@ scmi_xfer_lookup_unlocked(struct scmi_xfers_info *minfo, u16 xfer_id)
>  	return xfer ?: ERR_PTR(-EINVAL);
>  }
>  
> +/**
> + * scmi_msg_response_validate  - Validate message type against state of related
> + * xfer
> + *
> + * @cinfo: A reference to the channel descriptor.
> + * @msg_type: Message type to check
> + * @xfer: A reference to the xfer to validate against @msg_type
> + *
> + * This function checks if @msg_type is congruent with the current state of
> + * a pending @xfer; if an asynchronous delayed response is received before the
> + * related synchronous response (Out-of-Order Delayed Response) the missing
> + * synchronous response is assumed to be OK and completed, carrying on with the
> + * Delayed Response: this is done to address the case in which the underlying
> + * SCMI transport can deliver such out-of-order responses.
> + *
> + * Context: Assumes to be called with xfer->lock already acquired.
> + *
> + * Return: 0 on Success, error otherwise
> + */
> +static inline int scmi_msg_response_validate(struct scmi_chan_info *cinfo,
> +					     u8 msg_type,
> +					     struct scmi_xfer *xfer)
> +{
> +	/*
> +	 * Even if a response was indeed expected on this slot at this point,
> +	 * a buggy platform could wrongly reply feeding us an unexpected
> +	 * delayed response we're not prepared to handle: bail-out safely
> +	 * blaming firmware.
> +	 */
> +	if (msg_type == MSG_TYPE_DELAYED_RESP && !xfer->async_done) {
> +		dev_err(cinfo->dev,
> +			"Delayed Response for %d not expected! Buggy F/W ?\n",
> +			xfer->hdr.seq);
> +		return -EINVAL;
> +	}
> +
> +	switch (xfer->state) {
> +	case SCMI_XFER_SENT_OK:
> +		if (msg_type == MSG_TYPE_DELAYED_RESP) {
> +			/*
> +			 * Delayed Response expected but delivered earlier.
> +			 * Assume message RESPONSE was OK and skip state.
> +			 */
> +			xfer->hdr.status = SCMI_SUCCESS;
> +			xfer->state = SCMI_XFER_RESP_OK;
> +			complete(&xfer->done);
> +			dev_warn(cinfo->dev,
> +				 "Received valid OoO Delayed Response for %d\n",
> +				 xfer->hdr.seq);
> +		}
> +		break;
> +	case SCMI_XFER_RESP_OK:
> +		if (msg_type != MSG_TYPE_DELAYED_RESP)
> +			return -EINVAL;
> +		break;
> +	case SCMI_XFER_DRESP_OK:
> +		/* No further message expected once in SCMI_XFER_DRESP_OK */

Do we really need this case ? If so, how can this happen.

> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static bool scmi_xfer_is_free(struct scmi_xfer *xfer)
> +{
> +	int ret;
> +
> +	ret = atomic_cmpxchg(&xfer->busy, SCMI_XFER_FREE, SCMI_XFER_BUSY);
> +
> +	return ret == SCMI_XFER_FREE;
> +}
> +
> +/**
> + * scmi_xfer_command_acquire  -  Helper to lookup and acquire a command xfer
> + *
> + * @cinfo: A reference to the channel descriptor.
> + * @msg_hdr: A message header to use as lookup key
> + *
> + * When a valid xfer is found for the sequence number embedded in the provided
> + * msg_hdr, reference counting is properly updated and exclusive access to this
> + * xfer is granted till released with @scmi_xfer_command_release.
> + *
> + * Return: A valid @xfer on Success or error otherwise.
> + */
> +static inline struct scmi_xfer *
> +scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
> +{
> +	int ret;
> +	unsigned long flags;
> +	struct scmi_xfer *xfer;
> +	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> +	struct scmi_xfers_info *minfo = &info->tx_minfo;
> +	u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
> +	u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
> +
> +	/* Are we even expecting this? */
> +	spin_lock_irqsave(&minfo->xfer_lock, flags);
> +	xfer = scmi_xfer_lookup_unlocked(minfo, xfer_id);
> +	if (IS_ERR(xfer)) {
> +		dev_err(cinfo->dev,
> +			"Message for %d type %d is not expected!\n",
> +			xfer_id, msg_type);
> +		spin_unlock_irqrestore(&minfo->xfer_lock, flags);
> +		return xfer;
> +	}
> +	refcount_inc(&xfer->users);
> +	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
> +
> +	spin_lock_irqsave(&xfer->lock, flags);
> +	ret = scmi_msg_response_validate(cinfo, msg_type, xfer);
> +	/*
> +	 * If a pending xfer was found which was also in a congruent state with
> +	 * the received message, acquire exclusive access to it setting the busy
> +	 * flag.
> +	 * Spins only on the rare limit condition of concurrent reception of
> +	 * RESP and DRESP for the same xfer.
> +	 */
> +	if (!ret) {
> +		spin_until_cond(scmi_xfer_is_free(xfer));

I agree with the discussion between you and Peter around this, so I assume
it will be renamed or handled accordingly.

> +		xfer->hdr.type = msg_type;
> +	}
> +	spin_unlock_irqrestore(&xfer->lock, flags);
> +
> +	if (ret) {
> +		dev_err(cinfo->dev,
> +			"Invalid message type:%d for %d - HDR:0x%X  state:%d\n",
> +			msg_type, xfer_id, msg_hdr, xfer->state);
> +		/* On error the refcount incremented above has to be dropped */
> +		__scmi_xfer_put(minfo, xfer);
> +		xfer = ERR_PTR(-EINVAL);
> +	}
> +
> +	return xfer;
> +}
> +
> +static inline void scmi_xfer_command_release(struct scmi_info *info,
> +					     struct scmi_xfer *xfer)
> +{
> +	atomic_set(&xfer->busy, SCMI_XFER_FREE);
> +	__scmi_xfer_put(&info->tx_minfo, xfer);
> +}
> +
> +/**
> + * scmi_xfer_state_update  - Update xfer state
> + *
> + * @xfer: A reference to the xfer to update
> + *
> + * Context: Assumes to be called on an xfer exclusively acquired using the
> + *	    busy flag.
> + */
> +static inline void scmi_xfer_state_update(struct scmi_xfer *xfer)
> +{
> +	switch (xfer->hdr.type) {
> +	case MSG_TYPE_COMMAND:
> +		xfer->state = SCMI_XFER_RESP_OK;
> +		break;
> +	case MSG_TYPE_DELAYED_RESP:
> +		xfer->state = SCMI_XFER_DRESP_OK;
> +		break;
> +	}
> +}

Can't this be if () ..  else if(), switch sounds unnecessary for 2 conditions.

Other than the things already discussed with you and Peter, don't have much to
add ATM. I may look at this with fresh eyes once again in the next version.

-- 
Regards,
Sudeep


From Jonathan.Cameron at Huawei.com  Mon Aug  2 03:16:47 2021
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Mon, 2 Aug 2021 11:16:47 +0100
Subject: [PATCH] iio: adc: fsl-imx25-gcq: fix the right check and
 simplify code
In-Reply-To: <b84ea3e4-5650-d6ac-36f6-98067b286b45@cmss.chinamobile.com>
References: <20210727125209.28248-1-tangbin@cmss.chinamobile.com>
 <20210731174551.188aee79@jic23-huawei>
 <b84ea3e4-5650-d6ac-36f6-98067b286b45@cmss.chinamobile.com>
Message-ID: <20210802111647.000012ee@Huawei.com>

On Mon, 2 Aug 2021 10:31:58 +0800
tangbin <tangbin at cmss.chinamobile.com> wrote:

> Hi Jonathan:
> 
> On 2021/8/1 0:45, Jonathan Cameron wrote:
> > On Tue, 27 Jul 2021 20:52:09 +0800
> > Tang Bin <tangbin at cmss.chinamobile.com> wrote:
> >  
> >> For the function of platform_get_irq(), the example in platform.c is
> >> *		int irq = platform_get_irq(pdev, 0);
> >> *		if (irq < 0)
> >> *			return irq;
> >> So the return value of zero is unnecessary to check. And move it
> >> up to a little bit can simplify the code jump.
> >>
> >> Co-developed-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
> >> Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
> >> Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>  
> > Hi,
> >
> > Logically it is better to keep the irq handling all together, so
> > I would prefer we didn't move it.  
> Got it in this place.
> >
> > Also, platform_get_irq() is documented as never returning 0, so the current
> > code is not incorrect.  As such, this looks like noise unless there is
> > some plan to make use of the 0 return value?  What benefit do we get from
> > this change?  
> 
> Thanks for your reply, I think the benefit of this change maybe just 
> simplify the code.
> 
> Because the return value is never equal to 0, so the check in here is 
> redundant.
> 
> We can make the patch like this:
> 
> >> ---
> >>   drivers/iio/adc/fsl-imx25-gcq.c | 12 ++++--------
> >>   1 file changed, 4 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
> >> index 8cb51cf7a..d28976f21 100644
> >> --- a/drivers/iio/adc/fsl-imx25-gcq.c
> >> +++ b/drivers/iio/adc/fsl-imx25-gcq.c
> >> @@ -320,6 +320,10 @@ static int mx25_gcq_probe(struct platform_device *pdev)
> >>   	if (ret)
> >>   		return ret;
> >>   
> >> +	priv->irq = platform_get_irq(pdev, 0);
> >> +	if (priv->irq < 0)
> >> +		return priv->irq;
> >> +
> >>   	for (i = 0; i != 4; ++i) {
> >>   		if (!priv->vref[i])
> >>   			continue;
> >> @@ -336,14 +340,6 @@ static int mx25_gcq_probe(struct platform_device *pdev)
> >>   		goto err_vref_disable;
> >>   	}
> >>   
> >> -	priv->irq = platform_get_irq(pdev, 0);
> >> -	if (priv->irq <= 0) {
> >> -		ret = priv->irq;
> >> -		if (!ret)
> >> -			ret = -ENXIO;
> >> -		goto err_clk_unprepare;
> >> -	}
> >> -  
> 
> 	priv->irq = platform_get_irq(pdev, 0);
> 	if (priv->irq < 0) {
> 		ret = priv->irq;
> 		goto err_clk_unprepare;
> 	}
> 
>  ??? If you think this is ok, I will send V2 for you. If you think these 
> change is meaningless,

OK, it's a minor tidy up, so lets go with that, or perhaps this is even tidier?
Assuming types of ret and irq are appropriate (I've not checked!)


	ret = platform_get_irq(pdev, 0);
	if (ret)
		goto err_clk_unprepare;

	priv->irq = ret;


> 
> just dropped this.
> 
> Thanks
> 
> Tang Bin
> 
> 
> 
> 



From wenst at chromium.org  Mon Aug  2 03:21:01 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 2 Aug 2021 18:21:01 +0800
Subject: [PATCH v2 5/8] ASoC: mediatek: mt8195: add platform driver
In-Reply-To: <fc12d71febfebda12e57b287de0ad2668db20ffa.camel@mediatek.com>
References: <20210629014736.31153-1-trevor.wu@mediatek.com>
 <20210629014736.31153-6-trevor.wu@mediatek.com>
 <CAGXv+5FzOs+=9PbYAEahVXvdJG1FnRkSUo_r3AVYZzNKGqg0oA@mail.gmail.com>
 <9929a3a20df1a89fc94baf7c75c0c65d9a61de0f.camel@mediatek.com>
 <CAGXv+5HFjM_N_MM5ZddGLcuYVsOXAJwfNuKvB5Cfo0k=nO456g@mail.gmail.com>
 <266fd1f5de56743292ac5fc64664113c0bb0e41a.camel@mediatek.com>
 <CAGXv+5FVWNgCeAseULOJbU3=6ggQ=b=mtP_sEQd0NgtdX-ttiQ@mail.gmail.com>
 <31bcc613abb0f805400faa8b8108100cb578d9b1.camel@mediatek.com>
 <CAGXv+5HOL5j4gjgJa0RLjvf3+Vt2sGZcWU1KQXwjn7DOYy-JWg@mail.gmail.com>
 <fc12d71febfebda12e57b287de0ad2668db20ffa.camel@mediatek.com>
Message-ID: <CAGXv+5HGYOPHD3xro86xj0q4waJksfS=6NJa1hPU0=n1-Ur1bw@mail.gmail.com>

On Mon, Jul 26, 2021 at 10:31 PM Trevor Wu <trevor.wu at mediatek.com> wrote:
>
> On Fri, 2021-07-23 at 14:27 +0800, Chen-Yu Tsai wrote:
> > On Thu, Jul 22, 2021 at 4:56 PM Trevor Wu <trevor.wu at mediatek.com>
> > wrote:
> > >
> > > On Mon, 2021-07-19 at 18:05 +0800, Chen-Yu Tsai wrote:
> > > > Hi,
> > > >
> > > > On Thu, Jul 15, 2021 at 7:05 PM Trevor Wu <trevor.wu at mediatek.com
> > > > >
> > > > wrote:
> > > > >
> > > > > On Tue, 2021-07-13 at 14:00 +0800, Chen-Yu Tsai wrote:
> > > > > > On Mon, Jul 12, 2021 at 11:10 PM Trevor Wu <
> > > > > > trevor.wu at mediatek.com>
> > > > > > wrote:
> > > > > > >
> > > > > > > On Mon, 2021-07-12 at 14:57 +0800, Chen-Yu Tsai wrote:
> > > > > > > >  are all internal Hi,
> > > > > > > >
> > > > > > > > On Tue, Jun 29, 2021 at 9:49 AM Trevor Wu <
> > > > > > > > trevor.wu at mediatek.com
> > > > > > > > >
> > > > > > > >
> > > > > > > > wrote:
> > > > > > > > >
> > > > > > > > > This patch adds mt8195 platform and affiliated driver.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
> > > > > > > > > ---
> > > > > > > > >  sound/soc/mediatek/Kconfig                     |    9
> > > > > > > > > +
> > > > > > > > >  sound/soc/mediatek/Makefile                   |    1 +
> > > > > > > > >  sound/soc/mediatek/mt8195/Makefile            |   11 +
> > > > > > > > >  sound/soc/mediatek/mt8195/mt8195-afe-clk.c    |  899
> > > > > > > > > +++++
> > > > > > > > >  sound/soc/mediatek/mt8195/mt8195-afe-clk.h    |  201 +
> > > > > > > > >  sound/soc/mediatek/mt8195/mt8195-afe-common.h |  200 +
> > > > > > > > >  sound/soc/mediatek/mt8195/mt8195-afe-pcm.c    | 3264
> > > > > > > > > +++++++++++++++++
> > > > > > > > >  sound/soc/mediatek/mt8195/mt8195-reg.h        | 2793
> > > > > > > > > ++++++++++++++
> > > > > > > > >  8 files changed, 7378 insertions(+)
> > > > > > > > >  create mode 100644 sound/soc/mediatek/mt8195/Makefile
> > > > > > > > >  create mode 100644 sound/soc/mediatek/mt8195/mt8195-
> > > > > > > > > afe-
> > > > > > > > > clk.c
> > > > > > > > >  create mode 100644 sound/soc/mediatek/mt8195/mt8195-
> > > > > > > > > afe-
> > > > > > > > > clk.h
> > > > > > > > >  create mode 100644 sound/soc/mediatek/mt8195/mt8195-
> > > > > > > > > afe-
> > > > > > > > > common.h
> > > > > > > > >  create mode 100644 sound/soc/mediatek/mt8195/mt8195-
> > > > > > > > > afe-
> > > > > > > > > pcm.c
> > > > > > > > >  create mode 100644 sound/soc/mediatek/mt8195/mt8195-
> > > > > > > > > reg.h
> > > > > > > > >
> > > > > > > > > diff --git a/sound/soc/mediatek/Kconfig
> > > > > > > > > b/sound/soc/mediatek/Kconfig
> > > > > > > > > index 74dae4332d17..3389f382be06 100644
> > > > > > > > > --- a/sound/soc/mediatek/Kconfig
> > > > > > > > > +++ b/sound/soc/mediatek/Kconfig
> > > > > > > > > @@ -184,3 +184,12 @@ config
> > > > > > > > > SND_SOC_MT8192_MT6359_RT1015_RT5682
> > > > > > > > >           with the MT6359 RT1015 RT5682 audio codec.
> > > > > > > > >           Select Y if you have such device.
> > > > > > > > >           If unsure select "N".
> > > > > > > > > +
> > > > > > > > > +config SND_SOC_MT8195
> > > > > > > > > +       tristate "ASoC support for Mediatek MT8195
> > > > > > > > > chip"
> > > > > > > > > +       select SND_SOC_MEDIATEK
> > > > > > > > > +       help
> > > > > > > > > +         This adds ASoC platform driver support for
> > > > > > > > > Mediatek
> > > > > > > > > MT8195 chip
> > > > > > > > > +         that can be used with other codecs.
> > > > > > > > > +         Select Y if you have such device.
> > > > > > > > > +         If unsure select "N".
> > > > > > > > > diff --git a/sound/soc/mediatek/Makefile
> > > > > > > > > b/sound/soc/mediatek/Makefile
> > > > > > > > > index f6cb6b8508e3..34778ca12106 100644
> > > > > > > > > --- a/sound/soc/mediatek/Makefile
> > > > > > > > > +++ b/sound/soc/mediatek/Makefile
> > > > > > > > > @@ -5,3 +5,4 @@ obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
> > > > > > > > >  obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
> > > > > > > > >  obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
> > > > > > > > >  obj-$(CONFIG_SND_SOC_MT8192) += mt8192/
> > > > > > > > > +obj-$(CONFIG_SND_SOC_MT8195) += mt8195/
> > > > > > > > > diff --git a/sound/soc/mediatek/mt8195/Makefile
> > > > > > > > > b/sound/soc/mediatek/mt8195/Makefile
> > > > > > > > > new file mode 100644
> > > > > > > > > index 000000000000..b2c9fd88f39e
> > > > > > > > > --- /dev/null
> > > > > > > > > +++ b/sound/soc/mediatek/mt8195/Makefile
> > > > > > > > > @@ -0,0 +1,11 @@
> > > > > > > > > +# SPDX-License-Identifier: GPL-2.0
> > > > > > > > > +
> > > > > > > > > +# platform driver
> > > > > > > > > +snd-soc-mt8195-afe-objs := \
> > > > > > > > > +       mt8195-afe-clk.o \
> > > > > > > > > +       mt8195-afe-pcm.o \
> > > > > > > > > +       mt8195-dai-adda.o \
> > > > > > > > > +       mt8195-dai-etdm.o \
> > > > > > > > > +       mt8195-dai-pcm.o
> > > > > > > > > +
> > > > > > > > > +obj-$(CONFIG_SND_SOC_MT8195) += snd-soc-mt8195-afe.o
> > > > > > > > > diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-clk.c
> > > > > > > > > b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c
> > > > > > > > > new file mode 100644
> > > > > > > > > index 000000000000..57aa799b4f41
> > > > > > > > > --- /dev/null
> > > > > > > > > +++ b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c
> > > > > > > > > @@ -0,0 +1,899 @@
> > > > > > > > > +// SPDX-License-Identifier: GPL-2.0
> > > > > > > > > +/*
> > > > > > > > > + * mt8195-afe-clk.c  --  Mediatek 8195 afe clock ctrl
> > > > > > > > > + *
> > > > > > > > > + * Copyright (c) 2021 MediaTek Inc.
> > > > > > > > > + * Author: Bicycle Tsai <bicycle.tsai at mediatek.com>
> > > > > > > > > + *         Trevor Wu <trevor.wu at mediatek.com>
> > > > > > > > > + */
> > > > > > > > > +
> > > > > > > > > +#include <linux/clk.h>
> > > > > > > > > +
> > > > > > > > > +#include "mt8195-afe-common.h"
> > > > > > > > > +#include "mt8195-afe-clk.h"
> > > > > > > > > +#include "mt8195-reg.h"
> > > > > > > > > +
> > > > > > > > > +static const char *aud_clks[MT8195_CLK_NUM] = {
> > > > > > > >
> > > > > > > > Most of these clocks are not described in the device tree
> > > > > > > > binding. If
> > > > > > > > the driver needs to reference them, they should be
> > > > > > > > described.
> > > > > > > > We
> > > > > > > > should
> > > > > > > > not be hard-coding clock names across different drivers.
> > > > > > > >
> > > > > > >
> > > > > > > Sorry, I didn't know I have to list all clocks in the dt-
> > > > > > > binding.
> > > > > > > Originally, I thought these clocks will be described in the
> > > > > > > clock
> > > > > > > binding, so I didn't add them to the binding of afe driver.
> > > > > > > I will add these clocks to mt8195-afe-pcm.yaml.
> > > > > >
> > > > > > If the device consumes clocks, then the clocks that get
> > > > > > consumed
> > > > > > should
> > > > > > be listed in the device's bindings. This is not related to
> > > > > > the
> > > > > > clock
> > > > > > bindings, which is a clock provider.
> > > > > >
> > > > >
> > > > > Got it. Thanks.
> > > > >
> > > > > > > > The more important question is, why does the driver need
> > > > > > > > to
> > > > > > > > reference
> > > > > > > > all of them? Maybe we should take a step back and draw
> > > > > > > > out a
> > > > > > > > clock
> > > > > > > > tree
> > > > > > > > diagram for the hardware?
> > > > > > > >
> > > > > > >
> > > > > > > The clock structure is PLL -> MUX -> GATE.
> > > > > > > xtal, pll and divider are the possible clock inputs for
> > > > > > > MUX.
> > > > > > > Because we select the clock input of audio module based on
> > > > > > > the
> > > > > > > use
> > > > > > > case, we use clk_get to retrive all clocks which are
> > > > > > > possible
> > > > > > > to be
> > > > > > > used.
> > > > > >
> > > > > > So I see a couple the driver is doing reparenting:
> > > > > >
> > > > > >   a. Reparent audio_h to standard oscillator when ADDA is not
> > > > > > used,
> > > > > >      presumably to let the APLL be turned off
> > > > > >
> > > > > > Why not just turn off audio_h? It looks like audio_h feeds a
> > > > > > couple
> > > > > > clock
> > > > > > gates in the audio subsystem. Just a guess, but is this the
> > > > > > AHB
> > > > > > bus
> > > > > > clock?
> > > > > > Why not just have it parented to "univpll_d7" all the time
> > > > > > then?
> > > > > >
> > > > >
> > > > > Sorry, I am not sure if it is the AHB bus clock.
> > > > > I only know how audio module uses the clock.
> > > > > audio_h feeds to some clock gate like aud_adc_hires, which is
> > > > > used
> > > > > when
> > > > > sampling rate is higher than 48kHz, and hardware designer
> > > > > suggests
> > > > > us
> > > > > use apll1_ck when AFE requrires the clock.
> > > >
> > > > I see. So the simplified explanation is high clock rate for high
> > > > res
> > > > audio.
> > > > Would high clock rate work for standard sample rates?
> > >
> > > As far as I know, HW will switch clock to hires clock automatically
> > > when the required rate is high,(ex: aud_adc and aud_adc_hires) so
> > > it
> > > can't be controlled by driver.
> >
> > I see. That might not be so friendly to the Linux clk driver.
> >
> > > > Would using apll1 or univpll all the time work, instead of
> > > > reparenting?
> > > > What's the gain if we do reparenting?
> > > >
> > >
> > > As you said before, the gain is apll can be turned off when the
> > > clock
> > > is not requrired by ADDA. That's why we didn't use apll all the
> > > time.
> >
> > Right, and what's the gain from turning it off? Lower power
> > consumption?
> >
>
> Yes. Xtal_26m is supplied to most modules, but APLL1 is mainly used by
> afe. When audio feature is not used, we hope APLL1 can be turned off to
> lower power consumption.
>
> > > > > As I know, DSP also requires audio_h.
> > > > > When we disable the clock in AFE driver, the ref count in CCF
> > > > > is
> > > > > not
> > > > > becoming zero if DSP still uses it.
> > > > > But only AFE requires higher clock rate, so we reparent audio_h
> > > > > to
> > > > > 26M
> > > > > when it's not required in adda module.
> > > >
> > > > I see. Wouldn't reparenting the clock while it is in use by
> > > > another
> > > > module
> > > > cause glitches?
> > >
> > > I checked with the DSP owner.
> > > audio_h clock is required for DSP bus, but the clock rate is not
> > > important.
> > > The only thing it cares is audio_h should be powered on, so
> > > reparenting
> > > is harmless for DSP.
> >
> > OK.
> >
> > > > > > Also, reparenting really should be done implicitly with
> > > > > > clk_set_rate()
> > > > > > with the clock driver supporting reparenting on rate changes.
> > > > > >
> > > > > >   b. Assignment of PLLs for I2S/PCM MCLK outputs
> > > > > >
> > > > > > Is there a reason for explicit assignment, other than clock
> > > > > > rate
> > > > > > conflicts?
> > > > > > CCF supports requesting and locking the clock rate. And
> > > > > > again,
> > > > > > implicit
> > > > > > reparenting should be the norm. The clock driver's purpose is
> > > > > > to
> > > > > > fulfill
> > > > > > any and all clock rate requirements from its consumers. The
> > > > > > consumer
> > > > > > should
> > > > > > only need to ask for the clock rate, not a specific parent,
> > > > > > unless
> > > > > > there
> > > > > > are details that are not yet covered by the CCF.
> > > > > >
> > > > >
> > > > > For MCLK output, we should configure divider to get the target
> > > > > rate,
> > > > > and it can only divide the clock from current parent source.
> > > > > So we should do reparent to divider's parent in case the parent
> > > > > rate is
> > > > > not a multiple of target rate.
> > > >
> > > > Right. That is expected. What I'm saying is that the CCF provides
> > > > the
> > > > framework for automatically reparenting based on the requested
> > > > clock
> > > > rate. This is done in the clock driver's .determine_rate op.
> > > >
> > > > When properly implemented, and also restricting or locking the
> > > > clock
> > > > rates
> > > > of the PLLs, then you can simply request a clock rate on the leaf
> > > > clock,
> > > > in this case one of the MCLKs, and the CCF and clock driver would
> > > > handle
> > > > everything else. The consumer should not be reparenting clocks
> > > > manually
> > > > unless for a very good reason which cannot be satisfied by the
> > > > CCF.
> > > >
> > >
> > > In some use cases, we really need to reparent clock manually.
> > > For example, spdif in(slave) -> .... -> i2s out(master)
> > >
> > > APLL3/APLL4 are reserved for slave input like earc in or spdif in,
> > > which can refer to the external clock source.(APLL3 syncs with
> > > earc,
> > > and APLL4 syncs with spdif in.)
> > >
> > > When i2s out selects the clock source to APLL4, this makes sure
> > > that
> > > spdif in and i2s out works in the same clock source.
> > > If we just use APLL1/APLL2 on i2s out, there is little rate
> > > mismatch
> > > between data input and output. Finally, it results in XRUN.
> >
> > I see, that makes more sense.
> >
> > > If we only use set_rate, it's possible that it can't switch to the
> > > expected PLL source, because the rate of APLL3/APLL4 should be
> > > close to
> > > APLL1/APLL2.
> >
> > Well, in theory the CCF should choose the one with the closest rate.
> > And if APLL3/APLL4 is already tracking the external clock source, its
> > clock rate should match.
> >
> > If it's a static requirement, maybe we could replace the *-mclk-
> > source
> > DT properties with standard assigned-clocks and assigned-clock-
> > parents?
> > This would get handled by CCF directly, and then the only thing the
> > clk driver has to do is make sure it doesn't get reparented again.
> >
> > Or is there a need to do reparenting at runtime?
> >
>
> For the use case of APLL3/APLL4, static assignment should be ok.
>
> But I checked with CCF owner, we can't just use clk_set_rate(divider,
> rate) to get expected MCLK output, because reparenting MUX
> automatically is not supported now. (PLL -> MUX -> divider)
>
> We still have to call clk_set_parent() before clk_set_rate(). Which
> means some information should be got from DTS to check whether the PLL
> source can be switched or not, so *-mclk-source should be keeped to
> identify the case.

So for the clk stuff I already provided a proof of concept [1] offline.

I would like to see a device tree description that follows the design
of the hardware, such as only listing the clocks that actually do feed
into the audio subsystem, and not including all their parents (and
grand parents).

The driver should follow that description.


ChenYu

[1] https://crrev.com/c/3060172

> > > > > > A related question: the chip has five APLLs. How many MCLK
> > > > > > combinations
> > > > > > does the application need to support? I assume this includes
> > > > > > the
> > > > > > standard
> > > > > > 24.576 MHz and 22.5792 MHz clock rates.
> > > > > >
> > > > >
> > > > > APLL1 and APLL2 are used in most AFE modules, so their rate
> > > > > should
> > > > > be
> > > > > fixed.
> > > > > APLL1 is fixed to 196608000Hz.
> > > > > APLL2 is fixed to 180633600Hz.
> > > > > APLL is inputed to the divider(8bit), and MCLK is the output of
> > > > > divider.
> > > > > Other APLLs are reserved for some special usage which can't be
> > > > > supported by APLL1 & APLL2.
> > > > > But APLL3~APLL5 aren't used in the series, so I will remove
> > > > > them in
> > > > > v3.
> > > > >
> > > > > > > Some of them are not used in this series, because some
> > > > > > > modules
> > > > > > > are
> > > > > > > still developing. Should I only keep the clocks that have
> > > > > > > been
> > > > > > > used
> > > > > > > in
> > > > > > > the series?
> > > > > >
> > > > > > Yes please. Only add the ones that are used. Things that
> > > > > > aren't
> > > > > > used
> > > > > > don't get tested and verified, and end up as dead code. If
> > > > > > there
> > > > > > are
> > > > > > plans to extend them in the future, and you can leave
> > > > > > comments
> > > > > > stating
> > > > > > that intent, and also mention it in the cover letter.
> > > > > >
> > > > >
> > > > > OK, I will remove the unused clock in v3.
> > > > >
> > > > > > > > > +       /* xtal */
> > > > > > > > > +       [MT8195_CLK_XTAL_26M] = "clk26m",
> > > > > > > > > +       /* pll */
> > > > > > > > > +       [MT8195_CLK_APMIXED_APLL1] = "apll1",
> > > > > > > > > +       [MT8195_CLK_APMIXED_APLL2] = "apll2",
> > > > > > > > > +       [MT8195_CLK_APMIXED_APLL3] = "apll3",
> > > > > > > > > +       [MT8195_CLK_APMIXED_APLL4] = "apll4",
> > > > > > > > > +       [MT8195_CLK_APMIXED_APLL5] = "apll5",
> > > > > > > > > +       [MT8195_CLK_APMIXED_HDMIRX_APLL] =
> > > > > > > > > "hdmirx_apll",
> > > > > > > > > +       /* divider */
> > > > > > > > > +       [MT8195_CLK_TOP_APLL1] = "apll1_ck",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL1_D4] = "apll1_d4",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL2] = "apll2_ck",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL2_D4] = "apll2_d4",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL3] = "apll3_ck",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL3_D4] = "apll3_d4",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL4] = "apll4_ck",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL4_D4] = "apll4_d4",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL5] = "apll5_ck",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL5_D4] = "apll5_d4",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL12_DIV0] = "apll12_div0",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL12_DIV1] = "apll12_div1",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL12_DIV2] = "apll12_div2",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL12_DIV3] = "apll12_div3",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL12_DIV4] = "apll12_div4",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL12_DIV9] = "apll12_div9",
> > > > > > > > > +       [MT8195_CLK_TOP_HDMIRX_APLL] =
> > > > > > > > > "hdmirx_apll_ck",
> > > > > > > > > +       [MT8195_CLK_TOP_MAINPLL_D4_D4] =
> > > > > > > > > "mainpll_d4_d4",
> > > > > > > > > +       [MT8195_CLK_TOP_MAINPLL_D5_D2] =
> > > > > > > > > "mainpll_d5_d2",
> > > > > > > > > +       [MT8195_CLK_TOP_MAINPLL_D7_D2] =
> > > > > > > > > "mainpll_d7_d2",
> > > > > > > > > +       [MT8195_CLK_TOP_UNIVPLL_D4] = "univpll_d4",
> > > > > > > > > +       /* mux */
> > > > > > > > > +       [MT8195_CLK_TOP_APLL1_SEL] = "apll1_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL2_SEL] = "apll2_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL3_SEL] = "apll3_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL4_SEL] = "apll4_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_APLL5_SEL] = "apll5_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_A1SYS_HP_SEL] = "a1sys_hp_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_A2SYS_SEL] = "a2sys_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_A3SYS_SEL] = "a3sys_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_A4SYS_SEL] = "a4sys_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_ASM_H_SEL] = "asm_h_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_ASM_M_SEL] = "asm_m_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_ASM_L_SEL] = "asm_l_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_AUD_IEC_SEL] = "aud_iec_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_AUD_INTBUS_SEL] =
> > > > > > > > > "aud_intbus_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_AUDIO_H_SEL] = "audio_h_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL] =
> > > > > > > > > "audio_local_bus_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_DPTX_M_SEL] = "dptx_m_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_INTDIR_SEL] = "intdir_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_I2SO1_M_SEL] = "i2so1_m_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_I2SO2_M_SEL] = "i2so2_m_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_I2SI1_M_SEL] = "i2si1_m_sel",
> > > > > > > > > +       [MT8195_CLK_TOP_I2SI2_M_SEL] = "i2si2_m_sel",
> > > > > > > > > +       /* clock gate */
> > > > > > > > > +       [MT8195_CLK_TOP_MPHONE_SLAVE_B] =
> > > > > > > > > "mphone_slave_b",
> > > > > > > > > +       [MT8195_CLK_TOP_CFG_26M_AUD] = "cfg_26m_aud",
> > > > > > > > > +       [MT8195_CLK_INFRA_AO_AUDIO] = "infra_ao_audio",
> > > > > > > > > +       [MT8195_CLK_INFRA_AO_AUDIO_26M_B] =
> > > > > > > > > "infra_ao_audio_26m_b",
> > > > > > > > > +       [MT8195_CLK_SCP_ADSP_AUDIODSP] =
> > > > > > > > > "scp_adsp_audiodsp",
> > > > > > > >
> > > > > > > >
> > > > > > > > > +       [MT8195_CLK_AUD_AFE] = "aud_afe",
> > > > > > > > > +       [MT8195_CLK_AUD_LRCK_CNT] = "aud_lrck_cnt",
> > > > > > > > > +       [MT8195_CLK_AUD_SPDIFIN_TUNER_APLL] =
> > > > > > > > > "aud_spdifin_tuner_apll",
> > > > > > > > > +       [MT8195_CLK_AUD_SPDIFIN_TUNER_DBG] =
> > > > > > > > > "aud_spdifin_tuner_dbg",
> > > > > > > > > +       [MT8195_CLK_AUD_UL_TML] = "aud_ul_tml",
> > > > > > > > > +       [MT8195_CLK_AUD_APLL1_TUNER] =
> > > > > > > > > "aud_apll1_tuner",
> > > > > > > > > +       [MT8195_CLK_AUD_APLL2_TUNER] =
> > > > > > > > > "aud_apll2_tuner",
> > > > > > > > > +       [MT8195_CLK_AUD_TOP0_SPDF] = "aud_top0_spdf",
> > > > > > > > > +       [MT8195_CLK_AUD_APLL] = "aud_apll",
> > > > > > > > > +       [MT8195_CLK_AUD_APLL2] = "aud_apll2",
> > > > > > > > > +       [MT8195_CLK_AUD_DAC] = "aud_dac",
> > > > > > > > > +       [MT8195_CLK_AUD_DAC_PREDIS] = "aud_dac_predis",
> > > > > > > > > +       [MT8195_CLK_AUD_TML] = "aud_tml",
> > > > > > > > > +       [MT8195_CLK_AUD_ADC] = "aud_adc",
> > > > > > > > > +       [MT8195_CLK_AUD_DAC_HIRES] = "aud_dac_hires",
> > > > > > > > > +       [MT8195_CLK_AUD_A1SYS_HP] = "aud_a1sys_hp",
> > > > > > > > > +       [MT8195_CLK_AUD_AFE_DMIC1] = "aud_afe_dmic1",
> > > > > > > > > +       [MT8195_CLK_AUD_AFE_DMIC2] = "aud_afe_dmic2",
> > > > > > > > > +       [MT8195_CLK_AUD_AFE_DMIC3] = "aud_afe_dmic3",
> > > > > > > > > +       [MT8195_CLK_AUD_AFE_DMIC4] = "aud_afe_dmic4",
> > > > > > > > > +       [MT8195_CLK_AUD_AFE_26M_DMIC_TM] =
> > > > > > > > > "aud_afe_26m_dmic_tm",
> > > > > > > > > +       [MT8195_CLK_AUD_UL_TML_HIRES] =
> > > > > > > > > "aud_ul_tml_hires",
> > > > > > > > > +       [MT8195_CLK_AUD_ADC_HIRES] = "aud_adc_hires",
> > > > > > > > > +       [MT8195_CLK_AUD_ADDA6_ADC] = "aud_adda6_adc",
> > > > > > > > > +       [MT8195_CLK_AUD_ADDA6_ADC_HIRES] =
> > > > > > > > > "aud_adda6_adc_hires",
> > > > > > > > > +       [MT8195_CLK_AUD_LINEIN_TUNER] =
> > > > > > > > > "aud_linein_tuner",
> > > > > > > > > +       [MT8195_CLK_AUD_EARC_TUNER] = "aud_earc_tuner",
> > > > > > > > > +       [MT8195_CLK_AUD_I2SIN] = "aud_i2sin",
> > > > > > > > > +       [MT8195_CLK_AUD_TDM_IN] = "aud_tdm_in",
> > > > > > > > > +       [MT8195_CLK_AUD_I2S_OUT] = "aud_i2s_out",
> > > > > > > > > +       [MT8195_CLK_AUD_TDM_OUT] = "aud_tdm_out",
> > > > > > > > > +       [MT8195_CLK_AUD_HDMI_OUT] = "aud_hdmi_out",
> > > > > > > > > +       [MT8195_CLK_AUD_ASRC11] = "aud_asrc11",
> > > > > > > > > +       [MT8195_CLK_AUD_ASRC12] = "aud_asrc12",
> > > > > > > > > +       [MT8195_CLK_AUD_MULTI_IN] = "aud_multi_in",
> > > > > > > > > +       [MT8195_CLK_AUD_INTDIR] = "aud_intdir",
> > > > > > > > > +       [MT8195_CLK_AUD_A1SYS] = "aud_a1sys",
> > > > > > > > > +       [MT8195_CLK_AUD_A2SYS] = "aud_a2sys",
> > > > > > > > > +       [MT8195_CLK_AUD_PCMIF] = "aud_pcmif",
> > > > > > > > > +       [MT8195_CLK_AUD_A3SYS] = "aud_a3sys",
> > > > > > > > > +       [MT8195_CLK_AUD_A4SYS] = "aud_a4sys",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL1] = "aud_memif_ul1",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL2] = "aud_memif_ul2",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL3] = "aud_memif_ul3",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL4] = "aud_memif_ul4",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL5] = "aud_memif_ul5",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL6] = "aud_memif_ul6",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL8] = "aud_memif_ul8",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL9] = "aud_memif_ul9",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_UL10] = "aud_memif_ul10",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_DL2] = "aud_memif_dl2",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_DL3] = "aud_memif_dl3",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_DL6] = "aud_memif_dl6",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_DL7] = "aud_memif_dl7",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_DL8] = "aud_memif_dl8",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_DL10] = "aud_memif_dl10",
> > > > > > > > > +       [MT8195_CLK_AUD_MEMIF_DL11] = "aud_memif_dl11",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC0] = "aud_gasrc0",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC1] = "aud_gasrc1",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC2] = "aud_gasrc2",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC3] = "aud_gasrc3",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC4] = "aud_gasrc4",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC5] = "aud_gasrc5",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC6] = "aud_gasrc6",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC7] = "aud_gasrc7",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC8] = "aud_gasrc8",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC9] = "aud_gasrc9",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC10] = "aud_gasrc10",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC11] = "aud_gasrc11",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC12] = "aud_gasrc12",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC13] = "aud_gasrc13",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC14] = "aud_gasrc14",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC15] = "aud_gasrc15",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC16] = "aud_gasrc16",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC17] = "aud_gasrc17",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC18] = "aud_gasrc18",
> > > > > > > > > +       [MT8195_CLK_AUD_GASRC19] = "aud_gasrc19",
> > > > > > > >
> > > > > > > > The MT8195_CLK_AUD_* clocks are all internal to the audio
> > > > > > > > subsystem:
> > > > > > > > the bits that control these clock gates are in the same
> > > > > > > > address
> > > > > > > > space
> > > > > > > > as the audio parts. Would it be possible to model them as
> > > > > > > > internal
> > > > > > > > ASoC SUPPLY widgets? The external ones could be modeled
> > > > > > > > using
> > > > > > > > ASoC
> > > > > > > > CLK_SUPPLY widgets, and the dependencies could be modeled
> > > > > > > > with
> > > > > > > > ASoC
> > > > > > > > routes. The ASoC core could then handle power sequencing,
> > > > > > > > which
> > > > > > > > the
> > > > > > > > driver currently does manually.
> > > > > > > >
> > > > > > > > IMO this is better than having two drivers handling two
> > > > > > > > aspects
> > > > > > > > of
> > > > > > > > the same piece of hardware, while the two aspects are
> > > > > > > > intertwined.
> > > > > > > >
> > > > > > >
> > > > > > > Yes, it's ok to use the CLK_SUPPLY and SUPPLY to model such
> > > > > > > clocks.
> > > > > > > But those clocks are managed by CCF in the preceding SOCs
> > > > > > > like
> > > > > > > mt2701,
> > > > > > > mt6779 and mt8183. Additionally, in some audio modules,
> > > > > > > clocks
> > > > > > > should
> > > > > >
> > > > > > This being a new driver, we have some more freedom to improve
> > > > > > the
> > > > > > design.
> > > > > >
> > > > > > > be enabled before configuring parameters(hw_params). As far
> > > > > > > as
> > > > > > > I
> > > > > > > know,
> > > > > > > if we use CLK_SUPPLY or SUPPLY to model clocks, the power
> > > > > > > sequence
> > > > > > > is
> > > > > > > controlled by DAPM. It seems to be impossible to fulfill
> > > > > > > all
> > > > > > > use
> > > > > > > cases.
> > > > > > > That's why we just keep the manual control sequence and CCF
> > > > > > > seems
> > > > > > > to be
> > > > > > > the best choice to model such clock gatess.
> > > > > >
> > > > > > I see. So yes, using CCF does give you reference counting,
> > > > > > dependency
> > > > > > tracking and other advantages. And using DAPM supplies means
> > > > > > you
> > > > > > can't
> > > > > > enable the clock gates outside of DAPM without both pieces of
> > > > > > code
> > > > > > fighting for control.
> > > > > >
> > > > > > Can we at least move the audio clock gates into the audio
> > > > > > driver
> > > > > > though?
> > > > > > The arbitrary separation into two devices and drivers is
> > > > > > fishy.
> > > > > > And
> > > > > > with
> > > > > > the move the external references to the audio clock gates can
> > > > > > be
> > > > > > removed.
> > > > > >
> > > > >
> > > > > Because DAPM SUPPLY can't fit our control scenario.
> > > > > Did you suggest us implement the simple logic control(including
> > > > > ref
> > > > > count, clock dependency) for clock gate(MT8195_CLK_AUD_*) in
> > > > > afe
> > > > > driver
> > > > > instead of using CCF?
> > > >
> > > > I meant simply moving the CCF-based clk driver code (clk-mt8516-
> > > > aud.c)
> > > > from `drivers/clk` and incorporating it into the audio driver,
> > > > likely
> > > > in `mt8195-afe-clk.c` or maybe as a separate file. So the audio
> > > > driver
> > > > would be a clock provider, and a clock consumer. It will directly
> > > > use
> > > > the clocks it provides, internally, and you could remove all
> > > > those
> > > > clock references from the device tree.
> > > >
> > > > The goal is to have one hardware representation (device node)
> > > > only,
> > > > so
> > > > that it matches the hardware, which is one single unified block.
> > > >
> > > > After the driver is completed, we can look for opportunities to
> > > > improve
> > > > it, if resources are available.
> > >
> > > Thanks for your detailed information.
> > > I will try to move the CCF-based clk driver code to AFE driver.
> > > If there are no other internal concerns and blocking problems, I
> > > will
> > > include the changes in v3.
> >
> > Great.
> >
> > > > > > And regarding the clock requirements for different modules,
> > > > > > could
> > > > > > we
> > > > > > have
> > > > > > that information put in comments somewhere, so if someone
> > > > > > were to
> > > > > > revisit
> > > > > > it later, they would have the information needed to
> > > > > > understand
> > > > > > and
> > > > > > possibly
> > > > > > improve it? Because right now there's just a bunch of clocks
> > > > > > enabled
> > > > > > and
> > > > > > disabled and nothing to explain why that's needed.
> > > > > >
> > > > >
> > > > > For example,
> > > > > MT8195_CLK_AUD_ADC(clock gate) is one of the clock feeding to
> > > > > ADDA
> > > > > module.
> > > > > Did you want me show the clock gate list feeding to ADDA?
> > > > > On the other hand, I didn't know how to show the information
> > > > > properly
> > > > > in comments. Could you kindly share me an example for
> > > > > reference?
> > > >
> > > >
> > > > For example, in `mt8195_afe_enable_reg_rw_clk()` in mt8195-afe-
> > > > clk.c:
> > > >
> > > >         unsigned int clk_array[] = {
> > > >                 MT8195_CLK_SCP_ADSP_AUDIODSP,
> > > >                 MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL,
> > > >                 MT8195_CLK_TOP_CFG_26M_AUD,
> > > >                 MT8195_CLK_INFRA_AO_AUDIO,
> > > >                 MT8195_CLK_INFRA_AO_AUDIO_26M_B,
> > > >                 MT8195_CLK_TOP_AUD_INTBUS_SEL,
> > > >                 MT8195_CLK_TOP_A1SYS_HP_SEL,
> > > >                 MT8195_CLK_AUD_A1SYS_HP,
> > > >                 MT8195_CLK_AUD_A1SYS,
> > > >                 MT8195_CLK_TOP_AUDIO_H_SEL,
> > > >         };
> > > >
> > > > You could add a comment after each line stating why that clock
> > > > needs
> > > > to
> > > > be enabled. A simple note like "bus access clock" or "internal
> > > > logic
> > > > clock"
> > > > would suffice.
> > > >
> > >
> > > OK, I will add short notes to such clock lists.
> > >
> > > > The above list also has some redundancies that could be
> > > > eliminated.
> > > > MT8195_CLK_TOP_A1SYS_HP_SEL is parent to both
> > > > MT8195_CLK_AUD_A1SYS_HP
> > > > and
> > > > MT8195_CLK_AUD_A1SYS. When clocks are enabled, their parents are
> > > > also
> > > > enabled by CCF, so there's no need to enable them explicitly,
> > > > unless
> > > > that clock also directly feeds the clock consumer.
> > > >
> > >
> > > OK, I will review all clock usages and remove the unnecessary
> > > clocks.
> > >
> > > >
> > > > Another thing I wanted to bring up: is any of the code after
> > > >
> > > >     struct mt8195_afe_tuner_cfg {
> > > >
> > > > used? It looks like it is used to configure the five extra PLLs
> > > > in
> > > > the audio
> > > > subsystem, but the exposed (non-static) functions don't seem to
> > > > be
> > > > called
> > > > anywhere. Are they for modules not yet supported?
> > > >
> > >
> > > Yes, tuners are not supported now.
> > > I will remove the code and add them back when tuners are required
> > > in
> > > the future.
> >
> > Thanks.
> >
> >
> > ChenYu


From maz at kernel.org  Mon Aug  2 03:25:24 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Aug 2021 11:25:24 +0100
Subject: [PATCH 1/9] ARM: dts: bcm2711: fix emmc2bus node name
In-Reply-To: <1627820932-7247-2-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
 <1627820932-7247-2-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1072417634cf20c7dc46e545e9fcd242@kernel.org>

On 2021-08-01 13:28, Stefan Wahren wrote:
> Fix the node name to get the rid of the following DT schema warning:
> 'emmc2bus' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)
> (@[0-9a-f]+)?$'
> 
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> ---
>  arch/arm/boot/dts/bcm2711.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/bcm2711.dtsi 
> b/arch/arm/boot/dts/bcm2711.dtsi
> index b8a4096..afe0ef8 100644
> --- a/arch/arm/boot/dts/bcm2711.dtsi
> +++ b/arch/arm/boot/dts/bcm2711.dtsi
> @@ -405,7 +405,7 @@
>  	 * The firmware will find whether the emmc2bus alias is defined, and 
> if
>  	 * so, it'll edit the dma-ranges property below accordingly.
>  	 */
> -	emmc2bus: emmc2bus {
> +	emmc2bus: emmc2-bus {

There was a recent breakage on rk3399 because of a similar change.

This is a userspace visible change (it affects the sysfs paths),
which will break people's scripts. It would be a lot better to
add an annotation to the DT to acknowledge the issue and keep
the checker quiet.

         M.
-- 
Jazz is not dead. It just smells funny...


From sudeep.holla at arm.com  Mon Aug  2 03:24:25 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 2 Aug 2021 11:24:25 +0100
Subject: [PATCH v6 06/17] firmware: arm_scmi: Introduce monotonically
 increasing tokens
In-Reply-To: <20210728165430.GJ6592@e120937-lin>
References: <20210712141833.6628-1-cristian.marussi@arm.com>
 <20210712141833.6628-7-cristian.marussi@arm.com>
 <20210728141746.chqwhspnwviz67xn@bogus>
 <20210728165430.GJ6592@e120937-lin>
Message-ID: <20210802102425.67bhbvyrgzio7zzg@bogus>

On Wed, Jul 28, 2021 at 05:54:30PM +0100, Cristian Marussi wrote:
> On Wed, Jul 28, 2021 at 03:17:46PM +0100, Sudeep Holla wrote:
> > On Mon, Jul 12, 2021 at 03:18:22PM +0100, Cristian Marussi wrote:

[...]

> > >  
> > > +#define SCMI_PENDING_XFERS_HT_ORDER_SZ	9
> > > +
> > 
> > Is there any particular reason to choose half the token size as hash bucket
> > size ? IOW why not 1/3 or 1/4th of it ? I would appreciate a comment here.
> > I see it is mentioned in the commit log. Also is it not better to associate
> > or keep it close to MSG_TOKEN_ID_MASK and associated macros.
> > 
> 
> I'll move this in the proper place where associated macros are defined.
> 
> The reason for the size choice is tricky (and not sure about its value
> still...so I have not commented yet :D); the ideal size of this hashtable would
> be desc->max_msg so equal to the maximum number of inflight messages allowed on
> the system in order to minimize (probably to zero) collisions on the hashtable:
> unfortunately max_msg is only finally available at runtime time and the
> kernel hashtable is statically sized by design....
> 
> I tried to play some tricks to define dynamically the size but everything falls
> apart since a lot of stuff in linux/hashtable.h is based on ARRAY_SIZE() and
> friends (to speedup all I suppose). Another non-fit (in my opinion)
> alternative would be using relativistic hashtable (linux/rhashtable.h) but
> those are definitely overkill in our case since they are hashtables that
> can be resized completely at runtime while populated O_o. (with even
> more overhead)
> 
> At the end the size that fits all possible in-flight messages minimizing
> collisions in any possible case that I can set at compile time would be 10,
> which means really 2^10 1024 HT entries (equal to MAX_MSG_TOKEN) each of which
> is a struct list_head (*prev,*next 16bytes) i.e. 16KB HT: Peter pointed out
> that it would be a lot of wasted space on normal systems in which max in-flight
> messages are far-less than 1024 AND would not even fit in one 4Kb page, so I
> reduced it to 512 entries but the best would be 256 (8) if we want to
> fit in one regular 4kb page. The drawback will be a bit of HT collisions on
> system with more than 256 possible and effective in-flight messages.
>

I agree, 256 should be fine for now. Just add a note that it is chosen to
fit a page and can be updated if required.


> > >  /**
> > >   * struct scmi_xfers_info - Structure to manage transfer information
> > >   *
> > > - * @xfer_block: Preallocated Message array
> > >   * @xfer_alloc_table: Bitmap table for allocated messages.
> > >   *	Index of this bitmap table is also used for message
> > >   *	sequence identifier.
> > >   * @xfer_lock: Protection for message allocation
> > > + * @last_token: A counter to use as base to generate for monotonically
> > > + *		increasing tokens.
> > > + * @free_xfers: A free list for available to use xfers. It is initialized with
> > > + *		a number of xfers equal to the maximum allowed in-flight
> > > + *		messages.
> > > + * @pending_xfers: An hashtable, indexed by msg_hdr.seq, used to keep all the
> > > + *		   currently in-flight messages.
> > >   */
> > >  struct scmi_xfers_info {
> > > -	struct scmi_xfer *xfer_block;
> > >  	unsigned long *xfer_alloc_table;
> > >  	spinlock_t xfer_lock;
> > > +	atomic_t last_token;
> > 
> > Can we merge this and transfer_last_id ? Let this be free running like
> > transfer_last_id and just use [0-9] from this ? I don't see any point
> > having 2 different monotonically increasing tokens/id.
> > 
> 
> Mmm I was tempted about that, but the reason I did not was that in some
> rare limit condition as you can see in the ASCII art (:O) I can find a hole in
> the next available token ids so I have to skip and update last_token itself,
> not sure if this could cause confusion seeing transfer_ids with holes during
> tracing if I unify them.
>

That should be fine as it won't be used at all.

-- 
Regards,
Sudeep


From Dave.Martin at arm.com  Mon Aug  2 03:25:29 2021
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 2 Aug 2021 11:25:29 +0100
Subject: [PATCH v3 3/4] kselftest/arm64: Add tests for SVE vector
 configuration
In-Reply-To: <20210729173411.GT4670@sirena.org.uk>
References: <20210729151518.46388-1-broonie@kernel.org>
 <20210729151518.46388-4-broonie@kernel.org>
 <20210729160642.GP1724@arm.com>
 <20210729173411.GT4670@sirena.org.uk>
Message-ID: <20210802102517.GA25258@arm.com>

On Thu, Jul 29, 2021 at 06:34:11PM +0100, Mark Brown wrote:
> On Thu, Jul 29, 2021 at 05:06:42PM +0100, Dave Martin wrote:
> > On Thu, Jul 29, 2021 at 04:15:17PM +0100, Mark Brown wrote:
> 
> > > +	child = fork();
> > > +	if (child == -1) {
> > > +		ksft_print_msg("fork() failed: %d (%s)\n",
> > > +			       errno, strerror(errno));
> > > +		close(pipefd[0]);
> > > +		close(pipefd[1]);
> > > +		return -1;
> 
> > Since nothing reopens pipefd[0] or pipefd[1], you could also follow the
> > "goto out" convention and just (re)close both fds at the end, rather
> > than having to repeat the close() multiple times.  But it works as-is.
> 
> I find that when fork() gets involved that starts to get confusing since
> you have multiple contexts/control flows around and working out which
> cleanup path goes where is more of the issue.

Ack, the other option would be to factor out the child stuff into a
separate function, but this doesn't quite seem worth it here.

Although the code seemed a bit repetitive, it is at least clear in its
current form, so I don't have a strong view.

> 
> > > +		if (!WIFEXITED(ret)) {
> > > +			ksft_print_msg("child exited abnormally\n");
> > > +			close(pipefd[0]);
> > > +			return -1;
> > > +		}
> 
> > The WEXITSTATUS() check could go outside the loop.
> 
> OTOH I find that logically it's part of working out what happened with
> the child which is what the loop body is doing.  Anyway I changed to the
> do/while you suggested.

That's a reasonable position, but thinking about it a bit more, there's
not really any loop at all here.

There definitely is an unwaited-for child and we don't pass WHONANG to
wait(), so it will either return the child pid, or fail.

Without WUNTRACED or similar, the child must terminate to wake up the
wait().

So is this just a matter of

	pid = wait(&ret);
	if (pid == -1) {
		/* barf */
	}
	assert(pid == child);

	if (!WIFEXITED(ret)) {
		/* barf */
	}

	if (WEXITSTATUS(ret) != 0) {
		/* barf */
	}

	/* parse child's stdout etc. */

> Please delete unneeded context from mails when replying.  Doing this
> makes it much easier to find your reply in the message, helping ensure
> it won't be missed by people scrolling through the irrelevant quoted
> material.

Hmmm, usually I at least try to do that, but I did seem to leave rather
a lot of trailing junk that time.

(Working out which context is relevant is not always an exact science,
but in this case, it looks like I just forgot.)

Cheers
---Dave 


From cristian.marussi at arm.com  Mon Aug  2 03:27:27 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 2 Aug 2021 11:27:27 +0100
Subject: [PATCH v6 07/17] firmware: arm_scmi: Handle concurrent and
 out-of-order messages
In-Reply-To: <20210802101032.ozlidylogmdt2zqu@bogus>
References: <20210712141833.6628-1-cristian.marussi@arm.com>
 <20210712141833.6628-8-cristian.marussi@arm.com>
 <20210802101032.ozlidylogmdt2zqu@bogus>
Message-ID: <20210802102727.GP6592@e120937-lin>

On Mon, Aug 02, 2021 at 11:10:32AM +0100, Sudeep Holla wrote:
> On Mon, Jul 12, 2021 at 03:18:23PM +0100, Cristian Marussi wrote:
> > Even though in case of asynchronous commands an SCMI platform server is
> 
> Drop the term "server"
> 

Sure.

> > constrained to emit the delayed response message only after the related
> > message response has been sent, the configured underlying transport could
> > still deliver such messages together or in inverted order, causing races
> > due to the concurrent or out-of-order access to the underlying xfer.
> > 
> > Introduce a mechanism to grant exclusive access to an xfer in order to
> > properly serialize concurrent accesses to the same xfer originating from
> > multiple correlated messages.
> > 
> > Add additional state information to xfer descriptors so as to be able to
> > identify out-of-order message deliveries and act accordingly:
> > 
> >  - when a delayed response is expected but delivered before the related
> >    response, the synchronous response is considered as successfully
> >    received and the delayed response processing is carried on as usual.
> > 
> >  - when/if the missing synchronous response is subsequently received, it
> >    is discarded as not congruent with the current state of the xfer, or
> >    simply, because the xfer has been already released and so, now, the
> >    monotonically increasing sequence number carried by the late response
> >    is stale.
> > 
> > Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> > ---
> > v5 --> v6
> > - added spinlock comment
> > ---
> >  drivers/firmware/arm_scmi/common.h |  18 ++-
> >  drivers/firmware/arm_scmi/driver.c | 229 ++++++++++++++++++++++++-----
> >  2 files changed, 212 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
> > index 2233d0a188fc..9efebe1406d2 100644
> > --- a/drivers/firmware/arm_scmi/common.h
> > +++ b/drivers/firmware/arm_scmi/common.h
> > @@ -19,6 +19,7 @@
> >  #include <linux/module.h>
> >  #include <linux/refcount.h>
> >  #include <linux/scmi_protocol.h>
> > +#include <linux/spinlock.h>
> >  #include <linux/types.h>
> >  
> >  #include <asm/unaligned.h>
> > @@ -145,6 +146,13 @@ struct scmi_msg {
> >   * @pending: True for xfers added to @pending_xfers hashtable
> >   * @node: An hlist_node reference used to store this xfer, alternatively, on
> >   *	  the free list @free_xfers or in the @pending_xfers hashtable
> > + * @busy: An atomic flag to ensure exclusive write access to this xfer
> > + * @state: The current state of this transfer, with states transitions deemed
> > + *	   valid being:
> > + *	    - SCMI_XFER_SENT_OK -> SCMI_XFER_RESP_OK [ -> SCMI_XFER_DRESP_OK ]
> > + *	    - SCMI_XFER_SENT_OK -> SCMI_XFER_DRESP_OK
> > + *	      (Missing synchronous response is assumed OK and ignored)
> > + * @lock: A spinlock to protect state and busy fields.
> >   */
> >  struct scmi_xfer {
> >  	int transfer_id;
> > @@ -156,6 +164,15 @@ struct scmi_xfer {
> >  	refcount_t users;
> >  	bool pending;
> >  	struct hlist_node node;
> > +#define SCMI_XFER_FREE		0
> > +#define SCMI_XFER_BUSY		1
> > +	atomic_t busy;
> > +#define SCMI_XFER_SENT_OK	0
> > +#define SCMI_XFER_RESP_OK	1
> > +#define SCMI_XFER_DRESP_OK	2
> > +	int state;
> > +	/* A lock to protect state and busy fields */
> > +	spinlock_t lock;
> >  };
> >  
> >  /*
> > @@ -392,5 +409,4 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
> >  void scmi_notification_instance_data_set(const struct scmi_handle *handle,
> >  					 void *priv);
> >  void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
> > -
> >  #endif /* _SCMI_COMMON_H */
> > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> > index 245ede223302..5ef33d692670 100644
> > --- a/drivers/firmware/arm_scmi/driver.c
> > +++ b/drivers/firmware/arm_scmi/driver.c
> > @@ -369,6 +369,7 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
> >  
> >  	if (!IS_ERR(xfer)) {
> >  		refcount_set(&xfer->users, 1);
> > +		atomic_set(&xfer->busy, SCMI_XFER_FREE);
> >  		xfer->transfer_id = atomic_inc_return(&transfer_last_id);
> >  	}
> >  	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
> > @@ -430,6 +431,168 @@ scmi_xfer_lookup_unlocked(struct scmi_xfers_info *minfo, u16 xfer_id)
> >  	return xfer ?: ERR_PTR(-EINVAL);
> >  }
> >  
> > +/**
> > + * scmi_msg_response_validate  - Validate message type against state of related
> > + * xfer
> > + *
> > + * @cinfo: A reference to the channel descriptor.
> > + * @msg_type: Message type to check
> > + * @xfer: A reference to the xfer to validate against @msg_type
> > + *
> > + * This function checks if @msg_type is congruent with the current state of
> > + * a pending @xfer; if an asynchronous delayed response is received before the
> > + * related synchronous response (Out-of-Order Delayed Response) the missing
> > + * synchronous response is assumed to be OK and completed, carrying on with the
> > + * Delayed Response: this is done to address the case in which the underlying
> > + * SCMI transport can deliver such out-of-order responses.
> > + *
> > + * Context: Assumes to be called with xfer->lock already acquired.
> > + *
> > + * Return: 0 on Success, error otherwise
> > + */
> > +static inline int scmi_msg_response_validate(struct scmi_chan_info *cinfo,
> > +					     u8 msg_type,
> > +					     struct scmi_xfer *xfer)
> > +{
> > +	/*
> > +	 * Even if a response was indeed expected on this slot at this point,
> > +	 * a buggy platform could wrongly reply feeding us an unexpected
> > +	 * delayed response we're not prepared to handle: bail-out safely
> > +	 * blaming firmware.
> > +	 */
> > +	if (msg_type == MSG_TYPE_DELAYED_RESP && !xfer->async_done) {
> > +		dev_err(cinfo->dev,
> > +			"Delayed Response for %d not expected! Buggy F/W ?\n",
> > +			xfer->hdr.seq);
> > +		return -EINVAL;
> > +	}
> > +
> > +	switch (xfer->state) {
> > +	case SCMI_XFER_SENT_OK:
> > +		if (msg_type == MSG_TYPE_DELAYED_RESP) {
> > +			/*
> > +			 * Delayed Response expected but delivered earlier.
> > +			 * Assume message RESPONSE was OK and skip state.
> > +			 */
> > +			xfer->hdr.status = SCMI_SUCCESS;
> > +			xfer->state = SCMI_XFER_RESP_OK;
> > +			complete(&xfer->done);
> > +			dev_warn(cinfo->dev,
> > +				 "Received valid OoO Delayed Response for %d\n",
> > +				 xfer->hdr.seq);
> > +		}
> > +		break;
> > +	case SCMI_XFER_RESP_OK:
> > +		if (msg_type != MSG_TYPE_DELAYED_RESP)
> > +			return -EINVAL;
> > +		break;
> > +	case SCMI_XFER_DRESP_OK:
> > +		/* No further message expected once in SCMI_XFER_DRESP_OK */
> 
> Do we really need this case ? If so, how can this happen.
> 

Given that I am checking for state validity I thought to account also
for the case of possible (even though rare) duplicated delayed response.

> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static bool scmi_xfer_is_free(struct scmi_xfer *xfer)
> > +{
> > +	int ret;
> > +
> > +	ret = atomic_cmpxchg(&xfer->busy, SCMI_XFER_FREE, SCMI_XFER_BUSY);
> > +
> > +	return ret == SCMI_XFER_FREE;
> > +}
> > +
> > +/**
> > + * scmi_xfer_command_acquire  -  Helper to lookup and acquire a command xfer
> > + *
> > + * @cinfo: A reference to the channel descriptor.
> > + * @msg_hdr: A message header to use as lookup key
> > + *
> > + * When a valid xfer is found for the sequence number embedded in the provided
> > + * msg_hdr, reference counting is properly updated and exclusive access to this
> > + * xfer is granted till released with @scmi_xfer_command_release.
> > + *
> > + * Return: A valid @xfer on Success or error otherwise.
> > + */
> > +static inline struct scmi_xfer *
> > +scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
> > +{
> > +	int ret;
> > +	unsigned long flags;
> > +	struct scmi_xfer *xfer;
> > +	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> > +	struct scmi_xfers_info *minfo = &info->tx_minfo;
> > +	u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
> > +	u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
> > +
> > +	/* Are we even expecting this? */
> > +	spin_lock_irqsave(&minfo->xfer_lock, flags);
> > +	xfer = scmi_xfer_lookup_unlocked(minfo, xfer_id);
> > +	if (IS_ERR(xfer)) {
> > +		dev_err(cinfo->dev,
> > +			"Message for %d type %d is not expected!\n",
> > +			xfer_id, msg_type);
> > +		spin_unlock_irqrestore(&minfo->xfer_lock, flags);
> > +		return xfer;
> > +	}
> > +	refcount_inc(&xfer->users);
> > +	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
> > +
> > +	spin_lock_irqsave(&xfer->lock, flags);
> > +	ret = scmi_msg_response_validate(cinfo, msg_type, xfer);
> > +	/*
> > +	 * If a pending xfer was found which was also in a congruent state with
> > +	 * the received message, acquire exclusive access to it setting the busy
> > +	 * flag.
> > +	 * Spins only on the rare limit condition of concurrent reception of
> > +	 * RESP and DRESP for the same xfer.
> > +	 */
> > +	if (!ret) {
> > +		spin_until_cond(scmi_xfer_is_free(xfer));
> 
> I agree with the discussion between you and Peter around this, so I assume
> it will be renamed or handled accordingly.
> 

Ok I'll rename it.

> > +		xfer->hdr.type = msg_type;
> > +	}
> > +	spin_unlock_irqrestore(&xfer->lock, flags);
> > +
> > +	if (ret) {
> > +		dev_err(cinfo->dev,
> > +			"Invalid message type:%d for %d - HDR:0x%X  state:%d\n",
> > +			msg_type, xfer_id, msg_hdr, xfer->state);
> > +		/* On error the refcount incremented above has to be dropped */
> > +		__scmi_xfer_put(minfo, xfer);
> > +		xfer = ERR_PTR(-EINVAL);
> > +	}
> > +
> > +	return xfer;
> > +}
> > +
> > +static inline void scmi_xfer_command_release(struct scmi_info *info,
> > +					     struct scmi_xfer *xfer)
> > +{
> > +	atomic_set(&xfer->busy, SCMI_XFER_FREE);
> > +	__scmi_xfer_put(&info->tx_minfo, xfer);
> > +}
> > +
> > +/**
> > + * scmi_xfer_state_update  - Update xfer state
> > + *
> > + * @xfer: A reference to the xfer to update
> > + *
> > + * Context: Assumes to be called on an xfer exclusively acquired using the
> > + *	    busy flag.
> > + */
> > +static inline void scmi_xfer_state_update(struct scmi_xfer *xfer)
> > +{
> > +	switch (xfer->hdr.type) {
> > +	case MSG_TYPE_COMMAND:
> > +		xfer->state = SCMI_XFER_RESP_OK;
> > +		break;
> > +	case MSG_TYPE_DELAYED_RESP:
> > +		xfer->state = SCMI_XFER_DRESP_OK;
> > +		break;
> > +	}
> > +}
> 
> Can't this be if () ..  else if(), switch sounds unnecessary for 2 conditions.
> 

Yes indeed I'll rework in V7.

> Other than the things already discussed with you and Peter, don't have much to
> add ATM. I may look at this with fresh eyes once again in the next version.
> 

Thanks for the review.

Cristian



From tabba at google.com  Mon Aug  2 03:30:25 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 12:30:25 +0200
Subject: [PATCH v3 12/21] KVM: arm64: Add helpers to tag shared pages in
 SW bits
In-Reply-To: <20210729132818.4091769-13-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-13-qperret@google.com>
Message-ID: <CA+EHjTzT+aMGkc5cEwGT+05z6aGmbLi0DBetBGXLh3GFY2GXgQ@mail.gmail.com>

Hi Quentin,


On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> We will soon start annotating shared pages in page-tables in nVHE
> protected mode. Define all the states in which a page can be (owned,
> shared and owned, shared and borrowed), and provide helpers allowing to
> convert this into SW bits annotations using the matching prot
> attributes.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 26 +++++++++++++++++++
>  1 file changed, 26 insertions(+)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 9c227d87c36d..ae355bfd8c01 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -12,6 +12,32 @@
>  #include <asm/virt.h>
>  #include <nvhe/spinlock.h>
>
> +/*
> + * SW bits 0-1 are reserved to track the memory ownership state of each page:
> + *   00: The page is owned solely by the page-table owner.

nit: solely -> exclusively, because "exclusive" is the more common
term in context of shared resources

> + *   01: The page is owned by the page-table owner, but is shared
> + *       with another entity.
> + *   10: The page is shared with, but not owned by the page-table owner.
> + *   11: Reserved for future use (lending).
> + */
> +enum pkvm_page_state {
> +       PKVM_PAGE_OWNED                 = 0ULL,
> +       PKVM_PAGE_SHARED_OWNED          = KVM_PGTABLE_PROT_SW0,
> +       PKVM_PAGE_SHARED_BORROWED       = KVM_PGTABLE_PROT_SW1,
> +};
> +
> +#define PKVM_PAGE_STATE_PROT_MASK      (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
> +static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
> +                                                enum pkvm_page_state state)
> +{
> +       return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
> +}
> +
> +static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
> +{
> +       return prot & PKVM_PAGE_STATE_PROT_MASK;
> +}
> +

I think that this encoding is pretty neat and easy to follow.

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>  struct host_kvm {
>         struct kvm_arch arch;
>         struct kvm_pgtable pgt;
> --
> 2.32.0.432.gabb21c7263-goog
>


From will at kernel.org  Mon Aug  2 03:34:01 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Aug 2021 11:34:01 +0100
Subject: [PATCH v2 1/1] drivers: perf: Add LLC-TAD perf counter support
In-Reply-To: <20210614135849.6076-1-bbudiredla@marvell.com>
References: <20210614135849.6076-1-bbudiredla@marvell.com>
Message-ID: <20210802103401.GA27583@willie-the-truck>

On Mon, Jun 14, 2021 at 07:28:49PM +0530, Bhaskara Budiredla wrote:
> This driver adds support for Last-level cache tag-and-data unit
> (LLC-TAD) PMU that is featured in some of the Marvell's CN10K
> infrastructure silicons.
> 
> The LLC is divided into 2N slices distributed across N Mesh tiles
> in a single-socket configuration. The driver always configures the
> same counter for all of the TADs. The user would end up effectively
> reserving one of eight counters in every TAD to look across all TADs.
> The occurrences of events are aggregated and presented to the user
> at the end of an application run. The driver does not provide a way
> for the user to partition TADs so that different TADs are used for
> different applications.
> 
> The event counters are zeroed to start event counting to avoid any
> rollover issues. TAD perf counters are 64-bit, so it's not currently
> possible to overflow event counters at current mesh and core
> frequencies.

I couldn't spot where you disable sampling events, which rely heavily on
detecting overflow. Probably need PERF_PMU_CAP_NO_INTERRUPT.

> To measure tad pmu events use perf tool stat command. For instance:
> 
> perf stat -e tad_dat_msh_in_dss,tad_req_msh_out_any <application>
> perf stat -e tad_alloc_any,tad_hit_any,tad_tag_rd <application>
> 
> Signed-off-by: Bhaskara Budiredla <bbudiredla at marvell.com>
> ---
>  .../bindings/perf/marvell-cn10k-tad-pmu.txt   |  20 +

Adding the DT list for this ^^ as it looks a bit odd to me (also shouldn't
it be in YAML?)

>  drivers/perf/Kconfig                          |   7 +
>  drivers/perf/Makefile                         |   1 +
>  drivers/perf/marvell_cn10k_tad_pmu.c          | 428 ++++++++++++++++++

-ENODOCUMENTATION

>  4 files changed, 456 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-tad-pmu.txt
>  create mode 100644 drivers/perf/marvell_cn10k_tad_pmu.c
> 
> diff --git a/Documentation/devicetree/bindings/perf/marvell-cn10k-tad-pmu.txt b/Documentation/devicetree/bindings/perf/marvell-cn10k-tad-pmu.txt
> new file mode 100644
> index 000000000000..8b1f753303e2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/perf/marvell-cn10k-tad-pmu.txt
> @@ -0,0 +1,20 @@
> +* Marvell CN10K LLC-TAD performace monitor unit
> +
> +Required properties:
> +- compatible: must be:
> +	"marvell,cn10k-tad-pmu"
> +- tad-cnt: number of tad pmu regions
> +- tad-page-size: size of entire tad block
> +- tad-pmu-page-size: size of one tad pmu region
> +- reg: physical address and size
> +
> +Example:
> +
> +/* Actual values updated by firmware at boot time */
> +tad_pmu {
> +	compatible = "marvell,cn10k-tad-pmu";
> +	tad-cnt = <1>;
> +	tad-page-size = <0x1000>;
> +	tad-pmu-page-size = <0x1000>;
> +	reg = <0x87e2 0x80000000 0x0 0x1000>;
> +};
> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
> index 77522e5efe11..73dca11f8080 100644
> --- a/drivers/perf/Kconfig
> +++ b/drivers/perf/Kconfig
> @@ -137,6 +137,13 @@ config ARM_DMC620_PMU
>  	  Support for PMU events monitoring on the ARM DMC-620 memory
>  	  controller.
>  
> +config MARVELL_CN10K_TAD_PMU
> +	tristate "Marvell CN10K LLC-TAD PMU"
> +	depends on ARM64
> +	help
> +	  Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
> +	  performance monitors on CN10K family silicons.
> +
>  source "drivers/perf/hisilicon/Kconfig"
>  
>  endmenu
> diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
> index 5260b116c7da..2db5418d5b0a 100644
> --- a/drivers/perf/Makefile
> +++ b/drivers/perf/Makefile
> @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
>  obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
>  obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
>  obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
> +obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
> diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
> new file mode 100644
> index 000000000000..99878de481f0
> --- /dev/null
> +++ b/drivers/perf/marvell_cn10k_tad_pmu.c
> @@ -0,0 +1,428 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Marvell CN10K LLC-TAD perf driver
> + *
> + * Copyright (C) 2021 Marvell.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#define pr_fmt(fmt) "tad_pmu: " fmt
> +
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/cpuhotplug.h>
> +#include <linux/perf_event.h>
> +#include <linux/platform_device.h>
> +#include <linux/arm-smccc.h>
> +
> +#define TAD_PFC_OFFSET		0x0800
> +#define TAD_PFC(counter)	(TAD_PFC_OFFSET | (counter << 3))
> +#define TAD_PRF_OFFSET		0x0900
> +#define TAD_PRF(counter)	(TAD_PRF_OFFSET | (counter << 3))
> +#define TAD_PRF_CNTSEL_MASK	0xFF
> +#define TAD_MAX_COUNTERS	8
> +
> +#define to_tad_pmu(p) (container_of(p, struct tad_pmu, pmu))
> +
> +struct tad_region {
> +	void __iomem	*base;
> +};
> +
> +struct tad_pmu {
> +	struct pmu pmu;
> +	struct tad_region *regions;
> +	u32 region_cnt;
> +	unsigned int cpu;
> +	struct hlist_node node;
> +	struct perf_event *events[TAD_MAX_COUNTERS];
> +	DECLARE_BITMAP(counters_map, TAD_MAX_COUNTERS);
> +};
> +
> +static int tad_pmu_cpuhp_state;
> +
> +static void tad_pmu_event_counter_read(struct perf_event *event)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	u32 counter_idx = hwc->idx;
> +	u64 delta, prev, new;
> +	int i;
> +
> +	do {
> +		prev = local64_read(&hwc->prev_count);
> +		for (i = 0, new = 0; i < tad_pmu->region_cnt; i++)
> +			new += readq(tad_pmu->regions[i].base +
> +				     TAD_PFC(counter_idx));
> +	} while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev);
> +
> +	delta = (new - prev) & GENMASK_ULL(63, 0);
> +	local64_add(delta, &event->count);
> +}
> +
> +static void tad_pmu_event_counter_stop(struct perf_event *event, int flags)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	u32 counter_idx = hwc->idx;
> +	int i;
> +
> +	/* TAD()_PFC() stop counting on the write
> +	 * which sets TAD()_PRF()[CNTSEL] == 0
> +	 */
> +	for (i = 0; i < tad_pmu->region_cnt; i++)
> +		writeq(0, tad_pmu->regions[i].base + TAD_PRF(counter_idx));

writeq_relaxed() should be sufficient for this (and the others in this
driver), no?

> +static ssize_t tad_pmu_event_show(struct device *dev,
> +				struct device_attribute *attr, char *page)
> +{
> +	struct perf_pmu_events_attr *pmu_attr;
> +
> +	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
> +	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
> +}
> +
> +#define TAD_PMU_EVENT_ATTR(_name, _id)					\
> +	(&((struct perf_pmu_events_attr[]) {				\
> +		{ .attr = __ATTR(_name, 0444, tad_pmu_event_show, NULL),\
> +		  .id = _id, }						\
> +	})[0].attr.attr)

Use PMU_EVENT_ATTR_ID instead?

> +static int tad_pmu_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct tad_region *regions;
> +	struct tad_pmu *tad_pmu;
> +	struct resource *res;
> +	u32 tad_pmu_page_size;
> +	u32 tad_page_size;
> +	u32 tad_cnt;
> +	int i, ret;
> +	char *name;
> +
> +	tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu), GFP_KERNEL);
> +	if (!tad_pmu)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, tad_pmu);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "Mem resource not found\n");
> +		return -ENODEV;
> +	}
> +
> +	ret = of_property_read_u32(node, "tad-page-size", &tad_page_size);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't find tad-page-size property\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(node, "tad-pmu-page-size",
> +				   &tad_pmu_page_size);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't find tad-pmu-page-size property\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(node, "tad-cnt", &tad_cnt);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't find tad-cnt property\n");
> +		return ret;
> +	}
> +
> +	regions = kcalloc(tad_cnt, sizeof(*regions), GFP_KERNEL);

devm_kcalloc() instead?

Will


From schnelle at linux.ibm.com  Mon Aug  2 03:34:13 2021
From: schnelle at linux.ibm.com (Niklas Schnelle)
Date: Mon, 02 Aug 2021 12:34:13 +0200
Subject: [PATCH v2 13/21] s390/pci: don't set failed sg dma_address to
 DMA_MAPPING_ERROR
In-Reply-To: <20210723175008.22410-14-logang@deltatee.com>
References: <20210723175008.22410-1-logang@deltatee.com>
 <20210723175008.22410-14-logang@deltatee.com>
Message-ID: <a5a46d84866f69df8c9737ecd8b066b61f24960a.camel@linux.ibm.com>

On Fri, 2021-07-23 at 11:50 -0600, Logan Gunthorpe wrote:
> Setting the ->dma_address to DMA_MAPPING_ERROR is not part of
> the ->map_sg calling convention, so remove it.
> 
> Link: https://lore.kernel.org/linux-mips/20210716063241.GC13345 at lst.de/
> Suggested-by: Christoph Hellwig <hch at lst.de>
> Signed-off-by: Logan Gunthorpe <logang at deltatee.com>
> Cc: Niklas Schnelle <schnelle at linux.ibm.com>
> Cc: Gerald Schaefer <gerald.schaefer at linux.ibm.com>
> Cc: Heiko Carstens <hca at linux.ibm.com>
> Cc: Vasily Gorbik <gor at linux.ibm.com>
> Cc: Christian Borntraeger <borntraeger at de.ibm.com>
> ---
>  arch/s390/pci/pci_dma.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
> index c78b02012764..be48e5b5bfcf 100644
> --- a/arch/s390/pci/pci_dma.c
> +++ b/arch/s390/pci/pci_dma.c
> @@ -492,7 +492,6 @@ static int s390_dma_map_sg(struct device *dev, struct scatterlist *sg,
>  	for (i = 1; i < nr_elements; i++) {
>  		s = sg_next(s);
>  
> -		s->dma_address = DMA_MAPPING_ERROR;
>  		s->dma_length = 0;
>  
>  		if (s->offset || (size & ~PAGE_MASK) ||

Acked-by: Niklas Schnelle <schnelle at linux.ibm.com>

Thanks!



From o.rempel at pengutronix.de  Mon Aug  2 03:36:02 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Mon,  2 Aug 2021 12:36:02 +0200
Subject: [PATCH v3 2/3] dt-bindings: arm: fsl: add SKOV imx6q and imx6dl based
 boards
In-Reply-To: <20210802103603.28607-1-o.rempel@pengutronix.de>
References: <20210802103603.28607-1-o.rempel@pengutronix.de>
Message-ID: <20210802103603.28607-3-o.rempel@pengutronix.de>

Add SKOV imx6q/dl LT2, LT6 and mi1010ait-1cp1 boards.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index e2097011c4b0..600dfe984ab3 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -221,6 +221,9 @@ properties:
               - prt,prti6q                # Protonic PRTI6Q board
               - prt,prtwd2                # Protonic WD2 board
               - rex,imx6q-rex-pro         # Rex Pro i.MX6 Quad Board
+              - skov,imx6q-skov-revc-lt2  # SKOV IMX6 CPU QuadCore lt2
+              - skov,imx6q-skov-revc-lt6  # SKOV IMX6 CPU QuadCore lt6
+              - skov,imx6q-skov-reve-mi1010ait-1cp1 # SKOV IMX6 CPU QuadCore mi1010ait-1cp1
               - solidrun,cubox-i/q        # SolidRun Cubox-i Dual/Quad
               - solidrun,hummingboard/q
               - solidrun,hummingboard2/q
@@ -378,6 +381,8 @@ properties:
               - prt,prtvt7                # Protonic VT7 board
               - rex,imx6dl-rex-basic      # Rex Basic i.MX6 Dual Lite Board
               - riot,imx6s-riotboard      # RIoTboard i.MX6S
+              - skov,imx6dl-skov-revc-lt2 # SKOV IMX6 CPU SoloCore lt2
+              - skov,imx6dl-skov-revc-lt6 # SKOV IMX6 CPU SoloCore lt6
               - solidrun,cubox-i/dl            # SolidRun Cubox-i Solo/DualLite
               - solidrun,hummingboard/dl
               - solidrun,hummingboard2/dl      # SolidRun HummingBoard2 Solo/DualLite
-- 
2.30.2



From o.rempel at pengutronix.de  Mon Aug  2 03:36:03 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Mon,  2 Aug 2021 12:36:03 +0200
Subject: [PATCH v3 3/3] ARM: dts: add SKOV imx6q and imx6dl based boards
In-Reply-To: <20210802103603.28607-1-o.rempel@pengutronix.de>
References: <20210802103603.28607-1-o.rempel@pengutronix.de>
Message-ID: <20210802103603.28607-4-o.rempel@pengutronix.de>

From: Sam Ravnborg <sam at ravnborg.org>

Add SKOV imx6q/dl LT2, LT6 and mi1010ait-1cp1 boards.

Signed-off-by: Sam Ravnborg <sam at ravnborg.org>
Signed-off-by: S?ren Andersen <san at skov.dk>
Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
Signed-off-by: Ulrich ?lmann <u.oelmann at pengutronix.de>
Signed-off-by: Michael Grzeschik <m.grzeschik at pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 arch/arm/boot/dts/Makefile                    |   5 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts    |  13 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts    | 106 ++++
 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts     |  36 ++
 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts     | 128 +++++
 .../dts/imx6q-skov-reve-mi1010ait-1cp1.dts    | 127 +++++
 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi  |  54 ++
 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi       | 476 ++++++++++++++++++
 8 files changed, 945 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 828fefc9c436..ecff0743d35f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -475,6 +475,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6dl-sabrelite.dtb \
 	imx6dl-sabresd.dtb \
 	imx6dl-savageboard.dtb \
+	imx6dl-skov-revc-lt2.dtb \
+	imx6dl-skov-revc-lt6.dtb \
 	imx6dl-solidsense.dtb \
 	imx6dl-ts4900.dtb \
 	imx6dl-ts7970.dtb \
@@ -576,6 +578,9 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6q-sabresd.dtb \
 	imx6q-savageboard.dtb \
 	imx6q-sbc6x.dtb \
+	imx6q-skov-revc-lt2.dtb \
+	imx6q-skov-revc-lt6.dtb \
+	imx6q-skov-reve-mi1010ait-1cp1.dtb \
 	imx6q-solidsense.dtb \
 	imx6q-tbs2910.dtb \
 	imx6q-ts4900.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts b/arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
new file mode 100644
index 000000000000..667b8faa1807
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+#include "imx6qdl-skov-cpu-revc.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU SoloCore";
+	compatible = "skov,imx6dl-skov-revc-lt2", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts b/arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
new file mode 100644
index 000000000000..5dcc433fe2af
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+#include "imx6qdl-skov-cpu-revc.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU SoloCore";
+	compatible = "skov,imx6dl-skov-revc-lt6", "fsl,imx6dl";
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_backlight>;
+		enable-gpios = <&gpio6 23 GPIO_ACTIVE_LOW>;
+		pwms = <&pwm2 0 20000 0>;
+		brightness-levels = <0 255>;
+		num-interpolated-steps = <17>;
+		default-brightness-level = <8>;
+		power-supply = <&reg_24v0>;
+	};
+
+	display {
+		compatible = "fsl,imx-parallel-display";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+
+			display0_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			display0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+
+	panel {
+		compatible = "logictechno,lttd800480070-l6wh-rt";
+		backlight = <&backlight>;
+		power-supply = <&reg_3v3>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display0_out>;
+			};
+		};
+	};
+};
+
+&ipu1_di0_disp0 {
+	remote-endpoint = <&display0_in>;
+};
+
+&iomuxc {
+	pinctrl_backlight: backlightgrp {
+		fsl,pins = <
+			MX6QDL_PAD_RGMII_TD3__GPIO6_IO23		0x58
+		>;
+	};
+
+	pinctrl_ipu1: ipu1grp {
+		fsl,pins = <
+			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK	0x10
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x10
+			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02		0x10
+			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03		0x10
+			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00	0x10
+			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01	0x10
+			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02	0x10
+			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03	0x10
+			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04	0x10
+			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05	0x10
+			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06	0x10
+			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07	0x10
+			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08	0x10
+			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09	0x10
+			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10	0x10
+			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11	0x10
+			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12	0x10
+			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13	0x10
+			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14	0x10
+			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15	0x10
+			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16	0x10
+			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17	0x10
+			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18	0x10
+			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19	0x10
+			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20	0x10
+			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21	0x10
+			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22	0x10
+			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23	0x10
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-skov-revc-lt2.dts b/arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
new file mode 100644
index 000000000000..f00add7b3048
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+#include "imx6qdl-skov-cpu-revc.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU QuadCore";
+	compatible = "skov,imx6q-skov-revc-lt2", "fsl,imx6q";
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL		0x4001f878
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA		0x4001f878
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-skov-revc-lt6.dts b/arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
new file mode 100644
index 000000000000..3e3b36ad362a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+#include "imx6qdl-skov-cpu-revc.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU QuadCore";
+	compatible = "skov,imx6q-skov-revc-lt6", "fsl,imx6q";
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_backlight>;
+		enable-gpios = <&gpio6 23 GPIO_ACTIVE_LOW>;
+		pwms = <&pwm2 0 20000 0>;
+		brightness-levels = <0 255>;
+		num-interpolated-steps = <17>;
+		default-brightness-level = <8>;
+		power-supply = <&reg_24v0>;
+	};
+
+	display {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "fsl,imx-parallel-display";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1>;
+
+		port at 0 {
+			reg = <0>;
+
+			display0_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			display0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+
+	panel {
+		compatible = "logictechno,lttd800480070-l6wh-rt";
+		backlight = <&backlight>;
+		power-supply = <&reg_3v3>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display0_out>;
+			};
+		};
+	};
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&ipu1_di0_disp0 {
+	remote-endpoint = <&display0_in>;
+};
+
+&iomuxc {
+	pinctrl_backlight: backlightgrp {
+		fsl,pins = <
+			MX6QDL_PAD_RGMII_TD3__GPIO6_IO23		0x58
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL		0x4001F878
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA		0x4001F878
+		>;
+	};
+
+	pinctrl_ipu1: ipu1grp {
+		fsl,pins = <
+			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK	0x10
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x10
+			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02		0x10
+			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03		0x10
+			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00	0x10
+			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01	0x10
+			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02	0x10
+			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03	0x10
+			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04	0x10
+			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05	0x10
+			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06	0x10
+			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07	0x10
+			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08	0x10
+			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09	0x10
+			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10	0x10
+			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11	0x10
+			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12	0x10
+			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13	0x10
+			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14	0x10
+			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15	0x10
+			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16	0x10
+			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17	0x10
+			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18	0x10
+			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19	0x10
+			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20	0x10
+			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21	0x10
+			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22	0x10
+			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23	0x10
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts b/arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
new file mode 100644
index 000000000000..7f1f19b74bfa
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU QuadCore";
+	compatible = "skov,imx6q-skov-reve-mi1010ait-1cp1", "fsl,imx6q";
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_backlight>;
+		enable-gpios = <&gpio6 23 GPIO_ACTIVE_LOW>;
+		pwms = <&pwm2 0 20000 0>;
+		brightness-levels = <0 255>;
+		num-interpolated-steps = <17>;
+		default-brightness-level = <8>;
+		power-supply = <&reg_24v0>;
+	};
+
+	panel {
+		compatible = "multi-inno,mi1010ait-1cp";
+		backlight = <&backlight>;
+		power-supply = <&reg_3v3>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&lvds0_out>;
+			};
+		};
+	};
+};
+
+&clks {
+	assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+			  <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+	assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>,
+				 <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>;
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	clock-frequency = <100000>;
+	status = "okay";
+
+	touchscreen at 38 {
+		compatible = "edt,edt-ft5406";
+		reg = <0x38>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_touchscreen>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+		touchscreen-size-x = <1280>;
+		touchscreen-size-y = <800>;
+		wakeup-source;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&ldb {
+	status = "okay";
+
+	lvds-channel at 0 {
+		status = "okay";
+
+		port at 4 {
+			reg = <4>;
+
+			lvds0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl_backlight: backlightgrp {
+		fsl,pins = <
+			MX6QDL_PAD_RGMII_TD3__GPIO6_IO23		0x58
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			/* external 1 k pull up */
+			MX6QDL_PAD_EIM_D21__I2C1_SCL		0x40010878
+			/* external 1 k pull up */
+			MX6QDL_PAD_EIM_D28__I2C1_SDA		0x40010878
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL		0x4001F878
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA		0x4001F878
+		>;
+	};
+
+	pinctrl_touchscreen: touchscreengrp {
+		fsl,pins = <
+			/* external 10 k pull up */
+			/* CTP_INT */
+			MX6QDL_PAD_EIM_D19__GPIO3_IO19		0x1b0b0
+			/* CTP_RST */
+			MX6QDL_PAD_EIM_D23__GPIO3_IO23		0x1b0b0
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi b/arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
new file mode 100644
index 000000000000..69ae430a53bd
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+&ecspi4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi4>;
+	cs-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	touchscreen at 0 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_touch>;
+		compatible = "ti,tsc2046";
+		reg = <0>;
+		spi-max-frequency = <1000000>;
+		interrupts-extended = <&gpio3 19 IRQ_TYPE_LEVEL_LOW>;
+		vcc-supply  = <&reg_3v3>;
+		pendown-gpio = <&gpio3 19 GPIO_ACTIVE_LOW>;
+		ti,x-plate-ohms = /bits/ 16 <850>;
+		ti,y-plate-ohms = /bits/ 16 <295>;
+		ti,pressure-min = /bits/ 16 <2>;
+		ti,pressure-max = /bits/ 16 <1500>;
+		ti,vref-mv	= /bits/ 16 <3300>;
+		ti,settle-delay-usec = /bits/ 16 <15>;
+		ti,vref-delay-usecs = /bits/ 16 <0>;
+		ti,penirq-recheck-delay-usecs = /bits/ 16 <100>;
+		ti,debounce-max = /bits/ 16 <100>;
+		ti,debounce-tol = /bits/ 16 <(~0)>;
+		ti,debounce-rep = /bits/ 16 <4>;
+		touchscreen-swapped-x-y;
+		touchscreen-inverted-y;
+		wakeup-source;
+	};
+};
+
+&iomuxc {
+	pinctrl_ecspi4: ecspi4grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D28__ECSPI4_MOSI			0x100b1
+			MX6QDL_PAD_EIM_D22__ECSPI4_MISO			0x000b1
+			MX6QDL_PAD_EIM_D21__ECSPI4_SCLK			0x000b1
+			/* *no* external pull up */
+			MX6QDL_PAD_EIM_D20__GPIO3_IO20		0x40000058
+		>;
+	};
+
+	pinctrl_touch: touchgrp {
+		fsl,pins = <
+			/* external pull up */
+			MX6QDL_PAD_EIM_D19__GPIO3_IO19			0x10040
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi b/arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi
new file mode 100644
index 000000000000..82d044649aa7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi
@@ -0,0 +1,476 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	chosen {
+		stdout-path = &uart2;
+	};
+
+	aliases {
+		can0 = &can1;
+		can1 = &can2;
+		mdio-gpio0 = &mdio;
+		nand = &gpmi;
+		rtc0 = &i2c_rtc;
+		rtc1 = &snvs;
+		usb0 = &usbh1;
+		usb1 = &usbotg;
+	};
+
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 0>, /* 24V */
+		              <&adc 1>; /* temperature */
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			label = "D1";
+			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+			function = LED_FUNCTION_STATUS;
+			default-state = "on";
+			linux,default-trigger = "heartbeat";
+		};
+
+		led-1 {
+			label = "D2";
+			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		led-2 {
+			label = "D3";
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	mdio: mdio {
+		compatible = "microchip,mdio-smi0";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_mdio>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpios = <&gpio1 31 GPIO_ACTIVE_HIGH
+			 &gpio1 22 GPIO_ACTIVE_HIGH>;
+
+		switch at 0 {
+			compatible = "microchip,ksz8873";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_switch>;
+			interrupt-parent = <&gpio3>;
+			interrupt = <30 IRQ_TYPE_LEVEL_HIGH>;
+			reset-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+			reg = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ports at 0 {
+					reg = <0>;
+					phy-mode = "internal";
+					label = "lan1";
+				};
+
+				ports at 1 {
+					reg = <1>;
+					phy-mode = "internal";
+					label = "lan2";
+				};
+
+				ports at 2 {
+					reg = <2>;
+					label = "cpu";
+					ethernet = <&fec>;
+					phy-mode = "rmii";
+
+					fixed-link {
+						speed = <100>;
+						full-duplex;
+					};
+				};
+			};
+		};
+
+	};
+
+	clk50m_phy: phy-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+	};
+
+	reg_3v3: regulator-3v3 {
+		compatible = "regulator-fixed";
+		vin-supply = <&reg_5v0>;
+		regulator-name = "3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_5v0: regulator-5v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	reg_24v0: regulator-24v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "24v0";
+		regulator-min-microvolt = <24000000>;
+		regulator-max-microvolt = <24000000>;
+	};
+
+	reg_can1_stby: regulator-can1-stby {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can1_stby>;
+		regulator-name = "can1-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio3 31 GPIO_ACTIVE_LOW>;
+	};
+
+	reg_can2_stby: regulator-can2-stby {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can2_stby>;
+		regulator-name = "can2-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio4 11 GPIO_ACTIVE_LOW>;
+	};
+
+	reg_vcc_mmc: regulator-vcc-mmc {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_vcc_mmc>;
+		vin-supply = <&reg_3v3>;
+		regulator-name = "mmc_vcc_supply";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+		gpio = <&gpio7 8 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		startup-delay-us = <100>;
+	};
+
+	reg_vcc_mmc_io: regulator-vcc-mmc-io {
+		compatible = "regulator-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_vcc_mmc_io>;
+		vin-supply = <&reg_5v0>;
+		regulator-name = "mmc_io_supply";
+		regulator-type = "voltage";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		gpios = <&gpio7 13 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		states = <1800000 0x1>, <3300000 0x0>;
+		startup-delay-us = <100>;
+	};
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can1>;
+	xceiver-supply = <&reg_can1_stby>;
+	status = "okay";
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can2>;
+	xceiver-supply = <&reg_can2_stby>;
+	status = "okay";
+};
+
+&ecspi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1>;
+	cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <54000000>;
+		reg = <0>;
+	};
+};
+
+&ecspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+	cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	adc: adc at 0 {
+		compatible = "microchip,mcp3002";
+		reg = <0>;
+		spi-max-frequency = <1000000>;
+		#io-channel-cells = <1>;
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet>;
+	clocks = <&clks IMX6QDL_CLK_ENET>,
+		 <&clks IMX6QDL_CLK_ENET>,
+		 <&clk50m_phy>;
+	clock-names = "ipg", "ahb", "ptp";
+	phy-mode = "rmii";
+	phy-supply = <&reg_3v3>;
+	status = "okay";
+
+	fixed-link {
+		speed = <100>;
+		full-duplex;
+	};
+};
+
+&gpmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpmi_nand>;
+	nand-on-flash-bbt;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	i2c_rtc: rtc at 51 {
+		compatible = "nxp,pcf85063";
+		reg = <0x51>;
+		quartz-load-femtofarads = <12500>;
+	};
+};
+
+&pwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm2>;
+	#pwm-cells = <2>;
+	status = "okay";
+};
+
+&pwm3 {
+	/* used for LCD contrast control */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm3>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&usbh1 {
+	vbus-supply = <&reg_5v0>;
+	disable-over-current;
+	status = "okay";
+};
+
+/* no usbh2 */
+&usbphynop1 {
+	status = "disabled";
+};
+
+/* no usbh3 */
+&usbphynop2 {
+	status = "disabled";
+};
+
+&usbotg {
+	vbus-supply = <&reg_5v0>;
+	disable-over-current;
+	status = "okay";
+};
+
+&usdhc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	wp-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
+	cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+	cap-power-off-card;
+	full-pwr-cycle;
+	bus-width = <4>;
+	max-frequency = <50000000>;
+	cap-sd-highspeed;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-ddr50;
+	mmc-ddr-1_8v;
+	vmmc-supply = <&reg_vcc_mmc>;
+	vqmmc-supply = <&reg_vcc_mmc_io>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl_can1: can1grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_7__FLEXCAN1_TX			0x3008
+			MX6QDL_PAD_GPIO_8__FLEXCAN1_RX			0x1b000
+		>;
+	};
+
+	pinctrl_can1_stby: can1stbygrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D31__GPIO3_IO31			0x13008
+		>;
+	};
+
+	pinctrl_can2: can2grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX		0x3008
+			MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX		0x1b000
+		>;
+	};
+
+	pinctrl_can2_stby: can2stbygrp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_ROW2__GPIO4_IO11			0x13008
+		>;
+	};
+
+	pinctrl_ecspi1: ecspi1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D17__ECSPI1_MISO			0x100b1
+			MX6QDL_PAD_EIM_D18__ECSPI1_MOSI			0xb1
+			MX6QDL_PAD_EIM_D16__ECSPI1_SCLK			0xb1
+			/* *no* external pull up */
+			MX6QDL_PAD_EIM_D24__GPIO3_IO24			0x58
+		>;
+	};
+
+	pinctrl_ecspi2: ecspi2grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_OE__ECSPI2_MISO			0x100b1
+			MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI			0xb1
+			MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK			0xb1
+			/* external pull up */
+			MX6QDL_PAD_EIM_RW__GPIO2_IO26			0x58
+		>;
+	};
+
+	pinctrl_enet: enetgrp {
+		fsl,pins = <
+			/* RMII 50 MHz */
+			MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN		0x100f5
+			MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN		0x100f5
+			MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0		0x100c0
+			MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1		0x100c0
+			MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0		0x100f5
+			MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1		0x100f5
+			MX6QDL_PAD_GPIO_16__ENET_REF_CLK		0x1b0b0
+			MX6QDL_PAD_GPIO_5__GPIO1_IO05			0x58
+			/* GPIO for "link active" */
+			MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24		0x3038
+		>;
+	};
+
+	pinctrl_gpmi_nand: gpminandgrp {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CLE__NAND_CLE			0xb0b1
+			MX6QDL_PAD_NANDF_ALE__NAND_ALE			0xb0b1
+			MX6QDL_PAD_NANDF_RB0__NAND_READY_B		0xb000
+			MX6QDL_PAD_NANDF_CS0__NAND_CE0_B		0xb0b1
+			MX6QDL_PAD_NANDF_CS1__NAND_CE1_B		0xb0b1
+			MX6QDL_PAD_SD4_CMD__NAND_RE_B			0xb0b1
+			MX6QDL_PAD_SD4_CLK__NAND_WE_B			0xb0b1
+			MX6QDL_PAD_NANDF_D0__NAND_DATA00		0xb0b1
+			MX6QDL_PAD_NANDF_D1__NAND_DATA01		0xb0b1
+			MX6QDL_PAD_NANDF_D2__NAND_DATA02		0xb0b1
+			MX6QDL_PAD_NANDF_D3__NAND_DATA03		0xb0b1
+			MX6QDL_PAD_NANDF_D4__NAND_DATA04		0xb0b1
+			MX6QDL_PAD_NANDF_D5__NAND_DATA05		0xb0b1
+			MX6QDL_PAD_NANDF_D6__NAND_DATA06		0xb0b1
+			MX6QDL_PAD_NANDF_D7__NAND_DATA07		0xb0b1
+		>;
+	};
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			/* external 10 k pull up */
+			MX6QDL_PAD_GPIO_3__I2C3_SCL		0x40010878
+			/* external 10 k pull up */
+			MX6QDL_PAD_GPIO_6__I2C3_SDA		0x40010878
+		>;
+	};
+
+	pinctrl_mdio: mdiogrp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_MDIO__GPIO1_IO22		0x100b1
+			MX6QDL_PAD_ENET_MDC__GPIO1_IO31			0xb1
+		>;
+	};
+
+	pinctrl_pwm2: pwm2grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_1__PWM2_OUT			0x58
+		>;
+	};
+
+	pinctrl_pwm3: pwm3grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_DAT1__PWM3_OUT			0x58
+		>;
+	};
+
+	pinctrl_switch: switchgrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D30__GPIO3_IO30			0xb0
+		>;
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D26__UART2_TX_DATA		0x1b0b1
+			MX6QDL_PAD_EIM_D27__UART2_RX_DATA		0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc3: usdhc3grp {
+		fsl,pins = <
+			/* SoC internal pull up required */
+			MX6QDL_PAD_SD3_CMD__SD3_CMD			0x17059
+			MX6QDL_PAD_SD3_CLK__SD3_CLK			0x10059
+			MX6QDL_PAD_SD3_DAT0__SD3_DATA0			0x17059
+			MX6QDL_PAD_SD3_DAT1__SD3_DATA1			0x17059
+			MX6QDL_PAD_SD3_DAT2__SD3_DATA2			0x17059
+			MX6QDL_PAD_SD3_DAT3__SD3_DATA3			0x17059
+			/* SoC internal pull up required */
+			MX6QDL_PAD_SD3_DAT4__GPIO7_IO01			0x1b040
+			/* SoC internal pull up required */
+			MX6QDL_PAD_SD3_DAT5__GPIO7_IO00			0x1b040
+		>;
+	};
+
+	pinctrl_vcc_mmc: vccmmcgrp {
+		fsl,pins = <
+			MX6QDL_PAD_SD3_RST__GPIO7_IO08			0x58
+		>;
+	};
+
+	pinctrl_vcc_mmc_io: vccmmciogrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_18__GPIO7_IO13			0x58
+		>;
+	};
+};
-- 
2.30.2



From o.rempel at pengutronix.de  Mon Aug  2 03:36:01 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Mon,  2 Aug 2021 12:36:01 +0200
Subject: [PATCH v3 1/3] dt-bindings: vendor-prefixes: Add an entry for SKOV A/S
In-Reply-To: <20210802103603.28607-1-o.rempel@pengutronix.de>
References: <20210802103603.28607-1-o.rempel@pengutronix.de>
Message-ID: <20210802103603.28607-2-o.rempel@pengutronix.de>

Add "skov" entry for the SKOV A/S: https://www.skov.com/en/

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 62cb1d9341f5..738d4f44f0de 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1068,6 +1068,8 @@ patternProperties:
     description: Silicon Integrated Systems Corp.
   "^sitronix,.*":
     description: Sitronix Technology Corporation
+  "^skov,.*":
+    description: SKOV A/S
   "^skyworks,.*":
     description: Skyworks Solutions, Inc.
   "^smartlabs,.*":
-- 
2.30.2



From o.rempel at pengutronix.de  Mon Aug  2 03:36:00 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Mon,  2 Aug 2021 12:36:00 +0200
Subject: [PATCH v3 0/3] Mainline imx6 based SKOV boards
Message-ID: <20210802103603.28607-1-o.rempel@pengutronix.de>

changes v3:
- drop panel bindings patches, it is already in drm-misc-next
- remove some new lines
- reorder compatibles at the start of the nodes
- use lowercase for hex value
- add enable-active-high to the regulator-vcc-mmc-io and fix MMC voltage
  configuration.

changes v2:
- remove unnecessary newlines.
- change linux,wakeup to wakeup-source
- change switch at 3 unit-address to @0
- sort aliases alphabetically

Mainline imx6 based DTs for SKOV A/S boards

Oleksij Rempel (2):
  dt-bindings: vendor-prefixes: Add an entry for SKOV A/S
  dt-bindings: arm: fsl: add SKOV imx6q and imx6dl based boards

Sam Ravnborg (1):
  ARM: dts: add SKOV imx6q and imx6dl based boards

 .../devicetree/bindings/arm/fsl.yaml          |   5 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/boot/dts/Makefile                    |   5 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts    |  13 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts    | 106 ++++
 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts     |  36 ++
 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts     | 128 +++++
 .../dts/imx6q-skov-reve-mi1010ait-1cp1.dts    | 127 +++++
 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi  |  54 ++
 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi       | 476 ++++++++++++++++++
 10 files changed, 952 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi

-- 
2.30.2



From daniel at 0x0f.com  Mon Aug  2 03:39:57 2021
From: daniel at 0x0f.com (Daniel Palmer)
Date: Mon, 2 Aug 2021 19:39:57 +0900
Subject: [PATCH v2 3/3] ARM: dts: mstar: Add rtc device node
In-Reply-To: <20210801160921.233081-4-romain.perier@gmail.com>
References: <20210801160921.233081-1-romain.perier@gmail.com>
 <20210801160921.233081-4-romain.perier@gmail.com>
Message-ID: <CAFr9PXmqiu=toGf9DjoH8XMbPaiXaWLV=GsmR7OCkkqix5tRvw@mail.gmail.com>

Hi Romain,

On Mon, 2 Aug 2021 at 01:09, Romain Perier <romain.perier at gmail.com> wrote:
> +++ b/arch/arm/boot/dts/mstar-v7.dtsi
> @@ -116,6 +116,13 @@ watchdog at 6000 {
>                                 clocks = <&xtal_div2>;
>                         };
>
> +                       rtc at 2400 {

I think the rtc should be before the watchdog as the address is lower.
I think maybe this got flipped around during cherry-picking.
I can flip it around when I pull this into an mstar dts for 5.15
branch so you don't need to fix it and send a v3 assuming everything
else is ok.

Thanks,

Daniel


From broonie at kernel.org  Mon Aug  2 03:40:40 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Aug 2021 11:40:40 +0100
Subject: [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver
In-Reply-To: <20210731204845.21196-1-andre.przywara@arm.com>
References: <20210731204845.21196-1-andre.przywara@arm.com>
Message-ID: <20210802104040.GA4668@sirena.org.uk>

On Sat, Jul 31, 2021 at 09:48:43PM +0100, Andre Przywara wrote:
> The "Arm True Random Number Generator Firmware Interface"[1] provides
> an SMCCC based interface to a true hardware random number generator.
> So far we are using that in arch_get_random_seed(), but it might be
> useful to expose the entropy through the /dev/hwrng device as well. This
> allows to assess the quality of the implementation, by using "rngtest"
> from the rng-tools package, for example.

Reviewed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/88572cd1/attachment.sig>

From mark.rutland at arm.com  Mon Aug  2 03:42:00 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 11:42:00 +0100
Subject: [PATCH] arm64: fix compat syscall return truncation
Message-ID: <20210802104200.21390-1-mark.rutland@arm.com>

Due to inconsistencies in the way we manipulate compat GPRs, we have a
few issues today:

* For audit and tracing, where error codes are handled as a (native)
  long, negative error codes are expected to be sign-extended to the
  native 64-bits, or they may fail to be matched correctly. Thus a
  syscall which fails with an error may erroneously be identified as
  failing.

* For ptrace, *all* compat return values should be sign-extended for
  consistency with 32-bit arm, but we currently only do this for
  negative return codes.

* As we may transiently set the upper 32 bits of some compat GPRs while
  in the kernel, these can be sampled by perf, which is somewhat
  confusing. This means that where a syscall returns a pointer above 2G,
  this will be sign-extended, but will not be mistaken for an error as
  error codes are constrained to the inclusive range [-4096, -1] where
  no user pointer can exists.

To fix all of these, we must consistently use helpers to get/set the
compat GPRs, ensuring that we never write the upper 32 bits of the
return code, and always sign-extend when reading the return code.  This
patch does so, with the following changes:

* We re-organise syscall_get_return_value() to always sign-extend for
  compat tasks, and reimplement syscall_get_error() atop. We update
  syscall_trace_exit() to use syscall_get_return_value().

* We consistently use syscall_set_return_value() to set the return
  value, ensureing the upper 32 bits are never set unexpectedly.

* As the core audit code currently uses regs_return_value() rather than
  syscall_get_return_value(), we special-case this for
  compat_user_mode(regs) such that this will do the right thing. Going
  forward, we should try to move the core audit code over to
  syscall_get_return_value().

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reported-by: He Zhe <zhe.he at windriver.com>
Reported-by: weiyuchen <weiyuchen3 at huawei.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/ptrace.h  | 12 +++++++++++-
 arch/arm64/include/asm/syscall.h | 19 ++++++++++---------
 arch/arm64/kernel/ptrace.c       |  2 +-
 arch/arm64/kernel/signal.c       |  3 ++-
 arch/arm64/kernel/syscall.c      |  9 +++------
 5 files changed, 27 insertions(+), 18 deletions(-)

This patch addresses the issue reported by both He Zhe [1] and weiyuchen [2].
This was originally posted a reply, without a commit message [3].

I've tried to keep this entirely local to arm64 so that we can backport it; we
should subsequently try to cleanup audit as He Zhe was attempting in [1].

Thanks.
Mark.

[1] https://lore.kernel.org/r/20210416075533.7720-1-zhe.he at windriver.com
[2] https://lore.kernel.org/r/20210722060707.531-1-weiyuchen3 at huawei.com
[3] https://lore.kernel.org/r/20210730142336.GA19569 at C02TD0UTHF1T.local

diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index e58bca832dff..41b332c054ab 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -320,7 +320,17 @@ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
 
 static inline unsigned long regs_return_value(struct pt_regs *regs)
 {
-	return regs->regs[0];
+	unsigned long val = regs->regs[0];
+
+	/*
+	 * Audit currently uses regs_return_value() instead of
+	 * syscall_get_return_value(). Apply the same sign-extension here until
+	 * audit is updated to use syscall_get_return_value().
+	 */
+	if (compat_user_mode(regs))
+		val = sign_extend64(val, 31);
+
+	return val;
 }
 
 static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index cfc0672013f6..03e20895453a 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -29,22 +29,23 @@ static inline void syscall_rollback(struct task_struct *task,
 	regs->regs[0] = regs->orig_x0;
 }
 
-
-static inline long syscall_get_error(struct task_struct *task,
-				     struct pt_regs *regs)
+static inline long syscall_get_return_value(struct task_struct *task,
+					    struct pt_regs *regs)
 {
-	unsigned long error = regs->regs[0];
+	unsigned long val = regs->regs[0];
 
 	if (is_compat_thread(task_thread_info(task)))
-		error = sign_extend64(error, 31);
+		val = sign_extend64(val, 31);
 
-	return IS_ERR_VALUE(error) ? error : 0;
+	return val;
 }
 
-static inline long syscall_get_return_value(struct task_struct *task,
-					    struct pt_regs *regs)
+static inline long syscall_get_error(struct task_struct *task,
+				     struct pt_regs *regs)
 {
-	return regs->regs[0];
+	unsigned long error = syscall_get_return_value(task, regs);
+
+	return IS_ERR_VALUE(error) ? error : 0;
 }
 
 static inline void syscall_set_return_value(struct task_struct *task,
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 499b6b2f9757..b381a1ee9ea7 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1862,7 +1862,7 @@ void syscall_trace_exit(struct pt_regs *regs)
 	audit_syscall_exit(regs);
 
 	if (flags & _TIF_SYSCALL_TRACEPOINT)
-		trace_sys_exit(regs, regs_return_value(regs));
+		trace_sys_exit(regs, syscall_get_return_value(current, regs));
 
 	if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))
 		tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index f8192f4ae0b8..23036334f4dc 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -29,6 +29,7 @@
 #include <asm/unistd.h>
 #include <asm/fpsimd.h>
 #include <asm/ptrace.h>
+#include <asm/syscall.h>
 #include <asm/signal32.h>
 #include <asm/traps.h>
 #include <asm/vdso.h>
@@ -890,7 +891,7 @@ static void do_signal(struct pt_regs *regs)
 		     retval == -ERESTART_RESTARTBLOCK ||
 		     (retval == -ERESTARTSYS &&
 		      !(ksig.ka.sa.sa_flags & SA_RESTART)))) {
-			regs->regs[0] = -EINTR;
+			syscall_set_return_value(current, regs, -EINTR, 0);
 			regs->pc = continue_addr;
 		}
 
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 263d6c1a525f..50a0f1a38e84 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -54,10 +54,7 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
 		ret = do_ni_syscall(regs, scno);
 	}
 
-	if (is_compat_task())
-		ret = lower_32_bits(ret);
-
-	regs->regs[0] = ret;
+	syscall_set_return_value(current, regs, 0, ret);
 
 	/*
 	 * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(),
@@ -115,7 +112,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 		 * syscall. do_notify_resume() will send a signal to userspace
 		 * before the syscall is restarted.
 		 */
-		regs->regs[0] = -ERESTARTNOINTR;
+		syscall_set_return_value(current, regs, -ERESTARTNOINTR, 0);
 		return;
 	}
 
@@ -136,7 +133,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 		 * anyway.
 		 */
 		if (scno == NO_SYSCALL)
-			regs->regs[0] = -ENOSYS;
+			syscall_set_return_value(current, regs, -ENOSYS, 0);
 		scno = syscall_trace_enter(regs);
 		if (scno == NO_SYSCALL)
 			goto trace_exit;
-- 
2.11.0



From will at kernel.org  Mon Aug  2 03:55:45 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Aug 2021 11:55:45 +0100
Subject: [PATCH 0/3] iommu/drm/msm: Allow non-coherent masters to use
 system cache
In-Reply-To: <8b2742c8891abe4fec3664730717a089@codeaurora.org>
References: <cover.1610372717.git.saiprakash.ranjan@codeaurora.org>
 <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
Message-ID: <20210802105544.GA27657@willie-the-truck>

On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> On 2021-07-28 19:30, Georgi Djakov wrote:
> > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > the memory type setting required for the non-coherent masters to use
> > > system cache. Now that system cache support for GPU is added, we will
> > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > Without this, the system cache lines are not allocated for GPU.
> > > 
> > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > and makes GPU the user of this protection flag.
> > 
> > Thank you for the patchset! Are you planning to refresh it, as it does
> > not apply anymore?
> > 
> 
> I was waiting on Will's reply [1]. If there are no changes needed, then
> I can repost the patch.

I still think you need to handle the mismatched alias, no? You're adding
a new memory type to the SMMU which doesn't exist on the CPU side. That
can't be right.

Will


From tabba at google.com  Mon Aug  2 04:13:20 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 13:13:20 +0200
Subject: [PATCH v3 13/21] KVM: arm64: Expose host stage-2 manipulation
 helpers
In-Reply-To: <20210729132818.4091769-14-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-14-qperret@google.com>
Message-ID: <CA+EHjTxTaPc=bt_kyXf0TE85v5eyHnq0o3KQ3Pd6+kOwmm5oMw@mail.gmail.com>

Hi Quentin,

On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> We will need to manipulate the host stage-2 page-table from outside
> mem_protect.c soon. Introduce two functions allowing this, and make
> them usable to users of mem_protect.h.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 ++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 17 ++++++++++++++++-
>  2 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index ae355bfd8c01..47c2a0c51612 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -49,6 +49,8 @@ extern struct host_kvm host_kvm;
>  int __pkvm_prot_finalize(void);
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
>
> +int host_stage2_idmap_locked(u64 start, u64 end, enum kvm_pgtable_prot prot);
> +int host_stage2_set_owner_locked(u64 start, u64 end, u8 owner_id);
>  int kvm_host_prepare_stage2(void *pgt_pool_base);
>  void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 70c57d2c3024..a7f6134789e0 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -272,6 +272,21 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
>         return 0;
>  }
>
> +int host_stage2_idmap_locked(u64 start, u64 end, enum kvm_pgtable_prot prot)
> +{
> +       hyp_assert_lock_held(&host_kvm.lock);
> +
> +       return host_stage2_try(__host_stage2_idmap, start, end, prot);
> +}
> +
> +int host_stage2_set_owner_locked(u64 start, u64 end, u8 owner_id)
> +{
> +       hyp_assert_lock_held(&host_kvm.lock);
> +
> +       return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
> +                              start, end - start, &host_s2_pool, owner_id);
> +}

This is a potential issue elsewhere as well, but all functions in
kvm_pgtable.h, including kvm_pgtable_stage2_set_owner, specify an
address range via address and size. The two you have introduced here
take a start and an end. I'm not sure if making these two consistent
with the ones in kvm_pgtable.h would be good, or would just complicate
things in other places.

Thanks,
/fuad

>  static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
>  {
>         /*
> @@ -309,7 +324,7 @@ static int host_stage2_idmap(u64 addr)
>         if (ret)
>                 goto unlock;
>
> -       ret = host_stage2_try(__host_stage2_idmap, range.start, range.end, prot);
> +       ret = host_stage2_idmap_locked(range.start, range.end, prot);
>  unlock:
>         hyp_spin_unlock(&host_kvm.lock);
>
> --
> 2.32.0.432.gabb21c7263-goog
>


From catalin.marinas at arm.com  Mon Aug  2 04:21:36 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 12:21:36 +0100
Subject: [PATCH 06/10] arm64: Add Neoverse-N2, Cortex-A710 CPU part
 definition
In-Reply-To: <20210728135217.591173-7-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-7-suzuki.poulose@arm.com>
Message-ID: <20210802112136.GA18685@arm.com>

On Wed, Jul 28, 2021 at 02:52:13PM +0100, Suzuki K Poulose wrote:
> Add the CPU Partnumbers for the new Arm designs.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>

I presume this will go in via the coresight tree; if there are
conflicts, we may need a stable branch.


From mike.leach at linaro.org  Mon Aug  2 04:21:31 2021
From: mike.leach at linaro.org (Mike Leach)
Date: Mon, 2 Aug 2021 12:21:31 +0100
Subject: [PATCH 3/6] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <20210731074343.GG7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-4-james.clark@arm.com>
 <20210731074343.GG7437@leoy-ThinkPad-X240s>
Message-ID: <CAJ9a7Vj_KhV+v6VU+EQN5t818VS9jvf3v3-2JbwVMOHZbi3gcg@mail.gmail.com>

Hi Leo.

On Sat, 31 Jul 2021 at 08:43, Leo Yan <leo.yan at linaro.org> wrote:
>
> On Wed, Jul 21, 2021 at 10:07:02AM +0100, James Clark wrote:
> > Now that the metadata has a length field we can add extra registers
> > without breaking any previous versions of perf.
> >
> > Save the TRCDEVARCH register so that it can be used to configure the ETE
> > decoder in the next commit. If the sysfs file doesn't exist then 0 will
> > be saved which is an impossible register value and can also be used to
> > signify that the file couldn't be read.
>
> After reviewed the whole patch set, come back to highlight one thing:
> seems to me ETE is only a feature introduced by new ETMv4 revisions; in
> other words, if we support ETMv4.5 or any later revisions, it will
> support ETE feature.
>

The ETE hardware and trace protocol is introduced to support new
architectural features in the PE - principally those associated with
v9 architecture and beyond. It has has additional packet types that
will never appear in any ETM4.x trace sequence.
ETE (and TRBE) are defined as architectural features of the PE - i.e.
FEAT_ETE and FEAT_TRBE read from feature registers on the core.

You are correct in saying that some features in ETM v4.x beyond ETM
4.5 will also appear in ETE, but the reverse is not true - ETE is a
superset of ETMv4.

> Here I think the right thing to do is to support newer revisions for
> ETMv4, and then based on the revision it creates a decoder with
> supporting ETE feature.  For a more neat solution, if the perf tool
> passes the "correct" revision number to the OpenCSD decoder, it should
> can decode trace data with ETE packets.  In this way, the ETE decoding
> can be transparent for perf cs-etm code.
>

The OpenCSD decoder separates the ETMv4 decoder from the ETE decoder -
for the reasons given above.

Additionally the ETE decoder and the ETMv4 decoder required different
sets of ID registers to correctly set up the decoder.  For example,
for ETMv4 the version is extracted form TRCIDR1, for ETE the version
in TRCIDR1 is set 0xFF, and thus needs TRCDEVARCH to extract the
revision. It is likely that later updates to ETE will require an
additional TRCIDR register to be saved.

Choosing the base type of decoder in this way is how the library can
support ETMv3, EMTv4, ETE, STM, PTM etc - and while some of those
protocols use TRCIDR1 and TRCDEVARCH - not all do.

It would in theory be possible to have the OpenCSD library
"autodetect" the type of decoder needed based purely on a set of ID
registers. But this set of ID registers would be far larger than the
ones currently used, and would require modifcation to a lot of the
existing device drivers to ensure they were accessible via sysfs. This
register set includes the ID registers that are currently used to
identify the component on the AMBA bus and match to the correct
driver, plus additional CoreSight management registers. This would
also create a dependency between decoder creation and ID numbers - in
the same way that each new ETM4.x part number has to be added to the
ETM4.x device driver.

Such a system would require a significant update to the OpenCSD
infrastructure, and is not planned at this time.

Regards

Mike


> How about you think for this?  Sorry if I introduce noise due to my
> lack knowledge (and platform) for ETE.
>
> Thanks,
> Leo



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From catalin.marinas at arm.com  Mon Aug  2 04:21:50 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 12:21:50 +0100
Subject: [PATCH 06/10] arm64: Add Neoverse-N2, Cortex-A710 CPU part
 definition
In-Reply-To: <20210728135217.591173-7-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-7-suzuki.poulose@arm.com>
Message-ID: <20210802112149.GB18685@arm.com>

On Wed, Jul 28, 2021 at 02:52:13PM +0100, Suzuki K Poulose wrote:
> Add the CPU Partnumbers for the new Arm designs.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Mon Aug  2 04:22:35 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 12:22:35 +0100
Subject: [PATCH 07/10] arm64: Add erratum detection for TRBE overwrite in
 FILL mode
In-Reply-To: <20210728135217.591173-8-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-8-suzuki.poulose@arm.com>
Message-ID: <20210802112235.GC18685@arm.com>

On Wed, Jul 28, 2021 at 02:52:14PM +0100, Suzuki K Poulose wrote:
> Arm Neoverse-N2 and the Cortex-A710 cores are affected
> by a CPU erratum where the TRBE will overwrite the trace buffer
> in FILL mode. The TRBE doesn't stop (as expected in FILL mode)
> when it reaches the limit and wraps to the base to continue
> writing upto 3 cache lines. This will overwrite any trace that
> was written previously.
> 
> Add the Neoverse-N2 erratumi(#2139208) and Cortex-A710 erratum
> (#2119858) to the  detection logic.
> 
> This will be used by the TRBE driver in later patches to work
> around the issue. The detection has been kept with the core
> arm64 errata framework list to make sure :
>   - We don't duplicate the framework in TRBE driver
>   - The errata detection is advertised like the rest
>     of the CPU errata.
> 
> Note that the Kconfig entries will be added after we have added
> the work around in the TRBE driver, which depends on the cpucap
> from here.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> cc: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Mon Aug  2 04:24:54 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 12:24:54 +0100
Subject: [PATCH 09/10] arm64: Enable workaround for TRBE overwrite in
 FILL mode
In-Reply-To: <20210728135217.591173-10-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-10-suzuki.poulose@arm.com>
Message-ID: <20210802112453.GD18685@arm.com>

On Wed, Jul 28, 2021 at 02:52:16PM +0100, Suzuki K Poulose wrote:
> Now that we have the work around implmented in the TRBE
> driver, add the Kconfig entries and document the errata.
> 
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Mon Aug  2 04:27:12 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 12:27:12 +0100
Subject: [PATCH 10/10] arm64: errata: Add workaround for TSB flush failures
In-Reply-To: <20210728135217.591173-11-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-11-suzuki.poulose@arm.com>
Message-ID: <20210802112712.GE18685@arm.com>

On Wed, Jul 28, 2021 at 02:52:17PM +0100, Suzuki K Poulose wrote:
> Arm Neoverse-N2 (#2067961) and Cortex-A710 (#2054223) suffers
> from errata, where a TSB (trace synchronization barrier)
> fails to flush the trace data completely, when executed from
> a trace prohibited region. In Linux we always execute it
> after we have moved the PE to trace prohibited region. So,
> we can apply the workaround everytime a TSB is executed.
> 
> The work around is to issue two TSB consecutively.
> 
> NOTE: This errata is defined as LOCAL_CPU_ERRATUM, implying
> that a late CPU could be blocked from booting if it is the
> first CPU that requires the workaround. This is because we
> do not allow setting a cpu_hwcaps after the SMP boot. The
> other alternative is to use "this_cpu_has_cap()" instead
> of the faster system wide check, which may be a bit of an
> overhead, given we may have to do this in nvhe KVM host
> before a guest entry.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>

With Marc's comments addressed:

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From benh at kernel.crashing.org  Mon Aug  2 04:26:13 2021
From: benh at kernel.crashing.org (Benjamin Herrenschmidt)
Date: Mon, 02 Aug 2021 21:26:13 +1000
Subject: [PATCH v3 0/4] efi/arm64: work around Image placement issues
In-Reply-To: <20210726145156.12006-1-ardb@kernel.org>
References: <20210726145156.12006-1-ardb@kernel.org>
Message-ID: <b3041039f08ffd524eef37d35950b30c5e11255e.camel@kernel.crashing.org>

On Mon, 2021-07-26 at 16:51 +0200, Ard Biesheuvel wrote:
> Ben reported that distro GRUB may fail to boot in some circumstances,
> and tracked it down to an issue in the way distro GRUB allocates space
> for the image. Due to an oversight (addressed in patch #2), this
> condition is rarely triggered, but let's work around it in any case (#1)
> 
> Remaining patches add further warnings for conditions that are unlikely
> to occur, but should not be ignored.
> 
> Build tested only.
> 
> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>

All 4 patches:

Tested-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>

I checked that it catches all of the errors, including reverting my fix
for randomalloc.c and verifying that it caught (and successfully worked
around) the original boot  crash.

Cheers,
Ben.



From broonie at kernel.org  Mon Aug  2 04:33:30 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Aug 2021 12:33:30 +0100
Subject: [PATCH v3 3/4] kselftest/arm64: Add tests for SVE vector
 configuration
In-Reply-To: <20210802102517.GA25258@arm.com>
References: <20210729151518.46388-1-broonie@kernel.org>
 <20210729151518.46388-4-broonie@kernel.org>
 <20210729160642.GP1724@arm.com>
 <20210729173411.GT4670@sirena.org.uk>
 <20210802102517.GA25258@arm.com>
Message-ID: <20210802113330.GD4668@sirena.org.uk>

On Mon, Aug 02, 2021 at 11:25:29AM +0100, Dave Martin wrote:

> That's a reasonable position, but thinking about it a bit more, there's
> not really any loop at all here.
> 
> There definitely is an unwaited-for child and we don't pass WHONANG to
> wait(), so it will either return the child pid, or fail.
> 
> Without WUNTRACED or similar, the child must terminate to wake up the
> wait().

> So is this just a matter of

> 	pid = wait(&ret);
> 	if (pid == -1) {
> 		/* barf */
> 	}
> 	assert(pid == child);
> 
> 	if (!WIFEXITED(ret)) {
> 		/* barf */
> 	}
> 
> 	if (WEXITSTATUS(ret) != 0) {
> 		/* barf */
> 	}
> 
> 	/* parse child's stdout etc. */

That really doesn't seem like a good idea - it's just asking for
fragility if a signal gets delivered to the parent process or something.
Even if almost all the time there will only be one trip through the loop
we should still have the loop there for those few cases where it
triggers.

> 
> > Please delete unneeded context from mails when replying.  Doing this
> > makes it much easier to find your reply in the message, helping ensure
> > it won't be missed by people scrolling through the irrelevant quoted
> > material.
> 
> Hmmm, usually I at least try to do that, but I did seem to leave rather
> a lot of trailing junk that time.
> 
> (Working out which context is relevant is not always an exact science,
> but in this case, it looks like I just forgot.)
> 
> Cheers
> ---Dave 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/958ef258/attachment.sig>

From iwona.winiarska at intel.com  Mon Aug  2 04:37:30 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Mon, 2 Aug 2021 11:37:30 +0000
Subject: [PATCH 13/14] docs: hwmon: Document PECI drivers
In-Reply-To: <20210727225808.GU8018@packtop>
References: <20210712220447.957418-1-iwona.winiarska@intel.com>
 <20210712220447.957418-14-iwona.winiarska@intel.com>
 <20210727225808.GU8018@packtop>
Message-ID: <ea5621698508a800cea59b5533f8845b9f0befc6.camel@intel.com>

On Tue, 2021-07-27 at 22:58 +0000, Zev Weiss wrote:
> On Mon, Jul 12, 2021 at 05:04:46PM CDT, Iwona Winiarska wrote:
> > From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > 
> > Add documentation for peci-cputemp driver that provides DTS thermal
> > readings for CPU packages and CPU cores and peci-dimmtemp driver that
> > provides DTS thermal readings for DIMMs.
> > 
> > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> > ---
> > Documentation/hwmon/index.rst???????? |? 2 +
> > Documentation/hwmon/peci-cputemp.rst? | 93 +++++++++++++++++++++++++++
> > Documentation/hwmon/peci-dimmtemp.rst | 58 +++++++++++++++++
> > MAINTAINERS?????????????????????????? |? 2 +
> > 4 files changed, 155 insertions(+)
> > create mode 100644 Documentation/hwmon/peci-cputemp.rst
> > create mode 100644 Documentation/hwmon/peci-dimmtemp.rst
> > 
> > diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
> > index bc01601ea81a..cc76b5b3f791 100644
> > --- a/Documentation/hwmon/index.rst
> > +++ b/Documentation/hwmon/index.rst
> > @@ -154,6 +154,8 @@ Hardware Monitoring Kernel Drivers
> > ?? pcf8591
> > ?? pim4328
> > ?? pm6764tr
> > +?? peci-cputemp
> > +?? peci-dimmtemp
> > ?? pmbus
> > ?? powr1220
> > ?? pxe1610
> > diff --git a/Documentation/hwmon/peci-cputemp.rst
> > b/Documentation/hwmon/peci-cputemp.rst
> > new file mode 100644
> > index 000000000000..d3a218ba810a
> > --- /dev/null
> > +++ b/Documentation/hwmon/peci-cputemp.rst
> > @@ -0,0 +1,93 @@
> > +.. SPDX-License-Identifier: GPL-2.0-only
> > +
> > +Kernel driver peci-cputemp
> > +==========================
> > +
> > +Supported chips:
> > +???????One of Intel server CPUs listed below which is connected to a PECI
> > bus.
> > +???????????????* Intel Xeon E5/E7 v3 server processors
> > +???????????????????????Intel Xeon E5-14xx v3 family
> > +???????????????????????Intel Xeon E5-24xx v3 family
> > +???????????????????????Intel Xeon E5-16xx v3 family
> > +???????????????????????Intel Xeon E5-26xx v3 family
> > +???????????????????????Intel Xeon E5-46xx v3 family
> > +???????????????????????Intel Xeon E7-48xx v3 family
> > +???????????????????????Intel Xeon E7-88xx v3 family
> > +???????????????* Intel Xeon E5/E7 v4 server processors
> > +???????????????????????Intel Xeon E5-16xx v4 family
> > +???????????????????????Intel Xeon E5-26xx v4 family
> > +???????????????????????Intel Xeon E5-46xx v4 family
> > +???????????????????????Intel Xeon E7-48xx v4 family
> > +???????????????????????Intel Xeon E7-88xx v4 family
> > +???????????????* Intel Xeon Scalable server processors
> > +???????????????????????Intel Xeon D family
> > +???????????????????????Intel Xeon Bronze family
> > +???????????????????????Intel Xeon Silver family
> > +???????????????????????Intel Xeon Gold family
> > +???????????????????????Intel Xeon Platinum family
> > +
> > +???????Datasheet: Available from http://www.intel.com/design/literature.htm
> > +
> > +Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > +
> > +Description
> > +-----------
> > +
> > +This driver implements a generic PECI hwmon feature which provides Digital
> > +Thermal Sensor (DTS) thermal readings of the CPU package and CPU cores that
> > are
> > +accessible via the processor PECI interface.
> > +
> > +All temperature values are given in millidegree Celsius and will be
> > measurable
> > +only when the target CPU is powered on.
> > +
> > +Sysfs interface
> > +-------------------
> > +
> > +=======================
> > =======================================================
> > +temp1_label????????????"Die"
> > +temp1_input????????????Provides current die temperature of the CPU package.
> > +temp1_max??????????????Provides thermal control temperature of the CPU
> > package
> > +???????????????????????which is also known as Tcontrol.
> > +temp1_crit?????????????Provides shutdown temperature of the CPU package
> > which
> > +???????????????????????is also known as the maximum processor junction
> > +???????????????????????temperature, Tjmax or Tprochot.
> > +temp1_crit_hyst????????????????Provides the hysteresis value from Tcontrol
> > to Tjmax of
> > +???????????????????????the CPU package.
> > +
> > +temp2_label????????????"DTS"
> > +temp2_input????????????Provides current DTS temperature of the CPU package.
> 
> Would this be a good place to note the slightly counter-intuitive nature
> of DTS readings?? i.e. add something along the lines of "The DTS sensor
> produces a delta relative to Tjmax, so negative values are normal and
> values approaching zero are hot."? (In my experience people who aren't
> already familiar with it tend to think something's wrong when a CPU
> temperature reading shows -50C.)

I believe that what you're referring to is a result of "GetTemp", and we're
using it to calculate "Die" sensor values (temp1).
The sensor value is absolute - we don't expose "raw" thermal sensor value
(delta) anywhere.

DTS sensor is exposing temperature value scaled to fit DTS 2.0 thermal profile: 
https://www.intel.com/content/www/us/en/processors/xeon/scalable/xeon-scalable-thermal-guide.html
(section 5.2.3.2)

Similar to "Die" sensor - it's also exposed in absolute form.

I'll try to change description to avoid confusion.

> 
> > +temp2_max??????????????Provides thermal control temperature of the CPU
> > package
> > +???????????????????????which is also known as Tcontrol.
> > +temp2_crit?????????????Provides shutdown temperature of the CPU package which
> > +???????????????????????is also known as the maximum processor junction
> > +???????????????????????temperature, Tjmax or Tprochot.
> > +temp2_crit_hyst????????????????Provides the hysteresis value from Tcontrol to
> > Tjmax of
> > +???????????????????????the CPU package.
> > +
> > +temp3_label????????????"Tcontrol"
> > +temp3_input????????????Provides current Tcontrol temperature of the CPU
> > +???????????????????????package which is also known as Fan Temperature target.
> > +???????????????????????Indicates the relative value from thermal monitor trip
> > +???????????????????????temperature at which fans should be engaged.
> > +temp3_crit?????????????Provides Tcontrol critical value of the CPU package
> > +???????????????????????which is same to Tjmax.
> > +
> > +temp4_label????????????"Tthrottle"
> > +temp4_input????????????Provides current Tthrottle temperature of the CPU
> > +???????????????????????package. Used for throttling temperature. If this
> > value
> > +???????????????????????is allowed and lower than Tjmax - the throttle will
> > +???????????????????????occur and reported at lower than Tjmax.
> > +
> > +temp5_label????????????"Tjmax"
> > +temp5_input????????????Provides the maximum junction temperature, Tjmax of
> > the
> > +???????????????????????CPU package.
> > +
> > +temp[6-N]_label????????????????Provides string "Core X", where X is resolved
> > core
> > +???????????????????????number.
> > +temp[6-N]_input????????????????Provides current temperature of each core.
> > +temp[6-N]_max??????????Provides thermal control temperature of the core.
> > +temp[6-N]_crit?????????Provides shutdown temperature of the core.
> > +temp[6-N]_crit_hyst????Provides the hysteresis value from Tcontrol to Tjmax
> > of
> > +???????????????????????the core.
> 
> I only see *_label and *_input for the per-core temperature sensors, no
> *_max, *_crit, or *_crit_hyst.

You're right - this should be removed from documentation.

> 
> > +
> > +=======================
> > =======================================================
> > diff --git a/Documentation/hwmon/peci-dimmtemp.rst b/Documentation/hwmon/peci-
> > dimmtemp.rst
> > new file mode 100644
> > index 000000000000..1778d9317e43
> > --- /dev/null
> > +++ b/Documentation/hwmon/peci-dimmtemp.rst
> > @@ -0,0 +1,58 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +Kernel driver peci-dimmtemp
> > +===========================
> > +
> > +Supported chips:
> > +???????One of Intel server CPUs listed below which is connected to a PECI
> > bus.
> > +???????????????* Intel Xeon E5/E7 v3 server processors
> > +???????????????????????Intel Xeon E5-14xx v3 family
> > +???????????????????????Intel Xeon E5-24xx v3 family
> > +???????????????????????Intel Xeon E5-16xx v3 family
> > +???????????????????????Intel Xeon E5-26xx v3 family
> > +???????????????????????Intel Xeon E5-46xx v3 family
> > +???????????????????????Intel Xeon E7-48xx v3 family
> > +???????????????????????Intel Xeon E7-88xx v3 family
> > +???????????????* Intel Xeon E5/E7 v4 server processors
> > +???????????????????????Intel Xeon E5-16xx v4 family
> > +???????????????????????Intel Xeon E5-26xx v4 family
> > +???????????????????????Intel Xeon E5-46xx v4 family
> > +???????????????????????Intel Xeon E7-48xx v4 family
> > +???????????????????????Intel Xeon E7-88xx v4 family
> > +???????????????* Intel Xeon Scalable server processors
> > +???????????????????????Intel Xeon D family
> > +???????????????????????Intel Xeon Bronze family
> > +???????????????????????Intel Xeon Silver family
> > +???????????????????????Intel Xeon Gold family
> > +???????????????????????Intel Xeon Platinum family
> > +
> > +???????Datasheet: Available from http://www.intel.com/design/literature.htm
> > +
> > +Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > +
> > +Description
> > +-----------
> > +
> > +This driver implements a generic PECI hwmon feature which provides Digital
> > +Thermal Sensor (DTS) thermal readings of DIMM components that are accessible
> > +via the processor PECI interface.
> 
> I had thought "DTS" referred to a fairly specific sensor in the CPU; is
> the same term also used for DIMM temp sensors or is the mention of it
> here a copy/paste error?

Yeah - it should be "Temperature Sensor on DIMM".

Thanks
-Iwona

> 
> > +
> > +All temperature values are given in millidegree Celsius and will be
> > measurable
> > +only when the target CPU is powered on.
> > +
> > +Sysfs interface
> > +-------------------
> > +
> > +=======================
> > =======================================================
> > +
> > +temp[N]_label??????????Provides string "DIMM CI", where C is DIMM channel and
> > +???????????????????????I is DIMM index of the populated DIMM.
> > +temp[N]_input??????????Provides current temperature of the populated DIMM.
> > +temp[N]_max????????????Provides thermal control temperature of the DIMM.
> > +temp[N]_crit???????????Provides shutdown temperature of the DIMM.
> > +
> > +=======================
> > =======================================================
> > +
> > +Note:
> > +???????DIMM temperature attributes will appear when the client CPU's BIOS
> > +???????completes memory training and testing.
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 35ba9e3646bd..d16da127bbdc 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -14509,6 +14509,8 @@ M:??????Iwona Winiarska <iwona.winiarska at intel.com>
> > R:??????Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > L:??????linux-hwmon at vger.kernel.org
> > S:??????Supported
> > +F:?????Documentation/hwmon/peci-cputemp.rst
> > +F:?????Documentation/hwmon/peci-dimmtemp.rst
> > F:??????drivers/hwmon/peci/
> > 
> > PECI SUBSYSTEM
> > -- 
> > 2.31.1


From dongas86 at gmail.com  Mon Aug  2 04:36:20 2021
From: dongas86 at gmail.com (Dong Aisheng)
Date: Mon, 2 Aug 2021 19:36:20 +0800
Subject: [PATCH 5/7] dt-bindings: soc: imx: add missing anatop binding
In-Reply-To: <20210722024948.GA3198597@robh.at.kernel.org>
References: <20210715082536.1882077-1-aisheng.dong@nxp.com>
 <20210715082536.1882077-6-aisheng.dong@nxp.com>
 <20210722024948.GA3198597@robh.at.kernel.org>
Message-ID: <CAA+hA=TwGGwZi2HzZSLSZHYWEi8Pp6AnHeRpfDhD0pUfY_xPSQ@mail.gmail.com>

Hi Rob,

On Thu, Jul 22, 2021 at 10:49 AM Rob Herring <robh at kernel.org> wrote:
>
> On Thu, Jul 15, 2021 at 04:25:34PM +0800, Dong Aisheng wrote:
> > Anatop is a system combo module which supports various analog functions
> > like PLL, Regulators, LDOs, Sensors and etc.
> > This binding doc is generated based on the exist usage in dts
> > in order to fix dt schema check failures.
> >
> > Cc: Rob Herring <robh+dt at kernel.org>
> > Cc: Shawn Guo <shawnguo at kernel.org>
> > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> > ---
> >  .../bindings/soc/imx/fsl,anatop.yaml          | 68 +++++++++++++++++++
> >  1 file changed, 68 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> > new file mode 100644
> > index 000000000000..f379d960f527
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> > @@ -0,0 +1,68 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/soc/imx/fsl,anatop.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Freescale Anatop binding
> > +
> > +maintainers:
> > +  - Dong Aisheng <aisheng.dong at nxp.com>
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - items:
> > +          - const: fsl,imx6q-anatop
> > +          - const: syscon
> > +          - const: simple-mfd
> > +      - items:
> > +          - enum:
> > +              - fsl,imx6sl-anatop
> > +              - fsl,imx6sll-anatop
> > +              - fsl,imx6sx-anatop
> > +              - fsl,imx6ul-anatop
> > +              - fsl,imx7d-anatop
> > +          - const: fsl,imx6q-anatop
> > +          - const: syscon
> > +          - const: simple-mfd
> > +      - items:
> > +          - enum:
> > +              - fsl,imx8mq-anatop
> > +              - fsl,imx8mm-anatop
> > +              - fsl,vf610-anatop
> > +          - const: syscon
> > +      - items:
> > +          - enum:
> > +              - fsl,imx8mn-anatop
> > +              - fsl,imx8mp-anatop
> > +          - const: fsl,imx8mm-anatop
> > +          - const: syscon
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    items:
> > +      - description: Temperature Sensor
> > +      - description: PMU interrupt 1
> > +      - description: PMU interrupt 2
> > +    minItems: 1
> > +    maxItems: 3
>
> Don't need maxItems.
>

Got it

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +
> > +additionalProperties: true
>
> This should be the case only for common schemas used by other schemas.
>

Like iomuxc-gpr in patch 6, the problem is that for those nodes with
simple-mfd backwards compatibility,
there could be possibly some random subnodes since there're generic
combo registers.
That's why i use additionalProperties true to cover it.
Do you think it's ok?

e.g.
anatop: anatop at 20c8000 {
        compatible = "fsl,imx6q-anatop", "syscon", "simple-mfd";
        reg = <0x020c8000 0x1000>;
        interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
                     <0 54 IRQ_TYPE_LEVEL_HIGH>,
                     <0 127 IRQ_TYPE_LEVEL_HIGH>;

        reg_vdd1p1: regulator-1p1 {
                compatible = "fsl,anatop-regulator";
                regulator-name = "vdd1p1";
                regulator-min-microvolt = <1000000>;
                regulator-max-microvolt = <1200000>;
                ...
        };

        tempmon: tempmon {
                compatible = "fsl,imx6q-tempmon";
                interrupt-parent = <&gpc>;
                interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>;
                fsl,tempmon = <&anatop>;
                nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
                nvmem-cell-names = "calib", "temp_grade";
                clocks = <&clks IMX6QDL_CLK_PLL3_USB_OTG>;
                #thermal-sensor-cells = <0>;
        };
};

gpr: iomuxc-gpr at 20e0000 {
        compatible = "fsl,imx6q-iomuxc-gpr", "syscon", "simple-mfd";
        reg = <0x20e0000 0x38>;

        mux: mux-controller {
                compatible = "mmio-mux";
                #mux-control-cells = <1>;
        };
};

> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    anatop: anatop at 20c8000 {
>

Got it

Regards
Aisheng

> Drop unused labels.
>
> > +        compatible = "fsl,imx6q-anatop", "syscon", "simple-mfd";
> > +        reg = <0x020c8000 0x1000>;
> > +        interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <0 54 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <0 127 IRQ_TYPE_LEVEL_HIGH>;
> > +        };
> > --
> > 2.25.1
> >
> >


From dongas86 at gmail.com  Mon Aug  2 04:36:54 2021
From: dongas86 at gmail.com (Dong Aisheng)
Date: Mon, 2 Aug 2021 19:36:54 +0800
Subject: [PATCH 6/7] dt-bindings: soc: imx: add missing iomuxc gpr binding
In-Reply-To: <CAL_JsqLZLK75pj_HQDNY1CtHuKGRx-u36eDOyr8ObkR==GW6gQ@mail.gmail.com>
References: <20210715082536.1882077-1-aisheng.dong@nxp.com>
 <20210715082536.1882077-7-aisheng.dong@nxp.com>
 <1626357250.406964.968555.nullmailer@robh.at.kernel.org>
 <CAA+hA=TsEfz9Zo3wfsf6ZXnYHtfv5AbGNqVQEMn0q0bh1TOQDQ@mail.gmail.com>
 <CAL_JsqLZLK75pj_HQDNY1CtHuKGRx-u36eDOyr8ObkR==GW6gQ@mail.gmail.com>
Message-ID: <CAA+hA=SD8W2tp4VVrK9JkAVrWGCddZd+7UAchDh6sUu+uMLuqQ@mail.gmail.com>

On Thu, Jul 29, 2021 at 1:30 AM Rob Herring <robh at kernel.org> wrote:
>
> On Thu, Jul 15, 2021 at 9:30 PM Dong Aisheng <dongas86 at gmail.com> wrote:
> >
> > Hi Rob,
> >
> > On Thu, Jul 15, 2021 at 9:54 PM Rob Herring <robh at kernel.org> wrote:
> > >
> > > On Thu, 15 Jul 2021 16:25:35 +0800, Dong Aisheng wrote:
> > > > The General Purpose Registers IOMUXC_GPR are used to select operating
> > > > modes for general features in the SoC, usually not related to the IOMUX
> > > > itself.
> > > >
> > > > This binding doc is generated based on the exist usage in dts
> > > > in order to fix dt schema check failures.
> > > >
> > > > Cc: Rob Herring <robh+dt at kernel.org>
> > > > Cc: Shawn Guo <shawnguo at kernel.org>
> > > > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> > > > ---
> > > >  .../devicetree/bindings/soc/imx/fsl,gpr.yaml  | 69 +++++++++++++++++++
> > > >  1 file changed, 69 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,gpr.yaml
> > > >
> > >
> > > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> > > on your patch (DT_CHECKER_FLAGS is new in v5.13):
> > >
> > > yamllint warnings/errors:
> > >
> > > dtschema/dtc warnings/errors:
> > > /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/syscon.example.dt.yaml: iomuxc-gpr at 20e0000: compatible: 'oneOf' conditional failed, one must be fixed:
> > >         ['fsl,imx6q-iomuxc-gpr', 'syscon'] is too short
> > >         'fsl,imx53-iomuxc-gpr' was expected
> > >         'fsl,imx6q-iomuxc-gpr' is not one of ['fsl,imx6sl-iomuxc-gpr', 'fsl,imx6sll-iomuxc-gpr', 'fsl,imx6sx-iomuxc-gpr', 'fsl,imx6ul-iomuxc-gpr', 'fsl,imx7d-iomuxc-gpr']
> > >         'fsl,imx7d-iomuxc-gpr' was expected
> > >         'fsl,imx8mq-iomuxc-gpr' was expected
> > >         'fsl,imx6q-iomuxc-gpr' is not one of ['fsl,imx8mm-iomuxc-gpr', 'fsl,imx8mn-iomuxc-gpr', 'fsl,imx8mp-iomuxc-gpr']
> > >         'fsl,imx6q-iomuxc-gpr' was expected
> > >         From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/imx/fsl,gpr.yaml
> > > \ndoc reference errors (make refcheckdocs):
> > > Warning: MAINTAINERS references a file that doesn't exist: Documentation/devicetree/bindings/spi/spi-nxp-fspi.txt
> > > MAINTAINERS: Documentation/devicetree/bindings/spi/spi-nxp-fspi.txt
> >
> > The example in syscon.yaml is invalid and needs change as follows.
> > However, should I do it in a separate patch cause they're changes for
> > two irrelevant binding
> > files or merge into this one ?
>
> Separate patch.
>
> > diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml
> > b/Documentation/devicetree/bindings/mfd/syscon.yaml
> > index f14ae6da0068..11eae4c5848e 100644
> > --- a/Documentation/devicetree/bindings/mfd/syscon.yaml
> > +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
> > @@ -90,7 +90,7 @@ examples:
> >
> >    - |
> >      gpr: iomuxc-gpr at 20e0000 {
> > -        compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
> > +        compatible = "fsl,imx6q-iomuxc-gpr", "syscon", "mfd";
>
> I assume you mean 'simple-mfd'?
>
> Adding that means this example doesn't really even match the
> syscon.yaml, so I'd just drop the example.

Will drop, thanks

Regards
Aisheng


From christophe.leroy at csgroup.eu  Mon Aug  2 04:39:00 2021
From: christophe.leroy at csgroup.eu (LEROY Christophe)
Date: Mon, 2 Aug 2021 13:39:00 +0200
Subject: [PATCH] Revert "mm/pgtable: add stubs for
 {pmd/pub}_{set/clear}_huge"
In-Reply-To: <20210720112704.GA8419@willie-the-truck>
References: <20210717160118.9855-1-jonathan@marek.ca>
 <20210717183108.Horde.NxzyIKsItUWF4WlYgwgptg1@messagerie.c-s.fr>
 <20210719104918.GA6440@willie-the-truck>
 <CAMj1kXH5eBitt4max6dAOUbWsjy5XYqaMFV-L8HLWJmkbxUXAg@mail.gmail.com>
 <CAMj1kXFYFOmz1vGhQk7PmMNf1ELLVhvVgGe=vAxpkFTO_QkOTA@mail.gmail.com>
 <20210719175103.Horde.4PSTelFeNoNx8NpxkqkVPQ2@messagerie.c-s.fr>
 <CAMj1kXGbz9GGPHPDUxBi=VBnkKjwgvbamqxGFZE1UKY7dciXaA@mail.gmail.com>
 <20210719185843.Horde.Z9DmONNS9Hi0sokFE50aJQ6@messagerie.c-s.fr>
 <20210720112704.GA8419@willie-the-truck>
Message-ID: <cfd1e226-61d5-cbf2-1137-40c30a59d5d7@csgroup.eu>



Le 20/07/2021 ? 13:27, Will Deacon a ?crit?:
> On Mon, Jul 19, 2021 at 06:58:43PM +0200, Christophe Leroy wrote:
>> Ard Biesheuvel <ardb at kernel.org> a ?crit?:
>>> On Mon, 19 Jul 2021 at 17:45, Christophe Leroy
>>> <christophe.leroy at csgroup.eu> wrote:
>>>> Ard Biesheuvel <ardb at kernel.org> a ?crit :
>>>>> On Mon, 19 Jul 2021 at 15:58, Ard Biesheuvel <ardb at kernel.org> wrote:
>>>>>> On Mon, 19 Jul 2021 at 12:49, Will Deacon <will at kernel.org> wrote:
>>>>>>> For 4k pages with 3 levels of walk, we want to be able to use
>>>> 1GB mappings
>>>>>>> at level 1 (pgd), 2MB mappings at level 2 (pmd) as well as the usual 4k
>>>>>>> page mappings at level 3 (pte).
>>>>>>>
>>>>>>
>>>>>> Yes, we appear to use PUDs for 4k pages kernel regardless of whether
>>>>>> they are folded into PGDs to refer to level 1/1GB block mappings.
>>>>
>>>> And that's probably the source of the misunderstanding, because a 3
>>>> level architecture is supposed to only have pgd, pmd and pud.
>>>>
>>>
>>> Is this requirement documented somewhere? Having folded PUDs does not
>>> necessarily mean that PUDs don't exist, but simply that PUDs and PGDs
>>> are the same.
>>
>> If you look at linux/pgtable.h you can see that p4d_set_huge and
>> p4d_clear_huge are only for 5 level MMUs. Why shouldn't the same principle
>> apply to PUD and PMD ?
> 
> Prior to your patch, you could make the opposite argument. Why are
> p4x_{set_clear}_huge() guarded? Those were introduced after the others
> as well.
> 

Why are they guarded ? Probably because when they aren't, with ARM64 
defconfig we get:

   LD      vmlinux.o
   MODPOST vmlinux.symvers
   MODINFO modules.builtin.modinfo
   GEN     modules.builtin
   LD      .tmp_vmlinux.kallsyms1
aarch64-linux-gnu-ld: Unexpected GOT/PLT entries detected!
aarch64-linux-gnu-ld: Unexpected run-time procedure linkages detected!
aarch64-linux-gnu-ld: mm/vmalloc.o: in function `vunmap_p4d_range':
/home/chleroy/linux-powerpc/mm/vmalloc.c:385: undefined reference to 
`p4d_clear_huge'
aarch64-linux-gnu-ld: /home/chleroy/linux-powerpc/mm/vmalloc.c:385: 
undefined reference to `p4d_clear_huge'
make: *** [Makefile:1177: vmlinux] Error 1


Christophe


From iwona.winiarska at intel.com  Mon Aug  2 04:39:36 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Mon, 2 Aug 2021 11:39:36 +0000
Subject: [PATCH 13/14] docs: hwmon: Document PECI drivers
In-Reply-To: <0521a076-9772-532f-2eab-8870464ca211@roeck-us.net>
References: <20210712220447.957418-1-iwona.winiarska@intel.com>
 <20210712220447.957418-14-iwona.winiarska@intel.com>
 <20210727225808.GU8018@packtop>
 <0521a076-9772-532f-2eab-8870464ca211@roeck-us.net>
Message-ID: <ad6b0ccbed7ad3e4a8b8519571f5c23cca22a12d.camel@intel.com>

On Tue, 2021-07-27 at 17:49 -0700, Guenter Roeck wrote:
> On 7/27/21 3:58 PM, Zev Weiss wrote:
> > On Mon, Jul 12, 2021 at 05:04:46PM CDT, Iwona Winiarska wrote:
> > > From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > 
> > > Add documentation for peci-cputemp driver that provides DTS thermal
> > > readings for CPU packages and CPU cores and peci-dimmtemp driver that
> > > provides DTS thermal readings for DIMMs.
> > > 
> > > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> > > ---
> > > Documentation/hwmon/index.rst???????? |? 2 +
> > > Documentation/hwmon/peci-cputemp.rst? | 93 +++++++++++++++++++++++++++
> > > Documentation/hwmon/peci-dimmtemp.rst | 58 +++++++++++++++++
> > > MAINTAINERS?????????????????????????? |? 2 +
> > > 4 files changed, 155 insertions(+)
> > > create mode 100644 Documentation/hwmon/peci-cputemp.rst
> > > create mode 100644 Documentation/hwmon/peci-dimmtemp.rst
> > > 
> > > diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
> > > index bc01601ea81a..cc76b5b3f791 100644
> > > --- a/Documentation/hwmon/index.rst
> > > +++ b/Documentation/hwmon/index.rst
> > > @@ -154,6 +154,8 @@ Hardware Monitoring Kernel Drivers
> > > ??? pcf8591
> > > ??? pim4328
> > > ??? pm6764tr
> > > +?? peci-cputemp
> > > +?? peci-dimmtemp
> > > ??? pmbus
> > > ??? powr1220
> > > ??? pxe1610
> > > diff --git a/Documentation/hwmon/peci-cputemp.rst
> > > b/Documentation/hwmon/peci-cputemp.rst
> > > new file mode 100644
> > > index 000000000000..d3a218ba810a
> > > --- /dev/null
> > > +++ b/Documentation/hwmon/peci-cputemp.rst
> > > @@ -0,0 +1,93 @@
> > > +.. SPDX-License-Identifier: GPL-2.0-only
> > > +
> > > +Kernel driver peci-cputemp
> > > +==========================
> > > +
> > > +Supported chips:
> > > +???????One of Intel server CPUs listed below which is connected to a PECI
> > > bus.
> > > +???????????????* Intel Xeon E5/E7 v3 server processors
> > > +???????????????????????Intel Xeon E5-14xx v3 family
> > > +???????????????????????Intel Xeon E5-24xx v3 family
> > > +???????????????????????Intel Xeon E5-16xx v3 family
> > > +???????????????????????Intel Xeon E5-26xx v3 family
> > > +???????????????????????Intel Xeon E5-46xx v3 family
> > > +???????????????????????Intel Xeon E7-48xx v3 family
> > > +???????????????????????Intel Xeon E7-88xx v3 family
> > > +???????????????* Intel Xeon E5/E7 v4 server processors
> > > +???????????????????????Intel Xeon E5-16xx v4 family
> > > +???????????????????????Intel Xeon E5-26xx v4 family
> > > +???????????????????????Intel Xeon E5-46xx v4 family
> > > +???????????????????????Intel Xeon E7-48xx v4 family
> > > +???????????????????????Intel Xeon E7-88xx v4 family
> > > +???????????????* Intel Xeon Scalable server processors
> > > +???????????????????????Intel Xeon D family
> > > +???????????????????????Intel Xeon Bronze family
> > > +???????????????????????Intel Xeon Silver family
> > > +???????????????????????Intel Xeon Gold family
> > > +???????????????????????Intel Xeon Platinum family
> > > +
> > > +???????Datasheet: Available from http://www.intel.com/design/literature.htm
> > > +
> > > +Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > +
> > > +Description
> > > +-----------
> > > +
> > > +This driver implements a generic PECI hwmon feature which provides Digital
> > > +Thermal Sensor (DTS) thermal readings of the CPU package and CPU cores that
> > > are
> > > +accessible via the processor PECI interface.
> > > +
> > > +All temperature values are given in millidegree Celsius and will be
> > > measurable
> > > +only when the target CPU is powered on.
> > > +
> > > +Sysfs interface
> > > +-------------------
> > > +
> > > +=======================
> > > =======================================================
> > > +temp1_label????????????"Die"
> > > +temp1_input????????????Provides current die temperature of the CPU package.
> > > +temp1_max??????????????Provides thermal control temperature of the CPU
> > > package
> > > +???????????????????????which is also known as Tcontrol.
> > > +temp1_crit?????????????Provides shutdown temperature of the CPU package
> > > which
> > > +???????????????????????is also known as the maximum processor junction
> > > +???????????????????????temperature, Tjmax or Tprochot.
> > > +temp1_crit_hyst????????????????Provides the hysteresis value from Tcontrol
> > > to Tjmax of
> > > +???????????????????????the CPU package.
> > > +
> > > +temp2_label????????????"DTS"
> > > +temp2_input????????????Provides current DTS temperature of the CPU package.
> > 
> > Would this be a good place to note the slightly counter-intuitive nature
> > of DTS readings?? i.e. add something along the lines of "The DTS sensor
> > produces a delta relative to Tjmax, so negative values are normal and
> > values approaching zero are hot."? (In my experience people who aren't
> > already familiar with it tend to think something's wrong when a CPU
> > temperature reading shows -50C.)
> > 
> 
> All attributes shall follow the ABI, and the driver must translate reported
> values to degrees C. If those sensors do not follow the ABI and report something
> else, I won't accept the driver.
> 
> Guenter

Sure, I believe all attributes already follow the ABI and the reported values
are in millidegree Celsius.

Thanks
-Iwona
> 


From tangbin at cmss.chinamobile.com  Mon Aug  2 04:50:26 2021
From: tangbin at cmss.chinamobile.com (tangbin)
Date: Mon, 2 Aug 2021 19:50:26 +0800
Subject: [PATCH] iio: adc: fsl-imx25-gcq: fix the right check andsimplify
 code
In-Reply-To: <20210802111647.000012ee@Huawei.com>
References: <20210727125209.28248-1-tangbin@cmss.chinamobile.com>
 <20210731174551.188aee79@jic23-huawei>
 <b84ea3e4-5650-d6ac-36f6-98067b286b45@cmss.chinamobile.com>
 <20210802111647.000012ee@Huawei.com>
Message-ID: <d1e08b62-37dd-b1e2-2cf5-baa03ccb16f2@cmss.chinamobile.com>

Hi Jonathan:

On 2021/8/2 18:16, Jonathan Cameron wrote:
> On Mon, 2 Aug 2021 10:31:58 +0800
> tangbin <tangbin at cmss.chinamobile.com> wrote:
>
>> Hi Jonathan:
>>
>> On 2021/8/1 0:45, Jonathan Cameron wrote:
>>> On Tue, 27 Jul 2021 20:52:09 +0800
>>> Tang Bin <tangbin at cmss.chinamobile.com> wrote:
>>>   
>>>> For the function of platform_get_irq(), the example in platform.c is
>>>> *		int irq = platform_get_irq(pdev, 0);
>>>> *		if (irq < 0)
>>>> *			return irq;
>>>> So the return value of zero is unnecessary to check. And move it
>>>> up to a little bit can simplify the code jump.
>>>>
>>>> Co-developed-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
>>>> Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
>>>> Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
>>> Hi,
>>>
>>> Logically it is better to keep the irq handling all together, so
>>> I would prefer we didn't move it.
>> Got it in this place.
>>> Also, platform_get_irq() is documented as never returning 0, so the current
>>> code is not incorrect.  As such, this looks like noise unless there is
>>> some plan to make use of the 0 return value?  What benefit do we get from
>>> this change?
>> Thanks for your reply, I think the benefit of this change maybe just
>> simplify the code.
>>
>> Because the return value is never equal to 0, so the check in here is
>> redundant.
>>
>> We can make the patch like this:
>>
>>>> ---
>>>>    drivers/iio/adc/fsl-imx25-gcq.c | 12 ++++--------
>>>>    1 file changed, 4 insertions(+), 8 deletions(-)
>>>>
>>>> diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
>>>> index 8cb51cf7a..d28976f21 100644
>>>> --- a/drivers/iio/adc/fsl-imx25-gcq.c
>>>> +++ b/drivers/iio/adc/fsl-imx25-gcq.c
>>>> @@ -320,6 +320,10 @@ static int mx25_gcq_probe(struct platform_device *pdev)
>>>>    	if (ret)
>>>>    		return ret;
>>>>    
>>>> +	priv->irq = platform_get_irq(pdev, 0);
>>>> +	if (priv->irq < 0)
>>>> +		return priv->irq;
>>>> +
>>>>    	for (i = 0; i != 4; ++i) {
>>>>    		if (!priv->vref[i])
>>>>    			continue;
>>>> @@ -336,14 +340,6 @@ static int mx25_gcq_probe(struct platform_device *pdev)
>>>>    		goto err_vref_disable;
>>>>    	}
>>>>    
>>>> -	priv->irq = platform_get_irq(pdev, 0);
>>>> -	if (priv->irq <= 0) {
>>>> -		ret = priv->irq;
>>>> -		if (!ret)
>>>> -			ret = -ENXIO;
>>>> -		goto err_clk_unprepare;
>>>> -	}
>>>> -
>> 	priv->irq = platform_get_irq(pdev, 0);
>> 	if (priv->irq < 0) {
>> 		ret = priv->irq;
>> 		goto err_clk_unprepare;
>> 	}
>>
>>   ??? If you think this is ok, I will send V2 for you. If you think these
>> change is meaningless,
> OK, it's a minor tidy up, so lets go with that, or perhaps this is even tidier?
> Assuming types of ret and irq are appropriate (I've not checked!)
>
>
> 	ret = platform_get_irq(pdev, 0);
> 	if (ret)
> 		goto err_clk_unprepare;
>
> 	priv->irq = ret;
>
Thanks for your reply, ret or irq or priv->irq are all appropriate, and 
the changes of mine maybe traditional.

I will send v2 for you like your changes.

Thank you very much.

Tang Bin


>> just dropped this.
>>
>> Thanks
>>
>> Tang Bin
>>
>>
>>
>>




From andreyknvl at gmail.com  Mon Aug  2 04:52:09 2021
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Mon, 2 Aug 2021 13:52:09 +0200
Subject: [PATCH 3/3] arm64: kasan: mte: remove redundant mte_report_once
 logic
In-Reply-To: <20210731114930.GA1616@arm.com>
References: <20210714143843.56537-1-mark.rutland@arm.com>
 <20210714143843.56537-4-mark.rutland@arm.com>
 <20210727185418.GU13920@arm.com>
 <CA+fCnZcLE=DcVcq1TfLxRSOnBfD-iy2iGgyxg7zHk28YxWTHbQ@mail.gmail.com>
 <20210731104430.GA1112@arm.com>
 <CA+fCnZdvC_c6aqfZOPBRyJ4Hv9JA4tKWtvA7-m1W6nTPXSGoxw@mail.gmail.com>
 <20210731114930.GA1616@arm.com>
Message-ID: <CA+fCnZdKCiudrLmCaBKr76kHDsL2YZgnu48idYA9TwOUK16-1A@mail.gmail.com>

On Sat, Jul 31, 2021 at 1:49 PM Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> > > Because kasan has its own mechanism with KASAN_BIT_REPORTED.
> >
> > This mechanism only works when multi_shot is disabled. But milti_shot
> > is always enabled when running the tests. Yet I tested the series, and
> > I don't see multiple reports for each test, so everything somehow
> > works. But I don't understand how.
>
> When running tests, "reported" variable update is also disabled, so it
> wouldn't make any difference.
>
> When a fault happens in synchronous mode, to be able to continue safely
> the tag checking is disabled on the current CPU (and lazily on the other
> CPUs). So you won't be able to get another report on that CPU anyway. In
> the unlikely event that the test thread migrates to another CPU before
> completion, it may trigger another tag check fault on the new CPU and a
> report.
>
> We probably don't see multiple reports during a single test because (a)
> kasan tests have preemption disabled, (b) they are unlikely to migrate
> during the short time they run or (c) the kasan tests only do a single
> faulty access.

I've got a feeling there was some other reason for this "reported"
check, but I don't remember what that was. Maybe this was related to a
bug in the earlier version of the MTE patches.

Anyway, the code looks good and the tests work for me as expected, so:

Reviewed-by: Andrey Konovalov <andreyknvl at gmail.com>
Tested-by: Andrey Konovalov <andreyknvl at gmail.com>

Thanks!


From andreyknvl at gmail.com  Mon Aug  2 04:57:58 2021
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Mon, 2 Aug 2021 13:57:58 +0200
Subject: [PATCH 2/3] arm64: kasan: mte: use a constant kernel GCR_EL1 value
In-Reply-To: <20210714143843.56537-3-mark.rutland@arm.com>
References: <20210714143843.56537-1-mark.rutland@arm.com>
 <20210714143843.56537-3-mark.rutland@arm.com>
Message-ID: <CA+fCnZd7QYtzP_iy6FLaBXyX5RY1JKxVpYFZNCjKqUU5TWgz2g@mail.gmail.com>

On Wed, Jul 14, 2021 at 4:38 PM Mark Rutland <mark.rutland at arm.com> wrote:
>
> When KASAN_HW_TAGS is selected, KASAN is enabled at boot time, and the
> hardware supports MTE, we'll initialize `kernel_gcr_excl` with a value
> dependent on KASAN_TAG_MAX. While the resulting value is a constant
> which depends on KASAN_TAG_MAX, we have to perform some runtime work to
> generate the value, and have to read the value from memory during the
> exception entry path. It would be better if we could generate this as a
> constant at compile-time, and use it as such directly.
>
> Early in boot within __cpu_setup(), we initialize GCR_EL1 to a safe
> value, and later override this with the value required by KASAN. If
> CONFIG_KASAN_HW_TAGS is not selected, or if KASAN is disabeld at boot
> time, the kernel will not use IRG instructions, and so the initial value
> of GCR_EL1 is does not matter to the kernel. Thus, we can instead have
> __cpu_setup() initialize GCR_EL1 to a value consistent with
> KASAN_TAG_MAX, and avoid the need to re-initialize it during hotplug and
> resume form suspend.
>
> This patch makes arem64 use a compile-time constant KERNEL_GCR_EL1
> value, which is compatible with KASAN_HW_TAGS when this is selected.
> This removes the need to re-initialize GCR_EL1 dynamically, and acts as
> an optimization to the entry assembly, which no longer needs to load
> this value from memory. The redundant initialization hooks are removed.
>
> In order to do this, KASAN_TAG_MAX needs to be visible outside of the
> core KASAN code. To do this, I've moved the KASAN_TAG_* values into
> <linux/kasan-tags.h>.
>
> There should be no functional change as a result of this patch.
>
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Alexander Potapenko <glider at google.com>
> Cc: Andrey Konovalov <andreyknvl at gmail.com>
> Cc: Andrey Ryabinin <ryabinin.a.a at gmail.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Dmitry Vyukov <dvyukov at google.com>
> Cc: Peter Collingbourne <pcc at google.com>
> Cc: Vincenzo Frascino <vincenzo.frascino at arm.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/memory.h    |  1 -
>  arch/arm64/include/asm/mte-kasan.h |  5 -----
>  arch/arm64/include/asm/mte.h       |  6 ------
>  arch/arm64/include/asm/sysreg.h    | 16 ++++++++++++++++
>  arch/arm64/kernel/entry.S          |  5 ++---
>  arch/arm64/kernel/mte.c            | 31 -------------------------------
>  arch/arm64/kernel/suspend.c        |  1 -
>  arch/arm64/mm/proc.S               |  3 +--
>  include/linux/kasan-tags.h         | 15 +++++++++++++++
>  mm/kasan/hw_tags.c                 |  2 --
>  mm/kasan/kasan.h                   | 15 +--------------
>  11 files changed, 35 insertions(+), 65 deletions(-)
>  create mode 100644 include/linux/kasan-tags.h
>
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 824a3655dd93..7f4e6a923aa6 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -245,7 +245,6 @@ static inline const void *__tag_set(const void *addr, u8 tag)
>  #define arch_enable_tagging_async()            mte_enable_kernel_async()
>  #define arch_set_tagging_report_once(state)    mte_set_report_once(state)
>  #define arch_force_async_tag_fault()           mte_check_tfsr_exit()
> -#define arch_init_tags(max_tag)                        mte_init_tags(max_tag)
>  #define arch_get_random_tag()                  mte_get_random_tag()
>  #define arch_get_mem_tag(addr)                 mte_get_mem_tag(addr)
>  #define arch_set_mem_tag_range(addr, size, tag, init)  \
> diff --git a/arch/arm64/include/asm/mte-kasan.h b/arch/arm64/include/asm/mte-kasan.h
> index d952352bd008..82fa4ac4ad4e 100644
> --- a/arch/arm64/include/asm/mte-kasan.h
> +++ b/arch/arm64/include/asm/mte-kasan.h
> @@ -130,7 +130,6 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag,
>
>  void mte_enable_kernel_sync(void);
>  void mte_enable_kernel_async(void);
> -void mte_init_tags(u64 max_tag);
>
>  void mte_set_report_once(bool state);
>  bool mte_report_once(void);
> @@ -165,10 +164,6 @@ static inline void mte_enable_kernel_async(void)
>  {
>  }
>
> -static inline void mte_init_tags(u64 max_tag)
> -{
> -}
> -
>  static inline void mte_set_report_once(bool state)
>  {
>  }
> diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
> index 58c7f80f5596..3f93b9e0b339 100644
> --- a/arch/arm64/include/asm/mte.h
> +++ b/arch/arm64/include/asm/mte.h
> @@ -16,8 +16,6 @@
>
>  #include <asm/pgtable-types.h>
>
> -extern u64 gcr_kernel_excl;
> -
>  void mte_clear_page_tags(void *addr);
>  unsigned long mte_copy_tags_from_user(void *to, const void __user *from,
>                                       unsigned long n);
> @@ -43,7 +41,6 @@ void mte_copy_page_tags(void *kto, const void *kfrom);
>  void mte_thread_init_user(void);
>  void mte_thread_switch(struct task_struct *next);
>  void mte_suspend_enter(void);
> -void mte_suspend_exit(void);
>  long set_mte_ctrl(struct task_struct *task, unsigned long arg);
>  long get_mte_ctrl(struct task_struct *task);
>  int mte_ptrace_copy_tags(struct task_struct *child, long request,
> @@ -72,9 +69,6 @@ static inline void mte_thread_switch(struct task_struct *next)
>  static inline void mte_suspend_enter(void)
>  {
>  }
> -static inline void mte_suspend_exit(void)
> -{
> -}
>  static inline long set_mte_ctrl(struct task_struct *task, unsigned long arg)
>  {
>         return 0;
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 7b9c3acba684..f6687f6f536b 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -11,6 +11,7 @@
>
>  #include <linux/bits.h>
>  #include <linux/stringify.h>
> +#include <linux/kasan-tags.h>
>
>  /*
>   * ARMv8 ARM reserves the following encoding for system registers:
> @@ -1067,6 +1068,21 @@
>  #define SYS_GCR_EL1_RRND       (BIT(16))
>  #define SYS_GCR_EL1_EXCL_MASK  0xffffUL
>
> +#ifdef CONFIG_KASAN_HW_TAGS
> +/*
> + * KASAN always uses a whole byte for its tags. With CONFIG_KASAN_HW_TAGS it
> + * only uses tags in the range 0xF0-0xFF, which we map to MTE tags 0x0-0xF.
> + */
> +#define __MTE_TAG_MIN          (KASAN_TAG_MIN & 0xf)
> +#define __MTE_TAG_MAX          (KASAN_TAG_MAX & 0xf)
> +#define __MTE_TAG_INCL         GENMASK(__MTE_TAG_MAX, __MTE_TAG_MIN)
> +#define KERNEL_GCR_EL1_EXCL    (SYS_GCR_EL1_EXCL_MASK & ~__MTE_TAG_INCL)
> +#else
> +#define KERNEL_GCR_EL1_EXCL    SYS_GCR_EL1_EXCL_MASK
> +#endif
> +
> +#define KERNEL_GCR_EL1         (SYS_GCR_EL1_RRND | KERNEL_GCR_EL1_EXCL)
> +
>  /* RGSR_EL1 Definitions */
>  #define SYS_RGSR_EL1_TAG_MASK  0xfUL
>  #define SYS_RGSR_EL1_SEED_SHIFT        8
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 863d44f73028..247170bb5489 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -177,9 +177,8 @@ alternative_else_nop_endif
>  alternative_if_not ARM64_MTE
>         b       1f
>  alternative_else_nop_endif
> -       ldr_l   \tmp, gcr_kernel_excl
> -
> -       mte_set_gcr \tmp, \tmp2
> +       mov     \tmp, KERNEL_GCR_EL1
> +       msr_s   SYS_GCR_EL1, \tmp
>         isb
>  1:
>  #endif
> diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> index 36f51b0e438a..c106d2ff8b1d 100644
> --- a/arch/arm64/kernel/mte.c
> +++ b/arch/arm64/kernel/mte.c
> @@ -22,8 +22,6 @@
>  #include <asm/ptrace.h>
>  #include <asm/sysreg.h>
>
> -u64 gcr_kernel_excl __ro_after_init;
> -
>  static bool report_fault_once = true;
>
>  #ifdef CONFIG_KASAN_HW_TAGS
> @@ -101,26 +99,6 @@ int memcmp_pages(struct page *page1, struct page *page2)
>         return ret;
>  }
>
> -void mte_init_tags(u64 max_tag)
> -{
> -       static bool gcr_kernel_excl_initialized;
> -
> -       if (!gcr_kernel_excl_initialized) {
> -               /*
> -                * The format of the tags in KASAN is 0xFF and in MTE is 0xF.
> -                * This conversion extracts an MTE tag from a KASAN tag.
> -                */
> -               u64 incl = GENMASK(FIELD_GET(MTE_TAG_MASK >> MTE_TAG_SHIFT,
> -                                            max_tag), 0);
> -
> -               gcr_kernel_excl = ~incl & SYS_GCR_EL1_EXCL_MASK;
> -               gcr_kernel_excl_initialized = true;
> -       }
> -
> -       /* Enable the kernel exclude mask for random tags generation. */
> -       write_sysreg_s(SYS_GCR_EL1_RRND | gcr_kernel_excl, SYS_GCR_EL1);
> -}
> -
>  static inline void __mte_enable_kernel(const char *mode, unsigned long tcf)
>  {
>         /* Enable MTE Sync Mode for EL1. */
> @@ -248,15 +226,6 @@ void mte_suspend_enter(void)
>         mte_check_tfsr_el1();
>  }
>
> -void mte_suspend_exit(void)
> -{
> -       if (!system_supports_mte())
> -               return;
> -
> -       sysreg_clear_set_s(SYS_GCR_EL1, SYS_GCR_EL1_EXCL_MASK, gcr_kernel_excl);
> -       isb();
> -}
> -
>  long set_mte_ctrl(struct task_struct *task, unsigned long arg)
>  {
>         u64 sctlr = task->thread.sctlr_user & ~SCTLR_EL1_TCF0_MASK;
> diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
> index 938ce6fbee8a..19ee7c33769d 100644
> --- a/arch/arm64/kernel/suspend.c
> +++ b/arch/arm64/kernel/suspend.c
> @@ -76,7 +76,6 @@ void notrace __cpu_suspend_exit(void)
>         spectre_v4_enable_mitigation(NULL);
>
>         /* Restore additional feature-specific configuration */
> -       mte_suspend_exit();
>         ptrauth_suspend_exit();
>  }
>
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index 35936c5ae1ce..d35c90d2e47a 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -437,8 +437,7 @@ SYM_FUNC_START(__cpu_setup)
>         mov     x10, #MAIR_ATTR_NORMAL_TAGGED
>         bfi     mair, x10, #(8 *  MT_NORMAL_TAGGED), #8
>
> -       /* initialize GCR_EL1: all non-zero tags excluded by default */
> -       mov     x10, #(SYS_GCR_EL1_RRND | SYS_GCR_EL1_EXCL_MASK)
> +       mov     x10, #KERNEL_GCR_EL1
>         msr_s   SYS_GCR_EL1, x10
>
>         /*
> diff --git a/include/linux/kasan-tags.h b/include/linux/kasan-tags.h
> new file mode 100644
> index 000000000000..4f85f562512c
> --- /dev/null
> +++ b/include/linux/kasan-tags.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _LINUX_KASAN_TAGS_H
> +#define _LINUX_KASAN_TAGS_H
> +
> +#define KASAN_TAG_KERNEL       0xFF /* native kernel pointers tag */
> +#define KASAN_TAG_INVALID      0xFE /* inaccessible memory tag */
> +#define KASAN_TAG_MAX          0xFD /* maximum value for random tags */
> +
> +#ifdef CONFIG_KASAN_HW_TAGS
> +#define KASAN_TAG_MIN          0xF0 /* minimum value for random tags */
> +#else
> +#define KASAN_TAG_MIN          0x00 /* minimum value for random tags */
> +#endif
> +
> +#endif /* LINUX_KASAN_TAGS_H */
> diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
> index 4ea8c368b5b8..2c6c6c6ddfa2 100644
> --- a/mm/kasan/hw_tags.c
> +++ b/mm/kasan/hw_tags.c
> @@ -142,8 +142,6 @@ void kasan_init_hw_tags_cpu(void)
>         if (kasan_arg == KASAN_ARG_OFF)
>                 return;
>
> -       hw_init_tags(KASAN_TAG_MAX);
> -
>         /*
>          * Enable async mode only when explicitly requested through
>          * the command line.
> diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
> index 98e3059bfea4..89587f762ab4 100644
> --- a/mm/kasan/kasan.h
> +++ b/mm/kasan/kasan.h
> @@ -3,6 +3,7 @@
>  #define __MM_KASAN_KASAN_H
>
>  #include <linux/kasan.h>
> +#include <linux/kasan-tags.h>
>  #include <linux/kfence.h>
>  #include <linux/stackdepot.h>
>
> @@ -50,16 +51,6 @@ extern bool kasan_flag_async __ro_after_init;
>
>  #define KASAN_MEMORY_PER_SHADOW_PAGE   (KASAN_GRANULE_SIZE << PAGE_SHIFT)
>
> -#define KASAN_TAG_KERNEL       0xFF /* native kernel pointers tag */
> -#define KASAN_TAG_INVALID      0xFE /* inaccessible memory tag */
> -#define KASAN_TAG_MAX          0xFD /* maximum value for random tags */
> -
> -#ifdef CONFIG_KASAN_HW_TAGS
> -#define KASAN_TAG_MIN          0xF0 /* minimum value for random tags */
> -#else
> -#define KASAN_TAG_MIN          0x00 /* minimum value for random tags */
> -#endif
> -
>  #ifdef CONFIG_KASAN_GENERIC
>  #define KASAN_FREE_PAGE         0xFF  /* page was freed */
>  #define KASAN_PAGE_REDZONE      0xFE  /* redzone for kmalloc_large allocations */
> @@ -298,9 +289,6 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
>  #ifndef arch_enable_tagging_async
>  #define arch_enable_tagging_async()
>  #endif
> -#ifndef arch_init_tags
> -#define arch_init_tags(max_tag)
> -#endif
>  #ifndef arch_set_tagging_report_once
>  #define arch_set_tagging_report_once(state)
>  #endif
> @@ -319,7 +307,6 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
>
>  #define hw_enable_tagging_sync()               arch_enable_tagging_sync()
>  #define hw_enable_tagging_async()              arch_enable_tagging_async()
> -#define hw_init_tags(max_tag)                  arch_init_tags(max_tag)
>  #define hw_set_tagging_report_once(state)      arch_set_tagging_report_once(state)
>  #define hw_force_async_tag_fault()             arch_force_async_tag_fault()
>  #define hw_get_random_tag()                    arch_get_random_tag()
> --
> 2.11.0
>

This kind of breaks the idea of having a standalone MTE API, and
having KASAN use that API to set everything up. But the change does
simplify the logic quite a bit. So if ARM maintainers are happy with
it, I'm fine with it as well.

For KASAN parts:

Reviewed-by: Andrey Konovalov <andreyknvl at gmail.com>
Tested-by: Andrey Konovalov <andreyknvl at gmail.com>


From liuqi115 at huawei.com  Mon Aug  2 05:02:47 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Mon, 2 Aug 2021 20:02:47 +0800
Subject: [PATCH] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <2f32fff3-6b58-583f-8e85-06ec1553d3f4@huawei.com>
References: <20210719122417.10355-1-liuqi115@huawei.com>
 <20210721174153.34c1898dc9eea135eb0b8be8@kernel.org>
 <332df5b7d7bb4bd096b6521ffefaabe6@hisilicon.com>
 <20210723000318.5594c86e7c454aed82d9465d@kernel.org>
 <e63531dc8b7040219761e72fb9b1e74a@hisilicon.com>
 <20210731101537.a64063d84e86d7910bd58a96@kernel.org>
 <6a97dff6c33c4b84887223de2502bd3d@hisilicon.com>
 <2f32fff3-6b58-583f-8e85-06ec1553d3f4@huawei.com>
Message-ID: <ddb44b9b-cc18-8f49-e82c-b1ae00546962@huawei.com>



On 2021/8/2 11:52, liuqi (BA) wrote:
[...]

>> This might be the direction to go later. Anyway, "Rome wasn't built
>> in a day", for this stage, we might focus on optprobe for the case
>> of non-randomized module region :-).
>>
>> BTW, @liuqi, if users set "nokaslr" in bootargs, will your optprobe
>> always work and not fall back to normal kprobe even we remove the
>> dependency on RANDOMIZED_MODULE_REGION_FULL?
>>
> Hi Barry,
> 
> I do some tests on Hip08 platform, using nokaslr in booting cmdline and 
> remove dependency on RANDOMIZED_MODULE_REGION_FULL, optprobe seems work.
> Here is the log:
> 
> estuary:/$ uname -a
> Linux (none) 5.13.0-rc4+ #37 SMP PREEMPT Mon Aug 2 08:13:37 CST 2021 
> aarch64 GNU/Linux
> estuary:/$ zcat /proc/config.gz | grep RANDOMIZE_MODULE_REGION
> CONFIG_RANDOMIZE_MODULE_REGION_FULL=y
> estuary:/$ zcat /proc/config.gz | grep OPTPROBE
> CONFIG_OPTPROBES=y
> CONFIG_HAVE_OPTPROBES=y
> estuary:/$ cat /proc/cmdline
> console=ttyAMA0,115200 earlycon=pl011,0x9000000 kpti=off nokaslr
> estuary:/$ cat /sys/bus/platform/devices/hello_driver/kprobe_test
> [?? 61.304143] do_empty returned 0 and took 200 ns to execute
> [?? 61.304662] do_empty returned 0 and took 110 ns to execute
> [?? 61.305196] do_empty returned 0 and took 100 ns to execute
> [?? 61.305745] do_empty returned 0 and took 90 ns to execute
> [?? 61.306262] do_empty returned 0 and took 90 ns to execute
> [?? 61.306781] do_empty returned 0 and took 90 ns to execute
> [?? 61.307286] do_empty returned 0 and took 90 ns to execute
> [?? 61.307798] do_empty returned 0 and took 90 ns to execute
> [?? 61.308314] do_empty returned 0 and took 90 ns to execute
> [?? 61.308828] do_empty returned 0 and took 90 ns to execute
> [?? 61.309323] do_empty returned 0 and took 80 ns to execute
> [?? 61.309832] do_empty returned 0 and took 80 ns to execute
> [?? 61.310357] do_empty returned 0 and took 80 ns to execute
> [?? 61.310871] do_empty returned 0 and took 80 ns to execute
> [?? 61.311361] do_empty returned 0 and took 80 ns to execute
> [?? 61.311851] do_empty returned 0 and took 90 ns to execute
> [?? 61.312358] do_empty returned 0 and took 90 ns to execute
> [?? 61.312879] do_empty returned 0 and took 80 ns to execute
> 
> Thanks,
> Qi
> 
Hi Barry,


I've done test on Hip08 platform using nokaslr in booting cmdline and 
remove dependency on RANDOMIZED_MODULE_REGION_FULL, on following 4 cases:
1. probed code in module, pre_handler in kernel.
2. probed code in kernel, pre_handler in kernel.
3. probed code in module, pre_handler in module.
4. probed code in kernel, pre_handler in module.

and optprobe works in these 4 cases.

Thanks,
Qi
>>>
>>> Thank you,
>>>
>>> -- 
>>> Masami Hiramatsu <mhiramat at kernel.org>
>>
>> Thanks
>> Barry
>> .
>>
> 
> .



From ardb at kernel.org  Mon Aug  2 05:03:59 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 2 Aug 2021 14:03:59 +0200
Subject: [PATCH v3 0/4] efi/arm64: work around Image placement issues
In-Reply-To: <b3041039f08ffd524eef37d35950b30c5e11255e.camel@kernel.crashing.org>
References: <20210726145156.12006-1-ardb@kernel.org>
 <b3041039f08ffd524eef37d35950b30c5e11255e.camel@kernel.crashing.org>
Message-ID: <CAMj1kXEu_C13WRaBML9T5gvXsukxP8B0hzH3bn5ZD6HpNshmZw@mail.gmail.com>

On Mon, 2 Aug 2021 at 13:26, Benjamin Herrenschmidt
<benh at kernel.crashing.org> wrote:
>
> On Mon, 2021-07-26 at 16:51 +0200, Ard Biesheuvel wrote:
> > Ben reported that distro GRUB may fail to boot in some circumstances,
> > and tracked it down to an issue in the way distro GRUB allocates space
> > for the image. Due to an oversight (addressed in patch #2), this
> > condition is rarely triggered, but let's work around it in any case (#1)
> >
> > Remaining patches add further warnings for conditions that are unlikely
> > to occur, but should not be ignored.
> >
> > Build tested only.
> >
> > Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
>
> All 4 patches:
>
> Tested-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
>
> I checked that it catches all of the errors, including reverting my fix
> for randomalloc.c and verifying that it caught (and successfully worked
> around) the original boot  crash.
>

Excellent. Thanks for tracking this down and getting it fixed properly.


From leo.yan at linaro.org  Mon Aug  2 05:05:45 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 2 Aug 2021 20:05:45 +0800
Subject: [PATCH 3/6] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <CAJ9a7Vj_KhV+v6VU+EQN5t818VS9jvf3v3-2JbwVMOHZbi3gcg@mail.gmail.com>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-4-james.clark@arm.com>
 <20210731074343.GG7437@leoy-ThinkPad-X240s>
 <CAJ9a7Vj_KhV+v6VU+EQN5t818VS9jvf3v3-2JbwVMOHZbi3gcg@mail.gmail.com>
Message-ID: <20210802120545.GJ7437@leoy-ThinkPad-X240s>

Hi Mike,

On Mon, Aug 02, 2021 at 12:21:31PM +0100, Mike Leach wrote:

[...]

> > Here I think the right thing to do is to support newer revisions for
> > ETMv4, and then based on the revision it creates a decoder with
> > supporting ETE feature.  For a more neat solution, if the perf tool
> > passes the "correct" revision number to the OpenCSD decoder, it should
> > can decode trace data with ETE packets.  In this way, the ETE decoding
> > can be transparent for perf cs-etm code.
> >
> 
> The OpenCSD decoder separates the ETMv4 decoder from the ETE decoder -
> for the reasons given above.

Thanks for explanation.

> Additionally the ETE decoder and the ETMv4 decoder required different
> sets of ID registers to correctly set up the decoder.  For example,
> for ETMv4 the version is extracted form TRCIDR1, for ETE the version
> in TRCIDR1 is set 0xFF, and thus needs TRCDEVARCH to extract the
> revision. It is likely that later updates to ETE will require an
> additional TRCIDR register to be saved.

Okay, for ETMv4.x and ETE, finally I think we need to rely on TRCDEVARCH to
decide the tracer version based on the architecture number (arch 4 or 5)
and revision number.

> Choosing the base type of decoder in this way is how the library can
> support ETMv3, EMTv4, ETE, STM, PTM etc - and while some of those
> protocols use TRCIDR1 and TRCDEVARCH - not all do.
> 
> It would in theory be possible to have the OpenCSD library
> "autodetect" the type of decoder needed based purely on a set of ID
> registers. But this set of ID registers would be far larger than the
> ones currently used, and would require modifcation to a lot of the
> existing device drivers to ensure they were accessible via sysfs. This
> register set includes the ID registers that are currently used to
> identify the component on the AMBA bus and match to the correct
> driver, plus additional CoreSight management registers. This would
> also create a dependency between decoder creation and ID numbers - in
> the same way that each new ETM4.x part number has to be added to the
> ETM4.x device driver.
> 
> Such a system would require a significant update to the OpenCSD
> infrastructure, and is not planned at this time.

It's fine for me not introducing significant change in OpenCSD.

If so, I understand your suggestion in another email to add a new magic
number and a new protocol (this patch set has added the new protocol
CS_ETM_PROTO_ETE) for creating ETE decoder.

Just confirm one thing which is a bit confused me: for ETMv4.5 or any
newer ETM IPs, should the perf tool keep the existed way to create the
ETMv4 decoder?  Or there have updating is required for decoder to
support the extended packets?

Thanks,
Leo


From tangbin at cmss.chinamobile.com  Mon Aug  2 05:09:29 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Mon,  2 Aug 2021 20:09:29 +0800
Subject: [PATCH v2] iio: adc: fsl-imx25-gcq: fix the right check and simplify
 code
Message-ID: <20210802120929.33760-1-tangbin@cmss.chinamobile.com>

For the function of platform_get_irq(), the example in platform.c is
 *	int irq = platform_get_irq(pdev, 0);
 *	if (irq < 0)
 *		return irq;
the return value of zero is unnecessary to check, so make the right
check and simplify code.

Co-developed-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
Changes from v1
 - change the code to the original place and make it simple.
 - change the commit message.
---
 drivers/iio/adc/fsl-imx25-gcq.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
index 8cb51cf7a..2cdf45aa8 100644
--- a/drivers/iio/adc/fsl-imx25-gcq.c
+++ b/drivers/iio/adc/fsl-imx25-gcq.c
@@ -336,14 +336,11 @@ static int mx25_gcq_probe(struct platform_device *pdev)
 		goto err_vref_disable;
 	}
 
-	priv->irq = platform_get_irq(pdev, 0);
-	if (priv->irq <= 0) {
-		ret = priv->irq;
-		if (!ret)
-			ret = -ENXIO;
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
 		goto err_clk_unprepare;
-	}
 
+	priv->irq = ret;
 	ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv);
 	if (ret) {
 		dev_err(dev, "Failed requesting IRQ\n");
-- 
2.20.1.windows.1





From eizan at chromium.org  Mon Aug  2 05:12:06 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:06 +1000
Subject: [PATCH v6 0/9] Refactor MTK MDP driver into core/components
Message-ID: <20210802121215.703023-1-eizan@chromium.org>


This is an update to
https://patchwork.kernel.org/project/linux-mediatek/list/?series=283075
To address some comments and fixes.

This series has been verified to work on 5.13.


Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

Eizan Miyamoto (9):
  mtk-mdp: propagate errors from clock_on
  mtk-mdp: add driver to probe mdp components
  mtk-mdp: use pm_runtime in MDP component driver
  media: mtk-mdp: don't pm_run_time_get/put for master comp in clock_on
  mtk-mdp: make mdp driver to be loadable by platform_device_register*()
  soc: mediatek: mmsys: instantiate mdp virtual device from mmsys
  media: mtk-mdp: use mdp-rdma0 alias to point to MDP master
  dts: mtk-mdp: remove mediatek,vpu property from primary MDP device
  dt-bindings: mediatek: remove vpu requirement from mtk-mdp

 .../bindings/media/mediatek-mdp.txt           |   3 -
 arch/arm64/boot/dts/mediatek/mt8173.dtsi      |   1 -
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 268 +++++++++++++++--
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  34 +--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 282 ++++++++++++------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   3 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |   4 +-
 drivers/soc/mediatek/mtk-mmsys.c              |  20 +-
 8 files changed, 470 insertions(+), 145 deletions(-)

-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:07 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:07 +1000
Subject: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>

Up until this change, many errors were logged but ignored when powering
on clocks inside mtk_mdp_core. This change tries to do a better job at
propagating errors back to the power management framework.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 25 ++++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 27 ++++++++++++++-----
 3 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index b3426a551bea..76e295c8d9bc 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -13,10 +13,9 @@
 
 #include "mtk_mdp_comp.h"
 
-
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
-	int i, err;
+	int i, err, status;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
@@ -30,11 +29,23 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		if (IS_ERR(comp->clk[i]))
 			continue;
 		err = clk_prepare_enable(comp->clk[i]);
-		if (err)
-			dev_err(dev,
-			"failed to enable clock, err %d. type:%d i:%d\n",
-				err, comp->type, i);
+		if (err) {
+			status = err;
+			dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+			goto err_clk_prepare_enable;
+		}
+	}
+
+	return 0;
+
+err_clk_prepare_enable:
+	for (--i; i >= 0; i--) {
+		if (IS_ERR(comp->clk[i]))
+			continue;
+		clk_disable_unprepare(comp->clk[i]);
 	}
+
+	return status;
 }
 
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 7897766c96bb..92ab5249bcad 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -41,7 +41,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		      struct mtk_mdp_comp *comp,
 		      enum mtk_mdp_comp_type comp_type);
 void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
 
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 976aa1f4829b..412bbec0f735 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -52,13 +52,28 @@ static const struct of_device_id mtk_mdp_of_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids);
 
-static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 {
-	struct device *dev = &mdp->pdev->dev;
 	struct mtk_mdp_comp *comp_node;
+	int status;
+	struct device *dev = &mdp->pdev->dev;
+	int err;
 
-	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_on(dev, comp_node);
+	list_for_each_entry(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_clock_on(dev, comp_node);
+		if (err) {
+			status = err;
+			goto err_mtk_mdp_comp_clock_on;
+		}
+	}
+
+	return 0;
+
+err_mtk_mdp_comp_clock_on:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
+		mtk_mdp_comp_clock_off(dev, comp_node);
+
+	return status;
 }
 
 static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
@@ -274,9 +289,7 @@ static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
 {
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_clock_on(mdp);
-
-	return 0;
+	return mtk_mdp_clock_on(mdp);
 }
 
 static int __maybe_unused mtk_mdp_suspend(struct device *dev)
-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:08 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:08 +1000
Subject: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>

Broadly, this patch (1) adds a driver for various MTK MDP components to
go alongside the main MTK MDP driver, and (2) hooks them all together
using the component framework.

(1) Up until now, the MTK MDP driver controls 8 devices in the device
tree on its own. When running tests for the hardware video decoder, we
found that the iommus and LARBs were not being properly configured. To
configure them, a driver for each be added to mtk_mdp_comp so that
mtk_iommu_add_device() can (eventually) be called from dma_configure()
inside really_probe().

(2) The integration into the component framework allows us to defer the
registration with the v4l2 subsystem until all the MDP-related devices
have been probed, so that the relevant device node does not become
available until initialization of all the components is complete.

Some notes about how the component framework has been integrated:

- The driver for the rdma0 component serves double duty as the "master"
  (aggregate) driver as well as a component driver. This is a non-ideal
  compromise until a better solution is developed. This device is
  differentiated from the rest by checking for a "mediatek,vpu" property
  in the device node.

- The list of mdp components remains hard-coded as mtk_mdp_comp_dt_ids[]
  in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
  mtk_mdp_comp.c. This unfortunate duplication of information is
  addressed in a following patch in this series.

- The component driver calls component_add() for each device that is
  probed.

- In mtk_mdp_probe (the "master" device), we scan the device tree for
  any matching nodes against mtk_mdp_comp_dt_ids, and add component
  matches for them. The match criteria is a matching device node
  pointer.

- When the set of components devices that have been probed corresponds
  with the list that is generated by the "master", the callback to
  mtk_mdp_master_bind() is made, which then calls the component bind
  functions.

- Inside mtk_mdp_master_bind(), once all the component bind functions
  have been called, we can then register our device to the v4l2
  subsystem.

- The call to pm_runtime_enable() in the master device is called after
  all the components have been registered by their bind() functions
  called by mtk_mtp_master_bind(). As a result, the list of components
  will not change while power management callbacks mtk_mdp_suspend()/
  resume() are accessing the list of components.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 143 ++++++++++++--
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  25 +--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 174 +++++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   1 +
 4 files changed, 252 insertions(+), 91 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 76e295c8d9bc..7a0e3acffab9 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -5,13 +5,50 @@
  */
 
 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/of.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <soc/mediatek/smi.h>
 
 #include "mtk_mdp_comp.h"
+#include "mtk_mdp_core.h"
+
+/**
+ * enum mtk_mdp_comp_type - the MDP component
+ * @MTK_MDP_RDMA:		Read DMA
+ * @MTK_MDP_RSZ:		Reszer
+ * @MTK_MDP_WDMA:		Write DMA
+ * @MTK_MDP_WROT:		Write DMA with rotation
+ * @MTK_MDP_COMP_TYPE_MAX:	Placeholder for num elems in this enum
+ */
+enum mtk_mdp_comp_type {
+	MTK_MDP_RDMA,
+	MTK_MDP_RSZ,
+	MTK_MDP_WDMA,
+	MTK_MDP_WROT,
+	MTK_MDP_COMP_TYPE_MAX,
+};
+
+static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
+	{
+		.compatible = "mediatek,mt8173-mdp-rdma",
+		.data = (void *)MTK_MDP_RDMA
+	}, {
+		.compatible = "mediatek,mt8173-mdp-rsz",
+		.data = (void *)MTK_MDP_RSZ
+	}, {
+		.compatible = "mediatek,mt8173-mdp-wdma",
+		.data = (void *)MTK_MDP_WDMA
+	}, {
+		.compatible = "mediatek,mt8173-mdp-wrot",
+		.data = (void *)MTK_MDP_WROT
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
 int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
@@ -20,9 +57,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
 		if (err)
-			dev_err(dev,
-				"failed to get larb, err %d. type:%d\n",
-				err, comp->type);
+			dev_err(dev, "failed to get larb, err %d.\n", err);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -62,17 +97,41 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
 		mtk_smi_larb_put(comp->larb_dev);
 }
 
-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-		      struct mtk_mdp_comp *comp,
-		      enum mtk_mdp_comp_type comp_type)
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+{
+	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+	struct mtk_mdp_dev *mdp = data;
+
+	mtk_mdp_register_component(mdp, comp);
+
+	return 0;
+}
+
+static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+	struct mtk_mdp_dev *mdp = data;
+
+	mtk_mdp_unregister_component(mdp, comp);
+}
+
+static const struct component_ops mtk_mdp_component_ops = {
+	.bind   = mtk_mdp_comp_bind,
+	.unbind = mtk_mdp_comp_unbind,
+};
+
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 {
 	struct device_node *larb_node;
 	struct platform_device *larb_pdev;
 	int ret;
 	int i;
+	struct device_node *node = dev->of_node;
+	enum mtk_mdp_comp_type comp_type =
+		 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
 
-	comp->dev_node = of_node_get(node);
-	comp->type = comp_type;
+	INIT_LIST_HEAD(&comp->node);
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		comp->clk[i] = of_clk_get(node, i);
@@ -80,19 +139,17 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 			if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
 				dev_err(dev, "Failed to get clock\n");
 			ret = PTR_ERR(comp->clk[i]);
-			goto put_dev;
+			goto err;
 		}
 
 		/* Only RDMA needs two clocks */
-		if (comp->type != MTK_MDP_RDMA)
+		if (comp_type != MTK_MDP_RDMA)
 			break;
 	}
 
 	/* Only DMA capable components need the LARB property */
 	comp->larb_dev = NULL;
-	if (comp->type != MTK_MDP_RDMA &&
-	    comp->type != MTK_MDP_WDMA &&
-	    comp->type != MTK_MDP_WROT)
+	if (comp_type != MTK_MDP_RDMA && comp_type != MTK_MDP_WDMA && comp_type != MTK_MDP_WROT)
 		return 0;
 
 	larb_node = of_parse_phandle(node, "mediatek,larb", 0);
@@ -100,7 +157,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		dev_err(dev,
 			"Missing mediadek,larb phandle in %pOF node\n", node);
 		ret = -EINVAL;
-		goto put_dev;
+		goto err;
 	}
 
 	larb_pdev = of_find_device_by_node(larb_node);
@@ -108,7 +165,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
 		of_node_put(larb_node);
 		ret = -EPROBE_DEFER;
-		goto put_dev;
+		goto err;
 	}
 	of_node_put(larb_node);
 
@@ -116,13 +173,59 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 
 	return 0;
 
-put_dev:
-	of_node_put(comp->dev_node);
-
+err:
 	return ret;
 }
 
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
+static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
-	of_node_put(comp->dev_node);
+	struct device *dev = &pdev->dev;
+	struct device_node *vpu_node;
+	int status;
+	struct mtk_mdp_comp *comp;
+
+	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+	if (vpu_node) {
+		of_node_put(vpu_node);
+		/*
+		 * The device tree node with a mediatek,vpu property is deemed
+		 * the MDP "master" device, we don't want to add a component
+		 * for it in this function because the initialization for the
+		 * master is done elsewhere.
+		 */
+		dev_info(dev, "vpu node found, not probing\n");
+		return -ENODEV;
+	}
+
+	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+	if (!comp)
+		return -ENOMEM;
+
+	status = mtk_mdp_comp_init(comp, dev);
+	if (status) {
+		dev_err(dev, "Failed to initialize component: %d\n", status);
+		return status;
+	}
+
+	dev_set_drvdata(dev, comp);
+
+	return component_add(dev, &mtk_mdp_component_ops);
 }
+
+static int mtk_mdp_comp_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	component_del(dev, &mtk_mdp_component_ops);
+	return 0;
+}
+
+struct platform_driver mtk_mdp_component_driver = {
+	.probe          = mtk_mdp_comp_probe,
+	.remove         = mtk_mdp_comp_remove,
+	.driver         = {
+		.name   = "mediatek-mdp-comp",
+		.owner  = THIS_MODULE,
+		.of_match_table = mtk_mdp_comp_driver_dt_match,
+	},
+};
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 92ab5249bcad..df5fc4c94f90 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -7,42 +7,23 @@
 #ifndef __MTK_MDP_COMP_H__
 #define __MTK_MDP_COMP_H__
 
-/**
- * enum mtk_mdp_comp_type - the MDP component
- * @MTK_MDP_RDMA:	Read DMA
- * @MTK_MDP_RSZ:	Riszer
- * @MTK_MDP_WDMA:	Write DMA
- * @MTK_MDP_WROT:	Write DMA with rotation
- */
-enum mtk_mdp_comp_type {
-	MTK_MDP_RDMA,
-	MTK_MDP_RSZ,
-	MTK_MDP_WDMA,
-	MTK_MDP_WROT,
-};
-
 /**
  * struct mtk_mdp_comp - the MDP's function component data
  * @node:	list node to track sibing MDP components
- * @dev_node:	component device node
  * @clk:	clocks required for component
  * @larb_dev:	SMI device required for component
- * @type:	component type
  */
 struct mtk_mdp_comp {
 	struct list_head	node;
-	struct device_node	*dev_node;
 	struct clk		*clk[2];
 	struct device		*larb_dev;
-	enum mtk_mdp_comp_type	type;
 };
 
-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-		      struct mtk_mdp_comp *comp,
-		      enum mtk_mdp_comp_type comp_type);
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
+
 int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
 
+extern struct platform_driver mtk_mdp_component_driver;
 
 #endif /* __MTK_MDP_COMP_H__ */
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 412bbec0f735..b813a822439a 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
@@ -19,6 +20,7 @@
 #include <linux/workqueue.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_mdp_comp.h"
 #include "mtk_mdp_core.h"
 #include "mtk_mdp_m2m.h"
 #include "mtk_vpu.h"
@@ -32,16 +34,12 @@ module_param(mtk_mdp_dbg_level, int, 0644);
 static const struct of_device_id mtk_mdp_comp_dt_ids[] = {
 	{
 		.compatible = "mediatek,mt8173-mdp-rdma",
-		.data = (void *)MTK_MDP_RDMA
 	}, {
 		.compatible = "mediatek,mt8173-mdp-rsz",
-		.data = (void *)MTK_MDP_RSZ
 	}, {
 		.compatible = "mediatek,mt8173-mdp-wdma",
-		.data = (void *)MTK_MDP_WDMA
 	}, {
 		.compatible = "mediatek,mt8173-mdp-wrot",
-		.data = (void *)MTK_MDP_WROT
 	},
 	{ },
 };
@@ -106,6 +104,63 @@ static void mtk_mdp_reset_handler(void *priv)
 	queue_work(mdp->wdt_wq, &mdp->wdt_work);
 }
 
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static void release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
+static int mtk_mdp_master_bind(struct device *dev)
+{
+	int status;
+	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+	mtk_mdp_register_component(mdp, &mdp->comp_self);
+
+	status = component_bind_all(dev, mdp);
+	if (status) {
+		dev_err(dev, "Failed to bind all components: %d\n", status);
+		goto err_component_bind_all;
+	}
+
+	status = mtk_mdp_register_m2m_device(mdp);
+	if (status) {
+		dev_err(dev, "Failed to register m2m device: %d\n", status);
+		goto err_mtk_mdp_register_m2m_device;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+
+err_mtk_mdp_register_m2m_device:
+	component_unbind_all(dev, mdp);
+
+err_component_bind_all:
+	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+
+	return status;
+}
+
+static void mtk_mdp_master_unbind(struct device *dev)
+{
+	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+	pm_runtime_disable(dev);
+	mtk_mdp_unregister_m2m_device(mdp);
+	component_unbind_all(dev, mdp);
+	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+}
+
+static const struct component_master_ops mtk_mdp_com_ops = {
+	.bind		= mtk_mdp_master_bind,
+	.unbind		= mtk_mdp_master_unbind,
+};
+
 void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
 				struct mtk_mdp_comp *comp)
 {
@@ -123,8 +178,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	struct mtk_mdp_dev *mdp;
 	struct device *dev = &pdev->dev;
 	struct device_node *node, *parent;
-	struct mtk_mdp_comp *comp, *comp_temp;
-	int ret = 0;
+	int i, ret = 0;
+	struct component_match *match = NULL;
 
 	mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
 	if (!mdp)
@@ -149,36 +204,43 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	}
 
 	/* Iterate over sibling MDP function blocks */
+	i = 0;
 	for_each_child_of_node(parent, node) {
-		const struct of_device_id *of_id;
-		enum mtk_mdp_comp_type comp_type;
+		struct platform_device *pdev;
 
-		of_id = of_match_node(mtk_mdp_comp_dt_ids, node);
-		if (!of_id)
+		if (!of_match_node(mtk_mdp_comp_dt_ids, node))
 			continue;
 
-		if (!of_device_is_available(node)) {
-			dev_err(dev, "Skipping disabled component %pOF\n",
-				node);
+		if (!of_device_is_available(node))
 			continue;
-		}
-
-		comp_type = (enum mtk_mdp_comp_type)of_id->data;
 
-		comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
-		if (!comp) {
-			ret = -ENOMEM;
-			of_node_put(node);
-			goto err_comp;
+		pdev = of_find_device_by_node(node);
+		if (!pdev) {
+			dev_warn(dev, "Unable to find comp device %s\n",
+				 node->full_name);
+			continue;
 		}
 
-		ret = mtk_mdp_comp_init(dev, node, comp, comp_type);
-		if (ret) {
-			of_node_put(node);
-			goto err_comp;
+		/*
+		 * Do not add a match for my own (rdma0) device node.
+		 * I will be managing it directly instead using comp_self.
+		 */
+		if (&pdev->dev != dev) {
+			dev_dbg(dev, "adding match %d for: %pOF\n", i++, node);
+			component_match_add_release(dev, &match, release_of,
+						    compare_of,
+						    of_node_get(node));
 		}
+	}
 
-		mtk_mdp_register_component(mdp, comp);
+	/*
+	 * Create a component for myself so that clocks can be toggled in
+	 * clock_on().
+	 */
+	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
+	if (ret) {
+		dev_err(dev, "Failed to initialize component\n");
+		goto err_comp;
 	}
 
 	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
@@ -203,18 +265,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		goto err_dev_register;
 	}
 
-	ret = mtk_mdp_register_m2m_device(mdp);
-	if (ret) {
-		v4l2_err(&mdp->v4l2_dev, "Failed to init mem2mem device\n");
-		goto err_m2m_register;
-	}
-
 	mdp->vpu_dev = vpu_get_plat_device(pdev);
 	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
 				  VPU_RST_MDP);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register reset handler\n");
-		goto err_m2m_register;
+		goto err_wdt_reg;
 	}
 
 	platform_set_drvdata(pdev, mdp);
@@ -222,15 +278,25 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-		goto err_m2m_register;
+		goto err_set_max_seg_size;
+	}
+
+	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
+	if (ret) {
+		dev_err(dev, "Component master add failed\n");
+		goto err_component_master_add;
 	}
 
-	pm_runtime_enable(dev);
 	dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);
 
 	return 0;
 
-err_m2m_register:
+err_component_master_add:
+	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
+
+err_set_max_seg_size:
+
+err_wdt_reg:
 	v4l2_device_unregister(&mdp->v4l2_dev);
 
 err_dev_register:
@@ -242,11 +308,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 err_alloc_job_wq:
 
 err_comp:
-	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-		mtk_mdp_unregister_component(mdp, comp);
-		mtk_mdp_comp_deinit(dev, comp);
-	}
-
 	dev_dbg(dev, "err %d\n", ret);
 	return ret;
 }
@@ -254,11 +315,10 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 static int mtk_mdp_remove(struct platform_device *pdev)
 {
 	struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
-	struct mtk_mdp_comp *comp, *comp_temp;
 
-	pm_runtime_disable(&pdev->dev);
+	component_master_del(&pdev->dev, &mtk_mdp_com_ops);
+
 	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-	mtk_mdp_unregister_m2m_device(mdp);
 	v4l2_device_unregister(&mdp->v4l2_dev);
 
 	flush_workqueue(mdp->wdt_wq);
@@ -267,10 +327,8 @@ static int mtk_mdp_remove(struct platform_device *pdev)
 	flush_workqueue(mdp->job_wq);
 	destroy_workqueue(mdp->job_wq);
 
-	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-		mtk_mdp_unregister_component(mdp, comp);
-		mtk_mdp_comp_deinit(&pdev->dev, comp);
-	}
+	if (!list_empty(&mdp->comp_list))
+		dev_warn(&pdev->dev, "not all components removed\n");
 
 	dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
 	return 0;
@@ -323,7 +381,25 @@ static struct platform_driver mtk_mdp_driver = {
 	}
 };
 
-module_platform_driver(mtk_mdp_driver);
+static struct platform_driver * const mtk_mdp_drivers[] = {
+	&mtk_mdp_driver,
+	&mtk_mdp_component_driver,
+};
+
+static int __init mtk_mdp_init(void)
+{
+	return platform_register_drivers(mtk_mdp_drivers,
+					 ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+static void __exit mtk_mdp_exit(void)
+{
+	platform_unregister_drivers(mtk_mdp_drivers,
+				    ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+module_init(mtk_mdp_init);
+module_exit(mtk_mdp_exit);
 
 MODULE_AUTHOR("Houlong Wei <houlong.wei at mediatek.com>");
 MODULE_DESCRIPTION("Mediatek image processor driver");
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index a6e6dc36307b..8a52539b15d4 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -155,6 +155,7 @@ struct mtk_mdp_dev {
 	struct mtk_mdp_variant		*variant;
 	u16				id;
 	struct list_head		comp_list;
+	struct mtk_mdp_comp		comp_self;
 	struct v4l2_m2m_dev		*m2m_dev;
 	struct list_head		ctx_list;
 	struct video_device		*vdev;
-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:09 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:09 +1000
Subject: [PATCH v6 3/9] mtk-mdp: use pm_runtime in MDP component driver
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.3.I909f5375d930f5d0cc877128e30e2a67078b674c@changeid>

Without this change, the MDP components are not fully integrated into
the runtime power management subsystem, and the MDP driver does not
work.

For each of the component device drivers to be able to call
pm_runtime_get/put_sync() a pointer to the component's device struct
had to be added to struct mtk_mdp_comp, set by mtk_mdp_comp_init().

Note that the dev argument to mtk_mdp_comp_clock_on/off() has been
removed. Those functions used to be called from the "master" mdp driver
in mtk_mdp_core.c, but the component's device pointer no longer
corresponds to the mdp master device pointer, which is not the right
device to pass to pm_runtime_put/get_sync() which we had to add to get
the driver to work properly.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 24 +++++++++++++++----
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  6 +++--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  7 +++---
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7a0e3acffab9..472c261b01e8 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -12,6 +12,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <soc/mediatek/smi.h>
+#include <linux/pm_runtime.h>
 
 #include "mtk_mdp_comp.h"
 #include "mtk_mdp_core.h"
@@ -50,14 +51,22 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
-int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 {
 	int i, err, status;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
 		if (err)
-			dev_err(dev, "failed to get larb, err %d.\n", err);
+			dev_err(comp->dev, "failed to get larb, err %d.\n", err);
+	}
+
+	err = pm_runtime_get_sync(comp->dev);
+	if (err < 0) {
+		dev_err(comp->dev,
+			"failed to runtime get, err %d.\n",
+			err);
+		return err;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -66,7 +75,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		err = clk_prepare_enable(comp->clk[i]);
 		if (err) {
 			status = err;
-			dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+			dev_err(comp->dev, "failed to enable clock, err %d. i:%d\n", err, i);
 			goto err_clk_prepare_enable;
 		}
 	}
@@ -80,10 +89,12 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		clk_disable_unprepare(comp->clk[i]);
 	}
 
+	pm_runtime_put_sync(comp->dev);
+
 	return status;
 }
 
-void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 {
 	int i;
 
@@ -95,6 +106,8 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
 
 	if (comp->larb_dev)
 		mtk_smi_larb_put(comp->larb_dev);
+
+	return pm_runtime_put_sync(comp->dev);
 }
 
 static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
@@ -103,6 +116,7 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 	struct mtk_mdp_dev *mdp = data;
 
 	mtk_mdp_register_component(mdp, comp);
+	pm_runtime_enable(dev);
 
 	return 0;
 }
@@ -113,6 +127,7 @@ static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
 
+	pm_runtime_disable(dev);
 	mtk_mdp_unregister_component(mdp, comp);
 }
 
@@ -132,6 +147,7 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 		 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
 
 	INIT_LIST_HEAD(&comp->node);
+	comp->dev = dev;
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		comp->clk[i] = of_clk_get(node, i);
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index df5fc4c94f90..f2e22e7e7c45 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -12,17 +12,19 @@
  * @node:	list node to track sibing MDP components
  * @clk:	clocks required for component
  * @larb_dev:	SMI device required for component
+ * @dev:	component's device
  */
 struct mtk_mdp_comp {
 	struct list_head	node;
 	struct clk		*clk[2];
+	struct device		*dev;
 	struct device		*larb_dev;
 };
 
 int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
 
-int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
 
 extern struct platform_driver mtk_mdp_component_driver;
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index b813a822439a..714154450981 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -58,7 +58,7 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 	int err;
 
 	list_for_each_entry(comp_node, &mdp->comp_list, node) {
-		err = mtk_mdp_comp_clock_on(dev, comp_node);
+		err = mtk_mdp_comp_clock_on(comp_node);
 		if (err) {
 			status = err;
 			goto err_mtk_mdp_comp_clock_on;
@@ -69,18 +69,17 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 
 err_mtk_mdp_comp_clock_on:
 	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(dev, comp_node);
+		mtk_mdp_comp_clock_off(comp_node);
 
 	return status;
 }
 
 static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
 {
-	struct device *dev = &mdp->pdev->dev;
 	struct mtk_mdp_comp *comp_node;
 
 	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(dev, comp_node);
+		mtk_mdp_comp_clock_off(comp_node);
 }
 
 static void mtk_mdp_wdt_worker(struct work_struct *work)
-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:10 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:10 +1000
Subject: [PATCH v6 4/9] media: mtk-mdp: don't pm_run_time_get/put for master
 comp in clock_on
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.4.Ifd87681955689a08cce4c65e72ee5e8c6d09af95@changeid>

The original intent of commit 86698b9505bbc ("media: mtk-mdp: convert
mtk_mdp_dev.comp array to list") was to create a list to track all the
MDP components that needed to have their clocks enabled/disabled when
calling mtk_mdp_comp_clock_on/off. However, there was a bug inside
mtk_mdp_register_component where the args to a call to list_add were
swapped. The result is that only one component was added to
mtk_mdp_dev.comp_list because comp_list was instead being
repeatedly added to the single element lists headed by each
mtk_mdp_comp.

The order of the args to list_add in mtk_mdp_register_component was
fixed in https://patchwork.kernel.org/patch/11742895/ (Fix Null pointer
dereference when calling list_add).

Then, as a result of https://patchwork.kernel.org/patch/11530769/
(mtk-mdp: use pm_runtime in MDP component driver) if all the components
are added to the component list, the mdp "master" / rdma0 component
ends up having pm_runtime_get_sync() called on it twice recursively:

    rpm_resume+0x694/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_comp_clock_on+0x48/0x104 [mtk_mdp]
    mtk_mdp_pm_resume+0x2c/0x44 [mtk_mdp]
    pm_generic_runtime_resume+0x34/0x48
    __genpd_runtime_resume+0x6c/0x80
    genpd_runtime_resume+0x104/0x1ac
    __rpm_callback+0x120/0x238
    rpm_callback+0x34/0x8c
    rpm_resume+0x7a0/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_m2m_start_streaming+0x2c/0x3c [mtk_mdp]

(The calls to pm_runtime_get_sync are inlined and correspond to the
calls to __pm_runtime_resume). It is not correct to have
pm_runtime_get_sync called recursively and the second call will block
indefinitely.

As a result of all that, this change factors mtk_mdp_comp_clock_on/off
into mtk_mdp_comp_power_on/off and moves the calls to
pm_runtime_get/put into the power_on/off functions.

This change then special-cases the master/rdma0 MDP component and does
these things:
- the master/rdma0 component is not added to mtk_mdp_dev.comp_list
- the master/rdma0 component has its clocks (*but not power*) toggled
  by mtk_mpd_comp_clock_on/off inside mtk_mdp_clock_on/off.
- the other components have their clocks *and* power toggled with
  mtk_mdp_comp_power_on/off.

This change introduces the assumption that mtk_mdp_pm_resume will
always be called though a callback from pm_runtime_get_sync made on the
master / rdma0 component.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 57 ++++++++++++++---
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  5 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++++++++++-----
 3 files changed, 98 insertions(+), 26 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 472c261b01e8..7b6c8a3f3455 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -51,9 +51,9 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
-int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp)
 {
-	int i, err, status;
+	int status, err;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
@@ -63,12 +63,54 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 
 	err = pm_runtime_get_sync(comp->dev);
 	if (err < 0) {
-		dev_err(comp->dev,
-			"failed to runtime get, err %d.\n",
-			err);
+		dev_err(comp->dev, "failed to runtime get, err %d.\n", err);
 		return err;
 	}
 
+	err = mtk_mdp_comp_clock_on(comp);
+	if (err) {
+		dev_err(comp->dev, "failed to turn on clock. err=%d", err);
+		status = err;
+		goto err_mtk_mdp_comp_clock_on;
+	}
+
+	return 0;
+
+err_mtk_mdp_comp_clock_on:
+	err = pm_runtime_put_sync(comp->dev);
+	if (err)
+		dev_err(comp->dev, "failed to runtime put in cleanup. err=%d", err);
+
+	return status;
+}
+
+int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp)
+{
+	int status, err;
+
+	mtk_mdp_comp_clock_off(comp);
+
+	err = pm_runtime_put_sync(comp->dev);
+	if (err < 0) {
+		dev_err(comp->dev, "failed to runtime put, err %d.\n", err);
+		status = err;
+		goto err_pm_runtime_put_sync;
+	}
+
+	return 0;
+
+err_pm_runtime_put_sync:
+	err = mtk_mdp_comp_clock_on(comp);
+	if (err)
+		dev_err(comp->dev, "failed to turn on clock in cleanup. err=%d", err);
+
+	return status;
+}
+
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
+{
+	int i, err, status;
+
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		if (IS_ERR(comp->clk[i]))
 			continue;
@@ -94,7 +136,8 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 	return status;
 }
 
-int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
+
+void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 {
 	int i;
 
@@ -106,8 +149,6 @@ int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 
 	if (comp->larb_dev)
 		mtk_smi_larb_put(comp->larb_dev);
-
-	return pm_runtime_put_sync(comp->dev);
 }
 
 static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index f2e22e7e7c45..e3d6aef52869 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -23,8 +23,11 @@ struct mtk_mdp_comp {
 
 int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
 
+int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp);
+
 int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
-int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
+void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
 
 extern struct platform_driver mtk_mdp_component_driver;
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 714154450981..a72a9ba41ea6 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -57,29 +57,64 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 	struct device *dev = &mdp->pdev->dev;
 	int err;
 
+	/*
+	 * The master / rdma0 component will have pm_runtime_get_sync called
+	 * on it through mtk_mdp_m2m_start_streaming, making it unnecessary to
+	 * have mtk_mdp_comp_power_on called on it.
+	 */
+	err = mtk_mdp_comp_clock_on(&mdp->comp_self);
+	if (err)
+		return err;
+
 	list_for_each_entry(comp_node, &mdp->comp_list, node) {
-		err = mtk_mdp_comp_clock_on(comp_node);
+		err = mtk_mdp_comp_power_on(comp_node);
 		if (err) {
 			status = err;
-			goto err_mtk_mdp_comp_clock_on;
+			goto err_mtk_mdp_comp_power_on;
 		}
 	}
 
 	return 0;
 
-err_mtk_mdp_comp_clock_on:
-	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(comp_node);
-
+err_mtk_mdp_comp_power_on:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_off(comp_node);
+		if (err)
+			dev_err(&mdp->pdev->dev, "failed to power off after error. err=%d", err);
+	}
 	return status;
 }
 
-static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
 {
 	struct mtk_mdp_comp *comp_node;
+	int status, err;
+
+	list_for_each_entry(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_off(comp_node);
+		if (err) {
+			status = err;
+			goto err_mtk_mdp_comp_power_off;
+		}
+	}
 
-	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(comp_node);
+	/*
+	 * The master / rdma0 component will have pm_runtime_put called
+	 * on it through mtk_mdp_m2m_stop_streaming, making it unnecessary to
+	 * have mtk_mdp_comp_power_off called on it.
+	 */
+	mtk_mdp_comp_clock_off(&mdp->comp_self);
+
+	return 0;
+
+err_mtk_mdp_comp_power_off:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_on(comp_node);
+		if (err)
+			dev_err(&mdp->pdev->dev, "failed to power on after error. err=%d", err);
+	}
+
+	return status;
 }
 
 static void mtk_mdp_wdt_worker(struct work_struct *work)
@@ -118,8 +153,6 @@ static int mtk_mdp_master_bind(struct device *dev)
 	int status;
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_register_component(mdp, &mdp->comp_self);
-
 	status = component_bind_all(dev, mdp);
 	if (status) {
 		dev_err(dev, "Failed to bind all components: %d\n", status);
@@ -140,8 +173,6 @@ static int mtk_mdp_master_bind(struct device *dev)
 	component_unbind_all(dev, mdp);
 
 err_component_bind_all:
-	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
-
 	return status;
 }
 
@@ -152,7 +183,6 @@ static void mtk_mdp_master_unbind(struct device *dev)
 	pm_runtime_disable(dev);
 	mtk_mdp_unregister_m2m_device(mdp);
 	component_unbind_all(dev, mdp);
-	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
 }
 
 static const struct component_master_ops mtk_mdp_com_ops = {
@@ -337,9 +367,7 @@ static int __maybe_unused mtk_mdp_pm_suspend(struct device *dev)
 {
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_clock_off(mdp);
-
-	return 0;
+	return mtk_mdp_clock_off(mdp);
 }
 
 static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:11 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:11 +1000
Subject: [PATCH v6 5/9] mtk-mdp: make mdp driver to be loadable by
 platform_device_register*()
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>

Rather than hanging the MDP master component driver off of the rdma0
device, make it possible too create a "virtual" device by registering
it with platform_device_register_*() to be probed by the mtk_mdp_core
driver.

Broadly, three interdependent things are done by this change:
- Make it is possible to search for MDP devices in the device tree
  through the grandparent device's of_node.
- v4l-related setup is moved into from the mtk_mdp_core driver to the
  mtk_mdp_comp driver.
- Presence of a mediatek,vpu property in an MDP component device node
  is used to determine what device to use when dispatching DMA ops from
  the relevant ioctl, and also do V4L2 initialization in this case.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 51 ++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++-------------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |  2 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
 4 files changed, 60 insertions(+), 59 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7b6c8a3f3455..85ef274841a3 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -155,8 +155,45 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
+	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
+
+	/*
+	 * If this component has a "mediatek-vpu" property, it is responsible for
+	 * notifying the mdp master driver about it so it can be further initialized
+	 * later.
+	 */
+	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+	if (vpu_node) {
+		int ret;
+
+		mdp->vpu_dev = of_find_device_by_node(vpu_node);
+		if (WARN_ON(!mdp->vpu_dev)) {
+			dev_err(dev, "vpu pdev failed\n");
+			of_node_put(vpu_node);
+		}
+
+		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
+		if (ret) {
+			dev_err(dev, "Failed to register v4l2 device\n");
+			return -EINVAL;
+		}
+
+		ret = vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
+		if (ret) {
+			dev_err(dev, "Failed to set vb2 dma mag seg size\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * presence of the "mediatek,vpu" property in a device node
+		 * indicates that it is the primary MDP rdma device and MDP DMA
+		 * ops should be handled by its DMA callbacks.
+		 */
+		mdp->rdma_dev = dev;
+	}
+
 	pm_runtime_enable(dev);
 
 	return 0;
@@ -237,23 +274,9 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *vpu_node;
 	int status;
 	struct mtk_mdp_comp *comp;
 
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
-		of_node_put(vpu_node);
-		/*
-		 * The device tree node with a mediatek,vpu property is deemed
-		 * the MDP "master" device, we don't want to add a component
-		 * for it in this function because the initialization for the
-		 * master is done elsewhere.
-		 */
-		dev_info(dev, "vpu node found, not probing\n");
-		return -ENODEV;
-	}
-
 	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
 	if (!comp)
 		return -ENOMEM;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index a72a9ba41ea6..50eafcc9993d 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -159,6 +159,17 @@ static int mtk_mdp_master_bind(struct device *dev)
 		goto err_component_bind_all;
 	}
 
+	if (mdp->vpu_dev) {
+		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
+					  VPU_RST_MDP);
+		if (ret) {
+			dev_err(dev, "Failed to register reset handler\n");
+			goto err_wdt_reg;
+		}
+	} else {
+		dev_err(dev, "no vpu_dev found\n");
+	}
+
 	status = mtk_mdp_register_m2m_device(mdp);
 	if (status) {
 		dev_err(dev, "Failed to register m2m device: %d\n", status);
@@ -170,6 +181,8 @@ static int mtk_mdp_master_bind(struct device *dev)
 	return 0;
 
 err_mtk_mdp_register_m2m_device:
+
+err_wdt_reg:
 	component_unbind_all(dev, mdp);
 
 err_component_bind_all:
@@ -228,8 +241,13 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		of_node_put(node);
 		parent = dev->of_node;
 		dev_warn(dev, "device tree is out of date\n");
-	} else {
+	} else if (dev->of_node) {
 		parent = dev->of_node->parent;
+	} else if (dev->parent) {
+		/* maybe we were created from a call to platform_device_register_data() */
+		parent = dev->parent->parent->of_node;
+	} else {
+		return -ENODEV;
 	}
 
 	/* Iterate over sibling MDP function blocks */
@@ -262,16 +280,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		}
 	}
 
-	/*
-	 * Create a component for myself so that clocks can be toggled in
-	 * clock_on().
-	 */
-	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
-	if (ret) {
-		dev_err(dev, "Failed to initialize component\n");
-		goto err_comp;
-	}
-
 	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
 	if (!mdp->job_wq) {
 		dev_err(&pdev->dev, "unable to alloc job workqueue\n");
@@ -287,29 +295,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	}
 	INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker);
 
-	ret = v4l2_device_register(dev, &mdp->v4l2_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
-		ret = -EINVAL;
-		goto err_dev_register;
-	}
-
-	mdp->vpu_dev = vpu_get_plat_device(pdev);
-	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
-				  VPU_RST_MDP);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register reset handler\n");
-		goto err_wdt_reg;
-	}
-
 	platform_set_drvdata(pdev, mdp);
 
-	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-		goto err_set_max_seg_size;
-	}
-
 	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
 	if (ret) {
 		dev_err(dev, "Component master add failed\n");
@@ -321,22 +308,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	return 0;
 
 err_component_master_add:
-	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-
-err_set_max_seg_size:
-
-err_wdt_reg:
-	v4l2_device_unregister(&mdp->v4l2_dev);
-
-err_dev_register:
 	destroy_workqueue(mdp->wdt_wq);
 
 err_alloc_wdt_wq:
 	destroy_workqueue(mdp->job_wq);
 
 err_alloc_job_wq:
-
-err_comp:
 	dev_dbg(dev, "err %d\n", ret);
 	return ret;
 }
@@ -404,7 +381,6 @@ static struct platform_driver mtk_mdp_driver = {
 	.driver = {
 		.name	= MTK_MDP_MODULE_NAME,
 		.pm	= &mtk_mdp_pm_ops,
-		.of_match_table = mtk_mdp_of_ids,
 	}
 };
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index 8a52539b15d4..9fcd8b8e7c25 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -133,6 +133,7 @@ struct mtk_mdp_variant {
  * struct mtk_mdp_dev - abstraction for image processor entity
  * @lock:	the mutex protecting this data structure
  * @vpulock:	the mutex protecting the communication with VPU
+ * @rdma_dev:  device pointer to rdma device for MDP
  * @pdev:	pointer to the image processor platform device
  * @variant:	the IP variant information
  * @id:		image processor device index (0..MTK_MDP_MAX_DEVS)
@@ -151,6 +152,7 @@ struct mtk_mdp_variant {
 struct mtk_mdp_dev {
 	struct mutex			lock;
 	struct mutex			vpulock;
+	struct device			*rdma_dev;
 	struct platform_device		*pdev;
 	struct mtk_mdp_variant		*variant;
 	u16				id;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
index f14779e7596e..9834d3bbe851 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
@@ -929,7 +929,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
 	src_vq->mem_ops = &vb2_dma_contig_memops;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	src_vq->dev = &ctx->mdp_dev->pdev->dev;
+	src_vq->dev = ctx->mdp_dev->rdma_dev;
 	src_vq->lock = &ctx->mdp_dev->lock;
 
 	ret = vb2_queue_init(src_vq);
@@ -944,7 +944,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
 	dst_vq->mem_ops = &vb2_dma_contig_memops;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	dst_vq->dev = &ctx->mdp_dev->pdev->dev;
+	dst_vq->dev = ctx->mdp_dev->rdma_dev;
 	dst_vq->lock = &ctx->mdp_dev->lock;
 
 	return vb2_queue_init(dst_vq);
-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:12 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:12 +1000
Subject: [PATCH v6 6/9] soc: mediatek: mmsys: instantiate mdp virtual device
 from mmsys
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.6.Ie4214d2cc73ab276dd7c41d4f63c98e011fb42d4@changeid>

A virtual device that is probed by the mtk_mdp_core driver is
instantiated by the mtk_mmsys driver.

This better reflects the logical organization of the hardware and
driver: there are a number of hardware blocks that are used by the MDP
that have no strict hierarchy, and the software driver is responsible
for driving them properly.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

(no changes since v1)

 drivers/soc/mediatek/mtk-mmsys.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 080660ef11bf..e681029fe804 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -97,6 +97,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 	struct platform_device *clks;
 	struct platform_device *drm;
 	struct mtk_mmsys *mmsys;
+	struct platform_device *mdp;
 	int ret;
 
 	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
@@ -122,10 +123,27 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 					    PLATFORM_DEVID_AUTO, NULL, 0);
 	if (IS_ERR(drm)) {
 		platform_device_unregister(clks);
-		return PTR_ERR(drm);
+		ret = PTR_ERR(drm);
+		goto err_drm;
+	}
+
+	mdp = platform_device_register_data(&pdev->dev, "mtk-mdp",
+					    PLATFORM_DEVID_AUTO, NULL, 0);
+	if (IS_ERR(mdp)) {
+		ret = PTR_ERR(mdp);
+		dev_err(dev, "Failed to register mdp: %d\n", ret);
+		goto err_mdp;
 	}
 
 	return 0;
+
+err_mdp:
+	platform_device_unregister(drm);
+
+err_drm:
+	platform_device_unregister(clks);
+
+	return ret;
 }
 
 static const struct of_device_id of_match_mtk_mmsys[] = {
-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:13 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:13 +1000
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to MDP
 master
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>

... Instead of depending on the presence of a mediatek,vpu property in
the device node.

That property was originally added to link to the vpu node so that the
mtk_mdp_core driver could pass the right device to
vpu_wdt_reg_handler(). However in a previous patch in this series,
the driver has been modified to search the device tree for that node
instead.

That property was also used to indicate the primary MDP device, so that
it can be passed to the V4L2 subsystem as well as register it to be
used when setting up queues in the open() callback for the filesystem
device node that is created. In this case, assuming that the primary
MDP device is the one with a specific alias seems useable because the
alternative is to add a property to the device tree which doesn't
actually represent any facet of hardware (i.e., this being the primary
MDP device is a software decision). In other words, this solution is
equally as arbitrary, but at least it doesn't add a property to a
device node where said property is unrelated to the hardware present.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
 2 files changed, 64 insertions(+), 28 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 85ef274841a3..9527649de98e 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 		mtk_smi_larb_put(comp->larb_dev);
 }
 
-static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+/*
+ * The MDP master device node is identified by the device tree alias
+ * "mdp-rdma0".
+ */
+static bool is_mdp_master(struct device *dev)
+{
+	struct device_node *aliases, *mdp_rdma0_node;
+	const char *mdp_rdma0_path;
+
+	if (!dev->of_node)
+		return false;
+
+	aliases = of_find_node_by_path("/aliases");
+	if (!aliases) {
+		dev_err(dev, "no aliases found for mdp-rdma0");
+		return false;
+	}
+
+	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
+	if (!mdp_rdma0_path) {
+		dev_err(dev, "get mdp-rdma0 property of /aliases failed");
+		return false;
+	}
+
+	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
+	if (!mdp_rdma0_node) {
+		dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
+		return false;
+	}
+
+	return dev->of_node == mdp_rdma0_node;
+}
+
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
+			void *data)
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
-	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
 
-	/*
-	 * If this component has a "mediatek-vpu" property, it is responsible for
-	 * notifying the mdp master driver about it so it can be further initialized
-	 * later.
-	 */
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
+	if (is_mdp_master(dev)) {
 		int ret;
 
-		mdp->vpu_dev = of_find_device_by_node(vpu_node);
-		if (WARN_ON(!mdp->vpu_dev)) {
-			dev_err(dev, "vpu pdev failed\n");
-			of_node_put(vpu_node);
-		}
-
 		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
 		if (ret) {
 			dev_err(dev, "Failed to register v4l2 device\n");
@@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 		}
 
 		/*
-		 * presence of the "mediatek,vpu" property in a device node
-		 * indicates that it is the primary MDP rdma device and MDP DMA
-		 * ops should be handled by its DMA callbacks.
+		 * MDP DMA ops will be handled by the DMA callbacks associated with this
+		 * device;
 		 */
 		mdp->rdma_dev = dev;
 	}
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 50eafcc9993d..6a775463399c 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
 
 static int mtk_mdp_master_bind(struct device *dev)
 {
-	int status;
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+	struct device_node *vpu_node;
+	int status;
 
 	status = component_bind_all(dev, mdp);
 	if (status) {
@@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
 		goto err_component_bind_all;
 	}
 
-	if (mdp->vpu_dev) {
-		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
-					  VPU_RST_MDP);
-		if (ret) {
-			dev_err(dev, "Failed to register reset handler\n");
-			goto err_wdt_reg;
-		}
-	} else {
-		dev_err(dev, "no vpu_dev found\n");
+	if (mdp->rdma_dev == NULL) {
+		dev_err(dev, "Primary MDP device not found");
+		status = -ENODEV;
+		goto err_component_bind_all;
+	}
+
+	vpu_node = of_find_node_by_name(NULL, "vpu");
+	if (!vpu_node) {
+		dev_err(dev, "unable to find vpu node");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	mdp->vpu_dev = of_find_device_by_node(vpu_node);
+	if (!mdp->vpu_dev) {
+		dev_err(dev, "unable to find vpu device");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
+	if (status) {
+		dev_err(dev, "Failed to register reset handler\n");
+		goto err_wdt_reg;
 	}
 
 	status = mtk_mdp_register_m2m_device(mdp);
-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:14 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:14 +1000
Subject: [PATCH v6 8/9] dts: mtk-mdp: remove mediatek,
 vpu property from primary MDP device
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.8.Ib681f06d5189351b7fda0e3dcd6b15f3863a0071@changeid>

It is no longer used by the mediatek MDP driver.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

(no changes since v1)

 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d502073b551f..872427748110 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -1010,7 +1010,6 @@ mdp_rdma0: rdma at 14001000 {
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
 			mediatek,larb = <&larb0>;
-			mediatek,vpu = <&vpu>;
 		};
 
 		mdp_rdma1: rdma at 14002000 {
-- 
2.32.0.554.ge1b32706d8-goog



From eizan at chromium.org  Mon Aug  2 05:12:15 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Mon,  2 Aug 2021 22:12:15 +1000
Subject: [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from
 mtk-mdp
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <20210802220943.v6.9.If10dbdfade9f48710e485efe79e53e6e65144a2f@changeid>

It is no longer needed by the mtk-mdp driver

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

(no changes since v1)

 Documentation/devicetree/bindings/media/mediatek-mdp.txt | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index caa24943da33..4c325585f68f 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -4,8 +4,6 @@ Media Data Path is used for scaling and color space conversion.
 
 Required properties (controller node):
 - compatible: "mediatek,mt8173-mdp"
-- mediatek,vpu: the node of video processor unit, see
-  Documentation/devicetree/bindings/media/mediatek-vpu.txt for details.
 
 Required properties (all function blocks, child node):
 - compatible: Should be one of
@@ -41,7 +39,6 @@ Example:
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 		iommus = <&iommu M4U_PORT_MDP_RDMA0>;
 		mediatek,larb = <&larb0>;
-		mediatek,vpu = <&vpu>;
 	};
 
 	mdp_rdma1: rdma at 14002000 {
-- 
2.32.0.554.ge1b32706d8-goog



From catalin.marinas at arm.com  Mon Aug  2 05:19:48 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 13:19:48 +0100
Subject: [RFC PATCH 1/2] arm64: mm: Make virt_addr_valid to check for
 pfn_valid again
In-Reply-To: <1627490656-1267-1-git-send-email-olekstysh@gmail.com>
References: <1627490656-1267-1-git-send-email-olekstysh@gmail.com>
Message-ID: <20210802121947.GF18685@arm.com>

Adding Mike and Anshuman,

On Wed, Jul 28, 2021 at 07:44:15PM +0300, Oleksandr Tyshchenko wrote:
> From: Oleksandr Tyshchenko <oleksandr_tyshchenko at epam.com>
> 
> The problem is that Arm's implementation of virt_addr_valid()
> leads to memblock_is_map_memory() check, which will fail for
> ZONE_DEVICE based addresses. But, the pfn_valid() check in turn
> is able to cope with ZONE_DEVICE based memory.
> 
> You can find a good explanation of that problem at:
> https://lore.kernel.org/lkml/1614921898-4099-2-git-send-email-anshuman.khandual at arm.com
> 
> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko at epam.com>
> ---
> I am not quite sure whether it is a "correct" place and
> the change itself, I just partially restored a behaviour before:
> https://lore.kernel.org/lkml/20210511100550.28178-4-rppt at kernel.org
> So, the target of this patch is to get a feedback how to resolve
> this properly if, of course, this really needs to be resolved
> (I might miss important bits here).
> 
> It is worth mentioning that patch doesn't fix the current code base
> (if I am not mistaken, no one calls virt_addr_valid() on Arm64 for
> ZONE_DEVICE based addresses at the moment, so it seems that nothing
> is broken), the fix is intended for the subsequent patch in this
> series that will try to enable Xen's "unpopulated-alloc" usage
> on Arm (it was enabled on x86 so far).
> Please see:
> [RFC PATCH 2/2] xen/unpopulated-alloc: Query hypervisor to provide
> unallocated space
> 
> The subsequent patch will enable the code where virt_addr_valid()
> is used in drivers/xen/unpopulated-alloc.c:fill_list() to check that
> a virtual address returned by memremap_pages() is valid.

I wonder what the point of calling virt_addr_valid() in fill_list() is?
If memremap_pages() succeeded, the pages were mapped at the returned
vaddr, there's no need for an additional virt_addr_valid() check.

> ---
>  arch/arm64/include/asm/memory.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 824a365..1a35a44 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -351,7 +351,7 @@ static inline void *phys_to_virt(phys_addr_t x)
>  
>  #define virt_addr_valid(addr)	({					\
>  	__typeof__(addr) __addr = __tag_reset(addr);			\
> -	__is_lm_address(__addr) && pfn_is_map_memory(virt_to_pfn(__addr));	\
> +	__is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr));	\
>  })

pfn_valid() only guarantees the presence of a struct page but not
necessarily that the virtual address is accessible (valid). So this
change would break the NOMAP ranges case.

-- 
Catalin


From patrice.chotard at foss.st.com  Mon Aug  2 05:35:59 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Mon, 2 Aug 2021 14:35:59 +0200
Subject: [PATCH] [media] c8sectpfe: c8sectpfe-dvb: Remove unused including
 <linux/version.h>
In-Reply-To: <20210727053903.711-1-caihuoqing@baidu.com>
References: <20210727053903.711-1-caihuoqing@baidu.com>
Message-ID: <f33dbe73-c7db-acc6-8f74-866ff74857e1@foss.st.com>

Hi 

On 7/27/21 7:39 AM, Cai Huoqing wrote:
> Remove including <linux/version.h> that don't need it.
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> ---
>  drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 1 -
>  drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c  | 1 -
>  2 files changed, 2 deletions(-)
> 
> diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> index 338b205ae3a7..02dc78bd7fab 100644
> --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> @@ -28,7 +28,6 @@
>  #include <linux/usb.h>
>  #include <linux/slab.h>
>  #include <linux/time.h>
> -#include <linux/version.h>
>  #include <linux/wait.h>
>  #include <linux/pinctrl/pinctrl.h>
>  
> diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
> index 0560a9cb004b..feb48cb546d7 100644
> --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
> +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
> @@ -11,7 +11,6 @@
>  #include <linux/delay.h>
>  #include <linux/i2c.h>
>  #include <linux/interrupt.h>
> -#include <linux/version.h>
>  
>  #include <dt-bindings/media/c8sectpfe.h>
>  
> 

Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>
Thanks
Patrice


From maz at kernel.org  Mon Aug  2 05:36:11 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Aug 2021 13:36:11 +0100
Subject: [PATCH] KVM: arm64: Unregister HYP sections from kmemleak in
 protected mode
In-Reply-To: <20210729164214.GB31848@arm.com>
References: <20210729135016.3037277-1-maz@kernel.org>
 <20210729164214.GB31848@arm.com>
Message-ID: <87o8ag10sk.wl-maz@kernel.org>

On Thu, 29 Jul 2021 17:42:15 +0100,
Catalin Marinas <catalin.marinas at arm.com> wrote:
> 
> On Thu, Jul 29, 2021 at 02:50:16PM +0100, Marc Zyngier wrote:
> > Booting a KVM host in protected mode with kmemleak quickly results
> > in a pretty bad crash, as kmemleak doesn't know that the HYP sections
> > have been taken away.
> > 
> > Make the unregistration from kmemleak part of marking the sections
> > as HYP-private. The rest of the HYP-specific data is obtained via
> > the page allocator, which is not subjected to kmemleak.
> > 
> > Fixes: 90134ac9cabb ("KVM: arm64: Protect the .hyp sections from the host")
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > Cc: Quentin Perret <qperret at google.com>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: stable at vger.kernel.org # 5.13
> > ---
> >  arch/arm64/kvm/arm.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index e9a2b8f27792..23f12e602878 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -15,6 +15,7 @@
> >  #include <linux/fs.h>
> >  #include <linux/mman.h>
> >  #include <linux/sched.h>
> > +#include <linux/kmemleak.h>
> >  #include <linux/kvm.h>
> >  #include <linux/kvm_irqfd.h>
> >  #include <linux/irqbypass.h>
> > @@ -1960,8 +1961,12 @@ static inline int pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
> >  }
> >  
> >  #define pkvm_mark_hyp_section(__section)		\
> > +({							\
> > +	u64 sz = __section##_end - __section##_start;	\
> > +	kmemleak_free_part(__section##_start, sz);	\
> >  	pkvm_mark_hyp(__pa_symbol(__section##_start),	\
> > -			__pa_symbol(__section##_end))
> > +		      __pa_symbol(__section##_end));	\
> > +})
> 
> Using kmemleak_free_part() is fine in principle as this is not a slab
> object. However, the above would call the function even for ranges that
> are not tracked at all by kmemleak (text, idmap). Luckily Kmemleak won't
> complain, unless you #define DEBUG in the file (initially I tried to
> warn all the time but I couldn't fix all the callbacks).

Yeah, I had a look last week, and this fires everywhere (KVM only adds
a drop in an ocean of warnings).

> If it was just the BSS, I would move the kmemleak_free_part() call to
> finalize_hyp_mode() but there's the __hyp_rodata section as well.
> 
> I think we have some inconsistency with .hyp.rodata which falls under
> _sdata.._edata while the kernel's own .rodata goes immediately after
> _etext. Should we move __hyp_rodata outside _sdata.._edata as well? It
> would benefit from the RO NX marking (probably more useful without the
> protected mode). If this works, we'd only need to call kmemleak once for
> the BSS.

That's a good idea, and pretty easy to implement. I'll post a respin
shortly.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Mon Aug  2 05:38:29 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Aug 2021 13:38:29 +0100
Subject: [PATCH v2 1/2] arm64: Move .hyp.rodata outside of the _sdata.._edata
 range
In-Reply-To: <20210802123830.2195174-1-maz@kernel.org>
References: <20210802123830.2195174-1-maz@kernel.org>
Message-ID: <20210802123830.2195174-2-maz@kernel.org>

The HYP rodata section is currently lumped together with the BSS,
which isn't exactly what is expected (it gets registered with
kmemleak, for example).

Move it away so that it is actually marked RO. As an added
benefit, it isn't registered with kmemleak anymore.

Fixes: 380e18ade4a5 ("KVM: arm64: Introduce a BSS section for use at Hyp")
Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org #5.13
---
 arch/arm64/kernel/vmlinux.lds.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 709d2c433c5e..f6b1a88245db 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -181,6 +181,8 @@ SECTIONS
 	/* everything from this point to __init_begin will be marked RO NX */
 	RO_DATA(PAGE_SIZE)
 
+	HYPERVISOR_DATA_SECTIONS
+
 	idmap_pg_dir = .;
 	. += IDMAP_DIR_SIZE;
 	idmap_pg_end = .;
@@ -260,8 +262,6 @@ SECTIONS
 	_sdata = .;
 	RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
 
-	HYPERVISOR_DATA_SECTIONS
-
 	/*
 	 * Data written with the MMU off but read with the MMU on requires
 	 * cache lines to be invalidated, discarding up to a Cache Writeback
-- 
2.30.2



From maz at kernel.org  Mon Aug  2 05:38:28 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Aug 2021 13:38:28 +0100
Subject: [PATCH v2 0/2] KVM: arm64: Prevent kmemleak from accessing HYP data
Message-ID: <20210802123830.2195174-1-maz@kernel.org>

This is a rework of the patch previously posted at [1].

The gist of the problem is that kmemleak can legitimately access data
that has been removed from the kernel view, for two reasons:

(1) .hyp.rodata is lumped together with the BSS
(2) there is no separation of the HYP BSS from the kernel BSS

(1) can easily be addressed by moving the .hyp.rodata section into the
    kernel's RO zone, which avoids any kmemleak into that section.
(2) must be addressed by telling kmemleak about the address range.

Tested on a SC2A11 system, in protected and non-protected modes with
kmemleak active. Both patches are stable candidates.

[1] https://lore.kernel.org/r/20210729135016.3037277-1-maz at kernel.org

Marc Zyngier (2):
  arm64: Move .hyp.rodata outside of the _sdata.._edata range
  KVM: arm64: Unregister HYP sections from kmemleak in protected mode

 arch/arm64/kernel/vmlinux.lds.S | 4 ++--
 arch/arm64/kvm/arm.c            | 7 +++++++
 2 files changed, 9 insertions(+), 2 deletions(-)

-- 
2.30.2



From maz at kernel.org  Mon Aug  2 05:38:30 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Aug 2021 13:38:30 +0100
Subject: [PATCH v2 2/2] KVM: arm64: Unregister HYP sections from kmemleak in
 protected mode
In-Reply-To: <20210802123830.2195174-1-maz@kernel.org>
References: <20210802123830.2195174-1-maz@kernel.org>
Message-ID: <20210802123830.2195174-3-maz@kernel.org>

Booting a KVM host in protected mode with kmemleak quickly results
in a pretty bad crash, as kmemleak doesn't know that the HYP sections
have been taken away. This is specially true for the BSS section,
which is part of the kernel BSS section and registered at boot time
by kmemleak itself.

Unregister the HYP part of the BSS before making that section
HYP-private. The rest of the HYP-specific data is obtained via
the page allocator or lives in other sections, none of which is
subjected to kmemleak.

Fixes: 90134ac9cabb ("KVM: arm64: Protect the .hyp sections from the host")
Reviewed-by: Quentin Perret <qperret at google.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: stable at vger.kernel.org # 5.13
---
 arch/arm64/kvm/arm.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..52242f32c4be 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -15,6 +15,7 @@
 #include <linux/fs.h>
 #include <linux/mman.h>
 #include <linux/sched.h>
+#include <linux/kmemleak.h>
 #include <linux/kvm.h>
 #include <linux/kvm_irqfd.h>
 #include <linux/irqbypass.h>
@@ -1982,6 +1983,12 @@ static int finalize_hyp_mode(void)
 	if (ret)
 		return ret;
 
+	/*
+	 * Exclude HYP BSS from kmemleak so that it doesn't get peeked
+	 * at, which would end badly once the section is inaccessible.
+	 * None of other sections should ever be introspected.
+	 */
+	kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start);
 	ret = pkvm_mark_hyp_section(__hyp_bss);
 	if (ret)
 		return ret;
-- 
2.30.2



From Dave.Martin at arm.com  Mon Aug  2 05:37:50 2021
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 2 Aug 2021 13:37:50 +0100
Subject: [PATCH v3 3/4] kselftest/arm64: Add tests for SVE vector
 configuration
In-Reply-To: <20210802113330.GD4668@sirena.org.uk>
References: <20210729151518.46388-1-broonie@kernel.org>
 <20210729151518.46388-4-broonie@kernel.org>
 <20210729160642.GP1724@arm.com>
 <20210729173411.GT4670@sirena.org.uk>
 <20210802102517.GA25258@arm.com>
 <20210802113330.GD4668@sirena.org.uk>
Message-ID: <20210802123749.GB25258@arm.com>

On Mon, Aug 02, 2021 at 12:33:30PM +0100, Mark Brown wrote:
> On Mon, Aug 02, 2021 at 11:25:29AM +0100, Dave Martin wrote:
> 
> > That's a reasonable position, but thinking about it a bit more, there's
> > not really any loop at all here.
> > 
> > There definitely is an unwaited-for child and we don't pass WHONANG to
> > wait(), so it will either return the child pid, or fail.
> > 
> > Without WUNTRACED or similar, the child must terminate to wake up the
> > wait().
> 
> > So is this just a matter of
> 
> > 	pid = wait(&ret);
> > 	if (pid == -1) {
> > 		/* barf */
> > 	}
> > 	assert(pid == child);
> > 
> > 	if (!WIFEXITED(ret)) {
> > 		/* barf */
> > 	}
> > 
> > 	if (WEXITSTATUS(ret) != 0) {
> > 		/* barf */
> > 	}
> > 
> > 	/* parse child's stdout etc. */
> 
> That really doesn't seem like a good idea - it's just asking for
> fragility if a signal gets delivered to the parent process or something.
> Even if almost all the time there will only be one trip through the loop
> we should still have the loop there for those few cases where it
> triggers.

This concern only applies when the program actually registers signal
handlers.

wait() can't return for any other reason, and it mustn't, precisely
because historically software would have made this assumption.  This is
one reason why wait3() etc. are separate functions.

That aside though, can't we use popen(3)?

I tend to forget about popen because it is "boring" to use it, but it
looks like it fits this case quite well.  Then it would be libc's
problem how to fork and wait safely.

[...]

Cheers
---Dave


From nm at ti.com  Mon Aug  2 05:45:09 2021
From: nm at ti.com (Nishanth Menon)
Date: Mon, 2 Aug 2021 07:45:09 -0500
Subject: [PATCH v2 0/6] CAN: Add support for CAN in AM65,J721e and AM64
In-Reply-To: <20210726101012.26983-1-a-govindraju@ti.com>
References: <20210726101012.26983-1-a-govindraju@ti.com>
Message-ID: <20210802124509.z23lfg7xxkqaakbo@truce>

On 15:40-20210726, Aswath Govindraju wrote:
> The following series of patches add support for CAN in SoC's AM65, J721e
> and AM64.
> 
> This patch series is dependent on [1] and [2] and I have requested for an
> immutable tag from the Marc Kleine-Budde(maintainer of net tree).
> 
> [1] - https://lore.kernel.org/patchwork/patch/1423048/
> [2] - https://www.spinics.net/lists/linux-can/msg08108.html
> 
> changes since v1 -
> - changed the message ram configuration to use the maximum value
>   in each field, for better performance.
> 
> Aswath Govindraju (3):
>   arm64: dts: ti: am654-base-board: Disable mcan nodes
>   arm64: dts: ti: k3-am64-main: Add support for MCAN
>   arm64: dts: ti: k3-am642-evm/sk: Add support for main domain mcan
>     nodes in EVM and disable them on SK
> 
> Faiz Abbas (3):
>   arm64: dts: ti: k3-am65-mcu: Add Support for MCAN
>   arm64: dts: ti: k3-j721e: Add support for MCAN nodes
>   arm64: dts: ti: k3-j721e-common-proc-board: Add support for mcu_mcan
>     nodes

I noticed in my checkup: https://pastebin.ubuntu.com/p/zSk39M943N/
warnings with dtbs_check, I think the bindings need a little more help
here (please also notice the iot platform warnings getting introduced).

Since we are still working on the bindings[1], lets clean that up
before we consider the dts addition. I suspect we need to cook this
more towards the next cycle.

[1] https://lore.kernel.org/patchwork/patch/1470806/
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D)/Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From catalin.marinas at arm.com  Mon Aug  2 05:46:25 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 13:46:25 +0100
Subject: [PATCH] arm64: move the (z)install rules to arch/arm64/Makefile
In-Reply-To: <20210729140527.443116-1-masahiroy@kernel.org>
References: <20210729140527.443116-1-masahiroy@kernel.org>
Message-ID: <20210802124624.GG18685@arm.com>

On Thu, Jul 29, 2021 at 11:05:27PM +0900, Masahiro Yamada wrote:
> Currently, the (z)install targets in arch/arm64/Makefile descend into
> arch/arm64/boot/Makefile to invoke the shell script, but there is no
> good reason to do so.
> 
> arch/arm64/Makefile can run the shell script directly.
> 
> Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> ---
> 
>  arch/arm64/Makefile      | 7 +++++--
>  arch/arm64/boot/Makefile | 8 --------
>  2 files changed, 5 insertions(+), 10 deletions(-)

Is this part of some cross-arch clean-up? I can see x86 for example does
the same thing.

Thanks.

-- 
Catalin


From mike.leach at linaro.org  Mon Aug  2 05:48:12 2021
From: mike.leach at linaro.org (Mike Leach)
Date: Mon, 2 Aug 2021 13:48:12 +0100
Subject: [PATCH 3/6] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <20210802120545.GJ7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-4-james.clark@arm.com>
 <20210731074343.GG7437@leoy-ThinkPad-X240s>
 <CAJ9a7Vj_KhV+v6VU+EQN5t818VS9jvf3v3-2JbwVMOHZbi3gcg@mail.gmail.com>
 <20210802120545.GJ7437@leoy-ThinkPad-X240s>
Message-ID: <CAJ9a7VjhBViNuCf6sdixNYwcU6OMuGL2ccST=vCeojef6fcbJw@mail.gmail.com>

Hi Leo,

On Mon, 2 Aug 2021 at 13:05, Leo Yan <leo.yan at linaro.org> wrote:
>
> Hi Mike,
>
> On Mon, Aug 02, 2021 at 12:21:31PM +0100, Mike Leach wrote:
>
> [...]
>
> > > Here I think the right thing to do is to support newer revisions for
> > > ETMv4, and then based on the revision it creates a decoder with
> > > supporting ETE feature.  For a more neat solution, if the perf tool
> > > passes the "correct" revision number to the OpenCSD decoder, it should
> > > can decode trace data with ETE packets.  In this way, the ETE decoding
> > > can be transparent for perf cs-etm code.
> > >
> >
> > The OpenCSD decoder separates the ETMv4 decoder from the ETE decoder -
> > for the reasons given above.
>
> Thanks for explanation.
>
> > Additionally the ETE decoder and the ETMv4 decoder required different
> > sets of ID registers to correctly set up the decoder.  For example,
> > for ETMv4 the version is extracted form TRCIDR1, for ETE the version
> > in TRCIDR1 is set 0xFF, and thus needs TRCDEVARCH to extract the
> > revision. It is likely that later updates to ETE will require an
> > additional TRCIDR register to be saved.
>
> Okay, for ETMv4.x and ETE, finally I think we need to rely on TRCDEVARCH to
> decide the tracer version based on the architecture number (arch 4 or 5)
> and revision number.
>
> > Choosing the base type of decoder in this way is how the library can
> > support ETMv3, EMTv4, ETE, STM, PTM etc - and while some of those
> > protocols use TRCIDR1 and TRCDEVARCH - not all do.
> >
> > It would in theory be possible to have the OpenCSD library
> > "autodetect" the type of decoder needed based purely on a set of ID
> > registers. But this set of ID registers would be far larger than the
> > ones currently used, and would require modifcation to a lot of the
> > existing device drivers to ensure they were accessible via sysfs. This
> > register set includes the ID registers that are currently used to
> > identify the component on the AMBA bus and match to the correct
> > driver, plus additional CoreSight management registers. This would
> > also create a dependency between decoder creation and ID numbers - in
> > the same way that each new ETM4.x part number has to be added to the
> > ETM4.x device driver.
> >
> > Such a system would require a significant update to the OpenCSD
> > infrastructure, and is not planned at this time.
>
> It's fine for me not introducing significant change in OpenCSD.
>
> If so, I understand your suggestion in another email to add a new magic
> number and a new protocol (this patch set has added the new protocol
> CS_ETM_PROTO_ETE) for creating ETE decoder.
>
> Just confirm one thing which is a bit confused me: for ETMv4.5 or any
> newer ETM IPs, should the perf tool keep the existed way to create the
> ETMv4 decoder?  Or there have updating is required for decoder to
> support the extended packets?
>

Where the trace device is identified as an ETMv4.x, then perf will
continue to create an ETMv4.x decoder as it does now. The OpenCSD
ETM4.x decoder will track any needed updates for the ETM4.x series.

Only where the trace device is ETE, there will be the new magic number
and different ID registers be used - so the call to OpenCSD will
request an ETE decoder to be created.

The register value structures supplied to OpenCSD on decoder creation,
differ between ETM4.x and ETE.

Regards

Mike


> Thanks,
> Leo



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mkl at pengutronix.de  Mon Aug  2 05:59:40 2021
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Mon, 2 Aug 2021 14:59:40 +0200
Subject: [PATCH v2 1/6] arm64: dts: ti: k3-am65-mcu: Add Support for MCAN
In-Reply-To: <20210726101012.26983-2-a-govindraju@ti.com>
References: <20210726101012.26983-1-a-govindraju@ti.com>
 <20210726101012.26983-2-a-govindraju@ti.com>
Message-ID: <20210802125940.w2djzwuwysco566p@pengutronix.de>

On 26.07.2021 15:40:07, Aswath Govindraju wrote:
> From: Faiz Abbas <faiz_abbas at ti.com>
> 
> Add Support for two MCAN controllers present on the am65x SOC. Both support
> classic CAN messages as well as CAN-FD.
> 
> Signed-off-by: Faiz Abbas <faiz_abbas at ti.com>
> Signed-off-by: Aswath Govindraju <a-govindraju at ti.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi | 30 +++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> index c93ff1520a0e..6445f2d976e8 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> @@ -159,6 +159,36 @@
>  		};
>  	};
>  
> +	m_can0: mcan at 40528000 {
> +		compatible = "bosch,m_can";
> +		reg = <0x0 0x40528000 0x0 0x400>,
> +		      <0x0 0x40500000 0x0 0x4400>;
> +		reg-names = "m_can", "message_ram";
> +		power-domains = <&k3_pds 102 TI_SCI_PD_EXCLUSIVE>;
> +		clocks = <&k3_clks 102 0>, <&k3_clks 102 5>;
> +		clock-names = "cclk", "hclk";

The binding says the first should be hclk.

|  clock-names:
|    items:
|      - const: hclk
|      - const: cclk

Please also fix in the other dts files.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/c3217c8a/attachment.sig>

From rocco.yue at mediatek.com  Mon Aug  2 05:40:39 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Mon, 2 Aug 2021 20:40:39 +0800
Subject: [PATCH net-next v2] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <20210802031924.3256-1-rocco.yue@mediatek.com>
References: <20210802031924.3256-1-rocco.yue@mediatek.com>
Message-ID: <20210802124039.13231-1-rocco.yue@mediatek.com>

On Sat, 2021-07-31 at 11:17 -0600, David Ahern wrote:
On 7/30/21 7:52 PM, Rocco Yue wrote:

> IFLA_INET6_RA_MTU set. You can set "reject_message" in the policy to
> return a message that "IFLA_INET6_RA_MTU can not be set".

Hi David,

Regarding setting "reject_message" in the policy, after reviewing
the code, I fell that it is unnecessary, because the cost of
implementing it seems to be a bit high, which requires modifying
the function interface. The reasons is as follows:

The parameter "struct netlink_ext_ack *extack" is not exposed in the
function inet6_validate_link_af(), and the last argument when calling
nla_parse_nested_deprecated() is NULL, which makes the user space not
notified even if reject_message is set.

static int inet6_validate_link_af(...)
{
...
	err = nla_parse_nested_deprecated(tb, IFLA_INET6_MAX, nla,
					  inet6_af_policy, NULL);
...
}


Only when extack is not NULL, reject_message is valid.

static int validate_nla(...)
{
...
	switch (pt->type) {
	case NLA_REJECT:
		if (extack && pt->reject_message) {
			NL_SET_BAD_ATTR(extack, nla);
			extack->_msg = pt->reject_message;
			return -EINVAL;
		}
		err = -EINVAL;
		goto out_err;
...
}


Thanks
Rocco

From will at kernel.org  Mon Aug  2 06:04:39 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Aug 2021 14:04:39 +0100
Subject: [PATCH v2 23/24] iommu/arm-smmu: Allow non-strict in
 pgtable_quirks interface
In-Reply-To: <0fcd1f5225a6b435cbc697551a6247cd435c04db.1627468310.git.robin.murphy@arm.com>
References: <cover.1627468308.git.robin.murphy@arm.com>
 <0fcd1f5225a6b435cbc697551a6247cd435c04db.1627468310.git.robin.murphy@arm.com>
Message-ID: <20210802130438.GA28547@willie-the-truck>

On Wed, Jul 28, 2021 at 04:58:44PM +0100, Robin Murphy wrote:
> To make io-pgtable aware of a flush queue being dynamically enabled,
> allow IO_PGTABLE_QUIRK_NON_STRICT to be set even after a domain has been
> attached to, and hook up the final piece of the puzzle in iommu-dma.
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++++++++
>  drivers/iommu/arm/arm-smmu/arm-smmu.c       | 11 +++++++++++
>  drivers/iommu/dma-iommu.c                   |  3 +++
>  3 files changed, 29 insertions(+)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 19400826eba7..40fa9cb382c3 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2711,6 +2711,20 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
>  	return ret;
>  }
>  
> +static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
> +		unsigned long quirks)
> +{
> +	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> +
> +	if (quirks == IO_PGTABLE_QUIRK_NON_STRICT && smmu_domain->pgtbl_ops) {
> +		struct io_pgtable *iop = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
> +
> +		iop->cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
> +		return 0;
> +	}
> +	return -EINVAL;
> +}

I don't see anything serialising this against a concurrent iommu_unmap(), so
the ordering and atomicity looks quite suspicious to me here. I don't think
it's just the page-table quirks either, but also setting cookie->fq_domain.

Will


From olteanv at gmail.com  Mon Aug  2 06:07:23 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 2 Aug 2021 16:07:23 +0300
Subject: [RFC net-next v2 1/4] net: dsa: mt7530: enable assisted learning
 on CPU port
In-Reply-To: <20210731191023.1329446-2-dqfext@gmail.com>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-2-dqfext@gmail.com>
Message-ID: <20210802130723.6tieexl5zcxu44xr@skbuf>

On Sun, Aug 01, 2021 at 03:10:19AM +0800, DENG Qingfang wrote:
> Consider the following bridge configuration, where bond0 is not
> offloaded:
> 
>          +-- br0 --+
>         / /   |     \
>        / /    |      \
>       /  |    |     bond0
>      /   |    |     /   \
>    swp0 swp1 swp2 swp3 swp4
>      .        .       .
>      .        .       .
>      A        B       C
> 
> Address learning is enabled on offloaded ports (swp0~2) and the CPU
> port, so when client A sends a packet to C, the following will happen:
> 
> 1. The switch learns that client A can be reached at swp0.
> 2. The switch probably already knows that client C can be reached at the
>    CPU port, so it forwards the packet to the CPU.
> 3. The bridge core knows client C can be reached at bond0, so it
>    forwards the packet back to the switch.
> 4. The switch learns that client A can be reached at the CPU port.
> 5. The switch forwards the packet to either swp3 or swp4, according to
>    the packet's tag.
> 
> That makes client A's MAC address flap between swp0 and the CPU port. If
> client B sends a packet to A, it is possible that the packet is
> forwarded to the CPU. With offload_fwd_mark = 1, the bridge core won't
> forward it back to the switch, resulting in packet loss.
> 
> As we have the assisted_learning_on_cpu_port in DSA core now, enable
> that and disable hardware learning on the CPU port.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---

Reviewed-by: Vladimir Oltean <oltean at gmail.com>


From qperret at google.com  Mon Aug  2 06:11:07 2021
From: qperret at google.com (Quentin Perret)
Date: Mon, 2 Aug 2021 14:11:07 +0100
Subject: [PATCH v2 1/2] arm64: Move .hyp.rodata outside of the
 _sdata.._edata range
In-Reply-To: <20210802123830.2195174-2-maz@kernel.org>
References: <20210802123830.2195174-1-maz@kernel.org>
 <20210802123830.2195174-2-maz@kernel.org>
Message-ID: <YQfu6+3uo6qlxrpv@google.com>

Hi Marc,

On Monday 02 Aug 2021 at 13:38:29 (+0100), Marc Zyngier wrote:
> The HYP rodata section is currently lumped together with the BSS,
> which isn't exactly what is expected (it gets registered with
> kmemleak, for example).
> 
> Move it away so that it is actually marked RO. As an added
> benefit, it isn't registered with kmemleak anymore.

2d7bf218ca73 ("KVM: arm64: Add .hyp.data..ro_after_init ELF section")
states explicitly that the hyp ro_after_init section should remain RW in
the host as it is expected to modify it before initializing EL2. But I
can't seem to trigger anything with this patch applied, so I'll look
into this a bit more.

> Fixes: 380e18ade4a5 ("KVM: arm64: Introduce a BSS section for use at Hyp")

Not sure this is the patch to blame?

> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Cc: stable at vger.kernel.org #5.13
> ---
>  arch/arm64/kernel/vmlinux.lds.S | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
> index 709d2c433c5e..f6b1a88245db 100644
> --- a/arch/arm64/kernel/vmlinux.lds.S
> +++ b/arch/arm64/kernel/vmlinux.lds.S
> @@ -181,6 +181,8 @@ SECTIONS
>  	/* everything from this point to __init_begin will be marked RO NX */
>  	RO_DATA(PAGE_SIZE)
>  
> +	HYPERVISOR_DATA_SECTIONS
> +
>  	idmap_pg_dir = .;
>  	. += IDMAP_DIR_SIZE;
>  	idmap_pg_end = .;
> @@ -260,8 +262,6 @@ SECTIONS
>  	_sdata = .;
>  	RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
>  
> -	HYPERVISOR_DATA_SECTIONS
> -
>  	/*
>  	 * Data written with the MMU off but read with the MMU on requires
>  	 * cache lines to be invalidated, discarding up to a Cache Writeback
> -- 
> 2.30.2

Thanks,
Quentin


From linus.walleij at linaro.org  Mon Aug  2 06:19:15 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 2 Aug 2021 15:19:15 +0200
Subject: [PATCH 4/4] arm: dts: zynq: Replace 'io-standard' with
 'power-source' property
In-Reply-To: <2f5d9197-4a5e-08b5-7e47-595d337478d2@xilinx.com>
References: <1626868353-96475-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <1626868353-96475-5-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <YQMIhBPwcNw1YqMq@robh.at.kernel.org>
 <CACRpkdYrHTMLL_CQi0BoNZsXV3=2dBK38pkvd+EEkuPrzoG_Cw@mail.gmail.com>
 <2f5d9197-4a5e-08b5-7e47-595d337478d2@xilinx.com>
Message-ID: <CACRpkdZu2-EE1hqJ4nVA5uxaPuJRGWDH_ciKxRvrNncQ2Pyd5w@mail.gmail.com>

On Fri, Jul 30, 2021 at 2:46 PM Michal Simek <michal.simek at xilinx.com> wrote:

> Linux Zynq pinctrl driver and in tree dts files are using io-standard
> properties at least from 2015.

Ooops my wrong.

What about supporting both the new property and io-standard as
a fallback, simply?

Yours,
Linus Walleij


From maz at kernel.org  Mon Aug  2 06:20:42 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Aug 2021 14:20:42 +0100
Subject: [PATCH v2 1/2] arm64: Move .hyp.rodata outside of the
 _sdata.._edata range
In-Reply-To: <YQfu6+3uo6qlxrpv@google.com>
References: <20210802123830.2195174-1-maz@kernel.org>
 <20210802123830.2195174-2-maz@kernel.org>
 <YQfu6+3uo6qlxrpv@google.com>
Message-ID: <87mtq00yqd.wl-maz@kernel.org>

Hi Quentin,

On Mon, 02 Aug 2021 14:11:07 +0100,
Quentin Perret <qperret at google.com> wrote:
> 
> Hi Marc,
> 
> On Monday 02 Aug 2021 at 13:38:29 (+0100), Marc Zyngier wrote:
> > The HYP rodata section is currently lumped together with the BSS,
> > which isn't exactly what is expected (it gets registered with
> > kmemleak, for example).
> > 
> > Move it away so that it is actually marked RO. As an added
> > benefit, it isn't registered with kmemleak anymore.
> 
> 2d7bf218ca73 ("KVM: arm64: Add .hyp.data..ro_after_init ELF section")
> states explicitly that the hyp ro_after_init section should remain RW in
> the host as it is expected to modify it before initializing EL2. But I
> can't seem to trigger anything with this patch applied, so I'll look
> into this a bit more.

The switch to RO happens quite late. And if the host was to actually
try and change things there, it would be screwed anyway (we will have
already removed the pages from its S2).

I wouldn't be surprised if this was a consequence of the way we now
build the HYP object, and the comment in the original commit may not
be valid anymore.

> 
> > Fixes: 380e18ade4a5 ("KVM: arm64: Introduce a BSS section for use at Hyp")
> 
> Not sure this is the patch to blame?

My bad, this is plain wrong. I'm not sure it can be applied earlier
though if my rambling above is correct.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzysztof.kozlowski at canonical.com  Mon Aug  2 06:23:42 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  2 Aug 2021 15:23:42 +0200
Subject: [PATCH] pinctrl: samsung: Fix pinctrl bank pin count
In-Reply-To: <20210730192905.7173-1-semen.protsenko@linaro.org>
References: <20210730192905.7173-1-semen.protsenko@linaro.org>
Message-ID: <162791061524.24470.4507251211900093020.b4-ty@canonical.com>

On Fri, 30 Jul 2021 22:29:05 +0300, Sam Protsenko wrote:
> Commit 1abd18d1a51a ("pinctrl: samsung: Register pinctrl before GPIO")
> changes the order of GPIO and pinctrl registration: now pinctrl is
> registered before GPIO. That means gpio_chip->ngpio is not set when
> samsung_pinctrl_register() called, and one cannot rely on that value
> anymore. Use `pin_bank->nr_pins' instead of `pin_bank->gpio_chip.ngpio'
> to fix mentioned inconsistency.

Applied, thanks!

[1/1] pinctrl: samsung: Fix pinctrl bank pin count
      commit: 70115558ab02fe8d28a6634350b3491a542aaa02

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From arnd at kernel.org  Mon Aug  2 06:32:37 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 15:32:37 +0200
Subject: [GIT PULL] STM32 DT fixes for v5.14 #1
In-Reply-To: <c0b6031b-2de7-2ef8-71b2-a0af8f475932@foss.st.com>
References: <c0b6031b-2de7-2ef8-71b2-a0af8f475932@foss.st.com>
Message-ID: <162791113541.1139989.12661940653007966330.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 30 Jul 2021 15:58:54 +0200, Alexandre TORGUE wrote:
> Please consider this first round of STM32 DT fixes for v5.14. It
> concerns DHCOM/DHCOR fixes.
> 
> Thanks
> Alex
> 
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
> [...]

Merged into arm/fixes, thanks!

merge commit: b07bf042e678f5eac856052d332869423e365af0

       Arnd


From arnd at kernel.org  Mon Aug  2 06:32:38 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 15:32:38 +0200
Subject: [PATCH] ARM: ixp4xx: goramo_mlr depends on old PCI driver
In-Reply-To: <20210721151620.2373500-1-arnd@kernel.org>
References: <20210721151620.2373500-1-arnd@kernel.org>
Message-ID: <162791113519.1139989.4454280837316167458.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 21 Jul 2021 17:16:04 +0200, Arnd Bergmann wrote:
> When this driver is disabled, the board file fails to build,
> so add a dependency:
> 
> arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_preinit':
> arch/arm/mach-ixp4xx/goramo_mlr.c:472:9: error: implicit declaration of function 'ixp4xx_pci_preinit'; did you mean 'iop3xx_pci_preinit'? [-Werror=implicit-function-declaration]
>   472 |         ixp4xx_pci_preinit();
>       |         ^~~~~~~~~~~~~~~~~~
>       |         iop3xx_pci_preinit
> arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_postinit':
> arch/arm/mach-ixp4xx/goramo_mlr.c:481:22: error: implicit declaration of function 'ixp4xx_pci_read' [-Werror=implicit-function-declaration]
>   481 |                 if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
>       |                      ^~~~~~~~~~~~~~~
> arch/arm/mach-ixp4xx/goramo_mlr.c:231:35: error: 'IXP4XX_UART1_BASE_PHYS' undeclared here (not in a function)
>   231 |                 .start          = IXP4XX_UART1_BASE_PHYS,
>       |                                   ^~~~~~~~~~~~~~~~~~~~~~
> arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_init':
> arch/arm/mach-ixp4xx/goramo_mlr.c:376:9: error: implicit declaration of function 'ixp4xx_sys_init' [-Werror=implicit-function-declaration]
>   376 |         ixp4xx_sys_init();
>       |         ^~~~~~~~~~~~~~~

Applied to arm/fixes, thanks!

[1/1] ARM: ixp4xx: goramo_mlr depends on old PCI driver
      commit: 796a8c85b1216618258e08b463d3bef0d7123760

       Arnd


From arnd at kernel.org  Mon Aug  2 06:32:40 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 15:32:40 +0200
Subject: [GIT PULL] ARM: mvebu: fixes for v5.14 (#1)
In-Reply-To: <87k0l7zx4v.fsf@BL-laptop>
References: <87k0l7zx4v.fsf@BL-laptop>
Message-ID: <162791113549.1139989.15144544679312934599.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 30 Jul 2021 16:36:48 +0200, Gregory CLEMENT wrote:
> Here is the first pull request for fixes for mvebu for v5.14.
> 
> Gregory
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> [...]

Merged into arm/fixes, thanks!

merge commit: 6ebeca342f96a7c371ed5fe53189dd56fe0c0330

       Arnd


From arnd at kernel.org  Mon Aug  2 06:32:42 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 15:32:42 +0200
Subject: [GIT PULL] i.MX fixes for 5.14
In-Reply-To: <20210726023221.GF5901@dragon>
References: <20210726023221.GF5901@dragon>
Message-ID: <162791113528.1139989.15546456709229753234.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 26 Jul 2021 10:32:22 +0800, Shawn Guo wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-fixes-5.14
> 
> [...]

Merged into arm/fixes, thanks!

merge commit: bee757485161e2bb43fd0bcd5f7e17cfe2b11bbf

       Arnd


From arnd at kernel.org  Mon Aug  2 06:32:43 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 15:32:43 +0200
Subject: [GIT PULL] arm64: tegra: Device tree fixes for v5.14-rc3
In-Reply-To: <20210716233858.10096-1-thierry.reding@gmail.com>
References: <20210716233858.10096-1-thierry.reding@gmail.com>
Message-ID: <162791113497.1139989.17406882949519965534.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sat, 17 Jul 2021 01:38:58 +0200, Thierry Reding wrote:
> The following changes since commit c667dcd4dfcd515ad2c9b3953a33d742985a0b5e:
> 
>   arm64: tegra: Enable SMMU support for USB on Tegra194 (2021-07-09 16:50:44 +0200)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.14-rc3-arm64-dt
> 
> [...]

Merged into arm/fixes, thanks!

merge commit: 79e48a21045e6f2ccd9f59737685336d9ad75d54

       Arnd


From arnd at kernel.org  Mon Aug  2 06:33:59 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 15:33:59 +0200
Subject: [GIT PULL 1/3] Renesas ARM DT updates for v5.15
In-Reply-To: <cover.1627650696.git.geert+renesas@glider.be>
References: <cover.1627650695.git.geert+renesas@glider.be>
 <cover.1627650696.git.geert+renesas@glider.be>
Message-ID: <162791122493.1140356.14062105755897419012.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 30 Jul 2021 15:18:54 +0200, Geert Uytterhoeven wrote:
> The following changes since commit 2734d6c1b1a089fb593ef6a23d4b70903526fe0c:
> 
>   Linux 5.14-rc2 (2021-07-18 14:13:49 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-arm-dt-for-v5.15-tag1
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 272614ec1b6bde9ab56bf8c9a71c4ff9ccf2eff8

       Arnd


From arnd at kernel.org  Mon Aug  2 06:34:00 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 15:34:00 +0200
Subject: [GIT PULL 3/3] Renesas DT binding updates for v5.15
In-Reply-To: <cover.1627650706.git.geert+renesas@glider.be>
References: <cover.1627650695.git.geert+renesas@glider.be>
 <cover.1627650706.git.geert+renesas@glider.be>
Message-ID: <162791122501.1140356.6236184546400456466.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 30 Jul 2021 15:18:56 +0200, Geert Uytterhoeven wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-dt-bindings-for-v5.15-tag1
> 
> [...]

Merged into arm/dt, thanks!

merge commit: c4994975132eb2488ad1259c273812ae38f5fccd

       Arnd


From arnd at kernel.org  Mon Aug  2 06:34:27 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 15:34:27 +0200
Subject: [GIT PULL 2/3] Renesas driver updates for v5.15
In-Reply-To: <cover.1627650704.git.geert+renesas@glider.be>
References: <cover.1627650695.git.geert+renesas@glider.be>
 <cover.1627650704.git.geert+renesas@glider.be>
Message-ID: <162791126361.1140492.15958129543143485091.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 30 Jul 2021 15:18:55 +0200, Geert Uytterhoeven wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-drivers-for-v5.15-tag1
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: b6e952c35267b8da9a402f2f0c9ea23d5d929774

       Arnd


From dsahern at gmail.com  Mon Aug  2 06:35:39 2021
From: dsahern at gmail.com (David Ahern)
Date: Mon, 2 Aug 2021 07:35:39 -0600
Subject: [PATCH net-next v2] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <20210802124039.13231-1-rocco.yue@mediatek.com>
References: <20210802031924.3256-1-rocco.yue@mediatek.com>
 <20210802124039.13231-1-rocco.yue@mediatek.com>
Message-ID: <c20aa306-81a9-f083-25e8-85002063b4cc@gmail.com>

On 8/2/21 6:40 AM, Rocco Yue wrote:
> On Sat, 2021-07-31 at 11:17 -0600, David Ahern wrote:
> On 7/30/21 7:52 PM, Rocco Yue wrote:
> 
>> IFLA_INET6_RA_MTU set. You can set "reject_message" in the policy to
>> return a message that "IFLA_INET6_RA_MTU can not be set".
> 
> Hi David,
> 
> Regarding setting "reject_message" in the policy, after reviewing
> the code, I fell that it is unnecessary, because the cost of
> implementing it seems to be a bit high, which requires modifying
> the function interface. The reasons is as follows:

The policy can be setup now to do the right thing once the extack
argument is available.

do_setlink() has an extack argument. It calls validate_linkmsg which
calls validate_link_af meaning support can be added in a single patch.
If you decide to do it, then it should be a separate patch preceding
this one.


From olteanv at gmail.com  Mon Aug  2 06:36:13 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 2 Aug 2021 16:36:13 +0300
Subject: [RFC net-next v2 2/4] net: dsa: mt7530: use independent VLAN
 learning on VLAN-unaware bridges
In-Reply-To: <20210731191023.1329446-3-dqfext@gmail.com>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-3-dqfext@gmail.com>
Message-ID: <20210802133613.aeyduvt6qvy2ei7r@skbuf>

On Sun, Aug 01, 2021 at 03:10:20AM +0800, DENG Qingfang wrote:
> Consider the following bridge configuration, where bond0 is not
> offloaded:
> 
>          +-- br0 --+
>         / /   |     \
>        / /    |      \
>       /  |    |     bond0
>      /   |    |     /   \
>    swp0 swp1 swp2 swp3 swp4
>      .        .       .
>      .        .       .
>      A        B       C
> 
> Ideally, when the switch receives a packet from swp3 or swp4, it should
> forward the packet to the CPU, according to the port matrix and unknown
> unicast flood settings.
> 
> But packet loss will happen if the destination address is at one of the
> offloaded ports (swp0~2). For example, when client C sends a packet to
> A, the FDB lookup will indicate that it should be forwarded to swp0, but
> the port matrix of swp3 and swp4 is configured to only allow the CPU to
> be its destination, so it is dropped.
> 
> However, this issue does not happen if the bridge is VLAN-aware. That is
> because VLAN-aware bridges use independent VLAN learning, i.e. use VID
> for FDB lookup, on offloaded ports. As swp3 and swp4 are not offloaded,
> shared VLAN learning with default filter ID of 0 is used instead. So the
> lookup for A with filter ID 0 never hits and the packet can be forwarded
> to the CPU.
> 
> In the current code, only two combinations were used to toggle user
> ports' VLAN awareness: one is PCR.PORT_VLAN set to port matrix mode with
> PVC.VLAN_ATTR set to transparent port, the other is PCR.PORT_VLAN set to
> security mode with PVC.VLAN_ATTR set to user port.
> 
> It turns out that only PVC.VLAN_ATTR contributes to VLAN awareness, and
> port matrix mode just skips the VLAN table lookup. The reference manual
> is somehow misleading when describing PORT_VLAN modes. It states that
> PORT_MEM (VLAN port member) is used for destination if the VLAN table
> lookup hits, but actually **PORT_MEM & PORT_MATRIX** (bitwise AND of
> VLAN port member and port matrix) is used instead, which means we can
> have two or more separate VLAN-aware bridges with the same PVID and
> traffic won't leak between them.

"traffic won't leak" is only half the story. It won't leak, but when
multiple VLAN-unaware bridges share the same FID, they are still subject
to shortcircuit attempts if the same MAC address is present in the FDB
of both bridges. This patch doesn't solve that, maybe it is worth adding
a big comment in the code itself that clarifies that FDBs between
multiple VLAN-unaware bridges, as well as between multiple VLAN-aware
bridges, are not isolated per se, only that standalone ports are placed
under a different FID compared to bridges of whatever kind.

> 
> Therefore, to solve this, enable independent VLAN learning with PVID 0
> on VLAN-unaware bridges, by setting their PCR.PORT_VLAN to fallback
> mode, while leaving standalone ports in port matrix mode. The CPU port
> is always set to fallback mode to serve those bridges.
> 
> During testing, it is found that FDB lookup with filter ID of 0 will
> also hit entries with VID 0 even with independent VLAN learning. To
> avoid that, install all VLANs with filter ID of 1.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
>  drivers/net/dsa/mt7530.c | 70 ++++++++++++++++++++++++++++------------
>  drivers/net/dsa/mt7530.h |  4 ++-
>  2 files changed, 53 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 7e7e0a35e351..3876e265f844 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -1021,6 +1021,10 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
>  	mt7530_write(priv, MT7530_PCR_P(port),
>  		     PCR_MATRIX(dsa_user_ports(priv->ds)));
>  
> +	/* Set to fallback mode for independent VLAN learning */
> +	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
> +		   MT7530_PORT_FALLBACK_MODE);
> +
>  	return 0;
>  }
>  
> @@ -1229,6 +1233,10 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
>  			   PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
>  	priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
>  
> +	/* Set to fallback mode for independent VLAN learning */
> +	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
> +		   MT7530_PORT_FALLBACK_MODE);
> +
>  	mutex_unlock(&priv->reg_mutex);
>  
>  	return 0;
> @@ -1241,16 +1249,21 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
>  	bool all_user_ports_removed = true;
>  	int i;
>  
> -	/* When a port is removed from the bridge, the port would be set up
> -	 * back to the default as is at initial boot which is a VLAN-unaware
> -	 * port.
> +	/* This is called after .port_bridge_leave when leaving a VLAN-aware
> +	 * bridge. Don't set standalone ports to fallback mode.
>  	 */
> -	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
> -		   MT7530_PORT_MATRIX_MODE);
> +	if (dsa_to_port(ds, port)->bridge_dev)
> +		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
> +			   MT7530_PORT_FALLBACK_MODE);
> +

hmm, okay, the ordering between dsa_broadcast() and
dsa_port_switchdev_unsync_attrs() in dsa_port_bridge_leave() is a bit
awkward for you, but this looks okay.

>  	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
>  		   VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
>  		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
>  
> +	/* Set PVID to 0 */
> +	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
> +		   G0_PORT_VID_DEF);
> +
>  	for (i = 0; i < MT7530_NUM_PORTS; i++) {
>  		if (dsa_is_user_port(ds, i) &&
>  		    dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
> @@ -1276,15 +1289,14 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
>  	struct mt7530_priv *priv = ds->priv;
>  
>  	/* Trapped into security mode allows packet forwarding through VLAN
> -	 * table lookup. CPU port is set to fallback mode to let untagged
> -	 * frames pass through.
> +	 * table lookup.
>  	 */
> -	if (dsa_is_cpu_port(ds, port))
> -		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
> -			   MT7530_PORT_FALLBACK_MODE);
> -	else
> +	if (dsa_is_user_port(ds, port)) {
>  		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
>  			   MT7530_PORT_SECURITY_MODE);
> +		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
> +			   G0_PORT_VID(priv->ports[port].pvid));
> +	}
>  
>  	/* Set the port as a user port which is to be able to recognize VID
>  	 * from incoming packets before fetching entry within the VLAN table.
> @@ -1329,6 +1341,13 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
>  			   PCR_MATRIX(BIT(MT7530_CPU_PORT)));
>  	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
>  
> +	/* When a port is removed from the bridge, the port would be set up
> +	 * back to the default as is at initial boot which is a VLAN-unaware
> +	 * port.
> +	 */
> +	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
> +		   MT7530_PORT_MATRIX_MODE);
> +
>  	mutex_unlock(&priv->reg_mutex);
>  }
>  
> @@ -1511,7 +1530,7 @@ mt7530_hw_vlan_add(struct mt7530_priv *priv,
>  	/* Validate the entry with independent learning, create egress tag per
>  	 * VLAN and joining the port as one of the port members.
>  	 */
> -	val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | VLAN_VALID;
> +	val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | FID(1) | VLAN_VALID;
>  	mt7530_write(priv, MT7530_VAWD1, val);
>  
>  	/* Decide whether adding tag or not for those outgoing packets from the
> @@ -1601,9 +1620,13 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
>  	mt7530_hw_vlan_update(priv, vlan->vid, &new_entry, mt7530_hw_vlan_add);
>  
>  	if (pvid) {
> -		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
> -			   G0_PORT_VID(vlan->vid));
>  		priv->ports[port].pvid = vlan->vid;
> +
> +		/* Only configure PVID if VLAN filtering is enabled */
> +		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
> +			mt7530_rmw(priv, MT7530_PPBV1_P(port),
> +				   G0_PORT_VID_MASK,
> +				   G0_PORT_VID(vlan->vid));
>  	}
>  
>  	mutex_unlock(&priv->reg_mutex);
> @@ -1617,11 +1640,9 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
>  {
>  	struct mt7530_hw_vlan_entry target_entry;
>  	struct mt7530_priv *priv = ds->priv;
> -	u16 pvid;
>  
>  	mutex_lock(&priv->reg_mutex);
>  
> -	pvid = priv->ports[port].pvid;
>  	mt7530_hw_vlan_entry_init(&target_entry, port, 0);
>  	mt7530_hw_vlan_update(priv, vlan->vid, &target_entry,
>  			      mt7530_hw_vlan_del);
> @@ -1629,11 +1650,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
>  	/* PVID is being restored to the default whenever the PVID port
>  	 * is being removed from the VLAN.
>  	 */
> -	if (pvid == vlan->vid)
> -		pvid = G0_PORT_VID_DEF;
> +	if (priv->ports[port].pvid == vlan->vid) {
> +		priv->ports[port].pvid = G0_PORT_VID_DEF;
> +		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
> +			   G0_PORT_VID_DEF);
> +	}
>  
> -	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, pvid);
> -	priv->ports[port].pvid = pvid;
>  
>  	mutex_unlock(&priv->reg_mutex);
>  
> @@ -2134,6 +2156,10 @@ mt7530_setup(struct dsa_switch *ds)
>  				return ret;
>  		} else {
>  			mt7530_port_disable(ds, i);
> +
> +			/* Set default PVID to 0 on all user ports */
> +			mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
> +				   G0_PORT_VID_DEF);
>  		}
>  		/* Enable consistent egress tag */
>  		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
> @@ -2301,6 +2327,10 @@ mt7531_setup(struct dsa_switch *ds)
>  				return ret;
>  		} else {
>  			mt7530_port_disable(ds, i);
> +
> +			/* Set default PVID to 0 on all user ports */
> +			mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
> +				   G0_PORT_VID_DEF);
>  		}
>  
>  		/* Enable consistent egress tag */
> diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
> index b19b389ff10a..a308886fdebc 100644
> --- a/drivers/net/dsa/mt7530.h
> +++ b/drivers/net/dsa/mt7530.h
> @@ -148,6 +148,8 @@ enum mt7530_vlan_cmd {
>  #define  VTAG_EN			BIT(28)
>  /* VLAN Member Control */
>  #define  PORT_MEM(x)			(((x) & 0xff) << 16)
> +/* Filter ID */
> +#define  FID(x)				(((x) & 0x7) << 1)
>  /* VLAN Entry Valid */
>  #define  VLAN_VALID			BIT(0)
>  #define  PORT_MEM_SHFT			16
> @@ -247,7 +249,7 @@ enum mt7530_vlan_port_attr {
>  #define MT7530_PPBV1_P(x)		(0x2014 + ((x) * 0x100))
>  #define  G0_PORT_VID(x)			(((x) & 0xfff) << 0)
>  #define  G0_PORT_VID_MASK		G0_PORT_VID(0xfff)
> -#define  G0_PORT_VID_DEF		G0_PORT_VID(1)
> +#define  G0_PORT_VID_DEF		G0_PORT_VID(0)
>  
>  /* Register for port MAC control register */
>  #define MT7530_PMCR_P(x)		(0x3000 + ((x) * 0x100))
> -- 
> 2.25.1
> 

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From dsahern at gmail.com  Mon Aug  2 06:37:08 2021
From: dsahern at gmail.com (David Ahern)
Date: Mon, 2 Aug 2021 07:37:08 -0600
Subject: [PATCH net-next v2] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <20210802031924.3256-1-rocco.yue@mediatek.com>
References: <5be90cf4-f603-c2f2-fd7e-3886854457ba@gmail.com>
 <20210802031924.3256-1-rocco.yue@mediatek.com>
Message-ID: <f66750af-cbda-6d49-2b39-860c10357e95@gmail.com>

On 8/1/21 9:19 PM, Rocco Yue wrote:
> On Sat, 2021-07-31 at 11:17 -0600, David Ahern wrote:
> On 7/30/21 7:52 PM, Rocco Yue wrote:
>>> In this way, if the MTU values that the device receives from
>>> the network in the PCO IPv4 and the RA IPv6 procedures are
>>> different, the user space process can read ra_mtu to get
>>> the mtu value carried in the RA message without worrying
>>> about the issue of ipv4 being stuck due to the late arrival
>>> of RA message. After comparing the value of ra_mtu and ipv4
>>> mtu, then the device can use the lower MTU value for both
>>> IPv4 and IPv6.
>>
>> you are storing the value and sending to userspace but never using it
>> when sending a message. What's the pointing of processing the MTU in the
>> RA if you are not going to use it to control message size?
> 
> Hi David,
> 
> In the requirement of mobile operator at&t in 2021:
> AT&T <CDR-CDS-116> Prioritize Lower MTU value:
> If the MTU values that the device receives from the network in the PCO
> IPv4 <CDR-CDS-110> and the RA IPv6 <CDR-CDS-112> procedures are different,
> then the device shall use the lower MTU value for both IPv4 and IPv6.
> 
> And in the 3GPP 23.060:
> The PDP PDUs shall be routed and transferred between the MS and the GGSN
> or P-GW as N-PDUs. In order to avoid IP layer fragmentation between the
> MS and the GGSN or P-GW, the link MTU size in the MS should be set to the
> value provided by the network as a part of the IP configuration. This
> applies to both IPv6 and IPv4.
> 
> That means user needs to be able to correctly read the mtu value carried
> in the RA message so that user can correctly compare PCO ipv4 mtu and
> RA ipv6 mtu.
> 

Then userspace should get a link notification when ra_mtu is set so it
does not have to poll.


From maz at kernel.org  Mon Aug  2 06:39:10 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Aug 2021 14:39:10 +0100
Subject: [PATCH v2 0/4] kvm-arm64: Fix PMU reset values (and more)
In-Reply-To: <20210719123902.1493805-1-maz@kernel.org>
References: <20210719123902.1493805-1-maz@kernel.org>
Message-ID: <162791148977.3441299.3278138161976148684.b4-ty@kernel.org>

On Mon, 19 Jul 2021 13:38:58 +0100, Marc Zyngier wrote:
> This is the second version of the series initially posted at [1].
> 
> * From v1:
>   - Simplified masking in patch #1
>   - Added a patch dropping PMSWINC_EL0 as a shadow register, though it
>     is still advertised to userspace for the purpose of backward
>     compatibility of VM save/restore
>   - Collected ABs/RBs, with thanks
> 
> [...]

Applied to next, thanks!

[1/4] KVM: arm64: Narrow PMU sysreg reset values to architectural requirements
      commit: 0ab410a93d627ae73136d1a52c096262360b7992
[2/4] KVM: arm64: Drop unnecessary masking of PMU registers
      commit: f5eff40058a856c23c5ec2f31756f107a2b1ef84
[3/4] KVM: arm64: Disabling disabled PMU counters wastes a lot of time
      commit: ca4f202d08ba7f24cc97dce14c6d20ec7a679135
[4/4] KVM: arm64: Remove PMSWINC_EL0 shadow register
      commit: 7a3ba3095a32f9c4ec8f30d680fea5150e12c3f3

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From robh at kernel.org  Mon Aug  2 06:39:43 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 02 Aug 2021 07:39:43 -0600
Subject: [PATCH 4/5 v2] pata: ixp4xx: Add DT bindings
In-Reply-To: <20210731213555.2965356-4-linus.walleij@linaro.org>
References: <20210731213555.2965356-1-linus.walleij@linaro.org>
 <20210731213555.2965356-4-linus.walleij@linaro.org>
Message-ID: <1627911583.076118.918763.nullmailer@robh.at.kernel.org>

On Sat, 31 Jul 2021 23:35:54 +0200, Linus Walleij wrote:
> This adds device tree bindings for the Intel IXP4xx compact flash card
> interface.
> 
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> ChangeLog v1->v2:
> - Itemize the registers
> - Drop the epansion bus set-up to alleviate warnings
> ---
>  .../ata/intel,ixp4xx-compact-flash.yaml       | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.example.dt.yaml:0:0: /example-0/bus at c4000000: failed to match any schema with compatible: ['intel,ixp43x-expansion-bus-controller', 'syscon']
\ndoc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1511976

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From maz at kernel.org  Mon Aug  2 06:39:51 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Aug 2021 14:39:51 +0100
Subject: [PATCH v2 0/6] KVM: Remove kvm_is_transparent_hugepage() and
 friends
In-Reply-To: <20210726153552.1535838-1-maz@kernel.org>
References: <20210726153552.1535838-1-maz@kernel.org>
Message-ID: <162791157466.3441503.3535158079584793741.b4-ty@kernel.org>

On Mon, 26 Jul 2021 16:35:46 +0100, Marc Zyngier wrote:
> A while ago, Willy and Sean pointed out[0] that arm64 is the last user
> of kvm_is_transparent_hugepage(), and that there would actually be
> some benefit in looking at the userspace mapping directly instead.
> 
> This small series does exactly that, although it doesn't try to
> support more than a PMD-sized mapping yet for THPs. We could probably
> look into unifying this with the huge PUD code, and there is still
> some potential use of the contiguous hint.
> 
> [...]

Applied to next, thanks!

[1/6] KVM: arm64: Introduce helper to retrieve a PTE and its level
      commit: 63db506e07622c344a3c748a1c06293d48780f83
[2/6] KVM: arm64: Walk userspace page tables to compute the THP mapping size
      commit: 6011cf68c88545e16cb32039c2cecfdae6a32315
[3/6] KVM: arm64: Avoid mapping size adjustment on permission fault
      commit: f2cc327303b13a70311e823bd52aa0bca8c7ddbc
[4/6] KVM: Remove kvm_is_transparent_hugepage() and PageTransCompoundMap()
      commit: 205d76ff0684a0b4fe3ff3a283d143a47439d191
[5/6] KVM: arm64: Use get_page() instead of kvm_get_pfn()
      commit: 0fe49630101b3ce23bd21a2788440ac719ec868a
[6/6] KVM: Get rid of kvm_get_pfn()
      commit: 36c3ce6c0d03a6c9992c3359f879cdc70fde836a

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From olteanv at gmail.com  Mon Aug  2 06:43:36 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 2 Aug 2021 16:43:36 +0300
Subject: [RFC net-next v2 3/4] net: dsa: mt7530: set STP state also on
 filter ID 1
In-Reply-To: <20210731191023.1329446-4-dqfext@gmail.com>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-4-dqfext@gmail.com>
Message-ID: <20210802134336.gv66le6u2z52kfkh@skbuf>

On Sun, Aug 01, 2021 at 03:10:21AM +0800, DENG Qingfang wrote:
> As filter ID 1 is used, set STP state also on it.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
>  drivers/net/dsa/mt7530.c | 3 ++-
>  drivers/net/dsa/mt7530.h | 2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 3876e265f844..38d6ce37d692 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -1147,7 +1147,8 @@ mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
>  		break;
>  	}
>  
> -	mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK, stp_state);
> +	mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK,
> +		   FID_PST(stp_state));
>  }
>  
>  static int
> diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
> index a308886fdebc..294ff1cbd9e0 100644
> --- a/drivers/net/dsa/mt7530.h
> +++ b/drivers/net/dsa/mt7530.h
> @@ -181,7 +181,7 @@ enum mt7530_vlan_egress_attr {
>  
>  /* Register for port STP state control */
>  #define MT7530_SSP_P(x)			(0x2000 + ((x) * 0x100))
> -#define  FID_PST(x)			((x) & 0x3)

Shouldn't these macros have _two_ arguments, the FID and the port state?

> +#define  FID_PST(x)			(((x) & 0x3) * 0x5)

"* 5": explanation?

>  #define  FID_PST_MASK			FID_PST(0x3)
>  
>  enum mt7530_stp_state {
> -- 
> 2.25.1
> 

I don't exactly understand how this patch works, sorry.
Are you altering port state only on bridged ports, or also on standalone
ports after this patch? Are standalone ports in the proper STP state
(FORWARDING)?


From olteanv at gmail.com  Mon Aug  2 06:44:09 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 2 Aug 2021 16:44:09 +0300
Subject: [RFC net-next v2 4/4] Revert "mt7530 mt7530_fdb_write only set
 ivl bit vid larger than 1"
In-Reply-To: <20210731191023.1329446-5-dqfext@gmail.com>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-5-dqfext@gmail.com>
Message-ID: <20210802134409.dro5zjp5ymocpglf@skbuf>

On Sun, Aug 01, 2021 at 03:10:22AM +0800, DENG Qingfang wrote:
> This reverts commit 7e777021780e9c373fc0c04d40b8407ce8c3b5d5.
> 
> As independent VLAN learning is also used on VID 0 and 1, remove the
> special case.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
>  drivers/net/dsa/mt7530.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 38d6ce37d692..d72e04011cc5 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -366,8 +366,7 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
>  	int i;
>  
>  	reg[1] |= vid & CVID_MASK;
> -	if (vid > 1)
> -		reg[1] |= ATA2_IVL;
> +	reg[1] |= ATA2_IVL;
>  	reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
>  	reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
>  	/* STATIC_ENT indicate that entry is static wouldn't
> -- 
> 2.25.1
> 

Would you mind explaining what made VID 1 special in Eric's patch in the
first place?


From qperret at google.com  Mon Aug  2 06:47:28 2021
From: qperret at google.com (Quentin Perret)
Date: Mon, 2 Aug 2021 14:47:28 +0100
Subject: [PATCH v2 1/2] arm64: Move .hyp.rodata outside of the
 _sdata.._edata range
In-Reply-To: <87mtq00yqd.wl-maz@kernel.org>
References: <20210802123830.2195174-1-maz@kernel.org>
 <20210802123830.2195174-2-maz@kernel.org>
 <YQfu6+3uo6qlxrpv@google.com> <87mtq00yqd.wl-maz@kernel.org>
Message-ID: <YQf3cKjMa9rrGRqP@google.com>

On Monday 02 Aug 2021 at 14:20:42 (+0100), Marc Zyngier wrote:
> Hi Quentin,
> 
> On Mon, 02 Aug 2021 14:11:07 +0100,
> Quentin Perret <qperret at google.com> wrote:
> > 
> > Hi Marc,
> > 
> > On Monday 02 Aug 2021 at 13:38:29 (+0100), Marc Zyngier wrote:
> > > The HYP rodata section is currently lumped together with the BSS,
> > > which isn't exactly what is expected (it gets registered with
> > > kmemleak, for example).
> > > 
> > > Move it away so that it is actually marked RO. As an added
> > > benefit, it isn't registered with kmemleak anymore.
> > 
> > 2d7bf218ca73 ("KVM: arm64: Add .hyp.data..ro_after_init ELF section")
> > states explicitly that the hyp ro_after_init section should remain RW in
> > the host as it is expected to modify it before initializing EL2. But I
> > can't seem to trigger anything with this patch applied, so I'll look
> > into this a bit more.
> 
> The switch to RO happens quite late. And if the host was to actually
> try and change things there, it would be screwed anyway (we will have
> already removed the pages from its S2).

Yes, clearly mapping rodata RO in host happens much later than I
thought, so this should indeed be fine.

> I wouldn't be surprised if this was a consequence of the way we now
> build the HYP object, and the comment in the original commit may not
> be valid anymore.

Just had a quick look and that still seems valid, at least for some
things (e.g. see how we set hyp_cpu_logical_map[] early from EL1 while
it is clearly annotated as __ro_after_init in the EL2 code).

> > 
> > > Fixes: 380e18ade4a5 ("KVM: arm64: Introduce a BSS section for use at Hyp")
> > 
> > Not sure this is the patch to blame?
> 
> My bad, this is plain wrong. I'm not sure it can be applied earlier
> though if my rambling above is correct.

By the look of it going all the way back to 2d7bf218ca73 (in David's
PSCI proxy series) should actually be correct. But not sure if that's
really going to make a difference before the patch you've mentioned
above as the kmemleak issue will only be visible once we have a host
stage-2, so no big deal.

Thanks,
Quentin


From linux at roeck-us.net  Mon Aug  2 06:57:40 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 2 Aug 2021 06:57:40 -0700
Subject: [PATCH] spi: mediatek: Fix fifo transfer
In-Reply-To: <20210802030023.1748777-1-linux@roeck-us.net>
References: <20210802030023.1748777-1-linux@roeck-us.net>
Message-ID: <836776f1-5b8d-ba18-2bd7-3b21673a8b82@roeck-us.net>

On 8/1/21 8:00 PM, Guenter Roeck wrote:
> Commit 3a70dd2d0503 ("spi: mediatek: fix fifo rx mode") claims that
> fifo RX mode was never handled, and adds the presumably missing code
> to the FIFO transfer function. However, the claim that receive data
> was not handled is incorrect. It was handled as part of interrupt
> handling after the transfer was complete. The code added with the above
> mentioned commit reads data from the receive FIFO before the transfer
> is started, which is wrong. This results in an actual transfer error
> on a Hayato Chromebook.
> 
> Remove the code trying to handle receive data before the transfer is
> started to fix the problem.
> 
> Fixes: 3a70dd2d0503 ("spi: mediatek: fix fifo rx mode")
> Cc: Peter Hess <peter.hess at ph-home.de>
> Cc: Frank Wunderlich <frank-w at public-files.de>
> Cc: Tzung-Bi Shih <tzungbi at google.com>
> Cc: Hsin-Yi Wang <hsinyi at google.com>
> Signed-off-by: Guenter Roeck <linux at roeck-us.net>
> ---

I should have added here: If this patch isn't acceptable for some reason,
commit 3a70dd2d0503 should be reverted because it is obviously wrong
and introduces a severe regression.

Thanks,
Guenter

>   drivers/spi/spi-mt65xx.c | 19 +++++--------------
>   1 file changed, 5 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
> index 68dca8ceb3ad..7914255521c3 100644
> --- a/drivers/spi/spi-mt65xx.c
> +++ b/drivers/spi/spi-mt65xx.c
> @@ -426,24 +426,15 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
>   	mtk_spi_prepare_transfer(master, xfer);
>   	mtk_spi_setup_packet(master);
>   
> -	cnt = xfer->len / 4;
> -	if (xfer->tx_buf)
> +	if (xfer->tx_buf) {
> +		cnt = xfer->len / 4;
>   		iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt);
> -
> -	if (xfer->rx_buf)
> -		ioread32_rep(mdata->base + SPI_RX_DATA_REG, xfer->rx_buf, cnt);
> -
> -	remainder = xfer->len % 4;
> -	if (remainder > 0) {
> -		reg_val = 0;
> -		if (xfer->tx_buf) {
> +		remainder = xfer->len % 4;
> +		if (remainder > 0) {
> +			reg_val = 0;
>   			memcpy(&reg_val, xfer->tx_buf + (cnt * 4), remainder);
>   			writel(reg_val, mdata->base + SPI_TX_DATA_REG);
>   		}
> -		if (xfer->rx_buf) {
> -			reg_val = readl(mdata->base + SPI_RX_DATA_REG);
> -			memcpy(xfer->rx_buf + (cnt * 4), &reg_val, remainder);
> -		}
>   	}
>   
>   	mtk_spi_enable_transfer(master);
> 



From mike.leach at linaro.org  Mon Aug  2 07:04:14 2021
From: mike.leach at linaro.org (Mike Leach)
Date: Mon, 2 Aug 2021 15:04:14 +0100
Subject: [PATCH 2/6] perf cs-etm: Initialise architecture based on TRCIDR1
In-Reply-To: <20210731060312.GB7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-3-james.clark@arm.com>
 <CAJ9a7Viap53OgrM2e_DU4+oymFB41jspbKbvEVFQWROt7ifuXw@mail.gmail.com>
 <20210731060312.GB7437@leoy-ThinkPad-X240s>
Message-ID: <CAJ9a7VhdLaP3rkXwscAQpVe+jSgcx02WjY=RmiBkaCB6ObGTjQ@mail.gmail.com>

Hi Leo,

On Sat, 31 Jul 2021 at 07:03, Leo Yan <leo.yan at linaro.org> wrote:
>
> On Thu, Jul 22, 2021 at 12:10:35PM +0100, Mike Leach wrote:
> > HI James
> >
> > On Wed, 21 Jul 2021 at 10:07, James Clark <james.clark at arm.com> wrote:
> > >
> > > Currently the architecture is hard coded as ARCH_V8, but with the
> > > introduction of ETE we want to pick ARCH_AA64. And this change is also
> > > applicable to ETM v4.4 onwards as well.
> > >
> > > Signed-off-by: James Clark <james.clark at arm.com>
> > > ---
> > >  tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 14 +++++++++++++-
> > >  1 file changed, 13 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> > > index 30889a9d0165..5972a8afcc6b 100644
> > > --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> > > +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> > > @@ -126,6 +126,18 @@ static int cs_etm_decoder__gen_etmv3_config(struct cs_etm_trace_params *params,
> > >         return 0;
> > >  }
> > >
> > > +#define TRCIDR1_TRCARCHMIN_SHIFT 4
> > > +#define TRCIDR1_TRCARCHMIN_MASK  GENMASK(7, 4)
> > > +#define TRCIDR1_TRCARCHMIN(x)    (((x) & TRCIDR1_TRCARCHMIN_MASK) >> TRCIDR1_TRCARCHMIN_SHIFT)
> > > +static enum _ocsd_arch_version cs_etm_decoder__get_arch_ver(u32 reg_idr1)
> > > +{
> > > +       /*
> > > +        * If the ETM trace minor version is 4 or more then we can assume
> > > +        * the architecture is ARCH_AA64 rather than just V8
> > > +        */
> > > +       return TRCIDR1_TRCARCHMIN(reg_idr1) >= 4 ? ARCH_AA64 : ARCH_V8;
> > > +}
> >
> > This is true for ETM4.x & ETE 1.x (arch 5.x) but not ETM 3.x
> > Probably need to beef up this comment or the function name to emphasise this.
>
> Yeah, I think it's good to change the function name.  Eventually, this
> function should only be used for ETM4.x and ETE.
>
> Another minor comment is: can we refine the arch version number, e.g.
> change the OpenCSD's macro "ARCH_AA64" to "ARCH_V8R4", (or
> "ARCH_V8R3_AA64"), this can give more clear clue what's the ETM version.
>

The purpose of these macros is to inform the decoder of the
architecture of the PE - not the version of the ETM.

These OpenCSD macros are defined by the library headers
(ocsd_if_types.h) and not the perf headers.
These have been published as the API / ABI for OpenCSD and as such
changing them affects all OpenCSD clients, not just perf.

This PE architecture version is used along with the core profile to
determine which instructions are valid waypoint instructions to
associate with atom elements when walking the program image during
trace decode.

>From v8.3  onwards we moved away from filtering on specific
architecture versions. This was due to two factors:-
1. The architectural rules now allow architectural features for one
increment e.g. Arch 8.4, to be backported into  the previous increment
- e,g, 8.3, which made this filtering more difficult to track.
2. After discussion with the PE architects it was clear that
instructions in a later architect version would not re-use older
opcodes from a previous one and  be nop / invalid in the earlier
architectures. (certainly in the scope of AA64). Therefore
the policy in the decoder is to check for all the instructions we know
about for the latest version of architecture, even if we could be
decoding an earlier architecture version. This means we may check for
a few more opcodes than necessary for earlier version of the
architecture, but the overall decode is more robust and easier to
maintain.

Therefore for any AA64 core beyond v8.3 - it is safe to use the
ARCH_AA64 PE architecture version and the decoder will handle it.

Regards

Mike

> And a nitpick: how about to change OpenCSD macro "ARCH_V8r3" to
> "ARCH_V8R3" and assign it for ETMv4.3 IPs.
>
> Thanks,
> Leo



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mark.rutland at arm.com  Mon Aug  2 07:07:29 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 15:07:29 +0100
Subject: [PATCH 0/4] arm64: entry: rework user return handling
Message-ID: <20210802140733.52716-1-mark.rutland@arm.com>

These patches (based on v5.14-rc3) rework the arm64 entry code,
converting the bulk of `ret_to_user` and `work_pending` assembly code to
C. This simplifies the code, and ensure that for each exception there is
a single assembly<->c transition, which may make it easier to handle
backtracing in future if metadata is necessary.

The bulk of the additions are comments added in patch 2, which clarify
the semantics of some helpers functions used during entry/exit.

There should be no functional change as a result of this series, other
than that backtraces starting within do_notify_resume() will now include
the exception handler for the exception the kernel was entered with,
rather than `ret_to_user` or `work_pending` as previously. This is
generally immaterial, but may make it easier to debug some issues where
knowing the original exception is helpful.

This series leaves handling of TFSRE0_EL1 and single-step in assembly,
to avoid clashing with concurrent MTE rework, and as moving this to C
will require some generic kernel infrastructure (e.g. arch_atomic
bitops) which is not yet in mainline. I intend to follow these up for
the next cycle.

The series can be found on my `arm64/entry/user-return-rework` branch on
kernel.org:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/entry/user-return-rework
  git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/entry/user-return-rework

Thanks,
Mark.

Mark Rutland (4):
  arm64: entry: consolidate entry/exit helpers
  arm64: entry: clarify entry/exit helpers
  arm64: entry: move bulk of ret_to_user to C
  arm64: entry: call exit_to_user_mode() from C

 arch/arm64/include/asm/exception.h |   5 +-
 arch/arm64/kernel/entry-common.c   | 219 ++++++++++++++++++++++++++-----------
 arch/arm64/kernel/entry.S          |  36 +-----
 arch/arm64/kernel/signal.c         |   3 +-
 4 files changed, 162 insertions(+), 101 deletions(-)

-- 
2.11.0



From mark.rutland at arm.com  Mon Aug  2 07:07:30 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 15:07:30 +0100
Subject: [PATCH 1/4] arm64: entry: consolidate entry/exit helpers
In-Reply-To: <20210802140733.52716-1-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
Message-ID: <20210802140733.52716-2-mark.rutland@arm.com>

To make the various entry/exit helpers easier to understand and easier
to compare, this patch moves all the entry/exit helpers to be adjacent
at the top of entry-common.c, rather than being spread out throughout
the file.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Joey Gouly <joey.gouly at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/entry-common.c | 84 ++++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 42 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index db8b2e2d02c2..6f7a98d8d60f 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -75,6 +75,24 @@ static void noinstr exit_to_kernel_mode(struct pt_regs *regs)
 	}
 }
 
+asmlinkage void noinstr enter_from_user_mode(void)
+{
+	lockdep_hardirqs_off(CALLER_ADDR0);
+	CT_WARN_ON(ct_state() != CONTEXT_USER);
+	user_exit_irqoff();
+	trace_hardirqs_off_finish();
+}
+
+asmlinkage void noinstr exit_to_user_mode(void)
+{
+	mte_check_tfsr_exit();
+
+	trace_hardirqs_on_prepare();
+	lockdep_hardirqs_on_prepare(CALLER_ADDR0);
+	user_enter_irqoff();
+	lockdep_hardirqs_on(CALLER_ADDR0);
+}
+
 static void noinstr arm64_enter_nmi(struct pt_regs *regs)
 {
 	regs->lockdep_hardirqs = lockdep_hardirqs_enabled();
@@ -105,6 +123,30 @@ static void noinstr arm64_exit_nmi(struct pt_regs *regs)
 	__nmi_exit();
 }
 
+static void noinstr arm64_enter_el1_dbg(struct pt_regs *regs)
+{
+	regs->lockdep_hardirqs = lockdep_hardirqs_enabled();
+
+	lockdep_hardirqs_off(CALLER_ADDR0);
+	rcu_nmi_enter();
+
+	trace_hardirqs_off_finish();
+}
+
+static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)
+{
+	bool restore = regs->lockdep_hardirqs;
+
+	if (restore) {
+		trace_hardirqs_on_prepare();
+		lockdep_hardirqs_on_prepare(CALLER_ADDR0);
+	}
+
+	rcu_nmi_exit();
+	if (restore)
+		lockdep_hardirqs_on(CALLER_ADDR0);
+}
+
 static void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs)
 {
 	if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
@@ -265,30 +307,6 @@ static void noinstr el1_undef(struct pt_regs *regs)
 	exit_to_kernel_mode(regs);
 }
 
-static void noinstr arm64_enter_el1_dbg(struct pt_regs *regs)
-{
-	regs->lockdep_hardirqs = lockdep_hardirqs_enabled();
-
-	lockdep_hardirqs_off(CALLER_ADDR0);
-	rcu_nmi_enter();
-
-	trace_hardirqs_off_finish();
-}
-
-static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)
-{
-	bool restore = regs->lockdep_hardirqs;
-
-	if (restore) {
-		trace_hardirqs_on_prepare();
-		lockdep_hardirqs_on_prepare(CALLER_ADDR0);
-	}
-
-	rcu_nmi_exit();
-	if (restore)
-		lockdep_hardirqs_on(CALLER_ADDR0);
-}
-
 static void noinstr el1_dbg(struct pt_regs *regs, unsigned long esr)
 {
 	unsigned long far = read_sysreg(far_el1);
@@ -382,24 +400,6 @@ asmlinkage void noinstr el1h_64_error_handler(struct pt_regs *regs)
 	arm64_exit_nmi(regs);
 }
 
-asmlinkage void noinstr enter_from_user_mode(void)
-{
-	lockdep_hardirqs_off(CALLER_ADDR0);
-	CT_WARN_ON(ct_state() != CONTEXT_USER);
-	user_exit_irqoff();
-	trace_hardirqs_off_finish();
-}
-
-asmlinkage void noinstr exit_to_user_mode(void)
-{
-	mte_check_tfsr_exit();
-
-	trace_hardirqs_on_prepare();
-	lockdep_hardirqs_on_prepare(CALLER_ADDR0);
-	user_enter_irqoff();
-	lockdep_hardirqs_on(CALLER_ADDR0);
-}
-
 static void noinstr el0_da(struct pt_regs *regs, unsigned long esr)
 {
 	unsigned long far = read_sysreg(far_el1);
-- 
2.11.0



From mark.rutland at arm.com  Mon Aug  2 07:07:31 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 15:07:31 +0100
Subject: [PATCH 2/4] arm64: entry: clarify entry/exit helpers
In-Reply-To: <20210802140733.52716-1-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
Message-ID: <20210802140733.52716-3-mark.rutland@arm.com>

When entering an exception, we must perform irq/context state management
before we can use instrumentable C code. Similary, when exiting an
exception we cannot use instrumentable C code after we perform
irq/context state management.

Originally, we'd intended that the enter_from_*() and exit_to_*()
helpers would enforce this by virtue of being the first and last
functions called, respectively, in an exception handler. However, as
they now call instrumentable code themselves, this is not as clearly
true.

To make this more robust, this patch splits the irq/context state
management into separate helpers, with all the helpers commented to make
their intended purpose more obvious.

In exit_to_kernel_mode() we'll now check TFSR_EL1 before we assert that
IRQs are disabled, but this ordering is not important, and other than
this there should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Joey Gouly <joey.gouly at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/entry-common.c | 70 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 63 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 6f7a98d8d60f..6dc64f99f185 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -26,10 +26,14 @@
 #include <asm/system_misc.h>
 
 /*
+ * Handle IRQ/context state management when entering from kernel mode.
+ * Before this function is called it is not safe to call regular kernel code,
+ * intrumentable code, or any code which may trigger an exception.
+ *
  * This is intended to match the logic in irqentry_enter(), handling the kernel
  * mode transitions only.
  */
-static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
+static __always_inline void __enter_from_kernel_mode(struct pt_regs *regs)
 {
 	regs->exit_rcu = false;
 
@@ -45,20 +49,26 @@ static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
 	lockdep_hardirqs_off(CALLER_ADDR0);
 	rcu_irq_enter_check_tick();
 	trace_hardirqs_off_finish();
+}
 
+static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
+{
+	__enter_from_kernel_mode(regs);
 	mte_check_tfsr_entry();
 }
 
 /*
+ * Handle irq/context state management when exiting to kernel mode.
+ * after this function returns it is not safe to call regular kernel code,
+ * intrumentable code, or any code which may trigger an exception.
+ *
  * This is intended to match the logic in irqentry_exit(), handling the kernel
  * mode transitions only, and with preemption handled elsewhere.
  */
-static void noinstr exit_to_kernel_mode(struct pt_regs *regs)
+static __always_inline void __exit_to_kernel_mode(struct pt_regs *regs)
 {
 	lockdep_assert_irqs_disabled();
 
-	mte_check_tfsr_exit();
-
 	if (interrupts_enabled(regs)) {
 		if (regs->exit_rcu) {
 			trace_hardirqs_on_prepare();
@@ -75,7 +85,18 @@ static void noinstr exit_to_kernel_mode(struct pt_regs *regs)
 	}
 }
 
-asmlinkage void noinstr enter_from_user_mode(void)
+static void noinstr exit_to_kernel_mode(struct pt_regs *regs)
+{
+	mte_check_tfsr_exit();
+	__exit_to_kernel_mode(regs);
+}
+
+/*
+ * Handle IRQ/context state management when entering from user mode.
+ * Before this function is called it is not safe to call regular kernel code,
+ * intrumentable code, or any code which may trigger an exception.
+ */
+static __always_inline void __enter_from_user_mode(void)
 {
 	lockdep_hardirqs_off(CALLER_ADDR0);
 	CT_WARN_ON(ct_state() != CONTEXT_USER);
@@ -83,9 +104,18 @@ asmlinkage void noinstr enter_from_user_mode(void)
 	trace_hardirqs_off_finish();
 }
 
-asmlinkage void noinstr exit_to_user_mode(void)
+asmlinkage void noinstr enter_from_user_mode(void)
+{
+	__enter_from_user_mode();
+}
+
+/*
+ * Handle IRQ/context state management when exiting to user mode.
+ * After this function returns it is not safe to call regular kernel code,
+ * intrumentable code, or any code which may trigger an exception.
+ */
+static __always_inline void __exit_to_user_mode(void)
 {
-	mte_check_tfsr_exit();
 
 	trace_hardirqs_on_prepare();
 	lockdep_hardirqs_on_prepare(CALLER_ADDR0);
@@ -93,6 +123,17 @@ asmlinkage void noinstr exit_to_user_mode(void)
 	lockdep_hardirqs_on(CALLER_ADDR0);
 }
 
+asmlinkage void noinstr exit_to_user_mode(void)
+{
+	mte_check_tfsr_exit();
+	__exit_to_user_mode();
+}
+
+/*
+ * Handle IRQ/context state management when entering an NMI from user/kernel
+ * mode. Before this function is called it is not safe to call regular kernel
+ * code, intrumentable code, or any code which may trigger an exception.
+ */
 static void noinstr arm64_enter_nmi(struct pt_regs *regs)
 {
 	regs->lockdep_hardirqs = lockdep_hardirqs_enabled();
@@ -106,6 +147,11 @@ static void noinstr arm64_enter_nmi(struct pt_regs *regs)
 	ftrace_nmi_enter();
 }
 
+/*
+ * Handle IRQ/context state management when exiting an NMI from user/kernel
+ * mode. After this function returns it is not safe to call regular kernel
+ * code, intrumentable code, or any code which may trigger an exception.
+ */
 static void noinstr arm64_exit_nmi(struct pt_regs *regs)
 {
 	bool restore = regs->lockdep_hardirqs;
@@ -123,6 +169,11 @@ static void noinstr arm64_exit_nmi(struct pt_regs *regs)
 	__nmi_exit();
 }
 
+/*
+ * Handle IRQ/context state management when entering a debug exception from
+ * kernel mode. Before this function is called it is not safe to call regular
+ * kernel code, intrumentable code, or any code which may trigger an exception.
+ */
 static void noinstr arm64_enter_el1_dbg(struct pt_regs *regs)
 {
 	regs->lockdep_hardirqs = lockdep_hardirqs_enabled();
@@ -133,6 +184,11 @@ static void noinstr arm64_enter_el1_dbg(struct pt_regs *regs)
 	trace_hardirqs_off_finish();
 }
 
+/*
+ * Handle IRQ/context state management when exiting a debug exception from
+ * kernel mode. After this function returns it is not safe to call regular
+ * kernel code, intrumentable code, or any code which may trigger an exception.
+ */
 static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)
 {
 	bool restore = regs->lockdep_hardirqs;
-- 
2.11.0



From mark.rutland at arm.com  Mon Aug  2 07:07:32 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 15:07:32 +0100
Subject: [PATCH 3/4] arm64: entry: move bulk of ret_to_user to C
In-Reply-To: <20210802140733.52716-1-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
Message-ID: <20210802140733.52716-4-mark.rutland@arm.com>

In `ret_to_user` we perform some conditional work depending on the
thread flags, then perform some IRQ/context tracking which is intended
to balance with the IRQ/context tracking performed in the entry C code.

For simplicity and consistency, it would be preferable to move this all
to C. As a step towards that, this patch moves the conditional work and
IRQ/context tracking into a C helper function. To aid bisectability,
this is called from the `ret_to_user` assembly, and a subsequent patch
will move the call to C code.

As local_daif_mask() handles all necessary tracing and PMR manipulation,
we no longer need to handle this explicitly. As we call
exit_to_user_mode() directly, the `user_enter_irqoff` macro is no longer
used, and can be removed. As enter_from_user_mode() and
exit_to_user_mode() are no longer called from assembly, these can be
made static, and as these are typically very small, they are marked
__always_inline to avoid the overhead of a function call.

For now, enablement of single-step is left in entry.S, and for this we
still need to read the flags in ret_to_user(). It is safe to read this
separately as TIF_SINGLESTEP is not part of _TIF_WORK_MASK.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Joey Gouly <joey.gouly at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/exception.h |  5 +++--
 arch/arm64/kernel/entry-common.c   | 21 +++++++++++++++++++--
 arch/arm64/kernel/entry.S          | 36 +++---------------------------------
 arch/arm64/kernel/signal.c         |  3 +--
 4 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 4afbc45b8bb0..339477dca551 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -55,8 +55,8 @@ asmlinkage void el0t_32_error_handler(struct pt_regs *regs);
 
 asmlinkage void call_on_irq_stack(struct pt_regs *regs,
 				  void (*func)(struct pt_regs *));
-asmlinkage void enter_from_user_mode(void);
-asmlinkage void exit_to_user_mode(void);
+asmlinkage void asm_exit_to_user_mode(struct pt_regs *regs);
+
 void do_mem_abort(unsigned long far, unsigned int esr, struct pt_regs *regs);
 void do_undefinstr(struct pt_regs *regs);
 void do_bti(struct pt_regs *regs);
@@ -73,6 +73,7 @@ void do_el0_svc(struct pt_regs *regs);
 void do_el0_svc_compat(struct pt_regs *regs);
 void do_ptrauth_fault(struct pt_regs *regs, unsigned int esr);
 void do_serror(struct pt_regs *regs, unsigned int esr);
+void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags);
 
 void panic_bad_stack(struct pt_regs *regs, unsigned int esr, unsigned long far);
 #endif	/* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 6dc64f99f185..8ab4084d0f00 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -104,7 +104,7 @@ static __always_inline void __enter_from_user_mode(void)
 	trace_hardirqs_off_finish();
 }
 
-asmlinkage void noinstr enter_from_user_mode(void)
+static __always_inline void enter_from_user_mode(void)
 {
 	__enter_from_user_mode();
 }
@@ -123,12 +123,29 @@ static __always_inline void __exit_to_user_mode(void)
 	lockdep_hardirqs_on(CALLER_ADDR0);
 }
 
-asmlinkage void noinstr exit_to_user_mode(void)
+static __always_inline void exit_to_user_mode(void)
 {
 	mte_check_tfsr_exit();
 	__exit_to_user_mode();
 }
 
+static __always_inline void prepare_exit_to_user_mode(struct pt_regs *regs)
+{
+	unsigned long flags;
+
+	local_daif_mask();
+
+	flags = READ_ONCE(current_thread_info()->flags);
+	if (unlikely(flags & _TIF_WORK_MASK))
+		do_notify_resume(regs, flags);
+}
+
+asmlinkage void noinstr asm_exit_to_user_mode(struct pt_regs *regs)
+{
+	prepare_exit_to_user_mode(regs);
+	exit_to_user_mode();
+}
+
 /*
  * Handle IRQ/context state management when entering an NMI from user/kernel
  * mode. Before this function is called it is not safe to call regular kernel
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 863d44f73028..fe0a9bcc3e1f 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -29,16 +29,6 @@
 #include <asm/asm-uaccess.h>
 #include <asm/unistd.h>
 
-/*
- * Context tracking and irqflag tracing need to instrument transitions between
- * user and kernel mode.
- */
-	.macro user_enter_irqoff
-#if defined(CONFIG_CONTEXT_TRACKING) || defined(CONFIG_TRACE_IRQFLAGS)
-	bl	exit_to_user_mode
-#endif
-	.endm
-
 	.macro	clear_gp_regs
 	.irp	n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
 	mov	x\n, xzr
@@ -585,37 +575,17 @@ SYM_CODE_START_LOCAL(ret_to_kernel)
 	kernel_exit 1
 SYM_CODE_END(ret_to_kernel)
 
-/*
- * "slow" syscall return path.
- */
 SYM_CODE_START_LOCAL(ret_to_user)
-	disable_daif
-	gic_prio_kentry_setup tmp=x3
-#ifdef CONFIG_TRACE_IRQFLAGS
-	bl	trace_hardirqs_off
-#endif
-	ldr	x19, [tsk, #TSK_TI_FLAGS]
-	and	x2, x19, #_TIF_WORK_MASK
-	cbnz	x2, work_pending
-finish_ret_to_user:
-	user_enter_irqoff
+	mov	x0, sp
+	bl	asm_exit_to_user_mode
 	/* Ignore asynchronous tag check faults in the uaccess routines */
 	clear_mte_async_tcf
+	ldr	x19, [tsk, #TSK_TI_FLAGS]	// re-check for single-step
 	enable_step_tsk x19, x2
 #ifdef CONFIG_GCC_PLUGIN_STACKLEAK
 	bl	stackleak_erase
 #endif
 	kernel_exit 0
-
-/*
- * Ok, we need to do extra processing, enter the slow path.
- */
-work_pending:
-	mov	x0, sp				// 'regs'
-	mov	x1, x19
-	bl	do_notify_resume
-	ldr	x19, [tsk, #TSK_TI_FLAGS]	// re-check for single-step
-	b	finish_ret_to_user
 SYM_CODE_END(ret_to_user)
 
 	.popsection				// .entry.text
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index f8192f4ae0b8..53c2c85efb34 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -924,8 +924,7 @@ static bool cpu_affinity_invalid(struct pt_regs *regs)
 				 system_32bit_el0_cpumask());
 }
 
-asmlinkage void do_notify_resume(struct pt_regs *regs,
-				 unsigned long thread_flags)
+void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
 {
 	do {
 		if (thread_flags & _TIF_NEED_RESCHED) {
-- 
2.11.0



From mark.rutland at arm.com  Mon Aug  2 07:07:33 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 15:07:33 +0100
Subject: [PATCH 4/4] arm64: entry: call exit_to_user_mode() from C
In-Reply-To: <20210802140733.52716-1-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
Message-ID: <20210802140733.52716-5-mark.rutland@arm.com>

When handling an exception from EL0, we perform the entry work in that
exception's C handler, and once the C handler has finised, we return
back to the entry assembly. Subsequently in the common `ret_to_user`
assembly we perform the exit work that balances with the entry work.
This can be somewhat difficult to follow, and makes it hard to rework
the return paths (e.g. to pass additional context to the exit code, or
to have exception return logic for specific exceptions).

This patch reworks the entry code such that each EL0 C exception handler
is responsible for both the entry and exit work. This clearly balances
the two (and will permit additional variation in future), and avoids an
unnecessary bounce between assembly and C in the common case, leaving
`ret_from_fork` as the only place assembly has to call the exit code.
This means that the exit work is now inlined into the C handler, which
is already the case for the entry work, and allows the compiler to
generate better code (e.g. by immediately returning when there is no
exit work to perform).

To align with other exception entry/exit helpers, enter_from_user_mode()
is updated to take the EL0 pt_regs as a parameter, though this is
currently unused.

There should be no functional change as a result of this patch. However,
this should lead to slightly better backtraces when an error is
encountered within do_notify_resume(), as the C handler should appear in
the backtrace, indicating the specific exception that the kernel was
entered with.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Joey Gouly <joey.gouly at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/entry-common.c | 74 +++++++++++++++++++++++++---------------
 arch/arm64/kernel/entry.S        |  4 +--
 2 files changed, 48 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 8ab4084d0f00..9469f029da00 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -104,7 +104,7 @@ static __always_inline void __enter_from_user_mode(void)
 	trace_hardirqs_off_finish();
 }
 
-static __always_inline void enter_from_user_mode(void)
+static __always_inline void enter_from_user_mode(struct pt_regs *regs)
 {
 	__enter_from_user_mode();
 }
@@ -116,19 +116,12 @@ static __always_inline void enter_from_user_mode(void)
  */
 static __always_inline void __exit_to_user_mode(void)
 {
-
 	trace_hardirqs_on_prepare();
 	lockdep_hardirqs_on_prepare(CALLER_ADDR0);
 	user_enter_irqoff();
 	lockdep_hardirqs_on(CALLER_ADDR0);
 }
 
-static __always_inline void exit_to_user_mode(void)
-{
-	mte_check_tfsr_exit();
-	__exit_to_user_mode();
-}
-
 static __always_inline void prepare_exit_to_user_mode(struct pt_regs *regs)
 {
 	unsigned long flags;
@@ -140,10 +133,16 @@ static __always_inline void prepare_exit_to_user_mode(struct pt_regs *regs)
 		do_notify_resume(regs, flags);
 }
 
-asmlinkage void noinstr asm_exit_to_user_mode(struct pt_regs *regs)
+static __always_inline void exit_to_user_mode(struct pt_regs *regs)
 {
 	prepare_exit_to_user_mode(regs);
-	exit_to_user_mode();
+	mte_check_tfsr_exit();
+	__exit_to_user_mode();
+}
+
+asmlinkage void noinstr asm_exit_to_user_mode(struct pt_regs *regs)
+{
+	exit_to_user_mode(regs);
 }
 
 /*
@@ -477,9 +476,10 @@ static void noinstr el0_da(struct pt_regs *regs, unsigned long esr)
 {
 	unsigned long far = read_sysreg(far_el1);
 
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_mem_abort(far, esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_ia(struct pt_regs *regs, unsigned long esr)
@@ -494,37 +494,42 @@ static void noinstr el0_ia(struct pt_regs *regs, unsigned long esr)
 	if (!is_ttbr0_addr(far))
 		arm64_apply_bp_hardening();
 
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_mem_abort(far, esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_fpsimd_acc(struct pt_regs *regs, unsigned long esr)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_fpsimd_acc(esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_sve_acc(struct pt_regs *regs, unsigned long esr)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_sve_acc(esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_fpsimd_exc(struct pt_regs *regs, unsigned long esr)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_fpsimd_exc(esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_sys(struct pt_regs *regs, unsigned long esr)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_sysinstr(esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_pc(struct pt_regs *regs, unsigned long esr)
@@ -534,37 +539,42 @@ static void noinstr el0_pc(struct pt_regs *regs, unsigned long esr)
 	if (!is_ttbr0_addr(instruction_pointer(regs)))
 		arm64_apply_bp_hardening();
 
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_sp_pc_abort(far, esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_sp(struct pt_regs *regs, unsigned long esr)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_sp_pc_abort(regs->sp, esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_undef(struct pt_regs *regs)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_undefinstr(regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_bti(struct pt_regs *regs)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_bti(regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_inv(struct pt_regs *regs, unsigned long esr)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	bad_el0_sync(regs, 0, esr);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr)
@@ -572,23 +582,26 @@ static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr)
 	/* Only watchpoints write FAR_EL1, otherwise its UNKNOWN */
 	unsigned long far = read_sysreg(far_el1);
 
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	do_debug_exception(far, esr, regs);
 	local_daif_restore(DAIF_PROCCTX);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_svc(struct pt_regs *regs)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	cortex_a76_erratum_1463225_svc_handler();
 	do_el0_svc(regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_fpac(struct pt_regs *regs, unsigned long esr)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_ptrauth_fault(regs, esr);
+	exit_to_user_mode(regs);
 }
 
 asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs)
@@ -647,7 +660,7 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs)
 static void noinstr el0_interrupt(struct pt_regs *regs,
 				  void (*handler)(struct pt_regs *))
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 
 	write_sysreg(DAIF_PROCCTX_NOIRQ, daif);
 
@@ -655,6 +668,8 @@ static void noinstr el0_interrupt(struct pt_regs *regs,
 		arm64_apply_bp_hardening();
 
 	do_interrupt_handler(regs, handler);
+
+	exit_to_user_mode(regs);
 }
 
 static void noinstr __el0_irq_handler_common(struct pt_regs *regs)
@@ -681,12 +696,13 @@ static void noinstr __el0_error_handler_common(struct pt_regs *regs)
 {
 	unsigned long esr = read_sysreg(esr_el1);
 
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_ERRCTX);
 	arm64_enter_nmi(regs);
 	do_serror(regs, esr);
 	arm64_exit_nmi(regs);
 	local_daif_restore(DAIF_PROCCTX);
+	exit_to_user_mode(regs);
 }
 
 asmlinkage void noinstr el0t_64_error_handler(struct pt_regs *regs)
@@ -697,16 +713,18 @@ asmlinkage void noinstr el0t_64_error_handler(struct pt_regs *regs)
 #ifdef CONFIG_COMPAT
 static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	local_daif_restore(DAIF_PROCCTX);
 	do_cp15instr(esr, regs);
+	exit_to_user_mode(regs);
 }
 
 static void noinstr el0_svc_compat(struct pt_regs *regs)
 {
-	enter_from_user_mode();
+	enter_from_user_mode(regs);
 	cortex_a76_erratum_1463225_svc_handler();
 	do_el0_svc_compat(regs);
+	exit_to_user_mode(regs);
 }
 
 asmlinkage void noinstr el0t_32_sync_handler(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index fe0a9bcc3e1f..4b9bf685e0c0 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -576,8 +576,6 @@ SYM_CODE_START_LOCAL(ret_to_kernel)
 SYM_CODE_END(ret_to_kernel)
 
 SYM_CODE_START_LOCAL(ret_to_user)
-	mov	x0, sp
-	bl	asm_exit_to_user_mode
 	/* Ignore asynchronous tag check faults in the uaccess routines */
 	clear_mte_async_tcf
 	ldr	x19, [tsk, #TSK_TI_FLAGS]	// re-check for single-step
@@ -751,6 +749,8 @@ SYM_CODE_START(ret_from_fork)
 	mov	x0, x20
 	blr	x19
 1:	get_current_task tsk
+	mov	x0, sp
+	bl	asm_exit_to_user_mode
 	b	ret_to_user
 SYM_CODE_END(ret_from_fork)
 NOKPROBE(ret_from_fork)
-- 
2.11.0



From cniedermaier at dh-electronics.com  Mon Aug  2 07:10:32 2021
From: cniedermaier at dh-electronics.com (Christoph Niedermaier)
Date: Mon, 2 Aug 2021 16:10:32 +0200
Subject: [PATCH V7 1/7] ARM: dts: imx6q-dhcom: Use 1G ethernet on the PDK2
 board
Message-ID: <20210802141038.59663-1-cniedermaier@dh-electronics.com>

The PDK2 board is capable of running both 100M and 1G ethernet. However,
the i.MX6 has only one ethernet MAC, so it is possible to configure
either 100M or 1G Ethernet. In case of 100M option, the PHY is on the
SoM and the signals are routed to a RJ45 port. For 1G the PHY is on
the PDK2 board with another RJ45 port. 100M and 1G ethernet use
different signal pins from the i.MX6, but share the MDIO bus.

This SoM board combination is used to demonstrate how to enable 1G
ethernet configuration.

Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Fabio Estevam <festevam at denx.de>
Cc: Marek Vasut <marex at denx.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: kernel at dh-electronics.com
To: linux-arm-kernel at lists.infradead.org
---
V2: - Rebase on Shawn Guos branch for-next
V3: - Rework of the commit message
    - Remove superfluous property max-speed
V4: - No changes
V5: - No changes
V6: - Rebase on 5.14-rc1
V7: - Rebase on Shawn Guos branch for-next
    - Remove newline in fec node
---
 arch/arm/boot/dts/imx6q-dhcom-pdk2.dts | 50 ++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
index 224aa873e77c..3ed93a8e98fe 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
+++ b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
@@ -172,6 +172,45 @@
 	status = "disabled";
 };
 
+/* 1G ethernet */
+/delete-node/ &ethphy0;
+&fec {
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy7>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet_1G>;
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy7: ethernet-phy at 7 { /* KSZ 9021 */
+			compatible = "ethernet-phy-ieee802.3-c22";
+			interrupt-parent = <&gpio1>;
+			interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+			pinctrl-0 = <&pinctrl_ethphy7>;
+			pinctrl-names = "default";
+			reg = <7>;
+			reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <1000>;
+			reset-deassert-us = <1000>;
+			rxc-skew-ps = <3000>;
+			rxd0-skew-ps = <0>;
+			rxd1-skew-ps = <0>;
+			rxd2-skew-ps = <0>;
+			rxd3-skew-ps = <0>;
+			txc-skew-ps = <3000>;
+			txd0-skew-ps = <0>;
+			txd1-skew-ps = <0>;
+			txd2-skew-ps = <0>;
+			txd3-skew-ps = <0>;
+			rxdv-skew-ps = <0>;
+			txen-skew-ps = <0>;
+		};
+	};
+};
+
 &hdmi {
 	ddc-i2c-bus = <&i2c2>;
 	status = "okay";
@@ -254,9 +293,14 @@
 			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
 			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
 			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
-			MX6QDL_PAD_EIM_D29__GPIO3_IO29		0x000b0
-			MX6QDL_PAD_GPIO_0__GPIO1_IO00		0x000b1
-			MX6QDL_PAD_EIM_D26__GPIO3_IO26		0x000b1
+		>;
+	};
+
+	pinctrl_ethphy7: ethphy7-grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D29__GPIO3_IO29		0xb0 /* Reset */
+			MX6QDL_PAD_GPIO_0__GPIO1_IO00		0xb1 /* Int */
+			MX6QDL_PAD_EIM_D26__GPIO3_IO26		0xb1 /* WOL */
 		>;
 	};
 
-- 
2.11.0



From cniedermaier at dh-electronics.com  Mon Aug  2 07:10:33 2021
From: cniedermaier at dh-electronics.com (Christoph Niedermaier)
Date: Mon, 2 Aug 2021 16:10:33 +0200
Subject: [PATCH V7 2/7] ARM: dts: imx6q-dhcom: Rework of the DHCOM GPIO
 pinctrls
In-Reply-To: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
Message-ID: <20210802141038.59663-2-cniedermaier@dh-electronics.com>

The function of each SoM pins is defined in the DHCOM standard [1] and
subset of them is defined as GPIOs (pins A-W). To ensure the interchange-
ability of the DHCOM SoMs, the function of the pins are fixed and cannot
be changed. On board level the DHCOM GPIOs can be used associated with
different blocks e.g. for interrupt or reset, but the function is always
GPIO. If not used, they can be freely used in the user space.

Therefore the whole configuration of SoM pins is made in the SoM DT.
Defining the DHCOM GPIO pins as a separate pinctrl nodes makes moving a
subset of them to an appropriate block pinctrl group easier on board level,
since it is not necessary to have a large pinctrl hog group containing
unrelated pinmux entries on board level. This also makes it easy to update
the SoM DT without having to update all the board DTs too. If necessary it
is also possible to change the electrical properties of the DHCOM GPIOs by
overwriting the pinctrl on board level.

[1] https://wiki.dh-electronics.com/images/2/2e/DOC_DHCOM-Standard-Specification_R01_2016-11-17.pdf

Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Fabio Estevam <festevam at denx.de>
Cc: Marek Vasut <marex at denx.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: kernel at dh-electronics.com
To: linux-arm-kernel at lists.infradead.org
---
V2: - Rebase on Shawn Guos branch for-next
V3: - No changes
V4: - No changes
V5: - No changes
V6: - Rebase on 5.14-rc1
V7: - Rebase on Shawn Guos branch for-next
    - Rework of the commit message
---
 arch/arm/boot/dts/imx6q-dhcom-pdk2.dts | 105 ++++++++++++-------------------
 arch/arm/boot/dts/imx6q-dhcom-som.dtsi | 109 ++++++++++++++++++++++++++++++++-
 2 files changed, 148 insertions(+), 66 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
index 3ed93a8e98fe..3ea077ec8606 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
+++ b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
@@ -38,7 +38,7 @@
 		#size-cells = <0>;
 		interface-pix-fmt = "rgb24";
 		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_ipu1_lcdif>;
+		pinctrl-0 = <&pinctrl_ipu1_lcdif &pinctrl_dhcom_g>;
 		status = "okay";
 
 		port at 0 {
@@ -61,13 +61,13 @@
 	gpio-keys {
 		#size-cells = <0>;
 		compatible = "gpio-keys";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_keys_pdk2>;
 
 		button-0 {
 			label = "TA1-GPIO-A";
 			linux,code = <KEY_A>;
 			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			pinctrl-0 = <&pinctrl_dhcom_a>;
+			pinctrl-names = "default";
 			wakeup-source;
 		};
 
@@ -75,6 +75,8 @@
 			label = "TA2-GPIO-B";
 			linux,code = <KEY_B>;
 			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+			pinctrl-0 = <&pinctrl_dhcom_b>;
+			pinctrl-names = "default";
 			wakeup-source;
 		};
 
@@ -82,6 +84,8 @@
 			label = "TA3-GPIO-C";
 			linux,code = <KEY_C>;
 			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+			pinctrl-0 = <&pinctrl_dhcom_c>;
+			pinctrl-names = "default";
 			wakeup-source;
 		};
 
@@ -89,14 +93,14 @@
 			label = "TA4-GPIO-D";
 			linux,code = <KEY_D>;
 			gpios = <&gpio6 3 GPIO_ACTIVE_LOW>;
+			pinctrl-0 = <&pinctrl_dhcom_d>;
+			pinctrl-names = "default";
 			wakeup-source;
 		};
 	};
 
 	led {
 		compatible = "gpio-leds";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_leds_pdk2>;
 
 		/*
 		 * Disable led-5, because GPIO E is
@@ -107,6 +111,8 @@
 			function = LED_FUNCTION_INDICATOR;
 			gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* GPIO E */
 			default-state = "off";
+			pinctrl-0 = <&pinctrl_dhcom_e>;
+			pinctrl-names = "default";
 			status = "disabled";
 		};
 
@@ -115,6 +121,8 @@
 			function = LED_FUNCTION_INDICATOR;
 			gpios = <&gpio4 20 GPIO_ACTIVE_HIGH>; /* GPIO F */
 			default-state = "off";
+			pinctrl-0 = <&pinctrl_dhcom_f>;
+			pinctrl-names = "default";
 		};
 
 		led-7 {
@@ -122,6 +130,8 @@
 			function = LED_FUNCTION_INDICATOR;
 			gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* GPIO H */
 			default-state = "off";
+			pinctrl-0 = <&pinctrl_dhcom_h>;
+			pinctrl-names = "default";
 		};
 
 		led-8 {
@@ -129,6 +139,8 @@
 			function = LED_FUNCTION_INDICATOR;
 			gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */
 			default-state = "off";
+			pinctrl-0 = <&pinctrl_dhcom_i>;
+			pinctrl-names = "default";
 		};
 	};
 
@@ -228,7 +240,7 @@
 
 	touchscreen at 38 {
 		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_touchscreen>;
+		pinctrl-0 = <&pinctrl_dhcom_e>;
 		compatible = "edt,edt-ft5406";
 		reg = <0x38>;
 		interrupt-parent = <&gpio4>;
@@ -238,34 +250,28 @@
 
 &iomuxc {
 	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_hog_base &pinctrl_hog>;
-
-	pinctrl_hog: hog-grp {
-		fsl,pins = <
-			MX6QDL_PAD_GPIO_2__GPIO1_IO02		0x400120b0
-			MX6QDL_PAD_GPIO_4__GPIO1_IO04		0x400120b0
-			MX6QDL_PAD_GPIO_5__GPIO1_IO05		0x400120b0
-			MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03	0x400120b0
-			MX6QDL_PAD_DI0_PIN4__GPIO4_IO20		0x400120b0
-			MX6QDL_PAD_KEY_ROW0__GPIO4_IO07		0x120b0
-			MX6QDL_PAD_KEY_COL1__GPIO4_IO08		0x400120b0
-			MX6QDL_PAD_NANDF_CS1__GPIO6_IO14	0x400120b0
-			MX6QDL_PAD_NANDF_CS2__GPIO6_IO15	0x400120b0
-			MX6QDL_PAD_KEY_ROW1__GPIO4_IO09		0x400120b0
-			MX6QDL_PAD_SD3_DAT5__GPIO7_IO00		0x400120b0
-			MX6QDL_PAD_SD3_DAT4__GPIO7_IO01		0x400120b0
-			MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21	0x400120b0
-			MX6QDL_PAD_GPIO_18__GPIO7_IO13		0x400120b0
-			MX6QDL_PAD_SD1_CMD__GPIO1_IO18		0x400120b0
-			MX6QDL_PAD_SD1_DAT0__GPIO1_IO16		0x400120b0
-			MX6QDL_PAD_SD1_DAT1__GPIO1_IO17		0x400120b0
-			MX6QDL_PAD_SD1_DAT2__GPIO1_IO19		0x400120b0
-			MX6QDL_PAD_SD1_CLK__GPIO1_IO20		0x400120b0
-			MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18	0x400120b0
-			MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19	0x400120b0
-			MX6QDL_PAD_KEY_COL0__GPIO4_IO06		0x400120b0
+	pinctrl-0 = <
+			/*
+			 * The following DHCOM GPIOs are used on this board.
+			 * Therefore, they have been removed from the list below.
+			 * A: key TA1
+			 * B: key TA2
+			 * C: key TA3
+			 * D: key TA4
+			 * E: touchscreen
+			 * F: led6
+			 * G: backlight enable
+			 * H: led7
+			 * I: led8
+			 * J: PCIe reset
+			 */
+			&pinctrl_hog_base
+			&pinctrl_dhcom_k &pinctrl_dhcom_l
+			&pinctrl_dhcom_m &pinctrl_dhcom_n &pinctrl_dhcom_o
+			&pinctrl_dhcom_p &pinctrl_dhcom_q &pinctrl_dhcom_r
+			&pinctrl_dhcom_s &pinctrl_dhcom_t &pinctrl_dhcom_u
+			&pinctrl_dhcom_v &pinctrl_dhcom_w &pinctrl_dhcom_int
 		>;
-	};
 
 	pinctrl_audmux_ext: audmux-ext-grp {
 		fsl,pins = <
@@ -334,7 +340,6 @@
 			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21	0x38
 			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22	0x38
 			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23	0x38
-			MX6QDL_PAD_EIM_D27__GPIO3_IO27			0x120b0
 		>;
 	};
 
@@ -343,36 +348,6 @@
 			MX6QDL_PAD_SD1_DAT3__PWM1_OUT		0x1b0b1
 		>;
 	};
-
-	pinctrl_touchscreen: touchscreen-grp {
-		fsl,pins = <
-			MX6QDL_PAD_GPIO_19__GPIO4_IO05		0x1b0b1
-		>;
-	};
-
-	pinctrl_pcie_reset: pcie-reset-grp {
-		fsl,pins = <
-			MX6QDL_PAD_NANDF_CS1__GPIO6_IO14	0x120b0
-		>;
-	};
-
-	pinctrl_keys_pdk2: keys-pdk2-grp {
-		fsl,pins = <
-			MX6QDL_PAD_GPIO_2__GPIO1_IO02		0x120b0 /* TA1 */
-			MX6QDL_PAD_GPIO_4__GPIO1_IO04		0x120b0 /* TA2 */
-			MX6QDL_PAD_GPIO_5__GPIO1_IO05		0x120b0 /* TA3 */
-			MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03	0x120b0 /* TA4 */
-		>;
-	};
-
-	pinctrl_leds_pdk2: leds-pdk2-grp {
-		fsl,pins = <
-			MX6QDL_PAD_DI0_PIN4__GPIO4_IO20		0x120b0 /* led6 */
-			MX6QDL_PAD_KEY_ROW0__GPIO4_IO07		0x120b0 /* led7 */
-			MX6QDL_PAD_KEY_COL1__GPIO4_IO08		0x120b0 /* led8 */
-		>;
-	};
-
 };
 
 &ipu1_di0_disp0 {
@@ -380,7 +355,7 @@
 };
 
 &pcie {
-	pinctrl-0 = <&pinctrl_pcie &pinctrl_pcie_reset>;
+	pinctrl-0 = <&pinctrl_pcie &pinctrl_dhcom_j>;
 	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>;
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
index 688f04eeabc5..a361e161fba1 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
@@ -317,7 +317,17 @@
 
 &iomuxc {
 	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_hog_base>;
+	pinctrl-0 = <
+			&pinctrl_hog_base
+			&pinctrl_dhcom_a &pinctrl_dhcom_b &pinctrl_dhcom_c
+			&pinctrl_dhcom_d &pinctrl_dhcom_e &pinctrl_dhcom_f
+			&pinctrl_dhcom_g &pinctrl_dhcom_h &pinctrl_dhcom_i
+			&pinctrl_dhcom_j &pinctrl_dhcom_k &pinctrl_dhcom_l
+			&pinctrl_dhcom_m &pinctrl_dhcom_n &pinctrl_dhcom_o
+			&pinctrl_dhcom_p &pinctrl_dhcom_q &pinctrl_dhcom_r
+			&pinctrl_dhcom_s &pinctrl_dhcom_t &pinctrl_dhcom_u
+			&pinctrl_dhcom_v &pinctrl_dhcom_w &pinctrl_dhcom_int
+		>;
 
 	pinctrl_hog_base: hog-base-grp {
 		fsl,pins = <
@@ -329,6 +339,103 @@
 		>;
 	};
 
+	/* DHCOM GPIOs */
+	pinctrl_dhcom_a: dhcom-a-grp {
+		fsl,pins = <MX6QDL_PAD_GPIO_2__GPIO1_IO02	0x400120b0>;
+	};
+
+	pinctrl_dhcom_b: dhcom-b-grp {
+		fsl,pins = <MX6QDL_PAD_GPIO_4__GPIO1_IO04	0x400120b0>;
+	};
+
+	pinctrl_dhcom_c: dhcom-c-grp {
+		fsl,pins = <MX6QDL_PAD_GPIO_5__GPIO1_IO05	0x400120b0>;
+	};
+
+	pinctrl_dhcom_d: dhcom-d-grp {
+		fsl,pins = <MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03	0x400120b0>;
+	};
+
+	pinctrl_dhcom_e: dhcom-e-grp {
+		fsl,pins = <MX6QDL_PAD_GPIO_19__GPIO4_IO05	0x400120b0>;
+	};
+
+	pinctrl_dhcom_f: dhcom-f-grp {
+		fsl,pins = <MX6QDL_PAD_DI0_PIN4__GPIO4_IO20	0x400120b0>;
+	};
+
+	pinctrl_dhcom_g: dhcom-g-grp {
+		fsl,pins = <MX6QDL_PAD_EIM_D27__GPIO3_IO27	0x400120b0>;
+	};
+
+	pinctrl_dhcom_h: dhcom-h-grp {
+		fsl,pins = <MX6QDL_PAD_KEY_ROW0__GPIO4_IO07	0x400120b0>;
+	};
+
+	pinctrl_dhcom_i: dhcom-i-grp {
+		fsl,pins = <MX6QDL_PAD_KEY_COL1__GPIO4_IO08	0x400120b0>;
+	};
+
+	pinctrl_dhcom_j: dhcom-j-grp {
+		fsl,pins = <MX6QDL_PAD_NANDF_CS1__GPIO6_IO14	0x400120b0>;
+	};
+
+	pinctrl_dhcom_k: dhcom-k-grp {
+		fsl,pins = <MX6QDL_PAD_NANDF_CS2__GPIO6_IO15	0x400120b0>;
+	};
+
+	pinctrl_dhcom_l: dhcom-l-grp {
+		fsl,pins = <MX6QDL_PAD_KEY_ROW1__GPIO4_IO09	0x400120b0>;
+	};
+
+	pinctrl_dhcom_m: dhcom-m-grp {
+		fsl,pins = <MX6QDL_PAD_SD3_DAT5__GPIO7_IO00	0x400120b0>;
+	};
+
+	pinctrl_dhcom_n: dhcom-n-grp {
+		fsl,pins = <MX6QDL_PAD_SD3_DAT4__GPIO7_IO01	0x400120b0>;
+	};
+
+	pinctrl_dhcom_o: dhcom-o-grp {
+		fsl,pins = <MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21	0x400120b0>;
+	};
+
+	pinctrl_dhcom_p: dhcom-p-grp {
+		fsl,pins = <MX6QDL_PAD_GPIO_18__GPIO7_IO13	0x400120b0>;
+	};
+
+	pinctrl_dhcom_q: dhcom-q-grp {
+		fsl,pins = <MX6QDL_PAD_SD1_CMD__GPIO1_IO18	0x400120b0>;
+	};
+
+	pinctrl_dhcom_r: dhcom-r-grp {
+		fsl,pins = <MX6QDL_PAD_SD1_DAT0__GPIO1_IO16	0x400120b0>;
+	};
+
+	pinctrl_dhcom_s: dhcom-s-grp {
+		fsl,pins = <MX6QDL_PAD_SD1_DAT1__GPIO1_IO17	0x400120b0>;
+	};
+
+	pinctrl_dhcom_t: dhcom-t-grp {
+		fsl,pins = <MX6QDL_PAD_SD1_DAT2__GPIO1_IO19	0x400120b0>;
+	};
+
+	pinctrl_dhcom_u: dhcom-u-grp {
+		fsl,pins = <MX6QDL_PAD_SD1_CLK__GPIO1_IO20	0x400120b0>;
+	};
+
+	pinctrl_dhcom_v: dhcom-v-grp {
+		fsl,pins = <MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18	0x400120b0>;
+	};
+
+	pinctrl_dhcom_w: dhcom-w-grp {
+		fsl,pins = <MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19	0x400120b0>;
+	};
+
+	pinctrl_dhcom_int: dhcom-int-grp {
+		fsl,pins = <MX6QDL_PAD_KEY_COL0__GPIO4_IO06	0x400120b0>;
+	};
+
 	pinctrl_ecspi1: ecspi1-grp {
 		fsl,pins = <
 			MX6QDL_PAD_EIM_D17__ECSPI1_MISO		0x100b1
-- 
2.11.0



From robin.murphy at arm.com  Mon Aug  2 07:15:50 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 2 Aug 2021 15:15:50 +0100
Subject: [PATCH v2 23/24] iommu/arm-smmu: Allow non-strict in
 pgtable_quirks interface
In-Reply-To: <20210802130438.GA28547@willie-the-truck>
References: <cover.1627468308.git.robin.murphy@arm.com>
 <0fcd1f5225a6b435cbc697551a6247cd435c04db.1627468310.git.robin.murphy@arm.com>
 <20210802130438.GA28547@willie-the-truck>
Message-ID: <3dd7cdae-7111-6ff2-6350-a0e19fe4ab66@arm.com>

On 2021-08-02 14:04, Will Deacon wrote:
> On Wed, Jul 28, 2021 at 04:58:44PM +0100, Robin Murphy wrote:
>> To make io-pgtable aware of a flush queue being dynamically enabled,
>> allow IO_PGTABLE_QUIRK_NON_STRICT to be set even after a domain has been
>> attached to, and hook up the final piece of the puzzle in iommu-dma.
>>
>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
>> ---
>>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++++++++
>>   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 11 +++++++++++
>>   drivers/iommu/dma-iommu.c                   |  3 +++
>>   3 files changed, 29 insertions(+)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index 19400826eba7..40fa9cb382c3 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -2711,6 +2711,20 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
>>   	return ret;
>>   }
>>   
>> +static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
>> +		unsigned long quirks)
>> +{
>> +	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>> +
>> +	if (quirks == IO_PGTABLE_QUIRK_NON_STRICT && smmu_domain->pgtbl_ops) {
>> +		struct io_pgtable *iop = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
>> +
>> +		iop->cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
>> +		return 0;
>> +	}
>> +	return -EINVAL;
>> +}
> 
> I don't see anything serialising this against a concurrent iommu_unmap(), so
> the ordering and atomicity looks quite suspicious to me here. I don't think
> it's just the page-table quirks either, but also setting cookie->fq_domain.

Heh, I confess to very much taking the cheeky "let's say nothing and see 
what Will thinks about concurrency" approach here :)

The beauty of only allowing relaxation in the strict->non-strict 
direction is that it shouldn't need serialising as such - it doesn't 
matter if the update to cookie->fq_domain is observed between 
iommu_unmap() and iommu_dma_free_iova(), since there's no correctness 
impact to queueing IOVAs which may already have been invalidated and may 
or may not have been synced. AFAICS the only condition which matters is 
that the setting of the io-pgtable quirk must observe fq_domain being 
set. It feels like there must be enough dependencies on the read side, 
but we might need an smp_wmb() between the two in iommu_dma_init_fq()?

I've also flip-flopped a bit on whether fq_domain needs to be accessed 
with READ_ONCE/WRITE_ONCE - by the time of posting I'd convinced myself 
that it was probably OK, but looking again now I suppose this wacky 
reordering is theoretically possible:


	iommu_dma_unmap() {
		bool free_fq = cookie->fq_domain; // == false

		iommu_unmap();

		if (!cookie->fq_domain) // observes new non-NULL value
			iommu_tlb_sync(); // skipped

		iommu_dma_free_iova { // inlined
			if (free_fq) // false
				queue_iova();
			else
				free_iova_fast(); // Uh-oh!
		}
	}

so although I still can't see atomicity being a problem I guess we do 
need it for the sake of reordering at least.

Cheers,
Robin.


From broonie at kernel.org  Mon Aug  2 07:19:39 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Aug 2021 15:19:39 +0100
Subject: [PATCH v3 3/4] kselftest/arm64: Add tests for SVE vector
 configuration
In-Reply-To: <20210802123749.GB25258@arm.com>
References: <20210729151518.46388-1-broonie@kernel.org>
 <20210729151518.46388-4-broonie@kernel.org>
 <20210729160642.GP1724@arm.com>
 <20210729173411.GT4670@sirena.org.uk>
 <20210802102517.GA25258@arm.com>
 <20210802113330.GD4668@sirena.org.uk>
 <20210802123749.GB25258@arm.com>
Message-ID: <20210802141939.GF4668@sirena.org.uk>

On Mon, Aug 02, 2021 at 01:37:50PM +0100, Dave Martin wrote:
> On Mon, Aug 02, 2021 at 12:33:30PM +0100, Mark Brown wrote:

> > That really doesn't seem like a good idea - it's just asking for
> > fragility if a signal gets delivered to the parent process or something.
> > Even if almost all the time there will only be one trip through the loop
> > we should still have the loop there for those few cases where it
> > triggers.

> This concern only applies when the program actually registers signal
> handlers.

> wait() can't return for any other reason, and it mustn't, precisely
> because historically software would have made this assumption.  This is
> one reason why wait3() etc. are separate functions.

That's great for the reader with a detailed knowledge of exactly what
error handling can be skipped and how standards conforming Linux is but
less good for the reader who is merely aware of best practices.  I am
not clear what the problem that is solved by removing the loop here is
TBH - to me it just makes it less obvious that we've handled everything.

> That aside though, can't we use popen(3)?

> I tend to forget about popen because it is "boring" to use it, but it
> looks like it fits this case quite well.  Then it would be libc's
> problem how to fork and wait safely.

popen() appears to be break the _SET_VL_ONEXEC test.  Between a lack of
strace in my test filesystem and not spotting anything obvious in the
glibc sources I can't tell exactly where it's doing something different,
though it does feel like it should be a separate testcase if it's
anything interesting.  I do think there is value in having exactly
what's done to start the child process be clear in the test program, and
that coverage of anything interesting from popen() could be done
incrementally.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/5f861d23/attachment-0001.sig>

From patchwork-bot+netdevbpf at kernel.org  Mon Aug  2 07:20:07 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Mon, 02 Aug 2021 14:20:07 +0000
Subject: [PATCH] cavium: switch from 'pci_' to 'dma_' API
In-Reply-To: <27c2b1a5152add2b3ecdfded40f562c5e4abed14.1627714392.git.christophe.jaillet@wanadoo.fr>
References: <27c2b1a5152add2b3ecdfded40f562c5e4abed14.1627714392.git.christophe.jaillet@wanadoo.fr>
Message-ID: <162791400746.18419.15767649410545938098.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (refs/heads/master):

On Sat, 31 Jul 2021 09:10:00 +0200 you wrote:
> The wrappers in include/linux/pci-dma-compat.h should go away.
> 
> The patch has been generated with the coccinelle script below. It has been
> hand modified to use 'dma_set_mask_and_coherent()' instead of
> 'pci_set_dma_mask()/pci_set_consistent_dma_mask()' when applicable.
> 
> It has been compile tested.
> 
> [...]

Here is the summary with links:
  - cavium: switch from 'pci_' to 'dma_' API
    https://git.kernel.org/netdev/net-next/c/1e0dd56e962e

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From maz at kernel.org  Mon Aug  2 07:22:07 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  2 Aug 2021 15:22:07 +0100
Subject: [PATCH] KVM: arm64: fix comment typo
In-Reply-To: <20210728130623.12017-1-wangborong@cdjrlc.com>
References: <20210728130623.12017-1-wangborong@cdjrlc.com>
Message-ID: <162791412064.3442307.9131610789137541537.b4-ty@kernel.org>

On Wed, 28 Jul 2021 21:06:23 +0800, Jason Wang wrote:
> Remove the repeated word 'the' from two comments.

Applied to next, thanks!

[1/1] KVM: arm64: fix comment typo
      commit: 013cc4c6788f1ce9885d3c0281904f93ee8f2271

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From cniedermaier at dh-electronics.com  Mon Aug  2 07:10:34 2021
From: cniedermaier at dh-electronics.com (Christoph Niedermaier)
Date: Mon, 2 Aug 2021 16:10:34 +0200
Subject: [PATCH V7 3/7] ARM: dts: imx6q-dhcom: Rearrange of iomux
In-Reply-To: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
Message-ID: <20210802141038.59663-3-cniedermaier@dh-electronics.com>

Move iomux to the end, no change in function.

Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
Reviewed-by: Marek Vasut <marex at denx.de>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Fabio Estevam <festevam at denx.de>
Cc: Marek Vasut <marex at denx.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: kernel at dh-electronics.com
To: linux-arm-kernel at lists.infradead.org
---
V2: - Rebase on Shawn Guos branch for-next
V3: - Add Reviewed-by tag
V4: - No changes
V5: - No changes
V6: - Rebase on 5.14-rc1
V7: - Rebase on Shawn Guos branch for-next
---
 arch/arm/boot/dts/imx6q-dhcom-pdk2.dts |  56 ++++-----
 arch/arm/boot/dts/imx6q-dhcom-som.dtsi | 210 ++++++++++++++++-----------------
 2 files changed, 133 insertions(+), 133 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
index 3ea077ec8606..897bbeb91d64 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
+++ b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
@@ -248,6 +248,34 @@
 	};
 };
 
+&ipu1_di0_disp0 {
+	remote-endpoint = <&lcd_display_in>;
+};
+
+&pcie {
+	pinctrl-0 = <&pinctrl_pcie &pinctrl_dhcom_j>;
+	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	status = "okay";
+};
+
+&ssi1 {
+	status = "okay";
+};
+
+&sata {
+	status = "okay";
+};
+
+&usdhc3 {
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl-names = "default";
 	pinctrl-0 = <
@@ -349,31 +377,3 @@
 		>;
 	};
 };
-
-&ipu1_di0_disp0 {
-	remote-endpoint = <&lcd_display_in>;
-};
-
-&pcie {
-	pinctrl-0 = <&pinctrl_pcie &pinctrl_dhcom_j>;
-	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>;
-	status = "okay";
-};
-
-&pwm1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_pwm1>;
-	status = "okay";
-};
-
-&ssi1 {
-	status = "okay";
-};
-
-&sata {
-	status = "okay";
-};
-
-&usdhc3 {
-	status = "okay";
-};
diff --git a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
index a361e161fba1..829f31bc569d 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
@@ -315,6 +315,111 @@
 	};
 };
 
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie>;
+};
+
+&reg_arm {
+	vin-supply = <&sw3_reg>;
+};
+
+&reg_soc {
+	vin-supply = <&sw1_reg>;
+};
+
+&reg_pu {
+	vin-supply = <&sw1_reg>;
+};
+
+&reg_vdd1p1 {
+	vin-supply = <&sw2_reg>;
+};
+
+&reg_vdd2p5 {
+	vin-supply = <&sw2_reg>;
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	uart-has-rtscts;
+	dtr-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
+	dsr-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+	dcd-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+	rng-gpios = <&gpio2 31 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+	status = "okay";
+};
+
+&uart5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&usbh1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbh1>;
+	vbus-supply = <&reg_usb_h1_vbus>;
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbotg {
+	vbus-supply = <&reg_usb_otg_vbus>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg>;
+	disable-over-current;
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	cd-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;
+	keep-power-in-suspend;
+	status = "okay";
+};
+
+&usdhc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	cd-gpios = <&gpio7 8 GPIO_ACTIVE_LOW>;
+	fsl,wp-controller;
+	keep-power-in-suspend;
+	status = "disabled";
+};
+
+&usdhc4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	non-removable;
+	bus-width = <8>;
+	no-1-8-v;
+	keep-power-in-suspend;
+	status = "okay";
+};
+
+&weim {
+	#address-cells = <2>;
+	#size-cells = <1>;
+	fsl,weim-cs-gpr = <&gpr>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_weim &pinctrl_weim_cs0 &pinctrl_weim_cs1>;
+	/* It is necessary to setup 2x 64MB otherwise setting gpr fails */
+	ranges = <0 0 0x08000000 0x04000000>, /* CS0 */
+		 <1 0 0x0c000000 0x04000000>; /* CS1 */
+	status = "disabled";
+};
+
 &iomuxc {
 	pinctrl-names = "default";
 	pinctrl-0 = <
@@ -680,108 +785,3 @@
 		>;
 	};
 };
-
-&pcie {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_pcie>;
-};
-
-&reg_arm {
-	vin-supply = <&sw3_reg>;
-};
-
-&reg_soc {
-	vin-supply = <&sw1_reg>;
-};
-
-&reg_pu {
-	vin-supply = <&sw1_reg>;
-};
-
-&reg_vdd1p1 {
-	vin-supply = <&sw2_reg>;
-};
-
-&reg_vdd2p5 {
-	vin-supply = <&sw2_reg>;
-};
-
-&uart1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart1>;
-	uart-has-rtscts;
-	dtr-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
-	dsr-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
-	dcd-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
-	rng-gpios = <&gpio2 31 GPIO_ACTIVE_LOW>;
-	status = "okay";
-};
-
-&uart4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart4>;
-	status = "okay";
-};
-
-&uart5 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart5>;
-	uart-has-rtscts;
-	status = "okay";
-};
-
-&usbh1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usbh1>;
-	vbus-supply = <&reg_usb_h1_vbus>;
-	dr_mode = "host";
-	status = "okay";
-};
-
-&usbotg {
-	vbus-supply = <&reg_usb_otg_vbus>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usbotg>;
-	disable-over-current;
-	dr_mode = "otg";
-	status = "okay";
-};
-
-&usdhc2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usdhc2>;
-	cd-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;
-	keep-power-in-suspend;
-	status = "okay";
-};
-
-&usdhc3 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usdhc3>;
-	cd-gpios = <&gpio7 8 GPIO_ACTIVE_LOW>;
-	fsl,wp-controller;
-	keep-power-in-suspend;
-	status = "disabled";
-};
-
-&usdhc4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usdhc4>;
-	non-removable;
-	bus-width = <8>;
-	no-1-8-v;
-	keep-power-in-suspend;
-	status = "okay";
-};
-
-&weim {
-	#address-cells = <2>;
-	#size-cells = <1>;
-	fsl,weim-cs-gpr = <&gpr>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_weim &pinctrl_weim_cs0 &pinctrl_weim_cs1>;
-	/* It is necessary to setup 2x 64MB otherwise setting gpr fails */
-	ranges = <0 0 0x08000000 0x04000000>, /* CS0 */
-		 <1 0 0x0c000000 0x04000000>; /* CS1 */
-	status = "disabled";
-};
-- 
2.11.0



From cniedermaier at dh-electronics.com  Mon Aug  2 07:10:35 2021
From: cniedermaier at dh-electronics.com (Christoph Niedermaier)
Date: Mon, 2 Aug 2021 16:10:35 +0200
Subject: [PATCH V7 4/7] ARM: dts: imx6q-dhcom: Cleanup of the devicetrees
In-Reply-To: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
Message-ID: <20210802141038.59663-4-cniedermaier@dh-electronics.com>

Following cleanups of the devicetrees done, no change in function:
- Remove parentheses from the license
- Update copyright date
- Alphabetical sorting
- Add comments
- Update pinctrl names
- Hex values in lower case
- Set 3rd values of fixed regulators gpio property to 0
- Replace interrupt type with a define
- Remove superfluous property max-speed from the fec node

Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
Reviewed-by: Marek Vasut <marex at denx.de>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Fabio Estevam <festevam at denx.de>
Cc: Marek Vasut <marex at denx.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: kernel at dh-electronics.com
To: linux-arm-kernel at lists.infradead.org
---
V2: - Set 3rd values of fixed regulators gpio property to 0
    - Rebase on Shawn Guos branch for-next
V3: - Remove superfluous property max-speed from the fec node
    - Add Reviewed-by tag
V4: - No changes
V5: - No changes
V6: - Rebase on 5.14-rc1
V7: - Rebase on Shawn Guos branch for-next
---
 arch/arm/boot/dts/imx6q-dhcom-pdk2.dts |  90 +++++-----
 arch/arm/boot/dts/imx6q-dhcom-som.dtsi | 302 +++++++++++++++++----------------
 2 files changed, 204 insertions(+), 188 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
index 897bbeb91d64..4b8801e91bd4 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
+++ b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: (GPL-2.0+)
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2015 DH electronics GmbH
+ * Copyright (C) 2015-2021 DH electronics GmbH
  * Copyright (C) 2018 Marek Vasut <marex at denx.de>
  */
 
@@ -18,27 +18,27 @@
 	};
 
 	clk_ext_audio_codec: clock-codec {
-		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <24000000>;
+		compatible = "fixed-clock";
 	};
 
 	display_bl: display-bl {
-		compatible = "pwm-backlight";
-		pwms = <&pwm1 0 50000 PWM_POLARITY_INVERTED>;
 		brightness-levels = <0 16 22 30 40 55 75 102 138 188 255>;
+		compatible = "pwm-backlight";
 		default-brightness-level = <8>;
-		enable-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>;
+		enable-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>; /* GPIO G */
+		pwms = <&pwm1 0 50000 PWM_POLARITY_INVERTED>;
 		status = "okay";
 	};
 
 	lcd_display: disp0 {
-		compatible = "fsl,imx-parallel-display";
 		#address-cells = <1>;
 		#size-cells = <0>;
+		compatible = "fsl,imx-parallel-display";
 		interface-pix-fmt = "rgb24";
-		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_ipu1_lcdif &pinctrl_dhcom_g>;
+		pinctrl-names = "default";
 		status = "okay";
 
 		port at 0 {
@@ -63,36 +63,36 @@
 		compatible = "gpio-keys";
 
 		button-0 {
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; /* GPIO A */
 			label = "TA1-GPIO-A";
 			linux,code = <KEY_A>;
-			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
 			pinctrl-0 = <&pinctrl_dhcom_a>;
 			pinctrl-names = "default";
 			wakeup-source;
 		};
 
 		button-1 {
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* GPIO B */
 			label = "TA2-GPIO-B";
 			linux,code = <KEY_B>;
-			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
 			pinctrl-0 = <&pinctrl_dhcom_b>;
 			pinctrl-names = "default";
 			wakeup-source;
 		};
 
 		button-2 {
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; /* GPIO C */
 			label = "TA3-GPIO-C";
 			linux,code = <KEY_C>;
-			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
 			pinctrl-0 = <&pinctrl_dhcom_c>;
 			pinctrl-names = "default";
 			wakeup-source;
 		};
 
 		button-3 {
+			gpios = <&gpio6 3 GPIO_ACTIVE_LOW>; /* GPIO D */
 			label = "TA4-GPIO-D";
 			linux,code = <KEY_D>;
-			gpios = <&gpio6 3 GPIO_ACTIVE_LOW>;
 			pinctrl-0 = <&pinctrl_dhcom_d>;
 			pinctrl-names = "default";
 			wakeup-source;
@@ -108,9 +108,9 @@
 		 */
 		led-5 {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
 			function = LED_FUNCTION_INDICATOR;
 			gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* GPIO E */
-			default-state = "off";
 			pinctrl-0 = <&pinctrl_dhcom_e>;
 			pinctrl-names = "default";
 			status = "disabled";
@@ -118,35 +118,35 @@
 
 		led-6 {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
 			function = LED_FUNCTION_INDICATOR;
 			gpios = <&gpio4 20 GPIO_ACTIVE_HIGH>; /* GPIO F */
-			default-state = "off";
 			pinctrl-0 = <&pinctrl_dhcom_f>;
 			pinctrl-names = "default";
 		};
 
 		led-7 {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
 			function = LED_FUNCTION_INDICATOR;
 			gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* GPIO H */
-			default-state = "off";
 			pinctrl-0 = <&pinctrl_dhcom_h>;
 			pinctrl-names = "default";
 		};
 
 		led-8 {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
 			function = LED_FUNCTION_INDICATOR;
 			gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */
-			default-state = "off";
 			pinctrl-0 = <&pinctrl_dhcom_i>;
 			pinctrl-names = "default";
 		};
 	};
 
 	panel {
-		compatible = "edt,etm0700g0edh6";
 		backlight = <&display_bl>;
+		compatible = "edt,etm0700g0edh6";
 
 		port {
 			lcd_panel_in: endpoint {
@@ -156,23 +156,23 @@
 	};
 
 	sound {
-		compatible = "fsl,imx-audio-sgtl5000";
-		model = "imx-sgtl5000";
-		ssi-controller = <&ssi1>;
 		audio-codec = <&sgtl5000>;
 		audio-routing =
 			"MIC_IN", "Mic Jack",
 			"Mic Jack", "Mic Bias",
 			"LINE_IN", "Line In Jack",
 			"Headphone Jack", "HP_OUT";
-		mux-int-port = <1>;
+		compatible = "fsl,imx-audio-sgtl5000";
+		model = "imx-sgtl5000";
 		mux-ext-port = <3>;
+		mux-int-port = <1>;
+		ssi-controller = <&ssi1>;
 	};
 };
 
 &audmux {
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_audmux_ext>;
+	pinctrl-names = "default";
 	status = "okay";
 };
 
@@ -189,8 +189,8 @@
 &fec {
 	phy-mode = "rgmii";
 	phy-handle = <&ethphy7>;
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_enet_1G>;
+	pinctrl-names = "default";
 	status = "okay";
 
 	mdio {
@@ -204,20 +204,20 @@
 			pinctrl-0 = <&pinctrl_ethphy7>;
 			pinctrl-names = "default";
 			reg = <7>;
-			reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
 			reset-assert-us = <1000>;
 			reset-deassert-us = <1000>;
+			reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
 			rxc-skew-ps = <3000>;
 			rxd0-skew-ps = <0>;
 			rxd1-skew-ps = <0>;
 			rxd2-skew-ps = <0>;
 			rxd3-skew-ps = <0>;
+			rxdv-skew-ps = <0>;
 			txc-skew-ps = <3000>;
 			txd0-skew-ps = <0>;
 			txd1-skew-ps = <0>;
 			txd2-skew-ps = <0>;
 			txd3-skew-ps = <0>;
-			rxdv-skew-ps = <0>;
 			txen-skew-ps = <0>;
 		};
 	};
@@ -230,21 +230,21 @@
 
 &i2c2 {
 	sgtl5000: codec at a {
-		compatible = "fsl,sgtl5000";
-		reg = <0x0a>;
 		#sound-dai-cells = <0>;
 		clocks = <&clk_ext_audio_codec>;
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
 		VDDA-supply = <&reg_3p3v>;
 		VDDIO-supply = <&sw2_reg>;
 	};
 
 	touchscreen at 38 {
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_dhcom_e>;
 		compatible = "edt,edt-ft5406";
-		reg = <0x38>;
 		interrupt-parent = <&gpio4>;
 		interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */
+		pinctrl-0 = <&pinctrl_dhcom_e>;
+		pinctrl-names = "default";
+		reg = <0x38>;
 	};
 };
 
@@ -254,13 +254,13 @@
 
 &pcie {
 	pinctrl-0 = <&pinctrl_pcie &pinctrl_dhcom_j>;
-	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>;
+	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>; /* GPIO J */
 	status = "okay";
 };
 
 &pwm1 {
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm1>;
+	pinctrl-names = "default";
 	status = "okay";
 };
 
@@ -272,12 +272,11 @@
 	status = "okay";
 };
 
-&usdhc3 {
+&usdhc3 { /* Micro SD card on module */
 	status = "okay";
 };
 
 &iomuxc {
-	pinctrl-names = "default";
 	pinctrl-0 = <
 			/*
 			 * The following DHCOM GPIOs are used on this board.
@@ -300,50 +299,51 @@
 			&pinctrl_dhcom_s &pinctrl_dhcom_t &pinctrl_dhcom_u
 			&pinctrl_dhcom_v &pinctrl_dhcom_w &pinctrl_dhcom_int
 		>;
+	pinctrl-names = "default";
 
 	pinctrl_audmux_ext: audmux-ext-grp {
 		fsl,pins = <
-			MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
 			MX6QDL_PAD_CSI0_DAT4__AUD3_TXC		0x130b0
 			MX6QDL_PAD_CSI0_DAT5__AUD3_TXD		0x110b0
 			MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS		0x130b0
+			MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
 		>;
 	};
 
 	pinctrl_enet_1G: enet-1G-grp {
 		fsl,pins = <
-			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x100b0
 			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x100b0
-			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x100b0
-			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x100b0
-			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x100b0
-			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x100b0
-			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x100b0
-			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x100b0
+			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x100b0
 			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x100b0
-			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
 			MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
 			MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
 			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
 			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
 			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
+			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
+			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x100b0
+			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x100b0
+			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x100b0
+			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x100b0
+			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x100b0
+			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x100b0
 		>;
 	};
 
 	pinctrl_ethphy7: ethphy7-grp {
 		fsl,pins = <
+			MX6QDL_PAD_EIM_D26__GPIO3_IO26		0xb1 /* WOL */
 			MX6QDL_PAD_EIM_D29__GPIO3_IO29		0xb0 /* Reset */
 			MX6QDL_PAD_GPIO_0__GPIO1_IO00		0xb1 /* Int */
-			MX6QDL_PAD_EIM_D26__GPIO3_IO26		0xb1 /* WOL */
 		>;
 	};
 
 	pinctrl_ipu1_lcdif: ipu1-lcdif-grp {
 		fsl,pins = <
 			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK	0x38
-			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x38
 			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02		0x38
 			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03		0x38
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x38
 			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00	0x38
 			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01	0x38
 			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02	0x38
diff --git a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
index 829f31bc569d..99a275e06643 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: (GPL-2.0+)
+// SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright (C) 2015 DH electronics GmbH
+ * Copyright (C) 2015-2021 DH electronics GmbH
  * Copyright (C) 2018 Marek Vasut <marex at denx.de>
  */
 
@@ -28,14 +28,22 @@
 		serial4 = &uart3;
 	};
 
-	memory at 10000000 {
+	memory at 10000000 { /* Appropriate memory size will be filled by U-Boot */
 		device_type = "memory";
 		reg = <0x10000000 0x20000000>;
 	};
 
+	reg_3p3v: regulator-3P3V {
+		compatible = "regulator-fixed";
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-name = "3P3V";
+	};
+
 	reg_eth_vio: regulator-eth-vio {
 		compatible = "regulator-fixed";
-		gpio = <&gpio1 7 GPIO_ACTIVE_LOW>;
+		gpio = <&gpio1 7 0>;
 		pinctrl-0 = <&pinctrl_enet_vio>;
 		pinctrl-names = "default";
 		regulator-always-on;
@@ -54,86 +62,84 @@
 		regulator-name = "latch_oe_on";
 	};
 
-	reg_usb_otg_vbus: regulator-usb-otg-vbus {
+	reg_usb_h1_vbus: regulator-usb-h1-vbus {
 		compatible = "regulator-fixed";
-		regulator-name = "usb_otg_vbus";
+		enable-active-high;
+		gpio = <&gpio3 31 0>;
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
+		regulator-name = "usb_h1_vbus";
 	};
 
-	reg_usb_h1_vbus: regulator-usb-h1-vbus {
+	reg_usb_otg_vbus: regulator-usb-otg-vbus {
 		compatible = "regulator-fixed";
-		regulator-name = "usb_h1_vbus";
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
-		gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	reg_3p3v: regulator-3P3V {
-		compatible = "regulator-fixed";
-		regulator-name = "3P3V";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-always-on;
+		regulator-name = "usb_otg_vbus";
 	};
 };
 
 &can1 {
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan1>;
+	pinctrl-names = "default";
 };
 
+/*
+ * Special hardware required which uses the pins from micro SD card. The pins
+ * SD3_DAT0 and SD3_DAT1 are muxed as can2 Tx and Rx. The signals for can2 Tx
+ * and Rx are output on DHCOM uart1 rts/cts pins. So to enable can2 on the board
+ * device tree file, you also need to disable the micro SD card and the uart1
+ * rts/cts have to be disabled or output on other DHCOM pins.
+ */
 &can2 {
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_flexcan2>;
+	pinctrl-names = "default";
 };
 
 &ecspi1 {
 	cs-gpios = <&gpio2 30 GPIO_ACTIVE_LOW>, <&gpio4 11 GPIO_ACTIVE_LOW>;
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_ecspi1>;
+	pinctrl-names = "default";
 	status = "okay";
 
-	flash at 0 {	/* S25FL116K */
+	flash at 0 { /* S25FL116K */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
-		spi-max-frequency = <50000000>;
-		reg = <0>;
 		m25p,fast-read;
+		reg = <0>;
+		spi-max-frequency = <50000000>;
 	};
 };
 
 &ecspi2 {
 	cs-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_ecspi2>;
+	pinctrl-names = "default";
 	status = "okay";
 };
 
 &fec {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_enet_100M>;
 	phy-mode = "rmii";
 	phy-handle = <&ethphy0>;
+	pinctrl-0 = <&pinctrl_enet_100M>;
+	pinctrl-names = "default";
 	status = "okay";
 
 	mdio {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		ethphy0: ethernet-phy at 0 {	/* SMSC LAN8710Ai */
+		ethphy0: ethernet-phy at 0 { /* SMSC LAN8710Ai */
 			compatible = "ethernet-phy-ieee802.3-c22";
 			interrupt-parent = <&gpio4>;
 			interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
-			max-speed = <100>;
 			pinctrl-0 = <&pinctrl_ethphy0>;
 			pinctrl-names = "default";
 			reg = <0>;
-			reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
 			reset-assert-us = <1000>;
 			reset-deassert-us = <1000>;
+			reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
 			smsc,disable-energy-detect; /* Make plugin detection reliable */
 		};
 	};
@@ -196,139 +202,147 @@
 };
 
 &i2c1 {
+	/*
+	 * Info: According to erratum ERR007805 clock frequency limit is 375000.
+	 * The erratum for i.MX6S/DL is here [1] and for i.MX6Q/D is here [2].
+	 * [1] https://www.nxp.com/docs/en/errata/IMX6SDLCE.pdf
+	 * [2] https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf
+	 */
 	clock-frequency = <100000>;
-	pinctrl-names = "default", "gpio";
 	pinctrl-0 = <&pinctrl_i2c1>;
 	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	pinctrl-names = "default", "gpio";
 	scl-gpios = <&gpio3 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	sda-gpios = <&gpio3 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	status = "okay";
 };
 
 &i2c2 {
+	/* Info: Clock frequency limit is 375000 (for details see i2c1) */
 	clock-frequency = <100000>;
-	pinctrl-names = "default", "gpio";
 	pinctrl-0 = <&pinctrl_i2c2>;
 	pinctrl-1 = <&pinctrl_i2c2_gpio>;
+	pinctrl-names = "default", "gpio";
 	scl-gpios = <&gpio4 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	sda-gpios = <&gpio4 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	status = "okay";
 };
 
 &i2c3 {
+	/* Info: Clock frequency limit is 375000 (for details see i2c1) */
 	clock-frequency = <100000>;
-	pinctrl-names = "default", "gpio";
 	pinctrl-0 = <&pinctrl_i2c3>;
 	pinctrl-1 = <&pinctrl_i2c3_gpio>;
+	pinctrl-names = "default", "gpio";
 	scl-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	status = "okay";
 
 	ltc3676: pmic at 3c {
 		compatible = "lltc,ltc3676";
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_pmic_hw300>;
-		reg = <0x3c>;
 		interrupt-parent = <&gpio5>;
 		interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-0 = <&pinctrl_pmic>;
+		pinctrl-names = "default";
+		reg = <0x3c>;
 
 		regulators {
 			sw1_reg: sw1 {
-				regulator-min-microvolt = <787500>;
-				regulator-max-microvolt = <1527272>;
 				lltc,fb-voltage-divider = <100000 110000>;
-				regulator-suspend-mem-microvolt = <1040000>;
-				regulator-ramp-delay = <7000>;
-				regulator-boot-on;
 				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1527272>;
+				regulator-min-microvolt = <787500>;
+				regulator-ramp-delay = <7000>;
+				regulator-suspend-mem-microvolt = <1040000>;
 			};
 
 			sw2_reg: sw2 {
-				regulator-min-microvolt = <1885714>;
-				regulator-max-microvolt = <3657142>;
 				lltc,fb-voltage-divider = <100000 28000>;
-				regulator-ramp-delay = <7000>;
-				regulator-boot-on;
 				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <3657142>;
+				regulator-min-microvolt = <1885714>;
+				regulator-ramp-delay = <7000>;
 			};
 
 			sw3_reg: sw3 {
-				regulator-min-microvolt = <787500>;
-				regulator-max-microvolt = <1527272>;
 				lltc,fb-voltage-divider = <100000 110000>;
-				regulator-suspend-mem-microvolt = <980000>;
-				regulator-ramp-delay = <7000>;
-				regulator-boot-on;
 				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1527272>;
+				regulator-min-microvolt = <787500>;
+				regulator-ramp-delay = <7000>;
+				regulator-suspend-mem-microvolt = <980000>;
 			};
 
 			sw4_reg: sw4 {
-				regulator-min-microvolt = <855571>;
-				regulator-max-microvolt = <1659291>;
 				lltc,fb-voltage-divider = <100000 93100>;
-				regulator-ramp-delay = <7000>;
-				regulator-boot-on;
 				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1659291>;
+				regulator-min-microvolt = <855571>;
+				regulator-ramp-delay = <7000>;
 			};
 
 			ldo1_reg: ldo1 {
-				regulator-min-microvolt = <3240306>;
-				regulator-max-microvolt = <3240306>;
 				lltc,fb-voltage-divider = <102000 29400>;
-				regulator-boot-on;
 				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <3240306>;
+				regulator-min-microvolt = <3240306>;
 			};
 
 			ldo2_reg: ldo2 {
-				regulator-min-microvolt = <2484708>;
-				regulator-max-microvolt = <2484708>;
 				lltc,fb-voltage-divider = <100000 41200>;
-				regulator-boot-on;
 				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <2484708>;
+				regulator-min-microvolt = <2484708>;
 			};
 		};
 	};
 
-	touchscreen at 49 {	/* TSC2004 */
+	touchscreen at 49 { /* TSC2004 */
 		compatible = "ti,tsc2004";
+		interrupts-extended = <&gpio4 14 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-0 = <&pinctrl_tsc2004>;
+		pinctrl-names = "default";
 		reg = <0x49>;
 		vio-supply = <&reg_3p3v>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_tsc2004_hw300>;
-		interrupts-extended = <&gpio4 14 IRQ_TYPE_EDGE_FALLING>;
 		status = "disabled";
 	};
 
 	eeprom at 50 {
 		compatible = "atmel,24c02";
-		reg = <0x50>;
 		pagesize = <16>;
+		reg = <0x50>;
 	};
 
 	rtc_i2c: rtc at 56 {
 		compatible = "microcrystal,rv3029";
+		interrupt-parent = <&gpio7>;
+		interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-0 = <&pinctrl_rtc>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_rtc_hw300>;
 		reg = <0x56>;
-		interrupt-parent = <&gpio7>;
-		interrupts = <12 2>;
 	};
 };
 
 &pcie {
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie>;
+	pinctrl-names = "default";
 };
 
 &reg_arm {
 	vin-supply = <&sw3_reg>;
 };
 
-&reg_soc {
+&reg_pu {
 	vin-supply = <&sw1_reg>;
 };
 
-&reg_pu {
+&reg_soc {
 	vin-supply = <&sw1_reg>;
 };
 
@@ -340,71 +354,71 @@
 	vin-supply = <&sw2_reg>;
 };
 
-&uart1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_uart1>;
-	uart-has-rtscts;
-	dtr-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
-	dsr-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+&uart1 { /* DHCOM UART1 */
 	dcd-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+	dsr-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+	dtr-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
 	rng-gpios = <&gpio2 31 GPIO_ACTIVE_LOW>;
+	pinctrl-0 = <&pinctrl_uart1>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
 	status = "okay";
 };
 
-&uart4 {
-	pinctrl-names = "default";
+&uart4 { /* DHCOM UART3 */
 	pinctrl-0 = <&pinctrl_uart4>;
+	pinctrl-names = "default";
 	status = "okay";
 };
 
-&uart5 {
-	pinctrl-names = "default";
+&uart5 { /* DHCOM UART2 */
 	pinctrl-0 = <&pinctrl_uart5>;
+	pinctrl-names = "default";
 	uart-has-rtscts;
 	status = "okay";
 };
 
 &usbh1 {
-	pinctrl-names = "default";
+	dr_mode = "host";
 	pinctrl-0 = <&pinctrl_usbh1>;
+	pinctrl-names = "default";
 	vbus-supply = <&reg_usb_h1_vbus>;
-	dr_mode = "host";
 	status = "okay";
 };
 
 &usbotg {
-	vbus-supply = <&reg_usb_otg_vbus>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usbotg>;
 	disable-over-current;
 	dr_mode = "otg";
+	pinctrl-0 = <&pinctrl_usbotg>;
+	pinctrl-names = "default";
+	vbus-supply = <&reg_usb_otg_vbus>;
 	status = "okay";
 };
 
-&usdhc2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usdhc2>;
+&usdhc2 { /* External SD card via DHCOM */
 	cd-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;
 	keep-power-in-suspend;
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	pinctrl-names = "default";
 	status = "okay";
 };
 
-&usdhc3 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usdhc3>;
+&usdhc3 { /* Micro SD card on module */
 	cd-gpios = <&gpio7 8 GPIO_ACTIVE_LOW>;
 	fsl,wp-controller;
 	keep-power-in-suspend;
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-names = "default";
 	status = "disabled";
 };
 
-&usdhc4 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usdhc4>;
-	non-removable;
+&usdhc4 { /* eMMC on module */
 	bus-width = <8>;
-	no-1-8-v;
 	keep-power-in-suspend;
+	no-1-8-v;
+	non-removable;
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	pinctrl-names = "default";
 	status = "okay";
 };
 
@@ -412,8 +426,8 @@
 	#address-cells = <2>;
 	#size-cells = <1>;
 	fsl,weim-cs-gpr = <&gpr>;
-	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_weim &pinctrl_weim_cs0 &pinctrl_weim_cs1>;
+	pinctrl-names = "default";
 	/* It is necessary to setup 2x 64MB otherwise setting gpr fails */
 	ranges = <0 0 0x08000000 0x04000000>, /* CS0 */
 		 <1 0 0x0c000000 0x04000000>; /* CS1 */
@@ -421,7 +435,6 @@
 };
 
 &iomuxc {
-	pinctrl-names = "default";
 	pinctrl-0 = <
 			&pinctrl_hog_base
 			&pinctrl_dhcom_a &pinctrl_dhcom_b &pinctrl_dhcom_c
@@ -433,14 +446,17 @@
 			&pinctrl_dhcom_s &pinctrl_dhcom_t &pinctrl_dhcom_u
 			&pinctrl_dhcom_v &pinctrl_dhcom_w &pinctrl_dhcom_int
 		>;
+	pinctrl-names = "default";
 
 	pinctrl_hog_base: hog-base-grp {
 		fsl,pins = <
-			MX6QDL_PAD_EIM_A19__GPIO2_IO19		0x120b0
-			MX6QDL_PAD_EIM_A23__GPIO6_IO06		0x120b0
-			MX6QDL_PAD_EIM_A22__GPIO2_IO16		0x120b0
+			/* GPIOs for memory coding */
 			MX6QDL_PAD_EIM_A16__GPIO2_IO22		0x120b0
 			MX6QDL_PAD_EIM_A17__GPIO2_IO21		0x120b0
+			/* GPIOs for hardware coding */
+			MX6QDL_PAD_EIM_A19__GPIO2_IO19		0x120b0
+			MX6QDL_PAD_EIM_A22__GPIO2_IO16		0x120b0
+			MX6QDL_PAD_EIM_A23__GPIO6_IO06		0x120b0
 		>;
 	};
 
@@ -543,9 +559,9 @@
 
 	pinctrl_ecspi1: ecspi1-grp {
 		fsl,pins = <
+			MX6QDL_PAD_EIM_D16__ECSPI1_SCLK		0x100b1
 			MX6QDL_PAD_EIM_D17__ECSPI1_MISO		0x100b1
 			MX6QDL_PAD_EIM_D18__ECSPI1_MOSI		0x100b1
-			MX6QDL_PAD_EIM_D16__ECSPI1_SCLK		0x100b1
 			MX6QDL_PAD_EIM_EB2__GPIO2_IO30		0x1b0b0
 			MX6QDL_PAD_KEY_ROW2__GPIO4_IO11		0x1b0b0
 		>;
@@ -553,18 +569,18 @@
 
 	pinctrl_ecspi2: ecspi2-grp {
 		fsl,pins = <
-			MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO	0x100b1
-			MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI	0x100b1
 			MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK	0x100b1
+			MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI	0x100b1
+			MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO	0x100b1
 			MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29	0x1b0b0
 		>;
 	};
 
 	pinctrl_enet_100M: enet-100M-grp {
 		fsl,pins = <
-			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
-			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
 			MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN	0x1b0b0
+			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
+			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
 			MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER	0x1b0b0
 			MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0	0x1b0b0
 			MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1	0x1b0b0
@@ -590,8 +606,8 @@
 
 	pinctrl_flexcan1: flexcan1-grp {
 		fsl,pins = <
-			MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX	0x1b0b0
 			MX6QDL_PAD_GPIO_8__FLEXCAN1_RX		0x1b0b0
+			MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX	0x1b0b0
 		>;
 	};
 
@@ -644,40 +660,40 @@
 		>;
 	};
 
-	pinctrl_pmic_hw300: pmic-hw300-grp {
+	pinctrl_pcie: pcie-grp {
 		fsl,pins = <
-			MX6QDL_PAD_EIM_A25__GPIO5_IO02		0x1B0B0
+			MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x1b0b1 /* Wake */
 		>;
 	};
 
-	pinctrl_rtc_hw300: rtc-hw300-grp {
+	pinctrl_pmic: pmic-grp {
 		fsl,pins = <
-			MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x120B0
+			MX6QDL_PAD_EIM_A25__GPIO5_IO02		0x1b0b0
 		>;
 	};
 
-	pinctrl_tsc2004_hw300: tsc2004-hw300-grp {
+	pinctrl_rtc: rtc-grp {
 		fsl,pins = <
-			MX6QDL_PAD_KEY_COL4__GPIO4_IO14		0x120B0
+			MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x120b0
 		>;
 	};
 
-	pinctrl_pcie: pcie-grp {
+	pinctrl_tsc2004: tsc2004-grp {
 		fsl,pins = <
-			MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x1b0b1 /* Wake */
+			MX6QDL_PAD_KEY_COL4__GPIO4_IO14		0x120b0
 		>;
 	};
 
 	pinctrl_uart1: uart1-grp {
 		fsl,pins = <
-			MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA	0x1b0b1
-			MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA	0x1b0b1
-			MX6QDL_PAD_EIM_D20__UART1_RTS_B		0x1b0b1
 			MX6QDL_PAD_EIM_D19__UART1_CTS_B		0x4001b0b1
+			MX6QDL_PAD_EIM_D20__UART1_RTS_B		0x1b0b1
 			MX6QDL_PAD_EIM_D23__GPIO3_IO23		0x4001b0b1
 			MX6QDL_PAD_EIM_D24__GPIO3_IO24		0x4001b0b1
 			MX6QDL_PAD_EIM_D25__GPIO3_IO25		0x4001b0b1
 			MX6QDL_PAD_EIM_EB3__GPIO2_IO31		0x4001b0b1
+			MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA	0x1b0b1
+			MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA	0x1b0b1
 		>;
 	};
 
@@ -699,7 +715,7 @@
 
 	pinctrl_usbh1: usbh1-grp {
 		fsl,pins = <
-			MX6QDL_PAD_EIM_D31__GPIO3_IO31		0x120B0
+			MX6QDL_PAD_EIM_D31__GPIO3_IO31		0x120b0
 		>;
 	};
 
@@ -711,32 +727,32 @@
 
 	pinctrl_usdhc2: usdhc2-grp {
 		fsl,pins = <
-			MX6QDL_PAD_SD2_CMD__SD2_CMD		0x17059
+			MX6QDL_PAD_NANDF_CS3__GPIO6_IO16	0x120b0
 			MX6QDL_PAD_SD2_CLK__SD2_CLK		0x10059
+			MX6QDL_PAD_SD2_CMD__SD2_CMD		0x17059
 			MX6QDL_PAD_SD2_DAT0__SD2_DATA0		0x17059
 			MX6QDL_PAD_SD2_DAT1__SD2_DATA1		0x17059
 			MX6QDL_PAD_SD2_DAT2__SD2_DATA2		0x17059
 			MX6QDL_PAD_SD2_DAT3__SD2_DATA3		0x17059
-			MX6QDL_PAD_NANDF_CS3__GPIO6_IO16	0x120B0
 		>;
 	};
 
 	pinctrl_usdhc3: usdhc3-grp {
 		fsl,pins = <
-			MX6QDL_PAD_SD3_CMD__SD3_CMD		0x17059
 			MX6QDL_PAD_SD3_CLK__SD3_CLK		0x10059
+			MX6QDL_PAD_SD3_CMD__SD3_CMD		0x17059
 			MX6QDL_PAD_SD3_DAT0__SD3_DATA0		0x17059
 			MX6QDL_PAD_SD3_DAT1__SD3_DATA1		0x17059
 			MX6QDL_PAD_SD3_DAT2__SD3_DATA2		0x17059
 			MX6QDL_PAD_SD3_DAT3__SD3_DATA3		0x17059
-			MX6QDL_PAD_SD3_RST__GPIO7_IO08		0x120B0
+			MX6QDL_PAD_SD3_RST__GPIO7_IO08		0x120b0
 		>;
 	};
 
 	pinctrl_usdhc4: usdhc4-grp {
 		fsl,pins = <
-			MX6QDL_PAD_SD4_CMD__SD4_CMD		0x17059
 			MX6QDL_PAD_SD4_CLK__SD4_CLK		0x10059
+			MX6QDL_PAD_SD4_CMD__SD4_CMD		0x17059
 			MX6QDL_PAD_SD4_DAT0__SD4_DATA0		0x17059
 			MX6QDL_PAD_SD4_DAT1__SD4_DATA1		0x17059
 			MX6QDL_PAD_SD4_DAT2__SD4_DATA2		0x17059
@@ -750,26 +766,26 @@
 
 	pinctrl_weim: weim-grp {
 		fsl,pins = <
+			MX6QDL_PAD_EIM_DA0__EIM_AD00		0xb0a6
+			MX6QDL_PAD_EIM_DA1__EIM_AD01		0xb0a6
+			MX6QDL_PAD_EIM_DA2__EIM_AD02		0xb0a6
+			MX6QDL_PAD_EIM_DA3__EIM_AD03		0xb0a6
+			MX6QDL_PAD_EIM_DA4__EIM_AD04		0xb0a6
+			MX6QDL_PAD_EIM_DA5__EIM_AD05		0xb0a6
+			MX6QDL_PAD_EIM_DA6__EIM_AD06		0xb0a6
+			MX6QDL_PAD_EIM_DA7__EIM_AD07		0xb0a6
+			MX6QDL_PAD_EIM_DA8__EIM_AD08		0xb0a6
+			MX6QDL_PAD_EIM_DA9__EIM_AD09		0xb0a6
+			MX6QDL_PAD_EIM_DA10__EIM_AD10		0xb0a6
+			MX6QDL_PAD_EIM_DA11__EIM_AD11		0xb0a6
+			MX6QDL_PAD_EIM_DA12__EIM_AD12		0xb0a6
+			MX6QDL_PAD_EIM_DA13__EIM_AD13		0xb0a6
+			MX6QDL_PAD_EIM_DA14__EIM_AD14		0xb0a6
+			MX6QDL_PAD_EIM_DA15__EIM_AD15		0xb0a6
+			MX6QDL_PAD_EIM_D22__GPIO3_IO22		0x130b0
+			MX6QDL_PAD_EIM_LBA__EIM_LBA_B		0xb060 /* LE */
 			MX6QDL_PAD_EIM_OE__EIM_OE_B		0xb0a6
 			MX6QDL_PAD_EIM_RW__EIM_RW		0xb0a6 /* WE */
-			MX6QDL_PAD_EIM_LBA__EIM_LBA_B		0xb060 /* LE */
-			MX6QDL_PAD_EIM_D22__GPIO3_IO22		0x130b0
-			MX6QDL_PAD_EIM_DA15__EIM_AD15		0xb0a6
-			MX6QDL_PAD_EIM_DA14__EIM_AD14		0xb0a6
-			MX6QDL_PAD_EIM_DA13__EIM_AD13		0xb0a6
-			MX6QDL_PAD_EIM_DA12__EIM_AD12		0xb0a6
-			MX6QDL_PAD_EIM_DA11__EIM_AD11		0xb0a6
-			MX6QDL_PAD_EIM_DA10__EIM_AD10		0xb0a6
-			MX6QDL_PAD_EIM_DA9__EIM_AD09		0xb0a6
-			MX6QDL_PAD_EIM_DA8__EIM_AD08		0xb0a6
-			MX6QDL_PAD_EIM_DA7__EIM_AD07		0xb0a6
-			MX6QDL_PAD_EIM_DA6__EIM_AD06		0xb0a6
-			MX6QDL_PAD_EIM_DA5__EIM_AD05		0xb0a6
-			MX6QDL_PAD_EIM_DA4__EIM_AD04		0xb0a6
-			MX6QDL_PAD_EIM_DA3__EIM_AD03		0xb0a6
-			MX6QDL_PAD_EIM_DA2__EIM_AD02		0xb0a6
-			MX6QDL_PAD_EIM_DA1__EIM_AD01		0xb0a6
-			MX6QDL_PAD_EIM_DA0__EIM_AD00		0xb0a6
 		>;
 	};
 
-- 
2.11.0



From mark.rutland at arm.com  Mon Aug  2 07:30:19 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 2 Aug 2021 15:30:19 +0100
Subject: [aarch64 boot-wrapper PATCH 0/6] Various (build system) fixes
In-Reply-To: <20210730184021.498faf4c@slackpad.fritz.box>
References: <20210510120726.5242-1-andre.przywara@arm.com>
 <20210730184021.498faf4c@slackpad.fritz.box>
Message-ID: <20210802143019.GA59710@C02TD0UTHF1T.local>

On Fri, Jul 30, 2021 at 06:40:21PM +0100, Andre Przywara wrote:
> On Mon, 10 May 2021 13:07:20 +0100
> Andre Przywara <andre.przywara at arm.com> wrote:
> 
> > While playing around with the boot-wrapper (without reverting to my bash
> > history), I noticed some minor problems when building it, so this series
> > fixes some shortcomings.
> > 
> > See the respective patch subjects below for a summary.
> 
> Ping. Is there anything I can do to help those getting merged?

Sorry for the delay. I've picked the counter frequency fix for now, and
I'll see about picking up the rest with the next batch of updates. I'm
making a few other changes to defaults/configuration and would prefer to
do that all at once with a version-bump flag day.

Thanks,
Mark.

> 
> Cheers,
> Andre
> 
> > 
> > Thanks,
> > Andre
> > 
> > Andre Przywara (6):
> >   configure: Make PSCI the default boot method
> >   configure: Fix default DTB
> >   configure: Use earlycon instead of earlyprintk
> >   Fix arch counter frequency
> >   pointer auth: Document CPU feature bit mask
> >   configure: Autodetect GICv3
> > 
> >  Makefile.am         | 23 +++++++++--------------
> >  arch/aarch64/boot.S |  3 ++-
> >  configure.ac        | 16 ++++------------
> >  3 files changed, 15 insertions(+), 27 deletions(-)
> > 
> 


From bbudiredla at marvell.com  Mon Aug  2 07:34:16 2021
From: bbudiredla at marvell.com (Bhaskara Budiredla)
Date: Mon, 2 Aug 2021 14:34:16 +0000
Subject: [EXT] Re: [PATCH v2 1/1] drivers: perf: Add LLC-TAD perf counter
 support
In-Reply-To: <20210802103401.GA27583@willie-the-truck>
References: <20210614135849.6076-1-bbudiredla@marvell.com>
 <20210802103401.GA27583@willie-the-truck>
Message-ID: <CY4PR1801MB2070C4C855DF5BA87BE8C2B3DEEF9@CY4PR1801MB2070.namprd18.prod.outlook.com>

Hi Will,

>-----Original Message-----
>From: Will Deacon <will at kernel.org>
>Sent: Monday, August 2, 2021 4:04 PM
>To: Bhaskara Budiredla <bbudiredla at marvell.com>
>Cc: mark.rutland at arm.com; Sunil Kovvuri Goutham
><sgoutham at marvell.com>; linux-arm-kernel at lists.infradead.org; linux-
>kernel at vger.kernel.org; robh+dt at kernel.org; devicetree at vger.kernel.org
>Subject: [EXT] Re: [PATCH v2 1/1] drivers: perf: Add LLC-TAD perf counter
>support
>
>External Email
>
>----------------------------------------------------------------------
>On Mon, Jun 14, 2021 at 07:28:49PM +0530, Bhaskara Budiredla wrote:
>> This driver adds support for Last-level cache tag-and-data unit
>> (LLC-TAD) PMU that is featured in some of the Marvell's CN10K
>> infrastructure silicons.
>>
>> The LLC is divided into 2N slices distributed across N Mesh tiles in a
>> single-socket configuration. The driver always configures the same
>> counter for all of the TADs. The user would end up effectively
>> reserving one of eight counters in every TAD to look across all TADs.
>> The occurrences of events are aggregated and presented to the user at
>> the end of an application run. The driver does not provide a way for
>> the user to partition TADs so that different TADs are used for
>> different applications.
>>
>> The event counters are zeroed to start event counting to avoid any
>> rollover issues. TAD perf counters are 64-bit, so it's not currently
>> possible to overflow event counters at current mesh and core
>> frequencies.
>
>I couldn't spot where you disable sampling events, which rely heavily on
>detecting overflow. Probably need PERF_PMU_CAP_NO_INTERRUPT.

Sampling is not supported as counters are 64-bit. I will add
PERF_PMU_CAP_NO_INTERRUPT flag to pmu capabilities.

>
>> To measure tad pmu events use perf tool stat command. For instance:
>>
>> perf stat -e tad_dat_msh_in_dss,tad_req_msh_out_any <application> perf
>> stat -e tad_alloc_any,tad_hit_any,tad_tag_rd <application>
>>
>> Signed-off-by: Bhaskara Budiredla <bbudiredla at marvell.com>
>> ---
>>  .../bindings/perf/marvell-cn10k-tad-pmu.txt   |  20 +
>
>Adding the DT list for this ^^ as it looks a bit odd to me (also shouldn't it be in
>YAML?)

It was just for reference. Actual entries expected to be
amended by ATF. I will fix the formatting.

>
>>  drivers/perf/Kconfig                          |   7 +
>>  drivers/perf/Makefile                         |   1 +
>>  drivers/perf/marvell_cn10k_tad_pmu.c          | 428 ++++++++++++++++++
>
>-ENODOCUMENTATION
>
>>  4 files changed, 456 insertions(+)
>>  create mode 100644
>> Documentation/devicetree/bindings/perf/marvell-cn10k-tad-pmu.txt
>>  create mode 100644 drivers/perf/marvell_cn10k_tad_pmu.c
>>
>> diff --git
>> a/Documentation/devicetree/bindings/perf/marvell-cn10k-tad-pmu.txt
>> b/Documentation/devicetree/bindings/perf/marvell-cn10k-tad-pmu.txt
>> new file mode 100644
>> index 000000000000..8b1f753303e2
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/perf/marvell-cn10k-tad-pmu.txt
>> @@ -0,0 +1,20 @@
>> +* Marvell CN10K LLC-TAD performace monitor unit
>> +
>> +Required properties:
>> +- compatible: must be:
>> +	"marvell,cn10k-tad-pmu"
>> +- tad-cnt: number of tad pmu regions
>> +- tad-page-size: size of entire tad block
>> +- tad-pmu-page-size: size of one tad pmu region
>> +- reg: physical address and size
>> +
>> +Example:
>> +
>> +/* Actual values updated by firmware at boot time */ tad_pmu {
>> +	compatible = "marvell,cn10k-tad-pmu";
>> +	tad-cnt = <1>;
>> +	tad-page-size = <0x1000>;
>> +	tad-pmu-page-size = <0x1000>;
>> +	reg = <0x87e2 0x80000000 0x0 0x1000>; };
>> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig index
>> 77522e5efe11..73dca11f8080 100644
>> --- a/drivers/perf/Kconfig
>> +++ b/drivers/perf/Kconfig
>> @@ -137,6 +137,13 @@ config ARM_DMC620_PMU
>>  	  Support for PMU events monitoring on the ARM DMC-620 memory
>>  	  controller.
>>
>> +config MARVELL_CN10K_TAD_PMU
>> +	tristate "Marvell CN10K LLC-TAD PMU"
>> +	depends on ARM64
>> +	help
>> +	  Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
>> +	  performance monitors on CN10K family silicons.
>> +
>>  source "drivers/perf/hisilicon/Kconfig"
>>
>>  endmenu
>> diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile index
>> 5260b116c7da..2db5418d5b0a 100644
>> --- a/drivers/perf/Makefile
>> +++ b/drivers/perf/Makefile
>> @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) +=
>thunderx2_pmu.o
>>  obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
>>  obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
>>  obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
>> +obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
>> diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c
>> b/drivers/perf/marvell_cn10k_tad_pmu.c
>> new file mode 100644
>> index 000000000000..99878de481f0
>> --- /dev/null
>> +++ b/drivers/perf/marvell_cn10k_tad_pmu.c
>> @@ -0,0 +1,428 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Marvell CN10K LLC-TAD perf driver
>> + *
>> + * Copyright (C) 2021 Marvell.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> +modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#define pr_fmt(fmt) "tad_pmu: " fmt
>> +
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/cpuhotplug.h>
>> +#include <linux/perf_event.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/arm-smccc.h>
>> +
>> +#define TAD_PFC_OFFSET		0x0800
>> +#define TAD_PFC(counter)	(TAD_PFC_OFFSET | (counter << 3))
>> +#define TAD_PRF_OFFSET		0x0900
>> +#define TAD_PRF(counter)	(TAD_PRF_OFFSET | (counter << 3))
>> +#define TAD_PRF_CNTSEL_MASK	0xFF
>> +#define TAD_MAX_COUNTERS	8
>> +
>> +#define to_tad_pmu(p) (container_of(p, struct tad_pmu, pmu))
>> +
>> +struct tad_region {
>> +	void __iomem	*base;
>> +};
>> +
>> +struct tad_pmu {
>> +	struct pmu pmu;
>> +	struct tad_region *regions;
>> +	u32 region_cnt;
>> +	unsigned int cpu;
>> +	struct hlist_node node;
>> +	struct perf_event *events[TAD_MAX_COUNTERS];
>> +	DECLARE_BITMAP(counters_map, TAD_MAX_COUNTERS); };
>> +
>> +static int tad_pmu_cpuhp_state;
>> +
>> +static void tad_pmu_event_counter_read(struct perf_event *event) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>> +	struct hw_perf_event *hwc = &event->hw;
>> +	u32 counter_idx = hwc->idx;
>> +	u64 delta, prev, new;
>> +	int i;
>> +
>> +	do {
>> +		prev = local64_read(&hwc->prev_count);
>> +		for (i = 0, new = 0; i < tad_pmu->region_cnt; i++)
>> +			new += readq(tad_pmu->regions[i].base +
>> +				     TAD_PFC(counter_idx));
>> +	} while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev);
>> +
>> +	delta = (new - prev) & GENMASK_ULL(63, 0);
>> +	local64_add(delta, &event->count);
>> +}
>> +
>> +static void tad_pmu_event_counter_stop(struct perf_event *event, int
>> +flags) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>> +	struct hw_perf_event *hwc = &event->hw;
>> +	u32 counter_idx = hwc->idx;
>> +	int i;
>> +
>> +	/* TAD()_PFC() stop counting on the write
>> +	 * which sets TAD()_PRF()[CNTSEL] == 0
>> +	 */
>> +	for (i = 0; i < tad_pmu->region_cnt; i++)
>> +		writeq(0, tad_pmu->regions[i].base + TAD_PRF(counter_idx));
>
>writeq_relaxed() should be sufficient for this (and the others in this driver),
>no?

Yes, *_relaxed() is sufficient for writes. Taken.

>
>> +static ssize_t tad_pmu_event_show(struct device *dev,
>> +				struct device_attribute *attr, char *page) {
>> +	struct perf_pmu_events_attr *pmu_attr;
>> +
>> +	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
>> +	return sprintf(page, "event=0x%02llx\n", pmu_attr->id); }
>> +
>> +#define TAD_PMU_EVENT_ATTR(_name, _id)
>		\
>> +	(&((struct perf_pmu_events_attr[]) {				\
>> +		{ .attr = __ATTR(_name, 0444, tad_pmu_event_show, NULL),\
>> +		  .id = _id, }						\
>> +	})[0].attr.attr)
>
>Use PMU_EVENT_ATTR_ID instead?

Ok, taken.

>
>> +static int tad_pmu_probe(struct platform_device *pdev) {
>> +	struct device_node *node = pdev->dev.of_node;
>> +	struct tad_region *regions;
>> +	struct tad_pmu *tad_pmu;
>> +	struct resource *res;
>> +	u32 tad_pmu_page_size;
>> +	u32 tad_page_size;
>> +	u32 tad_cnt;
>> +	int i, ret;
>> +	char *name;
>> +
>> +	tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu),
>GFP_KERNEL);
>> +	if (!tad_pmu)
>> +		return -ENOMEM;
>> +
>> +	platform_set_drvdata(pdev, tad_pmu);
>> +
>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +	if (!res) {
>> +		dev_err(&pdev->dev, "Mem resource not found\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	ret = of_property_read_u32(node, "tad-page-size", &tad_page_size);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "Can't find tad-page-size property\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = of_property_read_u32(node, "tad-pmu-page-size",
>> +				   &tad_pmu_page_size);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "Can't find tad-pmu-page-size
>property\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = of_property_read_u32(node, "tad-cnt", &tad_cnt);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "Can't find tad-cnt property\n");
>> +		return ret;
>> +	}
>> +
>> +	regions = kcalloc(tad_cnt, sizeof(*regions), GFP_KERNEL);
>
>devm_kcalloc() instead?

Agree, taken.

>
>Will


From cniedermaier at dh-electronics.com  Mon Aug  2 07:10:36 2021
From: cniedermaier at dh-electronics.com (Christoph Niedermaier)
Date: Mon, 2 Aug 2021 16:10:36 +0200
Subject: [PATCH V7 5/7] ARM: dts: imx6qdl-dhcom: Split SoC-independent parts
 of DHCOM SOM and PDK2
In-Reply-To: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
Message-ID: <20210802141038.59663-5-cniedermaier@dh-electronics.com>

The DH electronics PDK2 can be populated with SoM with i.MX6S/DL/D/Q
variants. Split the SoC-independent parts of the SoM and PDK2 into the
imx6qdl-dhcom-*.dtsi and reduce imx6q-dhcom-pdk2.dts to example of
adding i.MX6S/DL/D/Q variants of the SoM into a PDK2 carrier board.

Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Fabio Estevam <festevam at denx.de>
Cc: Marek Vasut <marex at denx.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: kernel at dh-electronics.com
To: linux-arm-kernel at lists.infradead.org
---
V2: - Fix typo in commit message
    - Rebase on Shawn Guos branch for-next
V3: - No changes
V4: - No changes
V5: - No changes
V6: - Rebase on 5.14-rc1
V7: - Rebase on Shawn Guos branch for-next
---
 arch/arm/boot/dts/imx6q-dhcom-pdk2.dts             | 376 +--------------------
 arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi          | 361 ++++++++++++++++++++
 ...imx6q-dhcom-som.dtsi => imx6qdl-dhcom-som.dtsi} |  30 +-
 3 files changed, 393 insertions(+), 374 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi
 rename arch/arm/boot/dts/{imx6q-dhcom-som.dtsi => imx6qdl-dhcom-som.dtsi} (97%)

diff --git a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
index 4b8801e91bd4..d4d57370615d 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
+++ b/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
@@ -2,378 +2,24 @@
 /*
  * Copyright (C) 2015-2021 DH electronics GmbH
  * Copyright (C) 2018 Marek Vasut <marex at denx.de>
+ *
+ * DHCOM iMX6 variant:
+ * DHCM-iMX6Q-C0800-R102-F0819-E-SD-RTC-T-HS-I-01D2
+ * DHCOM PCB number: 493-300 or newer
+ * PDK2 PCB number: 516-400 or newer
  */
-
 /dts-v1/;
 
-#include "imx6q-dhcom-som.dtsi"
-#include <dt-bindings/leds/common.h>
+#include "imx6q.dtsi"
+#include "imx6qdl-dhcom-som.dtsi"
+#include "imx6qdl-dhcom-pdk2.dtsi"
 
 / {
-	model = "Freescale i.MX6 Quad DHCOM Premium Developer Kit (2)";
-	compatible = "dh,imx6q-dhcom-pdk2", "dh,imx6q-dhcom-som", "fsl,imx6q";
-
-	chosen {
-		stdout-path = "serial0:115200n8";
-	};
-
-	clk_ext_audio_codec: clock-codec {
-		#clock-cells = <0>;
-		clock-frequency = <24000000>;
-		compatible = "fixed-clock";
-	};
-
-	display_bl: display-bl {
-		brightness-levels = <0 16 22 30 40 55 75 102 138 188 255>;
-		compatible = "pwm-backlight";
-		default-brightness-level = <8>;
-		enable-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>; /* GPIO G */
-		pwms = <&pwm1 0 50000 PWM_POLARITY_INVERTED>;
-		status = "okay";
-	};
-
-	lcd_display: disp0 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		compatible = "fsl,imx-parallel-display";
-		interface-pix-fmt = "rgb24";
-		pinctrl-0 = <&pinctrl_ipu1_lcdif &pinctrl_dhcom_g>;
-		pinctrl-names = "default";
-		status = "okay";
-
-		port at 0 {
-			reg = <0>;
-
-			lcd_display_in: endpoint {
-				remote-endpoint = <&ipu1_di0_disp0>;
-			};
-		};
-
-		port at 1 {
-			reg = <1>;
-
-			lcd_display_out: endpoint {
-				remote-endpoint = <&lcd_panel_in>;
-			};
-		};
-	};
-
-	gpio-keys {
-		#size-cells = <0>;
-		compatible = "gpio-keys";
-
-		button-0 {
-			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; /* GPIO A */
-			label = "TA1-GPIO-A";
-			linux,code = <KEY_A>;
-			pinctrl-0 = <&pinctrl_dhcom_a>;
-			pinctrl-names = "default";
-			wakeup-source;
-		};
-
-		button-1 {
-			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* GPIO B */
-			label = "TA2-GPIO-B";
-			linux,code = <KEY_B>;
-			pinctrl-0 = <&pinctrl_dhcom_b>;
-			pinctrl-names = "default";
-			wakeup-source;
-		};
-
-		button-2 {
-			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; /* GPIO C */
-			label = "TA3-GPIO-C";
-			linux,code = <KEY_C>;
-			pinctrl-0 = <&pinctrl_dhcom_c>;
-			pinctrl-names = "default";
-			wakeup-source;
-		};
-
-		button-3 {
-			gpios = <&gpio6 3 GPIO_ACTIVE_LOW>; /* GPIO D */
-			label = "TA4-GPIO-D";
-			linux,code = <KEY_D>;
-			pinctrl-0 = <&pinctrl_dhcom_d>;
-			pinctrl-names = "default";
-			wakeup-source;
-		};
-	};
-
-	led {
-		compatible = "gpio-leds";
-
-		/*
-		 * Disable led-5, because GPIO E is
-		 * already used as touch interrupt.
-		 */
-		led-5 {
-			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
-			function = LED_FUNCTION_INDICATOR;
-			gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* GPIO E */
-			pinctrl-0 = <&pinctrl_dhcom_e>;
-			pinctrl-names = "default";
-			status = "disabled";
-		};
-
-		led-6 {
-			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
-			function = LED_FUNCTION_INDICATOR;
-			gpios = <&gpio4 20 GPIO_ACTIVE_HIGH>; /* GPIO F */
-			pinctrl-0 = <&pinctrl_dhcom_f>;
-			pinctrl-names = "default";
-		};
-
-		led-7 {
-			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
-			function = LED_FUNCTION_INDICATOR;
-			gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* GPIO H */
-			pinctrl-0 = <&pinctrl_dhcom_h>;
-			pinctrl-names = "default";
-		};
-
-		led-8 {
-			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
-			function = LED_FUNCTION_INDICATOR;
-			gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */
-			pinctrl-0 = <&pinctrl_dhcom_i>;
-			pinctrl-names = "default";
-		};
-	};
-
-	panel {
-		backlight = <&display_bl>;
-		compatible = "edt,etm0700g0edh6";
-
-		port {
-			lcd_panel_in: endpoint {
-				remote-endpoint = <&lcd_display_out>;
-			};
-		};
-	};
-
-	sound {
-		audio-codec = <&sgtl5000>;
-		audio-routing =
-			"MIC_IN", "Mic Jack",
-			"Mic Jack", "Mic Bias",
-			"LINE_IN", "Line In Jack",
-			"Headphone Jack", "HP_OUT";
-		compatible = "fsl,imx-audio-sgtl5000";
-		model = "imx-sgtl5000";
-		mux-ext-port = <3>;
-		mux-int-port = <1>;
-		ssi-controller = <&ssi1>;
-	};
-};
-
-&audmux {
-	pinctrl-0 = <&pinctrl_audmux_ext>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&can1 {
-	status = "okay";
-};
-
-&can2 {
-	status = "disabled";
-};
-
-/* 1G ethernet */
-/delete-node/ &ethphy0;
-&fec {
-	phy-mode = "rgmii";
-	phy-handle = <&ethphy7>;
-	pinctrl-0 = <&pinctrl_enet_1G>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	mdio {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		ethphy7: ethernet-phy at 7 { /* KSZ 9021 */
-			compatible = "ethernet-phy-ieee802.3-c22";
-			interrupt-parent = <&gpio1>;
-			interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-			pinctrl-0 = <&pinctrl_ethphy7>;
-			pinctrl-names = "default";
-			reg = <7>;
-			reset-assert-us = <1000>;
-			reset-deassert-us = <1000>;
-			reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
-			rxc-skew-ps = <3000>;
-			rxd0-skew-ps = <0>;
-			rxd1-skew-ps = <0>;
-			rxd2-skew-ps = <0>;
-			rxd3-skew-ps = <0>;
-			rxdv-skew-ps = <0>;
-			txc-skew-ps = <3000>;
-			txd0-skew-ps = <0>;
-			txd1-skew-ps = <0>;
-			txd2-skew-ps = <0>;
-			txd3-skew-ps = <0>;
-			txen-skew-ps = <0>;
-		};
-	};
-};
-
-&hdmi {
-	ddc-i2c-bus = <&i2c2>;
-	status = "okay";
-};
-
-&i2c2 {
-	sgtl5000: codec at a {
-		#sound-dai-cells = <0>;
-		clocks = <&clk_ext_audio_codec>;
-		compatible = "fsl,sgtl5000";
-		reg = <0x0a>;
-		VDDA-supply = <&reg_3p3v>;
-		VDDIO-supply = <&sw2_reg>;
-	};
-
-	touchscreen at 38 {
-		compatible = "edt,edt-ft5406";
-		interrupt-parent = <&gpio4>;
-		interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */
-		pinctrl-0 = <&pinctrl_dhcom_e>;
-		pinctrl-names = "default";
-		reg = <0x38>;
-	};
-};
-
-&ipu1_di0_disp0 {
-	remote-endpoint = <&lcd_display_in>;
-};
-
-&pcie {
-	pinctrl-0 = <&pinctrl_pcie &pinctrl_dhcom_j>;
-	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>; /* GPIO J */
-	status = "okay";
-};
-
-&pwm1 {
-	pinctrl-0 = <&pinctrl_pwm1>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&ssi1 {
-	status = "okay";
+	model = "DH electronics i.MX6Q DHCOM on Premium Developer Kit (2)";
+	compatible = "dh,imx6q-dhcom-pdk2", "dh,imx6q-dhcom-som",
+		     "fsl,imx6q";
 };
 
 &sata {
 	status = "okay";
 };
-
-&usdhc3 { /* Micro SD card on module */
-	status = "okay";
-};
-
-&iomuxc {
-	pinctrl-0 = <
-			/*
-			 * The following DHCOM GPIOs are used on this board.
-			 * Therefore, they have been removed from the list below.
-			 * A: key TA1
-			 * B: key TA2
-			 * C: key TA3
-			 * D: key TA4
-			 * E: touchscreen
-			 * F: led6
-			 * G: backlight enable
-			 * H: led7
-			 * I: led8
-			 * J: PCIe reset
-			 */
-			&pinctrl_hog_base
-			&pinctrl_dhcom_k &pinctrl_dhcom_l
-			&pinctrl_dhcom_m &pinctrl_dhcom_n &pinctrl_dhcom_o
-			&pinctrl_dhcom_p &pinctrl_dhcom_q &pinctrl_dhcom_r
-			&pinctrl_dhcom_s &pinctrl_dhcom_t &pinctrl_dhcom_u
-			&pinctrl_dhcom_v &pinctrl_dhcom_w &pinctrl_dhcom_int
-		>;
-	pinctrl-names = "default";
-
-	pinctrl_audmux_ext: audmux-ext-grp {
-		fsl,pins = <
-			MX6QDL_PAD_CSI0_DAT4__AUD3_TXC		0x130b0
-			MX6QDL_PAD_CSI0_DAT5__AUD3_TXD		0x110b0
-			MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS		0x130b0
-			MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
-		>;
-	};
-
-	pinctrl_enet_1G: enet-1G-grp {
-		fsl,pins = <
-			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x100b0
-			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x100b0
-			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x100b0
-			MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
-			MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
-			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
-			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
-			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
-			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
-			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x100b0
-			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x100b0
-			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x100b0
-			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x100b0
-			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x100b0
-			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x100b0
-		>;
-	};
-
-	pinctrl_ethphy7: ethphy7-grp {
-		fsl,pins = <
-			MX6QDL_PAD_EIM_D26__GPIO3_IO26		0xb1 /* WOL */
-			MX6QDL_PAD_EIM_D29__GPIO3_IO29		0xb0 /* Reset */
-			MX6QDL_PAD_GPIO_0__GPIO1_IO00		0xb1 /* Int */
-		>;
-	};
-
-	pinctrl_ipu1_lcdif: ipu1-lcdif-grp {
-		fsl,pins = <
-			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK	0x38
-			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02		0x38
-			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03		0x38
-			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x38
-			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00	0x38
-			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01	0x38
-			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02	0x38
-			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03	0x38
-			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04	0x38
-			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05	0x38
-			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06	0x38
-			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07	0x38
-			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08	0x38
-			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09	0x38
-			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10	0x38
-			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11	0x38
-			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12	0x38
-			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13	0x38
-			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14	0x38
-			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15	0x38
-			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16	0x38
-			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17	0x38
-			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18	0x38
-			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19	0x38
-			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20	0x38
-			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21	0x38
-			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22	0x38
-			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23	0x38
-		>;
-	};
-
-	pinctrl_pwm1: pwm1-grp {
-		fsl,pins = <
-			MX6QDL_PAD_SD1_DAT3__PWM1_OUT		0x1b0b1
-		>;
-	};
-};
diff --git a/arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi b/arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi
new file mode 100644
index 000000000000..dc21853706a5
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi
@@ -0,0 +1,361 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015-2021 DH electronics GmbH
+ * Copyright (C) 2018 Marek Vasut <marex at denx.de>
+ */
+
+#include <dt-bindings/leds/common.h>
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	clk_ext_audio_codec: clock-codec {
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		compatible = "fixed-clock";
+	};
+
+	display_bl: display-bl {
+		brightness-levels = <0 16 22 30 40 55 75 102 138 188 255>;
+		compatible = "pwm-backlight";
+		default-brightness-level = <8>;
+		enable-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>; /* GPIO G */
+		pwms = <&pwm1 0 50000 PWM_POLARITY_INVERTED>;
+		status = "okay";
+	};
+
+	lcd_display: disp0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "fsl,imx-parallel-display";
+		interface-pix-fmt = "rgb24";
+		pinctrl-0 = <&pinctrl_ipu1_lcdif &pinctrl_dhcom_g>;
+		pinctrl-names = "default";
+		status = "okay";
+
+		port at 0 {
+			reg = <0>;
+
+			lcd_display_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			lcd_display_out: endpoint {
+				remote-endpoint = <&lcd_panel_in>;
+			};
+		};
+	};
+
+	gpio-keys {
+		#size-cells = <0>;
+		compatible = "gpio-keys";
+
+		button-0 {
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; /* GPIO A */
+			label = "TA1-GPIO-A";
+			linux,code = <KEY_A>;
+			pinctrl-0 = <&pinctrl_dhcom_a>;
+			pinctrl-names = "default";
+			wakeup-source;
+		};
+
+		button-1 {
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* GPIO B */
+			label = "TA2-GPIO-B";
+			linux,code = <KEY_B>;
+			pinctrl-0 = <&pinctrl_dhcom_b>;
+			pinctrl-names = "default";
+			wakeup-source;
+		};
+
+		button-2 {
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; /* GPIO C */
+			label = "TA3-GPIO-C";
+			linux,code = <KEY_C>;
+			pinctrl-0 = <&pinctrl_dhcom_c>;
+			pinctrl-names = "default";
+			wakeup-source;
+		};
+
+		button-3 {
+			gpios = <&gpio6 3 GPIO_ACTIVE_LOW>; /* GPIO D */
+			label = "TA4-GPIO-D";
+			linux,code = <KEY_D>;
+			pinctrl-0 = <&pinctrl_dhcom_d>;
+			pinctrl-names = "default";
+			wakeup-source;
+		};
+	};
+
+	led {
+		compatible = "gpio-leds";
+
+		/*
+		 * Disable led-5, because GPIO E is
+		 * already used as touch interrupt.
+		 */
+		led-5 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
+			function = LED_FUNCTION_INDICATOR;
+			gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* GPIO E */
+			pinctrl-0 = <&pinctrl_dhcom_e>;
+			pinctrl-names = "default";
+			status = "disabled";
+		};
+
+		led-6 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
+			function = LED_FUNCTION_INDICATOR;
+			gpios = <&gpio4 20 GPIO_ACTIVE_HIGH>; /* GPIO F */
+			pinctrl-0 = <&pinctrl_dhcom_f>;
+			pinctrl-names = "default";
+		};
+
+		led-7 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
+			function = LED_FUNCTION_INDICATOR;
+			gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* GPIO H */
+			pinctrl-0 = <&pinctrl_dhcom_h>;
+			pinctrl-names = "default";
+		};
+
+		led-8 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "off";
+			function = LED_FUNCTION_INDICATOR;
+			gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */
+			pinctrl-0 = <&pinctrl_dhcom_i>;
+			pinctrl-names = "default";
+		};
+	};
+
+	panel {
+		backlight = <&display_bl>;
+		compatible = "edt,etm0700g0edh6";
+
+		port {
+			lcd_panel_in: endpoint {
+				remote-endpoint = <&lcd_display_out>;
+			};
+		};
+	};
+
+	sound {
+		audio-codec = <&sgtl5000>;
+		audio-routing =
+			"MIC_IN", "Mic Jack",
+			"Mic Jack", "Mic Bias",
+			"LINE_IN", "Line In Jack",
+			"Headphone Jack", "HP_OUT";
+		compatible = "fsl,imx-audio-sgtl5000";
+		model = "imx-sgtl5000";
+		mux-ext-port = <3>;
+		mux-int-port = <1>;
+		ssi-controller = <&ssi1>;
+	};
+};
+
+&audmux {
+	pinctrl-0 = <&pinctrl_audmux_ext>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&can1 {
+	status = "okay";
+};
+
+&can2 {
+	status = "disabled";
+};
+
+/* 1G ethernet */
+/delete-node/ &ethphy0;
+&fec {
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy7>;
+	pinctrl-0 = <&pinctrl_enet_1G>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy7: ethernet-phy at 7 { /* KSZ 9021 */
+			compatible = "ethernet-phy-ieee802.3-c22";
+			interrupt-parent = <&gpio1>;
+			interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+			pinctrl-0 = <&pinctrl_ethphy7>;
+			pinctrl-names = "default";
+			reg = <7>;
+			reset-assert-us = <1000>;
+			reset-deassert-us = <1000>;
+			reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
+			rxc-skew-ps = <3000>;
+			rxd0-skew-ps = <0>;
+			rxd1-skew-ps = <0>;
+			rxd2-skew-ps = <0>;
+			rxd3-skew-ps = <0>;
+			rxdv-skew-ps = <0>;
+			txc-skew-ps = <3000>;
+			txd0-skew-ps = <0>;
+			txd1-skew-ps = <0>;
+			txd2-skew-ps = <0>;
+			txd3-skew-ps = <0>;
+			txen-skew-ps = <0>;
+		};
+	};
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c2 {
+	sgtl5000: codec at a {
+		#sound-dai-cells = <0>;
+		clocks = <&clk_ext_audio_codec>;
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		VDDA-supply = <&reg_3p3v>;
+		VDDIO-supply = <&sw2_reg>;
+	};
+
+	touchscreen at 38 {
+		compatible = "edt,edt-ft5406";
+		interrupt-parent = <&gpio4>;
+		interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */
+		pinctrl-0 = <&pinctrl_dhcom_e>;
+		pinctrl-names = "default";
+		reg = <0x38>;
+	};
+};
+
+&ipu1_di0_disp0 {
+	remote-endpoint = <&lcd_display_in>;
+};
+
+&pcie {
+	pinctrl-0 = <&pinctrl_pcie &pinctrl_dhcom_j>;
+	reset-gpio = <&gpio6 14 GPIO_ACTIVE_LOW>; /* GPIO J */
+	status = "okay";
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&ssi1 {
+	status = "okay";
+};
+
+&usdhc2 { /* SD card */
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-0 = <
+			/*
+			 * The following DHCOM GPIOs are used on this board.
+			 * Therefore, they have been removed from the list below.
+			 * A: key TA1
+			 * B: key TA2
+			 * C: key TA3
+			 * D: key TA4
+			 * E: touchscreen
+			 * F: led6
+			 * G: backlight enable
+			 * H: led7
+			 * I: led8
+			 * J: PCIe reset
+			 */
+			&pinctrl_hog_base
+			&pinctrl_dhcom_k &pinctrl_dhcom_l
+			&pinctrl_dhcom_m &pinctrl_dhcom_n &pinctrl_dhcom_o
+			&pinctrl_dhcom_p &pinctrl_dhcom_q &pinctrl_dhcom_r
+			&pinctrl_dhcom_s &pinctrl_dhcom_t &pinctrl_dhcom_u
+			&pinctrl_dhcom_v &pinctrl_dhcom_w &pinctrl_dhcom_int
+		>;
+	pinctrl-names = "default";
+
+	pinctrl_audmux_ext: audmux-ext-grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT4__AUD3_TXC		0x130b0
+			MX6QDL_PAD_CSI0_DAT5__AUD3_TXD		0x110b0
+			MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS		0x130b0
+			MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
+		>;
+	};
+
+	pinctrl_enet_1G: enet-1G-grp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_MDC__ENET_MDC		0x100b0
+			MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x100b0
+			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x100b0
+			MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
+			MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
+			MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
+			MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
+			MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
+			MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
+			MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x100b0
+			MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x100b0
+			MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x100b0
+			MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x100b0
+			MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x100b0
+			MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x100b0
+		>;
+	};
+
+	pinctrl_ethphy7: ethphy7-grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D26__GPIO3_IO26		0xb1 /* WOL */
+			MX6QDL_PAD_EIM_D29__GPIO3_IO29		0xb0 /* Reset */
+			MX6QDL_PAD_GPIO_0__GPIO1_IO00		0xb1 /* Int */
+		>;
+	};
+
+	pinctrl_ipu1_lcdif: ipu1-lcdif-grp {
+		fsl,pins = <
+			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK	0x38
+			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02		0x38
+			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03		0x38
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x38
+			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00	0x38
+			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01	0x38
+			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02	0x38
+			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03	0x38
+			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04	0x38
+			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05	0x38
+			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06	0x38
+			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07	0x38
+			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08	0x38
+			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09	0x38
+			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10	0x38
+			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11	0x38
+			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12	0x38
+			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13	0x38
+			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14	0x38
+			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15	0x38
+			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16	0x38
+			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17	0x38
+			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18	0x38
+			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19	0x38
+			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20	0x38
+			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21	0x38
+			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22	0x38
+			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23	0x38
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi b/arch/arm/boot/dts/imx6qdl-dhcom-som.dtsi
similarity index 97%
rename from arch/arm/boot/dts/imx6q-dhcom-som.dtsi
rename to arch/arm/boot/dts/imx6qdl-dhcom-som.dtsi
index 99a275e06643..5d10c40313cb 100644
--- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-dhcom-som.dtsi
@@ -4,7 +4,6 @@
  * Copyright (C) 2018 Marek Vasut <marex at denx.de>
  */
 
-#include "imx6q.dtsi"
 #include <dt-bindings/pwm/pwm.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/clock/imx6qdl-clock.h>
@@ -82,18 +81,20 @@
 &can1 {
 	pinctrl-0 = <&pinctrl_flexcan1>;
 	pinctrl-names = "default";
+	status = "okay";
 };
 
 /*
- * Special hardware required which uses the pins from micro SD card. The pins
- * SD3_DAT0 and SD3_DAT1 are muxed as can2 Tx and Rx. The signals for can2 Tx
- * and Rx are output on DHCOM uart1 rts/cts pins. So to enable can2 on the board
- * device tree file, you also need to disable the micro SD card and the uart1
- * rts/cts have to be disabled or output on other DHCOM pins.
+ * Special SoM hardware required which uses the pins from micro SD card. The
+ * pins SD3_DAT0 and SD3_DAT1 are muxed as can2 Tx and Rx. The signals for can2
+ * Tx and Rx are routed to the DHCOM UART1 rts/cts pins. So to enable can2 on
+ * the board device tree file, the micro SD card must be disabled and the uart1
+ * rts/cts must be disabled or output on other DHCOM pins.
  */
 &can2 {
 	pinctrl-0 = <&pinctrl_flexcan2>;
 	pinctrl-names = "default";
+	status = "disabled";
 };
 
 &ecspi1 {
@@ -116,7 +117,7 @@
 	cs-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
 	pinctrl-0 = <&pinctrl_ecspi2>;
 	pinctrl-names = "default";
-	status = "okay";
+	status = "disabled";
 };
 
 &fec {
@@ -334,6 +335,11 @@
 	pinctrl-names = "default";
 };
 
+&pwm1 {
+	pinctrl-0 = <&pinctrl_pwm1>;
+	pinctrl-names = "default";
+};
+
 &reg_arm {
 	vin-supply = <&sw3_reg>;
 };
@@ -400,7 +406,7 @@
 	keep-power-in-suspend;
 	pinctrl-0 = <&pinctrl_usdhc2>;
 	pinctrl-names = "default";
-	status = "okay";
+	status = "disabled";
 };
 
 &usdhc3 { /* Micro SD card on module */
@@ -409,7 +415,7 @@
 	keep-power-in-suspend;
 	pinctrl-0 = <&pinctrl_usdhc3>;
 	pinctrl-names = "default";
-	status = "disabled";
+	status = "okay";
 };
 
 &usdhc4 { /* eMMC on module */
@@ -672,6 +678,12 @@
 		>;
 	};
 
+	pinctrl_pwm1: pwm1-grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_DAT3__PWM1_OUT		0x1b0b1
+		>;
+	};
+
 	pinctrl_rtc: rtc-grp {
 		fsl,pins = <
 			MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x120b0
-- 
2.11.0



From cniedermaier at dh-electronics.com  Mon Aug  2 07:10:37 2021
From: cniedermaier at dh-electronics.com (Christoph Niedermaier)
Date: Mon, 2 Aug 2021 16:10:37 +0200
Subject: [PATCH V7 6/7] ARM: dts: imx6qdl-dhcom: Add DHCOM based PicoITX board
In-Reply-To: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
Message-ID: <20210802141038.59663-6-cniedermaier@dh-electronics.com>

Add DT for DH PicoITX unit, which is a bare-bones carrier board for
the DHCOM. The board has ethernet port, USB, CAN, LEDs and a custom
board-to-board expansion connector.

Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Fabio Estevam <festevam at denx.de>
Cc: Marek Vasut <marex at denx.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: kernel at dh-electronics.com
To: linux-arm-kernel at lists.infradead.org
---
V2: - Rebase on Shawn Guos branch for-next
V3: - Replace the property label with the
      properties color and function
V4: - No changes
V5: - Include dt-bindings/leds/common.h file to carrier board file
V6: - Rebase on 5.14-rc1
V7: - Rebase on Shawn Guos branch for-next
---
 arch/arm/boot/dts/Makefile                   |  1 +
 arch/arm/boot/dts/imx6dl-dhcom-picoitx.dts   | 20 ++++++++
 arch/arm/boot/dts/imx6qdl-dhcom-picoitx.dtsi | 69 ++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6dl-dhcom-picoitx.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-dhcom-picoitx.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 828fefc9c436..199bc106627c 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -429,6 +429,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6dl-cubox-i-emmc-som-v15.dtb \
 	imx6dl-cubox-i-som-v15.dtb \
 	imx6dl-dfi-fs700-m60.dtb \
+	imx6dl-dhcom-picoitx.dtb \
 	imx6dl-eckelmann-ci4x10.dtb \
 	imx6dl-emcon-avari.dtb \
 	imx6dl-gw51xx.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-dhcom-picoitx.dts b/arch/arm/boot/dts/imx6dl-dhcom-picoitx.dts
new file mode 100644
index 000000000000..038bb0025556
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-dhcom-picoitx.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 DH electronics GmbH
+ *
+ * DHCOM iMX6 variant:
+ * DHCM-iMX6DL-C0800-R102-F0819-E-SD-RTC-T-HS-I-01D2
+ * DHCOM PCB number: 493-300 or newer
+ * PicoITX PCB number: 487-600 or newer
+ */
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-dhcom-som.dtsi"
+#include "imx6qdl-dhcom-picoitx.dtsi"
+
+/ {
+	model = "DH electronics i.MX6DL DHCOM on PicoITX";
+	compatible = "dh,imx6dl-dhcom-picoitx", "dh,imx6dl-dhcom-som",
+		     "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-dhcom-picoitx.dtsi b/arch/arm/boot/dts/imx6qdl-dhcom-picoitx.dtsi
new file mode 100644
index 000000000000..4cd4cb9543c8
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-dhcom-picoitx.dtsi
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 DH electronics GmbH
+ */
+
+#include <dt-bindings/leds/common.h>
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	led {
+		compatible = "gpio-leds";
+
+		led-0 {
+			color = <LED_COLOR_ID_YELLOW>;
+			default-state = "off";
+			function = LED_FUNCTION_INDICATOR;
+			gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */
+			pinctrl-0 = <&pinctrl_dhcom_i>;
+			pinctrl-names = "default";
+		};
+	};
+};
+
+&gpio1 {
+	gpio-line-names =
+		"", "", "DHCOM-A", "", "DHCOM-B", "PicoITX-In2", "", "",
+		"", "", "", "", "", "", "", "",
+		"DHCOM-R", "DHCOM-S", "DHCOM-Q", "DHCOM-T", "DHCOM-U", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+	gpio-line-names =
+		"", "", "", "", "", "PicoITX-In1", "DHCOM-INT", "DHCOM-H",
+		"DHCOM-I", "PicoITX-HW2", "", "", "", "", "", "",
+		"", "", "", "", "PicoITX-Out1", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio6 {
+	gpio-line-names =
+		"", "", "", "PicoITX-Out2", "", "", "SOM-HW1", "",
+		"", "", "", "", "", "", "PicoITX-HW0", "PicoITX-HW1",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&iomuxc {
+	pinctrl-0 = <
+			/*
+			 * The following DHCOM GPIOs are used on this board.
+			 * Therefore, they have been removed from the list below.
+			 * I: yellow led
+			 */
+			&pinctrl_hog_base
+			&pinctrl_dhcom_a &pinctrl_dhcom_b &pinctrl_dhcom_c
+			&pinctrl_dhcom_d &pinctrl_dhcom_e &pinctrl_dhcom_f
+			&pinctrl_dhcom_g &pinctrl_dhcom_h
+			&pinctrl_dhcom_j &pinctrl_dhcom_k &pinctrl_dhcom_l
+			&pinctrl_dhcom_m &pinctrl_dhcom_n &pinctrl_dhcom_o
+			&pinctrl_dhcom_p &pinctrl_dhcom_q &pinctrl_dhcom_r
+			&pinctrl_dhcom_s &pinctrl_dhcom_t &pinctrl_dhcom_u
+			&pinctrl_dhcom_v &pinctrl_dhcom_w &pinctrl_dhcom_int
+		>;
+	pinctrl-names = "default";
+};
-- 
2.11.0



From mark.rutland at arm.com  Mon Aug  2 07:43:42 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 2 Aug 2021 15:43:42 +0100
Subject: [boot-wrapper PATCH 04/12] Remove `flag_no_el3`
In-Reply-To: <20210730164333.GF19569@C02TD0UTHF1T.local>
References: <20210729152050.23635-1-mark.rutland@arm.com>
 <20210729152050.23635-5-mark.rutland@arm.com>
 <20210730161305.4064f576@slackpad.fritz.box>
 <20210730164333.GF19569@C02TD0UTHF1T.local>
Message-ID: <20210802144342.GB59710@C02TD0UTHF1T.local>

On Fri, Jul 30, 2021 at 05:43:33PM +0100, Mark Rutland wrote:
> On Fri, Jul 30, 2021 at 04:13:05PM +0100, Andre Przywara wrote:
> > On Thu, 29 Jul 2021 16:20:42 +0100
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > 
> > Hi,
> > 
> > > We set `flag_no_el3` when not booted at EL3 / monitor mode, and
> > > subsequently we use this to determine whether we need to drop exception
> > > level before entering Linux. As this can be derived from CurrentEL or
> > > CPSR, the flag itself is redundant, and we can defer the check until
> > > we're about to enter Linux.
> > > 
> > > In future this will allow more logic to be converted into C, where it
> > > will be easier to handle architectural variants.
> > > 
> > > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > > ---
> > >  arch/aarch32/boot.S | 14 +++-----------
> > >  arch/aarch64/boot.S | 13 ++-----------
> > >  2 files changed, 5 insertions(+), 22 deletions(-)
> > > 
> > > diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> > > index 2a85ad5..0bd1ca2 100644
> > > --- a/arch/aarch32/boot.S
> > > +++ b/arch/aarch32/boot.S
> > > @@ -31,9 +31,6 @@ ENTRY(_start)
> > >  	cmp	r0, #PSR_HYP
> > >  	bne	_switch_monitor
> > 
> > Can't this become "beq start_no_el3" now?
> 
> I'm working to *remove* the el3/no_el3 labels, and handle the specific
> exception levels as required, so I don't want to introduce that.
> 
> This says exactly what it does (i.e. switch to monitor mode), so I'd
> rather leave it as-is.
> 
> > > -	mov	r0, #1
> > > -	ldr	r1, =flag_no_el3
> > > -	str	r0, [r1]
> > >  	b	start_no_el3
> > >  
> > >  _switch_monitor:
> > > @@ -89,9 +86,9 @@ ENTRY(jump_kernel)
> > >  	ldr	lr, [r5], #4
> > >  	ldm	r5, {r0 - r2}
> > >  
> > > -	ldr	r4, =flag_no_el3
> > > -	ldr	r4, [r4]
> > > -	cmp	r4, #1
> > > +	mrs	r4, cpsr
> > > +	and	r4, #PSR_MODE_MASK
> > > +	cmp	r4, #PSR_MON
> > 
> > Is comparing explicitly against monitor mode the right thing? IIRC
> > normally we come out of reset in secure SVC, and this *is* EL3 (the
> > highest implemented exception level), from an ARMv8 perspective.
> 
> I agree it's not quite right, but the situation is more complicated:
> It's more complicated than that. For details see:
> 
> * G1.4.1 "About the AArch32 PE modes"
> * G1.9.1 "AArch32 state PE mode descriptions"
> * G1.17 "Reset into AArch32 state" says:
> 
> The summary is:
> 
> * AArch32 doesn't necessarily reset into EL3. EL3 an EL2 are OPTIONAL.
> 
> * Supervisor mode can exist in EL3, Secure EL1, and Non-Secure EL1, and
>   the PSR doesn't tell you which of the three you're in.
> 
> The boot-wrapper currently assumes we reset into EL3 or Non-Secure EL2,
> and this is after the switch, where we should be in monitor mode
> (otherwise PSCI cannot work, since we can't write to MVBAR). I'm not
> changing that assumption. 

Upon reflection, I'm going to drop this patch from the series for now
and rework it to make the above clearer and more robust...

> We should be able to rework that to *try* to switch to monitor mode, and
> if that fails stick to S/NS EL1. I'm happy to tackle that as a follow
> up, organising the logic so we can rely on:
> 
> * MON being EL3
> * HYP being NS EL2
> * SVC being S EL1 or NS EL1

... and to try to make this true as a first step.

Thanks,
Mark.


From acme at kernel.org  Mon Aug  2 07:44:36 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 2 Aug 2021 11:44:36 -0300
Subject: [RFC PATCH 1/6] perf tools: Add WARN_ONCE equivalent for UI
 warnings
In-Reply-To: <20210729155805.2830-2-james.clark@arm.com>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-2-james.clark@arm.com>
Message-ID: <YQgE1CBje091cL3t@kernel.org>

Em Thu, Jul 29, 2021 at 04:58:00PM +0100, James Clark escreveu:
> Currently WARN_ONCE prints to stderr and corrupts the TUI. Add
> equivalent methods for UI warnings.

This one and the the next 3 seem clean and useful, applying and then
waiting for people to comment on the coresight specific ones.

- Arnaldo
 
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  tools/perf/util/debug.h | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
> index 48f631966067..f99468a7f681 100644
> --- a/tools/perf/util/debug.h
> +++ b/tools/perf/util/debug.h
> @@ -22,6 +22,13 @@ extern int debug_data_convert;
>  	eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
>  #define pr_warning(fmt, ...) \
>  	eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
> +#define pr_warning_once(fmt, ...) ({		\
> +	static int __warned;			\
> +	if (unlikely(!__warned)) {		\
> +		pr_warning(fmt, ##__VA_ARGS__); \
> +		__warned = 1;			\
> +	}					\
> +})
>  #define pr_info(fmt, ...) \
>  	eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
>  #define pr_debug(fmt, ...) \
> @@ -55,6 +62,13 @@ void trace_event(union perf_event *event);
>  
>  int ui__error(const char *format, ...) __printf(1, 2);
>  int ui__warning(const char *format, ...) __printf(1, 2);
> +#define ui__warning_once(format, ...) ({		\
> +	static int __warned;				\
> +	if (unlikely(!__warned)) {			\
> +		ui__warning(format, ##__VA_ARGS__);	\
> +		__warned = 1;				\
> +	}						\
> +})
>  
>  void pr_stat(const char *fmt, ...);
>  
> -- 
> 2.28.0
> 

-- 

- Arnaldo


From pali at kernel.org  Mon Aug  2 07:45:38 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Mon, 2 Aug 2021 16:45:38 +0200
Subject: [PATCH v3 3/5] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <YPMTq1wSo1YLJBQi@lunn.ch>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210717123829.5201-1-pali@kernel.org>
 <20210717123829.5201-4-pali@kernel.org> <YPMTq1wSo1YLJBQi@lunn.ch>
Message-ID: <20210802144538.zbnshv3xml3t4euj@pali>

On Saturday 17 July 2021 19:30:19 Andrew Lunn wrote:
> On Sat, Jul 17, 2021 at 02:38:27PM +0200, Pali Roh?r wrote:
> > This change adds DT bindings documentation for device nodes with compatible
> > string "marvell,armada-3700-uart-clock".
> > 
> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > ---
> >  .../bindings/clock/armada3700-uart-clock.txt  | 24 +++++++++++++++++++
> >  .../devicetree/bindings/serial/mvebu-uart.txt |  9 ++++---
> >  2 files changed, 30 insertions(+), 3 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/clock/armada3700-uart-clock.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/clock/armada3700-uart-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.txt
> > new file mode 100644
> > index 000000000000..144bc6d7eae8
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.txt
> 
> Since this is a new binding, please use YAML.

Changed in v4.


From pali at kernel.org  Mon Aug  2 07:45:23 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  2 Aug 2021 16:45:23 +0200
Subject: [PATCH v4 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <20210624224909.6350-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
Message-ID: <20210802144529.1520-1-pali@kernel.org>

This patch series add support for baudrates higher than 230400 on
Marvell Armada 37xx boards.

Please review these patches as they touch both Device Tree bindings and
mvebu-uart.c driver.

Changes in v4:
* converted armada3700-uart-clock documentation to YAML
* split documentation changes into two commits:
  - first which adds clock documentation
  - second which updates UART documentation

Changes in v3:
v3 is rebased on top of Linus master branch and all already applied patches
were dropped. There are no changes in patches itself since v2.

Pali Roh?r (6):
  math64: New DIV_U64_ROUND_CLOSEST helper
  serial: mvebu-uart: implement UART clock driver for configuring UART
    base clock
  dt-bindings: mvebu-uart: document DT bindings for
    marvell,armada-3700-uart-clock
  dt-bindings: mvebu-uart: update information about UART clock
  arm64: dts: marvell: armada-37xx: add device node for UART clock and
    use it
  serial: mvebu-uart: implement support for baudrates higher than 230400

 .../bindings/clock/armada3700-uart-clock.yaml |  49 ++
 .../devicetree/bindings/serial/mvebu-uart.txt |   9 +-
 .../arm64/boot/dts/marvell/armada-3720-db.dts |   4 +
 .../dts/marvell/armada-3720-espressobin.dtsi  |   4 +
 .../dts/marvell/armada-3720-turris-mox.dts    |   4 +
 .../boot/dts/marvell/armada-3720-uDPU.dts     |   4 +
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi  |  15 +-
 drivers/tty/serial/Kconfig                    |   1 +
 drivers/tty/serial/mvebu-uart.c               | 592 +++++++++++++++++-
 include/linux/math64.h                        |  13 +
 10 files changed, 674 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml

-- 
2.20.1



From pali at kernel.org  Mon Aug  2 07:45:24 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  2 Aug 2021 16:45:24 +0200
Subject: [PATCH v4 1/6] math64: New DIV_U64_ROUND_CLOSEST helper
In-Reply-To: <20210802144529.1520-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
Message-ID: <20210802144529.1520-2-pali@kernel.org>

Provide DIV_U64_ROUND_CLOSEST helper which uses div_u64 to perform
division rounded to the closest integer using unsigned 64bit
dividend and unsigned 32bit divisor.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 include/linux/math64.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/linux/math64.h b/include/linux/math64.h
index 66deb1fdc2ef..1cc61d748e1f 100644
--- a/include/linux/math64.h
+++ b/include/linux/math64.h
@@ -281,6 +281,19 @@ u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div);
 #define DIV64_U64_ROUND_CLOSEST(dividend, divisor)	\
 	({ u64 _tmp = (divisor); div64_u64((dividend) + _tmp / 2, _tmp); })
 
+/*
+ * DIV_U64_ROUND_CLOSEST - unsigned 64bit divide with 32bit divisor rounded to nearest integer
+ * @dividend: unsigned 64bit dividend
+ * @divisor: unsigned 32bit divisor
+ *
+ * Divide unsigned 64bit dividend by unsigned 32bit divisor
+ * and round to closest integer.
+ *
+ * Return: dividend / divisor rounded to nearest integer
+ */
+#define DIV_U64_ROUND_CLOSEST(dividend, divisor)	\
+	({ u32 _tmp = (divisor); div_u64((u64)(dividend) + _tmp / 2, _tmp); })
+
 /*
  * DIV_S64_ROUND_CLOSEST - signed 64bit divide with 32bit divisor rounded to nearest integer
  * @dividend: signed 64bit dividend
-- 
2.20.1



From pali at kernel.org  Mon Aug  2 07:45:26 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  2 Aug 2021 16:45:26 +0200
Subject: [PATCH v4 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <20210802144529.1520-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
Message-ID: <20210802144529.1520-4-pali@kernel.org>

This change adds DT bindings documentation for device nodes with compatible
string "marvell,armada-3700-uart-clock".

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 .../bindings/clock/armada3700-uart-clock.yaml | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
new file mode 100644
index 000000000000..5ef04f3affda
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/marvell,armada-3700-uart-clock#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+title: Marvell Armada 3720 UART clocks
+properties:
+  compatible:
+    const: marvell,armada-3700-uart-clock
+  reg:
+    items:
+      - description: UART Clock Control Register
+      - description: UART 2 Baud Rate Divisor Register
+  clocks:
+    description: |
+      List of parent clocks suitable for UART from following set:
+        "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal"
+      UART clock can use one from this set and when more are provided
+      then kernel would choose and configure the most suitable one.
+      It is suggest to specify at least one TBG clock to achieve
+      baudrates above 230400 and also to specify clock which bootloader
+      used for UART (most probably xtal) for smooth boot log on UART.
+  clock-names:
+    items:
+      - const: TBG-A-P
+      - const: TBG-B-P
+      - const: TBG-A-S
+      - const: TBG-B-S
+      - const: xtal
+    minItems: 1
+    maxItems: 5
+  '#clock-cells':
+    const: 1
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+additionalProperties: false
+examples:
+  - |
+    uartclk: uartclk at 12000 {
+      compatible = "marvell,armada-3700-uart-clock";
+      reg = <0x12010 0x4>, <0x12210 0x4>;
+      clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>, <&xtalclk>;
+      clock-names = "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal";
+      #clock-cells = <1>;
+    };
-- 
2.20.1



From pali at kernel.org  Mon Aug  2 07:45:27 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  2 Aug 2021 16:45:27 +0200
Subject: [PATCH v4 4/6] dt-bindings: mvebu-uart: update information about UART
 clock
In-Reply-To: <20210802144529.1520-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
Message-ID: <20210802144529.1520-5-pali@kernel.org>

Device "marvell,armada-3700-uart" should use
"marvell,armada-3700-uart-clock" compatible clock.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 Documentation/devicetree/bindings/serial/mvebu-uart.txt | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/mvebu-uart.txt b/Documentation/devicetree/bindings/serial/mvebu-uart.txt
index 2d0dbdf32d1d..a062bbca532c 100644
--- a/Documentation/devicetree/bindings/serial/mvebu-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mvebu-uart.txt
@@ -14,7 +14,10 @@ Required properties:
       is provided (possible only with the "marvell,armada-3700-uart"
       compatible string for backward compatibility), it will only work
       if the baudrate was initialized by the bootloader and no baudrate
-      change will then be possible.
+      change will then be possible. When provided it should be UART1-clk
+      for standard variant of UART and UART2-clk for extended variant
+      of UART. TBG clock (with UART TBG divisors d1=d2=1) or xtal clock
+      should not be used and are supported only for backward compatibility.
 - interrupts:
     - Must contain three elements for the standard variant of the IP
       (marvell,armada-3700-uart): "uart-sum", "uart-tx" and "uart-rx",
@@ -34,7 +37,7 @@ Example:
 	uart0: serial at 12000 {
 		compatible = "marvell,armada-3700-uart";
 		reg = <0x12000 0x18>;
-		clocks = <&xtalclk>;
+		clocks = <&uartclk 0>;
 		interrupts =
 		<GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
 		<GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
@@ -45,7 +48,7 @@ Example:
 	uart1: serial at 12200 {
 		compatible = "marvell,armada-3700-uart-ext";
 		reg = <0x12200 0x30>;
-		clocks = <&xtalclk>;
+		clocks = <&uartclk 1>;
 		interrupts =
 		<GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
 		<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>;
-- 
2.20.1



From pali at kernel.org  Mon Aug  2 07:45:25 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  2 Aug 2021 16:45:25 +0200
Subject: [PATCH v4 2/6] serial: mvebu-uart: implement UART clock driver for
 configuring UART base clock
In-Reply-To: <20210802144529.1520-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
Message-ID: <20210802144529.1520-3-pali@kernel.org>

This patch implements a new device driver for controlling UART clocks on
Marvell Armada 3700 SoC. This device driver is loaded for devices which
match compatible string "marvell,armada-3700-uart-clock".

There are more pitfalls related to UART clocks. Both UARTs use same base
clock source. Also divisors for TBG base clock are shared between both
UARTs and are configured only from UART1 address space. Clocks can be
enabled / disabled separately for UART1 and UART2, but they are controlled
only from UART1 address space. Moreover Marvell Armada 3700 Functional
Specifications has swapped bits for enabling/disabling UART1 and UART2
clocks.

So driver for controlling UART2 needs to have access to UART1 address space
as UART1 address space contains some bits exclusively used by UART2 and
also bits which are shared for both UART1 and UART2.

For changing UART base clock (which controls both UARTs) during boot when
UART driver is not ready and only early console is active, is not simple
operation as it is required to also recalculate divisors to not change UART
baudrate used by early console. So for this operation UART1 clock driver
needs to access also into address space of UART2 where are registers for
UART2 divisors.

For these reasons, this new device driver for UART clocks does not use
ioremap_resource(), but only ioremap() to prevent resource conflicts
between UART clock driver and UART driver.

Shared between drivers are only two 4-bytes registers: UART Clock Control
and UART 2 Baud Rate Divisor. Access to these two registers are protected
by one spinlock to prevent any conflicts. Access is required only during
probe time, changing baudrate and during suspend/resume.

Hardware can be configured to use one of following clocks as UART base
clock: TBG-A-P, TBG-B-P, TBG-A-S, TBG-B-S, xtal. Not every clock is usable
for higher buadrates. In DT node can be specified any subset and kernel
choose the best one, which still supports required baudrate 9600. For
smooth boot log output it is needed to specify clock used by early console
otherwise garbage would be put on UART during probing for UART clock driver
and transitioning from early console to normal console.

This change is required to enable and configure TBG clock as a base clock
for UART. TBG clock is required to achieve higher baudrates than 230400.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/tty/serial/Kconfig      |   1 +
 drivers/tty/serial/mvebu-uart.c | 519 +++++++++++++++++++++++++++++++-
 2 files changed, 518 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 0c4cd4a348f4..b3726797a0f5 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1441,6 +1441,7 @@ config SERIAL_STM32_CONSOLE
 config SERIAL_MVEBU_UART
 	bool "Marvell EBU serial port support"
 	depends on ARCH_MVEBU || COMPILE_TEST
+	depends on COMMON_CLK
 	select SERIAL_CORE
 	help
 	  This driver is for Marvell EBU SoC's UART. If you have a machine
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index 414e92064ac6..a31235add99f 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -8,12 +8,14 @@
 */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/math64.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -68,8 +70,31 @@
 #define  STAT_BRK_ERR		(STAT_BRK_DET | STAT_FRM_ERR \
 				 | STAT_PAR_ERR | STAT_OVR_ERR)
 
+/*
+ * Marvell Armada 3700 Functional Specifications describes that bit 21 of UART
+ * Clock Control register controls UART1 and bit 20 controls UART2. But in
+ * reality bit 21 controls UART2 and bit 20 controls UART1. This seems to be a
+ * bug in Marvell documentation. Hence following CLK_DIS macros are swapped.
+ */
+
 #define UART_BRDV		0x10
+/* These bits are located in UART1 address space and control UART2 */
+#define  UART2_CLK_DIS		BIT(21)
+/* These bits are located in UART1 address space and control UART1 */
+#define  UART1_CLK_DIS		BIT(20)
+/* These bits are located in UART1 address space and control both UARTs */
+#define  CLK_NO_XTAL		BIT(19)
+#define  CLK_TBG_DIV1_SHIFT	15
+#define  CLK_TBG_DIV1_MASK	0x7
+#define  CLK_TBG_DIV1_MAX	6
+#define  CLK_TBG_DIV2_SHIFT	12
+#define  CLK_TBG_DIV2_MASK	0x7
+#define  CLK_TBG_DIV2_MAX	6
+#define  CLK_TBG_SEL_SHIFT	10
+#define  CLK_TBG_SEL_MASK	0x3
+/* These bits are located in both UARTs address space */
 #define  BRDV_BAUD_MASK         0x3FF
+#define  BRDV_BAUD_MAX		BRDV_BAUD_MASK
 
 #define UART_OSAMP		0x14
 #define  OSAMP_DEFAULT_DIVISOR	16
@@ -153,6 +178,8 @@ static struct mvebu_uart *to_mvuart(struct uart_port *port)
 
 static struct uart_port mvebu_uart_ports[MVEBU_NR_UARTS];
 
+static DEFINE_SPINLOCK(mvebu_uart_lock);
+
 /* Core UART Driver Operations */
 static unsigned int mvebu_uart_tx_empty(struct uart_port *port)
 {
@@ -445,6 +472,7 @@ static void mvebu_uart_shutdown(struct uart_port *port)
 static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 {
 	unsigned int d_divisor, m_divisor;
+	unsigned long flags;
 	u32 brdv, osamp;
 
 	if (!port->uartclk)
@@ -463,10 +491,12 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 	m_divisor = OSAMP_DEFAULT_DIVISOR;
 	d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
 
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
 	brdv = readl(port->membase + UART_BRDV);
 	brdv &= ~BRDV_BAUD_MASK;
 	brdv |= d_divisor;
 	writel(brdv, port->membase + UART_BRDV);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
 
 	osamp = readl(port->membase + UART_OSAMP);
 	osamp &= ~OSAMP_DIVISORS_MASK;
@@ -762,6 +792,7 @@ static int mvebu_uart_suspend(struct device *dev)
 {
 	struct mvebu_uart *mvuart = dev_get_drvdata(dev);
 	struct uart_port *port = mvuart->port;
+	unsigned long flags;
 
 	uart_suspend_port(&mvebu_uart_driver, port);
 
@@ -770,7 +801,9 @@ static int mvebu_uart_suspend(struct device *dev)
 	mvuart->pm_regs.ctrl = readl(port->membase + UART_CTRL(port));
 	mvuart->pm_regs.intr = readl(port->membase + UART_INTR(port));
 	mvuart->pm_regs.stat = readl(port->membase + UART_STAT);
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
 	mvuart->pm_regs.brdv = readl(port->membase + UART_BRDV);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
 	mvuart->pm_regs.osamp = readl(port->membase + UART_OSAMP);
 
 	device_set_wakeup_enable(dev, true);
@@ -782,13 +815,16 @@ static int mvebu_uart_resume(struct device *dev)
 {
 	struct mvebu_uart *mvuart = dev_get_drvdata(dev);
 	struct uart_port *port = mvuart->port;
+	unsigned long flags;
 
 	writel(mvuart->pm_regs.rbr, port->membase + UART_RBR(port));
 	writel(mvuart->pm_regs.tsh, port->membase + UART_TSH(port));
 	writel(mvuart->pm_regs.ctrl, port->membase + UART_CTRL(port));
 	writel(mvuart->pm_regs.intr, port->membase + UART_INTR(port));
 	writel(mvuart->pm_regs.stat, port->membase + UART_STAT);
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
 	writel(mvuart->pm_regs.brdv, port->membase + UART_BRDV);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
 	writel(mvuart->pm_regs.osamp, port->membase + UART_OSAMP);
 
 	uart_resume_port(&mvebu_uart_driver, port);
@@ -975,6 +1011,476 @@ static struct platform_driver mvebu_uart_platform_driver = {
 	},
 };
 
+/* This code is based on clk-fixed-factor.c driver and modified. */
+
+struct mvebu_uart_clock {
+	struct clk_hw clk_hw;
+	int clock_idx;
+	u32 pm_context_reg1;
+	u32 pm_context_reg2;
+};
+
+struct mvebu_uart_clock_base {
+	struct mvebu_uart_clock clocks[2];
+	unsigned int parent_rates[5];
+	int parent_idx;
+	unsigned int div;
+	void __iomem *reg1;
+	void __iomem *reg2;
+	bool configured;
+};
+
+#define PARENT_CLOCK_XTAL 4
+
+#define to_uart_clock(hw) container_of(hw, struct mvebu_uart_clock, clk_hw)
+#define to_uart_clock_base(uart_clock) container_of(uart_clock, \
+	struct mvebu_uart_clock_base, clocks[uart_clock->clock_idx])
+
+static int mvebu_uart_clock_prepare(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned int prev_clock_idx, prev_clock_rate, prev_d1d2;
+	unsigned int parent_clock_idx, parent_clock_rate;
+	unsigned long flags;
+	unsigned int d1, d2;
+	u64 divisor;
+	u32 val;
+
+	/*
+	 * This function just reconfigures UART Clock Control register (located
+	 * in UART1 address space which controls both UART1 and UART2) to
+	 * selected UART base clock and recalculate current UART1/UART2 divisors
+	 * in their address spaces, so final baudrate will not be changed by
+	 * switching UART base clock. This is required otherwise kernel boot log
+	 * stops working. It is needed to ensure that UART baudrate does not
+	 * change during this setup. It is one time operation, so based on
+	 * "configured" member this function is skipped on second call. Because
+	 * this UART Clock Control register (UART_BRDV) is shared between UART1
+	 * baudrate function, UART1 clock selector and UART2 clock selector,
+	 * every access to UART_BRDV (reg1) needs to be protected by lock.
+	 */
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+
+	if (uart_clock_base->configured) {
+		spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+		return 0;
+	}
+
+	parent_clock_idx = uart_clock_base->parent_idx;
+	parent_clock_rate = uart_clock_base->parent_rates[parent_clock_idx];
+
+	val = readl(uart_clock_base->reg1);
+
+	if (uart_clock_base->div > CLK_TBG_DIV1_MAX) {
+		d1 = CLK_TBG_DIV1_MAX;
+		d2 = uart_clock_base->div / CLK_TBG_DIV1_MAX;
+	} else {
+		d1 = uart_clock_base->div;
+		d2 = 1;
+	}
+
+	if (val & CLK_NO_XTAL) {
+		prev_clock_idx = (val >> CLK_TBG_SEL_SHIFT) & CLK_TBG_SEL_MASK;
+		prev_d1d2 = ((val >> CLK_TBG_DIV1_SHIFT) & CLK_TBG_DIV1_MASK)
+			  * ((val >> CLK_TBG_DIV2_SHIFT) & CLK_TBG_DIV2_MASK);
+	} else {
+		prev_clock_idx = PARENT_CLOCK_XTAL;
+		prev_d1d2 = 1;
+	}
+
+	/* Note that uart_clock_base->parent_rates[i] may not be available */
+	prev_clock_rate = uart_clock_base->parent_rates[prev_clock_idx];
+
+	/* Recalculate UART1 divisor so UART1 baudrate does not change */
+	if (prev_clock_rate) {
+		divisor = DIV_U64_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) *
+						parent_clock_rate * prev_d1d2,
+						prev_clock_rate * d1 * d2);
+		if (divisor < 1)
+			divisor = 1;
+		else if (divisor > BRDV_BAUD_MAX)
+			divisor = BRDV_BAUD_MAX;
+		val = (val & ~BRDV_BAUD_MASK) | divisor;
+	}
+
+	if (parent_clock_idx != PARENT_CLOCK_XTAL) {
+		/* Do not use XTAL, select TBG clock and TBG d1 * d2 divisors */
+		val |= CLK_NO_XTAL;
+		val &= ~(CLK_TBG_DIV1_MASK << CLK_TBG_DIV1_SHIFT);
+		val |= d1 << CLK_TBG_DIV1_SHIFT;
+		val &= ~(CLK_TBG_DIV2_MASK << CLK_TBG_DIV2_SHIFT);
+		val |= d2 << CLK_TBG_DIV2_SHIFT;
+		val &= ~(CLK_TBG_SEL_MASK << CLK_TBG_SEL_SHIFT);
+		val |= parent_clock_idx << CLK_TBG_SEL_SHIFT;
+	} else {
+		/* Use XTAL, TBG bits are then ignored */
+		val &= ~CLK_NO_XTAL;
+	}
+
+	writel(val, uart_clock_base->reg1);
+
+	/* Recalculate UART2 divisor so UART2 baudrate does not change */
+	if (prev_clock_rate) {
+		val = readl(uart_clock_base->reg2);
+		divisor = DIV_U64_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) *
+						parent_clock_rate * prev_d1d2,
+						prev_clock_rate * d1 * d2);
+		if (divisor < 1)
+			divisor = 1;
+		else if (divisor > BRDV_BAUD_MAX)
+			divisor = BRDV_BAUD_MAX;
+		val = (val & ~BRDV_BAUD_MASK) | divisor;
+		writel(val, uart_clock_base->reg2);
+	}
+
+	uart_clock_base->configured = true;
+
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+
+	return 0;
+}
+
+static int mvebu_uart_clock_enable(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+
+	val = readl(uart_clock_base->reg1);
+
+	if (uart_clock->clock_idx == 0)
+		val &= ~UART1_CLK_DIS;
+	else
+		val &= ~UART2_CLK_DIS;
+
+	writel(val, uart_clock_base->reg1);
+
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+
+	return 0;
+}
+
+static void mvebu_uart_clock_disable(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+
+	val = readl(uart_clock_base->reg1);
+
+	if (uart_clock->clock_idx == 0)
+		val |= UART1_CLK_DIS;
+	else
+		val |= UART2_CLK_DIS;
+
+	writel(val, uart_clock_base->reg1);
+
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+}
+
+static int mvebu_uart_clock_is_enabled(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	u32 val;
+
+	val = readl(uart_clock_base->reg1);
+
+	if (uart_clock->clock_idx == 0)
+		return !(val & UART1_CLK_DIS);
+	else
+		return !(val & UART2_CLK_DIS);
+}
+
+static int mvebu_uart_clock_save_context(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+	uart_clock->pm_context_reg1 = readl(uart_clock_base->reg1);
+	uart_clock->pm_context_reg2 = readl(uart_clock_base->reg2);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+
+	return 0;
+}
+
+static void mvebu_uart_clock_restore_context(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+	writel(uart_clock->pm_context_reg1, uart_clock_base->reg1);
+	writel(uart_clock->pm_context_reg2, uart_clock_base->reg2);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+}
+
+static unsigned long mvebu_uart_clock_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+
+	return parent_rate / uart_clock_base->div;
+}
+
+static long mvebu_uart_clock_round_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long *parent_rate)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+
+	return *parent_rate / uart_clock_base->div;
+}
+
+static int mvebu_uart_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long parent_rate)
+{
+	/*
+	 * We must report success but we can do so unconditionally because
+	 * mvebu_uart_clock_round_rate returns values that ensure this call is a
+	 * nop.
+	 */
+
+	return 0;
+}
+
+static const struct clk_ops mvebu_uart_clock_ops = {
+	.prepare = mvebu_uart_clock_prepare,
+	.enable = mvebu_uart_clock_enable,
+	.disable = mvebu_uart_clock_disable,
+	.is_enabled = mvebu_uart_clock_is_enabled,
+	.save_context = mvebu_uart_clock_save_context,
+	.restore_context = mvebu_uart_clock_restore_context,
+	.round_rate = mvebu_uart_clock_round_rate,
+	.set_rate = mvebu_uart_clock_set_rate,
+	.recalc_rate = mvebu_uart_clock_recalc_rate,
+};
+
+static int mvebu_uart_clock_register(struct device *dev,
+				     struct mvebu_uart_clock *uart_clock,
+				     const char *name,
+				     const char *parent_name)
+{
+	struct clk_init_data init = { };
+
+	uart_clock->clk_hw.init = &init;
+
+	init.name = name;
+	init.ops = &mvebu_uart_clock_ops;
+	init.flags = 0;
+	init.num_parents = 1;
+	init.parent_names = &parent_name;
+
+	return devm_clk_hw_register(dev, &uart_clock->clk_hw);
+}
+
+static int mvebu_uart_clock_probe(struct platform_device *pdev)
+{
+	static const char *const uart_clk_names[] = { "uart_1", "uart_2" };
+	static const char *const parent_clk_names[] = { "TBG-A-P", "TBG-B-P",
+							"TBG-A-S", "TBG-B-S",
+							"xtal" };
+	struct clk *parent_clks[ARRAY_SIZE(parent_clk_names)];
+	struct mvebu_uart_clock_base *uart_clock_base;
+	struct clk_hw_onecell_data *hw_clk_data;
+	struct device *dev = &pdev->dev;
+	int i, parent_clk_idx, ret;
+	unsigned long div, rate;
+	struct resource *res;
+	unsigned int d1, d2;
+
+	BUILD_BUG_ON(ARRAY_SIZE(uart_clk_names) !=
+		     ARRAY_SIZE(uart_clock_base->clocks));
+	BUILD_BUG_ON(ARRAY_SIZE(parent_clk_names) !=
+		     ARRAY_SIZE(uart_clock_base->parent_rates));
+
+	uart_clock_base = devm_kzalloc(dev,
+				       sizeof(*uart_clock_base),
+				       GFP_KERNEL);
+	if (!uart_clock_base)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "Couldn't get first register\n");
+		return -ENOENT;
+	}
+
+	/*
+	 * UART Clock Control register (reg1 / UART_BRDV) is in address range
+	 * of UART1 (standard UART variant), controls clock source and dividers
+	 * for both UART1 and UART2 and is supplied via DT as first resource.
+	 * Therefore use ioremap() function rather than ioremap_resource() to
+	 * avoid conflicts with UART1 driver. Access to UART_BRDV is protected
+	 * by lock shared between clock and UART driver.
+	 */
+	uart_clock_base->reg1 = devm_ioremap(dev, res->start,
+					     resource_size(res));
+	if (IS_ERR(uart_clock_base->reg1))
+		return PTR_ERR(uart_clock_base->reg1);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_err(dev, "Couldn't get second register\n");
+		return -ENOENT;
+	}
+
+	/*
+	 * UART 2 Baud Rate Divisor register (reg2 / UART_BRDV) is in address
+	 * range of UART2 (extended UART variant), controls only one UART2
+	 * specific divider and is supplied via DT as second resource.
+	 * Therefore use ioremap() function rather than ioremap_resource() to
+	 * avoid conflicts with UART2 driver. Access to UART_BRDV is protected
+	 * by lock shared between clock and UART driver.
+	 */
+	uart_clock_base->reg2 = devm_ioremap(dev, res->start,
+					     resource_size(res));
+	if (IS_ERR(uart_clock_base->reg2))
+		return PTR_ERR(uart_clock_base->reg2);
+
+	hw_clk_data = devm_kzalloc(dev,
+				   struct_size(hw_clk_data, hws,
+					       ARRAY_SIZE(uart_clk_names)),
+				   GFP_KERNEL);
+	if (!hw_clk_data)
+		return -ENOMEM;
+
+	hw_clk_data->num = ARRAY_SIZE(uart_clk_names);
+	for (i = 0; i < ARRAY_SIZE(uart_clk_names); i++) {
+		hw_clk_data->hws[i] = &uart_clock_base->clocks[i].clk_hw;
+		uart_clock_base->clocks[i].clock_idx = i;
+	}
+
+	parent_clk_idx = -1;
+
+	for (i = 0; i < ARRAY_SIZE(parent_clk_names); i++) {
+		parent_clks[i] = devm_clk_get(dev, parent_clk_names[i]);
+		if (IS_ERR(parent_clks[i])) {
+			if (PTR_ERR(parent_clks[i]) == -EPROBE_DEFER)
+				return -EPROBE_DEFER;
+			dev_warn(dev, "Couldn't get the parent clock %s: %ld\n",
+				parent_clk_names[i], PTR_ERR(parent_clks[i]));
+			continue;
+		}
+
+		ret = clk_prepare_enable(parent_clks[i]);
+		if (ret) {
+			dev_warn(dev, "Couldn't enable parent clock %s: %d\n",
+				parent_clk_names[i], ret);
+			continue;
+		}
+		rate = clk_get_rate(parent_clks[i]);
+		uart_clock_base->parent_rates[i] = rate;
+
+		if (i != PARENT_CLOCK_XTAL) {
+			/*
+			 * Calculate the smallest TBG d1 and d2 divisors that
+			 * still can provide 9600 baudrate.
+			 */
+			d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+						BRDV_BAUD_MAX);
+			if (d1 < 1)
+				d1 = 1;
+			else if (d1 > CLK_TBG_DIV1_MAX)
+				d1 = CLK_TBG_DIV1_MAX;
+
+			d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+						BRDV_BAUD_MAX * d1);
+			if (d2 < 1)
+				d2 = 1;
+			else if (d2 > CLK_TBG_DIV2_MAX)
+				d2 = CLK_TBG_DIV2_MAX;
+		} else {
+			/*
+			 * When UART clock uses XTAL clock as a source then it
+			 * is not possible to use d1 and d2 divisors.
+			 */
+			d1 = d2 = 1;
+		}
+
+		/* Skip clock source which cannot provide 9600 baudrate */
+		if (rate > 9600 * OSAMP_DEFAULT_DIVISOR * BRDV_BAUD_MAX * d1 * d2)
+			continue;
+
+		/*
+		 * Choose TBG clock source with the smallest divisors. Use XTAL
+		 * clock source only in case TBG is not available as XTAL cannot
+		 * be used for baudrates higher than 230400.
+		 */
+		if (parent_clk_idx == -1 ||
+		    (i != PARENT_CLOCK_XTAL && div > d1 * d2)) {
+			parent_clk_idx = i;
+			div = d1 * d2;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(parent_clk_names); i++) {
+		if (i == parent_clk_idx || IS_ERR(parent_clks[i]))
+			continue;
+		clk_disable_unprepare(parent_clks[i]);
+		devm_clk_put(dev, parent_clks[i]);
+	}
+
+	if (parent_clk_idx == -1) {
+		dev_err(dev, "No usable parent clock\n");
+		return -ENOENT;
+	}
+
+	uart_clock_base->parent_idx = parent_clk_idx;
+	uart_clock_base->div = div;
+
+	dev_notice(dev, "Using parent clock %s as base UART clock\n",
+		   __clk_get_name(parent_clks[parent_clk_idx]));
+
+	for (i = 0; i < ARRAY_SIZE(uart_clk_names); i++) {
+		ret = mvebu_uart_clock_register(dev,
+				&uart_clock_base->clocks[i],
+				uart_clk_names[i],
+				__clk_get_name(parent_clks[parent_clk_idx]));
+		if (ret) {
+			dev_err(dev, "Can't register UART clock %d: %d\n",
+				i, ret);
+			return ret;
+		}
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   hw_clk_data);
+}
+
+static const struct of_device_id mvebu_uart_clock_of_match[] = {
+	{ .compatible = "marvell,armada-3700-uart-clock", },
+	{ }
+};
+
+static struct platform_driver mvebu_uart_clock_platform_driver = {
+	.probe = mvebu_uart_clock_probe,
+	.driver		= {
+		.name	= "mvebu-uart-clock",
+		.of_match_table = mvebu_uart_clock_of_match,
+	},
+};
+
 static int __init mvebu_uart_init(void)
 {
 	int ret;
@@ -983,10 +1489,19 @@ static int __init mvebu_uart_init(void)
 	if (ret)
 		return ret;
 
+	ret = platform_driver_register(&mvebu_uart_clock_platform_driver);
+	if (ret) {
+		uart_unregister_driver(&mvebu_uart_driver);
+		return ret;
+	}
+
 	ret = platform_driver_register(&mvebu_uart_platform_driver);
-	if (ret)
+	if (ret) {
+		platform_driver_unregister(&mvebu_uart_clock_platform_driver);
 		uart_unregister_driver(&mvebu_uart_driver);
+		return ret;
+	}
 
-	return ret;
+	return 0;
 }
 arch_initcall(mvebu_uart_init);
-- 
2.20.1



From pali at kernel.org  Mon Aug  2 07:45:28 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  2 Aug 2021 16:45:28 +0200
Subject: [PATCH v4 5/6] arm64: dts: marvell: armada-37xx: add device node for
 UART clock and use it
In-Reply-To: <20210802144529.1520-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
Message-ID: <20210802144529.1520-6-pali@kernel.org>

This change defines DT node for UART clock "marvell,armada-3700-uart-clock"
and use this UART clock as a base clock for all UART devices.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 arch/arm64/boot/dts/marvell/armada-3720-db.dts    |  4 ++++
 .../boot/dts/marvell/armada-3720-espressobin.dtsi |  4 ++++
 .../boot/dts/marvell/armada-3720-turris-mox.dts   |  4 ++++
 arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts  |  4 ++++
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi      | 15 +++++++++++++--
 5 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index 3e5789f37206..accf014a6a1e 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -191,6 +191,10 @@
 	};
 };
 
+&uartclk {
+	status = "okay";
+};
+
 /*
  * Exported on the micro USB connector CON30(V2.0)/CON32(V1.4) through
  * an FTDI (also on CON24(V2.0)/CON26(V1.4)).
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
index 5fc613d24151..d03c7cdfbfb3 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
@@ -117,6 +117,10 @@
 	};
 };
 
+&uartclk {
+	status = "okay";
+};
+
 /* Exported on the micro USB connector J5 through an FTDI */
 &uart0 {
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
index cacf2a05fb22..972c6d400f8b 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
@@ -167,6 +167,10 @@
 	status = "disabled";
 };
 
+&uartclk {
+	status = "okay";
+};
+
 &uart0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
index 95d46e8d081c..c8217440b8dd 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
@@ -183,6 +183,10 @@
 	phy-names = "usb2-utmi-otg-phy";
 };
 
+&uartclk {
+	status = "okay";
+};
+
 &uart0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 20dd9d9e9d58..d9bdd374cf45 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -132,10 +132,21 @@
 				reg = <0x11500 0x40>;
 			};
 
+			uartclk: uartclk at 12000 {
+				compatible = "marvell,armada-3700-uart-clock";
+				reg = <0x12010 0x4>, <0x12210 0x4>;
+				clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>,
+					<&tbg 3>, <&xtalclk>;
+				clock-names = "TBG-A-P", "TBG-B-P", "TBG-A-S",
+					"TBG-B-S", "xtal";
+				#clock-cells = <1>;
+				status = "disabled";
+			};
+
 			uart0: serial at 12000 {
 				compatible = "marvell,armada-3700-uart";
 				reg = <0x12000 0x18>;
-				clocks = <&xtalclk>;
+				clocks = <&uartclk 0>;
 				interrupts =
 				<GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
 				<GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
@@ -147,7 +158,7 @@
 			uart1: serial at 12200 {
 				compatible = "marvell,armada-3700-uart-ext";
 				reg = <0x12200 0x30>;
-				clocks = <&xtalclk>;
+				clocks = <&uartclk 1>;
 				interrupts =
 				<GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
 				<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>;
-- 
2.20.1



From pali at kernel.org  Mon Aug  2 07:45:29 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  2 Aug 2021 16:45:29 +0200
Subject: [PATCH v4 6/6] serial: mvebu-uart: implement support for baudrates
 higher than 230400
In-Reply-To: <20210802144529.1520-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
Message-ID: <20210802144529.1520-7-pali@kernel.org>

This change implements simple usage of fractional divisor. When main
divisor D is too large to represent requested baudrate then use divisor M
from fractional divisor feature. All the M prescalers are set to same and
maximal value 63, so fractional part is not used at all.

Tests showed that UART at 1500000 baudrate via this configuration is stable
and usable. So there is no need to implement complicated calculation of
fractional coefficients yet.

To use this feature with higher baudrates, it is required to use UART clock
provided by UART clock driver. Default boot xtal clock is not capable of
higher baudrates and this change also contains code for determining upper
limit of possible baudrate.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/tty/serial/mvebu-uart.c | 79 ++++++++++++++++++++++++++-------
 1 file changed, 62 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index a31235add99f..0fe251b8627b 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -99,6 +99,7 @@
 #define UART_OSAMP		0x14
 #define  OSAMP_DEFAULT_DIVISOR	16
 #define  OSAMP_DIVISORS_MASK	0x3F3F3F3F
+#define  OSAMP_MAX_DIVISOR	63
 
 #define MVEBU_NR_UARTS		2
 
@@ -479,18 +480,59 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 		return -EOPNOTSUPP;
 
 	/*
-	 * The baudrate is derived from the UART clock thanks to two divisors:
-	 *   > D ("baud generator"): can divide the clock from 2 to 2^10 - 1.
-	 *   > M ("fractional divisor"): allows a better accuracy for
-	 *     baudrates higher than 230400.
+	 * The baudrate is derived from the UART clock thanks to divisors:
+	 *   > d1 * d2 ("TBG divisors"): can divide only TBG clock from 1 to 6
+	 *   > D ("baud generator"): can divide the clock from 1 to 1023
+	 *   > M ("fractional divisor"): allows a better accuracy (from 1 to 63)
 	 *
-	 * As the derivation of M is rather complicated, the code sticks to its
-	 * default value (x16) when all the prescalers are zeroed, and only
-	 * makes use of D to configure the desired baudrate.
+	 * Exact formulas for calculating baudrate:
+	 *
+	 * with default x16 scheme:
+	 *   baudrate = xtal / (d * 16)
+	 *   baudrate = tbg / (d1 * d2 * d * 16)
+	 *
+	 * with fractional divisor:
+	 *   baudrate = 10 * xtal / (d * (3 * (m1 + m2) + 2 * (m3 + m4)))
+	 *   baudrate = 10 * tbg / (d1*d2 * d * (3 * (m1 + m2) + 2 * (m3 + m4)))
+	 *
+	 * Oversampling value:
+	 *   osamp = (m1 << 0) | (m2 << 8) | (m3 << 16) | (m4 << 24);
+	 *
+	 * Where m1 controls number of clock cycles per bit for bits 1,2,3;
+	 * m2 for bits 4,5,6; m3 for bits 7,8 and m4 for bits 9,10.
+	 *
+	 * To simplify baudrate setup set all the M prescalers to same value.
+	 * For 9600 baudrate and higher it is enough to use just default (x16)
+	 * divisor or fractional divisor with M = 63, so there is no need to
+	 * use real fractional support (when the M prescalers are not equal).
+	 *
+	 * When all the M prescalers are zeroed then default (x16) divisor is
+	 * used. Default x16 scheme is more stable than M (fractional divisor),
+	 * so use M only when D divisor is not enough to derivate baudrate.
+	 *
+	 * Member port->uartclk is either xtal clock rate or TBG clock rate
+	 * divided by (d1 * d2). So UART clock driver already sets d1 and d2
+	 * divisors and UART driver cannot change them. Moreover they are
+	 * shared with both UARTs.
 	 */
+
 	m_divisor = OSAMP_DEFAULT_DIVISOR;
 	d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
 
+	if (d_divisor > BRDV_BAUD_MAX) {
+		/*
+		 * Experiments showed that small M divisors are unstable.
+		 * So use maximal possible M = 63 and calculate D divisor.
+		 */
+		m_divisor = OSAMP_MAX_DIVISOR;
+		d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
+	}
+
+	if (d_divisor < 1)
+		d_divisor = 1;
+	else if (d_divisor > BRDV_BAUD_MAX)
+		d_divisor = BRDV_BAUD_MAX;
+
 	spin_lock_irqsave(&mvebu_uart_lock, flags);
 	brdv = readl(port->membase + UART_BRDV);
 	brdv &= ~BRDV_BAUD_MASK;
@@ -500,6 +542,9 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 
 	osamp = readl(port->membase + UART_OSAMP);
 	osamp &= ~OSAMP_DIVISORS_MASK;
+	if (m_divisor != OSAMP_DEFAULT_DIVISOR)
+		osamp |= (m_divisor << 0) | (m_divisor << 8) |
+			(m_divisor << 16) | (m_divisor << 24);
 	writel(osamp, port->membase + UART_OSAMP);
 
 	return 0;
@@ -529,14 +574,14 @@ static void mvebu_uart_set_termios(struct uart_port *port,
 		port->ignore_status_mask |= STAT_RX_RDY(port) | STAT_BRK_ERR;
 
 	/*
-	 * Maximal divisor is 1023 * 16 when using default (x16) scheme.
-	 * Maximum achievable frequency with simple baudrate divisor is 230400.
-	 * Since the error per bit frame would be of more than 15%, achieving
-	 * higher frequencies would require to implement the fractional divisor
-	 * feature.
+	 * Maximal divisor is 1023 and maximal fractional divisor is 63. And
+	 * experiments showed that baudrates above 1/80 of base clock are not
+	 * stable and usable. So disallow baudrate above 1/80 of the base clock.
+	 * When port->uartclk is not available then mvebu_uart_baud_rate_set()
+	 * fails so values min_baud and max_baud in this case does not matter.
 	 */
-	min_baud = DIV_ROUND_UP(port->uartclk, 1023 * 16);
-	max_baud = 230400;
+	min_baud = DIV_ROUND_UP(port->uartclk, BRDV_BAUD_MAX*OSAMP_MAX_DIVISOR);
+	max_baud = port->uartclk / 80;
 
 	baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud);
 	if (mvebu_uart_baud_rate_set(port, baud)) {
@@ -1397,14 +1442,14 @@ static int mvebu_uart_clock_probe(struct platform_device *pdev)
 			 * Calculate the smallest TBG d1 and d2 divisors that
 			 * still can provide 9600 baudrate.
 			 */
-			d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+			d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_MAX_DIVISOR *
 						BRDV_BAUD_MAX);
 			if (d1 < 1)
 				d1 = 1;
 			else if (d1 > CLK_TBG_DIV1_MAX)
 				d1 = CLK_TBG_DIV1_MAX;
 
-			d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+			d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_MAX_DIVISOR *
 						BRDV_BAUD_MAX * d1);
 			if (d2 < 1)
 				d2 = 1;
@@ -1419,7 +1464,7 @@ static int mvebu_uart_clock_probe(struct platform_device *pdev)
 		}
 
 		/* Skip clock source which cannot provide 9600 baudrate */
-		if (rate > 9600 * OSAMP_DEFAULT_DIVISOR * BRDV_BAUD_MAX * d1 * d2)
+		if (rate > 9600 * OSAMP_MAX_DIVISOR * BRDV_BAUD_MAX * d1 * d2)
 			continue;
 
 		/*
-- 
2.20.1



From acme at kernel.org  Mon Aug  2 07:51:58 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 2 Aug 2021 11:51:58 -0300
Subject: [RFC PATCH 6/6] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <20210729155805.2830-7-james.clark@arm.com>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-7-james.clark@arm.com>
Message-ID: <YQgGjlWtbaNApkp6@kernel.org>

Em Thu, Jul 29, 2021 at 04:58:05PM +0100, James Clark escreveu:
> Currently decode will silently fail if no binary data is available for
> the decode. This is made worse if only partial data is available because
> the decode will appear to work, but any trace from that missing DSO will
> silently not be generated.
> 
> Add a UI popup once if there is any data missing, and then warn in the
> bottom left for each individual DSO that's missing.

Looks ok to me (the last 3 patches in this series, the rest I applied
already), can I get some Acked-by/Reviewed-by from the CoreSight people?

Thanks,

- Arnaldo
 
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  tools/perf/util/cs-etm.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index 32ad92d3e454..e6851260d059 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -746,8 +746,16 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
>  
>  	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
>  
> -	if (len <= 0)
> +	if (len <= 0) {
> +		ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n");
> +		if (!al.map->dso->auxtrace_warned) {
> +			pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
> +				    address,
> +				    al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
> +			al.map->dso->auxtrace_warned = true;
> +		}
>  		return 0;
> +	}
>  
>  	return len;
>  }
> -- 
> 2.28.0
> 

-- 

- Arnaldo


From tabba at google.com  Mon Aug  2 07:52:31 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 16:52:31 +0200
Subject: [PATCH v3 15/21] KVM: arm64: Introduce addr_is_memory()
In-Reply-To: <20210729132818.4091769-16-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-16-qperret@google.com>
Message-ID: <CA+EHjTxrdA3wVsBe7zwvvGUGgoWuaGwuWCBL0k2+FcAdTGB=Qw@mail.gmail.com>

Hi Quentin.

On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
>
> Introduce a helper usable in nVHE protected mode to check whether a
> physical address is in a RAM region or not.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 +
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 7 +++++++
>  2 files changed, 8 insertions(+)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index cc86598654b9..5968fbbb3514 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -51,6 +51,7 @@ extern const u8 pkvm_hyp_id;
>  int __pkvm_prot_finalize(void);
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
>
> +bool addr_is_memory(phys_addr_t phys);

I'm just wondering about the naming of the function. I understand what
you're trying to achieve with it, but an address without a unit that
conveys size or type seems to be missing something. Would
memregion_addr_is_memory or something like that be a better
description, since it is what find_mem_range finds?

Thanks,
/fuad


>  int host_stage2_idmap_locked(u64 start, u64 end, enum kvm_pgtable_prot prot);
>  int host_stage2_set_owner_locked(u64 start, u64 end, u8 owner_id);
>  int kvm_host_prepare_stage2(void *pgt_pool_base);
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index bb18940c3d12..4532f3d55a1a 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -196,6 +196,13 @@ static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range)
>         return false;
>  }
>
> +bool addr_is_memory(phys_addr_t phys)
> +{
> +       struct kvm_mem_range range;
> +
> +       return find_mem_range(phys, &range);
> +}
> +
>  static bool range_is_memory(u64 start, u64 end)
>  {
>         struct kvm_mem_range r1, r2;
> --
> 2.32.0.432.gabb21c7263-goog
>


From tabba at google.com  Mon Aug  2 07:52:49 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 2 Aug 2021 16:52:49 +0200
Subject: [PATCH v3 16/21] KVM: arm64: Enable retrieving protections
 attributes of PTEs
In-Reply-To: <20210729132818.4091769-17-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-17-qperret@google.com>
Message-ID: <CA+EHjTwL+grX__03SfeDdxeppjSovEZhKRvqjmA_4kSBwsjswg@mail.gmail.com>

Hi Quentin,

On Thu, Jul 29, 2021 at 3:29 PM Quentin Perret <qperret at google.com> wrote:
>
> Introduce helper functions in the KVM stage-2 and stage-1 page-table
> manipulation library allowing to retrieve the enum kvm_pgtable_prot of a
> PTE. This will be useful to implement custom walkers outside of
> pgtable.c.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_pgtable.h | 20 +++++++++++++++
>  arch/arm64/kvm/hyp/pgtable.c         | 37 ++++++++++++++++++++++++++++
>  2 files changed, 57 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index d5ca9b6ce241..7ff9f52239ba 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -505,4 +505,24 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
>   */
>  int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
>                          kvm_pte_t *ptep, u32 *level);
> +
> +/**
> + * kvm_pgtable_stage2_pte_prot() - Retrieve the protection attributes of a
> + *                                stage-2 Page-Table Entry.
> + * @pte:       Page-table entry
> + *
> + * Return: protection attributes of the page-table entry in the enum
> + *        kvm_pgtable_prot format.
> + */
> +enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte);
> +
> +/**
> + * kvm_pgtable_hyp_pte_prot() - Retrieve the protection attributes of a stage-1
> + *                             Page-Table Entry.
> + * @pte:       Page-table entry
> + *
> + * Return: protection attributes of the page-table entry in the enum
> + *        kvm_pgtable_prot format.
> + */
> +enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte);
>  #endif /* __ARM64_KVM_PGTABLE_H__ */
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 1915489bb127..a6eda8f23cb6 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -363,6 +363,26 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
>         return 0;
>  }
>
> +enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte)
> +{
> +       enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW;
> +       u32 ap;
> +
> +       if (!kvm_pte_valid(pte))
> +               return prot;
> +
> +       if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN))
> +               prot |= KVM_PGTABLE_PROT_X;
> +
> +       ap = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_AP, pte);
> +       if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RO)
> +               prot |= KVM_PGTABLE_PROT_R;
> +       else if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RW)
> +               prot |= KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;

nit: why not use the freshly minted KVM_PGTABLE_PROT_RW?

Thanks,
/fuad


> +
> +       return prot;
> +}
> +
>  static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new)
>  {
>         /*
> @@ -565,6 +585,23 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p
>         return 0;
>  }
>
> +enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte)
> +{
> +       enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW;
> +
> +       if (!kvm_pte_valid(pte))
> +               return prot;
> +
> +       if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R)
> +               prot |= KVM_PGTABLE_PROT_R;
> +       if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W)
> +               prot |= KVM_PGTABLE_PROT_W;
> +       if (!(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN))
> +               prot |= KVM_PGTABLE_PROT_X;
> +
> +       return prot;
> +}
> +
>  static bool stage2_pte_needs_update(kvm_pte_t old, kvm_pte_t new)
>  {
>         if (!kvm_pte_valid(old) || !kvm_pte_valid(new))
> --
> 2.32.0.432.gabb21c7263-goog
>


From arnd at kernel.org  Mon Aug  2 07:54:37 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 16:54:37 +0200
Subject: [PATCH] net: sparx5: fix bitmask check
Message-ID: <20210802145449.1154565-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Older compilers such as gcc-5.5 produce a warning in this driver
when ifh_encode_bitfield() is not getting inlined:

drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c: In function 'ifh_encode_bitfield':
include/linux/compiler_types.h:333:38: error: call to '__compiletime_assert_545' declared with attribute error: Unsupported width, must be <= 40
drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c:28:2: note: in expansion of macro 'compiletime_assert'
  compiletime_assert(width <= 40, "Unsupported width, must be <= 40");
  ^

Mark the function as __always_inline to make the check work correctly
on all compilers. To make this also work on 32-bit architectures, change
the GENMASK() to GENMASK_ULL().

Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
index 9d485a9d1f1f..6f362f6708c6 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
@@ -13,14 +13,15 @@
  */
 #define VSTAX 73
 
-static void ifh_encode_bitfield(void *ifh, u64 value, u32 pos, u32 width)
+static __always_inline void ifh_encode_bitfield(void *ifh, u64 value,
+						u32 pos, u32 width)
 {
 	u8 *ifh_hdr = ifh;
 	/* Calculate the Start IFH byte position of this IFH bit position */
 	u32 byte = (35 - (pos / 8));
 	/* Calculate the Start bit position in the Start IFH byte */
 	u32 bit  = (pos % 8);
-	u64 encode = GENMASK(bit + width - 1, bit) & (value << bit);
+	u64 encode = GENMASK_ULL(bit + width - 1, bit) & (value << bit);
 
 	/* Max width is 5 bytes - 40 bits. In worst case this will
 	 * spread over 6 bytes - 48 bits
-- 
2.29.2



From robh+dt at kernel.org  Mon Aug  2 07:55:57 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 08:55:57 -0600
Subject: [PATCH v2] memblock: make memblock_find_in_range method private
In-Reply-To: <20210802063737.22733-1-rppt@kernel.org>
References: <20210802063737.22733-1-rppt@kernel.org>
Message-ID: <CAL_Jsq+i17C=+9bg=XPattuHe+M8NE3B29+FCg4p3-bPDgSaKw@mail.gmail.com>

On Mon, Aug 2, 2021 at 12:37 AM Mike Rapoport <rppt at kernel.org> wrote:
>
> From: Mike Rapoport <rppt at linux.ibm.com>
>
> There are a lot of uses of memblock_find_in_range() along with
> memblock_reserve() from the times memblock allocation APIs did not exist.
>
> memblock_find_in_range() is the very core of memblock allocations, so any
> future changes to its internal behaviour would mandate updates of all the
> users outside memblock.
>
> Replace the calls to memblock_find_in_range() with an equivalent calls to
> memblock_phys_alloc() and memblock_phys_alloc_range() and make
> memblock_find_in_range() private method of memblock.
>
> This simplifies the callers, ensures that (unlikely) errors in
> memblock_reserve() are handled and improves maintainability of
> memblock_find_in_range().
>
> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
> ---
> v2: don't change error message in arm::reserve_crashkernel(), per Russell
> v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org
>
>  arch/arm/kernel/setup.c           | 18 +++++--------
>  arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
>  arch/arm64/mm/init.c              | 36 ++++++++-----------------
>  arch/mips/kernel/setup.c          | 14 +++++-----
>  arch/riscv/mm/init.c              | 44 ++++++++++---------------------
>  arch/s390/kernel/setup.c          | 10 ++++---
>  arch/x86/kernel/aperture_64.c     |  5 ++--
>  arch/x86/mm/init.c                | 21 +++++++++------
>  arch/x86/mm/numa.c                |  5 ++--
>  arch/x86/mm/numa_emulation.c      |  5 ++--
>  arch/x86/realmode/init.c          |  2 +-
>  drivers/acpi/tables.c             |  5 ++--
>  drivers/base/arch_numa.c          |  5 +---
>  drivers/of/of_reserved_mem.c      | 12 ++++++---
>  include/linux/memblock.h          |  2 --
>  mm/memblock.c                     |  2 +-
>  16 files changed, 78 insertions(+), 117 deletions(-)
>
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index f97eb2371672..67f5421b2af7 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
>                 unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
>                 if (crash_max > lowmem_max)
>                         crash_max = lowmem_max;
> -               crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
> -                                                   crash_size, CRASH_ALIGN);
> +
> +               crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> +                                                      CRASH_ALIGN, crash_max);
>                 if (!crash_base) {
>                         pr_err("crashkernel reservation failed - No suitable area found.\n");
>                         return;
>                 }
>         } else {
> +               unsigned long long crash_max = crash_base + crash_size;
>                 unsigned long long start;
>
> -               start = memblock_find_in_range(crash_base,
> -                                              crash_base + crash_size,
> -                                              crash_size, SECTION_SIZE);
> +               start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
> +                                                 crash_base, crash_max);
>                 if (start != crash_base) {

If this is true and start is non-zero, then you need an
memblock_free(). However, since the range is equal to the size, then
that can never happen and just checking !start is sufficient.

>                         pr_err("crashkernel reservation failed - memory is in use.\n");
>                         return;
>                 }
>         }
>
> -       ret = memblock_reserve(crash_base, crash_size);
> -       if (ret < 0) {
> -               pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
> -                       (unsigned long)crash_base);
> -               return;
> -       }
> -
>         pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
>                 (unsigned long)(crash_size >> 20),
>                 (unsigned long)(crash_base >> 20),
> diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c
> index d654921dd09b..578670e3f608 100644
> --- a/arch/arm64/kvm/hyp/reserved_mem.c
> +++ b/arch/arm64/kvm/hyp/reserved_mem.c
> @@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
>          * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
>          */
>         hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
> -       hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> -                                             ALIGN(hyp_mem_size, PMD_SIZE),
> -                                             PMD_SIZE);
> +       hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
> +                                          PMD_SIZE);
>         if (!hyp_mem_base)
> -               hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> -                                                     hyp_mem_size, PAGE_SIZE);
> +               hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
>         else
>                 hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
>
> @@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
>                 kvm_err("Failed to reserve hyp memory\n");
>                 return;
>         }
> -       memblock_reserve(hyp_mem_base, hyp_mem_size);
>
>         kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
>                  hyp_mem_base);
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 8490ed2917ff..d566478a06dd 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>  static void __init reserve_crashkernel(void)
>  {
>         unsigned long long crash_base, crash_size;
> +       unsigned long crash_max = arm64_dma_phys_limit;

It all works out to the same size, but it doesn't make sense that
crash_base and crash_size are long long and crash_max is long.

>         int ret;
>
>         ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> @@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
>
>         crash_size = PAGE_ALIGN(crash_size);
>
> -       if (crash_base == 0) {
> -               /* Current arm64 boot protocol requires 2MB alignment */
> -               crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
> -                               crash_size, SZ_2M);
> -               if (crash_base == 0) {
> -                       pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> -                               crash_size);
> -                       return;
> -               }
> -       } else {
> -               /* User specifies base address explicitly. */
> -               if (!memblock_is_region_memory(crash_base, crash_size)) {
> -                       pr_warn("cannot reserve crashkernel: region is not memory\n");
> -                       return;
> -               }
> +       /* User specifies base address explicitly. */
> +       if (crash_base)
> +               crash_max = crash_base + crash_size;
>
> -               if (memblock_is_region_reserved(crash_base, crash_size)) {
> -                       pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
> -                       return;
> -               }
> -
> -               if (!IS_ALIGNED(crash_base, SZ_2M)) {
> -                       pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
> -                       return;

We've lost the alignment check.

Perhaps memblock_phys_alloc_range() should check that the start
matches the alignment. That would simplify the return handling as it
seems NULL is not the only error case.

> -               }
> +       /* Current arm64 boot protocol requires 2MB alignment */
> +       crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> +                                              crash_base, crash_max);
> +       if (!crash_base) {
> +               pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> +                       crash_size);
> +               return;
>         }
> -       memblock_reserve(crash_base, crash_size);
>
>         pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>                 crash_base, crash_base + crash_size, crash_size >> 20);

[...]

> diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
> index 6534c92d0f83..31b5856010cb 100644
> --- a/arch/x86/realmode/init.c
> +++ b/arch/x86/realmode/init.c
> @@ -28,7 +28,7 @@ void __init reserve_real_mode(void)
>         WARN_ON(slab_is_available());
>
>         /* Has to be under 1M so we can execute real-mode AP code. */
> -       mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
> +       mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
>         if (!mem)
>                 pr_info("No sub-1M memory is available for the trampoline\n");
>         else

Don't you need to drop the memblock_reserve() after this?


From cniedermaier at dh-electronics.com  Mon Aug  2 07:10:38 2021
From: cniedermaier at dh-electronics.com (Christoph Niedermaier)
Date: Mon, 2 Aug 2021 16:10:38 +0200
Subject: [PATCH V7 7/7] ARM: dts: imx6qdl-dhcom: Add DHSOM based DRC02 board
In-Reply-To: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
Message-ID: <20210802141038.59663-7-cniedermaier@dh-electronics.com>

Add DT for DH DRC02 unit, which is a universal controller device.
The system has two ethernet ports, two CANs, RS485 and RS232, USB,
capacitive buttons and an OLED display.

Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Fabio Estevam <festevam at denx.de>
Cc: Marek Vasut <marex at denx.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: kernel at dh-electronics.com
To: linux-arm-kernel at lists.infradead.org
---
V2: - Rebase on Shawn Guos branch for-next
V3: - No changes
V4: - No changes
V5: - No changes
V6: - Rebase on 5.14-rc1
V7: - Rebase on Shawn Guos branch for-next
    - Delete cpu at 1 node from cpus
---
 arch/arm/boot/dts/Makefile                 |   3 +-
 arch/arm/boot/dts/imx6qdl-dhcom-drc02.dtsi | 139 +++++++++++++++++++++++++++++
 arch/arm/boot/dts/imx6s-dhcom-drc02.dts    |  30 +++++++
 3 files changed, 171 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/imx6qdl-dhcom-drc02.dtsi
 create mode 100644 arch/arm/boot/dts/imx6s-dhcom-drc02.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 199bc106627c..bcd1f3853b7d 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -610,7 +610,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6qp-tx6qp-8137-mb7.dtb \
 	imx6qp-vicutp.dtb \
 	imx6qp-wandboard-revd1.dtb \
-	imx6qp-zii-rdu2.dtb
+	imx6qp-zii-rdu2.dtb \
+	imx6s-dhcom-drc02.dtb
 dtb-$(CONFIG_SOC_IMX6SL) += \
 	imx6sl-evk.dtb \
 	imx6sl-tolino-shine2hd.dtb \
diff --git a/arch/arm/boot/dts/imx6qdl-dhcom-drc02.dtsi b/arch/arm/boot/dts/imx6qdl-dhcom-drc02.dtsi
new file mode 100644
index 000000000000..3d0a50a9ab21
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-dhcom-drc02.dtsi
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 DH electronics GmbH
+ */
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+/*
+ * Special SoM hardware required which uses the pins from micro SD card. The
+ * pins SD3_DAT0 and SD3_DAT1 are muxed as can2 Tx and Rx. The signals for can2
+ * Tx and Rx are routed to the DHCOM UART1 rts/cts pins. Therefore the micro SD
+ * card must be disabled and the uart1 rts/cts must be output on other DHCOM
+ * pins, see uart1 and usdhc3 node below.
+ */
+&can2 {
+	status = "okay";
+};
+
+&gpio1 {
+	/*
+	 * NOTE: On DRC02, the RS485_RX_En is controlled by a separate
+	 * GPIO line, however the i.MX6 UART driver assumes RX happens
+	 * during TX anyway and that it only controls drive enable DE
+	 * line. Hence, the RX is always enabled here.
+	 */
+	rs485-rx-en-hog {
+		gpio-hog;
+		gpios = <18 0>; /* GPIO Q */
+		line-name = "rs485-rx-en";
+		output-low;
+	};
+};
+
+&gpio3 {
+	gpio-line-names =
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "DRC02-In1", "", "", "", "";
+};
+
+&gpio4 {
+	gpio-line-names =
+		"", "", "", "", "", "DHCOM-E", "DRC02-In2", "DHCOM-H",
+		"DHCOM-I", "DRC02-HW0", "", "", "", "", "", "",
+		"", "", "", "", "DRC02-Out1", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio6 {
+	gpio-line-names =
+		"", "", "", "DRC02-Out2", "", "", "SOM-HW1", "",
+		"", "", "", "", "", "", "DRC02-HW2", "DRC02-HW1",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&i2c1 {
+	eeprom at 50 {
+		compatible = "atmel,24c04";
+		reg = <0x50>;
+		pagesize = <16>;
+	};
+};
+
+&uart1 {
+	/*
+	 * Due to the use of can2 the signals for can2 Tx and Rx are routed to
+	 * DHCOM UART1 rts/cts pins. Therefore this UART have to use DHCOM GPIOs
+	 * for rts/cts. So configure DHCOM GPIO I as rts and GPIO M as cts.
+	 */
+	/delete-property/ uart-has-rtscts;
+	cts-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>; /* GPIO M */
+	pinctrl-0 = <&pinctrl_uart1 &pinctrl_dhcom_i &pinctrl_dhcom_m>;
+	pinctrl-names = "default";
+	rts-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */
+};
+
+&uart5 {
+	/*
+	 * On DRC02 this UART is used as RS485 interface and RS485_TX_En is
+	 * controlled by DHCOM GPIO P. So remove rts/cts pins and the property
+	 * uart-has-rtscts from this UART and add the DHCOM GPIO P pin via
+	 * rts-gpios. The RS485_RX_En is controlled by DHCOM GPIO Q, see gpio1
+	 * node above.
+	 */
+	/delete-property/ uart-has-rtscts;
+	linux,rs485-enabled-at-boot-time;
+	pinctrl-0 = <&pinctrl_uart5_core &pinctrl_dhcom_p &pinctrl_dhcom_q>;
+	pinctrl-names = "default";
+	rts-gpios = <&gpio7 13 GPIO_ACTIVE_HIGH>; /* GPIO P */
+};
+
+&usdhc2 { /* SD card */
+	status = "okay";
+};
+
+&usdhc3 {
+	/*
+	 * Due to the use of can2 the micro SD card on module have to be
+	 * disabled, because the pins SD3_DAT0 and SD3_DAT1 are muxed as
+	 * can2 Tx and Rx.
+	 */
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl-0 = <
+			/*
+			 * The following DHCOM GPIOs are used on this board.
+			 * Therefore, they have been removed from the list below.
+			 * I: uart1 rts
+			 * M: uart1 cts
+			 * P: uart5 rs485-tx-en
+			 * Q: uart5 rs485-rx-en
+			 */
+			&pinctrl_hog_base
+			&pinctrl_dhcom_a &pinctrl_dhcom_b &pinctrl_dhcom_c
+			&pinctrl_dhcom_d &pinctrl_dhcom_e &pinctrl_dhcom_f
+			&pinctrl_dhcom_g &pinctrl_dhcom_h
+			&pinctrl_dhcom_j &pinctrl_dhcom_k &pinctrl_dhcom_l
+			&pinctrl_dhcom_n &pinctrl_dhcom_o
+			&pinctrl_dhcom_r
+			&pinctrl_dhcom_s &pinctrl_dhcom_t &pinctrl_dhcom_u
+			&pinctrl_dhcom_v &pinctrl_dhcom_w &pinctrl_dhcom_int
+		>;
+	pinctrl-names = "default";
+
+	pinctrl_uart5_core: uart5-core-grp {
+		fsl,pins = <
+			MX6QDL_PAD_CSI0_DAT14__UART5_TX_DATA	0x1b0b1
+			MX6QDL_PAD_CSI0_DAT15__UART5_RX_DATA	0x1b0b1
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6s-dhcom-drc02.dts b/arch/arm/boot/dts/imx6s-dhcom-drc02.dts
new file mode 100644
index 000000000000..4077b607c29e
--- /dev/null
+++ b/arch/arm/boot/dts/imx6s-dhcom-drc02.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 DH electronics GmbH
+ *
+ * DHCOM iMX6 variant:
+ * DHCM-iMX6S-C0800-R102-F0409-E-CAN2-RTC-I-01D2
+ * DHCOM PCB number: 493-400 or newer
+ * DRC02 PCB number: 568-100 or newer
+ */
+/dts-v1/;
+
+/*
+ * The kernel only distinguishes between i.MX6 Quad and DualLite,
+ * but the Solo is actually a DualLite with only one CPU. So use
+ * DualLite for the Solo and disable one CPU node.
+ */
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-dhcom-som.dtsi"
+#include "imx6qdl-dhcom-drc02.dtsi"
+
+/ {
+	model = "DH electronics i.MX6S DHCOM on DRC02";
+	compatible = "dh,imx6s-dhcom-drc02", "dh,imx6s-dhcom-som",
+		     "fsl,imx6dl";
+
+	cpus {
+		/delete-node/ cpu at 1;
+	};
+};
-- 
2.11.0



From kuba at kernel.org  Mon Aug  2 08:02:05 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 2 Aug 2021 08:02:05 -0700
Subject: [PATCH] net: sparx5: fix bitmask check
In-Reply-To: <20210802145449.1154565-1-arnd@kernel.org>
References: <20210802145449.1154565-1-arnd@kernel.org>
Message-ID: <20210802080205.6a9f9bb1@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Mon,  2 Aug 2021 16:54:37 +0200 Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> Older compilers such as gcc-5.5 produce a warning in this driver
> when ifh_encode_bitfield() is not getting inlined:
> 
> drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c: In function 'ifh_encode_bitfield':
> include/linux/compiler_types.h:333:38: error: call to '__compiletime_assert_545' declared with attribute error: Unsupported width, must be <= 40
> drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c:28:2: note: in expansion of macro 'compiletime_assert'
>   compiletime_assert(width <= 40, "Unsupported width, must be <= 40");
>   ^
> 
> Mark the function as __always_inline to make the check work correctly
> on all compilers. 

I fixed this by moving the check out to a macro wrapper in net:
6387f65e2acb ("net: sparx5: fix compiletime_assert for GCC 4.9")

> To make this also work on 32-bit architectures, change
> the GENMASK() to GENMASK_ULL().

Would you mind resending just that part against net/master?

> Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support")
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>


From robh at kernel.org  Mon Aug  2 08:01:55 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 09:01:55 -0600
Subject: [PATCH 5/7] dt-bindings: soc: imx: add missing anatop binding
In-Reply-To: <CAA+hA=TwGGwZi2HzZSLSZHYWEi8Pp6AnHeRpfDhD0pUfY_xPSQ@mail.gmail.com>
References: <20210715082536.1882077-1-aisheng.dong@nxp.com>
 <20210715082536.1882077-6-aisheng.dong@nxp.com>
 <20210722024948.GA3198597@robh.at.kernel.org>
 <CAA+hA=TwGGwZi2HzZSLSZHYWEi8Pp6AnHeRpfDhD0pUfY_xPSQ@mail.gmail.com>
Message-ID: <CAL_Jsq+4247uCgu5pDAEqO9Nn=9deeJBkiOrG3fTwdqPO+6J2w@mail.gmail.com>

On Mon, Aug 2, 2021 at 5:38 AM Dong Aisheng <dongas86 at gmail.com> wrote:
>
> Hi Rob,
>
> On Thu, Jul 22, 2021 at 10:49 AM Rob Herring <robh at kernel.org> wrote:
> >
> > On Thu, Jul 15, 2021 at 04:25:34PM +0800, Dong Aisheng wrote:
> > > Anatop is a system combo module which supports various analog functions
> > > like PLL, Regulators, LDOs, Sensors and etc.
> > > This binding doc is generated based on the exist usage in dts
> > > in order to fix dt schema check failures.
> > >
> > > Cc: Rob Herring <robh+dt at kernel.org>
> > > Cc: Shawn Guo <shawnguo at kernel.org>
> > > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> > > ---
> > >  .../bindings/soc/imx/fsl,anatop.yaml          | 68 +++++++++++++++++++
> > >  1 file changed, 68 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> > > new file mode 100644
> > > index 000000000000..f379d960f527
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> > > @@ -0,0 +1,68 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/soc/imx/fsl,anatop.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Freescale Anatop binding
> > > +
> > > +maintainers:
> > > +  - Dong Aisheng <aisheng.dong at nxp.com>
> > > +
> > > +properties:
> > > +  compatible:
> > > +    oneOf:
> > > +      - items:
> > > +          - const: fsl,imx6q-anatop
> > > +          - const: syscon
> > > +          - const: simple-mfd
> > > +      - items:
> > > +          - enum:
> > > +              - fsl,imx6sl-anatop
> > > +              - fsl,imx6sll-anatop
> > > +              - fsl,imx6sx-anatop
> > > +              - fsl,imx6ul-anatop
> > > +              - fsl,imx7d-anatop
> > > +          - const: fsl,imx6q-anatop
> > > +          - const: syscon
> > > +          - const: simple-mfd
> > > +      - items:
> > > +          - enum:
> > > +              - fsl,imx8mq-anatop
> > > +              - fsl,imx8mm-anatop
> > > +              - fsl,vf610-anatop
> > > +          - const: syscon
> > > +      - items:
> > > +          - enum:
> > > +              - fsl,imx8mn-anatop
> > > +              - fsl,imx8mp-anatop
> > > +          - const: fsl,imx8mm-anatop
> > > +          - const: syscon
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  interrupts:
> > > +    items:
> > > +      - description: Temperature Sensor
> > > +      - description: PMU interrupt 1
> > > +      - description: PMU interrupt 2
> > > +    minItems: 1
> > > +    maxItems: 3
> >
> > Don't need maxItems.
> >
>
> Got it
>
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +
> > > +additionalProperties: true
> >
> > This should be the case only for common schemas used by other schemas.
> >
>
> Like iomuxc-gpr in patch 6, the problem is that for those nodes with
> simple-mfd backwards compatibility,
> there could be possibly some random subnodes since there're generic
> combo registers.
> That's why i use additionalProperties true to cover it.
> Do you think it's ok?

No, because all that should be reviewed rather than random subnodes.
Otherwise, how do we validate them?

Rob


From robdclark at gmail.com  Mon Aug  2 08:08:07 2021
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 2 Aug 2021 08:08:07 -0700
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent masters
 to use system cache
In-Reply-To: <20210802105544.GA27657@willie-the-truck>
References: <cover.1610372717.git.saiprakash.ranjan@codeaurora.org>
 <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
Message-ID: <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>

On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
>
> On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> > On 2021-07-28 19:30, Georgi Djakov wrote:
> > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > > the memory type setting required for the non-coherent masters to use
> > > > system cache. Now that system cache support for GPU is added, we will
> > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > > Without this, the system cache lines are not allocated for GPU.
> > > >
> > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > > and makes GPU the user of this protection flag.
> > >
> > > Thank you for the patchset! Are you planning to refresh it, as it does
> > > not apply anymore?
> > >
> >
> > I was waiting on Will's reply [1]. If there are no changes needed, then
> > I can repost the patch.
>
> I still think you need to handle the mismatched alias, no? You're adding
> a new memory type to the SMMU which doesn't exist on the CPU side. That
> can't be right.
>

Just curious, and maybe this is a dumb question, but what is your
concern about mismatched aliases?  I mean the cache hierarchy on the
GPU device side (anything beyond the LLC) is pretty different and
doesn't really care about the smmu pgtable attributes..

BR,
-R


From leo.yan at linaro.org  Mon Aug  2 08:03:58 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 2 Aug 2021 23:03:58 +0800
Subject: [PATCH 2/6] perf cs-etm: Initialise architecture based on TRCIDR1
In-Reply-To: <CAJ9a7VhdLaP3rkXwscAQpVe+jSgcx02WjY=RmiBkaCB6ObGTjQ@mail.gmail.com>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-3-james.clark@arm.com>
 <CAJ9a7Viap53OgrM2e_DU4+oymFB41jspbKbvEVFQWROt7ifuXw@mail.gmail.com>
 <20210731060312.GB7437@leoy-ThinkPad-X240s>
 <CAJ9a7VhdLaP3rkXwscAQpVe+jSgcx02WjY=RmiBkaCB6ObGTjQ@mail.gmail.com>
Message-ID: <20210802150358.GA148327@leoy-ThinkPad-X240s>

Hi Mike,

On Mon, Aug 02, 2021 at 03:04:14PM +0100, Mike Leach wrote:

[...]

> > > > +#define TRCIDR1_TRCARCHMIN_SHIFT 4
> > > > +#define TRCIDR1_TRCARCHMIN_MASK  GENMASK(7, 4)
> > > > +#define TRCIDR1_TRCARCHMIN(x)    (((x) & TRCIDR1_TRCARCHMIN_MASK) >> TRCIDR1_TRCARCHMIN_SHIFT)
> > > > +static enum _ocsd_arch_version cs_etm_decoder__get_arch_ver(u32 reg_idr1)
> > > > +{
> > > > +       /*
> > > > +        * If the ETM trace minor version is 4 or more then we can assume
> > > > +        * the architecture is ARCH_AA64 rather than just V8
> > > > +        */
> > > > +       return TRCIDR1_TRCARCHMIN(reg_idr1) >= 4 ? ARCH_AA64 : ARCH_V8;
> > > > +}
> > >
> > > This is true for ETM4.x & ETE 1.x (arch 5.x) but not ETM 3.x
> > > Probably need to beef up this comment or the function name to emphasise this.
> >
> > Yeah, I think it's good to change the function name.  Eventually, this
> > function should only be used for ETM4.x and ETE.
> >
> > Another minor comment is: can we refine the arch version number, e.g.
> > change the OpenCSD's macro "ARCH_AA64" to "ARCH_V8R4", (or
> > "ARCH_V8R3_AA64"), this can give more clear clue what's the ETM version.
> >
> 
> The purpose of these macros is to inform the decoder of the
> architecture of the PE - not the version of the ETM.
> 
> These OpenCSD macros are defined by the library headers
> (ocsd_if_types.h) and not the perf headers.
> These have been published as the API / ABI for OpenCSD and as such
> changing them affects all OpenCSD clients, not just perf.

I understand these macros are defined in OpenCSD lib as APIs, since I
saw these macros have not been widely used in perf tool (e.g.
ARCH_AA64), so this is why I think it's good to take chance to refine
the naming conventions.

> This PE architecture version is used along with the core profile to
> determine which instructions are valid waypoint instructions to
> associate with atom elements when walking the program image during
> trace decode.
> 
> From v8.3  onwards we moved away from filtering on specific
> architecture versions. This was due to two factors:-
> 1. The architectural rules now allow architectural features for one
> increment e.g. Arch 8.4, to be backported into  the previous increment
> - e,g, 8.3, which made this filtering more difficult to track.
> 2. After discussion with the PE architects it was clear that
> instructions in a later architect version would not re-use older
> opcodes from a previous one and  be nop / invalid in the earlier
> architectures. (certainly in the scope of AA64). Therefore
> the policy in the decoder is to check for all the instructions we know
> about for the latest version of architecture, even if we could be
> decoding an earlier architecture version. This means we may check for
> a few more opcodes than necessary for earlier version of the
> architecture, but the overall decode is more robust and easier to
> maintain.
> 
> Therefore for any AA64 core beyond v8.3 - it is safe to use the
> ARCH_AA64 PE architecture version and the decoder will handle it.

I have no objection for current approach; but two things can cause
confusions and it might be difficult for maintenance:

- The first thing is now we base on the bit fields TRCIDR1::TRCARCHMIN
  to decide the PE architecture version.  In the ETMv4 spec,
  TRCIDR1::TRCARCHMIN is defined as the trace unit minor version,
  so essentially it's a minor version number for tracer (ETM) but not
  the PE architecture number.  But now we are using it to decide the
  PE architecture number (8.3, 8.4, etc...).

- The second thing is the macros' naming convention.
  E.g. "AA64" gives me an impression it is a general naming "Arm Arch 64"
  for all Arm 64-bit CPUs, it's something like an abbreviation for
  "aarch64"; so seems to me it doesn't show any meaningful info for PE's
  architecture version number.  This is why I proposed to use more
  explict macro definition for architectures (e.g. ARCH_V8R3, ARCH_V8R4,
  ARCH_V9R0, etc).

If we really want to use ARCH_AA64, it's better to give some comments in
the code.

Thanks a lot for shared the background info.

Leo


From rppt at kernel.org  Mon Aug  2 08:08:02 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 2 Aug 2021 18:08:02 +0300
Subject: [RFC PATCH 1/2] arm64: mm: Make virt_addr_valid to check for
 pfn_valid again
In-Reply-To: <20210802121947.GF18685@arm.com>
References: <1627490656-1267-1-git-send-email-olekstysh@gmail.com>
 <20210802121947.GF18685@arm.com>
Message-ID: <YQgKUibfW4jZbBXM@kernel.org>

Hi,

On Mon, Aug 02, 2021 at 01:19:48PM +0100, Catalin Marinas wrote:
> Adding Mike and Anshuman,
> 
> On Wed, Jul 28, 2021 at 07:44:15PM +0300, Oleksandr Tyshchenko wrote:
> > From: Oleksandr Tyshchenko <oleksandr_tyshchenko at epam.com>
> > 
> > The problem is that Arm's implementation of virt_addr_valid()
> > leads to memblock_is_map_memory() check, which will fail for
> > ZONE_DEVICE based addresses. But, the pfn_valid() check in turn
> > is able to cope with ZONE_DEVICE based memory.
> > 
> > You can find a good explanation of that problem at:
> > https://lore.kernel.org/lkml/1614921898-4099-2-git-send-email-anshuman.khandual at arm.com
> > 
> > Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko at epam.com>
> > ---
> > I am not quite sure whether it is a "correct" place and
> > the change itself, I just partially restored a behaviour before:
> > https://lore.kernel.org/lkml/20210511100550.28178-4-rppt at kernel.org
> > So, the target of this patch is to get a feedback how to resolve
> > this properly if, of course, this really needs to be resolved
> > (I might miss important bits here).
> > 
> > It is worth mentioning that patch doesn't fix the current code base
> > (if I am not mistaken, no one calls virt_addr_valid() on Arm64 for
> > ZONE_DEVICE based addresses at the moment, so it seems that nothing
> > is broken), the fix is intended for the subsequent patch in this
> > series that will try to enable Xen's "unpopulated-alloc" usage
> > on Arm (it was enabled on x86 so far).
> > Please see:
> > [RFC PATCH 2/2] xen/unpopulated-alloc: Query hypervisor to provide
> > unallocated space
> > 
> > The subsequent patch will enable the code where virt_addr_valid()
> > is used in drivers/xen/unpopulated-alloc.c:fill_list() to check that
> > a virtual address returned by memremap_pages() is valid.
 
> I wonder what the point of calling virt_addr_valid() in fill_list() is?
> If memremap_pages() succeeded, the pages were mapped at the returned
> vaddr, there's no need for an additional virt_addr_valid() check.

The virt_addr_valid() check in fill_list() looks bogus to me as well. If
memremap_pages() succeeds the range is guaranteed to have proper page
table.

I believe the first patch should be rather removal of the virt_addr_valid()
check in fill_list().
 
> > ---
> >  arch/arm64/include/asm/memory.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> > index 824a365..1a35a44 100644
> > --- a/arch/arm64/include/asm/memory.h
> > +++ b/arch/arm64/include/asm/memory.h
> > @@ -351,7 +351,7 @@ static inline void *phys_to_virt(phys_addr_t x)
> >  
> >  #define virt_addr_valid(addr)	({					\
> >  	__typeof__(addr) __addr = __tag_reset(addr);			\
> > -	__is_lm_address(__addr) && pfn_is_map_memory(virt_to_pfn(__addr));	\
> > +	__is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr));	\
> >  })
> 
> pfn_valid() only guarantees the presence of a struct page but not
> necessarily that the virtual address is accessible (valid). So this
> change would break the NOMAP ranges case.

+1

-- 
Sincerely yours,
Mike.


From will at kernel.org  Mon Aug  2 08:14:09 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Aug 2021 16:14:09 +0100
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent
 masters to use system cache
In-Reply-To: <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
References: <cover.1610372717.git.saiprakash.ranjan@codeaurora.org>
 <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
Message-ID: <20210802151409.GE28735@willie-the-truck>

On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> >
> > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> > > On 2021-07-28 19:30, Georgi Djakov wrote:
> > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > > > the memory type setting required for the non-coherent masters to use
> > > > > system cache. Now that system cache support for GPU is added, we will
> > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > > > Without this, the system cache lines are not allocated for GPU.
> > > > >
> > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > > > and makes GPU the user of this protection flag.
> > > >
> > > > Thank you for the patchset! Are you planning to refresh it, as it does
> > > > not apply anymore?
> > > >
> > >
> > > I was waiting on Will's reply [1]. If there are no changes needed, then
> > > I can repost the patch.
> >
> > I still think you need to handle the mismatched alias, no? You're adding
> > a new memory type to the SMMU which doesn't exist on the CPU side. That
> > can't be right.
> >
> 
> Just curious, and maybe this is a dumb question, but what is your
> concern about mismatched aliases?  I mean the cache hierarchy on the
> GPU device side (anything beyond the LLC) is pretty different and
> doesn't really care about the smmu pgtable attributes..

If the CPU accesses a shared buffer with different attributes to those which
the device is using then you fall into the "mismatched memory attributes"
part of the Arm architecture. It's reasonably unforgiving (you should go and
read it) and in some cases can apply to speculative accesses as well, but
the end result is typically loss of coherency.

Will


From mikelley at microsoft.com  Mon Aug  2 08:15:30 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Mon, 2 Aug 2021 15:15:30 +0000
Subject: [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64
In-Reply-To: <1626793023-13830-1-git-send-email-mikelley@microsoft.com>
References: <1626793023-13830-1-git-send-email-mikelley@microsoft.com>
Message-ID: <MWHPR21MB1593188EC3D8AD239BF15882D7EF9@MWHPR21MB1593.namprd21.prod.outlook.com>

From: Michael Kelley <mikelley at microsoft.com> Sent: Tuesday, July 20, 2021 7:57 AM
> 
> This series enables Linux guests running on Hyper-V on ARM64
> hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> Hyper-V and its hypercall mechanism.  Existing architecture
> independent drivers for Hyper-V's VMbus and synthetic devices just
> work when built for ARM64. Hyper-V code is built and included in
> the image and modules only if CONFIG_HYPERV is enabled.

Will and Catalin --

Gentle ping. :-)   The clock/timer issues are now worked out in that
Hyper-V is providing full Generic Timer functionality in guest VMs.
That dropped some code out of the patch set, and making additional
code architecture neutral reduced the ARM64 specific code in this patch
set even further.  

To my knowledge, all issues have been addressed, so I'm looking for
any further review from you as ARM64 maintainers, or your Ack so
this can be ready for the 5.15 merge window.

Thanks!

Michael

> 
> The five patches are organized as follows:
> 
> 1) Add definitions and functions for making Hyper-V hypercalls
>    and getting/setting virtual processor registers provided by
>    Hyper-V
> 
> 2) Add the function needed by the arch independent VMbus driver
>    for reporting a panic to Hyper-V.
> 
> 3) Add Hyper-V initialization code and utility functions that
>    report Hyper-v status.
> 
> 4) Export screen_info so it may be used by the Hyper-V frame buffer
>    driver built as a module. It is already exported for x86,
>    powerpc, and alpha architectures.
> 
> 5) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.
> 
> Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> with 4K/16K/64K page size. Linux guests with this patch series
> work with all three supported ARM64 page sizes.
> 
> The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> x86/x64-specific code and is not being built for ARM64. Enabling
> Hyper-V vPCI devices on ARM64 is in progress via a separate set
> of patches.
> 
> This patch set is based on the linux-next20210720 code tree.
> 
> Changes in v11:
> * Drop the previous Patch 1 as the fixes have already been
>   separately accepted upstream.
> * Drop the previous Patch 3 for enabling Hyper-V enlightened
>   clocks/timers.  Hyper-V is now offering the full ARM64
>   architectural Generic Timer in guest VMs, so the existing
>   arch_arch_timer.c driver just works. [Mark Rutland, Marc
>   Zyngier]
> * Simplified the previous Patch 4 and Patch 5 (now Patch 2 and 3)
>   by sharing more code between the x86 and ARM64 architectures.
> * Combined hyperv_early_init() and hyperv_init() into a single
>   initialization function that runs as an early_initcall. This
>   is possible because the Hyper-V enlightened clocks/timers
>   no longer need to be initialized early in the boot sequence.
> 
> Changes in v10:
> * Drop previous Patch 1 for SMCCC v1.2 HVC calls in favor of
>   Sudeep Holla's patch [Mark Rutland]
> * Use new helper functions in 5.13 for checking Hyper-V hypercall
>   return status
> * Set up per-CPU hypercall argument page that is now used by the
>   Hyper-V balloon driver
> * Rebase on 5.13-RC1
> 
> Changes in v9:
> * Added Patch 1 to enable making an SMCCC compliant hypercall
>   that returns results in other than registers X0 thru X3, per
>   version 1.2 and later of the SMCCC spec.
> * Using the ability to return results in registers X6 and X7,
>   converted hv_get_vpreg_128() to use a "fast" hypercall that
>   passes inputs and outputs in registers, and in doing so eliminated
>   a lot of memory allocation complexity.
> * Cleaned up some extra blank lines and use of spaces in aligning
>   local variables. [Sunil Muthuswamy]
> * Based on discussion about future directions, reverted the
>   population of hv_vp_index array to use a cpuhp state instead
>   of a hypercall, which is like it was in v7 and earlier.
> 
> Changes in v8:
> * Removed a lot of code based on refactoring the boundary between
>   arch independent and arch dependent code for Hyper-V, per comments
>   from Arnd Bergmann. The removed code was either duplicated on
>   the x86 side, or has been folded into architecture independent
>   code as not really being architecture dependent.
> * Added config dependency on !CONFIG_CPU_BIG_ENDIAN [Arnd Bergmann]
> * Reworked the approach to Hyper-V initialization. The functionality
>   is the same, but is now structured like the Xen code with an early
>   init function called in setup_arch() and an early initcall to
>   finish the initialization. [Arnd Bergmann]
> 
> Changes in v7:
> * Separately upstreamed split of hyperv-tlfs.h into arch dependent
>   and independent versions.  In this patch set, update the ARM64
>   hyperv-tlfs.h to include architecture independent definitions.
>   This approach eliminates a lot of lines of otherwise duplicated
>   code on the ARM64 side.
> * Break ARM64 mshyperv.h into smaller pieces. Have an initial
>   baseline, and add code along with patches for a particular
>   functional area. [Marc Zyngier]
> * In mshyperv.h, use static inline functions instead of #defines
>   where possible. [Arnd Bergmann]
> * Use VMbus INTID obtained from ACPI DSDT instead of hardcoding.
>   The STIMER INTID is still hardcoded because it is needed
>   before Linux has initialized the ACPI subsystem, so it can't
>   be obtained from the DSDT.  Wedging it into the GTDT seems
>   dubious, so was not done. [Marc Zyngier]
> * Update Hyper-V page size allocation functions to use
>   alloc_page() if PAGE_SIZE == HV_HYP_PAGE_SIZE [Arnd
>   Bergmann]
> * Various other minor changes based on feedback and to rebase
>   to latest linux-next [Marc Zyngier and Arnd Bergmann]
> 
> Changes in v6:
> * Use SMCCC hypercall interface instead of direct invocation
>   of HVC instruction and the Hyper-V hypercall interface
>   [Marc Zyngier]
> * Reimplemented functions to alloc/free Hyper-V size pages
>   using kmalloc/kfree since kmalloc now guarantees alignment of
>   power of 2 size allocations [Marc Zyngier]
> * Export screen_info in arm64 architecture so it can be used
>   by the Hyper-V buffer driver built as a module
> * Renamed source file arch/arm64/hyperv/hv_init.c to hv_core.c
>   to better reflect its content
> * Fixed the bit position of certain feature flags presented by
>   Hyper-V to the guest.  The bit positions on ARM64 don't match
>   the position on x86 like originally thought.
> * Minor fixups to rebase to 5.6-rc5 linux-next
> 
> Changes in v5:
> * Minor fixups to rebase to 5.4-rc1 linux-next
> 
> Changes in v4:
> * Moved clock-related code into an architecture independent
>   Hyper-V clocksource driver that is already upstream. Clock
>   related code is removed from this patch set except for the
>   ARM64 specific interrupt handler. [Marc Zyngier]
> * Separately upstreamed the split of mshyperv.h into arch independent
>   and arch dependent portions. The arch independent portion has been
>   removed from this patch set.
> * Divided patch #2 of the series into multiple smaller patches
>   [Marc Zyngier]
> * Changed a dozen or so smaller things based on feedback
>   [Marc Zyngier, Will Deacon]
> * Added functions to alloc/free Hyper-V size pages for use by
>   drivers for Hyper-V synthetic devices when updated to not assume
>   guest page size and Hyper-v page size are the same
> 
> Changes in v3:
> * Added initialization of hv_vp_index array like was recently
>   added on x86 branch [KY Srinivasan]
> * Changed Hyper-V ARM64 register symbols to be all uppercase
>   instead of mixed case [KY Srinivasan]
> * Separated mshyperv.h into two files, one architecture
>   independent and one architecture dependent. After this code
>   is upstream, will make changes to the x86 code to use the
>   architecture independent file and remove duplication. And
>   once we have a multi-architecture Hyper-V TLFS, will do a
>   separate patch to split hyperv-tlfs.h in the same way.
>   [KY Srinivasan]
> * Minor tweaks to rebase to latest linux-next code
> 
> Changes in v2:
> * Removed patch to implement slow_virt_to_phys() on ARM64.
>   Use of slow_virt_to_phys() in arch independent Hyper-V
>   drivers has been eliminated by commit 6ba34171bcbd
>   ("Drivers: hv: vmbus: Remove use of slow_virt_to_phys()")
> * Minor tweaks to rebase to latest linux-next code
> 
> Michael Kelley (5):
>   arm64: hyperv: Add Hyper-V hypercall and register access utilities
>   arm64: hyperv: Add panic handler
>   arm64: hyperv: Initialize hypervisor on boot
>   arm64: efi: Export screen_info
>   Drivers: hv: Enable Hyper-V code to be built on ARM64
> 
>  MAINTAINERS                          |   3 +
>  arch/arm64/Kbuild                    |   1 +
>  arch/arm64/hyperv/Makefile           |   2 +
>  arch/arm64/hyperv/hv_core.c          | 181 +++++++++++++++++++++++++++++++++++
>  arch/arm64/hyperv/mshyperv.c         |  83 ++++++++++++++++
>  arch/arm64/include/asm/hyperv-tlfs.h |  69 +++++++++++++
>  arch/arm64/include/asm/mshyperv.h    |  54 +++++++++++
>  arch/arm64/kernel/efi.c              |   1 +
>  drivers/hv/Kconfig                   |   5 +-
>  9 files changed, 397 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm64/hyperv/Makefile
>  create mode 100644 arch/arm64/hyperv/hv_core.c
>  create mode 100644 arch/arm64/hyperv/mshyperv.c
>  create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
>  create mode 100644 arch/arm64/include/asm/mshyperv.h
> 
> --
> 1.8.3.1



From will at kernel.org  Mon Aug  2 08:16:07 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Aug 2021 16:16:07 +0100
Subject: [Patch V2 0/2] iommu/arm-smmu: Fix races in iommu domain/group
 creation
In-Reply-To: <1623961837-12540-1-git-send-email-amhetre@nvidia.com>
References: <1623961837-12540-1-git-send-email-amhetre@nvidia.com>
Message-ID: <20210802151607.GF28735@willie-the-truck>

On Fri, Jun 18, 2021 at 02:00:35AM +0530, Ashish Mhetre wrote:
> Multiple iommu domains and iommu groups are getting created for the devices
> sharing same SID. It is expected for devices sharing same SID to be in same
> iommu group and same iommu domain.
> This is leading to context faults when one device is accessing IOVA from
> other device which shouldn't be the case for devices sharing same SID.
> Fix this by protecting iommu domain and iommu group creation with mutexes.

Robin -- any chance you could take a look at these, please? You had some
comments on the first version which convinced me that they are needed,
but I couldn't tell whether you wanted to solve this a different way or not.

Cheers,

Will


From leo.yan at linaro.org  Mon Aug  2 08:17:10 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 2 Aug 2021 23:17:10 +0800
Subject: [RFC PATCH 5/6] perf cs-etm: Improve Coresight zero timestamp
 warning
In-Reply-To: <20210729155805.2830-6-james.clark@arm.com>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-6-james.clark@arm.com>
Message-ID: <20210802151710.GB148327@leoy-ThinkPad-X240s>

On Thu, Jul 29, 2021 at 04:58:04PM +0100, James Clark wrote:
> Only show the warning if the user hasn't already set timeless mode and
> improve the text because there was ambiguity around the meaning of '...'
> 
> Change the warning to a UI warning instead of printing straight to
> stderr because this corrupts the UI when perf report TUI is used. The UI
> warning function also handles printing to stderr when in perf script
> mode.
> 
> Suggested-by: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: James Clark <james.clark at arm.com>

Reviewed-by: Leo Yan <leo.yan at linaro.org>

> ---
>  tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> index 3e1a05bc82cc..5084bd2ca6eb 100644
> --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> @@ -324,8 +324,11 @@ cs_etm_decoder__do_hard_timestamp(struct cs_etm_queue *etmq,
>  		 * underflow.
>  		 */
>  		packet_queue->cs_timestamp = 0;
> -		WARN_ONCE(true, "Zero Coresight timestamp found at Idx:%" OCSD_TRC_IDX_STR
> -				". Decoding may be improved with --itrace=Z...\n", indx);
> +		if (!cs_etm__etmq_is_timeless(etmq))
> +			pr_warning_once("Zero Coresight timestamp found at Idx:%" OCSD_TRC_IDX_STR
> +					". Decoding may be improved by prepending 'Z' to your current --itrace arguments.\n",
> +					indx);
> +
>  	} else if (packet_queue->instr_count > elem->timestamp) {
>  		/*
>  		 * Sanity check that the elem->timestamp - packet_queue->instr_count would not
> -- 
> 2.28.0
> 


From arnd at kernel.org  Mon Aug  2 08:21:53 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon,  2 Aug 2021 17:21:53 +0200
Subject: [PATCH] net: sparx5: fix bitmask on 32-bit targets
Message-ID: <20210802152201.1158412-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

I saw the build failure that was fixed in commit 6387f65e2acb ("net:
sparx5: fix compiletime_assert for GCC 4.9") and noticed another
issue that was introduced in the same patch: Using GENMASK() to
create a 64-bit mask does not work on 32-bit architectures.

This probably won't ever happen on this driver since it's specific
to a 64-bit SoC, but it's better to write it portably, so use
GENMASK_ULL() instead.

Fixes: f3cad2611a77 ("net: sparx5: add hostmode with phylink support")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
index 1a240e6bddd0..cb68eaaac881 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
@@ -32,7 +32,7 @@ static void __ifh_encode_bitfield(void *ifh, u64 value, u32 pos, u32 width)
 	u32 byte = (35 - (pos / 8));
 	/* Calculate the Start bit position in the Start IFH byte */
 	u32 bit  = (pos % 8);
-	u64 encode = GENMASK(bit + width - 1, bit) & (value << bit);
+	u64 encode = GENMASK_ULL(bit + width - 1, bit) & (value << bit);
 
 	/* The b0-b7 goes into the start IFH byte */
 	if (encode & 0xFF)
-- 
2.29.2



From arnd at kernel.org  Mon Aug  2 08:21:52 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 2 Aug 2021 17:21:52 +0200
Subject: [PATCH] net: sparx5: fix bitmask check
In-Reply-To: <20210802080205.6a9f9bb1@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
References: <20210802145449.1154565-1-arnd@kernel.org>
 <20210802080205.6a9f9bb1@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
Message-ID: <CAK8P3a0-z+_bsVVjy5h+f=O27BfUjBOFJ1-18aQOmUwf4rZTKg@mail.gmail.com>

On Mon, Aug 2, 2021 at 5:02 PM Jakub Kicinski <kuba at kernel.org> wrote:
>
> I fixed this by moving the check out to a macro wrapper in net:
> 6387f65e2acb ("net: sparx5: fix compiletime_assert for GCC 4.9")

Ok, got it.

> > To make this also work on 32-bit architectures, change
> > the GENMASK() to GENMASK_ULL().
>
> Would you mind resending just that part against net/master?

Done.

        Arnd


From lorenzo.pieralisi at arm.com  Mon Aug  2 08:23:57 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon,  2 Aug 2021 16:23:57 +0100
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
Message-ID: <20210802152359.12623-2-lorenzo.pieralisi@arm.com>

Add a __force attribute to the void* cast in acpi_os_map_iomem()
to prevent sparse warnings.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
---
 drivers/acpi/osl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 45c5c0e45e33..8f67bf0f090b 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -376,7 +376,7 @@ EXPORT_SYMBOL_GPL(acpi_os_map_iomem);
 
 void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
-	return (void *)acpi_os_map_iomem(phys, size);
+	return (__force void *)acpi_os_map_iomem(phys, size);
 }
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
-- 
2.31.0



From lorenzo.pieralisi at arm.com  Mon Aug  2 08:23:56 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon,  2 Aug 2021 16:23:56 +0100
Subject: [PATCH v2 0/3] ACPI: Fix acpi_os_map_memory() memory semantics
In-Reply-To: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
Message-ID: <20210802152359.12623-1-lorenzo.pieralisi@arm.com>

Patch series is a v2 of a previous version[1]:

v1->v2
	- Added patch 1 and 2 according to feedback received on[1]

[1] https://lore.kernel.org/linux-acpi/20210726100026.12538-1-lorenzo.pieralisi at arm.com

Lorenzo Pieralisi (3):
  ACPI: osl: Add __force attribute in acpi_os_map_iomem() cast
  ACPI: osl: Reorder acpi_os_map_iomem() __ref annotation
  ACPI: Add memory semantics to acpi_os_map_memory()

 arch/arm64/include/asm/acpi.h |  3 +++
 arch/arm64/kernel/acpi.c      | 19 ++++++++++++++++---
 drivers/acpi/osl.c            | 23 ++++++++++++++++-------
 include/acpi/acpi_io.h        | 12 ++++++++++--
 4 files changed, 45 insertions(+), 12 deletions(-)

-- 
2.31.0



From lorenzo.pieralisi at arm.com  Mon Aug  2 08:23:58 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon,  2 Aug 2021 16:23:58 +0100
Subject: [PATCH v2 2/3] ACPI: osl: Reorder acpi_os_map_iomem() __ref annotation
In-Reply-To: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
Message-ID: <20210802152359.12623-3-lorenzo.pieralisi@arm.com>

The __ref annotation has nothing to do with the acpi_os_map_iomem()
return value type.

Redefine the acpi_os_map_iomem() function prototype to avoid mixing the
__ref annotation with the return type declaration.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
---
 drivers/acpi/osl.c     | 4 ++--
 include/acpi/acpi_io.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 8f67bf0f090b..fdee0c6f4f7f 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -321,8 +321,8 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
  * During early init (when acpi_permanent_mmap has not been set yet) this
  * routine simply calls __acpi_map_table() to get the job done.
  */
-void __iomem __ref
-*acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
+void __iomem *__ref
+acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
 {
 	struct acpi_ioremap *map;
 	void __iomem *virt;
diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
index 027faa8883aa..a0094420303f 100644
--- a/include/acpi/acpi_io.h
+++ b/include/acpi/acpi_io.h
@@ -16,8 +16,8 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
 
 extern bool acpi_permanent_mmap;
 
-void __iomem __ref
-*acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
+void __iomem *__ref
+acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
 void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size);
 void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
 
-- 
2.31.0



From lorenzo.pieralisi at arm.com  Mon Aug  2 08:23:59 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon,  2 Aug 2021 16:23:59 +0100
Subject: [PATCH v2 3/3] ACPI: Add memory semantics to acpi_os_map_memory()
In-Reply-To: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
Message-ID: <20210802152359.12623-4-lorenzo.pieralisi@arm.com>

The memory attributes attached to memory regions depend on architecture
specific mappings.

For some memory regions, the attributes specified by firmware (eg
uncached) are not sufficient to determine how a memory region should be
mapped by an OS (for instance a region that is define as uncached in
firmware can be mapped as Normal or Device memory on arm64) and
therefore the OS must be given control on how to map the region to match
the expected mapping behaviour (eg if a mapping is requested with memory
semantics, it must allow unaligned accesses).

Rework acpi_os_map_memory() and acpi_os_ioremap() back-end to split
them into two separate code paths:

acpi_os_memmap() -> memory semantics
acpi_os_ioremap() -> MMIO semantics

The split allows the architectural implementation back-ends to detect
the default memory attributes required by the mapping in question
(ie the mapping API defines the semantics memory vs MMIO) and map the
memory accordingly.

Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702 at arm.com
Tested-by: Hanjun Guo <guohanjun at huawei.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Will Deacon <will at kernel.org>
Cc: Hanjun Guo <guohanjun at huawei.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
---
 arch/arm64/include/asm/acpi.h |  3 +++
 arch/arm64/kernel/acpi.c      | 19 ++++++++++++++++---
 drivers/acpi/osl.c            | 23 ++++++++++++++++-------
 include/acpi/acpi_io.h        |  8 ++++++++
 4 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index bd68e1b7f29f..7535dc7cc5aa 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -50,6 +50,9 @@ pgprot_t __acpi_get_mem_attribute(phys_addr_t addr);
 void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size);
 #define acpi_os_ioremap acpi_os_ioremap
 
+void __iomem *acpi_os_memmap(acpi_physical_address phys, acpi_size size);
+#define acpi_os_memmap acpi_os_memmap
+
 typedef u64 phys_cpuid_t;
 #define PHYS_CPUID_INVALID INVALID_HWID
 
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index f3851724fe35..1c9c2f7a1c04 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -273,7 +273,8 @@ pgprot_t __acpi_get_mem_attribute(phys_addr_t addr)
 	return __pgprot(PROT_DEVICE_nGnRnE);
 }
 
-void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+static void __iomem *__acpi_os_ioremap(acpi_physical_address phys,
+				       acpi_size size, bool memory)
 {
 	efi_memory_desc_t *md, *region = NULL;
 	pgprot_t prot;
@@ -299,9 +300,11 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
 	 * It is fine for AML to remap regions that are not represented in the
 	 * EFI memory map at all, as it only describes normal memory, and MMIO
 	 * regions that require a virtual mapping to make them accessible to
-	 * the EFI runtime services.
+	 * the EFI runtime services. Determine the region default
+	 * attributes by checking the requested memory semantics.
 	 */
-	prot = __pgprot(PROT_DEVICE_nGnRnE);
+	prot = memory ? __pgprot(PROT_NORMAL_NC) :
+			__pgprot(PROT_DEVICE_nGnRnE);
 	if (region) {
 		switch (region->type) {
 		case EFI_LOADER_CODE:
@@ -361,6 +364,16 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
 	return __ioremap(phys, size, prot);
 }
 
+void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+{
+	return __acpi_os_ioremap(phys, size, false);
+}
+
+void __iomem *acpi_os_memmap(acpi_physical_address phys, acpi_size size)
+{
+	return __acpi_os_ioremap(phys, size, true);
+}
+
 /*
  * Claim Synchronous External Aborts as a firmware first notification.
  *
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index fdee0c6f4f7f..2fcd3bb9a3c1 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -284,7 +284,8 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
 #define should_use_kmap(pfn)   page_is_ram(pfn)
 #endif
 
-static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
+static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz,
+			      bool memory)
 {
 	unsigned long pfn;
 
@@ -294,7 +295,8 @@ static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
 			return NULL;
 		return (void __iomem __force *)kmap(pfn_to_page(pfn));
 	} else
-		return acpi_os_ioremap(pg_off, pg_sz);
+		return memory ? acpi_os_memmap(pg_off, pg_sz) :
+				acpi_os_ioremap(pg_off, pg_sz);
 }
 
 static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
@@ -309,9 +311,10 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
 }
 
 /**
- * acpi_os_map_iomem - Get a virtual address for a given physical address range.
+ * __acpi_os_map_iomem - Get a virtual address for a given physical address range.
  * @phys: Start of the physical address range to map.
  * @size: Size of the physical address range to map.
+ * @memory: true if remapping memory, false if IO
  *
  * Look up the given physical address range in the list of existing ACPI memory
  * mappings.  If found, get a reference to it and return a pointer to it (its
@@ -321,8 +324,8 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
  * During early init (when acpi_permanent_mmap has not been set yet) this
  * routine simply calls __acpi_map_table() to get the job done.
  */
-void __iomem *__ref
-acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
+static void __iomem *__ref
+__acpi_os_map_iomem(acpi_physical_address phys, acpi_size size, bool memory)
 {
 	struct acpi_ioremap *map;
 	void __iomem *virt;
@@ -353,7 +356,7 @@ acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
 
 	pg_off = round_down(phys, PAGE_SIZE);
 	pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
-	virt = acpi_map(phys, size);
+	virt = acpi_map(phys, size, memory);
 	if (!virt) {
 		mutex_unlock(&acpi_ioremap_lock);
 		kfree(map);
@@ -372,11 +375,17 @@ acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
 	mutex_unlock(&acpi_ioremap_lock);
 	return map->virt + (phys - map->phys);
 }
+
+void __iomem *__ref
+acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
+{
+	return __acpi_os_map_iomem(phys, size, false);
+}
 EXPORT_SYMBOL_GPL(acpi_os_map_iomem);
 
 void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
-	return (__force void *)acpi_os_map_iomem(phys, size);
+	return (__force void *)__acpi_os_map_iomem(phys, size, true);
 }
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
index a0094420303f..b69a2a1c144c 100644
--- a/include/acpi/acpi_io.h
+++ b/include/acpi/acpi_io.h
@@ -14,6 +14,14 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
 }
 #endif
 
+#ifndef acpi_os_memmap
+static inline void __iomem *acpi_os_memmap(acpi_physical_address phys,
+					    acpi_size size)
+{
+	return ioremap_cache(phys, size);
+}
+#endif
+
 extern bool acpi_permanent_mmap;
 
 void __iomem *__ref
-- 
2.31.0



From alexdeucher at gmail.com  Mon Aug  2 08:27:18 2021
From: alexdeucher at gmail.com (Alex Deucher)
Date: Mon, 2 Aug 2021 11:27:18 -0400
Subject: [PATCH 09/14] drm/radeon: Convert to Linux IRQ interfaces
In-Reply-To: <20210727182721.17981-10-tzimmermann@suse.de>
References: <20210727182721.17981-1-tzimmermann@suse.de>
 <20210727182721.17981-10-tzimmermann@suse.de>
Message-ID: <CADnq5_O+ahz4_rgc5gGv=ZJ+vj21s2=6Y2wSkSoC7j55CP_LHQ@mail.gmail.com>

On Tue, Jul 27, 2021 at 2:27 PM Thomas Zimmermann <tzimmermann at suse.de> wrote:
>
> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> don't benefit from using it.
>
> DRM IRQ callbacks are now being called directly or inlined.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  drivers/gpu/drm/radeon/radeon_drv.c     |  4 ---
>  drivers/gpu/drm/radeon/radeon_irq_kms.c | 44 +++++++++++++++++++++----
>  drivers/gpu/drm/radeon/radeon_kms.h     |  4 ---
>  3 files changed, 37 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
> index c8dd68152d65..b74cebca1f89 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -607,10 +607,6 @@ static const struct drm_driver kms_driver = {
>         .postclose = radeon_driver_postclose_kms,
>         .lastclose = radeon_driver_lastclose_kms,
>         .unload = radeon_driver_unload_kms,
> -       .irq_preinstall = radeon_driver_irq_preinstall_kms,
> -       .irq_postinstall = radeon_driver_irq_postinstall_kms,
> -       .irq_uninstall = radeon_driver_irq_uninstall_kms,
> -       .irq_handler = radeon_driver_irq_handler_kms,
>         .ioctls = radeon_ioctls_kms,
>         .num_ioctls = ARRAY_SIZE(radeon_ioctls_kms),
>         .dumb_create = radeon_mode_dumb_create,
> diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
> index a36ce826d0c0..3907785d0798 100644
> --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
> +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
> @@ -31,7 +31,7 @@
>
>  #include <drm/drm_crtc_helper.h>
>  #include <drm/drm_device.h>
> -#include <drm/drm_irq.h>
> +#include <drm/drm_drv.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_vblank.h>
>  #include <drm/radeon_drm.h>
> @@ -51,7 +51,7 @@
>   * radeon_irq_process is a macro that points to the per-asic
>   * irq handler callback.
>   */
> -irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg)
> +static irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg)
>  {
>         struct drm_device *dev = (struct drm_device *) arg;
>         struct radeon_device *rdev = dev->dev_private;
> @@ -118,7 +118,7 @@ static void radeon_dp_work_func(struct work_struct *work)
>   * Gets the hw ready to enable irqs (all asics).
>   * This function disables all interrupt sources on the GPU.
>   */
> -void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
> +static void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
>  {
>         struct radeon_device *rdev = dev->dev_private;
>         unsigned long irqflags;
> @@ -150,7 +150,7 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
>   * Handles stuff to be done after enabling irqs (all asics).
>   * Returns 0 on success.
>   */
> -int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
> +static int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
>  {
>         struct radeon_device *rdev = dev->dev_private;
>
> @@ -169,7 +169,7 @@ int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
>   *
>   * This function disables all interrupt sources on the GPU (all asics).
>   */
> -void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
> +static void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
>  {
>         struct radeon_device *rdev = dev->dev_private;
>         unsigned long irqflags;
> @@ -194,6 +194,36 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
>         spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
>  }
>
> +static int radeon_irq_install(struct radeon_device *rdev, int irq)
> +{
> +       struct drm_device *dev = rdev->ddev;
> +       int ret;
> +
> +       if (irq == IRQ_NOTCONNECTED)
> +               return -ENOTCONN;
> +
> +       radeon_driver_irq_preinstall_kms(dev);
> +
> +       /* PCI devices require shared interrupts. */
> +       ret = request_irq(irq, radeon_driver_irq_handler_kms,
> +                         IRQF_SHARED, dev->driver->name, dev);
> +       if (ret)
> +               return ret;
> +
> +       radeon_driver_irq_postinstall_kms(dev);
> +
> +       return 0;
> +}
> +
> +static void radeon_irq_uninstall(struct radeon_device *rdev)
> +{
> +       struct drm_device *dev = rdev->ddev;
> +       struct pci_dev *pdev = to_pci_dev(dev->dev);
> +
> +       radeon_driver_irq_uninstall_kms(dev);
> +       free_irq(pdev->irq, dev);
> +}
> +
>  /**
>   * radeon_msi_ok - asic specific msi checks
>   *
> @@ -314,7 +344,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
>         INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
>
>         rdev->irq.installed = true;
> -       r = drm_irq_install(rdev->ddev, rdev->pdev->irq);
> +       r = radeon_irq_install(rdev, rdev->pdev->irq);
>         if (r) {
>                 rdev->irq.installed = false;
>                 flush_delayed_work(&rdev->hotplug_work);
> @@ -335,7 +365,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
>  void radeon_irq_kms_fini(struct radeon_device *rdev)
>  {
>         if (rdev->irq.installed) {
> -               drm_irq_uninstall(rdev->ddev);
> +               radeon_irq_uninstall(rdev);
>                 rdev->irq.installed = false;
>                 if (rdev->msi_enabled)
>                         pci_disable_msi(rdev->pdev);
> diff --git a/drivers/gpu/drm/radeon/radeon_kms.h b/drivers/gpu/drm/radeon/radeon_kms.h
> index 9b97bf38acd4..36e73cea9215 100644
> --- a/drivers/gpu/drm/radeon/radeon_kms.h
> +++ b/drivers/gpu/drm/radeon/radeon_kms.h
> @@ -31,9 +31,5 @@
>  u32 radeon_get_vblank_counter_kms(struct drm_crtc *crtc);
>  int radeon_enable_vblank_kms(struct drm_crtc *crtc);
>  void radeon_disable_vblank_kms(struct drm_crtc *crtc);
> -irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg);
> -void radeon_driver_irq_preinstall_kms(struct drm_device *dev);
> -int radeon_driver_irq_postinstall_kms(struct drm_device *dev);
> -void radeon_driver_irq_uninstall_kms(struct drm_device *dev);
>
>  #endif                         /* __RADEON_KMS_H__ */
> --
> 2.32.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


From u.kleine-koenig at pengutronix.de  Mon Aug  2 08:27:55 2021
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Mon, 2 Aug 2021 17:27:55 +0200
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <20210802094810.GJ22278@shell.armlinux.org.uk>
References: <20210722081817.2tsjzof4gvldq6ka@pengutronix.de>
 <YPlfcbkxiBmB+vw1@kunai>
 <CAHp75VfC=s12Unw3+Cn0ag71mM5i90=Jbwj4nYwB5cPKiUTRSA@mail.gmail.com>
 <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
 <20210802094810.GJ22278@shell.armlinux.org.uk>
Message-ID: <20210802152755.ibisunvibmwhiyry@pengutronix.de>

Hello Russell,

On Mon, Aug 02, 2021 at 10:48:10AM +0100, Russell King (Oracle) wrote:
> On Sat, Jul 31, 2021 at 02:00:04PM +0200, Uwe Kleine-K?nig wrote:
> > Hi Russell, hi Stephen,
> > 
> > On Sat, Jul 31, 2021 at 12:41:19AM -0700, Stephen Boyd wrote:
> > > +1 This patch doesn't fall under CCF maintainer.
> > 
> > Given that CCF is the only implementer of devm_clk_get at least an Ack
> > from your side would still be good I guess?
> 
> I think devm_clk_get() should not be part of CCF but should be
> part of the interface level - it's silly to have devm_clk_get()
> being CCF but not clk_get(). The same should go for the other
> devm wrappers around the plain clk_* interfaces.

What is the practical difference between "Function X is part of CCF" and
"Function X is part of the clk interface and there is only CCF who
implements it"?

> > I found a patch set adding devm variants of clk_enable (e.g.
> > https://lore.kernel.org/patchwork/patch/755667/) but this approach is
> > different as it also contains clk_get which IMHO makes more sense 
> > The discussion considered wrapping get+enable at one point, but I didn't
> > find a followup.
> 
> There have been several different approaches to wrapping things up,
> but here's a question: should we make it easier to do the lazy thing
> (get+enable) or should we make it easier to be power efficient?
> Shouldn't we be encouraging people to write power efficient drivers?

Yeah, sounds compelling, but I wonder if that's of practical importance.
How many driver authors do you expect to lure into making a better
driver just because devm_clk_get_prepared() doesn't exist? In contrast:
How many drivers become simpler with devm_clk_get_prepared() and so
it becomes easier to maintain them and easier to spot bugs?
In the absence of devm_clk_get_prepared(), is it better that several
frameworks (or drivers) open code it?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/404edd5e/attachment.sig>

From catalin.marinas at arm.com  Mon Aug  2 08:30:37 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 16:30:37 +0100
Subject: [PATCH v3 1/1] arm64/cpufeature: Optionally disable MTE via
 command-line
In-Reply-To: <20210730144957.30938-2-yee.lee@mediatek.com>
References: <20210730144957.30938-1-yee.lee@mediatek.com>
 <20210730144957.30938-2-yee.lee@mediatek.com>
Message-ID: <20210802153036.GH18685@arm.com>

On Fri, Jul 30, 2021 at 10:49:53PM +0800, yee.lee at mediatek.com wrote:
> From: Yee Lee <yee.lee at mediatek.com>
> 
> For some low-end devices with limited resources,
> MTE needs to be optionally disabled to save system
> costs such as tag memory and firmware controls.

I understand the cost of using MTE but I don't fully get what you mean
by firmware controls. If the ID_AA64PFR1_EL1.MTE reports that MTE is
present, the firmware should have initialised MTE correctly (e.g. tag
allocation storage, SCR_EL3.ATA) and not rely on a kernel command line
argument that may or may not be present.

> This allows ID_AA64PFR1_EL1.MTE to be overridden on 
> its shadow value by giving "arm64.nomte" on cmdline,
> and to suppress MTE feature.
> 
> Suggested-by: Marc Zyngier <maz at kernel.org>
> Suggested-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Yee Lee <yee.lee at mediatek.com>

While this patch appears to disable MTE, I don't think it can fully
prevent the access to the allocation tag storage, so the firmware must
still initialise it correctly.

The issue is that __cpu_setup already configures the MAIR_EL1 register
to use Normal Tagged memory for the kernel mapping and SCTLR_EL1.ATA is
set. The TCF field is zero, so no tag checking, but I couldn't figure
out from the ARM ARM whether this also prevents LDR/STR from attempting
to fetch the allocation tags. I think it's only the ATA bit and the MAIR
configuration.

With this patch, KASAN_HW_TAGS (if configured) won't be used and MTE
will not be presented to user applications, if that's what you want, but
does not fully disable MTE.

Since May this year, the ARM ARM was updated so that SCTLR_EL1.ATA/ATA0
are not permitted to be cached in the TLB. We could therefore move the
setting to cpu_enable_mte(). Something like below, untested (to be
folded into your patch):

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index aa53954c2f6b..cac23455a2b5 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -698,8 +698,7 @@
 	(SCTLR_ELx_M    | SCTLR_ELx_C    | SCTLR_ELx_SA   | SCTLR_EL1_SA0   | \
 	 SCTLR_EL1_SED  | SCTLR_ELx_I    | SCTLR_EL1_DZE  | SCTLR_EL1_UCT   | \
 	 SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN | SCTLR_ELx_ITFSB | \
-	 SCTLR_ELx_ATA  | SCTLR_EL1_ATA0 | ENDIAN_SET_EL1 | SCTLR_EL1_UCI   | \
-	 SCTLR_EL1_EPAN | SCTLR_EL1_RES1)
+	 ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_EPAN | SCTLR_EL1_RES1)

 /* MAIR_ELx memory attributes (used by Linux) */
 #define MAIR_ATTR_DEVICE_nGnRnE		UL(0x00)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9035c367d08b..23b1e3d83603 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1841,6 +1841,9 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused)
 #ifdef CONFIG_ARM64_MTE
 static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
 {
+	sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0);
+	isb();
+
 	/*
 	 * Clear the tags in the zero page. This needs to be done via the
 	 * linear map which has the Tagged attribute.

-- 
Catalin


From dqfext at gmail.com  Mon Aug  2 08:31:29 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Mon,  2 Aug 2021 23:31:29 +0800
Subject: [RFC net-next v2 3/4] net: dsa: mt7530: set STP state also on
 filter ID 1
In-Reply-To: <20210802134336.gv66le6u2z52kfkh@skbuf>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-4-dqfext@gmail.com>
 <20210802134336.gv66le6u2z52kfkh@skbuf>
Message-ID: <20210802153129.1817825-1-dqfext@gmail.com>

On Mon, Aug 02, 2021 at 04:43:36PM +0300, Vladimir Oltean wrote:
> On Sun, Aug 01, 2021 at 03:10:21AM +0800, DENG Qingfang wrote:
> > --- a/drivers/net/dsa/mt7530.h
> > +++ b/drivers/net/dsa/mt7530.h
> > @@ -181,7 +181,7 @@ enum mt7530_vlan_egress_attr {
> >  
> >  /* Register for port STP state control */
> >  #define MT7530_SSP_P(x)			(0x2000 + ((x) * 0x100))
> > -#define  FID_PST(x)			((x) & 0x3)
> 
> Shouldn't these macros have _two_ arguments, the FID and the port state?
> 
> > +#define  FID_PST(x)			(((x) & 0x3) * 0x5)
> 
> "* 5": explanation?
> 
> >  #define  FID_PST_MASK			FID_PST(0x3)
> >  
> >  enum mt7530_stp_state {
> > -- 
> > 2.25.1
> > 
> 
> I don't exactly understand how this patch works, sorry.
> Are you altering port state only on bridged ports, or also on standalone
> ports after this patch? Are standalone ports in the proper STP state
> (FORWARDING)?

The current code only sets FID 0's STP state. This patch sets both 0's and
1's states.

The *5 part is binary magic. [1:0] is FID 0's state, [3:2] is FID 1's state
and so on. Since 5 == 4'b0101, the value in [1:0] is copied to [3:2] after
the multiplication.

Perhaps I should only change FID 1's state.



From rppt at kernel.org  Mon Aug  2 08:37:00 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 2 Aug 2021 18:37:00 +0300
Subject: [PATCH v2] memblock: make memblock_find_in_range method private
In-Reply-To: <CAL_Jsq+i17C=+9bg=XPattuHe+M8NE3B29+FCg4p3-bPDgSaKw@mail.gmail.com>
References: <20210802063737.22733-1-rppt@kernel.org>
 <CAL_Jsq+i17C=+9bg=XPattuHe+M8NE3B29+FCg4p3-bPDgSaKw@mail.gmail.com>
Message-ID: <YQgRHNLt+8Swein9@kernel.org>

Hi Rob,

On Mon, Aug 02, 2021 at 08:55:57AM -0600, Rob Herring wrote:
> On Mon, Aug 2, 2021 at 12:37 AM Mike Rapoport <rppt at kernel.org> wrote:
> >
> > From: Mike Rapoport <rppt at linux.ibm.com>
> >
> > There are a lot of uses of memblock_find_in_range() along with
> > memblock_reserve() from the times memblock allocation APIs did not exist.
> >
> > memblock_find_in_range() is the very core of memblock allocations, so any
> > future changes to its internal behaviour would mandate updates of all the
> > users outside memblock.
> >
> > Replace the calls to memblock_find_in_range() with an equivalent calls to
> > memblock_phys_alloc() and memblock_phys_alloc_range() and make
> > memblock_find_in_range() private method of memblock.
> >
> > This simplifies the callers, ensures that (unlikely) errors in
> > memblock_reserve() are handled and improves maintainability of
> > memblock_find_in_range().
> >
> > Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
> > ---
> > v2: don't change error message in arm::reserve_crashkernel(), per Russell
> > v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org
> >
> >  arch/arm/kernel/setup.c           | 18 +++++--------
> >  arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
> >  arch/arm64/mm/init.c              | 36 ++++++++-----------------
> >  arch/mips/kernel/setup.c          | 14 +++++-----
> >  arch/riscv/mm/init.c              | 44 ++++++++++---------------------
> >  arch/s390/kernel/setup.c          | 10 ++++---
> >  arch/x86/kernel/aperture_64.c     |  5 ++--
> >  arch/x86/mm/init.c                | 21 +++++++++------
> >  arch/x86/mm/numa.c                |  5 ++--
> >  arch/x86/mm/numa_emulation.c      |  5 ++--
> >  arch/x86/realmode/init.c          |  2 +-
> >  drivers/acpi/tables.c             |  5 ++--
> >  drivers/base/arch_numa.c          |  5 +---
> >  drivers/of/of_reserved_mem.c      | 12 ++++++---
> >  include/linux/memblock.h          |  2 --
> >  mm/memblock.c                     |  2 +-
> >  16 files changed, 78 insertions(+), 117 deletions(-)
> >
> > diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> > index f97eb2371672..67f5421b2af7 100644
> > --- a/arch/arm/kernel/setup.c
> > +++ b/arch/arm/kernel/setup.c
> > @@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
> >                 unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
> >                 if (crash_max > lowmem_max)
> >                         crash_max = lowmem_max;
> > -               crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
> > -                                                   crash_size, CRASH_ALIGN);
> > +
> > +               crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> > +                                                      CRASH_ALIGN, crash_max);
> >                 if (!crash_base) {
> >                         pr_err("crashkernel reservation failed - No suitable area found.\n");
> >                         return;
> >                 }
> >         } else {
> > +               unsigned long long crash_max = crash_base + crash_size;
> >                 unsigned long long start;
> >
> > -               start = memblock_find_in_range(crash_base,
> > -                                              crash_base + crash_size,
> > -                                              crash_size, SECTION_SIZE);
> > +               start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
> > +                                                 crash_base, crash_max);
> >                 if (start != crash_base) {
> 
> If this is true and start is non-zero, then you need an
> memblock_free(). However, since the range is equal to the size, then
> that can never happen and just checking !start is sufficient.

Agree. Will update.
 
> >                         pr_err("crashkernel reservation failed - memory is in use.\n");
> >                         return;
> >                 }
> >         }
> >
> > -       ret = memblock_reserve(crash_base, crash_size);
> > -       if (ret < 0) {
> > -               pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
> > -                       (unsigned long)crash_base);
> > -               return;
> > -       }
> > -
> >         pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
> >                 (unsigned long)(crash_size >> 20),
> >                 (unsigned long)(crash_base >> 20),
> > diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c
> > index d654921dd09b..578670e3f608 100644
> > --- a/arch/arm64/kvm/hyp/reserved_mem.c
> > +++ b/arch/arm64/kvm/hyp/reserved_mem.c
> > @@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
> >          * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
> >          */
> >         hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
> > -       hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> > -                                             ALIGN(hyp_mem_size, PMD_SIZE),
> > -                                             PMD_SIZE);
> > +       hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
> > +                                          PMD_SIZE);
> >         if (!hyp_mem_base)
> > -               hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> > -                                                     hyp_mem_size, PAGE_SIZE);
> > +               hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
> >         else
> >                 hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
> >
> > @@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
> >                 kvm_err("Failed to reserve hyp memory\n");
> >                 return;
> >         }
> > -       memblock_reserve(hyp_mem_base, hyp_mem_size);
> >
> >         kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
> >                  hyp_mem_base);
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index 8490ed2917ff..d566478a06dd 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
> >  static void __init reserve_crashkernel(void)
> >  {
> >         unsigned long long crash_base, crash_size;
> > +       unsigned long crash_max = arm64_dma_phys_limit;
> 
> It all works out to the same size, but it doesn't make sense that
> crash_base and crash_size are long long and crash_max is long.

Indeed, thanks.
 
> >         int ret;
> >
> >         ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> > @@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
> >
> >         crash_size = PAGE_ALIGN(crash_size);
> >
> > -       if (crash_base == 0) {
> > -               /* Current arm64 boot protocol requires 2MB alignment */
> > -               crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
> > -                               crash_size, SZ_2M);
> > -               if (crash_base == 0) {
> > -                       pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> > -                               crash_size);
> > -                       return;
> > -               }
> > -       } else {
> > -               /* User specifies base address explicitly. */
> > -               if (!memblock_is_region_memory(crash_base, crash_size)) {
> > -                       pr_warn("cannot reserve crashkernel: region is not memory\n");
> > -                       return;
> > -               }
> > +       /* User specifies base address explicitly. */
> > +       if (crash_base)
> > +               crash_max = crash_base + crash_size;
> >
> > -               if (memblock_is_region_reserved(crash_base, crash_size)) {
> > -                       pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
> > -                       return;
> > -               }
> > -
> > -               if (!IS_ALIGNED(crash_base, SZ_2M)) {
> > -                       pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
> > -                       return;
> 
> We've lost the alignment check.
> 
> Perhaps memblock_phys_alloc_range() should check that the start
> matches the alignment. That would simplify the return handling as it
> seems NULL is not the only error case.

We only lost pr_warn() about the alignment check. When crash_base != 0, we
are trying to allocate the exact [base, base + size) region aligned at 2M.
If it is free we get the address, if not we get 0.
 
> > -               }
> > +       /* Current arm64 boot protocol requires 2MB alignment */
> > +       crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> > +                                              crash_base, crash_max);
> > +       if (!crash_base) {
> > +               pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> > +                       crash_size);
> > +               return;
> >         }
> > -       memblock_reserve(crash_base, crash_size);
> >
> >         pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
> >                 crash_base, crash_base + crash_size, crash_size >> 20);
> 
> [...]
> 
> > diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
> > index 6534c92d0f83..31b5856010cb 100644
> > --- a/arch/x86/realmode/init.c
> > +++ b/arch/x86/realmode/init.c
> > @@ -28,7 +28,7 @@ void __init reserve_real_mode(void)
> >         WARN_ON(slab_is_available());
> >
> >         /* Has to be under 1M so we can execute real-mode AP code. */
> > -       mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
> > +       mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
> >         if (!mem)
> >                 pr_info("No sub-1M memory is available for the trampoline\n");
> >         else
> 
> Don't you need to drop the memblock_reserve() after this?

Nope, it reserves the entire first 1M, which is more than we allocated
here. The call to memblock_reserve() in memblock_phys_alloc_range() will be
redundant here, but IMHO it's clearer this way.

-- 
Sincerely yours,
Mike.


From Dave.Martin at arm.com  Mon Aug  2 08:36:15 2021
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 2 Aug 2021 16:36:15 +0100
Subject: [PATCH v3 3/4] kselftest/arm64: Add tests for SVE vector
 configuration
In-Reply-To: <20210802141939.GF4668@sirena.org.uk>
References: <20210729151518.46388-1-broonie@kernel.org>
 <20210729151518.46388-4-broonie@kernel.org>
 <20210729160642.GP1724@arm.com>
 <20210729173411.GT4670@sirena.org.uk>
 <20210802102517.GA25258@arm.com>
 <20210802113330.GD4668@sirena.org.uk>
 <20210802123749.GB25258@arm.com>
 <20210802141939.GF4668@sirena.org.uk>
Message-ID: <20210802153614.GC25258@arm.com>

On Mon, Aug 02, 2021 at 03:19:39PM +0100, Mark Brown wrote:
> On Mon, Aug 02, 2021 at 01:37:50PM +0100, Dave Martin wrote:
> > On Mon, Aug 02, 2021 at 12:33:30PM +0100, Mark Brown wrote:
> 
> > > That really doesn't seem like a good idea - it's just asking for
> > > fragility if a signal gets delivered to the parent process or something.
> > > Even if almost all the time there will only be one trip through the loop
> > > we should still have the loop there for those few cases where it
> > > triggers.
> 
> > This concern only applies when the program actually registers signal
> > handlers.
> 
> > wait() can't return for any other reason, and it mustn't, precisely
> > because historically software would have made this assumption.  This is
> > one reason why wait3() etc. are separate functions.
> 
> That's great for the reader with a detailed knowledge of exactly what
> error handling can be skipped and how standards conforming Linux is but
> less good for the reader who is merely aware of best practices.  I am
> not clear what the problem that is solved by removing the loop here is
> TBH - to me it just makes it less obvious that we've handled everything.

Ok, leave it as is then.

(It would be good to collect some best-practice guidance on how to
actually use syscalls, but that's clearly way out of scope here...)

> > That aside though, can't we use popen(3)?
> 
> > I tend to forget about popen because it is "boring" to use it, but it
> > looks like it fits this case quite well.  Then it would be libc's
> > problem how to fork and wait safely.
> 
> popen() appears to be break the _SET_VL_ONEXEC test.  Between a lack of
> strace in my test filesystem and not spotting anything obvious in the
> glibc sources I can't tell exactly where it's doing something different,
> though it does feel like it should be a separate testcase if it's
> anything interesting.  I do think there is value in having exactly
> what's done to start the child process be clear in the test program, and
> that coverage of anything interesting from popen() could be done
> incrementally.

Ah, dang, popen() will run the target program via a shell, so there will
actually be two fork-exec()s, with the VL being reset to default by the
second exec.

Using PR_SET_SET_VL with popen() still makes sense, but if you want the
target program to get the new VL (not just the shell) then you'd need
PR_SVE_VL_INHERIT.  Then we would get confused later when trying to
test the !PR_SVE_VL_INHERIT case.  The way to "fix" this would be to
have the shell invoke something like vlset, but that will blur the test
in a different way, adding even more confusion.

So Ack, we can't test all the variations using the popen() method, so we
probably shouldn't use it here at all.  

This is the kind of reason why I tend not to go for it, I guess --
it looks convenient, but it's just that little bit overcooked as an API.
*sigh*


I'll review your final version of the series, but I guess we're all good.

Cheers
---Dave


From ardb at kernel.org  Mon Aug  2 08:37:40 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 2 Aug 2021 17:37:40 +0200
Subject: [PATCH v2 0/3] ACPI: Fix acpi_os_map_memory() memory semantics
In-Reply-To: <20210802152359.12623-1-lorenzo.pieralisi@arm.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-1-lorenzo.pieralisi@arm.com>
Message-ID: <CAMj1kXEyk5xfJsCy=KMuM2cVFR93zkCKBZjUzyiONDR9+Q4EBQ@mail.gmail.com>

On Mon, 2 Aug 2021 at 17:24, Lorenzo Pieralisi
<lorenzo.pieralisi at arm.com> wrote:
>
> Patch series is a v2 of a previous version[1]:
>
> v1->v2
>         - Added patch 1 and 2 according to feedback received on[1]
>
> [1] https://lore.kernel.org/linux-acpi/20210726100026.12538-1-lorenzo.pieralisi at arm.com
>
> Lorenzo Pieralisi (3):
>   ACPI: osl: Add __force attribute in acpi_os_map_iomem() cast
>   ACPI: osl: Reorder acpi_os_map_iomem() __ref annotation
>   ACPI: Add memory semantics to acpi_os_map_memory()
>

For the series,

Acked-by: Ard Biesheuvel <ardb at kernel.org>

>  arch/arm64/include/asm/acpi.h |  3 +++
>  arch/arm64/kernel/acpi.c      | 19 ++++++++++++++++---
>  drivers/acpi/osl.c            | 23 ++++++++++++++++-------
>  include/acpi/acpi_io.h        | 12 ++++++++++--
>  4 files changed, 45 insertions(+), 12 deletions(-)
>
> --
> 2.31.0
>


From leo.yan at linaro.org  Mon Aug  2 08:41:45 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 2 Aug 2021 23:41:45 +0800
Subject: [RFC PATCH 6/6] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <20210729155805.2830-7-james.clark@arm.com>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-7-james.clark@arm.com>
Message-ID: <20210802154145.GC148327@leoy-ThinkPad-X240s>

On Thu, Jul 29, 2021 at 04:58:05PM +0100, James Clark wrote:
> Currently decode will silently fail if no binary data is available for
> the decode. This is made worse if only partial data is available because
> the decode will appear to work, but any trace from that missing DSO will
> silently not be generated.
> 
> Add a UI popup once if there is any data missing, and then warn in the
> bottom left for each individual DSO that's missing.
> 
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  tools/perf/util/cs-etm.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index 32ad92d3e454..e6851260d059 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -746,8 +746,16 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
>  
>  	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
>  
> -	if (len <= 0)
> +	if (len <= 0) {
> +		ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n");
> +		if (!al.map->dso->auxtrace_warned) {
> +			pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
> +				    address,
> +				    al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
> +			al.map->dso->auxtrace_warned = true;
> +		}

This is very useful.

Just one comment: in particularly if the perf fails to find the kernel
symbols, the user needs to enable config "CONFIG_PROC_KCORE=y" or
specify option "-k /path/to/vmlinux".  In this case, using 'perf
archive' is not helpful.  So I think the UI warning can be imporved
like:

        ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n"
                         " Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols\n");

With this improvement, the patch looks good to me:

Reviewed-by: Leo Yan <leo.yan at linaro.org>

>  		return 0;
> +	}
>  
>  	return len;
>  }
> -- 
> 2.28.0
> 


From olteanv at gmail.com  Mon Aug  2 08:42:26 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 2 Aug 2021 18:42:26 +0300
Subject: [RFC net-next v2 3/4] net: dsa: mt7530: set STP state also on
 filter ID 1
In-Reply-To: <20210802153129.1817825-1-dqfext@gmail.com>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-4-dqfext@gmail.com>
 <20210802134336.gv66le6u2z52kfkh@skbuf>
 <20210802153129.1817825-1-dqfext@gmail.com>
Message-ID: <20210802154226.qggqzkxe6urkx3yf@skbuf>

On Mon, Aug 02, 2021 at 11:31:29PM +0800, DENG Qingfang wrote:
> On Mon, Aug 02, 2021 at 04:43:36PM +0300, Vladimir Oltean wrote:
> > On Sun, Aug 01, 2021 at 03:10:21AM +0800, DENG Qingfang wrote:
> > > --- a/drivers/net/dsa/mt7530.h
> > > +++ b/drivers/net/dsa/mt7530.h
> > > @@ -181,7 +181,7 @@ enum mt7530_vlan_egress_attr {
> > >
> > >  /* Register for port STP state control */
> > >  #define MT7530_SSP_P(x)			(0x2000 + ((x) * 0x100))
> > > -#define  FID_PST(x)			((x) & 0x3)
> >
> > Shouldn't these macros have _two_ arguments, the FID and the port state?
> >
> > > +#define  FID_PST(x)			(((x) & 0x3) * 0x5)
> >
> > "* 5": explanation?
> >
> > >  #define  FID_PST_MASK			FID_PST(0x3)
> > >
> > >  enum mt7530_stp_state {
> > > --
> > > 2.25.1
> > >
> >
> > I don't exactly understand how this patch works, sorry.
> > Are you altering port state only on bridged ports, or also on standalone
> > ports after this patch? Are standalone ports in the proper STP state
> > (FORWARDING)?
>
> The current code only sets FID 0's STP state. This patch sets both 0's and
> 1's states.
>
> The *5 part is binary magic. [1:0] is FID 0's state, [3:2] is FID 1's state
> and so on. Since 5 == 4'b0101, the value in [1:0] is copied to [3:2] after
> the multiplication.
>
> Perhaps I should only change FID 1's state.

Keep the patches dumb for us mortals please.
If you only change FID 1's state, I am concerned that the driver no
longer initializes FID 0's port state, and might leave that to the
default set by other pre-kernel initialization stage (bootloader?).
So even if you might assume that standalone ports are FORWARDING, they
might not be.


From will at kernel.org  Mon Aug  2 08:43:08 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Aug 2021 16:43:08 +0100
Subject: [PATCHv3] iommu/arm-smmu: Optimize ->tlb_flush_walk() for qcom
 implementation
In-Reply-To: <20210623134201.16140-1-saiprakash.ranjan@codeaurora.org>
References: <20210623134201.16140-1-saiprakash.ranjan@codeaurora.org>
Message-ID: <20210802154308.GG28735@willie-the-truck>

On Wed, Jun 23, 2021 at 07:12:01PM +0530, Sai Prakash Ranjan wrote:
> Currently for iommu_unmap() of large scatter-gather list with page size
> elements, the majority of time is spent in flushing of partial walks in
> __arm_lpae_unmap() which is a VA based TLB invalidation invalidating
> page-by-page on iommus like arm-smmu-v2 (TLBIVA).
> 
> For example: to unmap a 32MB scatter-gather list with page size elements
> (8192 entries), there are 16->2MB buffer unmaps based on the pgsize (2MB
> for 4K granule) and each of 2MB will further result in 512 TLBIVAs (2MB/4K)
> resulting in a total of 8192 TLBIVAs (512*16) for 16->2MB causing a huge
> overhead.
> 
> On qcom implementation, there are several performance improvements for
> TLB cache invalidations in HW like wait-for-safe (for realtime clients
> such as camera and display) and few others to allow for cache
> lookups/updates when TLBI is in progress for the same context bank.
> So the cost of over-invalidation is less compared to the unmap latency
> on several usecases like camera which deals with large buffers. So,
> ASID based TLB invalidations (TLBIASID) can be used to invalidate the
> entire context for partial walk flush thereby improving the unmap
> latency.
> 
> Non-strict mode can use this by default for all platforms given its
> all about over-invalidation saving time on individual unmaps and
> non-deterministic generally.
> 
> For this example of 32MB scatter-gather list unmap, this change results
> in just 16 ASID based TLB invalidations (TLBIASIDs) as opposed to 8192
> TLBIVAs thereby increasing the performance of unmaps drastically.
> 
> Test on QTI SM8150 SoC for 10 iterations of iommu_{map_sg}/unmap:
> (average over 10 iterations)
> 
> Before this optimization:
> 
>     size        iommu_map_sg      iommu_unmap
>       4K            2.067 us         1.854 us
>      64K            9.598 us         8.802 us
>       1M          148.890 us       130.718 us
>       2M          305.864 us        67.291 us
>      12M         1793.604 us       390.838 us
>      16M         2386.848 us       518.187 us
>      24M         3563.296 us       775.989 us
>      32M         4747.171 us      1033.364 us
> 
> After this optimization:
> 
>     size        iommu_map_sg      iommu_unmap
>       4K            1.723 us         1.765 us
>      64K            9.880 us         8.869 us
>       1M          155.364 us       135.223 us
>       2M          303.906 us         5.385 us
>      12M         1786.557 us        21.250 us
>      16M         2391.890 us        27.437 us
>      24M         3570.895 us        39.937 us
>      32M         4755.234 us        51.797 us
> 
> This is further reduced once the map/unmap_pages() support gets in which
> will result in just 1 TLBIASID as compared to 16 TLBIASIDs.
> 
> Real world data also shows big difference in unmap performance as below:
> 
> There were reports of camera frame drops because of high overhead in
> iommu unmap without this optimization because of frequent unmaps issued
> by camera of about 100MB/s taking more than 100ms thereby causing frame
> drops.
> 
> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan at codeaurora.org>
> ---
> 
> Changes in v3:
>  * Move the logic to arm-smmu driver from io-pgtable (Robin)
>  * Use a new set of iommu_flush_ops->arm_smmu_s1_tlb_impl_ops and use it for qcom impl
> 
> Changes in v2:
>  * Add a quirk to choose tlb_flush_all in partial walk flush
>  * Set the quirk for QTI SoC implementation
> 
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 13 +++++++++++++
>  drivers/iommu/arm/arm-smmu/arm-smmu.c      | 17 ++++++++++++++++-
>  2 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> index 7771d40176de..218c71465819 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
> @@ -10,6 +10,8 @@
>  
>  #include "arm-smmu.h"
>  
> +extern const struct iommu_flush_ops arm_smmu_s1_tlb_impl_ops;
> +
>  struct qcom_smmu {
>  	struct arm_smmu_device smmu;
>  	bool bypass_quirk;
> @@ -146,6 +148,8 @@ static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
>  {
>  	struct adreno_smmu_priv *priv;
>  
> +	pgtbl_cfg->tlb = &arm_smmu_s1_tlb_impl_ops;
> +
>  	/* Only enable split pagetables for the GPU device (SID 0) */
>  	if (!qcom_adreno_smmu_is_gpu_device(dev))
>  		return 0;
> @@ -185,6 +189,14 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
>  	{ }
>  };
>  
> +static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
> +		struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
> +{
> +	pgtbl_cfg->tlb = &arm_smmu_s1_tlb_impl_ops;
> +
> +	return 0;
> +}
> +
>  static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu)
>  {
>  	unsigned int last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1);
> @@ -308,6 +320,7 @@ static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
>  }
>  
>  static const struct arm_smmu_impl qcom_smmu_impl = {
> +	.init_context = qcom_smmu_init_context,
>  	.cfg_probe = qcom_smmu_cfg_probe,
>  	.def_domain_type = qcom_smmu_def_domain_type,
>  	.reset = qcom_smmu500_reset,
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index d3c6f54110a5..f3845e822565 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -341,6 +341,12 @@ static void arm_smmu_tlb_add_page_s1(struct iommu_iotlb_gather *gather,
>  				  ARM_SMMU_CB_S1_TLBIVAL);
>  }
>  
> +static void arm_smmu_tlb_inv_walk_impl_s1(unsigned long iova, size_t size,
> +				     size_t granule, void *cookie)
> +{
> +	arm_smmu_tlb_inv_context_s1(cookie);
> +}
> +
>  static void arm_smmu_tlb_inv_walk_s2(unsigned long iova, size_t size,
>  				     size_t granule, void *cookie)
>  {
> @@ -388,6 +394,12 @@ static const struct iommu_flush_ops arm_smmu_s1_tlb_ops = {
>  	.tlb_add_page	= arm_smmu_tlb_add_page_s1,
>  };
>  
> +const struct iommu_flush_ops arm_smmu_s1_tlb_impl_ops = {
> +	.tlb_flush_all	= arm_smmu_tlb_inv_context_s1,
> +	.tlb_flush_walk	= arm_smmu_tlb_inv_walk_impl_s1,
> +	.tlb_add_page	= arm_smmu_tlb_add_page_s1,
> +};

Hmm, dunno about this. Wouldn't it be a lot cleaner if the tlb_flush_walk
callbacks just did the right thing based on the smmu_domain (maybe in the
arm_smmu_cfg?) rather than having an entirely new set of ops just because
they're const and you can't overide the bit you want?

I don't think there's really an awful lot qcom-specific about the principle
here -- there's a trade-off between over-invalidation and invalidation
latency. That happens on the CPU as well.

Will


From mike.leach at linaro.org  Mon Aug  2 08:43:59 2021
From: mike.leach at linaro.org (Mike Leach)
Date: Mon, 2 Aug 2021 16:43:59 +0100
Subject: [PATCH 2/6] perf cs-etm: Initialise architecture based on TRCIDR1
In-Reply-To: <20210802150358.GA148327@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-3-james.clark@arm.com>
 <CAJ9a7Viap53OgrM2e_DU4+oymFB41jspbKbvEVFQWROt7ifuXw@mail.gmail.com>
 <20210731060312.GB7437@leoy-ThinkPad-X240s>
 <CAJ9a7VhdLaP3rkXwscAQpVe+jSgcx02WjY=RmiBkaCB6ObGTjQ@mail.gmail.com>
 <20210802150358.GA148327@leoy-ThinkPad-X240s>
Message-ID: <CAJ9a7VhBU4QYWYbzJs2Z91k=NC+xYnmKJ-HH9CKiNdpDxsY1SA@mail.gmail.com>

Hi Leo,

On Mon, 2 Aug 2021 at 16:04, Leo Yan <leo.yan at linaro.org> wrote:
>
> Hi Mike,
>
> On Mon, Aug 02, 2021 at 03:04:14PM +0100, Mike Leach wrote:
>
> [...]
>
> > > > > +#define TRCIDR1_TRCARCHMIN_SHIFT 4
> > > > > +#define TRCIDR1_TRCARCHMIN_MASK  GENMASK(7, 4)
> > > > > +#define TRCIDR1_TRCARCHMIN(x)    (((x) & TRCIDR1_TRCARCHMIN_MASK) >> TRCIDR1_TRCARCHMIN_SHIFT)
> > > > > +static enum _ocsd_arch_version cs_etm_decoder__get_arch_ver(u32 reg_idr1)
> > > > > +{
> > > > > +       /*
> > > > > +        * If the ETM trace minor version is 4 or more then we can assume
> > > > > +        * the architecture is ARCH_AA64 rather than just V8
> > > > > +        */
> > > > > +       return TRCIDR1_TRCARCHMIN(reg_idr1) >= 4 ? ARCH_AA64 : ARCH_V8;
> > > > > +}
> > > >
> > > > This is true for ETM4.x & ETE 1.x (arch 5.x) but not ETM 3.x
> > > > Probably need to beef up this comment or the function name to emphasise this.
> > >
> > > Yeah, I think it's good to change the function name.  Eventually, this
> > > function should only be used for ETM4.x and ETE.
> > >
> > > Another minor comment is: can we refine the arch version number, e.g.
> > > change the OpenCSD's macro "ARCH_AA64" to "ARCH_V8R4", (or
> > > "ARCH_V8R3_AA64"), this can give more clear clue what's the ETM version.
> > >
> >
> > The purpose of these macros is to inform the decoder of the
> > architecture of the PE - not the version of the ETM.
> >
> > These OpenCSD macros are defined by the library headers
> > (ocsd_if_types.h) and not the perf headers.
> > These have been published as the API / ABI for OpenCSD and as such
> > changing them affects all OpenCSD clients, not just perf.
>
> I understand these macros are defined in OpenCSD lib as APIs, since I
> saw these macros have not been widely used in perf tool (e.g.
> ARCH_AA64), so this is why I think it's good to take chance to refine
> the naming conventions.
>

The macros are used in other tools - so changing now affects those
too. Not something I am prepared to do without good reason.

> > This PE architecture version is used along with the core profile to
> > determine which instructions are valid waypoint instructions to
> > associate with atom elements when walking the program image during
> > trace decode.
> >
> > From v8.3  onwards we moved away from filtering on specific
> > architecture versions. This was due to two factors:-
> > 1. The architectural rules now allow architectural features for one
> > increment e.g. Arch 8.4, to be backported into  the previous increment
> > - e,g, 8.3, which made this filtering more difficult to track.
> > 2. After discussion with the PE architects it was clear that
> > instructions in a later architect version would not re-use older
> > opcodes from a previous one and  be nop / invalid in the earlier
> > architectures. (certainly in the scope of AA64). Therefore
> > the policy in the decoder is to check for all the instructions we know
> > about for the latest version of architecture, even if we could be
> > decoding an earlier architecture version. This means we may check for
> > a few more opcodes than necessary for earlier version of the
> > architecture, but the overall decode is more robust and easier to
> > maintain.
> >
> > Therefore for any AA64 core beyond v8.3 - it is safe to use the
> > ARCH_AA64 PE architecture version and the decoder will handle it.
>
> I have no objection for current approach; but two things can cause
> confusions and it might be difficult for maintenance:
>
> - The first thing is now we base on the bit fields TRCIDR1::TRCARCHMIN
>   to decide the PE architecture version.  In the ETMv4 spec,
>   TRCIDR1::TRCARCHMIN is defined as the trace unit minor version,
>   so essentially it's a minor version number for tracer (ETM) but not
>   the PE architecture number.  But now we are using it to decide the
>   PE architecture number (8.3, 8.4, etc...).
>

This is a slight weakness in the implementation of perf. Ideally one
does need to establish the architecture version of the PE - but perf
/cs-etm is using an assumption regarding the profile and version of
the core, according to the ETM / ETE versiom.
That said - the ETM / ETE version numbers do have a strong
relationship with PE architecture version numbers, so this assumption
holds for the current supported devices.

> - The second thing is the macros' naming convention.
>   E.g. "AA64" gives me an impression it is a general naming "Arm Arch 64"
>   for all Arm 64-bit CPUs, it's something like an abbreviation for
>   "aarch64"; so seems to me it doesn't show any meaningful info for PE's
>   architecture version number.  This is why I proposed to use more
>   explict macro definition for architectures (e.g. ARCH_V8R3, ARCH_V8R4,
>   ARCH_V9R0, etc).
>

For modern cores it is sufficient for the decoder to know the profile
and that it is aarch 64 - so yes the macro is simply saying this a
general AA64 core.
The macros for earlier versions are a little more specific as certain
filtering is used according to the version of the PE.

ARCH_V8R4,  ARCH_V9R0 etc would have no significance to the decoder
and would not be useful. If we get to the stage where we need more
specific PE architecture versions - then these can be added as
required.
Using the ARCH_AA64 macro means that we do not have to update the API
for every version update of the architecture, and there are no changes
required to the perf / cs-etm handling.

> If we really want to use ARCH_AA64, it's better to give some comments in
> the code.
>

There are comments in the OpenCSD headers, though additional ones in
the perf  / cs-etm handling soruce code could be added.

Regards

Mike


> Thanks a lot for shared the background info.
>
> Leo



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From martinwguy at gmail.com  Mon Aug  2 08:45:17 2021
From: martinwguy at gmail.com (Martin Guy)
Date: Mon, 2 Aug 2021 17:45:17 +0200
Subject: [PATCH] ARM: ep93xx: remove MaverickCrunch support
In-Reply-To: <20210802141245.1146772-1-arnd@kernel.org>
References: <20210802141245.1146772-1-arnd@kernel.org>
Message-ID: <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>

On 02/08/2021, Arnd Bergmann <arnd at kernel.org> wrote:
> The MaverickCrunch support for ep93xx never made it into glibc

This is true, but is not needed except for preserving FP registers in
catch/throw exeptions or longjmps.

> was removed from gcc in its 4.8 release in 2012.

I was sad about that, as I had managed to get it working correctly in
4.2 4.3 and 4.4.
Unfortunately the GCC ARM maintainer at the time was paid by ARM, and
they had no interest in it, as I gather the ARM-Cirrus partnership
ended up disappointingly.

> It is now one of
> the last parts of arch/arm/ that fails to build with the clang
> integrated assembler

Even if crunch support is not configured?

> According to Hartley Sweeten:
>
>  "Martin Guy did a lot of work trying to get the maverick crunch working
>   but I was never able to successfully use it for anything.

>   It "kind" of works but depending on the EP93xx silicon revision

It works fine on all production revisions except D0 (the first one)
which is so rare as to be unfindable. All the others from D1 on have
the exact same HW bugs.

>   there are still a number of hardware bugs that either give imprecise or garbage results.

Not my experience, See http://martinwguy.net/crunch/#CorrectnessTests
If "imprecise" means "doesn't handle unnormalized FP values correctly"
then yes, that's a feature if you need the 2.5 to 4gimes speedup it
provides.
But I would be interested (Hartley) if you have a concrete example.

> This touches mostly the ep93xx platform,

The ep93xx is the only chip series it was ever included in.

> If there are remaining users of MaverickCrunch, they can use LTS
> kernels for at least another five years before kernel support ends.

The only user ! am aware of is the HEAT deep space telescope in the Antarctic
http://martinwguy.blogspot.com/2015/10/maverickcrunch-code-runs-on-heat-deep.html

Personally I have no problem with removing kernel support if that
makes people's lives easier in some way.

  M

   M


From robin.murphy at arm.com  Mon Aug  2 08:46:37 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 2 Aug 2021 16:46:37 +0100
Subject: [Patch V2 0/2] iommu/arm-smmu: Fix races in iommu domain/group
 creation
In-Reply-To: <20210802151607.GF28735@willie-the-truck>
References: <1623961837-12540-1-git-send-email-amhetre@nvidia.com>
 <20210802151607.GF28735@willie-the-truck>
Message-ID: <9c38c53c-c145-097a-4c7e-40f1c06a1f01@arm.com>

On 2021-08-02 16:16, Will Deacon wrote:
> On Fri, Jun 18, 2021 at 02:00:35AM +0530, Ashish Mhetre wrote:
>> Multiple iommu domains and iommu groups are getting created for the devices
>> sharing same SID. It is expected for devices sharing same SID to be in same
>> iommu group and same iommu domain.
>> This is leading to context faults when one device is accessing IOVA from
>> other device which shouldn't be the case for devices sharing same SID.
>> Fix this by protecting iommu domain and iommu group creation with mutexes.
> 
> Robin -- any chance you could take a look at these, please? You had some
> comments on the first version which convinced me that they are needed,
> but I couldn't tell whether you wanted to solve this a different way or not.

Sorry, I was lamenting that this came to light due to the 
of_iommu_configure() flow being yucky, but that wasn't meant to imply 
that there aren't - or couldn't be in future - better reasons for 
iommu_probe_device() to be robust against concurrency anyway. I do think 
these are legitimate fixes to make in their own right, even if the 
current need might get swept back under the rug in future.

I would say, however, that the commit messages seem to focus too much on 
the wrong details and aren't overly useful, and patch #2 is missing 
Ashish's sign-off.

Thanks,
Robin.


From dqfext at gmail.com  Mon Aug  2 08:48:38 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Mon,  2 Aug 2021 23:48:38 +0800
Subject: [RFC net-next v2 4/4] Revert "mt7530 mt7530_fdb_write only set
 ivl bit vid larger than 1"
In-Reply-To: <20210802134409.dro5zjp5ymocpglf@skbuf>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-5-dqfext@gmail.com>
 <20210802134409.dro5zjp5ymocpglf@skbuf>
Message-ID: <20210802154838.1817958-1-dqfext@gmail.com>

On Mon, Aug 02, 2021 at 04:44:09PM +0300, Vladimir Oltean wrote:
> Would you mind explaining what made VID 1 special in Eric's patch in the
> first place?

The default value of all ports' PVID is 1, which is copied into the FDB
entry, even if the ports are VLAN unaware. So running `bridge fdb show`
will show entries like `dev sw0p0 vlan 1 self` even on a VLAN-unaware
bridge.

Eric probably thought VID 1 is the FDB of all VLAN-unaware bridges, but
that is not true. And his patch probably cause a new issue that FDB is
inaccessible in a VLAN-**aware** bridge with PVID 1.

This series sets PVID to 0 on VLAN-unaware ports, so `bridge fdb show`
will no longer print `vlan 1` on VLAN-unaware bridges, and we don't
need special case in port_fdb_{add,del} for assisted learning.


From olekstysh at gmail.com  Mon Aug  2 08:52:56 2021
From: olekstysh at gmail.com (Oleksandr)
Date: Mon, 2 Aug 2021 18:52:56 +0300
Subject: [RFC PATCH 1/2] arm64: mm: Make virt_addr_valid to check for
 pfn_valid again
In-Reply-To: <YQgKUibfW4jZbBXM@kernel.org>
References: <1627490656-1267-1-git-send-email-olekstysh@gmail.com>
 <20210802121947.GF18685@arm.com> <YQgKUibfW4jZbBXM@kernel.org>
Message-ID: <f9e1c4a0-a19f-6a56-7641-b4a9973c0807@gmail.com>


Hello, all.


On 02.08.21 18:08, Mike Rapoport wrote:
> Hi,
>
> On Mon, Aug 02, 2021 at 01:19:48PM +0100, Catalin Marinas wrote:
>> Adding Mike and Anshuman,
>>
>> On Wed, Jul 28, 2021 at 07:44:15PM +0300, Oleksandr Tyshchenko wrote:
>>> From: Oleksandr Tyshchenko <oleksandr_tyshchenko at epam.com>
>>>
>>> The problem is that Arm's implementation of virt_addr_valid()
>>> leads to memblock_is_map_memory() check, which will fail for
>>> ZONE_DEVICE based addresses. But, the pfn_valid() check in turn
>>> is able to cope with ZONE_DEVICE based memory.
>>>
>>> You can find a good explanation of that problem at:
>>> https://lore.kernel.org/lkml/1614921898-4099-2-git-send-email-anshuman.khandual at arm.com
>>>
>>> Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko at epam.com>
>>> ---
>>> I am not quite sure whether it is a "correct" place and
>>> the change itself, I just partially restored a behaviour before:
>>> https://lore.kernel.org/lkml/20210511100550.28178-4-rppt at kernel.org
>>> So, the target of this patch is to get a feedback how to resolve
>>> this properly if, of course, this really needs to be resolved
>>> (I might miss important bits here).
>>>
>>> It is worth mentioning that patch doesn't fix the current code base
>>> (if I am not mistaken, no one calls virt_addr_valid() on Arm64 for
>>> ZONE_DEVICE based addresses at the moment, so it seems that nothing
>>> is broken), the fix is intended for the subsequent patch in this
>>> series that will try to enable Xen's "unpopulated-alloc" usage
>>> on Arm (it was enabled on x86 so far).
>>> Please see:
>>> [RFC PATCH 2/2] xen/unpopulated-alloc: Query hypervisor to provide
>>> unallocated space
>>>
>>> The subsequent patch will enable the code where virt_addr_valid()
>>> is used in drivers/xen/unpopulated-alloc.c:fill_list() to check that
>>> a virtual address returned by memremap_pages() is valid.
>   
>> I wonder what the point of calling virt_addr_valid() in fill_list() is?
>> If memremap_pages() succeeded, the pages were mapped at the returned
>> vaddr, there's no need for an additional virt_addr_valid() check.
> The virt_addr_valid() check in fill_list() looks bogus to me as well. If
> memremap_pages() succeeds the range is guaranteed to have proper page
> table.
>
> I believe the first patch should be rather removal of the virt_addr_valid()
> check in fill_list().
Thank you for the clarification, I will send a patch to remove 
virt_addr_valid()
check in fill_list() for the non-RFC version.


>   
>>> ---
>>>   arch/arm64/include/asm/memory.h | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>>> index 824a365..1a35a44 100644
>>> --- a/arch/arm64/include/asm/memory.h
>>> +++ b/arch/arm64/include/asm/memory.h
>>> @@ -351,7 +351,7 @@ static inline void *phys_to_virt(phys_addr_t x)
>>>   
>>>   #define virt_addr_valid(addr)	({					\
>>>   	__typeof__(addr) __addr = __tag_reset(addr);			\
>>> -	__is_lm_address(__addr) && pfn_is_map_memory(virt_to_pfn(__addr));	\
>>> +	__is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr));	\
>>>   })
>> pfn_valid() only guarantees the presence of a struct page but not
>> necessarily that the virtual address is accessible (valid). So this
>> change would break the NOMAP ranges case.
> +1
Oh, I got it.

-- 
Regards,

Oleksandr Tyshchenko



From Dave.Martin at arm.com  Mon Aug  2 08:52:38 2021
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 2 Aug 2021 16:52:38 +0100
Subject: [PATCH] arm64/sve: Make fpsimd_bind_task_to_cpu() static
In-Reply-To: <20210730165846.18558-1-broonie@kernel.org>
References: <20210730165846.18558-1-broonie@kernel.org>
Message-ID: <20210802155238.GD25258@arm.com>

On Fri, Jul 30, 2021 at 05:58:46PM +0100, Mark Brown wrote:
> This function is not referenced outside fpsimd.c so can be static, making
> it that little bit easier to follow what is called from where.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

Otherwise, this seems sensible, since by definition no code that isn't
switching task contexts should be calling this directly.

Rather makes me wonder
why it wasn't static in the first place.  This might have arisen from
splitting out a backend function from something else that isn't static,
or maybe I was trying to do this directy from KVM.  The notion of non-
task context that the KVM now uses is newer than the original SVE code.

Anyway, assuming you've grepped and tried to build with KVM at least
(so, defconfig):

Reviewed-by: Dave Martin <Dave.Martin at arm.com>


> ---
>  arch/arm64/include/asm/fpsimd.h | 1 -
>  arch/arm64/kernel/fpsimd.c      | 4 +++-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index c072161d5c65..9a62884183e5 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -45,7 +45,6 @@ extern void fpsimd_preserve_current_state(void);
>  extern void fpsimd_restore_current_state(void);
>  extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
>  
> -extern void fpsimd_bind_task_to_cpu(void);
>  extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
>  				     void *sve_state, unsigned int sve_vl);
>  
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index e57b23f95284..eb8d972ad3d2 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -162,6 +162,8 @@ extern void __percpu *efi_sve_state;
>  DEFINE_PER_CPU(bool, fpsimd_context_busy);
>  EXPORT_PER_CPU_SYMBOL(fpsimd_context_busy);
>  
> +static void fpsimd_bind_task_to_cpu(void);
> +
>  static void __get_cpu_fpsimd_context(void)
>  {
>  	bool busy = __this_cpu_xchg(fpsimd_context_busy, true);
> @@ -1112,7 +1114,7 @@ void fpsimd_signal_preserve_current_state(void)
>   * The caller must have ownership of the cpu FPSIMD context before calling
>   * this function.
>   */
> -void fpsimd_bind_task_to_cpu(void)
> +static void fpsimd_bind_task_to_cpu(void)
>  {
>  	struct fpsimd_last_state_struct *last =
>  		this_cpu_ptr(&fpsimd_last_state);
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From maz at kernel.org  Mon Aug  2 08:55:13 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Aug 2021 16:55:13 +0100
Subject: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
In-Reply-To: <1626793023-13830-4-git-send-email-mikelley@microsoft.com>
References: <1626793023-13830-1-git-send-email-mikelley@microsoft.com>
 <1626793023-13830-4-git-send-email-mikelley@microsoft.com>
Message-ID: <87lf5j265a.wl-maz@kernel.org>

On Tue, 20 Jul 2021 15:57:01 +0100,
Michael Kelley <mikelley at microsoft.com> wrote:
> 
> Add ARM64-specific code to initialize the Hyper-V
> hypervisor when booting as a guest VM.
> 
> This code is built only when CONFIG_HYPERV is enabled.
> 
> Signed-off-by: Michael Kelley <mikelley at microsoft.com>
> ---
>  arch/arm64/hyperv/Makefile   |  2 +-
>  arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 84 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/hyperv/mshyperv.c
> 
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 1697d30..87c31c0 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,2 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-y		:= hv_core.o
> +obj-y		:= hv_core.o mshyperv.o
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> new file mode 100644
> index 0000000..2811fd0
> --- /dev/null
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Core routines for interacting with Microsoft's Hyper-V hypervisor,
> + * including hypervisor initialization.
> + *
> + * Copyright (C) 2021, Microsoft, Inc.
> + *
> + * Author : Michael Kelley <mikelley at microsoft.com>
> + */
> +
> +#include <linux/types.h>
> +#include <linux/acpi.h>
> +#include <linux/export.h>
> +#include <linux/errno.h>
> +#include <linux/version.h>
> +#include <linux/cpuhotplug.h>
> +#include <asm/mshyperv.h>
> +
> +static bool hyperv_initialized;
> +
> +static int __init hyperv_init(void)
> +{
> +	struct hv_get_vp_registers_output	result;
> +	u32	a, b, c, d;
> +	u64	guest_id;
> +	int	ret;
> +
> +	/*
> +	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
> +	 * have the string "MsHyperV".
> +	 */
> +	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
> +		return -EINVAL;

Before going ahead and parsing the local FADT copy, it would be
prudent to test that you are actually on an ACPI system, specially
given that this function is unconditionally called, even on DT
systems.  In the same vein, returning -EINVAL when failing to find
Hyper-V is a bit excessive.

> +
> +	/* Setup the guest ID */
> +	guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
> +	hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
> +
> +	/* Get the features and hints from Hyper-V */
> +	hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
> +	ms_hyperv.features = result.as32.a;
> +	ms_hyperv.priv_high = result.as32.b;
> +	ms_hyperv.misc_features = result.as32.c;
> +
> +	hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result);
> +	ms_hyperv.hints = result.as32.a;
> +
> +	pr_info("Hyper-V: privilege flags low 0x%x, high 0x%x, hints 0x%x, misc 0x%x\n",
> +		ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
> +		ms_hyperv.misc_features);
> +
> +	/* Get information about the Hyper-V host version */
> +	hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
> +	a = result.as32.a;
> +	b = result.as32.b;
> +	c = result.as32.c;
> +	d = result.as32.d;
> +	pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
> +		b >> 16, b & 0xFFFF, a,	d & 0xFFFFFF, c, d >> 24);
> +
> +	ret = hv_common_init();
> +	if (ret)
> +		return ret;
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online",
> +				hv_common_cpu_init, hv_common_cpu_die);
> +	if (ret < 0) {
> +		hv_common_free();
> +		return ret;
> +	}
> +
> +	hyperv_initialized = true;
> +	return 0;
> +}
> +
> +early_initcall(hyperv_init);
> +
> +bool hv_is_hyperv_initialized(void)
> +{
> +	return hyperv_initialized;
> +}
> +EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From dqfext at gmail.com  Mon Aug  2 08:58:10 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Mon,  2 Aug 2021 23:58:10 +0800
Subject: [RFC net-next v2 3/4] net: dsa: mt7530: set STP state also on
 filter ID 1
In-Reply-To: <20210802154226.qggqzkxe6urkx3yf@skbuf>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-4-dqfext@gmail.com>
 <20210802134336.gv66le6u2z52kfkh@skbuf>
 <20210802153129.1817825-1-dqfext@gmail.com>
 <20210802154226.qggqzkxe6urkx3yf@skbuf>
Message-ID: <20210802155810.1818085-1-dqfext@gmail.com>

On Mon, Aug 02, 2021 at 06:42:26PM +0300, Vladimir Oltean wrote:
> On Mon, Aug 02, 2021 at 11:31:29PM +0800, DENG Qingfang wrote:
> > The current code only sets FID 0's STP state. This patch sets both 0's and
> > 1's states.
> >
> > The *5 part is binary magic. [1:0] is FID 0's state, [3:2] is FID 1's state
> > and so on. Since 5 == 4'b0101, the value in [1:0] is copied to [3:2] after
> > the multiplication.
> >
> > Perhaps I should only change FID 1's state.
> 
> Keep the patches dumb for us mortals please.
> If you only change FID 1's state, I am concerned that the driver no
> longer initializes FID 0's port state, and might leave that to the
> default set by other pre-kernel initialization stage (bootloader?).
> So even if you might assume that standalone ports are FORWARDING, they
> might not be.

The default value is forwarding, and the switch is reset by the driver
so any pre-kernel initialization stage is no more.


From maz at kernel.org  Mon Aug  2 09:01:02 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 02 Aug 2021 17:01:02 +0100
Subject: [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64
In-Reply-To: <1626793023-13830-1-git-send-email-mikelley@microsoft.com>
References: <1626793023-13830-1-git-send-email-mikelley@microsoft.com>
Message-ID: <87k0l325vl.wl-maz@kernel.org>

On Tue, 20 Jul 2021 15:56:58 +0100,
Michael Kelley <mikelley at microsoft.com> wrote:
> 
> This series enables Linux guests running on Hyper-V on ARM64
> hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> Hyper-V and its hypercall mechanism.  Existing architecture
> independent drivers for Hyper-V's VMbus and synthetic devices just
> work when built for ARM64. Hyper-V code is built and included in
> the image and modules only if CONFIG_HYPERV is enabled.
> 
> The five patches are organized as follows:
> 
> 1) Add definitions and functions for making Hyper-V hypercalls
>    and getting/setting virtual processor registers provided by
>    Hyper-V
> 
> 2) Add the function needed by the arch independent VMbus driver
>    for reporting a panic to Hyper-V.
> 
> 3) Add Hyper-V initialization code and utility functions that
>    report Hyper-v status.
> 
> 4) Export screen_info so it may be used by the Hyper-V frame buffer
>    driver built as a module. It is already exported for x86,
>    powerpc, and alpha architectures.
> 
> 5) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.
> 
> Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> with 4K/16K/64K page size. Linux guests with this patch series
> work with all three supported ARM64 page sizes.
> 
> The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> x86/x64-specific code and is not being built for ARM64. Enabling
> Hyper-V vPCI devices on ARM64 is in progress via a separate set
> of patches.
> 
> This patch set is based on the linux-next20210720 code tree.
> 
> Changes in v11:
> * Drop the previous Patch 1 as the fixes have already been
>   separately accepted upstream.
> * Drop the previous Patch 3 for enabling Hyper-V enlightened
>   clocks/timers.  Hyper-V is now offering the full ARM64
>   architectural Generic Timer in guest VMs, so the existing
>   arch_arch_timer.c driver just works. [Mark Rutland, Marc
>   Zyngier]

Thanks for doing this. Assuming you fix the issue I mentioned in my
reply to patch #3. FWIW:

Acked-by: Marc Zyngier <maz at kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


From robh at kernel.org  Mon Aug  2 09:10:39 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 10:10:39 -0600
Subject: [PATCH v3 1/2] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <87sfzt1pg9.wl-maz@kernel.org>
References: <20210726083204.93196-1-mark.kettenis@xs4all.nl>
 <20210726083204.93196-2-mark.kettenis@xs4all.nl>
 <20210726231848.GA1025245@robh.at.kernel.org>
 <87sfzt1pg9.wl-maz@kernel.org>
Message-ID: <CAL_JsqLvqWiuib9s4PzX8pOQYJQ0eR7Gxz==J849eVJ5MDq4SA@mail.gmail.com>

On Sun, Aug 1, 2021 at 3:31 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Tue, 27 Jul 2021 00:18:48 +0100,
> Rob Herring <robh at kernel.org> wrote:
> >
> > On Mon, Jul 26, 2021 at 10:32:00AM +0200, Mark Kettenis wrote:
> > > From: Mark Kettenis <kettenis at openbsd.org>
> > >
> > > The Apple PCIe host controller is a PCIe host controller with
> > > multiple root ports present in Apple ARM SoC platforms, including
> > > various iPhone and iPad devices and the "Apple Silicon" Macs.
> > >
> > > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > > ---
> > >  .../devicetree/bindings/pci/apple,pcie.yaml   | 166 ++++++++++++++++++
> > >  MAINTAINERS                                   |   1 +
> > >  2 files changed, 167 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > new file mode 100644
> > > index 000000000000..bfcbdee79c64
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > @@ -0,0 +1,166 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Apple PCIe host controller
> > > +
> > > +maintainers:
> > > +  - Mark Kettenis <kettenis at openbsd.org>
> > > +
> > > +description: |
> > > +  The Apple PCIe host controller is a PCIe host controller with
> > > +  multiple root ports present in Apple ARM SoC platforms, including
> > > +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > +  The controller incorporates Synopsys DesigWare PCIe logic to
> > > +  implements its root ports.  But the ATU found on most DesignWare
> > > +  PCIe host bridges is absent.
> >
> > blank line
> >
> > > +  All root ports share a single ECAM space, but separate GPIOs are
> > > +  used to take the PCI devices on those ports out of reset.  Therefore
> > > +  the standard "reset-gpio" and "max-link-speed" properties appear on
> >
> > reset-gpios
> >
> > > +  the child nodes that represent the PCI bridges that correspond to
> > > +  the individual root ports.
> >
> > blank line
> >
> > > +  MSIs are handled by the PCIe controller and translated into regular
> > > +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> > > +  distributed over the root ports as the OS sees fit by programming
> > > +  the PCIe controller's port registers.
> > > +
> > > +allOf:
> > > +  - $ref: /schemas/pci/pci-bus.yaml#
> > > +
> > > +properties:
> > > +  compatible:
> > > +    items:
> > > +      - const: apple,t8103-pcie
> > > +      - const: apple,pcie
> > > +
> > > +  reg:
> > > +    minItems: 3
> > > +    maxItems: 5
> > > +
> > > +  reg-names:
> > > +    minItems: 3
> > > +    maxItems: 5
> > > +    items:
> > > +      - const: config
> > > +      - const: rc
> > > +      - const: port0
> > > +      - const: port1
> > > +      - const: port2
> > > +
> > > +  ranges:
> > > +    minItems: 2
> > > +    maxItems: 2
> > > +
> > > +  interrupts:
> > > +    description:
> > > +      Interrupt specifiers, one for each root port.
> > > +    minItems: 1
> > > +    maxItems: 3
> > > +
> > > +  msi-controller: true
> > > +  msi-parent: true
> > > +
> > > +  msi-ranges:
> > > +    description:
> > > +      A list of pairs <intid span>, where "intid" is the first
> > > +      interrupt number that can be used as an MSI, and "span" the size
> > > +      of that range.
> > > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > > +    items:
> > > +      minItems: 2
> > > +      maxItems: 2
> >
> > I still have issues I raised on v1 with this property. It's genericish
> > looking, but not generic. 'intid' as a single cell can't specify any
> > parent interrupt such as a GIC which uses 3 cells. You could put in all
> > the cells, but you'd still be assuming which cell you can increment.
>
> The GIC bindings already use similar abstractions, see what we do for
> both GICv2m and GICv3 MBIs. Other MSI controllers use similar
> properties (alpine and loongson, for example).

That's the problem. Everyone making up their own crap.

> > I think you should just list all these under 'interrupts' using
> > interrupt-names to make your life easier:
> >
> > interrupt-names:
> >   items:
> >     - const: port0
> >     - const: port1
> >     - const: port2
> >     - const: msi0
> >     - const: msi1
> >     - const: msi2
> >     - const: msi3
> >     ...
> >
> > Yeah, it's kind of verbose, but if the h/w block handles N interrupts,
> > you should list N interrupts. The worst case for the above is N entries
> > too if not contiguous.
>
> And that's where I beg to differ, again.
>
> Specifying interrupts like this gives the false impression that these
> interrupts are generated by the device that owns them (the RC). Which
> for MSIs is not the case.

It's no different than an interrupt controller node having an
interrupts property. The source is downstream and the interrupt
controller is combining/translating the interrupts.

The physical interrupt signals are connected to and originating in
this block. That sounds like perfectly 'describing the h/w' to me.

> This is not only verbose, this is
> semantically dubious. And what should we do when the number of
> possible interrupt is ridiculously large, as it is for the GICv3 ITS?

I don't disagree with the verbose part. But that's not really an issue
in this case.

> I wish we had a standard way to express these constraints. Until we
> do, I don't think enumerating individual interrupts is a practical
> thing to do, nor that it actually represents the topology of the
> system.

The only way a standard way will happen is to stop accepting the
custom properties.

All the custom properties suffer from knowledge of what the parent
interrupt controller is. To fix that, I think we need something like
this:

msi-ranges = <intspec base>, <intspec step>, <intspec end>;

'intspec' is defined by the parent interrupt-controller cells. step is
the value to add. And end is what to match on to stop aka the last
interrupt in the range. For example, if the GIC is the parent, we'd
have something like this:

<GIC_SPI 123 0>, <0 1 0>, <GIC_SPI 124 0>

Does this apply to cases other than MSI? I think so as don't we have
the same type of properties with the low power mode shadow interrupt
controllers?  So 'interrupt-ranges'?


It looks to me like there's an assumption in the kernel that an MSI
controller has a linear range of parent interrupts? Is that correct
and something that's guaranteed? That assumption leaks into the
existing bindings. It's fine for the kernel to assume that until
there's a case that's not linear, but a common binding needs to be
able handle a non-linear case.

Rob


From will at kernel.org  Mon Aug  2 09:12:06 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 2 Aug 2021 17:12:06 +0100
Subject: [PATCH] iommu/arm-smmu: Add clk_bulk_{prepare/unprepare} to
 system pm callbacks
In-Reply-To: <20210727093322.13202-1-saiprakash.ranjan@codeaurora.org>
References: <20210727093322.13202-1-saiprakash.ranjan@codeaurora.org>
Message-ID: <20210802161206.GA29168@willie-the-truck>

On Tue, Jul 27, 2021 at 03:03:22PM +0530, Sai Prakash Ranjan wrote:
> Some clocks for SMMU can have parent as XO such as gpu_cc_hub_cx_int_clk
> of GPU SMMU in QTI SC7280 SoC and in order to enter deep sleep states in
> such cases, we would need to drop the XO clock vote in unprepare call and
> this unprepare callback for XO is in RPMh (Resource Power Manager-Hardened)
> clock driver which controls RPMh managed clock resources for new QTI SoCs
> and is a blocking call.
> 
> Given we cannot have a sleeping calls such as clk_bulk_prepare() and
> clk_bulk_unprepare() in arm-smmu runtime pm callbacks since the iommu
> operations like map and unmap can be in atomic context and are in fast
> path, add this prepare and unprepare call to drop the XO vote only for
> system pm callbacks since it is not a fast path and we expect the system
> to enter deep sleep states with system pm as opposed to runtime pm.
> 
> This is a similar sequence of clock requests (prepare,enable and
> disable,unprepare) in arm-smmu probe and remove.
> 
> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan at codeaurora.org>
> Co-developed-by: Rajendra Nayak <rnayak at codeaurora.org>
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu.c | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)

[+Rob]

How does this work with that funny GPU which writes to the SMMU registers
directly? Does the SMMU need to remain independently clocked for that to
work or is it all in the same clock domain?

> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index d3c6f54110a5..9561ba4c5d39 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -2277,6 +2277,13 @@ static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
>  
>  static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
>  {
> +	int ret;
> +	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> +
> +	ret = clk_bulk_prepare(smmu->num_clks, smmu->clks);
> +	if (ret)
> +		return ret;
> +
>  	if (pm_runtime_suspended(dev))
>  		return 0;

If we subsequently fail to enable the clks in arm_smmu_runtime_resume()
should we unprepare them again?

Will

> @@ -2285,10 +2292,19 @@ static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
>  
>  static int __maybe_unused arm_smmu_pm_suspend(struct device *dev)
>  {
> +	int ret = 0;
> +	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> +
>  	if (pm_runtime_suspended(dev))
> -		return 0;
> +		goto clk_unprepare;
>  
> -	return arm_smmu_runtime_suspend(dev);
> +	ret = arm_smmu_runtime_suspend(dev);
> +	if (ret)
> +		return ret;
> +
> +clk_unprepare:
> +	clk_bulk_unprepare(smmu->num_clks, smmu->clks);
> +	return ret;
>  }
>  
>  static const struct dev_pm_ops arm_smmu_pm_ops = {
> -- 
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
> 


From broonie at kernel.org  Mon Aug  2 09:12:01 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Aug 2021 17:12:01 +0100
Subject: [PATCH] arm64/sve: Make fpsimd_bind_task_to_cpu() static
In-Reply-To: <20210802155238.GD25258@arm.com>
References: <20210730165846.18558-1-broonie@kernel.org>
 <20210802155238.GD25258@arm.com>
Message-ID: <20210802161201.GI4668@sirena.org.uk>

On Mon, Aug 02, 2021 at 04:52:38PM +0100, Dave Martin wrote:

> Rather makes me wonder
> why it wasn't static in the first place.  This might have arisen from
> splitting out a backend function from something else that isn't static,
> or maybe I was trying to do this directy from KVM.  The notion of non-
> task context that the KVM now uses is newer than the original SVE code.

IIRC there was something like that in the older KVM SVE stuff but I
didn't go spelunking enough to figure it out specifically.

> Anyway, assuming you've grepped and tried to build with KVM at least
> (so, defconfig):

grepped and my standard development builds include KVM.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/7549b76a/attachment.sig>

From Dave.Martin at arm.com  Mon Aug  2 09:16:39 2021
From: Dave.Martin at arm.com (Dave Martin)
Date: Mon, 2 Aug 2021 17:16:39 +0100
Subject: [PATCH] arm64/sve: Make fpsimd_bind_task_to_cpu() static
In-Reply-To: <20210802161201.GI4668@sirena.org.uk>
References: <20210730165846.18558-1-broonie@kernel.org>
 <20210802155238.GD25258@arm.com>
 <20210802161201.GI4668@sirena.org.uk>
Message-ID: <20210802161639.GE25258@arm.com>

On Mon, Aug 02, 2021 at 05:12:01PM +0100, Mark Brown wrote:
> On Mon, Aug 02, 2021 at 04:52:38PM +0100, Dave Martin wrote:
> 
> > Rather makes me wonder
> > why it wasn't static in the first place.  This might have arisen from
> > splitting out a backend function from something else that isn't static,
> > or maybe I was trying to do this directy from KVM.  The notion of non-
> > task context that the KVM now uses is newer than the original SVE code.
> 
> IIRC there was something like that in the older KVM SVE stuff but I
> didn't go spelunking enough to figure it out specifically.

Probably best not to ;)

> 
> > Anyway, assuming you've grepped and tried to build with KVM at least
> > (so, defconfig):
> 
> grepped and my standard development builds include KVM.

Fair enough, I would have been very surprised if you hadn't already done
that.

Cheers
---Dave


From broonie at kernel.org  Mon Aug  2 09:23:31 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Aug 2021 17:23:31 +0100
Subject: [PATCH v3 3/4] kselftest/arm64: Add tests for SVE vector
 configuration
In-Reply-To: <20210802153614.GC25258@arm.com>
References: <20210729151518.46388-1-broonie@kernel.org>
 <20210729151518.46388-4-broonie@kernel.org>
 <20210729160642.GP1724@arm.com>
 <20210729173411.GT4670@sirena.org.uk>
 <20210802102517.GA25258@arm.com>
 <20210802113330.GD4668@sirena.org.uk>
 <20210802123749.GB25258@arm.com>
 <20210802141939.GF4668@sirena.org.uk>
 <20210802153614.GC25258@arm.com>
Message-ID: <20210802162331.GJ4668@sirena.org.uk>

On Mon, Aug 02, 2021 at 04:36:15PM +0100, Dave Martin wrote:
> On Mon, Aug 02, 2021 at 03:19:39PM +0100, Mark Brown wrote:

> > popen() appears to be break the _SET_VL_ONEXEC test.  Between a lack of
> > strace in my test filesystem and not spotting anything obvious in the
> > glibc sources I can't tell exactly where it's doing something different,
> > though it does feel like it should be a separate testcase if it's

> Ah, dang, popen() will run the target program via a shell, so there will
> actually be two fork-exec()s, with the VL being reset to default by the
> second exec.

Oh, of course - it's basically a more useful system().  The bit where it
adds the sh invocation was buried somewhere in the glibc source I didn't
find.

> This is the kind of reason why I tend not to go for it, I guess --
> it looks convenient, but it's just that little bit overcooked as an API.
> *sigh*

Well, if you're working at the stdio level it's fine I think but this
program is at the level below that.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/62976772/attachment.sig>

From mark.rutland at arm.com  Mon Aug  2 09:26:23 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 2 Aug 2021 17:26:23 +0100
Subject: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
In-Reply-To: <1626793023-13830-4-git-send-email-mikelley@microsoft.com>
References: <1626793023-13830-1-git-send-email-mikelley@microsoft.com>
 <1626793023-13830-4-git-send-email-mikelley@microsoft.com>
Message-ID: <20210802162623.GC59710@C02TD0UTHF1T.local>

On Tue, Jul 20, 2021 at 07:57:01AM -0700, Michael Kelley wrote:
> Add ARM64-specific code to initialize the Hyper-V
> hypervisor when booting as a guest VM.
> 
> This code is built only when CONFIG_HYPERV is enabled.
> 
> Signed-off-by: Michael Kelley <mikelley at microsoft.com>
> ---
>  arch/arm64/hyperv/Makefile   |  2 +-
>  arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 84 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/hyperv/mshyperv.c
> 
> diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> index 1697d30..87c31c0 100644
> --- a/arch/arm64/hyperv/Makefile
> +++ b/arch/arm64/hyperv/Makefile
> @@ -1,2 +1,2 @@
>  # SPDX-License-Identifier: GPL-2.0
> -obj-y		:= hv_core.o
> +obj-y		:= hv_core.o mshyperv.o
> diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> new file mode 100644
> index 0000000..2811fd0
> --- /dev/null
> +++ b/arch/arm64/hyperv/mshyperv.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Core routines for interacting with Microsoft's Hyper-V hypervisor,
> + * including hypervisor initialization.
> + *
> + * Copyright (C) 2021, Microsoft, Inc.
> + *
> + * Author : Michael Kelley <mikelley at microsoft.com>
> + */
> +
> +#include <linux/types.h>
> +#include <linux/acpi.h>
> +#include <linux/export.h>
> +#include <linux/errno.h>
> +#include <linux/version.h>
> +#include <linux/cpuhotplug.h>
> +#include <asm/mshyperv.h>
> +
> +static bool hyperv_initialized;
> +
> +static int __init hyperv_init(void)
> +{
> +	struct hv_get_vp_registers_output	result;
> +	u32	a, b, c, d;
> +	u64	guest_id;
> +	int	ret;

As Marc suggests, before looking at the FADT, you need something like:

	/*
	 * Hyper-V VMs always have ACPI.
	 */
	if (acpi_disabled)
		return 0;

... where `acpi_disabled` is defined in <linux/acpi.h> (or via its
includes), so you don't need to include any additional headers.

> +
> +	/*
> +	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
> +	 * have the string "MsHyperV".
> +	 */
> +	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
> +		return -EINVAL;

As Marc suggests, it's no an error for a platform to not have Hyper-V,
so returning 0 in tihs case would be preferable.

Otherwise this looks fine to me.

Thanks,
Mark.

> +
> +	/* Setup the guest I[D */
> +	guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
> +	hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
> +
> +	/* Get the features and hints from Hyper-V */
> +	hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
> +	ms_hyperv.features = result.as32.a;
> +	ms_hyperv.priv_high = result.as32.b;
> +	ms_hyperv.misc_features = result.as32.c;
> +
> +	hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result);
> +	ms_hyperv.hints = result.as32.a;
> +
> +	pr_info("Hyper-V: privilege flags low 0x%x, high 0x%x, hints 0x%x, misc 0x%x\n",
> +		ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
> +		ms_hyperv.misc_features);
> +
> +	/* Get information about the Hyper-V host version */
> +	hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
> +	a = result.as32.a;
> +	b = result.as32.b;
> +	c = result.as32.c;
> +	d = result.as32.d;
> +	pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
> +		b >> 16, b & 0xFFFF, a,	d & 0xFFFFFF, c, d >> 24);
> +
> +	ret = hv_common_init();
> +	if (ret)
> +		return ret;
> +
> +	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online",
> +				hv_common_cpu_init, hv_common_cpu_die);
> +	if (ret < 0) {
> +		hv_common_free();
> +		return ret;
> +	}
> +
> +	hyperv_initialized = true;
> +	return 0;
> +}
> +
> +early_initcall(hyperv_init);
> +
> +bool hv_is_hyperv_initialized(void)
> +{
> +	return hyperv_initialized;
> +}
> +EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
> -- 
> 1.8.3.1
> 


From mark.rutland at arm.com  Mon Aug  2 09:28:56 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 2 Aug 2021 17:28:56 +0100
Subject: [PATCH v11 0/5] Enable Linux guests on Hyper-V on ARM64
In-Reply-To: <87k0l325vl.wl-maz@kernel.org>
References: <1626793023-13830-1-git-send-email-mikelley@microsoft.com>
 <87k0l325vl.wl-maz@kernel.org>
Message-ID: <20210802162856.GD59710@C02TD0UTHF1T.local>

On Mon, Aug 02, 2021 at 05:01:02PM +0100, Marc Zyngier wrote:
> On Tue, 20 Jul 2021 15:56:58 +0100,
> Michael Kelley <mikelley at microsoft.com> wrote:
> > 
> > This series enables Linux guests running on Hyper-V on ARM64
> > hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> > Hyper-V and its hypercall mechanism.  Existing architecture
> > independent drivers for Hyper-V's VMbus and synthetic devices just
> > work when built for ARM64. Hyper-V code is built and included in
> > the image and modules only if CONFIG_HYPERV is enabled.
> > 
> > The five patches are organized as follows:
> > 
> > 1) Add definitions and functions for making Hyper-V hypercalls
> >    and getting/setting virtual processor registers provided by
> >    Hyper-V
> > 
> > 2) Add the function needed by the arch independent VMbus driver
> >    for reporting a panic to Hyper-V.
> > 
> > 3) Add Hyper-V initialization code and utility functions that
> >    report Hyper-v status.
> > 
> > 4) Export screen_info so it may be used by the Hyper-V frame buffer
> >    driver built as a module. It is already exported for x86,
> >    powerpc, and alpha architectures.
> > 
> > 5) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.
> > 
> > Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> > with 4K/16K/64K page size. Linux guests with this patch series
> > work with all three supported ARM64 page sizes.
> > 
> > The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> > x86/x64-specific code and is not being built for ARM64. Enabling
> > Hyper-V vPCI devices on ARM64 is in progress via a separate set
> > of patches.
> > 
> > This patch set is based on the linux-next20210720 code tree.
> > 
> > Changes in v11:
> > * Drop the previous Patch 1 as the fixes have already been
> >   separately accepted upstream.
> > * Drop the previous Patch 3 for enabling Hyper-V enlightened
> >   clocks/timers.  Hyper-V is now offering the full ARM64
> >   architectural Generic Timer in guest VMs, so the existing
> >   arch_arch_timer.c driver just works. [Mark Rutland, Marc
> >   Zyngier]
> 
> Thanks for doing this. Assuming you fix the issue I mentioned in my
> reply to patch #3. FWIW:
> 
> Acked-by: Marc Zyngier <maz at kernel.org>

I've tried to provide concrete options for those. With those fixed up
somehow:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.


From robh at kernel.org  Mon Aug  2 09:30:47 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 10:30:47 -0600
Subject: [PATCH 4/5 v2] pata: ixp4xx: Add DT bindings
In-Reply-To: <20210731213555.2965356-4-linus.walleij@linaro.org>
References: <20210731213555.2965356-1-linus.walleij@linaro.org>
 <20210731213555.2965356-4-linus.walleij@linaro.org>
Message-ID: <CAL_JsqJkWtR_FevXZH7kGiHbFLbDypn-fy1W=twDYRVyn54wWQ@mail.gmail.com>

On Sat, Jul 31, 2021 at 3:38 PM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> This adds device tree bindings for the Intel IXP4xx compact flash card
> interface.
>
> Cc: devicetree at vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> ChangeLog v1->v2:
> - Itemize the registers
> - Drop the epansion bus set-up to alleviate warnings
> ---
>  .../ata/intel,ixp4xx-compact-flash.yaml       | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.yaml

I'll assume this passes with the
'intel,ixp43x-expansion-bus-controller' schema present.

Reviewed-by: Rob Herring <robh at kernel.org>


From linux at armlinux.org.uk  Mon Aug  2 09:38:24 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 2 Aug 2021 17:38:24 +0100
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <20210802152755.ibisunvibmwhiyry@pengutronix.de>
References: <YPlfcbkxiBmB+vw1@kunai>
 <CAHp75VfC=s12Unw3+Cn0ag71mM5i90=Jbwj4nYwB5cPKiUTRSA@mail.gmail.com>
 <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
 <20210802094810.GJ22278@shell.armlinux.org.uk>
 <20210802152755.ibisunvibmwhiyry@pengutronix.de>
Message-ID: <20210802163824.GK22278@shell.armlinux.org.uk>

On Mon, Aug 02, 2021 at 05:27:55PM +0200, Uwe Kleine-K?nig wrote:
> Hello Russell,
> 
> On Mon, Aug 02, 2021 at 10:48:10AM +0100, Russell King (Oracle) wrote:
> > I think devm_clk_get() should not be part of CCF but should be
> > part of the interface level - it's silly to have devm_clk_get()
> > being CCF but not clk_get(). The same should go for the other
> > devm wrappers around the plain clk_* interfaces.
> 
> What is the practical difference between "Function X is part of CCF" and
> "Function X is part of the clk interface and there is only CCF who
> implements it"?

clkdev is maintained by me as part of the API, and provides clk_get()
functionality for all clk implementations. To then have devm_clk_get(),
which merely provides a wrapper around clk_get() adding the devm
semantics being part of CCF is not sane - devm_clk_get() isn't
specific to CCF or in fact any clk API implementation.

> > There have been several different approaches to wrapping things up,
> > but here's a question: should we make it easier to do the lazy thing
> > (get+enable) or should we make it easier to be power efficient?
> > Shouldn't we be encouraging people to write power efficient drivers?
> 
> Yeah, sounds compelling, but I wonder if that's of practical importance.
> How many driver authors do you expect to lure into making a better
> driver just because devm_clk_get_prepared() doesn't exist? In contrast:
> How many drivers become simpler with devm_clk_get_prepared() and so
> it becomes easier to maintain them and easier to spot bugs?
> In the absence of devm_clk_get_prepared(), is it better that several
> frameworks (or drivers) open code it?

It probably depends on where you stand on power management and power
efficiency issues. Personally, I would like to see more effort put
into drivers to make them more power efficient, and I believe in the
coming years, power efficiency is going to become a big issue.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From catalin.marinas at arm.com  Mon Aug  2 09:46:22 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 17:46:22 +0100
Subject: [PATCH v2 3/3] ACPI: Add memory semantics to acpi_os_map_memory()
In-Reply-To: <20210802152359.12623-4-lorenzo.pieralisi@arm.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-4-lorenzo.pieralisi@arm.com>
Message-ID: <20210802164622.GJ18685@arm.com>

On Mon, Aug 02, 2021 at 04:23:59PM +0100, Lorenzo Pieralisi wrote:
> The memory attributes attached to memory regions depend on architecture
> specific mappings.
> 
> For some memory regions, the attributes specified by firmware (eg
> uncached) are not sufficient to determine how a memory region should be
> mapped by an OS (for instance a region that is define as uncached in
> firmware can be mapped as Normal or Device memory on arm64) and
> therefore the OS must be given control on how to map the region to match
> the expected mapping behaviour (eg if a mapping is requested with memory
> semantics, it must allow unaligned accesses).
> 
> Rework acpi_os_map_memory() and acpi_os_ioremap() back-end to split
> them into two separate code paths:
> 
> acpi_os_memmap() -> memory semantics
> acpi_os_ioremap() -> MMIO semantics
> 
> The split allows the architectural implementation back-ends to detect
> the default memory attributes required by the mapping in question
> (ie the mapping API defines the semantics memory vs MMIO) and map the
> memory accordingly.
> 
> Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702 at arm.com
> Tested-by: Hanjun Guo <guohanjun at huawei.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Acked-by: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Will Deacon <will at kernel.org>
> Cc: Hanjun Guo <guohanjun at huawei.com>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>

For the arm64 bits:

Acked-by: Catalin Marinas <catalin.marinas at arm.com>

I presume this will get merged via the ACPI tree?

-- 
Catalin


From mark.rutland at arm.com  Mon Aug  2 09:48:45 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 17:48:45 +0100
Subject: [PATCH 2/2] arm64: stacktrace: avoid tracing arch_stack_walk()
In-Reply-To: <20210802164845.45506-1-mark.rutland@arm.com>
References: <20210802164845.45506-1-mark.rutland@arm.com>
Message-ID: <20210802164845.45506-3-mark.rutland@arm.com>

When the function_graph tracer is in use, arch_stack_walk() may unwind
the stack incorrectly, erroneously reporting itself, missing the final
entry which is being traced, and reporting all traced entries between
these off-by-one from where they should be.

When ftrace hooks a function return, the original return address is
saved to the fgraph ret_stack, and the return address  in the LR (or the
function's frame record) is replaced with `return_to_handler`.

When arm64's unwinder encounter frames returning to `return_to_handler`,
it finds the associated original return address from the fgraph ret
stack, assuming the most recent `ret_to_hander` entry on the stack
corresponds to the most recent entry in the fgraph ret stack, and so on.

When arch_stack_walk() is used to dump the current task's stack, it
starts from the caller of arch_stack_walk(). However, arch_stack_walk()
can be traced, and so may push an entry on to the fgraph ret stack,
leaving the fgraph ret stack offset by one from the expected position.

This can be seen when dumping the stack via /proc/self/stack, where
enabling the graph tracer results in an unexpected
`stack_trace_save_tsk` entry at the start of the trace, and `el0_svc`
missing form the end of the trace.

This patch fixes this by marking arch_stack_walk() as notrace, as we do
for all other functions on the path to ftrace_graph_get_ret_stack().
While a few helper functions are not marked notrace, their calls/returns
are balanced, and will have no observable effect when examining the
fgraph ret stack.

It is possible for the an exeption boundary to cause a similar offset if
the return address of the interrupted context was in the LR. Fixing
those case will require some more substantial rework, and is left for
subsequent patches.

Before:

| # cat /proc/self/stack
| [<0>] proc_pid_stack+0xc4/0x140
| [<0>] proc_single_show+0x6c/0x120
| [<0>] seq_read_iter+0x240/0x4e0
| [<0>] seq_read+0xe8/0x140
| [<0>] vfs_read+0xb8/0x1e4
| [<0>] ksys_read+0x74/0x100
| [<0>] __arm64_sys_read+0x28/0x3c
| [<0>] invoke_syscall+0x50/0x120
| [<0>] el0_svc_common.constprop.0+0xc4/0xd4
| [<0>] do_el0_svc+0x30/0x9c
| [<0>] el0_svc+0x2c/0x54
| [<0>] el0t_64_sync_handler+0x1a8/0x1b0
| [<0>] el0t_64_sync+0x198/0x19c
| # echo function_graph > /sys/kernel/tracing/current_tracer
| # cat /proc/self/stack
| [<0>] stack_trace_save_tsk+0xa4/0x110
| [<0>] proc_pid_stack+0xc4/0x140
| [<0>] proc_single_show+0x6c/0x120
| [<0>] seq_read_iter+0x240/0x4e0
| [<0>] seq_read+0xe8/0x140
| [<0>] vfs_read+0xb8/0x1e4
| [<0>] ksys_read+0x74/0x100
| [<0>] __arm64_sys_read+0x28/0x3c
| [<0>] invoke_syscall+0x50/0x120
| [<0>] el0_svc_common.constprop.0+0xc4/0xd4
| [<0>] do_el0_svc+0x30/0x9c
| [<0>] el0t_64_sync_handler+0x1a8/0x1b0
| [<0>] el0t_64_sync+0x198/0x19c

After:

| # cat /proc/self/stack
| [<0>] proc_pid_stack+0xc4/0x140
| [<0>] proc_single_show+0x6c/0x120
| [<0>] seq_read_iter+0x240/0x4e0
| [<0>] seq_read+0xe8/0x140
| [<0>] vfs_read+0xb8/0x1e4
| [<0>] ksys_read+0x74/0x100
| [<0>] __arm64_sys_read+0x28/0x3c
| [<0>] invoke_syscall+0x50/0x120
| [<0>] el0_svc_common.constprop.0+0xc4/0xd4
| [<0>] do_el0_svc+0x30/0x9c
| [<0>] el0_svc+0x2c/0x54
| [<0>] el0t_64_sync_handler+0x1a8/0x1b0
| [<0>] el0t_64_sync+0x198/0x19c
| # echo function_graph > /sys/kernel/tracing/current_tracer
| # cat /proc/self/stack
| [<0>] proc_pid_stack+0xc4/0x140
| [<0>] proc_single_show+0x6c/0x120
| [<0>] seq_read_iter+0x240/0x4e0
| [<0>] seq_read+0xe8/0x140
| [<0>] vfs_read+0xb8/0x1e4
| [<0>] ksys_read+0x74/0x100
| [<0>] __arm64_sys_read+0x28/0x3c
| [<0>] invoke_syscall+0x50/0x120
| [<0>] el0_svc_common.constprop.0+0xc4/0xd4
| [<0>] do_el0_svc+0x30/0x9c
| [<0>] el0_svc+0x2c/0x54
| [<0>] el0t_64_sync_handler+0x1a8/0x1b0
| [<0>] el0t_64_sync+0x198/0x19c

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/stacktrace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b83c8d911930..8982a2b78acf 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -218,7 +218,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
 
 #ifdef CONFIG_STACKTRACE
 
-noinline void arch_stack_walk(stack_trace_consume_fn consume_entry,
+noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 			      void *cookie, struct task_struct *task,
 			      struct pt_regs *regs)
 {
-- 
2.11.0



From mark.rutland at arm.com  Mon Aug  2 09:48:44 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 17:48:44 +0100
Subject: [PATCH 1/2] arm64: stacktrace: fix comment
In-Reply-To: <20210802164845.45506-1-mark.rutland@arm.com>
References: <20210802164845.45506-1-mark.rutland@arm.com>
Message-ID: <20210802164845.45506-2-mark.rutland@arm.com>

Due to a copy-paste error, we describe struct stackframe::pc as a
snapshot of the `fp` field rather than the `lr` field.

Fix the comment.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/stacktrace.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 1801399204d7..8aebc00c1718 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -35,7 +35,7 @@ struct stack_info {
  * accounting information necessary for robust unwinding.
  *
  * @fp:          The fp value in the frame record (or the real fp)
- * @pc:          The fp value in the frame record (or the real lr)
+ * @pc:          The lr value in the frame record (or the real lr)
  *
  * @stacks_done: Stacks which have been entirely unwound, for which it is no
  *               longer valid to unwind to.
-- 
2.11.0



From mark.rutland at arm.com  Mon Aug  2 09:48:43 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon,  2 Aug 2021 17:48:43 +0100
Subject: [PATCH 0/2] arm64: stacktrace: minor fixes
Message-ID: <20210802164845.45506-1-mark.rutland@arm.com>

These patches address a couple of minor issues I spotted while reviewing
arm64's stacktrace code. Patch 1 is a simple comment fix, and patch 2
addresses an imbalance across the main stack and the fgraph return
stack.

Thanks,
Mark

Mark Rutland (2):
  arm64: stacktrace: fix comment
  arm64: stacktrace: avoid tracing arch_stack_walk()

 arch/arm64/include/asm/stacktrace.h | 2 +-
 arch/arm64/kernel/stacktrace.c      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

-- 
2.11.0



From segher at kernel.crashing.org  Mon Aug  2 09:47:47 2021
From: segher at kernel.crashing.org (Segher Boessenkool)
Date: Mon, 2 Aug 2021 11:47:47 -0500
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <YQeT5QRXc3CzK9nL@localhost.localdomain>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
 <20210801201336.2224111-3-adobriyan@gmail.com>
 <20210801213247.GM1583@gate.crashing.org>
 <YQeT5QRXc3CzK9nL@localhost.localdomain>
Message-ID: <20210802164747.GN1583@gate.crashing.org>

On Mon, Aug 02, 2021 at 09:42:45AM +0300, Alexey Dobriyan wrote:
> On Sun, Aug 01, 2021 at 04:32:47PM -0500, Segher Boessenkool wrote:
> > On Sun, Aug 01, 2021 at 11:13:36PM +0300, Alexey Dobriyan wrote:
> > > In theory, it enables "leakage" of userspace headers into kernel which
> > > may present licensing problem.
> > 
> > > -NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
> > > +NOSTDINC_FLAGS += -nostdinc
> > 
> > This is removing the compiler's own include files.  These are required
> > for all kinds of basic features, and required to be compliant to the C
> > standard at all.
> 
> No they are not required.

This is false, they *are* required, whenever you want to use these
features.  If you do not include the required headers you get undefined
behaviour.

> Kernel uses its own bool, uintptr_t and
> static_assert, memset(), CHAR_BIT.

Yes, and it occasionally gets it wrong.  Great fun.  See c46bbf5d2def
for the latest episode in this saga.  (Yes I know this is uapi so maybe
not the best example here, but it isn't like the kernel gets such things
wrong so often these days ;-) )

The kernel *cannot* make up its own types for this.  It has to use the
types it is required to use (by C, by the ABIs, etc.)  So why
reimplement this?

> noreturn, alignas newest C standard
> are next.

What is wrong with <stdalign.h> and <stdnoreturn.h>?

> This version changelog didn't mention but kernel would use
> -ffreestanding too if not other problems with the flag.

It is still true for freestanding C implementations, you just get a
severely reduced standard library,

> > These are not "userspace headers", that is what
> > -nostdinc takes care of already.
> 
> They are userspace headers in the sense they are external to the project
> just like userspace programs are external to the kernel.

So you are going to rewrite all of the rest of GCC inside the kernel
project as well?

> > In the case of GCC all these headers are GPL-with-runtime-exception, so
> > claiming this can cause licensing problems is fearmongering.
> 
> I agree licensing problem doesn't really exist.
> It would take gcc drop-in replacement with authors insane enough to not
> license standard headers properly.

There does still not exist a drop-in replacement for GCC, not if you
look closely and/or rely on details (like the kernel does).  Some of the
differences are hidden by "linux/compiler-*.h", but hardly all.

> > I strongly advise against doing this.
> 
> Kernel chose to be self-contained.

That is largely historical, imo.  Nowadays this is less necessary.

Also, the kernel chose to *do* use the compiler include files.  It is
you who wants to abolish that here.

> -isystem removal makes sense then.

-nostdinc -isystem $(shell $(CC) -print-file-name=include)  makes sense
for that: you do indeed not want the userspace headers.  Maiming the
compiler (by removing some of its functional parts, namely, its generic
headers) does not make sense.

> It will be used for intrinsics where necessary.

Like, everywhere.


Segher


From catalin.marinas at arm.com  Mon Aug  2 09:52:14 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 17:52:14 +0100
Subject: [PATCH v2 2/2] KVM: arm64: Unregister HYP sections from kmemleak
 in protected mode
In-Reply-To: <20210802123830.2195174-3-maz@kernel.org>
References: <20210802123830.2195174-1-maz@kernel.org>
 <20210802123830.2195174-3-maz@kernel.org>
Message-ID: <20210802165214.GK18685@arm.com>

On Mon, Aug 02, 2021 at 01:38:30PM +0100, Marc Zyngier wrote:
> Booting a KVM host in protected mode with kmemleak quickly results
> in a pretty bad crash, as kmemleak doesn't know that the HYP sections
> have been taken away. This is specially true for the BSS section,
> which is part of the kernel BSS section and registered at boot time
> by kmemleak itself.
> 
> Unregister the HYP part of the BSS before making that section
> HYP-private. The rest of the HYP-specific data is obtained via
> the page allocator or lives in other sections, none of which is
> subjected to kmemleak.
> 
> Fixes: 90134ac9cabb ("KVM: arm64: Protect the .hyp sections from the host")
> Reviewed-by: Quentin Perret <qperret at google.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: stable at vger.kernel.org # 5.13

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Mon Aug  2 09:52:39 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 17:52:39 +0100
Subject: [PATCH v2 1/2] arm64: Move .hyp.rodata outside of the
 _sdata.._edata range
In-Reply-To: <20210802123830.2195174-2-maz@kernel.org>
References: <20210802123830.2195174-1-maz@kernel.org>
 <20210802123830.2195174-2-maz@kernel.org>
Message-ID: <20210802165238.GL18685@arm.com>

On Mon, Aug 02, 2021 at 01:38:29PM +0100, Marc Zyngier wrote:
> The HYP rodata section is currently lumped together with the BSS,
> which isn't exactly what is expected (it gets registered with
> kmemleak, for example).
> 
> Move it away so that it is actually marked RO. As an added
> benefit, it isn't registered with kmemleak anymore.
> 
> Fixes: 380e18ade4a5 ("KVM: arm64: Introduce a BSS section for use at Hyp")
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Cc: stable at vger.kernel.org #5.13

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From broonie at kernel.org  Mon Aug  2 09:53:21 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Aug 2021 17:53:21 +0100
Subject: [PATCH 1/2] arm64: stacktrace: fix comment
In-Reply-To: <20210802164845.45506-2-mark.rutland@arm.com>
References: <20210802164845.45506-1-mark.rutland@arm.com>
 <20210802164845.45506-2-mark.rutland@arm.com>
Message-ID: <20210802165321.GK4668@sirena.org.uk>

On Mon, Aug 02, 2021 at 05:48:44PM +0100, Mark Rutland wrote:
> Due to a copy-paste error, we describe struct stackframe::pc as a
> snapshot of the `fp` field rather than the `lr` field.
> 
> Fix the comment.

Reviewed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/06c226e8/attachment.sig>

From catalin.marinas at arm.com  Mon Aug  2 09:54:23 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 2 Aug 2021 17:54:23 +0100
Subject: [PATCH] arm64: fix compat syscall return truncation
In-Reply-To: <20210802104200.21390-1-mark.rutland@arm.com>
References: <20210802104200.21390-1-mark.rutland@arm.com>
Message-ID: <20210802165422.GM18685@arm.com>

On Mon, Aug 02, 2021 at 11:42:00AM +0100, Mark Rutland wrote:
> Due to inconsistencies in the way we manipulate compat GPRs, we have a
> few issues today:
> 
> * For audit and tracing, where error codes are handled as a (native)
>   long, negative error codes are expected to be sign-extended to the
>   native 64-bits, or they may fail to be matched correctly. Thus a
>   syscall which fails with an error may erroneously be identified as
>   failing.
> 
> * For ptrace, *all* compat return values should be sign-extended for
>   consistency with 32-bit arm, but we currently only do this for
>   negative return codes.
> 
> * As we may transiently set the upper 32 bits of some compat GPRs while
>   in the kernel, these can be sampled by perf, which is somewhat
>   confusing. This means that where a syscall returns a pointer above 2G,
>   this will be sign-extended, but will not be mistaken for an error as
>   error codes are constrained to the inclusive range [-4096, -1] where
>   no user pointer can exists.
> 
> To fix all of these, we must consistently use helpers to get/set the
> compat GPRs, ensuring that we never write the upper 32 bits of the
> return code, and always sign-extend when reading the return code.  This
> patch does so, with the following changes:
> 
> * We re-organise syscall_get_return_value() to always sign-extend for
>   compat tasks, and reimplement syscall_get_error() atop. We update
>   syscall_trace_exit() to use syscall_get_return_value().
> 
> * We consistently use syscall_set_return_value() to set the return
>   value, ensureing the upper 32 bits are never set unexpectedly.
> 
> * As the core audit code currently uses regs_return_value() rather than
>   syscall_get_return_value(), we special-case this for
>   compat_user_mode(regs) such that this will do the right thing. Going
>   forward, we should try to move the core audit code over to
>   syscall_get_return_value().
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Reported-by: He Zhe <zhe.he at windriver.com>
> Reported-by: weiyuchen <weiyuchen3 at huawei.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

(to the best of my knowledge, I can't guarantee all cases have been
covered)


From mathieu.poirier at linaro.org  Mon Aug  2 10:03:07 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 2 Aug 2021 11:03:07 -0600
Subject: [RFC PATCH 6/6] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <YQgGjlWtbaNApkp6@kernel.org>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-7-james.clark@arm.com>
 <YQgGjlWtbaNApkp6@kernel.org>
Message-ID: <20210802170307.GA3050918@p14s>

On Mon, Aug 02, 2021 at 11:51:58AM -0300, Arnaldo Carvalho de Melo wrote:
> Em Thu, Jul 29, 2021 at 04:58:05PM +0100, James Clark escreveu:
> > Currently decode will silently fail if no binary data is available for
> > the decode. This is made worse if only partial data is available because
> > the decode will appear to work, but any trace from that missing DSO will
> > silently not be generated.
> > 
> > Add a UI popup once if there is any data missing, and then warn in the
> > bottom left for each individual DSO that's missing.
> 
> Looks ok to me (the last 3 patches in this series, the rest I applied
> already), can I get some Acked-by/Reviewed-by from the CoreSight people?
>

I have a substantial backlog of patches to go through and I will be away for the
next two weeks.  As such it will be some time before I get to review this set.

Regards,
Mathieu

> Thanks,
> 
> - Arnaldo
>  
> > Signed-off-by: James Clark <james.clark at arm.com>
> > ---
> >  tools/perf/util/cs-etm.c | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> > index 32ad92d3e454..e6851260d059 100644
> > --- a/tools/perf/util/cs-etm.c
> > +++ b/tools/perf/util/cs-etm.c
> > @@ -746,8 +746,16 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
> >  
> >  	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
> >  
> > -	if (len <= 0)
> > +	if (len <= 0) {
> > +		ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n");
> > +		if (!al.map->dso->auxtrace_warned) {
> > +			pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
> > +				    address,
> > +				    al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
> > +			al.map->dso->auxtrace_warned = true;
> > +		}
> >  		return 0;
> > +	}
> >  
> >  	return len;
> >  }
> > -- 
> > 2.28.0
> > 
> 
> -- 
> 
> - Arnaldo


From mikelley at microsoft.com  Mon Aug  2 10:13:03 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Mon, 2 Aug 2021 17:13:03 +0000
Subject: [PATCH v11 3/5] arm64: hyperv: Initialize hypervisor on boot
In-Reply-To: <20210802162623.GC59710@C02TD0UTHF1T.local>
References: <1626793023-13830-1-git-send-email-mikelley@microsoft.com>
 <1626793023-13830-4-git-send-email-mikelley@microsoft.com>
 <20210802162623.GC59710@C02TD0UTHF1T.local>
Message-ID: <MWHPR21MB15930692A0EF42DC49EAEE83D7EF9@MWHPR21MB1593.namprd21.prod.outlook.com>

From: Mark Rutland <mark.rutland at arm.com> Sent: Monday, August 2, 2021 9:26 AM
> 
> On Tue, Jul 20, 2021 at 07:57:01AM -0700, Michael Kelley wrote:
> > Add ARM64-specific code to initialize the Hyper-V
> > hypervisor when booting as a guest VM.
> >
> > This code is built only when CONFIG_HYPERV is enabled.
> >
> > Signed-off-by: Michael Kelley <mikelley at microsoft.com>
> > ---
> >  arch/arm64/hyperv/Makefile   |  2 +-
> >  arch/arm64/hyperv/mshyperv.c | 83 ++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 84 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/arm64/hyperv/mshyperv.c
> >
> > diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
> > index 1697d30..87c31c0 100644
> > --- a/arch/arm64/hyperv/Makefile
> > +++ b/arch/arm64/hyperv/Makefile
> > @@ -1,2 +1,2 @@
> >  # SPDX-License-Identifier: GPL-2.0
> > -obj-y		:= hv_core.o
> > +obj-y		:= hv_core.o mshyperv.o
> > diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
> > new file mode 100644
> > index 0000000..2811fd0
> > --- /dev/null
> > +++ b/arch/arm64/hyperv/mshyperv.c
> > @@ -0,0 +1,83 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +/*
> > + * Core routines for interacting with Microsoft's Hyper-V hypervisor,
> > + * including hypervisor initialization.
> > + *
> > + * Copyright (C) 2021, Microsoft, Inc.
> > + *
> > + * Author : Michael Kelley <mikelley at microsoft.com>
> > + */
> > +
> > +#include <linux/types.h>
> > +#include <linux/acpi.h>
> > +#include <linux/export.h>
> > +#include <linux/errno.h>
> > +#include <linux/version.h>
> > +#include <linux/cpuhotplug.h>
> > +#include <asm/mshyperv.h>
> > +
> > +static bool hyperv_initialized;
> > +
> > +static int __init hyperv_init(void)
> > +{
> > +	struct hv_get_vp_registers_output	result;
> > +	u32	a, b, c, d;
> > +	u64	guest_id;
> > +	int	ret;
> 
> As Marc suggests, before looking at the FADT, you need something like:
> 
> 	/*
> 	 * Hyper-V VMs always have ACPI.
> 	 */
> 	if (acpi_disabled)
> 		return 0;
> 
> ... where `acpi_disabled` is defined in <linux/acpi.h> (or via its
> includes), so you don't need to include any additional headers.
> 
> > +
> > +	/*
> > +	 * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will
> > +	 * have the string "MsHyperV".
> > +	 */
> > +	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
> > +		return -EINVAL;
> 
> As Marc suggests, it's no an error for a platform to not have Hyper-V,
> so returning 0 in tihs case would be preferable.
> 
> Otherwise this looks fine to me.
> 

Thanks Marc and Mark.  Good point that the code should cleanly
handle the case where a kernel is built with CONFIG_HYPERV but
running somewhere other than as a Hyper-V guest.

Michael




From andy.shevchenko at gmail.com  Mon Aug  2 10:13:05 2021
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Mon, 2 Aug 2021 20:13:05 +0300
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <20210802163824.GK22278@shell.armlinux.org.uk>
References: <YPlfcbkxiBmB+vw1@kunai>
 <CAHp75VfC=s12Unw3+Cn0ag71mM5i90=Jbwj4nYwB5cPKiUTRSA@mail.gmail.com>
 <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
 <20210802094810.GJ22278@shell.armlinux.org.uk>
 <20210802152755.ibisunvibmwhiyry@pengutronix.de>
 <20210802163824.GK22278@shell.armlinux.org.uk>
Message-ID: <CAHp75VcpA0vOwN8gBj2iikXW2dw+KCgZEM=QJ5Jx6UWqww=iCw@mail.gmail.com>

On Mon, Aug 2, 2021 at 7:38 PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:
> On Mon, Aug 02, 2021 at 05:27:55PM +0200, Uwe Kleine-K?nig wrote:
> > Hello Russell,
> > On Mon, Aug 02, 2021 at 10:48:10AM +0100, Russell King (Oracle) wrote:

...

> > > There have been several different approaches to wrapping things up,
> > > but here's a question: should we make it easier to do the lazy thing
> > > (get+enable) or should we make it easier to be power efficient?
> > > Shouldn't we be encouraging people to write power efficient drivers?
> >
> > Yeah, sounds compelling, but I wonder if that's of practical importance.
> > How many driver authors do you expect to lure into making a better
> > driver just because devm_clk_get_prepared() doesn't exist? In contrast:
> > How many drivers become simpler with devm_clk_get_prepared() and so
> > it becomes easier to maintain them and easier to spot bugs?
> > In the absence of devm_clk_get_prepared(), is it better that several
> > frameworks (or drivers) open code it?
>
> It probably depends on where you stand on power management and power
> efficiency issues. Personally, I would like to see more effort put
> into drivers to make them more power efficient, and I believe in the
> coming years, power efficiency is going to become a big issue.

While in the ideal world I 100% agree with the approach, IRL we have
to deal with constantly degrading quality of the code and instead of
thinking about power management and efficiency the absence of APIs
such as discussed provokes not only creating the power management
inefficient code, but also memory leaks here and there.

-- 
With Best Regards,
Andy Shevchenko


From broonie at kernel.org  Mon Aug  2 10:18:38 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Aug 2021 18:18:38 +0100
Subject: [PATCH 2/2] arm64: stacktrace: avoid tracing arch_stack_walk()
In-Reply-To: <20210802164845.45506-3-mark.rutland@arm.com>
References: <20210802164845.45506-1-mark.rutland@arm.com>
 <20210802164845.45506-3-mark.rutland@arm.com>
Message-ID: <20210802171838.GL4668@sirena.org.uk>

On Mon, Aug 02, 2021 at 05:48:45PM +0100, Mark Rutland wrote:
> When the function_graph tracer is in use, arch_stack_walk() may unwind
> the stack incorrectly, erroneously reporting itself, missing the final
> entry which is being traced, and reporting all traced entries between
> these off-by-one from where they should be.

Reviwed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/eb32ae0a/attachment.sig>

From monstr at monstr.eu  Mon Aug  2 10:21:58 2021
From: monstr at monstr.eu (Michal Simek)
Date: Mon, 2 Aug 2021 19:21:58 +0200
Subject: [PATCH 4/4] arm: dts: zynq: Replace 'io-standard' with
 'power-source' property
In-Reply-To: <CACRpkdZu2-EE1hqJ4nVA5uxaPuJRGWDH_ciKxRvrNncQ2Pyd5w@mail.gmail.com>
References: <1626868353-96475-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <1626868353-96475-5-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <YQMIhBPwcNw1YqMq@robh.at.kernel.org>
 <CACRpkdYrHTMLL_CQi0BoNZsXV3=2dBK38pkvd+EEkuPrzoG_Cw@mail.gmail.com>
 <2f5d9197-4a5e-08b5-7e47-595d337478d2@xilinx.com>
 <CACRpkdZu2-EE1hqJ4nVA5uxaPuJRGWDH_ciKxRvrNncQ2Pyd5w@mail.gmail.com>
Message-ID: <CAHTX3dLbRcfBhaqfbcK=RbQOAG5uxpSzHmMx7aP+QYHaP-idew@mail.gmail.com>

po 2. 8. 2021 v 15:20 odes?latel Linus Walleij
<linus.walleij at linaro.org> napsal:
>
> On Fri, Jul 30, 2021 at 2:46 PM Michal Simek <michal.simek at xilinx.com> wrote:
>
> > Linux Zynq pinctrl driver and in tree dts files are using io-standard
> > properties at least from 2015.
>
> Ooops my wrong.
>
> What about supporting both the new property and io-standard as
> a fallback, simply?

That's exactly what I have Sai to do and PIN_CONFIG_IOSTANDARD is still there.

https://lore.kernel.org/linux-arm-kernel/1626868353-96475-1-git-send-email-lakshmi.sai.krishna.potthuri at xilinx.com/T/#md7d304d9d8f746e51d909237b9073f2ae8930543

But IIRC I have also asked to show any warning message when io
standard property is used to convert to new property.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From robh at kernel.org  Mon Aug  2 10:29:35 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 11:29:35 -0600
Subject: [PATCH 4/4] arm: dts: zynq: Replace 'io-standard' with
 'power-source' property
In-Reply-To: <bc5185eb-8051-89ca-4a5f-c4e5fc90a7f2@xilinx.com>
References: <1626868353-96475-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <1626868353-96475-5-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <YQMIhBPwcNw1YqMq@robh.at.kernel.org>
 <bc5185eb-8051-89ca-4a5f-c4e5fc90a7f2@xilinx.com>
Message-ID: <CAL_Jsq+281knebcN--jQgYWtDQO4OV6ZO5CvnYpaYqrAaiGmPQ@mail.gmail.com>

On Thu, Jul 29, 2021 at 10:59 PM Michal Simek <michal.simek at xilinx.com> wrote:
>
>
>
> On 7/29/21 9:59 PM, Rob Herring wrote:
> > On Wed, Jul 21, 2021 at 05:22:33PM +0530, Sai Krishna Potthuri wrote:
> >> Replace 'io-standard' property with 'power-source' property in all zynq dts
> >> files to be in sync with Zynq pinctrl driver.
> >>
> >> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> >> ---
> >>  arch/arm/boot/dts/zynq-ebaz4205.dts |  8 ++++----
> >>  arch/arm/boot/dts/zynq-microzed.dts |  2 +-
> >>  arch/arm/boot/dts/zynq-zc702.dts    | 20 ++++++++++----------
> >>  arch/arm/boot/dts/zynq-zc706.dts    | 18 +++++++++---------
> >>  4 files changed, 24 insertions(+), 24 deletions(-)
> >>
> >> diff --git a/arch/arm/boot/dts/zynq-ebaz4205.dts b/arch/arm/boot/dts/zynq-ebaz4205.dts
> >> index b0b836aedd76..be7eae611fb7 100644
> >> --- a/arch/arm/boot/dts/zynq-ebaz4205.dts
> >> +++ b/arch/arm/boot/dts/zynq-ebaz4205.dts
> >> @@ -57,7 +57,7 @@
> >>
> >>              conf {
> >>                      groups = "gpio0_20_grp", "gpio0_32_grp";
> >> -                    io-standard = <3>;
> >> +                    power-source = <3>;
> >
> > This will break using a new DT with a kernel without patch 3.
> >
>
> What do you suggest? Not to update any old DT?

Your options are don't change the dts files, patch 3 needs to go to
stable kernels, or you document the breakage (if you don't care).

Rob


From ojaswin98 at gmail.com  Mon Aug  2 10:42:09 2021
From: ojaswin98 at gmail.com (Ojaswin Mujoo)
Date: Mon,  2 Aug 2021 23:12:09 +0530
Subject: [PATCH v2 0/2] staging: vchiq: Fixups to Kconfig
Message-ID: <cover.1627925241.git.ojaswin98@gmail.com>

Hi everyone,

This patchset performs some minor fixups to the config options defined in
/staging/vc04_services/Kconfig. 

Summary of the patches:

Patch 1: Makes BCM2835_VCHIQ imply VCHIQ_CDEV to make the behavior more
         compatible to how it was before VCHIQ_CDEV was introduced (in
         [1]).
Patch 2: Add some more details to the configs' help texts


Changes since v1 [2]:

*  As pre discussion with Greg and Stefan, used "imply" in BCM2835_VCHIQ
   instead of "default y" in VCHIQ_CDEV.
*  Added some more info in help texts of both the config options.

In patch 2, although the resources on VideoCore and vchiq are really
scattered around the internet, I've tried to keep the help text as
accurate as possible, as per my knowledge.
Please do let me know if anything is off in it and I'll fix it.

Thank you!
Ojaswin

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git/patch/?id=2b5930fb3dc06d86149071f9dc8b6992cac1c3aa

[2] https://lore.kernel.org/patchwork/cover/1469192/

Ojaswin Mujoo (2):
  staging: vchiq: Set $CONFIG_BCM2835_VCHIQ to imply $CONFIG_VCHIQ_CDEV
  staging: vchiq: Add details to Kconfig help texts

 drivers/staging/vc04_services/Kconfig | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

-- 
2.25.1



From ojaswin98 at gmail.com  Mon Aug  2 10:42:10 2021
From: ojaswin98 at gmail.com (Ojaswin Mujoo)
Date: Mon,  2 Aug 2021 23:12:10 +0530
Subject: [PATCH v2 1/2] staging: vchiq: Set $CONFIG_BCM2835_VCHIQ to imply
 $CONFIG_VCHIQ_CDEV
In-Reply-To: <cover.1627925241.git.ojaswin98@gmail.com>
References: <cover.1627925241.git.ojaswin98@gmail.com>
Message-ID: <da53207b24bc37f166b05c6835087becdc6b5b4d.1627925241.git.ojaswin98@gmail.com>

Before $CONFIG_VCHIQ_CDEV was defined, the vchiq cdev used to be created
unconditionally when CONFIG_BCM2835_VCHIQ=y. When an earlier commit
introduced the new config, its default behavior was set to disabled,
which might surprise some unsuspecting users.  Hence, modify
CONFIG_BCM2835_VCHIQ to imply CONFIG_VCHIQ_CDEV

Signed-off-by: Ojaswin Mujoo <ojaswin98 at gmail.com>
---
 drivers/staging/vc04_services/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/vc04_services/Kconfig b/drivers/staging/vc04_services/Kconfig
index 63caa6818d37..ad44b80f13ca 100644
--- a/drivers/staging/vc04_services/Kconfig
+++ b/drivers/staging/vc04_services/Kconfig
@@ -13,6 +13,7 @@ if BCM_VIDEOCORE
 
 config BCM2835_VCHIQ
 	tristate "BCM2835 VCHIQ"
+	imply VCHIQ_CDEV
 	help
 		Kernel to VideoCore communication interface for the
 		BCM2835 family of products.
-- 
2.25.1



From ojaswin98 at gmail.com  Mon Aug  2 10:42:11 2021
From: ojaswin98 at gmail.com (Ojaswin Mujoo)
Date: Mon,  2 Aug 2021 23:12:11 +0530
Subject: [PATCH v2 2/2] staging: vchiq: Add details to Kconfig help texts
In-Reply-To: <cover.1627925241.git.ojaswin98@gmail.com>
References: <cover.1627925241.git.ojaswin98@gmail.com>
Message-ID: <ab88d3222088aca29a319147b50a9d1e9f0f8b81.1627925241.git.ojaswin98@gmail.com>

Add some details to the Kconfig definitions of $CONFIG_VCHIQ_CDEV and
$CONFIG_BCM2835_VCHIQ to help make the motive behind the configs a bit
more clear.

Signed-off-by: Ojaswin Mujoo <ojaswin98 at gmail.com>
---
 drivers/staging/vc04_services/Kconfig | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/vc04_services/Kconfig b/drivers/staging/vc04_services/Kconfig
index ad44b80f13ca..cb7c82403dbf 100644
--- a/drivers/staging/vc04_services/Kconfig
+++ b/drivers/staging/vc04_services/Kconfig
@@ -15,18 +15,27 @@ config BCM2835_VCHIQ
 	tristate "BCM2835 VCHIQ"
 	imply VCHIQ_CDEV
 	help
-		Kernel to VideoCore communication interface for the
-		BCM2835 family of products.
-		Defaults to Y when the Broadcom Videocore services
-		are included in the build, N otherwise.
+		Broadcom BCM2835 and similar SoCs have a VPU called VideoCore. This config
+		enables the VCHIQ driver, which implements a messaging interface between
+		the kernel and the firmware running on VideoCore. Other drivers use this
+		interface to communicate to the VPU. More specifically, the VCHIQ driver is
+		used by audio/video and camera drivers as well as for implementing MMAL
+		API, which is in turn used by several multimedia services on the BCM2835
+		family of SoCs.
+		Defaults to Y when the Broadcom Videocore services are included in
+		the build, N otherwise.
 
 if BCM2835_VCHIQ
 
 config VCHIQ_CDEV
 	bool "VCHIQ Character Driver"
 	help
-		Enable the creation of VCHIQ character driver to help
-		communicate with the Videocore platform.
+		Enable the creation of VCHIQ character driver. The cdev exposes ioctls used
+		by userspace libraries and testing tools to interact with VideoCore, via
+		the VCHIQ core driver (Check BCM2835_VCHIQ for more info).
+		This can be set to 'N' if the VideoCore communication is not needed by
+		userspace but only by other kernel modules (like bcm2835-audio).  If not
+		sure, set this to 'Y'.
 
 endif
 
-- 
2.25.1



From catalin.marinas at arm.com  Mon Aug  2 11:06:17 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon,  2 Aug 2021 19:06:17 +0100
Subject: [PATCH] kselftest/arm64: Ignore check_gcr_el1_cswitch binary
In-Reply-To: <20210728173539.6231-1-broonie@kernel.org>
References: <20210728173539.6231-1-broonie@kernel.org>
Message-ID: <162792757024.21283.7196137698585667043.b4-ty@arm.com>

On Wed, 28 Jul 2021 18:35:39 +0100, Mark Brown wrote:
> We added check_gcr_el1_cswitch but did not ignore the generated binary,
> add it.

Applied to arm64 (for-next/kselftest), thanks!

[1/1] kselftest/arm64: Ignore check_gcr_el1_cswitch binary
      https://git.kernel.org/arm64/c/dac3ce63bffe

-- 
Catalin



From catalin.marinas at arm.com  Mon Aug  2 11:06:32 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon,  2 Aug 2021 19:06:32 +0100
Subject: [PATCH] arm64/sme: Document boot requirements for SME
In-Reply-To: <20210720204220.22951-1-broonie@kernel.org>
References: <20210720204220.22951-1-broonie@kernel.org>
Message-ID: <162792758531.21352.2745902381231565893.b4-ty@arm.com>

On Tue, 20 Jul 2021 21:42:20 +0100, Mark Brown wrote:
> Document our requirements for initialisation of the Scalable Matrix
> Extension (SME) at kernel start. While we do have the ability to handle
> mismatched vector lengths we will reject any late CPUs that can't support
> the minimum set we determine at boot so for clarity we document a
> requirement that all CPUs make the same vector length available.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/sme: Document boot requirements for SME
      https://git.kernel.org/arm64/c/a8caaa239c60

-- 
Catalin



From catalin.marinas at arm.com  Mon Aug  2 11:06:46 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon,  2 Aug 2021 19:06:46 +0100
Subject: [PATCH] arm64/sve: Make fpsimd_bind_task_to_cpu() static
In-Reply-To: <20210730165846.18558-1-broonie@kernel.org>
References: <20210730165846.18558-1-broonie@kernel.org>
Message-ID: <162792758532.21352.12357495715547060151.b4-ty@arm.com>

On Fri, 30 Jul 2021 17:58:46 +0100, Mark Brown wrote:
> This function is not referenced outside fpsimd.c so can be static, making
> it that little bit easier to follow what is called from where.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/sve: Make fpsimd_bind_task_to_cpu() static
      https://git.kernel.org/arm64/c/b24b5205099a

-- 
Catalin



From catalin.marinas at arm.com  Mon Aug  2 11:07:02 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon,  2 Aug 2021 19:07:02 +0100
Subject: [PATCH] arm64: unnecessary end 'return;' in void functions
In-Reply-To: <20210726123940.63232-1-wangborong@cdjrlc.com>
References: <20210726123940.63232-1-wangborong@cdjrlc.com>
Message-ID: <162792758531.21352.13618828441310922141.b4-ty@arm.com>

On Mon, 26 Jul 2021 20:39:40 +0800, Jason Wang wrote:
> The end 'return;' in a void function is useless and verbose. It can
> be removed safely.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: unnecessary end 'return;' in void functions
      https://git.kernel.org/arm64/c/8f1fbc975b86

-- 
Catalin



From catalin.marinas at arm.com  Mon Aug  2 11:07:54 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon,  2 Aug 2021 19:07:54 +0100
Subject: (subset) [PATCH 0/3] arm64: MTE cleanups
In-Reply-To: <20210714143843.56537-1-mark.rutland@arm.com>
References: <20210714143843.56537-1-mark.rutland@arm.com>
Message-ID: <162792763130.21542.6148745550396665864.b4-ty@arm.com>

On Wed, 14 Jul 2021 15:38:40 +0100, Mark Rutland wrote:
> While working on moving the MTE entry code over to C, I spotted a few things
> that could be improved more generally.
> 
> The first patch is a fix for a potential issue in some kernel configurations,
> the second avoids redundant work to generate and load a compile-time constant,
> and the third removes some redundant infrastructure for suprressing fault
> reporting which made the architectural fault handling code confusing.
> 
> [...]

Applied to arm64 (for-next/mte) and tweaked a bit because of the
conflicts. Thanks!

[2/3] arm64: kasan: mte: use a constant kernel GCR_EL1 value
      https://git.kernel.org/arm64/c/82868247897b
[3/3] arm64: kasan: mte: remove redundant mte_report_once logic
      https://git.kernel.org/arm64/c/767215030150

-- 
Catalin



From raagjadav at gmail.com  Mon Aug  2 11:09:02 2021
From: raagjadav at gmail.com (Raag Jadav)
Date: Mon,  2 Aug 2021 23:39:02 +0530
Subject: [PATCH] arm64: dts: ls1046a: fix eeprom entries
Message-ID: <1627927742-8675-1-git-send-email-raagjadav@gmail.com>

ls1046afrwy and ls1046ardb boards have CAT24C04[1] and CAT24C05[2]
eeproms respectively. Both are 4Kb (512 bytes) in size.
Remove multi-address entries, as we have auto-rollover support
in at24 driver.

[1] https://www.onsemi.com/pdf/datasheet/cat24c01-d.pdf
[2] https://www.onsemi.com/pdf/datasheet/cat24c03-d.pdf

Signed-off-by: Raag Jadav <raagjadav at gmail.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +-------
 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts  | 7 +------
 2 files changed, 2 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
index db3d303..83afe21 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
@@ -83,15 +83,9 @@
 			};
 
 			eeprom at 52 {
-				compatible = "atmel,24c512";
+				compatible = "atmel,24c04";
 				reg = <0x52>;
 			};
-
-			eeprom at 53 {
-				compatible = "atmel,24c512";
-				reg = <0x53>;
-			};
-
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
index 60acdf0..d220f98 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
@@ -59,14 +59,9 @@
 	};
 
 	eeprom at 52 {
-		compatible = "atmel,24c512";
+		compatible = "atmel,24c04";
 		reg = <0x52>;
 	};
-
-	eeprom at 53 {
-		compatible = "atmel,24c512";
-		reg = <0x53>;
-	};
 };
 
 &i2c3 {
-- 
2.7.4



From nathan at kernel.org  Mon Aug  2 11:18:32 2021
From: nathan at kernel.org (Nathan Chancellor)
Date: Mon, 2 Aug 2021 11:18:32 -0700
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <20210801201336.2224111-3-adobriyan@gmail.com>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
 <20210801201336.2224111-3-adobriyan@gmail.com>
Message-ID: <YQg2+C4Z98BMFucg@archlinux-ax161>

On Sun, Aug 01, 2021 at 11:13:36PM +0300, Alexey Dobriyan wrote:
> In theory, it enables "leakage" of userspace headers into kernel which
> may present licensing problem.
> 
> In practice, only stdarg.h was used, stdbool.h is trivial and SIMD
> intrinsics are contained to a few architectures and aren't global
> problem.
> 
> In general, kernel is very self contained code and -isystem removal
> will further isolate it from Ring Threeland influence.
> 
> nds32 keeps -isystem globally due to intrisics used in entrenched header.
> 
> -isystem is selectively reenabled for some files.
> 
> Not compile tested on hexagon.

With this series on top of v5.14-rc4 and a tangential patch to fix
another issue, ARCH=hexagon defconfig and allmodconfig show no issues.

Tested-by: Nathan Chancellor <nathan at kernel> # build (hexagon)

> Compile tested on:
> 
> alpha-allmodconfig alpha-allnoconfig alpha-defconfig arm64-allmodconfig
> arm64-allnoconfig arm64-defconfig arm-am200epdkit arm-aspeed_g4
> arm-aspeed_g5 arm-assabet arm-at91_dt arm-axm55xx arm-badge4 arm-bcm2835
> arm-cerfcube arm-clps711x arm-cm_x300 arm-cns3420vb arm-colibri_pxa270
> arm-colibri_pxa300 arm-collie arm-corgi arm-davinci_all arm-dove
> arm-ep93xx arm-eseries_pxa arm-exynos arm-ezx arm-footbridge arm-gemini
> arm-h3600 arm-h5000 arm-hackkit arm-hisi arm-imote2 arm-imx_v4_v5
> arm-imx_v6_v7 arm-integrator arm-iop32x arm-ixp4xx arm-jornada720
> arm-keystone arm-lart arm-lpc18xx arm-lpc32xx arm-lpd270 arm-lubbock
> arm-magician arm-mainstone arm-milbeaut_m10v arm-mini2440 arm-mmp2
> arm-moxart arm-mps2 arm-multi_v4t arm-multi_v5 arm-multi_v7 arm-mv78xx0
> arm-mvebu_v5 arm-mvebu_v7 arm-mxs arm-neponset arm-netwinder arm-nhk8815
> arm-omap1 arm-omap2plus arm-orion5x arm-oxnas_v6 arm-palmz72 arm-pcm027
> arm-pleb arm-pxa arm-pxa168 arm-pxa255-idp arm-pxa3xx arm-pxa910
> arm-qcom arm-realview arm-rpc arm-s3c2410 arm-s3c6400 arm-s5pv210
> arm-sama5 arm-shannon arm-shmobile arm-simpad arm-socfpga arm-spear13xx
> arm-spear3xx arm-spear6xx arm-spitz arm-stm32 arm-sunxi arm-tct_hammer
> arm-tegra arm-trizeps4 arm-u8500 arm-versatile arm-vexpress arm-vf610m4
> arm-viper arm-vt8500_v6_v7 arm-xcep arm-zeus csky-allmodconfig
> csky-allnoconfig csky-defconfig h8300-edosk2674 h8300-h8300h-sim
> h8300-h8s-sim i386-allmodconfig i386-allnoconfig i386-defconfig
> ia64-allmodconfig ia64-allnoconfig ia64-bigsur ia64-generic ia64-gensparse
> ia64-tiger ia64-zx1 m68k-amcore m68k-amiga m68k-apollo m68k-atari
> m68k-bvme6000 m68k-hp300 m68k-m5208evb m68k-m5249evb m68k-m5272c3
> m68k-m5275evb m68k-m5307c3 m68k-m5407c3 m68k-m5475evb m68k-mac
> m68k-multi m68k-mvme147 m68k-mvme16x m68k-q40 m68k-stmark2 m68k-sun3
> m68k-sun3x microblaze-allmodconfig microblaze-allnoconfig microblaze-mmu
> mips-ar7 mips-ath25 mips-ath79 mips-bcm47xx mips-bcm63xx mips-bigsur
> mips-bmips_be mips-bmips_stb mips-capcella mips-cavium_octeon mips-ci20
> mips-cobalt mips-cu1000-neo mips-cu1830-neo mips-db1xxx mips-decstation
> mips-decstation_64 mips-decstation_r4k mips-e55 mips-fuloong2e
> mips-gcw0 mips-generic mips-gpr mips-ip22 mips-ip27 mips-ip28 mips-ip32
> mips-jazz mips-jmr3927 mips-lemote2f mips-loongson1b mips-loongson1c
> mips-loongson2k mips-loongson3 mips-malta mips-maltaaprp mips-malta_kvm
> mips-malta_qemu_32r6 mips-maltasmvp mips-maltasmvp_eva mips-maltaup
> mips-maltaup_xpa mips-mpc30x mips-mtx1 mips-nlm_xlp mips-nlm_xlr
> mips-omega2p mips-pic32mzda mips-pistachio mips-qi_lb60 mips-rb532
> mips-rbtx49xx mips-rm200 mips-rs90 mips-rt305x mips-sb1250_swarm
> mips-tb0219 mips-tb0226 mips-tb0287 mips-vocore2 mips-workpad mips-xway
> nds32-allmodconfig nds32-allnoconfig nds32-defconfig nios2-10m50
> nios2-3c120 nios2-allmodconfig nios2-allnoconfig openrisc-allmodconfig
> openrisc-allnoconfig openrisc-or1klitex openrisc-or1ksim
> openrisc-simple_smp parisc-allnoconfig parisc-generic-32bit
> parisc-generic-64bit powerpc-acadia powerpc-adder875 powerpc-akebono
> powerpc-amigaone powerpc-arches powerpc-asp8347 powerpc-bamboo
> powerpc-bluestone powerpc-canyonlands powerpc-cell powerpc-chrp32
> powerpc-cm5200 powerpc-currituck powerpc-ebony powerpc-eiger
> powerpc-ep8248e powerpc-ep88xc powerpc-fsp2 powerpc-g5 powerpc-gamecube
> powerpc-ge_imp3a powerpc-holly powerpc-icon powerpc-iss476-smp
> powerpc-katmai powerpc-kilauea powerpc-klondike powerpc-kmeter1
> powerpc-ksi8560 powerpc-linkstation powerpc-lite5200b powerpc-makalu
> powerpc-maple powerpc-mgcoge powerpc-microwatt powerpc-motionpro
> powerpc-mpc512x powerpc-mpc5200 powerpc-mpc7448_hpc2 powerpc-mpc8272_ads
> powerpc-mpc8313_rdb powerpc-mpc8315_rdb powerpc-mpc832x_mds
> powerpc-mpc832x_rdb powerpc-mpc834x_itx powerpc-mpc834x_itxgp
> powerpc-mpc834x_mds powerpc-mpc836x_mds powerpc-mpc836x_rdk
> powerpc-mpc837x_mds powerpc-mpc837x_rdb powerpc-mpc83xx
> powerpc-mpc8540_ads powerpc-mpc8560_ads powerpc-mpc85xx_cds
> powerpc-mpc866_ads powerpc-mpc885_ads powerpc-mvme5100 powerpc-obs600
> powerpc-pasemi powerpc-pcm030 powerpc-pmac32 powerpc-powernv
> powerpc-ppa8548 powerpc-ppc40x powerpc-ppc44x powerpc-ppc64
> powerpc-ppc64e powerpc-ppc6xx powerpc-pq2fads powerpc-ps3
> powerpc-pseries powerpc-rainier powerpc-redwood powerpc-sam440ep
> powerpc-sbc8548 powerpc-sequoia powerpc-skiroot powerpc-socrates
> powerpc-storcenter powerpc-stx_gp3 powerpc-taishan powerpc-tqm5200
> powerpc-tqm8540 powerpc-tqm8541 powerpc-tqm8548 powerpc-tqm8555
> powerpc-tqm8560 powerpc-tqm8xx powerpc-walnut powerpc-warp powerpc-wii
> powerpc-xes_mpc85xx riscv-allmodconfig riscv-allnoconfig riscv-nommu_k210
> riscv-nommu_k210_sdcard riscv-nommu_virt riscv-rv32 s390-allmodconfig
> s390-allnoconfig s390-debug s390-zfcpdump sh-ap325rxa sh-apsh4a3a
> sh-apsh4ad0a sh-dreamcast sh-ecovec24 sh-ecovec24-romimage sh-edosk7705
> sh-edosk7760 sh-espt sh-hp6xx sh-j2 sh-kfr2r09 sh-kfr2r09-romimage
> sh-landisk sh-lboxre2 sh-magicpanelr2 sh-microdev sh-migor sh-polaris
> sh-r7780mp sh-r7785rp sh-rsk7201 sh-rsk7203 sh-rsk7264 sh-rsk7269
> sh-rts7751r2d1 sh-rts7751r2dplus sh-sdk7780 sh-sdk7786 sh-se7206 sh-se7343
> sh-se7619 sh-se7705 sh-se7712 sh-se7721 sh-se7722 sh-se7724 sh-se7750
> sh-se7751 sh-se7780 sh-secureedge5410 sh-sh03 sh-sh2007 sh-sh7710voipgw
> sh-sh7724_generic sh-sh7757lcr sh-sh7763rdp sh-sh7770_generic sh-sh7785lcr
> sh-sh7785lcr_32bit sh-shmin sh-shx3 sh-titan sh-ul2 sh-urquell
> sparc-allmodconfig sparc-allnoconfig sparc-sparc32 sparc-sparc64
> um-i386-allmodconfig um-i386-allnoconfig um-i386-defconfig
> um-x86_64-allmodconfig um-x86_64-allnoconfig x86_64-allmodconfig
> x86_64-allnoconfig x86_64-defconfig xtensa-allmodconfig xtensa-allnoconfig
> xtensa-audio_kc705 xtensa-cadence_csp xtensa-common xtensa-generic_kc705
> xtensa-iss xtensa-nommu_kc705 xtensa-smp_lx200 xtensa-virt
> xtensa-xip_kc705
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Michael Ellerman <mpe at ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> Cc: Paul Mackerras <paulus at samba.org>
> Cc: linuxppc-dev at lists.ozlabs.org
> Signed-off-by: Alexey Dobriyan <adobriyan at gmail.com>
> ---
>  Makefile                  | 2 +-
>  arch/arm64/lib/Makefile   | 2 ++
>  arch/nds32/Makefile       | 2 ++
>  arch/powerpc/lib/Makefile | 2 ++
>  crypto/Makefile           | 2 ++
>  lib/raid6/Makefile        | 4 ++++
>  6 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/Makefile b/Makefile
> index 6b555f64df06..b59053ec457a 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -979,7 +979,7 @@ KBUILD_CFLAGS += -falign-functions=64
>  endif
>  
>  # arch Makefile may override CC so keep this after arch Makefile is included
> -NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
> +NOSTDINC_FLAGS += -nostdinc
>  
>  # warn about C99 declaration after statement
>  KBUILD_CFLAGS += -Wdeclaration-after-statement
> diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
> index 6dd56a49790a..dcad998f12d7 100644
> --- a/arch/arm64/lib/Makefile
> +++ b/arch/arm64/lib/Makefile
> @@ -9,6 +9,8 @@ ifeq ($(CONFIG_KERNEL_MODE_NEON), y)
>  obj-$(CONFIG_XOR_BLOCKS)	+= xor-neon.o
>  CFLAGS_REMOVE_xor-neon.o	+= -mgeneral-regs-only
>  CFLAGS_xor-neon.o		+= -ffreestanding
> +# Enable <arm_neon.h>
> +CFLAGS_xor-neon.o		+= -isystem $(shell $(CC) -print-file-name=include)
>  endif
>  
>  lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
> diff --git a/arch/nds32/Makefile b/arch/nds32/Makefile
> index ccdca7142020..c17fc3a755c3 100644
> --- a/arch/nds32/Makefile
> +++ b/arch/nds32/Makefile
> @@ -9,6 +9,8 @@ endif
>  # Avoid generating FPU instructions
>  arch-y  += -mno-ext-fpu-sp -mno-ext-fpu-dp -mfloat-abi=soft
>  
> +# Enable <nds32_intrinsic.h>
> +KBUILD_CFLAGS	+= -isystem $(shell $(CC) -print-file-name=include)
>  KBUILD_CFLAGS	+= $(call cc-option, -mno-sched-prolog-epilog)
>  KBUILD_CFLAGS	+= -mcmodel=large
>  
> diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
> index 99a7c9132422..9e5d0f413b71 100644
> --- a/arch/powerpc/lib/Makefile
> +++ b/arch/powerpc/lib/Makefile
> @@ -65,5 +65,7 @@ obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o
>  
>  obj-$(CONFIG_ALTIVEC)	+= xor_vmx.o xor_vmx_glue.o
>  CFLAGS_xor_vmx.o += -maltivec $(call cc-option,-mabi=altivec)
> +# Enable <altivec.h>
> +CFLAGS_xor_vmx.o += -isystem $(shell $(CC) -print-file-name=include)
>  
>  obj-$(CONFIG_PPC64) += $(obj64-y)
> diff --git a/crypto/Makefile b/crypto/Makefile
> index 10526d4559b8..75ad9b040506 100644
> --- a/crypto/Makefile
> +++ b/crypto/Makefile
> @@ -117,6 +117,8 @@ aegis128-cflags-$(CONFIG_CC_IS_GCC) += -ffixed-q16 -ffixed-q17 -ffixed-q18 \
>  				       -ffixed-q28 -ffixed-q29 -ffixed-q30 \
>  				       -ffixed-q31
>  CFLAGS_aegis128-neon-inner.o += $(aegis128-cflags-y)
> +# Enable <arm_neon.h>
> +CFLAGS_aegis128-neon-inner.o += -isystem $(shell $(CC) -print-file-name=include)
>  CFLAGS_REMOVE_aegis128-neon-inner.o += -mgeneral-regs-only
>  aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o
>  endif
> diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile
> index c770570bfe4f..45e17619422b 100644
> --- a/lib/raid6/Makefile
> +++ b/lib/raid6/Makefile
> @@ -14,6 +14,8 @@ hostprogs	+= mktables
>  
>  ifeq ($(CONFIG_ALTIVEC),y)
>  altivec_flags := -maltivec $(call cc-option,-mabi=altivec)
> +# Enable <altivec.h>
> +altivec_flags += -isystem $(shell $(CC) -print-file-name=include)
>  
>  ifdef CONFIG_CC_IS_CLANG
>  # clang ppc port does not yet support -maltivec when -msoft-float is
> @@ -34,6 +36,8 @@ endif
>  # ARM/NEON intrinsics in a non C99-compliant environment (such as the kernel)
>  ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
>  NEON_FLAGS := -ffreestanding
> +# Enable <arm_neon.h>
> +NEON_FLAGS += -isystem $(shell $(CC) -print-file-name=include)
>  ifeq ($(ARCH),arm)
>  NEON_FLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon
>  endif
> -- 
> 2.31.1
> 


From clabbe.montjoie at gmail.com  Mon Aug  2 11:25:25 2021
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Mon, 2 Aug 2021 20:25:25 +0200
Subject: [PATCH] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <20210726152724.2281408-1-mudongliangabcd@gmail.com>
References: <20210726152724.2281408-1-mudongliangabcd@gmail.com>
Message-ID: <YQg4lehajLpQjyPd@Red>

Le Mon, Jul 26, 2021 at 11:27:12PM +0800, Dongliang Mu a ?crit :
> In sun8i_ce_hash_run, all the dma_mmap_sg/single will cause memory leak
> due to no corresponding unmap operation if errors happen.
> 
> Fix this by adding error handling part for all the dma_mmap_sg/single.
> 

I think it could be better worded, error handling is already there (but bad).

> Fixes: 56f6d5aee88d ("crypto: sun8i-ce - support hash algorithms")
> Signed-off-by: Dongliang Mu <mudongliangabcd at gmail.com>
> ---
>  .../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 28 +++++++++----------
>  1 file changed, 13 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> index 88194718a806..d454ad99deee 100644
> --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> @@ -286,16 +286,14 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
>  
>  	/* the padding could be up to two block. */
>  	buf = kzalloc(bs * 2, GFP_KERNEL | GFP_DMA);
> -	if (!buf) {
> -		err = -ENOMEM;
> -		goto theend;

Please keep all goto error for being consistent.

> -	}
> +	if (!buf)
> +		return -ENOMEM;
>  	bf = (__le32 *)buf;
>  
>  	result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
>  	if (!result) {
> -		err = -ENOMEM;
> -		goto theend;
> +		kfree(buf);
> +		return -ENOMEM;
>  	}
>  
>  	flow = rctx->flow;
> @@ -321,7 +319,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
>  	if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
>  		dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_result;
>  	}
>  
>  	len = areq->nbytes;
> @@ -334,7 +332,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
>  	if (len > 0) {
>  		dev_err(ce->dev, "remaining len %d\n", len);
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_unmap_sg;
>  	}
>  	addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE);
>  	cet->t_dst[0].addr = cpu_to_le32(addr_res);
> @@ -342,7 +340,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
>  	if (dma_mapping_error(ce->dev, addr_res)) {
>  		dev_err(ce->dev, "DMA map dest\n");
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_unmap_sg;
>  	}
>  
>  	byte_count = areq->nbytes;
> @@ -392,7 +390,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
>  	if (dma_mapping_error(ce->dev, addr_pad)) {
>  		dev_err(ce->dev, "DMA error on padding SG\n");
>  		err = -EINVAL;
> -		goto theend;
> +		goto err_addr_res;
>  	}
>  
>  	if (ce->variant->hash_t_dlen_in_bits)
> @@ -405,15 +403,15 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
>  	err = sun8i_ce_run_task(ce, flow, crypto_tfm_alg_name(areq->base.tfm));
>  
>  	dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE);
> +err_addr_res:
> +	dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> +err_unmap_sg:
>  	dma_unmap_sg(ce->dev, areq->src, sg_nents(areq->src),
>  		     DMA_TO_DEVICE);
> -	dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> -
> -
>  	memcpy(areq->result, result, algt->alg.hash.halg.digestsize);

The result should be copied only when everything is ok. Please add a "if (!err)"

Thanks for your work
Regards


From saravanak at google.com  Mon Aug  2 11:24:56 2021
From: saravanak at google.com (Saravana Kannan)
Date: Mon, 2 Aug 2021 11:24:56 -0700
Subject: [PATCH] clk: rk3308: make ddrphy4x clock critical
In-Reply-To: <162758560739.714452.5782743329332725952@swboyd.mtv.corp.google.com>
References: <BYAPR20MB24886765F888A9705CBEB70789E39@BYAPR20MB2488.namprd20.prod.outlook.com>
 <162734809017.2368309.7901135942001140161@swboyd.mtv.corp.google.com>
 <2634451.ElGaqSPkdT@diego>
 <162758560739.714452.5782743329332725952@swboyd.mtv.corp.google.com>
Message-ID: <CAGETcx8YYrkCV0UObtOqHUnS29Q-raC54KUh14wqyBDMJ4e46g@mail.gmail.com>

On Thu, Jul 29, 2021 at 12:06 PM Stephen Boyd <sboyd at kernel.org> wrote:
>
> Quoting Heiko St?bner (2021-07-28 02:53:54)
> > Am Dienstag, 27. Juli 2021, 03:08:10 CEST schrieb Stephen Boyd:
> > > Quoting Yunhao Tian (2021-07-21 05:48:16)
> > > > Currently, no driver support for DDR memory controller (DMC) is present,
> > > > as a result, no driver is explicitly consuming the ddrphy clock. This means
> > > > that VPLL1 (parent of ddr clock) will be shutdown if we enable
> > > > and then disable any child clock of VPLL1 (e.g. SCLK_I2S0_8CH_TX).
> > > > If VPLL1 is disabled, the whole system will freeze, because the DDR
> > > > controller will lose its clock. So, it's necessary to prevent VPLL1 from
> > > > shutting down, by marking the ddrphy4x CLK_IS_CRITICAL.
> > > >
> > > > This bug was discovered when I was porting rockchip_i2s_tdm driver to
> > > > mainline kernel from Rockchip 4.4 kernel. I guess that other Rockchip
> > > > SoCs without DMC driver may need the same patch. If this applies to
> > > > other devices, please let us know.
> > > >
> > > > Signed-off-by: Yunhao Tian <t123yh at outlook.com>
> > > > ---
> > > >  drivers/clk/rockchip/clk-rk3308.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/clk/rockchip/clk-rk3308.c b/drivers/clk/rockchip/clk-rk3308.c
> > > > index 2c3bd0c749f2..6be077166330 100644
> > > > --- a/drivers/clk/rockchip/clk-rk3308.c
> > > > +++ b/drivers/clk/rockchip/clk-rk3308.c
> > > > @@ -564,7 +564,7 @@ static struct rockchip_clk_branch rk3308_clk_branches[] __initdata = {
> > > >         COMPOSITE(SCLK_DDRCLK, "clk_ddrphy4x_src", mux_dpll_vpll0_vpll1_p, CLK_IGNORE_UNUSED,
> > > >                         RK3308_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 3, DFLAGS,
> > > >                         RK3308_CLKGATE_CON(0), 10, GFLAGS),
> > > > -       GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", CLK_IGNORE_UNUSED,
> > > > +       GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", CLK_IGNORE_UNUSED | CLK_IS_CRITICAL,
> > >
> > > Is it not enabled by default?
> >
> > All gates are enabled by default, but this gate shares a common parent
> > tree down to a pll, so if another leaf-user is disabling their part, this
> > untracked clock would get disabled as well.
>
> Right, this problem is cropping up in different places for various
> drivers.
>
> >
> > On that note, I remember a sort of CLK_HANDOFF was planned way back
> > in the past, meaning clock is critical until a driver picks it up, after this the
> > driver is responsible for it. Did that get any momentum?
> >
>
> Last I saw Saravana sent a patch to sort of connect CLK_HANDOFF to
> device driver sync_state() callback. I think we need to at least stash
> away that a clk is enabled at boot and then figure out how to tie in
> sync_state and/or something else.

Yeah, my clk_sync_state() series should do that. I'll get back on that
patch this week or next.

Yunhao,

Is there at least some DT device that consumes the DDR phy clock? Can
you point me to the DT for this board (not the SoC) so I can take a
look at it later?

Thanks,
Saravana


From mathieu.poirier at linaro.org  Mon Aug  2 11:25:57 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 2 Aug 2021 12:25:57 -0600
Subject: [PATCH v2 3/5] remoteproc: k3-r5: Add support for IPC-only mode
 for all R5Fs
In-Reply-To: <20210723220248.6554-4-s-anna@ti.com>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-4-s-anna@ti.com>
Message-ID: <20210802182557.GA3051951@p14s>

On Fri, Jul 23, 2021 at 05:02:46PM -0500, Suman Anna wrote:
> Add support to the K3 R5F remoteproc driver to configure all the R5F
> cores to be either in IPC-only mode or the traditional remoteproc mode.
> The IPC-only mode expects that the remote processors are already booted
> by the bootloader, and only performs the minimum steps required to
> initialize and deinitialize the virtio IPC transports. The remoteproc
> mode allows the kernel remoteproc driver to do the regular load and
> boot and other device management operations for a R5F core.
> 
> The IPC-only mode for a R5F core is detected and configured at driver
> probe time by querying the System Firmware for the R5F power and reset
> state and/or status and making sure that the R5F core is indeed started
> by the bootloaders, otherwise the device is configured for remoteproc
> mode.
> 
> Support for IPC-only mode is achieved through .attach(), .detach() and
> .get_loaded_rsc_table() callback ops and zeroing out the regular rproc
> ops .prepare(), .unprepare(), .start() and .stop(). The resource table
> follows a design-by-contract approach and is expected to be at the base
> of the DDR firmware region reserved for each remoteproc, it is mostly
> expected to contain only the virtio device and trace resource entries.
> 
> NOTE:
> The driver cannot configure a R5F core for remoteproc mode by any
> means without rebooting the kernel if that R5F core has been started
> by a bootloader. This is the current desired behavior and can be
> enhanced in the future if the feature is needed.
> 
> Signed-off-by: Suman Anna <s-anna at ti.com>
> ---
> v2: Addressed various review comments from v1
>  - Reworked the logic to not use remoteproc detach_on_shutdown and
>    local ipc-only state flags
>  - Plugged in the required IPC-only ops dynamically with the regular
>    remoteproc-mode ops zeroed out
>  - Dropped all the unneeded error checks in start, stop, prepare, 
>    unprepare, attach and detach callbacks
>  - Callback function descriptions updated to reflect the mode they
>    apply to
>  - Switched to dev_info for the mode information traces from dev_err
>  - Revised the last 2 paras of the patch description
> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-5-s-anna at ti.com/
> 
>  drivers/remoteproc/ti_k3_r5_remoteproc.c | 199 ++++++++++++++++++++++-
>  1 file changed, 196 insertions(+), 3 deletions(-)
> 

Reviewed-by: Mathieu Poirier <mathieu.poirier at linaro.org>

> diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c
> index 03f930758b2d..12658368aed6 100644
> --- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
> +++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
> @@ -428,6 +428,7 @@ static int k3_r5_rproc_request_mbox(struct rproc *rproc)
>   * private to each core. Only Core0 needs to be unhalted for running the
>   * cluster in this mode. The function uses the same reset logic as LockStep
>   * mode for this (though the behavior is agnostic of the reset release order).
> + * This callback is invoked only in remoteproc mode.
>   */
>  static int k3_r5_rproc_prepare(struct rproc *rproc)
>  {
> @@ -493,7 +494,8 @@ static int k3_r5_rproc_prepare(struct rproc *rproc)
>   * both cores. The access is made possible only with releasing the resets for
>   * both cores, but with only Core0 unhalted. This function re-uses the same
>   * reset assert logic as LockStep mode for this mode (though the behavior is
> - * agnostic of the reset assert order).
> + * agnostic of the reset assert order). This callback is invoked only in
> + * remoteproc mode.
>   */
>  static int k3_r5_rproc_unprepare(struct rproc *rproc)
>  {
> @@ -527,7 +529,8 @@ static int k3_r5_rproc_unprepare(struct rproc *rproc)
>   *
>   * The Single-CPU mode on applicable SoCs (eg: AM64x) only uses Core0 to execute
>   * code, so only Core0 needs to be unhalted. The function uses the same logic
> - * flow as Split-mode for this.
> + * flow as Split-mode for this. This callback is invoked only in remoteproc
> + * mode.
>   */
>  static int k3_r5_rproc_start(struct rproc *rproc)
>  {
> @@ -598,7 +601,8 @@ static int k3_r5_rproc_start(struct rproc *rproc)
>   * be done here, but is preferred to be done in the .unprepare() ops - this
>   * maintains the symmetric behavior between the .start(), .stop(), .prepare()
>   * and .unprepare() ops, and also balances them well between sysfs 'state'
> - * flow and device bind/unbind or module removal.
> + * flow and device bind/unbind or module removal. This callback is invoked
> + * only in remoteproc mode.
>   */
>  static int k3_r5_rproc_stop(struct rproc *rproc)
>  {
> @@ -635,6 +639,78 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
>  	return ret;
>  }
>  
> +/*
> + * Attach to a running R5F remote processor (IPC-only mode)
> + *
> + * The R5F attach callback only needs to request the mailbox, the remote
> + * processor is already booted, so there is no need to issue any TI-SCI
> + * commands to boot the R5F cores in IPC-only mode. This callback is invoked
> + * only in IPC-only mode.
> + */
> +static int k3_r5_rproc_attach(struct rproc *rproc)
> +{
> +	struct k3_r5_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +	int ret;
> +
> +	ret = k3_r5_rproc_request_mbox(rproc);
> +	if (ret)
> +		return ret;
> +
> +	dev_info(dev, "R5F core initialized in IPC-only mode\n");
> +	return 0;
> +}
> +
> +/*
> + * Detach from a running R5F remote processor (IPC-only mode)
> + *
> + * The R5F detach callback performs the opposite operation to attach callback
> + * and only needs to release the mailbox, the R5F cores are not stopped and
> + * will be left in booted state in IPC-only mode. This callback is invoked
> + * only in IPC-only mode.
> + */
> +static int k3_r5_rproc_detach(struct rproc *rproc)
> +{
> +	struct k3_r5_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +
> +	mbox_free_channel(kproc->mbox);
> +	dev_info(dev, "R5F core deinitialized in IPC-only mode\n");
> +	return 0;
> +}
> +
> +/*
> + * This function implements the .get_loaded_rsc_table() callback and is used
> + * to provide the resource table for the booted R5F in IPC-only mode. The K3 R5F
> + * firmwares follow a design-by-contract approach and are expected to have the
> + * resource table at the base of the DDR region reserved for firmware usage.
> + * This provides flexibility for the remote processor to be booted by different
> + * bootloaders that may or may not have the ability to publish the resource table
> + * address and size through a DT property. This callback is invoked only in
> + * IPC-only mode.
> + */
> +static struct resource_table *k3_r5_get_loaded_rsc_table(struct rproc *rproc,
> +							 size_t *rsc_table_sz)
> +{
> +	struct k3_r5_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +
> +	if (!kproc->rmem[0].cpu_addr) {
> +		dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found");
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	/*
> +	 * NOTE: The resource table size is currently hard-coded to a maximum
> +	 * of 256 bytes. The most common resource table usage for K3 firmwares
> +	 * is to only have the vdev resource entry and an optional trace entry.
> +	 * The exact size could be computed based on resource table address, but
> +	 * the hard-coded value suffices to support the IPC-only mode.
> +	 */
> +	*rsc_table_sz = 256;
> +	return (struct resource_table *)kproc->rmem[0].cpu_addr;
> +}
> +
>  /*
>   * Internal Memory translation helper
>   *
> @@ -1014,6 +1090,116 @@ static void k3_r5_adjust_tcm_sizes(struct k3_r5_rproc *kproc)
>  	}
>  }
>  
> +/*
> + * This function checks and configures a R5F core for IPC-only or remoteproc
> + * mode. The driver is configured to be in IPC-only mode for a R5F core when
> + * the core has been loaded and started by a bootloader. The IPC-only mode is
> + * detected by querying the System Firmware for reset, power on and halt status
> + * and ensuring that the core is running. Any incomplete steps at bootloader
> + * are validated and errored out.
> + *
> + * In IPC-only mode, the driver state flags for ATCM, BTCM and LOCZRAMA settings
> + * and cluster mode parsed originally from kernel DT are updated to reflect the
> + * actual values configured by bootloader. The driver internal device memory
> + * addresses for TCMs are also updated.
> + */
> +static int k3_r5_rproc_configure_mode(struct k3_r5_rproc *kproc)
> +{
> +	struct k3_r5_cluster *cluster = kproc->cluster;
> +	struct k3_r5_core *core = kproc->core;
> +	struct device *cdev = core->dev;
> +	bool r_state = false, c_state = false;
> +	u32 ctrl = 0, cfg = 0, stat = 0, halted = 0;
> +	u64 boot_vec = 0;
> +	u32 atcm_enable, btcm_enable, loczrama;
> +	struct k3_r5_core *core0;
> +	enum cluster_mode mode;
> +	int ret;
> +
> +	core0 = list_first_entry(&cluster->cores, struct k3_r5_core, elem);
> +
> +	ret = core->ti_sci->ops.dev_ops.is_on(core->ti_sci, core->ti_sci_id,
> +					      &r_state, &c_state);
> +	if (ret) {
> +		dev_err(cdev, "failed to get initial state, mode cannot be determined, ret = %d\n",
> +			ret);
> +		return ret;
> +	}
> +	if (r_state != c_state) {
> +		dev_warn(cdev, "R5F core may have been powered on by a different host, programmed state (%d) != actual state (%d)\n",
> +			 r_state, c_state);
> +	}
> +
> +	ret = reset_control_status(core->reset);
> +	if (ret < 0) {
> +		dev_err(cdev, "failed to get initial local reset status, ret = %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl,
> +				     &stat);
> +	if (ret < 0) {
> +		dev_err(cdev, "failed to get initial processor status, ret = %d\n",
> +			ret);
> +		return ret;
> +	}
> +	atcm_enable = cfg & PROC_BOOT_CFG_FLAG_R5_ATCM_EN ?  1 : 0;
> +	btcm_enable = cfg & PROC_BOOT_CFG_FLAG_R5_BTCM_EN ?  1 : 0;
> +	loczrama = cfg & PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE ?  1 : 0;
> +	if (cluster->soc_data->single_cpu_mode) {
> +		mode = cfg & PROC_BOOT_CFG_FLAG_R5_SINGLE_CORE ?
> +				CLUSTER_MODE_SINGLECPU : CLUSTER_MODE_SPLIT;
> +	} else {
> +		mode = cfg & PROC_BOOT_CFG_FLAG_R5_LOCKSTEP ?
> +				CLUSTER_MODE_LOCKSTEP : CLUSTER_MODE_SPLIT;
> +	}
> +	halted = ctrl & PROC_BOOT_CTRL_FLAG_R5_CORE_HALT;
> +
> +	/*
> +	 * IPC-only mode detection requires both local and module resets to
> +	 * be deasserted and R5F core to be unhalted. Local reset status is
> +	 * irrelevant if module reset is asserted (POR value has local reset
> +	 * deasserted), and is deemed as remoteproc mode
> +	 */
> +	if (c_state && !ret && !halted) {
> +		dev_info(cdev, "configured R5F for IPC-only mode\n");
> +		kproc->rproc->state = RPROC_DETACHED;
> +		ret = 1;
> +		/* override rproc ops with only required IPC-only mode ops */
> +		kproc->rproc->ops->prepare = NULL;
> +		kproc->rproc->ops->unprepare = NULL;
> +		kproc->rproc->ops->start = NULL;
> +		kproc->rproc->ops->stop = NULL;
> +		kproc->rproc->ops->attach = k3_r5_rproc_attach;
> +		kproc->rproc->ops->detach = k3_r5_rproc_detach;
> +		kproc->rproc->ops->get_loaded_rsc_table =
> +						k3_r5_get_loaded_rsc_table;
> +	} else if (!c_state) {
> +		dev_info(cdev, "configured R5F for remoteproc mode\n");
> +		ret = 0;
> +	} else {
> +		dev_err(cdev, "mismatched mode: local_reset = %s, module_reset = %s, core_state = %s\n",
> +			!ret ? "deasserted" : "asserted",
> +			c_state ? "deasserted" : "asserted",
> +			halted ? "halted" : "unhalted");
> +		ret = -EINVAL;
> +	}
> +
> +	/* fixup TCMs, cluster & core flags to actual values in IPC-only mode */
> +	if (ret > 0) {
> +		if (core == core0)
> +			cluster->mode = mode;
> +		core->atcm_enable = atcm_enable;
> +		core->btcm_enable = btcm_enable;
> +		core->loczrama = loczrama;
> +		core->mem[0].dev_addr = loczrama ? 0 : K3_R5_TCM_DEV_ADDR;
> +		core->mem[1].dev_addr = loczrama ? K3_R5_TCM_DEV_ADDR : 0;
> +	}
> +
> +	return ret;
> +}
> +
>  static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
>  {
>  	struct k3_r5_cluster *cluster = platform_get_drvdata(pdev);
> @@ -1054,6 +1240,12 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
>  		kproc->rproc = rproc;
>  		core->rproc = rproc;
>  
> +		ret = k3_r5_rproc_configure_mode(kproc);
> +		if (ret < 0)
> +			goto err_config;
> +		if (ret)
> +			goto init_rmem;
> +
>  		ret = k3_r5_rproc_configure(kproc);
>  		if (ret) {
>  			dev_err(dev, "initial configure failed, ret = %d\n",
> @@ -1061,6 +1253,7 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
>  			goto err_config;
>  		}
>  
> +init_rmem:
>  		k3_r5_adjust_tcm_sizes(kproc);
>  
>  		ret = k3_r5_reserved_mem_init(kproc);
> -- 
> 2.32.0
> 


From mathieu.poirier at linaro.org  Mon Aug  2 11:26:43 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 2 Aug 2021 12:26:43 -0600
Subject: [PATCH v2 5/5] remoteproc: k3-dsp: Add support for IPC-only mode
 for all K3 DSPs
In-Reply-To: <20210723220248.6554-6-s-anna@ti.com>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-6-s-anna@ti.com>
Message-ID: <20210802182643.GB3051951@p14s>

On Fri, Jul 23, 2021 at 05:02:48PM -0500, Suman Anna wrote:
> Add support to the K3 DSP remoteproc driver to configure all the C66x
> and C71x cores on J721E SoCs to be either in IPC-only mode or the
> traditional remoteproc mode. The IPC-only mode expects that the remote
> processors are already booted by the bootloader, and only perform the
> minimum steps required to initialize and deinitialize the virtio IPC
> transports. The remoteproc mode allows the kernel remoteproc driver to
> do the regular load and boot and other device management operations for
> a DSP.
> 
> The IPC-only mode for a DSP is detected and configured at driver probe
> time by querying the System Firmware for the DSP power and reset state
> and/or status and making sure that the DSP is indeed started by the
> bootloaders, otherwise the device is configured for remoteproc mode.
> 
> Support for IPC-only mode is achieved through .attach(), .detach() and
> .get_loaded_rsc_table() callback ops and zeroing out the regular rproc
> ops .prepare(), .unprepare(), .start() and .stop(). The resource table
> follows a design-by-contract approach and is expected to be at the base
> of the DDR firmware region reserved for each remoteproc, it is mostly
> expected to contain only the virtio device and trace resource entries.
> 
> NOTE:
> The driver cannot configure a DSP core for remoteproc mode by any
> means without rebooting the kernel if that DSP core has been started
> by a bootloader.  This is the current desired behavior and can be
> enhanced in the future if the feature is needed.
> 
> Signed-off-by: Suman Anna <s-anna at ti.com>
> ---
> v2: Addressed various review comments from v1
>  - Reworked the logic to not use remoteproc detach_on_shutdown and
>    local ipc-only state flags
>  - Plugged in the required IPC-only ops dynamically with the regular
>    remoteproc-mode ops zeroed out
>  - Dropped all the unneeded error checks in start, stop, prepare, 
>    unprepare, attach and detach callbacks
>  - Callback function descriptions updated to reflect the mode they
>    apply to
>  - Dropped unused r_state variable in probe
>  - Switched to dev_info for the mode information traces from dev_err
>  - Revised the last 2 paras of the patch description
> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-7-s-anna at ti.com/
> 
>  drivers/remoteproc/ti_k3_dsp_remoteproc.c | 132 +++++++++++++++++++---
>  1 file changed, 115 insertions(+), 17 deletions(-)
> 

Reviewed-by: Mathieu Poirier <mathieu.poirier at linaro.org>

> diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
> index faf60a274e8d..6eaecf02aee5 100644
> --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c
> +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c
> @@ -260,7 +260,8 @@ static int k3_dsp_rproc_request_mbox(struct rproc *rproc)
>   * used to release the global reset on C66x DSPs to allow loading into the DSP
>   * internal RAMs. The .prepare() ops is invoked by remoteproc core before any
>   * firmware loading, and is followed by the .start() ops after loading to
> - * actually let the C66x DSP cores run.
> + * actually let the C66x DSP cores run. This callback is invoked only in
> + * remoteproc mode.
>   */
>  static int k3_dsp_rproc_prepare(struct rproc *rproc)
>  {
> @@ -284,7 +285,7 @@ static int k3_dsp_rproc_prepare(struct rproc *rproc)
>   * powering down the C66x DSP cores. The cores themselves are only halted in the
>   * .stop() callback through the local reset, and the .unprepare() ops is invoked
>   * by the remoteproc core after the remoteproc is stopped to balance the global
> - * reset.
> + * reset. This callback is invoked only in remoteproc mode.
>   */
>  static int k3_dsp_rproc_unprepare(struct rproc *rproc)
>  {
> @@ -305,7 +306,7 @@ static int k3_dsp_rproc_unprepare(struct rproc *rproc)
>   *
>   * This function will be invoked only after the firmware for this rproc
>   * was loaded, parsed successfully, and all of its resource requirements
> - * were met.
> + * were met. This callback is invoked only in remoteproc mode.
>   */
>  static int k3_dsp_rproc_start(struct rproc *rproc)
>  {
> @@ -346,7 +347,7 @@ static int k3_dsp_rproc_start(struct rproc *rproc)
>   * Stop the DSP remote processor.
>   *
>   * This function puts the DSP processor into reset, and finishes processing
> - * of any pending messages.
> + * of any pending messages. This callback is invoked only in remoteproc mode.
>   */
>  static int k3_dsp_rproc_stop(struct rproc *rproc)
>  {
> @@ -359,6 +360,78 @@ static int k3_dsp_rproc_stop(struct rproc *rproc)
>  	return 0;
>  }
>  
> +/*
> + * Attach to a running DSP remote processor (IPC-only mode)
> + *
> + * This rproc attach callback only needs to request the mailbox, the remote
> + * processor is already booted, so there is no need to issue any TI-SCI
> + * commands to boot the DSP core. This callback is invoked only in IPC-only
> + * mode.
> + */
> +static int k3_dsp_rproc_attach(struct rproc *rproc)
> +{
> +	struct k3_dsp_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +	int ret;
> +
> +	ret = k3_dsp_rproc_request_mbox(rproc);
> +	if (ret)
> +		return ret;
> +
> +	dev_info(dev, "DSP initialized in IPC-only mode\n");
> +	return 0;
> +}
> +
> +/*
> + * Detach from a running DSP remote processor (IPC-only mode)
> + *
> + * This rproc detach callback performs the opposite operation to attach callback
> + * and only needs to release the mailbox, the DSP core is not stopped and will
> + * be left to continue to run its booted firmware. This callback is invoked only
> + * in IPC-only mode.
> + */
> +static int k3_dsp_rproc_detach(struct rproc *rproc)
> +{
> +	struct k3_dsp_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +
> +	mbox_free_channel(kproc->mbox);
> +	dev_info(dev, "DSP deinitialized in IPC-only mode\n");
> +	return 0;
> +}
> +
> +/*
> + * This function implements the .get_loaded_rsc_table() callback and is used
> + * to provide the resource table for a booted DSP in IPC-only mode. The K3 DSP
> + * firmwares follow a design-by-contract approach and are expected to have the
> + * resource table at the base of the DDR region reserved for firmware usage.
> + * This provides flexibility for the remote processor to be booted by different
> + * bootloaders that may or may not have the ability to publish the resource table
> + * address and size through a DT property. This callback is invoked only in
> + * IPC-only mode.
> + */
> +static struct resource_table *k3_dsp_get_loaded_rsc_table(struct rproc *rproc,
> +							  size_t *rsc_table_sz)
> +{
> +	struct k3_dsp_rproc *kproc = rproc->priv;
> +	struct device *dev = kproc->dev;
> +
> +	if (!kproc->rmem[0].cpu_addr) {
> +		dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found");
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	/*
> +	 * NOTE: The resource table size is currently hard-coded to a maximum
> +	 * of 256 bytes. The most common resource table usage for K3 firmwares
> +	 * is to only have the vdev resource entry and an optional trace entry.
> +	 * The exact size could be computed based on resource table address, but
> +	 * the hard-coded value suffices to support the IPC-only mode.
> +	 */
> +	*rsc_table_sz = 256;
> +	return (struct resource_table *)kproc->rmem[0].cpu_addr;
> +}
> +
>  /*
>   * Custom function to translate a DSP device address (internal RAMs only) to a
>   * kernel virtual address.  The DSPs can access their RAMs at either an internal
> @@ -605,6 +678,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
>  	struct k3_dsp_rproc *kproc;
>  	struct rproc *rproc;
>  	const char *fw_name;
> +	bool p_state = false;
>  	int ret = 0;
>  	int ret1;
>  
> @@ -683,19 +757,43 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
>  		goto release_tsp;
>  	}
>  
> -	/*
> -	 * ensure the DSP local reset is asserted to ensure the DSP doesn't
> -	 * execute bogus code in .prepare() when the module reset is released.
> -	 */
> -	if (data->uses_lreset) {
> -		ret = reset_control_status(kproc->reset);
> -		if (ret < 0) {
> -			dev_err(dev, "failed to get reset status, status = %d\n",
> -				ret);
> -			goto release_mem;
> -		} else if (ret == 0) {
> -			dev_warn(dev, "local reset is deasserted for device\n");
> -			k3_dsp_rproc_reset(kproc);
> +	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
> +					       NULL, &p_state);
> +	if (ret) {
> +		dev_err(dev, "failed to get initial state, mode cannot be determined, ret = %d\n",
> +			ret);
> +		goto release_mem;
> +	}
> +
> +	/* configure J721E devices for either remoteproc or IPC-only mode */
> +	if (p_state) {
> +		dev_info(dev, "configured DSP for IPC-only mode\n");
> +		rproc->state = RPROC_DETACHED;
> +		/* override rproc ops with only required IPC-only mode ops */
> +		rproc->ops->prepare = NULL;
> +		rproc->ops->unprepare = NULL;
> +		rproc->ops->start = NULL;
> +		rproc->ops->stop = NULL;
> +		rproc->ops->attach = k3_dsp_rproc_attach;
> +		rproc->ops->detach = k3_dsp_rproc_detach;
> +		rproc->ops->get_loaded_rsc_table = k3_dsp_get_loaded_rsc_table;
> +	} else {
> +		dev_info(dev, "configured DSP for remoteproc mode\n");
> +		/*
> +		 * ensure the DSP local reset is asserted to ensure the DSP
> +		 * doesn't execute bogus code in .prepare() when the module
> +		 * reset is released.
> +		 */
> +		if (data->uses_lreset) {
> +			ret = reset_control_status(kproc->reset);
> +			if (ret < 0) {
> +				dev_err(dev, "failed to get reset status, status = %d\n",
> +					ret);
> +				goto release_mem;
> +			} else if (ret == 0) {
> +				dev_warn(dev, "local reset is deasserted for device\n");
> +				k3_dsp_rproc_reset(kproc);
> +			}
>  		}
>  	}
>  
> -- 
> 2.32.0
> 


From clabbe.montjoie at gmail.com  Mon Aug  2 11:27:06 2021
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Mon, 2 Aug 2021 20:27:06 +0200
Subject: [PATCH v4] crypto: sun8i-ss: fix multiple memory leaks in
 sun8i_ss_hash_run
In-Reply-To: <20210726152533.2281139-1-mudongliangabcd@gmail.com>
References: <20210726152533.2281139-1-mudongliangabcd@gmail.com>
Message-ID: <YQg4+skrb9dxMgHw@Red>

Le Mon, Jul 26, 2021 at 11:25:21PM +0800, Dongliang Mu a ?crit :
> In sun8i_ss_hash_run, all the dma_mmap_sg/single will cause memory leak
> due to no corresponding unmap operation if errors happen.
> 
> Fix this by adding error handling part for all the dma_mmap_sg/single.
> 

Hello

I have nearly the same comment than on your sun8i-ce patch, (copy result only if err===0 and wording).

Regards


From robh at kernel.org  Mon Aug  2 11:29:02 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 12:29:02 -0600
Subject: [PATCH v2 3/3] dt-bindings: mediatek: convert pinctrl to yaml
In-Reply-To: <20210730120937.1435204-3-hsinyi@chromium.org>
References: <20210730120937.1435204-1-hsinyi@chromium.org>
 <20210730120937.1435204-3-hsinyi@chromium.org>
Message-ID: <YQg5bjYwCCZQ7bR9@robh.at.kernel.org>

On Fri, Jul 30, 2021 at 08:09:37PM +0800, Hsin-Yi Wang wrote:
> Convert mt65xx, mt6796, mt7622, mt8183 bindings to yaml.
> 
> Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
> ---
> v1->v2:
> - fix comments in v1.
> - fix mt7622 where groups is not required for conf node.
> ---
>  .../pinctrl/mediatek,mt65xx-pinctrl.yaml      | 206 ++++++++
>  .../pinctrl/mediatek,mt6797-pinctrl.yaml      | 173 +++++++
>  .../pinctrl/mediatek,mt7622-pinctrl.yaml      | 416 +++++++++++++++
>  .../pinctrl/mediatek,mt8183-pinctrl.yaml      | 228 ++++++++
>  .../bindings/pinctrl/pinctrl-mt65xx.txt       | 156 ------
>  .../bindings/pinctrl/pinctrl-mt6797.txt       |  83 ---
>  .../bindings/pinctrl/pinctrl-mt7622.txt       | 490 ------------------
>  .../bindings/pinctrl/pinctrl-mt8183.txt       | 132 -----
>  8 files changed, 1023 insertions(+), 861 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
> new file mode 100644
> index 0000000000000..f76c2c9cabe25
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
> @@ -0,0 +1,206 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt65xx-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek MT65xx Pin Controller Device Tree Bindings
> +
> +maintainers:
> +  - Andy Teng <andy.teng at mediatek.com>
> +
> +description: |+
> +  The Mediatek's Pin controller is used to control SoC pins.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt2701-pinctrl
> +      - mediatek,mt2712-pinctrl
> +      - mediatek,mt6397-pinctrl
> +      - mediatek,mt7623-pinctrl
> +      - mediatek,mt8127-pinctrl
> +      - mediatek,mt8135-pinctrl
> +      - mediatek,mt8167-pinctrl
> +      - mediatek,mt8173-pinctrl
> +      - mediatek,mt8516-pinctrl
> +
> +  reg:
> +    maxItems: 1
> +
> +  pins-are-numbered:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description: |
> +      Specify the subnodes are using numbered pinmux to specify pins.
> +
> +  gpio-controller: true
> +
> +  "#gpio-cells":
> +    const: 2
> +    description: |
> +      Number of cells in GPIO specifier. Since the generic GPIO
> +      binding is used, the amount of cells must be specified as 2. See the below
> +      mentioned gpio binding representation for description of particular cells.
> +
> +  mediatek,pctl-regmap:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    minItems: 1
> +    maxItems: 2
> +    description: |
> +      Should be phandles of the syscfg node.
> +
> +  interrupt-controller: true
> +
> +  interrupts:
> +    minItems: 1
> +    maxItems: 3
> +
> +  "#interrupt-cells":
> +    const: 2
> +
> +required:
> +  - compatible
> +  - pins-are-numbered
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +patternProperties:
> +  '-[0-9]+$':
> +    type: object

       additionalProperties: false

That's going to cause validation failures as the pattern below doesn't 
match 'pins1' or 'pins'.

> +    patternProperties:
> +      '-pins':
> +        type: object

I recommend moving the 'additionalProperties' below to here. Easier to 
follow the indentation.

Same issues on the rest of the schemas.

> +        description: |
> +          A pinctrl node should contain at least one subnodes representing the
> +          pinctrl groups available on the machine. Each subnode will list the
> +          pins it needs, and how they should be configured, with regard to muxer
> +          configuration, pullups, drive strength, input enable/disable and input
> +          schmitt.
> +        $ref: "/schemas/pinctrl/pincfg-node.yaml"
> +
> +        properties:
> +          pinmux:
> +            description:
> +              integer array, represents gpio pin number and mux setting.
> +              Supported pin number and mux varies for different SoCs, and are
> +              defined as macros in <soc>-pinfunc.h directly.
> +
> +          bias-disable: true
> +
> +          bias-pull-up:
> +            description: |
> +              Besides generic pinconfig options, it can be used as the pull up
> +              settings for 2 pull resistors, R0 and R1. User can configure those
> +              special pins. Some macros have been defined for this usage, such
> +              as MTK_PUPD_SET_R1R0_00. See dt-bindings/pinctrl/mt65xx.h for
> +              valid arguments.
> +
> +          bias-pull-down: true
> +
> +          input-enable: true
> +
> +          input-disable: true
> +
> +          output-low: true
> +
> +          output-high: true
> +
> +          input-schmitt-enable: true
> +
> +          input-schmitt-disable: true
> +
> +          drive-strength:
> +            description: |
> +              Can support some arguments, such as MTK_DRIVE_4mA, MTK_DRIVE_6mA,
> +              etc. See dt-bindings/pinctrl/mt65xx.h for valid arguments.
> +
> +        required:
> +          - pinmux
> +
> +        additionalProperties: false
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/pinctrl/mt8135-pinfunc.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        syscfg_pctl_a: syscfg-pctl-a at 10005000 {
> +          compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon";
> +          reg = <0 0x10005000 0 0x1000>;
> +        };
> +
> +        syscfg_pctl_b: syscfg-pctl-b at 1020c020 {
> +          compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon";
> +          reg = <0 0x1020C020 0 0x1000>;
> +        };
> +
> +        pinctrl at 1c20800 {
> +          compatible = "mediatek,mt8135-pinctrl";
> +          reg = <0 0x1000B000 0 0x1000>;
> +          mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>;
> +          pins-are-numbered;
> +          gpio-controller;
> +          #gpio-cells = <2>;
> +          interrupt-controller;
> +          #interrupt-cells = <2>;
> +          interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
> +              <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
> +              <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
> +
> +          i2c0_pins_a: i2c0-0 {
> +            pins1 {
> +              pinmux = <MT8135_PIN_100_SDA0__FUNC_SDA0>,
> +                <MT8135_PIN_101_SCL0__FUNC_SCL0>;
> +              bias-disable;
> +            };
> +          };
> +
> +          i2c1_pins_a: i2c1-0 {
> +            pins {
> +              pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
> +                <MT8135_PIN_196_SCL1__FUNC_SCL1>;
> +              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +            };
> +          };
> +
> +          i2c2_pins_a: i2c2-0 {
> +            pins1 {
> +              pinmux = <MT8135_PIN_193_SDA2__FUNC_SDA2>;
> +              bias-pull-down;
> +            };
> +
> +            pins2 {
> +              pinmux = <MT8135_PIN_49_WATCHDOG__FUNC_GPIO49>;
> +              bias-pull-up;
> +            };
> +          };
> +
> +          i2c3_pins_a: i2c3-0 {
> +            pins1 {
> +              pinmux = <MT8135_PIN_40_DAC_CLK__FUNC_GPIO40>,
> +                <MT8135_PIN_41_DAC_WS__FUNC_GPIO41>;
> +              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +            };
> +
> +            pins2 {
> +              pinmux = <MT8135_PIN_35_SCL3__FUNC_SCL3>,
> +                <MT8135_PIN_36_SDA3__FUNC_SDA3>;
> +              output-low;
> +              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> +            };
> +
> +            pins3 {
> +              pinmux = <MT8135_PIN_57_JTCK__FUNC_GPIO57>,
> +                <MT8135_PIN_60_JTDI__FUNC_JTDI>;
> +              drive-strength = <32>;
> +            };
> +          };
> +        };
> +    };
> diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
> new file mode 100644
> index 0000000000000..55e47c1e42f6c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
> @@ -0,0 +1,173 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt6797-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek MT6797 Pin Controller Device Tree Bindings
> +
> +maintainers:
> +  - Andy Teng <andy.teng at mediatek.com>
> +
> +description: |+
> +  The MediaTek's MT6797 Pin controller is used to control SoC pins.
> +
> +properties:
> +  compatible:
> +    const: mediatek,mt6797-pinctrl
> +
> +  reg:
> +    minItems: 5
> +    maxItems: 5
> +
> +  reg-names:
> +    items:
> +      - const: gpio
> +      - const: iocfgl
> +      - const: iocfgb
> +      - const: iocfgr
> +      - const: iocfgt
> +
> +  gpio-controller: true
> +
> +  "#gpio-cells":
> +    const: 2
> +    description: |
> +      Number of cells in GPIO specifier. Since the generic GPIO
> +      binding is used, the amount of cells must be specified as 2. See the below
> +      mentioned gpio binding representation for description of particular cells.
> +
> +  interrupt-controller: true
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  "#interrupt-cells":
> +    const: 2
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +patternProperties:
> +  '-[0-9]+$':
> +    type: object
> +    patternProperties:
> +      '-pins':
> +        type: object
> +        description: |
> +          A pinctrl node should contain at least one subnodes representing the
> +          pinctrl groups available on the machine. Each subnode will list the
> +          pins it needs, and how they should be configured, with regard to muxer
> +          configuration, pullups, drive strength, input enable/disable and input
> +          schmitt.
> +        $ref: "/schemas/pinctrl/pincfg-node.yaml"
> +
> +        properties:
> +          pinmux:
> +            description:
> +              integer array, represents gpio pin number and mux setting.
> +              Supported pin number and mux varies for different SoCs, and are
> +              defined as macros in <soc>-pinfunc.h directly.
> +
> +          bias-disable: true
> +
> +          bias-pull-up: true
> +
> +          bias-pull-down: true
> +
> +          input-enable: true
> +
> +          input-disable: true
> +
> +          output-enable: true
> +
> +          output-low: true
> +
> +          output-high: true
> +
> +          input-schmitt-enable: true
> +
> +          input-schmitt-disable: true
> +
> +          drive-strength:
> +            enum: [2, 4, 8, 12, 16]
> +
> +          slew-rate:
> +            enum: [0, 1]
> +
> +          mediatek,pull-up-adv:
> +            description: |
> +              Pull up setings for 2 pull resistors, R0 and R1. User can
> +              configure those special pins. Valid arguments are described as below:
> +              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
> +              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
> +              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
> +              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            enum: [0, 1, 2, 3]
> +
> +          mediatek,pull-down-adv:
> +            description: |
> +              Pull down settings for 2 pull resistors, R0 and R1. User can
> +              configure those special pins. Valid arguments are described as below:
> +              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
> +              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
> +              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
> +              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            enum: [0, 1, 2, 3]
> +
> +          mediatek,tdsel:
> +            description: |
> +              An integer describing the steps for output level shifter duty
> +              cycle when asserted (high pulse width adjustment). Valid arguments
> +              are from 0 to 15.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +
> +          mediatek,rdsel:
> +            description: |
> +              An integer describing the steps for input level shifter duty cycle
> +              when asserted (high pulse width adjustment). Valid arguments are
> +              from 0 to 63.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +
> +        required:
> +          - pinmux
> +
> +        additionalProperties: false
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/pinctrl/mt6797-pinfunc.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        pio: pinctrl at 10005000 {
> +            compatible = "mediatek,mt6797-pinctrl";
> +            reg = <0 0x10005000 0 0x1000>,
> +                  <0 0x10002000 0 0x400>,
> +                  <0 0x10002400 0 0x400>,
> +                  <0 0x10002800 0 0x400>,
> +                  <0 0x10002C00 0 0x400>;
> +            reg-names = "gpio", "iocfgl", "iocfgb", "iocfgr", "iocfgt";
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +
> +            uart_pins_a: uart-0 {
> +                pins1 {
> +                    pinmux = <MT6797_GPIO232__FUNC_URXD1>,
> +                            <MT6797_GPIO233__FUNC_UTXD1>;
> +                };
> +            };
> +        };
> +    };
> diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
> new file mode 100644
> index 0000000000000..a01c81895fb95
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
> @@ -0,0 +1,416 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7622-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek MT7622 Pin Controller Device Tree Bindings
> +
> +maintainers:
> +  - Andy Teng <andy.teng at mediatek.com>
> +
> +description: |+
> +  The MediaTek's MT7622 Pin controller is used to control SoC pins.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt7622-pinctrl
> +      - mediatek,mt7629-pinctrl
> +
> +  reg:
> +    maxItems: 1
> +
> +  reg-names:
> +    items:
> +      - const: eint
> +
> +  gpio-controller: true
> +
> +  "#gpio-cells":
> +    const: 2
> +    description: |
> +      Number of cells in GPIO specifier. Since the generic GPIO
> +      binding is used, the amount of cells must be specified as 2. See the below
> +      mentioned gpio binding representation for description of particular cells.
> +
> +  interrupt-controller: true
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  "#interrupt-cells":
> +    const: 2
> +
> +required:
> +  - compatible
> +  - reg
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +if:
> +  required:
> +    - interrupt-controller
> +then:
> +  required:
> +    - reg-names
> +    - interrupts
> +    - "#interrupt-cells"
> +
> +patternProperties:
> +  '-[0-9]+$':
> +    type: object
> +    patternProperties:
> +      'mux':
> +        type: object
> +        description: |
> +          pinmux configuration nodes.
> +        $ref: "/schemas/pinctrl/pinmux-node.yaml"
> +        properties:
> +          function:
> +            description: |
> +              A string containing the name of the function to mux to the group.
> +            enum: [emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm, sd,
> +                   spi, tdm, uart, watchdog, wifi]
> +
> +          groups:
> +            description: |
> +              An array of strings. Each string contains the name of a group.
> +            enum: [emmc, emmc_rst, esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
> +                   rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio, i2c0, i2c1_0,
> +                   i2c1_1, i2c1_2, i2c2_0, i2c2_1, i2c2_2, i2s_in_mclk_bclk_ws,
> +                   i2s1_in_data, i2s2_in_data, i2s3_in_data, i2s4_in_data,
> +                   i2s_out_mclk_bclk_ws, i2s1_out_data, i2s2_out_data,
> +                   i2s3_out_data, i2s4_out_data, ir_0_tx, ir_1_tx, ir_2_tx,
> +                   ir_0_rx, ir_1_rx, ir_2_rx, ephy_leds, ephy0_led, ephy1_led,
> +                   ephy2_led, ephy3_led, ephy4_led, wled, par_nand, snfi,
> +                   spi_nor, pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
> +                   pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
> +                   pcie0_pad_perst, pcie1_pad_perst, pmic_bus, pwm_ch1_0,
> +                   pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1, pwm_ch2_2,
> +                   pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0, pwm_ch4_1,
> +                   pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1, pwm_ch5_2,
> +                   pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3, pwm_ch7_0,
> +                   pwm_ch7_1, pwm_ch7_2, sd_0, sd_1, spic0_0, spic0_1, spic1_0,
> +                   spic1_1, spic2_0_wp_hold, spic2_0, tdm_0_out_mclk_bclk_ws,
> +                   tdm_0_in_mclk_bclk_ws, tdm_0_out_data, tdm_0_in_data,
> +                   tdm_1_out_mclk_bclk_ws, tdm_1_in_mclk_bclk_ws,
> +                   tdm_1_out_data, tdm_1_in_data, uart0_0_tx_rx, uart1_0_tx_rx,
> +                   uart1_0_rts_cts, uart1_1_tx_rx, uart1_1_rts_cts,
> +                   uart2_0_tx_rx, uart2_0_rts_cts, uart2_1_tx_rx,
> +                   uart2_1_rts_cts, uart2_2_tx_rx, uart2_2_rts_cts,
> +                   uart2_3_tx_rx, uart3_0_tx_rx, uart3_1_tx_rx, uart3_1_rts_cts,
> +                   uart4_0_tx_rx, uart4_1_tx_rx, uart4_1_rts_cts, uart4_2_tx_rx,
> +                   uart4_2_rts_cts, watchdog, i2c_0, i2c_1, wf2g_led, wf5g_led,
> +                   pcie_pereset, pcie_wake, pcie_clkreq, pwm_0, pwm_1, spi_0,
> +                   spi_1, spi_wp, spi_hold, uart0_txd_rxd, uart1_0_txd_rxd,
> +                   uart1_0_cts_rts, uart1_1_txd_rxd, uart1_1_cts_rts,
> +                   uart2_0_txd_rxd, uart2_0_cts_rts, uart2_1_txd_rxd,
> +                   uart2_1_cts_rts, wf0_2g, wf0_5g]

You are listing the same strings twice. So I'd drop this one and leave 
the if/then schemas below. (Though just the above is good enough.)

> +
> +        required:
> +          - groups
> +          - function
> +        
> +        allOf:
> +          - if:
> +              properties:
> +                functions:

function or functions? 

> +                  contains:
> +                    const: emmc

It's only a single string entry, right? So drop 'contains'

> +            then:
> +              properties:
> +                groups:
> +                  enum: [emmc, emmc_rst]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: eth
> +            then:
> +              properties:
> +                groups:
> +                  enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
> +                         rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: i2c
> +            then:
> +              properties:
> +                groups:
> +                  enum: [i2c0, i2c_0, i2c_1, i2c1_0, i2c1_1, i2c1_2, i2c2_0,
> +                         i2c2_1, i2c2_2]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: i2s
> +            then:
> +              properties:
> +                groups:
> +                  enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
> +                         i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
> +                         i2s1_out_data, i2s2_out_data, i2s3_out_data,
> +                         i2s4_out_data]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: ir
> +            then:
> +              properties:
> +                groups:
> +                  enum: [ir_0_tx, ir_1_tx, ir_2_tx, ir_0_rx, ir_1_rx, ir_2_rx]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: led
> +            then:
> +              properties:
> +                groups:
> +                  enum: [ephy_leds, ephy0_led, ephy1_led, ephy2_led, ephy3_led,
> +                         ephy4_led, wled, wf2g_led, wf5g_led]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: flash
> +            then:
> +              properties:
> +                groups:
> +                  enum: [par_nand, snfi, spi_nor]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: pcie
> +            then:
> +              properties:
> +                groups:
> +                  enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
> +                         pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
> +                         pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
> +                         pcie_wake, pcie_clkreq]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: pmic
> +            then:
> +              properties:
> +                groups:
> +                  enum: [pmic_bus]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: pwm
> +            then:
> +              properties:
> +                groups:
> +                  enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
> +                         pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
> +                         pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
> +                         pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3,
> +                         pwm_ch7_0, pwm_0, pwm_1]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: sd
> +            then:
> +              properties:
> +                groups:
> +                  enum: [sd_0, sd_1]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: spi
> +            then:
> +              properties:
> +                groups:
> +                  enum: [spic0_0, spic0_1, spic1_0, spic1_1, spic2_0_wp_hold,
> +                         spic2_0, spi_0, spi_1, spi_wp, spi_hold]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: tdm
> +            then:
> +              properties:
> +                groups:
> +                  enum: [tdm_0_out_mclk_bclk_ws, tdm_0_in_mclk_bclk_ws,
> +                         tdm_0_out_data, tdm_0_in_data, tdm_1_out_mclk_bclk_ws,
> +                         tdm_1_in_mclk_bclk_ws, tdm_1_out_data, tdm_1_in_data]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: uart
> +            then:
> +              properties:
> +                groups:
> +                  enum: [uart0_0_tx_rx, uart1_0_tx_rx, uart1_0_rts_cts,
> +                         uart1_1_tx_rx, uart1_1_rts_cts, uart2_0_tx_rx,
> +                         uart2_0_rts_cts, uart2_1_tx_rx, uart2_1_rts_cts,
> +                         uart2_2_tx_rx, uart2_2_rts_cts, uart2_3_tx_rx,
> +                         uart3_0_tx_rx, uart3_1_tx_rx, uart3_1_rts_cts,
> +                         uart4_0_tx_rx, uart4_1_tx_rx, uart4_1_rts_cts,
> +                         uart4_2_tx_rx, uart4_2_rts_cts, uart0_txd_rxd,
> +                         uart1_0_txd_rxd, uart1_0_cts_rts, uart1_1_txd_rxd,
> +                         uart1_1_cts_rts, uart2_0_txd_rxd, uart2_0_cts_rts,
> +                         uart2_1_txd_rxd, uart2_1_cts_rts]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: watchdog
> +            then:
> +              properties:
> +                groups:
> +                  enum: [watchdog]
> +          - if:
> +              properties:
> +                functions:
> +                  contains:
> +                    const: wifi
> +            then:
> +              properties:
> +                groups:
> +                  enum: [wf0_2g, wf0_5g]
> +          
> +      'conf':
> +        type: object
> +        description: |
> +          pinconf configuration nodes.
> +        $ref: "/schemas/pinctrl/pincfg-node.yaml"
> +
> +        properties:
> +          groups:
> +            description: |
> +              An array of strings. Each string contains the name of a group.
> +              Valid values are the same as the pinmux node.
> +
> +          pins:
> +            description: |
> +              An array of strings. Each string contains the name of a pin.
> +            enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
> +                   RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
> +                   I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
> +                   I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1,
> +                   G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2,
> +                   G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6,
> +                   NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0,
> +                   MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1,
> +                   MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2,
> +                   MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3,
> +                   MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL,
> +                   PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS,
> +                   GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N,
> +                   PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2,
> +                   AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4,
> +                   PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA,
> +                   WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4,
> +                   WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG,
> +                   EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS,
> +                   EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N,
> +                   WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD,
> +                   UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD,
> +                   UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N,
> +                   PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5,
> +                   GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK,
> +                   TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3,
> +                   WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6]
> +              
> +          bias-disable: true
> +
> +          bias-pull-up: true
> +
> +          bias-pull-down: true
> +
> +          input-enable: true
> +
> +          input-disable: true
> +
> +          output-enable: true
> +
> +          output-low: true
> +
> +          output-high: true
> +
> +          input-schmitt-enable: true
> +
> +          input-schmitt-disable: true
> +
> +          drive-strength:
> +            enum: [4, 8, 12, 16]
> +
> +          slew-rate:
> +            enum: [0, 1]
> +
> +          mediatek,tdsel:
> +            description: |
> +              An integer describing the steps for output level shifter duty
> +              cycle when asserted (high pulse width adjustment). Valid arguments
> +              are from 0 to 15.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +
> +          mediatek,rdsel:
> +            description: |
> +              An integer describing the steps for input level shifter duty cycle
> +              when asserted (high pulse width adjustment). Valid arguments are
> +              from 0 to 63.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +
> +        required:
> +          - pins
> +
> +        additionalProperties: false
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        pio: pinctrl at 10211000 {
> +          compatible = "mediatek,mt7622-pinctrl";
> +          reg = <0 0x10211000 0 0x1000>;
> +          gpio-controller;
> +          #gpio-cells = <2>;
> +
> +          pinctrl_eth_default: eth-0 {
> +            mux-mdio {
> +              groups = "mdc_mdio";
> +              function = "eth";
> +              drive-strength = <12>;
> +            };
> +
> +            mux-gmac2 {
> +              groups = "rgmii_via_gmac2";
> +              function = "eth";
> +              drive-strength = <12>;
> +            };
> +
> +            mux-esw {
> +              groups = "esw";
> +              function = "eth";
> +              drive-strength = <8>;
> +            };
> +
> +            conf-mdio {
> +              pins = "MDC";
> +              bias-pull-up;
> +            };
> +          };
> +        };
> +    };


From mathieu.poirier at linaro.org  Mon Aug  2 11:44:31 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 2 Aug 2021 12:44:31 -0600
Subject: [PATCH v2 1/5] remoteproc: Add support for detach-only during
 shutdown
In-Reply-To: <20210723220248.6554-2-s-anna@ti.com>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-2-s-anna@ti.com>
Message-ID: <20210802184431.GC3051951@p14s>

On Fri, Jul 23, 2021 at 05:02:44PM -0500, Suman Anna wrote:
> The remoteproc core has support for both stopping and detaching a
> remote processor that was attached to previously, through both the
> remoteproc sysfs and cdev interfaces. The rproc_shutdown() though
> unconditionally only uses the stop functionality at present. This
> may not be the default desired functionality for all the remoteproc
> platform drivers.
> 
> Enhance the remoteproc core logic to key off the presence of the
> .stop() ops and allow the individual remoteproc drivers to continue
> to use the standard rproc_add() and rproc_del() API. This allows
> the remoteproc drivers to only do detach if supported when the driver
> is uninstalled, and the remote processor continues to run undisturbed
> even after the driver removal.
> 
> Signed-off-by: Suman Anna <s-anna at ti.com>
> ---
> v2: Addressed various review comments from v1
>  - Reworked the logic to not use remoteproc detach_on_shutdown and
>    rely only on rproc callback ops
>  - Updated the last para of the patch description
> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-3-s-anna at ti.com/
> 
>  drivers/remoteproc/remoteproc_cdev.c  | 7 +++++++
>  drivers/remoteproc/remoteproc_core.c  | 5 ++++-
>  drivers/remoteproc/remoteproc_sysfs.c | 6 ++++++
>  3 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c
> index 4ad98b0b8caa..16c932beed88 100644
> --- a/drivers/remoteproc/remoteproc_cdev.c
> +++ b/drivers/remoteproc/remoteproc_cdev.c
> @@ -42,6 +42,13 @@ static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_
>  		    rproc->state != RPROC_ATTACHED)
>  			return -EINVAL;
>  
> +		if (rproc->state == RPROC_ATTACHED &&

This is already checked just above.

> +		    !rproc->ops->stop) {

This is checked in rproc_stop() where -EINVAL is returned if ops::stop has not
been provided. 

> +			dev_err(&rproc->dev,
> +				"stop not supported for this rproc, use detach\n");

The standard error message from the shell should be enough here, the same way it
is enough when the "start" and "stop" scenarios fail.

> +			return -EINVAL;
> +		}
> +
>  		rproc_shutdown(rproc);
>  	} else if (!strncmp(cmd, "detach", len)) {
>  		if (rproc->state != RPROC_ATTACHED)
> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> index 7de5905d276a..ab9e52180b04 100644
> --- a/drivers/remoteproc/remoteproc_core.c
> +++ b/drivers/remoteproc/remoteproc_core.c
> @@ -2075,7 +2075,10 @@ void rproc_shutdown(struct rproc *rproc)
>  	if (!atomic_dec_and_test(&rproc->power))
>  		goto out;
>  
> -	ret = rproc_stop(rproc, false);
> +	if (rproc->state == RPROC_ATTACHED && !rproc->ops->stop)
> +		ret = __rproc_detach(rproc);
> +	else
> +		ret = rproc_stop(rproc, false);

As I indicated in my last review I think rproc_shutdown() and rproc_del() should
be decoupled and the right call made in the platform drivers based on the state
of the remote processor.  Conditions such as the above make the core code
brittle, difficult to understand and tedious to maintain.

Thanks,
Mathieu

>  	if (ret) {
>  		atomic_inc(&rproc->power);
>  		goto out;
> diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
> index ea8b89f97d7b..133e766f38d4 100644
> --- a/drivers/remoteproc/remoteproc_sysfs.c
> +++ b/drivers/remoteproc/remoteproc_sysfs.c
> @@ -206,6 +206,12 @@ static ssize_t state_store(struct device *dev,
>  		    rproc->state != RPROC_ATTACHED)
>  			return -EINVAL;
>  
> +		if (rproc->state == RPROC_ATTACHED &&
> +		    !rproc->ops->stop) {
> +			dev_err(&rproc->dev, "stop not supported for this rproc, use detach\n");
> +			return -EINVAL;
> +		}
> +
>  		rproc_shutdown(rproc);
>  	} else if (sysfs_streq(buf, "detach")) {
>  		if (rproc->state != RPROC_ATTACHED)
> -- 
> 2.32.0
> 


From semen.protsenko at linaro.org  Mon Aug  2 12:24:22 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 2 Aug 2021 22:24:22 +0300
Subject: [PATCH 02/12] pinctrl: samsung: Add Exynos850 SoC specific data
In-Reply-To: <a2b6b868-e984-440c-75b1-599680537cc9@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-3-semen.protsenko@linaro.org>
 <a2b6b868-e984-440c-75b1-599680537cc9@canonical.com>
Message-ID: <CAPLW+4=ewQf8_hMKFFqPRaoqQxhRZZ1=NGboLstvVBOYcTc3aw@mail.gmail.com>

On Fri, 30 Jul 2021 at 18:22, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 30/07/2021 16:49, Sam Protsenko wrote:
> > Add Samsung Exynos850 SoC specific data to enable pinctrl support for
> > all platforms based on Exynos850.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> >  .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 129 ++++++++++++++++++
> >  drivers/pinctrl/samsung/pinctrl-exynos.h      |  29 ++++
> >  drivers/pinctrl/samsung/pinctrl-samsung.c     |   2 +
> >  drivers/pinctrl/samsung/pinctrl-samsung.h     |   1 +
> >  4 files changed, 161 insertions(+)
> >
> > diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> > index b6e56422a700..9c71ff84ba7e 100644
> > --- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> > +++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> > @@ -40,6 +40,24 @@ static const struct samsung_pin_bank_type exynos5433_bank_type_alive = {
> >       .reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
> >  };
> >
> > +/*
> > + * Bank type for non-alive type. Bit fields:
> > + * CON: 4, DAT: 1, PUD: 4, DRV: 4, CONPDN: 2, PUDPDN: 4
> > + */
> > +static struct samsung_pin_bank_type exynos850_bank_type_off  = {
> > +     .fld_width = { 4, 1, 4, 4, 2, 4, },
> > +     .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
> > +};
> > +
> > +/*
> > + * Bank type for alive type. Bit fields:
> > + * CON: 4, DAT: 1, PUD: 4, DRV: 4
> > + */
> > +static struct samsung_pin_bank_type exynos850_bank_type_alive = {
> > +     .fld_width = { 4, 1, 4, 4, },
> > +     .reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
> > +};
> > +
> >  /* Pad retention control code for accessing PMU regmap */
> >  static atomic_t exynos_shared_retention_refcnt;
> >
> > @@ -422,3 +440,114 @@ const struct samsung_pinctrl_of_match_data exynos7_of_data __initconst = {
> >       .ctrl           = exynos7_pin_ctrl,
> >       .num_ctrl       = ARRAY_SIZE(exynos7_pin_ctrl),
> >  };
> > +
> > +/* pin banks of exynos850 pin-controller 0 (ALIVE) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks0[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
>
> Why EXYNOS9 not EXYNOS850? Is it really shared with 96xx, 98xx and 9x0
> series?
>

Yeah, I double checked and those macros are actually used for 96xx
SoCs. So I suggest we leave it as is, as it seems to be related to the
whole architecture series, not only to Exynos850.

> > +     EXYNOS9_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
> > +     EXYNOS9_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
> > +     EXYNOS9_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
> > +     EXYNOS9_PIN_BANK_EINTW(4, 0x080, "gpa4", 0x10),
> > +     EXYNOS9_PIN_BANK_EINTN(3, 0x0A0, "gpq0"),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 1 (CMGP) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks1[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x000, "gpm0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x020, "gpm1", 0x04),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x040, "gpm2", 0x08),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x060, "gpm3", 0x0C),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x080, "gpm4", 0x10),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x0A0, "gpm5", 0x14),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x0C0, "gpm6", 0x18),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x0E0, "gpm7", 0x1C),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 2 (AUD) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks2[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTG(5, 0x020, "gpb1", 0x04),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 3 (HSI) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks3[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTG(6, 0x000, "gpf2", 0x00),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 4 (CORE) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks4[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTG(4, 0x000, "gpf0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTG(8, 0x020, "gpf1", 0x04),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 5 (PERI) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks5[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTG(2, 0x000, "gpg0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTG(6, 0x020, "gpp0", 0x04),
> > +     EXYNOS9_PIN_BANK_EINTG(4, 0x040, "gpp1", 0x08),
> > +     EXYNOS9_PIN_BANK_EINTG(4, 0x060, "gpp2", 0x0C),
> > +     EXYNOS9_PIN_BANK_EINTG(8, 0x080, "gpg1", 0x10),
> > +     EXYNOS9_PIN_BANK_EINTG(8, 0x0A0, "gpg2", 0x14),
> > +     EXYNOS9_PIN_BANK_EINTG(1, 0x0C0, "gpg3", 0x18),
> > +     EXYNOS9_PIN_BANK_EINTG(3, 0x0E0, "gpc0", 0x1C),
> > +     EXYNOS9_PIN_BANK_EINTG(6, 0x100, "gpc1", 0x20),
> > +};
> > +
> > +static const struct samsung_pin_ctrl exynos850_pin_ctrl[] __initconst = {
> > +     {
> > +             /* pin-controller instance 0 ALIVE data */
> > +             .pin_banks      = exynos850_pin_banks0,
> > +             .nr_banks       = ARRAY_SIZE(exynos850_pin_banks0),
> > +             .eint_gpio_init = exynos_eint_gpio_init,
> > +             .eint_wkup_init = exynos_eint_wkup_init,
> > +             .suspend        = exynos_pinctrl_suspend,
> > +             .resume         = exynos_pinctrl_resume,
>
> I guess retention registers will follow sometime later.
>

Good point, never noticed retention control is needed for
suspend/resume to work properly. I will remove suspend/resume ops in
v2, and PM support will be sent later.

> Best regards,
> Krzysztof


From heiko at sntech.de  Mon Aug  2 12:25:59 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 02 Aug 2021 21:25:59 +0200
Subject: [PATCH] clk: rk3308: make ddrphy4x clock critical
In-Reply-To: <CAGETcx8YYrkCV0UObtOqHUnS29Q-raC54KUh14wqyBDMJ4e46g@mail.gmail.com>
References: <BYAPR20MB24886765F888A9705CBEB70789E39@BYAPR20MB2488.namprd20.prod.outlook.com>
 <162758560739.714452.5782743329332725952@swboyd.mtv.corp.google.com>
 <CAGETcx8YYrkCV0UObtOqHUnS29Q-raC54KUh14wqyBDMJ4e46g@mail.gmail.com>
Message-ID: <16392318.geO5KgaWL5@diego>

Hi Saravana,

Am Montag, 2. August 2021, 20:24:56 CEST schrieb Saravana Kannan:
> On Thu, Jul 29, 2021 at 12:06 PM Stephen Boyd <sboyd at kernel.org> wrote:
> >
> > Quoting Heiko St?bner (2021-07-28 02:53:54)
> > > Am Dienstag, 27. Juli 2021, 03:08:10 CEST schrieb Stephen Boyd:
> > > > Quoting Yunhao Tian (2021-07-21 05:48:16)
> > > > > Currently, no driver support for DDR memory controller (DMC) is present,
> > > > > as a result, no driver is explicitly consuming the ddrphy clock. This means
> > > > > that VPLL1 (parent of ddr clock) will be shutdown if we enable
> > > > > and then disable any child clock of VPLL1 (e.g. SCLK_I2S0_8CH_TX).
> > > > > If VPLL1 is disabled, the whole system will freeze, because the DDR
> > > > > controller will lose its clock. So, it's necessary to prevent VPLL1 from
> > > > > shutting down, by marking the ddrphy4x CLK_IS_CRITICAL.
> > > > >
> > > > > This bug was discovered when I was porting rockchip_i2s_tdm driver to
> > > > > mainline kernel from Rockchip 4.4 kernel. I guess that other Rockchip
> > > > > SoCs without DMC driver may need the same patch. If this applies to
> > > > > other devices, please let us know.
> > > > >
> > > > > Signed-off-by: Yunhao Tian <t123yh at outlook.com>
> > > > > ---
> > > > >  drivers/clk/rockchip/clk-rk3308.c | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/drivers/clk/rockchip/clk-rk3308.c b/drivers/clk/rockchip/clk-rk3308.c
> > > > > index 2c3bd0c749f2..6be077166330 100644
> > > > > --- a/drivers/clk/rockchip/clk-rk3308.c
> > > > > +++ b/drivers/clk/rockchip/clk-rk3308.c
> > > > > @@ -564,7 +564,7 @@ static struct rockchip_clk_branch rk3308_clk_branches[] __initdata = {
> > > > >         COMPOSITE(SCLK_DDRCLK, "clk_ddrphy4x_src", mux_dpll_vpll0_vpll1_p, CLK_IGNORE_UNUSED,
> > > > >                         RK3308_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 3, DFLAGS,
> > > > >                         RK3308_CLKGATE_CON(0), 10, GFLAGS),
> > > > > -       GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", CLK_IGNORE_UNUSED,
> > > > > +       GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", CLK_IGNORE_UNUSED | CLK_IS_CRITICAL,
> > > >
> > > > Is it not enabled by default?
> > >
> > > All gates are enabled by default, but this gate shares a common parent
> > > tree down to a pll, so if another leaf-user is disabling their part, this
> > > untracked clock would get disabled as well.
> >
> > Right, this problem is cropping up in different places for various
> > drivers.
> >
> > >
> > > On that note, I remember a sort of CLK_HANDOFF was planned way back
> > > in the past, meaning clock is critical until a driver picks it up, after this the
> > > driver is responsible for it. Did that get any momentum?
> > >
> >
> > Last I saw Saravana sent a patch to sort of connect CLK_HANDOFF to
> > device driver sync_state() callback. I think we need to at least stash
> > away that a clk is enabled at boot and then figure out how to tie in
> > sync_state and/or something else.
> 
> Yeah, my clk_sync_state() series should do that. I'll get back on that
> patch this week or next.
> 
> Yunhao,
> 
> Is there at least some DT device that consumes the DDR phy clock? Can
> you point me to the DT for this board (not the SoC) so I can take a
> look at it later?

Not for the rk3308. If you're looking for live-examples of handoff clocks,
I can provide another examples though:


rockchip/clk-rk3288.c - pclk_rkpwm (in the separate critical clock list) ... with
arch/arm/boot/dts/rk3288.dtsi - clock is supplying pwm nodes.

As the comment in the clock driver suggests (line 850), some boards use
pwm-regulators for central components. The pwm-regulators are configured
at boot already, so the clock shouldn't be disabled till the pwm-regulator takes
over.


The whole memory handling is a blank slate on the kernel side for Rockchip
boards still. The bootloader sets up the memory and nobody has found the
time to modell things like memory scaling in a nice way yet.


Heiko




From oupton at google.com  Mon Aug  2 12:28:06 2021
From: oupton at google.com (Oliver Upton)
Date: Mon,  2 Aug 2021 19:28:06 +0000
Subject: [PATCH v3 0/3] KVM: arm64: Use generic guest entry infrastructure
Message-ID: <20210802192809.1851010-1-oupton@google.com>

The arm64 kernel doesn't yet support the full generic entry
infrastructure. That being said, KVM/arm64 doesn't properly handle
TIF_NOTIFY_RESUME and could pick this up by switching to the generic
guest entry infrasturture.

Patch 1 adds a missing vCPU stat to ARM64 to record the number of signal
exits to userspace.

Patch 2 unhitches entry-kvm from entry-generic, as ARM64 doesn't
currently support the generic infrastructure.

Patch 3 replaces the open-coded entry handling with the generic xfer
function.

This series was tested on an Ampere Mt. Jade reference system. The
series cleanly applies to kvm/queue (note that this is deliberate as the
generic kvm stats patches have not yet propagated to kvm-arm/queue) at
the following commit:

8ad5e63649ff ("KVM: Don't take mmu_lock for range invalidation unless necessary")

v1 -> v2:
 - Address Jing's comment
 - Carry Jing's r-b tag

v2 -> v3:
 - Roll all exit conditions into kvm_vcpu_exit_request() (Marc)
 - Avoid needlessly checking for work twice (Marc)

v1: http://lore.kernel.org/r/20210729195632.489978-1-oupton at google.com
v2: http://lore.kernel.org/r/20210729220916.1672875-1-oupton at google.com

Oliver Upton (3):
  KVM: arm64: Record number of signal exits as a vCPU stat
  entry: KVM: Allow use of generic KVM entry w/o full generic support
  KVM: arm64: Use generic KVM xfer to guest work function

 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/Kconfig            |  1 +
 arch/arm64/kvm/arm.c              | 71 +++++++++++++++++++------------
 arch/arm64/kvm/guest.c            |  1 +
 include/linux/entry-kvm.h         |  6 ++-
 5 files changed, 52 insertions(+), 28 deletions(-)

-- 
2.32.0.554.ge1b32706d8-goog



From oupton at google.com  Mon Aug  2 12:28:07 2021
From: oupton at google.com (Oliver Upton)
Date: Mon,  2 Aug 2021 19:28:07 +0000
Subject: [PATCH v3 1/3] KVM: arm64: Record number of signal exits as a vCPU
 stat
In-Reply-To: <20210802192809.1851010-1-oupton@google.com>
References: <20210802192809.1851010-1-oupton@google.com>
Message-ID: <20210802192809.1851010-2-oupton@google.com>

Most other architectures that implement KVM record a statistic
indicating the number of times a vCPU has exited due to a pending
signal. Add support for that stat to arm64.

Reviewed-by: Jing Zhang <jingzhangos at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/arm64/include/asm/kvm_host.h | 1 +
 arch/arm64/kvm/arm.c              | 1 +
 arch/arm64/kvm/guest.c            | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 41911585ae0c..70e129f2b574 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -576,6 +576,7 @@ struct kvm_vcpu_stat {
 	u64 wfi_exit_stat;
 	u64 mmio_exit_user;
 	u64 mmio_exit_kernel;
+	u64 signal_exits;
 	u64 exits;
 };
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..60d0a546d7fd 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -783,6 +783,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		if (signal_pending(current)) {
 			ret = -EINTR;
 			run->exit_reason = KVM_EXIT_INTR;
+			++vcpu->stat.signal_exits;
 		}
 
 		/*
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 1dfb83578277..853d1e8d2e73 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -50,6 +50,7 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	STATS_DESC_COUNTER(VCPU, wfi_exit_stat),
 	STATS_DESC_COUNTER(VCPU, mmio_exit_user),
 	STATS_DESC_COUNTER(VCPU, mmio_exit_kernel),
+	STATS_DESC_COUNTER(VCPU, signal_exits),
 	STATS_DESC_COUNTER(VCPU, exits)
 };
 static_assert(ARRAY_SIZE(kvm_vcpu_stats_desc) ==
-- 
2.32.0.554.ge1b32706d8-goog



From oupton at google.com  Mon Aug  2 12:28:08 2021
From: oupton at google.com (Oliver Upton)
Date: Mon,  2 Aug 2021 19:28:08 +0000
Subject: [PATCH v3 2/3] entry: KVM: Allow use of generic KVM entry w/o full
 generic support
In-Reply-To: <20210802192809.1851010-1-oupton@google.com>
References: <20210802192809.1851010-1-oupton@google.com>
Message-ID: <20210802192809.1851010-3-oupton@google.com>

Some architectures (e.g. arm64) have yet to adopt the generic entry
infrastructure. Despite that, it would be nice to use some common
plumbing for guest entry/exit handling. For example, KVM/arm64 currently
does not handle TIF_NOTIFY_PENDING correctly.

Allow use of only the generic KVM entry code by tightening up the
include list. No functional change intended.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 include/linux/entry-kvm.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/entry-kvm.h b/include/linux/entry-kvm.h
index 136b8d97d8c0..0d7865a0731c 100644
--- a/include/linux/entry-kvm.h
+++ b/include/linux/entry-kvm.h
@@ -2,7 +2,11 @@
 #ifndef __LINUX_ENTRYKVM_H
 #define __LINUX_ENTRYKVM_H
 
-#include <linux/entry-common.h>
+#include <linux/static_call_types.h>
+#include <linux/tracehook.h>
+#include <linux/syscalls.h>
+#include <linux/seccomp.h>
+#include <linux/sched.h>
 #include <linux/tick.h>
 
 /* Transfer to guest mode work */
-- 
2.32.0.554.ge1b32706d8-goog



From oupton at google.com  Mon Aug  2 12:28:09 2021
From: oupton at google.com (Oliver Upton)
Date: Mon,  2 Aug 2021 19:28:09 +0000
Subject: [PATCH v3 3/3] KVM: arm64: Use generic KVM xfer to guest work function
In-Reply-To: <20210802192809.1851010-1-oupton@google.com>
References: <20210802192809.1851010-1-oupton@google.com>
Message-ID: <20210802192809.1851010-4-oupton@google.com>

Clean up handling of checks for pending work by switching to the generic
infrastructure to do so.

We pick up handling for TIF_NOTIFY_RESUME from this switch, meaning that
task work will be correctly handled.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/arm64/kvm/Kconfig |  1 +
 arch/arm64/kvm/arm.c   | 72 ++++++++++++++++++++++++++----------------
 2 files changed, 45 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index a4eba0908bfa..8bc1fac5fa26 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -26,6 +26,7 @@ menuconfig KVM
 	select HAVE_KVM_ARCH_TLB_FLUSH_ALL
 	select KVM_MMIO
 	select KVM_GENERIC_DIRTYLOG_READ_PROTECT
+	select KVM_XFER_TO_GUEST_WORK
 	select SRCU
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 60d0a546d7fd..8245efc6e88f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -6,6 +6,7 @@
 
 #include <linux/bug.h>
 #include <linux/cpu_pm.h>
+#include <linux/entry-kvm.h>
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/kvm_host.h>
@@ -714,6 +715,45 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu)
 		static_branch_unlikely(&arm64_mismatched_32bit_el0);
 }
 
+/**
+ * kvm_vcpu_exit_request - returns true if the VCPU should *not* enter the guest
+ * @vcpu:	The VCPU pointer
+ * @ret:	Pointer to write optional return code
+ *
+ * Returns: true if the VCPU needs to return to a preemptible + interruptible
+ *	    and skip guest entry.
+ *
+ * This function disambiguates between two different types of exits: exits to a
+ * preemptible + interruptible kernel context and exits to userspace. For an
+ * exit to userspace, this function will write the return code to ret and return
+ * true. For an exit to preemptible + interruptible kernel context (i.e. check
+ * for pending work and re-enter), return true without writing to ret.
+ */
+static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret)
+{
+	struct kvm_run *run = vcpu->run;
+
+	/*
+	 * If we're using a userspace irqchip, then check if we need
+	 * to tell a userspace irqchip about timer or PMU level
+	 * changes and if so, exit to userspace (the actual level
+	 * state gets updated in kvm_timer_update_run and
+	 * kvm_pmu_update_run below).
+	 */
+	if (static_branch_unlikely(&userspace_irqchip_in_use)) {
+		if (kvm_timer_should_notify_user(vcpu) ||
+		    kvm_pmu_should_notify_user(vcpu)) {
+			*ret = -EINTR;
+			run->exit_reason = KVM_EXIT_INTR;
+			return true;
+		}
+	}
+
+	return kvm_request_pending(vcpu) ||
+			need_new_vmid_gen(&vcpu->arch.hw_mmu->vmid) ||
+			xfer_to_guest_mode_work_pending();
+}
+
 /**
  * kvm_arch_vcpu_ioctl_run - the main VCPU run function to execute guest code
  * @vcpu:	The VCPU pointer
@@ -757,7 +797,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		/*
 		 * Check conditions before entering the guest
 		 */
-		cond_resched();
+		ret = xfer_to_guest_mode_handle_work(vcpu);
+		if (!ret)
+			ret = 1;
 
 		update_vmid(&vcpu->arch.hw_mmu->vmid);
 
@@ -776,31 +818,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 
 		kvm_vgic_flush_hwstate(vcpu);
 
-		/*
-		 * Exit if we have a signal pending so that we can deliver the
-		 * signal to user space.
-		 */
-		if (signal_pending(current)) {
-			ret = -EINTR;
-			run->exit_reason = KVM_EXIT_INTR;
-			++vcpu->stat.signal_exits;
-		}
-
-		/*
-		 * If we're using a userspace irqchip, then check if we need
-		 * to tell a userspace irqchip about timer or PMU level
-		 * changes and if so, exit to userspace (the actual level
-		 * state gets updated in kvm_timer_update_run and
-		 * kvm_pmu_update_run below).
-		 */
-		if (static_branch_unlikely(&userspace_irqchip_in_use)) {
-			if (kvm_timer_should_notify_user(vcpu) ||
-			    kvm_pmu_should_notify_user(vcpu)) {
-				ret = -EINTR;
-				run->exit_reason = KVM_EXIT_INTR;
-			}
-		}
-
 		/*
 		 * Ensure we set mode to IN_GUEST_MODE after we disable
 		 * interrupts and before the final VCPU requests check.
@@ -809,8 +826,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		 */
 		smp_store_mb(vcpu->mode, IN_GUEST_MODE);
 
-		if (ret <= 0 || need_new_vmid_gen(&vcpu->arch.hw_mmu->vmid) ||
-		    kvm_request_pending(vcpu)) {
+		if (ret <= 0 || kvm_vcpu_exit_request(vcpu, &ret)) {
 			vcpu->mode = OUTSIDE_GUEST_MODE;
 			isb(); /* Ensure work in x_flush_hwstate is committed */
 			kvm_pmu_sync_hwstate(vcpu);
-- 
2.32.0.554.ge1b32706d8-goog



From robh at kernel.org  Mon Aug  2 12:33:55 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 13:33:55 -0600
Subject: [PATCH v5 01/14] dt-bindings: media: imx8q: add imx video codec
 bindings
In-Reply-To: <6ec97ccf157fcad84be33501f0e8f1c90f7e21c6.1627353315.git.ming.qian@nxp.com>
References: <cover.1627353315.git.ming.qian@nxp.com>
 <6ec97ccf157fcad84be33501f0e8f1c90f7e21c6.1627353315.git.ming.qian@nxp.com>
Message-ID: <YQhIo7eNAV6pBY+3@robh.at.kernel.org>

On Tue, 27 Jul 2021 11:20:44 +0800, Ming Qian wrote:
> Add devicetree binding documentation for IMX8Q Video Processing Unit IP
> 
> Signed-off-by: Ming Qian <ming.qian at nxp.com>
> Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
> Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
> ---
>  .../bindings/media/nxp,imx8q-vpu.yaml         | 178 ++++++++++++++++++
>  1 file changed, 178 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Mon Aug  2 13:09:03 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 14:09:03 -0600
Subject: [PATCH v3, 05/15] dt-bindings: media: mtk-vcodec: Separate video
 encoder and decoder dt-bindings
In-Reply-To: <20210727101051.24418-6-yunfei.dong@mediatek.com>
References: <20210727101051.24418-1-yunfei.dong@mediatek.com>
 <20210727101051.24418-6-yunfei.dong@mediatek.com>
Message-ID: <YQhQ3yUQIICmPUDg@robh.at.kernel.org>

On Tue, Jul 27, 2021 at 06:10:41PM +0800, Yunfei Dong wrote:
> Decoder will use component framework to manage hardware, it is big
> difference with encoder.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
> v3: change txt files to yaml.
> ---
>  .../media/mediatek,vcodec-decoder.yaml        | 138 ++++++++++++++++++
>  .../media/mediatek,vcodec-encoder.yaml        | 128 ++++++++++++++++
>  .../bindings/media/mediatek-vcodec.txt        | 130 -----------------
>  3 files changed, 266 insertions(+), 130 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
>  delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
> new file mode 100644
> index 000000000000..ea44acfeeb9f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
> @@ -0,0 +1,138 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-encoder.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Video Decode Accelerator With Component
> +
> +maintainers:
> +  - Yunfei Dong <yunfei.dong at mediatek.com>
> +
> +description: |+
> +  Mediatek Video Decode is the video decode hardware present in Mediatek
> +  SoCs which supports high resolution decoding functionalities.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8173-vcodec-dec
> +      - mediatek,mt8183-vcodec-dec
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 8
> +
> +  clock-names:
> +    items:
> +      - const: vcodecpll
> +      - const: univpll_d2
> +      - const: clk_cci400_sel
> +      - const: vdec_sel
> +      - const: vdecpll
> +      - const: vencpll
> +      - const: venc_lt_sel
> +      - const: vdec_bus_clk_src
> +
> +  assigned-clocks: true
> +
> +  assigned-clock-parents: true
> +
> +  iommus:
> +    minItems: 1
> +    maxItems: 32
> +    description: |
> +      List of the hardware port in respective IOMMU block for current Socs.
> +      Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +  dma-ranges:
> +    maxItems: 1
> +    description: |
> +      Describes the physical address space of IOMMU maps to memory.
> +
> +  mediatek,larb:
> +    maxItems: 1

Needs a type ref. Run 'make dt_binding_check' and it will tell you these 
things instead of me.

> +    description: |
> +      Mmust contain the local arbiters in the current Socs.
> +
> +  mediatek,scp:
> +    maxItems: 1

Needs a type ref. 

> +
> +  mediatek,scp:

Duplicate.

> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - iommus
> +  - assigned-clocks
> +  - assigned-clock-parents
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/mt8173-clk.h>
> +    #include <dt-bindings/memory/mt8173-larb-port.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    vcodec_dec: vcodec at 16000000 {
> +      compatible = "mediatek,mt8173-vcodec-dec";
> +      reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
> +          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
> +          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
> +          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
> +          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
> +          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
> +          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
> +          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
> +          <0 0x16026800 0 0x800>,   /*VP8_VD*/
> +          <0 0x16027000 0 0x800>,   /*VP6_VD*/
> +          <0 0x16027800 0 0x800>,   /*VP8_VL*/
> +          <0 0x16028400 0 0x400>;   /*VP9_VD*/
> +      interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
> +      mediatek,larb = <&larb1>;
> +      iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
> +             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
> +             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
> +             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
> +             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
> +             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
> +             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
> +             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
> +      mediatek,vpu = <&vpu>;
> +      power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
> +      clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
> +             <&topckgen CLK_TOP_UNIVPLL_D2>,
> +             <&topckgen CLK_TOP_CCI400_SEL>,
> +             <&topckgen CLK_TOP_VDEC_SEL>,
> +             <&topckgen CLK_TOP_VCODECPLL>,
> +             <&apmixedsys CLK_APMIXED_VENCPLL>,
> +             <&topckgen CLK_TOP_VENC_LT_SEL>,
> +             <&topckgen CLK_TOP_VCODECPLL_370P5>;
> +      clock-names = "vcodecpll",
> +                  "univpll_d2",
> +                  "clk_cci400_sel",
> +                  "vdec_sel",
> +                  "vdecpll",
> +                  "vencpll",
> +                  "venc_lt_sel",
> +                  "vdec_bus_clk_src";
> +      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
> +                      <&topckgen CLK_TOP_CCI400_SEL>,
> +                      <&topckgen CLK_TOP_VDEC_SEL>,
> +                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
> +                      <&apmixedsys CLK_APMIXED_VENCPLL>;
> +      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
> +                             <&topckgen CLK_TOP_UNIVPLL_D2>,
> +                             <&topckgen CLK_TOP_VCODECPLL>;
> +      assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
> +    };
> \ No newline at end of file
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
> new file mode 100644
> index 000000000000..feb0697cf50e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
> @@ -0,0 +1,128 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-encoder.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Video Encode Accelerator With Component
> +
> +maintainers:
> +  - Yunfei Dong <yunfei.dong at mediatek.com>
> +
> +description: |+
> +  Mediatek Video Encode is the video encode hardware present in Mediatek
> +  SoCs which supports high resolution decoding functionalities.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8173-vcodec-enc-vp8
> +      - mediatek,mt8173-vcodec-enc
> +      - mediatek,mt8183-vcodec-enc
> +      - mediatek,mt8192-vcodec-enc
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 5
> +
> +  clock-names:
> +    items:
> +      - const: vdec_sel
> +      - const: vdec-soc-vdec
> +      - const: vdec-soc-lat
> +      - const: vdec-vdec
> +      - const: vdec-top
> +
> +  assigned-clocks: true
> +
> +  assigned-clock-parents: true
> +
> +  iommus:
> +    minItems: 1
> +    maxItems: 32
> +    description: |
> +      List of the hardware port in respective IOMMU block for current Socs.
> +      Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +  dma-ranges:
> +    maxItems: 1
> +    description: |
> +      Describes the physical address space of IOMMU maps to memory.
> +
> +  mediatek,larb:
> +    maxItems: 1
> +    description: |
> +      Mmust contain the local arbiters in the current Socs.
> +
> +  mediatek,scp:
> +    maxItems: 1
> +
> +  mediatek,scp:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - iommus
> +  - assigned-clocks
> +  - assigned-clock-parents
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/mt8173-clk.h>
> +    #include <dt-bindings/memory/mt8173-larb-port.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    vcodec_enc_avc: vcodec at 18002000 {
> +      compatible = "mediatek,mt8173-vcodec-enc";
> +      reg = <0 0x18002000 0 0x1000>;
> +      interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
> +      iommus = <&iommu M4U_PORT_VENC_RCPU>,
> +             <&iommu M4U_PORT_VENC_REC>,
> +             <&iommu M4U_PORT_VENC_BSDMA>,
> +             <&iommu M4U_PORT_VENC_SV_COMV>,
> +             <&iommu M4U_PORT_VENC_RD_COMV>,
> +             <&iommu M4U_PORT_VENC_CUR_LUMA>,
> +             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
> +             <&iommu M4U_PORT_VENC_REF_LUMA>,
> +             <&iommu M4U_PORT_VENC_REF_CHROMA>,
> +             <&iommu M4U_PORT_VENC_NBM_RDMA>,
> +             <&iommu M4U_PORT_VENC_NBM_WDMA>;
> +      mediatek,larb = <&larb3>;
> +      mediatek,vpu = <&vpu>;
> +      clocks = <&topckgen CLK_TOP_VENC_SEL>;
> +      clock-names = "venc_sel";
> +      assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
> +      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
> +    };
> +
> +    vcodec_enc_vp8: vcodec at 19002000 {
> +      compatible = "mediatek,mt8173-vcodec-enc-vp8";
> +      reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
> +      interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
> +      iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
> +             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
> +             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
> +             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
> +             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
> +             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
> +             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
> +             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
> +             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
> +      mediatek,larb = <&larb5>;
> +      mediatek,vpu = <&vpu>;
> +      clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
> +      clock-names = "venc_lt_sel";
> +      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
> +      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
> +    };
> \ No newline at end of file

Fix this.

> diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> deleted file mode 100644
> index c44a6e6943af..000000000000
> --- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> +++ /dev/null
> @@ -1,130 +0,0 @@
> -Mediatek Video Codec
> -
> -Mediatek Video Codec is the video codec hw present in Mediatek SoCs which
> -supports high resolution encoding and decoding functionalities.
> -
> -Required properties:
> -- compatible : must be one of the following string:
> -  "mediatek,mt8173-vcodec-enc-vp8" for mt8173 vp8 encoder.
> -  "mediatek,mt8173-vcodec-enc" for mt8173 avc encoder.
> -  "mediatek,mt8183-vcodec-enc" for MT8183 encoder.
> -  "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
> -  "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
> -  "mediatek,mt8183-vcodec-dec" for MT8183 decoder.
> -- reg : Physical base address of the video codec registers and length of
> -  memory mapped region.
> -- interrupts : interrupt number to the cpu.
> -- mediatek,larb : must contain the local arbiters in the current Socs.
> -- clocks : list of clock specifiers, corresponding to entries in
> -  the clock-names property.
> -- clock-names: avc encoder must contain "venc_sel", vp8 encoder must
> -  contain "venc_lt_sel", decoder must contain "vcodecpll", "univpll_d2",
> -  "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", "venc_lt_sel",
> -  "vdec_bus_clk_src".
> -- iommus : should point to the respective IOMMU block with master port as
> -  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
> -  for details.
> -- dma-ranges : describes the dma address range space that the codec hw access.
> -One of the two following nodes:
> -- mediatek,vpu : the node of the video processor unit, if using VPU.
> -- mediatek,scp : the node of the SCP unit, if using SCP.
> -
> -
> -Example:
> -
> -vcodec_dec: vcodec at 16000000 {
> -    compatible = "mediatek,mt8173-vcodec-dec";
> -    reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
> -          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
> -          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
> -          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
> -          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
> -          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
> -          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
> -          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
> -          <0 0x16026800 0 0x800>,   /*VP8_VD*/
> -          <0 0x16027000 0 0x800>,   /*VP6_VD*/
> -          <0 0x16027800 0 0x800>,   /*VP8_VL*/
> -          <0 0x16028400 0 0x400>;   /*VP9_VD*/
> -    interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
> -    mediatek,larb = <&larb1>;
> -    iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
> -             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
> -             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
> -             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
> -             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
> -             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
> -             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
> -             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
> -    mediatek,vpu = <&vpu>;
> -    power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
> -    clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
> -             <&topckgen CLK_TOP_UNIVPLL_D2>,
> -             <&topckgen CLK_TOP_CCI400_SEL>,
> -             <&topckgen CLK_TOP_VDEC_SEL>,
> -             <&topckgen CLK_TOP_VCODECPLL>,
> -             <&apmixedsys CLK_APMIXED_VENCPLL>,
> -             <&topckgen CLK_TOP_VENC_LT_SEL>,
> -             <&topckgen CLK_TOP_VCODECPLL_370P5>;
> -    clock-names = "vcodecpll",
> -                  "univpll_d2",
> -                  "clk_cci400_sel",
> -                  "vdec_sel",
> -                  "vdecpll",
> -                  "vencpll",
> -                  "venc_lt_sel",
> -                  "vdec_bus_clk_src";
> -    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
> -                      <&topckgen CLK_TOP_CCI400_SEL>,
> -                      <&topckgen CLK_TOP_VDEC_SEL>,
> -                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
> -                      <&apmixedsys CLK_APMIXED_VENCPLL>;
> -    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
> -                             <&topckgen CLK_TOP_UNIVPLL_D2>,
> -                             <&topckgen CLK_TOP_VCODECPLL>;
> -    assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
> -  };
> -
> -vcodec_enc_avc: vcodec at 18002000 {
> -    compatible = "mediatek,mt8173-vcodec-enc";
> -    reg = <0 0x18002000 0 0x1000>;
> -    interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
> -    iommus = <&iommu M4U_PORT_VENC_RCPU>,
> -             <&iommu M4U_PORT_VENC_REC>,
> -             <&iommu M4U_PORT_VENC_BSDMA>,
> -             <&iommu M4U_PORT_VENC_SV_COMV>,
> -             <&iommu M4U_PORT_VENC_RD_COMV>,
> -             <&iommu M4U_PORT_VENC_CUR_LUMA>,
> -             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
> -             <&iommu M4U_PORT_VENC_REF_LUMA>,
> -             <&iommu M4U_PORT_VENC_REF_CHROMA>,
> -             <&iommu M4U_PORT_VENC_NBM_RDMA>,
> -             <&iommu M4U_PORT_VENC_NBM_WDMA>;
> -    mediatek,larb = <&larb3>;
> -    mediatek,vpu = <&vpu>;
> -    clocks = <&topckgen CLK_TOP_VENC_SEL>;
> -    clock-names = "venc_sel";
> -    assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
> -    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
> -  };
> -
> -vcodec_enc_vp8: vcodec at 19002000 {
> -    compatible = "mediatek,mt8173-vcodec-enc-vp8";
> -    reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
> -    interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
> -    iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
> -             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
> -             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
> -             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
> -             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
> -             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
> -             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
> -             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
> -             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
> -    mediatek,larb = <&larb5>;
> -    mediatek,vpu = <&vpu>;
> -    clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
> -    clock-names = "venc_lt_sel";
> -    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
> -    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
> -  };
> -- 
> 2.25.1
> 
> 


From broonie at kernel.org  Mon Aug  2 13:16:14 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 2 Aug 2021 21:16:14 +0100
Subject: [PATCH 2/3] spi: modify set_cs_timing parameter
In-Reply-To: <20210719091642.24633-1-mason.zhang@mediatek.com>
References: <20210719091642.24633-1-mason.zhang@mediatek.com>
Message-ID: <20210802201614.GA39900@sirena.org.uk>

On Mon, Jul 19, 2021 at 05:16:43PM +0800, Mason Zhang wrote:
> From: Mason Zhang <Mason.Zhang at mediatek.com>
> 
> No need pass in spi_delay to set_cs_timing callback.

This breaks the build:

/mnt/kernel/drivers/spi/spi-tegra114.c: In function 'tegra_spi_probe':
/mnt/kernel/drivers/spi/spi-tegra114.c:1328:24: error: assignment to 'int (*)(struct spi_device *)' from incompatible pointer type 'int (*)(struct spi_device *, struct spi_delay *, struct spi_delay *, struct spi_delay *)' [-Werror=incompatible-pointer-types]
  master->set_cs_timing = tegra_spi_set_hw_cs_timing;
                        ^
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210802/1ad17dc6/attachment.sig>

From linux at armlinux.org.uk  Mon Aug  2 13:28:55 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 2 Aug 2021 21:28:55 +0100
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <CAHp75VcpA0vOwN8gBj2iikXW2dw+KCgZEM=QJ5Jx6UWqww=iCw@mail.gmail.com>
References: <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
 <20210802094810.GJ22278@shell.armlinux.org.uk>
 <20210802152755.ibisunvibmwhiyry@pengutronix.de>
 <20210802163824.GK22278@shell.armlinux.org.uk>
 <CAHp75VcpA0vOwN8gBj2iikXW2dw+KCgZEM=QJ5Jx6UWqww=iCw@mail.gmail.com>
Message-ID: <20210802202855.GL22278@shell.armlinux.org.uk>

On Mon, Aug 02, 2021 at 08:13:05PM +0300, Andy Shevchenko wrote:
> On Mon, Aug 2, 2021 at 7:38 PM Russell King (Oracle)
> <linux at armlinux.org.uk> wrote:
> > It probably depends on where you stand on power management and power
> > efficiency issues. Personally, I would like to see more effort put
> > into drivers to make them more power efficient, and I believe in the
> > coming years, power efficiency is going to become a big issue.
> 
> While in the ideal world I 100% agree with the approach, IRL we have
> to deal with constantly degrading quality of the code and instead of
> thinking about power management and efficiency the absence of APIs
> such as discussed provokes not only creating the power management
> inefficient code, but also memory leaks here and there.

The point of my previous reply that you quoted above was to make a
prediction, it wasn't a rejection of the approach.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From adobriyan at gmail.com  Mon Aug  2 13:30:00 2021
From: adobriyan at gmail.com (Alexey Dobriyan)
Date: Mon, 2 Aug 2021 23:30:00 +0300
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <20210802164747.GN1583@gate.crashing.org>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
 <20210801201336.2224111-3-adobriyan@gmail.com>
 <20210801213247.GM1583@gate.crashing.org>
 <YQeT5QRXc3CzK9nL@localhost.localdomain>
 <20210802164747.GN1583@gate.crashing.org>
Message-ID: <YQhVyOdQKUnvz1n5@localhost.localdomain>

On Mon, Aug 02, 2021 at 11:47:47AM -0500, Segher Boessenkool wrote:
> On Mon, Aug 02, 2021 at 09:42:45AM +0300, Alexey Dobriyan wrote:
> > On Sun, Aug 01, 2021 at 04:32:47PM -0500, Segher Boessenkool wrote:
> > > On Sun, Aug 01, 2021 at 11:13:36PM +0300, Alexey Dobriyan wrote:
> > > > In theory, it enables "leakage" of userspace headers into kernel which
> > > > may present licensing problem.
> > > 
> > > > -NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
> > > > +NOSTDINC_FLAGS += -nostdinc
> > > 
> > > This is removing the compiler's own include files.  These are required
> > > for all kinds of basic features, and required to be compliant to the C
> > > standard at all.
> > 
> > No they are not required.
> 
> This is false, they *are* required, whenever you want to use these
> features.  If you do not include the required headers you get undefined
> behaviour.
> 
> > Kernel uses its own bool, uintptr_t and
> > static_assert, memset(), CHAR_BIT.
> 
> Yes, and it occasionally gets it wrong.  Great fun.  See c46bbf5d2def
> for the latest episode in this saga.  (Yes I know this is uapi so maybe
> not the best example here, but it isn't like the kernel gets such things
> wrong so often these days ;-) )
> 
> The kernel *cannot* make up its own types for this.  It has to use the
> types it is required to use (by C, by the ABIs, etc.)  So why
> reimplement this?

Yes, it can. gcc headers have stuff like this:

	#define __PTRDIFF_TYPE__ long int
	#define __SIZE_TYPE__ long unsigned int

If gcc can defined standard types, kernel can too.

> > noreturn, alignas newest C standard
> > are next.
> 
> What is wrong with <stdalign.h> and <stdnoreturn.h>?

These two are actually quite nice.

Have you seen <stddef.h>? Loads of macrology crap.
Kernel can ship nicer one.

> > This version changelog didn't mention but kernel would use
> > -ffreestanding too if not other problems with the flag.
> 
> It is still true for freestanding C implementations, you just get a
> severely reduced standard library,
> 
> > > These are not "userspace headers", that is what
> > > -nostdinc takes care of already.
> > 
> > They are userspace headers in the sense they are external to the project
> > just like userspace programs are external to the kernel.
> 
> So you are going to rewrite all of the rest of GCC inside the kernel
> project as well?

What an argument. "the rest of GCC" is already there except for stdarg.h.

> > > In the case of GCC all these headers are GPL-with-runtime-exception, so
> > > claiming this can cause licensing problems is fearmongering.
> > 
> > I agree licensing problem doesn't really exist.
> > It would take gcc drop-in replacement with authors insane enough to not
> > license standard headers properly.
> 
> There does still not exist a drop-in replacement for GCC, not if you
> look closely and/or rely on details (like the kernel does).  Some of the
> differences are hidden by "linux/compiler-*.h", but hardly all.
> 
> > > I strongly advise against doing this.
> > 
> > Kernel chose to be self-contained.
> 
> That is largely historical, imo.  Nowadays this is less necessary.

I kind of agree as in kernel should use int8_t and stuff because they
are standard.

Also, -isystem removal disables <float.h> and <stdatomic.h> which is
desireable.

> Also, the kernel chose to *do* use the compiler include files.  It is
> you who wants to abolish that here.
> 
> > -isystem removal makes sense then.
> 
> -nostdinc -isystem $(shell $(CC) -print-file-name=include)  makes sense
> for that: you do indeed not want the userspace headers.  Maiming the
> compiler (by removing some of its functional parts, namely, its generic
> headers) does not make sense.
> 
> > It will be used for intrinsics where necessary.
> 
> Like, everywhere.

No, where necessary. Patch demostrates there are only a few places which
want -isystem back.


From adobriyan at gmail.com  Mon Aug  2 13:32:02 2021
From: adobriyan at gmail.com (Alexey Dobriyan)
Date: Mon, 2 Aug 2021 23:32:02 +0300
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <YQg2+C4Z98BMFucg@archlinux-ax161>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
 <20210801201336.2224111-3-adobriyan@gmail.com>
 <YQg2+C4Z98BMFucg@archlinux-ax161>
Message-ID: <YQhWQkbN+pe354RW@localhost.localdomain>

On Mon, Aug 02, 2021 at 11:18:32AM -0700, Nathan Chancellor wrote:
> On Sun, Aug 01, 2021 at 11:13:36PM +0300, Alexey Dobriyan wrote:
> > In theory, it enables "leakage" of userspace headers into kernel which
> > may present licensing problem.
> > 
> > In practice, only stdarg.h was used, stdbool.h is trivial and SIMD
> > intrinsics are contained to a few architectures and aren't global
> > problem.
> > 
> > In general, kernel is very self contained code and -isystem removal
> > will further isolate it from Ring Threeland influence.
> > 
> > nds32 keeps -isystem globally due to intrisics used in entrenched header.
> > 
> > -isystem is selectively reenabled for some files.
> > 
> > Not compile tested on hexagon.
> 
> With this series on top of v5.14-rc4 and a tangential patch to fix
> another issue, ARCH=hexagon defconfig and allmodconfig show no issues.
> 
> Tested-by: Nathan Chancellor <nathan at kernel> # build (hexagon)

Oh wow, small miracle. Thank you!

Where can I find a cross-compiler? This link doesn't seem to have one
https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.1.0/


From nathan at kernel.org  Mon Aug  2 13:38:12 2021
From: nathan at kernel.org (Nathan Chancellor)
Date: Mon, 2 Aug 2021 13:38:12 -0700
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <YQhWQkbN+pe354RW@localhost.localdomain>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
 <20210801201336.2224111-3-adobriyan@gmail.com>
 <YQg2+C4Z98BMFucg@archlinux-ax161> <YQhWQkbN+pe354RW@localhost.localdomain>
Message-ID: <3b2d77db-9bed-2535-87df-a2280f3228a3@kernel.org>

On 8/2/2021 1:32 PM, Alexey Dobriyan wrote:
> On Mon, Aug 02, 2021 at 11:18:32AM -0700, Nathan Chancellor wrote:
>> On Sun, Aug 01, 2021 at 11:13:36PM +0300, Alexey Dobriyan wrote:
>>> In theory, it enables "leakage" of userspace headers into kernel which
>>> may present licensing problem.
>>>
>>> In practice, only stdarg.h was used, stdbool.h is trivial and SIMD
>>> intrinsics are contained to a few architectures and aren't global
>>> problem.
>>>
>>> In general, kernel is very self contained code and -isystem removal
>>> will further isolate it from Ring Threeland influence.
>>>
>>> nds32 keeps -isystem globally due to intrisics used in entrenched header.
>>>
>>> -isystem is selectively reenabled for some files.
>>>
>>> Not compile tested on hexagon.
>>
>> With this series on top of v5.14-rc4 and a tangential patch to fix
>> another issue, ARCH=hexagon defconfig and allmodconfig show no issues.
>>
>> Tested-by: Nathan Chancellor <nathan at kernel> # build (hexagon)
> 
> Oh wow, small miracle. Thank you!
> 
> Where can I find a cross-compiler? This link doesn't seem to have one
> https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/11.1.0/

Hexagon only builds with LLVM now because of the bump to require gcc 
4.9: https://lore.kernel.org/r/20210623141854.GA32155 at lst.de/

Brian Cain has a link in that thread to an LLVM toolchain that works 
well for defconfig (allmodconfig requires LLVM 13/14 from git). 
Otherwise, https://apt.llvm.org or LLVM from your package manager should 
be sufficient for the same targets.

$ make -skj"$(nproc)" ARCH=hexagon CROSS_COMPILE=hexagon-linux-musl- 
LLVM=1 LLVM_IAS=1 defconfig all

should work fine as long as the bin folder for whatever toolchain you 
download is in your PATH.

Cheers,
Nathan


From lukasz.luba at arm.com  Mon Aug  2 13:45:50 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Mon,  2 Aug 2021 21:45:50 +0100
Subject: [PATCH] cpufreq: arm_scmi: Fix error path when allocation failed
Message-ID: <20210802204550.12647-1-lukasz.luba@arm.com>

Print warning and return an error which would stop the initialization
when cpumask allocation failed.

Fixes: 80a064dbd556 ("scmi-cpufreq: Get opp_shared_cpus from opp-v2 for EM")
Signed-off-by: Lukasz Luba <lukasz.luba at arm.com>
---
 drivers/cpufreq/scmi-cpufreq.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index ec9a87ca2dbb..b159123e68fd 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -133,8 +133,10 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 		return -ENODEV;
 	}
 
-	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL))
-		ret = -ENOMEM;
+	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL)) {
+		dev_warn(cpu_dev, "failed to allocate cpumask\n");
+		return -ENOMEM;
+	}
 
 	/* Obtain CPUs that share SCMI performance controls */
 	ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
-- 
2.17.1



From robh at kernel.org  Mon Aug  2 13:53:09 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 14:53:09 -0600
Subject: [PATCH] dt-bindings: auxdisplay: arm-charlcd: Convert to
 json-schema
In-Reply-To: <4a63caa4136e8a31e82c7d75bb6f273498e8cccf.1627402256.git.geert@linux-m68k.org>
References: <4a63caa4136e8a31e82c7d75bb6f273498e8cccf.1627402256.git.geert@linux-m68k.org>
Message-ID: <YQhbNWgp94o2I2mc@robh.at.kernel.org>

On Tue, 27 Jul 2021 18:11:41 +0200, Geert Uytterhoeven wrote:
> Convert the ARM Versatile Character LCD Device Tree binding documentation
> to json-schema.
> 
> Correct compatible value.
> Document missing properties.
> 
> Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
> ---
>  .../auxdisplay/arm,versatile-lcd.yaml         | 44 +++++++++++++++++++
>  .../bindings/auxdisplay/arm-charlcd.txt       | 18 --------
>  MAINTAINERS                                   |  2 +-
>  3 files changed, 45 insertions(+), 19 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/auxdisplay/arm,versatile-lcd.yaml
>  delete mode 100644 Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt
> 

Applied, thanks!


From olteanv at gmail.com  Mon Aug  2 13:59:08 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 2 Aug 2021 23:59:08 +0300
Subject: [RFC net-next v2 4/4] Revert "mt7530 mt7530_fdb_write only set
 ivl bit vid larger than 1"
In-Reply-To: <20210802154838.1817958-1-dqfext@gmail.com>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-5-dqfext@gmail.com>
 <20210802134409.dro5zjp5ymocpglf@skbuf>
 <20210802154838.1817958-1-dqfext@gmail.com>
Message-ID: <20210802205908.queaqshisqk24pkf@skbuf>

On Mon, Aug 02, 2021 at 11:48:38PM +0800, DENG Qingfang wrote:
> On Mon, Aug 02, 2021 at 04:44:09PM +0300, Vladimir Oltean wrote:
> > Would you mind explaining what made VID 1 special in Eric's patch in the
> > first place?
>
> The default value of all ports' PVID is 1, which is copied into the FDB
> entry, even if the ports are VLAN unaware. So running `bridge fdb show`
> will show entries like `dev sw0p0 vlan 1 self` even on a VLAN-unaware
> bridge.
>
> Eric probably thought VID 1 is the FDB of all VLAN-unaware bridges, but
> that is not true. And his patch probably cause a new issue that FDB is
> inaccessible in a VLAN-**aware** bridge with PVID 1.
>
> This series sets PVID to 0 on VLAN-unaware ports, so `bridge fdb show`
> will no longer print `vlan 1` on VLAN-unaware bridges, and we don't
> need special case in port_fdb_{add,del} for assisted learning.

All things seriously worth mentioning in the commit message.


From olteanv at gmail.com  Mon Aug  2 14:00:06 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 3 Aug 2021 00:00:06 +0300
Subject: [RFC net-next v2 3/4] net: dsa: mt7530: set STP state also on
 filter ID 1
In-Reply-To: <20210802155810.1818085-1-dqfext@gmail.com>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-4-dqfext@gmail.com>
 <20210802134336.gv66le6u2z52kfkh@skbuf>
 <20210802153129.1817825-1-dqfext@gmail.com>
 <20210802154226.qggqzkxe6urkx3yf@skbuf>
 <20210802155810.1818085-1-dqfext@gmail.com>
Message-ID: <20210802210006.fhmb5s6dsnziyk7d@skbuf>

On Mon, Aug 02, 2021 at 11:58:10PM +0800, DENG Qingfang wrote:
> On Mon, Aug 02, 2021 at 06:42:26PM +0300, Vladimir Oltean wrote:
> > On Mon, Aug 02, 2021 at 11:31:29PM +0800, DENG Qingfang wrote:
> > > The current code only sets FID 0's STP state. This patch sets both 0's and
> > > 1's states.
> > >
> > > The *5 part is binary magic. [1:0] is FID 0's state, [3:2] is FID 1's state
> > > and so on. Since 5 == 4'b0101, the value in [1:0] is copied to [3:2] after
> > > the multiplication.
> > >
> > > Perhaps I should only change FID 1's state.
> >
> > Keep the patches dumb for us mortals please.
> > If you only change FID 1's state, I am concerned that the driver no
> > longer initializes FID 0's port state, and might leave that to the
> > default set by other pre-kernel initialization stage (bootloader?).
> > So even if you might assume that standalone ports are FORWARDING, they
> > might not be.
>
> The default value is forwarding, and the switch is reset by the driver
> so any pre-kernel initialization stage is no more.

So then change the port STP state only for FID 1 and resend. Any other
reason why this patch series is marked RFC? It looked okay to me otherwise.


From robh at kernel.org  Mon Aug  2 14:28:28 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 15:28:28 -0600
Subject: [PATCH v4 1/4] dt-bindings: remoteproc: mediatek: Add binding
 for mt8195 scp
In-Reply-To: <20210728035859.5405-2-tinghan.shen@mediatek.com>
References: <20210728035859.5405-1-tinghan.shen@mediatek.com>
 <20210728035859.5405-2-tinghan.shen@mediatek.com>
Message-ID: <YQhjfMoloq6uza42@robh.at.kernel.org>

On Wed, 28 Jul 2021 11:58:56 +0800, Tinghan Shen wrote:
> Add mt8195 compatible to binding document. The description of required
> properties are also modified to reflect the hardware change between
> mt8183 and mt8195. The mt8195 doesn't have to control the scp clock on
> kernel side.
> 
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> ---
>  Documentation/devicetree/bindings/remoteproc/mtk,scp.txt | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 

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


From robh at kernel.org  Mon Aug  2 14:28:44 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 15:28:44 -0600
Subject: [PATCH v4 2/4] dt-bindings: remoteproc: mediatek: Add binding
 for mt8192 scp
In-Reply-To: <20210728035859.5405-3-tinghan.shen@mediatek.com>
References: <20210728035859.5405-1-tinghan.shen@mediatek.com>
 <20210728035859.5405-3-tinghan.shen@mediatek.com>
Message-ID: <YQhjjFybXYEbGki0@robh.at.kernel.org>

On Wed, 28 Jul 2021 11:58:57 +0800, Tinghan Shen wrote:
> Add mt8192 compatible to binding document.
> 
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> ---
>  Documentation/devicetree/bindings/remoteproc/mtk,scp.txt | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 

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


From robh at kernel.org  Mon Aug  2 14:31:37 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 15:31:37 -0600
Subject: [PATCH v4 3/4] dt-bindings: remoteproc: mediatek: Convert
 mtk,scp to json-schema
In-Reply-To: <20210728035859.5405-4-tinghan.shen@mediatek.com>
References: <20210728035859.5405-1-tinghan.shen@mediatek.com>
 <20210728035859.5405-4-tinghan.shen@mediatek.com>
Message-ID: <YQhkOSEP0PAN9rY7@robh.at.kernel.org>

On Wed, Jul 28, 2021 at 11:58:58AM +0800, Tinghan Shen wrote:
> Convert the mtk,scp binding to DT schema format using json-schema.
> 
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> ---
>  .../bindings/remoteproc/mtk,scp.txt           | 41 ---------
>  .../bindings/remoteproc/mtk,scp.yaml          | 85 +++++++++++++++++++
>  2 files changed, 85 insertions(+), 41 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
>  create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
> 
> diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
> deleted file mode 100644
> index 88f37dee7bca..000000000000
> --- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
> +++ /dev/null
> @@ -1,41 +0,0 @@
> -Mediatek SCP Bindings
> -----------------------------------------
> -
> -This binding provides support for ARM Cortex M4 Co-processor found on some
> -Mediatek SoCs.
> -
> -Required properties:
> -- compatible		Should be one of:
> -				"mediatek,mt8183-scp"
> -				"mediatek,mt8192-scp"
> -				"mediatek,mt8195-scp"
> -- reg			Should contain the address ranges for memory regions:
> -			SRAM, CFG, and L1TCM.
> -- reg-names		Contains the corresponding names for the memory regions:
> -			"sram", "cfg", and "l1tcm".
> -- clocks		Required by mt8183 and mt8192. Clock for co-processor
> -			(See: ../clock/clock-bindings.txt)
> -- clock-names		Required by mt8183 and mt8192. Contains the
> -			corresponding name for the clock. This should be
> -			named "main".
> -
> -Subnodes
> ---------
> -
> -Subnodes of the SCP represent rpmsg devices. The names of the devices are not
> -important. The properties of these nodes are defined by the individual bindings
> -for the rpmsg devices - but must contain the following property:
> -
> -- mtk,rpmsg-name	Contains the name for the rpmsg device. Used to match
> -			the subnode to rpmsg device announced by SCP.
> -
> -Example:
> -
> -	scp: scp at 10500000 {
> -		compatible = "mediatek,mt8183-scp";
> -		reg = <0 0x10500000 0 0x80000>,
> -		      <0 0x105c0000 0 0x5000>;
> -		reg-names = "sram", "cfg";
> -		clocks = <&infracfg CLK_INFRA_SCPSYS>;
> -		clock-names = "main";
> -	};
> diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
> new file mode 100644
> index 000000000000..dc5fcbe65dae
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
> @@ -0,0 +1,85 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/remoteproc/mtk,scp.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek SCP Bindings
> +
> +maintainers:
> +  - Tinghan Shen <tinghan.shen at mediatek.com>
> +
> +description:
> +  This binding provides support for ARM Cortex M4 Co-processor found on some
> +  Mediatek SoCs.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mediatek,mt8183-scp
> +      - mediatek,mt8192-scp
> +      - mediatek,mt8195-scp
> +
> +  reg:
> +    description: |
> +      Should contain the address ranges for memory regions SRAM and CFG,
> +    maxItems: 2
> +
> +  reg-names:
> +    description: |
> +      Contains the corresponding names for the two memory regions. These
> +      should be named "sram", "cfg".
> +
> +  clocks:
> +    description: |
> +        Clock for co-processor (see ../clock/clock-bindings.txt).
> +        Required by mt8183 and mt8192.
> +    maxItems: 1
> +
> +  clock-names:
> +    description: |
> +      Contains the corresponding name for the clock. This should be
> +      named "main". Required by mt8183 and mt8192.
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +
> +patternProperties:
> +  ".*":
> +    if:
> +      type: object
> +    then:

This can be replaced with:

additionalProperties:
  type: object
  ... and the rest below here:

> +      description:
> +        Subnodes of the SCP represent rpmsg devices. The names of the devices
> +        are not important. The properties of these nodes are defined by the
> +        individual bindings for the rpmsg devices.
> +
> +      properties:
> +        mtk,rpmsg-name:
> +          description:
> +            Contains the name for the rpmsg device. Used to match
> +            the subnode to rpmsg device announced by SCP.
> +
> +      required:
> +        - mtk,rpmsg-name
> +
> +additionalProperties: true
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt8183-clk.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +        scp: scp at 10500000 {

Drop unused labels.

> +            compatible = "mediatek,mt8183-scp";
> +            reg = <0 0x10500000 0 0x80000>,
> +                  <0 0x105c0000 0 0x5000>;
> +            reg-names = "sram", "cfg";
> +            clocks = <&infracfg CLK_INFRA_SCPSYS>;
> +            clock-names = "main";
> +        };
> +    };
> -- 
> 2.18.0
> 
> 


From robh at kernel.org  Mon Aug  2 14:33:39 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 2 Aug 2021 15:33:39 -0600
Subject: [PATCH 1/9] dt-bindings: phy: mediatek: tphy: support type
 switch by pericfg
In-Reply-To: <1627459111-2907-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1627459111-2907-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YQhks7ca6Gr5gAPC@robh.at.kernel.org>

On Wed, 28 Jul 2021 15:58:23 +0800, Chunfeng Yun wrote:
> Add support type switch by pericfg register between USB3, PCIe,
> SATA, SGMII, this is used to replace the way through efuse or
> jumper.
> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  .../devicetree/bindings/phy/mediatek,tphy.yaml   | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From segher at kernel.crashing.org  Mon Aug  2 14:42:07 2021
From: segher at kernel.crashing.org (Segher Boessenkool)
Date: Mon, 2 Aug 2021 16:42:07 -0500
Subject: [PATCH 3/3] isystem: delete global -isystem compile option
In-Reply-To: <YQhVyOdQKUnvz1n5@localhost.localdomain>
References: <20210801201336.2224111-1-adobriyan@gmail.com>
 <20210801201336.2224111-3-adobriyan@gmail.com>
 <20210801213247.GM1583@gate.crashing.org>
 <YQeT5QRXc3CzK9nL@localhost.localdomain>
 <20210802164747.GN1583@gate.crashing.org>
 <YQhVyOdQKUnvz1n5@localhost.localdomain>
Message-ID: <20210802214207.GP1583@gate.crashing.org>

On Mon, Aug 02, 2021 at 11:30:00PM +0300, Alexey Dobriyan wrote:
> On Mon, Aug 02, 2021 at 11:47:47AM -0500, Segher Boessenkool wrote:
> > The kernel *cannot* make up its own types for this.  It has to use the
> > types it is required to use (by C, by the ABIs, etc.)  So why
> > reimplement this?
> 
> Yes, it can. gcc headers have stuff like this:
> 
> 	#define __PTRDIFF_TYPE__ long int
> 	#define __SIZE_TYPE__ long unsigned int
> 
> If gcc can defined standard types, kernel can too.

The kernel *has to* use those exact same types.  So why on earth do you
feel you should reimplement this?

> > > noreturn, alignas newest C standard
> > > are next.
> > 
> > What is wrong with <stdalign.h> and <stdnoreturn.h>?
> 
> These two are actually quite nice.
> 
> Have you seen <stddef.h>? Loads of macrology crap.
> Kernel can ship nicer one.

It is a pretty tame file.  And it works correctly for *all* targets,
including all Linux targets.  Why reimplement this?  No, it takes
virtually no resources to compile this.  And you do not have to maintain
it *at all*, the compiler will take care of it.  It is standard.

> > > They are userspace headers in the sense they are external to the project
> > > just like userspace programs are external to the kernel.
> > 
> > So you are going to rewrite all of the rest of GCC inside the kernel
> > project as well?
> 
> What an argument. "the rest of GCC" is already there except for stdarg.h.

???

That is there as well.  But you want to remove it.

"The rest of GCC" is everything in cc1 (the compiler binary), in libgcc
(not that the kernel wants that either on most targets, although it is
required), etc.  A few GB of binary goodness.

> > > Kernel chose to be self-contained.
> > 
> > That is largely historical, imo.  Nowadays this is less necessary.
> 
> I kind of agree as in kernel should use int8_t and stuff because they
> are standard.

s8 is a much nicer name, heh.  But it could
  #define s8 int8_t
certainly.

What I meant was the kernel wanted to avoid standard headers because
those traditionally have been a bit problematic.  But decades have gone
by, and nowadays the kernel's own headers are at least as bad.

> Also, -isystem removal disables <float.h> and <stdatomic.h> which is
> desireable.

Why?  Do you think  #include <float.h>  will ever make it past code
review?  Do you need to throw up extra barriers so people will have a
harder time changing that policy, if ever they think that a good idea?

> > > It will be used for intrinsics where necessary.
> > 
> > Like, everywhere.
> 
> No, where necessary. Patch demostrates there are only a few places which
> want -isystem back.

Yes, where necessary, that is what I said.  So, potentially everywhere.
An arch can decide to use some builtin in a generic header, for example.

Your patch makes for more work in the future, that is the best it does.


Segher


From pasha.tatashin at soleen.com  Mon Aug  2 14:53:54 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:53:54 -0400
Subject: [PATCH v16 01/15] arm64: kernel: add helper for booted at EL2 and not
 VHE
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-2-pasha.tatashin@soleen.com>

Replace places that contain logic like this:
	is_hyp_mode_available() && !is_kernel_in_hyp_mode()

With a dedicated boolean function  is_hyp_nvhe(). This will be needed
later in kexec in order to sooner switch back to EL2.

Suggested-by: James Morse <james.morse at arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/virt.h | 5 +++++
 arch/arm64/kernel/cpu-reset.h | 3 +--
 arch/arm64/kernel/hibernate.c | 2 +-
 arch/arm64/kernel/sdei.c      | 2 +-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 7379f35ae2c6..a9457e96203c 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -128,6 +128,11 @@ static __always_inline bool is_protected_kvm_enabled(void)
 		return cpus_have_final_cap(ARM64_KVM_PROTECTED_MODE);
 }
 
+static inline bool is_hyp_nvhe(void)
+{
+	return is_hyp_mode_available() && !is_kernel_in_hyp_mode();
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* ! __ASM__VIRT_H */
diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h
index 9a7b1262ef17..81b3d0fe7a63 100644
--- a/arch/arm64/kernel/cpu-reset.h
+++ b/arch/arm64/kernel/cpu-reset.h
@@ -20,8 +20,7 @@ static inline void __noreturn __nocfi cpu_soft_restart(unsigned long entry,
 {
 	typeof(__cpu_soft_restart) *restart;
 
-	unsigned long el2_switch = !is_kernel_in_hyp_mode() &&
-		is_hyp_mode_available();
+	unsigned long el2_switch = is_hyp_nvhe();
 	restart = (void *)__pa_symbol(function_nocfi(__cpu_soft_restart));
 
 	cpu_install_idmap();
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 46a0b4d6e251..4c9533f4c0c4 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -49,7 +49,7 @@
 extern int in_suspend;
 
 /* Do we need to reset el2? */
-#define el2_reset_needed() (is_hyp_mode_available() && !is_kernel_in_hyp_mode())
+#define el2_reset_needed() (is_hyp_nvhe())
 
 /* temporary el2 vectors in the __hibernate_exit_text section. */
 extern char hibernate_el2_vectors[];
diff --git a/arch/arm64/kernel/sdei.c b/arch/arm64/kernel/sdei.c
index 47f77d1234cb..d20620a1c51a 100644
--- a/arch/arm64/kernel/sdei.c
+++ b/arch/arm64/kernel/sdei.c
@@ -202,7 +202,7 @@ unsigned long sdei_arch_get_entry_point(int conduit)
 	 * dropped to EL1 because we don't support VHE, then we can't support
 	 * SDEI.
 	 */
-	if (is_hyp_mode_available() && !is_kernel_in_hyp_mode()) {
+	if (is_hyp_nvhe()) {
 		pr_err("Not supported on this hardware/boot configuration\n");
 		goto out_err;
 	}
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:53:53 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:53:53 -0400
Subject: [PATCH v16 00/15] arm64: MMU enabled kexec relocation
Message-ID: <20210802215408.804942-1-pasha.tatashin@soleen.com>

Changelog:
v16:
	- Merged with 5.14-rc4
v15:
	- Changed trans_pgd_copy_el2_vectors() to use vector table that
	  only shared by kexec and hibernate. This way sync does not have
	  dangling branch that was recently introduced. (Reported by Marc
	  Zyngier)
	- Renamed is_hyp_callable() to is_hyp_nvhe() as requested by Marc
	  Zyngier
	- Clean-ups, comment fixes.
	- Sync with upstream 368094df48e680fa51cedb68537408cfa64b788e
v14:
	- Fixed a bug in "arm64: hyp-stub: Move elx_sync into the vectors"
	  that was noticed by Marc Zyngier
	- Merged with upstream
v13:
	- Fixed a hang on ThunderX2, thank you Pingfan Liu for reporting
	  the problem. In relocation function we need civac not ivac, we
	  need to clean data in addition to invalidating it.
	  Since I was using ThunderX2 machine I also measured the new
	  performance data on this large ARM64 server. The MMU improves
	  kexec relocation 190 times on this machine! (see below for
	  raw data). Saves 7.5s during CentOS kexec reboot.
v12:
	- A major change compared to previous version. Instead of using
	  contiguous VA range a copy of linear map is now used to perform
	  copying of segments during relocation as it was agreed in the
	  discussion of version 11 of this project.
	- In addition to using linear map, I also took several ideas from
	  James Morse to better organize the kexec relocation:
	  	1. skip relocation function entirely if that is not needed
		2. remove the PoC flushing function since it is not needed
		   anymore with MMU enabled.
v11:
	- Fixed missing KEXEC_CORE dependency for trans_pgd.c
	- Removed useless "if(rc) return rc" statement (thank you Tyler Hicks)
	- Another 12 patches were accepted into maintainer's get.
	  Re-based patches against:
	  https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
	  Branch: for-next/kexec
v10:
	- Addressed a lot of comments form James Morse and from  Marc Zyngier
	- Added review-by's
	- Synchronized with mainline

v9:	- 9 patches from previous series landed in upstream, so now series
	  is smaller
	- Added two patches from James Morse to address idmap issues for machines
	  with high physical addresses.
	- Addressed comments from Selin Dag about compiling issues. He also tested
	  my series and got similar performance results: ~60 ms instead of ~580 ms
	  with an initramfs size of ~120MB.
v8:
	- Synced with mainline to keep series up-to-date
v7:
	-- Addressed comments from James Morse
	- arm64: hibernate: pass the allocated pgdp to ttbr0
	  Removed "Fixes" tag, and added Added Reviewed-by: James Morse
	- arm64: hibernate: check pgd table allocation
	  Sent out as a standalone patch so it can be sent to stable
	  Series applies on mainline + this patch
	- arm64: hibernate: add trans_pgd public functions
	  Remove second allocation of tmp_pg_dir in swsusp_arch_resume
	  Added Reviewed-by: James Morse <james.morse at arm.com>
	- arm64: kexec: move relocation function setup and clean up
	  Fixed typo in commit log
	  Changed kern_reloc to phys_addr_t types.
	  Added explanation why kern_reloc is needed.
	  Split into four patches:
	  arm64: kexec: make dtb_mem always enabled
	  arm64: kexec: remove unnecessary debug prints
	  arm64: kexec: call kexec_image_info only once
	  arm64: kexec: move relocation function setup
	- arm64: kexec: add expandable argument to relocation function
	  Changed types of new arguments from unsigned long to phys_addr_t.
	  Changed offset prefix to KEXEC_*
	  Split into four patches:
	  arm64: kexec: cpu_soft_restart change argument types
	  arm64: kexec: arm64_relocate_new_kernel clean-ups
	  arm64: kexec: arm64_relocate_new_kernel don't use x0 as temp
	  arm64: kexec: add expandable argument to relocation function
	- arm64: kexec: configure trans_pgd page table for kexec
	  Added invalid entries into EL2 vector table
	  Removed KEXEC_EL2_VECTOR_TABLE_SIZE and KEXEC_EL2_VECTOR_TABLE_OFFSET
	  Copy relocation functions and table into separate pages
	  Changed types in kern_reloc_arg.
	  Split into three patches:
	  arm64: kexec: offset for relocation function
	  arm64: kexec: kexec EL2 vectors
	  arm64: kexec: configure trans_pgd page table for kexec
	- arm64: kexec: enable MMU during kexec relocation
	  Split into two patches:
	  arm64: kexec: enable MMU during kexec relocation
	  arm64: kexec: remove head from relocation argument
v6:
	- Sync with mainline tip
	- Added Acked's from Dave Young
v5:
	- Addressed comments from Matthias Brugger: added review-by's, improved
	  comments, and made cleanups to swsusp_arch_resume() in addition to
	  create_safe_exec_page().
	- Synced with mainline tip.
v4:
	- Addressed comments from James Morse.
	- Split "check pgd table allocation" into two patches, and moved to
	  the beginning of series  for simpler backport of the fixes.
	  Added "Fixes:" tags to commit logs.
	- Changed "arm64, hibernate:" to "arm64: hibernate:"
	- Added Reviewed-by's
	- Moved "add PUD_SECT_RDONLY" earlier in series to be with other
	  clean-ups
	- Added "Derived from:" to arch/arm64/mm/trans_pgd.c
	- Removed "flags" from trans_info
	- Changed .trans_alloc_page assumption to return zeroed page.
	- Simplify changes to trans_pgd_map_page(), by keeping the old
	  code.
	- Simplify changes to trans_pgd_create_copy, by keeping the old
	  code.
	- Removed: "add trans_pgd_create_empty"
	- replace init_mm with NULL, and keep using non "__" version of
	  populate functions.
v3:
	- Split changes to create_safe_exec_page() into several patches for
	  easier review as request by Mark Rutland. This is why this series
	  has 3 more patches.
	- Renamed trans_table to tans_pgd as agreed with Mark. The header
	  comment in trans_pgd.c explains that trans stands for
	  transitional page tables. Meaning they are used in transition
	  between two kernels.
v2:
	- Fixed hibernate bug reported by James Morse
	- Addressed comments from James Morse:
	  * More incremental changes to trans_table
	  * Removed TRANS_FORCEMAP
	  * Added kexec reboot data for image with 380M in size.

Enable MMU during kexec relocation in order to improve reboot performance.

If kexec functionality is used for a fast system update, with a minimal
downtime, the relocation of kernel + initramfs takes a significant portion
of reboot.

The reason for slow relocation is because it is done without MMU, and thus
not benefiting from D-Cache.

Performance data
----------------

Cavium ThunderX2:
Kernel Image size: 38M Iniramfs size: 46M Total relocation size: 84M
MMU-disabled:
relocation	7.489539915s
MMU-enabled:
relocation	0.03946095s

Relocation performance is improved 190 times.

Broadcom Stingray:
For this experiment, the size of kernel plus initramfs is small, only 25M.
If initramfs was larger, than the improvements would be greater, as time
spent in relocation is proportional to the size of relocation.

MMU-disabled::
kernel shutdown	0.022131328s
relocation	0.440510736s
kernel startup	0.294706768s

Relocation was taking: 58.2% of reboot time

MMU-enabled:
kernel shutdown	0.032066576s
relocation	0.022158152s
kernel startup	0.296055880s

Now: Relocation takes 6.3% of reboot time

Total reboot is x2.16 times faster.

With bigger userland (fitImage 380M), the reboot time is improved by 3.57s,
and is reduced from 3.9s down to 0.33s

Previous approaches and discussions
-----------------------------------
v15: https://lore.kernel.org/lkml/20210609004419.936873-1-pasha.tatashin at soleen.com
v14: https://lore.kernel.org/lkml/20210527150526.271941-1-pasha.tatashin at soleen.com
v13: https://lore.kernel.org/lkml/20210408040537.2703241-1-pasha.tatashin at soleen.com
v12: https://lore.kernel.org/lkml/20210303002230.1083176-1-pasha.tatashin at soleen.com
v11: https://lore.kernel.org/lkml/20210127172706.617195-1-pasha.tatashin at soleen.com
v10: https://lore.kernel.org/linux-arm-kernel/20210125191923.1060122-1-pasha.tatashin at soleen.com
v9: https://lore.kernel.org/lkml/20200326032420.27220-1-pasha.tatashin at soleen.com
v8: https://lore.kernel.org/lkml/20191204155938.2279686-1-pasha.tatashin at soleen.com
v7: https://lore.kernel.org/lkml/20191016200034.1342308-1-pasha.tatashin at soleen.com
v6: https://lore.kernel.org/lkml/20191004185234.31471-1-pasha.tatashin at soleen.com
v5: https://lore.kernel.org/lkml/20190923203427.294286-1-pasha.tatashin at soleen.com
v4: https://lore.kernel.org/lkml/20190909181221.309510-1-pasha.tatashin at soleen.com
v3: https://lore.kernel.org/lkml/20190821183204.23576-1-pasha.tatashin at soleen.com
v2: https://lore.kernel.org/lkml/20190817024629.26611-1-pasha.tatashin at soleen.com
v1: https://lore.kernel.org/lkml/20190801152439.11363-1-pasha.tatashin at soleen.com

Pavel Tatashin (15):
  arm64: kernel: add helper for booted at EL2 and not VHE
  arm64: trans_pgd: hibernate: Add trans_pgd_copy_el2_vectors
  arm64: hibernate: abstract ttrb0 setup function
  arm64: kexec: flush image and lists during kexec load time
  arm64: kexec: skip relocation code for inplace kexec
  arm64: kexec: Use dcache ops macros instead of open-coding
  arm64: kexec: pass kimage as the only argument to relocation function
  arm64: kexec: configure EL2 vectors for kexec
  arm64: kexec: relocate in EL1 mode
  arm64: kexec: use ld script for relocation function
  arm64: kexec: install a copy of the linear-map
  arm64: kexec: keep MMU enabled during kexec relocation
  arm64: kexec: remove the pre-kexec PoC maintenance
  arm64: kexec: remove cpu-reset.h
  arm64: trans_pgd: remove trans_pgd_map_page()

 arch/arm64/Kconfig                   |   2 +-
 arch/arm64/include/asm/assembler.h   |  49 ++++++--
 arch/arm64/include/asm/kexec.h       |  12 ++
 arch/arm64/include/asm/mmu_context.h |  24 ++++
 arch/arm64/include/asm/sections.h    |   1 +
 arch/arm64/include/asm/trans_pgd.h   |  12 +-
 arch/arm64/include/asm/virt.h        |   7 ++
 arch/arm64/kernel/asm-offsets.c      |  11 ++
 arch/arm64/kernel/cpu-reset.S        |   7 +-
 arch/arm64/kernel/cpu-reset.h        |  32 -----
 arch/arm64/kernel/hibernate-asm.S    |  72 -----------
 arch/arm64/kernel/hibernate.c        |  49 ++------
 arch/arm64/kernel/machine_kexec.c    | 177 ++++++++++++++-------------
 arch/arm64/kernel/relocate_kernel.S  |  70 +++++------
 arch/arm64/kernel/sdei.c             |   2 +-
 arch/arm64/kernel/vmlinux.lds.S      |  19 +++
 arch/arm64/mm/Makefile               |   1 +
 arch/arm64/mm/trans_pgd-asm.S        |  65 ++++++++++
 arch/arm64/mm/trans_pgd.c            |  82 ++++---------
 19 files changed, 356 insertions(+), 338 deletions(-)
 delete mode 100644 arch/arm64/kernel/cpu-reset.h
 create mode 100644 arch/arm64/mm/trans_pgd-asm.S


base-commit: c500bee1c5b2f1d59b1081ac879d73268ab0ff17
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:53:56 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:53:56 -0400
Subject: [PATCH v16 03/15] arm64: hibernate: abstract ttrb0 setup function
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-4-pasha.tatashin@soleen.com>

Currently, only hibernate sets custom ttbr0 with safe idmaped function.
Kexec, is also going to be using this functionality when relocation code
is going to be idmapped.

Move the setup sequence to a dedicated cpu_install_ttbr0() for custom
ttbr0.

Suggested-by: James Morse <james.morse at arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/mmu_context.h | 24 ++++++++++++++++++++++++
 arch/arm64/kernel/hibernate.c        | 21 +--------------------
 2 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index eeb210997149..edb57e075abe 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -115,6 +115,30 @@ static inline void cpu_install_idmap(void)
 	cpu_switch_mm(lm_alias(idmap_pg_dir), &init_mm);
 }
 
+/*
+ * Load our new page tables. A strict BBM approach requires that we ensure that
+ * TLBs are free of any entries that may overlap with the global mappings we are
+ * about to install.
+ *
+ * For a real hibernate/resume/kexec cycle TTBR0 currently points to a zero
+ * page, but TLBs may contain stale ASID-tagged entries (e.g. for EFI runtime
+ * services), while for a userspace-driven test_resume cycle it points to
+ * userspace page tables (and we must point it at a zero page ourselves).
+ *
+ * We change T0SZ as part of installing the idmap. This is undone by
+ * cpu_uninstall_idmap() in __cpu_suspend_exit().
+ */
+static inline void cpu_install_ttbr0(phys_addr_t ttbr0, unsigned long t0sz)
+{
+	cpu_set_reserved_ttbr0();
+	local_flush_tlb_all();
+	__cpu_set_tcr_t0sz(t0sz);
+
+	/* avoid cpu_switch_mm() and its SW-PAN and CNP interactions */
+	write_sysreg(ttbr0, ttbr0_el1);
+	isb();
+}
+
 /*
  * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
  * avoiding the possibility of conflicting TLB entries being allocated.
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index b96ef9060e4c..2758f75d6809 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -212,26 +212,7 @@ static int create_safe_exec_page(void *src_start, size_t length,
 	if (rc)
 		return rc;
 
-	/*
-	 * Load our new page tables. A strict BBM approach requires that we
-	 * ensure that TLBs are free of any entries that may overlap with the
-	 * global mappings we are about to install.
-	 *
-	 * For a real hibernate/resume cycle TTBR0 currently points to a zero
-	 * page, but TLBs may contain stale ASID-tagged entries (e.g. for EFI
-	 * runtime services), while for a userspace-driven test_resume cycle it
-	 * points to userspace page tables (and we must point it at a zero page
-	 * ourselves).
-	 *
-	 * We change T0SZ as part of installing the idmap. This is undone by
-	 * cpu_uninstall_idmap() in __cpu_suspend_exit().
-	 */
-	cpu_set_reserved_ttbr0();
-	local_flush_tlb_all();
-	__cpu_set_tcr_t0sz(t0sz);
-	write_sysreg(trans_ttbr0, ttbr0_el1);
-	isb();
-
+	cpu_install_ttbr0(trans_ttbr0, t0sz);
 	*phys_dst_addr = virt_to_phys(page);
 
 	return 0;
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:53:55 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:53:55 -0400
Subject: [PATCH v16 02/15] arm64: trans_pgd: hibernate: Add
 trans_pgd_copy_el2_vectors
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-3-pasha.tatashin@soleen.com>

Users of trans_pgd may also need a copy of vector table because it is
also may be overwritten if a linear map can be overwritten.

Move setup of EL2 vectors from hibernate to trans_pgd, so it can be
later shared with kexec as well.

Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/trans_pgd.h |  7 +++-
 arch/arm64/include/asm/virt.h      |  2 ++
 arch/arm64/kernel/hibernate-asm.S  | 52 ---------------------------
 arch/arm64/kernel/hibernate.c      | 26 ++++++--------
 arch/arm64/mm/Makefile             |  1 +
 arch/arm64/mm/trans_pgd-asm.S      | 58 ++++++++++++++++++++++++++++++
 arch/arm64/mm/trans_pgd.c          | 25 ++++++++++++-
 7 files changed, 101 insertions(+), 70 deletions(-)
 create mode 100644 arch/arm64/mm/trans_pgd-asm.S

diff --git a/arch/arm64/include/asm/trans_pgd.h b/arch/arm64/include/asm/trans_pgd.h
index 5d08e5adf3d5..411323bda7a4 100644
--- a/arch/arm64/include/asm/trans_pgd.h
+++ b/arch/arm64/include/asm/trans_pgd.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
 /*
- * Copyright (c) 2020, Microsoft Corporation.
+ * Copyright (c) 2021, Microsoft Corporation.
  * Pavel Tatashin <pasha.tatashin at soleen.com>
  */
 
@@ -36,4 +36,9 @@ int trans_pgd_map_page(struct trans_pgd_info *info, pgd_t *trans_pgd,
 int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0,
 			 unsigned long *t0sz, void *page);
 
+int trans_pgd_copy_el2_vectors(struct trans_pgd_info *info,
+			       phys_addr_t *el2_vectors);
+
+extern char trans_pgd_stub_vectors[];
+
 #endif /* _ASM_TRANS_TABLE_H */
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index a9457e96203c..3c8af033a997 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -67,6 +67,8 @@
  */
 extern u32 __boot_cpu_mode[2];
 
+#define ARM64_VECTOR_TABLE_LEN	SZ_2K
+
 void __hyp_set_vectors(phys_addr_t phys_vector_base);
 void __hyp_reset_vectors(void);
 
diff --git a/arch/arm64/kernel/hibernate-asm.S b/arch/arm64/kernel/hibernate-asm.S
index 81c0186a5e32..a30a2c3f905e 100644
--- a/arch/arm64/kernel/hibernate-asm.S
+++ b/arch/arm64/kernel/hibernate-asm.S
@@ -112,56 +112,4 @@ alternative_insn "dc cvau, x4",  "dc civac, x4",  ARM64_WORKAROUND_CLEAN_CACHE
 	hvc	#0
 3:	ret
 SYM_CODE_END(swsusp_arch_suspend_exit)
-
-/*
- * Restore the hyp stub.
- * This must be done before the hibernate page is unmapped by _cpu_resume(),
- * but happens before any of the hyp-stub's code is cleaned to PoC.
- *
- * x24: The physical address of __hyp_stub_vectors
- */
-SYM_CODE_START_LOCAL(el1_sync)
-	msr	vbar_el2, x24
-	eret
-SYM_CODE_END(el1_sync)
-
-.macro invalid_vector	label
-SYM_CODE_START_LOCAL(\label)
-	b \label
-SYM_CODE_END(\label)
-.endm
-
-	invalid_vector	el2_sync_invalid
-	invalid_vector	el2_irq_invalid
-	invalid_vector	el2_fiq_invalid
-	invalid_vector	el2_error_invalid
-	invalid_vector	el1_sync_invalid
-	invalid_vector	el1_irq_invalid
-	invalid_vector	el1_fiq_invalid
-	invalid_vector	el1_error_invalid
-
-/* el2 vectors - switch el2 here while we restore the memory image. */
-	.align 11
-SYM_CODE_START(hibernate_el2_vectors)
-	ventry	el2_sync_invalid		// Synchronous EL2t
-	ventry	el2_irq_invalid			// IRQ EL2t
-	ventry	el2_fiq_invalid			// FIQ EL2t
-	ventry	el2_error_invalid		// Error EL2t
-
-	ventry	el2_sync_invalid		// Synchronous EL2h
-	ventry	el2_irq_invalid			// IRQ EL2h
-	ventry	el2_fiq_invalid			// FIQ EL2h
-	ventry	el2_error_invalid		// Error EL2h
-
-	ventry	el1_sync			// Synchronous 64-bit EL1
-	ventry	el1_irq_invalid			// IRQ 64-bit EL1
-	ventry	el1_fiq_invalid			// FIQ 64-bit EL1
-	ventry	el1_error_invalid		// Error 64-bit EL1
-
-	ventry	el1_sync_invalid		// Synchronous 32-bit EL1
-	ventry	el1_irq_invalid			// IRQ 32-bit EL1
-	ventry	el1_fiq_invalid			// FIQ 32-bit EL1
-	ventry	el1_error_invalid		// Error 32-bit EL1
-SYM_CODE_END(hibernate_el2_vectors)
-
 .popsection
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 4c9533f4c0c4..b96ef9060e4c 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -51,9 +51,6 @@ extern int in_suspend;
 /* Do we need to reset el2? */
 #define el2_reset_needed() (is_hyp_nvhe())
 
-/* temporary el2 vectors in the __hibernate_exit_text section. */
-extern char hibernate_el2_vectors[];
-
 /* hyp-stub vectors, used to restore el2 during resume from hibernate. */
 extern char __hyp_stub_vectors[];
 
@@ -434,6 +431,7 @@ int swsusp_arch_resume(void)
 	void *zero_page;
 	size_t exit_size;
 	pgd_t *tmp_pg_dir;
+	phys_addr_t el2_vectors;
 	void __noreturn (*hibernate_exit)(phys_addr_t, phys_addr_t, void *,
 					  void *, phys_addr_t, phys_addr_t);
 	struct trans_pgd_info trans_info = {
@@ -461,6 +459,14 @@ int swsusp_arch_resume(void)
 		return -ENOMEM;
 	}
 
+	if (el2_reset_needed()) {
+		rc = trans_pgd_copy_el2_vectors(&trans_info, &el2_vectors);
+		if (rc) {
+			pr_err("Failed to setup el2 vectors\n");
+			return rc;
+		}
+	}
+
 	exit_size = __hibernate_exit_text_end - __hibernate_exit_text_start;
 	/*
 	 * Copy swsusp_arch_suspend_exit() to a safe page. This will generate
@@ -473,26 +479,14 @@ int swsusp_arch_resume(void)
 		return rc;
 	}
 
-	/*
-	 * The hibernate exit text contains a set of el2 vectors, that will
-	 * be executed at el2 with the mmu off in order to reload hyp-stub.
-	 */
-	dcache_clean_inval_poc((unsigned long)hibernate_exit,
-			    (unsigned long)hibernate_exit + exit_size);
-
 	/*
 	 * KASLR will cause the el2 vectors to be in a different location in
 	 * the resumed kernel. Load hibernate's temporary copy into el2.
 	 *
 	 * We can skip this step if we booted at EL1, or are running with VHE.
 	 */
-	if (el2_reset_needed()) {
-		phys_addr_t el2_vectors = (phys_addr_t)hibernate_exit;
-		el2_vectors += hibernate_el2_vectors -
-			       __hibernate_exit_text_start;     /* offset */
-
+	if (el2_reset_needed())
 		__hyp_set_vectors(el2_vectors);
-	}
 
 	hibernate_exit(virt_to_phys(tmp_pg_dir), resume_hdr.ttbr1_el1,
 		       resume_hdr.reenter_kernel, restore_pblist,
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index f188c9092696..ff1e800ba7a1 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_PTDUMP_CORE)	+= ptdump.o
 obj-$(CONFIG_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
 obj-$(CONFIG_TRANS_TABLE)	+= trans_pgd.o
+obj-$(CONFIG_TRANS_TABLE)	+= trans_pgd-asm.o
 obj-$(CONFIG_DEBUG_VIRTUAL)	+= physaddr.o
 obj-$(CONFIG_ARM64_MTE)		+= mteswap.o
 KASAN_SANITIZE_physaddr.o	+= n
diff --git a/arch/arm64/mm/trans_pgd-asm.S b/arch/arm64/mm/trans_pgd-asm.S
new file mode 100644
index 000000000000..831d6369494e
--- /dev/null
+++ b/arch/arm64/mm/trans_pgd-asm.S
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Copyright (c) 2021, Microsoft Corporation.
+ * Pavel Tatashin <pasha.tatashin at soleen.com>
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/kvm_asm.h>
+
+.macro invalid_vector	label
+SYM_CODE_START_LOCAL(\label)
+	.align 7
+	b	\label
+SYM_CODE_END(\label)
+.endm
+
+.macro el1_sync_vector
+SYM_CODE_START_LOCAL(el1_sync)
+	.align 7
+	cmp	x0, #HVC_SET_VECTORS	/* Called from hibernate */
+	b.ne	1f
+	msr	vbar_el2, x1
+	mov	x0, xzr
+	eret
+1:	/* Unexpected argument, set an error */
+	mov_q	x0, HVC_STUB_ERR
+	eret
+SYM_CODE_END(el1_sync)
+.endm
+
+SYM_CODE_START(trans_pgd_stub_vectors)
+	invalid_vector	hyp_stub_el2t_sync_invalid	// Synchronous EL2t
+	invalid_vector	hyp_stub_el2t_irq_invalid	// IRQ EL2t
+	invalid_vector	hyp_stub_el2t_fiq_invalid	// FIQ EL2t
+	invalid_vector	hyp_stub_el2t_error_invalid	// Error EL2t
+
+	invalid_vector	hyp_stub_el2h_sync_invalid	// Synchronous EL2h
+	invalid_vector	hyp_stub_el2h_irq_invalid	// IRQ EL2h
+	invalid_vector	hyp_stub_el2h_fiq_invalid	// FIQ EL2h
+	invalid_vector	hyp_stub_el2h_error_invalid	// Error EL2h
+
+	el1_sync_vector					// Synchronous 64-bit EL1
+	invalid_vector	hyp_stub_el1_irq_invalid	// IRQ 64-bit EL1
+	invalid_vector	hyp_stub_el1_fiq_invalid	// FIQ 64-bit EL1
+	invalid_vector	hyp_stub_el1_error_invalid	// Error 64-bit EL1
+
+	invalid_vector	hyp_stub_32b_el1_sync_invalid	// Synchronous 32-bit EL1
+	invalid_vector	hyp_stub_32b_el1_irq_invalid	// IRQ 32-bit EL1
+	invalid_vector	hyp_stub_32b_el1_fiq_invalid	// FIQ 32-bit EL1
+	invalid_vector	hyp_stub_32b_el1_error_invalid	// Error 32-bit EL1
+	.align 11
+SYM_INNER_LABEL(__trans_pgd_stub_vectors_end, SYM_L_LOCAL)
+SYM_CODE_END(trans_pgd_stub_vectors)
+
+# Check the trans_pgd_stub_vectors didn't overflow
+.org . - (__trans_pgd_stub_vectors_end - trans_pgd_stub_vectors) + SZ_2K
diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index 527f0a39c3da..a08cf313c858 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -5,7 +5,7 @@
  *
  * This file derived from: arch/arm64/kernel/hibernate.c
  *
- * Copyright (c) 2020, Microsoft Corporation.
+ * Copyright (c) 2021, Microsoft Corporation.
  * Pavel Tatashin <pasha.tatashin at soleen.com>
  *
  */
@@ -322,3 +322,26 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0,
 
 	return 0;
 }
+
+/*
+ * Create a copy of the vector table so we can call HVC_SET_VECTORS or
+ * HVC_SOFT_RESTART from contexts where the table may be overwritten.
+ */
+int trans_pgd_copy_el2_vectors(struct trans_pgd_info *info,
+			       phys_addr_t *el2_vectors)
+{
+	void *hyp_stub = trans_alloc(info);
+
+	if (!hyp_stub)
+		return -ENOMEM;
+	*el2_vectors = virt_to_phys(hyp_stub);
+	memcpy(hyp_stub, &trans_pgd_stub_vectors, ARM64_VECTOR_TABLE_LEN);
+	caches_clean_inval_pou((unsigned long)hyp_stub,
+			       (unsigned long)hyp_stub +
+			       ARM64_VECTOR_TABLE_LEN);
+	dcache_clean_inval_poc((unsigned long)hyp_stub,
+			       (unsigned long)hyp_stub +
+			       ARM64_VECTOR_TABLE_LEN);
+
+	return 0;
+}
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:53:57 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:53:57 -0400
Subject: [PATCH v16 04/15] arm64: kexec: flush image and lists during kexec
 load time
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-5-pasha.tatashin@soleen.com>

Currently, during kexec load we are copying relocation function and
flushing it. However, we can also flush kexec relocation buffers and
if new kernel image is already in place (i.e. crash kernel), we can
also flush the new kernel image itself.

Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/kernel/machine_kexec.c | 58 ++++++++++++++-----------------
 1 file changed, 26 insertions(+), 32 deletions(-)

diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 213d56c14f60..b6d5a02cba2e 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -60,29 +60,6 @@ void machine_kexec_cleanup(struct kimage *kimage)
 	/* Empty routine needed to avoid build errors. */
 }
 
-int machine_kexec_post_load(struct kimage *kimage)
-{
-	void *reloc_code = page_to_virt(kimage->control_code_page);
-
-	memcpy(reloc_code, arm64_relocate_new_kernel,
-	       arm64_relocate_new_kernel_size);
-	kimage->arch.kern_reloc = __pa(reloc_code);
-	kexec_image_info(kimage);
-
-	/*
-	 * For execution with the MMU off, reloc_code needs to be cleaned to the
-	 * PoC and invalidated from the I-cache.
-	 */
-	dcache_clean_inval_poc((unsigned long)reloc_code,
-			    (unsigned long)reloc_code +
-				    arm64_relocate_new_kernel_size);
-	icache_inval_pou((uintptr_t)reloc_code,
-				(uintptr_t)reloc_code +
-					arm64_relocate_new_kernel_size);
-
-	return 0;
-}
-
 /**
  * machine_kexec_prepare - Prepare for a kexec reboot.
  *
@@ -163,6 +140,32 @@ static void kexec_segment_flush(const struct kimage *kimage)
 	}
 }
 
+int machine_kexec_post_load(struct kimage *kimage)
+{
+	void *reloc_code = page_to_virt(kimage->control_code_page);
+
+	/* If in place flush new kernel image, else flush lists and buffers */
+	if (kimage->head & IND_DONE)
+		kexec_segment_flush(kimage);
+	else
+		kexec_list_flush(kimage);
+
+	memcpy(reloc_code, arm64_relocate_new_kernel,
+	       arm64_relocate_new_kernel_size);
+	kimage->arch.kern_reloc = __pa(reloc_code);
+	kexec_image_info(kimage);
+
+	/* Flush the reloc_code in preparation for its execution. */
+	dcache_clean_inval_poc((unsigned long)reloc_code,
+			       (unsigned long)reloc_code +
+			       arm64_relocate_new_kernel_size);
+	icache_inval_pou((uintptr_t)reloc_code,
+			 (uintptr_t)reloc_code +
+			 arm64_relocate_new_kernel_size);
+
+	return 0;
+}
+
 /**
  * machine_kexec - Do the kexec reboot.
  *
@@ -180,13 +183,6 @@ void machine_kexec(struct kimage *kimage)
 	WARN(in_kexec_crash && (stuck_cpus || smp_crash_stop_failed()),
 		"Some CPUs may be stale, kdump will be unreliable.\n");
 
-	/* Flush the kimage list and its buffers. */
-	kexec_list_flush(kimage);
-
-	/* Flush the new image if already in place. */
-	if ((kimage != kexec_crash_image) && (kimage->head & IND_DONE))
-		kexec_segment_flush(kimage);
-
 	pr_info("Bye!\n");
 
 	local_daif_mask();
@@ -261,8 +257,6 @@ void arch_kexec_protect_crashkres(void)
 {
 	int i;
 
-	kexec_segment_flush(kexec_crash_image);
-
 	for (i = 0; i < kexec_crash_image->nr_segments; i++)
 		set_memory_valid(
 			__phys_to_virt(kexec_crash_image->segment[i].mem),
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:53:58 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:53:58 -0400
Subject: [PATCH v16 05/15] arm64: kexec: skip relocation code for inplace kexec
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-6-pasha.tatashin@soleen.com>

In case of kdump or when segments are already in place the relocation
is not needed, therefore the setup of relocation function and call to
it can be skipped.

Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
Suggested-by: James Morse <james.morse at arm.com>
---
 arch/arm64/kernel/machine_kexec.c   | 34 ++++++++++++++++++-----------
 arch/arm64/kernel/relocate_kernel.S |  3 ---
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index b6d5a02cba2e..7f1cb5a2a463 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -144,16 +144,16 @@ int machine_kexec_post_load(struct kimage *kimage)
 {
 	void *reloc_code = page_to_virt(kimage->control_code_page);
 
-	/* If in place flush new kernel image, else flush lists and buffers */
-	if (kimage->head & IND_DONE)
+	/* If in place, relocation is not used, only flush next kernel */
+	if (kimage->head & IND_DONE) {
 		kexec_segment_flush(kimage);
-	else
-		kexec_list_flush(kimage);
+		kexec_image_info(kimage);
+		return 0;
+	}
 
 	memcpy(reloc_code, arm64_relocate_new_kernel,
 	       arm64_relocate_new_kernel_size);
 	kimage->arch.kern_reloc = __pa(reloc_code);
-	kexec_image_info(kimage);
 
 	/* Flush the reloc_code in preparation for its execution. */
 	dcache_clean_inval_poc((unsigned long)reloc_code,
@@ -162,6 +162,8 @@ int machine_kexec_post_load(struct kimage *kimage)
 	icache_inval_pou((uintptr_t)reloc_code,
 			 (uintptr_t)reloc_code +
 			 arm64_relocate_new_kernel_size);
+	kexec_list_flush(kimage);
+	kexec_image_info(kimage);
 
 	return 0;
 }
@@ -188,19 +190,25 @@ void machine_kexec(struct kimage *kimage)
 	local_daif_mask();
 
 	/*
-	 * cpu_soft_restart will shutdown the MMU, disable data caches, then
-	 * transfer control to the kern_reloc which contains a copy of
-	 * the arm64_relocate_new_kernel routine.  arm64_relocate_new_kernel
-	 * uses physical addressing to relocate the new image to its final
-	 * position and transfers control to the image entry point when the
-	 * relocation is complete.
+	 * Both restart and cpu_soft_restart will shutdown the MMU, disable data
+	 * caches. However, restart will start new kernel or purgatory directly,
+	 * cpu_soft_restart will transfer control to arm64_relocate_new_kernel
 	 * In kexec case, kimage->start points to purgatory assuming that
 	 * kernel entry and dtb address are embedded in purgatory by
 	 * userspace (kexec-tools).
 	 * In kexec_file case, the kernel starts directly without purgatory.
 	 */
-	cpu_soft_restart(kimage->arch.kern_reloc, kimage->head, kimage->start,
-			 kimage->arch.dtb_mem);
+	if (kimage->head & IND_DONE) {
+		typeof(__cpu_soft_restart) *restart;
+
+		cpu_install_idmap();
+		restart = (void *)__pa_symbol(function_nocfi(__cpu_soft_restart));
+		restart(is_hyp_nvhe(), kimage->start, kimage->arch.dtb_mem,
+			0, 0);
+	} else {
+		cpu_soft_restart(kimage->arch.kern_reloc, kimage->head,
+				 kimage->start, kimage->arch.dtb_mem);
+	}
 
 	BUG(); /* Should never get here. */
 }
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index b78ea5de97a4..8058fabe0a76 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -32,8 +32,6 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 	mov	x16, x0				/* x16 = kimage_head */
 	mov	x14, xzr			/* x14 = entry ptr */
 	mov	x13, xzr			/* x13 = copy dest */
-	/* Check if the new image needs relocation. */
-	tbnz	x16, IND_DONE_BIT, .Ldone
 	raw_dcache_line_size x15, x1		/* x15 = dcache line size */
 .Lloop:
 	and	x12, x16, PAGE_MASK		/* x12 = addr */
@@ -65,7 +63,6 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 .Lnext:
 	ldr	x16, [x14], #8			/* entry = *ptr++ */
 	tbz	x16, IND_DONE_BIT, .Lloop	/* while (!(entry & DONE)) */
-.Ldone:
 	/* wait for writes from copy_page to finish */
 	dsb	nsh
 	ic	iallu
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:53:59 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:53:59 -0400
Subject: [PATCH v16 06/15] arm64: kexec: Use dcache ops macros instead of
 open-coding
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-7-pasha.tatashin@soleen.com>

kexec does dcache maintenance when it re-writes all memory. Our
dcache_by_line_op macro depends on reading the sanitized DminLine
from memory. Kexec may have overwritten this, so open-codes the
sequence.

dcache_by_line_op is a whole set of macros, it uses dcache_line_size
which uses read_ctr for the sanitsed DminLine. Reading the DminLine
is the first thing the dcache_by_line_op does.

Rename dcache_by_line_op dcache_by_myline_op and take DminLine as
an argument. Kexec can now use the slightly smaller macro.

This makes up-coming changes to the dcache maintenance easier on
the eye.

Code generated by the existing callers is unchanged.

Suggested-by: James Morse <james.morse at arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/assembler.h  | 30 ++++++++++++++++++++++-------
 arch/arm64/kernel/relocate_kernel.S | 13 +++----------
 2 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 89faca0e740d..71999a325055 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -405,19 +405,19 @@ alternative_endif
 
 /*
  * Macro to perform a data cache maintenance for the interval
- * [start, end)
+ * [start, end) with dcache line size explicitly provided.
  *
  * 	op:		operation passed to dc instruction
  * 	domain:		domain used in dsb instruciton
  * 	start:          starting virtual address of the region
  * 	end:            end virtual address of the region
+ *	linesz:		dcache line size
  * 	fixup:		optional label to branch to on user fault
- * 	Corrupts:       start, end, tmp1, tmp2
+ * 	Corrupts:       start, end, tmp
  */
-	.macro dcache_by_line_op op, domain, start, end, tmp1, tmp2, fixup
-	dcache_line_size \tmp1, \tmp2
-	sub	\tmp2, \tmp1, #1
-	bic	\start, \start, \tmp2
+	.macro dcache_by_myline_op op, domain, start, end, linesz, tmp, fixup
+	sub	\tmp, \linesz, #1
+	bic	\start, \start, \tmp
 .Ldcache_op\@:
 	.ifc	\op, cvau
 	__dcache_op_workaround_clean_cache \op, \start
@@ -436,7 +436,7 @@ alternative_endif
 	.endif
 	.endif
 	.endif
-	add	\start, \start, \tmp1
+	add	\start, \start, \linesz
 	cmp	\start, \end
 	b.lo	.Ldcache_op\@
 	dsb	\domain
@@ -444,6 +444,22 @@ alternative_endif
 	_cond_extable .Ldcache_op\@, \fixup
 	.endm
 
+/*
+ * Macro to perform a data cache maintenance for the interval
+ * [start, end)
+ *
+ * 	op:		operation passed to dc instruction
+ * 	domain:		domain used in dsb instruciton
+ * 	start:          starting virtual address of the region
+ * 	end:            end virtual address of the region
+ * 	fixup:		optional label to branch to on user fault
+ * 	Corrupts:       start, end, tmp1, tmp2
+ */
+	.macro dcache_by_line_op op, domain, start, end, tmp1, tmp2, fixup
+	dcache_line_size \tmp1, \tmp2
+	dcache_by_myline_op \op, \domain, \start, \end, \tmp1, \tmp2, \fixup
+	.endm
+
 /*
  * Macro to perform an instruction cache maintenance for the interval
  * [start, end)
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index 8058fabe0a76..8c43779e8cc6 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -41,16 +41,9 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 	tbz	x16, IND_SOURCE_BIT, .Ltest_indirection
 
 	/* Invalidate dest page to PoC. */
-	mov     x2, x13
-	add     x20, x2, #PAGE_SIZE
-	sub     x1, x15, #1
-	bic     x2, x2, x1
-2:	dc      ivac, x2
-	add     x2, x2, x15
-	cmp     x2, x20
-	b.lo    2b
-	dsb     sy
-
+	mov	x2, x13
+	add	x1, x2, #PAGE_SIZE
+	dcache_by_myline_op ivac, sy, x2, x1, x15, x20
 	copy_page x13, x12, x1, x2, x3, x4, x5, x6, x7, x8
 	b	.Lnext
 .Ltest_indirection:
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:00 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:00 -0400
Subject: [PATCH v16 07/15] arm64: kexec: pass kimage as the only argument to
 relocation function
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-8-pasha.tatashin@soleen.com>

Currently, kexec relocation function (arm64_relocate_new_kernel) accepts
the following arguments:

head:		start of array that contains relocation information.
entry:		entry point for new kernel or purgatory.
dtb_mem:	first and only argument to entry.

The number of arguments cannot be easily expended, because this
function is also called from HVC_SOFT_RESTART, which preserves only
three arguments. And, also arm64_relocate_new_kernel is written in
assembly but called without stack, thus no place to move extra arguments
to free registers.

Soon, we will need to pass more arguments: once we enable MMU we
will need to pass information about page tables.

Pass kimage to arm64_relocate_new_kernel, and teach it to get the
required fields from kimage.

Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/kernel/asm-offsets.c     |  7 +++++++
 arch/arm64/kernel/machine_kexec.c   |  7 +++++--
 arch/arm64/kernel/relocate_kernel.S | 10 ++++------
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index c85670692afa..b41409b09d04 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -9,6 +9,7 @@
 
 #include <linux/arm_sdei.h>
 #include <linux/sched.h>
+#include <linux/kexec.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <linux/kvm_host.h>
@@ -170,6 +171,12 @@ int main(void)
   DEFINE(PTRAUTH_KERNEL_KEY_APIA,	offsetof(struct ptrauth_keys_kernel, apia));
 #endif
   BLANK();
+#endif
+#ifdef CONFIG_KEXEC_CORE
+  DEFINE(KIMAGE_ARCH_DTB_MEM,		offsetof(struct kimage, arch.dtb_mem));
+  DEFINE(KIMAGE_HEAD,			offsetof(struct kimage, head));
+  DEFINE(KIMAGE_START,			offsetof(struct kimage, start));
+  BLANK();
 #endif
   return 0;
 }
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 7f1cb5a2a463..e210b19592c6 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -84,6 +84,9 @@ static void kexec_list_flush(struct kimage *kimage)
 {
 	kimage_entry_t *entry;
 
+	dcache_clean_inval_poc((unsigned long)kimage,
+			       (unsigned long)kimage + sizeof(*kimage));
+
 	for (entry = &kimage->head; ; entry++) {
 		unsigned int flag;
 		unsigned long addr;
@@ -206,8 +209,8 @@ void machine_kexec(struct kimage *kimage)
 		restart(is_hyp_nvhe(), kimage->start, kimage->arch.dtb_mem,
 			0, 0);
 	} else {
-		cpu_soft_restart(kimage->arch.kern_reloc, kimage->head,
-				 kimage->start, kimage->arch.dtb_mem);
+		cpu_soft_restart(kimage->arch.kern_reloc, virt_to_phys(kimage),
+				 0, 0);
 	}
 
 	BUG(); /* Should never get here. */
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index 8c43779e8cc6..63ea19868f63 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -27,9 +27,7 @@
  */
 SYM_CODE_START(arm64_relocate_new_kernel)
 	/* Setup the list loop variables. */
-	mov	x18, x2				/* x18 = dtb address */
-	mov	x17, x1				/* x17 = kimage_start */
-	mov	x16, x0				/* x16 = kimage_head */
+	ldr	x16, [x0, #KIMAGE_HEAD]		/* x16 = kimage_head */
 	mov	x14, xzr			/* x14 = entry ptr */
 	mov	x13, xzr			/* x13 = copy dest */
 	raw_dcache_line_size x15, x1		/* x15 = dcache line size */
@@ -63,12 +61,12 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 	isb
 
 	/* Start new image. */
-	mov	x0, x18
+	ldr	x4, [x0, #KIMAGE_START]		/* relocation start */
+	ldr	x0, [x0, #KIMAGE_ARCH_DTB_MEM]	/* dtb address */
 	mov	x1, xzr
 	mov	x2, xzr
 	mov	x3, xzr
-	br	x17
-
+	br	x4
 SYM_CODE_END(arm64_relocate_new_kernel)
 
 .align 3	/* To keep the 64-bit values below naturally aligned. */
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:01 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:01 -0400
Subject: [PATCH v16 08/15] arm64: kexec: configure EL2 vectors for kexec
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-9-pasha.tatashin@soleen.com>

If we have a EL2 mode without VHE, the EL2 vectors are needed in order
to switch to EL2 and jump to new world with hypervisor privileges.

In preparation to MMU enabled relocation, configure our EL2 table now.

Kexec uses #HVC_SOFT_RESTART to branch to the new world, so extend
el1_sync vector that is provided by trans_pgd_copy_el2_vectors() to
support this case.

Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/Kconfig                |  2 +-
 arch/arm64/include/asm/kexec.h    |  1 +
 arch/arm64/kernel/asm-offsets.c   |  1 +
 arch/arm64/kernel/machine_kexec.c | 31 +++++++++++++++++++++++++++++++
 arch/arm64/mm/trans_pgd-asm.S     |  9 ++++++++-
 5 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5b13a932561..86dc6ddd2b8a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1138,7 +1138,7 @@ config CRASH_DUMP
 
 config TRANS_TABLE
 	def_bool y
-	depends on HIBERNATION
+	depends on HIBERNATION || KEXEC_CORE
 
 config XEN_DOM0
 	def_bool y
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 00dbcc71aeb2..753a1c398898 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -96,6 +96,7 @@ struct kimage_arch {
 	void *dtb;
 	phys_addr_t dtb_mem;
 	phys_addr_t kern_reloc;
+	phys_addr_t el2_vectors;
 };
 
 #ifdef CONFIG_KEXEC_FILE
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index b41409b09d04..47ccb57b787e 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -174,6 +174,7 @@ int main(void)
 #endif
 #ifdef CONFIG_KEXEC_CORE
   DEFINE(KIMAGE_ARCH_DTB_MEM,		offsetof(struct kimage, arch.dtb_mem));
+  DEFINE(KIMAGE_ARCH_EL2_VECTORS,	offsetof(struct kimage, arch.el2_vectors));
   DEFINE(KIMAGE_HEAD,			offsetof(struct kimage, head));
   DEFINE(KIMAGE_START,			offsetof(struct kimage, start));
   BLANK();
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index e210b19592c6..59a4b4172b68 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -21,6 +21,7 @@
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
 #include <asm/page.h>
+#include <asm/trans_pgd.h>
 
 #include "cpu-reset.h"
 
@@ -43,7 +44,9 @@ static void _kexec_image_info(const char *func, int line,
 	pr_debug("    start:       %lx\n", kimage->start);
 	pr_debug("    head:        %lx\n", kimage->head);
 	pr_debug("    nr_segments: %lu\n", kimage->nr_segments);
+	pr_debug("    dtb_mem: %pa\n", &kimage->arch.dtb_mem);
 	pr_debug("    kern_reloc: %pa\n", &kimage->arch.kern_reloc);
+	pr_debug("    el2_vectors: %pa\n", &kimage->arch.el2_vectors);
 
 	for (i = 0; i < kimage->nr_segments; i++) {
 		pr_debug("      segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
@@ -143,9 +146,27 @@ static void kexec_segment_flush(const struct kimage *kimage)
 	}
 }
 
+/* Allocates pages for kexec page table */
+static void *kexec_page_alloc(void *arg)
+{
+	struct kimage *kimage = (struct kimage *)arg;
+	struct page *page = kimage_alloc_control_pages(kimage, 0);
+
+	if (!page)
+		return NULL;
+
+	memset(page_address(page), 0, PAGE_SIZE);
+
+	return page_address(page);
+}
+
 int machine_kexec_post_load(struct kimage *kimage)
 {
 	void *reloc_code = page_to_virt(kimage->control_code_page);
+	struct trans_pgd_info info = {
+		.trans_alloc_page	= kexec_page_alloc,
+		.trans_alloc_arg	= kimage,
+	};
 
 	/* If in place, relocation is not used, only flush next kernel */
 	if (kimage->head & IND_DONE) {
@@ -154,6 +175,14 @@ int machine_kexec_post_load(struct kimage *kimage)
 		return 0;
 	}
 
+	kimage->arch.el2_vectors = 0;
+	if (is_hyp_nvhe()) {
+		int rc = trans_pgd_copy_el2_vectors(&info,
+						    &kimage->arch.el2_vectors);
+		if (rc)
+			return rc;
+	}
+
 	memcpy(reloc_code, arm64_relocate_new_kernel,
 	       arm64_relocate_new_kernel_size);
 	kimage->arch.kern_reloc = __pa(reloc_code);
@@ -209,6 +238,8 @@ void machine_kexec(struct kimage *kimage)
 		restart(is_hyp_nvhe(), kimage->start, kimage->arch.dtb_mem,
 			0, 0);
 	} else {
+		if (is_hyp_nvhe())
+			__hyp_set_vectors(kimage->arch.el2_vectors);
 		cpu_soft_restart(kimage->arch.kern_reloc, virt_to_phys(kimage),
 				 0, 0);
 	}
diff --git a/arch/arm64/mm/trans_pgd-asm.S b/arch/arm64/mm/trans_pgd-asm.S
index 831d6369494e..c1f2ed1be6de 100644
--- a/arch/arm64/mm/trans_pgd-asm.S
+++ b/arch/arm64/mm/trans_pgd-asm.S
@@ -24,7 +24,14 @@ SYM_CODE_START_LOCAL(el1_sync)
 	msr	vbar_el2, x1
 	mov	x0, xzr
 	eret
-1:	/* Unexpected argument, set an error */
+1:	cmp	x0, #HVC_SOFT_RESTART	/* Called from kexec */
+	b.ne	2f
+	mov	x0, x2
+	mov	x2, x4
+	mov	x4, x1
+	mov	x1, x3
+	br	x4
+2:	/* Unexpected argument, set an error */
 	mov_q	x0, HVC_STUB_ERR
 	eret
 SYM_CODE_END(el1_sync)
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:02 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:02 -0400
Subject: [PATCH v16 09/15] arm64: kexec: relocate in EL1 mode
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-10-pasha.tatashin@soleen.com>

Since we are going to keep MMU enabled during relocation, we need to
keep EL1 mode throughout the relocation.

Keep EL1 enabled, and switch EL2 only before entering the new world.

Suggested-by: James Morse <james.morse at arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/kernel/cpu-reset.h       |  3 +--
 arch/arm64/kernel/machine_kexec.c   |  4 ++--
 arch/arm64/kernel/relocate_kernel.S | 13 +++++++++++--
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h
index 81b3d0fe7a63..296abbac7192 100644
--- a/arch/arm64/kernel/cpu-reset.h
+++ b/arch/arm64/kernel/cpu-reset.h
@@ -20,11 +20,10 @@ static inline void __noreturn __nocfi cpu_soft_restart(unsigned long entry,
 {
 	typeof(__cpu_soft_restart) *restart;
 
-	unsigned long el2_switch = is_hyp_nvhe();
 	restart = (void *)__pa_symbol(function_nocfi(__cpu_soft_restart));
 
 	cpu_install_idmap();
-	restart(el2_switch, entry, arg0, arg1, arg2);
+	restart(0, entry, arg0, arg1, arg2);
 	unreachable();
 }
 
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 59a4b4172b68..cf5d6f22a041 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -240,8 +240,8 @@ void machine_kexec(struct kimage *kimage)
 	} else {
 		if (is_hyp_nvhe())
 			__hyp_set_vectors(kimage->arch.el2_vectors);
-		cpu_soft_restart(kimage->arch.kern_reloc, virt_to_phys(kimage),
-				 0, 0);
+		cpu_soft_restart(kimage->arch.kern_reloc,
+				 virt_to_phys(kimage), 0, 0);
 	}
 
 	BUG(); /* Should never get here. */
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index 63ea19868f63..b4fb97312a80 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -13,6 +13,7 @@
 #include <asm/kexec.h>
 #include <asm/page.h>
 #include <asm/sysreg.h>
+#include <asm/virt.h>
 
 /*
  * arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it.
@@ -61,12 +62,20 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 	isb
 
 	/* Start new image. */
+	ldr	x1, [x0, #KIMAGE_ARCH_EL2_VECTORS]	/* relocation start */
+	cbz	x1, .Lel1
+	ldr	x1, [x0, #KIMAGE_START]		/* relocation start */
+	ldr	x2, [x0, #KIMAGE_ARCH_DTB_MEM]	/* dtb address */
+	mov	x3, xzr
+	mov	x4, xzr
+	mov     x0, #HVC_SOFT_RESTART
+	hvc	#0				/* Jumps from el2 */
+.Lel1:
 	ldr	x4, [x0, #KIMAGE_START]		/* relocation start */
 	ldr	x0, [x0, #KIMAGE_ARCH_DTB_MEM]	/* dtb address */
-	mov	x1, xzr
 	mov	x2, xzr
 	mov	x3, xzr
-	br	x4
+	br	x4				/* Jumps from el1 */
 SYM_CODE_END(arm64_relocate_new_kernel)
 
 .align 3	/* To keep the 64-bit values below naturally aligned. */
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:03 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:03 -0400
Subject: [PATCH v16 10/15] arm64: kexec: use ld script for relocation function
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-11-pasha.tatashin@soleen.com>

Currently, relocation code declares start and end variables
which are used to compute its size.

The better way to do this is to use ld script incited, and put relocation
function in its own section.

Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/sections.h   |  1 +
 arch/arm64/kernel/machine_kexec.c   | 16 ++++++----------
 arch/arm64/kernel/relocate_kernel.S | 15 ++-------------
 arch/arm64/kernel/vmlinux.lds.S     | 19 +++++++++++++++++++
 4 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
index e4ad9db53af1..152cb35bf9df 100644
--- a/arch/arm64/include/asm/sections.h
+++ b/arch/arm64/include/asm/sections.h
@@ -21,5 +21,6 @@ extern char __exittext_begin[], __exittext_end[];
 extern char __irqentry_text_start[], __irqentry_text_end[];
 extern char __mmuoff_data_start[], __mmuoff_data_end[];
 extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
+extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[];
 
 #endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index cf5d6f22a041..83da6045cd45 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -21,14 +21,11 @@
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
 #include <asm/page.h>
+#include <asm/sections.h>
 #include <asm/trans_pgd.h>
 
 #include "cpu-reset.h"
 
-/* Global variables for the arm64_relocate_new_kernel routine. */
-extern const unsigned char arm64_relocate_new_kernel[];
-extern const unsigned long arm64_relocate_new_kernel_size;
-
 /**
  * kexec_image_info - For debugging output.
  */
@@ -163,6 +160,7 @@ static void *kexec_page_alloc(void *arg)
 int machine_kexec_post_load(struct kimage *kimage)
 {
 	void *reloc_code = page_to_virt(kimage->control_code_page);
+	long reloc_size;
 	struct trans_pgd_info info = {
 		.trans_alloc_page	= kexec_page_alloc,
 		.trans_alloc_arg	= kimage,
@@ -183,17 +181,15 @@ int machine_kexec_post_load(struct kimage *kimage)
 			return rc;
 	}
 
-	memcpy(reloc_code, arm64_relocate_new_kernel,
-	       arm64_relocate_new_kernel_size);
+	reloc_size = __relocate_new_kernel_end - __relocate_new_kernel_start;
+	memcpy(reloc_code, __relocate_new_kernel_start, reloc_size);
 	kimage->arch.kern_reloc = __pa(reloc_code);
 
 	/* Flush the reloc_code in preparation for its execution. */
 	dcache_clean_inval_poc((unsigned long)reloc_code,
-			       (unsigned long)reloc_code +
-			       arm64_relocate_new_kernel_size);
+			       (unsigned long)reloc_code +  reloc_size);
 	icache_inval_pou((uintptr_t)reloc_code,
-			 (uintptr_t)reloc_code +
-			 arm64_relocate_new_kernel_size);
+			 (uintptr_t)reloc_code + reloc_size);
 	kexec_list_flush(kimage);
 	kexec_image_info(kimage);
 
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index b4fb97312a80..9d2400855ee4 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -15,6 +15,7 @@
 #include <asm/sysreg.h>
 #include <asm/virt.h>
 
+.pushsection    ".kexec_relocate.text", "ax"
 /*
  * arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it.
  *
@@ -77,16 +78,4 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 	mov	x3, xzr
 	br	x4				/* Jumps from el1 */
 SYM_CODE_END(arm64_relocate_new_kernel)
-
-.align 3	/* To keep the 64-bit values below naturally aligned. */
-
-.Lcopy_end:
-.org	KEXEC_CONTROL_PAGE_SIZE
-
-/*
- * arm64_relocate_new_kernel_size - Number of bytes to copy to the
- * control_code_page.
- */
-.globl arm64_relocate_new_kernel_size
-arm64_relocate_new_kernel_size:
-	.quad	.Lcopy_end - arm64_relocate_new_kernel
+.popsection
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 709d2c433c5e..9479d66f03bf 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -63,6 +63,7 @@
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/cache.h>
 #include <asm/kernel-pgtable.h>
+#include <asm/kexec.h>
 #include <asm/memory.h>
 #include <asm/page.h>
 
@@ -100,6 +101,16 @@ jiffies = jiffies_64;
 #define HIBERNATE_TEXT
 #endif
 
+#ifdef CONFIG_KEXEC_CORE
+#define KEXEC_TEXT					\
+	. = ALIGN(SZ_4K);				\
+	__relocate_new_kernel_start = .;		\
+	*(.kexec_relocate.text)				\
+	__relocate_new_kernel_end = .;
+#else
+#define KEXEC_TEXT
+#endif
+
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 #define TRAMP_TEXT					\
 	. = ALIGN(PAGE_SIZE);				\
@@ -160,6 +171,7 @@ SECTIONS
 			HYPERVISOR_TEXT
 			IDMAP_TEXT
 			HIBERNATE_TEXT
+			KEXEC_TEXT
 			TRAMP_TEXT
 			*(.fixup)
 			*(.gnu.warning)
@@ -348,3 +360,10 @@ ASSERT(swapper_pg_dir - reserved_pg_dir == RESERVED_SWAPPER_OFFSET,
 ASSERT(swapper_pg_dir - tramp_pg_dir == TRAMP_SWAPPER_OFFSET,
        "TRAMP_SWAPPER_OFFSET is wrong!")
 #endif
+
+#ifdef CONFIG_KEXEC_CORE
+/* kexec relocation code should fit into one KEXEC_CONTROL_PAGE_SIZE */
+ASSERT(__relocate_new_kernel_end - (__relocate_new_kernel_start & ~(SZ_4K - 1))
+	<= SZ_4K, "kexec relocation code is too big or misaligned")
+ASSERT(KEXEC_CONTROL_PAGE_SIZE >= SZ_4K, "KEXEC_CONTROL_PAGE_SIZE is brokern")
+#endif
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:04 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:04 -0400
Subject: [PATCH v16 11/15] arm64: kexec: install a copy of the linear-map
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-12-pasha.tatashin@soleen.com>

To perform the kexec relocation with the MMU enabled, we need a copy
of the linear map.

Create one, and install it from the relocation code. This has to be done
from the assembly code as it will be idmapped with TTBR0. The kernel
runs in TTRB1, so can't use the break-before-make sequence on the mapping
it is executing from.

The makes no difference yet as the relocation code runs with the MMU
disabled.

Suggested-by: James Morse <james.morse at arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/assembler.h  | 19 +++++++++++++++++++
 arch/arm64/include/asm/kexec.h      |  2 ++
 arch/arm64/kernel/asm-offsets.c     |  2 ++
 arch/arm64/kernel/hibernate-asm.S   | 20 --------------------
 arch/arm64/kernel/machine_kexec.c   | 16 ++++++++++++++--
 arch/arm64/kernel/relocate_kernel.S |  3 +++
 6 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 71999a325055..4289c4e1c2a3 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -483,6 +483,25 @@ alternative_endif
 	_cond_extable .Licache_op\@, \fixup
 	.endm
 
+/*
+ * To prevent the possibility of old and new partial table walks being visible
+ * in the tlb, switch the ttbr to a zero page when we invalidate the old
+ * records. D4.7.1 'General TLB maintenance requirements' in ARM DDI 0487A.i
+ * Even switching to our copied tables will cause a changed output address at
+ * each stage of the walk.
+ */
+	.macro break_before_make_ttbr_switch zero_page, page_table, tmp, tmp2
+	phys_to_ttbr \tmp, \zero_page
+	msr	ttbr1_el1, \tmp
+	isb
+	tlbi	vmalle1
+	dsb	nsh
+	phys_to_ttbr \tmp, \page_table
+	offset_ttbr1 \tmp, \tmp2
+	msr	ttbr1_el1, \tmp
+	isb
+	.endm
+
 /*
  * reset_pmuserenr_el0 - reset PMUSERENR_EL0 if PMUv3 present
  */
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 753a1c398898..d678f0ceb7ee 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -97,6 +97,8 @@ struct kimage_arch {
 	phys_addr_t dtb_mem;
 	phys_addr_t kern_reloc;
 	phys_addr_t el2_vectors;
+	phys_addr_t ttbr1;
+	phys_addr_t zero_page;
 };
 
 #ifdef CONFIG_KEXEC_FILE
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 47ccb57b787e..a98384d13ee7 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -175,6 +175,8 @@ int main(void)
 #ifdef CONFIG_KEXEC_CORE
   DEFINE(KIMAGE_ARCH_DTB_MEM,		offsetof(struct kimage, arch.dtb_mem));
   DEFINE(KIMAGE_ARCH_EL2_VECTORS,	offsetof(struct kimage, arch.el2_vectors));
+  DEFINE(KIMAGE_ARCH_ZERO_PAGE,		offsetof(struct kimage, arch.zero_page));
+  DEFINE(KIMAGE_ARCH_TTBR1,		offsetof(struct kimage, arch.ttbr1));
   DEFINE(KIMAGE_HEAD,			offsetof(struct kimage, head));
   DEFINE(KIMAGE_START,			offsetof(struct kimage, start));
   BLANK();
diff --git a/arch/arm64/kernel/hibernate-asm.S b/arch/arm64/kernel/hibernate-asm.S
index a30a2c3f905e..0e1d9c3c6a93 100644
--- a/arch/arm64/kernel/hibernate-asm.S
+++ b/arch/arm64/kernel/hibernate-asm.S
@@ -15,26 +15,6 @@
 #include <asm/page.h>
 #include <asm/virt.h>
 
-/*
- * To prevent the possibility of old and new partial table walks being visible
- * in the tlb, switch the ttbr to a zero page when we invalidate the old
- * records. D4.7.1 'General TLB maintenance requirements' in ARM DDI 0487A.i
- * Even switching to our copied tables will cause a changed output address at
- * each stage of the walk.
- */
-.macro break_before_make_ttbr_switch zero_page, page_table, tmp, tmp2
-	phys_to_ttbr \tmp, \zero_page
-	msr	ttbr1_el1, \tmp
-	isb
-	tlbi	vmalle1
-	dsb	nsh
-	phys_to_ttbr \tmp, \page_table
-	offset_ttbr1 \tmp, \tmp2
-	msr	ttbr1_el1, \tmp
-	isb
-.endm
-
-
 /*
  * Resume from hibernate
  *
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 83da6045cd45..50bc0a265c86 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -159,6 +159,8 @@ static void *kexec_page_alloc(void *arg)
 
 int machine_kexec_post_load(struct kimage *kimage)
 {
+	int rc;
+	pgd_t *trans_pgd;
 	void *reloc_code = page_to_virt(kimage->control_code_page);
 	long reloc_size;
 	struct trans_pgd_info info = {
@@ -175,12 +177,22 @@ int machine_kexec_post_load(struct kimage *kimage)
 
 	kimage->arch.el2_vectors = 0;
 	if (is_hyp_nvhe()) {
-		int rc = trans_pgd_copy_el2_vectors(&info,
-						    &kimage->arch.el2_vectors);
+		rc = trans_pgd_copy_el2_vectors(&info,
+						&kimage->arch.el2_vectors);
 		if (rc)
 			return rc;
 	}
 
+	/* Create a copy of the linear map */
+	trans_pgd = kexec_page_alloc(kimage);
+	if (!trans_pgd)
+		return -ENOMEM;
+	rc = trans_pgd_create_copy(&info, &trans_pgd, PAGE_OFFSET, PAGE_END);
+	if (rc)
+		return rc;
+	kimage->arch.ttbr1 = __pa(trans_pgd);
+	kimage->arch.zero_page = __pa(empty_zero_page);
+
 	reloc_size = __relocate_new_kernel_end - __relocate_new_kernel_start;
 	memcpy(reloc_code, __relocate_new_kernel_start, reloc_size);
 	kimage->arch.kern_reloc = __pa(reloc_code);
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index 9d2400855ee4..a07b737533c3 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -29,10 +29,13 @@
  */
 SYM_CODE_START(arm64_relocate_new_kernel)
 	/* Setup the list loop variables. */
+	ldr	x18, [x0, #KIMAGE_ARCH_ZERO_PAGE] /* x18 = zero page for BBM */
+	ldr	x17, [x0, #KIMAGE_ARCH_TTBR1]	/* x17 = linear map copy */
 	ldr	x16, [x0, #KIMAGE_HEAD]		/* x16 = kimage_head */
 	mov	x14, xzr			/* x14 = entry ptr */
 	mov	x13, xzr			/* x13 = copy dest */
 	raw_dcache_line_size x15, x1		/* x15 = dcache line size */
+	break_before_make_ttbr_switch	x18, x17, x1, x2 /* set linear map */
 .Lloop:
 	and	x12, x16, PAGE_MASK		/* x12 = addr */
 
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:06 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:06 -0400
Subject: [PATCH v16 13/15] arm64: kexec: remove the pre-kexec PoC maintenance
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-14-pasha.tatashin@soleen.com>

Now that kexec does its relocations with the MMU enabled, we no longer
need to clean the relocation data to the PoC.

Suggested-by: James Morse <james.morse at arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/kernel/machine_kexec.c | 43 -------------------------------
 1 file changed, 43 deletions(-)

diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index b43195a7fcb6..b1856f34cc51 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -77,48 +77,6 @@ int machine_kexec_prepare(struct kimage *kimage)
 	return 0;
 }
 
-/**
- * kexec_list_flush - Helper to flush the kimage list and source pages to PoC.
- */
-static void kexec_list_flush(struct kimage *kimage)
-{
-	kimage_entry_t *entry;
-
-	dcache_clean_inval_poc((unsigned long)kimage,
-			       (unsigned long)kimage + sizeof(*kimage));
-
-	for (entry = &kimage->head; ; entry++) {
-		unsigned int flag;
-		unsigned long addr;
-
-		/* flush the list entries. */
-		dcache_clean_inval_poc((unsigned long)entry,
-				    (unsigned long)entry +
-					    sizeof(kimage_entry_t));
-
-		flag = *entry & IND_FLAGS;
-		if (flag == IND_DONE)
-			break;
-
-		addr = (unsigned long)phys_to_virt(*entry & PAGE_MASK);
-
-		switch (flag) {
-		case IND_INDIRECTION:
-			/* Set entry point just before the new list page. */
-			entry = (kimage_entry_t *)addr - 1;
-			break;
-		case IND_SOURCE:
-			/* flush the source pages. */
-			dcache_clean_inval_poc(addr, addr + PAGE_SIZE);
-			break;
-		case IND_DESTINATION:
-			break;
-		default:
-			BUG();
-		}
-	}
-}
-
 /**
  * kexec_segment_flush - Helper to flush the kimage segments to PoC.
  */
@@ -207,7 +165,6 @@ int machine_kexec_post_load(struct kimage *kimage)
 			       (unsigned long)reloc_code +  reloc_size);
 	icache_inval_pou((uintptr_t)reloc_code,
 			 (uintptr_t)reloc_code + reloc_size);
-	kexec_list_flush(kimage);
 	kexec_image_info(kimage);
 
 	return 0;
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:05 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:05 -0400
Subject: [PATCH v16 12/15] arm64: kexec: keep MMU enabled during kexec
 relocation
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-13-pasha.tatashin@soleen.com>

Now, that we have linear map page tables configured, keep MMU enabled
to allow faster relocation of segments to final destination.

Cavium ThunderX2:
Kernel Image size: 38M Iniramfs size: 46M Total relocation size: 84M
MMU-disabled:
relocation	7.489539915s
MMU-enabled:
relocation	0.03946095s

Broadcom Stingray:
The performance data: for a moderate size kernel + initramfs: 25M the
relocation was taking 0.382s, with enabled MMU it now takes
0.019s only or x20 improvement.

The time is proportional to the size of relocation, therefore if initramfs
is larger, 100M it could take over a second.

Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/kexec.h      |  3 +++
 arch/arm64/kernel/asm-offsets.c     |  1 +
 arch/arm64/kernel/machine_kexec.c   | 16 +++++++++++----
 arch/arm64/kernel/relocate_kernel.S | 31 +++++++++++++++++++----------
 4 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index d678f0ceb7ee..dca6dedc3b25 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -97,8 +97,11 @@ struct kimage_arch {
 	phys_addr_t dtb_mem;
 	phys_addr_t kern_reloc;
 	phys_addr_t el2_vectors;
+	phys_addr_t ttbr0;
 	phys_addr_t ttbr1;
 	phys_addr_t zero_page;
+	unsigned long phys_offset;
+	unsigned long t0sz;
 };
 
 #ifdef CONFIG_KEXEC_FILE
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index a98384d13ee7..134af7791249 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -176,6 +176,7 @@ int main(void)
   DEFINE(KIMAGE_ARCH_DTB_MEM,		offsetof(struct kimage, arch.dtb_mem));
   DEFINE(KIMAGE_ARCH_EL2_VECTORS,	offsetof(struct kimage, arch.el2_vectors));
   DEFINE(KIMAGE_ARCH_ZERO_PAGE,		offsetof(struct kimage, arch.zero_page));
+  DEFINE(KIMAGE_ARCH_PHYS_OFFSET,	offsetof(struct kimage, arch.phys_offset));
   DEFINE(KIMAGE_ARCH_TTBR1,		offsetof(struct kimage, arch.ttbr1));
   DEFINE(KIMAGE_HEAD,			offsetof(struct kimage, head));
   DEFINE(KIMAGE_START,			offsetof(struct kimage, start));
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 50bc0a265c86..b43195a7fcb6 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -196,6 +196,11 @@ int machine_kexec_post_load(struct kimage *kimage)
 	reloc_size = __relocate_new_kernel_end - __relocate_new_kernel_start;
 	memcpy(reloc_code, __relocate_new_kernel_start, reloc_size);
 	kimage->arch.kern_reloc = __pa(reloc_code);
+	rc = trans_pgd_idmap_page(&info, &kimage->arch.ttbr0,
+				  &kimage->arch.t0sz, reloc_code);
+	if (rc)
+		return rc;
+	kimage->arch.phys_offset = virt_to_phys(kimage) - (long)kimage;
 
 	/* Flush the reloc_code in preparation for its execution. */
 	dcache_clean_inval_poc((unsigned long)reloc_code,
@@ -230,9 +235,9 @@ void machine_kexec(struct kimage *kimage)
 	local_daif_mask();
 
 	/*
-	 * Both restart and cpu_soft_restart will shutdown the MMU, disable data
+	 * Both restart and kernel_reloc will shutdown the MMU, disable data
 	 * caches. However, restart will start new kernel or purgatory directly,
-	 * cpu_soft_restart will transfer control to arm64_relocate_new_kernel
+	 * kernel_reloc contains the body of arm64_relocate_new_kernel
 	 * In kexec case, kimage->start points to purgatory assuming that
 	 * kernel entry and dtb address are embedded in purgatory by
 	 * userspace (kexec-tools).
@@ -246,10 +251,13 @@ void machine_kexec(struct kimage *kimage)
 		restart(is_hyp_nvhe(), kimage->start, kimage->arch.dtb_mem,
 			0, 0);
 	} else {
+		void (*kernel_reloc)(struct kimage *kimage);
+
 		if (is_hyp_nvhe())
 			__hyp_set_vectors(kimage->arch.el2_vectors);
-		cpu_soft_restart(kimage->arch.kern_reloc,
-				 virt_to_phys(kimage), 0, 0);
+		cpu_install_ttbr0(kimage->arch.ttbr0, kimage->arch.t0sz);
+		kernel_reloc = (void *)kimage->arch.kern_reloc;
+		kernel_reloc(kimage);
 	}
 
 	BUG(); /* Should never get here. */
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index a07b737533c3..c81b05ac4650 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -4,6 +4,8 @@
  *
  * Copyright (C) Linaro.
  * Copyright (C) Huawei Futurewei Technologies.
+ * Copyright (C) 2020, Microsoft Corporation.
+ * Pavel Tatashin <pasha.tatashin at soleen.com>
  */
 
 #include <linux/kexec.h>
@@ -15,6 +17,13 @@
 #include <asm/sysreg.h>
 #include <asm/virt.h>
 
+.macro turn_off_mmu tmp1, tmp2
+	mov_q   \tmp1, INIT_SCTLR_EL1_MMU_OFF
+	pre_disable_mmu_workaround
+	msr	sctlr_el1, \tmp1
+	isb
+.endm
+
 .pushsection    ".kexec_relocate.text", "ax"
 /*
  * arm64_relocate_new_kernel - Put a 2nd stage image in place and boot it.
@@ -32,22 +41,21 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 	ldr	x18, [x0, #KIMAGE_ARCH_ZERO_PAGE] /* x18 = zero page for BBM */
 	ldr	x17, [x0, #KIMAGE_ARCH_TTBR1]	/* x17 = linear map copy */
 	ldr	x16, [x0, #KIMAGE_HEAD]		/* x16 = kimage_head */
-	mov	x14, xzr			/* x14 = entry ptr */
-	mov	x13, xzr			/* x13 = copy dest */
+	ldr	x22, [x0, #KIMAGE_ARCH_PHYS_OFFSET]	/* x22 phys_offset */
 	raw_dcache_line_size x15, x1		/* x15 = dcache line size */
 	break_before_make_ttbr_switch	x18, x17, x1, x2 /* set linear map */
 .Lloop:
 	and	x12, x16, PAGE_MASK		/* x12 = addr */
-
+	sub	x12, x12, x22			/* Convert x12 to virt */
 	/* Test the entry flags. */
 .Ltest_source:
 	tbz	x16, IND_SOURCE_BIT, .Ltest_indirection
 
 	/* Invalidate dest page to PoC. */
-	mov	x2, x13
-	add	x1, x2, #PAGE_SIZE
-	dcache_by_myline_op ivac, sy, x2, x1, x15, x20
+	mov	x19, x13
 	copy_page x13, x12, x1, x2, x3, x4, x5, x6, x7, x8
+	add	x1, x19, #PAGE_SIZE
+	dcache_by_myline_op civac, sy, x19, x1, x15, x20
 	b	.Lnext
 .Ltest_indirection:
 	tbz	x16, IND_INDIRECTION_BIT, .Ltest_destination
@@ -64,19 +72,20 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 	ic	iallu
 	dsb	nsh
 	isb
+	ldr	x4, [x0, #KIMAGE_START]			/* relocation start */
+	ldr	x1, [x0, #KIMAGE_ARCH_EL2_VECTORS]	/* relocation start */
+	ldr	x0, [x0, #KIMAGE_ARCH_DTB_MEM]		/* dtb address */
+	turn_off_mmu x12, x13
 
 	/* Start new image. */
-	ldr	x1, [x0, #KIMAGE_ARCH_EL2_VECTORS]	/* relocation start */
 	cbz	x1, .Lel1
-	ldr	x1, [x0, #KIMAGE_START]		/* relocation start */
-	ldr	x2, [x0, #KIMAGE_ARCH_DTB_MEM]	/* dtb address */
+	mov	x1, x4				/* relocation start */
+	mov	x2, x0				/* dtb address */
 	mov	x3, xzr
 	mov	x4, xzr
 	mov     x0, #HVC_SOFT_RESTART
 	hvc	#0				/* Jumps from el2 */
 .Lel1:
-	ldr	x4, [x0, #KIMAGE_START]		/* relocation start */
-	ldr	x0, [x0, #KIMAGE_ARCH_DTB_MEM]	/* dtb address */
 	mov	x2, xzr
 	mov	x3, xzr
 	br	x4				/* Jumps from el1 */
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:07 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:07 -0400
Subject: [PATCH v16 14/15] arm64: kexec: remove cpu-reset.h
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-15-pasha.tatashin@soleen.com>

This header contains only cpu_soft_restart() which is never used directly
anymore. So, remove this header, and rename the helper to be
cpu_soft_restart().

Suggested-by: James Morse <james.morse at arm.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/kexec.h    |  6 ++++++
 arch/arm64/kernel/cpu-reset.S     |  7 +++----
 arch/arm64/kernel/cpu-reset.h     | 30 ------------------------------
 arch/arm64/kernel/machine_kexec.c |  6 ++----
 4 files changed, 11 insertions(+), 38 deletions(-)
 delete mode 100644 arch/arm64/kernel/cpu-reset.h

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index dca6dedc3b25..9839bfc163d7 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -90,6 +90,12 @@ static inline void crash_prepare_suspend(void) {}
 static inline void crash_post_resume(void) {}
 #endif
 
+#if defined(CONFIG_KEXEC_CORE)
+void cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
+		      unsigned long arg0, unsigned long arg1,
+		      unsigned long arg2);
+#endif
+
 #define ARCH_HAS_KIMAGE_ARCH
 
 struct kimage_arch {
diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S
index d47ff63a5b66..48a8af97faa9 100644
--- a/arch/arm64/kernel/cpu-reset.S
+++ b/arch/arm64/kernel/cpu-reset.S
@@ -16,8 +16,7 @@
 .pushsection    .idmap.text, "awx"
 
 /*
- * __cpu_soft_restart(el2_switch, entry, arg0, arg1, arg2) - Helper for
- * cpu_soft_restart.
+ * cpu_soft_restart(el2_switch, entry, arg0, arg1, arg2)
  *
  * @el2_switch: Flag to indicate a switch to EL2 is needed.
  * @entry: Location to jump to for soft reset.
@@ -29,7 +28,7 @@
  * branch to what would be the reset vector. It must be executed with the
  * flat identity mapping.
  */
-SYM_CODE_START(__cpu_soft_restart)
+SYM_CODE_START(cpu_soft_restart)
 	mov_q	x12, INIT_SCTLR_EL1_MMU_OFF
 	pre_disable_mmu_workaround
 	/*
@@ -48,6 +47,6 @@ SYM_CODE_START(__cpu_soft_restart)
 	mov	x1, x3				// arg1
 	mov	x2, x4				// arg2
 	br	x8
-SYM_CODE_END(__cpu_soft_restart)
+SYM_CODE_END(cpu_soft_restart)
 
 .popsection
diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h
deleted file mode 100644
index 296abbac7192..000000000000
--- a/arch/arm64/kernel/cpu-reset.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * CPU reset routines
- *
- * Copyright (C) 2015 Huawei Futurewei Technologies.
- */
-
-#ifndef _ARM64_CPU_RESET_H
-#define _ARM64_CPU_RESET_H
-
-#include <asm/virt.h>
-
-void __cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
-	unsigned long arg0, unsigned long arg1, unsigned long arg2);
-
-static inline void __noreturn __nocfi cpu_soft_restart(unsigned long entry,
-						       unsigned long arg0,
-						       unsigned long arg1,
-						       unsigned long arg2)
-{
-	typeof(__cpu_soft_restart) *restart;
-
-	restart = (void *)__pa_symbol(function_nocfi(__cpu_soft_restart));
-
-	cpu_install_idmap();
-	restart(0, entry, arg0, arg1, arg2);
-	unreachable();
-}
-
-#endif
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index b1856f34cc51..6f1da3fd5320 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -24,8 +24,6 @@
 #include <asm/sections.h>
 #include <asm/trans_pgd.h>
 
-#include "cpu-reset.h"
-
 /**
  * kexec_image_info - For debugging output.
  */
@@ -201,10 +199,10 @@ void machine_kexec(struct kimage *kimage)
 	 * In kexec_file case, the kernel starts directly without purgatory.
 	 */
 	if (kimage->head & IND_DONE) {
-		typeof(__cpu_soft_restart) *restart;
+		typeof(cpu_soft_restart) *restart;
 
 		cpu_install_idmap();
-		restart = (void *)__pa_symbol(function_nocfi(__cpu_soft_restart));
+		restart = (void *)__pa_symbol(function_nocfi(cpu_soft_restart));
 		restart(is_hyp_nvhe(), kimage->start, kimage->arch.dtb_mem,
 			0, 0);
 	} else {
-- 
2.25.1



From pasha.tatashin at soleen.com  Mon Aug  2 14:54:08 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Mon,  2 Aug 2021 17:54:08 -0400
Subject: [PATCH v16 15/15] arm64: trans_pgd: remove trans_pgd_map_page()
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210802215408.804942-16-pasha.tatashin@soleen.com>

The intend of trans_pgd_map_page() was to map contiguous range of VA
memory to the memory that is getting relocated during kexec. However,
since we are now using linear map instead of contiguous range this
function is not needed

Suggested-by: Pingfan Liu <kernelfans at gmail.com>
Signed-off-by: Pavel Tatashin <pasha.tatashin at soleen.com>
---
 arch/arm64/include/asm/trans_pgd.h |  5 +--
 arch/arm64/mm/trans_pgd.c          | 57 ------------------------------
 2 files changed, 1 insertion(+), 61 deletions(-)

diff --git a/arch/arm64/include/asm/trans_pgd.h b/arch/arm64/include/asm/trans_pgd.h
index 411323bda7a4..c373d43c07ec 100644
--- a/arch/arm64/include/asm/trans_pgd.h
+++ b/arch/arm64/include/asm/trans_pgd.h
@@ -15,7 +15,7 @@
 /*
  * trans_alloc_page
  *	- Allocator that should return exactly one zeroed page, if this
- *	  allocator fails, trans_pgd_create_copy() and trans_pgd_map_page()
+ *	  allocator fails, trans_pgd_create_copy() and trans_pgd_idmap_page()
  *	  return -ENOMEM error.
  *
  * trans_alloc_arg
@@ -30,9 +30,6 @@ struct trans_pgd_info {
 int trans_pgd_create_copy(struct trans_pgd_info *info, pgd_t **trans_pgd,
 			  unsigned long start, unsigned long end);
 
-int trans_pgd_map_page(struct trans_pgd_info *info, pgd_t *trans_pgd,
-		       void *page, unsigned long dst_addr, pgprot_t pgprot);
-
 int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0,
 			 unsigned long *t0sz, void *page);
 
diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index a08cf313c858..b70588a42c29 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -217,63 +217,6 @@ int trans_pgd_create_copy(struct trans_pgd_info *info, pgd_t **dst_pgdp,
 	return rc;
 }
 
-/*
- * Add map entry to trans_pgd for a base-size page at PTE level.
- * info:	contains allocator and its argument
- * trans_pgd:	page table in which new map is added.
- * page:	page to be mapped.
- * dst_addr:	new VA address for the page
- * pgprot:	protection for the page.
- *
- * Returns 0 on success, and -ENOMEM on failure.
- */
-int trans_pgd_map_page(struct trans_pgd_info *info, pgd_t *trans_pgd,
-		       void *page, unsigned long dst_addr, pgprot_t pgprot)
-{
-	pgd_t *pgdp;
-	p4d_t *p4dp;
-	pud_t *pudp;
-	pmd_t *pmdp;
-	pte_t *ptep;
-
-	pgdp = pgd_offset_pgd(trans_pgd, dst_addr);
-	if (pgd_none(READ_ONCE(*pgdp))) {
-		p4dp = trans_alloc(info);
-		if (!pgdp)
-			return -ENOMEM;
-		pgd_populate(NULL, pgdp, p4dp);
-	}
-
-	p4dp = p4d_offset(pgdp, dst_addr);
-	if (p4d_none(READ_ONCE(*p4dp))) {
-		pudp = trans_alloc(info);
-		if (!pudp)
-			return -ENOMEM;
-		p4d_populate(NULL, p4dp, pudp);
-	}
-
-	pudp = pud_offset(p4dp, dst_addr);
-	if (pud_none(READ_ONCE(*pudp))) {
-		pmdp = trans_alloc(info);
-		if (!pmdp)
-			return -ENOMEM;
-		pud_populate(NULL, pudp, pmdp);
-	}
-
-	pmdp = pmd_offset(pudp, dst_addr);
-	if (pmd_none(READ_ONCE(*pmdp))) {
-		ptep = trans_alloc(info);
-		if (!ptep)
-			return -ENOMEM;
-		pmd_populate_kernel(NULL, pmdp, ptep);
-	}
-
-	ptep = pte_offset_kernel(pmdp, dst_addr);
-	set_pte(ptep, pfn_pte(virt_to_pfn(page), pgprot));
-
-	return 0;
-}
-
 /*
  * The page we want to idmap may be outside the range covered by VA_BITS that
  * can be built using the kernel's p?d_populate() helpers. As a one off, for a
-- 
2.25.1



From linus.walleij at linaro.org  Mon Aug  2 15:05:15 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 3 Aug 2021 00:05:15 +0200
Subject: [PATCH] ARM: dts: ixp4xx: Add a devicetree for Freecom FSG-3
In-Reply-To: <87sfzt0z5f.wl-maz@kernel.org>
References: <20210729144128.2834328-1-linus.walleij@linaro.org>
 <87tuk91er6.wl-maz@kernel.org> <YQan0ALPnn4aBM7y@lunn.ch>
 <87sfzt0z5f.wl-maz@kernel.org>
Message-ID: <CACRpkdaPuw9c95c3hBVxALnqOLHK6hUJiNZmwbExxD9+usKw3w@mail.gmail.com>

On Sun, Aug 1, 2021 at 8:59 PM Marc Zyngier <maz at kernel.org> wrote:
> Andrew Lunn <andrew at lunn.ch> wrote:

> > The driver exports the file "registers" in /sysfs. Do you see any sort
> > of application/driver running in userspace which might be talking to
> > the switch?
>
> Hmmm. Which driver? I don't see any switch-related driver, nor any
> userspace (what I have is an extremely minimal OpenWRT userspace that
> has hardly more than busybox).

I think Andrew is referring to CONFIG_MICREL_KS8995MA
drivers/net/phy/spi_ks8995.c (previously a Kendin product).
http://ww1.microchip.com/downloads/en/DeviceDoc/ks8995ma.pdf

We are guessing the FSG-3 has this switch.

Unfortunately we don't know which pins it is connected to,
but it is an SPI device. Should look like this:

+       spi {
+               compatible = "spi-gpio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               sck-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+               miso-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+               mosi-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+               cs-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+               num-chipselects = <1>;
+
+               switch at 0 {
+                       compatible = "micrel,ks8995";
+                       reg = <0>;
+                       spi-max-frequency = <50000000>;
+               };
+       };

Maybe you can see which pins it is using in the original firmware?

It may be completely unconnected as it can also be configured from
a companion EEPROM with no interaction from the host.

Yours,
Linus Walleij


From lkp at intel.com  Mon Aug  2 15:08:42 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 3 Aug 2021 06:08:42 +0800
Subject: [xlnx:xlnx_rebase_v5.4 19/1765] drivers/mtd/nand/raw/arasan_nand.c:
 linux/delay.h is included more than once.
Message-ID: <202108030632.G1jLzHgc-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.4
head:   2f686fa6c0bf7fa168dc45dd7ce1359217212911
commit: 1dea215e98f470c4fabe230cb5dcb648e3301fb9 [19/1765] mtd: rawnand: Add support for ARASAN NAND controller
compiler: gcc-10 (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>


includecheck warnings: (new ones prefixed by >>)
>> drivers/mtd/nand/raw/arasan_nand.c: linux/delay.h is included more than once.

Please review and possibly fold the followup patch.

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Mon Aug  2 15:08:49 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 3 Aug 2021 06:08:49 +0800
Subject: [RFC PATCH xlnx] mtd: rawnand: fix duplicated inclusion
In-Reply-To: <202108030632.G1jLzHgc-lkp@intel.com>
References: <202108030632.G1jLzHgc-lkp@intel.com>
Message-ID: <20210802220849.GA99678@1ff464ac9fe6>

Generated by: scripts/checkincludes.pl

Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: kernel test robot <lkp at intel.com>
---
 arasan_nand.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/arasan_nand.c b/drivers/mtd/nand/raw/arasan_nand.c
index b182643100df0..2adc461400992 100644
--- a/drivers/mtd/nand/raw/arasan_nand.c
+++ b/drivers/mtd/nand/raw/arasan_nand.c
@@ -8,7 +8,6 @@
  *
  */
 #include <linux/clk.h>
-#include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io-64-nonatomic-lo-hi.h>


From sboyd at kernel.org  Mon Aug  2 15:09:17 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 02 Aug 2021 15:09:17 -0700
Subject: [RESEND PATCH v4] clk: stm32f4: fix post divisor setup for
 I2S/SAI PLLs
In-Reply-To: <1371790418.70998.1627846630234@mail1.libero.it>
References: <20210725160725.10788-1-dariobin@libero.it>
 <CAPTRvHkf0cK_4ZidM17rPo99gWDmxgqFt4CDUjqFFwkOeQeFDg@mail.gmail.com>
 <1926284813.753014.1627553002984@mail1.libero.it>
 <CAPTRvH=R822osk86tRJqJCPNYY85t8t90+HJWcz43iASbcg2Jw@mail.gmail.com>
 <1371790418.70998.1627846630234@mail1.libero.it>
Message-ID: <162794215799.714452.17355927940378699473@swboyd.mtv.corp.google.com>

Quoting Dario Binacchi (2021-08-01 12:37:10)
> 
> As said in a previous email to Stephen, the patch I submitted fixes commit 517633ef630e
> ("clk: stm32f4: Add post divisor for I2S & SAI PLLs"), so IMHO it should not be dropped from the tree.
> What Dillon suggested should instead be fixed by another patch.

Ok. I'll send off the fix to Linus today.


From mcgrof at kernel.org  Mon Aug  2 15:40:02 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 2 Aug 2021 15:40:02 -0700
Subject: [PATCH v3] lib: Use PFN_PHYS() in devmem_is_allowed()
In-Reply-To: <20210731025057.78825-1-wangliang101@huawei.com>
References: <20210731025057.78825-1-wangliang101@huawei.com>
Message-ID: <YQh0Quhry/+dbTbn@bombadil.infradead.org>

On Sat, Jul 31, 2021 at 10:50:57AM +0800, Liang Wang wrote:
> The physical address may exceed 32 bits on 32-bit systems with
> more than 32 bits of physcial address,use PFN_PHYS() in devmem_is_allowed(),
> or the physical address may overflow and be truncated.
> We found this bug when mapping a high addresses through devmem tool,
> when CONFIG_STRICT_DEVMEM is enabled on the ARM with ARM_LPAE and devmem
> is used to map a high address that is not in the iomem address range,
> an unexpected error indicating no permission is returned.
> 
> This bug was initially introduced from v2.6.37, and the function was moved
> to lib when v5.11.
> 
> Cc: Luis Chamberlain <mcgrof at kernel.org>
> Fixes: 087aaffcdf9c ("ARM: implement CONFIG_STRICT_DEVMEM by disabling access to RAM via /dev/mem")
> Fixes: 527701eda5f1 ("lib: Add a generic version of devmem_is_allowed()")
> Cc: stable at vger.kernel.org # v2.6.37
> Signed-off-by: Liang Wang <wangliang101 at huawei.com>

Reviewed-by: Luis Chamberlain <mcgrof at kernel.org>

  Luis


From leoyang.li at nxp.com  Mon Aug  2 15:44:29 2021
From: leoyang.li at nxp.com (Li Yang)
Date: Mon, 2 Aug 2021 17:44:29 -0500
Subject: [PATCH] arm64: dts: ls1046a: fix eeprom entries
In-Reply-To: <1627927742-8675-1-git-send-email-raagjadav@gmail.com>
References: <1627927742-8675-1-git-send-email-raagjadav@gmail.com>
Message-ID: <CADRPPNQ2M1N1pV2brfFRXOf1ASK2bhiZpQivNhNws_+RUfCT-g@mail.gmail.com>

On Mon, Aug 2, 2021 at 1:10 PM Raag Jadav <raagjadav at gmail.com> wrote:
>
> ls1046afrwy and ls1046ardb boards have CAT24C04[1] and CAT24C05[2]
> eeproms respectively. Both are 4Kb (512 bytes) in size.

These part names are from onsemi instead of atmel.  Are there same
part names from atmel which are also compatible with the onsemi parts?
 If we want to use onsemi only part names, probably we will need two
compatible strings with the first one from onsemi and the second from
atmel.  Although the binding doesn't support onsemi prefix yet.

> Remove multi-address entries, as we have auto-rollover support
> in at24 driver.

The device tree should describe hardware instead of matching how
driver deal with it.  Is the board really using a single chip or
multiple chips here?

>
> [1] https://www.onsemi.com/pdf/datasheet/cat24c01-d.pdf
> [2] https://www.onsemi.com/pdf/datasheet/cat24c03-d.pdf
>
> Signed-off-by: Raag Jadav <raagjadav at gmail.com>
> ---
>  arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +-------
>  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts  | 7 +------
>  2 files changed, 2 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> index db3d303..83afe21 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> @@ -83,15 +83,9 @@
>                         };
>
>                         eeprom at 52 {
> -                               compatible = "atmel,24c512";
> +                               compatible = "atmel,24c04";
>                                 reg = <0x52>;
>                         };
> -
> -                       eeprom at 53 {
> -                               compatible = "atmel,24c512";
> -                               reg = <0x53>;
> -                       };
> -
>                 };
>         };
>  };
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> index 60acdf0..d220f98 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> @@ -59,14 +59,9 @@
>         };
>
>         eeprom at 52 {
> -               compatible = "atmel,24c512";
> +               compatible = "atmel,24c04";
>                 reg = <0x52>;
>         };
> -
> -       eeprom at 53 {
> -               compatible = "atmel,24c512";
> -               reg = <0x53>;
> -       };
>  };
>
>  &i2c3 {
> --
> 2.7.4
>


From chunkuang.hu at kernel.org  Mon Aug  2 16:00:37 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Tue, 3 Aug 2021 07:00:37 +0800
Subject: [PATCH v5] drm/mediatek: add dither 6 setting
In-Reply-To: <1626762588-6020-2-git-send-email-yongqiang.niu@mediatek.com>
References: <1626762588-6020-1-git-send-email-yongqiang.niu@mediatek.com>
 <1626762588-6020-2-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <CAAOTY_9ynURx3Arevk_Tdc2V2uobJbeRA_2JjmZtsc=wT2V6aA@mail.gmail.com>

Hi, Yongqiang:

Yongqiang Niu <yongqiang.niu at mediatek.com> ? 2021?7?20? ?? ??2:30???
>
> dither 6 setting is missed in a6b7c98afdca
> bit 1 is lfsr_en( "Enables LFSR-type dithering"), need enable
> bit 2 is rdither_en(Enables running order dithering), need disable
>
> Fixes: a6b7c98afdca(drm/mediatek: add mtk_dither_set_common())
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 99cbf44..7dd8e05 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -26,6 +26,7 @@
>  #define DISP_OD_CFG                            0x0020
>  #define DISP_OD_SIZE                           0x0030
>  #define DISP_DITHER_5                          0x0114
> +#define DISP_DITHER_6                          0x0118
>  #define DISP_DITHER_7                          0x011c
>  #define DISP_DITHER_15                         0x013c
>  #define DISP_DITHER_16                         0x0140
> @@ -135,6 +136,7 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
>
>         if (bpc >= MTK_MIN_BPC) {
>                 mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
> +               mtk_ddp_write(cmdq_pkt, 0x3002, cmdq_reg, regs, DISP_DITHER_6);

Symbolized 0x3002. BIT(1) is lfsr_en.

Regards,
Chun-Kuang.

>                 mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
>                 mtk_ddp_write(cmdq_pkt,
>                               DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
> --
> 1.8.1.1.dirty
>


From helgaas at kernel.org  Mon Aug  2 16:05:18 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 2 Aug 2021 18:05:18 -0500
Subject: [PATCH v6 0/8] PCI: hv: Support host bridge probing on ARM64
In-Reply-To: <YQepiKkFoJHC0gsK@boqun-archlinux>
Message-ID: <20210802230518.GA1473900@bjorn-Precision-5520>

On Mon, Aug 02, 2021 at 04:15:04PM +0800, Boqun Feng wrote:
> On Tue, Jul 27, 2021 at 02:06:49AM +0800, Boqun Feng wrote:
> > Hi,
> > 
> > This is the v6 for the preparation of virtual PCI support on Hyper-V
> > ARM64, Previous versions:
> > 
> > v1:	https://lore.kernel.org/lkml/20210319161956.2838291-1-boqun.feng at gmail.com/
> > v2:	https://lore.kernel.org/lkml/20210503144635.2297386-1-boqun.feng at gmail.com/
> > v3:	https://lore.kernel.org/lkml/20210609163211.3467449-1-boqun.feng at gmail.com/
> > v4:	https://lore.kernel.org/lkml/20210714102737.198432-1-boqun.feng at gmail.com/
> > v5:	https://lore.kernel.org/lkml/20210720134429.511541-1-boqun.feng at gmail.com/
> > 
> > Changes since last version:
> > 
> > *	Rebase to 5.14-rc3
> > 
> > *	Comment fixes as suggested by Bjorn.
> > 
> > The basic problem we need to resolve is that ARM64 is an arch with
> > PCI_DOMAINS_GENERIC=y, so the bus sysdata is pci_config_window. However,
> > Hyper-V PCI provides a paravirtualized PCI interface, so there is no
> > actual pci_config_window for a PCI host bridge, so no information can be
> > retrieve from the pci_config_window of a Hyper-V virtual PCI bus. Also
> > there is no corresponding ACPI device for the Hyper-V PCI root bridge,
> > which introduces a special case when trying to find the ACPI device from
> > the sysdata (see patch #3).
> > 
> > With this patchset, we could enable the virtual PCI on Hyper-V ARM64
> > guest with other code under development.
> > 
> > Comments and suggestions are welcome.
> 
> Ping ;-)

Lorenzo normally takes care of the native drivers (including Hyper-V),
so I don't want to get in his way.  If he's too busy and doesn't get a
chance, poke me again after -rc6 or so and I'll pick it up.

> > Arnd Bergmann (1):
> >   PCI: hv: Generify PCI probing
> > 
> > Boqun Feng (7):
> >   PCI: Introduce domain_nr in pci_host_bridge
> >   PCI: Support populating MSI domains of root buses via bridges
> >   arm64: PCI: Restructure pcibios_root_bridge_prepare()
> >   arm64: PCI: Support root bridge preparation for Hyper-V
> >   PCI: hv: Set ->domain_nr of pci_host_bridge at probing time
> >   PCI: hv: Set up MSI domain at bridge probing time
> >   PCI: hv: Turn on the host bridge probing on ARM64
> > 
> >  arch/arm64/kernel/pci.c             | 29 +++++++---
> >  drivers/pci/controller/pci-hyperv.c | 86 +++++++++++++++++------------
> >  drivers/pci/probe.c                 | 12 +++-
> >  include/linux/pci.h                 | 11 ++++
> >  4 files changed, 93 insertions(+), 45 deletions(-)
> > 
> > -- 
> > 2.32.0
> > 


From semen.protsenko at linaro.org  Mon Aug  2 16:06:05 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 3 Aug 2021 02:06:05 +0300
Subject: [PATCH 04/12] tty: serial: samsung: Init USI to keep clocks
 running
In-Reply-To: <a1701931-136e-235c-8392-a3f64c050d74@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-5-semen.protsenko@linaro.org>
 <a1701931-136e-235c-8392-a3f64c050d74@canonical.com>
Message-ID: <CAPLW+4mMCzzyqqJTse-UEpjQoVu1b-9Xz3_3L=nmg63uKYFnGw@mail.gmail.com>

On Fri, 30 Jul 2021 at 19:32, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 30/07/2021 16:49, Sam Protsenko wrote:
> > UART block is a part of USI (Universal Serial Interface) IP-core in
> > Samsung SoCs since Exynos9810 (e.g. in Exynos850). USI allows one to
> > enable one of three types of serial interface: UART, SPI or I2C. That's
> > possible because USI shares almost all internal circuits within each
> > protocol. USI also provides some additional registers so it's possible
> > to configure it.
> >
> > One USI register called USI_OPTION has reset value of 0x0. Because of
> > this the clock gating behavior is controlled by hardware (HWACG =
> > Hardware Auto Clock Gating), which simply means the serial won't work
> > after reset as is. In order to make it work, USI_OPTION[2:1] bits must
> > be set to 0b01, so that HWACG is controlled manually (by software).
> > Bits meaning:
> >   - CLKREQ_ON = 1: clock is continuously provided to IP
> >   - CLKSTOP_ON = 0: drive IP_CLKREQ to High (needs to be set along with
> >                     CLKREQ_ON = 1)
> >
> > USI is not present on older chips, like s3c2410, s3c2412, s3c2440,
> > s3c6400, s5pv210, exynos5433, exynos4210. So the new boolean field
> > '.has_usi' was added to struct s3c24xx_uart_info. USI registers will be
> > only actually accessed when '.has_usi' field is set to "1".
> >
> > This feature is needed for further serial enablement on Exynos850, but
> > some other new Exynos chips (like Exynos9810) may benefit from this
> > feature as well.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> >  drivers/tty/serial/samsung_tty.c | 33 +++++++++++++++++++++++++++++++-
> >  include/linux/serial_s3c.h       |  9 +++++++++
> >  2 files changed, 41 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
> > index 9fbc61151c2e..0f3cbd0b37e3 100644
> > --- a/drivers/tty/serial/samsung_tty.c
> > +++ b/drivers/tty/serial/samsung_tty.c
> > @@ -65,6 +65,7 @@ enum s3c24xx_port_type {
> >  struct s3c24xx_uart_info {
> >       char                    *name;
> >       enum s3c24xx_port_type  type;
> > +     unsigned int            has_usi;
> >       unsigned int            port_type;
> >       unsigned int            fifosize;
> >       unsigned long           rx_fifomask;
> > @@ -1352,6 +1353,29 @@ static int apple_s5l_serial_startup(struct uart_port *port)
> >       return ret;
> >  }
> >
> > +static void exynos_usi_init(struct uart_port *port)
> > +{
> > +     struct s3c24xx_uart_port *ourport = to_ourport(port);
> > +     struct s3c24xx_uart_info *info = ourport->info;
> > +
> > +     if (!info->has_usi)
> > +             return;
> > +
> > +     /*
> > +      * USI_RESET is an active High signal. Reset value of USI_RESET is 0x1
> > +      * to drive stable value to PAD. Due to this feature, the USI_RESET must
> > +      * be cleared (set as 0x0) before starting a transaction.
>
> "before starting a transaction" suggests it is related with transaction
> or something before starting it. Don't you need it simply after reset or
> resume?
>

Not sure what you are suggesting. USI_RESET is set to "1" at start up
(means USI block hangs in reset state), so we have to make it "0"
(that's what this code does); only then UART becomes functional and
UART transactions can be performed. And exynos_usi_init() is called
exactly where you hinted: at init and on resume.

Anyway, the whole comment is confusing, I'll simplify and rework it in
v2. Please let me know if I'm missing the point though.

> > +      */
> > +     wr_regl(port, USI_CON, USI_RESET);
>
> You are clearing entire register, not only USI_RESET bitfield. Is it
> really what you want?
>

Yeah, USI_CON[31:1] bits are reserved, and the reset value of this
register is 0x00000001. But anyway, I'm going to rework that code like
this, for clarity and consistence:

8<--------------------------------------------------------------------->8
    /* Clear the software reset of USI block (it's set at startup) */
    val = rd_regl(port, USI_CON);
    val &= ~(USI_RESET_MASK)
    wr_regl(port, USI_CON, val);
    udelay(1);

    /* Continuously provide the clock to USI IP w/o gating (for Rx mode) */
    val = rd_regl(port, USI_OPTION);
    val &= ~USI_HWACG_MASK;
    val |= USI_HWACG_CLKREQ_ON;
    wr_regl(port, USI_OPTION, val);
8<--------------------------------------------------------------------->8

> > +     udelay(1);
> > +
> > +     /*
> > +      * Set the HWACG option bit in case of UART Rx mode.
> > +      * CLKREQ_ON = 1, CLKSTOP_ON = 0 (set USI_OPTION[2:1] = 0x1).
> > +      */
> > +     wr_regl(port, USI_OPTION, USI_HWACG_CLKREQ_ON);
> > +}
> > +
> >  /* power power management control */
> >
> >  static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
> > @@ -1379,6 +1403,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
> >               if (!IS_ERR(ourport->baudclk))
> >                       clk_prepare_enable(ourport->baudclk);
> >
> > +             exynos_usi_init(port);
> >               break;
> >       default:
> >               dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level);
> > @@ -2102,6 +2127,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
> >       if (ret)
> >               pr_warn("uart: failed to enable baudclk\n");
> >
> > +     exynos_usi_init(port);
> > +
> >       /* Keep all interrupts masked and cleared */
> >       switch (ourport->info->type) {
> >       case TYPE_S3C6400:
> > @@ -2750,10 +2777,11 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
> >  #endif
> >
> >  #if defined(CONFIG_ARCH_EXYNOS)
> > -#define EXYNOS_COMMON_SERIAL_DRV_DATA                                \
> > +#define EXYNOS_COMMON_SERIAL_DRV_DATA_USI(_has_usi)          \
> >       .info = &(struct s3c24xx_uart_info) {                   \
> >               .name           = "Samsung Exynos UART",        \
> >               .type           = TYPE_S3C6400,                 \
> > +             .has_usi        = _has_usi,                     \
> >               .port_type      = PORT_S3C6400,                 \
> >               .has_divslot    = 1,                            \
> >               .rx_fifomask    = S5PV210_UFSTAT_RXMASK,        \
> > @@ -2773,6 +2801,9 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
> >               .has_fracval    = 1,                            \
> >       }                                                       \
> >
> > +#define EXYNOS_COMMON_SERIAL_DRV_DATA                                \
> > +     EXYNOS_COMMON_SERIAL_DRV_DATA_USI(0)
> > +
> >  static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
> >       EXYNOS_COMMON_SERIAL_DRV_DATA,
> >       .fifosize = { 256, 64, 16, 16 },
> > diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h
> > index f6c3323fc4c5..013c2646863e 100644
> > --- a/include/linux/serial_s3c.h
> > +++ b/include/linux/serial_s3c.h
> > @@ -28,6 +28,15 @@
> >  #define S3C2410_UFSTAT         (0x18)
> >  #define S3C2410_UMSTAT         (0x1C)
> >
> > +/* USI Control Register offset */
> > +#define USI_CON                      (0xC4)
> > +/* USI Option Register offset */
> > +#define USI_OPTION           (0xC8)
> > +/* USI_CON[0] = 0b0: clear USI global software reset (Active High) */
> > +#define USI_RESET            (0<<0)
>
> Just 0x0. I understand you wanted to hint it is a bit field, but the
> shift of 0 actually creates more questions.
>

After some consideration I decided to adhere to existing style and do
something like this (in v2):

8<--------------------------------------------------------------------->8
#define USI_CON          (0xC4)
#define USI_OPTION      (0xC8)

#define USI_CON_RESET_CLEAR        (0<<0)
#define USI_CON_RESET_SET        (1<<0)
#define USI_CON_RESET_MASK        (1<<0)

#define USI_OPTION_HWACG_CLKREQ_ON    (1<<1)
#define USI_OPTION_HWACG_CLKSTOP_ON    (1<<2)
#define USI_OPTION_HWACG_MASK        (3<<1)
8<--------------------------------------------------------------------->8

The whole reason for those comments was missing public TRM. But in the
end I decided it just looks ugly. Also, this way I can do RMW
operation (discussed above) in more logical way.

Please let me know if code snippets above look good to you.

>
> Best regards,
> Krzysztof


From chunkuang.hu at kernel.org  Mon Aug  2 16:16:23 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Tue, 3 Aug 2021 07:16:23 +0800
Subject: [PATCH v3] drm/mediatek: clear pending flag when cmdq packet is
 done.
In-Reply-To: <1627888227-5757-2-git-send-email-yongqiang.niu@mediatek.com>
References: <1627888227-5757-1-git-send-email-yongqiang.niu@mediatek.com>
 <1627888227-5757-2-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <CAAOTY_-7MNrO5my3_9EAeSVxtsVC-dGTZH31tph9TpY3faAdwQ@mail.gmail.com>

Hi, Yongqiang:

Yongqiang Niu <yongqiang.niu at mediatek.com> ? 2021?8?2? ?? ??3:11???
>
> In cmdq mode, packet may be flushed before it is executed, so
> the pending flag should be cleared after cmdq packet is done.
>
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 51 +++++++++++++++++++++++++++++----
>  1 file changed, 46 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 4c25e33..2a2d43e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -267,6 +267,40 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  {
>         struct mtk_drm_crtc *mtk_crtc = container_of(cl, struct mtk_drm_crtc, cmdq_cl);
>         struct cmdq_cb_data *data = mssg;
> +       struct mtk_crtc_state *state;
> +       unsigned int i;
> +
> +       state = to_mtk_crtc_state(mtk_crtc->base.state);
> +
> +       if (state->pending_config) {

No matter pending_config is true or not, it would be false after this.
So we could simply drop this checking.

> +               state->pending_config = false;
> +       }
> +
> +       if (mtk_crtc->pending_planes) {
> +               for (i = 0; i < mtk_crtc->layer_nr; i++) {
> +                       struct drm_plane *plane = &mtk_crtc->planes[i];
> +                       struct mtk_plane_state *plane_state;
> +
> +                       plane_state = to_mtk_plane_state(plane->state);
> +
> +                       if (plane_state->pending.config)

Ditto.

> +                               plane_state->pending.config = false;
> +               }
> +               mtk_crtc->pending_planes = false;
> +       }
> +
> +       if (mtk_crtc->pending_async_planes) {
> +               for (i = 0; i < mtk_crtc->layer_nr; i++) {
> +                       struct drm_plane *plane = &mtk_crtc->planes[i];
> +                       struct mtk_plane_state *plane_state;
> +
> +                       plane_state = to_mtk_plane_state(plane->state);
> +
> +                       if (plane_state->pending.async_config)

Ditto.

Regards,
Chun-Kuang.

> +                               plane_state->pending.async_config = false;
> +               }
> +               mtk_crtc->pending_async_planes = false;
> +       }
>
>         mtk_crtc->cmdq_vblank_cnt = 0;
>         mtk_drm_cmdq_pkt_destroy(mtk_crtc->cmdq_chan, data->pkt);
> @@ -423,7 +457,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
>                                     state->pending_vrefresh, 0,
>                                     cmdq_handle);
>
> -               state->pending_config = false;
> +               if (!cmdq_handle)
> +                       state->pending_config = false;
>         }
>
>         if (mtk_crtc->pending_planes) {
> @@ -443,9 +478,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
>                                 mtk_ddp_comp_layer_config(comp, local_layer,
>                                                           plane_state,
>                                                           cmdq_handle);
> -                       plane_state->pending.config = false;
> +                       if (!cmdq_handle)
> +                               plane_state->pending.config = false;
>                 }
> -               mtk_crtc->pending_planes = false;
> +
> +               if (!cmdq_handle)
> +                       mtk_crtc->pending_planes = false;
>         }
>
>         if (mtk_crtc->pending_async_planes) {
> @@ -465,9 +503,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
>                                 mtk_ddp_comp_layer_config(comp, local_layer,
>                                                           plane_state,
>                                                           cmdq_handle);
> -                       plane_state->pending.async_config = false;
> +                       if (!cmdq_handle)
> +                               plane_state->pending.async_config = false;
>                 }
> -               mtk_crtc->pending_async_planes = false;
> +
> +               if (!cmdq_handle)
> +                       mtk_crtc->pending_async_planes = false;
>         }
>  }
>
> --
> 1.8.1.1.dirty
>


From s-anna at ti.com  Mon Aug  2 16:21:38 2021
From: s-anna at ti.com (Suman Anna)
Date: Mon, 2 Aug 2021 18:21:38 -0500
Subject: [PATCH v2 1/5] remoteproc: Add support for detach-only during
 shutdown
In-Reply-To: <20210802184431.GC3051951@p14s>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-2-s-anna@ti.com> <20210802184431.GC3051951@p14s>
Message-ID: <cd399fef-6db7-72eb-933f-7454a043ed14@ti.com>

Hi Mathieu,

On 8/2/21 1:44 PM, Mathieu Poirier wrote:
> On Fri, Jul 23, 2021 at 05:02:44PM -0500, Suman Anna wrote:
>> The remoteproc core has support for both stopping and detaching a
>> remote processor that was attached to previously, through both the
>> remoteproc sysfs and cdev interfaces. The rproc_shutdown() though
>> unconditionally only uses the stop functionality at present. This
>> may not be the default desired functionality for all the remoteproc
>> platform drivers.
>>
>> Enhance the remoteproc core logic to key off the presence of the
>> .stop() ops and allow the individual remoteproc drivers to continue
>> to use the standard rproc_add() and rproc_del() API. This allows
>> the remoteproc drivers to only do detach if supported when the driver
>> is uninstalled, and the remote processor continues to run undisturbed
>> even after the driver removal.
>>
>> Signed-off-by: Suman Anna <s-anna at ti.com>
>> ---
>> v2: Addressed various review comments from v1
>>  - Reworked the logic to not use remoteproc detach_on_shutdown and
>>    rely only on rproc callback ops
>>  - Updated the last para of the patch description
>> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-3-s-anna at ti.com/
>>
>>  drivers/remoteproc/remoteproc_cdev.c  | 7 +++++++
>>  drivers/remoteproc/remoteproc_core.c  | 5 ++++-
>>  drivers/remoteproc/remoteproc_sysfs.c | 6 ++++++
>>  3 files changed, 17 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c
>> index 4ad98b0b8caa..16c932beed88 100644
>> --- a/drivers/remoteproc/remoteproc_cdev.c
>> +++ b/drivers/remoteproc/remoteproc_cdev.c
>> @@ -42,6 +42,13 @@ static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_
>>  		    rproc->state != RPROC_ATTACHED)
>>  			return -EINVAL;
>>  
>> +		if (rproc->state == RPROC_ATTACHED &&
> 
> This is already checked just above.
> 
>> +		    !rproc->ops->stop) {

Well, this is checking for both conditions, and not just the stop ops
independently. We expect to have .stop() defined normally for both regular
remoteproc mode and attached mode where you want to stop (and not detach), but
as you can see, I am supporting only detach and so will not have .stop() defined
 with RPROC_ATTACHED.

> 
> This is checked in rproc_stop() where -EINVAL is returned if ops::stop has not
> been provided.

rproc_shutdown() actually doesn't return any status, so all its internal
checking gets ignored and a success is returned today.

> 
>> +			dev_err(&rproc->dev,
>> +				"stop not supported for this rproc, use detach\n");
> 
> The standard error message from the shell should be enough here, the same way it
> is enough when the "start" and "stop" scenarios fail.

Thought this was a bit more informative, but sure this trace can be dropped.

> 
>> +			return -EINVAL;
>> +		}
>> +
>>  		rproc_shutdown(rproc);
>>  	} else if (!strncmp(cmd, "detach", len)) {
>>  		if (rproc->state != RPROC_ATTACHED)
>> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
>> index 7de5905d276a..ab9e52180b04 100644
>> --- a/drivers/remoteproc/remoteproc_core.c
>> +++ b/drivers/remoteproc/remoteproc_core.c
>> @@ -2075,7 +2075,10 @@ void rproc_shutdown(struct rproc *rproc)
>>  	if (!atomic_dec_and_test(&rproc->power))
>>  		goto out;
>>  
>> -	ret = rproc_stop(rproc, false);
>> +	if (rproc->state == RPROC_ATTACHED && !rproc->ops->stop)
>> +		ret = __rproc_detach(rproc);
>> +	else
>> +		ret = rproc_stop(rproc, false);
> 
> As I indicated in my last review I think rproc_shutdown() and rproc_del() should
> be decoupled and the right call made in the platform drivers based on the state
> of the remote processor.  

We have various remoteproc API provided in pairs - rproc_alloc()/rproc_free(),
rproc_add()/rproc_del(), rproc_boot()/rproc_shutdown() and
rproc_attach()/rproc_detach(). The drivers are configuring conditions for
auto-boot and RPROC_DETACHED. The reason they are coupled is primarily because
of the auto-boot done during rproc_add(). And we handle the RPROC_DETACHED case
just as well in rproc_boot().

While what you have suggested works, but I am not quite convinced on this
asymmetric usage, and why this state-machine logic should be split between the
core and remoteproc drivers differently between attach and detach. To me,
calling rproc_detach() in remoteproc drivers would have made sense only if they
are also calling rproc_attach().


Conditions such as the above make the core code
> brittle, difficult to understand and tedious to maintain.

The logic I have added actually makes rproc_shutdown behavior to be on par with
the rproc_boot().

regards
Suman

> 
> Thanks,
> Mathieu
> 
>>  	if (ret) {
>>  		atomic_inc(&rproc->power);
>>  		goto out;
>> diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
>> index ea8b89f97d7b..133e766f38d4 100644
>> --- a/drivers/remoteproc/remoteproc_sysfs.c
>> +++ b/drivers/remoteproc/remoteproc_sysfs.c
>> @@ -206,6 +206,12 @@ static ssize_t state_store(struct device *dev,
>>  		    rproc->state != RPROC_ATTACHED)
>>  			return -EINVAL;
>>  
>> +		if (rproc->state == RPROC_ATTACHED &&
>> +		    !rproc->ops->stop) {
>> +			dev_err(&rproc->dev, "stop not supported for this rproc, use detach\n");
>> +			return -EINVAL;
>> +		}
>> +
>>  		rproc_shutdown(rproc);
>>  	} else if (sysfs_streq(buf, "detach")) {
>>  		if (rproc->state != RPROC_ATTACHED)
>> -- 
>> 2.32.0
>>



From chunkuang.hu at kernel.org  Mon Aug  2 16:21:49 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Tue, 3 Aug 2021 07:21:49 +0800
Subject: [PATCH v2 7/7] drm/mediatek: mtk_dsi: Reset the dsi0 hardware
In-Reply-To: <20210714121116.v2.7.Idbb4727ddf00ba2fe796b630906baff10d994d89@changeid>
References: <20210714101141.2089082-1-enric.balletbo@collabora.com>
 <20210714121116.v2.7.Idbb4727ddf00ba2fe796b630906baff10d994d89@changeid>
Message-ID: <CAAOTY__EA323tC+BswgTfx4EM9FF8Hf9AAkqoxuacuxQwr4SnA@mail.gmail.com>

Hi, Enric:

Enric Balletbo i Serra <enric.balletbo at collabora.com> ? 2021?7?14? ?? ??6:12???
>
> Reset dsi0 HW to default when power on. This prevents to have different
> settingbetween the bootloader and the kernel.
>
> As not all Mediatek boards have the reset consumer configured in their
> board description, also is not needed on all of them, the reset is optional,
> so the change is compatible with all boards.

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

>
> Cc: Jitao Shi <jitao.shi at mediatek.com>
> Suggested-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> ---
>
> (no changes since v1)
>
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index ae403c67cbd9..d8b81e2ab841 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -11,6 +11,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
> +#include <linux/reset.h>
>
>  #include <video/mipi_display.h>
>  #include <video/videomode.h>
> @@ -980,8 +981,10 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>         struct mtk_dsi *dsi = dev_get_drvdata(dev);
>
>         ret = mtk_dsi_encoder_init(drm, dsi);
> +       if (ret)
> +               return ret;
>
> -       return ret;
> +       return device_reset_optional(dev);
>  }
>
>  static void mtk_dsi_unbind(struct device *dev, struct device *master,
> --
> 2.30.2
>


From semen.protsenko at linaro.org  Mon Aug  2 16:27:44 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 3 Aug 2021 02:27:44 +0300
Subject: [PATCH 00/12] Add minimal support for Exynos850 SoC
In-Reply-To: <2dacc205-04ce-c206-a393-50ba0d5aa1a7@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <5e35b0a7-13aa-3c62-ca49-14af2fcb2a08@canonical.com>
 <c3486111-0ec9-9679-d2a2-68b2f33a2450@canonical.com>
 <CAPLW+4kbnJEBkc0D=RWt59JxBan8X1uDy6sSXBiYAq8N9FDV6A@mail.gmail.com>
 <13f166bb-7103-25d5-35a6-8ec53a1f1817@canonical.com>
 <2dacc205-04ce-c206-a393-50ba0d5aa1a7@canonical.com>
Message-ID: <CAPLW+4=1Anr6rCWEBL04D81aEAEVKD5cGE+ObXH3q-HNHce07w@mail.gmail.com>

On Sat, 31 Jul 2021 at 11:12, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 31/07/2021 09:29, Krzysztof Kozlowski wrote:
> > On 30/07/2021 21:02, Sam Protsenko wrote:
> >> Hi Krzysztof,
> >>
> >> On Fri, 30 Jul 2021 at 20:21, Krzysztof Kozlowski
> >> <krzysztof.kozlowski at canonical.com> wrote:
> >>>
> >>> On 30/07/2021 17:18, Krzysztof Kozlowski wrote:
> >>>> On 30/07/2021 16:49, Sam Protsenko wrote:
> >>>>> This patch series adds initial platform support for Samsung Exynos850
> >>>>> SoC [1]. With this patchset it's possible to run the kernel with BusyBox
> >>>>> rootfs as a RAM disk. More advanced platform support (like MMC driver
> >>>>> additions) will be added later. The idea is to keep the first submission
> >>>>> minimal to ease the review, and then build up on top of that.
> >>>>>
> >>>>> [1] https://www.samsung.com/semiconductor/minisite/exynos/products/mobileprocessor/exynos-850/
> >>>>>
> >>>>
> >>>> Great work!
> >>>>
> >>
> >> Thanks, Krzysztof! And thank you for reviewing the whole series.
> >>
> >>>> What's the SoC revision number (should be accessible via
> >>>> /sys/bus/soc/devices/soc0/)? Recent wrap in numbering of Exynos chips
> >>>> might bring confusion...
> >>
> >> # cat /sys/devices/soc0/revision
> >> 0
> >
> > soc_id but you're right it won't be set for unknown SoCs. You need to
> > extend drivers/soc/samsung/exynos-chipid.c to parse new values (E3830000
> > for product ID) and maybe new register offsets (previous offset is 0x0,
> > for 3830 is 0x10 I think). Also revision mask might change.
> >
> >>> Judging by vendor's sources it is quite confusing. It looks mostly like
> >>> Exynos3830 but in few other cases it uses Exynos9 compatibles (Exynos9,
> >>> Exynos9820). Only in few places there is Exynos850. Marketing department
> >>> made it so confusing...  The revision embedded in SoC would be very
> >>> interesting.
> >>>
> >>
> >> As I understand, this SoC is called Exynos850 everywhere now.
> >> Exynos3830 is its old name, not used anymore. As you noticed from
> >> patch #2, it shares some definitions with Exynos9 SoC, so I guess some
> >> software is similar for both architectures. Not sure about hardware
> >> though, never worked with Exynos9 CPUs. Anyway, I asked Samsung
> >> representatives about naming, and it seems like we should stick to
> >> "Exynos850" name, even in code.
> >
> >
> > Since the chip identifies itself as E3830000, I would prefer naming
> > matching real product ID instead of what is pushed by marketing or sales
> > representatives. The marketing names don't have to follow any
> > engineering rules, they can be changed and renamed. Sales follows rather
> > money and corporate rules, not consistency for upstream project.
>
> On the other hand we have already two exceptions for naming
> inconsistency - Exynos3250 identifies itself as 3472 (which is confusing
> because 3250 is two core and there is a separate quad-core
> Exyons3472...) and Exynos5800 is actually marketing name for a revision
> of Exynos5422. Maybe indeed will be easier to go with the branded name
> 850...
>

Well, chip engraving says "3830", but I was specifically told to stick
to "850" in upstream kernel. I can presume there was some mix ups with
this naming, and it might be the case it's better to stick to "850"
exactly to avoid further confusion. Yes, I can see that
EXYNOS3830_SOC_ID = 0xE3830000 in chipid driver, but we can return
"EXYNOS850" string for that const, right? If you google "Exynos850"
and "Exynos3830", it's obvious everybody uses the former, so I'd
appreciate if we can stick to "850" in the end.

>
> Best regards,
> Krzysztof


From oupton at google.com  Mon Aug  2 16:27:57 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 2 Aug 2021 16:27:57 -0700
Subject: [PATCH v5 09/13] KVM: arm64: Allow userspace to configure a
 vCPU's virtual offset
In-Reply-To: <877dh82jrh.wl-maz@kernel.org>
References: <20210729173300.181775-1-oupton@google.com>
 <20210729173300.181775-10-oupton@google.com>
 <877dh82jrh.wl-maz@kernel.org>
Message-ID: <CAOQ_QsiLLUgPYO4q3kn1mApTMysCO=5U9g0h3Xqu8a11bpbAJA@mail.gmail.com>

On Fri, Jul 30, 2021 at 3:12 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Thu, 29 Jul 2021 18:32:56 +0100,
> Oliver Upton <oupton at google.com> wrote:
> >
> > Add a new vCPU attribute that allows userspace to directly manipulate
> > the virtual counter-timer offset. Exposing such an interface allows for
> > the precise migration of guest virtual counter-timers, as it is an
> > indepotent interface.
> >
> > Uphold the existing behavior of writes to CNTVOFF_EL2 for this new
> > interface, wherein a write to a single vCPU is broadcasted to all vCPUs
> > within a VM.
> >
> > Reviewed-by: Andrew Jones <drjones at redhat.com>
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > ---
> >  Documentation/virt/kvm/devices/vcpu.rst | 22 ++++++++
> >  arch/arm64/include/uapi/asm/kvm.h       |  1 +
> >  arch/arm64/kvm/arch_timer.c             | 68 ++++++++++++++++++++++++-
> >  3 files changed, 89 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
> > index 0f46f2588905..ecbab7adc602 100644
> > --- a/Documentation/virt/kvm/devices/vcpu.rst
> > +++ b/Documentation/virt/kvm/devices/vcpu.rst
> > @@ -139,6 +139,28 @@ configured values on other VCPUs.  Userspace should configure the interrupt
> >  numbers on at least one VCPU after creating all VCPUs and before running any
> >  VCPUs.
> >
> > +2.2. ATTRIBUTE: KVM_ARM_VCPU_TIMER_OFFSET_VTIMER
> > +------------------------------------------------
> > +
> > +:Parameters: Pointer to a 64-bit unsigned counter-timer offset.
> > +
> > +Returns:
> > +
> > +      ======= ======================================
> > +      -EFAULT Error reading/writing the provided
> > +              parameter address
> > +      -ENXIO  Attribute not supported
> > +      ======= ======================================
> > +
> > +Specifies the guest's virtual counter-timer offset from the host's
> > +virtual counter. The guest's virtual counter is then derived by
> > +the following equation:
> > +
> > +  guest_cntvct = host_cntvct - KVM_ARM_VCPU_TIMER_OFFSET_VTIMER
>
> I still have a problem with this, specially as you later introduce a
> physical timer offset. My gut feeling is that the virtual offset
> should be relative to the physical counter *of the guest*, and not
> that of the host. The physical offset should be the only one that is
> relative to the host. Anything else should be deriving from it.
>
> If you don't set the ptimer offset, then the two definitions are
> strictly identical. It will also match the definition of a
> userspace-visible CNTVOFF_EL2 with NV, which is strictly relative to
> the guest view of the physical counter.

Yeah, this sounds good to me. I very much like the idea of maintaining
exactly one offset from the host to the guest. So long as users are
fine with paying the cost of an emulated physical counter-timer on
non-ECV hosts. That said, a non-NV guest shouldn't be using the
physical counter in the first place..

>
> > +
> > +KVM does not allow the use of varying offset values for different vCPUs;
> > +the last written offset value will be broadcasted to all vCPUs in a VM.
> > +
>
> Please document the effects of this attribute w.r.t. writing
> CNTVCT_EL0 from userspace.
>

Good idea.

> > -int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> > +int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> > +{
> > +     u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> > +     u64 offset;
> > +
> > +     if (get_user(offset, uaddr))
> > +             return -EFAULT;
> > +
> > +     switch (attr->attr) {
> > +     case KVM_ARM_VCPU_TIMER_OFFSET_VTIMER:
> > +             update_vtimer_cntvoff(vcpu, offset);
>
> Probably not a good idea if the timer is already enabled on any of the
> CPUs (we probably already have that problem, so let's fix it once and
> for all).

hmm... would this cause any issues to enforce ordering on an existing
UAPI? If I understand the suggestion correctly, we will refuse to
write the counter offset for a VM with an active timer.

If that is the case, then when we migrate a guest the VMM would have
to be very deliberate about the order in which it restores registers,
no?

> > +int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> > +{
> > +     u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> > +     struct arch_timer_context *timer;
> > +     u64 offset;
> > +
> > +     switch (attr->attr) {
> > +     case KVM_ARM_VCPU_TIMER_OFFSET_VTIMER:
> > +             timer = vcpu_vtimer(vcpu);
> > +             break;
> > +     default:
> > +             return -ENXIO;
>
> What is the rational for retrieving this offset the first place? I
> don't dislike the symmetry, but we already have an architectural way
> of getting it (read the counter registers).

I don't believe this is necessary any more.

The reason that I had exposed the virtual counter offset as a device
attribute was to separate VMM and guest manipulation of the virtual
counter. A VMM migrating an EL2 guest would likely want to adjust the
vtimer according to the difference in virtual counters between two
hosts without changing any guest-visible sysregs. However, if we go
with your suggestion above, the hypervisor would only ever need to
poke a physical offset attribute to make transparent changes to *both*
counters.

So, I suppose this is what I'm proposing: treat VMM writes to
CNTVOFF_EL2 the same as guest writes. For CNTPOFF_EL2, we do a special
dance; guest writes to CNTPOFF_EL2 will be visible in the register
_and_ change the value KVM writes to CNTPOFF_EL2 in hardware. Host
writes to a physical offset device attribute will cause KVM to change
the hardware value of CNTPOFF_EL2, but not update the guest-visible
register value. This way, a guest can be transparently migrated
between hosts with different counters.

>
> > +     }
> > +
> > +     offset = timer_get_offset(timer);
> > +     return put_user(offset, uaddr);
> > +}
> > +
> > +int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> > +{
> > +     switch (attr->attr) {
> > +     case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> > +     case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> > +             return kvm_arm_timer_get_attr_irq(vcpu, attr);
> > +     case KVM_ARM_VCPU_TIMER_OFFSET_VTIMER:
> > +             return kvm_arm_timer_get_attr_offset(vcpu, attr);
> > +     }
> > +
> > +     return -ENXIO;
> > +}
> > +
> >  int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> >  {
> >       switch (attr->attr) {
> >       case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> >       case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> > +     case KVM_ARM_VCPU_TIMER_OFFSET_VTIMER:
> >               return 0;
> >       }
> >
>
> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


From rajatja at google.com  Mon Aug  2 17:09:08 2021
From: rajatja at google.com (Rajat Jain)
Date: Mon, 2 Aug 2021 17:09:08 -0700
Subject: [PATCH v2 0/3] iommu: Enable non-strict DMA on QCom SD/MMC
In-Reply-To: <CAD=FV=XaTqNDn=vLEXfJ2dV+EH2UoxPfzWeiS+_sZ9hrQ274bw@mail.gmail.com>
References: <20210624171759.4125094-1-dianders@chromium.org>
 <YNXXwvuErVnlHt+s@8bytes.org>
 <CAD=FV=UFxZH7g8gH5+M=Fv4Y-e1bsLkNkPGJhNwhvVychcGQcQ@mail.gmail.com>
 <CAD=FV=W=HmgH3O3z+nThWL6U+X4Oh37COe-uTzVB9SanP2n86w@mail.gmail.com>
 <YOaymBHc4g2cIfRn@8bytes.org>
 <CAD=FV=U_mKPaGfWyN1SVi9S2hPBpG=rE_p89+Jvjr95d0TvgsA@mail.gmail.com>
 <e3555c49-2978-355f-93bb-dbfa7d09cab8@arm.com>
 <CAD=FV=XaTqNDn=vLEXfJ2dV+EH2UoxPfzWeiS+_sZ9hrQ274bw@mail.gmail.com>
Message-ID: <CACK8Z6FV+QYR01=aP4AT8rNUQMkX-WwesHzf5XY8465KuUZ=_Q@mail.gmail.com>

Hi Robin, Doug,

On Wed, Jul 14, 2021 at 8:14 AM Doug Anderson <dianders at chromium.org> wrote:
>
> Hi,
>
> On Tue, Jul 13, 2021 at 11:07 AM Robin Murphy <robin.murphy at arm.com> wrote:
> >
> > On 2021-07-08 15:36, Doug Anderson wrote:
> > [...]
> > >> Or document for the users that want performance how to
> > >> change the setting, so that they can decide.
> > >
> > > Pushing this to the users can make sense for a Linux distribution but
> > > probably less sense for an embedded platform. So I'm happy to make
> > > some way for a user to override this (like via kernel command line),
> > > but I also strongly believe there should be a default that users don't
> > > have to futz with that we think is correct.
> >
> > FYI I did make progress on the "punt it to userspace" approach. I'm not
> > posting it even as an RFC yet because I still need to set up a machine
> > to try actually testing any of it (it's almost certainly broken
> > somewhere), but in the end it comes out looking surprisingly not too bad
> > overall. If you're curious to take a look in the meantime I put it here:
> >
> > https://gitlab.arm.com/linux-arm/linux-rm/-/commits/iommu/fq

I was wondering if you got any closer to testing / sending it out? I
looked at the patches and am trying to understand, would they also
make it possible to convert at runtime, an existing "non-strict"
domain (for a particular device) into a "strict" domain leaving the
other devices/domains as-is? Please let me know when you think your
patches are good to be tested, and I'd also be interested in trying
them out.

>
> Being able to change this at runtime through sysfs sounds great and it
> fills all the needs I'm aware of, thanks! In Chrome OS we can just use
> this with some udev rules and get everything we need.

I still have another (inverse) use case where this does not work:
We have an Intel chromebook with the default domain type being
non-strict. There is an LTE modem (an internal PCI device which cannot
be marked external), which we'd like to be treated as a "Strict" DMA
domain.

Do I understand it right that using Rob's patches, I could potentially
switch the domain to "strict" *after* booting (since we don't use
initramfs), but by that time, the driver might have already attached
to the modem device (using "non-strict" domain), and thus the damage
may have already been done? So perhaps we still need a device property
that the firmware could use to indicate "strictness" for certain
devices at boot?

Thanks,
Rajat


From rajatja at google.com  Mon Aug  2 17:34:36 2021
From: rajatja at google.com (Rajat Jain)
Date: Mon, 2 Aug 2021 17:34:36 -0700
Subject: [PATCH v2 0/3] iommu: Enable non-strict DMA on QCom SD/MMC
In-Reply-To: <CACK8Z6FV+QYR01=aP4AT8rNUQMkX-WwesHzf5XY8465KuUZ=_Q@mail.gmail.com>
References: <20210624171759.4125094-1-dianders@chromium.org>
 <YNXXwvuErVnlHt+s@8bytes.org>
 <CAD=FV=UFxZH7g8gH5+M=Fv4Y-e1bsLkNkPGJhNwhvVychcGQcQ@mail.gmail.com>
 <CAD=FV=W=HmgH3O3z+nThWL6U+X4Oh37COe-uTzVB9SanP2n86w@mail.gmail.com>
 <YOaymBHc4g2cIfRn@8bytes.org>
 <CAD=FV=U_mKPaGfWyN1SVi9S2hPBpG=rE_p89+Jvjr95d0TvgsA@mail.gmail.com>
 <e3555c49-2978-355f-93bb-dbfa7d09cab8@arm.com>
 <CAD=FV=XaTqNDn=vLEXfJ2dV+EH2UoxPfzWeiS+_sZ9hrQ274bw@mail.gmail.com>
 <CACK8Z6FV+QYR01=aP4AT8rNUQMkX-WwesHzf5XY8465KuUZ=_Q@mail.gmail.com>
Message-ID: <CACK8Z6Hzy+t05kY0VGwEnzcHZXgg9BAuS+DmRf3==J+G62qXgQ@mail.gmail.com>

Hi Rob,

On Mon, Aug 2, 2021 at 5:09 PM Rajat Jain <rajatja at google.com> wrote:
>
> Hi Robin, Doug,
>
> On Wed, Jul 14, 2021 at 8:14 AM Doug Anderson <dianders at chromium.org> wrote:
> >
> > Hi,
> >
> > On Tue, Jul 13, 2021 at 11:07 AM Robin Murphy <robin.murphy at arm.com> wrote:
> > >
> > > On 2021-07-08 15:36, Doug Anderson wrote:
> > > [...]
> > > >> Or document for the users that want performance how to
> > > >> change the setting, so that they can decide.
> > > >
> > > > Pushing this to the users can make sense for a Linux distribution but
> > > > probably less sense for an embedded platform. So I'm happy to make
> > > > some way for a user to override this (like via kernel command line),
> > > > but I also strongly believe there should be a default that users don't
> > > > have to futz with that we think is correct.
> > >
> > > FYI I did make progress on the "punt it to userspace" approach. I'm not
> > > posting it even as an RFC yet because I still need to set up a machine
> > > to try actually testing any of it (it's almost certainly broken
> > > somewhere), but in the end it comes out looking surprisingly not too bad
> > > overall. If you're curious to take a look in the meantime I put it here:
> > >
> > > https://gitlab.arm.com/linux-arm/linux-rm/-/commits/iommu/fq

BTW, is there another mirror to this? I (and another colleague) are
getting the following error when trying to clone it:

rajatja at rajat2:~/rob_iommu$ git clone
https://git.gitlab.arm.com/linux-arm/linux-rm.git
Cloning into 'linux-rm'...
remote: Enumerating objects: 125712, done.
remote: Counting objects: 100% (125712/125712), done.
remote: Compressing objects: 100% (41203/41203), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
error: 804 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet fatal:
early EOF
fatal: fetch-pack: invalid index-pack output rajatja at rajat2:~/rob_iommu$

We've tried both git and https methods.

>
> I was wondering if you got any closer to testing / sending it out? I
> looked at the patches and am trying to understand, would they also
> make it possible to convert at runtime, an existing "non-strict"
> domain (for a particular device) into a "strict" domain leaving the
> other devices/domains as-is? Please let me know when you think your
> patches are good to be tested, and I'd also be interested in trying
> them out.
>
> >
> > Being able to change this at runtime through sysfs sounds great and it
> > fills all the needs I'm aware of, thanks! In Chrome OS we can just use
> > this with some udev rules and get everything we need.
>
> I still have another (inverse) use case where this does not work:
> We have an Intel chromebook with the default domain type being
> non-strict. There is an LTE modem (an internal PCI device which cannot
> be marked external), which we'd like to be treated as a "Strict" DMA
> domain.
>
> Do I understand it right that using Rob's patches, I could potentially
> switch the domain to "strict" *after* booting (since we don't use
> initramfs), but by that time, the driver might have already attached
> to the modem device (using "non-strict" domain), and thus the damage
> may have already been done? So perhaps we still need a device property
> that the firmware could use to indicate "strictness" for certain
> devices at boot?
>
> Thanks,
> Rajat


From robdclark at gmail.com  Mon Aug  2 18:14:25 2021
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 2 Aug 2021 18:14:25 -0700
Subject: [PATCH] iommu/arm-smmu: Add clk_bulk_{prepare/unprepare} to
 system pm callbacks
In-Reply-To: <20210802161206.GA29168@willie-the-truck>
References: <20210727093322.13202-1-saiprakash.ranjan@codeaurora.org>
 <20210802161206.GA29168@willie-the-truck>
Message-ID: <CAF6AEGueDncLYzw9ic=2wkfidOBcG_HcquH7K0ya9xEfY5oteg@mail.gmail.com>

On Mon, Aug 2, 2021 at 9:12 AM Will Deacon <will at kernel.org> wrote:
>
> On Tue, Jul 27, 2021 at 03:03:22PM +0530, Sai Prakash Ranjan wrote:
> > Some clocks for SMMU can have parent as XO such as gpu_cc_hub_cx_int_clk
> > of GPU SMMU in QTI SC7280 SoC and in order to enter deep sleep states in
> > such cases, we would need to drop the XO clock vote in unprepare call and
> > this unprepare callback for XO is in RPMh (Resource Power Manager-Hardened)
> > clock driver which controls RPMh managed clock resources for new QTI SoCs
> > and is a blocking call.
> >
> > Given we cannot have a sleeping calls such as clk_bulk_prepare() and
> > clk_bulk_unprepare() in arm-smmu runtime pm callbacks since the iommu
> > operations like map and unmap can be in atomic context and are in fast
> > path, add this prepare and unprepare call to drop the XO vote only for
> > system pm callbacks since it is not a fast path and we expect the system
> > to enter deep sleep states with system pm as opposed to runtime pm.
> >
> > This is a similar sequence of clock requests (prepare,enable and
> > disable,unprepare) in arm-smmu probe and remove.
> >
> > Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan at codeaurora.org>
> > Co-developed-by: Rajendra Nayak <rnayak at codeaurora.org>
> > Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> > ---
> >  drivers/iommu/arm/arm-smmu/arm-smmu.c | 20 ++++++++++++++++++--
> >  1 file changed, 18 insertions(+), 2 deletions(-)
>
> [+Rob]
>
> How does this work with that funny GPU which writes to the SMMU registers
> directly? Does the SMMU need to remain independently clocked for that to
> work or is it all in the same clock domain?

AFAIU the device_link stuff should keep the SMMU clocked as long as
the GPU is alive, so I think this should work out ok.. ie. the SMMU
won't suspend while the GPU is not suspended.

BR,
-R


> > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > index d3c6f54110a5..9561ba4c5d39 100644
> > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > @@ -2277,6 +2277,13 @@ static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
> >
> >  static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
> >  {
> > +     int ret;
> > +     struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> > +
> > +     ret = clk_bulk_prepare(smmu->num_clks, smmu->clks);
> > +     if (ret)
> > +             return ret;
> > +
> >       if (pm_runtime_suspended(dev))
> >               return 0;
>
> If we subsequently fail to enable the clks in arm_smmu_runtime_resume()
> should we unprepare them again?
>
> Will
>
> > @@ -2285,10 +2292,19 @@ static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
> >
> >  static int __maybe_unused arm_smmu_pm_suspend(struct device *dev)
> >  {
> > +     int ret = 0;
> > +     struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> > +
> >       if (pm_runtime_suspended(dev))
> > -             return 0;
> > +             goto clk_unprepare;
> >
> > -     return arm_smmu_runtime_suspend(dev);
> > +     ret = arm_smmu_runtime_suspend(dev);
> > +     if (ret)
> > +             return ret;
> > +
> > +clk_unprepare:
> > +     clk_bulk_unprepare(smmu->num_clks, smmu->clks);
> > +     return ret;
> >  }
> >
> >  static const struct dev_pm_ops arm_smmu_pm_ops = {
> > --
> > QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> > of Code Aurora Forum, hosted by The Linux Foundation
> >
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu


From robdclark at gmail.com  Mon Aug  2 18:36:04 2021
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 2 Aug 2021 18:36:04 -0700
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent masters
 to use system cache
In-Reply-To: <20210802151409.GE28735@willie-the-truck>
References: <cover.1610372717.git.saiprakash.ranjan@codeaurora.org>
 <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
Message-ID: <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>

On Mon, Aug 2, 2021 at 8:14 AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> > On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> > >
> > > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> > > > On 2021-07-28 19:30, Georgi Djakov wrote:
> > > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > > > > the memory type setting required for the non-coherent masters to use
> > > > > > system cache. Now that system cache support for GPU is added, we will
> > > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > > > > Without this, the system cache lines are not allocated for GPU.
> > > > > >
> > > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > > > > and makes GPU the user of this protection flag.
> > > > >
> > > > > Thank you for the patchset! Are you planning to refresh it, as it does
> > > > > not apply anymore?
> > > > >
> > > >
> > > > I was waiting on Will's reply [1]. If there are no changes needed, then
> > > > I can repost the patch.
> > >
> > > I still think you need to handle the mismatched alias, no? You're adding
> > > a new memory type to the SMMU which doesn't exist on the CPU side. That
> > > can't be right.
> > >
> >
> > Just curious, and maybe this is a dumb question, but what is your
> > concern about mismatched aliases?  I mean the cache hierarchy on the
> > GPU device side (anything beyond the LLC) is pretty different and
> > doesn't really care about the smmu pgtable attributes..
>
> If the CPU accesses a shared buffer with different attributes to those which
> the device is using then you fall into the "mismatched memory attributes"
> part of the Arm architecture. It's reasonably unforgiving (you should go and
> read it) and in some cases can apply to speculative accesses as well, but
> the end result is typically loss of coherency.

Ok, I might have a few other sections to read first to decipher the
terminology..

But my understanding of LLC is that it looks just like system memory
to the CPU and GPU (I think that would make it "the point of
coherence" between the GPU and CPU?)  If that is true, shouldn't it be
invisible from the point of view of different CPU mapping options?

BR,
-R


From sunilmut at microsoft.com  Mon Aug  2 19:11:13 2021
From: sunilmut at microsoft.com (Sunil Muthuswamy)
Date: Tue, 3 Aug 2021 02:11:13 +0000
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <87tuka24kj.wl-maz@kernel.org>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
Message-ID: <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>

 On Saturday, July 31, 2021 2:52 AM,
 Marc Zyngier <maz at kernel.org> wrote:
> 
> [...]
> 
> > > I also want to understand *how* you are going to plumb this into both
> > > ACPI and DT, given that neither understand how to link a PCI endpoint
> > > to a set of RDs.
> > >
> > > 	M.
> >
> > One way to do this for NUMA-aware systems would be to use the NUMA
> > related information that is available with PCI endpoints or root complex, to
> > pick a Redistributor/CPU that is in the NUMA node, as specified by the PCI
> > endpoint/root complex. In DT PCI devices can specify this using
> > 'numa-node-id' and in ACPI using the '_PXM (Proximity)'. For systems that
> > are not NUMA-aware, we can go with *any* Redistributor/CPU.
> 
> This makes zero sense. From the point of view of a device, all the RDs
> should be reachable, and firmware has no say in it. Dealing with
> interrupt affinity is the responsibility of the endpoint driver, and
> NUMA affinity is only a performance optimisation.
> 
> > Is there any additional information we would be able to gather from ACPI
> > or DT that's not there currently, that would be useful here?
> 
> You will need some firmware information describing that a given set of
> devices must use the RDs for their MSIs. Just like we currently
> describe it in IORT for the ITS. You cannot /assume/ things. At the
> moment, there is nothing at all, because no-one (including Microsoft)
> thought it would be a good idea not to have an ITS, which is also why
> ACPI doesn't describe MBIs as a potential MSI provider.
> 
I am a little bit confused by your above comment. Maybe you can help me
understand the ask. You indicate that from the point of the view of the
device, all the RDs should be reachable. But, then if we define a mapping
between PCI endpoint and RD in the firmware, we would be doing exactly
the opposite. i.e. restricting the RDs that are reachable by the device. Can
you please clarify?

Is your concern that the device should be able to only DMA to a subset of
GIC Redistributor, for the MSIs? If so, in the IORT, there is "memory address
size limit" for both device and root complex nodes. In the implementation,
we can enforce that the GICR is within that range. And, if a device deviates
further than that (ex: by having accessibility gaps within the GICR range),
then that is out of scope for support.

- Sunil


From chenhaoa at uniontech.com  Mon Aug  2 19:18:56 2021
From: chenhaoa at uniontech.com (Hao Chen)
Date: Tue,  3 Aug 2021 10:18:56 +0800
Subject: [net-next,v8] net: stmmac: optimize check in ops '.begin'
Message-ID: <20210803021856.20416-1-chenhaoa@uniontech.com>

I want to get permanent MAC address when the interface is down. And I think
it is more convenient to get statistics in the down state by 'ethtool -S'.
But current all of the ethool command return -EBUSY.

I don't think we should check that the network interface is up in '.begin',
which will cause that all the ethtool commands can't be used when the
network interface is down. If some ethtool commands can only be used in the
up state, check it in the corresponding ethool OPS function is better.
This is too rude and unreasonable.

Compile-tested on arm64. Tested on an arm64 system with an on-board
STMMAC chip.

Changes v7 ... v8:
- Optimize commit description information, optimization parameters of
  pm_runtime function.

Changes v6 ... v7:
- fix arg type error of 'dev' to 'priv->device'.

Changes v5 ... v6:
- The 4.19.90 kernel not support pm_runtime, so implemente '.begin' and
  '.complete' again. Add return value check of pm_runtime function.

Changes v4 ... v5:
- test the '.begin' will return -13 error on my machine based on 4.19.90
  kernel. The platform driver does not supported pm_runtime. So remove the
  implementation of '.begin' and '.complete'.

Changes v3 ... v4:
- implement '.complete' ethtool OPS.

Changes v2 ... v3:
- add linux/pm_runtime.h head file.

Changes v1 ... v2:
- fix spell error of dev.

Signed-off-by: Hao Chen <chenhaoa at uniontech.com>
---
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c    | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index d0ce608b81c3..8e2ae0ff7f8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -12,8 +12,9 @@
 #include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/mii.h>
-#include <linux/phylink.h>
 #include <linux/net_tstamp.h>
+#include <linux/phylink.h>
+#include <linux/pm_runtime.h>
 #include <asm/io.h>
 
 #include "stmmac.h"
@@ -410,11 +411,14 @@ static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
 
 }
 
-static int stmmac_check_if_running(struct net_device *dev)
+static int stmmac_ethtool_begin(struct net_device *dev)
 {
-	if (!netif_running(dev))
-		return -EBUSY;
-	return 0;
+	return pm_runtime_resume_and_get(dev->dev);
+}
+
+static void stmmac_ethtool_complete(struct net_device *dev)
+{
+	pm_runtime_put(dev->dev);
 }
 
 static int stmmac_ethtool_get_regs_len(struct net_device *dev)
@@ -1073,7 +1077,8 @@ static int stmmac_set_tunable(struct net_device *dev,
 static const struct ethtool_ops stmmac_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES,
-	.begin = stmmac_check_if_running,
+	.begin = stmmac_ethtool_begin,
+	.complete = stmmac_ethtool_complete,
 	.get_drvinfo = stmmac_ethtool_getdrvinfo,
 	.get_msglevel = stmmac_ethtool_getmsglevel,
 	.set_msglevel = stmmac_ethtool_setmsglevel,
-- 
2.20.1





From chenhaoa at uniontech.com  Mon Aug  2 19:20:08 2021
From: chenhaoa at uniontech.com (Hao Chen)
Date: Tue,  3 Aug 2021 10:20:08 +0800
Subject: [net-next,v8] net: stmmac: optimize check in ops '.begin'
Message-ID: <20210803022008.21284-1-chenhaoa@uniontech.com>

I want to get permanent MAC address when the interface is down. And I think
it is more convenient to get statistics in the down state by 'ethtool -S'.
But current all of the ethool command return -EBUSY.

I don't think we should check that the network interface is up in '.begin',
which will cause that all the ethtool commands can't be used when the
network interface is down. If some ethtool commands can only be used in the
up state, check it in the corresponding ethool OPS function is better.
This is too rude and unreasonable.

Compile-tested on arm64. Tested on an arm64 system with an on-board
STMMAC chip.

Changes v7 ... v8:
- Optimize commit description information, optimization parameters of
  pm_runtime function.

Changes v6 ... v7:
- fix arg type error of 'dev' to 'priv->device'.

Changes v5 ... v6:
- The 4.19.90 kernel not support pm_runtime, so implemente '.begin' and
  '.complete' again. Add return value check of pm_runtime function.

Changes v4 ... v5:
- test the '.begin' will return -13 error on my machine based on 4.19.90
  kernel. The platform driver does not supported pm_runtime. So remove the
  implementation of '.begin' and '.complete'.

Changes v3 ... v4:
- implement '.complete' ethtool OPS.

Changes v2 ... v3:
- add linux/pm_runtime.h head file.

Changes v1 ... v2:
- fix spell error of dev.

Signed-off-by: Hao Chen <chenhaoa at uniontech.com>
---
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c    | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index d0ce608b81c3..8e2ae0ff7f8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -12,8 +12,9 @@
 #include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/mii.h>
-#include <linux/phylink.h>
 #include <linux/net_tstamp.h>
+#include <linux/phylink.h>
+#include <linux/pm_runtime.h>
 #include <asm/io.h>
 
 #include "stmmac.h"
@@ -410,11 +411,14 @@ static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
 
 }
 
-static int stmmac_check_if_running(struct net_device *dev)
+static int stmmac_ethtool_begin(struct net_device *dev)
 {
-	if (!netif_running(dev))
-		return -EBUSY;
-	return 0;
+	return pm_runtime_resume_and_get(dev->dev);
+}
+
+static void stmmac_ethtool_complete(struct net_device *dev)
+{
+	pm_runtime_put(dev->dev);
 }
 
 static int stmmac_ethtool_get_regs_len(struct net_device *dev)
@@ -1073,7 +1077,8 @@ static int stmmac_set_tunable(struct net_device *dev,
 static const struct ethtool_ops stmmac_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES,
-	.begin = stmmac_check_if_running,
+	.begin = stmmac_ethtool_begin,
+	.complete = stmmac_ethtool_complete,
 	.get_drvinfo = stmmac_ethtool_getdrvinfo,
 	.get_msglevel = stmmac_ethtool_getmsglevel,
 	.set_msglevel = stmmac_ethtool_setmsglevel,
-- 
2.20.1





From chenhaoa at uniontech.com  Mon Aug  2 19:20:52 2021
From: chenhaoa at uniontech.com (Hao Chen)
Date: Tue,  3 Aug 2021 10:20:52 +0800
Subject: [net-next,v8] net: stmmac: optimize check in ops '.begin'
Message-ID: <20210803022052.21897-1-chenhaoa@uniontech.com>

I want to get permanent MAC address when the interface is down. And I think
it is more convenient to get statistics in the down state by 'ethtool -S'.
But current all of the ethool command return -EBUSY.

I don't think we should check that the network interface is up in '.begin',
which will cause that all the ethtool commands can't be used when the
network interface is down. If some ethtool commands can only be used in the
up state, check it in the corresponding ethool OPS function is better.
This is too rude and unreasonable.

Compile-tested on arm64. Tested on an arm64 system with an on-board
STMMAC chip.

Changes v7 ... v8:
- Optimize commit description information, optimization parameters of
  pm_runtime function.

Changes v6 ... v7:
- fix arg type error of 'dev' to 'priv->device'.

Changes v5 ... v6:
- The 4.19.90 kernel not support pm_runtime, so implemente '.begin' and
  '.complete' again. Add return value check of pm_runtime function.

Changes v4 ... v5:
- test the '.begin' will return -13 error on my machine based on 4.19.90
  kernel. The platform driver does not supported pm_runtime. So remove the
  implementation of '.begin' and '.complete'.

Changes v3 ... v4:
- implement '.complete' ethtool OPS.

Changes v2 ... v3:
- add linux/pm_runtime.h head file.

Changes v1 ... v2:
- fix spell error of dev.

Signed-off-by: Hao Chen <chenhaoa at uniontech.com>
---
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c    | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index d0ce608b81c3..8e2ae0ff7f8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -12,8 +12,9 @@
 #include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/mii.h>
-#include <linux/phylink.h>
 #include <linux/net_tstamp.h>
+#include <linux/phylink.h>
+#include <linux/pm_runtime.h>
 #include <asm/io.h>
 
 #include "stmmac.h"
@@ -410,11 +411,14 @@ static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
 
 }
 
-static int stmmac_check_if_running(struct net_device *dev)
+static int stmmac_ethtool_begin(struct net_device *dev)
 {
-	if (!netif_running(dev))
-		return -EBUSY;
-	return 0;
+	return pm_runtime_resume_and_get(dev->dev);
+}
+
+static void stmmac_ethtool_complete(struct net_device *dev)
+{
+	pm_runtime_put(dev->dev);
 }
 
 static int stmmac_ethtool_get_regs_len(struct net_device *dev)
@@ -1073,7 +1077,8 @@ static int stmmac_set_tunable(struct net_device *dev,
 static const struct ethtool_ops stmmac_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES,
-	.begin = stmmac_check_if_running,
+	.begin = stmmac_ethtool_begin,
+	.complete = stmmac_ethtool_complete,
 	.get_drvinfo = stmmac_ethtool_getdrvinfo,
 	.get_msglevel = stmmac_ethtool_getmsglevel,
 	.set_msglevel = stmmac_ethtool_setmsglevel,
-- 
2.20.1





From t123yh at outlook.com  Mon Aug  2 19:23:29 2021
From: t123yh at outlook.com (Tian Yunhao)
Date: Tue, 3 Aug 2021 02:23:29 +0000
Subject: [PATCH] clk: rk3308: make ddrphy4x clock critical
In-Reply-To: <CAGETcx8YYrkCV0UObtOqHUnS29Q-raC54KUh14wqyBDMJ4e46g@mail.gmail.com>
References: <BYAPR20MB24886765F888A9705CBEB70789E39@BYAPR20MB2488.namprd20.prod.outlook.com>
 <162734809017.2368309.7901135942001140161@swboyd.mtv.corp.google.com>
 <2634451.ElGaqSPkdT@diego>
 <162758560739.714452.5782743329332725952@swboyd.mtv.corp.google.com>,
 <CAGETcx8YYrkCV0UObtOqHUnS29Q-raC54KUh14wqyBDMJ4e46g@mail.gmail.com>
Message-ID: <BYAPR20MB24880A45E81C042CD4061C5C89F09@BYAPR20MB2488.namprd20.prod.outlook.com>

> Yunhao,
> 
> Is there at least some DT device that consumes the DDR phy clock? Can
you point me to the DT for this board (not the SoC) so I can take a
look at it later?

Hi Saravana,

If you don't mind, you can refer to 4.4 kernel modified by Rockchip. 

This is one of a board DTS: [1] (note line 203: &dmc). This is not the board I'm using, but I think specific board is not related to our problem here.

[1]: https://github.com/rockchip-linux/kernel/blob/develop-4.4/arch/arm64/boot/dts/rockchip/rk3308-ai-va-v10.dts

From chenhaoa at uniontech.com  Mon Aug  2 19:22:32 2021
From: chenhaoa at uniontech.com (Hao Chen)
Date: Tue,  3 Aug 2021 10:22:32 +0800
Subject: [net-next,v8] net: stmmac: optimize check in ops '.begin'
Message-ID: <20210803022232.23145-1-chenhaoa@uniontech.com>

I want to get permanent MAC address when the interface is down. And I think
it is more convenient to get statistics in the down state by 'ethtool -S'.
But current all of the ethool command return -EBUSY.

I don't think we should check that the network interface is up in '.begin',
which will cause that all the ethtool commands can't be used when the
network interface is down. If some ethtool commands can only be used in the
up state, check it in the corresponding ethool OPS function is better.
This is too rude and unreasonable.

Compile-tested on arm64. Tested on an arm64 system with an on-board
STMMAC chip.

Changes v7 ... v8:
- Optimize commit description information, optimization parameters of
  pm_runtime function.

Changes v6 ... v7:
- fix arg type error of 'dev' to 'priv->device'.

Changes v5 ... v6:
- The 4.19.90 kernel not support pm_runtime, so implemente '.begin' and
  '.complete' again. Add return value check of pm_runtime function.

Changes v4 ... v5:
- test the '.begin' will return -13 error on my machine based on 4.19.90
  kernel. The platform driver does not supported pm_runtime. So remove the
  implementation of '.begin' and '.complete'.

Changes v3 ... v4:
- implement '.complete' ethtool OPS.

Changes v2 ... v3:
- add linux/pm_runtime.h head file.

Changes v1 ... v2:
- fix spell error of dev.

Signed-off-by: Hao Chen <chenhaoa at uniontech.com>
---
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c    | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index d0ce608b81c3..8e2ae0ff7f8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -12,8 +12,9 @@
 #include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/mii.h>
-#include <linux/phylink.h>
 #include <linux/net_tstamp.h>
+#include <linux/phylink.h>
+#include <linux/pm_runtime.h>
 #include <asm/io.h>
 
 #include "stmmac.h"
@@ -410,11 +411,14 @@ static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
 
 }
 
-static int stmmac_check_if_running(struct net_device *dev)
+static int stmmac_ethtool_begin(struct net_device *dev)
 {
-	if (!netif_running(dev))
-		return -EBUSY;
-	return 0;
+	return pm_runtime_resume_and_get(dev->dev);
+}
+
+static void stmmac_ethtool_complete(struct net_device *dev)
+{
+	pm_runtime_put(dev->dev);
 }
 
 static int stmmac_ethtool_get_regs_len(struct net_device *dev)
@@ -1073,7 +1077,8 @@ static int stmmac_set_tunable(struct net_device *dev,
 static const struct ethtool_ops stmmac_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES,
-	.begin = stmmac_check_if_running,
+	.begin = stmmac_ethtool_begin,
+	.complete = stmmac_ethtool_complete,
 	.get_drvinfo = stmmac_ethtool_getdrvinfo,
 	.get_msglevel = stmmac_ethtool_getmsglevel,
 	.set_msglevel = stmmac_ethtool_setmsglevel,
-- 
2.20.1





From jason-jh.lin at mediatek.com  Mon Aug  2 19:24:13 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Tue, 3 Aug 2021 10:24:13 +0800
Subject: [PATCH v5 0/6] Add Mediatek Soc DRM (vdosys0) support for mt8195
In-Reply-To: <a8ce9da7-21c2-f9ef-161a-647d3f8748f3@collabora.com>
References: <20210729170737.21424-1-jason-jh.lin@mediatek.com>
 <a8ce9da7-21c2-f9ef-161a-647d3f8748f3@collabora.com>
Message-ID: <a18c9073b5dec59a4bdb3253dbc75dd56763da47.camel@mediatek.com>

Hi Enric,

On Fri, 2021-07-30 at 13:45 +0200, Enric Balletbo i Serra wrote:
> Hi Jason,
> 
> Thank you for your patch.
> 
> On 29/7/21 19:07, jason-jh.lin wrote:
> > The hardware path of vdosys0 with eDP panel output need to go
> > through
> > by several modules, such as, OVL, RDMA, COLOR, CCORR, AAL, GAMMA,
> > DITHER, DSC and MERGE.
> > 
> 
> 
> You said in other discussions that vdosys0 has eDP panel output and
> vdosys1 has
> DP output. Is it possible to switch the outputs? What I am wondering
> is if this
> configuration is hardware specific or board specific, i.e it'll be
> possible to
> have another board that has DP output on vdosys0 and eDP output for
> vdosys1?
> 
> Thanks,
>   Enric
> 

Because the configuration is hardware specific in mt8195 SoC, it is
possible to switch the output to DP or HDMI for vdosys1 and to switch
the output to DSI or eDP for vdosys0.
Due to the hot plug reqirement for HDMI and DP, vdosys1 will support
runtime sitching output. vdosys0 can do that too, but there is no hot
plug requirement for DSI panel or eDP panel.
So we configure the output to eDP for vdosys0 in build time currently.

In another board, such as mt8173 SoC, it doesn't have vdosys1 but it is
able to set the output to DSI and HDMI for vdosys0 at the same time.

Regards,
Jason-JH.Lin

> 
> > Change in v5:
> > - add power-domain property into vdosys0 and vdosys1 dts node.
> > - add MT8195 prifix and remove unused VDO1 define in mt8195-mmsys.h
> > 
> > Change in v4:
> > - extract dt-binding patches to another patch series
> >   
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597__;!!CTRNKA9wMg0ARbw!3juKPT3EahvXs9aSRTDPxQfapIiXFGGx996Kss9b8DITyA19pd5F4K0AWsEp1U3C3FSl$
> >  
> > - squash DSC module into mtk_drm_ddp_comp.c
> > - add coment and simplify MERGE config function
> > 
> > Change in v3:
> > - change mmsys and display dt-bindings document from txt to yaml
> > - add MERGE additional description in display dt-bindings document
> > - fix mboxes-cells number of vdosys0 node in dts
> > - drop mutex eof convert define
> > - remove pm_runtime apis in DSC and MERGE
> > - change DSC and MERGE enum to alphabetic order
> > 
> > Change in v2:
> > - add DSC yaml file
> > - add mt8195 drm driver porting parts in to one patch
> > - remove useless define, variable, structure member and function
> > - simplify DSC and MERGE file and switch threre order
> > 
> > jason-jh.lin (6):
> >   arm64: dts: mt8195: add display node for vdosys0
> >   soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
> >   soc: mediatek: add mtk-mutex support for mt8195 vdosys0
> >   drm/mediatek: add mediatek-drm of vdosys0 support for mt8195
> >   drm/mediatek: add DSC support for mt8195
> >   drm/mediatek: add MERGE support for mt8195
> > 
> >  arch/arm64/boot/dts/mediatek/mt8195.dtsi    | 112 ++++++++
> >  drivers/gpu/drm/mediatek/Makefile           |   1 +
> >  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
> >  drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 277
> > ++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_disp_rdma.c    |   6 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  62 +++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   2 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  32 ++-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
> >  drivers/soc/mediatek/mt8195-mmsys.h         |  96 +++++++
> >  drivers/soc/mediatek/mtk-mmsys.c            |  11 +
> >  drivers/soc/mediatek/mtk-mutex.c            |  93 ++++++-
> >  include/linux/soc/mediatek/mtk-mmsys.h      |   9 +
> >  13 files changed, 706 insertions(+), 4 deletions(-)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
> >  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From chenhaoa at uniontech.com  Mon Aug  2 19:23:13 2021
From: chenhaoa at uniontech.com (Hao Chen)
Date: Tue,  3 Aug 2021 10:23:13 +0800
Subject: [net-next,v8] net: stmmac: optimize check in ops '.begin'
Message-ID: <20210803022313.23612-1-chenhaoa@uniontech.com>

I want to get permanent MAC address when the interface is down. And I think
it is more convenient to get statistics in the down state by 'ethtool -S'.
But current all of the ethool command return -EBUSY.

I don't think we should check that the network interface is up in '.begin',
which will cause that all the ethtool commands can't be used when the
network interface is down. If some ethtool commands can only be used in the
up state, check it in the corresponding ethool OPS function is better.
This is too rude and unreasonable.

Compile-tested on arm64. Tested on an arm64 system with an on-board
STMMAC chip.

Changes v7 ... v8:
- Optimize commit description information, optimization parameters of
  pm_runtime function.

Changes v6 ... v7:
- fix arg type error of 'dev' to 'priv->device'.

Changes v5 ... v6:
- The 4.19.90 kernel not support pm_runtime, so implemente '.begin' and
  '.complete' again. Add return value check of pm_runtime function.

Changes v4 ... v5:
- test the '.begin' will return -13 error on my machine based on 4.19.90
  kernel. The platform driver does not supported pm_runtime. So remove the
  implementation of '.begin' and '.complete'.

Changes v3 ... v4:
- implement '.complete' ethtool OPS.

Changes v2 ... v3:
- add linux/pm_runtime.h head file.

Changes v1 ... v2:
- fix spell error of dev.

Signed-off-by: Hao Chen <chenhaoa at uniontech.com>
---
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c    | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index d0ce608b81c3..8e2ae0ff7f8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -12,8 +12,9 @@
 #include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/mii.h>
-#include <linux/phylink.h>
 #include <linux/net_tstamp.h>
+#include <linux/phylink.h>
+#include <linux/pm_runtime.h>
 #include <asm/io.h>
 
 #include "stmmac.h"
@@ -410,11 +411,14 @@ static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
 
 }
 
-static int stmmac_check_if_running(struct net_device *dev)
+static int stmmac_ethtool_begin(struct net_device *dev)
 {
-	if (!netif_running(dev))
-		return -EBUSY;
-	return 0;
+	return pm_runtime_resume_and_get(dev->dev);
+}
+
+static void stmmac_ethtool_complete(struct net_device *dev)
+{
+	pm_runtime_put(dev->dev);
 }
 
 static int stmmac_ethtool_get_regs_len(struct net_device *dev)
@@ -1073,7 +1077,8 @@ static int stmmac_set_tunable(struct net_device *dev,
 static const struct ethtool_ops stmmac_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES,
-	.begin = stmmac_check_if_running,
+	.begin = stmmac_ethtool_begin,
+	.complete = stmmac_ethtool_complete,
 	.get_drvinfo = stmmac_ethtool_getdrvinfo,
 	.get_msglevel = stmmac_ethtool_getmsglevel,
 	.set_msglevel = stmmac_ethtool_setmsglevel,
-- 
2.20.1





From chenhaoa at uniontech.com  Mon Aug  2 19:31:22 2021
From: chenhaoa at uniontech.com (Hao Chen)
Date: Tue,  3 Aug 2021 10:31:22 +0800
Subject: [net-next,v8] net: stmmac: optimize check in ops '.begin'
Message-ID: <20210803023122.30817-1-chenhaoa@uniontech.com>

I want to get permanent MAC address when the interface is down. And I think
it is more convenient to get statistics in the down state by 'ethtool -S'.
But current all of the ethool command return -EBUSY.

I don't think we should check that the network interface is up in '.begin',
which will cause that all the ethtool commands can't be used when the
network interface is down. If some ethtool commands can only be used in the
up state, check it in the corresponding ethool OPS function is better.
This is too rude and unreasonable.

Compile-tested on arm64. Tested on an arm64 system with an on-board
STMMAC chip.

Changes v7 ... v8:
- Optimize commit description information, optimization parameters of
  pm_runtime function.

Changes v6 ... v7:
- fix arg type error of 'dev' to 'priv->device'.

Changes v5 ... v6:
- The 4.19.90 kernel not support pm_runtime, so implemente '.begin' and
  '.complete' again. Add return value check of pm_runtime function.

Changes v4 ... v5:
- test the '.begin' will return -13 error on my machine based on 4.19.90
  kernel. The platform driver does not supported pm_runtime. So remove the
  implementation of '.begin' and '.complete'.

Changes v3 ... v4:
- implement '.complete' ethtool OPS.

Changes v2 ... v3:
- add linux/pm_runtime.h head file.

Changes v1 ... v2:
- fix spell error of dev.

Signed-off-by: Hao Chen <chenhaoa at uniontech.com>
---
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c    | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index d0ce608b81c3..8e2ae0ff7f8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -12,8 +12,9 @@
 #include <linux/ethtool.h>
 #include <linux/interrupt.h>
 #include <linux/mii.h>
-#include <linux/phylink.h>
 #include <linux/net_tstamp.h>
+#include <linux/phylink.h>
+#include <linux/pm_runtime.h>
 #include <asm/io.h>
 
 #include "stmmac.h"
@@ -410,11 +411,14 @@ static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
 
 }
 
-static int stmmac_check_if_running(struct net_device *dev)
+static int stmmac_ethtool_begin(struct net_device *dev)
 {
-	if (!netif_running(dev))
-		return -EBUSY;
-	return 0;
+	return pm_runtime_resume_and_get(dev->dev);
+}
+
+static void stmmac_ethtool_complete(struct net_device *dev)
+{
+	pm_runtime_put(dev->dev);
 }
 
 static int stmmac_ethtool_get_regs_len(struct net_device *dev)
@@ -1073,7 +1077,8 @@ static int stmmac_set_tunable(struct net_device *dev,
 static const struct ethtool_ops stmmac_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 				     ETHTOOL_COALESCE_MAX_FRAMES,
-	.begin = stmmac_check_if_running,
+	.begin = stmmac_ethtool_begin,
+	.complete = stmmac_ethtool_complete,
 	.get_drvinfo = stmmac_ethtool_getdrvinfo,
 	.get_msglevel = stmmac_ethtool_getmsglevel,
 	.set_msglevel = stmmac_ethtool_setmsglevel,
-- 
2.20.1





From jason-jh.lin at mediatek.com  Mon Aug  2 19:30:30 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Tue, 3 Aug 2021 10:30:30 +0800
Subject: [PATCH v5 2/6] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys0
In-Reply-To: <51476e76-467c-6ade-69ba-09d861bee029@collabora.com>
References: <20210729170737.21424-1-jason-jh.lin@mediatek.com>
 <20210729170737.21424-3-jason-jh.lin@mediatek.com>
 <51476e76-467c-6ade-69ba-09d861bee029@collabora.com>
Message-ID: <32065fff2e122e44f4896e29e9fdeaa2137ad90c.camel@mediatek.com>

Hi Enric,

On Fri, 2021-07-30 at 13:41 +0200, Enric Balletbo i Serra wrote:
> Hi Jason,
> 
> Thank you for your patch.
> 
> On 29/7/21 19:07, jason-jh.lin wrote:
> > Add mt8195 vdosys0 clock driver name and routing table to
> > the driver data of mtk-mmsys.
> > 
> 
> This patch is the one that is really introducing mt8195 mmsys
> support. It is a
> bit confusing sent the binding on another patchset. Please include
> [1] in this
> patchset so it's clear.
> 
> [1]
> 
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210722092624.14401-2-jason-jh.lin at mediatek.com/__;!!CTRNKA9wMg0ARbw!3MaHl_gSJTB1nJ3RMsmAf7oLpKF8I3nDGIgkcVBlZ_LjV8Z0g88U5giQCAXRidxVujDS$
>  
Ok, I'll add this.
> 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> > This patch is base on [1]
> > 
> > [1]add mt8195 SoC DRM binding
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597__;!!CTRNKA9wMg0ARbw!3MaHl_gSJTB1nJ3RMsmAf7oLpKF8I3nDGIgkcVBlZ_LjV8Z0g88U5giQCAXRiX1vDsmL$
> >  
> > ---
> >  drivers/soc/mediatek/mt8195-mmsys.h    | 96
> > ++++++++++++++++++++++++++
> >  drivers/soc/mediatek/mtk-mmsys.c       | 11 +++
> >  include/linux/soc/mediatek/mtk-mmsys.h |  9 +++
> >  3 files changed, 116 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h
> > 
> > diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
> > b/drivers/soc/mediatek/mt8195-mmsys.h
> > new file mode 100644
> > index 000000000000..9339a786ec5d
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> > @@ -0,0 +1,96 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +
> > +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
> > +#define __SOC_MEDIATEK_MT8195_MMSYS_H
> > +
> > +#define MT8195_VDO0_OVL_MOUT_EN					
> > 0xf14
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			
> > BIT(0)
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			
> > BIT(1)
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
> > +#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			
> > BIT(4)
> > +#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			
> > BIT(5)
> > +#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
> > +
> > +#define MT8195_VDO0_SEL_IN					0xf34
> > +#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		(0 <<
> > 0)
> > +#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		(1 <<
> > 0)
> > +#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		(2 <<
> > 0)
> > +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		
> > (0 << 4)
> > +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		(1 <<
> > 4)
> > +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		
> > (0 << 5)
> > +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		(1 <<
> > 5)
> > +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		(0 <<
> > 8)
> > +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		
> > (1 << 8)
> > +#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		
> > (0 << 9)
> > +#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		(0 <<
> > 12)
> > +#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			
> > (1 << 12)
> > +#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		(2 <<
> > 12)
> > +#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			
> > (0 << 16)
> > +#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			
> > (1 << 16)
> > +#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			
> > (0 << 17)
> > +#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			(1 <<
> > 17)
> > +#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			
> > (0 << 20)
> > +#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			
> > (1 << 20)
> > +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		
> > (0 << 21)
> > +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		
> > (1 << 21)
> > +#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			
> > (0 << 22)
> > +#define MT8195_SEL_IN_DISP_WDMA0_FROM_VPP_MERGE			
> > (1 << 22)
> > +
> > +#define MT8195_VDO0_SEL_OUT					
> > 0xf38
> > +#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		(0 <<
> > 0)
> > +#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			(1 <<
> > 0)
> > +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		(0 <<
> > 1)
> > +#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			
> > (1 << 1)
> > +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		(2 <<
> > 1)
> > +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			
> > (0 << 4)
> > +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			
> > (1 << 4)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DSI1				
> > (0 << 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			(1 <<
> > 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			
> > (2 << 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			
> > (3 << 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			
> > (4 << 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			
> > (0 << 11)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA0			
> > (1 << 11)
> > +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			(0 <<
> > 12)
> > +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		(1 <<
> > 12)
> > +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			
> > (2 << 12)
> > +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			(0 <<
> > 16)
> > +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			
> > (1 << 16)
> > +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 <<
> > 16)
> > +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			
> > (3 << 16)
> > +
> > +static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[]
> > = {
> 
> If I understood correctly, in previous discussion you said that there
> will be
> two routing tables, one that is supposed to be for vdosys0 and
> another one
> vdosys1. The name here is too generic in my opinion, let's use a more
> specific
> name thinking in the future.
> 

we use one routing table for both vdosys0 and vdosys1 because they have
different component list. we can recognize those register configuration
are for vdosys0 and vdosys1 in the same routting table.

Regards,
Jason-JH.Lin
> 
> > +	{
> > +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> > +		MT8195_VDO0_OVL_MOUT_EN,
> > MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
> > +	}, {
> > +		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
> > +		MT8195_VDO0_OVL_MOUT_EN,
> > MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
> > +	}, {
> > +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> > +		MT8195_VDO0_SEL_IN,
> > MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
> > +	}, {
> > +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> > +		MT8195_VDO0_SEL_IN,
> > MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
> > +	}, {
> > +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> > +		MT8195_VDO0_SEL_IN,
> > MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
> > +	}, {
> > +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> > +		MT8195_VDO0_SEL_IN,
> > MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
> > +	}, {
> > +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> > +		MT8195_VDO0_SEL_OUT,
> > MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
> > +	}, {
> > +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> > +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0
> > +	}, {
> > +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> > +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
> > +	}, {
> > +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> > +		MT8195_VDO0_SEL_OUT,
> > MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
> > +	}
> > +};
> > +
> > +#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
> > diff --git a/drivers/soc/mediatek/mtk-mmsys.c
> > b/drivers/soc/mediatek/mtk-mmsys.c
> > index 080660ef11bf..1fb241750897 100644
> > --- a/drivers/soc/mediatek/mtk-mmsys.c
> > +++ b/drivers/soc/mediatek/mtk-mmsys.c
> > @@ -13,6 +13,7 @@
> >  #include "mtk-mmsys.h"
> >  #include "mt8167-mmsys.h"
> >  #include "mt8183-mmsys.h"
> > +#include "mt8195-mmsys.h"
> >  
> >  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data
> > = {
> >  	.clk_driver = "clk-mt2701-mm",
> > @@ -52,6 +53,12 @@ static const struct mtk_mmsys_driver_data
> > mt8183_mmsys_driver_data = {
> >  	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
> >  };
> >  
> > +static const struct mtk_mmsys_driver_data
> > mt8195_vdosys0_driver_data = {
> > +	.clk_driver = "clk-mt8195-vdo0",
> > +	.routes = mmsys_mt8195_routing_table,
> > +	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
> > +};
> > +
> >  struct mtk_mmsys {
> >  	void __iomem *regs;
> >  	const struct mtk_mmsys_driver_data *data;
> > @@ -157,6 +164,10 @@ static const struct of_device_id
> > of_match_mtk_mmsys[] = {
> >  		.compatible = "mediatek,mt8183-mmsys",
> >  		.data = &mt8183_mmsys_driver_data,
> >  	},
> > +	{
> > +		.compatible = "mediatek,mt8195-vdosys0",
> > +		.data = &mt8195_vdosys0_driver_data,
> > +	},
> >  	{ }
> >  };
> >  
> > diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> > b/include/linux/soc/mediatek/mtk-mmsys.h
> > index 2228bf6133da..01bedfb08094 100644
> > --- a/include/linux/soc/mediatek/mtk-mmsys.h
> > +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> > @@ -39,6 +39,15 @@ enum mtk_ddp_comp_id {
> >  	DDP_COMPONENT_UFOE,
> >  	DDP_COMPONENT_WDMA0,
> >  	DDP_COMPONENT_WDMA1,
> > +	DDP_COMPONENT_MERGE0,
> > +	DDP_COMPONENT_MERGE1,
> > +	DDP_COMPONENT_MERGE2,
> > +	DDP_COMPONENT_MERGE3,
> > +	DDP_COMPONENT_MERGE4,
> > +	DDP_COMPONENT_MERGE5,
> > +	DDP_COMPONENT_DSC0,
> > +	DDP_COMPONENT_DSC1,
> > +	DDP_COMPONENT_DP_INTF0,
> >  	DDP_COMPONENT_ID_MAX,
> >  };
> >  
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From Mason.Zhang at mediatek.com  Mon Aug  2 19:13:29 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Tue, 3 Aug 2021 10:13:29 +0800
Subject: [PATCH 1/1] spi: tegra114: Fix set_cs_timing param
Message-ID: <20210803021328.28291-1-Mason.Zhang@mediatek.com>

This patch fixed set_cs_timing param, because cs timing delay has
been moved to spi_device.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 drivers/spi/spi-tegra114.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 5131141bbf0d..e9de1d958bbd 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -717,12 +717,12 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
 	dma_release_channel(dma_chan);
 }
 
-static int tegra_spi_set_hw_cs_timing(struct spi_device *spi,
-				      struct spi_delay *setup,
-				      struct spi_delay *hold,
-				      struct spi_delay *inactive)
+static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
 {
 	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
+	struct spi_delay *setup = &spi->cs_setup;
+	struct spi_delay *hold = &spi->cs_hold;
+	struct spi_delay *inactive = &spi->cs_inactive;
 	u8 setup_dly, hold_dly, inactive_dly;
 	u32 setup_hold;
 	u32 spi_cs_timing;
-- 
2.18.0

From mason.zhang at mediatek.com  Mon Aug  2 20:14:48 2021
From: mason.zhang at mediatek.com (Mason Zhang)
Date: Tue, 3 Aug 2021 11:14:48 +0800
Subject: [PATCH 2/3] spi: modify set_cs_timing parameter
In-Reply-To: <20210802201614.GA39900@sirena.org.uk>
References: <20210719091642.24633-1-mason.zhang@mediatek.com>
 <20210802201614.GA39900@sirena.org.uk>
Message-ID: <1627960488.7721.2.camel@mbjsdccf07>

On Mon, 2021-08-02 at 21:16 +0100, Mark Brown wrote:
> On Mon, Jul 19, 2021 at 05:16:43PM +0800, Mason Zhang wrote:
> > From: Mason Zhang <Mason.Zhang at mediatek.com>
> > 
> > No need pass in spi_delay to set_cs_timing callback.
> 
> This breaks the build:
> 
> /mnt/kernel/drivers/spi/spi-tegra114.c: In function 'tegra_spi_probe':
> /mnt/kernel/drivers/spi/spi-tegra114.c:1328:24: error: assignment to 'int (*)(struct spi_device *)' from incompatible pointer type 'int (*)(struct spi_device *, struct spi_delay *, struct spi_delay *, struct spi_delay *)' [-Werror=incompatible-pointer-types]
>   master->set_cs_timing = tegra_spi_set_hw_cs_timing;
>                         ^

Dear Mark:

	I have fixed this build err in this patch:

https://lore.kernel.org/linux-spi/20210803021328.28291-1-Mason.Zhang at mediatek.com/T/#u


Thanks
Mason

From anshuman.khandual at arm.com  Mon Aug  2 20:51:48 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 3 Aug 2021 09:21:48 +0530
Subject: [PATCH 10/10] arm64: errata: Add workaround for TSB flush failures
In-Reply-To: <32f719c8f9f61b244b3fc29137f76a19@kernel.org>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-11-suzuki.poulose@arm.com>
 <87mtq5a1gs.wl-maz@kernel.org> <c41330d9-c2a2-afbe-624f-77c1e94f0490@arm.com>
 <477c4943-7c35-8502-0291-4c0ed3a03905@arm.com>
 <32f719c8f9f61b244b3fc29137f76a19@kernel.org>
Message-ID: <eb02839d-b7af-0284-e4ef-8c628e0548d9@arm.com>



On 8/2/21 3:05 PM, Marc Zyngier wrote:
> On 2021-08-02 10:12, Anshuman Khandual wrote:
>> On 7/29/21 4:11 PM, Suzuki K Poulose wrote:
>>> On 29/07/2021 10:55, Marc Zyngier wrote:
>>>> On Wed, 28 Jul 2021 14:52:17 +0100,
>>>> Suzuki K Poulose <suzuki.poulose at arm.com>
> 
> [...]
> 
>>>>> +??????????? __tsb_csync();??????????????????????? \
>>>>> +??????????? __tsb_csync();??????????????????????? \
>>>>> +??????? } else {??????????????????????????? \
>>>>> +??????????? __tsb_csync();??????????????????????? \
>>>>> +??????? }??????????????????????????????? \
>>>>
>>>> nit: You could keep one unconditional __tsb_csync().
>>>
>>> I thought about that, I was worried if the CPU expects them back to back
>>> without any other instructions in between them. Thinking about it a bit
>>> more, it doesn't look like that is the case. I will confirm this and
>>> change it accordingly.
>> But its a very subtle change which might be difficult to debug and blame
>> later on, if indeed both the instructions need to be back to back. Seems
>> like just better to leave this unchanged.
> 
> Is that an actual requirement? Sounds like you want to find out
> from the errata document.

Sure, will get back on this.

> 
> And if they actually need to be back to back, what ensures that
> this is always called with interrupt disabled?
> 
> You would also need to have them in the same asm block to avoid
> the compiler reordering stuff.

Agreed, both the above constructs will be required to make sure that
the instructions will be executed consecutively (if required).


From dongas86 at gmail.com  Mon Aug  2 21:04:44 2021
From: dongas86 at gmail.com (Dong Aisheng)
Date: Tue, 3 Aug 2021 12:04:44 +0800
Subject: [PATCH 5/7] dt-bindings: soc: imx: add missing anatop binding
In-Reply-To: <CAL_Jsq+4247uCgu5pDAEqO9Nn=9deeJBkiOrG3fTwdqPO+6J2w@mail.gmail.com>
References: <20210715082536.1882077-1-aisheng.dong@nxp.com>
 <20210715082536.1882077-6-aisheng.dong@nxp.com>
 <20210722024948.GA3198597@robh.at.kernel.org>
 <CAA+hA=TwGGwZi2HzZSLSZHYWEi8Pp6AnHeRpfDhD0pUfY_xPSQ@mail.gmail.com>
 <CAL_Jsq+4247uCgu5pDAEqO9Nn=9deeJBkiOrG3fTwdqPO+6J2w@mail.gmail.com>
Message-ID: <CAA+hA=RQdpjMCivgBq2fBHD2NFqK5_8pSDgqmxGJohRiGac2wQ@mail.gmail.com>

On Mon, Aug 2, 2021 at 11:02 PM Rob Herring <robh at kernel.org> wrote:
>
> On Mon, Aug 2, 2021 at 5:38 AM Dong Aisheng <dongas86 at gmail.com> wrote:
> >
> > Hi Rob,
> >
> > On Thu, Jul 22, 2021 at 10:49 AM Rob Herring <robh at kernel.org> wrote:
> > >
> > > On Thu, Jul 15, 2021 at 04:25:34PM +0800, Dong Aisheng wrote:
> > > > Anatop is a system combo module which supports various analog functions
> > > > like PLL, Regulators, LDOs, Sensors and etc.
> > > > This binding doc is generated based on the exist usage in dts
> > > > in order to fix dt schema check failures.
> > > >
> > > > Cc: Rob Herring <robh+dt at kernel.org>
> > > > Cc: Shawn Guo <shawnguo at kernel.org>
> > > > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> > > > ---
> > > >  .../bindings/soc/imx/fsl,anatop.yaml          | 68 +++++++++++++++++++
> > > >  1 file changed, 68 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> > > > new file mode 100644
> > > > index 000000000000..f379d960f527
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/soc/imx/fsl,anatop.yaml
> > > > @@ -0,0 +1,68 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/soc/imx/fsl,anatop.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Freescale Anatop binding
> > > > +
> > > > +maintainers:
> > > > +  - Dong Aisheng <aisheng.dong at nxp.com>
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    oneOf:
> > > > +      - items:
> > > > +          - const: fsl,imx6q-anatop
> > > > +          - const: syscon
> > > > +          - const: simple-mfd
> > > > +      - items:
> > > > +          - enum:
> > > > +              - fsl,imx6sl-anatop
> > > > +              - fsl,imx6sll-anatop
> > > > +              - fsl,imx6sx-anatop
> > > > +              - fsl,imx6ul-anatop
> > > > +              - fsl,imx7d-anatop
> > > > +          - const: fsl,imx6q-anatop
> > > > +          - const: syscon
> > > > +          - const: simple-mfd
> > > > +      - items:
> > > > +          - enum:
> > > > +              - fsl,imx8mq-anatop
> > > > +              - fsl,imx8mm-anatop
> > > > +              - fsl,vf610-anatop
> > > > +          - const: syscon
> > > > +      - items:
> > > > +          - enum:
> > > > +              - fsl,imx8mn-anatop
> > > > +              - fsl,imx8mp-anatop
> > > > +          - const: fsl,imx8mm-anatop
> > > > +          - const: syscon
> > > > +
> > > > +  reg:
> > > > +    maxItems: 1
> > > > +
> > > > +  interrupts:
> > > > +    items:
> > > > +      - description: Temperature Sensor
> > > > +      - description: PMU interrupt 1
> > > > +      - description: PMU interrupt 2
> > > > +    minItems: 1
> > > > +    maxItems: 3
> > >
> > > Don't need maxItems.
> > >
> >
> > Got it
> >
> > > > +
> > > > +required:
> > > > +  - compatible
> > > > +  - reg
> > > > +
> > > > +additionalProperties: true
> > >
> > > This should be the case only for common schemas used by other schemas.
> > >
> >
> > Like iomuxc-gpr in patch 6, the problem is that for those nodes with
> > simple-mfd backwards compatibility,
> > there could be possibly some random subnodes since there're generic
> > combo registers.
> > That's why i use additionalProperties true to cover it.
> > Do you think it's ok?
>
> No, because all that should be reviewed rather than random subnodes.
> Otherwise, how do we validate them?

anatop and iomuxc-gpr are not simple mfd devices as they're misc
registers and could contain
various sub misc functions. And those sub functions usually have a
separate dt binding doc which
already covers them and does validation.
The binding here is addressing validation itself. It does not limit
the possible various sub function nodes
which already have a binding doc. Just like a bus node.

If we define them now, it means we may need to keep updating schema when new
user node appear as current dts may not use all possible sub functions.

However, i do agree that defining them all (and may need add more in
the future) helps validation.
But i'm not sure if it's worthy to do it for such cases for a 'bus' node?

Could you help clarify a bit more?

Regards
Aisheng

>
> Rob


From andrew at aj.id.au  Mon Aug  2 21:07:07 2021
From: andrew at aj.id.au (Andrew Jeffery)
Date: Tue, 03 Aug 2021 13:37:07 +0930
Subject: [RFC PATCH 0/6] leds: Fix pca955x GPIO pin mappings
In-Reply-To: <CAHp75Vdx9QA7dmSWK8GHxBBxP0uYjrz=Gm=75yqaWbBX6k3v=w@mail.gmail.com>
References: <20210723075858.376378-1-andrew@aj.id.au>
 <CAHp75VeQML7njMZ6x8kC-ZJVexC1xJ6n1cB3JneVMAVfuOJgWw@mail.gmail.com>
 <d019990e-a725-4ef5-bb54-aadee9d18b86@www.fastmail.com>
 <CAHp75Vc2W+WmwNj1AvH6EiT_80c+5gADV9QzK+asHxpd1Ucppw@mail.gmail.com>
 <6cc64039-f82a-4c1e-ad2c-16fad7aa3178@www.fastmail.com>
 <CAHp75Vdx9QA7dmSWK8GHxBBxP0uYjrz=Gm=75yqaWbBX6k3v=w@mail.gmail.com>
Message-ID: <50aaf381-8cda-4656-9222-f23fda75d3bc@www.fastmail.com>



On Thu, 29 Jul 2021, at 17:10, Andy Shevchenko wrote:
> On Thu, Jul 29, 2021 at 3:39 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> > On Wed, 28 Jul 2021, at 18:43, Andy Shevchenko wrote:
> > > On Wed, Jul 28, 2021 at 8:43 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> > > > However, userspace would never have
> > > > got the results it expected with the existing driver implementation, so
> > > > I guess you could argue that no such (useful) userspace exists. Given
> > > > that, we could adopt the strategy of always defining a gpiochip
> > > > covering the whole pin space, and parts of the devicetree binding just
> > > > become redundant.
> > >
> > > I'm lost now. GPIO has its own userspace ABI, how does it work right
> > > now in application to this chip?
> >
> > As above, it "works" if the GPIOs specified in the devicetree are
> > contiguous from line 0. It's broken if they're not.
> 
> So, "it never works" means there is no bug. Now, what we need is to
> keep the same enumeration scheme, but if you wish to be used half/half
> (or any other ratio), the driver should do like the above mentioned
> PWM, i.e. register entire space and depending on the requestor either
> proceed with a line or mark it as BUSY.
> 
> Ideally, looking into what the chip can do, this should be indeed
> converted to some like pin control + PWM + LED + GPIO drivers. Then
> the function in pin mux configuration can show what exactly is enabled
> on the certain line(s).

So just to clarify, you want both solutions here?

1. A gpiochip that covers the entire pin space
2. A pinmux implementation that manages pin allocation to the different drivers

In that case we can largely leave this series as is? We only need to 
adjust how we configure the gpiochip by dropping the pin-mapping 
implementation?

I don't have a need to implement a PWM driver for it right now but that 
would make sense to do at some point.

Andrew


From mchehab+huawei at kernel.org  Mon Aug  2 21:25:28 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Tue, 3 Aug 2021 06:25:28 +0200
Subject: [PATCH v7 08/10] arm64: dts: HiSilicon: Add support for HiKey
 970 PCIe controller hardware
In-Reply-To: <20210724041150.GA4053@thinkpad>
References: <cover.1626855713.git.mchehab+huawei@kernel.org>
 <e483ba44ed3d70e1f4ca899bb287fa38ee8a2876.1626855713.git.mchehab+huawei@kernel.org>
 <20210722133628.GC4446@workstation>
 <20210723085318.243f155f@coco.lan> <20210724041150.GA4053@thinkpad>
Message-ID: <20210803062528.0a264682@coco.lan>

Em Sat, 24 Jul 2021 09:41:50 +0530
Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org> escreveu:

> On Fri, Jul 23, 2021 at 08:53:18AM +0200, Mauro Carvalho Chehab wrote:
> > Em Thu, 22 Jul 2021 19:06:28 +0530
> > Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org> escreveu:
> >   
> > > On Wed, Jul 21, 2021 at 10:39:10AM +0200, Mauro Carvalho Chehab wrote:  
> > > > From: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > > > 
> > > > Add DTS bindings for the HiKey 970 board's PCIe hardware.
> > > > 
> > > > Co-developed-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
> > > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> > > > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
> > > > ---
> > > >  arch/arm64/boot/dts/hisilicon/hi3670.dtsi     | 71 +++++++++++++++++++
> > > >  .../boot/dts/hisilicon/hikey970-pmic.dtsi     |  1 -
> > > >  drivers/pci/controller/dwc/pcie-kirin.c       | 12 ----
> > > >  3 files changed, 71 insertions(+), 13 deletions(-)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/hisilicon/hi3670.dtsi b/arch/arm64/boot/dts/hisilicon/hi3670.dtsi
> > > > index 1f228612192c..6dfcfcfeedae 100644
> > > > --- a/arch/arm64/boot/dts/hisilicon/hi3670.dtsi
> > > > +++ b/arch/arm64/boot/dts/hisilicon/hi3670.dtsi
> > > > @@ -177,6 +177,12 @@ sctrl: sctrl at fff0a000 {
> > > >  			#clock-cells = <1>;
> > > >  		};
> > > >  
> > > > +		pmctrl: pmctrl at fff31000 {
> > > > +			compatible = "hisilicon,hi3670-pmctrl", "syscon";
> > > > +			reg = <0x0 0xfff31000 0x0 0x1000>;
> > > > +			#clock-cells = <1>;
> > > > +		};
> > > > +    
> > > 
> > > Irrelevant change to this patch.  
> > 
> > Huh?
> > 
> > This is used by PCIe PHY, as part of the power on procedures:
> > 
> > 	+static int hi3670_pcie_noc_power(struct hi3670_pcie_phy *phy, bool enable)
> > 	+{
> > 	+       struct device *dev = phy->dev;
> > 	+       u32 time = 100;
> > 	+       unsigned int val = NOC_PW_MASK;
> > 	+       int rst;
> > 	+
> > 	+       if (enable)
> > 	+               val = NOC_PW_MASK | NOC_PW_SET_BIT;
> > 	+       else
> > 	+               val = NOC_PW_MASK;
> > 	+       rst = enable ? 1 : 0;
> > 	+
> > 	+       regmap_write(phy->pmctrl, NOC_POWER_IDLEREQ_1, val);
> > 
> >   
> 
> Ah... you're hardcoding the syscon compatible in driver. Sorry missed that.
> 
> But if these syscon nodes are independent memory regions or belong to non
> PCI/PHY memory map, you could've fetched the reference through a DT property
> along with the offset then used it in driver.
> 
> Like,
> 
> 	pcie_phy: pcie-phy at fc000000 {
> 		...
> 		hisilicon,noc-power-regs = <&pmctrl 0x38c>;
> 		hisilicon,sctrl-cmos-regs = <&sctrl 0x60>;
> 		...
> 	};
> 
> The benefit of doing this way is, if the pmctrl, sctrl register layout changes
> in future, you can handle it without any issues.

Interesting approach, but probably overkill. I mean, the register mapping
here should be the same for all Kirin 970 PHY based devices. A PHY for a 
different SoC will likely have other differences than just those two regs.

Regards,
Mauro


From viresh.kumar at linaro.org  Mon Aug  2 21:34:45 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 3 Aug 2021 10:04:45 +0530
Subject: [PATCH] cpufreq: arm_scmi: Fix error path when allocation failed
In-Reply-To: <20210802204550.12647-1-lukasz.luba@arm.com>
References: <20210802204550.12647-1-lukasz.luba@arm.com>
Message-ID: <20210803043445.7sm4mnl4f5f7co7h@vireshk-i7>

On 02-08-21, 21:45, Lukasz Luba wrote:
> Print warning and return an error which would stop the initialization
> when cpumask allocation failed.
> 
> Fixes: 80a064dbd556 ("scmi-cpufreq: Get opp_shared_cpus from opp-v2 for EM")
> Signed-off-by: Lukasz Luba <lukasz.luba at arm.com>
> ---
>  drivers/cpufreq/scmi-cpufreq.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
> index ec9a87ca2dbb..b159123e68fd 100644
> --- a/drivers/cpufreq/scmi-cpufreq.c
> +++ b/drivers/cpufreq/scmi-cpufreq.c
> @@ -133,8 +133,10 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
>  		return -ENODEV;
>  	}
>  
> -	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL))
> -		ret = -ENOMEM;
> +	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL)) {
> +		dev_warn(cpu_dev, "failed to allocate cpumask\n");

We shouldn't be printing here anything I believe as the allocation
core does it for us. That's why you won't see a print message anywhere
for failed allocations.

> +		return -ENOMEM;
> +	}
>  
>  	/* Obtain CPUs that share SCMI performance controls */
>  	ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
> -- 
> 2.17.1
> 

-- 
viresh


From andrew at aj.id.au  Mon Aug  2 21:48:51 2021
From: andrew at aj.id.au (Andrew Jeffery)
Date: Tue, 03 Aug 2021 14:18:51 +0930
Subject: [PATCH v6 0/9] ASPEED sgpio driver enhancement.
In-Reply-To: <CAMpxmJU4jN-hpNYPLHLbjx4uZ6vDqcyuMVQXhHg1BWXOqyS22A@mail.gmail.com>
References: <20210712100317.23298-1-steven_lee@aspeedtech.com>
 <CAMpxmJXfUterUdaGHOJT5hwcVJ+3cqgSQVdp-6Atuyyo36FxfQ@mail.gmail.com>
 <20210723031615.GA10457@aspeedtech.com>
 <CAMpxmJU4jN-hpNYPLHLbjx4uZ6vDqcyuMVQXhHg1BWXOqyS22A@mail.gmail.com>
Message-ID: <58256e8f-6c9a-4ad4-b51e-4048b6feb42a@www.fastmail.com>



On Fri, 23 Jul 2021, at 17:00, Bartosz Golaszewski wrote:
> On Fri, Jul 23, 2021 at 5:16 AM Steven Lee <steven_lee at aspeedtech.com> wrote:
> >
> > The 07/21/2021 21:27, Bartosz Golaszewski wrote:
> > > On Mon, Jul 12, 2021 at 12:03 PM Steven Lee <steven_lee at aspeedtech.com> wrote:
> > > >
> > > > AST2600 SoC has 2 SGPIO master interfaces one with 128 pins another one
> > > > with 80 pins, AST2500/AST2400 SoC has 1 SGPIO master interface that
> > > > supports up to 80 pins.
> > > > In the current driver design, the max number of sgpio pins is hardcoded
> > > > in macro MAX_NR_HW_SGPIO and the value is 80.
> > > >
> > > > For supporting sgpio master interfaces of AST2600 SoC, the patch series
> > > > contains the following enhancement:
> > > > - Convert txt dt-bindings to yaml.
> > > > - Update aspeed-g6 dtsi to support the enhanced sgpio.
> > > > - Support muiltiple SGPIO master interfaces.
> > > > - Support up to 128 pins by dts ngpios property.
> > > > - Pair input/output GPIOs instead of using 0 as GPIO input pin base and
> > > >   MAX_NR_HW_SGPIO as GPIO output pin base.
> > > > - Support wdt reset tolerance.
> > > > - Fix irq_chip issues which causes multiple sgpio devices use the same
> > > >   irq_chip data.
> > > > - Replace all of_*() APIs with device_*().
> > > >
> > > > Changes from v5:
> > > > * Squash v5 patch-05 and patch-06 to one patch.
> > > > * Remove MAX_NR_HW_SGPIO and corresponding design to make the gpio
> > > >   input/output pin base are determined by ngpios.
> > > >   For example, if MAX_NR_HW_SGPIO is 80 and ngpios is 10, the original
> > > >   pin order is as follows:
> > > >     Input:
> > > >     0 1 2 3 ... 9
> > > >     Output:
> > > >     80 81 82 ... 89
> > > >
> > > >   With the new design, pin order is changed as follows:
> > > >     Input:
> > > >     0 2 4 6 ... 18(ngpios * 2 - 2)
> > > >     Output:
> > > >     1 3 5 7 ... 19(ngpios * 2 - 1)
> > > > * Replace ast2600-sgpiom-128 and ast2600-sgpiom-80 compatibles by
> > > >   ast2600-sgpiom.
> > > > * Fix coding style issues.
> > > >
> > > > Changes from v4:
> > > > * Remove ngpios from dtsi
> > > > * Add ast2400 and ast2500 platform data.
> > > > * Remove unused macros.
> > > > * Add ngpios check in a separate patch.
> > > > * Fix coding style issues.
> > > >
> > > > Changes from v3:
> > > > * Split dt-bindings patch to 2 patches
> > > > * Rename ast2600-sgpiom1 compatible with ast2600-sgiom-128
> > > > * Rename ast2600-sgpiom2 compatible with ast2600-sgiom-80
> > > > * Correct the typo in commit messages.
> > > > * Fix coding style issues.
> > > > * Replace all of_*() APIs with device_*().
> > > >
> > > > Changes from v2:
> > > > * Remove maximum/minimum of ngpios from bindings.
> > > > * Remove max-ngpios from bindings and dtsi.
> > > > * Remove ast2400-sgpiom and ast2500-sgpiom compatibles from dts and
> > > >   driver.
> > > > * Add ast2600-sgpiom1 and ast2600-sgpiom2 compatibles as their max
> > > >   number of available gpio pins are different.
> > > > * Modify functions to pass aspeed_sgpio struct instead of passing
> > > >   max_ngpios.
> > > > * Split sgpio driver patch to 3 patches
> > > >
> > > > Changes from v1:
> > > > * Fix yaml format issues.
> > > > * Fix issues reported by kernel test robot.
> > > >
> > > > Please help to review.
> > > >
> > > > Thanks,
> > > > Steven
> > > >
> > > > Steven Lee (9):
> > > >   dt-bindings: aspeed-sgpio: Convert txt bindings to yaml.
> > > >   dt-bindings: aspeed-sgpio: Add ast2600 sgpio
> > > >   ARM: dts: aspeed-g6: Add SGPIO node.
> > > >   ARM: dts: aspeed-g5: Remove ngpios from sgpio node.
> > > >   gpio: gpio-aspeed-sgpio: Add AST2600 sgpio support
> > > >   gpio: gpio-aspeed-sgpio: Add set_config function
> > > >   gpio: gpio-aspeed-sgpio: Move irq_chip to aspeed-sgpio struct
> > > >   gpio: gpio-aspeed-sgpio: Use generic device property APIs
> > > >   gpio: gpio-aspeed-sgpio: Return error if ngpios is not multiple of 8.
> > > >
> > > >  .../bindings/gpio/aspeed,sgpio.yaml           |  77 ++++++++
> > > >  .../devicetree/bindings/gpio/sgpio-aspeed.txt |  46 -----
> > > >  arch/arm/boot/dts/aspeed-g5.dtsi              |   1 -
> > > >  arch/arm/boot/dts/aspeed-g6.dtsi              |  28 +++
> > > >  drivers/gpio/gpio-aspeed-sgpio.c              | 178 +++++++++++-------
> > > >  5 files changed, 215 insertions(+), 115 deletions(-)
> > > >  create mode 100644 Documentation/devicetree/bindings/gpio/aspeed,sgpio.yaml
> > > >  delete mode 100644 Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
> > > >
> > > > --
> > > > 2.17.1
> > > >
> > >
> > > The series looks good to me. Can the DTS and GPIO patches go into
> > > v5.15 separately?
> > >
> >
> > Hi Bart,
> >
> > Thanks for the review.
> > Shall we do anything to make the patches go into v5.15 or wait for picking-up?
> >
> > Steven
> >
> > > Bart
> 
> It's more of a question to the relevant SoC maintainers.
> 
> Joel, Andrew: can I take the GPIO patches through the GPIO tree and
> you'll take the ARM patches separately into v5.15?

I think that should be okay. I'll poke Joel.

Andrew


From tabba at google.com  Mon Aug  2 22:02:42 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 3 Aug 2021 07:02:42 +0200
Subject: [PATCH v3 17/21] KVM: arm64: Mark host bss and rodata section as
 shared
In-Reply-To: <20210729132818.4091769-18-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-18-qperret@google.com>
Message-ID: <CA+EHjTwfsA8Z+_dJzqjsBXJ_SSC55Bcxc6HQ_Q4OJDrqmk0Unw@mail.gmail.com>

Hi Quentin,

On Thu, Jul 29, 2021 at 3:29 PM Quentin Perret <qperret at google.com> wrote:
>
> As the hypervisor maps the host's .bss and .rodata sections in its
> stage-1, make sure to tag them as shared in hyp and host page-tables.
>
> But since the hypervisor relies on the presence of these mappings, we
> cannot let the host in complete control of the memory regions -- it
> must not unshare or donate them to another entity for example. To
> prevent this, let's transfer the ownership of those ranges to the
> hypervisor itself, and share the pages back with the host.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/nvhe/setup.c | 82 +++++++++++++++++++++++++++++----
>  1 file changed, 74 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> index 0b574d106519..7f557b264f62 100644
> --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> @@ -58,6 +58,7 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>  {
>         void *start, *end, *virt = hyp_phys_to_virt(phys);
>         unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT;
> +       enum kvm_pgtable_prot prot;
>         int ret, i;
>
>         /* Recreate the hyp page-table using the early page allocator */
> @@ -83,10 +84,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>         if (ret)
>                 return ret;
>
> -       ret = pkvm_create_mappings(__start_rodata, __end_rodata, PAGE_HYP_RO);
> -       if (ret)
> -               return ret;
> -
>         ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO);
>         if (ret)
>                 return ret;
> @@ -95,10 +92,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>         if (ret)
>                 return ret;
>
> -       ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, PAGE_HYP_RO);
> -       if (ret)
> -               return ret;
> -
>         ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP);
>         if (ret)
>                 return ret;
> @@ -117,6 +110,24 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>                         return ret;
>         }
>
> +       /*
> +        * Map the host's .bss and .rodata sections RO in the hypervisor, but
> +        * transfer the ownerhsip from the host to the hypervisor itself to
> +        * make sure it can't be donated or shared with another entity.

nit: ownerhsip -> ownership

> +        *
> +        * The ownership transtion requires matching changes in the host

nit: transtion -> transition

> +        * stage-2. This will done later (see finalize_host_mappings()) once the

nit: will done -> will be done

> +        * hyp_vmemmap is addressable.
> +        */
> +       prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
> +       ret = pkvm_create_mappings(__start_rodata, __end_rodata, prot);
> +       if (ret)
> +               return ret;
> +
> +       ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, prot);

nit: for clarity, I wonder if it might be good to create an alias of
__hyp_bss_end as __bss_start or something. When it's been moved here,
it sticks out a bit more and makes the reader wonder about the
significance of __hyp_bss_end.

> +       if (ret)
> +               return ret;
> +
>         return 0;
>  }
>
> @@ -148,6 +159,57 @@ static void hpool_put_page(void *addr)
>         hyp_put_page(&hpool, addr);
>  }
>
> +static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
> +                                        kvm_pte_t *ptep,
> +                                        enum kvm_pgtable_walk_flags flag,
> +                                        void * const arg)
> +{
> +       enum kvm_pgtable_prot prot;
> +       enum pkvm_page_state state;
> +       kvm_pte_t pte = *ptep;
> +       phys_addr_t phys;
> +
> +       if (!kvm_pte_valid(pte))
> +               return 0;
> +
> +       if (level != (KVM_PGTABLE_MAX_LEVELS - 1))
> +               return -EINVAL;

I know that it's not in scope here, but I'm wondering whether we
should be checking for KVM_PTE_TYPE_PAGE instead of the level. Maybe
it would be good to have a helper somewhere for all these checks both
for clarity and to ensure that nothing has gone wrong with the pte.

> +
> +       phys = kvm_pte_to_phys(pte);
> +       if (!addr_is_memory(phys))
> +               return 0;
> +
> +       /*
> +        * Adjust the host stage-2 mappings to match the ownership attributes
> +        * configured in the hypervisor stage-1.
> +        */
> +       state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte));
> +       switch (state) {
> +       case PKVM_PAGE_OWNED:
> +               return host_stage2_set_owner_locked(phys, phys + PAGE_SIZE, pkvm_hyp_id);
> +       case PKVM_PAGE_SHARED_OWNED:
> +               prot = pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_BORROWED);
> +               break;
> +       case PKVM_PAGE_SHARED_BORROWED:
> +               prot = pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_OWNED);
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return host_stage2_idmap_locked(phys, phys + PAGE_SIZE, prot);
> +}
> +
> +static int finalize_host_mappings(void)
> +{
> +       struct kvm_pgtable_walker walker = {
> +               .cb     = finalize_host_mappings_walker,
> +               .flags  = KVM_PGTABLE_WALK_LEAF,
> +       };
> +
> +       return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker);
> +}
> +
>  void __noreturn __pkvm_init_finalise(void)
>  {
>         struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data);
> @@ -167,6 +229,10 @@ void __noreturn __pkvm_init_finalise(void)
>         if (ret)
>                 goto out;
>
> +       ret = finalize_host_mappings();
> +       if (ret)
> +               goto out;
> +
>         pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) {
>                 .zalloc_page = hyp_zalloc_hyp_page,
>                 .phys_to_virt = hyp_phys_to_virt,
> --
> 2.32.0.432.gabb21c7263-goog
>

Thanks,
/fuad


From kishon at ti.com  Mon Aug  2 22:03:03 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 10:33:03 +0530
Subject: [PATCH v7 0/7] Add SR-IOV support in PCIe Endpoint Core
Message-ID: <20210803050310.27122-1-kishon@ti.com>

Patch series
*) Adds support to add virtual functions to enable endpoint controller
   which supports SR-IOV capability
*) Add support in Cadence endpoint driver to configure virtual functions
*) Enable pci_endpoint_test driver to create pci_device for virtual
   functions

v1 of the patch series can be found at [1]
v2 of the patch series can be found at [2]
v3 of the patch series can be found at [3]
v4 of the patch series can be found at [4]
v5 of the patch series can be found at [5]
v6 of the patch series can be found at [6]

Here both physical functions and virtual functions use the same
pci_endpoint_test driver and existing pcitest utility can be used
to test virtual functions as well.

Changes from v6:
*) Rebased to 5.13-rc4

Changes from v5:
*) Rebased to 5.13-rc1

Changes from v4:
*) Added a fix in Cadence driver which was overwriting BAR configuration
   of physical function.
*) Didn't include Tom's Acked-by since Cadence driver is modified in
   this revision.

Changes from v3:
*) Fixed Rob's comment and added his Reviewed-by as suggested by him.

Changes from v2:
*) Fixed DT binding documentation comment by Rob
*) Fixed the error check in pci-epc-core.c

Changes from v1:
*) Re-based and Re-worked to latest kernel 5.10.0-rc2+ (now has generic
   binding for EP)

[1] -> http://lore.kernel.org/r/20191231113534.30405-1-kishon at ti.com
[2] -> http://lore.kernel.org/r/20201112175358.2653-1-kishon at ti.com
[3] -> https://lore.kernel.org/r/20210305050410.9201-1-kishon at ti.com
[4] -> http://lore.kernel.org/r/20210310160943.7606-1-kishon at ti.com
[5] -> https://lore.kernel.org/r/20210419083401.31628-1-kishon at ti.com
[6] -> http://lore.kernel.org/r/20210517074723.10212-1-kishon at ti.com

Kishon Vijay Abraham I (7):
  dt-bindings: PCI: pci-ep: Add binding to specify virtual function
  PCI: endpoint: Add support to add virtual function in endpoint core
  PCI: endpoint: Add support to link a physical function to a virtual
    function
  PCI: endpoint: Add virtual function number in pci_epc ops
  PCI: cadence: Add support to configure virtual functions
  misc: pci_endpoint_test: Populate sriov_configure ops to configure
    SR-IOV device
  Documentation: PCI: endpoint/pci-endpoint-cfs: Guide to use SR-IOV

 .../PCI/endpoint/pci-endpoint-cfs.rst         |  12 +-
 .../devicetree/bindings/pci/pci-ep.yaml       |   7 +
 drivers/misc/pci_endpoint_test.c              |   1 +
 .../pci/controller/cadence/pcie-cadence-ep.c  | 285 ++++++++++++++----
 drivers/pci/controller/cadence/pcie-cadence.h |   7 +
 .../pci/controller/dwc/pcie-designware-ep.c   |  36 +--
 drivers/pci/controller/pcie-rcar-ep.c         |  19 +-
 drivers/pci/controller/pcie-rockchip-ep.c     |  18 +-
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  79 +++--
 drivers/pci/endpoint/functions/pci-epf-test.c |  66 ++--
 drivers/pci/endpoint/pci-ep-cfs.c             |  24 ++
 drivers/pci/endpoint/pci-epc-core.c           | 130 +++++---
 drivers/pci/endpoint/pci-epf-core.c           | 144 ++++++++-
 include/linux/pci-epc.h                       |  57 ++--
 include/linux/pci-epf.h                       |  16 +-
 15 files changed, 684 insertions(+), 217 deletions(-)

-- 
2.17.1



From kishon at ti.com  Mon Aug  2 22:03:04 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 10:33:04 +0530
Subject: [PATCH v7 1/7] dt-bindings: PCI: pci-ep: Add binding to specify
 virtual function
In-Reply-To: <20210803050310.27122-1-kishon@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
Message-ID: <20210803050310.27122-2-kishon@ti.com>

Add binding to specify virtual function (associated with each physical
function) in endpoint mode.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/pci/pci-ep.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/pci-ep.yaml b/Documentation/devicetree/bindings/pci/pci-ep.yaml
index 7847bbcd4a03..ccec51ab5247 100644
--- a/Documentation/devicetree/bindings/pci/pci-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/pci-ep.yaml
@@ -23,6 +23,13 @@ properties:
     default: 1
     maximum: 255
 
+  max-virtual-functions:
+    description: Array representing the number of virtual functions corresponding to each physical
+      function
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    minItems: 1
+    maxItems: 255
+
   max-link-speed:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [ 1, 2, 3, 4 ]
-- 
2.17.1



From kishon at ti.com  Mon Aug  2 22:03:05 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 10:33:05 +0530
Subject: [PATCH v7 2/7] PCI: endpoint: Add support to add virtual function in
 endpoint core
In-Reply-To: <20210803050310.27122-1-kishon@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
Message-ID: <20210803050310.27122-3-kishon@ti.com>

Add support to add virtual function in endpoint core. The virtual
function can only be associated with a physical function instead of a
endpoint controller. Provide APIs to associate a virtual function with
a physical function here.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/endpoint/pci-epc-core.c |  2 +-
 drivers/pci/endpoint/pci-epf-core.c | 96 ++++++++++++++++++++++++++++-
 include/linux/pci-epf.h             | 16 ++++-
 3 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index adec9bee72cf..01c58ca84dcc 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -548,7 +548,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf,
 	u32 func_no;
 	int ret = 0;
 
-	if (IS_ERR_OR_NULL(epc))
+	if (IS_ERR_OR_NULL(epc) || epf->is_vf)
 		return -EINVAL;
 
 	if (type == PRIMARY_INTERFACE && epf->epc)
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index e9289d10f822..ae7107a3196e 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -62,13 +62,20 @@ EXPORT_SYMBOL_GPL(pci_epf_type_add_cfs);
  */
 void pci_epf_unbind(struct pci_epf *epf)
 {
+	struct pci_epf *epf_vf;
+
 	if (!epf->driver) {
 		dev_WARN(&epf->dev, "epf device not bound to driver\n");
 		return;
 	}
 
 	mutex_lock(&epf->lock);
-	epf->driver->ops->unbind(epf);
+	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		if (epf_vf->is_bound)
+			epf_vf->driver->ops->unbind(epf_vf);
+	}
+	if (epf->is_bound)
+		epf->driver->ops->unbind(epf);
 	mutex_unlock(&epf->lock);
 	module_put(epf->driver->owner);
 }
@@ -83,6 +90,7 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind);
  */
 int pci_epf_bind(struct pci_epf *epf)
 {
+	struct pci_epf *epf_vf;
 	int ret;
 
 	if (!epf->driver) {
@@ -94,13 +102,95 @@ int pci_epf_bind(struct pci_epf *epf)
 		return -EAGAIN;
 
 	mutex_lock(&epf->lock);
+	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		epf_vf->func_no = epf->func_no;
+		epf_vf->epc = epf->epc;
+		epf_vf->sec_epc = epf->sec_epc;
+		ret = epf_vf->driver->ops->bind(epf_vf);
+		if (ret)
+			goto ret;
+		epf_vf->is_bound = true;
+	}
+
 	ret = epf->driver->ops->bind(epf);
+	if (ret)
+		goto ret;
+	epf->is_bound = true;
+
+	mutex_unlock(&epf->lock);
+	return 0;
+
+ret:
 	mutex_unlock(&epf->lock);
+	pci_epf_unbind(epf);
 
 	return ret;
 }
 EXPORT_SYMBOL_GPL(pci_epf_bind);
 
+/**
+ * pci_epf_add_vepf() - associate virtual EP function to physical EP function
+ * @epf_pf: the physical EP function to which the virtual EP function should be
+ *   associated
+ * @epf_vf: the virtual EP function to be added
+ *
+ * A physical endpoint function can be associated with multiple virtual
+ * endpoint functions. Invoke pci_epf_add_epf() to add a virtual PCI endpoint
+ * function to a physical PCI endpoint function.
+ */
+int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf)
+{
+	u32 vfunc_no;
+
+	if (IS_ERR_OR_NULL(epf_pf) || IS_ERR_OR_NULL(epf_vf))
+		return -EINVAL;
+
+	if (epf_pf->epc || epf_vf->epc || epf_vf->epf_pf)
+		return -EBUSY;
+
+	if (epf_pf->sec_epc || epf_vf->sec_epc)
+		return -EBUSY;
+
+	mutex_lock(&epf_pf->lock);
+	vfunc_no = find_first_zero_bit(&epf_pf->vfunction_num_map,
+				       BITS_PER_LONG);
+	if (vfunc_no >= BITS_PER_LONG)
+		return -EINVAL;
+
+	set_bit(vfunc_no, &epf_pf->vfunction_num_map);
+	epf_vf->vfunc_no = vfunc_no;
+
+	epf_vf->epf_pf = epf_pf;
+	epf_vf->is_vf = true;
+
+	list_add_tail(&epf_vf->list, &epf_pf->pci_vepf);
+	mutex_unlock(&epf_pf->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_add_vepf);
+
+/**
+ * pci_epf_remove_vepf() - remove virtual EP function from physical EP function
+ * @epf_pf: the physical EP function from which the virtual EP function should
+ *   be removed
+ * @epf_vf: the virtual EP function to be removed
+ *
+ * Invoke to remove a virtual endpoint function from the physcial endpoint
+ * function.
+ */
+void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf)
+{
+	if (IS_ERR_OR_NULL(epf_pf) || IS_ERR_OR_NULL(epf_vf))
+		return;
+
+	mutex_lock(&epf_pf->lock);
+	clear_bit(epf_vf->vfunc_no, &epf_pf->vfunction_num_map);
+	list_del(&epf_vf->list);
+	mutex_unlock(&epf_pf->lock);
+}
+EXPORT_SYMBOL_GPL(pci_epf_remove_vepf);
+
 /**
  * pci_epf_free_space() - free the allocated PCI EPF register space
  * @epf: the EPF device from whom to free the memory
@@ -317,6 +407,10 @@ struct pci_epf *pci_epf_create(const char *name)
 		return ERR_PTR(-ENOMEM);
 	}
 
+	/* VFs are numbered starting with 1. So set BIT(0) by default */
+	epf->vfunction_num_map = 1;
+	INIT_LIST_HEAD(&epf->pci_vepf);
+
 	dev = &epf->dev;
 	device_initialize(dev);
 	dev->bus = &pci_epf_bus_type;
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 2debc27ba95e..043b4c9c7188 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -121,8 +121,10 @@ struct pci_epf_bar {
  * @bar: represents the BAR of EPF device
  * @msi_interrupts: number of MSI interrupts required by this function
  * @msix_interrupts: number of MSI-X interrupts required by this function
- * @func_no: unique function number within this endpoint device
+ * @func_no: unique (physical) function number within this endpoint device
+ * @vfunc_no: unique virtual function number within a physical function
  * @epc: the EPC device to which this EPF device is bound
+ * @epf_pf: the physical EPF device to which this virtual EPF device is bound
  * @driver: the EPF driver to which this EPF device is bound
  * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc
  * @nb: notifier block to notify EPF of any EPC events (like linkup)
@@ -133,6 +135,10 @@ struct pci_epf_bar {
  * @sec_epc_bar: represents the BAR of EPF device associated with secondary EPC
  * @sec_epc_func_no: unique (physical) function number within the secondary EPC
  * @group: configfs group associated with the EPF device
+ * @is_bound: indicates if bind notification to function driver has been invoked
+ * @is_vf: true - virtual function, false - physical function
+ * @vfunction_num_map: bitmap to manage virtual function number
+ * @pci_vepf: list of virtual endpoint functions associated with this function
  */
 struct pci_epf {
 	struct device		dev;
@@ -142,8 +148,10 @@ struct pci_epf {
 	u8			msi_interrupts;
 	u16			msix_interrupts;
 	u8			func_no;
+	u8			vfunc_no;
 
 	struct pci_epc		*epc;
+	struct pci_epf		*epf_pf;
 	struct pci_epf_driver	*driver;
 	struct list_head	list;
 	struct notifier_block   nb;
@@ -156,6 +164,10 @@ struct pci_epf {
 	struct pci_epf_bar	sec_epc_bar[6];
 	u8			sec_epc_func_no;
 	struct config_group	*group;
+	unsigned int		is_bound;
+	unsigned int		is_vf;
+	unsigned long		vfunction_num_map;
+	struct list_head	pci_vepf;
 };
 
 /**
@@ -199,4 +211,6 @@ int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
 struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf,
 					  struct config_group *group);
+int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);
+void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);
 #endif /* __LINUX_PCI_EPF_H */
-- 
2.17.1



From kishon at ti.com  Mon Aug  2 22:03:06 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 10:33:06 +0530
Subject: [PATCH v7 3/7] PCI: endpoint: Add support to link a physical function
 to a virtual function
In-Reply-To: <20210803050310.27122-1-kishon@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
Message-ID: <20210803050310.27122-4-kishon@ti.com>

While the physical function has to be linked to endpoint controller, the
virtual function has to be linked to a physical function. Add support to
link a physical function to a virtual function in pci-ep-cfs.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/endpoint/pci-ep-cfs.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
index f3a8b833b479..999911801877 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -475,6 +475,28 @@ static struct configfs_attribute *pci_epf_attrs[] = {
 	NULL,
 };
 
+static int pci_epf_vepf_link(struct config_item *epf_pf_item,
+			     struct config_item *epf_vf_item)
+{
+	struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
+	struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
+	struct pci_epf *epf_pf = epf_pf_group->epf;
+	struct pci_epf *epf_vf = epf_vf_group->epf;
+
+	return pci_epf_add_vepf(epf_pf, epf_vf);
+}
+
+static void pci_epf_vepf_unlink(struct config_item *epf_pf_item,
+				struct config_item *epf_vf_item)
+{
+	struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
+	struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
+	struct pci_epf *epf_pf = epf_pf_group->epf;
+	struct pci_epf *epf_vf = epf_vf_group->epf;
+
+	pci_epf_remove_vepf(epf_pf, epf_vf);
+}
+
 static void pci_epf_release(struct config_item *item)
 {
 	struct pci_epf_group *epf_group = to_pci_epf_group(item);
@@ -487,6 +509,8 @@ static void pci_epf_release(struct config_item *item)
 }
 
 static struct configfs_item_operations pci_epf_ops = {
+	.allow_link		= pci_epf_vepf_link,
+	.drop_link		= pci_epf_vepf_unlink,
 	.release		= pci_epf_release,
 };
 
-- 
2.17.1



From kishon at ti.com  Mon Aug  2 22:03:07 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 10:33:07 +0530
Subject: [PATCH v7 4/7] PCI: endpoint: Add virtual function number in pci_epc
 ops
In-Reply-To: <20210803050310.27122-1-kishon@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
Message-ID: <20210803050310.27122-5-kishon@ti.com>

Add virtual function number in pci_epc ops. EPC controller driver
can perform virtual function specific initialization based on the
virtual function number.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c  |  44 +++---
 .../pci/controller/dwc/pcie-designware-ep.c   |  36 ++---
 drivers/pci/controller/pcie-rcar-ep.c         |  19 +--
 drivers/pci/controller/pcie-rockchip-ep.c     |  18 +--
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  79 ++++++-----
 drivers/pci/endpoint/functions/pci-epf-test.c |  66 +++++----
 drivers/pci/endpoint/pci-epc-core.c           | 128 ++++++++++++------
 drivers/pci/endpoint/pci-epf-core.c           |  48 ++++++-
 include/linux/pci-epc.h                       |  57 ++++----
 9 files changed, 313 insertions(+), 182 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 897cdde02bd8..912a15be8bfd 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -16,7 +16,7 @@
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE		0x1
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY	0x3
 
-static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -47,7 +47,7 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				struct pci_epf_bar *epf_bar)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -117,7 +117,7 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				   struct pci_epf_bar *epf_bar)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -147,8 +147,8 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 	epf->epf_bar[bar] = NULL;
 }
 
-static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
-				 u64 pci_addr, size_t size)
+static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
+				 phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -169,7 +169,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
 	return 0;
 }
 
-static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -189,7 +189,7 @@ static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
 	clear_bit(r, &ep->ob_region_map);
 }
 
-static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 mmc)
+static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -209,7 +209,7 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 mmc)
 	return 0;
 }
 
-static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -230,7 +230,7 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
 	return mme;
 }
 
-static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -247,8 +247,9 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u16 interrupts,
-				 enum pci_barno bir, u32 offset)
+static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
+				 u16 interrupts, enum pci_barno bir,
+				 u32 offset)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -317,7 +318,8 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
 	writel(0, ep->irq_cpu_addr + offset);
 }
 
-static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 intx)
+static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
+					u8 intx)
 {
 	u16 cmd;
 
@@ -334,7 +336,7 @@ static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 intx)
 	return 0;
 }
 
-static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
+static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				     u8 interrupt_num)
 {
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -382,7 +384,7 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr, u8 interrupt_num,
 				    u32 entry_size, u32 *msi_data,
 				    u32 *msi_addr_offset)
@@ -419,7 +421,7 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
 	pci_addr &= GENMASK_ULL(63, 2);
 
 	for (i = 0; i < interrupt_num; i++) {
-		ret = cdns_pcie_ep_map_addr(epc, fn, addr,
+		ret = cdns_pcie_ep_map_addr(epc, fn, vfn, addr,
 					    pci_addr & ~pci_addr_mask,
 					    entry_size);
 		if (ret)
@@ -433,7 +435,7 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
+static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				      u16 interrupt_num)
 {
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
@@ -478,7 +480,7 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  enum pci_epc_irq_type type,
 				  u16 interrupt_num)
 {
@@ -486,13 +488,13 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
 
 	switch (type) {
 	case PCI_EPC_IRQ_LEGACY:
-		return cdns_pcie_ep_send_legacy_irq(ep, fn, 0);
+		return cdns_pcie_ep_send_legacy_irq(ep, fn, vfn, 0);
 
 	case PCI_EPC_IRQ_MSI:
-		return cdns_pcie_ep_send_msi_irq(ep, fn, interrupt_num);
+		return cdns_pcie_ep_send_msi_irq(ep, fn, vfn, interrupt_num);
 
 	case PCI_EPC_IRQ_MSIX:
-		return cdns_pcie_ep_send_msix_irq(ep, fn, interrupt_num);
+		return cdns_pcie_ep_send_msix_irq(ep, fn, vfn, interrupt_num);
 
 	default:
 		break;
@@ -531,7 +533,7 @@ static const struct pci_epc_features cdns_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &cdns_pcie_epc_features;
 }
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 8d028a88b375..998b698f4085 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -125,7 +125,7 @@ static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap)
 	return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap);
 }
 
-static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				   struct pci_epf_header *hdr)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -202,7 +202,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
 	return 0;
 }
 
-static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
+static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				 struct pci_epf_bar *epf_bar)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -217,7 +217,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
 	ep->epf_bar[bar] = NULL;
 }
 
-static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			      struct pci_epf_bar *epf_bar)
 {
 	int ret;
@@ -276,7 +276,7 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
 	return -EINVAL;
 }
 
-static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
+static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				  phys_addr_t addr)
 {
 	int ret;
@@ -292,9 +292,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
 	clear_bit(atu_index, ep->ob_window_map);
 }
 
-static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
-			       phys_addr_t addr,
-			       u64 pci_addr, size_t size)
+static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			       phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	int ret;
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -309,7 +308,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
 	return 0;
 }
 
-static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
+static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -333,7 +332,8 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
+static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			      u8 interrupts)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -358,7 +358,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 	return 0;
 }
 
-static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -382,8 +382,8 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-			       enum pci_barno bir, u32 offset)
+static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			       u16 interrupts, enum pci_barno bir, u32 offset)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -418,7 +418,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
 	return 0;
 }
 
-static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				enum pci_epc_irq_type type, u16 interrupt_num)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -450,7 +450,7 @@ static int dw_pcie_ep_start(struct pci_epc *epc)
 }
 
 static const struct pci_epc_features*
-dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 
@@ -525,14 +525,14 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 	aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1);
 	msg_addr = ((u64)msg_addr_upper) << 32 |
 			(msg_addr_lower & ~aligned_offset);
-	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
+	ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
 				  epc->mem->window.page_size);
 	if (ret)
 		return ret;
 
 	writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset);
 
-	dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
+	dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
 
 	return 0;
 }
@@ -593,14 +593,14 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	}
 
 	aligned_offset = msg_addr & (epc->mem->window.page_size - 1);
-	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,  msg_addr,
+	ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
 				  epc->mem->window.page_size);
 	if (ret)
 		return ret;
 
 	writel(msg_data, ep->msi_mem + aligned_offset);
 
-	dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
+	dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
 
 	return 0;
 }
diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
index b4a288e24aaf..6cee4e09acca 100644
--- a/drivers/pci/controller/pcie-rcar-ep.c
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -159,7 +159,7 @@ static int rcar_pcie_ep_get_pdata(struct rcar_pcie_endpoint *ep,
 	return 0;
 }
 
-static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -195,7 +195,7 @@ static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				struct pci_epf_bar *epf_bar)
 {
 	int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT;
@@ -246,7 +246,7 @@ static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
 	return 0;
 }
 
-static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				   struct pci_epf_bar *epf_bar)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -259,7 +259,8 @@ static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 	clear_bit(atu_index + 1, ep->ib_window_map);
 }
 
-static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
+static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
+				u8 interrupts)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
 	struct rcar_pcie *pcie = &ep->pcie;
@@ -272,7 +273,7 @@ static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
 	return 0;
 }
 
-static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
 	struct rcar_pcie *pcie = &ep->pcie;
@@ -285,7 +286,7 @@ static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
 	return ((flags & MSICAP0_MMESE_MASK) >> MSICAP0_MMESE_OFFSET);
 }
 
-static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				 phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -322,7 +323,7 @@ static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rcar_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void rcar_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -403,7 +404,7 @@ static int rcar_pcie_ep_assert_msi(struct rcar_pcie *pcie,
 	return 0;
 }
 
-static int rcar_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  enum pci_epc_irq_type type,
 				  u16 interrupt_num)
 {
@@ -451,7 +452,7 @@ static const struct pci_epc_features rcar_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-rcar_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+rcar_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &rcar_pcie_epc_features;
 }
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index 7631dc3961c1..5fb9ce6e536e 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -122,7 +122,7 @@ static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn,
 			    ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r));
 }
 
-static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 					 struct pci_epf_header *hdr)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -159,7 +159,7 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				    struct pci_epf_bar *epf_bar)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -227,7 +227,7 @@ static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				       struct pci_epf_bar *epf_bar)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -256,7 +256,7 @@ static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 			    ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar));
 }
 
-static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				     phys_addr_t addr, u64 pci_addr,
 				     size_t size)
 {
@@ -284,7 +284,7 @@ static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 					phys_addr_t addr)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -308,7 +308,7 @@ static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
 	clear_bit(r, &ep->ob_region_map);
 }
 
-static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
 				    u8 multi_msg_cap)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -329,7 +329,7 @@ static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
 	struct rockchip_pcie *rockchip = &ep->rockchip;
@@ -471,7 +471,7 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				      enum pci_epc_irq_type type,
 				      u16 interrupt_num)
 {
@@ -510,7 +510,7 @@ static const struct pci_epc_features rockchip_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &rockchip_pcie_epc_features;
 }
diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c b/drivers/pci/endpoint/functions/pci-epf-ntb.c
index bce274d02dcf..0059b13a613f 100644
--- a/drivers/pci/endpoint/functions/pci-epf-ntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c
@@ -87,6 +87,7 @@ struct epf_ntb {
 
 struct epf_ntb_epc {
 	u8 func_no;
+	u8 vfunc_no;
 	bool linkup;
 	bool is_msix;
 	int msix_bar;
@@ -143,14 +144,15 @@ static int epf_ntb_link_up(struct epf_ntb *ntb, bool link_up)
 	struct epf_ntb_epc *ntb_epc;
 	struct epf_ntb_ctrl *ctrl;
 	struct pci_epc *epc;
+	u8 func_no, vfunc_no;
 	bool is_msix;
-	u8 func_no;
 	int ret;
 
 	for (type = PRIMARY_INTERFACE; type <= SECONDARY_INTERFACE; type++) {
 		ntb_epc = ntb->epc[type];
 		epc = ntb_epc->epc;
 		func_no = ntb_epc->func_no;
+		vfunc_no = ntb_epc->vfunc_no;
 		is_msix = ntb_epc->is_msix;
 		ctrl = ntb_epc->reg;
 		if (link_up)
@@ -158,7 +160,7 @@ static int epf_ntb_link_up(struct epf_ntb *ntb, bool link_up)
 		else
 			ctrl->link_status &= ~LINK_STATUS_UP;
 		irq_type = is_msix ? PCI_EPC_IRQ_MSIX : PCI_EPC_IRQ_MSI;
-		ret = pci_epc_raise_irq(epc, func_no, irq_type, 1);
+		ret = pci_epc_raise_irq(epc, func_no, vfunc_no, irq_type, 1);
 		if (ret) {
 			dev_err(&epc->dev,
 				"%s intf: Failed to raise Link Up IRQ\n",
@@ -238,10 +240,10 @@ static int epf_ntb_configure_mw(struct epf_ntb *ntb,
 	enum pci_barno peer_barno;
 	struct epf_ntb_ctrl *ctrl;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	u64 addr, size;
 	int ret = 0;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -267,8 +269,9 @@ static int epf_ntb_configure_mw(struct epf_ntb *ntb,
 	}
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	ret = pci_epc_map_addr(epc, func_no, phys_addr, addr, size);
+	ret = pci_epc_map_addr(epc, func_no, vfunc_no, phys_addr, addr, size);
 	if (ret)
 		dev_err(&epc->dev,
 			"%s intf: Failed to map memory window %d address\n",
@@ -296,8 +299,8 @@ static void epf_ntb_teardown_mw(struct epf_ntb *ntb,
 	enum pci_barno peer_barno;
 	struct epf_ntb_ctrl *ctrl;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -311,8 +314,9 @@ static void epf_ntb_teardown_mw(struct epf_ntb *ntb,
 	if (mw + NTB_MW_OFFSET == BAR_DB_MW1)
 		phys_addr += ctrl->mw1_offset;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	pci_epc_unmap_addr(epc, func_no, phys_addr);
+	pci_epc_unmap_addr(epc, func_no, vfunc_no, phys_addr);
 }
 
 /**
@@ -385,8 +389,8 @@ static int epf_ntb_configure_msi(struct epf_ntb *ntb,
 	struct epf_ntb_ctrl *peer_ctrl;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 	int ret, i;
 
 	ntb_epc = ntb->epc[type];
@@ -400,8 +404,9 @@ static int epf_ntb_configure_msi(struct epf_ntb *ntb,
 
 	phys_addr = peer_epf_bar->phys_addr;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	ret = pci_epc_map_msi_irq(epc, func_no, phys_addr, db_count,
+	ret = pci_epc_map_msi_irq(epc, func_no, vfunc_no, phys_addr, db_count,
 				  db_entry_size, &db_data, &db_offset);
 	if (ret) {
 		dev_err(&epc->dev, "%s intf: Failed to map MSI IRQ\n",
@@ -491,10 +496,10 @@ static int epf_ntb_configure_msix(struct epf_ntb *ntb,
 	u32 db_entry_size, msg_data;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	size_t align;
 	u64 msg_addr;
-	u8 func_no;
 	int ret, i;
 
 	ntb_epc = ntb->epc[type];
@@ -512,12 +517,13 @@ static int epf_ntb_configure_msix(struct epf_ntb *ntb,
 	align = epc_features->align;
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	db_entry_size = peer_ctrl->db_entry_size;
 
 	for (i = 0; i < db_count; i++) {
 		msg_addr = ALIGN_DOWN(msix_tbl[i].msg_addr, align);
 		msg_data = msix_tbl[i].msg_data;
-		ret = pci_epc_map_addr(epc, func_no, phys_addr, msg_addr,
+		ret = pci_epc_map_addr(epc, func_no, vfunc_no, phys_addr, msg_addr,
 				       db_entry_size);
 		if (ret) {
 			dev_err(&epc->dev,
@@ -586,8 +592,8 @@ epf_ntb_teardown_db(struct epf_ntb *ntb, enum pci_epc_interface_type type)
 	struct pci_epf_bar *peer_epf_bar;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -597,8 +603,9 @@ epf_ntb_teardown_db(struct epf_ntb *ntb, enum pci_epc_interface_type type)
 	peer_epf_bar = &peer_ntb_epc->epf_bar[peer_barno];
 	phys_addr = peer_epf_bar->phys_addr;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	pci_epc_unmap_addr(epc, func_no, phys_addr);
+	pci_epc_unmap_addr(epc, func_no, vfunc_no, phys_addr);
 }
 
 /**
@@ -728,14 +735,15 @@ static void epf_ntb_peer_spad_bar_clear(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
 	epf_bar = &ntb_epc->epf_bar[barno];
-	pci_epc_clear_bar(epc, func_no, epf_bar);
+	pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 }
 
 /**
@@ -775,9 +783,9 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	struct pci_epf_bar *peer_epf_bar, *epf_bar;
 	enum pci_barno peer_barno, barno;
 	u32 peer_spad_offset;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	dev = &ntb->epf->dev;
@@ -790,6 +798,7 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
 	epf_bar = &ntb_epc->epf_bar[barno];
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	epc = ntb_epc->epc;
 
 	peer_spad_offset = peer_ntb_epc->reg->spad_offset;
@@ -798,7 +807,7 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	epf_bar->barno = barno;
 	epf_bar->flags = PCI_BASE_ADDRESS_MEM_TYPE_32;
 
-	ret = pci_epc_set_bar(epc, func_no, epf_bar);
+	ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 	if (ret) {
 		dev_err(dev, "%s intf: peer SPAD BAR set failed\n",
 			pci_epc_interface_string(type));
@@ -842,14 +851,15 @@ static void epf_ntb_config_sspad_bar_clear(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
 	epf_bar = &ntb_epc->epf_bar[barno];
-	pci_epc_clear_bar(epc, func_no, epf_bar);
+	pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 }
 
 /**
@@ -886,10 +896,10 @@ static int epf_ntb_config_sspad_bar_set(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct epf_ntb *ntb;
 	struct pci_epc *epc;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	ntb = ntb_epc->epf_ntb;
@@ -897,10 +907,11 @@ static int epf_ntb_config_sspad_bar_set(struct epf_ntb_epc *ntb_epc)
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
 	epf_bar = &ntb_epc->epf_bar[barno];
 
-	ret = pci_epc_set_bar(epc, func_no, epf_bar);
+	ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 	if (ret) {
 		dev_err(dev, "%s inft: Config/Status/SPAD BAR set failed\n",
 			pci_epc_interface_string(ntb_epc->type));
@@ -1214,17 +1225,18 @@ static void epf_ntb_db_mw_bar_clear(struct epf_ntb_epc *ntb_epc)
 	struct pci_epf_bar *epf_bar;
 	enum epf_ntb_bar bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	for (bar = BAR_DB_MW1; bar < BAR_MW4; bar++) {
 		barno = ntb_epc->epf_ntb_bar[bar];
 		epf_bar = &ntb_epc->epf_bar[barno];
-		pci_epc_clear_bar(epc, func_no, epf_bar);
+		pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 	}
 }
 
@@ -1263,10 +1275,10 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	const struct pci_epc_features *epc_features;
 	bool msix_capable, msi_capable;
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
 	u32 db_count;
-	u8 func_no;
 	int ret;
 
 	ntb_epc = ntb->epc[type];
@@ -1282,6 +1294,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	}
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	db_count = ntb->db_count;
 	if (db_count > MAX_DB_COUNT) {
@@ -1293,7 +1306,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	epc = ntb_epc->epc;
 
 	if (msi_capable) {
-		ret = pci_epc_set_msi(epc, func_no, db_count);
+		ret = pci_epc_set_msi(epc, func_no, vfunc_no, db_count);
 		if (ret) {
 			dev_err(dev, "%s intf: MSI configuration failed\n",
 				pci_epc_interface_string(type));
@@ -1302,7 +1315,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	}
 
 	if (msix_capable) {
-		ret = pci_epc_set_msix(epc, func_no, db_count,
+		ret = pci_epc_set_msix(epc, func_no, vfunc_no, db_count,
 				       ntb_epc->msix_bar,
 				       ntb_epc->msix_table_offset);
 		if (ret) {
@@ -1423,11 +1436,11 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 	u32 num_mws, db_count;
 	enum epf_ntb_bar bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
 	size_t align;
 	int ret, i;
-	u8 func_no;
 	u64 size;
 
 	ntb_epc = ntb->epc[type];
@@ -1437,6 +1450,7 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 	epc_features = ntb_epc->epc_features;
 	align = epc_features->align;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	epc = ntb_epc->epc;
 	num_mws = ntb->num_mws;
 	db_count = ntb->db_count;
@@ -1464,7 +1478,7 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 		barno = ntb_epc->epf_ntb_bar[bar];
 		epf_bar = &ntb_epc->epf_bar[barno];
 
-		ret = pci_epc_set_bar(epc, func_no, epf_bar);
+		ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 		if (ret) {
 			dev_err(dev, "%s intf: DoorBell BAR set failed\n",
 				pci_epc_interface_string(type));
@@ -1536,9 +1550,9 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 	const struct pci_epc_features *epc_features;
 	struct pci_epf_bar *epf_bar;
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epf *epf;
 	struct device *dev;
-	u8 func_no;
 
 	dev = &ntb->epf->dev;
 
@@ -1547,6 +1561,7 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 		return -ENOMEM;
 
 	epf = ntb->epf;
+	vfunc_no = epf->vfunc_no;
 	if (type == PRIMARY_INTERFACE) {
 		func_no = epf->func_no;
 		epf_bar = epf->bar;
@@ -1558,11 +1573,12 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 	ntb_epc->linkup = false;
 	ntb_epc->epc = epc;
 	ntb_epc->func_no = func_no;
+	ntb_epc->vfunc_no = vfunc_no;
 	ntb_epc->type = type;
 	ntb_epc->epf_bar = epf_bar;
 	ntb_epc->epf_ntb = ntb;
 
-	epc_features = pci_epc_get_features(epc, func_no);
+	epc_features = pci_epc_get_features(epc, func_no, vfunc_no);
 	if (!epc_features)
 		return -EINVAL;
 	ntb_epc->epc_features = epc_features;
@@ -1702,10 +1718,10 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 				      enum pci_epc_interface_type type)
 {
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct pci_epf *epf;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	ntb_epc = ntb->epc[type];
@@ -1713,6 +1729,7 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 	dev = &epf->dev;
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	ret = epf_ntb_config_sspad_bar_set(ntb->epc[type]);
 	if (ret) {
@@ -1742,7 +1759,7 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 		goto err_db_mw_bar_init;
 	}
 
-	ret = pci_epc_write_header(epc, func_no, epf->header);
+	ret = pci_epc_write_header(epc, func_no, vfunc_no, epf->header);
 	if (ret) {
 		dev_err(dev, "%s intf: Configuration header write failed\n",
 			pci_epc_interface_string(type));
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index d2708ca4bece..aaca7134b63b 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -247,8 +247,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, src_phys_addr,
+			       reg->src_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map source address\n");
 		reg->status = STATUS_SRC_ADDR_INVALID;
@@ -263,8 +263,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 		goto err_src_map_addr;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, dst_phys_addr,
+			       reg->dst_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map destination address\n");
 		reg->status = STATUS_DST_ADDR_INVALID;
@@ -291,13 +291,13 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 	pci_epf_test_print_rate("COPY", reg->size, &start, &end, use_dma);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, dst_phys_addr);
 
 err_dst_addr:
 	pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
 
 err_src_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, src_phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, src_phys_addr);
 
 err_src_addr:
 	pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
@@ -331,8 +331,8 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, phys_addr,
+			       reg->src_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map address\n");
 		reg->status = STATUS_SRC_ADDR_INVALID;
@@ -386,7 +386,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 	kfree(buf);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, phys_addr);
 
 err_addr:
 	pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
@@ -419,8 +419,8 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, phys_addr,
+			       reg->dst_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map address\n");
 		reg->status = STATUS_DST_ADDR_INVALID;
@@ -479,7 +479,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 	kfree(buf);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, phys_addr);
 
 err_addr:
 	pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
@@ -501,13 +501,16 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq_type,
 
 	switch (irq_type) {
 	case IRQ_TYPE_LEGACY:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_LEGACY, 0);
 		break;
 	case IRQ_TYPE_MSI:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSI, irq);
 		break;
 	case IRQ_TYPE_MSIX:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX, irq);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSIX, irq);
 		break;
 	default:
 		dev_err(dev, "Failed to raise IRQ, unknown type\n");
@@ -542,7 +545,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 
 	if (command & COMMAND_RAISE_LEGACY_IRQ) {
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_LEGACY, 0);
 		goto reset_handler;
 	}
 
@@ -580,22 +584,22 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 	}
 
 	if (command & COMMAND_RAISE_MSI_IRQ) {
-		count = pci_epc_get_msi(epc, epf->func_no);
+		count = pci_epc_get_msi(epc, epf->func_no, epf->vfunc_no);
 		if (reg->irq_number > count || count <= 0)
 			goto reset_handler;
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI,
-				  reg->irq_number);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSI, reg->irq_number);
 		goto reset_handler;
 	}
 
 	if (command & COMMAND_RAISE_MSIX_IRQ) {
-		count = pci_epc_get_msix(epc, epf->func_no);
+		count = pci_epc_get_msix(epc, epf->func_no, epf->vfunc_no);
 		if (reg->irq_number > count || count <= 0)
 			goto reset_handler;
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX,
-				  reg->irq_number);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSIX, reg->irq_number);
 		goto reset_handler;
 	}
 
@@ -618,7 +622,8 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 		epf_bar = &epf->bar[bar];
 
 		if (epf_test->reg[bar]) {
-			pci_epc_clear_bar(epc, epf->func_no, epf_bar);
+			pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no,
+					  epf_bar);
 			pci_epf_free_space(epf, epf_test->reg[bar], bar,
 					   PRIMARY_INTERFACE);
 		}
@@ -650,7 +655,8 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
 		if (!!(epc_features->reserved_bar & (1 << bar)))
 			continue;
 
-		ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
+		ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
+				      epf_bar);
 		if (ret) {
 			pci_epf_free_space(epf, epf_test->reg[bar], bar,
 					   PRIMARY_INTERFACE);
@@ -674,13 +680,13 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 	bool msi_capable = true;
 	int ret;
 
-	epc_features = pci_epc_get_features(epc, epf->func_no);
+	epc_features = pci_epc_get_features(epc, epf->func_no, epf->vfunc_no);
 	if (epc_features) {
 		msix_capable = epc_features->msix_capable;
 		msi_capable = epc_features->msi_capable;
 	}
 
-	ret = pci_epc_write_header(epc, epf->func_no, header);
+	ret = pci_epc_write_header(epc, epf->func_no, epf->vfunc_no, header);
 	if (ret) {
 		dev_err(dev, "Configuration header write failed\n");
 		return ret;
@@ -691,7 +697,8 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 		return ret;
 
 	if (msi_capable) {
-		ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
+		ret = pci_epc_set_msi(epc, epf->func_no, epf->vfunc_no,
+				      epf->msi_interrupts);
 		if (ret) {
 			dev_err(dev, "MSI configuration failed\n");
 			return ret;
@@ -699,7 +706,8 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 	}
 
 	if (msix_capable) {
-		ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts,
+		ret = pci_epc_set_msix(epc, epf->func_no, epf->vfunc_no,
+				       epf->msix_interrupts,
 				       epf_test->test_reg_bar,
 				       epf_test->msix_table_offset);
 		if (ret) {
@@ -832,7 +840,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 	if (WARN_ON_ONCE(!epc))
 		return -EINVAL;
 
-	epc_features = pci_epc_get_features(epc, epf->func_no);
+	epc_features = pci_epc_get_features(epc, epf->func_no, epf->vfunc_no);
 	if (!epc_features) {
 		dev_err(&epf->dev, "epc_features not implemented\n");
 		return -EOPNOTSUPP;
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 01c58ca84dcc..da2b6e792490 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -137,24 +137,29 @@ EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar);
  * @epc: the features supported by *this* EPC device will be returned
  * @func_no: the features supported by the EPC device specific to the
  *	     endpoint function with func_no will be returned
+ * @vfunc_no: the features supported by the EPC device specific to the
+ *	     virtual endpoint function with vfunc_no will be returned
  *
  * Invoke to get the features provided by the EPC which may be
  * specific to an endpoint function. Returns pci_epc_features on success
  * and NULL for any failures.
  */
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
-						    u8 func_no)
+						    u8 func_no, u8 vfunc_no)
 {
 	const struct pci_epc_features *epc_features;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return NULL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return NULL;
+
 	if (!epc->ops->get_features)
 		return NULL;
 
 	mutex_lock(&epc->lock);
-	epc_features = epc->ops->get_features(epc, func_no);
+	epc_features = epc->ops->get_features(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	return epc_features;
@@ -205,13 +210,14 @@ EXPORT_SYMBOL_GPL(pci_epc_start);
 /**
  * pci_epc_raise_irq() - interrupt the host system
  * @epc: the EPC device which has to interrupt the host
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @type: specify the type of interrupt; legacy, MSI or MSI-X
  * @interrupt_num: the MSI or MSI-X interrupt number
  *
  * Invoke to raise an legacy, MSI or MSI-X interrupt
  */
-int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		      enum pci_epc_irq_type type, u16 interrupt_num)
 {
 	int ret;
@@ -219,11 +225,14 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->raise_irq)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->raise_irq(epc, func_no, type, interrupt_num);
+	ret = epc->ops->raise_irq(epc, func_no, vfunc_no, type, interrupt_num);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -235,6 +244,7 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
  *                         MSI data
  * @epc: the EPC device which has the MSI capability
  * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: the physical address of the outbound region
  * @interrupt_num: the MSI interrupt number
  * @entry_size: Size of Outbound address region for each interrupt
@@ -250,21 +260,25 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
  * physical address (in outbound region) of the other interface to ring
  * doorbell.
  */
-int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, phys_addr_t phys_addr,
-			u8 interrupt_num, u32 entry_size, u32 *msi_data,
-			u32 *msi_addr_offset)
+int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			phys_addr_t phys_addr, u8 interrupt_num, u32 entry_size,
+			u32 *msi_data, u32 *msi_addr_offset)
 {
 	int ret;
 
 	if (IS_ERR_OR_NULL(epc))
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->map_msi_irq)
 		return -EINVAL;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->map_msi_irq(epc, func_no, phys_addr, interrupt_num,
-				    entry_size, msi_data, msi_addr_offset);
+	ret = epc->ops->map_msi_irq(epc, func_no, vfunc_no, phys_addr,
+				    interrupt_num, entry_size, msi_data,
+				    msi_addr_offset);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -274,22 +288,26 @@ EXPORT_SYMBOL_GPL(pci_epc_map_msi_irq);
 /**
  * pci_epc_get_msi() - get the number of MSI interrupt numbers allocated
  * @epc: the EPC device to which MSI interrupts was requested
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  *
  * Invoke to get the number of MSI interrupts allocated by the RC
  */
-int pci_epc_get_msi(struct pci_epc *epc, u8 func_no)
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	int interrupt;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return 0;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return 0;
+
 	if (!epc->ops->get_msi)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	interrupt = epc->ops->get_msi(epc, func_no);
+	interrupt = epc->ops->get_msi(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	if (interrupt < 0)
@@ -304,12 +322,13 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msi);
 /**
  * pci_epc_set_msi() - set the number of MSI interrupt numbers required
  * @epc: the EPC device on which MSI has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @interrupts: number of MSI interrupts required by the EPF
  *
  * Invoke to set the required number of MSI interrupts.
  */
-int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no, u8 interrupts)
 {
 	int ret;
 	u8 encode_int;
@@ -318,13 +337,16 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 	    interrupts > 32)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_msi)
 		return 0;
 
 	encode_int = order_base_2(interrupts);
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_msi(epc, func_no, encode_int);
+	ret = epc->ops->set_msi(epc, func_no, vfunc_no, encode_int);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -334,22 +356,26 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msi);
 /**
  * pci_epc_get_msix() - get the number of MSI-X interrupt numbers allocated
  * @epc: the EPC device to which MSI-X interrupts was requested
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  *
  * Invoke to get the number of MSI-X interrupts allocated by the RC
  */
-int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)
+int pci_epc_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	int interrupt;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return 0;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return 0;
+
 	if (!epc->ops->get_msix)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	interrupt = epc->ops->get_msix(epc, func_no);
+	interrupt = epc->ops->get_msix(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	if (interrupt < 0)
@@ -362,15 +388,16 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msix);
 /**
  * pci_epc_set_msix() - set the number of MSI-X interrupt numbers required
  * @epc: the EPC device on which MSI-X has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @interrupts: number of MSI-X interrupts required by the EPF
  * @bir: BAR where the MSI-X table resides
  * @offset: Offset pointing to the start of MSI-X table
  *
  * Invoke to set the required number of MSI-X interrupts.
  */
-int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-		     enum pci_barno bir, u32 offset)
+int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		     u16 interrupts, enum pci_barno bir, u32 offset)
 {
 	int ret;
 
@@ -378,11 +405,15 @@ int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
 	    interrupts < 1 || interrupts > 2048)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_msix)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_msix(epc, func_no, interrupts - 1, bir, offset);
+	ret = epc->ops->set_msix(epc, func_no, vfunc_no, interrupts - 1, bir,
+				 offset);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -392,22 +423,26 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msix);
 /**
  * pci_epc_unmap_addr() - unmap CPU address from PCI address
  * @epc: the EPC device on which address is allocated
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: physical address of the local system
  *
  * Invoke to unmap the CPU address from PCI address.
  */
-void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr)
 {
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return;
+
 	if (!epc->ops->unmap_addr)
 		return;
 
 	mutex_lock(&epc->lock);
-	epc->ops->unmap_addr(epc, func_no, phys_addr);
+	epc->ops->unmap_addr(epc, func_no, vfunc_no, phys_addr);
 	mutex_unlock(&epc->lock);
 }
 EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
@@ -415,14 +450,15 @@ EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
 /**
  * pci_epc_map_addr() - map CPU address to PCI address
  * @epc: the EPC device on which address is allocated
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: physical address of the local system
  * @pci_addr: PCI address to which the physical address should be mapped
  * @size: the size of the allocation
  *
  * Invoke to map CPU address with PCI address.
  */
-int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		     phys_addr_t phys_addr, u64 pci_addr, size_t size)
 {
 	int ret;
@@ -430,11 +466,15 @@ int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->map_addr)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->map_addr(epc, func_no, phys_addr, pci_addr, size);
+	ret = epc->ops->map_addr(epc, func_no, vfunc_no, phys_addr, pci_addr,
+				 size);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -444,12 +484,13 @@ EXPORT_SYMBOL_GPL(pci_epc_map_addr);
 /**
  * pci_epc_clear_bar() - reset the BAR
  * @epc: the EPC device for which the BAR has to be cleared
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @epf_bar: the struct epf_bar that contains the BAR information
  *
  * Invoke to reset the BAR of the endpoint device.
  */
-void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		       struct pci_epf_bar *epf_bar)
 {
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
@@ -457,11 +498,14 @@ void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
 	     epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64))
 		return;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return;
+
 	if (!epc->ops->clear_bar)
 		return;
 
 	mutex_lock(&epc->lock);
-	epc->ops->clear_bar(epc, func_no, epf_bar);
+	epc->ops->clear_bar(epc, func_no, vfunc_no, epf_bar);
 	mutex_unlock(&epc->lock);
 }
 EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
@@ -469,12 +513,13 @@ EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
 /**
  * pci_epc_set_bar() - configure BAR in order for host to assign PCI addr space
  * @epc: the EPC device on which BAR has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @epf_bar: the struct epf_bar that contains the BAR information
  *
  * Invoke to configure the BAR of the endpoint device.
  */
-int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		    struct pci_epf_bar *epf_bar)
 {
 	int ret;
@@ -489,11 +534,14 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
 	     !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64)))
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_bar)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_bar(epc, func_no, epf_bar);
+	ret = epc->ops->set_bar(epc, func_no, vfunc_no, epf_bar);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -503,7 +551,8 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
 /**
  * pci_epc_write_header() - write standard configuration header
  * @epc: the EPC device to which the configuration header should be written
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @header: standard configuration header fields
  *
  * Invoke to write the configuration header to the endpoint controller. Every
@@ -511,7 +560,7 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
  * configuration header would be written. The callback function should write
  * the header fields to this dedicated location.
  */
-int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			 struct pci_epf_header *header)
 {
 	int ret;
@@ -519,11 +568,14 @@ int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->write_header)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->write_header(epc, func_no, header);
+	ret = epc->ops->write_header(epc, func_no, vfunc_no, header);
 	mutex_unlock(&epc->lock);
 
 	return ret;
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index ae7107a3196e..d9e1a8dd1ceb 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -90,11 +90,14 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind);
  */
 int pci_epf_bind(struct pci_epf *epf)
 {
+	struct device *dev = &epf->dev;
 	struct pci_epf *epf_vf;
+	u8 func_no, vfunc_no;
+	struct pci_epc *epc;
 	int ret;
 
 	if (!epf->driver) {
-		dev_WARN(&epf->dev, "epf device not bound to driver\n");
+		dev_WARN(dev, "epf device not bound to driver\n");
 		return -EINVAL;
 	}
 
@@ -103,7 +106,50 @@ int pci_epf_bind(struct pci_epf *epf)
 
 	mutex_lock(&epf->lock);
 	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		vfunc_no = epf_vf->vfunc_no;
+
+		if (vfunc_no < 1) {
+			dev_err(dev, "Invalid virtual function number\n");
+			ret = -EINVAL;
+			goto ret;
+		}
+
+		epc = epf->epc;
+		func_no = epf->func_no;
+		if (!IS_ERR_OR_NULL(epc)) {
+			if (!epc->max_vfs) {
+				dev_err(dev, "No support for virt function\n");
+				ret = -EINVAL;
+				goto ret;
+			}
+
+			if (vfunc_no > epc->max_vfs[func_no]) {
+				dev_err(dev, "PF%d: Exceeds max vfunc number\n",
+					func_no);
+				ret = -EINVAL;
+				goto ret;
+			}
+		}
+
+		epc = epf->sec_epc;
+		func_no = epf->sec_epc_func_no;
+		if (!IS_ERR_OR_NULL(epc)) {
+			if (!epc->max_vfs) {
+				dev_err(dev, "No support for virt function\n");
+				ret = -EINVAL;
+				goto ret;
+			}
+
+			if (vfunc_no > epc->max_vfs[func_no]) {
+				dev_err(dev, "PF%d: Exceeds max vfunc number\n",
+					func_no);
+				ret = -EINVAL;
+				goto ret;
+			}
+		}
+
 		epf_vf->func_no = epf->func_no;
+		epf_vf->sec_epc_func_no = epf->sec_epc_func_no;
 		epf_vf->epc = epf->epc;
 		epf_vf->sec_epc = epf->sec_epc;
 		ret = epf_vf->driver->ops->bind(epf_vf);
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 50a649d33e68..a48778e1a4ee 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -62,31 +62,32 @@ pci_epc_interface_string(enum pci_epc_interface_type type)
  * @owner: the module owner containing the ops
  */
 struct pci_epc_ops {
-	int	(*write_header)(struct pci_epc *epc, u8 func_no,
+	int	(*write_header)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				struct pci_epf_header *hdr);
-	int	(*set_bar)(struct pci_epc *epc, u8 func_no,
+	int	(*set_bar)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			   struct pci_epf_bar *epf_bar);
-	void	(*clear_bar)(struct pci_epc *epc, u8 func_no,
+	void	(*clear_bar)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			     struct pci_epf_bar *epf_bar);
-	int	(*map_addr)(struct pci_epc *epc, u8 func_no,
+	int	(*map_addr)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			    phys_addr_t addr, u64 pci_addr, size_t size);
-	void	(*unmap_addr)(struct pci_epc *epc, u8 func_no,
+	void	(*unmap_addr)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			      phys_addr_t addr);
-	int	(*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts);
-	int	(*get_msi)(struct pci_epc *epc, u8 func_no);
-	int	(*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts,
-			    enum pci_barno, u32 offset);
-	int	(*get_msix)(struct pci_epc *epc, u8 func_no);
-	int	(*raise_irq)(struct pci_epc *epc, u8 func_no,
+	int	(*set_msi)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			   u8 interrupts);
+	int	(*get_msi)(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+	int	(*set_msix)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			    u16 interrupts, enum pci_barno, u32 offset);
+	int	(*get_msix)(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+	int	(*raise_irq)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			     enum pci_epc_irq_type type, u16 interrupt_num);
-	int	(*map_msi_irq)(struct pci_epc *epc, u8 func_no,
+	int	(*map_msi_irq)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			       phys_addr_t phys_addr, u8 interrupt_num,
 			       u32 entry_size, u32 *msi_data,
 			       u32 *msi_addr_offset);
 	int	(*start)(struct pci_epc *epc);
 	void	(*stop)(struct pci_epc *epc);
 	const struct pci_epc_features* (*get_features)(struct pci_epc *epc,
-						       u8 func_no);
+						       u8 func_no, u8 vfunc_no);
 	struct module *owner;
 };
 
@@ -128,6 +129,8 @@ struct pci_epc_mem {
  *       single window.
  * @num_windows: number of windows supported by device
  * @max_functions: max number of functions that can be configured in this EPC
+ * @max_vfs: Array indicating the maximum number of virtual functions that can
+ *   be associated with each physical function
  * @group: configfs group representing the PCI EPC device
  * @lock: mutex to protect pci_epc ops
  * @function_num_map: bitmap to manage physical function number
@@ -141,6 +144,7 @@ struct pci_epc {
 	struct pci_epc_mem		*mem;
 	unsigned int			num_windows;
 	u8				max_functions;
+	u8				*max_vfs;
 	struct config_group		*group;
 	/* mutex to protect against concurrent access of EP controller */
 	struct mutex			lock;
@@ -208,31 +212,32 @@ void pci_epc_linkup(struct pci_epc *epc);
 void pci_epc_init_notify(struct pci_epc *epc);
 void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
 			enum pci_epc_interface_type type);
-int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			 struct pci_epf_header *hdr);
-int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		    struct pci_epf_bar *epf_bar);
-void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		       struct pci_epf_bar *epf_bar);
-int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		     phys_addr_t phys_addr,
 		     u64 pci_addr, size_t size);
-void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr);
-int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
-int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);
-int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-		     enum pci_barno, u32 offset);
-int pci_epc_get_msix(struct pci_epc *epc, u8 func_no);
-int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		    u8 interrupts);
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		     u16 interrupts, enum pci_barno, u32 offset);
+int pci_epc_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr, u8 interrupt_num,
 			u32 entry_size, u32 *msi_data, u32 *msi_addr_offset);
-int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		      enum pci_epc_irq_type type, u16 interrupt_num);
 int pci_epc_start(struct pci_epc *epc);
 void pci_epc_stop(struct pci_epc *epc);
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
-						    u8 func_no);
+						    u8 func_no, u8 vfunc_no);
 enum pci_barno
 pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features);
 enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
-- 
2.17.1



From kishon at ti.com  Mon Aug  2 22:03:08 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 10:33:08 +0530
Subject: [PATCH v7 5/7] PCI: cadence: Add support to configure virtual
 functions
In-Reply-To: <20210803050310.27122-1-kishon@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
Message-ID: <20210803050310.27122-6-kishon@ti.com>

Now that support for SR-IOV is added in PCIe endpoint core, add support
to configure virtual functions in the Cadence PCIe EP driver.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Acked-by: Tom Joseph <tjoseph at cadence.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c  | 241 +++++++++++++++---
 drivers/pci/controller/cadence/pcie-cadence.h |   7 +
 2 files changed, 217 insertions(+), 31 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 912a15be8bfd..791915054ff4 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -20,7 +20,18 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie *pcie = &ep->pcie;
+	u32 reg;
+
+	if (vfn > 1) {
+		dev_dbg(&epc->dev, "Only Virtual Function #1 has deviceID\n");
+		return 0;
+	} else if (vfn == 1) {
+		reg = cap + PCI_SRIOV_VF_DID;
+		cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid);
+		return 0;
+	}
 
 	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
 	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
@@ -51,12 +62,14 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				struct pci_epf_bar *epf_bar)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie_epf *epf = &ep->epf[fn];
 	struct cdns_pcie *pcie = &ep->pcie;
 	dma_addr_t bar_phys = epf_bar->phys_addr;
 	enum pci_barno bar = epf_bar->barno;
 	int flags = epf_bar->flags;
 	u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
+	u32 first_vf_offset, stride;
 	u64 sz;
 
 	/* BAR size is 2^(aperture + 7) */
@@ -92,26 +105,50 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 
 	addr0 = lower_32_bits(bar_phys);
 	addr1 = upper_32_bits(bar_phys);
+
+	if (vfn == 1) {
+		/* All virtual functions use the same BAR config */
+		if (bar < BAR_4) {
+			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn);
+			b = bar;
+		} else {
+			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn);
+			b = bar - BAR_4;
+		}
+	} else if (vfn == 0) {
+		/* BAR configuration for physical function */
+		if (bar < BAR_4) {
+			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
+			b = bar;
+		} else {
+			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
+			b = bar - BAR_4;
+		}
+	}
+
+	if (vfn == 0 || vfn == 1) {
+		cfg = cdns_pcie_readl(pcie, reg);
+		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+		cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+			CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+		cdns_pcie_writel(pcie, reg, cfg);
+	}
+
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+		epf = &epf->epf[vfn - 1];
+	}
+
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
 			 addr0);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
 			 addr1);
 
-	if (bar < BAR_4) {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
-		b = bar;
-	} else {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
-		b = bar - BAR_4;
-	}
-
-	cfg = cdns_pcie_readl(pcie, reg);
-	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
-		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
-	cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
-		CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
-	cdns_pcie_writel(pcie, reg, cfg);
-
 	epf->epf_bar[bar] = epf_bar;
 
 	return 0;
@@ -121,25 +158,48 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				   struct pci_epf_bar *epf_bar)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie_epf *epf = &ep->epf[fn];
 	struct cdns_pcie *pcie = &ep->pcie;
 	enum pci_barno bar = epf_bar->barno;
+	u32 first_vf_offset, stride;
 	u32 reg, cfg, b, ctrl;
 
-	if (bar < BAR_4) {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
-		b = bar;
-	} else {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
-		b = bar - BAR_4;
+	if (vfn == 1) {
+		if (bar < BAR_4) {
+			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn);
+			b = bar;
+		} else {
+			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn);
+			b = bar - BAR_4;
+		}
+	} else if (vfn == 0) {
+		if (bar < BAR_4) {
+			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
+			b = bar;
+		} else {
+			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
+			b = bar - BAR_4;
+		}
 	}
 
-	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
-	cfg = cdns_pcie_readl(pcie, reg);
-	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
-		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
-	cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
-	cdns_pcie_writel(pcie, reg, cfg);
+	if (vfn == 0 || vfn == 1) {
+		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
+		cfg = cdns_pcie_readl(pcie, reg);
+		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+		cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
+		cdns_pcie_writel(pcie, reg, cfg);
+	}
+
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+		epf = &epf->epf[vfn - 1];
+	}
 
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0);
@@ -152,8 +212,18 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
+	u32 first_vf_offset, stride;
 	u32 r;
 
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+	}
+
 	r = find_first_zero_bit(&ep->ob_region_map,
 				sizeof(ep->ob_region_map) * BITS_PER_LONG);
 	if (r >= ep->max_regions - 1) {
@@ -193,9 +263,19 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
+	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	u32 first_vf_offset, stride;
 	u16 flags;
 
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+	}
+
 	/*
 	 * Set the Multiple Message Capable bitfield into the Message Control
 	 * register.
@@ -213,9 +293,19 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
+	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	u32 first_vf_offset, stride;
 	u16 flags, mme;
 
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+	}
+
 	/* Validate that the MSI feature is actually enabled. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
 	if (!(flags & PCI_MSI_FLAGS_ENABLE))
@@ -232,11 +322,21 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 
 static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
+	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
+	u32 first_vf_offset, stride;
 	u32 val, reg;
 
+	if (vfunc_no > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, func_no, sriov_cap
+							+ PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, func_no, sriov_cap +
+					       PCI_SRIOV_VF_STRIDE);
+		func_no = func_no + first_vf_offset + ((vfunc_no - 1) * stride);
+	}
+
 	reg = cap + PCI_MSIX_FLAGS;
 	val = cdns_pcie_ep_fn_readw(pcie, func_no, reg);
 	if (!(val & PCI_MSIX_FLAGS_ENABLE))
@@ -251,11 +351,21 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
 				 u16 interrupts, enum pci_barno bir,
 				 u32 offset)
 {
+	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
+	u32 first_vf_offset, stride;
 	u32 val, reg;
 
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+	}
+
 	reg = cap + PCI_MSIX_FLAGS;
 	val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
 	val &= ~PCI_MSIX_FLAGS_QSIZE;
@@ -275,8 +385,8 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
 	return 0;
 }
 
-static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
-				     u8 intx, bool is_asserted)
+static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
+				     bool is_asserted)
 {
 	struct cdns_pcie *pcie = &ep->pcie;
 	unsigned long flags;
@@ -339,11 +449,21 @@ static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				     u8 interrupt_num)
 {
+	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie *pcie = &ep->pcie;
 	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
 	u16 flags, mme, data, data_mask;
 	u8 msi_count;
 	u64 pci_addr, pci_addr_mask = 0xff;
+	u32 first_vf_offset, stride;
+
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+	}
 
 	/* Check whether the MSI feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
@@ -389,15 +509,25 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				    u32 entry_size, u32 *msi_data,
 				    u32 *msi_addr_offset)
 {
+	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
 	struct cdns_pcie *pcie = &ep->pcie;
 	u64 pci_addr, pci_addr_mask = 0xff;
 	u16 flags, mme, data, data_mask;
+	u32 first_vf_offset, stride;
 	u8 msi_count;
 	int ret;
 	int i;
 
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+	}
+
 	/* Check whether the MSI feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
 	if (!(flags & PCI_MSI_FLAGS_ENABLE))
@@ -438,16 +568,29 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				      u16 interrupt_num)
 {
+	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
 	u32 tbl_offset, msg_data, reg;
 	struct cdns_pcie *pcie = &ep->pcie;
 	struct pci_epf_msix_tbl *msix_tbl;
+	u32 first_vf_offset, stride;
 	struct cdns_pcie_epf *epf;
 	u64 pci_addr_mask = 0xff;
 	u64 msg_addr;
 	u16 flags;
 	u8 bir;
 
+	epf = &ep->epf[fn];
+
+	if (vfn > 0) {
+		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+							PCI_SRIOV_VF_OFFSET);
+		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
+					       PCI_SRIOV_VF_STRIDE);
+		fn = fn + first_vf_offset + ((vfn - 1) * stride);
+		epf = &epf->epf[vfn - 1];
+	}
+
 	/* Check whether the MSI-X feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
 	if (!(flags & PCI_MSIX_FLAGS_ENABLE))
@@ -458,7 +601,6 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 	bir = tbl_offset & PCI_MSIX_TABLE_BIR;
 	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
 
-	epf = &ep->epf[fn];
 	msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
 	msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
 	msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
@@ -485,9 +627,15 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  u16 interrupt_num)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	struct device *dev = pcie->dev;
 
 	switch (type) {
 	case PCI_EPC_IRQ_LEGACY:
+		if (vfn > 0) {
+			dev_err(dev, "Cannot raise legacy interrupts for VF\n");
+			return -EINVAL;
+		}
 		return cdns_pcie_ep_send_legacy_irq(ep, fn, vfn, 0);
 
 	case PCI_EPC_IRQ_MSI:
@@ -525,6 +673,13 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
 	return 0;
 }
 
+static const struct pci_epc_features cdns_pcie_epc_vf_features = {
+	.linkup_notifier = false,
+	.msi_capable = true,
+	.msix_capable = true,
+	.align = 65536,
+};
+
 static const struct pci_epc_features cdns_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
@@ -535,7 +690,10 @@ static const struct pci_epc_features cdns_pcie_epc_features = {
 static const struct pci_epc_features*
 cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
-	return &cdns_pcie_epc_features;
+	if (!vfunc_no)
+		return &cdns_pcie_epc_features;
+
+	return &cdns_pcie_epc_vf_features;
 }
 
 static const struct pci_epc_ops cdns_pcie_epc_ops = {
@@ -561,9 +719,11 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *np = dev->of_node;
 	struct cdns_pcie *pcie = &ep->pcie;
+	struct cdns_pcie_epf *epf;
 	struct resource *res;
 	struct pci_epc *epc;
 	int ret;
+	int i;
 
 	pcie->is_rc = false;
 
@@ -608,6 +768,25 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	if (!ep->epf)
 		return -ENOMEM;
 
+	epc->max_vfs = devm_kcalloc(dev, epc->max_functions,
+				    sizeof(*epc->max_vfs), GFP_KERNEL);
+	if (!epc->max_vfs)
+		return -ENOMEM;
+
+	ret = of_property_read_u8_array(np, "max-virtual-functions",
+					epc->max_vfs, epc->max_functions);
+	if (ret == 0) {
+		for (i = 0; i < epc->max_functions; i++) {
+			epf = &ep->epf[i];
+			if (epc->max_vfs[i] == 0)
+				continue;
+			epf->epf = devm_kcalloc(dev, epc->max_vfs[i],
+						sizeof(*ep->epf), GFP_KERNEL);
+			if (!epf->epf)
+				return -ENOMEM;
+		}
+	}
+
 	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
 			       resource_size(pcie->mem_res), PAGE_SIZE);
 	if (ret < 0) {
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 30db2d68c17a..927b49e42997 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -50,6 +50,10 @@
 	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
 #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
 	(CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0280 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0284 + (fn) * 0x0008)
 #define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
 	(GENMASK(4, 0) << ((b) * 8))
 #define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
@@ -114,6 +118,7 @@
 
 #define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET	0x90
 #define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET	0xb0
+#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET	0x200
 
 /*
  * Root Port Registers (PCI configuration space for the root port function)
@@ -308,9 +313,11 @@ struct cdns_pcie_rc {
 
 /**
  * struct cdns_pcie_epf - Structure to hold info about endpoint function
+ * @epf: Info about virtual functions attached to the physical function
  * @epf_bar: reference to the pci_epf_bar for the six Base Address Registers
  */
 struct cdns_pcie_epf {
+	struct cdns_pcie_epf *epf;
 	struct pci_epf_bar *epf_bar[PCI_STD_NUM_BARS];
 };
 
-- 
2.17.1



From kishon at ti.com  Mon Aug  2 22:03:09 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 10:33:09 +0530
Subject: [PATCH v7 6/7] misc: pci_endpoint_test: Populate sriov_configure ops
 to configure SR-IOV device
In-Reply-To: <20210803050310.27122-1-kishon@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
Message-ID: <20210803050310.27122-7-kishon@ti.com>

Populate sriov_configure ops with pci_sriov_configure_simple to
configure SR-IOV device.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/misc/pci_endpoint_test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 1b2868ca4f2a..c7ee34013485 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -978,6 +978,7 @@ static struct pci_driver pci_endpoint_test_driver = {
 	.id_table	= pci_endpoint_test_tbl,
 	.probe		= pci_endpoint_test_probe,
 	.remove		= pci_endpoint_test_remove,
+	.sriov_configure = pci_sriov_configure_simple,
 };
 module_pci_driver(pci_endpoint_test_driver);
 
-- 
2.17.1



From kishon at ti.com  Mon Aug  2 22:03:10 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 10:33:10 +0530
Subject: [PATCH v7 7/7] Documentation: PCI: endpoint/pci-endpoint-cfs: Guide
 to use SR-IOV
In-Reply-To: <20210803050310.27122-1-kishon@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
Message-ID: <20210803050310.27122-8-kishon@ti.com>

Add Documentation to help users use PCI endpoint to create virtual
functions using configfs. An endpoint function is designated as a
virtual endpoint function device when it is linked to a physical
endpoint function device (instead of a endpoint controller).

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 Documentation/PCI/endpoint/pci-endpoint-cfs.rst | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/PCI/endpoint/pci-endpoint-cfs.rst b/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
index db609b97ad58..fb73345cfb8a 100644
--- a/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
+++ b/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
@@ -43,6 +43,7 @@ entries corresponding to EPF driver will be created by the EPF core.
 		.. <EPF Driver1>/
 			... <EPF Device 11>/
 			... <EPF Device 21>/
+			... <EPF Device 31>/
 		.. <EPF Driver2>/
 			... <EPF Device 12>/
 			... <EPF Device 22>/
@@ -68,6 +69,7 @@ created)
 				... subsys_vendor_id
 				... subsys_id
 				... interrupt_pin
+			        ... <Symlink EPF Device 31>/
                                 ... primary/
 			                ... <Symlink EPC Device1>/
                                 ... secondary/
@@ -79,6 +81,13 @@ interface should be added in 'primary' directory and symlink of endpoint
 controller connected to secondary interface should be added in 'secondary'
 directory.
 
+The <EPF Device> directory can have a list of symbolic links
+(<Symlink EPF Device 31>) to other <EPF Device>. These symbolic links should
+be created by the user to represent the virtual functions that are bound to
+the physical function. In the above directory structure <EPF Device 11> is a
+physical function and <EPF Device 31> is a virtual function. An EPF device once
+it's linked to another EPF device, cannot be linked to a EPC device.
+
 EPC Device
 ==========
 
@@ -98,7 +107,8 @@ entries corresponding to EPC device will be created by the EPC core.
 
 The <EPC Device> directory will have a list of symbolic links to
 <EPF Device>. These symbolic links should be created by the user to
-represent the functions present in the endpoint device.
+represent the functions present in the endpoint device. Only <EPF Device>
+that represents a physical function can be linked to a EPC device.
 
 The <EPC Device> directory will also have a *start* field. Once
 "1" is written to this field, the endpoint device will be ready to
-- 
2.17.1



From viresh.kumar at linaro.org  Mon Aug  2 22:05:38 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 3 Aug 2021 10:35:38 +0530
Subject: [PATCH v13 1/2] dt-bindings: cpufreq: add bindings for MediaTek
 cpufreq HW
In-Reply-To: <1627574891-26514-2-git-send-email-hector.yuan@mediatek.com>
References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com>
 <1627574891-26514-2-git-send-email-hector.yuan@mediatek.com>
Message-ID: <20210803050538.g6aj2zsep735ywqv@vireshk-i7>

On 30-07-21, 00:08, Hector Yuan wrote:
> From: "Hector.Yuan" <hector.yuan at mediatek.com>
> 
> Add devicetree bindings for MediaTek HW driver.
> 
> Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
> ---
>  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml      |   70 ++++++++++++++++++++
>  1 file changed, 70 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> 
> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> new file mode 100644
> index 0000000..6bb2c97
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> @@ -0,0 +1,70 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek's CPUFREQ Bindings
> +
> +maintainers:
> +  - Hector Yuan <hector.yuan at mediatek.com>
> +
> +description:
> +  CPUFREQ HW is a hardware engine used by MediaTek
> +  SoCs to manage frequency in hardware. It is capable of controlling frequency
> +  for multiple clusters.
> +

Should this somewhere have a reference to
Documentation/devicetree/bindings/dvfs/performance-domain.yaml ?

> +properties:
> +  compatible:
> +    const: mediatek,cpufreq-hw
> +
> +  reg:
> +    minItems: 1
> +    maxItems: 2
> +    description: |
> +      Addresses and sizes for the memory of the
> +      HW bases in each frequency domain.
> +
> +  "#performance-domain-cells":
> +    description:
> +      Number of cells in a performance domain specifier. Typically 1 for nodes
> +      providing multiple performance domains (e.g. performance controllers),
> +      but can be any value as specified by device tree binding documentation
> +      of particular provider.

You say this can have any value, 1 or more, but then ...

> +    const: 1

You fix it to 1 ?

Perhaps you should add a reference to the performance-domain.yaml here
as well, and say const 1 here and describe how the parameter is going
to be used. You should only explain it in respect to your SoC.

But I am not that good with Yaml stuff, I will let Rob correct me here
:)

-- 
viresh


From hsinyi at chromium.org  Mon Aug  2 22:13:16 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Tue,  3 Aug 2021 13:13:16 +0800
Subject: [PATCH v3 1/3] arm: dts: mt8135: Move pinfunc to
 include/dt-bindings/pinctrl
Message-ID: <20210803051318.2570994-1-hsinyi@chromium.org>

Move mt8135-pinfunc.h into include/dt-bindings/pinctrl so that we can
include it in yaml examples.

Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 arch/arm/boot/dts/mt8135.dtsi                                   | 2 +-
 .../boot/dts => include/dt-bindings/pinctrl}/mt8135-pinfunc.h   | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename {arch/arm/boot/dts => include/dt-bindings/pinctrl}/mt8135-pinfunc.h (100%)

diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi
index 0e4e835026db0..a031b36363187 100644
--- a/arch/arm/boot/dts/mt8135.dtsi
+++ b/arch/arm/boot/dts/mt8135.dtsi
@@ -9,7 +9,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/mt8135-resets.h>
-#include "mt8135-pinfunc.h"
+#include <dt-bindings/pinctrl/mt8135-pinfunc.h>
 
 / {
 	#address-cells = <2>;
diff --git a/arch/arm/boot/dts/mt8135-pinfunc.h b/include/dt-bindings/pinctrl/mt8135-pinfunc.h
similarity index 100%
rename from arch/arm/boot/dts/mt8135-pinfunc.h
rename to include/dt-bindings/pinctrl/mt8135-pinfunc.h
-- 
2.32.0.554.ge1b32706d8-goog



From hsinyi at chromium.org  Mon Aug  2 22:13:17 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Tue,  3 Aug 2021 13:13:17 +0800
Subject: [PATCH v3 2/3] arm: dts: mt8183: Move pinfunc to
 include/dt-bindings/pinctrl
In-Reply-To: <20210803051318.2570994-1-hsinyi@chromium.org>
References: <20210803051318.2570994-1-hsinyi@chromium.org>
Message-ID: <20210803051318.2570994-2-hsinyi@chromium.org>

Move mt8183-pinfunc.h into include/dt-bindings/pinctrl so that we can
include it in yaml examples.

Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi                        | 2 +-
 .../mediatek => include/dt-bindings/pinctrl}/mt8183-pinfunc.h   | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename {arch/arm64/boot/dts/mediatek => include/dt-bindings/pinctrl}/mt8183-pinfunc.h (100%)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index f90df6439c088..1933045da95de 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -14,7 +14,7 @@
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/thermal/thermal.h>
-#include "mt8183-pinfunc.h"
+#include <dt-bindings/pinctrl/mt8183-pinfunc.h>
 
 / {
 	compatible = "mediatek,mt8183";
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h b/include/dt-bindings/pinctrl/mt8183-pinfunc.h
similarity index 100%
rename from arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h
rename to include/dt-bindings/pinctrl/mt8183-pinfunc.h
-- 
2.32.0.554.ge1b32706d8-goog



From hsinyi at chromium.org  Mon Aug  2 22:13:19 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Tue,  3 Aug 2021 13:13:19 +0800
Subject: [PATCH v3 3/3] dt-bindings: mediatek: convert pinctrl to yaml
In-Reply-To: <20210803051318.2570994-1-hsinyi@chromium.org>
References: <20210803051318.2570994-1-hsinyi@chromium.org>
Message-ID: <20210803051318.2570994-3-hsinyi@chromium.org>

Convert mt65xx, mt6796, mt7622, mt8183 bindings to yaml.

Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
v2->v3:
fix comments in v2.
---
 .../pinctrl/mediatek,mt65xx-pinctrl.yaml      | 206 ++++++++
 .../pinctrl/mediatek,mt6797-pinctrl.yaml      | 173 +++++++
 .../pinctrl/mediatek,mt7622-pinctrl.yaml      | 373 +++++++++++++
 .../pinctrl/mediatek,mt8183-pinctrl.yaml      | 228 ++++++++
 .../bindings/pinctrl/pinctrl-mt65xx.txt       | 156 ------
 .../bindings/pinctrl/pinctrl-mt6797.txt       |  83 ---
 .../bindings/pinctrl/pinctrl-mt7622.txt       | 490 ------------------
 .../bindings/pinctrl/pinctrl-mt8183.txt       | 132 -----
 8 files changed, 980 insertions(+), 861 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
new file mode 100644
index 0000000000000..b977fbb8cb5e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
@@ -0,0 +1,206 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt65xx-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT65xx Pin Controller Device Tree Bindings
+
+maintainers:
+  - Andy Teng <andy.teng at mediatek.com>
+
+description: |+
+  The Mediatek's Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt2701-pinctrl
+      - mediatek,mt2712-pinctrl
+      - mediatek,mt6397-pinctrl
+      - mediatek,mt7623-pinctrl
+      - mediatek,mt8127-pinctrl
+      - mediatek,mt8135-pinctrl
+      - mediatek,mt8167-pinctrl
+      - mediatek,mt8173-pinctrl
+      - mediatek,mt8516-pinctrl
+
+  reg:
+    maxItems: 1
+
+  pins-are-numbered:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: |
+      Specify the subnodes are using numbered pinmux to specify pins.
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO
+      binding is used, the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+
+  mediatek,pctl-regmap:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 2
+    description: |
+      Should be phandles of the syscfg node.
+
+  interrupt-controller: true
+
+  interrupts:
+    minItems: 1
+    maxItems: 3
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - pins-are-numbered
+  - gpio-controller
+  - "#gpio-cells"
+
+patternProperties:
+  '-[0-9]+$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      'pins':
+        type: object
+        additionalProperties: false
+        description: |
+          A pinctrl node should contain at least one subnodes representing the
+          pinctrl groups available on the machine. Each subnode will list the
+          pins it needs, and how they should be configured, with regard to muxer
+          configuration, pullups, drive strength, input enable/disable and input
+          schmitt.
+        $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+        properties:
+          pinmux:
+            description:
+              integer array, represents gpio pin number and mux setting.
+              Supported pin number and mux varies for different SoCs, and are
+              defined as macros in <soc>-pinfunc.h directly.
+
+          bias-disable: true
+
+          bias-pull-up:
+            description: |
+              Besides generic pinconfig options, it can be used as the pull up
+              settings for 2 pull resistors, R0 and R1. User can configure those
+              special pins. Some macros have been defined for this usage, such
+              as MTK_PUPD_SET_R1R0_00. See dt-bindings/pinctrl/mt65xx.h for
+              valid arguments.
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          input-disable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            description: |
+              Can support some arguments, such as MTK_DRIVE_4mA, MTK_DRIVE_6mA,
+              etc. See dt-bindings/pinctrl/mt65xx.h for valid arguments.
+
+        required:
+          - pinmux
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt8135-pinfunc.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        syscfg_pctl_a: syscfg-pctl-a at 10005000 {
+          compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon";
+          reg = <0 0x10005000 0 0x1000>;
+        };
+
+        syscfg_pctl_b: syscfg-pctl-b at 1020c020 {
+          compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon";
+          reg = <0 0x1020C020 0 0x1000>;
+        };
+
+        pinctrl at 1c20800 {
+          compatible = "mediatek,mt8135-pinctrl";
+          reg = <0 0x1000B000 0 0x1000>;
+          mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>;
+          pins-are-numbered;
+          gpio-controller;
+          #gpio-cells = <2>;
+          interrupt-controller;
+          #interrupt-cells = <2>;
+          interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+              <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+              <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+
+          i2c0_pins_a: i2c0-0 {
+            pins1 {
+              pinmux = <MT8135_PIN_100_SDA0__FUNC_SDA0>,
+                <MT8135_PIN_101_SCL0__FUNC_SCL0>;
+              bias-disable;
+            };
+          };
+
+          i2c1_pins_a: i2c1-0 {
+            pins {
+              pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
+                <MT8135_PIN_196_SCL1__FUNC_SCL1>;
+              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+            };
+          };
+
+          i2c2_pins_a: i2c2-0 {
+            pins1 {
+              pinmux = <MT8135_PIN_193_SDA2__FUNC_SDA2>;
+              bias-pull-down;
+            };
+
+            pins2 {
+              pinmux = <MT8135_PIN_49_WATCHDOG__FUNC_GPIO49>;
+              bias-pull-up;
+            };
+          };
+
+          i2c3_pins_a: i2c3-0 {
+            pins1 {
+              pinmux = <MT8135_PIN_40_DAC_CLK__FUNC_GPIO40>,
+                <MT8135_PIN_41_DAC_WS__FUNC_GPIO41>;
+              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+            };
+
+            pins2 {
+              pinmux = <MT8135_PIN_35_SCL3__FUNC_SCL3>,
+                <MT8135_PIN_36_SDA3__FUNC_SDA3>;
+              output-low;
+              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+            };
+
+            pins3 {
+              pinmux = <MT8135_PIN_57_JTCK__FUNC_GPIO57>,
+                <MT8135_PIN_60_JTDI__FUNC_JTDI>;
+              drive-strength = <32>;
+            };
+          };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
new file mode 100644
index 0000000000000..17b4a33bb23b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
@@ -0,0 +1,173 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt6797-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT6797 Pin Controller Device Tree Bindings
+
+maintainers:
+  - Andy Teng <andy.teng at mediatek.com>
+
+description: |+
+  The MediaTek's MT6797 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    const: mediatek,mt6797-pinctrl
+
+  reg:
+    minItems: 5
+    maxItems: 5
+
+  reg-names:
+    items:
+      - const: gpio
+      - const: iocfgl
+      - const: iocfgb
+      - const: iocfgr
+      - const: iocfgt
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO
+      binding is used, the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - gpio-controller
+  - "#gpio-cells"
+
+patternProperties:
+  '-[0-9]+$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      'pins':
+        type: object
+        additionalProperties: false
+        description: |
+          A pinctrl node should contain at least one subnodes representing the
+          pinctrl groups available on the machine. Each subnode will list the
+          pins it needs, and how they should be configured, with regard to muxer
+          configuration, pullups, drive strength, input enable/disable and input
+          schmitt.
+        $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+        properties:
+          pinmux:
+            description:
+              integer array, represents gpio pin number and mux setting.
+              Supported pin number and mux varies for different SoCs, and are
+              defined as macros in <soc>-pinfunc.h directly.
+
+          bias-disable: true
+
+          bias-pull-up: true
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          input-disable: true
+
+          output-enable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [2, 4, 8, 12, 16]
+
+          slew-rate:
+            enum: [0, 1]
+
+          mediatek,pull-up-adv:
+            description: |
+              Pull up setings for 2 pull resistors, R0 and R1. User can
+              configure those special pins. Valid arguments are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,pull-down-adv:
+            description: |
+              Pull down settings for 2 pull resistors, R0 and R1. User can
+              configure those special pins. Valid arguments are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,tdsel:
+            description: |
+              An integer describing the steps for output level shifter duty
+              cycle when asserted (high pulse width adjustment). Valid arguments
+              are from 0 to 15.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+          mediatek,rdsel:
+            description: |
+              An integer describing the steps for input level shifter duty cycle
+              when asserted (high pulse width adjustment). Valid arguments are
+              from 0 to 63.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+        required:
+          - pinmux
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt6797-pinfunc.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pio: pinctrl at 10005000 {
+            compatible = "mediatek,mt6797-pinctrl";
+            reg = <0 0x10005000 0 0x1000>,
+                  <0 0x10002000 0 0x400>,
+                  <0 0x10002400 0 0x400>,
+                  <0 0x10002800 0 0x400>,
+                  <0 0x10002C00 0 0x400>;
+            reg-names = "gpio", "iocfgl", "iocfgb", "iocfgr", "iocfgt";
+            gpio-controller;
+            #gpio-cells = <2>;
+
+            uart_pins_a: uart-0 {
+                pins1 {
+                    pinmux = <MT6797_GPIO232__FUNC_URXD1>,
+                            <MT6797_GPIO233__FUNC_UTXD1>;
+                };
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
new file mode 100644
index 0000000000000..94c0352e206a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
@@ -0,0 +1,373 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7622-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT7622 Pin Controller Device Tree Bindings
+
+maintainers:
+  - Andy Teng <andy.teng at mediatek.com>
+
+description: |+
+  The MediaTek's MT7622 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-pinctrl
+      - mediatek,mt7629-pinctrl
+
+  reg:
+    maxItems: 1
+
+  reg-names:
+    items:
+      - const: eint
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO
+      binding is used, the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - gpio-controller
+  - "#gpio-cells"
+
+if:
+  required:
+    - interrupt-controller
+then:
+  required:
+    - reg-names
+    - interrupts
+    - "#interrupt-cells"
+
+patternProperties:
+  '-[0-9]+$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      'mux':
+        type: object
+        additionalProperties: false
+        description: |
+          pinmux configuration nodes.
+        $ref: "/schemas/pinctrl/pinmux-node.yaml"
+        properties:
+          function:
+            description: |
+              A string containing the name of the function to mux to the group.
+            enum: [emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm, sd,
+                   spi, tdm, uart, watchdog, wifi]
+
+          groups:
+            description: |
+              An array of strings. Each string contains the name of a group.
+
+          drive-strength:
+            enum: [4, 8, 12, 16]
+
+        required:
+          - groups
+          - function
+
+        allOf:
+          - if:
+              properties:
+                function:
+                  const: emmc
+            then:
+              properties:
+                groups:
+                  enum: [emmc, emmc_rst]
+          - if:
+              properties:
+                function:
+                  const: eth
+            then:
+              properties:
+                groups:
+                  enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
+                         rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
+          - if:
+              properties:
+                function:
+                  const: i2c
+            then:
+              properties:
+                groups:
+                  enum: [i2c0, i2c_0, i2c_1, i2c1_0, i2c1_1, i2c1_2, i2c2_0,
+                         i2c2_1, i2c2_2]
+          - if:
+              properties:
+                function:
+                  const: i2s
+            then:
+              properties:
+                groups:
+                  enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
+                         i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
+                         i2s1_out_data, i2s2_out_data, i2s3_out_data,
+                         i2s4_out_data]
+          - if:
+              properties:
+                function:
+                  const: ir
+            then:
+              properties:
+                groups:
+                  enum: [ir_0_tx, ir_1_tx, ir_2_tx, ir_0_rx, ir_1_rx, ir_2_rx]
+          - if:
+              properties:
+                function:
+                  const: led
+            then:
+              properties:
+                groups:
+                  enum: [ephy_leds, ephy0_led, ephy1_led, ephy2_led, ephy3_led,
+                         ephy4_led, wled, wf2g_led, wf5g_led]
+          - if:
+              properties:
+                function:
+                  const: flash
+            then:
+              properties:
+                groups:
+                  enum: [par_nand, snfi, spi_nor]
+          - if:
+              properties:
+                function:
+                  const: pcie
+            then:
+              properties:
+                groups:
+                  enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
+                         pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
+                         pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
+                         pcie_wake, pcie_clkreq]
+          - if:
+              properties:
+                function:
+                  const: pmic
+            then:
+              properties:
+                groups:
+                  enum: [pmic_bus]
+          - if:
+              properties:
+                function:
+                  const: pwm
+            then:
+              properties:
+                groups:
+                  enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
+                         pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
+                         pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
+                         pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3,
+                         pwm_ch7_0, pwm_0, pwm_1]
+          - if:
+              properties:
+                function:
+                  const: sd
+            then:
+              properties:
+                groups:
+                  enum: [sd_0, sd_1]
+          - if:
+              properties:
+                function:
+                  const: spi
+            then:
+              properties:
+                groups:
+                  enum: [spic0_0, spic0_1, spic1_0, spic1_1, spic2_0_wp_hold,
+                         spic2_0, spi_0, spi_1, spi_wp, spi_hold]
+          - if:
+              properties:
+                function:
+                  const: tdm
+            then:
+              properties:
+                groups:
+                  enum: [tdm_0_out_mclk_bclk_ws, tdm_0_in_mclk_bclk_ws,
+                         tdm_0_out_data, tdm_0_in_data, tdm_1_out_mclk_bclk_ws,
+                         tdm_1_in_mclk_bclk_ws, tdm_1_out_data, tdm_1_in_data]
+          - if:
+              properties:
+                function:
+                  const: uart
+            then:
+              properties:
+                groups:
+                  enum: [uart0_0_tx_rx, uart1_0_tx_rx, uart1_0_rts_cts,
+                         uart1_1_tx_rx, uart1_1_rts_cts, uart2_0_tx_rx,
+                         uart2_0_rts_cts, uart2_1_tx_rx, uart2_1_rts_cts,
+                         uart2_2_tx_rx, uart2_2_rts_cts, uart2_3_tx_rx,
+                         uart3_0_tx_rx, uart3_1_tx_rx, uart3_1_rts_cts,
+                         uart4_0_tx_rx, uart4_1_tx_rx, uart4_1_rts_cts,
+                         uart4_2_tx_rx, uart4_2_rts_cts, uart0_txd_rxd,
+                         uart1_0_txd_rxd, uart1_0_cts_rts, uart1_1_txd_rxd,
+                         uart1_1_cts_rts, uart2_0_txd_rxd, uart2_0_cts_rts,
+                         uart2_1_txd_rxd, uart2_1_cts_rts]
+          - if:
+              properties:
+                function:
+                  const: watchdog
+            then:
+              properties:
+                groups:
+                  enum: [watchdog]
+          - if:
+              properties:
+                function:
+                  const: wifi
+            then:
+              properties:
+                groups:
+                  enum: [wf0_2g, wf0_5g]
+
+      'conf':
+        type: object
+        additionalProperties: false
+        description: |
+          pinconf configuration nodes.
+        $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+        properties:
+          groups:
+            description: |
+              An array of strings. Each string contains the name of a group.
+              Valid values are the same as the pinmux node.
+
+          pins:
+            description: |
+              An array of strings. Each string contains the name of a pin.
+            enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
+                   RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
+                   I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
+                   I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1,
+                   G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2,
+                   G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6,
+                   NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0,
+                   MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1,
+                   MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2,
+                   MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3,
+                   MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL,
+                   PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS,
+                   GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N,
+                   PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2,
+                   AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4,
+                   PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA,
+                   WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4,
+                   WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG,
+                   EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS,
+                   EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N,
+                   WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD,
+                   UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD,
+                   UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N,
+                   PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5,
+                   GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK,
+                   TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3,
+                   WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6]
+
+          bias-disable: true
+
+          bias-pull-up: true
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          input-disable: true
+
+          output-enable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [4, 8, 12, 16]
+
+          slew-rate:
+            enum: [0, 1]
+
+          mediatek,tdsel:
+            description: |
+              An integer describing the steps for output level shifter duty
+              cycle when asserted (high pulse width adjustment). Valid arguments
+              are from 0 to 15.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+          mediatek,rdsel:
+            description: |
+              An integer describing the steps for input level shifter duty cycle
+              when asserted (high pulse width adjustment). Valid arguments are
+              from 0 to 63.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+        required:
+          - pins
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pio: pinctrl at 10211000 {
+          compatible = "mediatek,mt7622-pinctrl";
+          reg = <0 0x10211000 0 0x1000>;
+          gpio-controller;
+          #gpio-cells = <2>;
+
+          pinctrl_eth_default: eth-0 {
+            mux-mdio {
+              groups = "mdc_mdio";
+              function = "eth";
+              drive-strength = <12>;
+            };
+
+            mux-gmac2 {
+              groups = "rgmii_via_gmac2";
+              function = "eth";
+              drive-strength = <12>;
+            };
+
+            mux-esw {
+              groups = "esw";
+              function = "eth";
+              drive-strength = <8>;
+            };
+
+            conf-mdio {
+              pins = "MDC";
+              bias-pull-up;
+            };
+          };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
new file mode 100644
index 0000000000000..2d5b646a6d3bd
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
@@ -0,0 +1,228 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt8183-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT8183 Pin Controller Device Tree Bindings
+
+maintainers:
+  - Andy Teng <andy.teng at mediatek.com>
+
+description: |+
+  The MediaTek's MT8183 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    const: mediatek,mt8183-pinctrl
+
+  reg:
+    minItems: 10
+    maxItems: 10
+
+  reg-names:
+    items:
+      - const: iocfg0
+      - const: iocfg1
+      - const: iocfg2
+      - const: iocfg3
+      - const: iocfg4
+      - const: iocfg5
+      - const: iocfg6
+      - const: iocfg7
+      - const: iocfg8
+      - const: eint
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO
+      binding is used, the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+
+  gpio-ranges:
+    minItems: 1
+    maxItems: 5
+    description: |
+      GPIO valid number range.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - gpio-controller
+  - "#gpio-cells"
+  - gpio-ranges
+
+patternProperties:
+  '-[0-9]+$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      'pins':
+        type: object
+        additionalProperties: false
+        description: |
+          A pinctrl node should contain at least one subnodes representing the
+          pinctrl groups available on the machine. Each subnode will list the
+          pins it needs, and how they should be configured, with regard to muxer
+          configuration, pullups, drive strength, input enable/disable and input
+          schmitt.
+        $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+        properties:
+          pinmux:
+            description:
+              integer array, represents gpio pin number and mux setting.
+              Supported pin number and mux varies for different SoCs, and are
+              defined as macros in <soc>-pinfunc.h directly.
+
+          bias-disable: true
+
+          bias-pull-up: true
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          input-disable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [2, 4, 6, 8, 10, 12, 14, 16]
+
+          mediatek,drive-strength-adv:
+            description: |
+              Describe the specific driving setup property.
+              For I2C pins, the existing generic driving setup can only support
+              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
+              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
+              driving setup, the existing generic setup will be disabled.
+              The specific driving setup is controlled by E1E0EN.
+              When E1=0/E0=0, the strength is 0.125mA.
+              When E1=0/E0=1, the strength is 0.25mA.
+              When E1=1/E0=0, the strength is 0.5mA.
+              When E1=1/E0=1, the strength is 1mA.
+              EN is used to enable or disable the specific driving setup.
+              Valid arguments are described as below:
+              0: (E1, E0, EN) = (0, 0, 0)
+              1: (E1, E0, EN) = (0, 0, 1)
+              2: (E1, E0, EN) = (0, 1, 0)
+              3: (E1, E0, EN) = (0, 1, 1)
+              4: (E1, E0, EN) = (1, 0, 0)
+              5: (E1, E0, EN) = (1, 0, 1)
+              6: (E1, E0, EN) = (1, 1, 0)
+              7: (E1, E0, EN) = (1, 1, 1)
+              So the valid arguments are from 0 to 7.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
+          mediatek,pull-up-adv:
+            description: |
+              Pull up setings for 2 pull resistors, R0 and R1. User can
+              configure those special pins. Valid arguments are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,pull-down-adv:
+            description: |
+              Pull down settings for 2 pull resistors, R0 and R1. User can
+              configure those special pins. Valid arguments are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,tdsel:
+            description: |
+              An integer describing the steps for output level shifter duty
+              cycle when asserted (high pulse width adjustment). Valid arguments
+              are from 0 to 15.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+          mediatek,rdsel:
+            description: |
+              An integer describing the steps for input level shifter duty cycle
+              when asserted (high pulse width adjustment). Valid arguments are
+              from 0 to 63.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+        required:
+          - pinmux
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt8183-pinfunc.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pio: pinctrl at 10005000 {
+          compatible = "mediatek,mt8183-pinctrl";
+          reg = <0 0x10005000 0 0x1000>,
+                <0 0x11f20000 0 0x1000>,
+                <0 0x11e80000 0 0x1000>,
+                <0 0x11e70000 0 0x1000>,
+                <0 0x11e90000 0 0x1000>,
+                <0 0x11d30000 0 0x1000>,
+                <0 0x11d20000 0 0x1000>,
+                <0 0x11c50000 0 0x1000>,
+                <0 0x11f30000 0 0x1000>,
+                <0 0x1000b000 0 0x1000>;
+          reg-names = "iocfg0", "iocfg1", "iocfg2",
+                "iocfg3", "iocfg4", "iocfg5",
+                "iocfg6", "iocfg7", "iocfg8",
+                "eint";
+          gpio-controller;
+          #gpio-cells = <2>;
+          gpio-ranges = <&pio 0 0 192>;
+          interrupt-controller;
+          interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+          #interrupt-cells = <2>;
+
+          i2c0_pins_a: i2c-0 {
+            pins1 {
+              pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
+                <PINMUX_GPIO49__FUNC_SDA5>;
+              mediatek,pull-up-adv = <3>;
+              mediatek,drive-strength-adv = <7>;
+            };
+          };
+
+          i2c1_pins_a: i2c-1 {
+            pins {
+              pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
+                <PINMUX_GPIO51__FUNC_SDA3>;
+              mediatek,pull-down-adv = <2>;
+              mediatek,drive-strength-adv = <4>;
+            };
+          };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
deleted file mode 100644
index 5fe2c26c28bf1..0000000000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-* Mediatek MT65XX Pin Controller
-
-The Mediatek's Pin controller is used to control SoC pins.
-
-Required properties:
-- compatible: value should be one of the following.
-	"mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl.
-	"mediatek,mt2712-pinctrl", compatible with mt2712 pinctrl.
-	"mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
-	"mediatek,mt7623-pinctrl", compatible with mt7623 pinctrl.
-	"mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
-	"mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
-	"mediatek,mt8167-pinctrl", compatible with mt8167 pinctrl.
-	"mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
-	"mediatek,mt8365-pinctrl", compatible with mt8365 pinctrl.
-	"mediatek,mt8516-pinctrl", compatible with mt8516 pinctrl.
-- pins-are-numbered: Specify the subnodes are using numbered pinmux to
-  specify pins.
-- gpio-controller : Marks the device node as a gpio controller.
-- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
-  binding is used, the amount of cells must be specified as 2. See the below
-  mentioned gpio binding representation for description of particular cells.
-
-	Eg: <&pio 6 0>
-	<[phandle of the gpio controller node]
-	[line number within the gpio controller]
-	[flags]>
-
-	Values for gpio specifier:
-	- Line number: is a value between 0 to 202.
-	- Flags:  bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
-            Only the following flags are supported:
-            0 - GPIO_ACTIVE_HIGH
-            1 - GPIO_ACTIVE_LOW
-
-Optional properties:
-- mediatek,pctl-regmap: Should be a phandle of the syscfg node.
-- reg: physicall address base for EINT registers
-- interrupt-controller: Marks the device node as an interrupt controller
-- #interrupt-cells: Should be two.
-- interrupts : The interrupt outputs from the controller.
-
-Please refer to pinctrl-bindings.txt in this directory for details of the
-common pinctrl bindings used by client devices.
-
-Subnode format
-A pinctrl node should contain at least one subnodes representing the
-pinctrl groups available on the machine. Each subnode will list the
-pins it needs, and how they should be configured, with regard to muxer
-configuration, pullups, drive strength, input enable/disable and input schmitt.
-
-    node {
-	pinmux = <PIN_NUMBER_PINMUX>;
-	GENERIC_PINCONFIG;
-    };
-
-Required properties:
-- pinmux: integer array, represents gpio pin number and mux setting.
-    Supported pin number and mux varies for different SoCs, and are defined
-    as macros in boot/dts/<soc>-pinfunc.h directly.
-
-Optional properties:
-- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
-    bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high,
-    input-schmitt-enable, input-schmitt-disable and drive-strength are valid.
-
-    Some special pins have extra pull up strength, there are R0 and R1 pull-up
-    resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11.
-    So when config bias-pull-up, it support arguments for those special pins.
-    Some macros have been defined for this usage, such as MTK_PUPD_SET_R1R0_00.
-    See dt-bindings/pinctrl/mt65xx.h.
-
-    When config drive-strength, it can support some arguments, such as
-    MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
-
-Examples:
-
-#include "mt8135-pinfunc.h"
-
-...
-{
-	syscfg_pctl_a: syscfg-pctl-a at 10005000 {
-		compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon";
-		reg = <0 0x10005000 0 0x1000>;
-	};
-
-	syscfg_pctl_b: syscfg-pctl-b at 1020c020 {
-		compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon";
-		reg = <0 0x1020C020 0 0x1000>;
-	};
-
-	pinctrl at 1c20800 {
-		compatible = "mediatek,mt8135-pinctrl";
-		reg = <0 0x1000B000 0 0x1000>;
-		mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>;
-		pins-are-numbered;
-		gpio-controller;
-		#gpio-cells = <2>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
-
-		i2c0_pins_a: i2c0 at 0 {
-			pins1 {
-				pinmux = <MT8135_PIN_100_SDA0__FUNC_SDA0>,
-					 <MT8135_PIN_101_SCL0__FUNC_SCL0>;
-				bias-disable;
-			};
-		};
-
-		i2c1_pins_a: i2c1 at 0 {
-			pins {
-				pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
-					 <MT8135_PIN_196_SCL1__FUNC_SCL1>;
-				bias-pull-up = <55>;
-			};
-		};
-
-		i2c2_pins_a: i2c2 at 0 {
-			pins1 {
-				pinmux = <MT8135_PIN_193_SDA2__FUNC_SDA2>;
-				bias-pull-down;
-			};
-
-			pins2 {
-				pinmux = <MT8135_PIN_49_WATCHDOG__FUNC_GPIO49>;
-				bias-pull-up;
-			};
-		};
-
-		i2c3_pins_a: i2c3 at 0 {
-			pins1 {
-				pinmux = <MT8135_PIN_40_DAC_CLK__FUNC_GPIO40>,
-					 <MT8135_PIN_41_DAC_WS__FUNC_GPIO41>;
-				bias-pull-up = <55>;
-			};
-
-			pins2 {
-				pinmux = <MT8135_PIN_35_SCL3__FUNC_SCL3>,
-					 <MT8135_PIN_36_SDA3__FUNC_SDA3>;
-				output-low;
-				bias-pull-up = <55>;
-			};
-
-			pins3 {
-				pinmux = <MT8135_PIN_57_JTCK__FUNC_GPIO57>,
-					 <MT8135_PIN_60_JTDI__FUNC_JTDI>;
-				drive-strength = <32>;
-			};
-		};
-
-		...
-	}
-};
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
deleted file mode 100644
index bd83401e6179a..0000000000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-* MediaTek MT6797 Pin Controller
-
-The MediaTek's MT6797 Pin controller is used to control SoC pins.
-
-Required properties:
-- compatible: Value should be one of the following.
-              "mediatek,mt6797-pinctrl", compatible with mt6797 pinctrl.
-- reg:        Should contain address and size for gpio, iocfgl, iocfgb,
-              iocfgr and iocfgt register bases.
-- reg-names:  An array of strings describing the "reg" entries. Must
-              contain "gpio", "iocfgl", "iocfgb", "iocfgr", "iocfgt".
-- gpio-controller: Marks the device node as a gpio controller.
-- #gpio-cells: Should be two. The first cell is the gpio pin number
-               and the second cell is used for optional parameters.
-
-Optional properties:
-- interrupt-controller: Marks the device node as an interrupt controller.
-- #interrupt-cells: Should be two.
-- interrupts : The interrupt outputs from the controller.
-
-Please refer to pinctrl-bindings.txt in this directory for details of the
-common pinctrl bindings used by client devices.
-
-Subnode format
-A pinctrl node should contain at least one subnodes representing the
-pinctrl groups available on the machine. Each subnode will list the
-pins it needs, and how they should be configured, with regard to muxer
-configuration, pullups, drive strength, input enable/disable and input schmitt.
-
-    node {
-        pinmux = <PIN_NUMBER_PINMUX>;
-        GENERIC_PINCONFIG;
-    };
-
-Required properties:
-- pinmux: Integer array, represents gpio pin number and mux setting.
-    Supported pin number and mux varies for different SoCs, and are defined
-    as macros in dt-bindings/pinctrl/<soc>-pinfunc.h directly.
-
-Optional properties:
-- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
-    bias-pull, bias-pull-down, input-enable, input-schmitt-enable,
-    input-schmitt-disable, output-enable output-low, output-high,
-    drive-strength, and slew-rate are valid.
-
-    Valid arguments for 'slew-rate' are '0' for no slew rate controlled and
-    '1' for slower slew rate respectively. Valid arguments for 'drive-strength'
-    is limited, such as 2, 4, 8, 12, or 16 in mA.
-
-    Some optional vendor properties as defined are valid to specify in a
-    pinconf subnode:
-    - mediatek,tdsel: An integer describing the steps for output level shifter
-      duty cycle when asserted (high pulse width adjustment). Valid arguments
-      are from 0 to 15.
-    - mediatek,rdsel: An integer describing the steps for input level shifter
-      duty cycle when asserted (high pulse width adjustment). Valid arguments
-      are from 0 to 63.
-    - mediatek,pull-up-adv: An integer describing the code R1R0 as 0, 1, 2
-      or 3 for the advanced pull-up resistors.
-    - mediatek,pull-down-adv: An integer describing the code R1R0 as 0, 1, 2,
-      or 3 for the advanced pull-down resistors.
-
-Examples:
-
-        pio: pinctrl at 10005000 {
-                compatible = "mediatek,mt6797-pinctrl";
-                reg = <0 0x10005000 0 0x1000>,
-                      <0 0x10002000 0 0x400>,
-                      <0 0x10002400 0 0x400>,
-                      <0 0x10002800 0 0x400>,
-                      <0 0x10002C00 0 0x400>;
-                reg-names = "gpio", "iocfgl", "iocfgb",
-                            "iocfgr", "iocfgt";
-                gpio-controller;
-                #gpio-cells = <2>;
-
-                uart1_pins_a: uart1 {
-                        pins1 {
-                                pinmux = <MT6797_GPIO232__FUNC_URXD1>,
-                                         <MT6797_GPIO233__FUNC_UTXD1>;
-                        };
-                };
-        };
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
deleted file mode 100644
index 7a7aca1ed705b..0000000000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+++ /dev/null
@@ -1,490 +0,0 @@
-== MediaTek MT7622 pinctrl controller ==
-
-Required properties for the root node:
- - compatible: Should be one of the following
-	       "mediatek,mt7622-pinctrl" for MT7622 SoC
-	       "mediatek,mt7629-pinctrl" for MT7629 SoC
- - reg: offset and length of the pinctrl space
-
- - gpio-controller: Marks the device node as a GPIO controller.
- - #gpio-cells: Should be two. The first cell is the pin number and the
-   second is the GPIO flags.
-
-Optional properties:
-- interrupt-controller  : Marks the device node as an interrupt controller
-
-If the property interrupt-controller is defined, following property is required
-- reg-names: A string describing the "reg" entries. Must contain "eint".
-- interrupts : The interrupt output from the controller.
-- #interrupt-cells: Should be two.
-
-Please refer to pinctrl-bindings.txt in this directory for details of the
-common pinctrl bindings used by client devices, including the meaning of the
-phrase "pin configuration node".
-
-MT7622 pin configuration nodes act as a container for an arbitrary number of
-subnodes. Each of these subnodes represents some desired configuration for a
-pin, a group, or a list of pins or groups. This configuration can include the
-mux function to select on those pin(s)/group(s), and various pin configuration
-parameters, such as pull-up, slew rate, etc.
-
-We support 2 types of configuration nodes. Those nodes can be either pinmux
-nodes or pinconf nodes. Each configuration node can consist of multiple nodes
-describing the pinmux and pinconf options.
-
-The name of each subnode doesn't matter as long as it is unique; all subnodes
-should be enumerated and processed purely based on their content.
-
-== pinmux nodes content ==
-
-The following generic properties as defined in pinctrl-bindings.txt are valid
-to specify in a pinmux subnode:
-
-Required properties are:
- - groups: An array of strings. Each string contains the name of a group.
-  Valid values for these names are listed below.
- - function: A string containing the name of the function to mux to the
-  group. Valid values for function names are listed below.
-
-== pinconf nodes content ==
-
-The following generic properties as defined in pinctrl-bindings.txt are valid
-to specify in a pinconf subnode:
-
-Required properties are:
- - pins: An array of strings. Each string contains the name of a pin.
-  Valid values for these names are listed below.
- - groups: An array of strings. Each string contains the name of a group.
-  Valid values for these names are listed below.
-
-Optional properies are:
- bias-disable, bias-pull, bias-pull-down, input-enable,
- input-schmitt-enable, input-schmitt-disable, output-enable
- output-low, output-high, drive-strength, slew-rate
-
- Valid arguments for 'slew-rate' are '0' for no slew rate controlled and '1' for
- slower slew rate respectively.
- Valid arguments for 'drive-strength', 4, 8, 12, or 16 in mA.
-
-The following specific properties as defined are valid to specify in a pinconf
-subnode:
-
-Optional properties are:
- - mediatek,tdsel: An integer describing the steps for output level shifter duty
-   cycle when asserted (high pulse width adjustment). Valid arguments are from 0
-   to 15.
- - mediatek,rdsel: An integer describing the steps for input level shifter duty
-   cycle when asserted (high pulse width adjustment). Valid arguments are from 0
-   to 63.
-
-== Valid values for pins, function and groups on MT7622 ==
-
-Valid values for pins are:
-pins can be referenced via the pin names as the below table shown and the
-related physical number is also put ahead of those names which helps cross
-references to pins between groups to know whether pins assignment conflict
-happens among devices try to acquire those available pins.
-
-	Pin #:  Valid values for pins
-	-----------------------------
-	PIN 0: "GPIO_A"
-	PIN 1: "I2S1_IN"
-	PIN 2: "I2S1_OUT"
-	PIN 3: "I2S_BCLK"
-	PIN 4: "I2S_WS"
-	PIN 5: "I2S_MCLK"
-	PIN 6: "TXD0"
-	PIN 7: "RXD0"
-	PIN 8: "SPI_WP"
-	PIN 9: "SPI_HOLD"
-	PIN 10: "SPI_CLK"
-	PIN 11: "SPI_MOSI"
-	PIN 12: "SPI_MISO"
-	PIN 13: "SPI_CS"
-	PIN 14: "I2C_SDA"
-	PIN 15: "I2C_SCL"
-	PIN 16: "I2S2_IN"
-	PIN 17: "I2S3_IN"
-	PIN 18: "I2S4_IN"
-	PIN 19: "I2S2_OUT"
-	PIN 20: "I2S3_OUT"
-	PIN 21: "I2S4_OUT"
-	PIN 22: "GPIO_B"
-	PIN 23: "MDC"
-	PIN 24: "MDIO"
-	PIN 25: "G2_TXD0"
-	PIN 26: "G2_TXD1"
-	PIN 27: "G2_TXD2"
-	PIN 28: "G2_TXD3"
-	PIN 29: "G2_TXEN"
-	PIN 30: "G2_TXC"
-	PIN 31: "G2_RXD0"
-	PIN 32: "G2_RXD1"
-	PIN 33: "G2_RXD2"
-	PIN 34: "G2_RXD3"
-	PIN 35: "G2_RXDV"
-	PIN 36: "G2_RXC"
-	PIN 37: "NCEB"
-	PIN 38: "NWEB"
-	PIN 39: "NREB"
-	PIN 40: "NDL4"
-	PIN 41: "NDL5"
-	PIN 42: "NDL6"
-	PIN 43: "NDL7"
-	PIN 44: "NRB"
-	PIN 45: "NCLE"
-	PIN 46: "NALE"
-	PIN 47: "NDL0"
-	PIN 48: "NDL1"
-	PIN 49: "NDL2"
-	PIN 50: "NDL3"
-	PIN 51: "MDI_TP_P0"
-	PIN 52: "MDI_TN_P0"
-	PIN 53: "MDI_RP_P0"
-	PIN 54: "MDI_RN_P0"
-	PIN 55: "MDI_TP_P1"
-	PIN 56: "MDI_TN_P1"
-	PIN 57: "MDI_RP_P1"
-	PIN 58: "MDI_RN_P1"
-	PIN 59: "MDI_RP_P2"
-	PIN 60: "MDI_RN_P2"
-	PIN 61: "MDI_TP_P2"
-	PIN 62: "MDI_TN_P2"
-	PIN 63: "MDI_TP_P3"
-	PIN 64: "MDI_TN_P3"
-	PIN 65: "MDI_RP_P3"
-	PIN 66: "MDI_RN_P3"
-	PIN 67: "MDI_RP_P4"
-	PIN 68: "MDI_RN_P4"
-	PIN 69: "MDI_TP_P4"
-	PIN 70: "MDI_TN_P4"
-	PIN 71: "PMIC_SCL"
-	PIN 72: "PMIC_SDA"
-	PIN 73: "SPIC1_CLK"
-	PIN 74: "SPIC1_MOSI"
-	PIN 75: "SPIC1_MISO"
-	PIN 76: "SPIC1_CS"
-	PIN 77: "GPIO_D"
-	PIN 78: "WATCHDOG"
-	PIN 79: "RTS3_N"
-	PIN 80: "CTS3_N"
-	PIN 81: "TXD3"
-	PIN 82: "RXD3"
-	PIN 83: "PERST0_N"
-	PIN 84: "PERST1_N"
-	PIN 85: "WLED_N"
-	PIN 86: "EPHY_LED0_N"
-	PIN 87: "AUXIN0"
-	PIN 88: "AUXIN1"
-	PIN 89: "AUXIN2"
-	PIN 90: "AUXIN3"
-	PIN 91: "TXD4"
-	PIN 92: "RXD4"
-	PIN 93: "RTS4_N"
-	PIN 94: "CST4_N"
-	PIN 95: "PWM1"
-	PIN 96: "PWM2"
-	PIN 97: "PWM3"
-	PIN 98: "PWM4"
-	PIN 99: "PWM5"
-	PIN 100: "PWM6"
-	PIN 101: "PWM7"
-	PIN 102: "GPIO_E"
-
-Valid values for function are:
-	"emmc", "eth", "i2c", "i2s", "ir", "led", "flash", "pcie",
-	"pmic", "pwm", "sd", "spi", "tdm", "uart", "watchdog"
-
-Valid values for groups are:
-additional data is put followingly with valid value allowing us to know which
-applicable function and which relevant pins (in pin#) are able applied for that
-group.
-
-	Valid value			function	pins (in pin#)
-	-------------------------------------------------------------------------
-	"emmc"				"emmc"		40, 41, 42, 43, 44, 45,
-							47, 48, 49, 50
-	"emmc_rst"			"emmc"		37
-	"esw"				"eth"		51, 52, 53, 54, 55, 56,
-							57, 58, 59, 60, 61, 62,
-							63, 64, 65, 66, 67, 68,
-							69, 70
-	"esw_p0_p1"			"eth"		51, 52, 53, 54, 55, 56,
-							57, 58
-	"esw_p2_p3_p4"			"eth"		59, 60, 61, 62, 63, 64,
-							65, 66, 67, 68, 69, 70
-	"rgmii_via_esw"			"eth"		59, 60, 61, 62, 63, 64,
-							65, 66, 67, 68, 69, 70
-	"rgmii_via_gmac1"		"eth"		59, 60, 61, 62, 63, 64,
-							65, 66, 67, 68, 69, 70
-	"rgmii_via_gmac2"		"eth"		25, 26, 27, 28, 29, 30,
-							31, 32, 33, 34, 35, 36
-	"mdc_mdio"			"eth"		23, 24
-	"i2c0"				"i2c"		14, 15
-	"i2c1_0"			"i2c"		55, 56
-	"i2c1_1"			"i2c"		73, 74
-	"i2c1_2"			"i2c"		87, 88
-	"i2c2_0"			"i2c"		57, 58
-	"i2c2_1"			"i2c"		75, 76
-	"i2c2_2"			"i2c"		89, 90
-	"i2s_in_mclk_bclk_ws"		"i2s"		3, 4, 5
-	"i2s1_in_data"			"i2s"		1
-	"i2s2_in_data"			"i2s"		16
-	"i2s3_in_data"			"i2s"		17
-	"i2s4_in_data"			"i2s"		18
-	"i2s_out_mclk_bclk_ws"		"i2s"		3, 4, 5
-	"i2s1_out_data"			"i2s"		2
-	"i2s2_out_data"			"i2s"		19
-	"i2s3_out_data"			"i2s"		20
-	"i2s4_out_data"			"i2s"		21
-	"ir_0_tx"			"ir"		16
-	"ir_1_tx"			"ir"		59
-	"ir_2_tx"			"ir"		99
-	"ir_0_rx"			"ir"		17
-	"ir_1_rx"			"ir"		60
-	"ir_2_rx"			"ir"		100
-	"ephy_leds"			"led"		86, 91, 92, 93, 94
-	"ephy0_led"			"led"		86
-	"ephy1_led"			"led"		91
-	"ephy2_led"			"led"		92
-	"ephy3_led"			"led"		93
-	"ephy4_led"			"led"		94
-	"wled"				"led"		85
-	"par_nand"			"flash"		37, 38, 39, 40, 41, 42,
-							43, 44, 45, 46, 47, 48,
-							49, 50
-	"snfi"				"flash"		8, 9, 10, 11, 12, 13
-	"spi_nor"			"flash"		8, 9, 10, 11, 12, 13
-	"pcie0_0_waken"			"pcie"		14
-	"pcie0_1_waken"			"pcie"		79
-	"pcie1_0_waken"			"pcie"		14
-	"pcie0_0_clkreq"		"pcie"		15
-	"pcie0_1_clkreq"		"pcie"		80
-	"pcie1_0_clkreq"		"pcie"		15
-	"pcie0_pad_perst"		"pcie"		83
-	"pcie1_pad_perst"		"pcie"		84
-	"pmic_bus"			"pmic"		71, 72
-	"pwm_ch1_0"			"pwm"		51
-	"pwm_ch1_1"			"pwm"		73
-	"pwm_ch1_2"			"pwm"		95
-	"pwm_ch2_0"			"pwm"		52
-	"pwm_ch2_1"			"pwm"		74
-	"pwm_ch2_2"			"pwm"		96
-	"pwm_ch3_0"			"pwm"		53
-	"pwm_ch3_1"			"pwm"		75
-	"pwm_ch3_2"			"pwm"		97
-	"pwm_ch4_0"			"pwm"		54
-	"pwm_ch4_1"			"pwm"		67
-	"pwm_ch4_2"			"pwm"		76
-	"pwm_ch4_3"			"pwm"		98
-	"pwm_ch5_0"			"pwm"		68
-	"pwm_ch5_1"			"pwm"		77
-	"pwm_ch5_2"			"pwm"		99
-	"pwm_ch6_0"			"pwm"		69
-	"pwm_ch6_1"			"pwm"		78
-	"pwm_ch6_2"			"pwm"		81
-	"pwm_ch6_3"			"pwm"		100
-	"pwm_ch7_0"			"pwm"		70
-	"pwm_ch7_1"			"pwm"		82
-	"pwm_ch7_2"			"pwm"		101
-	"sd_0"				"sd"		16, 17, 18, 19, 20, 21
-	"sd_1"				"sd"		25, 26, 27, 28, 29, 30
-	"spic0_0"			"spi"		63, 64, 65, 66
-	"spic0_1"			"spi"		79, 80, 81, 82
-	"spic1_0"			"spi"		67, 68, 69, 70
-	"spic1_1"			"spi"		73, 74, 75, 76
-	"spic2_0_wp_hold"		"spi"		8, 9
-	"spic2_0"			"spi"		10, 11, 12, 13
-	"tdm_0_out_mclk_bclk_ws"	"tdm"		8, 9, 10
-	"tdm_0_in_mclk_bclk_ws"		"tdm"		11, 12, 13
-	"tdm_0_out_data"		"tdm"		20
-	"tdm_0_in_data"			"tdm"		21
-	"tdm_1_out_mclk_bclk_ws"	"tdm"		57, 58, 59
-	"tdm_1_in_mclk_bclk_ws"		"tdm"		60, 61, 62
-	"tdm_1_out_data"		"tdm"		55
-	"tdm_1_in_data"			"tdm"		56
-	"uart0_0_tx_rx"			"uart"		6, 7
-	"uart1_0_tx_rx"			"uart"		55, 56
-	"uart1_0_rts_cts"		"uart"		57, 58
-	"uart1_1_tx_rx"			"uart"		73, 74
-	"uart1_1_rts_cts"		"uart"		75, 76
-	"uart2_0_tx_rx"			"uart"		3, 4
-	"uart2_0_rts_cts"		"uart"		1, 2
-	"uart2_1_tx_rx"			"uart"		51, 52
-	"uart2_1_rts_cts"		"uart"		53, 54
-	"uart2_2_tx_rx"			"uart"		59, 60
-	"uart2_2_rts_cts"		"uart"		61, 62
-	"uart2_3_tx_rx"			"uart"		95, 96
-	"uart3_0_tx_rx"			"uart"		57, 58
-	"uart3_1_tx_rx"			"uart"		81, 82
-	"uart3_1_rts_cts"		"uart"		79, 80
-	"uart4_0_tx_rx"			"uart"		61, 62
-	"uart4_1_tx_rx"			"uart"		91, 92
-	"uart4_1_rts_cts"		"uart"		93, 94
-	"uart4_2_tx_rx"			"uart"		97, 98
-	"uart4_2_rts_cts"		"uart"		95, 96
-	"watchdog"			"watchdog"	78
-
-
-== Valid values for pins, function and groups on MT7629 ==
-
-	Pin #:  Valid values for pins
-	-----------------------------
-	PIN 0: "TOP_5G_CLK"
-	PIN 1: "TOP_5G_DATA"
-	PIN 2: "WF0_5G_HB0"
-	PIN 3: "WF0_5G_HB1"
-	PIN 4: "WF0_5G_HB2"
-	PIN 5: "WF0_5G_HB3"
-	PIN 6: "WF0_5G_HB4"
-	PIN 7: "WF0_5G_HB5"
-	PIN 8: "WF0_5G_HB6"
-	PIN 9: "XO_REQ"
-	PIN 10: "TOP_RST_N"
-	PIN 11: "SYS_WATCHDOG"
-	PIN 12: "EPHY_LED0_N_JTDO"
-	PIN 13: "EPHY_LED1_N_JTDI"
-	PIN 14: "EPHY_LED2_N_JTMS"
-	PIN 15: "EPHY_LED3_N_JTCLK"
-	PIN 16: "EPHY_LED4_N_JTRST_N"
-	PIN 17: "WF2G_LED_N"
-	PIN 18: "WF5G_LED_N"
-	PIN 19: "I2C_SDA"
-	PIN 20: "I2C_SCL"
-	PIN 21: "GPIO_9"
-	PIN 22: "GPIO_10"
-	PIN 23: "GPIO_11"
-	PIN 24: "GPIO_12"
-	PIN 25: "UART1_TXD"
-	PIN 26: "UART1_RXD"
-	PIN 27: "UART1_CTS"
-	PIN 28: "UART1_RTS"
-	PIN 29: "UART2_TXD"
-	PIN 30: "UART2_RXD"
-	PIN 31: "UART2_CTS"
-	PIN 32: "UART2_RTS"
-	PIN 33: "MDI_TP_P1"
-	PIN 34: "MDI_TN_P1"
-	PIN 35: "MDI_RP_P1"
-	PIN 36: "MDI_RN_P1"
-	PIN 37: "MDI_RP_P2"
-	PIN 38: "MDI_RN_P2"
-	PIN 39: "MDI_TP_P2"
-	PIN 40: "MDI_TN_P2"
-	PIN 41: "MDI_TP_P3"
-	PIN 42: "MDI_TN_P3"
-	PIN 43: "MDI_RP_P3"
-	PIN 44: "MDI_RN_P3"
-	PIN 45: "MDI_RP_P4"
-	PIN 46: "MDI_RN_P4"
-	PIN 47: "MDI_TP_P4"
-	PIN 48: "MDI_TN_P4"
-	PIN 49: "SMI_MDC"
-	PIN 50: "SMI_MDIO"
-	PIN 51: "PCIE_PERESET_N"
-	PIN 52: "PWM_0"
-	PIN 53: "GPIO_0"
-	PIN 54: "GPIO_1"
-	PIN 55: "GPIO_2"
-	PIN 56: "GPIO_3"
-	PIN 57: "GPIO_4"
-	PIN 58: "GPIO_5"
-	PIN 59: "GPIO_6"
-	PIN 60: "GPIO_7"
-	PIN 61: "GPIO_8"
-	PIN 62: "SPI_CLK"
-	PIN 63: "SPI_CS"
-	PIN 64: "SPI_MOSI"
-	PIN 65: "SPI_MISO"
-	PIN 66: "SPI_WP"
-	PIN 67: "SPI_HOLD"
-	PIN 68: "UART0_TXD"
-	PIN 69: "UART0_RXD"
-	PIN 70: "TOP_2G_CLK"
-	PIN 71: "TOP_2G_DATA"
-	PIN 72: "WF0_2G_HB0"
-	PIN 73: "WF0_2G_HB1"
-	PIN 74: "WF0_2G_HB2"
-	PIN 75: "WF0_2G_HB3"
-	PIN 76: "WF0_2G_HB4"
-	PIN 77: "WF0_2G_HB5"
-	PIN 78: "WF0_2G_HB6"
-
-Valid values for function are:
-	"eth", "i2c", "led", "flash", "pcie", "pwm", "spi", "uart",
-	"watchdog", "wifi"
-
-Valid values for groups are:
-	Valid value			function	pins (in pin#)
-	----------------------------------------------------------------
-	"mdc_mdio"			"eth"		23, 24
-	"i2c_0"				"i2c"		19, 20
-	"i2c_1"				"i2c"		53, 54
-	"ephy_leds"			"led"		12, 13, 14, 15, 16,
-							17, 18
-	"ephy0_led"			"led"		12
-	"ephy1_led"			"led"		13
-	"ephy2_led"			"led"		14
-	"ephy3_led"			"led"		15
-	"ephy4_led"			"led"		16
-	"wf2g_led"			"led"		17
-	"wf5g_led"			"led"		18
-	"snfi"				"flash"		62, 63, 64, 65, 66, 67
-	"spi_nor"			"flash"		62, 63, 64, 65, 66, 67
-	"pcie_pereset"			"pcie"		51
-	"pcie_wake"			"pcie"		55
-	"pcie_clkreq"			"pcie"		56
-	"pwm_0"				"pwm"		52
-	"pwm_1"				"pwm"		61
-	"spi_0"				"spi"		21, 22, 23, 24
-	"spi_1"				"spi"		62, 63, 64, 65
-	"spi_wp"			"spi"		66
-	"spi_hold"			"spi"		67
-	"uart0_txd_rxd"			"uart"		68, 69
-	"uart1_0_txd_rxd"		"uart"		25, 26
-	"uart1_0_cts_rts"		"uart"		27, 28
-	"uart1_1_txd_rxd"		"uart"		53, 54
-	"uart1_1_cts_rts"		"uart"		55, 56
-	"uart2_0_txd_rxd"		"uart"		29, 30
-	"uart2_0_cts_rts"		"uart"		31, 32
-	"uart2_1_txd_rxd"		"uart"		57, 58
-	"uart2_1_cts_rts"		"uart"		59, 60
-	"watchdog"			"watchdog"	11
-	"wf0_2g"			"wifi"		70, 71, 72, 73, 74,
-							75, 76, 77, 78
-	"wf0_5g"			"wifi"		0, 1, 2, 3, 4, 5, 6,
-							7, 8, 9, 10
-
-Example:
-
-	pio: pinctrl at 10211000 {
-		compatible = "mediatek,mt7622-pinctrl";
-		reg = <0 0x10211000 0 0x1000>;
-		gpio-controller;
-		#gpio-cells = <2>;
-
-		pinctrl_eth_default: eth-default {
-			mux-mdio {
-				groups = "mdc_mdio";
-				function = "eth";
-				drive-strength = <12>;
-			};
-
-			mux-gmac2 {
-				groups = "gmac2";
-				function = "eth";
-				drive-strength = <12>;
-			};
-
-			mux-esw {
-				groups = "esw";
-				function = "eth";
-				drive-strength = <8>;
-			};
-
-			conf-mdio {
-				pins = "MDC";
-				bias-pull-up;
-			};
-		};
-	};
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
deleted file mode 100644
index eccbe3f55d3f3..0000000000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-* Mediatek MT8183 Pin Controller
-
-The Mediatek's Pin controller is used to control SoC pins.
-
-Required properties:
-- compatible: value should be one of the following.
-	"mediatek,mt8183-pinctrl", compatible with mt8183 pinctrl.
-- gpio-controller : Marks the device node as a gpio controller.
-- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
-  binding is used, the amount of cells must be specified as 2. See the below
-  mentioned gpio binding representation for description of particular cells.
-- gpio-ranges : gpio valid number range.
-- reg: physical address base for gpio base registers. There are 10 GPIO
-  physical address base in mt8183.
-
-Optional properties:
-- reg-names: gpio base register names. There are 10 gpio base register
-  names in mt8183. They are "iocfg0", "iocfg1", "iocfg2", "iocfg3", "iocfg4",
-  "iocfg5", "iocfg6", "iocfg7", "iocfg8", "eint".
-- interrupt-controller: Marks the device node as an interrupt controller
-- #interrupt-cells: Should be two.
-- interrupts : The interrupt outputs to sysirq.
-
-Please refer to pinctrl-bindings.txt in this directory for details of the
-common pinctrl bindings used by client devices.
-
-Subnode format
-A pinctrl node should contain at least one subnodes representing the
-pinctrl groups available on the machine. Each subnode will list the
-pins it needs, and how they should be configured, with regard to muxer
-configuration, pullups, drive strength, input enable/disable and input schmitt.
-
-    node {
-	pinmux = <PIN_NUMBER_PINMUX>;
-	GENERIC_PINCONFIG;
-    };
-
-Required properties:
-- pinmux: integer array, represents gpio pin number and mux setting.
-    Supported pin number and mux varies for different SoCs, and are defined
-    as macros in boot/dts/<soc>-pinfunc.h directly.
-
-Optional properties:
-- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
-    bias-pull-down, bias-pull-up, input-enable, input-disable, output-low,
-    output-high, input-schmitt-enable, input-schmitt-disable
-    and drive-strength are valid.
-
-    Some special pins have extra pull up strength, there are R0 and R1 pull-up
-    resistors available, but for user, it's only need to set R1R0 as 00, 01,
-    10 or 11. So It needs config "mediatek,pull-up-adv" or
-    "mediatek,pull-down-adv" to support arguments for those special pins.
-    Valid arguments are from 0 to 3.
-
-    mediatek,tdsel: An integer describing the steps for output level shifter
-      duty cycle when asserted (high pulse width adjustment). Valid arguments
-      are from 0 to 15.
-    mediatek,rdsel: An integer describing the steps for input level shifter
-      duty cycle when asserted (high pulse width adjustment). Valid arguments
-      are from 0 to 63.
-
-    When config drive-strength, it can support some arguments, such as
-    MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
-    It can only support 2/4/6/8/10/12/14/16mA in mt8183.
-    For I2C pins, there are existing generic driving setup and the specific
-    driving setup. I2C pins can only support 2/4/6/8/10/12/14/16mA driving
-    adjustment in generic driving setup. But in specific driving setup,
-    they can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
-    driving setup for I2C pins, the existing generic driving setup will be
-    disabled. For some special features, we need the I2C pins specific
-    driving setup. The specific driving setup is controlled by E1E0EN.
-    So we need add extra vendor driving preperty instead of
-    the generic driving property.
-    We can add "mediatek,drive-strength-adv = <XXX>;" to describe the specific
-    driving setup property. "XXX" means the value of E1E0EN. EN is 0 or 1.
-    It is used to enable or disable the specific driving setup.
-    E1E0 is used to describe the detail strength specification of the I2C pin.
-    When E1=0/E0=0, the strength is 0.125mA.
-    When E1=0/E0=1, the strength is 0.25mA.
-    When E1=1/E0=0, the strength is 0.5mA.
-    When E1=1/E0=1, the strength is 1mA.
-    So the valid arguments of "mediatek,drive-strength-adv" are from 0 to 7.
-
-Examples:
-
-#include "mt8183-pinfunc.h"
-
-...
-{
-	pio: pinctrl at 10005000 {
-		compatible = "mediatek,mt8183-pinctrl";
-		reg = <0 0x10005000 0 0x1000>,
-		      <0 0x11f20000 0 0x1000>,
-		      <0 0x11e80000 0 0x1000>,
-		      <0 0x11e70000 0 0x1000>,
-		      <0 0x11e90000 0 0x1000>,
-		      <0 0x11d30000 0 0x1000>,
-		      <0 0x11d20000 0 0x1000>,
-		      <0 0x11c50000 0 0x1000>,
-		      <0 0x11f30000 0 0x1000>,
-		      <0 0x1000b000 0 0x1000>;
-		reg-names = "iocfg0", "iocfg1", "iocfg2",
-			    "iocfg3", "iocfg4", "iocfg5",
-			    "iocfg6", "iocfg7", "iocfg8",
-			    "eint";
-		gpio-controller;
-		#gpio-cells = <2>;
-		gpio-ranges = <&pio 0 0 192>;
-		interrupt-controller;
-		interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
-		#interrupt-cells = <2>;
-
-		i2c0_pins_a: i2c0 {
-			pins1 {
-				pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
-					 <PINMUX_GPIO49__FUNC_SDA5>;
-				mediatek,pull-up-adv = <3>;
-				mediatek,drive-strength-adv = <7>;
-			};
-		};
-
-		i2c1_pins_a: i2c1 {
-			pins {
-				pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
-					 <PINMUX_GPIO51__FUNC_SDA3>;
-				mediatek,pull-down-adv = <2>;
-				mediatek,drive-strength-adv = <4>;
-			};
-		};
-		...
-	};
-};
-- 
2.32.0.554.ge1b32706d8-goog



From tabba at google.com  Mon Aug  2 22:31:03 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 3 Aug 2021 07:31:03 +0200
Subject: [PATCH v3 19/21] KVM: arm64: Refactor protected nVHE stage-1
 locking
In-Reply-To: <20210729132818.4091769-20-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-20-qperret@google.com>
Message-ID: <CA+EHjTwWt+jvRZsk5KEhQWzn+XqdV2gZSq7oCuOCVXRa1=JiWw@mail.gmail.com>

Hi Quentin,

On Thu, Jul 29, 2021 at 3:29 PM Quentin Perret <qperret at google.com> wrote:
>
> Refactor the hypervisor stage-1 locking in nVHE protected mode to expose
> a new pkvm_create_mappings_locked() function. This will be used in later
> patches to allow walking and changing the hypervisor stage-1 without
> releasing the lock.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/mm.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/mm.c         | 18 ++++++++++++++++--
>  2 files changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> index 8ec3a5a7744b..c76d7136ed9b 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> @@ -23,6 +23,7 @@ int hyp_map_vectors(void);
>  int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
>  int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
>  int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
> +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
>  int __pkvm_create_mappings(unsigned long start, unsigned long size,
>                            unsigned long phys, enum kvm_pgtable_prot prot);
>  unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
> diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
> index a8efdf0f9003..6fbe8e8030f6 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mm.c
> @@ -67,13 +67,15 @@ unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
>         return addr;
>  }
>
> -int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot)
>  {
>         unsigned long start = (unsigned long)from;
>         unsigned long end = (unsigned long)to;
>         unsigned long virt_addr;
>         phys_addr_t phys;
>
> +       hyp_assert_lock_held(&pkvm_pgd_lock);
> +
>         start = start & PAGE_MASK;
>         end = PAGE_ALIGN(end);
>
> @@ -81,7 +83,8 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>                 int err;
>
>                 phys = hyp_virt_to_phys((void *)virt_addr);
> -               err = __pkvm_create_mappings(virt_addr, PAGE_SIZE, phys, prot);
> +               err = kvm_pgtable_hyp_map(&pkvm_pgtable, virt_addr, PAGE_SIZE,
> +                                         phys, prot);
>                 if (err)
>                         return err;
>         }
> @@ -89,6 +92,17 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>         return 0;
>  }
>
> +int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> +{
> +       int ret;
> +
> +       hyp_spin_lock(&pkvm_pgd_lock);
> +       ret = pkvm_create_mappings_locked(from, to, prot);
> +       hyp_spin_unlock(&pkvm_pgd_lock);
> +
> +       return ret;
> +}
> +

I'm wondering whether this patch should also refactor
__pkvm_create_mappings. It doesn't quite do the exact same thing and
has different parameters.

Thanks,
/fuad

>  int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back)
>  {
>         unsigned long start, end;
> --
> 2.32.0.432.gabb21c7263-goog
>


From ikjn at chromium.org  Mon Aug  2 22:37:01 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Tue, 3 Aug 2021 13:37:01 +0800
Subject: [PATCH v2 11/11] memory: mtk-smi: mt8195: Add initial setting for
 smi-larb
In-Reply-To: <1627540902.13818.3.camel@mhfsdcap03>
References: <20210715121209.31024-1-yong.wu@mediatek.com>
 <20210715121209.31024-12-yong.wu@mediatek.com>
 <CAATdQgAfo9oNR5=ogEottHajODngi1ahvKUnEOUczzjreYpPcQ@mail.gmail.com>
 <1626935902.27875.7.camel@mhfsdcap03> <1627540902.13818.3.camel@mhfsdcap03>
Message-ID: <CAATdQgCf2sNwZWBKOC=HJU7Ur+7J6+uc75UD6xjfMF71Dxr18Q@mail.gmail.com>

Hi,

On Thu, Jul 29, 2021 at 2:41 PM Yong Wu <yong.wu at mediatek.com> wrote:
>
> Hi Ikjoon,
>
> Just a ping.
>
> On Thu, 2021-07-22 at 14:38 +0800, Yong Wu wrote:
> > On Wed, 2021-07-21 at 21:40 +0800, Ikjoon Jang wrote:
> > > On Thu, Jul 15, 2021 at 8:23 PM Yong Wu <yong.wu at mediatek.com> wrote:
> > > >
> > > > To improve the performance, We add some initial setting for smi larbs.
> > > > there are two part:
> > > > 1), Each port has the special ostd(outstanding) value in each larb.
> > > > 2), Two general setting for each larb.

Honestly, I think nobody outside Mediatek will understand this.
Can you please update this to be more generic?
Like "Apply default bus settings for mt8195, without this, XXX
problems can happen.. "?

Or for example, adding brief descriptions on what
MTK_SMI_FLAG_LARB_THRT_EN, MTK_SMI_FLAG_LARB_SW_FLAG,
and MTK_SMI_FLAG_LARB_SW_FLAG[] are for would be better if it's available.

> > > >
> > > > In some SoC, this setting maybe changed dynamically for some special case
> > > > like 4K, and this initial setting is enough in mt8195.
> > > >
> > > > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > > > ---
> > [...]
> > > >  struct mtk_smi {
> > > > @@ -213,12 +228,22 @@ static void mtk_smi_larb_config_port_mt8173(struct device *dev)
> > > >  static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
> > > >  {
> > > >         struct mtk_smi_larb *larb = dev_get_drvdata(dev);
> > > > -       u32 reg;
> > > > +       u32 reg, flags_general = larb->larb_gen->flags_general;
> > > > +       const u8 *larbostd = larb->larb_gen->ostd[larb->larbid];
> > > >         int i;
> > > >
> > > >         if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
> > > >                 return;
> > > >
> > > > +       if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_LARB_THRT_EN))
> > > > +               writel_relaxed(SMI_LARB_THRT_EN, larb->base + SMI_LARB_CMD_THRT_CON);
> > > > +
> > > > +       if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_LARB_SW_FLAG))
> > > > +               writel_relaxed(SMI_LARB_SW_FLAG_1, larb->base + SMI_LARB_SW_FLAG);
> > > > +
> > > > +       for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++)
> > > > +               writel_relaxed(larbostd[i], larb->base + SMI_LARB_OSTDL_PORTx(i));
> > >
> > > All other mtk platform's larbs have the same format for SMI_LARB_OSTDL_PORTx()
> > > registers at the same offset? or is this unique feature for mt8195?
> >
> > All the other Platform's larbs have the same format at the same offset.
>
> In this case, Do you have some other further comment? If no, I will keep
> the current solution for this.

Sorry for the late response,
I have no further comments or any objections on here. Please go ahead for v3.
I just had no idea on the register definitions and wanted to be sure that
newly added register definitions are common to all MTK platforms.

Thanks!

>
> Thanks.
>
> >
> > >
> > > > +
> > > >         for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
> > > >                 reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
> > > >                 reg |= F_MMU_EN;
> > > > @@ -227,6 +252,51 @@ static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
> > > >         }
> > > >  }
> > > >
> >
> > [...]
> >
>


From tzungbi at google.com  Mon Aug  2 22:37:50 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Tue, 3 Aug 2021 13:37:50 +0800
Subject: [v7,1/3] dt-bindings: mediatek: mt8195: update mtk-wdt document
In-Reply-To: <20210726122901.12195-2-Christine.Zhu@mediatek.com>
References: <20210726122901.12195-1-Christine.Zhu@mediatek.com>
 <20210726122901.12195-2-Christine.Zhu@mediatek.com>
Message-ID: <CA+Px+wX+gy4hV3BsTU81ThS=FUe0HidUV-iZZvQ3qm4WxKXGxQ@mail.gmail.com>

On Mon, Jul 26, 2021 at 8:30 PM Christine Zhu
<Christine.Zhu at mediatek.com> wrote:
> @@ -13,6 +13,7 @@ Required properties:
>         "mediatek,mt8183-wdt": for MT8183
>         "mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
>         "mediatek,mt8192-wdt": for MT8192
> +       "mediatek,mt8195-wdt": for MT8195
Just realized the patch has been applied in commit b326f2c85f3d
("dt-bindings: watchdog: Add compatible for Mediatek MT8195").  Could
you rebase the series to the latest tree and resend?


From masahiroy at kernel.org  Mon Aug  2 22:40:44 2021
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Tue, 3 Aug 2021 14:40:44 +0900
Subject: [PATCH] arm64: move the (z)install rules to arch/arm64/Makefile
In-Reply-To: <20210802124624.GG18685@arm.com>
References: <20210729140527.443116-1-masahiroy@kernel.org>
 <20210802124624.GG18685@arm.com>
Message-ID: <CAK7LNARFWRgGsea03mZJfSPjyxYLxz3g6fjTs9aon9hxYvsxcw@mail.gmail.com>

On Mon, Aug 2, 2021 at 9:46 PM Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> On Thu, Jul 29, 2021 at 11:05:27PM +0900, Masahiro Yamada wrote:
> > Currently, the (z)install targets in arch/arm64/Makefile descend into
> > arch/arm64/boot/Makefile to invoke the shell script, but there is no
> > good reason to do so.
> >
> > arch/arm64/Makefile can run the shell script directly.
> >
> > Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> > ---
> >
> >  arch/arm64/Makefile      | 7 +++++--
> >  arch/arm64/boot/Makefile | 8 --------
> >  2 files changed, 5 insertions(+), 10 deletions(-)
>
> Is this part of some cross-arch clean-up? I can see x86 for example does
> the same thing.
>
> Thanks.
>

Yes. I want to do these cleanups tree-wide, but
I sent patches per arch.

Please pick it up to your arm64 tree
if you do not mind.



-- 
Best Regards
Masahiro Yamada


From mudongliangabcd at gmail.com  Mon Aug  2 22:57:06 2021
From: mudongliangabcd at gmail.com (Dongliang Mu)
Date: Tue, 3 Aug 2021 13:57:06 +0800
Subject: [PATCH] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <YQg4lehajLpQjyPd@Red>
References: <20210726152724.2281408-1-mudongliangabcd@gmail.com>
 <YQg4lehajLpQjyPd@Red>
Message-ID: <CAD-N9QWvR-7caWCnk1CMo8sWPEC=CfKU2_v=YkTVr0o5L7wehA@mail.gmail.com>

On Tue, Aug 3, 2021 at 2:25 AM Corentin Labbe <clabbe.montjoie at gmail.com> wrote:
>
> Le Mon, Jul 26, 2021 at 11:27:12PM +0800, Dongliang Mu a ?crit :
> > In sun8i_ce_hash_run, all the dma_mmap_sg/single will cause memory leak
> > due to no corresponding unmap operation if errors happen.
> >
> > Fix this by adding error handling part for all the dma_mmap_sg/single.
> >
>
> I think it could be better worded, error handling is already there (but bad).

Sure. How about "Fix this by freeing the objects allocated by
dma_mmap_sg/single when errors occur."?

>
> > Fixes: 56f6d5aee88d ("crypto: sun8i-ce - support hash algorithms")
> > Signed-off-by: Dongliang Mu <mudongliangabcd at gmail.com>
> > ---
> >  .../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 28 +++++++++----------
> >  1 file changed, 13 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> > index 88194718a806..d454ad99deee 100644
> > --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> > +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> > @@ -286,16 +286,14 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> >
> >       /* the padding could be up to two block. */
> >       buf = kzalloc(bs * 2, GFP_KERNEL | GFP_DMA);
> > -     if (!buf) {
> > -             err = -ENOMEM;
> > -             goto theend;
>
> Please keep all goto error for being consistent.

OK, no problem.

BTW, usually for the 1st malloc failure, I prefer returning with errno directly.

>
> > -     }
> > +     if (!buf)
> > +             return -ENOMEM;
> >       bf = (__le32 *)buf;
> >
> >       result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
> >       if (!result) {
> > -             err = -ENOMEM;
> > -             goto theend;
> > +             kfree(buf);
> > +             return -ENOMEM;
> >       }
> >
> >       flow = rctx->flow;
> > @@ -321,7 +319,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> >       if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
> >               dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
> >               err = -EINVAL;
> > -             goto theend;
> > +             goto err_result;
> >       }
> >
> >       len = areq->nbytes;
> > @@ -334,7 +332,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> >       if (len > 0) {
> >               dev_err(ce->dev, "remaining len %d\n", len);
> >               err = -EINVAL;
> > -             goto theend;
> > +             goto err_unmap_sg;
> >       }
> >       addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE);
> >       cet->t_dst[0].addr = cpu_to_le32(addr_res);
> > @@ -342,7 +340,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> >       if (dma_mapping_error(ce->dev, addr_res)) {
> >               dev_err(ce->dev, "DMA map dest\n");
> >               err = -EINVAL;
> > -             goto theend;
> > +             goto err_unmap_sg;
> >       }
> >
> >       byte_count = areq->nbytes;
> > @@ -392,7 +390,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> >       if (dma_mapping_error(ce->dev, addr_pad)) {
> >               dev_err(ce->dev, "DMA error on padding SG\n");
> >               err = -EINVAL;
> > -             goto theend;
> > +             goto err_addr_res;
> >       }
> >
> >       if (ce->variant->hash_t_dlen_in_bits)
> > @@ -405,15 +403,15 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> >       err = sun8i_ce_run_task(ce, flow, crypto_tfm_alg_name(areq->base.tfm));
> >
> >       dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE);
> > +err_addr_res:
> > +     dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> > +err_unmap_sg:
> >       dma_unmap_sg(ce->dev, areq->src, sg_nents(areq->src),
> >                    DMA_TO_DEVICE);
> > -     dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> > -
> > -
> >       memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
>
> The result should be copied only when everything is ok. Please add a "if (!err)"

Sure.

>
> Thanks for your work
> Regards


From joel at jms.id.au  Mon Aug  2 22:57:49 2021
From: joel at jms.id.au (Joel Stanley)
Date: Tue, 3 Aug 2021 05:57:49 +0000
Subject: [PATCH v6 0/9] ASPEED sgpio driver enhancement.
In-Reply-To: <58256e8f-6c9a-4ad4-b51e-4048b6feb42a@www.fastmail.com>
References: <20210712100317.23298-1-steven_lee@aspeedtech.com>
 <CAMpxmJXfUterUdaGHOJT5hwcVJ+3cqgSQVdp-6Atuyyo36FxfQ@mail.gmail.com>
 <20210723031615.GA10457@aspeedtech.com>
 <CAMpxmJU4jN-hpNYPLHLbjx4uZ6vDqcyuMVQXhHg1BWXOqyS22A@mail.gmail.com>
 <58256e8f-6c9a-4ad4-b51e-4048b6feb42a@www.fastmail.com>
Message-ID: <CACPK8XdfisvSzr3uWYmfd+u1UtM5+cyMBMvcDZJ+jQ38A1BSXg@mail.gmail.com>

On Tue, 3 Aug 2021 at 04:49, Andrew Jeffery <andrew at aj.id.au> wrote:
> On Fri, 23 Jul 2021, at 17:00, Bartosz Golaszewski wrote:
> > Joel, Andrew: can I take the GPIO patches through the GPIO tree and
> > you'll take the ARM patches separately into v5.15?
>
> I think that should be okay. I'll poke Joel.

Yes, that's fine. I have merged the first four patches into the aspeed tree.

Cheers,

Joel


From yee.lee at mediatek.com  Mon Aug  2 22:55:47 2021
From: yee.lee at mediatek.com (Yee Lee)
Date: Tue, 3 Aug 2021 13:55:47 +0800
Subject: [PATCH v3 1/1] arm64/cpufeature: Optionally disable MTE via
 command-line
In-Reply-To: <20210802153036.GH18685@arm.com>
References: <20210730144957.30938-1-yee.lee@mediatek.com>
 <20210730144957.30938-2-yee.lee@mediatek.com>
 <20210802153036.GH18685@arm.com>
Message-ID: <a200fcaf086b590d5c675eea8e0546fa9db9849e.camel@mediatek.com>

On Mon, 2021-08-02 at 16:30 +0100, Catalin Marinas wrote:
> On Fri, Jul 30, 2021 at 10:49:53PM +0800, yee.lee at mediatek.com wrote:
> > From: Yee Lee <yee.lee at mediatek.com>
> > 
> > For some low-end devices with limited resources,
> > MTE needs to be optionally disabled to save system
> > costs such as tag memory and firmware controls.
> 
> I understand the cost of using MTE but I don't fully get what you
> mean
> by firmware controls. If the ID_AA64PFR1_EL1.MTE reports that MTE is
> present, the firmware should have initialised MTE correctly (e.g. tag
> allocation storage, SCR_EL3.ATA) and not rely on a kernel command
> line
> argument that may or may not be present.

Thanks for the reminding. 
Yes, it seems not able to fully disable MTE.
This still provides an option in runtime for evaluation and test.
And it is also useful for firmware development and hw issue workaround.
> 
> > This allows ID_AA64PFR1_EL1.MTE to be overridden on 
> > its shadow value by giving "arm64.nomte" on cmdline,
> > and to suppress MTE feature.
> > 
> > Suggested-by: Marc Zyngier <maz at kernel.org>
> > Suggested-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> > Signed-off-by: Yee Lee <yee.lee at mediatek.com>
> 
> While this patch appears to disable MTE, I don't think it can fully
> prevent the access to the allocation tag storage, so the firmware
> must
> still initialise it correctly.
> 
> The issue is that __cpu_setup already configures the MAIR_EL1
> register
> to use Normal Tagged memory for the kernel mapping and SCTLR_EL1.ATA
> is
> set. The TCF field is zero, so no tag checking, but I couldn't figure
> out from the ARM ARM whether this also prevents LDR/STR from
> attempting
> to fetch the allocation tags. I think it's only the ATA bit and the
> MAIR
> configuration.
> 
> With this patch, KASAN_HW_TAGS (if configured) won't be used and MTE
> will not be presented to user applications, if that's what you want,
> but
> does not fully disable MTE.
> 
> Since May this year, the ARM ARM was updated so that
> SCTLR_EL1.ATA/ATA0
> are not permitted to be cached in the TLB. We could therefore move
> the
> setting to cpu_enable_mte(). Something like below, untested (to be
> folded into your patch):
> 
ok. will be integrated in v4 and tested.

BR,
Yee

> diff --git a/arch/arm64/include/asm/sysreg.h
> b/arch/arm64/include/asm/sysreg.h
> index aa53954c2f6b..cac23455a2b5 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -698,8 +698,7 @@
>  	(SCTLR_ELx_M    | SCTLR_ELx_C    | SCTLR_ELx_SA   |
> SCTLR_EL1_SA0   | \
>  	 SCTLR_EL1_SED  | SCTLR_ELx_I    | SCTLR_EL1_DZE  |
> SCTLR_EL1_UCT   | \
>  	 SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN |
> SCTLR_ELx_ITFSB | \
> -	 SCTLR_ELx_ATA  | SCTLR_EL1_ATA0 | ENDIAN_SET_EL1 |
> SCTLR_EL1_UCI   | \
> -	 SCTLR_EL1_EPAN | SCTLR_EL1_RES1)
> +	 ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_EPAN |
> SCTLR_EL1_RES1)
> 
>  /* MAIR_ELx memory attributes (used by Linux) */
>  #define MAIR_ATTR_DEVICE_nGnRnE		UL(0x00)
> diff --git a/arch/arm64/kernel/cpufeature.c
> b/arch/arm64/kernel/cpufeature.c
> index 9035c367d08b..23b1e3d83603 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1841,6 +1841,9 @@ static void bti_enable(const struct
> arm64_cpu_capabilities *__unused)
>  #ifdef CONFIG_ARM64_MTE
>  static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
>  {
> +	sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0);
> +	isb();
> +
>  	/*
>  	 * Clear the tags in the zero page. This needs to be done via
> the
>  	 * linear map which has the Tagged attribute.
> 

From ikjn at chromium.org  Mon Aug  2 23:05:18 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Tue, 3 Aug 2021 14:05:18 +0800
Subject: [PATCH 08/11] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <1627635002-24521-8-git-send-email-chunfeng.yun@mediatek.com>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
 <1627635002-24521-8-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <CAATdQgDWkohpzgr=z+uzro4m9Bd=v88DNnJ-M88-5-0annhH_w@mail.gmail.com>

Hi Chunfeng,

On Fri, Jul 30, 2021 at 4:51 PM Chunfeng Yun <chunfeng.yun at mediatek.com> wrote:
>
> Use @bw_budget_table[] to update fs bus bandwidth due to
> not all microframes consume @bw_cost_per_microframe, see
> setup_sch_info().
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
>  1 file changed, 7 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
> index 0bb1a6295d64..10c0f0f6461f 100644
> --- a/drivers/usb/host/xhci-mtk-sch.c
> +++ b/drivers/usb/host/xhci-mtk-sch.c
> @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
>                  * Compared with hs bus, no matter what ep type,
>                  * the hub will always delay one uframe to send data
>                  */
> -               for (j = 0; j < sch_ep->cs_count; j++) {
> -                       tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
> +               for (j = 0; j < sch_ep->num_budget_microframes; j++) {
> +                       tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j];
>                         if (tmp > FS_PAYLOAD_MAX)
>                                 return -ESCH_BW_OVERFLOW;
>                 }
> @@ -534,21 +534,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
>  {
>         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
>         u32 base, num_esit;
> -       int bw_updated;
>         int i, j;
>
>         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
>
> -       if (used)
> -               bw_updated = sch_ep->bw_cost_per_microframe;
> -       else
> -               bw_updated = -sch_ep->bw_cost_per_microframe;
> -
>         for (i = 0; i < num_esit; i++) {
>                 base = sch_ep->offset + i * sch_ep->esit;
>
> -               for (j = 0; j < sch_ep->cs_count; j++)
> -                       tt->fs_bus_bw[base + j] += bw_updated;
> +               for (j = 0; j < sch_ep->num_budget_microframes; j++)
> +                       if (used)
> +                               tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j];
> +                       else
> +                               tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j];

I agree that xhci-mtk-sch still has more rooms for tt periodic bandwidth
but I think this approach could trigger a problem.

for example, if there are two endpoints scheduled in the same u-frame index,
* ep1out  = iso 192bytes bw_budget_table[] = { 188, 188, 0, ...} --> y0
* ep2in = int 64bytes, bw_budget_table[] = { 0, 0, 64, ... }  --> y0

(If this is possible allocation from this patch),
I guess xhci-mtk could have some problems on internal scheduling?

>         }
>
>         if (used)

> --
> 2.18.0
>


From mudongliangabcd at gmail.com  Mon Aug  2 23:06:43 2021
From: mudongliangabcd at gmail.com (Dongliang Mu)
Date: Tue, 3 Aug 2021 14:06:43 +0800
Subject: [PATCH] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <CAD-N9QWvR-7caWCnk1CMo8sWPEC=CfKU2_v=YkTVr0o5L7wehA@mail.gmail.com>
References: <20210726152724.2281408-1-mudongliangabcd@gmail.com>
 <YQg4lehajLpQjyPd@Red>
 <CAD-N9QWvR-7caWCnk1CMo8sWPEC=CfKU2_v=YkTVr0o5L7wehA@mail.gmail.com>
Message-ID: <CAD-N9QVfreHCV7673DVq6aS3+3RYQ4-x8eZuGF0pvUbRhTL-Cg@mail.gmail.com>

On Tue, Aug 3, 2021 at 1:57 PM Dongliang Mu <mudongliangabcd at gmail.com> wrote:
>
> On Tue, Aug 3, 2021 at 2:25 AM Corentin Labbe <clabbe.montjoie at gmail.com> wrote:
> >
> > Le Mon, Jul 26, 2021 at 11:27:12PM +0800, Dongliang Mu a ?crit :
> > > In sun8i_ce_hash_run, all the dma_mmap_sg/single will cause memory leak
> > > due to no corresponding unmap operation if errors happen.
> > >
> > > Fix this by adding error handling part for all the dma_mmap_sg/single.
> > >
> >
> > I think it could be better worded, error handling is already there (but bad).
>
> Sure. How about "Fix this by freeing the objects allocated by
> dma_mmap_sg/single when errors occur."?
>
> >
> > > Fixes: 56f6d5aee88d ("crypto: sun8i-ce - support hash algorithms")
> > > Signed-off-by: Dongliang Mu <mudongliangabcd at gmail.com>
> > > ---
> > >  .../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 28 +++++++++----------
> > >  1 file changed, 13 insertions(+), 15 deletions(-)
> > >
> > > diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> > > index 88194718a806..d454ad99deee 100644
> > > --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> > > +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
> > > @@ -286,16 +286,14 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> > >
> > >       /* the padding could be up to two block. */
> > >       buf = kzalloc(bs * 2, GFP_KERNEL | GFP_DMA);
> > > -     if (!buf) {
> > > -             err = -ENOMEM;
> > > -             goto theend;
> >
> > Please keep all goto error for being consistent.
>
> OK, no problem.
>
> BTW, usually for the 1st malloc failure, I prefer returning with errno directly.

For this case, as crypto_finalize_hash_request must be executed, so
directly return is incorrect. I will add a goto label before
crypto_finalize_hash_request.

>
> >
> > > -     }
> > > +     if (!buf)
> > > +             return -ENOMEM;
> > >       bf = (__le32 *)buf;
> > >
> > >       result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
> > >       if (!result) {
> > > -             err = -ENOMEM;
> > > -             goto theend;
> > > +             kfree(buf);
> > > +             return -ENOMEM;
> > >       }
> > >
> > >       flow = rctx->flow;
> > > @@ -321,7 +319,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> > >       if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
> > >               dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
> > >               err = -EINVAL;
> > > -             goto theend;
> > > +             goto err_result;
> > >       }
> > >
> > >       len = areq->nbytes;
> > > @@ -334,7 +332,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> > >       if (len > 0) {
> > >               dev_err(ce->dev, "remaining len %d\n", len);
> > >               err = -EINVAL;
> > > -             goto theend;
> > > +             goto err_unmap_sg;
> > >       }
> > >       addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE);
> > >       cet->t_dst[0].addr = cpu_to_le32(addr_res);
> > > @@ -342,7 +340,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> > >       if (dma_mapping_error(ce->dev, addr_res)) {
> > >               dev_err(ce->dev, "DMA map dest\n");
> > >               err = -EINVAL;
> > > -             goto theend;
> > > +             goto err_unmap_sg;
> > >       }
> > >
> > >       byte_count = areq->nbytes;
> > > @@ -392,7 +390,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> > >       if (dma_mapping_error(ce->dev, addr_pad)) {
> > >               dev_err(ce->dev, "DMA error on padding SG\n");
> > >               err = -EINVAL;
> > > -             goto theend;
> > > +             goto err_addr_res;
> > >       }
> > >
> > >       if (ce->variant->hash_t_dlen_in_bits)
> > > @@ -405,15 +403,15 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
> > >       err = sun8i_ce_run_task(ce, flow, crypto_tfm_alg_name(areq->base.tfm));
> > >
> > >       dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE);
> > > +err_addr_res:
> > > +     dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> > > +err_unmap_sg:
> > >       dma_unmap_sg(ce->dev, areq->src, sg_nents(areq->src),
> > >                    DMA_TO_DEVICE);
> > > -     dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
> > > -
> > > -
> > >       memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
> >
> > The result should be copied only when everything is ok. Please add a "if (!err)"
>
> Sure.
>
> >
> > Thanks for your work
> > Regards


From mudongliangabcd at gmail.com  Mon Aug  2 23:31:38 2021
From: mudongliangabcd at gmail.com (Dongliang Mu)
Date: Tue,  3 Aug 2021 14:31:38 +0800
Subject: [PATCH v2] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
Message-ID: <20210803063149.2821093-1-mudongliangabcd@gmail.com>

In sun8i_ce_hash_run, all the dma_mmap_sg/single will cause memory leak
due to no corresponding unmap operation if errors happen.

Fix this by freeing the objects allocated bydma_mmap_sg/single
when errors occur.

Fixes: 56f6d5aee88d ("crypto: sun8i-ce - support hash algorithms")
Signed-off-by: Dongliang Mu <mudongliangabcd at gmail.com>
---
v1->v2: fix some wording and keep error handling code consistent
 .../crypto/allwinner/sun8i-ce/sun8i-ce-hash.c | 27 ++++++++++---------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
index 88194718a806..05bb781da701 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
@@ -288,14 +288,14 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
 	buf = kzalloc(bs * 2, GFP_KERNEL | GFP_DMA);
 	if (!buf) {
 		err = -ENOMEM;
-		goto theend;
+		goto out;
 	}
 	bf = (__le32 *)buf;
 
 	result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
 	if (!result) {
 		err = -ENOMEM;
-		goto theend;
+		goto err_buf;
 	}
 
 	flow = rctx->flow;
@@ -321,7 +321,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
 	if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
 		dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
 		err = -EINVAL;
-		goto theend;
+		goto err_result;
 	}
 
 	len = areq->nbytes;
@@ -334,7 +334,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
 	if (len > 0) {
 		dev_err(ce->dev, "remaining len %d\n", len);
 		err = -EINVAL;
-		goto theend;
+		goto err_unmap_sg;
 	}
 	addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE);
 	cet->t_dst[0].addr = cpu_to_le32(addr_res);
@@ -342,7 +342,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
 	if (dma_mapping_error(ce->dev, addr_res)) {
 		dev_err(ce->dev, "DMA map dest\n");
 		err = -EINVAL;
-		goto theend;
+		goto err_unmap_sg;
 	}
 
 	byte_count = areq->nbytes;
@@ -392,7 +392,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
 	if (dma_mapping_error(ce->dev, addr_pad)) {
 		dev_err(ce->dev, "DMA error on padding SG\n");
 		err = -EINVAL;
-		goto theend;
+		goto err_addr_res;
 	}
 
 	if (ce->variant->hash_t_dlen_in_bits)
@@ -405,15 +405,18 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
 	err = sun8i_ce_run_task(ce, flow, crypto_tfm_alg_name(areq->base.tfm));
 
 	dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE);
+err_addr_res:
+	dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
+err_unmap_sg:
 	dma_unmap_sg(ce->dev, areq->src, sg_nents(areq->src),
 		     DMA_TO_DEVICE);
-	dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
-
-
 	memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
-theend:
-	kfree(buf);
+err_result:
 	kfree(result);
-	crypto_finalize_hash_request(engine, breq, err);
+err_buf:
+	kfree(buf);
+out:
+	if (!err)
+		crypto_finalize_hash_request(engine, breq, err);
 	return 0;
 }
-- 
2.25.1



From hsin-hsiung.wang at mediatek.com  Mon Aug  2 23:34:21 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 3 Aug 2021 14:34:21 +0800
Subject: [PATCH v10 5/5] arm64: dts: mt8192: add spmi node
In-Reply-To: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1627972461-2627-6-git-send-email-hsin-hsiung.wang@mediatek.com>

Add spmi node to SOC MT8192.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
---
changes since v9:
- No change.
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 9810f1d441da..1237e3624e44 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -316,6 +316,23 @@
 			clock-names = "clk13m";
 		};
 
+		spmi: spmi at 10027000 {
+			compatible = "mediatek,mt6873-spmi";
+			reg = <0 0x10027000 0 0x000e00>,
+			      <0 0x10029000 0 0x000100>;
+			reg-names = "pmif", "spmimst";
+			clocks = <&infracfg CLK_INFRA_PMIC_AP>,
+				 <&infracfg CLK_INFRA_PMIC_TMR>,
+				 <&topckgen CLK_TOP_SPMI_MST_SEL>;
+			clock-names = "pmif_sys_ck",
+				      "pmif_tmr_ck",
+				      "spmimst_clk_mux";
+			assigned-clocks = <&topckgen CLK_TOP_PWRAP_ULPOSC_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_OSC_D10>;
+			#address-cells = <2>;
+			#size-cells = <0>;
+		};
+
 		scp_adsp: clock-controller at 10720000 {
 			compatible = "mediatek,mt8192-scp_adsp";
 			reg = <0 0x10720000 0 0x1000>;
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Mon Aug  2 23:34:19 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 3 Aug 2021 14:34:19 +0800
Subject: [PATCH v10 3/5] spmi: mediatek: Add support for MT6873/8192
In-Reply-To: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1627972461-2627-4-git-send-email-hsin-hsiung.wang@mediatek.com>

Add spmi support for MT6873/8192.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
---
changes since v9:
- No change.
---
 drivers/spmi/Kconfig         |  10 +
 drivers/spmi/Makefile        |   2 +
 drivers/spmi/spmi-mtk-pmif.c | 465 +++++++++++++++++++++++++++++++++++
 3 files changed, 477 insertions(+)
 create mode 100644 drivers/spmi/spmi-mtk-pmif.c

diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index 2874b6c26028..ea5703f6e544 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -34,4 +34,14 @@ config SPMI_MSM_PMIC_ARB
 	  This is required for communicating with Qualcomm PMICs and
 	  other devices that have the SPMI interface.
 
+config SPMI_MTK_PMIF
+	tristate "Mediatek SPMI Controller (PMIC Arbiter)"
+	help
+	  If you say yes to this option, support will be included for the
+	  built-in SPMI PMIC Arbiter interface on Mediatek family
+	  processors.
+
+	  This is required for communicating with Mediatek PMICs and
+	  other devices that have the SPMI interface.
+
 endif
diff --git a/drivers/spmi/Makefile b/drivers/spmi/Makefile
index 6e092e6f290c..0b21aaffcbb9 100644
--- a/drivers/spmi/Makefile
+++ b/drivers/spmi/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_SPMI)	+= spmi.o
 
 obj-$(CONFIG_SPMI_HISI3670)	+= hisi-spmi-controller.o
 obj-$(CONFIG_SPMI_MSM_PMIC_ARB)	+= spmi-pmic-arb.o
+obj-$(CONFIG_SPMI_MTK_PMIF)	+= spmi-mtk-pmif.o
+
diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
new file mode 100644
index 000000000000..94c45d46ab0c
--- /dev/null
+++ b/drivers/spmi/spmi-mtk-pmif.c
@@ -0,0 +1,465 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2021 MediaTek Inc.
+
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/spmi.h>
+
+#define SWINF_IDLE	0x00
+#define SWINF_WFVLDCLR	0x06
+
+#define GET_SWINF(x)	(((x) >> 1) & 0x7)
+
+#define PMIF_CMD_REG_0		0
+#define PMIF_CMD_REG		1
+#define PMIF_CMD_EXT_REG	2
+#define PMIF_CMD_EXT_REG_LONG	3
+
+#define PMIF_DELAY_US   10
+#define PMIF_TIMEOUT_US (10 * 1000)
+
+#define PMIF_CHAN_OFFSET 0x5
+
+#define PMIF_MAX_CLKS	3
+
+#define SPMI_OP_ST_BUSY 1
+
+struct ch_reg {
+	u32 ch_sta;
+	u32 wdata;
+	u32 rdata;
+	u32 ch_send;
+	u32 ch_rdy;
+};
+
+struct pmif_data {
+	const u32	*regs;
+	const u32	*spmimst_regs;
+	u32	soc_chan;
+};
+
+struct pmif {
+	void __iomem	*base;
+	void __iomem	*spmimst_base;
+	struct ch_reg	chan;
+	struct clk_bulk_data clks[PMIF_MAX_CLKS];
+	u32 nclks;
+	const struct pmif_data *data;
+};
+
+static const char * const pmif_clock_names[] = {
+	"pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux",
+};
+
+enum pmif_regs {
+	PMIF_INIT_DONE,
+	PMIF_INF_EN,
+	PMIF_ARB_EN,
+	PMIF_CMDISSUE_EN,
+	PMIF_TIMER_CTRL,
+	PMIF_SPI_MODE_CTRL,
+	PMIF_IRQ_EVENT_EN_0,
+	PMIF_IRQ_FLAG_0,
+	PMIF_IRQ_CLR_0,
+	PMIF_IRQ_EVENT_EN_1,
+	PMIF_IRQ_FLAG_1,
+	PMIF_IRQ_CLR_1,
+	PMIF_IRQ_EVENT_EN_2,
+	PMIF_IRQ_FLAG_2,
+	PMIF_IRQ_CLR_2,
+	PMIF_IRQ_EVENT_EN_3,
+	PMIF_IRQ_FLAG_3,
+	PMIF_IRQ_CLR_3,
+	PMIF_IRQ_EVENT_EN_4,
+	PMIF_IRQ_FLAG_4,
+	PMIF_IRQ_CLR_4,
+	PMIF_WDT_EVENT_EN_0,
+	PMIF_WDT_FLAG_0,
+	PMIF_WDT_EVENT_EN_1,
+	PMIF_WDT_FLAG_1,
+	PMIF_SWINF_0_STA,
+	PMIF_SWINF_0_WDATA_31_0,
+	PMIF_SWINF_0_RDATA_31_0,
+	PMIF_SWINF_0_ACC,
+	PMIF_SWINF_0_VLD_CLR,
+	PMIF_SWINF_1_STA,
+	PMIF_SWINF_1_WDATA_31_0,
+	PMIF_SWINF_1_RDATA_31_0,
+	PMIF_SWINF_1_ACC,
+	PMIF_SWINF_1_VLD_CLR,
+	PMIF_SWINF_2_STA,
+	PMIF_SWINF_2_WDATA_31_0,
+	PMIF_SWINF_2_RDATA_31_0,
+	PMIF_SWINF_2_ACC,
+	PMIF_SWINF_2_VLD_CLR,
+	PMIF_SWINF_3_STA,
+	PMIF_SWINF_3_WDATA_31_0,
+	PMIF_SWINF_3_RDATA_31_0,
+	PMIF_SWINF_3_ACC,
+	PMIF_SWINF_3_VLD_CLR,
+};
+
+static const u32 mt6873_regs[] = {
+	[PMIF_INIT_DONE] =	0x0000,
+	[PMIF_INF_EN] =		0x0024,
+	[PMIF_ARB_EN] =		0x0150,
+	[PMIF_CMDISSUE_EN] =	0x03B4,
+	[PMIF_TIMER_CTRL] =	0x03E0,
+	[PMIF_SPI_MODE_CTRL] =	0x0400,
+	[PMIF_IRQ_EVENT_EN_0] =	0x0418,
+	[PMIF_IRQ_FLAG_0] =	0x0420,
+	[PMIF_IRQ_CLR_0] =	0x0424,
+	[PMIF_IRQ_EVENT_EN_1] =	0x0428,
+	[PMIF_IRQ_FLAG_1] =	0x0430,
+	[PMIF_IRQ_CLR_1] =	0x0434,
+	[PMIF_IRQ_EVENT_EN_2] =	0x0438,
+	[PMIF_IRQ_FLAG_2] =	0x0440,
+	[PMIF_IRQ_CLR_2] =	0x0444,
+	[PMIF_IRQ_EVENT_EN_3] =	0x0448,
+	[PMIF_IRQ_FLAG_3] =	0x0450,
+	[PMIF_IRQ_CLR_3] =	0x0454,
+	[PMIF_IRQ_EVENT_EN_4] =	0x0458,
+	[PMIF_IRQ_FLAG_4] =	0x0460,
+	[PMIF_IRQ_CLR_4] =	0x0464,
+	[PMIF_WDT_EVENT_EN_0] =	0x046C,
+	[PMIF_WDT_FLAG_0] =	0x0470,
+	[PMIF_WDT_EVENT_EN_1] =	0x0474,
+	[PMIF_WDT_FLAG_1] =	0x0478,
+	[PMIF_SWINF_0_ACC] =	0x0C00,
+	[PMIF_SWINF_0_WDATA_31_0] =	0x0C04,
+	[PMIF_SWINF_0_RDATA_31_0] =	0x0C14,
+	[PMIF_SWINF_0_VLD_CLR] =	0x0C24,
+	[PMIF_SWINF_0_STA] =	0x0C28,
+	[PMIF_SWINF_1_ACC] =	0x0C40,
+	[PMIF_SWINF_1_WDATA_31_0] =	0x0C44,
+	[PMIF_SWINF_1_RDATA_31_0] =	0x0C54,
+	[PMIF_SWINF_1_VLD_CLR] =	0x0C64,
+	[PMIF_SWINF_1_STA] =	0x0C68,
+	[PMIF_SWINF_2_ACC] =	0x0C80,
+	[PMIF_SWINF_2_WDATA_31_0] =	0x0C84,
+	[PMIF_SWINF_2_RDATA_31_0] =	0x0C94,
+	[PMIF_SWINF_2_VLD_CLR] =	0x0CA4,
+	[PMIF_SWINF_2_STA] =	0x0CA8,
+	[PMIF_SWINF_3_ACC] =	0x0CC0,
+	[PMIF_SWINF_3_WDATA_31_0] =	0x0CC4,
+	[PMIF_SWINF_3_RDATA_31_0] =	0x0CD4,
+	[PMIF_SWINF_3_VLD_CLR] =	0x0CE4,
+	[PMIF_SWINF_3_STA] =	0x0CE8,
+};
+
+enum spmi_regs {
+	SPMI_OP_ST_CTRL,
+	SPMI_GRP_ID_EN,
+	SPMI_OP_ST_STA,
+	SPMI_MST_SAMPL,
+	SPMI_MST_REQ_EN,
+	SPMI_REC_CTRL,
+	SPMI_REC0,
+	SPMI_REC1,
+	SPMI_REC2,
+	SPMI_REC3,
+	SPMI_REC4,
+	SPMI_MST_DBG,
+};
+
+static const u32 mt6873_spmi_regs[] = {
+	[SPMI_OP_ST_CTRL] =	0x0000,
+	[SPMI_GRP_ID_EN] =	0x0004,
+	[SPMI_OP_ST_STA] =	0x0008,
+	[SPMI_MST_SAMPL] =	0x000c,
+	[SPMI_MST_REQ_EN] =	0x0010,
+	[SPMI_REC_CTRL] =	0x0040,
+	[SPMI_REC0] =		0x0044,
+	[SPMI_REC1] =		0x0048,
+	[SPMI_REC2] =		0x004c,
+	[SPMI_REC3] =		0x0050,
+	[SPMI_REC4] =		0x0054,
+	[SPMI_MST_DBG] =	0x00fc,
+};
+
+static u32 pmif_readl(struct pmif *arb, enum pmif_regs reg)
+{
+	return readl(arb->base + arb->data->regs[reg]);
+}
+
+static void pmif_writel(struct pmif *arb, u32 val, enum pmif_regs reg)
+{
+	writel(val, arb->base + arb->data->regs[reg]);
+}
+
+static void mtk_spmi_writel(struct pmif *arb, u32 val, enum spmi_regs reg)
+{
+	writel(val, arb->spmimst_base + arb->data->spmimst_regs[reg]);
+}
+
+static bool pmif_is_fsm_vldclr(struct pmif *arb)
+{
+	u32 reg_rdata;
+
+	reg_rdata = pmif_readl(arb, arb->chan.ch_sta);
+	return GET_SWINF(reg_rdata) == SWINF_WFVLDCLR;
+}
+
+static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
+{
+	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+	u32 rdata, cmd;
+	int ret;
+
+	/* Check the opcode */
+	if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
+		return -EINVAL;
+
+	cmd = opc - SPMI_CMD_RESET;
+
+	mtk_spmi_writel(arb, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL);
+	ret = readl_poll_timeout_atomic(arb->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA],
+					rdata, (rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY,
+					PMIF_DELAY_US, PMIF_TIMEOUT_US);
+	if (ret < 0)
+		dev_err(&ctrl->dev, "timeout, err = %d\n", ret);
+
+	return ret;
+}
+
+static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+			      u16 addr, u8 *buf, size_t len)
+{
+	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+	struct ch_reg *inf_reg;
+	int ret;
+	u32 data, cmd;
+
+	/* Check for argument validation. */
+	if (sid & ~0xf) {
+		dev_err(&ctrl->dev, "exceed the max slv id\n");
+		return -EINVAL;
+	}
+
+	if (len > 4) {
+		dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
+		return -EINVAL;
+	}
+
+	if (opc >= 0x60 && opc <= 0x7f)
+		opc = PMIF_CMD_REG;
+	else if ((opc >= 0x20 && opc <= 0x2f) || (opc >= 0x38 && opc <= 0x3f))
+		opc = PMIF_CMD_EXT_REG_LONG;
+	else
+		return -EINVAL;
+
+	/* Wait for Software Interface FSM state to be IDLE. */
+	inf_reg = &arb->chan;
+	ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
+					data, GET_SWINF(data) == SWINF_IDLE,
+					PMIF_DELAY_US, PMIF_TIMEOUT_US);
+	if (ret < 0) {
+		/* set channel ready if the data has transferred */
+		if (pmif_is_fsm_vldclr(arb))
+			pmif_writel(arb, 1, inf_reg->ch_rdy);
+		dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
+		goto out;
+	}
+
+	/* Send the command. */
+	cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr;
+	pmif_writel(arb, cmd, inf_reg->ch_send);
+
+	/*
+	 * Wait for Software Interface FSM state to be WFVLDCLR,
+	 * read the data and clear the valid flag.
+	 */
+	ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
+					data, GET_SWINF(data) == SWINF_WFVLDCLR,
+					PMIF_DELAY_US, PMIF_TIMEOUT_US);
+	if (ret < 0) {
+		dev_err(&ctrl->dev, "failed to wait for SWINF_WFVLDCLR\n");
+		goto out;
+	}
+
+	data = pmif_readl(arb, inf_reg->rdata);
+	memcpy(buf, &data, len);
+	pmif_writel(arb, 1, inf_reg->ch_rdy);
+
+out:
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+			       u16 addr, const u8 *buf, size_t len)
+{
+	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+	struct ch_reg *inf_reg;
+	int ret;
+	u32 data, cmd;
+
+	if (len > 4) {
+		dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
+		return -EINVAL;
+	}
+
+	/* Check the opcode */
+	if (opc >= 0x40 && opc <= 0x5F)
+		opc = PMIF_CMD_REG;
+	else if ((opc <= 0xF) || (opc >= 0x30 && opc <= 0x37))
+		opc = PMIF_CMD_EXT_REG_LONG;
+	else if (opc >= 0x80)
+		opc = PMIF_CMD_REG_0;
+	else
+		return -EINVAL;
+
+	/* Wait for Software Interface FSM state to be IDLE. */
+	inf_reg = &arb->chan;
+	ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
+					data, GET_SWINF(data) == SWINF_IDLE,
+					PMIF_DELAY_US, PMIF_TIMEOUT_US);
+	if (ret < 0) {
+		/* set channel ready if the data has transferred */
+		if (pmif_is_fsm_vldclr(arb))
+			pmif_writel(arb, 1, inf_reg->ch_rdy);
+		dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
+		goto out;
+	}
+
+	/* Set the write data. */
+	memcpy(&data, buf, len);
+	pmif_writel(arb, data, inf_reg->wdata);
+
+	/* Send the command. */
+	cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr;
+	pmif_writel(arb, cmd, inf_reg->ch_send);
+
+out:
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static const struct pmif_data mt6873_pmif_arb = {
+	.regs = mt6873_regs,
+	.spmimst_regs = mt6873_spmi_regs,
+	.soc_chan = 2,
+};
+
+static int mtk_spmi_probe(struct platform_device *pdev)
+{
+	struct pmif *arb;
+	struct spmi_controller *ctrl;
+	int err, i;
+	u32 chan_offset;
+
+	ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*arb));
+	if (!ctrl)
+		return -ENOMEM;
+
+	arb = spmi_controller_get_drvdata(ctrl);
+	arb->data = of_device_get_match_data(&pdev->dev);
+	if (!arb->data) {
+		err = -EINVAL;
+		dev_err(&pdev->dev, "Cannot get drv_data\n");
+		goto err_put_ctrl;
+	}
+
+	arb->base = devm_platform_ioremap_resource_byname(pdev, "pmif");
+	if (IS_ERR(arb->base)) {
+		err = PTR_ERR(arb->base);
+		dev_err(&pdev->dev, "pmif failed to get the remappped memory\n");
+		goto err_put_ctrl;
+	}
+
+	arb->spmimst_base = devm_platform_ioremap_resource_byname(pdev, "spmimst");
+	if (IS_ERR(arb->spmimst_base)) {
+		err = PTR_ERR(arb->spmimst_base);
+		dev_err(&pdev->dev, "spmimst failed to get the remappped memory\n");
+		goto err_put_ctrl;
+	}
+
+	arb->nclks = ARRAY_SIZE(pmif_clock_names);
+	if (arb->nclks > PMIF_MAX_CLKS) {
+		err = -EINVAL;
+		dev_err(&pdev->dev, "exceed the max clock numbers\n");
+		goto err_put_ctrl;
+	}
+
+	for (i = 0; i < arb->nclks; i++)
+		arb->clks[i].id = pmif_clock_names[i];
+
+	err = devm_clk_bulk_get(&pdev->dev, arb->nclks, arb->clks);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to get clocks: %d\n", err);
+		goto err_put_ctrl;
+	}
+
+	err = clk_bulk_prepare_enable(arb->nclks, arb->clks);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to enable clocks: %d\n", err);
+		goto err_put_ctrl;
+	}
+
+	ctrl->cmd = pmif_arb_cmd;
+	ctrl->read_cmd = pmif_spmi_read_cmd;
+	ctrl->write_cmd = pmif_spmi_write_cmd;
+
+	chan_offset = PMIF_CHAN_OFFSET * arb->data->soc_chan;
+	arb->chan.ch_sta = PMIF_SWINF_0_STA + chan_offset;
+	arb->chan.wdata = PMIF_SWINF_0_WDATA_31_0 + chan_offset;
+	arb->chan.rdata = PMIF_SWINF_0_RDATA_31_0 + chan_offset;
+	arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset;
+	arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset;
+
+	platform_set_drvdata(pdev, ctrl);
+
+	err = spmi_controller_add(ctrl);
+	if (err)
+		goto err_domain_remove;
+
+	return 0;
+
+err_domain_remove:
+	clk_bulk_disable_unprepare(arb->nclks, arb->clks);
+err_put_ctrl:
+	spmi_controller_put(ctrl);
+	return err;
+}
+
+static int mtk_spmi_remove(struct platform_device *pdev)
+{
+	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
+	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+
+	clk_bulk_disable_unprepare(arb->nclks, arb->clks);
+	spmi_controller_remove(ctrl);
+	spmi_controller_put(ctrl);
+	return 0;
+}
+
+static const struct of_device_id mtk_spmi_match_table[] = {
+	{
+		.compatible = "mediatek,mt6873-spmi",
+		.data = &mt6873_pmif_arb,
+	}, {
+		/* sentinel */
+	},
+};
+MODULE_DEVICE_TABLE(of, mtk_spmi_match_table);
+
+static struct platform_driver mtk_spmi_driver = {
+	.driver		= {
+		.name	= "spmi-mtk",
+		.of_match_table = of_match_ptr(mtk_spmi_match_table),
+	},
+	.probe		= mtk_spmi_probe,
+	.remove		= mtk_spmi_remove,
+};
+module_platform_driver(mtk_spmi_driver);
+
+MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>");
+MODULE_DESCRIPTION("MediaTek SPMI Driver");
+MODULE_LICENSE("GPL");
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Mon Aug  2 23:34:18 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 3 Aug 2021 14:34:18 +0800
Subject: [PATCH v10 2/5] dt-bindings: spmi: document binding for the Mediatek
 SPMI controller
In-Reply-To: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1627972461-2627-3-git-send-email-hsin-hsiung.wang@mediatek.com>

This adds documentation for the SPMI controller found on Mediatek SoCs.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
changes since v9:
- No change.
---
 .../bindings/spmi/mtk,spmi-mtk-pmif.yaml      | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml

diff --git a/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml b/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml
new file mode 100644
index 000000000000..a221cc1ac6c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spmi/mtk,spmi-mtk-pmif.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek SPMI Controller Device Tree Bindings
+
+maintainers:
+  - Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
+
+description: |+
+  On MediaTek SoCs the PMIC is connected via SPMI and the controller allows
+  for multiple SoCs to control a single SPMI master.
+
+allOf:
+  - $ref: "spmi.yaml"
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt6873-spmi
+      - mediatek,mt8195-spmi
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pmif
+      - const: spmimst
+
+  clocks:
+    minItems: 3
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: pmif_sys_ck
+      - const: pmif_tmr_ck
+      - const: spmimst_clk_mux
+
+  assigned-clocks:
+    maxItems: 1
+
+  assigned-clock-parents:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8192-clk.h>
+
+    spmi: spmi at 10027000 {
+        compatible = "mediatek,mt6873-spmi";
+        reg = <0 0x10027000 0 0x000e00>,
+              <0 0x10029000 0 0x000100>;
+        reg-names = "pmif", "spmimst";
+        clocks = <&infracfg CLK_INFRA_PMIC_AP>,
+                 <&infracfg CLK_INFRA_PMIC_TMR>,
+                 <&topckgen CLK_TOP_SPMI_MST_SEL>;
+        clock-names = "pmif_sys_ck",
+                      "pmif_tmr_ck",
+                      "spmimst_clk_mux";
+        assigned-clocks = <&topckgen CLK_TOP_PWRAP_ULPOSC_SEL>;
+        assigned-clock-parents = <&topckgen CLK_TOP_OSC_D10>;
+    };
+...
-- 
2.18.0

From rppt at kernel.org  Mon Aug  2 23:42:18 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Tue,  3 Aug 2021 09:42:18 +0300
Subject: [PATCH v3] memblock: make memblock_find_in_range method private
Message-ID: <20210803064218.6611-1-rppt@kernel.org>

From: Mike Rapoport <rppt at linux.ibm.com>

There are a lot of uses of memblock_find_in_range() along with
memblock_reserve() from the times memblock allocation APIs did not exist.

memblock_find_in_range() is the very core of memblock allocations, so any
future changes to its internal behaviour would mandate updates of all the
users outside memblock.

Replace the calls to memblock_find_in_range() with an equivalent calls to
memblock_phys_alloc() and memblock_phys_alloc_range() and make
memblock_find_in_range() private method of memblock.

This simplifies the callers, ensures that (unlikely) errors in
memblock_reserve() are handled and improves maintainability of
memblock_find_in_range().

Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
---
v3:
* simplify check for exact crash kerenl allocation on arm, per Rob
* make crash_max unsigned long long on arm64, per Rob
 
v2: https://lore.kernel.org/lkml/20210802063737.22733-1-rppt at kernel.org 
* don't change error message in arm::reserve_crashkernel(), per Russell

v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org

 arch/arm/kernel/setup.c           | 20 +++++---------
 arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
 arch/arm64/mm/init.c              | 36 ++++++++-----------------
 arch/mips/kernel/setup.c          | 14 +++++-----
 arch/riscv/mm/init.c              | 44 ++++++++++---------------------
 arch/s390/kernel/setup.c          | 10 ++++---
 arch/x86/kernel/aperture_64.c     |  5 ++--
 arch/x86/mm/init.c                | 21 +++++++++------
 arch/x86/mm/numa.c                |  5 ++--
 arch/x86/mm/numa_emulation.c      |  5 ++--
 arch/x86/realmode/init.c          |  2 +-
 drivers/acpi/tables.c             |  5 ++--
 drivers/base/arch_numa.c          |  5 +---
 drivers/of/of_reserved_mem.c      | 12 ++++++---
 include/linux/memblock.h          |  2 --
 mm/memblock.c                     |  2 +-
 16 files changed, 79 insertions(+), 118 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index f97eb2371672..284a80c0b6e1 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
 		unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
 		if (crash_max > lowmem_max)
 			crash_max = lowmem_max;
-		crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
-						    crash_size, CRASH_ALIGN);
+
+		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+						       CRASH_ALIGN, crash_max);
 		if (!crash_base) {
 			pr_err("crashkernel reservation failed - No suitable area found.\n");
 			return;
 		}
 	} else {
+		unsigned long long crash_max = crash_base + crash_size;
 		unsigned long long start;
 
-		start = memblock_find_in_range(crash_base,
-					       crash_base + crash_size,
-					       crash_size, SECTION_SIZE);
-		if (start != crash_base) {
+		start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
+						  crash_base, crash_max);
+		if (!start) {
 			pr_err("crashkernel reservation failed - memory is in use.\n");
 			return;
 		}
 	}
 
-	ret = memblock_reserve(crash_base, crash_size);
-	if (ret < 0) {
-		pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
-			(unsigned long)crash_base);
-		return;
-	}
-
 	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
 		(unsigned long)(crash_size >> 20),
 		(unsigned long)(crash_base >> 20),
diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c
index d654921dd09b..578670e3f608 100644
--- a/arch/arm64/kvm/hyp/reserved_mem.c
+++ b/arch/arm64/kvm/hyp/reserved_mem.c
@@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
 	 * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
 	 */
 	hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
-	hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
-					      ALIGN(hyp_mem_size, PMD_SIZE),
-					      PMD_SIZE);
+	hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
+					   PMD_SIZE);
 	if (!hyp_mem_base)
-		hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
-						      hyp_mem_size, PAGE_SIZE);
+		hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
 	else
 		hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
 
@@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
 		kvm_err("Failed to reserve hyp memory\n");
 		return;
 	}
-	memblock_reserve(hyp_mem_base, hyp_mem_size);
 
 	kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
 		 hyp_mem_base);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2917ff..0bffd2d1854f 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
 	unsigned long long crash_base, crash_size;
+	unsigned long long crash_max = arm64_dma_phys_limit;
 	int ret;
 
 	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
@@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
 
 	crash_size = PAGE_ALIGN(crash_size);
 
-	if (crash_base == 0) {
-		/* Current arm64 boot protocol requires 2MB alignment */
-		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
-				crash_size, SZ_2M);
-		if (crash_base == 0) {
-			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
-				crash_size);
-			return;
-		}
-	} else {
-		/* User specifies base address explicitly. */
-		if (!memblock_is_region_memory(crash_base, crash_size)) {
-			pr_warn("cannot reserve crashkernel: region is not memory\n");
-			return;
-		}
+	/* User specifies base address explicitly. */
+	if (crash_base)
+		crash_max = crash_base + crash_size;
 
-		if (memblock_is_region_reserved(crash_base, crash_size)) {
-			pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
-			return;
-		}
-
-		if (!IS_ALIGNED(crash_base, SZ_2M)) {
-			pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
-			return;
-		}
+	/* Current arm64 boot protocol requires 2MB alignment */
+	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
+					       crash_base, crash_max);
+	if (!crash_base) {
+		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
+			crash_size);
+		return;
 	}
-	memblock_reserve(crash_base, crash_size);
 
 	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 23a140327a0b..f979adfd4fc2 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -452,8 +452,9 @@ static void __init mips_parse_crashkernel(void)
 		return;
 
 	if (crash_base <= 0) {
-		crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX,
-							crash_size, CRASH_ALIGN);
+		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+						       CRASH_ALIGN,
+						       CRASH_ADDR_MAX);
 		if (!crash_base) {
 			pr_warn("crashkernel reservation failed - No suitable area found.\n");
 			return;
@@ -461,8 +462,9 @@ static void __init mips_parse_crashkernel(void)
 	} else {
 		unsigned long long start;
 
-		start = memblock_find_in_range(crash_base, crash_base + crash_size,
-						crash_size, 1);
+		start = memblock_phys_alloc_range(crash_size, 1,
+						  crash_base,
+						  crash_base + crash_size);
 		if (start != crash_base) {
 			pr_warn("Invalid memory region reserved for crash kernel\n");
 			return;
@@ -656,10 +658,6 @@ static void __init arch_mem_init(char **cmdline_p)
 	mips_reserve_vmcore();
 
 	mips_parse_crashkernel();
-#ifdef CONFIG_KEXEC
-	if (crashk_res.start != crashk_res.end)
-		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
-#endif
 	device_tree_init();
 
 	/*
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index a14bf3910eec..88649337c568 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -812,38 +812,22 @@ static void __init reserve_crashkernel(void)
 
 	crash_size = PAGE_ALIGN(crash_size);
 
-	if (crash_base == 0) {
-		/*
-		 * Current riscv boot protocol requires 2MB alignment for
-		 * RV64 and 4MB alignment for RV32 (hugepage size)
-		 */
-		crash_base = memblock_find_in_range(search_start, search_end,
-						    crash_size, PMD_SIZE);
-
-		if (crash_base == 0) {
-			pr_warn("crashkernel: couldn't allocate %lldKB\n",
-				crash_size >> 10);
-			return;
-		}
-	} else {
-		/* User specifies base address explicitly. */
-		if (!memblock_is_region_memory(crash_base, crash_size)) {
-			pr_warn("crashkernel: requested region is not memory\n");
-			return;
-		}
-
-		if (memblock_is_region_reserved(crash_base, crash_size)) {
-			pr_warn("crashkernel: requested region is reserved\n");
-			return;
-		}
-
+	if (crash_base) {
+		search_start = crash_base;
+		search_end = crash_base + crash_size;
+	}
 
-		if (!IS_ALIGNED(crash_base, PMD_SIZE)) {
-			pr_warn("crashkernel: requested region is misaligned\n");
-			return;
-		}
+	/*
+	 * Current riscv boot protocol requires 2MB alignment for
+	 * RV64 and 4MB alignment for RV32 (hugepage size)
+	 */
+	crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
+					       search_start, search_end);
+	if (crash_base == 0) {
+		pr_warn("crashkernel: couldn't allocate %lldKB\n",
+			crash_size >> 10);
+		return;
 	}
-	memblock_reserve(crash_base, crash_size);
 
 	pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index ff0f9e838916..3d9efee0f43c 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -626,8 +626,9 @@ static void __init reserve_crashkernel(void)
 			return;
 		}
 		low = crash_base ?: low;
-		crash_base = memblock_find_in_range(low, high, crash_size,
-						    KEXEC_CRASH_MEM_ALIGN);
+		crash_base = memblock_phys_alloc_range(crash_size,
+						       KEXEC_CRASH_MEM_ALIGN,
+						       low, high);
 	}
 
 	if (!crash_base) {
@@ -636,14 +637,15 @@ static void __init reserve_crashkernel(void)
 		return;
 	}
 
-	if (register_memory_notifier(&kdump_mem_nb))
+	if (register_memory_notifier(&kdump_mem_nb)) {
+		memblock_free(crash_base, crash_size);
 		return;
+	}
 
 	if (!OLDMEM_BASE && MACHINE_IS_VM)
 		diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
 	crashk_res.start = crash_base;
 	crashk_res.end = crash_base + crash_size - 1;
-	memblock_remove(crash_base, crash_size);
 	pr_info("Reserving %lluMB of memory at %lluMB "
 		"for crashkernel (System RAM: %luMB)\n",
 		crash_size >> 20, crash_base >> 20,
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 294ed4392a0e..10562885f5fc 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -109,14 +109,13 @@ static u32 __init allocate_aperture(void)
 	 * memory. Unfortunately we cannot move it up because that would
 	 * make the IOMMU useless.
 	 */
-	addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR,
-				      aper_size, aper_size);
+	addr = memblock_phys_alloc_range(aper_size, aper_size,
+					 GART_MIN_ADDR, GART_MAX_ADDR);
 	if (!addr) {
 		pr_err("Cannot allocate aperture memory hole [mem %#010lx-%#010lx] (%uKB)\n",
 		       addr, addr + aper_size - 1, aper_size >> 10);
 		return 0;
 	}
-	memblock_reserve(addr, aper_size);
 	pr_info("Mapping aperture over RAM [mem %#010lx-%#010lx] (%uKB)\n",
 		addr, addr + aper_size - 1, aper_size >> 10);
 	register_nosave_region(addr >> PAGE_SHIFT,
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 75ef19aa8903..1152a29ce109 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -26,6 +26,7 @@
 #include <asm/pti.h>
 #include <asm/text-patching.h>
 #include <asm/memtype.h>
+#include <xen/xen.h>
 
 /*
  * We need to define the tracepoints somewhere, and tlb.c
@@ -127,14 +128,12 @@ __ref void *alloc_low_pages(unsigned int num)
 		unsigned long ret = 0;
 
 		if (min_pfn_mapped < max_pfn_mapped) {
-			ret = memblock_find_in_range(
+			ret = memblock_phys_alloc_range(
+					PAGE_SIZE * num, PAGE_SIZE,
 					min_pfn_mapped << PAGE_SHIFT,
-					max_pfn_mapped << PAGE_SHIFT,
-					PAGE_SIZE * num , PAGE_SIZE);
+					max_pfn_mapped << PAGE_SHIFT);
 		}
-		if (ret)
-			memblock_reserve(ret, PAGE_SIZE * num);
-		else if (can_use_brk_pgt)
+		if (!ret && can_use_brk_pgt)
 			ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE));
 
 		if (!ret)
@@ -610,9 +609,15 @@ static void __init memory_map_top_down(unsigned long map_start,
 	unsigned long addr;
 	unsigned long mapped_ram_size = 0;
 
+	real_end = ALIGN_DOWN(map_end, PMD_SIZE);
+
 	/* xen has big range in reserved near end of ram, skip it at first.*/
-	addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE);
-	real_end = addr + PMD_SIZE;
+	if (xen_domain()) {
+		addr = memblock_phys_alloc_range(PMD_SIZE, PMD_SIZE,
+						 map_start, map_end);
+		memblock_free(addr, PMD_SIZE);
+		real_end = addr + PMD_SIZE;
+	}
 
 	/* step_size need to be small so pgt_buf from BRK could cover it */
 	step_size = PMD_SIZE;
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index e94da744386f..a1b5c71099e6 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -376,15 +376,14 @@ static int __init numa_alloc_distance(void)
 	cnt++;
 	size = cnt * cnt * sizeof(numa_distance[0]);
 
-	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
-				      size, PAGE_SIZE);
+	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0,
+					 PFN_PHYS(max_pfn_mapped));
 	if (!phys) {
 		pr_warn("Warning: can't allocate distance table!\n");
 		/* don't retry until explicitly reset */
 		numa_distance = (void *)1LU;
 		return -ENOMEM;
 	}
-	memblock_reserve(phys, size);
 
 	numa_distance = __va(phys);
 	numa_distance_cnt = cnt;
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
index 87d77cc52f86..737491b13728 100644
--- a/arch/x86/mm/numa_emulation.c
+++ b/arch/x86/mm/numa_emulation.c
@@ -447,13 +447,12 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
 	if (numa_dist_cnt) {
 		u64 phys;
 
-		phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
-					      phys_size, PAGE_SIZE);
+		phys = memblock_phys_alloc_range(phys_size, PAGE_SIZE, 0,
+						 PFN_PHYS(max_pfn_mapped));
 		if (!phys) {
 			pr_warn("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
 			goto no_emu;
 		}
-		memblock_reserve(phys, phys_size);
 		phys_dist = __va(phys);
 
 		for (i = 0; i < numa_dist_cnt; i++)
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 6534c92d0f83..31b5856010cb 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -28,7 +28,7 @@ void __init reserve_real_mode(void)
 	WARN_ON(slab_is_available());
 
 	/* Has to be under 1M so we can execute real-mode AP code. */
-	mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
+	mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
 	if (!mem)
 		pr_info("No sub-1M memory is available for the trampoline\n");
 	else
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index a37a1532a575..f9383736fa0f 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -583,8 +583,8 @@ void __init acpi_table_upgrade(void)
 	}
 
 	acpi_tables_addr =
-		memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
-				       all_tables_size, PAGE_SIZE);
+		memblock_phys_alloc_range(all_tables_size, PAGE_SIZE,
+					  0, ACPI_TABLE_UPGRADE_MAX_PHYS);
 	if (!acpi_tables_addr) {
 		WARN_ON(1);
 		return;
@@ -599,7 +599,6 @@ void __init acpi_table_upgrade(void)
 	 * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
 	 * works fine.
 	 */
-	memblock_reserve(acpi_tables_addr, all_tables_size);
 	arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
 
 	/*
diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index 4cc4e117727d..46c503486e96 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -279,13 +279,10 @@ static int __init numa_alloc_distance(void)
 	int i, j;
 
 	size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
-	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
-				      size, PAGE_SIZE);
+	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, PFN_PHYS(max_pfn));
 	if (WARN_ON(!phys))
 		return -ENOMEM;
 
-	memblock_reserve(phys, size);
-
 	numa_distance = __va(phys);
 	numa_distance_cnt = nr_node_ids;
 
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index fd3964d24224..59c1390cdf42 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -33,18 +33,22 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
 	phys_addr_t *res_base)
 {
 	phys_addr_t base;
+	int err = 0;
 
 	end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
 	align = !align ? SMP_CACHE_BYTES : align;
-	base = memblock_find_in_range(start, end, size, align);
+	base = memblock_phys_alloc_range(size, align, start, end);
 	if (!base)
 		return -ENOMEM;
 
 	*res_base = base;
-	if (nomap)
-		return memblock_mark_nomap(base, size);
+	if (nomap) {
+		err = memblock_mark_nomap(base, size);
+		if (err)
+			memblock_free(base, size);
+	}
 
-	return memblock_reserve(base, size);
+	return err;
 }
 
 /*
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 4a53c3ca86bd..b066024c62e3 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -99,8 +99,6 @@ void memblock_discard(void);
 static inline void memblock_discard(void) {}
 #endif
 
-phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
-				   phys_addr_t size, phys_addr_t align);
 void memblock_allow_resize(void);
 int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
 int memblock_add(phys_addr_t base, phys_addr_t size);
diff --git a/mm/memblock.c b/mm/memblock.c
index de7b553baa50..28a813d9e955 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -315,7 +315,7 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
  * Return:
  * Found address on success, 0 on failure.
  */
-phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
+static phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
 					phys_addr_t end, phys_addr_t size,
 					phys_addr_t align)
 {

base-commit: ff1176468d368232b684f75e82563369208bc371
-- 
2.28.0



From hsin-hsiung.wang at mediatek.com  Mon Aug  2 23:34:17 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 3 Aug 2021 14:34:17 +0800
Subject: [PATCH v10 1/5] dt-bindings: spmi: modify the constraint 'maxItems'
 to 'minItems'
In-Reply-To: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1627972461-2627-2-git-send-email-hsin-hsiung.wang@mediatek.com>

The constraint of 'maxItem: 1' might be larger than 1, so we modify it
to 'minItem: 1'.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
changes since v9:
- No change.
---
 Documentation/devicetree/bindings/spmi/spmi.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/spmi/spmi.yaml b/Documentation/devicetree/bindings/spmi/spmi.yaml
index 1d243faef2f8..5938d807674f 100644
--- a/Documentation/devicetree/bindings/spmi/spmi.yaml
+++ b/Documentation/devicetree/bindings/spmi/spmi.yaml
@@ -25,7 +25,7 @@ properties:
     pattern: "^spmi at .*"
 
   reg:
-    maxItems: 1
+    minItems: 1
 
   "#address-cells":
     const: 2
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Mon Aug  2 23:34:16 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 3 Aug 2021 14:34:16 +0800
Subject: [PATCH v10 0/5] Add SPMI support for Mediatek SoC IC
Message-ID: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>

This series adds support for new SoC MT6873/MT8192/MT8195 to the spmi driver.
This series is based on Chun-Jie's patches[1][2].

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127
[2] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521655

changes since v9:
- rebase to v5.14-rc1.

Henry Chen (1):
  spmi: mediatek: Add support for MT8195

Hsin-Hsiung Wang (4):
  dt-bindings: spmi: modify the constraint 'maxItems' to 'minItems'
  dt-bindings: spmi: document binding for the Mediatek SPMI controller
  spmi: mediatek: Add support for MT6873/8192
  arm64: dts: mt8192: add spmi node

 .../bindings/spmi/mtk,spmi-mtk-pmif.yaml      |  76 +++
 .../devicetree/bindings/spmi/spmi.yaml        |   2 +-
 arch/arm64/boot/dts/mediatek/mt8192.dtsi      |  17 +
 drivers/spmi/Kconfig                          |  10 +
 drivers/spmi/Makefile                         |   2 +
 drivers/spmi/spmi-mtk-pmif.c                  | 555 ++++++++++++++++++
 6 files changed, 661 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml
 create mode 100644 drivers/spmi/spmi-mtk-pmif.c


base-commit: e73f0f0ee7541171d89f2e2491130c7771ba58d3
prerequisite-patch-id: 8e70d378642e084a14296dbaa2aa4e07c1d30563
prerequisite-patch-id: 82ced16215cdd31201c6146ddb5c30bc17525996
prerequisite-patch-id: 7f2137e77cfc439c2e4b4e4369a6d6b48fec1ece
prerequisite-patch-id: 15f52bb664f0f0436627d056a53afefb0b99f67a
prerequisite-patch-id: 479b44dfdc6d7b367c0d441d8635d2dc02466057
prerequisite-patch-id: 5df1858972e343d3750cdda1063655fc232eb831
prerequisite-patch-id: 7e63a29430f65c2a0d56d7353df884645d70ed8c
prerequisite-patch-id: 2a6200e8a05329d51aaa4fd63aacfbba66d16177
prerequisite-patch-id: 604d2702c4217b77de3dc305ff08f630ba38fdb4
prerequisite-patch-id: d3ece2688dbd45eee248a8c6ba3206c0c673c904
prerequisite-patch-id: 1bebe1cd9b267c974cae50c3df8c0f8f4f0b0b3d
prerequisite-patch-id: 3b34fe85667da5287bde9fd2378359be4a126266
prerequisite-patch-id: 5d3d139212ab304739b75f7638251703b95948d5
prerequisite-patch-id: 621291b21be177a63eaf6769aa6d2ee8ddb2ea2b
prerequisite-patch-id: 024f786586b409420782d24218b15f05f6476667
prerequisite-patch-id: 946aae93303bde26226289dc389c94de96a9dacd
prerequisite-patch-id: b3ddf6f2079c3c269bd24091243030a971c43cbc
prerequisite-patch-id: 5c0e0308aa8eb06ca6df6f5467bc925f2cc106ad
prerequisite-patch-id: d4e481acd8b970f08d3e4da9c8fc0ad6e1fff551
prerequisite-patch-id: 99db7309fbe1b9f73a07e25d5174db8976c77a2c
prerequisite-patch-id: cffbc99e9e60f6db43cf7879f17e05c5b041d312
prerequisite-patch-id: 69871b871ab339881b50a2d6988173050b6c7a4f
prerequisite-patch-id: 4f5900b98a0c7cbe62694f2477a6cb410187714b
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Mon Aug  2 23:34:20 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 3 Aug 2021 14:34:20 +0800
Subject: [PATCH v10 4/5] spmi: mediatek: Add support for MT8195
In-Reply-To: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1627972461-2627-5-git-send-email-hsin-hsiung.wang@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Add spmi support for MT8195.

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
changes since v9:
- No change.
---
 drivers/spmi/spmi-mtk-pmif.c | 90 ++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
index 94c45d46ab0c..0c320801c9d5 100644
--- a/drivers/spmi/spmi-mtk-pmif.c
+++ b/drivers/spmi/spmi-mtk-pmif.c
@@ -150,6 +150,54 @@ static const u32 mt6873_regs[] = {
 	[PMIF_SWINF_3_STA] =	0x0CE8,
 };
 
+static const u32 mt8195_regs[] = {
+	[PMIF_INIT_DONE] =			0x0000,
+	[PMIF_INF_EN] =				0x0024,
+	[PMIF_ARB_EN] =				0x0150,
+	[PMIF_CMDISSUE_EN] =			0x03B8,
+	[PMIF_TIMER_CTRL] =			0x03E4,
+	[PMIF_SPI_MODE_CTRL] =			0x0408,
+	[PMIF_IRQ_EVENT_EN_0] =			0x0420,
+	[PMIF_IRQ_FLAG_0] =			0x0428,
+	[PMIF_IRQ_CLR_0] =			0x042C,
+	[PMIF_IRQ_EVENT_EN_1] =			0x0430,
+	[PMIF_IRQ_FLAG_1] =			0x0438,
+	[PMIF_IRQ_CLR_1] =			0x043C,
+	[PMIF_IRQ_EVENT_EN_2] =			0x0440,
+	[PMIF_IRQ_FLAG_2] =			0x0448,
+	[PMIF_IRQ_CLR_2] =			0x044C,
+	[PMIF_IRQ_EVENT_EN_3] =			0x0450,
+	[PMIF_IRQ_FLAG_3] =			0x0458,
+	[PMIF_IRQ_CLR_3] =			0x045C,
+	[PMIF_IRQ_EVENT_EN_4] =			0x0460,
+	[PMIF_IRQ_FLAG_4] =			0x0468,
+	[PMIF_IRQ_CLR_4] =			0x046C,
+	[PMIF_WDT_EVENT_EN_0] =			0x0474,
+	[PMIF_WDT_FLAG_0] =			0x0478,
+	[PMIF_WDT_EVENT_EN_1] =			0x047C,
+	[PMIF_WDT_FLAG_1] =			0x0480,
+	[PMIF_SWINF_0_ACC] =			0x0800,
+	[PMIF_SWINF_0_WDATA_31_0] =		0x0804,
+	[PMIF_SWINF_0_RDATA_31_0] =		0x0814,
+	[PMIF_SWINF_0_VLD_CLR] =		0x0824,
+	[PMIF_SWINF_0_STA] =			0x0828,
+	[PMIF_SWINF_1_ACC] =			0x0840,
+	[PMIF_SWINF_1_WDATA_31_0] =		0x0844,
+	[PMIF_SWINF_1_RDATA_31_0] =		0x0854,
+	[PMIF_SWINF_1_VLD_CLR] =		0x0864,
+	[PMIF_SWINF_1_STA] =			0x0868,
+	[PMIF_SWINF_2_ACC] =			0x0880,
+	[PMIF_SWINF_2_WDATA_31_0] =		0x0884,
+	[PMIF_SWINF_2_RDATA_31_0] =		0x0894,
+	[PMIF_SWINF_2_VLD_CLR] =		0x08A4,
+	[PMIF_SWINF_2_STA] =			0x08A8,
+	[PMIF_SWINF_3_ACC] =			0x08C0,
+	[PMIF_SWINF_3_WDATA_31_0] =		0x08C4,
+	[PMIF_SWINF_3_RDATA_31_0] =		0x08D4,
+	[PMIF_SWINF_3_VLD_CLR] =		0x08E4,
+	[PMIF_SWINF_3_STA] =			0x08E8,
+};
+
 enum spmi_regs {
 	SPMI_OP_ST_CTRL,
 	SPMI_GRP_ID_EN,
@@ -163,6 +211,15 @@ enum spmi_regs {
 	SPMI_REC3,
 	SPMI_REC4,
 	SPMI_MST_DBG,
+
+	/* MT8195 spmi regs */
+	SPMI_MST_RCS_CTRL,
+	SPMI_SLV_3_0_EINT,
+	SPMI_SLV_7_4_EINT,
+	SPMI_SLV_B_8_EINT,
+	SPMI_SLV_F_C_EINT,
+	SPMI_REC_CMD_DEC,
+	SPMI_DEC_DBG,
 };
 
 static const u32 mt6873_spmi_regs[] = {
@@ -180,6 +237,28 @@ static const u32 mt6873_spmi_regs[] = {
 	[SPMI_MST_DBG] =	0x00fc,
 };
 
+static const u32 mt8195_spmi_regs[] = {
+	[SPMI_OP_ST_CTRL] =	0x0000,
+	[SPMI_GRP_ID_EN] =	0x0004,
+	[SPMI_OP_ST_STA] =	0x0008,
+	[SPMI_MST_SAMPL] =	0x000C,
+	[SPMI_MST_REQ_EN] =	0x0010,
+	[SPMI_MST_RCS_CTRL] =	0x0014,
+	[SPMI_SLV_3_0_EINT] =	0x0020,
+	[SPMI_SLV_7_4_EINT] =	0x0024,
+	[SPMI_SLV_B_8_EINT] =	0x0028,
+	[SPMI_SLV_F_C_EINT] =	0x002C,
+	[SPMI_REC_CTRL] =	0x0040,
+	[SPMI_REC0] =		0x0044,
+	[SPMI_REC1] =		0x0048,
+	[SPMI_REC2] =		0x004C,
+	[SPMI_REC3] =		0x0050,
+	[SPMI_REC4] =		0x0054,
+	[SPMI_REC_CMD_DEC] =	0x005C,
+	[SPMI_DEC_DBG] =	0x00F8,
+	[SPMI_MST_DBG] =	0x00FC,
+};
+
 static u32 pmif_readl(struct pmif *arb, enum pmif_regs reg)
 {
 	return readl(arb->base + arb->data->regs[reg]);
@@ -348,6 +427,14 @@ static const struct pmif_data mt6873_pmif_arb = {
 	.soc_chan = 2,
 };
 
+static const struct pmif_data mt8195_pmif_arb[] = {
+	{
+		.regs = mt8195_regs,
+		.spmimst_regs = mt8195_spmi_regs,
+		.soc_chan = 2,
+	},
+};
+
 static int mtk_spmi_probe(struct platform_device *pdev)
 {
 	struct pmif *arb;
@@ -444,6 +531,9 @@ static const struct of_device_id mtk_spmi_match_table[] = {
 	{
 		.compatible = "mediatek,mt6873-spmi",
 		.data = &mt6873_pmif_arb,
+	}, {
+		.compatible = "mediatek,mt8195-spmi",
+		.data = &mt8195_pmif_arb,
 	}, {
 		/* sentinel */
 	},
-- 
2.18.0

From yee.lee at mediatek.com  Tue Aug  3 00:08:22 2021
From: yee.lee at mediatek.com (yee.lee at mediatek.com)
Date: Tue, 3 Aug 2021 15:08:22 +0800
Subject: [PATCH v4 1/1] arm64/cpufeature: Optionally disable MTE via
 command-line
In-Reply-To: <20210803070824.7586-1-yee.lee@mediatek.com>
References: <20210803070824.7586-1-yee.lee@mediatek.com>
Message-ID: <20210803070824.7586-2-yee.lee@mediatek.com>

From: Yee Lee <yee.lee at mediatek.com>

MTE support needs to be optionally disabled in runtime 
for HW issue workaround, FW development and some 
evaluation works on system resource and performance.

This patch makes two changes:
(1) moves init of tag-allocation bits(ATA/ATA0) to
cpu_enable_mte() as not cached in TLB.

(2) allows ID_AA64PFR1_EL1.MTE to be overridden on
its shadow value by giving "arm64.nomte" on cmdline.

When the feature value is off, ATA and TCF will not set 
and the related functionalities are accordingly suppressed.

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Suggested-by: Marc Zyngier <maz at kernel.org>
Suggested-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Yee Lee <yee.lee at mediatek.com>
---
 Documentation/admin-guide/kernel-parameters.txt | 3 +++
 arch/arm64/include/asm/sysreg.h                 | 3 +--
 arch/arm64/kernel/cpufeature.c                  | 3 +++
 arch/arm64/kernel/idreg-override.c              | 2 ++
 4 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index bdb22006f713..6f257e39d89e 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -380,6 +380,9 @@
 	arm64.nopauth	[ARM64] Unconditionally disable Pointer Authentication
 			support
 
+	arm64.nomte	[ARM64] Unconditionally disable Memory Tagging Extension
+			support
+
 	ataflop=	[HW,M68k]
 
 	atarimouse=	[HW,MOUSE] Atari Mouse
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7b9c3acba684..e3e2c93b35f4 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -698,8 +698,7 @@
 	(SCTLR_ELx_M    | SCTLR_ELx_C    | SCTLR_ELx_SA   | SCTLR_EL1_SA0   | \
 	 SCTLR_EL1_SED  | SCTLR_ELx_I    | SCTLR_EL1_DZE  | SCTLR_EL1_UCT   | \
 	 SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN | SCTLR_ELx_ITFSB | \
-	 SCTLR_ELx_ATA  | SCTLR_EL1_ATA0 | ENDIAN_SET_EL1 | SCTLR_EL1_UCI   | \
-	 SCTLR_EL1_EPAN | SCTLR_EL1_RES1)
+	 ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_EPAN | SCTLR_EL1_RES1)
 
 /* MAIR_ELx memory attributes (used by Linux) */
 #define MAIR_ATTR_DEVICE_nGnRnE		UL(0x00)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0ead8bfedf20..51e6bf4bb7b5 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1843,6 +1843,9 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused)
 #ifdef CONFIG_ARM64_MTE
 static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
 {
+	sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0);
+	isb();
+
 	/*
 	 * Clear the tags in the zero page. This needs to be done via the
 	 * linear map which has the Tagged attribute.
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 53a381a7f65d..d8e606fe3c21 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -54,6 +54,7 @@ static const struct ftr_set_desc pfr1 __initconst = {
 	.override	= &id_aa64pfr1_override,
 	.fields		= {
 	        { "bt", ID_AA64PFR1_BT_SHIFT },
+		{ "mte", ID_AA64PFR1_MTE_SHIFT},
 		{}
 	},
 };
@@ -100,6 +101,7 @@ static const struct {
 	{ "arm64.nopauth",
 	  "id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "
 	  "id_aa64isar1.api=0 id_aa64isar1.apa=0"	   },
+	{ "arm64.nomte",		"id_aa64pfr1.mte=0" },
 	{ "nokaslr",			"kaslr.disabled=1" },
 };
 
-- 
2.18.0

From viresh.kumar at linaro.org  Tue Aug  3 00:13:02 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 3 Aug 2021 12:43:02 +0530
Subject: [PATCH v13 2/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW
In-Reply-To: <1627574891-26514-3-git-send-email-hector.yuan@mediatek.com>
References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com>
 <1627574891-26514-3-git-send-email-hector.yuan@mediatek.com>
Message-ID: <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7>

On 30-07-21, 00:08, Hector Yuan wrote:
> From: "Hector.Yuan" <hector.yuan at mediatek.com>
> 
> Add cpufreq HW support

Please write a proper commit log, what you are adding and which SoCs
it will apply to. Also add a full stop (.) at the end.

> Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
> ---
>  drivers/cpufreq/Kconfig.arm           |   12 ++
>  drivers/cpufreq/Makefile              |    1 +
>  drivers/cpufreq/mediatek-cpufreq-hw.c |  357 +++++++++++++++++++++++++++++++++
>  include/linux/cpufreq.h               |   39 ++++

The changes to cpufreq.h should be done in a separate patch.

> diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
> new file mode 100644
> index 0000000..ca50a3a
> --- /dev/null
> +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
> @@ -0,0 +1,357 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 MediaTek Inc.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/cpufreq.h>
> +#include <linux/energy_model.h>
> +#include <linux/init.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/pm_qos.h>
> +#include <linux/slab.h>
> +
> +#define LUT_MAX_ENTRIES			32U
> +#define LUT_FREQ			GENMASK(11, 0)
> +#define LUT_ROW_SIZE			0x4
> +#define CPUFREQ_HW_STATUS		BIT(0)
> +#define SVS_HW_STATUS			BIT(1)
> +#define POLL_USEC			1000
> +#define TIMEOUT_USEC			300000
> +
> +enum {
> +	REG_FREQ_LUT_TABLE,
> +	REG_FREQ_ENABLE,
> +	REG_FREQ_PERF_STATE,
> +	REG_FREQ_HW_STATE,
> +	REG_EM_POWER_TBL,
> +	REG_FREQ_LATENCY,
> +
> +	REG_ARRAY_SIZE,
> +};
> +
> +struct cpufreq_mtk {
> +	struct cpufreq_frequency_table *table;
> +	void __iomem *reg_bases[REG_ARRAY_SIZE];
> +	int nr_opp;
> +	cpumask_t related_cpus;
> +};
> +
> +static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
> +	[REG_FREQ_LUT_TABLE]	= 0x0,
> +	[REG_FREQ_ENABLE]	= 0x84,
> +	[REG_FREQ_PERF_STATE]	= 0x88,
> +	[REG_FREQ_HW_STATE]	= 0x8c,
> +	[REG_EM_POWER_TBL]	= 0x90,
> +	[REG_FREQ_LATENCY]	= 0x110,
> +};
> +
> +static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
> +
> +static int __maybe_unused
> +mtk_cpufreq_get_cpu_power(unsigned long *mW,
> +			  unsigned long *KHz, struct device *cpu_dev)
> +{
> +	struct cpufreq_mtk *c;
> +	struct cpufreq_policy *policy;
> +	int i;
> +
> +	policy = cpufreq_cpu_get_raw(cpu_dev->id);
> +	if (!policy)
> +		return 0;
> +
> +	c = mtk_freq_domain_map[policy->cpu];
> +
> +	for (i = 0; i < c->nr_opp; i++) {
> +		if (c->table[i].frequency < *KHz)
> +			break;
> +	}
> +	i--;
> +
> +	*KHz = c->table[i].frequency;
> +	*mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
> +			    i * LUT_ROW_SIZE) / 1000;
> +
> +	return 0;
> +}
> +
> +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
> +				       unsigned int index)
> +{
> +	struct cpufreq_mtk *c = policy->driver_data;
> +
> +	writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
> +
> +	return 0;
> +}
> +
> +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
> +{
> +	struct cpufreq_mtk *c;
> +	struct cpufreq_policy *policy;
> +	unsigned int index;
> +
> +	policy = cpufreq_cpu_get_raw(cpu);
> +	if (!policy)
> +		return 0;
> +
> +	c = mtk_freq_domain_map[policy->cpu];
> +
> +	index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
> +	index = min(index, LUT_MAX_ENTRIES - 1);
> +
> +	return c->table[index].frequency;
> +}
> +
> +static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
> +					       unsigned int target_freq)
> +{
> +	struct cpufreq_mtk *c = policy->driver_data;
> +	unsigned int index;
> +
> +	index = cpufreq_table_find_index_dl(policy, target_freq);
> +
> +	writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
> +
> +	return policy->freq_table[index].frequency;
> +}
> +
> +static int mtk_cpu_create_freq_table(struct platform_device *pdev,
> +				     struct cpufreq_mtk *c)
> +{
> +	struct device *dev = &pdev->dev;
> +	void __iomem *base_table;
> +	u32 data, i, freq, prev_freq = 0;
> +
> +	c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
> +				sizeof(*c->table), GFP_KERNEL);
> +	if (!c->table)
> +		return -ENOMEM;
> +
> +	base_table = c->reg_bases[REG_FREQ_LUT_TABLE];
> +
> +	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
> +		data = readl_relaxed(base_table + (i * LUT_ROW_SIZE));
> +		freq = FIELD_GET(LUT_FREQ, data) * 1000;
> +
> +		if (freq == prev_freq)
> +			break;
> +
> +		c->table[i].frequency = freq;
> +
> +		dev_dbg(dev, "index=%d freq=%d\n",
> +			i, c->table[i].frequency);

Won't this fit in a single line ?

> +
> +		prev_freq = freq;
> +	}
> +
> +	c->table[i].frequency = CPUFREQ_TABLE_END;
> +	c->nr_opp = i;
> +
> +	return 0;
> +}
> +
> +static int mtk_cpu_resources_init(struct platform_device *pdev,
> +				  unsigned int cpu, int index,
> +				  const u16 *offsets)
> +{
> +	struct cpufreq_mtk *c;
> +	struct device *dev = &pdev->dev;
> +	int ret, i;
> +	void __iomem *base;
> +
> +	if (mtk_freq_domain_map[cpu])

This should not happen anymore, isn't it ?

> +		return 0;
> +
> +	c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
> +	if (!c)
> +		return -ENOMEM;
> +
> +	base = devm_platform_ioremap_resource(pdev, index);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
> +		c->reg_bases[i] = base + offsets[i];
> +
> +	ret = of_perf_domain_get_sharing_cpumask(index, "performance-domains",

Instead of parsing parsing "performance-domains" twice, I would rather
pass a CPU number here instead of index.

> +						 "#performance-domain-cells",
> +						 &c->related_cpus);

You could have directly passed policy->cpus here instead.

> +	if (ret) {
> +		dev_info(dev, "Domain-%d failed to get related CPUs\n", index);
> +		return ret;
> +	}
> +
> +	ret = mtk_cpu_create_freq_table(pdev, c);
> +	if (ret) {
> +		dev_info(dev, "Domain-%d failed to create freq table\n", index);
> +		return ret;
> +	}
> +
> +	mtk_freq_domain_map[cpu] = c;

I will rather use policy->driver_data to store this now.

> +
> +	return 0;
> +}
> +
> +static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
> +{
> +	struct platform_device *pdev = cpufreq_get_driver_data();
> +	struct cpufreq_mtk *c;
> +	struct device *cpu_dev;
> +	struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
> +	struct pm_qos_request *qos_request;
> +	struct device_node *cpu_np;
> +	struct of_phandle_args args;
> +	const u16 *offsets;
> +	unsigned int latency;
> +	int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;
> +	int ret;

It looks much more organized when the variable definitions are in
decreasing order of their length, instead of the random order as it is
right now.

> +
> +	offsets = of_device_get_match_data(&pdev->dev);
> +	if (!offsets)
> +		return -EINVAL;
> +
> +	cpu_np = of_cpu_device_node_get(policy->cpu);
> +	if (!cpu_np) {
> +		dev_info(&pdev->dev, "Failed to get cpu %d device\n",
> +			 policy->cpu);
> +		return -ENODEV;
> +	}
> +
> +	ret = of_parse_phandle_with_args(cpu_np, "performance-domains",
> +					 "#performance-domain-cells", 0,
> +					 &args);
> +	if (ret < 0)

What about dropping cpu_np and same later in the code as well ?

> +		return ret;
> +
> +	/* Get the bases of cpufreq for domains */
> +	ret = mtk_cpu_resources_init(pdev, policy->cpu, args.args[0], offsets);
> +	if (ret) {
> +		dev_info(&pdev->dev, "CPUFreq resource init failed\n");
> +		return ret;
> +	}
> +
> +	cpu_dev = get_cpu_device(policy->cpu);
> +	if (!cpu_dev) {
> +		pr_err("failed to get cpu%d device\n", policy->cpu);
> +		return -ENODEV;
> +	}
> +
> +	c = mtk_freq_domain_map[policy->cpu];
> +	if (!c) {
> +		pr_err("No scaling support for CPU%d\n", policy->cpu);
> +		return -ENODEV;
> +	}
> +
> +	cpumask_copy(policy->cpus, &c->related_cpus);
> +
> +	policy->freq_table = c->table;
> +	policy->driver_data = c;

Oh you already do this, you can remove mtk_freq_domain_map array now.

> +
> +	latency = readl_relaxed(c->reg_bases[REG_FREQ_LATENCY]);
> +	if (!latency)
> +		latency = CPUFREQ_ETERNAL;
> +
> +	/* us convert to ns */
> +	policy->cpuinfo.transition_latency = latency * 1000;

You want to multiple CPUFREQ_ETERNAL too ?

> +
> +	policy->fast_switch_possible = true;
> +
> +	qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL);

This is a small structure, why not allocate it on stack instead ?

> +	if (!qos_request)
> +		return -ENOMEM;
> +
> +	/* Let CPUs leave idle-off state for SVS CPU initializing */
> +	cpu_latency_qos_add_request(qos_request, 0);
> +
> +	/* HW should be in enabled state to proceed now */
> +	writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]);
> +
> +	if (readl_poll_timeout(c->reg_bases[REG_FREQ_HW_STATE], sig,
> +			       (sig & pwr_hw) == pwr_hw, POLL_USEC,
> +			       TIMEOUT_USEC)) {
> +		if (!(sig & CPUFREQ_HW_STATUS)) {
> +			pr_info("cpufreq hardware of CPU%d is not enabled\n",
> +				policy->cpu);
> +			return -ENODEV;
> +		}
> +
> +		pr_info("SVS of CPU%d is not enabled\n", policy->cpu);
> +	}
> +
> +	cpu_latency_qos_remove_request(qos_request);
> +
> +	em_dev_register_perf_domain(cpu_dev, c->nr_opp, &em_cb, policy->cpus, true);
> +
> +	kfree(qos_request);

Why free after registering for em ? And also move the entire qos thing
into a separate routine instead of adding it to ->init().

> +
> +	return 0;
> +}
> +
> +static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
> +{
> +	struct cpufreq_mtk *c;
> +
> +	c = mtk_freq_domain_map[policy->cpu];
> +
> +	/* HW should be in paused state now */
> +	writel_relaxed(0x0, c->reg_bases[REG_FREQ_ENABLE]);

Please make sure each and every resource is freed here and in probe on
failures.

> +
> +	return 0;
> +}
> +
> +static struct cpufreq_driver cpufreq_mtk_hw_driver = {
> +	.flags		= CPUFREQ_NEED_INITIAL_FREQ_CHECK |
> +			  CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
> +			  CPUFREQ_IS_COOLING_DEV,
> +	.verify		= cpufreq_generic_frequency_table_verify,
> +	.target_index	= mtk_cpufreq_hw_target_index,
> +	.get		= mtk_cpufreq_hw_get,
> +	.init		= mtk_cpufreq_hw_cpu_init,
> +	.exit		= mtk_cpufreq_hw_cpu_exit,
> +	.fast_switch	= mtk_cpufreq_hw_fast_switch,
> +	.name		= "mtk-cpufreq-hw",
> +	.attr		= cpufreq_generic_attr,
> +};
> +
> +static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +
> +	cpufreq_mtk_hw_driver.driver_data = pdev;
> +
> +	ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver);
> +	if (ret) {
> +		dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");
> +		return ret;
> +	}
> +
> +	return 0;

You can do return ret here and drop the earlier return and its {}.

> +}
> +
> +static int mtk_cpufreq_hw_driver_remove(struct platform_device *pdev)
> +{
> +	return cpufreq_unregister_driver(&cpufreq_mtk_hw_driver);
> +}
> +
> +static const struct of_device_id mtk_cpufreq_hw_match[] = {
> +	{ .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_offsets },
> +	{}
> +};
> +
> +static struct platform_driver mtk_cpufreq_hw_driver = {
> +	.probe = mtk_cpufreq_hw_driver_probe,
> +	.remove = mtk_cpufreq_hw_driver_remove,
> +	.driver = {
> +		.name = "mtk-cpufreq-hw",
> +		.of_match_table = mtk_cpufreq_hw_match,
> +	},
> +};
> +module_platform_driver(mtk_cpufreq_hw_driver);
> +
> +MODULE_DESCRIPTION("Mediatek cpufreq-hw driver");
> +MODULE_LICENSE("GPL v2");

You can add Module-author as well here if you want.

> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 9fd7194..4916d70 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -13,6 +13,8 @@
>  #include <linux/completion.h>
>  #include <linux/kobject.h>
>  #include <linux/notifier.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/pm_qos.h>
>  #include <linux/spinlock.h>
>  #include <linux/sysfs.h>
> @@ -1036,6 +1038,43 @@ void arch_set_freq_scale(const struct cpumask *cpus,
>  }
>  #endif
>  
> +#ifdef CONFIG_CPU_FREQ

There is another CONFIG_CPU_FREQ a few lines above, please use the
same block for this routine as well.

> +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name,
> +						     const char *cell_name,
> +						     struct cpumask *cpumask)
> +{
> +	struct device_node *cpu_np;
> +	struct of_phandle_args args;
> +	int cpu, ret;
> +
> +	for_each_possible_cpu(cpu) {
> +		cpu_np = of_cpu_device_node_get(cpu);
> +		if (!cpu_np)
> +			continue;
> +
> +		ret = of_parse_phandle_with_args(cpu_np, list_name,
> +						 cell_name, 0,
> +						 &args);
> +
> +		of_node_put(cpu_np);
> +		if (ret < 0)
> +			continue;
> +
> +		if (index == args.args[0])
> +			cpumask_set_cpu(cpu, cpumask);
> +	}
> +
> +	return 0;
> +}
> +#else
> +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name,
> +						     const char *cell_name,
> +						     struct cpumask *cpumask)
> +{
> +	return 0;

	return -EOPNOTSUPP;

> +}
> +#endif

-- 
viresh


From yee.lee at mediatek.com  Tue Aug  3 00:08:21 2021
From: yee.lee at mediatek.com (yee.lee at mediatek.com)
Date: Tue, 3 Aug 2021 15:08:21 +0800
Subject: [PATCH v4 0/1] arm64/cpufeature: Support optionally disable MTE
Message-ID: <20210803070824.7586-1-yee.lee@mediatek.com>

From: Yee Lee <yee.lee at mediatek.com>

An option in runtime to disable MTE support is necessary for some
scenarios such as HW issue workaround, FW tests and 
some evaluation works in performance and resoruce costs.
 
This patch supoorts to override id-reg on the
shadow capability via comandline and suppress MTE feature.

SCTLR_EL1.ATA/ATA0 setting is moved to cpu_enable_mte()
since they are not allowed to be cache TLB.

All works in this patch turn off related software support,
but not fully disable MTE in HW side.

=== Test ===
QEMU5.2 + MTE

(1) normal boot
MTE feature is enabled and HW-tags KASAN works.

(2) passed "arm64.nomte" in cmdline
boot log:
..(skip)
[    0.000000] CPU features: SYS_ID_AA64PFR1_EL1[11:8]: forced to 0

====
Changed since v4:
 - Move ATA/ATA0 setting to cpu_enable_mte()

Changed since v3:
 - Add documentation text

Changed since v2:
 - Use id-reg override machanism to suppress feature.

Yee Lee (1):
  arm64/cpufeature: Optionally disable MTE via command-line

 Documentation/admin-guide/kernel-parameters.txt | 3 +++
 arch/arm64/include/asm/sysreg.h                 | 3 +--
 arch/arm64/kernel/cpufeature.c                  | 3 +++
 arch/arm64/kernel/idreg-override.c              | 2 ++
 4 files changed, 9 insertions(+), 2 deletions(-)

-- 
2.18.0

From o.rempel at pengutronix.de  Tue Aug  3 00:29:58 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Tue,  3 Aug 2021 09:29:58 +0200
Subject: [PATCH v1] dt-bindings: timer: fsl, imxgpt: add optional osc_per clock
Message-ID: <20210803072958.4815-1-o.rempel@pengutronix.de>

Add optional osc_per and fix dts validation warnings on imx6 SoCs.

Fixes: df8cad689eae ("dt-bindings: timer: Convert i.MX GPT to json-schema")
Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 .../devicetree/bindings/timer/fsl,imxgpt.yaml   | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
index a4f51f46b7a1..e496dd9f4988 100644
--- a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
+++ b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
@@ -43,11 +43,15 @@ properties:
     items:
       - description: SoC GPT ipg clock
       - description: SoC GPT per clock
+      - description: optional SoC GPT oscillator
+    minItems: 2
 
   clock-names:
     items:
       - const: ipg
       - const: per
+      - const: osc_per
+    minItems: 2
 
 required:
   - compatible
@@ -70,3 +74,16 @@ examples:
                  <&clks IMX27_CLK_PER1_GATE>;
         clock-names = "ipg", "per";
     };
+
+  - |
+    #include <dt-bindings/clock/imx6qdl-clock.h>
+
+    timer at 2098000 {
+        compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
+        reg = <0x02098000 0x4000>;
+        interrupts = <26>;
+        clocks = <&clks IMX6QDL_CLK_GPT_IPG>,
+                 <&clks IMX6QDL_CLK_GPT_IPG_PER>,
+                 <&clks IMX6QDL_CLK_GPT_3M>;
+        clock-names = "ipg", "per", "osc_per";
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug  3 00:37:47 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 3 Aug 2021 09:37:47 +0200
Subject: [PATCH 04/12] tty: serial: samsung: Init USI to keep clocks
 running
In-Reply-To: <CAPLW+4mMCzzyqqJTse-UEpjQoVu1b-9Xz3_3L=nmg63uKYFnGw@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-5-semen.protsenko@linaro.org>
 <a1701931-136e-235c-8392-a3f64c050d74@canonical.com>
 <CAPLW+4mMCzzyqqJTse-UEpjQoVu1b-9Xz3_3L=nmg63uKYFnGw@mail.gmail.com>
Message-ID: <7364ccb2-70da-6400-ae6d-6a30171b6678@canonical.com>

On 03/08/2021 01:06, Sam Protsenko wrote:

(...)

>>> diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h
>>> index f6c3323fc4c5..013c2646863e 100644
>>> --- a/include/linux/serial_s3c.h
>>> +++ b/include/linux/serial_s3c.h
>>> @@ -28,6 +28,15 @@
>>>  #define S3C2410_UFSTAT         (0x18)
>>>  #define S3C2410_UMSTAT         (0x1C)
>>>
>>> +/* USI Control Register offset */
>>> +#define USI_CON                      (0xC4)
>>> +/* USI Option Register offset */
>>> +#define USI_OPTION           (0xC8)
>>> +/* USI_CON[0] = 0b0: clear USI global software reset (Active High) */
>>> +#define USI_RESET            (0<<0)
>>
>> Just 0x0. I understand you wanted to hint it is a bit field, but the
>> shift of 0 actually creates more questions.
>>
> 
> After some consideration I decided to adhere to existing style and do
> something like this (in v2):
> 
> 8<--------------------------------------------------------------------->8
> #define USI_CON          (0xC4)
> #define USI_OPTION      (0xC8)
> 
> #define USI_CON_RESET_CLEAR        (0<<0)
> #define USI_CON_RESET_SET        (1<<0)
> #define USI_CON_RESET_MASK        (1<<0)
> 
> #define USI_OPTION_HWACG_CLKREQ_ON    (1<<1)
> #define USI_OPTION_HWACG_CLKSTOP_ON    (1<<2)
> #define USI_OPTION_HWACG_MASK        (3<<1)
> 8<--------------------------------------------------------------------->8
> 
> The whole reason for those comments was missing public TRM. But in the
> end I decided it just looks ugly. Also, this way I can do RMW
> operation (discussed above) in more logical way.
> 
> Please let me know if code snippets above look good to you.

Please skip the USI_CON_RESET_CLEAR. There is no such pattern in the
code. Clearing bit is an obvious operation and such code is already
everywhere:
    val &= ~USI_CON_RESET

(or &= ~USI_RESET_MASK)

Therefore for USI_CON_RESET only:
    #define USI_CON_RESET             (1<<0)
    #define USI_CON_RESET_MASK        (1<<0)


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Aug  3 00:41:24 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 3 Aug 2021 09:41:24 +0200
Subject: [PATCH 00/12] Add minimal support for Exynos850 SoC
In-Reply-To: <CAPLW+4=1Anr6rCWEBL04D81aEAEVKD5cGE+ObXH3q-HNHce07w@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <5e35b0a7-13aa-3c62-ca49-14af2fcb2a08@canonical.com>
 <c3486111-0ec9-9679-d2a2-68b2f33a2450@canonical.com>
 <CAPLW+4kbnJEBkc0D=RWt59JxBan8X1uDy6sSXBiYAq8N9FDV6A@mail.gmail.com>
 <13f166bb-7103-25d5-35a6-8ec53a1f1817@canonical.com>
 <2dacc205-04ce-c206-a393-50ba0d5aa1a7@canonical.com>
 <CAPLW+4=1Anr6rCWEBL04D81aEAEVKD5cGE+ObXH3q-HNHce07w@mail.gmail.com>
Message-ID: <0277c701-cc25-cdc5-d3b9-cf2cc2ba4de5@canonical.com>

On 03/08/2021 01:27, Sam Protsenko wrote:
> On Sat, 31 Jul 2021 at 11:12, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 31/07/2021 09:29, Krzysztof Kozlowski wrote:
>>> On 30/07/2021 21:02, Sam Protsenko wrote:
>>>> Hi Krzysztof,
>>>>
>>>> On Fri, 30 Jul 2021 at 20:21, Krzysztof Kozlowski
>>>> <krzysztof.kozlowski at canonical.com> wrote:
>>>>>
>>>>> On 30/07/2021 17:18, Krzysztof Kozlowski wrote:
>>>>>> On 30/07/2021 16:49, Sam Protsenko wrote:
>>>>>>> This patch series adds initial platform support for Samsung Exynos850
>>>>>>> SoC [1]. With this patchset it's possible to run the kernel with BusyBox
>>>>>>> rootfs as a RAM disk. More advanced platform support (like MMC driver
>>>>>>> additions) will be added later. The idea is to keep the first submission
>>>>>>> minimal to ease the review, and then build up on top of that.
>>>>>>>
>>>>>>> [1] https://www.samsung.com/semiconductor/minisite/exynos/products/mobileprocessor/exynos-850/
>>>>>>>
>>>>>>
>>>>>> Great work!
>>>>>>
>>>>
>>>> Thanks, Krzysztof! And thank you for reviewing the whole series.
>>>>
>>>>>> What's the SoC revision number (should be accessible via
>>>>>> /sys/bus/soc/devices/soc0/)? Recent wrap in numbering of Exynos chips
>>>>>> might bring confusion...
>>>>
>>>> # cat /sys/devices/soc0/revision
>>>> 0
>>>
>>> soc_id but you're right it won't be set for unknown SoCs. You need to
>>> extend drivers/soc/samsung/exynos-chipid.c to parse new values (E3830000
>>> for product ID) and maybe new register offsets (previous offset is 0x0,
>>> for 3830 is 0x10 I think). Also revision mask might change.
>>>
>>>>> Judging by vendor's sources it is quite confusing. It looks mostly like
>>>>> Exynos3830 but in few other cases it uses Exynos9 compatibles (Exynos9,
>>>>> Exynos9820). Only in few places there is Exynos850. Marketing department
>>>>> made it so confusing...  The revision embedded in SoC would be very
>>>>> interesting.
>>>>>
>>>>
>>>> As I understand, this SoC is called Exynos850 everywhere now.
>>>> Exynos3830 is its old name, not used anymore. As you noticed from
>>>> patch #2, it shares some definitions with Exynos9 SoC, so I guess some
>>>> software is similar for both architectures. Not sure about hardware
>>>> though, never worked with Exynos9 CPUs. Anyway, I asked Samsung
>>>> representatives about naming, and it seems like we should stick to
>>>> "Exynos850" name, even in code.
>>>
>>>
>>> Since the chip identifies itself as E3830000, I would prefer naming
>>> matching real product ID instead of what is pushed by marketing or sales
>>> representatives. The marketing names don't have to follow any
>>> engineering rules, they can be changed and renamed. Sales follows rather
>>> money and corporate rules, not consistency for upstream project.
>>
>> On the other hand we have already two exceptions for naming
>> inconsistency - Exynos3250 identifies itself as 3472 (which is confusing
>> because 3250 is two core and there is a separate quad-core
>> Exyons3472...) and Exynos5800 is actually marketing name for a revision
>> of Exynos5422. Maybe indeed will be easier to go with the branded name
>> 850...
>>
> 
> Well, chip engraving says "3830", but I was specifically told to stick
> to "850" in upstream kernel. I can presume there was some mix ups with
> this naming, and it might be the case it's better to stick to "850"
> exactly to avoid further confusion. Yes, I can see that
> EXYNOS3830_SOC_ID = 0xE3830000 in chipid driver, but we can return
> "EXYNOS850" string for that const, right? If you google "Exynos850"
> and "Exynos3830", it's obvious everybody uses the former, so I'd
> appreciate if we can stick to "850" in the end.

Yeah, let it be. If you have some pushback from some company
representatives about naming, encourage them to speak up here. Otherwise
you will be the guy in the middle bringing arguments between different
parties. :)


Best regards,
Krzysztof


From sboyd at kernel.org  Tue Aug  3 00:44:15 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Aug 2021 00:44:15 -0700
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <20210802094810.GJ22278@shell.armlinux.org.uk>
References: <YPkg0wtYIoHKpTUW@kunai> <YPlfcbkxiBmB+vw1@kunai>
 <CAHp75VfC=s12Unw3+Cn0ag71mM5i90=Jbwj4nYwB5cPKiUTRSA@mail.gmail.com>
 <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
 <20210802094810.GJ22278@shell.armlinux.org.uk>
Message-ID: <162797665579.714452.9746229195858722362@swboyd.mtv.corp.google.com>

Quoting Russell King (Oracle) (2021-08-02 02:48:10)
> 
> > > I still wonder if it would be better if we had some sort of DT binding
> > > that said "turn this clk on when the driver probes this device and keep
> > > it on until the driver is unbound".
> > 
> > This doesn't sound like a hardware property and so I don't think this
> > belongs into DT and I would be surprised if the dt maintainers would be
> > willing to accept an idea with this semantic.
> 
> I really don't like that idea - enabling or disabling a clock is
> an implementation decision, one which can change over time. Even
> if a clock is required to be on for e.g. accessing device registers,
> we may decide that, if we want maximum power savings, to disable
> that clock when the device is not being used, but an initial driver
> implementation may not do that. If we encourage people to throw a
> property in DT, then the driver's runtime behaviour becomes a
> combination of the DT being used and the driver implementation.
> Let's keep that to a minimum.
> 

I suspect that sometimes we want to express that some clk is on all the
time in DT because there isn't any sort of consumer driver for it. We
have fixed rate clks that sort of do that, but I'm thinking about
something like a GPIO clk gate that is downstream of some clk source,
and this gpio gate is enabled once at boot and then forgotten about. I
suppose in this case we could have a property in the clk gpio binding
that expresses this property of the hardware so it's best to not make
something more generic that could be abused.


From kishon at ti.com  Tue Aug  3 00:49:26 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 13:19:26 +0530
Subject: [PATCH v2 0/6] PCI: Add support for J7200 and AM64
Message-ID: <20210803074932.19820-1-kishon@ti.com>

This series adds the compatible specific to J7200 and AM64 and
applies the erratas and configuration specific to them.

This series also includes Nadeem's patch that adds a quirk in
Cadence driver which is used by J7200 [1].

The DT binding for both J7200 and AM64 is already merged.

v1 of the patch series can be found at [2]

Changes from v1:
1) As suggested by Bjorn, used unsigned int :1, instead of bool for
structure members
2) Removed using unnecessary local variables and also fixed some
code alignment

[1] -> https://lore.kernel.org/r/20210528155626.21793-1-nadeem at cadence.com
[2] -> https://lore.kernel.org/r/20210706105035.9915-1-kishon at ti.com

Kishon Vijay Abraham I (5):
  PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
  PCI: j721e: Add PCIe support for J7200
  PCI: j721e: Add PCIe support for AM64
  misc: pci_endpoint_test: Do not request or allocate IRQs in probe
  misc: pci_endpoint_test: Add deviceID for AM64 and J7200

Nadeem Athani (1):
  PCI: cadence: Add quirk flag to set minimum delay in LTSSM
    Detect.Quiet state

 drivers/misc/pci_endpoint_test.c              | 27 ++++++--
 drivers/pci/controller/cadence/pci-j721e.c    | 61 +++++++++++++++++--
 .../pci/controller/cadence/pcie-cadence-ep.c  |  4 ++
 .../controller/cadence/pcie-cadence-host.c    |  3 +
 drivers/pci/controller/cadence/pcie-cadence.c | 17 ++++++
 drivers/pci/controller/cadence/pcie-cadence.h | 17 +++++-
 6 files changed, 117 insertions(+), 12 deletions(-)

-- 
2.17.1



From kishon at ti.com  Tue Aug  3 00:49:27 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 13:19:27 +0530
Subject: [PATCH v2 1/6] PCI: cadence: Use bitfield for *quirk_retrain_flag*
 instead of bool
In-Reply-To: <20210803074932.19820-1-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
Message-ID: <20210803074932.19820-2-kishon@ti.com>

No functional change. As we are intending to add additional 1-bit
members in struct j721e_pcie_data/struct cdns_pcie_rc, use bitfields
instead of bool since it takes less space. As discussed in [1],
the preference is to use bitfileds instead of bool inside structures.

[1] -> https://lore.kernel.org/linux-fsdevel/CA+55aFzKQ6Pj18TB8p4Yr0M4t+S+BsiHH=BJNmn=76-NcjTj-g at mail.gmail.com/

Suggested-by: Bjorn Helgaas <bhelgaas at google.com>
Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c    | 2 +-
 drivers/pci/controller/cadence/pcie-cadence.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 35e61048e133..0c5813b230b4 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -66,7 +66,7 @@ enum j721e_pcie_mode {
 
 struct j721e_pcie_data {
 	enum j721e_pcie_mode	mode;
-	bool quirk_retrain_flag;
+	unsigned int		quirk_retrain_flag:1;
 };
 
 static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 927b49e42997..a978a2eeedad 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -308,7 +308,7 @@ struct cdns_pcie_rc {
 	u32			vendor_id;
 	u32			device_id;
 	bool			avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
-	bool                    quirk_retrain_flag;
+	unsigned int		quirk_retrain_flag:1;
 };
 
 /**
-- 
2.17.1



From kishon at ti.com  Tue Aug  3 00:49:28 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 13:19:28 +0530
Subject: [PATCH v2 2/6] PCI: cadence: Add quirk flag to set minimum delay in
 LTSSM Detect.Quiet state
In-Reply-To: <20210803074932.19820-1-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
Message-ID: <20210803074932.19820-3-kishon@ti.com>

From: Nadeem Athani <nadeem at cadence.com>

PCIe fails to link up if SERDES lanes not used by PCIe are assigned to
another protocol. For example, link training fails if lanes 2 and 3 are
assigned to another protocol while lanes 0 and 1 are used for PCIe to
form a two lane link. This failure is due to an incorrect tie-off on an
internal status signal indicating electrical idle.

Status signals going from SERDES to PCIe Controller are tied-off when a
lane is not assigned to PCIe. Signal indicating electrical idle is
incorrectly tied-off to a state that indicates non-idle. As a result,
PCIe sees unused lanes to be out of electrical idle and this causes
LTSSM to exit Detect.Quiet state without waiting for 12ms timeout to
occur. If a receiver is not detected on the first receiver detection
attempt in Detect.Active state, LTSSM goes back to Detect.Quiet and
again moves forward to Detect.Active state without waiting for 12ms as
required by PCIe base specification. Since wait time in Detect.Quiet is
skipped, multiple receiver detect operations are performed back-to-back
without allowing time for capacitance on the transmit lines to
discharge. This causes subsequent receiver detection to always fail even
if a receiver gets connected eventually.

Add a quirk flag "quirk_detect_quiet_flag" to program the minimum
time the LTSSM should wait on entering Detect.Quiet state here.
This has to be set for J7200 as it has an incorrect tie-off on unused
lanes.

Signed-off-by: Nadeem Athani <nadeem at cadence.com>
Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c    |  4 ++++
 .../pci/controller/cadence/pcie-cadence-host.c  |  3 +++
 drivers/pci/controller/cadence/pcie-cadence.c   | 17 +++++++++++++++++
 drivers/pci/controller/cadence/pcie-cadence.h   | 15 +++++++++++++++
 4 files changed, 39 insertions(+)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 791915054ff4..e05c157afef0 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -804,6 +804,10 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
 	/* Reserve region 0 for IRQs */
 	set_bit(0, &ep->ob_region_map);
+
+	if (ep->quirk_detect_quiet_flag)
+		cdns_pcie_detect_quiet_min_delay_set(&ep->pcie);
+
 	spin_lock_init(&ep->lock);
 
 	return 0;
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index ae1c55503513..fb96d37a135c 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -498,6 +498,9 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 		return PTR_ERR(rc->cfg_base);
 	rc->cfg_res = res;
 
+	if (rc->quirk_detect_quiet_flag)
+		cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
+
 	ret = cdns_pcie_start_link(pcie);
 	if (ret) {
 		dev_err(dev, "Failed to start link\n");
diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
index 3c3646502d05..65b6c8bed0d4 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.c
+++ b/drivers/pci/controller/cadence/pcie-cadence.c
@@ -7,6 +7,23 @@
 
 #include "pcie-cadence.h"
 
+void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie)
+{
+	u32 delay = 0x3;
+	u32 ltssm_control_cap;
+
+	/*
+	 * Set the LTSSM Detect Quiet state min. delay to 2ms.
+	 */
+
+	ltssm_control_cap = cdns_pcie_readl(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP);
+	ltssm_control_cap = ((ltssm_control_cap &
+			    ~CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK) |
+			    CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay));
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP, ltssm_control_cap);
+}
+
 void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
 				   u32 r, bool is_io,
 				   u64 cpu_addr, u64 pci_addr, size_t size)
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index a978a2eeedad..cda430d0f6e4 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -194,6 +194,14 @@
 /* AXI link down register */
 #define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824)
 
+/* LTSSM Capabilities register */
+#define CDNS_PCIE_LTSSM_CONTROL_CAP             (CDNS_PCIE_LM_BASE + 0x0054)
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK  GENMASK(2, 1)
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT 1
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay) \
+	 (((delay) << CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT) & \
+	 CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK)
+
 enum cdns_pcie_rp_bar {
 	RP_BAR_UNDEFINED = -1,
 	RP_BAR0,
@@ -300,6 +308,7 @@ struct cdns_pcie {
  * @avail_ib_bar: Satus of RP_BAR0, RP_BAR1 and	RP_NO_BAR if it's free or
  *                available
  * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
+ * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
  */
 struct cdns_pcie_rc {
 	struct cdns_pcie	pcie;
@@ -309,6 +318,7 @@ struct cdns_pcie_rc {
 	u32			device_id;
 	bool			avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
 	unsigned int		quirk_retrain_flag:1;
+	unsigned int		quirk_detect_quiet_flag:1;
 };
 
 /**
@@ -341,6 +351,7 @@ struct cdns_pcie_epf {
  *        registers fields (RMW) accessible by both remote RC and EP to
  *        minimize time between read and write
  * @epf: Structure to hold info about endpoint function
+ * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
  */
 struct cdns_pcie_ep {
 	struct cdns_pcie	pcie;
@@ -355,6 +366,7 @@ struct cdns_pcie_ep {
 	/* protect writing to PCI_STATUS while raising legacy interrupts */
 	spinlock_t		lock;
 	struct cdns_pcie_epf	*epf;
+	unsigned int		quirk_detect_quiet_flag:1;
 };
 
 
@@ -515,6 +527,9 @@ static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	return 0;
 }
 #endif
+
+void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
+
 void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
 				   u32 r, bool is_io,
 				   u64 cpu_addr, u64 pci_addr, size_t size);
-- 
2.17.1



From kishon at ti.com  Tue Aug  3 00:49:29 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 13:19:29 +0530
Subject: [PATCH v2 3/6] PCI: j721e: Add PCIe support for J7200
In-Reply-To: <20210803074932.19820-1-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
Message-ID: <20210803074932.19820-4-kishon@ti.com>

J7200 has the same PCIe IP as in J721E with minor changes in the
wrapper. J7200 allows byte access of bridge configuration space
registers and the register field for LINK_DOWN interrupt is different.
J7200 also requires "quirk_detect_quiet_flag" to be set. Configure these
changes as part of driver data applicable only to J7200.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 40 +++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 0c5813b230b4..8e76f2e7e782 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -27,6 +27,7 @@
 #define STATUS_REG_SYS_2	0x508
 #define STATUS_CLR_REG_SYS_2	0x708
 #define LINK_DOWN		BIT(1)
+#define J7200_LINK_DOWN		BIT(10)
 
 #define J721E_PCIE_USER_CMD_STATUS	0x4
 #define LINK_TRAINING_ENABLE		BIT(0)
@@ -57,6 +58,7 @@ struct j721e_pcie {
 	struct cdns_pcie	*cdns_pcie;
 	void __iomem		*user_cfg_base;
 	void __iomem		*intd_cfg_base;
+	u32			linkdown_irq_regfield;
 };
 
 enum j721e_pcie_mode {
@@ -67,6 +69,9 @@ enum j721e_pcie_mode {
 struct j721e_pcie_data {
 	enum j721e_pcie_mode	mode;
 	unsigned int		quirk_retrain_flag:1;
+	unsigned int		quirk_detect_quiet_flag:1;
+	u32			linkdown_irq_regfield;
+	unsigned int		byte_access_allowed:1;
 };
 
 static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
@@ -98,12 +103,12 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
 	u32 reg;
 
 	reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
-	if (!(reg & LINK_DOWN))
+	if (!(reg & pcie->linkdown_irq_regfield))
 		return IRQ_NONE;
 
 	dev_err(dev, "LINK DOWN!\n");
 
-	j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN);
+	j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, pcie->linkdown_irq_regfield);
 	return IRQ_HANDLED;
 }
 
@@ -112,7 +117,7 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
 	u32 reg;
 
 	reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2);
-	reg |= LINK_DOWN;
+	reg |= pcie->linkdown_irq_regfield;
 	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
 }
 
@@ -284,10 +289,25 @@ static struct pci_ops cdns_ti_pcie_host_ops = {
 static const struct j721e_pcie_data j721e_pcie_rc_data = {
 	.mode = PCI_MODE_RC,
 	.quirk_retrain_flag = true,
+	.byte_access_allowed = false,
+	.linkdown_irq_regfield = LINK_DOWN,
 };
 
 static const struct j721e_pcie_data j721e_pcie_ep_data = {
 	.mode = PCI_MODE_EP,
+	.linkdown_irq_regfield = LINK_DOWN,
+};
+
+static const struct j721e_pcie_data j7200_pcie_rc_data = {
+	.mode = PCI_MODE_RC,
+	.quirk_detect_quiet_flag = true,
+	.linkdown_irq_regfield = J7200_LINK_DOWN,
+	.byte_access_allowed = true,
+};
+
+static const struct j721e_pcie_data j7200_pcie_ep_data = {
+	.mode = PCI_MODE_EP,
+	.quirk_detect_quiet_flag = true,
 };
 
 static const struct of_device_id of_j721e_pcie_match[] = {
@@ -299,6 +319,14 @@ static const struct of_device_id of_j721e_pcie_match[] = {
 		.compatible = "ti,j721e-pcie-ep",
 		.data = &j721e_pcie_ep_data,
 	},
+	{
+		.compatible = "ti,j7200-pcie-host",
+		.data = &j7200_pcie_rc_data,
+	},
+	{
+		.compatible = "ti,j7200-pcie-ep",
+		.data = &j7200_pcie_ep_data,
+	},
 	{},
 };
 
@@ -332,6 +360,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 
 	pcie->dev = dev;
 	pcie->mode = mode;
+	pcie->linkdown_irq_regfield =  data->linkdown_irq_regfield;
 
 	base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg");
 	if (IS_ERR(base))
@@ -391,9 +420,11 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 			goto err_get_sync;
 		}
 
-		bridge->ops = &cdns_ti_pcie_host_ops;
+		if (!data->byte_access_allowed)
+			bridge->ops = &cdns_ti_pcie_host_ops;
 		rc = pci_host_bridge_priv(bridge);
 		rc->quirk_retrain_flag = data->quirk_retrain_flag;
+		rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
 
 		cdns_pcie = &rc->pcie;
 		cdns_pcie->dev = dev;
@@ -459,6 +490,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 			ret = -ENOMEM;
 			goto err_get_sync;
 		}
+		ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
 
 		cdns_pcie = &ep->pcie;
 		cdns_pcie->dev = dev;
-- 
2.17.1



From kishon at ti.com  Tue Aug  3 00:49:30 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 13:19:30 +0530
Subject: [PATCH v2 4/6] PCI: j721e: Add PCIe support for AM64
In-Reply-To: <20210803074932.19820-1-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
Message-ID: <20210803074932.19820-5-kishon@ti.com>

AM64 has the same PCIe IP as in J7200 with certain erratas not
applicable (quirk_detect_quiet_flag). Add support for "ti,am64-pcie-host"
compatible and "ti,am64-pcie-ep" compatible that is specific to AM64.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 8e76f2e7e782..2ec037c43bd5 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -310,6 +310,17 @@ static const struct j721e_pcie_data j7200_pcie_ep_data = {
 	.quirk_detect_quiet_flag = true,
 };
 
+static const struct j721e_pcie_data am64_pcie_rc_data = {
+	.mode = PCI_MODE_RC,
+	.linkdown_irq_regfield = J7200_LINK_DOWN,
+	.byte_access_allowed = true,
+};
+
+static const struct j721e_pcie_data am64_pcie_ep_data = {
+	.mode = PCI_MODE_EP,
+	.linkdown_irq_regfield = J7200_LINK_DOWN,
+};
+
 static const struct of_device_id of_j721e_pcie_match[] = {
 	{
 		.compatible = "ti,j721e-pcie-host",
@@ -327,6 +338,14 @@ static const struct of_device_id of_j721e_pcie_match[] = {
 		.compatible = "ti,j7200-pcie-ep",
 		.data = &j7200_pcie_ep_data,
 	},
+	{
+		.compatible = "ti,am64-pcie-host",
+		.data = &am64_pcie_rc_data,
+	},
+	{
+		.compatible = "ti,am64-pcie-ep",
+		.data = &am64_pcie_ep_data,
+	},
 	{},
 };
 
-- 
2.17.1



From kishon at ti.com  Tue Aug  3 00:49:31 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 13:19:31 +0530
Subject: [PATCH v2 5/6] misc: pci_endpoint_test: Do not request or allocate
 IRQs in probe
In-Reply-To: <20210803074932.19820-1-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
Message-ID: <20210803074932.19820-6-kishon@ti.com>

Allocation of IRQ vectors and requesting IRQ is done as part of
PCITEST_SET_IRQTYPE. Do not request or allocate IRQs in probe for
AM654 and J721E so that the user space test script has better control
of the devices for which the IRQs are configured. Since certain user
space scripts could rely on allocation of IRQ vectors during probe,
remove allocation of IRQs only for TI's K3 platform.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/misc/pci_endpoint_test.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index c7ee34013485..9740f2a0e7cd 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -79,6 +79,9 @@
 #define PCI_DEVICE_ID_RENESAS_R8A774C0		0x002d
 #define PCI_DEVICE_ID_RENESAS_R8A774E1		0x0025
 
+#define is_j721e_pci_dev(pdev)         \
+		((pdev)->device == PCI_DEVICE_ID_TI_J721E)
+
 static DEFINE_IDA(pci_endpoint_test_ida);
 
 #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
@@ -810,9 +813,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
 
 	pci_set_master(pdev);
 
-	if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
-		err = -EINVAL;
-		goto err_disable_irq;
+	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
+		if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
+			err = -EINVAL;
+			goto err_disable_irq;
+		}
 	}
 
 	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
@@ -850,9 +855,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
 		goto err_ida_remove;
 	}
 
-	if (!pci_endpoint_test_request_irq(test)) {
-		err = -EINVAL;
-		goto err_kfree_test_name;
+	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
+		if (!pci_endpoint_test_request_irq(test)) {
+			err = -EINVAL;
+			goto err_kfree_test_name;
+		}
 	}
 
 	misc_device = &test->miscdev;
-- 
2.17.1



From kishon at ti.com  Tue Aug  3 00:49:32 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 13:19:32 +0530
Subject: [PATCH v2 6/6] misc: pci_endpoint_test: Add deviceID for AM64 and
 J7200
In-Reply-To: <20210803074932.19820-1-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
Message-ID: <20210803074932.19820-7-kishon@ti.com>

Add device ID specific to AM64 and J7200 in pci_endpoint_test so that
endpoints configured with those deviceIDs can use pci_endpoint_test
driver.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/misc/pci_endpoint_test.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 9740f2a0e7cd..707cf9d7e8c0 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -69,6 +69,8 @@
 #define FLAG_USE_DMA				BIT(0)
 
 #define PCI_DEVICE_ID_TI_AM654			0xb00c
+#define PCI_DEVICE_ID_TI_J7200			0xb00f
+#define PCI_DEVICE_ID_TI_AM64			0xb010
 #define PCI_DEVICE_ID_LS1088A			0x80c0
 
 #define is_am654_pci_dev(pdev)		\
@@ -976,6 +978,12 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E),
 	  .driver_data = (kernel_ulong_t)&j721e_data,
 	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J7200),
+	  .driver_data = (kernel_ulong_t)&j721e_data,
+	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM64),
+	  .driver_data = (kernel_ulong_t)&j721e_data,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
-- 
2.17.1



From tinghan.shen at mediatek.com  Tue Aug  3 00:59:19 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Tue, 3 Aug 2021 15:59:19 +0800
Subject: [PATCH v5 2/5] dt-bindings: remoteproc: mediatek: Add binding for
 mt8192 scp
In-Reply-To: <20210803075922.11611-1-tinghan.shen@mediatek.com>
References: <20210803075922.11611-1-tinghan.shen@mediatek.com>
Message-ID: <20210803075922.11611-3-tinghan.shen@mediatek.com>

Add mt8192 compatible to binding document.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
index d64466eefbe3..88f37dee7bca 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
@@ -7,14 +7,17 @@ Mediatek SoCs.
 Required properties:
 - compatible		Should be one of:
 				"mediatek,mt8183-scp"
+				"mediatek,mt8192-scp"
 				"mediatek,mt8195-scp"
 - reg			Should contain the address ranges for memory regions:
 			SRAM, CFG, and L1TCM.
 - reg-names		Contains the corresponding names for the memory regions:
 			"sram", "cfg", and "l1tcm".
-- clocks		Required by mt8183. Clock for co-processor (See: ../clock/clock-bindings.txt)
-- clock-names		Required by mt8183. Contains the corresponding name for the clock. This
-			should be named "main".
+- clocks		Required by mt8183 and mt8192. Clock for co-processor
+			(See: ../clock/clock-bindings.txt)
+- clock-names		Required by mt8183 and mt8192. Contains the
+			corresponding name for the clock. This should be
+			named "main".
 
 Subnodes
 --------
-- 
2.18.0

From tinghan.shen at mediatek.com  Tue Aug  3 00:59:18 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Tue, 3 Aug 2021 15:59:18 +0800
Subject: [PATCH v5 1/5] dt-bindings: remoteproc: mediatek: Add binding for
 mt8195 scp
In-Reply-To: <20210803075922.11611-1-tinghan.shen@mediatek.com>
References: <20210803075922.11611-1-tinghan.shen@mediatek.com>
Message-ID: <20210803075922.11611-2-tinghan.shen@mediatek.com>

Add mt8195 compatible to binding document. The description of required
properties are also modified to reflect the hardware change between
mt8183 and mt8195. The mt8195 doesn't have to control the scp clock on
kernel side.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
index 3f5f78764b60..d64466eefbe3 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
@@ -5,13 +5,15 @@ This binding provides support for ARM Cortex M4 Co-processor found on some
 Mediatek SoCs.
 
 Required properties:
-- compatible		Should be "mediatek,mt8183-scp"
+- compatible		Should be one of:
+				"mediatek,mt8183-scp"
+				"mediatek,mt8195-scp"
 - reg			Should contain the address ranges for memory regions:
 			SRAM, CFG, and L1TCM.
 - reg-names		Contains the corresponding names for the memory regions:
 			"sram", "cfg", and "l1tcm".
-- clocks		Clock for co-processor (See: ../clock/clock-bindings.txt)
-- clock-names		Contains the corresponding name for the clock. This
+- clocks		Required by mt8183. Clock for co-processor (See: ../clock/clock-bindings.txt)
+- clock-names		Required by mt8183. Contains the corresponding name for the clock. This
 			should be named "main".
 
 Subnodes
-- 
2.18.0

From tinghan.shen at mediatek.com  Tue Aug  3 00:59:21 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Tue, 3 Aug 2021 15:59:21 +0800
Subject: [PATCH v5 4/5] dt-bindings: remoteproc: mediatek: Convert mtk,
 scp to json-schema
In-Reply-To: <20210803075922.11611-1-tinghan.shen@mediatek.com>
References: <20210803075922.11611-1-tinghan.shen@mediatek.com>
Message-ID: <20210803075922.11611-5-tinghan.shen@mediatek.com>

Convert the mtk,scp binding to DT schema format using json-schema.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 .../bindings/remoteproc/mtk,scp.txt           | 41 ---------
 .../bindings/remoteproc/mtk,scp.yaml          | 92 +++++++++++++++++++
 2 files changed, 92 insertions(+), 41 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
 create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
deleted file mode 100644
index 88f37dee7bca..000000000000
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-Mediatek SCP Bindings
-----------------------------------------
-
-This binding provides support for ARM Cortex M4 Co-processor found on some
-Mediatek SoCs.
-
-Required properties:
-- compatible		Should be one of:
-				"mediatek,mt8183-scp"
-				"mediatek,mt8192-scp"
-				"mediatek,mt8195-scp"
-- reg			Should contain the address ranges for memory regions:
-			SRAM, CFG, and L1TCM.
-- reg-names		Contains the corresponding names for the memory regions:
-			"sram", "cfg", and "l1tcm".
-- clocks		Required by mt8183 and mt8192. Clock for co-processor
-			(See: ../clock/clock-bindings.txt)
-- clock-names		Required by mt8183 and mt8192. Contains the
-			corresponding name for the clock. This should be
-			named "main".
-
-Subnodes
---------
-
-Subnodes of the SCP represent rpmsg devices. The names of the devices are not
-important. The properties of these nodes are defined by the individual bindings
-for the rpmsg devices - but must contain the following property:
-
-- mtk,rpmsg-name	Contains the name for the rpmsg device. Used to match
-			the subnode to rpmsg device announced by SCP.
-
-Example:
-
-	scp: scp at 10500000 {
-		compatible = "mediatek,mt8183-scp";
-		reg = <0 0x10500000 0 0x80000>,
-		      <0 0x105c0000 0 0x5000>;
-		reg-names = "sram", "cfg";
-		clocks = <&infracfg CLK_INFRA_SCPSYS>;
-		clock-names = "main";
-	};
diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
new file mode 100644
index 000000000000..f57f1518fe13
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/mtk,scp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek SCP Bindings
+
+maintainers:
+  - Tinghan Shen <tinghan.shen at mediatek.com>
+
+description:
+  This binding provides support for ARM Cortex M4 Co-processor found on some
+  Mediatek SoCs.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8183-scp
+      - mediatek,mt8192-scp
+      - mediatek,mt8195-scp
+
+  reg:
+    description:
+      Should contain the address ranges for memory regions SRAM, CFG, and
+      L1TCM.
+    maxItems: 3
+
+  reg-names:
+    items:
+      - const: sram
+      - const: cfg
+      - const: l1tcm
+
+  clocks:
+    description:
+      Clock for co-processor (see ../clock/clock-bindings.txt).
+      Required by mt8183 and mt8192.
+    maxItems: 1
+
+  clock-names:
+    const: main
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+if:
+  properties:
+    compatible:
+      enum:
+        - mediatek,mt8183-scp
+        - mediatek,mt8192-scp
+then:
+  required:
+    - clocks
+    - clock-names
+
+additionalProperties:
+  type: object
+  description:
+    Subnodes of the SCP represent rpmsg devices. The names of the devices
+    are not important. The properties of these nodes are defined by the
+    individual bindings for the rpmsg devices.
+  properties:
+    mtk,rpmsg-name:
+      $ref: /schemas/types.yaml#/definitions/string-array
+      description:
+        Contains the name for the rpmsg device. Used to match
+        the subnode to rpmsg device announced by SCP.
+
+  required:
+    - mtk,rpmsg-name
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+
+    scp at 10500000 {
+        compatible = "mediatek,mt8183-scp";
+        reg = <0x10500000 0x80000>,
+              <0x10700000 0x8000>,
+              <0x10720000 0xe0000>;
+        reg-names = "sram", "cfg", "l1tcm";
+        clocks = <&infracfg CLK_INFRA_SCPSYS>;
+        clock-names = "main";
+
+        cros_ec {
+            mtk,rpmsg-name = "cros-ec-rpmsg";
+        };
+    };
-- 
2.18.0

From krzysztof.kozlowski at canonical.com  Tue Aug  3 01:01:00 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 3 Aug 2021 10:01:00 +0200
Subject: [PATCH v5 3/5] dt-bindings: vendor-prefixes: Add another prefix
 for Mediatek Co.
In-Reply-To: <20210803075922.11611-4-tinghan.shen@mediatek.com>
References: <20210803075922.11611-1-tinghan.shen@mediatek.com>
 <20210803075922.11611-4-tinghan.shen@mediatek.com>
Message-ID: <f084bd57-c6df-cade-fefd-217897caf88e@canonical.com>

On 03/08/2021 09:59, Tinghan Shen wrote:
> Add document binding for mediatek.
> 
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 07fb0d25fc15..c4252cd570b0 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -760,6 +760,8 @@ patternProperties:
>      description: MStar Semiconductor, Inc. (acquired by MediaTek Inc.)
>    "^mti,.*":
>      description: Imagination Technologies Ltd. (formerly MIPS Technologies Inc.)
> +  "^mtk,.*":
> +    description: MediaTek Inc.

NAK, you already have one MediaTek Inc. I doubt these are different
companies...


Best regards,
Krzysztof


From tinghan.shen at mediatek.com  Tue Aug  3 00:59:17 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Tue, 3 Aug 2021 15:59:17 +0800
Subject: [PATCH v5 0/5] Mediatek MT8195 SCP support
Message-ID: <20210803075922.11611-1-tinghan.shen@mediatek.com>

Changes since v4:
- Move clock acquirement to mtk_scp_of_data
- Add new vendor-prefix for Mediatek SCP
- Refine mtk,scp.yaml
  - Remove '|' in 'description'
  - Add 'items' to replace 'description' in reg-names property
  - Add 'const' to replace 'description' in clock-names property
  - Add optional required property for mt8183 and mt8192
  - Rewrite 'patternProperties' by 'additionalProperties'
  - Rewrite example with 1 address and size-cell.
  - Drop dts label from example 

Changes since v3:
- Add missing patch version in mail subject
- No change to patches.

Changes since v2:
- Add compatible for mt8192
- Convert mtk,scp.txt to mtk,scp.yaml 
- Refine clock checking method

Changes since v1:
- Fix missing 'compatible' line in binding document

Tinghan Shen (5):
  dt-bindings: remoteproc: mediatek: Add binding for mt8195 scp
  dt-bindings: remoteproc: mediatek: Add binding for mt8192 scp
  dt-bindings: vendor-prefixes: Add another prefix for Mediatek Co.
  dt-bindings: remoteproc: mediatek: Convert mtk,scp to json-schema
  remoteproc: mediatek: Support mt8195 scp

 .../bindings/remoteproc/mtk,scp.txt           | 36 --------
 .../bindings/remoteproc/mtk,scp.yaml          | 92 +++++++++++++++++++
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 +
 drivers/remoteproc/mtk_common.h               |  1 +
 drivers/remoteproc/mtk_scp.c                  | 48 +++++++++-
 5 files changed, 138 insertions(+), 41 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
 create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml

-- 
2.18.0

From tinghan.shen at mediatek.com  Tue Aug  3 00:59:22 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Tue, 3 Aug 2021 15:59:22 +0800
Subject: [PATCH v5 5/5] remoteproc: mediatek: Support mt8195 scp
In-Reply-To: <20210803075922.11611-1-tinghan.shen@mediatek.com>
References: <20210803075922.11611-1-tinghan.shen@mediatek.com>
Message-ID: <20210803075922.11611-6-tinghan.shen@mediatek.com>

The SCP clock design is changed on mt8195 that doesn't need to control
SCP clock on kernel side.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 drivers/remoteproc/mtk_common.h |  1 +
 drivers/remoteproc/mtk_scp.c    | 48 +++++++++++++++++++++++++++++----
 2 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 61901f5efa05..5ff3867c72f3 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -72,6 +72,7 @@ struct scp_ipi_desc {
 struct mtk_scp;
 
 struct mtk_scp_of_data {
+	int (*scp_clk_get)(struct mtk_scp *scp);
 	int (*scp_before_load)(struct mtk_scp *scp);
 	void (*scp_irq_handler)(struct mtk_scp *scp);
 	void (*scp_reset_assert)(struct mtk_scp *scp);
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 9679cc26895e..36e48cf58ed6 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -312,6 +312,32 @@ static int scp_elf_read_ipi_buf_addr(struct mtk_scp *scp,
 	return -ENOENT;
 }
 
+static int mt8183_scp_clk_get(struct mtk_scp *scp)
+{
+	struct device *dev = scp->dev;
+	int ret = 0;
+
+	scp->clk = devm_clk_get(dev, "main");
+	if (IS_ERR(scp->clk)) {
+		dev_err(dev, "Failed to get clock\n");
+		ret = PTR_ERR(scp->clk);
+	}
+
+	return ret;
+}
+
+static int mt8192_scp_clk_get(struct mtk_scp *scp)
+{
+	return mt8183_scp_clk_get(scp);
+}
+
+static int mt8195_scp_clk_get(struct mtk_scp *scp)
+{
+	scp->clk = NULL;
+
+	return 0;
+}
+
 static int mt8183_scp_before_load(struct mtk_scp *scp)
 {
 	/* Clear SCP to host interrupt */
@@ -785,12 +811,9 @@ static int scp_probe(struct platform_device *pdev)
 	if (ret)
 		goto destroy_mutex;
 
-	scp->clk = devm_clk_get(dev, "main");
-	if (IS_ERR(scp->clk)) {
-		dev_err(dev, "Failed to get clock\n");
-		ret = PTR_ERR(scp->clk);
+	ret = scp->data->scp_clk_get(scp);
+	if (ret)
 		goto release_dev_mem;
-	}
 
 	/* register SCP initialization IPI */
 	ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp);
@@ -852,6 +875,7 @@ static int scp_remove(struct platform_device *pdev)
 }
 
 static const struct mtk_scp_of_data mt8183_of_data = {
+	.scp_clk_get = mt8183_scp_clk_get,
 	.scp_before_load = mt8183_scp_before_load,
 	.scp_irq_handler = mt8183_scp_irq_handler,
 	.scp_reset_assert = mt8183_scp_reset_assert,
@@ -864,6 +888,19 @@ static const struct mtk_scp_of_data mt8183_of_data = {
 };
 
 static const struct mtk_scp_of_data mt8192_of_data = {
+	.scp_clk_get = mt8192_scp_clk_get,
+	.scp_before_load = mt8192_scp_before_load,
+	.scp_irq_handler = mt8192_scp_irq_handler,
+	.scp_reset_assert = mt8192_scp_reset_assert,
+	.scp_reset_deassert = mt8192_scp_reset_deassert,
+	.scp_stop = mt8192_scp_stop,
+	.scp_da_to_va = mt8192_scp_da_to_va,
+	.host_to_scp_reg = MT8192_GIPC_IN_SET,
+	.host_to_scp_int_bit = MT8192_HOST_IPC_INT_BIT,
+};
+
+static const struct mtk_scp_of_data mt8195_of_data = {
+	.scp_clk_get = mt8195_scp_clk_get,
 	.scp_before_load = mt8192_scp_before_load,
 	.scp_irq_handler = mt8192_scp_irq_handler,
 	.scp_reset_assert = mt8192_scp_reset_assert,
@@ -877,6 +914,7 @@ static const struct mtk_scp_of_data mt8192_of_data = {
 static const struct of_device_id mtk_scp_of_match[] = {
 	{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
 	{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
+	{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
-- 
2.18.0

From tinghan.shen at mediatek.com  Tue Aug  3 00:59:20 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Tue, 3 Aug 2021 15:59:20 +0800
Subject: [PATCH v5 3/5] dt-bindings: vendor-prefixes: Add another prefix for
 Mediatek Co.
In-Reply-To: <20210803075922.11611-1-tinghan.shen@mediatek.com>
References: <20210803075922.11611-1-tinghan.shen@mediatek.com>
Message-ID: <20210803075922.11611-4-tinghan.shen@mediatek.com>

Add document binding for mediatek.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 07fb0d25fc15..c4252cd570b0 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -760,6 +760,8 @@ patternProperties:
     description: MStar Semiconductor, Inc. (acquired by MediaTek Inc.)
   "^mti,.*":
     description: Imagination Technologies Ltd. (formerly MIPS Technologies Inc.)
+  "^mtk,.*":
+    description: MediaTek Inc.
   "^multi-inno,.*":
     description: Multi-Inno Technology Co.,Ltd
   "^mundoreader,.*":
-- 
2.18.0

From mike.leach at linaro.org  Tue Aug  3 01:06:17 2021
From: mike.leach at linaro.org (Mike Leach)
Date: Tue, 3 Aug 2021 09:06:17 +0100
Subject: [RFC PATCH 6/6] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <20210802170307.GA3050918@p14s>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-7-james.clark@arm.com>
 <YQgGjlWtbaNApkp6@kernel.org> <20210802170307.GA3050918@p14s>
Message-ID: <CAJ9a7VhLqgsEOVV3yksLiTJ2w2FOogNS92-gX5G4sgL8wiEwCA@mail.gmail.com>

HI James,

On Mon, 2 Aug 2021 at 18:03, Mathieu Poirier <mathieu.poirier at linaro.org> wrote:
>
> On Mon, Aug 02, 2021 at 11:51:58AM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Thu, Jul 29, 2021 at 04:58:05PM +0100, James Clark escreveu:
> > > Currently decode will silently fail if no binary data is available for
> > > the decode. This is made worse if only partial data is available because
> > > the decode will appear to work, but any trace from that missing DSO will
> > > silently not be generated.
> > >

The decoder actually outputs a OCSD_GEN_TRC_ELEM_ADDR_NACC packet if
binary memory data is missing.
These packets are currently ignored by perf / cs-etm-decoder.c.

I think this per DSO warning is fine, but perhaps at some point add in
handling for OCSD_GEN_TRC_ELEM_ADDR_NACC - which perhaps is only
active when dumping trace packets.

Regards

Mike


> > > Add a UI popup once if there is any data missing, and then warn in the
> > > bottom left for each individual DSO that's missing.
> >
> > Looks ok to me (the last 3 patches in this series, the rest I applied
> > already), can I get some Acked-by/Reviewed-by from the CoreSight people?
> >
>
> I have a substantial backlog of patches to go through and I will be away for the
> next two weeks.  As such it will be some time before I get to review this set.
>
> Regards,
> Mathieu
>
> > Thanks,
> >
> > - Arnaldo
> >
> > > Signed-off-by: James Clark <james.clark at arm.com>
> > > ---
> > >  tools/perf/util/cs-etm.c | 10 +++++++++-
> > >  1 file changed, 9 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> > > index 32ad92d3e454..e6851260d059 100644
> > > --- a/tools/perf/util/cs-etm.c
> > > +++ b/tools/perf/util/cs-etm.c
> > > @@ -746,8 +746,16 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
> > >
> > >     len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
> > >
> > > -   if (len <= 0)
> > > +   if (len <= 0) {
> > > +           ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n");
> > > +           if (!al.map->dso->auxtrace_warned) {
> > > +                   pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
> > > +                               address,
> > > +                               al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
> > > +                   al.map->dso->auxtrace_warned = true;
> > > +           }
> > >             return 0;
> > > +   }
> > >
> > >     return len;
> > >  }
> > > --
> > > 2.28.0
> > >
> >
> > --
> >
> > - Arnaldo



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From sboyd at kernel.org  Tue Aug  3 01:11:54 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Aug 2021 01:11:54 -0700
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <20210802163824.GK22278@shell.armlinux.org.uk>
References: <YPlfcbkxiBmB+vw1@kunai>
 <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
 <20210802094810.GJ22278@shell.armlinux.org.uk>
 <20210802152755.ibisunvibmwhiyry@pengutronix.de>
 <20210802163824.GK22278@shell.armlinux.org.uk>
Message-ID: <162797831443.714452.3551045763456936564@swboyd.mtv.corp.google.com>

Quoting Russell King (Oracle) (2021-08-02 09:38:24)
> On Mon, Aug 02, 2021 at 05:27:55PM +0200, Uwe Kleine-Konig wrote:
> > Hello Russell,
> > 
> > On Mon, Aug 02, 2021 at 10:48:10AM +0100, Russell King (Oracle) wrote:
> 
> > > There have been several different approaches to wrapping things up,
> > > but here's a question: should we make it easier to do the lazy thing
> > > (get+enable) or should we make it easier to be power efficient?
> > > Shouldn't we be encouraging people to write power efficient drivers?
> > 
> > Yeah, sounds compelling, but I wonder if that's of practical importance.
> > How many driver authors do you expect to lure into making a better
> > driver just because devm_clk_get_prepared() doesn't exist? In contrast:
> > How many drivers become simpler with devm_clk_get_prepared() and so
> > it becomes easier to maintain them and easier to spot bugs?
> > In the absence of devm_clk_get_prepared(), is it better that several
> > frameworks (or drivers) open code it?
> 
> It probably depends on where you stand on power management and power
> efficiency issues. Personally, I would like to see more effort put
> into drivers to make them more power efficient, and I believe in the
> coming years, power efficiency is going to become a big issue.
> 

I agree we should put more effort into power efficiency in the kernel.
I've occasionally heard from driver writers that they never will turn
the clk off even in low power modes though. They feel like it's a
nuisance to have to do anything with the clk framework in their driver.
When I say "why not use runtime PM?" I get told that they're not turning
the clk off because it needs to be on all the time, so using runtime PM
makes the driver more complicated, not less, and adds no value. I think
some touchscreens are this way, and watchdogs too. Looking at the
drivers being converted in this series I suspect RTC is one of those
sorts of devices as well. But SPI and I2C most likely could benefit from
using runtime PM and so those ones don't feel appropriate to convert.

Maybe this series would be more compelling if those various drivers that
are hand rolling the devm action were converted to the consolidated
official devm function. The truth is it's already happening in various
subsystems so consolidating that logic into one place would be a win
code size wise and very hard to ignore.

Doing

 $ git grep devm_add_action | grep clk

seems to catch quite a few of them.


From robin.murphy at arm.com  Tue Aug  3 01:19:08 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 3 Aug 2021 09:19:08 +0100
Subject: [PATCH v2 0/3] iommu: Enable non-strict DMA on QCom SD/MMC
In-Reply-To: <CACK8Z6FV+QYR01=aP4AT8rNUQMkX-WwesHzf5XY8465KuUZ=_Q@mail.gmail.com>
References: <20210624171759.4125094-1-dianders@chromium.org>
 <YNXXwvuErVnlHt+s@8bytes.org>
 <CAD=FV=UFxZH7g8gH5+M=Fv4Y-e1bsLkNkPGJhNwhvVychcGQcQ@mail.gmail.com>
 <CAD=FV=W=HmgH3O3z+nThWL6U+X4Oh37COe-uTzVB9SanP2n86w@mail.gmail.com>
 <YOaymBHc4g2cIfRn@8bytes.org>
 <CAD=FV=U_mKPaGfWyN1SVi9S2hPBpG=rE_p89+Jvjr95d0TvgsA@mail.gmail.com>
 <e3555c49-2978-355f-93bb-dbfa7d09cab8@arm.com>
 <CAD=FV=XaTqNDn=vLEXfJ2dV+EH2UoxPfzWeiS+_sZ9hrQ274bw@mail.gmail.com>
 <CACK8Z6FV+QYR01=aP4AT8rNUQMkX-WwesHzf5XY8465KuUZ=_Q@mail.gmail.com>
Message-ID: <9a1bc174-3230-912c-09ae-25d9f021e8fc@arm.com>

On 2021-08-03 01:09, Rajat Jain wrote:
> Hi Robin, Doug,
> 
> On Wed, Jul 14, 2021 at 8:14 AM Doug Anderson <dianders at chromium.org> wrote:
>>
>> Hi,
>>
>> On Tue, Jul 13, 2021 at 11:07 AM Robin Murphy <robin.murphy at arm.com> wrote:
>>>
>>> On 2021-07-08 15:36, Doug Anderson wrote:
>>> [...]
>>>>> Or document for the users that want performance how to
>>>>> change the setting, so that they can decide.
>>>>
>>>> Pushing this to the users can make sense for a Linux distribution but
>>>> probably less sense for an embedded platform. So I'm happy to make
>>>> some way for a user to override this (like via kernel command line),
>>>> but I also strongly believe there should be a default that users don't
>>>> have to futz with that we think is correct.
>>>
>>> FYI I did make progress on the "punt it to userspace" approach. I'm not
>>> posting it even as an RFC yet because I still need to set up a machine
>>> to try actually testing any of it (it's almost certainly broken
>>> somewhere), but in the end it comes out looking surprisingly not too bad
>>> overall. If you're curious to take a look in the meantime I put it here:
>>>
>>> https://gitlab.arm.com/linux-arm/linux-rm/-/commits/iommu/fq
> 
> I was wondering if you got any closer to testing / sending it out? I
> looked at the patches and am trying to understand, would they also
> make it possible to convert at runtime, an existing "non-strict"
> domain (for a particular device) into a "strict" domain leaving the
> other devices/domains as-is? Please let me know when you think your
> patches are good to be tested, and I'd also be interested in trying
> them out.

Yup, most recently here:

https://lore.kernel.org/linux-iommu/cover.1627468308.git.robin.murphy at arm.com/

I'm currently getting v3 ready, so I'll try to remember to add you to 
the CC list.

>> Being able to change this at runtime through sysfs sounds great and it
>> fills all the needs I'm aware of, thanks! In Chrome OS we can just use
>> this with some udev rules and get everything we need.
> 
> I still have another (inverse) use case where this does not work:
> We have an Intel chromebook with the default domain type being
> non-strict. There is an LTE modem (an internal PCI device which cannot
> be marked external), which we'd like to be treated as a "Strict" DMA
> domain.
> 
> Do I understand it right that using Rob's patches, I could potentially
> switch the domain to "strict" *after* booting (since we don't use
> initramfs), but by that time, the driver might have already attached
> to the modem device (using "non-strict" domain), and thus the damage
> may have already been done? So perhaps we still need a device property
> that the firmware could use to indicate "strictness" for certain
> devices at boot?

Well, in my view the "external facing" firmware property *should* 
effectively be the "I don't trust this device not to misbehave" 
property, but I guess it's a bit too conflated with other aspects of 
Thunderbolt root ports (at least in the ACPI definition) to abuse in 
that manner.

Ideas off the top of my head would be to flip the default domain type 
and manually relax all the other performance-sensitive devices instead, 
or module_blacklist the modem driver to load manually later after 
tweaking its group. However, if you think it's a sufficiently general 
concern, maybe a quirk to set pci_dev->untrusted might be worth 
exploring? It may make sense to drive such a thing from a command-line 
option rather than a hard-coded list, though, since trust is really down 
to the individual use-case.

[ re gitlab.arm.com, I understand it tends not to like large transfers - 
some colleagues have reported similar issues pushing large repos as 
well. I'd suggest cloning the base mainline repo from kernel.org or 
another reliable source, then fetching my branch into that. I've just 
tried that on a different machine (outside the work network) and it 
worked fine) ]

Thanks,
Robin.


From tabba at google.com  Tue Aug  3 01:22:03 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 3 Aug 2021 10:22:03 +0200
Subject: [PATCH v3 20/21] KVM: arm64: Restrict EL2 stage-1 changes in
 protected mode
In-Reply-To: <20210729132818.4091769-21-qperret@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-21-qperret@google.com>
Message-ID: <CA+EHjTw7W=5JqH+oZAqLPrf_6222eazDnSk24h4EuGE1VLwKYg@mail.gmail.com>

Hi Quentin,

> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 0ccea58df7e0..1b67f562b6fc 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -338,6 +338,95 @@ static int host_stage2_idmap(u64 addr)
>         return ret;
>  }
>
> +static inline bool check_prot(enum kvm_pgtable_prot prot,
> +                             enum kvm_pgtable_prot required,
> +                             enum kvm_pgtable_prot denied)
> +{
> +       return (prot & (required | denied)) == required;
> +}
> +
> +int __pkvm_host_share_hyp(u64 pfn)
> +{
> +       phys_addr_t addr = hyp_pfn_to_phys(pfn);
> +       enum kvm_pgtable_prot prot, cur;
> +       void *virt = __hyp_va(addr);
> +       enum pkvm_page_state state;
> +       kvm_pte_t pte;
> +       u32 level;
> +       int ret;
> +
> +       if (!range_is_memory(addr, addr + PAGE_SIZE))
> +               return -EINVAL;
> +
> +       hyp_spin_lock(&host_kvm.lock);
> +       hyp_spin_lock(&pkvm_pgd_lock);
> +
> +       ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, &level);
> +       if (ret)
> +               goto unlock;
> +       if (!pte)
> +               goto map_shared;

Should this check whether kvm_pte_valid as well, is that guaranteed to
always be the case, or implicitly handled later?

> +
> +       /*
> +        * Check attributes in the host stage-2 PTE. We need the page to be:
> +        *  - mapped RWX as we're sharing memory;
> +        *  - not borrowed, as that implies absence of ownership.
> +        * Otherwise, we can't let it got through
> +        */
> +       cur = kvm_pgtable_stage2_pte_prot(pte);
> +       prot = pkvm_mkstate(0, PKVM_PAGE_SHARED_BORROWED);
> +       if (!check_prot(cur, KVM_PGTABLE_PROT_RWX, prot)) {
> +               ret = -EPERM;
> +               goto unlock;
> +       }
> +
> +       state = pkvm_getstate(cur);
> +       if (state == PKVM_PAGE_OWNED)
> +               goto map_shared;
> +
> +       /*
> +        * Tolerate double-sharing the same page, but this requires
> +        * cross-checking the hypervisor stage-1.
> +        */
> +       if (state != PKVM_PAGE_SHARED_OWNED) {
> +               ret = -EPERM;
> +               goto unlock;
> +       }
> +
> +       ret = kvm_pgtable_get_leaf(&pkvm_pgtable, (u64)virt, &pte, &level);
> +       if (ret)
> +               goto unlock;
> +
> +       /*
> +        * If the page has been shared with the hypervisor, it must be
> +        * SHARED_BORROWED already.
> +        */

This comment confused me at first, but then I realized it's referring
to the page from the hyp's point of view. Could you add something to
the comment to that effect?

It might also make it easier to follow if the variables could be
annotated to specify whether cur, state, and prot are the host's or
hyps (and not reuse the same one for both).

> +       cur = kvm_pgtable_hyp_pte_prot(pte);
> +       prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
> +       if (!check_prot(cur, prot, ~prot))
> +               ret = EPERM;
> +       goto unlock;
> +
> +map_shared:
> +       /*
> +        * If the page is not yet shared, adjust mappings in both page-tables
> +        * while both locks are held.
> +        */
> +       prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
> +       ret = pkvm_create_mappings_locked(virt, virt + PAGE_SIZE, prot);
> +       BUG_ON(ret);
> +
> +       prot = pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_OWNED);
> +       ret = host_stage2_idmap_locked(addr, addr + PAGE_SIZE, prot);
> +       BUG_ON(ret);
> +
> +unlock:
> +       hyp_spin_unlock(&pkvm_pgd_lock);
> +       hyp_spin_unlock(&host_kvm.lock);
> +
> +       return ret;
> +}
> +
>  void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
>  {
>         struct kvm_vcpu_fault_info fault;
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 0625bf2353c2..cbab146cda6a 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -259,10 +259,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size,
>  {
>         int err;
>
> -       if (!kvm_host_owns_hyp_mappings()) {
> -               return kvm_call_hyp_nvhe(__pkvm_create_mappings,
> -                                        start, size, phys, prot);
> -       }
> +       if (WARN_ON(!kvm_host_owns_hyp_mappings()))
> +               return -EINVAL;
>
>         mutex_lock(&kvm_hyp_pgd_mutex);
>         err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot);
> @@ -282,6 +280,21 @@ static phys_addr_t kvm_kaddr_to_phys(void *kaddr)
>         }
>  }
>
> +static int pkvm_share_hyp(phys_addr_t start, phys_addr_t end)
> +{
> +       phys_addr_t addr;
> +       int ret;
> +
> +       for (addr = ALIGN_DOWN(start, PAGE_SIZE); addr < end; addr += PAGE_SIZE) {
> +               ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp,
> +                                       __phys_to_pfn(addr));

I guess we don't expect this to happen often, but I wonder if it would
be better to have the looping in the hyp call rather than here, to
reduce the number of hyp calls when sharing.

Thanks,
/fuad

> +               if (ret)
> +                       return ret;
> +       }
> +
> +       return 0;
> +}
> +
>  /**
>   * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode
>   * @from:      The virtual kernel start address of the range
> @@ -302,6 +315,13 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>         if (is_kernel_in_hyp_mode())
>                 return 0;
>
> +       if (!kvm_host_owns_hyp_mappings()) {
> +               if (WARN_ON(prot != PAGE_HYP))
> +                       return -EPERM;
> +               return pkvm_share_hyp(kvm_kaddr_to_phys(from),
> +                                     kvm_kaddr_to_phys(to));
> +       }
> +
>         start = start & PAGE_MASK;
>         end = PAGE_ALIGN(end);
>
> --
> 2.32.0.432.gabb21c7263-goog
>


From dqfext at gmail.com  Tue Aug  3 01:23:16 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue,  3 Aug 2021 16:23:16 +0800
Subject: [RFC net-next v2 3/4] net: dsa: mt7530: set STP state also on
 filter ID 1
In-Reply-To: <20210802210006.fhmb5s6dsnziyk7d@skbuf>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-4-dqfext@gmail.com>
 <20210802134336.gv66le6u2z52kfkh@skbuf>
 <20210802153129.1817825-1-dqfext@gmail.com>
 <20210802154226.qggqzkxe6urkx3yf@skbuf>
 <20210802155810.1818085-1-dqfext@gmail.com>
 <20210802210006.fhmb5s6dsnziyk7d@skbuf>
Message-ID: <20210803082316.2910759-1-dqfext@gmail.com>

On Tue, Aug 03, 2021 at 12:00:06AM +0300, Vladimir Oltean wrote:
> 
> So then change the port STP state only for FID 1 and resend. Any other
> reason why this patch series is marked RFC? It looked okay to me otherwise.

Okay, will resend with that change and without RFC.

By the way, if I were to implement .port_fast_age, should I only flush
dynamically learned FDB entries? What about MDB entries?


From robin.murphy at arm.com  Tue Aug  3 01:35:12 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 3 Aug 2021 09:35:12 +0100
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
Message-ID: <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>

On 2021-08-03 03:11, Sunil Muthuswamy wrote:
>   On Saturday, July 31, 2021 2:52 AM,
>   Marc Zyngier <maz at kernel.org> wrote:
>>
>> [...]
>>
>>>> I also want to understand *how* you are going to plumb this into both
>>>> ACPI and DT, given that neither understand how to link a PCI endpoint
>>>> to a set of RDs.
>>>>
>>>> 	M.
>>>
>>> One way to do this for NUMA-aware systems would be to use the NUMA
>>> related information that is available with PCI endpoints or root complex, to
>>> pick a Redistributor/CPU that is in the NUMA node, as specified by the PCI
>>> endpoint/root complex. In DT PCI devices can specify this using
>>> 'numa-node-id' and in ACPI using the '_PXM (Proximity)'. For systems that
>>> are not NUMA-aware, we can go with *any* Redistributor/CPU.
>>
>> This makes zero sense. From the point of view of a device, all the RDs
>> should be reachable, and firmware has no say in it. Dealing with
>> interrupt affinity is the responsibility of the endpoint driver, and
>> NUMA affinity is only a performance optimisation.
>>
>>> Is there any additional information we would be able to gather from ACPI
>>> or DT that's not there currently, that would be useful here?
>>
>> You will need some firmware information describing that a given set of
>> devices must use the RDs for their MSIs. Just like we currently
>> describe it in IORT for the ITS. You cannot /assume/ things. At the
>> moment, there is nothing at all, because no-one (including Microsoft)
>> thought it would be a good idea not to have an ITS, which is also why
>> ACPI doesn't describe MBIs as a potential MSI provider.
>>
> I am a little bit confused by your above comment. Maybe you can help me
> understand the ask. You indicate that from the point of the view of the
> device, all the RDs should be reachable. But, then if we define a mapping
> between PCI endpoint and RD in the firmware, we would be doing exactly
> the opposite. i.e. restricting the RDs that are reachable by the device. Can
> you please clarify?
> 
> Is your concern that the device should be able to only DMA to a subset of
> GIC Redistributor, for the MSIs? If so, in the IORT, there is "memory address
> size limit" for both device and root complex nodes. In the implementation,
> we can enforce that the GICR is within that range. And, if a device deviates
> further than that (ex: by having accessibility gaps within the GICR range),
> then that is out of scope for support.

No, please don't try to abuse the Memory Address Size Limit - that has 
far more chance of adversely affecting normal DMA operation than of 
being any use here.

I believe the point Marc was trying to make is that firmware should not 
associate a device with any one *specific* redistributor, however ACPI 
currently has no way to describe that MSIs can target redistributors *at 
all*, only ITS groups - there is no such concept as a "redistributor group".

Robin.


From olteanv at gmail.com  Tue Aug  3 01:48:48 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 3 Aug 2021 11:48:48 +0300
Subject: [RFC net-next v2 3/4] net: dsa: mt7530: set STP state also on
 filter ID 1
In-Reply-To: <20210803082316.2910759-1-dqfext@gmail.com>
References: <20210731191023.1329446-1-dqfext@gmail.com>
 <20210731191023.1329446-4-dqfext@gmail.com>
 <20210802134336.gv66le6u2z52kfkh@skbuf>
 <20210802153129.1817825-1-dqfext@gmail.com>
 <20210802154226.qggqzkxe6urkx3yf@skbuf>
 <20210802155810.1818085-1-dqfext@gmail.com>
 <20210802210006.fhmb5s6dsnziyk7d@skbuf>
 <20210803082316.2910759-1-dqfext@gmail.com>
Message-ID: <20210803084848.cdvc5qxseott54yy@skbuf>

On Tue, Aug 03, 2021 at 04:23:16PM +0800, DENG Qingfang wrote:
> On Tue, Aug 03, 2021 at 12:00:06AM +0300, Vladimir Oltean wrote:
> > 
> > So then change the port STP state only for FID 1 and resend. Any other
> > reason why this patch series is marked RFC? It looked okay to me otherwise.
> 
> Okay, will resend with that change and without RFC.
> 
> By the way, if I were to implement .port_fast_age, should I only flush
> dynamically learned FDB entries? What about MDB entries?

Yes, only dynamically learned entries. That should also answer the
question about MDB entries, since a multicast address should never be a
source MAC address so they should never be dynamically learned.
The bridge should handle the deletion of static entries when needed.


From lukasz.luba at arm.com  Tue Aug  3 01:49:18 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 3 Aug 2021 09:49:18 +0100
Subject: [PATCH] cpufreq: arm_scmi: Fix error path when allocation failed
In-Reply-To: <20210803043445.7sm4mnl4f5f7co7h@vireshk-i7>
References: <20210802204550.12647-1-lukasz.luba@arm.com>
 <20210803043445.7sm4mnl4f5f7co7h@vireshk-i7>
Message-ID: <455e76f8-43c5-2976-e10b-a0fffeaee25f@arm.com>

Hi Viresh,

On 8/3/21 5:34 AM, Viresh Kumar wrote:
> On 02-08-21, 21:45, Lukasz Luba wrote:
>> Print warning and return an error which would stop the initialization
>> when cpumask allocation failed.
>>
>> Fixes: 80a064dbd556 ("scmi-cpufreq: Get opp_shared_cpus from opp-v2 for EM")
>> Signed-off-by: Lukasz Luba <lukasz.luba at arm.com>
>> ---
>>   drivers/cpufreq/scmi-cpufreq.c | 6 ++++--
>>   1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
>> index ec9a87ca2dbb..b159123e68fd 100644
>> --- a/drivers/cpufreq/scmi-cpufreq.c
>> +++ b/drivers/cpufreq/scmi-cpufreq.c
>> @@ -133,8 +133,10 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
>>   		return -ENODEV;
>>   	}
>>   
>> -	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL))
>> -		ret = -ENOMEM;
>> +	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL)) {
>> +		dev_warn(cpu_dev, "failed to allocate cpumask\n");
> 
> We shouldn't be printing here anything I believe as the allocation
> core does it for us. That's why you won't see a print message anywhere
> for failed allocations.

Thanks for the comment. Let me send the v2.


From will at kernel.org  Tue Aug  3 02:06:26 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 3 Aug 2021 10:06:26 +0100
Subject: [PATCH] arm64: move the (z)install rules to arch/arm64/Makefile
In-Reply-To: <CAK7LNARFWRgGsea03mZJfSPjyxYLxz3g6fjTs9aon9hxYvsxcw@mail.gmail.com>
References: <20210729140527.443116-1-masahiroy@kernel.org>
 <20210802124624.GG18685@arm.com>
 <CAK7LNARFWRgGsea03mZJfSPjyxYLxz3g6fjTs9aon9hxYvsxcw@mail.gmail.com>
Message-ID: <20210803090626.GA30265@willie-the-truck>

On Tue, Aug 03, 2021 at 02:40:44PM +0900, Masahiro Yamada wrote:
> On Mon, Aug 2, 2021 at 9:46 PM Catalin Marinas <catalin.marinas at arm.com> wrote:
> >
> > On Thu, Jul 29, 2021 at 11:05:27PM +0900, Masahiro Yamada wrote:
> > > Currently, the (z)install targets in arch/arm64/Makefile descend into
> > > arch/arm64/boot/Makefile to invoke the shell script, but there is no
> > > good reason to do so.
> > >
> > > arch/arm64/Makefile can run the shell script directly.
> > >
> > > Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> > > ---
> > >
> > >  arch/arm64/Makefile      | 7 +++++--
> > >  arch/arm64/boot/Makefile | 8 --------
> > >  2 files changed, 5 insertions(+), 10 deletions(-)
> >
> > Is this part of some cross-arch clean-up? I can see x86 for example does
> > the same thing.
> >
> > Thanks.
> >
> 
> Yes. I want to do these cleanups tree-wide, but
> I sent patches per arch.
> 
> Please pick it up to your arm64 tree
> if you do not mind.

Just to confirm -- this would be for 5.15, right?

Will


From tzimmermann at suse.de  Tue Aug  3 02:06:50 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:50 +0200
Subject: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
Message-ID: <20210803090704.32152-1-tzimmermann@suse.de>

DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
IRQ interfaces.

DRM provides IRQ helpers for setting up, receiving and removing IRQ
handlers. It's an abstraction over plain Linux functions. The code
is mid-layerish with several callbacks to hook into the rsp drivers.
Old UMS driver have their interrupts enabled via ioctl, so these
abstractions makes some sense. Modern KMS manage all their interrupts
internally. Using the DRM helpers adds indirection without benefits.

Most KMS drivers already use Linux IRQ functions instead of DRM's
abstraction layer. Patches 1 to 12 convert the remaining ones.
The patches also resolve a bug for devices without assigned interrupt
number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
not detect if the device has no interrupt assigned.

Patch 13 removes an unused function.

Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
the old non-KMS drivers still use the functionality.

v2:
	* drop IRQ_NOTCONNECTED test from atmel-hlcdc (Sam)
	* use devm_request_irq() in atmel-hlcdc (Sam)
	* unify variable names in arm/hlcdc (Sam)

Thomas Zimmermann (14):
  drm/amdgpu: Convert to Linux IRQ interfaces
  drm/arm/hdlcd: Convert to Linux IRQ interfaces
  drm/atmel-hlcdc: Convert to Linux IRQ interfaces
  drm/fsl-dcu: Convert to Linux IRQ interfaces
  drm/gma500: Convert to Linux IRQ interfaces
  drm/kmb: Convert to Linux IRQ interfaces
  drm/msm: Convert to Linux IRQ interfaces
  drm/mxsfb: Convert to Linux IRQ interfaces
  drm/radeon: Convert to Linux IRQ interfaces
  drm/tidss: Convert to Linux IRQ interfaces
  drm/tilcdc: Convert to Linux IRQ interfaces
  drm/vc4: Convert to Linux IRQ interfaces
  drm: Remove unused devm_drm_irq_install()
  drm: IRQ midlayer is now legacy

 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c      |   1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c      |  21 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h      |   2 +-
 drivers/gpu/drm/arm/hdlcd_drv.c              | 174 ++++++++++---------
 drivers/gpu/drm/arm/hdlcd_drv.h              |   1 +
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c |  80 +++++----
 drivers/gpu/drm/drm_irq.c                    |  95 +---------
 drivers/gpu/drm/drm_legacy_misc.c            |   3 +-
 drivers/gpu/drm/drm_vblank.c                 |   8 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c    |  78 +++++----
 drivers/gpu/drm/gma500/power.c               |   1 +
 drivers/gpu/drm/gma500/psb_drv.c             |   8 +-
 drivers/gpu/drm/gma500/psb_drv.h             |   5 -
 drivers/gpu/drm/gma500/psb_irq.c             |  26 ++-
 drivers/gpu/drm/gma500/psb_irq.h             |   4 +-
 drivers/gpu/drm/i810/i810_dma.c              |   3 +-
 drivers/gpu/drm/kmb/kmb_drv.c                |  26 ++-
 drivers/gpu/drm/mga/mga_dma.c                |   2 +-
 drivers/gpu/drm/mga/mga_drv.h                |   1 -
 drivers/gpu/drm/msm/msm_drv.c                | 113 +++++++-----
 drivers/gpu/drm/msm/msm_kms.h                |   2 +-
 drivers/gpu/drm/mxsfb/mxsfb_drv.c            |  81 +++++----
 drivers/gpu/drm/mxsfb/mxsfb_drv.h            |   2 +
 drivers/gpu/drm/r128/r128_cce.c              |   3 +-
 drivers/gpu/drm/radeon/radeon_drv.c          |   4 -
 drivers/gpu/drm/radeon/radeon_irq_kms.c      |  44 ++++-
 drivers/gpu/drm/radeon/radeon_kms.h          |   4 -
 drivers/gpu/drm/tidss/tidss_drv.c            |  15 +-
 drivers/gpu/drm/tidss/tidss_drv.h            |   2 +
 drivers/gpu/drm/tidss/tidss_irq.c            |  27 ++-
 drivers/gpu/drm/tidss/tidss_irq.h            |   4 +-
 drivers/gpu/drm/tilcdc/tilcdc_drv.c          |  51 ++++--
 drivers/gpu/drm/tilcdc/tilcdc_drv.h          |   3 +
 drivers/gpu/drm/vc4/vc4_drv.c                |   4 -
 drivers/gpu/drm/vc4/vc4_drv.h                |   8 +-
 drivers/gpu/drm/vc4/vc4_irq.c                |  48 +++--
 drivers/gpu/drm/vc4/vc4_v3d.c                |  17 +-
 drivers/gpu/drm/via/via_mm.c                 |   3 +-
 include/drm/drm_device.h                     |  18 +-
 include/drm/drm_drv.h                        |  44 +----
 include/drm/drm_irq.h                        |  32 ----
 include/drm/drm_legacy.h                     |   3 +
 42 files changed, 567 insertions(+), 504 deletions(-)
 delete mode 100644 include/drm/drm_irq.h


base-commit: c9d6903562aa335593daf44b4a1edeaef6bf9206
prerequisite-patch-id: c2b2f08f0eccc9f5df0c0da49fa1d36267deb11d
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: c3f32630e1d2de2eb74316c930578847d4b83fb3
prerequisite-patch-id: b32ca0abfc255601f8a5052d3b88be09527dabcb
prerequisite-patch-id: 22a3f264168bacb04ef65306b32b86be8dc982ef
prerequisite-patch-id: 095a0acb604eb02956e1a7e53da41371c64eb813
prerequisite-patch-id: 7a2417d5d8d453204bd94aa873e3faae812f26fc
--
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:53 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:53 +0200
Subject: [PATCH v2 03/14] drm/atmel-hlcdc: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-4-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it. DRM IRQ callbacks are now being called
directly or inlined.

v2:
	* use managed release via devm_request_irq() (Sam)
	* drop extra test for irq != IRQ_NOTCONNECTED (Sam)

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Reviewed-by: Sam Ravnborg <sam at ravnborg.org>
Tested-by: Dan Sneddon <Dan.Sneddon at microchip.com>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 80 ++++++++++++--------
 1 file changed, 47 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index f09b6dd8754c..1656d27b78b6 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -22,7 +22,6 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -557,6 +556,51 @@ static irqreturn_t atmel_hlcdc_dc_irq_handler(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static void atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
+{
+	struct atmel_hlcdc_dc *dc = dev->dev_private;
+	unsigned int cfg = 0;
+	int i;
+
+	/* Enable interrupts on activated layers */
+	for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
+		if (dc->layers[i])
+			cfg |= ATMEL_HLCDC_LAYER_STATUS(i);
+	}
+
+	regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, cfg);
+}
+
+static void atmel_hlcdc_dc_irq_disable(struct drm_device *dev)
+{
+	struct atmel_hlcdc_dc *dc = dev->dev_private;
+	unsigned int isr;
+
+	regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, 0xffffffff);
+	regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr);
+}
+
+static int atmel_hlcdc_dc_irq_install(struct drm_device *dev, unsigned int irq)
+{
+	int ret;
+
+	atmel_hlcdc_dc_irq_disable(dev);
+
+	ret = devm_request_irq(dev->dev, irq, atmel_hlcdc_dc_irq_handler, 0,
+			       dev->driver->name, dev);
+	if (ret)
+		return ret;
+
+	atmel_hlcdc_dc_irq_postinstall(dev);
+
+	return 0;
+}
+
+static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev)
+{
+	atmel_hlcdc_dc_irq_disable(dev);
+}
+
 static const struct drm_mode_config_funcs mode_config_funcs = {
 	.fb_create = drm_gem_fb_create,
 	.atomic_check = drm_atomic_helper_check,
@@ -647,7 +691,7 @@ static int atmel_hlcdc_dc_load(struct drm_device *dev)
 	drm_mode_config_reset(dev);
 
 	pm_runtime_get_sync(dev->dev);
-	ret = drm_irq_install(dev, dc->hlcdc->irq);
+	ret = atmel_hlcdc_dc_irq_install(dev, dc->hlcdc->irq);
 	pm_runtime_put_sync(dev->dev);
 	if (ret < 0) {
 		dev_err(dev->dev, "failed to install IRQ handler\n");
@@ -676,7 +720,7 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
 	drm_mode_config_cleanup(dev);
 
 	pm_runtime_get_sync(dev->dev);
-	drm_irq_uninstall(dev);
+	atmel_hlcdc_dc_irq_uninstall(dev);
 	pm_runtime_put_sync(dev->dev);
 
 	dev->dev_private = NULL;
@@ -685,40 +729,10 @@ static void atmel_hlcdc_dc_unload(struct drm_device *dev)
 	clk_disable_unprepare(dc->hlcdc->periph_clk);
 }
 
-static int atmel_hlcdc_dc_irq_postinstall(struct drm_device *dev)
-{
-	struct atmel_hlcdc_dc *dc = dev->dev_private;
-	unsigned int cfg = 0;
-	int i;
-
-	/* Enable interrupts on activated layers */
-	for (i = 0; i < ATMEL_HLCDC_MAX_LAYERS; i++) {
-		if (dc->layers[i])
-			cfg |= ATMEL_HLCDC_LAYER_STATUS(i);
-	}
-
-	regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IER, cfg);
-
-	return 0;
-}
-
-static void atmel_hlcdc_dc_irq_uninstall(struct drm_device *dev)
-{
-	struct atmel_hlcdc_dc *dc = dev->dev_private;
-	unsigned int isr;
-
-	regmap_write(dc->hlcdc->regmap, ATMEL_HLCDC_IDR, 0xffffffff);
-	regmap_read(dc->hlcdc->regmap, ATMEL_HLCDC_ISR, &isr);
-}
-
 DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver atmel_hlcdc_dc_driver = {
 	.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
-	.irq_handler = atmel_hlcdc_dc_irq_handler,
-	.irq_preinstall = atmel_hlcdc_dc_irq_uninstall,
-	.irq_postinstall = atmel_hlcdc_dc_irq_postinstall,
-	.irq_uninstall = atmel_hlcdc_dc_irq_uninstall,
 	DRM_GEM_CMA_DRIVER_OPS,
 	.fops = &fops,
 	.name = "atmel-hlcdc",
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:51 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:51 +0200
Subject: [PATCH v2 01/14] drm/amdgpu: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-2-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

The interrupt number returned by pci_msi_vector() is now stored
in struct amdgpu_irq. Calls to pci_msi_vector() can fail and return
a negative errno code. Abort initlaizaton in thi case. The DRM IRQ
midlayer does not handle this correctly.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
Acked-by: Christian K?nig <christian.koenig at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 21 ++++++++++++++-------
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h |  2 +-
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index d637b0536f84..2b0b0e8a6acb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -1777,7 +1777,6 @@ static const struct drm_driver amdgpu_kms_driver = {
 	.open = amdgpu_driver_open_kms,
 	.postclose = amdgpu_driver_postclose_kms,
 	.lastclose = amdgpu_driver_lastclose_kms,
-	.irq_handler = amdgpu_irq_handler,
 	.ioctls = amdgpu_ioctls_kms,
 	.num_ioctls = ARRAY_SIZE(amdgpu_ioctls_kms),
 	.dumb_create = amdgpu_mode_dumb_create,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 7dfdabe1cdf9..3ac39b44a211 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -46,7 +46,6 @@
 #include <linux/pci.h>
 
 #include <drm/drm_crtc_helper.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_vblank.h>
 #include <drm/amdgpu_drm.h>
 #include <drm/drm_drv.h>
@@ -184,7 +183,7 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev)
  * Returns:
  * result of handling the IRQ, as defined by &irqreturn_t
  */
-irqreturn_t amdgpu_irq_handler(int irq, void *arg)
+static irqreturn_t amdgpu_irq_handler(int irq, void *arg)
 {
 	struct drm_device *dev = (struct drm_device *) arg;
 	struct amdgpu_device *adev = drm_to_adev(dev);
@@ -307,6 +306,7 @@ static void amdgpu_restore_msix(struct amdgpu_device *adev)
 int amdgpu_irq_init(struct amdgpu_device *adev)
 {
 	int r = 0;
+	unsigned int irq;
 
 	spin_lock_init(&adev->irq.lock);
 
@@ -349,15 +349,22 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 	INIT_WORK(&adev->irq.ih2_work, amdgpu_irq_handle_ih2);
 	INIT_WORK(&adev->irq.ih_soft_work, amdgpu_irq_handle_ih_soft);
 
-	adev->irq.installed = true;
-	/* Use vector 0 for MSI-X */
-	r = drm_irq_install(adev_to_drm(adev), pci_irq_vector(adev->pdev, 0));
+	/* Use vector 0 for MSI-X. */
+	r = pci_irq_vector(adev->pdev, 0);
+	if (r < 0)
+		return r;
+	irq = r;
+
+	/* PCI devices require shared interrupts. */
+	r = request_irq(irq, amdgpu_irq_handler, IRQF_SHARED, adev_to_drm(adev)->driver->name,
+			adev_to_drm(adev));
 	if (r) {
-		adev->irq.installed = false;
 		if (!amdgpu_device_has_dc_support(adev))
 			flush_work(&adev->hotplug_work);
 		return r;
 	}
+	adev->irq.installed = true;
+	adev->irq.irq = irq;
 	adev_to_drm(adev)->max_vblank_count = 0x00ffffff;
 
 	DRM_DEBUG("amdgpu: irq initialized.\n");
@@ -368,7 +375,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
 void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
 {
 	if (adev->irq.installed) {
-		drm_irq_uninstall(&adev->ddev);
+		free_irq(adev->irq.irq, adev_to_drm(adev));
 		adev->irq.installed = false;
 		if (adev->irq.msi_enabled)
 			pci_free_irq_vectors(adev->pdev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
index 78ad4784cc74..e9f2c11ea416 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h
@@ -80,6 +80,7 @@ struct amdgpu_irq_src_funcs {
 
 struct amdgpu_irq {
 	bool				installed;
+	unsigned int			irq;
 	spinlock_t			lock;
 	/* interrupt sources */
 	struct amdgpu_irq_client	client[AMDGPU_IRQ_CLIENTID_MAX];
@@ -100,7 +101,6 @@ struct amdgpu_irq {
 };
 
 void amdgpu_irq_disable_all(struct amdgpu_device *adev);
-irqreturn_t amdgpu_irq_handler(int irq, void *arg);
 
 int amdgpu_irq_init(struct amdgpu_device *adev);
 void amdgpu_irq_fini_sw(struct amdgpu_device *adev);
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:54 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:54 +0200
Subject: [PATCH v2 04/14] drm/fsl-dcu: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-5-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it. DRM IRQ callbacks are now being called
directly or inlined.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 78 +++++++++++++----------
 1 file changed, 46 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 7528e8a2d359..660fe573db96 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -23,7 +23,6 @@
 #include <drm/drm_fb_cma_helper.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_modeset_helper.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
@@ -51,7 +50,7 @@ static const struct regmap_config fsl_dcu_regmap_config = {
 	.volatile_reg = fsl_dcu_drm_is_volatile_reg,
 };
 
-static void fsl_dcu_irq_uninstall(struct drm_device *dev)
+static void fsl_dcu_irq_reset(struct drm_device *dev)
 {
 	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
 
@@ -59,6 +58,45 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev)
 	regmap_write(fsl_dev->regmap, DCU_INT_MASK, ~0);
 }
 
+static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+	unsigned int int_status;
+	int ret;
+
+	ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status);
+	if (ret) {
+		dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
+		return IRQ_NONE;
+	}
+
+	if (int_status & DCU_INT_STATUS_VBLANK)
+		drm_handle_vblank(dev, 0);
+
+	regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
+
+	return IRQ_HANDLED;
+}
+
+static int fsl_dcu_irq_install(struct drm_device *dev, unsigned int irq)
+{
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	fsl_dcu_irq_reset(dev);
+
+	return request_irq(irq, fsl_dcu_drm_irq, 0, dev->driver->name, dev);
+}
+
+static void fsl_dcu_irq_uninstall(struct drm_device *dev)
+{
+	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+
+	fsl_dcu_irq_reset(dev);
+	free_irq(fsl_dev->irq, dev);
+}
+
 static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
 {
 	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
@@ -73,13 +111,13 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
 	if (ret < 0) {
 		dev_err(dev->dev, "failed to initialize vblank\n");
-		goto done;
+		goto done_vblank;
 	}
 
-	ret = drm_irq_install(dev, fsl_dev->irq);
+	ret = fsl_dcu_irq_install(dev, fsl_dev->irq);
 	if (ret < 0) {
 		dev_err(dev->dev, "failed to install IRQ handler\n");
-		goto done;
+		goto done_irq;
 	}
 
 	if (legacyfb_depth != 16 && legacyfb_depth != 24 &&
@@ -90,11 +128,11 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
 	}
 
 	return 0;
-done:
+done_irq:
 	drm_kms_helper_poll_fini(dev);
 
 	drm_mode_config_cleanup(dev);
-	drm_irq_uninstall(dev);
+done_vblank:
 	dev->dev_private = NULL;
 
 	return ret;
@@ -106,41 +144,17 @@ static void fsl_dcu_unload(struct drm_device *dev)
 	drm_kms_helper_poll_fini(dev);
 
 	drm_mode_config_cleanup(dev);
-	drm_irq_uninstall(dev);
+	fsl_dcu_irq_uninstall(dev);
 
 	dev->dev_private = NULL;
 }
 
-static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
-{
-	struct drm_device *dev = arg;
-	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
-	unsigned int int_status;
-	int ret;
-
-	ret = regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status);
-	if (ret) {
-		dev_err(dev->dev, "read DCU_INT_STATUS failed\n");
-		return IRQ_NONE;
-	}
-
-	if (int_status & DCU_INT_STATUS_VBLANK)
-		drm_handle_vblank(dev, 0);
-
-	regmap_write(fsl_dev->regmap, DCU_INT_STATUS, int_status);
-
-	return IRQ_HANDLED;
-}
-
 DEFINE_DRM_GEM_CMA_FOPS(fsl_dcu_drm_fops);
 
 static const struct drm_driver fsl_dcu_drm_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
 	.load			= fsl_dcu_load,
 	.unload			= fsl_dcu_unload,
-	.irq_handler		= fsl_dcu_drm_irq,
-	.irq_preinstall		= fsl_dcu_irq_uninstall,
-	.irq_uninstall		= fsl_dcu_irq_uninstall,
 	DRM_GEM_CMA_DRIVER_OPS,
 	.fops			= &fsl_dcu_drm_fops,
 	.name			= "fsl-dcu-drm",
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:56 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:56 +0200
Subject: [PATCH v2 06/14] drm/kmb: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-7-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/kmb/kmb_drv.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c
index f54392ec4fab..1c2f4799f421 100644
--- a/drivers/gpu/drm/kmb/kmb_drv.c
+++ b/drivers/gpu/drm/kmb/kmb_drv.c
@@ -17,7 +17,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 
@@ -413,14 +412,29 @@ static void kmb_irq_reset(struct drm_device *drm)
 	kmb_write_lcd(to_kmb(drm), LCD_INT_ENABLE, 0);
 }
 
+static int kmb_irq_install(struct drm_device *drm, unsigned int irq)
+{
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	kmb_irq_reset(drm);
+
+	return request_irq(irq, kmb_isr, 0, drm->driver->name, drm);
+}
+
+static void kmb_irq_uninstall(struct drm_device *drm)
+{
+	struct kmb_drm_private *kmb = to_kmb(drm);
+
+	kmb_irq_reset(drm);
+	free_irq(kmb->irq_lcd, drm);
+}
+
 DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver kmb_driver = {
 	.driver_features = DRIVER_GEM |
 	    DRIVER_MODESET | DRIVER_ATOMIC,
-	.irq_handler = kmb_isr,
-	.irq_preinstall = kmb_irq_reset,
-	.irq_uninstall = kmb_irq_reset,
 	/* GEM Operations */
 	.fops = &fops,
 	DRM_GEM_CMA_DRIVER_OPS_VMAP,
@@ -442,7 +456,7 @@ static int kmb_remove(struct platform_device *pdev)
 	of_node_put(kmb->crtc.port);
 	kmb->crtc.port = NULL;
 	pm_runtime_get_sync(drm->dev);
-	drm_irq_uninstall(drm);
+	kmb_irq_uninstall(drm);
 	pm_runtime_put_sync(drm->dev);
 	pm_runtime_disable(drm->dev);
 
@@ -532,7 +546,7 @@ static int kmb_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_free;
 
-	ret = drm_irq_install(&kmb->drm, kmb->irq_lcd);
+	ret = kmb_irq_install(&kmb->drm, kmb->irq_lcd);
 	if (ret < 0) {
 		drm_err(&kmb->drm, "failed to install IRQ handler\n");
 		goto err_irq;
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:55 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:55 +0200
Subject: [PATCH v2 05/14] drm/gma500: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-6-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it. DRM IRQ callbacks are now being called
directly or inlined.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/gma500/power.c   |  1 +
 drivers/gpu/drm/gma500/psb_drv.c |  8 ++------
 drivers/gpu/drm/gma500/psb_drv.h |  5 -----
 drivers/gpu/drm/gma500/psb_irq.c | 26 ++++++++++++++++++++++++--
 drivers/gpu/drm/gma500/psb_irq.h |  4 ++--
 5 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/gma500/power.c b/drivers/gpu/drm/gma500/power.c
index f07641dfa5a4..20ace6010f9f 100644
--- a/drivers/gpu/drm/gma500/power.c
+++ b/drivers/gpu/drm/gma500/power.c
@@ -32,6 +32,7 @@
 #include "psb_drv.h"
 #include "psb_reg.h"
 #include "psb_intel_reg.h"
+#include "psb_irq.h"
 #include <linux/mutex.h>
 #include <linux/pm_runtime.h>
 
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 3850842d58f3..58bce1a60a4d 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -23,7 +23,6 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_pciids.h>
 #include <drm/drm_vblank.h>
 
@@ -33,6 +32,7 @@
 #include "power.h"
 #include "psb_drv.h"
 #include "psb_intel_reg.h"
+#include "psb_irq.h"
 #include "psb_reg.h"
 
 static const struct drm_driver driver;
@@ -380,7 +380,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
 	PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
 	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 
-	drm_irq_install(dev, pdev->irq);
+	psb_irq_install(dev, pdev->irq);
 
 	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
 
@@ -515,10 +515,6 @@ static const struct drm_driver driver = {
 	.lastclose = drm_fb_helper_lastclose,
 
 	.num_ioctls = ARRAY_SIZE(psb_ioctls),
-	.irq_preinstall = psb_irq_preinstall,
-	.irq_postinstall = psb_irq_postinstall,
-	.irq_uninstall = psb_irq_uninstall,
-	.irq_handler = psb_irq_handler,
 
 	.dumb_create = psb_gem_dumb_create,
 	.ioctls = psb_ioctls,
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index d6e7c2c2c947..f2bae270ca7b 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -624,11 +624,6 @@ static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
 }
 
 /* psb_irq.c */
-extern irqreturn_t psb_irq_handler(int irq, void *arg);
-extern void psb_irq_preinstall(struct drm_device *dev);
-extern int psb_irq_postinstall(struct drm_device *dev);
-extern void psb_irq_uninstall(struct drm_device *dev);
-
 extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
 extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
 extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 104009e78487..deb1fbc1f748 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -8,6 +8,7 @@
  *
  **************************************************************************/
 
+#include <drm/drm_drv.h>
 #include <drm/drm_vblank.h>
 
 #include "power.h"
@@ -222,7 +223,7 @@ static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2)
 	PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2);
 }
 
-irqreturn_t psb_irq_handler(int irq, void *arg)
+static irqreturn_t psb_irq_handler(int irq, void *arg)
 {
 	struct drm_device *dev = arg;
 	struct drm_psb_private *dev_priv = dev->dev_private;
@@ -304,7 +305,7 @@ void psb_irq_preinstall(struct drm_device *dev)
 	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 }
 
-int psb_irq_postinstall(struct drm_device *dev)
+void psb_irq_postinstall(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	unsigned long irqflags;
@@ -332,12 +333,31 @@ int psb_irq_postinstall(struct drm_device *dev)
 		dev_priv->ops->hotplug_enable(dev, true);
 
 	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+}
+
+int psb_irq_install(struct drm_device *dev, unsigned int irq)
+{
+	int ret;
+
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	psb_irq_preinstall(dev);
+
+	/* PCI devices require shared interrupts. */
+	ret = request_irq(irq, psb_irq_handler, IRQF_SHARED, dev->driver->name, dev);
+	if (ret)
+		return ret;
+
+	psb_irq_postinstall(dev);
+
 	return 0;
 }
 
 void psb_irq_uninstall(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct pci_dev *pdev = to_pci_dev(dev->dev);
 	unsigned long irqflags;
 	unsigned int i;
 
@@ -366,6 +386,8 @@ void psb_irq_uninstall(struct drm_device *dev)
 	/* This register is safe even if display island is off */
 	PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
 	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
+
+	free_irq(pdev->irq, dev);
 }
 
 /*
diff --git a/drivers/gpu/drm/gma500/psb_irq.h b/drivers/gpu/drm/gma500/psb_irq.h
index 17c9b0b62471..a97cb49393d8 100644
--- a/drivers/gpu/drm/gma500/psb_irq.h
+++ b/drivers/gpu/drm/gma500/psb_irq.h
@@ -19,9 +19,9 @@ bool sysirq_init(struct drm_device *dev);
 void sysirq_uninit(struct drm_device *dev);
 
 void psb_irq_preinstall(struct drm_device *dev);
-int  psb_irq_postinstall(struct drm_device *dev);
+void psb_irq_postinstall(struct drm_device *dev);
+int  psb_irq_install(struct drm_device *dev, unsigned int irq);
 void psb_irq_uninstall(struct drm_device *dev);
-irqreturn_t psb_irq_handler(int irq, void *arg);
 
 int  psb_enable_vblank(struct drm_crtc *crtc);
 void psb_disable_vblank(struct drm_crtc *crtc);
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:52 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:52 +0200
Subject: [PATCH v2 02/14] drm/arm/hdlcd: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-3-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

v2:
	* name struct drm_device variables 'drm' (Sam)

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Acked-by: Sam Ravnborg <sam at ravnborg.org>
---
 drivers/gpu/drm/arm/hdlcd_drv.c | 174 ++++++++++++++++++--------------
 drivers/gpu/drm/arm/hdlcd_drv.h |   1 +
 2 files changed, 97 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 81ae92390736..479c2422a2e0 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -29,7 +29,6 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_modeset_helper.h>
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
@@ -38,6 +37,94 @@
 #include "hdlcd_drv.h"
 #include "hdlcd_regs.h"
 
+static irqreturn_t hdlcd_irq(int irq, void *arg)
+{
+	struct drm_device *drm = arg;
+	struct hdlcd_drm_private *hdlcd = drm->dev_private;
+	unsigned long irq_status;
+
+	irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
+
+#ifdef CONFIG_DEBUG_FS
+	if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
+		atomic_inc(&hdlcd->buffer_underrun_count);
+
+	if (irq_status & HDLCD_INTERRUPT_DMA_END)
+		atomic_inc(&hdlcd->dma_end_count);
+
+	if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
+		atomic_inc(&hdlcd->bus_error_count);
+
+	if (irq_status & HDLCD_INTERRUPT_VSYNC)
+		atomic_inc(&hdlcd->vsync_count);
+
+#endif
+	if (irq_status & HDLCD_INTERRUPT_VSYNC)
+		drm_crtc_handle_vblank(&hdlcd->crtc);
+
+	/* acknowledge interrupt(s) */
+	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
+
+	return IRQ_HANDLED;
+}
+
+static void hdlcd_irq_preinstall(struct drm_device *drm)
+{
+	struct hdlcd_drm_private *hdlcd = drm->dev_private;
+	/* Ensure interrupts are disabled */
+	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
+	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
+}
+
+static void hdlcd_irq_postinstall(struct drm_device *drm)
+{
+#ifdef CONFIG_DEBUG_FS
+	struct hdlcd_drm_private *hdlcd = drm->dev_private;
+	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+
+	/* enable debug interrupts */
+	irq_mask |= HDLCD_DEBUG_INT_MASK;
+
+	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
+#endif
+}
+
+static int hdlcd_irq_install(struct drm_device *drm, int irq)
+{
+	int ret;
+
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	hdlcd_irq_preinstall(drm);
+
+	ret = request_irq(irq, hdlcd_irq, 0, drm->driver->name, drm);
+	if (ret)
+		return ret;
+
+	hdlcd_irq_postinstall(drm);
+
+	return 0;
+}
+
+static void hdlcd_irq_uninstall(struct drm_device *drm)
+{
+	struct hdlcd_drm_private *hdlcd = drm->dev_private;
+	/* disable all the interrupts that we might have enabled */
+	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+
+#ifdef CONFIG_DEBUG_FS
+	/* disable debug interrupts */
+	irq_mask &= ~HDLCD_DEBUG_INT_MASK;
+#endif
+
+	/* disable vsync interrupts */
+	irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
+	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
+
+	free_irq(hdlcd->irq, drm);
+}
+
 static int hdlcd_load(struct drm_device *drm, unsigned long flags)
 {
 	struct hdlcd_drm_private *hdlcd = drm->dev_private;
@@ -90,7 +177,12 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
 		goto setup_fail;
 	}
 
-	ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		goto irq_fail;
+	hdlcd->irq = ret;
+
+	ret = hdlcd_irq_install(drm, hdlcd->irq);
 	if (ret < 0) {
 		DRM_ERROR("failed to install IRQ handler\n");
 		goto irq_fail;
@@ -122,76 +214,6 @@ static void hdlcd_setup_mode_config(struct drm_device *drm)
 	drm->mode_config.funcs = &hdlcd_mode_config_funcs;
 }
 
-static irqreturn_t hdlcd_irq(int irq, void *arg)
-{
-	struct drm_device *drm = arg;
-	struct hdlcd_drm_private *hdlcd = drm->dev_private;
-	unsigned long irq_status;
-
-	irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
-
-#ifdef CONFIG_DEBUG_FS
-	if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
-		atomic_inc(&hdlcd->buffer_underrun_count);
-
-	if (irq_status & HDLCD_INTERRUPT_DMA_END)
-		atomic_inc(&hdlcd->dma_end_count);
-
-	if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
-		atomic_inc(&hdlcd->bus_error_count);
-
-	if (irq_status & HDLCD_INTERRUPT_VSYNC)
-		atomic_inc(&hdlcd->vsync_count);
-
-#endif
-	if (irq_status & HDLCD_INTERRUPT_VSYNC)
-		drm_crtc_handle_vblank(&hdlcd->crtc);
-
-	/* acknowledge interrupt(s) */
-	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
-
-	return IRQ_HANDLED;
-}
-
-static void hdlcd_irq_preinstall(struct drm_device *drm)
-{
-	struct hdlcd_drm_private *hdlcd = drm->dev_private;
-	/* Ensure interrupts are disabled */
-	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
-	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
-}
-
-static int hdlcd_irq_postinstall(struct drm_device *drm)
-{
-#ifdef CONFIG_DEBUG_FS
-	struct hdlcd_drm_private *hdlcd = drm->dev_private;
-	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
-
-	/* enable debug interrupts */
-	irq_mask |= HDLCD_DEBUG_INT_MASK;
-
-	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
-#endif
-	return 0;
-}
-
-static void hdlcd_irq_uninstall(struct drm_device *drm)
-{
-	struct hdlcd_drm_private *hdlcd = drm->dev_private;
-	/* disable all the interrupts that we might have enabled */
-	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
-
-#ifdef CONFIG_DEBUG_FS
-	/* disable debug interrupts */
-	irq_mask &= ~HDLCD_DEBUG_INT_MASK;
-#endif
-
-	/* disable vsync interrupts */
-	irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
-
-	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
-}
-
 #ifdef CONFIG_DEBUG_FS
 static int hdlcd_show_underrun_count(struct seq_file *m, void *arg)
 {
@@ -236,10 +258,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver hdlcd_driver = {
 	.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
-	.irq_handler = hdlcd_irq,
-	.irq_preinstall = hdlcd_irq_preinstall,
-	.irq_postinstall = hdlcd_irq_postinstall,
-	.irq_uninstall = hdlcd_irq_uninstall,
 	DRM_GEM_CMA_DRIVER_OPS,
 #ifdef CONFIG_DEBUG_FS
 	.debugfs_init = hdlcd_debugfs_init,
@@ -316,7 +334,7 @@ static int hdlcd_drm_bind(struct device *dev)
 err_unload:
 	of_node_put(hdlcd->crtc.port);
 	hdlcd->crtc.port = NULL;
-	drm_irq_uninstall(drm);
+	hdlcd_irq_uninstall(drm);
 	of_reserved_mem_device_release(drm->dev);
 err_free:
 	drm_mode_config_cleanup(drm);
@@ -338,7 +356,7 @@ static void hdlcd_drm_unbind(struct device *dev)
 	hdlcd->crtc.port = NULL;
 	pm_runtime_get_sync(dev);
 	drm_atomic_helper_shutdown(drm);
-	drm_irq_uninstall(drm);
+	hdlcd_irq_uninstall(drm);
 	pm_runtime_put(dev);
 	if (pm_runtime_enabled(dev))
 		pm_runtime_disable(dev);
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
index fd438d177b64..909c39c28487 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.h
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -11,6 +11,7 @@ struct hdlcd_drm_private {
 	struct clk			*clk;
 	struct drm_crtc			crtc;
 	struct drm_plane		*plane;
+	unsigned int			irq;
 #ifdef CONFIG_DEBUG_FS
 	atomic_t buffer_underrun_count;
 	atomic_t bus_error_count;
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:57 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:57 +0200
Subject: [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-8-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/msm/msm_drv.c | 113 ++++++++++++++++++++--------------
 drivers/gpu/drm/msm/msm_kms.h |   2 +-
 2 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 1594ae39d54f..a332b09a5a11 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -14,7 +14,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_prime.h>
 #include <drm/drm_of.h>
 #include <drm/drm_vblank.h>
@@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
 	msm_writel(val | or, addr);
 }
 
+static irqreturn_t msm_irq(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	BUG_ON(!kms);
+
+	return kms->funcs->irq(kms);
+}
+
+static void msm_irq_preinstall(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	BUG_ON(!kms);
+
+	kms->funcs->irq_preinstall(kms);
+}
+
+static int msm_irq_postinstall(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	BUG_ON(!kms);
+
+	if (kms->funcs->irq_postinstall)
+		return kms->funcs->irq_postinstall(kms);
+
+	return 0;
+}
+
+static int msm_irq_install(struct drm_device *dev, unsigned int irq)
+{
+	int ret;
+
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	msm_irq_preinstall(dev);
+
+	ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
+	if (ret)
+		return ret;
+
+	ret = msm_irq_postinstall(dev);
+	if (ret) {
+		free_irq(irq, dev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void msm_irq_uninstall(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	kms->funcs->irq_uninstall(kms);
+	free_irq(kms->irq, dev);
+}
+
 struct msm_vblank_work {
 	struct work_struct work;
 	int crtc_id;
@@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
 	}
 
 	/* We must cancel and cleanup any pending vblank enable/disable
-	 * work before drm_irq_uninstall() to avoid work re-enabling an
+	 * work before msm_irq_uninstall() to avoid work re-enabling an
 	 * irq after uninstall has disabled it.
 	 */
 
@@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
 	drm_mode_config_cleanup(ddev);
 
 	pm_runtime_get_sync(dev);
-	drm_irq_uninstall(ddev);
+	msm_irq_uninstall(ddev);
 	pm_runtime_put_sync(dev);
 
 	if (kms && kms->funcs)
@@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
 
 	if (kms) {
 		pm_runtime_get_sync(dev);
-		ret = drm_irq_install(ddev, kms->irq);
+		ret = msm_irq_install(ddev, kms->irq);
 		pm_runtime_put_sync(dev);
 		if (ret < 0) {
 			DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
@@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
 	context_close(ctx);
 }
 
-static irqreturn_t msm_irq(int irq, void *arg)
-{
-	struct drm_device *dev = arg;
-	struct msm_drm_private *priv = dev->dev_private;
-	struct msm_kms *kms = priv->kms;
-	BUG_ON(!kms);
-	return kms->funcs->irq(kms);
-}
-
-static void msm_irq_preinstall(struct drm_device *dev)
-{
-	struct msm_drm_private *priv = dev->dev_private;
-	struct msm_kms *kms = priv->kms;
-	BUG_ON(!kms);
-	kms->funcs->irq_preinstall(kms);
-}
-
-static int msm_irq_postinstall(struct drm_device *dev)
-{
-	struct msm_drm_private *priv = dev->dev_private;
-	struct msm_kms *kms = priv->kms;
-	BUG_ON(!kms);
-
-	if (kms->funcs->irq_postinstall)
-		return kms->funcs->irq_postinstall(kms);
-
-	return 0;
-}
-
-static void msm_irq_uninstall(struct drm_device *dev)
-{
-	struct msm_drm_private *priv = dev->dev_private;
-	struct msm_kms *kms = priv->kms;
-	BUG_ON(!kms);
-	kms->funcs->irq_uninstall(kms);
-}
-
 int msm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
 	.open               = msm_open,
 	.postclose           = msm_postclose,
 	.lastclose          = drm_fb_helper_lastclose,
-	.irq_handler        = msm_irq,
-	.irq_preinstall     = msm_irq_preinstall,
-	.irq_postinstall    = msm_irq_postinstall,
-	.irq_uninstall      = msm_irq_uninstall,
 	.dumb_create        = msm_gem_dumb_create,
 	.dumb_map_offset    = msm_gem_dumb_map_offset,
 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 086a2d59b8c8..9de7c42e1071 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -150,7 +150,7 @@ struct msm_kms {
 	const struct msm_kms_funcs *funcs;
 	struct drm_device *dev;
 
-	/* irq number to be passed on to drm_irq_install */
+	/* irq number to be passed on to msm_irq_install */
 	int irq;
 
 	/* mapper-id used to request GEM buffer mapped for scanout: */
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:58 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:58 +0200
Subject: [PATCH v2 08/14] drm/mxsfb: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-9-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/mxsfb/mxsfb_drv.c | 81 +++++++++++++++++++------------
 drivers/gpu/drm/mxsfb/mxsfb_drv.h |  2 +
 2 files changed, 52 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index c277d3f61a5e..ec0432fe1bdf 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -24,7 +24,6 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_mode_config.h>
 #include <drm/drm_of.h>
 #include <drm/drm_probe_helper.h>
@@ -153,6 +152,49 @@ static int mxsfb_attach_bridge(struct mxsfb_drm_private *mxsfb)
 	return 0;
 }
 
+static irqreturn_t mxsfb_irq_handler(int irq, void *data)
+{
+	struct drm_device *drm = data;
+	struct mxsfb_drm_private *mxsfb = drm->dev_private;
+	u32 reg;
+
+	reg = readl(mxsfb->base + LCDC_CTRL1);
+
+	if (reg & CTRL1_CUR_FRAME_DONE_IRQ)
+		drm_crtc_handle_vblank(&mxsfb->crtc);
+
+	writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
+
+	return IRQ_HANDLED;
+}
+
+static void mxsfb_irq_disable(struct drm_device *drm)
+{
+	struct mxsfb_drm_private *mxsfb = drm->dev_private;
+
+	mxsfb_enable_axi_clk(mxsfb);
+	mxsfb->crtc.funcs->disable_vblank(&mxsfb->crtc);
+	mxsfb_disable_axi_clk(mxsfb);
+}
+
+static int mxsfb_irq_install(struct drm_device *dev, int irq)
+{
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	mxsfb_irq_disable(dev);
+
+	return request_irq(irq, mxsfb_irq_handler, 0,  dev->driver->name, dev);
+}
+
+static void mxsfb_irq_uninstall(struct drm_device *dev)
+{
+	struct mxsfb_drm_private *mxsfb = dev->dev_private;
+
+	mxsfb_irq_disable(dev);
+	free_irq(mxsfb->irq, dev);
+}
+
 static int mxsfb_load(struct drm_device *drm,
 		      const struct mxsfb_devdata *devdata)
 {
@@ -226,8 +268,13 @@ static int mxsfb_load(struct drm_device *drm,
 
 	drm_mode_config_reset(drm);
 
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		goto err_vblank;
+	mxsfb->irq = ret;
+
 	pm_runtime_get_sync(drm->dev);
-	ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
+	ret = mxsfb_irq_install(drm, mxsfb->irq);
 	pm_runtime_put_sync(drm->dev);
 
 	if (ret < 0) {
@@ -255,7 +302,7 @@ static void mxsfb_unload(struct drm_device *drm)
 	drm_mode_config_cleanup(drm);
 
 	pm_runtime_get_sync(drm->dev);
-	drm_irq_uninstall(drm);
+	mxsfb_irq_uninstall(drm);
 	pm_runtime_put_sync(drm->dev);
 
 	drm->dev_private = NULL;
@@ -263,38 +310,10 @@ static void mxsfb_unload(struct drm_device *drm)
 	pm_runtime_disable(drm->dev);
 }
 
-static void mxsfb_irq_disable(struct drm_device *drm)
-{
-	struct mxsfb_drm_private *mxsfb = drm->dev_private;
-
-	mxsfb_enable_axi_clk(mxsfb);
-	mxsfb->crtc.funcs->disable_vblank(&mxsfb->crtc);
-	mxsfb_disable_axi_clk(mxsfb);
-}
-
-static irqreturn_t mxsfb_irq_handler(int irq, void *data)
-{
-	struct drm_device *drm = data;
-	struct mxsfb_drm_private *mxsfb = drm->dev_private;
-	u32 reg;
-
-	reg = readl(mxsfb->base + LCDC_CTRL1);
-
-	if (reg & CTRL1_CUR_FRAME_DONE_IRQ)
-		drm_crtc_handle_vblank(&mxsfb->crtc);
-
-	writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
-
-	return IRQ_HANDLED;
-}
-
 DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver mxsfb_driver = {
 	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
-	.irq_handler		= mxsfb_irq_handler,
-	.irq_preinstall		= mxsfb_irq_disable,
-	.irq_uninstall		= mxsfb_irq_disable,
 	DRM_GEM_CMA_DRIVER_OPS,
 	.fops	= &fops,
 	.name	= "mxsfb-drm",
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
index 7c720e226fdf..ddb5b0417a82 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h
@@ -33,6 +33,8 @@ struct mxsfb_drm_private {
 	struct clk			*clk_axi;
 	struct clk			*clk_disp_axi;
 
+	unsigned int			irq;
+
 	struct drm_device		*drm;
 	struct {
 		struct drm_plane	primary;
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:06:59 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:06:59 +0200
Subject: [PATCH v2 09/14] drm/radeon: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-10-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/radeon_drv.c     |  4 ---
 drivers/gpu/drm/radeon/radeon_irq_kms.c | 44 +++++++++++++++++++++----
 drivers/gpu/drm/radeon/radeon_kms.h     |  4 ---
 3 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index c8dd68152d65..b74cebca1f89 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -607,10 +607,6 @@ static const struct drm_driver kms_driver = {
 	.postclose = radeon_driver_postclose_kms,
 	.lastclose = radeon_driver_lastclose_kms,
 	.unload = radeon_driver_unload_kms,
-	.irq_preinstall = radeon_driver_irq_preinstall_kms,
-	.irq_postinstall = radeon_driver_irq_postinstall_kms,
-	.irq_uninstall = radeon_driver_irq_uninstall_kms,
-	.irq_handler = radeon_driver_irq_handler_kms,
 	.ioctls = radeon_ioctls_kms,
 	.num_ioctls = ARRAY_SIZE(radeon_ioctls_kms),
 	.dumb_create = radeon_mode_dumb_create,
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index a36ce826d0c0..3907785d0798 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -31,7 +31,7 @@
 
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_device.h>
-#include <drm/drm_irq.h>
+#include <drm/drm_drv.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
 #include <drm/radeon_drm.h>
@@ -51,7 +51,7 @@
  * radeon_irq_process is a macro that points to the per-asic
  * irq handler callback.
  */
-irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg)
+static irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg)
 {
 	struct drm_device *dev = (struct drm_device *) arg;
 	struct radeon_device *rdev = dev->dev_private;
@@ -118,7 +118,7 @@ static void radeon_dp_work_func(struct work_struct *work)
  * Gets the hw ready to enable irqs (all asics).
  * This function disables all interrupt sources on the GPU.
  */
-void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
+static void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	unsigned long irqflags;
@@ -150,7 +150,7 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
  * Handles stuff to be done after enabling irqs (all asics).
  * Returns 0 on success.
  */
-int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
+static int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 
@@ -169,7 +169,7 @@ int radeon_driver_irq_postinstall_kms(struct drm_device *dev)
  *
  * This function disables all interrupt sources on the GPU (all asics).
  */
-void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
+static void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	unsigned long irqflags;
@@ -194,6 +194,36 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
 	spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
 }
 
+static int radeon_irq_install(struct radeon_device *rdev, int irq)
+{
+	struct drm_device *dev = rdev->ddev;
+	int ret;
+
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	radeon_driver_irq_preinstall_kms(dev);
+
+	/* PCI devices require shared interrupts. */
+	ret = request_irq(irq, radeon_driver_irq_handler_kms,
+			  IRQF_SHARED, dev->driver->name, dev);
+	if (ret)
+		return ret;
+
+	radeon_driver_irq_postinstall_kms(dev);
+
+	return 0;
+}
+
+static void radeon_irq_uninstall(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct pci_dev *pdev = to_pci_dev(dev->dev);
+
+	radeon_driver_irq_uninstall_kms(dev);
+	free_irq(pdev->irq, dev);
+}
+
 /**
  * radeon_msi_ok - asic specific msi checks
  *
@@ -314,7 +344,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
 	INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
 
 	rdev->irq.installed = true;
-	r = drm_irq_install(rdev->ddev, rdev->pdev->irq);
+	r = radeon_irq_install(rdev, rdev->pdev->irq);
 	if (r) {
 		rdev->irq.installed = false;
 		flush_delayed_work(&rdev->hotplug_work);
@@ -335,7 +365,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
 void radeon_irq_kms_fini(struct radeon_device *rdev)
 {
 	if (rdev->irq.installed) {
-		drm_irq_uninstall(rdev->ddev);
+		radeon_irq_uninstall(rdev);
 		rdev->irq.installed = false;
 		if (rdev->msi_enabled)
 			pci_disable_msi(rdev->pdev);
diff --git a/drivers/gpu/drm/radeon/radeon_kms.h b/drivers/gpu/drm/radeon/radeon_kms.h
index 9b97bf38acd4..36e73cea9215 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.h
+++ b/drivers/gpu/drm/radeon/radeon_kms.h
@@ -31,9 +31,5 @@
 u32 radeon_get_vblank_counter_kms(struct drm_crtc *crtc);
 int radeon_enable_vblank_kms(struct drm_crtc *crtc);
 void radeon_disable_vblank_kms(struct drm_crtc *crtc);
-irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg);
-void radeon_driver_irq_preinstall_kms(struct drm_device *dev);
-int radeon_driver_irq_postinstall_kms(struct drm_device *dev);
-void radeon_driver_irq_uninstall_kms(struct drm_device *dev);
 
 #endif				/* __RADEON_KMS_H__ */
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:07:00 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:07:00 +0200
Subject: [PATCH v2 10/14] drm/tidss: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-11-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
---
 drivers/gpu/drm/tidss/tidss_drv.c | 15 +++++----------
 drivers/gpu/drm/tidss/tidss_drv.h |  2 ++
 drivers/gpu/drm/tidss/tidss_irq.c | 27 ++++++++++++++++++++++++---
 drivers/gpu/drm/tidss/tidss_irq.h |  4 +---
 4 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/tidss/tidss_drv.c b/drivers/gpu/drm/tidss/tidss_drv.c
index 66e3c86eb5c7..d620f35688da 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.c
+++ b/drivers/gpu/drm/tidss/tidss_drv.c
@@ -16,7 +16,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_cma_helper.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
 
@@ -118,11 +117,6 @@ static const struct drm_driver tidss_driver = {
 	.date			= "20180215",
 	.major			= 1,
 	.minor			= 0,
-
-	.irq_preinstall		= tidss_irq_preinstall,
-	.irq_postinstall	= tidss_irq_postinstall,
-	.irq_handler		= tidss_irq_handler,
-	.irq_uninstall		= tidss_irq_uninstall,
 };
 
 static int tidss_probe(struct platform_device *pdev)
@@ -172,10 +166,11 @@ static int tidss_probe(struct platform_device *pdev)
 		ret = irq;
 		goto err_runtime_suspend;
 	}
+	tidss->irq = irq;
 
-	ret = drm_irq_install(ddev, irq);
+	ret = tidss_irq_install(ddev, irq);
 	if (ret) {
-		dev_err(dev, "drm_irq_install failed: %d\n", ret);
+		dev_err(dev, "tidss_irq_install failed: %d\n", ret);
 		goto err_runtime_suspend;
 	}
 
@@ -196,7 +191,7 @@ static int tidss_probe(struct platform_device *pdev)
 	return 0;
 
 err_irq_uninstall:
-	drm_irq_uninstall(ddev);
+	tidss_irq_uninstall(ddev);
 
 err_runtime_suspend:
 #ifndef CONFIG_PM
@@ -219,7 +214,7 @@ static int tidss_remove(struct platform_device *pdev)
 
 	drm_atomic_helper_shutdown(ddev);
 
-	drm_irq_uninstall(ddev);
+	tidss_irq_uninstall(ddev);
 
 #ifndef CONFIG_PM
 	/* If we don't have PM, we need to call suspend manually */
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h
index 7de4bba52e6f..d7f27b0b0315 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.h
+++ b/drivers/gpu/drm/tidss/tidss_drv.h
@@ -27,6 +27,8 @@ struct tidss_device {
 	unsigned int num_planes;
 	struct drm_plane *planes[TIDSS_MAX_PLANES];
 
+	unsigned int irq;
+
 	spinlock_t wait_lock;	/* protects the irq masks */
 	dispc_irq_t irq_mask;	/* enabled irqs in addition to wait_list */
 };
diff --git a/drivers/gpu/drm/tidss/tidss_irq.c b/drivers/gpu/drm/tidss/tidss_irq.c
index 2ed3e3296776..0c681c7600bc 100644
--- a/drivers/gpu/drm/tidss/tidss_irq.c
+++ b/drivers/gpu/drm/tidss/tidss_irq.c
@@ -4,6 +4,9 @@
  * Author: Tomi Valkeinen <tomi.valkeinen at ti.com>
  */
 
+#include <linux/platform_device.h>
+
+#include <drm/drm_drv.h>
 #include <drm/drm_print.h>
 
 #include "tidss_crtc.h"
@@ -50,7 +53,7 @@ void tidss_irq_disable_vblank(struct drm_crtc *crtc)
 	spin_unlock_irqrestore(&tidss->wait_lock, flags);
 }
 
-irqreturn_t tidss_irq_handler(int irq, void *arg)
+static irqreturn_t tidss_irq_handler(int irq, void *arg)
 {
 	struct drm_device *ddev = (struct drm_device *)arg;
 	struct tidss_device *tidss = to_tidss(ddev);
@@ -90,7 +93,7 @@ void tidss_irq_resume(struct tidss_device *tidss)
 	spin_unlock_irqrestore(&tidss->wait_lock, flags);
 }
 
-void tidss_irq_preinstall(struct drm_device *ddev)
+static void tidss_irq_preinstall(struct drm_device *ddev)
 {
 	struct tidss_device *tidss = to_tidss(ddev);
 
@@ -104,7 +107,7 @@ void tidss_irq_preinstall(struct drm_device *ddev)
 	tidss_runtime_put(tidss);
 }
 
-int tidss_irq_postinstall(struct drm_device *ddev)
+static void tidss_irq_postinstall(struct drm_device *ddev)
 {
 	struct tidss_device *tidss = to_tidss(ddev);
 	unsigned long flags;
@@ -129,6 +132,22 @@ int tidss_irq_postinstall(struct drm_device *ddev)
 	spin_unlock_irqrestore(&tidss->wait_lock, flags);
 
 	tidss_runtime_put(tidss);
+}
+
+int tidss_irq_install(struct drm_device *ddev, unsigned int irq)
+{
+	int ret;
+
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	tidss_irq_preinstall(ddev);
+
+	ret = request_irq(irq, tidss_irq_handler, 0, ddev->driver->name, ddev);
+	if (ret)
+		return ret;
+
+	tidss_irq_postinstall(ddev);
 
 	return 0;
 }
@@ -140,4 +159,6 @@ void tidss_irq_uninstall(struct drm_device *ddev)
 	tidss_runtime_get(tidss);
 	dispc_set_irqenable(tidss->dispc, 0);
 	tidss_runtime_put(tidss);
+
+	free_irq(tidss->irq, ddev);
 }
diff --git a/drivers/gpu/drm/tidss/tidss_irq.h b/drivers/gpu/drm/tidss/tidss_irq.h
index 4aaad5dfd7c2..b512614d5863 100644
--- a/drivers/gpu/drm/tidss/tidss_irq.h
+++ b/drivers/gpu/drm/tidss/tidss_irq.h
@@ -67,10 +67,8 @@ struct tidss_device;
 void tidss_irq_enable_vblank(struct drm_crtc *crtc);
 void tidss_irq_disable_vblank(struct drm_crtc *crtc);
 
-void tidss_irq_preinstall(struct drm_device *ddev);
-int tidss_irq_postinstall(struct drm_device *ddev);
+int tidss_irq_install(struct drm_device *ddev, unsigned int irq);
 void tidss_irq_uninstall(struct drm_device *ddev);
-irqreturn_t tidss_irq_handler(int irq, void *arg);
 
 void tidss_irq_resume(struct tidss_device *tidss);
 
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:07:01 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:07:01 +0200
Subject: [PATCH v2 11/14] drm/tilcdc: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-12-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/tilcdc/tilcdc_drv.c | 51 ++++++++++++++++++++++-------
 drivers/gpu/drm/tilcdc/tilcdc_drv.h |  3 ++
 2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index f1d3a9f919fd..6b03f89a98d4 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -20,7 +20,6 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_mm.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
@@ -124,6 +123,39 @@ static int cpufreq_transition(struct notifier_block *nb,
 }
 #endif
 
+static irqreturn_t tilcdc_irq(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct tilcdc_drm_private *priv = dev->dev_private;
+
+	return tilcdc_crtc_irq(priv->crtc);
+}
+
+static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq)
+{
+	struct tilcdc_drm_private *priv = dev->dev_private;
+	int ret;
+
+	ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev);
+	if (ret)
+		return ret;
+
+	priv->irq_enabled = false;
+
+	return 0;
+}
+
+static void tilcdc_irq_uninstall(struct drm_device *dev)
+{
+	struct tilcdc_drm_private *priv = dev->dev_private;
+
+	if (!priv->irq_enabled)
+		return;
+
+	free_irq(priv->irq, dev);
+	priv->irq_enabled = false;
+}
+
 /*
  * DRM operations:
  */
@@ -145,7 +177,7 @@ static void tilcdc_fini(struct drm_device *dev)
 		drm_dev_unregister(dev);
 
 	drm_kms_helper_poll_fini(dev);
-	drm_irq_uninstall(dev);
+	tilcdc_irq_uninstall(dev);
 	drm_mode_config_cleanup(dev);
 
 	if (priv->clk)
@@ -336,7 +368,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
 		goto init_failed;
 	}
 
-	ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		goto init_failed;
+	priv->irq = ret;
+
+	ret = tilcdc_irq_install(ddev, priv->irq);
 	if (ret < 0) {
 		dev_err(dev, "failed to install IRQ handler\n");
 		goto init_failed;
@@ -360,13 +397,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
 	return ret;
 }
 
-static irqreturn_t tilcdc_irq(int irq, void *arg)
-{
-	struct drm_device *dev = arg;
-	struct tilcdc_drm_private *priv = dev->dev_private;
-	return tilcdc_crtc_irq(priv->crtc);
-}
-
 #if defined(CONFIG_DEBUG_FS)
 static const struct {
 	const char *name;
@@ -454,7 +484,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
 
 static const struct drm_driver tilcdc_driver = {
 	.driver_features    = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
-	.irq_handler        = tilcdc_irq,
 	DRM_GEM_CMA_DRIVER_OPS,
 #ifdef CONFIG_DEBUG_FS
 	.debugfs_init       = tilcdc_debugfs_init,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
index d29806ca8817..b818448c83f6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
@@ -46,6 +46,8 @@ struct tilcdc_drm_private {
 	struct clk *clk;         /* functional clock */
 	int rev;                 /* IP revision */
 
+	unsigned int irq;
+
 	/* don't attempt resolutions w/ higher W * H * Hz: */
 	uint32_t max_bandwidth;
 	/*
@@ -82,6 +84,7 @@ struct tilcdc_drm_private {
 
 	bool is_registered;
 	bool is_componentized;
+	bool irq_enabled;
 };
 
 /* Sub-module for display.  Since we don't know at compile time what panels
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:07:02 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:07:02 +0200
Subject: [PATCH v2 12/14] drm/vc4: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-13-tzimmermann@suse.de>

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Calls to platform_get_irq() can fail with a negative errno code.
Abort initialization in this case. The DRM IRQ midlayer does not
handle this case correctly.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/vc4/vc4_drv.c |  4 ---
 drivers/gpu/drm/vc4/vc4_drv.h |  8 +++---
 drivers/gpu/drm/vc4/vc4_irq.c | 48 +++++++++++++++++++++++++++--------
 drivers/gpu/drm/vc4/vc4_v3d.c | 17 ++++++++-----
 4 files changed, 53 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 73335feb712f..f6c16c5aee68 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -168,10 +168,6 @@ static struct drm_driver vc4_drm_driver = {
 			    DRIVER_SYNCOBJ),
 	.open = vc4_open,
 	.postclose = vc4_close,
-	.irq_handler = vc4_irq,
-	.irq_preinstall = vc4_irq_preinstall,
-	.irq_postinstall = vc4_irq_postinstall,
-	.irq_uninstall = vc4_irq_uninstall,
 
 #if defined(CONFIG_DEBUG_FS)
 	.debugfs_init = vc4_debugfs_init,
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 5dceadc61600..ef73e0aaf726 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -74,6 +74,8 @@ struct vc4_perfmon {
 struct vc4_dev {
 	struct drm_device base;
 
+	unsigned int irq;
+
 	struct vc4_hvs *hvs;
 	struct vc4_v3d *v3d;
 	struct vc4_dpi *dpi;
@@ -895,9 +897,9 @@ extern struct platform_driver vc4_vec_driver;
 extern struct platform_driver vc4_txp_driver;
 
 /* vc4_irq.c */
-irqreturn_t vc4_irq(int irq, void *arg);
-void vc4_irq_preinstall(struct drm_device *dev);
-int vc4_irq_postinstall(struct drm_device *dev);
+void vc4_irq_enable(struct drm_device *dev);
+void vc4_irq_disable(struct drm_device *dev);
+int vc4_irq_install(struct drm_device *dev, int irq);
 void vc4_irq_uninstall(struct drm_device *dev);
 void vc4_irq_reset(struct drm_device *dev);
 
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index e226c24e543f..20fa8e34c20b 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -45,6 +45,10 @@
  * current job can make progress.
  */
 
+#include <linux/platform_device.h>
+
+#include <drm/drm_drv.h>
+
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -192,7 +196,7 @@ vc4_irq_finish_render_job(struct drm_device *dev)
 	schedule_work(&vc4->job_done_work);
 }
 
-irqreturn_t
+static irqreturn_t
 vc4_irq(int irq, void *arg)
 {
 	struct drm_device *dev = arg;
@@ -234,8 +238,8 @@ vc4_irq(int irq, void *arg)
 	return status;
 }
 
-void
-vc4_irq_preinstall(struct drm_device *dev)
+static void
+vc4_irq_prepare(struct drm_device *dev)
 {
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 
@@ -251,24 +255,22 @@ vc4_irq_preinstall(struct drm_device *dev)
 	V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
 }
 
-int
-vc4_irq_postinstall(struct drm_device *dev)
+void
+vc4_irq_enable(struct drm_device *dev)
 {
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 
 	if (!vc4->v3d)
-		return 0;
+		return;
 
 	/* Enable the render done interrupts. The out-of-memory interrupt is
 	 * enabled as soon as we have a binner BO allocated.
 	 */
 	V3D_WRITE(V3D_INTENA, V3D_INT_FLDONE | V3D_INT_FRDONE);
-
-	return 0;
 }
 
 void
-vc4_irq_uninstall(struct drm_device *dev)
+vc4_irq_disable(struct drm_device *dev)
 {
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 
@@ -282,11 +284,37 @@ vc4_irq_uninstall(struct drm_device *dev)
 	V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
 
 	/* Finish any interrupt handler still in flight. */
-	disable_irq(dev->irq);
+	disable_irq(vc4->irq);
 
 	cancel_work_sync(&vc4->overflow_mem_work);
 }
 
+int vc4_irq_install(struct drm_device *dev, int irq)
+{
+	int ret;
+
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	vc4_irq_prepare(dev);
+
+	ret = request_irq(irq, vc4_irq, 0, dev->driver->name, dev);
+	if (ret)
+		return ret;
+
+	vc4_irq_enable(dev);
+
+	return 0;
+}
+
+void vc4_irq_uninstall(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	vc4_irq_disable(dev);
+	free_irq(vc4->irq, dev);
+}
+
 /** Reinitializes interrupt registers when a GPU reset is performed. */
 void vc4_irq_reset(struct drm_device *dev)
 {
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 73d63d72575b..7bb3067f8425 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -10,8 +10,6 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-#include <drm/drm_irq.h>
-
 #include "vc4_drv.h"
 #include "vc4_regs.h"
 
@@ -361,7 +359,7 @@ static int vc4_v3d_runtime_suspend(struct device *dev)
 	struct vc4_v3d *v3d = dev_get_drvdata(dev);
 	struct vc4_dev *vc4 = v3d->vc4;
 
-	vc4_irq_uninstall(&vc4->base);
+	vc4_irq_disable(&vc4->base);
 
 	clk_disable_unprepare(v3d->clk);
 
@@ -381,8 +379,8 @@ static int vc4_v3d_runtime_resume(struct device *dev)
 	vc4_v3d_init_hw(&vc4->base);
 
 	/* We disabled the IRQ as part of vc4_irq_uninstall in suspend. */
-	enable_irq(vc4->base.irq);
-	vc4_irq_postinstall(&vc4->base);
+	enable_irq(vc4->irq);
+	vc4_irq_enable(&vc4->base);
 
 	return 0;
 }
@@ -448,7 +446,12 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
 
 	vc4_v3d_init_hw(drm);
 
-	ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		return ret;
+	vc4->irq = ret;
+
+	ret = vc4_irq_install(drm, vc4->irq);
 	if (ret) {
 		DRM_ERROR("Failed to install IRQ handler\n");
 		return ret;
@@ -473,7 +476,7 @@ static void vc4_v3d_unbind(struct device *dev, struct device *master,
 
 	pm_runtime_disable(dev);
 
-	drm_irq_uninstall(drm);
+	vc4_irq_uninstall(drm);
 
 	/* Disable the binner's overflow memory address, so the next
 	 * driver probe (if any) doesn't try to reuse our old
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:07:03 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:07:03 +0200
Subject: [PATCH v2 13/14] drm: Remove unused devm_drm_irq_install()
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-14-tzimmermann@suse.de>

DRM IRQ helpers will become legacy. The function devm_drm_irq_install()
is unused and won't be required later.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
---
 drivers/gpu/drm/drm_irq.c | 32 --------------------------------
 include/drm/drm_irq.h     |  1 -
 2 files changed, 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 201eae4bba6c..dc6e38fa8a48 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -209,38 +209,6 @@ int drm_irq_uninstall(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_irq_uninstall);
 
-static void devm_drm_irq_uninstall(void *data)
-{
-	drm_irq_uninstall(data);
-}
-
-/**
- * devm_drm_irq_install - install IRQ handler
- * @dev: DRM device
- * @irq: IRQ number to install the handler for
- *
- * devm_drm_irq_install is a  help function of drm_irq_install.
- *
- * if the driver uses devm_drm_irq_install, there is no need
- * to call drm_irq_uninstall when the drm module get unloaded,
- * as this will done automagically.
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
-int devm_drm_irq_install(struct drm_device *dev, int irq)
-{
-	int ret;
-
-	ret = drm_irq_install(dev, irq);
-	if (ret)
-		return ret;
-
-	return devm_add_action_or_reset(dev->dev,
-					devm_drm_irq_uninstall, dev);
-}
-EXPORT_SYMBOL(devm_drm_irq_install);
-
 #if IS_ENABLED(CONFIG_DRM_LEGACY)
 int drm_legacy_irq_control(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv)
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h
index 631b22f9757d..53634b988f57 100644
--- a/include/drm/drm_irq.h
+++ b/include/drm/drm_irq.h
@@ -28,5 +28,4 @@ struct drm_device;
 
 int drm_irq_install(struct drm_device *dev, int irq);
 int drm_irq_uninstall(struct drm_device *dev);
-int devm_drm_irq_install(struct drm_device *dev, int irq);
 #endif
-- 
2.32.0



From tzimmermann at suse.de  Tue Aug  3 02:07:04 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue,  3 Aug 2021 11:07:04 +0200
Subject: [PATCH v2 14/14] drm: IRQ midlayer is now legacy
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <20210803090704.32152-15-tzimmermann@suse.de>

Hide the DRM midlayer behind CONFIG_DRM_LEGACY, make functions use
the prefix drm_legacy_, and move declarations to drm_legacy.h.
In struct drm_device, move the fields irq and irq_enabled behind
CONFIG_DRM_LEGACY.

All callers have been updated.

Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
Acked-by: Sam Ravnborg <sam at ravnborg.org>
---
 drivers/gpu/drm/drm_irq.c         | 63 ++++---------------------------
 drivers/gpu/drm/drm_legacy_misc.c |  3 +-
 drivers/gpu/drm/drm_vblank.c      |  8 ++--
 drivers/gpu/drm/i810/i810_dma.c   |  3 +-
 drivers/gpu/drm/mga/mga_dma.c     |  2 +-
 drivers/gpu/drm/mga/mga_drv.h     |  1 -
 drivers/gpu/drm/r128/r128_cce.c   |  3 +-
 drivers/gpu/drm/via/via_mm.c      |  3 +-
 include/drm/drm_device.h          | 18 ++-------
 include/drm/drm_drv.h             | 44 ++-------------------
 include/drm/drm_irq.h             | 31 ---------------
 include/drm/drm_legacy.h          |  3 ++
 12 files changed, 27 insertions(+), 155 deletions(-)
 delete mode 100644 include/drm/drm_irq.h

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index dc6e38fa8a48..13e1d5c4ec82 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -60,46 +60,14 @@
 #include <drm/drm.h>
 #include <drm/drm_device.h>
 #include <drm/drm_drv.h>
-#include <drm/drm_irq.h>
+#include <drm/drm_legacy.h>
 #include <drm/drm_print.h>
 #include <drm/drm_vblank.h>
 
 #include "drm_internal.h"
 
-/**
- * DOC: irq helpers
- *
- * The DRM core provides very simple support helpers to enable IRQ handling on a
- * device through the drm_irq_install() and drm_irq_uninstall() functions. This
- * only supports devices with a single interrupt on the main device stored in
- * &drm_device.dev and set as the device paramter in drm_dev_alloc().
- *
- * These IRQ helpers are strictly optional. Since these helpers don't automatically
- * clean up the requested interrupt like e.g. devm_request_irq() they're not really
- * recommended.
- */
-
-/**
- * drm_irq_install - install IRQ handler
- * @dev: DRM device
- * @irq: IRQ number to install the handler for
- *
- * Initializes the IRQ related data. Installs the handler, calling the driver
- * &drm_driver.irq_preinstall and &drm_driver.irq_postinstall functions before
- * and after the installation.
- *
- * This is the simplified helper interface provided for drivers with no special
- * needs.
- *
- * @irq must match the interrupt number that would be passed to request_irq(),
- * if called directly instead of using this helper function.
- *
- * &drm_driver.irq_handler is called to handle the registered interrupt.
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
-int drm_irq_install(struct drm_device *dev, int irq)
+#if IS_ENABLED(CONFIG_DRM_LEGACY)
+static int drm_legacy_irq_install(struct drm_device *dev, int irq)
 {
 	int ret;
 	unsigned long sh_flags = 0;
@@ -144,24 +112,8 @@ int drm_irq_install(struct drm_device *dev, int irq)
 
 	return ret;
 }
-EXPORT_SYMBOL(drm_irq_install);
 
-/**
- * drm_irq_uninstall - uninstall the IRQ handler
- * @dev: DRM device
- *
- * Calls the driver's &drm_driver.irq_uninstall function and unregisters the IRQ
- * handler.  This should only be called by drivers which used drm_irq_install()
- * to set up their interrupt handler.
- *
- * Note that for kernel modesetting drivers it is a bug if this function fails.
- * The sanity checks are only to catch buggy user modesetting drivers which call
- * the same function through an ioctl.
- *
- * Returns:
- * Zero on success or a negative error code on failure.
- */
-int drm_irq_uninstall(struct drm_device *dev)
+int drm_legacy_irq_uninstall(struct drm_device *dev)
 {
 	unsigned long irqflags;
 	bool irq_enabled;
@@ -207,9 +159,8 @@ int drm_irq_uninstall(struct drm_device *dev)
 
 	return 0;
 }
-EXPORT_SYMBOL(drm_irq_uninstall);
+EXPORT_SYMBOL(drm_legacy_irq_uninstall);
 
-#if IS_ENABLED(CONFIG_DRM_LEGACY)
 int drm_legacy_irq_control(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv)
 {
@@ -238,13 +189,13 @@ int drm_legacy_irq_control(struct drm_device *dev, void *data,
 		    ctl->irq != irq)
 			return -EINVAL;
 		mutex_lock(&dev->struct_mutex);
-		ret = drm_irq_install(dev, irq);
+		ret = drm_legacy_irq_install(dev, irq);
 		mutex_unlock(&dev->struct_mutex);
 
 		return ret;
 	case DRM_UNINST_HANDLER:
 		mutex_lock(&dev->struct_mutex);
-		ret = drm_irq_uninstall(dev);
+		ret = drm_legacy_irq_uninstall(dev);
 		mutex_unlock(&dev->struct_mutex);
 
 		return ret;
diff --git a/drivers/gpu/drm/drm_legacy_misc.c b/drivers/gpu/drm/drm_legacy_misc.c
index 83db43b7a25e..d4c5434062d7 100644
--- a/drivers/gpu/drm/drm_legacy_misc.c
+++ b/drivers/gpu/drm/drm_legacy_misc.c
@@ -35,7 +35,6 @@
 
 #include <drm/drm_device.h>
 #include <drm/drm_drv.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_print.h>
 
 #include "drm_internal.h"
@@ -78,7 +77,7 @@ int drm_legacy_setup(struct drm_device * dev)
 void drm_legacy_dev_reinit(struct drm_device *dev)
 {
 	if (dev->irq_enabled)
-		drm_irq_uninstall(dev);
+		drm_legacy_irq_uninstall(dev);
 
 	mutex_lock(&dev->struct_mutex);
 
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index bba6781cc48f..3e260f3e2863 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1739,10 +1739,10 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe,
 
 static bool drm_wait_vblank_supported(struct drm_device *dev)
 {
-	if  (IS_ENABLED(CONFIG_DRM_LEGACY)) {
-		if (unlikely(drm_core_check_feature(dev, DRIVER_LEGACY)))
-			return dev->irq_enabled;
-	}
+#if IS_ENABLED(CONFIG_DRM_LEGACY)
+	if (unlikely(drm_core_check_feature(dev, DRIVER_LEGACY)))
+		return dev->irq_enabled;
+#endif
 	return drm_dev_has_vblank(dev);
 }
 
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index d78c82af367c..9fb4dd63342f 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -38,7 +38,6 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_print.h>
 #include <drm/i810_drm.h>
 
@@ -209,7 +208,7 @@ static int i810_dma_cleanup(struct drm_device *dev)
 	 * is freed, it's too late.
 	 */
 	if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled)
-		drm_irq_uninstall(dev);
+		drm_legacy_irq_uninstall(dev);
 
 	if (dev->dev_private) {
 		int i;
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index 403efc1f1a7c..331c2f0da57a 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -949,7 +949,7 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
 	 * is freed, it's too late.
 	 */
 	if (dev->irq_enabled)
-		drm_irq_uninstall(dev);
+		drm_legacy_irq_uninstall(dev);
 
 	if (dev->dev_private) {
 		drm_mga_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h
index 84395d81ab9b..f61401c70b90 100644
--- a/drivers/gpu/drm/mga/mga_drv.h
+++ b/drivers/gpu/drm/mga/mga_drv.h
@@ -38,7 +38,6 @@
 #include <drm/drm_device.h>
 #include <drm/drm_file.h>
 #include <drm/drm_ioctl.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_legacy.h>
 #include <drm/drm_print.h>
 #include <drm/drm_sarea.h>
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c
index 2a2933c16308..c04d84a69dd2 100644
--- a/drivers/gpu/drm/r128/r128_cce.c
+++ b/drivers/gpu/drm/r128/r128_cce.c
@@ -39,7 +39,6 @@
 
 #include <drm/drm_device.h>
 #include <drm/drm_file.h>
-#include <drm/drm_irq.h>
 #include <drm/drm_legacy.h>
 #include <drm/drm_print.h>
 #include <drm/r128_drm.h>
@@ -603,7 +602,7 @@ int r128_do_cleanup_cce(struct drm_device *dev)
 	 * is freed, it's too late.
 	 */
 	if (dev->irq_enabled)
-		drm_irq_uninstall(dev);
+		drm_legacy_irq_uninstall(dev);
 
 	if (dev->dev_private) {
 		drm_r128_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index dae1bacd86c1..c9afa1a51f23 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -29,7 +29,6 @@
 
 #include <drm/drm_device.h>
 #include <drm/drm_file.h>
-#include <drm/drm_irq.h>
 #include <drm/via_drm.h>
 
 #include "via_drv.h"
@@ -86,7 +85,7 @@ int via_final_context(struct drm_device *dev, int context)
 	/* Last context, perform cleanup */
 	if (list_is_singular(&dev->ctxlist)) {
 		DRM_DEBUG("Last Context\n");
-		drm_irq_uninstall(dev);
+		drm_legacy_irq_uninstall(dev);
 		via_cleanup_futex(dev_priv);
 		via_do_cleanup_map(dev);
 	}
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index f588f967bb14..604b1d1b2d72 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -191,20 +191,6 @@ struct drm_device {
 	 */
 	struct list_head clientlist;
 
-	/**
-	 * @irq_enabled:
-	 *
-	 * Indicates that interrupt handling is enabled, specifically vblank
-	 * handling. Drivers which don't use drm_irq_install() need to set this
-	 * to true manually.
-	 */
-	bool irq_enabled;
-
-	/**
-	 * @irq: Used by the drm_irq_install() and drm_irq_unistall() helpers.
-	 */
-	int irq;
-
 	/**
 	 * @vblank_disable_immediate:
 	 *
@@ -372,6 +358,10 @@ struct drm_device {
 
 	/* Scatter gather memory */
 	struct drm_sg_mem *sg;
+
+	/* IRQs */
+	bool irq_enabled;
+	int irq;
 #endif
 };
 
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index b439ae1921b8..0cd95953cdf5 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -137,10 +137,6 @@ enum drm_driver_feature {
 	 * @DRIVER_HAVE_IRQ:
 	 *
 	 * Legacy irq support. Only for legacy drivers. Do not use.
-	 *
-	 * New drivers can either use the drm_irq_install() and
-	 * drm_irq_uninstall() helper functions, or roll their own irq support
-	 * code by calling request_irq() directly.
 	 */
 	DRIVER_HAVE_IRQ			= BIT(30),
 	/**
@@ -271,42 +267,6 @@ struct drm_driver {
 	 */
 	void (*release) (struct drm_device *);
 
-	/**
-	 * @irq_handler:
-	 *
-	 * Interrupt handler called when using drm_irq_install(). Not used by
-	 * drivers which implement their own interrupt handling.
-	 */
-	irqreturn_t(*irq_handler) (int irq, void *arg);
-
-	/**
-	 * @irq_preinstall:
-	 *
-	 * Optional callback used by drm_irq_install() which is called before
-	 * the interrupt handler is registered. This should be used to clear out
-	 * any pending interrupts (from e.g. firmware based drives) and reset
-	 * the interrupt handling registers.
-	 */
-	void (*irq_preinstall) (struct drm_device *dev);
-
-	/**
-	 * @irq_postinstall:
-	 *
-	 * Optional callback used by drm_irq_install() which is called after
-	 * the interrupt handler is registered. This should be used to enable
-	 * interrupt generation in the hardware.
-	 */
-	int (*irq_postinstall) (struct drm_device *dev);
-
-	/**
-	 * @irq_uninstall:
-	 *
-	 * Optional callback used by drm_irq_uninstall() which is called before
-	 * the interrupt handler is unregistered. This should be used to disable
-	 * interrupt generation in the hardware.
-	 */
-	void (*irq_uninstall) (struct drm_device *dev);
-
 	/**
 	 * @master_set:
 	 *
@@ -504,6 +464,10 @@ struct drm_driver {
 	int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
 	int (*dma_quiescent) (struct drm_device *);
 	int (*context_dtor) (struct drm_device *dev, int context);
+	irqreturn_t (*irq_handler)(int irq, void *arg);
+	void (*irq_preinstall)(struct drm_device *dev);
+	int (*irq_postinstall)(struct drm_device *dev);
+	void (*irq_uninstall)(struct drm_device *dev);
 	u32 (*get_vblank_counter)(struct drm_device *dev, unsigned int pipe);
 	int (*enable_vblank)(struct drm_device *dev, unsigned int pipe);
 	void (*disable_vblank)(struct drm_device *dev, unsigned int pipe);
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h
deleted file mode 100644
index 53634b988f57..000000000000
--- a/include/drm/drm_irq.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2016 Intel Corp.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _DRM_IRQ_H_
-#define _DRM_IRQ_H_
-
-struct drm_device;
-
-int drm_irq_install(struct drm_device *dev, int irq);
-int drm_irq_uninstall(struct drm_device *dev);
-#endif
diff --git a/include/drm/drm_legacy.h b/include/drm/drm_legacy.h
index b17e79e12bc2..58dc8d8cc907 100644
--- a/include/drm/drm_legacy.h
+++ b/include/drm/drm_legacy.h
@@ -192,6 +192,9 @@ do {										\
 void drm_legacy_idlelock_take(struct drm_lock_data *lock);
 void drm_legacy_idlelock_release(struct drm_lock_data *lock);
 
+/* drm_irq.c */
+int drm_legacy_irq_uninstall(struct drm_device *dev);
+
 /* drm_pci.c */
 
 #ifdef CONFIG_PCI
-- 
2.32.0



From lukasz.luba at arm.com  Tue Aug  3 02:07:44 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue,  3 Aug 2021 10:07:44 +0100
Subject: [PATCH v2] cpufreq: arm_scmi: Fix error path when allocation failed
Message-ID: <20210803090744.12143-1-lukasz.luba@arm.com>

Stop the initialization when cpumask allocation failed and return an
error.

Fixes: 80a064dbd556 ("scmi-cpufreq: Get opp_shared_cpus from opp-v2 for EM")
Signed-off-by: Lukasz Luba <lukasz.luba at arm.com>
---
changes:
v2:
- removed dev_warn() since it's not needed in this case
- adjusted the patch description

 drivers/cpufreq/scmi-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index ec9a87ca2dbb..75f818d04b48 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -134,7 +134,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	}
 
 	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL))
-		ret = -ENOMEM;
+		return -ENOMEM;
 
 	/* Obtain CPUs that share SCMI performance controls */
 	ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
-- 
2.17.1



From lkp at intel.com  Tue Aug  3 02:14:51 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 3 Aug 2021 17:14:51 +0800
Subject: [PATCH 1/1] spi: tegra114: Fix set_cs_timing param
In-Reply-To: <20210803021328.28291-1-Mason.Zhang@mediatek.com>
References: <20210803021328.28291-1-Mason.Zhang@mediatek.com>
Message-ID: <202108031744.g063aSQs-lkp@intel.com>

Hi Mason,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on spi/for-next]
[also build test ERROR on v5.14-rc4 next-20210802]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Mason-Zhang/spi-tegra114-Fix-set_cs_timing-param/20210803-103149
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
config: m68k-allmodconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/8920b64abf63231756f3910e4954bdda80d01257
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Mason-Zhang/spi-tegra114-Fix-set_cs_timing-param/20210803-103149
        git checkout 8920b64abf63231756f3910e4954bdda80d01257
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash drivers/net/ethernet/stmicro/stmmac/ drivers/spi/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/spi/spi-tegra114.c: In function 'tegra_spi_set_hw_cs_timing':
>> drivers/spi/spi-tegra114.c:723:32: error: 'struct spi_device' has no member named 'cs_setup'
     723 |  struct spi_delay *setup = &spi->cs_setup;
         |                                ^~
>> drivers/spi/spi-tegra114.c:724:31: error: 'struct spi_device' has no member named 'cs_hold'
     724 |  struct spi_delay *hold = &spi->cs_hold;
         |                               ^~
>> drivers/spi/spi-tegra114.c:725:35: error: 'struct spi_device' has no member named 'cs_inactive'
     725 |  struct spi_delay *inactive = &spi->cs_inactive;
         |                                   ^~
   drivers/spi/spi-tegra114.c: In function 'tegra_spi_probe':
>> drivers/spi/spi-tegra114.c:1328:24: error: assignment to 'int (*)(struct spi_device *, struct spi_delay *, struct spi_delay *, struct spi_delay *)' from incompatible pointer type 'int (*)(struct spi_device *)' [-Werror=incompatible-pointer-types]
    1328 |  master->set_cs_timing = tegra_spi_set_hw_cs_timing;
         |                        ^
   cc1: some warnings being treated as errors


vim +723 drivers/spi/spi-tegra114.c

   719	
   720	static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
   721	{
   722		struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
 > 723		struct spi_delay *setup = &spi->cs_setup;
 > 724		struct spi_delay *hold = &spi->cs_hold;
 > 725		struct spi_delay *inactive = &spi->cs_inactive;
   726		u8 setup_dly, hold_dly, inactive_dly;
   727		u32 setup_hold;
   728		u32 spi_cs_timing;
   729		u32 inactive_cycles;
   730		u8 cs_state;
   731	
   732		if ((setup && setup->unit != SPI_DELAY_UNIT_SCK) ||
   733		    (hold && hold->unit != SPI_DELAY_UNIT_SCK) ||
   734		    (inactive && inactive->unit != SPI_DELAY_UNIT_SCK)) {
   735			dev_err(&spi->dev,
   736				"Invalid delay unit %d, should be SPI_DELAY_UNIT_SCK\n",
   737				SPI_DELAY_UNIT_SCK);
   738			return -EINVAL;
   739		}
   740	
   741		setup_dly = setup ? setup->value : 0;
   742		hold_dly = hold ? hold->value : 0;
   743		inactive_dly = inactive ? inactive->value : 0;
   744	
   745		setup_dly = min_t(u8, setup_dly, MAX_SETUP_HOLD_CYCLES);
   746		hold_dly = min_t(u8, hold_dly, MAX_SETUP_HOLD_CYCLES);
   747		if (setup_dly && hold_dly) {
   748			setup_hold = SPI_SETUP_HOLD(setup_dly - 1, hold_dly - 1);
   749			spi_cs_timing = SPI_CS_SETUP_HOLD(tspi->spi_cs_timing1,
   750							  spi->chip_select,
   751							  setup_hold);
   752			if (tspi->spi_cs_timing1 != spi_cs_timing) {
   753				tspi->spi_cs_timing1 = spi_cs_timing;
   754				tegra_spi_writel(tspi, spi_cs_timing, SPI_CS_TIMING1);
   755			}
   756		}
   757	
   758		inactive_cycles = min_t(u8, inactive_dly, MAX_INACTIVE_CYCLES);
   759		if (inactive_cycles)
   760			inactive_cycles--;
   761		cs_state = inactive_cycles ? 0 : 1;
   762		spi_cs_timing = tspi->spi_cs_timing2;
   763		SPI_SET_CS_ACTIVE_BETWEEN_PACKETS(spi_cs_timing, spi->chip_select,
   764						  cs_state);
   765		SPI_SET_CYCLES_BETWEEN_PACKETS(spi_cs_timing, spi->chip_select,
   766					       inactive_cycles);
   767		if (tspi->spi_cs_timing2 != spi_cs_timing) {
   768			tspi->spi_cs_timing2 = spi_cs_timing;
   769			tegra_spi_writel(tspi, spi_cs_timing, SPI_CS_TIMING2);
   770		}
   771	
   772		return 0;
   773	}
   774	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 60677 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210803/45f1beeb/attachment-0001.gz>

From lorenzo.pieralisi at arm.com  Tue Aug  3 02:16:05 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue, 3 Aug 2021 10:16:05 +0100
Subject: [PATCH v2 3/3] ACPI: Add memory semantics to acpi_os_map_memory()
In-Reply-To: <20210802164622.GJ18685@arm.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-4-lorenzo.pieralisi@arm.com>
 <20210802164622.GJ18685@arm.com>
Message-ID: <20210803091605.GA9637@lpieralisi>

On Mon, Aug 02, 2021 at 05:46:22PM +0100, Catalin Marinas wrote:
> On Mon, Aug 02, 2021 at 04:23:59PM +0100, Lorenzo Pieralisi wrote:
> > The memory attributes attached to memory regions depend on architecture
> > specific mappings.
> > 
> > For some memory regions, the attributes specified by firmware (eg
> > uncached) are not sufficient to determine how a memory region should be
> > mapped by an OS (for instance a region that is define as uncached in
> > firmware can be mapped as Normal or Device memory on arm64) and
> > therefore the OS must be given control on how to map the region to match
> > the expected mapping behaviour (eg if a mapping is requested with memory
> > semantics, it must allow unaligned accesses).
> > 
> > Rework acpi_os_map_memory() and acpi_os_ioremap() back-end to split
> > them into two separate code paths:
> > 
> > acpi_os_memmap() -> memory semantics
> > acpi_os_ioremap() -> MMIO semantics
> > 
> > The split allows the architectural implementation back-ends to detect
> > the default memory attributes required by the mapping in question
> > (ie the mapping API defines the semantics memory vs MMIO) and map the
> > memory accordingly.
> > 
> > Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702 at arm.com
> > Tested-by: Hanjun Guo <guohanjun at huawei.com>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Acked-by: Ard Biesheuvel <ardb at kernel.org>
> > Cc: Ard Biesheuvel <ardb at kernel.org>
> > Cc: Will Deacon <will at kernel.org>
> > Cc: Hanjun Guo <guohanjun at huawei.com>
> > Cc: Sudeep Holla <sudeep.holla at arm.com>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
> 
> For the arm64 bits:
> 
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> 
> I presume this will get merged via the ACPI tree?

Thank you, I don't know what's the best option in Rafael's opinion
(of course if he is OK with the patches which are mostly touching
ACPI code).

Lorenzo


From dmitry.baryshkov at linaro.org  Tue Aug  3 02:37:29 2021
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Tue, 3 Aug 2021 12:37:29 +0300
Subject: [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-8-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-8-tzimmermann@suse.de>
Message-ID: <1f5f285a-b923-16ff-2ca1-6f92e22ffcab@linaro.org>

On 03/08/2021 12:06, Thomas Zimmermann wrote:
> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> don't benefit from using it.
> 
> DRM IRQ callbacks are now being called directly or inlined.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

Rob should probably also give his blessing on this patch though.

> ---
>   drivers/gpu/drm/msm/msm_drv.c | 113 ++++++++++++++++++++--------------
>   drivers/gpu/drm/msm/msm_kms.h |   2 +-
>   2 files changed, 69 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 1594ae39d54f..a332b09a5a11 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -14,7 +14,6 @@
>   #include <drm/drm_drv.h>
>   #include <drm/drm_file.h>
>   #include <drm/drm_ioctl.h>
> -#include <drm/drm_irq.h>
>   #include <drm/drm_prime.h>
>   #include <drm/drm_of.h>
>   #include <drm/drm_vblank.h>
> @@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
>   	msm_writel(val | or, addr);
>   }
>   
> +static irqreturn_t msm_irq(int irq, void *arg)
> +{
> +	struct drm_device *dev = arg;
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct msm_kms *kms = priv->kms;
> +
> +	BUG_ON(!kms);
> +
> +	return kms->funcs->irq(kms);
> +}
> +
> +static void msm_irq_preinstall(struct drm_device *dev)
> +{
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct msm_kms *kms = priv->kms;
> +
> +	BUG_ON(!kms);
> +
> +	kms->funcs->irq_preinstall(kms);
> +}
> +
> +static int msm_irq_postinstall(struct drm_device *dev)
> +{
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct msm_kms *kms = priv->kms;
> +
> +	BUG_ON(!kms);
> +
> +	if (kms->funcs->irq_postinstall)
> +		return kms->funcs->irq_postinstall(kms);
> +
> +	return 0;
> +}
> +
> +static int msm_irq_install(struct drm_device *dev, unsigned int irq)
> +{
> +	int ret;
> +
> +	if (irq == IRQ_NOTCONNECTED)
> +		return -ENOTCONN;
> +
> +	msm_irq_preinstall(dev);
> +
> +	ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
> +	if (ret)
> +		return ret;
> +
> +	ret = msm_irq_postinstall(dev);
> +	if (ret) {
> +		free_irq(irq, dev);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static void msm_irq_uninstall(struct drm_device *dev)
> +{
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct msm_kms *kms = priv->kms;
> +
> +	kms->funcs->irq_uninstall(kms);
> +	free_irq(kms->irq, dev);
> +}
> +
>   struct msm_vblank_work {
>   	struct work_struct work;
>   	int crtc_id;
> @@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
>   	}
>   
>   	/* We must cancel and cleanup any pending vblank enable/disable
> -	 * work before drm_irq_uninstall() to avoid work re-enabling an
> +	 * work before msm_irq_uninstall() to avoid work re-enabling an
>   	 * irq after uninstall has disabled it.
>   	 */
>   
> @@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
>   	drm_mode_config_cleanup(ddev);
>   
>   	pm_runtime_get_sync(dev);
> -	drm_irq_uninstall(ddev);
> +	msm_irq_uninstall(ddev);
>   	pm_runtime_put_sync(dev);
>   
>   	if (kms && kms->funcs)
> @@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
>   
>   	if (kms) {
>   		pm_runtime_get_sync(dev);
> -		ret = drm_irq_install(ddev, kms->irq);
> +		ret = msm_irq_install(ddev, kms->irq);
>   		pm_runtime_put_sync(dev);
>   		if (ret < 0) {
>   			DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
> @@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
>   	context_close(ctx);
>   }
>   
> -static irqreturn_t msm_irq(int irq, void *arg)
> -{
> -	struct drm_device *dev = arg;
> -	struct msm_drm_private *priv = dev->dev_private;
> -	struct msm_kms *kms = priv->kms;
> -	BUG_ON(!kms);
> -	return kms->funcs->irq(kms);
> -}
> -
> -static void msm_irq_preinstall(struct drm_device *dev)
> -{
> -	struct msm_drm_private *priv = dev->dev_private;
> -	struct msm_kms *kms = priv->kms;
> -	BUG_ON(!kms);
> -	kms->funcs->irq_preinstall(kms);
> -}
> -
> -static int msm_irq_postinstall(struct drm_device *dev)
> -{
> -	struct msm_drm_private *priv = dev->dev_private;
> -	struct msm_kms *kms = priv->kms;
> -	BUG_ON(!kms);
> -
> -	if (kms->funcs->irq_postinstall)
> -		return kms->funcs->irq_postinstall(kms);
> -
> -	return 0;
> -}
> -
> -static void msm_irq_uninstall(struct drm_device *dev)
> -{
> -	struct msm_drm_private *priv = dev->dev_private;
> -	struct msm_kms *kms = priv->kms;
> -	BUG_ON(!kms);
> -	kms->funcs->irq_uninstall(kms);
> -}
> -
>   int msm_crtc_enable_vblank(struct drm_crtc *crtc)
>   {
>   	struct drm_device *dev = crtc->dev;
> @@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
>   	.open               = msm_open,
>   	.postclose           = msm_postclose,
>   	.lastclose          = drm_fb_helper_lastclose,
> -	.irq_handler        = msm_irq,
> -	.irq_preinstall     = msm_irq_preinstall,
> -	.irq_postinstall    = msm_irq_postinstall,
> -	.irq_uninstall      = msm_irq_uninstall,
>   	.dumb_create        = msm_gem_dumb_create,
>   	.dumb_map_offset    = msm_gem_dumb_map_offset,
>   	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
> diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
> index 086a2d59b8c8..9de7c42e1071 100644
> --- a/drivers/gpu/drm/msm/msm_kms.h
> +++ b/drivers/gpu/drm/msm/msm_kms.h
> @@ -150,7 +150,7 @@ struct msm_kms {
>   	const struct msm_kms_funcs *funcs;
>   	struct drm_device *dev;
>   
> -	/* irq number to be passed on to drm_irq_install */
> +	/* irq number to be passed on to msm_irq_install */
>   	int irq;
>   
>   	/* mapper-id used to request GEM buffer mapped for scanout: */
> 


-- 
With best wishes
Dmitry


From maz at kernel.org  Tue Aug  3 02:44:34 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 03 Aug 2021 10:44:34 +0100
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <7h7diwgjup.fsf@baylibre.com>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
Message-ID: <87im0m277h.wl-maz@kernel.org>

On Mon, 14 Jun 2021 23:30:22 +0100,
Kevin Hilman <khilman at baylibre.com> wrote:
> 
> Marc Zyngier <maz at kernel.org> writes:
> 
> > On Fri, 21 May 2021 10:47:48 +0100,
> > Lee Jones <lee.jones at linaro.org> wrote:
> >> 
> >> [1  <text/plain; UTF-8 (quoted-printable)>]
> >> On Tue, 20 Oct 2020 at 19:23, Kevin Hilman <khilman at baylibre.com> wrote:
> >> 
> >> > Neil Armstrong <narmstrong at baylibre.com> writes:
> >> >
> >> > > In order to reduce the kernel Image size on multi-platform distributions,
> >> > > make it possible to build the Amlogic GPIO IRQ controller as a module
> >> > > by switching it to a platform driver.
> >> > >
> >> > > Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> >> >
> >> > Reviewed-by: Kevin Hilman <khilman at baylibre.com>
> >> > Tested-by: Kevin Hilman <khilman at baylibre.com>
> >> >
> >> > Tested as a module on meson-sm1-khadas-vim3l where the wired networking
> >> > uses GPIO IRQs.
> >> >
> >> 
> >> Good morning Neil, Kevin,
> >> 
> >> What happened to this set in the end?  I still don't see it in Mainline.
> >
> > Last time I tried this patch, it broke my test setup in non-obvious
> > ways. Has someone checked that the issue I reported back then has been
> > resolved now that fw_devlink is more usable?
> 
> OK, after much anticipation (and much delay due to me forgetting about
> this), I just gave this series a spin again on top of v5.13-rc6, and it
> seems to work fine with `fw_devlink=on`
> 
> I started with your config[1] and accepting all the defaults of any new
> configs.  IOW, I ran: yes '' | make oldconfig after copying your config
> to .config.
> 
> With that it seems to be working fine for me.
> 
> Right after boot (and before network probes) I see module loaded, but no
> users yet in /proc/interrupts:
> 
> / # uname -a
> Linux buildroot 5.13.0-rc6-00002-g679c8e852942 #5 SMP PREEMPT Mon Jun 14 15:08:40 PDT 2021 aarch64 GNU/Linux
> / # lsmod |grep gpio
> irq_meson_gpio         20480  0
> leds_gpio              16384  0
> / # cat /proc/interrupts
>            CPU0       CPU1       CPU2       CPU3
>   9:          0          0          0          0     GICv2  25 Level     vgic
>  11:          0          0          0          0     GICv2  30 Level     kvm guest ptimer
>  12:          0          0          0          0     GICv2  27 Level     kvm guest vtimer
>  13:       1416        916        534       1421     GICv2  26 Level     arch_timer
>  15:          5          0          0          0     GICv2  89 Edge      dw_hdmi_top_irq, ff600000.hdmi-tx
>  22:         38          0          0          0     GICv2 225 Edge      ttyAML0
>  23:         20          0          0          0     GICv2 227 Edge      ff805000.i2c
>  25:          2          0          0          0     GICv2 232 Edge      ff809000.adc
>  28:        322          0          0          0     GICv2  35 Edge      meson
>  31:          0          0          0          0     GICv2 222 Edge      ffe05000.sd
>  32:        787          0          0          0     GICv2 223 Edge      ffe07000.mmc
>  34:          0          0          0          0     GICv2 194 Level     panfrost-job
>  35:          0          0          0          0     GICv2 193 Level     panfrost-mmu
>  36:          3          0          0          0     GICv2 192 Level     panfrost-gpu
>  39:          0          0          0          0     GICv2  63 Level     ff400000.usb, ff400000.usb
>  40:         32          0          0          0     GICv2  62 Level     xhci-hcd:usb1
> IPI0:       425        544        664        925       Rescheduling interrupts
> IPI1:        86        166        269        136       Function call interrupts
> IPI2:         0          0          0          0       CPU stop interrupts
> IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
> IPI4:         0          0          0          0       Timer broadcast interrupts
> IPI5:         0          0          0          0       IRQ work interrupts
> IPI6:         0          0          0          0       CPU wake-up interrupts
> Err:          0
> 
> So then I init the network interface and PHY works, DHCP works etc.
> 
> / # udhcpc
> udhcpc: started, v1.31.1
> [  102.250449] meson8b-dwmac ff3f0000.ethernet eth0: PHY [0.0:00] driver [RTL8211F Gigabit Ethernet] (irq=37)
> [  102.256413] meson8b-dwmac ff3f0000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
> [  102.269433] meson8b-dwmac ff3f0000.ethernet eth0: No Safety Features support found
> [  102.271357] meson8b-dwmac ff3f0000.ethernet eth0: PTP not supported by HW
> [  102.278493] meson8b-dwmac ff3f0000.ethernet eth0: configuring for phy/rgmii link mode
> udhcpc: sending discover
> [  104.743301] meson8b-dwmac ff3f0000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
> [  104.746470] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
> udhcpc: sending discover
> udhcpc: sending select for 192.168.0.122
> udhcpc: lease of 192.168.0.122 obtained, lease time 600
> deleting routers
> adding dns 192.168.0.254
> adding dns 192.168.0.254
> / # cat /proc/interrupts
>            CPU0       CPU1       CPU2       CPU3
>   9:          0          0          0          0     GICv2  25 Level     vgic
>  11:          0          0          0          0     GICv2  30 Level     kvm guest ptimer
>  12:          0          0          0          0     GICv2  27 Level     kvm guest vtimer
>  13:       1575       1018        604       1588     GICv2  26 Level     arch_timer
>  14:          8          0          0          0     GICv2  40 Level     eth0
>  15:          5          0          0          0     GICv2  89 Edge      dw_hdmi_top_irq, ff600000.hdmi-tx
>  22:        132          0          0          0     GICv2 225 Edge      ttyAML0
>  23:         20          0          0          0     GICv2 227 Edge      ff805000.i2c
>  25:          2          0          0          0     GICv2 232 Edge      ff809000.adc
>  28:        322          0          0          0     GICv2  35 Edge      meson
>  31:          0          0          0          0     GICv2 222 Edge      ffe05000.sd
>  32:        787          0          0          0     GICv2 223 Edge      ffe07000.mmc
>  34:          0          0          0          0     GICv2 194 Level     panfrost-job
>  35:          0          0          0          0     GICv2 193 Level     panfrost-mmu
>  36:          3          0          0          0     GICv2 192 Level     panfrost-gpu
>  37:          2          0          0          0  meson-gpio-irqchip  26 Level     0.0:00
>  39:          0          0          0          0     GICv2  63 Level     ff400000.usb, ff400000.usb
>  40:         32          0          0          0     GICv2  62 Level     xhci-hcd:usb1
> IPI0:       476        567        720        956       Rescheduling interrupts
> IPI1:        93        166        270        137       Function call interrupts
> IPI2:         0          0          0          0       CPU stop interrupts
> IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
> IPI4:         0          0          0          0       Timer broadcast interrupts
> IPI5:         0          0          0          0       IRQ work interrupts
> IPI6:         0          0          0          0       CPU wake-up interrupts
> Err:          0
> / #

This thing keeps failing on my end. It only works if I force the
irqchip module to be present before the MDIO module is loaded. Here's
an example:

root at tiger-roach:~# modprobe mdio_mux_meson_g12a
[  125.871544] libphy: mdio_mux: probed
[  125.882575] g12a-mdio_mux ff64c000.mdio-multiplexer: Error: Failed to register MDIO bus for child /soc/bus at ff600000/mdio-multiplexer at 4c000/mdio at 0
[  125.892630] libphy: mdio_mux: probed

Trying to bring up the Ethernet interface will fail. Note that there
was no attempt to load the irqchip driver.

root at tiger-roach:~# modprobe -r mdio_mux_meson_g12a
root at tiger-roach:~# modprobe irq-meson-gpio 
[  144.983344] meson-gpio-intc ffd0f080.interrupt-controller: 100 to 8 gpio interrupt mux initialized
root at tiger-roach:~# modprobe mdio_mux_meson_g12a
[  150.376464] libphy: mdio_mux: probed
[  150.391039] libphy: mdio_mux: probed

And it now works.

Is it a MDIO issue? a fw_devlink issue? No idea. But I'd really like
to see this addressed before taking this patch, as everything works
just fine as long as the irqchip is built in (which on its own could
well pure luck).

Saravana, could you please have a look from a fw_devlink perspective?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Tue Aug  3 02:51:11 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 03 Aug 2021 10:51:11 +0100
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <87im0m277h.wl-maz@kernel.org>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
Message-ID: <87h7g626wg.wl-maz@kernel.org>

On Tue, 03 Aug 2021 10:44:34 +0100,
Marc Zyngier <maz at kernel.org> wrote:

[...]

> This thing keeps failing on my end. It only works if I force the
> irqchip module to be present before the MDIO module is loaded. Here's
> an example:
> 
> root at tiger-roach:~# modprobe mdio_mux_meson_g12a
> [  125.871544] libphy: mdio_mux: probed
> [  125.882575] g12a-mdio_mux ff64c000.mdio-multiplexer: Error: Failed to register MDIO bus for child /soc/bus at ff600000/mdio-multiplexer at 4c000/mdio at 0
> [  125.892630] libphy: mdio_mux: probed
> 
> Trying to bring up the Ethernet interface will fail. Note that there
> was no attempt to load the irqchip driver.
> 
> root at tiger-roach:~# modprobe -r mdio_mux_meson_g12a
> root at tiger-roach:~# modprobe irq-meson-gpio 
> [  144.983344] meson-gpio-intc ffd0f080.interrupt-controller: 100 to 8 gpio interrupt mux initialized
> root at tiger-roach:~# modprobe mdio_mux_meson_g12a
> [  150.376464] libphy: mdio_mux: probed
> [  150.391039] libphy: mdio_mux: probed
> 
> And it now works.

An additional source of amusement is that this patch allows the
irqchip to be removed from the kernel. It becomes really fun when you
have live interrupts...

	M.

-- 
Without deviation from the norm, progress is not possible.


From narmstrong at baylibre.com  Tue Aug  3 02:51:59 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 3 Aug 2021 11:51:59 +0200
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <87im0m277h.wl-maz@kernel.org>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
Message-ID: <f5a12599-f7dd-75a4-08ea-867f833e2572@baylibre.com>

On 03/08/2021 11:44, Marc Zyngier wrote:
> On Mon, 14 Jun 2021 23:30:22 +0100,
> Kevin Hilman <khilman at baylibre.com> wrote:
>>
>> Marc Zyngier <maz at kernel.org> writes:
>>
>>> On Fri, 21 May 2021 10:47:48 +0100,
>>> Lee Jones <lee.jones at linaro.org> wrote:
>>>>
>>>> [1  <text/plain; UTF-8 (quoted-printable)>]
>>>> On Tue, 20 Oct 2020 at 19:23, Kevin Hilman <khilman at baylibre.com> wrote:
>>>>
>>>>> Neil Armstrong <narmstrong at baylibre.com> writes:
>>>>>
>>>>>> In order to reduce the kernel Image size on multi-platform distributions,
>>>>>> make it possible to build the Amlogic GPIO IRQ controller as a module
>>>>>> by switching it to a platform driver.
>>>>>>
>>>>>> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
>>>>>
>>>>> Reviewed-by: Kevin Hilman <khilman at baylibre.com>
>>>>> Tested-by: Kevin Hilman <khilman at baylibre.com>
>>>>>
>>>>> Tested as a module on meson-sm1-khadas-vim3l where the wired networking
>>>>> uses GPIO IRQs.
>>>>>
>>>>
>>>> Good morning Neil, Kevin,
>>>>
>>>> What happened to this set in the end?  I still don't see it in Mainline.
>>>
>>> Last time I tried this patch, it broke my test setup in non-obvious
>>> ways. Has someone checked that the issue I reported back then has been
>>> resolved now that fw_devlink is more usable?
>>
>> OK, after much anticipation (and much delay due to me forgetting about
>> this), I just gave this series a spin again on top of v5.13-rc6, and it
>> seems to work fine with `fw_devlink=on`
>>
>> I started with your config[1] and accepting all the defaults of any new
>> configs.  IOW, I ran: yes '' | make oldconfig after copying your config
>> to .config.
>>
>> With that it seems to be working fine for me.
>>
>> Right after boot (and before network probes) I see module loaded, but no
>> users yet in /proc/interrupts:
>>
>> / # uname -a
>> Linux buildroot 5.13.0-rc6-00002-g679c8e852942 #5 SMP PREEMPT Mon Jun 14 15:08:40 PDT 2021 aarch64 GNU/Linux
>> / # lsmod |grep gpio
>> irq_meson_gpio         20480  0
>> leds_gpio              16384  0
>> / # cat /proc/interrupts
>>            CPU0       CPU1       CPU2       CPU3
>>   9:          0          0          0          0     GICv2  25 Level     vgic
>>  11:          0          0          0          0     GICv2  30 Level     kvm guest ptimer
>>  12:          0          0          0          0     GICv2  27 Level     kvm guest vtimer
>>  13:       1416        916        534       1421     GICv2  26 Level     arch_timer
>>  15:          5          0          0          0     GICv2  89 Edge      dw_hdmi_top_irq, ff600000.hdmi-tx
>>  22:         38          0          0          0     GICv2 225 Edge      ttyAML0
>>  23:         20          0          0          0     GICv2 227 Edge      ff805000.i2c
>>  25:          2          0          0          0     GICv2 232 Edge      ff809000.adc
>>  28:        322          0          0          0     GICv2  35 Edge      meson
>>  31:          0          0          0          0     GICv2 222 Edge      ffe05000.sd
>>  32:        787          0          0          0     GICv2 223 Edge      ffe07000.mmc
>>  34:          0          0          0          0     GICv2 194 Level     panfrost-job
>>  35:          0          0          0          0     GICv2 193 Level     panfrost-mmu
>>  36:          3          0          0          0     GICv2 192 Level     panfrost-gpu
>>  39:          0          0          0          0     GICv2  63 Level     ff400000.usb, ff400000.usb
>>  40:         32          0          0          0     GICv2  62 Level     xhci-hcd:usb1
>> IPI0:       425        544        664        925       Rescheduling interrupts
>> IPI1:        86        166        269        136       Function call interrupts
>> IPI2:         0          0          0          0       CPU stop interrupts
>> IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
>> IPI4:         0          0          0          0       Timer broadcast interrupts
>> IPI5:         0          0          0          0       IRQ work interrupts
>> IPI6:         0          0          0          0       CPU wake-up interrupts
>> Err:          0
>>
>> So then I init the network interface and PHY works, DHCP works etc.
>>
>> / # udhcpc
>> udhcpc: started, v1.31.1
>> [  102.250449] meson8b-dwmac ff3f0000.ethernet eth0: PHY [0.0:00] driver [RTL8211F Gigabit Ethernet] (irq=37)
>> [  102.256413] meson8b-dwmac ff3f0000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
>> [  102.269433] meson8b-dwmac ff3f0000.ethernet eth0: No Safety Features support found
>> [  102.271357] meson8b-dwmac ff3f0000.ethernet eth0: PTP not supported by HW
>> [  102.278493] meson8b-dwmac ff3f0000.ethernet eth0: configuring for phy/rgmii link mode
>> udhcpc: sending discover
>> [  104.743301] meson8b-dwmac ff3f0000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
>> [  104.746470] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
>> udhcpc: sending discover
>> udhcpc: sending select for 192.168.0.122
>> udhcpc: lease of 192.168.0.122 obtained, lease time 600
>> deleting routers
>> adding dns 192.168.0.254
>> adding dns 192.168.0.254
>> / # cat /proc/interrupts
>>            CPU0       CPU1       CPU2       CPU3
>>   9:          0          0          0          0     GICv2  25 Level     vgic
>>  11:          0          0          0          0     GICv2  30 Level     kvm guest ptimer
>>  12:          0          0          0          0     GICv2  27 Level     kvm guest vtimer
>>  13:       1575       1018        604       1588     GICv2  26 Level     arch_timer
>>  14:          8          0          0          0     GICv2  40 Level     eth0
>>  15:          5          0          0          0     GICv2  89 Edge      dw_hdmi_top_irq, ff600000.hdmi-tx
>>  22:        132          0          0          0     GICv2 225 Edge      ttyAML0
>>  23:         20          0          0          0     GICv2 227 Edge      ff805000.i2c
>>  25:          2          0          0          0     GICv2 232 Edge      ff809000.adc
>>  28:        322          0          0          0     GICv2  35 Edge      meson
>>  31:          0          0          0          0     GICv2 222 Edge      ffe05000.sd
>>  32:        787          0          0          0     GICv2 223 Edge      ffe07000.mmc
>>  34:          0          0          0          0     GICv2 194 Level     panfrost-job
>>  35:          0          0          0          0     GICv2 193 Level     panfrost-mmu
>>  36:          3          0          0          0     GICv2 192 Level     panfrost-gpu
>>  37:          2          0          0          0  meson-gpio-irqchip  26 Level     0.0:00
>>  39:          0          0          0          0     GICv2  63 Level     ff400000.usb, ff400000.usb
>>  40:         32          0          0          0     GICv2  62 Level     xhci-hcd:usb1
>> IPI0:       476        567        720        956       Rescheduling interrupts
>> IPI1:        93        166        270        137       Function call interrupts
>> IPI2:         0          0          0          0       CPU stop interrupts
>> IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
>> IPI4:         0          0          0          0       Timer broadcast interrupts
>> IPI5:         0          0          0          0       IRQ work interrupts
>> IPI6:         0          0          0          0       CPU wake-up interrupts
>> Err:          0
>> / #
> 
> This thing keeps failing on my end. It only works if I force the
> irqchip module to be present before the MDIO module is loaded. Here's
> an example:
> 
> root at tiger-roach:~# modprobe mdio_mux_meson_g12a
> [  125.871544] libphy: mdio_mux: probed
> [  125.882575] g12a-mdio_mux ff64c000.mdio-multiplexer: Error: Failed to register MDIO bus for child /soc/bus at ff600000/mdio-multiplexer at 4c000/mdio at 0
> [  125.892630] libphy: mdio_mux: probed

This error is caused because the PHY in the mdio at 0 sub-bus cannot get the IRQ from the irq-meson-gpio driver,
so it may be a dependency issue causing the PHY not probing the irq-meson-gpio node.

IRQ management from PHY drivers is weird, because the core request the IRQ instead of the PHY driver.
maybe causing fw_devlink issue not detecting the link.

Neil

> 
> Trying to bring up the Ethernet interface will fail. Note that there
> was no attempt to load the irqchip driver.
> 
> root at tiger-roach:~# modprobe -r mdio_mux_meson_g12a
> root at tiger-roach:~# modprobe irq-meson-gpio 
> [  144.983344] meson-gpio-intc ffd0f080.interrupt-controller: 100 to 8 gpio interrupt mux initialized
> root at tiger-roach:~# modprobe mdio_mux_meson_g12a
> [  150.376464] libphy: mdio_mux: probed
> [  150.391039] libphy: mdio_mux: probed
> 
> And it now works.
> 
> Is it a MDIO issue? a fw_devlink issue? No idea. But I'd really like
> to see this addressed before taking this patch, as everything works
> just fine as long as the irqchip is built in (which on its own could
> well pure luck).
> 
> Saravana, could you please have a look from a fw_devlink perspective?
> 
> Thanks,
> 
> 	M.
> 



From lorenzo.pieralisi at arm.com  Tue Aug  3 02:58:39 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue, 3 Aug 2021 10:58:39 +0100
Subject: [PATCH v2 5/6] misc: pci_endpoint_test: Do not request or
 allocate IRQs in probe
In-Reply-To: <20210803074932.19820-6-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
 <20210803074932.19820-6-kishon@ti.com>
Message-ID: <20210803095839.GA11252@lpieralisi>

On Tue, Aug 03, 2021 at 01:19:31PM +0530, Kishon Vijay Abraham I wrote:
> Allocation of IRQ vectors and requesting IRQ is done as part of
> PCITEST_SET_IRQTYPE. Do not request or allocate IRQs in probe for
> AM654 and J721E so that the user space test script has better control
> of the devices for which the IRQs are configured. Since certain user
> space scripts could rely on allocation of IRQ vectors during probe,
> remove allocation of IRQs only for TI's K3 platform.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  drivers/misc/pci_endpoint_test.c | 19 +++++++++++++------
>  1 file changed, 13 insertions(+), 6 deletions(-)

I don't claim to understand the inner details of the endpoint test
device but it looks like this approach should be redesigned.

I don't believe using devices quirks is the best approach to
expose/remove a feature to userspace, this can soon become
unmaintenable.

Maybe you can elaborate a bit more on what the real issue is please ?

Thanks,
Lorenzo

> diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
> index c7ee34013485..9740f2a0e7cd 100644
> --- a/drivers/misc/pci_endpoint_test.c
> +++ b/drivers/misc/pci_endpoint_test.c
> @@ -79,6 +79,9 @@
>  #define PCI_DEVICE_ID_RENESAS_R8A774C0		0x002d
>  #define PCI_DEVICE_ID_RENESAS_R8A774E1		0x0025
>  
> +#define is_j721e_pci_dev(pdev)         \
> +		((pdev)->device == PCI_DEVICE_ID_TI_J721E)
> +
>  static DEFINE_IDA(pci_endpoint_test_ida);
>  
>  #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
> @@ -810,9 +813,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
>  
>  	pci_set_master(pdev);
>  
> -	if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
> -		err = -EINVAL;
> -		goto err_disable_irq;
> +	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
> +		if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
> +			err = -EINVAL;
> +			goto err_disable_irq;
> +		}
>  	}
>  
>  	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
> @@ -850,9 +855,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
>  		goto err_ida_remove;
>  	}
>  
> -	if (!pci_endpoint_test_request_irq(test)) {
> -		err = -EINVAL;
> -		goto err_kfree_test_name;
> +	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
> +		if (!pci_endpoint_test_request_irq(test)) {
> +			err = -EINVAL;
> +			goto err_kfree_test_name;
> +		}
>  	}
>  
>  	misc_device = &test->miscdev;
> -- 
> 2.17.1
> 


From will at kernel.org  Tue Aug  3 03:05:17 2021
From: will at kernel.org (Will Deacon)
Date: Tue,  3 Aug 2021 11:05:17 +0100
Subject: [PATCH 0/2] arm64: stacktrace: minor fixes
In-Reply-To: <20210802164845.45506-1-mark.rutland@arm.com>
References: <20210802164845.45506-1-mark.rutland@arm.com>
Message-ID: <162798357625.1498135.17761715523508973677.b4-ty@kernel.org>

On Mon, 2 Aug 2021 17:48:43 +0100, Mark Rutland wrote:
> These patches address a couple of minor issues I spotted while reviewing
> arm64's stacktrace code. Patch 1 is a simple comment fix, and patch 2
> addresses an imbalance across the main stack and the fgraph return
> stack.
> 
> Thanks,
> Mark
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/2] arm64: stacktrace: fix comment
      https://git.kernel.org/arm64/c/8d5903f45714
[2/2] arm64: stacktrace: avoid tracing arch_stack_walk()
      https://git.kernel.org/arm64/c/0c32706dac1b

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Aug  3 03:05:18 2021
From: will at kernel.org (Will Deacon)
Date: Tue,  3 Aug 2021 11:05:18 +0100
Subject: [PATCH] arm64: fix compat syscall return truncation
In-Reply-To: <20210802104200.21390-1-mark.rutland@arm.com>
References: <20210802104200.21390-1-mark.rutland@arm.com>
Message-ID: <162798246925.1496416.18370048177731333482.b4-ty@kernel.org>

On Mon, 2 Aug 2021 11:42:00 +0100, Mark Rutland wrote:
> Due to inconsistencies in the way we manipulate compat GPRs, we have a
> few issues today:
> 
> * For audit and tracing, where error codes are handled as a (native)
>   long, negative error codes are expected to be sign-extended to the
>   native 64-bits, or they may fail to be matched correctly. Thus a
>   syscall which fails with an error may erroneously be identified as
>   failing.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: fix compat syscall return truncation
      https://git.kernel.org/arm64/c/e30e8d46cf60

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Aug  3 03:05:19 2021
From: will at kernel.org (Will Deacon)
Date: Tue,  3 Aug 2021 11:05:19 +0100
Subject: [PATCH] arm64: move warning about toolchains to archprepare
In-Reply-To: <20210801053525.105235-1-masahiroy@kernel.org>
References: <20210801053525.105235-1-masahiroy@kernel.org>
Message-ID: <162798335878.1497520.5664687589447099118.b4-ty@kernel.org>

On Sun, 1 Aug 2021 14:35:25 +0900, Masahiro Yamada wrote:
> Commit 987fdfec2410 ("arm64: move --fix-cortex-a53-843419 linker test to
> Kconfig") fixed the false-positive warning in the installation step.
> 
> Yet, there are some cases where this false-positive is shown. For example,
> you can see it when you cross 987fdfec2410 during git-bisect.
> 
>   $ git checkout 987fdfec2410^
>     [ snip ]
>   $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig all
>     [ snip ]
>   $ git checkout v5.13
>     [ snip]
>   $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig all
>     [ snip ]
>   arch/arm64/Makefile:25: ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: move warning about toolchains to archprepare
      https://git.kernel.org/arm64/c/64ee84c75b5f

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Aug  3 03:05:20 2021
From: will at kernel.org (Will Deacon)
Date: Tue,  3 Aug 2021 11:05:20 +0100
Subject: [PATCH v2] arm64: fix the doc of RANDOMIZE_MODULE_REGION_FULL
In-Reply-To: <20210730125131.13724-1-song.bao.hua@hisilicon.com>
References: <20210730125131.13724-1-song.bao.hua@hisilicon.com>
Message-ID: <162798340286.1497797.18069753288714137637.b4-ty@kernel.org>

On Sat, 31 Jul 2021 00:51:31 +1200, Barry Song wrote:
> Obviously kaslr is setting the module region to 2GB rather than 4GB since
> commit b2eed9b588112 ("arm64/kernel: kaslr: reduce module randomization
> range to 2 GB"). So fix the size of region in Kconfig.
> On the other hand, even though RANDOMIZE_MODULE_REGION_FULL is not set,
> module_alloc() can fall back to a 2GB window if ARM64_MODULE_PLTS is set.
> In this case, veneers are still needed. !RANDOMIZE_MODULE_REGION_FULL
> doesn't necessarily mean veneers are not needed.
> So fix the doc to be more precise to avoid any confusion to the readers
> of the code.

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: fix the doc of RANDOMIZE_MODULE_REGION_FULL
      https://git.kernel.org/arm64/c/f9c4ff2ab9fe

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From lorenzo.pieralisi at arm.com  Tue Aug  3 03:08:48 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue, 3 Aug 2021 11:08:48 +0100
Subject: [PATCH v2 2/6] PCI: cadence: Add quirk flag to set minimum delay
 in LTSSM Detect.Quiet state
In-Reply-To: <20210803074932.19820-3-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
 <20210803074932.19820-3-kishon@ti.com>
Message-ID: <20210803100848.GB11252@lpieralisi>

On Tue, Aug 03, 2021 at 01:19:28PM +0530, Kishon Vijay Abraham I wrote:
> From: Nadeem Athani <nadeem at cadence.com>
> 
> PCIe fails to link up if SERDES lanes not used by PCIe are assigned to
> another protocol. For example, link training fails if lanes 2 and 3 are
> assigned to another protocol while lanes 0 and 1 are used for PCIe to
> form a two lane link. This failure is due to an incorrect tie-off on an
> internal status signal indicating electrical idle.
> 
> Status signals going from SERDES to PCIe Controller are tied-off when a
> lane is not assigned to PCIe. Signal indicating electrical idle is
> incorrectly tied-off to a state that indicates non-idle. As a result,
> PCIe sees unused lanes to be out of electrical idle and this causes
> LTSSM to exit Detect.Quiet state without waiting for 12ms timeout to
> occur. If a receiver is not detected on the first receiver detection
> attempt in Detect.Active state, LTSSM goes back to Detect.Quiet and
> again moves forward to Detect.Active state without waiting for 12ms as
> required by PCIe base specification. Since wait time in Detect.Quiet is
> skipped, multiple receiver detect operations are performed back-to-back
> without allowing time for capacitance on the transmit lines to
> discharge. This causes subsequent receiver detection to always fail even
> if a receiver gets connected eventually.
> 
> Add a quirk flag "quirk_detect_quiet_flag" to program the minimum
> time the LTSSM should wait on entering Detect.Quiet state here.
> This has to be set for J7200 as it has an incorrect tie-off on unused
> lanes.
> 
> Signed-off-by: Nadeem Athani <nadeem at cadence.com>
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  .../pci/controller/cadence/pcie-cadence-ep.c    |  4 ++++
>  .../pci/controller/cadence/pcie-cadence-host.c  |  3 +++
>  drivers/pci/controller/cadence/pcie-cadence.c   | 17 +++++++++++++++++
>  drivers/pci/controller/cadence/pcie-cadence.h   | 15 +++++++++++++++
>  4 files changed, 39 insertions(+)
> 
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> index 791915054ff4..e05c157afef0 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> @@ -804,6 +804,10 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
>  	ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
>  	/* Reserve region 0 for IRQs */
>  	set_bit(0, &ep->ob_region_map);
> +
> +	if (ep->quirk_detect_quiet_flag)
> +		cdns_pcie_detect_quiet_min_delay_set(&ep->pcie);
> +
>  	spin_lock_init(&ep->lock);
>  
>  	return 0;
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
> index ae1c55503513..fb96d37a135c 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence-host.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
> @@ -498,6 +498,9 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
>  		return PTR_ERR(rc->cfg_base);
>  	rc->cfg_res = res;
>  
> +	if (rc->quirk_detect_quiet_flag)
> +		cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
> +
>  	ret = cdns_pcie_start_link(pcie);
>  	if (ret) {
>  		dev_err(dev, "Failed to start link\n");
> diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
> index 3c3646502d05..65b6c8bed0d4 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence.c
> @@ -7,6 +7,23 @@
>  
>  #include "pcie-cadence.h"
>  
> +void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie)
> +{
> +	u32 delay = 0x3;
> +	u32 ltssm_control_cap;
> +
> +	/*
> +	 * Set the LTSSM Detect Quiet state min. delay to 2ms.
> +	 */
> +

Nit: empty line not needed

> +	ltssm_control_cap = cdns_pcie_readl(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP);
> +	ltssm_control_cap = ((ltssm_control_cap &
> +			    ~CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK) |
> +			    CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay));
> +
> +	cdns_pcie_writel(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP, ltssm_control_cap);
> +}
> +
>  void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
>  				   u32 r, bool is_io,
>  				   u64 cpu_addr, u64 pci_addr, size_t size)
> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
> index a978a2eeedad..cda430d0f6e4 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence.h
> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
> @@ -194,6 +194,14 @@
>  /* AXI link down register */
>  #define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824)
>  
> +/* LTSSM Capabilities register */
> +#define CDNS_PCIE_LTSSM_CONTROL_CAP             (CDNS_PCIE_LM_BASE + 0x0054)
> +#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK  GENMASK(2, 1)
> +#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT 1
> +#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay) \
> +	 (((delay) << CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT) & \
> +	 CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK)
> +
>  enum cdns_pcie_rp_bar {
>  	RP_BAR_UNDEFINED = -1,
>  	RP_BAR0,
> @@ -300,6 +308,7 @@ struct cdns_pcie {
>   * @avail_ib_bar: Satus of RP_BAR0, RP_BAR1 and	RP_NO_BAR if it's free or
>   *                available
>   * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
> + * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
>   */
>  struct cdns_pcie_rc {
>  	struct cdns_pcie	pcie;
> @@ -309,6 +318,7 @@ struct cdns_pcie_rc {
>  	u32			device_id;
>  	bool			avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
>  	unsigned int		quirk_retrain_flag:1;
> +	unsigned int		quirk_detect_quiet_flag:1;
>  };
>  
>  /**
> @@ -341,6 +351,7 @@ struct cdns_pcie_epf {
>   *        registers fields (RMW) accessible by both remote RC and EP to
>   *        minimize time between read and write
>   * @epf: Structure to hold info about endpoint function
> + * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
>   */
>  struct cdns_pcie_ep {
>  	struct cdns_pcie	pcie;
> @@ -355,6 +366,7 @@ struct cdns_pcie_ep {
>  	/* protect writing to PCI_STATUS while raising legacy interrupts */
>  	spinlock_t		lock;
>  	struct cdns_pcie_epf	*epf;
> +	unsigned int		quirk_detect_quiet_flag:1;
>  };
>  
>  
> @@ -515,6 +527,9 @@ static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
>  	return 0;
>  }
>  #endif
> +
> +void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
> +
>  void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
>  				   u32 r, bool is_io,
>  				   u64 cpu_addr, u64 pci_addr, size_t size);
> -- 
> 2.17.1
> 


From qperret at google.com  Tue Aug  3 03:13:12 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 3 Aug 2021 11:13:12 +0100
Subject: [PATCH v3 10/21] KVM: arm64: Enable forcing page-level stage-2
 mappings
In-Reply-To: <CA+EHjTxCvqQ=jmBPJ1N6ShBf=f4J5cjT4pt9akfnqNjQUoqzWw@mail.gmail.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-11-qperret@google.com>
 <CA+EHjTxCvqQ=jmBPJ1N6ShBf=f4J5cjT4pt9akfnqNjQUoqzWw@mail.gmail.com>
Message-ID: <YQkWuCVkKWJX81en@google.com>

Hi Fuad,

On Monday 02 Aug 2021 at 11:49:28 (+0200), Fuad Tabba wrote:
> On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
> >
> > Much of the stage-2 manipulation logic relies on being able to destroy
> > block mappings if e.g. installing a smaller mapping in the range. The
> > rationale for this behaviour is that stage-2 mappings can always be
> > re-created lazily. However, this gets more complicated when the stage-2
> > page-table is used to store metadata about the underlying pages. In such
> > cases, destroying a block mapping may lead to losing part of the state,
> > and confuse the user of those metadata (such as the hypervisor in nVHE
> > protected mode).
> >
> > To avoid this, introduce a callback function in the pgtable struct which
> > is called during all map operations to determine whether the mappings
> > can use blocks, or should be forced to page granularity. This is used by
> > the hypervisor when creating the host stage-2 to force page-level
> > mappings when using non-default protection attributes.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_pgtable.h  | 65 ++++++++++++++++-----------
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 30 +++++++++++--
> >  arch/arm64/kvm/hyp/pgtable.c          | 29 +++++++++---
> >  3 files changed, 91 insertions(+), 33 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> > index 83c5c97d9eac..ba7dcade2798 100644
> > --- a/arch/arm64/include/asm/kvm_pgtable.h
> > +++ b/arch/arm64/include/asm/kvm_pgtable.h
> > @@ -115,25 +115,6 @@ enum kvm_pgtable_stage2_flags {
> >         KVM_PGTABLE_S2_IDMAP                    = BIT(1),
> >  };
> >
> > -/**
> > - * struct kvm_pgtable - KVM page-table.
> > - * @ia_bits:           Maximum input address size, in bits.
> > - * @start_level:       Level at which the page-table walk starts.
> > - * @pgd:               Pointer to the first top-level entry of the page-table.
> > - * @mm_ops:            Memory management callbacks.
> > - * @mmu:               Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
> > - */
> > -struct kvm_pgtable {
> > -       u32                                     ia_bits;
> > -       u32                                     start_level;
> > -       kvm_pte_t                               *pgd;
> > -       struct kvm_pgtable_mm_ops               *mm_ops;
> > -
> > -       /* Stage-2 only */
> > -       struct kvm_s2_mmu                       *mmu;
> > -       enum kvm_pgtable_stage2_flags           flags;
> > -};
> > -
> >  /**
> >   * enum kvm_pgtable_prot - Page-table permissions and attributes.
> >   * @KVM_PGTABLE_PROT_X:                Execute permission.
> > @@ -149,11 +130,41 @@ enum kvm_pgtable_prot {
> >         KVM_PGTABLE_PROT_DEVICE                 = BIT(3),
> >  };
> >
> > -#define PAGE_HYP               (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
> > +#define KVM_PGTABLE_PROT_RW    (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
> > +#define KVM_PGTABLE_PROT_RWX   (KVM_PGTABLE_PROT_RW | KVM_PGTABLE_PROT_X)
> > +
> > +#define PAGE_HYP               KVM_PGTABLE_PROT_RW
> >  #define PAGE_HYP_EXEC          (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X)
> >  #define PAGE_HYP_RO            (KVM_PGTABLE_PROT_R)
> >  #define PAGE_HYP_DEVICE                (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE)
> 
> I wonder if it would be useful to add a couple of other aliases for
> default memory and default mmio protections, e.g.,
> 
> #define  KVM_PGTABLE_PROT_MEM KVM_PGTABLE_PROT_RWX
> #define  KVM_PGTABLE_PROT_MMIO KVM_PGTABLE_PROT_RW
> 
> I think that using these below, e.g., host_stage2_force_pte_cb(),
> might make it clearer and answer comments you had in earlier patches
> about why "RWX" for memory.

Sure I can add something. I'll probably call them something else than
KVM_PGTABLE_PROT_{MEM,MMIO} though, just to make it clear this is all
specific to the host stage-2 stuff and not a general requirement of the
pgtable code to map things like this.

> >
> > +typedef bool (*kvm_pgtable_force_pte_cb_t)(u64 addr, u64 end,
> > +                                          enum kvm_pgtable_prot prot);
> > +
> > +/**
> > + * struct kvm_pgtable - KVM page-table.
> > + * @ia_bits:           Maximum input address size, in bits.
> > + * @start_level:       Level at which the page-table walk starts.
> > + * @pgd:               Pointer to the first top-level entry of the page-table.
> > + * @mm_ops:            Memory management callbacks.
> > + * @mmu:               Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
> > + * @flags:             Stage-2 page-table flags.
> > + * @force_pte_cb:      Callback function used during map operations to decide
> > + *                     whether block mappings can be used to map the given IPA
> > + *                     range.
> > + */
> 
> nit: I think it might be clearer (and probably not longer) to rephrase
> to describe in terms of the return value of the callback, e.g., "...
> function that returns true if page level mappings must be used instead
> of block mappings."

Works for me, thanks for the suggestion.

> > +struct kvm_pgtable {
> > +       u32                                     ia_bits;
> > +       u32                                     start_level;
> > +       kvm_pte_t                               *pgd;
> > +       struct kvm_pgtable_mm_ops               *mm_ops;
> > +
> > +       /* Stage-2 only */
> > +       struct kvm_s2_mmu                       *mmu;
> > +       enum kvm_pgtable_stage2_flags           flags;
> > +       kvm_pgtable_force_pte_cb_t              force_pte_cb;
> > +};
> > +
> >  /**
> >   * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk.
> >   * @KVM_PGTABLE_WALK_LEAF:             Visit leaf entries, including invalid
> > @@ -246,21 +257,25 @@ int kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
> >  u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift);
> >
> >  /**
> > - * kvm_pgtable_stage2_init_flags() - Initialise a guest stage-2 page-table.
> > + * __kvm_pgtable_stage2_init() - Initialise a guest stage-2 page-table.
> >   * @pgt:       Uninitialised page-table structure to initialise.
> >   * @arch:      Arch-specific KVM structure representing the guest virtual
> >   *             machine.
> >   * @mm_ops:    Memory management callbacks.
> >   * @flags:     Stage-2 configuration flags.
> > + * @force_pte_cb: Callback function used during map operations to decide
> > + *             whether block mappings can be used to map the given IPA
> > + *             range.
> 
> nit: same nit as above with describing the callback in terms of its return value
> 
> >   *
> >   * Return: 0 on success, negative error code on failure.
> >   */
> > -int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> > -                                 struct kvm_pgtable_mm_ops *mm_ops,
> > -                                 enum kvm_pgtable_stage2_flags flags);
> > +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> > +                             struct kvm_pgtable_mm_ops *mm_ops,
> > +                             enum kvm_pgtable_stage2_flags flags,
> > +                             kvm_pgtable_force_pte_cb_t force_pte_cb);
> >
> >  #define kvm_pgtable_stage2_init(pgt, arch, mm_ops) \
> > -       kvm_pgtable_stage2_init_flags(pgt, arch, mm_ops, 0)
> > +       __kvm_pgtable_stage2_init(pgt, arch, mm_ops, 0, NULL)
> >
> >  /**
> >   * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index 2148d3968aa5..70c57d2c3024 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -89,6 +89,7 @@ static void prepare_host_vtcr(void)
> >                                           id_aa64mmfr1_el1_sys_val, phys_shift);
> >  }
> >
> > +static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot);
> 
> nit: newline
> 
> >  int kvm_host_prepare_stage2(void *pgt_pool_base)
> >  {
> >         struct kvm_s2_mmu *mmu = &host_kvm.arch.mmu;
> > @@ -101,8 +102,9 @@ int kvm_host_prepare_stage2(void *pgt_pool_base)
> >         if (ret)
> >                 return ret;
> >
> > -       ret = kvm_pgtable_stage2_init_flags(&host_kvm.pgt, &host_kvm.arch,
> > -                                           &host_kvm.mm_ops, KVM_HOST_S2_FLAGS);
> > +       ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, &host_kvm.arch,
> > +                                       &host_kvm.mm_ops, KVM_HOST_S2_FLAGS,
> > +                                       host_stage2_force_pte_cb);
> >         if (ret)
> >                 return ret;
> >
> > @@ -270,9 +272,31 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
> >         return 0;
> >  }
> >
> > +static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
> > +{
> > +       /*
> > +        * Block mappings must be used with care in the host stage-2 as a
> > +        * kvm_pgtable_stage2_map() operation targeting a page in the range of
> > +        * an existing block will delete the block under the assumption that
> > +        * mappings in the rest of the block range can always be rebuilt lazily.
> > +        * That assumption is correct for the host stage-2 with RWX mappings
> > +        * targeting memory or RW mappings targeting MMIO ranges (see
> > +        * host_stage2_idmap() below which implements some of the host memory
> > +        * abort logic). However, this is not safe for any other mappings where
> > +        * the host stage-2 page-table is in fact the only place where this
> > +        * state is stored. In all those cases, it is safer to use page-level
> > +        * mappings, hence avoiding to lose the state because of side-effects in
> > +        * kvm_pgtable_stage2_map().
> > +        */
> > +       if (range_is_memory(addr, end))
> > +               return prot != KVM_PGTABLE_PROT_RWX;
> > +       else
> > +               return prot != KVM_PGTABLE_PROT_RW;
> > +}
> 
> Just checking, I don't think that it's possible for the range to be
> big enough to somehow include both memory and mmio, neither now nor in
> future use cases, is it?

That really shouldn't be the case no -- the host_stage2_idmap() function
tries hard to respect that, so I figured as long as these two are
consistent we should be fine.

> > +
> >  static int host_stage2_idmap(u64 addr)
> >  {
> > -       enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
> > +       enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_RW;
> >         struct kvm_mem_range range;
> >         bool is_memory = find_mem_range(addr, &range);
> >         int ret;
> > diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> > index 2689fcb7901d..bcc02e6e0f62 100644
> > --- a/arch/arm64/kvm/hyp/pgtable.c
> > +++ b/arch/arm64/kvm/hyp/pgtable.c
> > @@ -452,6 +452,8 @@ int kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits,
> >         pgt->start_level        = KVM_PGTABLE_MAX_LEVELS - levels;
> >         pgt->mm_ops             = mm_ops;
> >         pgt->mmu                = NULL;
> > +       pgt->force_pte_cb       = NULL;
> > +
> >         return 0;
> >  }
> >
> > @@ -489,6 +491,9 @@ struct stage2_map_data {
> >         void                            *memcache;
> >
> >         struct kvm_pgtable_mm_ops       *mm_ops;
> > +
> > +       /* Force mappings to page granularity */
> > +       bool                            force_pte;
> >  };
> >
> >  u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
> > @@ -602,6 +607,15 @@ static bool stage2_pte_executable(kvm_pte_t pte)
> >         return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN);
> >  }
> >
> > +static bool stage2_block_mapping_allowed(u64 addr, u64 end, u32 level,
> > +                                        struct stage2_map_data *data)
> > +{
> > +       if (data->force_pte && (level < (KVM_PGTABLE_MAX_LEVELS - 1)))
> > +               return false;
> 
> I'm not sure I understand why checking the level is necessary. Can
> there be block mapping at the last possible level?

That's probably just a matter of naming, but this function is in fact
called at every level, just like kvm_block_mapping_supported() was
before. And we rely on it returning true at the last level, so I need to
do that check here.

Maybe renaming this stage2_leaf_mapping_allowed() would clarify?

Thanks,
Quentin


From romain.perier at gmail.com  Tue Aug  3 03:13:24 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Tue, 3 Aug 2021 12:13:24 +0200
Subject: [PATCH 05/10] ARM: dts: mstar: Set gpio compatible for ssd20xd
In-Reply-To: <CACRpkdaEMeYieH=g+3jveWgPS_8CXSgC-iryzbsoZp7LLrkzKA@mail.gmail.com>
References: <20210717045627.1739959-1-daniel@0x0f.com>
 <20210717045627.1739959-6-daniel@0x0f.com>
 <CACRpkdaEMeYieH=g+3jveWgPS_8CXSgC-iryzbsoZp7LLrkzKA@mail.gmail.com>
Message-ID: <CABgxDo+BrfwahXW7eui1J5tLhQSx8=TB7o6TATLLS4G+HtxYXA@mail.gmail.com>

Le ven. 30 juil. 2021 ? 12:11, Linus Walleij
<linus.walleij at linaro.org> a ?crit :
>
> On Sat, Jul 17, 2021 at 6:56 AM Daniel Palmer <daniel at 0x0f.com> wrote:
>
> > Now there is gpio support for ssd20xd set the right compatible in the gpio node.
> >
> > Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Romain Perier <romain.perier at gmail.com>

Regards,
Romain


From lorenzo.pieralisi at arm.com  Tue Aug  3 03:14:54 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue, 3 Aug 2021 11:14:54 +0100
Subject: [PATCH v2 3/6] PCI: j721e: Add PCIe support for J7200
In-Reply-To: <20210803074932.19820-4-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
 <20210803074932.19820-4-kishon@ti.com>
Message-ID: <20210803101454.GC11252@lpieralisi>

On Tue, Aug 03, 2021 at 01:19:29PM +0530, Kishon Vijay Abraham I wrote:
> J7200 has the same PCIe IP as in J721E with minor changes in the
> wrapper. J7200 allows byte access of bridge configuration space
> registers and the register field for LINK_DOWN interrupt is different.
> J7200 also requires "quirk_detect_quiet_flag" to be set. Configure these
> changes as part of driver data applicable only to J7200.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  drivers/pci/controller/cadence/pci-j721e.c | 40 +++++++++++++++++++---
>  1 file changed, 36 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
> index 0c5813b230b4..8e76f2e7e782 100644
> --- a/drivers/pci/controller/cadence/pci-j721e.c
> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> @@ -27,6 +27,7 @@
>  #define STATUS_REG_SYS_2	0x508
>  #define STATUS_CLR_REG_SYS_2	0x708
>  #define LINK_DOWN		BIT(1)
> +#define J7200_LINK_DOWN		BIT(10)
>  
>  #define J721E_PCIE_USER_CMD_STATUS	0x4
>  #define LINK_TRAINING_ENABLE		BIT(0)
> @@ -57,6 +58,7 @@ struct j721e_pcie {
>  	struct cdns_pcie	*cdns_pcie;
>  	void __iomem		*user_cfg_base;
>  	void __iomem		*intd_cfg_base;
> +	u32			linkdown_irq_regfield;
>  };
>  
>  enum j721e_pcie_mode {
> @@ -67,6 +69,9 @@ enum j721e_pcie_mode {
>  struct j721e_pcie_data {
>  	enum j721e_pcie_mode	mode;
>  	unsigned int		quirk_retrain_flag:1;
> +	unsigned int		quirk_detect_quiet_flag:1;
> +	u32			linkdown_irq_regfield;
> +	unsigned int		byte_access_allowed:1;
>  };
>  
>  static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
> @@ -98,12 +103,12 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
>  	u32 reg;
>  
>  	reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
> -	if (!(reg & LINK_DOWN))
> +	if (!(reg & pcie->linkdown_irq_regfield))
>  		return IRQ_NONE;
>  
>  	dev_err(dev, "LINK DOWN!\n");
>  
> -	j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN);
> +	j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, pcie->linkdown_irq_regfield);
>  	return IRQ_HANDLED;
>  }
>  
> @@ -112,7 +117,7 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
>  	u32 reg;
>  
>  	reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2);
> -	reg |= LINK_DOWN;
> +	reg |= pcie->linkdown_irq_regfield;
>  	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
>  }
>  
> @@ -284,10 +289,25 @@ static struct pci_ops cdns_ti_pcie_host_ops = {
>  static const struct j721e_pcie_data j721e_pcie_rc_data = {
>  	.mode = PCI_MODE_RC,
>  	.quirk_retrain_flag = true,
> +	.byte_access_allowed = false,
> +	.linkdown_irq_regfield = LINK_DOWN,
>  };
>  
>  static const struct j721e_pcie_data j721e_pcie_ep_data = {
>  	.mode = PCI_MODE_EP,
> +	.linkdown_irq_regfield = LINK_DOWN,
> +};
> +
> +static const struct j721e_pcie_data j7200_pcie_rc_data = {
> +	.mode = PCI_MODE_RC,
> +	.quirk_detect_quiet_flag = true,
> +	.linkdown_irq_regfield = J7200_LINK_DOWN,
> +	.byte_access_allowed = true,
> +};
> +
> +static const struct j721e_pcie_data j7200_pcie_ep_data = {
> +	.mode = PCI_MODE_EP,
> +	.quirk_detect_quiet_flag = true,
>  };
>  
>  static const struct of_device_id of_j721e_pcie_match[] = {
> @@ -299,6 +319,14 @@ static const struct of_device_id of_j721e_pcie_match[] = {
>  		.compatible = "ti,j721e-pcie-ep",
>  		.data = &j721e_pcie_ep_data,
>  	},
> +	{
> +		.compatible = "ti,j7200-pcie-host",
> +		.data = &j7200_pcie_rc_data,
> +	},
> +	{
> +		.compatible = "ti,j7200-pcie-ep",
> +		.data = &j7200_pcie_ep_data,
> +	},
>  	{},
>  };
>  
> @@ -332,6 +360,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
>  
>  	pcie->dev = dev;
>  	pcie->mode = mode;
> +	pcie->linkdown_irq_regfield =  data->linkdown_irq_regfield;
                                     ^
Nit: too many spaces

>  	base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg");
>  	if (IS_ERR(base))
> @@ -391,9 +420,11 @@ static int j721e_pcie_probe(struct platform_device *pdev)
>  			goto err_get_sync;
>  		}
>  
> -		bridge->ops = &cdns_ti_pcie_host_ops;
> +		if (!data->byte_access_allowed)
> +			bridge->ops = &cdns_ti_pcie_host_ops;
>  		rc = pci_host_bridge_priv(bridge);
>  		rc->quirk_retrain_flag = data->quirk_retrain_flag;
> +		rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
>  
>  		cdns_pcie = &rc->pcie;
>  		cdns_pcie->dev = dev;
> @@ -459,6 +490,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
>  			ret = -ENOMEM;
>  			goto err_get_sync;
>  		}
> +		ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
>  
>  		cdns_pcie = &ep->pcie;
>  		cdns_pcie->dev = dev;
> -- 
> 2.17.1
> 


From grygorii.strashko at ti.com  Tue Aug  3 03:17:23 2021
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Tue, 3 Aug 2021 13:17:23 +0300
Subject: [PATCH] dt-bindings: soc: ti: pruss: Add dma-coherent property
In-Reply-To: <20210730031901.26243-1-s-anna@ti.com>
References: <20210730031901.26243-1-s-anna@ti.com>
Message-ID: <60d2172e-92cc-85b4-f0d1-c64724e5a42f@ti.com>



On 30/07/2021 06:19, Suman Anna wrote:
> Update the PRUSS schema file to include the dma-coherent property
> that indicates the coherency of the IP. The PRUSS IPs on 66AK2G
> SoCs do use this property.
> 
> Signed-off-by: Suman Anna <s-anna at ti.com>
> ---
> Hi Santosh,
> 
> This patch updates the PRUSS binding in preparation for adding the
> PRUSS nodes for 66AK2G SoCs. Without this, the dtbs_check would
> complain about the undefined dma-coherent property. Patch is top
> of the AM64 ICSSG binding update patch [1].
> 
> regards
> Suman
> 
> [1] https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210623165032.31223-2-s-anna at ti.com/
> 
>   .../devicetree/bindings/soc/ti/ti,pruss.yaml  | 37 +++++++++++++------
>   1 file changed, 25 insertions(+), 12 deletions(-)
> 
Reviewed-by: Grygorii Strashko <grygorii.strashko at ti.com>

-- 
Best regards,
grygorii


From qperret at google.com  Tue Aug  3 03:20:00 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 3 Aug 2021 11:20:00 +0100
Subject: [PATCH v3 13/21] KVM: arm64: Expose host stage-2 manipulation
 helpers
In-Reply-To: <CA+EHjTxTaPc=bt_kyXf0TE85v5eyHnq0o3KQ3Pd6+kOwmm5oMw@mail.gmail.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-14-qperret@google.com>
 <CA+EHjTxTaPc=bt_kyXf0TE85v5eyHnq0o3KQ3Pd6+kOwmm5oMw@mail.gmail.com>
Message-ID: <YQkYUOaXx7+/EQP/@google.com>

On Monday 02 Aug 2021 at 13:13:20 (+0200), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
> >
> > We will need to manipulate the host stage-2 page-table from outside
> > mem_protect.c soon. Introduce two functions allowing this, and make
> > them usable to users of mem_protect.h.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 ++
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 17 ++++++++++++++++-
> >  2 files changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index ae355bfd8c01..47c2a0c51612 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -49,6 +49,8 @@ extern struct host_kvm host_kvm;
> >  int __pkvm_prot_finalize(void);
> >  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
> >
> > +int host_stage2_idmap_locked(u64 start, u64 end, enum kvm_pgtable_prot prot);
> > +int host_stage2_set_owner_locked(u64 start, u64 end, u8 owner_id);
> >  int kvm_host_prepare_stage2(void *pgt_pool_base);
> >  void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index 70c57d2c3024..a7f6134789e0 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -272,6 +272,21 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
> >         return 0;
> >  }
> >
> > +int host_stage2_idmap_locked(u64 start, u64 end, enum kvm_pgtable_prot prot)
> > +{
> > +       hyp_assert_lock_held(&host_kvm.lock);
> > +
> > +       return host_stage2_try(__host_stage2_idmap, start, end, prot);
> > +}
> > +
> > +int host_stage2_set_owner_locked(u64 start, u64 end, u8 owner_id)
> > +{
> > +       hyp_assert_lock_held(&host_kvm.lock);
> > +
> > +       return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
> > +                              start, end - start, &host_s2_pool, owner_id);
> > +}
> 
> This is a potential issue elsewhere as well, but all functions in
> kvm_pgtable.h, including kvm_pgtable_stage2_set_owner, specify an
> address range via address and size. The two you have introduced here
> take a start and an end. I'm not sure if making these two consistent
> with the ones in kvm_pgtable.h would be good, or would just complicate
> things in other places.

Good point, and it looks like specifying these two with start-size
parameters would simplify the callers a tiny bit as well, so I'll fold
that in v4.

Thanks,
Quentin


From qperret at google.com  Tue Aug  3 03:23:47 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 3 Aug 2021 11:23:47 +0100
Subject: [PATCH v3 15/21] KVM: arm64: Introduce addr_is_memory()
In-Reply-To: <CA+EHjTxrdA3wVsBe7zwvvGUGgoWuaGwuWCBL0k2+FcAdTGB=Qw@mail.gmail.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-16-qperret@google.com>
 <CA+EHjTxrdA3wVsBe7zwvvGUGgoWuaGwuWCBL0k2+FcAdTGB=Qw@mail.gmail.com>
Message-ID: <YQkZMyyqgqb8+Uqq@google.com>

On Monday 02 Aug 2021 at 16:52:31 (+0200), Fuad Tabba wrote:
> Hi Quentin.
> 
> On Thu, Jul 29, 2021 at 3:28 PM Quentin Perret <qperret at google.com> wrote:
> >
> > Introduce a helper usable in nVHE protected mode to check whether a
> > physical address is in a RAM region or not.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 +
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 7 +++++++
> >  2 files changed, 8 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index cc86598654b9..5968fbbb3514 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -51,6 +51,7 @@ extern const u8 pkvm_hyp_id;
> >  int __pkvm_prot_finalize(void);
> >  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
> >
> > +bool addr_is_memory(phys_addr_t phys);
> 
> I'm just wondering about the naming of the function. I understand what
> you're trying to achieve with it, but an address without a unit that
> conveys size or type seems to be missing something. Would

Well it does have a type no? I was hopping this would make it clear what
it actually does.

> memregion_addr_is_memory or something like that be a better
> description, since it is what find_mem_range finds?

I think the callers shouldn't need to care about the implementation
details though. This just replies to the question 'is this physical
address in RAM range or not?'. And I could actually imagine that we
would change the implementation some day to avoid the binary search, but
the users probably don't need to care.

Thanks,
Quentin


From qperret at google.com  Tue Aug  3 03:24:14 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 3 Aug 2021 11:24:14 +0100
Subject: [PATCH v3 16/21] KVM: arm64: Enable retrieving protections
 attributes of PTEs
In-Reply-To: <CA+EHjTwL+grX__03SfeDdxeppjSovEZhKRvqjmA_4kSBwsjswg@mail.gmail.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-17-qperret@google.com>
 <CA+EHjTwL+grX__03SfeDdxeppjSovEZhKRvqjmA_4kSBwsjswg@mail.gmail.com>
Message-ID: <YQkZTnVLwVYDFvoA@google.com>

On Monday 02 Aug 2021 at 16:52:49 (+0200), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Thu, Jul 29, 2021 at 3:29 PM Quentin Perret <qperret at google.com> wrote:
> >
> > Introduce helper functions in the KVM stage-2 and stage-1 page-table
> > manipulation library allowing to retrieve the enum kvm_pgtable_prot of a
> > PTE. This will be useful to implement custom walkers outside of
> > pgtable.c.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_pgtable.h | 20 +++++++++++++++
> >  arch/arm64/kvm/hyp/pgtable.c         | 37 ++++++++++++++++++++++++++++
> >  2 files changed, 57 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> > index d5ca9b6ce241..7ff9f52239ba 100644
> > --- a/arch/arm64/include/asm/kvm_pgtable.h
> > +++ b/arch/arm64/include/asm/kvm_pgtable.h
> > @@ -505,4 +505,24 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
> >   */
> >  int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
> >                          kvm_pte_t *ptep, u32 *level);
> > +
> > +/**
> > + * kvm_pgtable_stage2_pte_prot() - Retrieve the protection attributes of a
> > + *                                stage-2 Page-Table Entry.
> > + * @pte:       Page-table entry
> > + *
> > + * Return: protection attributes of the page-table entry in the enum
> > + *        kvm_pgtable_prot format.
> > + */
> > +enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte);
> > +
> > +/**
> > + * kvm_pgtable_hyp_pte_prot() - Retrieve the protection attributes of a stage-1
> > + *                             Page-Table Entry.
> > + * @pte:       Page-table entry
> > + *
> > + * Return: protection attributes of the page-table entry in the enum
> > + *        kvm_pgtable_prot format.
> > + */
> > +enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte);
> >  #endif /* __ARM64_KVM_PGTABLE_H__ */
> > diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> > index 1915489bb127..a6eda8f23cb6 100644
> > --- a/arch/arm64/kvm/hyp/pgtable.c
> > +++ b/arch/arm64/kvm/hyp/pgtable.c
> > @@ -363,6 +363,26 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
> >         return 0;
> >  }
> >
> > +enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte)
> > +{
> > +       enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW;
> > +       u32 ap;
> > +
> > +       if (!kvm_pte_valid(pte))
> > +               return prot;
> > +
> > +       if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN))
> > +               prot |= KVM_PGTABLE_PROT_X;
> > +
> > +       ap = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_AP, pte);
> > +       if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RO)
> > +               prot |= KVM_PGTABLE_PROT_R;
> > +       else if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RW)
> > +               prot |= KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
> 
> nit: why not use the freshly minted KVM_PGTABLE_PROT_RW?

No good reason, I'll fix that up, thanks!


From anshuman.khandual at arm.com  Tue Aug  3 03:25:22 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 3 Aug 2021 15:55:22 +0530
Subject: [PATCH 08/10] coresight: trbe: Workaround TRBE errat overwrite in
 FILL mode
In-Reply-To: <20210728135217.591173-9-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-9-suzuki.poulose@arm.com>
Message-ID: <7edeb6de-5de6-e9b1-c684-a7f5782d9a7b@arm.com>



On 7/28/21 7:22 PM, Suzuki K Poulose wrote:
> ARM Neoverse-N2 (#2139208) and Cortex-A710(##2119858) suffers from
> an erratum, which when triggered, might cause the TRBE to overwrite
> the trace data already collected in FILL mode, in the event of a WRAP.
> i.e, the TRBE doesn't stop writing the data, instead wraps to the base
> and could write upto 3 cache line size worth trace. Thus, this could
> corrupt the trace at the "BASE" pointer.
> 
> The workaround is to program the write pointer 256bytes from the
> base, such that if the erratum is triggered, it doesn't overwrite
> the trace data that was captured. This skipped region could be
> padded with ignore packets at the end of the session, so that
> the decoder sees a continuous buffer with some padding at the
> beginning. The trace data written at the base is considered
> lost as the limit could have been in the middle of the perf
> ring buffer, and jumping to the "base" is not acceptable.

If the write pointer is guaranteed to have always started beyond
[base + 256] and then wraps around. Why cannot the initial trace
at [base .. base + 256] not to be considered for perf ?

> We set the flags already to indicate that some amount of trace
> was lost during the FILL event IRQ. So this is fine.

Right, from perf data flag point of view it is not a problem.
But I am still wondering why cannot the trace at the base can
not be consumed by perf.

> 
> One important change with the work around is, we program the
> TRBBASER_EL1 to current page where we are allowed to write.
> Otherwise, it could overwrite a region that may be consumed
> by the perf. Towards this, we always make sure that the

While enabling TRBE after required reconfiguration, this will
cause both TRBBASER_EL1 and TRBPTR_EL1 to change each time
around (basically TRBBASER_EL1 follows handle->head) ?

> "handle->head" and thus the trbe_write is PAGE_SIZE aligned,
> so that we can set the BASE to the PAGE base and move the
> TRBPTR to the 256bytes offset.

Now that base needs to follow handle->head, both needs to be
PAGE_SIZE aligned (including the write pointer) because base
pointer needs to be PAGE_SIZE aligned ?

> 
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-trbe.c | 111 +++++++++++++++++--
>  1 file changed, 102 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 9ea28813182b..cd997ed5d918 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -17,6 +17,7 @@
>  
>  #include <asm/barrier.h>
>  #include <asm/cputype.h>
> +#include <asm/cpufeature.h>
>  
>  #include "coresight-self-hosted-trace.h"
>  #include "coresight-trbe.h"
> @@ -84,9 +85,17 @@ struct trbe_buf {
>   * per TRBE instance, we keep track of the list of errata that
>   * affects the given instance of the TRBE.
>   */
> -#define TRBE_ERRATA_MAX			0
> +#define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
> +#define TRBE_ERRATA_MAX				1

Although I am not sure how to achieve it, TRBE_ERRATA_MAX should be
derived from errata cpucap start and end markers which identify all
TRBE specific erratas. The hard coding above could be avoided.

> +
> +/*
> + * Safe limit for the number of bytes that may be overwritten
> + * when the erratum is triggered.

Specify which errata ?

> + */
> +#define TRBE_WORKAROUND_OVERWRITE_FILL_MODE_SKIP	256

Needs to have _BYTES. TRBE_ERRATA_OVERWRITE_FILL_MODE_SKIP_BYTES ?

>  
>  static unsigned long trbe_errata_cpucaps[TRBE_ERRATA_MAX] = {
> +	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,

s/TRBE_WORKAROUND_OVERWRITE_FILL_MODE/TRBE_ERRATA_OVERWRITE_FILL_MODE instead ?

ARM64_WORKAROUND_TRBE_XXX -----> TRBE_ERRATA_XXX

>  };
>  
>  /*
> @@ -531,10 +540,13 @@ static enum trbe_fault_action trbe_get_fault_act(u64 trbsr)
>  	if ((ec == TRBE_EC_STAGE1_ABORT) || (ec == TRBE_EC_STAGE2_ABORT))
>  		return TRBE_FAULT_ACT_FATAL;
>  
> -	if (is_trbe_wrap(trbsr) && (ec == TRBE_EC_OTHERS) && (bsc == TRBE_BSC_FILLED)) {
> -		if (get_trbe_write_pointer() == get_trbe_base_pointer())
> -			return TRBE_FAULT_ACT_WRAP;
> -	}
> +	/*
> +	 * It is not necessary to verify the TRBPTR == TRBBASER to detect
> +	 * a FILL event. Moreover, CPU errata could make this check invalid.
> +	 */

Why should the check be dropped for CPU instances which dont have the errata ?

> +	if (is_trbe_wrap(trbsr) && (ec == TRBE_EC_OTHERS) && (bsc == TRBE_BSC_FILLED))
> +		return TRBE_FAULT_ACT_WRAP;
> +
>  	return TRBE_FAULT_ACT_SPURIOUS;
>  }
>  
> @@ -544,6 +556,7 @@ static unsigned long trbe_get_trace_size(struct perf_output_handle *handle,
>  {
>  	u64 write;
>  	u64 start_off, end_off;
> +	u64 size;
>  
>  	/*
>  	 * If the TRBE has wrapped around the write pointer has
> @@ -559,7 +572,18 @@ static unsigned long trbe_get_trace_size(struct perf_output_handle *handle,
>  
>  	if (WARN_ON_ONCE(end_off < start_off))
>  		return 0;
> -	return (end_off - start_off);
> +
> +	size = end_off - start_off;
> +	/*
> +	 * If the TRBE is affected by the following erratum, we must fill
> +	 * the space we skipped with IGNORE packets. And we are always
> +	 * guaranteed to have at least a PAGE_SIZE space in the buffer.
> +	 */
> +	if (trbe_has_erratum(TRBE_WORKAROUND_OVERWRITE_FILL_MODE, buf->cpudata) &&
> +	    !WARN_ON(size < TRBE_WORKAROUND_OVERWRITE_FILL_MODE_SKIP))

Why warn here ? The skid can some times be less than 256 bytes. OR because
now write pointer alignment is PAGE_SIZE (from later code), size too needs
to be always a PAGE_SIZE multiple ?

> +		__trbe_pad_buf(buf, start_off, TRBE_WORKAROUND_OVERWRITE_FILL_MODE_SKIP);
> +
> +	return size;
>  }
>  
>  static void *arm_trbe_alloc_buffer(struct coresight_device *csdev,
> @@ -704,20 +728,73 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
>  	return size;
>  }
>  
> +
> +static int trbe_apply_work_around_before_enable(struct trbe_buf *buf)
> +{
> +	/*
> +	 * TRBE_WORKAROUND_OVERWRITE_FILL_MODE causes the TRBE to overwrite a few cache
> +	 * line size from the "TRBBASER_EL1" in the event of a "FILL".
> +	 * Thus, we could loose some amount of the trace at the base.
> +	 *
> +	 * To work around this:
> +	 * - Software must leave 256bytes of space from the base, so that
> +	 *   the trace collected now is not overwritten.
> +	 * - Fill the first 256bytes with IGNORE packets for the decoder
> +	 *   to ignore at the end of the session, so that the decoder ignores
> +	 *   this gap.
> +	 *
> +	 * This also means that, the TRBE driver must set the TRBBASER_EL1
> +	 * such that, when the erratum is triggered, it doesn't overwrite
> +	 * the "area" outside the area marked by (handle->head, +size).
> +	 * So, we make sure that the handle->head is always PAGE aligned,
> +	 * by tweaking the required alignment for the TRBE (trbe_align).
> +	 * And when we enable the TRBE,
> +	 *
> +	 *   - move the TRBPTR_EL1 to 256bytes past the starting point.
> +	 *     So that any trace collected in this run is not overwritten.
> +	 *
> +	 *   - set the TRBBASER_EL1 to the original trbe_write. This will
> +	 *     ensure that, if the TRBE hits the erratum, it would only
> +	 *     write within the region allowed for the TRBE.
> +	 *
> +	 * At the trace collection time, we always pad the skipped bytes
> +	 * with IGNORE packets to make sure the decoder doesn't see any
> +	 * overwritten packets.
> +	 */
> +	if (trbe_has_erratum(TRBE_WORKAROUND_OVERWRITE_FILL_MODE, buf->cpudata)) {
> +		if (WARN_ON(!IS_ALIGNED(buf->trbe_write, PAGE_SIZE)))
> +			return -EINVAL;
> +		buf->trbe_hw_base = buf->trbe_write;
> +		buf->trbe_write += TRBE_WORKAROUND_OVERWRITE_FILL_MODE_SKIP;

Not sure if I really understood this correctly, but would not the
above keep on reducing the usable buffer space for TRBE each time
around ? BTW buffer adjustment complexity here requires a proper
ASCII diagram based illustration like before.

> +	}
> +
> +	return 0;
> +}
> +
>  static int __arm_trbe_enable(struct trbe_buf *buf,
>  			     struct perf_output_handle *handle)
>  {
> +	int ret = 0;
> +
>  	buf->trbe_limit = compute_trbe_buffer_limit(handle);
>  	buf->trbe_write = buf->trbe_base + PERF_IDX2OFF(handle->head, buf);
>  	if (buf->trbe_limit == buf->trbe_base) {
> -		trbe_stop_and_truncate_event(handle);
> -		return -ENOSPC;
> +		ret = -ENOSPC;
> +		goto err;
>  	}
>  	/* Set the base of the TRBE to the buffer base */
>  	buf->trbe_hw_base = buf->trbe_base;
> +
> +	ret = trbe_apply_work_around_before_enable(buf);
> +	if (ret)
> +		goto err;
> +
>  	*this_cpu_ptr(buf->cpudata->drvdata->handle) = handle;
>  	trbe_enable_hw(buf);
>  	return 0;
> +err:
> +	trbe_stop_and_truncate_event(handle);
> +	return ret;
>  }
>  
>  static int arm_trbe_enable(struct coresight_device *csdev, u32 mode, void *data)
> @@ -1003,7 +1080,23 @@ static void arm_trbe_probe_cpu(void *info)
>  		pr_err("Unsupported alignment on cpu %d\n", cpu);
>  		goto cpu_clear;
>  	}
> -	cpudata->trbe_align = cpudata->trbe_hw_align;
> +
> +	/*
> +	 * If the TRBE is affected by erratum TRBE_WORKAROUND_OVERWRITE_FILL_MODE,

Better to address it with the original errata name i.e
ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE instead. But not a big issue
though.

> +	 * we must always program the TBRPTR_EL1, 256bytes from a page
> +	 * boundary, with TRBBASER_EL1 set to the page, to prevent
> +	 * TRBE over-writing 256bytes at TRBBASER_EL1 on FILL event.
> +	 *
> +	 * Thus make sure we always align our write pointer to a PAGE_SIZE,
> +	 * which also guarantees that we have at least a PAGE_SIZE space in
> +	 * the buffer (TRBLIMITR is PAGE aligned) and thus we can skip
> +	 * the required bytes at the base.
> +	 */

Should not TRBPTR_EL1 be aligned to 256 bytes instead, as TRBBASER_EL1 is
always at PAGE_SIZE boundary. Hence TRBPTR_EL1 could never be in between
base and [base + 256 bytes]. Why alignment needs to go all the way upto
PAGE_SIZE instead ? OR am I missing something here ?

> +	if (trbe_has_erratum(TRBE_WORKAROUND_OVERWRITE_FILL_MODE, cpudata))
> +		cpudata->trbe_align = PAGE_SIZE;
> +	else
> +		cpudata->trbe_align = cpudata->trbe_hw_align;
> +
>  	cpudata->trbe_flag = get_trbe_flag_update(trbidr);
>  	cpudata->cpu = cpu;
>  	cpudata->drvdata = drvdata;
> 

I will visit this patch again. Not sure if I really understand all this
changes correctly enough.


From eballetbo at gmail.com  Tue Aug  3 03:26:50 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:26:50 +0200
Subject: [PATCH v6 3/9] mtk-mdp: use pm_runtime in MDP component driver
In-Reply-To: <20210802220943.v6.3.I909f5375d930f5d0cc877128e30e2a67078b674c@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.3.I909f5375d930f5d0cc877128e30e2a67078b674c@changeid>
Message-ID: <CAFqH_50CLCXSQ=24MpPMQb5DtC6k3iUaWp5dLrbjfAr-3MBpBQ@mail.gmail.com>

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:14:
>
> Without this change, the MDP components are not fully integrated into
> the runtime power management subsystem, and the MDP driver does not
> work.
>
> For each of the component device drivers to be able to call
> pm_runtime_get/put_sync() a pointer to the component's device struct
> had to be added to struct mtk_mdp_comp, set by mtk_mdp_comp_init().
>
> Note that the dev argument to mtk_mdp_comp_clock_on/off() has been
> removed. Those functions used to be called from the "master" mdp driver
> in mtk_mdp_core.c, but the component's device pointer no longer
> corresponds to the mdp master device pointer, which is not the right
> device to pass to pm_runtime_put/get_sync() which we had to add to get
> the driver to work properly.
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>


> ---
>
> (no changes since v1)
>
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 24 +++++++++++++++----
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  6 +++--
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  7 +++---
>  3 files changed, 27 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 7a0e3acffab9..472c261b01e8 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -12,6 +12,7 @@
>  #include <linux/of_address.h>
>  #include <linux/of_platform.h>
>  #include <soc/mediatek/smi.h>
> +#include <linux/pm_runtime.h>
>
>  #include "mtk_mdp_comp.h"
>  #include "mtk_mdp_core.h"
> @@ -50,14 +51,22 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
>
> -int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
> +int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
>  {
>         int i, err, status;
>
>         if (comp->larb_dev) {
>                 err = mtk_smi_larb_get(comp->larb_dev);
>                 if (err)
> -                       dev_err(dev, "failed to get larb, err %d.\n", err);
> +                       dev_err(comp->dev, "failed to get larb, err %d.\n", err);
> +       }
> +
> +       err = pm_runtime_get_sync(comp->dev);
> +       if (err < 0) {
> +               dev_err(comp->dev,
> +                       "failed to runtime get, err %d.\n",
> +                       err);
> +               return err;
>         }
>
>         for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
> @@ -66,7 +75,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>                 err = clk_prepare_enable(comp->clk[i]);
>                 if (err) {
>                         status = err;
> -                       dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
> +                       dev_err(comp->dev, "failed to enable clock, err %d. i:%d\n", err, i);
>                         goto err_clk_prepare_enable;
>                 }
>         }
> @@ -80,10 +89,12 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>                 clk_disable_unprepare(comp->clk[i]);
>         }
>
> +       pm_runtime_put_sync(comp->dev);
> +
>         return status;
>  }
>
> -void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
> +int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
>  {
>         int i;
>
> @@ -95,6 +106,8 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
>
>         if (comp->larb_dev)
>                 mtk_smi_larb_put(comp->larb_dev);
> +
> +       return pm_runtime_put_sync(comp->dev);
>  }
>
>  static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
> @@ -103,6 +116,7 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
>         struct mtk_mdp_dev *mdp = data;
>
>         mtk_mdp_register_component(mdp, comp);
> +       pm_runtime_enable(dev);
>
>         return 0;
>  }
> @@ -113,6 +127,7 @@ static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
>         struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>         struct mtk_mdp_dev *mdp = data;
>
> +       pm_runtime_disable(dev);
>         mtk_mdp_unregister_component(mdp, comp);
>  }
>
> @@ -132,6 +147,7 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
>                  (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
>
>         INIT_LIST_HEAD(&comp->node);
> +       comp->dev = dev;
>
>         for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
>                 comp->clk[i] = of_clk_get(node, i);
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> index df5fc4c94f90..f2e22e7e7c45 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> @@ -12,17 +12,19 @@
>   * @node:      list node to track sibing MDP components
>   * @clk:       clocks required for component
>   * @larb_dev:  SMI device required for component
> + * @dev:       component's device
>   */
>  struct mtk_mdp_comp {
>         struct list_head        node;
>         struct clk              *clk[2];
> +       struct device           *dev;
>         struct device           *larb_dev;
>  };
>
>  int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
>
> -int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
> -void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
> +int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
> +int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
>
>  extern struct platform_driver mtk_mdp_component_driver;
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index b813a822439a..714154450981 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -58,7 +58,7 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
>         int err;
>
>         list_for_each_entry(comp_node, &mdp->comp_list, node) {
> -               err = mtk_mdp_comp_clock_on(dev, comp_node);
> +               err = mtk_mdp_comp_clock_on(comp_node);
>                 if (err) {
>                         status = err;
>                         goto err_mtk_mdp_comp_clock_on;
> @@ -69,18 +69,17 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
>
>  err_mtk_mdp_comp_clock_on:
>         list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
> -               mtk_mdp_comp_clock_off(dev, comp_node);
> +               mtk_mdp_comp_clock_off(comp_node);
>
>         return status;
>  }
>
>  static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
>  {
> -       struct device *dev = &mdp->pdev->dev;
>         struct mtk_mdp_comp *comp_node;
>
>         list_for_each_entry(comp_node, &mdp->comp_list, node)
> -               mtk_mdp_comp_clock_off(dev, comp_node);
> +               mtk_mdp_comp_clock_off(comp_node);
>  }
>
>  static void mtk_mdp_wdt_worker(struct work_struct *work)
> --
> 2.32.0.554.ge1b32706d8-goog
>
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From eballetbo at gmail.com  Tue Aug  3 03:26:55 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:26:55 +0200
Subject: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components
In-Reply-To: <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
Message-ID: <CAFqH_516sHNQMYf-whxM7V8Cw91J4QsLPo5obU=VNoZNC3Av=Q@mail.gmail.com>

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:13:
>
> Broadly, this patch (1) adds a driver for various MTK MDP components to
> go alongside the main MTK MDP driver, and (2) hooks them all together
> using the component framework.
>
> (1) Up until now, the MTK MDP driver controls 8 devices in the device
> tree on its own. When running tests for the hardware video decoder, we
> found that the iommus and LARBs were not being properly configured. To
> configure them, a driver for each be added to mtk_mdp_comp so that
> mtk_iommu_add_device() can (eventually) be called from dma_configure()
> inside really_probe().
>
> (2) The integration into the component framework allows us to defer the
> registration with the v4l2 subsystem until all the MDP-related devices
> have been probed, so that the relevant device node does not become
> available until initialization of all the components is complete.
>
> Some notes about how the component framework has been integrated:
>
> - The driver for the rdma0 component serves double duty as the "master"
>   (aggregate) driver as well as a component driver. This is a non-ideal
>   compromise until a better solution is developed. This device is
>   differentiated from the rest by checking for a "mediatek,vpu" property
>   in the device node.
>
> - The list of mdp components remains hard-coded as mtk_mdp_comp_dt_ids[]
>   in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
>   mtk_mdp_comp.c. This unfortunate duplication of information is
>   addressed in a following patch in this series.
>
> - The component driver calls component_add() for each device that is
>   probed.
>
> - In mtk_mdp_probe (the "master" device), we scan the device tree for
>   any matching nodes against mtk_mdp_comp_dt_ids, and add component
>   matches for them. The match criteria is a matching device node
>   pointer.
>
> - When the set of components devices that have been probed corresponds
>   with the list that is generated by the "master", the callback to
>   mtk_mdp_master_bind() is made, which then calls the component bind
>   functions.
>
> - Inside mtk_mdp_master_bind(), once all the component bind functions
>   have been called, we can then register our device to the v4l2
>   subsystem.
>
> - The call to pm_runtime_enable() in the master device is called after
>   all the components have been registered by their bind() functions
>   called by mtk_mtp_master_bind(). As a result, the list of components
>   will not change while power management callbacks mtk_mdp_suspend()/
>   resume() are accessing the list of components.
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>



> ---
>
> (no changes since v1)
>
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 143 ++++++++++++--
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  25 +--
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 174 +++++++++++++-----
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   1 +
>  4 files changed, 252 insertions(+), 91 deletions(-)
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 76e295c8d9bc..7a0e3acffab9 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -5,13 +5,50 @@
>   */
>
>  #include <linux/clk.h>
> +#include <linux/component.h>
>  #include <linux/device.h>
>  #include <linux/of.h>
> +#include <linux/module.h>
>  #include <linux/of_address.h>
>  #include <linux/of_platform.h>
>  #include <soc/mediatek/smi.h>
>
>  #include "mtk_mdp_comp.h"
> +#include "mtk_mdp_core.h"
> +
> +/**
> + * enum mtk_mdp_comp_type - the MDP component
> + * @MTK_MDP_RDMA:              Read DMA
> + * @MTK_MDP_RSZ:               Reszer
> + * @MTK_MDP_WDMA:              Write DMA
> + * @MTK_MDP_WROT:              Write DMA with rotation
> + * @MTK_MDP_COMP_TYPE_MAX:     Placeholder for num elems in this enum
> + */
> +enum mtk_mdp_comp_type {
> +       MTK_MDP_RDMA,
> +       MTK_MDP_RSZ,
> +       MTK_MDP_WDMA,
> +       MTK_MDP_WROT,
> +       MTK_MDP_COMP_TYPE_MAX,
> +};
> +
> +static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
> +       {
> +               .compatible = "mediatek,mt8173-mdp-rdma",
> +               .data = (void *)MTK_MDP_RDMA
> +       }, {
> +               .compatible = "mediatek,mt8173-mdp-rsz",
> +               .data = (void *)MTK_MDP_RSZ
> +       }, {
> +               .compatible = "mediatek,mt8173-mdp-wdma",
> +               .data = (void *)MTK_MDP_WDMA
> +       }, {
> +               .compatible = "mediatek,mt8173-mdp-wrot",
> +               .data = (void *)MTK_MDP_WROT
> +       },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
>
>  int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>  {
> @@ -20,9 +57,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>         if (comp->larb_dev) {
>                 err = mtk_smi_larb_get(comp->larb_dev);
>                 if (err)
> -                       dev_err(dev,
> -                               "failed to get larb, err %d. type:%d\n",
> -                               err, comp->type);
> +                       dev_err(dev, "failed to get larb, err %d.\n", err);
>         }
>
>         for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
> @@ -62,17 +97,41 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
>                 mtk_smi_larb_put(comp->larb_dev);
>  }
>
> -int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
> -                     struct mtk_mdp_comp *comp,
> -                     enum mtk_mdp_comp_type comp_type)
> +static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
> +{
> +       struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
> +       struct mtk_mdp_dev *mdp = data;
> +
> +       mtk_mdp_register_component(mdp, comp);
> +
> +       return 0;
> +}
> +
> +static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
> +                          void *data)
> +{
> +       struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
> +       struct mtk_mdp_dev *mdp = data;
> +
> +       mtk_mdp_unregister_component(mdp, comp);
> +}
> +
> +static const struct component_ops mtk_mdp_component_ops = {
> +       .bind   = mtk_mdp_comp_bind,
> +       .unbind = mtk_mdp_comp_unbind,
> +};
> +
> +int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
>  {
>         struct device_node *larb_node;
>         struct platform_device *larb_pdev;
>         int ret;
>         int i;
> +       struct device_node *node = dev->of_node;
> +       enum mtk_mdp_comp_type comp_type =
> +                (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
>
> -       comp->dev_node = of_node_get(node);
> -       comp->type = comp_type;
> +       INIT_LIST_HEAD(&comp->node);
>
>         for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
>                 comp->clk[i] = of_clk_get(node, i);
> @@ -80,19 +139,17 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>                         if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
>                                 dev_err(dev, "Failed to get clock\n");
>                         ret = PTR_ERR(comp->clk[i]);
> -                       goto put_dev;
> +                       goto err;
>                 }
>
>                 /* Only RDMA needs two clocks */
> -               if (comp->type != MTK_MDP_RDMA)
> +               if (comp_type != MTK_MDP_RDMA)
>                         break;
>         }
>
>         /* Only DMA capable components need the LARB property */
>         comp->larb_dev = NULL;
> -       if (comp->type != MTK_MDP_RDMA &&
> -           comp->type != MTK_MDP_WDMA &&
> -           comp->type != MTK_MDP_WROT)
> +       if (comp_type != MTK_MDP_RDMA && comp_type != MTK_MDP_WDMA && comp_type != MTK_MDP_WROT)
>                 return 0;
>
>         larb_node = of_parse_phandle(node, "mediatek,larb", 0);
> @@ -100,7 +157,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>                 dev_err(dev,
>                         "Missing mediadek,larb phandle in %pOF node\n", node);
>                 ret = -EINVAL;
> -               goto put_dev;
> +               goto err;
>         }
>
>         larb_pdev = of_find_device_by_node(larb_node);
> @@ -108,7 +165,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>                 dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
>                 of_node_put(larb_node);
>                 ret = -EPROBE_DEFER;
> -               goto put_dev;
> +               goto err;
>         }
>         of_node_put(larb_node);
>
> @@ -116,13 +173,59 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>
>         return 0;
>
> -put_dev:
> -       of_node_put(comp->dev_node);
> -
> +err:
>         return ret;
>  }
>
> -void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
> +static int mtk_mdp_comp_probe(struct platform_device *pdev)
>  {
> -       of_node_put(comp->dev_node);
> +       struct device *dev = &pdev->dev;
> +       struct device_node *vpu_node;
> +       int status;
> +       struct mtk_mdp_comp *comp;
> +
> +       vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> +       if (vpu_node) {
> +               of_node_put(vpu_node);
> +               /*
> +                * The device tree node with a mediatek,vpu property is deemed
> +                * the MDP "master" device, we don't want to add a component
> +                * for it in this function because the initialization for the
> +                * master is done elsewhere.
> +                */
> +               dev_info(dev, "vpu node found, not probing\n");
> +               return -ENODEV;
> +       }
> +
> +       comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
> +       if (!comp)
> +               return -ENOMEM;
> +
> +       status = mtk_mdp_comp_init(comp, dev);
> +       if (status) {
> +               dev_err(dev, "Failed to initialize component: %d\n", status);
> +               return status;
> +       }
> +
> +       dev_set_drvdata(dev, comp);
> +
> +       return component_add(dev, &mtk_mdp_component_ops);
>  }
> +
> +static int mtk_mdp_comp_remove(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +
> +       component_del(dev, &mtk_mdp_component_ops);
> +       return 0;
> +}
> +
> +struct platform_driver mtk_mdp_component_driver = {
> +       .probe          = mtk_mdp_comp_probe,
> +       .remove         = mtk_mdp_comp_remove,
> +       .driver         = {
> +               .name   = "mediatek-mdp-comp",
> +               .owner  = THIS_MODULE,
> +               .of_match_table = mtk_mdp_comp_driver_dt_match,
> +       },
> +};
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> index 92ab5249bcad..df5fc4c94f90 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> @@ -7,42 +7,23 @@
>  #ifndef __MTK_MDP_COMP_H__
>  #define __MTK_MDP_COMP_H__
>
> -/**
> - * enum mtk_mdp_comp_type - the MDP component
> - * @MTK_MDP_RDMA:      Read DMA
> - * @MTK_MDP_RSZ:       Riszer
> - * @MTK_MDP_WDMA:      Write DMA
> - * @MTK_MDP_WROT:      Write DMA with rotation
> - */
> -enum mtk_mdp_comp_type {
> -       MTK_MDP_RDMA,
> -       MTK_MDP_RSZ,
> -       MTK_MDP_WDMA,
> -       MTK_MDP_WROT,
> -};
> -
>  /**
>   * struct mtk_mdp_comp - the MDP's function component data
>   * @node:      list node to track sibing MDP components
> - * @dev_node:  component device node
>   * @clk:       clocks required for component
>   * @larb_dev:  SMI device required for component
> - * @type:      component type
>   */
>  struct mtk_mdp_comp {
>         struct list_head        node;
> -       struct device_node      *dev_node;
>         struct clk              *clk[2];
>         struct device           *larb_dev;
> -       enum mtk_mdp_comp_type  type;
>  };
>
> -int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
> -                     struct mtk_mdp_comp *comp,
> -                     enum mtk_mdp_comp_type comp_type);
> -void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
> +int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
> +
>  int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
>  void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
>
> +extern struct platform_driver mtk_mdp_component_driver;
>
>  #endif /* __MTK_MDP_COMP_H__ */
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index 412bbec0f735..b813a822439a 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -6,6 +6,7 @@
>   */
>
>  #include <linux/clk.h>
> +#include <linux/component.h>
>  #include <linux/device.h>
>  #include <linux/errno.h>
>  #include <linux/interrupt.h>
> @@ -19,6 +20,7 @@
>  #include <linux/workqueue.h>
>  #include <soc/mediatek/smi.h>
>
> +#include "mtk_mdp_comp.h"
>  #include "mtk_mdp_core.h"
>  #include "mtk_mdp_m2m.h"
>  #include "mtk_vpu.h"
> @@ -32,16 +34,12 @@ module_param(mtk_mdp_dbg_level, int, 0644);
>  static const struct of_device_id mtk_mdp_comp_dt_ids[] = {
>         {
>                 .compatible = "mediatek,mt8173-mdp-rdma",
> -               .data = (void *)MTK_MDP_RDMA
>         }, {
>                 .compatible = "mediatek,mt8173-mdp-rsz",
> -               .data = (void *)MTK_MDP_RSZ
>         }, {
>                 .compatible = "mediatek,mt8173-mdp-wdma",
> -               .data = (void *)MTK_MDP_WDMA
>         }, {
>                 .compatible = "mediatek,mt8173-mdp-wrot",
> -               .data = (void *)MTK_MDP_WROT
>         },
>         { },
>  };
> @@ -106,6 +104,63 @@ static void mtk_mdp_reset_handler(void *priv)
>         queue_work(mdp->wdt_wq, &mdp->wdt_work);
>  }
>
> +static int compare_of(struct device *dev, void *data)
> +{
> +       return dev->of_node == data;
> +}
> +
> +static void release_of(struct device *dev, void *data)
> +{
> +       of_node_put(data);
> +}
> +
> +static int mtk_mdp_master_bind(struct device *dev)
> +{
> +       int status;
> +       struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> +
> +       mtk_mdp_register_component(mdp, &mdp->comp_self);
> +
> +       status = component_bind_all(dev, mdp);
> +       if (status) {
> +               dev_err(dev, "Failed to bind all components: %d\n", status);
> +               goto err_component_bind_all;
> +       }
> +
> +       status = mtk_mdp_register_m2m_device(mdp);
> +       if (status) {
> +               dev_err(dev, "Failed to register m2m device: %d\n", status);
> +               goto err_mtk_mdp_register_m2m_device;
> +       }
> +
> +       pm_runtime_enable(dev);
> +
> +       return 0;
> +
> +err_mtk_mdp_register_m2m_device:
> +       component_unbind_all(dev, mdp);
> +
> +err_component_bind_all:
> +       mtk_mdp_unregister_component(mdp, &mdp->comp_self);
> +
> +       return status;
> +}
> +
> +static void mtk_mdp_master_unbind(struct device *dev)
> +{
> +       struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> +
> +       pm_runtime_disable(dev);
> +       mtk_mdp_unregister_m2m_device(mdp);
> +       component_unbind_all(dev, mdp);
> +       mtk_mdp_unregister_component(mdp, &mdp->comp_self);
> +}
> +
> +static const struct component_master_ops mtk_mdp_com_ops = {
> +       .bind           = mtk_mdp_master_bind,
> +       .unbind         = mtk_mdp_master_unbind,
> +};
> +
>  void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
>                                 struct mtk_mdp_comp *comp)
>  {
> @@ -123,8 +178,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>         struct mtk_mdp_dev *mdp;
>         struct device *dev = &pdev->dev;
>         struct device_node *node, *parent;
> -       struct mtk_mdp_comp *comp, *comp_temp;
> -       int ret = 0;
> +       int i, ret = 0;
> +       struct component_match *match = NULL;
>
>         mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
>         if (!mdp)
> @@ -149,36 +204,43 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>         }
>
>         /* Iterate over sibling MDP function blocks */
> +       i = 0;
>         for_each_child_of_node(parent, node) {
> -               const struct of_device_id *of_id;
> -               enum mtk_mdp_comp_type comp_type;
> +               struct platform_device *pdev;
>
> -               of_id = of_match_node(mtk_mdp_comp_dt_ids, node);
> -               if (!of_id)
> +               if (!of_match_node(mtk_mdp_comp_dt_ids, node))
>                         continue;
>
> -               if (!of_device_is_available(node)) {
> -                       dev_err(dev, "Skipping disabled component %pOF\n",
> -                               node);
> +               if (!of_device_is_available(node))
>                         continue;
> -               }
> -
> -               comp_type = (enum mtk_mdp_comp_type)of_id->data;
>
> -               comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
> -               if (!comp) {
> -                       ret = -ENOMEM;
> -                       of_node_put(node);
> -                       goto err_comp;
> +               pdev = of_find_device_by_node(node);
> +               if (!pdev) {
> +                       dev_warn(dev, "Unable to find comp device %s\n",
> +                                node->full_name);
> +                       continue;
>                 }
>
> -               ret = mtk_mdp_comp_init(dev, node, comp, comp_type);
> -               if (ret) {
> -                       of_node_put(node);
> -                       goto err_comp;
> +               /*
> +                * Do not add a match for my own (rdma0) device node.
> +                * I will be managing it directly instead using comp_self.
> +                */
> +               if (&pdev->dev != dev) {
> +                       dev_dbg(dev, "adding match %d for: %pOF\n", i++, node);
> +                       component_match_add_release(dev, &match, release_of,
> +                                                   compare_of,
> +                                                   of_node_get(node));
>                 }
> +       }
>
> -               mtk_mdp_register_component(mdp, comp);
> +       /*
> +        * Create a component for myself so that clocks can be toggled in
> +        * clock_on().
> +        */
> +       ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
> +       if (ret) {
> +               dev_err(dev, "Failed to initialize component\n");
> +               goto err_comp;
>         }
>
>         mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
> @@ -203,18 +265,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>                 goto err_dev_register;
>         }
>
> -       ret = mtk_mdp_register_m2m_device(mdp);
> -       if (ret) {
> -               v4l2_err(&mdp->v4l2_dev, "Failed to init mem2mem device\n");
> -               goto err_m2m_register;
> -       }
> -
>         mdp->vpu_dev = vpu_get_plat_device(pdev);
>         ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
>                                   VPU_RST_MDP);
>         if (ret) {
>                 dev_err(&pdev->dev, "Failed to register reset handler\n");
> -               goto err_m2m_register;
> +               goto err_wdt_reg;
>         }
>
>         platform_set_drvdata(pdev, mdp);
> @@ -222,15 +278,25 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>         ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
>         if (ret) {
>                 dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
> -               goto err_m2m_register;
> +               goto err_set_max_seg_size;
> +       }
> +
> +       ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
> +       if (ret) {
> +               dev_err(dev, "Component master add failed\n");
> +               goto err_component_master_add;
>         }
>
> -       pm_runtime_enable(dev);
>         dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);
>
>         return 0;
>
> -err_m2m_register:
> +err_component_master_add:
> +       vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> +
> +err_set_max_seg_size:
> +
> +err_wdt_reg:
>         v4l2_device_unregister(&mdp->v4l2_dev);
>
>  err_dev_register:
> @@ -242,11 +308,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>  err_alloc_job_wq:
>
>  err_comp:
> -       list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
> -               mtk_mdp_unregister_component(mdp, comp);
> -               mtk_mdp_comp_deinit(dev, comp);
> -       }
> -
>         dev_dbg(dev, "err %d\n", ret);
>         return ret;
>  }
> @@ -254,11 +315,10 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>  static int mtk_mdp_remove(struct platform_device *pdev)
>  {
>         struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
> -       struct mtk_mdp_comp *comp, *comp_temp;
>
> -       pm_runtime_disable(&pdev->dev);
> +       component_master_del(&pdev->dev, &mtk_mdp_com_ops);
> +
>         vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> -       mtk_mdp_unregister_m2m_device(mdp);
>         v4l2_device_unregister(&mdp->v4l2_dev);
>
>         flush_workqueue(mdp->wdt_wq);
> @@ -267,10 +327,8 @@ static int mtk_mdp_remove(struct platform_device *pdev)
>         flush_workqueue(mdp->job_wq);
>         destroy_workqueue(mdp->job_wq);
>
> -       list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
> -               mtk_mdp_unregister_component(mdp, comp);
> -               mtk_mdp_comp_deinit(&pdev->dev, comp);
> -       }
> +       if (!list_empty(&mdp->comp_list))
> +               dev_warn(&pdev->dev, "not all components removed\n");
>
>         dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
>         return 0;
> @@ -323,7 +381,25 @@ static struct platform_driver mtk_mdp_driver = {
>         }
>  };
>
> -module_platform_driver(mtk_mdp_driver);
> +static struct platform_driver * const mtk_mdp_drivers[] = {
> +       &mtk_mdp_driver,
> +       &mtk_mdp_component_driver,
> +};
> +
> +static int __init mtk_mdp_init(void)
> +{
> +       return platform_register_drivers(mtk_mdp_drivers,
> +                                        ARRAY_SIZE(mtk_mdp_drivers));
> +}
> +
> +static void __exit mtk_mdp_exit(void)
> +{
> +       platform_unregister_drivers(mtk_mdp_drivers,
> +                                   ARRAY_SIZE(mtk_mdp_drivers));
> +}
> +
> +module_init(mtk_mdp_init);
> +module_exit(mtk_mdp_exit);
>
>  MODULE_AUTHOR("Houlong Wei <houlong.wei at mediatek.com>");
>  MODULE_DESCRIPTION("Mediatek image processor driver");
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> index a6e6dc36307b..8a52539b15d4 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> @@ -155,6 +155,7 @@ struct mtk_mdp_dev {
>         struct mtk_mdp_variant          *variant;
>         u16                             id;
>         struct list_head                comp_list;
> +       struct mtk_mdp_comp             comp_self;
>         struct v4l2_m2m_dev             *m2m_dev;
>         struct list_head                ctx_list;
>         struct video_device             *vdev;
> --
> 2.32.0.554.ge1b32706d8-goog
>


From eballetbo at gmail.com  Tue Aug  3 03:26:59 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:26:59 +0200
Subject: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on
In-Reply-To: <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>
Message-ID: <CAFqH_53NWzhrSWqf-1qYqN7d7TRzh5g4u1+Z_3VnzoS=_CGzqg@mail.gmail.com>

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:13:
>
> Up until this change, many errors were logged but ignored when powering
> on clocks inside mtk_mdp_core. This change tries to do a better job at
> propagating errors back to the power management framework.
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>

> ---
>
> (no changes since v1)
>
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 25 ++++++++++++-----
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 +-
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 27 ++++++++++++++-----
>  3 files changed, 39 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index b3426a551bea..76e295c8d9bc 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -13,10 +13,9 @@
>
>  #include "mtk_mdp_comp.h"
>
> -
> -void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
> +int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>  {
> -       int i, err;
> +       int i, err, status;
>
>         if (comp->larb_dev) {
>                 err = mtk_smi_larb_get(comp->larb_dev);
> @@ -30,11 +29,23 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>                 if (IS_ERR(comp->clk[i]))
>                         continue;
>                 err = clk_prepare_enable(comp->clk[i]);
> -               if (err)
> -                       dev_err(dev,
> -                       "failed to enable clock, err %d. type:%d i:%d\n",
> -                               err, comp->type, i);
> +               if (err) {
> +                       status = err;
> +                       dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
> +                       goto err_clk_prepare_enable;
> +               }
> +       }
> +
> +       return 0;
> +
> +err_clk_prepare_enable:
> +       for (--i; i >= 0; i--) {
> +               if (IS_ERR(comp->clk[i]))
> +                       continue;
> +               clk_disable_unprepare(comp->clk[i]);

nit: We could use bulk functions here, but that's probably a follow-up patch.




>         }
> +
> +       return status;
>  }
>
>  void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> index 7897766c96bb..92ab5249bcad 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> @@ -41,7 +41,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>                       struct mtk_mdp_comp *comp,
>                       enum mtk_mdp_comp_type comp_type);
>  void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
> -void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
> +int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
>  void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
>
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index 976aa1f4829b..412bbec0f735 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -52,13 +52,28 @@ static const struct of_device_id mtk_mdp_of_ids[] = {
>  };
>  MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids);
>
> -static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
> +static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
>  {
> -       struct device *dev = &mdp->pdev->dev;
>         struct mtk_mdp_comp *comp_node;
> +       int status;
> +       struct device *dev = &mdp->pdev->dev;
> +       int err;
>
> -       list_for_each_entry(comp_node, &mdp->comp_list, node)
> -               mtk_mdp_comp_clock_on(dev, comp_node);
> +       list_for_each_entry(comp_node, &mdp->comp_list, node) {
> +               err = mtk_mdp_comp_clock_on(dev, comp_node);
> +               if (err) {
> +                       status = err;
> +                       goto err_mtk_mdp_comp_clock_on;
> +               }
> +       }
> +
> +       return 0;
> +
> +err_mtk_mdp_comp_clock_on:
> +       list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
> +               mtk_mdp_comp_clock_off(dev, comp_node);
> +
> +       return status;
>  }
>
>  static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
> @@ -274,9 +289,7 @@ static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
>  {
>         struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
>
> -       mtk_mdp_clock_on(mdp);
> -
> -       return 0;
> +       return mtk_mdp_clock_on(mdp);
>  }
>
>  static int __maybe_unused mtk_mdp_suspend(struct device *dev)
> --
> 2.32.0.554.ge1b32706d8-goog
>


From eballetbo at gmail.com  Tue Aug  3 03:27:03 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:27:03 +0200
Subject: [PATCH v6 4/9] media: mtk-mdp: don't pm_run_time_get/put for
 master comp in clock_on
In-Reply-To: <20210802220943.v6.4.Ifd87681955689a08cce4c65e72ee5e8c6d09af95@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.4.Ifd87681955689a08cce4c65e72ee5e8c6d09af95@changeid>
Message-ID: <CAFqH_50or=_pb7UDCvoPEoA7s1r6qNTNnMuo4pPuFfGqj4d50w@mail.gmail.com>

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:13:

>
> The original intent of commit 86698b9505bbc ("media: mtk-mdp: convert
> mtk_mdp_dev.comp array to list") was to create a list to track all the
> MDP components that needed to have their clocks enabled/disabled when
> calling mtk_mdp_comp_clock_on/off. However, there was a bug inside
> mtk_mdp_register_component where the args to a call to list_add were
> swapped. The result is that only one component was added to
> mtk_mdp_dev.comp_list because comp_list was instead being
> repeatedly added to the single element lists headed by each
> mtk_mdp_comp.
>
> The order of the args to list_add in mtk_mdp_register_component was
> fixed in https://patchwork.kernel.org/patch/11742895/ (Fix Null pointer
> dereference when calling list_add).
>
> Then, as a result of https://patchwork.kernel.org/patch/11530769/
> (mtk-mdp: use pm_runtime in MDP component driver) if all the components
> are added to the component list, the mdp "master" / rdma0 component
> ends up having pm_runtime_get_sync() called on it twice recursively:
>
>     rpm_resume+0x694/0x8f8
>     __pm_runtime_resume+0x7c/0xa0 ***NOTE***
>     mtk_mdp_comp_clock_on+0x48/0x104 [mtk_mdp]
>     mtk_mdp_pm_resume+0x2c/0x44 [mtk_mdp]
>     pm_generic_runtime_resume+0x34/0x48
>     __genpd_runtime_resume+0x6c/0x80
>     genpd_runtime_resume+0x104/0x1ac
>     __rpm_callback+0x120/0x238
>     rpm_callback+0x34/0x8c
>     rpm_resume+0x7a0/0x8f8
>     __pm_runtime_resume+0x7c/0xa0 ***NOTE***
>     mtk_mdp_m2m_start_streaming+0x2c/0x3c [mtk_mdp]
>
> (The calls to pm_runtime_get_sync are inlined and correspond to the
> calls to __pm_runtime_resume). It is not correct to have
> pm_runtime_get_sync called recursively and the second call will block
> indefinitely.
>
> As a result of all that, this change factors mtk_mdp_comp_clock_on/off
> into mtk_mdp_comp_power_on/off and moves the calls to
> pm_runtime_get/put into the power_on/off functions.
>
> This change then special-cases the master/rdma0 MDP component and does
> these things:
> - the master/rdma0 component is not added to mtk_mdp_dev.comp_list
> - the master/rdma0 component has its clocks (*but not power*) toggled
>   by mtk_mpd_comp_clock_on/off inside mtk_mdp_clock_on/off.
> - the other components have their clocks *and* power toggled with
>   mtk_mdp_comp_power_on/off.
>
> This change introduces the assumption that mtk_mdp_pm_resume will
> always be called though a callback from pm_runtime_get_sync made on the
> master / rdma0 component.
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
>
> (no changes since v1)
>
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 57 ++++++++++++++---
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  5 +-
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++++++++++-----
>  3 files changed, 98 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 472c261b01e8..7b6c8a3f3455 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -51,9 +51,9 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
>
> -int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
> +int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp)
>  {
> -       int i, err, status;
> +       int status, err;
>
>         if (comp->larb_dev) {
>                 err = mtk_smi_larb_get(comp->larb_dev);
> @@ -63,12 +63,54 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
>
>         err = pm_runtime_get_sync(comp->dev);
>         if (err < 0) {
> -               dev_err(comp->dev,
> -                       "failed to runtime get, err %d.\n",
> -                       err);
> +               dev_err(comp->dev, "failed to runtime get, err %d.\n", err);
>                 return err;
>         }
>
> +       err = mtk_mdp_comp_clock_on(comp);
> +       if (err) {
> +               dev_err(comp->dev, "failed to turn on clock. err=%d", err);
> +               status = err;
> +               goto err_mtk_mdp_comp_clock_on;
> +       }
> +
> +       return 0;
> +
> +err_mtk_mdp_comp_clock_on:
> +       err = pm_runtime_put_sync(comp->dev);
> +       if (err)
> +               dev_err(comp->dev, "failed to runtime put in cleanup. err=%d", err);
> +
> +       return status;
> +}
> +
> +int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp)
> +{
> +       int status, err;
> +
> +       mtk_mdp_comp_clock_off(comp);
> +
> +       err = pm_runtime_put_sync(comp->dev);
> +       if (err < 0) {
> +               dev_err(comp->dev, "failed to runtime put, err %d.\n", err);
> +               status = err;
> +               goto err_pm_runtime_put_sync;
> +       }
> +
> +       return 0;
> +
> +err_pm_runtime_put_sync:
> +       err = mtk_mdp_comp_clock_on(comp);
> +       if (err)
> +               dev_err(comp->dev, "failed to turn on clock in cleanup. err=%d", err);
> +
> +       return status;
> +}
> +
> +int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
> +{
> +       int i, err, status;
> +
>         for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
>                 if (IS_ERR(comp->clk[i]))
>                         continue;
> @@ -94,7 +136,8 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
>         return status;
>  }
>
> -int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
> +
> +void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
>  {
>         int i;
>
> @@ -106,8 +149,6 @@ int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
>
>         if (comp->larb_dev)
>                 mtk_smi_larb_put(comp->larb_dev);
> -
> -       return pm_runtime_put_sync(comp->dev);
>  }
>
>  static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> index f2e22e7e7c45..e3d6aef52869 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> @@ -23,8 +23,11 @@ struct mtk_mdp_comp {
>
>  int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
>
> +int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp);
> +int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp);
> +
>  int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
> -int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
> +void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
>
>  extern struct platform_driver mtk_mdp_component_driver;
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index 714154450981..a72a9ba41ea6 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -57,29 +57,64 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
>         struct device *dev = &mdp->pdev->dev;
>         int err;
>
> +       /*
> +        * The master / rdma0 component will have pm_runtime_get_sync called
> +        * on it through mtk_mdp_m2m_start_streaming, making it unnecessary to
> +        * have mtk_mdp_comp_power_on called on it.
> +        */
> +       err = mtk_mdp_comp_clock_on(&mdp->comp_self);
> +       if (err)
> +               return err;
> +
>         list_for_each_entry(comp_node, &mdp->comp_list, node) {
> -               err = mtk_mdp_comp_clock_on(comp_node);
> +               err = mtk_mdp_comp_power_on(comp_node);
>                 if (err) {
>                         status = err;
> -                       goto err_mtk_mdp_comp_clock_on;
> +                       goto err_mtk_mdp_comp_power_on;
>                 }
>         }
>
>         return 0;
>
> -err_mtk_mdp_comp_clock_on:
> -       list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
> -               mtk_mdp_comp_clock_off(comp_node);
> -
> +err_mtk_mdp_comp_power_on:
> +       list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
> +               err = mtk_mdp_comp_power_off(comp_node);
> +               if (err)
> +                       dev_err(&mdp->pdev->dev, "failed to power off after error. err=%d", err);
> +       }
>         return status;
>  }
>
> -static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
> +static int mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
>  {
>         struct mtk_mdp_comp *comp_node;
> +       int status, err;
> +
> +       list_for_each_entry(comp_node, &mdp->comp_list, node) {
> +               err = mtk_mdp_comp_power_off(comp_node);
> +               if (err) {
> +                       status = err;
> +                       goto err_mtk_mdp_comp_power_off;
> +               }
> +       }
>
> -       list_for_each_entry(comp_node, &mdp->comp_list, node)
> -               mtk_mdp_comp_clock_off(comp_node);
> +       /*
> +        * The master / rdma0 component will have pm_runtime_put called
> +        * on it through mtk_mdp_m2m_stop_streaming, making it unnecessary to
> +        * have mtk_mdp_comp_power_off called on it.
> +        */
> +       mtk_mdp_comp_clock_off(&mdp->comp_self);
> +
> +       return 0;
> +
> +err_mtk_mdp_comp_power_off:
> +       list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
> +               err = mtk_mdp_comp_power_on(comp_node);
> +               if (err)
> +                       dev_err(&mdp->pdev->dev, "failed to power on after error. err=%d", err);
> +       }
> +
> +       return status;
>  }
>
>  static void mtk_mdp_wdt_worker(struct work_struct *work)
> @@ -118,8 +153,6 @@ static int mtk_mdp_master_bind(struct device *dev)
>         int status;
>         struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
>
> -       mtk_mdp_register_component(mdp, &mdp->comp_self);
> -
>         status = component_bind_all(dev, mdp);
>         if (status) {
>                 dev_err(dev, "Failed to bind all components: %d\n", status);
> @@ -140,8 +173,6 @@ static int mtk_mdp_master_bind(struct device *dev)
>         component_unbind_all(dev, mdp);
>
>  err_component_bind_all:
> -       mtk_mdp_unregister_component(mdp, &mdp->comp_self);
> -
>         return status;
>  }
>
> @@ -152,7 +183,6 @@ static void mtk_mdp_master_unbind(struct device *dev)
>         pm_runtime_disable(dev);
>         mtk_mdp_unregister_m2m_device(mdp);
>         component_unbind_all(dev, mdp);
> -       mtk_mdp_unregister_component(mdp, &mdp->comp_self);
>  }
>
>  static const struct component_master_ops mtk_mdp_com_ops = {
> @@ -337,9 +367,7 @@ static int __maybe_unused mtk_mdp_pm_suspend(struct device *dev)
>  {
>         struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
>
> -       mtk_mdp_clock_off(mdp);
> -
> -       return 0;
> +       return mtk_mdp_clock_off(mdp);
>  }
>
>  static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
> --
> 2.32.0.554.ge1b32706d8-goog
>


From eballetbo at gmail.com  Tue Aug  3 03:27:07 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:27:07 +0200
Subject: [PATCH v6 6/9] soc: mediatek: mmsys: instantiate mdp virtual
 device from mmsys
In-Reply-To: <20210802220943.v6.6.Ie4214d2cc73ab276dd7c41d4f63c98e011fb42d4@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.6.Ie4214d2cc73ab276dd7c41d4f63c98e011fb42d4@changeid>
Message-ID: <CAFqH_51Vn1VSbL8BU=J0gpOm9c7zevX2o6qWf=-hFp1tbeN-Aw@mail.gmail.com>

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:14:
>
> A virtual device that is probed by the mtk_mdp_core driver is
> instantiated by the mtk_mmsys driver.
>
> This better reflects the logical organization of the hardware and
> driver: there are a number of hardware blocks that are used by the MDP
> that have no strict hierarchy, and the software driver is responsible
> for driving them properly.
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>


> ---
>
> (no changes since v1)
>
>  drivers/soc/mediatek/mtk-mmsys.c | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
> index 080660ef11bf..e681029fe804 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -97,6 +97,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
>         struct platform_device *clks;
>         struct platform_device *drm;
>         struct mtk_mmsys *mmsys;
> +       struct platform_device *mdp;
>         int ret;
>
>         mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
> @@ -122,10 +123,27 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
>                                             PLATFORM_DEVID_AUTO, NULL, 0);
>         if (IS_ERR(drm)) {
>                 platform_device_unregister(clks);
> -               return PTR_ERR(drm);
> +               ret = PTR_ERR(drm);
> +               goto err_drm;
> +       }
> +
> +       mdp = platform_device_register_data(&pdev->dev, "mtk-mdp",
> +                                           PLATFORM_DEVID_AUTO, NULL, 0);
> +       if (IS_ERR(mdp)) {
> +               ret = PTR_ERR(mdp);
> +               dev_err(dev, "Failed to register mdp: %d\n", ret);
> +               goto err_mdp;
>         }
>
>         return 0;
> +
> +err_mdp:
> +       platform_device_unregister(drm);
> +
> +err_drm:
> +       platform_device_unregister(clks);
> +
> +       return ret;
>  }
>
>  static const struct of_device_id of_match_mtk_mmsys[] = {
> --
> 2.32.0.554.ge1b32706d8-goog
>


From eballetbo at gmail.com  Tue Aug  3 03:27:11 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:27:11 +0200
Subject: [PATCH v6 8/9] dts: mtk-mdp: remove mediatek,vpu property from
 primary MDP device
In-Reply-To: <20210802220943.v6.8.Ib681f06d5189351b7fda0e3dcd6b15f3863a0071@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.8.Ib681f06d5189351b7fda0e3dcd6b15f3863a0071@changeid>
Message-ID: <CAFqH_51E+93_TZ2jpdkfWxDLSaijPcj6RLs+BHkw0GpKObT75w@mail.gmail.com>

Hi Eizan,

Thank you for your patch

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:14:
>
> It is no longer used by the mediatek MDP driver.
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>


> ---
>
> (no changes since v1)
>
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> index d502073b551f..872427748110 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> @@ -1010,7 +1010,6 @@ mdp_rdma0: rdma at 14001000 {
>                         power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
>                         iommus = <&iommu M4U_PORT_MDP_RDMA0>;
>                         mediatek,larb = <&larb0>;
> -                       mediatek,vpu = <&vpu>;
>                 };
>
>                 mdp_rdma1: rdma at 14002000 {
> --
> 2.32.0.554.ge1b32706d8-goog
>


From eballetbo at gmail.com  Tue Aug  3 03:27:17 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:27:17 +0200
Subject: [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from
 mtk-mdp
In-Reply-To: <20210802220943.v6.9.If10dbdfade9f48710e485efe79e53e6e65144a2f@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.9.If10dbdfade9f48710e485efe79e53e6e65144a2f@changeid>
Message-ID: <CAFqH_53dZxhTwVmSRJ5DX+uV86cPRZjyEri3UEzcRLiye=OhNA@mail.gmail.com>

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:15:
>
> It is no longer needed by the mtk-mdp driver
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>


> ---
>
> (no changes since v1)
>
>  Documentation/devicetree/bindings/media/mediatek-mdp.txt | 3 ---
>  1 file changed, 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
> index caa24943da33..4c325585f68f 100644
> --- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
> +++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
> @@ -4,8 +4,6 @@ Media Data Path is used for scaling and color space conversion.
>
>  Required properties (controller node):
>  - compatible: "mediatek,mt8173-mdp"
> -- mediatek,vpu: the node of video processor unit, see
> -  Documentation/devicetree/bindings/media/mediatek-vpu.txt for details.
>
>  Required properties (all function blocks, child node):
>  - compatible: Should be one of
> @@ -41,7 +39,6 @@ Example:
>                 power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
>                 iommus = <&iommu M4U_PORT_MDP_RDMA0>;
>                 mediatek,larb = <&larb0>;
> -               mediatek,vpu = <&vpu>;
>         };
>
>         mdp_rdma1: rdma at 14002000 {
> --
> 2.32.0.554.ge1b32706d8-goog
>


From eballetbo at gmail.com  Tue Aug  3 03:27:21 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:27:21 +0200
Subject: [PATCH v6 5/9] mtk-mdp: make mdp driver to be loadable by
 platform_device_register*()
In-Reply-To: <20210802220943.v6.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>
Message-ID: <CAFqH_52pZ-7HtnVYtDQf-1Y000Tz-Omzs+eQuYV7Zm_K7sBxJQ@mail.gmail.com>

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:13:
>
> Rather than hanging the MDP master component driver off of the rdma0
> device, make it possible too create a "virtual" device by registering
> it with platform_device_register_*() to be probed by the mtk_mdp_core
> driver.
>
> Broadly, three interdependent things are done by this change:
> - Make it is possible to search for MDP devices in the device tree
>   through the grandparent device's of_node.
> - v4l-related setup is moved into from the mtk_mdp_core driver to the
>   mtk_mdp_comp driver.
> - Presence of a mediatek,vpu property in an MDP component device node
>   is used to determine what device to use when dispatching DMA ops from
>   the relevant ioctl, and also do V4L2 initialization in this case.
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
>
> Changes in v6:
> - Don't propagate errors from clock_on/off as an afterthought.
> - Split apart modifying mdp driver to be loadable from mmsys from
>   actually loading it from mmsys into two changs to make review easier.
> - Update devicetree bindings to reflect no longer needing the
>   mediatek,vpu property in the mdp_rdma0 device node.
> - Some stylistic cleanups.
>
> Changes in v5:
> - rebase and test on 5.13-next @ e2f74b13dbe6
>
> Changes in v4:
> - rebase and test on 5.13
> - don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873
>
> Changes in v3:
> - get mdp master from aliases instead of strcmp against of_node->name
>
> Changes in v2:
> - rebased onto Linux 5.12
> - 100 char line length allowance was utilized in a few places
> - Removal of a redundant dev_err() print at the end of
>   mtk_mdp_comp_init()
> - Instead of printing errors and ignoring them, I've added a patch to
>   correctly propagate them.
> - Use of C style comments.
> - Three additional patches were added to eliminate dependency on the
>   mediatek,vpu property inside the mdp_rdma0 device node.
>
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 51 ++++++++++-----
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++-------------
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.h |  2 +
>  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
>  4 files changed, 60 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 7b6c8a3f3455..85ef274841a3 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -155,8 +155,45 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
>  {
>         struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>         struct mtk_mdp_dev *mdp = data;
> +       struct device_node *vpu_node;
>
>         mtk_mdp_register_component(mdp, comp);
> +
> +       /*
> +        * If this component has a "mediatek-vpu" property, it is responsible for
> +        * notifying the mdp master driver about it so it can be further initialized
> +        * later.
> +        */
> +       vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> +       if (vpu_node) {
> +               int ret;
> +
> +               mdp->vpu_dev = of_find_device_by_node(vpu_node);
> +               if (WARN_ON(!mdp->vpu_dev)) {

This looks a bit excessive IMO, but on the other hand looks like this
is a transitional patch as all this will be removed after some rework
on the latest patch.

> +                       dev_err(dev, "vpu pdev failed\n");

You already did a WARN_ON, this print is not needed. But again, all
this seems to be transitional and is removed later. So it doesn't
really bothers me

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>


> +                       of_node_put(vpu_node);
> +               }
> +
> +               ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> +               if (ret) {
> +                       dev_err(dev, "Failed to register v4l2 device\n");
> +                       return -EINVAL;
> +               }
> +
> +               ret = vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
> +               if (ret) {
> +                       dev_err(dev, "Failed to set vb2 dma mag seg size\n");
> +                       return -EINVAL;
> +               }
> +
> +               /*
> +                * presence of the "mediatek,vpu" property in a device node
> +                * indicates that it is the primary MDP rdma device and MDP DMA
> +                * ops should be handled by its DMA callbacks.
> +                */
> +               mdp->rdma_dev = dev;
> +       }
> +
>         pm_runtime_enable(dev);
>
>         return 0;
> @@ -237,23 +274,9 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
>  static int mtk_mdp_comp_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> -       struct device_node *vpu_node;
>         int status;
>         struct mtk_mdp_comp *comp;
>
> -       vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> -       if (vpu_node) {
> -               of_node_put(vpu_node);
> -               /*
> -                * The device tree node with a mediatek,vpu property is deemed
> -                * the MDP "master" device, we don't want to add a component
> -                * for it in this function because the initialization for the
> -                * master is done elsewhere.
> -                */
> -               dev_info(dev, "vpu node found, not probing\n");
> -               return -ENODEV;
> -       }
> -
>         comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
>         if (!comp)
>                 return -ENOMEM;
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index a72a9ba41ea6..50eafcc9993d 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -159,6 +159,17 @@ static int mtk_mdp_master_bind(struct device *dev)
>                 goto err_component_bind_all;
>         }
>
> +       if (mdp->vpu_dev) {
> +               int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
> +                                         VPU_RST_MDP);
> +               if (ret) {
> +                       dev_err(dev, "Failed to register reset handler\n");
> +                       goto err_wdt_reg;
> +               }
> +       } else {
> +               dev_err(dev, "no vpu_dev found\n");
> +       }
> +
>         status = mtk_mdp_register_m2m_device(mdp);
>         if (status) {
>                 dev_err(dev, "Failed to register m2m device: %d\n", status);
> @@ -170,6 +181,8 @@ static int mtk_mdp_master_bind(struct device *dev)
>         return 0;
>
>  err_mtk_mdp_register_m2m_device:
> +
> +err_wdt_reg:
>         component_unbind_all(dev, mdp);
>
>  err_component_bind_all:
> @@ -228,8 +241,13 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>                 of_node_put(node);
>                 parent = dev->of_node;
>                 dev_warn(dev, "device tree is out of date\n");
> -       } else {
> +       } else if (dev->of_node) {
>                 parent = dev->of_node->parent;
> +       } else if (dev->parent) {
> +               /* maybe we were created from a call to platform_device_register_data() */
> +               parent = dev->parent->parent->of_node;
> +       } else {
> +               return -ENODEV;
>         }
>
>         /* Iterate over sibling MDP function blocks */
> @@ -262,16 +280,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>                 }
>         }
>
> -       /*
> -        * Create a component for myself so that clocks can be toggled in
> -        * clock_on().
> -        */
> -       ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
> -       if (ret) {
> -               dev_err(dev, "Failed to initialize component\n");
> -               goto err_comp;
> -       }
> -
>         mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
>         if (!mdp->job_wq) {
>                 dev_err(&pdev->dev, "unable to alloc job workqueue\n");
> @@ -287,29 +295,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>         }
>         INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker);
>
> -       ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> -       if (ret) {
> -               dev_err(&pdev->dev, "Failed to register v4l2 device\n");
> -               ret = -EINVAL;
> -               goto err_dev_register;
> -       }
> -
> -       mdp->vpu_dev = vpu_get_plat_device(pdev);
> -       ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
> -                                 VPU_RST_MDP);
> -       if (ret) {
> -               dev_err(&pdev->dev, "Failed to register reset handler\n");
> -               goto err_wdt_reg;
> -       }
> -
>         platform_set_drvdata(pdev, mdp);
>
> -       ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
> -       if (ret) {
> -               dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
> -               goto err_set_max_seg_size;
> -       }
> -
>         ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
>         if (ret) {
>                 dev_err(dev, "Component master add failed\n");
> @@ -321,22 +308,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>         return 0;
>
>  err_component_master_add:
> -       vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> -
> -err_set_max_seg_size:
> -
> -err_wdt_reg:
> -       v4l2_device_unregister(&mdp->v4l2_dev);
> -
> -err_dev_register:
>         destroy_workqueue(mdp->wdt_wq);
>
>  err_alloc_wdt_wq:
>         destroy_workqueue(mdp->job_wq);
>
>  err_alloc_job_wq:
> -
> -err_comp:
>         dev_dbg(dev, "err %d\n", ret);
>         return ret;
>  }
> @@ -404,7 +381,6 @@ static struct platform_driver mtk_mdp_driver = {
>         .driver = {
>                 .name   = MTK_MDP_MODULE_NAME,
>                 .pm     = &mtk_mdp_pm_ops,
> -               .of_match_table = mtk_mdp_of_ids,
>         }
>  };
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> index 8a52539b15d4..9fcd8b8e7c25 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> @@ -133,6 +133,7 @@ struct mtk_mdp_variant {
>   * struct mtk_mdp_dev - abstraction for image processor entity
>   * @lock:      the mutex protecting this data structure
>   * @vpulock:   the mutex protecting the communication with VPU
> + * @rdma_dev:  device pointer to rdma device for MDP
>   * @pdev:      pointer to the image processor platform device
>   * @variant:   the IP variant information
>   * @id:                image processor device index (0..MTK_MDP_MAX_DEVS)
> @@ -151,6 +152,7 @@ struct mtk_mdp_variant {
>  struct mtk_mdp_dev {
>         struct mutex                    lock;
>         struct mutex                    vpulock;
> +       struct device                   *rdma_dev;
>         struct platform_device          *pdev;
>         struct mtk_mdp_variant          *variant;
>         u16                             id;
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> index f14779e7596e..9834d3bbe851 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> @@ -929,7 +929,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
>         src_vq->mem_ops = &vb2_dma_contig_memops;
>         src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
>         src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> -       src_vq->dev = &ctx->mdp_dev->pdev->dev;
> +       src_vq->dev = ctx->mdp_dev->rdma_dev;
>         src_vq->lock = &ctx->mdp_dev->lock;
>
>         ret = vb2_queue_init(src_vq);
> @@ -944,7 +944,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
>         dst_vq->mem_ops = &vb2_dma_contig_memops;
>         dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
>         dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> -       dst_vq->dev = &ctx->mdp_dev->pdev->dev;
> +       dst_vq->dev = ctx->mdp_dev->rdma_dev;
>         dst_vq->lock = &ctx->mdp_dev->lock;
>
>         return vb2_queue_init(dst_vq);
> --
> 2.32.0.554.ge1b32706d8-goog
>


From grygorii.strashko at ti.com  Tue Aug  3 03:27:18 2021
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Tue, 3 Aug 2021 13:27:18 +0300
Subject: [PATCH 3/3] ARM: Map the lowmem and kernel separately
In-Reply-To: <CACRpkdYAzGzqfdREogAFnyGqSnHLQmdCR=GZ=YqhzoTUA0MfCA@mail.gmail.com>
References: <20210517145719.110966-1-linus.walleij@linaro.org>
 <20210517145719.110966-4-linus.walleij@linaro.org>
 <20210730202259.dbifugsvry5vjdr7@earthen>
 <CACRpkdYAzGzqfdREogAFnyGqSnHLQmdCR=GZ=YqhzoTUA0MfCA@mail.gmail.com>
Message-ID: <f3eb9c84-19c6-cba2-ffcc-2dbcb48051ad@ti.com>



On 31/07/2021 01:40, Linus Walleij wrote:
> On Fri, Jul 30, 2021 at 10:23 PM Nishanth Menon <nm at ti.com> wrote:
>> On 16:57-20210517, Linus Walleij wrote:
>>> Using our knowledge of where the physical kernel sections start
>>> and end we can split mapping of lowmem and kernel apart.
>>>
>> [...]
>>>
>>> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
>>
>>
>> We noticed a regression in k2g platforms with this patch.
>> commit 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel
>> separately")
>>
>> Boot log: https://pastebin.ubuntu.com/p/Sf3r28D8MR/
>> Bisect log: https://pastebin.ubuntu.com/p/6PTYpNVFDy/
> 
> Given how invasive the patch is I'm surprised that k2g is the
> only thing so far complaining about it. Let's fix this!
> 
> I've had similar reports and in those cases it has been that the boot
> loader did not turn off the caches before jumping to execute the
> Linux kernel.
> 
> So first can you check that cache is off?
> 
> Next can you turn on DEBUG_LL and enable the debug messages
> in arch/arm/mmu.c in map_lowmem() in some way that works for
> you, for example I just add a patch like this:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/patch/?id=d10c46631a6eaef1339e376b878de985143b27ff
> (Beware of ugly debug habits!)
> 
> Next is this using the keystone 2 pv fixup thing  mdesc->pv_fixup
> mdesc->pv_fixup in early_paging_init()?
> 
> I added a special print
> there to see if that gets called. This code is really scary but I
> suppose Santosh can explain what is supposed to happen here
> and what I may have stepped on. (I see Santosh work at Oracle
> now? Interesting.)

It should be called on all keystone 2 platforms by default (LAPE is default mode for K2).

Huh. Below as I remember it:
- K2 starts using memory window (aliased memory) at 00 8000 0000 (No IO coherency is supported)
- K2, early at boot, is switching to LPAE memory window 08 0000 0000 (IO coherency is supported)
   so all, already mapped memory, has to be fixed - phys addresses.


-- 
Best regards,
grygorii


From eballetbo at gmail.com  Tue Aug  3 03:27:26 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:27:26 +0200
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
Message-ID: <CAFqH_527RL56P=zEg7yTaeeqTvFOjT3ThxpX-Qumk25dR6+-bA@mail.gmail.com>

Hi Eizan,

Thank you for your patch.

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:14:
>
> ... Instead of depending on the presence of a mediatek,vpu property in

Looks like there is something missing in the commit message?

> the device node.
>
> That property was originally added to link to the vpu node so that the
> mtk_mdp_core driver could pass the right device to
> vpu_wdt_reg_handler(). However in a previous patch in this series,
> the driver has been modified to search the device tree for that node
> instead.
>
> That property was also used to indicate the primary MDP device, so that
> it can be passed to the V4L2 subsystem as well as register it to be
> used when setting up queues in the open() callback for the filesystem
> device node that is created. In this case, assuming that the primary
> MDP device is the one with a specific alias seems useable because the
> alternative is to add a property to the device tree which doesn't
> actually represent any facet of hardware (i.e., this being the primary
> MDP device is a software decision). In other words, this solution is
> equally as arbitrary, but at least it doesn't add a property to a
> device node where said property is unrelated to the hardware present.
>
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>

Other than the above,

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>



> ---
>
> (no changes since v1)
>
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
>  2 files changed, 64 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 85ef274841a3..9527649de98e 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
>                 mtk_smi_larb_put(comp->larb_dev);
>  }
>
> -static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
> +/*
> + * The MDP master device node is identified by the device tree alias
> + * "mdp-rdma0".
> + */
> +static bool is_mdp_master(struct device *dev)
> +{
> +       struct device_node *aliases, *mdp_rdma0_node;
> +       const char *mdp_rdma0_path;
> +
> +       if (!dev->of_node)
> +               return false;
> +
> +       aliases = of_find_node_by_path("/aliases");
> +       if (!aliases) {
> +               dev_err(dev, "no aliases found for mdp-rdma0");
> +               return false;
> +       }
> +
> +       mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
> +       if (!mdp_rdma0_path) {
> +               dev_err(dev, "get mdp-rdma0 property of /aliases failed");
> +               return false;
> +       }
> +
> +       mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
> +       if (!mdp_rdma0_node) {
> +               dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
> +               return false;
> +       }
> +
> +       return dev->of_node == mdp_rdma0_node;
> +}
> +
> +static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
> +                       void *data)
>  {
>         struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>         struct mtk_mdp_dev *mdp = data;
> -       struct device_node *vpu_node;
>
>         mtk_mdp_register_component(mdp, comp);
>
> -       /*
> -        * If this component has a "mediatek-vpu" property, it is responsible for
> -        * notifying the mdp master driver about it so it can be further initialized
> -        * later.
> -        */
> -       vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> -       if (vpu_node) {
> +       if (is_mdp_master(dev)) {
>                 int ret;
>
> -               mdp->vpu_dev = of_find_device_by_node(vpu_node);
> -               if (WARN_ON(!mdp->vpu_dev)) {
> -                       dev_err(dev, "vpu pdev failed\n");
> -                       of_node_put(vpu_node);
> -               }
> -
>                 ret = v4l2_device_register(dev, &mdp->v4l2_dev);
>                 if (ret) {
>                         dev_err(dev, "Failed to register v4l2 device\n");
> @@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
>                 }
>
>                 /*
> -                * presence of the "mediatek,vpu" property in a device node
> -                * indicates that it is the primary MDP rdma device and MDP DMA
> -                * ops should be handled by its DMA callbacks.
> +                * MDP DMA ops will be handled by the DMA callbacks associated with this
> +                * device;
>                  */
>                 mdp->rdma_dev = dev;
>         }
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index 50eafcc9993d..6a775463399c 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
>
>  static int mtk_mdp_master_bind(struct device *dev)
>  {
> -       int status;
>         struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> +       struct device_node *vpu_node;
> +       int status;
>
>         status = component_bind_all(dev, mdp);
>         if (status) {
> @@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
>                 goto err_component_bind_all;
>         }
>
> -       if (mdp->vpu_dev) {
> -               int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
> -                                         VPU_RST_MDP);
> -               if (ret) {
> -                       dev_err(dev, "Failed to register reset handler\n");
> -                       goto err_wdt_reg;
> -               }
> -       } else {
> -               dev_err(dev, "no vpu_dev found\n");
> +       if (mdp->rdma_dev == NULL) {
> +               dev_err(dev, "Primary MDP device not found");
> +               status = -ENODEV;
> +               goto err_component_bind_all;
> +       }
> +
> +       vpu_node = of_find_node_by_name(NULL, "vpu");
> +       if (!vpu_node) {
> +               dev_err(dev, "unable to find vpu node");
> +               status = -ENODEV;
> +               goto err_wdt_reg;
> +       }
> +
> +       mdp->vpu_dev = of_find_device_by_node(vpu_node);
> +       if (!mdp->vpu_dev) {
> +               dev_err(dev, "unable to find vpu device");
> +               status = -ENODEV;
> +               goto err_wdt_reg;
> +       }
> +
> +       status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
> +       if (status) {
> +               dev_err(dev, "Failed to register reset handler\n");
> +               goto err_wdt_reg;
>         }
>
>         status = mtk_mdp_register_m2m_device(mdp);
> --
> 2.32.0.554.ge1b32706d8-goog
>


From Dave.Martin at arm.com  Tue Aug  3 03:26:21 2021
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 3 Aug 2021 11:26:21 +0100
Subject: [PATCH v4 3/4] kselftest/arm64: Add tests for SVE vector
 configuration
In-Reply-To: <20210729173713.4534-4-broonie@kernel.org>
References: <20210729173713.4534-1-broonie@kernel.org>
 <20210729173713.4534-4-broonie@kernel.org>
Message-ID: <20210803102620.GF25258@arm.com>

On Thu, Jul 29, 2021 at 06:37:12PM +0100, Mark Brown wrote:
> We provide interfaces for configuring the SVE vector length seen by
> processes using prctl and also via /proc for configuring the default
> values. Provide tests that exercise all these interfaces and verify that
> they take effect as expected, though at present no test fully enumerates
> all the possible vector lengths.
> 
> A subset of this is already tested via sve-probe-vls but the /proc
> interfaces are not currently covered at all.
> 
> In preparation for the forthcoming support for SME, the Scalable Matrix
> Extension, which has separately but similarly configured vector lengths
> which we expect to offer similar userspace interfaces for, all the actual
> files and prctls used are parameterised and we don't validate that the
> architectural minimum vector length is the minimum we see.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  tools/testing/selftests/arm64/fp/.gitignore   |   1 +
>  tools/testing/selftests/arm64/fp/Makefile     |   3 +-
>  tools/testing/selftests/arm64/fp/vec-syscfg.c | 594 ++++++++++++++++++
>  3 files changed, 597 insertions(+), 1 deletion(-)
>  create mode 100644 tools/testing/selftests/arm64/fp/vec-syscfg.c

[...]

> diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
> new file mode 100644
> index 000000000000..15fec1aaeec6
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c

[...]

> +static int stdio_read_integer(FILE *f, const char *what, int *val)
> +{
> +	int ret, n;
> +

n needs to be initialised to 0, since fscanf won't touch it if there is
a matching failure before it reaches the %n conversion.

With that,

Reviewed-by: Dave Martin <Dave.Martin at arm.com>

(One minor coment below, but that's just in relation to a possibly
future test.)

> +	ret = fscanf(f, "%d%*1[\n]%n", val, &n);
> +	if (ret < 1 || n < 1) {
> +		ksft_print_msg("%d %d %d\n", ret, n, *val);
> +		ksft_print_msg("failed to parse VL from %s\n", what);
> +		return -1;
> +	}
> +
> +	return 0;
> +}

[...]

> +/* If we didn't request it a new VL shouldn't affect the child */
> +static void prctl_set_for_child(struct vec_data *data)
> +{
> +	int ret, child_vl;
> +
> +	if (data->min_vl == data->max_vl) {
> +		ksft_test_result_skip("%s only one VL supported\n",
> +				      data->name);
> +		return;
> +	}
> +
> +	ret = prctl(data->prctl_set, data->min_vl | PR_SVE_VL_INHERIT);
> +	if (ret < 0) {
> +		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
> +				      data->name, data->min_vl,
> +				      errno, strerror(errno));
> +		return;
> +	}
> +
> +	/* The _INHERIT flag should be present when we read the VL */
> +	ret = prctl(data->prctl_get);
> +	if (ret == -1) {
> +		ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
> +				      data->name, errno, strerror(errno));
> +		return;
> +	}
> +	if (!(ret & PR_SVE_VL_INHERIT)) {
> +		ksft_test_result_fail("%s prctl() does not report _INHERIT\n",
> +				      data->name);
> +		return;
> +	}

It occurs to me that tt would make sense to test that the
PR_SVE_VL_INHERIT flag (or lack thereof) does the right thing for
further execs in the child.  If reposting, it could make sense to add
this as a TODO, but don't sweat it otherwise.

[...]

Cheers
---Dave


From eballetbo at gmail.com  Tue Aug  3 03:29:52 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 12:29:52 +0200
Subject: [PATCH v6 0/9] Refactor MTK MDP driver into core/components
In-Reply-To: <20210802121215.703023-1-eizan@chromium.org>
References: <20210802121215.703023-1-eizan@chromium.org>
Message-ID: <CAFqH_51ZYwokcWAV0tg5z3vBhHmP3MHGKYf=jWDCa78RSYpifw@mail.gmail.com>

Hi all,

Missatge de Eizan Miyamoto <eizan at chromium.org> del dia dl., 2 d?ag.
2021 a les 14:12:
>
>
> This is an update to
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=283075
> To address some comments and fixes.
>
> This series has been verified to work on 5.13.
>

The series have also been validated on top of 5.14-rc4 and linux-next
on an Acer Chromebook R 13 without observing any problems and running
some video decoding tests, so, for the full series.

Tested-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>

>
> Changes in v6:
> - Don't propagate errors from clock_on/off as an afterthought.
> - Split apart modifying mdp driver to be loadable from mmsys from
>   actually loading it from mmsys into two changs to make review easier.
> - Update devicetree bindings to reflect no longer needing the
>   mediatek,vpu property in the mdp_rdma0 device node.
> - Some stylistic cleanups.
>
> Changes in v5:
> - rebase and test on 5.13-next @ e2f74b13dbe6
>
> Changes in v4:
> - rebase and test on 5.13
> - don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873
>
> Changes in v3:
> - get mdp master from aliases instead of strcmp against of_node->name
>
> Changes in v2:
> - rebased onto Linux 5.12
> - 100 char line length allowance was utilized in a few places
> - Removal of a redundant dev_err() print at the end of
>   mtk_mdp_comp_init()
> - Instead of printing errors and ignoring them, I've added a patch to
>   correctly propagate them.
> - Use of C style comments.
> - Three additional patches were added to eliminate dependency on the
>   mediatek,vpu property inside the mdp_rdma0 device node.
>
> Eizan Miyamoto (9):
>   mtk-mdp: propagate errors from clock_on
>   mtk-mdp: add driver to probe mdp components
>   mtk-mdp: use pm_runtime in MDP component driver
>   media: mtk-mdp: don't pm_run_time_get/put for master comp in clock_on
>   mtk-mdp: make mdp driver to be loadable by platform_device_register*()
>   soc: mediatek: mmsys: instantiate mdp virtual device from mmsys
>   media: mtk-mdp: use mdp-rdma0 alias to point to MDP master
>   dts: mtk-mdp: remove mediatek,vpu property from primary MDP device
>   dt-bindings: mediatek: remove vpu requirement from mtk-mdp
>
>  .../bindings/media/mediatek-mdp.txt           |   3 -
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi      |   1 -
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 268 +++++++++++++++--
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  34 +--
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 282 ++++++++++++------
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   3 +
>  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |   4 +-
>  drivers/soc/mediatek/mtk-mmsys.c              |  20 +-
>  8 files changed, 470 insertions(+), 145 deletions(-)
>
> --
> 2.32.0.554.ge1b32706d8-goog
>


From qperret at google.com  Tue Aug  3 03:34:09 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 3 Aug 2021 11:34:09 +0100
Subject: [PATCH v3 17/21] KVM: arm64: Mark host bss and rodata section as
 shared
In-Reply-To: <CA+EHjTwfsA8Z+_dJzqjsBXJ_SSC55Bcxc6HQ_Q4OJDrqmk0Unw@mail.gmail.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-18-qperret@google.com>
 <CA+EHjTwfsA8Z+_dJzqjsBXJ_SSC55Bcxc6HQ_Q4OJDrqmk0Unw@mail.gmail.com>
Message-ID: <YQkboRdFP9oPVJgn@google.com>

On Tuesday 03 Aug 2021 at 07:02:42 (+0200), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Thu, Jul 29, 2021 at 3:29 PM Quentin Perret <qperret at google.com> wrote:
> >
> > As the hypervisor maps the host's .bss and .rodata sections in its
> > stage-1, make sure to tag them as shared in hyp and host page-tables.
> >
> > But since the hypervisor relies on the presence of these mappings, we
> > cannot let the host in complete control of the memory regions -- it
> > must not unshare or donate them to another entity for example. To
> > prevent this, let's transfer the ownership of those ranges to the
> > hypervisor itself, and share the pages back with the host.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/nvhe/setup.c | 82 +++++++++++++++++++++++++++++----
> >  1 file changed, 74 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> > index 0b574d106519..7f557b264f62 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> > @@ -58,6 +58,7 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
> >  {
> >         void *start, *end, *virt = hyp_phys_to_virt(phys);
> >         unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT;
> > +       enum kvm_pgtable_prot prot;
> >         int ret, i;
> >
> >         /* Recreate the hyp page-table using the early page allocator */
> > @@ -83,10 +84,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
> >         if (ret)
> >                 return ret;
> >
> > -       ret = pkvm_create_mappings(__start_rodata, __end_rodata, PAGE_HYP_RO);
> > -       if (ret)
> > -               return ret;
> > -
> >         ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO);
> >         if (ret)
> >                 return ret;
> > @@ -95,10 +92,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
> >         if (ret)
> >                 return ret;
> >
> > -       ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, PAGE_HYP_RO);
> > -       if (ret)
> > -               return ret;
> > -
> >         ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP);
> >         if (ret)
> >                 return ret;
> > @@ -117,6 +110,24 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
> >                         return ret;
> >         }
> >
> > +       /*
> > +        * Map the host's .bss and .rodata sections RO in the hypervisor, but
> > +        * transfer the ownerhsip from the host to the hypervisor itself to
> > +        * make sure it can't be donated or shared with another entity.
> 
> nit: ownerhsip -> ownership
> 
> > +        *
> > +        * The ownership transtion requires matching changes in the host
> 
> nit: transtion -> transition
> 
> > +        * stage-2. This will done later (see finalize_host_mappings()) once the
> 
> nit: will done -> will be done

Urgh, I clearly went too fast writing this, thanks!

> > +        * hyp_vmemmap is addressable.
> > +        */
> > +       prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
> > +       ret = pkvm_create_mappings(__start_rodata, __end_rodata, prot);
> > +       if (ret)
> > +               return ret;
> > +
> > +       ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, prot);
> 
> nit: for clarity, I wonder if it might be good to create an alias of
> __hyp_bss_end as __bss_start or something. When it's been moved here,
> it sticks out a bit more and makes the reader wonder about the
> significance of __hyp_bss_end.

I understand what you mean, but I'm not sure this aliasing is really
going to clarify things much. We have a comment in arm.c (see
init_hyp_mode()) to explain exactly why we're doing this, so maybe it
would be worth adding it here too. WDYT?

> > +       if (ret)
> > +               return ret;
> > +
> >         return 0;
> >  }
> >
> > @@ -148,6 +159,57 @@ static void hpool_put_page(void *addr)
> >         hyp_put_page(&hpool, addr);
> >  }
> >
> > +static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
> > +                                        kvm_pte_t *ptep,
> > +                                        enum kvm_pgtable_walk_flags flag,
> > +                                        void * const arg)
> > +{
> > +       enum kvm_pgtable_prot prot;
> > +       enum pkvm_page_state state;
> > +       kvm_pte_t pte = *ptep;
> > +       phys_addr_t phys;
> > +
> > +       if (!kvm_pte_valid(pte))
> > +               return 0;
> > +
> > +       if (level != (KVM_PGTABLE_MAX_LEVELS - 1))
> > +               return -EINVAL;
> 
> I know that it's not in scope here, but I'm wondering whether we
> should be checking for KVM_PTE_TYPE_PAGE instead of the level. Maybe

Well these would check different things no?

> it would be good to have a helper somewhere for all these checks both
> for clarity and to ensure that nothing has gone wrong with the pte.

The reason I need this check is just to make sure the call to
host_stage2_idmap_locked() further down is correct with a hardcoded
PAGE_SIZE size. The alternative would be to not be lazy and actually
compute the current granule size based on the level and use that, as
that would make this code robust to using block mappings at EL2 stage-1
in the future.

And I'll fix this up for v4.

Cheers,
Quentin

> > +
> > +       phys = kvm_pte_to_phys(pte);
> > +       if (!addr_is_memory(phys))
> > +               return 0;
> > +
> > +       /*
> > +        * Adjust the host stage-2 mappings to match the ownership attributes
> > +        * configured in the hypervisor stage-1.
> > +        */
> > +       state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte));
> > +       switch (state) {
> > +       case PKVM_PAGE_OWNED:
> > +               return host_stage2_set_owner_locked(phys, phys + PAGE_SIZE, pkvm_hyp_id);
> > +       case PKVM_PAGE_SHARED_OWNED:
> > +               prot = pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_BORROWED);
> > +               break;
> > +       case PKVM_PAGE_SHARED_BORROWED:
> > +               prot = pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_OWNED);
> > +               break;
> > +       default:
> > +               return -EINVAL;
> > +       }
> > +
> > +       return host_stage2_idmap_locked(phys, phys + PAGE_SIZE, prot);
> > +}
> > +
> > +static int finalize_host_mappings(void)
> > +{
> > +       struct kvm_pgtable_walker walker = {
> > +               .cb     = finalize_host_mappings_walker,
> > +               .flags  = KVM_PGTABLE_WALK_LEAF,
> > +       };
> > +
> > +       return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker);
> > +}
> > +
> >  void __noreturn __pkvm_init_finalise(void)
> >  {
> >         struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data);
> > @@ -167,6 +229,10 @@ void __noreturn __pkvm_init_finalise(void)
> >         if (ret)
> >                 goto out;
> >
> > +       ret = finalize_host_mappings();
> > +       if (ret)
> > +               goto out;
> > +
> >         pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) {
> >                 .zalloc_page = hyp_zalloc_hyp_page,
> >                 .phys_to_virt = hyp_phys_to_virt,
> > --
> > 2.32.0.432.gabb21c7263-goog
> >
> 
> Thanks,
> /fuad


From andy.shevchenko at gmail.com  Tue Aug  3 03:33:38 2021
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Tue, 3 Aug 2021 13:33:38 +0300
Subject: [RFC PATCH 0/6] leds: Fix pca955x GPIO pin mappings
In-Reply-To: <50aaf381-8cda-4656-9222-f23fda75d3bc@www.fastmail.com>
References: <20210723075858.376378-1-andrew@aj.id.au>
 <CAHp75VeQML7njMZ6x8kC-ZJVexC1xJ6n1cB3JneVMAVfuOJgWw@mail.gmail.com>
 <d019990e-a725-4ef5-bb54-aadee9d18b86@www.fastmail.com>
 <CAHp75Vc2W+WmwNj1AvH6EiT_80c+5gADV9QzK+asHxpd1Ucppw@mail.gmail.com>
 <6cc64039-f82a-4c1e-ad2c-16fad7aa3178@www.fastmail.com>
 <CAHp75Vdx9QA7dmSWK8GHxBBxP0uYjrz=Gm=75yqaWbBX6k3v=w@mail.gmail.com>
 <50aaf381-8cda-4656-9222-f23fda75d3bc@www.fastmail.com>
Message-ID: <CAHp75Ve-6zKE9UX+LR022cGAA6xvd8CeLnnKE_fT3snnzmNusA@mail.gmail.com>

On Tue, Aug 3, 2021 at 7:07 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> On Thu, 29 Jul 2021, at 17:10, Andy Shevchenko wrote:
> > On Thu, Jul 29, 2021 at 3:39 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> > > On Wed, 28 Jul 2021, at 18:43, Andy Shevchenko wrote:
> > > > On Wed, Jul 28, 2021 at 8:43 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> > > > > However, userspace would never have
> > > > > got the results it expected with the existing driver implementation, so
> > > > > I guess you could argue that no such (useful) userspace exists. Given
> > > > > that, we could adopt the strategy of always defining a gpiochip
> > > > > covering the whole pin space, and parts of the devicetree binding just
> > > > > become redundant.
> > > >
> > > > I'm lost now. GPIO has its own userspace ABI, how does it work right
> > > > now in application to this chip?
> > >
> > > As above, it "works" if the GPIOs specified in the devicetree are
> > > contiguous from line 0. It's broken if they're not.
> >
> > So, "it never works" means there is no bug. Now, what we need is to
> > keep the same enumeration scheme, but if you wish to be used half/half
> > (or any other ratio), the driver should do like the above mentioned
> > PWM, i.e. register entire space and depending on the requestor either
> > proceed with a line or mark it as BUSY.
> >
> > Ideally, looking into what the chip can do, this should be indeed
> > converted to some like pin control + PWM + LED + GPIO drivers. Then
> > the function in pin mux configuration can show what exactly is enabled
> > on the certain line(s).
>
> So just to clarify, you want both solutions here?
>
> 1. A gpiochip that covers the entire pin space
> 2. A pinmux implementation that manages pin allocation to the different drivers
>
> In that case we can largely leave this series as is? We only need to
> adjust how we configure the gpiochip by dropping the pin-mapping
> implementation?

Nope. It's far from what I think of. Re-reading again your cover
letter it points out that pin mux per se does not exist in the
hardware. In this case things become a bit too complicated, but we
still may manage to handle them. Before I was thinking about this
hierarchy

1. pinmux driver (which is actually the main driver here)
2. LED driver (using regmap API)
3. GPIO driver (via gpio-regmap)
4. PWM driver.

Now what we need here is some kind of "virtual" pinmux. Do I
understand correctly?

To be clear: I do not like putting everything into one driver when the
logical parts may be separated.

-- 
With Best Regards,
Andy Shevchenko


From catalin.marinas at arm.com  Tue Aug  3 03:34:41 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 3 Aug 2021 11:34:41 +0100
Subject: [PATCH] arm64/mm: Fix idmap on [16K|36VA|48PA]
In-Reply-To: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com>
References: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210803103440.GA5786@arm.com>

On Mon, Aug 02, 2021 at 10:12:39AM +0530, Anshuman Khandual wrote:
> When creating the idmap, the kernel may add one extra level to idmap memory
> outside the VA range. But for [16K|36VA|48PA], we need two levels to reach
> 48 bits. If the bootloader places the kernel in memory above (1 << 46), the

Did you mean (1 << 36)?

> kernel will fail to enable the MMU. Although we are not aware of a platform
> where this happens, it is worth to accommodate such scenarios and prevent a
> possible kernel crash.
> 
> Lets fix the problem on the above configuration by creating two additional
> idmap page table levels when 'idmap_text_end' is outside the VA range. This
> reduces 'idmap_t0sz' to cover the entire PA range which would prevent table
> misconfiguration (fault) when a given 'idmap_t0sz' value requires a single
> additional page table level where as two have been built.
[...]
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index c5c994a..da33bbc 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -329,7 +329,9 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
>  
>  #if (VA_BITS < 48)
>  #define EXTRA_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
> +#define EXTRA_SHIFT_1	(EXTRA_SHIFT + PAGE_SHIFT - 3)
>  #define EXTRA_PTRS	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT))
> +#define EXTRA_PTRS_1	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT_1))
>  
>  	/*
>  	 * If VA_BITS < 48, we have to configure an additional table level.
> @@ -342,8 +344,30 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
>  #error "Mismatch between VA_BITS and page size/number of translation levels"
>  #endif
>  
> +/*
> + * In this particular CONFIG_ARM64_16K_PAGES config, there might be a
> + * scenario where 'idmap_text_end' ends up high enough in the PA range
> + * requiring two additional idmap page table levels. Reduce idmap_t0sz
> + * to cover the entire PA range. This prevents table misconfiguration
> + * when a given idmap_t0sz value just requires single additional level
> + * where as two levels have been built.
> + */
> +#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_PA_BITS_48)
> +	mov	x4, EXTRA_PTRS_1
> +	create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6
> +
> +	mov	x4, PTRS_PER_PTE
> +	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
> +
> +	mov	x5, #64 - PHYS_MASK_SHIFT
> +	adr_l	x6, idmap_t0sz
> +	str	x5, [x6]
> +	dmb	sy
> +	dc	ivac, x6
> +#else
>  	mov	x4, EXTRA_PTRS
>  	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
> +#endif
>  #else
>  	/*
>  	 * If VA_BITS == 48, we don't have to configure an additional

There's a prior idmap_t0sz setting based on __idmap_text_end. Isn't that
sufficient? We don't care about covering the whole PA space, just the
__idmap_text_end.

-- 
Catalin


From will at kernel.org  Tue Aug  3 03:36:00 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 3 Aug 2021 11:36:00 +0100
Subject: [PATCH v2 23/24] iommu/arm-smmu: Allow non-strict in
 pgtable_quirks interface
In-Reply-To: <3dd7cdae-7111-6ff2-6350-a0e19fe4ab66@arm.com>
References: <cover.1627468308.git.robin.murphy@arm.com>
 <0fcd1f5225a6b435cbc697551a6247cd435c04db.1627468310.git.robin.murphy@arm.com>
 <20210802130438.GA28547@willie-the-truck>
 <3dd7cdae-7111-6ff2-6350-a0e19fe4ab66@arm.com>
Message-ID: <20210803103559.GA30690@willie-the-truck>

On Mon, Aug 02, 2021 at 03:15:50PM +0100, Robin Murphy wrote:
> On 2021-08-02 14:04, Will Deacon wrote:
> > On Wed, Jul 28, 2021 at 04:58:44PM +0100, Robin Murphy wrote:
> > > To make io-pgtable aware of a flush queue being dynamically enabled,
> > > allow IO_PGTABLE_QUIRK_NON_STRICT to be set even after a domain has been
> > > attached to, and hook up the final piece of the puzzle in iommu-dma.
> > > 
> > > Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> > > ---
> > >   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++++++++
> > >   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 11 +++++++++++
> > >   drivers/iommu/dma-iommu.c                   |  3 +++
> > >   3 files changed, 29 insertions(+)
> > > 
> > > diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > index 19400826eba7..40fa9cb382c3 100644
> > > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > @@ -2711,6 +2711,20 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
> > >   	return ret;
> > >   }
> > > +static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
> > > +		unsigned long quirks)
> > > +{
> > > +	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> > > +
> > > +	if (quirks == IO_PGTABLE_QUIRK_NON_STRICT && smmu_domain->pgtbl_ops) {
> > > +		struct io_pgtable *iop = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
> > > +
> > > +		iop->cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
> > > +		return 0;
> > > +	}
> > > +	return -EINVAL;
> > > +}
> > 
> > I don't see anything serialising this against a concurrent iommu_unmap(), so
> > the ordering and atomicity looks quite suspicious to me here. I don't think
> > it's just the page-table quirks either, but also setting cookie->fq_domain.
> 
> Heh, I confess to very much taking the cheeky "let's say nothing and see
> what Will thinks about concurrency" approach here :)

Damnit, I fell for that didn't I?

Overall, I'm really nervous about the concurrency here and think we'd be
better off requiring the unbind as we have for the other domain changes.

> The beauty of only allowing relaxation in the strict->non-strict direction
> is that it shouldn't need serialising as such - it doesn't matter if the
> update to cookie->fq_domain is observed between iommu_unmap() and
> iommu_dma_free_iova(), since there's no correctness impact to queueing IOVAs
> which may already have been invalidated and may or may not have been synced.
> AFAICS the only condition which matters is that the setting of the
> io-pgtable quirk must observe fq_domain being set. It feels like there must
> be enough dependencies on the read side, but we might need an smp_wmb()
> between the two in iommu_dma_init_fq()?
> 
> I've also flip-flopped a bit on whether fq_domain needs to be accessed with
> READ_ONCE/WRITE_ONCE - by the time of posting I'd convinced myself that it
> was probably OK, but looking again now I suppose this wacky reordering is
> theoretically possible:
> 
> 
> 	iommu_dma_unmap() {
> 		bool free_fq = cookie->fq_domain; // == false
> 
> 		iommu_unmap();
> 
> 		if (!cookie->fq_domain) // observes new non-NULL value
> 			iommu_tlb_sync(); // skipped
> 
> 		iommu_dma_free_iova { // inlined
> 			if (free_fq) // false
> 				queue_iova();
> 			else
> 				free_iova_fast(); // Uh-oh!
> 		}
> 	}
> 
> so although I still can't see atomicity being a problem I guess we do need
> it for the sake of reordering at least.

With your changes, I think quite a few things can go wrong.

  * cookie->fq_domain may be observed but iovad->fq could be NULL
  * We can miss the smp_wmb() in the pgtable code but end up deferring the
    IOVA reclaim
  * iommu_change_dev_def_domain() only holds the group mutex afaict, so can
    possibly run concurrently with itself on the same domain?
  * iommu_dma_init_fq() can flip the domain type back from
    IOMMU_DOMAIN_DMA_FQ to IOMMU_DOMAIN_DMA on the error path
  * set_pgtable_quirks() isn't atomic, which probably is ok for now, but the
    moment we use it anywhere else it's dangerous

and I suspect there are more :/

Will


From qperret at google.com  Tue Aug  3 03:37:05 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 3 Aug 2021 11:37:05 +0100
Subject: [PATCH v3 19/21] KVM: arm64: Refactor protected nVHE stage-1
 locking
In-Reply-To: <CA+EHjTwWt+jvRZsk5KEhQWzn+XqdV2gZSq7oCuOCVXRa1=JiWw@mail.gmail.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-20-qperret@google.com>
 <CA+EHjTwWt+jvRZsk5KEhQWzn+XqdV2gZSq7oCuOCVXRa1=JiWw@mail.gmail.com>
Message-ID: <YQkcUXnrqp7hsZZT@google.com>

Hey Fuad,

On Tuesday 03 Aug 2021 at 07:31:03 (+0200), Fuad Tabba wrote:
> Hi Quentin,
> 
> On Thu, Jul 29, 2021 at 3:29 PM Quentin Perret <qperret at google.com> wrote:
> >
> > Refactor the hypervisor stage-1 locking in nVHE protected mode to expose
> > a new pkvm_create_mappings_locked() function. This will be used in later
> > patches to allow walking and changing the hypervisor stage-1 without
> > releasing the lock.
> >
> > Signed-off-by: Quentin Perret <qperret at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/nvhe/mm.h |  1 +
> >  arch/arm64/kvm/hyp/nvhe/mm.c         | 18 ++++++++++++++++--
> >  2 files changed, 17 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> > index 8ec3a5a7744b..c76d7136ed9b 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> > @@ -23,6 +23,7 @@ int hyp_map_vectors(void);
> >  int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
> >  int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
> >  int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
> > +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
> >  int __pkvm_create_mappings(unsigned long start, unsigned long size,
> >                            unsigned long phys, enum kvm_pgtable_prot prot);
> >  unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
> > index a8efdf0f9003..6fbe8e8030f6 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mm.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mm.c
> > @@ -67,13 +67,15 @@ unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
> >         return addr;
> >  }
> >
> > -int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> > +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot)
> >  {
> >         unsigned long start = (unsigned long)from;
> >         unsigned long end = (unsigned long)to;
> >         unsigned long virt_addr;
> >         phys_addr_t phys;
> >
> > +       hyp_assert_lock_held(&pkvm_pgd_lock);
> > +
> >         start = start & PAGE_MASK;
> >         end = PAGE_ALIGN(end);
> >
> > @@ -81,7 +83,8 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> >                 int err;
> >
> >                 phys = hyp_virt_to_phys((void *)virt_addr);
> > -               err = __pkvm_create_mappings(virt_addr, PAGE_SIZE, phys, prot);
> > +               err = kvm_pgtable_hyp_map(&pkvm_pgtable, virt_addr, PAGE_SIZE,
> > +                                         phys, prot);
> >                 if (err)
> >                         return err;
> >         }
> > @@ -89,6 +92,17 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> >         return 0;
> >  }
> >
> > +int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> > +{
> > +       int ret;
> > +
> > +       hyp_spin_lock(&pkvm_pgd_lock);
> > +       ret = pkvm_create_mappings_locked(from, to, prot);
> > +       hyp_spin_unlock(&pkvm_pgd_lock);
> > +
> > +       return ret;
> > +}
> > +
> 
> I'm wondering whether this patch should also refactor
> __pkvm_create_mappings. It doesn't quite do the exact same thing and
> has different parameters.

Sorry, not sure I'm understanding your suggestion here. What do you
think should be done to __pkvm_create_mappings?

Cheers,
Quentin


From Mason.Zhang at mediatek.com  Tue Aug  3 03:22:29 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Tue, 3 Aug 2021 18:22:29 +0800
Subject: [PATCH v2 0/4] *** spi cs_timing restructure ***
Message-ID: <20210803102228.2535-1-Mason.Zhang@mediatek.com>

Hello,
This patchset has restructure spi cs_timing, as we know spi core has
removed spi_set_cs_timing() API, it is a correct decision because it
asked spi devices to call it in one more time.
so we need find another way to support user set cs_timing. Actually,
spi_device set spi_delay for cs_timing is enough, and about how to
set cs_timing, just put it one the master driver.
We have test this patch in mediatek platform, it can compeletly meets
our needs.

Changed in v2:
  - fix tegra spi build err

Mason Zhang (4):
  spi: move cs spi_delay to spi_device
  spi: modify set_cs_timing parameter
  spi: mediatek: modify set_cs_timing callback
  spi: tegra114: Fix set_cs_timing param

 drivers/spi/spi-mt65xx.c   | 102 ++++++++++++++++++++-----------------
 drivers/spi/spi-tegra114.c |   8 +--
 drivers/spi/spi.c          |   6 +--
 include/linux/spi/spi.h    |  23 ++++-----
 4 files changed, 73 insertions(+), 66 deletions(-)

-- 
2.18.0

From Mason.Zhang at mediatek.com  Tue Aug  3 03:23:34 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Tue, 3 Aug 2021 18:23:34 +0800
Subject: [PATCH v2 1/4] spi: move cs spi_delay to spi_device
Message-ID: <20210803102333.22568-1-Mason.Zhang@mediatek.com>

As we know, spi core layer has removed spi_set_cs_timing() API.
So this patch moved spi_delay for cs_timing from spi_controller
to spi_device, because cs timing should be set by spi_device but
not controller.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 drivers/spi/spi.c       |  6 +++---
 include/linux/spi/spi.h | 20 +++++++++-----------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c99181165321..5d68e6cd2a18 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -842,9 +842,9 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
 	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
 	    !spi->controller->set_cs_timing) {
 		if (activate)
-			spi_delay_exec(&spi->controller->cs_setup, NULL);
+			spi_delay_exec(&spi->cs_setup, NULL);
 		else
-			spi_delay_exec(&spi->controller->cs_hold, NULL);
+			spi_delay_exec(&spi->cs_hold, NULL);
 	}
 
 	if (spi->mode & SPI_CS_HIGH)
@@ -887,7 +887,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
 	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
 	    !spi->controller->set_cs_timing) {
 		if (!activate)
-			spi_delay_exec(&spi->controller->cs_inactive, NULL);
+			spi_delay_exec(&spi->cs_inactive, NULL);
 	}
 }
 
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 97b8d12b5f2b..651e19ba3415 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -147,7 +147,11 @@ extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer);
  *	not using a GPIO line)
  * @word_delay: delay to be inserted between consecutive
  *	words of a transfer
- *
+ * @cs_setup: delay to be introduced by the controller after CS is asserted
+ * @cs_hold: delay to be introduced by the controller before CS is deasserted
+ * @cs_inactive: delay to be introduced by the controller after CS is
+ *	deasserted. If @cs_change_delay is used from @spi_transfer, then the
+ *	two delays will be added up.
  * @statistics: statistics for the spi_device
  *
  * A @spi_device is used to interchange data between an SPI slave
@@ -188,6 +192,10 @@ struct spi_device {
 	int			cs_gpio;	/* LEGACY: chip select gpio */
 	struct gpio_desc	*cs_gpiod;	/* chip select gpio desc */
 	struct spi_delay	word_delay; /* inter-word delay */
+	/* CS delays */
+	struct spi_delay	cs_setup;
+	struct spi_delay	cs_hold;
+	struct spi_delay	cs_inactive;
 
 	/* the statistics */
 	struct spi_statistics	statistics;
@@ -412,11 +420,6 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
  *	     controller has native support for memory like operations.
  * @unprepare_message: undo any work done by prepare_message().
  * @slave_abort: abort the ongoing transfer request on an SPI slave controller
- * @cs_setup: delay to be introduced by the controller after CS is asserted
- * @cs_hold: delay to be introduced by the controller before CS is deasserted
- * @cs_inactive: delay to be introduced by the controller after CS is
- *	deasserted. If @cs_change_delay is used from @spi_transfer, then the
- *	two delays will be added up.
  * @cs_gpios: LEGACY: array of GPIO descs to use as chip select lines; one per
  *	CS number. Any individual value may be -ENOENT for CS lines that
  *	are not GPIOs (driven by the SPI controller itself). Use the cs_gpiods
@@ -638,11 +641,6 @@ struct spi_controller {
 	/* Optimized handlers for SPI memory-like operations. */
 	const struct spi_controller_mem_ops *mem_ops;
 
-	/* CS delays */
-	struct spi_delay	cs_setup;
-	struct spi_delay	cs_hold;
-	struct spi_delay	cs_inactive;
-
 	/* gpio chip select */
 	int			*cs_gpios;
 	struct gpio_desc	**cs_gpiods;
-- 
2.18.0

From u.kleine-koenig at pengutronix.de  Tue Aug  3 03:40:12 2021
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 3 Aug 2021 12:40:12 +0200
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <162797831443.714452.3551045763456936564@swboyd.mtv.corp.google.com>
References: <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <06e799be-b7c0-5b93-8586-678a449d2239@microchip.com>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
 <20210802094810.GJ22278@shell.armlinux.org.uk>
 <20210802152755.ibisunvibmwhiyry@pengutronix.de>
 <20210802163824.GK22278@shell.armlinux.org.uk>
 <162797831443.714452.3551045763456936564@swboyd.mtv.corp.google.com>
Message-ID: <20210803104012.wf2buscbukxufesl@pengutronix.de>

On Tue, Aug 03, 2021 at 01:11:54AM -0700, Stephen Boyd wrote:
> Quoting Russell King (Oracle) (2021-08-02 09:38:24)
> > On Mon, Aug 02, 2021 at 05:27:55PM +0200, Uwe Kleine-Konig wrote:
> > > Hello Russell,
> > > 
> > > On Mon, Aug 02, 2021 at 10:48:10AM +0100, Russell King (Oracle) wrote:
> > 
> > > > There have been several different approaches to wrapping things up,
> > > > but here's a question: should we make it easier to do the lazy thing
> > > > (get+enable) or should we make it easier to be power efficient?
> > > > Shouldn't we be encouraging people to write power efficient drivers?
> > > 
> > > Yeah, sounds compelling, but I wonder if that's of practical importance.
> > > How many driver authors do you expect to lure into making a better
> > > driver just because devm_clk_get_prepared() doesn't exist? In contrast:
> > > How many drivers become simpler with devm_clk_get_prepared() and so
> > > it becomes easier to maintain them and easier to spot bugs?
> > > In the absence of devm_clk_get_prepared(), is it better that several
> > > frameworks (or drivers) open code it?
> > 
> > It probably depends on where you stand on power management and power
> > efficiency issues. Personally, I would like to see more effort put
> > into drivers to make them more power efficient, and I believe in the
> > coming years, power efficiency is going to become a big issue.
> > 
> 
> I agree we should put more effort into power efficiency in the kernel.
> I've occasionally heard from driver writers that they never will turn
> the clk off even in low power modes though. They feel like it's a
> nuisance to have to do anything with the clk framework in their driver.
> When I say "why not use runtime PM?" I get told that they're not turning
> the clk off because it needs to be on all the time, so using runtime PM
> makes the driver more complicated, not less, and adds no value. I think
> some touchscreens are this way, and watchdogs too. Looking at the
> drivers being converted in this series I suspect RTC is one of those
> sorts of devices as well. But SPI and I2C most likely could benefit from
> using runtime PM and so those ones don't feel appropriate to convert.
> 
> Maybe this series would be more compelling if those various drivers that
> are hand rolling the devm action were converted to the consolidated
> official devm function. The truth is it's already happening in various
> subsystems so consolidating that logic into one place would be a win
> code size wise and very hard to ignore.
> 
> Doing
> 
>  $ git grep devm_add_action | grep clk
> 
> seems to catch quite a few of them.

Another upside is that grepping for these drivers with a potential for
further improvement become easier to grep for as
devm_clk_get_{prepared,enabled} is a much better hint :-)

The changes to these drivers probably won't go through a clk tree, so
adding these patches before adding devm_clk_get_enabled() would only
help for the warm and cozy feeling that it is right to do so, correct?

As my focus is limited to (mostly) drivers/pwm and I already have quite
some other patch quests on my list:

So can I lure you in merging the new functions and I will create a
kernel janitor task to convert more existing drivers?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210803/1659805c/attachment.sig>

From Mason.Zhang at mediatek.com  Tue Aug  3 03:24:02 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Tue, 3 Aug 2021 18:24:02 +0800
Subject: [PATCH v2 2/4] spi: modify set_cs_timing parameter
Message-ID: <20210803102401.30920-1-Mason.Zhang@mediatek.com>

No need pass in spi_delay to set_cs_timing callback.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 include/linux/spi/spi.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 651e19ba3415..fe027efb85c2 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -553,8 +553,7 @@ struct spi_controller {
 	 * to configure specific CS timing through spi_set_cs_timing() after
 	 * spi_setup().
 	 */
-	int (*set_cs_timing)(struct spi_device *spi, struct spi_delay *setup,
-			     struct spi_delay *hold, struct spi_delay *inactive);
+	int (*set_cs_timing)(struct spi_device *spi);
 
 	/* bidirectional bulk transfers
 	 *
-- 
2.18.0

From Mason.Zhang at mediatek.com  Tue Aug  3 03:24:29 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Tue, 3 Aug 2021 18:24:29 +0800
Subject: [PATCH v2 3/4] spi: mediatek: modify set_cs_timing callback
Message-ID: <20210803102428.6476-1-Mason.Zhang@mediatek.com>

This patch modified set_cs_timing callback:
  1 support spi_device set cs_timing in their driver;
  2 support set absolute time but no clk count, because;
    clk src will change in different platform;
  3 call this function in prepare_message but not in other API.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 102 +++++++++++++++++++++------------------
 1 file changed, 56 insertions(+), 46 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 6f2925118b98..7a34f5b1201d 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -208,6 +208,60 @@ static void mtk_spi_reset(struct mtk_spi *mdata)
 	writel(reg_val, mdata->base + SPI_CMD_REG);
 }
 
+static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
+{
+	struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
+	struct spi_delay *cs_setup = &spi->cs_setup;
+	struct spi_delay *cs_hold = &spi->cs_hold;
+	struct spi_delay *cs_inactive = &spi->cs_inactive;
+	u16 setup, hold, inactive;
+	u32 reg_val;
+	int delay;
+
+	delay = spi_delay_to_ns(cs_setup, NULL);
+	if (delay < 0)
+		return delay;
+	setup = (delay / 1000) * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000);
+
+	delay = spi_delay_to_ns(cs_hold, NULL);
+	if (delay < 0)
+		return delay;
+	hold = (delay / 1000) * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000);
+
+	delay = spi_delay_to_ns(cs_inactive, NULL);
+	if (delay < 0)
+		return delay;
+	inactive = (delay / 1000) * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000);
+
+	setup    = setup ? setup : 1;
+	hold     = hold ? hold : 1;
+	inactive = inactive ? inactive : 1;
+
+	reg_val = readl(mdata->base + SPI_CFG0_REG);
+	if (mdata->dev_comp->enhance_timing) {
+		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
+		reg_val |= (((hold - 1) & 0xffff)
+			   << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
+		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
+		reg_val |= (((setup - 1) & 0xffff)
+			   << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
+	} else {
+		reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
+		reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+		reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
+		reg_val |= (((setup - 1) & 0xff)
+			    << SPI_CFG0_CS_SETUP_OFFSET);
+	}
+	writel(reg_val, mdata->base + SPI_CFG0_REG);
+
+	reg_val = readl(mdata->base + SPI_CFG1_REG);
+	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
+	reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+	writel(reg_val, mdata->base + SPI_CFG1_REG);
+
+	return 0;
+}
+
 static int mtk_spi_prepare_message(struct spi_master *master,
 				   struct spi_message *msg)
 {
@@ -284,6 +338,8 @@ static int mtk_spi_prepare_message(struct spi_master *master,
 		<< SPI_CFG1_GET_TICK_DLY_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
 
+	/* set hw cs timing */
+	mtk_spi_set_hw_cs_timing(spi);
 	return 0;
 }
 
@@ -528,52 +584,6 @@ static bool mtk_spi_can_dma(struct spi_master *master,
 		(unsigned long)xfer->rx_buf % 4 == 0);
 }
 
-static int mtk_spi_set_hw_cs_timing(struct spi_device *spi,
-				    struct spi_delay *setup,
-				    struct spi_delay *hold,
-				    struct spi_delay *inactive)
-{
-	struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
-	u16 setup_dly, hold_dly, inactive_dly;
-	u32 reg_val;
-
-	if ((setup && setup->unit != SPI_DELAY_UNIT_SCK) ||
-	    (hold && hold->unit != SPI_DELAY_UNIT_SCK) ||
-	    (inactive && inactive->unit != SPI_DELAY_UNIT_SCK)) {
-		dev_err(&spi->dev,
-			"Invalid delay unit, should be SPI_DELAY_UNIT_SCK\n");
-		return -EINVAL;
-	}
-
-	setup_dly = setup ? setup->value : 1;
-	hold_dly = hold ? hold->value : 1;
-	inactive_dly = inactive ? inactive->value : 1;
-
-	reg_val = readl(mdata->base + SPI_CFG0_REG);
-	if (mdata->dev_comp->enhance_timing) {
-		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
-		reg_val |= (((hold_dly - 1) & 0xffff)
-			   << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
-		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
-		reg_val |= (((setup_dly - 1) & 0xffff)
-			   << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
-	} else {
-		reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
-		reg_val |= (((hold_dly - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
-		reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
-		reg_val |= (((setup_dly - 1) & 0xff)
-			    << SPI_CFG0_CS_SETUP_OFFSET);
-	}
-	writel(reg_val, mdata->base + SPI_CFG0_REG);
-
-	reg_val = readl(mdata->base + SPI_CFG1_REG);
-	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
-	reg_val |= (((inactive_dly - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
-	writel(reg_val, mdata->base + SPI_CFG1_REG);
-
-	return 0;
-}
-
 static int mtk_spi_setup(struct spi_device *spi)
 {
 	struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
-- 
2.18.0

From Mason.Zhang at mediatek.com  Tue Aug  3 03:25:18 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Tue, 3 Aug 2021 18:25:18 +0800
Subject: [PATCH v2 4/4] spi: tegra114: Fix set_cs_timing param
Message-ID: <20210803102517.20944-1-Mason.Zhang@mediatek.com>

This patch fixed set_cs_timing param, because cs timing delay has
been moved to spi_device.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 drivers/spi/spi-tegra114.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 5131141bbf0d..e9de1d958bbd 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -717,12 +717,12 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
 	dma_release_channel(dma_chan);
 }
 
-static int tegra_spi_set_hw_cs_timing(struct spi_device *spi,
-				      struct spi_delay *setup,
-				      struct spi_delay *hold,
-				      struct spi_delay *inactive)
+static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
 {
 	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
+	struct spi_delay *setup = &spi->cs_setup;
+	struct spi_delay *hold = &spi->cs_hold;
+	struct spi_delay *inactive = &spi->cs_inactive;
 	u8 setup_dly, hold_dly, inactive_dly;
 	u32 setup_hold;
 	u32 spi_cs_timing;
-- 
2.18.0

From qperret at google.com  Tue Aug  3 03:43:26 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 3 Aug 2021 11:43:26 +0100
Subject: [PATCH v3 20/21] KVM: arm64: Restrict EL2 stage-1 changes in
 protected mode
In-Reply-To: <CA+EHjTw7W=5JqH+oZAqLPrf_6222eazDnSk24h4EuGE1VLwKYg@mail.gmail.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-21-qperret@google.com>
 <CA+EHjTw7W=5JqH+oZAqLPrf_6222eazDnSk24h4EuGE1VLwKYg@mail.gmail.com>
Message-ID: <YQkdztIHwXfj7Sbc@google.com>

On Tuesday 03 Aug 2021 at 10:22:03 (+0200), Fuad Tabba wrote:
> Hi Quentin,
> 
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index 0ccea58df7e0..1b67f562b6fc 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -338,6 +338,95 @@ static int host_stage2_idmap(u64 addr)
> >         return ret;
> >  }
> >
> > +static inline bool check_prot(enum kvm_pgtable_prot prot,
> > +                             enum kvm_pgtable_prot required,
> > +                             enum kvm_pgtable_prot denied)
> > +{
> > +       return (prot & (required | denied)) == required;
> > +}
> > +
> > +int __pkvm_host_share_hyp(u64 pfn)
> > +{
> > +       phys_addr_t addr = hyp_pfn_to_phys(pfn);
> > +       enum kvm_pgtable_prot prot, cur;
> > +       void *virt = __hyp_va(addr);
> > +       enum pkvm_page_state state;
> > +       kvm_pte_t pte;
> > +       u32 level;
> > +       int ret;
> > +
> > +       if (!range_is_memory(addr, addr + PAGE_SIZE))
> > +               return -EINVAL;
> > +
> > +       hyp_spin_lock(&host_kvm.lock);
> > +       hyp_spin_lock(&pkvm_pgd_lock);
> > +
> > +       ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, &level);
> > +       if (ret)
> > +               goto unlock;
> > +       if (!pte)
> > +               goto map_shared;
> 
> Should this check whether kvm_pte_valid as well, is that guaranteed to
> always be the case, or implicitly handled later?

Yep, this is implicitly handled by kvm_pgtable_stage2_pte_prot() which
is guaranteed not to return KVM_PGTABLE_PROT_RWX for an invalid mapping.

> > +
> > +       /*
> > +        * Check attributes in the host stage-2 PTE. We need the page to be:
> > +        *  - mapped RWX as we're sharing memory;
> > +        *  - not borrowed, as that implies absence of ownership.
> > +        * Otherwise, we can't let it got through
> > +        */
> > +       cur = kvm_pgtable_stage2_pte_prot(pte);
> > +       prot = pkvm_mkstate(0, PKVM_PAGE_SHARED_BORROWED);
> > +       if (!check_prot(cur, KVM_PGTABLE_PROT_RWX, prot)) {
> > +               ret = -EPERM;
> > +               goto unlock;
> > +       }
> > +
> > +       state = pkvm_getstate(cur);
> > +       if (state == PKVM_PAGE_OWNED)
> > +               goto map_shared;
> > +
> > +       /*
> > +        * Tolerate double-sharing the same page, but this requires
> > +        * cross-checking the hypervisor stage-1.
> > +        */
> > +       if (state != PKVM_PAGE_SHARED_OWNED) {
> > +               ret = -EPERM;
> > +               goto unlock;
> > +       }
> > +
> > +       ret = kvm_pgtable_get_leaf(&pkvm_pgtable, (u64)virt, &pte, &level);
> > +       if (ret)
> > +               goto unlock;
> > +
> > +       /*
> > +        * If the page has been shared with the hypervisor, it must be
> > +        * SHARED_BORROWED already.
> > +        */
> 
> This comment confused me at first, but then I realized it's referring
> to the page from the hyp's point of view. Could you add something to
> the comment to that effect?

Sure thing.

> It might also make it easier to follow if the variables could be
> annotated to specify whether cur, state, and prot are the host's or
> hyps (and not reuse the same one for both).
> 
> > +       cur = kvm_pgtable_hyp_pte_prot(pte);
> > +       prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
> > +       if (!check_prot(cur, prot, ~prot))
> > +               ret = EPERM;
> > +       goto unlock;
> > +
> > +map_shared:
> > +       /*
> > +        * If the page is not yet shared, adjust mappings in both page-tables
> > +        * while both locks are held.
> > +        */
> > +       prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
> > +       ret = pkvm_create_mappings_locked(virt, virt + PAGE_SIZE, prot);
> > +       BUG_ON(ret);
> > +
> > +       prot = pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_OWNED);
> > +       ret = host_stage2_idmap_locked(addr, addr + PAGE_SIZE, prot);
> > +       BUG_ON(ret);
> > +
> > +unlock:
> > +       hyp_spin_unlock(&pkvm_pgd_lock);
> > +       hyp_spin_unlock(&host_kvm.lock);
> > +
> > +       return ret;
> > +}
> > +
> >  void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
> >  {
> >         struct kvm_vcpu_fault_info fault;
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index 0625bf2353c2..cbab146cda6a 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -259,10 +259,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size,
> >  {
> >         int err;
> >
> > -       if (!kvm_host_owns_hyp_mappings()) {
> > -               return kvm_call_hyp_nvhe(__pkvm_create_mappings,
> > -                                        start, size, phys, prot);
> > -       }
> > +       if (WARN_ON(!kvm_host_owns_hyp_mappings()))
> > +               return -EINVAL;
> >
> >         mutex_lock(&kvm_hyp_pgd_mutex);
> >         err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot);
> > @@ -282,6 +280,21 @@ static phys_addr_t kvm_kaddr_to_phys(void *kaddr)
> >         }
> >  }
> >
> > +static int pkvm_share_hyp(phys_addr_t start, phys_addr_t end)
> > +{
> > +       phys_addr_t addr;
> > +       int ret;
> > +
> > +       for (addr = ALIGN_DOWN(start, PAGE_SIZE); addr < end; addr += PAGE_SIZE) {
> > +               ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp,
> > +                                       __phys_to_pfn(addr));
> 
> I guess we don't expect this to happen often, but I wonder if it would
> be better to have the looping in the hyp call rather than here, to
> reduce the number of hyp calls when sharing.

Yes, I was wondering the same thing, but ended up doing the looping here
to avoid spending long periods of time in a non-preemptible state at
EL2. Probably doesn't make a big difference for now, but it might if we
ever need to share large memory regions.

Cheers,
Quentin

> 
> Thanks,
> /fuad
> 
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> >  /**
> >   * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode
> >   * @from:      The virtual kernel start address of the range
> > @@ -302,6 +315,13 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> >         if (is_kernel_in_hyp_mode())
> >                 return 0;
> >
> > +       if (!kvm_host_owns_hyp_mappings()) {
> > +               if (WARN_ON(prot != PAGE_HYP))
> > +                       return -EPERM;
> > +               return pkvm_share_hyp(kvm_kaddr_to_phys(from),
> > +                                     kvm_kaddr_to_phys(to));
> > +       }
> > +
> >         start = start & PAGE_MASK;
> >         end = PAGE_ALIGN(end);
> >
> > --
> > 2.32.0.432.gabb21c7263-goog
> >


From tabba at google.com  Tue Aug  3 03:43:30 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 3 Aug 2021 12:43:30 +0200
Subject: [PATCH v3 10/21] KVM: arm64: Enable forcing page-level stage-2
 mappings
In-Reply-To: <YQkWuCVkKWJX81en@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-11-qperret@google.com>
 <CA+EHjTxCvqQ=jmBPJ1N6ShBf=f4J5cjT4pt9akfnqNjQUoqzWw@mail.gmail.com>
 <YQkWuCVkKWJX81en@google.com>
Message-ID: <CA+EHjTwamSQ+msUUnuCi6c_hw5TzDy-7dSxLxEnGmA4T4uhw_Q@mail.gmail.com>

Hi Quentin,

> > > +static bool stage2_block_mapping_allowed(u64 addr, u64 end, u32 level,
> > > +                                        struct stage2_map_data *data)
> > > +{
> > > +       if (data->force_pte && (level < (KVM_PGTABLE_MAX_LEVELS - 1)))
> > > +               return false;
> >
> > I'm not sure I understand why checking the level is necessary. Can
> > there be block mapping at the last possible level?
>
> That's probably just a matter of naming, but this function is in fact
> called at every level, just like kvm_block_mapping_supported() was
> before. And we rely on it returning true at the last level, so I need to
> do that check here.
>
> Maybe renaming this stage2_leaf_mapping_allowed() would clarify?

Yes it would.

Thanks,
/fuad


From linux at armlinux.org.uk  Tue Aug  3 03:49:33 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 3 Aug 2021 11:49:33 +0100
Subject: [PATCH 3/3] ARM: Map the lowmem and kernel separately
In-Reply-To: <f3eb9c84-19c6-cba2-ffcc-2dbcb48051ad@ti.com>
References: <20210517145719.110966-1-linus.walleij@linaro.org>
 <20210517145719.110966-4-linus.walleij@linaro.org>
 <20210730202259.dbifugsvry5vjdr7@earthen>
 <CACRpkdYAzGzqfdREogAFnyGqSnHLQmdCR=GZ=YqhzoTUA0MfCA@mail.gmail.com>
 <f3eb9c84-19c6-cba2-ffcc-2dbcb48051ad@ti.com>
Message-ID: <20210803104932.GM22278@shell.armlinux.org.uk>

On Tue, Aug 03, 2021 at 01:27:18PM +0300, Grygorii Strashko wrote:
> 
> 
> On 31/07/2021 01:40, Linus Walleij wrote:
> > On Fri, Jul 30, 2021 at 10:23 PM Nishanth Menon <nm at ti.com> wrote:
> > > On 16:57-20210517, Linus Walleij wrote:
> > > > Using our knowledge of where the physical kernel sections start
> > > > and end we can split mapping of lowmem and kernel apart.
> > > > 
> > > [...]
> > > > 
> > > > Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> > > 
> > > 
> > > We noticed a regression in k2g platforms with this patch.
> > > commit 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel
> > > separately")
> > > 
> > > Boot log: https://pastebin.ubuntu.com/p/Sf3r28D8MR/
> > > Bisect log: https://pastebin.ubuntu.com/p/6PTYpNVFDy/
> > 
> > Given how invasive the patch is I'm surprised that k2g is the
> > only thing so far complaining about it. Let's fix this!
> > 
> > I've had similar reports and in those cases it has been that the boot
> > loader did not turn off the caches before jumping to execute the
> > Linux kernel.
> > 
> > So first can you check that cache is off?
> > 
> > Next can you turn on DEBUG_LL and enable the debug messages
> > in arch/arm/mmu.c in map_lowmem() in some way that works for
> > you, for example I just add a patch like this:
> > https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/patch/?id=d10c46631a6eaef1339e376b878de985143b27ff
> > (Beware of ugly debug habits!)
> > 
> > Next is this using the keystone 2 pv fixup thing  mdesc->pv_fixup
> > mdesc->pv_fixup in early_paging_init()?
> > 
> > I added a special print
> > there to see if that gets called. This code is really scary but I
> > suppose Santosh can explain what is supposed to happen here
> > and what I may have stepped on. (I see Santosh work at Oracle
> > now? Interesting.)
> 
> It should be called on all keystone 2 platforms by default (LAPE is default mode for K2).
> 
> Huh. Below as I remember it:
> - K2 starts using memory window (aliased memory) at 00 8000 0000 (No IO coherency is supported)
> - K2, early at boot, is switching to LPAE memory window 08 0000 0000 (IO coherency is supported)
>   so all, already mapped memory, has to be fixed - phys addresses.

If I remember correctly, the code that fixes that up assumes that
(a) the kernel is mapped using section mappings in the lowmem mapping
    at PAGE_OFFSET.._end-1
(b) that no other RAM is mapped (iow, it's called before the kernel
    starts building the real page mappings in paging_init()).

It looks to me like Linus missed the code in arch/arm/mm/pv-fixup-asm.S
and as the kernel is no longer mapped in the lowmem mapping, this
likely writes a load of entries in the page tables that are random...

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From tabba at google.com  Tue Aug  3 03:51:14 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 3 Aug 2021 12:51:14 +0200
Subject: [PATCH v3 19/21] KVM: arm64: Refactor protected nVHE stage-1
 locking
In-Reply-To: <YQkcUXnrqp7hsZZT@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-20-qperret@google.com>
 <CA+EHjTwWt+jvRZsk5KEhQWzn+XqdV2gZSq7oCuOCVXRa1=JiWw@mail.gmail.com>
 <YQkcUXnrqp7hsZZT@google.com>
Message-ID: <CA+EHjTye7hA7XqGSx5DvqXAcVaA9HYkC-rqeQ5fnQY7MdpHkFw@mail.gmail.com>

Hi Quentin,

> > > +int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> > > +{
> > > +       int ret;
> > > +
> > > +       hyp_spin_lock(&pkvm_pgd_lock);
> > > +       ret = pkvm_create_mappings_locked(from, to, prot);
> > > +       hyp_spin_unlock(&pkvm_pgd_lock);
> > > +
> > > +       return ret;
> > > +}
> > > +
> >
> > I'm wondering whether this patch should also refactor
> > __pkvm_create_mappings. It doesn't quite do the exact same thing and
> > has different parameters.
>
> Sorry, not sure I'm understanding your suggestion here. What do you
> think should be done to __pkvm_create_mappings?

Sorry, my comment wasn't very clear, and "refactor" is the wrong word.
I think it should probably be renamed, because __pkvm_create_mappings
isn't called by pkvm_create_mappings nor by
pkvm_create_mappings_locked. It also has different parameters and
behaves slightly differently.

Thanks,
/fuad

> Cheers,
> Quentin


From lorenzo.pieralisi at arm.com  Tue Aug  3 03:52:52 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue, 3 Aug 2021 11:52:52 +0100
Subject: [PATCH v2 0/6] PCI: Add support for J7200 and AM64
In-Reply-To: <20210803074932.19820-1-kishon@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
Message-ID: <20210803105252.GD11252@lpieralisi>

On Tue, Aug 03, 2021 at 01:19:26PM +0530, Kishon Vijay Abraham I wrote:
> This series adds the compatible specific to J7200 and AM64 and
> applies the erratas and configuration specific to them.
> 
> This series also includes Nadeem's patch that adds a quirk in
> Cadence driver which is used by J7200 [1].
> 
> The DT binding for both J7200 and AM64 is already merged.
> 
> v1 of the patch series can be found at [2]
> 
> Changes from v1:
> 1) As suggested by Bjorn, used unsigned int :1, instead of bool for
> structure members
> 2) Removed using unnecessary local variables and also fixed some
> code alignment
> 
> [1] -> https://lore.kernel.org/r/20210528155626.21793-1-nadeem at cadence.com
> [2] -> https://lore.kernel.org/r/20210706105035.9915-1-kishon at ti.com
> 
> Kishon Vijay Abraham I (5):
>   PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
>   PCI: j721e: Add PCIe support for J7200
>   PCI: j721e: Add PCIe support for AM64
>   misc: pci_endpoint_test: Do not request or allocate IRQs in probe
>   misc: pci_endpoint_test: Add deviceID for AM64 and J7200
> 
> Nadeem Athani (1):
>   PCI: cadence: Add quirk flag to set minimum delay in LTSSM
>     Detect.Quiet state
> 
>  drivers/misc/pci_endpoint_test.c              | 27 ++++++--
>  drivers/pci/controller/cadence/pci-j721e.c    | 61 +++++++++++++++++--
>  .../pci/controller/cadence/pcie-cadence-ep.c  |  4 ++
>  .../controller/cadence/pcie-cadence-host.c    |  3 +
>  drivers/pci/controller/cadence/pcie-cadence.c | 17 ++++++
>  drivers/pci/controller/cadence/pcie-cadence.h | 17 +++++-
>  6 files changed, 117 insertions(+), 12 deletions(-)

I am not convinced about patch (5) the rest of the series can be
merged (even though I assume patch (6) depends on (5)).

Please let me know,
Lorenzo


From tabba at google.com  Tue Aug  3 03:54:32 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 3 Aug 2021 12:54:32 +0200
Subject: [PATCH v3 17/21] KVM: arm64: Mark host bss and rodata section as
 shared
In-Reply-To: <YQkboRdFP9oPVJgn@google.com>
References: <20210729132818.4091769-1-qperret@google.com>
 <20210729132818.4091769-18-qperret@google.com>
 <CA+EHjTwfsA8Z+_dJzqjsBXJ_SSC55Bcxc6HQ_Q4OJDrqmk0Unw@mail.gmail.com>
 <YQkboRdFP9oPVJgn@google.com>
Message-ID: <CA+EHjTym0agkuzuy1ZnxU7QbL4jP1xmW4sX2YixBCVo5cSKzog@mail.gmail.com>

Hi Quentin,

> > > +       ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, prot);
> >
> > nit: for clarity, I wonder if it might be good to create an alias of
> > __hyp_bss_end as __bss_start or something. When it's been moved here,
> > it sticks out a bit more and makes the reader wonder about the
> > significance of __hyp_bss_end.
>
> I understand what you mean, but I'm not sure this aliasing is really
> going to clarify things much. We have a comment in arm.c (see
> init_hyp_mode()) to explain exactly why we're doing this, so maybe it
> would be worth adding it here too. WDYT?

Not sure to be honest. Comments are good, until they're stale, and
replicating the comment increases the odds of that happening. No
strong opinion either way.

> > > +       if (ret)
> > > +               return ret;
> > > +
> > >         return 0;
> > >  }
> > >
> > > @@ -148,6 +159,57 @@ static void hpool_put_page(void *addr)
> > >         hyp_put_page(&hpool, addr);
> > >  }
> > >
> > > +static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
> > > +                                        kvm_pte_t *ptep,
> > > +                                        enum kvm_pgtable_walk_flags flag,
> > > +                                        void * const arg)
> > > +{
> > > +       enum kvm_pgtable_prot prot;
> > > +       enum pkvm_page_state state;
> > > +       kvm_pte_t pte = *ptep;
> > > +       phys_addr_t phys;
> > > +
> > > +       if (!kvm_pte_valid(pte))
> > > +               return 0;
> > > +
> > > +       if (level != (KVM_PGTABLE_MAX_LEVELS - 1))
> > > +               return -EINVAL;
> >
> > I know that it's not in scope here, but I'm wondering whether we
> > should be checking for KVM_PTE_TYPE_PAGE instead of the level. Maybe
>
> Well these would check different things no?
>
> > it would be good to have a helper somewhere for all these checks both
> > for clarity and to ensure that nothing has gone wrong with the pte.
>
> The reason I need this check is just to make sure the call to
> host_stage2_idmap_locked() further down is correct with a hardcoded
> PAGE_SIZE size. The alternative would be to not be lazy and actually
> compute the current granule size based on the level and use that, as
> that would make this code robust to using block mappings at EL2 stage-1
> in the future.
>
> And I'll fix this up for v4.

I get it now. Thanks!
/fuad


> Cheers,
> Quentin
>
> > > +
> > > +       phys = kvm_pte_to_phys(pte);
> > > +       if (!addr_is_memory(phys))
> > > +               return 0;
> > > +
> > > +       /*
> > > +        * Adjust the host stage-2 mappings to match the ownership attributes
> > > +        * configured in the hypervisor stage-1.
> > > +        */
> > > +       state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte));
> > > +       switch (state) {
> > > +       case PKVM_PAGE_OWNED:
> > > +               return host_stage2_set_owner_locked(phys, phys + PAGE_SIZE, pkvm_hyp_id);
> > > +       case PKVM_PAGE_SHARED_OWNED:
> > > +               prot = pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_BORROWED);
> > > +               break;
> > > +       case PKVM_PAGE_SHARED_BORROWED:
> > > +               prot = pkvm_mkstate(KVM_PGTABLE_PROT_RWX, PKVM_PAGE_SHARED_OWNED);
> > > +               break;
> > > +       default:
> > > +               return -EINVAL;
> > > +       }
> > > +
> > > +       return host_stage2_idmap_locked(phys, phys + PAGE_SIZE, prot);
> > > +}
> > > +
> > > +static int finalize_host_mappings(void)
> > > +{
> > > +       struct kvm_pgtable_walker walker = {
> > > +               .cb     = finalize_host_mappings_walker,
> > > +               .flags  = KVM_PGTABLE_WALK_LEAF,
> > > +       };
> > > +
> > > +       return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker);
> > > +}
> > > +
> > >  void __noreturn __pkvm_init_finalise(void)
> > >  {
> > >         struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data);
> > > @@ -167,6 +229,10 @@ void __noreturn __pkvm_init_finalise(void)
> > >         if (ret)
> > >                 goto out;
> > >
> > > +       ret = finalize_host_mappings();
> > > +       if (ret)
> > > +               goto out;
> > > +
> > >         pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) {
> > >                 .zalloc_page = hyp_zalloc_hyp_page,
> > >                 .phys_to_virt = hyp_phys_to_virt,
> > > --
> > > 2.32.0.432.gabb21c7263-goog
> > >
> >
> > Thanks,
> > /fuad


From patchwork-bot+netdevbpf at kernel.org  Tue Aug  3 04:00:06 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Tue, 03 Aug 2021 11:00:06 +0000
Subject: [PATCH] net: sparx5: fix bitmask on 32-bit targets
In-Reply-To: <20210802152201.1158412-1-arnd@kernel.org>
References: <20210802152201.1158412-1-arnd@kernel.org>
Message-ID: <162798840606.8237.17724316386643673744.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (refs/heads/master):

On Mon,  2 Aug 2021 17:21:53 +0200 you wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> I saw the build failure that was fixed in commit 6387f65e2acb ("net:
> sparx5: fix compiletime_assert for GCC 4.9") and noticed another
> issue that was introduced in the same patch: Using GENMASK() to
> create a 64-bit mask does not work on 32-bit architectures.
> 
> [...]

Here is the summary with links:
  - net: sparx5: fix bitmask on 32-bit targets
    https://git.kernel.org/netdev/net/c/f41e57af926a

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From mason.zhang at mediatek.com  Tue Aug  3 03:52:50 2021
From: mason.zhang at mediatek.com (Mason Zhang)
Date: Tue, 3 Aug 2021 18:52:50 +0800
Subject: [PATCH 2/3] spi: modify set_cs_timing parameter
In-Reply-To: <1627960488.7721.2.camel@mbjsdccf07>
References: <20210719091642.24633-1-mason.zhang@mediatek.com>
 <20210802201614.GA39900@sirena.org.uk> <1627960488.7721.2.camel@mbjsdccf07>
Message-ID: <1627987970.27248.4.camel@mbjsdccf07>

On Tue, 2021-08-03 at 11:14 +0800, Mason Zhang wrote:
> Dear Mark:
> 
> 	I have fixed this build err in this patch:
> 
> https://lore.kernel.org/linux-spi/20210803021328.28291-1-Mason.Zhang at mediatek.com/T/#u
> 
> 
> Thanks
> Mason

Dear Mark:

	I have submit this change separately, but still have build err, so I
have updated the patch v2 as below:

https://lore.kernel.org/linux-spi/20210803102228.2535-1-Mason.Zhang at mediatek.com/T/#u

Thanks
Mason

From anshuman.khandual at arm.com  Tue Aug  3 04:27:04 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 3 Aug 2021 16:57:04 +0530
Subject: [PATCH] arm64/mm: Fix idmap on [16K|36VA|48PA]
In-Reply-To: <20210803103440.GA5786@arm.com>
References: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com>
 <20210803103440.GA5786@arm.com>
Message-ID: <7bad50a2-76f1-7946-3a15-35e46fb289c0@arm.com>



On 8/3/21 4:04 PM, Catalin Marinas wrote:
> On Mon, Aug 02, 2021 at 10:12:39AM +0530, Anshuman Khandual wrote:
>> When creating the idmap, the kernel may add one extra level to idmap memory
>> outside the VA range. But for [16K|36VA|48PA], we need two levels to reach
>> 48 bits. If the bootloader places the kernel in memory above (1 << 46), the
> 
> Did you mean (1 << 36)?

No it is actually (1 << 47). If __idmap_text_end is beyond (1 << 47), a single
additional page table level in idmap would not be sufficient to map it. Rather
two more levels would be required. A single additional page table level covers
(PAGE_SHIFT - 3 = 14 - 3 = 11) bits on 16K pages.

First  additional page table level covers	VA(36) --> (47)
Second additional page table level covers	VA(48) --> (48)

> 
>> kernel will fail to enable the MMU. Although we are not aware of a platform
>> where this happens, it is worth to accommodate such scenarios and prevent a
>> possible kernel crash.
>>
>> Lets fix the problem on the above configuration by creating two additional
>> idmap page table levels when 'idmap_text_end' is outside the VA range. This
>> reduces 'idmap_t0sz' to cover the entire PA range which would prevent table
>> misconfiguration (fault) when a given 'idmap_t0sz' value requires a single
>> additional page table level where as two have been built.
> [...]
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index c5c994a..da33bbc 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -329,7 +329,9 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
>>  
>>  #if (VA_BITS < 48)
>>  #define EXTRA_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
>> +#define EXTRA_SHIFT_1	(EXTRA_SHIFT + PAGE_SHIFT - 3)
>>  #define EXTRA_PTRS	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT))
>> +#define EXTRA_PTRS_1	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT_1))
>>  
>>  	/*
>>  	 * If VA_BITS < 48, we have to configure an additional table level.
>> @@ -342,8 +344,30 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
>>  #error "Mismatch between VA_BITS and page size/number of translation levels"
>>  #endif
>>  
>> +/*
>> + * In this particular CONFIG_ARM64_16K_PAGES config, there might be a
>> + * scenario where 'idmap_text_end' ends up high enough in the PA range
>> + * requiring two additional idmap page table levels. Reduce idmap_t0sz
>> + * to cover the entire PA range. This prevents table misconfiguration
>> + * when a given idmap_t0sz value just requires single additional level
>> + * where as two levels have been built.
>> + */
>> +#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_PA_BITS_48)
>> +	mov	x4, EXTRA_PTRS_1
>> +	create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6
>> +
>> +	mov	x4, PTRS_PER_PTE
>> +	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
>> +
>> +	mov	x5, #64 - PHYS_MASK_SHIFT
>> +	adr_l	x6, idmap_t0sz
>> +	str	x5, [x6]
>> +	dmb	sy
>> +	dc	ivac, x6
>> +#else
>>  	mov	x4, EXTRA_PTRS
>>  	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
>> +#endif
>>  #else
>>  	/*
>>  	 * If VA_BITS == 48, we don't have to configure an additional
> 
> There's a prior idmap_t0sz setting based on __idmap_text_end. Isn't that
> sufficient? We don't care about covering the whole PA space, just the
> __idmap_text_end.

Right but its bit tricky here.

__idmap_text_end could be any where between VA_BITS (36) and PA_BITS (48)
which would require (one or two) additional page table levels. But in this
solution it creates two additional page table levels for idmap which would
completely map upto PA_BITS, regardless of __idmap_text_end's position. So
in case __idmap_text_end is between VA_BITS (36) and VA_BITS(47), a single
additional page table level is required where as we have created two ! So
to avoid such a situation, adjust idmap_t0sz accordingly. Otherwise there
will be a MMU mis-configuration.

This patch is indented for stable back port and hence tries to be as simple
and minimal as possible. So it creates two additional page table levels
mapping upto PA_BITS without just considering __idmap_text_end's position.
Reducing __idmap_t0sz upto PA_BITS should not be a problem irrespective of
ID_AA64MMFR0_EL1.PARANGE value. As __idmap_text_end would never be on a PA
which is not supported. Hence out of range PA would never be on the bus for
translation.


From iwona.winiarska at intel.com  Tue Aug  3 04:31:19 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:19 +0200
Subject: [PATCH v2 00/15] Introduce PECI subsystem
Message-ID: <20210803113134.2262882-1-iwona.winiarska@intel.com>

Hi Greg,

This is a second round of patches introducing PECI subsystem.
I don't think it is ready to be applied right away (we're still
missing r-b's), but I hope we have chance to complete discussion in
the 5.15 development cycle. I would appreciate if you could take
a look.

Note: All changes to arch/x86 are contained within patches 01-02, plus
small Kconfig change adding "depends on PECI" to GENERIC_LIB_X86
Kconfig in patch 10.

The Platform Environment Control Interface (PECI) is a communication
interface between Intel processors and management controllers (e.g.
Baseboard Management Controller, BMC).

This series adds a PECI subsystem and introduces drivers which run in
the Linux instance on the management controller (not the main Intel
processor) and is intended to be used by the OpenBMC [1], a Linux
distribution for BMC devices.
The information exposed over PECI (like processor and DIMM
temperature) refers to the Intel processor and can be consumed by
daemons running on the BMC to, for example, display the processor
temperature in its web interface.

The PECI bus is collection of code that provides interface support
between PECI devices (that actually represent processors) and PECI
controllers (such as the "peci-aspeed" controller) that allow to
access physical PECI interface. PECI devices are bound to PECI
drivers that provides access to PECI services. This series introduces
a generic "peci-cpu" driver that exposes hardware monitoring "cputemp"
and "dimmtemp" using the auxiliary bus.

Exposing "raw" PECI to userspace, either to write userspace drivers or
for debug/testing purpose was left out of this series to encourage
writing kernel drivers instead, but may be pursued in the future.

Introducing PECI to upstream Linux was already attempted before [2].
Since it's been over a year since last revision, and the series
changed quite a bit in the meantime, I've decided to start from v1.

I would also like to give credit to everyone who helped me with
different aspects of preliminary review:
- Pierre-Louis Bossart,
- Tony Luck, 
- Andy Shevchenko,
- Dave Hansen.

[1] https://github.com/openbmc/openbmc
[2] https://lore.kernel.org/openbmc/20191211194624.2872-1-jae.hyun.yoo at linux.intel.com/

Changes v1 -> v2:

Biggest changes when it comes to diffstat are locking in HWMON
(I decided to clean things up a bit while adding it), switching to
devres usage in more places and exposing sysfs interface in separate patch.

* Moved extending X86 ARCHITECTURE MAINTAINERS earlier in series (Dan)
* Removed "default n" for GENERIC_LIB_X86 (Dan)
* Added vendor prefix for peci-aspeed specific properties (Rob)
* Refactored PECI to use devres consistently (Dan)
* Added missing sysfs documentation and excluded adding peci-sysfs to
  separate patch (Dan)
* Used module_init() instead of subsys_init() for peci module initialization (Dan)
* Removed redundant struct peci_device member (Dan)
* Improved PECI Kconfig help (Randy/Dan)
* Fixed/removed log messages (Dan, Guenter)
* Refactored peci-cputemp and peci-dimmtemp and added missing locks (Guenter)
* Removed unused dev_set_drvdata() in peci-cputemp and peci-dimmtemp (Guenter)
* Fixed used types, names, fixed broken and added additional comments
  to peci-hwmon (Guenter, Zev)
* Refactored peci-dimmtemp to not return -ETIMEDOUT (Guenter)
* Added sanity check for min_peci_revision in peci-hwmon drivers (Zev)
* Added assert for DIMM_NUMS_MAX and additional warning in peci-dimmtemp (Zev)
* Fixed macro names in peci-aspeed (Zev)
* Refactored peci-aspeed sanitizing properties to a single helper function (Zev)
* Fixed peci_cpu_device_ids definition for Broadwell Xeon D (David)
* Refactor peci_request to use a single allocation (Zev)
* Used min_t() to improve code readability (Zev)
* Added macro for PECI_RDENDPTCFG_MMIO_WR_LEN_BASE and fixed adev type
  array name to more descriptive (Zev)
* Fixed peci-hwmon commit-msg and documentation (Zev)

Thanks
-Iwona

Iwona Winiarska (13):
  x86/cpu: Move intel-family to arch-independent headers
  x86/cpu: Extract cpuid helpers to arch-independent
  dt-bindings: Add generic bindings for PECI
  dt-bindings: Add bindings for peci-aspeed
  ARM: dts: aspeed: Add PECI controller nodes
  peci: Add core infrastructure
  peci: Add device detection
  peci: Add sysfs interface for PECI bus
  peci: Add support for PECI device drivers
  peci: Add peci-cpu driver
  hwmon: peci: Add cputemp driver
  hwmon: peci: Add dimmtemp driver
  docs: Add PECI documentation

Jae Hyun Yoo (2):
  peci: Add peci-aspeed controller driver
  docs: hwmon: Document PECI drivers

 Documentation/ABI/testing/sysfs-bus-peci      |  16 +
 .../devicetree/bindings/peci/peci-aspeed.yaml | 109 ++++
 .../bindings/peci/peci-controller.yaml        |  33 +
 Documentation/hwmon/index.rst                 |   2 +
 Documentation/hwmon/peci-cputemp.rst          |  90 +++
 Documentation/hwmon/peci-dimmtemp.rst         |  57 ++
 Documentation/index.rst                       |   1 +
 Documentation/peci/index.rst                  |  16 +
 Documentation/peci/peci.rst                   |  48 ++
 MAINTAINERS                                   |  32 +
 arch/arm/boot/dts/aspeed-g4.dtsi              |  14 +
 arch/arm/boot/dts/aspeed-g5.dtsi              |  14 +
 arch/arm/boot/dts/aspeed-g6.dtsi              |  14 +
 arch/x86/Kconfig                              |   1 +
 arch/x86/include/asm/cpu.h                    |   3 -
 arch/x86/include/asm/intel-family.h           | 141 +---
 arch/x86/include/asm/microcode.h              |   2 +-
 arch/x86/kvm/cpuid.h                          |   3 +-
 arch/x86/lib/Makefile                         |   2 +-
 drivers/Kconfig                               |   3 +
 drivers/Makefile                              |   1 +
 drivers/edac/mce_amd.c                        |   3 +-
 drivers/hwmon/Kconfig                         |   2 +
 drivers/hwmon/Makefile                        |   1 +
 drivers/hwmon/peci/Kconfig                    |  31 +
 drivers/hwmon/peci/Makefile                   |   7 +
 drivers/hwmon/peci/common.h                   |  58 ++
 drivers/hwmon/peci/cputemp.c                  | 591 +++++++++++++++++
 drivers/hwmon/peci/dimmtemp.c                 | 614 ++++++++++++++++++
 drivers/peci/Kconfig                          |  37 ++
 drivers/peci/Makefile                         |  10 +
 drivers/peci/controller/Kconfig               |  16 +
 drivers/peci/controller/Makefile              |   3 +
 drivers/peci/controller/peci-aspeed.c         | 445 +++++++++++++
 drivers/peci/core.c                           | 238 +++++++
 drivers/peci/cpu.c                            | 344 ++++++++++
 drivers/peci/device.c                         | 221 +++++++
 drivers/peci/internal.h                       | 137 ++++
 drivers/peci/request.c                        | 477 ++++++++++++++
 drivers/peci/sysfs.c                          |  82 +++
 include/linux/peci-cpu.h                      |  38 ++
 include/linux/peci.h                          | 110 ++++
 include/linux/x86/cpu.h                       |   9 +
 include/linux/x86/intel-family.h              | 146 +++++
 lib/Kconfig                                   |   4 +
 lib/Makefile                                  |   2 +
 lib/x86/Makefile                              |   3 +
 {arch/x86/lib => lib/x86}/cpu.c               |   2 +-
 48 files changed, 4084 insertions(+), 149 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-peci
 create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.yaml
 create mode 100644 Documentation/devicetree/bindings/peci/peci-controller.yaml
 create mode 100644 Documentation/hwmon/peci-cputemp.rst
 create mode 100644 Documentation/hwmon/peci-dimmtemp.rst
 create mode 100644 Documentation/peci/index.rst
 create mode 100644 Documentation/peci/peci.rst
 create mode 100644 drivers/hwmon/peci/Kconfig
 create mode 100644 drivers/hwmon/peci/Makefile
 create mode 100644 drivers/hwmon/peci/common.h
 create mode 100644 drivers/hwmon/peci/cputemp.c
 create mode 100644 drivers/hwmon/peci/dimmtemp.c
 create mode 100644 drivers/peci/Kconfig
 create mode 100644 drivers/peci/Makefile
 create mode 100644 drivers/peci/controller/Kconfig
 create mode 100644 drivers/peci/controller/Makefile
 create mode 100644 drivers/peci/controller/peci-aspeed.c
 create mode 100644 drivers/peci/core.c
 create mode 100644 drivers/peci/cpu.c
 create mode 100644 drivers/peci/device.c
 create mode 100644 drivers/peci/internal.h
 create mode 100644 drivers/peci/request.c
 create mode 100644 drivers/peci/sysfs.c
 create mode 100644 include/linux/peci-cpu.h
 create mode 100644 include/linux/peci.h
 create mode 100644 include/linux/x86/cpu.h
 create mode 100644 include/linux/x86/intel-family.h
 create mode 100644 lib/x86/Makefile
 rename {arch/x86/lib => lib/x86}/cpu.c (95%)

-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:20 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:20 +0200
Subject: [PATCH v2 01/15] x86/cpu: Move intel-family to arch-independent
 headers
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-2-iwona.winiarska@intel.com>

Baseboard management controllers (BMC) often run Linux but are usually
implemented with non-X86 processors. They can use PECI to access package
config space (PCS) registers on the host CPU and since some information,
e.g. figuring out the core count, can be obtained using different
registers on different CPU generations, they need to decode the family
and model.

Move the data from arch/x86/include/asm/intel-family.h into a new file
include/linux/x86/intel-family.h so that it can be used by other
architectures.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Tony Luck <tony.luck at intel.com>
Reviewed-by: Dan Williams <dan.j.williams at intel.com>
---
To limit tree-wide changes and help people that were expecting
intel-family defines in arch/x86 to find it more easily without going
through git history, we're not removing the original header
completely, we're keeping it as a "stub" that includes the new one.
If there is a consensus that the tree-wide option is better,
we can choose this approach.

 MAINTAINERS                         |   2 +
 arch/x86/include/asm/intel-family.h | 141 +--------------------------
 include/linux/x86/intel-family.h    | 146 ++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 140 deletions(-)
 create mode 100644 include/linux/x86/intel-family.h

diff --git a/MAINTAINERS b/MAINTAINERS
index c9467d2839f5..104773d40952 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9241,6 +9241,7 @@ M:	x86 at kernel.org
 L:	linux-kernel at vger.kernel.org
 S:	Supported
 F:	arch/x86/include/asm/intel-family.h
+F:	include/linux/x86/intel-family.h
 
 INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
 M:	Jani Nikula <jani.nikula at linux.intel.com>
@@ -20105,6 +20106,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core
 F:	Documentation/devicetree/bindings/x86/
 F:	Documentation/x86/
 F:	arch/x86/
+F:	include/linux/x86/
 
 X86 ENTRY CODE
 M:	Andy Lutomirski <luto at kernel.org>
diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
index 27158436f322..0d4fe1b4e1f6 100644
--- a/arch/x86/include/asm/intel-family.h
+++ b/arch/x86/include/asm/intel-family.h
@@ -2,145 +2,6 @@
 #ifndef _ASM_X86_INTEL_FAMILY_H
 #define _ASM_X86_INTEL_FAMILY_H
 
-/*
- * "Big Core" Processors (Branded as Core, Xeon, etc...)
- *
- * While adding a new CPUID for a new microarchitecture, add a new
- * group to keep logically sorted out in chronological order. Within
- * that group keep the CPUID for the variants sorted by model number.
- *
- * The defined symbol names have the following form:
- *	INTEL_FAM6{OPTFAMILY}_{MICROARCH}{OPTDIFF}
- * where:
- * OPTFAMILY	Describes the family of CPUs that this belongs to. Default
- *		is assumed to be "_CORE" (and should be omitted). Other values
- *		currently in use are _ATOM and _XEON_PHI
- * MICROARCH	Is the code name for the micro-architecture for this core.
- *		N.B. Not the platform name.
- * OPTDIFF	If needed, a short string to differentiate by market segment.
- *
- *		Common OPTDIFFs:
- *
- *			- regular client parts
- *		_L	- regular mobile parts
- *		_G	- parts with extra graphics on
- *		_X	- regular server parts
- *		_D	- micro server parts
- *
- *		Historical OPTDIFFs:
- *
- *		_EP	- 2 socket server parts
- *		_EX	- 4+ socket server parts
- *
- * The #define line may optionally include a comment including platform or core
- * names. An exception is made for skylake/kabylake where steppings seem to have gotten
- * their own names :-(
- */
-
-/* Wildcard match for FAM6 so X86_MATCH_INTEL_FAM6_MODEL(ANY) works */
-#define INTEL_FAM6_ANY			X86_MODEL_ANY
-
-#define INTEL_FAM6_CORE_YONAH		0x0E
-
-#define INTEL_FAM6_CORE2_MEROM		0x0F
-#define INTEL_FAM6_CORE2_MEROM_L	0x16
-#define INTEL_FAM6_CORE2_PENRYN		0x17
-#define INTEL_FAM6_CORE2_DUNNINGTON	0x1D
-
-#define INTEL_FAM6_NEHALEM		0x1E
-#define INTEL_FAM6_NEHALEM_G		0x1F /* Auburndale / Havendale */
-#define INTEL_FAM6_NEHALEM_EP		0x1A
-#define INTEL_FAM6_NEHALEM_EX		0x2E
-
-#define INTEL_FAM6_WESTMERE		0x25
-#define INTEL_FAM6_WESTMERE_EP		0x2C
-#define INTEL_FAM6_WESTMERE_EX		0x2F
-
-#define INTEL_FAM6_SANDYBRIDGE		0x2A
-#define INTEL_FAM6_SANDYBRIDGE_X	0x2D
-#define INTEL_FAM6_IVYBRIDGE		0x3A
-#define INTEL_FAM6_IVYBRIDGE_X		0x3E
-
-#define INTEL_FAM6_HASWELL		0x3C
-#define INTEL_FAM6_HASWELL_X		0x3F
-#define INTEL_FAM6_HASWELL_L		0x45
-#define INTEL_FAM6_HASWELL_G		0x46
-
-#define INTEL_FAM6_BROADWELL		0x3D
-#define INTEL_FAM6_BROADWELL_G		0x47
-#define INTEL_FAM6_BROADWELL_X		0x4F
-#define INTEL_FAM6_BROADWELL_D		0x56
-
-#define INTEL_FAM6_SKYLAKE_L		0x4E	/* Sky Lake             */
-#define INTEL_FAM6_SKYLAKE		0x5E	/* Sky Lake             */
-#define INTEL_FAM6_SKYLAKE_X		0x55	/* Sky Lake             */
-/*                 CASCADELAKE_X	0x55	   Sky Lake -- s: 7     */
-/*                 COOPERLAKE_X		0x55	   Sky Lake -- s: 11    */
-
-#define INTEL_FAM6_KABYLAKE_L		0x8E	/* Sky Lake             */
-/*                 AMBERLAKE_L		0x8E	   Sky Lake -- s: 9     */
-/*                 COFFEELAKE_L		0x8E	   Sky Lake -- s: 10    */
-/*                 WHISKEYLAKE_L	0x8E       Sky Lake -- s: 11,12 */
-
-#define INTEL_FAM6_KABYLAKE		0x9E	/* Sky Lake             */
-/*                 COFFEELAKE		0x9E	   Sky Lake -- s: 10-13 */
-
-#define INTEL_FAM6_COMETLAKE		0xA5	/* Sky Lake             */
-#define INTEL_FAM6_COMETLAKE_L		0xA6	/* Sky Lake             */
-
-#define INTEL_FAM6_CANNONLAKE_L		0x66	/* Palm Cove */
-
-#define INTEL_FAM6_ICELAKE_X		0x6A	/* Sunny Cove */
-#define INTEL_FAM6_ICELAKE_D		0x6C	/* Sunny Cove */
-#define INTEL_FAM6_ICELAKE		0x7D	/* Sunny Cove */
-#define INTEL_FAM6_ICELAKE_L		0x7E	/* Sunny Cove */
-#define INTEL_FAM6_ICELAKE_NNPI		0x9D	/* Sunny Cove */
-
-#define INTEL_FAM6_LAKEFIELD		0x8A	/* Sunny Cove / Tremont */
-
-#define INTEL_FAM6_ROCKETLAKE		0xA7	/* Cypress Cove */
-
-#define INTEL_FAM6_TIGERLAKE_L		0x8C	/* Willow Cove */
-#define INTEL_FAM6_TIGERLAKE		0x8D	/* Willow Cove */
-
-#define INTEL_FAM6_SAPPHIRERAPIDS_X	0x8F	/* Golden Cove */
-
-#define INTEL_FAM6_ALDERLAKE		0x97	/* Golden Cove / Gracemont */
-#define INTEL_FAM6_ALDERLAKE_L		0x9A	/* Golden Cove / Gracemont */
-
-/* "Small Core" Processors (Atom) */
-
-#define INTEL_FAM6_ATOM_BONNELL		0x1C /* Diamondville, Pineview */
-#define INTEL_FAM6_ATOM_BONNELL_MID	0x26 /* Silverthorne, Lincroft */
-
-#define INTEL_FAM6_ATOM_SALTWELL	0x36 /* Cedarview */
-#define INTEL_FAM6_ATOM_SALTWELL_MID	0x27 /* Penwell */
-#define INTEL_FAM6_ATOM_SALTWELL_TABLET	0x35 /* Cloverview */
-
-#define INTEL_FAM6_ATOM_SILVERMONT	0x37 /* Bay Trail, Valleyview */
-#define INTEL_FAM6_ATOM_SILVERMONT_D	0x4D /* Avaton, Rangely */
-#define INTEL_FAM6_ATOM_SILVERMONT_MID	0x4A /* Merriefield */
-
-#define INTEL_FAM6_ATOM_AIRMONT		0x4C /* Cherry Trail, Braswell */
-#define INTEL_FAM6_ATOM_AIRMONT_MID	0x5A /* Moorefield */
-#define INTEL_FAM6_ATOM_AIRMONT_NP	0x75 /* Lightning Mountain */
-
-#define INTEL_FAM6_ATOM_GOLDMONT	0x5C /* Apollo Lake */
-#define INTEL_FAM6_ATOM_GOLDMONT_D	0x5F /* Denverton */
-
-/* Note: the micro-architecture is "Goldmont Plus" */
-#define INTEL_FAM6_ATOM_GOLDMONT_PLUS	0x7A /* Gemini Lake */
-
-#define INTEL_FAM6_ATOM_TREMONT_D	0x86 /* Jacobsville */
-#define INTEL_FAM6_ATOM_TREMONT		0x96 /* Elkhart Lake */
-#define INTEL_FAM6_ATOM_TREMONT_L	0x9C /* Jasper Lake */
-
-/* Xeon Phi */
-
-#define INTEL_FAM6_XEON_PHI_KNL		0x57 /* Knights Landing */
-#define INTEL_FAM6_XEON_PHI_KNM		0x85 /* Knights Mill */
-
-/* Family 5 */
-#define INTEL_FAM5_QUARK_X1000		0x09 /* Quark X1000 SoC */
+#include <linux/x86/intel-family.h>
 
 #endif /* _ASM_X86_INTEL_FAMILY_H */
diff --git a/include/linux/x86/intel-family.h b/include/linux/x86/intel-family.h
new file mode 100644
index 000000000000..ae4b075c1ab9
--- /dev/null
+++ b/include/linux/x86/intel-family.h
@@ -0,0 +1,146 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_X86_INTEL_FAMILY_H
+#define _LINUX_X86_INTEL_FAMILY_H
+
+/*
+ * "Big Core" Processors (Branded as Core, Xeon, etc...)
+ *
+ * While adding a new CPUID for a new microarchitecture, add a new
+ * group to keep logically sorted out in chronological order. Within
+ * that group keep the CPUID for the variants sorted by model number.
+ *
+ * The defined symbol names have the following form:
+ *	INTEL_FAM6{OPTFAMILY}_{MICROARCH}{OPTDIFF}
+ * where:
+ * OPTFAMILY	Describes the family of CPUs that this belongs to. Default
+ *		is assumed to be "_CORE" (and should be omitted). Other values
+ *		currently in use are _ATOM and _XEON_PHI
+ * MICROARCH	Is the code name for the micro-architecture for this core.
+ *		N.B. Not the platform name.
+ * OPTDIFF	If needed, a short string to differentiate by market segment.
+ *
+ *		Common OPTDIFFs:
+ *
+ *			- regular client parts
+ *		_L	- regular mobile parts
+ *		_G	- parts with extra graphics on
+ *		_X	- regular server parts
+ *		_D	- micro server parts
+ *
+ *		Historical OPTDIFFs:
+ *
+ *		_EP	- 2 socket server parts
+ *		_EX	- 4+ socket server parts
+ *
+ * The #define line may optionally include a comment including platform or core
+ * names. An exception is made for skylake/kabylake where steppings seem to have gotten
+ * their own names :-(
+ */
+
+/* Wildcard match for FAM6 so X86_MATCH_INTEL_FAM6_MODEL(ANY) works */
+#define INTEL_FAM6_ANY			X86_MODEL_ANY
+
+#define INTEL_FAM6_CORE_YONAH		0x0E
+
+#define INTEL_FAM6_CORE2_MEROM		0x0F
+#define INTEL_FAM6_CORE2_MEROM_L	0x16
+#define INTEL_FAM6_CORE2_PENRYN		0x17
+#define INTEL_FAM6_CORE2_DUNNINGTON	0x1D
+
+#define INTEL_FAM6_NEHALEM		0x1E
+#define INTEL_FAM6_NEHALEM_G		0x1F /* Auburndale / Havendale */
+#define INTEL_FAM6_NEHALEM_EP		0x1A
+#define INTEL_FAM6_NEHALEM_EX		0x2E
+
+#define INTEL_FAM6_WESTMERE		0x25
+#define INTEL_FAM6_WESTMERE_EP		0x2C
+#define INTEL_FAM6_WESTMERE_EX		0x2F
+
+#define INTEL_FAM6_SANDYBRIDGE		0x2A
+#define INTEL_FAM6_SANDYBRIDGE_X	0x2D
+#define INTEL_FAM6_IVYBRIDGE		0x3A
+#define INTEL_FAM6_IVYBRIDGE_X		0x3E
+
+#define INTEL_FAM6_HASWELL		0x3C
+#define INTEL_FAM6_HASWELL_X		0x3F
+#define INTEL_FAM6_HASWELL_L		0x45
+#define INTEL_FAM6_HASWELL_G		0x46
+
+#define INTEL_FAM6_BROADWELL		0x3D
+#define INTEL_FAM6_BROADWELL_G		0x47
+#define INTEL_FAM6_BROADWELL_X		0x4F
+#define INTEL_FAM6_BROADWELL_D		0x56
+
+#define INTEL_FAM6_SKYLAKE_L		0x4E	/* Sky Lake             */
+#define INTEL_FAM6_SKYLAKE		0x5E	/* Sky Lake             */
+#define INTEL_FAM6_SKYLAKE_X		0x55	/* Sky Lake             */
+/*                 CASCADELAKE_X	0x55	   Sky Lake -- s: 7     */
+/*                 COOPERLAKE_X		0x55	   Sky Lake -- s: 11    */
+
+#define INTEL_FAM6_KABYLAKE_L		0x8E	/* Sky Lake             */
+/*                 AMBERLAKE_L		0x8E	   Sky Lake -- s: 9     */
+/*                 COFFEELAKE_L		0x8E	   Sky Lake -- s: 10    */
+/*                 WHISKEYLAKE_L	0x8E       Sky Lake -- s: 11,12 */
+
+#define INTEL_FAM6_KABYLAKE		0x9E	/* Sky Lake             */
+/*                 COFFEELAKE		0x9E	   Sky Lake -- s: 10-13 */
+
+#define INTEL_FAM6_COMETLAKE		0xA5	/* Sky Lake             */
+#define INTEL_FAM6_COMETLAKE_L		0xA6	/* Sky Lake             */
+
+#define INTEL_FAM6_CANNONLAKE_L		0x66	/* Palm Cove */
+
+#define INTEL_FAM6_ICELAKE_X		0x6A	/* Sunny Cove */
+#define INTEL_FAM6_ICELAKE_D		0x6C	/* Sunny Cove */
+#define INTEL_FAM6_ICELAKE		0x7D	/* Sunny Cove */
+#define INTEL_FAM6_ICELAKE_L		0x7E	/* Sunny Cove */
+#define INTEL_FAM6_ICELAKE_NNPI		0x9D	/* Sunny Cove */
+
+#define INTEL_FAM6_LAKEFIELD		0x8A	/* Sunny Cove / Tremont */
+
+#define INTEL_FAM6_ROCKETLAKE		0xA7	/* Cypress Cove */
+
+#define INTEL_FAM6_TIGERLAKE_L		0x8C	/* Willow Cove */
+#define INTEL_FAM6_TIGERLAKE		0x8D	/* Willow Cove */
+
+#define INTEL_FAM6_SAPPHIRERAPIDS_X	0x8F	/* Golden Cove */
+
+#define INTEL_FAM6_ALDERLAKE		0x97	/* Golden Cove / Gracemont */
+#define INTEL_FAM6_ALDERLAKE_L		0x9A	/* Golden Cove / Gracemont */
+
+/* "Small Core" Processors (Atom) */
+
+#define INTEL_FAM6_ATOM_BONNELL		0x1C /* Diamondville, Pineview */
+#define INTEL_FAM6_ATOM_BONNELL_MID	0x26 /* Silverthorne, Lincroft */
+
+#define INTEL_FAM6_ATOM_SALTWELL	0x36 /* Cedarview */
+#define INTEL_FAM6_ATOM_SALTWELL_MID	0x27 /* Penwell */
+#define INTEL_FAM6_ATOM_SALTWELL_TABLET	0x35 /* Cloverview */
+
+#define INTEL_FAM6_ATOM_SILVERMONT	0x37 /* Bay Trail, Valleyview */
+#define INTEL_FAM6_ATOM_SILVERMONT_D	0x4D /* Avaton, Rangely */
+#define INTEL_FAM6_ATOM_SILVERMONT_MID	0x4A /* Merriefield */
+
+#define INTEL_FAM6_ATOM_AIRMONT		0x4C /* Cherry Trail, Braswell */
+#define INTEL_FAM6_ATOM_AIRMONT_MID	0x5A /* Moorefield */
+#define INTEL_FAM6_ATOM_AIRMONT_NP	0x75 /* Lightning Mountain */
+
+#define INTEL_FAM6_ATOM_GOLDMONT	0x5C /* Apollo Lake */
+#define INTEL_FAM6_ATOM_GOLDMONT_D	0x5F /* Denverton */
+
+/* Note: the micro-architecture is "Goldmont Plus" */
+#define INTEL_FAM6_ATOM_GOLDMONT_PLUS	0x7A /* Gemini Lake */
+
+#define INTEL_FAM6_ATOM_TREMONT_D	0x86 /* Jacobsville */
+#define INTEL_FAM6_ATOM_TREMONT		0x96 /* Elkhart Lake */
+#define INTEL_FAM6_ATOM_TREMONT_L	0x9C /* Jasper Lake */
+
+/* Xeon Phi */
+
+#define INTEL_FAM6_XEON_PHI_KNL		0x57 /* Knights Landing */
+#define INTEL_FAM6_XEON_PHI_KNM		0x85 /* Knights Mill */
+
+/* Family 5 */
+#define INTEL_FAM5_QUARK_X1000		0x09 /* Quark X1000 SoC */
+
+#endif /* _LINUX_X86_INTEL_FAMILY_H */
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:21 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:21 +0200
Subject: [PATCH v2 02/15] x86/cpu: Extract cpuid helpers to arch-independent
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-3-iwona.winiarska@intel.com>

Baseboard management controllers (BMC) often run Linux but are usually
implemented with non-X86 processors. They can use PECI to access package
config space (PCS) registers on the host CPU and since some information,
e.g. figuring out the core count, can be obtained using different
registers on different CPU generations, they need to decode the family
and model.

The format of Package Identifier PCS register that describes CPUID
information has the same layout as CPUID_1.EAX, so let's allow to reuse
cpuid helpers by making it available for other architectures as well.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Tony Luck <tony.luck at intel.com>
Reviewed-by: Dan Williams <dan.j.williams at intel.com>
---
 MAINTAINERS                      | 1 +
 arch/x86/Kconfig                 | 1 +
 arch/x86/include/asm/cpu.h       | 3 ---
 arch/x86/include/asm/microcode.h | 2 +-
 arch/x86/kvm/cpuid.h             | 3 ++-
 arch/x86/lib/Makefile            | 2 +-
 drivers/edac/mce_amd.c           | 3 +--
 include/linux/x86/cpu.h          | 9 +++++++++
 lib/Kconfig                      | 4 ++++
 lib/Makefile                     | 2 ++
 lib/x86/Makefile                 | 3 +++
 {arch/x86/lib => lib/x86}/cpu.c  | 2 +-
 12 files changed, 26 insertions(+), 9 deletions(-)
 create mode 100644 include/linux/x86/cpu.h
 create mode 100644 lib/x86/Makefile
 rename {arch/x86/lib => lib/x86}/cpu.c (95%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 104773d40952..7cdab7229651 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20107,6 +20107,7 @@ F:	Documentation/devicetree/bindings/x86/
 F:	Documentation/x86/
 F:	arch/x86/
 F:	include/linux/x86/
+F:	lib/x86/
 
 X86 ENTRY CODE
 M:	Andy Lutomirski <luto at kernel.org>
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 88fb922c23a0..9096593999ba 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -141,6 +141,7 @@ config X86
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_RESERVATION_MODE
 	select GENERIC_IRQ_SHOW
+	select GENERIC_LIB_X86
 	select GENERIC_PENDING_IRQ		if SMP
 	select GENERIC_PTDUMP
 	select GENERIC_SMP_IDLE_THREAD
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 33d41e350c79..2a663a05a795 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -37,9 +37,6 @@ extern int _debug_hotplug_cpu(int cpu, int action);
 
 int mwait_usable(const struct cpuinfo_x86 *);
 
-unsigned int x86_family(unsigned int sig);
-unsigned int x86_model(unsigned int sig);
-unsigned int x86_stepping(unsigned int sig);
 #ifdef CONFIG_CPU_SUP_INTEL
 extern void __init sld_setup(struct cpuinfo_x86 *c);
 extern void switch_to_sld(unsigned long tifn);
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index ab45a220fac4..4b0eabf63b98 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -2,9 +2,9 @@
 #ifndef _ASM_X86_MICROCODE_H
 #define _ASM_X86_MICROCODE_H
 
-#include <asm/cpu.h>
 #include <linux/earlycpio.h>
 #include <linux/initrd.h>
+#include <linux/x86/cpu.h>
 
 struct ucode_patch {
 	struct list_head plist;
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index c99edfff7f82..bf070d2a2175 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -4,10 +4,11 @@
 
 #include "x86.h"
 #include "reverse_cpuid.h"
-#include <asm/cpu.h>
 #include <asm/processor.h>
 #include <uapi/asm/kvm_para.h>
 
+#include <linux/x86/cpu.h>
+
 extern u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
 void kvm_set_cpu_caps(void);
 
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index bad4dee4f0e4..fd73c1b72c3e 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -41,7 +41,7 @@ clean-files := inat-tables.c
 
 obj-$(CONFIG_SMP) += msr-smp.o cache-smp.o
 
-lib-y := delay.o misc.o cmdline.o cpu.o
+lib-y := delay.o misc.o cmdline.o
 lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o
 lib-y += memcpy_$(BITS).o
 lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc.o copy_mc_64.o
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index 27d56920b469..f545f5fad02c 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -1,8 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/module.h>
 #include <linux/slab.h>
-
-#include <asm/cpu.h>
+#include <linux/x86/cpu.h>
 
 #include "mce_amd.h"
 
diff --git a/include/linux/x86/cpu.h b/include/linux/x86/cpu.h
new file mode 100644
index 000000000000..5f383d47886d
--- /dev/null
+++ b/include/linux/x86/cpu.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _LINUX_X86_CPU_H
+#define _LINUX_X86_CPU_H
+
+unsigned int x86_family(unsigned int sig);
+unsigned int x86_model(unsigned int sig);
+unsigned int x86_stepping(unsigned int sig);
+
+#endif /* _LINUX_X86_CPU_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 5c9c0687f76d..e538d4d773bd 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -715,3 +715,7 @@ config PLDMFW
 
 config ASN1_ENCODER
        tristate
+
+config GENERIC_LIB_X86
+	bool
+	depends on X86
diff --git a/lib/Makefile b/lib/Makefile
index 5efd1b435a37..befbd9413432 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -360,3 +360,5 @@ obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
 obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o
 
 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
+
+obj-$(CONFIG_GENERIC_LIB_X86) += x86/
diff --git a/lib/x86/Makefile b/lib/x86/Makefile
new file mode 100644
index 000000000000..342024c272fc
--- /dev/null
+++ b/lib/x86/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-y := cpu.o
diff --git a/arch/x86/lib/cpu.c b/lib/x86/cpu.c
similarity index 95%
rename from arch/x86/lib/cpu.c
rename to lib/x86/cpu.c
index 7ad68917a51e..17af59a2fddf 100644
--- a/arch/x86/lib/cpu.c
+++ b/lib/x86/cpu.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/types.h>
 #include <linux/export.h>
-#include <asm/cpu.h>
+#include <linux/x86/cpu.h>
 
 unsigned int x86_family(unsigned int sig)
 {
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:22 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:22 +0200
Subject: [PATCH v2 03/15] dt-bindings: Add generic bindings for PECI
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-4-iwona.winiarska@intel.com>

Add device tree bindings for the PECI controller.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
---
 .../bindings/peci/peci-controller.yaml        | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/peci/peci-controller.yaml

diff --git a/Documentation/devicetree/bindings/peci/peci-controller.yaml b/Documentation/devicetree/bindings/peci/peci-controller.yaml
new file mode 100644
index 000000000000..bbc3d3f3a929
--- /dev/null
+++ b/Documentation/devicetree/bindings/peci/peci-controller.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/peci/peci-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic Device Tree Bindings for PECI
+
+maintainers:
+  - Iwona Winiarska <iwona.winiarska at intel.com>
+
+description:
+  PECI (Platform Environment Control Interface) is an interface that provides a
+  communication channel from Intel processors and chipset components to external
+  monitoring or control devices.
+
+properties:
+  $nodename:
+    pattern: "^peci-controller(@.*)?$"
+
+  cmd-timeout-ms:
+    description:
+      Command timeout in units of ms.
+
+additionalProperties: true
+
+examples:
+  - |
+    peci-controller at 1e78b000 {
+      reg = <0x1e78b000 0x100>;
+      cmd-timeout-ms = <500>;
+    };
+...
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:23 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:23 +0200
Subject: [PATCH v2 04/15] dt-bindings: Add bindings for peci-aspeed
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-5-iwona.winiarska@intel.com>

Add device tree bindings for the peci-aspeed controller driver.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
---
 .../devicetree/bindings/peci/peci-aspeed.yaml | 109 ++++++++++++++++++
 1 file changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.yaml

diff --git a/Documentation/devicetree/bindings/peci/peci-aspeed.yaml b/Documentation/devicetree/bindings/peci/peci-aspeed.yaml
new file mode 100644
index 000000000000..2929d1e000d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/peci/peci-aspeed.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/peci/peci-aspeed.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed PECI Bus Device Tree Bindings
+
+maintainers:
+  - Iwona Winiarska <iwona.winiarska at intel.com>
+  - Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+allOf:
+  - $ref: peci-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2400-peci
+      - aspeed,ast2500-peci
+      - aspeed,ast2600-peci
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    description:
+      Clock source for PECI controller. Should reference the external
+      oscillator clock.
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  cmd-timeout-ms:
+    minimum: 1
+    maximum: 1000
+    default: 1000
+
+  aspeed,clock-divider:
+    description:
+      This value determines PECI controller internal clock dividing
+      rate. The divider will be calculated as 2 raised to the power of
+      the given value.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 7
+    default: 0
+
+  aspeed,msg-timing:
+    description:
+      Message timing negotiation period. This value will determine the period
+      of message timing negotiation to be issued by PECI controller. The unit
+      of the programmed value is four times of PECI clock period.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 255
+    default: 1
+
+  aspeed,addr-timing:
+    description:
+      Address timing negotiation period. This value will determine the period
+      of address timing negotiation to be issued by PECI controller. The unit
+      of the programmed value is four times of PECI clock period.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 255
+    default: 1
+
+  aspeed,rd-sampling-point:
+    description:
+      Read sampling point selection. The whole period of a bit time will be
+      divided into 16 time frames. This value will determine the time frame
+      in which the controller will sample PECI signal for data read back.
+      Usually in the middle of a bit time is the best.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 15
+    default: 8
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+    peci-controller at 1e78b000 {
+      compatible = "aspeed,ast2600-peci";
+      reg = <0x1e78b000 0x100>;
+      interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>;
+      resets = <&syscon ASPEED_RESET_PECI>;
+      cmd-timeout-ms = <1000>;
+      aspeed,clock-divider = <0>;
+      aspeed,msg-timing = <1>;
+      aspeed,addr-timing = <1>;
+      aspeed,rd-sampling-point = <8>;
+    };
+...
-- 
2.31.1



From wangborong at cdjrlc.com  Tue Aug  3 04:33:00 2021
From: wangborong at cdjrlc.com (Jason Wang)
Date: Tue,  3 Aug 2021 19:33:00 +0800
Subject: [PATCH] mtd: rawnand: remove never changed ret variable
Message-ID: <20210803113300.24230-1-wangborong@cdjrlc.com>

The ret variable used for returning value in the function
`meson_nfc_rw_cmd_prepare_and_execute` is never change after initialising.
Therefore, we can remove it safely and return 0 at the end of the function.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
---
 drivers/mtd/nand/raw/meson_nand.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index 817bddccb775..ac3be92872d0 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -580,7 +580,7 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand,
 	u32 *addrs = nfc->cmdfifo.rw.addrs;
 	u32 cs = nfc->param.chip_select;
 	u32 cmd0, cmd_num, row_start;
-	int ret = 0, i;
+	int i;
 
 	cmd_num = sizeof(struct nand_rw_cmd) / sizeof(int);
 
@@ -620,7 +620,7 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand,
 		meson_nfc_cmd_idle(nfc, nfc->timing.tadl);
 	}
 
-	return ret;
+	return 0;
 }
 
 static int meson_nfc_write_page_sub(struct nand_chip *nand,
-- 
2.32.0



From fido_max at inbox.ru  Tue Aug  3 04:35:38 2021
From: fido_max at inbox.ru (Maxim Kochetkov)
Date: Tue,  3 Aug 2021 14:35:38 +0300
Subject: [PATCH v4] soc: fsl: qe: convert QE interrupt controller to
 platform_device
Message-ID: <20210803113538.560277-1-fido_max@inbox.ru>

Since 5.13 QE's ucc nodes can't get interrupts from devicetree:

	ucc at 2000 {
		cell-index = <1>;
		reg = <0x2000 0x200>;
		interrupts = <32>;
		interrupt-parent = <&qeic>;
	};

Now fw_devlink expects driver to create and probe a struct device
for interrupt controller.

So lets convert this driver to simple platform_device with probe().
Also use platform_get_ and devm_ family function to get/allocate
resources and drop unused .compatible = "qeic".

[1] - https://lore.kernel.org/lkml/CAGETcx9PiX==mLxB9PO8Myyk6u2vhPVwTMsA5NkD-ywH5xhusw at mail.gmail.com
Fixes: e590474768f1 ("driver core: Set fw_devlink=on by default")
Fixes: ea718c699055 ("Revert "Revert "driver core: Set fw_devlink=on by default""")
Signed-off-by: Maxim Kochetkov <fido_max at inbox.ru>
Reported-by: kernel test robot <lkp at intel.com>
Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
---
 drivers/soc/fsl/qe/qe_ic.c | 75 ++++++++++++++++++++++----------------
 1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c
index 3f711c1a0996..e710d554425d 100644
--- a/drivers/soc/fsl/qe/qe_ic.c
+++ b/drivers/soc/fsl/qe/qe_ic.c
@@ -23,6 +23,7 @@
 #include <linux/signal.h>
 #include <linux/device.h>
 #include <linux/spinlock.h>
+#include <linux/platform_device.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <soc/fsl/qe/qe.h>
@@ -404,41 +405,40 @@ static void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
 	chip->irq_eoi(&desc->irq_data);
 }
 
-static void __init qe_ic_init(struct device_node *node)
+static int qe_ic_init(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	void (*low_handler)(struct irq_desc *desc);
 	void (*high_handler)(struct irq_desc *desc);
 	struct qe_ic *qe_ic;
-	struct resource res;
-	u32 ret;
+	struct resource *res;
+	struct device_node *node = pdev->dev.of_node;
 
-	ret = of_address_to_resource(node, 0, &res);
-	if (ret)
-		return;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(dev, "no memory resource defined\n");
+		return -ENODEV;
+	}
 
-	qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
+	qe_ic = devm_kzalloc(dev, sizeof(*qe_ic), GFP_KERNEL);
 	if (qe_ic == NULL)
-		return;
+		return -ENOMEM;
 
-	qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
-					       &qe_ic_host_ops, qe_ic);
-	if (qe_ic->irqhost == NULL) {
-		kfree(qe_ic);
-		return;
+	qe_ic->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (qe_ic->regs == NULL) {
+		dev_err(dev, "failed to ioremap() registers\n");
+		return -ENODEV;
 	}
 
-	qe_ic->regs = ioremap(res.start, resource_size(&res));
-
 	qe_ic->hc_irq = qe_ic_irq_chip;
 
-	qe_ic->virq_high = irq_of_parse_and_map(node, 0);
-	qe_ic->virq_low = irq_of_parse_and_map(node, 1);
+	qe_ic->virq_high = platform_get_irq(pdev, 0);
+	qe_ic->virq_low = platform_get_irq(pdev, 1);
 
-	if (!qe_ic->virq_low) {
-		printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
-		kfree(qe_ic);
-		return;
+	if (qe_ic->virq_low < 0) {
+		return -ENODEV;
 	}
+
 	if (qe_ic->virq_high != qe_ic->virq_low) {
 		low_handler = qe_ic_cascade_low;
 		high_handler = qe_ic_cascade_high;
@@ -447,6 +447,13 @@ static void __init qe_ic_init(struct device_node *node)
 		high_handler = NULL;
 	}
 
+	qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
+					       &qe_ic_host_ops, qe_ic);
+	if (qe_ic->irqhost == NULL) {
+		dev_err(dev, "failed to add irq domain\n");
+		return -ENODEV;
+	}
+
 	qe_ic_write(qe_ic->regs, QEIC_CICR, 0);
 
 	irq_set_handler_data(qe_ic->virq_low, qe_ic);
@@ -456,20 +463,26 @@ static void __init qe_ic_init(struct device_node *node)
 		irq_set_handler_data(qe_ic->virq_high, qe_ic);
 		irq_set_chained_handler(qe_ic->virq_high, high_handler);
 	}
+	return 0;
 }
+static const struct of_device_id qe_ic_ids[] = {
+	{ .compatible = "fsl,qe-ic"},
+	{ .type = "qeic"},
+	{},
+};
 
-static int __init qe_ic_of_init(void)
+static struct platform_driver qe_ic_driver =
 {
-	struct device_node *np;
+	.driver	= {
+		.name		= "qe-ic",
+		.of_match_table	= qe_ic_ids,
+	},
+	.probe	= qe_ic_init,
+};
 
-	np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
-	if (!np) {
-		np = of_find_node_by_type(NULL, "qeic");
-		if (!np)
-			return -ENODEV;
-	}
-	qe_ic_init(np);
-	of_node_put(np);
+static int __init qe_ic_of_init(void)
+{
+	platform_driver_register(&qe_ic_driver);
 	return 0;
 }
 subsys_initcall(qe_ic_of_init);
-- 
2.31.1



From linus.walleij at linaro.org  Tue Aug  3 04:34:28 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 3 Aug 2021 13:34:28 +0200
Subject: [PATCH 3/3] ARM: Map the lowmem and kernel separately
In-Reply-To: <20210803104932.GM22278@shell.armlinux.org.uk>
References: <20210517145719.110966-1-linus.walleij@linaro.org>
 <20210517145719.110966-4-linus.walleij@linaro.org>
 <20210730202259.dbifugsvry5vjdr7@earthen>
 <CACRpkdYAzGzqfdREogAFnyGqSnHLQmdCR=GZ=YqhzoTUA0MfCA@mail.gmail.com>
 <f3eb9c84-19c6-cba2-ffcc-2dbcb48051ad@ti.com>
 <20210803104932.GM22278@shell.armlinux.org.uk>
Message-ID: <CACRpkdbUDnTzne+tdgxC5K6h6ubn2QC8dOOEPjeRyugQn9GuSg@mail.gmail.com>

On Tue, Aug 3, 2021 at 12:49 PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:

> It looks to me like Linus missed the code in arch/arm/mm/pv-fixup-asm.S
> and as the kernel is no longer mapped in the lowmem mapping, this
> likely writes a load of entries in the page tables that are random...

Oops. I'll do my homework. I'll read this code and see if I can fix this.

Yours,
Linus Walleij


From iwona.winiarska at intel.com  Tue Aug  3 04:31:24 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:24 +0200
Subject: [PATCH v2 05/15] ARM: dts: aspeed: Add PECI controller nodes
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-6-iwona.winiarska@intel.com>

Add PECI controller nodes with all required information.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
---
 arch/arm/boot/dts/aspeed-g4.dtsi | 14 ++++++++++++++
 arch/arm/boot/dts/aspeed-g5.dtsi | 14 ++++++++++++++
 arch/arm/boot/dts/aspeed-g6.dtsi | 14 ++++++++++++++
 3 files changed, 42 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index c5aeb3cf3a09..87f07d7396d0 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -385,6 +385,20 @@ ibt: ibt at 140 {
 				};
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2400-peci";
+				reg = <0x1e78b000 0x60>;
+				interrupts = <15>;
+				clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				aspeed,clock-divider = <0>;
+				aspeed,msg-timing = <1>;
+				aspeed,addr-timing = <1>;
+				aspeed,rd-sampling-point = <8>;
+				status = "disabled";
+			};
+
 			uart2: serial at 1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x20>;
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 329eaeef66fb..f54d1a9eba22 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -506,6 +506,20 @@ ibt: ibt at 140 {
 				};
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2500-peci";
+				reg = <0x1e78b000 0x60>;
+				interrupts = <15>;
+				clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				aspeed,clock-divider = <0>;
+				aspeed,msg-timing = <1>;
+				aspeed,addr-timing = <1>;
+				aspeed,rd-sampling-point = <8>;
+				status = "disabled";
+			};
+
 			uart2: serial at 1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x20>;
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index f96607b7b4e2..7fd9eaa02be4 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -459,6 +459,20 @@ wdt4: watchdog at 1e7850c0 {
 				status = "disabled";
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2600-peci";
+				reg = <0x1e78b000 0x100>;
+				interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				aspeed,clock-divider = <0>;
+				aspeed,msg-timing = <1>;
+				aspeed,addr-timing = <1>;
+				aspeed,rd-sampling-point = <8>;
+				status = "disabled";
+			};
+
 			lpc: lpc at 1e789000 {
 				compatible = "aspeed,ast2600-lpc-v2", "simple-mfd", "syscon";
 				reg = <0x1e789000 0x1000>;
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:25 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:25 +0200
Subject: [PATCH v2 06/15] peci: Add core infrastructure
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-7-iwona.winiarska@intel.com>

Intel processors provide access for various services designed to support
processor and DRAM thermal management, platform manageability and
processor interface tuning and diagnostics.
Those services are available via the Platform Environment Control
Interface (PECI) that provides a communication channel between the
processor and the Baseboard Management Controller (BMC) or other
platform management device.

This change introduces PECI subsystem by adding the initial core module
and API for controller drivers.

Co-developed-by: Jason M Bills <jason.m.bills at linux.intel.com>
Signed-off-by: Jason M Bills <jason.m.bills at linux.intel.com>
Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS             |   9 +++
 drivers/Kconfig         |   3 +
 drivers/Makefile        |   1 +
 drivers/peci/Kconfig    |  15 ++++
 drivers/peci/Makefile   |   5 ++
 drivers/peci/core.c     | 155 ++++++++++++++++++++++++++++++++++++++++
 drivers/peci/internal.h |  16 +++++
 include/linux/peci.h    |  99 +++++++++++++++++++++++++
 8 files changed, 303 insertions(+)
 create mode 100644 drivers/peci/Kconfig
 create mode 100644 drivers/peci/Makefile
 create mode 100644 drivers/peci/core.c
 create mode 100644 drivers/peci/internal.h
 create mode 100644 include/linux/peci.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7cdab7229651..d411974aaa5e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14503,6 +14503,15 @@ L:	platform-driver-x86 at vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/peaq-wmi.c
 
+PECI SUBSYSTEM
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+R:	Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/peci/
+F:	drivers/peci/
+F:	include/linux/peci.h
+
 PENSANDO ETHERNET DRIVERS
 M:	Shannon Nelson <snelson at pensando.io>
 M:	drivers at pensando.io
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 8bad63417a50..f472b3d972b3 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -236,4 +236,7 @@ source "drivers/interconnect/Kconfig"
 source "drivers/counter/Kconfig"
 
 source "drivers/most/Kconfig"
+
+source "drivers/peci/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 27c018bdf4de..8d96f0c3dde5 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -189,3 +189,4 @@ obj-$(CONFIG_GNSS)		+= gnss/
 obj-$(CONFIG_INTERCONNECT)	+= interconnect/
 obj-$(CONFIG_COUNTER)		+= counter/
 obj-$(CONFIG_MOST)		+= most/
+obj-$(CONFIG_PECI)		+= peci/
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
new file mode 100644
index 000000000000..71a4ad81225a
--- /dev/null
+++ b/drivers/peci/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menuconfig PECI
+	tristate "PECI support"
+	help
+	  The Platform Environment Control Interface (PECI) is an interface
+	  that provides a communication channel to Intel processors and
+	  chipset components from external monitoring or control devices.
+
+	  If you are building a Baseboard Management Controller (BMC) kernel
+	  for Intel platform say Y here and also to the specific driver for
+	  your adapter(s) below. If unsure say N.
+
+	  This support is also available as a module. If so, the module
+	  will be called peci.
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
new file mode 100644
index 000000000000..e789a354e842
--- /dev/null
+++ b/drivers/peci/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Core functionality
+peci-y := core.o
+obj-$(CONFIG_PECI) += peci.o
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
new file mode 100644
index 000000000000..7b3938af0396
--- /dev/null
+++ b/drivers/peci/core.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/idr.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/peci.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+static DEFINE_IDA(peci_controller_ida);
+
+static void peci_controller_dev_release(struct device *dev)
+{
+	struct peci_controller *controller = to_peci_controller(dev);
+
+	pm_runtime_disable(&controller->dev);
+
+	mutex_destroy(&controller->bus_lock);
+	ida_free(&peci_controller_ida, controller->id);
+	fwnode_handle_put(controller->dev.fwnode);
+	kfree(controller);
+}
+
+struct device_type peci_controller_type = {
+	.release	= peci_controller_dev_release,
+};
+
+static struct peci_controller *peci_controller_alloc(struct device *dev,
+						     struct peci_controller_ops *ops)
+{
+	struct fwnode_handle *node = fwnode_handle_get(dev_fwnode(dev));
+	struct peci_controller *controller;
+	int ret;
+
+	if (!ops->xfer)
+		return ERR_PTR(-EINVAL);
+
+	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		return ERR_PTR(-ENOMEM);
+
+	ret = ida_alloc_max(&peci_controller_ida, U8_MAX, GFP_KERNEL);
+	if (ret < 0)
+		goto err;
+	controller->id = ret;
+
+	controller->ops = ops;
+
+	controller->dev.parent = dev;
+	controller->dev.bus = &peci_bus_type;
+	controller->dev.type = &peci_controller_type;
+	controller->dev.fwnode = node;
+	controller->dev.of_node = to_of_node(node);
+
+	device_initialize(&controller->dev);
+
+	mutex_init(&controller->bus_lock);
+
+	pm_runtime_no_callbacks(&controller->dev);
+	pm_suspend_ignore_children(&controller->dev, true);
+	pm_runtime_enable(&controller->dev);
+
+	return controller;
+
+err:
+	kfree(controller);
+	return ERR_PTR(ret);
+}
+
+static void unregister_controller(void *_controller)
+{
+	struct peci_controller *controller = _controller;
+
+	device_unregister(&controller->dev);
+}
+
+/**
+ * devm_peci_controller_add() - add PECI controller
+ * @dev: device for devm operations
+ * @ops: pointer to controller specific methods
+ *
+ * In final stage of its probe(), peci_controller driver calls
+ * devm_peci_controller_add() to register itself with the PECI bus.
+ *
+ * Return: Pointer to the newly allocated controller or ERR_PTR() in case of failure.
+ */
+struct peci_controller *devm_peci_controller_add(struct device *dev,
+						 struct peci_controller_ops *ops)
+{
+	struct peci_controller *controller;
+	int ret;
+
+	controller = peci_controller_alloc(dev, ops);
+	if (IS_ERR(controller))
+		return controller;
+
+	ret = dev_set_name(&controller->dev, "peci-%d", controller->id);
+	if (ret)
+		goto err;
+
+	ret = device_add(&controller->dev);
+	if (ret)
+		goto err;
+
+	ret = devm_add_action_or_reset(dev, unregister_controller, controller);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return controller;
+
+err:
+	put_device(&controller->dev);
+
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
+
+struct bus_type peci_bus_type = {
+	.name		= "peci",
+};
+
+static int __init peci_init(void)
+{
+	int ret;
+
+	ret = bus_register(&peci_bus_type);
+	if (ret < 0) {
+		pr_err("failed to register PECI bus type!\n");
+		return ret;
+	}
+
+	return 0;
+}
+module_init(peci_init);
+
+static void __exit peci_exit(void)
+{
+	bus_unregister(&peci_bus_type);
+}
+module_exit(peci_exit);
+
+MODULE_AUTHOR("Jason M Bills <jason.m.bills at linux.intel.com>");
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI bus core module");
+MODULE_LICENSE("GPL");
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
new file mode 100644
index 000000000000..918dea745a86
--- /dev/null
+++ b/drivers/peci/internal.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2021 Intel Corporation */
+
+#ifndef __PECI_INTERNAL_H
+#define __PECI_INTERNAL_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+
+struct peci_controller;
+
+extern struct bus_type peci_bus_type;
+
+extern struct device_type peci_controller_type;
+
+#endif /* __PECI_INTERNAL_H */
diff --git a/include/linux/peci.h b/include/linux/peci.h
new file mode 100644
index 000000000000..26e0a4e73b50
--- /dev/null
+++ b/include/linux/peci.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2021 Intel Corporation */
+
+#ifndef __LINUX_PECI_H
+#define __LINUX_PECI_H
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+/*
+ * Currently we don't support any PECI command over 32 bytes.
+ */
+#define PECI_REQUEST_MAX_BUF_SIZE 32
+
+struct peci_controller;
+struct peci_request;
+
+/**
+ * struct peci_controller_ops - PECI controller specific methods
+ * @xfer: PECI transfer function
+ *
+ * PECI controllers may have different hardware interfaces - the drivers
+ * implementing PECI controllers can use this structure to abstract away those
+ * differences by exposing a common interface for PECI core.
+ */
+struct peci_controller_ops {
+	int (*xfer)(struct peci_controller *controller, u8 addr, struct peci_request *req);
+};
+
+/**
+ * struct peci_controller - PECI controller
+ * @dev: device object to register PECI controller to the device model
+ * @ops: pointer to device specific controller operations
+ * @bus_lock: lock used to protect multiple callers
+ * @id: PECI controller ID
+ *
+ * PECI controllers usually connect to their drivers using non-PECI bus,
+ * such as the platform bus.
+ * Each PECI controller can communicate with one or more PECI devices.
+ */
+struct peci_controller {
+	struct device dev;
+	struct peci_controller_ops *ops;
+	struct mutex bus_lock; /* held for the duration of xfer */
+	u8 id;
+};
+
+struct peci_controller *devm_peci_controller_add(struct device *parent,
+						 struct peci_controller_ops *ops);
+
+static inline struct peci_controller *to_peci_controller(void *d)
+{
+	return container_of(d, struct peci_controller, dev);
+}
+
+/**
+ * struct peci_device - PECI device
+ * @dev: device object to register PECI device to the device model
+ * @controller: manages the bus segment hosting this PECI device
+ * @addr: address used on the PECI bus connected to the parent controller
+ *
+ * A peci_device identifies a single device (i.e. CPU) connected to a PECI bus.
+ * The behaviour exposed to the rest of the system is defined by the PECI driver
+ * managing the device.
+ */
+struct peci_device {
+	struct device dev;
+	u8 addr;
+};
+
+static inline struct peci_device *to_peci_device(struct device *d)
+{
+	return container_of(d, struct peci_device, dev);
+}
+
+/**
+ * struct peci_request - PECI request
+ * @device: PECI device to which the request is sent
+ * @tx: TX buffer specific data
+ * @tx.buf: TX buffer
+ * @tx.len: transfer data length in bytes
+ * @rx: RX buffer specific data
+ * @rx.buf: RX buffer
+ * @rx.len: received data length in bytes
+ *
+ * A peci_request represents a request issued by PECI originator (TX) and
+ * a response received from PECI responder (RX).
+ */
+struct peci_request {
+	struct peci_device *device;
+	struct {
+		u8 buf[PECI_REQUEST_MAX_BUF_SIZE];
+		u8 len;
+	} rx, tx;
+};
+
+#endif /* __LINUX_PECI_H */
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:26 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:26 +0200
Subject: [PATCH v2 07/15] peci: Add peci-aspeed controller driver
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-8-iwona.winiarska@intel.com>

From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>

ASPEED AST24xx/AST25xx/AST26xx SoCs supports the PECI electrical
interface (a.k.a PECI wire).

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS                           |   9 +
 drivers/peci/Kconfig                  |   6 +
 drivers/peci/Makefile                 |   3 +
 drivers/peci/controller/Kconfig       |  16 +
 drivers/peci/controller/Makefile      |   3 +
 drivers/peci/controller/peci-aspeed.c | 445 ++++++++++++++++++++++++++
 6 files changed, 482 insertions(+)
 create mode 100644 drivers/peci/controller/Kconfig
 create mode 100644 drivers/peci/controller/Makefile
 create mode 100644 drivers/peci/controller/peci-aspeed.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d411974aaa5e..6e9d53ff68ab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2866,6 +2866,15 @@ S:	Maintained
 F:	Documentation/hwmon/asc7621.rst
 F:	drivers/hwmon/asc7621.c
 
+ASPEED PECI CONTROLLER
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+M:	Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/peci/peci-aspeed.yaml
+F:	drivers/peci/controller/peci-aspeed.c
+
 ASPEED PINCTRL DRIVERS
 M:	Andrew Jeffery <andrew at aj.id.au>
 L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
index 71a4ad81225a..99279df97a78 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -13,3 +13,9 @@ menuconfig PECI
 
 	  This support is also available as a module. If so, the module
 	  will be called peci.
+
+if PECI
+
+source "drivers/peci/controller/Kconfig"
+
+endif # PECI
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index e789a354e842..926d8df15cbd 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -3,3 +3,6 @@
 # Core functionality
 peci-y := core.o
 obj-$(CONFIG_PECI) += peci.o
+
+# Hardware specific bus drivers
+obj-y += controller/
diff --git a/drivers/peci/controller/Kconfig b/drivers/peci/controller/Kconfig
new file mode 100644
index 000000000000..6d48df08db1c
--- /dev/null
+++ b/drivers/peci/controller/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config PECI_ASPEED
+	tristate "ASPEED PECI support"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	depends on OF
+	depends on HAS_IOMEM
+	help
+	  This option enables PECI controller driver for ASPEED AST2400,
+	  AST2500 and AST2600 SoCs.
+
+	  Say Y here if your system runs on ASPEED SoC and you are using it
+	  as BMC for Intel platform.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called peci-aspeed.
diff --git a/drivers/peci/controller/Makefile b/drivers/peci/controller/Makefile
new file mode 100644
index 000000000000..022c28ef1bf0
--- /dev/null
+++ b/drivers/peci/controller/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_PECI_ASPEED)	+= peci-aspeed.o
diff --git a/drivers/peci/controller/peci-aspeed.c b/drivers/peci/controller/peci-aspeed.c
new file mode 100644
index 000000000000..1d708c983749
--- /dev/null
+++ b/drivers/peci/controller/peci-aspeed.c
@@ -0,0 +1,445 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2012-2017 ASPEED Technology Inc.
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/peci.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include <asm/unaligned.h>
+
+/* ASPEED PECI Registers */
+/* Control Register */
+#define ASPEED_PECI_CTRL			0x00
+#define   ASPEED_PECI_CTRL_SAMPLING_MASK	GENMASK(19, 16)
+#define   ASPEED_PECI_CTRL_RD_MODE_MASK		GENMASK(13, 12)
+#define     ASPEED_PECI_CTRL_RD_MODE_DBG	BIT(13)
+#define     ASPEED_PECI_CTRL_RD_MODE_COUNT	BIT(12)
+#define   ASPEED_PECI_CTRL_CLK_SOURCE		BIT(11)
+#define   ASPEED_PECI_CTRL_CLK_DIV_MASK		GENMASK(10, 8)
+#define   ASPEED_PECI_CTRL_INVERT_OUT		BIT(7)
+#define   ASPEED_PECI_CTRL_INVERT_IN		BIT(6)
+#define   ASPEED_PECI_CTRL_BUS_CONTENTION_EN	BIT(5)
+#define   ASPEED_PECI_CTRL_PECI_EN		BIT(4)
+#define   ASPEED_PECI_CTRL_PECI_CLK_EN		BIT(0)
+
+/* Timing Negotiation Register */
+#define ASPEED_PECI_TIMING_NEGOTIATION		0x04
+#define   ASPEED_PECI_T_NEGO_MSG_MASK		GENMASK(15, 8)
+#define   ASPEED_PECI_T_NEGO_ADDR_MASK		GENMASK(7, 0)
+
+/* Command Register */
+#define ASPEED_PECI_CMD				0x08
+#define   ASPEED_PECI_CMD_PIN_MONITORING	BIT(31)
+#define   ASPEED_PECI_CMD_STS_MASK		GENMASK(27, 24)
+#define     ASPEED_PECI_CMD_STS_ADDR_T_NEGO	0x3
+#define   ASPEED_PECI_CMD_IDLE_MASK		\
+	  (ASPEED_PECI_CMD_STS_MASK | ASPEED_PECI_CMD_PIN_MONITORING)
+#define   ASPEED_PECI_CMD_FIRE			BIT(0)
+
+/* Read/Write Length Register */
+#define ASPEED_PECI_RW_LENGTH			0x0c
+#define   ASPEED_PECI_AW_FCS_EN			BIT(31)
+#define   ASPEED_PECI_RD_LEN_MASK		GENMASK(23, 16)
+#define   ASPEED_PECI_WR_LEN_MASK		GENMASK(15, 8)
+#define   ASPEED_PECI_TARGET_ADDR_MASK		GENMASK(7, 0)
+
+/* Expected FCS Data Register */
+#define ASPEED_PECI_EXPECTED_FCS		0x10
+#define   ASPEED_PECI_EXPECTED_RD_FCS_MASK	GENMASK(23, 16)
+#define   ASPEED_PECI_EXPECTED_AW_FCS_AUTO_MASK	GENMASK(15, 8)
+#define   ASPEED_PECI_EXPECTED_WR_FCS_MASK	GENMASK(7, 0)
+
+/* Captured FCS Data Register */
+#define ASPEED_PECI_CAPTURED_FCS		0x14
+#define   ASPEED_PECI_CAPTURED_RD_FCS_MASK	GENMASK(23, 16)
+#define   ASPEED_PECI_CAPTURED_WR_FCS_MASK	GENMASK(7, 0)
+
+/* Interrupt Register */
+#define ASPEED_PECI_INT_CTRL			0x18
+#define   ASPEED_PECI_TIMING_NEGO_SEL_MASK	GENMASK(31, 30)
+#define     ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO	0
+#define     ASPEED_PECI_2ND_BIT_OF_ADDR_NEGO	1
+#define     ASPEED_PECI_MESSAGE_NEGO		2
+#define   ASPEED_PECI_INT_MASK			GENMASK(4, 0)
+#define     ASPEED_PECI_INT_BUS_TIMEOUT		BIT(4)
+#define     ASPEED_PECI_INT_BUS_CONTENTION	BIT(3)
+#define     ASPEED_PECI_INT_WR_FCS_BAD		BIT(2)
+#define     ASPEED_PECI_INT_WR_FCS_ABORT	BIT(1)
+#define     ASPEED_PECI_INT_CMD_DONE		BIT(0)
+
+/* Interrupt Status Register */
+#define ASPEED_PECI_INT_STS			0x1c
+#define   ASPEED_PECI_INT_TIMING_RESULT_MASK	GENMASK(29, 16)
+	  /* bits[4..0]: Same bit fields in the 'Interrupt Register' */
+
+/* Rx/Tx Data Buffer Registers */
+#define ASPEED_PECI_WR_DATA0			0x20
+#define ASPEED_PECI_WR_DATA1			0x24
+#define ASPEED_PECI_WR_DATA2			0x28
+#define ASPEED_PECI_WR_DATA3			0x2c
+#define ASPEED_PECI_RD_DATA0			0x30
+#define ASPEED_PECI_RD_DATA1			0x34
+#define ASPEED_PECI_RD_DATA2			0x38
+#define ASPEED_PECI_RD_DATA3			0x3c
+#define ASPEED_PECI_WR_DATA4			0x40
+#define ASPEED_PECI_WR_DATA5			0x44
+#define ASPEED_PECI_WR_DATA6			0x48
+#define ASPEED_PECI_WR_DATA7			0x4c
+#define ASPEED_PECI_RD_DATA4			0x50
+#define ASPEED_PECI_RD_DATA5			0x54
+#define ASPEED_PECI_RD_DATA6			0x58
+#define ASPEED_PECI_RD_DATA7			0x5c
+#define   ASPEED_PECI_DATA_BUF_SIZE_MAX		32
+
+/* Timing Negotiation */
+#define ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT	8
+#define ASPEED_PECI_RD_SAMPLING_POINT_MAX	(BIT(4) - 1)
+#define ASPEED_PECI_CLK_DIV_DEFAULT		0
+#define ASPEED_PECI_CLK_DIV_MAX			(BIT(3) - 1)
+#define ASPEED_PECI_MSG_TIMING_DEFAULT		1
+#define ASPEED_PECI_MSG_TIMING_MAX		(BIT(8) - 1)
+#define ASPEED_PECI_ADDR_TIMING_DEFAULT		1
+#define ASPEED_PECI_ADDR_TIMING_MAX		(BIT(8) - 1)
+
+/* Timeout */
+#define ASPEED_PECI_IDLE_CHECK_TIMEOUT_US	(50 * USEC_PER_MSEC)
+#define ASPEED_PECI_IDLE_CHECK_INTERVAL_US	(10 * USEC_PER_MSEC)
+#define ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT	(1000)
+#define ASPEED_PECI_CMD_TIMEOUT_MS_MAX		(1000)
+
+struct aspeed_peci {
+	struct peci_controller *controller;
+	struct device *dev;
+	void __iomem *base;
+	struct clk *clk;
+	struct reset_control *rst;
+	int irq;
+	spinlock_t lock; /* to sync completion status handling */
+	struct completion xfer_complete;
+	u32 status;
+	u32 cmd_timeout_ms;
+	u32 msg_timing;
+	u32 addr_timing;
+	u32 rd_sampling_point;
+	u32 clk_div;
+};
+
+static void aspeed_peci_init_regs(struct aspeed_peci *priv)
+{
+	u32 val;
+
+	val = FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK, ASPEED_PECI_CLK_DIV_DEFAULT);
+	val |= ASPEED_PECI_CTRL_PECI_CLK_EN;
+	writel(val, priv->base + ASPEED_PECI_CTRL);
+	/*
+	 * Timing negotiation period setting.
+	 * The unit of the programmed value is 4 times of PECI clock period.
+	 */
+	val = FIELD_PREP(ASPEED_PECI_T_NEGO_MSG_MASK, priv->msg_timing);
+	val |= FIELD_PREP(ASPEED_PECI_T_NEGO_ADDR_MASK, priv->addr_timing);
+	writel(val, priv->base + ASPEED_PECI_TIMING_NEGOTIATION);
+
+	/* Clear interrupts */
+	val = readl(priv->base + ASPEED_PECI_INT_STS) | ASPEED_PECI_INT_MASK;
+	writel(val, priv->base + ASPEED_PECI_INT_STS);
+
+	/* Set timing negotiation mode and enable interrupts */
+	val = FIELD_PREP(ASPEED_PECI_TIMING_NEGO_SEL_MASK, ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO);
+	val |= ASPEED_PECI_INT_MASK;
+	writel(val, priv->base + ASPEED_PECI_INT_CTRL);
+
+	val = FIELD_PREP(ASPEED_PECI_CTRL_SAMPLING_MASK, priv->rd_sampling_point);
+	val |= FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK, priv->clk_div);
+	val |= ASPEED_PECI_CTRL_PECI_EN;
+	val |= ASPEED_PECI_CTRL_PECI_CLK_EN;
+	writel(val, priv->base + ASPEED_PECI_CTRL);
+}
+
+static inline int aspeed_peci_check_idle(struct aspeed_peci *priv)
+{
+	u32 cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
+
+	if (FIELD_GET(ASPEED_PECI_CMD_STS_MASK, cmd_sts) == ASPEED_PECI_CMD_STS_ADDR_T_NEGO)
+		aspeed_peci_init_regs(priv);
+
+	return readl_poll_timeout(priv->base + ASPEED_PECI_CMD,
+				  cmd_sts,
+				  !(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK),
+				  ASPEED_PECI_IDLE_CHECK_INTERVAL_US,
+				  ASPEED_PECI_IDLE_CHECK_TIMEOUT_US);
+}
+
+static int aspeed_peci_xfer(struct peci_controller *controller,
+			    u8 addr, struct peci_request *req)
+{
+	struct aspeed_peci *priv = dev_get_drvdata(controller->dev.parent);
+	unsigned long flags, timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
+	u32 peci_head;
+	int ret;
+
+	if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
+	    req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
+		return -EINVAL;
+
+	/* Check command sts and bus idle state */
+	ret = aspeed_peci_check_idle(priv);
+	if (ret)
+		return ret; /* -ETIMEDOUT */
+
+	spin_lock_irqsave(&priv->lock, flags);
+	reinit_completion(&priv->xfer_complete);
+
+	peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
+		    FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
+		    FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
+
+	writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
+
+	memcpy_toio(priv->base + ASPEED_PECI_WR_DATA0, req->tx.buf, min_t(u8, req->tx.len, 16));
+	if (req->tx.len > 16)
+		memcpy_toio(priv->base + ASPEED_PECI_WR_DATA4, req->tx.buf + 16,
+			    req->tx.len - 16);
+
+	dev_dbg(priv->dev, "HEAD : 0x%08x\n", peci_head);
+	print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf, req->tx.len);
+
+	priv->status = 0;
+	writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	ret = wait_for_completion_interruptible_timeout(&priv->xfer_complete, timeout);
+	if (ret < 0)
+		return ret;
+
+	if (ret == 0) {
+		dev_dbg(priv->dev, "Timeout waiting for a response!\n");
+		return -ETIMEDOUT;
+	}
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	writel(0, priv->base + ASPEED_PECI_CMD);
+
+	if (priv->status != ASPEED_PECI_INT_CMD_DONE) {
+		spin_unlock_irqrestore(&priv->lock, flags);
+		dev_dbg(priv->dev, "No valid response!\n");
+		return -EIO;
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	memcpy_fromio(req->rx.buf, priv->base + ASPEED_PECI_RD_DATA0, min_t(u8, req->rx.len, 16));
+	if (req->rx.len > 16)
+		memcpy_fromio(req->rx.buf + 16, priv->base + ASPEED_PECI_RD_DATA4,
+			      req->rx.len - 16);
+
+	print_hex_dump_bytes("RX : ", DUMP_PREFIX_NONE, req->rx.buf, req->rx.len);
+
+	return 0;
+}
+
+static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
+{
+	struct aspeed_peci *priv = arg;
+	u32 status;
+
+	spin_lock(&priv->lock);
+	status = readl(priv->base + ASPEED_PECI_INT_STS);
+	writel(status, priv->base + ASPEED_PECI_INT_STS);
+	priv->status |= (status & ASPEED_PECI_INT_MASK);
+
+	/*
+	 * In most cases, interrupt bits will be set one by one but also note
+	 * that multiple interrupt bits could be set at the same time.
+	 */
+	if (status & ASPEED_PECI_INT_BUS_TIMEOUT)
+		dev_dbg_ratelimited(priv->dev, "ASPEED_PECI_INT_BUS_TIMEOUT\n");
+
+	if (status & ASPEED_PECI_INT_BUS_CONTENTION)
+		dev_dbg_ratelimited(priv->dev, "ASPEED_PECI_INT_BUS_CONTENTION\n");
+
+	if (status & ASPEED_PECI_INT_WR_FCS_BAD)
+		dev_dbg_ratelimited(priv->dev, "ASPEED_PECI_INT_WR_FCS_BAD\n");
+
+	if (status & ASPEED_PECI_INT_WR_FCS_ABORT)
+		dev_dbg_ratelimited(priv->dev, "ASPEED_PECI_INT_WR_FCS_ABORT\n");
+
+	/*
+	 * All commands should be ended up with a ASPEED_PECI_INT_CMD_DONE bit
+	 * set even in an error case.
+	 */
+	if (status & ASPEED_PECI_INT_CMD_DONE)
+		complete(&priv->xfer_complete);
+
+	spin_unlock(&priv->lock);
+
+	return IRQ_HANDLED;
+}
+
+static void aspeed_peci_property_sanitize(struct device *dev, const char *propname,
+					  u32 min, u32 max, u32 default_val, u32 *propval)
+{
+	u32 val;
+	int ret;
+
+	ret = device_property_read_u32(dev, propname, &val);
+	if (ret) {
+		val = default_val;
+	} else if (val > max || val < min) {
+		dev_warn(dev, "Invalid %s: %u, falling back to: %u\n",
+			 propname, val, default_val);
+
+		val = default_val;
+	}
+
+	*propval = val;
+}
+
+static void aspeed_peci_property_setup(struct aspeed_peci *priv)
+{
+	aspeed_peci_property_sanitize(priv->dev, "aspeed,clock-divider",
+				      0, ASPEED_PECI_CLK_DIV_MAX,
+				      ASPEED_PECI_CLK_DIV_DEFAULT, &priv->clk_div);
+	aspeed_peci_property_sanitize(priv->dev, "aspeed,msg-timing",
+				      0, ASPEED_PECI_MSG_TIMING_MAX,
+				      ASPEED_PECI_MSG_TIMING_DEFAULT, &priv->msg_timing);
+	aspeed_peci_property_sanitize(priv->dev, "aspeed,addr-timing",
+				      0, ASPEED_PECI_ADDR_TIMING_MAX,
+				      ASPEED_PECI_ADDR_TIMING_DEFAULT, &priv->addr_timing);
+	aspeed_peci_property_sanitize(priv->dev, "aspeed,rd-sampling-point",
+				      0, ASPEED_PECI_RD_SAMPLING_POINT_MAX,
+				      ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT,
+				      &priv->rd_sampling_point);
+	aspeed_peci_property_sanitize(priv->dev, "cmd-timeout-ms",
+				      1, ASPEED_PECI_CMD_TIMEOUT_MS_MAX,
+				      ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT, &priv->cmd_timeout_ms);
+}
+
+static struct peci_controller_ops aspeed_ops = {
+	.xfer = aspeed_peci_xfer,
+};
+
+static void aspeed_peci_reset_control_release(void *data)
+{
+	reset_control_assert(data);
+}
+
+int aspeed_peci_reset_control_deassert(struct device *dev, struct reset_control *rst)
+{
+	int ret;
+
+	ret = reset_control_deassert(rst);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, aspeed_peci_reset_control_release, rst);
+}
+
+static void aspeed_peci_clk_release(void *data)
+{
+	clk_disable_unprepare(data);
+}
+
+static int aspeed_peci_clk_enable(struct device *dev, struct clk *clk)
+{
+	int ret;
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, aspeed_peci_clk_release, clk);
+}
+
+static int aspeed_peci_probe(struct platform_device *pdev)
+{
+	struct peci_controller *controller;
+	struct aspeed_peci *priv;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
+	dev_set_drvdata(priv->dev, priv);
+
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (!priv->irq)
+		return priv->irq;
+
+	ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_peci_irq_handler,
+			       0, "peci-aspeed", priv);
+	if (ret)
+		return ret;
+
+	init_completion(&priv->xfer_complete);
+	spin_lock_init(&priv->lock);
+
+	priv->rst = devm_reset_control_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->rst))
+		return dev_err_probe(priv->dev, PTR_ERR(priv->rst),
+				     "failed to get reset control\n");
+
+	ret = aspeed_peci_reset_control_deassert(priv->dev, priv->rst);
+	if (ret)
+		return dev_err_probe(priv->dev, ret, "cannot deassert reset control\n");
+
+	priv->clk = devm_clk_get(priv->dev, NULL);
+	if (IS_ERR(priv->clk))
+		return dev_err_probe(priv->dev, PTR_ERR(priv->clk), "failed to get clk\n");
+
+	ret = aspeed_peci_clk_enable(priv->dev, priv->clk);
+	if (ret)
+		return dev_err_probe(priv->dev, ret, "failed to enable clock\n");
+
+	aspeed_peci_property_setup(priv);
+
+	aspeed_peci_init_regs(priv);
+
+	controller = devm_peci_controller_add(priv->dev, &aspeed_ops);
+	if (IS_ERR(controller))
+		return dev_err_probe(priv->dev, PTR_ERR(controller),
+				     "failed to add aspeed peci controller\n");
+
+	priv->controller = controller;
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_peci_of_table[] = {
+	{ .compatible = "aspeed,ast2400-peci", },
+	{ .compatible = "aspeed,ast2500-peci", },
+	{ .compatible = "aspeed,ast2600-peci", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, aspeed_peci_of_table);
+
+static struct platform_driver aspeed_peci_driver = {
+	.probe  = aspeed_peci_probe,
+	.driver = {
+		.name           = "peci-aspeed",
+		.of_match_table = aspeed_peci_of_table,
+	},
+};
+module_platform_driver(aspeed_peci_driver);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_DESCRIPTION("ASPEED PECI driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI);
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:27 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:27 +0200
Subject: [PATCH v2 08/15] peci: Add device detection
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-9-iwona.winiarska@intel.com>

Since PECI devices are discoverable, we can dynamically detect devices
that are actually available in the system.

This change complements the earlier implementation by rescanning PECI
bus to detect available devices. For this purpose, it also introduces the
minimal API for PECI requests.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 drivers/peci/Makefile   |   2 +-
 drivers/peci/core.c     |  33 ++++++++++++
 drivers/peci/device.c   | 114 ++++++++++++++++++++++++++++++++++++++++
 drivers/peci/internal.h |  14 +++++
 drivers/peci/request.c  |  50 ++++++++++++++++++
 5 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 drivers/peci/device.c
 create mode 100644 drivers/peci/request.c

diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index 926d8df15cbd..c5f9d3fe21bb 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 # Core functionality
-peci-y := core.o
+peci-y := core.o request.o device.o
 obj-$(CONFIG_PECI) += peci.o
 
 # Hardware specific bus drivers
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index 7b3938af0396..d143f1a7fe98 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -34,6 +34,20 @@ struct device_type peci_controller_type = {
 	.release	= peci_controller_dev_release,
 };
 
+static int peci_controller_scan_devices(struct peci_controller *controller)
+{
+	int ret;
+	u8 addr;
+
+	for (addr = PECI_BASE_ADDR; addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX; addr++) {
+		ret = peci_device_create(controller, addr);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static struct peci_controller *peci_controller_alloc(struct device *dev,
 						     struct peci_controller_ops *ops)
 {
@@ -76,10 +90,23 @@ static struct peci_controller *peci_controller_alloc(struct device *dev,
 	return ERR_PTR(ret);
 }
 
+static int unregister_child(struct device *dev, void *dummy)
+{
+	peci_device_destroy(to_peci_device(dev));
+
+	return 0;
+}
+
 static void unregister_controller(void *_controller)
 {
 	struct peci_controller *controller = _controller;
 
+	/*
+	 * Detach any active PECI devices. This can't fail, thus we do not
+	 * check the returned value.
+	 */
+	device_for_each_child_reverse(&controller->dev, NULL, unregister_child);
+
 	device_unregister(&controller->dev);
 }
 
@@ -115,6 +142,12 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
 	if (ret)
 		return ERR_PTR(ret);
 
+	/*
+	 * Ignoring retval since failures during scan are non-critical for
+	 * controller itself.
+	 */
+	peci_controller_scan_devices(controller);
+
 	return controller;
 
 err:
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
new file mode 100644
index 000000000000..32811248997b
--- /dev/null
+++ b/drivers/peci/device.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/peci.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+static int peci_detect(struct peci_controller *controller, u8 addr)
+{
+	struct peci_request *req;
+	int ret;
+
+	/*
+	 * PECI Ping is a command encoded by tx_len = 0, rx_len = 0.
+	 * We expect correct Write FCS if the device at the target address
+	 * is able to respond.
+	 */
+	req = peci_request_alloc(NULL, 0, 0);
+	if (!req)
+		return -ENOMEM;
+
+	mutex_lock(&controller->bus_lock);
+	ret = controller->ops->xfer(controller, addr, req);
+	mutex_unlock(&controller->bus_lock);
+
+	peci_request_free(req);
+
+	return ret;
+}
+
+static bool peci_addr_valid(u8 addr)
+{
+	return addr >= PECI_BASE_ADDR && addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX;
+}
+
+static int peci_dev_exists(struct device *dev, void *data)
+{
+	struct peci_device *device = to_peci_device(dev);
+	u8 *addr = data;
+
+	if (device->addr == *addr)
+		return -EBUSY;
+
+	return 0;
+}
+
+int peci_device_create(struct peci_controller *controller, u8 addr)
+{
+	struct peci_device *device;
+	int ret;
+
+	if (WARN_ON(!peci_addr_valid(addr)))
+		return -EINVAL;
+
+	/* Check if we have already detected this device before. */
+	ret = device_for_each_child(&controller->dev, &addr, peci_dev_exists);
+	if (ret)
+		return 0;
+
+	ret = peci_detect(controller, addr);
+	if (ret) {
+		/*
+		 * Device not present or host state doesn't allow successful
+		 * detection at this time.
+		 */
+		if (ret == -EIO || ret == -ETIMEDOUT)
+			return 0;
+
+		return ret;
+	}
+
+	device = kzalloc(sizeof(*device), GFP_KERNEL);
+	if (!device)
+		return -ENOMEM;
+
+	device->addr = addr;
+	device->dev.parent = &controller->dev;
+	device->dev.bus = &peci_bus_type;
+	device->dev.type = &peci_device_type;
+
+	ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
+	if (ret)
+		goto err_free;
+
+	ret = device_register(&device->dev);
+	if (ret)
+		goto err_put;
+
+	return 0;
+
+err_put:
+	put_device(&device->dev);
+err_free:
+	kfree(device);
+
+	return ret;
+}
+
+void peci_device_destroy(struct peci_device *device)
+{
+	device_unregister(&device->dev);
+}
+
+static void peci_device_release(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+
+	kfree(device);
+}
+
+struct device_type peci_device_type = {
+	.release	= peci_device_release,
+};
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 918dea745a86..57d11a902c5d 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -8,6 +8,20 @@
 #include <linux/types.h>
 
 struct peci_controller;
+struct peci_device;
+struct peci_request;
+
+/* PECI CPU address range 0x30-0x37 */
+#define PECI_BASE_ADDR		0x30
+#define PECI_DEVICE_NUM_MAX	8
+
+struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len);
+void peci_request_free(struct peci_request *req);
+
+extern struct device_type peci_device_type;
+
+int peci_device_create(struct peci_controller *controller, u8 addr);
+void peci_device_destroy(struct peci_device *device);
 
 extern struct bus_type peci_bus_type;
 
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
new file mode 100644
index 000000000000..81b567bc7b87
--- /dev/null
+++ b/drivers/peci/request.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/export.h>
+#include <linux/peci.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "internal.h"
+
+/**
+ * peci_request_alloc() - allocate &struct peci_requests
+ * @device: PECI device to which request is going to be sent
+ * @tx_len: TX length
+ * @rx_len: RX length
+ *
+ * Return: A pointer to a newly allocated &struct peci_request on success or NULL otherwise.
+ */
+struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len)
+{
+	struct peci_request *req;
+
+	if (WARN_ON_ONCE(tx_len > PECI_REQUEST_MAX_BUF_SIZE || rx_len > PECI_REQUEST_MAX_BUF_SIZE))
+		return NULL;
+	/*
+	 * PECI controllers that we are using now don't support DMA, this
+	 * should be converted to DMA API once support for controllers that do
+	 * allow it is added to avoid an extra copy.
+	 */
+	req = kzalloc(sizeof(*req), GFP_KERNEL);
+	if (!req)
+		return NULL;
+
+	req->device = device;
+	req->tx.len = tx_len;
+	req->rx.len = rx_len;
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_alloc, PECI);
+
+/**
+ * peci_request_free() - free peci_request
+ * @req: the PECI request to be freed
+ */
+void peci_request_free(struct peci_request *req)
+{
+	kfree(req);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_free, PECI);
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:28 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:28 +0200
Subject: [PATCH v2 09/15] peci: Add sysfs interface for PECI bus
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-10-iwona.winiarska@intel.com>

PECI devices may not be discoverable at the time when PECI controller is
being added (e.g. BMC can boot up when the Host system is still in S5).
Since we currently don't have the capabilities to figure out the Host
system state inside the PECI subsystem itself, we have to rely on
userspace to do it for us.

In the future, PECI subsystem may be expanded with mechanisms that allow
us to avoid depending on userspace interaction (e.g. CPU presence could
be detected using GPIO, and the information on whether it's discoverable
could be obtained over IPMI).
Unfortunately, those methods may ultimately not be available (support
will vary from platform to platform), which means that we still need
platform independent method triggered by userspace.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
---
 Documentation/ABI/testing/sysfs-bus-peci | 16 +++++
 drivers/peci/Makefile                    |  2 +-
 drivers/peci/core.c                      |  3 +-
 drivers/peci/device.c                    |  1 +
 drivers/peci/internal.h                  |  5 ++
 drivers/peci/sysfs.c                     | 82 ++++++++++++++++++++++++
 6 files changed, 107 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-peci
 create mode 100644 drivers/peci/sysfs.c

diff --git a/Documentation/ABI/testing/sysfs-bus-peci b/Documentation/ABI/testing/sysfs-bus-peci
new file mode 100644
index 000000000000..56c2b2216bbd
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-peci
@@ -0,0 +1,16 @@
+What:		/sys/bus/peci/rescan
+Date:		July 2021
+KernelVersion:	5.15
+Contact:	Iwona Winiarska <iwona.winiarska at intel.com>
+Description:
+		Writing a non-zero value to this attribute will
+		initiate scan for PECI devices on all PECI controllers
+		in the system.
+
+What:		/sys/bus/peci/devices/<controller_id>-<device_addr>/remove
+Date:		July 2021
+KernelVersion:	5.15
+Contact:	Iwona Winiarska <iwona.winiarska at intel.com>
+Description:
+		Writing a non-zero value to this attribute will
+		remove the PECI device and any of its children.
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index c5f9d3fe21bb..917f689e147a 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 # Core functionality
-peci-y := core.o request.o device.o
+peci-y := core.o request.o device.o sysfs.o
 obj-$(CONFIG_PECI) += peci.o
 
 # Hardware specific bus drivers
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index d143f1a7fe98..c473acb3c2a0 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -34,7 +34,7 @@ struct device_type peci_controller_type = {
 	.release	= peci_controller_dev_release,
 };
 
-static int peci_controller_scan_devices(struct peci_controller *controller)
+int peci_controller_scan_devices(struct peci_controller *controller)
 {
 	int ret;
 	u8 addr;
@@ -159,6 +159,7 @@ EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
 
 struct bus_type peci_bus_type = {
 	.name		= "peci",
+	.bus_groups	= peci_bus_groups,
 };
 
 static int __init peci_init(void)
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index 32811248997b..d77d9dabd51e 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -110,5 +110,6 @@ static void peci_device_release(struct device *dev)
 }
 
 struct device_type peci_device_type = {
+	.groups		= peci_device_groups,
 	.release	= peci_device_release,
 };
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 57d11a902c5d..978e12c8e1d3 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 
 struct peci_controller;
+struct attribute_group;
 struct peci_device;
 struct peci_request;
 
@@ -19,12 +20,16 @@ struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u
 void peci_request_free(struct peci_request *req);
 
 extern struct device_type peci_device_type;
+extern const struct attribute_group *peci_device_groups[];
 
 int peci_device_create(struct peci_controller *controller, u8 addr);
 void peci_device_destroy(struct peci_device *device);
 
 extern struct bus_type peci_bus_type;
+extern const struct attribute_group *peci_bus_groups[];
 
 extern struct device_type peci_controller_type;
 
+int peci_controller_scan_devices(struct peci_controller *controller);
+
 #endif /* __PECI_INTERNAL_H */
diff --git a/drivers/peci/sysfs.c b/drivers/peci/sysfs.c
new file mode 100644
index 000000000000..db9ef05776e3
--- /dev/null
+++ b/drivers/peci/sysfs.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/peci.h>
+
+#include "internal.h"
+
+static int rescan_controller(struct device *dev, void *data)
+{
+	if (dev->type != &peci_controller_type)
+		return 0;
+
+	return peci_controller_scan_devices(to_peci_controller(dev));
+}
+
+static ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count)
+{
+	bool res;
+	int ret;
+
+	ret = kstrtobool(buf, &res);
+	if (ret)
+		return ret;
+
+	if (!res)
+		return count;
+
+	ret = bus_for_each_dev(&peci_bus_type, NULL, NULL, rescan_controller);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static BUS_ATTR_WO(rescan);
+
+static struct attribute *peci_bus_attrs[] = {
+	&bus_attr_rescan.attr,
+	NULL
+};
+
+static const struct attribute_group peci_bus_group = {
+	.attrs = peci_bus_attrs,
+};
+
+const struct attribute_group *peci_bus_groups[] = {
+	&peci_bus_group,
+	NULL
+};
+
+static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct peci_device *device = to_peci_device(dev);
+	bool res;
+	int ret;
+
+	ret = kstrtobool(buf, &res);
+	if (ret)
+		return ret;
+
+	if (res && device_remove_file_self(dev, attr))
+		peci_device_destroy(device);
+
+	return count;
+}
+static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0200, NULL, remove_store);
+
+static struct attribute *peci_device_attrs[] = {
+	&dev_attr_remove.attr,
+	NULL
+};
+
+static const struct attribute_group peci_device_group = {
+	.attrs = peci_device_attrs,
+};
+
+const struct attribute_group *peci_device_groups[] = {
+	&peci_device_group,
+	NULL
+};
-- 
2.31.1



From masahiroy at kernel.org  Tue Aug  3 04:35:19 2021
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Tue, 3 Aug 2021 20:35:19 +0900
Subject: [PATCH] arm64: move the (z)install rules to arch/arm64/Makefile
In-Reply-To: <20210803090626.GA30265@willie-the-truck>
References: <20210729140527.443116-1-masahiroy@kernel.org>
 <20210802124624.GG18685@arm.com>
 <CAK7LNARFWRgGsea03mZJfSPjyxYLxz3g6fjTs9aon9hxYvsxcw@mail.gmail.com>
 <20210803090626.GA30265@willie-the-truck>
Message-ID: <CAK7LNAQ1pRhpZYVEnyZCdqizFRo+1T_fJjCXciG42a_qNnKsnQ@mail.gmail.com>

On Tue, Aug 3, 2021 at 6:06 PM Will Deacon <will at kernel.org> wrote:
>
> On Tue, Aug 03, 2021 at 02:40:44PM +0900, Masahiro Yamada wrote:
> > On Mon, Aug 2, 2021 at 9:46 PM Catalin Marinas <catalin.marinas at arm.com> wrote:
> > >
> > > On Thu, Jul 29, 2021 at 11:05:27PM +0900, Masahiro Yamada wrote:
> > > > Currently, the (z)install targets in arch/arm64/Makefile descend into
> > > > arch/arm64/boot/Makefile to invoke the shell script, but there is no
> > > > good reason to do so.
> > > >
> > > > arch/arm64/Makefile can run the shell script directly.
> > > >
> > > > Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> > > > ---
> > > >
> > > >  arch/arm64/Makefile      | 7 +++++--
> > > >  arch/arm64/boot/Makefile | 8 --------
> > > >  2 files changed, 5 insertions(+), 10 deletions(-)
> > >
> > > Is this part of some cross-arch clean-up? I can see x86 for example does
> > > the same thing.
> > >
> > > Thanks.
> > >
> >
> > Yes. I want to do these cleanups tree-wide, but
> > I sent patches per arch.
> >
> > Please pick it up to your arm64 tree
> > if you do not mind.
>
> Just to confirm -- this would be for 5.15, right?
>
> Will


Right.

This is not a bug fix, but a clean-up.

So, we can queue it for the next MW.


-- 
Best Regards
Masahiro Yamada


From iwona.winiarska at intel.com  Tue Aug  3 04:31:29 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:29 +0200
Subject: [PATCH v2 10/15] peci: Add support for PECI device drivers
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-11-iwona.winiarska@intel.com>

Here we're adding support for PECI device drivers, which unlike PECI
controller drivers are actually able to provide functionalities to
userspace.

We're also extending peci_request API to allow querying more details
about PECI device (e.g. model/family), that's going to be used to find
a compatible peci_driver.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 drivers/peci/Kconfig    |   1 +
 drivers/peci/core.c     |  49 +++++++++
 drivers/peci/device.c   | 105 ++++++++++++++++++++
 drivers/peci/internal.h |  75 ++++++++++++++
 drivers/peci/request.c  | 214 ++++++++++++++++++++++++++++++++++++++++
 include/linux/peci.h    |  19 ++++
 lib/Kconfig             |   2 +-
 7 files changed, 464 insertions(+), 1 deletion(-)

diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
index 99279df97a78..1d0532e3a801 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -2,6 +2,7 @@
 
 menuconfig PECI
 	tristate "PECI support"
+	select GENERIC_LIB_X86
 	help
 	  The Platform Environment Control Interface (PECI) is an interface
 	  that provides a communication channel to Intel processors and
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index c473acb3c2a0..33c07920493d 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -157,8 +157,57 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
 }
 EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
 
+static const struct peci_device_id *
+peci_bus_match_device_id(const struct peci_device_id *id, struct peci_device *device)
+{
+	while (id->family != 0) {
+		if (id->family == device->info.family &&
+		    id->model == device->info.model)
+			return id;
+		id++;
+	}
+
+	return NULL;
+}
+
+static int peci_bus_device_match(struct device *dev, struct device_driver *drv)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *peci_drv = to_peci_driver(drv);
+
+	if (dev->type != &peci_device_type)
+		return 0;
+
+	if (peci_bus_match_device_id(peci_drv->id_table, device))
+		return 1;
+
+	return 0;
+}
+
+static int peci_bus_device_probe(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *driver = to_peci_driver(dev->driver);
+
+	return driver->probe(device, peci_bus_match_device_id(driver->id_table, device));
+}
+
+static int peci_bus_device_remove(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *driver = to_peci_driver(dev->driver);
+
+	if (driver->remove)
+		driver->remove(device);
+
+	return 0;
+}
+
 struct bus_type peci_bus_type = {
 	.name		= "peci",
+	.match		= peci_bus_device_match,
+	.probe		= peci_bus_device_probe,
+	.remove		= peci_bus_device_remove,
 	.bus_groups	= peci_bus_groups,
 };
 
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index d77d9dabd51e..a78c02399574 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -1,11 +1,85 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // Copyright (c) 2018-2021 Intel Corporation
 
+#include <linux/bitfield.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
+#include <linux/x86/cpu.h>
 
 #include "internal.h"
 
+#define REVISION_NUM_MASK GENMASK(15, 8)
+static int peci_get_revision(struct peci_device *device, u8 *revision)
+{
+	struct peci_request *req;
+	u64 dib;
+
+	req = peci_get_dib(device);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	/*
+	 * PECI device may be in a state where it is unable to return a proper
+	 * DIB, in which case it returns 0 as DIB value.
+	 * Let's treat this as an error to avoid carrying on with the detection
+	 * using invalid revision.
+	 */
+	dib = peci_request_data_dib(req);
+	if (dib == 0) {
+		peci_request_free(req);
+		return -EIO;
+	}
+
+	*revision = FIELD_GET(REVISION_NUM_MASK, dib);
+
+	peci_request_free(req);
+
+	return 0;
+}
+
+static int peci_get_cpu_id(struct peci_device *device, u32 *cpu_id)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_pkg_cfg_readl(device, PECI_PCS_PKG_ID, PECI_PKG_ID_CPU_ID);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*cpu_id = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+
+static int peci_device_info_init(struct peci_device *device)
+{
+	u8 revision;
+	u32 cpu_id;
+	int ret;
+
+	ret = peci_get_cpu_id(device, &cpu_id);
+	if (ret)
+		return ret;
+
+	device->info.family = x86_family(cpu_id);
+	device->info.model = x86_model(cpu_id);
+
+	ret = peci_get_revision(device, &revision);
+	if (ret)
+		return ret;
+	device->info.peci_revision = revision;
+
+	device->info.socket_id = device->addr - PECI_BASE_ADDR;
+
+	return 0;
+}
+
 static int peci_detect(struct peci_controller *controller, u8 addr)
 {
 	struct peci_request *req;
@@ -79,6 +153,10 @@ int peci_device_create(struct peci_controller *controller, u8 addr)
 	device->dev.bus = &peci_bus_type;
 	device->dev.type = &peci_device_type;
 
+	ret = peci_device_info_init(device);
+	if (ret)
+		goto err_free;
+
 	ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
 	if (ret)
 		goto err_free;
@@ -102,6 +180,33 @@ void peci_device_destroy(struct peci_device *device)
 	device_unregister(&device->dev);
 }
 
+int __peci_driver_register(struct peci_driver *driver, struct module *owner,
+			   const char *mod_name)
+{
+	driver->driver.bus = &peci_bus_type;
+	driver->driver.owner = owner;
+	driver->driver.mod_name = mod_name;
+
+	if (!driver->probe) {
+		pr_err("peci: trying to register driver without probe callback\n");
+		return -EINVAL;
+	}
+
+	if (!driver->id_table) {
+		pr_err("peci: trying to register driver without device id table\n");
+		return -EINVAL;
+	}
+
+	return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_NS_GPL(__peci_driver_register, PECI);
+
+void peci_driver_unregister(struct peci_driver *driver)
+{
+	driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, PECI);
+
 static void peci_device_release(struct device *dev)
 {
 	struct peci_device *device = to_peci_device(dev);
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 978e12c8e1d3..d661e1b65694 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -19,6 +19,34 @@ struct peci_request;
 struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len);
 void peci_request_free(struct peci_request *req);
 
+int peci_request_status(struct peci_request *req);
+u64 peci_request_data_dib(struct peci_request *req);
+
+u8 peci_request_data_readb(struct peci_request *req);
+u16 peci_request_data_readw(struct peci_request *req);
+u32 peci_request_data_readl(struct peci_request *req);
+u64 peci_request_data_readq(struct peci_request *req);
+
+struct peci_request *peci_get_dib(struct peci_device *device);
+struct peci_request *peci_get_temp(struct peci_device *device);
+
+struct peci_request *peci_pkg_cfg_readb(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_pkg_cfg_readw(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_pkg_cfg_readl(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_pkg_cfg_readq(struct peci_device *device, u8 index, u16 param);
+
+/**
+ * struct peci_device_id - PECI device data to match
+ * @data: pointer to driver private data specific to device
+ * @family: device family
+ * @model: device model
+ */
+struct peci_device_id {
+	const void *data;
+	u16 family;
+	u8 model;
+};
+
 extern struct device_type peci_device_type;
 extern const struct attribute_group *peci_device_groups[];
 
@@ -28,6 +56,53 @@ void peci_device_destroy(struct peci_device *device);
 extern struct bus_type peci_bus_type;
 extern const struct attribute_group *peci_bus_groups[];
 
+/**
+ * struct peci_driver - PECI driver
+ * @driver: inherit device driver
+ * @probe: probe callback
+ * @remove: remove callback
+ * @id_table: PECI device match table to decide which device to bind
+ */
+struct peci_driver {
+	struct device_driver driver;
+	int (*probe)(struct peci_device *device, const struct peci_device_id *id);
+	void (*remove)(struct peci_device *device);
+	const struct peci_device_id *id_table;
+};
+
+static inline struct peci_driver *to_peci_driver(struct device_driver *d)
+{
+	return container_of(d, struct peci_driver, driver);
+}
+
+int __peci_driver_register(struct peci_driver *driver, struct module *owner,
+			   const char *mod_name);
+/**
+ * peci_driver_register() - register PECI driver
+ * @driver: the driver to be registered
+ * @owner: owner module of the driver being registered
+ * @mod_name: module name string
+ *
+ * PECI drivers that don't need to do anything special in module init should
+ * use the convenience "module_peci_driver" macro instead
+ *
+ * Return: zero on success, else a negative error code.
+ */
+#define peci_driver_register(driver) \
+	__peci_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+void peci_driver_unregister(struct peci_driver *driver);
+
+/**
+ * module_peci_driver() - helper macro for registering a modular PECI driver
+ * @__peci_driver: peci_driver struct
+ *
+ * Helper macro for PECI drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_peci_driver(__peci_driver) \
+	module_driver(__peci_driver, peci_driver_register, peci_driver_unregister)
+
 extern struct device_type peci_controller_type;
 
 int peci_controller_scan_devices(struct peci_controller *controller);
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
index 81b567bc7b87..fe032d5a5e1b 100644
--- a/drivers/peci/request.c
+++ b/drivers/peci/request.c
@@ -1,13 +1,140 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // Copyright (c) 2021 Intel Corporation
 
+#include <linux/bug.h>
 #include <linux/export.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 
+#include <asm/unaligned.h>
+
 #include "internal.h"
 
+#define PECI_GET_DIB_CMD		0xf7
+#define  PECI_GET_DIB_WR_LEN		1
+#define  PECI_GET_DIB_RD_LEN		8
+
+#define PECI_RDPKGCFG_CMD		0xa1
+#define  PECI_RDPKGCFG_WR_LEN		5
+#define  PECI_RDPKGCFG_RD_LEN_BASE	1
+#define PECI_WRPKGCFG_CMD		0xa5
+#define  PECI_WRPKGCFG_WR_LEN_BASE	6
+#define  PECI_WRPKGCFG_RD_LEN		1
+
+/* Device Specific Completion Code (CC) Definition */
+#define PECI_CC_SUCCESS				0x40
+#define PECI_CC_NEED_RETRY			0x80
+#define PECI_CC_OUT_OF_RESOURCE			0x81
+#define PECI_CC_UNAVAIL_RESOURCE		0x82
+#define PECI_CC_INVALID_REQ			0x90
+#define PECI_CC_MCA_ERROR			0x91
+#define PECI_CC_CATASTROPHIC_MCA_ERROR		0x93
+#define PECI_CC_FATAL_MCA_ERROR			0x94
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB		0x98
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB_IERR	0x9B
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB_MCA	0x9C
+
+#define PECI_RETRY_BIT			BIT(0)
+
+#define PECI_RETRY_TIMEOUT		msecs_to_jiffies(700)
+#define PECI_RETRY_INTERVAL_MIN		msecs_to_jiffies(1)
+#define PECI_RETRY_INTERVAL_MAX		msecs_to_jiffies(128)
+
+static u8 peci_request_data_cc(struct peci_request *req)
+{
+	return req->rx.buf[0];
+}
+
+/**
+ * peci_request_status() - return -errno based on PECI completion code
+ * @req: the PECI request that contains response data with completion code
+ *
+ * It can't be used for Ping(), GetDIB() and GetTemp() - for those commands we
+ * don't expect completion code in the response.
+ *
+ * Return: -errno
+ */
+int peci_request_status(struct peci_request *req)
+{
+	u8 cc = peci_request_data_cc(req);
+
+	if (cc != PECI_CC_SUCCESS)
+		dev_dbg(&req->device->dev, "ret: %#02x\n", cc);
+
+	switch (cc) {
+	case PECI_CC_SUCCESS:
+		return 0;
+	case PECI_CC_NEED_RETRY:
+	case PECI_CC_OUT_OF_RESOURCE:
+	case PECI_CC_UNAVAIL_RESOURCE:
+		return -EAGAIN;
+	case PECI_CC_INVALID_REQ:
+		return -EINVAL;
+	case PECI_CC_MCA_ERROR:
+	case PECI_CC_CATASTROPHIC_MCA_ERROR:
+	case PECI_CC_FATAL_MCA_ERROR:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB_IERR:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB_MCA:
+		return -EIO;
+	}
+
+	WARN_ONCE(1, "Unknown PECI completion code: %#02x\n", cc);
+
+	return -EIO;
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_status, PECI);
+
+static int peci_request_xfer(struct peci_request *req)
+{
+	struct peci_device *device = req->device;
+	struct peci_controller *controller = to_peci_controller(device->dev.parent);
+	int ret;
+
+	mutex_lock(&controller->bus_lock);
+	ret = controller->ops->xfer(controller, device->addr, req);
+	mutex_unlock(&controller->bus_lock);
+
+	return ret;
+}
+
+static int peci_request_xfer_retry(struct peci_request *req)
+{
+	long wait_interval = PECI_RETRY_INTERVAL_MIN;
+	struct peci_device *device = req->device;
+	struct peci_controller *controller = to_peci_controller(device->dev.parent);
+	unsigned long start = jiffies;
+	int ret;
+
+	/* Don't try to use it for ping */
+	if (WARN_ON(!req->rx.buf))
+		return 0;
+
+	do {
+		ret = peci_request_xfer(req);
+		if (ret) {
+			dev_dbg(&controller->dev, "xfer error: %d\n", ret);
+			return ret;
+		}
+
+		if (peci_request_status(req) != -EAGAIN)
+			return 0;
+
+		/* Set the retry bit to indicate a retry attempt */
+		req->tx.buf[1] |= PECI_RETRY_BIT;
+
+		if (schedule_timeout_interruptible(wait_interval))
+			return -ERESTARTSYS;
+
+		wait_interval = min_t(long, wait_interval * 2, PECI_RETRY_INTERVAL_MAX);
+	} while (time_before(jiffies, start + PECI_RETRY_TIMEOUT));
+
+	dev_dbg(&controller->dev, "request timed out\n");
+
+	return -ETIMEDOUT;
+}
+
 /**
  * peci_request_alloc() - allocate &struct peci_requests
  * @device: PECI device to which request is going to be sent
@@ -48,3 +175,90 @@ void peci_request_free(struct peci_request *req)
 	kfree(req);
 }
 EXPORT_SYMBOL_NS_GPL(peci_request_free, PECI);
+
+struct peci_request *peci_get_dib(struct peci_device *device)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_GET_DIB_WR_LEN, PECI_GET_DIB_RD_LEN);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_GET_DIB_CMD;
+
+	ret = peci_request_xfer(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_get_dib, PECI);
+
+static struct peci_request *
+__pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDPKGCFG_WR_LEN, PECI_RDPKGCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_RDPKGCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = index;
+	put_unaligned_le16(param, &req->tx.buf[3]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+u8 peci_request_data_readb(struct peci_request *req)
+{
+	return req->rx.buf[1];
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readb, PECI);
+
+u16 peci_request_data_readw(struct peci_request *req)
+{
+	return get_unaligned_le16(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readw, PECI);
+
+u32 peci_request_data_readl(struct peci_request *req)
+{
+	return get_unaligned_le32(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readl, PECI);
+
+u64 peci_request_data_readq(struct peci_request *req)
+{
+	return get_unaligned_le64(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readq, PECI);
+
+u64 peci_request_data_dib(struct peci_request *req)
+{
+	return get_unaligned_le64(&req->rx.buf[0]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_dib, PECI);
+
+#define __read_pkg_config(x, type) \
+struct peci_request *peci_pkg_cfg_##x(struct peci_device *device, u8 index, u16 param) \
+{ \
+	return __pkg_cfg_read(device, index, param, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_pkg_cfg_##x, PECI)
+
+__read_pkg_config(readb, u8);
+__read_pkg_config(readw, u16);
+__read_pkg_config(readl, u32);
+__read_pkg_config(readq, u64);
diff --git a/include/linux/peci.h b/include/linux/peci.h
index 26e0a4e73b50..dcf1c53f4e40 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -14,6 +14,14 @@
  */
 #define PECI_REQUEST_MAX_BUF_SIZE 32
 
+#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
+#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
+#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
+#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
+#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
+#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
+#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
+
 struct peci_controller;
 struct peci_request;
 
@@ -59,6 +67,11 @@ static inline struct peci_controller *to_peci_controller(void *d)
  * struct peci_device - PECI device
  * @dev: device object to register PECI device to the device model
  * @controller: manages the bus segment hosting this PECI device
+ * @info: PECI device characteristics
+ * @info.family: device family
+ * @info.model: device model
+ * @info.peci_revision: PECI revision supported by the PECI device
+ * @info.socket_id: the socket ID represented by the PECI device
  * @addr: address used on the PECI bus connected to the parent controller
  *
  * A peci_device identifies a single device (i.e. CPU) connected to a PECI bus.
@@ -67,6 +80,12 @@ static inline struct peci_controller *to_peci_controller(void *d)
  */
 struct peci_device {
 	struct device dev;
+	struct {
+		u16 family;
+		u8 model;
+		u8 peci_revision;
+		u8 socket_id;
+	} info;
 	u8 addr;
 };
 
diff --git a/lib/Kconfig b/lib/Kconfig
index e538d4d773bd..7f7972d357c2 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -718,4 +718,4 @@ config ASN1_ENCODER
 
 config GENERIC_LIB_X86
 	bool
-	depends on X86
+	depends on X86 || PECI
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:30 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:30 +0200
Subject: [PATCH v2 11/15] peci: Add peci-cpu driver
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-12-iwona.winiarska@intel.com>

PECI is an interface that may be used by different types of devices.
Here we're adding a peci-cpu driver compatible with Intel processors.
The driver is responsible for handling auxiliary devices that can
subsequently be used by other drivers (e.g. hwmons).

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS              |   1 +
 drivers/peci/Kconfig     |  15 ++
 drivers/peci/Makefile    |   2 +
 drivers/peci/cpu.c       | 344 +++++++++++++++++++++++++++++++++++++++
 drivers/peci/device.c    |   1 +
 drivers/peci/internal.h  |  27 +++
 drivers/peci/request.c   | 213 ++++++++++++++++++++++++
 include/linux/peci-cpu.h |  38 +++++
 include/linux/peci.h     |   8 -
 9 files changed, 641 insertions(+), 8 deletions(-)
 create mode 100644 drivers/peci/cpu.c
 create mode 100644 include/linux/peci-cpu.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6e9d53ff68ab..3f5d48e1d143 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14519,6 +14519,7 @@ L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
 S:	Supported
 F:	Documentation/devicetree/bindings/peci/
 F:	drivers/peci/
+F:	include/linux/peci-cpu.h
 F:	include/linux/peci.h
 
 PENSANDO ETHERNET DRIVERS
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
index 1d0532e3a801..2ea01f43f547 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -17,6 +17,21 @@ menuconfig PECI
 
 if PECI
 
+config PECI_CPU
+	tristate "PECI CPU"
+	select AUXILIARY_BUS
+	help
+	  This option enables peci-cpu driver for Intel processors. It is
+	  responsible for creating auxiliary devices that can subsequently
+	  be used by other drivers in order to perform various
+	  functionalities such as e.g. temperature monitoring.
+
+	  Additional drivers must be enabled in order to use the functionality
+	  of the device.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-cpu.
+
 source "drivers/peci/controller/Kconfig"
 
 endif # PECI
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index 917f689e147a..7de18137e738 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -3,6 +3,8 @@
 # Core functionality
 peci-y := core.o request.o device.o sysfs.o
 obj-$(CONFIG_PECI) += peci.o
+peci-cpu-y := cpu.o
+obj-$(CONFIG_PECI_CPU) += peci-cpu.o
 
 # Hardware specific bus drivers
 obj-y += controller/
diff --git a/drivers/peci/cpu.c b/drivers/peci/cpu.c
new file mode 100644
index 000000000000..97b9043be1e2
--- /dev/null
+++ b/drivers/peci/cpu.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/slab.h>
+#include <linux/x86/intel-family.h>
+
+#include "internal.h"
+
+/**
+ * peci_temp_read() - read the maximum die temperature from PECI target device
+ * @device: PECI device to which request is going to be sent
+ * @temp_raw: where to store the read temperature
+ *
+ * It uses GetTemp PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_temp_read(struct peci_device *device, s16 *temp_raw)
+{
+	struct peci_request *req;
+
+	req = peci_get_temp(device);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	*temp_raw = peci_request_data_temp(req);
+
+	peci_request_free(req);
+
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(peci_temp_read, PECI_CPU);
+
+/**
+ * peci_pcs_read() - read PCS register
+ * @device: PECI device to which request is going to be sent
+ * @index: PCS index
+ * @param: PCS parameter
+ * @data: where to store the read data
+ *
+ * It uses RdPkgConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_pcs_read(struct peci_device *device, u8 index, u16 param, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_pkg_cfg_readl(device, index, param);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_pcs_read, PECI_CPU);
+
+/**
+ * peci_pci_local_read() - read 32-bit memory location using raw address
+ * @device: PECI device to which request is going to be sent
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @reg: register
+ * @data: where to store the read data
+ *
+ * It uses RdPCIConfigLocal PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_pci_local_read(struct peci_device *device, u8 bus, u8 dev, u8 func,
+			u16 reg, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_pci_cfg_local_readl(device, bus, dev, func, reg);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_pci_local_read, PECI_CPU);
+
+/**
+ * peci_ep_pci_local_read() - read 32-bit memory location using raw address
+ * @device: PECI device to which request is going to be sent
+ * @seg: PCI segment
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @reg: register
+ * @data: where to store the read data
+ *
+ * Like &peci_pci_local_read, but it uses RdEndpointConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_ep_pci_local_read(struct peci_device *device, u8 seg,
+			   u8 bus, u8 dev, u8 func, u16 reg, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_ep_pci_cfg_local_readl(device, seg, bus, dev, func, reg);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_ep_pci_local_read, PECI_CPU);
+
+/**
+ * peci_mmio_read() - read 32-bit memory location using 64-bit bar offset address
+ * @device: PECI device to which request is going to be sent
+ * @bar: PCI bar
+ * @seg: PCI segment
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @address: 64-bit MMIO address
+ * @data: where to store the read data
+ *
+ * It uses RdEndpointConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_mmio_read(struct peci_device *device, u8 bar, u8 seg,
+		   u8 bus, u8 dev, u8 func, u64 address, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_ep_mmio64_readl(device, bar, seg, bus, dev, func, address);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_mmio_read, PECI_CPU);
+
+static const char * const peci_adev_types[] = {
+	"cputemp",
+	"dimmtemp",
+};
+
+struct peci_cpu {
+	struct peci_device *device;
+	const struct peci_device_id *id;
+};
+
+static void adev_release(struct device *dev)
+{
+	struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+	auxiliary_device_uninit(adev);
+
+	kfree(adev->name);
+	kfree(adev);
+}
+
+static struct auxiliary_device *adev_alloc(struct peci_cpu *priv, int idx)
+{
+	struct peci_controller *controller = to_peci_controller(priv->device->dev.parent);
+	struct auxiliary_device *adev;
+	const char *name;
+	int ret;
+
+	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+	if (!adev)
+		return ERR_PTR(-ENOMEM);
+
+	name = kasprintf(GFP_KERNEL, "%s.%s", peci_adev_types[idx], (const char *)priv->id->data);
+	if (!name) {
+		ret = -ENOMEM;
+		goto free_adev;
+	}
+
+	adev->name = name;
+	adev->dev.parent = &priv->device->dev;
+	adev->dev.release = adev_release;
+	adev->id = (controller->id << 16) | (priv->device->addr);
+
+	ret = auxiliary_device_init(adev);
+	if (ret)
+		goto free_name;
+
+	return adev;
+
+free_name:
+	kfree(name);
+free_adev:
+	kfree(adev);
+	return ERR_PTR(ret);
+}
+
+static void unregister_adev(void *_adev)
+{
+	struct auxiliary_device *adev = _adev;
+
+	auxiliary_device_delete(adev);
+}
+
+static int devm_adev_add(struct device *dev, int idx)
+{
+	struct peci_cpu *priv = dev_get_drvdata(dev);
+	struct auxiliary_device *adev;
+	int ret;
+
+	adev = adev_alloc(priv, idx);
+	if (IS_ERR(adev))
+		return PTR_ERR(adev);
+
+	ret = auxiliary_device_add(adev);
+	if (ret) {
+		auxiliary_device_uninit(adev);
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(&priv->device->dev, unregister_adev, adev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void peci_cpu_add_adevices(struct peci_cpu *priv)
+{
+	struct device *dev = &priv->device->dev;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(peci_adev_types); i++) {
+		ret = devm_adev_add(dev, i);
+		if (ret) {
+			dev_warn(dev, "Failed to register PECI auxiliary: %s, ret = %d\n",
+				 peci_adev_types[i], ret);
+			continue;
+		}
+	}
+}
+
+static int
+peci_cpu_probe(struct peci_device *device, const struct peci_device_id *id)
+{
+	struct device *dev = &device->dev;
+	struct peci_cpu *priv;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, priv);
+	priv->device = device;
+	priv->id = id;
+
+	peci_cpu_add_adevices(priv);
+
+	return 0;
+}
+
+static const struct peci_device_id peci_cpu_device_ids[] = {
+	{ /* Haswell Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_HASWELL_X,
+		.data	= "hsx",
+	},
+	{ /* Broadwell Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_BROADWELL_X,
+		.data	= "bdx",
+	},
+	{ /* Broadwell Xeon D */
+		.family	= 6,
+		.model	= INTEL_FAM6_BROADWELL_D,
+		.data	= "bdxd",
+	},
+	{ /* Skylake Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_SKYLAKE_X,
+		.data	= "skx",
+	},
+	{ /* Icelake Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_ICELAKE_X,
+		.data	= "icx",
+	},
+	{ /* Icelake Xeon D */
+		.family	= 6,
+		.model	= INTEL_FAM6_ICELAKE_D,
+		.data	= "icxd",
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(peci, peci_cpu_device_ids);
+
+static struct peci_driver peci_cpu_driver = {
+	.probe		= peci_cpu_probe,
+	.id_table	= peci_cpu_device_ids,
+	.driver		= {
+		.name		= "peci-cpu",
+	},
+};
+module_peci_driver(peci_cpu_driver);
+
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI CPU driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI);
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index a78c02399574..9c377d32cec4 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -3,6 +3,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/peci.h>
+#include <linux/peci-cpu.h>
 #include <linux/slab.h>
 #include <linux/x86/cpu.h>
 
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index d661e1b65694..c6bbf18b66cb 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -21,6 +21,7 @@ void peci_request_free(struct peci_request *req);
 
 int peci_request_status(struct peci_request *req);
 u64 peci_request_data_dib(struct peci_request *req);
+s16 peci_request_data_temp(struct peci_request *req);
 
 u8 peci_request_data_readb(struct peci_request *req);
 u16 peci_request_data_readw(struct peci_request *req);
@@ -35,6 +36,32 @@ struct peci_request *peci_pkg_cfg_readw(struct peci_device *device, u8 index, u1
 struct peci_request *peci_pkg_cfg_readl(struct peci_device *device, u8 index, u16 param);
 struct peci_request *peci_pkg_cfg_readq(struct peci_device *device, u8 index, u16 param);
 
+struct peci_request *peci_pci_cfg_local_readb(struct peci_device *device,
+					      u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_pci_cfg_local_readw(struct peci_device *device,
+					      u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_pci_cfg_local_readl(struct peci_device *device,
+					      u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_ep_pci_cfg_local_readb(struct peci_device *device, u8 seg,
+						 u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_ep_pci_cfg_local_readw(struct peci_device *device, u8 seg,
+						 u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_ep_pci_cfg_local_readl(struct peci_device *device, u8 seg,
+						 u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_ep_pci_cfg_readb(struct peci_device *device, u8 seg,
+					   u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_ep_pci_cfg_readw(struct peci_device *device, u8 seg,
+					   u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_ep_pci_cfg_readl(struct peci_device *device, u8 seg,
+					   u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_ep_mmio32_readl(struct peci_device *device, u8 bar, u8 seg,
+					  u8 bus, u8 dev, u8 func, u64 offset);
+
+struct peci_request *peci_ep_mmio64_readl(struct peci_device *device, u8 bar, u8 seg,
+					  u8 bus, u8 dev, u8 func, u64 offset);
 /**
  * struct peci_device_id - PECI device data to match
  * @data: pointer to driver private data specific to device
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
index fe032d5a5e1b..eacd6d2513b1 100644
--- a/drivers/peci/request.c
+++ b/drivers/peci/request.c
@@ -3,6 +3,7 @@
 
 #include <linux/bug.h>
 #include <linux/export.h>
+#include <linux/pci.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -15,6 +16,10 @@
 #define  PECI_GET_DIB_WR_LEN		1
 #define  PECI_GET_DIB_RD_LEN		8
 
+#define PECI_GET_TEMP_CMD		0x01
+#define  PECI_GET_TEMP_WR_LEN		1
+#define  PECI_GET_TEMP_RD_LEN		2
+
 #define PECI_RDPKGCFG_CMD		0xa1
 #define  PECI_RDPKGCFG_WR_LEN		5
 #define  PECI_RDPKGCFG_RD_LEN_BASE	1
@@ -22,6 +27,45 @@
 #define  PECI_WRPKGCFG_WR_LEN_BASE	6
 #define  PECI_WRPKGCFG_RD_LEN		1
 
+#define PECI_RDIAMSR_CMD		0xb1
+#define  PECI_RDIAMSR_WR_LEN		5
+#define  PECI_RDIAMSR_RD_LEN		9
+#define PECI_WRIAMSR_CMD		0xb5
+#define PECI_RDIAMSREX_CMD		0xd1
+#define  PECI_RDIAMSREX_WR_LEN		6
+#define  PECI_RDIAMSREX_RD_LEN		9
+
+#define PECI_RDPCICFG_CMD		0x61
+#define  PECI_RDPCICFG_WR_LEN		6
+#define  PECI_RDPCICFG_RD_LEN		5
+#define  PECI_RDPCICFG_RD_LEN_MAX	24
+#define PECI_WRPCICFG_CMD		0x65
+
+#define PECI_RDPCICFGLOCAL_CMD			0xe1
+#define  PECI_RDPCICFGLOCAL_WR_LEN		5
+#define  PECI_RDPCICFGLOCAL_RD_LEN_BASE		1
+#define PECI_WRPCICFGLOCAL_CMD			0xe5
+#define  PECI_WRPCICFGLOCAL_WR_LEN_BASE		6
+#define  PECI_WRPCICFGLOCAL_RD_LEN		1
+
+#define PECI_ENDPTCFG_TYPE_LOCAL_PCI		0x03
+#define PECI_ENDPTCFG_TYPE_PCI			0x04
+#define PECI_ENDPTCFG_TYPE_MMIO			0x05
+#define PECI_ENDPTCFG_ADDR_TYPE_PCI		0x04
+#define PECI_ENDPTCFG_ADDR_TYPE_MMIO_D		0x05
+#define PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q		0x06
+#define PECI_RDENDPTCFG_CMD			0xc1
+#define  PECI_RDENDPTCFG_PCI_WR_LEN		12
+#define  PECI_RDENDPTCFG_MMIO_WR_LEN_BASE	10
+#define  PECI_RDENDPTCFG_MMIO_D_WR_LEN		14
+#define  PECI_RDENDPTCFG_MMIO_Q_WR_LEN		18
+#define  PECI_RDENDPTCFG_RD_LEN_BASE		1
+#define PECI_WRENDPTCFG_CMD			0xc5
+#define  PECI_WRENDPTCFG_PCI_WR_LEN_BASE	13
+#define  PECI_WRENDPTCFG_MMIO_D_WR_LEN_BASE	15
+#define  PECI_WRENDPTCFG_MMIO_Q_WR_LEN_BASE	19
+#define  PECI_WRENDPTCFG_RD_LEN			1
+
 /* Device Specific Completion Code (CC) Definition */
 #define PECI_CC_SUCCESS				0x40
 #define PECI_CC_NEED_RETRY			0x80
@@ -197,6 +241,27 @@ struct peci_request *peci_get_dib(struct peci_device *device)
 }
 EXPORT_SYMBOL_NS_GPL(peci_get_dib, PECI);
 
+struct peci_request *peci_get_temp(struct peci_device *device)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_GET_TEMP_WR_LEN, PECI_GET_TEMP_RD_LEN);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_GET_TEMP_CMD;
+
+	ret = peci_request_xfer(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_get_temp, PECI);
+
 static struct peci_request *
 __pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
 {
@@ -221,6 +286,108 @@ __pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
 	return req;
 }
 
+static u32 __get_pci_addr(u8 bus, u8 dev, u8 func, u16 reg)
+{
+	return reg | PCI_DEVID(bus, PCI_DEVFN(dev, func)) << 12;
+}
+
+static struct peci_request *
+__pci_cfg_local_read(struct peci_device *device, u8 bus, u8 dev, u8 func, u16 reg, u8 len)
+{
+	struct peci_request *req;
+	u32 pci_addr;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDPCICFGLOCAL_WR_LEN,
+				 PECI_RDPCICFGLOCAL_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	pci_addr = __get_pci_addr(bus, dev, func, reg);
+
+	req->tx.buf[0] = PECI_RDPCICFGLOCAL_CMD;
+	req->tx.buf[1] = 0;
+	put_unaligned_le24(pci_addr, &req->tx.buf[2]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+static struct peci_request *
+__ep_pci_cfg_read(struct peci_device *device, u8 msg_type, u8 seg,
+		  u8 bus, u8 dev, u8 func, u16 reg, u8 len)
+{
+	struct peci_request *req;
+	u32 pci_addr;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDENDPTCFG_PCI_WR_LEN,
+				 PECI_RDENDPTCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	pci_addr = __get_pci_addr(bus, dev, func, reg);
+
+	req->tx.buf[0] = PECI_RDENDPTCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = msg_type;
+	req->tx.buf[3] = 0;
+	req->tx.buf[4] = 0;
+	req->tx.buf[5] = 0;
+	req->tx.buf[6] = PECI_ENDPTCFG_ADDR_TYPE_PCI;
+	req->tx.buf[7] = seg; /* PCI Segment */
+	put_unaligned_le32(pci_addr, &req->tx.buf[8]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+static struct peci_request *
+__ep_mmio_read(struct peci_device *device, u8 bar, u8 addr_type, u8 seg,
+	       u8 bus, u8 dev, u8 func, u64 offset, u8 tx_len, u8 len)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, tx_len, PECI_RDENDPTCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_RDENDPTCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = PECI_ENDPTCFG_TYPE_MMIO;
+	req->tx.buf[3] = 0; /* Endpoint ID */
+	req->tx.buf[4] = 0; /* Reserved */
+	req->tx.buf[5] = bar;
+	req->tx.buf[6] = addr_type;
+	req->tx.buf[7] = seg; /* PCI Segment */
+	req->tx.buf[8] = PCI_DEVFN(dev, func);
+	req->tx.buf[9] = bus; /* PCI Bus */
+
+	if (addr_type == PECI_ENDPTCFG_ADDR_TYPE_MMIO_D)
+		put_unaligned_le32(offset, &req->tx.buf[10]);
+	else
+		put_unaligned_le64(offset, &req->tx.buf[10]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
 u8 peci_request_data_readb(struct peci_request *req)
 {
 	return req->rx.buf[1];
@@ -251,6 +418,12 @@ u64 peci_request_data_dib(struct peci_request *req)
 }
 EXPORT_SYMBOL_NS_GPL(peci_request_data_dib, PECI);
 
+s16 peci_request_data_temp(struct peci_request *req)
+{
+	return get_unaligned_le16(&req->rx.buf[0]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_temp, PECI);
+
 #define __read_pkg_config(x, type) \
 struct peci_request *peci_pkg_cfg_##x(struct peci_device *device, u8 index, u16 param) \
 { \
@@ -262,3 +435,43 @@ __read_pkg_config(readb, u8);
 __read_pkg_config(readw, u16);
 __read_pkg_config(readl, u32);
 __read_pkg_config(readq, u64);
+
+#define __read_pci_config_local(x, type) \
+struct peci_request * \
+peci_pci_cfg_local_##x(struct peci_device *device, u8 bus, u8 dev, u8 func, u16 reg) \
+{ \
+	return __pci_cfg_local_read(device, bus, dev, func, reg, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_pci_cfg_local_##x, PECI)
+
+__read_pci_config_local(readb, u8);
+__read_pci_config_local(readw, u16);
+__read_pci_config_local(readl, u32);
+
+#define __read_ep_pci_config(x, msg_type, type) \
+struct peci_request * \
+peci_ep_pci_cfg_##x(struct peci_device *device, u8 seg, u8 bus, u8 dev, u8 func, u16 reg) \
+{ \
+	return __ep_pci_cfg_read(device, msg_type, seg, bus, dev, func, reg, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_ep_pci_cfg_##x, PECI)
+
+__read_ep_pci_config(local_readb, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u8);
+__read_ep_pci_config(local_readw, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u16);
+__read_ep_pci_config(local_readl, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u32);
+__read_ep_pci_config(readb, PECI_ENDPTCFG_TYPE_PCI, u8);
+__read_ep_pci_config(readw, PECI_ENDPTCFG_TYPE_PCI, u16);
+__read_ep_pci_config(readl, PECI_ENDPTCFG_TYPE_PCI, u32);
+
+#define __read_ep_mmio(x, y, addr_type, type1, type2) \
+struct peci_request *peci_ep_mmio##y##_##x(struct peci_device *device, u8 bar, u8 seg, \
+					   u8 bus, u8 dev, u8 func, u64 offset) \
+{ \
+	return __ep_mmio_read(device, bar, addr_type, seg, bus, dev, func, \
+			      offset, PECI_RDENDPTCFG_MMIO_WR_LEN_BASE + sizeof(type1), \
+			      sizeof(type2)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_ep_mmio##y##_##x, PECI)
+
+__read_ep_mmio(readl, 32, PECI_ENDPTCFG_ADDR_TYPE_MMIO_D, u32, u32);
+__read_ep_mmio(readl, 64, PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q, u64, u32);
diff --git a/include/linux/peci-cpu.h b/include/linux/peci-cpu.h
new file mode 100644
index 000000000000..d1b307ec2429
--- /dev/null
+++ b/include/linux/peci-cpu.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2021 Intel Corporation */
+
+#ifndef __LINUX_PECI_CPU_H
+#define __LINUX_PECI_CPU_H
+
+#include <linux/types.h>
+
+#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
+#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
+#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
+#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
+#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
+#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
+#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
+#define PECI_PCS_MODULE_TEMP		9  /* Per Core DTS Temperature Read */
+#define PECI_PCS_THERMAL_MARGIN		10 /* DTS thermal margin */
+#define PECI_PCS_DDR_DIMM_TEMP		14 /* DDR DIMM Temperature */
+#define PECI_PCS_TEMP_TARGET		16 /* Temperature Target Read */
+#define PECI_PCS_TDP_UNITS		30 /* Units for power/energy registers */
+
+struct peci_device;
+
+int peci_temp_read(struct peci_device *device, s16 *temp_raw);
+
+int peci_pcs_read(struct peci_device *device, u8 index,
+		  u16 param, u32 *data);
+
+int peci_pci_local_read(struct peci_device *device, u8 bus, u8 dev,
+			u8 func, u16 reg, u32 *data);
+
+int peci_ep_pci_local_read(struct peci_device *device, u8 seg,
+			   u8 bus, u8 dev, u8 func, u16 reg, u32 *data);
+
+int peci_mmio_read(struct peci_device *device, u8 bar, u8 seg,
+		   u8 bus, u8 dev, u8 func, u64 address, u32 *data);
+
+#endif /* __LINUX_PECI_CPU_H */
diff --git a/include/linux/peci.h b/include/linux/peci.h
index dcf1c53f4e40..ce43705eaac4 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -14,14 +14,6 @@
  */
 #define PECI_REQUEST_MAX_BUF_SIZE 32
 
-#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
-#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
-#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
-#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
-#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
-#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
-#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
-
 struct peci_controller;
 struct peci_request;
 
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:31 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:31 +0200
Subject: [PATCH v2 12/15] hwmon: peci: Add cputemp driver
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-13-iwona.winiarska@intel.com>

Add peci-cputemp driver for Digital Thermal Sensor (DTS) thermal
readings of the processor package and processor cores that are
accessible via the PECI interface.

The main use case for the driver (and PECI interface) is out-of-band
management, where we're able to obtain the DTS readings from an external
entity connected with PECI, e.g. BMC on server platforms.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS                  |   7 +
 drivers/hwmon/Kconfig        |   2 +
 drivers/hwmon/Makefile       |   1 +
 drivers/hwmon/peci/Kconfig   |  18 ++
 drivers/hwmon/peci/Makefile  |   5 +
 drivers/hwmon/peci/common.h  |  58 ++++
 drivers/hwmon/peci/cputemp.c | 591 +++++++++++++++++++++++++++++++++++
 7 files changed, 682 insertions(+)
 create mode 100644 drivers/hwmon/peci/Kconfig
 create mode 100644 drivers/hwmon/peci/Makefile
 create mode 100644 drivers/hwmon/peci/common.h
 create mode 100644 drivers/hwmon/peci/cputemp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3f5d48e1d143..e36b5c0824e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14512,6 +14512,13 @@ L:	platform-driver-x86 at vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/peaq-wmi.c
 
+PECI HARDWARE MONITORING DRIVERS
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+R:	Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+L:	linux-hwmon at vger.kernel.org
+S:	Supported
+F:	drivers/hwmon/peci/
+
 PECI SUBSYSTEM
 M:	Iwona Winiarska <iwona.winiarska at intel.com>
 R:	Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e3675377bc5d..61c0e3404415 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1507,6 +1507,8 @@ config SENSORS_PCF8591
 	  These devices are hard to detect and rarely found on mainstream
 	  hardware. If unsure, say N.
 
+source "drivers/hwmon/peci/Kconfig"
+
 source "drivers/hwmon/pmbus/Kconfig"
 
 config SENSORS_PWM_FAN
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index d712c61c1f5e..f52331f212ed 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -202,6 +202,7 @@ obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
 obj-$(CONFIG_SENSORS_XGENE)	+= xgene-hwmon.o
 
 obj-$(CONFIG_SENSORS_OCC)	+= occ/
+obj-$(CONFIG_SENSORS_PECI)	+= peci/
 obj-$(CONFIG_PMBUS)		+= pmbus/
 
 ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG
diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
new file mode 100644
index 000000000000..e10eed68d70a
--- /dev/null
+++ b/drivers/hwmon/peci/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SENSORS_PECI_CPUTEMP
+	tristate "PECI CPU temperature monitoring client"
+	depends on PECI
+	select SENSORS_PECI
+	select PECI_CPU
+	help
+	  If you say yes here you get support for the generic Intel PECI
+	  cputemp driver which provides Digital Thermal Sensor (DTS) thermal
+	  readings of the CPU package and CPU cores that are accessible via
+	  the processor PECI interface.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-cputemp.
+
+config SENSORS_PECI
+	tristate
diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
new file mode 100644
index 000000000000..e8a0ada5ab1f
--- /dev/null
+++ b/drivers/hwmon/peci/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+peci-cputemp-y := cputemp.o
+
+obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
diff --git a/drivers/hwmon/peci/common.h b/drivers/hwmon/peci/common.h
new file mode 100644
index 000000000000..734506b0eca2
--- /dev/null
+++ b/drivers/hwmon/peci/common.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2021 Intel Corporation */
+
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+#ifndef __PECI_HWMON_COMMON_H
+#define __PECI_HWMON_COMMON_H
+
+#define PECI_HWMON_UPDATE_INTERVAL	HZ
+
+/**
+ * struct peci_sensor_state - PECI state information
+ * @valid: flag to indicate the sensor value is valid
+ * @last_updated: time of the last update in jiffies
+ * @lock: mutex to protect sensor access
+ */
+struct peci_sensor_state {
+	bool valid;
+	unsigned long last_updated;
+	struct mutex lock; /* protect sensor access */
+};
+
+/**
+ * struct peci_sensor_data - PECI sensor information
+ * @value: sensor value in milli units
+ * @state: sensor update state
+ */
+
+struct peci_sensor_data {
+	s32 value;
+	struct peci_sensor_state state;
+};
+
+/**
+ * peci_sensor_need_update() - check whether sensor update is needed or not
+ * @sensor: pointer to sensor data struct
+ *
+ * Return: true if update is needed, false if not.
+ */
+
+static inline bool peci_sensor_need_update(struct peci_sensor_state *state)
+{
+	return !state->valid ||
+	       time_after(jiffies, state->last_updated + PECI_HWMON_UPDATE_INTERVAL);
+}
+
+/**
+ * peci_sensor_mark_updated() - mark the sensor is updated
+ * @sensor: pointer to sensor data struct
+ */
+static inline void peci_sensor_mark_updated(struct peci_sensor_state *state)
+{
+	state->valid = true;
+	state->last_updated = jiffies;
+}
+
+#endif /* __PECI_HWMON_COMMON_H */
diff --git a/drivers/hwmon/peci/cputemp.c b/drivers/hwmon/peci/cputemp.c
new file mode 100644
index 000000000000..9c6858a9fb6d
--- /dev/null
+++ b/drivers/hwmon/peci/cputemp.c
@@ -0,0 +1,591 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/units.h>
+#include <linux/x86/intel-family.h>
+
+#include "common.h"
+
+#define CORE_NUMS_MAX		64
+
+#define BASE_CHANNEL_NUMS	5
+#define CPUTEMP_CHANNEL_NUMS	(BASE_CHANNEL_NUMS + CORE_NUMS_MAX)
+
+#define TEMP_TARGET_FAN_TEMP_MASK	GENMASK(15, 8)
+#define TEMP_TARGET_REF_TEMP_MASK	GENMASK(23, 16)
+#define TEMP_TARGET_TJ_OFFSET_MASK	GENMASK(29, 24)
+
+#define DTS_MARGIN_MASK		GENMASK(15, 0)
+#define PCS_MODULE_TEMP_MASK	GENMASK(15, 0)
+
+#define DTS_FIXED_POINT_FRACTION	64
+
+struct resolved_cores_reg {
+	u8 bus;
+	u8 dev;
+	u8 func;
+	u8 offset;
+};
+
+struct cpu_info {
+	struct resolved_cores_reg *reg;
+	u8 min_peci_revision;
+};
+
+struct peci_temp_target {
+	s32 tcontrol;
+	s32 tthrottle;
+	s32 tjmax;
+	struct peci_sensor_state state;
+};
+
+enum peci_temp_target_type {
+	tcontrol_type,
+	tthrottle_type,
+	tjmax_type,
+	crit_hyst_type,
+};
+
+struct peci_cputemp {
+	struct peci_device *peci_dev;
+	struct device *dev;
+	const char *name;
+	const struct cpu_info *gen_info;
+	struct {
+		struct peci_temp_target target;
+		struct peci_sensor_data die;
+		struct peci_sensor_data dts;
+		struct peci_sensor_data core[CORE_NUMS_MAX];
+	} temp;
+	const char **coretemp_label;
+	DECLARE_BITMAP(core_mask, CORE_NUMS_MAX);
+};
+
+enum cputemp_channels {
+	channel_die,
+	channel_dts,
+	channel_tcontrol,
+	channel_tthrottle,
+	channel_tjmax,
+	channel_core,
+};
+
+static const char * const cputemp_label[BASE_CHANNEL_NUMS] = {
+	"Die",
+	"DTS",
+	"Tcontrol",
+	"Tthrottle",
+	"Tjmax",
+};
+
+static int update_temp_target(struct peci_cputemp *priv)
+{
+	s32 tthrottle_offset, tcontrol_margin;
+	u32 pcs;
+	int ret;
+
+	if (!peci_sensor_need_update(&priv->temp.target.state))
+		return 0;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_TEMP_TARGET, 0, &pcs);
+	if (ret)
+		return ret;
+
+	priv->temp.target.tjmax =
+		FIELD_GET(TEMP_TARGET_REF_TEMP_MASK, pcs) * MILLIDEGREE_PER_DEGREE;
+
+	tcontrol_margin = FIELD_GET(TEMP_TARGET_FAN_TEMP_MASK, pcs);
+	tcontrol_margin = sign_extend32(tcontrol_margin, 7) * MILLIDEGREE_PER_DEGREE;
+	priv->temp.target.tcontrol = priv->temp.target.tjmax - tcontrol_margin;
+
+	tthrottle_offset = FIELD_GET(TEMP_TARGET_TJ_OFFSET_MASK, pcs) * MILLIDEGREE_PER_DEGREE;
+	priv->temp.target.tthrottle = priv->temp.target.tjmax - tthrottle_offset;
+
+	peci_sensor_mark_updated(&priv->temp.target.state);
+
+	return 0;
+}
+
+static int get_temp_target(struct peci_cputemp *priv, enum peci_temp_target_type type, long *val)
+{
+	int ret;
+
+	mutex_lock(&priv->temp.target.state.lock);
+
+	ret = update_temp_target(priv);
+	if (ret)
+		goto unlock;
+
+	switch (type) {
+	case tcontrol_type:
+		*val = priv->temp.target.tcontrol;
+		break;
+	case tthrottle_type:
+		*val = priv->temp.target.tthrottle;
+		break;
+	case tjmax_type:
+		*val = priv->temp.target.tjmax;
+		break;
+	case crit_hyst_type:
+		*val = priv->temp.target.tjmax - priv->temp.target.tcontrol;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+unlock:
+	mutex_unlock(&priv->temp.target.state.lock);
+
+	return ret;
+}
+
+/*
+ * Processors return a value of DTS reading in S10.6 fixed point format
+ * (16 bits: 10-bit signed magnitude, 6-bit fraction).
+ * Error codes:
+ *   0x8000: General sensor error
+ *   0x8001: Reserved
+ *   0x8002: Underflow on reading value
+ *   0x8003-0x81ff: Reserved
+ */
+static bool dts_valid(s32 val)
+{
+	return val < 0x8000 || val > 0x81ff;
+}
+
+static s32 dts_to_millidegree(s32 val)
+{
+	return sign_extend32(val, 15) * MILLIDEGREE_PER_DEGREE / DTS_FIXED_POINT_FRACTION;
+}
+
+static int get_die_temp(struct peci_cputemp *priv, long *val)
+{
+	long tjmax;
+	s16 temp;
+	int ret;
+
+	mutex_lock(&priv->temp.die.state.lock);
+	if (!peci_sensor_need_update(&priv->temp.die.state))
+		goto skip_update;
+
+	ret = peci_temp_read(priv->peci_dev, &temp);
+	if (ret)
+		goto err_unlock;
+
+	if (!dts_valid(temp)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tjmax_type, &tjmax);
+	if (ret)
+		goto err_unlock;
+
+	priv->temp.die.value = (s32)tjmax + dts_to_millidegree(temp);
+
+	peci_sensor_mark_updated(&priv->temp.die.state);
+
+skip_update:
+	*val = priv->temp.die.value;
+	mutex_unlock(&priv->temp.die.state.lock);
+
+	return 0;
+
+err_unlock:
+	mutex_unlock(&priv->temp.die.state.lock);
+	return ret;
+}
+
+static int get_dts(struct peci_cputemp *priv, long *val)
+{
+	s32 dts_margin;
+	long tcontrol;
+	u32 pcs;
+	int ret;
+
+	mutex_lock(&priv->temp.dts.state.lock);
+	if (!peci_sensor_need_update(&priv->temp.dts.state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_THERMAL_MARGIN, 0, &pcs);
+	if (ret)
+		goto err_unlock;
+
+	dts_margin = FIELD_GET(DTS_MARGIN_MASK, pcs);
+	if (!dts_valid(dts_margin)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tcontrol_type, &tcontrol);
+	if (ret)
+		goto err_unlock;
+
+	/* Note that the tcontrol should be available before calling it */
+	priv->temp.dts.value = (s32)tcontrol - dts_to_millidegree(dts_margin);
+
+	peci_sensor_mark_updated(&priv->temp.dts.state);
+
+skip_update:
+	*val = priv->temp.dts.value;
+	mutex_unlock(&priv->temp.dts.state.lock);
+
+	return 0;
+
+err_unlock:
+	mutex_unlock(&priv->temp.dts.state.lock);
+	return ret;
+}
+
+static int get_core_temp(struct peci_cputemp *priv, int core_index, long *val)
+{
+	s32 core_dts_margin;
+	long tjmax;
+	u32 pcs;
+	int ret;
+
+	mutex_lock(&priv->temp.core[core_index].state.lock);
+	if (!peci_sensor_need_update(&priv->temp.core[core_index].state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_MODULE_TEMP, core_index, &pcs);
+	if (ret)
+		goto err_unlock;
+
+	core_dts_margin = FIELD_GET(PCS_MODULE_TEMP_MASK, pcs);
+	if (!dts_valid(core_dts_margin)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tjmax_type, &tjmax);
+	if (ret)
+		goto err_unlock;
+
+	/* Note that the tjmax should be available before calling it */
+	priv->temp.core[core_index].value = (s32)tjmax + dts_to_millidegree(core_dts_margin);
+
+	peci_sensor_mark_updated(&priv->temp.core[core_index].state);
+
+skip_update:
+	*val = priv->temp.core[core_index].value;
+	mutex_unlock(&priv->temp.core[core_index].state.lock);
+
+	return 0;
+
+err_unlock:
+	mutex_unlock(&priv->temp.core[core_index].state.lock);
+	return ret;
+}
+
+static int cputemp_read_string(struct device *dev, enum hwmon_sensor_types type,
+			       u32 attr, int channel, const char **str)
+{
+	struct peci_cputemp *priv = dev_get_drvdata(dev);
+
+	if (attr != hwmon_temp_label)
+		return -EOPNOTSUPP;
+
+	*str = channel < channel_core ?
+		cputemp_label[channel] : priv->coretemp_label[channel - channel_core];
+
+	return 0;
+}
+
+static int cputemp_read(struct device *dev, enum hwmon_sensor_types type,
+			u32 attr, int channel, long *val)
+{
+	struct peci_cputemp *priv = dev_get_drvdata(dev);
+
+	switch (attr) {
+	case hwmon_temp_input:
+		switch (channel) {
+		case channel_die:
+			return get_die_temp(priv, val);
+		case channel_dts:
+			return get_dts(priv, val);
+		case channel_tcontrol:
+			return get_temp_target(priv, tcontrol_type, val);
+		case channel_tthrottle:
+			return get_temp_target(priv, tthrottle_type, val);
+		case channel_tjmax:
+			return get_temp_target(priv, tjmax_type, val);
+		default:
+			return get_core_temp(priv, channel - channel_core, val);
+		}
+		break;
+	case hwmon_temp_max:
+		return get_temp_target(priv, tcontrol_type, val);
+	case hwmon_temp_crit:
+		return get_temp_target(priv, tjmax_type, val);
+	case hwmon_temp_crit_hyst:
+		return get_temp_target(priv, crit_hyst_type, val);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static umode_t cputemp_is_visible(const void *data, enum hwmon_sensor_types type,
+				  u32 attr, int channel)
+{
+	const struct peci_cputemp *priv = data;
+
+	if (channel > CPUTEMP_CHANNEL_NUMS)
+		return 0;
+
+	if (channel < channel_core)
+		return 0444;
+
+	if (test_bit(channel - channel_core, priv->core_mask))
+		return 0444;
+
+	return 0;
+}
+
+static int init_core_mask(struct peci_cputemp *priv)
+{
+	struct peci_device *peci_dev = priv->peci_dev;
+	struct resolved_cores_reg *reg = priv->gen_info->reg;
+	u64 core_mask;
+	u32 data;
+	int ret;
+
+	/* Get the RESOLVED_CORES register value */
+	switch (peci_dev->info.model) {
+	case INTEL_FAM6_ICELAKE_X:
+	case INTEL_FAM6_ICELAKE_D:
+		ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg->dev,
+					     reg->func, reg->offset + 4, &data);
+		if (ret)
+			return ret;
+
+		core_mask = (u64)data << 32;
+
+		ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg->dev,
+					     reg->func, reg->offset, &data);
+		if (ret)
+			return ret;
+
+		core_mask |= data;
+
+		break;
+	default:
+		ret = peci_pci_local_read(peci_dev, reg->bus, reg->dev,
+					  reg->func, reg->offset, &data);
+		if (ret)
+			return ret;
+
+		core_mask = data;
+
+		break;
+	}
+
+	if (!core_mask)
+		return -EIO;
+
+	bitmap_from_u64(priv->core_mask, core_mask);
+
+	return 0;
+}
+
+static int create_temp_label(struct peci_cputemp *priv)
+{
+	unsigned long core_max = find_last_bit(priv->core_mask, CORE_NUMS_MAX);
+	int i;
+
+	priv->coretemp_label = devm_kzalloc(priv->dev, core_max * sizeof(char *), GFP_KERNEL);
+	if (!priv->coretemp_label)
+		return -ENOMEM;
+
+	for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX) {
+		priv->coretemp_label[i] = devm_kasprintf(priv->dev, GFP_KERNEL, "Core %d", i);
+		if (!priv->coretemp_label[i])
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void check_resolved_cores(struct peci_cputemp *priv)
+{
+	/*
+	 * Failure to resolve cores is non-critical, we're still able to
+	 * provide other sensor data.
+	 */
+
+	if (init_core_mask(priv))
+		return;
+
+	if (create_temp_label(priv))
+		bitmap_zero(priv->core_mask, CORE_NUMS_MAX);
+}
+
+static void sensor_init(struct peci_cputemp *priv)
+{
+	int i;
+
+	mutex_init(&priv->temp.target.state.lock);
+	mutex_init(&priv->temp.die.state.lock);
+	mutex_init(&priv->temp.dts.state.lock);
+
+	for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX)
+		mutex_init(&priv->temp.core[i].state.lock);
+}
+
+static const struct hwmon_ops peci_cputemp_ops = {
+	.is_visible = cputemp_is_visible,
+	.read_string = cputemp_read_string,
+	.read = cputemp_read,
+};
+
+static const u32 peci_cputemp_temp_channel_config[] = {
+	/* Die temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST,
+	/* DTS margin */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST,
+	/* Tcontrol temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_CRIT,
+	/* Tthrottle temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT,
+	/* Tjmax temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT,
+	/* Core temperature - for all core channels */
+	[channel_core ... CPUTEMP_CHANNEL_NUMS - 1] = HWMON_T_LABEL | HWMON_T_INPUT,
+	0
+};
+
+static const struct hwmon_channel_info peci_cputemp_temp_channel = {
+	.type = hwmon_temp,
+	.config = peci_cputemp_temp_channel_config,
+};
+
+static const struct hwmon_channel_info *peci_cputemp_info[] = {
+	&peci_cputemp_temp_channel,
+	NULL
+};
+
+static const struct hwmon_chip_info peci_cputemp_chip_info = {
+	.ops = &peci_cputemp_ops,
+	.info = peci_cputemp_info,
+};
+
+static int peci_cputemp_probe(struct auxiliary_device *adev,
+			      const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct peci_device *peci_dev = to_peci_device(dev->parent);
+	struct peci_cputemp *priv;
+	struct device *hwmon_dev;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_cputemp.cpu%d",
+				    peci_dev->info.socket_id);
+	if (!priv->name)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	priv->peci_dev = peci_dev;
+	priv->gen_info = (const struct cpu_info *)id->driver_data;
+
+	/*
+	 * This is just a sanity check. Since we're using commands that are
+	 * guaranteed to be supported on a given platform, we should never see
+	 * revision lower than expected.
+	 */
+	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
+		dev_warn(priv->dev,
+			 "Unexpected PECI revision %#x, some features may be unavailable\n",
+			 peci_dev->info.peci_revision);
+
+	check_resolved_cores(priv);
+
+	sensor_init(priv);
+
+	hwmon_dev = devm_hwmon_device_register_with_info(priv->dev, priv->name,
+							 priv, &peci_cputemp_chip_info, NULL);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+/*
+ * RESOLVED_CORES PCI configuration register may have different location on
+ * different platforms.
+ */
+static struct resolved_cores_reg resolved_cores_reg_hsx = {
+	.bus = 1,
+	.dev = 30,
+	.func = 3,
+	.offset = 0xb4,
+};
+
+static struct resolved_cores_reg resolved_cores_reg_icx = {
+	.bus = 14,
+	.dev = 30,
+	.func = 3,
+	.offset = 0xd0,
+};
+
+static const struct cpu_info cpu_hsx = {
+	.reg		= &resolved_cores_reg_hsx,
+	.min_peci_revision = 0x33,
+};
+
+static const struct cpu_info cpu_icx = {
+	.reg		= &resolved_cores_reg_icx,
+	.min_peci_revision = 0x40,
+};
+
+static const struct auxiliary_device_id peci_cputemp_ids[] = {
+	{
+		.name = "peci_cpu.cputemp.hsx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.bdx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.bdxd",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.skx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.icx",
+		.driver_data = (kernel_ulong_t)&cpu_icx,
+	},
+	{
+		.name = "peci_cpu.cputemp.icxd",
+		.driver_data = (kernel_ulong_t)&cpu_icx,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(auxiliary, peci_cputemp_ids);
+
+static struct auxiliary_driver peci_cputemp_driver = {
+	.probe		= peci_cputemp_probe,
+	.id_table	= peci_cputemp_ids,
+};
+
+module_auxiliary_driver(peci_cputemp_driver);
+
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI cputemp driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI_CPU);
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:32 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:32 +0200
Subject: [PATCH v2 13/15] hwmon: peci: Add dimmtemp driver
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-14-iwona.winiarska@intel.com>

Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that
are accessible via the processor PECI interface.

The main use case for the driver (and PECI interface) is out-of-band
management, where we're able to obtain thermal readings from an external
entity connected with PECI, e.g. BMC on server platforms.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
Note that the timeout was completely removed - we're going to probe
for detected DIMMs every 5 seconds until we reach "stable" state of
either getting correct DIMM data or getting all -EINVAL (which
suggest that the CPU doesn't have any DIMMs).

 drivers/hwmon/peci/Kconfig    |  13 +
 drivers/hwmon/peci/Makefile   |   2 +
 drivers/hwmon/peci/dimmtemp.c | 614 ++++++++++++++++++++++++++++++++++
 3 files changed, 629 insertions(+)
 create mode 100644 drivers/hwmon/peci/dimmtemp.c

diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
index e10eed68d70a..9d32a57badfe 100644
--- a/drivers/hwmon/peci/Kconfig
+++ b/drivers/hwmon/peci/Kconfig
@@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP
 	  This driver can also be built as a module. If so, the module
 	  will be called peci-cputemp.
 
+config SENSORS_PECI_DIMMTEMP
+	tristate "PECI DIMM temperature monitoring client"
+	depends on PECI
+	select SENSORS_PECI
+	select PECI_CPU
+	help
+	  If you say yes here you get support for the generic Intel PECI hwmon
+	  driver which provides Temperature Sensor on DIMM readings that are
+	  accessible via the processor PECI interface.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-dimmtemp.
+
 config SENSORS_PECI
 	tristate
diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
index e8a0ada5ab1f..191cfa0227f3 100644
--- a/drivers/hwmon/peci/Makefile
+++ b/drivers/hwmon/peci/Makefile
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 peci-cputemp-y := cputemp.o
+peci-dimmtemp-y := dimmtemp.o
 
 obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
+obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)	+= peci-dimmtemp.o
diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c
new file mode 100644
index 000000000000..6264c29bb6c0
--- /dev/null
+++ b/drivers/hwmon/peci/dimmtemp.c
@@ -0,0 +1,614 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/units.h>
+#include <linux/workqueue.h>
+#include <linux/x86/intel-family.h>
+
+#include "common.h"
+
+#define DIMM_MASK_CHECK_DELAY_JIFFIES	msecs_to_jiffies(5000)
+
+/* Max number of channel ranks and DIMM index per channel */
+#define CHAN_RANK_MAX_ON_HSX	8
+#define DIMM_IDX_MAX_ON_HSX	3
+#define CHAN_RANK_MAX_ON_BDX	4
+#define DIMM_IDX_MAX_ON_BDX	3
+#define CHAN_RANK_MAX_ON_BDXD	2
+#define DIMM_IDX_MAX_ON_BDXD	2
+#define CHAN_RANK_MAX_ON_SKX	6
+#define DIMM_IDX_MAX_ON_SKX	2
+#define CHAN_RANK_MAX_ON_ICX	8
+#define DIMM_IDX_MAX_ON_ICX	2
+#define CHAN_RANK_MAX_ON_ICXD	4
+#define DIMM_IDX_MAX_ON_ICXD	2
+
+#define CHAN_RANK_MAX		CHAN_RANK_MAX_ON_HSX
+#define DIMM_IDX_MAX		DIMM_IDX_MAX_ON_HSX
+#define DIMM_NUMS_MAX		(CHAN_RANK_MAX * DIMM_IDX_MAX)
+
+#define CPU_SEG_MASK		GENMASK(23, 16)
+#define GET_CPU_SEG(x)		(((x) & CPU_SEG_MASK) >> 16)
+#define CPU_BUS_MASK		GENMASK(7, 0)
+#define GET_CPU_BUS(x)		((x) & CPU_BUS_MASK)
+
+#define DIMM_TEMP_MAX		GENMASK(15, 8)
+#define DIMM_TEMP_CRIT		GENMASK(23, 16)
+#define GET_TEMP_MAX(x)		(((x) & DIMM_TEMP_MAX) >> 8)
+#define GET_TEMP_CRIT(x)	(((x) & DIMM_TEMP_CRIT) >> 16)
+
+struct peci_dimmtemp;
+
+struct dimm_info {
+	int chan_rank_max;
+	int dimm_idx_max;
+	u8 min_peci_revision;
+	int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order,
+			       int chan_rank, u32 *data);
+};
+
+struct peci_dimm_thresholds {
+	long temp_max;
+	long temp_crit;
+	struct peci_sensor_state state;
+};
+
+enum peci_dimm_threshold_type {
+	temp_max_type,
+	temp_crit_type,
+};
+
+struct peci_dimmtemp {
+	struct peci_device *peci_dev;
+	struct device *dev;
+	const char *name;
+	const struct dimm_info *gen_info;
+	struct delayed_work detect_work;
+	struct {
+		struct peci_sensor_data temp;
+		struct peci_dimm_thresholds thresholds;
+	} dimm[DIMM_NUMS_MAX];
+	char **dimmtemp_label;
+	DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX);
+};
+
+static u8 __dimm_temp(u32 reg, int dimm_order)
+{
+	return (reg >> (dimm_order * 8)) & 0xff;
+}
+
+static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long *val)
+{
+	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
+	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
+	u32 data;
+	int ret;
+
+	mutex_lock(&priv->dimm[dimm_no].temp.state.lock);
+	if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &data);
+	if (ret) {
+		mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
+		return ret;
+	}
+
+	priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) * MILLIDEGREE_PER_DEGREE;
+
+	peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state);
+
+skip_update:
+	*val = priv->dimm[dimm_no].temp.value;
+	mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
+	return 0;
+}
+
+static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
+{
+	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
+	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
+	u32 data;
+	int ret;
+
+	if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state))
+		return 0;
+
+	ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank, &data);
+	if (ret == -ENODATA) /* Use default or previous value */
+		return 0;
+	if (ret)
+		return ret;
+
+	priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) * MILLIDEGREE_PER_DEGREE;
+	priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) * MILLIDEGREE_PER_DEGREE;
+
+	peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state);
+
+	return 0;
+}
+
+static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum peci_dimm_threshold_type type,
+			       int dimm_no, long *val)
+{
+	int ret;
+
+	mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock);
+	ret = update_thresholds(priv, dimm_no);
+	if (ret)
+		goto unlock;
+
+	switch (type) {
+	case temp_max_type:
+		*val = priv->dimm[dimm_no].thresholds.temp_max;
+		break;
+	case temp_crit_type:
+		*val = priv->dimm[dimm_no].thresholds.temp_crit;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+unlock:
+	mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock);
+
+	return ret;
+}
+
+static int dimmtemp_read_string(struct device *dev,
+				enum hwmon_sensor_types type,
+				u32 attr, int channel, const char **str)
+{
+	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
+
+	if (attr != hwmon_temp_label)
+		return -EOPNOTSUPP;
+
+	*str = (const char *)priv->dimmtemp_label[channel];
+
+	return 0;
+}
+
+static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type,
+			 u32 attr, int channel, long *val)
+{
+	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
+
+	switch (attr) {
+	case hwmon_temp_input:
+		return get_dimm_temp(priv, channel, val);
+	case hwmon_temp_max:
+		return get_dimm_thresholds(priv, temp_max_type, channel, val);
+	case hwmon_temp_crit:
+		return get_dimm_thresholds(priv, temp_crit_type, channel, val);
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static umode_t dimmtemp_is_visible(const void *data, enum hwmon_sensor_types type,
+				   u32 attr, int channel)
+{
+	const struct peci_dimmtemp *priv = data;
+
+	if (test_bit(channel, priv->dimm_mask))
+		return 0444;
+
+	return 0;
+}
+
+static const struct hwmon_ops peci_dimmtemp_ops = {
+	.is_visible = dimmtemp_is_visible,
+	.read_string = dimmtemp_read_string,
+	.read = dimmtemp_read,
+};
+
+static int check_populated_dimms(struct peci_dimmtemp *priv)
+{
+	int chan_rank_max = priv->gen_info->chan_rank_max;
+	int dimm_idx_max = priv->gen_info->dimm_idx_max;
+	u32 chan_rank_empty = 0;
+	u64 dimm_mask = 0;
+	int chan_rank, dimm_idx, ret;
+	u32 pcs;
+
+	BUILD_BUG_ON(CHAN_RANK_MAX > 32);
+	BUILD_BUG_ON(DIMM_NUMS_MAX > 64);
+	if (chan_rank_max * dimm_idx_max > DIMM_NUMS_MAX) {
+		WARN_ONCE(1, "Unsupported number of DIMMs");
+		return -EINVAL;
+	}
+
+	for (chan_rank = 0; chan_rank < chan_rank_max; chan_rank++) {
+		ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &pcs);
+		if (ret) {
+			/*
+			 * Overall, we expect either success or -EINVAL in
+			 * order to determine whether DIMM is populated or not.
+			 * For anything else - we fall back to defering the
+			 * detection to be performed at a later point in time.
+			 */
+			if (ret == -EINVAL) {
+				chan_rank_empty |= BIT(chan_rank);
+				continue;
+			}
+
+			return -EAGAIN;
+		}
+
+		for (dimm_idx = 0; dimm_idx < dimm_idx_max; dimm_idx++)
+			if (__dimm_temp(pcs, dimm_idx))
+				dimm_mask |= BIT(chan_rank * dimm_idx_max + dimm_idx);
+	}
+
+	/* If we got all -EINVALs, it means that the CPU doesn't have any DIMMs. */
+	if (chan_rank_empty == GENMASK(chan_rank_max - 1, 0))
+		return -ENODEV;
+
+	/*
+	 * It's possible that memory training is not done yet. In this case we
+	 * defer the detection to be performed at a later point in time.
+	 */
+	if (!dimm_mask)
+		return -EAGAIN;
+
+	dev_dbg(priv->dev, "Scanned populated DIMMs: %#llx\n", dimm_mask);
+
+	bitmap_from_u64(priv->dimm_mask, dimm_mask);
+
+	return 0;
+}
+
+static int create_dimm_temp_label(struct peci_dimmtemp *priv, int chan)
+{
+	int rank = chan / priv->gen_info->dimm_idx_max;
+	int idx = chan % priv->gen_info->dimm_idx_max;
+
+	priv->dimmtemp_label[chan] = devm_kasprintf(priv->dev, GFP_KERNEL,
+						    "DIMM %c%d", 'A' + rank,
+						    idx + 1);
+	if (!priv->dimmtemp_label[chan])
+		return -ENOMEM;
+
+	return 0;
+}
+
+static const u32 peci_dimmtemp_temp_channel_config[] = {
+	[0 ... DIMM_NUMS_MAX - 1] = HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT,
+	0
+};
+
+static const struct hwmon_channel_info peci_dimmtemp_temp_channel = {
+	.type = hwmon_temp,
+	.config = peci_dimmtemp_temp_channel_config,
+};
+
+static const struct hwmon_channel_info *peci_dimmtemp_temp_info[] = {
+	&peci_dimmtemp_temp_channel,
+	NULL
+};
+
+static const struct hwmon_chip_info peci_dimmtemp_chip_info = {
+	.ops = &peci_dimmtemp_ops,
+	.info = peci_dimmtemp_temp_info,
+};
+
+static int create_dimm_temp_info(struct peci_dimmtemp *priv)
+{
+	int ret, i, channels;
+	struct device *dev;
+
+	/*
+	 * We expect to either find populated DIMMs and carry on with creating
+	 * sensors, or find out that there are no DIMMs populated.
+	 * All other states mean that the platform never reached the state that
+	 * allows to check DIMM state - causing us to retry later on.
+	 */
+	ret = check_populated_dimms(priv);
+	if (ret == -ENODEV) {
+		dev_dbg(priv->dev, "No DIMMs found\n");
+		return 0;
+	} else if (ret) {
+		schedule_delayed_work(&priv->detect_work, DIMM_MASK_CHECK_DELAY_JIFFIES);
+		dev_dbg(priv->dev, "Deferred populating DIMM temp info\n");
+		return ret;
+	}
+
+	channels = priv->gen_info->chan_rank_max * priv->gen_info->dimm_idx_max;
+
+	priv->dimmtemp_label = devm_kzalloc(priv->dev, channels * sizeof(char *), GFP_KERNEL);
+	if (!priv->dimmtemp_label)
+		return -ENOMEM;
+
+	for_each_set_bit(i, priv->dimm_mask, DIMM_NUMS_MAX) {
+		ret = create_dimm_temp_label(priv, i);
+		if (ret)
+			return ret;
+		mutex_init(&priv->dimm[i].thresholds.state.lock);
+		mutex_init(&priv->dimm[i].temp.state.lock);
+	}
+
+	dev = devm_hwmon_device_register_with_info(priv->dev, priv->name, priv,
+						   &peci_dimmtemp_chip_info, NULL);
+	if (IS_ERR(dev)) {
+		dev_err(priv->dev, "Failed to register hwmon device\n");
+		return PTR_ERR(dev);
+	}
+
+	dev_dbg(priv->dev, "%s: sensor '%s'\n", dev_name(dev), priv->name);
+
+	return 0;
+}
+
+static void create_dimm_temp_info_delayed(struct work_struct *work)
+{
+	struct peci_dimmtemp *priv = container_of(to_delayed_work(work),
+						  struct peci_dimmtemp,
+						  detect_work);
+	int ret;
+
+	ret = create_dimm_temp_info(priv);
+	if (ret && ret != -EAGAIN)
+		dev_err(priv->dev, "Failed to populate DIMM temp info\n");
+}
+
+static void remove_delayed_work(void *_priv)
+{
+	struct peci_dimmtemp *priv = _priv;
+
+	cancel_delayed_work_sync(&priv->detect_work);
+}
+
+static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct peci_device *peci_dev = to_peci_device(dev->parent);
+	struct peci_dimmtemp *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_dimmtemp.cpu%d",
+				    peci_dev->info.socket_id);
+	if (!priv->name)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	priv->peci_dev = peci_dev;
+	priv->gen_info = (const struct dimm_info *)id->driver_data;
+
+	/*
+	 * This is just a sanity check. Since we're using commands that are
+	 * guaranteed to be supported on a given platform, we should never see
+	 * revision lower than expected.
+	 */
+	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
+		dev_warn(priv->dev,
+			 "Unexpected PECI revision %#x, some features may be unavailable\n",
+			 peci_dev->info.peci_revision);
+
+	INIT_DELAYED_WORK(&priv->detect_work, create_dimm_temp_info_delayed);
+
+	ret = devm_add_action_or_reset(priv->dev, remove_delayed_work, priv);
+	if (ret)
+		return ret;
+
+	ret = create_dimm_temp_info(priv);
+	if (ret && ret != -EAGAIN) {
+		dev_err(dev, "Failed to populate DIMM temp info\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+read_thresholds_hsx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 20, Function 0: IMC 0 channel 0 -> rank 0
+	 * Device 20, Function 1: IMC 0 channel 1 -> rank 1
+	 * Device 21, Function 0: IMC 0 channel 2 -> rank 2
+	 * Device 21, Function 1: IMC 0 channel 3 -> rank 3
+	 * Device 23, Function 0: IMC 1 channel 0 -> rank 4
+	 * Device 23, Function 1: IMC 1 channel 1 -> rank 5
+	 * Device 24, Function 0: IMC 1 channel 2 -> rank 6
+	 * Device 24, Function 1: IMC 1 channel 3 -> rank 7
+	 */
+	dev = 20 + chan_rank / 2 + chan_rank / 4;
+	func = chan_rank % 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 1, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_bdxd(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
+	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
+	 * Device 12, Function 2: IMC 1 channel 0 -> rank 2
+	 * Device 12, Function 6: IMC 1 channel 1 -> rank 3
+	 */
+	dev = 10 + chan_rank / 2 * 2;
+	func = (chan_rank % 2) ? 6 : 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_skx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
+	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
+	 * Device 11, Function 2: IMC 0 channel 2 -> rank 2
+	 * Device 12, Function 2: IMC 1 channel 0 -> rank 3
+	 * Device 12, Function 6: IMC 1 channel 1 -> rank 4
+	 * Device 13, Function 2: IMC 1 channel 2 -> rank 5
+	 */
+	dev = 10 + chan_rank / 3 * 2 + (chan_rank % 3 == 2 ? 1 : 0);
+	func = chan_rank % 3 == 1 ? 6 : 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_icx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u32 reg_val;
+	u64 offset;
+	int ret;
+	u8 dev;
+
+	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd4, &reg_val);
+	if (ret || !(reg_val & BIT(31)))
+		return -ENODATA; /* Use default or previous value */
+
+	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd0, &reg_val);
+	if (ret)
+		return -ENODATA; /* Use default or previous value */
+
+	/*
+	 * Device 26, Offset 224e0: IMC 0 channel 0 -> rank 0
+	 * Device 26, Offset 264e0: IMC 0 channel 1 -> rank 1
+	 * Device 27, Offset 224e0: IMC 1 channel 0 -> rank 2
+	 * Device 27, Offset 264e0: IMC 1 channel 1 -> rank 3
+	 * Device 28, Offset 224e0: IMC 2 channel 0 -> rank 4
+	 * Device 28, Offset 264e0: IMC 2 channel 1 -> rank 5
+	 * Device 29, Offset 224e0: IMC 3 channel 0 -> rank 6
+	 * Device 29, Offset 264e0: IMC 3 channel 1 -> rank 7
+	 */
+	dev = 26 + chan_rank / 2;
+	offset = 0x224e0 + dimm_order * 4 + (chan_rank % 2) * 0x4000;
+
+	ret = peci_mmio_read(priv->peci_dev, 0, GET_CPU_SEG(reg_val), GET_CPU_BUS(reg_val),
+			     dev, 0, offset, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct dimm_info dimm_hsx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_HSX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_HSX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_hsx,
+};
+
+static const struct dimm_info dimm_bdx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_BDX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_hsx,
+};
+
+static const struct dimm_info dimm_bdxd = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_BDXD,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDXD,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_bdxd,
+};
+
+static const struct dimm_info dimm_skx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_SKX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_SKX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_skx,
+};
+
+static const struct dimm_info dimm_icx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_ICX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICX,
+	.min_peci_revision = 0x40,
+	.read_thresholds = &read_thresholds_icx,
+};
+
+static const struct dimm_info dimm_icxd = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_ICXD,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICXD,
+	.min_peci_revision = 0x40,
+	.read_thresholds = &read_thresholds_icx,
+};
+
+static const struct auxiliary_device_id peci_dimmtemp_ids[] = {
+	{
+		.name = "peci_cpu.dimmtemp.hsx",
+		.driver_data = (kernel_ulong_t)&dimm_hsx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.bdx",
+		.driver_data = (kernel_ulong_t)&dimm_bdx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.bdxd",
+		.driver_data = (kernel_ulong_t)&dimm_bdxd,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.skx",
+		.driver_data = (kernel_ulong_t)&dimm_skx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.icx",
+		.driver_data = (kernel_ulong_t)&dimm_icx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.icxd",
+		.driver_data = (kernel_ulong_t)&dimm_icxd,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(auxiliary, peci_dimmtemp_ids);
+
+static struct auxiliary_driver peci_dimmtemp_driver = {
+	.probe		= peci_dimmtemp_probe,
+	.id_table	= peci_dimmtemp_ids,
+};
+
+module_auxiliary_driver(peci_dimmtemp_driver);
+
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI dimmtemp driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI_CPU);
-- 
2.31.1



From iwona.winiarska at intel.com  Tue Aug  3 04:31:33 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:33 +0200
Subject: [PATCH v2 14/15] docs: hwmon: Document PECI drivers
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-15-iwona.winiarska@intel.com>

From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>

Add documentation for peci-cputemp driver that provides DTS thermal
readings for CPU packages and CPU cores, and peci-dimmtemp driver that
provides Temperature Sensor on DIMM readings.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 Documentation/hwmon/index.rst         |  2 +
 Documentation/hwmon/peci-cputemp.rst  | 90 +++++++++++++++++++++++++++
 Documentation/hwmon/peci-dimmtemp.rst | 57 +++++++++++++++++
 MAINTAINERS                           |  2 +
 4 files changed, 151 insertions(+)
 create mode 100644 Documentation/hwmon/peci-cputemp.rst
 create mode 100644 Documentation/hwmon/peci-dimmtemp.rst

diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index bc01601ea81a..cc76b5b3f791 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -154,6 +154,8 @@ Hardware Monitoring Kernel Drivers
    pcf8591
    pim4328
    pm6764tr
+   peci-cputemp
+   peci-dimmtemp
    pmbus
    powr1220
    pxe1610
diff --git a/Documentation/hwmon/peci-cputemp.rst b/Documentation/hwmon/peci-cputemp.rst
new file mode 100644
index 000000000000..fe0422248dc5
--- /dev/null
+++ b/Documentation/hwmon/peci-cputemp.rst
@@ -0,0 +1,90 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+Kernel driver peci-cputemp
+==========================
+
+Supported chips:
+	One of Intel server CPUs listed below which is connected to a PECI bus.
+		* Intel Xeon E5/E7 v3 server processors
+			Intel Xeon E5-14xx v3 family
+			Intel Xeon E5-24xx v3 family
+			Intel Xeon E5-16xx v3 family
+			Intel Xeon E5-26xx v3 family
+			Intel Xeon E5-46xx v3 family
+			Intel Xeon E7-48xx v3 family
+			Intel Xeon E7-88xx v3 family
+		* Intel Xeon E5/E7 v4 server processors
+			Intel Xeon E5-16xx v4 family
+			Intel Xeon E5-26xx v4 family
+			Intel Xeon E5-46xx v4 family
+			Intel Xeon E7-48xx v4 family
+			Intel Xeon E7-88xx v4 family
+		* Intel Xeon Scalable server processors
+			Intel Xeon D family
+			Intel Xeon Bronze family
+			Intel Xeon Silver family
+			Intel Xeon Gold family
+			Intel Xeon Platinum family
+
+	Datasheet: Available from http://www.intel.com/design/literature.htm
+
+Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+Description
+-----------
+
+This driver implements a generic PECI hwmon feature which provides Digital
+Thermal Sensor (DTS) thermal readings of the CPU package and CPU cores that are
+accessible via the processor PECI interface.
+
+All temperature values are given in millidegree Celsius and will be measurable
+only when the target CPU is powered on.
+
+Sysfs interface
+-------------------
+
+======================= =======================================================
+temp1_label		"Die"
+temp1_input		Provides current die temperature of the CPU package.
+temp1_max		Provides thermal control temperature of the CPU package
+			which is also known as Tcontrol.
+temp1_crit		Provides shutdown temperature of the CPU package which
+			is also known as the maximum processor junction
+			temperature, Tjmax or Tprochot.
+temp1_crit_hyst		Provides the hysteresis value from Tcontrol to Tjmax of
+			the CPU package.
+
+temp2_label		"DTS"
+temp2_input		Provides current temperature of the CPU package scaled
+			to match DTS thermal profile.
+temp2_max		Provides thermal control temperature of the CPU package
+			which is also known as Tcontrol.
+temp2_crit		Provides shutdown temperature of the CPU package which
+			is also known as the maximum processor junction
+			temperature, Tjmax or Tprochot.
+temp2_crit_hyst		Provides the hysteresis value from Tcontrol to Tjmax of
+			the CPU package.
+
+temp3_label		"Tcontrol"
+temp3_input		Provides current Tcontrol temperature of the CPU
+			package which is also known as Fan Temperature target.
+			Indicates the relative value from thermal monitor trip
+			temperature at which fans should be engaged.
+temp3_crit		Provides Tcontrol critical value of the CPU package
+			which is same to Tjmax.
+
+temp4_label		"Tthrottle"
+temp4_input		Provides current Tthrottle temperature of the CPU
+			package. Used for throttling temperature. If this value
+			is allowed and lower than Tjmax - the throttle will
+			occur and reported at lower than Tjmax.
+
+temp5_label		"Tjmax"
+temp5_input		Provides the maximum junction temperature, Tjmax of the
+			CPU package.
+
+temp[6-N]_label		Provides string "Core X", where X is resolved core
+			number.
+temp[6-N]_input		Provides current temperature of each core.
+
+======================= =======================================================
diff --git a/Documentation/hwmon/peci-dimmtemp.rst b/Documentation/hwmon/peci-dimmtemp.rst
new file mode 100644
index 000000000000..e562aed620de
--- /dev/null
+++ b/Documentation/hwmon/peci-dimmtemp.rst
@@ -0,0 +1,57 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver peci-dimmtemp
+===========================
+
+Supported chips:
+	One of Intel server CPUs listed below which is connected to a PECI bus.
+		* Intel Xeon E5/E7 v3 server processors
+			Intel Xeon E5-14xx v3 family
+			Intel Xeon E5-24xx v3 family
+			Intel Xeon E5-16xx v3 family
+			Intel Xeon E5-26xx v3 family
+			Intel Xeon E5-46xx v3 family
+			Intel Xeon E7-48xx v3 family
+			Intel Xeon E7-88xx v3 family
+		* Intel Xeon E5/E7 v4 server processors
+			Intel Xeon E5-16xx v4 family
+			Intel Xeon E5-26xx v4 family
+			Intel Xeon E5-46xx v4 family
+			Intel Xeon E7-48xx v4 family
+			Intel Xeon E7-88xx v4 family
+		* Intel Xeon Scalable server processors
+			Intel Xeon D family
+			Intel Xeon Bronze family
+			Intel Xeon Silver family
+			Intel Xeon Gold family
+			Intel Xeon Platinum family
+
+	Datasheet: Available from http://www.intel.com/design/literature.htm
+
+Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+Description
+-----------
+
+This driver implements a generic PECI hwmon feature which provides
+Temperature sensor on DIMM readings that are accessible via the processor PECI interface.
+
+All temperature values are given in millidegree Celsius and will be measurable
+only when the target CPU is powered on.
+
+Sysfs interface
+-------------------
+
+======================= =======================================================
+
+temp[N]_label		Provides string "DIMM CI", where C is DIMM channel and
+			I is DIMM index of the populated DIMM.
+temp[N]_input		Provides current temperature of the populated DIMM.
+temp[N]_max		Provides thermal control temperature of the DIMM.
+temp[N]_crit		Provides shutdown temperature of the DIMM.
+
+======================= =======================================================
+
+Note:
+	DIMM temperature attributes will appear when the client CPU's BIOS
+	completes memory training and testing.
diff --git a/MAINTAINERS b/MAINTAINERS
index e36b5c0824e3..4861a214d9fe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14517,6 +14517,8 @@ M:	Iwona Winiarska <iwona.winiarska at intel.com>
 R:	Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
 L:	linux-hwmon at vger.kernel.org
 S:	Supported
+F:	Documentation/hwmon/peci-cputemp.rst
+F:	Documentation/hwmon/peci-dimmtemp.rst
 F:	drivers/hwmon/peci/
 
 PECI SUBSYSTEM
-- 
2.31.1



From bbhushan2 at marvell.com  Tue Aug  3 04:38:24 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Tue, 3 Aug 2021 11:38:24 +0000
Subject: [EXT] Re: [PATCH 1/4] dt-bindings: perf: marvell: cn10k ddr
 performance monitor
In-Reply-To: <YQM56mlxM19UDu93@robh.at.kernel.org>
References: <20210726091027.798-1-bbhushan2@marvell.com>
 <20210726091027.798-2-bbhushan2@marvell.com>
 <YQM56mlxM19UDu93@robh.at.kernel.org>
Message-ID: <CO6PR18MB446536021939F4F3E8F4C6E4E3F09@CO6PR18MB4465.namprd18.prod.outlook.com>



> -----Original Message-----
> From: Rob Herring <robh at kernel.org>
> Sent: Friday, July 30, 2021 5:00 AM
> To: Bharat Bhushan <bbhushan2 at marvell.com>
> Cc: will at kernel.org; mark.rutland at arm.com; linux-arm-
> kernel at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; Sunil Kovvuri Goutham <sgoutham at marvell.com>
> Subject: [EXT] Re: [PATCH 1/4] dt-bindings: perf: marvell: cn10k ddr performance
> monitor
> 
> External Email
> 
> ----------------------------------------------------------------------
> On Mon, Jul 26, 2021 at 02:40:24PM +0530, Bharat Bhushan wrote:
> > Add binding documentation for the Marvell CN10k DDR performance
> > monitor unit.
> >
> > Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
> > ---
> >  .../bindings/perf/marvell-cn10k-ddr.txt           | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.txt
> 
> Bindings are in DT schema format now.

I did not paid attention it changed to DT schema. Will do required changed in next version.
Just waiting for comments in other patches. 

Thanks
-Bharat

> 
> Rob


From iwona.winiarska at intel.com  Tue Aug  3 04:31:34 2021
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue,  3 Aug 2021 13:31:34 +0200
Subject: [PATCH v2 15/15] docs: Add PECI documentation
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <20210803113134.2262882-16-iwona.winiarska@intel.com>

Add a brief overview of PECI and PECI wire interface.
The documentation also contains kernel-doc for PECI subsystem internals
and PECI CPU Driver API.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 Documentation/index.rst      |  1 +
 Documentation/peci/index.rst | 16 ++++++++++++
 Documentation/peci/peci.rst  | 48 ++++++++++++++++++++++++++++++++++++
 MAINTAINERS                  |  1 +
 4 files changed, 66 insertions(+)
 create mode 100644 Documentation/peci/index.rst
 create mode 100644 Documentation/peci/peci.rst

diff --git a/Documentation/index.rst b/Documentation/index.rst
index 54ce34fd6fbd..7671f2cd474f 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -137,6 +137,7 @@ needed).
    misc-devices/index
    scheduler/index
    mhi/index
+   peci/index
 
 Architecture-agnostic documentation
 -----------------------------------
diff --git a/Documentation/peci/index.rst b/Documentation/peci/index.rst
new file mode 100644
index 000000000000..989de10416e7
--- /dev/null
+++ b/Documentation/peci/index.rst
@@ -0,0 +1,16 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+====================
+Linux PECI Subsystem
+====================
+
+.. toctree::
+
+   peci
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/peci/peci.rst b/Documentation/peci/peci.rst
new file mode 100644
index 000000000000..a12c8e10c4a9
--- /dev/null
+++ b/Documentation/peci/peci.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+========
+Overview
+========
+
+The Platform Environment Control Interface (PECI) is a communication
+interface between Intel processor and management controllers
+(e.g. Baseboard Management Controller, BMC).
+PECI provides services that allow the management controller to
+configure, monitor and debug platform by accessing various registers.
+It defines a dedicated command protocol, where the management
+controller is acting as a PECI originator and the processor - as
+a PECI responder.
+PECI can be used in both single processor and multiple-processor based
+systems.
+
+NOTE:
+Intel PECI specification is not released as a dedicated document,
+instead it is a part of External Design Specification (EDS) for given
+Intel CPU. External Design Specifications are usually not publicly
+available.
+
+PECI Wire
+---------
+
+PECI Wire interface uses a single wire for self-clocking and data
+transfer. It does not require any additional control lines - the
+physical layer is a self-clocked one-wire bus signal that begins each
+bit with a driven, rising edge from an idle near zero volts. The
+duration of the signal driven high allows to determine whether the bit
+value is logic '0' or logic '1'. PECI Wire also includes variable data
+rate established with every message.
+
+For PECI Wire, each processor package will utilize unique, fixed
+addresses within a defined range and that address should
+have a fixed relationship with the processor socket ID - if one of the
+processors is removed, it does not affect addresses of remaining
+processors.
+
+PECI subsystem internals
+------------------------
+
+.. kernel-doc:: include/linux/peci.h
+
+PECI CPU Driver API
+-------------------
+.. kernel-doc:: include/linux/peci-cpu.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 4861a214d9fe..c50d4d0005e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14527,6 +14527,7 @@ R:	Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
 L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
 S:	Supported
 F:	Documentation/devicetree/bindings/peci/
+F:	Documentation/peci/
 F:	drivers/peci/
 F:	include/linux/peci-cpu.h
 F:	include/linux/peci.h
-- 
2.31.1



From will at kernel.org  Tue Aug  3 04:38:56 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 3 Aug 2021 12:38:56 +0100
Subject: [PATCH v3 1/4] KVM: arm64: Introduce a new VMID allocator for KVM
In-Reply-To: <20210729104009.382-2-shameerali.kolothum.thodi@huawei.com>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-2-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210803113856.GA30853@willie-the-truck>

On Thu, Jul 29, 2021 at 11:40:06AM +0100, Shameer Kolothum wrote:
> A new VMID allocator for arm64 KVM use. This is based on
> arm64 ASID allocator algorithm.
> 
> One major deviation from the ASID allocator is the way we
> flush the context. Unlike ASID allocator, we expect less
> frequent rollover in the case of VMIDs. Hence, instead of
> marking the CPU as flush_pending and issuing a local context
> invalidation on the next context switch, we broadcast TLB
> flush + I-cache invalidation over the inner shareable domain
> on rollover.
> 
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---

[...]

> +void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
> +{
> +	unsigned long flags;
> +	unsigned int cpu;
> +	u64 vmid, old_active_vmid;
> +
> +	vmid = atomic64_read(&kvm_vmid->id);
> +
> +	/*
> +	 * Please refer comments in check_and_switch_context() in
> +	 * arch/arm64/mm/context.c.
> +	 */
> +	old_active_vmid = atomic64_read(this_cpu_ptr(&active_vmids));
> +	if (old_active_vmid && vmid_gen_match(vmid) &&
> +	    atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_vmids),
> +				     old_active_vmid, vmid))
> +		return;
> +
> +	raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
> +
> +	/* Check that our VMID belongs to the current generation. */
> +	vmid = atomic64_read(&kvm_vmid->id);
> +	if (!vmid_gen_match(vmid)) {
> +		vmid = new_vmid(kvm_vmid);
> +		atomic64_set(&kvm_vmid->id, vmid);

new_vmid() can just set kvm_vmid->id directly

> +	}
> +
> +	cpu = smp_processor_id();

Why?

Will


From will at kernel.org  Tue Aug  3 04:40:35 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 3 Aug 2021 12:40:35 +0100
Subject: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU schedule out
In-Reply-To: <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210803114034.GB30853@willie-the-truck>

On Thu, Jul 29, 2021 at 11:40:09AM +0100, Shameer Kolothum wrote:
> Like ASID allocator, we copy the active_vmids into the
> reserved_vmids on a rollover. But it's unlikely that
> every CPU will have a?vCPU as current task and we may
> end up unnecessarily?reserving the VMID space.
> 
> Hence, clear active_vmids when scheduling out a vCPU.
> 
> Suggested-by: Will Deacon <will at kernel.org>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 1 +
>  arch/arm64/kvm/arm.c              | 1 +
>  arch/arm64/kvm/vmid.c             | 6 ++++++
>  3 files changed, 8 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index bb993bce1363..d93141cb8d16 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -687,6 +687,7 @@ extern unsigned int kvm_arm_vmid_bits;
>  int kvm_arm_vmid_alloc_init(void);
>  void kvm_arm_vmid_alloc_free(void);
>  void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
> +void kvm_arm_vmid_clear_active(void);
>  
>  static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
>  {
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 077e55a511a9..b134a1b89c84 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -435,6 +435,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>  	kvm_timer_vcpu_put(vcpu);
>  	kvm_vgic_put(vcpu);
>  	kvm_vcpu_pmu_restore_host(vcpu);
> +	kvm_arm_vmid_clear_active();
>  
>  	vcpu->cpu = -1;
>  }
> diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
> index 5584e84aed95..5fd51f5445c1 100644
> --- a/arch/arm64/kvm/vmid.c
> +++ b/arch/arm64/kvm/vmid.c
> @@ -116,6 +116,12 @@ static u64 new_vmid(struct kvm_vmid *kvm_vmid)
>  	return idx2vmid(vmid) | generation;
>  }
>  
> +/* Call with preemption disabled */
> +void kvm_arm_vmid_clear_active(void)
> +{
> +	atomic64_set(this_cpu_ptr(&active_vmids), 0);
> +}

I think this is very broken, as it will force everybody to take the
slow-path when they see an active_vmid of 0.

It also doesn't solve the issue I mentioned before, as an active_vmid of 0
means that the reserved vmid is preserved.

Needs more thought...

Will


From martinwguy at gmail.com  Tue Aug  3 04:40:58 2021
From: martinwguy at gmail.com (Martin Guy)
Date: Tue, 3 Aug 2021 13:40:58 +0200
Subject: [PATCH] ARM: ep93xx: remove MaverickCrunch support
In-Reply-To: <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>
References: <20210802141245.1146772-1-arnd@kernel.org>
 <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>
Message-ID: <CAL4-wQpKLtSj0xfNUXXLhbtN1wC051jpRneAuLYOi1riZfiinw@mail.gmail.com>

I forward opinion from people currently producing and supporting EP93XX boards:

From: Technologic Systems Support Team <support at embeddedarm.com>
To: martinwguy at gmail.com
Cc: jerome.oufella at savoirfairelinux.com

> I expect our customers would care if support was dropped.
> Unfortunately I don't know to what extent.  I'd like to bring
> Jerome Oufella of Savoir Faire Linux into the conversation here,
> as he runs the software company who most of our customers
> contract through when they need a modern Linux kernel running
> on one of our Cirrus Logic EP93XX series single board computers.
> I expect his opinion will be more valuable than mine.
?>
> Good morning Jerome,
>
> A member of the Linux Kernel Development community reached out
> to us this morning letting us know the community has suggested
> dropping support for the MavericCrunch FPU on the EP9302 processor.
> Would this impact any of the development your team has been doing
> for some of our mutual customers?

From: Jerome Oufella<jerome.oufella at savoirfairelinux.com>
> I am aware of a few companies who rely on variants of the TS-7250
> running not-too-old LTS releases (4.19, 5.4) to cope with their patch policies.
>
> With Linux 5.10 being the next "Super LTS", this presumably brings its
> support lifespan until about 2030, which (I believe) they would be
> comfortable with considering the age of the platform.
>
> Jerome Oufella
> Vice-President, Technologies
> www.savoirfairelinux.com


From semen.protsenko at linaro.org  Tue Aug  3 04:41:15 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 3 Aug 2021 14:41:15 +0300
Subject: [PATCH 04/12] tty: serial: samsung: Init USI to keep clocks
 running
In-Reply-To: <7364ccb2-70da-6400-ae6d-6a30171b6678@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-5-semen.protsenko@linaro.org>
 <a1701931-136e-235c-8392-a3f64c050d74@canonical.com>
 <CAPLW+4mMCzzyqqJTse-UEpjQoVu1b-9Xz3_3L=nmg63uKYFnGw@mail.gmail.com>
 <7364ccb2-70da-6400-ae6d-6a30171b6678@canonical.com>
Message-ID: <CAPLW+4m=rAAcRuRp7oC4_opjPpM=eVyeBipbaC+V=wtjErWxUQ@mail.gmail.com>

On Tue, 3 Aug 2021 at 10:37, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 03/08/2021 01:06, Sam Protsenko wrote:
>
> (...)
>
> >>> diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h
> >>> index f6c3323fc4c5..013c2646863e 100644
> >>> --- a/include/linux/serial_s3c.h
> >>> +++ b/include/linux/serial_s3c.h
> >>> @@ -28,6 +28,15 @@
> >>>  #define S3C2410_UFSTAT         (0x18)
> >>>  #define S3C2410_UMSTAT         (0x1C)
> >>>
> >>> +/* USI Control Register offset */
> >>> +#define USI_CON                      (0xC4)
> >>> +/* USI Option Register offset */
> >>> +#define USI_OPTION           (0xC8)
> >>> +/* USI_CON[0] = 0b0: clear USI global software reset (Active High) */
> >>> +#define USI_RESET            (0<<0)
> >>
> >> Just 0x0. I understand you wanted to hint it is a bit field, but the
> >> shift of 0 actually creates more questions.
> >>
> >
> > After some consideration I decided to adhere to existing style and do
> > something like this (in v2):
> >
> > 8<--------------------------------------------------------------------->8
> > #define USI_CON          (0xC4)
> > #define USI_OPTION      (0xC8)
> >
> > #define USI_CON_RESET_CLEAR        (0<<0)
> > #define USI_CON_RESET_SET        (1<<0)
> > #define USI_CON_RESET_MASK        (1<<0)
> >
> > #define USI_OPTION_HWACG_CLKREQ_ON    (1<<1)
> > #define USI_OPTION_HWACG_CLKSTOP_ON    (1<<2)
> > #define USI_OPTION_HWACG_MASK        (3<<1)
> > 8<--------------------------------------------------------------------->8
> >
> > The whole reason for those comments was missing public TRM. But in the
> > end I decided it just looks ugly. Also, this way I can do RMW
> > operation (discussed above) in more logical way.
> >
> > Please let me know if code snippets above look good to you.
>
> Please skip the USI_CON_RESET_CLEAR. There is no such pattern in the
> code. Clearing bit is an obvious operation and such code is already
> everywhere:
>     val &= ~USI_CON_RESET
>
> (or &= ~USI_RESET_MASK)
>
> Therefore for USI_CON_RESET only:
>     #define USI_CON_RESET             (1<<0)
>     #define USI_CON_RESET_MASK        (1<<0)
>

Sure, I'll make it so.

>
> Best regards,
> Krzysztof


From lorenzo.pieralisi at arm.com  Tue Aug  3 04:45:30 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue, 3 Aug 2021 12:45:30 +0100
Subject: [PATCH v7 5/7] PCI: cadence: Add support to configure virtual
 functions
In-Reply-To: <20210803050310.27122-6-kishon@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
 <20210803050310.27122-6-kishon@ti.com>
Message-ID: <20210803114530.GE11252@lpieralisi>

On Tue, Aug 03, 2021 at 10:33:08AM +0530, Kishon Vijay Abraham I wrote:
> Now that support for SR-IOV is added in PCIe endpoint core, add support
> to configure virtual functions in the Cadence PCIe EP driver.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> Acked-by: Tom Joseph <tjoseph at cadence.com>
> ---
>  .../pci/controller/cadence/pcie-cadence-ep.c  | 241 +++++++++++++++---
>  drivers/pci/controller/cadence/pcie-cadence.h |   7 +
>  2 files changed, 217 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> index 912a15be8bfd..791915054ff4 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> @@ -20,7 +20,18 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
>  				     struct pci_epf_header *hdr)
>  {
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	struct cdns_pcie *pcie = &ep->pcie;
> +	u32 reg;
> +
> +	if (vfn > 1) {
> +		dev_dbg(&epc->dev, "Only Virtual Function #1 has deviceID\n");
> +		return 0;

Shouldn't this return an error ?

> +	} else if (vfn == 1) {
> +		reg = cap + PCI_SRIOV_VF_DID;
> +		cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid);
> +		return 0;
> +	}
>  
>  	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
>  	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
> @@ -51,12 +62,14 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>  				struct pci_epf_bar *epf_bar)
>  {
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	struct cdns_pcie_epf *epf = &ep->epf[fn];
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	dma_addr_t bar_phys = epf_bar->phys_addr;
>  	enum pci_barno bar = epf_bar->barno;
>  	int flags = epf_bar->flags;
>  	u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
> +	u32 first_vf_offset, stride;
>  	u64 sz;
>  
>  	/* BAR size is 2^(aperture + 7) */
> @@ -92,26 +105,50 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>  
>  	addr0 = lower_32_bits(bar_phys);
>  	addr1 = upper_32_bits(bar_phys);
> +
> +	if (vfn == 1) {
> +		/* All virtual functions use the same BAR config */
> +		if (bar < BAR_4) {
> +			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn);
> +			b = bar;
> +		} else {
> +			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn);
> +			b = bar - BAR_4;
> +		}
> +	} else if (vfn == 0) {
> +		/* BAR configuration for physical function */
> +		if (bar < BAR_4) {
> +			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
> +			b = bar;
> +		} else {
> +			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
> +			b = bar - BAR_4;
> +		}
> +	}

Code in both branches is almost identical except for what is
assigned to reg, it is not fundamental but maybe it can be rewritten
more concisely.

Lorenzo

> +
> +	if (vfn == 0 || vfn == 1) {
> +		cfg = cdns_pcie_readl(pcie, reg);
> +		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> +			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
> +		cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
> +			CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
> +		cdns_pcie_writel(pcie, reg, cfg);
> +	}
> +
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +		epf = &epf->epf[vfn - 1];
> +	}
> +
>  	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
>  			 addr0);
>  	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
>  			 addr1);
>  
> -	if (bar < BAR_4) {
> -		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
> -		b = bar;
> -	} else {
> -		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
> -		b = bar - BAR_4;
> -	}
> -
> -	cfg = cdns_pcie_readl(pcie, reg);
> -	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> -		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
> -	cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
> -		CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
> -	cdns_pcie_writel(pcie, reg, cfg);
> -
>  	epf->epf_bar[bar] = epf_bar;
>  
>  	return 0;
> @@ -121,25 +158,48 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>  				   struct pci_epf_bar *epf_bar)
>  {
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	struct cdns_pcie_epf *epf = &ep->epf[fn];
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	enum pci_barno bar = epf_bar->barno;
> +	u32 first_vf_offset, stride;
>  	u32 reg, cfg, b, ctrl;
>  
> -	if (bar < BAR_4) {
> -		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
> -		b = bar;
> -	} else {
> -		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
> -		b = bar - BAR_4;
> +	if (vfn == 1) {
> +		if (bar < BAR_4) {
> +			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn);
> +			b = bar;
> +		} else {
> +			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn);
> +			b = bar - BAR_4;
> +		}
> +	} else if (vfn == 0) {
> +		if (bar < BAR_4) {
> +			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
> +			b = bar;
> +		} else {
> +			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
> +			b = bar - BAR_4;
> +		}
>  	}
>  
> -	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
> -	cfg = cdns_pcie_readl(pcie, reg);
> -	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> -		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
> -	cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
> -	cdns_pcie_writel(pcie, reg, cfg);
> +	if (vfn == 0 || vfn == 1) {
> +		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
> +		cfg = cdns_pcie_readl(pcie, reg);
> +		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> +			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
> +		cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
> +		cdns_pcie_writel(pcie, reg, cfg);
> +	}
> +
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +		epf = &epf->epf[vfn - 1];
> +	}
>  
>  	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0);
>  	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0);
> @@ -152,8 +212,18 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
>  {
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>  	struct cdns_pcie *pcie = &ep->pcie;
> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
> +	u32 first_vf_offset, stride;
>  	u32 r;
>  
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +	}
> +
>  	r = find_first_zero_bit(&ep->ob_region_map,
>  				sizeof(ep->ob_region_map) * BITS_PER_LONG);
>  	if (r >= ep->max_regions - 1) {
> @@ -193,9 +263,19 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
>  {
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>  	struct cdns_pcie *pcie = &ep->pcie;
> +	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
> +	u32 first_vf_offset, stride;
>  	u16 flags;
>  
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +	}
> +
>  	/*
>  	 * Set the Multiple Message Capable bitfield into the Message Control
>  	 * register.
> @@ -213,9 +293,19 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
>  {
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>  	struct cdns_pcie *pcie = &ep->pcie;
> +	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
> +	u32 first_vf_offset, stride;
>  	u16 flags, mme;
>  
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +	}
> +
>  	/* Validate that the MSI feature is actually enabled. */
>  	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
>  	if (!(flags & PCI_MSI_FLAGS_ENABLE))
> @@ -232,11 +322,21 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
>  
>  static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
>  {
> +	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
> +	u32 first_vf_offset, stride;
>  	u32 val, reg;
>  
> +	if (vfunc_no > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, func_no, sriov_cap
> +							+ PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, func_no, sriov_cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		func_no = func_no + first_vf_offset + ((vfunc_no - 1) * stride);
> +	}
> +
>  	reg = cap + PCI_MSIX_FLAGS;
>  	val = cdns_pcie_ep_fn_readw(pcie, func_no, reg);
>  	if (!(val & PCI_MSIX_FLAGS_ENABLE))
> @@ -251,11 +351,21 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
>  				 u16 interrupts, enum pci_barno bir,
>  				 u32 offset)
>  {
> +	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
> +	u32 first_vf_offset, stride;
>  	u32 val, reg;
>  
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +	}
> +
>  	reg = cap + PCI_MSIX_FLAGS;
>  	val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
>  	val &= ~PCI_MSIX_FLAGS_QSIZE;
> @@ -275,8 +385,8 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
>  	return 0;
>  }
>  
> -static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
> -				     u8 intx, bool is_asserted)
> +static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
> +				     bool is_asserted)
>  {
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	unsigned long flags;
> @@ -339,11 +449,21 @@ static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
>  static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
>  				     u8 interrupt_num)
>  {
> +	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
>  	u16 flags, mme, data, data_mask;
>  	u8 msi_count;
>  	u64 pci_addr, pci_addr_mask = 0xff;
> +	u32 first_vf_offset, stride;
> +
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +	}
>  
>  	/* Check whether the MSI feature has been enabled by the PCI host. */
>  	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
> @@ -389,15 +509,25 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
>  				    u32 entry_size, u32 *msi_data,
>  				    u32 *msi_addr_offset)
>  {
> +	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>  	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	u64 pci_addr, pci_addr_mask = 0xff;
>  	u16 flags, mme, data, data_mask;
> +	u32 first_vf_offset, stride;
>  	u8 msi_count;
>  	int ret;
>  	int i;
>  
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +	}
> +
>  	/* Check whether the MSI feature has been enabled by the PCI host. */
>  	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
>  	if (!(flags & PCI_MSI_FLAGS_ENABLE))
> @@ -438,16 +568,29 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
>  static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
>  				      u16 interrupt_num)
>  {
> +	u32 sriov_cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>  	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
>  	u32 tbl_offset, msg_data, reg;
>  	struct cdns_pcie *pcie = &ep->pcie;
>  	struct pci_epf_msix_tbl *msix_tbl;
> +	u32 first_vf_offset, stride;
>  	struct cdns_pcie_epf *epf;
>  	u64 pci_addr_mask = 0xff;
>  	u64 msg_addr;
>  	u16 flags;
>  	u8 bir;
>  
> +	epf = &ep->epf[fn];
> +
> +	if (vfn > 0) {
> +		first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +							PCI_SRIOV_VF_OFFSET);
> +		stride = cdns_pcie_ep_fn_readw(pcie, fn, sriov_cap +
> +					       PCI_SRIOV_VF_STRIDE);
> +		fn = fn + first_vf_offset + ((vfn - 1) * stride);
> +		epf = &epf->epf[vfn - 1];
> +	}
> +
>  	/* Check whether the MSI-X feature has been enabled by the PCI host. */
>  	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
>  	if (!(flags & PCI_MSIX_FLAGS_ENABLE))
> @@ -458,7 +601,6 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
>  	bir = tbl_offset & PCI_MSIX_TABLE_BIR;
>  	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
>  
> -	epf = &ep->epf[fn];
>  	msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
>  	msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
>  	msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
> @@ -485,9 +627,15 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
>  				  u16 interrupt_num)
>  {
>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> +	struct cdns_pcie *pcie = &ep->pcie;
> +	struct device *dev = pcie->dev;
>  
>  	switch (type) {
>  	case PCI_EPC_IRQ_LEGACY:
> +		if (vfn > 0) {
> +			dev_err(dev, "Cannot raise legacy interrupts for VF\n");
> +			return -EINVAL;
> +		}
>  		return cdns_pcie_ep_send_legacy_irq(ep, fn, vfn, 0);
>  
>  	case PCI_EPC_IRQ_MSI:
> @@ -525,6 +673,13 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
>  	return 0;
>  }
>  
> +static const struct pci_epc_features cdns_pcie_epc_vf_features = {
> +	.linkup_notifier = false,
> +	.msi_capable = true,
> +	.msix_capable = true,
> +	.align = 65536,
> +};
> +
>  static const struct pci_epc_features cdns_pcie_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
> @@ -535,7 +690,10 @@ static const struct pci_epc_features cdns_pcie_epc_features = {
>  static const struct pci_epc_features*
>  cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
>  {
> -	return &cdns_pcie_epc_features;
> +	if (!vfunc_no)
> +		return &cdns_pcie_epc_features;
> +
> +	return &cdns_pcie_epc_vf_features;
>  }
>  
>  static const struct pci_epc_ops cdns_pcie_epc_ops = {
> @@ -561,9 +719,11 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct device_node *np = dev->of_node;
>  	struct cdns_pcie *pcie = &ep->pcie;
> +	struct cdns_pcie_epf *epf;
>  	struct resource *res;
>  	struct pci_epc *epc;
>  	int ret;
> +	int i;
>  
>  	pcie->is_rc = false;
>  
> @@ -608,6 +768,25 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
>  	if (!ep->epf)
>  		return -ENOMEM;
>  
> +	epc->max_vfs = devm_kcalloc(dev, epc->max_functions,
> +				    sizeof(*epc->max_vfs), GFP_KERNEL);
> +	if (!epc->max_vfs)
> +		return -ENOMEM;
> +
> +	ret = of_property_read_u8_array(np, "max-virtual-functions",
> +					epc->max_vfs, epc->max_functions);
> +	if (ret == 0) {
> +		for (i = 0; i < epc->max_functions; i++) {
> +			epf = &ep->epf[i];
> +			if (epc->max_vfs[i] == 0)
> +				continue;
> +			epf->epf = devm_kcalloc(dev, epc->max_vfs[i],
> +						sizeof(*ep->epf), GFP_KERNEL);
> +			if (!epf->epf)
> +				return -ENOMEM;
> +		}
> +	}
> +
>  	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
>  			       resource_size(pcie->mem_res), PAGE_SIZE);
>  	if (ret < 0) {
> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
> index 30db2d68c17a..927b49e42997 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence.h
> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
> @@ -50,6 +50,10 @@
>  	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
>  #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
>  	(CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
> +#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) \
> +	(CDNS_PCIE_LM_BASE + 0x0280 + (fn) * 0x0008)
> +#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn) \
> +	(CDNS_PCIE_LM_BASE + 0x0284 + (fn) * 0x0008)
>  #define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
>  	(GENMASK(4, 0) << ((b) * 8))
>  #define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
> @@ -114,6 +118,7 @@
>  
>  #define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET	0x90
>  #define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET	0xb0
> +#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET	0x200
>  
>  /*
>   * Root Port Registers (PCI configuration space for the root port function)
> @@ -308,9 +313,11 @@ struct cdns_pcie_rc {
>  
>  /**
>   * struct cdns_pcie_epf - Structure to hold info about endpoint function
> + * @epf: Info about virtual functions attached to the physical function
>   * @epf_bar: reference to the pci_epf_bar for the six Base Address Registers
>   */
>  struct cdns_pcie_epf {
> +	struct cdns_pcie_epf *epf;
>  	struct pci_epf_bar *epf_bar[PCI_STD_NUM_BARS];
>  };
>  
> -- 
> 2.17.1
> 


From eizan at chromium.org  Tue Aug  3 04:46:42 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Tue, 3 Aug 2021 21:46:42 +1000
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <CAFqH_527RL56P=zEg7yTaeeqTvFOjT3ThxpX-Qumk25dR6+-bA@mail.gmail.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <CAFqH_527RL56P=zEg7yTaeeqTvFOjT3ThxpX-Qumk25dR6+-bA@mail.gmail.com>
Message-ID: <CAOak1e90y_2aaD4ssH9WfqUUXjUSWkN_rLW51NujkD7oMayhew@mail.gmail.com>

Hi Enric, thanks for your comment.

> > ... Instead of depending on the presence of a mediatek,vpu property in
>
> Looks like there is something missing in the commit message?

That line is a continuation of the commit message header, I.e., it's
meant to read:
"use mdp-rdma0 alias to point to MDP master Instead of depending on
the presence of a mediatek,vpu property in the device node"

Eizan


From joey.gouly at arm.com  Tue Aug  3 04:53:50 2021
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 3 Aug 2021 12:53:50 +0100
Subject: [PATCH 2/4] arm64: entry: clarify entry/exit helpers
In-Reply-To: <20210802140733.52716-3-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
 <20210802140733.52716-3-mark.rutland@arm.com>
Message-ID: <20210803115350.GA52119@e124191.cambridge.arm.com>

On Mon, Aug 02, 2021 at 03:07:31PM +0100, Mark Rutland wrote:
> When entering an exception, we must perform irq/context state management
> before we can use instrumentable C code. Similary, when exiting an

typo: Similarily

> exception we cannot use instrumentable C code after we perform
> irq/context state management.
> 
> Originally, we'd intended that the enter_from_*() and exit_to_*()
> helpers would enforce this by virtue of being the first and last
> functions called, respectively, in an exception handler. However, as
> they now call instrumentable code themselves, this is not as clearly
> true.
> 
> To make this more robust, this patch splits the irq/context state
> management into separate helpers, with all the helpers commented to make
> their intended purpose more obvious.
> 
> In exit_to_kernel_mode() we'll now check TFSR_EL1 before we assert that
> IRQs are disabled, but this ordering is not important, and other than
> this there should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: James Morse <james.morse at arm.com>
> Cc: Joey Gouly <joey.gouly at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/kernel/entry-common.c | 70 ++++++++++++++++++++++++++++++++++++----
>  1 file changed, 63 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
> index 6f7a98d8d60f..6dc64f99f185 100644
> --- a/arch/arm64/kernel/entry-common.c
> +++ b/arch/arm64/kernel/entry-common.c
> @@ -26,10 +26,14 @@
>  #include <asm/system_misc.h>
>  
>  /*
> + * Handle IRQ/context state management when entering from kernel mode.
> + * Before this function is called it is not safe to call regular kernel code,
> + * intrumentable code, or any code which may trigger an exception.
> + *
>   * This is intended to match the logic in irqentry_enter(), handling the kernel
>   * mode transitions only.
>   */
> -static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
> +static __always_inline void __enter_from_kernel_mode(struct pt_regs *regs)
>  {
>  	regs->exit_rcu = false;
>  
> @@ -45,20 +49,26 @@ static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
>  	lockdep_hardirqs_off(CALLER_ADDR0);
>  	rcu_irq_enter_check_tick();
>  	trace_hardirqs_off_finish();
> +}
>  
> +static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
> +{
> +	__enter_from_kernel_mode(regs);
>  	mte_check_tfsr_entry();
>  }
>  
>  /*
> + * Handle irq/context state management when exiting to kernel mode.
Uppercase IRQ to match the other comments.
> + * after this function returns it is not safe to call regular kernel code,
'After' to match the other comments.
> + * intrumentable code, or any code which may trigger an exception.
> + *
>   * This is intended to match the logic in irqentry_exit(), handling the kernel
>   * mode transitions only, and with preemption handled elsewhere.
>   */
> -static void noinstr exit_to_kernel_mode(struct pt_regs *regs)
> +static __always_inline void __exit_to_kernel_mode(struct pt_regs *regs)
>  {
>  	lockdep_assert_irqs_disabled();
>  
> -	mte_check_tfsr_exit();
> -
>  	if (interrupts_enabled(regs)) {
>  		if (regs->exit_rcu) {
>  			trace_hardirqs_on_prepare();
> @@ -75,7 +85,18 @@ static void noinstr exit_to_kernel_mode(struct pt_regs *regs)

Reviewed-by: Joey Gouly <joey.gouly at arm.com>


From semen.protsenko at linaro.org  Tue Aug  3 04:55:06 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 3 Aug 2021 14:55:06 +0300
Subject: [PATCH 09/12] dt-bindings: clock: Add bindings for Exynos850
 clock controller
In-Reply-To: <042095c4-8404-9292-83d3-531bfdcd7b35@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-10-semen.protsenko@linaro.org>
 <042095c4-8404-9292-83d3-531bfdcd7b35@canonical.com>
Message-ID: <CAPLW+4kvg-4K79y4+U+w75896uAsMBeZoTm-f8us7BCEEbhr9g@mail.gmail.com>

On Fri, 30 Jul 2021 at 18:43, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 30/07/2021 16:49, Sam Protsenko wrote:
> > Add documentation for Exynos850 clock driver bindings and corresponding
> > clock ID constants, which will be used further both in clock driver and
> > in device tree files. Constants are grouped per domain basis (CMU) for
> > more convenient usage, but those are just unique numbers and have
> > nothing to do with register offsets, etc.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> >  .../bindings/clock/exynos850-clock.yaml       |  70 +++++
> >  include/dt-bindings/clock/exynos850.h         | 267 ++++++++++++++++++
> >  2 files changed, 337 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/clock/exynos850-clock.yaml
> >  create mode 100644 include/dt-bindings/clock/exynos850.h
> >
> > diff --git a/Documentation/devicetree/bindings/clock/exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/exynos850-clock.yaml
> > new file mode 100644
> > index 000000000000..201c2b79e629
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/exynos850-clock.yaml
> > @@ -0,0 +1,70 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/clock/exynos850-clock.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Clock bindings for Samsung Exynos850 clock controller
>
> What plans do you have for this binding? Is it complete? If yes, there
> is no point to have binding for each SoC clock controller and this
> should be merged into for example:
> Documentation/devicetree/bindings/clock/exynos5420-clock.txt
>

Yeah, I'll remove the whole patch in v2. It's not really needed here,
as clk driver is just a stub for now. I'll send a separate patch
series for the clock driver later, including bindings.

> First - convert exynos5420-clock.txt into YAML. Then add Exynos850.
>
> Other files can be also integrated.
>
> > +
> > +maintainers:
> > +  - Sam Protsenko <semen.protsenko at linaro.org>
>
> I propose also:
> +Sylwester Nawrocki <s.nawrocki at samsung.com>
> +Tomasz Figa <tomasz.figa at gmail.com>
> +Chanwoo Choi <cw00.choi at samsung.com>
>
> > +
> > +description: |
> > +  The Exynos850 clock controller generates and supplies clock to various
> > +  controllers within the SoC.
>
>
> > Each clock is assigned an identifier and client
> > +  nodes can use this identifier to specify the clock which they consume.
>
> Skip the sentence, it's generic clock provider/consumer description.
>
> > +
> > +  All available clocks are defined as preprocessor macros in
> > +  dt-bindings/clock/exynos850.h header and can be used in device tree sources.
> > +
> > +properties:
> > +  compatible:
> > +    const: samsung,exynos850-clock
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  '#clock-cells':
> > +    const: 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - '#clock-cells'
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  # Clock controller node
> > +  - |
> > +    clock: clock-controller at 0x120e0000 {
> > +        compatible = "samsung,exynos850-clock";
> > +        reg = <0x0 0x120e0000 0x8000>;
> > +        #clock-cells = <1>;
> > +    };
> > +
> > +  # Required external clocks (should be provided in particular board DTS)
> > +  - |
> > +    fixed-rate-clocks {
> > +        oscclk {
>
> Use a generic node name:
> s/oscclk/clock/
>
> > +            compatible = "samsung,exynos850-oscclk";
> > +            clock-frequency = <26000000>;
> > +        };
> > +    };
> > +
> > +  # UART controller node that consumes the clock generated by the clock
> > +  # controller
> > +  - |
> > +    #include <dt-bindings/clock/exynos850.h>
> > +
> > +    serial_0: uart at 13820000 {
> > +        compatible = "samsung,exynos850-uart";
> > +        reg = <0x0 0x13820000 0x100>;
> > +        interrupts = <GIC_SPI INTREQ__UART IRQ_TYPE_LEVEL_HIGH>;
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&uart0_bus>;
> > +        clocks = <&clock GATE_UART_QCH>, <&clock DOUT_UART>;
> > +        clock-names = "gate_uart_clk0", "uart";
> > +    };
> > +
> > +...
> > diff --git a/include/dt-bindings/clock/exynos850.h b/include/dt-bindings/clock/exynos850.h
> > new file mode 100644
> > index 000000000000..b197db4427fc
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/exynos850.h
> > @@ -0,0 +1,267 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
> > + * Copyright (C) 2021 Linaro Ltd.
> > + *
> > + * Device Tree binding constants for Exynos850 clock controller.
> > + */
> > +
> > +#ifndef _DT_BINDINGS_CLOCK_EXYNOS_850_H
> > +#define _DT_BINDINGS_CLOCK_EXYNOS_850_H
> > +
> > +#define NONE                                 (0 + 0)
>
> What type of clock is it?
>
> > +#define OSCCLK                                       (0 + 1)
>
> Isn't this CLK_FIN_PLL?
>
> > +
> > +#define CLK_APM_BASE                         (10)
> > +#define UMUX_DLL_USER                                (CLK_APM_BASE + 0)
>
> Why having a base? We are not using it in any other bindings.
>
> > +#define UMUX_CLK_APM_BUS                     (CLK_APM_BASE + 1)
> > +#define GATE_APM_CMU_APM_QCH                 (CLK_APM_BASE + 2)
> > +#define GATE_GREBEINTEGRATION_QCH_GREBE              (CLK_APM_BASE + 3)
> > +#define GATE_GREBEINTEGRATION_QCH_DBG                (CLK_APM_BASE + 4)
> > +#define GATE_I3C_APM_PMIC_QCH_S_I3C          (CLK_APM_BASE + 5)
> > +#define GATE_I3C_APM_PMIC_QCH                        (CLK_APM_BASE + 6)
> > +#define GATE_INTMEM_QCH                              (CLK_APM_BASE + 7)
> > +#define GATE_MAILBOX_APM_AP_QCH                      (CLK_APM_BASE + 8)
> > +#define GATE_MAILBOX_APM_CHUB_QCH            (CLK_APM_BASE + 9)
> > +#define GATE_MAILBOX_APM_CP_QCH                      (CLK_APM_BASE + 10)
> > +#define GATE_MAILBOX_APM_GNSS_QCH            (CLK_APM_BASE + 11)
> > +#define GATE_MAILBOX_APM_WLBT_QCH            (CLK_APM_BASE + 12)
> > +#define GATE_MAILBOX_AP_CHUB_QCH             (CLK_APM_BASE + 13)
> > +#define GATE_MAILBOX_AP_CP_QCH                       (CLK_APM_BASE + 14)
> > +#define GATE_MAILBOX_AP_CP_S_QCH             (CLK_APM_BASE + 15)
> > +#define GATE_MAILBOX_AP_GNSS_QCH             (CLK_APM_BASE + 16)
> > +#define GATE_MAILBOX_AP_WLBT_QCH             (CLK_APM_BASE + 17)
> > +#define GATE_MAILBOX_CP_CHUB_QCH             (CLK_APM_BASE + 18)
> > +#define GATE_MAILBOX_CP_GNSS_QCH             (CLK_APM_BASE + 19)
> > +#define GATE_MAILBOX_CP_WLBT_QCH             (CLK_APM_BASE + 20)
> > +#define GATE_MAILBOX_GNSS_CHUB_QCH           (CLK_APM_BASE + 21)
> > +#define GATE_MAILBOX_GNSS_WLBT_QCH           (CLK_APM_BASE + 22)
> > +#define GATE_MAILBOX_WLBT_ABOX_QCH           (CLK_APM_BASE + 23)
> > +#define GATE_MAILBOX_WLBT_CHUB_QCH           (CLK_APM_BASE + 24)
> > +#define GATE_PMU_INTR_GEN_QCH                        (CLK_APM_BASE + 25)
> > +#define GATE_ROM_CRC32_HOST_QCH                      (CLK_APM_BASE + 26)
> > +#define GATE_SPEEDY_APM_QCH                  (CLK_APM_BASE + 27)
> > +#define GATE_WDT_APM_QCH                     (CLK_APM_BASE + 28)
> > +
> > +#define CLK_AUD_BASE                         (50)
> > +#define UMUX_CLK_AUD_CPU_HCH                 (CLK_AUD_BASE + 0)
> > +#define GATE_ABOX_QCH_CPU                    (CLK_AUD_BASE + 1)
> > +#define GATE_ABOX_QCH_ACLK                   (CLK_AUD_BASE + 2)
> > +#define GATE_ABOX_QCH_BCLK0                  (CLK_AUD_BASE + 3)
> > +#define GATE_ABOX_QCH_BCLK1                  (CLK_AUD_BASE + 4)
> > +#define GATE_ABOX_QCH_FM                     (CLK_AUD_BASE + 5)
> > +#define GATE_ABOX_QCH_BCLK2                  (CLK_AUD_BASE + 6)
> > +#define GATE_ABOX_QCH_CCLK_ASB                       (CLK_AUD_BASE + 7)
> > +#define GATE_ABOX_QCH_BCLK3                  (CLK_AUD_BASE + 8)
> > +#define GATE_ABOX_QCH_BCLK4                  (CLK_AUD_BASE + 9)
> > +#define GATE_ABOX_QCH_BCLK5                  (CLK_AUD_BASE + 10)
> > +#define GATE_ABOX_QCH_BCLK6                  (CLK_AUD_BASE + 11)
> > +#define GATE_ABOX_QCH_BCLK_CNT                       (CLK_AUD_BASE + 12)
> > +#define GATE_AUD_CMU_AUD_QCH                 (CLK_AUD_BASE + 13)
> > +#define GATE_GPIO_AUD_QCH                    (CLK_AUD_BASE + 14)
> > +#define GATE_SYSMMU_AUD_QCH_S1                       (CLK_AUD_BASE + 15)
> > +#define GATE_WDT_AUD_QCH                     (CLK_AUD_BASE + 16)
> > +#define PLL_AUD_OUT                          (CLK_AUD_BASE + 17)
> > +#define DOUT_CLK_AUD_CPU                     (CLK_AUD_BASE + 18)
> > +#define DOUT_CLK_AUD_CPU_ACLK                        (CLK_AUD_BASE + 19)
> > +#define DOUT_CLK_AUD_CPU_PCLKDBG             (CLK_AUD_BASE + 20)
> > +#define DOUT_CLK_AUD_BUSD                    (CLK_AUD_BASE + 21)
> > +#define DOUT_CLK_AUD_UAIF0                   (CLK_AUD_BASE + 23)
> > +#define DOUT_CLK_AUD_UAIF1                   (CLK_AUD_BASE + 24)
> > +#define DOUT_CLK_AUD_FM                              (CLK_AUD_BASE + 25)
> > +#define DOUT_CLK_AUD_BUSP                    (CLK_AUD_BASE + 26)
> > +#define DOUT_CLK_AUD_UAIF2                   (CLK_AUD_BASE + 27)
> > +#define DOUT_CLK_AUD_CNT                     (CLK_AUD_BASE + 28)
> > +#define DOUT_CLK_AUD_UAIF3                   (CLK_AUD_BASE + 29)
> > +#define DOUT_CLK_AUD_UAIF4                   (CLK_AUD_BASE + 30)
> > +#define DOUT_CLK_AUD_UAIF5                   (CLK_AUD_BASE + 31)
> > +#define DOUT_CLK_AUD_UAIF6                   (CLK_AUD_BASE + 32)
> > +#define DOUT_CLK_AUD_AUDIF                   (CLK_AUD_BASE + 33)
> > +#define DOUT_CLK_AUD_MCLK                    (CLK_AUD_BASE + 34)
> > +#define UMUX_CLK_AUD_FM                              (CLK_AUD_BASE + 35)
> > +
> > +#define CLK_CHUB_BASE                                (100)
> > +#define GATE_BAAW_C_CHUB_QCH                 (CLK_CHUB_BASE  + 0)
> > +#define GATE_BAAW_D_CHUB_QCH                 (CLK_CHUB_BASE  + 1)
> > +#define GATE_CHUB_CMU_CHUB_QCH                       (CLK_CHUB_BASE  + 2)
> > +#define GATE_CM4_CHUB_QCH                    (CLK_CHUB_BASE  + 3)
> > +#define GATE_DMIC_AHB0_QCH                   (CLK_CHUB_BASE  + 4)
> > +#define GATE_DMIC_IF_QCH_PCLK                        (CLK_CHUB_BASE  + 5)
> > +#define GATE_DMIC_IF_QCH_DMIC_CLK            (CLK_CHUB_BASE  + 6)
> > +#define GATE_HWACG_SYS_DMIC0_QCH             (CLK_CHUB_BASE  + 7)
> > +#define GATE_PWM_CHUB_QCH                    (CLK_CHUB_BASE  + 8)
> > +#define GATE_SWEEPER_C_CHUB_QCH                      (CLK_CHUB_BASE  + 9)
> > +#define GATE_SWEEPER_D_CHUB_QCH                      (CLK_CHUB_BASE  + 10)
> > +#define GATE_TIMER_CHUB_QCH                  (CLK_CHUB_BASE  + 11)
> > +#define GATE_WDT_CHUB_QCH                    (CLK_CHUB_BASE  + 12)
> > +#define GATE_U_DMIC_CLK_SCAN_MUX_QCH         (CLK_CHUB_BASE  + 13)
> > +#define DOUT_CLK_CHUB_BUS                    (CLK_CHUB_BASE  + 14)
> > +#define DOUT_CLK_CHUB_DMIC_IF                        (CLK_CHUB_BASE  + 15)
> > +#define DOUT_CLK_CHUB_DMIC_IF_DIV2           (CLK_CHUB_BASE  + 16)
> > +#define DOUT_CLK_CHUB_DMIC                   (CLK_CHUB_BASE  + 17)
> > +
> > +#define CLK_CMGP_BASE                                (150)
> > +#define UMUX_CLK_CMGP_USI_CMGP0                      (CLK_CMGP_BASE +  0)
> > +#define UMUX_CLK_CMGP_USI_CMGP1                      (CLK_CMGP_BASE +  1)
> > +#define GATE_ADC_CMGP_QCH_S0                 (CLK_CMGP_BASE +  2)
> > +#define GATE_ADC_CMGP_QCH_S1                 (CLK_CMGP_BASE +  3)
> > +#define GATE_ADC_CMGP_QCH_ADC                        (CLK_CMGP_BASE +  4)
> > +#define GATE_CMGP_CMU_CMGP_QCH                       (CLK_CMGP_BASE +  5)
> > +#define GATE_GPIO_CMGP_QCH                   (CLK_CMGP_BASE +  6)
> > +#define GATE_USI_CMGP0_QCH                   (CLK_CMGP_BASE +  7)
> > +#define GATE_USI_CMGP1_QCH                   (CLK_CMGP_BASE +  8)
> > +#define DOUT_CLK_CMGP_ADC                    (CLK_CMGP_BASE +  9)
> > +#define DOUT_CLK_CMGP_USI_CMGP0                      (CLK_CMGP_BASE +  10)
> > +#define DOUT_CLK_CMGP_USI_CMGP1                      (CLK_CMGP_BASE +  11)
> > +
> > +#define CLK_TOP_BASE                         (200)
>
> You seem to register all clocks under one CMU. Are you sure that this
> reflects the HW? It looks quite a big set of clocks for one block... It
> does not look scallable.
>
> > +#define GATE_CMU_TOP_CMUREF_QCH                      (CLK_TOP_BASE + 0)
> > +#define GATE_DFTMUX_CMU_QCH_CLK_CIS0         (CLK_TOP_BASE + 1)
> > +#define GATE_DFTMUX_CMU_QCH_CLK_CIS1         (CLK_TOP_BASE + 2)
> > +#define GATE_DFTMUX_CMU_QCH_CLK_CIS2         (CLK_TOP_BASE + 3)
> > +#define GATE_OTP_QCH                         (CLK_TOP_BASE + 4)
> > +#define GATE_ADM_AHB_SSS_QCH                 (CLK_TOP_BASE + 5)
> > +#define GATE_BAAW_P_CHUB_QCH                 (CLK_TOP_BASE + 6)
> > +#define GATE_BAAW_P_GNSS_QCH                 (CLK_TOP_BASE + 7)
> > +#define GATE_BAAW_P_MODEM_QCH                        (CLK_TOP_BASE + 8)
> > +#define GATE_BAAW_P_WLBT_QCH                 (CLK_TOP_BASE + 9)
> > +
> > +#define CLK_CORE_BASE                                (250)
> > +#define GATE_CCI_550_QCH                     (CLK_CORE_BASE + 0)
> > +#define GATE_CORE_CMU_CORE_QCH                       (CLK_CORE_BASE + 1)
> > +#define GATE_GIC_QCH                         (CLK_CORE_BASE + 2)
> > +#define GATE_GPIO_CORE_QCH                   (CLK_CORE_BASE + 3)
> > +#define GATE_MMC_EMBD_QCH                    (CLK_CORE_BASE + 4)
> > +#define GATE_PDMA_CORE_QCH                   (CLK_CORE_BASE + 5)
> > +#define GATE_RTIC_QCH                                (CLK_CORE_BASE + 6)
> > +#define GATE_SPDMA_CORE_QCH                  (CLK_CORE_BASE + 7)
> > +#define GATE_SSS_QCH                         (CLK_CORE_BASE + 8)
> > +#define GATE_TREX_D_CORE_QCH                 (CLK_CORE_BASE + 9)
> > +#define GATE_TREX_P_CORE_QCH                 (CLK_CORE_BASE + 10)
> > +#define GATE_CSSYS_DBG_QCH                   (CLK_CORE_BASE + 11)
> > +#define GATE_SECJTAG_QCH                     (CLK_CORE_BASE + 12)
> > +#define DOUT_CORE_MMC_EMBD                   (CLK_CORE_BASE + 13)
> > +
> > +#define CLK_DPU_BASE                         (300)
> > +#define GATE_DPU_QCH_S_DPP                   (CLK_DPU_BASE  + 0)
> > +#define GATE_DPU_QCH_S_DMA                   (CLK_DPU_BASE  + 1)
> > +#define GATE_DPU_QCH_S_DECON                 (CLK_DPU_BASE  + 2)
> > +#define GATE_DPU_CMU_DPU_QCH                 (CLK_DPU_BASE  + 3)
> > +#define GATE_SMMU_DPU_QCH                    (CLK_DPU_BASE  + 4)
> > +#define DOUT_CLK_DPU_BUSP                    (CLK_DPU_BASE  + 5)
> > +
> > +#define CLK_G3D_BASE                         (350)
> > +#define GATE_G3D_CMU_G3D_QCH                 (CLK_G3D_BASE + 0)
> > +#define GATE_GPU_QCH                         (CLK_G3D_BASE + 1)
> > +#define DOUT_CLK_G3D_BUSP                    (CLK_G3D_BASE + 2)
> > +
> > +#define CLK_HIS_BASE                         (400)
> > +#define GATE_GPIO_HSI_QCH                    (CLK_HIS_BASE + 0)
> > +#define GATE_HSI_CMU_HSI_QCH                 (CLK_HIS_BASE + 1)
> > +#define GATE_MMC_CARD_QCH                    (CLK_HIS_BASE + 2)
> > +#define GATE_USB20DRD_TOP_QCH_LINK           (CLK_HIS_BASE + 3)
> > +#define GATE_USB20DRD_TOP_QCH_20CTRL         (CLK_HIS_BASE + 4)
> > +#define GATE_USB20DRD_TOP_QCH_REFCLK         (CLK_HIS_BASE + 5)
> > +#define GATE_USB20DRD_TOP_QCH_RTC            (CLK_HIS_BASE + 6)
> > +#define PLL_MMC_OUT                          (CLK_HIS_BASE + 7)
> > +#define HSI_BUS                                      (CLK_HIS_BASE + 8)
>
> Please prefix HSI/IS/MFCM with something reasonable. Most of other
> bindings prefix everything with CLK or ACLK/SCLK/PCLK/PHYCLK/DOUT, but
> having GATE/DOUT/MUX is reasonable as well. However here and further you
> miss prefixes.
>
> > +#define HSI_MMC_CARD                         (CLK_HIS_BASE + 9)
> > +#define HSI_USB20DRD                         (CLK_HIS_BASE + 10)
> > +
> > +#define CLK_IS_BASE                          (450)
> > +#define GATE_CSIS0_QCH                               (CLK_IS_BASE + 0)
> > +#define GATE_CSIS1_QCH                               (CLK_IS_BASE + 1)
> > +#define GATE_CSIS2_QCH                               (CLK_IS_BASE + 2)
> > +#define GATE_IS_CMU_IS_QCH                   (CLK_IS_BASE + 3)
> > +#define GATE_IS_TOP_QCH_S_00                 (CLK_IS_BASE + 4)
> > +#define GATE_IS_TOP_QCH_S_02                 (CLK_IS_BASE + 5)
> > +#define GATE_IS_TOP_QCH_S_03                 (CLK_IS_BASE + 6)
> > +#define GATE_IS_TOP_QCH_S_04                 (CLK_IS_BASE + 7)
> > +#define GATE_IS_TOP_QCH_S_05                 (CLK_IS_BASE + 8)
> > +#define GATE_IS_TOP_QCH_S_06                 (CLK_IS_BASE + 9)
> > +#define GATE_SYSMMU_IS0_QCH                  (CLK_IS_BASE + 10)
> > +#define GATE_SYSMMU_IS1_QCH                  (CLK_IS_BASE + 11)
> > +#define IS_BUS                                       (CLK_IS_BASE + 12)
> > +#define IS_VRA                                       (CLK_IS_BASE + 13)
> > +#define IS_ITP                                       (CLK_IS_BASE + 14)
> > +#define IS_GDC                                       (CLK_IS_BASE + 15)
> > +#define UMUX_CLK_IS_BUS                              (CLK_IS_BASE + 15)
> > +#define UMUX_CLK_IS_ITP                              (CLK_IS_BASE + 16)
> > +#define UMUX_CLK_IS_VRA                              (CLK_IS_BASE + 17)
> > +#define UMUX_CLK_IS_GDC                              (CLK_IS_BASE + 18)
> > +#define GATE_CLK_ITP                         (CLK_IS_BASE + 19)
> > +#define GATE_CLK_VRA                         (CLK_IS_BASE + 20)
> > +#define GATE_CLK_GDC                         (CLK_IS_BASE + 21)
> > +#define CIS_CLK0                             (CLK_IS_BASE + 22)
> > +#define CIS_CLK1                             (CLK_IS_BASE + 23)
> > +#define CIS_CLK2                             (CLK_IS_BASE + 24)
> > +
> > +#define CLK_MFCMSCL_BASE                     (500)
> > +#define GATE_JPEG_QCH                                (CLK_MFCMSCL_BASE + 0)
> > +#define GATE_M2M_QCH                         (CLK_MFCMSCL_BASE + 1)
> > +#define GATE_MCSC_QCH                                (CLK_MFCMSCL_BASE + 2)
> > +#define GATE_MFC_QCH                         (CLK_MFCMSCL_BASE + 3)
> > +#define GATE_MFCMSCL_CMU_MFCMSCL_QCH         (CLK_MFCMSCL_BASE + 4)
> > +#define GATE_SYSMMU_MFCMSCL_QCH                      (CLK_MFCMSCL_BASE + 5)
> > +#define GATE_CMU_MIF_CMUREF_QCH                      (CLK_MFCMSCL_BASE + 6)
> > +#define GATE_DMC_QCH                         (CLK_MFCMSCL_BASE + 7)
> > +#define GATE_MIF_CMU_MIF_QCH                 (CLK_MFCMSCL_BASE + 8)
> > +#define GATE_CMU_MIF1_CMU_REF_QCH            (CLK_MFCMSCL_BASE + 9)
> > +#define GATE_DMC1_QCH                                (CLK_MFCMSCL_BASE + 10)
> > +#define GATE_MIF1_CMU_MIF1_QCH                       (CLK_MFCMSCL_BASE + 11)
> > +#define GATE_MODEM_CMU_MODEM_QCH             (CLK_MFCMSCL_BASE + 12)
> > +#define DOUT_CLK_MFCMSCL_BUSP                        (CLK_MFCMSCL_BASE + 13)
> > +#define MFCMSCL_MFC                          (CLK_MFCMSCL_BASE + 14)
> > +#define MFCMSCL_M2M                          (CLK_MFCMSCL_BASE + 15)
> > +#define MFCMSCL_MCSC                         (CLK_MFCMSCL_BASE + 16)
> > +#define MFCMSCL_JPEG                         (CLK_MFCMSCL_BASE + 17)
> > +#define UMUX_CLKCMU_MFCMSCL_MFC                      (CLK_MFCMSCL_BASE + 18)
> > +#define UMUX_CLKCMU_MFCMSCL_M2M                      (CLK_MFCMSCL_BASE + 19)
> > +#define UMUX_CLKCMU_MFCMSCL_MCSC             (CLK_MFCMSCL_BASE + 20)
> > +#define UMUX_CLKCMU_MFCMSCL_JPEG             (CLK_MFCMSCL_BASE + 21)
> > +
> > +#define CLK_PERI_BASE                                (550)
> > +#define UMUX_CLKCMU_PERI_BUS_USER            (CLK_PERI_BASE + 0)
> > +#define UMUX_CLKCMU_PERI_UART_USER           (CLK_PERI_BASE + 1)
> > +#define UMUX_CLKCMU_PERI_HSI2C_USER          (CLK_PERI_BASE + 2)
> > +#define UMUX_CLKCMU_PERI_SPI_USER            (CLK_PERI_BASE + 3)
> > +#define GATE_BUSIF_TMU_QCH                   (CLK_PERI_BASE + 4)
> > +#define GATE_GPIO_PERI_QCH                   (CLK_PERI_BASE + 5)
> > +#define GATE_HSI2C_0_QCH                     (CLK_PERI_BASE + 6)
> > +#define GATE_HSI2C_1_QCH                     (CLK_PERI_BASE + 7)
> > +#define GATE_HSI2C_2_QCH                     (CLK_PERI_BASE + 8)
> > +#define GATE_I2C_0_QCH                               (CLK_PERI_BASE + 9)
> > +#define GATE_I2C_1_QCH                               (CLK_PERI_BASE + 10)
> > +#define GATE_I2C_2_QCH                               (CLK_PERI_BASE + 11)
> > +#define GATE_I2C_3_QCH                               (CLK_PERI_BASE + 12)
> > +#define GATE_I2C_4_QCH                               (CLK_PERI_BASE + 13)
> > +#define GATE_I2C_5_QCH                               (CLK_PERI_BASE + 14)
> > +#define GATE_I2C_6_QCH                               (CLK_PERI_BASE + 15)
> > +#define GATE_MCT_QCH                         (CLK_PERI_BASE + 16)
> > +#define GATE_OTP_CON_TOP_QCH                 (CLK_PERI_BASE + 17)
> > +#define GATE_PWM_MOTOR_QCH                   (CLK_PERI_BASE + 18)
> > +#define GATE_SPI_0_QCH                               (CLK_PERI_BASE + 19)
> > +#define GATE_UART_QCH                                (CLK_PERI_BASE + 20)
> > +#define GATE_WDT_0_QCH                               (CLK_PERI_BASE + 21)
> > +#define GATE_WDT_1_QCH                               (CLK_PERI_BASE + 22)
> > +#define DOUT_CLK_PERI_SPI_0                  (CLK_PERI_BASE + 23)
> > +#define DOUT_CLK_PERI_HSI2C_0                        (CLK_PERI_BASE + 24)
> > +#define DOUT_CLK_PERI_HSI2C_1                        (CLK_PERI_BASE + 25)
> > +#define DOUT_CLK_PERI_HSI2C_2                        (CLK_PERI_BASE + 26)
> > +#define DOUT_I2C_0                           (CLK_PERI_BASE + 27)
> > +#define DOUT_I2C_1                           (CLK_PERI_BASE + 28)
> > +#define DOUT_I2C_2                           (CLK_PERI_BASE + 29)
> > +#define DOUT_I2C_3                           (CLK_PERI_BASE + 30)
> > +#define DOUT_I2C_4                           (CLK_PERI_BASE + 31)
> > +#define DOUT_I2C_5                           (CLK_PERI_BASE + 32)
> > +#define DOUT_I2C_6                           (CLK_PERI_BASE + 33)
> > +#define DOUT_UART                            (CLK_PERI_BASE + 34)
> > +
> > +#define CLK_CLKOUT_BASE                              (700)
> > +#define OSC_NFC                                      (CLK_CLKOUT_BASE + 0)
> > +#define OSC_AUD                                      (CLK_CLKOUT_BASE + 1)
>
> What are these?
>
> > +
> > +/* Must be greater than maximal clock ID */
>
> Why?
>
> > +#define CLK_NR_CLKS                          (1125 + 1)
> > +
> > +#endif /* _DT_BINDINGS_CLOCK_EXYNOS_850_H */
> >
>
>
> Best regards,
> Krzysztof


From arnd at kernel.org  Tue Aug  3 04:58:47 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 3 Aug 2021 13:58:47 +0200
Subject: [PATCH] ARM: ep93xx: remove MaverickCrunch support
In-Reply-To: <CAL4-wQpKLtSj0xfNUXXLhbtN1wC051jpRneAuLYOi1riZfiinw@mail.gmail.com>
References: <20210802141245.1146772-1-arnd@kernel.org>
 <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>
 <CAL4-wQpKLtSj0xfNUXXLhbtN1wC051jpRneAuLYOi1riZfiinw@mail.gmail.com>
Message-ID: <CAK8P3a2z_xxpz9hAYoBx5=bS81V=TkjEU6WHNhPi1UhQ3UScfw@mail.gmail.com>

On Tue, Aug 3, 2021 at 1:41 PM Martin Guy <martinwguy at gmail.com> wrote:
>
> I forward opinion from people currently producing and supporting EP93XX boards:

Thanks a lot for bringing them in. I definitely don't want to remove support for
something that is actively being used, and we don't have to merge the patch
if they currently rely on MaverickCrunch on older platforms.

It does sound however like Jerome's customers are using a normal (softfloat)
Linus distro on EP93xx, rather than one using the original MaverickCrunch
FPU instructions. There are no plans to discontinue EP93xx support, there
is actually a good amount of recent work going into updating the platform.

Jerome, please let me know if I understood you correctly here. If your
customers do rely on MaverickCrunch support in user space, I would
leave that in the kernel for as long as ep93xx itself is supported, and instead
require building support with the GNU assembler to avoid having to
add support to the clang integrated assembler. If you don't know of anyone
using MaverickCrunch, I would go ahead with my patch to remove kernel
support.

      Arnd

> From: Technologic Systems Support Team <support at embeddedarm.com>
> To: martinwguy at gmail.com
> Cc: jerome.oufella at savoirfairelinux.com
>
> > I expect our customers would care if support was dropped.
> > Unfortunately I don't know to what extent.  I'd like to bring
> > Jerome Oufella of Savoir Faire Linux into the conversation here,
> > as he runs the software company who most of our customers
> > contract through when they need a modern Linux kernel running
> > on one of our Cirrus Logic EP93XX series single board computers.
> > I expect his opinion will be more valuable than mine.
> >
> > Good morning Jerome,
> >
> > A member of the Linux Kernel Development community reached out
> > to us this morning letting us know the community has suggested
> > dropping support for the MavericCrunch FPU on the EP9302 processor.
> > Would this impact any of the development your team has been doing
> > for some of our mutual customers?
>
> From: Jerome Oufella<jerome.oufella at savoirfairelinux.com>
> > I am aware of a few companies who rely on variants of the TS-7250
> > running not-too-old LTS releases (4.19, 5.4) to cope with their patch policies.
> >
> > With Linux 5.10 being the next "Super LTS", this presumably brings its
> > support lifespan until about 2030, which (I believe) they would be
> > comfortable with considering the age of the platform.
> >
> > Jerome Oufella
> > Vice-President, Technologies
> > www.savoirfairelinux.com


From bot at kernelci.org  Tue Aug  3 05:03:37 2021
From: bot at kernelci.org (kernelci.org bot)
Date: Tue, 03 Aug 2021 05:03:37 -0700 (PDT)
Subject: arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 2 errors,
 1 warning (v5.14-rc4-6-gbee0cf777c04)
Message-ID: <61093099.1c69fb81.43242.7343@mx.google.com>

arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 2 errors, 1 warning (v5.14-rc4-6-gbee0cf777c04)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v5.14-rc4-6-gbee0cf777c04/

Tree: arm64
Branch: for-kernelci
Git Describe: v5.14-rc4-6-gbee0cf777c04
Git Commit: bee0cf777c04b3681789589403c009f6bcd055cd
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Build Failure Detected:

arm64:
    allmodconfig: (gcc-8) FAIL

Errors and Warnings Detected:

arm64:
    allmodconfig (gcc-8): 2 errors, 1 warning

Errors summary:

    1    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1864? declared with attribute error: FIELD_PREP: value too large for the field
    1    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1857? declared with attribute error: FIELD_PREP: value too large for the field

Warnings summary:

    1    kernel/trace/trace_osnoise.c:1461:8: warning: ?main? is usually a function [-Wmain]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
allmodconfig (arm64, gcc-8) ? FAIL, 2 errors, 1 warning, 0 section mismatches

Errors:
    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1857? declared with attribute error: FIELD_PREP: value too large for the field
    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1864? declared with attribute error: FIELD_PREP: value too large for the field

Warnings:
    kernel/trace/trace_osnoise.c:1461:8: warning: ?main? is usually a function [-Wmain]

--------------------------------------------------------------------------------
defconfig (arm64, gcc-8) ? PASS, 0 errors, 0 warnings, 0 section mismatches

---
For more info write to <info at kernelci.org>


From patrice.chotard at foss.st.com  Tue Aug  3 05:03:36 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:03:36 +0200
Subject: [PATCH v3 01/13] ARM: dts: sti: update flexgen compatible within
 stih418-clock
In-Reply-To: <20210331204228.26107-2-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-2-avolmat@me.com>
Message-ID: <1d5c9ee4-a025-8520-0ab1-4b7f2f80bcc4@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> With the introduction of new flexgen compatible within the clk-flexgen
> driver, remove the clock-output-names entry from the flexgen nodes
> and set the new proper compatible corresponding.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih418-clock.dtsi | 96 ++--------------------------
>  1 file changed, 5 insertions(+), 91 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
> index 8fa092462102..35d12979cdf4 100644
> --- a/arch/arm/boot/dts/stih418-clock.dtsi
> +++ b/arch/arm/boot/dts/stih418-clock.dtsi
> @@ -83,15 +83,12 @@
>  			};
>  
>  			clk_s_a0_flexgen: clk-s-a0-flexgen {
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih410-a0";
>  
>  				#clock-cells = <1>;
>  
>  				clocks = <&clk_s_a0_pll 0>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-ic-lmi0",
> -						     "clk-ic-lmi1";
>  			};
>  		};
>  
> @@ -132,7 +129,7 @@
>  
>  			clk_s_c0_flexgen: clk-s-c0-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih418-c0";
>  
>  				clocks = <&clk_s_c0_pll0 0>,
>  					 <&clk_s_c0_pll1 0>,
> @@ -142,49 +139,6 @@
>  					 <&clk_s_c0_quadfs 3>,
>  					 <&clk_sysin>;
>  
> -				clock-output-names = "clk-icn-gpu",
> -						     "clk-fdma",
> -						     "clk-nand",
> -						     "clk-hva",
> -						     "clk-proc-stfe",
> -						     "clk-tp",
> -						     "clk-rx-icn-dmu",
> -						     "clk-rx-icn-hva",
> -						     "clk-icn-cpu",
> -						     "clk-tx-icn-dmu",
> -						     "clk-mmc-0",
> -						     "clk-mmc-1",
> -						     "clk-jpegdec",
> -						     "clk-icn-reg",
> -						     "clk-proc-bdisp-0",
> -						     "clk-proc-bdisp-1",
> -						     "clk-pp-dmu",
> -						     "clk-vid-dmu",
> -						     "clk-dss-lpc",
> -						     "clk-st231-aud-0",
> -						     "clk-st231-gp-1",
> -						     "clk-st231-dmu",
> -						     "clk-icn-lmi",
> -						     "clk-tx-icn-1",
> -						     "clk-icn-sbc",
> -						     "clk-stfe-frc2",
> -						     "clk-eth-phyref",
> -						     "clk-eth-ref-phyclk",
> -						     "clk-flash-promip",
> -						     "clk-main-disp",
> -						     "clk-aux-disp",
> -						     "clk-compo-dvp",
> -						     "clk-tx-icn-hades",
> -						     "clk-rx-icn-hades",
> -						     "clk-icn-reg-16",
> -						     "clk-pp-hevc",
> -						     "clk-clust-hevc",
> -						     "clk-hwpe-hevc",
> -						     "clk-fc-hevc",
> -						     "clk-proc-mixer",
> -						     "clk-proc-sc",
> -						     "clk-avsp-hevc";
> -
>  				/*
>  				 * ARM Peripheral clock for timers
>  				 */
> @@ -221,20 +175,13 @@
>  
>  			clk_s_d0_flexgen: clk-s-d0-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen-audio", "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih410-d0";
>  
>  				clocks = <&clk_s_d0_quadfs 0>,
>  					 <&clk_s_d0_quadfs 1>,
>  					 <&clk_s_d0_quadfs 2>,
>  					 <&clk_s_d0_quadfs 3>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-pcm-0",
> -						     "clk-pcm-1",
> -						     "clk-pcm-2",
> -						     "clk-spdiff",
> -						     "clk-pcmr10-master",
> -						     "clk-usb2-phy";
>  			};
>  		};
>  
> @@ -257,7 +204,7 @@
>  
>  			clk_s_d2_flexgen: clk-s-d2-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen-video", "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih418-d2";
>  
>  				clocks = <&clk_s_d2_quadfs 0>,
>  					 <&clk_s_d2_quadfs 1>,
> @@ -266,30 +213,6 @@
>  					 <&clk_sysin>,
>  					 <&clk_sysin>,
>  					 <&clk_tmdsout_hdmi>;
> -
> -				clock-output-names = "clk-pix-main-disp",
> -						     "",
> -						     "",
> -						     "",
> -						     "",
> -						     "clk-tmds-hdmi-div2",
> -						     "clk-pix-aux-disp",
> -						     "clk-denc",
> -						     "clk-pix-hddac",
> -						     "clk-hddac",
> -						     "clk-sddac",
> -						     "clk-pix-dvo",
> -						     "clk-dvo",
> -						     "clk-pix-hdmi",
> -						     "clk-tmds-hdmi",
> -						     "clk-ref-hdmiphy",
> -						     "", "", "", "", "",
> -						     "", "", "", "", "",
> -						     "", "", "", "", "",
> -						     "", "", "", "", "",
> -						     "", "", "", "", "",
> -						     "", "", "", "", "",
> -						     "", "clk-vp9";
>  			};
>  		};
>  
> @@ -312,22 +235,13 @@
>  
>  			clk_s_d3_flexgen: clk-s-d3-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih407-d3";
>  
>  				clocks = <&clk_s_d3_quadfs 0>,
>  					 <&clk_s_d3_quadfs 1>,
>  					 <&clk_s_d3_quadfs 2>,
>  					 <&clk_s_d3_quadfs 3>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-stfe-frc1",
> -						     "clk-tsout-0",
> -						     "clk-tsout-1",
> -						     "clk-mchi",
> -						     "clk-vsens-compo",
> -						     "clk-frc1-remote",
> -						     "clk-lpc-0",
> -						     "clk-lpc-1";
>  			};
>  		};
>  	};
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From patrice.chotard at foss.st.com  Tue Aug  3 05:03:59 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:03:59 +0200
Subject: [PATCH v3 02/13] ARM: dts: sti: update flexgen compatible within
 stih407-clock
In-Reply-To: <20210331204228.26107-3-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-3-avolmat@me.com>
Message-ID: <9ae5a54f-7367-cdac-7d5d-fc49f8d6b0e5@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> With the introduction of new flexgen compatible within the clk-flexgen
> driver, remove the clock-output-names entry from the flexgen nodes
> and set the new proper compatible corresponding.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih407-clock.dtsi | 85 ++--------------------------
>  1 file changed, 6 insertions(+), 79 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
> index 1ab40db7c91a..ecd568777e5f 100644
> --- a/arch/arm/boot/dts/stih407-clock.dtsi
> +++ b/arch/arm/boot/dts/stih407-clock.dtsi
> @@ -83,15 +83,12 @@
>  			};
>  
>  			clk_s_a0_flexgen: clk-s-a0-flexgen {
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih407-a0";
>  
>  				#clock-cells = <1>;
>  
>  				clocks = <&clk_s_a0_pll 0>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-ic-lmi0";
> -				clock-critical = <CLK_IC_LMI0>;
>  			};
>  		};
>  
> @@ -134,7 +131,7 @@
>  
>  			clk_s_c0_flexgen: clk-s-c0-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih407-c0";
>  
>  				clocks = <&clk_s_c0_pll0 0>,
>  					 <&clk_s_c0_pll1 0>,
> @@ -144,45 +141,6 @@
>  					 <&clk_s_c0_quadfs 3>,
>  					 <&clk_sysin>;
>  
> -				clock-output-names = "clk-icn-gpu",
> -						     "clk-fdma",
> -						     "clk-nand",
> -						     "clk-hva",
> -						     "clk-proc-stfe",
> -						     "clk-proc-tp",
> -						     "clk-rx-icn-dmu",
> -						     "clk-rx-icn-hva",
> -						     "clk-icn-cpu",
> -						     "clk-tx-icn-dmu",
> -						     "clk-mmc-0",
> -						     "clk-mmc-1",
> -						     "clk-jpegdec",
> -						     "clk-ext2fa9",
> -						     "clk-ic-bdisp-0",
> -						     "clk-ic-bdisp-1",
> -						     "clk-pp-dmu",
> -						     "clk-vid-dmu",
> -						     "clk-dss-lpc",
> -						     "clk-st231-aud-0",
> -						     "clk-st231-gp-1",
> -						     "clk-st231-dmu",
> -						     "clk-icn-lmi",
> -						     "clk-tx-icn-disp-1",
> -						     "clk-icn-sbc",
> -						     "clk-stfe-frc2",
> -						     "clk-eth-phy",
> -						     "clk-eth-ref-phyclk",
> -						     "clk-flash-promip",
> -						     "clk-main-disp",
> -						     "clk-aux-disp",
> -						     "clk-compo-dvp";
> -				clock-critical = <CLK_PROC_STFE>,
> -						 <CLK_ICN_CPU>,
> -						 <CLK_TX_ICN_DMU>,
> -						 <CLK_EXT2F_A9>,
> -						 <CLK_ICN_LMI>,
> -						 <CLK_ICN_SBC>;
> -
>  				/*
>  				 * ARM Peripheral clock for timers
>  				 */
> @@ -219,18 +177,13 @@
>  
>  			clk_s_d0_flexgen: clk-s-d0-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen-audio", "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih407-d0";
>  
>  				clocks = <&clk_s_d0_quadfs 0>,
>  					 <&clk_s_d0_quadfs 1>,
>  					 <&clk_s_d0_quadfs 2>,
>  					 <&clk_s_d0_quadfs 3>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-pcm-0",
> -						     "clk-pcm-1",
> -						     "clk-pcm-2",
> -						     "clk-spdiff";
>  			};
>  		};
>  
> @@ -253,7 +206,7 @@
>  
>  			clk_s_d2_flexgen: clk-s-d2-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen-video", "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih407-d2";
>  
>  				clocks = <&clk_s_d2_quadfs 0>,
>  					 <&clk_s_d2_quadfs 1>,
> @@ -262,24 +215,7 @@
>  					 <&clk_sysin>,
>  					 <&clk_sysin>,
>  					 <&clk_tmdsout_hdmi>;
> -
> -				clock-output-names = "clk-pix-main-disp",
> -						     "clk-pix-pip",
> -						     "clk-pix-gdp1",
> -						     "clk-pix-gdp2",
> -						     "clk-pix-gdp3",
> -						     "clk-pix-gdp4",
> -						     "clk-pix-aux-disp",
> -						     "clk-denc",
> -						     "clk-pix-hddac",
> -						     "clk-hddac",
> -						     "clk-sddac",
> -						     "clk-pix-dvo",
> -						     "clk-dvo",
> -						     "clk-pix-hdmi",
> -						     "clk-tmds-hdmi",
> -						     "clk-ref-hdmiphy";
> -						     };
> +			};
>  		};
>  
>  		clk_s_d3_quadfs: clk-s-d3-quadfs at 9107000 {
> @@ -301,22 +237,13 @@
>  
>  			clk_s_d3_flexgen: clk-s-d3-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih407-d3";
>  
>  				clocks = <&clk_s_d3_quadfs 0>,
>  					 <&clk_s_d3_quadfs 1>,
>  					 <&clk_s_d3_quadfs 2>,
>  					 <&clk_s_d3_quadfs 3>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-stfe-frc1",
> -						     "clk-tsout-0",
> -						     "clk-tsout-1",
> -						     "clk-mchi",
> -						     "clk-vsens-compo",
> -						     "clk-frc1-remote",
> -						     "clk-lpc-0",
> -						     "clk-lpc-1";
>  			};
>  		};
>  	};
> 

Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From patrice.chotard at foss.st.com  Tue Aug  3 05:04:24 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:04:24 +0200
Subject: [PATCH v3 03/13] ARM: dts: sti: update flexgen compatible within
 stih410-clock
In-Reply-To: <20210331204228.26107-4-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-4-avolmat@me.com>
Message-ID: <5c50c236-7bc6-5307-fd9a-a03b3f3512b1@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> With the introduction of new flexgen compatible within the clk-flexgen
> driver, remove the clock-output-names entry from the flexgen nodes
> and set the new proper compatible corresponding.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih410-clock.dtsi | 95 ++--------------------------
>  1 file changed, 6 insertions(+), 89 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
> index 81a8c25d7ba5..04b0d7080353 100644
> --- a/arch/arm/boot/dts/stih410-clock.dtsi
> +++ b/arch/arm/boot/dts/stih410-clock.dtsi
> @@ -83,16 +83,12 @@
>  			};
>  
>  			clk_s_a0_flexgen: clk-s-a0-flexgen {
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih410-a0";
>  
>  				#clock-cells = <1>;
>  
>  				clocks = <&clk_s_a0_pll 0>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-ic-lmi0",
> -						     "clk-ic-lmi1";
> -				clock-critical = <CLK_IC_LMI0>;
>  			};
>  		};
>  
> @@ -135,7 +131,7 @@
>  
>  			clk_s_c0_flexgen: clk-s-c0-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih410-c0";
>  
>  				clocks = <&clk_s_c0_pll0 0>,
>  					 <&clk_s_c0_pll1 0>,
> @@ -145,52 +141,6 @@
>  					 <&clk_s_c0_quadfs 3>,
>  					 <&clk_sysin>;
>  
> -				clock-output-names = "clk-icn-gpu",
> -						     "clk-fdma",
> -						     "clk-nand",
> -						     "clk-hva",
> -						     "clk-proc-stfe",
> -						     "clk-proc-tp",
> -						     "clk-rx-icn-dmu",
> -						     "clk-rx-icn-hva",
> -						     "clk-icn-cpu",
> -						     "clk-tx-icn-dmu",
> -						     "clk-mmc-0",
> -						     "clk-mmc-1",
> -						     "clk-jpegdec",
> -						     "clk-ext2fa9",
> -						     "clk-ic-bdisp-0",
> -						     "clk-ic-bdisp-1",
> -						     "clk-pp-dmu",
> -						     "clk-vid-dmu",
> -						     "clk-dss-lpc",
> -						     "clk-st231-aud-0",
> -						     "clk-st231-gp-1",
> -						     "clk-st231-dmu",
> -						     "clk-icn-lmi",
> -						     "clk-tx-icn-disp-1",
> -						     "clk-icn-sbc",
> -						     "clk-stfe-frc2",
> -						     "clk-eth-phy",
> -						     "clk-eth-ref-phyclk",
> -						     "clk-flash-promip",
> -						     "clk-main-disp",
> -						     "clk-aux-disp",
> -						     "clk-compo-dvp",
> -						     "clk-tx-icn-hades",
> -						     "clk-rx-icn-hades",
> -						     "clk-icn-reg-16",
> -						     "clk-pp-hades",
> -						     "clk-clust-hades",
> -						     "clk-hwpe-hades",
> -						     "clk-fc-hades";
> -				clock-critical = <CLK_PROC_STFE>,
> -						 <CLK_ICN_CPU>,
> -						 <CLK_TX_ICN_DMU>,
> -						 <CLK_EXT2F_A9>,
> -						 <CLK_ICN_LMI>,
> -						 <CLK_ICN_SBC>;
> -
>  				/*
>  				 * ARM Peripheral clock for timers
>  				 */
> @@ -227,20 +177,13 @@
>  
>  			clk_s_d0_flexgen: clk-s-d0-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen-audio", "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih410-d0";
>  
>  				clocks = <&clk_s_d0_quadfs 0>,
>  					 <&clk_s_d0_quadfs 1>,
>  					 <&clk_s_d0_quadfs 2>,
>  					 <&clk_s_d0_quadfs 3>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-pcm-0",
> -						     "clk-pcm-1",
> -						     "clk-pcm-2",
> -						     "clk-spdiff",
> -						     "clk-pcmr10-master",
> -						     "clk-usb2-phy";
>  			};
>  		};
>  
> @@ -263,7 +206,7 @@
>  
>  			clk_s_d2_flexgen: clk-s-d2-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen-video", "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih407-d2";
>  
>  				clocks = <&clk_s_d2_quadfs 0>,
>  					 <&clk_s_d2_quadfs 1>,
> @@ -272,24 +215,7 @@
>  					 <&clk_sysin>,
>  					 <&clk_sysin>,
>  					 <&clk_tmdsout_hdmi>;
> -
> -				clock-output-names = "clk-pix-main-disp",
> -						     "clk-pix-pip",
> -						     "clk-pix-gdp1",
> -						     "clk-pix-gdp2",
> -						     "clk-pix-gdp3",
> -						     "clk-pix-gdp4",
> -						     "clk-pix-aux-disp",
> -						     "clk-denc",
> -						     "clk-pix-hddac",
> -						     "clk-hddac",
> -						     "clk-sddac",
> -						     "clk-pix-dvo",
> -						     "clk-dvo",
> -						     "clk-pix-hdmi",
> -						     "clk-tmds-hdmi",
> -						     "clk-ref-hdmiphy";
> -						     };
> +			};
>  		};
>  
>  		clk_s_d3_quadfs: clk-s-d3-quadfs at 9107000 {
> @@ -311,22 +237,13 @@
>  
>  			clk_s_d3_flexgen: clk-s-d3-flexgen {
>  				#clock-cells = <1>;
> -				compatible = "st,flexgen";
> +				compatible = "st,flexgen", "st,flexgen-stih407-d3";
>  
>  				clocks = <&clk_s_d3_quadfs 0>,
>  					 <&clk_s_d3_quadfs 1>,
>  					 <&clk_s_d3_quadfs 2>,
>  					 <&clk_s_d3_quadfs 3>,
>  					 <&clk_sysin>;
> -
> -				clock-output-names = "clk-stfe-frc1",
> -						     "clk-tsout-0",
> -						     "clk-tsout-1",
> -						     "clk-mchi",
> -						     "clk-vsens-compo",
> -						     "clk-frc1-remote",
> -						     "clk-lpc-0",
> -						     "clk-lpc-1";
>  			};
>  		};
>  	};
> 

Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From patrice.chotard at foss.st.com  Tue Aug  3 05:05:17 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:05:17 +0200
Subject: [PATCH v3 05/13] ARM: dts: sti: update clkgen-pll entries in
 stih410-clock
In-Reply-To: <20210331204228.26107-6-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-6-avolmat@me.com>
Message-ID: <95e6d88a-9447-b268-c321-4c978a241fcd@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The clkgen-pll driver now embed the clock names (assuming the
> right compatible is used). Remove all clock-output-names property
> and update when necessary the compatible.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih410-clock.dtsi | 16 +++-------------
>  1 file changed, 3 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
> index 04b0d7080353..3aeabdd6e305 100644
> --- a/arch/arm/boot/dts/stih410-clock.dtsi
> +++ b/arch/arm/boot/dts/stih410-clock.dtsi
> @@ -39,8 +39,6 @@
>  				compatible = "st,stih407-clkgen-plla9";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clockgen-a9-pll-odf";
>  			};
>  		};
>  
> @@ -74,12 +72,9 @@
>  
>  			clk_s_a0_pll: clk-s-a0-pll {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll0";
> +				compatible = "st,clkgen-pll0-a0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-a0-pll-ofd-0";
> -				clock-critical = <0>; /* clk-s-a0-pll-ofd-0 */
>  			};
>  
>  			clk_s_a0_flexgen: clk-s-a0-flexgen {
> @@ -112,21 +107,16 @@
>  
>  			clk_s_c0_pll0: clk-s-c0-pll0 {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll0";
> +				compatible = "st,clkgen-pll0-c0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-c0-pll0-odf-0";
> -				clock-critical = <0>; /* clk-s-c0-pll0-odf-0 */
>  			};
>  
>  			clk_s_c0_pll1: clk-s-c0-pll1 {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll1";
> +				compatible = "st,clkgen-pll1-c0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-c0-pll1-odf-0";
>  			};
>  
>  			clk_s_c0_flexgen: clk-s-c0-flexgen {
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From patrice.chotard at foss.st.com  Tue Aug  3 05:04:54 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:04:54 +0200
Subject: [PATCH v3 04/13] ARM: dts: sti: update clkgen-pll entries in
 stih407-clock
In-Reply-To: <20210331204228.26107-5-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-5-avolmat@me.com>
Message-ID: <99fc7f03-ffe0-626c-057b-8e8a043c5ae7@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The clkgen-pll driver now embed the clock names (assuming the
> right compatible is used). Remove all clock-output-names property
> and update when necessary the compatible.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih407-clock.dtsi | 16 +++-------------
>  1 file changed, 3 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
> index ecd568777e5f..2603226a6ca8 100644
> --- a/arch/arm/boot/dts/stih407-clock.dtsi
> +++ b/arch/arm/boot/dts/stih407-clock.dtsi
> @@ -36,8 +36,6 @@
>  				compatible = "st,stih407-clkgen-plla9";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clockgen-a9-pll-odf";
>  			};
>  		};
>  
> @@ -74,12 +72,9 @@
>  
>  			clk_s_a0_pll: clk-s-a0-pll {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll0";
> +				compatible = "st,clkgen-pll0-a0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-a0-pll-ofd-0";
> -				clock-critical = <0>; /* clk-s-a0-pll-ofd-0 */
>  			};
>  
>  			clk_s_a0_flexgen: clk-s-a0-flexgen {
> @@ -112,21 +107,16 @@
>  
>  			clk_s_c0_pll0: clk-s-c0-pll0 {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll0";
> +				compatible = "st,clkgen-pll0-c0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-c0-pll0-odf-0";
> -				clock-critical = <0>; /* clk-s-c0-pll0-odf-0 */
>  			};
>  
>  			clk_s_c0_pll1: clk-s-c0-pll1 {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll1";
> +				compatible = "st,clkgen-pll1-c0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-c0-pll1-odf-0";
>  			};
>  
>  			clk_s_c0_flexgen: clk-s-c0-flexgen {
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From patrice.chotard at foss.st.com  Tue Aug  3 05:05:30 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:05:30 +0200
Subject: [PATCH v3 06/13] ARM: dts: sti: update clkgen-pll entries in
 stih418-clock
In-Reply-To: <20210331204228.26107-7-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-7-avolmat@me.com>
Message-ID: <8793dc22-93dd-eee0-3f57-412dcf8c579c@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The clkgen-pll driver now embed the clock names (assuming the
> right compatible is used). Remove all clock-output-names property
> and update when necessary the compatible.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih418-clock.dtsi | 14 +++-----------
>  1 file changed, 3 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
> index 35d12979cdf4..d628e656458d 100644
> --- a/arch/arm/boot/dts/stih418-clock.dtsi
> +++ b/arch/arm/boot/dts/stih418-clock.dtsi
> @@ -39,8 +39,6 @@
>  				compatible = "st,stih418-clkgen-plla9";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clockgen-a9-pll-odf";
>  			};
>  		};
>  
> @@ -75,11 +73,9 @@
>  
>  			clk_s_a0_pll: clk-s-a0-pll {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll0";
> +				compatible = "st,clkgen-pll0-a0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-a0-pll-ofd-0";
>  			};
>  
>  			clk_s_a0_flexgen: clk-s-a0-flexgen {
> @@ -111,20 +107,16 @@
>  
>  			clk_s_c0_pll0: clk-s-c0-pll0 {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll0";
> +				compatible = "st,clkgen-pll0-c0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-c0-pll0-odf-0";
>  			};
>  
>  			clk_s_c0_pll1: clk-s-c0-pll1 {
>  				#clock-cells = <1>;
> -				compatible = "st,clkgen-pll1";
> +				compatible = "st,clkgen-pll1-c0";
>  
>  				clocks = <&clk_sysin>;
> -
> -				clock-output-names = "clk-s-c0-pll1-odf-0";
>  			};
>  
>  			clk_s_c0_flexgen: clk-s-c0-flexgen {
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From vilhelm.gray at gmail.com  Tue Aug  3 05:06:10 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:10 +0900
Subject: [PATCH v14 00/17] Introduce the Counter character device interface
Message-ID: <cover.1627990337.git.vilhelm.gray@gmail.com>

Changes in v14:
 - Initialize counter_fops owner to THIS_MODULE
 - Implement ops_exist_lock to prevent counter->ops use during removal
 - Set counter->ops to NULL on counter_unregister to indicate removal;
   chrdev callbacks return -ENODEV if driver is removed
 - Refactor counter_fops read, poll, ioctl, and release callbacks to
   utilize ops_exist_lock where needed and to check counter->ops
 - Wake up sleeping chrdev read() on counter_unregister
 - Move chrdev_lock introduce to the "counter: Add character device
   interface" patch; this is a more appropriate place to introduce this
   lock because the chrdev code is intended from the get-go to only
   allow for a single open() at a time

For convenience, this patchset is also available on my personal git
repo: https://gitlab.com/vilhelmgray/iio/-/tree/counter_chrdev_v14

The patches preceding "counter: Internalize sysfs interface code" are
primarily cleanup and fixes that can be picked up and applied now to the
IIO tree if so desired. The "counter: Internalize sysfs interface code"
patch as well may be considered for pickup because it is relatively safe
and makes no changes to the userspace interface.

To summarize the main points of this patchset: there are no changes to
the existing Counter sysfs userspace interface; a Counter character
device interface is introduced that allows Counter events and associated
data to be read() by userspace; the events_configure() and
watch_validate() driver callbacks are introduced to support Counter
events; and IRQ support is added to the 104-QUAD-8 driver, serving as an
example of how to support the new Counter events functionality.

William Breathitt Gray (17):
  counter: 104-quad-8: Return error when invalid mode during
    ceiling_write
  counter: Return error code on invalid modes
  counter: Standardize to ERANGE for limit exceeded errors
  counter: Rename counter_signal_value to counter_signal_level
  counter: Rename counter_count_function to counter_function
  counter: Internalize sysfs interface code
  counter: Update counter.h comments to reflect sysfs internalization
  docs: counter: Update to reflect sysfs internalization
  counter: Move counter enums to uapi header
  counter: Add character device interface
  docs: counter: Document character device interface
  tools/counter: Create Counter tools
  counter: Implement signalZ_action_component_id sysfs attribute
  counter: Implement *_component_id sysfs attributes
  counter: Implement events_queue_size sysfs attribute
  counter: 104-quad-8: Replace mutex with spinlock
  counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8

 Documentation/ABI/testing/sysfs-bus-counter   |   38 +-
 Documentation/driver-api/generic-counter.rst  |  358 +++-
 .../userspace-api/ioctl/ioctl-number.rst      |    1 +
 MAINTAINERS                                   |    3 +-
 drivers/counter/104-quad-8.c                  |  728 ++++----
 drivers/counter/Kconfig                       |    6 +-
 drivers/counter/Makefile                      |    1 +
 drivers/counter/counter-chrdev.c              |  553 ++++++
 drivers/counter/counter-chrdev.h              |   14 +
 drivers/counter/counter-core.c                |  192 +++
 drivers/counter/counter-sysfs.c               |  962 +++++++++++
 drivers/counter/counter-sysfs.h               |   13 +
 drivers/counter/counter.c                     | 1496 -----------------
 drivers/counter/ftm-quaddec.c                 |   59 +-
 drivers/counter/intel-qep.c                   |  150 +-
 drivers/counter/interrupt-cnt.c               |   73 +-
 drivers/counter/microchip-tcb-capture.c       |  103 +-
 drivers/counter/stm32-lptimer-cnt.c           |  211 ++-
 drivers/counter/stm32-timer-cnt.c             |  147 +-
 drivers/counter/ti-eqep.c                     |  205 ++-
 include/linux/counter.h                       |  719 ++++----
 include/linux/counter_enum.h                  |   45 -
 include/uapi/linux/counter.h                  |  154 ++
 tools/Makefile                                |   13 +-
 tools/counter/Build                           |    1 +
 tools/counter/Makefile                        |   53 +
 tools/counter/counter_example.c               |   93 +
 27 files changed, 3623 insertions(+), 2768 deletions(-)
 create mode 100644 drivers/counter/counter-chrdev.c
 create mode 100644 drivers/counter/counter-chrdev.h
 create mode 100644 drivers/counter/counter-core.c
 create mode 100644 drivers/counter/counter-sysfs.c
 create mode 100644 drivers/counter/counter-sysfs.h
 delete mode 100644 drivers/counter/counter.c
 delete mode 100644 include/linux/counter_enum.h
 create mode 100644 include/uapi/linux/counter.h
 create mode 100644 tools/counter/Build
 create mode 100644 tools/counter/Makefile
 create mode 100644 tools/counter/counter_example.c

-- 
2.32.0



From joey.gouly at arm.com  Tue Aug  3 05:06:10 2021
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 3 Aug 2021 13:06:10 +0100
Subject: [PATCH 3/4] arm64: entry: move bulk of ret_to_user to C
In-Reply-To: <20210802140733.52716-4-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
 <20210802140733.52716-4-mark.rutland@arm.com>
Message-ID: <20210803120610.GB52119@e124191.cambridge.arm.com>

On Mon, Aug 02, 2021 at 03:07:32PM +0100, Mark Rutland wrote:
> In `ret_to_user` we perform some conditional work depending on the
> thread flags, then perform some IRQ/context tracking which is intended
> to balance with the IRQ/context tracking performed in the entry C code.
> 
> For simplicity and consistency, it would be preferable to move this all
> to C. As a step towards that, this patch moves the conditional work and
> IRQ/context tracking into a C helper function. To aid bisectability,
> this is called from the `ret_to_user` assembly, and a subsequent patch
> will move the call to C code.
> 

[..]

> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 863d44f73028..fe0a9bcc3e1f 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -29,16 +29,6 @@
>  #include <asm/asm-uaccess.h>
>  #include <asm/unistd.h>
>  
> -/*
> - * Context tracking and irqflag tracing need to instrument transitions between
> - * user and kernel mode.
> - */
> -	.macro user_enter_irqoff
> -#if defined(CONFIG_CONTEXT_TRACKING) || defined(CONFIG_TRACE_IRQFLAGS)
> -	bl	exit_to_user_mode
> -#endif
> -	.endm
> -
>  	.macro	clear_gp_regs
>  	.irp	n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29
>  	mov	x\n, xzr
> @@ -585,37 +575,17 @@ SYM_CODE_START_LOCAL(ret_to_kernel)
>  	kernel_exit 1
>  SYM_CODE_END(ret_to_kernel)
>  
> -/*
> - * "slow" syscall return path.
> - */
>  SYM_CODE_START_LOCAL(ret_to_user)
> -	disable_daif
> -	gic_prio_kentry_setup tmp=x3

The `gic_prio_kentry_setup` macro is now unused too!

> -#ifdef CONFIG_TRACE_IRQFLAGS
> -	bl	trace_hardirqs_off
> -#endif
> -	ldr	x19, [tsk, #TSK_TI_FLAGS]
> -	and	x2, x19, #_TIF_WORK_MASK
> -	cbnz	x2, work_pending
> -finish_ret_to_user:
> -	user_enter_irqoff
> +	mov	x0, sp
> +	bl	asm_exit_to_user_mode
>  	/* Ignore asynchronous tag check faults in the uaccess routines */
>  	clear_mte_async_tcf
> +	ldr	x19, [tsk, #TSK_TI_FLAGS]	// re-check for single-step
>  	enable_step_tsk x19, x2
>  #ifdef CONFIG_GCC_PLUGIN_STACKLEAK
>  	bl	stackleak_erase
>  #endif
>  	kernel_exit 0
> -
> -/*
> - * Ok, we need to do extra processing, enter the slow path.
> - */
> -work_pending:
> -	mov	x0, sp				// 'regs'
> -	mov	x1, x19
> -	bl	do_notify_resume
> -	ldr	x19, [tsk, #TSK_TI_FLAGS]	// re-check for single-step
> -	b	finish_ret_to_user
>  SYM_CODE_END(ret_to_user)
>  
>  	.popsection				// .entry.text

Reviewed-by: Joey Gouly <joey.gouly at arm.com>


From vilhelm.gray at gmail.com  Tue Aug  3 05:06:11 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:11 +0900
Subject: [PATCH v14 01/17] counter: 104-quad-8: Return error when invalid mode
 during ceiling_write
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <a2147f022829b66839a1db5530a7fada47856847.1627990337.git.vilhelm.gray@gmail.com>

The 104-QUAD-8 only has two count modes where a ceiling value makes
sense: Range Limit and Modulo-N. Outside of these two modes, setting a
ceiling value is an invalid operation -- so let's report it as such by
returning -EINVAL.

Fixes: fc069262261c ("counter: 104-quad-8: Add lock guards - generic interface")
Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index 09a9a77cce06..81f9642777fb 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -715,12 +715,13 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
 	case 1:
 	case 3:
 		quad8_preset_register_set(priv, count->id, ceiling);
-		break;
+		mutex_unlock(&priv->lock);
+		return len;
 	}
 
 	mutex_unlock(&priv->lock);
 
-	return len;
+	return -EINVAL;
 }
 
 static ssize_t quad8_count_preset_enable_read(struct counter_device *counter,
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:12 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:12 +0900
Subject: [PATCH v14 02/17] counter: Return error code on invalid modes
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <7af82d4e39610da11edce0ee370285fe1cb1eac8.1627990337.git.vilhelm.gray@gmail.com>

Only a select set of modes (function, action, etc.) are valid for a
given device configuration. This patch ensures that invalid modes result
in a return -EINVAL. Such a situation should never occur in reality, but
it's good to define a default switch case for the sake of making the
intent of the code clear.

Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
Cc: Alexandre Torgue <alexandre.torgue at st.com>
Acked-by: David Lechner <david at lechnology.com>
Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c            | 20 ++++++++++++------
 drivers/counter/microchip-tcb-capture.c |  6 ++++++
 drivers/counter/stm32-lptimer-cnt.c     | 10 +++++----
 drivers/counter/ti-eqep.c               | 27 +++++++++++++++----------
 4 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index 81f9642777fb..b358b2b2b883 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -273,6 +273,10 @@ static int quad8_function_set(struct counter_device *counter,
 			*scale = 2;
 			mode_cfg |= QUAD8_CMR_QUADRATURE_X4;
 			break;
+		default:
+			/* should never reach this path */
+			mutex_unlock(&priv->lock);
+			return -EINVAL;
 		}
 	}
 
@@ -349,7 +353,7 @@ static int quad8_action_get(struct counter_device *counter,
 	case QUAD8_COUNT_FUNCTION_PULSE_DIRECTION:
 		if (synapse->signal->id == signal_a_id)
 			*action = QUAD8_SYNAPSE_ACTION_RISING_EDGE;
-		break;
+		return 0;
 	case QUAD8_COUNT_FUNCTION_QUADRATURE_X1:
 		if (synapse->signal->id == signal_a_id) {
 			quad8_direction_get(counter, count, &direction);
@@ -359,17 +363,18 @@ static int quad8_action_get(struct counter_device *counter,
 			else
 				*action = QUAD8_SYNAPSE_ACTION_FALLING_EDGE;
 		}
-		break;
+		return 0;
 	case QUAD8_COUNT_FUNCTION_QUADRATURE_X2:
 		if (synapse->signal->id == signal_a_id)
 			*action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES;
-		break;
+		return 0;
 	case QUAD8_COUNT_FUNCTION_QUADRATURE_X4:
 		*action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES;
-		break;
+		return 0;
+	default:
+		/* should never reach this path */
+		return -EINVAL;
 	}
-
-	return 0;
 }
 
 static const struct counter_ops quad8_ops = {
@@ -529,6 +534,9 @@ static int quad8_count_mode_set(struct counter_device *counter,
 	case COUNTER_COUNT_MODE_MODULO_N:
 		cnt_mode = 3;
 		break;
+	default:
+		/* should never reach this path */
+		return -EINVAL;
 	}
 
 	mutex_lock(&priv->lock);
diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
index 51b8af80f98b..0c9a61962911 100644
--- a/drivers/counter/microchip-tcb-capture.c
+++ b/drivers/counter/microchip-tcb-capture.c
@@ -133,6 +133,9 @@ static int mchp_tc_count_function_set(struct counter_device *counter,
 		bmr |= ATMEL_TC_QDEN | ATMEL_TC_POSEN;
 		cmr |= ATMEL_TC_ETRGEDG_RISING | ATMEL_TC_ABETRG | ATMEL_TC_XC0;
 		break;
+	default:
+		/* should never reach this path */
+		return -EINVAL;
 	}
 
 	regmap_write(priv->regmap, ATMEL_TC_BMR, bmr);
@@ -226,6 +229,9 @@ static int mchp_tc_count_action_set(struct counter_device *counter,
 	case MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE:
 		edge = ATMEL_TC_ETRGEDG_BOTH;
 		break;
+	default:
+		/* should never reach this path */
+		return -EINVAL;
 	}
 
 	return regmap_write_bits(priv->regmap,
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index c19d998df5ba..78f383b77bd2 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -206,9 +206,10 @@ static int stm32_lptim_cnt_function_set(struct counter_device *counter,
 		priv->quadrature_mode = 1;
 		priv->polarity = STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES;
 		return 0;
+	default:
+		/* should never reach this path */
+		return -EINVAL;
 	}
-
-	return -EINVAL;
 }
 
 static ssize_t stm32_lptim_cnt_enable_read(struct counter_device *counter,
@@ -326,9 +327,10 @@ static int stm32_lptim_cnt_action_get(struct counter_device *counter,
 	case STM32_LPTIM_ENCODER_BOTH_EDGE:
 		*action = priv->polarity;
 		return 0;
+	default:
+		/* should never reach this path */
+		return -EINVAL;
 	}
-
-	return -EINVAL;
 }
 
 static int stm32_lptim_cnt_action_set(struct counter_device *counter,
diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index 65df9ef5b5bc..c303eb17c111 100644
--- a/drivers/counter/ti-eqep.c
+++ b/drivers/counter/ti-eqep.c
@@ -157,7 +157,7 @@ static int ti_eqep_action_get(struct counter_device *counter,
 		 * QEPA and QEPB trigger QCLK.
 		 */
 		*action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES;
-		break;
+		return 0;
 	case TI_EQEP_COUNT_FUNC_DIR_COUNT:
 		/* In direction-count mode only rising edge of QEPA is counted
 		 * and QEPB gives direction.
@@ -165,12 +165,14 @@ static int ti_eqep_action_get(struct counter_device *counter,
 		switch (synapse->signal->id) {
 		case TI_EQEP_SIGNAL_QEPA:
 			*action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE;
-			break;
-		default:
+			return 0;
+		case TI_EQEP_SIGNAL_QEPB:
 			*action = TI_EQEP_SYNAPSE_ACTION_NONE;
-			break;
+			return 0;
+		default:
+			/* should never reach this path */
+			return -EINVAL;
 		}
-		break;
 	case TI_EQEP_COUNT_FUNC_UP_COUNT:
 	case TI_EQEP_COUNT_FUNC_DOWN_COUNT:
 		/* In up/down-count modes only QEPA is counted and QEPB is not
@@ -186,15 +188,18 @@ static int ti_eqep_action_get(struct counter_device *counter,
 				*action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES;
 			else
 				*action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE;
-			break;
-		default:
+			return 0;
+		case TI_EQEP_SIGNAL_QEPB:
 			*action = TI_EQEP_SYNAPSE_ACTION_NONE;
-			break;
+			return 0;
+		default:
+			/* should never reach this path */
+			return -EINVAL;
 		}
-		break;
+	default:
+		/* should never reach this path */
+		return -EINVAL;
 	}
-
-	return 0;
 }
 
 static const struct counter_ops ti_eqep_counter_ops = {
-- 
2.32.0



From patrice.chotard at foss.st.com  Tue Aug  3 05:06:51 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:06:51 +0200
Subject: [PATCH v3 07/13] ARM: dts: sti: update clkgen-fsyn entries in
 stih407-clock
In-Reply-To: <20210331204228.26107-8-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-8-avolmat@me.com>
Message-ID: <8125585a-84b2-7914-17a1-52f4d1b4ef37@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The clkgen-fsyn driver now embed the clock names (assuming the
> right compatible is used). Remove all clock-output-names property
> and update when necessary the compatible.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih407-clock.dtsi | 27 +++------------------------
>  1 file changed, 3 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih407-clock.dtsi b/arch/arm/boot/dts/stih407-clock.dtsi
> index 2603226a6ca8..9cce9541e26b 100644
> --- a/arch/arm/boot/dts/stih407-clock.dtsi
> +++ b/arch/arm/boot/dts/stih407-clock.dtsi
> @@ -93,12 +93,6 @@
>  			reg = <0x9103000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-c0-fs0-ch0",
> -					     "clk-s-c0-fs0-ch1",
> -					     "clk-s-c0-fs0-ch2",
> -					     "clk-s-c0-fs0-ch3";
> -			clock-critical = <0>; /* clk-s-c0-fs0-ch0 */
>  		};
>  
>  		clk_s_c0: clockgen-c at 9103000 {
> @@ -150,15 +144,10 @@
>  
>  		clk_s_d0_quadfs: clk-s-d0-quadfs at 9104000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d0";
>  			reg = <0x9104000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d0-fs0-ch0",
> -					     "clk-s-d0-fs0-ch1",
> -					     "clk-s-d0-fs0-ch2",
> -					     "clk-s-d0-fs0-ch3";
>  		};
>  
>  		clockgen-d0 at 9104000 {
> @@ -179,15 +168,10 @@
>  
>  		clk_s_d2_quadfs: clk-s-d2-quadfs at 9106000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d2";
>  			reg = <0x9106000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d2-fs0-ch0",
> -					     "clk-s-d2-fs0-ch1",
> -					     "clk-s-d2-fs0-ch2",
> -					     "clk-s-d2-fs0-ch3";
>  		};
>  
>  		clockgen-d2 at 9106000 {
> @@ -210,15 +194,10 @@
>  
>  		clk_s_d3_quadfs: clk-s-d3-quadfs at 9107000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d3";
>  			reg = <0x9107000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d3-fs0-ch0",
> -					     "clk-s-d3-fs0-ch1",
> -					     "clk-s-d3-fs0-ch2",
> -					     "clk-s-d3-fs0-ch3";
>  		};
>  
>  		clockgen-d3 at 9107000 {
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From vilhelm.gray at gmail.com  Tue Aug  3 05:06:13 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:13 +0900
Subject: [PATCH v14 03/17] counter: Standardize to ERANGE for limit exceeded
 errors
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <ae8d3b20b8b02c96b1c9898ffa2f9fa5d99edc81.1627990337.git.vilhelm.gray@gmail.com>

ERANGE is a semantically better error code to return when an argument
value falls outside the supported limit range of a device.

Cc: Jarkko Nikula <jarkko.nikula at linux.intel.com>
Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
Cc: Alexandre Torgue <alexandre.torgue at st.com>
Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Reviewed-by: David Lechner <david at lechnology.com>
Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c        | 6 +++---
 drivers/counter/intel-qep.c         | 2 +-
 drivers/counter/interrupt-cnt.c     | 3 +++
 drivers/counter/stm32-lptimer-cnt.c | 2 +-
 4 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index b358b2b2b883..d54efdb8d393 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -154,7 +154,7 @@ static int quad8_count_write(struct counter_device *counter,
 
 	/* Only 24-bit values are supported */
 	if (val > 0xFFFFFF)
-		return -EINVAL;
+		return -ERANGE;
 
 	mutex_lock(&priv->lock);
 
@@ -669,7 +669,7 @@ static ssize_t quad8_count_preset_write(struct counter_device *counter,
 
 	/* Only 24-bit values are supported */
 	if (preset > 0xFFFFFF)
-		return -EINVAL;
+		return -ERANGE;
 
 	mutex_lock(&priv->lock);
 
@@ -714,7 +714,7 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
 
 	/* Only 24-bit values are supported */
 	if (ceiling > 0xFFFFFF)
-		return -EINVAL;
+		return -ERANGE;
 
 	mutex_lock(&priv->lock);
 
diff --git a/drivers/counter/intel-qep.c b/drivers/counter/intel-qep.c
index 1a9512e28519..204f94577666 100644
--- a/drivers/counter/intel-qep.c
+++ b/drivers/counter/intel-qep.c
@@ -319,7 +319,7 @@ static ssize_t spike_filter_ns_write(struct counter_device *counter,
 	}
 
 	if (length > INTEL_QEPFLT_MAX_COUNT(length))
-		return -EINVAL;
+		return -ERANGE;
 
 	mutex_lock(&qep->lock);
 	if (qep->enabled) {
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
index 5df7cd13d4c7..66cac4900327 100644
--- a/drivers/counter/interrupt-cnt.c
+++ b/drivers/counter/interrupt-cnt.c
@@ -107,6 +107,9 @@ static int interrupt_cnt_write(struct counter_device *counter,
 {
 	struct interrupt_cnt_priv *priv = counter->priv;
 
+	if (val != (typeof(priv->count.counter))val)
+		return -ERANGE;
+
 	atomic_set(&priv->count, val);
 
 	return 0;
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index 78f383b77bd2..49aeb9e393f3 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -283,7 +283,7 @@ static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
 		return ret;
 
 	if (ceiling > STM32_LPTIM_MAX_ARR)
-		return -EINVAL;
+		return -ERANGE;
 
 	priv->ceiling = ceiling;
 
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:14 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:14 +0900
Subject: [PATCH v14 04/17] counter: Rename counter_signal_value to
 counter_signal_level
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <3f17010abe2415859cea9a5fddabd3c97f635ff5.1627990337.git.vilhelm.gray@gmail.com>

Signal values will always be levels so let's be explicit it about it to
make the intent of the code clear.

Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c            |  5 +++--
 drivers/counter/counter.c               | 12 ++++++------
 drivers/counter/interrupt-cnt.c         |  4 ++--
 drivers/counter/microchip-tcb-capture.c |  4 ++--
 include/linux/counter.h                 | 12 ++++++------
 5 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index d54efdb8d393..b4dd07cf51eb 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -97,7 +97,8 @@ struct quad8 {
 #define QUAD8_CMR_QUADRATURE_X4 0x18
 
 static int quad8_signal_read(struct counter_device *counter,
-	struct counter_signal *signal, enum counter_signal_value *val)
+			     struct counter_signal *signal,
+			     enum counter_signal_level *level)
 {
 	const struct quad8 *const priv = counter->priv;
 	unsigned int state;
@@ -109,7 +110,7 @@ static int quad8_signal_read(struct counter_device *counter,
 	state = inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS)
 		& BIT(signal->id - 16);
 
-	*val = (state) ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
+	*level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
 
 	return 0;
 }
diff --git a/drivers/counter/counter.c b/drivers/counter/counter.c
index 6a683d086008..cb92673552b5 100644
--- a/drivers/counter/counter.c
+++ b/drivers/counter/counter.c
@@ -289,9 +289,9 @@ struct counter_signal_unit {
 	struct counter_signal *signal;
 };
 
-static const char *const counter_signal_value_str[] = {
-	[COUNTER_SIGNAL_LOW] = "low",
-	[COUNTER_SIGNAL_HIGH] = "high"
+static const char *const counter_signal_level_str[] = {
+	[COUNTER_SIGNAL_LEVEL_LOW] = "low",
+	[COUNTER_SIGNAL_LEVEL_HIGH] = "high"
 };
 
 static ssize_t counter_signal_show(struct device *dev,
@@ -302,13 +302,13 @@ static ssize_t counter_signal_show(struct device *dev,
 	const struct counter_signal_unit *const component = devattr->component;
 	struct counter_signal *const signal = component->signal;
 	int err;
-	enum counter_signal_value val;
+	enum counter_signal_level level;
 
-	err = counter->ops->signal_read(counter, signal, &val);
+	err = counter->ops->signal_read(counter, signal, &level);
 	if (err)
 		return err;
 
-	return sprintf(buf, "%s\n", counter_signal_value_str[val]);
+	return sprintf(buf, "%s\n", counter_signal_level_str[level]);
 }
 
 struct counter_name_unit {
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
index 66cac4900327..d06367bef8f0 100644
--- a/drivers/counter/interrupt-cnt.c
+++ b/drivers/counter/interrupt-cnt.c
@@ -130,7 +130,7 @@ static int interrupt_cnt_function_get(struct counter_device *counter,
 
 static int interrupt_cnt_signal_read(struct counter_device *counter,
 				     struct counter_signal *signal,
-				     enum counter_signal_value *val)
+				     enum counter_signal_level *level)
 {
 	struct interrupt_cnt_priv *priv = counter->priv;
 	int ret;
@@ -142,7 +142,7 @@ static int interrupt_cnt_signal_read(struct counter_device *counter,
 	if (ret < 0)
 		return ret;
 
-	*val = ret ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
+	*level = ret ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
 
 	return 0;
 }
diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
index 0c9a61962911..6be3adf74114 100644
--- a/drivers/counter/microchip-tcb-capture.c
+++ b/drivers/counter/microchip-tcb-capture.c
@@ -158,7 +158,7 @@ static int mchp_tc_count_function_set(struct counter_device *counter,
 
 static int mchp_tc_count_signal_read(struct counter_device *counter,
 				     struct counter_signal *signal,
-				     enum counter_signal_value *val)
+				     enum counter_signal_level *lvl)
 {
 	struct mchp_tc_data *const priv = counter->priv;
 	bool sigstatus;
@@ -171,7 +171,7 @@ static int mchp_tc_count_signal_read(struct counter_device *counter,
 	else
 		sigstatus = (sr & ATMEL_TC_MTIOA);
 
-	*val = sigstatus ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
+	*lvl = sigstatus ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
 
 	return 0;
 }
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 9dbd5df4cd34..79f5dcaf6ba0 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -290,16 +290,16 @@ struct counter_device_state {
 	const struct attribute_group **groups;
 };
 
-enum counter_signal_value {
-	COUNTER_SIGNAL_LOW = 0,
-	COUNTER_SIGNAL_HIGH
+enum counter_signal_level {
+	COUNTER_SIGNAL_LEVEL_LOW,
+	COUNTER_SIGNAL_LEVEL_HIGH,
 };
 
 /**
  * struct counter_ops - Callbacks from driver
  * @signal_read:	optional read callback for Signal attribute. The read
- *			value of the respective Signal should be passed back via
- *			the val parameter.
+ *			level of the respective Signal should be passed back via
+ *			the level parameter.
  * @count_read:		optional read callback for Count attribute. The read
  *			value of the respective Count should be passed back via
  *			the val parameter.
@@ -324,7 +324,7 @@ enum counter_signal_value {
 struct counter_ops {
 	int (*signal_read)(struct counter_device *counter,
 			   struct counter_signal *signal,
-			   enum counter_signal_value *val);
+			   enum counter_signal_level *level);
 	int (*count_read)(struct counter_device *counter,
 			  struct counter_count *count, unsigned long *val);
 	int (*count_write)(struct counter_device *counter,
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:15 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:15 +0900
Subject: [PATCH v14 05/17] counter: Rename counter_count_function to
 counter_function
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <8268c54d6f42075a19bb08151a37831e22652499.1627990337.git.vilhelm.gray@gmail.com>

The phrase "Counter Count function" is verbose and unintentionally
implies that function is a Count extension. This patch adjusts the
Counter subsystem code to use the more direct "Counter function" phrase
to make the intent of this code clearer.

Cc: Jarkko Nikula <jarkko.nikula at linux.intel.com>
Cc: Patrick Havelange <patrick.havelange at essensium.com>
Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
Cc: Alexandre Torgue <alexandre.torgue at st.com>
Cc: David Lechner <david at lechnology.com>
Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c            | 10 +++----
 drivers/counter/counter.c               | 38 ++++++++++++-------------
 drivers/counter/ftm-quaddec.c           |  5 ++--
 drivers/counter/intel-qep.c             |  4 +--
 drivers/counter/interrupt-cnt.c         |  4 +--
 drivers/counter/microchip-tcb-capture.c |  4 +--
 drivers/counter/stm32-lptimer-cnt.c     |  6 ++--
 drivers/counter/stm32-timer-cnt.c       | 10 +++----
 drivers/counter/ti-eqep.c               | 10 +++----
 include/linux/counter.h                 | 20 ++++++-------
 10 files changed, 55 insertions(+), 56 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index b4dd07cf51eb..5283ff128c17 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -194,11 +194,11 @@ enum quad8_count_function {
 	QUAD8_COUNT_FUNCTION_QUADRATURE_X4
 };
 
-static const enum counter_count_function quad8_count_functions_list[] = {
-	[QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
-	[QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A,
-	[QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
-	[QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4
+static const enum counter_function quad8_count_functions_list[] = {
+	[QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_FUNCTION_PULSE_DIRECTION,
+	[QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_FUNCTION_QUADRATURE_X1_A,
+	[QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_FUNCTION_QUADRATURE_X2_A,
+	[QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_FUNCTION_QUADRATURE_X4
 };
 
 static int quad8_function_get(struct counter_device *counter,
diff --git a/drivers/counter/counter.c b/drivers/counter/counter.c
index cb92673552b5..de921e8a3f72 100644
--- a/drivers/counter/counter.c
+++ b/drivers/counter/counter.c
@@ -744,15 +744,15 @@ static ssize_t counter_count_store(struct device *dev,
 	return len;
 }
 
-static const char *const counter_count_function_str[] = {
-	[COUNTER_COUNT_FUNCTION_INCREASE] = "increase",
-	[COUNTER_COUNT_FUNCTION_DECREASE] = "decrease",
-	[COUNTER_COUNT_FUNCTION_PULSE_DIRECTION] = "pulse-direction",
-	[COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a",
-	[COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b",
-	[COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a",
-	[COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b",
-	[COUNTER_COUNT_FUNCTION_QUADRATURE_X4] = "quadrature x4"
+static const char *const counter_function_str[] = {
+	[COUNTER_FUNCTION_INCREASE] = "increase",
+	[COUNTER_FUNCTION_DECREASE] = "decrease",
+	[COUNTER_FUNCTION_PULSE_DIRECTION] = "pulse-direction",
+	[COUNTER_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a",
+	[COUNTER_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b",
+	[COUNTER_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a",
+	[COUNTER_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b",
+	[COUNTER_FUNCTION_QUADRATURE_X4] = "quadrature x4"
 };
 
 static ssize_t counter_function_show(struct device *dev,
@@ -764,7 +764,7 @@ static ssize_t counter_function_show(struct device *dev,
 	const struct counter_count_unit *const component = devattr->component;
 	struct counter_count *const count = component->count;
 	size_t func_index;
-	enum counter_count_function function;
+	enum counter_function function;
 
 	err = counter->ops->function_get(counter, count, &func_index);
 	if (err)
@@ -773,7 +773,7 @@ static ssize_t counter_function_show(struct device *dev,
 	count->function = func_index;
 
 	function = count->functions_list[func_index];
-	return sprintf(buf, "%s\n", counter_count_function_str[function]);
+	return sprintf(buf, "%s\n", counter_function_str[function]);
 }
 
 static ssize_t counter_function_store(struct device *dev,
@@ -785,14 +785,14 @@ static ssize_t counter_function_store(struct device *dev,
 	struct counter_count *const count = component->count;
 	const size_t num_functions = count->num_functions;
 	size_t func_index;
-	enum counter_count_function function;
+	enum counter_function function;
 	int err;
 	struct counter_device *const counter = dev_get_drvdata(dev);
 
 	/* Find requested Count function mode */
 	for (func_index = 0; func_index < num_functions; func_index++) {
 		function = count->functions_list[func_index];
-		if (sysfs_streq(buf, counter_count_function_str[function]))
+		if (sysfs_streq(buf, counter_function_str[function]))
 			break;
 	}
 	/* Return error if requested Count function mode not found */
@@ -880,25 +880,25 @@ static int counter_count_ext_register(
 }
 
 struct counter_func_avail_unit {
-	const enum counter_count_function *functions_list;
+	const enum counter_function *functions_list;
 	size_t num_functions;
 };
 
-static ssize_t counter_count_function_available_show(struct device *dev,
+static ssize_t counter_function_available_show(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
 	const struct counter_device_attr *const devattr = to_counter_attr(attr);
 	const struct counter_func_avail_unit *const component = devattr->component;
-	const enum counter_count_function *const func_list = component->functions_list;
+	const enum counter_function *const func_list = component->functions_list;
 	const size_t num_functions = component->num_functions;
 	size_t i;
-	enum counter_count_function function;
+	enum counter_function function;
 	ssize_t len = 0;
 
 	for (i = 0; i < num_functions; i++) {
 		function = func_list[i];
 		len += sprintf(buf + len, "%s\n",
-			       counter_count_function_str[function]);
+			       counter_function_str[function]);
 	}
 
 	return len;
@@ -968,7 +968,7 @@ static int counter_count_attributes_create(
 	parm.group = group;
 	parm.prefix = "";
 	parm.name = "function_available";
-	parm.show = counter_count_function_available_show;
+	parm.show = counter_function_available_show;
 	parm.store = NULL;
 	parm.component = avail_comp;
 	err = counter_attribute_create(&parm);
diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
index 9371532406ca..53c15f84909b 100644
--- a/drivers/counter/ftm-quaddec.c
+++ b/drivers/counter/ftm-quaddec.c
@@ -171,9 +171,8 @@ enum ftm_quaddec_count_function {
 	FTM_QUADDEC_COUNT_ENCODER_MODE_1,
 };
 
-static const enum counter_count_function ftm_quaddec_count_functions[] = {
-	[FTM_QUADDEC_COUNT_ENCODER_MODE_1] =
-	COUNTER_COUNT_FUNCTION_QUADRATURE_X4
+static const enum counter_function ftm_quaddec_count_functions[] = {
+	[FTM_QUADDEC_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X4
 };
 
 static int ftm_quaddec_count_read(struct counter_device *counter,
diff --git a/drivers/counter/intel-qep.c b/drivers/counter/intel-qep.c
index 204f94577666..8a6847d5fb2b 100644
--- a/drivers/counter/intel-qep.c
+++ b/drivers/counter/intel-qep.c
@@ -126,8 +126,8 @@ static int intel_qep_count_read(struct counter_device *counter,
 	return 0;
 }
 
-static const enum counter_count_function intel_qep_count_functions[] = {
-	COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
+static const enum counter_function intel_qep_count_functions[] = {
+	COUNTER_FUNCTION_QUADRATURE_X4,
 };
 
 static int intel_qep_function_get(struct counter_device *counter,
diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
index d06367bef8f0..1de4243db488 100644
--- a/drivers/counter/interrupt-cnt.c
+++ b/drivers/counter/interrupt-cnt.c
@@ -115,8 +115,8 @@ static int interrupt_cnt_write(struct counter_device *counter,
 	return 0;
 }
 
-static const enum counter_count_function interrupt_cnt_functions[] = {
-	COUNTER_COUNT_FUNCTION_INCREASE,
+static const enum counter_function interrupt_cnt_functions[] = {
+	COUNTER_FUNCTION_INCREASE,
 };
 
 static int interrupt_cnt_function_get(struct counter_device *counter,
diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
index 6be3adf74114..4c57d43e7d66 100644
--- a/drivers/counter/microchip-tcb-capture.c
+++ b/drivers/counter/microchip-tcb-capture.c
@@ -38,8 +38,8 @@ enum mchp_tc_count_function {
 };
 
 static const enum counter_count_function mchp_tc_count_functions[] = {
-	[MCHP_TC_FUNCTION_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE,
-	[MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
+	[MCHP_TC_FUNCTION_INCREASE] = COUNTER_FUNCTION_INCREASE,
+	[MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_FUNCTION_QUADRATURE_X4,
 };
 
 enum mchp_tc_synapse_action {
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index 49aeb9e393f3..13656957c45f 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -134,9 +134,9 @@ enum stm32_lptim_cnt_function {
 	STM32_LPTIM_ENCODER_BOTH_EDGE,
 };
 
-static const enum counter_count_function stm32_lptim_cnt_functions[] = {
-	[STM32_LPTIM_COUNTER_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE,
-	[STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
+static const enum counter_function stm32_lptim_cnt_functions[] = {
+	[STM32_LPTIM_COUNTER_INCREASE] = COUNTER_FUNCTION_INCREASE,
+	[STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_FUNCTION_QUADRATURE_X4,
 };
 
 enum stm32_lptim_synapse_action {
diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
index 603b30ada839..3fb0debd7425 100644
--- a/drivers/counter/stm32-timer-cnt.c
+++ b/drivers/counter/stm32-timer-cnt.c
@@ -50,11 +50,11 @@ enum stm32_count_function {
 	STM32_COUNT_ENCODER_MODE_3,
 };
 
-static const enum counter_count_function stm32_count_functions[] = {
-	[STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_COUNT_FUNCTION_INCREASE,
-	[STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
-	[STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B,
-	[STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
+static const enum counter_function stm32_count_functions[] = {
+	[STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_FUNCTION_INCREASE,
+	[STM32_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X2_A,
+	[STM32_COUNT_ENCODER_MODE_2] = COUNTER_FUNCTION_QUADRATURE_X2_B,
+	[STM32_COUNT_ENCODER_MODE_3] = COUNTER_FUNCTION_QUADRATURE_X4,
 };
 
 static int stm32_count_read(struct counter_device *counter,
diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index c303eb17c111..94fe58bb3eab 100644
--- a/drivers/counter/ti-eqep.c
+++ b/drivers/counter/ti-eqep.c
@@ -294,11 +294,11 @@ static struct counter_signal ti_eqep_signals[] = {
 	},
 };
 
-static const enum counter_count_function ti_eqep_position_functions[] = {
-	[TI_EQEP_COUNT_FUNC_QUAD_COUNT]	= COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
-	[TI_EQEP_COUNT_FUNC_DIR_COUNT]	= COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
-	[TI_EQEP_COUNT_FUNC_UP_COUNT]	= COUNTER_COUNT_FUNCTION_INCREASE,
-	[TI_EQEP_COUNT_FUNC_DOWN_COUNT]	= COUNTER_COUNT_FUNCTION_DECREASE,
+static const enum counter_function ti_eqep_position_functions[] = {
+	[TI_EQEP_COUNT_FUNC_QUAD_COUNT]	= COUNTER_FUNCTION_QUADRATURE_X4,
+	[TI_EQEP_COUNT_FUNC_DIR_COUNT]	= COUNTER_FUNCTION_PULSE_DIRECTION,
+	[TI_EQEP_COUNT_FUNC_UP_COUNT]	= COUNTER_FUNCTION_INCREASE,
+	[TI_EQEP_COUNT_FUNC_DOWN_COUNT]	= COUNTER_FUNCTION_DECREASE,
 };
 
 static const enum counter_synapse_action ti_eqep_position_synapse_actions[] = {
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 79f5dcaf6ba0..d16ce2819b48 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -162,15 +162,15 @@ struct counter_count_ext {
 	void *priv;
 };
 
-enum counter_count_function {
-	COUNTER_COUNT_FUNCTION_INCREASE = 0,
-	COUNTER_COUNT_FUNCTION_DECREASE,
-	COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
-	COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A,
-	COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B,
-	COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
-	COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B,
-	COUNTER_COUNT_FUNCTION_QUADRATURE_X4
+enum counter_function {
+	COUNTER_FUNCTION_INCREASE = 0,
+	COUNTER_FUNCTION_DECREASE,
+	COUNTER_FUNCTION_PULSE_DIRECTION,
+	COUNTER_FUNCTION_QUADRATURE_X1_A,
+	COUNTER_FUNCTION_QUADRATURE_X1_B,
+	COUNTER_FUNCTION_QUADRATURE_X2_A,
+	COUNTER_FUNCTION_QUADRATURE_X2_B,
+	COUNTER_FUNCTION_QUADRATURE_X4
 };
 
 /**
@@ -192,7 +192,7 @@ struct counter_count {
 	const char *name;
 
 	size_t function;
-	const enum counter_count_function *functions_list;
+	const enum counter_function *functions_list;
 	size_t num_functions;
 
 	struct counter_synapse *synapses;
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:17 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:17 +0900
Subject: [PATCH v14 07/17] counter: Update counter.h comments to reflect sysfs
 internalization
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <1ce1988777a86177cbdb001cad49faddfe7660dc.1627990337.git.vilhelm.gray@gmail.com>

The Counter subsystem architecture and driver implementations have
changed in order to handle Counter sysfs interactions in a more
consistent way. This patch updates the Generic Counter interface
header file comments to reflect the changes.

Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/counter-core.c |  3 ++
 include/linux/counter.h        | 62 ++++++++++++++++------------------
 2 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
index 15f735ef296e..9442e3b91468 100644
--- a/drivers/counter/counter-core.c
+++ b/drivers/counter/counter-core.c
@@ -41,6 +41,9 @@ static struct bus_type counter_bus_type = {
  * This function registers a Counter to the system. A sysfs "counter" directory
  * will be created and populated with sysfs attributes correlating with the
  * Counter Signals, Synapses, and Counts respectively.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
  */
 int counter_register(struct counter_device *const counter)
 {
diff --git a/include/linux/counter.h b/include/linux/counter.h
index b69277f5c4c5..445f22d8bfe2 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -188,11 +188,10 @@ struct counter_comp {
 
 /**
  * struct counter_signal - Counter Signal node
- * @id:		unique ID used to identify signal
- * @name:	device-specific Signal name; ideally, this should match the name
- *		as it appears in the datasheet documentation
- * @ext:	optional array of Counter Signal extensions
- * @num_ext:	number of Counter Signal extensions specified in @ext
+ * @id:		unique ID used to identify the Signal
+ * @name:	device-specific Signal name
+ * @ext:	optional array of Signal extensions
+ * @num_ext:	number of Signal extensions specified in @ext
  */
 struct counter_signal {
 	int id;
@@ -206,7 +205,7 @@ struct counter_signal {
  * struct counter_synapse - Counter Synapse node
  * @actions_list:	array of available action modes
  * @num_actions:	number of action modes specified in @actions_list
- * @signal:		pointer to associated signal
+ * @signal:		pointer to the associated Signal
  */
 struct counter_synapse {
 	const enum counter_synapse_action *actions_list;
@@ -217,15 +216,14 @@ struct counter_synapse {
 
 /**
  * struct counter_count - Counter Count node
- * @id:			unique ID used to identify Count
- * @name:		device-specific Count name; ideally, this should match
- *			the name as it appears in the datasheet documentation
- * @functions_list:	array available function modes
+ * @id:			unique ID used to identify the Count
+ * @name:		device-specific Count name
+ * @functions_list:	array of available function modes
  * @num_functions:	number of function modes specified in @functions_list
- * @synapses:		array of synapses for initialization
- * @num_synapses:	number of synapses specified in @synapses
- * @ext:		optional array of Counter Count extensions
- * @num_ext:		number of Counter Count extensions specified in @ext
+ * @synapses:		array of Synapses for initialization
+ * @num_synapses:	number of Synapses specified in @synapses
+ * @ext:		optional array of Count extensions
+ * @num_ext:		number of Count extensions specified in @ext
  */
 struct counter_count {
 	int id;
@@ -243,27 +241,27 @@ struct counter_count {
 
 /**
  * struct counter_ops - Callbacks from driver
- * @signal_read:	optional read callback for Signal attribute. The read
- *			level of the respective Signal should be passed back via
- *			the level parameter.
- * @count_read:		optional read callback for Count attribute. The read
- *			value of the respective Count should be passed back via
- *			the val parameter.
- * @count_write:	optional write callback for Count attribute. The write
- *			value for the respective Count is passed in via the val
+ * @signal_read:	optional read callback for Signals. The read level of
+ *			the respective Signal should be passed back via the
+ *			level parameter.
+ * @count_read:		read callback for Counts. The read value of the
+ *			respective Count should be passed back via the value
+ *			parameter.
+ * @count_write:	optional write callback for Counts. The write value for
+ *			the respective Count is passed in via the value
  *			parameter.
  * @function_read:	read callback the Count function modes. The read
  *			function mode of the respective Count should be passed
  *			back via the function parameter.
- * @function_write:	write callback for Count function modes. The function
- *			mode to write for the respective Count is passed in via
- *			the function parameter.
- * @action_read:	read callback the Synapse action modes. The read action
- *			mode of the respective Synapse should be passed back via
- *			the action parameter.
- * @action_write:	write callback for Synapse action modes. The action mode
- *			to write for the respective Synapse is passed in via the
- *			action parameter.
+ * @function_write:	optional write callback for Count function modes. The
+ *			function mode to write for the respective Count is
+ *			passed in via the function parameter.
+ * @action_read:	optional read callback the Synapse action modes. The
+ *			read action mode of the respective Synapse should be
+ *			passed back via the action parameter.
+ * @action_write:	optional write callback for Synapse action modes. The
+ *			action mode to write for the respective Synapse is
+ *			passed in via the action parameter.
  */
 struct counter_ops {
 	int (*signal_read)(struct counter_device *counter,
@@ -291,7 +289,7 @@ struct counter_ops {
 
 /**
  * struct counter_device - Counter data structure
- * @name:		name of the device as it appears in the datasheet
+ * @name:		name of the device
  * @parent:		optional parent device providing the counters
  * @ops:		callbacks from driver
  * @signals:		array of Signals
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:18 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:18 +0900
Subject: [PATCH v14 08/17] docs: counter: Update to reflect sysfs
 internalization
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <bc652529b7d225e03d1ea457d64c6f6f8b1efd04.1627990337.git.vilhelm.gray@gmail.com>

The Counter subsystem architecture and driver implementations have
changed in order to handle Counter sysfs interactions in a more
consistent way. This patch updates the Generic Counter interface
documentation to reflect the changes.

Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter  |   9 +-
 Documentation/driver-api/generic-counter.rst | 243 ++++++++++++++-----
 2 files changed, 185 insertions(+), 67 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index 20fe5afd4f9e..dee79b606847 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -286,7 +286,14 @@ What:		/sys/bus/counter/devices/counterX/signalY/signal
 KernelVersion:	5.2
 Contact:	linux-iio at vger.kernel.org
 Description:
-		Signal data of Signal Y represented as a string.
+		Signal level state of Signal Y. The following signal level
+		states are available:
+
+		low:
+			Low level state.
+
+		high:
+			High level state.
 
 What:		/sys/bus/counter/devices/counterX/signalY/synchronous_mode
 KernelVersion:	5.2
diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
index 64fe7db080e5..f6397218aa4c 100644
--- a/Documentation/driver-api/generic-counter.rst
+++ b/Documentation/driver-api/generic-counter.rst
@@ -250,8 +250,8 @@ for defining a counter device.
 .. kernel-doc:: drivers/counter/counter.c
    :export:
 
-Implementation
-==============
+Driver Implementation
+=====================
 
 To support a counter device, a driver must first allocate the available
 Counter Signals via counter_signal structures. These Signals should
@@ -267,25 +267,61 @@ respective counter_count structure. These counter_count structures are
 set to the counts array member of an allocated counter_device structure
 before the Counter is registered to the system.
 
-Driver callbacks should be provided to the counter_device structure via
-a constant counter_ops structure in order to communicate with the
-device: to read and write various Signals and Counts, and to set and get
-the "action mode" and "function mode" for various Synapses and Counts
-respectively.
+Driver callbacks must be provided to the counter_device structure in
+order to communicate with the device: to read and write various Signals
+and Counts, and to set and get the "action mode" and "function mode" for
+various Synapses and Counts respectively.
 
 A defined counter_device structure may be registered to the system by
 passing it to the counter_register function, and unregistered by passing
 it to the counter_unregister function. Similarly, the
-devm_counter_register and devm_counter_unregister functions may be used
-if device memory-managed registration is desired.
-
-Extension sysfs attributes can be created for auxiliary functionality
-and data by passing in defined counter_device_ext, counter_count_ext,
-and counter_signal_ext structures. In these cases, the
-counter_device_ext structure is used for global/miscellaneous exposure
-and configuration of the respective Counter device, while the
-counter_count_ext and counter_signal_ext structures allow for auxiliary
-exposure and configuration of a specific Count or Signal respectively.
+devm_counter_register function may be used if device memory-managed
+registration is desired.
+
+The struct counter_comp structure is used to define counter extensions
+for Signals, Synapses, and Counts.
+
+The "type" member specifies the type of high-level data (e.g. BOOL,
+COUNT_DIRECTION, etc.) handled by this extension. The "``*_read``" and
+"``*_write``" members can then be set by the counter device driver with
+callbacks to handle that data using native C data types (i.e. u8, u64,
+etc.).
+
+Convenience macros such as ``COUNTER_COMP_COUNT_U64`` are provided for
+use by driver authors. In particular, driver authors are expected to use
+the provided macros for standard Counter subsystem attributes in order
+to maintain a consistent interface for userspace. For example, a counter
+device driver may define several standard attributes like so::
+
+        struct counter_comp count_ext[] = {
+                COUNTER_COMP_DIRECTION(count_direction_read),
+                COUNTER_COMP_ENABLE(count_enable_read, count_enable_write),
+                COUNTER_COMP_CEILING(count_ceiling_read, count_ceiling_write),
+        };
+
+This makes it simple to see, add, and modify the attributes that are
+supported by this driver ("direction", "enable", and "ceiling") and to
+maintain this code without getting lost in a web of struct braces.
+
+Callbacks must match the function type expected for the respective
+component or extension. These function types are defined in the struct
+counter_comp structure as the "``*_read``" and "``*_write``" union
+members.
+
+The corresponding callback prototypes for the extensions mentioned in
+the previous example above would be::
+
+        int count_direction_read(struct counter_device *counter,
+                                 struct counter_count *count,
+                                 enum counter_count_direction *direction);
+        int count_enable_read(struct counter_device *counter,
+                              struct counter_count *count, u8 *enable);
+        int count_enable_write(struct counter_device *counter,
+                               struct counter_count *count, u8 enable);
+        int count_ceiling_read(struct counter_device *counter,
+                               struct counter_count *count, u64 *ceiling);
+        int count_ceiling_write(struct counter_device *counter,
+                                struct counter_count *count, u64 ceiling);
 
 Determining the type of extension to create is a matter of scope.
 
@@ -313,52 +349,127 @@ Determining the type of extension to create is a matter of scope.
   chip overheated via a device extension called "error_overtemp":
   /sys/bus/counter/devices/counterX/error_overtemp
 
-Architecture
-============
-
-When the Generic Counter interface counter module is loaded, the
-counter_init function is called which registers a bus_type named
-"counter" to the system. Subsequently, when the module is unloaded, the
-counter_exit function is called which unregisters the bus_type named
-"counter" from the system.
-
-Counter devices are registered to the system via the counter_register
-function, and later removed via the counter_unregister function. The
-counter_register function establishes a unique ID for the Counter
-device and creates a respective sysfs directory, where X is the
-mentioned unique ID:
-
-    /sys/bus/counter/devices/counterX
-
-Sysfs attributes are created within the counterX directory to expose
-functionality, configurations, and data relating to the Counts, Signals,
-and Synapses of the Counter device, as well as options and information
-for the Counter device itself.
-
-Each Signal has a directory created to house its relevant sysfs
-attributes, where Y is the unique ID of the respective Signal:
-
-    /sys/bus/counter/devices/counterX/signalY
-
-Similarly, each Count has a directory created to house its relevant
-sysfs attributes, where Y is the unique ID of the respective Count:
-
-    /sys/bus/counter/devices/counterX/countY
-
-For a more detailed breakdown of the available Generic Counter interface
-sysfs attributes, please refer to the
-Documentation/ABI/testing/sysfs-bus-counter file.
-
-The Signals and Counts associated with the Counter device are registered
-to the system as well by the counter_register function. The
-signal_read/signal_write driver callbacks are associated with their
-respective Signal attributes, while the count_read/count_write and
-function_get/function_set driver callbacks are associated with their
-respective Count attributes; similarly, the same is true for the
-action_get/action_set driver callbacks and their respective Synapse
-attributes. If a driver callback is left undefined, then the respective
-read/write permission is left disabled for the relevant attributes.
-
-Similarly, extension sysfs attributes are created for the defined
-counter_device_ext, counter_count_ext, and counter_signal_ext
-structures that are passed in.
+Subsystem Architecture
+======================
+
+Counter drivers pass and take data natively (i.e. ``u8``, ``u64``, etc.)
+and the shared counter module handles the translation between the sysfs
+interface. This guarantees a standard userspace interface for all
+counter drivers, and enables a Generic Counter chrdev interface via a
+generalized device driver ABI.
+
+A high-level view of how a count value is passed down from a counter
+driver is exemplified by the following. The driver callbacks are first
+registered to the Counter core component for use by the Counter
+userspace interface components::
+
+        Driver callbacks registration:
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        +----------------------------+
+                        | Counter device driver      |
+                        +----------------------------+
+                        | Processes data from device |
+                        +----------------------------+
+                                |
+                         -------------------
+                        / driver callbacks /
+                        -------------------
+                                |
+                                V
+                        +----------------------+
+                        | Counter core         |
+                        +----------------------+
+                        | Routes device driver |
+                        | callbacks to the     |
+                        | userspace interfaces |
+                        +----------------------+
+                                |
+                         -------------------
+                        / driver callbacks /
+                        -------------------
+                                |
+                +---------------+
+                |
+                V
+        +--------------------+
+        | Counter sysfs      |
+        +--------------------+
+        | Translates to the  |
+        | standard Counter   |
+        | sysfs output       |
+        +--------------------+
+
+Thereafter, data can be transferred directly between the Counter device
+driver and Counter userspace interface::
+
+        Count data request:
+        ~~~~~~~~~~~~~~~~~~~
+                         ----------------------
+                        / Counter device       \
+                        +----------------------+
+                        | Count register: 0x28 |
+                        +----------------------+
+                                |
+                         -----------------
+                        / raw count data /
+                        -----------------
+                                |
+                                V
+                        +----------------------------+
+                        | Counter device driver      |
+                        +----------------------------+
+                        | Processes data from device |
+                        |----------------------------|
+                        | Type: u64                  |
+                        | Value: 42                  |
+                        +----------------------------+
+                                |
+                         ----------
+                        / u64     /
+                        ----------
+                                |
+                +---------------+
+                |
+                V
+        +--------------------+
+        | Counter sysfs      |
+        +--------------------+
+        | Translates to the  |
+        | standard Counter   |
+        | sysfs output       |
+        |--------------------|
+        | Type: const char * |
+        | Value: "42"        |
+        +--------------------+
+                |
+         ---------------
+        / const char * /
+        ---------------
+                |
+                V
+        +--------------------------------------------------+
+        | `/sys/bus/counter/devices/counterX/countY/count` |
+        +--------------------------------------------------+
+        \ Count: "42"                                      /
+         --------------------------------------------------
+
+There are three primary components involved:
+
+Counter device driver
+---------------------
+Communicates with the hardware device to read/write data; e.g. counter
+drivers for quadrature encoders, timers, etc.
+
+Counter core
+------------
+Registers the counter device driver to the system so that the respective
+callbacks are called during userspace interaction.
+
+Counter sysfs
+-------------
+Translates counter data to the standard Counter sysfs interface format
+and vice versa.
+
+Please refer to the ``Documentation/ABI/testing/sysfs-bus-counter`` file
+for a detailed breakdown of the available Generic Counter interface
+sysfs attributes.
-- 
2.32.0



From patrice.chotard at foss.st.com  Tue Aug  3 05:07:17 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:07:17 +0200
Subject: [PATCH v3 08/13] ARM: dts: sti: update clkgen-fsyn entries in
 stih410-clock
In-Reply-To: <20210331204228.26107-9-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-9-avolmat@me.com>
Message-ID: <b2817d9f-5afe-5f26-77d9-641c6b17bea7@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The clkgen-fsyn driver now embed the clock names (assuming the
> right compatible is used). Remove all clock-output-names property
> and update when necessary the compatible.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih410-clock.dtsi | 27 +++------------------------
>  1 file changed, 3 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
> index 3aeabdd6e305..6b0e6d4477a3 100644
> --- a/arch/arm/boot/dts/stih410-clock.dtsi
> +++ b/arch/arm/boot/dts/stih410-clock.dtsi
> @@ -93,12 +93,6 @@
>  			reg = <0x9103000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-c0-fs0-ch0",
> -					     "clk-s-c0-fs0-ch1",
> -					     "clk-s-c0-fs0-ch2",
> -					     "clk-s-c0-fs0-ch3";
> -			clock-critical = <0>; /* clk-s-c0-fs0-ch0 */
>  		};
>  
>  		clk_s_c0: clockgen-c at 9103000 {
> @@ -150,15 +144,10 @@
>  
>  		clk_s_d0_quadfs: clk-s-d0-quadfs at 9104000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d0";
>  			reg = <0x9104000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d0-fs0-ch0",
> -					     "clk-s-d0-fs0-ch1",
> -					     "clk-s-d0-fs0-ch2",
> -					     "clk-s-d0-fs0-ch3";
>  		};
>  
>  		clockgen-d0 at 9104000 {
> @@ -179,15 +168,10 @@
>  
>  		clk_s_d2_quadfs: clk-s-d2-quadfs at 9106000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d2";
>  			reg = <0x9106000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d2-fs0-ch0",
> -					     "clk-s-d2-fs0-ch1",
> -					     "clk-s-d2-fs0-ch2",
> -					     "clk-s-d2-fs0-ch3";
>  		};
>  
>  		clockgen-d2 at 9106000 {
> @@ -210,15 +194,10 @@
>  
>  		clk_s_d3_quadfs: clk-s-d3-quadfs at 9107000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d3";
>  			reg = <0x9107000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d3-fs0-ch0",
> -					     "clk-s-d3-fs0-ch1",
> -					     "clk-s-d3-fs0-ch2",
> -					     "clk-s-d3-fs0-ch3";
>  		};
>  
>  		clockgen-d3 at 9107000 {
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From vilhelm.gray at gmail.com  Tue Aug  3 05:06:19 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:19 +0900
Subject: [PATCH v14 09/17] counter: Move counter enums to uapi header
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <b94e0aeee4d03215f39b31d1954a073e84caa849.1627990337.git.vilhelm.gray@gmail.com>

This is in preparation for a subsequent patch implementing a character
device interface for the Counter subsystem.

Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 MAINTAINERS                  |  1 +
 include/linux/counter.h      | 42 +--------------------------
 include/uapi/linux/counter.h | 56 ++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 41 deletions(-)
 create mode 100644 include/uapi/linux/counter.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 68472ad47dcf..c0817c45401d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4764,6 +4764,7 @@ F:	Documentation/ABI/testing/sysfs-bus-counter
 F:	Documentation/driver-api/generic-counter.rst
 F:	drivers/counter/
 F:	include/linux/counter.h
+F:	include/uapi/linux/counter.h
 
 CP2615 I2C DRIVER
 M:	Bence Cs?k?s <bence98 at sch.bme.hu>
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 445f22d8bfe2..7c9f7e23953a 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -9,6 +9,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <uapi/linux/counter.h>
 
 struct counter_device;
 struct counter_count;
@@ -27,47 +28,6 @@ enum counter_comp_type {
 	COUNTER_COMP_COUNT_MODE,
 };
 
-enum counter_scope {
-	COUNTER_SCOPE_DEVICE,
-	COUNTER_SCOPE_SIGNAL,
-	COUNTER_SCOPE_COUNT,
-};
-
-enum counter_count_direction {
-	COUNTER_COUNT_DIRECTION_FORWARD,
-	COUNTER_COUNT_DIRECTION_BACKWARD,
-};
-
-enum counter_count_mode {
-	COUNTER_COUNT_MODE_NORMAL,
-	COUNTER_COUNT_MODE_RANGE_LIMIT,
-	COUNTER_COUNT_MODE_NON_RECYCLE,
-	COUNTER_COUNT_MODE_MODULO_N,
-};
-
-enum counter_function {
-	COUNTER_FUNCTION_INCREASE,
-	COUNTER_FUNCTION_DECREASE,
-	COUNTER_FUNCTION_PULSE_DIRECTION,
-	COUNTER_FUNCTION_QUADRATURE_X1_A,
-	COUNTER_FUNCTION_QUADRATURE_X1_B,
-	COUNTER_FUNCTION_QUADRATURE_X2_A,
-	COUNTER_FUNCTION_QUADRATURE_X2_B,
-	COUNTER_FUNCTION_QUADRATURE_X4,
-};
-
-enum counter_signal_level {
-	COUNTER_SIGNAL_LEVEL_LOW,
-	COUNTER_SIGNAL_LEVEL_HIGH,
-};
-
-enum counter_synapse_action {
-	COUNTER_SYNAPSE_ACTION_NONE,
-	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
-	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
-	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
-};
-
 /**
  * struct counter_comp - Counter component node
  * @type:		Counter component data type
diff --git a/include/uapi/linux/counter.h b/include/uapi/linux/counter.h
new file mode 100644
index 000000000000..6113938a6044
--- /dev/null
+++ b/include/uapi/linux/counter.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Userspace ABI for Counter character devices
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#ifndef _UAPI_COUNTER_H_
+#define _UAPI_COUNTER_H_
+
+/* Component scope definitions */
+enum counter_scope {
+	COUNTER_SCOPE_DEVICE,
+	COUNTER_SCOPE_SIGNAL,
+	COUNTER_SCOPE_COUNT,
+};
+
+/* Count direction values */
+enum counter_count_direction {
+	COUNTER_COUNT_DIRECTION_FORWARD,
+	COUNTER_COUNT_DIRECTION_BACKWARD,
+};
+
+/* Count mode values */
+enum counter_count_mode {
+	COUNTER_COUNT_MODE_NORMAL,
+	COUNTER_COUNT_MODE_RANGE_LIMIT,
+	COUNTER_COUNT_MODE_NON_RECYCLE,
+	COUNTER_COUNT_MODE_MODULO_N,
+};
+
+/* Count function values */
+enum counter_function {
+	COUNTER_FUNCTION_INCREASE,
+	COUNTER_FUNCTION_DECREASE,
+	COUNTER_FUNCTION_PULSE_DIRECTION,
+	COUNTER_FUNCTION_QUADRATURE_X1_A,
+	COUNTER_FUNCTION_QUADRATURE_X1_B,
+	COUNTER_FUNCTION_QUADRATURE_X2_A,
+	COUNTER_FUNCTION_QUADRATURE_X2_B,
+	COUNTER_FUNCTION_QUADRATURE_X4,
+};
+
+/* Signal values */
+enum counter_signal_level {
+	COUNTER_SIGNAL_LEVEL_LOW,
+	COUNTER_SIGNAL_LEVEL_HIGH,
+};
+
+/* Action mode values */
+enum counter_synapse_action {
+	COUNTER_SYNAPSE_ACTION_NONE,
+	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
+	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
+};
+
+#endif /* _UAPI_COUNTER_H_ */
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:20 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:20 +0900
Subject: [PATCH v14 10/17] counter: Add character device interface
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <2c51fa594245c3396400617caa686b8bf0887d16.1627990337.git.vilhelm.gray@gmail.com>

This patch introduces a character device interface for the Counter
subsystem. Device data is exposed through standard character device read
operations. Device data is gathered when a Counter event is pushed by
the respective Counter device driver. Configuration is handled via ioctl
operations on the respective Counter character device node.

Cc: David Lechner <david at lechnology.com>
Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/Makefile         |   2 +-
 drivers/counter/counter-chrdev.c | 553 +++++++++++++++++++++++++++++++
 drivers/counter/counter-chrdev.h |  14 +
 drivers/counter/counter-core.c   |  58 +++-
 include/linux/counter.h          |  51 +++
 include/uapi/linux/counter.h     |  98 ++++++
 6 files changed, 768 insertions(+), 8 deletions(-)
 create mode 100644 drivers/counter/counter-chrdev.c
 create mode 100644 drivers/counter/counter-chrdev.h

diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
index 1ab7e087fdc2..8fde6c100ebc 100644
--- a/drivers/counter/Makefile
+++ b/drivers/counter/Makefile
@@ -4,7 +4,7 @@
 #
 
 obj-$(CONFIG_COUNTER) += counter.o
-counter-y := counter-core.o counter-sysfs.o
+counter-y := counter-core.o counter-sysfs.o counter-chrdev.o
 
 obj-$(CONFIG_104_QUAD_8)	+= 104-quad-8.o
 obj-$(CONFIG_INTERRUPT_CNT)		+= interrupt-cnt.o
diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c
new file mode 100644
index 000000000000..30659b67d8f3
--- /dev/null
+++ b/drivers/counter/counter-chrdev.c
@@ -0,0 +1,553 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Generic Counter character device interface
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#include <linux/bitops.h>
+#include <linux/cdev.h>
+#include <linux/counter.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/kfifo.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/nospec.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/timekeeping.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+
+#include "counter-chrdev.h"
+
+struct counter_comp_node {
+	struct list_head l;
+	struct counter_component component;
+	struct counter_comp comp;
+	void *parent;
+};
+
+static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
+				   size_t len, loff_t *f_ps)
+{
+	struct counter_device *const counter = filp->private_data;
+	int err;
+	unsigned int copied;
+
+	if (!counter->ops)
+		return -ENODEV;
+
+	if (len < sizeof(struct counter_event))
+		return -EINVAL;
+
+	do {
+		if (kfifo_is_empty(&counter->events)) {
+			if (filp->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+
+			err = wait_event_interruptible(counter->events_wait,
+					!kfifo_is_empty(&counter->events) ||
+					!counter->ops);
+			if (err < 0)
+				return err;
+			if (!counter->ops)
+				return -ENODEV;
+		}
+
+		if (mutex_lock_interruptible(&counter->events_lock))
+			return -ERESTARTSYS;
+		err = kfifo_to_user(&counter->events, buf, len, &copied);
+		mutex_unlock(&counter->events_lock);
+		if (err < 0)
+			return err;
+	} while (!copied);
+
+	return copied;
+}
+
+static __poll_t counter_chrdev_poll(struct file *filp,
+				    struct poll_table_struct *pollt)
+{
+	struct counter_device *const counter = filp->private_data;
+	__poll_t events = 0;
+
+	if (!counter->ops)
+		return events;
+
+	poll_wait(filp, &counter->events_wait, pollt);
+
+	if (!kfifo_is_empty(&counter->events))
+		events = EPOLLIN | EPOLLRDNORM;
+
+	return events;
+}
+
+static void counter_events_list_free(struct list_head *const events_list)
+{
+	struct counter_event_node *p, *n;
+	struct counter_comp_node *q, *o;
+
+	list_for_each_entry_safe(p, n, events_list, l) {
+		/* Free associated component nodes */
+		list_for_each_entry_safe(q, o, &p->comp_list, l) {
+			list_del(&q->l);
+			kfree(q);
+		}
+
+		/* Free event node */
+		list_del(&p->l);
+		kfree(p);
+	}
+}
+
+static int counter_set_event_node(struct counter_device *const counter,
+				  struct counter_watch *const watch,
+				  const struct counter_comp_node *const cfg)
+{
+	struct counter_event_node *event_node;
+	int err = 0;
+	struct counter_comp_node *comp_node;
+
+	/* Search for event in the list */
+	list_for_each_entry(event_node, &counter->next_events_list, l)
+		if (event_node->event == watch->event &&
+		    event_node->channel == watch->channel)
+			break;
+
+	/* If event is not already in the list */
+	if (&event_node->l == &counter->next_events_list) {
+		/* Allocate new event node */
+		event_node = kmalloc(sizeof(*event_node), GFP_KERNEL);
+		if (!event_node)
+			return -ENOMEM;
+
+		/* Configure event node and add to the list */
+		event_node->event = watch->event;
+		event_node->channel = watch->channel;
+		INIT_LIST_HEAD(&event_node->comp_list);
+		list_add(&event_node->l, &counter->next_events_list);
+	}
+
+	/* Check if component watch has already been set before */
+	list_for_each_entry(comp_node, &event_node->comp_list, l)
+		if (comp_node->parent == cfg->parent &&
+		    comp_node->comp.count_u8_read == cfg->comp.count_u8_read) {
+			err = -EINVAL;
+			goto exit_free_event_node;
+		}
+
+	/* Allocate component node */
+	comp_node = kmalloc(sizeof(*comp_node), GFP_KERNEL);
+	if (!comp_node) {
+		err = -ENOMEM;
+		goto exit_free_event_node;
+	}
+	*comp_node = *cfg;
+
+	/* Add component node to event node */
+	list_add_tail(&comp_node->l, &event_node->comp_list);
+
+exit_free_event_node:
+	/* Free event node if no one else is watching */
+	if (list_empty(&event_node->comp_list)) {
+		list_del(&event_node->l);
+		kfree(event_node);
+	}
+
+	return err;
+}
+
+static int counter_enable_events(struct counter_device *const counter)
+{
+	unsigned long flags;
+	int err = 0;
+
+	mutex_lock(&counter->n_events_list_lock);
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	counter_events_list_free(&counter->events_list);
+	list_replace_init(&counter->next_events_list,
+			  &counter->events_list);
+
+	if (counter->ops->events_configure)
+		err = counter->ops->events_configure(counter);
+
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static int counter_disable_events(struct counter_device *const counter)
+{
+	unsigned long flags;
+	int err = 0;
+
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	counter_events_list_free(&counter->events_list);
+
+	if (counter->ops->events_configure)
+		err = counter->ops->events_configure(counter);
+
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+
+	mutex_lock(&counter->n_events_list_lock);
+
+	counter_events_list_free(&counter->next_events_list);
+
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static int counter_add_watch(struct counter_device *const counter,
+			     const unsigned long arg)
+{
+	void __user *const uwatch = (void __user *)arg;
+	struct counter_watch watch;
+	struct counter_comp_node comp_node = {};
+	size_t parent, id;
+	struct counter_comp *ext;
+	size_t num_ext;
+	int err = 0;
+
+	if (copy_from_user(&watch, uwatch, sizeof(watch)))
+		return -EFAULT;
+
+	if (watch.component.type == COUNTER_COMPONENT_NONE)
+		goto no_component;
+
+	parent = watch.component.parent;
+
+	/* Configure parent component info for comp node */
+	switch (watch.component.scope) {
+	case COUNTER_SCOPE_DEVICE:
+		ext = counter->ext;
+		num_ext = counter->num_ext;
+		break;
+	case COUNTER_SCOPE_SIGNAL:
+		if (parent >= counter->num_signals)
+			return -EINVAL;
+		parent = array_index_nospec(parent, counter->num_signals);
+
+		comp_node.parent = counter->signals + parent;
+
+		ext = counter->signals[parent].ext;
+		num_ext = counter->signals[parent].num_ext;
+		break;
+	case COUNTER_SCOPE_COUNT:
+		if (parent >= counter->num_counts)
+			return -EINVAL;
+		parent = array_index_nospec(parent, counter->num_counts);
+
+		comp_node.parent = counter->counts + parent;
+
+		ext = counter->counts[parent].ext;
+		num_ext = counter->counts[parent].num_ext;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	id = watch.component.id;
+
+	/* Configure component info for comp node */
+	switch (watch.component.type) {
+	case COUNTER_COMPONENT_SIGNAL:
+		if (watch.component.scope != COUNTER_SCOPE_SIGNAL)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_SIGNAL_LEVEL;
+		comp_node.comp.signal_u32_read = counter->ops->signal_read;
+		break;
+	case COUNTER_COMPONENT_COUNT:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_U64;
+		comp_node.comp.count_u64_read = counter->ops->count_read;
+		break;
+	case COUNTER_COMPONENT_FUNCTION:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_FUNCTION;
+		comp_node.comp.count_u32_read = counter->ops->function_read;
+		break;
+	case COUNTER_COMPONENT_SYNAPSE_ACTION:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+		if (id >= counter->counts[parent].num_synapses)
+			return -EINVAL;
+		id = array_index_nospec(id, counter->counts[parent].num_synapses);
+
+		comp_node.comp.type = COUNTER_COMP_SYNAPSE_ACTION;
+		comp_node.comp.action_read = counter->ops->action_read;
+		comp_node.comp.priv = counter->counts[parent].synapses + id;
+		break;
+	case COUNTER_COMPONENT_EXTENSION:
+		if (id >= num_ext)
+			return -EINVAL;
+		id = array_index_nospec(id, num_ext);
+
+		comp_node.comp = ext[id];
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* Check if any read callback is set; this is part of a union */
+	if (!comp_node.comp.count_u8_read)
+		return -EOPNOTSUPP;
+
+no_component:
+	mutex_lock(&counter->n_events_list_lock);
+
+	if (counter->ops->watch_validate) {
+		err = counter->ops->watch_validate(counter, &watch);
+		if (err < 0)
+			goto err_exit;
+	}
+
+	comp_node.component = watch.component;
+
+	err = counter_set_event_node(counter, &watch, &comp_node);
+
+err_exit:
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static long counter_chrdev_ioctl(struct file *filp, unsigned int cmd,
+				 unsigned long arg)
+{
+	struct counter_device *const counter = filp->private_data;
+	int ret = -ENODEV;
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	if (!counter->ops)
+		goto out_unlock;
+
+	switch (cmd) {
+	case COUNTER_ADD_WATCH_IOCTL:
+		ret = counter_add_watch(counter, arg);
+		break;
+	case COUNTER_ENABLE_EVENTS_IOCTL:
+		ret = counter_enable_events(counter);
+		break;
+	case COUNTER_DISABLE_EVENTS_IOCTL:
+		ret = counter_disable_events(counter);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+out_unlock:
+	mutex_unlock(&counter->ops_exist_lock);
+
+	return ret;
+}
+
+static int counter_chrdev_open(struct inode *inode, struct file *filp)
+{
+	struct counter_device *const counter = container_of(inode->i_cdev,
+							    typeof(*counter),
+							    chrdev);
+
+	if (test_and_set_bit_lock(0, counter->chrdev_lock))
+		return -EBUSY;
+
+	get_device(&counter->dev);
+	filp->private_data = counter;
+
+	return nonseekable_open(inode, filp);
+}
+
+static int counter_chrdev_release(struct inode *inode, struct file *filp)
+{
+	struct counter_device *const counter = filp->private_data;
+	int ret = 0;
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	if (!counter->ops) {
+		counter_events_list_free(&counter->events_list);
+		counter_events_list_free(&counter->next_events_list);
+		ret = -ENODEV;
+		goto out_unlock;
+	}
+
+	ret = counter_disable_events(counter);
+	if (ret < 0) {
+		mutex_unlock(&counter->ops_exist_lock);
+		return ret;
+	}
+
+out_unlock:
+	mutex_unlock(&counter->ops_exist_lock);
+
+	put_device(&counter->dev);
+	clear_bit_unlock(0, counter->chrdev_lock);
+
+	return ret;
+}
+
+static const struct file_operations counter_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.read = counter_chrdev_read,
+	.poll = counter_chrdev_poll,
+	.unlocked_ioctl = counter_chrdev_ioctl,
+	.open = counter_chrdev_open,
+	.release = counter_chrdev_release,
+};
+
+int counter_chrdev_add(struct counter_device *const counter)
+{
+	/* Initialize Counter events lists */
+	INIT_LIST_HEAD(&counter->events_list);
+	INIT_LIST_HEAD(&counter->next_events_list);
+	spin_lock_init(&counter->events_list_lock);
+	mutex_init(&counter->n_events_list_lock);
+	init_waitqueue_head(&counter->events_wait);
+	mutex_init(&counter->events_lock);
+
+	/* Initialize character device */
+	clear_bit(0, counter->chrdev_lock);
+	cdev_init(&counter->chrdev, &counter_fops);
+
+	/* Allocate Counter events queue */
+	return kfifo_alloc(&counter->events, 64, GFP_KERNEL);
+}
+
+void counter_chrdev_remove(struct counter_device *const counter)
+{
+	kfifo_free(&counter->events);
+}
+
+static int counter_get_data(struct counter_device *const counter,
+			    const struct counter_comp_node *const comp_node,
+			    u64 *const value)
+{
+	const struct counter_comp *const comp = &comp_node->comp;
+	void *const parent = comp_node->parent;
+	u8 value_u8 = 0;
+	u32 value_u32 = 0;
+	int ret;
+
+	if (comp_node->component.type == COUNTER_COMPONENT_NONE)
+		return 0;
+
+	switch (comp->type) {
+	case COUNTER_COMP_U8:
+	case COUNTER_COMP_BOOL:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			ret = comp->device_u8_read(counter, &value_u8);
+			break;
+		case COUNTER_SCOPE_SIGNAL:
+			ret = comp->signal_u8_read(counter, parent, &value_u8);
+			break;
+		case COUNTER_SCOPE_COUNT:
+			ret = comp->count_u8_read(counter, parent, &value_u8);
+			break;
+		}
+		*value = value_u8;
+		return ret;
+	case COUNTER_COMP_SIGNAL_LEVEL:
+	case COUNTER_COMP_FUNCTION:
+	case COUNTER_COMP_ENUM:
+	case COUNTER_COMP_COUNT_DIRECTION:
+	case COUNTER_COMP_COUNT_MODE:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			ret = comp->device_u32_read(counter, &value_u32);
+			break;
+		case COUNTER_SCOPE_SIGNAL:
+			ret = comp->signal_u32_read(counter, parent,
+						    &value_u32);
+			break;
+		case COUNTER_SCOPE_COUNT:
+			ret = comp->count_u32_read(counter, parent, &value_u32);
+			break;
+		}
+		*value = value_u32;
+		return ret;
+	case COUNTER_COMP_U64:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			return comp->device_u64_read(counter, value);
+		case COUNTER_SCOPE_SIGNAL:
+			return comp->signal_u64_read(counter, parent, value);
+		case COUNTER_SCOPE_COUNT:
+			return comp->count_u64_read(counter, parent, value);
+		default:
+			return -EINVAL;
+		}
+	case COUNTER_COMP_SYNAPSE_ACTION:
+		ret = comp->action_read(counter, parent, comp->priv,
+					&value_u32);
+		*value = value_u32;
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ * counter_push_event - queue event for userspace reading
+ * @counter:	pointer to Counter structure
+ * @event:	triggered event
+ * @channel:	event channel
+ *
+ * Note: If no one is watching for the respective event, it is silently
+ * discarded.
+ */
+void counter_push_event(struct counter_device *const counter, const u8 event,
+			const u8 channel)
+{
+	struct counter_event ev;
+	unsigned int copied = 0;
+	unsigned long flags;
+	struct counter_event_node *event_node;
+	struct counter_comp_node *comp_node;
+
+	ev.timestamp = ktime_get_ns();
+	ev.watch.event = event;
+	ev.watch.channel = channel;
+
+	/* Could be in an interrupt context, so use a spin lock */
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	/* Search for event in the list */
+	list_for_each_entry(event_node, &counter->events_list, l)
+		if (event_node->event == event &&
+		    event_node->channel == channel)
+			break;
+
+	/* If event is not in the list */
+	if (&event_node->l == &counter->events_list)
+		goto exit_early;
+
+	/* Read and queue relevant comp for userspace */
+	list_for_each_entry(comp_node, &event_node->comp_list, l) {
+		ev.watch.component = comp_node->component;
+		ev.status = -counter_get_data(counter, comp_node, &ev.value);
+
+		copied += kfifo_in(&counter->events, &ev, 1);
+	}
+
+exit_early:
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+
+	if (copied)
+		wake_up_poll(&counter->events_wait, EPOLLIN);
+}
+EXPORT_SYMBOL_GPL(counter_push_event);
diff --git a/drivers/counter/counter-chrdev.h b/drivers/counter/counter-chrdev.h
new file mode 100644
index 000000000000..5529d16703c4
--- /dev/null
+++ b/drivers/counter/counter-chrdev.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Counter character device interface
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#ifndef _COUNTER_CHRDEV_H_
+#define _COUNTER_CHRDEV_H_
+
+#include <linux/counter.h>
+
+int counter_chrdev_add(struct counter_device *const counter);
+void counter_chrdev_remove(struct counter_device *const counter);
+
+#endif /* _COUNTER_CHRDEV_H_ */
diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
index 9442e3b91468..bfc4119f8b4e 100644
--- a/drivers/counter/counter-core.c
+++ b/drivers/counter/counter-core.c
@@ -3,14 +3,22 @@
  * Generic Counter interface
  * Copyright (C) 2020 William Breathitt Gray
  */
+#include <linux/cdev.h>
 #include <linux/counter.h>
 #include <linux/device.h>
+#include <linux/device/bus.h>
 #include <linux/export.h>
+#include <linux/fs.h>
 #include <linux/gfp.h>
 #include <linux/idr.h>
 #include <linux/init.h>
+#include <linux/kdev_t.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/wait.h>
 
+#include "counter-chrdev.h"
 #include "counter-sysfs.h"
 
 /* Provides a unique ID for each counter device */
@@ -21,6 +29,7 @@ static void counter_device_release(struct device *dev)
 	struct counter_device *const counter = dev_get_drvdata(dev);
 
 	counter_chrdev_remove(counter);
+
 	ida_free(&counter_ida, dev->id);
 }
 
@@ -34,6 +43,8 @@ static struct bus_type counter_bus_type = {
 	.dev_name = "counter",
 };
 
+static dev_t counter_devt;
+
 /**
  * counter_register - register Counter to the system
  * @counter:	pointer to Counter to register
@@ -56,10 +67,13 @@ int counter_register(struct counter_device *const counter)
 	if (id < 0)
 		return id;
 
+	mutex_init(&counter->ops_exist_lock);
+
 	/* Configure device structure for Counter */
 	dev->id = id;
 	dev->type = &counter_device_type;
 	dev->bus = &counter_bus_type;
+	dev->devt = MKDEV(MAJOR(counter_devt), id);
 	if (counter->parent) {
 		dev->parent = counter->parent;
 		dev->of_node = counter->parent->of_node;
@@ -67,18 +81,22 @@ int counter_register(struct counter_device *const counter)
 	device_initialize(dev);
 	dev_set_drvdata(dev, counter);
 
-	/* Add Counter sysfs attributes */
-	err = counter_sysfs_add(counter);
+	err = counter_chrdev_add(counter);
 	if (err < 0)
 		goto err_free_id;
 
-	/* Add device to system */
-	err = device_add(dev);
+	err = counter_sysfs_add(counter);
 	if (err < 0)
-		goto err_free_id;
+		goto err_remove_chrdev;
+
+	err = cdev_device_add(&counter->chrdev, dev);
+	if (err < 0)
+		goto err_remove_chrdev;
 
 	return 0;
 
+err_remove_chrdev:
+	counter_chrdev_remove(counter);
 err_free_id:
 	put_device(dev);
 	return err;
@@ -96,7 +114,16 @@ void counter_unregister(struct counter_device *const counter)
 	if (!counter)
 		return;
 
-	device_unregister(&counter->dev);
+	cdev_device_del(&counter->chrdev, &counter->dev);
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	counter->ops = NULL;
+	wake_up(&counter->events_wait);
+
+	mutex_unlock(&counter->ops_exist_lock);
+
+	put_device(&counter->dev);
 }
 EXPORT_SYMBOL_GPL(counter_unregister);
 
@@ -130,13 +157,30 @@ int devm_counter_register(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_counter_register);
 
+#define COUNTER_DEV_MAX 256
+
 static int __init counter_init(void)
 {
-	return bus_register(&counter_bus_type);
+	int err;
+
+	err = bus_register(&counter_bus_type);
+	if (err < 0)
+		return err;
+
+	err = alloc_chrdev_region(&counter_devt, 0, COUNTER_DEV_MAX, "counter");
+	if (err < 0)
+		goto err_unregister_bus;
+
+	return 0;
+
+err_unregister_bus:
+	bus_unregister(&counter_bus_type);
+	return err;
 }
 
 static void __exit counter_exit(void)
 {
+	unregister_chrdev_region(counter_devt, COUNTER_DEV_MAX);
 	bus_unregister(&counter_bus_type);
 }
 
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 7c9f7e23953a..9c9984655f8c 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -6,9 +6,14 @@
 #ifndef _COUNTER_H_
 #define _COUNTER_H_
 
+#include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/kfifo.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
 #include <linux/types.h>
+#include <linux/wait.h>
 #include <uapi/linux/counter.h>
 
 struct counter_device;
@@ -199,6 +204,20 @@ struct counter_count {
 	size_t num_ext;
 };
 
+/**
+ * struct counter_event_node - Counter Event node
+ * @l:		list of current watching Counter events
+ * @event:	event that triggers
+ * @channel:	event channel
+ * @comp_list:	list of components to watch when event triggers
+ */
+struct counter_event_node {
+	struct list_head l;
+	u8 event;
+	u8 channel;
+	struct list_head comp_list;
+};
+
 /**
  * struct counter_ops - Callbacks from driver
  * @signal_read:	optional read callback for Signals. The read level of
@@ -222,6 +241,13 @@ struct counter_count {
  * @action_write:	optional write callback for Synapse action modes. The
  *			action mode to write for the respective Synapse is
  *			passed in via the action parameter.
+ * @events_configure:	optional write callback to configure events. The list of
+ *			struct counter_event_node may be accessed via the
+ *			events_list member of the counter parameter.
+ * @watch_validate:	optional callback to validate a watch. The Counter
+ *			component watch configuration is passed in via the watch
+ *			parameter. A return value of 0 indicates a valid Counter
+ *			component watch configuration.
  */
 struct counter_ops {
 	int (*signal_read)(struct counter_device *counter,
@@ -245,6 +271,9 @@ struct counter_ops {
 			    struct counter_count *count,
 			    struct counter_synapse *synapse,
 			    enum counter_synapse_action action);
+	int (*events_configure)(struct counter_device *counter);
+	int (*watch_validate)(struct counter_device *counter,
+			      const struct counter_watch *watch);
 };
 
 /**
@@ -260,6 +289,16 @@ struct counter_ops {
  * @num_ext:		number of Counter device extensions specified in @ext
  * @priv:		optional private data supplied by driver
  * @dev:		internal device structure
+ * @chrdev:		internal character device structure
+ * @events_list:	list of current watching Counter events
+ * @events_list_lock:	lock to protect Counter events list operations
+ * @next_events_list:	list of next watching Counter events
+ * @n_events_list_lock:	lock to protect Counter next events list operations
+ * @events:		queue of detected Counter events
+ * @events_wait:	wait queue to allow blocking reads of Counter events
+ * @events_lock:	lock to protect Counter events queue read operations
+ * @chrdev_lock:	lock to limit chrdev to a single open at a time
+ * @ops_exist_lock:	lock to prevent use during removal
  */
 struct counter_device {
 	const char *name;
@@ -278,12 +317,24 @@ struct counter_device {
 	void *priv;
 
 	struct device dev;
+	struct cdev chrdev;
+	struct list_head events_list;
+	spinlock_t events_list_lock;
+	struct list_head next_events_list;
+	struct mutex n_events_list_lock;
+	DECLARE_KFIFO_PTR(events, struct counter_event);
+	wait_queue_head_t events_wait;
+	struct mutex events_lock;
+	DECLARE_BITMAP(chrdev_lock, 1);
+	struct mutex ops_exist_lock;
 };
 
 int counter_register(struct counter_device *const counter);
 void counter_unregister(struct counter_device *const counter);
 int devm_counter_register(struct device *dev,
 			  struct counter_device *const counter);
+void counter_push_event(struct counter_device *const counter, const u8 event,
+			const u8 channel);
 
 #define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \
 { \
diff --git a/include/uapi/linux/counter.h b/include/uapi/linux/counter.h
index 6113938a6044..d0aa95aeff7b 100644
--- a/include/uapi/linux/counter.h
+++ b/include/uapi/linux/counter.h
@@ -6,6 +6,19 @@
 #ifndef _UAPI_COUNTER_H_
 #define _UAPI_COUNTER_H_
 
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/* Component type definitions */
+enum counter_component_type {
+	COUNTER_COMPONENT_NONE,
+	COUNTER_COMPONENT_SIGNAL,
+	COUNTER_COMPONENT_COUNT,
+	COUNTER_COMPONENT_FUNCTION,
+	COUNTER_COMPONENT_SYNAPSE_ACTION,
+	COUNTER_COMPONENT_EXTENSION,
+};
+
 /* Component scope definitions */
 enum counter_scope {
 	COUNTER_SCOPE_DEVICE,
@@ -13,6 +26,91 @@ enum counter_scope {
 	COUNTER_SCOPE_COUNT,
 };
 
+/**
+ * struct counter_component - Counter component identification
+ * @type: component type (one of enum counter_component_type)
+ * @scope: component scope (one of enum counter_scope)
+ * @parent: parent ID (matching the ID suffix of the respective parent sysfs
+ *          path as described by the ABI documentation file
+ *          Documentation/ABI/testing/sysfs-bus-counter)
+ * @id: component ID (matching the ID provided by the respective *_component_id
+ *      sysfs attribute of the desired component)
+ *
+ * For example, if the Count 2 ceiling extension of Counter device 4 is desired,
+ * set type equal to COUNTER_COMPONENT_EXTENSION, scope equal to
+ * COUNTER_COUNT_SCOPE, parent equal to 2, and id equal to the value provided by
+ * the respective /sys/bus/counter/devices/counter4/count2/ceiling_component_id
+ * sysfs attribute.
+ */
+struct counter_component {
+	__u8 type;
+	__u8 scope;
+	__u8 parent;
+	__u8 id;
+};
+
+/* Event type definitions */
+enum counter_event_type {
+	/* Count value increased past ceiling */
+	COUNTER_EVENT_OVERFLOW,
+	/* Count value decreased past floor */
+	COUNTER_EVENT_UNDERFLOW,
+	/* Count value increased past ceiling, or decreased past floor */
+	COUNTER_EVENT_OVERFLOW_UNDERFLOW,
+	/* Count value reached threshold */
+	COUNTER_EVENT_THRESHOLD,
+	/* Index signal detected */
+	COUNTER_EVENT_INDEX,
+};
+
+/**
+ * struct counter_watch - Counter component watch configuration
+ * @component: component to watch when event triggers
+ * @event: event that triggers (one of enum counter_event_type)
+ * @channel: event channel (typically 0 unless the device supports concurrent
+ *	     events of the same type)
+ */
+struct counter_watch {
+	struct counter_component component;
+	__u8 event;
+	__u8 channel;
+};
+
+/*
+ * Queues a Counter watch for the specified event.
+ *
+ * The queued watches will not be applied until COUNTER_ENABLE_EVENTS_IOCTL is
+ * called.
+ */
+#define COUNTER_ADD_WATCH_IOCTL _IOW(0x3E, 0x00, struct counter_watch)
+/*
+ * Enables monitoring the events specified by the Counter watches that were
+ * queued by COUNTER_ADD_WATCH_IOCTL.
+ *
+ * If events are already enabled, the new set of watches replaces the old one.
+ * Calling this ioctl also has the effect of clearing the queue of watches added
+ * by COUNTER_ADD_WATCH_IOCTL.
+ */
+#define COUNTER_ENABLE_EVENTS_IOCTL _IO(0x3E, 0x01)
+/*
+ * Stops monitoring the previously enabled events.
+ */
+#define COUNTER_DISABLE_EVENTS_IOCTL _IO(0x3E, 0x02)
+
+/**
+ * struct counter_event - Counter event data
+ * @timestamp: best estimate of time of event occurrence, in nanoseconds
+ * @value: component value
+ * @watch: component watch configuration
+ * @status: return status (system error number)
+ */
+struct counter_event {
+	__aligned_u64 timestamp;
+	__aligned_u64 value;
+	struct counter_watch watch;
+	__u8 status;
+};
+
 /* Count direction values */
 enum counter_count_direction {
 	COUNTER_COUNT_DIRECTION_FORWARD,
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:21 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:21 +0900
Subject: [PATCH v14 11/17] docs: counter: Document character device interface
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <b8457d92a74fb25d7c0beb769fc9c8c04a9eb3d1.1627990337.git.vilhelm.gray@gmail.com>

This patch adds high-level documentation about the Counter subsystem
character device interface.

Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/driver-api/generic-counter.rst  | 177 ++++++++++++++----
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 2 files changed, 137 insertions(+), 41 deletions(-)

diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
index f6397218aa4c..e9cb95c1c828 100644
--- a/Documentation/driver-api/generic-counter.rst
+++ b/Documentation/driver-api/generic-counter.rst
@@ -223,19 +223,6 @@ whether an input line is differential or single-ended) and instead focus
 on the core idea of what the data and process represent (e.g. position
 as interpreted from quadrature encoding data).
 
-Userspace Interface
-===================
-
-Several sysfs attributes are generated by the Generic Counter interface,
-and reside under the /sys/bus/counter/devices/counterX directory, where
-counterX refers to the respective counter device. Please see
-Documentation/ABI/testing/sysfs-bus-counter for detailed
-information on each Generic Counter interface sysfs attribute.
-
-Through these sysfs attributes, programs and scripts may interact with
-the Generic Counter paradigm Counts, Signals, and Synapses of respective
-counter devices.
-
 Driver API
 ==========
 
@@ -388,16 +375,16 @@ userspace interface components::
                         / driver callbacks /
                         -------------------
                                 |
-                +---------------+
-                |
-                V
-        +--------------------+
-        | Counter sysfs      |
-        +--------------------+
-        | Translates to the  |
-        | standard Counter   |
-        | sysfs output       |
-        +--------------------+
+                +---------------+---------------+
+                |                               |
+                V                               V
+        +--------------------+          +---------------------+
+        | Counter sysfs      |          | Counter chrdev      |
+        +--------------------+          +---------------------+
+        | Translates to the  |          | Translates to the   |
+        | standard Counter   |          | standard Counter    |
+        | sysfs output       |          | character device    |
+        +--------------------+          +---------------------+
 
 Thereafter, data can be transferred directly between the Counter device
 driver and Counter userspace interface::
@@ -428,23 +415,30 @@ driver and Counter userspace interface::
                         / u64     /
                         ----------
                                 |
-                +---------------+
-                |
-                V
-        +--------------------+
-        | Counter sysfs      |
-        +--------------------+
-        | Translates to the  |
-        | standard Counter   |
-        | sysfs output       |
-        |--------------------|
-        | Type: const char * |
-        | Value: "42"        |
-        +--------------------+
-                |
-         ---------------
-        / const char * /
-        ---------------
+                +---------------+---------------+
+                |                               |
+                V                               V
+        +--------------------+          +---------------------+
+        | Counter sysfs      |          | Counter chrdev      |
+        +--------------------+          +---------------------+
+        | Translates to the  |          | Translates to the   |
+        | standard Counter   |          | standard Counter    |
+        | sysfs output       |          | character device    |
+        |--------------------|          |---------------------|
+        | Type: const char * |          | Type: u64           |
+        | Value: "42"        |          | Value: 42           |
+        +--------------------+          +---------------------+
+                |                               |
+         ---------------                 -----------------------
+        / const char * /                / struct counter_event /
+        ---------------                 -----------------------
+                |                               |
+                |                               V
+                |                       +-----------+
+                |                       | read      |
+                |                       +-----------+
+                |                       \ Count: 42 /
+                |                        -----------
                 |
                 V
         +--------------------------------------------------+
@@ -453,7 +447,7 @@ driver and Counter userspace interface::
         \ Count: "42"                                      /
          --------------------------------------------------
 
-There are three primary components involved:
+There are four primary components involved:
 
 Counter device driver
 ---------------------
@@ -473,3 +467,104 @@ and vice versa.
 Please refer to the ``Documentation/ABI/testing/sysfs-bus-counter`` file
 for a detailed breakdown of the available Generic Counter interface
 sysfs attributes.
+
+Counter chrdev
+--------------
+Translates counter data to the standard Counter character device; data
+is transferred via standard character device read calls, while Counter
+events are configured via ioctl calls.
+
+Sysfs Interface
+===============
+
+Several sysfs attributes are generated by the Generic Counter interface,
+and reside under the ``/sys/bus/counter/devices/counterX`` directory,
+where ``X`` is to the respective counter device id. Please see
+``Documentation/ABI/testing/sysfs-bus-counter`` for detailed information
+on each Generic Counter interface sysfs attribute.
+
+Through these sysfs attributes, programs and scripts may interact with
+the Generic Counter paradigm Counts, Signals, and Synapses of respective
+counter devices.
+
+Counter Character Device
+========================
+
+Counter character device nodes are created under the ``/dev`` directory
+as ``counterX``, where ``X`` is the respective counter device id.
+Defines for the standard Counter data types are exposed via the
+userspace ``include/uapi/linux/counter.h`` file.
+
+Counter events
+--------------
+Counter device drivers can support Counter events by utilizing the
+``counter_push_event`` function::
+
+        void counter_push_event(struct counter_device *const counter, const u8 event,
+                                const u8 channel);
+
+The event id is specified by the ``event`` parameter; the event channel
+id is specified by the ``channel`` parameter. When this function is
+called, the Counter data associated with the respective event is
+gathered, and a ``struct counter_event`` is generated for each datum and
+pushed to userspace.
+
+Counter events can be configured by users to report various Counter
+data of interest. This can be conceptualized as a list of Counter
+component read calls to perform. For example:
+
+        +-------------------------------------------------+
+        | COUNTER_EVENT_OVERFLOW | COUNTER_EVENT_INDEX    |
+        +========================+========================+
+        | Channel 0              | Channel 0              |
+        +------------------------+------------------------+
+        | * Count 0              | * Signal 0             |
+        | * Count 1              | * Signal 0 Extension 0 |
+        | * Signal 3             | * Extension 4          |
+        | * Count 4 Extension 2  +------------------------+
+        | * Signal 5 Extension 0 | Channel 1              |
+        |                        +------------------------+
+        |                        | * Signal 4             |
+        |                        | * Signal 4 Extension 0 |
+        |                        | * Count 7              |
+        +------------------------+------------------------+
+
+When ``counter_push_event(counter, COUNTER_EVENT_INDEX, 1)`` is called
+for example, it will go down the list for the ``COUNTER_EVENT_INDEX``
+event channel 1 and execute the read callbacks for Signal 4, Signal 4
+Extension 0, and Count 4 -- the data returned for each is pushed to a
+kfifo as a ``struct counter_event``, which userspace can retrieve via a
+standard read operation on the respective character device node.
+
+Userspace
+---------
+Userspace applications can configure Counter events via ioctl operations
+on the Counter character device node. There following ioctl codes are
+supported and provided by the ``linux/counter.h`` userspace header file:
+
+* :c:macro:`COUNTER_ADD_WATCH_IOCTL`
+
+* :c:macro:`COUNTER_ENABLE_EVENTS_IOCTL`
+
+* :c:macro:`COUNTER_DISABLE_EVENTS_IOCTL`
+
+To configure events to gather Counter data, users first populate a
+``struct counter_watch`` with the relevant event id, event channel id,
+and the information for the desired Counter component from which to
+read, and then pass it via the ``COUNTER_ADD_WATCH_IOCTL`` ioctl
+command.
+
+Note that an event can be watched without gathering Counter data by
+setting the ``component.type`` member equal to
+``COUNTER_COMPONENT_NONE``. With this configuration the Counter
+character device will simply populate the event timestamps for those
+respective ``struct counter_event`` elements and ignore the component
+value.
+
+The ``COUNTER_ADD_WATCH_IOCTL`` command will buffer these Counter
+watches. When ready, the ``COUNTER_ENABLE_EVENTS_IOCTL`` ioctl command
+may be used to activate these Counter watches.
+
+Userspace applications can then execute a ``read`` operation (optionally
+calling ``poll`` first) on the Counter character device node to retrieve
+``struct counter_event`` elements with the desired data.
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 1409e40e6345..fc4ccc79b1b8 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -88,6 +88,7 @@ Code  Seq#    Include File                                           Comments
                                                                      <http://infiniband.sourceforge.net/>
 0x20  all    drivers/cdrom/cm206.h
 0x22  all    scsi/sg.h
+0x3E  00-0F  linux/counter.h                                         <mailto:linux-iio at vger.kernel.org>
 '!'   00-1F  uapi/linux/seccomp.h
 '#'   00-3F                                                          IEEE 1394 Subsystem
                                                                      Block for the entire subsystem
-- 
2.32.0



From patrice.chotard at foss.st.com  Tue Aug  3 05:07:40 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:07:40 +0200
Subject: [PATCH v3 09/13] ARM: dts: sti: update clkgen-fsyn entries in
 stih418-clock
In-Reply-To: <20210331204228.26107-10-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-10-avolmat@me.com>
Message-ID: <309611a8-0e71-9683-c38e-afa435c8f89d@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The clkgen-fsyn driver now embed the clock names (assuming the
> right compatible is used). Remove all clock-output-names property
> and update when necessary the compatible.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih418-clock.dtsi | 26 +++-----------------------
>  1 file changed, 3 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
> index d628e656458d..e84c476b83ed 100644
> --- a/arch/arm/boot/dts/stih418-clock.dtsi
> +++ b/arch/arm/boot/dts/stih418-clock.dtsi
> @@ -94,11 +94,6 @@
>  			reg = <0x9103000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-c0-fs0-ch0",
> -					     "clk-s-c0-fs0-ch1",
> -					     "clk-s-c0-fs0-ch2",
> -					     "clk-s-c0-fs0-ch3";
>  		};
>  
>  		clk_s_c0: clockgen-c at 9103000 {
> @@ -150,15 +145,10 @@
>  
>  		clk_s_d0_quadfs: clk-s-d0-quadfs at 9104000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d0";
>  			reg = <0x9104000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d0-fs0-ch0",
> -					     "clk-s-d0-fs0-ch1",
> -					     "clk-s-d0-fs0-ch2",
> -					     "clk-s-d0-fs0-ch3";
>  		};
>  
>  		clockgen-d0 at 9104000 {
> @@ -179,15 +169,10 @@
>  
>  		clk_s_d2_quadfs: clk-s-d2-quadfs at 9106000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d2";
>  			reg = <0x9106000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d2-fs0-ch0",
> -					     "clk-s-d2-fs0-ch1",
> -					     "clk-s-d2-fs0-ch2",
> -					     "clk-s-d2-fs0-ch3";
>  		};
>  
>  		clockgen-d2 at 9106000 {
> @@ -210,15 +195,10 @@
>  
>  		clk_s_d3_quadfs: clk-s-d3-quadfs at 9107000 {
>  			#clock-cells = <1>;
> -			compatible = "st,quadfs";
> +			compatible = "st,quadfs-d3";
>  			reg = <0x9107000 0x1000>;
>  
>  			clocks = <&clk_sysin>;
> -
> -			clock-output-names = "clk-s-d3-fs0-ch0",
> -					     "clk-s-d3-fs0-ch1",
> -					     "clk-s-d3-fs0-ch2",
> -					     "clk-s-d3-fs0-ch3";
>  		};
>  
>  		clockgen-d3 at 9107000 {
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From vilhelm.gray at gmail.com  Tue Aug  3 05:06:22 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:22 +0900
Subject: [PATCH v14 12/17] tools/counter: Create Counter tools
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <fd51641e28c1517dc6b4a172cc032d1a1b9d47ca.1627990337.git.vilhelm.gray@gmail.com>

This creates an example Counter program under tools/counter/*
to exemplify the Counter character device interface.

Cc: Pavel Machek <pavel at ucw.cz>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 MAINTAINERS                     |  1 +
 tools/Makefile                  | 13 ++---
 tools/counter/Build             |  1 +
 tools/counter/Makefile          | 53 +++++++++++++++++++
 tools/counter/counter_example.c | 93 +++++++++++++++++++++++++++++++++
 5 files changed, 155 insertions(+), 6 deletions(-)
 create mode 100644 tools/counter/Build
 create mode 100644 tools/counter/Makefile
 create mode 100644 tools/counter/counter_example.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c0817c45401d..b6e809c269a5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4765,6 +4765,7 @@ F:	Documentation/driver-api/generic-counter.rst
 F:	drivers/counter/
 F:	include/linux/counter.h
 F:	include/uapi/linux/counter.h
+F:	tools/counter/
 
 CP2615 I2C DRIVER
 M:	Bence Cs?k?s <bence98 at sch.bme.hu>
diff --git a/tools/Makefile b/tools/Makefile
index 7e9d34ddd74c..5da1fde03a9a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -12,6 +12,7 @@ help:
 	@echo '  acpi                   - ACPI tools'
 	@echo '  bpf                    - misc BPF tools'
 	@echo '  cgroup                 - cgroup tools'
+	@echo '  counter                - counter tools'
 	@echo '  cpupower               - a tool for all things x86 CPU power'
 	@echo '  debugging              - tools for debugging'
 	@echo '  firewire               - the userspace part of nosy, an IEEE-1394 traffic sniffer'
@@ -65,7 +66,7 @@ acpi: FORCE
 cpupower: FORCE
 	$(call descend,power/$@)
 
-cgroup firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
+cgroup counter firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
 	$(call descend,$@)
 
 bpf/%: FORCE
@@ -100,7 +101,7 @@ freefall: FORCE
 kvm_stat: FORCE
 	$(call descend,kvm/$@)
 
-all: acpi cgroup cpupower gpio hv firewire liblockdep \
+all: acpi cgroup counter cpupower gpio hv firewire liblockdep \
 		perf selftests bootconfig spi turbostat usb \
 		virtio vm bpf x86_energy_perf_policy \
 		tmon freefall iio objtool kvm_stat wmi \
@@ -112,7 +113,7 @@ acpi_install:
 cpupower_install:
 	$(call descend,power/$(@:_install=),install)
 
-cgroup_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
+cgroup_install counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
 	$(call descend,$(@:_install=),install)
 
 liblockdep_install:
@@ -133,7 +134,7 @@ freefall_install:
 kvm_stat_install:
 	$(call descend,kvm/$(@:_install=),install)
 
-install: acpi_install cgroup_install cpupower_install gpio_install \
+install: acpi_install cgroup_install counter_install cpupower_install gpio_install \
 		hv_install firewire_install iio_install liblockdep_install \
 		perf_install selftests_install turbostat_install usb_install \
 		virtio_install vm_install bpf_install x86_energy_perf_policy_install \
@@ -147,7 +148,7 @@ acpi_clean:
 cpupower_clean:
 	$(call descend,power/cpupower,clean)
 
-cgroup_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
+cgroup_clean counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
 	$(call descend,$(@:_clean=),clean)
 
 liblockdep_clean:
@@ -181,7 +182,7 @@ freefall_clean:
 build_clean:
 	$(call descend,build,clean)
 
-clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
+clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_clean \
 		perf_clean selftests_clean turbostat_clean bootconfig_clean spi_clean usb_clean virtio_clean \
 		vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
 		freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \
diff --git a/tools/counter/Build b/tools/counter/Build
new file mode 100644
index 000000000000..33f4a51d715e
--- /dev/null
+++ b/tools/counter/Build
@@ -0,0 +1 @@
+counter_example-y += counter_example.o
diff --git a/tools/counter/Makefile b/tools/counter/Makefile
new file mode 100644
index 000000000000..5ebc195fd9c0
--- /dev/null
+++ b/tools/counter/Makefile
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: GPL-2.0
+include ../scripts/Makefile.include
+
+bindir ?= /usr/bin
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+endif
+
+# Do not use make's built-in rules
+# (this improves performance and avoids hard-to-debug behaviour);
+MAKEFLAGS += -r
+
+override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
+
+ALL_TARGETS := counter_example
+ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
+
+all: $(ALL_PROGRAMS)
+
+export srctree OUTPUT CC LD CFLAGS
+include $(srctree)/tools/build/Makefile.include
+
+#
+# We need the following to be outside of kernel tree
+#
+$(OUTPUT)include/linux/counter.h: ../../include/uapi/linux/counter.h
+	mkdir -p $(OUTPUT)include/linux 2>&1 || true
+	ln -sf $(CURDIR)/../../include/uapi/linux/counter.h $@
+
+prepare: $(OUTPUT)include/linux/counter.h
+
+COUNTER_EXAMPLE := $(OUTPUT)counter_example.o
+$(COUNTER_EXAMPLE): prepare FORCE
+	$(Q)$(MAKE) $(build)=counter_example
+$(OUTPUT)counter_example: $(COUNTER_EXAMPLE)
+	$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+
+clean:
+	rm -f $(ALL_PROGRAMS)
+	rm -rf $(OUTPUT)include/linux/counter.h
+	find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
+
+install: $(ALL_PROGRAMS)
+	install -d -m 755 $(DESTDIR)$(bindir);		\
+	for program in $(ALL_PROGRAMS); do		\
+		install $$program $(DESTDIR)$(bindir);	\
+	done
+
+FORCE:
+
+.PHONY: all install clean FORCE prepare
diff --git a/tools/counter/counter_example.c b/tools/counter/counter_example.c
new file mode 100644
index 000000000000..90d69fb9463b
--- /dev/null
+++ b/tools/counter/counter_example.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Counter - example userspace application
+ *
+ * The userspace application opens /dev/counter0, configures the
+ * COUNTER_EVENT_INDEX event channel 0 to gather Count 0 count and Count
+ * 1 count, and prints out the data as it becomes available on the
+ * character device node.
+ *
+ * Copyright (C) 2021 William Breathitt Gray
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/counter.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+static struct counter_watch watches[2] = {
+	{
+		/* Component data: Count 0 count */
+		.component.type = COUNTER_COMPONENT_COUNT,
+		.component.scope = COUNTER_SCOPE_COUNT,
+		.component.parent = 0,
+		/* Event type: Index */
+		.event = COUNTER_EVENT_INDEX,
+		/* Device event channel 0 */
+		.channel = 0,
+	},
+	{
+		/* Component data: Count 1 count */
+		.component.type = COUNTER_COMPONENT_COUNT,
+		.component.scope = COUNTER_SCOPE_COUNT,
+		.component.parent = 1,
+		/* Event type: Index */
+		.event = COUNTER_EVENT_INDEX,
+		/* Device event channel 0 */
+		.channel = 0,
+	},
+};
+
+int main(void)
+{
+	int fd;
+	int ret;
+	struct counter_event event_data[2];
+
+	fd = open("/dev/counter0", O_RDWR);
+	if (fd == -1) {
+		perror("Unable to open /dev/counter0");
+		return -errno;
+	}
+
+	ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches);
+	if (ret == -1) {
+		perror("Error adding watches[0]");
+		return -errno;
+	}
+	ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + 1);
+	if (ret == -1) {
+		perror("Error adding watches[1]");
+		return -errno;
+	}
+	ret = ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
+	if (ret == -1) {
+		perror("Error enabling events");
+		return -errno;
+	}
+
+	for (;;) {
+		ret = read(fd, event_data, sizeof(event_data));
+		if (ret == -1) {
+			perror("Failed to read event data");
+			return 1;
+		}
+
+		if (ret != sizeof(event_data)) {
+			fprintf(stderr, "Failed to read event data\n");
+			return -EIO;
+		}
+
+		printf("Timestamp 0: %llu\tCount 0: %llu\n"
+		       "Error Message 0: %s\n"
+		       "Timestamp 1: %llu\tCount 1: %llu\n"
+		       "Error Message 1: %s\n",
+		       event_data[0].timestamp, event_data[0].value,
+		       strerror(event_data[0].status),
+		       event_data[1].timestamp, event_data[1].value,
+		       strerror(event_data[1].status));
+	}
+
+	return 0;
+}
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:23 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:23 +0900
Subject: [PATCH v14 13/17] counter: Implement signalZ_action_component_id
 sysfs attribute
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <7a9fc7e7272650e0d43b23a6ba65bffe889f4c86.1627990337.git.vilhelm.gray@gmail.com>

The Generic Counter chrdev interface expects users to supply component
IDs in order to select Synapses for requests. In order for users to know
what component ID belongs to which Synapse this information must be
exposed. The signalZ_action_component_id attribute provides a way for
users to discover what component ID belongs to the respective Synapse.

Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter |  7 ++++
 drivers/counter/counter-sysfs.c             | 46 ++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index dee79b606847..9809d8a47431 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -203,6 +203,13 @@ Description:
 		both edges:
 			Any state transition.
 
+What:		/sys/bus/counter/devices/counterX/countY/signalZ_action_component_id
+KernelVersion:	5.15
+Contact:	linux-iio at vger.kernel.org
+Description:
+		Read-only attribute that indicates the component ID of the
+		respective Synapse of Count Y for Signal Z.
+
 What:		/sys/bus/counter/devices/counterX/countY/spike_filter_ns
 KernelVersion:	5.14
 Contact:	linux-iio at vger.kernel.org
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index dbb507c9da11..11bef9f8190f 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -393,7 +393,6 @@ static int counter_avail_attr_create(struct device *const dev,
 	struct counter_attribute *counter_attr;
 	struct device_attribute *dev_attr;
 
-	/* Allocate Counter attribute */
 	counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL);
 	if (!counter_attr)
 		return -ENOMEM;
@@ -535,6 +534,46 @@ static int counter_name_attr_create(struct device *const dev,
 	return 0;
 }
 
+static ssize_t counter_comp_id_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	const size_t id = (size_t)to_counter_attribute(attr)->comp.priv;
+
+	return sprintf(buf, "%zu\n", id);
+}
+
+static int counter_comp_id_attr_create(struct device *const dev,
+				       struct counter_attribute_group *const group,
+				       const char *name, const size_t id)
+{
+	struct counter_attribute *counter_attr;
+
+	/* Allocate Counter attribute */
+	counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL);
+	if (!counter_attr)
+		return -ENOMEM;
+
+	/* Generate component ID name */
+	name = devm_kasprintf(dev, GFP_KERNEL, "%s_component_id", name);
+	if (!name)
+		return -ENOMEM;
+
+	/* Configure Counter attribute */
+	counter_attr->comp.priv = (void *)id;
+
+	/* Configure device attribute */
+	sysfs_attr_init(&counter_attr->dev_attr.attr);
+	counter_attr->dev_attr.attr.name = name;
+	counter_attr->dev_attr.attr.mode = 0444;
+	counter_attr->dev_attr.show = counter_comp_id_show;
+
+	/* Store list node */
+	list_add(&counter_attr->l, &group->attr_list);
+	group->num_attr++;
+
+	return 0;
+}
+
 static struct counter_comp counter_signal_comp = {
 	.type = COUNTER_COMP_SIGNAL_LEVEL,
 	.name = "signal",
@@ -629,6 +668,11 @@ static int counter_sysfs_synapses_add(struct counter_device *const counter,
 					  COUNTER_SCOPE_COUNT, count);
 		if (err < 0)
 			return err;
+
+		/* Create Synapse component ID attribute */
+		err = counter_comp_id_attr_create(dev, group, comp.name, i);
+		if (err < 0)
+			return err;
 	}
 
 	return 0;
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:24 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:24 +0900
Subject: [PATCH v14 14/17] counter: Implement *_component_id sysfs attributes
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <8c0a574f52b6b42961c7c0aed6bca9a35339a0f4.1627990337.git.vilhelm.gray@gmail.com>

The Generic Counter chrdev interface expects users to supply component
IDs in order to select extensions for requests. In order for users to
know what component ID belongs to which extension this information must
be exposed. The *_component_id attribute provides a way for users to
discover what component ID belongs to which respective extension.

Cc: David Lechner <david at lechnology.com>
Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter | 16 +++++++++-
 drivers/counter/counter-sysfs.c             | 33 +++++++++++++++++----
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index 9809d8a47431..e0e99adb0ecc 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -203,12 +203,26 @@ Description:
 		both edges:
 			Any state transition.
 
+What:		/sys/bus/counter/devices/counterX/countY/ceiling_component_id
+What:		/sys/bus/counter/devices/counterX/countY/floor_component_id
+What:		/sys/bus/counter/devices/counterX/countY/count_mode_component_id
+What:		/sys/bus/counter/devices/counterX/countY/direction_component_id
+What:		/sys/bus/counter/devices/counterX/countY/enable_component_id
+What:		/sys/bus/counter/devices/counterX/countY/error_noise_component_id
+What:		/sys/bus/counter/devices/counterX/countY/prescaler_component_id
+What:		/sys/bus/counter/devices/counterX/countY/preset_component_id
+What:		/sys/bus/counter/devices/counterX/countY/preset_enable_component_id
 What:		/sys/bus/counter/devices/counterX/countY/signalZ_action_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/cable_fault_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/cable_fault_enable_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/filter_clock_prescaler_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/index_polarity_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/synchronous_mode_component_id
 KernelVersion:	5.15
 Contact:	linux-iio at vger.kernel.org
 Description:
 		Read-only attribute that indicates the component ID of the
-		respective Synapse of Count Y for Signal Z.
+		respective extension or Synapse.
 
 What:		/sys/bus/counter/devices/counterX/countY/spike_filter_ns
 KernelVersion:	5.14
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index 11bef9f8190f..df1d75e0d7b8 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -588,6 +588,7 @@ static int counter_signal_attrs_create(struct counter_device *const counter,
 	int err;
 	struct counter_comp comp;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Create main Signal attribute */
 	comp = counter_signal_comp;
@@ -603,8 +604,14 @@ static int counter_signal_attrs_create(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < signal->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, signal->ext + i,
-					  scope, signal);
+		ext = &signal->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, signal);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
@@ -695,6 +702,7 @@ static int counter_count_attrs_create(struct counter_device *const counter,
 	int err;
 	struct counter_comp comp;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Create main Count attribute */
 	comp = counter_count_comp;
@@ -719,8 +727,14 @@ static int counter_count_attrs_create(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < count->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, count->ext + i,
-					  scope, count);
+		ext = &count->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, count);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
@@ -784,6 +798,7 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 	struct device *const dev = &counter->dev;
 	int err;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Add Signals sysfs attributes */
 	err = counter_sysfs_signals_add(counter, cattr_group);
@@ -816,8 +831,14 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < counter->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, counter->ext + i,
-					  scope, NULL);
+		ext = &counter->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, NULL);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
-- 
2.32.0



From joey.gouly at arm.com  Tue Aug  3 05:07:34 2021
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 3 Aug 2021 13:07:34 +0100
Subject: [PATCH 1/4] arm64: entry: consolidate entry/exit helpers
In-Reply-To: <20210802140733.52716-2-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
 <20210802140733.52716-2-mark.rutland@arm.com>
Message-ID: <20210803120734.GC52119@e124191.cambridge.arm.com>

On Mon, Aug 02, 2021 at 03:07:30PM +0100, Mark Rutland wrote:
> To make the various entry/exit helpers easier to understand and easier
> to compare, this patch moves all the entry/exit helpers to be adjacent
> at the top of entry-common.c, rather than being spread out throughout
> the file.
> 
> There should be no functional change as a result of this patch.
> 

Reviewed-by: Joey Gouly <joey.gouly at arm.com>


From vilhelm.gray at gmail.com  Tue Aug  3 05:06:25 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:25 +0900
Subject: [PATCH v14 15/17] counter: Implement events_queue_size sysfs attribute
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <f96446090ae4a671ca310a01920eaf4db70bfc84.1627990337.git.vilhelm.gray@gmail.com>

The events_queue_size sysfs attribute provides a way for users to
dynamically configure the Counter events queue size for the Counter
character device interface. The size is in number of struct
counter_event data structures. The number of elements will be rounded-up
to a power of 2 due to a requirement of the kfifo_alloc function called
during reallocation of the queue.

Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter |  8 ++++
 drivers/counter/counter-sysfs.c             | 45 +++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index e0e99adb0ecc..84ebb1ed28ed 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -233,6 +233,14 @@ Description:
 		shorter or equal to configured value are ignored. Value 0 means
 		filter is disabled.
 
+What:		/sys/bus/counter/devices/counterX/events_queue_size
+KernelVersion:	5.15
+Contact:	linux-iio at vger.kernel.org
+Description:
+		Size of the Counter events queue in number of struct
+		counter_event data structures. The number of elements will be
+		rounded-up to a power of 2.
+
 What:		/sys/bus/counter/devices/counterX/name
 KernelVersion:	5.2
 Contact:	linux-iio at vger.kernel.org
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index df1d75e0d7b8..d2d6495f73c5 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -3,11 +3,13 @@
  * Generic Counter sysfs interface
  * Copyright (C) 2020 William Breathitt Gray
  */
+#include <linux/bitops.h>
 #include <linux/counter.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/gfp.h>
 #include <linux/kernel.h>
+#include <linux/kfifo.h>
 #include <linux/kstrtox.h>
 #include <linux/list.h>
 #include <linux/string.h>
@@ -785,12 +787,49 @@ static int counter_num_counts_read(struct counter_device *counter, u8 *val)
 	return 0;
 }
 
+static int counter_events_queue_size_read(struct counter_device *counter,
+					  u64 *val)
+{
+	*val = kfifo_size(&counter->events);
+	return 0;
+}
+
+static int counter_events_queue_size_write(struct counter_device *counter,
+					   u64 val)
+{
+	DECLARE_KFIFO_PTR(events, struct counter_event);
+	int err = 0;
+
+	/* Verify chrdev is not currently being used */
+	if (test_and_set_bit_lock(0, counter->chrdev_lock))
+		return -EBUSY;
+
+	/* Allocate new events queue */
+	err = kfifo_alloc(&events, val, GFP_KERNEL);
+	if (err)
+		goto exit_early;
+
+	/* Swap in new events queue */
+	kfifo_free(&counter->events);
+	counter->events.kfifo = events.kfifo;
+
+exit_early:
+	clear_bit_unlock(0, counter->chrdev_lock);
+
+	return err;
+}
+
 static struct counter_comp counter_num_signals_comp =
 	COUNTER_COMP_DEVICE_U8("num_signals", counter_num_signals_read, NULL);
 
 static struct counter_comp counter_num_counts_comp =
 	COUNTER_COMP_DEVICE_U8("num_counts", counter_num_counts_read, NULL);
 
+static struct counter_comp counter_events_queue_size_comp =
+	COUNTER_COMP_DEVICE_U64("events_queue_size",
+				counter_events_queue_size_read,
+				counter_events_queue_size_write);
+
 static int counter_sysfs_attr_add(struct counter_device *const counter,
 				  struct counter_attribute_group *cattr_group)
 {
@@ -829,6 +868,12 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 	if (err < 0)
 		return err;
 
+	/* Create events_queue_size attribute */
+	err = counter_attr_create(dev, cattr_group,
+				  &counter_events_queue_size_comp, scope, NULL);
+	if (err < 0)
+		return err;
+
 	/* Create an attribute for each extension */
 	for (i = 0; i < counter->num_ext; i++) {
 		ext = &counter->ext[i];
-- 
2.32.0



From patrice.chotard at foss.st.com  Tue Aug  3 05:08:05 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:08:05 +0200
Subject: [PATCH v3 10/13] ARM: dts: sti: add the spinor controller node
 within stih407-family
In-Reply-To: <20210331204228.26107-11-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-11-avolmat@me.com>
Message-ID: <2ddabd06-d247-5486-979c-b9df2f596490@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The STiH407 family (and further versions STiH410/STiH418) embedded
> a serial flash controller allowing fast access to SPI-NOR.
> This commit adds the corresponding node, relying on the st-spi-fsm
> drivers.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
> v2: commit log improvement
> 
>  arch/arm/boot/dts/stih407-family.dtsi | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 23a1746f3baa..21f3347a91d6 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -616,6 +616,21 @@
>  			st,lpc-mode = <ST_LPC_MODE_CLKSRC>;
>  		};
>  
> +		spifsm: spifsm at 9022000{
> +			compatible = "st,spi-fsm";
> +			reg = <0x9022000 0x1000>;
> +			reg-names = "spi-fsm";
> +			clocks = <&clk_s_c0_flexgen CLK_FLASH_PROMIP>;
> +			clock-names = "emi_clk";
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_fsm>;
> +			st,syscfg = <&syscfg_core>;
> +			st,boot-device-reg = <0x8c4>;
> +			st,boot-device-spi = <0x68>;
> +
> +			status = "disabled";
> +		};
> +
>  		sata0: sata at 9b20000 {
>  			compatible = "st,ahci";
>  			reg = <0x9b20000 0x1000>;
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From vilhelm.gray at gmail.com  Tue Aug  3 05:06:26 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:26 +0900
Subject: [PATCH v14 16/17] counter: 104-quad-8: Replace mutex with spinlock
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <84a8ebac37852c7660afa462e8ba982ea3e5bc2d.1627990337.git.vilhelm.gray@gmail.com>

This patch replaces the mutex I/O lock with a spinlock. This is in
preparation for a subsequent patch adding IRQ support for 104-QUAD-8
devices; we can't sleep in an interrupt context, so we'll need to use a
spinlock instead.

Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c | 90 +++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 37 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index d1161c27c488..a56751bf1e9b 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/types.h>
+#include <linux/spinlock.h>
 
 #define QUAD8_EXTENT 32
 
@@ -28,6 +29,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
 
 /**
  * struct quad8 - device private data structure
+ * @lock:		lock to prevent clobbering device states during R/W ops
  * @counter:		instance of the counter_device
  * @fck_prescaler:	array of filter clock prescaler configurations
  * @preset:		array of preset values
@@ -42,7 +44,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
  * @base:		base port address of the device
  */
 struct quad8 {
-	struct mutex lock;
+	spinlock_t lock;
 	struct counter_device counter;
 	unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
 	unsigned int preset[QUAD8_NUM_COUNTERS];
@@ -123,6 +125,7 @@ static int quad8_count_read(struct counter_device *counter,
 	unsigned int flags;
 	unsigned int borrow;
 	unsigned int carry;
+	unsigned long irqflags;
 	int i;
 
 	flags = inb(base_offset + 1);
@@ -132,7 +135,7 @@ static int quad8_count_read(struct counter_device *counter,
 	/* Borrow XOR Carry effectively doubles count range */
 	*val = (unsigned long)(borrow ^ carry) << 24;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Reset Byte Pointer; transfer Counter to Output Latch */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
@@ -141,7 +144,7 @@ static int quad8_count_read(struct counter_device *counter,
 	for (i = 0; i < 3; i++)
 		*val |= (unsigned long)inb(base_offset) << (8 * i);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -151,13 +154,14 @@ static int quad8_count_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
+	unsigned long irqflags;
 	int i;
 
 	/* Only 24-bit values are supported */
 	if (val > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Reset Byte Pointer */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
@@ -182,7 +186,7 @@ static int quad8_count_write(struct counter_device *counter,
 	/* Reset Error flag */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -200,8 +204,9 @@ static int quad8_function_read(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int id = count->id;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	if (priv->quadrature_mode[id])
 		switch (priv->quadrature_scale[id]) {
@@ -218,7 +223,7 @@ static int quad8_function_read(struct counter_device *counter,
 	else
 		*function = COUNTER_FUNCTION_PULSE_DIRECTION;
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -233,10 +238,11 @@ static int quad8_function_write(struct counter_device *counter,
 	unsigned int *const scale = priv->quadrature_scale + id;
 	unsigned int *const synchronous_mode = priv->synchronous_mode + id;
 	const int base_offset = priv->base + 2 * id + 1;
+	unsigned long irqflags;
 	unsigned int mode_cfg;
 	unsigned int idr_cfg;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	mode_cfg = priv->count_mode[id] << 1;
 	idr_cfg = priv->index_polarity[id] << 1;
@@ -271,7 +277,7 @@ static int quad8_function_write(struct counter_device *counter,
 			break;
 		default:
 			/* should never reach this path */
-			mutex_unlock(&priv->lock);
+			spin_unlock_irqrestore(&priv->lock, irqflags);
 			return -EINVAL;
 		}
 	}
@@ -279,7 +285,7 @@ static int quad8_function_write(struct counter_device *counter,
 	/* Load mode configuration to Counter Mode Register */
 	outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -405,9 +411,10 @@ static int quad8_index_polarity_set(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 	const int base_offset = priv->base + 2 * channel_id + 1;
+	unsigned long irqflags;
 	unsigned int idr_cfg = index_polarity << 1;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	idr_cfg |= priv->synchronous_mode[channel_id];
 
@@ -416,7 +423,7 @@ static int quad8_index_polarity_set(struct counter_device *counter,
 	/* Load Index Control configuration to Index Control Register */
 	outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -445,15 +452,16 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 	const int base_offset = priv->base + 2 * channel_id + 1;
+	unsigned long irqflags;
 	unsigned int idr_cfg = synchronous_mode;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	idr_cfg |= priv->index_polarity[channel_id] << 1;
 
 	/* Index function must be non-synchronous in non-quadrature mode */
 	if (synchronous_mode && !priv->quadrature_mode[channel_id]) {
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return -EINVAL;
 	}
 
@@ -462,7 +470,7 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
 	/* Load Index Control configuration to Index Control Register */
 	outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -509,6 +517,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 	unsigned int count_mode;
 	unsigned int mode_cfg;
 	const int base_offset = priv->base + 2 * count->id + 1;
+	unsigned long irqflags;
 
 	/* Map Generic Counter count mode to 104-QUAD-8 count mode */
 	switch (cnt_mode) {
@@ -529,7 +538,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 		return -EINVAL;
 	}
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->count_mode[count->id] = count_mode;
 
@@ -543,7 +552,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 	/* Load mode configuration to Counter Mode Register */
 	outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -563,9 +572,10 @@ static int quad8_count_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
+	unsigned long irqflags;
 	unsigned int ior_cfg;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->ab_enable[count->id] = enable;
 
@@ -574,7 +584,7 @@ static int quad8_count_enable_write(struct counter_device *counter,
 	/* Load I/O control configuration */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -625,16 +635,17 @@ static int quad8_count_preset_write(struct counter_device *counter,
 				    struct counter_count *count, u64 preset)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
 	/* Only 24-bit values are supported */
 	if (preset > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	quad8_preset_register_set(priv, count->id, preset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -643,8 +654,9 @@ static int quad8_count_ceiling_read(struct counter_device *counter,
 				    struct counter_count *count, u64 *ceiling)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Range Limit and Modulo-N count modes use preset value as ceiling */
 	switch (priv->count_mode[count->id]) {
@@ -658,7 +670,7 @@ static int quad8_count_ceiling_read(struct counter_device *counter,
 		break;
 	}
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -667,23 +679,24 @@ static int quad8_count_ceiling_write(struct counter_device *counter,
 				     struct counter_count *count, u64 ceiling)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
 	/* Only 24-bit values are supported */
 	if (ceiling > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Range Limit and Modulo-N count modes use preset value as ceiling */
 	switch (priv->count_mode[count->id]) {
 	case 1:
 	case 3:
 		quad8_preset_register_set(priv, count->id, ceiling);
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return 0;
 	}
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return -EINVAL;
 }
@@ -705,12 +718,13 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id + 1;
+	unsigned long irqflags;
 	unsigned int ior_cfg;
 
 	/* Preset enable is active low in Input/Output Control register */
 	preset_enable = !preset_enable;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->preset_enable[count->id] = preset_enable;
 
@@ -719,7 +733,7 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 	/* Load I/O control configuration to Input / Output Control Register */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -730,22 +744,23 @@ static int quad8_signal_cable_fault_read(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
+	unsigned long irqflags;
 	bool disabled;
 	unsigned int status;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	disabled = !(priv->cable_fault_enable & BIT(channel_id));
 
 	if (disabled) {
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return -EINVAL;
 	}
 
 	/* Logic 0 = cable fault */
 	status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	/* Mask respective channel and invert logic */
 	*cable_fault = !(status & BIT(channel_id));
@@ -771,9 +786,10 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
+	unsigned long irqflags;
 	unsigned int cable_fault_enable;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	if (enable)
 		priv->cable_fault_enable |= BIT(channel_id);
@@ -785,7 +801,7 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
 
 	outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -808,8 +824,9 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
 	const int base_offset = priv->base + 2 * channel_id;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->fck_prescaler[channel_id] = prescaler;
 
@@ -821,7 +838,7 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
 	     base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -990,8 +1007,7 @@ static int quad8_probe(struct device *dev, unsigned int id)
 	priv->counter.priv = priv;
 	priv->base = base[id];
 
-	/* Initialize mutex */
-	mutex_init(&priv->lock);
+	spin_lock_init(&priv->lock);
 
 	/* Reset all counters and disable interrupt function */
 	outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
-- 
2.32.0



From vilhelm.gray at gmail.com  Tue Aug  3 05:06:27 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue,  3 Aug 2021 21:06:27 +0900
Subject: [PATCH v14 17/17] counter: 104-quad-8: Add IRQ support for the ACCES
 104-QUAD-8
In-Reply-To: <cover.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <8e3f1de5ef880b7244f312852f40c03748d0b145.1627990337.git.vilhelm.gray@gmail.com>

The LSI/CSI LS7266R1 chip provides programmable output via the FLG pins.
When interrupts are enabled on the ACCES 104-QUAD-8, they occur whenever
FLG1 is active. Four functions are available for the FLG1 signal: Carry,
Compare, Carry-Borrow, and Index.

	Carry:
		Interrupt generated on active low Carry signal. Carry
		signal toggles every time the respective channel's
		counter overflows.

	Compare:
		Interrupt generated on active low Compare signal.
		Compare signal toggles every time respective channel's
		preset register is equal to the respective channel's
		counter.

	Carry-Borrow:
		Interrupt generated on active low Carry signal and
		active low Borrow signal. Carry signal toggles every
		time the respective channel's counter overflows. Borrow
		signal toggles every time the respective channel's
		counter underflows.

	Index:
		Interrupt generated on active high Index signal.

These four functions correspond respectivefly to the following four
Counter event types: COUNTER_EVENT_OVERFLOW, COUNTER_EVENT_THRESHOLD,
COUNTER_EVENT_OVERFLOW_UNDERFLOW, and COUNTER_EVENT_INDEX. Interrupts
push Counter events to event channel X, where 'X' is the respective
channel whose FLG1 activated.

This patch adds IRQ support for the ACCES 104-QUAD-8. The interrupt line
numbers for the devices may be configured via the irq array module
parameter.

Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c | 167 +++++++++++++++++++++++++++++++++--
 drivers/counter/Kconfig      |   6 +-
 2 files changed, 164 insertions(+), 9 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index a56751bf1e9b..1cbd60aaed69 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
+#include <linux/interrupt.h>
 #include <linux/isa.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -25,6 +26,10 @@ static unsigned int num_quad8;
 module_param_hw_array(base, uint, ioport, &num_quad8, 0);
 MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
 
+static unsigned int irq[max_num_isa_dev(QUAD8_EXTENT)];
+module_param_hw_array(irq, uint, irq, NULL, 0);
+MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
+
 #define QUAD8_NUM_COUNTERS 8
 
 /**
@@ -38,6 +43,8 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
  * @quadrature_scale:	array of quadrature mode scale configurations
  * @ab_enable:		array of A and B inputs enable configurations
  * @preset_enable:	array of set_to_preset_on_index attribute configurations
+ * @irq_trigger:	array of current IRQ trigger function configurations
+ * @next_irq_trigger:	array of next IRQ trigger function configurations
  * @synchronous_mode:	array of index function synchronous mode configurations
  * @index_polarity:	array of index function polarity configurations
  * @cable_fault_enable:	differential encoder cable status enable configurations
@@ -53,13 +60,17 @@ struct quad8 {
 	unsigned int quadrature_scale[QUAD8_NUM_COUNTERS];
 	unsigned int ab_enable[QUAD8_NUM_COUNTERS];
 	unsigned int preset_enable[QUAD8_NUM_COUNTERS];
+	unsigned int irq_trigger[QUAD8_NUM_COUNTERS];
+	unsigned int next_irq_trigger[QUAD8_NUM_COUNTERS];
 	unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
 	unsigned int index_polarity[QUAD8_NUM_COUNTERS];
 	unsigned int cable_fault_enable;
 	unsigned int base;
 };
 
+#define QUAD8_REG_INTERRUPT_STATUS 0x10
 #define QUAD8_REG_CHAN_OP 0x11
+#define QUAD8_REG_INDEX_INTERRUPT 0x12
 #define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
 #define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17
 /* Borrow Toggle flip-flop */
@@ -92,8 +103,8 @@ struct quad8 {
 #define QUAD8_RLD_CNTR_OUT 0x10
 /* Transfer Preset Register LSB to FCK Prescaler */
 #define QUAD8_RLD_PRESET_PSC 0x18
-#define QUAD8_CHAN_OP_ENABLE_COUNTERS 0x00
 #define QUAD8_CHAN_OP_RESET_COUNTERS 0x01
+#define QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC 0x04
 #define QUAD8_CMR_QUADRATURE_X1 0x08
 #define QUAD8_CMR_QUADRATURE_X2 0x10
 #define QUAD8_CMR_QUADRATURE_X4 0x18
@@ -378,13 +389,103 @@ static int quad8_action_read(struct counter_device *counter,
 	}
 }
 
+enum {
+	QUAD8_EVENT_NONE = -1,
+	QUAD8_EVENT_CARRY = 0,
+	QUAD8_EVENT_COMPARE = 1,
+	QUAD8_EVENT_CARRY_BORROW = 2,
+	QUAD8_EVENT_INDEX = 3,
+};
+
+static int quad8_events_configure(struct counter_device *counter)
+{
+	struct quad8 *const priv = counter->priv;
+	unsigned long irq_enabled = 0;
+	unsigned long irqflags;
+	size_t channel;
+	unsigned long ior_cfg;
+	unsigned long base_offset;
+
+	spin_lock_irqsave(&priv->lock, irqflags);
+
+	/* Enable interrupts for the requested channels, disable for the rest */
+	for (channel = 0; channel < QUAD8_NUM_COUNTERS; channel++) {
+		if (priv->next_irq_trigger[channel] == QUAD8_EVENT_NONE)
+			continue;
+
+		if (priv->irq_trigger[channel] != priv->next_irq_trigger[channel]) {
+			/* Save new IRQ function configuration */
+			priv->irq_trigger[channel] = priv->next_irq_trigger[channel];
+
+			/* Load configuration to I/O Control Register */
+			ior_cfg = priv->ab_enable[channel] |
+				  priv->preset_enable[channel] << 1 |
+				  priv->irq_trigger[channel] << 3;
+			base_offset = priv->base + 2 * channel + 1;
+			outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
+		}
+
+		/* Reset next IRQ trigger function configuration */
+		priv->next_irq_trigger[channel] = QUAD8_EVENT_NONE;
+
+		/* Enable IRQ line */
+		irq_enabled |= BIT(channel);
+	}
+
+	outb(irq_enabled, priv->base + QUAD8_REG_INDEX_INTERRUPT);
+
+	spin_unlock_irqrestore(&priv->lock, irqflags);
+
+	return 0;
+}
+
+static int quad8_watch_validate(struct counter_device *counter,
+				const struct counter_watch *watch)
+{
+	struct quad8 *const priv = counter->priv;
+
+	if (watch->channel > QUAD8_NUM_COUNTERS - 1)
+		return -EINVAL;
+
+	switch (watch->event) {
+	case COUNTER_EVENT_OVERFLOW:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_CARRY;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_CARRY)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_THRESHOLD:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_COMPARE;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_COMPARE)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_CARRY_BORROW;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_CARRY_BORROW)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_INDEX:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_INDEX;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_INDEX)
+			return -EINVAL;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 static const struct counter_ops quad8_ops = {
 	.signal_read = quad8_signal_read,
 	.count_read = quad8_count_read,
 	.count_write = quad8_count_write,
 	.function_read = quad8_function_read,
 	.function_write = quad8_function_write,
-	.action_read = quad8_action_read
+	.action_read = quad8_action_read,
+	.events_configure = quad8_events_configure,
+	.watch_validate = quad8_watch_validate,
 };
 
 static const char *const quad8_index_polarity_modes[] = {
@@ -579,7 +680,8 @@ static int quad8_count_enable_write(struct counter_device *counter,
 
 	priv->ab_enable[count->id] = enable;
 
-	ior_cfg = enable | priv->preset_enable[count->id] << 1;
+	ior_cfg = enable | priv->preset_enable[count->id] << 1 |
+		  priv->irq_trigger[count->id] << 3;
 
 	/* Load I/O control configuration */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
@@ -728,7 +830,8 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 
 	priv->preset_enable[count->id] = preset_enable;
 
-	ior_cfg = priv->ab_enable[count->id] | preset_enable << 1;
+	ior_cfg = priv->ab_enable[count->id] | preset_enable << 1 |
+		  priv->irq_trigger[count->id] << 3;
 
 	/* Load I/O control configuration to Input / Output Control Register */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
@@ -980,11 +1083,54 @@ static struct counter_count quad8_counts[] = {
 	QUAD8_COUNT(7, "Channel 8 Count")
 };
 
+static irqreturn_t quad8_irq_handler(int irq, void *private)
+{
+	struct quad8 *const priv = private;
+	const unsigned long base = priv->base;
+	unsigned long irq_status;
+	unsigned long channel;
+	u8 event;
+
+	irq_status = inb(base + QUAD8_REG_INTERRUPT_STATUS);
+	if (!irq_status)
+		return IRQ_NONE;
+
+	for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) {
+		switch (priv->irq_trigger[channel]) {
+		case QUAD8_EVENT_CARRY:
+			event = COUNTER_EVENT_OVERFLOW;
+				break;
+		case QUAD8_EVENT_COMPARE:
+			event = COUNTER_EVENT_THRESHOLD;
+				break;
+		case QUAD8_EVENT_CARRY_BORROW:
+			event = COUNTER_EVENT_OVERFLOW_UNDERFLOW;
+				break;
+		case QUAD8_EVENT_INDEX:
+			event = COUNTER_EVENT_INDEX;
+				break;
+		default:
+			/* should never reach this path */
+			WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
+				  priv->irq_trigger[channel], channel);
+			continue;
+		}
+
+		counter_push_event(&priv->counter, event, channel);
+	}
+
+	/* Clear pending interrupts on device */
+	outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
+
+	return IRQ_HANDLED;
+}
+
 static int quad8_probe(struct device *dev, unsigned int id)
 {
 	struct quad8 *priv;
 	int i, j;
 	unsigned int base_offset;
+	int err;
 
 	if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
@@ -1009,6 +1155,8 @@ static int quad8_probe(struct device *dev, unsigned int id)
 
 	spin_lock_init(&priv->lock);
 
+	/* Reset Index/Interrupt Register */
+	outb(0x00, base[id] + QUAD8_REG_INDEX_INTERRUPT);
 	/* Reset all counters and disable interrupt function */
 	outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
 	/* Set initial configuration for all counters */
@@ -1035,11 +1183,18 @@ static int quad8_probe(struct device *dev, unsigned int id)
 		outb(QUAD8_CTR_IOR, base_offset + 1);
 		/* Disable index function; negative index polarity */
 		outb(QUAD8_CTR_IDR, base_offset + 1);
+		/* Initialize next IRQ trigger function configuration */
+		priv->next_irq_trigger[i] = QUAD8_EVENT_NONE;
 	}
 	/* Disable Differential Encoder Cable Status for all channels */
 	outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS);
-	/* Enable all counters */
-	outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
+	/* Enable all counters and enable interrupt function */
+	outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base[id] + QUAD8_REG_CHAN_OP);
+
+	err = devm_request_irq(dev, irq[id], quad8_irq_handler, IRQF_SHARED,
+			       priv->counter.name, priv);
+	if (err)
+		return err;
 
 	return devm_counter_register(dev, &priv->counter);
 }
diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index d5d2540b30c2..3dcdb681c4e4 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -23,11 +23,11 @@ config 104_QUAD_8
 	  A counter's respective error flag may be cleared by performing a write
 	  operation on the respective count value attribute. Although the
 	  104-QUAD-8 counters have a 25-bit range, only the lower 24 bits may be
-	  set, either directly or via the counter's preset attribute. Interrupts
-	  are not supported by this driver.
+	  set, either directly or via the counter's preset attribute.
 
 	  The base port addresses for the devices may be configured via the base
-	  array module parameter.
+	  array module parameter. The interrupt line numbers for the devices may
+	  be configured via the irq array module parameter.
 
 config INTERRUPT_CNT
 	tristate "Interrupt counter driver"
-- 
2.32.0



From patrice.chotard at foss.st.com  Tue Aug  3 05:08:32 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:08:32 +0200
Subject: [PATCH v3 11/13] ARM: dts: sti: disable rng11 on the stih418
 platform
In-Reply-To: <20210331204228.26107-12-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-12-avolmat@me.com>
Message-ID: <01885352-44d1-2997-f320-5f236140e8ac@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The rng11 is not available on the STiH418 hence is disabled in the
> stih418.dtsi
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih418.dtsi | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih418.dtsi b/arch/arm/boot/dts/stih418.dtsi
> index a05e2278b448..39a249983496 100644
> --- a/arch/arm/boot/dts/stih418.dtsi
> +++ b/arch/arm/boot/dts/stih418.dtsi
> @@ -27,6 +27,10 @@
>  	};
>  
>  	soc {
> +		rng11: rng at 8a8a000 {
> +			status = "disabled";
> +		};
> +
>  		usb2_picophy1: phy2 at 0 {
>  			compatible = "st,stih407-usb2-phy";
>  			reg = <0 0>;
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From patrice.chotard at foss.st.com  Tue Aug  3 05:08:48 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:08:48 +0200
Subject: [PATCH v3 12/13] ARM: dts: sti: add the thermal sensor node
 within stih418
In-Reply-To: <20210331204228.26107-13-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-13-avolmat@me.com>
Message-ID: <ca0bc89c-2a04-f1eb-de3a-01b271692df8@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> The STiH418 embedded the same sensor as the STiH410.
> This commit adds the corresponding node, relying on the st_thermal
> driver.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih418.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih418.dtsi b/arch/arm/boot/dts/stih418.dtsi
> index 39a249983496..97eda4392fbe 100644
> --- a/arch/arm/boot/dts/stih418.dtsi
> +++ b/arch/arm/boot/dts/stih418.dtsi
> @@ -108,5 +108,13 @@
>  			assigned-clock-parents = <&clk_s_c0_pll1 0>;
>  			assigned-clock-rates = <200000000>;
>  		};
> +
> +		thermal at 91a0000 {
> +			compatible = "st,stih407-thermal";
> +			reg = <0x91a0000 0x28>;
> +			clock-names = "thermal";
> +			clocks = <&clk_sysin>;
> +			interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
> +		};
>  	};
>  };
> 

Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From patrice.chotard at foss.st.com  Tue Aug  3 05:09:33 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Tue, 3 Aug 2021 14:09:33 +0200
Subject: [PATCH v3 13/13] ARM: dts: sti: Introduce 4KOpen (stih418-b2264)
 board
In-Reply-To: <20210331204228.26107-14-avolmat@me.com>
References: <20210331204228.26107-1-avolmat@me.com>
 <20210331204228.26107-14-avolmat@me.com>
Message-ID: <7dcac1f0-8eda-1a62-3328-c8daac8daddf@foss.st.com>

Hi Alain

On 3/31/21 10:42 PM, Alain Volmat wrote:
> 4KOpen (B2264) is a board based on the STMicroelectronics STiH418 soc:
>   - 2GB DDR
>   - HDMI
>   - Ethernet 1000-BaseT
>   - PCIe (mini PCIe connector)
>   - MicroSD slot
>   - USB2 and USB3 connectors
>   - Sata
>   - 40 pins GPIO header
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
> v3: add 300MHz opp, add led, add ethernet pinctrl
> v2: fix bootargs (removal of console=)
>     removal of rng11 node, moved into stih418.dtsi
> 
>  arch/arm/boot/dts/Makefile          |   3 +-
>  arch/arm/boot/dts/stih418-b2264.dts | 151 ++++++++++++++++++++++++++++
>  2 files changed, 153 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/stih418-b2264.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 8e5d4ab4e75e..3c1877627e91 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1061,7 +1061,8 @@ dtb-$(CONFIG_ARCH_STI) += \
>  	stih407-b2120.dtb \
>  	stih410-b2120.dtb \
>  	stih410-b2260.dtb \
> -	stih418-b2199.dtb
> +	stih418-b2199.dtb \
> +	stih418-b2264.dtb
>  dtb-$(CONFIG_ARCH_STM32) += \
>  	stm32f429-disco.dtb \
>  	stm32f469-disco.dtb \
> diff --git a/arch/arm/boot/dts/stih418-b2264.dts b/arch/arm/boot/dts/stih418-b2264.dts
> new file mode 100644
> index 000000000000..a99604bebf8c
> --- /dev/null
> +++ b/arch/arm/boot/dts/stih418-b2264.dts
> @@ -0,0 +1,151 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2021 STMicroelectronics
> + * Author: Alain Volmat <avolmat at me.com>
> + */
> +/dts-v1/;
> +#include "stih418.dtsi"
> +#include <dt-bindings/gpio/gpio.h>
> +/ {
> +	model = "STiH418 B2264";
> +	compatible = "st,stih418-b2264", "st,stih418";
> +
> +	chosen {
> +		stdout-path = &sbc_serial0;
> +	};
> +
> +	memory at 40000000 {
> +		device_type = "memory";
> +		reg = <0x40000000 0xc0000000>;
> +	};
> +
> +	cpus {
> +		cpu at 0 {
> +			operating-points-v2 = <&cpu_opp_table>;
> +			/* u-boot puts hpen in SBC dmem at 0xb8 offset */
> +			cpu-release-addr = <0x94100b8>;
> +		};
> +		cpu at 1 {
> +			operating-points-v2 = <&cpu_opp_table>;
> +			/* u-boot puts hpen in SBC dmem at 0xb8 offset */
> +			cpu-release-addr = <0x94100b8>;
> +		};
> +		cpu at 2 {
> +			operating-points-v2 = <&cpu_opp_table>;
> +			/* u-boot puts hpen in SBC dmem at 0xb8 offset */
> +			cpu-release-addr = <0x94100b8>;
> +		};
> +		cpu at 3 {
> +			operating-points-v2 = <&cpu_opp_table>;
> +			/* u-boot puts hpen in SBC dmem at 0xb8 offset */
> +			cpu-release-addr = <0x94100b8>;
> +		};
> +	};
> +
> +	cpu_opp_table: opp_table {
> +		compatible = "operating-points-v2";
> +		opp-shared;
> +
> +		opp00 {
> +			opp-hz = /bits/ 64 <300000000>;
> +			opp-microvolt = <784000>;
> +		};
> +		opp01 {
> +			opp-hz = /bits/ 64 <500000000>;
> +			opp-microvolt = <784000>;
> +		};
> +		opp02 {
> +			opp-hz = /bits/ 64 <800000000>;
> +			opp-microvolt = <784000>;
> +		};
> +		opp03 {
> +			opp-hz = /bits/ 64 <1200000000>;
> +			opp-microvolt = <784000>;
> +		};
> +		opp04 {
> +			opp-hz = /bits/ 64 <1500000000>;
> +			opp-microvolt = <784000>;
> +		};
> +	};
> +
> +	aliases {
> +		ttyAS0 = &sbc_serial0;
> +		ethernet0 = &ethernet0;
> +	};
> +
> +	soc {
> +		leds {
> +			compatible = "gpio-leds";
> +			green {
> +				gpios = <&pio1 3 GPIO_ACTIVE_HIGH>;
> +				default-state = "off";
> +			};
> +		};
> +
> +		pin-controller-sbc at 961f080 {
> +			gmac1 {
> +				rgmii1-0 {
> +					st,pins {
> +						rxd0 = <&pio1 4 ALT1 IN DE_IO 300 CLK_A>;
> +						rxd1 = <&pio1 5 ALT1 IN DE_IO 300 CLK_A>;
> +						rxd2 = <&pio1 6 ALT1 IN DE_IO 300 CLK_A>;
> +						rxd3 = <&pio1 7 ALT1 IN DE_IO 300 CLK_A>;
> +						rxdv = <&pio2 0 ALT1 IN DE_IO 300 CLK_A>;
> +					};
> +				};
> +			};
> +		};
> +
> +	};
> +};
> +
> +&ehci0 {
> +	status = "okay";
> +};
> +
> +&ethernet0 {
> +	phy-mode = "rgmii";
> +	pinctrl-0 = <&pinctrl_rgmii1 &pinctrl_rgmii1_mdio_1>;
> +	st,tx-retime-src = "clkgen";
> +
> +	snps,reset-gpio = <&pio0 7 0>;
> +	snps,reset-active-low;
> +	snps,reset-delays-us = <0 10000 1000000>;
> +
> +	status = "okay";
> +};
> +
> +&miphy28lp_phy {
> +	phy_port0: port at 9b22000 {
> +		st,sata-gen = <2>; /* SATA GEN3 */
> +		st,osc-rdy;
> +	};
> +};
> +
> +&mmc0 {
> +	status = "okay";
> +};
> +
> +&ohci1 {
> +	status = "okay";
> +};
> +
> +&pwm1 {
> +	status = "okay";
> +};
> +
> +&sata0 {
> +	status = "okay";
> +};
> +
> +&sbc_serial0 {
> +	status = "okay";
> +};
> +
> +&spifsm {
> +	status = "okay";
> +};
> +
> +&st_dwc3 {
> +	status = "okay";
> +};
> 
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From linus.walleij at linaro.org  Tue Aug  3 05:12:33 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 3 Aug 2021 14:12:33 +0200
Subject: [PATCH] ARM: ep93xx: remove MaverickCrunch support
In-Reply-To: <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>
References: <20210802141245.1146772-1-arnd@kernel.org>
 <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>
Message-ID: <CACRpkdbRbgjo1AkZVd0J1nhuo601o8=20rKR+ccaJR1+vqn6qg@mail.gmail.com>

On Mon, Aug 2, 2021 at 5:45 PM Martin Guy <martinwguy at gmail.com> wrote:

> > was removed from gcc in its 4.8 release in 2012.
>
> I was sad about that, as I had managed to get it working correctly in
> 4.2 4.3 and 4.4.
> Unfortunately the GCC ARM maintainer at the time was paid by ARM, and
> they had no interest in it, as I gather the ARM-Cirrus partnership
> ended up disappointingly.

Political issues aside, have you considered contributing support
to LLVM instead?

It currently doesn't even support ARMv4 AFAIK but reportedly
has an easier to use and maintain back-end. (I do not know if
this is true, I just browsed this:
https://llvm.org/docs/WritingAnLLVMBackend.html )
Current ARM Targets are here:
https://github.com/llvm/llvm-project/tree/main/llvm/lib/Target/ARM
And they have a very clear and straight-forward developer policy:
https://llvm.org/docs/DeveloperPolicy.html

If ARMv4 support could be added to LLVM, that would solve
a lot of my headaches for ARM32, where we have things like
SA110 being actively maintained.

Yours,
Linus Walleij


From shameerali.kolothum.thodi at huawei.com  Tue Aug  3 05:12:49 2021
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Tue, 3 Aug 2021 12:12:49 +0000
Subject: [PATCH v3 1/4] KVM: arm64: Introduce a new VMID allocator for KVM
In-Reply-To: <20210803113856.GA30853@willie-the-truck>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-2-shameerali.kolothum.thodi@huawei.com>
 <20210803113856.GA30853@willie-the-truck>
Message-ID: <318d2eaad3864fdf84ea6d14218a10e1@huawei.com>



> -----Original Message-----
> From: Will Deacon [mailto:will at kernel.org]
> Sent: 03 August 2021 12:39
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org; maz at kernel.org; catalin.marinas at arm.com;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Linuxarm
> <linuxarm at huawei.com>
> Subject: Re: [PATCH v3 1/4] KVM: arm64: Introduce a new VMID allocator for
> KVM
> 
> On Thu, Jul 29, 2021 at 11:40:06AM +0100, Shameer Kolothum wrote:
> > A new VMID allocator for arm64 KVM use. This is based on
> > arm64 ASID allocator algorithm.
> >
> > One major deviation from the ASID allocator is the way we
> > flush the context. Unlike ASID allocator, we expect less
> > frequent rollover in the case of VMIDs. Hence, instead of
> > marking the CPU as flush_pending and issuing a local context
> > invalidation on the next context switch, we broadcast TLB
> > flush + I-cache invalidation over the inner shareable domain
> > on rollover.
> >
> > Signed-off-by: Shameer Kolothum
> <shameerali.kolothum.thodi at huawei.com>
> > ---
> 
> [...]
> 
> > +void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
> > +{
> > +	unsigned long flags;
> > +	unsigned int cpu;
> > +	u64 vmid, old_active_vmid;
> > +
> > +	vmid = atomic64_read(&kvm_vmid->id);
> > +
> > +	/*
> > +	 * Please refer comments in check_and_switch_context() in
> > +	 * arch/arm64/mm/context.c.
> > +	 */
> > +	old_active_vmid = atomic64_read(this_cpu_ptr(&active_vmids));
> > +	if (old_active_vmid && vmid_gen_match(vmid) &&
> > +	    atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_vmids),
> > +				     old_active_vmid, vmid))
> > +		return;
> > +
> > +	raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
> > +
> > +	/* Check that our VMID belongs to the current generation. */
> > +	vmid = atomic64_read(&kvm_vmid->id);
> > +	if (!vmid_gen_match(vmid)) {
> > +		vmid = new_vmid(kvm_vmid);
> > +		atomic64_set(&kvm_vmid->id, vmid);
> 
> new_vmid() can just set kvm_vmid->id directly

Ok.
> 
> > +	}
> > +
> > +	cpu = smp_processor_id();
> 
> Why?

Left over from previous one. Forgot to remove
as we don't have the tlb_flush_pending check anymore.

Thanks,
Shameer

> 
> Will


From robin.murphy at arm.com  Tue Aug  3 05:13:12 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 3 Aug 2021 13:13:12 +0100
Subject: [PATCH v2 23/24] iommu/arm-smmu: Allow non-strict in
 pgtable_quirks interface
In-Reply-To: <20210803103559.GA30690@willie-the-truck>
References: <cover.1627468308.git.robin.murphy@arm.com>
 <0fcd1f5225a6b435cbc697551a6247cd435c04db.1627468310.git.robin.murphy@arm.com>
 <20210802130438.GA28547@willie-the-truck>
 <3dd7cdae-7111-6ff2-6350-a0e19fe4ab66@arm.com>
 <20210803103559.GA30690@willie-the-truck>
Message-ID: <529750e7-89a0-cfb7-8cef-36bb78b06340@arm.com>

On 2021-08-03 11:36, Will Deacon wrote:
> On Mon, Aug 02, 2021 at 03:15:50PM +0100, Robin Murphy wrote:
>> On 2021-08-02 14:04, Will Deacon wrote:
>>> On Wed, Jul 28, 2021 at 04:58:44PM +0100, Robin Murphy wrote:
>>>> To make io-pgtable aware of a flush queue being dynamically enabled,
>>>> allow IO_PGTABLE_QUIRK_NON_STRICT to be set even after a domain has been
>>>> attached to, and hook up the final piece of the puzzle in iommu-dma.
>>>>
>>>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
>>>> ---
>>>>    drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 +++++++++++++++
>>>>    drivers/iommu/arm/arm-smmu/arm-smmu.c       | 11 +++++++++++
>>>>    drivers/iommu/dma-iommu.c                   |  3 +++
>>>>    3 files changed, 29 insertions(+)
>>>>
>>>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> index 19400826eba7..40fa9cb382c3 100644
>>>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> @@ -2711,6 +2711,20 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
>>>>    	return ret;
>>>>    }
>>>> +static int arm_smmu_set_pgtable_quirks(struct iommu_domain *domain,
>>>> +		unsigned long quirks)
>>>> +{
>>>> +	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>>> +
>>>> +	if (quirks == IO_PGTABLE_QUIRK_NON_STRICT && smmu_domain->pgtbl_ops) {
>>>> +		struct io_pgtable *iop = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
>>>> +
>>>> +		iop->cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
>>>> +		return 0;
>>>> +	}
>>>> +	return -EINVAL;
>>>> +}
>>>
>>> I don't see anything serialising this against a concurrent iommu_unmap(), so
>>> the ordering and atomicity looks quite suspicious to me here. I don't think
>>> it's just the page-table quirks either, but also setting cookie->fq_domain.
>>
>> Heh, I confess to very much taking the cheeky "let's say nothing and see
>> what Will thinks about concurrency" approach here :)
> 
> Damnit, I fell for that didn't I?
> 
> Overall, I'm really nervous about the concurrency here and think we'd be
> better off requiring the unbind as we have for the other domain changes.

Sure, the dynamic switch is what makes it ultimately work for Doug's 
use-case (where the unbind isn't viable), but I had every expectation 
that we might need to hold back those two patches for much deeper 
consideration. It's no accident that the first 22 patches can still be 
usefully applied without them!

In all honesty I don't really like this particular patch much, mostly 
because I increasingly dislike IO_PGTABLE_QUIRK_NON_STRICT at all, but 
since the interface was there it made it super easy to prove the 
concept. I have a more significant refactoring of the io-pgtable code 
sketched out in my mind already, it's just going to be more work.

>> The beauty of only allowing relaxation in the strict->non-strict direction
>> is that it shouldn't need serialising as such - it doesn't matter if the
>> update to cookie->fq_domain is observed between iommu_unmap() and
>> iommu_dma_free_iova(), since there's no correctness impact to queueing IOVAs
>> which may already have been invalidated and may or may not have been synced.
>> AFAICS the only condition which matters is that the setting of the
>> io-pgtable quirk must observe fq_domain being set. It feels like there must
>> be enough dependencies on the read side, but we might need an smp_wmb()
>> between the two in iommu_dma_init_fq()?
>>
>> I've also flip-flopped a bit on whether fq_domain needs to be accessed with
>> READ_ONCE/WRITE_ONCE - by the time of posting I'd convinced myself that it
>> was probably OK, but looking again now I suppose this wacky reordering is
>> theoretically possible:
>>
>>
>> 	iommu_dma_unmap() {
>> 		bool free_fq = cookie->fq_domain; // == false
>>
>> 		iommu_unmap();
>>
>> 		if (!cookie->fq_domain) // observes new non-NULL value
>> 			iommu_tlb_sync(); // skipped
>>
>> 		iommu_dma_free_iova { // inlined
>> 			if (free_fq) // false
>> 				queue_iova();
>> 			else
>> 				free_iova_fast(); // Uh-oh!
>> 		}
>> 	}
>>
>> so although I still can't see atomicity being a problem I guess we do need
>> it for the sake of reordering at least.
> 
> With your changes, I think quite a few things can go wrong.
> 
>    * cookie->fq_domain may be observed but iovad->fq could be NULL

Good point, I guess that already technically applies (if iovad->fq sat 
in a write buffer long enough), but it certainly becomes far easier to 
provoke. However a barrier after assigning fq_domain (as mentioned 
above) paired with the control dependency around the queue_iova() call 
would also fix that, right?

>    * We can miss the smp_wmb() in the pgtable code but end up deferring the
>      IOVA reclaim
>    * iommu_change_dev_def_domain() only holds the group mutex afaict, so can
>      possibly run concurrently with itself on the same domain?
>    * iommu_dma_init_fq() can flip the domain type back from
>      IOMMU_DOMAIN_DMA_FQ to IOMMU_DOMAIN_DMA on the error path
>    * set_pgtable_quirks() isn't atomic, which probably is ok for now, but the
>      moment we use it anywhere else it's dangerous

In other words, IO_PGTABLE_QUIRK_NON_STRICT is definitely the problem. 
I'll have a hack on that this afternoon, and if it starts to look 
rabbit-holey I'll split this bit off and post v3 of the rest of the series.

If all the io-pgtable and fq behaviour for a given call could be 
consistent based on a single READ_ONCE(cookie->fq_domain) in 
iommu_dma_unmap(), do you see any remaining issues other than the point 
above?

Thanks,
Robin.


From rocco.yue at mediatek.com  Tue Aug  3 04:57:59 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Tue, 3 Aug 2021 19:57:59 +0800
Subject: [PATCH net-next v2] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <f66750af-cbda-6d49-2b39-860c10357e95@gmail.com>
References: <f66750af-cbda-6d49-2b39-860c10357e95@gmail.com>
Message-ID: <20210803115759.4342-1-rocco.yue@mediatek.com>

On Mon, 2021-08-02 at 07:35 -0600, David Ahern wrote:
> On 8/2/21 6:40 AM, Rocco Yue wrote:
>> 
>> Regarding setting "reject_message" in the policy, after reviewing
>> the code, I fell that it is unnecessary, because the cost of
>> implementing it seems to be a bit high, which requires modifying
>> the function interface. The reasons is as follows:
> 
> The policy can be setup now to do the right thing once the extack
> argument is available.
> 
> do_setlink() has an extack argument. It calls validate_linkmsg which
> calls validate_link_af meaning support can be added in a single patch.
> If you decide to do it, then it should be a separate patch preceding
> this one.
> 

Hi David,

Thanks for your advice,
I will send a separate patch to add extack arg firstly.

> Then userspace should get a link notification when ra_mtu is set so it
> does not have to poll.

It make sense, I will do it.

Thanks
Rocco

From sven at svenpeter.dev  Tue Aug  3 05:16:49 2021
From: sven at svenpeter.dev (Sven Peter)
Date: Tue,  3 Aug 2021 14:16:49 +0200
Subject: [PATCH v5 1/3] iommu/io-pgtable: Add DART pagetable format
In-Reply-To: <20210803121651.61594-1-sven@svenpeter.dev>
References: <20210803121651.61594-1-sven@svenpeter.dev>
Message-ID: <20210803121651.61594-2-sven@svenpeter.dev>

Apple's DART iommu uses a pagetable format that shares some
similarities with the ones already implemented by io-pgtable.c.
Add a new format variant to support the required differences
so that we don't have to duplicate the pagetable handling code.

Reviewed-by: Alexander Graf <graf at amazon.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Reviewed-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Sven Peter <sven at svenpeter.dev>
---
 drivers/iommu/io-pgtable-arm.c | 63 ++++++++++++++++++++++++++++++++++
 drivers/iommu/io-pgtable.c     |  1 +
 include/linux/io-pgtable.h     |  7 ++++
 3 files changed, 71 insertions(+)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 053df4048a29..0779eb96bd29 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -130,6 +130,9 @@
 #define ARM_MALI_LPAE_MEMATTR_IMP_DEF	0x88ULL
 #define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL
 
+#define APPLE_DART_PTE_PROT_NO_WRITE (1<<7)
+#define APPLE_DART_PTE_PROT_NO_READ (1<<8)
+
 /* IOPTE accessors */
 #define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d))
 
@@ -402,6 +405,15 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
 {
 	arm_lpae_iopte pte;
 
+	if (data->iop.fmt == APPLE_DART) {
+		pte = 0;
+		if (!(prot & IOMMU_WRITE))
+			pte |= APPLE_DART_PTE_PROT_NO_WRITE;
+		if (!(prot & IOMMU_READ))
+			pte |= APPLE_DART_PTE_PROT_NO_READ;
+		return pte;
+	}
+
 	if (data->iop.fmt == ARM_64_LPAE_S1 ||
 	    data->iop.fmt == ARM_32_LPAE_S1) {
 		pte = ARM_LPAE_PTE_nG;
@@ -1102,6 +1114,52 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
 	return NULL;
 }
 
+static struct io_pgtable *
+apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
+{
+	struct arm_lpae_io_pgtable *data;
+	int i;
+
+	if (cfg->oas > 36)
+		return NULL;
+
+	data = arm_lpae_alloc_pgtable(cfg);
+	if (!data)
+		return NULL;
+
+	/*
+	 * The table format itself always uses two levels, but the total VA
+	 * space is mapped by four separate tables, making the MMIO registers
+	 * an effective "level 1". For simplicity, though, we treat this
+	 * equivalently to LPAE stage 2 concatenation at level 2, with the
+	 * additional TTBRs each just pointing at consecutive pages.
+	 */
+	if (data->start_level < 1)
+		goto out_free_data;
+	if (data->start_level == 1 && data->pgd_bits > 2)
+		goto out_free_data;
+	if (data->start_level > 1)
+		data->pgd_bits = 0;
+	data->start_level = 2;
+	cfg->apple_dart_cfg.n_ttbrs = 1 << data->pgd_bits;
+	data->pgd_bits += data->bits_per_level;
+
+	data->pgd = __arm_lpae_alloc_pages(ARM_LPAE_PGD_SIZE(data), GFP_KERNEL,
+					   cfg);
+	if (!data->pgd)
+		goto out_free_data;
+
+	for (i = 0; i < cfg->apple_dart_cfg.n_ttbrs; ++i)
+		cfg->apple_dart_cfg.ttbr[i] =
+			virt_to_phys(data->pgd + i * ARM_LPAE_GRANULE(data));
+
+	return &data->iop;
+
+out_free_data:
+	kfree(data);
+	return NULL;
+}
+
 struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = {
 	.alloc	= arm_64_lpae_alloc_pgtable_s1,
 	.free	= arm_lpae_free_pgtable,
@@ -1127,6 +1185,11 @@ struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns = {
 	.free	= arm_lpae_free_pgtable,
 };
 
+struct io_pgtable_init_fns io_pgtable_apple_dart_init_fns = {
+	.alloc	= apple_dart_alloc_pgtable,
+	.free	= arm_lpae_free_pgtable,
+};
+
 #ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST
 
 static struct io_pgtable_cfg *cfg_cookie __initdata;
diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c
index 6e9917ce980f..f4bfcef98297 100644
--- a/drivers/iommu/io-pgtable.c
+++ b/drivers/iommu/io-pgtable.c
@@ -20,6 +20,7 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = {
 	[ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,
 	[ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,
 	[ARM_MALI_LPAE] = &io_pgtable_arm_mali_lpae_init_fns,
+	[APPLE_DART] = &io_pgtable_apple_dart_init_fns,
 #endif
 #ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S
 	[ARM_V7S] = &io_pgtable_arm_v7s_init_fns,
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index c43f3b899d2a..a738483fb4da 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -16,6 +16,7 @@ enum io_pgtable_fmt {
 	ARM_V7S,
 	ARM_MALI_LPAE,
 	AMD_IOMMU_V1,
+	APPLE_DART,
 	IO_PGTABLE_NUM_FMTS,
 };
 
@@ -136,6 +137,11 @@ struct io_pgtable_cfg {
 			u64	transtab;
 			u64	memattr;
 		} arm_mali_lpae_cfg;
+
+		struct {
+			u64 ttbr[4];
+			u32 n_ttbrs;
+		} apple_dart_cfg;
 	};
 };
 
@@ -254,5 +260,6 @@ extern struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns;
 extern struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns;
 extern struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns;
 extern struct io_pgtable_init_fns io_pgtable_amd_iommu_v1_init_fns;
+extern struct io_pgtable_init_fns io_pgtable_apple_dart_init_fns;
 
 #endif /* __IO_PGTABLE_H */
-- 
2.25.1



From sven at svenpeter.dev  Tue Aug  3 05:16:48 2021
From: sven at svenpeter.dev (Sven Peter)
Date: Tue,  3 Aug 2021 14:16:48 +0200
Subject: [PATCH v5 0/3] Apple M1 DART IOMMU driver
Message-ID: <20210803121651.61594-1-sven@svenpeter.dev>

Hi,

This is v5 of my Apple M1 DART IOMMU driver series as a follow up to the previous
versions [1][2][3][7].

Short summary: this series adds support for the iommu found in Apple's new M1
SoC which is required to use DMA on most peripherals like the display controller,
the USB ports or the internal PCIe bus (which is used for WiFi, Ethernet and
more USB ports).
So far this code has been tested by multiple people with dwc3 in host and
device mode (which both only require changes to the device tree after this
patchset) and PCIe (using a yet to be finalized patchset).

Note that this version has to be applied on top of iommu/core or iommu/next since
it now uses the new map_pages/unmap_pages API.


== Testing this patchset with the USB-C controller == 

The two USB-C ports on the M1 machines are exposed as two separate dwc3
controllers which are behind a DART. Now that my USB phy bringup code has been
merged into our bootloader m1n1 you can easily test this patchset yourself:

1) Follow the instructions at [4] to setup our bootloader m1n1 on your M1
   machine which will allow you to boot kernels using a normal USB cable.
   Note that you'll still need a special setup to expose the UART for very
   low-level debugging.

2) Apply this patchset and add the DART and dwc3 nodes as done in e.g. [5].

3) Boot the kernel through our bootloader m1n1. You'll need a version after
   commit [6] which enables the USB PHY and the USB PD chip.

Note that the dwc3 controller has a quirk where each root port can only be used
once right now. The most stable way to test is to already connected the USB
device(s) before booting the kernel.

It's also possible to test the PCIe bus but this requires a more complex setup
for now. I can write a quick howto if anyone is interested though.
(tl;dr: Mark Kettenis has a u-boot fork that includes PCIe bringup code and
Marc Zyngier has a WIP patchset to add a PCIe driver)

== Project Blurb ==

Asahi Linux is an open community project dedicated to developing and
maintaining mainline support for Apple Silicon on Linux. Feel free to
drop by #asahi and #asahi-dev on OFTC to chat with us, or check
our website for more information on the project:

https://asahilinux.org/

== Changes ==

Changes for v5:
 - Added reviewed-by and tested-by tags (thanks!)
 - Rebased on top of iommu/core and replaced map/unmap with map_pages/unmap_pages
 - Removed software bypass hacks: I've tried a few different variants now
   and they all have drawbacks or incompatibilities that I am not comfortable
   with. This means that PCIe devices (for which there is no kernel support yet
   anyway) will not work correctly for now on 4K kernels. I plan to address this
   in a follow-up series where I want to modify the dma-iommu layer to support
   pagesize mismatches.
 - Removed reference to ARM from the constants for the io-pgtable code
 - Addressed the following comments by Robin Murphy, which resulted in some major
   changes to apple-dart.c
   - Correctly assign iommu_groups in apple_dart_device_group
   - Get rid of the fwspec-inspired of_xlate linked lists and replaced them with
     a simple static array with a streamid bitmap covering all known cases
   - Relax locking: Now only a single spinlock around TLB flushes and a mutex
     around domain initialization are required. attach_dev/detach_dev uses
     atomic64_t.
   - Set .suppress_bind_attrs to prevent manual unbinding
   - Get rid of .shutdown since there's no real need to clean anything up
   - Manage interrupts manually instead of using devm_* to prevent situations
     where a shared interrupt could trigger while clocks are disabled
   - apple_dart_irq now prints "unknown" when more than a single error bit
     has been set.
   - Use DL_FLAG_AUTOREMOVE_SUPPLIER so that there's no need to keep track
     of the pointer
   - Ignore any unknown protection flags instead of failing
   - Use dev_err_ratelimited and clk_bulk_disable_unprepare instead of
     open-coding them
   - Correctly set and clear iommu_bus_ops
   - Removed unhelpful WARN_ONs and duplicate sanity checks
   - Removed unnecessary identity stream map reset code 
   - Renamed apple-dart-iommu.c to apple-dart.c
   - Fixed commit style to use the correct subsystem style
 - Possibly some smaller fixes I forgot about

Changes for v4:
 - Addressed Rob Herring's remark about the incorrect phandles in the device
   tree binding example and added his reviewed-by tag
 - Take the software linear mapping range from the bus instead of hardcoding
   it in the driver
 - Use def_domain_type to force bypass mode if there's a pagesize mismatch
   between the DART (hardwired to 16KB) and the kernel (may use 4K)
 - Added lockdep_assert_held instead of comments as suggested by Rouven Czerwinski
 - rebased on 5.13-rc7

Changes for v3:
 - fixed name of the iommu node in the device tree binding example
   pointed out by Arnd Bergmann
 - remove hardware specific checks from io-pgtable.c  as pointed out by
   Will Deacon
 - introduced a fake bypass mode by programming static linear pagetables
   if the DART does not support regular bypass mode as proposed by Alex
   Graf
 - added checks to enforce bypass mode if there is a pagesize mismatch
   between the DART HW and the CPU.
 - fixed usage of GFP_KERNEL during a held spinlock found by Julia Lawall
 - rebased on v5.13-rc3

Changes for v2:
 - fixed devicetree binding linting issues pointed out by Rob Herring and
   reworked that file.
 - made DART-specific code in io-pgtable.c unconditional and removed flag from
   Kconfig as proposed by Robin Murphy.
 - allowed multiple DART nodes in the "iommus" property as proposed by
   Rob Herring and Robin Murphy. this resulted in significant changes
   to apple-iommu-dart.c.
 - the domain aperture is now forced to 32bit if translation is enabled after
   the original suggestion to limit the aperture by Mark Kettenis and the
   follow-up discussion and investigation with Mark Kettenis, Arnd Bergmann,
   Robin Murphy and Rob Herring. This change also simplified the code
   in io-pgtable.c and made some of the improvements suggested during review
   not apply anymore.
 - added support for bypassed and isolated domain modes.
 - reject IOMMU_MMIO and IOMMU_NOEXEC since it's unknown how to set these up
   for now or if the hardware even supports these flags.
 - renamed some registers to be less confusing (mainly s/DOMAIN/STREAM/ to
   prevent confusion with linux's iommu domain concept).


[1] https://lore.kernel.org/linux-iommu/20210320151903.60759-1-sven at svenpeter.dev/
[2] https://lore.kernel.org/linux-iommu/20210328074009.95932-1-sven at svenpeter.dev/
[3] https://lore.kernel.org/linux-iommu/20210603085003.50465-1-sven at svenpeter.dev/
[4] https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart
[5] https://github.com/AsahiLinux/linux/commit/7d4ebb0b22e9bfec849e2af86ddeb46ec29d7feb
[6] https://github.com/AsahiLinux/m1n1/commit/9529ec2b4fd6550f9cfd66d9f2448b90804699a1
[7] https://lore.kernel.org/linux-iommu/20210627143405.77298-1-sven at svenpeter.dev/

Sven Peter (3):
  iommu/io-pgtable: Add DART pagetable format
  dt-bindings: iommu: add DART iommu bindings
  iommu/dart: Add DART iommu driver

 .../devicetree/bindings/iommu/apple,dart.yaml |  81 ++
 MAINTAINERS                                   |   7 +
 drivers/iommu/Kconfig                         |  14 +
 drivers/iommu/Makefile                        |   1 +
 drivers/iommu/apple-dart.c                    | 923 ++++++++++++++++++
 drivers/iommu/io-pgtable-arm.c                |  63 ++
 drivers/iommu/io-pgtable.c                    |   1 +
 include/linux/io-pgtable.h                    |   7 +
 8 files changed, 1097 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/apple,dart.yaml
 create mode 100644 drivers/iommu/apple-dart.c

-- 
2.25.1



From sven at svenpeter.dev  Tue Aug  3 05:16:50 2021
From: sven at svenpeter.dev (Sven Peter)
Date: Tue,  3 Aug 2021 14:16:50 +0200
Subject: [PATCH v5 2/3] dt-bindings: iommu: add DART iommu bindings
In-Reply-To: <20210803121651.61594-1-sven@svenpeter.dev>
References: <20210803121651.61594-1-sven@svenpeter.dev>
Message-ID: <20210803121651.61594-3-sven@svenpeter.dev>

DART (Device Address Resolution Table) is the iommu found on Apple
ARM SoCs such as the M1.

Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Signed-off-by: Sven Peter <sven at svenpeter.dev>
---
 .../devicetree/bindings/iommu/apple,dart.yaml | 81 +++++++++++++++++++
 MAINTAINERS                                   |  6 ++
 2 files changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/apple,dart.yaml

diff --git a/Documentation/devicetree/bindings/iommu/apple,dart.yaml b/Documentation/devicetree/bindings/iommu/apple,dart.yaml
new file mode 100644
index 000000000000..94aa9e9afa59
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/apple,dart.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/apple,dart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple DART IOMMU
+
+maintainers:
+  - Sven Peter <sven at svenpeter.dev>
+
+description: |+
+  Apple SoCs may contain an implementation of their Device Address
+  Resolution Table which provides a mandatory layer of address
+  translations for various masters.
+
+  Each DART instance is capable of handling up to 16 different streams
+  with individual pagetables and page-level read/write protection flags.
+
+  This DART IOMMU also raises interrupts in response to various
+  fault conditions.
+
+properties:
+  compatible:
+    const: apple,t8103-dart
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    description:
+      Reference to the gate clock phandle if required for this IOMMU.
+      Optional since not all IOMMUs are attached to a clock gate.
+
+  '#iommu-cells':
+    const: 1
+    description:
+      Has to be one. The single cell describes the stream id emitted by
+      a master to the IOMMU.
+
+required:
+  - compatible
+  - reg
+  - '#iommu-cells'
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |+
+    dart1: iommu at 82f80000 {
+      compatible = "apple,t8103-dart";
+      reg = <0x82f80000 0x4000>;
+      interrupts = <1 781 4>;
+      #iommu-cells = <1>;
+    };
+
+    master1 {
+      iommus = <&dart1 0>;
+    };
+
+  - |+
+    dart2a: iommu at 82f00000 {
+      compatible = "apple,t8103-dart";
+      reg = <0x82f00000 0x4000>;
+      interrupts = <1 781 4>;
+      #iommu-cells = <1>;
+    };
+    dart2b: iommu at 82f80000 {
+      compatible = "apple,t8103-dart";
+      reg = <0x82f80000 0x4000>;
+      interrupts = <1 781 4>;
+      #iommu-cells = <1>;
+    };
+
+    master2 {
+      iommus = <&dart2a 0>, <&dart2b 1>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index c9467d2839f5..0f450f7d5336 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1262,6 +1262,12 @@ L:	linux-input at vger.kernel.org
 S:	Odd fixes
 F:	drivers/input/mouse/bcm5974.c
 
+APPLE DART IOMMU DRIVER
+M:	Sven Peter <sven at svenpeter.dev>
+L:	iommu at lists.linux-foundation.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iommu/apple,dart.yaml
+
 APPLE SMC DRIVER
 M:	Henrik Rydberg <rydberg at bitmath.org>
 L:	linux-hwmon at vger.kernel.org
-- 
2.25.1



From sven at svenpeter.dev  Tue Aug  3 05:16:51 2021
From: sven at svenpeter.dev (Sven Peter)
Date: Tue,  3 Aug 2021 14:16:51 +0200
Subject: [PATCH v5 3/3] iommu/dart: Add DART iommu driver
In-Reply-To: <20210803121651.61594-1-sven@svenpeter.dev>
References: <20210803121651.61594-1-sven@svenpeter.dev>
Message-ID: <20210803121651.61594-4-sven@svenpeter.dev>

Apple's new SoCs use iommus for almost all peripherals. These Device
Address Resolution Tables must be setup before these peripherals can
act as DMA masters.

Tested-by: Alyssa Rosenzweig <alyssa at rosenzweig.io>
Signed-off-by: Sven Peter <sven at svenpeter.dev>
---
 MAINTAINERS                |   1 +
 drivers/iommu/Kconfig      |  14 +
 drivers/iommu/Makefile     |   1 +
 drivers/iommu/apple-dart.c | 923 +++++++++++++++++++++++++++++++++++++
 4 files changed, 939 insertions(+)
 create mode 100644 drivers/iommu/apple-dart.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 0f450f7d5336..5f3ef4298594 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1267,6 +1267,7 @@ M:	Sven Peter <sven at svenpeter.dev>
 L:	iommu at lists.linux-foundation.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/iommu/apple,dart.yaml
+F:	drivers/iommu/apple-dart.c
 
 APPLE SMC DRIVER
 M:	Henrik Rydberg <rydberg at bitmath.org>
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c84da8205be7..dfe81da483e9 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -290,6 +290,20 @@ config SPAPR_TCE_IOMMU
 	  Enables bits of IOMMU API required by VFIO. The iommu_ops
 	  is not implemented as it is not necessary for VFIO.
 
+config APPLE_DART
+	tristate "Apple DART IOMMU Support"
+	depends on ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64)
+	select IOMMU_API
+	select IOMMU_IO_PGTABLE_LPAE
+	default ARCH_APPLE
+	help
+	  Support for Apple DART (Device Address Resolution Table) IOMMUs
+	  found in Apple ARM SoCs like the M1.
+	  This IOMMU is required for most peripherals using DMA to access
+	  the main memory.
+
+	  Say Y here if you are using an Apple SoC.
+
 # ARM IOMMU support
 config ARM_SMMU
 	tristate "ARM Ltd. System MMU (SMMU) Support"
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index c0fb0ba88143..bc7f730edbb0 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o
 obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
 obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o io-pgfault.o
 obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
+obj-$(CONFIG_APPLE_DART) += apple-dart.o
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
new file mode 100644
index 000000000000..559db9259e65
--- /dev/null
+++ b/drivers/iommu/apple-dart.c
@@ -0,0 +1,923 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Apple DART (Device Address Resolution Table) IOMMU driver
+ *
+ * Copyright (C) 2021 The Asahi Linux Contributors
+ *
+ * Based on arm/arm-smmu/arm-ssmu.c and arm/arm-smmu-v3/arm-smmu-v3.c
+ *  Copyright (C) 2013 ARM Limited
+ *  Copyright (C) 2015 ARM Limited
+ * and on exynos-iommu.c
+ *  Copyright (c) 2011,2016 Samsung Electronics Co., Ltd.
+ */
+
+#include <linux/atomic.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/dev_printk.h>
+#include <linux/dma-iommu.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io-pgtable.h>
+#include <linux/iommu.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_iommu.h>
+#include <linux/of_platform.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/swab.h>
+#include <linux/types.h>
+
+#define DART_MAX_STREAMS 16
+#define DART_MAX_TTBR 4
+#define MAX_DARTS_PER_DEVICE 2
+
+#define DART_STREAM_ALL 0xffff
+
+#define DART_PARAMS1 0x00
+#define DART_PARAMS_PAGE_SHIFT GENMASK(27, 24)
+
+#define DART_PARAMS2 0x04
+#define DART_PARAMS_BYPASS_SUPPORT BIT(0)
+
+#define DART_STREAM_COMMAND 0x20
+#define DART_STREAM_COMMAND_BUSY BIT(2)
+#define DART_STREAM_COMMAND_INVALIDATE BIT(20)
+
+#define DART_STREAM_SELECT 0x34
+
+#define DART_ERROR 0x40
+#define DART_ERROR_STREAM GENMASK(27, 24)
+#define DART_ERROR_CODE GENMASK(11, 0)
+#define DART_ERROR_FLAG BIT(31)
+
+#define DART_ERROR_READ_FAULT BIT(4)
+#define DART_ERROR_WRITE_FAULT BIT(3)
+#define DART_ERROR_NO_PTE BIT(2)
+#define DART_ERROR_NO_PMD BIT(1)
+#define DART_ERROR_NO_TTBR BIT(0)
+
+#define DART_CONFIG 0x60
+#define DART_CONFIG_LOCK BIT(15)
+
+#define DART_STREAM_COMMAND_BUSY_TIMEOUT 100
+
+#define DART_ERROR_ADDR_HI 0x54
+#define DART_ERROR_ADDR_LO 0x50
+
+#define DART_TCR(sid) (0x100 + 4 * (sid))
+#define DART_TCR_TRANSLATE_ENABLE BIT(7)
+#define DART_TCR_BYPASS0_ENABLE BIT(8)
+#define DART_TCR_BYPASS1_ENABLE BIT(12)
+
+#define DART_TTBR(sid, idx) (0x200 + 16 * (sid) + 4 * (idx))
+#define DART_TTBR_VALID BIT(31)
+#define DART_TTBR_SHIFT 12
+
+/*
+ * Private structure associated with each DART device.
+ *
+ * @dev: device struct
+ * @regs: mapped MMIO region
+ * @irq: interrupt number, can be shared with other DARTs
+ * @clks: clocks associated with this DART
+ * @num_clks: number of @clks
+ * @lock: lock for hardware operations involving this dart
+ * @pgsize: pagesize supported by this DART
+ * @supports_bypass: indicates if this DART supports bypass mode
+ * @force_bypass: force bypass mode due to pagesize mismatch?
+ * @sid2group: maps stream ids to iommu_groups
+ * @iommu: iommu core device
+ */
+struct apple_dart {
+	struct device *dev;
+
+	void __iomem *regs;
+
+	int irq;
+	struct clk_bulk_data *clks;
+	int num_clks;
+
+	spinlock_t lock;
+
+	u32 pgsize;
+	u32 supports_bypass : 1;
+	u32 force_bypass : 1;
+
+	struct iommu_group *sid2group[DART_MAX_STREAMS];
+	struct iommu_device iommu;
+};
+
+/*
+ * Convenience struct to identify streams.
+ *
+ * The normal variant is used inside apple_dart_master_cfg which isn't written
+ * to concurrently.
+ * The atomic variant is used inside apple_dart_domain where we have to guard
+ * against races from potential parallel calls to attach/detach_device.
+ * Note that even inside the atomic variant the apple_dart pointer is not
+ * protected: This pointer is initialized once under the domain init mutex
+ * and never changed again afterwards. Devices with different dart pointers
+ * cannot be attached to the same domain.
+ *
+ * @dart dart pointer
+ * @sid stream id bitmap
+ */
+struct apple_dart_stream_map {
+	struct apple_dart *dart;
+	unsigned long sidmap;
+};
+struct apple_dart_atomic_stream_map {
+	struct apple_dart *dart;
+	atomic64_t sidmap;
+};
+
+/*
+ * This structure is attached to each iommu domain handled by a DART.
+ *
+ * @pgtbl_ops: pagetable ops allocated by io-pgtable
+ * @finalized: true if the domain has been completely initialized
+ * @init_lock: protects domain initialization
+ * @stream_maps: streams attached to this domain (valid for DMA/UNMANAGED only)
+ * @domain: core iommu domain pointer
+ */
+struct apple_dart_domain {
+	struct io_pgtable_ops *pgtbl_ops;
+
+	bool finalized;
+	struct mutex init_lock;
+	struct apple_dart_atomic_stream_map stream_maps[MAX_DARTS_PER_DEVICE];
+
+	struct iommu_domain domain;
+};
+
+/*
+ * This structure is attached to devices with dev_iommu_priv_set() on of_xlate
+ * and contains a list of streams bound to this device.
+ * So far the worst case seen is a single device with two streams
+ * from different darts, such that this simple static array is enough.
+ *
+ * @streams: streams for this device
+ */
+struct apple_dart_master_cfg {
+	struct apple_dart_stream_map stream_maps[MAX_DARTS_PER_DEVICE];
+};
+
+/*
+ * Helper macro to iterate over apple_dart_master_cfg.stream_maps and
+ * apple_dart_domain.stream_maps
+ *
+ * @i int used as loop variable
+ * @base pointer to base struct (apple_dart_master_cfg or apple_dart_domain)
+ * @stream pointer to the apple_dart_streams struct for each loop iteration
+ */
+#define for_each_stream_map(i, base, stream_map)                               \
+	for (i = 0, stream_map = &(base)->stream_maps[0];                      \
+	     i < MAX_DARTS_PER_DEVICE && stream_map->dart;                     \
+	     stream_map = &(base)->stream_maps[++i])
+
+static struct platform_driver apple_dart_driver;
+static const struct iommu_ops apple_dart_iommu_ops;
+static const struct iommu_flush_ops apple_dart_tlb_ops;
+
+static struct apple_dart_domain *to_dart_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct apple_dart_domain, domain);
+}
+
+static void
+apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map)
+{
+	int sid;
+
+	for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
+		writel(DART_TCR_TRANSLATE_ENABLE,
+		       stream_map->dart->regs + DART_TCR(sid));
+}
+
+static void apple_dart_hw_disable_dma(struct apple_dart_stream_map *stream_map)
+{
+	int sid;
+
+	for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
+		writel(0, stream_map->dart->regs + DART_TCR(sid));
+}
+
+static void
+apple_dart_hw_enable_bypass(struct apple_dart_stream_map *stream_map)
+{
+	int sid;
+
+	WARN_ON(!stream_map->dart->supports_bypass);
+	for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
+		writel(DART_TCR_BYPASS0_ENABLE | DART_TCR_BYPASS1_ENABLE,
+		       stream_map->dart->regs + DART_TCR(sid));
+}
+
+static void apple_dart_hw_set_ttbr(struct apple_dart_stream_map *stream_map,
+				   u8 idx, phys_addr_t paddr)
+{
+	int sid;
+
+	WARN_ON(paddr & ((1 << DART_TTBR_SHIFT) - 1));
+	for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
+		writel(DART_TTBR_VALID | (paddr >> DART_TTBR_SHIFT),
+		       stream_map->dart->regs + DART_TTBR(sid, idx));
+}
+
+static void apple_dart_hw_clear_ttbr(struct apple_dart_stream_map *stream_map,
+				     u8 idx)
+{
+	int sid;
+
+	for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
+		writel(0, stream_map->dart->regs + DART_TTBR(sid, idx));
+}
+
+static void
+apple_dart_hw_clear_all_ttbrs(struct apple_dart_stream_map *stream_map)
+{
+	int i;
+
+	for (i = 0; i < DART_MAX_TTBR; ++i)
+		apple_dart_hw_clear_ttbr(stream_map, i);
+}
+
+static int
+apple_dart_hw_stream_command(struct apple_dart_stream_map *stream_map,
+			     u32 command)
+{
+	unsigned long flags;
+	int ret;
+	u32 command_reg;
+
+	spin_lock_irqsave(&stream_map->dart->lock, flags);
+
+	writel(stream_map->sidmap, stream_map->dart->regs + DART_STREAM_SELECT);
+	writel(command, stream_map->dart->regs + DART_STREAM_COMMAND);
+
+	ret = readl_poll_timeout_atomic(
+		stream_map->dart->regs + DART_STREAM_COMMAND, command_reg,
+		!(command_reg & DART_STREAM_COMMAND_BUSY), 1,
+		DART_STREAM_COMMAND_BUSY_TIMEOUT);
+
+	spin_unlock_irqrestore(&stream_map->dart->lock, flags);
+
+	if (ret) {
+		dev_err(stream_map->dart->dev,
+			"busy bit did not clear after command %x for streams %lx\n",
+			command, stream_map->sidmap);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+apple_dart_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map)
+{
+	return apple_dart_hw_stream_command(stream_map,
+					    DART_STREAM_COMMAND_INVALIDATE);
+}
+
+static int apple_dart_hw_reset(struct apple_dart *dart)
+{
+	u32 config;
+	struct apple_dart_stream_map stream_map;
+
+	config = readl(dart->regs + DART_CONFIG);
+	if (config & DART_CONFIG_LOCK) {
+		dev_err(dart->dev, "DART is locked down until reboot: %08x\n",
+			config);
+		return -EINVAL;
+	}
+
+	stream_map.dart = dart;
+	stream_map.sidmap = DART_STREAM_ALL;
+	apple_dart_hw_disable_dma(&stream_map);
+	apple_dart_hw_clear_all_ttbrs(&stream_map);
+
+	/* clear any pending errors before the interrupt is unmasked */
+	writel(readl(dart->regs + DART_ERROR), dart->regs + DART_ERROR);
+
+	return apple_dart_hw_invalidate_tlb(&stream_map);
+}
+
+static void apple_dart_domain_flush_tlb(struct apple_dart_domain *domain)
+{
+	int i;
+	struct apple_dart_atomic_stream_map *domain_stream_map;
+	struct apple_dart_stream_map stream_map;
+
+	for_each_stream_map(i, domain, domain_stream_map) {
+		stream_map.dart = domain_stream_map->dart;
+		stream_map.sidmap = atomic64_read(&domain_stream_map->sidmap);
+		apple_dart_hw_invalidate_tlb(&stream_map);
+	}
+}
+
+static void apple_dart_flush_iotlb_all(struct iommu_domain *domain)
+{
+	apple_dart_domain_flush_tlb(to_dart_domain(domain));
+}
+
+static void apple_dart_iotlb_sync(struct iommu_domain *domain,
+				  struct iommu_iotlb_gather *gather)
+{
+	apple_dart_domain_flush_tlb(to_dart_domain(domain));
+}
+
+static void apple_dart_iotlb_sync_map(struct iommu_domain *domain,
+				      unsigned long iova, size_t size)
+{
+	apple_dart_domain_flush_tlb(to_dart_domain(domain));
+}
+
+static void apple_dart_tlb_flush_all(void *cookie)
+{
+	apple_dart_domain_flush_tlb(cookie);
+}
+
+static void apple_dart_tlb_flush_walk(unsigned long iova, size_t size,
+				      size_t granule, void *cookie)
+{
+	apple_dart_domain_flush_tlb(cookie);
+}
+
+static const struct iommu_flush_ops apple_dart_tlb_ops = {
+	.tlb_flush_all = apple_dart_tlb_flush_all,
+	.tlb_flush_walk = apple_dart_tlb_flush_walk,
+};
+
+static phys_addr_t apple_dart_iova_to_phys(struct iommu_domain *domain,
+					   dma_addr_t iova)
+{
+	struct apple_dart_domain *dart_domain = to_dart_domain(domain);
+	struct io_pgtable_ops *ops = dart_domain->pgtbl_ops;
+
+	if (!ops)
+		return 0;
+
+	return ops->iova_to_phys(ops, iova);
+}
+
+static int apple_dart_map_pages(struct iommu_domain *domain, unsigned long iova,
+				phys_addr_t paddr, size_t pgsize,
+				size_t pgcount, int prot, gfp_t gfp,
+				size_t *mapped)
+{
+	struct apple_dart_domain *dart_domain = to_dart_domain(domain);
+	struct io_pgtable_ops *ops = dart_domain->pgtbl_ops;
+
+	if (!ops)
+		return -ENODEV;
+
+	return ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot, gfp,
+			      mapped);
+}
+
+static size_t apple_dart_unmap_pages(struct iommu_domain *domain,
+				     unsigned long iova, size_t pgsize,
+				     size_t pgcount,
+				     struct iommu_iotlb_gather *gather)
+{
+	struct apple_dart_domain *dart_domain = to_dart_domain(domain);
+	struct io_pgtable_ops *ops = dart_domain->pgtbl_ops;
+
+	return ops->unmap_pages(ops, iova, pgsize, pgcount, gather);
+}
+
+static void
+apple_dart_setup_translation(struct apple_dart_domain *domain,
+			     struct apple_dart_stream_map *stream_map)
+{
+	int i;
+	struct io_pgtable_cfg *pgtbl_cfg =
+		&io_pgtable_ops_to_pgtable(domain->pgtbl_ops)->cfg;
+
+	for (i = 0; i < pgtbl_cfg->apple_dart_cfg.n_ttbrs; ++i)
+		apple_dart_hw_set_ttbr(stream_map, i,
+				       pgtbl_cfg->apple_dart_cfg.ttbr[i]);
+	for (; i < DART_MAX_TTBR; ++i)
+		apple_dart_hw_clear_ttbr(stream_map, i);
+
+	apple_dart_hw_enable_translation(stream_map);
+	apple_dart_hw_invalidate_tlb(stream_map);
+}
+
+static int apple_dart_finalize_domain(struct iommu_domain *domain,
+				      struct apple_dart_master_cfg *cfg)
+{
+	struct apple_dart_domain *dart_domain = to_dart_domain(domain);
+	struct apple_dart *dart = cfg->stream_maps[0].dart;
+	struct io_pgtable_cfg pgtbl_cfg;
+	int ret = 0;
+	int i;
+
+	mutex_lock(&dart_domain->init_lock);
+
+	if (dart_domain->finalized)
+		goto done;
+
+	for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
+		dart_domain->stream_maps[i].dart = cfg->stream_maps[i].dart;
+		atomic64_set(&dart_domain->stream_maps[i].sidmap,
+			     cfg->stream_maps[i].sidmap);
+	}
+
+	pgtbl_cfg = (struct io_pgtable_cfg){
+		.pgsize_bitmap = dart->pgsize,
+		.ias = 32,
+		.oas = 36,
+		.coherent_walk = 1,
+		.tlb = &apple_dart_tlb_ops,
+		.iommu_dev = dart->dev,
+	};
+
+	dart_domain->pgtbl_ops =
+		alloc_io_pgtable_ops(APPLE_DART, &pgtbl_cfg, domain);
+	if (!dart_domain->pgtbl_ops) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
+	domain->geometry.aperture_start = 0;
+	domain->geometry.aperture_end = DMA_BIT_MASK(32);
+	domain->geometry.force_aperture = true;
+
+	dart_domain->finalized = true;
+
+done:
+	mutex_unlock(&dart_domain->init_lock);
+	return ret;
+}
+
+static int
+apple_dart_mod_streams(struct apple_dart_atomic_stream_map *domain_maps,
+		       struct apple_dart_stream_map *master_maps,
+		       bool add_streams)
+{
+	int i;
+
+	for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
+		if (domain_maps[i].dart != master_maps[i].dart)
+			return -EINVAL;
+	}
+
+	for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
+		if (!domain_maps[i].dart)
+			break;
+		if (add_streams)
+			atomic64_or(master_maps[i].sidmap,
+				    &domain_maps[i].sidmap);
+		else
+			atomic64_and(~master_maps[i].sidmap,
+				     &domain_maps[i].sidmap);
+	}
+
+	return 0;
+}
+
+static int apple_dart_domain_add_streams(struct apple_dart_domain *domain,
+					 struct apple_dart_master_cfg *cfg)
+{
+	return apple_dart_mod_streams(domain->stream_maps, cfg->stream_maps,
+				      true);
+}
+
+static int apple_dart_domain_remove_streams(struct apple_dart_domain *domain,
+					    struct apple_dart_master_cfg *cfg)
+{
+	return apple_dart_mod_streams(domain->stream_maps, cfg->stream_maps,
+				      false);
+}
+
+static int apple_dart_attach_dev(struct iommu_domain *domain,
+				 struct device *dev)
+{
+	int ret, i;
+	struct apple_dart_stream_map *stream_map;
+	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
+	struct apple_dart_domain *dart_domain = to_dart_domain(domain);
+
+	if (cfg->stream_maps[0].dart->force_bypass &&
+	    domain->type != IOMMU_DOMAIN_IDENTITY)
+		return -EINVAL;
+	if (!cfg->stream_maps[0].dart->supports_bypass &&
+	    domain->type == IOMMU_DOMAIN_IDENTITY)
+		return -EINVAL;
+
+	ret = apple_dart_finalize_domain(domain, cfg);
+	if (ret)
+		return ret;
+
+	switch (domain->type) {
+	case IOMMU_DOMAIN_DMA:
+	case IOMMU_DOMAIN_UNMANAGED:
+		ret = apple_dart_domain_add_streams(dart_domain, cfg);
+		if (ret)
+			return ret;
+
+		for_each_stream_map(i, cfg, stream_map)
+			apple_dart_setup_translation(dart_domain, stream_map);
+		break;
+	case IOMMU_DOMAIN_BLOCKED:
+		for_each_stream_map(i, cfg, stream_map)
+			apple_dart_hw_disable_dma(stream_map);
+		break;
+	case IOMMU_DOMAIN_IDENTITY:
+		for_each_stream_map(i, cfg, stream_map)
+			apple_dart_hw_enable_bypass(stream_map);
+		break;
+	}
+
+	return ret;
+}
+
+static void apple_dart_detach_dev(struct iommu_domain *domain,
+				  struct device *dev)
+{
+	int i;
+	struct apple_dart_stream_map *stream_map;
+	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
+	struct apple_dart_domain *dart_domain = to_dart_domain(domain);
+
+	for_each_stream_map(i, cfg, stream_map)
+		apple_dart_hw_disable_dma(stream_map);
+
+	if (domain->type == IOMMU_DOMAIN_DMA ||
+	    domain->type == IOMMU_DOMAIN_UNMANAGED)
+		apple_dart_domain_remove_streams(dart_domain, cfg);
+}
+
+static struct iommu_device *apple_dart_probe_device(struct device *dev)
+{
+	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
+	struct apple_dart_stream_map *stream_map;
+	int i;
+
+	if (!cfg)
+		return ERR_PTR(-ENODEV);
+
+	for_each_stream_map(i, cfg, stream_map)
+		device_link_add(
+			dev, stream_map->dart->dev,
+			DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
+	return &cfg->stream_maps[0].dart->iommu;
+}
+
+static void apple_dart_release_device(struct device *dev)
+{
+	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
+
+	if (!cfg)
+		return;
+
+	dev_iommu_priv_set(dev, NULL);
+	kfree(cfg);
+}
+
+static struct iommu_domain *apple_dart_domain_alloc(unsigned int type)
+{
+	struct apple_dart_domain *dart_domain;
+
+	if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED &&
+	    type != IOMMU_DOMAIN_IDENTITY && type != IOMMU_DOMAIN_BLOCKED)
+		return NULL;
+
+	dart_domain = kzalloc(sizeof(*dart_domain), GFP_KERNEL);
+	if (!dart_domain)
+		return NULL;
+
+	iommu_get_dma_cookie(&dart_domain->domain);
+	mutex_init(&dart_domain->init_lock);
+
+	/* no need to allocate pgtbl_ops or do any other finalization steps */
+	if (type == IOMMU_DOMAIN_IDENTITY || type == IOMMU_DOMAIN_BLOCKED)
+		dart_domain->finalized = true;
+
+	return &dart_domain->domain;
+}
+
+static void apple_dart_domain_free(struct iommu_domain *domain)
+{
+	struct apple_dart_domain *dart_domain = to_dart_domain(domain);
+
+	if (dart_domain->pgtbl_ops)
+		free_io_pgtable_ops(dart_domain->pgtbl_ops);
+
+	kfree(dart_domain);
+}
+
+static int apple_dart_of_xlate(struct device *dev, struct of_phandle_args *args)
+{
+	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
+	struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
+	struct apple_dart *dart = platform_get_drvdata(iommu_pdev);
+	struct apple_dart *cfg_dart;
+	int i, sid;
+
+	if (args->args_count != 1)
+		return -EINVAL;
+	sid = args->args[0];
+
+	if (!cfg)
+		cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+	dev_iommu_priv_set(dev, cfg);
+
+	cfg_dart = cfg->stream_maps[0].dart;
+	if (cfg_dart) {
+		if (cfg_dart->supports_bypass != dart->supports_bypass)
+			return -EINVAL;
+		if (cfg_dart->force_bypass != dart->force_bypass)
+			return -EINVAL;
+		if (cfg_dart->pgsize != dart->pgsize)
+			return -EINVAL;
+	}
+
+	for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
+		if (cfg->stream_maps[i].dart == dart) {
+			cfg->stream_maps[i].sidmap |= 1 << sid;
+			return 0;
+		}
+	}
+	for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) {
+		if (!cfg->stream_maps[i].dart) {
+			cfg->stream_maps[i].dart = dart;
+			cfg->stream_maps[i].sidmap = 1 << sid;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static struct iommu_group *apple_dart_device_group(struct device *dev)
+{
+	static DEFINE_MUTEX(lock);
+	int i, sid;
+	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
+	struct apple_dart_stream_map *stream_map;
+	struct iommu_group *group = NULL;
+	struct iommu_group *res = ERR_PTR(-EINVAL);
+
+	mutex_lock(&lock);
+
+	for_each_stream_map(i, cfg, stream_map) {
+		for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) {
+			struct iommu_group *stream_group =
+				stream_map->dart->sid2group[sid];
+
+			if (group && group != stream_group) {
+				res = ERR_PTR(-EINVAL);
+				goto out;
+			}
+
+			group = stream_group;
+		}
+	}
+
+	if (group) {
+		res = iommu_group_ref_get(group);
+		goto out;
+	}
+
+#ifdef CONFIG_PCI
+	if (dev_is_pci(dev))
+		group = pci_device_group(dev);
+	else
+#endif
+		group = generic_device_group(dev);
+
+	for_each_stream_map(i, cfg, stream_map)
+		for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS)
+			stream_map->dart->sid2group[sid] = group;
+
+	res = group;
+
+out:
+	mutex_unlock(&lock);
+	return res;
+}
+
+static int apple_dart_def_domain_type(struct device *dev)
+{
+	struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
+
+	if (cfg->stream_maps[0].dart->force_bypass)
+		return IOMMU_DOMAIN_IDENTITY;
+	if (!cfg->stream_maps[0].dart->supports_bypass)
+		return IOMMU_DOMAIN_DMA;
+
+	return 0;
+}
+
+static const struct iommu_ops apple_dart_iommu_ops = {
+	.domain_alloc = apple_dart_domain_alloc,
+	.domain_free = apple_dart_domain_free,
+	.attach_dev = apple_dart_attach_dev,
+	.detach_dev = apple_dart_detach_dev,
+	.map_pages = apple_dart_map_pages,
+	.unmap_pages = apple_dart_unmap_pages,
+	.flush_iotlb_all = apple_dart_flush_iotlb_all,
+	.iotlb_sync = apple_dart_iotlb_sync,
+	.iotlb_sync_map = apple_dart_iotlb_sync_map,
+	.iova_to_phys = apple_dart_iova_to_phys,
+	.probe_device = apple_dart_probe_device,
+	.release_device = apple_dart_release_device,
+	.device_group = apple_dart_device_group,
+	.of_xlate = apple_dart_of_xlate,
+	.def_domain_type = apple_dart_def_domain_type,
+	.pgsize_bitmap = -1UL, /* Restricted during dart probe */
+};
+
+static irqreturn_t apple_dart_irq(int irq, void *dev)
+{
+	struct apple_dart *dart = dev;
+	const char *fault_name = NULL;
+	u32 error = readl(dart->regs + DART_ERROR);
+	u32 error_code = FIELD_GET(DART_ERROR_CODE, error);
+	u32 addr_lo = readl(dart->regs + DART_ERROR_ADDR_LO);
+	u32 addr_hi = readl(dart->regs + DART_ERROR_ADDR_HI);
+	u64 addr = addr_lo | (((u64)addr_hi) << 32);
+	u8 stream_idx = FIELD_GET(DART_ERROR_STREAM, error);
+
+	if (!(error & DART_ERROR_FLAG))
+		return IRQ_NONE;
+
+	/* there should only be a single bit set but let's use == to be sure */
+	if (error_code == DART_ERROR_READ_FAULT)
+		fault_name = "READ FAULT";
+	else if (error_code == DART_ERROR_WRITE_FAULT)
+		fault_name = "WRITE FAULT";
+	else if (error_code == DART_ERROR_NO_PTE)
+		fault_name = "NO PTE FOR IOVA";
+	else if (error_code == DART_ERROR_NO_PMD)
+		fault_name = "NO PMD FOR IOVA";
+	else if (error_code == DART_ERROR_NO_TTBR)
+		fault_name = "NO TTBR FOR IOVA";
+	else
+		fault_name = "unknown";
+
+	dev_err_ratelimited(
+		dart->dev,
+		"translation fault: status:0x%x stream:%d code:0x%x (%s) at 0x%llx",
+		error, stream_idx, error_code, fault_name, addr);
+
+	writel(error, dart->regs + DART_ERROR);
+	return IRQ_HANDLED;
+}
+
+static int apple_dart_set_bus_ops(const struct iommu_ops *ops)
+{
+	int ret;
+
+	if (!iommu_present(&platform_bus_type)) {
+		ret = bus_set_iommu(&platform_bus_type, ops);
+		if (ret)
+			return ret;
+	}
+#ifdef CONFIG_PCI
+	if (!iommu_present(&pci_bus_type)) {
+		ret = bus_set_iommu(&pci_bus_type, ops);
+		if (ret) {
+			bus_set_iommu(&platform_bus_type, NULL);
+			return ret;
+		}
+	}
+#endif
+	return 0;
+}
+
+static int apple_dart_probe(struct platform_device *pdev)
+{
+	int ret;
+	u32 dart_params[2];
+	struct resource *res;
+	struct apple_dart *dart;
+	struct device *dev = &pdev->dev;
+
+	dart = devm_kzalloc(dev, sizeof(*dart), GFP_KERNEL);
+	if (!dart)
+		return -ENOMEM;
+
+	dart->dev = dev;
+	spin_lock_init(&dart->lock);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (resource_size(res) < 0x4000) {
+		dev_err(dev, "MMIO region too small (%pr)\n", res);
+		return -EINVAL;
+	}
+
+	dart->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(dart->regs))
+		return PTR_ERR(dart->regs);
+
+	dart->irq = platform_get_irq(pdev, 0);
+	if (dart->irq < 0)
+		return -ENODEV;
+
+	ret = devm_clk_bulk_get_all(dev, &dart->clks);
+	if (ret < 0)
+		return ret;
+	dart->num_clks = ret;
+
+	ret = clk_bulk_prepare_enable(dart->num_clks, dart->clks);
+	if (ret)
+		return ret;
+
+	ret = apple_dart_hw_reset(dart);
+	if (ret)
+		goto err_clk_disable;
+
+	dart_params[0] = readl(dart->regs + DART_PARAMS1);
+	dart_params[1] = readl(dart->regs + DART_PARAMS2);
+	dart->pgsize = 1 << FIELD_GET(DART_PARAMS_PAGE_SHIFT, dart_params[0]);
+	dart->supports_bypass = dart_params[1] & DART_PARAMS_BYPASS_SUPPORT;
+	dart->force_bypass = dart->pgsize > PAGE_SIZE;
+
+	ret = request_irq(dart->irq, apple_dart_irq, IRQF_SHARED,
+			  "apple-dart fault handler", dart);
+	if (ret)
+		goto err_clk_disable;
+
+	platform_set_drvdata(pdev, dart);
+
+	ret = apple_dart_set_bus_ops(&apple_dart_iommu_ops);
+	if (ret)
+		goto err_free_irq;
+
+	ret = iommu_device_sysfs_add(&dart->iommu, dev, NULL, "apple-dart.%s",
+				     dev_name(&pdev->dev));
+	if (ret)
+		goto err_remove_bus_ops;
+
+	ret = iommu_device_register(&dart->iommu, &apple_dart_iommu_ops, dev);
+	if (ret)
+		goto err_sysfs_remove;
+
+	dev_info(
+		&pdev->dev,
+		"DART [pagesize %x, bypass support: %d, bypass forced: %d] initialized\n",
+		dart->pgsize, dart->supports_bypass, dart->force_bypass);
+	return 0;
+
+err_sysfs_remove:
+	iommu_device_sysfs_remove(&dart->iommu);
+err_remove_bus_ops:
+	apple_dart_set_bus_ops(NULL);
+err_free_irq:
+	free_irq(dart->irq, dart);
+err_clk_disable:
+	clk_bulk_disable_unprepare(dart->num_clks, dart->clks);
+
+	return ret;
+}
+
+static int apple_dart_remove(struct platform_device *pdev)
+{
+	struct apple_dart *dart = platform_get_drvdata(pdev);
+
+	apple_dart_hw_reset(dart);
+	free_irq(dart->irq, dart);
+	apple_dart_set_bus_ops(NULL);
+
+	iommu_device_unregister(&dart->iommu);
+	iommu_device_sysfs_remove(&dart->iommu);
+
+	clk_bulk_disable_unprepare(dart->num_clks, dart->clks);
+
+	return 0;
+}
+
+static const struct of_device_id apple_dart_of_match[] = {
+	{ .compatible = "apple,t8103-dart", .data = NULL },
+	{},
+};
+MODULE_DEVICE_TABLE(of, apple_dart_of_match);
+
+static struct platform_driver apple_dart_driver = {
+	.driver	= {
+		.name			= "apple-dart",
+		.of_match_table		= apple_dart_of_match,
+		.suppress_bind_attrs    = true,
+	},
+	.probe	= apple_dart_probe,
+	.remove	= apple_dart_remove,
+};
+
+module_platform_driver(apple_dart_driver);
+
+MODULE_DESCRIPTION("IOMMU API for Apple's DART");
+MODULE_AUTHOR("Sven Peter <sven at svenpeter.dev>");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From joey.gouly at arm.com  Tue Aug  3 05:17:20 2021
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 3 Aug 2021 13:17:20 +0100
Subject: [PATCH 4/4] arm64: entry: call exit_to_user_mode() from C
In-Reply-To: <20210802140733.52716-5-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
 <20210802140733.52716-5-mark.rutland@arm.com>
Message-ID: <20210803121720.GD52119@e124191.cambridge.arm.com>

On Mon, Aug 02, 2021 at 03:07:33PM +0100, Mark Rutland wrote:
> When handling an exception from EL0, we perform the entry work in that
> exception's C handler, and once the C handler has finised, we return
typo: finished

> back to the entry assembly. Subsequently in the common `ret_to_user`
> assembly we perform the exit work that balances with the entry work.
> This can be somewhat difficult to follow, and makes it hard to rework
> the return paths (e.g. to pass additional context to the exit code, or
> to have exception return logic for specific exceptions).
> 

[..]

Reviewed-by: Joey Gouly <joey.gouly at arm.com>


From rocco.yue at mediatek.com  Tue Aug  3 05:02:50 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Tue, 3 Aug 2021 20:02:50 +0800
Subject: [PATCH net-next] net: add extack arg for link ops
Message-ID: <20210803120250.32642-1-rocco.yue@mediatek.com>

Pass extack arg to validate_linkmsg and validate_link_af callbacks.
If a netlink attribute has a reject_message, use the extended ack
mechanism to carry the message back to user space.

Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
---
 include/net/rtnetlink.h | 3 ++-
 net/core/rtnetlink.c    | 9 +++++----
 net/ipv4/devinet.c      | 5 +++--
 net/ipv6/addrconf.c     | 5 +++--
 4 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 384e800665f2..9f48733bfd21 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -153,7 +153,8 @@ struct rtnl_af_ops {
 						    u32 ext_filter_mask);
 
 	int			(*validate_link_af)(const struct net_device *dev,
-						    const struct nlattr *attr);
+						    const struct nlattr *attr,
+						    struct netlink_ext_ack *extack);
 	int			(*set_link_af)(struct net_device *dev,
 					       const struct nlattr *attr,
 					       struct netlink_ext_ack *extack);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f6af3e74fc44..8c78715338b0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2268,7 +2268,8 @@ static int rtnl_ensure_unique_netns(struct nlattr *tb[],
 	return -EINVAL;
 }
 
-static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
+static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[],
+			    struct netlink_ext_ack *extack)
 {
 	if (dev) {
 		if (tb[IFLA_ADDRESS] &&
@@ -2295,7 +2296,7 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
 				return -EOPNOTSUPP;
 
 			if (af_ops->validate_link_af) {
-				err = af_ops->validate_link_af(dev, af);
+				err = af_ops->validate_link_af(dev, af, extack);
 				if (err < 0)
 					return err;
 			}
@@ -2603,7 +2604,7 @@ static int do_setlink(const struct sk_buff *skb,
 	const struct net_device_ops *ops = dev->netdev_ops;
 	int err;
 
-	err = validate_linkmsg(dev, tb);
+	err = validate_linkmsg(dev, tb, extack);
 	if (err < 0)
 		return err;
 
@@ -3301,7 +3302,7 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 			m_ops = master_dev->rtnl_link_ops;
 	}
 
-	err = validate_linkmsg(dev, tb);
+	err = validate_linkmsg(dev, tb, extack);
 	if (err < 0)
 		return err;
 
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 73721a4448bd..26856064096a 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1950,7 +1950,8 @@ static const struct nla_policy inet_af_policy[IFLA_INET_MAX+1] = {
 };
 
 static int inet_validate_link_af(const struct net_device *dev,
-				 const struct nlattr *nla)
+				 const struct nlattr *nla,
+				 struct netlink_ext_ack *extack)
 {
 	struct nlattr *a, *tb[IFLA_INET_MAX+1];
 	int err, rem;
@@ -1959,7 +1960,7 @@ static int inet_validate_link_af(const struct net_device *dev,
 		return -EAFNOSUPPORT;
 
 	err = nla_parse_nested_deprecated(tb, IFLA_INET_MAX, nla,
-					  inet_af_policy, NULL);
+					  inet_af_policy, extack);
 	if (err < 0)
 		return err;
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3bf685fe64b9..59792779551e 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5784,7 +5784,8 @@ static int check_stable_privacy(struct inet6_dev *idev, struct net *net,
 }
 
 static int inet6_validate_link_af(const struct net_device *dev,
-				  const struct nlattr *nla)
+				  const struct nlattr *nla,
+				  struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[IFLA_INET6_MAX + 1];
 	struct inet6_dev *idev = NULL;
@@ -5797,7 +5798,7 @@ static int inet6_validate_link_af(const struct net_device *dev,
 	}
 
 	err = nla_parse_nested_deprecated(tb, IFLA_INET6_MAX, nla,
-					  inet6_af_policy, NULL);
+					  inet6_af_policy, extack);
 	if (err)
 		return err;
 
-- 
2.18.0

From linus.walleij at linaro.org  Tue Aug  3 05:25:15 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 3 Aug 2021 14:25:15 +0200
Subject: [GIT PULL] Ux500 DTS changes for the v5.15 kernel cycle
Message-ID: <CACRpkdbjBv5ywZZD8rK07d5sLcHsG8o4iYD-3jHO=HLg6-nKnA@mail.gmail.com>

Hi SoC maintainers,

here is a first set of DTS changes for v5.15 that would be nice if
you could pull into the appropriate DTS branch in the SoC tree.

The details are in the signed tag, mainly some new phones,
and some generic fixes.

Please pull it in!

Yours,
Linus Walleij

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
tags/ux500-dts-v5.15-1

for you to fetch changes up to fe2fc0fd379371af510caf39181460f2eed4c35b:

  ARM: dts: ux500: Adjust operating points to reality (2021-08-02
01:41:59 +0200)

----------------------------------------------------------------
Ux500 Device Tree updates for the v5.15 kernel cycle:

- New device trees for these mobile phones:
  - Samsung Gavini
  - Samsung Codina
  - Samsung Kyle
- Flag eMMC cards as non-SD non-SDIO to save time
- Link USB PHY to USB controller in the device tree
- Fix up the operating points to the actual clock frequencies

----------------------------------------------------------------
Linus Walleij (5):
      ARM: dts: ux500: Add device tree for Samsung Gavini
      ARM: dts: ux500: Flag eMMCs as non-SDIO/SD
      ARM: dts: ux500: Add devicetree for Codina
      ARM: dts: ux500: Add a device tree for Kyle
      ARM: dts: ux500: Adjust operating points to reality

Stephan Gerhold (1):
      ARM: dts: ux500: ab8500: Link USB PHY to USB controller node

 arch/arm/boot/dts/Makefile                     |   5 +-
 arch/arm/boot/dts/ste-ab8500.dtsi              |   8 +-
 arch/arm/boot/dts/ste-ab8505.dtsi              |   6 +
 arch/arm/boot/dts/ste-db8500.dtsi              |   7 +-
 arch/arm/boot/dts/ste-db8520.dtsi              |   7 +-
 arch/arm/boot/dts/ste-db9500.dtsi              |   9 +-
 arch/arm/boot/dts/ste-dbx5x0-pinctrl.dtsi      |  18 +
 arch/arm/boot/dts/ste-href.dtsi                |   4 +
 arch/arm/boot/dts/ste-snowball.dts             |   2 +
 arch/arm/boot/dts/ste-ux500-samsung-codina.dts | 863 +++++++++++++++++++++++++
 arch/arm/boot/dts/ste-ux500-samsung-gavini.dts | 854 ++++++++++++++++++++++++
 arch/arm/boot/dts/ste-ux500-samsung-golden.dts |   2 +
 arch/arm/boot/dts/ste-ux500-samsung-janice.dts |   2 +
 arch/arm/boot/dts/ste-ux500-samsung-kyle.dts   | 664 +++++++++++++++++++
 arch/arm/boot/dts/ste-ux500-samsung-skomer.dts |   2 +
 15 files changed, 2438 insertions(+), 15 deletions(-)
 create mode 100644 arch/arm/boot/dts/ste-ux500-samsung-codina.dts
 create mode 100644 arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
 create mode 100644 arch/arm/boot/dts/ste-ux500-samsung-kyle.dts


From arnd at kernel.org  Tue Aug  3 05:29:00 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 3 Aug 2021 14:29:00 +0200
Subject: [PATCH] ARM: ep93xx: remove MaverickCrunch support
In-Reply-To: <CACRpkdbRbgjo1AkZVd0J1nhuo601o8=20rKR+ccaJR1+vqn6qg@mail.gmail.com>
References: <20210802141245.1146772-1-arnd@kernel.org>
 <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>
 <CACRpkdbRbgjo1AkZVd0J1nhuo601o8=20rKR+ccaJR1+vqn6qg@mail.gmail.com>
Message-ID: <CAK8P3a0QTxd4ghTYz7kRWnxLrL8hBQ1PwNuR4ptLw-dOkKmPPg@mail.gmail.com>

On Tue, Aug 3, 2021 at 2:12 PM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Mon, Aug 2, 2021 at 5:45 PM Martin Guy <martinwguy at gmail.com> wrote:
>
> > > was removed from gcc in its 4.8 release in 2012.
> >
> > I was sad about that, as I had managed to get it working correctly in
> > 4.2 4.3 and 4.4.
> > Unfortunately the GCC ARM maintainer at the time was paid by ARM, and
> > they had no interest in it, as I gather the ARM-Cirrus partnership
> > ended up disappointingly.
>
> Political issues aside, have you considered contributing support
> to LLVM instead?
>
> It currently doesn't even support ARMv4 AFAIK but reportedly
> has an easier to use and maintain back-end. (I do not know if
> this is true, I just browsed this:
> https://llvm.org/docs/WritingAnLLVMBackend.html )
> Current ARM Targets are here:
> https://github.com/llvm/llvm-project/tree/main/llvm/lib/Target/ARM
> And they have a very clear and straight-forward developer policy:
> https://llvm.org/docs/DeveloperPolicy.html
>
> If ARMv4 support could be added to LLVM, that would solve
> a lot of my headaches for ARM32, where we have things like
> SA110 being actively maintained.

I think for ARMv4 support, the only thing we need from llvm is
to have R_ARM_V4BX relocations, and for lld to support the
--fix-v4bx switch that turns 'bx' instructions into 'mov' when those
relocations are found. This is something that we have previously
discussed with the llvm developers and that may easily happen.

For the Crunch support, I don't think it's worth spending any effort
on adding that to llvm. If there are any remaining users, they have
probably stopped upgrading their user space long ago (to be
confirmed). The SoC itself has been "not recommended for new
design" since 2019, so we are unlikely to see new users of the platform
in the future, and I think existing users are equally unlikely to move
from softfp to crunch even if they have the option.

       Arnd


From james.clark at arm.com  Tue Aug  3 05:29:45 2021
From: james.clark at arm.com (James Clark)
Date: Tue, 3 Aug 2021 13:29:45 +0100
Subject: [PATCH 3/6] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <20210802120545.GJ7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-4-james.clark@arm.com>
 <20210731074343.GG7437@leoy-ThinkPad-X240s>
 <CAJ9a7Vj_KhV+v6VU+EQN5t818VS9jvf3v3-2JbwVMOHZbi3gcg@mail.gmail.com>
 <20210802120545.GJ7437@leoy-ThinkPad-X240s>
Message-ID: <ef068f6a-0a31-bd34-7140-5d7cca331369@arm.com>



On 02/08/2021 13:05, Leo Yan wrote:
> If so, I understand your suggestion in another email to add a new magic
> number and a new protocol (this patch set has added the new protocol
> CS_ETM_PROTO_ETE) for creating ETE decoder.

Yes this is what I'm working on now. I think that it's actually
cleaner than the previous change where there was some half way
solution that old versions of perf wouldn't properly decode ETE
but would try to anyway.

James


From james.clark at arm.com  Tue Aug  3 05:33:01 2021
From: james.clark at arm.com (James Clark)
Date: Tue, 3 Aug 2021 13:33:01 +0100
Subject: [PATCH 3/6] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <20210731063731.GC7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-4-james.clark@arm.com>
 <CAJ9a7Vjz_CMugYrLcAqr_aFsK6jYcqR3xLwJUi9KTXB3aPjnEQ@mail.gmail.com>
 <20210731063731.GC7437@leoy-ThinkPad-X240s>
Message-ID: <6d1954d2-28bc-4b70-25fc-e74d63cc86cd@arm.com>



On 31/07/2021 07:37, Leo Yan wrote:
> I checked ETMv4.3 and ETMv4.4 spec (ARM IHI0064E for ETMv4.3 and ARM
> IHI0064F for ETMv4.4), both clarify ETMv4 has the register TRCDEVARCH;
> thus TRCDEVARCH is not a new register introduced by ETE.
> 
> For this case, it's good to directly add a new field in the metadata
> array for recording register TRCDEVARCH.

This might be true, but the OpenCSD library doesn't take TRCDEVARCH as a config
parameter for ETMv4 so it couldn't be used. This is the struct:

        typedef struct _ocsd_etmv4_cfg 
        {
        uint32_t                reg_idr0;    /**< ID0 register */
        uint32_t                reg_idr1;    /**< ID1 register */
        uint32_t                reg_idr2;    /**< ID2 register */
        uint32_t                reg_idr8;
        uint32_t                reg_idr9;   
        uint32_t                reg_idr10;
        uint32_t                reg_idr11;
        uint32_t                reg_idr12;
        uint32_t                reg_idr13;
        uint32_t                reg_configr;  /**< Config Register */
        uint32_t                reg_traceidr;  /**< Trace Stream ID register */
        ocsd_arch_version_t    arch_ver;   /**< Architecture version */
        ocsd_core_profile_t    core_prof;  /**< Core Profile */
        } ocsd_etmv4_cfg;

And this is ETE where TRCDEVARCH is used:

        typedef struct _ocsd_ete_cfg
        {
        uint32_t                reg_idr0;       /**< ID0 register */
        uint32_t                reg_idr1;       /**< ID1 register */
        uint32_t                reg_idr2;       /**< ID2 register */
        uint32_t                reg_idr8;       /**< ID8 - maxspec */
        uint32_t                reg_devarch;    /**< DevArch register */
        uint32_t                reg_configr;    /**< Config Register */
        uint32_t                reg_traceidr;   /**< Trace Stream ID register */
        ocsd_arch_version_t    arch_ver;        /**< Architecture version */
        ocsd_core_profile_t    core_prof;       /**< Core Profile */
        } ocsd_ete_cfg;

Thanks
James


From james.clark at arm.com  Tue Aug  3 05:34:36 2021
From: james.clark at arm.com (James Clark)
Date: Tue, 3 Aug 2021 13:34:36 +0100
Subject: [PATCH 3/6] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <20210731063731.GC7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-4-james.clark@arm.com>
 <CAJ9a7Vjz_CMugYrLcAqr_aFsK6jYcqR3xLwJUi9KTXB3aPjnEQ@mail.gmail.com>
 <20210731063731.GC7437@leoy-ThinkPad-X240s>
Message-ID: <9156d7a1-3676-ab98-2c38-26f9765b845c@arm.com>



On 31/07/2021 07:37, Leo Yan wrote:
>>> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
>>> index 85168d87b2d7..65a863bdf5cc 100644
>>> --- a/tools/perf/arch/arm/util/cs-etm.c
>>> +++ b/tools/perf/arch/arm/util/cs-etm.c
>>> @@ -53,6 +53,7 @@ static const char *metadata_etmv4_ro[CS_ETMV4_PRIV_MAX] = {
>>>         [CS_ETMV4_TRCIDR2]              = "trcidr/trcidr2",
>>>         [CS_ETMV4_TRCIDR8]              = "trcidr/trcidr8",
>>>         [CS_ETMV4_TRCAUTHSTATUS]        = "mgmt/trcauthstatus",
>>> +       [CS_ETE_TRCDEVARCH]             = "mgmt/trcdevarch"
> ETMv4 supports TRCDEVARCH, so I think it's good to use the naming
> "CS_ETMV4_TRCDEVARCH"?
> 

Based on the other discussions do you still think I should do this?

As part of the new magic number I moved it into a new enum so it
might be clearer now?

James


From will at kernel.org  Tue Aug  3 05:35:49 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 3 Aug 2021 13:35:49 +0100
Subject: [PATCH v2 23/24] iommu/arm-smmu: Allow non-strict in
 pgtable_quirks interface
In-Reply-To: <529750e7-89a0-cfb7-8cef-36bb78b06340@arm.com>
References: <cover.1627468308.git.robin.murphy@arm.com>
 <0fcd1f5225a6b435cbc697551a6247cd435c04db.1627468310.git.robin.murphy@arm.com>
 <20210802130438.GA28547@willie-the-truck>
 <3dd7cdae-7111-6ff2-6350-a0e19fe4ab66@arm.com>
 <20210803103559.GA30690@willie-the-truck>
 <529750e7-89a0-cfb7-8cef-36bb78b06340@arm.com>
Message-ID: <20210803123548.GA30932@willie-the-truck>

On Tue, Aug 03, 2021 at 01:13:12PM +0100, Robin Murphy wrote:
> On 2021-08-03 11:36, Will Deacon wrote:
> > Overall, I'm really nervous about the concurrency here and think we'd be
> > better off requiring the unbind as we have for the other domain changes.
> 
> Sure, the dynamic switch is what makes it ultimately work for Doug's
> use-case (where the unbind isn't viable), but I had every expectation that
> we might need to hold back those two patches for much deeper consideration.
> It's no accident that the first 22 patches can still be usefully applied
> without them!

Oh, the rest of the series looks great which is why I jumped on this bit!

> In all honesty I don't really like this particular patch much, mostly
> because I increasingly dislike IO_PGTABLE_QUIRK_NON_STRICT at all, but since
> the interface was there it made it super easy to prove the concept. I have a
> more significant refactoring of the io-pgtable code sketched out in my mind
> already, it's just going to be more work.

Intriguing... Move the smp_wmb() into the IOVA code instead?

> > With your changes, I think quite a few things can go wrong.
> > 
> >    * cookie->fq_domain may be observed but iovad->fq could be NULL
> 
> Good point, I guess that already technically applies (if iovad->fq sat in a
> write buffer long enough), but it certainly becomes far easier to provoke.
> However a barrier after assigning fq_domain (as mentioned above) paired with
> the control dependency around the queue_iova() call would also fix that,
> right?
> 
> >    * We can miss the smp_wmb() in the pgtable code but end up deferring the
> >      IOVA reclaim
> >    * iommu_change_dev_def_domain() only holds the group mutex afaict, so can
> >      possibly run concurrently with itself on the same domain?
> >    * iommu_dma_init_fq() can flip the domain type back from
> >      IOMMU_DOMAIN_DMA_FQ to IOMMU_DOMAIN_DMA on the error path
> >    * set_pgtable_quirks() isn't atomic, which probably is ok for now, but the
> >      moment we use it anywhere else it's dangerous
> 
> In other words, IO_PGTABLE_QUIRK_NON_STRICT is definitely the problem. I'll
> have a hack on that this afternoon, and if it starts to look rabbit-holey
> I'll split this bit off and post v3 of the rest of the series.
> 
> If all the io-pgtable and fq behaviour for a given call could be consistent
> based on a single READ_ONCE(cookie->fq_domain) in iommu_dma_unmap(), do you
> see any remaining issues other than the point above?

I'd have to see the patches, and I didn't look exhaustively at the current
stuff. But yes, I think the basic flow needs to be that there is an atomic
flag (i.e. cookie->fq_domain) which indicates which mode is being used
and if you flip that concurrently then you need to guarantee that everybody
is either using the old more or the new mode and not some halfway state in
between.

Will


From james.clark at arm.com  Tue Aug  3 05:36:10 2021
From: james.clark at arm.com (James Clark)
Date: Tue, 3 Aug 2021 13:36:10 +0100
Subject: [PATCH 3/6] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <20210731063731.GC7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-4-james.clark@arm.com>
 <CAJ9a7Vjz_CMugYrLcAqr_aFsK6jYcqR3xLwJUi9KTXB3aPjnEQ@mail.gmail.com>
 <20210731063731.GC7437@leoy-ThinkPad-X240s>
Message-ID: <ed38005f-7723-6b62-ebcb-3db750604b6a@arm.com>



On 31/07/2021 07:37, Leo Yan wrote:
>>> diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
>>> index d65c7b19407d..52d82dce9d59 100644
>>> --- a/tools/perf/util/cs-etm.h
>>> +++ b/tools/perf/util/cs-etm.h
>>> @@ -59,7 +59,7 @@ enum {
>>>  /* define fixed version 0 length - allow new format reader to read old files. */
>>>  #define CS_ETM_NR_TRC_PARAMS_V0 (CS_ETM_ETMIDR - CS_ETM_ETMCR + 1)
>>>
>>> -/* ETMv4 metadata */
>>> +/* ETMv4 + ETE metadata */
>>>  enum {
>>>         /* Dynamic, configurable parameters */
>>>         CS_ETMV4_TRCCONFIGR = CS_ETM_COMMON_BLK_MAX_V1,
>>> @@ -70,7 +70,8 @@ enum {
>>>         CS_ETMV4_TRCIDR2,
>>>         CS_ETMV4_TRCIDR8,
>>>         CS_ETMV4_TRCAUTHSTATUS,
>>> -       CS_ETMV4_PRIV_MAX,
>>> +       CS_ETE_TRCDEVARCH,
>>> +       CS_ETMV4_PRIV_MAX
> Spurious change for "CS_ETMV4_PRIV_MAX"?

This change will be removed in the next version due to moving it into
a new enum. But it wasn't a mistake, CS_ETMV4_PRIV_MAX is used to define the length
of the header so it always needs to be at the end if another item is saved.

James


From dqfext at gmail.com  Tue Aug  3 05:40:18 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue,  3 Aug 2021 20:40:18 +0800
Subject: [PATCH net-next 0/4] mt7530 software fallback bridging fix
Message-ID: <20210803124022.2912298-1-dqfext@gmail.com>

DSA core has gained software fallback support since commit 2f5dc00f7a3e,
but it does not work properly on mt7530. This patch series fixes the
issues.

DENG Qingfang (4):
  net: dsa: mt7530: enable assisted learning on CPU port
  net: dsa: mt7530: use independent VLAN learning on VLAN-unaware
    bridges
  net: dsa: mt7530: set STP state on filter ID 1
  net: dsa: mt7530: always install FDB entries with IVL and FID 1

 drivers/net/dsa/mt7530.c | 87 +++++++++++++++++++++++++++-------------
 drivers/net/dsa/mt7530.h |  9 +++--
 2 files changed, 66 insertions(+), 30 deletions(-)

-- 
2.25.1



From dqfext at gmail.com  Tue Aug  3 05:40:19 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue,  3 Aug 2021 20:40:19 +0800
Subject: [PATCH net-next 1/4] net: dsa: mt7530: enable assisted learning on
 CPU port
In-Reply-To: <20210803124022.2912298-1-dqfext@gmail.com>
References: <20210803124022.2912298-1-dqfext@gmail.com>
Message-ID: <20210803124022.2912298-2-dqfext@gmail.com>

Consider the following bridge configuration, where bond0 is not
offloaded:

         +-- br0 --+
        / /   |     \
       / /    |      \
      /  |    |     bond0
     /   |    |     /   \
   swp0 swp1 swp2 swp3 swp4
     .        .       .
     .        .       .
     A        B       C

Address learning is enabled on offloaded ports (swp0~2) and the CPU
port, so when client A sends a packet to C, the following will happen:

1. The switch learns that client A can be reached at swp0.
2. The switch probably already knows that client C can be reached at the
   CPU port, so it forwards the packet to the CPU.
3. The bridge core knows client C can be reached at bond0, so it
   forwards the packet back to the switch.
4. The switch learns that client A can be reached at the CPU port.
5. The switch forwards the packet to either swp3 or swp4, according to
   the packet's tag.

That makes client A's MAC address flap between swp0 and the CPU port. If
client B sends a packet to A, it is possible that the packet is
forwarded to the CPU. With offload_fwd_mark = 1, the bridge core won't
forward it back to the switch, resulting in packet loss.

As we have the assisted_learning_on_cpu_port in DSA core now, enable
that and disable hardware learning on the CPU port.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
Reviewed-by: Vladimir Oltean <oltean at gmail.com>
---
RFC -> v1: no changes.

 drivers/net/dsa/mt7530.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index b6e0b347947e..abe57b04fc39 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2046,6 +2046,7 @@ mt7530_setup(struct dsa_switch *ds)
 	 * as two netdev instances.
 	 */
 	dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
+	ds->assisted_learning_on_cpu_port = true;
 	ds->mtu_enforcement_ingress = true;
 
 	if (priv->id == ID_MT7530) {
@@ -2116,15 +2117,15 @@ mt7530_setup(struct dsa_switch *ds)
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
 
+		/* Disable learning by default on all ports */
+		mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+
 		if (dsa_is_cpu_port(ds, i)) {
 			ret = mt753x_cpu_port_enable(ds, i);
 			if (ret)
 				return ret;
 		} else {
 			mt7530_port_disable(ds, i);
-
-			/* Disable learning by default on all user ports */
-			mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
 		}
 		/* Enable consistent egress tag */
 		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
@@ -2281,6 +2282,9 @@ mt7531_setup(struct dsa_switch *ds)
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
 
+		/* Disable learning by default on all ports */
+		mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+
 		mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
 
 		if (dsa_is_cpu_port(ds, i)) {
@@ -2289,9 +2293,6 @@ mt7531_setup(struct dsa_switch *ds)
 				return ret;
 		} else {
 			mt7530_port_disable(ds, i);
-
-			/* Disable learning by default on all user ports */
-			mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
 		}
 
 		/* Enable consistent egress tag */
@@ -2299,6 +2300,7 @@ mt7531_setup(struct dsa_switch *ds)
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 	}
 
+	ds->assisted_learning_on_cpu_port = true;
 	ds->mtu_enforcement_ingress = true;
 
 	/* Flush the FDB table */
-- 
2.25.1



From dqfext at gmail.com  Tue Aug  3 05:40:20 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue,  3 Aug 2021 20:40:20 +0800
Subject: [PATCH net-next 2/4] net: dsa: mt7530: use independent VLAN learning
 on VLAN-unaware bridges
In-Reply-To: <20210803124022.2912298-1-dqfext@gmail.com>
References: <20210803124022.2912298-1-dqfext@gmail.com>
Message-ID: <20210803124022.2912298-3-dqfext@gmail.com>

Consider the following bridge configuration, where bond0 is not
offloaded:

         +-- br0 --+
        / /   |     \
       / /    |      \
      /  |    |     bond0
     /   |    |     /   \
   swp0 swp1 swp2 swp3 swp4
     .        .       .
     .        .       .
     A        B       C

Ideally, when the switch receives a packet from swp3 or swp4, it should
forward the packet to the CPU, according to the port matrix and unknown
unicast flood settings.

But packet loss will happen if the destination address is at one of the
offloaded ports (swp0~2). For example, when client C sends a packet to
A, the FDB lookup will indicate that it should be forwarded to swp0, but
the port matrix of swp3 and swp4 is configured to only allow the CPU to
be its destination, so it is dropped.

However, this issue does not happen if the bridge is VLAN-aware. That is
because VLAN-aware bridges use independent VLAN learning, i.e. use VID
for FDB lookup, on offloaded ports. As swp3 and swp4 are not offloaded,
shared VLAN learning with default filter ID of 0 is used instead. So the
lookup for A with filter ID 0 never hits and the packet can be forwarded
to the CPU.

In the current code, only two combinations were used to toggle user
ports' VLAN awareness: one is PCR.PORT_VLAN set to port matrix mode with
PVC.VLAN_ATTR set to transparent port, the other is PCR.PORT_VLAN set to
security mode with PVC.VLAN_ATTR set to user port.

It turns out that only PVC.VLAN_ATTR contributes to VLAN awareness, and
port matrix mode just skips the VLAN table lookup. The reference manual
is somehow misleading when describing PORT_VLAN modes. It states that
PORT_MEM (VLAN port member) is used for destination if the VLAN table
lookup hits, but actually **PORT_MEM & PORT_MATRIX** (bitwise AND of
VLAN port member and port matrix) is used instead, which means we can
have two or more separate VLAN-aware bridges with the same PVID and
traffic won't leak between them.

Therefore, to solve this, enable independent VLAN learning with PVID 0
on VLAN-unaware bridges, by setting their PCR.PORT_VLAN to fallback
mode, while leaving standalone ports in port matrix mode. The CPU port
is always set to fallback mode to serve those bridges.

During testing, it is found that FDB lookup with filter ID of 0 will
also hit entries with VID 0 even with independent VLAN learning. To
avoid that, install all VLANs with filter ID of 1.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
---
RFC -> v1: no changes.

 drivers/net/dsa/mt7530.c | 70 ++++++++++++++++++++++++++++------------
 drivers/net/dsa/mt7530.h |  4 ++-
 2 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index abe57b04fc39..12f449a54833 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1021,6 +1021,10 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
 	mt7530_write(priv, MT7530_PCR_P(port),
 		     PCR_MATRIX(dsa_user_ports(priv->ds)));
 
+	/* Set to fallback mode for independent VLAN learning */
+	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
+		   MT7530_PORT_FALLBACK_MODE);
+
 	return 0;
 }
 
@@ -1229,6 +1233,10 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
 			   PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
 	priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
 
+	/* Set to fallback mode for independent VLAN learning */
+	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
+		   MT7530_PORT_FALLBACK_MODE);
+
 	mutex_unlock(&priv->reg_mutex);
 
 	return 0;
@@ -1241,16 +1249,21 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
 	bool all_user_ports_removed = true;
 	int i;
 
-	/* When a port is removed from the bridge, the port would be set up
-	 * back to the default as is at initial boot which is a VLAN-unaware
-	 * port.
+	/* This is called after .port_bridge_leave when leaving a VLAN-aware
+	 * bridge. Don't set standalone ports to fallback mode.
 	 */
-	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
-		   MT7530_PORT_MATRIX_MODE);
+	if (dsa_to_port(ds, port)->bridge_dev)
+		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
+			   MT7530_PORT_FALLBACK_MODE);
+
 	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
 		   VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
 		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 
+	/* Set PVID to 0 */
+	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
+		   G0_PORT_VID_DEF);
+
 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
 		if (dsa_is_user_port(ds, i) &&
 		    dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
@@ -1276,15 +1289,14 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
 	struct mt7530_priv *priv = ds->priv;
 
 	/* Trapped into security mode allows packet forwarding through VLAN
-	 * table lookup. CPU port is set to fallback mode to let untagged
-	 * frames pass through.
+	 * table lookup.
 	 */
-	if (dsa_is_cpu_port(ds, port))
-		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
-			   MT7530_PORT_FALLBACK_MODE);
-	else
+	if (dsa_is_user_port(ds, port)) {
 		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
 			   MT7530_PORT_SECURITY_MODE);
+		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
+			   G0_PORT_VID(priv->ports[port].pvid));
+	}
 
 	/* Set the port as a user port which is to be able to recognize VID
 	 * from incoming packets before fetching entry within the VLAN table.
@@ -1329,6 +1341,13 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 			   PCR_MATRIX(BIT(MT7530_CPU_PORT)));
 	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
 
+	/* When a port is removed from the bridge, the port would be set up
+	 * back to the default as is at initial boot which is a VLAN-unaware
+	 * port.
+	 */
+	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
+		   MT7530_PORT_MATRIX_MODE);
+
 	mutex_unlock(&priv->reg_mutex);
 }
 
@@ -1511,7 +1530,7 @@ mt7530_hw_vlan_add(struct mt7530_priv *priv,
 	/* Validate the entry with independent learning, create egress tag per
 	 * VLAN and joining the port as one of the port members.
 	 */
-	val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | VLAN_VALID;
+	val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | FID(1) | VLAN_VALID;
 	mt7530_write(priv, MT7530_VAWD1, val);
 
 	/* Decide whether adding tag or not for those outgoing packets from the
@@ -1601,9 +1620,13 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
 	mt7530_hw_vlan_update(priv, vlan->vid, &new_entry, mt7530_hw_vlan_add);
 
 	if (pvid) {
-		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
-			   G0_PORT_VID(vlan->vid));
 		priv->ports[port].pvid = vlan->vid;
+
+		/* Only configure PVID if VLAN filtering is enabled */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
+			mt7530_rmw(priv, MT7530_PPBV1_P(port),
+				   G0_PORT_VID_MASK,
+				   G0_PORT_VID(vlan->vid));
 	}
 
 	mutex_unlock(&priv->reg_mutex);
@@ -1617,11 +1640,9 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
 {
 	struct mt7530_hw_vlan_entry target_entry;
 	struct mt7530_priv *priv = ds->priv;
-	u16 pvid;
 
 	mutex_lock(&priv->reg_mutex);
 
-	pvid = priv->ports[port].pvid;
 	mt7530_hw_vlan_entry_init(&target_entry, port, 0);
 	mt7530_hw_vlan_update(priv, vlan->vid, &target_entry,
 			      mt7530_hw_vlan_del);
@@ -1629,11 +1650,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
 	/* PVID is being restored to the default whenever the PVID port
 	 * is being removed from the VLAN.
 	 */
-	if (pvid == vlan->vid)
-		pvid = G0_PORT_VID_DEF;
+	if (priv->ports[port].pvid == vlan->vid) {
+		priv->ports[port].pvid = G0_PORT_VID_DEF;
+		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
+			   G0_PORT_VID_DEF);
+	}
 
-	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, pvid);
-	priv->ports[port].pvid = pvid;
 
 	mutex_unlock(&priv->reg_mutex);
 
@@ -2126,6 +2148,10 @@ mt7530_setup(struct dsa_switch *ds)
 				return ret;
 		} else {
 			mt7530_port_disable(ds, i);
+
+			/* Set default PVID to 0 on all user ports */
+			mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
+				   G0_PORT_VID_DEF);
 		}
 		/* Enable consistent egress tag */
 		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
@@ -2293,6 +2319,10 @@ mt7531_setup(struct dsa_switch *ds)
 				return ret;
 		} else {
 			mt7530_port_disable(ds, i);
+
+			/* Set default PVID to 0 on all user ports */
+			mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
+				   G0_PORT_VID_DEF);
 		}
 
 		/* Enable consistent egress tag */
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index b19b389ff10a..a308886fdebc 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -148,6 +148,8 @@ enum mt7530_vlan_cmd {
 #define  VTAG_EN			BIT(28)
 /* VLAN Member Control */
 #define  PORT_MEM(x)			(((x) & 0xff) << 16)
+/* Filter ID */
+#define  FID(x)				(((x) & 0x7) << 1)
 /* VLAN Entry Valid */
 #define  VLAN_VALID			BIT(0)
 #define  PORT_MEM_SHFT			16
@@ -247,7 +249,7 @@ enum mt7530_vlan_port_attr {
 #define MT7530_PPBV1_P(x)		(0x2014 + ((x) * 0x100))
 #define  G0_PORT_VID(x)			(((x) & 0xfff) << 0)
 #define  G0_PORT_VID_MASK		G0_PORT_VID(0xfff)
-#define  G0_PORT_VID_DEF		G0_PORT_VID(1)
+#define  G0_PORT_VID_DEF		G0_PORT_VID(0)
 
 /* Register for port MAC control register */
 #define MT7530_PMCR_P(x)		(0x3000 + ((x) * 0x100))
-- 
2.25.1



From dqfext at gmail.com  Tue Aug  3 05:40:21 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue,  3 Aug 2021 20:40:21 +0800
Subject: [PATCH net-next 3/4] net: dsa: mt7530: set STP state on filter ID 1
In-Reply-To: <20210803124022.2912298-1-dqfext@gmail.com>
References: <20210803124022.2912298-1-dqfext@gmail.com>
Message-ID: <20210803124022.2912298-4-dqfext@gmail.com>

As filter ID 1 is the only one used for bridges, set STP state on it.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
RFC -> v1: only set FID 1's state

 drivers/net/dsa/mt7530.c | 3 ++-
 drivers/net/dsa/mt7530.h | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 12f449a54833..8d84d7ddad38 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1147,7 +1147,8 @@ mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 		break;
 	}
 
-	mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK, stp_state);
+	mt7530_rmw(priv, MT7530_SSP_P(port), FID1_PST_MASK,
+		   FID1_PST(stp_state));
 }
 
 static int
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index a308886fdebc..53b7bb1f5368 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -181,8 +181,8 @@ enum mt7530_vlan_egress_attr {
 
 /* Register for port STP state control */
 #define MT7530_SSP_P(x)			(0x2000 + ((x) * 0x100))
-#define  FID_PST(x)			((x) & 0x3)
-#define  FID_PST_MASK			FID_PST(0x3)
+#define  FID1_PST(x)			(((x) & 0x3) << 2)
+#define  FID1_PST_MASK			FID1_PST(0x3)
 
 enum mt7530_stp_state {
 	MT7530_STP_DISABLED = 0,
-- 
2.25.1



From dqfext at gmail.com  Tue Aug  3 05:40:22 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue,  3 Aug 2021 20:40:22 +0800
Subject: [PATCH net-next 4/4] net: dsa: mt7530: always install FDB entries
 with IVL and FID 1
In-Reply-To: <20210803124022.2912298-1-dqfext@gmail.com>
References: <20210803124022.2912298-1-dqfext@gmail.com>
Message-ID: <20210803124022.2912298-5-dqfext@gmail.com>

This reverts commit 7e777021780e ("mt7530 mt7530_fdb_write only set ivl
bit vid larger than 1").

Before this series, the default value of all ports' PVID is 1, which is
copied into the FDB entry, even if the ports are VLAN unaware. So
`bridge fdb show` will show entries like `dev swp0 vlan 1 self` even on
a VLAN-unaware bridge.

The blamed commit does not solve that issue completely, instead it may
cause a new issue that FDB is inaccessible in a VLAN-aware bridge with
PVID 1.

This series sets PVID to 0 on VLAN-unaware ports, so `bridge fdb show`
will no longer print `vlan 1` on VLAN-unaware bridges, and that special
case in fdb_write is not required anymore.

Set FDB entries' filter ID to 1 to match the VLAN table.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
RFC -> v1: Detailed commit message. Also set FDB entries' FID to 1.

 drivers/net/dsa/mt7530.c | 4 ++--
 drivers/net/dsa/mt7530.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 8d84d7ddad38..ac2b45e472bd 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -366,8 +366,8 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
 	int i;
 
 	reg[1] |= vid & CVID_MASK;
-	if (vid > 1)
-		reg[1] |= ATA2_IVL;
+	reg[1] |= ATA2_IVL;
+	reg[1] |= ATA2_FID(1);
 	reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
 	reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
 	/* STATIC_ENT indicate that entry is static wouldn't
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 53b7bb1f5368..73b0e0eb8f2f 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -80,6 +80,7 @@ enum mt753x_bpdu_port_fw {
 #define  STATIC_ENT			3
 #define MT7530_ATA2			0x78
 #define  ATA2_IVL			BIT(15)
+#define  ATA2_FID(x)			(((x) & 0x7) << 12)
 
 /* Register for address table write data */
 #define MT7530_ATWD			0x7c
-- 
2.25.1



From patrice.chotard at foss.st.com  Tue Aug  3 05:45:03 2021
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Tue, 3 Aug 2021 14:45:03 +0200
Subject: [PATCH 1/4] ARM: dts: sti: remove clk_ignore_unused from bootargs for
 stih407-b2120
In-Reply-To: <20210803124506.23365-1-patrice.chotard@foss.st.com>
References: <20210803124506.23365-1-patrice.chotard@foss.st.com>
Message-ID: <20210803124506.23365-2-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Remove clk_ignore_unused from bootargs as it's no more needed.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/boot/dts/stih407-b2120.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/stih407-b2120.dts b/arch/arm/boot/dts/stih407-b2120.dts
index 31c85f945c6b..9c79982ee7ba 100644
--- a/arch/arm/boot/dts/stih407-b2120.dts
+++ b/arch/arm/boot/dts/stih407-b2120.dts
@@ -11,7 +11,6 @@
 	compatible = "st,stih407-b2120", "st,stih407";
 
 	chosen {
-		bootargs = "clk_ignore_unused";
 		stdout-path = &sbc_serial0;
 	};
 
-- 
2.17.1



From patrice.chotard at foss.st.com  Tue Aug  3 05:45:04 2021
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Tue, 3 Aug 2021 14:45:04 +0200
Subject: [PATCH 2/4] ARM: dts: sti: remove clk_ignore_unused from bootargs for
 stih410-b2120
In-Reply-To: <20210803124506.23365-1-patrice.chotard@foss.st.com>
References: <20210803124506.23365-1-patrice.chotard@foss.st.com>
Message-ID: <20210803124506.23365-3-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Remove clk_ignore_unused from bootargs as it's no more needed.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/boot/dts/stih410-b2120.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/stih410-b2120.dts b/arch/arm/boot/dts/stih410-b2120.dts
index 158b2268748e..9d3b118f5f0f 100644
--- a/arch/arm/boot/dts/stih410-b2120.dts
+++ b/arch/arm/boot/dts/stih410-b2120.dts
@@ -11,7 +11,6 @@
 	compatible = "st,stih410-b2120", "st,stih410";
 
 	chosen {
-		bootargs = "clk_ignore_unused";
 		stdout-path = &sbc_serial0;
 	};
 
-- 
2.17.1



From patrice.chotard at foss.st.com  Tue Aug  3 05:45:02 2021
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Tue, 3 Aug 2021 14:45:02 +0200
Subject: [PATCH 0/4] ARM: dts: sti: remove clk_ignore_unused from bootargs
Message-ID: <20210803124506.23365-1-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Remove clk_ignore_unused from bootargs from STi boards DT.

Patrice Chotard (4):
  ARM: dts: sti: remove clk_ignore_unused from bootargs for
    stih407-b2120
  ARM: dts: sti: remove clk_ignore_unused from bootargs for
    stih410-b2120
  ARM: dts: sti: remove clk_ignore_unused from bootargs for
    stih418-b2199
  ARM: dts: sti: remove clk_ignore_unused from bootargs for
    stih410-b2260

 arch/arm/boot/dts/stih407-b2120.dts | 1 -
 arch/arm/boot/dts/stih410-b2120.dts | 1 -
 arch/arm/boot/dts/stih410-b2260.dts | 1 -
 arch/arm/boot/dts/stih418-b2199.dts | 1 -
 4 files changed, 4 deletions(-)

-- 
2.17.1



From patrice.chotard at foss.st.com  Tue Aug  3 05:45:06 2021
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Tue, 3 Aug 2021 14:45:06 +0200
Subject: [PATCH 4/4] ARM: dts: sti: remove clk_ignore_unused from bootargs for
 stih410-b2260
In-Reply-To: <20210803124506.23365-1-patrice.chotard@foss.st.com>
References: <20210803124506.23365-1-patrice.chotard@foss.st.com>
Message-ID: <20210803124506.23365-5-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Remove clk_ignore_unused from bootargs as it's no more needed.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/boot/dts/stih410-b2260.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/stih410-b2260.dts b/arch/arm/boot/dts/stih410-b2260.dts
index e2bb59783146..9d579c16c295 100644
--- a/arch/arm/boot/dts/stih410-b2260.dts
+++ b/arch/arm/boot/dts/stih410-b2260.dts
@@ -12,7 +12,6 @@
 	compatible = "st,stih410-b2260", "st,stih410";
 
 	chosen {
-		bootargs = "clk_ignore_unused";
 		stdout-path = &uart1;
 	};
 
-- 
2.17.1



From patrice.chotard at foss.st.com  Tue Aug  3 05:45:05 2021
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Tue, 3 Aug 2021 14:45:05 +0200
Subject: [PATCH 3/4] ARM: dts: sti: remove clk_ignore_unused from bootargs for
 stih418-b2199
In-Reply-To: <20210803124506.23365-1-patrice.chotard@foss.st.com>
References: <20210803124506.23365-1-patrice.chotard@foss.st.com>
Message-ID: <20210803124506.23365-4-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Remove clk_ignore_unused from bootargs as it's no more needed.

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 arch/arm/boot/dts/stih418-b2199.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/stih418-b2199.dts b/arch/arm/boot/dts/stih418-b2199.dts
index 48c3c64e4c48..b66e2b29edea 100644
--- a/arch/arm/boot/dts/stih418-b2199.dts
+++ b/arch/arm/boot/dts/stih418-b2199.dts
@@ -11,7 +11,6 @@
 	compatible = "st,stih418-b2199", "st,stih418";
 
 	chosen {
-		bootargs = "clk_ignore_unused";
 		stdout-path = &sbc_serial0;
 	};
 
-- 
2.17.1



From bot at kernelci.org  Tue Aug  3 05:46:45 2021
From: bot at kernelci.org (kernelci.org bot)
Date: Tue, 03 Aug 2021 05:46:45 -0700 (PDT)
Subject: arm64/for-kernelci baseline: 43 runs,
 4 regressions (v5.14-rc4-6-gbee0cf777c04)
Message-ID: <61093ab5.1c69fb81.25063.c795@mx.google.com>

arm64/for-kernelci baseline: 43 runs, 4 regressions (v5.14-rc4-6-gbee0cf777c04)

Regressions Summary
-------------------

platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
bcm2837-rpi-3-b  | arm64 | lab-baylibre  | gcc-8    | defconfig | 1          
hip07-d05        | arm64 | lab-collabora | gcc-8    | defconfig | 1          
rk3399-gru-kevin | arm64 | lab-collabora | gcc-8    | defconfig | 2          

  Details:  https://kernelci.org/test/job/arm64/branch/for-kernelci/kernel/v5.14-rc4-6-gbee0cf777c04/plan/baseline/

  Test:     baseline
  Tree:     arm64
  Branch:   for-kernelci
  Describe: v5.14-rc4-6-gbee0cf777c04
  URL:      https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  SHA:      bee0cf777c04b3681789589403c009f6bcd055cd 


Test Regressions
---------------- 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
bcm2837-rpi-3-b  | arm64 | lab-baylibre  | gcc-8    | defconfig | 1          

  Details:     https://kernelci.org/test/plan/id/61093121b8e1e080d8b13662

  Results:     0 PASS, 1 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc4-6-gbee0cf777c04/arm64/defconfig/gcc-8/lab-baylibre/baseline-bcm2837-rpi-3-b.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc4-6-gbee0cf777c04/arm64/defconfig/gcc-8/lab-baylibre/baseline-bcm2837-rpi-3-b.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.login: https://kernelci.org/test/case/id/61093121b8e1e080d8b13663
        failing since 21 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1) 
 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
hip07-d05        | arm64 | lab-collabora | gcc-8    | defconfig | 1          

  Details:     https://kernelci.org/test/plan/id/6109313aefc84db165b13664

  Results:     0 PASS, 1 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc4-6-gbee0cf777c04/arm64/defconfig/gcc-8/lab-collabora/baseline-hip07-d05.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc4-6-gbee0cf777c04/arm64/defconfig/gcc-8/lab-collabora/baseline-hip07-d05.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.login: https://kernelci.org/test/case/id/6109313aefc84db165b13665
        failing since 32 days (last pass: v5.13-rc7-174-g8ab9b1a98a22, first fail: v5.13-13-g68ddb29c953a) 
 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
rk3399-gru-kevin | arm64 | lab-collabora | gcc-8    | defconfig | 2          

  Details:     https://kernelci.org/test/plan/id/61093198f59185b8bab13662

  Results:     89 PASS, 2 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc4-6-gbee0cf777c04/arm64/defconfig/gcc-8/lab-collabora/baseline-rk3399-gru-kevin.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc4-6-gbee0cf777c04/arm64/defconfig/gcc-8/lab-collabora/baseline-rk3399-gru-kevin.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.bootrr.rockchip-usb2phy1-probed: https://kernelci.org/test/case/id/61093198f59185b8bab1366c
        failing since 21 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1)

    2021-08-03T12:07:43.407288  <8>[   24.000212] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=rockchip-usb2phy0-probed RESULT=fail>
    2021-08-03T12:07:44.431054  /lava-4317122/1/../bin/lava-test-case
    2021-08-03T12:07:44.441963  <8>[   25.036053] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=rockchip-usb2phy1-probed RESULT=fail>   

  * baseline.bootrr.rockchip-usb2phy0-probed: https://kernelci.org/test/case/id/61093198f59185b8bab1366d
        failing since 21 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1)

    2021-08-03T12:07:43.395537  /lava-4317122/1/../bin/lava-test-case   
  


From cristian.marussi at arm.com  Tue Aug  3 05:52:17 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 3 Aug 2021 13:52:17 +0100
Subject: [PATCH v6 06/17] firmware: arm_scmi: Introduce monotonically
 increasing tokens
In-Reply-To: <20210802102425.67bhbvyrgzio7zzg@bogus>
References: <20210712141833.6628-1-cristian.marussi@arm.com>
 <20210712141833.6628-7-cristian.marussi@arm.com>
 <20210728141746.chqwhspnwviz67xn@bogus>
 <20210728165430.GJ6592@e120937-lin>
 <20210802102425.67bhbvyrgzio7zzg@bogus>
Message-ID: <20210803125217.GQ6592@e120937-lin>

On Mon, Aug 02, 2021 at 11:24:25AM +0100, Sudeep Holla wrote:
> On Wed, Jul 28, 2021 at 05:54:30PM +0100, Cristian Marussi wrote:
> > On Wed, Jul 28, 2021 at 03:17:46PM +0100, Sudeep Holla wrote:
> > > On Mon, Jul 12, 2021 at 03:18:22PM +0100, Cristian Marussi wrote:
> 
> [...]
> 

Hi Sudeep,

I'm goignt to post V7 with all the remarks on the series from you and Peter
addressed.  A few notes beow on this patch.

> > > >  
> > > > +#define SCMI_PENDING_XFERS_HT_ORDER_SZ	9
> > > > +
> > > 
> > > Is there any particular reason to choose half the token size as hash bucket
> > > size ? IOW why not 1/3 or 1/4th of it ? I would appreciate a comment here.
> > > I see it is mentioned in the commit log. Also is it not better to associate
> > > or keep it close to MSG_TOKEN_ID_MASK and associated macros.
> > > 
> > 
> > I'll move this in the proper place where associated macros are defined.
> > 
> > The reason for the size choice is tricky (and not sure about its value
> > still...so I have not commented yet :D); the ideal size of this hashtable would
> > be desc->max_msg so equal to the maximum number of inflight messages allowed on
> > the system in order to minimize (probably to zero) collisions on the hashtable:
> > unfortunately max_msg is only finally available at runtime time and the
> > kernel hashtable is statically sized by design....
> > 
> > I tried to play some tricks to define dynamically the size but everything falls
> > apart since a lot of stuff in linux/hashtable.h is based on ARRAY_SIZE() and
> > friends (to speedup all I suppose). Another non-fit (in my opinion)
> > alternative would be using relativistic hashtable (linux/rhashtable.h) but
> > those are definitely overkill in our case since they are hashtables that
> > can be resized completely at runtime while populated O_o. (with even
> > more overhead)
> > 
> > At the end the size that fits all possible in-flight messages minimizing
> > collisions in any possible case that I can set at compile time would be 10,
> > which means really 2^10 1024 HT entries (equal to MAX_MSG_TOKEN) each of which
> > is a struct list_head (*prev,*next 16bytes) i.e. 16KB HT: Peter pointed out
> > that it would be a lot of wasted space on normal systems in which max in-flight
> > messages are far-less than 1024 AND would not even fit in one 4Kb page, so I
> > reduced it to 512 entries but the best would be 256 (8) if we want to
> > fit in one regular 4kb page. The drawback will be a bit of HT collisions on
> > system with more than 256 possible and effective in-flight messages.
> >
> 
> I agree, 256 should be fine for now. Just add a note that it is chosen to
> fit a page and can be updated if required.
> 
> 

Yes I added a comment explaining the situation, but, my bad, the 'good'
size that fits the HT into a 4k page is indeed 512 (9) because the HT array
is made of hlist_head (so only one pointer, good I double checked on myself :P)

> > > >  /**
> > > >   * struct scmi_xfers_info - Structure to manage transfer information
> > > >   *
> > > > - * @xfer_block: Preallocated Message array
> > > >   * @xfer_alloc_table: Bitmap table for allocated messages.
> > > >   *	Index of this bitmap table is also used for message
> > > >   *	sequence identifier.
> > > >   * @xfer_lock: Protection for message allocation
> > > > + * @last_token: A counter to use as base to generate for monotonically
> > > > + *		increasing tokens.
> > > > + * @free_xfers: A free list for available to use xfers. It is initialized with
> > > > + *		a number of xfers equal to the maximum allowed in-flight
> > > > + *		messages.
> > > > + * @pending_xfers: An hashtable, indexed by msg_hdr.seq, used to keep all the
> > > > + *		   currently in-flight messages.
> > > >   */
> > > >  struct scmi_xfers_info {
> > > > -	struct scmi_xfer *xfer_block;
> > > >  	unsigned long *xfer_alloc_table;
> > > >  	spinlock_t xfer_lock;
> > > > +	atomic_t last_token;
> > > 
> > > Can we merge this and transfer_last_id ? Let this be free running like
> > > transfer_last_id and just use [0-9] from this ? I don't see any point
> > > having 2 different monotonically increasing tokens/id.
> > > 
> > 
> > Mmm I was tempted about that, but the reason I did not was that in some
> > rare limit condition as you can see in the ASCII art (:O) I can find a hole in
> > the next available token ids so I have to skip and update last_token itself,
> > not sure if this could cause confusion seeing transfer_ids with holes during
> > tracing if I unify them.
> >
> 
> That should be fine as it won't be used at all.
> 

In V7 I removed mx_info last_token and I'm using last_transfer_id; my
only concern (mostly theoretical I think) is that last_transfer_id is
picked from a global atomic and so it is shared by any platform or
channel instance. (and being global is good for tracing correlation
in fact...)

In particular this means that it is also shared with notifications
(which do not use monotonic seqnums), so that, if a flood of notifs
suddenly kicks in, a lot of transfer_idS would be burnt (for tracing
notifs.. not for seqnums) and any following command will end up picking
a good valid monotonic seqnum BUT far away from the previous one
(i.e. there will be holes in the set of monotonic seqnums): no issue
with that but it could lead, under some very awkward limit conditions,
to an early reuse of seqnums for commands (i.e. a less effective
mitigation of seqnums reusing).

Anyway in my tests on this new version I have see no issues and the
above mentioned case is clearly borderline so I made the change (and
noted the above scenario in a comment)

Thanks,
Cristian



From tony at atomide.com  Tue Aug  3 05:53:56 2021
From: tony at atomide.com (Tony Lindgren)
Date: Tue, 3 Aug 2021 15:53:56 +0300
Subject: [PATCH 00/11] Add PRU-ICSS nodes on AM335x, AM437x & AM57xx SoCs
In-Reply-To: <20210729224621.2295-1-s-anna@ti.com>
References: <20210729224621.2295-1-s-anna@ti.com>
Message-ID: <YQk8ZEhoVki7k57C@atomide.com>

* Suman Anna <s-anna at ti.com> [210729 22:46]:
> Patches are on top of 5.14-rc3 (should apply cleanly on 5.14-rc1 as
> well), as I had to use that version due to some Ethernet issues for NFS.
> 
> Let me know if you prefer the AM57 style of a separate dtsi file for
> PRUSS, and I can repost these quickly.

Thanks looks good to me, applied to omap-for-v5.15/dt.

Regards,

Tony


From shameerali.kolothum.thodi at huawei.com  Tue Aug  3 05:55:25 2021
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Tue, 3 Aug 2021 12:55:25 +0000
Subject: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU schedule out
In-Reply-To: <20210803114034.GB30853@willie-the-truck>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
 <20210803114034.GB30853@willie-the-truck>
Message-ID: <ee2863107d614ef8a36006b5aa912eca@huawei.com>



> -----Original Message-----
> From: Will Deacon [mailto:will at kernel.org]
> Sent: 03 August 2021 12:41
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org; maz at kernel.org; catalin.marinas at arm.com;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Linuxarm
> <linuxarm at huawei.com>
> Subject: Re: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU
> schedule out
> 
> On Thu, Jul 29, 2021 at 11:40:09AM +0100, Shameer Kolothum wrote:
> > Like ASID allocator, we copy the active_vmids into the
> > reserved_vmids on a rollover. But it's unlikely that
> > every CPU will have a?vCPU as current task and we may
> > end up unnecessarily?reserving the VMID space.
> >
> > Hence, clear active_vmids when scheduling out a vCPU.
> >
> > Suggested-by: Will Deacon <will at kernel.org>
> > Signed-off-by: Shameer Kolothum
> <shameerali.kolothum.thodi at huawei.com>
> > ---
> >  arch/arm64/include/asm/kvm_host.h | 1 +
> >  arch/arm64/kvm/arm.c              | 1 +
> >  arch/arm64/kvm/vmid.c             | 6 ++++++
> >  3 files changed, 8 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h
> b/arch/arm64/include/asm/kvm_host.h
> > index bb993bce1363..d93141cb8d16 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -687,6 +687,7 @@ extern unsigned int kvm_arm_vmid_bits;
> >  int kvm_arm_vmid_alloc_init(void);
> >  void kvm_arm_vmid_alloc_free(void);
> >  void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
> > +void kvm_arm_vmid_clear_active(void);
> >
> >  static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch
> *vcpu_arch)
> >  {
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 077e55a511a9..b134a1b89c84 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -435,6 +435,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> >  	kvm_timer_vcpu_put(vcpu);
> >  	kvm_vgic_put(vcpu);
> >  	kvm_vcpu_pmu_restore_host(vcpu);
> > +	kvm_arm_vmid_clear_active();
> >
> >  	vcpu->cpu = -1;
> >  }
> > diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
> > index 5584e84aed95..5fd51f5445c1 100644
> > --- a/arch/arm64/kvm/vmid.c
> > +++ b/arch/arm64/kvm/vmid.c
> > @@ -116,6 +116,12 @@ static u64 new_vmid(struct kvm_vmid
> *kvm_vmid)
> >  	return idx2vmid(vmid) | generation;
> >  }
> >
> > +/* Call with preemption disabled */
> > +void kvm_arm_vmid_clear_active(void)
> > +{
> > +	atomic64_set(this_cpu_ptr(&active_vmids), 0);
> > +}
> 
> I think this is very broken, as it will force everybody to take the
> slow-path when they see an active_vmid of 0.

Yes. I have seen that happening in my test setup.

> It also doesn't solve the issue I mentioned before, as an active_vmid of 0
> means that the reserved vmid is preserved.
> 
> Needs more thought...

How about we clear all the active_vmids in kvm_arch_free_vm() if it
matches the kvm_vmid->id ? But we may have to hold the lock 
there.

Thanks,
Shameer
 



From wangborong at cdjrlc.com  Tue Aug  3 05:55:25 2021
From: wangborong at cdjrlc.com (Jason Wang)
Date: Tue,  3 Aug 2021 20:55:25 +0800
Subject: [PATCH] crypto: sun8i-ce - use kfree_sensitive to clear and free
 sensitive data
Message-ID: <20210803125525.72603-1-wangborong@cdjrlc.com>

The kfree_sensitive is a kernel API to clear sensitive information
that should not be leaked to other future users of the same memory
objects and free the memory. Its function is the same as the
combination  of memzero_explicit and kfree. Thus, we can replace the
combination APIs with the single kfree_sensitive API.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
---
 drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c | 9 +++------
 drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c | 3 +--
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c
index cd1baee424a1..b3a9bbfb8831 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c
@@ -26,8 +26,7 @@ void sun8i_ce_prng_exit(struct crypto_tfm *tfm)
 {
 	struct sun8i_ce_rng_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	memzero_explicit(ctx->seed, ctx->slen);
-	kfree(ctx->seed);
+	kfree_sensitive(ctx->seed);
 	ctx->seed = NULL;
 	ctx->slen = 0;
 }
@@ -38,8 +37,7 @@ int sun8i_ce_prng_seed(struct crypto_rng *tfm, const u8 *seed,
 	struct sun8i_ce_rng_tfm_ctx *ctx = crypto_rng_ctx(tfm);
 
 	if (ctx->seed && ctx->slen != slen) {
-		memzero_explicit(ctx->seed, ctx->slen);
-		kfree(ctx->seed);
+		kfree_sensitive(ctx->seed);
 		ctx->slen = 0;
 		ctx->seed = NULL;
 	}
@@ -157,9 +155,8 @@ int sun8i_ce_prng_generate(struct crypto_rng *tfm, const u8 *src,
 		memcpy(dst, d, dlen);
 		memcpy(ctx->seed, d + dlen, ctx->slen);
 	}
-	memzero_explicit(d, todo);
 err_iv:
-	kfree(d);
+	kfree_sensitive(d);
 err_mem:
 	return err;
 }
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c
index 5b7af4498bd5..19cd2e52f89d 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c
@@ -95,9 +95,8 @@ static int sun8i_ce_trng_read(struct hwrng *rng, void *data, size_t max, bool wa
 		memcpy(data, d, max);
 		err = max;
 	}
-	memzero_explicit(d, todo);
 err_dst:
-	kfree(d);
+	kfree_sensitive(d);
 	return err;
 }
 
-- 
2.32.0



From semen.protsenko at linaro.org  Tue Aug  3 05:58:38 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 3 Aug 2021 15:58:38 +0300
Subject: [PATCH 11/12] dt-bindings: interrupt-controller: Add IRQ
 constants for Exynos850
In-Reply-To: <d603be80-4fb6-1bad-1963-c9fa7d1e63fb@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-12-semen.protsenko@linaro.org>
 <d603be80-4fb6-1bad-1963-c9fa7d1e63fb@canonical.com>
Message-ID: <CAPLW+4mPeSOuiQ1iYTVXqTzmPP7o1uPX8Gapzr7Es0wRBpYt6g@mail.gmail.com>

On Sat, 31 Jul 2021 at 11:45, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 30/07/2021 16:49, Sam Protsenko wrote:
> > Add external GIC interrupt constants for SPI[479:0] for Exynos850 SoC.
> > Interrupt names were taken from TRM without change, hence double
> > underscore in const namings.
>
> I am not sure what is the benefit of defining these in header. Unlike
> other DT consts (e.g. clock IDs) drivers do not us them at all. Using
> them in DT does not reduce chance of mistakes in numbers - instead of in
> DTS you can make a mistake here in header file. In the same time, they
> grow the interrupt property in DTS making it more difficult to read.
>
> I also did not see anyone else using this approach, so it's not only me
> (Marc also find it confusing).
>
> If vendor kernel did similar, it's not an argument. Samsung LSI /.
> vendor kernel has terrible code quality so usually it is not a good example.
>

Agreed. I'll use IRQ numbers in dts directly, in v2. I probably
thought that IRQ header might replace missing public TRM, but that's a
poor substitute anyway.

>
> Best regards,
> Krzysztof


From tony at atomide.com  Tue Aug  3 06:05:29 2021
From: tony at atomide.com (Tony Lindgren)
Date: Tue,  3 Aug 2021 16:05:29 +0300
Subject: [GIT PULL] Fixes for omaps for v5.14-rc series
Message-ID: <pull-1627995895-406133@atomide.com>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.14/fixes-rc5-signed

for you to fetch changes up to 353b7a55dcaf5fb8758e09ebe2ddf5f3adbac7c5:

  Merge branch 'fixes-v5.14' into fixes (2021-07-27 11:25:08 +0300)

----------------------------------------------------------------
Fixes for omaps for v5.14-rc series

Some fixes for regressions and boot issues for various devices:

- Fix gpt12 system timer regression on earlier beagleboard revisions

- Fix potential NULL pointer access for omap_hwmod_get_pwrdm()

- Disable RNG on secure am335x variants as it's not accessible

- Fix flakey DCDC2 voltage causing hangs on am43x-epos-evm by reducing
  i2c0 bus speed for tps65218

- Fix typo for am437x-l4 can at 0 node

- Fix omap5 regression caused by vdds_1v8_main fixed-regulator

----------------------------------------------------------------
Dario Binacchi (1):
      ARM: dts: am437x-l4: fix typo in can at 0 node

Dave Gerlach (1):
      ARM: dts: am43x-epos-evm: Reduce i2c0 bus speed for tps65218

H. Nikolaus Schaller (1):
      omap5-board-common: remove not physically existing vdds_1v8_main fixed-regulator

Kevin Hilman (1):
      bus: ti-sysc: AM3: RNG is GP only

Tero Kristo (1):
      ARM: omap2+: hwmod: fix potential NULL pointer access

Tony Lindgren (2):
      bus: ti-sysc: Fix gpt12 system timer issue with reserved status
      Merge branch 'fixes-v5.14' into fixes

 arch/arm/boot/dts/am437x-l4.dtsi          |  2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts      |  2 +-
 arch/arm/boot/dts/omap5-board-common.dtsi |  9 +--------
 arch/arm/mach-omap2/omap_hwmod.c          | 10 +++++++++-
 drivers/bus/ti-sysc.c                     | 22 +++++++++++++++-------
 5 files changed, 27 insertions(+), 18 deletions(-)


From james.clark at arm.com  Tue Aug  3 06:09:38 2021
From: james.clark at arm.com (James Clark)
Date: Tue, 3 Aug 2021 14:09:38 +0100
Subject: [PATCH 5/6] perf cs-etm: Create ETE decoder
In-Reply-To: <20210731072341.GE7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-6-james.clark@arm.com>
 <20210731072341.GE7437@leoy-ThinkPad-X240s>
Message-ID: <654cf3ae-325b-49c9-a9d0-ebf704a83d6f@arm.com>



On 31/07/2021 08:23, Leo Yan wrote:
> On Wed, Jul 21, 2021 at 10:07:04AM +0100, James Clark wrote:
>> If the TRCDEVARCH register was saved, and it shows that ETE is present,
>> then instantiate an OCSD_BUILTIN_DCD_ETE decoder instead of
>> OCSD_BUILTIN_DCD_ETMV4I. ETE is the new trace feature for Armv9.
>>
>> Testing performed
>> =================
>>
>> * Old files with v0 headers still open correctly
>> * Old files with v1 headers with no TRCDEVARCH saved still open
>> * New files with TRCDEVARCH open using an old version of perf that
>>   supports v1 headers
>> * Coresight decoding results in the same output if there are no new ETE
>>   packet types
>>
>> Signed-off-by: James Clark <james.clark at arm.com>
>> ---
>>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 29 ++++++++++-
>>  .../perf/util/cs-etm-decoder/cs-etm-decoder.h |  7 +++
>>  tools/perf/util/cs-etm.c                      | 49 ++++++++++++++++++-
>>  tools/perf/util/cs-etm.h                      |  1 +
>>  4 files changed, 82 insertions(+), 4 deletions(-)
>>
>> diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
>> index 60147c908425..37bc9d6a7677 100644
>> --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
>> +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
>> @@ -127,8 +127,12 @@ static int cs_etm_decoder__gen_etmv3_config(struct cs_etm_trace_params *params,
>>  #define TRCIDR1_TRCARCHMIN_SHIFT 4
>>  #define TRCIDR1_TRCARCHMIN_MASK  GENMASK(7, 4)
>>  #define TRCIDR1_TRCARCHMIN(x)    (((x) & TRCIDR1_TRCARCHMIN_MASK) >> TRCIDR1_TRCARCHMIN_SHIFT)
>> -static enum _ocsd_arch_version cs_etm_decoder__get_arch_ver(u32 reg_idr1)
>> +static enum _ocsd_arch_version cs_etm_decoder__get_arch_ver(u32 reg_idr1, u32 reg_devarch)
>>  {
>> +	/* ETE has to be v9 so set arch version to v8.3+ (ARCH__AA64) */
>> +	if (cs_etm__is_ete(reg_devarch))
>> +		return ARCH_AA64;
>> +
> 
> Based on values used in below change, I think we can unify the ETM
> versio number like:
> 
>   ARCH_V8R3 : REVISION, bits[19:16] is 0x3
>   ARCH_V8R4 : REVISION, bits[19:16] is 0x4
>   ARCH_V8R5 : REVISION, bits[19:16] is 0x5

Do you mean make this change in OpenCSD? At the moment it understands these
values so I'm not sure if the extra ones would be useful:

	/** Core Architecture Version */
	typedef enum _ocsd_arch_version {
	    ARCH_UNKNOWN = 0x0000,   /**< unknown architecture */
	    ARCH_CUSTOM = 0x0001,    /**< None ARM, custom architecture */
	    ARCH_V7 = 0x0700,        /**< V7 architecture */
	    ARCH_V8 = 0x0800,        /**< V8 architecture */
	    ARCH_V8r3 = 0x0803,      /**< V8.3 architecture */
	    ARCH_AA64 = 0x0864,      /**< Min v8r3 plus additional AA64 PE features */
	    ARCH_V8_max = ARCH_AA64,
	} ocsd_arch_version_t;

[...]

>> diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
>> index 11f3391d06f2..9137796fe3c5 100644
>> --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
>> +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
>> @@ -37,11 +37,17 @@ struct cs_etmv4_trace_params {
>>  	u32 reg_traceidr;
>>  };
>>  
>> +struct cs_ete_trace_params {
>> +	struct cs_etmv4_trace_params base_params;
>> +	u32 reg_devarch;
> 
> As we have said, can we directly support ETMv4.5, so that it can
> smoothly support ETE features?  If so, we don't need to add a new
> structure "cs_ete_trace_params" at here.
> 

I think with the new magic number change this is more likely to stay,
what are your thoughts?

[...]

>> +
>> +#define TRCDEVARCH_ARCHPART_SHIFT 0
>> +#define TRCDEVARCH_ARCHPART_MASK  GENMASK(11, 0)
>> +#define TRCDEVARCH_ARCHPART(x)    (((x) & TRCDEVARCH_ARCHPART_MASK) >> TRCDEVARCH_ARCHPART_SHIFT)
>> +
>> +#define TRCDEVARCH_ARCHVER_SHIFT 12
>> +#define TRCDEVARCH_ARCHVER_MASK  GENMASK(15, 12)
>> +#define TRCDEVARCH_ARCHVER(x)    (((x) & TRCDEVARCH_ARCHVER_MASK) >> TRCDEVARCH_ARCHVER_SHIFT)
>> +
>> +bool cs_etm__is_ete(u32 trcdevarch)
>> +{
>> +	/*
>> +	 * ETE if ARCHVER is 5 (ARCHVER is 4 for ETM) and ARCHPART is 0xA13.
>> +	 * See ETM_DEVARCH_ETE_ARCH in coresight-etm4x.h
>> +	 */
>> +	return TRCDEVARCH_ARCHVER(trcdevarch) == 5 && TRCDEVARCH_ARCHPART(trcdevarch) == 0xA13;
> 
> I think this is incorrect.
> 
> Here should check the bit field "REVISION, bits[19:16]".  If it's
> field value is >= 5, then we can say it supports ETE.  I checked the
> spec for ETMv4.4 and ETMv4.6, both use the same values for the
> Bits[15:12] = 0x4, so the architecture ID is same for ETMv4.x IPs.
> 

I tried to copy this as closely as possible from the ETE driver. See in coresight-etm4x.h

	#define ETM_DEVARCH_ETE_ARCH						\
		(ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETE | ETM_DEVARCH_PRESENT) 

Where ETM_DEVARCH_ARCHID_ETE is ARCHVER == 5 and ARCHPART == 0xA13. I didn't check 
ETM_DEVARCH_ARCHITECT_ARM because I thought that wouldn't be necessary. If we want to make
the change do detect >= 5 then I think this should be made in the driver first. @Suzuki,
what do you think?

Thanks
James



From cristian.marussi at arm.com  Tue Aug  3 06:10:09 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:09 +0100
Subject: [PATCH v7 00/15] Introduce SCMI transport based on VirtIO
Message-ID: <20210803131024.40280-1-cristian.marussi@arm.com>

Hi all,

While reworking this series starting from the work done up to V3 by
OpenSynergy, I am keeping the original autorship and list distribution
unchanged.

The main aim of this rework, as said, is to simplify where possible the
SCMI VirtIO support added in V3 by adding at first some new general
mechanisms in the SCMI Transport layer.

Indeed, after some initial small fixes, patches 03/04/05 add such new
additional mechanisms to the SCMI core to ease implementation of more
complex transports like virtio, while also addressing a few general issues
already potentially affecting existing transports.

In terms of rework I dropped original V3 patches 05/06/07/08/12 as no more
needed, and modified where needed the remaining original patches to take
advantage of the above mentioned new SCMI transport features.

DT bindings patch has been ported on top of freshly YAML converted arm,scmi
bindings.

Moreover, since V5 I dropped support for polling mode from the virtio-scmi
transport, since it is an optional general mechanism provided by the core
to allow transports lacking a completion IRQ to work and it seemed a
needless addition/complication in the context of virtio transport.

Additionally, since V5 I simplified a bit the virtio-scmi transport probing
sequence observing that, as of now, only one single SCMI VirtIO device can
be possibly used, since the SCMI VirtIO devices are not identifiable from
the VirtIO layer and neither they are currently identifiable from the DT
config; as a consequence only one single SCMI transport channel is
currently supported when using virtio-scmi transport.

The series has been tested using an emulated fake SCMI device and also a
proper SCP-fw SCMI stack running through QEMU vhost-users, with the SCMI
stack compiled, in both cases, as builtin and as a loadable module, running
tests against mocked SCMI Sensors using HWMON and IIO interfaces to check
the functionality of notifications and sync/async commands.

Virtio-scmi support has been exercised in the following testing scenario
on a JUNO board:

 - normal sync/async command transfers
 - notifications
 - concurrent delivery of correlated response and delayed responses
 - out-of-order delivery of delayed responses before related responses
 - unexpected delayed response delivery for sync commands
 - late delivery of timed-out responses and delayed responses

Some basic regression testing against mailbox transport has been performed
for commands and notifications too.

No sensible overhead in total handling time of commands and notifications
has been observed, even though this series do indeed add a considerable
amount of code to execute on TX path.

This series is based on sudeep/for-next/scmi [1] on top of

commit bdb8742dc6f7 ("firmware: arm_scmi: Fix range check for the maximum
		     number of pending messages")

Any feedback/testing is welcome :D

Thanks,
Cristian

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git/log/?h=for-next/scmi
---
v6 --> v7
 - rebased on sudeep/for-next/scmi (v5.14-rc1)
 - added Cc: for maintainers regarding Virtio SCMI device number addition
   in include/uapi/linux/virtio_ids.h (previously only list was Cc'ed)
 - V6 patches 01 and 02 have been removed from V7 since already queued on
   sudeep/for-next/scmi
 - renamed scmi_desc .init/.exit to .transport_init/.exit
 - moved "firmware: arm_scmi: Add priv parameter to scmi_rx_callback" later
   in the series
 - simplified new SCMI Kconfig layout
 - refactored/simplified  support for non-polling transports
 - moved introduction of xfer refcounting from "firmware: arm_scmi:
   Introduce monotonically increasing tokens" to "firmware: arm_scmi:
   Handle concurrent and out-of-order messages"
 - renamed scmi_xfer_is_free to scmi_xfer_acquired
 - moved scmi_xfer_state_update() call inside scmi_xfer_command_acquire
 - added missing barrier in do_xfer()
 - added proper comment to justify pending_xfers sizing and relocated such
   #define directive
 - removed last_token atomic counter, now generating monotonic seqnums
   based on transfer_id

V5 --> V6:
 - removed delegated xfers and its usage
 - add and use *priv optional parameter in scmi_rx_callback()
 - made .poll_done and .clear_channel ops optional

V4 --> V5:
 - removed msg raw_payload helpers
 - reworked msg helpers to use xfer->priv reference
 - simplified SCMI device probe sequence (one static device)
 - added new SCMI Kconfig layout
 - removed SCMI virtio polling support

V3 --> V4:
 - using new delegated xfers support and monotonically increasing tokens
   in virtio transport
 - ported SCMI virtio transport DT bindings to YAML format
 - added virtio-scmi polling support
 - added delegated xfers support


Cristian Marussi (9):
  firmware: arm_scmi: Add support for type handling in common functions
  firmware: arm_scmi: Remove scmi_dump_header_dbg() helper
  firmware: arm_scmi: Add optional transport_init/exit support
  firmware: arm_scmi: Introduce monotonically increasing tokens
  firmware: arm_scmi: Handle concurrent and out-of-order messages
  firmware: arm_scmi: Make .clear_channel optional
  firmware: arm_scmi: Make polling mode optional
  firmware: arm_scmi: Make SCMI transports configurable
  firmware: arm_scmi: Add priv parameter to scmi_rx_callback

Igor Skalkin (4):
  firmware: arm_scmi: Make shmem support optional for transports
  firmware: arm_scmi: Add method to override max message number
  dt-bindings: arm: Add virtio transport for SCMI
  firmware: arm_scmi: Add virtio transport

Peter Hilber (2):
  firmware: arm_scmi: Add message passing abstractions for transports
  firmware: arm_scmi: Add optional link_supplier() transport op

 .../bindings/firmware/arm,scmi.yaml           |   8 +-
 MAINTAINERS                                   |   1 +
 drivers/firmware/Kconfig                      |  34 +-
 drivers/firmware/arm_scmi/Kconfig             |  95 +++
 drivers/firmware/arm_scmi/Makefile            |   8 +-
 drivers/firmware/arm_scmi/common.h            | 113 ++-
 drivers/firmware/arm_scmi/driver.c            | 649 +++++++++++++++---
 drivers/firmware/arm_scmi/mailbox.c           |   2 +-
 drivers/firmware/arm_scmi/msg.c               | 111 +++
 drivers/firmware/arm_scmi/smc.c               |   3 +-
 drivers/firmware/arm_scmi/virtio.c            | 491 +++++++++++++
 include/uapi/linux/virtio_ids.h               |   1 +
 include/uapi/linux/virtio_scmi.h              |  24 +
 13 files changed, 1403 insertions(+), 137 deletions(-)
 create mode 100644 drivers/firmware/arm_scmi/Kconfig
 create mode 100644 drivers/firmware/arm_scmi/msg.c
 create mode 100644 drivers/firmware/arm_scmi/virtio.c
 create mode 100644 include/uapi/linux/virtio_scmi.h

-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:10 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:10 +0100
Subject: [PATCH v7 01/15] firmware: arm_scmi: Add support for type handling in
 common functions
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-2-cristian.marussi@arm.com>

Add SCMI type handling to pack/unpack_scmi_header common helper functions.
Initialize hdr.type properly when initializing a command xfer.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
Needed later in the series to support serialization
---
 drivers/firmware/arm_scmi/common.h | 6 +++++-
 drivers/firmware/arm_scmi/driver.c | 1 +
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 8685619d38f9..7c2b9fd7e929 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -70,6 +70,7 @@ struct scmi_msg_resp_prot_version {
  *
  * @id: The identifier of the message being sent
  * @protocol_id: The identifier of the protocol used to send @id message
+ * @type: The SCMI type for this message
  * @seq: The token to identify the message. When a message returns, the
  *	platform returns the whole message header unmodified including the
  *	token
@@ -80,6 +81,7 @@ struct scmi_msg_resp_prot_version {
 struct scmi_msg_hdr {
 	u8 id;
 	u8 protocol_id;
+	u8 type;
 	u16 seq;
 	u32 status;
 	bool poll_completion;
@@ -89,13 +91,14 @@ struct scmi_msg_hdr {
  * pack_scmi_header() - packs and returns 32-bit header
  *
  * @hdr: pointer to header containing all the information on message id,
- *	protocol id and sequence id.
+ *	protocol id, sequence id and type.
  *
  * Return: 32-bit packed message header to be sent to the platform.
  */
 static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
 {
 	return FIELD_PREP(MSG_ID_MASK, hdr->id) |
+		FIELD_PREP(MSG_TYPE_MASK, hdr->type) |
 		FIELD_PREP(MSG_TOKEN_ID_MASK, hdr->seq) |
 		FIELD_PREP(MSG_PROTOCOL_ID_MASK, hdr->protocol_id);
 }
@@ -110,6 +113,7 @@ static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
 {
 	hdr->id = MSG_XTRACT_ID(msg_hdr);
 	hdr->protocol_id = MSG_XTRACT_PROT_ID(msg_hdr);
+	hdr->type = MSG_XTRACT_TYPE(msg_hdr);
 }
 
 /**
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 9b2e8d42a992..a7a789c5d101 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -566,6 +566,7 @@ static int xfer_get_init(const struct scmi_protocol_handle *ph,
 
 	xfer->tx.len = tx_size;
 	xfer->rx.len = rx_size ? : info->desc->max_msg_size;
+	xfer->hdr.type = MSG_TYPE_COMMAND;
 	xfer->hdr.id = msg_id;
 	xfer->hdr.poll_completion = false;
 
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:11 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:11 +0100
Subject: [PATCH v7 02/15] firmware: arm_scmi: Remove scmi_dump_header_dbg()
 helper
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-3-cristian.marussi@arm.com>

Being a while that we have SCMI trace events in the SCMI stack, remove
this debug helper and its call sites.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index a7a789c5d101..bd7f81b2b46b 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -172,19 +172,6 @@ static inline int scmi_to_linux_errno(int errno)
 	return -EIO;
 }
 
-/**
- * scmi_dump_header_dbg() - Helper to dump a message header.
- *
- * @dev: Device pointer corresponding to the SCMI entity
- * @hdr: pointer to header.
- */
-static inline void scmi_dump_header_dbg(struct device *dev,
-					struct scmi_msg_hdr *hdr)
-{
-	dev_dbg(dev, "Message ID: %x Sequence ID: %x Protocol: %x\n",
-		hdr->id, hdr->seq, hdr->protocol_id);
-}
-
 void scmi_notification_instance_data_set(const struct scmi_handle *handle,
 					 void *priv)
 {
@@ -288,7 +275,6 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 	}
 
 	unpack_scmi_header(msg_hdr, &xfer->hdr);
-	scmi_dump_header_dbg(dev, &xfer->hdr);
 	info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
 					    xfer);
 	scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
@@ -339,8 +325,6 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
 	if (msg_type == MSG_TYPE_DELAYED_RESP)
 		xfer->rx.len = info->desc->max_msg_size;
 
-	scmi_dump_header_dbg(dev, &xfer->hdr);
-
 	info->desc->ops->fetch_response(cinfo, xfer);
 
 	trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:12 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:12 +0100
Subject: [PATCH v7 03/15] firmware: arm_scmi: Add optional transport_init/exit
 support
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-4-cristian.marussi@arm.com>

Some SCMI transport could need to perform some transport specific setup
before they can be used by the SCMI core transport layer: typically this
early setup consists in registering with some other kernel subsystem.

Add the optional capability for a transport to provide a couple of init
and exit functions that are assured to be called early during the SCMI
core initialization phase, well before the SCMI core probing step.

[ Peter: Adapted RFC patch by Cristian for submission to upstream. ]
Signed-off-by: Peter Hilber <peter.hilber at opensynergy.com>
[ Cristian: Fixed scmi_transports_exit point of invocation ]
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v6 --> v7
- renamed to transport_init/exit
v4 --> V5
- removed useless pr_debug
- moved scmi_transport_exit() invocation
---
 drivers/firmware/arm_scmi/common.h |  8 +++++
 drivers/firmware/arm_scmi/driver.c | 57 ++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 7c2b9fd7e929..9454488021ea 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -321,6 +321,12 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
 /**
  * struct scmi_desc - Description of SoC integration
  *
+ * @transport_init: An optional function that a transport can provide to
+ *		    initialize some transport-specific setup during SCMI core
+ *		    initialization, so ahead of SCMI core probing.
+ * @transport_exit: An optional function that a transport can provide to
+ *		    de-initialize some transport-specific setup during SCMI core
+ *		    de-initialization, so after SCMI core removal.
  * @ops: Pointer to the transport specific ops structure
  * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
  * @max_msg: Maximum number of messages that can be pending
@@ -328,6 +334,8 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
  * @max_msg_size: Maximum size of data per message that can be handled.
  */
 struct scmi_desc {
+	int (*transport_init)(void);
+	void (*transport_exit)(void);
 	const struct scmi_transport_ops *ops;
 	int max_rx_timeout_ms;
 	int max_msg;
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index bd7f81b2b46b..374bf97a7b4a 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1581,10 +1581,65 @@ static struct platform_driver scmi_driver = {
 	.remove = scmi_remove,
 };
 
+/**
+ * __scmi_transports_setup  - Common helper to call transport-specific
+ * .init/.exit code if provided.
+ *
+ * @init: A flag to distinguish between init and exit.
+ *
+ * Note that, if provided, we invoke .init/.exit functions for all the
+ * transports currently compiled in.
+ *
+ * Return: 0 on Success.
+ */
+static inline int __scmi_transports_setup(bool init)
+{
+	int ret = 0;
+	const struct of_device_id *trans;
+
+	for (trans = scmi_of_match; trans->data; trans++) {
+		const struct scmi_desc *tdesc = trans->data;
+
+		if ((init && !tdesc->transport_init) ||
+		    (!init && !tdesc->transport_exit))
+			continue;
+
+		if (init)
+			ret = tdesc->transport_init();
+		else
+			tdesc->transport_exit();
+
+		if (ret) {
+			pr_err("SCMI transport %s FAILED initialization!\n",
+			       trans->compatible);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int __init scmi_transports_init(void)
+{
+	return __scmi_transports_setup(true);
+}
+
+static void __exit scmi_transports_exit(void)
+{
+	__scmi_transports_setup(false);
+}
+
 static int __init scmi_driver_init(void)
 {
+	int ret;
+
 	scmi_bus_init();
 
+	/* Initialize any compiled-in transport which provided an init/exit */
+	ret = scmi_transports_init();
+	if (ret)
+		return ret;
+
 	scmi_base_register();
 
 	scmi_clock_register();
@@ -1613,6 +1668,8 @@ static void __exit scmi_driver_exit(void)
 
 	scmi_bus_exit();
 
+	scmi_transports_exit();
+
 	platform_driver_unregister(&scmi_driver);
 }
 module_exit(scmi_driver_exit);
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:13 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:13 +0100
Subject: [PATCH v7 04/15] firmware: arm_scmi: Introduce monotonically
 increasing tokens
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-5-cristian.marussi@arm.com>

Tokens are sequence numbers embedded in the each SCMI message header: they
are used to correlate commands with responses (and delayed responses), but
their usage and policy of selection is entirely up to the caller (usually
the OSPM agent), while they are completely opaque to the callee (i.e. SCMI
platform) which merely copies them back from the command into the response
message header.
This also means that the platform does not, can not and should not enforce
any kind of policy on received messages depending on the contained sequence
number: platform can perfectly handle concurrent requests carrying the same
identifiying token if that should happen.

Moreover the platform is not required to produce in-order responses to
agent requests, the only constraint in these regards is that in case of
an asynchronous message the delayed response must be sent after the
immediate response for the synchronous part of the command transaction.

Currenly the SCMI stack of the OSPM agent selects a token for the egressing
commands picking the lowest possible number which is not already in use by
an existing in-flight transaction, which means, in other words, that we
immediately reuse any token after its transaction has completed or it has
timed out: this policy indeed does simplify management and lookup of tokens
and associated xfers.

Under the above assumptions and constraints, since there is really no state
shared between the agent and the platform to let the platform know when a
token and its associated message has timed out, the current policy of early
reuse of tokens can easily lead to the situation in which a spurious or
late received response (or delayed_response), related to an old stale and
timed out transaction, can be wrongly associated to a newer valid in-flight
xfer that just happens to have reused the same token.

This misbehaviour on such late/spurious responses is more easily exposed on
those transports that naturally have an higher level of parallelism in
processing multiple concurrent in-flight messages.

This commit introduces a new policy of selection of tokens for the OSPM
agent: each new command transfer now gets the next available, monotonically
increasing token, until tokens are exhausted and the counter rolls over.

Such new policy mitigates the above issues with late/spurious responses
since the tokens are now reused as late as possible (when they roll back
ideally) and so it is much easier to identify such late/spurious responses
to stale timed out transactions: this also helps in simplifying the
specific transports implementation since stale transport messages can be
easily identified and discarded early on in the rx path without the need
to cross check their actual state with the core transport layer.
This mitigation is even more effective when, as is usually the case, the
maximum number of pending messages is capped by the platform to a much
lower number than the whole possible range of tokens values (2^10).

This internal policy change in the core SCMI transport layer is fully
transparent to the specific transports so it has not and should not have
any impact on the transports implementation.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v6 --> v7
- avoid 'ghost' naming in commit message
- removed xfer->users refcounting (it will be added later in the series
  where it is a better fit
- removed redundant check in scmi_xfer_lookup_unlocked
- added proper comment to justify pending_xfers sizing and moved
  such define away into common.h
- removed last_token atomic counters, now generating monotonic seqnums
  based on transfer_id
v4 --> V5
- removed empirical profiling info from commit msg
- do NOT use monotonic tokens and pending HT for notifications (not needed)
- release xfer_lock later in scmi_xfer_get
---
 drivers/firmware/arm_scmi/common.h |  32 ++++
 drivers/firmware/arm_scmi/driver.c | 254 +++++++++++++++++++++++++----
 2 files changed, 251 insertions(+), 35 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 9454488021ea..651af0c7bed9 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -14,6 +14,8 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/hashtable.h>
+#include <linux/list.h>
 #include <linux/module.h>
 #include <linux/scmi_protocol.h>
 #include <linux/types.h>
@@ -65,6 +67,16 @@ struct scmi_msg_resp_prot_version {
 #define MSG_XTRACT_TOKEN(hdr)	FIELD_GET(MSG_TOKEN_ID_MASK, (hdr))
 #define MSG_TOKEN_MAX		(MSG_XTRACT_TOKEN(MSG_TOKEN_ID_MASK) + 1)
 
+/*
+ * Size of @pending_xfers hashtable included in @scmi_xfers_info; ideally, in
+ * order to minimize space and collisions, this should equal max_msg, i.e. the
+ * maximum number of in-flight messages on a specific platform, but such value
+ * is only available at runtime while kernel hashtables are statically sized:
+ * pick instead as a fixed static size the maximum number of entries that can
+ * fit the whole table into one 4k page.
+ */
+#define SCMI_PENDING_XFERS_HT_ORDER_SZ		9
+
 /**
  * struct scmi_msg_hdr - Message(Tx/Rx) header
  *
@@ -138,6 +150,9 @@ struct scmi_msg {
  *	buffer for the rx path as we use for the tx path.
  * @done: command message transmit completion event
  * @async_done: pointer to delayed response message received event completion
+ * @pending: True for xfers added to @pending_xfers hashtable
+ * @node: An hlist_node reference used to store this xfer, alternatively, on
+ *	  the free list @free_xfers or in the @pending_xfers hashtable
  */
 struct scmi_xfer {
 	int transfer_id;
@@ -146,8 +161,25 @@ struct scmi_xfer {
 	struct scmi_msg rx;
 	struct completion done;
 	struct completion *async_done;
+	bool pending;
+	struct hlist_node node;
 };
 
+/*
+ * An helper macro to lookup an xfer from the @pending_xfers hashtable
+ * using the message sequence number token as a key.
+ */
+#define XFER_FIND(__ht, __k)					\
+({								\
+	typeof(__k) k_ = __k;					\
+	struct scmi_xfer *xfer_ = NULL;				\
+								\
+	hash_for_each_possible((__ht), xfer_, node, k_)		\
+		if (xfer_->hdr.seq == k_)			\
+			break;					\
+	xfer_;							\
+})
+
 struct scmi_xfer_ops;
 
 /**
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 374bf97a7b4a..3c99390f9415 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/ktime.h>
+#include <linux/hashtable.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
@@ -67,16 +68,21 @@ struct scmi_requested_dev {
 /**
  * struct scmi_xfers_info - Structure to manage transfer information
  *
- * @xfer_block: Preallocated Message array
  * @xfer_alloc_table: Bitmap table for allocated messages.
  *	Index of this bitmap table is also used for message
  *	sequence identifier.
  * @xfer_lock: Protection for message allocation
+ * @free_xfers: A free list for available to use xfers. It is initialized with
+ *		a number of xfers equal to the maximum allowed in-flight
+ *		messages.
+ * @pending_xfers: An hashtable, indexed by msg_hdr.seq, used to keep all the
+ *		   currently in-flight messages.
  */
 struct scmi_xfers_info {
-	struct scmi_xfer *xfer_block;
 	unsigned long *xfer_alloc_table;
 	spinlock_t xfer_lock;
+	struct hlist_head free_xfers;
+	DECLARE_HASHTABLE(pending_xfers, SCMI_PENDING_XFERS_HT_ORDER_SZ);
 };
 
 /**
@@ -191,46 +197,185 @@ void *scmi_notification_instance_data_get(const struct scmi_handle *handle)
 	return info->notify_priv;
 }
 
+/**
+ * scmi_xfer_token_set  - Reserve and set new token for the xfer at hand
+ *
+ * @minfo: Pointer to Tx/Rx Message management info based on channel type
+ * @xfer: The xfer to act upon
+ *
+ * Pick the next unused monotonically increasing token and set it into
+ * xfer->hdr.seq: picking a monotonically increasing value avoids immediate
+ * reuse of freshly completed or timed-out xfers, thus mitigating the risk
+ * of incorrect association of a late and expired xfer with a live in-flight
+ * transaction, both happening to re-use the same token identifier.
+ *
+ * Since platform is NOT required to answer our request in-order we should
+ * account for a few rare but possible scenarios:
+ *
+ *  - exactly 'next_token' may be NOT available so pick xfer_id >= next_token
+ *    using find_next_zero_bit() starting from candidate next_token bit
+ *
+ *  - all tokens ahead upto (MSG_TOKEN_ID_MASK - 1) are used in-flight but we
+ *    are plenty of free tokens at start, so try a second pass using
+ *    find_next_zero_bit() and starting from 0.
+ *
+ *  X = used in-flight
+ *
+ * Normal
+ * ------
+ *
+ *		|- xfer_id picked
+ *   -----------+----------------------------------------------------------
+ *   | | |X|X|X| | | | | | ... ... ... ... ... ... ... ... ... ... ...|X|X|
+ *   ----------------------------------------------------------------------
+ *		^
+ *		|- next_token
+ *
+ * Out-of-order pending at start
+ * -----------------------------
+ *
+ *	  |- xfer_id picked, last_token fixed
+ *   -----+----------------------------------------------------------------
+ *   |X|X| | | | |X|X| ... ... ... ... ... ... ... ... ... ... ... ...|X| |
+ *   ----------------------------------------------------------------------
+ *    ^
+ *    |- next_token
+ *
+ *
+ * Out-of-order pending at end
+ * ---------------------------
+ *
+ *	  |- xfer_id picked, last_token fixed
+ *   -----+----------------------------------------------------------------
+ *   |X|X| | | | |X|X| ... ... ... ... ... ... ... ... ... ... |X|X|X||X|X|
+ *   ----------------------------------------------------------------------
+ *								^
+ *								|- next_token
+ *
+ * Context: Assumes to be called with @xfer_lock already acquired.
+ *
+ * Return: 0 on Success or error
+ */
+static int scmi_xfer_token_set(struct scmi_xfers_info *minfo,
+			       struct scmi_xfer *xfer)
+{
+	unsigned long xfer_id, next_token;
+
+	/*
+	 * Pick a candidate monotonic token in range [0, MSG_TOKEN_MAX - 1]
+	 * using the pre-allocated transfer_id as a base.
+	 * Note that the global transfer_id is shared across all message types
+	 * so there could be holes in the allocated set of monotonic sequence
+	 * numbers, but that is going to limit the effectiveness of the
+	 * mitigation only in very rare limit conditions.
+	 */
+	next_token = (xfer->transfer_id & (MSG_TOKEN_MAX - 1));
+
+	/* Pick the next available xfer_id >= next_token */
+	xfer_id = find_next_zero_bit(minfo->xfer_alloc_table,
+				     MSG_TOKEN_MAX, next_token);
+	if (xfer_id == MSG_TOKEN_MAX) {
+		/*
+		 * After heavily out-of-order responses, there are no free
+		 * tokens ahead, but only at start of xfer_alloc_table so
+		 * try again from the beginning.
+		 */
+		xfer_id = find_next_zero_bit(minfo->xfer_alloc_table,
+					     MSG_TOKEN_MAX, 0);
+		/*
+		 * Something is wrong if we got here since there can be a
+		 * maximum number of (MSG_TOKEN_MAX - 1) in-flight messages
+		 * but we have not found any free token [0, MSG_TOKEN_MAX - 1].
+		 */
+		if (WARN_ON_ONCE(xfer_id == MSG_TOKEN_MAX))
+			return -ENOMEM;
+	}
+
+	/* Update +/- last_token accordingly if we skipped some hole */
+	if (xfer_id != next_token)
+		atomic_add((int)(xfer_id - next_token), &transfer_last_id);
+
+	/* Set in-flight */
+	set_bit(xfer_id, minfo->xfer_alloc_table);
+	xfer->hdr.seq = (u16)xfer_id;
+
+	return 0;
+}
+
+/**
+ * scmi_xfer_token_clear  - Release the token
+ *
+ * @minfo: Pointer to Tx/Rx Message management info based on channel type
+ * @xfer: The xfer to act upon
+ */
+static inline void scmi_xfer_token_clear(struct scmi_xfers_info *minfo,
+					 struct scmi_xfer *xfer)
+{
+	clear_bit(xfer->hdr.seq, minfo->xfer_alloc_table);
+}
+
 /**
  * scmi_xfer_get() - Allocate one message
  *
  * @handle: Pointer to SCMI entity handle
  * @minfo: Pointer to Tx/Rx Message management info based on channel type
+ * @set_pending: If true a monotonic token is picked and the xfer is added to
+ *		 the pending hash table.
  *
  * Helper function which is used by various message functions that are
  * exposed to clients of this driver for allocating a message traffic event.
  *
- * This function can sleep depending on pending requests already in the system
- * for the SCMI entity. Further, this also holds a spinlock to maintain
- * integrity of internal data structures.
+ * Picks an xfer from the free list @free_xfers (if any available) and, if
+ * required, sets a monotonically increasing token and stores the inflight xfer
+ * into the @pending_xfers hashtable for later retrieval.
+ *
+ * The successfully initialized xfer is refcounted.
+ *
+ * Context: Holds @xfer_lock while manipulating @xfer_alloc_table and
+ *	    @free_xfers.
  *
  * Return: 0 if all went fine, else corresponding error.
  */
 static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
-				       struct scmi_xfers_info *minfo)
+				       struct scmi_xfers_info *minfo,
+				       bool set_pending)
 {
-	u16 xfer_id;
+	int ret;
+	unsigned long flags;
 	struct scmi_xfer *xfer;
-	unsigned long flags, bit_pos;
-	struct scmi_info *info = handle_to_scmi_info(handle);
 
-	/* Keep the locked section as small as possible */
 	spin_lock_irqsave(&minfo->xfer_lock, flags);
-	bit_pos = find_first_zero_bit(minfo->xfer_alloc_table,
-				      info->desc->max_msg);
-	if (bit_pos == info->desc->max_msg) {
+	if (hlist_empty(&minfo->free_xfers)) {
 		spin_unlock_irqrestore(&minfo->xfer_lock, flags);
 		return ERR_PTR(-ENOMEM);
 	}
-	set_bit(bit_pos, minfo->xfer_alloc_table);
-	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
 
-	xfer_id = bit_pos;
+	/* grab an xfer from the free_list */
+	xfer = hlist_entry(minfo->free_xfers.first, struct scmi_xfer, node);
+	hlist_del_init(&xfer->node);
 
-	xfer = &minfo->xfer_block[xfer_id];
-	xfer->hdr.seq = xfer_id;
+	/*
+	 * Allocate transfer_id early so that can be used also as base for
+	 * monotonic sequence number generation if needed.
+	 */
 	xfer->transfer_id = atomic_inc_return(&transfer_last_id);
 
+	if (set_pending) {
+		/* Pick and set monotonic token */
+		ret = scmi_xfer_token_set(minfo, xfer);
+		if (!ret) {
+			hash_add(minfo->pending_xfers, &xfer->node,
+				 xfer->hdr.seq);
+			xfer->pending = true;
+		} else {
+			dev_err(handle->dev,
+				"Failed to get monotonic token %d\n", ret);
+			hlist_add_head(&xfer->node, &minfo->free_xfers);
+			xfer = ERR_PTR(ret);
+		}
+	}
+	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
 	return xfer;
 }
 
@@ -240,6 +385,9 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
  * @minfo: Pointer to Tx/Rx Message management info based on channel type
  * @xfer: message that was reserved by scmi_xfer_get
  *
+ * After refcount check, possibly release an xfer, clearing the token slot,
+ * removing xfer from @pending_xfers and putting it back into free_xfers.
+ *
  * This holds a spinlock to maintain integrity of internal data structures.
  */
 static void
@@ -247,16 +395,39 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
 {
 	unsigned long flags;
 
-	/*
-	 * Keep the locked section as small as possible
-	 * NOTE: we might escape with smp_mb and no lock here..
-	 * but just be conservative and symmetric.
-	 */
 	spin_lock_irqsave(&minfo->xfer_lock, flags);
-	clear_bit(xfer->hdr.seq, minfo->xfer_alloc_table);
+	if (xfer->pending) {
+		scmi_xfer_token_clear(minfo, xfer);
+		hash_del(&xfer->node);
+		xfer->pending = false;
+	}
+	hlist_add_head(&xfer->node, &minfo->free_xfers);
 	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
 }
 
+/**
+ * scmi_xfer_lookup_unlocked  -  Helper to lookup an xfer_id
+ *
+ * @minfo: Pointer to Tx/Rx Message management info based on channel type
+ * @xfer_id: Token ID to lookup in @pending_xfers
+ *
+ * Refcounting is untouched.
+ *
+ * Context: Assumes to be called with @xfer_lock already acquired.
+ *
+ * Return: A valid xfer on Success or error otherwise
+ */
+static struct scmi_xfer *
+scmi_xfer_lookup_unlocked(struct scmi_xfers_info *minfo, u16 xfer_id)
+{
+	struct scmi_xfer *xfer = NULL;
+
+	if (test_bit(xfer_id, minfo->xfer_alloc_table))
+		xfer = XFER_FIND(minfo->pending_xfers, xfer_id);
+
+	return xfer ?: ERR_PTR(-EINVAL);
+}
+
 static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 {
 	struct scmi_xfer *xfer;
@@ -266,7 +437,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 	ktime_t ts;
 
 	ts = ktime_get_boottime();
-	xfer = scmi_xfer_get(cinfo->handle, minfo);
+	xfer = scmi_xfer_get(cinfo->handle, minfo, false);
 	if (IS_ERR(xfer)) {
 		dev_err(dev, "failed to get free message slot (%ld)\n",
 			PTR_ERR(xfer));
@@ -292,19 +463,22 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 static void scmi_handle_response(struct scmi_chan_info *cinfo,
 				 u16 xfer_id, u8 msg_type)
 {
+	unsigned long flags;
 	struct scmi_xfer *xfer;
 	struct device *dev = cinfo->dev;
 	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
 	struct scmi_xfers_info *minfo = &info->tx_minfo;
 
 	/* Are we even expecting this? */
-	if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
+	spin_lock_irqsave(&minfo->xfer_lock, flags);
+	xfer = scmi_xfer_lookup_unlocked(minfo, xfer_id);
+	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+	if (IS_ERR(xfer)) {
 		dev_err(dev, "message for %d is not expected!\n", xfer_id);
 		info->desc->ops->clear_channel(cinfo);
 		return;
 	}
 
-	xfer = &minfo->xfer_block[xfer_id];
 	/*
 	 * Even if a response was indeed expected on this slot at this point,
 	 * a buggy platform could wrongly reply feeding us an unexpected
@@ -541,7 +715,7 @@ static int xfer_get_init(const struct scmi_protocol_handle *ph,
 	    tx_size > info->desc->max_msg_size)
 		return -ERANGE;
 
-	xfer = scmi_xfer_get(pi->handle, minfo);
+	xfer = scmi_xfer_get(pi->handle, minfo, true);
 	if (IS_ERR(xfer)) {
 		ret = PTR_ERR(xfer);
 		dev_err(dev, "failed to get free message slot(%d)\n", ret);
@@ -1018,18 +1192,25 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
 		return -EINVAL;
 	}
 
-	info->xfer_block = devm_kcalloc(dev, desc->max_msg,
-					sizeof(*info->xfer_block), GFP_KERNEL);
-	if (!info->xfer_block)
-		return -ENOMEM;
+	hash_init(info->pending_xfers);
 
-	info->xfer_alloc_table = devm_kcalloc(dev, BITS_TO_LONGS(desc->max_msg),
+	/* Allocate a bitmask sized to hold MSG_TOKEN_MAX tokens */
+	info->xfer_alloc_table = devm_kcalloc(dev, BITS_TO_LONGS(MSG_TOKEN_MAX),
 					      sizeof(long), GFP_KERNEL);
 	if (!info->xfer_alloc_table)
 		return -ENOMEM;
 
-	/* Pre-initialize the buffer pointer to pre-allocated buffers */
-	for (i = 0, xfer = info->xfer_block; i < desc->max_msg; i++, xfer++) {
+	/*
+	 * Preallocate a number of xfers equal to max inflight messages,
+	 * pre-initialize the buffer pointer to pre-allocated buffers and
+	 * attach all of them to the free list
+	 */
+	INIT_HLIST_HEAD(&info->free_xfers);
+	for (i = 0; i < desc->max_msg; i++) {
+		xfer = devm_kzalloc(dev, sizeof(*xfer), GFP_KERNEL);
+		if (!xfer)
+			return -ENOMEM;
+
 		xfer->rx.buf = devm_kcalloc(dev, sizeof(u8), desc->max_msg_size,
 					    GFP_KERNEL);
 		if (!xfer->rx.buf)
@@ -1037,6 +1218,9 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
 
 		xfer->tx.buf = xfer->rx.buf;
 		init_completion(&xfer->done);
+
+		/* Add initialized xfer to the free list */
+		hlist_add_head(&xfer->node, &info->free_xfers);
 	}
 
 	spin_lock_init(&info->xfer_lock);
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:14 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:14 +0100
Subject: [PATCH v7 05/15] firmware: arm_scmi: Handle concurrent and
 out-of-order messages
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-6-cristian.marussi@arm.com>

Even though in case of asynchronous commands an SCMI platform is
constrained to emit the delayed response message only after the related
message response has been sent, the configured underlying transport could
still deliver such messages together or in inverted order, causing races
due to the concurrent or out-of-order access to the underlying xfer.

Introduce a mechanism to grant exclusive access to an xfer in order to
properly serialize concurrent accesses to the same xfer originating from
multiple correlated messages.

Add additional state information to xfer descriptors so as to be able to
identify out-of-order message deliveries and act accordingly:

 - when a delayed response is expected but delivered before the related
   response, the synchronous response is considered as successfully
   received and the delayed response processing is carried on as usual.

 - when/if the missing synchronous response is subsequently received, it
   is discarded as not congruent with the current state of the xfer, or
   simply, because the xfer has been already released and so, now, the
   monotonically increasing sequence number carried by the late response
   is stale.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v6 --> v7
- re-added xfer refcounting moved out of previous 'monotonic' patch
- removed un-needed 2-way switch in scmi_xfer_state_update()
- renamed scmi_xfer_is_free to scmi_xfer_acquired
- moved scmi_xfer_state_update() call inside scmi_xfer_command_acquire
  to avoid races between msg validation and xfer state update
- added smp_mb() after xfer->state init before .send_message
v5 --> v6
- added spinlock comment
---
 drivers/firmware/arm_scmi/common.h |  30 +++-
 drivers/firmware/arm_scmi/driver.c | 257 ++++++++++++++++++++++++-----
 2 files changed, 246 insertions(+), 41 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 651af0c7bed9..dd19ec2e0105 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -17,7 +17,9 @@
 #include <linux/hashtable.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/refcount.h>
 #include <linux/scmi_protocol.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 
 #include <asm/unaligned.h>
@@ -153,6 +155,23 @@ struct scmi_msg {
  * @pending: True for xfers added to @pending_xfers hashtable
  * @node: An hlist_node reference used to store this xfer, alternatively, on
  *	  the free list @free_xfers or in the @pending_xfers hashtable
+ * @users: A refcount to track the active users for this xfer.
+ *	   This is meant to protect against the possibility that, when a command
+ *	   transaction times out concurrently with the reception of a valid
+ *	   response message, the xfer could be finally put on the TX path, and
+ *	   so vanish, while on the RX path scmi_rx_callback() is still
+ *	   processing it: in such a case this refcounting will ensure that, even
+ *	   though the timed-out transaction will anyway cause the command
+ *	   request to be reported as failed by time-out, the underlying xfer
+ *	   cannot be discarded and possibly reused until the last one user on
+ *	   the RX path has released it.
+ * @busy: An atomic flag to ensure exclusive write access to this xfer
+ * @state: The current state of this transfer, with states transitions deemed
+ *	   valid being:
+ *	    - SCMI_XFER_SENT_OK -> SCMI_XFER_RESP_OK [ -> SCMI_XFER_DRESP_OK ]
+ *	    - SCMI_XFER_SENT_OK -> SCMI_XFER_DRESP_OK
+ *	      (Missing synchronous response is assumed OK and ignored)
+ * @lock: A spinlock to protect state and busy fields.
  */
 struct scmi_xfer {
 	int transfer_id;
@@ -163,6 +182,16 @@ struct scmi_xfer {
 	struct completion *async_done;
 	bool pending;
 	struct hlist_node node;
+	refcount_t users;
+#define SCMI_XFER_FREE		0
+#define SCMI_XFER_BUSY		1
+	atomic_t busy;
+#define SCMI_XFER_SENT_OK	0
+#define SCMI_XFER_RESP_OK	1
+#define SCMI_XFER_DRESP_OK	2
+	int state;
+	/* A lock to protect state and busy fields */
+	spinlock_t lock;
 };
 
 /*
@@ -399,5 +428,4 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
 void scmi_notification_instance_data_set(const struct scmi_handle *handle,
 					 void *priv);
 void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
-
 #endif /* _SCMI_COMMON_H */
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3c99390f9415..bfc35d7c7dbd 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -374,6 +374,11 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
 			xfer = ERR_PTR(ret);
 		}
 	}
+
+	if (!IS_ERR(xfer)) {
+		refcount_set(&xfer->users, 1);
+		atomic_set(&xfer->busy, SCMI_XFER_FREE);
+	}
 	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
 
 	return xfer;
@@ -396,12 +401,14 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
 	unsigned long flags;
 
 	spin_lock_irqsave(&minfo->xfer_lock, flags);
-	if (xfer->pending) {
-		scmi_xfer_token_clear(minfo, xfer);
-		hash_del(&xfer->node);
-		xfer->pending = false;
+	if (refcount_dec_and_test(&xfer->users)) {
+		if (xfer->pending) {
+			scmi_xfer_token_clear(minfo, xfer);
+			hash_del(&xfer->node);
+			xfer->pending = false;
+		}
+		hlist_add_head(&xfer->node, &minfo->free_xfers);
 	}
-	hlist_add_head(&xfer->node, &minfo->free_xfers);
 	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
 }
 
@@ -428,6 +435,171 @@ scmi_xfer_lookup_unlocked(struct scmi_xfers_info *minfo, u16 xfer_id)
 	return xfer ?: ERR_PTR(-EINVAL);
 }
 
+/**
+ * scmi_msg_response_validate  - Validate message type against state of related
+ * xfer
+ *
+ * @cinfo: A reference to the channel descriptor.
+ * @msg_type: Message type to check
+ * @xfer: A reference to the xfer to validate against @msg_type
+ *
+ * This function checks if @msg_type is congruent with the current state of
+ * a pending @xfer; if an asynchronous delayed response is received before the
+ * related synchronous response (Out-of-Order Delayed Response) the missing
+ * synchronous response is assumed to be OK and completed, carrying on with the
+ * Delayed Response: this is done to address the case in which the underlying
+ * SCMI transport can deliver such out-of-order responses.
+ *
+ * Context: Assumes to be called with xfer->lock already acquired.
+ *
+ * Return: 0 on Success, error otherwise
+ */
+static inline int scmi_msg_response_validate(struct scmi_chan_info *cinfo,
+					     u8 msg_type,
+					     struct scmi_xfer *xfer)
+{
+	/*
+	 * Even if a response was indeed expected on this slot at this point,
+	 * a buggy platform could wrongly reply feeding us an unexpected
+	 * delayed response we're not prepared to handle: bail-out safely
+	 * blaming firmware.
+	 */
+	if (msg_type == MSG_TYPE_DELAYED_RESP && !xfer->async_done) {
+		dev_err(cinfo->dev,
+			"Delayed Response for %d not expected! Buggy F/W ?\n",
+			xfer->hdr.seq);
+		return -EINVAL;
+	}
+
+	switch (xfer->state) {
+	case SCMI_XFER_SENT_OK:
+		if (msg_type == MSG_TYPE_DELAYED_RESP) {
+			/*
+			 * Delayed Response expected but delivered earlier.
+			 * Assume message RESPONSE was OK and skip state.
+			 */
+			xfer->hdr.status = SCMI_SUCCESS;
+			xfer->state = SCMI_XFER_RESP_OK;
+			complete(&xfer->done);
+			dev_warn(cinfo->dev,
+				 "Received valid OoO Delayed Response for %d\n",
+				 xfer->hdr.seq);
+		}
+		break;
+	case SCMI_XFER_RESP_OK:
+		if (msg_type != MSG_TYPE_DELAYED_RESP)
+			return -EINVAL;
+		break;
+	case SCMI_XFER_DRESP_OK:
+		/* No further message expected once in SCMI_XFER_DRESP_OK */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * scmi_xfer_state_update  - Update xfer state
+ *
+ * @xfer: A reference to the xfer to update
+ * @msg_type: Type of message being processed.
+ *
+ * Note that this message is assumed to have been already successfully validated
+ * by @scmi_msg_response_validate(), so here we just update the state.
+ *
+ * Context: Assumes to be called on an xfer exclusively acquired using the
+ *	    busy flag.
+ */
+static inline void scmi_xfer_state_update(struct scmi_xfer *xfer, u8 msg_type)
+{
+	xfer->hdr.type = msg_type;
+
+	/* Unknown command types were already discarded earlier */
+	if (xfer->hdr.type == MSG_TYPE_COMMAND)
+		xfer->state = SCMI_XFER_RESP_OK;
+	else
+		xfer->state = SCMI_XFER_DRESP_OK;
+}
+
+static bool scmi_xfer_acquired(struct scmi_xfer *xfer)
+{
+	int ret;
+
+	ret = atomic_cmpxchg(&xfer->busy, SCMI_XFER_FREE, SCMI_XFER_BUSY);
+
+	return ret == SCMI_XFER_FREE;
+}
+
+/**
+ * scmi_xfer_command_acquire  -  Helper to lookup and acquire a command xfer
+ *
+ * @cinfo: A reference to the channel descriptor.
+ * @msg_hdr: A message header to use as lookup key
+ *
+ * When a valid xfer is found for the sequence number embedded in the provided
+ * msg_hdr, reference counting is properly updated and exclusive access to this
+ * xfer is granted till released with @scmi_xfer_command_release.
+ *
+ * Return: A valid @xfer on Success or error otherwise.
+ */
+static inline struct scmi_xfer *
+scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
+{
+	int ret;
+	unsigned long flags;
+	struct scmi_xfer *xfer;
+	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
+	struct scmi_xfers_info *minfo = &info->tx_minfo;
+	u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
+	u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
+
+	/* Are we even expecting this? */
+	spin_lock_irqsave(&minfo->xfer_lock, flags);
+	xfer = scmi_xfer_lookup_unlocked(minfo, xfer_id);
+	if (IS_ERR(xfer)) {
+		dev_err(cinfo->dev,
+			"Message for %d type %d is not expected!\n",
+			xfer_id, msg_type);
+		spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+		return xfer;
+	}
+	refcount_inc(&xfer->users);
+	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
+	spin_lock_irqsave(&xfer->lock, flags);
+	ret = scmi_msg_response_validate(cinfo, msg_type, xfer);
+	/*
+	 * If a pending xfer was found which was also in a congruent state with
+	 * the received message, acquire exclusive access to it setting the busy
+	 * flag.
+	 * Spins only on the rare limit condition of concurrent reception of
+	 * RESP and DRESP for the same xfer.
+	 */
+	if (!ret) {
+		spin_until_cond(scmi_xfer_acquired(xfer));
+		scmi_xfer_state_update(xfer, msg_type);
+	}
+	spin_unlock_irqrestore(&xfer->lock, flags);
+
+	if (ret) {
+		dev_err(cinfo->dev,
+			"Invalid message type:%d for %d - HDR:0x%X  state:%d\n",
+			msg_type, xfer_id, msg_hdr, xfer->state);
+		/* On error the refcount incremented above has to be dropped */
+		__scmi_xfer_put(minfo, xfer);
+		xfer = ERR_PTR(-EINVAL);
+	}
+
+	return xfer;
+}
+
+static inline void scmi_xfer_command_release(struct scmi_info *info,
+					     struct scmi_xfer *xfer)
+{
+	atomic_set(&xfer->busy, SCMI_XFER_FREE);
+	__scmi_xfer_put(&info->tx_minfo, xfer);
+}
+
 static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 {
 	struct scmi_xfer *xfer;
@@ -460,57 +632,35 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 	info->desc->ops->clear_channel(cinfo);
 }
 
-static void scmi_handle_response(struct scmi_chan_info *cinfo,
-				 u16 xfer_id, u8 msg_type)
+static void scmi_handle_response(struct scmi_chan_info *cinfo, u32 msg_hdr)
 {
-	unsigned long flags;
 	struct scmi_xfer *xfer;
-	struct device *dev = cinfo->dev;
 	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
-	struct scmi_xfers_info *minfo = &info->tx_minfo;
 
-	/* Are we even expecting this? */
-	spin_lock_irqsave(&minfo->xfer_lock, flags);
-	xfer = scmi_xfer_lookup_unlocked(minfo, xfer_id);
-	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+	xfer = scmi_xfer_command_acquire(cinfo, msg_hdr);
 	if (IS_ERR(xfer)) {
-		dev_err(dev, "message for %d is not expected!\n", xfer_id);
 		info->desc->ops->clear_channel(cinfo);
 		return;
 	}
 
-	/*
-	 * Even if a response was indeed expected on this slot at this point,
-	 * a buggy platform could wrongly reply feeding us an unexpected
-	 * delayed response we're not prepared to handle: bail-out safely
-	 * blaming firmware.
-	 */
-	if (unlikely(msg_type == MSG_TYPE_DELAYED_RESP && !xfer->async_done)) {
-		dev_err(dev,
-			"Delayed Response for %d not expected! Buggy F/W ?\n",
-			xfer_id);
-		info->desc->ops->clear_channel(cinfo);
-		/* It was unexpected, so nobody will clear the xfer if not us */
-		__scmi_xfer_put(minfo, xfer);
-		return;
-	}
-
 	/* rx.len could be shrunk in the sync do_xfer, so reset to maxsz */
-	if (msg_type == MSG_TYPE_DELAYED_RESP)
+	if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP)
 		xfer->rx.len = info->desc->max_msg_size;
 
 	info->desc->ops->fetch_response(cinfo, xfer);
 
 	trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
 			   xfer->hdr.protocol_id, xfer->hdr.seq,
-			   msg_type);
+			   xfer->hdr.type);
 
-	if (msg_type == MSG_TYPE_DELAYED_RESP) {
+	if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) {
 		info->desc->ops->clear_channel(cinfo);
 		complete(xfer->async_done);
 	} else {
 		complete(&xfer->done);
 	}
+
+	scmi_xfer_command_release(info, xfer);
 }
 
 /**
@@ -527,7 +677,6 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
  */
 void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
 {
-	u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
 	u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
 
 	switch (msg_type) {
@@ -536,7 +685,7 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
 		break;
 	case MSG_TYPE_COMMAND:
 	case MSG_TYPE_DELAYED_RESP:
-		scmi_handle_response(cinfo, xfer_id, msg_type);
+		scmi_handle_response(cinfo, msg_hdr);
 		break;
 	default:
 		WARN_ONCE(1, "received unknown msg_type:%d\n", msg_type);
@@ -548,7 +697,7 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
  * xfer_put() - Release a transmit message
  *
  * @ph: Pointer to SCMI protocol handle
- * @xfer: message that was reserved by scmi_xfer_get
+ * @xfer: message that was reserved by xfer_get_init
  */
 static void xfer_put(const struct scmi_protocol_handle *ph,
 		     struct scmi_xfer *xfer)
@@ -566,7 +715,12 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
 {
 	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
 
+	/*
+	 * Poll also on xfer->done so that polling can be forcibly terminated
+	 * in case of out-of-order receptions of delayed responses
+	 */
 	return info->desc->ops->poll_done(cinfo, xfer) ||
+	       try_wait_for_completion(&xfer->done) ||
 	       ktime_after(ktime_get(), stop);
 }
 
@@ -606,6 +760,16 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 			      xfer->hdr.protocol_id, xfer->hdr.seq,
 			      xfer->hdr.poll_completion);
 
+	xfer->state = SCMI_XFER_SENT_OK;
+	/*
+	 * Even though spinlocking is not needed here since no race is possible
+	 * on xfer->state due to the monotonically increasing tokens allocation,
+	 * we must anyway ensure xfer->state initialization is not re-ordered
+	 * after the .send_message() to be sure that on the RX path an early
+	 * ISR calling scmi_rx_callback() cannot see an old stale xfer->state.
+	 */
+	smp_mb();
+
 	ret = info->desc->ops->send_message(cinfo, xfer);
 	if (ret < 0) {
 		dev_dbg(dev, "Failed to send message %d\n", ret);
@@ -617,10 +781,22 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 
 		spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
 
-		if (ktime_before(ktime_get(), stop))
-			info->desc->ops->fetch_response(cinfo, xfer);
-		else
+		if (ktime_before(ktime_get(), stop)) {
+			unsigned long flags;
+
+			/*
+			 * Do not fetch_response if an out-of-order delayed
+			 * response is being processed.
+			 */
+			spin_lock_irqsave(&xfer->lock, flags);
+			if (xfer->state == SCMI_XFER_SENT_OK) {
+				info->desc->ops->fetch_response(cinfo, xfer);
+				xfer->state = SCMI_XFER_RESP_OK;
+			}
+			spin_unlock_irqrestore(&xfer->lock, flags);
+		} else {
 			ret = -ETIMEDOUT;
+		}
 	} else {
 		/* And we wait for the response. */
 		timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
@@ -1218,6 +1394,7 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
 
 		xfer->tx.buf = xfer->rx.buf;
 		init_completion(&xfer->done);
+		spin_lock_init(&xfer->lock);
 
 		/* Add initialized xfer to the free list */
 		hlist_add_head(&xfer->node, &info->free_xfers);
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:16 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:16 +0100
Subject: [PATCH v7 07/15] firmware: arm_scmi: Make polling mode optional
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-8-cristian.marussi@arm.com>

Add a check for the presence of .poll_done transport operation so that
transports that do not need to support polling mode have no need to provide
a dummy .poll_done callback either and polling mode can be disabled in the
SCMI core for that tranport.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v6 --> v7
- s/EINVAL/-EINVAL/
- refactored to bail out early when polling mode not supported
---
 drivers/firmware/arm_scmi/driver.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 6c77fcc1bcb7..5ff0bcbb4db4 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -751,6 +751,12 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 	struct device *dev = info->dev;
 	struct scmi_chan_info *cinfo;
 
+	if (xfer->hdr.poll_completion && !info->desc->ops->poll_done) {
+		dev_warn_once(dev,
+			      "Polling mode is not supported by transport.\n");
+		return -EINVAL;
+	}
+
 	/*
 	 * Initialise protocol id now from protocol handle to avoid it being
 	 * overridden by mistake (or malice) by the protocol code mangling with
@@ -787,7 +793,6 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 		ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
 
 		spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
-
 		if (ktime_before(ktime_get(), stop)) {
 			unsigned long flags;
 
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:15 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:15 +0100
Subject: [PATCH v7 06/15] firmware: arm_scmi: Make .clear_channel optional
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-7-cristian.marussi@arm.com>

Make transport operation .clear_channel optional since some transports
do not need it and so avoid to have them implement dummy callbacks.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index bfc35d7c7dbd..6c77fcc1bcb7 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -600,6 +600,13 @@ static inline void scmi_xfer_command_release(struct scmi_info *info,
 	__scmi_xfer_put(&info->tx_minfo, xfer);
 }
 
+static inline void scmi_clear_channel(struct scmi_info *info,
+				      struct scmi_chan_info *cinfo)
+{
+	if (info->desc->ops->clear_channel)
+		info->desc->ops->clear_channel(cinfo);
+}
+
 static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 {
 	struct scmi_xfer *xfer;
@@ -613,7 +620,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 	if (IS_ERR(xfer)) {
 		dev_err(dev, "failed to get free message slot (%ld)\n",
 			PTR_ERR(xfer));
-		info->desc->ops->clear_channel(cinfo);
+		scmi_clear_channel(info, cinfo);
 		return;
 	}
 
@@ -629,7 +636,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 
 	__scmi_xfer_put(minfo, xfer);
 
-	info->desc->ops->clear_channel(cinfo);
+	scmi_clear_channel(info, cinfo);
 }
 
 static void scmi_handle_response(struct scmi_chan_info *cinfo, u32 msg_hdr)
@@ -639,7 +646,7 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, u32 msg_hdr)
 
 	xfer = scmi_xfer_command_acquire(cinfo, msg_hdr);
 	if (IS_ERR(xfer)) {
-		info->desc->ops->clear_channel(cinfo);
+		scmi_clear_channel(info, cinfo);
 		return;
 	}
 
@@ -654,7 +661,7 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, u32 msg_hdr)
 			   xfer->hdr.type);
 
 	if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) {
-		info->desc->ops->clear_channel(cinfo);
+		scmi_clear_channel(info, cinfo);
 		complete(xfer->async_done);
 	} else {
 		complete(&xfer->done);
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:17 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:17 +0100
Subject: [PATCH v7 08/15] firmware: arm_scmi: Make SCMI transports configurable
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-9-cristian.marussi@arm.com>

Add configuration options to be able to select which SCMI transports have
to be compiled into the SCMI stack.

Mailbox and SMC are by default enabled if their related dependencies are
satisfied.

While doing that move all SCMI related config options in their own
dedicated submenu.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
Used a BUILD_BUG_ON() to avoid the scenario where SCMI is configured
without any transport. Coul dnot do in any other way in Kconfig due to
circular dependencies.

This will be neeed later on to add new Virtio based transport and
optionally exclude other transports.

v6 --> v7
- using if ARM_SCMI_PROTOCOL to simplify depends
---
 drivers/firmware/Kconfig           | 34 +--------------
 drivers/firmware/arm_scmi/Kconfig  | 70 ++++++++++++++++++++++++++++++
 drivers/firmware/arm_scmi/Makefile |  4 +-
 drivers/firmware/arm_scmi/common.h |  4 +-
 drivers/firmware/arm_scmi/driver.c |  6 ++-
 5 files changed, 80 insertions(+), 38 deletions(-)
 create mode 100644 drivers/firmware/arm_scmi/Kconfig

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 1db738d5b301..8d41f73f5395 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -6,39 +6,7 @@
 
 menu "Firmware Drivers"
 
-config ARM_SCMI_PROTOCOL
-	tristate "ARM System Control and Management Interface (SCMI) Message Protocol"
-	depends on ARM || ARM64 || COMPILE_TEST
-	depends on MAILBOX || HAVE_ARM_SMCCC_DISCOVERY
-	help
-	  ARM System Control and Management Interface (SCMI) protocol is a
-	  set of operating system-independent software interfaces that are
-	  used in system management. SCMI is extensible and currently provides
-	  interfaces for: Discovery and self-description of the interfaces
-	  it supports, Power domain management which is the ability to place
-	  a given device or domain into the various power-saving states that
-	  it supports, Performance management which is the ability to control
-	  the performance of a domain that is composed of compute engines
-	  such as application processors and other accelerators, Clock
-	  management which is the ability to set and inquire rates on platform
-	  managed clocks and Sensor management which is the ability to read
-	  sensor data, and be notified of sensor value.
-
-	  This protocol library provides interface for all the client drivers
-	  making use of the features offered by the SCMI.
-
-config ARM_SCMI_POWER_DOMAIN
-	tristate "SCMI power domain driver"
-	depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
-	default y
-	select PM_GENERIC_DOMAINS if PM
-	help
-	  This enables support for the SCMI power domains which can be
-	  enabled or disabled via the SCP firmware
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called scmi_pm_domain. Note this may needed early in boot
-	  before rootfs may be available.
+source "drivers/firmware/arm_scmi/Kconfig"
 
 config ARM_SCPI_PROTOCOL
 	tristate "ARM System Control and Power Interface (SCPI) Message Protocol"
diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
new file mode 100644
index 000000000000..a6fcd06b2232
--- /dev/null
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "ARM System Control and Management Interface Protocol"
+
+config ARM_SCMI_PROTOCOL
+	tristate "ARM System Control and Management Interface (SCMI) Message Protocol"
+	depends on ARM || ARM64 || COMPILE_TEST
+	help
+	  ARM System Control and Management Interface (SCMI) protocol is a
+	  set of operating system-independent software interfaces that are
+	  used in system management. SCMI is extensible and currently provides
+	  interfaces for: Discovery and self-description of the interfaces
+	  it supports, Power domain management which is the ability to place
+	  a given device or domain into the various power-saving states that
+	  it supports, Performance management which is the ability to control
+	  the performance of a domain that is composed of compute engines
+	  such as application processors and other accelerators, Clock
+	  management which is the ability to set and inquire rates on platform
+	  managed clocks and Sensor management which is the ability to read
+	  sensor data, and be notified of sensor value.
+
+	  This protocol library provides interface for all the client drivers
+	  making use of the features offered by the SCMI.
+
+if ARM_SCMI_PROTOCOL
+
+config ARM_SCMI_HAVE_TRANSPORT
+	bool
+	help
+	  This declares whether at least one SCMI transport has been configured.
+	  Used to trigger a build bug when trying to build SCMI without any
+	  configured transport.
+
+config ARM_SCMI_TRANSPORT_MAILBOX
+	bool "SCMI transport based on Mailbox"
+	depends on MAILBOX
+	select ARM_SCMI_HAVE_TRANSPORT
+	default y
+	help
+	  Enable mailbox based transport for SCMI.
+
+	  If you want the ARM SCMI PROTOCOL stack to include support for a
+	  transport based on mailboxes, answer Y.
+
+config ARM_SCMI_TRANSPORT_SMC
+	bool "SCMI transport based on SMC"
+	depends on HAVE_ARM_SMCCC_DISCOVERY
+	select ARM_SCMI_HAVE_TRANSPORT
+	default y
+	help
+	  Enable SMC based transport for SCMI.
+
+	  If you want the ARM SCMI PROTOCOL stack to include support for a
+	  transport based on SMC, answer Y.
+
+endif #ARM_SCMI_PROTOCOL
+
+config ARM_SCMI_POWER_DOMAIN
+	tristate "SCMI power domain driver"
+	depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
+	default y
+	select PM_GENERIC_DOMAINS if PM
+	help
+	  This enables support for the SCMI power domains which can be
+	  enabled or disabled via the SCP firmware
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called scmi_pm_domain. Note this may needed early in boot
+	  before rootfs may be available.
+
+endmenu
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index 6a2ef63306d6..38163d6991b3 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -2,8 +2,8 @@
 scmi-bus-y = bus.o
 scmi-driver-y = driver.o notify.o
 scmi-transport-y = shmem.o
-scmi-transport-$(CONFIG_MAILBOX) += mailbox.o
-scmi-transport-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += smc.o
+scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o
+scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o
 scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \
 		    $(scmi-transport-y)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index dd19ec2e0105..204cde53a9a7 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -403,8 +403,10 @@ struct scmi_desc {
 	int max_msg_size;
 };
 
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
 extern const struct scmi_desc scmi_mailbox_desc;
-#ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY
+#endif
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
 extern const struct scmi_desc scmi_smc_desc;
 #endif
 
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 5ff0bcbb4db4..d20e6760b488 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1933,10 +1933,10 @@ ATTRIBUTE_GROUPS(versions);
 
 /* Each compatible listed below must have descriptor associated with it */
 static const struct of_device_id scmi_of_match[] = {
-#ifdef CONFIG_MAILBOX
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
 	{ .compatible = "arm,scmi", .data = &scmi_mailbox_desc },
 #endif
-#ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
 	{ .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
 #endif
 	{ /* Sentinel */ },
@@ -2008,6 +2008,8 @@ static int __init scmi_driver_init(void)
 
 	scmi_bus_init();
 
+	BUILD_BUG_ON(!IS_ENABLED(CONFIG_ARM_SCMI_HAVE_TRANSPORT));
+
 	/* Initialize any compiled-in transport which provided an init/exit */
 	ret = scmi_transports_init();
 	if (ret)
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:19 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:19 +0100
Subject: [PATCH v7 10/15] firmware: arm_scmi: Add method to override max
 message number
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-11-cristian.marussi@arm.com>

From: Igor Skalkin <igor.skalkin at opensynergy.com>

The maximum number of simultaneously pending messages is a transport
specific quantity that is usually described statically in struct scmi_desc.

Some transports, though, can calculate such number only at run-time after
some initial transport specific setup and probing is completed; moreover
the resulting max message numbers could also be different between rx and
tx channels.

Add an optional get_max_msg() operation so that a transport can report more
accurate max message numbers for each channel type.

The value in scmi_desc.max_msg is still used as default when transport does
not provide any get_max_msg() method.

Signed-off-by: Igor Skalkin <igor.skalkin at opensynergy.com>
[ Peter: Adapted patch for submission to upstream. ]
Co-developed-by: Peter Hilber <peter.hilber at opensynergy.com>
Signed-off-by: Peter Hilber <peter.hilber at opensynergy.com>
[ Cristian: refactored how get_max_msg() is used to minimize core changes ]
Co-developed-by: Cristian Marussi <cristian.marussi at arm.com>
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v4 --> v5
- refactored usage of get_max_msg()
---
 drivers/firmware/arm_scmi/common.h |  9 +++++--
 drivers/firmware/arm_scmi/driver.c | 40 +++++++++++++++++++++++++++---
 2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 204cde53a9a7..6320345865e8 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -351,6 +351,9 @@ struct scmi_chan_info {
  * @chan_available: Callback to check if channel is available or not
  * @chan_setup: Callback to allocate and setup a channel
  * @chan_free: Callback to free a channel
+ * @get_max_msg: Optional callback to provide max_msg dynamically
+ *		 Returns the maximum number of messages for the channel type
+ *		 (tx or rx) that can be pending simultaneously in the system
  * @send_message: Callback to send a message
  * @mark_txdone: Callback to mark tx as done
  * @fetch_response: Callback to fetch response
@@ -363,6 +366,7 @@ struct scmi_transport_ops {
 	int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev,
 			  bool tx);
 	int (*chan_free)(int id, void *p, void *data);
+	unsigned int (*get_max_msg)(struct scmi_chan_info *base_cinfo);
 	int (*send_message)(struct scmi_chan_info *cinfo,
 			    struct scmi_xfer *xfer);
 	void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret);
@@ -390,8 +394,9 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
  *		    de-initialization, so after SCMI core removal.
  * @ops: Pointer to the transport specific ops structure
  * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds)
- * @max_msg: Maximum number of messages that can be pending
- *	simultaneously in the system
+ * @max_msg: Maximum number of messages for a channel type (tx or rx) that can
+ *	be pending simultaneously in the system. May be overridden by the
+ *	get_max_msg op.
  * @max_msg_size: Maximum size of data per message that can be handled.
  */
 struct scmi_desc {
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index d20e6760b488..a907f3fe4c08 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -72,6 +72,7 @@ struct scmi_requested_dev {
  *	Index of this bitmap table is also used for message
  *	sequence identifier.
  * @xfer_lock: Protection for message allocation
+ * @max_msg: Maximum number of messages that can be pending
  * @free_xfers: A free list for available to use xfers. It is initialized with
  *		a number of xfers equal to the maximum allowed in-flight
  *		messages.
@@ -81,6 +82,7 @@ struct scmi_requested_dev {
 struct scmi_xfers_info {
 	unsigned long *xfer_alloc_table;
 	spinlock_t xfer_lock;
+	int max_msg;
 	struct hlist_head free_xfers;
 	DECLARE_HASHTABLE(pending_xfers, SCMI_PENDING_XFERS_HT_ORDER_SZ);
 };
@@ -1373,10 +1375,10 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
 	const struct scmi_desc *desc = sinfo->desc;
 
 	/* Pre-allocated messages, no more than what hdr.seq can support */
-	if (WARN_ON(!desc->max_msg || desc->max_msg > MSG_TOKEN_MAX)) {
+	if (WARN_ON(!info->max_msg || info->max_msg > MSG_TOKEN_MAX)) {
 		dev_err(dev,
 			"Invalid maximum messages %d, not in range [1 - %lu]\n",
-			desc->max_msg, MSG_TOKEN_MAX);
+			info->max_msg, MSG_TOKEN_MAX);
 		return -EINVAL;
 	}
 
@@ -1394,7 +1396,7 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
 	 * attach all of them to the free list
 	 */
 	INIT_HLIST_HEAD(&info->free_xfers);
-	for (i = 0; i < desc->max_msg; i++) {
+	for (i = 0; i < info->max_msg; i++) {
 		xfer = devm_kzalloc(dev, sizeof(*xfer), GFP_KERNEL);
 		if (!xfer)
 			return -ENOMEM;
@@ -1417,10 +1419,40 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
 	return 0;
 }
 
+static int scmi_channels_max_msg_configure(struct scmi_info *sinfo)
+{
+	const struct scmi_desc *desc = sinfo->desc;
+
+	if (!desc->ops->get_max_msg) {
+		sinfo->tx_minfo.max_msg = desc->max_msg;
+		sinfo->rx_minfo.max_msg = desc->max_msg;
+	} else {
+		struct scmi_chan_info *base_cinfo;
+
+		base_cinfo = idr_find(&sinfo->tx_idr, SCMI_PROTOCOL_BASE);
+		if (!base_cinfo)
+			return -EINVAL;
+		sinfo->tx_minfo.max_msg = desc->ops->get_max_msg(base_cinfo);
+
+		/* RX channel is optional so can be skipped */
+		base_cinfo = idr_find(&sinfo->rx_idr, SCMI_PROTOCOL_BASE);
+		if (base_cinfo)
+			sinfo->rx_minfo.max_msg =
+				desc->ops->get_max_msg(base_cinfo);
+	}
+
+	return 0;
+}
+
 static int scmi_xfer_info_init(struct scmi_info *sinfo)
 {
-	int ret = __scmi_xfer_info_init(sinfo, &sinfo->tx_minfo);
+	int ret;
+
+	ret = scmi_channels_max_msg_configure(sinfo);
+	if (ret)
+		return ret;
 
+	ret = __scmi_xfer_info_init(sinfo, &sinfo->tx_minfo);
 	if (!ret && idr_find(&sinfo->rx_idr, SCMI_PROTOCOL_BASE))
 		ret = __scmi_xfer_info_init(sinfo, &sinfo->rx_minfo);
 
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:18 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:18 +0100
Subject: [PATCH v7 09/15] firmware: arm_scmi: Make shmem support optional for
 transports
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-10-cristian.marussi@arm.com>

From: Igor Skalkin <igor.skalkin at opensynergy.com>

Upcoming new SCMI transports won't need any kind of shared memory support.
Compile shmem.c only if a shmem based transport is selected.

Signed-off-by: Igor Skalkin <igor.skalkin at opensynergy.com>
[ Peter: Adapted patch for submission to upstream. ]
Co-developed-by: Peter Hilber <peter.hilber at opensynergy.com>
Signed-off-by: Peter Hilber <peter.hilber at opensynergy.com>
[ Cristian: Adapted patch/commit_msg to new SCMI Kconfig layout ]
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v4 --> v5
- Adapted to new SCMI Kconfig layout
---
 drivers/firmware/arm_scmi/Kconfig  | 8 ++++++++
 drivers/firmware/arm_scmi/Makefile | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index a6fcd06b2232..cd84e5f2ee02 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -30,10 +30,17 @@ config ARM_SCMI_HAVE_TRANSPORT
 	  Used to trigger a build bug when trying to build SCMI without any
 	  configured transport.
 
+config ARM_SCMI_HAVE_SHMEM
+	bool
+	help
+	  This declares whether a shared memory based transport for SCMI is
+	  available.
+
 config ARM_SCMI_TRANSPORT_MAILBOX
 	bool "SCMI transport based on Mailbox"
 	depends on MAILBOX
 	select ARM_SCMI_HAVE_TRANSPORT
+	select ARM_SCMI_HAVE_SHMEM
 	default y
 	help
 	  Enable mailbox based transport for SCMI.
@@ -45,6 +52,7 @@ config ARM_SCMI_TRANSPORT_SMC
 	bool "SCMI transport based on SMC"
 	depends on HAVE_ARM_SMCCC_DISCOVERY
 	select ARM_SCMI_HAVE_TRANSPORT
+	select ARM_SCMI_HAVE_SHMEM
 	default y
 	help
 	  Enable SMC based transport for SCMI.
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index 38163d6991b3..e0e6bd3dba9e 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 scmi-bus-y = bus.o
 scmi-driver-y = driver.o notify.o
-scmi-transport-y = shmem.o
+scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) = shmem.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:20 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:20 +0100
Subject: [PATCH v7 11/15] firmware: arm_scmi: Add message passing abstractions
 for transports
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-12-cristian.marussi@arm.com>

From: Peter Hilber <peter.hilber at opensynergy.com>

Add abstractions for future transports using message passing, such as
virtio. Derive the abstractions from the shared memory abstractions.

Abstract the transport SDU through the opaque struct scmi_msg_payld.
Also enable the transport to determine all other required information
about the transport SDU.

Signed-off-by: Peter Hilber <peter.hilber at opensynergy.com>
[ Cristian: Adapted to new SCMI Kconfig layout, updated Copyrights ]
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v6 --> v7
- removed uneeded includes
v4 --> v5
- adapted to new SCMI Kconfig
- removed raw_payload msg helpers
v3 --> v4
- added raw_payload msg helpers
---
 drivers/firmware/arm_scmi/Kconfig  |   6 ++
 drivers/firmware/arm_scmi/Makefile |   1 +
 drivers/firmware/arm_scmi/common.h |  15 ++++
 drivers/firmware/arm_scmi/msg.c    | 111 +++++++++++++++++++++++++++++
 4 files changed, 133 insertions(+)
 create mode 100644 drivers/firmware/arm_scmi/msg.c

diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index cd84e5f2ee02..24fed705b02c 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -36,6 +36,12 @@ config ARM_SCMI_HAVE_SHMEM
 	  This declares whether a shared memory based transport for SCMI is
 	  available.
 
+config ARM_SCMI_HAVE_MSG
+	bool
+	help
+	  This declares whether a message passing based transport for SCMI is
+	  available.
+
 config ARM_SCMI_TRANSPORT_MAILBOX
 	bool "SCMI transport based on Mailbox"
 	depends on MAILBOX
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index e0e6bd3dba9e..aaad9f6589aa 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -4,6 +4,7 @@ scmi-driver-y = driver.o notify.o
 scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) = shmem.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
+scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o
 scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \
 		    $(scmi-transport-y)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 6320345865e8..4da6cecc0a1c 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -432,6 +432,21 @@ void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem);
 bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
 		     struct scmi_xfer *xfer);
 
+/* declarations for message passing transports */
+struct scmi_msg_payld;
+
+/* Maximum overhead of message w.r.t. struct scmi_desc.max_msg_size */
+#define SCMI_MSG_MAX_PROT_OVERHEAD (2 * sizeof(__le32))
+
+size_t msg_response_size(struct scmi_xfer *xfer);
+size_t msg_command_size(struct scmi_xfer *xfer);
+void msg_tx_prepare(struct scmi_msg_payld *msg, struct scmi_xfer *xfer);
+u32 msg_read_header(struct scmi_msg_payld *msg);
+void msg_fetch_response(struct scmi_msg_payld *msg, size_t len,
+			struct scmi_xfer *xfer);
+void msg_fetch_notification(struct scmi_msg_payld *msg, size_t len,
+			    size_t max_len, struct scmi_xfer *xfer);
+
 void scmi_notification_instance_data_set(const struct scmi_handle *handle,
 					 void *priv);
 void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
diff --git a/drivers/firmware/arm_scmi/msg.c b/drivers/firmware/arm_scmi/msg.c
new file mode 100644
index 000000000000..d33a704e5814
--- /dev/null
+++ b/drivers/firmware/arm_scmi/msg.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * For transports using message passing.
+ *
+ * Derived from shm.c.
+ *
+ * Copyright (C) 2019-2021 ARM Ltd.
+ * Copyright (C) 2020-2021 OpenSynergy GmbH
+ */
+
+#include <linux/types.h>
+
+#include "common.h"
+
+/*
+ * struct scmi_msg_payld - Transport SDU layout
+ *
+ * The SCMI specification requires all parameters, message headers, return
+ * arguments or any protocol data to be expressed in little endian format only.
+ */
+struct scmi_msg_payld {
+	__le32 msg_header;
+	__le32 msg_payload[];
+};
+
+/**
+ * msg_command_size() - Actual size of transport SDU for command.
+ *
+ * @xfer: message which core has prepared for sending
+ *
+ * Return: transport SDU size.
+ */
+size_t msg_command_size(struct scmi_xfer *xfer)
+{
+	return sizeof(struct scmi_msg_payld) + xfer->tx.len;
+}
+
+/**
+ * msg_response_size() - Maximum size of transport SDU for response.
+ *
+ * @xfer: message which core has prepared for sending
+ *
+ * Return: transport SDU size.
+ */
+size_t msg_response_size(struct scmi_xfer *xfer)
+{
+	return sizeof(struct scmi_msg_payld) + sizeof(__le32) + xfer->rx.len;
+}
+
+/**
+ * msg_tx_prepare() - Set up transport SDU for command.
+ *
+ * @msg: transport SDU for command
+ * @xfer: message which is being sent
+ */
+void msg_tx_prepare(struct scmi_msg_payld *msg, struct scmi_xfer *xfer)
+{
+	msg->msg_header = cpu_to_le32(pack_scmi_header(&xfer->hdr));
+	if (xfer->tx.buf)
+		memcpy(msg->msg_payload, xfer->tx.buf, xfer->tx.len);
+}
+
+/**
+ * msg_read_header() - Read SCMI header from transport SDU.
+ *
+ * @msg: transport SDU
+ *
+ * Return: SCMI header
+ */
+u32 msg_read_header(struct scmi_msg_payld *msg)
+{
+	return le32_to_cpu(msg->msg_header);
+}
+
+/**
+ * msg_fetch_response() - Fetch response SCMI payload from transport SDU.
+ *
+ * @msg: transport SDU with response
+ * @len: transport SDU size
+ * @xfer: message being responded to
+ */
+void msg_fetch_response(struct scmi_msg_payld *msg, size_t len,
+			struct scmi_xfer *xfer)
+{
+	size_t prefix_len = sizeof(*msg) + sizeof(msg->msg_payload[0]);
+
+	xfer->hdr.status = le32_to_cpu(msg->msg_payload[0]);
+	xfer->rx.len = min_t(size_t, xfer->rx.len,
+			     len >= prefix_len ? len - prefix_len : 0);
+
+	/* Take a copy to the rx buffer.. */
+	memcpy(xfer->rx.buf, &msg->msg_payload[1], xfer->rx.len);
+}
+
+/**
+ * msg_fetch_notification() - Fetch notification payload from transport SDU.
+ *
+ * @msg: transport SDU with notification
+ * @len: transport SDU size
+ * @max_len: maximum SCMI payload size to fetch
+ * @xfer: notification message
+ */
+void msg_fetch_notification(struct scmi_msg_payld *msg, size_t len,
+			    size_t max_len, struct scmi_xfer *xfer)
+{
+	xfer->rx.len = min_t(size_t, max_len,
+			     len >= sizeof(*msg) ? len - sizeof(*msg) : 0);
+
+	/* Take a copy to the rx buffer.. */
+	memcpy(xfer->rx.buf, msg->msg_payload, xfer->rx.len);
+}
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:21 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:21 +0100
Subject: [PATCH v7 12/15] firmware: arm_scmi: Add optional link_supplier()
 transport op
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-13-cristian.marussi@arm.com>

From: Peter Hilber <peter.hilber at opensynergy.com>

Some transports are also effectively registered with other kernel subsystem
in order to be properly probed and initialized; as a consequence such kind
of transports, and their related devices, might still not have been probed
and initialized at the time the main SCMI core driver is probed.

Add an optional .link_supplier() transport operation which can be used by
the core SCMI stack to dynamically check if the transport is ready and
dynamically link its device to the SCMI platform instance device.

Signed-off-by: Peter Hilber <peter.hilber at opensynergy.com>
[ Cristian: reworded commit message ]
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v6 --> v7
- fixed commit message
v5 --> v6
- reworded commit message
---
 drivers/firmware/arm_scmi/common.h | 2 ++
 drivers/firmware/arm_scmi/driver.c | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 4da6cecc0a1c..024d97fbf97b 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -348,6 +348,7 @@ struct scmi_chan_info {
 /**
  * struct scmi_transport_ops - Structure representing a SCMI transport ops
  *
+ * @link_supplier: Optional callback to add link to a supplier device
  * @chan_available: Callback to check if channel is available or not
  * @chan_setup: Callback to allocate and setup a channel
  * @chan_free: Callback to free a channel
@@ -362,6 +363,7 @@ struct scmi_chan_info {
  * @poll_done: Callback to poll transfer status
  */
 struct scmi_transport_ops {
+	int (*link_supplier)(struct device *dev);
 	bool (*chan_available)(struct device *dev, int idx);
 	int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev,
 			  bool tx);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index a907f3fe4c08..7ae4ec8f8d1f 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1814,6 +1814,12 @@ static int scmi_probe(struct platform_device *pdev)
 	handle->devm_protocol_get = scmi_devm_protocol_get;
 	handle->devm_protocol_put = scmi_devm_protocol_put;
 
+	if (desc->ops->link_supplier) {
+		ret = desc->ops->link_supplier(dev);
+		if (ret)
+			return ret;
+	}
+
 	ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
 	if (ret)
 		return ret;
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:22 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:22 +0100
Subject: [PATCH v7 13/15] dt-bindings: arm: Add virtio transport for SCMI
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-14-cristian.marussi@arm.com>

From: Igor Skalkin <igor.skalkin at opensynergy.com>

Document the properties for arm,scmi-virtio compatible nodes.
The backing virtio SCMI device is described in patch [1].

While doing that, make shmem property required only for pre-existing
mailbox and smc transports, since virtio-scmi does not need it.

[1] https://lists.oasis-open.org/archives/virtio-comment/202102/msg00018.html

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Igor Skalkin <igor.skalkin at opensynergy.com>
[ Peter: Adapted patch for submission to upstream. ]
Co-developed-by: Peter Hilber <peter.hilber at opensynergy.com>
Signed-off-by: Peter Hilber <peter.hilber at opensynergy.com>
[ Cristian: converted to yaml format, moved shmen required property. ]
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v3 --> V4
- convertd to YAML
- make shmem required only for pre-existing mailbox and smc transport
- updated VirtIO specification patch message reference
- dropped virtio-mmio SCMI device example since really not pertinent to
  virtio-scmi dt bindings transport: it is not even referenced in SCMI
  virtio DT node since they are enumerated by VirtIO subsystem and there
  could be PCI based SCMI devices anyway.
---
 Documentation/devicetree/bindings/firmware/arm,scmi.yaml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index cebf6ffe70d5..5c4c6782e052 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -34,6 +34,10 @@ properties:
       - description: SCMI compliant firmware with ARM SMC/HVC transport
         items:
           - const: arm,scmi-smc
+      - description: SCMI compliant firmware with SCMI Virtio transport.
+                     The virtio transport only supports a single device.
+        items:
+          - const: arm,scmi-virtio
 
   interrupts:
     description:
@@ -172,6 +176,7 @@ patternProperties:
       Each sub-node represents a protocol supported. If the platform
       supports a dedicated communication channel for a particular protocol,
       then the corresponding transport properties must be present.
+      The virtio transport does not support a dedicated communication channel.
 
     properties:
       reg:
@@ -195,7 +200,6 @@ patternProperties:
 
 required:
   - compatible
-  - shmem
 
 if:
   properties:
@@ -209,6 +213,7 @@ then:
 
   required:
     - mboxes
+    - shmem
 
 else:
   if:
@@ -219,6 +224,7 @@ else:
   then:
     required:
       - arm,smc-id
+      - shmem
 
 examples:
   - |
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:23 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:23 +0100
Subject: [PATCH v7 14/15] firmware: arm_scmi: Add priv parameter to
 scmi_rx_callback
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-15-cristian.marussi@arm.com>

Add a new opaque void *priv parameter to scmi_rx_callback which can be
optionally provided by the transport layer when invoking scmi_rx_callback
and that will be passed back to the transport layer in xfer->priv.

This can be used by transports that needs to keep track of their specific
data structures together with the valid xfers.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v6 --> v7
- moved this patch later in the series right before virtio support
  that directly needs it.
---
 drivers/firmware/arm_scmi/common.h  |  4 +++-
 drivers/firmware/arm_scmi/driver.c  | 17 ++++++++++++-----
 drivers/firmware/arm_scmi/mailbox.c |  2 +-
 drivers/firmware/arm_scmi/smc.c     |  3 ++-
 4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 024d97fbf97b..7864c21269b0 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -172,6 +172,7 @@ struct scmi_msg {
  *	    - SCMI_XFER_SENT_OK -> SCMI_XFER_DRESP_OK
  *	      (Missing synchronous response is assumed OK and ignored)
  * @lock: A spinlock to protect state and busy fields.
+ * @priv: A pointer for transport private usage.
  */
 struct scmi_xfer {
 	int transfer_id;
@@ -192,6 +193,7 @@ struct scmi_xfer {
 	int state;
 	/* A lock to protect state and busy fields */
 	spinlock_t lock;
+	void *priv;
 };
 
 /*
@@ -417,7 +419,7 @@ extern const struct scmi_desc scmi_mailbox_desc;
 extern const struct scmi_desc scmi_smc_desc;
 #endif
 
-void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr);
+void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
 void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
 
 /* shmem related declarations */
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 7ae4ec8f8d1f..aaca01a4d752 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -609,7 +609,8 @@ static inline void scmi_clear_channel(struct scmi_info *info,
 		info->desc->ops->clear_channel(cinfo);
 }
 
-static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
+static void scmi_handle_notification(struct scmi_chan_info *cinfo,
+				     u32 msg_hdr, void *priv)
 {
 	struct scmi_xfer *xfer;
 	struct device *dev = cinfo->dev;
@@ -627,6 +628,8 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 	}
 
 	unpack_scmi_header(msg_hdr, &xfer->hdr);
+	if (priv)
+		xfer->priv = priv;
 	info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
 					    xfer);
 	scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
@@ -641,7 +644,8 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr)
 	scmi_clear_channel(info, cinfo);
 }
 
-static void scmi_handle_response(struct scmi_chan_info *cinfo, u32 msg_hdr)
+static void scmi_handle_response(struct scmi_chan_info *cinfo,
+				 u32 msg_hdr, void *priv)
 {
 	struct scmi_xfer *xfer;
 	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
@@ -656,6 +660,8 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, u32 msg_hdr)
 	if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP)
 		xfer->rx.len = info->desc->max_msg_size;
 
+	if (priv)
+		xfer->priv = priv;
 	info->desc->ops->fetch_response(cinfo, xfer);
 
 	trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
@@ -677,6 +683,7 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, u32 msg_hdr)
  *
  * @cinfo: SCMI channel info
  * @msg_hdr: Message header
+ * @priv: Transport specific private data.
  *
  * Processes one received message to appropriate transfer information and
  * signals completion of the transfer.
@@ -684,17 +691,17 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, u32 msg_hdr)
  * NOTE: This function will be invoked in IRQ context, hence should be
  * as optimal as possible.
  */
-void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
+void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv)
 {
 	u8 msg_type = MSG_XTRACT_TYPE(msg_hdr);
 
 	switch (msg_type) {
 	case MSG_TYPE_NOTIFICATION:
-		scmi_handle_notification(cinfo, msg_hdr);
+		scmi_handle_notification(cinfo, msg_hdr, priv);
 		break;
 	case MSG_TYPE_COMMAND:
 	case MSG_TYPE_DELAYED_RESP:
-		scmi_handle_response(cinfo, msg_hdr);
+		scmi_handle_response(cinfo, msg_hdr, priv);
 		break;
 	default:
 		WARN_ONCE(1, "received unknown msg_type:%d\n", msg_type);
diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c
index e3dcb58314ae..e09eb12bf421 100644
--- a/drivers/firmware/arm_scmi/mailbox.c
+++ b/drivers/firmware/arm_scmi/mailbox.c
@@ -43,7 +43,7 @@ static void rx_callback(struct mbox_client *cl, void *m)
 {
 	struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
 
-	scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem));
+	scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL);
 }
 
 static bool mailbox_chan_available(struct device *dev, int idx)
diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index bed5596c7209..4effecc3bb46 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -154,7 +154,8 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
 	if (scmi_info->irq)
 		wait_for_completion(&scmi_info->tx_complete);
 
-	scmi_rx_callback(scmi_info->cinfo, shmem_read_header(scmi_info->shmem));
+	scmi_rx_callback(scmi_info->cinfo,
+			 shmem_read_header(scmi_info->shmem), NULL);
 
 	mutex_unlock(&scmi_info->shmem_lock);
 
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug  3 06:10:24 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue,  3 Aug 2021 14:10:24 +0100
Subject: [PATCH v7 15/15] firmware: arm_scmi: Add virtio transport
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <20210803131024.40280-16-cristian.marussi@arm.com>

From: Igor Skalkin <igor.skalkin at opensynergy.com>

This transport enables communications with an SCMI platform through virtio;
the SCMI platform will be represented by a virtio device.

Implement an SCMI virtio driver according to the virtio SCMI device spec
[1]. Virtio device id 32 has been reserved for the SCMI device [2].

The virtio transport has one Tx channel (virtio cmdq, A2P channel) and
at most one Rx channel (virtio eventq, P2A channel).

The following feature bit defined in [1] is not implemented:
VIRTIO_SCMI_F_SHARED_MEMORY.

The number of messages which can be pending simultaneously is restricted
according to the virtqueue capacity negotiated at probing time.

As soon as Rx channel message buffers are allocated or have been read
out by the arm-scmi driver, feed them back to the virtio device.

Since some virtio devices may not have the short response time exhibited
by SCMI platforms using other transports, set a generous response
timeout.

SCMI polling mode is not supported by this virtio transport since deemed
meaningless: polling mode operation is offered by the SCMI core to those
transports that could not provide a completion interrupt on the TX path,
which is never the case for virtio whose core callbacks can easily call
into core scmi_rx_callback upon messages reception.

[1] https://github.com/oasis-tcs/virtio-spec/blob/master/virtio-scmi.tex
[2] https://www.oasis-open.org/committees/ballot.php?id=3496

Cc: "Michael S. Tsirkin" <mst at redhat.com>
Cc: Jason Wang <jasowang at redhat.com>
Signed-off-by: Igor Skalkin <igor.skalkin at opensynergy.com>
[ Peter: Adapted patch for submission to upstream. ]
Co-developed-by: Peter Hilber <peter.hilber at opensynergy.com>
Signed-off-by: Peter Hilber <peter.hilber at opensynergy.com>
[ Cristian: simplified driver logic, changed link_supplier and channel
	    available/setup logic, removed dummy callbacks ]
Co-developed-by: Cristian Marussi <cristian.marussi at arm.com>
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
NOTE THAT VIRTIO TRANSPORT IS ADDED AS default=n

V6 --> V7
- renamed desc init/exit to transport_init/exit
- reviewed Kconfig option to fit V7 ARM_SCMI Kconfig

V5 --> V6
- removed usage of delegated xfers
- using new scmi_rx_callback with priv argument
- removed .dummy clear_channel/.poll_done callbacks
- added missing spinlock comments
- updated Copyrights

V4 --> V5
- adapted Virtio transport config to new SCMI Kconfig layout
- removed support for polling
- added validate virtio method support
- removed usage of raw_payload helpers
- removed dynamic search of matching devices
- added one single statically configured device

V3 --> V4
- using delegated xfers
- using raw_payload msg helpers
---
 MAINTAINERS                        |   1 +
 drivers/firmware/arm_scmi/Kconfig  |  11 +
 drivers/firmware/arm_scmi/Makefile |   1 +
 drivers/firmware/arm_scmi/common.h |   3 +
 drivers/firmware/arm_scmi/driver.c |   3 +
 drivers/firmware/arm_scmi/virtio.c | 491 +++++++++++++++++++++++++++++
 include/uapi/linux/virtio_ids.h    |   1 +
 include/uapi/linux/virtio_scmi.h   |  24 ++
 8 files changed, 535 insertions(+)
 create mode 100644 drivers/firmware/arm_scmi/virtio.c
 create mode 100644 include/uapi/linux/virtio_scmi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a61f4f3b78a9..db1c7b74642e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17940,6 +17940,7 @@ F:	drivers/regulator/scmi-regulator.c
 F:	drivers/reset/reset-scmi.c
 F:	include/linux/sc[mp]i_protocol.h
 F:	include/trace/events/scmi.h
+F:	include/uapi/linux/virtio_scmi.h
 
 SYSTEM RESET/SHUTDOWN DRIVERS
 M:	Sebastian Reichel <sre at kernel.org>
diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index 24fed705b02c..7f4d2435503b 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -66,6 +66,17 @@ config ARM_SCMI_TRANSPORT_SMC
 	  If you want the ARM SCMI PROTOCOL stack to include support for a
 	  transport based on SMC, answer Y.
 
+config ARM_SCMI_TRANSPORT_VIRTIO
+	bool "SCMI transport based on VirtIO"
+	depends on VIRTIO
+	select ARM_SCMI_HAVE_TRANSPORT
+	select ARM_SCMI_HAVE_MSG
+	help
+	  This enables the virtio based transport for SCMI.
+
+	  If you want the ARM SCMI PROTOCOL stack to include support for a
+	  transport based on VirtIO, answer Y.
+
 endif #ARM_SCMI_PROTOCOL
 
 config ARM_SCMI_POWER_DOMAIN
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index aaad9f6589aa..1dcf123d64ab 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -5,6 +5,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) = shmem.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
 scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
+scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o
 scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \
 		    $(scmi-transport-y)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 7864c21269b0..dea1bfbe1052 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -418,6 +418,9 @@ extern const struct scmi_desc scmi_mailbox_desc;
 #ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
 extern const struct scmi_desc scmi_smc_desc;
 #endif
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO
+extern const struct scmi_desc scmi_virtio_desc;
+#endif
 
 void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
 void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index aaca01a4d752..00fcacd06562 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1983,6 +1983,9 @@ static const struct of_device_id scmi_of_match[] = {
 #endif
 #ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
 	{ .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
+#endif
+#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO
+	{ .compatible = "arm,scmi-virtio", .data = &scmi_virtio_desc},
 #endif
 	{ /* Sentinel */ },
 };
diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
new file mode 100644
index 000000000000..3dacf794b177
--- /dev/null
+++ b/drivers/firmware/arm_scmi/virtio.c
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Virtio Transport driver for Arm System Control and Management Interface
+ * (SCMI).
+ *
+ * Copyright (C) 2020-2021 OpenSynergy.
+ * Copyright (C) 2021 ARM Ltd.
+ */
+
+/**
+ * DOC: Theory of Operation
+ *
+ * The scmi-virtio transport implements a driver for the virtio SCMI device.
+ *
+ * There is one Tx channel (virtio cmdq, A2P channel) and at most one Rx
+ * channel (virtio eventq, P2A channel). Each channel is implemented through a
+ * virtqueue. Access to each virtqueue is protected by spinlocks.
+ */
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+
+#include <uapi/linux/virtio_ids.h>
+#include <uapi/linux/virtio_scmi.h>
+
+#include "common.h"
+
+#define VIRTIO_SCMI_MAX_MSG_SIZE 128 /* Value may be increased. */
+#define VIRTIO_SCMI_MAX_PDU_SIZE \
+	(VIRTIO_SCMI_MAX_MSG_SIZE + SCMI_MSG_MAX_PROT_OVERHEAD)
+#define DESCRIPTORS_PER_TX_MSG 2
+
+/**
+ * struct scmi_vio_channel - Transport channel information
+ *
+ * @vqueue: Associated virtqueue
+ * @cinfo: SCMI Tx or Rx channel
+ * @free_list: List of unused scmi_vio_msg, maintained for Tx channels only
+ * @is_rx: Whether channel is an Rx channel
+ * @ready: Whether transport user is ready to hear about channel
+ * @max_msg: Maximum number of pending messages for this channel.
+ * @lock: Protects access to all members except ready.
+ * @ready_lock: Protects access to ready. If required, it must be taken before
+ *              lock.
+ */
+struct scmi_vio_channel {
+	struct virtqueue *vqueue;
+	struct scmi_chan_info *cinfo;
+	struct list_head free_list;
+	bool is_rx;
+	bool ready;
+	unsigned int max_msg;
+	/* lock to protect access to all members except ready. */
+	spinlock_t lock;
+	/* lock to rotects access to ready flag. */
+	spinlock_t ready_lock;
+};
+
+/**
+ * struct scmi_vio_msg - Transport PDU information
+ *
+ * @request: SDU used for commands
+ * @input: SDU used for (delayed) responses and notifications
+ * @list: List which scmi_vio_msg may be part of
+ * @rx_len: Input SDU size in bytes, once input has been received
+ */
+struct scmi_vio_msg {
+	struct scmi_msg_payld *request;
+	struct scmi_msg_payld *input;
+	struct list_head list;
+	unsigned int rx_len;
+};
+
+/* Only one SCMI VirtIO device can possibly exist */
+static struct virtio_device *scmi_vdev;
+
+static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
+{
+	return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
+}
+
+static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
+			       struct scmi_vio_msg *msg)
+{
+	struct scatterlist sg_in;
+	int rc;
+	unsigned long flags;
+
+	sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);
+
+	spin_lock_irqsave(&vioch->lock, flags);
+
+	rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
+	if (rc)
+		dev_err_once(vioch->cinfo->dev,
+			     "failed to add to virtqueue (%d)\n", rc);
+	else
+		virtqueue_kick(vioch->vqueue);
+
+	spin_unlock_irqrestore(&vioch->lock, flags);
+
+	return rc;
+}
+
+static void scmi_finalize_message(struct scmi_vio_channel *vioch,
+				  struct scmi_vio_msg *msg)
+{
+	if (vioch->is_rx) {
+		scmi_vio_feed_vq_rx(vioch, msg);
+	} else {
+		unsigned long flags;
+
+		spin_lock_irqsave(&vioch->lock, flags);
+		list_add(&msg->list, &vioch->free_list);
+		spin_unlock_irqrestore(&vioch->lock, flags);
+	}
+}
+
+static void scmi_vio_complete_cb(struct virtqueue *vqueue)
+{
+	unsigned long ready_flags;
+	unsigned long flags;
+	unsigned int length;
+	struct scmi_vio_channel *vioch;
+	struct scmi_vio_msg *msg;
+	bool cb_enabled = true;
+
+	if (WARN_ON_ONCE(!vqueue->vdev->priv))
+		return;
+	vioch = &((struct scmi_vio_channel *)vqueue->vdev->priv)[vqueue->index];
+
+	for (;;) {
+		spin_lock_irqsave(&vioch->ready_lock, ready_flags);
+
+		if (!vioch->ready) {
+			if (!cb_enabled)
+				(void)virtqueue_enable_cb(vqueue);
+			goto unlock_ready_out;
+		}
+
+		spin_lock_irqsave(&vioch->lock, flags);
+		if (cb_enabled) {
+			virtqueue_disable_cb(vqueue);
+			cb_enabled = false;
+		}
+		msg = virtqueue_get_buf(vqueue, &length);
+		if (!msg) {
+			if (virtqueue_enable_cb(vqueue))
+				goto unlock_out;
+			cb_enabled = true;
+		}
+		spin_unlock_irqrestore(&vioch->lock, flags);
+
+		if (msg) {
+			msg->rx_len = length;
+			scmi_rx_callback(vioch->cinfo,
+					 msg_read_header(msg->input), msg);
+
+			scmi_finalize_message(vioch, msg);
+		}
+
+		spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
+	}
+
+unlock_out:
+	spin_unlock_irqrestore(&vioch->lock, flags);
+unlock_ready_out:
+	spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
+}
+
+static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };
+
+static vq_callback_t *scmi_vio_complete_callbacks[] = {
+	scmi_vio_complete_cb,
+	scmi_vio_complete_cb
+};
+
+static unsigned int virtio_get_max_msg(struct scmi_chan_info *base_cinfo)
+{
+	struct scmi_vio_channel *vioch = base_cinfo->transport_info;
+
+	return vioch->max_msg;
+}
+
+static int virtio_link_supplier(struct device *dev)
+{
+	if (!scmi_vdev) {
+		dev_notice_once(dev,
+				"Deferring probe after not finding a bound scmi-virtio device\n");
+		return -EPROBE_DEFER;
+	}
+
+	if (!device_link_add(dev, &scmi_vdev->dev,
+			     DL_FLAG_AUTOREMOVE_CONSUMER)) {
+		dev_err(dev, "Adding link to supplier virtio device failed\n");
+		return -ECANCELED;
+	}
+
+	return 0;
+}
+
+static bool virtio_chan_available(struct device *dev, int idx)
+{
+	struct scmi_vio_channel *channels, *vioch = NULL;
+
+	if (WARN_ON_ONCE(!scmi_vdev))
+		return false;
+
+	channels = (struct scmi_vio_channel *)scmi_vdev->priv;
+
+	switch (idx) {
+	case VIRTIO_SCMI_VQ_TX:
+		vioch = &channels[VIRTIO_SCMI_VQ_TX];
+		break;
+	case VIRTIO_SCMI_VQ_RX:
+		if (scmi_vio_have_vq_rx(scmi_vdev))
+			vioch = &channels[VIRTIO_SCMI_VQ_RX];
+		break;
+	default:
+		return false;
+	}
+
+	return vioch && !vioch->cinfo ? true : false;
+}
+
+static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+			     bool tx)
+{
+	unsigned long flags;
+	struct scmi_vio_channel *vioch;
+	int index = tx ? VIRTIO_SCMI_VQ_TX : VIRTIO_SCMI_VQ_RX;
+	int i;
+
+	if (!scmi_vdev)
+		return -EPROBE_DEFER;
+
+	vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
+
+	for (i = 0; i < vioch->max_msg; i++) {
+		struct scmi_vio_msg *msg;
+
+		msg = devm_kzalloc(cinfo->dev, sizeof(*msg), GFP_KERNEL);
+		if (!msg)
+			return -ENOMEM;
+
+		if (tx) {
+			msg->request = devm_kzalloc(cinfo->dev,
+						    VIRTIO_SCMI_MAX_PDU_SIZE,
+						    GFP_KERNEL);
+			if (!msg->request)
+				return -ENOMEM;
+		}
+
+		msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
+					  GFP_KERNEL);
+		if (!msg->input)
+			return -ENOMEM;
+
+		if (tx) {
+			spin_lock_irqsave(&vioch->lock, flags);
+			list_add_tail(&msg->list, &vioch->free_list);
+			spin_unlock_irqrestore(&vioch->lock, flags);
+		} else {
+			scmi_vio_feed_vq_rx(vioch, msg);
+		}
+	}
+
+	spin_lock_irqsave(&vioch->lock, flags);
+	cinfo->transport_info = vioch;
+	/* Indirectly setting channel not available any more */
+	vioch->cinfo = cinfo;
+	spin_unlock_irqrestore(&vioch->lock, flags);
+
+	spin_lock_irqsave(&vioch->ready_lock, flags);
+	vioch->ready = true;
+	spin_unlock_irqrestore(&vioch->ready_lock, flags);
+
+	return 0;
+}
+
+static int virtio_chan_free(int id, void *p, void *data)
+{
+	unsigned long flags;
+	struct scmi_chan_info *cinfo = p;
+	struct scmi_vio_channel *vioch = cinfo->transport_info;
+
+	spin_lock_irqsave(&vioch->ready_lock, flags);
+	vioch->ready = false;
+	spin_unlock_irqrestore(&vioch->ready_lock, flags);
+
+	scmi_free_channel(cinfo, data, id);
+
+	spin_lock_irqsave(&vioch->lock, flags);
+	vioch->cinfo = NULL;
+	spin_unlock_irqrestore(&vioch->lock, flags);
+
+	return 0;
+}
+
+static int virtio_send_message(struct scmi_chan_info *cinfo,
+			       struct scmi_xfer *xfer)
+{
+	struct scmi_vio_channel *vioch = cinfo->transport_info;
+	struct scatterlist sg_out;
+	struct scatterlist sg_in;
+	struct scatterlist *sgs[DESCRIPTORS_PER_TX_MSG] = { &sg_out, &sg_in };
+	unsigned long flags;
+	int rc;
+	struct scmi_vio_msg *msg;
+
+	spin_lock_irqsave(&vioch->lock, flags);
+
+	if (list_empty(&vioch->free_list)) {
+		spin_unlock_irqrestore(&vioch->lock, flags);
+		return -EBUSY;
+	}
+
+	msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
+	list_del(&msg->list);
+
+	msg_tx_prepare(msg->request, xfer);
+
+	sg_init_one(&sg_out, msg->request, msg_command_size(xfer));
+	sg_init_one(&sg_in, msg->input, msg_response_size(xfer));
+
+	rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC);
+	if (rc) {
+		list_add(&msg->list, &vioch->free_list);
+		dev_err_once(vioch->cinfo->dev,
+			     "%s() failed to add to virtqueue (%d)\n", __func__,
+			     rc);
+	} else {
+		virtqueue_kick(vioch->vqueue);
+	}
+
+	spin_unlock_irqrestore(&vioch->lock, flags);
+
+	return rc;
+}
+
+static void virtio_fetch_response(struct scmi_chan_info *cinfo,
+				  struct scmi_xfer *xfer)
+{
+	struct scmi_vio_msg *msg = xfer->priv;
+
+	if (msg) {
+		msg_fetch_response(msg->input, msg->rx_len, xfer);
+		xfer->priv = NULL;
+	}
+}
+
+static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
+				      size_t max_len, struct scmi_xfer *xfer)
+{
+	struct scmi_vio_msg *msg = xfer->priv;
+
+	if (msg) {
+		msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);
+		xfer->priv = NULL;
+	}
+}
+
+static const struct scmi_transport_ops scmi_virtio_ops = {
+	.link_supplier = virtio_link_supplier,
+	.chan_available = virtio_chan_available,
+	.chan_setup = virtio_chan_setup,
+	.chan_free = virtio_chan_free,
+	.get_max_msg = virtio_get_max_msg,
+	.send_message = virtio_send_message,
+	.fetch_response = virtio_fetch_response,
+	.fetch_notification = virtio_fetch_notification,
+};
+
+static int scmi_vio_probe(struct virtio_device *vdev)
+{
+	struct device *dev = &vdev->dev;
+	struct scmi_vio_channel *channels;
+	bool have_vq_rx;
+	int vq_cnt;
+	int i;
+	int ret;
+	struct virtqueue *vqs[VIRTIO_SCMI_VQ_MAX_CNT];
+
+	/* Only one SCMI VirtiO device allowed */
+	if (scmi_vdev)
+		return -EINVAL;
+
+	have_vq_rx = scmi_vio_have_vq_rx(vdev);
+	vq_cnt = have_vq_rx ? VIRTIO_SCMI_VQ_MAX_CNT : 1;
+
+	channels = devm_kcalloc(dev, vq_cnt, sizeof(*channels), GFP_KERNEL);
+	if (!channels)
+		return -ENOMEM;
+
+	if (have_vq_rx)
+		channels[VIRTIO_SCMI_VQ_RX].is_rx = true;
+
+	ret = virtio_find_vqs(vdev, vq_cnt, vqs, scmi_vio_complete_callbacks,
+			      scmi_vio_vqueue_names, NULL);
+	if (ret) {
+		dev_err(dev, "Failed to get %d virtqueue(s)\n", vq_cnt);
+		return ret;
+	}
+
+	for (i = 0; i < vq_cnt; i++) {
+		unsigned int sz;
+
+		spin_lock_init(&channels[i].lock);
+		spin_lock_init(&channels[i].ready_lock);
+		INIT_LIST_HEAD(&channels[i].free_list);
+		channels[i].vqueue = vqs[i];
+
+		sz = virtqueue_get_vring_size(channels[i].vqueue);
+		/* Tx messages need multiple descriptors. */
+		if (!channels[i].is_rx)
+			sz /= DESCRIPTORS_PER_TX_MSG;
+
+		if (sz > MSG_TOKEN_MAX) {
+			dev_info_once(dev,
+				      "%s virtqueue could hold %d messages. Only %ld allowed to be pending.\n",
+				      channels[i].is_rx ? "rx" : "tx",
+				      sz, MSG_TOKEN_MAX);
+			sz = MSG_TOKEN_MAX;
+		}
+		channels[i].max_msg = sz;
+	}
+
+	vdev->priv = channels;
+	scmi_vdev = vdev;
+
+	return 0;
+}
+
+static void scmi_vio_remove(struct virtio_device *vdev)
+{
+	vdev->config->reset(vdev);
+	vdev->config->del_vqs(vdev);
+	scmi_vdev = NULL;
+}
+
+static int scmi_vio_validate(struct virtio_device *vdev)
+{
+	if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+		dev_err(&vdev->dev,
+			"device does not comply with spec version 1.x\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned int features[] = {
+	VIRTIO_SCMI_F_P2A_CHANNELS,
+};
+
+static const struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_SCMI, VIRTIO_DEV_ANY_ID },
+	{ 0 }
+};
+
+static struct virtio_driver virtio_scmi_driver = {
+	.driver.name = "scmi-virtio",
+	.driver.owner = THIS_MODULE,
+	.feature_table = features,
+	.feature_table_size = ARRAY_SIZE(features),
+	.id_table = id_table,
+	.probe = scmi_vio_probe,
+	.remove = scmi_vio_remove,
+	.validate = scmi_vio_validate,
+};
+
+static int __init virtio_scmi_init(void)
+{
+	return register_virtio_driver(&virtio_scmi_driver);
+}
+
+static void __exit virtio_scmi_exit(void)
+{
+	unregister_virtio_driver(&virtio_scmi_driver);
+}
+
+const struct scmi_desc scmi_virtio_desc = {
+	.transport_init = virtio_scmi_init,
+	.transport_exit = virtio_scmi_exit,
+	.ops = &scmi_virtio_ops,
+	.max_rx_timeout_ms = 60000, /* for non-realtime virtio devices */
+	.max_msg = 0, /* overridden by virtio_get_max_msg() */
+	.max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
+};
diff --git a/include/uapi/linux/virtio_ids.h b/include/uapi/linux/virtio_ids.h
index 70a8057ad4bb..f74155f6882d 100644
--- a/include/uapi/linux/virtio_ids.h
+++ b/include/uapi/linux/virtio_ids.h
@@ -55,6 +55,7 @@
 #define VIRTIO_ID_FS			26 /* virtio filesystem */
 #define VIRTIO_ID_PMEM			27 /* virtio pmem */
 #define VIRTIO_ID_MAC80211_HWSIM	29 /* virtio mac80211-hwsim */
+#define VIRTIO_ID_SCMI			32 /* virtio SCMI */
 #define VIRTIO_ID_BT			40 /* virtio bluetooth */
 
 /*
diff --git a/include/uapi/linux/virtio_scmi.h b/include/uapi/linux/virtio_scmi.h
new file mode 100644
index 000000000000..f8ddd04a3ace
--- /dev/null
+++ b/include/uapi/linux/virtio_scmi.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+/*
+ * Copyright (C) 2020-2021 OpenSynergy GmbH
+ * Copyright (C) 2021 ARM Ltd.
+ */
+
+#ifndef _UAPI_LINUX_VIRTIO_SCMI_H
+#define _UAPI_LINUX_VIRTIO_SCMI_H
+
+#include <linux/virtio_types.h>
+
+/* Device implements some SCMI notifications, or delayed responses. */
+#define VIRTIO_SCMI_F_P2A_CHANNELS 0
+
+/* Device implements any SCMI statistics shared memory region */
+#define VIRTIO_SCMI_F_SHARED_MEMORY 1
+
+/* Virtqueues */
+
+#define VIRTIO_SCMI_VQ_TX 0 /* cmdq */
+#define VIRTIO_SCMI_VQ_RX 1 /* eventq */
+#define VIRTIO_SCMI_VQ_MAX_CNT 2
+
+#endif /* _UAPI_LINUX_VIRTIO_SCMI_H */
-- 
2.17.1



From catalin.marinas at arm.com  Tue Aug  3 06:12:02 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 3 Aug 2021 14:12:02 +0100
Subject: [PATCH] arm64/mm: Fix idmap on [16K|36VA|48PA]
In-Reply-To: <7bad50a2-76f1-7946-3a15-35e46fb289c0@arm.com>
References: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com>
 <20210803103440.GA5786@arm.com>
 <7bad50a2-76f1-7946-3a15-35e46fb289c0@arm.com>
Message-ID: <20210803131201.GB5786@arm.com>

On Tue, Aug 03, 2021 at 04:57:04PM +0530, Anshuman Khandual wrote:
> On 8/3/21 4:04 PM, Catalin Marinas wrote:
> > On Mon, Aug 02, 2021 at 10:12:39AM +0530, Anshuman Khandual wrote:
> >> +/*
> >> + * In this particular CONFIG_ARM64_16K_PAGES config, there might be a
> >> + * scenario where 'idmap_text_end' ends up high enough in the PA range
> >> + * requiring two additional idmap page table levels. Reduce idmap_t0sz
> >> + * to cover the entire PA range. This prevents table misconfiguration
> >> + * when a given idmap_t0sz value just requires single additional level
> >> + * where as two levels have been built.
> >> + */
> >> +#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_PA_BITS_48)

I don't think you need the PA_BITS_48 check in here. It's either this
one or PA_BITS_52 in the future. Anyway, I think so far our assumption
is that the kernel will always be placed in the first 48-bit, so we
don't need extra check.

> >> +	mov	x4, EXTRA_PTRS_1
> >> +	create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6
> >> +
> >> +	mov	x4, PTRS_PER_PTE
> >> +	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
> >> +
> >> +	mov	x5, #64 - PHYS_MASK_SHIFT
> >> +	adr_l	x6, idmap_t0sz
> >> +	str	x5, [x6]
> >> +	dmb	sy
> >> +	dc	ivac, x6
> >> +#else
> >>  	mov	x4, EXTRA_PTRS
> >>  	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
> >> +#endif
> >>  #else
> >>  	/*
> >>  	 * If VA_BITS == 48, we don't have to configure an additional
> > 
> > There's a prior idmap_t0sz setting based on __idmap_text_end. Isn't that
> > sufficient? We don't care about covering the whole PA space, just the
> > __idmap_text_end.
> 
> Right but its bit tricky here.
> 
> __idmap_text_end could be any where between VA_BITS (36) and PA_BITS (48)
> which would require (one or two) additional page table levels. But in this
> solution it creates two additional page table levels for idmap which would
> completely map upto PA_BITS, regardless of __idmap_text_end's position. So
> in case __idmap_text_end is between VA_BITS (36) and VA_BITS(47), a single
> additional page table level is required where as we have created two ! So
> to avoid such a situation, adjust idmap_t0sz accordingly. Otherwise there
> will be a MMU mis-configuration.

I get it now. You need 4 levels with 16K pages for idmap as 3 levels
(one extra in head.S) are not sufficient. The normal page table uses 2
levels with 36-bit VA. Here you chose to go with 4 levels always as the
simplest option.

Do we need to adjust idmap_ptrs_per_pgd? I think even without your
patch, its value is wrong as it doesn't seem to be adjusted for the
extra level. I can't figure out whether it matter but I think we should
remove this variable altogether and just set the x4 register to what we
need in head.S

> This patch is indented for stable back port and hence tries to be as simple
> and minimal as possible. So it creates two additional page table levels
> mapping upto PA_BITS without just considering __idmap_text_end's position.
> Reducing __idmap_t0sz upto PA_BITS should not be a problem irrespective of
> ID_AA64MMFR0_EL1.PARANGE value. As __idmap_text_end would never be on a PA
> which is not supported. Hence out of range PA would never be on the bus for
> translation.

I'd rather have a clean solution (might as well be this one) than
worrying about a stable back-port. It's highly unlikely that we'll trip
over this problem in practice: first you'd need RAM above 47-bit and
second you'd have to enable EXPERT and 36-bit VA.

It looks like idmap_t0sz is used by the kvm_mmu_init() code to calculate
hyp_va_bits. Does it mean that idmap_t0sz should always match PA_SIZE?
Or maybe we should just decouple the two.

-- 
Catalin


From john.ogness at linutronix.de  Tue Aug  3 06:13:01 2021
From: john.ogness at linutronix.de (John Ogness)
Date: Tue,  3 Aug 2021 15:19:01 +0206
Subject: [PATCH printk v1 10/10] serial: 8250: implement write_atomic
In-Reply-To: <20210803131301.5588-1-john.ogness@linutronix.de>
References: <20210803131301.5588-1-john.ogness@linutronix.de>
Message-ID: <20210803131301.5588-11-john.ogness@linutronix.de>

Implement an NMI-safe write_atomic() console function in order to
support synchronous console printing.

Since interrupts need to be disabled during transmit, all usage of
the IER register is wrapped with access functions that use the
printk cpulock to synchronize register access while tracking the
state of the interrupts. This is necessary because write_atomic()
can be called from an NMI context that has preempted write_atomic().

Signed-off-by: John Ogness <john.ogness at linutronix.de>
---
 drivers/tty/serial/8250/8250.h         | 47 ++++++++++++-
 drivers/tty/serial/8250/8250_core.c    | 17 +++--
 drivers/tty/serial/8250/8250_fsl.c     |  9 +++
 drivers/tty/serial/8250/8250_ingenic.c |  7 ++
 drivers/tty/serial/8250/8250_mtk.c     | 29 +++++++-
 drivers/tty/serial/8250/8250_port.c    | 92 ++++++++++++++++----------
 drivers/tty/serial/8250/Kconfig        |  1 +
 include/linux/serial_8250.h            |  5 ++
 8 files changed, 163 insertions(+), 44 deletions(-)

diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 6473361525d1..9e8785ab9886 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -132,12 +132,55 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value)
 	up->dl_write(up, value);
 }
 
+static inline void serial8250_set_IER(struct uart_8250_port *up,
+				      unsigned char ier)
+{
+	struct uart_port *port = &up->port;
+	unsigned long flags;
+	bool is_console;
+
+	is_console = uart_console(port);
+
+	if (is_console)
+		console_atomic_cpu_lock(flags);
+
+	serial_out(up, UART_IER, ier);
+
+	if (is_console)
+		console_atomic_cpu_unlock(flags);
+}
+
+static inline unsigned char serial8250_clear_IER(struct uart_8250_port *up)
+{
+	struct uart_port *port = &up->port;
+	unsigned int clearval = 0;
+	unsigned long flags;
+	unsigned int prior;
+	bool is_console;
+
+	is_console = uart_console(port);
+
+	if (up->capabilities & UART_CAP_UUE)
+		clearval = UART_IER_UUE;
+
+	if (is_console)
+		console_atomic_cpu_lock(flags);
+
+	prior = serial_port_in(port, UART_IER);
+	serial_port_out(port, UART_IER, clearval);
+
+	if (is_console)
+		console_atomic_cpu_unlock(flags);
+
+	return prior;
+}
+
 static inline bool serial8250_set_THRI(struct uart_8250_port *up)
 {
 	if (up->ier & UART_IER_THRI)
 		return false;
 	up->ier |= UART_IER_THRI;
-	serial_out(up, UART_IER, up->ier);
+	serial8250_set_IER(up, up->ier);
 	return true;
 }
 
@@ -146,7 +189,7 @@ static inline bool serial8250_clear_THRI(struct uart_8250_port *up)
 	if (!(up->ier & UART_IER_THRI))
 		return false;
 	up->ier &= ~UART_IER_THRI;
-	serial_out(up, UART_IER, up->ier);
+	serial8250_set_IER(up, up->ier);
 	return true;
 }
 
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 1ce193daea7f..fad00c0414e3 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -264,10 +264,8 @@ static void serial8250_backup_timeout(struct timer_list *t)
 	 * Must disable interrupts or else we risk racing with the interrupt
 	 * based handler.
 	 */
-	if (up->port.irq) {
-		ier = serial_in(up, UART_IER);
-		serial_out(up, UART_IER, 0);
-	}
+	if (up->port.irq)
+		ier = serial8250_clear_IER(up);
 
 	iir = serial_in(up, UART_IIR);
 
@@ -290,7 +288,7 @@ static void serial8250_backup_timeout(struct timer_list *t)
 		serial8250_tx_chars(up);
 
 	if (up->port.irq)
-		serial_out(up, UART_IER, ier);
+		serial8250_set_IER(up, ier);
 
 	spin_unlock_irqrestore(&up->port.lock, flags);
 
@@ -568,6 +566,14 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev)
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
 
+static void univ8250_console_write_atomic(struct console *co, const char *s,
+					  unsigned int count)
+{
+	struct uart_8250_port *up = &serial8250_ports[co->index];
+
+	serial8250_console_write_atomic(up, s, count);
+}
+
 static void univ8250_console_write(struct console *co, const char *s,
 				   unsigned int count)
 {
@@ -661,6 +667,7 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 
 static struct console univ8250_console = {
 	.name		= "ttyS",
+	.write_atomic	= univ8250_console_write_atomic,
 	.write		= univ8250_console_write,
 	.device		= uart_console_device,
 	.setup		= univ8250_console_setup,
diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c
index 4e75d2e4f87c..00e0f8f6607b 100644
--- a/drivers/tty/serial/8250/8250_fsl.c
+++ b/drivers/tty/serial/8250/8250_fsl.c
@@ -59,9 +59,18 @@ int fsl8250_handle_irq(struct uart_port *port)
 
 	/* Stop processing interrupts on input overrun */
 	if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) {
+		unsigned long flags;
 		unsigned long delay;
+		bool is_console;
 
+		is_console = uart_console(port);
+
+		if (is_console)
+			console_atomic_cpu_lock(flags);
 		up->ier = port->serial_in(port, UART_IER);
+		if (is_console)
+			console_atomic_cpu_unlock(flags);
+
 		if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
 			port->ops->stop_rx(port);
 		} else {
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
index 988bf6bcce42..ff0e1d84ec7e 100644
--- a/drivers/tty/serial/8250/8250_ingenic.c
+++ b/drivers/tty/serial/8250/8250_ingenic.c
@@ -146,6 +146,8 @@ OF_EARLYCON_DECLARE(x1000_uart, "ingenic,x1000-uart",
 
 static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
 {
+	unsigned long flags;
+	bool is_console;
 	int ier;
 
 	switch (offset) {
@@ -167,7 +169,12 @@ static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
 		 * If we have enabled modem status IRQs we should enable
 		 * modem mode.
 		 */
+		is_console = uart_console(p);
+		if (is_console)
+			console_atomic_cpu_lock(flags);
 		ier = p->serial_in(p, UART_IER);
+		if (is_console)
+			console_atomic_cpu_unlock(flags);
 
 		if (ier & UART_IER_MSI)
 			value |= UART_MCR_MDCE | UART_MCR_FCM;
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
index f7d3023f860f..f26140ebd67a 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -213,12 +213,37 @@ static void mtk8250_shutdown(struct uart_port *port)
 
 static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask)
 {
-	serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask));
+	struct uart_port *port = &up->port;
+	unsigned long flags;
+	unsigned int ier;
+	bool is_console;
+
+	is_console = uart_console(port);
+
+	if (is_console)
+		console_atomic_cpu_lock(flags);
+
+	ier = serial_in(up, UART_IER);
+	serial_out(up, UART_IER, ier & (~mask));
+
+	if (is_console)
+		console_atomic_cpu_unlock(flags);
 }
 
 static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask)
 {
-	serial_out(up, UART_IER, serial_in(up, UART_IER) | mask);
+	struct uart_port *port = &up->port;
+	unsigned long flags;
+	unsigned int ier;
+
+	if (uart_console(port))
+		console_atomic_cpu_lock(flags);
+
+	ier = serial_in(up, UART_IER);
+	serial_out(up, UART_IER, ier | mask);
+
+	if (uart_console(port))
+		console_atomic_cpu_unlock(flags);
 }
 
 static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 2164290cbd31..2c2a5abc1baf 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -757,7 +757,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
 			serial_out(p, UART_EFR, UART_EFR_ECB);
 			serial_out(p, UART_LCR, 0);
 		}
-		serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
+		serial8250_set_IER(p, sleep ? UART_IERX_SLEEP : 0);
 		if (p->capabilities & UART_CAP_EFR) {
 			serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
 			serial_out(p, UART_EFR, efr);
@@ -1429,7 +1429,7 @@ static void serial8250_stop_rx(struct uart_port *port)
 
 	up->ier &= ~(UART_IER_RLSI | UART_IER_RDI);
 	up->port.read_status_mask &= ~UART_LSR_DR;
-	serial_port_out(port, UART_IER, up->ier);
+	serial8250_set_IER(up, up->ier);
 
 	serial8250_rpm_put(up);
 }
@@ -1459,7 +1459,7 @@ void serial8250_em485_stop_tx(struct uart_8250_port *p)
 		serial8250_clear_and_reinit_fifos(p);
 
 		p->ier |= UART_IER_RLSI | UART_IER_RDI;
-		serial_port_out(&p->port, UART_IER, p->ier);
+		serial8250_set_IER(p, p->ier);
 	}
 }
 EXPORT_SYMBOL_GPL(serial8250_em485_stop_tx);
@@ -1681,7 +1681,7 @@ static void serial8250_disable_ms(struct uart_port *port)
 	mctrl_gpio_disable_ms(up->gpios);
 
 	up->ier &= ~UART_IER_MSI;
-	serial_port_out(port, UART_IER, up->ier);
+	serial8250_set_IER(up, up->ier);
 }
 
 static void serial8250_enable_ms(struct uart_port *port)
@@ -1697,7 +1697,7 @@ static void serial8250_enable_ms(struct uart_port *port)
 	up->ier |= UART_IER_MSI;
 
 	serial8250_rpm_get(up);
-	serial_port_out(port, UART_IER, up->ier);
+	serial8250_set_IER(up, up->ier);
 	serial8250_rpm_put(up);
 }
 
@@ -2124,14 +2124,7 @@ static void serial8250_put_poll_char(struct uart_port *port,
 	struct uart_8250_port *up = up_to_u8250p(port);
 
 	serial8250_rpm_get(up);
-	/*
-	 *	First save the IER then disable the interrupts
-	 */
-	ier = serial_port_in(port, UART_IER);
-	if (up->capabilities & UART_CAP_UUE)
-		serial_port_out(port, UART_IER, UART_IER_UUE);
-	else
-		serial_port_out(port, UART_IER, 0);
+	ier = serial8250_clear_IER(up);
 
 	wait_for_xmitr(up, BOTH_EMPTY);
 	/*
@@ -2144,7 +2137,7 @@ static void serial8250_put_poll_char(struct uart_port *port,
 	 *	and restore the IER
 	 */
 	wait_for_xmitr(up, BOTH_EMPTY);
-	serial_port_out(port, UART_IER, ier);
+	serial8250_set_IER(up, ier);
 	serial8250_rpm_put(up);
 }
 
@@ -2447,7 +2440,7 @@ void serial8250_do_shutdown(struct uart_port *port)
 	 */
 	spin_lock_irqsave(&port->lock, flags);
 	up->ier = 0;
-	serial_port_out(port, UART_IER, 0);
+	serial8250_set_IER(up, 0);
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	synchronize_irq(port->irq);
@@ -2816,7 +2809,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 	if (up->capabilities & UART_CAP_RTOIE)
 		up->ier |= UART_IER_RTOIE;
 
-	serial_port_out(port, UART_IER, up->ier);
+	serial8250_set_IER(up, up->ier);
 
 	if (up->capabilities & UART_CAP_EFR) {
 		unsigned char efr = 0;
@@ -3282,7 +3275,7 @@ EXPORT_SYMBOL_GPL(serial8250_set_defaults);
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
 
-static void serial8250_console_putchar(struct uart_port *port, int ch)
+static void serial8250_console_putchar_locked(struct uart_port *port, int ch)
 {
 	struct uart_8250_port *up = up_to_u8250p(port);
 
@@ -3290,6 +3283,18 @@ static void serial8250_console_putchar(struct uart_port *port, int ch)
 	serial_port_out(port, UART_TX, ch);
 }
 
+static void serial8250_console_putchar(struct uart_port *port, int ch)
+{
+	struct uart_8250_port *up = up_to_u8250p(port);
+	unsigned long flags;
+
+	wait_for_xmitr(up, UART_LSR_THRE);
+
+	console_atomic_cpu_lock(flags);
+	serial8250_console_putchar_locked(port, ch);
+	console_atomic_cpu_unlock(flags);
+}
+
 /*
  *	Restore serial console when h/w power-off detected
  */
@@ -3311,6 +3316,32 @@ static void serial8250_console_restore(struct uart_8250_port *up)
 	serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
 }
 
+void serial8250_console_write_atomic(struct uart_8250_port *up,
+				     const char *s, unsigned int count)
+{
+	struct uart_port *port = &up->port;
+	unsigned long flags;
+	unsigned int ier;
+
+	console_atomic_cpu_lock(flags);
+
+	touch_nmi_watchdog();
+
+	ier = serial8250_clear_IER(up);
+
+	if (atomic_fetch_inc(&up->console_printing)) {
+		uart_console_write(port, "\n", 1,
+				   serial8250_console_putchar_locked);
+	}
+	uart_console_write(port, s, count, serial8250_console_putchar_locked);
+	atomic_dec(&up->console_printing);
+
+	wait_for_xmitr(up, BOTH_EMPTY);
+	serial8250_set_IER(up, ier);
+
+	console_atomic_cpu_unlock(flags);
+}
+
 /*
  *	Print a string to the serial port trying not to disturb
  *	any possible real use of the port...
@@ -3327,24 +3358,12 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
 	struct uart_port *port = &up->port;
 	unsigned long flags;
 	unsigned int ier;
-	int locked = 1;
 
 	touch_nmi_watchdog();
 
-	if (oops_in_progress)
-		locked = spin_trylock_irqsave(&port->lock, flags);
-	else
-		spin_lock_irqsave(&port->lock, flags);
-
-	/*
-	 *	First save the IER then disable the interrupts
-	 */
-	ier = serial_port_in(port, UART_IER);
+	spin_lock_irqsave(&port->lock, flags);
 
-	if (up->capabilities & UART_CAP_UUE)
-		serial_port_out(port, UART_IER, UART_IER_UUE);
-	else
-		serial_port_out(port, UART_IER, 0);
+	ier = serial8250_clear_IER(up);
 
 	/* check scratch reg to see if port powered off during system sleep */
 	if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) {
@@ -3358,7 +3377,9 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
 		mdelay(port->rs485.delay_rts_before_send);
 	}
 
+	atomic_inc(&up->console_printing);
 	uart_console_write(port, s, count, serial8250_console_putchar);
+	atomic_dec(&up->console_printing);
 
 	/*
 	 *	Finally, wait for transmitter to become empty
@@ -3371,8 +3392,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
 		if (em485->tx_stopped)
 			up->rs485_stop_tx(up);
 	}
-
-	serial_port_out(port, UART_IER, ier);
+	serial8250_set_IER(up, ier);
 
 	/*
 	 *	The receive handling will happen properly because the
@@ -3384,8 +3404,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
 	if (up->msr_saved_flags)
 		serial8250_modem_status(up);
 
-	if (locked)
-		spin_unlock_irqrestore(&port->lock, flags);
+	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static unsigned int probe_baud(struct uart_port *port)
@@ -3405,6 +3424,7 @@ static unsigned int probe_baud(struct uart_port *port)
 
 int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
 {
+	struct uart_8250_port *up = up_to_u8250p(port);
 	int baud = 9600;
 	int bits = 8;
 	int parity = 'n';
@@ -3414,6 +3434,8 @@ int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
 	if (!port->iobase && !port->membase)
 		return -ENODEV;
 
+	atomic_set(&up->console_printing, 0);
+
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 	else if (probe)
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index d1b3c2373fa4..1671d2882ba7 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -9,6 +9,7 @@ config SERIAL_8250
 	depends on !S390
 	select SERIAL_CORE
 	select SERIAL_MCTRL_GPIO if GPIOLIB
+	select HAVE_ATOMIC_CONSOLE
 	help
 	  This selects whether you want to include the driver for the standard
 	  serial ports.  The standard answer is Y.  People who might say N
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 5db211f43b29..aa011f668705 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -7,6 +7,7 @@
 #ifndef _LINUX_SERIAL_8250_H
 #define _LINUX_SERIAL_8250_H
 
+#include <linux/atomic.h>
 #include <linux/serial_core.h>
 #include <linux/serial_reg.h>
 #include <linux/platform_device.h>
@@ -125,6 +126,8 @@ struct uart_8250_port {
 #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
 	unsigned char		msr_saved_flags;
 
+	atomic_t		console_printing;
+
 	struct uart_8250_dma	*dma;
 	const struct uart_8250_ops *ops;
 
@@ -180,6 +183,8 @@ void serial8250_init_port(struct uart_8250_port *up);
 void serial8250_set_defaults(struct uart_8250_port *up);
 void serial8250_console_write(struct uart_8250_port *up, const char *s,
 			      unsigned int count);
+void serial8250_console_write_atomic(struct uart_8250_port *up, const char *s,
+				     unsigned int count);
 int serial8250_console_setup(struct uart_port *port, char *options, bool probe);
 int serial8250_console_exit(struct uart_port *port);
 
-- 
2.20.1



From acme at kernel.org  Tue Aug  3 06:24:09 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Tue, 3 Aug 2021 10:24:09 -0300
Subject: [RFC PATCH 6/6] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <20210802154145.GC148327@leoy-ThinkPad-X240s>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-7-james.clark@arm.com>
 <20210802154145.GC148327@leoy-ThinkPad-X240s>
Message-ID: <YQlDefz+g45dqFsP@kernel.org>

Em Mon, Aug 02, 2021 at 11:41:45PM +0800, Leo Yan escreveu:
> On Thu, Jul 29, 2021 at 04:58:05PM +0100, James Clark wrote:
> > Currently decode will silently fail if no binary data is available for
> > the decode. This is made worse if only partial data is available because
> > the decode will appear to work, but any trace from that missing DSO will
> > silently not be generated.
> > 
> > Add a UI popup once if there is any data missing, and then warn in the
> > bottom left for each individual DSO that's missing.
> > 
> > Signed-off-by: James Clark <james.clark at arm.com>
> > ---
> >  tools/perf/util/cs-etm.c | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> > index 32ad92d3e454..e6851260d059 100644
> > --- a/tools/perf/util/cs-etm.c
> > +++ b/tools/perf/util/cs-etm.c
> > @@ -746,8 +746,16 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
> >  
> >  	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
> >  
> > -	if (len <= 0)
> > +	if (len <= 0) {
> > +		ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n");
> > +		if (!al.map->dso->auxtrace_warned) {
> > +			pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
> > +				    address,
> > +				    al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
> > +			al.map->dso->auxtrace_warned = true;
> > +		}
> 
> This is very useful.
> 
> Just one comment: in particularly if the perf fails to find the kernel
> symbols, the user needs to enable config "CONFIG_PROC_KCORE=y" or
> specify option "-k /path/to/vmlinux".  In this case, using 'perf
> archive' is not helpful.  So I think the UI warning can be imporved
> like:
> 
>         ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n"
>                          " Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols\n");

one can also use debuginfod-client, which, as time passes, probably will
be the main way of finding DSOs now that we have build-ids in
PERF_RECORD_MMAP2 and debuginfod servers such as:

export DEBUGINFOD_URLS=https://debuginfod.fedoraproject.org/

https://fedoraproject.org/wiki/Debuginfod
 
> With this improvement, the patch looks good to me:
> 
> Reviewed-by: Leo Yan <leo.yan at linaro.org>

Does this apply to the other 5 patches in this series?

- Arnaldo
 
> >  		return 0;
> > +	}
> >  
> >  	return len;
> >  }
> > -- 
> > 2.28.0
> > 

-- 

- Arnaldo


From acme at kernel.org  Tue Aug  3 06:25:39 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Tue, 3 Aug 2021 10:25:39 -0300
Subject: [RFC PATCH 5/6] perf cs-etm: Improve Coresight zero timestamp
 warning
In-Reply-To: <20210802151710.GB148327@leoy-ThinkPad-X240s>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-6-james.clark@arm.com>
 <20210802151710.GB148327@leoy-ThinkPad-X240s>
Message-ID: <YQlD06FZ3SyBeolc@kernel.org>

Em Mon, Aug 02, 2021 at 11:17:10PM +0800, Leo Yan escreveu:
> On Thu, Jul 29, 2021 at 04:58:04PM +0100, James Clark wrote:
> > Only show the warning if the user hasn't already set timeless mode and
> > improve the text because there was ambiguity around the meaning of '...'
> > 
> > Change the warning to a UI warning instead of printing straight to
> > stderr because this corrupts the UI when perf report TUI is used. The UI
> > warning function also handles printing to stderr when in perf script
> > mode.
> > 
> > Suggested-by: Leo Yan <leo.yan at linaro.org>
> > Signed-off-by: James Clark <james.clark at arm.com>
> 
> Reviewed-by: Leo Yan <leo.yan at linaro.org>

Thanks, applied.

- Arnaldo

 
> > ---
> >  tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 7 +++++--
> >  1 file changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> > index 3e1a05bc82cc..5084bd2ca6eb 100644
> > --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> > +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> > @@ -324,8 +324,11 @@ cs_etm_decoder__do_hard_timestamp(struct cs_etm_queue *etmq,
> >  		 * underflow.
> >  		 */
> >  		packet_queue->cs_timestamp = 0;
> > -		WARN_ONCE(true, "Zero Coresight timestamp found at Idx:%" OCSD_TRC_IDX_STR
> > -				". Decoding may be improved with --itrace=Z...\n", indx);
> > +		if (!cs_etm__etmq_is_timeless(etmq))
> > +			pr_warning_once("Zero Coresight timestamp found at Idx:%" OCSD_TRC_IDX_STR
> > +					". Decoding may be improved by prepending 'Z' to your current --itrace arguments.\n",
> > +					indx);
> > +
> >  	} else if (packet_queue->instr_count > elem->timestamp) {
> >  		/*
> >  		 * Sanity check that the elem->timestamp - packet_queue->instr_count would not
> > -- 
> > 2.28.0
> > 

-- 

- Arnaldo


From robh at kernel.org  Tue Aug  3 06:59:32 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 03 Aug 2021 07:59:32 -0600
Subject: [PATCH v3 3/3] dt-bindings: mediatek: convert pinctrl to yaml
In-Reply-To: <20210803051318.2570994-3-hsinyi@chromium.org>
References: <20210803051318.2570994-1-hsinyi@chromium.org>
 <20210803051318.2570994-3-hsinyi@chromium.org>
Message-ID: <1627999172.502726.3179055.nullmailer@robh.at.kernel.org>

On Tue, 03 Aug 2021 13:13:19 +0800, Hsin-Yi Wang wrote:
> Convert mt65xx, mt6796, mt7622, mt8183 bindings to yaml.
> 
> Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
> ---
> v2->v3:
> fix comments in v2.
> ---
>  .../pinctrl/mediatek,mt65xx-pinctrl.yaml      | 206 ++++++++
>  .../pinctrl/mediatek,mt6797-pinctrl.yaml      | 173 +++++++
>  .../pinctrl/mediatek,mt7622-pinctrl.yaml      | 373 +++++++++++++
>  .../pinctrl/mediatek,mt8183-pinctrl.yaml      | 228 ++++++++
>  .../bindings/pinctrl/pinctrl-mt65xx.txt       | 156 ------
>  .../bindings/pinctrl/pinctrl-mt6797.txt       |  83 ---
>  .../bindings/pinctrl/pinctrl-mt7622.txt       | 490 ------------------
>  .../bindings/pinctrl/pinctrl-mt8183.txt       | 132 -----
>  8 files changed, 980 insertions(+), 861 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.example.dts:21:18: fatal error: dt-bindings/pinctrl/mt8183-pinfunc.h: No such file or directory
   21 |         #include <dt-bindings/pinctrl/mt8183-pinfunc.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1419: dt_binding_check] Error 2
\ndoc reference errors (make refcheckdocs):
MAINTAINERS: Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
MAINTAINERS: Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt

See https://patchwork.ozlabs.org/patch/1512734

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From leo.yan at linaro.org  Tue Aug  3 07:01:22 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 3 Aug 2021 22:01:22 +0800
Subject: [RFC PATCH 6/6] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <YQlDefz+g45dqFsP@kernel.org>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-7-james.clark@arm.com>
 <20210802154145.GC148327@leoy-ThinkPad-X240s>
 <YQlDefz+g45dqFsP@kernel.org>
Message-ID: <20210803140122.GC247709@leoy-ThinkPad-X240s>

On Tue, Aug 03, 2021 at 10:24:09AM -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Aug 02, 2021 at 11:41:45PM +0800, Leo Yan escreveu:
> > On Thu, Jul 29, 2021 at 04:58:05PM +0100, James Clark wrote:
> > > Currently decode will silently fail if no binary data is available for
> > > the decode. This is made worse if only partial data is available because
> > > the decode will appear to work, but any trace from that missing DSO will
> > > silently not be generated.
> > > 
> > > Add a UI popup once if there is any data missing, and then warn in the
> > > bottom left for each individual DSO that's missing.
> > > 
> > > Signed-off-by: James Clark <james.clark at arm.com>
> > > ---
> > >  tools/perf/util/cs-etm.c | 10 +++++++++-
> > >  1 file changed, 9 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> > > index 32ad92d3e454..e6851260d059 100644
> > > --- a/tools/perf/util/cs-etm.c
> > > +++ b/tools/perf/util/cs-etm.c
> > > @@ -746,8 +746,16 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
> > >  
> > >  	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
> > >  
> > > -	if (len <= 0)
> > > +	if (len <= 0) {
> > > +		ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n");
> > > +		if (!al.map->dso->auxtrace_warned) {
> > > +			pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
> > > +				    address,
> > > +				    al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
> > > +			al.map->dso->auxtrace_warned = true;
> > > +		}
> > 
> > This is very useful.
> > 
> > Just one comment: in particularly if the perf fails to find the kernel
> > symbols, the user needs to enable config "CONFIG_PROC_KCORE=y" or
> > specify option "-k /path/to/vmlinux".  In this case, using 'perf
> > archive' is not helpful.  So I think the UI warning can be imporved
> > like:
> > 
> >         ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' to export data from the traced system.\n"
> >                          " Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols\n");
> 
> one can also use debuginfod-client, which, as time passes, probably will
> be the main way of finding DSOs now that we have build-ids in
> PERF_RECORD_MMAP2 and debuginfod servers such as:
> 
> export DEBUGINFOD_URLS=https://debuginfod.fedoraproject.org/

If so, maybe should use more general description for missing DSO.

> https://fedoraproject.org/wiki/Debuginfod
>  
> > With this improvement, the patch looks good to me:
> > 
> > Reviewed-by: Leo Yan <leo.yan at linaro.org>
> 
> Does this apply to the other 5 patches in this series?

I finished to reivew patches 01, 04, 05, 06/06, so my review tag can
apply on these patches.  Current patch 06/06 needs James to improve for
the comments.

Thanks,
Leo


From eballetbo at gmail.com  Tue Aug  3 07:05:53 2021
From: eballetbo at gmail.com (Enric Balletbo Serra)
Date: Tue, 3 Aug 2021 16:05:53 +0200
Subject: [PATCH v8,
 2/2] soc: mediatek: mmsys: Add mt8192 mmsys routing table
In-Reply-To: <1627894773-23872-3-git-send-email-yongqiang.niu@mediatek.com>
References: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
 <1627894773-23872-3-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <CAFqH_50eD=KihDrE3Vi0w+qEh6USF-sZTD+ZBjUeCiwXz4HD8Q@mail.gmail.com>

Hi Yongqiang,

Thank you for your patch

Missatge de Yongqiang Niu <yongqiang.niu at mediatek.com> del dia dl., 2
d?ag. 2021 a les 11:00:
>
> mt8192 has different routing registers than mt8183
>

... than mt8183 and other Mediatek SoC's I guess ;-)

> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>

Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>

Thanks,
   Enric


> ---
>  drivers/soc/mediatek/mt8192-mmsys.h | 67 +++++++++++++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c    | 11 ++++++
>  2 files changed, 78 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mt8192-mmsys.h
>
> diff --git a/drivers/soc/mediatek/mt8192-mmsys.h b/drivers/soc/mediatek/mt8192-mmsys.h
> new file mode 100644
> index 0000000..0e4b233
> --- /dev/null
> +++ b/drivers/soc/mediatek/mt8192-mmsys.h
> @@ -0,0 +1,67 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __SOC_MEDIATEK_MT8192_MMSYS_H
> +#define __SOC_MEDIATEK_MT8192_MMSYS_H
> +
> +#define MT8192_MMSYS_OVL_MOUT_EN               0xf04
> +#define MT8192_DISP_OVL1_2L_MOUT_EN            0xf08
> +#define MT8192_DISP_OVL0_2L_MOUT_EN            0xf18
> +#define MT8192_DISP_OVL0_MOUT_EN               0xf1c
> +#define MT8192_DISP_RDMA0_SEL_IN               0xf2c
> +#define MT8192_DISP_RDMA0_SOUT_SEL             0xf30
> +#define MT8192_DISP_CCORR0_SOUT_SEL            0xf34
> +#define MT8192_DISP_AAL0_SEL_IN                        0xf38
> +#define MT8192_DISP_DITHER0_MOUT_EN            0xf3c
> +#define MT8192_DISP_DSI0_SEL_IN                        0xf40
> +#define MT8192_DISP_OVL2_2L_MOUT_EN            0xf4c
> +
> +#define MT8192_DISP_OVL0_GO_BLEND                      BIT(0)
> +#define MT8192_DITHER0_MOUT_IN_DSI0                    BIT(0)
> +#define MT8192_OVL0_MOUT_EN_DISP_RDMA0                 BIT(0)
> +#define MT8192_OVL2_2L_MOUT_EN_RDMA4                   BIT(0)
> +#define MT8192_DISP_OVL0_GO_BG                         BIT(1)
> +#define MT8192_DISP_OVL0_2L_GO_BLEND                   BIT(2)
> +#define MT8192_DISP_OVL0_2L_GO_BG                      BIT(3)
> +#define MT8192_OVL1_2L_MOUT_EN_RDMA1                   BIT(4)
> +#define MT8192_OVL0_MOUT_EN_OVL0_2L                    BIT(4)
> +#define MT8192_RDMA0_SEL_IN_OVL0_2L                    0x3
> +#define MT8192_RDMA0_SOUT_COLOR0                       0x1
> +#define MT8192_CCORR0_SOUT_AAL0                                0x1
> +#define MT8192_AAL0_SEL_IN_CCORR0                      0x1
> +#define MT8192_DSI0_SEL_IN_DITHER0                     0x1
> +
> +static const struct mtk_mmsys_routes mmsys_mt8192_routing_table[] = {
> +       {
> +               DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
> +               MT8192_DISP_OVL0_2L_MOUT_EN, MT8192_OVL0_MOUT_EN_DISP_RDMA0,
> +       }, {
> +               DDP_COMPONENT_OVL_2L2, DDP_COMPONENT_RDMA4,
> +               MT8192_DISP_OVL2_2L_MOUT_EN, MT8192_OVL2_2L_MOUT_EN_RDMA4
> +       }, {
> +               DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +               MT8192_DISP_DITHER0_MOUT_EN, MT8192_DITHER0_MOUT_IN_DSI0
> +       }, {
> +               DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
> +               MT8192_DISP_RDMA0_SEL_IN, MT8192_RDMA0_SEL_IN_OVL0_2L
> +       }, {
> +               DDP_COMPONENT_CCORR, DDP_COMPONENT_AAL0,
> +               MT8192_DISP_AAL0_SEL_IN, MT8192_AAL0_SEL_IN_CCORR0
> +       }, {
> +               DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +               MT8192_DISP_DSI0_SEL_IN, MT8192_DSI0_SEL_IN_DITHER0
> +       }, {
> +               DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
> +               MT8192_DISP_RDMA0_SOUT_SEL, MT8192_RDMA0_SOUT_COLOR0
> +       }, {
> +               DDP_COMPONENT_CCORR, DDP_COMPONENT_AAL0,
> +               MT8192_DISP_CCORR0_SOUT_SEL, MT8192_CCORR0_SOUT_AAL0
> +       }, {
> +               DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL_2L0,
> +               MT8192_MMSYS_OVL_MOUT_EN, MT8192_DISP_OVL0_GO_BG,
> +       }, {
> +               DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
> +               MT8192_MMSYS_OVL_MOUT_EN, MT8192_DISP_OVL0_2L_GO_BLEND,
> +       }
> +};
> +
> +#endif /* __SOC_MEDIATEK_MT8192_MMSYS_H */
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
> index 080660e..de7b122 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -13,6 +13,7 @@
>  #include "mtk-mmsys.h"
>  #include "mt8167-mmsys.h"
>  #include "mt8183-mmsys.h"
> +#include "mt8192-mmsys.h"
>
>  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
>         .clk_driver = "clk-mt2701-mm",
> @@ -52,6 +53,12 @@
>         .num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
>  };
>
> +static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
> +       .clk_driver = "clk-mt8192-mm",
> +       .routes = mmsys_mt8192_routing_table,
> +       .num_routes = ARRAY_SIZE(mmsys_mt8192_routing_table),
> +};
> +
>  struct mtk_mmsys {
>         void __iomem *regs;
>         const struct mtk_mmsys_driver_data *data;
> @@ -157,6 +164,10 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
>                 .compatible = "mediatek,mt8183-mmsys",
>                 .data = &mt8183_mmsys_driver_data,
>         },
> +       {
> +               .compatible = "mediatek,mt8192-mmsys",
> +               .data = &mt8192_mmsys_driver_data,
> +       },
>         { }
>  };
>
> --
> 1.8.1.1.dirty
>


From broonie at kernel.org  Tue Aug  3 07:04:46 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue,  3 Aug 2021 15:04:46 +0100
Subject: [PATCH v5 0/4] kselftest/arm64: Vector length configuration tests
Message-ID: <20210803140450.46624-1-broonie@kernel.org>

Currently we don't have full automated tests for the vector length
configuation ABIs offered for SVE, we have a helper binary for setting
the vector length which can be used for manual tests and we use the
prctl() interface to enumerate the vector lengths but don't actually
verify that the vector lengths enumerated were set.

This patch series provides a small helper which allows us to get the
currently configured vector length using the RDVL instruction via either
a library call or stdout of a process and then uses this to both add
verification of enumerated vector lengths to our existing tests and also
add a new test program which exercises both the prctl() and sysfs
interfaces.

In preparation for the forthcomng support for the Scalable Matrix
Extension (SME) [1] which introduces a new vector length managed via a
very similar hardware interface the helper and new test program are
parameterised with the goal of allowing reuse for SME.

[1] https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/scalable-matrix-extension-armv9-a-architecture

v5:
 - Fix a potentially uninialized variable case.
 - Clarify an error message.
 - Add TODO.
v4:
 - Fix fscanf() format string handling to properly confirm the newline.
 - Pull fclose() out of stdio read helper.
 - Change style of child monitoring loop.
v3:
 - Add BTI landing pads to the asm helper functions.
 - Clean up pipes used to talk to children.
 - Remove another unneeded include.
 - Make functions in the main executable static.
 - Match the newline when parsing vector length from the child.
 - Factor out the fscanf() and fclose() from parsing integers from file
   descriptors.
 - getauxval() returns unsigned long.
v2:
 - Tweak log message on failure in sve-probe-vls.
 - Stylistic changes in vec-syscfg.
 - Flush stdout before forking in vec-syscfg.
 - Use EXIT_FAILURE.
 - Use fdopen() to get child output.
 - Replace a bunch of UNIX API usage with stdio.
 - Add a TODO list.
 - Verify that we're root before testing writes to /proc.

Mark Brown (4):
  kselftest/arm64: Provide a helper binary and "library" for SVE RDVL
  kselftest/arm64: Validate vector lengths are set in sve-probe-vls
  kselftest/arm64: Add tests for SVE vector configuration
  kselftest/arm64: Add a TODO list for floating point tests

 tools/testing/selftests/arm64/fp/.gitignore   |   2 +
 tools/testing/selftests/arm64/fp/Makefile     |  11 +-
 tools/testing/selftests/arm64/fp/TODO         |   4 +
 tools/testing/selftests/arm64/fp/rdvl-sve.c   |  14 +
 tools/testing/selftests/arm64/fp/rdvl.S       |  10 +
 tools/testing/selftests/arm64/fp/rdvl.h       |   8 +
 .../selftests/arm64/fp/sve-probe-vls.c        |   5 +
 tools/testing/selftests/arm64/fp/vec-syscfg.c | 593 ++++++++++++++++++
 8 files changed, 644 insertions(+), 3 deletions(-)
 create mode 100644 tools/testing/selftests/arm64/fp/TODO
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sve.c
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl.S
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl.h
 create mode 100644 tools/testing/selftests/arm64/fp/vec-syscfg.c


base-commit: ff1176468d368232b684f75e82563369208bc371
-- 
2.20.1



From broonie at kernel.org  Tue Aug  3 07:04:47 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue,  3 Aug 2021 15:04:47 +0100
Subject: [PATCH v5 1/4] kselftest/arm64: Provide a helper binary and "library"
 for SVE RDVL
In-Reply-To: <20210803140450.46624-1-broonie@kernel.org>
References: <20210803140450.46624-1-broonie@kernel.org>
Message-ID: <20210803140450.46624-2-broonie@kernel.org>

SVE provides an instruction RDVL which reports the currently configured
vector length. In order to validate that our vector length configuration
interfaces are working correctly without having to build the C code for
our test programs with SVE enabled provide a trivial assembly library
with a C callable function that executes RDVL. Since these interfaces
also control behaviour on exec*() provide a trivial wrapper program which
reports the currently configured vector length on stdout, tests can use
this to verify that behaviour on exec*() is as expected.

In preparation for providing similar helper functionality for SME, the
Scalable Matrix Extension, which allows separately configured vector
lengths to be read back both the assembler function and wrapper binary
have SVE included in their name.

Signed-off-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Dave Martin <Dave.Martin at arm.com>
---
 tools/testing/selftests/arm64/fp/.gitignore |  1 +
 tools/testing/selftests/arm64/fp/Makefile   |  6 +++++-
 tools/testing/selftests/arm64/fp/rdvl-sve.c | 14 ++++++++++++++
 tools/testing/selftests/arm64/fp/rdvl.S     | 10 ++++++++++
 tools/testing/selftests/arm64/fp/rdvl.h     |  8 ++++++++
 5 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sve.c
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl.S
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl.h

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index d66f76d2a650..6b53a7b60fee 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -1,4 +1,5 @@
 fpsimd-test
+rdvl-sve
 sve-probe-vls
 sve-ptrace
 sve-test
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index a57009d3a0dc..ed62e7003b96 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -2,12 +2,16 @@
 
 CFLAGS += -I../../../../../usr/include/
 TEST_GEN_PROGS := sve-ptrace sve-probe-vls
-TEST_PROGS_EXTENDED := fpsimd-test fpsimd-stress sve-test sve-stress vlset
+TEST_PROGS_EXTENDED := fpsimd-test fpsimd-stress \
+	rdvl-sve \
+	sve-test sve-stress \
+	vlset
 
 all: $(TEST_GEN_PROGS) $(TEST_PROGS_EXTENDED)
 
 fpsimd-test: fpsimd-test.o
 	$(CC) -nostdlib $^ -o $@
+rdvl-sve: rdvl-sve.o rdvl.o
 sve-ptrace: sve-ptrace.o sve-ptrace-asm.o
 sve-probe-vls: sve-probe-vls.o
 sve-test: sve-test.o
diff --git a/tools/testing/selftests/arm64/fp/rdvl-sve.c b/tools/testing/selftests/arm64/fp/rdvl-sve.c
new file mode 100644
index 000000000000..7f8a13a18f5d
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/rdvl-sve.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <stdio.h>
+
+#include "rdvl.h"
+
+int main(void)
+{
+	int vl = rdvl_sve();
+
+	printf("%d\n", vl);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/arm64/fp/rdvl.S b/tools/testing/selftests/arm64/fp/rdvl.S
new file mode 100644
index 000000000000..c916c1c9defd
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/rdvl.S
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2021 ARM Limited.
+
+.arch_extension sve
+
+.globl rdvl_sve
+rdvl_sve:
+	hint	34			// BTI C
+	rdvl	x0, #1
+	ret
diff --git a/tools/testing/selftests/arm64/fp/rdvl.h b/tools/testing/selftests/arm64/fp/rdvl.h
new file mode 100644
index 000000000000..7c9d953fc9e7
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/rdvl.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef RDVL_H
+#define RDVL_H
+
+int rdvl_sve(void);
+
+#endif
-- 
2.20.1



From broonie at kernel.org  Tue Aug  3 07:04:48 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue,  3 Aug 2021 15:04:48 +0100
Subject: [PATCH v5 2/4] kselftest/arm64: Validate vector lengths are set in
 sve-probe-vls
In-Reply-To: <20210803140450.46624-1-broonie@kernel.org>
References: <20210803140450.46624-1-broonie@kernel.org>
Message-ID: <20210803140450.46624-3-broonie@kernel.org>

Currently sve-probe-vls does not verify that the vector lengths reported
by the prctl() interface are actually what is reported by the architecture,
use the rdvl_sve() helper to validate this.

Signed-off-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Dave Martin <Dave.Martin at arm.com>
---
 tools/testing/selftests/arm64/fp/Makefile        | 2 +-
 tools/testing/selftests/arm64/fp/sve-probe-vls.c | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index ed62e7003b96..fa3a0167db2d 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -13,7 +13,7 @@ fpsimd-test: fpsimd-test.o
 	$(CC) -nostdlib $^ -o $@
 rdvl-sve: rdvl-sve.o rdvl.o
 sve-ptrace: sve-ptrace.o sve-ptrace-asm.o
-sve-probe-vls: sve-probe-vls.o
+sve-probe-vls: sve-probe-vls.o rdvl.o
 sve-test: sve-test.o
 	$(CC) -nostdlib $^ -o $@
 vlset: vlset.o
diff --git a/tools/testing/selftests/arm64/fp/sve-probe-vls.c b/tools/testing/selftests/arm64/fp/sve-probe-vls.c
index 76e138525d55..a24eca7a4ecb 100644
--- a/tools/testing/selftests/arm64/fp/sve-probe-vls.c
+++ b/tools/testing/selftests/arm64/fp/sve-probe-vls.c
@@ -13,6 +13,7 @@
 #include <asm/sigcontext.h>
 
 #include "../../kselftest.h"
+#include "rdvl.h"
 
 int main(int argc, char **argv)
 {
@@ -38,6 +39,10 @@ int main(int argc, char **argv)
 
 		vl &= PR_SVE_VL_LEN_MASK;
 
+		if (rdvl_sve() != vl)
+			ksft_exit_fail_msg("PR_SVE_SET_VL reports %d, RDVL %d\n",
+					   vl, rdvl_sve());
+
 		if (!sve_vl_valid(vl))
 			ksft_exit_fail_msg("VL %d invalid\n", vl);
 		vq = sve_vq_from_vl(vl);
-- 
2.20.1



From broonie at kernel.org  Tue Aug  3 07:04:49 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue,  3 Aug 2021 15:04:49 +0100
Subject: [PATCH v5 3/4] kselftest/arm64: Add tests for SVE vector configuration
In-Reply-To: <20210803140450.46624-1-broonie@kernel.org>
References: <20210803140450.46624-1-broonie@kernel.org>
Message-ID: <20210803140450.46624-4-broonie@kernel.org>

We provide interfaces for configuring the SVE vector length seen by
processes using prctl and also via /proc for configuring the default
values. Provide tests that exercise all these interfaces and verify that
they take effect as expected, though at present no test fully enumerates
all the possible vector lengths.

A subset of this is already tested via sve-probe-vls but the /proc
interfaces are not currently covered at all.

In preparation for the forthcoming support for SME, the Scalable Matrix
Extension, which has separately but similarly configured vector lengths
which we expect to offer similar userspace interfaces for, all the actual
files and prctls used are parameterised and we don't validate that the
architectural minimum vector length is the minimum we see.

Signed-off-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Dave Martin <Dave.Martin at arm.com>
---
 tools/testing/selftests/arm64/fp/.gitignore   |   1 +
 tools/testing/selftests/arm64/fp/Makefile     |   3 +-
 tools/testing/selftests/arm64/fp/vec-syscfg.c | 593 ++++++++++++++++++
 3 files changed, 596 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/fp/vec-syscfg.c

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index 6b53a7b60fee..b67395903b9b 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -3,4 +3,5 @@ rdvl-sve
 sve-probe-vls
 sve-ptrace
 sve-test
+vec-syscfg
 vlset
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index fa3a0167db2d..f2abdd6ba12e 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 CFLAGS += -I../../../../../usr/include/
-TEST_GEN_PROGS := sve-ptrace sve-probe-vls
+TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
 TEST_PROGS_EXTENDED := fpsimd-test fpsimd-stress \
 	rdvl-sve \
 	sve-test sve-stress \
@@ -16,6 +16,7 @@ sve-ptrace: sve-ptrace.o sve-ptrace-asm.o
 sve-probe-vls: sve-probe-vls.o rdvl.o
 sve-test: sve-test.o
 	$(CC) -nostdlib $^ -o $@
+vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
 
 include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
new file mode 100644
index 000000000000..c02071dcb563
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
@@ -0,0 +1,593 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 ARM Limited.
+ * Original author: Mark Brown <broonie at kernel.org>
+ */
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <asm/sigcontext.h>
+#include <asm/hwcap.h>
+
+#include "../../kselftest.h"
+#include "rdvl.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+#define ARCH_MIN_VL SVE_VL_MIN
+
+struct vec_data {
+	const char *name;
+	unsigned long hwcap_type;
+	unsigned long hwcap;
+	const char *rdvl_binary;
+	int (*rdvl)(void);
+
+	int prctl_get;
+	int prctl_set;
+	const char *default_vl_file;
+
+	int default_vl;
+	int min_vl;
+	int max_vl;
+};
+
+
+static struct vec_data vec_data[] = {
+	{
+		.name = "SVE",
+		.hwcap_type = AT_HWCAP,
+		.hwcap = HWCAP_SVE,
+		.rdvl = rdvl_sve,
+		.rdvl_binary = "./rdvl-sve",
+		.prctl_get = PR_SVE_GET_VL,
+		.prctl_set = PR_SVE_SET_VL,
+		.default_vl_file = "/proc/sys/abi/sve_default_vector_length",
+	},
+};
+
+static int stdio_read_integer(FILE *f, const char *what, int *val)
+{
+	int n = 0;
+	int ret;
+
+	ret = fscanf(f, "%d%*1[\n]%n", val, &n);
+	if (ret < 1 || n < 1) {
+		ksft_print_msg("failed to parse integer from %s\n", what);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* Start a new process and return the vector length it sees */
+static int get_child_rdvl(struct vec_data *data)
+{
+	FILE *out;
+	int pipefd[2];
+	pid_t pid, child;
+	int read_vl, ret;
+
+	ret = pipe(pipefd);
+	if (ret == -1) {
+		ksft_print_msg("pipe() failed: %d (%s)\n",
+			       errno, strerror(errno));
+		return -1;
+	}
+
+	fflush(stdout);
+
+	child = fork();
+	if (child == -1) {
+		ksft_print_msg("fork() failed: %d (%s)\n",
+			       errno, strerror(errno));
+		close(pipefd[0]);
+		close(pipefd[1]);
+		return -1;
+	}
+
+	/* Child: put vector length on the pipe */
+	if (child == 0) {
+		/*
+		 * Replace stdout with the pipe, errors to stderr from
+		 * here as kselftest prints to stdout.
+		 */
+		ret = dup2(pipefd[1], 1);
+		if (ret == -1) {
+			fprintf(stderr, "dup2() %d\n", errno);
+			exit(EXIT_FAILURE);
+		}
+
+		/* exec() a new binary which puts the VL on stdout */
+		ret = execl(data->rdvl_binary, data->rdvl_binary, NULL);
+		fprintf(stderr, "execl(%s) failed: %d\n",
+			data->rdvl_binary, errno, strerror(errno));
+
+		exit(EXIT_FAILURE);
+	}
+
+	close(pipefd[1]);
+
+	/* Parent; wait for the exit status from the child & verify it */
+	do {
+		pid = wait(&ret);
+		if (pid == -1) {
+			ksft_print_msg("wait() failed: %d (%s)\n",
+				       errno, strerror(errno));
+			close(pipefd[0]);
+			return -1;
+		}
+	} while (pid != child);
+
+	assert(pid == child);
+
+	if (!WIFEXITED(ret)) {
+		ksft_print_msg("child exited abnormally\n");
+		close(pipefd[0]);
+		return -1;
+	}
+
+	if (WEXITSTATUS(ret) != 0) {
+		ksft_print_msg("child returned error %d\n",
+			       WEXITSTATUS(ret));
+		close(pipefd[0]);
+		return -1;
+	}
+
+	out = fdopen(pipefd[0], "r");
+	if (!out) {
+		ksft_print_msg("failed to open child stdout\n");
+		close(pipefd[0]);
+		return -1;
+	}
+
+	ret = stdio_read_integer(out, "child", &read_vl);
+	fclose(out);
+	if (ret != 0)
+		return ret;
+
+	return read_vl;
+}
+
+static int file_read_integer(const char *name, int *val)
+{
+	FILE *f;
+	int ret;
+
+	f = fopen(name, "r");
+	if (!f) {
+		ksft_test_result_fail("Unable to open %s: %d (%s)\n",
+				      name, errno,
+				      strerror(errno));
+		return -1;
+	}
+
+	ret = stdio_read_integer(f, name, val);
+	fclose(f);
+
+	return ret;
+}
+
+static int file_write_integer(const char *name, int val)
+{
+	FILE *f;
+	int ret;
+
+	f = fopen(name, "w");
+	if (!f) {
+		ksft_test_result_fail("Unable to open %s: %d (%s)\n",
+				      name, errno,
+				      strerror(errno));
+		return -1;
+	}
+
+	fprintf(f, "%d", val);
+	fclose(f);
+	if (ret < 0) {
+		ksft_test_result_fail("Error writing %d to %s\n",
+				      val, name);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Verify that we can read the default VL via proc, checking that it
+ * is set in a freshly spawned child.
+ */
+static void proc_read_default(struct vec_data *data)
+{
+	int default_vl, child_vl, ret;
+
+	ret = file_read_integer(data->default_vl_file, &default_vl);
+	if (ret != 0)
+		return;
+
+	/* Is this the actual default seen by new processes? */
+	child_vl = get_child_rdvl(data);
+	if (child_vl != default_vl) {
+		ksft_test_result_fail("%s is %d but child VL is %d\n",
+				      data->default_vl_file,
+				      default_vl, child_vl);
+		return;
+	}
+
+	ksft_test_result_pass("%s default vector length %d\n", data->name,
+			      default_vl);
+	data->default_vl = default_vl;
+}
+
+/* Verify that we can write a minimum value and have it take effect */
+static void proc_write_min(struct vec_data *data)
+{
+	int ret, new_default, child_vl;
+
+	if (geteuid() != 0) {
+		ksft_test_result_skip("Need to be root to write to /proc\n");
+		return;
+	}
+
+	ret = file_write_integer(data->default_vl_file, ARCH_MIN_VL);
+	if (ret != 0)
+		return;
+
+	/* What was the new value? */
+	ret = file_read_integer(data->default_vl_file, &new_default);
+	if (ret != 0)
+		return;
+
+	/* Did it take effect in a new process? */
+	child_vl = get_child_rdvl(data);
+	if (child_vl != new_default) {
+		ksft_test_result_fail("%s is %d but child VL is %d\n",
+				      data->default_vl_file,
+				      new_default, child_vl);
+		return;
+	}
+
+	ksft_test_result_pass("%s minimum vector length %d\n", data->name,
+			      new_default);
+	data->min_vl = new_default;
+
+	file_write_integer(data->default_vl_file, data->default_vl);
+}
+
+/* Verify that we can write a maximum value and have it take effect */
+static void proc_write_max(struct vec_data *data)
+{
+	int ret, new_default, child_vl;
+
+	if (geteuid() != 0) {
+		ksft_test_result_skip("Need to be root to write to /proc\n");
+		return;
+	}
+
+	/* -1 is accepted by the /proc interface as the maximum VL */
+	ret = file_write_integer(data->default_vl_file, -1);
+	if (ret != 0)
+		return;
+
+	/* What was the new value? */
+	ret = file_read_integer(data->default_vl_file, &new_default);
+	if (ret != 0)
+		return;
+
+	/* Did it take effect in a new process? */
+	child_vl = get_child_rdvl(data);
+	if (child_vl != new_default) {
+		ksft_test_result_fail("%s is %d but child VL is %d\n",
+				      data->default_vl_file,
+				      new_default, child_vl);
+		return;
+	}
+
+	ksft_test_result_pass("%s maximum vector length %d\n", data->name,
+			      new_default);
+	data->max_vl = new_default;
+
+	file_write_integer(data->default_vl_file, data->default_vl);
+}
+
+/* Can we read back a VL from prctl? */
+static void prctl_get(struct vec_data *data)
+{
+	int ret;
+
+	ret = prctl(data->prctl_get);
+	if (ret == -1) {
+		ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
+				      data->name, errno, strerror(errno));
+		return;
+	}
+
+	/* Mask out any flags */
+	ret &= PR_SVE_VL_LEN_MASK;
+
+	/* Is that what we can read back directly? */
+	if (ret == data->rdvl())
+		ksft_test_result_pass("%s current VL is %d\n",
+				      data->name, ret);
+	else
+		ksft_test_result_fail("%s prctl() VL %d but RDVL is %d\n",
+				      data->name, ret, data->rdvl());
+}
+
+/* Does the prctl let us set the VL we already have? */
+static void prctl_set_same(struct vec_data *data)
+{
+	int cur_vl = data->rdvl();
+	int ret;
+
+	ret = prctl(data->prctl_set, cur_vl);
+	if (ret < 0) {
+		ksft_test_result_fail("%s prctl set failed: %d (%s)\n",
+				      data->name, errno, strerror(errno));
+		return;
+	}
+
+	if (cur_vl != data->rdvl())
+		ksft_test_result_pass("%s current VL is %d\n",
+				      data->name, ret);
+	else
+		ksft_test_result_fail("%s prctl() VL %d but RDVL is %d\n",
+				      data->name, ret, data->rdvl());
+}
+
+/* Can we set a new VL for this process? */
+static void prctl_set(struct vec_data *data)
+{
+	int ret;
+
+	if (data->min_vl == data->max_vl) {
+		ksft_test_result_skip("%s only one VL supported\n",
+				      data->name);
+		return;
+	}
+
+	/* Try to set the minimum VL */
+	ret = prctl(data->prctl_set, data->min_vl);
+	if (ret < 0) {
+		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
+				      data->name, data->min_vl,
+				      errno, strerror(errno));
+		return;
+	}
+
+	if ((ret & PR_SVE_VL_LEN_MASK) != data->min_vl) {
+		ksft_test_result_fail("%s prctl set %d but return value is %d\n",
+				      data->name, data->min_vl, data->rdvl());
+		return;
+	}
+
+	if (data->rdvl() != data->min_vl) {
+		ksft_test_result_fail("%s set %d but RDVL is %d\n",
+				      data->name, data->min_vl, data->rdvl());
+		return;
+	}
+
+	/* Try to set the maximum VL */
+	ret = prctl(data->prctl_set, data->max_vl);
+	if (ret < 0) {
+		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
+				      data->name, data->max_vl,
+				      errno, strerror(errno));
+		return;
+	}
+
+	if ((ret & PR_SVE_VL_LEN_MASK) != data->max_vl) {
+		ksft_test_result_fail("%s prctl() set %d but return value is %d\n",
+				      data->name, data->max_vl, data->rdvl());
+		return;
+	}
+
+	/* The _INHERIT flag should not be present when we read the VL */
+	ret = prctl(data->prctl_get);
+	if (ret == -1) {
+		ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
+				      data->name, errno, strerror(errno));
+		return;
+	}
+
+	if (ret & PR_SVE_VL_INHERIT) {
+		ksft_test_result_fail("%s prctl() reports _INHERIT\n",
+				      data->name);
+		return;
+	}
+
+	ksft_test_result_pass("%s prctl() set min/max\n", data->name);
+}
+
+/* If we didn't request it a new VL shouldn't affect the child */
+static void prctl_set_no_child(struct vec_data *data)
+{
+	int ret, child_vl;
+
+	if (data->min_vl == data->max_vl) {
+		ksft_test_result_skip("%s only one VL supported\n",
+				      data->name);
+		return;
+	}
+
+	ret = prctl(data->prctl_set, data->min_vl);
+	if (ret < 0) {
+		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
+				      data->name, data->min_vl,
+				      errno, strerror(errno));
+		return;
+	}
+
+	/* Ensure the default VL is different */
+	ret = file_write_integer(data->default_vl_file, data->max_vl);
+	if (ret != 0)
+		return;
+
+	/* Check that the child has the default we just set */
+	child_vl = get_child_rdvl(data);
+	if (child_vl != data->max_vl) {
+		ksft_test_result_fail("%s is %d but child VL is %d\n",
+				      data->default_vl_file,
+				      data->max_vl, child_vl);
+		return;
+	}
+
+	ksft_test_result_pass("%s vector length used default\n", data->name);
+
+	file_write_integer(data->default_vl_file, data->default_vl);
+}
+
+/* If we didn't request it a new VL shouldn't affect the child */
+static void prctl_set_for_child(struct vec_data *data)
+{
+	int ret, child_vl;
+
+	if (data->min_vl == data->max_vl) {
+		ksft_test_result_skip("%s only one VL supported\n",
+				      data->name);
+		return;
+	}
+
+	ret = prctl(data->prctl_set, data->min_vl | PR_SVE_VL_INHERIT);
+	if (ret < 0) {
+		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
+				      data->name, data->min_vl,
+				      errno, strerror(errno));
+		return;
+	}
+
+	/* The _INHERIT flag should be present when we read the VL */
+	ret = prctl(data->prctl_get);
+	if (ret == -1) {
+		ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
+				      data->name, errno, strerror(errno));
+		return;
+	}
+	if (!(ret & PR_SVE_VL_INHERIT)) {
+		ksft_test_result_fail("%s prctl() does not report _INHERIT\n",
+				      data->name);
+		return;
+	}
+
+	/* Ensure the default VL is different */
+	ret = file_write_integer(data->default_vl_file, data->max_vl);
+	if (ret != 0)
+		return;
+
+	/* Check that the child inherited our VL */
+	child_vl = get_child_rdvl(data);
+	if (child_vl != data->min_vl) {
+		ksft_test_result_fail("%s is %d but child VL is %d\n",
+				      data->default_vl_file,
+				      data->min_vl, child_vl);
+		return;
+	}
+
+	ksft_test_result_pass("%s vector length was inherited\n", data->name);
+
+	file_write_integer(data->default_vl_file, data->default_vl);
+}
+
+/* _ONEXEC takes effect only in the child process */
+static void prctl_set_onexec(struct vec_data *data)
+{
+	int ret, child_vl;
+
+	if (data->min_vl == data->max_vl) {
+		ksft_test_result_skip("%s only one VL supported\n",
+				      data->name);
+		return;
+	}
+
+	/* Set a known value for the default and our current VL */
+	ret = file_write_integer(data->default_vl_file, data->max_vl);
+	if (ret != 0)
+		return;
+
+	ret = prctl(data->prctl_set, data->max_vl);
+	if (ret < 0) {
+		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
+				      data->name, data->min_vl,
+				      errno, strerror(errno));
+		return;
+	}
+
+	/* Set a different value for the child to have on exec */
+	ret = prctl(data->prctl_set, data->min_vl | PR_SVE_SET_VL_ONEXEC);
+	if (ret < 0) {
+		ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
+				      data->name, data->min_vl,
+				      errno, strerror(errno));
+		return;
+	}
+
+	/* Our current VL should stay the same */
+	if (data->rdvl() != data->max_vl) {
+		ksft_test_result_fail("%s VL changed by _ONEXEC prctl()\n",
+				      data->name);
+		return;
+	}
+
+	/* Check that the child inherited our VL */
+	child_vl = get_child_rdvl(data);
+	if (child_vl != data->min_vl) {
+		ksft_test_result_fail("Set %d _ONEXEC but child VL is %d\n",
+				      data->min_vl, child_vl);
+		return;
+	}
+
+	ksft_test_result_pass("%s vector length set on exec\n", data->name);
+
+	file_write_integer(data->default_vl_file, data->default_vl);
+}
+
+typedef void (*test_type)(struct vec_data *);
+
+static const test_type tests[] = {
+	/*
+	 * The default/min/max tests must be first and in this order
+	 * to provide data for other tests.
+	 */
+	proc_read_default,
+	proc_write_min,
+	proc_write_max,
+
+	prctl_get,
+	prctl_set,
+	prctl_set_no_child,
+	prctl_set_for_child,
+	prctl_set_onexec,
+};
+
+int main(void)
+{
+	int i, j;
+
+	ksft_print_header();
+	ksft_set_plan(ARRAY_SIZE(tests) * ARRAY_SIZE(vec_data));
+
+	for (i = 0; i < ARRAY_SIZE(vec_data); i++) {
+		struct vec_data *data = &vec_data[i];
+		unsigned long supported;
+
+		supported = getauxval(data->hwcap_type) & data->hwcap;
+
+		for (j = 0; j < ARRAY_SIZE(tests); j++) {
+			if (supported)
+				tests[j](data);
+			else
+				ksft_test_result_skip("%s not supported\n",
+						      data->name);
+		}
+	}
+
+	ksft_exit_pass();
+}
-- 
2.20.1



From broonie at kernel.org  Tue Aug  3 07:04:50 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue,  3 Aug 2021 15:04:50 +0100
Subject: [PATCH v5 4/4] kselftest/arm64: Add a TODO list for floating point
 tests
In-Reply-To: <20210803140450.46624-1-broonie@kernel.org>
References: <20210803140450.46624-1-broonie@kernel.org>
Message-ID: <20210803140450.46624-5-broonie@kernel.org>

Write down some ideas for additional coverage for floating point in case
someone feels inspired to look into them.

Signed-off-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Dave Martin <Dave.Martin at arm.com>
---
 tools/testing/selftests/arm64/fp/TODO | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/fp/TODO

diff --git a/tools/testing/selftests/arm64/fp/TODO b/tools/testing/selftests/arm64/fp/TODO
new file mode 100644
index 000000000000..b6b7ebfcf362
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/TODO
@@ -0,0 +1,4 @@
+- Test unsupported values in the ABIs.
+- More coverage for ptrace (eg, vector length conversions).
+- Coverage for signals.
+- Test PR_SVE_VL_INHERITY after a double fork.
-- 
2.20.1



From andriy.shevchenko at linux.intel.com  Tue Aug  3 07:07:50 2021
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Tue, 3 Aug 2021 17:07:50 +0300
Subject: [PATCH printk v1 10/10] serial: 8250: implement write_atomic
In-Reply-To: <20210803131301.5588-11-john.ogness@linutronix.de>
References: <20210803131301.5588-1-john.ogness@linutronix.de>
 <20210803131301.5588-11-john.ogness@linutronix.de>
Message-ID: <YQlNtr7TNAWtB8XF@smile.fi.intel.com>

On Tue, Aug 03, 2021 at 03:19:01PM +0206, John Ogness wrote:
> Implement an NMI-safe write_atomic() console function in order to
> support synchronous console printing.
> 
> Since interrupts need to be disabled during transmit, all usage of
> the IER register is wrapped with access functions that use the
> printk cpulock to synchronize register access while tracking the
> state of the interrupts. This is necessary because write_atomic()
> can be called from an NMI context that has preempted write_atomic().

...

> +static inline void serial8250_set_IER(struct uart_8250_port *up,
> +				      unsigned char ier)
> +{
> +	struct uart_port *port = &up->port;
> +	unsigned long flags;
> +	bool is_console;

> +	is_console = uart_console(port);
> +
> +	if (is_console)
> +		console_atomic_cpu_lock(flags);
> +
> +	serial_out(up, UART_IER, ier);
> +
> +	if (is_console)
> +		console_atomic_cpu_unlock(flags);

I would rewrite it as

	if (uart_console()) {
		console_atomic_cpu_lock(flags);
		serial_out(up, UART_IER, ier);
		console_atomic_cpu_unlock(flags);
	} else {
		serial_out(up, UART_IER, ier);
	}

No additional variable, easier to get the algorithm on the first glance, less
error prone.

> +}

> +static inline unsigned char serial8250_clear_IER(struct uart_8250_port *up)
> +{
> +	struct uart_port *port = &up->port;
> +	unsigned int clearval = 0;
> +	unsigned long flags;
> +	unsigned int prior;
> +	bool is_console;
> +
> +	is_console = uart_console(port);
> +
> +	if (up->capabilities & UART_CAP_UUE)
> +		clearval = UART_IER_UUE;
> +
> +	if (is_console)
> +		console_atomic_cpu_lock(flags);
> +
> +	prior = serial_port_in(port, UART_IER);
> +	serial_port_out(port, UART_IER, clearval);
> +
> +	if (is_console)
> +		console_atomic_cpu_unlock(flags);

Ditto.

> +	return prior;
> +}

...

> +		is_console = uart_console(port);
> +
> +		if (is_console)
> +			console_atomic_cpu_lock(flags);
>  		up->ier = port->serial_in(port, UART_IER);
> +		if (is_console)
> +			console_atomic_cpu_unlock(flags);
> +

I'm wondering why you can't call above function here?

...

> +		is_console = uart_console(p);
> +		if (is_console)
> +			console_atomic_cpu_lock(flags);
>  		ier = p->serial_in(p, UART_IER);
> +		if (is_console)
> +			console_atomic_cpu_unlock(flags);

Ditto.

...

> +	is_console = uart_console(port);
> +
> +	if (is_console)
> +		console_atomic_cpu_lock(flags);
> +
> +	ier = serial_in(up, UART_IER);
> +	serial_out(up, UART_IER, ier & (~mask));
> +
> +	if (is_console)
> +		console_atomic_cpu_unlock(flags);

Ditto.

...

> +	if (uart_console(port))
> +		console_atomic_cpu_lock(flags);
> +
> +	ier = serial_in(up, UART_IER);
> +	serial_out(up, UART_IER, ier | mask);
> +
> +	if (uart_console(port))
> +		console_atomic_cpu_unlock(flags);

Ditto.

Looking into above note, that uart_console(port) can give different results
here, AFAIR.

-- 
With Best Regards,
Andy Shevchenko




From broonie at kernel.org  Tue Aug  3 07:10:45 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 3 Aug 2021 15:10:45 +0100
Subject: [PATCH v2 4/4] spi: tegra114: Fix set_cs_timing param
In-Reply-To: <20210803102517.20944-1-Mason.Zhang@mediatek.com>
References: <20210803102517.20944-1-Mason.Zhang@mediatek.com>
Message-ID: <20210803141045.GN4668@sirena.org.uk>

On Tue, Aug 03, 2021 at 06:25:18PM +0800, Mason Zhang wrote:
> This patch fixed set_cs_timing param, because cs timing delay has
> been moved to spi_device.
> 
> Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
> ---
>  drivers/spi/spi-tegra114.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)

Each individual patch in the series needs to be buildable by itself, if
an earlier commit in the series causes things to fail to build then that
commit needs to be improved so that this doesn't happen.  This supports
things like bisection.

Please also look into how you're sending serieses, these patches aren't
threaded together as normal and there's a weird "***" in the subject of
the first patch.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210803/a642995e/attachment.sig>

From bigeasy at linutronix.de  Tue Aug  3 07:15:57 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Tue,  3 Aug 2021 16:15:57 +0200
Subject: [PATCH 14/38] coresight: Replace deprecated CPU-hotplug functions.
In-Reply-To: <20210803141621.780504-1-bigeasy@linutronix.de>
References: <20210803141621.780504-1-bigeasy@linutronix.de>
Message-ID: <20210803141621.780504-15-bigeasy@linutronix.de>

The functions get_online_cpus() and put_online_cpus() have been
deprecated during the CPU hotplug rework. They map directly to
cpus_read_lock() and cpus_read_unlock().

Replace deprecated CPU-hotplug functions with the official version.
The behavior remains unchanged.

Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Leo Yan <leo.yan at linaro.org>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: coresight at lists.linaro.org
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
---
 drivers/hwtracing/coresight/coresight-cpu-debug.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 9731d3a960735..00de46565bc40 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -588,11 +588,11 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id)
 
 	drvdata->base = base;
 
-	get_online_cpus();
+	cpus_read_lock();
 	per_cpu(debug_drvdata, drvdata->cpu) = drvdata;
 	ret = smp_call_function_single(drvdata->cpu, debug_init_arch_data,
 				       drvdata, 1);
-	put_online_cpus();
+	cpus_read_unlock();
 
 	if (ret) {
 		dev_err(dev, "CPU%d debug arch init failed\n", drvdata->cpu);
-- 
2.32.0



From wangborong at cdjrlc.com  Tue Aug  3 07:20:20 2021
From: wangborong at cdjrlc.com (Jason Wang)
Date: Tue,  3 Aug 2021 22:20:20 +0800
Subject: [PATCH] arm64: fix typo in a comment
Message-ID: <20210803142020.124230-1-wangborong@cdjrlc.com>

The double 'the' after 'If' in this comment "If the the TLB range ops
are supported..." is repeated. Consequently, one 'the' should be
removed from the comment.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
---
 arch/arm64/include/asm/tlbflush.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index cc3f5a33ff9c..118dabbda553 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -308,7 +308,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
 
 	/*
 	 * When the CPU does not support TLB range operations, flush the TLB
-	 * entries one by one at the granularity of 'stride'. If the the TLB
+	 * entries one by one at the granularity of 'stride'. If the TLB
 	 * range ops are supported, then:
 	 *
 	 * 1. If 'pages' is odd, flush the first page through non-range
-- 
2.32.0



From dsahern at gmail.com  Tue Aug  3 07:32:48 2021
From: dsahern at gmail.com (David Ahern)
Date: Tue, 3 Aug 2021 08:32:48 -0600
Subject: [PATCH net-next] net: add extack arg for link ops
In-Reply-To: <20210803120250.32642-1-rocco.yue@mediatek.com>
References: <20210803120250.32642-1-rocco.yue@mediatek.com>
Message-ID: <f6f10fe7-afdd-fdce-c091-861a738feb8a@gmail.com>

On 8/3/21 6:02 AM, Rocco Yue wrote:
> Pass extack arg to validate_linkmsg and validate_link_af callbacks.
> If a netlink attribute has a reject_message, use the extended ack
> mechanism to carry the message back to user space.
> 
> Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
> ---
>  include/net/rtnetlink.h | 3 ++-
>  net/core/rtnetlink.c    | 9 +++++----
>  net/ipv4/devinet.c      | 5 +++--
>  net/ipv6/addrconf.c     | 5 +++--
>  4 files changed, 13 insertions(+), 9 deletions(-)
> 

Reviewed-by: David Ahern <dsahern at kernel.org>


From olteanv at gmail.com  Tue Aug  3 07:43:45 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 3 Aug 2021 17:43:45 +0300
Subject: [PATCH net-next 3/4] net: dsa: mt7530: set STP state on filter
 ID 1
In-Reply-To: <20210803124022.2912298-4-dqfext@gmail.com>
References: <20210803124022.2912298-1-dqfext@gmail.com>
 <20210803124022.2912298-4-dqfext@gmail.com>
Message-ID: <20210803144345.jmucndmrflnqlfo3@skbuf>

On Tue, Aug 03, 2021 at 08:40:21PM +0800, DENG Qingfang wrote:
> As filter ID 1 is the only one used for bridges, set STP state on it.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
> RFC -> v1: only set FID 1's state
> 
>  drivers/net/dsa/mt7530.c | 3 ++-
>  drivers/net/dsa/mt7530.h | 4 ++--
>  2 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 12f449a54833..8d84d7ddad38 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -1147,7 +1147,8 @@ mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
>  		break;
>  	}
>  
> -	mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK, stp_state);
> +	mt7530_rmw(priv, MT7530_SSP_P(port), FID1_PST_MASK,
> +		   FID1_PST(stp_state));
>  }
>  
>  static int
> diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
> index a308886fdebc..53b7bb1f5368 100644
> --- a/drivers/net/dsa/mt7530.h
> +++ b/drivers/net/dsa/mt7530.h
> @@ -181,8 +181,8 @@ enum mt7530_vlan_egress_attr {
>  
>  /* Register for port STP state control */
>  #define MT7530_SSP_P(x)			(0x2000 + ((x) * 0x100))
> -#define  FID_PST(x)			((x) & 0x3)
> -#define  FID_PST_MASK			FID_PST(0x3)
> +#define  FID1_PST(x)			(((x) & 0x3) << 2)
> +#define  FID1_PST_MASK			FID1_PST(0x3)

Not a reason to resend, but I still would have expected a macro:

#define FID_PST(fid, state)		((state) & 0x3) << ((fid) * 2)
#define FID_PST_MASK(fid)		FID_PST(fid, 0x3)

#define FID_STANDALONE			0
#define FID_BRIDGED			1

and called with:

	mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK(FID_BRIDGED),
		   FID_PST(FID_BRIDGED, stp_state));

>  
>  enum mt7530_stp_state {
>  	MT7530_STP_DISABLED = 0,
> -- 
> 2.25.1
> 

Anyhow.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From olteanv at gmail.com  Tue Aug  3 07:45:52 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 3 Aug 2021 17:45:52 +0300
Subject: [PATCH net-next 4/4] net: dsa: mt7530: always install FDB
 entries with IVL and FID 1
In-Reply-To: <20210803124022.2912298-5-dqfext@gmail.com>
References: <20210803124022.2912298-1-dqfext@gmail.com>
 <20210803124022.2912298-5-dqfext@gmail.com>
Message-ID: <20210803144552.fluxxfoey2tbqyyu@skbuf>

On Tue, Aug 03, 2021 at 08:40:22PM +0800, DENG Qingfang wrote:
> This reverts commit 7e777021780e ("mt7530 mt7530_fdb_write only set ivl
> bit vid larger than 1").
> 
> Before this series, the default value of all ports' PVID is 1, which is
> copied into the FDB entry, even if the ports are VLAN unaware. So
> `bridge fdb show` will show entries like `dev swp0 vlan 1 self` even on
> a VLAN-unaware bridge.
> 
> The blamed commit does not solve that issue completely, instead it may
> cause a new issue that FDB is inaccessible in a VLAN-aware bridge with
> PVID 1.
> 
> This series sets PVID to 0 on VLAN-unaware ports, so `bridge fdb show`
> will no longer print `vlan 1` on VLAN-unaware bridges, and that special
> case in fdb_write is not required anymore.
> 
> Set FDB entries' filter ID to 1 to match the VLAN table.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
> RFC -> v1: Detailed commit message. Also set FDB entries' FID to 1.
> 
>  drivers/net/dsa/mt7530.c | 4 ++--
>  drivers/net/dsa/mt7530.h | 1 +
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 8d84d7ddad38..ac2b45e472bd 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -366,8 +366,8 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
>  	int i;
>  
>  	reg[1] |= vid & CVID_MASK;
> -	if (vid > 1)
> -		reg[1] |= ATA2_IVL;
> +	reg[1] |= ATA2_IVL;
> +	reg[1] |= ATA2_FID(1);

Maybe it would be good to resend with a set of #defines for the
standalone/bridged port FID values after all, what do you think?

>  	reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
>  	reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
>  	/* STATIC_ENT indicate that entry is static wouldn't
> diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
> index 53b7bb1f5368..73b0e0eb8f2f 100644
> --- a/drivers/net/dsa/mt7530.h
> +++ b/drivers/net/dsa/mt7530.h
> @@ -80,6 +80,7 @@ enum mt753x_bpdu_port_fw {
>  #define  STATIC_ENT			3
>  #define MT7530_ATA2			0x78
>  #define  ATA2_IVL			BIT(15)
> +#define  ATA2_FID(x)			(((x) & 0x7) << 12)
>  
>  /* Register for address table write data */
>  #define MT7530_ATWD			0x7c
> -- 
> 2.25.1
> 



From lkp at intel.com  Tue Aug  3 07:48:21 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 03 Aug 2021 22:48:21 +0800
Subject: [soc:for-next] BUILD SUCCESS 76b8992dc7e4f5ede8158f9cf105e580825dd0f4
Message-ID: <61095735.zGf1xrKbmn48rwX0%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: 76b8992dc7e4f5ede8158f9cf105e580825dd0f4  soc: document merges

elapsed time: 729m

configs tested: 140
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210803
sh                           se7751_defconfig
arc                    vdk_hs38_smp_defconfig
m68k                       bvme6000_defconfig
arm                         mv78xx0_defconfig
powerpc                     kmeter1_defconfig
sh                     sh7710voipgw_defconfig
arm                          pxa3xx_defconfig
arm                         assabet_defconfig
arm                          pxa910_defconfig
powerpc                 mpc8315_rdb_defconfig
ia64                                defconfig
x86_64                            allnoconfig
riscv                               defconfig
arm                         nhk8815_defconfig
arm                  colibri_pxa300_defconfig
arm                     davinci_all_defconfig
sh                           se7750_defconfig
sh                         apsh4a3a_defconfig
riscv                            allyesconfig
powerpc                     powernv_defconfig
mips                         bigsur_defconfig
openrisc                 simple_smp_defconfig
arm                        spear3xx_defconfig
arc                          axs103_defconfig
sh                           se7724_defconfig
m68k                         apollo_defconfig
arm                       cns3420vb_defconfig
arm                          iop32x_defconfig
mips                 decstation_r4k_defconfig
arm                        trizeps4_defconfig
sh                           se7722_defconfig
arm                     eseries_pxa_defconfig
sh                          r7780mp_defconfig
sh                            titan_defconfig
powerpc                    socrates_defconfig
mips                      fuloong2e_defconfig
mips                      malta_kvm_defconfig
sh                        sh7763rdp_defconfig
sh                          sdk7786_defconfig
riscv                    nommu_k210_defconfig
arm                          badge4_defconfig
arm                              alldefconfig
powerpc                 xes_mpc85xx_defconfig
m68k                        mvme16x_defconfig
mips                       rbtx49xx_defconfig
powerpc                     ksi8560_defconfig
arm                       imx_v6_v7_defconfig
powerpc                      bamboo_defconfig
arm                          ixp4xx_defconfig
powerpc                      ppc44x_defconfig
powerpc                  iss476-smp_defconfig
powerpc                     akebono_defconfig
nds32                             allnoconfig
powerpc                    klondike_defconfig
mips                       bmips_be_defconfig
riscv                             allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802
riscv                    nommu_virt_defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210803
x86_64               randconfig-c001-20210802
x86_64               randconfig-a002-20210802
x86_64               randconfig-a004-20210802
x86_64               randconfig-a006-20210802
x86_64               randconfig-a003-20210802
x86_64               randconfig-a001-20210802
x86_64               randconfig-a005-20210802
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug  3 07:47:49 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 03 Aug 2021 22:47:49 +0800
Subject: [soc:arm/drivers] BUILD SUCCESS
 b6e952c35267b8da9a402f2f0c9ea23d5d929774
Message-ID: <61095715.6VwKJY1PCq5RNHKV%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/drivers
branch HEAD: b6e952c35267b8da9a402f2f0c9ea23d5d929774  Merge tag 'renesas-drivers-for-v5.15-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into arm/drivers

elapsed time: 728m

configs tested: 97
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
arm                          pxa3xx_defconfig
sh                           se7751_defconfig
arm                         assabet_defconfig
arm                          pxa910_defconfig
powerpc                 mpc8315_rdb_defconfig
parisc                              defconfig
ia64                                defconfig
x86_64                            allnoconfig
riscv                               defconfig
arm                         nhk8815_defconfig
mips                           ip27_defconfig
arm                           h3600_defconfig
mips                        jmr3927_defconfig
arm                      footbridge_defconfig
mips                      maltasmvp_defconfig
mips                  maltasmvp_eva_defconfig
riscv                    nommu_virt_defconfig
arm                         palmz72_defconfig
mips                   sb1250_swarm_defconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210803
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug  3 07:47:59 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 03 Aug 2021 22:47:59 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS 6ebeca342f96a7c371ed5fe53189dd56fe0c0330
Message-ID: <6109571f.iYdjMFP9AyzCltFp%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 6ebeca342f96a7c371ed5fe53189dd56fe0c0330  Merge tag 'mvebu-fixes-5.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu into arm/fixes

elapsed time: 728m

configs tested: 140
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210803
sh                           se7751_defconfig
arc                    vdk_hs38_smp_defconfig
m68k                       bvme6000_defconfig
arm                         mv78xx0_defconfig
powerpc                     kmeter1_defconfig
sh                     sh7710voipgw_defconfig
arm                          pxa3xx_defconfig
arm                         assabet_defconfig
arm                          pxa910_defconfig
powerpc                 mpc8315_rdb_defconfig
ia64                                defconfig
x86_64                            allnoconfig
riscv                               defconfig
arm                         nhk8815_defconfig
arm                  colibri_pxa300_defconfig
arm                     davinci_all_defconfig
sh                           se7750_defconfig
sh                         apsh4a3a_defconfig
riscv                            allyesconfig
powerpc                     powernv_defconfig
mips                         bigsur_defconfig
openrisc                 simple_smp_defconfig
arm                        spear3xx_defconfig
arc                          axs103_defconfig
sh                           se7724_defconfig
m68k                         apollo_defconfig
arm                       cns3420vb_defconfig
arm                          iop32x_defconfig
mips                 decstation_r4k_defconfig
arm                        trizeps4_defconfig
sh                           se7722_defconfig
arm                     eseries_pxa_defconfig
sh                          r7780mp_defconfig
sh                            titan_defconfig
powerpc                    socrates_defconfig
mips                      fuloong2e_defconfig
mips                      malta_kvm_defconfig
sh                        sh7763rdp_defconfig
sh                          sdk7786_defconfig
riscv                    nommu_k210_defconfig
arm                          badge4_defconfig
arm                              alldefconfig
powerpc                 xes_mpc85xx_defconfig
m68k                        mvme16x_defconfig
mips                       rbtx49xx_defconfig
powerpc                     ksi8560_defconfig
arm                       imx_v6_v7_defconfig
powerpc                      bamboo_defconfig
arm                          ixp4xx_defconfig
powerpc                      ppc44x_defconfig
powerpc                  iss476-smp_defconfig
powerpc                     akebono_defconfig
nds32                             allnoconfig
powerpc                    klondike_defconfig
mips                       bmips_be_defconfig
riscv                             allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802
riscv                    nommu_virt_defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210803
x86_64               randconfig-c001-20210802
x86_64               randconfig-a002-20210802
x86_64               randconfig-a004-20210802
x86_64               randconfig-a006-20210802
x86_64               randconfig-a003-20210802
x86_64               randconfig-a001-20210802
x86_64               randconfig-a005-20210802
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug  3 07:48:16 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 03 Aug 2021 22:48:16 +0800
Subject: [soc:arm/soc] BUILD SUCCESS 9450fe3e77d2863f5241aed817aa60f7a766945f
Message-ID: <61095730.WRfm1Qsm4JCHNxod%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/soc
branch HEAD: 9450fe3e77d2863f5241aed817aa60f7a766945f  ARM: ep93xx: remove MaverickCrunch support

elapsed time: 729m

configs tested: 33
configs skipped: 99

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
arm                          pxa3xx_defconfig
sh                           se7751_defconfig
arm                         assabet_defconfig
arm                          pxa910_defconfig
powerpc                 mpc8315_rdb_defconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802

clang tested configs:
x86_64               randconfig-c001-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From robh+dt at kernel.org  Tue Aug  3 07:54:49 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 08:54:49 -0600
Subject: [PATCH v3 3/3] dt-bindings: mediatek: convert pinctrl to yaml
In-Reply-To: <1627999172.502726.3179055.nullmailer@robh.at.kernel.org>
References: <20210803051318.2570994-1-hsinyi@chromium.org>
 <20210803051318.2570994-3-hsinyi@chromium.org>
 <1627999172.502726.3179055.nullmailer@robh.at.kernel.org>
Message-ID: <CAL_JsqJOppSJx+rNvqtz9LGM_GFwjy9xCF1+On3-K1b8fOmuyg@mail.gmail.com>

On Tue, Aug 3, 2021 at 7:59 AM Rob Herring <robh at kernel.org> wrote:
>
> On Tue, 03 Aug 2021 13:13:19 +0800, Hsin-Yi Wang wrote:
> > Convert mt65xx, mt6796, mt7622, mt8183 bindings to yaml.
> >
> > Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
> > ---
> > v2->v3:
> > fix comments in v2.
> > ---
> >  .../pinctrl/mediatek,mt65xx-pinctrl.yaml      | 206 ++++++++
> >  .../pinctrl/mediatek,mt6797-pinctrl.yaml      | 173 +++++++
> >  .../pinctrl/mediatek,mt7622-pinctrl.yaml      | 373 +++++++++++++
> >  .../pinctrl/mediatek,mt8183-pinctrl.yaml      | 228 ++++++++
> >  .../bindings/pinctrl/pinctrl-mt65xx.txt       | 156 ------
> >  .../bindings/pinctrl/pinctrl-mt6797.txt       |  83 ---
> >  .../bindings/pinctrl/pinctrl-mt7622.txt       | 490 ------------------
> >  .../bindings/pinctrl/pinctrl-mt8183.txt       | 132 -----
> >  8 files changed, 980 insertions(+), 861 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
> >  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
> >  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
> >  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
> >  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
> >  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
> >  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
> >  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
> >
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.example.dts:21:18: fatal error: dt-bindings/pinctrl/mt8183-pinfunc.h: No such file or directory
>    21 |         #include <dt-bindings/pinctrl/mt8183-pinfunc.h>
>       |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> compilation terminated.
> make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.example.dt.yaml] Error 1
> make[1]: *** Waiting for unfinished jobs....
> make: *** [Makefile:1419: dt_binding_check] Error 2
> \ndoc reference errors (make refcheckdocs):
> MAINTAINERS: Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
> MAINTAINERS: Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt

Not sure why the header patch is not getting applied, so ignore that.
But these MAINTAINERS references need to be fixed.

Rob


From robh at kernel.org  Tue Aug  3 07:55:51 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 08:55:51 -0600
Subject: [PATCH v3 3/3] dt-bindings: mediatek: convert pinctrl to yaml
In-Reply-To: <20210803051318.2570994-3-hsinyi@chromium.org>
References: <20210803051318.2570994-1-hsinyi@chromium.org>
 <20210803051318.2570994-3-hsinyi@chromium.org>
Message-ID: <YQlY9/5GNOGKG4gv@robh.at.kernel.org>

On Tue, Aug 03, 2021 at 01:13:19PM +0800, Hsin-Yi Wang wrote:
> Convert mt65xx, mt6796, mt7622, mt8183 bindings to yaml.
> 
> Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
> ---
> v2->v3:
> fix comments in v2.

That's assumed... A good revision history will list out what changed to 
remind reviewers what they said. (I kind of remember since it was just 
yesterday, more more than that assume I've forgotten.) This is different 
than the commit msg which should tell us 'why' and not 'what' as there 
we have the diff and can read what changed.

> ---
>  .../pinctrl/mediatek,mt65xx-pinctrl.yaml      | 206 ++++++++
>  .../pinctrl/mediatek,mt6797-pinctrl.yaml      | 173 +++++++
>  .../pinctrl/mediatek,mt7622-pinctrl.yaml      | 373 +++++++++++++
>  .../pinctrl/mediatek,mt8183-pinctrl.yaml      | 228 ++++++++
>  .../bindings/pinctrl/pinctrl-mt65xx.txt       | 156 ------
>  .../bindings/pinctrl/pinctrl-mt6797.txt       |  83 ---
>  .../bindings/pinctrl/pinctrl-mt7622.txt       | 490 ------------------
>  .../bindings/pinctrl/pinctrl-mt8183.txt       | 132 -----
>  8 files changed, 980 insertions(+), 861 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt

With the MAINTAINERS references fixed,

Reviewed-by: Rob Herring <robh at kernel.org>


From kishon at ti.com  Tue Aug  3 07:56:42 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 3 Aug 2021 20:26:42 +0530
Subject: [PATCH v7 5/7] PCI: cadence: Add support to configure virtual
 functions
In-Reply-To: <20210803114530.GE11252@lpieralisi>
References: <20210803050310.27122-1-kishon@ti.com>
 <20210803050310.27122-6-kishon@ti.com> <20210803114530.GE11252@lpieralisi>
Message-ID: <be907fe7-4095-e28b-5575-76629edc30f0@ti.com>

Hi Lorenzo,

On 03/08/21 5:15 pm, Lorenzo Pieralisi wrote:
> On Tue, Aug 03, 2021 at 10:33:08AM +0530, Kishon Vijay Abraham I wrote:
>> Now that support for SR-IOV is added in PCIe endpoint core, add support
>> to configure virtual functions in the Cadence PCIe EP driver.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>> Acked-by: Tom Joseph <tjoseph at cadence.com>
>> ---
>>  .../pci/controller/cadence/pcie-cadence-ep.c  | 241 +++++++++++++++---
>>  drivers/pci/controller/cadence/pcie-cadence.h |   7 +
>>  2 files changed, 217 insertions(+), 31 deletions(-)
>>
>> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
>> index 912a15be8bfd..791915054ff4 100644
>> --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
>> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
>> @@ -20,7 +20,18 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
>>  				     struct pci_epf_header *hdr)
>>  {
>>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>>  	struct cdns_pcie *pcie = &ep->pcie;
>> +	u32 reg;
>> +
>> +	if (vfn > 1) {
>> +		dev_dbg(&epc->dev, "Only Virtual Function #1 has deviceID\n");
>> +		return 0;
> 
> Shouldn't this return an error ?

Since the same function driver could be used for physical function and
virtual function, I tried to avoid adding any additional case specific
for virtual function in the function driver.

If we want to return an error here, then the function driver should be
modified to not invoke writeheader for vfn > 1.
> 
>> +	} else if (vfn == 1) {
>> +		reg = cap + PCI_SRIOV_VF_DID;
>> +		cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid);
>> +		return 0;
>> +	}
>>  
>>  	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
>>  	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
>> @@ -51,12 +62,14 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>>  				struct pci_epf_bar *epf_bar)
>>  {
>>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
>> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
>>  	struct cdns_pcie_epf *epf = &ep->epf[fn];
>>  	struct cdns_pcie *pcie = &ep->pcie;
>>  	dma_addr_t bar_phys = epf_bar->phys_addr;
>>  	enum pci_barno bar = epf_bar->barno;
>>  	int flags = epf_bar->flags;
>>  	u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
>> +	u32 first_vf_offset, stride;
>>  	u64 sz;
>>  
>>  	/* BAR size is 2^(aperture + 7) */
>> @@ -92,26 +105,50 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>>  
>>  	addr0 = lower_32_bits(bar_phys);
>>  	addr1 = upper_32_bits(bar_phys);
>> +
>> +	if (vfn == 1) {
>> +		/* All virtual functions use the same BAR config */
>> +		if (bar < BAR_4) {
>> +			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn);
>> +			b = bar;
>> +		} else {
>> +			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn);
>> +			b = bar - BAR_4;
>> +		}
>> +	} else if (vfn == 0) {
>> +		/* BAR configuration for physical function */
>> +		if (bar < BAR_4) {
>> +			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
>> +			b = bar;
>> +		} else {
>> +			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
>> +			b = bar - BAR_4;
>> +		}
>> +	}
> 
> Code in both branches is almost identical except for what is
> assigned to reg, it is not fundamental but maybe it can be rewritten
> more concisely.

okay.. let me think.

Thanks
Kishon


From robdclark at gmail.com  Tue Aug  3 08:04:13 2021
From: robdclark at gmail.com (Rob Clark)
Date: Tue, 3 Aug 2021 08:04:13 -0700
Subject: [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces
In-Reply-To: <1f5f285a-b923-16ff-2ca1-6f92e22ffcab@linaro.org>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-8-tzimmermann@suse.de>
 <1f5f285a-b923-16ff-2ca1-6f92e22ffcab@linaro.org>
Message-ID: <CAF6AEGuYnnZ7tcdU-9jOWn4ei36Ufc1ovvfT3KTg8_dkSfXn+w@mail.gmail.com>

On Tue, Aug 3, 2021 at 2:37 AM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On 03/08/2021 12:06, Thomas Zimmermann wrote:
> > Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> > IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> > don't benefit from using it.
> >
> > DRM IRQ callbacks are now being called directly or inlined.
> >
> > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>
> Rob should probably also give his blessing on this patch though.

It looks ok.. I can't really test it this week, but it should be
pretty obvious if it wasn't working

BR,
-R

>
> > ---
> >   drivers/gpu/drm/msm/msm_drv.c | 113 ++++++++++++++++++++--------------
> >   drivers/gpu/drm/msm/msm_kms.h |   2 +-
> >   2 files changed, 69 insertions(+), 46 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> > index 1594ae39d54f..a332b09a5a11 100644
> > --- a/drivers/gpu/drm/msm/msm_drv.c
> > +++ b/drivers/gpu/drm/msm/msm_drv.c
> > @@ -14,7 +14,6 @@
> >   #include <drm/drm_drv.h>
> >   #include <drm/drm_file.h>
> >   #include <drm/drm_ioctl.h>
> > -#include <drm/drm_irq.h>
> >   #include <drm/drm_prime.h>
> >   #include <drm/drm_of.h>
> >   #include <drm/drm_vblank.h>
> > @@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
> >       msm_writel(val | or, addr);
> >   }
> >
> > +static irqreturn_t msm_irq(int irq, void *arg)
> > +{
> > +     struct drm_device *dev = arg;
> > +     struct msm_drm_private *priv = dev->dev_private;
> > +     struct msm_kms *kms = priv->kms;
> > +
> > +     BUG_ON(!kms);
> > +
> > +     return kms->funcs->irq(kms);
> > +}
> > +
> > +static void msm_irq_preinstall(struct drm_device *dev)
> > +{
> > +     struct msm_drm_private *priv = dev->dev_private;
> > +     struct msm_kms *kms = priv->kms;
> > +
> > +     BUG_ON(!kms);
> > +
> > +     kms->funcs->irq_preinstall(kms);
> > +}
> > +
> > +static int msm_irq_postinstall(struct drm_device *dev)
> > +{
> > +     struct msm_drm_private *priv = dev->dev_private;
> > +     struct msm_kms *kms = priv->kms;
> > +
> > +     BUG_ON(!kms);
> > +
> > +     if (kms->funcs->irq_postinstall)
> > +             return kms->funcs->irq_postinstall(kms);
> > +
> > +     return 0;
> > +}
> > +
> > +static int msm_irq_install(struct drm_device *dev, unsigned int irq)
> > +{
> > +     int ret;
> > +
> > +     if (irq == IRQ_NOTCONNECTED)
> > +             return -ENOTCONN;
> > +
> > +     msm_irq_preinstall(dev);
> > +
> > +     ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = msm_irq_postinstall(dev);
> > +     if (ret) {
> > +             free_irq(irq, dev);
> > +             return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void msm_irq_uninstall(struct drm_device *dev)
> > +{
> > +     struct msm_drm_private *priv = dev->dev_private;
> > +     struct msm_kms *kms = priv->kms;
> > +
> > +     kms->funcs->irq_uninstall(kms);
> > +     free_irq(kms->irq, dev);
> > +}
> > +
> >   struct msm_vblank_work {
> >       struct work_struct work;
> >       int crtc_id;
> > @@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
> >       }
> >
> >       /* We must cancel and cleanup any pending vblank enable/disable
> > -      * work before drm_irq_uninstall() to avoid work re-enabling an
> > +      * work before msm_irq_uninstall() to avoid work re-enabling an
> >        * irq after uninstall has disabled it.
> >        */
> >
> > @@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
> >       drm_mode_config_cleanup(ddev);
> >
> >       pm_runtime_get_sync(dev);
> > -     drm_irq_uninstall(ddev);
> > +     msm_irq_uninstall(ddev);
> >       pm_runtime_put_sync(dev);
> >
> >       if (kms && kms->funcs)
> > @@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
> >
> >       if (kms) {
> >               pm_runtime_get_sync(dev);
> > -             ret = drm_irq_install(ddev, kms->irq);
> > +             ret = msm_irq_install(ddev, kms->irq);
> >               pm_runtime_put_sync(dev);
> >               if (ret < 0) {
> >                       DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
> > @@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
> >       context_close(ctx);
> >   }
> >
> > -static irqreturn_t msm_irq(int irq, void *arg)
> > -{
> > -     struct drm_device *dev = arg;
> > -     struct msm_drm_private *priv = dev->dev_private;
> > -     struct msm_kms *kms = priv->kms;
> > -     BUG_ON(!kms);
> > -     return kms->funcs->irq(kms);
> > -}
> > -
> > -static void msm_irq_preinstall(struct drm_device *dev)
> > -{
> > -     struct msm_drm_private *priv = dev->dev_private;
> > -     struct msm_kms *kms = priv->kms;
> > -     BUG_ON(!kms);
> > -     kms->funcs->irq_preinstall(kms);
> > -}
> > -
> > -static int msm_irq_postinstall(struct drm_device *dev)
> > -{
> > -     struct msm_drm_private *priv = dev->dev_private;
> > -     struct msm_kms *kms = priv->kms;
> > -     BUG_ON(!kms);
> > -
> > -     if (kms->funcs->irq_postinstall)
> > -             return kms->funcs->irq_postinstall(kms);
> > -
> > -     return 0;
> > -}
> > -
> > -static void msm_irq_uninstall(struct drm_device *dev)
> > -{
> > -     struct msm_drm_private *priv = dev->dev_private;
> > -     struct msm_kms *kms = priv->kms;
> > -     BUG_ON(!kms);
> > -     kms->funcs->irq_uninstall(kms);
> > -}
> > -
> >   int msm_crtc_enable_vblank(struct drm_crtc *crtc)
> >   {
> >       struct drm_device *dev = crtc->dev;
> > @@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
> >       .open               = msm_open,
> >       .postclose           = msm_postclose,
> >       .lastclose          = drm_fb_helper_lastclose,
> > -     .irq_handler        = msm_irq,
> > -     .irq_preinstall     = msm_irq_preinstall,
> > -     .irq_postinstall    = msm_irq_postinstall,
> > -     .irq_uninstall      = msm_irq_uninstall,
> >       .dumb_create        = msm_gem_dumb_create,
> >       .dumb_map_offset    = msm_gem_dumb_map_offset,
> >       .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
> > diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
> > index 086a2d59b8c8..9de7c42e1071 100644
> > --- a/drivers/gpu/drm/msm/msm_kms.h
> > +++ b/drivers/gpu/drm/msm/msm_kms.h
> > @@ -150,7 +150,7 @@ struct msm_kms {
> >       const struct msm_kms_funcs *funcs;
> >       struct drm_device *dev;
> >
> > -     /* irq number to be passed on to drm_irq_install */
> > +     /* irq number to be passed on to msm_irq_install */
> >       int irq;
> >
> >       /* mapper-id used to request GEM buffer mapped for scanout: */
> >
>
>
> --
> With best wishes
> Dmitry


From sam at ravnborg.org  Tue Aug  3 08:00:08 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Tue, 3 Aug 2021 17:00:08 +0200
Subject: [PATCH v2 11/14] drm/tilcdc: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-12-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-12-tzimmermann@suse.de>
Message-ID: <YQlZ+EQVbO9N3Mla@ravnborg.org>

Hi Thomas,

On Tue, Aug 03, 2021 at 11:07:01AM +0200, Thomas Zimmermann wrote:
> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> don't benefit from using it.
> 
> DRM IRQ callbacks are now being called directly or inlined.
> 
> Calls to platform_get_irq() can fail with a negative errno code.
> Abort initialization in this case. The DRM IRQ midlayer does not
> handle this case correctly.

I cannot see why the irq_enabled flag is needed here, and the changelog
do not help me.
What do I miss?

	Sam


> 
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> ---
>  drivers/gpu/drm/tilcdc/tilcdc_drv.c | 51 ++++++++++++++++++++++-------
>  drivers/gpu/drm/tilcdc/tilcdc_drv.h |  3 ++
>  2 files changed, 43 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> index f1d3a9f919fd..6b03f89a98d4 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> @@ -20,7 +20,6 @@
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_gem_cma_helper.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
> -#include <drm/drm_irq.h>
>  #include <drm/drm_mm.h>
>  #include <drm/drm_probe_helper.h>
>  #include <drm/drm_vblank.h>
> @@ -124,6 +123,39 @@ static int cpufreq_transition(struct notifier_block *nb,
>  }
>  #endif
>  
> +static irqreturn_t tilcdc_irq(int irq, void *arg)
> +{
> +	struct drm_device *dev = arg;
> +	struct tilcdc_drm_private *priv = dev->dev_private;
> +
> +	return tilcdc_crtc_irq(priv->crtc);
> +}
> +
> +static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq)
> +{
> +	struct tilcdc_drm_private *priv = dev->dev_private;
> +	int ret;
> +
> +	ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev);
> +	if (ret)
> +		return ret;
> +
> +	priv->irq_enabled = false;
> +
> +	return 0;
> +}
> +
> +static void tilcdc_irq_uninstall(struct drm_device *dev)
> +{
> +	struct tilcdc_drm_private *priv = dev->dev_private;
> +
> +	if (!priv->irq_enabled)
> +		return;
> +
> +	free_irq(priv->irq, dev);
> +	priv->irq_enabled = false;
> +}
> +
>  /*
>   * DRM operations:
>   */
> @@ -145,7 +177,7 @@ static void tilcdc_fini(struct drm_device *dev)
>  		drm_dev_unregister(dev);
>  
>  	drm_kms_helper_poll_fini(dev);
> -	drm_irq_uninstall(dev);
> +	tilcdc_irq_uninstall(dev);
>  	drm_mode_config_cleanup(dev);
>  
>  	if (priv->clk)
> @@ -336,7 +368,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
>  		goto init_failed;
>  	}
>  
> -	ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret < 0)
> +		goto init_failed;
> +	priv->irq = ret;
> +
> +	ret = tilcdc_irq_install(ddev, priv->irq);
>  	if (ret < 0) {
>  		dev_err(dev, "failed to install IRQ handler\n");
>  		goto init_failed;
> @@ -360,13 +397,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
>  	return ret;
>  }
>  
> -static irqreturn_t tilcdc_irq(int irq, void *arg)
> -{
> -	struct drm_device *dev = arg;
> -	struct tilcdc_drm_private *priv = dev->dev_private;
> -	return tilcdc_crtc_irq(priv->crtc);
> -}
> -
>  #if defined(CONFIG_DEBUG_FS)
>  static const struct {
>  	const char *name;
> @@ -454,7 +484,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
>  
>  static const struct drm_driver tilcdc_driver = {
>  	.driver_features    = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
> -	.irq_handler        = tilcdc_irq,
>  	DRM_GEM_CMA_DRIVER_OPS,
>  #ifdef CONFIG_DEBUG_FS
>  	.debugfs_init       = tilcdc_debugfs_init,
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> index d29806ca8817..b818448c83f6 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> @@ -46,6 +46,8 @@ struct tilcdc_drm_private {
>  	struct clk *clk;         /* functional clock */
>  	int rev;                 /* IP revision */
>  
> +	unsigned int irq;
> +
>  	/* don't attempt resolutions w/ higher W * H * Hz: */
>  	uint32_t max_bandwidth;
>  	/*
> @@ -82,6 +84,7 @@ struct tilcdc_drm_private {
>  
>  	bool is_registered;
>  	bool is_componentized;
> +	bool irq_enabled;
>  };
>  
>  /* Sub-module for display.  Since we don't know at compile time what panels
> -- 
> 2.32.0


From sam at ravnborg.org  Tue Aug  3 08:04:54 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Tue, 3 Aug 2021 17:04:54 +0200
Subject: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
In-Reply-To: <20210803090704.32152-1-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
Message-ID: <YQlbFjbrnyeWv7QP@ravnborg.org>

Hi Thomas,

On Tue, Aug 03, 2021 at 11:06:50AM +0200, Thomas Zimmermann wrote:
> DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
> the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
> IRQ interfaces.
> 
> DRM provides IRQ helpers for setting up, receiving and removing IRQ
> handlers. It's an abstraction over plain Linux functions. The code
> is mid-layerish with several callbacks to hook into the rsp drivers.
> Old UMS driver have their interrupts enabled via ioctl, so these
> abstractions makes some sense. Modern KMS manage all their interrupts
> internally. Using the DRM helpers adds indirection without benefits.
> 
> Most KMS drivers already use Linux IRQ functions instead of DRM's
> abstraction layer. Patches 1 to 12 convert the remaining ones.
> The patches also resolve a bug for devices without assigned interrupt
> number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
> not detect if the device has no interrupt assigned.
> 
> Patch 13 removes an unused function.
> 
> Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
> the old non-KMS drivers still use the functionality.
> 
> v2:
> 	* drop IRQ_NOTCONNECTED test from atmel-hlcdc (Sam)
> 	* use devm_request_irq() in atmel-hlcdc (Sam)
> 	* unify variable names in arm/hlcdc (Sam)
> 
> Thomas Zimmermann (14):

The following patches are all:
Acked-by: Sam Ravnborg <sam at ravnborg.org>

>   drm/fsl-dcu: Convert to Linux IRQ interfaces
>   drm/gma500: Convert to Linux IRQ interfaces
>   drm/kmb: Convert to Linux IRQ interfaces
>   drm/msm: Convert to Linux IRQ interfaces
>   drm/mxsfb: Convert to Linux IRQ interfaces
>   drm/tidss: Convert to Linux IRQ interfaces
>   drm/vc4: Convert to Linux IRQ interfaces
>   drm: Remove unused devm_drm_irq_install()

The remaining patches I either skipped or already had a feedback from
me or I asked a question.

	Sam


From mans0n at gorani.run  Tue Aug  3 08:13:18 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Wed,  4 Aug 2021 00:13:18 +0900
Subject: [PATCH 0/2] Add MUSB for MT7623
Message-ID: <20210803151320.71531-1-mans0n@gorani.run>

These patches add support for the MUSB controller on Mediatek MT7623.
Tested on Mercury RUSH-318AC Wi-Fi router.

I got to know this from a BPI-R2 forum post [1], and managed to make it work on OpenWrt snapshot.
I'd like to know if this also works on BPI-R2, I can happily share the details if needed.
And I've just copy & pasted nodes from mt2701, please let me know if I missed some big differences between SoCs...

[1] http://forum.banana-pi.org/t/bpi-r2-otg-port/10551

Sungbo Eo (2):
  dt-bindings: usb: mtk-musb: add MT7623 compatible
  arm: dts: mt7623: add musb device nodes

 .../bindings/usb/mediatek,musb.yaml           |  1 +
 arch/arm/boot/dts/mt7623.dtsi                 | 34 +++++++++++++++++++
 arch/arm/boot/dts/mt7623a.dtsi                |  4 +++
 3 files changed, 39 insertions(+)

-- 
2.32.0



From mans0n at gorani.run  Tue Aug  3 08:13:19 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Wed,  4 Aug 2021 00:13:19 +0900
Subject: [PATCH 1/2] dt-bindings: usb: mtk-musb: add MT7623 compatible
In-Reply-To: <20210803151320.71531-1-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
Message-ID: <20210803151320.71531-2-mans0n@gorani.run>

Document MT7623 compatible for mtk-musb.

Signed-off-by: Sungbo Eo <mans0n at gorani.run>
---
 Documentation/devicetree/bindings/usb/mediatek,musb.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,musb.yaml b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
index 84ddacfdbe9b..03d62d60ce5f 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
@@ -19,6 +19,7 @@ properties:
       - enum:
           - mediatek,mt8516-musb
           - mediatek,mt2701-musb
+          - mediatek,mt7623-musb
       - const: mediatek,mtk-musb
 
   reg:
-- 
2.32.0



From mans0n at gorani.run  Tue Aug  3 08:13:20 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Wed,  4 Aug 2021 00:13:20 +0900
Subject: [PATCH 2/2] arm: dts: mt7623: add musb device nodes
In-Reply-To: <20210803151320.71531-1-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
Message-ID: <20210803151320.71531-3-mans0n@gorani.run>

MT7623 has an musb controller that is compatible with the one from MT2701.

Signed-off-by: Sungbo Eo <mans0n at gorani.run>
---
 arch/arm/boot/dts/mt7623.dtsi  | 34 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
 2 files changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index 3c11f7cfcc40..806dc067ec8f 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -905,6 +905,40 @@ u3port1: usb-phy at 1a244900 {
 		};
 	};
 
+	usb3: usb at 11200000 {
+		compatible = "mediatek,mt7623-musb",
+			     "mediatek,mtk-musb";
+		reg = <0 0x11200000 0 0x1000>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "mc";
+		phys = <&u2port2 PHY_TYPE_USB2>;
+		dr_mode = "otg";
+		clocks = <&pericfg CLK_PERI_USB0>,
+			 <&pericfg CLK_PERI_USB0_MCU>,
+			 <&pericfg CLK_PERI_USB_SLV>;
+		clock-names = "main","mcu","univpll";
+		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
+		status = "disabled";
+	};
+
+	u2phy1: t-phy at 11210000 {
+		compatible = "mediatek,mt7623-tphy",
+			     "mediatek,generic-tphy-v1";
+		reg = <0 0x11210000 0 0x0800>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "okay";
+
+		u2port2: usb-phy at 1a1c4800 {
+			reg = <0 0x11210800 0 0x0100>;
+			clocks = <&topckgen CLK_TOP_USB_PHY48M>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+	};
+
 	ethsys: syscon at 1b000000 {
 		compatible = "mediatek,mt7623-ethsys",
 			     "mediatek,mt2701-ethsys",
diff --git a/arch/arm/boot/dts/mt7623a.dtsi b/arch/arm/boot/dts/mt7623a.dtsi
index 0735a1fb8ad9..c10ce6f4ab27 100644
--- a/arch/arm/boot/dts/mt7623a.dtsi
+++ b/arch/arm/boot/dts/mt7623a.dtsi
@@ -42,3 +42,7 @@ &usb1 {
 &usb2 {
 	power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>;
 };
+
+&usb3 {
+	power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>;
+};
-- 
2.32.0



From linux at roeck-us.net  Tue Aug  3 08:24:14 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Tue, 3 Aug 2021 08:24:14 -0700
Subject: [PATCH v2 12/15] hwmon: peci: Add cputemp driver
In-Reply-To: <20210803113134.2262882-13-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-13-iwona.winiarska@intel.com>
Message-ID: <cd7e15fb-04ba-1eb3-e6b9-43f6d904125e@roeck-us.net>

On 8/3/21 4:31 AM, Iwona Winiarska wrote:
> Add peci-cputemp driver for Digital Thermal Sensor (DTS) thermal
> readings of the processor package and processor cores that are
> accessible via the PECI interface.
> 
> The main use case for the driver (and PECI interface) is out-of-band
> management, where we're able to obtain the DTS readings from an external
> entity connected with PECI, e.g. BMC on server platforms.
> 
> Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> ---
>   MAINTAINERS                  |   7 +
>   drivers/hwmon/Kconfig        |   2 +
>   drivers/hwmon/Makefile       |   1 +
>   drivers/hwmon/peci/Kconfig   |  18 ++
>   drivers/hwmon/peci/Makefile  |   5 +
>   drivers/hwmon/peci/common.h  |  58 ++++
>   drivers/hwmon/peci/cputemp.c | 591 +++++++++++++++++++++++++++++++++++
>   7 files changed, 682 insertions(+)
>   create mode 100644 drivers/hwmon/peci/Kconfig
>   create mode 100644 drivers/hwmon/peci/Makefile
>   create mode 100644 drivers/hwmon/peci/common.h
>   create mode 100644 drivers/hwmon/peci/cputemp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3f5d48e1d143..e36b5c0824e3 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14512,6 +14512,13 @@ L:	platform-driver-x86 at vger.kernel.org
>   S:	Maintained
>   F:	drivers/platform/x86/peaq-wmi.c
>   
> +PECI HARDWARE MONITORING DRIVERS
> +M:	Iwona Winiarska <iwona.winiarska at intel.com>
> +R:	Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> +L:	linux-hwmon at vger.kernel.org
> +S:	Supported
> +F:	drivers/hwmon/peci/
> +
>   PECI SUBSYSTEM
>   M:	Iwona Winiarska <iwona.winiarska at intel.com>
>   R:	Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index e3675377bc5d..61c0e3404415 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -1507,6 +1507,8 @@ config SENSORS_PCF8591
>   	  These devices are hard to detect and rarely found on mainstream
>   	  hardware. If unsure, say N.
>   
> +source "drivers/hwmon/peci/Kconfig"
> +
>   source "drivers/hwmon/pmbus/Kconfig"
>   
>   config SENSORS_PWM_FAN
> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> index d712c61c1f5e..f52331f212ed 100644
> --- a/drivers/hwmon/Makefile
> +++ b/drivers/hwmon/Makefile
> @@ -202,6 +202,7 @@ obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
>   obj-$(CONFIG_SENSORS_XGENE)	+= xgene-hwmon.o
>   
>   obj-$(CONFIG_SENSORS_OCC)	+= occ/
> +obj-$(CONFIG_SENSORS_PECI)	+= peci/
>   obj-$(CONFIG_PMBUS)		+= pmbus/
>   
>   ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG
> diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
> new file mode 100644
> index 000000000000..e10eed68d70a
> --- /dev/null
> +++ b/drivers/hwmon/peci/Kconfig
> @@ -0,0 +1,18 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +config SENSORS_PECI_CPUTEMP
> +	tristate "PECI CPU temperature monitoring client"
> +	depends on PECI
> +	select SENSORS_PECI
> +	select PECI_CPU
> +	help
> +	  If you say yes here you get support for the generic Intel PECI
> +	  cputemp driver which provides Digital Thermal Sensor (DTS) thermal
> +	  readings of the CPU package and CPU cores that are accessible via
> +	  the processor PECI interface.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called peci-cputemp.
> +
> +config SENSORS_PECI
> +	tristate
> diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
> new file mode 100644
> index 000000000000..e8a0ada5ab1f
> --- /dev/null
> +++ b/drivers/hwmon/peci/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +peci-cputemp-y := cputemp.o
> +
> +obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
> diff --git a/drivers/hwmon/peci/common.h b/drivers/hwmon/peci/common.h
> new file mode 100644
> index 000000000000..734506b0eca2
> --- /dev/null
> +++ b/drivers/hwmon/peci/common.h
> @@ -0,0 +1,58 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright (c) 2021 Intel Corporation */
> +
> +#include <linux/mutex.h>
> +#include <linux/types.h>
> +
> +#ifndef __PECI_HWMON_COMMON_H
> +#define __PECI_HWMON_COMMON_H
> +
> +#define PECI_HWMON_UPDATE_INTERVAL	HZ
> +
> +/**
> + * struct peci_sensor_state - PECI state information
> + * @valid: flag to indicate the sensor value is valid
> + * @last_updated: time of the last update in jiffies
> + * @lock: mutex to protect sensor access
> + */
> +struct peci_sensor_state {
> +	bool valid;
> +	unsigned long last_updated;
> +	struct mutex lock; /* protect sensor access */
> +};
> +
> +/**
> + * struct peci_sensor_data - PECI sensor information
> + * @value: sensor value in milli units
> + * @state: sensor update state
> + */
> +
> +struct peci_sensor_data {
> +	s32 value;
> +	struct peci_sensor_state state;
> +};
> +
> +/**
> + * peci_sensor_need_update() - check whether sensor update is needed or not
> + * @sensor: pointer to sensor data struct
> + *
> + * Return: true if update is needed, false if not.
> + */
> +
> +static inline bool peci_sensor_need_update(struct peci_sensor_state *state)
> +{
> +	return !state->valid ||
> +	       time_after(jiffies, state->last_updated + PECI_HWMON_UPDATE_INTERVAL);
> +}
> +
> +/**
> + * peci_sensor_mark_updated() - mark the sensor is updated
> + * @sensor: pointer to sensor data struct
> + */
> +static inline void peci_sensor_mark_updated(struct peci_sensor_state *state)
> +{
> +	state->valid = true;
> +	state->last_updated = jiffies;
> +}
> +
> +#endif /* __PECI_HWMON_COMMON_H */
> diff --git a/drivers/hwmon/peci/cputemp.c b/drivers/hwmon/peci/cputemp.c
> new file mode 100644
> index 000000000000..9c6858a9fb6d
> --- /dev/null
> +++ b/drivers/hwmon/peci/cputemp.c
> @@ -0,0 +1,591 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2018-2021 Intel Corporation
> +
> +#include <linux/auxiliary_bus.h>
> +#include <linux/bitfield.h>
> +#include <linux/bitops.h>
> +#include <linux/hwmon.h>
> +#include <linux/jiffies.h>
> +#include <linux/module.h>
> +#include <linux/peci.h>
> +#include <linux/peci-cpu.h>
> +#include <linux/units.h>
> +#include <linux/x86/intel-family.h>
> +
> +#include "common.h"
> +
> +#define CORE_NUMS_MAX		64
> +
> +#define BASE_CHANNEL_NUMS	5
> +#define CPUTEMP_CHANNEL_NUMS	(BASE_CHANNEL_NUMS + CORE_NUMS_MAX)
> +
> +#define TEMP_TARGET_FAN_TEMP_MASK	GENMASK(15, 8)
> +#define TEMP_TARGET_REF_TEMP_MASK	GENMASK(23, 16)
> +#define TEMP_TARGET_TJ_OFFSET_MASK	GENMASK(29, 24)
> +
> +#define DTS_MARGIN_MASK		GENMASK(15, 0)
> +#define PCS_MODULE_TEMP_MASK	GENMASK(15, 0)
> +
> +#define DTS_FIXED_POINT_FRACTION	64
> +
> +struct resolved_cores_reg {
> +	u8 bus;
> +	u8 dev;
> +	u8 func;
> +	u8 offset;
> +};
> +
> +struct cpu_info {
> +	struct resolved_cores_reg *reg;
> +	u8 min_peci_revision;
> +};
> +
> +struct peci_temp_target {
> +	s32 tcontrol;
> +	s32 tthrottle;
> +	s32 tjmax;
> +	struct peci_sensor_state state;
> +};
> +
> +enum peci_temp_target_type {
> +	tcontrol_type,
> +	tthrottle_type,
> +	tjmax_type,
> +	crit_hyst_type,
> +};
> +
> +struct peci_cputemp {
> +	struct peci_device *peci_dev;
> +	struct device *dev;
> +	const char *name;
> +	const struct cpu_info *gen_info;
> +	struct {
> +		struct peci_temp_target target;
> +		struct peci_sensor_data die;
> +		struct peci_sensor_data dts;
> +		struct peci_sensor_data core[CORE_NUMS_MAX];
> +	} temp;
> +	const char **coretemp_label;
> +	DECLARE_BITMAP(core_mask, CORE_NUMS_MAX);
> +};
> +
> +enum cputemp_channels {
> +	channel_die,
> +	channel_dts,
> +	channel_tcontrol,
> +	channel_tthrottle,
> +	channel_tjmax,
> +	channel_core,
> +};
> +
> +static const char * const cputemp_label[BASE_CHANNEL_NUMS] = {
> +	"Die",
> +	"DTS",
> +	"Tcontrol",
> +	"Tthrottle",
> +	"Tjmax",
> +};
> +
> +static int update_temp_target(struct peci_cputemp *priv)
> +{
> +	s32 tthrottle_offset, tcontrol_margin;
> +	u32 pcs;
> +	int ret;
> +
> +	if (!peci_sensor_need_update(&priv->temp.target.state))
> +		return 0;
> +
> +	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_TEMP_TARGET, 0, &pcs);
> +	if (ret)
> +		return ret;
> +
> +	priv->temp.target.tjmax =
> +		FIELD_GET(TEMP_TARGET_REF_TEMP_MASK, pcs) * MILLIDEGREE_PER_DEGREE;
> +
> +	tcontrol_margin = FIELD_GET(TEMP_TARGET_FAN_TEMP_MASK, pcs);
> +	tcontrol_margin = sign_extend32(tcontrol_margin, 7) * MILLIDEGREE_PER_DEGREE;
> +	priv->temp.target.tcontrol = priv->temp.target.tjmax - tcontrol_margin;
> +
> +	tthrottle_offset = FIELD_GET(TEMP_TARGET_TJ_OFFSET_MASK, pcs) * MILLIDEGREE_PER_DEGREE;
> +	priv->temp.target.tthrottle = priv->temp.target.tjmax - tthrottle_offset;
> +
> +	peci_sensor_mark_updated(&priv->temp.target.state);
> +
> +	return 0;
> +}
> +
> +static int get_temp_target(struct peci_cputemp *priv, enum peci_temp_target_type type, long *val)
> +{
> +	int ret;
> +
> +	mutex_lock(&priv->temp.target.state.lock);
> +
> +	ret = update_temp_target(priv);
> +	if (ret)
> +		goto unlock;
> +
> +	switch (type) {
> +	case tcontrol_type:
> +		*val = priv->temp.target.tcontrol;
> +		break;
> +	case tthrottle_type:
> +		*val = priv->temp.target.tthrottle;
> +		break;
> +	case tjmax_type:
> +		*val = priv->temp.target.tjmax;
> +		break;
> +	case crit_hyst_type:
> +		*val = priv->temp.target.tjmax - priv->temp.target.tcontrol;
> +		break;
> +	default:
> +		ret = -EOPNOTSUPP;
> +		break;
> +	}
> +unlock:
> +	mutex_unlock(&priv->temp.target.state.lock);
> +
> +	return ret;
> +}
> +
> +/*
> + * Processors return a value of DTS reading in S10.6 fixed point format
> + * (16 bits: 10-bit signed magnitude, 6-bit fraction).
> + * Error codes:
> + *   0x8000: General sensor error
> + *   0x8001: Reserved
> + *   0x8002: Underflow on reading value
> + *   0x8003-0x81ff: Reserved
> + */
> +static bool dts_valid(s32 val)
> +{
> +	return val < 0x8000 || val > 0x81ff;
> +}
> +
> +static s32 dts_to_millidegree(s32 val)
> +{
> +	return sign_extend32(val, 15) * MILLIDEGREE_PER_DEGREE / DTS_FIXED_POINT_FRACTION;
> +}
> +
> +static int get_die_temp(struct peci_cputemp *priv, long *val)
> +{
> +	long tjmax;
> +	s16 temp;
> +	int ret;
> +
> +	mutex_lock(&priv->temp.die.state.lock);
> +	if (!peci_sensor_need_update(&priv->temp.die.state))
> +		goto skip_update;
> +
> +	ret = peci_temp_read(priv->peci_dev, &temp);
> +	if (ret)
> +		goto err_unlock;
> +
> +	if (!dts_valid(temp)) {
> +		ret = -EIO;
> +		goto err_unlock;
> +	}
> +
> +	ret = get_temp_target(priv, tjmax_type, &tjmax);
> +	if (ret)
> +		goto err_unlock;
> +
> +	priv->temp.die.value = (s32)tjmax + dts_to_millidegree(temp);
> +
> +	peci_sensor_mark_updated(&priv->temp.die.state);
> +
> +skip_update:
> +	*val = priv->temp.die.value;
> +	mutex_unlock(&priv->temp.die.state.lock);
> +
> +	return 0;
> +
> +err_unlock:
> +	mutex_unlock(&priv->temp.die.state.lock);
> +	return ret;
> +}
> +
> +static int get_dts(struct peci_cputemp *priv, long *val)
> +{
> +	s32 dts_margin;
> +	long tcontrol;
> +	u32 pcs;
> +	int ret;
> +
> +	mutex_lock(&priv->temp.dts.state.lock);
> +	if (!peci_sensor_need_update(&priv->temp.dts.state))
> +		goto skip_update;
> +
> +	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_THERMAL_MARGIN, 0, &pcs);
> +	if (ret)
> +		goto err_unlock;
> +
> +	dts_margin = FIELD_GET(DTS_MARGIN_MASK, pcs);
> +	if (!dts_valid(dts_margin)) {
> +		ret = -EIO;
> +		goto err_unlock;
> +	}
> +
> +	ret = get_temp_target(priv, tcontrol_type, &tcontrol);
> +	if (ret)
> +		goto err_unlock;
> +
> +	/* Note that the tcontrol should be available before calling it */
> +	priv->temp.dts.value = (s32)tcontrol - dts_to_millidegree(dts_margin);
> +
> +	peci_sensor_mark_updated(&priv->temp.dts.state);
> +
> +skip_update:
> +	*val = priv->temp.dts.value;
> +	mutex_unlock(&priv->temp.dts.state.lock);
> +
> +	return 0;
> +
> +err_unlock:
> +	mutex_unlock(&priv->temp.dts.state.lock);
> +	return ret;

Simplify (see below)

> +}
> +
> +static int get_core_temp(struct peci_cputemp *priv, int core_index, long *val)
> +{
> +	s32 core_dts_margin;
> +	long tjmax;
> +	u32 pcs;
> +	int ret;

	int ret = 0;

to handle simplification below.

> +
> +	mutex_lock(&priv->temp.core[core_index].state.lock);
> +	if (!peci_sensor_need_update(&priv->temp.core[core_index].state))
> +		goto skip_update;
> +
> +	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_MODULE_TEMP, core_index, &pcs);
> +	if (ret)
> +		goto err_unlock;
> +
> +	core_dts_margin = FIELD_GET(PCS_MODULE_TEMP_MASK, pcs);
> +	if (!dts_valid(core_dts_margin)) {
> +		ret = -EIO;
> +		goto err_unlock;
> +	}
> +
> +	ret = get_temp_target(priv, tjmax_type, &tjmax);
> +	if (ret)
> +		goto err_unlock;
> +
> +	/* Note that the tjmax should be available before calling it */
> +	priv->temp.core[core_index].value = (s32)tjmax + dts_to_millidegree(core_dts_margin);
> +
> +	peci_sensor_mark_updated(&priv->temp.core[core_index].state);
> +
> +skip_update:
> +	*val = priv->temp.core[core_index].value;
> +	mutex_unlock(&priv->temp.core[core_index].state.lock);
> +
> +	return 0;
> +
> +err_unlock:
> +	mutex_unlock(&priv->temp.core[core_index].state.lock);
> +	return ret;

Simplify:

skip_update:
	*val = priv->temp.core[core_index].value;
err_unlock:
	mutex_unlock(&priv->temp.core[core_index].state.lock);
	return ret;

> +}
> +
> +static int cputemp_read_string(struct device *dev, enum hwmon_sensor_types type,
> +			       u32 attr, int channel, const char **str)
> +{
> +	struct peci_cputemp *priv = dev_get_drvdata(dev);
> +
> +	if (attr != hwmon_temp_label)
> +		return -EOPNOTSUPP;
> +
> +	*str = channel < channel_core ?
> +		cputemp_label[channel] : priv->coretemp_label[channel - channel_core];
> +
> +	return 0;
> +}
> +
> +static int cputemp_read(struct device *dev, enum hwmon_sensor_types type,
> +			u32 attr, int channel, long *val)
> +{
> +	struct peci_cputemp *priv = dev_get_drvdata(dev);
> +
> +	switch (attr) {
> +	case hwmon_temp_input:
> +		switch (channel) {
> +		case channel_die:
> +			return get_die_temp(priv, val);
> +		case channel_dts:
> +			return get_dts(priv, val);
> +		case channel_tcontrol:
> +			return get_temp_target(priv, tcontrol_type, val);
> +		case channel_tthrottle:
> +			return get_temp_target(priv, tthrottle_type, val);
> +		case channel_tjmax:
> +			return get_temp_target(priv, tjmax_type, val);
> +		default:
> +			return get_core_temp(priv, channel - channel_core, val);
> +		}
> +		break;
> +	case hwmon_temp_max:
> +		return get_temp_target(priv, tcontrol_type, val);
> +	case hwmon_temp_crit:
> +		return get_temp_target(priv, tjmax_type, val);
> +	case hwmon_temp_crit_hyst:
> +		return get_temp_target(priv, crit_hyst_type, val);
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	return 0;
> +}
> +
> +static umode_t cputemp_is_visible(const void *data, enum hwmon_sensor_types type,
> +				  u32 attr, int channel)
> +{
> +	const struct peci_cputemp *priv = data;
> +
> +	if (channel > CPUTEMP_CHANNEL_NUMS)
> +		return 0;
> +
> +	if (channel < channel_core)
> +		return 0444;
> +
> +	if (test_bit(channel - channel_core, priv->core_mask))
> +		return 0444;
> +
> +	return 0;
> +}
> +
> +static int init_core_mask(struct peci_cputemp *priv)
> +{
> +	struct peci_device *peci_dev = priv->peci_dev;
> +	struct resolved_cores_reg *reg = priv->gen_info->reg;
> +	u64 core_mask;
> +	u32 data;
> +	int ret;
> +
> +	/* Get the RESOLVED_CORES register value */
> +	switch (peci_dev->info.model) {
> +	case INTEL_FAM6_ICELAKE_X:
> +	case INTEL_FAM6_ICELAKE_D:
> +		ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg->dev,
> +					     reg->func, reg->offset + 4, &data);
> +		if (ret)
> +			return ret;
> +
> +		core_mask = (u64)data << 32;
> +
> +		ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg->dev,
> +					     reg->func, reg->offset, &data);
> +		if (ret)
> +			return ret;
> +
> +		core_mask |= data;
> +
> +		break;
> +	default:
> +		ret = peci_pci_local_read(peci_dev, reg->bus, reg->dev,
> +					  reg->func, reg->offset, &data);
> +		if (ret)
> +			return ret;
> +
> +		core_mask = data;
> +
> +		break;
> +	}
> +
> +	if (!core_mask)
> +		return -EIO;
> +
> +	bitmap_from_u64(priv->core_mask, core_mask);
> +
> +	return 0;
> +}
> +
> +static int create_temp_label(struct peci_cputemp *priv)
> +{
> +	unsigned long core_max = find_last_bit(priv->core_mask, CORE_NUMS_MAX);
> +	int i;
> +
> +	priv->coretemp_label = devm_kzalloc(priv->dev, core_max * sizeof(char *), GFP_KERNEL);
> +	if (!priv->coretemp_label)
> +		return -ENOMEM;
> +
> +	for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX) {
> +		priv->coretemp_label[i] = devm_kasprintf(priv->dev, GFP_KERNEL, "Core %d", i);
> +		if (!priv->coretemp_label[i])
> +			return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +static void check_resolved_cores(struct peci_cputemp *priv)
> +{
> +	/*
> +	 * Failure to resolve cores is non-critical, we're still able to
> +	 * provide other sensor data.
> +	 */
> +
> +	if (init_core_mask(priv))
> +		return;
> +
> +	if (create_temp_label(priv))
> +		bitmap_zero(priv->core_mask, CORE_NUMS_MAX);
> +}
> +
> +static void sensor_init(struct peci_cputemp *priv)
> +{
> +	int i;
> +
> +	mutex_init(&priv->temp.target.state.lock);
> +	mutex_init(&priv->temp.die.state.lock);
> +	mutex_init(&priv->temp.dts.state.lock);
> +
> +	for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX)
> +		mutex_init(&priv->temp.core[i].state.lock);
> +}
> +
> +static const struct hwmon_ops peci_cputemp_ops = {
> +	.is_visible = cputemp_is_visible,
> +	.read_string = cputemp_read_string,
> +	.read = cputemp_read,
> +};
> +
> +static const u32 peci_cputemp_temp_channel_config[] = {
> +	/* Die temperature */
> +	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST,
> +	/* DTS margin */
> +	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST,
> +	/* Tcontrol temperature */
> +	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_CRIT,
> +	/* Tthrottle temperature */
> +	HWMON_T_LABEL | HWMON_T_INPUT,
> +	/* Tjmax temperature */
> +	HWMON_T_LABEL | HWMON_T_INPUT,
> +	/* Core temperature - for all core channels */
> +	[channel_core ... CPUTEMP_CHANNEL_NUMS - 1] = HWMON_T_LABEL | HWMON_T_INPUT,
> +	0
> +};
> +
> +static const struct hwmon_channel_info peci_cputemp_temp_channel = {
> +	.type = hwmon_temp,
> +	.config = peci_cputemp_temp_channel_config,
> +};
> +
> +static const struct hwmon_channel_info *peci_cputemp_info[] = {
> +	&peci_cputemp_temp_channel,
> +	NULL
> +};
> +
> +static const struct hwmon_chip_info peci_cputemp_chip_info = {
> +	.ops = &peci_cputemp_ops,
> +	.info = peci_cputemp_info,
> +};
> +
> +static int peci_cputemp_probe(struct auxiliary_device *adev,
> +			      const struct auxiliary_device_id *id)
> +{
> +	struct device *dev = &adev->dev;
> +	struct peci_device *peci_dev = to_peci_device(dev->parent);
> +	struct peci_cputemp *priv;
> +	struct device *hwmon_dev;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_cputemp.cpu%d",
> +				    peci_dev->info.socket_id);
> +	if (!priv->name)
> +		return -ENOMEM;
> +
> +	priv->dev = dev;
> +	priv->peci_dev = peci_dev;
> +	priv->gen_info = (const struct cpu_info *)id->driver_data;
> +
> +	/*
> +	 * This is just a sanity check. Since we're using commands that are
> +	 * guaranteed to be supported on a given platform, we should never see
> +	 * revision lower than expected.
> +	 */
> +	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
> +		dev_warn(priv->dev,
> +			 "Unexpected PECI revision %#x, some features may be unavailable\n",
> +			 peci_dev->info.peci_revision);
> +
> +	check_resolved_cores(priv);
> +
> +	sensor_init(priv);
> +
> +	hwmon_dev = devm_hwmon_device_register_with_info(priv->dev, priv->name,
> +							 priv, &peci_cputemp_chip_info, NULL);
> +
> +	return PTR_ERR_OR_ZERO(hwmon_dev);
> +}
> +
> +/*
> + * RESOLVED_CORES PCI configuration register may have different location on
> + * different platforms.
> + */
> +static struct resolved_cores_reg resolved_cores_reg_hsx = {
> +	.bus = 1,
> +	.dev = 30,
> +	.func = 3,
> +	.offset = 0xb4,
> +};
> +
> +static struct resolved_cores_reg resolved_cores_reg_icx = {
> +	.bus = 14,
> +	.dev = 30,
> +	.func = 3,
> +	.offset = 0xd0,
> +};
> +
> +static const struct cpu_info cpu_hsx = {
> +	.reg		= &resolved_cores_reg_hsx,
> +	.min_peci_revision = 0x33,
> +};
> +
> +static const struct cpu_info cpu_icx = {
> +	.reg		= &resolved_cores_reg_icx,
> +	.min_peci_revision = 0x40,
> +};
> +
> +static const struct auxiliary_device_id peci_cputemp_ids[] = {
> +	{
> +		.name = "peci_cpu.cputemp.hsx",
> +		.driver_data = (kernel_ulong_t)&cpu_hsx,
> +	},
> +	{
> +		.name = "peci_cpu.cputemp.bdx",
> +		.driver_data = (kernel_ulong_t)&cpu_hsx,
> +	},
> +	{
> +		.name = "peci_cpu.cputemp.bdxd",
> +		.driver_data = (kernel_ulong_t)&cpu_hsx,
> +	},
> +	{
> +		.name = "peci_cpu.cputemp.skx",
> +		.driver_data = (kernel_ulong_t)&cpu_hsx,
> +	},
> +	{
> +		.name = "peci_cpu.cputemp.icx",
> +		.driver_data = (kernel_ulong_t)&cpu_icx,
> +	},
> +	{
> +		.name = "peci_cpu.cputemp.icxd",
> +		.driver_data = (kernel_ulong_t)&cpu_icx,
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(auxiliary, peci_cputemp_ids);
> +
> +static struct auxiliary_driver peci_cputemp_driver = {
> +	.probe		= peci_cputemp_probe,
> +	.id_table	= peci_cputemp_ids,
> +};
> +
> +module_auxiliary_driver(peci_cputemp_driver);
> +
> +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
> +MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
> +MODULE_DESCRIPTION("PECI cputemp driver");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS(PECI_CPU);
> 



From dqfext at gmail.com  Tue Aug  3 08:29:01 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue,  3 Aug 2021 23:29:01 +0800
Subject: [PATCH net-next 4/4] net: dsa: mt7530: always install FDB entries
 with IVL and FID 1
In-Reply-To: <20210803144552.fluxxfoey2tbqyyu@skbuf>
References: <20210803124022.2912298-1-dqfext@gmail.com>
 <20210803124022.2912298-5-dqfext@gmail.com>
 <20210803144552.fluxxfoey2tbqyyu@skbuf>
Message-ID: <20210803152901.2913035-1-dqfext@gmail.com>

On Tue, Aug 03, 2021 at 05:45:52PM +0300, Vladimir Oltean wrote:
> 
> Maybe it would be good to resend with a set of #defines for the
> standalone/bridged port FID values after all, what do you think?

Will do.


From will at kernel.org  Tue Aug  3 08:30:37 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 3 Aug 2021 16:30:37 +0100
Subject: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU schedule out
In-Reply-To: <ee2863107d614ef8a36006b5aa912eca@huawei.com>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
 <20210803114034.GB30853@willie-the-truck>
 <ee2863107d614ef8a36006b5aa912eca@huawei.com>
Message-ID: <20210803153036.GA31125@willie-the-truck>

On Tue, Aug 03, 2021 at 12:55:25PM +0000, Shameerali Kolothum Thodi wrote:
> > > diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
> > > index 5584e84aed95..5fd51f5445c1 100644
> > > --- a/arch/arm64/kvm/vmid.c
> > > +++ b/arch/arm64/kvm/vmid.c
> > > @@ -116,6 +116,12 @@ static u64 new_vmid(struct kvm_vmid
> > *kvm_vmid)
> > >  	return idx2vmid(vmid) | generation;
> > >  }
> > >
> > > +/* Call with preemption disabled */
> > > +void kvm_arm_vmid_clear_active(void)
> > > +{
> > > +	atomic64_set(this_cpu_ptr(&active_vmids), 0);
> > > +}
> > 
> > I think this is very broken, as it will force everybody to take the
> > slow-path when they see an active_vmid of 0.
> 
> Yes. I have seen that happening in my test setup.

Why didn't you say so?!

> > It also doesn't solve the issue I mentioned before, as an active_vmid of 0
> > means that the reserved vmid is preserved.
> > 
> > Needs more thought...
> 
> How about we clear all the active_vmids in kvm_arch_free_vm() if it
> matches the kvm_vmid->id ? But we may have to hold the lock 
> there

I think we have to be really careful not to run into the "suspended
animation" problem described in ae120d9edfe9 ("ARM: 7767/1: let the ASID
allocator handle suspended animation") if we go down this road.

Maybe something along the lines of:

ROLLOVER

  * Take lock
  * Inc generation
    => This will force everybody down the slow path
  * Record active VMIDs
  * Broadcast TLBI
    => Only active VMIDs can be dirty
    => Reserve active VMIDs and mark as allocated

VCPU SCHED IN

  * Set active VMID
  * Check generation
  * If mismatch then:
        * Take lock
        * Try to match a reserved VMID
        * If no reserved VMID, allocate new

VCPU SCHED OUT

  * Clear active VMID

but I'm not daft enough to think I got it right first time. I think it
needs both implementing *and* modelling in TLA+ before we merge it!

Will


From will at kernel.org  Tue Aug  3 08:32:22 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 3 Aug 2021 16:32:22 +0100
Subject: [PATCH v3 10/15] KVM: arm64: Guest exit handlers for nVHE hyp
In-Reply-To: <20210719160346.609914-11-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-11-tabba@google.com>
Message-ID: <20210803153222.GB31125@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:41PM +0100, Fuad Tabba wrote:
> Add an array of pointers to handlers for various trap reasons in
> nVHE code.
> 
> The current code selects how to fixup a guest on exit based on a
> series of if/else statements. Future patches will also require
> different handling for guest exists. Create an array of handlers
> to consolidate them.
> 
> No functional change intended as the array isn't populated yet.
> 
> Acked-by: Will Deacon <will at kernel.org>
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/kvm/hyp/include/hyp/switch.h | 43 +++++++++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/switch.c        | 35 ++++++++++++++++++++
>  2 files changed, 78 insertions(+)

Definitely keep my Ack on this, but Clang just chucked out a warning due to:

> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index a0e78a6027be..5a2b89b96c67 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -409,6 +409,46 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
>  	return true;
>  }
>  
> +typedef int (*exit_handle_fn)(struct kvm_vcpu *);
> +
> +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu);

and:

> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index 86f3d6482935..36da423006bd 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -158,6 +158,41 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
>  		write_sysreg(pmu->events_host, pmcntenset_el0);
>  }
>  
> +typedef int (*exit_handle_fn)(struct kvm_vcpu *);

Which leads to:

arch/arm64/kvm/hyp/nvhe/switch.c:189:15: warning: redefinition of typedef 'exit_handle_fn' is a C11 feature [-Wtypedef-redefinition]
typedef int (*exit_handle_fn)(struct kvm_vcpu *);
              ^
./arch/arm64/kvm/hyp/include/hyp/switch.h:416:15: note: previous definition is here
typedef int (*exit_handle_fn)(struct kvm_vcpu *);
              ^
1 warning generated.

So I guess just pick your favourite?

Will


From linux at roeck-us.net  Tue Aug  3 08:39:37 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Tue, 3 Aug 2021 08:39:37 -0700
Subject: [PATCH v2 13/15] hwmon: peci: Add dimmtemp driver
In-Reply-To: <20210803113134.2262882-14-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-14-iwona.winiarska@intel.com>
Message-ID: <20210803153937.GA337938@roeck-us.net>

On Tue, Aug 03, 2021 at 01:31:32PM +0200, Iwona Winiarska wrote:
> Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that
> are accessible via the processor PECI interface.
> 
> The main use case for the driver (and PECI interface) is out-of-band
> management, where we're able to obtain thermal readings from an external
> entity connected with PECI, e.g. BMC on server platforms.
> 
> Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> ---
> Note that the timeout was completely removed - we're going to probe
> for detected DIMMs every 5 seconds until we reach "stable" state of
> either getting correct DIMM data or getting all -EINVAL (which
> suggest that the CPU doesn't have any DIMMs).
> 
>  drivers/hwmon/peci/Kconfig    |  13 +
>  drivers/hwmon/peci/Makefile   |   2 +
>  drivers/hwmon/peci/dimmtemp.c | 614 ++++++++++++++++++++++++++++++++++
>  3 files changed, 629 insertions(+)
>  create mode 100644 drivers/hwmon/peci/dimmtemp.c
> 
> diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
> index e10eed68d70a..9d32a57badfe 100644
> --- a/drivers/hwmon/peci/Kconfig
> +++ b/drivers/hwmon/peci/Kconfig
> @@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP
>  	  This driver can also be built as a module. If so, the module
>  	  will be called peci-cputemp.
>  
> +config SENSORS_PECI_DIMMTEMP
> +	tristate "PECI DIMM temperature monitoring client"
> +	depends on PECI
> +	select SENSORS_PECI
> +	select PECI_CPU
> +	help
> +	  If you say yes here you get support for the generic Intel PECI hwmon
> +	  driver which provides Temperature Sensor on DIMM readings that are
> +	  accessible via the processor PECI interface.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called peci-dimmtemp.
> +
>  config SENSORS_PECI
>  	tristate
> diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
> index e8a0ada5ab1f..191cfa0227f3 100644
> --- a/drivers/hwmon/peci/Makefile
> +++ b/drivers/hwmon/peci/Makefile
> @@ -1,5 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  
>  peci-cputemp-y := cputemp.o
> +peci-dimmtemp-y := dimmtemp.o
>  
>  obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
> +obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)	+= peci-dimmtemp.o
> diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c
> new file mode 100644
> index 000000000000..6264c29bb6c0
> --- /dev/null
> +++ b/drivers/hwmon/peci/dimmtemp.c
> @@ -0,0 +1,614 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2018-2021 Intel Corporation
> +
> +#include <linux/auxiliary_bus.h>
> +#include <linux/bitfield.h>
> +#include <linux/bitops.h>
> +#include <linux/hwmon.h>
> +#include <linux/jiffies.h>
> +#include <linux/module.h>
> +#include <linux/peci.h>
> +#include <linux/peci-cpu.h>
> +#include <linux/units.h>
> +#include <linux/workqueue.h>
> +#include <linux/x86/intel-family.h>
> +
> +#include "common.h"
> +
> +#define DIMM_MASK_CHECK_DELAY_JIFFIES	msecs_to_jiffies(5000)
> +
> +/* Max number of channel ranks and DIMM index per channel */
> +#define CHAN_RANK_MAX_ON_HSX	8
> +#define DIMM_IDX_MAX_ON_HSX	3
> +#define CHAN_RANK_MAX_ON_BDX	4
> +#define DIMM_IDX_MAX_ON_BDX	3
> +#define CHAN_RANK_MAX_ON_BDXD	2
> +#define DIMM_IDX_MAX_ON_BDXD	2
> +#define CHAN_RANK_MAX_ON_SKX	6
> +#define DIMM_IDX_MAX_ON_SKX	2
> +#define CHAN_RANK_MAX_ON_ICX	8
> +#define DIMM_IDX_MAX_ON_ICX	2
> +#define CHAN_RANK_MAX_ON_ICXD	4
> +#define DIMM_IDX_MAX_ON_ICXD	2
> +
> +#define CHAN_RANK_MAX		CHAN_RANK_MAX_ON_HSX
> +#define DIMM_IDX_MAX		DIMM_IDX_MAX_ON_HSX
> +#define DIMM_NUMS_MAX		(CHAN_RANK_MAX * DIMM_IDX_MAX)
> +
> +#define CPU_SEG_MASK		GENMASK(23, 16)
> +#define GET_CPU_SEG(x)		(((x) & CPU_SEG_MASK) >> 16)
> +#define CPU_BUS_MASK		GENMASK(7, 0)
> +#define GET_CPU_BUS(x)		((x) & CPU_BUS_MASK)
> +
> +#define DIMM_TEMP_MAX		GENMASK(15, 8)
> +#define DIMM_TEMP_CRIT		GENMASK(23, 16)
> +#define GET_TEMP_MAX(x)		(((x) & DIMM_TEMP_MAX) >> 8)
> +#define GET_TEMP_CRIT(x)	(((x) & DIMM_TEMP_CRIT) >> 16)
> +
> +struct peci_dimmtemp;
> +
> +struct dimm_info {
> +	int chan_rank_max;
> +	int dimm_idx_max;
> +	u8 min_peci_revision;
> +	int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order,
> +			       int chan_rank, u32 *data);
> +};
> +
> +struct peci_dimm_thresholds {
> +	long temp_max;
> +	long temp_crit;
> +	struct peci_sensor_state state;
> +};
> +
> +enum peci_dimm_threshold_type {
> +	temp_max_type,
> +	temp_crit_type,
> +};
> +
> +struct peci_dimmtemp {
> +	struct peci_device *peci_dev;
> +	struct device *dev;
> +	const char *name;
> +	const struct dimm_info *gen_info;
> +	struct delayed_work detect_work;
> +	struct {
> +		struct peci_sensor_data temp;
> +		struct peci_dimm_thresholds thresholds;
> +	} dimm[DIMM_NUMS_MAX];
> +	char **dimmtemp_label;
> +	DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX);
> +};
> +
> +static u8 __dimm_temp(u32 reg, int dimm_order)
> +{
> +	return (reg >> (dimm_order * 8)) & 0xff;
> +}
> +
> +static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long *val)
> +{
> +	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
> +	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
> +	u32 data;
> +	int ret;

	int ret = 0;

> +
> +	mutex_lock(&priv->dimm[dimm_no].temp.state.lock);
> +	if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state))
> +		goto skip_update;
> +
> +	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &data);
> +	if (ret) {
> +		mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
> +		return ret;
> +	}

	if (ret)
		goto unlock;

> +
> +	priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) * MILLIDEGREE_PER_DEGREE;
> +
> +	peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state);
> +
> +skip_update:
> +	*val = priv->dimm[dimm_no].temp.value;

unlock:
> +	mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
> +	return 0;

	return ret;

> +}
> +
> +static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
> +{
> +	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
> +	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
> +	u32 data;
> +	int ret;
> +
> +	if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state))
> +		return 0;
> +
> +	ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank, &data);
> +	if (ret == -ENODATA) /* Use default or previous value */
> +		return 0;
> +	if (ret)
> +		return ret;
> +
> +	priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) * MILLIDEGREE_PER_DEGREE;
> +	priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) * MILLIDEGREE_PER_DEGREE;
> +
> +	peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state);
> +
> +	return 0;
> +}
> +
> +static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum peci_dimm_threshold_type type,
> +			       int dimm_no, long *val)
> +{
> +	int ret;
> +
> +	mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock);
> +	ret = update_thresholds(priv, dimm_no);
> +	if (ret)
> +		goto unlock;
> +
> +	switch (type) {
> +	case temp_max_type:
> +		*val = priv->dimm[dimm_no].thresholds.temp_max;
> +		break;
> +	case temp_crit_type:
> +		*val = priv->dimm[dimm_no].thresholds.temp_crit;
> +		break;
> +	default:
> +		ret = -EOPNOTSUPP;
> +		break;
> +	}
> +unlock:
> +	mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock);
> +
> +	return ret;
> +}
> +
> +static int dimmtemp_read_string(struct device *dev,
> +				enum hwmon_sensor_types type,
> +				u32 attr, int channel, const char **str)
> +{
> +	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
> +
> +	if (attr != hwmon_temp_label)
> +		return -EOPNOTSUPP;
> +
> +	*str = (const char *)priv->dimmtemp_label[channel];
> +
> +	return 0;
> +}
> +
> +static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type,
> +			 u32 attr, int channel, long *val)
> +{
> +	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
> +
> +	switch (attr) {
> +	case hwmon_temp_input:
> +		return get_dimm_temp(priv, channel, val);
> +	case hwmon_temp_max:
> +		return get_dimm_thresholds(priv, temp_max_type, channel, val);
> +	case hwmon_temp_crit:
> +		return get_dimm_thresholds(priv, temp_crit_type, channel, val);
> +	default:
> +		break;
> +	}
> +
> +	return -EOPNOTSUPP;
> +}
> +
> +static umode_t dimmtemp_is_visible(const void *data, enum hwmon_sensor_types type,
> +				   u32 attr, int channel)
> +{
> +	const struct peci_dimmtemp *priv = data;
> +
> +	if (test_bit(channel, priv->dimm_mask))
> +		return 0444;
> +
> +	return 0;
> +}
> +
> +static const struct hwmon_ops peci_dimmtemp_ops = {
> +	.is_visible = dimmtemp_is_visible,
> +	.read_string = dimmtemp_read_string,
> +	.read = dimmtemp_read,
> +};
> +
> +static int check_populated_dimms(struct peci_dimmtemp *priv)
> +{
> +	int chan_rank_max = priv->gen_info->chan_rank_max;
> +	int dimm_idx_max = priv->gen_info->dimm_idx_max;
> +	u32 chan_rank_empty = 0;
> +	u64 dimm_mask = 0;
> +	int chan_rank, dimm_idx, ret;
> +	u32 pcs;
> +
> +	BUILD_BUG_ON(CHAN_RANK_MAX > 32);
> +	BUILD_BUG_ON(DIMM_NUMS_MAX > 64);

I don't immediately see the value of those build bugs. What happens if
CHAN_RANK_MAX > 32 or DIMM_NUMS_MAX > 64 ? Where do those limits come
from ?

> +	if (chan_rank_max * dimm_idx_max > DIMM_NUMS_MAX) {
> +		WARN_ONCE(1, "Unsupported number of DIMMs");

Maybe display the values (chan_rank_max and dimm_idx_max).

> +		return -EINVAL;
> +	}
> +
> +	for (chan_rank = 0; chan_rank < chan_rank_max; chan_rank++) {
> +		ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &pcs);
> +		if (ret) {
> +			/*
> +			 * Overall, we expect either success or -EINVAL in
> +			 * order to determine whether DIMM is populated or not.
> +			 * For anything else - we fall back to defering the

Why " - " ?

> +			 * detection to be performed at a later point in time.
> +			 */
> +			if (ret == -EINVAL) {
> +				chan_rank_empty |= BIT(chan_rank);
> +				continue;
> +			}
> +
> +			return -EAGAIN;
> +		}
> +
> +		for (dimm_idx = 0; dimm_idx < dimm_idx_max; dimm_idx++)
> +			if (__dimm_temp(pcs, dimm_idx))
> +				dimm_mask |= BIT(chan_rank * dimm_idx_max + dimm_idx);
> +	}
> +
> +	/* If we got all -EINVALs, it means that the CPU doesn't have any DIMMs. */
> +	if (chan_rank_empty == GENMASK(chan_rank_max - 1, 0))
> +		return -ENODEV;
> +
> +	/*
> +	 * It's possible that memory training is not done yet. In this case we
> +	 * defer the detection to be performed at a later point in time.
> +	 */
> +	if (!dimm_mask)
> +		return -EAGAIN;
> +
> +	dev_dbg(priv->dev, "Scanned populated DIMMs: %#llx\n", dimm_mask);
> +
> +	bitmap_from_u64(priv->dimm_mask, dimm_mask);
> +
> +	return 0;
> +}
> +
> +static int create_dimm_temp_label(struct peci_dimmtemp *priv, int chan)
> +{
> +	int rank = chan / priv->gen_info->dimm_idx_max;
> +	int idx = chan % priv->gen_info->dimm_idx_max;
> +
> +	priv->dimmtemp_label[chan] = devm_kasprintf(priv->dev, GFP_KERNEL,
> +						    "DIMM %c%d", 'A' + rank,
> +						    idx + 1);
> +	if (!priv->dimmtemp_label[chan])
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +static const u32 peci_dimmtemp_temp_channel_config[] = {
> +	[0 ... DIMM_NUMS_MAX - 1] = HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT,
> +	0
> +};
> +
> +static const struct hwmon_channel_info peci_dimmtemp_temp_channel = {
> +	.type = hwmon_temp,
> +	.config = peci_dimmtemp_temp_channel_config,
> +};
> +
> +static const struct hwmon_channel_info *peci_dimmtemp_temp_info[] = {
> +	&peci_dimmtemp_temp_channel,
> +	NULL
> +};
> +
> +static const struct hwmon_chip_info peci_dimmtemp_chip_info = {
> +	.ops = &peci_dimmtemp_ops,
> +	.info = peci_dimmtemp_temp_info,
> +};
> +
> +static int create_dimm_temp_info(struct peci_dimmtemp *priv)
> +{
> +	int ret, i, channels;
> +	struct device *dev;
> +
> +	/*
> +	 * We expect to either find populated DIMMs and carry on with creating
> +	 * sensors, or find out that there are no DIMMs populated.
> +	 * All other states mean that the platform never reached the state that
> +	 * allows to check DIMM state - causing us to retry later on.
> +	 */
> +	ret = check_populated_dimms(priv);
> +	if (ret == -ENODEV) {
> +		dev_dbg(priv->dev, "No DIMMs found\n");
> +		return 0;
> +	} else if (ret) {
> +		schedule_delayed_work(&priv->detect_work, DIMM_MASK_CHECK_DELAY_JIFFIES);
> +		dev_dbg(priv->dev, "Deferred populating DIMM temp info\n");
> +		return ret;
> +	}
> +
> +	channels = priv->gen_info->chan_rank_max * priv->gen_info->dimm_idx_max;
> +
> +	priv->dimmtemp_label = devm_kzalloc(priv->dev, channels * sizeof(char *), GFP_KERNEL);
> +	if (!priv->dimmtemp_label)
> +		return -ENOMEM;
> +
> +	for_each_set_bit(i, priv->dimm_mask, DIMM_NUMS_MAX) {
> +		ret = create_dimm_temp_label(priv, i);
> +		if (ret)
> +			return ret;
> +		mutex_init(&priv->dimm[i].thresholds.state.lock);
> +		mutex_init(&priv->dimm[i].temp.state.lock);
> +	}
> +
> +	dev = devm_hwmon_device_register_with_info(priv->dev, priv->name, priv,
> +						   &peci_dimmtemp_chip_info, NULL);
> +	if (IS_ERR(dev)) {
> +		dev_err(priv->dev, "Failed to register hwmon device\n");
> +		return PTR_ERR(dev);
> +	}
> +
> +	dev_dbg(priv->dev, "%s: sensor '%s'\n", dev_name(dev), priv->name);
> +
> +	return 0;
> +}
> +
> +static void create_dimm_temp_info_delayed(struct work_struct *work)
> +{
> +	struct peci_dimmtemp *priv = container_of(to_delayed_work(work),
> +						  struct peci_dimmtemp,
> +						  detect_work);
> +	int ret;
> +
> +	ret = create_dimm_temp_info(priv);
> +	if (ret && ret != -EAGAIN)
> +		dev_err(priv->dev, "Failed to populate DIMM temp info\n");
> +}
> +
> +static void remove_delayed_work(void *_priv)
> +{
> +	struct peci_dimmtemp *priv = _priv;
> +
> +	cancel_delayed_work_sync(&priv->detect_work);
> +}
> +
> +static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id)
> +{
> +	struct device *dev = &adev->dev;
> +	struct peci_device *peci_dev = to_peci_device(dev->parent);
> +	struct peci_dimmtemp *priv;
> +	int ret;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_dimmtemp.cpu%d",
> +				    peci_dev->info.socket_id);
> +	if (!priv->name)
> +		return -ENOMEM;
> +
> +	priv->dev = dev;
> +	priv->peci_dev = peci_dev;
> +	priv->gen_info = (const struct dimm_info *)id->driver_data;
> +
> +	/*
> +	 * This is just a sanity check. Since we're using commands that are
> +	 * guaranteed to be supported on a given platform, we should never see
> +	 * revision lower than expected.
> +	 */
> +	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
> +		dev_warn(priv->dev,
> +			 "Unexpected PECI revision %#x, some features may be unavailable\n",
> +			 peci_dev->info.peci_revision);
> +
> +	INIT_DELAYED_WORK(&priv->detect_work, create_dimm_temp_info_delayed);
> +
> +	ret = devm_add_action_or_reset(priv->dev, remove_delayed_work, priv);
> +	if (ret)
> +		return ret;
> +
> +	ret = create_dimm_temp_info(priv);
> +	if (ret && ret != -EAGAIN) {
> +		dev_err(dev, "Failed to populate DIMM temp info\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +read_thresholds_hsx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
> +{
> +	u8 dev, func;
> +	u16 reg;
> +	int ret;
> +
> +	/*
> +	 * Device 20, Function 0: IMC 0 channel 0 -> rank 0
> +	 * Device 20, Function 1: IMC 0 channel 1 -> rank 1
> +	 * Device 21, Function 0: IMC 0 channel 2 -> rank 2
> +	 * Device 21, Function 1: IMC 0 channel 3 -> rank 3
> +	 * Device 23, Function 0: IMC 1 channel 0 -> rank 4
> +	 * Device 23, Function 1: IMC 1 channel 1 -> rank 5
> +	 * Device 24, Function 0: IMC 1 channel 2 -> rank 6
> +	 * Device 24, Function 1: IMC 1 channel 3 -> rank 7
> +	 */
> +	dev = 20 + chan_rank / 2 + chan_rank / 4;
> +	func = chan_rank % 2;
> +	reg = 0x120 + dimm_order * 4;
> +
> +	ret = peci_pci_local_read(priv->peci_dev, 1, dev, func, reg, data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int
> +read_thresholds_bdxd(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
> +{
> +	u8 dev, func;
> +	u16 reg;
> +	int ret;
> +
> +	/*
> +	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
> +	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
> +	 * Device 12, Function 2: IMC 1 channel 0 -> rank 2
> +	 * Device 12, Function 6: IMC 1 channel 1 -> rank 3
> +	 */
> +	dev = 10 + chan_rank / 2 * 2;
> +	func = (chan_rank % 2) ? 6 : 2;
> +	reg = 0x120 + dimm_order * 4;
> +
> +	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int
> +read_thresholds_skx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
> +{
> +	u8 dev, func;
> +	u16 reg;
> +	int ret;
> +
> +	/*
> +	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
> +	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
> +	 * Device 11, Function 2: IMC 0 channel 2 -> rank 2
> +	 * Device 12, Function 2: IMC 1 channel 0 -> rank 3
> +	 * Device 12, Function 6: IMC 1 channel 1 -> rank 4
> +	 * Device 13, Function 2: IMC 1 channel 2 -> rank 5
> +	 */
> +	dev = 10 + chan_rank / 3 * 2 + (chan_rank % 3 == 2 ? 1 : 0);
> +	func = chan_rank % 3 == 1 ? 6 : 2;
> +	reg = 0x120 + dimm_order * 4;
> +
> +	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int
> +read_thresholds_icx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
> +{
> +	u32 reg_val;
> +	u64 offset;
> +	int ret;
> +	u8 dev;
> +
> +	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd4, &reg_val);
> +	if (ret || !(reg_val & BIT(31)))
> +		return -ENODATA; /* Use default or previous value */
> +
> +	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd0, &reg_val);
> +	if (ret)
> +		return -ENODATA; /* Use default or previous value */
> +
> +	/*
> +	 * Device 26, Offset 224e0: IMC 0 channel 0 -> rank 0
> +	 * Device 26, Offset 264e0: IMC 0 channel 1 -> rank 1
> +	 * Device 27, Offset 224e0: IMC 1 channel 0 -> rank 2
> +	 * Device 27, Offset 264e0: IMC 1 channel 1 -> rank 3
> +	 * Device 28, Offset 224e0: IMC 2 channel 0 -> rank 4
> +	 * Device 28, Offset 264e0: IMC 2 channel 1 -> rank 5
> +	 * Device 29, Offset 224e0: IMC 3 channel 0 -> rank 6
> +	 * Device 29, Offset 264e0: IMC 3 channel 1 -> rank 7
> +	 */
> +	dev = 26 + chan_rank / 2;
> +	offset = 0x224e0 + dimm_order * 4 + (chan_rank % 2) * 0x4000;
> +
> +	ret = peci_mmio_read(priv->peci_dev, 0, GET_CPU_SEG(reg_val), GET_CPU_BUS(reg_val),
> +			     dev, 0, offset, data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static const struct dimm_info dimm_hsx = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_HSX,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_HSX,
> +	.min_peci_revision = 0x33,
> +	.read_thresholds = &read_thresholds_hsx,
> +};
> +
> +static const struct dimm_info dimm_bdx = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_BDX,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDX,
> +	.min_peci_revision = 0x33,
> +	.read_thresholds = &read_thresholds_hsx,
> +};
> +
> +static const struct dimm_info dimm_bdxd = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_BDXD,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDXD,
> +	.min_peci_revision = 0x33,
> +	.read_thresholds = &read_thresholds_bdxd,
> +};
> +
> +static const struct dimm_info dimm_skx = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_SKX,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_SKX,
> +	.min_peci_revision = 0x33,
> +	.read_thresholds = &read_thresholds_skx,
> +};
> +
> +static const struct dimm_info dimm_icx = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_ICX,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICX,
> +	.min_peci_revision = 0x40,
> +	.read_thresholds = &read_thresholds_icx,
> +};
> +
> +static const struct dimm_info dimm_icxd = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_ICXD,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICXD,
> +	.min_peci_revision = 0x40,
> +	.read_thresholds = &read_thresholds_icx,
> +};
> +
> +static const struct auxiliary_device_id peci_dimmtemp_ids[] = {
> +	{
> +		.name = "peci_cpu.dimmtemp.hsx",
> +		.driver_data = (kernel_ulong_t)&dimm_hsx,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.bdx",
> +		.driver_data = (kernel_ulong_t)&dimm_bdx,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.bdxd",
> +		.driver_data = (kernel_ulong_t)&dimm_bdxd,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.skx",
> +		.driver_data = (kernel_ulong_t)&dimm_skx,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.icx",
> +		.driver_data = (kernel_ulong_t)&dimm_icx,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.icxd",
> +		.driver_data = (kernel_ulong_t)&dimm_icxd,
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(auxiliary, peci_dimmtemp_ids);
> +
> +static struct auxiliary_driver peci_dimmtemp_driver = {
> +	.probe		= peci_dimmtemp_probe,
> +	.id_table	= peci_dimmtemp_ids,
> +};
> +
> +module_auxiliary_driver(peci_dimmtemp_driver);
> +
> +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
> +MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
> +MODULE_DESCRIPTION("PECI dimmtemp driver");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS(PECI_CPU);


From catalin.marinas at arm.com  Tue Aug  3 08:47:33 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue,  3 Aug 2021 16:47:33 +0100
Subject: [PATCH v5 0/4] kselftest/arm64: Vector length configuration tests
In-Reply-To: <20210803140450.46624-1-broonie@kernel.org>
References: <20210803140450.46624-1-broonie@kernel.org>
Message-ID: <162800564638.22044.15141225072637378536.b4-ty@arm.com>

On Tue, 3 Aug 2021 15:04:46 +0100, Mark Brown wrote:
> Currently we don't have full automated tests for the vector length
> configuation ABIs offered for SVE, we have a helper binary for setting
> the vector length which can be used for manual tests and we use the
> prctl() interface to enumerate the vector lengths but don't actually
> verify that the vector lengths enumerated were set.
> 
> This patch series provides a small helper which allows us to get the
> currently configured vector length using the RDVL instruction via either
> a library call or stdout of a process and then uses this to both add
> verification of enumerated vector lengths to our existing tests and also
> add a new test program which exercises both the prctl() and sysfs
> interfaces.
> 
> [...]

Applied to arm64 (for-next/kselftest), thanks!

[1/4] kselftest/arm64: Provide a helper binary and "library" for SVE RDVL
      https://git.kernel.org/arm64/c/7710861017ac
[2/4] kselftest/arm64: Validate vector lengths are set in sve-probe-vls
      https://git.kernel.org/arm64/c/b43ab36a6d86
[3/4] kselftest/arm64: Add tests for SVE vector configuration
      https://git.kernel.org/arm64/c/95cf3f23877b
[4/4] kselftest/arm64: Add a TODO list for floating point tests
      https://git.kernel.org/arm64/c/e96595c55d23

-- 
Catalin



From catalin.marinas at arm.com  Tue Aug  3 08:47:49 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue,  3 Aug 2021 16:47:49 +0100
Subject: [PATCH] arm64: move the (z)install rules to arch/arm64/Makefile
In-Reply-To: <20210729140527.443116-1-masahiroy@kernel.org>
References: <20210729140527.443116-1-masahiroy@kernel.org>
Message-ID: <162800566375.22137.6946161452098258110.b4-ty@arm.com>

On Thu, 29 Jul 2021 23:05:27 +0900, Masahiro Yamada wrote:
> Currently, the (z)install targets in arch/arm64/Makefile descend into
> arch/arm64/boot/Makefile to invoke the shell script, but there is no
> good reason to do so.
> 
> arch/arm64/Makefile can run the shell script directly.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: move the (z)install rules to arch/arm64/Makefile
      https://git.kernel.org/arm64/c/70a4039bd4d7

-- 
Catalin



From catalin.marinas at arm.com  Tue Aug  3 08:48:08 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue,  3 Aug 2021 16:48:08 +0100
Subject: [PATCH] arm64: fix typo in a comment
In-Reply-To: <20210803142020.124230-1-wangborong@cdjrlc.com>
References: <20210803142020.124230-1-wangborong@cdjrlc.com>
Message-ID: <162800566375.22137.4299409500738989157.b4-ty@arm.com>

On Tue, 3 Aug 2021 22:20:20 +0800, Jason Wang wrote:
> The double 'the' after 'If' in this comment "If the the TLB range ops
> are supported..." is repeated. Consequently, one 'the' should be
> removed from the comment.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: fix typo in a comment
      https://git.kernel.org/arm64/c/312b7104f39b

-- 
Catalin



From catalin.marinas at arm.com  Tue Aug  3 08:48:27 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue,  3 Aug 2021 16:48:27 +0100
Subject: [PATCH v4 1/1] arm64/cpufeature: Optionally disable MTE via
 command-line
In-Reply-To: <20210803070824.7586-2-yee.lee@mediatek.com>
References: <20210803070824.7586-1-yee.lee@mediatek.com>
 <20210803070824.7586-2-yee.lee@mediatek.com>
Message-ID: <162800569298.22283.5858826672578810642.b4-ty@arm.com>

On Tue, 3 Aug 2021 15:08:22 +0800, yee.lee at mediatek.com wrote:
> MTE support needs to be optionally disabled in runtime
> for HW issue workaround, FW development and some
> evaluation works on system resource and performance.
> 
> This patch makes two changes:
> (1) moves init of tag-allocation bits(ATA/ATA0) to
> cpu_enable_mte() as not cached in TLB.
> 
> [...]

Applied to arm64 (for-next/mte), thanks!

[1/1] arm64/cpufeature: Optionally disable MTE via command-line
      https://git.kernel.org/arm64/c/7a062ce31807

-- 
Catalin



From jerome.oufella at savoirfairelinux.com  Tue Aug  3 08:52:09 2021
From: jerome.oufella at savoirfairelinux.com (Jerome Oufella)
Date: Tue, 3 Aug 2021 11:52:09 -0400 (EDT)
Subject: [PATCH] ARM: ep93xx: remove MaverickCrunch support
In-Reply-To: <CAK8P3a2z_xxpz9hAYoBx5=bS81V=TkjEU6WHNhPi1UhQ3UScfw@mail.gmail.com>
References: <20210802141245.1146772-1-arnd@kernel.org>
 <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>
 <CAL4-wQpKLtSj0xfNUXXLhbtN1wC051jpRneAuLYOi1riZfiinw@mail.gmail.com>
 <CAK8P3a2z_xxpz9hAYoBx5=bS81V=TkjEU6WHNhPi1UhQ3UScfw@mail.gmail.com>
Message-ID: <817752520.64672.1628005929651.JavaMail.zimbra@savoirfairelinux.com>

On Aug 3, 2021, at 7:58 AM, Arnd Bergmann arnd at kernel.org wrote:

> On Tue, Aug 3, 2021 at 1:41 PM Martin Guy <martinwguy at gmail.com> wrote:
>>
>> I forward opinion from people currently producing and supporting EP93XX boards:
> 
> Thanks a lot for bringing them in. I definitely don't want to remove support for
> something that is actively being used, and we don't have to merge the patch
> if they currently rely on MaverickCrunch on older platforms.
> 
> It does sound however like Jerome's customers are using a normal (softfloat)
> Linus distro on EP93xx, rather than one using the original MaverickCrunch
> FPU instructions. There are no plans to discontinue EP93xx support, there
> is actually a good amount of recent work going into updating the platform.
> 
> Jerome, please let me know if I understood you correctly here. If your
> customers do rely on MaverickCrunch support in user space, I would
> leave that in the kernel for as long as ep93xx itself is supported, and instead
> require building support with the GNU assembler to avoid having to
> add support to the clang integrated assembler. If you don't know of anyone
> using MaverickCrunch, I would go ahead with my patch to remove kernel
> support.
> 
>      Arnd

Arnd,

You are correct on assuming usage of softfloat toolchains and not
using the MaverickCrunch unit. AFAIK, I am not aware of active users
of this FPU on recent setups.

 Jerome


From mathieu.poirier at linaro.org  Tue Aug  3 08:52:20 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 3 Aug 2021 09:52:20 -0600
Subject: [PATCH 14/38] coresight: Replace deprecated CPU-hotplug functions.
In-Reply-To: <20210803141621.780504-15-bigeasy@linutronix.de>
References: <20210803141621.780504-1-bigeasy@linutronix.de>
 <20210803141621.780504-15-bigeasy@linutronix.de>
Message-ID: <20210803155220.GA3091608@p14s>

On Tue, Aug 03, 2021 at 04:15:57PM +0200, Sebastian Andrzej Siewior wrote:
> The functions get_online_cpus() and put_online_cpus() have been
> deprecated during the CPU hotplug rework. They map directly to
> cpus_read_lock() and cpus_read_unlock().
> 
> Replace deprecated CPU-hotplug functions with the official version.
> The behavior remains unchanged.
> 
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Leo Yan <leo.yan at linaro.org>
> Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
> ---
>  drivers/hwtracing/coresight/coresight-cpu-debug.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> index 9731d3a960735..00de46565bc40 100644
> --- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
> +++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
> @@ -588,11 +588,11 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id)
>  
>  	drvdata->base = base;
>  
> -	get_online_cpus();
> +	cpus_read_lock();
>  	per_cpu(debug_drvdata, drvdata->cpu) = drvdata;
>  	ret = smp_call_function_single(drvdata->cpu, debug_init_arch_data,
>  				       drvdata, 1);
> -	put_online_cpus();
> +	cpus_read_unlock();
>

Applied - thanks,
Mathieu

>  	if (ret) {
>  		dev_err(dev, "CPU%d debug arch init failed\n", drvdata->cpu);
> -- 
> 2.32.0
> 


From lee.jones at linaro.org  Tue Aug  3 08:54:49 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Tue,  3 Aug 2021 16:54:49 +0100
Subject: [PATCH 0/3] power: reset: Convert Power-Off driver to tristate
Message-ID: <20210803155452.435812-1-lee.jones@linaro.org>

Provide support to compile the Power-Off driver as a module.

Elliot Berman (2):
  reboot: Export reboot_mode
  power: reset: Enable tristate on restart power-off driver

Lee Jones (1):
  arch: Export machine_restart() instances so they can be called from
    modules

 arch/arc/kernel/reset.c            | 1 +
 arch/arm/kernel/reboot.c           | 1 +
 arch/arm64/kernel/process.c        | 1 +
 arch/csky/kernel/power.c           | 1 +
 arch/h8300/kernel/process.c        | 1 +
 arch/hexagon/kernel/reset.c        | 1 +
 arch/m68k/kernel/process.c         | 1 +
 arch/microblaze/kernel/reset.c     | 1 +
 arch/mips/kernel/reset.c           | 1 +
 arch/mips/lantiq/falcon/reset.c    | 1 +
 arch/mips/sgi-ip27/ip27-reset.c    | 1 +
 arch/nios2/kernel/process.c        | 1 +
 arch/openrisc/kernel/process.c     | 1 +
 arch/parisc/kernel/process.c       | 1 +
 arch/powerpc/kernel/setup-common.c | 1 +
 arch/riscv/kernel/reset.c          | 1 +
 arch/s390/kernel/setup.c           | 1 +
 arch/sh/kernel/reboot.c            | 1 +
 arch/sparc/kernel/process_32.c     | 1 +
 arch/sparc/kernel/reboot.c         | 1 +
 arch/um/kernel/reboot.c            | 1 +
 arch/x86/kernel/reboot.c           | 1 +
 arch/xtensa/kernel/setup.c         | 1 +
 drivers/power/reset/Kconfig        | 2 +-
 kernel/reboot.c                    | 2 ++
 25 files changed, 26 insertions(+), 1 deletion(-)


-- 
2.32.0.554.ge1b32706d8-goog



From lee.jones at linaro.org  Tue Aug  3 08:54:50 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Tue,  3 Aug 2021 16:54:50 +0100
Subject: [PATCH 1/3] arch: Export machine_restart() instances so they can be
 called from modules
In-Reply-To: <20210803155452.435812-1-lee.jones@linaro.org>
References: <20210803155452.435812-1-lee.jones@linaro.org>
Message-ID: <20210803155452.435812-2-lee.jones@linaro.org>

A recent attempt to convert the Power Reset Restart driver to tristate
failed because of the following compile error (reported once merged by
Stephen Rothwell via Linux Next):

  ERROR: "machine_restart" [drivers/power/reset/restart-poweroff.ko] undefined!

This error occurs since some of the machine_restart() instances are
not currently exported for use in modules.  This patch aims to rectify
that.

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---

NB: If it's safe to omit some of these, let me know and I'll revise the patch.

 arch/arc/kernel/reset.c            | 1 +
 arch/arm/kernel/reboot.c           | 1 +
 arch/arm64/kernel/process.c        | 1 +
 arch/csky/kernel/power.c           | 1 +
 arch/h8300/kernel/process.c        | 1 +
 arch/hexagon/kernel/reset.c        | 1 +
 arch/m68k/kernel/process.c         | 1 +
 arch/microblaze/kernel/reset.c     | 1 +
 arch/mips/kernel/reset.c           | 1 +
 arch/mips/lantiq/falcon/reset.c    | 1 +
 arch/mips/sgi-ip27/ip27-reset.c    | 1 +
 arch/nios2/kernel/process.c        | 1 +
 arch/openrisc/kernel/process.c     | 1 +
 arch/parisc/kernel/process.c       | 1 +
 arch/powerpc/kernel/setup-common.c | 1 +
 arch/riscv/kernel/reset.c          | 1 +
 arch/s390/kernel/setup.c           | 1 +
 arch/sh/kernel/reboot.c            | 1 +
 arch/sparc/kernel/process_32.c     | 1 +
 arch/sparc/kernel/reboot.c         | 1 +
 arch/um/kernel/reboot.c            | 1 +
 arch/x86/kernel/reboot.c           | 1 +
 arch/xtensa/kernel/setup.c         | 1 +
 23 files changed, 23 insertions(+)

diff --git a/arch/arc/kernel/reset.c b/arch/arc/kernel/reset.c
index fd6c3eb930bad..ae4f8a43b0af4 100644
--- a/arch/arc/kernel/reset.c
+++ b/arch/arc/kernel/reset.c
@@ -20,6 +20,7 @@ void machine_restart(char *__unused)
 	pr_info("Put your restart handler here\n");
 	machine_halt();
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_power_off(void)
 {
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 0ce388f154226..2878260efd130 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -150,3 +150,4 @@ void machine_restart(char *cmd)
 	printk("Reboot failed -- System halted\n");
 	while (1);
 }
+EXPORT_SYMBOL(machine_restart);
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index b4bb67f17a2ca..cf89ce91d7145 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -212,6 +212,7 @@ void machine_restart(char *cmd)
 	printk("Reboot failed -- System halted\n");
 	while (1);
 }
+EXPORT_SYMBOL(machine_restart);
 
 #define bstr(suffix, str) [PSR_BTYPE_ ## suffix >> PSR_BTYPE_SHIFT] = str
 static const char *const btypes[] = {
diff --git a/arch/csky/kernel/power.c b/arch/csky/kernel/power.c
index 923ee4e381b81..b466c825cbb3c 100644
--- a/arch/csky/kernel/power.c
+++ b/arch/csky/kernel/power.c
@@ -28,3 +28,4 @@ void machine_restart(char *cmd)
 	do_kernel_restart(cmd);
 	asm volatile ("bkpt");
 }
+EXPORT_SYMBOL(machine_restart);
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 46b1342ce515b..8203ac5cd33ec 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -66,6 +66,7 @@ void machine_restart(char *__unused)
 	local_irq_disable();
 	__asm__("jmp @@0");
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_halt(void)
 {
diff --git a/arch/hexagon/kernel/reset.c b/arch/hexagon/kernel/reset.c
index da36114d928f0..433378d52063c 100644
--- a/arch/hexagon/kernel/reset.c
+++ b/arch/hexagon/kernel/reset.c
@@ -19,6 +19,7 @@ void machine_halt(void)
 void machine_restart(char *cmd)
 {
 }
+EXPORT_SYMBOL(machine_restart);
 
 void (*pm_power_off)(void) = NULL;
 EXPORT_SYMBOL(pm_power_off);
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index da83cc83e7912..e0264704686e9 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -57,6 +57,7 @@ void machine_restart(char * __unused)
 		mach_reset();
 	for (;;);
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_halt(void)
 {
diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c
index 5f4722908164d..902fbe3777846 100644
--- a/arch/microblaze/kernel/reset.c
+++ b/arch/microblaze/kernel/reset.c
@@ -41,3 +41,4 @@ void machine_restart(char *cmd)
 	pr_emerg("Reboot failed -- System halted\n");
 	while (1);
 }
+EXPORT_SYMBOL(machine_restart);
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c
index 6288780b779e7..2d3193a3cf68b 100644
--- a/arch/mips/kernel/reset.c
+++ b/arch/mips/kernel/reset.c
@@ -99,6 +99,7 @@ void machine_restart(char *command)
 	pr_emerg("Reboot failed -- System halted\n");
 	machine_hang();
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_halt(void)
 {
diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c
index 261996c230cf6..80dd9759ffa55 100644
--- a/arch/mips/lantiq/falcon/reset.c
+++ b/arch/mips/lantiq/falcon/reset.c
@@ -51,6 +51,7 @@ static void machine_restart(char *command)
 		(void *)WDT_REG_BASE);
 	unreachable();
 }
+EXPORT_SYMBOL(machine_restart);
 
 static void machine_halt(void)
 {
diff --git a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c
index 5ac5ad6387343..a3f8f4498b7c5 100644
--- a/arch/mips/sgi-ip27/ip27-reset.c
+++ b/arch/mips/sgi-ip27/ip27-reset.c
@@ -29,6 +29,7 @@
 #include "ip27-common.h"
 
 void machine_restart(char *command) __noreturn;
+EXPORT_SYMBOL(machine_restart);
 void machine_halt(void) __noreturn;
 void machine_power_off(void) __noreturn;
 
diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c
index c5f916ca6845f..6f9459e8ae4ed 100644
--- a/arch/nios2/kernel/process.c
+++ b/arch/nios2/kernel/process.c
@@ -51,6 +51,7 @@ void machine_restart(char *__unused)
 	: "r" (cpuinfo.reset_addr)
 	: "r4");
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_halt(void)
 {
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index eb62429681fc8..12c3022c46387 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -61,6 +61,7 @@ void machine_restart(char *cmd)
 	pr_emerg("Reboot failed -- System halted\n");
 	while (1);
 }
+EXPORT_SYMBOL(machine_restart);
 
 /*
  * Similar to machine_power_off, but don't shut off power.  Add code
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index b144fbe29bc16..05e9f03124b64 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -96,6 +96,7 @@ void machine_restart(char *cmd)
 	while (1) ;
 
 }
+EXPORT_SYMBOL(machine_restart);
 
 void (*chassis_power_off)(void);
 
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 74a98fff2c2f9..54ebae540dd7d 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -159,6 +159,7 @@ void machine_restart(char *cmd)
 
 	machine_hang();
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_power_off(void)
 {
diff --git a/arch/riscv/kernel/reset.c b/arch/riscv/kernel/reset.c
index ee5878d968cc1..596a36b91eaa2 100644
--- a/arch/riscv/kernel/reset.c
+++ b/arch/riscv/kernel/reset.c
@@ -20,6 +20,7 @@ void machine_restart(char *cmd)
 	do_kernel_restart(cmd);
 	while (1);
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_halt(void)
 {
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 5aab59ad56881..fd2394af0d43a 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -276,6 +276,7 @@ void machine_restart(char *command)
 		console_unblank();
 	_machine_restart(command);
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_halt(void)
 {
diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
index 5c33f036418be..36b6c61f3b129 100644
--- a/arch/sh/kernel/reboot.c
+++ b/arch/sh/kernel/reboot.c
@@ -83,6 +83,7 @@ void machine_restart(char *cmd)
 {
 	machine_ops.restart(cmd);
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_halt(void)
 {
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 3b9794978e5bc..30a1674683946 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -104,6 +104,7 @@ void machine_restart(char * cmd)
 	prom_feval ("reset");
 	panic("Reboot failed!");
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_power_off(void)
 {
diff --git a/arch/sparc/kernel/reboot.c b/arch/sparc/kernel/reboot.c
index 69c1b6c047d53..53adef425d7de 100644
--- a/arch/sparc/kernel/reboot.c
+++ b/arch/sparc/kernel/reboot.c
@@ -52,4 +52,5 @@ void machine_restart(char *cmd)
 	prom_reboot("");
 	panic("Reboot failed!");
 }
+EXPORT_SYMBOL(machine_restart);
 
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 48c0610d506e0..4b764311efb89 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -47,6 +47,7 @@ void machine_restart(char * __unused)
 	uml_cleanup();
 	reboot_skas();
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_power_off(void)
 {
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index b29657b76e3fa..b48c30ead7167 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -733,6 +733,7 @@ static void native_machine_restart(char *__unused)
 		machine_shutdown();
 	__machine_emergency_restart(0);
 }
+EXPORT_SYMBOL(machine_restart);
 
 static void native_machine_halt(void)
 {
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index ed184106e4cf9..a84cc934300d5 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -564,6 +564,7 @@ void machine_restart(char * cmd)
 {
 	platform_restart();
 }
+EXPORT_SYMBOL(machine_restart);
 
 void machine_halt(void)
 {
-- 
2.32.0.554.ge1b32706d8-goog



From lee.jones at linaro.org  Tue Aug  3 08:54:52 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Tue,  3 Aug 2021 16:54:52 +0100
Subject: [PATCH 3/3] power: reset: Enable tristate on restart power-off driver
In-Reply-To: <20210803155452.435812-1-lee.jones@linaro.org>
References: <20210803155452.435812-1-lee.jones@linaro.org>
Message-ID: <20210803155452.435812-4-lee.jones@linaro.org>

From: Elliot Berman <eberman at codeaurora.org>

Since reboot_mode is an exported symbol, restart power-off driver can be
compiled as module.

Signed-off-by: Elliot Berman <eberman at codeaurora.org>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/power/reset/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 4d1192062508d..e155b2e2a75c4 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -192,7 +192,7 @@ config POWER_RESET_REGULATOR
 	  power regulator defined in the devicetree.
 
 config POWER_RESET_RESTART
-	bool "Restart power-off driver"
+	tristate "Restart power-off driver"
 	help
 	  Some boards don't actually have the ability to power off.
 	  Instead they restart, and u-boot holds the SoC until the
-- 
2.32.0.554.ge1b32706d8-goog



From lee.jones at linaro.org  Tue Aug  3 08:54:51 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Tue,  3 Aug 2021 16:54:51 +0100
Subject: [PATCH 2/3] reboot: Export reboot_mode
In-Reply-To: <20210803155452.435812-1-lee.jones@linaro.org>
References: <20210803155452.435812-1-lee.jones@linaro.org>
Message-ID: <20210803155452.435812-3-lee.jones@linaro.org>

From: Elliot Berman <eberman at codeaurora.org>

Export reboot_mode to support kernel modules wishing to modify reboot_mode.

Signed-off-by: Elliot Berman <eberman at codeaurora.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>
Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 kernel/reboot.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/reboot.c b/kernel/reboot.c
index a6ad5eb2fa733..7ca414aa070b6 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -32,7 +32,9 @@ EXPORT_SYMBOL(cad_pid);
 #define DEFAULT_REBOOT_MODE
 #endif
 enum reboot_mode reboot_mode DEFAULT_REBOOT_MODE;
+EXPORT_SYMBOL_GPL(reboot_mode);
 enum reboot_mode panic_reboot_mode = REBOOT_UNDEFINED;
+EXPORT_SYMBOL_GPL(panic_reboot_mode);
 
 /*
  * This variable is used privately to keep track of whether or not
-- 
2.32.0.554.ge1b32706d8-goog



From shameerali.kolothum.thodi at huawei.com  Tue Aug  3 08:56:08 2021
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Tue, 3 Aug 2021 15:56:08 +0000
Subject: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU schedule out
In-Reply-To: <20210803153036.GA31125@willie-the-truck>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
 <20210803114034.GB30853@willie-the-truck>
 <ee2863107d614ef8a36006b5aa912eca@huawei.com>
 <20210803153036.GA31125@willie-the-truck>
Message-ID: <58bf7a27a4c440c685c6b1e7c9325441@huawei.com>



> -----Original Message-----
> From: Will Deacon [mailto:will at kernel.org]
> Sent: 03 August 2021 16:31
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org; maz at kernel.org; catalin.marinas at arm.com;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Linuxarm
> <linuxarm at huawei.com>
> Subject: Re: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU
> schedule out
> 
> On Tue, Aug 03, 2021 at 12:55:25PM +0000, Shameerali Kolothum Thodi
> wrote:
> > > > diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
> > > > index 5584e84aed95..5fd51f5445c1 100644
> > > > --- a/arch/arm64/kvm/vmid.c
> > > > +++ b/arch/arm64/kvm/vmid.c
> > > > @@ -116,6 +116,12 @@ static u64 new_vmid(struct kvm_vmid
> > > *kvm_vmid)
> > > >  	return idx2vmid(vmid) | generation;
> > > >  }
> > > >
> > > > +/* Call with preemption disabled */
> > > > +void kvm_arm_vmid_clear_active(void)
> > > > +{
> > > > +	atomic64_set(this_cpu_ptr(&active_vmids), 0);
> > > > +}
> > >
> > > I think this is very broken, as it will force everybody to take the
> > > slow-path when they see an active_vmid of 0.
> >
> > Yes. I have seen that happening in my test setup.
> 
> Why didn't you say so?!

Sorry. I thought of getting some performance numbers with and
without this patch and measure the impact. But didn't quite get time
to finish it yet.
 
> 
> > > It also doesn't solve the issue I mentioned before, as an active_vmid of 0
> > > means that the reserved vmid is preserved.
> > >
> > > Needs more thought...
> >
> > How about we clear all the active_vmids in kvm_arch_free_vm() if it
> > matches the kvm_vmid->id ? But we may have to hold the lock
> > there
> 
> I think we have to be really careful not to run into the "suspended
> animation" problem described in ae120d9edfe9 ("ARM: 7767/1: let the ASID
> allocator handle suspended animation") if we go down this road.


Ok. I will go through that.
 
> Maybe something along the lines of:
> 
> ROLLOVER
> 
>   * Take lock
>   * Inc generation
>     => This will force everybody down the slow path
>   * Record active VMIDs
>   * Broadcast TLBI
>     => Only active VMIDs can be dirty
>     => Reserve active VMIDs and mark as allocated
> 
> VCPU SCHED IN
> 
>   * Set active VMID
>   * Check generation
>   * If mismatch then:
>         * Take lock
>         * Try to match a reserved VMID
>         * If no reserved VMID, allocate new
> 
> VCPU SCHED OUT
> 
>   * Clear active VMID
> 
> but I'm not daft enough to think I got it right first time. I think it
> needs both implementing *and* modelling in TLA+ before we merge it!
> 

Ok. I need some time to digest the above first :).

On another note, how serious do you think is the problem of extra
reservation of the VMID space? Just wondering if we can skip this
patch for now or not..

Thanks,
Shameer


From dqfext at gmail.com  Tue Aug  3 09:04:00 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed,  4 Aug 2021 00:04:00 +0800
Subject: [PATCH net-next v2 0/4] mt7530 software fallback bridging fix
Message-ID: <20210803160405.3025624-1-dqfext@gmail.com>

DSA core has gained software fallback support since commit 2f5dc00f7a3e
("net: bridge: switchdev: let drivers inform which bridge ports are
offloaded"), but it does not work properly on mt7530. This patch series
fixes the issues.

DENG Qingfang (4):
  net: dsa: mt7530: enable assisted learning on CPU port
  net: dsa: mt7530: use independent VLAN learning on VLAN-unaware
    bridges
  net: dsa: mt7530: set STP state on filter ID 1
  net: dsa: mt7530: always install FDB entries with IVL and FID 1

 drivers/net/dsa/mt7530.c | 88 ++++++++++++++++++++++++++++------------
 drivers/net/dsa/mt7530.h | 14 +++++--
 2 files changed, 72 insertions(+), 30 deletions(-)

-- 
2.25.1



From dqfext at gmail.com  Tue Aug  3 09:04:01 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed,  4 Aug 2021 00:04:01 +0800
Subject: [PATCH net-next v2 1/4] net: dsa: mt7530: enable assisted learning on
 CPU port
In-Reply-To: <20210803160405.3025624-1-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
Message-ID: <20210803160405.3025624-2-dqfext@gmail.com>

Consider the following bridge configuration, where bond0 is not
offloaded:

         +-- br0 --+
        / /   |     \
       / /    |      \
      /  |    |     bond0
     /   |    |     /   \
   swp0 swp1 swp2 swp3 swp4
     .        .       .
     .        .       .
     A        B       C

Address learning is enabled on offloaded ports (swp0~2) and the CPU
port, so when client A sends a packet to C, the following will happen:

1. The switch learns that client A can be reached at swp0.
2. The switch probably already knows that client C can be reached at the
   CPU port, so it forwards the packet to the CPU.
3. The bridge core knows client C can be reached at bond0, so it
   forwards the packet back to the switch.
4. The switch learns that client A can be reached at the CPU port.
5. The switch forwards the packet to either swp3 or swp4, according to
   the packet's tag.

That makes client A's MAC address flap between swp0 and the CPU port. If
client B sends a packet to A, it is possible that the packet is
forwarded to the CPU. With offload_fwd_mark = 1, the bridge core won't
forward it back to the switch, resulting in packet loss.

As we have the assisted_learning_on_cpu_port in DSA core now, enable
that and disable hardware learning on the CPU port.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
Reviewed-by: Vladimir Oltean <oltean at gmail.com>
---
v1 -> v2: no changes.

 drivers/net/dsa/mt7530.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index b6e0b347947e..abe57b04fc39 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2046,6 +2046,7 @@ mt7530_setup(struct dsa_switch *ds)
 	 * as two netdev instances.
 	 */
 	dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
+	ds->assisted_learning_on_cpu_port = true;
 	ds->mtu_enforcement_ingress = true;
 
 	if (priv->id == ID_MT7530) {
@@ -2116,15 +2117,15 @@ mt7530_setup(struct dsa_switch *ds)
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
 
+		/* Disable learning by default on all ports */
+		mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+
 		if (dsa_is_cpu_port(ds, i)) {
 			ret = mt753x_cpu_port_enable(ds, i);
 			if (ret)
 				return ret;
 		} else {
 			mt7530_port_disable(ds, i);
-
-			/* Disable learning by default on all user ports */
-			mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
 		}
 		/* Enable consistent egress tag */
 		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
@@ -2281,6 +2282,9 @@ mt7531_setup(struct dsa_switch *ds)
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
 
+		/* Disable learning by default on all ports */
+		mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+
 		mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
 
 		if (dsa_is_cpu_port(ds, i)) {
@@ -2289,9 +2293,6 @@ mt7531_setup(struct dsa_switch *ds)
 				return ret;
 		} else {
 			mt7530_port_disable(ds, i);
-
-			/* Disable learning by default on all user ports */
-			mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
 		}
 
 		/* Enable consistent egress tag */
@@ -2299,6 +2300,7 @@ mt7531_setup(struct dsa_switch *ds)
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 	}
 
+	ds->assisted_learning_on_cpu_port = true;
 	ds->mtu_enforcement_ingress = true;
 
 	/* Flush the FDB table */
-- 
2.25.1



From dqfext at gmail.com  Tue Aug  3 09:04:02 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed,  4 Aug 2021 00:04:02 +0800
Subject: [PATCH net-next v2 2/4] net: dsa: mt7530: use independent VLAN
 learning on VLAN-unaware bridges
In-Reply-To: <20210803160405.3025624-1-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
Message-ID: <20210803160405.3025624-3-dqfext@gmail.com>

Consider the following bridge configuration, where bond0 is not
offloaded:

         +-- br0 --+
        / /   |     \
       / /    |      \
      /  |    |     bond0
     /   |    |     /   \
   swp0 swp1 swp2 swp3 swp4
     .        .       .
     .        .       .
     A        B       C

Ideally, when the switch receives a packet from swp3 or swp4, it should
forward the packet to the CPU, according to the port matrix and unknown
unicast flood settings.

But packet loss will happen if the destination address is at one of the
offloaded ports (swp0~2). For example, when client C sends a packet to
A, the FDB lookup will indicate that it should be forwarded to swp0, but
the port matrix of swp3 and swp4 is configured to only allow the CPU to
be its destination, so it is dropped.

However, this issue does not happen if the bridge is VLAN-aware. That is
because VLAN-aware bridges use independent VLAN learning, i.e. use VID
for FDB lookup, on offloaded ports. As swp3 and swp4 are not offloaded,
shared VLAN learning with default filter ID of 0 is used instead. So the
lookup for A with filter ID 0 never hits and the packet can be forwarded
to the CPU.

In the current code, only two combinations were used to toggle user
ports' VLAN awareness: one is PCR.PORT_VLAN set to port matrix mode with
PVC.VLAN_ATTR set to transparent port, the other is PCR.PORT_VLAN set to
security mode with PVC.VLAN_ATTR set to user port.

It turns out that only PVC.VLAN_ATTR contributes to VLAN awareness, and
port matrix mode just skips the VLAN table lookup. The reference manual
is somehow misleading when describing PORT_VLAN modes. It states that
PORT_MEM (VLAN port member) is used for destination if the VLAN table
lookup hits, but actually **PORT_MEM & PORT_MATRIX** (bitwise AND of
VLAN port member and port matrix) is used instead, which means we can
have two or more separate VLAN-aware bridges with the same PVID and
traffic won't leak between them.

Therefore, to solve this, enable independent VLAN learning with PVID 0
on VLAN-unaware bridges, by setting their PCR.PORT_VLAN to fallback
mode, while leaving standalone ports in port matrix mode. The CPU port
is always set to fallback mode to serve those bridges.

During testing, it is found that FDB lookup with filter ID of 0 will
also hit entries with VID 0 even with independent VLAN learning. To
avoid that, install all VLANs with filter ID of 1.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
v1 -> v2: use FID enum instead of hardcoding.

 drivers/net/dsa/mt7530.c | 71 +++++++++++++++++++++++++++++-----------
 drivers/net/dsa/mt7530.h |  9 ++++-
 2 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index abe57b04fc39..606a9f4db579 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1021,6 +1021,10 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
 	mt7530_write(priv, MT7530_PCR_P(port),
 		     PCR_MATRIX(dsa_user_ports(priv->ds)));
 
+	/* Set to fallback mode for independent VLAN learning */
+	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
+		   MT7530_PORT_FALLBACK_MODE);
+
 	return 0;
 }
 
@@ -1229,6 +1233,10 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
 			   PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
 	priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
 
+	/* Set to fallback mode for independent VLAN learning */
+	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
+		   MT7530_PORT_FALLBACK_MODE);
+
 	mutex_unlock(&priv->reg_mutex);
 
 	return 0;
@@ -1241,16 +1249,21 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
 	bool all_user_ports_removed = true;
 	int i;
 
-	/* When a port is removed from the bridge, the port would be set up
-	 * back to the default as is at initial boot which is a VLAN-unaware
-	 * port.
+	/* This is called after .port_bridge_leave when leaving a VLAN-aware
+	 * bridge. Don't set standalone ports to fallback mode.
 	 */
-	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
-		   MT7530_PORT_MATRIX_MODE);
+	if (dsa_to_port(ds, port)->bridge_dev)
+		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
+			   MT7530_PORT_FALLBACK_MODE);
+
 	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
 		   VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
 		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 
+	/* Set PVID to 0 */
+	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
+		   G0_PORT_VID_DEF);
+
 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
 		if (dsa_is_user_port(ds, i) &&
 		    dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
@@ -1276,15 +1289,14 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
 	struct mt7530_priv *priv = ds->priv;
 
 	/* Trapped into security mode allows packet forwarding through VLAN
-	 * table lookup. CPU port is set to fallback mode to let untagged
-	 * frames pass through.
+	 * table lookup.
 	 */
-	if (dsa_is_cpu_port(ds, port))
-		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
-			   MT7530_PORT_FALLBACK_MODE);
-	else
+	if (dsa_is_user_port(ds, port)) {
 		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
 			   MT7530_PORT_SECURITY_MODE);
+		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
+			   G0_PORT_VID(priv->ports[port].pvid));
+	}
 
 	/* Set the port as a user port which is to be able to recognize VID
 	 * from incoming packets before fetching entry within the VLAN table.
@@ -1329,6 +1341,13 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 			   PCR_MATRIX(BIT(MT7530_CPU_PORT)));
 	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
 
+	/* When a port is removed from the bridge, the port would be set up
+	 * back to the default as is at initial boot which is a VLAN-unaware
+	 * port.
+	 */
+	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
+		   MT7530_PORT_MATRIX_MODE);
+
 	mutex_unlock(&priv->reg_mutex);
 }
 
@@ -1511,7 +1530,8 @@ mt7530_hw_vlan_add(struct mt7530_priv *priv,
 	/* Validate the entry with independent learning, create egress tag per
 	 * VLAN and joining the port as one of the port members.
 	 */
-	val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | VLAN_VALID;
+	val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | FID(FID_BRIDGED) |
+	      VLAN_VALID;
 	mt7530_write(priv, MT7530_VAWD1, val);
 
 	/* Decide whether adding tag or not for those outgoing packets from the
@@ -1601,9 +1621,13 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
 	mt7530_hw_vlan_update(priv, vlan->vid, &new_entry, mt7530_hw_vlan_add);
 
 	if (pvid) {
-		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
-			   G0_PORT_VID(vlan->vid));
 		priv->ports[port].pvid = vlan->vid;
+
+		/* Only configure PVID if VLAN filtering is enabled */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
+			mt7530_rmw(priv, MT7530_PPBV1_P(port),
+				   G0_PORT_VID_MASK,
+				   G0_PORT_VID(vlan->vid));
 	}
 
 	mutex_unlock(&priv->reg_mutex);
@@ -1617,11 +1641,9 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
 {
 	struct mt7530_hw_vlan_entry target_entry;
 	struct mt7530_priv *priv = ds->priv;
-	u16 pvid;
 
 	mutex_lock(&priv->reg_mutex);
 
-	pvid = priv->ports[port].pvid;
 	mt7530_hw_vlan_entry_init(&target_entry, port, 0);
 	mt7530_hw_vlan_update(priv, vlan->vid, &target_entry,
 			      mt7530_hw_vlan_del);
@@ -1629,11 +1651,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
 	/* PVID is being restored to the default whenever the PVID port
 	 * is being removed from the VLAN.
 	 */
-	if (pvid == vlan->vid)
-		pvid = G0_PORT_VID_DEF;
+	if (priv->ports[port].pvid == vlan->vid) {
+		priv->ports[port].pvid = G0_PORT_VID_DEF;
+		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
+			   G0_PORT_VID_DEF);
+	}
 
-	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, pvid);
-	priv->ports[port].pvid = pvid;
 
 	mutex_unlock(&priv->reg_mutex);
 
@@ -2126,6 +2149,10 @@ mt7530_setup(struct dsa_switch *ds)
 				return ret;
 		} else {
 			mt7530_port_disable(ds, i);
+
+			/* Set default PVID to 0 on all user ports */
+			mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
+				   G0_PORT_VID_DEF);
 		}
 		/* Enable consistent egress tag */
 		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
@@ -2293,6 +2320,10 @@ mt7531_setup(struct dsa_switch *ds)
 				return ret;
 		} else {
 			mt7530_port_disable(ds, i);
+
+			/* Set default PVID to 0 on all user ports */
+			mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
+				   G0_PORT_VID_DEF);
 		}
 
 		/* Enable consistent egress tag */
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index b19b389ff10a..d44640bbd865 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -148,11 +148,18 @@ enum mt7530_vlan_cmd {
 #define  VTAG_EN			BIT(28)
 /* VLAN Member Control */
 #define  PORT_MEM(x)			(((x) & 0xff) << 16)
+/* Filter ID */
+#define  FID(x)				(((x) & 0x7) << 1)
 /* VLAN Entry Valid */
 #define  VLAN_VALID			BIT(0)
 #define  PORT_MEM_SHFT			16
 #define  PORT_MEM_MASK			0xff
 
+enum mt7530_fid {
+	FID_STANDALONE = 0,
+	FID_BRIDGED = 1,
+};
+
 #define MT7530_VAWD2			0x98
 /* Egress Tag Control */
 #define  ETAG_CTRL_P(p, x)		(((x) & 0x3) << ((p) << 1))
@@ -247,7 +254,7 @@ enum mt7530_vlan_port_attr {
 #define MT7530_PPBV1_P(x)		(0x2014 + ((x) * 0x100))
 #define  G0_PORT_VID(x)			(((x) & 0xfff) << 0)
 #define  G0_PORT_VID_MASK		G0_PORT_VID(0xfff)
-#define  G0_PORT_VID_DEF		G0_PORT_VID(1)
+#define  G0_PORT_VID_DEF		G0_PORT_VID(0)
 
 /* Register for port MAC control register */
 #define MT7530_PMCR_P(x)		(0x3000 + ((x) * 0x100))
-- 
2.25.1



From dqfext at gmail.com  Tue Aug  3 09:04:03 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed,  4 Aug 2021 00:04:03 +0800
Subject: [PATCH net-next v2 3/4] net: dsa: mt7530: set STP state on filter ID 1
In-Reply-To: <20210803160405.3025624-1-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
Message-ID: <20210803160405.3025624-4-dqfext@gmail.com>

As filter ID 1 is the only one used for bridges, set STP state on it.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
v1 -> v2: use FID enum instead of hardcoding.

 drivers/net/dsa/mt7530.c | 3 ++-
 drivers/net/dsa/mt7530.h | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 606a9f4db579..9b39ccd9dd4c 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1147,7 +1147,8 @@ mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 		break;
 	}
 
-	mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK, stp_state);
+	mt7530_rmw(priv, MT7530_SSP_P(port), FID_PST_MASK(FID_BRIDGED),
+		   FID_PST(FID_BRIDGED, stp_state));
 }
 
 static int
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index d44640bbd865..5b70ccef9459 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -186,8 +186,8 @@ enum mt7530_vlan_egress_attr {
 
 /* Register for port STP state control */
 #define MT7530_SSP_P(x)			(0x2000 + ((x) * 0x100))
-#define  FID_PST(x)			((x) & 0x3)
-#define  FID_PST_MASK			FID_PST(0x3)
+#define  FID_PST(fid, state)		(((state) & 0x3) << ((fid) * 2))
+#define  FID_PST_MASK(fid)		FID_PST(fid, 0x3)
 
 enum mt7530_stp_state {
 	MT7530_STP_DISABLED = 0,
-- 
2.25.1



From dqfext at gmail.com  Tue Aug  3 09:04:04 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed,  4 Aug 2021 00:04:04 +0800
Subject: [PATCH net-next v2 4/4] net: dsa: mt7530: always install FDB entries
 with IVL and FID 1
In-Reply-To: <20210803160405.3025624-1-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
Message-ID: <20210803160405.3025624-5-dqfext@gmail.com>

This reverts commit 7e777021780e ("mt7530 mt7530_fdb_write only set ivl
bit vid larger than 1").

Before this series, the default value of all ports' PVID is 1, which is
copied into the FDB entry, even if the ports are VLAN unaware. So
`bridge fdb show` will show entries like `dev swp0 vlan 1 self` even on
a VLAN-unaware bridge.

The blamed commit does not solve that issue completely, instead it may
cause a new issue that FDB is inaccessible in a VLAN-aware bridge with
PVID 1.

This series sets PVID to 0 on VLAN-unaware ports, so `bridge fdb show`
will no longer print `vlan 1` on VLAN-unaware bridges, and that special
case in fdb_write is not required anymore.

Set FDB entries' filter ID to 1 to match the VLAN table.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
v1 -> v2: use FID enum instead of hardcoding.

 drivers/net/dsa/mt7530.c | 4 ++--
 drivers/net/dsa/mt7530.h | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 9b39ccd9dd4c..385e169080d9 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -366,8 +366,8 @@ mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,
 	int i;
 
 	reg[1] |= vid & CVID_MASK;
-	if (vid > 1)
-		reg[1] |= ATA2_IVL;
+	reg[1] |= ATA2_IVL;
+	reg[1] |= ATA2_FID(FID_BRIDGED);
 	reg[2] |= (aging & AGE_TIMER_MASK) << AGE_TIMER;
 	reg[2] |= (port_mask & PORT_MAP_MASK) << PORT_MAP;
 	/* STATIC_ENT indicate that entry is static wouldn't
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 5b70ccef9459..4a91d80f51bb 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -80,6 +80,7 @@ enum mt753x_bpdu_port_fw {
 #define  STATIC_ENT			3
 #define MT7530_ATA2			0x78
 #define  ATA2_IVL			BIT(15)
+#define  ATA2_FID(x)			(((x) & 0x7) << 12)
 
 /* Register for address table write data */
 #define MT7530_ATWD			0x7c
-- 
2.25.1



From sre at kernel.org  Tue Aug  3 09:14:59 2021
From: sre at kernel.org (Sebastian Reichel)
Date: Tue, 3 Aug 2021 18:14:59 +0200
Subject: [PATCH 3/3] power: reset: Enable tristate on restart power-off
 driver
In-Reply-To: <20210803155452.435812-4-lee.jones@linaro.org>
References: <20210803155452.435812-1-lee.jones@linaro.org>
 <20210803155452.435812-4-lee.jones@linaro.org>
Message-ID: <20210803161459.5752zkc6jhj3mduf@earth.universe>

Hi,

On Tue, Aug 03, 2021 at 04:54:52PM +0100, Lee Jones wrote:
> From: Elliot Berman <eberman at codeaurora.org>
> 
> Since reboot_mode is an exported symbol, restart power-off driver can be
> compiled as module.
> 
> Signed-off-by: Elliot Berman <eberman at codeaurora.org>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---

Acked-by: Sebastian Reichel <sre at kernel.org>

-- Sebastian

>  drivers/power/reset/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
> index 4d1192062508d..e155b2e2a75c4 100644
> --- a/drivers/power/reset/Kconfig
> +++ b/drivers/power/reset/Kconfig
> @@ -192,7 +192,7 @@ config POWER_RESET_REGULATOR
>  	  power regulator defined in the devicetree.
>  
>  config POWER_RESET_RESTART
> -	bool "Restart power-off driver"
> +	tristate "Restart power-off driver"
>  	help
>  	  Some boards don't actually have the ability to power off.
>  	  Instead they restart, and u-boot holds the SoC until the
> -- 
> 2.32.0.554.ge1b32706d8-goog
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210803/a131d025/attachment.sig>

From catalin.marinas at arm.com  Tue Aug  3 09:19:26 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 3 Aug 2021 17:19:26 +0100
Subject: [PATCH v2] arch: vdso: remove if-conditionals of
 $(c-gettimeofday-y)
In-Reply-To: <20210731060020.12913-1-masahiroy@kernel.org>
References: <20210731060020.12913-1-masahiroy@kernel.org>
Message-ID: <20210803161925.GC5786@arm.com>

On Sat, Jul 31, 2021 at 03:00:20PM +0900, Masahiro Yamada wrote:
> arm, arm64, csky, mips, powerpc always select GENERIC_GETTIMEOFDAY,
> hence $(gettimeofday-y) never becomes empty.
> 
> riscv conditionally selects GENERIC_GETTIMEOFDAY when MMU=y && 64BIT=y,
> but arch/riscv/kernel/vdso/vgettimeofday.o is built only under that
> condition. So, you can always define CFLAGS_vgettimeofday.o
> 
> Remove all the meaningless conditionals.
> 
> Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From jason-jh.lin at mediatek.com  Tue Aug  3 09:11:33 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 4 Aug 2021 00:11:33 +0800
Subject: [PATCH v5 1/6] arm64: dts: mt8195: add display node for vdosys0
In-Reply-To: <CAAOTY_9sasTb=W3Kkhx-UZ-ATSe_ge8A14pmOHFCOQjag89r0Q@mail.gmail.com>
References: <20210729170737.21424-1-jason-jh.lin@mediatek.com>
 <20210729170737.21424-2-jason-jh.lin@mediatek.com>
 <CAAOTY_9sasTb=W3Kkhx-UZ-ATSe_ge8A14pmOHFCOQjag89r0Q@mail.gmail.com>
Message-ID: <134fedc082a5d698f2f3a2143c0ce8757f3aaf0c.camel@mediatek.com>

Hi CK,

On Sun, 2021-08-01 at 08:36 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?7?30? ?? ??1:07???
> > 
> > Add display node for vdosys0.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> > This patch is based on [1][2][3][4]
> > 
> > [1]arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and
> > Makefile
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/__;!!CTRNKA9wMg0ARbw!3bjfjGf2GYJ5FQ5EWsjG9yPGwf6uVMv8dDyXLY2Tlq_sTczeIJkEDTWVt1dxp4b7tojj$
> >  
> > [2]arm64: dts: mt8195: add IOMMU and smi nodes
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/__;!!CTRNKA9wMg0ARbw!3bjfjGf2GYJ5FQ5EWsjG9yPGwf6uVMv8dDyXLY2Tlq_sTczeIJkEDTWVt1dxp0sfXPc-$
> >  
> > [3]arm64: dts: mt8195: add gce node
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210705053429.4380-4-jason-jh.lin at mediatek.com/__;!!CTRNKA9wMg0ARbw!3bjfjGf2GYJ5FQ5EWsjG9yPGwf6uVMv8dDyXLY2Tlq_sTczeIJkEDTWVt1dxp5uw6cqB$
> >  
> > [4]add mt8195 SoC DRM binding
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597__;!!CTRNKA9wMg0ARbw!3bjfjGf2GYJ5FQ5EWsjG9yPGwf6uVMv8dDyXLY2Tlq_sTczeIJkEDTWVt1dxp0qn1imR$
> >  
> > ---
> >  arch/arm64/boot/dts/mediatek/mt8195.dtsi | 112
> > +++++++++++++++++++++++
> >  1 file changed, 112 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > index 04d3e95175fa..4fa47cb2bede 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > @@ -1155,9 +1155,121 @@
> >                         #clock-cells = <1>;
> >                 };
> > 
> 
> [snip]
> 
> > +
> > +               merge0: disp_vpp_merge0 at 1c014000 {
> > +                       compatible = "mediatek,mt8195-disp-merge";
> > +                       reg = <0 0x1c014000 0 0x1000>;
> > +                       interrupts = <GIC_SPI 656
> > IRQ_TYPE_LEVEL_HIGH 0>;
> > +                       power-domains = <&spm
> > MT8195_POWER_DOMAIN_VDOSYS0>;
> > +                       clocks = <&vdosys0 CLK_VDO0_VPP_MERGE0>;
> 
> Why this merge has no async clock?
> 
> Regards,
> Chun-Kuang.
> 
Only the MERGE linked to the display function block that is cross
vdosys0 to vdosys1 need to add async clock.

I'll add this description into this patch [1]
[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20210729154912.20051-4-jason-jh.lin at mediatek.com/

Regards,
Jason-JH.Lin

> > +                       mediatek,gce-client-reg =
> > +                                <&gce1 SUBSYS_1c01XXXX 0x4000
> > 0x1000>;
> > +               };
> > +
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From mathieu.poirier at linaro.org  Tue Aug  3 09:23:11 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 3 Aug 2021 10:23:11 -0600
Subject: [PATCH v2 1/5] remoteproc: Add support for detach-only during
 shutdown
In-Reply-To: <cd399fef-6db7-72eb-933f-7454a043ed14@ti.com>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-2-s-anna@ti.com>
 <20210802184431.GC3051951@p14s>
 <cd399fef-6db7-72eb-933f-7454a043ed14@ti.com>
Message-ID: <20210803162311.GB3091608@p14s>

Good morning,

On Mon, Aug 02, 2021 at 06:21:38PM -0500, Suman Anna wrote:
> Hi Mathieu,
> 
> On 8/2/21 1:44 PM, Mathieu Poirier wrote:
> > On Fri, Jul 23, 2021 at 05:02:44PM -0500, Suman Anna wrote:
> >> The remoteproc core has support for both stopping and detaching a
> >> remote processor that was attached to previously, through both the
> >> remoteproc sysfs and cdev interfaces. The rproc_shutdown() though
> >> unconditionally only uses the stop functionality at present. This
> >> may not be the default desired functionality for all the remoteproc
> >> platform drivers.
> >>
> >> Enhance the remoteproc core logic to key off the presence of the
> >> .stop() ops and allow the individual remoteproc drivers to continue
> >> to use the standard rproc_add() and rproc_del() API. This allows
> >> the remoteproc drivers to only do detach if supported when the driver
> >> is uninstalled, and the remote processor continues to run undisturbed
> >> even after the driver removal.
> >>
> >> Signed-off-by: Suman Anna <s-anna at ti.com>
> >> ---
> >> v2: Addressed various review comments from v1
> >>  - Reworked the logic to not use remoteproc detach_on_shutdown and
> >>    rely only on rproc callback ops
> >>  - Updated the last para of the patch description
> >> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-3-s-anna at ti.com/
> >>
> >>  drivers/remoteproc/remoteproc_cdev.c  | 7 +++++++
> >>  drivers/remoteproc/remoteproc_core.c  | 5 ++++-
> >>  drivers/remoteproc/remoteproc_sysfs.c | 6 ++++++
> >>  3 files changed, 17 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c
> >> index 4ad98b0b8caa..16c932beed88 100644
> >> --- a/drivers/remoteproc/remoteproc_cdev.c
> >> +++ b/drivers/remoteproc/remoteproc_cdev.c
> >> @@ -42,6 +42,13 @@ static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_
> >>  		    rproc->state != RPROC_ATTACHED)
> >>  			return -EINVAL;
> >>  
> >> +		if (rproc->state == RPROC_ATTACHED &&
> > 
> > This is already checked just above.
> > 
> >> +		    !rproc->ops->stop) {
> 
> Well, this is checking for both conditions, and not just the stop ops
> independently. We expect to have .stop() defined normally for both regular
> remoteproc mode and attached mode where you want to stop (and not detach), but
> as you can see, I am supporting only detach and so will not have .stop() defined
>  with RPROC_ATTACHED.
> 
> > 
> > This is checked in rproc_stop() where -EINVAL is returned if ops::stop has not
> > been provided.
> 
> rproc_shutdown() actually doesn't return any status, so all its internal
> checking gets ignored and a success is returned today.
> 

That is correct, and I have suggested to add a return value in my previous
review.

> > 
> >> +			dev_err(&rproc->dev,
> >> +				"stop not supported for this rproc, use detach\n");
> > 
> > The standard error message from the shell should be enough here, the same way it
> > is enough when the "start" and "stop" scenarios fail.
> 
> Thought this was a bit more informative, but sure this trace can be dropped.
> 
> > 
> >> +			return -EINVAL;
> >> +		}
> >> +
> >>  		rproc_shutdown(rproc);
> >>  	} else if (!strncmp(cmd, "detach", len)) {
> >>  		if (rproc->state != RPROC_ATTACHED)
> >> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> >> index 7de5905d276a..ab9e52180b04 100644
> >> --- a/drivers/remoteproc/remoteproc_core.c
> >> +++ b/drivers/remoteproc/remoteproc_core.c
> >> @@ -2075,7 +2075,10 @@ void rproc_shutdown(struct rproc *rproc)
> >>  	if (!atomic_dec_and_test(&rproc->power))
> >>  		goto out;
> >>  
> >> -	ret = rproc_stop(rproc, false);
> >> +	if (rproc->state == RPROC_ATTACHED && !rproc->ops->stop)
> >> +		ret = __rproc_detach(rproc);
> >> +	else
> >> +		ret = rproc_stop(rproc, false);
> > 
> > As I indicated in my last review I think rproc_shutdown() and rproc_del() should
> > be decoupled and the right call made in the platform drivers based on the state
> > of the remote processor.  
> 
> We have various remoteproc API provided in pairs - rproc_alloc()/rproc_free(),
> rproc_add()/rproc_del(), rproc_boot()/rproc_shutdown() and
> rproc_attach()/rproc_detach(). The drivers are configuring conditions for
> auto-boot and RPROC_DETACHED. The reason they are coupled is primarily because
> of the auto-boot done during rproc_add(). And we handle the RPROC_DETACHED case
> just as well in rproc_boot().
>

The difference with rproc_boot() is that we are checking only the state of the
remoteproc, everything else related to the remote processor operations is
seamlessly handles by the state machine.  It is also tied to the
rproc_trigger_auto_boot() mechanic - decoupling that would be messy without
bringing any advantages other than keeping with a semantic symmetry.

> While what you have suggested works, but I am not quite convinced on this
> asymmetric usage, and why this state-machine logic should be split between the
> core and remoteproc drivers differently between attach and detach. To me,
> calling rproc_detach() in remoteproc drivers would have made sense only if they
> are also calling rproc_attach().

As pointed out above I see rproc_boot() as a special case but if that really
concerns you I'm open to consider patches that will take rproc_attach() out of
rproc_boot(). 

> 
> 
> Conditions such as the above make the core code
> > brittle, difficult to understand and tedious to maintain.
> 
> The logic I have added actually makes rproc_shutdown behavior to be on par with
> the rproc_boot().
> 
> regards
> Suman
> 
> > 
> > Thanks,
> > Mathieu
> > 
> >>  	if (ret) {
> >>  		atomic_inc(&rproc->power);
> >>  		goto out;
> >> diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
> >> index ea8b89f97d7b..133e766f38d4 100644
> >> --- a/drivers/remoteproc/remoteproc_sysfs.c
> >> +++ b/drivers/remoteproc/remoteproc_sysfs.c
> >> @@ -206,6 +206,12 @@ static ssize_t state_store(struct device *dev,
> >>  		    rproc->state != RPROC_ATTACHED)
> >>  			return -EINVAL;
> >>  
> >> +		if (rproc->state == RPROC_ATTACHED &&
> >> +		    !rproc->ops->stop) {
> >> +			dev_err(&rproc->dev, "stop not supported for this rproc, use detach\n");
> >> +			return -EINVAL;
> >> +		}
> >> +
> >>  		rproc_shutdown(rproc);
> >>  	} else if (sysfs_streq(buf, "detach")) {
> >>  		if (rproc->state != RPROC_ATTACHED)
> >> -- 
> >> 2.32.0
> >>
> 


From nfraprado at collabora.com  Tue Aug  3 09:26:36 2021
From: nfraprado at collabora.com (=?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=)
Date: Tue,  3 Aug 2021 13:26:36 -0300
Subject: [PATCH v3 0/5] Add support for QCOM SPMI Flash LEDs
Message-ID: <20210803162641.1525980-1-nfraprado@collabora.com>

Hi,

this patch series adds support for Qualcomm's SPMI Flash LEDs present in the
PM8941 PMIC. It is used as part of MSM8974 based devices, like the Nexus 5
(hammerhead), as a camera flash or as a lantern when in torch mode.

The driver code is based on the parts of the QPNP LEDs driver from downstream
[1] that handled the flash LED.

This hardware doesn't have any publicly available documentation, so all my
knowledge about its behavior came from reading the downstream driver code and
from inspecting the SPMI registers used for the LED operations. I have collected
my findings at [2].

Bjorn, Jacek and Pavel, big thanks for your review in v2. I didn't answer the
emails but I believe I addressed all of the feedback you gave me. Sorry for the
long delay, I'll try to actually answer the feedback this time, and in a timely
manner too.

The changes in this v3 are too many to list, but the biggest ones were:
- The two LEDs can now be operated independently even when in torch mode
- The flashes can now strobe consecutive times without needing to manually
  disable them between strobes
- Implemented strobe_get()
- Moved dt parsing to a separate function
- Split multiplexed torch/flash on/off and torch/flash regulator on/off
  functions
- Removed configurations from the dt-binding that didn't have any visible
  impact, instead hardcoding them inside the driver
- Moved LED dt nodes configuration to hammerhead dts
- Set current on brightness callback and timeout on timeout callback, instead of
  setting everything every time when strobing/turning torch on

Fault detection and V4L2 flash wrapper support are still missing but, as others
have pointed out before, they can be implemented later if desired.

Thanks,
N?colas

v2: https://lore.kernel.org/linux-arm-msm/20210126140240.1517044-1-nfraprado at protonmail.com/
v1 RFC: https://lore.kernel.org/linux-arm-msm/20201106165737.1029106-1-nfraprado at protonmail.com/

[1] https://github.com/AICP/kernel_lge_hammerhead/blob/n7.1/drivers/leds/leds-qpnp.c
[2] https://gitlab.collabora.com/nfraprado/linux/-/wikis/PM8941-Flash-LEDs

N?colas F. R. A. Prado (5):
  dt-bindings: leds: Add binding for qcom-spmi-flash
  leds: Add driver for QCOM SPMI Flash LEDs
  ARM: qcom_defconfig: Enable QCOM SPMI Flash LEDs
  ARM: dts: qcom: pm8941: Add nodes for QCOM SPMI Flash LEDs
  ARM: dts: qcom: msm8974-hammerhead: Enable and configure flash LED
    node

 .../bindings/leds/leds-qcom-spmi-flash.yaml   |   93 ++
 .../qcom-msm8974-lge-nexus5-hammerhead.dts    |   20 +
 arch/arm/boot/dts/qcom-pm8941.dtsi            |   25 +
 arch/arm/configs/qcom_defconfig               |    2 +
 drivers/leds/flash/Kconfig                    |    8 +
 drivers/leds/flash/Makefile                   |    1 +
 drivers/leds/flash/leds-qcom-spmi-flash.c     | 1251 +++++++++++++++++
 7 files changed, 1400 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml
 create mode 100644 drivers/leds/flash/leds-qcom-spmi-flash.c

-- 
2.32.0



From nfraprado at collabora.com  Tue Aug  3 09:26:37 2021
From: nfraprado at collabora.com (=?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=)
Date: Tue,  3 Aug 2021 13:26:37 -0300
Subject: [PATCH v3 1/5] dt-bindings: leds: Add binding for qcom-spmi-flash
In-Reply-To: <20210803162641.1525980-1-nfraprado@collabora.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
Message-ID: <20210803162641.1525980-2-nfraprado@collabora.com>

Add devicetree binding for Qualcomm's SPMI Flash LEDs which are part of
the PM8941 PMIC. These LEDs are used both as lantern and camera flash on
phones based on the MSM8974 SoC, like the Nexus 5.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---

Changes in v3:
- Removed clamp-curr, headroom, startup-dly and safety-timer properties since
  they didn't impact the behavior. They're now hardcoded in the driver (patch 2)
- Added valid ranges for led-max-microamp, flash-max-microamp and
  flash-max-timeout-us
- Removed dt-bindings header file that held some constants (moved to inside the
  driver in patch 2)

Added in v2

 .../bindings/leds/leds-qcom-spmi-flash.yaml   | 93 +++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml

diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml
new file mode 100644
index 000000000000..da674d73c033
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/leds-qcom-spmi-flash.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SPMI Flash LEDs
+
+maintainers:
+  - N?colas F. R. A. Prado <n at nfraprado.net>
+
+description: |
+  The Qualcomm SPMI Flash LEDs are part of Qualcomm PMICs and are used primarily
+  as a camera or video flash. They can also be used as a lantern when on torch
+  mode.
+  The PMIC is connected to Host processor via SPMI bus.
+
+properties:
+  compatible:
+    const: qcom,spmi-flash-leds
+
+  reg:
+    maxItems: 1
+
+  flash-boost-supply:
+    description: SMBB regulator for LED flash mode
+
+  torch-boost-supply:
+    description: SMBB regulator for LED torch mode
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+patternProperties:
+  "^led@[0-1]$":
+    type: object
+    $ref: common.yaml#
+
+    properties:
+      reg:
+        maxItems: 1
+
+      led-max-microamp:
+        minimum: 12500
+        maximum: 200000
+        multipleOf: 12500
+
+      flash-max-microamp:
+        minimum: 12500
+        maximum: 1000000
+        multipleOf: 12500
+
+      flash-max-timeout-us:
+        minimum: 10000
+        maximum: 1280000
+        multipleOf: 10000
+
+    required:
+      - reg
+
+required:
+  - compatible
+  - reg
+  - flash-boost-supply
+  - torch-boost-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/leds/common.h>
+
+    spmi-flash-leds at d300 {
+        compatible = "qcom,spmi-flash-leds";
+        reg = <0xd300 0x100>;
+        flash-boost-supply = <&pm8941_5vs1>;
+        torch-boost-supply = <&pm8941_5v>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        led at 0 {
+            reg = <0>;
+            function = LED_FUNCTION_FLASH;
+            color = <LED_COLOR_ID_WHITE>;
+            led-max-microamp = <200000>;
+            flash-max-microamp = <1000000>;
+            flash-max-timeout-us = <1280000>;
+        };
+    };
+...
-- 
2.32.0



From nfraprado at collabora.com  Tue Aug  3 09:26:38 2021
From: nfraprado at collabora.com (=?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=)
Date: Tue,  3 Aug 2021 13:26:38 -0300
Subject: [PATCH v3 2/5] leds: Add driver for QCOM SPMI Flash LEDs
In-Reply-To: <20210803162641.1525980-1-nfraprado@collabora.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
Message-ID: <20210803162641.1525980-3-nfraprado@collabora.com>

Add driver for Qualcomm's SPMI Flash LEDs. These are controlled
through an SPMI bus and are part of the PM8941 PMIC. There are two LEDs
present on the chip, which can be used independently as camera flash or,
when in torch mode, as a lantern.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---

Changes in v3:
- The two LEDs can now be operated independently even when in torch mode
- The flashes can now strobe consecutive times without needing to manually
  disable them between strobes
- Implemented strobe_get()
- Moved dt parsing to a separate function
- Split multiplexed torch/flash on/off and torch/flash regulator on/off
  functions
- Set current on brightness callback and timeout on timeout callback, instead of
  setting everything every time when strobing/turning torch on
- And a whole lot of other minor changes

Changes in v2:
- Thanks to Jacek:
  - Implemented flash LED class framework
- Thanks to Bjorn:
  - Renamed driver to "qcom spmi flash"
- Refactored code
- Added missing copyright

 drivers/leds/flash/Kconfig                |    8 +
 drivers/leds/flash/Makefile               |    1 +
 drivers/leds/flash/leds-qcom-spmi-flash.c | 1251 +++++++++++++++++++++
 3 files changed, 1260 insertions(+)
 create mode 100644 drivers/leds/flash/leds-qcom-spmi-flash.c

diff --git a/drivers/leds/flash/Kconfig b/drivers/leds/flash/Kconfig
index 3f49f3edbffb..72f61323cd2a 100644
--- a/drivers/leds/flash/Kconfig
+++ b/drivers/leds/flash/Kconfig
@@ -24,4 +24,12 @@ config LEDS_RT8515
 	  To compile this driver as a module, choose M here: the module
 	  will be called leds-rt8515.
 
+config LEDS_QCOM_SPMI_FLASH
+	tristate "Support for QCOM SPMI Flash LEDs"
+	depends on REGMAP_SPMI
+	depends on OF
+	help
+	  This option enables support for the flash/torch LEDs present in
+	  Qualcomm's PM8941 PMIC.
+
 endif # LEDS_CLASS_FLASH
diff --git a/drivers/leds/flash/Makefile b/drivers/leds/flash/Makefile
index 09aee561f769..c141d277e9b6 100644
--- a/drivers/leds/flash/Makefile
+++ b/drivers/leds/flash/Makefile
@@ -2,3 +2,4 @@
 
 obj-$(CONFIG_LEDS_RT4505)	+= leds-rt4505.o
 obj-$(CONFIG_LEDS_RT8515)	+= leds-rt8515.o
+obj-$(CONFIG_LEDS_QCOM_SPMI_FLASH)	+= leds-qcom-spmi-flash.o
diff --git a/drivers/leds/flash/leds-qcom-spmi-flash.c b/drivers/leds/flash/leds-qcom-spmi-flash.c
new file mode 100644
index 000000000000..9763707bb986
--- /dev/null
+++ b/drivers/leds/flash/leds-qcom-spmi-flash.c
@@ -0,0 +1,1251 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Qualcomm SPMI Flash LEDs Driver
+ *
+ * Copyright (c) 2020-2021, N?colas F. R. A. Prado <n at nfraprado.net>
+ * Copyright (c) 2021, Collabora Ltd.
+ *
+ * Based on QPNP LEDs driver from downstream MSM kernel sources.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/led-class-flash.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spmi.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+
+#define QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE	0x05
+#define QCOM_FLASH_ADDR_STATUS			0x10
+#define QCOM_FLASH_ADDR_SAFETY_TIMER		0x40
+#define QCOM_FLASH_ADDR_MAX_CURR		0x41
+#define QCOM_FLASH_ADDR_CURR_LED0		0x42
+#define QCOM_FLASH_ADDR_CURR_LED1		0x43
+#define QCOM_FLASH_ADDR_CLAMP_CURR		0x44
+#define QCOM_FLASH_ADDR_ENABLE_CONTROL		0x46
+#define QCOM_FLASH_ADDR_LED_STROBE_CTRL		0x47
+#define QCOM_FLASH_ADDR_LED_TMR_CTRL		0x48
+#define QCOM_FLASH_ADDR_HEADROOM		0x4A
+#define QCOM_FLASH_ADDR_STARTUP_DELAY		0x4B
+#define QCOM_FLASH_ADDR_MASK_ENABLE		0x4C
+#define QCOM_FLASH_ADDR_VREG_OK_FORCE		0x4F
+#define QCOM_FLASH_ADDR_LED_UNLOCK_SECURE	0xD0
+#define QCOM_FLASH_ADDR_LED_TORCH		0xE4
+#define QCOM_FLASH_ADDR_FAULT_DETECT		0x51
+#define QCOM_FLASH_ADDR_RAMP_RATE		0x54
+#define QCOM_FLASH_ADDR_VPH_PWR_DROOP		0x5A
+
+#define QCOM_FLASH_MAX_LEVEL		0x4F
+#define QCOM_FLASH_TORCH_MAX_LEVEL	0x0F
+#define	QCOM_FLASH_NO_MASK		0x00
+
+#define QCOM_FLASH_MASK_1		0x20
+#define QCOM_FLASH_MASK_REG_MASK	0xE0
+#define QCOM_FLASH_HEADROOM_MASK	0x03
+#define QCOM_FLASH_SAFETY_TIMER_MASK	0x7F
+#define QCOM_FLASH_CURRENT_MASK		0xFF
+#define QCOM_FLASH_MAX_CURRENT_MASK	0x7F
+#define QCOM_FLASH_TMR_MASK		0x03
+#define QCOM_FLASH_TMR_WATCHDOG		0x03
+#define QCOM_FLASH_TMR_SAFETY		0x00
+#define QCOM_FLASH_FAULT_DETECT_MASK	0x80
+#define QCOM_FLASH_HW_VREG_OK		0x40
+#define QCOM_FLASH_VREG_MASK		0xC0
+#define QCOM_FLASH_STARTUP_DLY_MASK	0x02
+#define QCOM_FLASH_RAMP_RATE_MASK	0xBF
+#define QCOM_FLASH_VPH_PWR_DROOP_MASK	0xF3
+
+#define QCOM_FLASH_ENABLE_ALL		0xE0
+#define QCOM_FLASH_ENABLE_MODULE	0x80
+#define QCOM_FLASH_ENABLE_MODULE_MASK	0x80
+#define QCOM_FLASH_DISABLE_ALL		0x00
+#define QCOM_FLASH_ENABLE_MASK		0xE0
+#define QCOM_FLASH_ENABLE_LED0		0xC0
+#define QCOM_FLASH_ENABLE_LED1		0xA0
+#define QCOM_FLASH_INIT_MASK		0xE0
+#define QCOM_FLASH_SELFCHECK_ENABLE	0x80
+#define QCOM_FLASH_SELFCHECK_DISABLE	0x00
+
+#define QCOM_FLASH_STROBE_SW		0xC0
+#define QCOM_FLASH_STROBE_HW		0x04
+#define QCOM_FLASH_STROBE_MASK		0xC7
+#define QCOM_FLASH_STROBE_LED0		0x80
+#define QCOM_FLASH_STROBE_LED1		0x40
+
+#define QCOM_FLASH_TORCH_MASK		0x03
+#define QCOM_FLASH_LED_TORCH_ENABLE	0x00
+#define QCOM_FLASH_LED_TORCH_DISABLE	0x03
+#define QCOM_FLASH_UNLOCK_SECURE	0xA5
+#define QCOM_FLASH_SECURE_MASK		0xFF
+
+#define QCOM_FLASH_SUBTYPE_DUAL		0x01
+#define QCOM_FLASH_SUBTYPE_SINGLE	0x02
+
+#define QCOM_FLASH_DURATION_STEP	10000
+#define QCOM_FLASH_DURATION_MIN		10000
+#define QCOM_FLASH_DURATION_DEFAULT	200000
+
+#define QCOM_FLASH_CURRENT_STEP		12500
+#define QCOM_FLASH_CURRENT_MIN		12500
+
+#define QCOM_FLASH_DEFAULT_CLAMP	200000
+
+#define QCOM_FLASH_MASK_ON_LED0		0x8
+#define QCOM_FLASH_MASK_ON_LED1		0x2
+#define QCOM_FLASH_MASK_STATUS_TIMEDOUT	0x5
+
+enum qcom_flash_headroom {
+	QCOM_FLASH_HEADROOM_250MV,
+	QCOM_FLASH_HEADROOM_300MV,
+	QCOM_FLASH_HEADROOM_400MV,
+	QCOM_FLASH_HEADROOM_500MV,
+};
+
+enum qcom_flash_startup_dly {
+	QCOM_FLASH_STARTUP_DLY_10US,
+	QCOM_FLASH_STARTUP_DLY_32US,
+	QCOM_FLASH_STARTUP_DLY_64US,
+	QCOM_FLASH_STARTUP_DLY_128US,
+};
+
+enum qcom_flash_ids {
+	QCOM_FLASH_ID_LED0,
+	QCOM_FLASH_ID_LED1,
+};
+
+/**
+ * struct qcom_flash_led - Represents each individual flash LED
+ * @fled_cdev: flash LED classdev
+ * @id: LED ID as given by enum qcom_flash_ids
+ * @default_on: default state for the LED
+ * @flash_enable_cmd: enable command for particular flash
+ * @flash_strobe_cmd: strobe command for particular flash
+ * @current_addr: address to write for current
+ * @mask_led_on: bitmask for STATUS register that shows if LED is on
+ * @flash_current_invalidated: whether the flash current in the current register
+ *	was invalidated by torch usage
+ */
+struct qcom_flash_led {
+	struct led_classdev_flash fled_cdev;
+	enum qcom_flash_ids id;
+	bool default_on;
+	u8 flash_enable_cmd;
+	u8 flash_strobe_cmd;
+	u16 current_addr;
+	u8 mask_led_on;
+	bool flash_current_invalidated;
+};
+
+/**
+ * struct qcom_flash_device - QCOM SPMI Flash device, contains 2 flash LEDs
+ * @regmap: regmap used to access LED registers over SPMI
+ * @base: base register given in device tree
+ * @dev: device from devicetree
+ * @flash_supply: voltage regulator to supply the flashes
+ * @torch_supply: voltage regulator to supply torch mode
+ * @leds: flash LEDs
+ * @num_leds: number of LEDs registered (between 0 and 2)
+ * @lock: lock to protect SPMI transactions
+ * @torch_enable_cmd: enable flash LED torch mode
+ * @peripheral_subtype: module peripheral subtype
+ * @flash_regulator_on: flash regulator status
+ * @torch_regulator_on: torch regulator status
+ * @torch_enabled: whether torch mode is enabled
+ */
+struct qcom_flash_device {
+	struct regmap *regmap;
+	unsigned int base;
+	struct device *dev;
+	struct regulator *flash_supply;
+	struct regulator *torch_supply;
+	struct qcom_flash_led leds[2];
+	u8 num_leds;
+	struct mutex lock;
+	u8 torch_enable_cmd;
+	unsigned int peripheral_subtype;
+	bool flash_regulator_on;
+	bool torch_regulator_on;
+	bool torch_enabled;
+};
+
+struct qcom_flash_config {
+	unsigned int base;
+	struct regulator *flash_supply;
+	struct regulator *torch_supply;
+	unsigned int num_leds;
+
+	enum qcom_flash_ids id[2];
+	bool default_on[2];
+	u32 led_max_brightness[2];
+	u32 flash_max_brightness[2];
+	u32 flash_max_timeout[2];
+};
+
+static inline struct qcom_flash_led *flcdev_to_led(struct led_classdev_flash *fled_cdev)
+{
+	return container_of(fled_cdev, struct qcom_flash_led, fled_cdev);
+}
+
+static inline struct qcom_flash_device *led_to_leds_dev(struct qcom_flash_led *led)
+{
+	return container_of(led, struct qcom_flash_device, leds[led->id]);
+}
+
+static inline int qcom_flash_read_reg(struct qcom_flash_device *leds_dev,
+				      unsigned int reg, unsigned int *val)
+{
+	return regmap_read(leds_dev->regmap, leds_dev->base + reg, val);
+}
+
+static inline int qcom_flash_masked_write(struct qcom_flash_device *leds_dev,
+					  unsigned int reg, unsigned int mask,
+					  unsigned int val)
+{
+	return regmap_update_bits(leds_dev->regmap, leds_dev->base + reg, mask,
+				  val);
+}
+
+static u8 qcom_flash_duration_to_reg(u32 us)
+{
+	if (us < QCOM_FLASH_DURATION_MIN)
+		us = QCOM_FLASH_DURATION_MIN;
+	return (us - QCOM_FLASH_DURATION_MIN) / QCOM_FLASH_DURATION_STEP;
+}
+
+static u8 qcom_flash_current_to_reg(u32 ua)
+{
+	if (ua < QCOM_FLASH_CURRENT_MIN)
+		ua = QCOM_FLASH_CURRENT_MIN;
+	return (ua - QCOM_FLASH_CURRENT_MIN) / QCOM_FLASH_CURRENT_STEP;
+}
+
+static void clamp_align(u32 *v, u32 min, u32 max, u32 step)
+{
+	*v = clamp_val(*v, min, max);
+	if (step > 1)
+		*v = (*v - min) / step * step + min;
+}
+
+static int qcom_flash_status_get(struct qcom_flash_led *led)
+{
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	unsigned int status;
+	int rc;
+
+	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_STATUS, &status);
+	if (rc) {
+		dev_err(leds_dev->dev, "Failure reading status, rc =  %d\n",
+			rc);
+		return rc;
+	}
+
+	return status & led->mask_led_on;
+}
+
+static int qcom_flash_status_clear(struct qcom_flash_device *leds_dev)
+{
+	unsigned int enable_val;
+	int rc;
+
+	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
+				 &enable_val);
+	if (rc) {
+		dev_err(leds_dev->dev, "Enable reg read failed(%d)\n", rc);
+		return rc;
+	}
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
+				     QCOM_FLASH_ENABLE_MASK, QCOM_FLASH_DISABLE_ALL);
+	if (rc) {
+		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
+				     QCOM_FLASH_ENABLE_MASK, enable_val);
+	if (rc) {
+		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int qcom_flash_check_timedout(struct qcom_flash_device *leds_dev)
+{
+	unsigned int status;
+	int rc;
+
+	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_STATUS, &status);
+	if (rc) {
+		dev_err(leds_dev->dev, "Failure reading status, rc =  %d\n",
+			rc);
+		return rc;
+	}
+
+	return status & QCOM_FLASH_MASK_STATUS_TIMEDOUT;
+}
+
+static int qcom_flash_torch_reg_enable(struct qcom_flash_device *leds_dev,
+				       bool state)
+{
+	int rc;
+
+	if (leds_dev->torch_enabled == state)
+		return 0;
+
+	/*
+	 * For the TORCH register (0xE4) to become writable, the UNLOCK_SECURE
+	 * register (0xD0) needs to be written with the UNLOCK_SECURE value
+	 * (0xA5) first.
+	 * It gets re-locked after any register write.
+	 */
+	rc = qcom_flash_masked_write(leds_dev,
+				     QCOM_FLASH_ADDR_LED_UNLOCK_SECURE,
+				     QCOM_FLASH_SECURE_MASK,
+				     QCOM_FLASH_UNLOCK_SECURE);
+	if (rc) {
+		dev_err(leds_dev->dev, "Secure reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_TORCH,
+				     QCOM_FLASH_TORCH_MASK,
+				     state ? QCOM_FLASH_LED_TORCH_ENABLE :
+					     QCOM_FLASH_LED_TORCH_DISABLE);
+	if (rc) {
+		dev_err(leds_dev->dev, "Torch reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int qcom_flash_max_brightness_set(struct qcom_flash_led *led,
+					 unsigned int brightness)
+{
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	struct device *dev = leds_dev->dev;
+	int rc;
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_MAX_CURR,
+				     QCOM_FLASH_CURRENT_MASK, brightness);
+	if (rc) {
+		dev_err(dev, "Max current reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int qcom_flash_brightness_set(struct qcom_flash_led *led,
+				     unsigned int brightness)
+{
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	struct device *dev = leds_dev->dev;
+	int rc;
+
+	rc = qcom_flash_masked_write(leds_dev, led->current_addr,
+				     QCOM_FLASH_CURRENT_MASK, brightness);
+	if (rc) {
+		dev_err(dev, "Current reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int qcom_flash_fled_regulator_on(struct qcom_flash_device *leds_dev)
+{
+	int rc;
+
+	if (leds_dev->flash_regulator_on)
+		return 0;
+
+	rc = regulator_enable(leds_dev->flash_supply);
+	if (rc) {
+		dev_err(leds_dev->dev, "Regulator enable failed(%d)\n", rc);
+		return rc;
+	}
+
+	leds_dev->flash_regulator_on = true;
+
+	return 0;
+}
+
+static int qcom_flash_fled_regulator_off(struct qcom_flash_device *leds_dev)
+{
+	unsigned int i;
+	u8 enable = 0;
+	int rc;
+
+	if (!leds_dev->flash_regulator_on)
+		return 0;
+
+	for (i = 0; i < leds_dev->num_leds; i++) {
+		rc = qcom_flash_status_get(&leds_dev->leds[i]);
+		if (rc < 0)
+			return rc;
+
+		if (!rc)
+			continue;
+
+		enable |= leds_dev->leds[i].flash_enable_cmd;
+	}
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
+				     QCOM_FLASH_ENABLE_MASK, enable);
+	if (rc)
+		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
+
+	if (enable)
+		return 0;
+
+	rc = regulator_disable(leds_dev->flash_supply);
+	if (rc) {
+		dev_err(leds_dev->dev, "Regulator disable failed(%d)\n", rc);
+		return rc;
+	}
+
+	leds_dev->flash_regulator_on = false;
+
+	return 0;
+}
+
+static int qcom_flash_torch_regulator_on(struct qcom_flash_device *leds_dev)
+{
+	int rc;
+
+	if (leds_dev->torch_regulator_on)
+		return 0;
+
+	rc = regulator_enable(leds_dev->torch_supply);
+	if (rc) {
+		dev_err(leds_dev->dev, "Regulator enable failed(%d)\n", rc);
+		return rc;
+	}
+
+	leds_dev->torch_regulator_on = true;
+
+	return 0;
+}
+
+static int qcom_flash_torch_regulator_off(struct qcom_flash_device *leds_dev)
+{
+	int rc;
+
+	if (!leds_dev->torch_regulator_on)
+		return 0;
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
+				     QCOM_FLASH_ENABLE_MODULE_MASK,
+				     QCOM_FLASH_DISABLE_ALL);
+	if (rc)
+		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
+
+	rc = regulator_disable(leds_dev->torch_supply);
+	if (rc) {
+		dev_err(leds_dev->dev, "Regulator disable failed(%d)\n", rc);
+		return rc;
+	}
+
+	leds_dev->torch_regulator_on = false;
+
+	return 0;
+}
+
+static int qcom_flash_fled_on(struct qcom_flash_led *led)
+{
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	struct device *dev = leds_dev->dev;
+	int rc, error;
+
+	rc = qcom_flash_fled_regulator_on(leds_dev);
+	if (rc)
+		goto error_flash_set;
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
+				     led->flash_enable_cmd,
+				     led->flash_enable_cmd);
+	if (rc) {
+		dev_err(dev, "Enable reg write failed(%d)\n", rc);
+		goto error_flash_set;
+	}
+
+	/*
+	 * TODO The downstream driver also allowed HW strobe. Add support for it
+	 * after v4l2 support is added and ISP can be used
+	 */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
+				     led->flash_strobe_cmd,
+				     led->flash_strobe_cmd);
+	if (rc) {
+		dev_err(dev, "LED %d strobe reg write failed(%d)\n", led->id,
+			rc);
+		goto error_flash_set;
+	}
+
+	return 0;
+
+error_flash_set:
+	error = qcom_flash_fled_regulator_off(leds_dev);
+	if (error)
+		return error;
+	return rc;
+}
+
+static int qcom_flash_fled_off(struct qcom_flash_led *led)
+{
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	struct device *dev = leds_dev->dev;
+	int rc, error;
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
+				     led->flash_strobe_cmd,
+				     QCOM_FLASH_DISABLE_ALL);
+	if (rc)
+		dev_err(dev, "LED %d flash write failed(%d)\n", led->id, rc);
+
+	error = qcom_flash_fled_regulator_off(leds_dev);
+	if (error)
+		return error;
+	return rc;
+}
+
+static int qcom_flash_torch_on(struct qcom_flash_led *led)
+{
+	int rc, error;
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	struct device *dev = leds_dev->dev;
+
+	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
+		rc = qcom_flash_torch_regulator_on(leds_dev);
+		if (rc)
+			goto error_reg_write;
+	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
+		rc = qcom_flash_fled_regulator_on(leds_dev);
+		if (rc)
+			goto error_flash_set;
+
+		/*
+		 * Write 0x80 to MODULE_ENABLE before writing
+		 * 0xE0 in order to avoid a hardware bug caused
+		 * by register value going from 0x00 to 0xE0.
+		 */
+		rc = qcom_flash_masked_write(leds_dev,
+					     QCOM_FLASH_ADDR_ENABLE_CONTROL,
+					     QCOM_FLASH_ENABLE_MODULE_MASK,
+					     QCOM_FLASH_ENABLE_MODULE);
+		if (rc) {
+			dev_err(dev, "Enable reg write failed(%d)\n", rc);
+			goto error_flash_set;
+		}
+	}
+
+	rc = qcom_flash_torch_reg_enable(leds_dev, true);
+	if (rc)
+		goto error_reg_write;
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
+				     QCOM_FLASH_ENABLE_MASK,
+				     leds_dev->torch_enable_cmd);
+	if (rc) {
+		dev_err(dev, "Enable reg write failed(%d)\n", rc);
+		goto error_reg_write;
+	}
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
+				     led->flash_strobe_cmd,
+				     led->flash_strobe_cmd);
+	if (rc) {
+		dev_err(dev, "LED %d strobe reg write failed(%d)\n", led->id,
+			rc);
+		goto error_reg_write;
+	}
+
+	leds_dev->torch_enabled = true;
+
+	return 0;
+
+error_reg_write:
+	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE)
+		goto error_flash_set;
+
+	error = qcom_flash_torch_regulator_off(leds_dev);
+	if (error)
+		return error;
+	return rc;
+
+error_flash_set:
+	error = qcom_flash_fled_regulator_off(leds_dev);
+	if (error)
+		return error;
+	return rc;
+}
+
+static int qcom_flash_torch_off(struct qcom_flash_led *led)
+{
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	struct device *dev = leds_dev->dev;
+	int rc, error;
+	unsigned int i;
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
+				     led->flash_strobe_cmd, QCOM_FLASH_DISABLE_ALL);
+	if (rc) {
+		dev_err(dev, "LED %d flash write failed(%d)\n", led->id, rc);
+		goto error_torch_set;
+	}
+
+	/* Keep torch on if the other LED is still on */
+	for (i = 0; i < leds_dev->num_leds; i++)
+		if (leds_dev->leds[i].fled_cdev.led_cdev.brightness)
+			return 0;
+
+	rc = qcom_flash_torch_reg_enable(leds_dev, false);
+	if (rc)
+		goto error_torch_set;
+
+	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
+		rc = qcom_flash_torch_regulator_off(leds_dev);
+		if (rc)
+			return rc;
+	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
+		rc = qcom_flash_fled_regulator_off(leds_dev);
+		if (rc)
+			return rc;
+	}
+
+	leds_dev->torch_enabled = false;
+
+	return 0;
+
+error_torch_set:
+	error = qcom_flash_torch_regulator_off(leds_dev);
+	if (error)
+		return error;
+	return rc;
+}
+
+static int qcom_flash_ledcdev_brightness_set(struct led_classdev *led_cdev,
+					     enum led_brightness value)
+{
+	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
+	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	unsigned int max_brightness;
+	int rc;
+
+	if (value > led_cdev->max_brightness) {
+		dev_err(leds_dev->dev, "Invalid brightness value\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&leds_dev->lock);
+	if (!value) {
+		rc = qcom_flash_torch_off(led);
+	} else {
+		/*
+		 * The minimum on value for the brightness register is 0, but for
+		 * led_classdev is 1, as 0 there means off.
+		 */
+		rc = qcom_flash_brightness_set(led, led_cdev->brightness - 1);
+		if (rc)
+			goto unlock;
+
+		led->flash_current_invalidated = true;
+
+		if (leds_dev->torch_enabled) {
+			/* Clear status to update brightness */
+			rc = qcom_flash_status_clear(leds_dev);
+			if (rc)
+				goto unlock;
+		} else {
+			/*
+			 * Clear status from previous flash strobe so the LED
+			 * can turn on
+			 */
+			rc = qcom_flash_check_timedout(leds_dev);
+			if (rc > 0)
+				rc = qcom_flash_status_clear(leds_dev);
+			else if (rc < 0)
+				goto unlock;
+
+			max_brightness = led_cdev->max_brightness - 1;
+			rc = qcom_flash_max_brightness_set(led, max_brightness);
+			if (rc)
+				goto unlock;
+		}
+		rc = qcom_flash_torch_on(led);
+	}
+
+unlock:
+	mutex_unlock(&leds_dev->lock);
+	return rc;
+}
+
+static int qcom_flash_flcdev_brightness_set(struct led_classdev_flash *fled_cdev,
+					    u32 brightness)
+{
+	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	unsigned int bright;
+	int rc;
+
+	/* Can't operate on flash if torch is on */
+	if (leds_dev->torch_enabled)
+		return -EBUSY;
+
+	clamp_align(&brightness, QCOM_FLASH_CURRENT_MIN,
+		    fled_cdev->brightness.max, QCOM_FLASH_CURRENT_STEP);
+	fled_cdev->brightness.val = brightness;
+
+	bright = qcom_flash_current_to_reg(brightness);
+
+	mutex_lock(&leds_dev->lock);
+	rc = qcom_flash_brightness_set(led, bright);
+	if (rc)
+		goto unlock;
+
+	if (led->flash_current_invalidated) {
+		bright = qcom_flash_current_to_reg(fled_cdev->brightness.max);
+		rc = qcom_flash_max_brightness_set(led, bright);
+		if (rc)
+			goto unlock;
+	}
+
+	led->flash_current_invalidated = false;
+
+unlock:
+	mutex_unlock(&leds_dev->lock);
+	return rc;
+}
+
+static int qcom_flash_flcdev_strobe_set(struct led_classdev_flash *fled_cdev,
+					bool state)
+{
+	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	unsigned int bright;
+	unsigned int i;
+	int rc;
+
+	/* Can't operate on flash if torch is on */
+	if (leds_dev->torch_enabled)
+		return -EBUSY;
+
+	mutex_lock(&leds_dev->lock);
+	if (!state) {
+		rc = qcom_flash_fled_off(led);
+	} else {
+		/*
+		 * Turn off flash LEDs from previous strobe
+		 */
+		rc = qcom_flash_check_timedout(leds_dev);
+		if (rc > 0) {
+			for (i = 0; i < leds_dev->num_leds; i++) {
+				rc = qcom_flash_fled_off(&leds_dev->leds[i]);
+				if (rc)
+					goto unlock;
+			}
+		} else if (rc < 0) {
+			goto unlock;
+		}
+
+		if (led->flash_current_invalidated) {
+			bright = qcom_flash_current_to_reg(fled_cdev->brightness.val);
+			rc = qcom_flash_brightness_set(led, bright);
+			if (rc)
+				goto unlock;
+
+			bright = qcom_flash_current_to_reg(fled_cdev->brightness.max);
+			rc = qcom_flash_max_brightness_set(led, bright);
+			if (rc)
+				goto unlock;
+
+			led->flash_current_invalidated = false;
+		}
+
+		rc = qcom_flash_fled_on(led);
+	}
+
+unlock:
+	mutex_unlock(&leds_dev->lock);
+	return rc;
+}
+
+static int qcom_flash_flcdev_strobe_get(struct led_classdev_flash *fled_cdev,
+					bool *state)
+{
+	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	int status;
+
+	mutex_lock(&leds_dev->lock);
+	status = qcom_flash_status_get(led);
+	mutex_unlock(&leds_dev->lock);
+	if (status < 0)
+		return status;
+
+	*state = status && !leds_dev->torch_enabled;
+	return 0;
+}
+
+static int qcom_flash_flcdev_timeout_set(struct led_classdev_flash *fled_cdev,
+					 u32 timeout)
+{
+	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	unsigned int time, i;
+	int rc;
+
+	clamp_align(&timeout, QCOM_FLASH_DURATION_MIN, fled_cdev->timeout.max,
+		    QCOM_FLASH_DURATION_STEP);
+
+	/* Since the timeout register is shared between LEDs, update for all */
+	for (i = 0; i < leds_dev->num_leds; i++)
+		leds_dev->leds[i].fled_cdev.timeout.val = timeout;
+
+	time = qcom_flash_duration_to_reg(fled_cdev->timeout.val);
+
+	mutex_lock(&leds_dev->lock);
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_SAFETY_TIMER,
+				     QCOM_FLASH_SAFETY_TIMER_MASK, time);
+	if (rc)
+		dev_err(leds_dev->dev, "Safety timer reg write failed(%d)\n",
+			rc);
+	mutex_unlock(&leds_dev->lock);
+
+	return rc;
+}
+
+static int qcom_flash_flcdev_fault_get(struct led_classdev_flash *fled_cdev,
+				       u32 *fault)
+{
+	/*
+	 * TODO Add fault detection when we find out how to. No clue from
+	 * inspecting the SPMI registers
+	 */
+	*fault = 0;
+	return 0;
+}
+
+static const struct led_flash_ops flash_ops = {
+	.flash_brightness_set	= qcom_flash_flcdev_brightness_set,
+	.strobe_set		= qcom_flash_flcdev_strobe_set,
+	.strobe_get		= qcom_flash_flcdev_strobe_get,
+	.timeout_set		= qcom_flash_flcdev_timeout_set,
+	.fault_get		= qcom_flash_flcdev_fault_get,
+};
+
+static int qcom_flash_setup_flcdev(struct qcom_flash_config *cfg,
+				   struct qcom_flash_led *led,
+				   struct device_node *node)
+{
+	int rc;
+	struct device *dev = led_to_leds_dev(led)->dev;
+	struct led_classdev_flash *fled_cdev = &led->fled_cdev;
+	struct led_classdev *led_cdev = &fled_cdev->led_cdev;
+	struct led_init_data init_data = {};
+	struct led_flash_setting *setting;
+
+	init_data.fwnode = of_fwnode_handle(node);
+
+	led_cdev->brightness_set_blocking = qcom_flash_ledcdev_brightness_set;
+
+	led_cdev->max_brightness = cfg->led_max_brightness[led->id];
+	led_cdev->max_brightness /= QCOM_FLASH_CURRENT_STEP;
+
+	setting = &fled_cdev->brightness;
+	setting->max = cfg->flash_max_brightness[led->id];
+	setting->min = QCOM_FLASH_CURRENT_MIN;
+	setting->step = QCOM_FLASH_CURRENT_STEP;
+	setting->val = setting->min;
+
+	setting = &fled_cdev->timeout;
+	setting->max = cfg->flash_max_timeout[led->id];
+	setting->min = QCOM_FLASH_DURATION_MIN;
+	setting->step = QCOM_FLASH_DURATION_STEP;
+	setting->val = QCOM_FLASH_DURATION_DEFAULT;
+
+	fled_cdev->ops = &flash_ops;
+	led_cdev->flags |= LED_DEV_CAP_FLASH;
+
+	rc = devm_led_classdev_flash_register_ext(dev, fled_cdev, &init_data);
+	if (rc)
+		dev_err(dev, "unable to register led %d,rc=%d\n", led->id, rc);
+
+	return rc;
+}
+
+static int qcom_flash_setup_fled(struct qcom_flash_config *cfg,
+				 struct qcom_flash_led *led,
+				 enum qcom_flash_ids id)
+{
+	led->id = cfg->id[id];
+	led->default_on = cfg->default_on[id];
+	led->flash_current_invalidated = true;
+
+	if (led->id == QCOM_FLASH_ID_LED0) {
+		led->flash_enable_cmd = QCOM_FLASH_ENABLE_LED0;
+		led->flash_strobe_cmd = QCOM_FLASH_STROBE_LED0;
+		led->current_addr = QCOM_FLASH_ADDR_CURR_LED0;
+		led->mask_led_on = QCOM_FLASH_MASK_ON_LED0;
+	} else {
+		led->flash_enable_cmd = QCOM_FLASH_ENABLE_LED1;
+		led->flash_strobe_cmd = QCOM_FLASH_STROBE_LED1;
+		led->current_addr = QCOM_FLASH_ADDR_CURR_LED1;
+		led->mask_led_on = QCOM_FLASH_MASK_ON_LED1;
+	}
+
+	return 0;
+}
+
+static int qcom_flash_setup_regs(struct qcom_flash_device *leds_dev)
+{
+	int rc;
+
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
+				     QCOM_FLASH_STROBE_MASK,
+				     QCOM_FLASH_DISABLE_ALL);
+	if (rc) {
+		dev_err(leds_dev->dev, "LED flash write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* Disable flash LED module */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
+				     QCOM_FLASH_ENABLE_MASK,
+				     QCOM_FLASH_DISABLE_ALL);
+	if (rc) {
+		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* Set Vreg force */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_VREG_OK_FORCE,
+				     QCOM_FLASH_VREG_MASK,
+				     QCOM_FLASH_HW_VREG_OK);
+	if (rc) {
+		dev_err(leds_dev->dev, "Vreg OK reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* Set self fault check */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_FAULT_DETECT,
+				     QCOM_FLASH_FAULT_DETECT_MASK,
+				     QCOM_FLASH_SELFCHECK_DISABLE);
+	if (rc) {
+		dev_err(leds_dev->dev, "Fault detect reg write failed(%d)\n",
+			rc);
+		return rc;
+	}
+
+	/* Set mask enable */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_MASK_ENABLE,
+				     QCOM_FLASH_MASK_REG_MASK,
+				     QCOM_FLASH_MASK_1);
+	if (rc) {
+		dev_err(leds_dev->dev, "Mask enable reg write failed(%d)\n",
+			rc);
+		return rc;
+	}
+
+	/* Set ramp rate */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_RAMP_RATE,
+				     QCOM_FLASH_RAMP_RATE_MASK, 0xBF);
+	if (rc) {
+		dev_err(leds_dev->dev, "Ramp rate reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* Enable VPH_PWR_DROOP and set threshold to 2.9V */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_VPH_PWR_DROOP,
+				     QCOM_FLASH_VPH_PWR_DROOP_MASK, 0xC2);
+	if (rc) {
+		dev_err(leds_dev->dev, "VPH_PWR_DROOP reg write failed(%d)\n",
+			rc);
+		return rc;
+	}
+
+	/* Set headroom */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_HEADROOM,
+				     QCOM_FLASH_HEADROOM_MASK,
+				     QCOM_FLASH_HEADROOM_500MV);
+	if (rc) {
+		dev_err(leds_dev->dev, "Headroom reg write failed(%d)\n", rc);
+		return rc;
+	}
+
+	/* Set startup delay */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_STARTUP_DELAY,
+				     QCOM_FLASH_STARTUP_DLY_MASK,
+				     QCOM_FLASH_STARTUP_DLY_10US);
+	if (rc) {
+		dev_err(leds_dev->dev, "Startup delay reg write failed(%d)\n",
+			rc);
+		return rc;
+	}
+
+	/*
+	 * TODO The downstream driver also supported watchdog mode. Not sure
+	 * about the difference, so only support safety timer for now
+	 */
+	/* Set timer control */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_TMR_CTRL,
+				     QCOM_FLASH_TMR_MASK,
+				     QCOM_FLASH_TMR_SAFETY);
+	if (rc) {
+		dev_err(leds_dev->dev, "LED timer ctrl reg write failed(%d)\n",
+			rc);
+		return rc;
+	}
+
+	/* Set clamp current */
+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_CLAMP_CURR,
+				     QCOM_FLASH_CURRENT_MASK,
+				     qcom_flash_current_to_reg(QCOM_FLASH_DEFAULT_CLAMP));
+	if (rc)
+		dev_err(leds_dev->dev, "Clamp current reg write failed(%d)\n",
+			rc);
+
+	return rc;
+}
+
+static int qcom_flash_setup_led(struct qcom_flash_config *cfg,
+				struct qcom_flash_led *led,
+				enum qcom_flash_ids id,
+				struct device_node *node)
+{
+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
+	struct led_classdev *led_cdev = &led->fled_cdev.led_cdev;
+	int rc;
+
+	rc = qcom_flash_setup_fled(cfg, led, id);
+	if (rc)
+		return rc;
+
+	rc = qcom_flash_setup_flcdev(cfg, led, node);
+	if (rc)
+		return rc;
+
+	/* configure default state */
+	if (!led->default_on) {
+		led_cdev->brightness = LED_OFF;
+	} else {
+		led_cdev->brightness = led_cdev->max_brightness;
+		mutex_lock(&leds_dev->lock);
+		rc = qcom_flash_torch_on(led);
+		mutex_unlock(&leds_dev->lock);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
+
+static int qcom_flash_setup_leds_device(struct qcom_flash_device *leds_dev,
+					struct qcom_flash_config *cfg,
+					struct device *dev)
+{
+	int rc;
+
+	leds_dev->dev = dev;
+
+	leds_dev->base = cfg->base;
+	leds_dev->num_leds = cfg->num_leds;
+
+	leds_dev->regmap = dev_get_regmap(dev->parent, NULL);
+	if (!leds_dev->regmap) {
+		dev_err(dev, "Failure getting regmap\n");
+		return -ENODEV;
+	}
+
+	rc = qcom_flash_setup_regs(leds_dev);
+	if (rc)
+		return rc;
+
+	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE,
+				 &leds_dev->peripheral_subtype);
+	if (rc) {
+		dev_err(dev, "Unable to read from addr=%x, rc(%d)\n",
+			QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE, rc);
+		return rc;
+	}
+
+	leds_dev->flash_supply = cfg->flash_supply;
+
+	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
+		leds_dev->torch_supply = cfg->torch_supply;
+		leds_dev->torch_enable_cmd = QCOM_FLASH_ENABLE_MODULE;
+	} else {
+		leds_dev->torch_enable_cmd = QCOM_FLASH_ENABLE_ALL;
+	}
+
+	mutex_init(&leds_dev->lock);
+
+	return 0;
+}
+
+static int qcom_flash_parse_dt(struct device *dev,
+			       struct qcom_flash_config *cfg,
+			       struct device_node *sub_nodes[])
+{
+	struct device_node *node = dev->of_node;
+	struct device_node *child_node;
+	const char *temp_string;
+	int rc, parsed_leds = 0;
+	u32 val;
+
+	rc = of_property_read_u32(node, "reg", &val);
+	if (rc < 0) {
+		dev_err(dev, "Failure reading reg, rc = %d\n", rc);
+		return rc;
+	}
+	cfg->base = val;
+
+	cfg->flash_supply = devm_regulator_get(dev, "flash-boost");
+	cfg->torch_supply = devm_regulator_get(dev, "torch-boost");
+
+	for_each_available_child_of_node(node, child_node) {
+		/* LED properties */
+
+		rc = of_property_read_u32(child_node, "reg",
+					  &cfg->id[parsed_leds]);
+		if (rc) {
+			dev_err(dev, "Failure reading led id, rc =  %d\n", rc);
+			of_node_put(child_node);
+			return rc;
+		}
+
+		/* Assume LED IDs are ordered in DT for simplicity */
+		if (cfg->id[parsed_leds] != parsed_leds) {
+			dev_err(dev, "Unordered LED nodes in DT\n");
+			of_node_put(child_node);
+			return -EINVAL;
+		}
+
+		sub_nodes[parsed_leds] = child_node;
+
+		rc = of_property_read_string(child_node, "default-state",
+					     &temp_string);
+		if (!rc) {
+			if (strncmp(temp_string, "on", sizeof("on")) == 0)
+				cfg->default_on[parsed_leds] = true;
+		} else if (rc != -EINVAL) {
+			dev_err(dev,
+				"Failure reading default-state, rc =  %d\n",
+				rc);
+			of_node_put(child_node);
+			return rc;
+		}
+
+		/* FLED properties */
+
+		rc = of_property_read_u32(child_node, "led-max-microamp",
+					  &cfg->led_max_brightness[parsed_leds]);
+		if (rc < 0) {
+			dev_err(dev, "Failure reading max_current, rc =  %d\n",
+				rc);
+			of_node_put(child_node);
+			return rc;
+		}
+
+		rc = of_property_read_u32(child_node, "flash-max-microamp",
+					  &cfg->flash_max_brightness[parsed_leds]);
+		if (rc < 0) {
+			dev_err(dev, "Failure reading max_current, rc =  %d\n",
+				rc);
+			of_node_put(child_node);
+			return rc;
+		}
+
+		rc = of_property_read_u32(child_node, "flash-max-timeout-us",
+					  &cfg->flash_max_timeout[parsed_leds]);
+		if (rc < 0) {
+			dev_err(dev, "Failure reading max_timeout, rc =  %d\n",
+				rc);
+			of_node_put(child_node);
+			return rc;
+		}
+
+		parsed_leds++;
+		if (parsed_leds >= 2) {
+			of_node_put(child_node);
+			break;
+		}
+	}
+	cfg->num_leds = parsed_leds;
+
+	return 0;
+}
+
+static int qcom_flash_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct qcom_flash_device *leds_dev;
+	struct qcom_flash_config cfg = { 0 };
+	struct device_node *sub_nodes[2];
+	unsigned int i;
+	int rc;
+
+	leds_dev = devm_kzalloc(dev, sizeof(*leds_dev), GFP_KERNEL);
+	if (!leds_dev)
+		return -ENOMEM;
+
+	rc = qcom_flash_parse_dt(dev, &cfg, sub_nodes);
+	if (rc)
+		return rc;
+
+	rc = qcom_flash_setup_leds_device(leds_dev, &cfg, dev);
+	if (rc)
+		return rc;
+
+	for (i = 0; i < leds_dev->num_leds; i++) {
+		rc = qcom_flash_setup_led(&cfg, &leds_dev->leds[i], i,
+					  sub_nodes[i]);
+		if (rc)
+			return rc;
+	}
+
+	platform_set_drvdata(pdev, leds_dev);
+
+	return 0;
+}
+
+static int qcom_flash_remove(struct platform_device *pdev)
+{
+	struct qcom_flash_device *leds_dev = platform_get_drvdata(pdev);
+
+	mutex_destroy(&leds_dev->lock);
+
+	return 0;
+}
+
+static const struct of_device_id qcom_flash_spmi_of_match[] = {
+	{ .compatible = "qcom,spmi-flash-leds" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, qcom_flash_spmi_of_match);
+
+static struct platform_driver qcom_flash_driver = {
+	.driver		= {
+		.name	= "qcom,spmi-flash-leds",
+		.of_match_table = qcom_flash_spmi_of_match,
+	},
+	.probe		= qcom_flash_probe,
+	.remove		= qcom_flash_remove,
+};
+module_platform_driver(qcom_flash_driver);
+
+MODULE_DESCRIPTION("Qualcomm SPMI Flash LED driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("N?colas F. R. A. Prado <n at nfraprado.net>");
-- 
2.32.0



From nfraprado at collabora.com  Tue Aug  3 09:26:39 2021
From: nfraprado at collabora.com (=?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=)
Date: Tue,  3 Aug 2021 13:26:39 -0300
Subject: [PATCH v3 3/5] ARM: qcom_defconfig: Enable QCOM SPMI Flash LEDs
In-Reply-To: <20210803162641.1525980-1-nfraprado@collabora.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
Message-ID: <20210803162641.1525980-4-nfraprado@collabora.com>

Enable module for the Qualcomm SPMI Flash LEDs present on the PM8941
PMIC. These LEDs are used on phones based on the MSM8974 SoC like the
Nexus 5.

Also enable LED flash class since these LEDs make use of it.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---

Changes in v3:
- Made CONFIG_LEDS_CLASS_FLASH =m

Changes in v2:
- Enabled CONFIG_LEDS_CLASS_FLASH since the driver now depends on it.

 arch/arm/configs/qcom_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 9c286861a9c0..1be619a12637 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -206,6 +206,7 @@ CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_MSM=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_FLASH=m
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_PM8058=y
 CONFIG_LEDS_TRIGGERS=y
@@ -308,3 +309,4 @@ CONFIG_QCOM_WDT=y
 CONFIG_ARM_PSCI=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPUFREQ_DT=y
+CONFIG_LEDS_QCOM_SPMI_FLASH=m
-- 
2.32.0



From nfraprado at collabora.com  Tue Aug  3 09:26:40 2021
From: nfraprado at collabora.com (=?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=)
Date: Tue,  3 Aug 2021 13:26:40 -0300
Subject: [PATCH v3 4/5] ARM: dts: qcom: pm8941: Add nodes for QCOM SPMI Flash
 LEDs
In-Reply-To: <20210803162641.1525980-1-nfraprado@collabora.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
Message-ID: <20210803162641.1525980-5-nfraprado@collabora.com>

Add nodes for Qualcomm's SPMI Flash LEDs present in PM8941. There are
two white LEDs which can be used as flash or torch.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---

Changes in v3:
- Disabled node
- Removed LED configuration (moved to hammerhead dts in patch 5)

Changes in v2:
- Moved from hammerhead dts to pm8941 dtsi, as it was this way downstream
- Now using values from leds-qcom-spmi-flash.h

 arch/arm/boot/dts/qcom-pm8941.dtsi | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi
index c1f2012d1c8b..e9e4369a488b 100644
--- a/arch/arm/boot/dts/qcom-pm8941.dtsi
+++ b/arch/arm/boot/dts/qcom-pm8941.dtsi
@@ -2,6 +2,7 @@
 #include <dt-bindings/iio/qcom,spmi-vadc.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/leds/common.h>
 
 &spmi_bus {
 
@@ -189,5 +190,29 @@ pm8941_5vs2: 5vs2 {
 				regulator-initial-mode = <1>;
 			};
 		};
+
+		spmi-flash-leds at d300 {
+			status = "disabled";
+
+			compatible = "qcom,spmi-flash-leds";
+			reg = <0xd300 0x100>;
+			flash-boost-supply = <&pm8941_5vs1>;
+			torch-boost-supply = <&pm8941_5v>;
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pm8941_flash0: led at 0 {
+				reg = <0>;
+				function = LED_FUNCTION_FLASH;
+				color = <LED_COLOR_ID_WHITE>;
+			};
+
+			pm8941_flash1: led at 1 {
+				reg = <1>;
+				function = LED_FUNCTION_FLASH;
+				color = <LED_COLOR_ID_WHITE>;
+			};
+		};
 	};
 };
-- 
2.32.0



From nfraprado at collabora.com  Tue Aug  3 09:26:41 2021
From: nfraprado at collabora.com (=?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=)
Date: Tue,  3 Aug 2021 13:26:41 -0300
Subject: [PATCH v3 5/5] ARM: dts: qcom: msm8974-hammerhead: Enable and
 configure flash LED node
In-Reply-To: <20210803162641.1525980-1-nfraprado@collabora.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
Message-ID: <20210803162641.1525980-6-nfraprado@collabora.com>

Enable the flash LED node from PM8941 and configure the LEDs. This
enables the Nexus 5 to make use of the LEDs as flash or lantern.

Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---

Added in v3

 .../qcom-msm8974-lge-nexus5-hammerhead.dts    | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
index 30ee913faae6..78ac56be81b3 100644
--- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
+++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
@@ -759,4 +759,24 @@ otg {
 			};
 		};
 	};
+
+	pm8941 at 1 {
+		spmi-flash-leds at d300 {
+			status = "okay";
+
+			led at 0 {
+				led-max-microamp = <200000>;
+				flash-max-microamp = <1000000>;
+				flash-max-timeout-us = <1280000>;
+				default-state = "off";
+			};
+
+			led at 1 {
+				led-max-microamp = <200000>;
+				flash-max-microamp = <1000000>;
+				flash-max-timeout-us = <1280000>;
+				default-state = "off";
+			};
+		};
+	};
 };
-- 
2.32.0



From olteanv at gmail.com  Tue Aug  3 09:48:53 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 3 Aug 2021 19:48:53 +0300
Subject: [PATCH net-next v2 2/4] net: dsa: mt7530: use independent VLAN
 learning on VLAN-unaware bridges
In-Reply-To: <20210803160405.3025624-3-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
 <20210803160405.3025624-3-dqfext@gmail.com>
Message-ID: <20210803164853.gxw4zfxmmgs2kgry@skbuf>

On Wed, Aug 04, 2021 at 12:04:02AM +0800, DENG Qingfang wrote:
> Consider the following bridge configuration, where bond0 is not
> offloaded:
> 
>          +-- br0 --+
>         / /   |     \
>        / /    |      \
>       /  |    |     bond0
>      /   |    |     /   \
>    swp0 swp1 swp2 swp3 swp4
>      .        .       .
>      .        .       .
>      A        B       C
> 
> Ideally, when the switch receives a packet from swp3 or swp4, it should
> forward the packet to the CPU, according to the port matrix and unknown
> unicast flood settings.
> 
> But packet loss will happen if the destination address is at one of the
> offloaded ports (swp0~2). For example, when client C sends a packet to
> A, the FDB lookup will indicate that it should be forwarded to swp0, but
> the port matrix of swp3 and swp4 is configured to only allow the CPU to
> be its destination, so it is dropped.
> 
> However, this issue does not happen if the bridge is VLAN-aware. That is
> because VLAN-aware bridges use independent VLAN learning, i.e. use VID
> for FDB lookup, on offloaded ports. As swp3 and swp4 are not offloaded,
> shared VLAN learning with default filter ID of 0 is used instead. So the
> lookup for A with filter ID 0 never hits and the packet can be forwarded
> to the CPU.
> 
> In the current code, only two combinations were used to toggle user
> ports' VLAN awareness: one is PCR.PORT_VLAN set to port matrix mode with
> PVC.VLAN_ATTR set to transparent port, the other is PCR.PORT_VLAN set to
> security mode with PVC.VLAN_ATTR set to user port.
> 
> It turns out that only PVC.VLAN_ATTR contributes to VLAN awareness, and
> port matrix mode just skips the VLAN table lookup. The reference manual
> is somehow misleading when describing PORT_VLAN modes. It states that
> PORT_MEM (VLAN port member) is used for destination if the VLAN table
> lookup hits, but actually **PORT_MEM & PORT_MATRIX** (bitwise AND of
> VLAN port member and port matrix) is used instead, which means we can
> have two or more separate VLAN-aware bridges with the same PVID and
> traffic won't leak between them.
> 
> Therefore, to solve this, enable independent VLAN learning with PVID 0
> on VLAN-unaware bridges, by setting their PCR.PORT_VLAN to fallback
> mode, while leaving standalone ports in port matrix mode. The CPU port
> is always set to fallback mode to serve those bridges.
> 
> During testing, it is found that FDB lookup with filter ID of 0 will
> also hit entries with VID 0 even with independent VLAN learning. To
> avoid that, install all VLANs with filter ID of 1.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
> v1 -> v2: use FID enum instead of hardcoding.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

> @@ -1629,11 +1651,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
>  	/* PVID is being restored to the default whenever the PVID port
>  	 * is being removed from the VLAN.
>  	 */
> -	if (pvid == vlan->vid)
> -		pvid = G0_PORT_VID_DEF;
> +	if (priv->ports[port].pvid == vlan->vid) {
> +		priv->ports[port].pvid = G0_PORT_VID_DEF;
> +		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
> +			   G0_PORT_VID_DEF);
> +	}

After this patch set gets merged, can you also please take a look at the
following:

Documentation/networking/switchdev.rst says:

When the bridge has VLAN filtering enabled and a PVID is not configured on the
ingress port, untagged and 802.1p tagged packets must be dropped. When the bridge
has VLAN filtering enabled and a PVID exists on the ingress port, untagged and
priority-tagged packets must be accepted and forwarded according to the
bridge's port membership of the PVID VLAN. When the bridge has VLAN filtering
disabled, the presence/lack of a PVID should not influence the packet
forwarding decision.

I'm not sure if this happens or not with mt7530, since the driver
attempts to change the pvid back to 0. You are not changing this
behavior in this series, so no reason to deal with it as part of it.

>  
> -	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, pvid);
> -	priv->ports[port].pvid = pvid;
>  
>  	mutex_unlock(&priv->reg_mutex);
>  


From olteanv at gmail.com  Tue Aug  3 09:50:04 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 3 Aug 2021 19:50:04 +0300
Subject: [PATCH net-next v2 3/4] net: dsa: mt7530: set STP state on
 filter ID 1
In-Reply-To: <20210803160405.3025624-4-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
 <20210803160405.3025624-4-dqfext@gmail.com>
Message-ID: <20210803165004.za4oz7xhf6iynee7@skbuf>

On Wed, Aug 04, 2021 at 12:04:03AM +0800, DENG Qingfang wrote:
> As filter ID 1 is the only one used for bridges, set STP state on it.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From olteanv at gmail.com  Tue Aug  3 09:51:38 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 3 Aug 2021 19:51:38 +0300
Subject: [PATCH net-next v2 4/4] net: dsa: mt7530: always install FDB
 entries with IVL and FID 1
In-Reply-To: <20210803160405.3025624-5-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
 <20210803160405.3025624-5-dqfext@gmail.com>
Message-ID: <20210803165138.3obbvtjj2xn6j2n5@skbuf>

On Wed, Aug 04, 2021 at 12:04:04AM +0800, DENG Qingfang wrote:
> This reverts commit 7e777021780e ("mt7530 mt7530_fdb_write only set ivl
> bit vid larger than 1").
> 
> Before this series, the default value of all ports' PVID is 1, which is
> copied into the FDB entry, even if the ports are VLAN unaware. So
> `bridge fdb show` will show entries like `dev swp0 vlan 1 self` even on
> a VLAN-unaware bridge.
> 
> The blamed commit does not solve that issue completely, instead it may
> cause a new issue that FDB is inaccessible in a VLAN-aware bridge with
> PVID 1.
> 
> This series sets PVID to 0 on VLAN-unaware ports, so `bridge fdb show`
> will no longer print `vlan 1` on VLAN-unaware bridges, and that special
> case in fdb_write is not required anymore.
> 
> Set FDB entries' filter ID to 1 to match the VLAN table.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---

The way FDB entries are installed now makes a lot more intuitive sense.


From cki-project at redhat.com  Tue Aug  3 09:52:11 2021
From: cki-project at redhat.com (CKI Project)
Date: Tue, 03 Aug 2021 16:52:11 -0000
Subject: =?utf-8?b?4p2M?= FAIL: Test report for kernel 5.14.0-rc4 (arm-next,
 bee0cf77)
Message-ID: <cki.9091DA6927.M31X8JG0FP@redhat.com>


Hello,

We ran automated tests on a recent commit from this kernel tree:

       Kernel repo: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
            Commit: bee0cf777c04 - Merge branch 'for-next/fixes' into for-kernelci

The results of these automated tests are provided below.

    Overall result: FAILED (see details below)
             Merge: OK
           Compile: OK
             Tests: FAILED

All kernel binaries, config files, and logs are available for download here:

  https://arr-cki-prod-datawarehouse-public.s3.amazonaws.com/index.html?prefix=datawarehouse-public/2021/08/03/347072490

One or more kernel tests failed:

    aarch64:
     ? LTP
     ? ALSA PCM loopback test
     ? stress: stress-ng

We hope that these logs can help you find the problem quickly. For the full
detail on our testing procedures, please scroll to the bottom of this message.

Please reply to this email if you have any questions about the tests that we
ran or if you have any suggestions on how to make future tests more effective.

        ,-.   ,-.
       ( C ) ( K )  Continuous
        `-',-.`-'   Kernel
          ( I )     Integration
           `-'
______________________________________________________________________________

Compile testing
---------------

We compiled the kernel for 1 architecture:

    aarch64:
      make options: make -j24 INSTALL_MOD_STRIP=1 targz-pkg



Hardware testing
----------------
We booted each kernel and ran the following tests:

  aarch64:
    Host 1:
       ? Boot test
       ? Reboot test
       ? ACPI table test
       ? ACPI enabled test
       ? LTP
       ? CIFS Connectathon
       ? POSIX pjd-fstest suites
       ? Loopdev Sanity
       ? jvm - jcstress tests
       ? Memory: fork_mem
       ? Memory function: memfd_create
       ? AMTU (Abstract Machine Test Utility)
       ? Networking bridge: sanity
       ? Ethernet drivers sanity
       ? Networking socket: fuzz
       ? Networking: igmp conformance test
       ? Networking route: pmtu
       ? Networking route_func - local
       ? Networking route_func - forward
       ? Networking TCP: keepalive test
       ? Networking UDP: socket
       ? Networking cki netfilter test
       ? Networking tunnel: geneve basic test
       ? Networking tunnel: gre basic
       ? L2TP basic test
       ? Networking tunnel: vxlan basic
       ? Networking ipsec: basic netns - transport
       ? Networking ipsec: basic netns - tunnel
       ? Libkcapi AF_ALG test
       ? pciutils: update pci ids test
       ? ALSA PCM loopback test
       ? ALSA Control (mixer) Userspace Element test
       ? storage: SCSI VPD
       ? trace: ftrace/tracer
       ? ? xarray-idr-radixtree-test
       ? ? i2c: i2cdetect sanity
       ? ? NFS Connectathon
       ? ? Firmware test suite
       ? ? Memory function: kaslr
       ? ? audit: audit testsuite test
       ? ? lvm cache test
       ? ? lvm snapper test

    Host 2:
       ? Boot test
       ? Reboot test
       ? xfstests - ext4
       ? xfstests - xfs
       ? selinux-policy: serge-testsuite
       ? storage: software RAID testing
       ? Storage: swraid mdadm raid_module test
       ? ? Podman system integration test - as root
       ? ? Podman system integration test - as user
       ? ? xfstests - btrfs
       ? ? IPMI driver test
       ? ? IPMItool loop stress test
       ? ? Storage blktests
       ? ? Storage block - filesystem fio test
       ? ? Storage block - queue scheduler test
       ? ? Storage nvme - tcp
       ? ? stress: stress-ng

  Test sources: https://gitlab.com/cki-project/kernel-tests
    ? Pull requests are welcome for new tests or improvements to existing tests!

Aborted tests
-------------
Tests that didn't complete running successfully are marked with ???.
If this was caused by an infrastructure issue, we try to mark that
explicitly in the report.

Waived tests
------------
If the test run included waived tests, they are marked with ?. Such tests are
executed but their results are not taken into account. Tests are waived when
their results are not reliable enough, e.g. when they're just introduced or are
being fixed.

Testing timeout
---------------
We aim to provide a report within reasonable timeframe. Tests that haven't
finished running yet are marked with ?.



From arnd at kernel.org  Tue Aug  3 10:11:49 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 3 Aug 2021 19:11:49 +0200
Subject: [PATCH] ARM: ep93xx: remove MaverickCrunch support
In-Reply-To: <817752520.64672.1628005929651.JavaMail.zimbra@savoirfairelinux.com>
References: <20210802141245.1146772-1-arnd@kernel.org>
 <CAL4-wQqCL1S-GYu7VKJeTT37wh=rR=SMUuwgKiXnnn_Y=uydOA@mail.gmail.com>
 <CAL4-wQpKLtSj0xfNUXXLhbtN1wC051jpRneAuLYOi1riZfiinw@mail.gmail.com>
 <CAK8P3a2z_xxpz9hAYoBx5=bS81V=TkjEU6WHNhPi1UhQ3UScfw@mail.gmail.com>
 <817752520.64672.1628005929651.JavaMail.zimbra@savoirfairelinux.com>
Message-ID: <CAK8P3a042r2V10WY=M3mvhZS2Q9_iBHLDgSNzJpJEGgNJOD7zQ@mail.gmail.com>

On Tue, Aug 3, 2021 at 5:52 PM Jerome Oufella
<jerome.oufella at savoirfairelinux.com> wrote:
>
> You are correct on assuming usage of softfloat toolchains and not
> using the MaverickCrunch unit. AFAIK, I am not aware of active users
> of this FPU on recent setups.

Ok, thank you for the confirmation, I'll queue it up in the soc tree then.

Of course, as there is nothing wrong with the feature other than it
probably having no users and breaking the build when using the
clang integrated assembler, I don't mind reverting it later if we end
up finding a user that does rely on ancient MaverickCrunch binaries
to run on future kernels.

       Arnd


From dqfext at gmail.com  Tue Aug  3 10:13:21 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed,  4 Aug 2021 01:13:21 +0800
Subject: [PATCH net-next v2 2/4] net: dsa: mt7530: use independent VLAN
 learning on VLAN-unaware bridges
In-Reply-To: <20210803164853.gxw4zfxmmgs2kgry@skbuf>
References: <20210803160405.3025624-1-dqfext@gmail.com>
 <20210803160405.3025624-3-dqfext@gmail.com>
 <20210803164853.gxw4zfxmmgs2kgry@skbuf>
Message-ID: <20210803171321.3026041-1-dqfext@gmail.com>

On Tue, Aug 03, 2021 at 07:48:53PM +0300, Vladimir Oltean wrote:
> After this patch set gets merged, can you also please take a look at the
> following:
> 
> Documentation/networking/switchdev.rst says:
> 
> When the bridge has VLAN filtering enabled and a PVID is not configured on the
> ingress port, untagged and 802.1p tagged packets must be dropped. When the bridge
> has VLAN filtering enabled and a PVID exists on the ingress port, untagged and
> priority-tagged packets must be accepted and forwarded according to the
> bridge's port membership of the PVID VLAN. When the bridge has VLAN filtering
> disabled, the presence/lack of a PVID should not influence the packet
> forwarding decision.
> 
> I'm not sure if this happens or not with mt7530, since the driver
> attempts to change the pvid back to 0. You are not changing this
> behavior in this series, so no reason to deal with it as part of it.
> 

There is PVC.ACC_FRM which controls the acceptable frame type.
Currently the driver does not use it, so untagged and priority-tagged frames
can get into a VLAN-aware port without a PVID.


From lorenzo.pieralisi at arm.com  Tue Aug  3 10:14:51 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue, 3 Aug 2021 18:14:51 +0100
Subject: [PATCH v6 8/8] PCI: hv: Turn on the host bridge probing on ARM64
In-Reply-To: <20210726180657.142727-9-boqun.feng@gmail.com>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-9-boqun.feng@gmail.com>
Message-ID: <20210803171451.GA15466@lpieralisi>

On Tue, Jul 27, 2021 at 02:06:57AM +0800, Boqun Feng wrote:
> Now we have everything we need, just provide a proper sysdata type for
> the bus to use on ARM64 and everything else works.
> 
> Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
> ---
>  drivers/pci/controller/pci-hyperv.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> index e6276aaa4659..62dbe98d1fe1 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -40,6 +40,7 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
> +#include <linux/pci-ecam.h>
>  #include <linux/delay.h>
>  #include <linux/semaphore.h>
>  #include <linux/irqdomain.h>
> @@ -448,7 +449,11 @@ enum hv_pcibus_state {
>  };
>  
>  struct hv_pcibus_device {
> +#ifdef CONFIG_X86
>  	struct pci_sysdata sysdata;
> +#elif defined(CONFIG_ARM64)
> +	struct pci_config_window sysdata;

This is ugly. HV does not need pci_config_window at all right
(other than arm64 pcibios_root_bridge_prepare()) ?

The issue is that in HV you have to have *some* sysdata != NULL, it is
just some data to retrieve the hv_pcibus_device.

Mmaybe we can rework ARM64 ACPI code to store the acpi_device in struct
pci_host_bridge->private instead of retrieving it from pci_config_window
so that we decouple HV from the ARM64 back-end.

HV would just set struct pci_host_bridge->private == NULL.

I need to think about this a bit, I don't think it should block
this series though but it would be nicer.

Lorenzo

> +#endif
>  	struct pci_host_bridge *bridge;
>  	struct fwnode_handle *fwnode;
>  	/* Protocol version negotiated with the host */
> @@ -3075,7 +3080,9 @@ static int hv_pci_probe(struct hv_device *hdev,
>  			 dom_req, dom);
>  
>  	hbus->bridge->domain_nr = dom;
> +#ifdef CONFIG_X86
>  	hbus->sysdata.domain = dom;
> +#endif
>  
>  	hbus->hdev = hdev;
>  	INIT_LIST_HEAD(&hbus->children);
> -- 
> 2.32.0
> 


From frank-w at public-files.de  Tue Aug  3 10:15:48 2021
From: frank-w at public-files.de (Frank Wunderlich)
Date: Tue, 3 Aug 2021 19:15:48 +0200
Subject: Aw: [PATCH 0/2] Add MUSB for MT7623
In-Reply-To: <20210803151320.71531-1-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
Message-ID: <trinity-0f9449b8-5114-46e5-9a4f-00b62155a938-1628010948338@3c-app-gmx-bs54>

Hi,

> Gesendet: Dienstag, 03. August 2021 um 17:13 Uhr
> Von: "Sungbo Eo" <mans0n at gorani.run>
> An: linux-mediatek at lists.infradead.org
> Cc: "Chunfeng Yun" <chunfeng.yun at mediatek.com>, "Greg Kroah-Hartman" <gregkh at linuxfoundation.org>, "Rob Herring" <robh+dt at kernel.org>, "Matthias Brugger" <matthias.bgg at gmail.com>, "Min Guo" <min.guo at mediatek.com>, "Frank Wunderlich" <frank-w at public-files.de>, devicetree at vger.kernel.org, linux-usb at vger.kernel.org, linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org, "Sungbo Eo" <mans0n at gorani.run>
> Betreff: [PATCH 0/2] Add MUSB for MT7623
>
> These patches add support for the MUSB controller on Mediatek MT7623.
> Tested on Mercury RUSH-318AC Wi-Fi router.
>
> I got to know this from a BPI-R2 forum post [1], and managed to make it work on OpenWrt snapshot.
> I'd like to know if this also works on BPI-R2, I can happily share the details if needed.
> And I've just copy & pasted nodes from mt2701, please let me know if I missed some big differences between SoCs...
>
> [1] http://forum.banana-pi.org/t/bpi-r2-otg-port/10551

thanks for working on it. do both otg-roles (host/client) work on your device?

unfortunately at least host-mode does not work (do not know how to test client mode). i guess because iddig and vusb nodes are missing.

i took your Patchset and enabled the usb-node for bpi-r2.

+&usb3 {
+       status = "okay";
+};

and added these config-symbols:

+CONFIG_USB_CONN_GPIO=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_MEDIATEK=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_CONFIGFS=y
+#CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+#CONFIG_PHY_MTK_TPHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MUSB_DUAL_ROLE=y
+CONFIG_USB_INVENTRA_DMA=y

btw. imho otg-node should be named usb0 as other dts (kernel 4.4) also use usb0, else i think it's confusing.

in my last attempt i had these below usb-node in boards devicetree:

+       usb_vbus: regulator at 0 {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&pio 237 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       connector{
+               compatible = "gpio-usb-b-connector", "usb-b-connector";
+               type = "micro";
+               id-gpios = <&pio 44 GPIO_ACTIVE_HIGH>;
+               vbus-supply = <&usb_vbus>;
+       };

after adding these i see the connection of otg-cable with usb-stick in dmesg:

[   53.656304] usb-conn-gpio 11200000.usb:connector: repeated rot
[   53.696324] usb-conn-gpio 11200000.usb:connector: repeated role: host

but usb-stick is not powered (led of the stick is off) and of course i see no mass-storage device.

and now i'm back on the traceback on power down i've reported Author of musb driver some time ago

[  156.785185] WARNING: CPU: 0 PID: 1 at drivers/power/reset/mt6323-poweroff.c:4
[  156.795156] Unable to power off system

[  156.884496] [<c0cca1ec>] (warn_slowpath_fmt) from [<c090562c>] (mt6323_do_pw)
[  156.893203]  r8:c3296d40 r7:00000024 r6:0ccccb60 r5:c10fe3d8 r4:00000000
[  156.900030] [<c09054b0>] (mt6323_do_pwroff) from [<c010ba68>] (machine_power)
[  156.908558]  r8:fee1dead r7:c1312590 r6:92f61d00 r5:00000000 r4:4321fedc
[  156.915385] [<c010ba34>] (machine_power_off) from [<c01524bc>] (kernel_power)

i guess it's related to the usb_vbus.

regards Frank



From saravanak at google.com  Tue Aug  3 10:51:32 2021
From: saravanak at google.com (Saravana Kannan)
Date: Tue, 3 Aug 2021 10:51:32 -0700
Subject: [PATCH v4] soc: fsl: qe: convert QE interrupt controller to
 platform_device
In-Reply-To: <20210803113538.560277-1-fido_max@inbox.ru>
References: <20210803113538.560277-1-fido_max@inbox.ru>
Message-ID: <CAGETcx8QC+AMXvmk4RB=LGp00QLVVX4uCeeruAjFnGq_irMh4Q@mail.gmail.com>

On Tue, Aug 3, 2021 at 4:33 AM Maxim Kochetkov <fido_max at inbox.ru> wrote:
>
> Since 5.13 QE's ucc nodes can't get interrupts from devicetree:
>
>         ucc at 2000 {
>                 cell-index = <1>;
>                 reg = <0x2000 0x200>;
>                 interrupts = <32>;
>                 interrupt-parent = <&qeic>;
>         };
>
> Now fw_devlink expects driver to create and probe a struct device
> for interrupt controller.
>
> So lets convert this driver to simple platform_device with probe().
> Also use platform_get_ and devm_ family function to get/allocate
> resources and drop unused .compatible = "qeic".

Yes, please!

Acked-by: Saravana Kannan <saravanak at google.com>

-Saravana

>
> [1] - https://lore.kernel.org/lkml/CAGETcx9PiX==mLxB9PO8Myyk6u2vhPVwTMsA5NkD-ywH5xhusw at mail.gmail.com
> Fixes: e590474768f1 ("driver core: Set fw_devlink=on by default")
> Fixes: ea718c699055 ("Revert "Revert "driver core: Set fw_devlink=on by default""")
> Signed-off-by: Maxim Kochetkov <fido_max at inbox.ru>
> Reported-by: kernel test robot <lkp at intel.com>
> Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
> ---
>  drivers/soc/fsl/qe/qe_ic.c | 75 ++++++++++++++++++++++----------------
>  1 file changed, 44 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c
> index 3f711c1a0996..e710d554425d 100644
> --- a/drivers/soc/fsl/qe/qe_ic.c
> +++ b/drivers/soc/fsl/qe/qe_ic.c
> @@ -23,6 +23,7 @@
>  #include <linux/signal.h>
>  #include <linux/device.h>
>  #include <linux/spinlock.h>
> +#include <linux/platform_device.h>
>  #include <asm/irq.h>
>  #include <asm/io.h>
>  #include <soc/fsl/qe/qe.h>
> @@ -404,41 +405,40 @@ static void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
>         chip->irq_eoi(&desc->irq_data);
>  }
>
> -static void __init qe_ic_init(struct device_node *node)
> +static int qe_ic_init(struct platform_device *pdev)
>  {
> +       struct device *dev = &pdev->dev;
>         void (*low_handler)(struct irq_desc *desc);
>         void (*high_handler)(struct irq_desc *desc);
>         struct qe_ic *qe_ic;
> -       struct resource res;
> -       u32 ret;
> +       struct resource *res;
> +       struct device_node *node = pdev->dev.of_node;
>
> -       ret = of_address_to_resource(node, 0, &res);
> -       if (ret)
> -               return;
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (res == NULL) {
> +               dev_err(dev, "no memory resource defined\n");
> +               return -ENODEV;
> +       }
>
> -       qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
> +       qe_ic = devm_kzalloc(dev, sizeof(*qe_ic), GFP_KERNEL);
>         if (qe_ic == NULL)
> -               return;
> +               return -ENOMEM;
>
> -       qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
> -                                              &qe_ic_host_ops, qe_ic);
> -       if (qe_ic->irqhost == NULL) {
> -               kfree(qe_ic);
> -               return;
> +       qe_ic->regs = devm_ioremap(dev, res->start, resource_size(res));
> +       if (qe_ic->regs == NULL) {
> +               dev_err(dev, "failed to ioremap() registers\n");
> +               return -ENODEV;
>         }
>
> -       qe_ic->regs = ioremap(res.start, resource_size(&res));
> -
>         qe_ic->hc_irq = qe_ic_irq_chip;
>
> -       qe_ic->virq_high = irq_of_parse_and_map(node, 0);
> -       qe_ic->virq_low = irq_of_parse_and_map(node, 1);
> +       qe_ic->virq_high = platform_get_irq(pdev, 0);
> +       qe_ic->virq_low = platform_get_irq(pdev, 1);
>
> -       if (!qe_ic->virq_low) {
> -               printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
> -               kfree(qe_ic);
> -               return;
> +       if (qe_ic->virq_low < 0) {
> +               return -ENODEV;
>         }
> +
>         if (qe_ic->virq_high != qe_ic->virq_low) {
>                 low_handler = qe_ic_cascade_low;
>                 high_handler = qe_ic_cascade_high;
> @@ -447,6 +447,13 @@ static void __init qe_ic_init(struct device_node *node)
>                 high_handler = NULL;
>         }
>
> +       qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
> +                                              &qe_ic_host_ops, qe_ic);
> +       if (qe_ic->irqhost == NULL) {
> +               dev_err(dev, "failed to add irq domain\n");
> +               return -ENODEV;
> +       }
> +
>         qe_ic_write(qe_ic->regs, QEIC_CICR, 0);
>
>         irq_set_handler_data(qe_ic->virq_low, qe_ic);
> @@ -456,20 +463,26 @@ static void __init qe_ic_init(struct device_node *node)
>                 irq_set_handler_data(qe_ic->virq_high, qe_ic);
>                 irq_set_chained_handler(qe_ic->virq_high, high_handler);
>         }
> +       return 0;
>  }
> +static const struct of_device_id qe_ic_ids[] = {
> +       { .compatible = "fsl,qe-ic"},
> +       { .type = "qeic"},
> +       {},
> +};
>
> -static int __init qe_ic_of_init(void)
> +static struct platform_driver qe_ic_driver =
>  {
> -       struct device_node *np;
> +       .driver = {
> +               .name           = "qe-ic",
> +               .of_match_table = qe_ic_ids,
> +       },
> +       .probe  = qe_ic_init,
> +};
>
> -       np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
> -       if (!np) {
> -               np = of_find_node_by_type(NULL, "qeic");
> -               if (!np)
> -                       return -ENODEV;
> -       }
> -       qe_ic_init(np);
> -       of_node_put(np);
> +static int __init qe_ic_of_init(void)
> +{
> +       platform_driver_register(&qe_ic_driver);
>         return 0;
>  }
>  subsys_initcall(qe_ic_of_init);
> --
> 2.31.1
>


From dqfext at gmail.com  Tue Aug  3 10:53:54 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed,  4 Aug 2021 01:53:54 +0800
Subject: [PATCH net-next v2 4/4] net: dsa: mt7530: always install FDB
 entries with IVL and FID 1
In-Reply-To: <20210803165138.3obbvtjj2xn6j2n5@skbuf>
References: <20210803160405.3025624-1-dqfext@gmail.com>
 <20210803160405.3025624-5-dqfext@gmail.com>
 <20210803165138.3obbvtjj2xn6j2n5@skbuf>
Message-ID: <20210803175354.3026608-1-dqfext@gmail.com>

On Tue, Aug 03, 2021 at 07:51:38PM +0300, Vladimir Oltean wrote:
> 
> The way FDB entries are installed now makes a lot more intuitive sense.

Did you forget to add the Reviewed-by tag?


From catalin.marinas at arm.com  Tue Aug  3 11:05:26 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 3 Aug 2021 19:05:26 +0100
Subject: [PATCH v3] memblock: make memblock_find_in_range method private
In-Reply-To: <20210803064218.6611-1-rppt@kernel.org>
References: <20210803064218.6611-1-rppt@kernel.org>
Message-ID: <20210803180526.GD5786@arm.com>

On Tue, Aug 03, 2021 at 09:42:18AM +0300, Mike Rapoport wrote:
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 8490ed2917ff..0bffd2d1854f 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>  static void __init reserve_crashkernel(void)
>  {
>  	unsigned long long crash_base, crash_size;
> +	unsigned long long crash_max = arm64_dma_phys_limit;
>  	int ret;
>  
>  	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> @@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
>  
>  	crash_size = PAGE_ALIGN(crash_size);
>  
> -	if (crash_base == 0) {
> -		/* Current arm64 boot protocol requires 2MB alignment */
> -		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
> -				crash_size, SZ_2M);
> -		if (crash_base == 0) {
> -			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> -				crash_size);
> -			return;
> -		}
> -	} else {
> -		/* User specifies base address explicitly. */
> -		if (!memblock_is_region_memory(crash_base, crash_size)) {
> -			pr_warn("cannot reserve crashkernel: region is not memory\n");
> -			return;
> -		}
> +	/* User specifies base address explicitly. */
> +	if (crash_base)
> +		crash_max = crash_base + crash_size;
>  
> -		if (memblock_is_region_reserved(crash_base, crash_size)) {
> -			pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
> -			return;
> -		}
> -
> -		if (!IS_ALIGNED(crash_base, SZ_2M)) {
> -			pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
> -			return;
> -		}
> +	/* Current arm64 boot protocol requires 2MB alignment */
> +	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> +					       crash_base, crash_max);
> +	if (!crash_base) {
> +		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> +			crash_size);
> +		return;
>  	}
> -	memblock_reserve(crash_base, crash_size);

We'll miss a bit on debug information provided to the user in case of a
wrong crash_base/size option on the command line. Not sure we care much,
though the alignment would probably be useful (maybe we document it
somewhere).

What I haven't checked is whether memblock_phys_alloc_range() aims to
get a 2MB aligned end (size) as well. If crash_size is not 2MB aligned,
crash_max wouldn't be either and the above could fail. We only care
about the crash_base to be aligned but the memblock_phys_alloc_range()
doc says that both the start and size would be aligned to this.

-- 
Catalin


From andy.shevchenko at gmail.com  Tue Aug  3 11:20:19 2021
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Tue, 3 Aug 2021 21:20:19 +0300
Subject: [PATCH v2 3/4] spi: mediatek: modify set_cs_timing callback
In-Reply-To: <20210803102428.6476-1-Mason.Zhang@mediatek.com>
References: <20210803102428.6476-1-Mason.Zhang@mediatek.com>
Message-ID: <CAHp75VcPhBB+21wVErWRq+mSDaCkpQBovn+xvMbXyfENnuu40Q@mail.gmail.com>

On Tue, Aug 3, 2021 at 1:42 PM Mason Zhang <Mason.Zhang at mediatek.com> wrote:
>
> This patch modified set_cs_timing callback:
>   1 support spi_device set cs_timing in their driver;
>   2 support set absolute time but no clk count, because;
>     clk src will change in different platform;
>   3 call this function in prepare_message but not in other API.

Perhaps it should be 3 patches?

...

> +static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
> +{
> +       struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
> +       struct spi_delay *cs_setup = &spi->cs_setup;
> +       struct spi_delay *cs_hold = &spi->cs_hold;
> +       struct spi_delay *cs_inactive = &spi->cs_inactive;
> +       u16 setup, hold, inactive;
> +       u32 reg_val;
> +       int delay;
> +
> +       delay = spi_delay_to_ns(cs_setup, NULL);
> +       if (delay < 0)
> +               return delay;
> +       setup = (delay / 1000) * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000);

1000 is NSEC_PER_USEC (here and below)?

> +       delay = spi_delay_to_ns(cs_hold, NULL);
> +       if (delay < 0)
> +               return delay;
> +       hold = (delay / 1000) * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000);
> +
> +       delay = spi_delay_to_ns(cs_inactive, NULL);
> +       if (delay < 0)
> +               return delay;
> +       inactive = (delay / 1000) * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000);

> +       setup    = setup ? setup : 1;
> +       hold     = hold ? hold : 1;
> +       inactive = inactive ? inactive : 1;

All of these can be simplified by using ?: (short ternary) form.

> +       reg_val = readl(mdata->base + SPI_CFG0_REG);
> +       if (mdata->dev_comp->enhance_timing) {
> +               reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
> +               reg_val |= (((hold - 1) & 0xffff)
> +                          << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
> +               reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
> +               reg_val |= (((setup - 1) & 0xffff)
> +                          << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
> +       } else {
> +               reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
> +               reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
> +               reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
> +               reg_val |= (((setup - 1) & 0xff)
> +                           << SPI_CFG0_CS_SETUP_OFFSET);
> +       }
> +       writel(reg_val, mdata->base + SPI_CFG0_REG);
> +
> +       reg_val = readl(mdata->base + SPI_CFG1_REG);
> +       reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
> +       reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
> +       writel(reg_val, mdata->base + SPI_CFG1_REG);
> +
> +       return 0;
> +}

-- 
With Best Regards,
Andy Shevchenko


From olteanv at gmail.com  Tue Aug  3 11:23:33 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 3 Aug 2021 21:23:33 +0300
Subject: [PATCH net-next v2 4/4] net: dsa: mt7530: always install FDB
 entries with IVL and FID 1
In-Reply-To: <20210803175354.3026608-1-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
 <20210803160405.3025624-5-dqfext@gmail.com>
 <20210803165138.3obbvtjj2xn6j2n5@skbuf>
 <20210803175354.3026608-1-dqfext@gmail.com>
Message-ID: <20210803182333.s2oc4yizwrzy746i@skbuf>

On Wed, Aug 04, 2021 at 01:53:54AM +0800, DENG Qingfang wrote:
> On Tue, Aug 03, 2021 at 07:51:38PM +0300, Vladimir Oltean wrote:
> > 
> > The way FDB entries are installed now makes a lot more intuitive sense.
> 
> Did you forget to add the Reviewed-by tag?

Yeah, in fact I did. I was in a rush and by the time I figured that
I didn't do that, I had already left home.

Still, in fact the patch is obviously correct, which is nice. Standalone
ports never learn and the FDB lookup will always miss because it's in
FID 0 (a separate FID compared to the bridge ports) and there is no FDB
entry there. Packets will always be flooded to their only possible
destination, the CPU port. Ports under VLAN-unaware bridges always use
IVL and learn using the pvid, which is zero, and which happily coincides
with the VID which the bridge uses to install VLAN-unaware FDB entries.
Ports under VLAN-aware bridges again use IVL but the VID is taken from
the packet not just from the pvid, so the VID will be >= 1 there. Again
it coincides with the vid that the bridge uses to offload FDB entries.
Nice, I really like it, it is really simple.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From anitha.chrisanthus at intel.com  Tue Aug  3 11:36:10 2021
From: anitha.chrisanthus at intel.com (Chrisanthus, Anitha)
Date: Tue, 3 Aug 2021 18:36:10 +0000
Subject: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
In-Reply-To: <YQlbFjbrnyeWv7QP@ravnborg.org>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <YQlbFjbrnyeWv7QP@ravnborg.org>
Message-ID: <BY5PR11MB41822706053ADEE927E34E628CF09@BY5PR11MB4182.namprd11.prod.outlook.com>

Hi Thomas,
Can you please hold off on applying the kmb patch, I am seeing some issues while testing. Modetest works, but video playback only plays once, and it fails the second time with this patch.

Thanks,
Anitha


> -----Original Message-----
> From: Sam Ravnborg <sam at ravnborg.org>
> Sent: Tuesday, August 3, 2021 8:05 AM
> To: Thomas Zimmermann <tzimmermann at suse.de>
> Cc: daniel at ffwll.ch; airlied at linux.ie; alexander.deucher at amd.com;
> christian.koenig at amd.com; liviu.dudau at arm.com; brian.starkey at arm.com;
> bbrezillon at kernel.org; nicolas.ferre at microchip.com;
> maarten.lankhorst at linux.intel.com; mripard at kernel.org; stefan at agner.ch;
> alison.wang at nxp.com; patrik.r.jakobsson at gmail.com; Chrisanthus, Anitha
> <anitha.chrisanthus at intel.com>; robdclark at gmail.com; Dea, Edmund J
> <edmund.j.dea at intel.com>; sean at poorly.run; shawnguo at kernel.org;
> s.hauer at pengutronix.de; kernel at pengutronix.de; jyri.sarha at iki.fi;
> tomba at kernel.org; Dan.Sneddon at microchip.com;
> tomi.valkeinen at ideasonboard.com; amd-gfx at lists.freedesktop.org; dri-
> devel at lists.freedesktop.org; linux-arm-kernel at lists.infradead.org; linux-arm-
> msm at vger.kernel.org; freedreno at lists.freedesktop.org
> Subject: Re: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
> 
> Hi Thomas,
> 
> On Tue, Aug 03, 2021 at 11:06:50AM +0200, Thomas Zimmermann wrote:
> > DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
> > the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
> > IRQ interfaces.
> >
> > DRM provides IRQ helpers for setting up, receiving and removing IRQ
> > handlers. It's an abstraction over plain Linux functions. The code
> > is mid-layerish with several callbacks to hook into the rsp drivers.
> > Old UMS driver have their interrupts enabled via ioctl, so these
> > abstractions makes some sense. Modern KMS manage all their interrupts
> > internally. Using the DRM helpers adds indirection without benefits.
> >
> > Most KMS drivers already use Linux IRQ functions instead of DRM's
> > abstraction layer. Patches 1 to 12 convert the remaining ones.
> > The patches also resolve a bug for devices without assigned interrupt
> > number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
> > not detect if the device has no interrupt assigned.
> >
> > Patch 13 removes an unused function.
> >
> > Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
> > the old non-KMS drivers still use the functionality.
> >
> > v2:
> > 	* drop IRQ_NOTCONNECTED test from atmel-hlcdc (Sam)
> > 	* use devm_request_irq() in atmel-hlcdc (Sam)
> > 	* unify variable names in arm/hlcdc (Sam)
> >
> > Thomas Zimmermann (14):
> 
> The following patches are all:
> Acked-by: Sam Ravnborg <sam at ravnborg.org>
> 
> >   drm/fsl-dcu: Convert to Linux IRQ interfaces
> >   drm/gma500: Convert to Linux IRQ interfaces
> >   drm/kmb: Convert to Linux IRQ interfaces
> >   drm/msm: Convert to Linux IRQ interfaces
> >   drm/mxsfb: Convert to Linux IRQ interfaces
> >   drm/tidss: Convert to Linux IRQ interfaces
> >   drm/vc4: Convert to Linux IRQ interfaces
> >   drm: Remove unused devm_drm_irq_install()
> 
> The remaining patches I either skipped or already had a feedback from
> me or I asked a question.
> 
> 	Sam


From michael.riesch at wolfvision.net  Tue Aug  3 11:53:04 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue,  3 Aug 2021 20:53:04 +0200
Subject: [PATCH 0/5] arm64: dts: rockchip: rk3568-evb1-v10: add sd card support
Message-ID: <20210803185309.10013-1-michael.riesch@wolfvision.net>

Hi all,

This series enables the SD card reader on the RK3568 EVB1
and completes the support for the on-board eMMC.

As the PMU IO domains are required, this depends on the
patch "soc: rockchip: io-domain: add rk3568 support" [1].

Best regards,
Michael

[1] https://patchwork.kernel.org/project/linux-rockchip/patch/20210527072917.1425321-1-jay.xu at rock-chips.com/

Michael Riesch (5):
  arm64: dts: rockchip: rk3568-evb1-v10: add regulators of rk809 pmic
  arm64: dts: rockchip: enable io domains for rk356x
  arm64: dts: rockchip: rk3568-evb1-v10: enable io domains
  arm64: dts: rockchip: rk3568-evb1-v10: add pinctrl and alias to emmc
    node
  arm64: dts: rockchip: rk3568-evb1-v10: add node for sd card

 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 237 ++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |   5 +
 2 files changed, 242 insertions(+)

-- 
2.17.1



From michael.riesch at wolfvision.net  Tue Aug  3 11:53:05 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue,  3 Aug 2021 20:53:05 +0200
Subject: [PATCH 1/5] arm64: dts: rockchip: rk3568-evb1-v10: add regulators of
 rk809 pmic
In-Reply-To: <20210803185309.10013-1-michael.riesch@wolfvision.net>
References: <20210803185309.10013-1-michael.riesch@wolfvision.net>
Message-ID: <20210803185309.10013-2-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 206 ++++++++++++++++++
 1 file changed, 206 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 65e536c78d2e..f682144a1892 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -104,6 +104,203 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>;
+		rockchip,system-power-controller;
+		wakeup-source;
+
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-init-microvolt = <900000>;
+				regulator-ramp-delay = <6001>;
+				regulator-initial-mode = <0x2>;
+				regulator-name = "vdd_logic";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-init-microvolt = <900000>;
+				regulator-ramp-delay = <6001>;
+				regulator-initial-mode = <0x2>;
+				regulator-name = "vdd_gpu";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+				regulator-name = "vcc_ddr";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-init-microvolt = <900000>;
+				regulator-ramp-delay = <6001>;
+				regulator-initial-mode = <0x2>;
+				regulator-name = "vdd_npu";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-name = "vdda0v9_image";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-name = "vdda_0v9";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-name = "vdda0v9_pmu";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_acodec";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc3v3_pmu";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca_1v8";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca1v8_pmu";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca1v8_image";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_3v3";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
 &mdio0 {
 	rgmii_phy0: ethernet-phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
@@ -124,6 +321,15 @@
 	};
 };
 
+&pinctrl {
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
 &sdhci {
 	bus-width = <8>;
 	max-frequency = <200000000>;
-- 
2.17.1



From michael.riesch at wolfvision.net  Tue Aug  3 11:53:06 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue,  3 Aug 2021 20:53:06 +0200
Subject: [PATCH 2/5] arm64: dts: rockchip: enable io domains for rk356x
In-Reply-To: <20210803185309.10013-1-michael.riesch@wolfvision.net>
References: <20210803185309.10013-1-michael.riesch@wolfvision.net>
Message-ID: <20210803185309.10013-3-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 3e90a8832bb9..834863940eba 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -203,6 +203,11 @@
 	pmugrf: syscon at fdc20000 {
 		compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd";
 		reg = <0x0 0xfdc20000 0x0 0x10000>;
+
+		pmu_io_domains: io-domains {
+			compatible = "rockchip,rk3568-pmu-io-voltage-domain";
+			status = "disabled";
+		};
 	};
 
 	grf: syscon at fdc60000 {
-- 
2.17.1



From michael.riesch at wolfvision.net  Tue Aug  3 11:53:07 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue,  3 Aug 2021 20:53:07 +0200
Subject: [PATCH 3/5] arm64: dts: rockchip: rk3568-evb1-v10: enable io domains
In-Reply-To: <20210803185309.10013-1-michael.riesch@wolfvision.net>
References: <20210803185309.10013-1-michael.riesch@wolfvision.net>
Message-ID: <20210803185309.10013-4-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index f682144a1892..f3fd4a6813a2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -330,6 +330,19 @@
 	};
 };
 
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_1v8>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	max-frequency = <200000000>;
-- 
2.17.1



From michael.riesch at wolfvision.net  Tue Aug  3 11:53:08 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue,  3 Aug 2021 20:53:08 +0200
Subject: [PATCH 4/5] arm64: dts: rockchip: rk3568-evb1-v10: add pinctrl and
 alias to emmc node
In-Reply-To: <20210803185309.10013-1-michael.riesch@wolfvision.net>
References: <20210803185309.10013-1-michael.riesch@wolfvision.net>
Message-ID: <20210803185309.10013-5-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index f3fd4a6813a2..3ac70a8183c4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -16,6 +16,7 @@
 	aliases {
 		ethernet0 = &gmac0;
 		ethernet1 = &gmac1;
+		emmc = &sdhci;
 	};
 
 	chosen: chosen {
@@ -347,6 +348,8 @@
 	bus-width = <8>;
 	max-frequency = <200000000>;
 	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
 	status = "okay";
 };
 
-- 
2.17.1



From michael.riesch at wolfvision.net  Tue Aug  3 11:53:09 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Tue,  3 Aug 2021 20:53:09 +0200
Subject: [PATCH 5/5] arm64: dts: rockchip: rk3568-evb1-v10: add node for sd
 card
In-Reply-To: <20210803185309.10013-1-michael.riesch@wolfvision.net>
References: <20210803185309.10013-1-michael.riesch@wolfvision.net>
Message-ID: <20210803185309.10013-6-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 3ac70a8183c4..b0f5aa8c979c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -17,6 +17,7 @@
 		ethernet0 = &gmac0;
 		ethernet1 = &gmac1;
 		emmc = &sdhci;
+		sd = &sdmmc0;
 	};
 
 	chosen: chosen {
@@ -353,6 +354,20 @@
 	status = "okay";
 };
 
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	sd-uhs-sdr104;
+	supports-sd;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
 &uart2 {
 	status = "okay";
 };
-- 
2.17.1



From lkp at intel.com  Tue Aug  3 11:58:54 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 04 Aug 2021 02:58:54 +0800
Subject: [soc:arm/dt] BUILD SUCCESS
 c4994975132eb2488ad1259c273812ae38f5fccd
Message-ID: <610991ee.CDbJrE2zNU9V7TIF%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/dt
branch HEAD: c4994975132eb2488ad1259c273812ae38f5fccd  Merge tag 'renesas-dt-bindings-for-v5.15-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into arm/dt

elapsed time: 979m

configs tested: 108
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
powerpc                    klondike_defconfig
arm                        mvebu_v7_defconfig
powerpc                     tqm8540_defconfig
arm                        neponset_defconfig
sh                        edosk7705_defconfig
arm                          pxa3xx_defconfig
sh                           se7751_defconfig
arm                         assabet_defconfig
arm                          pxa910_defconfig
powerpc                 mpc8315_rdb_defconfig
sh                           se7722_defconfig
arm                     eseries_pxa_defconfig
sh                          r7780mp_defconfig
sh                            titan_defconfig
mips                     decstation_defconfig
sh                ecovec24-romimage_defconfig
arm                           u8500_defconfig
arm                        magician_defconfig
powerpc                 mpc837x_mds_defconfig
sh                  sh7785lcr_32bit_defconfig
powerpc                         ps3_defconfig
arc                     haps_hs_smp_defconfig
powerpc                     sbc8548_defconfig
um                               alldefconfig
arm                           sunxi_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210803
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From rppt at kernel.org  Tue Aug  3 12:07:37 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 3 Aug 2021 22:07:37 +0300
Subject: [PATCH v3] memblock: make memblock_find_in_range method private
In-Reply-To: <20210803180526.GD5786@arm.com>
References: <20210803064218.6611-1-rppt@kernel.org>
 <20210803180526.GD5786@arm.com>
Message-ID: <YQmT+Z9QhcwI43GK@kernel.org>

On Tue, Aug 03, 2021 at 07:05:26PM +0100, Catalin Marinas wrote:
> On Tue, Aug 03, 2021 at 09:42:18AM +0300, Mike Rapoport wrote:
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index 8490ed2917ff..0bffd2d1854f 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
> >  static void __init reserve_crashkernel(void)
> >  {
> >  	unsigned long long crash_base, crash_size;
> > +	unsigned long long crash_max = arm64_dma_phys_limit;
> >  	int ret;
> >  
> >  	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> > @@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
> >  
> >  	crash_size = PAGE_ALIGN(crash_size);
> >  
> > -	if (crash_base == 0) {
> > -		/* Current arm64 boot protocol requires 2MB alignment */
> > -		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
> > -				crash_size, SZ_2M);
> > -		if (crash_base == 0) {
> > -			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> > -				crash_size);
> > -			return;
> > -		}
> > -	} else {
> > -		/* User specifies base address explicitly. */
> > -		if (!memblock_is_region_memory(crash_base, crash_size)) {
> > -			pr_warn("cannot reserve crashkernel: region is not memory\n");
> > -			return;
> > -		}
> > +	/* User specifies base address explicitly. */
> > +	if (crash_base)
> > +		crash_max = crash_base + crash_size;
> >  
> > -		if (memblock_is_region_reserved(crash_base, crash_size)) {
> > -			pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
> > -			return;
> > -		}
> > -
> > -		if (!IS_ALIGNED(crash_base, SZ_2M)) {
> > -			pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
> > -			return;
> > -		}
> > +	/* Current arm64 boot protocol requires 2MB alignment */
> > +	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> > +					       crash_base, crash_max);
> > +	if (!crash_base) {
> > +		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> > +			crash_size);
> > +		return;
> >  	}
> > -	memblock_reserve(crash_base, crash_size);
> 
> We'll miss a bit on debug information provided to the user in case of a
> wrong crash_base/size option on the command line. Not sure we care much,
> though the alignment would probably be useful (maybe we document it
> somewhere).

It is already documented:

Documentation/admin-guide/kdump/kdump.rst:
   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
   the kernel, X if explicitly specified, must be aligned to 2MiB (0x200000).
 
> What I haven't checked is whether memblock_phys_alloc_range() aims to
> get a 2MB aligned end (size) as well. If crash_size is not 2MB aligned,
> crash_max wouldn't be either and the above could fail. We only care
> about the crash_base to be aligned but the memblock_phys_alloc_range()
> doc says that both the start and size would be aligned to this.

The doc lies :)

memblock_phys_alloc_range() boils down to 

	for_each_free_mem_range_reverse(i, nid, flags, &this_start, &this_end,
					NULL) {

		/* clamp this_{start,end} to the user defined limits */

		cand = round_down(this_end - size, align);
		if (cand >= this_start)
			return cand;
	}

-- 
Sincerely yours,
Mike.


From ezequiel at collabora.com  Tue Aug  3 12:15:39 2021
From: ezequiel at collabora.com (Ezequiel Garcia)
Date: Tue, 03 Aug 2021 16:15:39 -0300
Subject: [PATCH v1 2/2] media: hantro: Add scaling lists feature
In-Reply-To: <20210715151223.656453-3-benjamin.gaignard@collabora.com>
References: <20210715151223.656453-1-benjamin.gaignard@collabora.com>
 <20210715151223.656453-3-benjamin.gaignard@collabora.com>
Message-ID: <1c3d2d66902978e3533074b4d95c8da220cab255.camel@collabora.com>

On Thu, 2021-07-15 at 17:12 +0200, Benjamin Gaignard wrote:
> If the bitstream embedded scaling lists allow the driver to use
> them for decode the frames.
> The scaling lists are expected to be in raster scan order (i.e. not up
> right diagonal scan order)
> Allocate the memory needed to store lists.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>

Reviewed-by: Ezequiel Garcia <ezequiel at collabora.com>

Thanks!

> ---
> ?drivers/staging/media/hantro/hantro_drv.c???? |? 8 +--
> ?.../staging/media/hantro/hantro_g2_hevc_dec.c | 52 +++++++++++++++++++
> ?drivers/staging/media/hantro/hantro_hevc.c??? | 21 ++++++++
> ?drivers/staging/media/hantro/hantro_hw.h????? |? 3 ++
> ?4 files changed, 81 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
> index 8ad074a464fe..5610b7821a54 100644
> --- a/drivers/staging/media/hantro/hantro_drv.c
> +++ b/drivers/staging/media/hantro/hantro_drv.c
> @@ -267,9 +267,6 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
> ??????????????????? sps->bit_depth_luma_minus8 != 2)
> ????????????????????????/* Only 8-bit or 10-bit is supported */
> ????????????????????????return -EINVAL;
> -???????????????if (sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED)
> -???????????????????????/* No scaling support */
> -???????????????????????return -EINVAL;
> ????????}
> ????????return 0;
> ?}
> @@ -451,6 +448,11 @@ static const struct hantro_ctrl controls[] = {
> ????????????????.cfg = {
> ????????????????????????.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS,
> ????????????????},
> +???????}, {
> +???????????????.codec = HANTRO_HEVC_DECODER,
> +???????????????.cfg = {
> +???????????????????????.id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
> +???????????????},
> ????????}, {
> ????????????????.codec = HANTRO_HEVC_DECODER,
> ????????????????.cfg = {
> diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> index 90de74aa6b13..f95135ad553c 100644
> --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> @@ -608,6 +608,56 @@ static void set_buffers(struct hantro_ctx *ctx)
> ????????hantro_write_addr(vpu, G2_TILE_BSD, ctx->hevc_dec.tile_bsd.dma);
> ?}
> ?
> +static void prepare_scaling_list_buffer(struct hantro_ctx *ctx)
> +{
> +???????struct hantro_dev *vpu = ctx->dev;
> +???????const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
> +???????const struct v4l2_ctrl_hevc_scaling_matrix *sc = ctrls->scaling;
> +???????const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
> +???????u8 *p = ((u8 *)ctx->hevc_dec.scaling_lists.cpu);
> +???????unsigned int scaling_list_enabled;
> +???????unsigned int i, j, k;
> +
> +???????scaling_list_enabled = !!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED);
> +???????hantro_reg_write(vpu, &g2_scaling_list_e, scaling_list_enabled);
> +
> +???????if (!scaling_list_enabled)
> +???????????????return;
> +
> +???????for (i = 0; i < ARRAY_SIZE(sc->scaling_list_dc_coef_16x16); i++)
> +???????????????*p++ = sc->scaling_list_dc_coef_16x16[i];
> +
> +???????for (i = 0; i < ARRAY_SIZE(sc->scaling_list_dc_coef_32x32); i++)
> +???????????????*p++ = sc->scaling_list_dc_coef_32x32[i];
> +
> +???????/* 128-bit boundary */
> +???????p += 8;
> +
> +???????/* write scaling lists column by column */
> +
> +???????for (i = 0; i < 6; i++)
> +???????????????for (j = 0; j < 4; j++)
> +???????????????????????for (k = 0; k < 4; k++)
> +???????????????????????????????*p++ = sc->scaling_list_4x4[i][4 * k + j];
> +
> +???????for (i = 0; i < 6; i++)
> +???????????????for (j = 0; j < 8; j++)
> +???????????????????????for (k = 0; k < 8; k++)
> +???????????????????????????????*p++ = sc->scaling_list_8x8[i][8 * k + j];
> +
> +???????for (i = 0; i < 6; i++)
> +???????????????for (j = 0; j < 8; j++)
> +???????????????????????for (k = 0; k < 8; k++)
> +???????????????????????????????*p++ = sc->scaling_list_16x16[i][8 * k + j];
> +
> +???????for (i = 0; i < 2; i++)
> +???????????????for (j = 0; j < 8; j++)
> +???????????????????????for (k = 0; k < 8; k++)
> +???????????????????????????????*p++ = sc->scaling_list_32x32[i][8 * k + j];
> +
> +???????hantro_write_addr(vpu, HEVC_SCALING_LIST, ctx->hevc_dec.scaling_lists.dma);
> +}
> +
> ?static void hantro_g2_check_idle(struct hantro_dev *vpu)
> ?{
> ????????int i;
> @@ -668,6 +718,8 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx)
> ????????set_buffers(ctx);
> ????????prepare_tile_info_buffer(ctx);
> ?
> +???????prepare_scaling_list_buffer(ctx);
> +
> ????????hantro_end_prepare_run(ctx);
> ?
> ????????hantro_reg_write(vpu, &g2_mode, HEVC_DEC_MODE);
> diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
> index 4e816ea73018..95f765d9ff4e 100644
> --- a/drivers/staging/media/hantro/hantro_hevc.c
> +++ b/drivers/staging/media/hantro/hantro_hevc.c
> @@ -20,6 +20,8 @@
> ?/* tile border coefficients of filter */
> ?#define VERT_SAO_RAM_SIZE 48 /* bytes per pixel */
> ?
> +#define SCALING_LIST_SIZE (16 * 64)
> +
> ?#define MAX_TILE_COLS 20
> ?#define MAX_TILE_ROWS 22
> ?
> @@ -296,6 +298,11 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx)
> ????????if (WARN_ON(!ctrls->decode_params))
> ????????????????return -EINVAL;
> ?
> +???????ctrls->scaling =
> +???????????????hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
> +???????if (WARN_ON(!ctrls->scaling))
> +???????????????return -EINVAL;
> +
> ????????ctrls->sps =
> ????????????????hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SPS);
> ????????if (WARN_ON(!ctrls->sps))
> @@ -324,6 +331,12 @@ void hantro_hevc_dec_exit(struct hantro_ctx *ctx)
> ????????????????????????????????? hevc_dec->tile_sizes.dma);
> ????????hevc_dec->tile_sizes.cpu = NULL;
> ?
> +???????if (hevc_dec->scaling_lists.cpu)
> +???????????????dma_free_coherent(vpu->dev, hevc_dec->scaling_lists.size,
> +???????????????????????????????? hevc_dec->scaling_lists.cpu,
> +???????????????????????????????? hevc_dec->scaling_lists.dma);
> +???????hevc_dec->scaling_lists.cpu = NULL;
> +
> ????????if (hevc_dec->tile_filter.cpu)
> ????????????????dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size,
> ????????????????????????????????? hevc_dec->tile_filter.cpu,
> @@ -367,6 +380,14 @@ int hantro_hevc_dec_init(struct hantro_ctx *ctx)
> ?
> ????????hevc_dec->tile_sizes.size = size;
> ?
> +???????hevc_dec->scaling_lists.cpu = dma_alloc_coherent(vpu->dev, SCALING_LIST_SIZE,
> +??????????????????????????????????????????????????????? &hevc_dec->scaling_lists.dma,
> +??????????????????????????????????????????????????????? GFP_KERNEL);
> +???????if (!hevc_dec->scaling_lists.cpu)
> +???????????????return -ENOMEM;
> +
> +???????hevc_dec->scaling_lists.size = SCALING_LIST_SIZE;
> +
> ????????hantro_hevc_ref_init(ctx);
> ?
> ????????return 0;
> diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
> index d8126f8178f5..1becc22af0f9 100644
> --- a/drivers/staging/media/hantro/hantro_hw.h
> +++ b/drivers/staging/media/hantro/hantro_hw.h
> @@ -108,6 +108,7 @@ struct hantro_h264_dec_hw_ctx {
> ? */
> ?struct hantro_hevc_dec_ctrls {
> ????????const struct v4l2_ctrl_hevc_decode_params *decode_params;
> +???????const struct v4l2_ctrl_hevc_scaling_matrix *scaling;
> ????????const struct v4l2_ctrl_hevc_sps *sps;
> ????????const struct v4l2_ctrl_hevc_pps *pps;
> ????????u32 hevc_hdr_skip_length;
> @@ -120,6 +121,7 @@ struct hantro_hevc_dec_ctrls {
> ? * @tile_sao:??????????Tile SAO buffer
> ? * @tile_bsd:??????????Tile BSD control buffer
> ? * @ref_bufs:??????????Internal reference buffers
> + * @scaling_lists:?????Scaling lists buffer
> ? * @ref_bufs_poc:??????Internal reference buffers picture order count
> ? * @ref_bufs_used:?????Bitfield of used reference buffers
> ? * @ctrls:?????????????V4L2 controls attached to a run
> @@ -131,6 +133,7 @@ struct hantro_hevc_dec_hw_ctx {
> ????????struct hantro_aux_buf tile_sao;
> ????????struct hantro_aux_buf tile_bsd;
> ????????struct hantro_aux_buf ref_bufs[NUM_REF_PICTURES];
> +???????struct hantro_aux_buf scaling_lists;
> ????????int ref_bufs_poc[NUM_REF_PICTURES];
> ????????u32 ref_bufs_used;
> ????????struct hantro_hevc_dec_ctrls ctrls;

-- 
Kindly,
Ezequiel



From robh at kernel.org  Tue Aug  3 12:17:30 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 13:17:30 -0600
Subject: [PATCH v13 1/2] dt-bindings: cpufreq: add bindings for MediaTek
 cpufreq HW
In-Reply-To: <20210803050538.g6aj2zsep735ywqv@vireshk-i7>
References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com>
 <1627574891-26514-2-git-send-email-hector.yuan@mediatek.com>
 <20210803050538.g6aj2zsep735ywqv@vireshk-i7>
Message-ID: <YQmWSj0g9ZcZGHtg@robh.at.kernel.org>

On Tue, Aug 03, 2021 at 10:35:38AM +0530, Viresh Kumar wrote:
> On 30-07-21, 00:08, Hector Yuan wrote:
> > From: "Hector.Yuan" <hector.yuan at mediatek.com>
> > 
> > Add devicetree bindings for MediaTek HW driver.
> > 
> > Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
> > ---
> >  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml      |   70 ++++++++++++++++++++
> >  1 file changed, 70 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > new file mode 100644
> > index 0000000..6bb2c97
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> > @@ -0,0 +1,70 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MediaTek's CPUFREQ Bindings
> > +
> > +maintainers:
> > +  - Hector Yuan <hector.yuan at mediatek.com>
> > +
> > +description:
> > +  CPUFREQ HW is a hardware engine used by MediaTek
> > +  SoCs to manage frequency in hardware. It is capable of controlling frequency
> > +  for multiple clusters.
> > +
> 
> Should this somewhere have a reference to
> Documentation/devicetree/bindings/dvfs/performance-domain.yaml ?
> 
> > +properties:
> > +  compatible:
> > +    const: mediatek,cpufreq-hw
> > +
> > +  reg:
> > +    minItems: 1
> > +    maxItems: 2
> > +    description: |
> > +      Addresses and sizes for the memory of the
> > +      HW bases in each frequency domain.
> > +
> > +  "#performance-domain-cells":
> > +    description:
> > +      Number of cells in a performance domain specifier. Typically 1 for nodes
> > +      providing multiple performance domains (e.g. performance controllers),
> > +      but can be any value as specified by device tree binding documentation
> > +      of particular provider.
> 
> You say this can have any value, 1 or more, but then ...
> 
> > +    const: 1
> 
> You fix it to 1 ?
> 
> Perhaps you should add a reference to the performance-domain.yaml here
> as well, and say const 1 here and describe how the parameter is going
> to be used. You should only explain it in respect to your SoC.

Correct in terms of what should be described, but no need to reference 
performance-domain.yaml.

Rob


From robh at kernel.org  Tue Aug  3 12:22:27 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 13:22:27 -0600
Subject: [PATCH v13 1/2] dt-bindings: cpufreq: add bindings for MediaTek
 cpufreq HW
In-Reply-To: <1627574891-26514-2-git-send-email-hector.yuan@mediatek.com>
References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com>
 <1627574891-26514-2-git-send-email-hector.yuan@mediatek.com>
Message-ID: <YQmXc2kofIZacBRw@robh.at.kernel.org>

On Fri, Jul 30, 2021 at 12:08:10AM +0800, Hector Yuan wrote:
> From: "Hector.Yuan" <hector.yuan at mediatek.com>
> 
> Add devicetree bindings for MediaTek HW driver.
> 
> Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
> ---
>  .../bindings/cpufreq/cpufreq-mediatek-hw.yaml      |   70 ++++++++++++++++++++
>  1 file changed, 70 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> 
> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> new file mode 100644
> index 0000000..6bb2c97
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
> @@ -0,0 +1,70 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek's CPUFREQ Bindings
> +
> +maintainers:
> +  - Hector Yuan <hector.yuan at mediatek.com>
> +
> +description:
> +  CPUFREQ HW is a hardware engine used by MediaTek
> +  SoCs to manage frequency in hardware. It is capable of controlling frequency
> +  for multiple clusters.

Strange choice of line breaks.

> +
> +properties:
> +  compatible:
> +    const: mediatek,cpufreq-hw
> +
> +  reg:
> +    minItems: 1
> +    maxItems: 2
> +    description: |

Don't need '|' unless there's formatting to preserve.

> +      Addresses and sizes for the memory of the
> +      HW bases in each frequency domain.

'Each entry corresponds to a register bank for each frequency 
domain present.'

> +
> +  "#performance-domain-cells":
> +    description:
> +      Number of cells in a performance domain specifier. Typically 1 for nodes
> +      providing multiple performance domains (e.g. performance controllers),
> +      but can be any value as specified by device tree binding documentation
> +      of particular provider.
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#performance-domain-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    cpus {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            cpu0: cpu at 0 {
> +                device_type = "cpu";
> +                compatible = "arm,cortex-a55";
> +                enable-method = "psci";
> +                performance-domains = <&performance 0>;
> +                reg = <0x000>;
> +            };
> +    };
> +
> +    /* ... */
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        performance: performance-controller at 11bc00 {
> +            compatible = "mediatek,cpufreq-hw";
> +            reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>;
> +
> +            #performance-domain-cells = <1>;
> +        };
> +    };
> -- 
> 1.7.9.5
> 
> 


From ezequiel at collabora.com  Tue Aug  3 12:27:49 2021
From: ezequiel at collabora.com (Ezequiel Garcia)
Date: Tue, 03 Aug 2021 16:27:49 -0300
Subject: [PATCH v1 2/2] media: hantro: Add scaling lists feature
In-Reply-To: <1c3d2d66902978e3533074b4d95c8da220cab255.camel@collabora.com>
References: <20210715151223.656453-1-benjamin.gaignard@collabora.com>
 <20210715151223.656453-3-benjamin.gaignard@collabora.com>
 <1c3d2d66902978e3533074b4d95c8da220cab255.camel@collabora.com>
Message-ID: <a3faa3c6b82d8fde19bb87b90ca133ca914ea526.camel@collabora.com>

On Tue, 2021-08-03 at 16:15 -0300, Ezequiel Garcia wrote:
> On Thu, 2021-07-15 at 17:12 +0200, Benjamin Gaignard wrote:
> > If the bitstream embedded scaling lists allow the driver to use
> > them for decode the frames.
> > The scaling lists are expected to be in raster scan order (i.e. not up
> > right diagonal scan order)
> > Allocate the memory needed to store lists.
> > 
> > Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
> 
> Reviewed-by: Ezequiel Garcia <ezequiel at collabora.com>
> 

Forgot to mention that I couldn't apply this patch,
so my R-b assumes this is tested and passes the usual tests.

Thanks!
Ezequiel

> Thanks!
> 
> > ---
> > ?drivers/staging/media/hantro/hantro_drv.c???? |? 8 +--
> > ?.../staging/media/hantro/hantro_g2_hevc_dec.c | 52 +++++++++++++++++++
> > ?drivers/staging/media/hantro/hantro_hevc.c??? | 21 ++++++++
> > ?drivers/staging/media/hantro/hantro_hw.h????? |? 3 ++
> > ?4 files changed, 81 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
> > index 8ad074a464fe..5610b7821a54 100644
> > --- a/drivers/staging/media/hantro/hantro_drv.c
> > +++ b/drivers/staging/media/hantro/hantro_drv.c
> > @@ -267,9 +267,6 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
> > ??????????????????? sps->bit_depth_luma_minus8 != 2)
> > ????????????????????????/* Only 8-bit or 10-bit is supported */
> > ????????????????????????return -EINVAL;
> > -???????????????if (sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED)
> > -???????????????????????/* No scaling support */
> > -???????????????????????return -EINVAL;
> > ????????}
> > ????????return 0;
> > ?}
> > @@ -451,6 +448,11 @@ static const struct hantro_ctrl controls[] = {
> > ????????????????.cfg = {
> > ????????????????????????.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS,
> > ????????????????},
> > +???????}, {
> > +???????????????.codec = HANTRO_HEVC_DECODER,
> > +???????????????.cfg = {
> > +???????????????????????.id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
> > +???????????????},
> > ????????}, {
> > ????????????????.codec = HANTRO_HEVC_DECODER,
> > ????????????????.cfg = {
> > diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> > index 90de74aa6b13..f95135ad553c 100644
> > --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> > +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> > @@ -608,6 +608,56 @@ static void set_buffers(struct hantro_ctx *ctx)
> > ????????hantro_write_addr(vpu, G2_TILE_BSD, ctx->hevc_dec.tile_bsd.dma);
> > ?}
> > ?
> > +static void prepare_scaling_list_buffer(struct hantro_ctx *ctx)
> > +{
> > +???????struct hantro_dev *vpu = ctx->dev;
> > +???????const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
> > +???????const struct v4l2_ctrl_hevc_scaling_matrix *sc = ctrls->scaling;
> > +???????const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
> > +???????u8 *p = ((u8 *)ctx->hevc_dec.scaling_lists.cpu);
> > +???????unsigned int scaling_list_enabled;
> > +???????unsigned int i, j, k;
> > +
> > +???????scaling_list_enabled = !!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED);
> > +???????hantro_reg_write(vpu, &g2_scaling_list_e, scaling_list_enabled);
> > +
> > +???????if (!scaling_list_enabled)
> > +???????????????return;
> > +
> > +???????for (i = 0; i < ARRAY_SIZE(sc->scaling_list_dc_coef_16x16); i++)
> > +???????????????*p++ = sc->scaling_list_dc_coef_16x16[i];
> > +
> > +???????for (i = 0; i < ARRAY_SIZE(sc->scaling_list_dc_coef_32x32); i++)
> > +???????????????*p++ = sc->scaling_list_dc_coef_32x32[i];
> > +
> > +???????/* 128-bit boundary */
> > +???????p += 8;
> > +
> > +???????/* write scaling lists column by column */
> > +
> > +???????for (i = 0; i < 6; i++)
> > +???????????????for (j = 0; j < 4; j++)
> > +???????????????????????for (k = 0; k < 4; k++)
> > +???????????????????????????????*p++ = sc->scaling_list_4x4[i][4 * k + j];
> > +
> > +???????for (i = 0; i < 6; i++)
> > +???????????????for (j = 0; j < 8; j++)
> > +???????????????????????for (k = 0; k < 8; k++)
> > +???????????????????????????????*p++ = sc->scaling_list_8x8[i][8 * k + j];
> > +
> > +???????for (i = 0; i < 6; i++)
> > +???????????????for (j = 0; j < 8; j++)
> > +???????????????????????for (k = 0; k < 8; k++)
> > +???????????????????????????????*p++ = sc->scaling_list_16x16[i][8 * k + j];
> > +
> > +???????for (i = 0; i < 2; i++)
> > +???????????????for (j = 0; j < 8; j++)
> > +???????????????????????for (k = 0; k < 8; k++)
> > +???????????????????????????????*p++ = sc->scaling_list_32x32[i][8 * k + j];
> > +
> > +???????hantro_write_addr(vpu, HEVC_SCALING_LIST, ctx->hevc_dec.scaling_lists.dma);
> > +}
> > +
> > ?static void hantro_g2_check_idle(struct hantro_dev *vpu)
> > ?{
> > ????????int i;
> > @@ -668,6 +718,8 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx)
> > ????????set_buffers(ctx);
> > ????????prepare_tile_info_buffer(ctx);
> > ?
> > +???????prepare_scaling_list_buffer(ctx);
> > +
> > ????????hantro_end_prepare_run(ctx);
> > ?
> > ????????hantro_reg_write(vpu, &g2_mode, HEVC_DEC_MODE);
> > diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
> > index 4e816ea73018..95f765d9ff4e 100644
> > --- a/drivers/staging/media/hantro/hantro_hevc.c
> > +++ b/drivers/staging/media/hantro/hantro_hevc.c
> > @@ -20,6 +20,8 @@
> > ?/* tile border coefficients of filter */
> > ?#define VERT_SAO_RAM_SIZE 48 /* bytes per pixel */
> > ?
> > +#define SCALING_LIST_SIZE (16 * 64)
> > +
> > ?#define MAX_TILE_COLS 20
> > ?#define MAX_TILE_ROWS 22
> > ?
> > @@ -296,6 +298,11 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx)
> > ????????if (WARN_ON(!ctrls->decode_params))
> > ????????????????return -EINVAL;
> > ?
> > +???????ctrls->scaling =
> > +???????????????hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
> > +???????if (WARN_ON(!ctrls->scaling))
> > +???????????????return -EINVAL;
> > +
> > ????????ctrls->sps =
> > ????????????????hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SPS);
> > ????????if (WARN_ON(!ctrls->sps))
> > @@ -324,6 +331,12 @@ void hantro_hevc_dec_exit(struct hantro_ctx *ctx)
> > ????????????????????????????????? hevc_dec->tile_sizes.dma);
> > ????????hevc_dec->tile_sizes.cpu = NULL;
> > ?
> > +???????if (hevc_dec->scaling_lists.cpu)
> > +???????????????dma_free_coherent(vpu->dev, hevc_dec->scaling_lists.size,
> > +???????????????????????????????? hevc_dec->scaling_lists.cpu,
> > +???????????????????????????????? hevc_dec->scaling_lists.dma);
> > +???????hevc_dec->scaling_lists.cpu = NULL;
> > +
> > ????????if (hevc_dec->tile_filter.cpu)
> > ????????????????dma_free_coherent(vpu->dev, hevc_dec->tile_filter.size,
> > ????????????????????????????????? hevc_dec->tile_filter.cpu,
> > @@ -367,6 +380,14 @@ int hantro_hevc_dec_init(struct hantro_ctx *ctx)
> > ?
> > ????????hevc_dec->tile_sizes.size = size;
> > ?
> > +???????hevc_dec->scaling_lists.cpu = dma_alloc_coherent(vpu->dev, SCALING_LIST_SIZE,
> > +??????????????????????????????????????????????????????? &hevc_dec->scaling_lists.dma,
> > +??????????????????????????????????????????????????????? GFP_KERNEL);
> > +???????if (!hevc_dec->scaling_lists.cpu)
> > +???????????????return -ENOMEM;
> > +
> > +???????hevc_dec->scaling_lists.size = SCALING_LIST_SIZE;
> > +
> > ????????hantro_hevc_ref_init(ctx);
> > ?
> > ????????return 0;
> > diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
> > index d8126f8178f5..1becc22af0f9 100644
> > --- a/drivers/staging/media/hantro/hantro_hw.h
> > +++ b/drivers/staging/media/hantro/hantro_hw.h
> > @@ -108,6 +108,7 @@ struct hantro_h264_dec_hw_ctx {
> > ? */
> > ?struct hantro_hevc_dec_ctrls {
> > ????????const struct v4l2_ctrl_hevc_decode_params *decode_params;
> > +???????const struct v4l2_ctrl_hevc_scaling_matrix *scaling;
> > ????????const struct v4l2_ctrl_hevc_sps *sps;
> > ????????const struct v4l2_ctrl_hevc_pps *pps;
> > ????????u32 hevc_hdr_skip_length;
> > @@ -120,6 +121,7 @@ struct hantro_hevc_dec_ctrls {
> > ? * @tile_sao:??????????Tile SAO buffer
> > ? * @tile_bsd:??????????Tile BSD control buffer
> > ? * @ref_bufs:??????????Internal reference buffers
> > + * @scaling_lists:?????Scaling lists buffer
> > ? * @ref_bufs_poc:??????Internal reference buffers picture order count
> > ? * @ref_bufs_used:?????Bitfield of used reference buffers
> > ? * @ctrls:?????????????V4L2 controls attached to a run
> > @@ -131,6 +133,7 @@ struct hantro_hevc_dec_hw_ctx {
> > ????????struct hantro_aux_buf tile_sao;
> > ????????struct hantro_aux_buf tile_bsd;
> > ????????struct hantro_aux_buf ref_bufs[NUM_REF_PICTURES];
> > +???????struct hantro_aux_buf scaling_lists;
> > ????????int ref_bufs_poc[NUM_REF_PICTURES];
> > ????????u32 ref_bufs_used;
> > ????????struct hantro_hevc_dec_ctrls ctrls;
> 

-- 
Kindly,
Ezequiel



From robh at kernel.org  Tue Aug  3 12:28:47 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 13:28:47 -0600
Subject: [PATCH] dt-bindings: soc: ti: pruss: Add dma-coherent property
In-Reply-To: <20210730031901.26243-1-s-anna@ti.com>
References: <20210730031901.26243-1-s-anna@ti.com>
Message-ID: <YQmY7/OSHJxRkM5m@robh.at.kernel.org>

On Thu, Jul 29, 2021 at 10:19:01PM -0500, Suman Anna wrote:
> Update the PRUSS schema file to include the dma-coherent property
> that indicates the coherency of the IP. The PRUSS IPs on 66AK2G
> SoCs do use this property.
> 
> Signed-off-by: Suman Anna <s-anna at ti.com>
> ---
> Hi Santosh,
> 
> This patch updates the PRUSS binding in preparation for adding the
> PRUSS nodes for 66AK2G SoCs. Without this, the dtbs_check would
> complain about the undefined dma-coherent property. Patch is top
> of the AM64 ICSSG binding update patch [1].

New required properties are not backwards compatible. You are kind of 
saying that here (not used yet?), but make that clear in the commit msg.

With that fixed,

Reviewed-by: Rob Herring <robh at kernel.org>

> 
> regards
> Suman
> 
> [1] https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210623165032.31223-2-s-anna at ti.com/
> 
>  .../devicetree/bindings/soc/ti/ti,pruss.yaml  | 37 +++++++++++++------
>  1 file changed, 25 insertions(+), 12 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
> index 47d7fd24bc56..9d128b9e7deb 100644
> --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
> +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
> @@ -85,6 +85,8 @@ properties:
>    dma-ranges:
>      maxItems: 1
>  
> +  dma-coherent: true
> +
>    power-domains:
>      description: |
>        This property is as per sci-pm-domain.txt.
> @@ -324,18 +326,29 @@ additionalProperties: false
>  # - interrupt-controller
>  # - pru
>  
> -if:
> -  properties:
> -    compatible:
> -      contains:
> -        enum:
> -          - ti,k2g-pruss
> -          - ti,am654-icssg
> -          - ti,j721e-icssg
> -          - ti,am642-icssg
> -then:
> -  required:
> -    - power-domains
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - ti,k2g-pruss
> +              - ti,am654-icssg
> +              - ti,j721e-icssg
> +              - ti,am642-icssg
> +    then:
> +      required:
> +        - power-domains
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - ti,k2g-pruss
> +    then:
> +      required:
> +        - dma-coherent
>  
>  examples:
>    - |
> -- 
> 2.32.0
> 
> 


From ezequiel at collabora.com  Tue Aug  3 12:29:14 2021
From: ezequiel at collabora.com (Ezequiel Garcia)
Date: Tue, 03 Aug 2021 16:29:14 -0300
Subject: [PATCH v1 1/2] media: hevc: Add scaling matrix control
In-Reply-To: <20210715151223.656453-2-benjamin.gaignard@collabora.com>
References: <20210715151223.656453-1-benjamin.gaignard@collabora.com>
 <20210715151223.656453-2-benjamin.gaignard@collabora.com>
Message-ID: <b89860d253b5610d6c20c1d843fc2e63d3e73c28.camel@collabora.com>

On Thu, 2021-07-15 at 17:12 +0200, Benjamin Gaignard wrote:
> HEVC scaling lists are used for the scaling process for transform
> coefficients.
> V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED has to set when they are
> encoded in the bitstream.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>

The HEVC control structs have some holes that we should fix soon,
but the scaling matrix struct looks good, so I think we can merge this one.

Reviewed-by: Ezequiel Garcia <ezequiel at collabora.com>

Thanks,
Ezequiel

> ---
> ?.../media/v4l/ext-ctrls-codec.rst???????????? | 57 +++++++++++++++++++
> ?.../media/v4l/vidioc-queryctrl.rst??????????? |? 6 ++
> ?drivers/media/v4l2-core/v4l2-ctrls-core.c???? |? 6 ++
> ?drivers/media/v4l2-core/v4l2-ctrls-defs.c???? |? 4 ++
> ?include/media/hevc-ctrls.h??????????????????? | 11 ++++
> ?5 files changed, 84 insertions(+)
> 
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> index dc096a5562cd..ab3bda79b440 100644
> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> @@ -3071,6 +3071,63 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
> ?
> ???? \normalsize
> ?
> +``V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (struct)``
> +??? Specifies the HEVC scaling matrix parameters used for the scaling process
> +??? for transform coefficients.
> +??? These matrix and parameters are defined according to :ref:`hevc`.
> +??? They are described in section 7.4.5 "Scaling list data semantics" of
> +??? the specification.
> +
> +.. c:type:: v4l2_ctrl_hevc_scaling_matrix
> +
> +.. raw:: latex
> +
> +??? \scriptsize
> +
> +.. tabularcolumns:: |p{5.4cm}|p{6.8cm}|p{5.1cm}|
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_hevc_scaling_matrix
> +??? :header-rows:? 0
> +??? :stub-columns: 0
> +??? :widths:?????? 1 1 2
> +
> +??? * - __u8
> +????? - ``scaling_list_4x4[6][16]``
> +????? - Scaling list is used for the scaling process for transform
> +??????? coefficients. The values on each scaling list are expected
> +??????? in raster scan order.
> +??? * - __u8
> +????? - ``scaling_list_8x8[6][64]``
> +????? - Scaling list is used for the scaling process for transform
> +??????? coefficients. The values on each scaling list are expected
> +??????? in raster scan order.
> +??? * - __u8
> +????? - ``scaling_list_16x16[6][64]``
> +????? - Scaling list is used for the scaling process for transform
> +??????? coefficients. The values on each scaling list are expected
> +??????? in raster scan order.
> +??? * - __u8
> +????? - ``scaling_list_32x32[2][64]``
> +????? - Scaling list is used for the scaling process for transform
> +??????? coefficients. The values on each scaling list are expected
> +??????? in raster scan order.
> +??? * - __u8
> +????? - ``scaling_list_dc_coef_16x16[6]``
> +????? - Scaling list is used for the scaling process for transform
> +??????? coefficients. The values on each scaling list are expected
> +??????? in raster scan order.
> +??? * - __u8
> +????? - ``scaling_list_dc_coef_32x32[2]``
> +????? - Scaling list is used for the scaling process for transform
> +??????? coefficients. The values on each scaling list are expected
> +??????? in raster scan order.
> +
> +.. raw:: latex
> +
> +??? \normalsize
> +
> ?.. c:type:: v4l2_hevc_dpb_entry
> ?
> ?.. raw:: latex
> diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> index f9ecf6276129..2f491c17dd5d 100644
> --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> @@ -495,6 +495,12 @@ See also the examples in :ref:`control`.
> ?????? - n/a
> ?????? - A struct :c:type:`v4l2_ctrl_hevc_slice_params`, containing HEVC
> ????????slice parameters for stateless video decoders.
> +??? * - ``V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX``
> +????? - n/a
> +????? - n/a
> +????? - n/a
> +????? - A struct :c:type:`v4l2_ctrl_hevc_scaling_matrix`, containing HEVC
> +???????scaling matrix for stateless video decoders.
> ???? * - ``V4L2_CTRL_TYPE_VP8_FRAME``
> ?????? - n/a
> ?????? - n/a
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> index c4b5082849b6..70adfc1b9c81 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> @@ -687,6 +687,9 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
> ?
> ????????????????break;
> ?
> +???????case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
> +???????????????break;
> +
> ????????case V4L2_CTRL_TYPE_AREA:
> ????????????????area = p;
> ????????????????if (!area->width || !area->height)
> @@ -1240,6 +1243,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
> ????????case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> ????????????????elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
> ????????????????break;
> +???????case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
> +???????????????elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix);
> +???????????????break;
> ????????case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
> ????????????????elem_size = sizeof(struct v4l2_ctrl_hevc_decode_params);
> ????????????????break;
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> index b6344bbf1e00..cb29c2a7fabe 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> @@ -996,6 +996,7 @@ const char *v4l2_ctrl_get_name(u32 id)
> ????????case V4L2_CID_MPEG_VIDEO_HEVC_SPS:??????????????????????return "HEVC Sequence Parameter Set";
> ????????case V4L2_CID_MPEG_VIDEO_HEVC_PPS:??????????????????????return "HEVC Picture Parameter Set";
> ????????case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:?????????????return "HEVC Slice Parameters";
> +???????case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX:???????????return "HEVC Scaling Matrix";
> ????????case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:????????????return "HEVC Decode Parameters";
> ????????case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:??????????????return "HEVC Decode Mode";
> ????????case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:???????????????return "HEVC Start Code";
> @@ -1488,6 +1489,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
> ????????case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
> ????????????????*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
> ????????????????break;
> +???????case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX:
> +???????????????*type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX;
> +???????????????break;
> ????????case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:
> ????????????????*type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS;
> ????????????????break;
> diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
> index 781371bff2ad..ef63bc205756 100644
> --- a/include/media/hevc-ctrls.h
> +++ b/include/media/hevc-ctrls.h
> @@ -19,6 +19,7 @@
> ?#define V4L2_CID_MPEG_VIDEO_HEVC_SPS???????????(V4L2_CID_CODEC_BASE + 1008)
> ?#define V4L2_CID_MPEG_VIDEO_HEVC_PPS???????????(V4L2_CID_CODEC_BASE + 1009)
> ?#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS??(V4L2_CID_CODEC_BASE + 1010)
> +#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX????????(V4L2_CID_CODEC_BASE + 1011)
> ?#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS?(V4L2_CID_CODEC_BASE + 1012)
> ?#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE???(V4L2_CID_CODEC_BASE + 1015)
> ?#define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE????(V4L2_CID_CODEC_BASE + 1016)
> @@ -27,6 +28,7 @@
> ?#define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
> ?#define V4L2_CTRL_TYPE_HEVC_PPS 0x0121
> ?#define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122
> +#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123
> ?#define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124
> ?
> ?enum v4l2_mpeg_video_hevc_decode_mode {
> @@ -225,6 +227,15 @@ struct v4l2_ctrl_hevc_decode_params {
> ????????__u64???flags;
> ?};
> ?
> +struct v4l2_ctrl_hevc_scaling_matrix {
> +???????__u8????scaling_list_4x4[6][16];
> +???????__u8????scaling_list_8x8[6][64];
> +???????__u8????scaling_list_16x16[6][64];
> +???????__u8????scaling_list_32x32[2][64];
> +???????__u8????scaling_list_dc_coef_16x16[6];
> +???????__u8????scaling_list_dc_coef_32x32[2];
> +};
> +
> ?/*? MPEG-class control IDs specific to the Hantro driver as defined by V4L2 */
> ?#define V4L2_CID_CODEC_HANTRO_BASE?????????????????????????????(V4L2_CTRL_CLASS_CODEC | 0x1200)
> ?/*

-- 
Kindly,
Ezequiel



From broonie at kernel.org  Tue Aug  3 12:30:49 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 3 Aug 2021 20:30:49 +0100
Subject: [PATCH v2 3/4] spi: mediatek: modify set_cs_timing callback
In-Reply-To: <CAHp75VcPhBB+21wVErWRq+mSDaCkpQBovn+xvMbXyfENnuu40Q@mail.gmail.com>
References: <20210803102428.6476-1-Mason.Zhang@mediatek.com>
 <CAHp75VcPhBB+21wVErWRq+mSDaCkpQBovn+xvMbXyfENnuu40Q@mail.gmail.com>
Message-ID: <20210803193049.GQ4668@sirena.org.uk>

On Tue, Aug 03, 2021 at 09:20:19PM +0300, Andy Shevchenko wrote:
> On Tue, Aug 3, 2021 at 1:42 PM Mason Zhang <Mason.Zhang at mediatek.com> wrote:

> > +       inactive = inactive ? inactive : 1;

> All of these can be simplified by using ?: (short ternary) form.

Please don't, if anything just don't use the ternery operator at all for
things like this - it doesn't help with legibility.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210803/214f5362/attachment.sig>

From s-anna at ti.com  Tue Aug  3 12:32:32 2021
From: s-anna at ti.com (Suman Anna)
Date: Tue, 3 Aug 2021 14:32:32 -0500
Subject: [PATCH] dt-bindings: soc: ti: pruss: Add dma-coherent property
In-Reply-To: <YQmY7/OSHJxRkM5m@robh.at.kernel.org>
References: <20210730031901.26243-1-s-anna@ti.com>
 <YQmY7/OSHJxRkM5m@robh.at.kernel.org>
Message-ID: <411c54ef-6ae6-2a17-c2c4-fb19580b5513@ti.com>

On 8/3/21 2:28 PM, Rob Herring wrote:
> On Thu, Jul 29, 2021 at 10:19:01PM -0500, Suman Anna wrote:
>> Update the PRUSS schema file to include the dma-coherent property
>> that indicates the coherency of the IP. The PRUSS IPs on 66AK2G
>> SoCs do use this property.
>>
>> Signed-off-by: Suman Anna <s-anna at ti.com>
>> ---
>> Hi Santosh,
>>
>> This patch updates the PRUSS binding in preparation for adding the
>> PRUSS nodes for 66AK2G SoCs. Without this, the dtbs_check would
>> complain about the undefined dma-coherent property. Patch is top
>> of the AM64 ICSSG binding update patch [1].
> 
> New required properties are not backwards compatible. You are kind of 
> saying that here (not used yet?), but make that clear in the commit msg.

OK. Yeah, we haven't added the K2G dts nodes yet, and the new required property
is only applicable for that SoC and not others.

regards
Suman

> 
> With that fixed,
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> 
>>
>> regards
>> Suman
>>
>> [1] https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210623165032.31223-2-s-anna at ti.com/
>>
>>  .../devicetree/bindings/soc/ti/ti,pruss.yaml  | 37 +++++++++++++------
>>  1 file changed, 25 insertions(+), 12 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
>> index 47d7fd24bc56..9d128b9e7deb 100644
>> --- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
>> +++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
>> @@ -85,6 +85,8 @@ properties:
>>    dma-ranges:
>>      maxItems: 1
>>  
>> +  dma-coherent: true
>> +
>>    power-domains:
>>      description: |
>>        This property is as per sci-pm-domain.txt.
>> @@ -324,18 +326,29 @@ additionalProperties: false
>>  # - interrupt-controller
>>  # - pru
>>  
>> -if:
>> -  properties:
>> -    compatible:
>> -      contains:
>> -        enum:
>> -          - ti,k2g-pruss
>> -          - ti,am654-icssg
>> -          - ti,j721e-icssg
>> -          - ti,am642-icssg
>> -then:
>> -  required:
>> -    - power-domains
>> +allOf:
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            enum:
>> +              - ti,k2g-pruss
>> +              - ti,am654-icssg
>> +              - ti,j721e-icssg
>> +              - ti,am642-icssg
>> +    then:
>> +      required:
>> +        - power-domains
>> +
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            enum:
>> +              - ti,k2g-pruss
>> +    then:
>> +      required:
>> +        - dma-coherent
>>  
>>  examples:
>>    - |
>> -- 
>> 2.32.0
>>
>>



From martin.blumenstingl at googlemail.com  Tue Aug  3 12:32:41 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Tue, 3 Aug 2021 21:32:41 +0200
Subject: [PATCH v1 0/6] clk: switch dividers to .determine_rate
In-Reply-To: <20210702225145.2643303-1-martin.blumenstingl@googlemail.com>
References: <20210702225145.2643303-1-martin.blumenstingl@googlemail.com>
Message-ID: <CAFBinCDGHdqEDv4DA4QU9T2pmMS3GMSo_tJDzya=Uhcr8Fr5Uw@mail.gmail.com>

Hi Stephen,


On Sat, Jul 3, 2021 at 12:51 AM Martin Blumenstingl
<martin.blumenstingl at googlemail.com> wrote:
[...]
> Martin Blumenstingl (6):
>   clk: divider: Implement and wire up .determine_rate by default
>   clk: imx: clk-divider-gate: Switch to clk_divider.determine_rate
Abel has already picked this patch (thanks!)

Can you please take the rest of the series (that is: patch 1 and patches 3-6)?
I can also re-send them if you prefer that.

Best regards,
Martin


From raagjadav at gmail.com  Tue Aug  3 12:44:54 2021
From: raagjadav at gmail.com (Raag Jadav)
Date: Wed, 4 Aug 2021 01:14:54 +0530
Subject: [PATCH] arm64: dts: ls1046a: fix eeprom entries
In-Reply-To: <CADRPPNQ2M1N1pV2brfFRXOf1ASK2bhiZpQivNhNws_+RUfCT-g@mail.gmail.com>
References: <1627927742-8675-1-git-send-email-raagjadav@gmail.com>
 <CADRPPNQ2M1N1pV2brfFRXOf1ASK2bhiZpQivNhNws_+RUfCT-g@mail.gmail.com>
Message-ID: <20210803194454.GA9471@localhost>

On Mon, Aug 02, 2021 at 05:44:29PM -0500, Li Yang wrote:
> On Mon, Aug 2, 2021 at 1:10 PM Raag Jadav <raagjadav at gmail.com> wrote:
> >
> > ls1046afrwy and ls1046ardb boards have CAT24C04[1] and CAT24C05[2]
> > eeproms respectively. Both are 4Kb (512 bytes) in size.
> 
> These part names are from onsemi instead of atmel.  Are there same
> part names from atmel which are also compatible with the onsemi parts?

The part names are different, but they are functionally compatible.

>  If we want to use onsemi only part names, probably we will need two
> compatible strings with the first one from onsemi and the second from
> atmel.  Although the binding doesn't support onsemi prefix yet.

Should I add it to the at24 binding document with atmel as a fallback?

> 
> > Remove multi-address entries, as we have auto-rollover support
> > in at24 driver.
> 
> The device tree should describe hardware instead of matching how
> driver deal with it.  Is the board really using a single chip or
> multiple chips here?

Yes, both the boards have a single chip each.

> 
> >
> > [1] https://www.onsemi.com/pdf/datasheet/cat24c01-d.pdf
> > [2] https://www.onsemi.com/pdf/datasheet/cat24c03-d.pdf
> >
> > Signed-off-by: Raag Jadav <raagjadav at gmail.com>
> > ---
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +-------
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts  | 7 +------
> >  2 files changed, 2 insertions(+), 13 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> > index db3d303..83afe21 100644
> > --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> > @@ -83,15 +83,9 @@
> >                         };
> >
> >                         eeprom at 52 {
> > -                               compatible = "atmel,24c512";
> > +                               compatible = "atmel,24c04";
> >                                 reg = <0x52>;
> >                         };
> > -
> > -                       eeprom at 53 {
> > -                               compatible = "atmel,24c512";
> > -                               reg = <0x53>;
> > -                       };
> > -
> >                 };
> >         };
> >  };
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > index 60acdf0..d220f98 100644
> > --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > @@ -59,14 +59,9 @@
> >         };
> >
> >         eeprom at 52 {
> > -               compatible = "atmel,24c512";
> > +               compatible = "atmel,24c04";
> >                 reg = <0x52>;
> >         };
> > -
> > -       eeprom at 53 {
> > -               compatible = "atmel,24c512";
> > -               reg = <0x53>;
> > -       };
> >  };
> >
> >  &i2c3 {
> > --
> > 2.7.4
> >


From zajec5 at gmail.com  Tue Aug  3 12:45:32 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Tue, 3 Aug 2021 21:45:32 +0200
Subject: PCI DT regressions affecting Northstar (iproc driver)
Message-ID: <440bd70a-81c4-357d-9fb5-1f45fca17148@gmail.com>

Hi,

I normally stick to LTS kernel releases and I just late-found 2
regressions while switching from 5.4 to the 5.10.

The whole thing is about Broadcom's Northstar platform and a bit quirky
iproc PCI driver (precisely: pcie-iproc-bcma part). The iproc PCI driver
supports both: platform device (based on DT) and bcma device.

Northstar support uses a mix of DT and bcma. The later is a bus with
EEPROM containing platform devices info. Its history is decades old and
that design comes from pre-DT times. In any case:
1. Northstar PCI controllers are bcma devices with minimalistic DT nodes
2. Everything worked great with 5.4 and quite OK with 5.8

Reference:
* arch/arm/boot/dts/bcm5301x.dtsi
* drivers/pci/controller/pcie-iproc-bcma.c

Could you look at those problems and check if it's possible to fix them
in some easy way (without a big refactoring) please?

**********

The first regression results in "no space for" and "failed to assign"
info-errors like:
[    1.353173] pci 0000:00:00.0: BAR 8: no space for [mem size 0x00c00000]
[    1.359816] pci 0000:00:00.0: BAR 8: failed to assign [mem size 0x00c00000]

They don't seem to cause any real harm, PCI devices are still visible.

It is caused by the:

commit 7ef1c871da16125ae58db13716fe82795dcbe3e8
Author: Rob Herring <robh at kernel.org>
Date:   Mon Oct 28 11:32:38 2019 -0500

     PCI: iproc: Use pci_parse_request_of_pci_ranges()

     Convert the iProc host bridge to use the common
     pci_parse_request_of_pci_ranges().

     There's no need to assign the resources to a temporary list, so just use
     bridge->windows directly.

     Signed-off-by: Rob Herring <robh at kernel.org>
     Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
     Reviewed-by: Andrew Murray <andrew.murray at arm.com>
     Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
     Cc: Bjorn Helgaas <bhelgaas at google.com>
     Cc: Ray Jui <rjui at broadcom.com>
     Cc: Scott Branden <sbranden at broadcom.com>
     Cc: bcm-kernel-feedback-list at broadcom.com

**********

The second regression results in "No bus range found for" errors like:
[    1.096377] pcie_iproc_bcma bcma0:7: host bridge /axi at 18000000/pcie at 12000 ranges:
[    1.103954] pcie_iproc_bcma bcma0:7:   No bus range found for /axi at 18000000/pcie at 12000, using [bus 00-ff]

It results in not registering PCI bus at all.

Forwardtrace for that error:

iproc_pcie_bcma_probe()
devm_pci_alloc_host_bridge()
devm_of_pci_bridge_init()
pci_parse_request_of_pci_ranges()
devm_of_pci_get_host_bridge_resources()
of_pci_range_parser_init()
parser_init()
return -ENOENT;

It is caused by the :

commit 669cbc708122fc7a02282058a09f096200cee090
Author: Rob Herring <robh at kernel.org>
Date:   Tue Jul 21 20:25:13 2020 -0600

     PCI: Move DT resource setup into devm_pci_alloc_host_bridge()

     Now that pci_parse_request_of_pci_ranges() callers just setup
     pci_host_bridge.windows and dma_ranges directly and don't need the bus
     range returned, we can just initialize them when allocating the
     pci_host_bridge struct.

     With this, pci_parse_request_of_pci_ranges() becomes a static function.

     Link: https://lore.kernel.org/r/20200722022514.1283916-19-robh at kernel.org
     Signed-off-by: Rob Herring <robh at kernel.org>
     Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
     Acked-by: Bjorn Helgaas <bhelgaas at google.com>
     Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
     Cc: Bjorn Helgaas <bhelgaas at google.com>

**********

7ef1c871da16~1
[    1.160172] pcie_iproc_bcma bcma0:7: link: UP
[    1.164661] pcie_iproc_bcma bcma0:7: PCI host bridge to bus 0000:00
[    1.170978] pci_bus 0000:00: root bus resource [mem 0x08000000-0x0fffffff]
[    1.177873] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    1.185835] pci 0000:00:00.0: [14e4:d612] type 01 class 0x060400
[    1.191878] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.201562] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.211257] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x1c may corrupt adjacent RW1C bits
[    1.221023] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x1c may corrupt adjacent RW1C bits
[    1.230796] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.240592] pci 0000:00:00.0: PME# supported from D0 D3hot D3cold
[    1.246702] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4c may corrupt adjacent RW1C bits
[    1.257090] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.266871] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.276557] pci_bus 0000:00: 1-byte config write to 0000:00:00.0 offset 0xc may corrupt adjacent RW1C bits
[    1.286238] PCI: bus0: Fast back to back transfers disabled
[    1.291828] pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.299848] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.309740] pci 0000:01:00.0: [14e4:4365] type 00 class 0x028000
[    1.315818] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00007fff 64bit]
[    1.322633] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x007fffff 64bit]
[    1.329441] pci 0000:01:00.0: reg 0x20: [mem 0x00000000-0x000fffff 64bit pref]
[    1.336773] pci 0000:01:00.0: supports D1 D2
[    1.341625] PCI: bus1: Fast back to back transfers disabled
[    1.347223] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    1.353870] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
[    1.360532] pci 0000:00:00.0: BAR 8: assigned [mem 0x08000000-0x08bfffff]
[    1.367341] pci 0000:00:00.0: BAR 9: assigned [mem 0x08c00000-0x08cfffff 64bit pref]
[    1.375118] pci 0000:01:00.0: BAR 2: assigned [mem 0x08000000-0x087fffff 64bit]
[    1.382459] pci 0000:01:00.0: BAR 4: assigned [mem 0x08c00000-0x08cfffff 64bit pref]
[    1.390237] pci 0000:01:00.0: BAR 0: assigned [mem 0x08800000-0x08807fff 64bit]
[    1.397566] pci 0000:00:00.0: PCI bridge to [bus 01]
[    1.402545] pci 0000:00:00.0:   bridge window [mem 0x08000000-0x08bfffff]
[    1.409343] pci 0000:00:00.0:   bridge window [mem 0x08c00000-0x08cfffff 64bit pref]
[    1.540170] pcie_iproc_bcma bcma0:8: link: UP
[    1.544652] pcie_iproc_bcma bcma0:8: PCI host bridge to bus 0001:00
[    1.550967] pci_bus 0001:00: root bus resource [mem 0x20000000-0x27ffffff]
[    1.557861] pci_bus 0001:00: No busn resource found for root bus, will use [bus 00-ff]
[    1.565826] pci 0001:00:00.0: [14e4:d612] type 01 class 0x060400
[    1.571915] pci 0001:00:00.0: PME# supported from D0 D3hot D3cold
[    1.578596] PCI: bus0: Fast back to back transfers disabled
[    1.584208] pci 0001:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.592378] pci 0001:01:00.0: [14e4:4365] type 00 class 0x028000
[    1.598442] pci 0001:01:00.0: reg 0x10: [mem 0x00000000-0x00007fff 64bit]
[    1.605276] pci 0001:01:00.0: reg 0x18: [mem 0x00000000-0x007fffff 64bit]
[    1.612092] pci 0001:01:00.0: reg 0x20: [mem 0x00000000-0x000fffff 64bit pref]
[    1.619420] pci 0001:01:00.0: supports D1 D2
[    1.624263] PCI: bus1: Fast back to back transfers disabled
[    1.629861] pci_bus 0001:01: busn_res: [bus 01-ff] end is updated to 01
[    1.636525] pci_bus 0001:00: busn_res: [bus 00-ff] end is updated to 01
[    1.643175] pci 0001:00:00.0: BAR 8: assigned [mem 0x20000000-0x20bfffff]
[    1.649978] pci 0001:00:00.0: BAR 9: assigned [mem 0x20c00000-0x20cfffff 64bit pref]
[    1.657753] pci 0001:01:00.0: BAR 2: assigned [mem 0x20000000-0x207fffff 64bit]
[    1.665092] pci 0001:01:00.0: BAR 4: assigned [mem 0x20c00000-0x20cfffff 64bit pref]
[    1.672865] pci 0001:01:00.0: BAR 0: assigned [mem 0x20800000-0x20807fff 64bit]
[    1.680200] pci 0001:00:00.0: PCI bridge to [bus 01]
[    1.685175] pci 0001:00:00.0:   bridge window [mem 0x20000000-0x20bfffff]
[    1.691987] pci 0001:00:00.0:   bridge window [mem 0x20c00000-0x20cfffff 64bit pref]
[    1.820168] pcie_iproc_bcma bcma0:9: PHY or data link is INACTIVE!
[    1.826370] pcie_iproc_bcma bcma0:9: no PCIe EP device detected
[    1.832308] pcie_iproc_bcma bcma0:9: PCIe controller setup failed

7ef1c871da16
[    1.159737] pcie_iproc_bcma bcma0:7: link: UP
[    1.164214] pcie_iproc_bcma bcma0:7: PCI host bridge to bus 0000:00
[    1.170517] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    1.178474] pci 0000:00:00.0: [14e4:d612] type 01 class 0x060400
[    1.184517] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.194207] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.203900] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x1c may corrupt adjacent RW1C bits
[    1.213667] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x1c may corrupt adjacent RW1C bits
[    1.223440] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.233236] pci 0000:00:00.0: PME# supported from D0 D3hot D3cold
[    1.239347] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4c may corrupt adjacent RW1C bits
[    1.249724] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.259512] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.269202] pci_bus 0000:00: 1-byte config write to 0000:00:00.0 offset 0xc may corrupt adjacent RW1C bits
[    1.278882] PCI: bus0: Fast back to back transfers disabled
[    1.284473] pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.292498] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.302387] pci 0000:01:00.0: [14e4:4365] type 00 class 0x028000
[    1.308449] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00007fff 64bit]
[    1.315276] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x007fffff 64bit]
[    1.322091] pci 0000:01:00.0: reg 0x20: [mem 0x00000000-0x000fffff 64bit pref]
[    1.329420] pci 0000:01:00.0: supports D1 D2
[    1.334283] PCI: bus1: Fast back to back transfers disabled
[    1.339889] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    1.346523] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
[    1.353173] pci 0000:00:00.0: BAR 8: no space for [mem size 0x00c00000]
[    1.359816] pci 0000:00:00.0: BAR 8: failed to assign [mem size 0x00c00000]
[    1.366790] pci 0000:00:00.0: BAR 9: no space for [mem size 0x00100000 64bit pref]
[    1.374386] pci 0000:00:00.0: BAR 9: failed to assign [mem size 0x00100000 64bit pref]
[    1.382325] pci 0000:01:00.0: BAR 2: no space for [mem size 0x00800000 64bit]
[    1.389470] pci 0000:01:00.0: BAR 2: failed to assign [mem size 0x00800000 64bit]
[    1.396971] pci 0000:01:00.0: BAR 4: no space for [mem size 0x00100000 64bit pref]
[    1.404559] pci 0000:01:00.0: BAR 4: failed to assign [mem size 0x00100000 64bit pref]
[    1.412497] pci 0000:01:00.0: BAR 0: no space for [mem size 0x00008000 64bit]
[    1.419646] pci 0000:01:00.0: BAR 0: failed to assign [mem size 0x00008000 64bit]
[    1.427146] pci 0000:00:00.0: PCI bridge to [bus 01]
[    1.549735] pcie_iproc_bcma bcma0:8: link: UP
[    1.554214] pcie_iproc_bcma bcma0:8: PCI host bridge to bus 0001:00
[    1.560519] pci_bus 0001:00: No busn resource found for root bus, will use [bus 00-ff]
[    1.568474] pci 0001:00:00.0: [14e4:d612] type 01 class 0x060400
[    1.574563] pci 0001:00:00.0: PME# supported from D0 D3hot D3cold
[    1.581269] PCI: bus0: Fast back to back transfers disabled
[    1.586865] pci 0001:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.595034] pci 0001:01:00.0: [14e4:4365] type 00 class 0x028000
[    1.601111] pci 0001:01:00.0: reg 0x10: [mem 0x00000000-0x00007fff 64bit]
[    1.607925] pci 0001:01:00.0: reg 0x18: [mem 0x00000000-0x007fffff 64bit]
[    1.614747] pci 0001:01:00.0: reg 0x20: [mem 0x00000000-0x000fffff 64bit pref]
[    1.622081] pci 0001:01:00.0: supports D1 D2
[    1.626921] PCI: bus1: Fast back to back transfers disabled
[    1.632533] pci_bus 0001:01: busn_res: [bus 01-ff] end is updated to 01
[    1.639170] pci_bus 0001:00: busn_res: [bus 00-ff] end is updated to 01
[    1.645828] pci 0001:00:00.0: BAR 8: no space for [mem size 0x00c00000]
[    1.652462] pci 0001:00:00.0: BAR 8: failed to assign [mem size 0x00c00000]
[    1.659435] pci 0001:00:00.0: BAR 9: no space for [mem size 0x00100000 64bit pref]
[    1.667030] pci 0001:00:00.0: BAR 9: failed to assign [mem size 0x00100000 64bit pref]
[    1.674970] pci 0001:01:00.0: BAR 2: no space for [mem size 0x00800000 64bit]
[    1.682122] pci 0001:01:00.0: BAR 2: failed to assign [mem size 0x00800000 64bit]
[    1.689620] pci 0001:01:00.0: BAR 4: no space for [mem size 0x00100000 64bit pref]
[    1.697206] pci 0001:01:00.0: BAR 4: failed to assign [mem size 0x00100000 64bit pref]
[    1.705143] pci 0001:01:00.0: BAR 0: no space for [mem size 0x00008000 64bit]
[    1.712305] pci 0001:01:00.0: BAR 0: failed to assign [mem size 0x00008000 64bit]
[    1.719813] pci 0001:00:00.0: PCI bridge to [bus 01]
[    1.849735] pcie_iproc_bcma bcma0:9: PHY or data link is INACTIVE!
[    1.855938] pcie_iproc_bcma bcma0:9: no PCIe EP device detected
[    1.861884] pcie_iproc_bcma bcma0:9: PCIe controller setup failed

669cbc708122~1
[    1.208125] pcie_iproc_bcma bcma0:7: link: UP
[    1.212626] pcie_iproc_bcma bcma0:7: PCI host bridge to bus 0000:00
[    1.218951] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff]
[    1.226912] pci 0000:00:00.0: [14e4:d612] type 01 class 0x060400
[    1.232962] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.242662] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.252360] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x1c may corrupt adjacent RW1C bits
[    1.262136] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x1c may corrupt adjacent RW1C bits
[    1.271918] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.281724] pci 0000:00:00.0: PME# supported from D0 D3hot D3cold
[    1.287837] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4c may corrupt adjacent RW1C bits
[    1.298272] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.308040] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x4 may corrupt adjacent RW1C bits
[    1.317743] pci_bus 0000:00: 1-byte config write to 0000:00:00.0 offset 0xc may corrupt adjacent RW1C bits
[    1.327435] PCI: bus0: Fast back to back transfers disabled
[    1.333033] pci 0000:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.341064] pci_bus 0000:00: 2-byte config write to 0000:00:00.0 offset 0x3e may corrupt adjacent RW1C bits
[    1.350969] pci 0000:01:00.0: [14e4:4365] type 00 class 0x028000
[    1.357038] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00007fff 64bit]
[    1.363872] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x007fffff 64bit]
[    1.370703] pci 0000:01:00.0: reg 0x20: [mem 0x00000000-0x000fffff 64bit pref]
[    1.378031] pci 0000:01:00.0: supports D1 D2
[    1.408606] PCI: bus1: Fast back to back transfers disabled
[    1.414208] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    1.420891] pci_bus 0000:00: busn_res: [bus 00-ff] end is updated to 01
[    1.427540] pci 0000:00:00.0: BAR 8: no space for [mem size 0x00c00000]
[    1.434188] pci 0000:00:00.0: BAR 8: failed to assign [mem size 0x00c00000]
[    1.441180] pci 0000:00:00.0: BAR 9: no space for [mem size 0x00100000 64bit pref]
[    1.448774] pci 0000:00:00.0: BAR 9: failed to assign [mem size 0x00100000 64bit pref]
[    1.456713] pci 0000:01:00.0: BAR 2: no space for [mem size 0x00800000 64bit]
[    1.463877] pci 0000:01:00.0: BAR 2: failed to assign [mem size 0x00800000 64bit]
[    1.471386] pci 0000:01:00.0: BAR 4: no space for [mem size 0x00100000 64bit pref]
[    1.478984] pci 0000:01:00.0: BAR 4: failed to assign [mem size 0x00100000 64bit pref]
[    1.486921] pci 0000:01:00.0: BAR 0: no space for [mem size 0x00008000 64bit]
[    1.494075] pci 0000:01:00.0: BAR 0: failed to assign [mem size 0x00008000 64bit]
[    1.501581] pci 0000:00:00.0: PCI bridge to [bus 01]
[    1.618123] pcie_iproc_bcma bcma0:8: link: UP
[    1.622607] pcie_iproc_bcma bcma0:8: PCI host bridge to bus 0001:00
[    1.628926] pci_bus 0001:00: No busn resource found for root bus, will use [bus 00-ff]
[    1.636887] pci 0001:00:00.0: [14e4:d612] type 01 class 0x060400
[    1.642985] pci 0001:00:00.0: PME# supported from D0 D3hot D3cold
[    1.649708] PCI: bus0: Fast back to back transfers disabled
[    1.655304] pci 0001:00:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.663478] pci 0001:01:00.0: [14e4:4365] type 00 class 0x028000
[    1.669567] pci 0001:01:00.0: reg 0x10: [mem 0x00000000-0x00007fff 64bit]
[    1.676382] pci 0001:01:00.0: reg 0x18: [mem 0x00000000-0x007fffff 64bit]
[    1.683215] pci 0001:01:00.0: reg 0x20: [mem 0x00000000-0x000fffff 64bit pref]
[    1.690560] pci 0001:01:00.0: supports D1 D2
[    1.718605] PCI: bus1: Fast back to back transfers disabled
[    1.724202] pci_bus 0001:01: busn_res: [bus 01-ff] end is updated to 01
[    1.730884] pci_bus 0001:00: busn_res: [bus 00-ff] end is updated to 01
[    1.737533] pci 0001:00:00.0: BAR 8: no space for [mem size 0x00c00000]
[    1.744178] pci 0001:00:00.0: BAR 8: failed to assign [mem size 0x00c00000]
[    1.751172] pci 0001:00:00.0: BAR 9: no space for [mem size 0x00100000 64bit pref]
[    1.758767] pci 0001:00:00.0: BAR 9: failed to assign [mem size 0x00100000 64bit pref]
[    1.766708] pci 0001:01:00.0: BAR 2: no space for [mem size 0x00800000 64bit]
[    1.773869] pci 0001:01:00.0: BAR 2: failed to assign [mem size 0x00800000 64bit]
[    1.781378] pci 0001:01:00.0: BAR 4: no space for [mem size 0x00100000 64bit pref]
[    1.788985] pci 0001:01:00.0: BAR 4: failed to assign [mem size 0x00100000 64bit pref]
[    1.796923] pci 0001:01:00.0: BAR 0: no space for [mem size 0x00008000 64bit]
[    1.804082] pci 0001:01:00.0: BAR 0: failed to assign [mem size 0x00008000 64bit]
[    1.811593] pci 0001:00:00.0: PCI bridge to [bus 01]
[    1.928122] pcie_iproc_bcma bcma0:9: PHY or data link is INACTIVE!
[    1.934324] pcie_iproc_bcma bcma0:9: no PCIe EP device detected
[    1.940271] pcie_iproc_bcma bcma0:9: PCIe controller setup failed

669cbc708122
[    1.096377] pcie_iproc_bcma bcma0:7: host bridge /axi at 18000000/pcie at 12000 ranges:
[    1.103954] pcie_iproc_bcma bcma0:7:   No bus range found for /axi at 18000000/pcie at 12000, using [bus 00-ff]
[    1.113593] pcie_iproc_bcma: probe of bcma0:7 failed with error -12
[    1.120019] pcie_iproc_bcma bcma0:8: host bridge /axi at 18000000/pcie at 13000 ranges:
[    1.127538] pcie_iproc_bcma bcma0:8:   No bus range found for /axi at 18000000/pcie at 13000, using [bus 00-ff]
[    1.137172] pcie_iproc_bcma: probe of bcma0:8 failed with error -12
[    1.258092] pcie_iproc_bcma bcma0:9: PHY or data link is INACTIVE!
[    1.264296] pcie_iproc_bcma bcma0:9: no PCIe EP device detected
[    1.270250] pcie_iproc_bcma bcma0:9: PCIe controller setup failed


From sboyd at kernel.org  Tue Aug  3 13:16:11 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Aug 2021 13:16:11 -0700
Subject: [PATCH v1 0/6] clk: switch dividers to .determine_rate
In-Reply-To: <CAFBinCDGHdqEDv4DA4QU9T2pmMS3GMSo_tJDzya=Uhcr8Fr5Uw@mail.gmail.com>
References: <20210702225145.2643303-1-martin.blumenstingl@googlemail.com>
 <CAFBinCDGHdqEDv4DA4QU9T2pmMS3GMSo_tJDzya=Uhcr8Fr5Uw@mail.gmail.com>
Message-ID: <162802177168.3896750.7152723802271449673@swboyd.mtv.corp.google.com>

Quoting Martin Blumenstingl (2021-08-03 12:32:41)
> Hi Stephen,
> 
> 
> On Sat, Jul 3, 2021 at 12:51 AM Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
> [...]
> > Martin Blumenstingl (6):
> >   clk: divider: Implement and wire up .determine_rate by default
> >   clk: imx: clk-divider-gate: Switch to clk_divider.determine_rate
> Abel has already picked this patch (thanks!)
> 
> Can you please take the rest of the series (that is: patch 1 and patches 3-6)?
> I can also re-send them if you prefer that.
> 

No need to resend. I can pick them up.


From sboyd at kernel.org  Tue Aug  3 13:17:28 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 03 Aug 2021 13:17:28 -0700
Subject: [v14 02/21] dt-bindings: ARM: Mediatek: Add mmsys document
 binding for MT8192
In-Reply-To: <CAFqH_51D0A_Oht785cxvWjuNFYgLL25-qX1QEpLhWBARtTgVMA@mail.gmail.com>
References: <20210726105719.15793-1-chun-jie.chen@mediatek.com>
 <20210726105719.15793-3-chun-jie.chen@mediatek.com>
 <162740843452.2368309.13157283201271440368@swboyd.mtv.corp.google.com>
 <CAFqH_51D0A_Oht785cxvWjuNFYgLL25-qX1QEpLhWBARtTgVMA@mail.gmail.com>
Message-ID: <162802184879.3896750.16823365734333299735@swboyd.mtv.corp.google.com>

Quoting Enric Balletbo Serra (2021-07-28 01:47:21)
> Hi Chun-Jie and Stephen,
> 
> Missatge de Stephen Boyd <sboyd at kernel.org> del dia dt., 27 de jul.
> 2021 a les 19:54:
> >
> > Quoting Chun-Jie Chen (2021-07-26 03:57:00)
> > > This patch adds the mmsys document binding for MT8192 SoC.
> > >
> > > Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > > Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> > > Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
> > > Acked-by: Rob Herring <robh at kernel.org>
> > > ---
> >
> > Applied to clk-next
> >
> 
> This will conflict in linux-next as the binding was already converted
> to yaml. See
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml?id=63e1125e6bb8eae3cd20292f6a10ee421dd574ae
> 

Looks like it has been resolved in linux-next. Is there anything to do?


From martin.blumenstingl at googlemail.com  Tue Aug  3 13:41:08 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Tue, 3 Aug 2021 22:41:08 +0200
Subject: [PATCHv1 0/3] Add Reset controller to Ethernet PHY
In-Reply-To: <20210729201100.3994-1-linux.amoon@gmail.com>
References: <20210729201100.3994-1-linux.amoon@gmail.com>
Message-ID: <CAFBinCAPP7J-B53FCrY50oF9ttsOkkknG1NhBbL8BYZVPdkJSA@mail.gmail.com>

Hi Anand,

On Thu, Jul 29, 2021 at 10:11 PM Anand Moon <linux.amoon at gmail.com> wrote:
>
> It is being observed some time the Ethernet interface
> will not send / recive any packet after reboot.
>
> Earlier I had submitted Ethernet reset ID patch
> but it did not resolve it issue much, Adding new
> reset controller of the Ethernet PHY for Amlogic SoC
> could help resolve the issue.
nowhere in this series you are addressing the issue from [0]
Some more comments in the individual patch


Best regards,
Martin


[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64/boot/dts/amlogic?id=19f6fe976a61f9afc289b062b7ef67f99b72e7b9


From martin.blumenstingl at googlemail.com  Tue Aug  3 13:45:13 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Tue, 3 Aug 2021 22:45:13 +0200
Subject: [PATCHv1 3/3] net: stmmac: dwmac-meson8b: Add reset controller
 for ethernet phy
In-Reply-To: <20210729201100.3994-4-linux.amoon@gmail.com>
References: <20210729201100.3994-1-linux.amoon@gmail.com>
 <20210729201100.3994-4-linux.amoon@gmail.com>
Message-ID: <CAFBinCAVaaXd+jXBtA9RETP5AavOfeUVZLkU1ohGT2Lmx+H1cw@mail.gmail.com>

Hi Anand,

On Thu, Jul 29, 2021 at 10:11 PM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Add reset controller for Ethernet phy reset on every boot for
> Amlogic SoC.
I think this description does not match what's going on inside the SoC:
- for all SoCs earlier than GXL the PHY is external so the reset for
the PHY is a GPIO
- the reset line you are passing in the .dts belongs to the Ethernet
controller on SoCs earlier than GXL
- I *believe* that the rset line which you're passing in the .dts
belongs to the Ethernet controller AND the built-in MDIO mux on GXL
and newer, see also [0]
- from how the PRG_ETH registers work I doubt that these are connected
to a reset line (as they're managing mostly delays and protocol - so I
don't see what would be reset). This is speculation though.


Best regards,
Martin


[0] https://lore.kernel.org/linux-amlogic/553e127c-9839-d15b-d435-c01f18c7be48 at gmail.com/


From heiko at sntech.de  Tue Aug  3 13:47:07 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 03 Aug 2021 22:47:07 +0200
Subject: [PATCH 4/5] arm64: dts: rockchip: rk3568-evb1-v10: add pinctrl
 and alias to emmc node
In-Reply-To: <20210803185309.10013-5-michael.riesch@wolfvision.net>
References: <20210803185309.10013-1-michael.riesch@wolfvision.net>
 <20210803185309.10013-5-michael.riesch@wolfvision.net>
Message-ID: <4739137.8F6SAcFxjW@diego>

Am Dienstag, 3. August 2021, 20:53:08 CEST schrieb Michael Riesch:
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> index f3fd4a6813a2..3ac70a8183c4 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> @@ -16,6 +16,7 @@
>  	aliases {
>  		ethernet0 = &gmac0;
>  		ethernet1 = &gmac1;
> +		emmc = &sdhci;

what is this supposed to do?

I don't think "emmc" is defined as any form of alias, instead
mmc aliases generally are more "mmcX" for X 0,1,etc .

Heiko

>  	};
>  
>  	chosen: chosen {
> @@ -347,6 +348,8 @@
>  	bus-width = <8>;
>  	max-frequency = <200000000>;
>  	non-removable;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
>  	status = "okay";
>  };
>  
> 






From heiko at sntech.de  Tue Aug  3 13:48:04 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 03 Aug 2021 22:48:04 +0200
Subject: [PATCH 5/5] arm64: dts: rockchip: rk3568-evb1-v10: add node for
 sd card
In-Reply-To: <20210803185309.10013-6-michael.riesch@wolfvision.net>
References: <20210803185309.10013-1-michael.riesch@wolfvision.net>
 <20210803185309.10013-6-michael.riesch@wolfvision.net>
Message-ID: <2936848.7s5MMGUR32@diego>

Am Dienstag, 3. August 2021, 20:53:09 CEST schrieb Michael Riesch:
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> index 3ac70a8183c4..b0f5aa8c979c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> @@ -17,6 +17,7 @@
>  		ethernet0 = &gmac0;
>  		ethernet1 = &gmac1;
>  		emmc = &sdhci;
> +		sd = &sdmmc0;

same thing as in the previous patch.

I guess you may want something like

	mmc0 = &sdhci;
	mmc1 = &sdmmc0;

maybe?


Heiko

>  	};
>  
>  	chosen: chosen {
> @@ -353,6 +354,20 @@
>  	status = "okay";
>  };
>  
> +&sdmmc0 {
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
> +	disable-wp;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
> +	sd-uhs-sdr104;
> +	supports-sd;
> +	vmmc-supply = <&vcc3v3_sd>;
> +	vqmmc-supply = <&vccio_sd>;
> +	status = "okay";
> +};
> +
>  &uart2 {
>  	status = "okay";
>  };
> 






From oupton at google.com  Tue Aug  3 14:18:17 2021
From: oupton at google.com (Oliver Upton)
Date: Tue, 3 Aug 2021 14:18:17 -0700
Subject: [PATCH v5 02/13] KVM: x86: Refactor tsc synchronization code
In-Reply-To: <YQRAGSJ1PxwXA2m/@google.com>
References: <20210729173300.181775-1-oupton@google.com>
 <20210729173300.181775-3-oupton@google.com>
 <YQRAGSJ1PxwXA2m/@google.com>
Message-ID: <CAOQ_Qsiko1U4ZQPuSkxQtzxZ_PVvW7JCMoBvY06uMoNrVSjj+g@mail.gmail.com>

On Fri, Jul 30, 2021 at 11:08 AM Sean Christopherson <seanjc at google.com> wrote:
>
> On Thu, Jul 29, 2021, Oliver Upton wrote:
> > Refactor kvm_synchronize_tsc to make a new function that allows callers
> > to specify TSC parameters (offset, value, nanoseconds, etc.) explicitly
> > for the sake of participating in TSC synchronization.
> >
> > This changes the locking semantics around TSC writes.
>
> "refactor" and "changes the locking semantics" are somewhat contradictory.  The
> correct way to do this is to first change the locking semantics, then extract the
> helper you want.  That makes review and archaeology easier, and isolates the
> locking change in case it isn't so safe after all.

Indeed, it was mere laziness doing so :)

> > Writes to the TSC will now take the pvclock gtod lock while holding the tsc
> > write lock, whereas before these locks were disjoint.
> >
> > Reviewed-by: David Matlack <dmatlack at google.com>
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > ---
> > +/*
> > + * Infers attempts to synchronize the guest's tsc from host writes. Sets the
> > + * offset for the vcpu and tracks the TSC matching generation that the vcpu
> > + * participates in.
> > + *
> > + * Must hold kvm->arch.tsc_write_lock to call this function.
>
> Drop this blurb, lockdep assertions exist for a reason :-)
>

Ack.

> > + */
> > +static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc,
> > +                               u64 ns, bool matched)
> > +{
> > +     struct kvm *kvm = vcpu->kvm;
> > +     bool already_matched;
>
> Eww, not your code, but "matched" and "already_matched" are not helpful names,
> e.g. they don't provide a clue as to _what_ matched, and thus don't explain why
> there are two separate variables.  And I would expect an "already" variant to
> come in from the caller, not the other way 'round.
>
>   matched         => freq_matched
>   already_matched => gen_matched

Yeah, everything this series touches is a bit messy. I greedily
avoided the pile of cleanups that are needed, but alas...

> > +     spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags);
>
> I believe this can be spin_lock(), since AFAICT the caller _must_ disable IRQs
> when taking tsc_write_lock, i.e. we know IRQs are disabled at this point.

Definitely.


>
> > +     if (!matched) {
> > +             /*
> > +              * We split periods of matched TSC writes into generations.
> > +              * For each generation, we track the original measured
> > +              * nanosecond time, offset, and write, so if TSCs are in
> > +              * sync, we can match exact offset, and if not, we can match
> > +              * exact software computation in compute_guest_tsc()
> > +              *
> > +              * These values are tracked in kvm->arch.cur_xxx variables.
> > +              */
> > +             kvm->arch.nr_vcpus_matched_tsc = 0;
> > +             kvm->arch.cur_tsc_generation++;
> > +             kvm->arch.cur_tsc_nsec = ns;
> > +             kvm->arch.cur_tsc_write = tsc;
> > +             kvm->arch.cur_tsc_offset = offset;
>
> IMO, adjusting kvm->arch.cur_tsc_* belongs outside of pvclock_gtod_sync_lock.
> Based on the existing code, it is protected by tsc_write_lock.  I don't care
> about the extra work while holding pvclock_gtod_sync_lock, but it's very confusing
> to see code that reads variables outside of a lock, then take a lock and write
> those same variables without first rechecking.
>
> > +             matched = false;
>
> What's the point of clearing "matched"?  It's already false...

None, besides just yanking the old chunk of code :)

>
> > +     } else if (!already_matched) {
> > +             kvm->arch.nr_vcpus_matched_tsc++;
> > +     }
> > +
> > +     kvm_track_tsc_matching(vcpu);
> > +     spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags);
> > +}
> > +

--
Thanks,
Oliver


From robh at kernel.org  Tue Aug  3 15:00:39 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 16:00:39 -0600
Subject: PCI DT regressions affecting Northstar (iproc driver)
In-Reply-To: <440bd70a-81c4-357d-9fb5-1f45fca17148@gmail.com>
References: <440bd70a-81c4-357d-9fb5-1f45fca17148@gmail.com>
Message-ID: <CAL_JsqKd9Yz=pEdv7bjRcvQnio1nPJzBVxz9rexmQ-u00REQYA@mail.gmail.com>

On Tue, Aug 3, 2021 at 1:45 PM Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>
> Hi,
>
> I normally stick to LTS kernel releases and I just late-found 2
> regressions while switching from 5.4 to the 5.10.
>
> The whole thing is about Broadcom's Northstar platform and a bit quirky
> iproc PCI driver (precisely: pcie-iproc-bcma part). The iproc PCI driver
> supports both: platform device (based on DT) and bcma device.
>
> Northstar support uses a mix of DT and bcma. The later is a bus with
> EEPROM containing platform devices info. Its history is decades old and
> that design comes from pre-DT times. In any case:
> 1. Northstar PCI controllers are bcma devices with minimalistic DT nodes
> 2. Everything worked great with 5.4 and quite OK with 5.8
>
> Reference:
> * arch/arm/boot/dts/bcm5301x.dtsi
> * drivers/pci/controller/pcie-iproc-bcma.c
>
> Could you look at those problems and check if it's possible to fix them
> in some easy way (without a big refactoring) please?

I just sent some untested fixes.

Rob


From robh+dt at kernel.org  Tue Aug  3 15:18:07 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 3 Aug 2021 16:18:07 -0600
Subject: [PATCH v11 2/4] PCI: mediatek: Add new method to get shared
 pcie-cfg base address and parse node
In-Reply-To: <1626749978.2466.14.camel@mhfsdcap03>
References: <20210719073456.28666-1-chuanjia.liu@mediatek.com>
 <20210719073456.28666-3-chuanjia.liu@mediatek.com>
 <1626749978.2466.14.camel@mhfsdcap03>
Message-ID: <CAL_Jsq+DcNe8jVqisHXt3jQHeJAoLKmiah7o8ePVKra5OvAbGA@mail.gmail.com>

On Mon, Jul 19, 2021 at 8:59 PM Chuanjia Liu <chuanjia.liu at mediatek.com> wrote:
>
> On Mon, 2021-07-19 at 15:34 +0800, Chuanjia Liu wrote:
> > For the new dts format, add a new method to get
> > shared pcie-cfg base address and parse node.
> >
> > Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> > Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> > ---
> >  drivers/pci/controller/pcie-mediatek.c | 52 +++++++++++++++++++-------
> >  1 file changed, 39 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> > index 25bee693834f..928e0983a900 100644
> > --- a/drivers/pci/controller/pcie-mediatek.c
> > +++ b/drivers/pci/controller/pcie-mediatek.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/irqchip/chained_irq.h>
> >  #include <linux/irqdomain.h>
> >  #include <linux/kernel.h>
> > +#include <linux/mfd/syscon.h>
> >  #include <linux/msi.h>
> >  #include <linux/module.h>
> >  #include <linux/of_address.h>
> > @@ -23,6 +24,7 @@
> >  #include <linux/phy/phy.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_runtime.h>
> > +#include <linux/regmap.h>
> >  #include <linux/reset.h>
> >
> >  #include "../pci.h"
> > @@ -207,6 +209,7 @@ struct mtk_pcie_port {
> >   * struct mtk_pcie - PCIe host information
> >   * @dev: pointer to PCIe device
> >   * @base: IO mapped register base
> > + * @cfg: IO mapped register map for PCIe config
> >   * @free_ck: free-run reference clock
> >   * @mem: non-prefetchable memory resource
> >   * @ports: pointer to PCIe port information
> > @@ -215,6 +218,7 @@ struct mtk_pcie_port {
> >  struct mtk_pcie {
> >       struct device *dev;
> >       void __iomem *base;
> > +     struct regmap *cfg;
> >       struct clk *free_ck;
> >
> >       struct list_head ports;
> > @@ -650,7 +654,11 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
> >               return err;
> >       }
> >
> > -     port->irq = platform_get_irq(pdev, port->slot);
> > +     if (of_find_property(dev->of_node, "interrupt-names", NULL))
> > +             port->irq = platform_get_irq_byname(pdev, "pcie_irq");
> > +     else
> > +             port->irq = platform_get_irq(pdev, port->slot);
> > +
> >       if (port->irq < 0)
> >               return port->irq;
> >
> > @@ -682,6 +690,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
> >               val |= PCIE_CSR_LTSSM_EN(port->slot) |
> >                      PCIE_CSR_ASPM_L1_EN(port->slot);
> >               writel(val, pcie->base + PCIE_SYS_CFG_V2);
> > +     } else if (pcie->cfg) {
> > +             val = PCIE_CSR_LTSSM_EN(port->slot) |
> > +                   PCIE_CSR_ASPM_L1_EN(port->slot);
> > +             regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
> >       }
> >
> >       /* Assert all reset signals */
> > @@ -985,6 +997,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> >       struct device *dev = pcie->dev;
> >       struct platform_device *pdev = to_platform_device(dev);
> >       struct resource *regs;
> > +     struct device_node *cfg_node;
> >       int err;
> >
> >       /* get shared registers, which are optional */
> > @@ -995,6 +1008,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> >                       return PTR_ERR(pcie->base);
> >       }
> >
> > +     cfg_node = of_find_compatible_node(NULL, NULL,
> > +                                        "mediatek,generic-pciecfg");
> > +     if (cfg_node) {
> > +             pcie->cfg = syscon_node_to_regmap(cfg_node);
> > +             if (IS_ERR(pcie->cfg))
> > +                     return PTR_ERR(pcie->cfg);
> > +     }
> > +
> >       pcie->free_ck = devm_clk_get(dev, "free_ck");
> >       if (IS_ERR(pcie->free_ck)) {
> >               if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
> > @@ -1027,22 +1048,27 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
> >       struct device *dev = pcie->dev;
> >       struct device_node *node = dev->of_node, *child;
> >       struct mtk_pcie_port *port, *tmp;
> > -     int err;
> > +     int err, slot;
> > +
> > +     slot = of_get_pci_domain_nr(dev->of_node);
> > +     if (slot < 0) {
> > +             for_each_available_child_of_node(node, child) {
> > +                     err = of_pci_get_devfn(child);
> > +                     if (err < 0) {
> > +                             dev_err(dev, "failed to get devfn: %d\n", err);
> > +                             goto error_put_node;
> > +                     }
> >
> > -     for_each_available_child_of_node(node, child) {
> > -             int slot;
> > +                     slot = PCI_SLOT(err);
> >
> > -             err = of_pci_get_devfn(child);
> > -             if (err < 0) {
> > -                     dev_err(dev, "failed to parse devfn: %d\n", err);
> > -                     goto error_put_node;
> > +                     err = mtk_pcie_parse_port(pcie, child, slot);
> > +                     if (err)
> > +                             goto error_put_node;
> >               }
> > -
> > -             slot = PCI_SLOT(err);
> > -
> > -             err = mtk_pcie_parse_port(pcie, child, slot);
> > +     } else {
> > +             err = mtk_pcie_parse_port(pcie, node, slot);
> >               if (err)
> > -                     goto error_put_node;
> > +                     return err;
>
> Hi?Rob
> I changed this in the v9 version:
> When the new dts format is used, of_node_get() is not called.
> So when mtk_pcie_parse_port fails, of_node_put don't need to be called.
> if you still ok for this, I will add R-b in next version.

Yes, and that's small enough change to keep my R-b.

Rob


From leoyang.li at nxp.com  Tue Aug  3 15:20:25 2021
From: leoyang.li at nxp.com (Li Yang)
Date: Tue, 3 Aug 2021 17:20:25 -0500
Subject: [PATCH] arm64: dts: ls1046a: fix eeprom entries
In-Reply-To: <20210803194454.GA9471@localhost>
References: <1627927742-8675-1-git-send-email-raagjadav@gmail.com>
 <CADRPPNQ2M1N1pV2brfFRXOf1ASK2bhiZpQivNhNws_+RUfCT-g@mail.gmail.com>
 <20210803194454.GA9471@localhost>
Message-ID: <CADRPPNSbzpqs2VOV6DMUF5VP1Gx=W9-2W91Rt9ELEZxT+xsgvA@mail.gmail.com>

On Tue, Aug 3, 2021 at 2:45 PM Raag Jadav <raagjadav at gmail.com> wrote:
>
> On Mon, Aug 02, 2021 at 05:44:29PM -0500, Li Yang wrote:
> > On Mon, Aug 2, 2021 at 1:10 PM Raag Jadav <raagjadav at gmail.com> wrote:
> > >
> > > ls1046afrwy and ls1046ardb boards have CAT24C04[1] and CAT24C05[2]
> > > eeproms respectively. Both are 4Kb (512 bytes) in size.
> >
> > These part names are from onsemi instead of atmel.  Are there same
> > part names from atmel which are also compatible with the onsemi parts?
>
> The part names are different, but they are functionally compatible.
>
> >  If we want to use onsemi only part names, probably we will need two
> > compatible strings with the first one from onsemi and the second from
> > atmel.  Although the binding doesn't support onsemi prefix yet.
>
> Should I add it to the at24 binding document with atmel as a fallback?

I think that will be the best.

>
> >
> > > Remove multi-address entries, as we have auto-rollover support
> > > in at24 driver.
> >
> > The device tree should describe hardware instead of matching how
> > driver deal with it.  Is the board really using a single chip or
> > multiple chips here?
>
> Yes, both the boards have a single chip each.

Then I am fine with the change, but please make it clear in the description.

>
> >
> > >
> > > [1] https://www.onsemi.com/pdf/datasheet/cat24c01-d.pdf
> > > [2] https://www.onsemi.com/pdf/datasheet/cat24c03-d.pdf
> > >
> > > Signed-off-by: Raag Jadav <raagjadav at gmail.com>
> > > ---
> > >  arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +-------
> > >  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts  | 7 +------
> > >  2 files changed, 2 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> > > index db3d303..83afe21 100644
> > > --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> > > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> > > @@ -83,15 +83,9 @@
> > >                         };
> > >
> > >                         eeprom at 52 {
> > > -                               compatible = "atmel,24c512";
> > > +                               compatible = "atmel,24c04";
> > >                                 reg = <0x52>;
> > >                         };
> > > -
> > > -                       eeprom at 53 {
> > > -                               compatible = "atmel,24c512";
> > > -                               reg = <0x53>;
> > > -                       };
> > > -
> > >                 };
> > >         };
> > >  };
> > > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > > index 60acdf0..d220f98 100644
> > > --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> > > @@ -59,14 +59,9 @@
> > >         };
> > >
> > >         eeprom at 52 {
> > > -               compatible = "atmel,24c512";
> > > +               compatible = "atmel,24c04";
> > >                 reg = <0x52>;
> > >         };
> > > -
> > > -       eeprom at 53 {
> > > -               compatible = "atmel,24c512";
> > > -               reg = <0x53>;
> > > -       };
> > >  };
> > >
> > >  &i2c3 {
> > > --
> > > 2.7.4
> > >


From broonie at kernel.org  Tue Aug  3 15:35:29 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue,  3 Aug 2021 23:35:29 +0100
Subject: [PATCH] spi: mediatek: Fix fifo transfer
In-Reply-To: <20210802030023.1748777-1-linux@roeck-us.net>
References: <20210802030023.1748777-1-linux@roeck-us.net>
Message-ID: <162803013702.42391.66595124838577926.b4-ty@kernel.org>

On Sun, 1 Aug 2021 20:00:23 -0700, Guenter Roeck wrote:
> Commit 3a70dd2d0503 ("spi: mediatek: fix fifo rx mode") claims that
> fifo RX mode was never handled, and adds the presumably missing code
> to the FIFO transfer function. However, the claim that receive data
> was not handled is incorrect. It was handled as part of interrupt
> handling after the transfer was complete. The code added with the above
> mentioned commit reads data from the receive FIFO before the transfer
> is started, which is wrong. This results in an actual transfer error
> on a Hayato Chromebook.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: mediatek: Fix fifo transfer
      commit: 0d5c3954b35eddff0da0436c31e8d721eceb7dc2

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Tue Aug  3 15:35:30 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue,  3 Aug 2021 23:35:30 +0100
Subject: (subset) [PATCH v2 0/8] arm: ep93xx: CCF conversion
In-Reply-To: <20210726140001.24820-1-nikita.shubin@maquefel.me>
References: <20210726115058.23729-1-nikita.shubin@maquefel.me>
 <20210726140001.24820-1-nikita.shubin@maquefel.me>
Message-ID: <162803013703.42391.16928190328940334025.b4-ty@kernel.org>

On Mon, 26 Jul 2021 16:59:48 +0300, Nikita Shubin wrote:
> This series series of patches converts ep93xx to Common Clock Framework.
> 
> It consists of preparation patches to use clk_prepare_enable where it is
> needed, instead of clk_enable used in ep93xx drivers prior to CCF and
> a patch converting mach-ep93xx/clock.c to CCF.
> 
> Link: https://lore.kernel.org/patchwork/cover/1445563/
> Link: https://lore.kernel.org/patchwork/patch/1435884/
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[2/8] spi: spi-ep93xx: Prepare clock before using it
      commit: 7c72dc56a631b87043e3c5838f5094db30d8c58d

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Tue Aug  3 15:35:31 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue,  3 Aug 2021 23:35:31 +0100
Subject: [PATCH] spi: bcm2835aux: use 'unsigned int' instead of 'unsigned'
In-Reply-To: <20210731133342.432575-1-wangborong@cdjrlc.com>
References: <20210731133342.432575-1-wangborong@cdjrlc.com>
Message-ID: <162803013702.42391.3293196498865210081.b4-ty@kernel.org>

On Sat, 31 Jul 2021 21:33:42 +0800, Jason Wang wrote:
> Prefer 'unsigned int' to bare use of 'unsigned'.

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: bcm2835aux: use 'unsigned int' instead of 'unsigned'
      commit: b09bff2676be3ae286e6161a1a581a40c53a3c62

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From sudeep.holla at arm.com  Tue Aug  3 15:41:45 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 3 Aug 2021 23:41:45 +0100
Subject: [PATCH v2] cpufreq: arm_scmi: Fix error path when allocation
 failed
In-Reply-To: <20210803090744.12143-1-lukasz.luba@arm.com>
References: <20210803090744.12143-1-lukasz.luba@arm.com>
Message-ID: <20210803224145.zyr36sliwa7a67xf@bogus>

On Tue, Aug 03, 2021 at 10:07:44AM +0100, Lukasz Luba wrote:
> Stop the initialization when cpumask allocation failed and return an
> error.
>

Good catch!

Reviewed-by: Sudeep Holla <sudeep.holla at arm.com>

-- 
Regards,
Sudeep


From broonie at kernel.org  Tue Aug  3 16:22:00 2021
From: broonie at kernel.org (Mark Brown)
Date: Wed,  4 Aug 2021 00:22:00 +0100
Subject: [PATCH] ASoC: mediatek: mt6359: convert to use
 module_platform_driver
In-Reply-To: <20210531051203.228567-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210531051203.228567-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <162803121460.44131.10692737941162516565.b4-ty@kernel.org>

On Mon, 31 May 2021 14:12:03 +0900, Nobuhiro Iwamatsu wrote:
> Simplify the code by using module_platform_driver macro for
> mt6359-accdet.
> 
> 
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: mediatek: mt6359: convert to use module_platform_driver
      commit: edcade2e5e942453f001bd7a0d31f55059cec34f

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From mans0n at gorani.run  Tue Aug  3 17:14:55 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Wed, 4 Aug 2021 09:14:55 +0900
Subject: Aw: [PATCH 0/2] Add MUSB for MT7623
In-Reply-To: <trinity-0f9449b8-5114-46e5-9a4f-00b62155a938-1628010948338@3c-app-gmx-bs54>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <trinity-0f9449b8-5114-46e5-9a4f-00b62155a938-1628010948338@3c-app-gmx-bs54>
Message-ID: <f3607979-ea50-fc1c-0afe-a55881aa24f0@gorani.run>

Hi Frank,

On 2021-08-04 02:15, Frank Wunderlich wrote:
> Hi,
> 
>> Gesendet: Dienstag, 03. August 2021 um 17:13 Uhr
>> Von: "Sungbo Eo" <mans0n at gorani.run>
>> An: linux-mediatek at lists.infradead.org
>> Cc: "Chunfeng Yun" <chunfeng.yun at mediatek.com>, "Greg Kroah-Hartman" <gregkh at linuxfoundation.org>, "Rob Herring" <robh+dt at kernel.org>, "Matthias Brugger" <matthias.bgg at gmail.com>, "Min Guo" <min.guo at mediatek.com>, "Frank Wunderlich" <frank-w at public-files.de>, devicetree at vger.kernel.org, linux-usb at vger.kernel.org, linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org, "Sungbo Eo" <mans0n at gorani.run>
>> Betreff: [PATCH 0/2] Add MUSB for MT7623
>>
>> These patches add support for the MUSB controller on Mediatek MT7623.
>> Tested on Mercury RUSH-318AC Wi-Fi router.
>>
>> I got to know this from a BPI-R2 forum post [1], and managed to make it work on OpenWrt snapshot.
>> I'd like to know if this also works on BPI-R2, I can happily share the details if needed.
>> And I've just copy & pasted nodes from mt2701, please let me know if I missed some big differences between SoCs...
>>
>> [1] http://forum.banana-pi.org/t/bpi-r2-otg-port/10551
> 
> thanks for working on it. do both otg-roles (host/client) work on your device?

Yes, I tested it with host mode and device mode.
I also tried manual role-switch via sysfs and it worked with some prior setup.
Note that my device has a USB Type-A connector and not micro B, so I can't help with id pin stuff...

> 
> unfortunately at least host-mode does not work (do not know how to test client mode). i guess because iddig and vusb nodes are missing.
> 
> i took your Patchset and enabled the usb-node for bpi-r2.
> 
> +&usb3 {
> +       status = "okay";
> +};
> 
> and added these config-symbols:
> 
> +CONFIG_USB_CONN_GPIO=y
> +CONFIG_USB_MUSB_HDRC=y
> +CONFIG_USB_MUSB_MEDIATEK=y
> +CONFIG_NOP_USB_XCEIV=y
> +CONFIG_USB_CONFIGFS=y
> +#CONFIG_USB_CONFIGFS_MASS_STORAGE=y
> +#CONFIG_PHY_MTK_TPHY=y
> +CONFIG_USB_GADGET=y
> +CONFIG_USB_MUSB_DUAL_ROLE=y
> +CONFIG_USB_INVENTRA_DMA=y
> 
> btw. imho otg-node should be named usb0 as other dts (kernel 4.4) also use usb0, else i think it's confusing.

You certainly have a point. I'll follow your suggestion. Thanks!

> 
> in my last attempt i had these below usb-node in boards devicetree:
> 
> +       usb_vbus: regulator at 0 {
> +               compatible = "regulator-fixed";
> +               regulator-name = "usb_vbus";
> +               regulator-min-microvolt = <5000000>;
> +               regulator-max-microvolt = <5000000>;
> +               gpio = <&pio 237 GPIO_ACTIVE_HIGH>;
> +               enable-active-high;
> +       };
> +
> +       connector{
> +               compatible = "gpio-usb-b-connector", "usb-b-connector";
> +               type = "micro";
> +               id-gpios = <&pio 44 GPIO_ACTIVE_HIGH>;
> +               vbus-supply = <&usb_vbus>;
> +       };
> 
> after adding these i see the connection of otg-cable with usb-stick in dmesg:
> 
> [   53.656304] usb-conn-gpio 11200000.usb:connector: repeated rot
> [   53.696324] usb-conn-gpio 11200000.usb:connector: repeated role: host
> 
> but usb-stick is not powered (led of the stick is off) and of course i see no mass-storage device.

I observed the same symptom (but different error log).

[    2.722253] musb-hdrc musb-hdrc.1.auto: VBUS_ERROR in a_idle (80, <SessEnd), retry #0, port1 00000104

In my case adding `regulator-always-on;` in the regulator node solved the problem temporarily.
But after that I switched to relying on pinctrl.

+&pio {
+       musb_pins: musb {
+               pins-musb {
+                       pinmux = <MT7623_PIN_237_EXT_SDIO2_FUNC_DRV_VBUS>;
+               };
+       };
+};
+
+&usb3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&musb_pins>;
+       status = "okay";
+
+       dr_mode = "host";
+
+       connector {
+               compatible = "usb-a-connector";
+       };
+};

root at OpenWrt:~# lsusb -t
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=, Driver=usb-storage, 480M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci-mtk/1p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci-mtk/1p, 480M

I tested device mode with legacy CDC composite device module.
You can also take more complicated configfs approach, though.
https://elinux.org/images/e/ef/USB_Gadget_Configfs_API_0.pdf

+       dr_mode = "host";
-       dr_mode = "peripheral";

root at OpenWrt:/# insmod g_cdc
[   64.565254] using random self ethernet address
[   64.569711] using random host ethernet address
[   64.575966] usb0: HOST MAC 26:36:2d:e5:8f:6f
[   64.580501] usb0: MAC 92:d7:f9:c7:88:01
[   64.584409] g_cdc gadget: CDC Composite Gadget, version: King Kamehameha Day 2008
[   64.592454] g_cdc gadget: g_cdc ready

I also tried usb-role-switch,

-       dr_mode = "host";
+       usb-role-switch;

After boot the initial mode of musb is "none", and it did not turn vbus on even if I set it to host mode.
Later I found out that I need to load any gadget driver before setting it to host mode.

# echo peripheral > /sys/devices/platform/11200000.usb/musb-hdrc.1.auto/mode
# insmod g_cdc
# echo host > /sys/devices/platform/11200000.usb/musb-hdrc.1.auto/mode

That's all I know. Please let me know if I skipped some details.
Thanks.

> 
> and now i'm back on the traceback on power down i've reported Author of musb driver some time ago
> 
> [  156.785185] WARNING: CPU: 0 PID: 1 at drivers/power/reset/mt6323-poweroff.c:4
> [  156.795156] Unable to power off system
> 
> [  156.884496] [<c0cca1ec>] (warn_slowpath_fmt) from [<c090562c>] (mt6323_do_pw)
> [  156.893203]  r8:c3296d40 r7:00000024 r6:0ccccb60 r5:c10fe3d8 r4:00000000
> [  156.900030] [<c09054b0>] (mt6323_do_pwroff) from [<c010ba68>] (machine_power)
> [  156.908558]  r8:fee1dead r7:c1312590 r6:92f61d00 r5:00000000 r4:4321fedc
> [  156.915385] [<c010ba34>] (machine_power_off) from [<c01524bc>] (kernel_power)
> 
> i guess it's related to the usb_vbus.
> 
> regards Frank
> 


From palmerdabbelt at google.com  Tue Aug  3 17:20:00 2021
From: palmerdabbelt at google.com (Palmer Dabbelt)
Date: Tue, 03 Aug 2021 17:20:00 -0700 (PDT)
Subject: [PATCH v2] lib: Use PFN_PHYS() in devmem_is_allowed()
In-Reply-To: <12e37243-0cdb-6765-c3ef-c98fd291591c@huawei.com>
Message-ID: <mhng-e101fb5a-2f16-45a0-8436-454ac2bf4223@palmerdabbelt-glaptop>

On Fri, 30 Jul 2021 00:04:05 PDT (-0700), wangkefeng.wang at huawei.com wrote:
>
> On 2021/7/30 14:49, Liang Wang wrote:
>> The physical address may exceed 32 bits on ARM(when ARM_LPAE enabled),
>> use PFN_PHYS() in devmem_is_allowed(), or the physical address may
>> overflow and be truncated.
>>
>> This bug was initially introduced from v2.6.37, and the function was moved
>> to lib when v5.10.
>>
>> Fixes: 087aaffcdf9c ("ARM: implement CONFIG_STRICT_DEVMEM by disabling access to RAM via /dev/mem")
>> Fixes: 527701eda5f1 ("lib: Add a generic version of devmem_is_allowed()")
>> Cc: stable at vger.kernel.org # v2.6.37
>> Signed-off-by: Liang Wang <wangliang101 at huawei.com>
> Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>> ---
>> v2: update subject and changelog
>>   lib/devmem_is_allowed.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/lib/devmem_is_allowed.c b/lib/devmem_is_allowed.c
>> index c0d67c541849..60be9e24bd57 100644
>> --- a/lib/devmem_is_allowed.c
>> +++ b/lib/devmem_is_allowed.c
>> @@ -19,7 +19,7 @@
>>    */
>>   int devmem_is_allowed(unsigned long pfn)
>>   {
>> -	if (iomem_is_exclusive(pfn << PAGE_SHIFT))
>> +	if (iomem_is_exclusive(PFN_PHYS(pfn)))
>>   		return 0;
>>   	if (!page_is_ram(pfn))
>>   		return 1;

Acked-by: Palmer Dabbelt <palmerdabbelt at google.com>

I only see the reply so I'm assuming this is going in through some other 
tree, but LMK if you want it via the RISC-V tree as IIRC we're using it 
too.

Thanks!


From lkp at intel.com  Tue Aug  3 17:55:00 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 04 Aug 2021 08:55:00 +0800
Subject: [nomadik:ixp4xx-gorano-hss] BUILD SUCCESS
 76e4e0999f99da11495214dc9ee7a96a788c3c2f
Message-ID: <6109e564.LctfISvlFtrrF4UH%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-gorano-hss
branch HEAD: 76e4e0999f99da11495214dc9ee7a96a788c3c2f  RFC: ARM: dts: Proposed Goramo MultiLink device tree

elapsed time: 727m

configs tested: 124
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210803
powerpc                 xes_mpc85xx_defconfig
arm                         s3c6400_defconfig
arm                            xcep_defconfig
arm                         vf610m4_defconfig
ia64                             alldefconfig
powerpc                     tqm8541_defconfig
nios2                         3c120_defconfig
arm                            pleb_defconfig
powerpc                     pseries_defconfig
arm                        trizeps4_defconfig
arm                          imote2_defconfig
powerpc                 mpc8313_rdb_defconfig
mips                          ath25_defconfig
mips                           ci20_defconfig
powerpc                   bluestone_defconfig
mips                          rm200_defconfig
powerpc                      ppc64e_defconfig
powerpc                      ppc6xx_defconfig
sh                     sh7710voipgw_defconfig
powerpc                           allnoconfig
powerpc                 mpc8540_ads_defconfig
powerpc                       ebony_defconfig
powerpc                      bamboo_defconfig
powerpc                     kilauea_defconfig
mips                        bcm63xx_defconfig
powerpc                 mpc8315_rdb_defconfig
m68k                        mvme16x_defconfig
mips                       rbtx49xx_defconfig
powerpc                     ksi8560_defconfig
xtensa                generic_kc705_defconfig
mips                           ip27_defconfig
powerpc64                           defconfig
arm                           sama5_defconfig
sh                          sdk7786_defconfig
arc                    vdk_hs38_smp_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a004-20210802
i386                 randconfig-a005-20210802
i386                 randconfig-a002-20210802
i386                 randconfig-a006-20210802
i386                 randconfig-a001-20210802
i386                 randconfig-a003-20210802
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210803
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug  3 17:54:57 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 04 Aug 2021 08:54:57 +0800
Subject: [nomadik:ux500-reset-controller] BUILD SUCCESS
 a37cdb0fd38ca845b7a5d2253506456296cafaa4
Message-ID: <6109e561.k/WK8FlUKhBw8/D2%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-reset-controller
branch HEAD: a37cdb0fd38ca845b7a5d2253506456296cafaa4  ARM: dts: ux500: Add reset capability to Samsung phones

elapsed time: 726m

configs tested: 143
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210803
mips                           ip28_defconfig
arm                        cerfcube_defconfig
arm                        neponset_defconfig
arc                        nsimosci_defconfig
arm                         hackkit_defconfig
powerpc                      obs600_defconfig
m68k                          atari_defconfig
mips                           rs90_defconfig
mips                        jmr3927_defconfig
mips                           ip32_defconfig
powerpc                     tqm8541_defconfig
nios2                         3c120_defconfig
arm                            pleb_defconfig
powerpc                     pseries_defconfig
arm                        trizeps4_defconfig
arm                          imote2_defconfig
arm                            dove_defconfig
h8300                            alldefconfig
sh                           se7619_defconfig
powerpc                   bluestone_defconfig
mips                          rm200_defconfig
powerpc                      ppc64e_defconfig
powerpc                      ppc6xx_defconfig
sh                     sh7710voipgw_defconfig
powerpc                           allnoconfig
x86_64                           alldefconfig
powerpc                     mpc512x_defconfig
openrisc                 simple_smp_defconfig
powerpc                     ppa8548_defconfig
s390                             alldefconfig
sh                           se7343_defconfig
h8300                    h8300h-sim_defconfig
ia64                      gensparse_defconfig
sh                        apsh4ad0a_defconfig
mips                          rb532_defconfig
arc                          axs103_defconfig
sh                           se7722_defconfig
arm                         socfpga_defconfig
mips                         db1xxx_defconfig
powerpc                   lite5200b_defconfig
arm                           omap1_defconfig
sparc                       sparc32_defconfig
powerpc                 mpc8540_ads_defconfig
powerpc                       ebony_defconfig
powerpc                      bamboo_defconfig
powerpc                     kilauea_defconfig
mips                        bcm63xx_defconfig
powerpc                 mpc8315_rdb_defconfig
xtensa                generic_kc705_defconfig
mips                           ip27_defconfig
powerpc64                           defconfig
arm                           sama5_defconfig
sh                          sdk7786_defconfig
arc                    vdk_hs38_smp_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a004-20210802
i386                 randconfig-a005-20210802
i386                 randconfig-a002-20210802
i386                 randconfig-a006-20210802
i386                 randconfig-a001-20210802
i386                 randconfig-a003-20210802
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210803
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug  3 17:55:05 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 04 Aug 2021 08:55:05 +0800
Subject: [nomadik:ux500-cleanups] BUILD SUCCESS
 d40fb5e5094f1b8b90ff660cb37161713784735a
Message-ID: <6109e569.DmzcF0kJj5MSFo+4%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-cleanups
branch HEAD: d40fb5e5094f1b8b90ff660cb37161713784735a  watchdog: db8500_wdt: Rename symbols

elapsed time: 727m

configs tested: 117
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210803
powerpc                     tqm8541_defconfig
nios2                         3c120_defconfig
arm                            pleb_defconfig
powerpc                     pseries_defconfig
arm                        trizeps4_defconfig
arm                          imote2_defconfig
arm                            dove_defconfig
h8300                            alldefconfig
sh                           se7619_defconfig
powerpc                   bluestone_defconfig
mips                          rm200_defconfig
powerpc                      ppc64e_defconfig
powerpc                      ppc6xx_defconfig
sh                     sh7710voipgw_defconfig
powerpc                           allnoconfig
mips                  cavium_octeon_defconfig
mips                     decstation_defconfig
mips                         bigsur_defconfig
sh                             espt_defconfig
sh                            shmin_defconfig
powerpc                 mpc8540_ads_defconfig
powerpc                       ebony_defconfig
powerpc                      bamboo_defconfig
powerpc                     kilauea_defconfig
mips                        bcm63xx_defconfig
powerpc                 mpc8315_rdb_defconfig
xtensa                generic_kc705_defconfig
mips                           ip27_defconfig
powerpc64                           defconfig
arm                           sama5_defconfig
sh                          sdk7786_defconfig
arc                    vdk_hs38_smp_defconfig
s390                             allyesconfig
powerpc                       holly_defconfig
powerpc                        warp_defconfig
powerpc                     stx_gp3_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a004-20210802
i386                 randconfig-a005-20210802
i386                 randconfig-a002-20210802
i386                 randconfig-a006-20210802
i386                 randconfig-a001-20210802
i386                 randconfig-a003-20210802
x86_64               randconfig-a012-20210802
x86_64               randconfig-a016-20210802
x86_64               randconfig-a013-20210802
x86_64               randconfig-a011-20210802
x86_64               randconfig-a014-20210802
x86_64               randconfig-a015-20210802
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug  3 17:55:02 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 04 Aug 2021 08:55:02 +0800
Subject: [nomadik:ixp4xx-net-arnd] BUILD SUCCESS
 b9ce474cc7758470da9d124fda8982ebe8d9fe5d
Message-ID: <6109e566.11FmyV8uTCGyUNZO%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-net-arnd
branch HEAD: b9ce474cc7758470da9d124fda8982ebe8d9fe5d  ARM: dts: Add PTP timesource to the IXP456x

elapsed time: 727m

configs tested: 137
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210803
powerpc                     tqm8541_defconfig
nios2                         3c120_defconfig
arm                            pleb_defconfig
powerpc                     pseries_defconfig
arm                        trizeps4_defconfig
arm                          imote2_defconfig
arm                            dove_defconfig
h8300                            alldefconfig
sh                           se7619_defconfig
powerpc                 mpc8313_rdb_defconfig
mips                          ath25_defconfig
mips                           ci20_defconfig
powerpc                   bluestone_defconfig
mips                          rm200_defconfig
powerpc                      ppc64e_defconfig
powerpc                      ppc6xx_defconfig
sh                     sh7710voipgw_defconfig
powerpc                           allnoconfig
mips                  cavium_octeon_defconfig
mips                     decstation_defconfig
mips                         bigsur_defconfig
sh                             espt_defconfig
sh                            shmin_defconfig
powerpc                 mpc8540_ads_defconfig
powerpc                       ebony_defconfig
powerpc                      bamboo_defconfig
powerpc                     kilauea_defconfig
mips                        bcm63xx_defconfig
powerpc                 mpc8315_rdb_defconfig
powerpc                 xes_mpc85xx_defconfig
m68k                        mvme16x_defconfig
mips                       rbtx49xx_defconfig
powerpc                     ksi8560_defconfig
xtensa                generic_kc705_defconfig
mips                           ip27_defconfig
powerpc64                           defconfig
arm                           sama5_defconfig
sh                          sdk7786_defconfig
arc                    vdk_hs38_smp_defconfig
s390                             allyesconfig
powerpc                       holly_defconfig
powerpc                        warp_defconfig
powerpc                     stx_gp3_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a004-20210802
i386                 randconfig-a005-20210802
i386                 randconfig-a002-20210802
i386                 randconfig-a006-20210802
i386                 randconfig-a001-20210802
i386                 randconfig-a003-20210802
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
x86_64               randconfig-a012-20210802
x86_64               randconfig-a016-20210802
x86_64               randconfig-a013-20210802
x86_64               randconfig-a011-20210802
x86_64               randconfig-a014-20210802
x86_64               randconfig-a015-20210802
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210803
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug  3 17:55:07 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 04 Aug 2021 08:55:07 +0800
Subject: [nomadik:ixp4xx-cleanup-v5.14-rc1] BUILD SUCCESS
 9d01d459fb5ae06a8e307f9241d1837894418472
Message-ID: <6109e56b.2gJoevbjeX1KmgmQ%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-cleanup-v5.14-rc1
branch HEAD: 9d01d459fb5ae06a8e307f9241d1837894418472   watchdog: ixp4xx: Implement restart

elapsed time: 727m

configs tested: 115
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210803
mips                           ip28_defconfig
arm                        cerfcube_defconfig
arm                        neponset_defconfig
arc                        nsimosci_defconfig
arm                         hackkit_defconfig
powerpc                      obs600_defconfig
m68k                          atari_defconfig
mips                           rs90_defconfig
mips                        jmr3927_defconfig
mips                           ip32_defconfig
arm                            dove_defconfig
h8300                            alldefconfig
sh                           se7619_defconfig
x86_64                           alldefconfig
powerpc                     mpc512x_defconfig
openrisc                 simple_smp_defconfig
powerpc                     ppa8548_defconfig
powerpc                      ppc64e_defconfig
s390                             alldefconfig
sh                           se7343_defconfig
h8300                    h8300h-sim_defconfig
ia64                      gensparse_defconfig
sh                        apsh4ad0a_defconfig
mips                          rb532_defconfig
arc                          axs103_defconfig
sh                           se7722_defconfig
arm                         socfpga_defconfig
mips                         db1xxx_defconfig
powerpc                   lite5200b_defconfig
arm                           omap1_defconfig
sparc                       sparc32_defconfig
powerpc                 mpc8540_ads_defconfig
powerpc                       ebony_defconfig
powerpc                      bamboo_defconfig
powerpc                     kilauea_defconfig
mips                        bcm63xx_defconfig
powerpc                 mpc8315_rdb_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210803
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug  3 17:55:09 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 04 Aug 2021 08:55:09 +0800
Subject: [nomadik:ux500-dts-for-v5.15] BUILD SUCCESS
 fe2fc0fd379371af510caf39181460f2eed4c35b
Message-ID: <6109e56d.REKL72kbJG2VR4T1%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-dts-for-v5.15
branch HEAD: fe2fc0fd379371af510caf39181460f2eed4c35b  ARM: dts: ux500: Adjust operating points to reality

elapsed time: 727m

configs tested: 76
configs skipped: 97

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
powerpc                 xes_mpc85xx_defconfig
arm                         s3c6400_defconfig
arm                            xcep_defconfig
arm                         vf610m4_defconfig
ia64                             alldefconfig
powerpc                 mpc8313_rdb_defconfig
mips                          ath25_defconfig
mips                           ci20_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From saravanak at google.com  Tue Aug  3 18:36:45 2021
From: saravanak at google.com (Saravana Kannan)
Date: Tue, 3 Aug 2021 18:36:45 -0700
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <87im0m277h.wl-maz@kernel.org>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
Message-ID: <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>

On Tue, Aug 3, 2021 at 2:44 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 14 Jun 2021 23:30:22 +0100,
> Kevin Hilman <khilman at baylibre.com> wrote:
> >
> > Marc Zyngier <maz at kernel.org> writes:
> >
> > > On Fri, 21 May 2021 10:47:48 +0100,
> > > Lee Jones <lee.jones at linaro.org> wrote:
> > >>
> > >> [1  <text/plain; UTF-8 (quoted-printable)>]
> > >> On Tue, 20 Oct 2020 at 19:23, Kevin Hilman <khilman at baylibre.com> wrote:
> > >>
> > >> > Neil Armstrong <narmstrong at baylibre.com> writes:
> > >> >
> > >> > > In order to reduce the kernel Image size on multi-platform distributions,
> > >> > > make it possible to build the Amlogic GPIO IRQ controller as a module
> > >> > > by switching it to a platform driver.
> > >> > >
> > >> > > Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> > >> >
> > >> > Reviewed-by: Kevin Hilman <khilman at baylibre.com>
> > >> > Tested-by: Kevin Hilman <khilman at baylibre.com>
> > >> >
> > >> > Tested as a module on meson-sm1-khadas-vim3l where the wired networking
> > >> > uses GPIO IRQs.
> > >> >
> > >>
> > >> Good morning Neil, Kevin,
> > >>
> > >> What happened to this set in the end?  I still don't see it in Mainline.
> > >
> > > Last time I tried this patch, it broke my test setup in non-obvious
> > > ways. Has someone checked that the issue I reported back then has been
> > > resolved now that fw_devlink is more usable?
> >
> > OK, after much anticipation (and much delay due to me forgetting about
> > this), I just gave this series a spin again on top of v5.13-rc6, and it
> > seems to work fine with `fw_devlink=on`
> >
> > I started with your config[1] and accepting all the defaults of any new
> > configs.  IOW, I ran: yes '' | make oldconfig after copying your config
> > to .config.
> >
> > With that it seems to be working fine for me.
> >
> > Right after boot (and before network probes) I see module loaded, but no
> > users yet in /proc/interrupts:
> >
> > / # uname -a
> > Linux buildroot 5.13.0-rc6-00002-g679c8e852942 #5 SMP PREEMPT Mon Jun 14 15:08:40 PDT 2021 aarch64 GNU/Linux
> > / # lsmod |grep gpio
> > irq_meson_gpio         20480  0
> > leds_gpio              16384  0
> > / # cat /proc/interrupts
> >            CPU0       CPU1       CPU2       CPU3
> >   9:          0          0          0          0     GICv2  25 Level     vgic
> >  11:          0          0          0          0     GICv2  30 Level     kvm guest ptimer
> >  12:          0          0          0          0     GICv2  27 Level     kvm guest vtimer
> >  13:       1416        916        534       1421     GICv2  26 Level     arch_timer
> >  15:          5          0          0          0     GICv2  89 Edge      dw_hdmi_top_irq, ff600000.hdmi-tx
> >  22:         38          0          0          0     GICv2 225 Edge      ttyAML0
> >  23:         20          0          0          0     GICv2 227 Edge      ff805000.i2c
> >  25:          2          0          0          0     GICv2 232 Edge      ff809000.adc
> >  28:        322          0          0          0     GICv2  35 Edge      meson
> >  31:          0          0          0          0     GICv2 222 Edge      ffe05000.sd
> >  32:        787          0          0          0     GICv2 223 Edge      ffe07000.mmc
> >  34:          0          0          0          0     GICv2 194 Level     panfrost-job
> >  35:          0          0          0          0     GICv2 193 Level     panfrost-mmu
> >  36:          3          0          0          0     GICv2 192 Level     panfrost-gpu
> >  39:          0          0          0          0     GICv2  63 Level     ff400000.usb, ff400000.usb
> >  40:         32          0          0          0     GICv2  62 Level     xhci-hcd:usb1
> > IPI0:       425        544        664        925       Rescheduling interrupts
> > IPI1:        86        166        269        136       Function call interrupts
> > IPI2:         0          0          0          0       CPU stop interrupts
> > IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
> > IPI4:         0          0          0          0       Timer broadcast interrupts
> > IPI5:         0          0          0          0       IRQ work interrupts
> > IPI6:         0          0          0          0       CPU wake-up interrupts
> > Err:          0
> >
> > So then I init the network interface and PHY works, DHCP works etc.
> >
> > / # udhcpc
> > udhcpc: started, v1.31.1
> > [  102.250449] meson8b-dwmac ff3f0000.ethernet eth0: PHY [0.0:00] driver [RTL8211F Gigabit Ethernet] (irq=37)
> > [  102.256413] meson8b-dwmac ff3f0000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
> > [  102.269433] meson8b-dwmac ff3f0000.ethernet eth0: No Safety Features support found
> > [  102.271357] meson8b-dwmac ff3f0000.ethernet eth0: PTP not supported by HW
> > [  102.278493] meson8b-dwmac ff3f0000.ethernet eth0: configuring for phy/rgmii link mode
> > udhcpc: sending discover
> > [  104.743301] meson8b-dwmac ff3f0000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
> > [  104.746470] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
> > udhcpc: sending discover
> > udhcpc: sending select for 192.168.0.122
> > udhcpc: lease of 192.168.0.122 obtained, lease time 600
> > deleting routers
> > adding dns 192.168.0.254
> > adding dns 192.168.0.254
> > / # cat /proc/interrupts
> >            CPU0       CPU1       CPU2       CPU3
> >   9:          0          0          0          0     GICv2  25 Level     vgic
> >  11:          0          0          0          0     GICv2  30 Level     kvm guest ptimer
> >  12:          0          0          0          0     GICv2  27 Level     kvm guest vtimer
> >  13:       1575       1018        604       1588     GICv2  26 Level     arch_timer
> >  14:          8          0          0          0     GICv2  40 Level     eth0
> >  15:          5          0          0          0     GICv2  89 Edge      dw_hdmi_top_irq, ff600000.hdmi-tx
> >  22:        132          0          0          0     GICv2 225 Edge      ttyAML0
> >  23:         20          0          0          0     GICv2 227 Edge      ff805000.i2c
> >  25:          2          0          0          0     GICv2 232 Edge      ff809000.adc
> >  28:        322          0          0          0     GICv2  35 Edge      meson
> >  31:          0          0          0          0     GICv2 222 Edge      ffe05000.sd
> >  32:        787          0          0          0     GICv2 223 Edge      ffe07000.mmc
> >  34:          0          0          0          0     GICv2 194 Level     panfrost-job
> >  35:          0          0          0          0     GICv2 193 Level     panfrost-mmu
> >  36:          3          0          0          0     GICv2 192 Level     panfrost-gpu
> >  37:          2          0          0          0  meson-gpio-irqchip  26 Level     0.0:00
> >  39:          0          0          0          0     GICv2  63 Level     ff400000.usb, ff400000.usb
> >  40:         32          0          0          0     GICv2  62 Level     xhci-hcd:usb1
> > IPI0:       476        567        720        956       Rescheduling interrupts
> > IPI1:        93        166        270        137       Function call interrupts
> > IPI2:         0          0          0          0       CPU stop interrupts
> > IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
> > IPI4:         0          0          0          0       Timer broadcast interrupts
> > IPI5:         0          0          0          0       IRQ work interrupts
> > IPI6:         0          0          0          0       CPU wake-up interrupts
> > Err:          0
> > / #
>
> This thing keeps failing on my end. It only works if I force the
> irqchip module to be present before the MDIO module is loaded. Here's
> an example:
>
> root at tiger-roach:~# modprobe mdio_mux_meson_g12a
> [  125.871544] libphy: mdio_mux: probed
> [  125.882575] g12a-mdio_mux ff64c000.mdio-multiplexer: Error: Failed to register MDIO bus for child /soc/bus at ff600000/mdio-multiplexer at 4c000/mdio at 0
> [  125.892630] libphy: mdio_mux: probed
>
> Trying to bring up the Ethernet interface will fail. Note that there
> was no attempt to load the irqchip driver.
>
> root at tiger-roach:~# modprobe -r mdio_mux_meson_g12a
> root at tiger-roach:~# modprobe irq-meson-gpio
> [  144.983344] meson-gpio-intc ffd0f080.interrupt-controller: 100 to 8 gpio interrupt mux initialized
> root at tiger-roach:~# modprobe mdio_mux_meson_g12a
> [  150.376464] libphy: mdio_mux: probed
> [  150.391039] libphy: mdio_mux: probed
>
> And it now works.
>
> Is it a MDIO issue? a fw_devlink issue? No idea. But I'd really like
> to see this addressed before taking this patch, as everything works
> just fine as long as the irqchip is built in (which on its own could
> well pure luck).
>
> Saravana, could you please have a look from a fw_devlink perspective?

Sigh... I spent several hours looking at this and wrote up an analysis
and then realized I might be looking at the wrong DT files.

Marc, can you point me to the board file in upstream that corresponds
to the platform in which you see this issue? I'm not asking for [1],
but the actual final .dts (not .dtsi) file that corresponds to the
platform/board/system.

Based on your error messages, it's failing for mdio at 0 which
corresponds to ext_mdio. But none of the board dts files in upstream
have a compatible property for "ext_mdio". Which means fw_devlink
_should_ propagate the gpio_intc IRQ dependency all the way up to
eth_phy.

Also, in the failing case, can you run:
ls -ld supplier:*

in the /sys/devices/....<something>/ folder that corresponds to the
"eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?

Thanks,
Saravana

[1] - arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi


From saravanak at google.com  Tue Aug  3 19:11:58 2021
From: saravanak at google.com (Saravana Kannan)
Date: Tue, 3 Aug 2021 19:11:58 -0700
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <87h7g626wg.wl-maz@kernel.org>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org> <87h7g626wg.wl-maz@kernel.org>
Message-ID: <CAGETcx-XEJ25SvUO92wVyqjna+=CU6UTSQKqDimy008z0afA1g@mail.gmail.com>

On Tue, Aug 3, 2021 at 2:51 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Tue, 03 Aug 2021 10:44:34 +0100,
> Marc Zyngier <maz at kernel.org> wrote:
>
> [...]
>
> > This thing keeps failing on my end. It only works if I force the
> > irqchip module to be present before the MDIO module is loaded. Here's
> > an example:
> >
> > root at tiger-roach:~# modprobe mdio_mux_meson_g12a
> > [  125.871544] libphy: mdio_mux: probed
> > [  125.882575] g12a-mdio_mux ff64c000.mdio-multiplexer: Error: Failed to register MDIO bus for child /soc/bus at ff600000/mdio-multiplexer at 4c000/mdio at 0
> > [  125.892630] libphy: mdio_mux: probed
> >
> > Trying to bring up the Ethernet interface will fail. Note that there
> > was no attempt to load the irqchip driver.
> >
> > root at tiger-roach:~# modprobe -r mdio_mux_meson_g12a
> > root at tiger-roach:~# modprobe irq-meson-gpio
> > [  144.983344] meson-gpio-intc ffd0f080.interrupt-controller: 100 to 8 gpio interrupt mux initialized
> > root at tiger-roach:~# modprobe mdio_mux_meson_g12a
> > [  150.376464] libphy: mdio_mux: probed
> > [  150.391039] libphy: mdio_mux: probed
> >
> > And it now works.
>
> An additional source of amusement is that this patch allows the
> irqchip to be removed from the kernel. It becomes really fun when you
> have live interrupts...

Which is why I wrote IRQCHIP_PLATFORM_DRIVER_BEGIN/END macros. Maybe
those should be used instead?

-Saravana

[1] - https://lore.kernel.org/lkml/20200718000637.3632841-2-saravanak at google.com/


From alim.akhtar at samsung.com  Mon Aug  2 20:25:39 2021
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue,  3 Aug 2021 08:55:39 +0530
Subject: [PATCH v11] dt-bindings: ufs: Add bindings for Samsung ufs host
References: <CGME20210803032734epcas5p2143008ddb212fe53fcd28b813c85c9d8@epcas5p2.samsung.com>
Message-ID: <20210803032539.15676-1-alim.akhtar@samsung.com>

This patch adds DT bindings for Samsung ufs hci

Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
Changes since v10
* Rebased on v5.14-rc2 
* removed Rob Herring earlier Reviewed-by tag

This patch was part of exynos ufs driver series, somehow
this got missed to applied on the tree, sending again as a new
patch v11, removing Rob's earlier Reviewed-by tag.

 .../bindings/ufs/samsung,exynos-ufs.yaml      | 89 +++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml

diff --git a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
new file mode 100644
index 000000000000..38193975c9f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ufs/samsung,exynos-ufs.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung SoC series UFS host controller Device Tree Bindings
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+
+description: |
+  Each Samsung UFS host controller instance should have its own node.
+  This binding define Samsung specific binding other then what is used
+  in the common ufshcd bindings
+  [1] Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
+
+properties:
+
+  compatible:
+    enum:
+      - samsung,exynos7-ufs
+
+  reg:
+    items:
+     - description: HCI register
+     - description: vendor specific register
+     - description: unipro register
+     - description: UFS protector register
+
+  reg-names:
+    items:
+      - const: hci
+      - const: vs_hci
+      - const: unipro
+      - const: ufsp
+
+  clocks:
+    items:
+      - description: ufs link core clock
+      - description: unipro main clock
+
+  clock-names:
+    items:
+      - const: core_clk
+      - const: sclk_unipro_main
+
+  interrupts:
+    maxItems: 1
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: ufs-phy
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - phys
+  - phy-names
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/exynos7-clk.h>
+
+    ufs: ufs at 15570000 {
+       compatible = "samsung,exynos7-ufs";
+       reg = <0x15570000 0x100>,
+             <0x15570100 0x100>,
+             <0x15571000 0x200>,
+             <0x15572000 0x300>;
+       reg-names = "hci", "vs_hci", "unipro", "ufsp";
+       interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+       clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
+                <&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
+       clock-names = "core_clk", "sclk_unipro_main";
+       pinctrl-names = "default";
+       pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
+       phys = <&ufs_phy>;
+       phy-names = "ufs-phy";
+    };
+...

base-commit: 2734d6c1b1a089fb593ef6a23d4b70903526fe0c
-- 
2.17.1



From anshuman.khandual at arm.com  Tue Aug  3 20:46:33 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 4 Aug 2021 09:16:33 +0530
Subject: [PATCH] arm64/mm: Fix idmap on [16K|36VA|48PA]
In-Reply-To: <20210803131201.GB5786@arm.com>
References: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com>
 <20210803103440.GA5786@arm.com>
 <7bad50a2-76f1-7946-3a15-35e46fb289c0@arm.com>
 <20210803131201.GB5786@arm.com>
Message-ID: <4d6a4a0c-7f68-991d-5b0e-08c280543fe8@arm.com>



On 8/3/21 6:42 PM, Catalin Marinas wrote:
> On Tue, Aug 03, 2021 at 04:57:04PM +0530, Anshuman Khandual wrote:
>> On 8/3/21 4:04 PM, Catalin Marinas wrote:
>>> On Mon, Aug 02, 2021 at 10:12:39AM +0530, Anshuman Khandual wrote:
>>>> +/*
>>>> + * In this particular CONFIG_ARM64_16K_PAGES config, there might be a
>>>> + * scenario where 'idmap_text_end' ends up high enough in the PA range
>>>> + * requiring two additional idmap page table levels. Reduce idmap_t0sz
>>>> + * to cover the entire PA range. This prevents table misconfiguration
>>>> + * when a given idmap_t0sz value just requires single additional level
>>>> + * where as two levels have been built.
>>>> + */
>>>> +#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_PA_BITS_48)
> 
> I don't think you need the PA_BITS_48 check in here. It's either this
> one or PA_BITS_52 in the future. Anyway, I think so far our assumption

Even PA_BITS_52 range will be well within the two extra idmap page table
levels limit, so it should be covered with this proposed code.

> is that the kernel will always be placed in the first 48-bit, so we
> don't need extra check.

The check on ARM64_PA_BITS_48 here is a code hardening construct. Because
(PAGE_SHIFT - 3) is an important factor which ends up pushing the idmap to
have two extra levels. Could we just assert ARM64_16K_PAGES instead, along
with ARM64_VA_BITS_36 ? I am concerned because in future other page size
configs might have ARM64_VA_BITS_36 as well.

Something like ...

#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_16K_PAGES)

> 
>>>> +	mov	x4, EXTRA_PTRS_1
>>>> +	create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6
>>>> +
>>>> +	mov	x4, PTRS_PER_PTE
>>>> +	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
>>>> +
>>>> +	mov	x5, #64 - PHYS_MASK_SHIFT
>>>> +	adr_l	x6, idmap_t0sz
>>>> +	str	x5, [x6]
>>>> +	dmb	sy
>>>> +	dc	ivac, x6
>>>> +#else
>>>>  	mov	x4, EXTRA_PTRS
>>>>  	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
>>>> +#endif
>>>>  #else
>>>>  	/*
>>>>  	 * If VA_BITS == 48, we don't have to configure an additional
>>>
>>> There's a prior idmap_t0sz setting based on __idmap_text_end. Isn't that
>>> sufficient? We don't care about covering the whole PA space, just the
>>> __idmap_text_end.
>>
>> Right but its bit tricky here.
>>
>> __idmap_text_end could be any where between VA_BITS (36) and PA_BITS (48)
>> which would require (one or two) additional page table levels. But in this
>> solution it creates two additional page table levels for idmap which would
>> completely map upto PA_BITS, regardless of __idmap_text_end's position. So
>> in case __idmap_text_end is between VA_BITS (36) and VA_BITS(47), a single
>> additional page table level is required where as we have created two ! So
>> to avoid such a situation, adjust idmap_t0sz accordingly. Otherwise there
>> will be a MMU mis-configuration.
> 
> I get it now. You need 4 levels with 16K pages for idmap as 3 levels
> (one extra in head.S) are not sufficient. The normal page table uses 2
> levels with 36-bit VA. Here you chose to go with 4 levels always as the
> simplest option.
> 
> Do we need to adjust idmap_ptrs_per_pgd? I think even without your

IIUC idmap_ptrs_per_pgd tracks the number of entries at the highest level
i.e PGD but *as per* the VA_BITS config. IIUC it is used by map_memory()
which creates the mapping for the standard VA_BITS based idmap without the
extra levels, which get their entries populated with create_table_entry().
Hence idmap_ptrs_per_pgd need not be updated when new levels are added. It
should be left unchanged as PTRS_PER_PGD.

> patch, its value is wrong as it doesn't seem to be adjusted for the

The only time the entries get adjusted is when existing number of levels
dont change but all entries at PGD i.e PTRS_PER_PGD are not required. But
seems like it is not done correctly either.

Current idmap_t0sz is decided on what is required for __idmap_text_end
coverage but not PHYS_MASK_SHIFT. So the number of entries at PGD level
should be computed as follows.

idmap_ptrs_per_pgd = 1 << ((64 - idmap_t0sz) - PGDIR_SHIFT)

but instead here is what we have.

        /*
         * If VA_BITS == 48, we don't have to configure an additional
         * translation level, but the top-level table has more entries.
         */
        mov     x4, #1 << (PHYS_MASK_SHIFT - PGDIR_SHIFT)
        str_l   x4, idmap_ptrs_per_pgd, x5

A reduced idmap_t0sz here covers __idmap_text_end not PHYS_MASK_SHIFT.
I guess this just works because idmap page table levels required for the
reduced idmap_t0sz and PHYS_MASK_SHIFT remains the same in all possible
cases for now. The only deviation would have been [16K|36VA|48PA] which
must have faced this issue but then it was blocked by another problem
altogether (being solved here).

> extra level. I can't figure out whether it matter but I think we should
> remove this variable altogether and just set the x4 register to what we
> need in head.S

Right, idmap_ptrs_per_pgd is not required for anything else other than
map_memory() which take it at x4. Could be dropped without any problem.

> 
>> This patch is indented for stable back port and hence tries to be as simple
>> and minimal as possible. So it creates two additional page table levels
>> mapping upto PA_BITS without just considering __idmap_text_end's position.
>> Reducing __idmap_t0sz upto PA_BITS should not be a problem irrespective of
>> ID_AA64MMFR0_EL1.PARANGE value. As __idmap_text_end would never be on a PA
>> which is not supported. Hence out of range PA would never be on the bus for
>> translation.
> 
> I'd rather have a clean solution (might as well be this one) than
> worrying about a stable back-port. It's highly unlikely that we'll trip
> over this problem in practice: first you'd need RAM above 47-bit and
> second you'd have to enable EXPERT and 36-bit VA.

I am working on a solution which re-works idmap extension logic based on the
difference between __idmap_text_end and PGDIR_SHIFT coverage, then creating
additional page table levels and reducing idmap_t0sz appropriately. All the
existing code including this fix here, will be dropped completely. Because
it might be difficult to extend this patch to get the entire thing in order,
the idea was to just fix [16K|36VA|48PA] which could then be backported and
then do the rework in mainline (which need not be backported).

To summarize here, you would prefer to skip the above transition and instead
directly move to the rework which may not be backported ? Please do suggest.

> 
> It looks like idmap_t0sz is used by the kvm_mmu_init() code to calculate
> hyp_va_bits. Does it mean that idmap_t0sz should always match PA_SIZE?

Default value for idmap_t0sz is TCR_T0SZ(VA_BITS_MIN) unless it gets reduced
further to map __idmap_text_end after extending the idmap levels. So it does
not always match PA_SIZE.

> Or maybe we should just decouple the two.

I dont have adequate understanding on this area. It seems like the hyp borrows
the already discovered __idmap_text_end placement via idmap_t0sz to figure out
whether it also needs to have an extended ID map (at EL2). Decoupling it might
suggest KVM should rediscover __idmap_text_end's placement ?


From viresh.kumar at linaro.org  Tue Aug  3 21:02:37 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 4 Aug 2021 09:32:37 +0530
Subject: [PATCH v2] cpufreq: arm_scmi: Fix error path when allocation
 failed
In-Reply-To: <20210803090744.12143-1-lukasz.luba@arm.com>
References: <20210803090744.12143-1-lukasz.luba@arm.com>
Message-ID: <20210804040237.ssrba26jpe572mjf@vireshk-i7>

On 03-08-21, 10:07, Lukasz Luba wrote:
> Stop the initialization when cpumask allocation failed and return an
> error.
> 
> Fixes: 80a064dbd556 ("scmi-cpufreq: Get opp_shared_cpus from opp-v2 for EM")
> Signed-off-by: Lukasz Luba <lukasz.luba at arm.com>
> ---
> changes:
> v2:
> - removed dev_warn() since it's not needed in this case
> - adjusted the patch description
> 
>  drivers/cpufreq/scmi-cpufreq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
> index ec9a87ca2dbb..75f818d04b48 100644
> --- a/drivers/cpufreq/scmi-cpufreq.c
> +++ b/drivers/cpufreq/scmi-cpufreq.c
> @@ -134,7 +134,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
>  	}
>  
>  	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL))
> -		ret = -ENOMEM;
> +		return -ENOMEM;
>  
>  	/* Obtain CPUs that share SCMI performance controls */
>  	ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);

Applied. Thanks.

-- 
viresh


From o.rempel at pengutronix.de  Tue Aug  3 21:34:38 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Wed,  4 Aug 2021 06:34:38 +0200
Subject: [PATCH v4 2/3] dt-bindings: arm: fsl: add SKOV imx6q and imx6dl based
 boards
In-Reply-To: <20210804043439.11757-1-o.rempel@pengutronix.de>
References: <20210804043439.11757-1-o.rempel@pengutronix.de>
Message-ID: <20210804043439.11757-3-o.rempel@pengutronix.de>

Add SKOV imx6q/dl LT2, LT6 and mi1010ait-1cp1 boards.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index e2097011c4b0..600dfe984ab3 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -221,6 +221,9 @@ properties:
               - prt,prti6q                # Protonic PRTI6Q board
               - prt,prtwd2                # Protonic WD2 board
               - rex,imx6q-rex-pro         # Rex Pro i.MX6 Quad Board
+              - skov,imx6q-skov-revc-lt2  # SKOV IMX6 CPU QuadCore lt2
+              - skov,imx6q-skov-revc-lt6  # SKOV IMX6 CPU QuadCore lt6
+              - skov,imx6q-skov-reve-mi1010ait-1cp1 # SKOV IMX6 CPU QuadCore mi1010ait-1cp1
               - solidrun,cubox-i/q        # SolidRun Cubox-i Dual/Quad
               - solidrun,hummingboard/q
               - solidrun,hummingboard2/q
@@ -378,6 +381,8 @@ properties:
               - prt,prtvt7                # Protonic VT7 board
               - rex,imx6dl-rex-basic      # Rex Basic i.MX6 Dual Lite Board
               - riot,imx6s-riotboard      # RIoTboard i.MX6S
+              - skov,imx6dl-skov-revc-lt2 # SKOV IMX6 CPU SoloCore lt2
+              - skov,imx6dl-skov-revc-lt6 # SKOV IMX6 CPU SoloCore lt6
               - solidrun,cubox-i/dl            # SolidRun Cubox-i Solo/DualLite
               - solidrun,hummingboard/dl
               - solidrun,hummingboard2/dl      # SolidRun HummingBoard2 Solo/DualLite
-- 
2.30.2



From o.rempel at pengutronix.de  Tue Aug  3 21:34:39 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Wed,  4 Aug 2021 06:34:39 +0200
Subject: [PATCH v4 3/3] ARM: dts: add SKOV imx6q and imx6dl based boards
In-Reply-To: <20210804043439.11757-1-o.rempel@pengutronix.de>
References: <20210804043439.11757-1-o.rempel@pengutronix.de>
Message-ID: <20210804043439.11757-4-o.rempel@pengutronix.de>

From: Sam Ravnborg <sam at ravnborg.org>

Add SKOV imx6q/dl LT2, LT6 and mi1010ait-1cp1 boards.

Signed-off-by: Sam Ravnborg <sam at ravnborg.org>
Signed-off-by: S?ren Andersen <san at skov.dk>
Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
Signed-off-by: Ulrich ?lmann <u.oelmann at pengutronix.de>
Signed-off-by: Michael Grzeschik <m.grzeschik at pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 arch/arm/boot/dts/Makefile                    |   5 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts    |  13 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts    | 106 ++++
 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts     |  36 ++
 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts     | 128 +++++
 .../dts/imx6q-skov-reve-mi1010ait-1cp1.dts    | 127 +++++
 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi  |  54 ++
 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi       | 477 ++++++++++++++++++
 8 files changed, 946 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 828fefc9c436..ecff0743d35f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -475,6 +475,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6dl-sabrelite.dtb \
 	imx6dl-sabresd.dtb \
 	imx6dl-savageboard.dtb \
+	imx6dl-skov-revc-lt2.dtb \
+	imx6dl-skov-revc-lt6.dtb \
 	imx6dl-solidsense.dtb \
 	imx6dl-ts4900.dtb \
 	imx6dl-ts7970.dtb \
@@ -576,6 +578,9 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
 	imx6q-sabresd.dtb \
 	imx6q-savageboard.dtb \
 	imx6q-sbc6x.dtb \
+	imx6q-skov-revc-lt2.dtb \
+	imx6q-skov-revc-lt6.dtb \
+	imx6q-skov-reve-mi1010ait-1cp1.dtb \
 	imx6q-solidsense.dtb \
 	imx6q-tbs2910.dtb \
 	imx6q-ts4900.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts b/arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
new file mode 100644
index 000000000000..667b8faa1807
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+#include "imx6qdl-skov-cpu-revc.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU SoloCore";
+	compatible = "skov,imx6dl-skov-revc-lt2", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts b/arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
new file mode 100644
index 000000000000..5dcc433fe2af
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+#include "imx6qdl-skov-cpu-revc.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU SoloCore";
+	compatible = "skov,imx6dl-skov-revc-lt6", "fsl,imx6dl";
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_backlight>;
+		enable-gpios = <&gpio6 23 GPIO_ACTIVE_LOW>;
+		pwms = <&pwm2 0 20000 0>;
+		brightness-levels = <0 255>;
+		num-interpolated-steps = <17>;
+		default-brightness-level = <8>;
+		power-supply = <&reg_24v0>;
+	};
+
+	display {
+		compatible = "fsl,imx-parallel-display";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+
+			display0_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			display0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+
+	panel {
+		compatible = "logictechno,lttd800480070-l6wh-rt";
+		backlight = <&backlight>;
+		power-supply = <&reg_3v3>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display0_out>;
+			};
+		};
+	};
+};
+
+&ipu1_di0_disp0 {
+	remote-endpoint = <&display0_in>;
+};
+
+&iomuxc {
+	pinctrl_backlight: backlightgrp {
+		fsl,pins = <
+			MX6QDL_PAD_RGMII_TD3__GPIO6_IO23		0x58
+		>;
+	};
+
+	pinctrl_ipu1: ipu1grp {
+		fsl,pins = <
+			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK	0x10
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x10
+			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02		0x10
+			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03		0x10
+			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00	0x10
+			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01	0x10
+			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02	0x10
+			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03	0x10
+			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04	0x10
+			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05	0x10
+			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06	0x10
+			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07	0x10
+			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08	0x10
+			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09	0x10
+			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10	0x10
+			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11	0x10
+			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12	0x10
+			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13	0x10
+			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14	0x10
+			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15	0x10
+			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16	0x10
+			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17	0x10
+			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18	0x10
+			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19	0x10
+			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20	0x10
+			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21	0x10
+			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22	0x10
+			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23	0x10
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-skov-revc-lt2.dts b/arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
new file mode 100644
index 000000000000..f00add7b3048
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+#include "imx6qdl-skov-cpu-revc.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU QuadCore";
+	compatible = "skov,imx6q-skov-revc-lt2", "fsl,imx6q";
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL		0x4001f878
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA		0x4001f878
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-skov-revc-lt6.dts b/arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
new file mode 100644
index 000000000000..3e3b36ad362a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+#include "imx6qdl-skov-cpu-revc.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU QuadCore";
+	compatible = "skov,imx6q-skov-revc-lt6", "fsl,imx6q";
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_backlight>;
+		enable-gpios = <&gpio6 23 GPIO_ACTIVE_LOW>;
+		pwms = <&pwm2 0 20000 0>;
+		brightness-levels = <0 255>;
+		num-interpolated-steps = <17>;
+		default-brightness-level = <8>;
+		power-supply = <&reg_24v0>;
+	};
+
+	display {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "fsl,imx-parallel-display";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1>;
+
+		port at 0 {
+			reg = <0>;
+
+			display0_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			display0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+
+	panel {
+		compatible = "logictechno,lttd800480070-l6wh-rt";
+		backlight = <&backlight>;
+		power-supply = <&reg_3v3>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display0_out>;
+			};
+		};
+	};
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&ipu1_di0_disp0 {
+	remote-endpoint = <&display0_in>;
+};
+
+&iomuxc {
+	pinctrl_backlight: backlightgrp {
+		fsl,pins = <
+			MX6QDL_PAD_RGMII_TD3__GPIO6_IO23		0x58
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL		0x4001F878
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA		0x4001F878
+		>;
+	};
+
+	pinctrl_ipu1: ipu1grp {
+		fsl,pins = <
+			MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK	0x10
+			MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15		0x10
+			MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02		0x10
+			MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03		0x10
+			MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00	0x10
+			MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01	0x10
+			MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02	0x10
+			MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03	0x10
+			MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04	0x10
+			MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05	0x10
+			MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06	0x10
+			MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07	0x10
+			MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08	0x10
+			MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09	0x10
+			MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10	0x10
+			MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11	0x10
+			MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12	0x10
+			MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13	0x10
+			MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14	0x10
+			MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15	0x10
+			MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16	0x10
+			MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17	0x10
+			MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18	0x10
+			MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19	0x10
+			MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20	0x10
+			MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21	0x10
+			MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22	0x10
+			MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23	0x10
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts b/arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
new file mode 100644
index 000000000000..7f1f19b74bfa
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-skov-cpu.dtsi"
+
+/ {
+	model = "SKOV IMX6 CPU QuadCore";
+	compatible = "skov,imx6q-skov-reve-mi1010ait-1cp1", "fsl,imx6q";
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_backlight>;
+		enable-gpios = <&gpio6 23 GPIO_ACTIVE_LOW>;
+		pwms = <&pwm2 0 20000 0>;
+		brightness-levels = <0 255>;
+		num-interpolated-steps = <17>;
+		default-brightness-level = <8>;
+		power-supply = <&reg_24v0>;
+	};
+
+	panel {
+		compatible = "multi-inno,mi1010ait-1cp";
+		backlight = <&backlight>;
+		power-supply = <&reg_3v3>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&lvds0_out>;
+			};
+		};
+	};
+};
+
+&clks {
+	assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
+			  <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+	assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>,
+				 <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>;
+};
+
+&hdmi {
+	ddc-i2c-bus = <&i2c2>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	clock-frequency = <100000>;
+	status = "okay";
+
+	touchscreen at 38 {
+		compatible = "edt,edt-ft5406";
+		reg = <0x38>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_touchscreen>;
+		interrupt-parent = <&gpio3>;
+		interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
+		touchscreen-size-x = <1280>;
+		touchscreen-size-y = <800>;
+		wakeup-source;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&ldb {
+	status = "okay";
+
+	lvds-channel at 0 {
+		status = "okay";
+
+		port at 4 {
+			reg = <4>;
+
+			lvds0_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl_backlight: backlightgrp {
+		fsl,pins = <
+			MX6QDL_PAD_RGMII_TD3__GPIO6_IO23		0x58
+		>;
+	};
+
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins = <
+			/* external 1 k pull up */
+			MX6QDL_PAD_EIM_D21__I2C1_SCL		0x40010878
+			/* external 1 k pull up */
+			MX6QDL_PAD_EIM_D28__I2C1_SDA		0x40010878
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_COL3__I2C2_SCL		0x4001F878
+			/* internal 22 k pull up required */
+			MX6QDL_PAD_KEY_ROW3__I2C2_SDA		0x4001F878
+		>;
+	};
+
+	pinctrl_touchscreen: touchscreengrp {
+		fsl,pins = <
+			/* external 10 k pull up */
+			/* CTP_INT */
+			MX6QDL_PAD_EIM_D19__GPIO3_IO19		0x1b0b0
+			/* CTP_RST */
+			MX6QDL_PAD_EIM_D23__GPIO3_IO23		0x1b0b0
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi b/arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
new file mode 100644
index 000000000000..69ae430a53bd
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+&ecspi4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi4>;
+	cs-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	touchscreen at 0 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_touch>;
+		compatible = "ti,tsc2046";
+		reg = <0>;
+		spi-max-frequency = <1000000>;
+		interrupts-extended = <&gpio3 19 IRQ_TYPE_LEVEL_LOW>;
+		vcc-supply  = <&reg_3v3>;
+		pendown-gpio = <&gpio3 19 GPIO_ACTIVE_LOW>;
+		ti,x-plate-ohms = /bits/ 16 <850>;
+		ti,y-plate-ohms = /bits/ 16 <295>;
+		ti,pressure-min = /bits/ 16 <2>;
+		ti,pressure-max = /bits/ 16 <1500>;
+		ti,vref-mv	= /bits/ 16 <3300>;
+		ti,settle-delay-usec = /bits/ 16 <15>;
+		ti,vref-delay-usecs = /bits/ 16 <0>;
+		ti,penirq-recheck-delay-usecs = /bits/ 16 <100>;
+		ti,debounce-max = /bits/ 16 <100>;
+		ti,debounce-tol = /bits/ 16 <(~0)>;
+		ti,debounce-rep = /bits/ 16 <4>;
+		touchscreen-swapped-x-y;
+		touchscreen-inverted-y;
+		wakeup-source;
+	};
+};
+
+&iomuxc {
+	pinctrl_ecspi4: ecspi4grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D28__ECSPI4_MOSI			0x100b1
+			MX6QDL_PAD_EIM_D22__ECSPI4_MISO			0x000b1
+			MX6QDL_PAD_EIM_D21__ECSPI4_SCLK			0x000b1
+			/* *no* external pull up */
+			MX6QDL_PAD_EIM_D20__GPIO3_IO20		0x40000058
+		>;
+	};
+
+	pinctrl_touch: touchgrp {
+		fsl,pins = <
+			/* external pull up */
+			MX6QDL_PAD_EIM_D19__GPIO3_IO19			0x10040
+		>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi b/arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi
new file mode 100644
index 000000000000..77a91a97e6cf
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi
@@ -0,0 +1,477 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (C) 2020 Pengutronix, Ulrich Oelmann <kernel at pengutronix.de>
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	chosen {
+		stdout-path = &uart2;
+	};
+
+	aliases {
+		can0 = &can1;
+		can1 = &can2;
+		mdio-gpio0 = &mdio;
+		nand = &gpmi;
+		rtc0 = &i2c_rtc;
+		rtc1 = &snvs;
+		usb0 = &usbh1;
+		usb1 = &usbotg;
+	};
+
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 0>, /* 24V */
+		              <&adc 1>; /* temperature */
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			label = "D1";
+			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+			function = LED_FUNCTION_STATUS;
+			default-state = "on";
+			linux,default-trigger = "heartbeat";
+		};
+
+		led-1 {
+			label = "D2";
+			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+
+		led-2 {
+			label = "D3";
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	mdio: mdio {
+		compatible = "microchip,mdio-smi0";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_mdio>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>,
+			<&gpio1 22 GPIO_ACTIVE_HIGH>;
+
+		switch at 0 {
+			compatible = "microchip,ksz8873";
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_switch>;
+			interrupt-parent = <&gpio3>;
+			interrupt = <30 IRQ_TYPE_LEVEL_HIGH>;
+			reset-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+			reg = <0>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ports at 0 {
+					reg = <0>;
+					phy-mode = "internal";
+					label = "lan1";
+				};
+
+				ports at 1 {
+					reg = <1>;
+					phy-mode = "internal";
+					label = "lan2";
+				};
+
+				ports at 2 {
+					reg = <2>;
+					label = "cpu";
+					ethernet = <&fec>;
+					phy-mode = "rmii";
+
+					fixed-link {
+						speed = <100>;
+						full-duplex;
+					};
+				};
+			};
+		};
+
+	};
+
+	clk50m_phy: phy-clock {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <50000000>;
+	};
+
+	reg_3v3: regulator-3v3 {
+		compatible = "regulator-fixed";
+		vin-supply = <&reg_5v0>;
+		regulator-name = "3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_5v0: regulator-5v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "5v0";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	reg_24v0: regulator-24v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "24v0";
+		regulator-min-microvolt = <24000000>;
+		regulator-max-microvolt = <24000000>;
+	};
+
+	reg_can1_stby: regulator-can1-stby {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can1_stby>;
+		regulator-name = "can1-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio3 31 GPIO_ACTIVE_LOW>;
+	};
+
+	reg_can2_stby: regulator-can2-stby {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can2_stby>;
+		regulator-name = "can2-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio4 11 GPIO_ACTIVE_LOW>;
+	};
+
+	reg_vcc_mmc: regulator-vcc-mmc {
+		compatible = "regulator-fixed";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_vcc_mmc>;
+		vin-supply = <&reg_3v3>;
+		regulator-name = "mmc_vcc_supply";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+		regulator-boot-on;
+		gpio = <&gpio7 8 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		startup-delay-us = <100>;
+	};
+
+	reg_vcc_mmc_io: regulator-vcc-mmc-io {
+		compatible = "regulator-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_vcc_mmc_io>;
+		vin-supply = <&reg_5v0>;
+		regulator-name = "mmc_io_supply";
+		regulator-type = "voltage";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		gpios = <&gpio7 13 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		states = <1800000 0x1>, <3300000 0x0>;
+		startup-delay-us = <100>;
+	};
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can1>;
+	xceiver-supply = <&reg_can1_stby>;
+	status = "okay";
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_can2>;
+	xceiver-supply = <&reg_can2_stby>;
+	status = "okay";
+};
+
+&ecspi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1>;
+	cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <54000000>;
+		reg = <0>;
+	};
+};
+
+&ecspi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+	cs-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	adc: adc at 0 {
+		compatible = "microchip,mcp3002";
+		reg = <0>;
+		vref-supply = <&reg_3v3>;
+		spi-max-frequency = <1000000>;
+		#io-channel-cells = <1>;
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet>;
+	clocks = <&clks IMX6QDL_CLK_ENET>,
+		 <&clks IMX6QDL_CLK_ENET>,
+		 <&clk50m_phy>;
+	clock-names = "ipg", "ahb", "ptp";
+	phy-mode = "rmii";
+	phy-supply = <&reg_3v3>;
+	status = "okay";
+
+	fixed-link {
+		speed = <100>;
+		full-duplex;
+	};
+};
+
+&gpmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpmi_nand>;
+	nand-on-flash-bbt;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+};
+
+&i2c3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	clock-frequency = <400000>;
+	status = "okay";
+
+	i2c_rtc: rtc at 51 {
+		compatible = "nxp,pcf85063";
+		reg = <0x51>;
+		quartz-load-femtofarads = <12500>;
+	};
+};
+
+&pwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm2>;
+	#pwm-cells = <2>;
+	status = "okay";
+};
+
+&pwm3 {
+	/* used for LCD contrast control */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm3>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&usbh1 {
+	vbus-supply = <&reg_5v0>;
+	disable-over-current;
+	status = "okay";
+};
+
+/* no usbh2 */
+&usbphynop1 {
+	status = "disabled";
+};
+
+/* no usbh3 */
+&usbphynop2 {
+	status = "disabled";
+};
+
+&usbotg {
+	vbus-supply = <&reg_5v0>;
+	disable-over-current;
+	status = "okay";
+};
+
+&usdhc3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	wp-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
+	cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+	cap-power-off-card;
+	full-pwr-cycle;
+	bus-width = <4>;
+	max-frequency = <50000000>;
+	cap-sd-highspeed;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-ddr50;
+	mmc-ddr-1_8v;
+	vmmc-supply = <&reg_vcc_mmc>;
+	vqmmc-supply = <&reg_vcc_mmc_io>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl_can1: can1grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_7__FLEXCAN1_TX			0x3008
+			MX6QDL_PAD_GPIO_8__FLEXCAN1_RX			0x1b000
+		>;
+	};
+
+	pinctrl_can1_stby: can1stbygrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D31__GPIO3_IO31			0x13008
+		>;
+	};
+
+	pinctrl_can2: can2grp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX		0x3008
+			MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX		0x1b000
+		>;
+	};
+
+	pinctrl_can2_stby: can2stbygrp {
+		fsl,pins = <
+			MX6QDL_PAD_KEY_ROW2__GPIO4_IO11			0x13008
+		>;
+	};
+
+	pinctrl_ecspi1: ecspi1grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D17__ECSPI1_MISO			0x100b1
+			MX6QDL_PAD_EIM_D18__ECSPI1_MOSI			0xb1
+			MX6QDL_PAD_EIM_D16__ECSPI1_SCLK			0xb1
+			/* *no* external pull up */
+			MX6QDL_PAD_EIM_D24__GPIO3_IO24			0x58
+		>;
+	};
+
+	pinctrl_ecspi2: ecspi2grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_OE__ECSPI2_MISO			0x100b1
+			MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI			0xb1
+			MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK			0xb1
+			/* external pull up */
+			MX6QDL_PAD_EIM_RW__GPIO2_IO26			0x58
+		>;
+	};
+
+	pinctrl_enet: enetgrp {
+		fsl,pins = <
+			/* RMII 50 MHz */
+			MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN		0x100f5
+			MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN		0x100f5
+			MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0		0x100c0
+			MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1		0x100c0
+			MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0		0x100f5
+			MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1		0x100f5
+			MX6QDL_PAD_GPIO_16__ENET_REF_CLK		0x1b0b0
+			MX6QDL_PAD_GPIO_5__GPIO1_IO05			0x58
+			/* GPIO for "link active" */
+			MX6QDL_PAD_ENET_RX_ER__GPIO1_IO24		0x3038
+		>;
+	};
+
+	pinctrl_gpmi_nand: gpminandgrp {
+		fsl,pins = <
+			MX6QDL_PAD_NANDF_CLE__NAND_CLE			0xb0b1
+			MX6QDL_PAD_NANDF_ALE__NAND_ALE			0xb0b1
+			MX6QDL_PAD_NANDF_RB0__NAND_READY_B		0xb000
+			MX6QDL_PAD_NANDF_CS0__NAND_CE0_B		0xb0b1
+			MX6QDL_PAD_NANDF_CS1__NAND_CE1_B		0xb0b1
+			MX6QDL_PAD_SD4_CMD__NAND_RE_B			0xb0b1
+			MX6QDL_PAD_SD4_CLK__NAND_WE_B			0xb0b1
+			MX6QDL_PAD_NANDF_D0__NAND_DATA00		0xb0b1
+			MX6QDL_PAD_NANDF_D1__NAND_DATA01		0xb0b1
+			MX6QDL_PAD_NANDF_D2__NAND_DATA02		0xb0b1
+			MX6QDL_PAD_NANDF_D3__NAND_DATA03		0xb0b1
+			MX6QDL_PAD_NANDF_D4__NAND_DATA04		0xb0b1
+			MX6QDL_PAD_NANDF_D5__NAND_DATA05		0xb0b1
+			MX6QDL_PAD_NANDF_D6__NAND_DATA06		0xb0b1
+			MX6QDL_PAD_NANDF_D7__NAND_DATA07		0xb0b1
+		>;
+	};
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			/* external 10 k pull up */
+			MX6QDL_PAD_GPIO_3__I2C3_SCL		0x40010878
+			/* external 10 k pull up */
+			MX6QDL_PAD_GPIO_6__I2C3_SDA		0x40010878
+		>;
+	};
+
+	pinctrl_mdio: mdiogrp {
+		fsl,pins = <
+			MX6QDL_PAD_ENET_MDIO__GPIO1_IO22		0x100b1
+			MX6QDL_PAD_ENET_MDC__GPIO1_IO31			0xb1
+		>;
+	};
+
+	pinctrl_pwm2: pwm2grp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_1__PWM2_OUT			0x58
+		>;
+	};
+
+	pinctrl_pwm3: pwm3grp {
+		fsl,pins = <
+			MX6QDL_PAD_SD1_DAT1__PWM3_OUT			0x58
+		>;
+	};
+
+	pinctrl_switch: switchgrp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D30__GPIO3_IO30			0xb0
+		>;
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX6QDL_PAD_EIM_D26__UART2_TX_DATA		0x1b0b1
+			MX6QDL_PAD_EIM_D27__UART2_RX_DATA		0x1b0b1
+		>;
+	};
+
+	pinctrl_usdhc3: usdhc3grp {
+		fsl,pins = <
+			/* SoC internal pull up required */
+			MX6QDL_PAD_SD3_CMD__SD3_CMD			0x17059
+			MX6QDL_PAD_SD3_CLK__SD3_CLK			0x10059
+			MX6QDL_PAD_SD3_DAT0__SD3_DATA0			0x17059
+			MX6QDL_PAD_SD3_DAT1__SD3_DATA1			0x17059
+			MX6QDL_PAD_SD3_DAT2__SD3_DATA2			0x17059
+			MX6QDL_PAD_SD3_DAT3__SD3_DATA3			0x17059
+			/* SoC internal pull up required */
+			MX6QDL_PAD_SD3_DAT4__GPIO7_IO01			0x1b040
+			/* SoC internal pull up required */
+			MX6QDL_PAD_SD3_DAT5__GPIO7_IO00			0x1b040
+		>;
+	};
+
+	pinctrl_vcc_mmc: vccmmcgrp {
+		fsl,pins = <
+			MX6QDL_PAD_SD3_RST__GPIO7_IO08			0x58
+		>;
+	};
+
+	pinctrl_vcc_mmc_io: vccmmciogrp {
+		fsl,pins = <
+			MX6QDL_PAD_GPIO_18__GPIO7_IO13			0x58
+		>;
+	};
+};
-- 
2.30.2



From o.rempel at pengutronix.de  Tue Aug  3 21:34:36 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Wed,  4 Aug 2021 06:34:36 +0200
Subject: [PATCH v34 0/3] Mainline imx6 based SKOV boards
Message-ID: <20210804043439.11757-1-o.rempel@pengutronix.de>

changes v4:
- add vref-supply to adc at 0
- split gpio assignment for the mdio node

changes v3:
- drop panel bindings patches, it is already in drm-misc-next
- remove some new lines
- reorder compatibles at the start of the nodes
- use lowercase for hex value
- add enable-active-high to the regulator-vcc-mmc-io and fix MMC voltage
  configuration.

changes v2:
- remove unnecessary newlines.
- change linux,wakeup to wakeup-source
- change switch at 3 unit-address to @0
- sort aliases alphabetically

Mainline imx6 based DTs for SKOV A/S boards

Oleksij Rempel (2):
  dt-bindings: vendor-prefixes: Add an entry for SKOV A/S
  dt-bindings: arm: fsl: add SKOV imx6q and imx6dl based boards

Sam Ravnborg (1):
  ARM: dts: add SKOV imx6q and imx6dl based boards

 .../devicetree/bindings/arm/fsl.yaml          |   5 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/boot/dts/Makefile                    |   5 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts    |  13 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts    | 106 ++++
 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts     |  36 ++
 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts     | 128 +++++
 .../dts/imx6q-skov-reve-mi1010ait-1cp1.dts    | 127 +++++
 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi  |  54 ++
 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi       | 477 ++++++++++++++++++
 10 files changed, 953 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi

-- 
2.30.2



From o.rempel at pengutronix.de  Tue Aug  3 21:34:37 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Wed,  4 Aug 2021 06:34:37 +0200
Subject: [PATCH v4 1/3] dt-bindings: vendor-prefixes: Add an entry for SKOV A/S
In-Reply-To: <20210804043439.11757-1-o.rempel@pengutronix.de>
References: <20210804043439.11757-1-o.rempel@pengutronix.de>
Message-ID: <20210804043439.11757-2-o.rempel@pengutronix.de>

Add "skov" entry for the SKOV A/S: https://www.skov.com/en/

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 62cb1d9341f5..738d4f44f0de 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1068,6 +1068,8 @@ patternProperties:
     description: Silicon Integrated Systems Corp.
   "^sitronix,.*":
     description: Sitronix Technology Corporation
+  "^skov,.*":
+    description: SKOV A/S
   "^skyworks,.*":
     description: Skyworks Solutions, Inc.
   "^smartlabs,.*":
-- 
2.30.2



From hsinyi at chromium.org  Tue Aug  3 21:40:31 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Wed,  4 Aug 2021 12:40:31 +0800
Subject: [PATCH v4 1/3] arm: dts: mt8135: Move pinfunc to
 include/dt-bindings/pinctrl
Message-ID: <20210804044033.3047296-1-hsinyi@chromium.org>

Move mt8135-pinfunc.h into include/dt-bindings/pinctrl so that we can
include it in yaml examples.

Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 arch/arm/boot/dts/mt8135.dtsi                                   | 2 +-
 .../boot/dts => include/dt-bindings/pinctrl}/mt8135-pinfunc.h   | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename {arch/arm/boot/dts => include/dt-bindings/pinctrl}/mt8135-pinfunc.h (100%)

diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi
index 0e4e835026db0..a031b36363187 100644
--- a/arch/arm/boot/dts/mt8135.dtsi
+++ b/arch/arm/boot/dts/mt8135.dtsi
@@ -9,7 +9,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/mt8135-resets.h>
-#include "mt8135-pinfunc.h"
+#include <dt-bindings/pinctrl/mt8135-pinfunc.h>
 
 / {
 	#address-cells = <2>;
diff --git a/arch/arm/boot/dts/mt8135-pinfunc.h b/include/dt-bindings/pinctrl/mt8135-pinfunc.h
similarity index 100%
rename from arch/arm/boot/dts/mt8135-pinfunc.h
rename to include/dt-bindings/pinctrl/mt8135-pinfunc.h
-- 
2.32.0.554.ge1b32706d8-goog



From hsinyi at chromium.org  Tue Aug  3 21:40:32 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Wed,  4 Aug 2021 12:40:32 +0800
Subject: [PATCH v4 2/3] arm: dts: mt8183: Move pinfunc to
 include/dt-bindings/pinctrl
In-Reply-To: <20210804044033.3047296-1-hsinyi@chromium.org>
References: <20210804044033.3047296-1-hsinyi@chromium.org>
Message-ID: <20210804044033.3047296-2-hsinyi@chromium.org>

Move mt8183-pinfunc.h into include/dt-bindings/pinctrl so that we can
include it in yaml examples.

Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi                        | 2 +-
 .../mediatek => include/dt-bindings/pinctrl}/mt8183-pinfunc.h   | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename {arch/arm64/boot/dts/mediatek => include/dt-bindings/pinctrl}/mt8183-pinfunc.h (100%)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index f90df6439c088..1933045da95de 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -14,7 +14,7 @@
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/thermal/thermal.h>
-#include "mt8183-pinfunc.h"
+#include <dt-bindings/pinctrl/mt8183-pinfunc.h>
 
 / {
 	compatible = "mediatek,mt8183";
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h b/include/dt-bindings/pinctrl/mt8183-pinfunc.h
similarity index 100%
rename from arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h
rename to include/dt-bindings/pinctrl/mt8183-pinfunc.h
-- 
2.32.0.554.ge1b32706d8-goog



From hsinyi at chromium.org  Tue Aug  3 21:40:34 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Wed,  4 Aug 2021 12:40:34 +0800
Subject: [PATCH v4 3/3] dt-bindings: mediatek: convert pinctrl to yaml
In-Reply-To: <20210804044033.3047296-1-hsinyi@chromium.org>
References: <20210804044033.3047296-1-hsinyi@chromium.org>
Message-ID: <20210804044033.3047296-3-hsinyi@chromium.org>

Convert mt65xx, mt6796, mt7622, mt8183 bindings to yaml.

Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
Reviewed-by: Rob Herring <robh at kernel.org>
---
v3->v4:
- update MAINTAINERS
v2->v3:
- fix pattern regex '-pins'
- drop duplicate enum that constraints already have
- fix typos
v1->v2:
- fix a few minItems/maxItems
- convert text constraints into schema in mt7622
- fix pattern regex
---
 .../pinctrl/mediatek,mt65xx-pinctrl.yaml      | 206 ++++++++
 .../pinctrl/mediatek,mt6797-pinctrl.yaml      | 173 +++++++
 .../pinctrl/mediatek,mt7622-pinctrl.yaml      | 373 +++++++++++++
 .../pinctrl/mediatek,mt8183-pinctrl.yaml      | 228 ++++++++
 .../bindings/pinctrl/pinctrl-mt65xx.txt       | 156 ------
 .../bindings/pinctrl/pinctrl-mt6797.txt       |  83 ---
 .../bindings/pinctrl/pinctrl-mt7622.txt       | 490 ------------------
 .../bindings/pinctrl/pinctrl-mt8183.txt       | 132 -----
 MAINTAINERS                                   |   6 +-
 9 files changed, 984 insertions(+), 863 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
new file mode 100644
index 0000000000000..f8e6e138dc13a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
@@ -0,0 +1,206 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt65xx-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT65xx Pin Controller Device Tree Bindings
+
+maintainers:
+  - Sean Wang <sean.wang at kernel.org>
+
+description: |+
+  The Mediatek's Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt2701-pinctrl
+      - mediatek,mt2712-pinctrl
+      - mediatek,mt6397-pinctrl
+      - mediatek,mt7623-pinctrl
+      - mediatek,mt8127-pinctrl
+      - mediatek,mt8135-pinctrl
+      - mediatek,mt8167-pinctrl
+      - mediatek,mt8173-pinctrl
+      - mediatek,mt8516-pinctrl
+
+  reg:
+    maxItems: 1
+
+  pins-are-numbered:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: |
+      Specify the subnodes are using numbered pinmux to specify pins.
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO
+      binding is used, the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+
+  mediatek,pctl-regmap:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 2
+    description: |
+      Should be phandles of the syscfg node.
+
+  interrupt-controller: true
+
+  interrupts:
+    minItems: 1
+    maxItems: 3
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - pins-are-numbered
+  - gpio-controller
+  - "#gpio-cells"
+
+patternProperties:
+  '-[0-9]+$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      'pins':
+        type: object
+        additionalProperties: false
+        description: |
+          A pinctrl node should contain at least one subnodes representing the
+          pinctrl groups available on the machine. Each subnode will list the
+          pins it needs, and how they should be configured, with regard to muxer
+          configuration, pullups, drive strength, input enable/disable and input
+          schmitt.
+        $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+        properties:
+          pinmux:
+            description:
+              integer array, represents gpio pin number and mux setting.
+              Supported pin number and mux varies for different SoCs, and are
+              defined as macros in <soc>-pinfunc.h directly.
+
+          bias-disable: true
+
+          bias-pull-up:
+            description: |
+              Besides generic pinconfig options, it can be used as the pull up
+              settings for 2 pull resistors, R0 and R1. User can configure those
+              special pins. Some macros have been defined for this usage, such
+              as MTK_PUPD_SET_R1R0_00. See dt-bindings/pinctrl/mt65xx.h for
+              valid arguments.
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          input-disable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            description: |
+              Can support some arguments, such as MTK_DRIVE_4mA, MTK_DRIVE_6mA,
+              etc. See dt-bindings/pinctrl/mt65xx.h for valid arguments.
+
+        required:
+          - pinmux
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt8135-pinfunc.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        syscfg_pctl_a: syscfg-pctl-a at 10005000 {
+          compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon";
+          reg = <0 0x10005000 0 0x1000>;
+        };
+
+        syscfg_pctl_b: syscfg-pctl-b at 1020c020 {
+          compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon";
+          reg = <0 0x1020C020 0 0x1000>;
+        };
+
+        pinctrl at 1c20800 {
+          compatible = "mediatek,mt8135-pinctrl";
+          reg = <0 0x1000B000 0 0x1000>;
+          mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>;
+          pins-are-numbered;
+          gpio-controller;
+          #gpio-cells = <2>;
+          interrupt-controller;
+          #interrupt-cells = <2>;
+          interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+              <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+              <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+
+          i2c0_pins_a: i2c0-0 {
+            pins1 {
+              pinmux = <MT8135_PIN_100_SDA0__FUNC_SDA0>,
+                <MT8135_PIN_101_SCL0__FUNC_SCL0>;
+              bias-disable;
+            };
+          };
+
+          i2c1_pins_a: i2c1-0 {
+            pins {
+              pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
+                <MT8135_PIN_196_SCL1__FUNC_SCL1>;
+              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+            };
+          };
+
+          i2c2_pins_a: i2c2-0 {
+            pins1 {
+              pinmux = <MT8135_PIN_193_SDA2__FUNC_SDA2>;
+              bias-pull-down;
+            };
+
+            pins2 {
+              pinmux = <MT8135_PIN_49_WATCHDOG__FUNC_GPIO49>;
+              bias-pull-up;
+            };
+          };
+
+          i2c3_pins_a: i2c3-0 {
+            pins1 {
+              pinmux = <MT8135_PIN_40_DAC_CLK__FUNC_GPIO40>,
+                <MT8135_PIN_41_DAC_WS__FUNC_GPIO41>;
+              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+            };
+
+            pins2 {
+              pinmux = <MT8135_PIN_35_SCL3__FUNC_SCL3>,
+                <MT8135_PIN_36_SDA3__FUNC_SDA3>;
+              output-low;
+              bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+            };
+
+            pins3 {
+              pinmux = <MT8135_PIN_57_JTCK__FUNC_GPIO57>,
+                <MT8135_PIN_60_JTDI__FUNC_JTDI>;
+              drive-strength = <32>;
+            };
+          };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
new file mode 100644
index 0000000000000..76a6df75ed9c3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
@@ -0,0 +1,173 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt6797-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT6797 Pin Controller Device Tree Bindings
+
+maintainers:
+  - Sean Wang <sean.wang at kernel.org>
+
+description: |+
+  The MediaTek's MT6797 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    const: mediatek,mt6797-pinctrl
+
+  reg:
+    minItems: 5
+    maxItems: 5
+
+  reg-names:
+    items:
+      - const: gpio
+      - const: iocfgl
+      - const: iocfgb
+      - const: iocfgr
+      - const: iocfgt
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO
+      binding is used, the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - gpio-controller
+  - "#gpio-cells"
+
+patternProperties:
+  '-[0-9]+$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      'pins':
+        type: object
+        additionalProperties: false
+        description: |
+          A pinctrl node should contain at least one subnodes representing the
+          pinctrl groups available on the machine. Each subnode will list the
+          pins it needs, and how they should be configured, with regard to muxer
+          configuration, pullups, drive strength, input enable/disable and input
+          schmitt.
+        $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+        properties:
+          pinmux:
+            description:
+              integer array, represents gpio pin number and mux setting.
+              Supported pin number and mux varies for different SoCs, and are
+              defined as macros in <soc>-pinfunc.h directly.
+
+          bias-disable: true
+
+          bias-pull-up: true
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          input-disable: true
+
+          output-enable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [2, 4, 8, 12, 16]
+
+          slew-rate:
+            enum: [0, 1]
+
+          mediatek,pull-up-adv:
+            description: |
+              Pull up setings for 2 pull resistors, R0 and R1. User can
+              configure those special pins. Valid arguments are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,pull-down-adv:
+            description: |
+              Pull down settings for 2 pull resistors, R0 and R1. User can
+              configure those special pins. Valid arguments are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,tdsel:
+            description: |
+              An integer describing the steps for output level shifter duty
+              cycle when asserted (high pulse width adjustment). Valid arguments
+              are from 0 to 15.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+          mediatek,rdsel:
+            description: |
+              An integer describing the steps for input level shifter duty cycle
+              when asserted (high pulse width adjustment). Valid arguments are
+              from 0 to 63.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+        required:
+          - pinmux
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt6797-pinfunc.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pio: pinctrl at 10005000 {
+            compatible = "mediatek,mt6797-pinctrl";
+            reg = <0 0x10005000 0 0x1000>,
+                  <0 0x10002000 0 0x400>,
+                  <0 0x10002400 0 0x400>,
+                  <0 0x10002800 0 0x400>,
+                  <0 0x10002C00 0 0x400>;
+            reg-names = "gpio", "iocfgl", "iocfgb", "iocfgr", "iocfgt";
+            gpio-controller;
+            #gpio-cells = <2>;
+
+            uart_pins_a: uart-0 {
+                pins1 {
+                    pinmux = <MT6797_GPIO232__FUNC_URXD1>,
+                            <MT6797_GPIO233__FUNC_UTXD1>;
+                };
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
new file mode 100644
index 0000000000000..0feecd376c694
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
@@ -0,0 +1,373 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7622-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT7622 Pin Controller Device Tree Bindings
+
+maintainers:
+  - Sean Wang <sean.wang at kernel.org>
+
+description: |+
+  The MediaTek's MT7622 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt7622-pinctrl
+      - mediatek,mt7629-pinctrl
+
+  reg:
+    maxItems: 1
+
+  reg-names:
+    items:
+      - const: eint
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO
+      binding is used, the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - gpio-controller
+  - "#gpio-cells"
+
+if:
+  required:
+    - interrupt-controller
+then:
+  required:
+    - reg-names
+    - interrupts
+    - "#interrupt-cells"
+
+patternProperties:
+  '-[0-9]+$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      'mux':
+        type: object
+        additionalProperties: false
+        description: |
+          pinmux configuration nodes.
+        $ref: "/schemas/pinctrl/pinmux-node.yaml"
+        properties:
+          function:
+            description: |
+              A string containing the name of the function to mux to the group.
+            enum: [emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm, sd,
+                   spi, tdm, uart, watchdog, wifi]
+
+          groups:
+            description: |
+              An array of strings. Each string contains the name of a group.
+
+          drive-strength:
+            enum: [4, 8, 12, 16]
+
+        required:
+          - groups
+          - function
+
+        allOf:
+          - if:
+              properties:
+                function:
+                  const: emmc
+            then:
+              properties:
+                groups:
+                  enum: [emmc, emmc_rst]
+          - if:
+              properties:
+                function:
+                  const: eth
+            then:
+              properties:
+                groups:
+                  enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
+                         rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
+          - if:
+              properties:
+                function:
+                  const: i2c
+            then:
+              properties:
+                groups:
+                  enum: [i2c0, i2c_0, i2c_1, i2c1_0, i2c1_1, i2c1_2, i2c2_0,
+                         i2c2_1, i2c2_2]
+          - if:
+              properties:
+                function:
+                  const: i2s
+            then:
+              properties:
+                groups:
+                  enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
+                         i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
+                         i2s1_out_data, i2s2_out_data, i2s3_out_data,
+                         i2s4_out_data]
+          - if:
+              properties:
+                function:
+                  const: ir
+            then:
+              properties:
+                groups:
+                  enum: [ir_0_tx, ir_1_tx, ir_2_tx, ir_0_rx, ir_1_rx, ir_2_rx]
+          - if:
+              properties:
+                function:
+                  const: led
+            then:
+              properties:
+                groups:
+                  enum: [ephy_leds, ephy0_led, ephy1_led, ephy2_led, ephy3_led,
+                         ephy4_led, wled, wf2g_led, wf5g_led]
+          - if:
+              properties:
+                function:
+                  const: flash
+            then:
+              properties:
+                groups:
+                  enum: [par_nand, snfi, spi_nor]
+          - if:
+              properties:
+                function:
+                  const: pcie
+            then:
+              properties:
+                groups:
+                  enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
+                         pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
+                         pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
+                         pcie_wake, pcie_clkreq]
+          - if:
+              properties:
+                function:
+                  const: pmic
+            then:
+              properties:
+                groups:
+                  enum: [pmic_bus]
+          - if:
+              properties:
+                function:
+                  const: pwm
+            then:
+              properties:
+                groups:
+                  enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
+                         pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
+                         pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
+                         pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3,
+                         pwm_ch7_0, pwm_0, pwm_1]
+          - if:
+              properties:
+                function:
+                  const: sd
+            then:
+              properties:
+                groups:
+                  enum: [sd_0, sd_1]
+          - if:
+              properties:
+                function:
+                  const: spi
+            then:
+              properties:
+                groups:
+                  enum: [spic0_0, spic0_1, spic1_0, spic1_1, spic2_0_wp_hold,
+                         spic2_0, spi_0, spi_1, spi_wp, spi_hold]
+          - if:
+              properties:
+                function:
+                  const: tdm
+            then:
+              properties:
+                groups:
+                  enum: [tdm_0_out_mclk_bclk_ws, tdm_0_in_mclk_bclk_ws,
+                         tdm_0_out_data, tdm_0_in_data, tdm_1_out_mclk_bclk_ws,
+                         tdm_1_in_mclk_bclk_ws, tdm_1_out_data, tdm_1_in_data]
+          - if:
+              properties:
+                function:
+                  const: uart
+            then:
+              properties:
+                groups:
+                  enum: [uart0_0_tx_rx, uart1_0_tx_rx, uart1_0_rts_cts,
+                         uart1_1_tx_rx, uart1_1_rts_cts, uart2_0_tx_rx,
+                         uart2_0_rts_cts, uart2_1_tx_rx, uart2_1_rts_cts,
+                         uart2_2_tx_rx, uart2_2_rts_cts, uart2_3_tx_rx,
+                         uart3_0_tx_rx, uart3_1_tx_rx, uart3_1_rts_cts,
+                         uart4_0_tx_rx, uart4_1_tx_rx, uart4_1_rts_cts,
+                         uart4_2_tx_rx, uart4_2_rts_cts, uart0_txd_rxd,
+                         uart1_0_txd_rxd, uart1_0_cts_rts, uart1_1_txd_rxd,
+                         uart1_1_cts_rts, uart2_0_txd_rxd, uart2_0_cts_rts,
+                         uart2_1_txd_rxd, uart2_1_cts_rts]
+          - if:
+              properties:
+                function:
+                  const: watchdog
+            then:
+              properties:
+                groups:
+                  enum: [watchdog]
+          - if:
+              properties:
+                function:
+                  const: wifi
+            then:
+              properties:
+                groups:
+                  enum: [wf0_2g, wf0_5g]
+
+      'conf':
+        type: object
+        additionalProperties: false
+        description: |
+          pinconf configuration nodes.
+        $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+        properties:
+          groups:
+            description: |
+              An array of strings. Each string contains the name of a group.
+              Valid values are the same as the pinmux node.
+
+          pins:
+            description: |
+              An array of strings. Each string contains the name of a pin.
+            enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
+                   RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
+                   I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
+                   I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1,
+                   G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2,
+                   G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6,
+                   NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0,
+                   MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1,
+                   MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2,
+                   MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3,
+                   MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL,
+                   PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS,
+                   GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N,
+                   PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2,
+                   AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4,
+                   PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA,
+                   WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4,
+                   WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG,
+                   EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS,
+                   EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N,
+                   WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD,
+                   UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD,
+                   UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N,
+                   PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5,
+                   GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK,
+                   TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3,
+                   WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6]
+
+          bias-disable: true
+
+          bias-pull-up: true
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          input-disable: true
+
+          output-enable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [4, 8, 12, 16]
+
+          slew-rate:
+            enum: [0, 1]
+
+          mediatek,tdsel:
+            description: |
+              An integer describing the steps for output level shifter duty
+              cycle when asserted (high pulse width adjustment). Valid arguments
+              are from 0 to 15.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+          mediatek,rdsel:
+            description: |
+              An integer describing the steps for input level shifter duty cycle
+              when asserted (high pulse width adjustment). Valid arguments are
+              from 0 to 63.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+        required:
+          - pins
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pio: pinctrl at 10211000 {
+          compatible = "mediatek,mt7622-pinctrl";
+          reg = <0 0x10211000 0 0x1000>;
+          gpio-controller;
+          #gpio-cells = <2>;
+
+          pinctrl_eth_default: eth-0 {
+            mux-mdio {
+              groups = "mdc_mdio";
+              function = "eth";
+              drive-strength = <12>;
+            };
+
+            mux-gmac2 {
+              groups = "rgmii_via_gmac2";
+              function = "eth";
+              drive-strength = <12>;
+            };
+
+            mux-esw {
+              groups = "esw";
+              function = "eth";
+              drive-strength = <8>;
+            };
+
+            conf-mdio {
+              pins = "MDC";
+              bias-pull-up;
+            };
+          };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
new file mode 100644
index 0000000000000..cc1509e9b981b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
@@ -0,0 +1,228 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/mediatek,mt8183-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT8183 Pin Controller Device Tree Bindings
+
+maintainers:
+  - Sean Wang <sean.wang at kernel.org>
+
+description: |+
+  The MediaTek's MT8183 Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    const: mediatek,mt8183-pinctrl
+
+  reg:
+    minItems: 10
+    maxItems: 10
+
+  reg-names:
+    items:
+      - const: iocfg0
+      - const: iocfg1
+      - const: iocfg2
+      - const: iocfg3
+      - const: iocfg4
+      - const: iocfg5
+      - const: iocfg6
+      - const: iocfg7
+      - const: iocfg8
+      - const: eint
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO
+      binding is used, the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+
+  gpio-ranges:
+    minItems: 1
+    maxItems: 5
+    description: |
+      GPIO valid number range.
+
+  interrupt-controller: true
+
+  interrupts:
+    maxItems: 1
+
+  "#interrupt-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - gpio-controller
+  - "#gpio-cells"
+  - gpio-ranges
+
+patternProperties:
+  '-[0-9]+$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      'pins':
+        type: object
+        additionalProperties: false
+        description: |
+          A pinctrl node should contain at least one subnodes representing the
+          pinctrl groups available on the machine. Each subnode will list the
+          pins it needs, and how they should be configured, with regard to muxer
+          configuration, pullups, drive strength, input enable/disable and input
+          schmitt.
+        $ref: "/schemas/pinctrl/pincfg-node.yaml"
+
+        properties:
+          pinmux:
+            description:
+              integer array, represents gpio pin number and mux setting.
+              Supported pin number and mux varies for different SoCs, and are
+              defined as macros in <soc>-pinfunc.h directly.
+
+          bias-disable: true
+
+          bias-pull-up: true
+
+          bias-pull-down: true
+
+          input-enable: true
+
+          input-disable: true
+
+          output-low: true
+
+          output-high: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+          drive-strength:
+            enum: [2, 4, 6, 8, 10, 12, 14, 16]
+
+          mediatek,drive-strength-adv:
+            description: |
+              Describe the specific driving setup property.
+              For I2C pins, the existing generic driving setup can only support
+              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
+              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
+              driving setup, the existing generic setup will be disabled.
+              The specific driving setup is controlled by E1E0EN.
+              When E1=0/E0=0, the strength is 0.125mA.
+              When E1=0/E0=1, the strength is 0.25mA.
+              When E1=1/E0=0, the strength is 0.5mA.
+              When E1=1/E0=1, the strength is 1mA.
+              EN is used to enable or disable the specific driving setup.
+              Valid arguments are described as below:
+              0: (E1, E0, EN) = (0, 0, 0)
+              1: (E1, E0, EN) = (0, 0, 1)
+              2: (E1, E0, EN) = (0, 1, 0)
+              3: (E1, E0, EN) = (0, 1, 1)
+              4: (E1, E0, EN) = (1, 0, 0)
+              5: (E1, E0, EN) = (1, 0, 1)
+              6: (E1, E0, EN) = (1, 1, 0)
+              7: (E1, E0, EN) = (1, 1, 1)
+              So the valid arguments are from 0 to 7.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
+          mediatek,pull-up-adv:
+            description: |
+              Pull up setings for 2 pull resistors, R0 and R1. User can
+              configure those special pins. Valid arguments are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,pull-down-adv:
+            description: |
+              Pull down settings for 2 pull resistors, R0 and R1. User can
+              configure those special pins. Valid arguments are described as below:
+              0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled.
+              1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled.
+              2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled.
+              3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+          mediatek,tdsel:
+            description: |
+              An integer describing the steps for output level shifter duty
+              cycle when asserted (high pulse width adjustment). Valid arguments
+              are from 0 to 15.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+          mediatek,rdsel:
+            description: |
+              An integer describing the steps for input level shifter duty cycle
+              when asserted (high pulse width adjustment). Valid arguments are
+              from 0 to 63.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+        required:
+          - pinmux
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/mt8183-pinfunc.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pio: pinctrl at 10005000 {
+          compatible = "mediatek,mt8183-pinctrl";
+          reg = <0 0x10005000 0 0x1000>,
+                <0 0x11f20000 0 0x1000>,
+                <0 0x11e80000 0 0x1000>,
+                <0 0x11e70000 0 0x1000>,
+                <0 0x11e90000 0 0x1000>,
+                <0 0x11d30000 0 0x1000>,
+                <0 0x11d20000 0 0x1000>,
+                <0 0x11c50000 0 0x1000>,
+                <0 0x11f30000 0 0x1000>,
+                <0 0x1000b000 0 0x1000>;
+          reg-names = "iocfg0", "iocfg1", "iocfg2",
+                "iocfg3", "iocfg4", "iocfg5",
+                "iocfg6", "iocfg7", "iocfg8",
+                "eint";
+          gpio-controller;
+          #gpio-cells = <2>;
+          gpio-ranges = <&pio 0 0 192>;
+          interrupt-controller;
+          interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
+          #interrupt-cells = <2>;
+
+          i2c0_pins_a: i2c-0 {
+            pins1 {
+              pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
+                <PINMUX_GPIO49__FUNC_SDA5>;
+              mediatek,pull-up-adv = <3>;
+              mediatek,drive-strength-adv = <7>;
+            };
+          };
+
+          i2c1_pins_a: i2c-1 {
+            pins {
+              pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
+                <PINMUX_GPIO51__FUNC_SDA3>;
+              mediatek,pull-down-adv = <2>;
+              mediatek,drive-strength-adv = <4>;
+            };
+          };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
deleted file mode 100644
index 5fe2c26c28bf1..0000000000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-* Mediatek MT65XX Pin Controller
-
-The Mediatek's Pin controller is used to control SoC pins.
-
-Required properties:
-- compatible: value should be one of the following.
-	"mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl.
-	"mediatek,mt2712-pinctrl", compatible with mt2712 pinctrl.
-	"mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
-	"mediatek,mt7623-pinctrl", compatible with mt7623 pinctrl.
-	"mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
-	"mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
-	"mediatek,mt8167-pinctrl", compatible with mt8167 pinctrl.
-	"mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
-	"mediatek,mt8365-pinctrl", compatible with mt8365 pinctrl.
-	"mediatek,mt8516-pinctrl", compatible with mt8516 pinctrl.
-- pins-are-numbered: Specify the subnodes are using numbered pinmux to
-  specify pins.
-- gpio-controller : Marks the device node as a gpio controller.
-- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
-  binding is used, the amount of cells must be specified as 2. See the below
-  mentioned gpio binding representation for description of particular cells.
-
-	Eg: <&pio 6 0>
-	<[phandle of the gpio controller node]
-	[line number within the gpio controller]
-	[flags]>
-
-	Values for gpio specifier:
-	- Line number: is a value between 0 to 202.
-	- Flags:  bit field of flags, as defined in <dt-bindings/gpio/gpio.h>.
-            Only the following flags are supported:
-            0 - GPIO_ACTIVE_HIGH
-            1 - GPIO_ACTIVE_LOW
-
-Optional properties:
-- mediatek,pctl-regmap: Should be a phandle of the syscfg node.
-- reg: physicall address base for EINT registers
-- interrupt-controller: Marks the device node as an interrupt controller
-- #interrupt-cells: Should be two.
-- interrupts : The interrupt outputs from the controller.
-
-Please refer to pinctrl-bindings.txt in this directory for details of the
-common pinctrl bindings used by client devices.
-
-Subnode format
-A pinctrl node should contain at least one subnodes representing the
-pinctrl groups available on the machine. Each subnode will list the
-pins it needs, and how they should be configured, with regard to muxer
-configuration, pullups, drive strength, input enable/disable and input schmitt.
-
-    node {
-	pinmux = <PIN_NUMBER_PINMUX>;
-	GENERIC_PINCONFIG;
-    };
-
-Required properties:
-- pinmux: integer array, represents gpio pin number and mux setting.
-    Supported pin number and mux varies for different SoCs, and are defined
-    as macros in boot/dts/<soc>-pinfunc.h directly.
-
-Optional properties:
-- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
-    bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high,
-    input-schmitt-enable, input-schmitt-disable and drive-strength are valid.
-
-    Some special pins have extra pull up strength, there are R0 and R1 pull-up
-    resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11.
-    So when config bias-pull-up, it support arguments for those special pins.
-    Some macros have been defined for this usage, such as MTK_PUPD_SET_R1R0_00.
-    See dt-bindings/pinctrl/mt65xx.h.
-
-    When config drive-strength, it can support some arguments, such as
-    MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
-
-Examples:
-
-#include "mt8135-pinfunc.h"
-
-...
-{
-	syscfg_pctl_a: syscfg-pctl-a at 10005000 {
-		compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon";
-		reg = <0 0x10005000 0 0x1000>;
-	};
-
-	syscfg_pctl_b: syscfg-pctl-b at 1020c020 {
-		compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon";
-		reg = <0 0x1020C020 0 0x1000>;
-	};
-
-	pinctrl at 1c20800 {
-		compatible = "mediatek,mt8135-pinctrl";
-		reg = <0 0x1000B000 0 0x1000>;
-		mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>;
-		pins-are-numbered;
-		gpio-controller;
-		#gpio-cells = <2>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
-
-		i2c0_pins_a: i2c0 at 0 {
-			pins1 {
-				pinmux = <MT8135_PIN_100_SDA0__FUNC_SDA0>,
-					 <MT8135_PIN_101_SCL0__FUNC_SCL0>;
-				bias-disable;
-			};
-		};
-
-		i2c1_pins_a: i2c1 at 0 {
-			pins {
-				pinmux = <MT8135_PIN_195_SDA1__FUNC_SDA1>,
-					 <MT8135_PIN_196_SCL1__FUNC_SCL1>;
-				bias-pull-up = <55>;
-			};
-		};
-
-		i2c2_pins_a: i2c2 at 0 {
-			pins1 {
-				pinmux = <MT8135_PIN_193_SDA2__FUNC_SDA2>;
-				bias-pull-down;
-			};
-
-			pins2 {
-				pinmux = <MT8135_PIN_49_WATCHDOG__FUNC_GPIO49>;
-				bias-pull-up;
-			};
-		};
-
-		i2c3_pins_a: i2c3 at 0 {
-			pins1 {
-				pinmux = <MT8135_PIN_40_DAC_CLK__FUNC_GPIO40>,
-					 <MT8135_PIN_41_DAC_WS__FUNC_GPIO41>;
-				bias-pull-up = <55>;
-			};
-
-			pins2 {
-				pinmux = <MT8135_PIN_35_SCL3__FUNC_SCL3>,
-					 <MT8135_PIN_36_SDA3__FUNC_SDA3>;
-				output-low;
-				bias-pull-up = <55>;
-			};
-
-			pins3 {
-				pinmux = <MT8135_PIN_57_JTCK__FUNC_GPIO57>,
-					 <MT8135_PIN_60_JTDI__FUNC_JTDI>;
-				drive-strength = <32>;
-			};
-		};
-
-		...
-	}
-};
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
deleted file mode 100644
index bd83401e6179a..0000000000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-* MediaTek MT6797 Pin Controller
-
-The MediaTek's MT6797 Pin controller is used to control SoC pins.
-
-Required properties:
-- compatible: Value should be one of the following.
-              "mediatek,mt6797-pinctrl", compatible with mt6797 pinctrl.
-- reg:        Should contain address and size for gpio, iocfgl, iocfgb,
-              iocfgr and iocfgt register bases.
-- reg-names:  An array of strings describing the "reg" entries. Must
-              contain "gpio", "iocfgl", "iocfgb", "iocfgr", "iocfgt".
-- gpio-controller: Marks the device node as a gpio controller.
-- #gpio-cells: Should be two. The first cell is the gpio pin number
-               and the second cell is used for optional parameters.
-
-Optional properties:
-- interrupt-controller: Marks the device node as an interrupt controller.
-- #interrupt-cells: Should be two.
-- interrupts : The interrupt outputs from the controller.
-
-Please refer to pinctrl-bindings.txt in this directory for details of the
-common pinctrl bindings used by client devices.
-
-Subnode format
-A pinctrl node should contain at least one subnodes representing the
-pinctrl groups available on the machine. Each subnode will list the
-pins it needs, and how they should be configured, with regard to muxer
-configuration, pullups, drive strength, input enable/disable and input schmitt.
-
-    node {
-        pinmux = <PIN_NUMBER_PINMUX>;
-        GENERIC_PINCONFIG;
-    };
-
-Required properties:
-- pinmux: Integer array, represents gpio pin number and mux setting.
-    Supported pin number and mux varies for different SoCs, and are defined
-    as macros in dt-bindings/pinctrl/<soc>-pinfunc.h directly.
-
-Optional properties:
-- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
-    bias-pull, bias-pull-down, input-enable, input-schmitt-enable,
-    input-schmitt-disable, output-enable output-low, output-high,
-    drive-strength, and slew-rate are valid.
-
-    Valid arguments for 'slew-rate' are '0' for no slew rate controlled and
-    '1' for slower slew rate respectively. Valid arguments for 'drive-strength'
-    is limited, such as 2, 4, 8, 12, or 16 in mA.
-
-    Some optional vendor properties as defined are valid to specify in a
-    pinconf subnode:
-    - mediatek,tdsel: An integer describing the steps for output level shifter
-      duty cycle when asserted (high pulse width adjustment). Valid arguments
-      are from 0 to 15.
-    - mediatek,rdsel: An integer describing the steps for input level shifter
-      duty cycle when asserted (high pulse width adjustment). Valid arguments
-      are from 0 to 63.
-    - mediatek,pull-up-adv: An integer describing the code R1R0 as 0, 1, 2
-      or 3 for the advanced pull-up resistors.
-    - mediatek,pull-down-adv: An integer describing the code R1R0 as 0, 1, 2,
-      or 3 for the advanced pull-down resistors.
-
-Examples:
-
-        pio: pinctrl at 10005000 {
-                compatible = "mediatek,mt6797-pinctrl";
-                reg = <0 0x10005000 0 0x1000>,
-                      <0 0x10002000 0 0x400>,
-                      <0 0x10002400 0 0x400>,
-                      <0 0x10002800 0 0x400>,
-                      <0 0x10002C00 0 0x400>;
-                reg-names = "gpio", "iocfgl", "iocfgb",
-                            "iocfgr", "iocfgt";
-                gpio-controller;
-                #gpio-cells = <2>;
-
-                uart1_pins_a: uart1 {
-                        pins1 {
-                                pinmux = <MT6797_GPIO232__FUNC_URXD1>,
-                                         <MT6797_GPIO233__FUNC_UTXD1>;
-                        };
-                };
-        };
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
deleted file mode 100644
index 7a7aca1ed705b..0000000000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+++ /dev/null
@@ -1,490 +0,0 @@
-== MediaTek MT7622 pinctrl controller ==
-
-Required properties for the root node:
- - compatible: Should be one of the following
-	       "mediatek,mt7622-pinctrl" for MT7622 SoC
-	       "mediatek,mt7629-pinctrl" for MT7629 SoC
- - reg: offset and length of the pinctrl space
-
- - gpio-controller: Marks the device node as a GPIO controller.
- - #gpio-cells: Should be two. The first cell is the pin number and the
-   second is the GPIO flags.
-
-Optional properties:
-- interrupt-controller  : Marks the device node as an interrupt controller
-
-If the property interrupt-controller is defined, following property is required
-- reg-names: A string describing the "reg" entries. Must contain "eint".
-- interrupts : The interrupt output from the controller.
-- #interrupt-cells: Should be two.
-
-Please refer to pinctrl-bindings.txt in this directory for details of the
-common pinctrl bindings used by client devices, including the meaning of the
-phrase "pin configuration node".
-
-MT7622 pin configuration nodes act as a container for an arbitrary number of
-subnodes. Each of these subnodes represents some desired configuration for a
-pin, a group, or a list of pins or groups. This configuration can include the
-mux function to select on those pin(s)/group(s), and various pin configuration
-parameters, such as pull-up, slew rate, etc.
-
-We support 2 types of configuration nodes. Those nodes can be either pinmux
-nodes or pinconf nodes. Each configuration node can consist of multiple nodes
-describing the pinmux and pinconf options.
-
-The name of each subnode doesn't matter as long as it is unique; all subnodes
-should be enumerated and processed purely based on their content.
-
-== pinmux nodes content ==
-
-The following generic properties as defined in pinctrl-bindings.txt are valid
-to specify in a pinmux subnode:
-
-Required properties are:
- - groups: An array of strings. Each string contains the name of a group.
-  Valid values for these names are listed below.
- - function: A string containing the name of the function to mux to the
-  group. Valid values for function names are listed below.
-
-== pinconf nodes content ==
-
-The following generic properties as defined in pinctrl-bindings.txt are valid
-to specify in a pinconf subnode:
-
-Required properties are:
- - pins: An array of strings. Each string contains the name of a pin.
-  Valid values for these names are listed below.
- - groups: An array of strings. Each string contains the name of a group.
-  Valid values for these names are listed below.
-
-Optional properies are:
- bias-disable, bias-pull, bias-pull-down, input-enable,
- input-schmitt-enable, input-schmitt-disable, output-enable
- output-low, output-high, drive-strength, slew-rate
-
- Valid arguments for 'slew-rate' are '0' for no slew rate controlled and '1' for
- slower slew rate respectively.
- Valid arguments for 'drive-strength', 4, 8, 12, or 16 in mA.
-
-The following specific properties as defined are valid to specify in a pinconf
-subnode:
-
-Optional properties are:
- - mediatek,tdsel: An integer describing the steps for output level shifter duty
-   cycle when asserted (high pulse width adjustment). Valid arguments are from 0
-   to 15.
- - mediatek,rdsel: An integer describing the steps for input level shifter duty
-   cycle when asserted (high pulse width adjustment). Valid arguments are from 0
-   to 63.
-
-== Valid values for pins, function and groups on MT7622 ==
-
-Valid values for pins are:
-pins can be referenced via the pin names as the below table shown and the
-related physical number is also put ahead of those names which helps cross
-references to pins between groups to know whether pins assignment conflict
-happens among devices try to acquire those available pins.
-
-	Pin #:  Valid values for pins
-	-----------------------------
-	PIN 0: "GPIO_A"
-	PIN 1: "I2S1_IN"
-	PIN 2: "I2S1_OUT"
-	PIN 3: "I2S_BCLK"
-	PIN 4: "I2S_WS"
-	PIN 5: "I2S_MCLK"
-	PIN 6: "TXD0"
-	PIN 7: "RXD0"
-	PIN 8: "SPI_WP"
-	PIN 9: "SPI_HOLD"
-	PIN 10: "SPI_CLK"
-	PIN 11: "SPI_MOSI"
-	PIN 12: "SPI_MISO"
-	PIN 13: "SPI_CS"
-	PIN 14: "I2C_SDA"
-	PIN 15: "I2C_SCL"
-	PIN 16: "I2S2_IN"
-	PIN 17: "I2S3_IN"
-	PIN 18: "I2S4_IN"
-	PIN 19: "I2S2_OUT"
-	PIN 20: "I2S3_OUT"
-	PIN 21: "I2S4_OUT"
-	PIN 22: "GPIO_B"
-	PIN 23: "MDC"
-	PIN 24: "MDIO"
-	PIN 25: "G2_TXD0"
-	PIN 26: "G2_TXD1"
-	PIN 27: "G2_TXD2"
-	PIN 28: "G2_TXD3"
-	PIN 29: "G2_TXEN"
-	PIN 30: "G2_TXC"
-	PIN 31: "G2_RXD0"
-	PIN 32: "G2_RXD1"
-	PIN 33: "G2_RXD2"
-	PIN 34: "G2_RXD3"
-	PIN 35: "G2_RXDV"
-	PIN 36: "G2_RXC"
-	PIN 37: "NCEB"
-	PIN 38: "NWEB"
-	PIN 39: "NREB"
-	PIN 40: "NDL4"
-	PIN 41: "NDL5"
-	PIN 42: "NDL6"
-	PIN 43: "NDL7"
-	PIN 44: "NRB"
-	PIN 45: "NCLE"
-	PIN 46: "NALE"
-	PIN 47: "NDL0"
-	PIN 48: "NDL1"
-	PIN 49: "NDL2"
-	PIN 50: "NDL3"
-	PIN 51: "MDI_TP_P0"
-	PIN 52: "MDI_TN_P0"
-	PIN 53: "MDI_RP_P0"
-	PIN 54: "MDI_RN_P0"
-	PIN 55: "MDI_TP_P1"
-	PIN 56: "MDI_TN_P1"
-	PIN 57: "MDI_RP_P1"
-	PIN 58: "MDI_RN_P1"
-	PIN 59: "MDI_RP_P2"
-	PIN 60: "MDI_RN_P2"
-	PIN 61: "MDI_TP_P2"
-	PIN 62: "MDI_TN_P2"
-	PIN 63: "MDI_TP_P3"
-	PIN 64: "MDI_TN_P3"
-	PIN 65: "MDI_RP_P3"
-	PIN 66: "MDI_RN_P3"
-	PIN 67: "MDI_RP_P4"
-	PIN 68: "MDI_RN_P4"
-	PIN 69: "MDI_TP_P4"
-	PIN 70: "MDI_TN_P4"
-	PIN 71: "PMIC_SCL"
-	PIN 72: "PMIC_SDA"
-	PIN 73: "SPIC1_CLK"
-	PIN 74: "SPIC1_MOSI"
-	PIN 75: "SPIC1_MISO"
-	PIN 76: "SPIC1_CS"
-	PIN 77: "GPIO_D"
-	PIN 78: "WATCHDOG"
-	PIN 79: "RTS3_N"
-	PIN 80: "CTS3_N"
-	PIN 81: "TXD3"
-	PIN 82: "RXD3"
-	PIN 83: "PERST0_N"
-	PIN 84: "PERST1_N"
-	PIN 85: "WLED_N"
-	PIN 86: "EPHY_LED0_N"
-	PIN 87: "AUXIN0"
-	PIN 88: "AUXIN1"
-	PIN 89: "AUXIN2"
-	PIN 90: "AUXIN3"
-	PIN 91: "TXD4"
-	PIN 92: "RXD4"
-	PIN 93: "RTS4_N"
-	PIN 94: "CST4_N"
-	PIN 95: "PWM1"
-	PIN 96: "PWM2"
-	PIN 97: "PWM3"
-	PIN 98: "PWM4"
-	PIN 99: "PWM5"
-	PIN 100: "PWM6"
-	PIN 101: "PWM7"
-	PIN 102: "GPIO_E"
-
-Valid values for function are:
-	"emmc", "eth", "i2c", "i2s", "ir", "led", "flash", "pcie",
-	"pmic", "pwm", "sd", "spi", "tdm", "uart", "watchdog"
-
-Valid values for groups are:
-additional data is put followingly with valid value allowing us to know which
-applicable function and which relevant pins (in pin#) are able applied for that
-group.
-
-	Valid value			function	pins (in pin#)
-	-------------------------------------------------------------------------
-	"emmc"				"emmc"		40, 41, 42, 43, 44, 45,
-							47, 48, 49, 50
-	"emmc_rst"			"emmc"		37
-	"esw"				"eth"		51, 52, 53, 54, 55, 56,
-							57, 58, 59, 60, 61, 62,
-							63, 64, 65, 66, 67, 68,
-							69, 70
-	"esw_p0_p1"			"eth"		51, 52, 53, 54, 55, 56,
-							57, 58
-	"esw_p2_p3_p4"			"eth"		59, 60, 61, 62, 63, 64,
-							65, 66, 67, 68, 69, 70
-	"rgmii_via_esw"			"eth"		59, 60, 61, 62, 63, 64,
-							65, 66, 67, 68, 69, 70
-	"rgmii_via_gmac1"		"eth"		59, 60, 61, 62, 63, 64,
-							65, 66, 67, 68, 69, 70
-	"rgmii_via_gmac2"		"eth"		25, 26, 27, 28, 29, 30,
-							31, 32, 33, 34, 35, 36
-	"mdc_mdio"			"eth"		23, 24
-	"i2c0"				"i2c"		14, 15
-	"i2c1_0"			"i2c"		55, 56
-	"i2c1_1"			"i2c"		73, 74
-	"i2c1_2"			"i2c"		87, 88
-	"i2c2_0"			"i2c"		57, 58
-	"i2c2_1"			"i2c"		75, 76
-	"i2c2_2"			"i2c"		89, 90
-	"i2s_in_mclk_bclk_ws"		"i2s"		3, 4, 5
-	"i2s1_in_data"			"i2s"		1
-	"i2s2_in_data"			"i2s"		16
-	"i2s3_in_data"			"i2s"		17
-	"i2s4_in_data"			"i2s"		18
-	"i2s_out_mclk_bclk_ws"		"i2s"		3, 4, 5
-	"i2s1_out_data"			"i2s"		2
-	"i2s2_out_data"			"i2s"		19
-	"i2s3_out_data"			"i2s"		20
-	"i2s4_out_data"			"i2s"		21
-	"ir_0_tx"			"ir"		16
-	"ir_1_tx"			"ir"		59
-	"ir_2_tx"			"ir"		99
-	"ir_0_rx"			"ir"		17
-	"ir_1_rx"			"ir"		60
-	"ir_2_rx"			"ir"		100
-	"ephy_leds"			"led"		86, 91, 92, 93, 94
-	"ephy0_led"			"led"		86
-	"ephy1_led"			"led"		91
-	"ephy2_led"			"led"		92
-	"ephy3_led"			"led"		93
-	"ephy4_led"			"led"		94
-	"wled"				"led"		85
-	"par_nand"			"flash"		37, 38, 39, 40, 41, 42,
-							43, 44, 45, 46, 47, 48,
-							49, 50
-	"snfi"				"flash"		8, 9, 10, 11, 12, 13
-	"spi_nor"			"flash"		8, 9, 10, 11, 12, 13
-	"pcie0_0_waken"			"pcie"		14
-	"pcie0_1_waken"			"pcie"		79
-	"pcie1_0_waken"			"pcie"		14
-	"pcie0_0_clkreq"		"pcie"		15
-	"pcie0_1_clkreq"		"pcie"		80
-	"pcie1_0_clkreq"		"pcie"		15
-	"pcie0_pad_perst"		"pcie"		83
-	"pcie1_pad_perst"		"pcie"		84
-	"pmic_bus"			"pmic"		71, 72
-	"pwm_ch1_0"			"pwm"		51
-	"pwm_ch1_1"			"pwm"		73
-	"pwm_ch1_2"			"pwm"		95
-	"pwm_ch2_0"			"pwm"		52
-	"pwm_ch2_1"			"pwm"		74
-	"pwm_ch2_2"			"pwm"		96
-	"pwm_ch3_0"			"pwm"		53
-	"pwm_ch3_1"			"pwm"		75
-	"pwm_ch3_2"			"pwm"		97
-	"pwm_ch4_0"			"pwm"		54
-	"pwm_ch4_1"			"pwm"		67
-	"pwm_ch4_2"			"pwm"		76
-	"pwm_ch4_3"			"pwm"		98
-	"pwm_ch5_0"			"pwm"		68
-	"pwm_ch5_1"			"pwm"		77
-	"pwm_ch5_2"			"pwm"		99
-	"pwm_ch6_0"			"pwm"		69
-	"pwm_ch6_1"			"pwm"		78
-	"pwm_ch6_2"			"pwm"		81
-	"pwm_ch6_3"			"pwm"		100
-	"pwm_ch7_0"			"pwm"		70
-	"pwm_ch7_1"			"pwm"		82
-	"pwm_ch7_2"			"pwm"		101
-	"sd_0"				"sd"		16, 17, 18, 19, 20, 21
-	"sd_1"				"sd"		25, 26, 27, 28, 29, 30
-	"spic0_0"			"spi"		63, 64, 65, 66
-	"spic0_1"			"spi"		79, 80, 81, 82
-	"spic1_0"			"spi"		67, 68, 69, 70
-	"spic1_1"			"spi"		73, 74, 75, 76
-	"spic2_0_wp_hold"		"spi"		8, 9
-	"spic2_0"			"spi"		10, 11, 12, 13
-	"tdm_0_out_mclk_bclk_ws"	"tdm"		8, 9, 10
-	"tdm_0_in_mclk_bclk_ws"		"tdm"		11, 12, 13
-	"tdm_0_out_data"		"tdm"		20
-	"tdm_0_in_data"			"tdm"		21
-	"tdm_1_out_mclk_bclk_ws"	"tdm"		57, 58, 59
-	"tdm_1_in_mclk_bclk_ws"		"tdm"		60, 61, 62
-	"tdm_1_out_data"		"tdm"		55
-	"tdm_1_in_data"			"tdm"		56
-	"uart0_0_tx_rx"			"uart"		6, 7
-	"uart1_0_tx_rx"			"uart"		55, 56
-	"uart1_0_rts_cts"		"uart"		57, 58
-	"uart1_1_tx_rx"			"uart"		73, 74
-	"uart1_1_rts_cts"		"uart"		75, 76
-	"uart2_0_tx_rx"			"uart"		3, 4
-	"uart2_0_rts_cts"		"uart"		1, 2
-	"uart2_1_tx_rx"			"uart"		51, 52
-	"uart2_1_rts_cts"		"uart"		53, 54
-	"uart2_2_tx_rx"			"uart"		59, 60
-	"uart2_2_rts_cts"		"uart"		61, 62
-	"uart2_3_tx_rx"			"uart"		95, 96
-	"uart3_0_tx_rx"			"uart"		57, 58
-	"uart3_1_tx_rx"			"uart"		81, 82
-	"uart3_1_rts_cts"		"uart"		79, 80
-	"uart4_0_tx_rx"			"uart"		61, 62
-	"uart4_1_tx_rx"			"uart"		91, 92
-	"uart4_1_rts_cts"		"uart"		93, 94
-	"uart4_2_tx_rx"			"uart"		97, 98
-	"uart4_2_rts_cts"		"uart"		95, 96
-	"watchdog"			"watchdog"	78
-
-
-== Valid values for pins, function and groups on MT7629 ==
-
-	Pin #:  Valid values for pins
-	-----------------------------
-	PIN 0: "TOP_5G_CLK"
-	PIN 1: "TOP_5G_DATA"
-	PIN 2: "WF0_5G_HB0"
-	PIN 3: "WF0_5G_HB1"
-	PIN 4: "WF0_5G_HB2"
-	PIN 5: "WF0_5G_HB3"
-	PIN 6: "WF0_5G_HB4"
-	PIN 7: "WF0_5G_HB5"
-	PIN 8: "WF0_5G_HB6"
-	PIN 9: "XO_REQ"
-	PIN 10: "TOP_RST_N"
-	PIN 11: "SYS_WATCHDOG"
-	PIN 12: "EPHY_LED0_N_JTDO"
-	PIN 13: "EPHY_LED1_N_JTDI"
-	PIN 14: "EPHY_LED2_N_JTMS"
-	PIN 15: "EPHY_LED3_N_JTCLK"
-	PIN 16: "EPHY_LED4_N_JTRST_N"
-	PIN 17: "WF2G_LED_N"
-	PIN 18: "WF5G_LED_N"
-	PIN 19: "I2C_SDA"
-	PIN 20: "I2C_SCL"
-	PIN 21: "GPIO_9"
-	PIN 22: "GPIO_10"
-	PIN 23: "GPIO_11"
-	PIN 24: "GPIO_12"
-	PIN 25: "UART1_TXD"
-	PIN 26: "UART1_RXD"
-	PIN 27: "UART1_CTS"
-	PIN 28: "UART1_RTS"
-	PIN 29: "UART2_TXD"
-	PIN 30: "UART2_RXD"
-	PIN 31: "UART2_CTS"
-	PIN 32: "UART2_RTS"
-	PIN 33: "MDI_TP_P1"
-	PIN 34: "MDI_TN_P1"
-	PIN 35: "MDI_RP_P1"
-	PIN 36: "MDI_RN_P1"
-	PIN 37: "MDI_RP_P2"
-	PIN 38: "MDI_RN_P2"
-	PIN 39: "MDI_TP_P2"
-	PIN 40: "MDI_TN_P2"
-	PIN 41: "MDI_TP_P3"
-	PIN 42: "MDI_TN_P3"
-	PIN 43: "MDI_RP_P3"
-	PIN 44: "MDI_RN_P3"
-	PIN 45: "MDI_RP_P4"
-	PIN 46: "MDI_RN_P4"
-	PIN 47: "MDI_TP_P4"
-	PIN 48: "MDI_TN_P4"
-	PIN 49: "SMI_MDC"
-	PIN 50: "SMI_MDIO"
-	PIN 51: "PCIE_PERESET_N"
-	PIN 52: "PWM_0"
-	PIN 53: "GPIO_0"
-	PIN 54: "GPIO_1"
-	PIN 55: "GPIO_2"
-	PIN 56: "GPIO_3"
-	PIN 57: "GPIO_4"
-	PIN 58: "GPIO_5"
-	PIN 59: "GPIO_6"
-	PIN 60: "GPIO_7"
-	PIN 61: "GPIO_8"
-	PIN 62: "SPI_CLK"
-	PIN 63: "SPI_CS"
-	PIN 64: "SPI_MOSI"
-	PIN 65: "SPI_MISO"
-	PIN 66: "SPI_WP"
-	PIN 67: "SPI_HOLD"
-	PIN 68: "UART0_TXD"
-	PIN 69: "UART0_RXD"
-	PIN 70: "TOP_2G_CLK"
-	PIN 71: "TOP_2G_DATA"
-	PIN 72: "WF0_2G_HB0"
-	PIN 73: "WF0_2G_HB1"
-	PIN 74: "WF0_2G_HB2"
-	PIN 75: "WF0_2G_HB3"
-	PIN 76: "WF0_2G_HB4"
-	PIN 77: "WF0_2G_HB5"
-	PIN 78: "WF0_2G_HB6"
-
-Valid values for function are:
-	"eth", "i2c", "led", "flash", "pcie", "pwm", "spi", "uart",
-	"watchdog", "wifi"
-
-Valid values for groups are:
-	Valid value			function	pins (in pin#)
-	----------------------------------------------------------------
-	"mdc_mdio"			"eth"		23, 24
-	"i2c_0"				"i2c"		19, 20
-	"i2c_1"				"i2c"		53, 54
-	"ephy_leds"			"led"		12, 13, 14, 15, 16,
-							17, 18
-	"ephy0_led"			"led"		12
-	"ephy1_led"			"led"		13
-	"ephy2_led"			"led"		14
-	"ephy3_led"			"led"		15
-	"ephy4_led"			"led"		16
-	"wf2g_led"			"led"		17
-	"wf5g_led"			"led"		18
-	"snfi"				"flash"		62, 63, 64, 65, 66, 67
-	"spi_nor"			"flash"		62, 63, 64, 65, 66, 67
-	"pcie_pereset"			"pcie"		51
-	"pcie_wake"			"pcie"		55
-	"pcie_clkreq"			"pcie"		56
-	"pwm_0"				"pwm"		52
-	"pwm_1"				"pwm"		61
-	"spi_0"				"spi"		21, 22, 23, 24
-	"spi_1"				"spi"		62, 63, 64, 65
-	"spi_wp"			"spi"		66
-	"spi_hold"			"spi"		67
-	"uart0_txd_rxd"			"uart"		68, 69
-	"uart1_0_txd_rxd"		"uart"		25, 26
-	"uart1_0_cts_rts"		"uart"		27, 28
-	"uart1_1_txd_rxd"		"uart"		53, 54
-	"uart1_1_cts_rts"		"uart"		55, 56
-	"uart2_0_txd_rxd"		"uart"		29, 30
-	"uart2_0_cts_rts"		"uart"		31, 32
-	"uart2_1_txd_rxd"		"uart"		57, 58
-	"uart2_1_cts_rts"		"uart"		59, 60
-	"watchdog"			"watchdog"	11
-	"wf0_2g"			"wifi"		70, 71, 72, 73, 74,
-							75, 76, 77, 78
-	"wf0_5g"			"wifi"		0, 1, 2, 3, 4, 5, 6,
-							7, 8, 9, 10
-
-Example:
-
-	pio: pinctrl at 10211000 {
-		compatible = "mediatek,mt7622-pinctrl";
-		reg = <0 0x10211000 0 0x1000>;
-		gpio-controller;
-		#gpio-cells = <2>;
-
-		pinctrl_eth_default: eth-default {
-			mux-mdio {
-				groups = "mdc_mdio";
-				function = "eth";
-				drive-strength = <12>;
-			};
-
-			mux-gmac2 {
-				groups = "gmac2";
-				function = "eth";
-				drive-strength = <12>;
-			};
-
-			mux-esw {
-				groups = "esw";
-				function = "eth";
-				drive-strength = <8>;
-			};
-
-			conf-mdio {
-				pins = "MDC";
-				bias-pull-up;
-			};
-		};
-	};
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
deleted file mode 100644
index eccbe3f55d3f3..0000000000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-* Mediatek MT8183 Pin Controller
-
-The Mediatek's Pin controller is used to control SoC pins.
-
-Required properties:
-- compatible: value should be one of the following.
-	"mediatek,mt8183-pinctrl", compatible with mt8183 pinctrl.
-- gpio-controller : Marks the device node as a gpio controller.
-- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
-  binding is used, the amount of cells must be specified as 2. See the below
-  mentioned gpio binding representation for description of particular cells.
-- gpio-ranges : gpio valid number range.
-- reg: physical address base for gpio base registers. There are 10 GPIO
-  physical address base in mt8183.
-
-Optional properties:
-- reg-names: gpio base register names. There are 10 gpio base register
-  names in mt8183. They are "iocfg0", "iocfg1", "iocfg2", "iocfg3", "iocfg4",
-  "iocfg5", "iocfg6", "iocfg7", "iocfg8", "eint".
-- interrupt-controller: Marks the device node as an interrupt controller
-- #interrupt-cells: Should be two.
-- interrupts : The interrupt outputs to sysirq.
-
-Please refer to pinctrl-bindings.txt in this directory for details of the
-common pinctrl bindings used by client devices.
-
-Subnode format
-A pinctrl node should contain at least one subnodes representing the
-pinctrl groups available on the machine. Each subnode will list the
-pins it needs, and how they should be configured, with regard to muxer
-configuration, pullups, drive strength, input enable/disable and input schmitt.
-
-    node {
-	pinmux = <PIN_NUMBER_PINMUX>;
-	GENERIC_PINCONFIG;
-    };
-
-Required properties:
-- pinmux: integer array, represents gpio pin number and mux setting.
-    Supported pin number and mux varies for different SoCs, and are defined
-    as macros in boot/dts/<soc>-pinfunc.h directly.
-
-Optional properties:
-- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable,
-    bias-pull-down, bias-pull-up, input-enable, input-disable, output-low,
-    output-high, input-schmitt-enable, input-schmitt-disable
-    and drive-strength are valid.
-
-    Some special pins have extra pull up strength, there are R0 and R1 pull-up
-    resistors available, but for user, it's only need to set R1R0 as 00, 01,
-    10 or 11. So It needs config "mediatek,pull-up-adv" or
-    "mediatek,pull-down-adv" to support arguments for those special pins.
-    Valid arguments are from 0 to 3.
-
-    mediatek,tdsel: An integer describing the steps for output level shifter
-      duty cycle when asserted (high pulse width adjustment). Valid arguments
-      are from 0 to 15.
-    mediatek,rdsel: An integer describing the steps for input level shifter
-      duty cycle when asserted (high pulse width adjustment). Valid arguments
-      are from 0 to 63.
-
-    When config drive-strength, it can support some arguments, such as
-    MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h.
-    It can only support 2/4/6/8/10/12/14/16mA in mt8183.
-    For I2C pins, there are existing generic driving setup and the specific
-    driving setup. I2C pins can only support 2/4/6/8/10/12/14/16mA driving
-    adjustment in generic driving setup. But in specific driving setup,
-    they can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
-    driving setup for I2C pins, the existing generic driving setup will be
-    disabled. For some special features, we need the I2C pins specific
-    driving setup. The specific driving setup is controlled by E1E0EN.
-    So we need add extra vendor driving preperty instead of
-    the generic driving property.
-    We can add "mediatek,drive-strength-adv = <XXX>;" to describe the specific
-    driving setup property. "XXX" means the value of E1E0EN. EN is 0 or 1.
-    It is used to enable or disable the specific driving setup.
-    E1E0 is used to describe the detail strength specification of the I2C pin.
-    When E1=0/E0=0, the strength is 0.125mA.
-    When E1=0/E0=1, the strength is 0.25mA.
-    When E1=1/E0=0, the strength is 0.5mA.
-    When E1=1/E0=1, the strength is 1mA.
-    So the valid arguments of "mediatek,drive-strength-adv" are from 0 to 7.
-
-Examples:
-
-#include "mt8183-pinfunc.h"
-
-...
-{
-	pio: pinctrl at 10005000 {
-		compatible = "mediatek,mt8183-pinctrl";
-		reg = <0 0x10005000 0 0x1000>,
-		      <0 0x11f20000 0 0x1000>,
-		      <0 0x11e80000 0 0x1000>,
-		      <0 0x11e70000 0 0x1000>,
-		      <0 0x11e90000 0 0x1000>,
-		      <0 0x11d30000 0 0x1000>,
-		      <0 0x11d20000 0 0x1000>,
-		      <0 0x11c50000 0 0x1000>,
-		      <0 0x11f30000 0 0x1000>,
-		      <0 0x1000b000 0 0x1000>;
-		reg-names = "iocfg0", "iocfg1", "iocfg2",
-			    "iocfg3", "iocfg4", "iocfg5",
-			    "iocfg6", "iocfg7", "iocfg8",
-			    "eint";
-		gpio-controller;
-		#gpio-cells = <2>;
-		gpio-ranges = <&pio 0 0 192>;
-		interrupt-controller;
-		interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>;
-		#interrupt-cells = <2>;
-
-		i2c0_pins_a: i2c0 {
-			pins1 {
-				pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
-					 <PINMUX_GPIO49__FUNC_SDA5>;
-				mediatek,pull-up-adv = <3>;
-				mediatek,drive-strength-adv = <7>;
-			};
-		};
-
-		i2c1_pins_a: i2c1 {
-			pins {
-				pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
-					 <PINMUX_GPIO51__FUNC_SDA3>;
-				mediatek,pull-down-adv = <2>;
-				mediatek,drive-strength-adv = <4>;
-			};
-		};
-		...
-	};
-};
diff --git a/MAINTAINERS b/MAINTAINERS
index 50df0c02ba030..c957c8841043b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14667,8 +14667,10 @@ PIN CONTROLLER - MEDIATEK
 M:	Sean Wang <sean.wang at kernel.org>
 L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
-F:	Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
-F:	Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+F:	Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
+F:	Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml
+F:	Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
+F:	Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
 F:	drivers/pinctrl/mediatek/
 
 PIN CONTROLLER - MICROCHIP AT91
-- 
2.32.0.554.ge1b32706d8-goog



From andrew at aj.id.au  Tue Aug  3 21:55:29 2021
From: andrew at aj.id.au (Andrew Jeffery)
Date: Wed, 04 Aug 2021 14:25:29 +0930
Subject: [RFC PATCH 0/6] leds: Fix pca955x GPIO pin mappings
In-Reply-To: <CAHp75Ve-6zKE9UX+LR022cGAA6xvd8CeLnnKE_fT3snnzmNusA@mail.gmail.com>
References: <20210723075858.376378-1-andrew@aj.id.au>
 <CAHp75VeQML7njMZ6x8kC-ZJVexC1xJ6n1cB3JneVMAVfuOJgWw@mail.gmail.com>
 <d019990e-a725-4ef5-bb54-aadee9d18b86@www.fastmail.com>
 <CAHp75Vc2W+WmwNj1AvH6EiT_80c+5gADV9QzK+asHxpd1Ucppw@mail.gmail.com>
 <6cc64039-f82a-4c1e-ad2c-16fad7aa3178@www.fastmail.com>
 <CAHp75Vdx9QA7dmSWK8GHxBBxP0uYjrz=Gm=75yqaWbBX6k3v=w@mail.gmail.com>
 <50aaf381-8cda-4656-9222-f23fda75d3bc@www.fastmail.com>
 <CAHp75Ve-6zKE9UX+LR022cGAA6xvd8CeLnnKE_fT3snnzmNusA@mail.gmail.com>
Message-ID: <7c20e892-1675-47b6-874f-5e42e7bd73ef@www.fastmail.com>



On Tue, 3 Aug 2021, at 20:03, Andy Shevchenko wrote:
> On Tue, Aug 3, 2021 at 7:07 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> > On Thu, 29 Jul 2021, at 17:10, Andy Shevchenko wrote:
> > > On Thu, Jul 29, 2021 at 3:39 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> > > > On Wed, 28 Jul 2021, at 18:43, Andy Shevchenko wrote:
> > > > > On Wed, Jul 28, 2021 at 8:43 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> > > > > > However, userspace would never have
> > > > > > got the results it expected with the existing driver implementation, so
> > > > > > I guess you could argue that no such (useful) userspace exists. Given
> > > > > > that, we could adopt the strategy of always defining a gpiochip
> > > > > > covering the whole pin space, and parts of the devicetree binding just
> > > > > > become redundant.
> > > > >
> > > > > I'm lost now. GPIO has its own userspace ABI, how does it work right
> > > > > now in application to this chip?
> > > >
> > > > As above, it "works" if the GPIOs specified in the devicetree are
> > > > contiguous from line 0. It's broken if they're not.
> > >
> > > So, "it never works" means there is no bug. Now, what we need is to
> > > keep the same enumeration scheme, but if you wish to be used half/half
> > > (or any other ratio), the driver should do like the above mentioned
> > > PWM, i.e. register entire space and depending on the requestor either
> > > proceed with a line or mark it as BUSY.
> > >
> > > Ideally, looking into what the chip can do, this should be indeed
> > > converted to some like pin control + PWM + LED + GPIO drivers. Then
> > > the function in pin mux configuration can show what exactly is enabled
> > > on the certain line(s).
> >
> > So just to clarify, you want both solutions here?
> >
> > 1. A gpiochip that covers the entire pin space
> > 2. A pinmux implementation that manages pin allocation to the different drivers
> >
> > In that case we can largely leave this series as is? We only need to
> > adjust how we configure the gpiochip by dropping the pin-mapping
> > implementation?
> 
> Nope. It's far from what I think of. Re-reading again your cover
> letter it points out that pin mux per se does not exist in the
> hardware. In this case things become a bit too complicated, but we
> still may manage to handle them. Before I was thinking about this
> hierarchy
> 
> 1. pinmux driver (which is actually the main driver here)
> 2. LED driver (using regmap API)
> 3. GPIO driver (via gpio-regmap)
> 4. PWM driver.

Okay - I need to look at gpio-regmap, this wasn't something I was aware 
of.

> 
> Now what we need here is some kind of "virtual" pinmux. Do I
> understand correctly?

Possibly. My thoughts went to pinctrl as part of its job is mutual 
exclusion *and* pin mapping, plus we get the nice debugfs interface 
with the pin allocation details. The need for pin mapping came from 
trying to stay true to the intent of the existing devicetree binding. 
If we throw that out and have the gpiochip cover the pin space for the 
chip then using pinctrl only gives us mutual exclusion and the debugfs 
interface. pinctrl seems pretty heavy-weight to use *just* for mutual 
exclusion - with no requirement for pin mapping I feel whether or not 
we go this way hinges on the utility of debugfs.

As outlined earlier, there's no mux hardware, the only thing that 
changes is software's intent.

> 
> To be clear: I do not like putting everything into one driver when the
> logical parts may be separated.

Right, its already a bit unwieldy.

Andrew


From wangkefeng.wang at huawei.com  Tue Aug  3 22:01:46 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 4 Aug 2021 13:01:46 +0800
Subject: [PATCH v3] lib: Use PFN_PHYS() in devmem_is_allowed()
In-Reply-To: <20210731025057.78825-1-wangliang101@huawei.com>
References: <20210731025057.78825-1-wangliang101@huawei.com>
Message-ID: <668986ec-bdc5-482f-39ed-8e059008016d@huawei.com>


On 2021/7/31 10:50, Liang Wang wrote:
> The physical address may exceed 32 bits on 32-bit systems with
> more than 32 bits of physcial address,use PFN_PHYS() in devmem_is_allowed(),
> or the physical address may overflow and be truncated.
> We found this bug when mapping a high addresses through devmem tool,
> when CONFIG_STRICT_DEVMEM is enabled on the ARM with ARM_LPAE and devmem
> is used to map a high address that is not in the iomem address range,
> an unexpected error indicating no permission is returned.
>
> This bug was initially introduced from v2.6.37, and the function was moved
> to lib when v5.11.
>
> Cc: Luis Chamberlain <mcgrof at kernel.org>
> Fixes: 087aaffcdf9c ("ARM: implement CONFIG_STRICT_DEVMEM by disabling access to RAM via /dev/mem")
> Fixes: 527701eda5f1 ("lib: Add a generic version of devmem_is_allowed()")
> Cc: stable at vger.kernel.org # v2.6.37
> Signed-off-by: Liang Wang <wangliang101 at huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>


From wangkefeng.wang at huawei.com  Tue Aug  3 22:03:01 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 4 Aug 2021 13:03:01 +0800
Subject: [PATCH v2] lib: Use PFN_PHYS() in devmem_is_allowed()
In-Reply-To: <mhng-e101fb5a-2f16-45a0-8436-454ac2bf4223@palmerdabbelt-glaptop>
References: <mhng-e101fb5a-2f16-45a0-8436-454ac2bf4223@palmerdabbelt-glaptop>
Message-ID: <4c0ec8b2-6b9c-d8da-dd84-29937c968636@huawei.com>


On 2021/8/4 8:20, Palmer Dabbelt wrote:
> On Fri, 30 Jul 2021 00:04:05 PDT (-0700), wangkefeng.wang at huawei.com 
> wrote:
>>
>> On 2021/7/30 14:49, Liang Wang wrote:
>>> The physical address may exceed 32 bits on ARM(when ARM_LPAE enabled),
>>> use PFN_PHYS() in devmem_is_allowed(), or the physical address may
>>> overflow and be truncated.
>>>
>>> This bug was initially introduced from v2.6.37, and the function was 
>>> moved
>>> to lib when v5.10.
>>>
>>> Fixes: 087aaffcdf9c ("ARM: implement CONFIG_STRICT_DEVMEM by 
>>> disabling access to RAM via /dev/mem")
>>> Fixes: 527701eda5f1 ("lib: Add a generic version of 
>>> devmem_is_allowed()")
>>> Cc: stable at vger.kernel.org # v2.6.37
>>> Signed-off-by: Liang Wang <wangliang101 at huawei.com>
>> Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>>> ---
>>> v2: update subject and changelog
>>> ? lib/devmem_is_allowed.c | 2 +-
>>> ? 1 file changed, 1 insertion(+), 1 deletion(-)
...
> Acked-by: Palmer Dabbelt <palmerdabbelt at google.com>
>
> I only see the reply so I'm assuming this is going in through some 
> other tree, but LMK if you want it via the RISC-V tree as IIRC we're 
> using it too.

Hi Palmer,? there is a v3 with changelog updated,

https://lore.kernel.org/lkml/20210731025057.78825-1-wangliang101 at huawei.com/


>
> Thanks!
> .
>


From palmer at dabbelt.com  Tue Aug  3 22:14:28 2021
From: palmer at dabbelt.com (Palmer Dabbelt)
Date: Tue, 03 Aug 2021 22:14:28 -0700 (PDT)
Subject: [PATCH v3] lib: Use PFN_PHYS() in devmem_is_allowed()
In-Reply-To: <668986ec-bdc5-482f-39ed-8e059008016d@huawei.com>
Message-ID: <mhng-9a8d70d0-a3d6-4e2b-8bad-46bf87abc80c@palmerdabbelt-glaptop>

On Tue, 03 Aug 2021 22:01:46 PDT (-0700), wangkefeng.wang at huawei.com wrote:
>
> On 2021/7/31 10:50, Liang Wang wrote:
>> The physical address may exceed 32 bits on 32-bit systems with
>> more than 32 bits of physcial address,use PFN_PHYS() in devmem_is_allowed(),
>> or the physical address may overflow and be truncated.
>> We found this bug when mapping a high addresses through devmem tool,
>> when CONFIG_STRICT_DEVMEM is enabled on the ARM with ARM_LPAE and devmem
>> is used to map a high address that is not in the iomem address range,
>> an unexpected error indicating no permission is returned.
>>
>> This bug was initially introduced from v2.6.37, and the function was moved
>> to lib when v5.11.
>>
>> Cc: Luis Chamberlain <mcgrof at kernel.org>
>> Fixes: 087aaffcdf9c ("ARM: implement CONFIG_STRICT_DEVMEM by disabling access to RAM via /dev/mem")
>> Fixes: 527701eda5f1 ("lib: Add a generic version of devmem_is_allowed()")
>> Cc: stable at vger.kernel.org # v2.6.37
>> Signed-off-by: Liang Wang <wangliang101 at huawei.com>
> Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>

Weird, it's still only your replies that are coming through.  Given that 
this only manifests on 32-bit Arm systems, I'm going to leave this up to 
them for now.

Acked-by: Palmer Dabbelt <palmerdabbelt at google.com>


From chunfeng.yun at mediatek.com  Tue Aug  3 22:19:44 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 4 Aug 2021 13:19:44 +0800
Subject: [PATCH 08/11] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <CAATdQgDWkohpzgr=z+uzro4m9Bd=v88DNnJ-M88-5-0annhH_w@mail.gmail.com>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
 <1627635002-24521-8-git-send-email-chunfeng.yun@mediatek.com>
 <CAATdQgDWkohpzgr=z+uzro4m9Bd=v88DNnJ-M88-5-0annhH_w@mail.gmail.com>
Message-ID: <1628054384.14982.12.camel@mhfsdcap03>

On Tue, 2021-08-03 at 14:05 +0800, Ikjoon Jang wrote:
> Hi Chunfeng,
> 
> On Fri, Jul 30, 2021 at 4:51 PM Chunfeng Yun <chunfeng.yun at mediatek.com> wrote:
> >
> > Use @bw_budget_table[] to update fs bus bandwidth due to
> > not all microframes consume @bw_cost_per_microframe, see
> > setup_sch_info().
> >
> > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > ---
> >  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
> >  1 file changed, 7 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
> > index 0bb1a6295d64..10c0f0f6461f 100644
> > --- a/drivers/usb/host/xhci-mtk-sch.c
> > +++ b/drivers/usb/host/xhci-mtk-sch.c
> > @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
> >                  * Compared with hs bus, no matter what ep type,
> >                  * the hub will always delay one uframe to send data
> >                  */
> > -               for (j = 0; j < sch_ep->cs_count; j++) {
> > -                       tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
> > +               for (j = 0; j < sch_ep->num_budget_microframes; j++) {
> > +                       tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j];
> >                         if (tmp > FS_PAYLOAD_MAX)
> >                                 return -ESCH_BW_OVERFLOW;
> >                 }
> > @@ -534,21 +534,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
> >  {
> >         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
> >         u32 base, num_esit;
> > -       int bw_updated;
> >         int i, j;
> >
> >         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> >
> > -       if (used)
> > -               bw_updated = sch_ep->bw_cost_per_microframe;
> > -       else
> > -               bw_updated = -sch_ep->bw_cost_per_microframe;
> > -
> >         for (i = 0; i < num_esit; i++) {
> >                 base = sch_ep->offset + i * sch_ep->esit;
> >
> > -               for (j = 0; j < sch_ep->cs_count; j++)
> > -                       tt->fs_bus_bw[base + j] += bw_updated;
> > +               for (j = 0; j < sch_ep->num_budget_microframes; j++)
> > +                       if (used)
> > +                               tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j];
> > +                       else
> > +                               tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j];
> 
> I agree that xhci-mtk-sch still has more rooms for tt periodic bandwidth
> but I think this approach could trigger a problem.
See updat_bus_bw(), when add fs ep's bandwidth, it uses
bw_budget_table[], so prefer to use the same way

> 
> for example, if there are two endpoints scheduled in the same u-frame index,
> * ep1out  = iso 192bytes bw_budget_table[] = { 188, 188, 0, ...} --> y0
> * ep2in = int 64bytes, bw_budget_table[] = { 0, 0, 64, ... }  --> y0
> 
> (If this is possible allocation from this patch),
> I guess xhci-mtk could have some problems on internal scheduling?

Test it on dvt env. don't encounter issues;

Thanks

> 
> >         }
> >
> >         if (used)
> 
> > --
> > 2.18.0
> >


From kuan-ying.lee at mediatek.com  Tue Aug  3 22:31:08 2021
From: kuan-ying.lee at mediatek.com (kuan.ying lee)
Date: Wed, 4 Aug 2021 13:31:08 +0800
Subject: [PATCH 1/2] kasan, mm: reset tag when access metadata
In-Reply-To: <CA+fCnZdprormHJHHuEMC07+OnHdC9MLb9PLpBnE1P9TvrVisfw@mail.gmail.com>
References: <20210727040021.21371-1-Kuan-Ying.Lee@mediatek.com>
 <20210727040021.21371-2-Kuan-Ying.Lee@mediatek.com>
 <CANpmjNM03Pag9OvBBVnWnSBePRxsT+BvZtBwrh_61Qzmvp+dvA@mail.gmail.com>
 <b6b96caf30e62996fa3b75ae8d146c9cc0dcbbf6.camel@mediatek.com>
 <20210727192217.GV13920@arm.com>
 <CA+fCnZdprormHJHHuEMC07+OnHdC9MLb9PLpBnE1P9TvrVisfw@mail.gmail.com>
Message-ID: <bbba73eb31ac508792d2b8e0971229f3660e7847.camel@mediatek.com>

On Fri, 2021-07-30 at 16:57 +0200, Andrey Konovalov wrote:
> On Tue, Jul 27, 2021 at 9:22 PM Catalin Marinas <
> catalin.marinas at arm.com> wrote:
> > 
> > On Tue, Jul 27, 2021 at 04:32:02PM +0800, Kuan-Ying Lee wrote:
> > > On Tue, 2021-07-27 at 09:10 +0200, Marco Elver wrote:
> > > > +Cc Catalin
> > > > 
> > > > On Tue, 27 Jul 2021 at 06:00, Kuan-Ying Lee <
> > > > Kuan-Ying.Lee at mediatek.com> wrote:
> > > > > 
> > > > > Hardware tag-based KASAN doesn't use compiler
> > > > > instrumentation, we
> > > > > can not use kasan_disable_current() to ignore tag check.
> > > > > 
> > > > > Thus, we need to reset tags when accessing metadata.
> > > > > 
> > > > > Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> > > > 
> > > > This looks reasonable, but the patch title is not saying this
> > > > is
> > > > kmemleak, nor does the description say what the problem is.
> > > > What
> > > > problem did you encounter? Was it a false positive?
> > > 
> > > kmemleak would scan kernel memory to check memory leak.
> > > When it scans on the invalid slab and dereference, the issue
> > > will occur like below.
> > > 
> > > So I think we should reset the tag before scanning.
> > > 
> > > # echo scan > /sys/kernel/debug/kmemleak
> > > [  151.905804]
> > > =================================================================
> > > =
> > > [  151.907120] BUG: KASAN: out-of-bounds in scan_block+0x58/0x170
> > > [  151.908773] Read at addr f7ff0000c0074eb0 by task kmemleak/138
> > > [  151.909656] Pointer tag: [f7], memory tag: [fe]
> > 
> > It would be interesting to find out why the tag doesn't match.
> > Kmemleak
> > should in principle only scan valid objects that have been
> > allocated and
> > the pointer can be safely dereferenced. 0xfe is KASAN_TAG_INVALID,
> > so it
> > either goes past the size of the object (into the red zone) or it
> > still
> > accesses the object after it was marked as freed but before being
> > released from kmemleak.
> > 
> > With slab, looking at __cache_free(), it calls kasan_slab_free()
> > before
> > ___cache_free() -> kmemleak_free_recursive(), so the second
> > scenario is
> > possible. With slub, however, slab_free_hook() first releases the
> > object
> > from kmemleak before poisoning it. Based on the stack dump, you are
> > using slub, so it may be that kmemleak goes into the object red
> > zones.
> > 
> > I'd like this clarified before blindly resetting the tag.
> 
> AFAIK, kmemleak scans the whole object including the leftover redzone
> for kmalloc-allocated objects.
> 
> Looking at the report, there are 11 0xf7 granules, which amounts to
> 176 bytes, and the object is allocated from the kmalloc-256 cache. So
> when kmemleak accesses the last 256-176 bytes, it causes faults, as
> those are marked with KASAN_KMALLOC_REDZONE == KASAN_TAG_INVALID ==
> 0xfe.
> 
> Generally, resetting tags in kasan_disable/enable_current() section
> should be fine to suppress MTE faults, provided those sections had
> been added correctly in the first place.

Thanks Andrey for explanation.
I will refine commit and upload v2.

Thanks.

From anshuman.khandual at arm.com  Tue Aug  3 23:47:26 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 4 Aug 2021 12:17:26 +0530
Subject: [PATCH] arm64/mm: Fix idmap on [16K|36VA|48PA]
In-Reply-To: <4d6a4a0c-7f68-991d-5b0e-08c280543fe8@arm.com>
References: <1627879359-30303-1-git-send-email-anshuman.khandual@arm.com>
 <20210803103440.GA5786@arm.com>
 <7bad50a2-76f1-7946-3a15-35e46fb289c0@arm.com>
 <20210803131201.GB5786@arm.com>
 <4d6a4a0c-7f68-991d-5b0e-08c280543fe8@arm.com>
Message-ID: <cad9294f-8158-6aa4-5740-26f534530740@arm.com>



On 8/4/21 9:16 AM, Anshuman Khandual wrote:
> I am working on a solution which re-works idmap extension logic based on the
> difference between __idmap_text_end and PGDIR_SHIFT coverage, then creating
> additional page table levels and reducing idmap_t0sz appropriately. All the
> existing code including this fix here, will be dropped completely. Because
> it might be difficult to extend this patch to get the entire thing in order,
> the idea was to just fix [16K|36VA|48PA] which could then be backported and
> then do the rework in mainline (which need not be backported)

FYI.

Here is the rework (draft standard, lightly tested and not documented) which
I have been working on. It tries to take care of three different situations,
when __idmap_text_end would not be covered with the existing idmap levels.

1. idmap requires single new level
2. idmap requires two new levels
3. idmap does not require more levels but idmap_ptrs_per_pgd needs adjustment

Applies after the fix here.

---
 arch/arm64/include/asm/assembler.h |  9 ++++++
 arch/arm64/kernel/head.S           | 62 +++++++++++++++-----------------------
 2 files changed, 33 insertions(+), 38 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 89faca0..d826641 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -25,6 +25,15 @@
 #include <asm/ptrace.h>
 #include <asm/thread_info.h>
 
+	.macro shift_to_nr_ptrs, reg1, reg2, reg3, tmp
+	ldr_l   \reg3, idmap_t0sz
+	add     \reg3, \reg3, \tmp
+	mov     \reg2, #64
+	sub     \reg2, \reg2, \reg3
+	mov     \reg1, #1
+	lsr     \reg1, \reg1, \reg2
+	.endm
+
 	/*
 	 * Provide a wxN alias for each wN register so what we can paste a xN
 	 * reference after a 'w' to obtain the 32-bit version.
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index da33bbc..b308787 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -327,54 +327,40 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
 	dmb	sy
 	dc	ivac, x6		// Invalidate potentially stale cache line
 
-#if (VA_BITS < 48)
 #define EXTRA_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
 #define EXTRA_SHIFT_1	(EXTRA_SHIFT + PAGE_SHIFT - 3)
-#define EXTRA_PTRS	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT))
-#define EXTRA_PTRS_1	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT_1))
-
-	/*
-	 * If VA_BITS < 48, we have to configure an additional table level.
-	 * First, we have to verify our assumption that the current value of
-	 * VA_BITS was chosen such that all translation levels are fully
-	 * utilised, and that lowering T0SZ will always result in an additional
-	 * translation level to be configured.
-	 */
-#if VA_BITS != EXTRA_SHIFT
+#if (VA_BITS > EXTRA_SHIFT)
 #error "Mismatch between VA_BITS and page size/number of translation levels"
 #endif
 
-/*
- * In this particular CONFIG_ARM64_16K_PAGES config, there might be a
- * scenario where 'idmap_text_end' ends up high enough in the PA range
- * requiring two additional idmap page table levels. Reduce idmap_t0sz
- * to cover the entire PA range. This prevents table misconfiguration
- * when a given idmap_t0sz value just requires single additional level
- * where as two levels have been built.
- */
-#if defined(CONFIG_ARM64_VA_BITS_36) && defined(CONFIG_ARM64_PA_BITS_48)
-	mov	x4, EXTRA_PTRS_1
-	create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6
+#if (VA_BITS == EXTRA_SHIFT)
+	mov	x6, #TCR_T0SZ(VA_BITS_MIN)
+	sub	x6, x6, x5
+	cmp	x6, #(PAGE_SHIFT - 3)
+	b.gt	8f
 
-	mov	x4, PTRS_PER_PTE
+	shift_to_nr_ptrs x4, x5, x6, #EXTRA_SHIFT
 	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
+	b	1f
+8:
+	shift_to_nr_ptrs x4, x5, x6, #EXTRA_SHIFT_1
+	create_table_entry x0, x3, EXTRA_SHIFT_1, x4, x5, x6
 
-	mov	x5, #64 - PHYS_MASK_SHIFT
-	adr_l	x6, idmap_t0sz
-	str	x5, [x6]
-	dmb	sy
-	dc	ivac, x6
-#else
-	mov	x4, EXTRA_PTRS
+	mov     x4, PTRS_PER_PTE
 	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
-#endif
-#else
-	/*
-	 * If VA_BITS == 48, we don't have to configure an additional
-	 * translation level, but the top-level table has more entries.
-	 */
-	mov	x4, #1 << (PHYS_MASK_SHIFT - PGDIR_SHIFT)
+#elif (VA_BITS < EXTRA_SHIFT)
+	mov	x6, #64
+	sub	x6, x6, x5
+	cmp	x6, EXTRA_SHIFT
+	b.eq	1f
+	b.gt	8f
+
+	shift_to_nr_ptrs x4, x5, x6, #PGDIR_SHIFT
 	str_l	x4, idmap_ptrs_per_pgd, x5
+	b	1f
+8:
+	shift_to_nr_ptrs x4, x5, x6, #EXTRA_SHIFT
+	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
 #endif
 1:
 	ldr_l	x4, idmap_ptrs_per_pgd
-- 
2.7.4



From oupton at google.com  Tue Aug  3 23:59:37 2021
From: oupton at google.com (Oliver Upton)
Date: Tue, 3 Aug 2021 23:59:37 -0700
Subject: [PATCH v5 11/13] KVM: arm64: Provide userspace access to the
 physical counter offset
In-Reply-To: <CAOQ_QsiwuancUsFEVr3TBeP6yLZMfAqNRv3ww2H+hcUGfxs9LA@mail.gmail.com>
References: <20210729173300.181775-1-oupton@google.com>
 <20210729173300.181775-12-oupton@google.com>
 <875yws2h5w.wl-maz@kernel.org>
 <CAOQ_QsgCrEWQqakicR3Peu_c8oCMeq8Cok+CK8vJVURUwAdG0A@mail.gmail.com>
 <87wnp722tm.wl-maz@kernel.org>
 <CAOQ_QsiwuancUsFEVr3TBeP6yLZMfAqNRv3ww2H+hcUGfxs9LA@mail.gmail.com>
Message-ID: <CAOQ_QsiChO1mGGOFL96d35bbLaUBXyYf9cZw1h-Cf3G4P=1YXg@mail.gmail.com>

Hi Marc,

On Fri, Jul 30, 2021 at 9:48 AM Oliver Upton <oupton at google.com> wrote:
>
> On Fri, Jul 30, 2021 at 9:18 AM Marc Zyngier <maz at kernel.org> wrote:
> > You want the ARM FVP model, or maybe even the Foundation model. It has
> > support all the way to ARMv8.7 apparently. I personally use the FVP,
> > get in touch offline and I'll help you with the setup.
> >
> > In general, I tend to trust the ARM models a lot more than QEMU for
> > the quality of the emulation. You can tune it in some bizarre way
> > (the cache modelling is terrifying), and it will definitely do all
> > kind of crazy reordering and speculation.
>
> Awesome, thanks. I'll give this a try.
>

I have another spin of this series ready to kick out the door that
implements ECV support but ran into some issues testing it... Seems
that the ARM Foundation model only implements ECV=0x01, when we need
ECV=0x02 for CNTPOFF_EL2 to be valid. Any thoughts, or shall I just
send out the series and stare at it long enough to make sure the ECV
parts look right ;-)

--
Thanks,
Oliver


From tzimmermann at suse.de  Wed Aug  4 00:10:43 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Wed, 4 Aug 2021 09:10:43 +0200
Subject: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
In-Reply-To: <BY5PR11MB41822706053ADEE927E34E628CF09@BY5PR11MB4182.namprd11.prod.outlook.com>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <YQlbFjbrnyeWv7QP@ravnborg.org>
 <BY5PR11MB41822706053ADEE927E34E628CF09@BY5PR11MB4182.namprd11.prod.outlook.com>
Message-ID: <4dbc29d7-5f88-e3ac-5dab-e2dc5c6a703e@suse.de>

Hi

Am 03.08.21 um 20:36 schrieb Chrisanthus, Anitha:
> Hi Thomas,
> Can you please hold off on applying the kmb patch, I am seeing some issues while testing. Modetest works, but video playback only plays once, and it fails the second time with this patch.

Sounds a bit like the testing issue at [1]. For testing, you need the 
latest drm-misc-next or drm-tip. Specifically, you need commit 
1e4cd78ed493 ("drm: Don't test for IRQ support in VBLANK ioctls").

Let me know whether this works for you.

Best regards
Thomas

[1] https://patchwork.freedesktop.org/patch/447057/?series=93078&rev=1

> 
> Thanks,
> Anitha
> 
> 
>> -----Original Message-----
>> From: Sam Ravnborg <sam at ravnborg.org>
>> Sent: Tuesday, August 3, 2021 8:05 AM
>> To: Thomas Zimmermann <tzimmermann at suse.de>
>> Cc: daniel at ffwll.ch; airlied at linux.ie; alexander.deucher at amd.com;
>> christian.koenig at amd.com; liviu.dudau at arm.com; brian.starkey at arm.com;
>> bbrezillon at kernel.org; nicolas.ferre at microchip.com;
>> maarten.lankhorst at linux.intel.com; mripard at kernel.org; stefan at agner.ch;
>> alison.wang at nxp.com; patrik.r.jakobsson at gmail.com; Chrisanthus, Anitha
>> <anitha.chrisanthus at intel.com>; robdclark at gmail.com; Dea, Edmund J
>> <edmund.j.dea at intel.com>; sean at poorly.run; shawnguo at kernel.org;
>> s.hauer at pengutronix.de; kernel at pengutronix.de; jyri.sarha at iki.fi;
>> tomba at kernel.org; Dan.Sneddon at microchip.com;
>> tomi.valkeinen at ideasonboard.com; amd-gfx at lists.freedesktop.org; dri-
>> devel at lists.freedesktop.org; linux-arm-kernel at lists.infradead.org; linux-arm-
>> msm at vger.kernel.org; freedreno at lists.freedesktop.org
>> Subject: Re: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
>>
>> Hi Thomas,
>>
>> On Tue, Aug 03, 2021 at 11:06:50AM +0200, Thomas Zimmermann wrote:
>>> DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
>>> the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
>>> IRQ interfaces.
>>>
>>> DRM provides IRQ helpers for setting up, receiving and removing IRQ
>>> handlers. It's an abstraction over plain Linux functions. The code
>>> is mid-layerish with several callbacks to hook into the rsp drivers.
>>> Old UMS driver have their interrupts enabled via ioctl, so these
>>> abstractions makes some sense. Modern KMS manage all their interrupts
>>> internally. Using the DRM helpers adds indirection without benefits.
>>>
>>> Most KMS drivers already use Linux IRQ functions instead of DRM's
>>> abstraction layer. Patches 1 to 12 convert the remaining ones.
>>> The patches also resolve a bug for devices without assigned interrupt
>>> number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
>>> not detect if the device has no interrupt assigned.
>>>
>>> Patch 13 removes an unused function.
>>>
>>> Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
>>> the old non-KMS drivers still use the functionality.
>>>
>>> v2:
>>> 	* drop IRQ_NOTCONNECTED test from atmel-hlcdc (Sam)
>>> 	* use devm_request_irq() in atmel-hlcdc (Sam)
>>> 	* unify variable names in arm/hlcdc (Sam)
>>>
>>> Thomas Zimmermann (14):
>>
>> The following patches are all:
>> Acked-by: Sam Ravnborg <sam at ravnborg.org>
>>
>>>    drm/fsl-dcu: Convert to Linux IRQ interfaces
>>>    drm/gma500: Convert to Linux IRQ interfaces
>>>    drm/kmb: Convert to Linux IRQ interfaces
>>>    drm/msm: Convert to Linux IRQ interfaces
>>>    drm/mxsfb: Convert to Linux IRQ interfaces
>>>    drm/tidss: Convert to Linux IRQ interfaces
>>>    drm/vc4: Convert to Linux IRQ interfaces
>>>    drm: Remove unused devm_drm_irq_install()
>>
>> The remaining patches I either skipped or already had a feedback from
>> me or I asked a question.
>>
>> 	Sam

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Felix Imend?rffer

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210804/8c597011/attachment-0001.sig>

From liuqi115 at huawei.com  Wed Aug  4 00:29:54 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Wed, 4 Aug 2021 15:29:54 +0800
Subject: [PATCH v8 2/2] drivers/perf: hisi: Add driver for HiSilicon PCIe
 PMU
In-Reply-To: <20210802100343.GA27282@willie-the-truck>
References: <20210728080932.72515-1-liuqi115@huawei.com>
 <20210728080932.72515-3-liuqi115@huawei.com>
 <20210802100343.GA27282@willie-the-truck>
Message-ID: <a56266c4-c434-f078-6027-f30c021bd593@huawei.com>


Hi Will,
> Hmm, I was hoping that you would expose all the events as proper perf_events
> and get rid of the subevents entirely.
> 
> Then userspace could do things like:
> 
>    // Count number of RX memory reads
>    $ perf stat -e hisi_pcie0_0/rx_memory_read/
> 
>    // Count delay cycles
>    $ perf stat -e hisi_pcie0_0/latency/
> 
>    // Count both of the above (events must be in the same group)
>    $ perf stat -g -e hisi_pcie0_0/latency/ -e hisi_pcie0_0/rx_memory_read/
> 
> Note that in all three of these cases the hardware will be programmed in
> the same way and both HISI_PCIE_CNT and HISI_PCIE_EXT_CNT are allocated!
> 
> So for example, doing this (i.e. without the '-g'):
> 
>    $ perf stat -e hisi_pcie0_0/latency/ -e hisi_pcie0_0/rx_memory_read/
> 
> would fail because the first event would allocate both of the counters.

I'm confused with this situation when getting rid of subevent:

$ perf stat -e hisi_pcie0_0/latency/ -e hisi_pcie0_0/rx_memory_read/

In this case, driver checks the relationship of "latency" and 
"rx_memory_read" in pmu->add() function and return a -EINVAL, but this 
seems lead to time division multiplexing.

	if (event->pmu->add(event, PERF_EF_START)) {
		perf_event_set_state(event, PERF_EVENT_STATE_INACTIVE);
		event->oncpu = -1;
		ret = -EAGAIN;
		goto out;
	}
	...
out:
	perf_pmu_enable(event->pmu);

This result doesn't meet our expection, do I miss something here?

How about add an array to record events and check the relationship in 
event_init() function? It seems that perf stat could only failed when 
driver return invalid value in pmu->event_init() function.

Thanks,
Qi
> 
> All you need to do is check the counter scheduling constraints when
> accepting an event group in the driver. No need for subevents at all.
> 
> Does that make sense?
> 
> Will
> .
> 



From frank-w at public-files.de  Wed Aug  4 00:30:21 2021
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 4 Aug 2021 09:30:21 +0200
Subject: Aw: [PATCH v8, 2/2] soc: mediatek: mmsys: Add mt8192 mmsys routing
 table
In-Reply-To: <1627894773-23872-3-git-send-email-yongqiang.niu@mediatek.com>
References: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
 <1627894773-23872-3-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <trinity-a5eeacb8-1625-4111-b613-19ee1609b902-1628062221917@3c-app-gmx-bap67>

Hi

can you please test if your device still work after applying this

https://patchwork.kernel.org/project/linux-mediatek/patch/20210729070549.5514-1-linux at fw-web.de/

and

duplicate value constants in your routes?

e.g. changing

+		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
+		MT8192_DISP_OVL0_2L_MOUT_EN, MT8192_OVL0_MOUT_EN_DISP_RDMA0,

to

+		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
+		MT8192_DISP_OVL0_2L_MOUT_EN, MT8192_OVL0_MOUT_EN_DISP_RDMA0,
+		MT8192_OVL0_MOUT_EN_DISP_RDMA0

regards Frank


From liuqi115 at huawei.com  Wed Aug  4 01:05:31 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Wed, 4 Aug 2021 16:05:31 +0800
Subject: [PATCH 0/2] coresight: ultrasoc: Add support for System Memory
 Buffer device
In-Reply-To: <20210719111737.47891-1-liuqi115@huawei.com>
References: <20210719111737.47891-1-liuqi115@huawei.com>
Message-ID: <41661d60-d8ef-9d50-57eb-8964c6f6eef8@huawei.com>

Gentle ping...
Hi Mathieu and Suzuki, can you have a look at this patchset? thanks.

On 2021/7/19 19:17, Qi Liu wrote:
> This patchset add support for SMB(System Memory Buffer) device, SMB
> obtains CPU instructions from Coresight ETM device and stores these
> messages in system memory.
> SMB is developed by Ultrasoc technology, which is acquired by Siemens,
> and we still use "Ultrasoc" to name document and driver.
> 
> Change since RFC:
> - Move ultrasoc driver to drivers/hwtracing/coresight.
> - Remove ultrasoc-axi-com.c, as AXI-COM doesn't need to be configured in
>    basic tracing function.
> - Remove ultrasoc.c as SMB does not need to register with the ultrasoc core.
> - Address the comments from Mathieu and Suzuki.
> - Link: https://lists.linaro.org/pipermail/coresight/2021-June/006535.html
> 
> Qi Liu (2):
>    Documentation: tracing: Documentation for ultrasoc SMB drivers
>    coresight: ultrasoc: Add System Memory Buffer driver
> 
>   .../trace/coresight/ultrasoc-trace.rst        | 193 +++++
>   MAINTAINERS                                   |   7 +
>   drivers/hwtracing/coresight/Kconfig           |   3 +
>   drivers/hwtracing/coresight/Makefile          |   2 +
>   drivers/hwtracing/coresight/ultrasoc/Kconfig  |  12 +
>   drivers/hwtracing/coresight/ultrasoc/Makefile |   6 +
>   .../coresight/ultrasoc/ultrasoc-smb.c         | 722 ++++++++++++++++++
>   .../coresight/ultrasoc/ultrasoc-smb.h         | 142 ++++
>   8 files changed, 1087 insertions(+)
>   create mode 100644 Documentation/trace/coresight/ultrasoc-trace.rst
>   create mode 100644 drivers/hwtracing/coresight/ultrasoc/Kconfig
>   create mode 100644 drivers/hwtracing/coresight/ultrasoc/Makefile
>   create mode 100644 drivers/hwtracing/coresight/ultrasoc/ultrasoc-smb.c
>   create mode 100644 drivers/hwtracing/coresight/ultrasoc/ultrasoc-smb.h
> 



From p.yadav at ti.com  Wed Aug  4 01:09:54 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Wed, 4 Aug 2021 13:39:54 +0530
Subject: [PATCH v2 01/35] mtd: spi-nor: core: Introduce SPI_NOR_PARSE_SFDP
In-Reply-To: <20210727045222.905056-2-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-2-tudor.ambarus@microchip.com>
Message-ID: <20210804080952.4ys7wmae4j4h4ktk@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> SPI NOR flashes that statically declare one of the
> SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
> the RDSFDP command are gratuiously receiving the RDSFDP command
> in the attempt of parsing the SFDP tables. It is not desirable to issue
> commands that are not supported, so introduce a flag to help on this
> situation.
> 
> New flash additions that support the SFDP standard should be declared
> using SPI_NOR_PARSE_SFDP. Support that can be discovered when parsing
> SFDP should not be duplicated by explicit flags at flash declaration.
> All the flash parameters will be discovered when parsing SFDP.
> Sometimes manufacturers wrongly define some fields in the SFDP tables.
> If that's the case, SFDP data can be amended with the fixups() hooks.
> It is not common, but if the SFDP tables are entirely wrong, and it
> does not worth the hassle to tweak the SFDP parameters by using the
> fixups hooks, or if the flash does not define the SFDP tables at all,
> then statically init the flash with the SPI_NOR_SKIP_SFDP flag and
> specify the rest of flash capabilities with the flash info flags.
> 
> With time, we want to convert all flashes to SPI_NOR_PARSE_SFDP and
> stop triggering the SFDP parsing with the
> SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
> SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable, the rest
> are a long term goal.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> Reviewed-by: Heiko Thiery <heiko.thiery at gmail.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From frank-w at public-files.de  Wed Aug  4 01:11:08 2021
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 4 Aug 2021 10:11:08 +0200
Subject: Aw: Re:  [PATCH 0/2] Add MUSB for MT7623
In-Reply-To: <f3607979-ea50-fc1c-0afe-a55881aa24f0@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <trinity-0f9449b8-5114-46e5-9a4f-00b62155a938-1628010948338@3c-app-gmx-bs54>
 <f3607979-ea50-fc1c-0afe-a55881aa24f0@gorani.run>
Message-ID: <trinity-8910c659-6e4e-4979-a6d0-eaf5b8bee213-1628064668849@3c-app-gmx-bap67>

> Gesendet: Mittwoch, 04. August 2021 um 02:14 Uhr
> Von: "Sungbo Eo" <mans0n at gorani.run>

> > thanks for working on it. do both otg-roles (host/client) work on your device?
>
> Yes, I tested it with host mode and device mode.
> I also tried manual role-switch via sysfs and it worked with some prior setup.
> Note that my device has a USB Type-A connector and not micro B, so I can't help with id pin stuff...

> > but usb-stick is not powered (led of the stick is off) and of course i see no mass-storage device.
>
> I observed the same symptom (but different error log).
>
> [    2.722253] musb-hdrc musb-hdrc.1.auto: VBUS_ERROR in a_idle (80, <SessEnd), retry #0, port1 00000104
>
> In my case adding `regulator-always-on;` in the regulator node solved the problem temporarily.
> But after that I switched to relying on pinctrl.

i've found out that usb-stick is powered if i first connect otg-cable and then the stick to the cable...regulator always on does not change anything for me (only supporess "disabling vusb" message on boot). traceback on poweroff is still there.

role switch happen on inserting stick into cable, not before (insert cable into r2) as i expected.

need to figure out which CONFIG options i need to get USB-Stick as mass storage working.

i wonder why it works on your board without the vusb/connector subnodes

> +&pio {
> +       musb_pins: musb {
> +               pins-musb {
> +                       pinmux = <MT7623_PIN_237_EXT_SDIO2_FUNC_DRV_VBUS>;
> +               };
> +       };
> +};

imho it's the same gpio used for regulator, right? whats the difference?
i tried this instead of the regulator-node => not powered (cable first, then stick).

> +&usb3 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&musb_pins>;
> +       status = "okay";
> +
> +       dr_mode = "host";
> +
> +       connector {
> +               compatible = "usb-a-connector";
> +       };
> +};
>
> root at OpenWrt:~# lsusb -t
> /:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M
>     |__ Port 1: Dev 2, If 0, Class=, Driver=usb-storage, 480M
> /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci-mtk/1p, 5000M
> /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci-mtk/1p, 480M
>
> I tested device mode with legacy CDC composite device module.
> You can also take more complicated configfs approach, though.
> https://elinux.org/images/e/ef/USB_Gadget_Configfs_API_0.pdf
>
> +       dr_mode = "host";
> -       dr_mode = "peripheral";
>
> root at OpenWrt:/# insmod g_cdc
> [   64.565254] using random self ethernet address
> [   64.569711] using random host ethernet address
> [   64.575966] usb0: HOST MAC 26:36:2d:e5:8f:6f
> [   64.580501] usb0: MAC 92:d7:f9:c7:88:01
> [   64.584409] g_cdc gadget: CDC Composite Gadget, version: King Kamehameha Day 2008
> [   64.592454] g_cdc gadget: g_cdc ready
>
> I also tried usb-role-switch,
>
> -       dr_mode = "host";
> +       usb-role-switch;
>
> After boot the initial mode of musb is "none", and it did not turn vbus on even if I set it to host mode.
> Later I found out that I need to load any gadget driver before setting it to host mode.
>
> # echo peripheral > /sys/devices/platform/11200000.usb/musb-hdrc.1.auto/mode
> # insmod g_cdc
> # echo host > /sys/devices/platform/11200000.usb/musb-hdrc.1.auto/mode
>
> That's all I know. Please let me know if I skipped some details.
> Thanks.
>
> >
> > and now i'm back on the traceback on power down i've reported Author of musb driver some time ago
> >
> > [  156.785185] WARNING: CPU: 0 PID: 1 at drivers/power/reset/mt6323-poweroff.c:4
> > [  156.795156] Unable to power off system
> >
> > [  156.884496] [<c0cca1ec>] (warn_slowpath_fmt) from [<c090562c>] (mt6323_do_pw)
> > [  156.893203]  r8:c3296d40 r7:00000024 r6:0ccccb60 r5:c10fe3d8 r4:00000000
> > [  156.900030] [<c09054b0>] (mt6323_do_pwroff) from [<c010ba68>] (machine_power)
> > [  156.908558]  r8:fee1dead r7:c1312590 r6:92f61d00 r5:00000000 r4:4321fedc
> > [  156.915385] [<c010ba34>] (machine_power_off) from [<c01524bc>] (kernel_power)
> >
> > i guess it's related to the usb_vbus.
> >
> > regards Frank
> >
>


From nicolas.ferre at microchip.com  Wed Aug  4 01:17:21 2021
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Wed, 4 Aug 2021 10:17:21 +0200
Subject: [GIT PULL] ARM: at91: soc for 5.15
Message-ID: <20210804081721.11093-1-nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

Arnd, Olof,

Here are the soc changes for 5.15 which contains the introduction of our new
SoC family: the SAMA7G5.
Note that one header file is shared with the clock sub-system. We synchronized
with Stephen to make it appear in this Pull-Request.

Thanks, best regards,
  Nicolas

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git at91-soc-5.15

for you to fetch changes up to ad9bc2e35cf575644064284943aefdde426644cc:

  ARM: at91: pm: add sama7g5 shdwc (2021-07-19 14:32:13 +0200)

----------------------------------------------------------------
AT91 soc for 5.13:

- Add new SoC based on a Cortex-A7 core: the SAMA7G5 family
  - mach-at91 entry, Kconfig and header files
  - Power Management Controller (PMC) code and associated power
    management changes. Support for suspend/resume, Ultra Low Power modes
    and Backup with Memory in Self-Refresh mode.
  - Power management association with DDR controller and shutdown
    controller for addressing this variety of modes.

----------------------------------------------------------------
Claudiu Beznea (23):
      clk: at91: add register definition for sama7g5's master clock
      ARM: at91: pm: move pm_bu to soc_pm data structure
      ARM: at91: pm: move the setup of soc_pm.bu->suspended
      ARM: at91: pm: document at91_soc_pm structure
      ARM: at91: pm: check for different controllers in at91_pm_modes_init()
      ARM: at91: pm: do not initialize pdev
      ARM: at91: pm: use r7 instead of tmp1
      ARM: at91: pm: avoid push and pop on stack while memory is in self-refersh
      ARM: at91: pm: s/CONFIG_SOC_SAM9X60/CONFIG_HAVE_AT91_SAM9X60_PLL/g
      ARM: at91: pm: add support for waiting MCK1..4
      ARM: at91: sfrbu: add sfrbu registers definitions for sama7g5
      ARM: at91: ddr: add registers definitions for sama7g5's ddr
      ARM: at91: pm: add self-refresh support for sama7g5
      ARM: at91: pm: add support for MCK1..4 save/restore for ulp modes
      ARM: at91: pm: add support for 2.5V LDO regulator control
      ARM: at91: pm: wait for ddr power mode off
      ARM: at91: pm: add sama7g5 ddr controller
      ARM: at91: pm: add sama7g5 ddr phy controller
      ARM: at91: pm: save ddr phy calibration data to securam
      ARM: at91: pm: add backup mode support for SAMA7G5
      ARM: at91: pm: add sama7g5's pmc
      ARM: at91: pm: add pm support for SAMA7G5
      ARM: at91: pm: add sama7g5 shdwc

Eugen Hristev (3):
      ARM: at91: add new SoC sama7g5
      ARM: at91: debug: add sama7g5 low level debug uart
      ARM: at91: sama7: introduce sama7 SoC family

 arch/arm/Kconfig.debug               |  10 +
 arch/arm/mach-at91/Kconfig           |  18 +
 arch/arm/mach-at91/Makefile          |   1 +
 arch/arm/mach-at91/generic.h         |   2 +
 arch/arm/mach-at91/pm.c              | 343 +++++++++++----
 arch/arm/mach-at91/pm.h              |   3 +
 arch/arm/mach-at91/pm_data-offsets.c |   2 +
 arch/arm/mach-at91/pm_suspend.S      | 827 ++++++++++++++++++++++++++---------
 arch/arm/mach-at91/sama7.c           |  33 ++
 include/linux/clk/at91_pmc.h         |  26 ++
 include/soc/at91/sama7-ddr.h         |  80 ++++
 include/soc/at91/sama7-sfrbu.h       |  34 ++
 12 files changed, 1090 insertions(+), 289 deletions(-)
 create mode 100644 arch/arm/mach-at91/sama7.c
 create mode 100644 include/soc/at91/sama7-ddr.h
 create mode 100644 include/soc/at91/sama7-sfrbu.h

-- 
Nicolas Ferre


From nicolas.ferre at microchip.com  Wed Aug  4 01:20:26 2021
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Wed, 4 Aug 2021 10:20:26 +0200
Subject: [GIT PULL] ARM: at91: soc for 5.15
In-Reply-To: <20210804081721.11093-1-nicolas.ferre@microchip.com>
References: <20210804081721.11093-1-nicolas.ferre@microchip.com>
Message-ID: <25bf6f36-e6b5-e7ed-840d-3ff635c15d58@microchip.com>

On 04/08/2021 at 10:17, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> Arnd, Olof,
> 
> Here are the soc changes for 5.15 which contains the introduction of our new
> SoC family: the SAMA7G5.
> Note that one header file is shared with the clock sub-system. We synchronized
> with Stephen to make it appear in this Pull-Request.
> 
> Thanks, best regards,
>    Nicolas
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>    Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>    git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git at91-soc-5.15
> 
> for you to fetch changes up to ad9bc2e35cf575644064284943aefdde426644cc:
> 
>    ARM: at91: pm: add sama7g5 shdwc (2021-07-19 14:32:13 +0200)
> 
> ----------------------------------------------------------------
> AT91 soc for 5.13:
Error with tag, please disregard this message. Sorry for the noise!

Regards,
   Nicolas

> 
> - Add new SoC based on a Cortex-A7 core: the SAMA7G5 family
>    - mach-at91 entry, Kconfig and header files
>    - Power Management Controller (PMC) code and associated power
>      management changes. Support for suspend/resume, Ultra Low Power modes
>      and Backup with Memory in Self-Refresh mode.
>    - Power management association with DDR controller and shutdown
>      controller for addressing this variety of modes.
> 
> ----------------------------------------------------------------
> Claudiu Beznea (23):
>        clk: at91: add register definition for sama7g5's master clock
>        ARM: at91: pm: move pm_bu to soc_pm data structure
>        ARM: at91: pm: move the setup of soc_pm.bu->suspended
>        ARM: at91: pm: document at91_soc_pm structure
>        ARM: at91: pm: check for different controllers in at91_pm_modes_init()
>        ARM: at91: pm: do not initialize pdev
>        ARM: at91: pm: use r7 instead of tmp1
>        ARM: at91: pm: avoid push and pop on stack while memory is in self-refersh
>        ARM: at91: pm: s/CONFIG_SOC_SAM9X60/CONFIG_HAVE_AT91_SAM9X60_PLL/g
>        ARM: at91: pm: add support for waiting MCK1..4
>        ARM: at91: sfrbu: add sfrbu registers definitions for sama7g5
>        ARM: at91: ddr: add registers definitions for sama7g5's ddr
>        ARM: at91: pm: add self-refresh support for sama7g5
>        ARM: at91: pm: add support for MCK1..4 save/restore for ulp modes
>        ARM: at91: pm: add support for 2.5V LDO regulator control
>        ARM: at91: pm: wait for ddr power mode off
>        ARM: at91: pm: add sama7g5 ddr controller
>        ARM: at91: pm: add sama7g5 ddr phy controller
>        ARM: at91: pm: save ddr phy calibration data to securam
>        ARM: at91: pm: add backup mode support for SAMA7G5
>        ARM: at91: pm: add sama7g5's pmc
>        ARM: at91: pm: add pm support for SAMA7G5
>        ARM: at91: pm: add sama7g5 shdwc
> 
> Eugen Hristev (3):
>        ARM: at91: add new SoC sama7g5
>        ARM: at91: debug: add sama7g5 low level debug uart
>        ARM: at91: sama7: introduce sama7 SoC family
> 
>   arch/arm/Kconfig.debug               |  10 +
>   arch/arm/mach-at91/Kconfig           |  18 +
>   arch/arm/mach-at91/Makefile          |   1 +
>   arch/arm/mach-at91/generic.h         |   2 +
>   arch/arm/mach-at91/pm.c              | 343 +++++++++++----
>   arch/arm/mach-at91/pm.h              |   3 +
>   arch/arm/mach-at91/pm_data-offsets.c |   2 +
>   arch/arm/mach-at91/pm_suspend.S      | 827 ++++++++++++++++++++++++++---------
>   arch/arm/mach-at91/sama7.c           |  33 ++
>   include/linux/clk/at91_pmc.h         |  26 ++
>   include/soc/at91/sama7-ddr.h         |  80 ++++
>   include/soc/at91/sama7-sfrbu.h       |  34 ++
>   12 files changed, 1090 insertions(+), 289 deletions(-)
>   create mode 100644 arch/arm/mach-at91/sama7.c
>   create mode 100644 include/soc/at91/sama7-ddr.h
>   create mode 100644 include/soc/at91/sama7-sfrbu.h
> 


-- 
Nicolas Ferre


From Kuan-Ying.Lee at mediatek.com  Wed Aug  4 01:22:29 2021
From: Kuan-Ying.Lee at mediatek.com (Kuan-Ying Lee)
Date: Wed, 4 Aug 2021 16:22:29 +0800
Subject: [PATCH v2 1/2] kasan, kmemleak: reset tags when scanning block
In-Reply-To: <20210804082230.10837-1-Kuan-Ying.Lee@mediatek.com>
References: <20210804082230.10837-1-Kuan-Ying.Lee@mediatek.com>
Message-ID: <20210804082230.10837-2-Kuan-Ying.Lee@mediatek.com>

Kmemleak need to scan kernel memory to check memory leak.
With hardware tag-based kasan enabled, when it scans on
the invalid slab and dereference, the issue will occur
as below.

Hardware tag-based KASAN doesn't use compiler instrumentation, we
can not use kasan_disable_current() to ignore tag check.

Based on the below report, there are 11 0xf7 granules, which amounts to
176 bytes, and the object is allocated from the kmalloc-256 cache. So
when kmemleak accesses the last 256-176 bytes, it causes faults, as
those are marked with KASAN_KMALLOC_REDZONE == KASAN_TAG_INVALID ==
0xfe.

Thus, we reset tags before accessing metadata to avoid from false positives.

[  151.905804] ==================================================================
[  151.907120] BUG: KASAN: out-of-bounds in scan_block+0x58/0x170
[  151.908773] Read at addr f7ff0000c0074eb0 by task kmemleak/138
[  151.909656] Pointer tag: [f7], memory tag: [fe]
[  151.910195]
[  151.910876] CPU: 7 PID: 138 Comm: kmemleak Not tainted 5.14.0-rc2-00001-g8cae8cd89f05-dirty #134
[  151.912085] Hardware name: linux,dummy-virt (DT)
[  151.912868] Call trace:
[  151.913211]  dump_backtrace+0x0/0x1b0
[  151.913796]  show_stack+0x1c/0x30
[  151.914248]  dump_stack_lvl+0x68/0x84
[  151.914778]  print_address_description+0x7c/0x2b4
[  151.915340]  kasan_report+0x138/0x38c
[  151.915804]  __do_kernel_fault+0x190/0x1c4
[  151.916386]  do_tag_check_fault+0x78/0x90
[  151.916856]  do_mem_abort+0x44/0xb4
[  151.917308]  el1_abort+0x40/0x60
[  151.917754]  el1h_64_sync_handler+0xb4/0xd0
[  151.918270]  el1h_64_sync+0x78/0x7c
[  151.918714]  scan_block+0x58/0x170
[  151.919157]  scan_gray_list+0xdc/0x1a0
[  151.919626]  kmemleak_scan+0x2ac/0x560
[  151.920129]  kmemleak_scan_thread+0xb0/0xe0
[  151.920635]  kthread+0x154/0x160
[  151.921115]  ret_from_fork+0x10/0x18
[  151.921717]
[  151.922077] Allocated by task 0:
[  151.922523]  kasan_save_stack+0x2c/0x60
[  151.923099]  __kasan_kmalloc+0xec/0x104
[  151.923502]  __kmalloc+0x224/0x3c4
[  151.924172]  __register_sysctl_paths+0x200/0x290
[  151.924709]  register_sysctl_table+0x2c/0x40
[  151.925175]  sysctl_init+0x20/0x34
[  151.925665]  proc_sys_init+0x3c/0x48
[  151.926136]  proc_root_init+0x80/0x9c
[  151.926547]  start_kernel+0x648/0x6a4
[  151.926987]  __primary_switched+0xc0/0xc8
[  151.927557]
[  151.927994] Freed by task 0:
[  151.928340]  kasan_save_stack+0x2c/0x60
[  151.928766]  kasan_set_track+0x2c/0x40
[  151.929173]  kasan_set_free_info+0x44/0x54
[  151.929568]  ____kasan_slab_free.constprop.0+0x150/0x1b0
[  151.930063]  __kasan_slab_free+0x14/0x20
[  151.930449]  slab_free_freelist_hook+0xa4/0x1fc
[  151.930924]  kfree+0x1e8/0x30c
[  151.931285]  put_fs_context+0x124/0x220
[  151.931731]  vfs_kern_mount.part.0+0x60/0xd4
[  151.932280]  kern_mount+0x24/0x4c
[  151.932686]  bdev_cache_init+0x70/0x9c
[  151.933122]  vfs_caches_init+0xdc/0xf4
[  151.933578]  start_kernel+0x638/0x6a4
[  151.934014]  __primary_switched+0xc0/0xc8
[  151.934478]
[  151.934757] The buggy address belongs to the object at ffff0000c0074e00
[  151.934757]  which belongs to the cache kmalloc-256 of size 256
[  151.935744] The buggy address is located 176 bytes inside of
[  151.935744]  256-byte region [ffff0000c0074e00, ffff0000c0074f00)
[  151.936702] The buggy address belongs to the page:
[  151.937378] page:(____ptrval____) refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x100074
[  151.938682] head:(____ptrval____) order:2 compound_mapcount:0 compound_pincount:0
[  151.939440] flags: 0xbfffc0000010200(slab|head|node=0|zone=2|lastcpupid=0xffff|kasantag=0x0)
[  151.940886] raw: 0bfffc0000010200 0000000000000000 dead000000000122 f5ff0000c0002300
[  151.941634] raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000
[  151.942353] page dumped because: kasan: bad access detected
[  151.942923]
[  151.943214] Memory state around the buggy address:
[  151.943896]  ffff0000c0074c00: f0 f0 f0 f0 f0 f0 f0 f0 f0 fe fe fe fe fe fe fe
[  151.944857]  ffff0000c0074d00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
[  151.945892] >ffff0000c0074e00: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 fe fe fe fe fe
[  151.946407]                                                     ^
[  151.946939]  ffff0000c0074f00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
[  151.947445]  ffff0000c0075000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  151.947999] ==================================================================
[  151.948524] Disabling lock debugging due to kernel taint
[  156.434569] kmemleak: 181 new suspected memory leaks (see /sys/kernel/debug/kmemleak)

Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Cc: Marco Elver <elver at google.com>
Cc: Andrey Konovalov <andreyknvl at gmail.com>
---
 mm/kmemleak.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 228a2fbe0657..73d46d16d575 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -290,7 +290,7 @@ static void hex_dump_object(struct seq_file *seq,
 	warn_or_seq_printf(seq, "  hex dump (first %zu bytes):\n", len);
 	kasan_disable_current();
 	warn_or_seq_hex_dump(seq, DUMP_PREFIX_NONE, HEX_ROW_SIZE,
-			     HEX_GROUP_SIZE, ptr, len, HEX_ASCII);
+			     HEX_GROUP_SIZE, kasan_reset_tag((void *)ptr), len, HEX_ASCII);
 	kasan_enable_current();
 }
 
@@ -1171,7 +1171,7 @@ static bool update_checksum(struct kmemleak_object *object)
 
 	kasan_disable_current();
 	kcsan_disable_current();
-	object->checksum = crc32(0, (void *)object->pointer, object->size);
+	object->checksum = crc32(0, kasan_reset_tag((void *)object->pointer), object->size);
 	kasan_enable_current();
 	kcsan_enable_current();
 
@@ -1246,7 +1246,7 @@ static void scan_block(void *_start, void *_end,
 			break;
 
 		kasan_disable_current();
-		pointer = *ptr;
+		pointer = *(unsigned long *)kasan_reset_tag((void *)ptr);
 		kasan_enable_current();
 
 		untagged_ptr = (unsigned long)kasan_reset_tag((void *)pointer);
-- 
2.18.0

From Kuan-Ying.Lee at mediatek.com  Wed Aug  4 01:22:28 2021
From: Kuan-Ying.Lee at mediatek.com (Kuan-Ying Lee)
Date: Wed, 4 Aug 2021 16:22:28 +0800
Subject: [PATCH v2 0/2] kasan: reset tag when accessing invalid data
Message-ID: <20210804082230.10837-1-Kuan-Ying.Lee@mediatek.com>

With hardware tag-based kasan enabled, we reset the tag
when we access metadata to avoid from false alarm.

Changes since v2:
 - Refine the commit message in detail.
 - Thanks Andrey's explanation about false alarm
   of kmemleak.

Kuan-Ying Lee (2):
  kasan, kmemleak: reset tags when scanning block
  kasan, slub: reset tag when printing address

 mm/kmemleak.c | 6 +++---
 mm/slub.c     | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

-- 
2.18.0

From Kuan-Ying.Lee at mediatek.com  Wed Aug  4 01:22:30 2021
From: Kuan-Ying.Lee at mediatek.com (Kuan-Ying Lee)
Date: Wed, 4 Aug 2021 16:22:30 +0800
Subject: [PATCH v2 2/2] kasan, slub: reset tag when printing address
In-Reply-To: <20210804082230.10837-1-Kuan-Ying.Lee@mediatek.com>
References: <20210804082230.10837-1-Kuan-Ying.Lee@mediatek.com>
Message-ID: <20210804082230.10837-3-Kuan-Ying.Lee@mediatek.com>

The address still includes the tags when it is printed.
With hardware tag-based kasan enabled, we will get a
false positive KASAN issue when we access metadata.

Reset the tag before we access the metadata.

Fixes: aa1ef4d7b3f6 ("kasan, mm: reset tags when accessing metadata")
Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
Suggested-by: Marco Elver <elver at google.com>
---
 mm/slub.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index b6c5205252eb..f77d8cd79ef7 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -576,8 +576,8 @@ static void print_section(char *level, char *text, u8 *addr,
 			  unsigned int length)
 {
 	metadata_access_enable();
-	print_hex_dump(level, kasan_reset_tag(text), DUMP_PREFIX_ADDRESS,
-			16, 1, addr, length, 1);
+	print_hex_dump(level, text, DUMP_PREFIX_ADDRESS,
+			16, 1, kasan_reset_tag((void *)addr), length, 1);
 	metadata_access_disable();
 }
 
-- 
2.18.0

From p.yadav at ti.com  Wed Aug  4 01:23:47 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Wed, 4 Aug 2021 13:53:47 +0530
Subject: [PATCH v2 02/35] mtd: spi-nor: core: Report correct name in case
 of ID collisions
In-Reply-To: <20210727045222.905056-3-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-3-tudor.ambarus@microchip.com>
Message-ID: <20210804082345.ztciqvdeljvyx5by@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> Provide a way to report the correct flash name in case of ID collisions.
> There will be a single flash_info entry when flash IDs collide, and the
> differentiation between the flash types will be made at runtime
> if possible.

I have the same comments as last time around. I am not convinced that 
this approach is better than having multiple entries, one for each 
colliding flash. I wonder how you will handle different fixups for the 
colliding flashes for example, since nor->info is const.

Maybe I will change my mind once I read through the rest of the series, 
in which case I will report back here.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c  | 7 +++++--
>  drivers/mtd/spi-nor/sysfs.c | 2 +-
>  include/linux/mtd/spi-nor.h | 2 ++
>  3 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 3d9f3698fb7b..1a278d33b02d 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3027,7 +3027,7 @@ static void spi_nor_debugfs_init(struct spi_nor *nor,
>  {
>  	struct mtd_info *mtd = &nor->mtd;
>  
> -	mtd->dbg.partname = info->name;
> +	mtd->dbg.partname = nor->name;
>  	mtd->dbg.partid = devm_kasprintf(nor->dev, GFP_KERNEL, "spi-nor:%*phN",
>  					 info->id_len, info->id);
>  }
> @@ -3208,7 +3208,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	/* Configure OTP parameters and ops */
>  	spi_nor_otp_init(nor);
>  
> -	dev_info(dev, "%s (%lld Kbytes)\n", info->name,
> +	if (!nor->name)
> +		nor->name = info->name;
> +
> +	dev_info(dev, "%s (%lld Kbytes)\n", nor->name,
>  			(long long)mtd->size >> 10);
>  
>  	dev_dbg(dev,
> diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c
> index 9aec9d8a98ad..017119768f32 100644
> --- a/drivers/mtd/spi-nor/sysfs.c
> +++ b/drivers/mtd/spi-nor/sysfs.c
> @@ -25,7 +25,7 @@ static ssize_t partname_show(struct device *dev,
>  	struct spi_mem *spimem = spi_get_drvdata(spi);
>  	struct spi_nor *nor = spi_mem_get_drvdata(spimem);
>  
> -	return sysfs_emit(buf, "%s\n", nor->info->name);
> +	return sysfs_emit(buf, "%s\n", nor->name);
>  }
>  static DEVICE_ATTR_RO(partname);
>  
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index f67457748ed8..bd92acdd1899 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -369,6 +369,7 @@ struct spi_nor_flash_parameter;
>   * @bouncebuf:		bounce buffer used when the buffer passed by the MTD
>   *                      layer is not DMA-able
>   * @bouncebuf_size:	size of the bounce buffer
> + * @name:		used to point to correct name in case of ID collisions.
>   * @info:		SPI NOR part JEDEC MFR ID and other info
>   * @manufacturer:	SPI NOR manufacturer
>   * @page_size:		the page size of the SPI NOR
> @@ -399,6 +400,7 @@ struct spi_nor {
>  	struct spi_mem		*spimem;
>  	u8			*bouncebuf;
>  	size_t			bouncebuf_size;
> +	const char *name;
>  	const struct flash_info	*info;
>  	const struct spi_nor_manufacturer *manufacturer;
>  	u32			page_size;
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From cristian.marussi at arm.com  Wed Aug  4 01:33:58 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 4 Aug 2021 09:33:58 +0100
Subject: [PATCH] firmware: arm_scmi: Free mailbox channels if probe fails
In-Reply-To: <1628029342-3638-1-git-send-email-rishabhb@codeaurora.org>
References: <1628029342-3638-1-git-send-email-rishabhb@codeaurora.org>
Message-ID: <20210804083358.GR6592@e120937-lin>

On Tue, Aug 03, 2021 at 03:22:22PM -0700, Rishabh Bhatnagar wrote:
> Mailbox channels for the base protocol are setup during probe.
> There can be a scenario where probe fails to acquire the base
> protocol due to a timeout leading to cleaning up of all device
> managed memory including the scmi_mailbox structure setup during
> mailbox_chan_setup function.
> [   12.735104]arm-scmi soc:qcom,scmi: timed out in resp(caller: version_get+0x84/0x140)
> [   12.735224]arm-scmi soc:qcom,scmi: unable to communicate with SCMI
> [   12.735947]arm-scmi: probe of soc:qcom,scmi failed with error -110
> 
> Now when a message arrives at cpu slightly after the timeout, the mailbox
> controller will try to call the rx_callback of the client and might end
> up accessing freed memory.
> [   12.758363][    C0] Call trace:
> [   12.758367][    C0]  rx_callback+0x24/0x160
> [   12.758372][    C0]  mbox_chan_received_data+0x44/0x94
> [   12.758386][    C0]  __handle_irq_event_percpu+0xd4/0x240
> This patch frees the mailbox channels setup during probe and adds some more
> error handling in case the probe fails.
> 
> Change-Id: I1214ec2c4c92c4a3ca5fa73de11e0e403b13b46a
> Signed-off-by: Rishabh Bhatnagar <rishabhb at codeaurora.org>

Hi Rishabh,

Good catch, thanks for this.

> ---
>  drivers/firmware/arm_scmi/driver.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 9b2e8d4..518c7b9 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -1430,7 +1430,7 @@ static int scmi_probe(struct platform_device *pdev)
>  
>  	ret = scmi_xfer_info_init(info);
>  	if (ret)
> -		return ret;
> +		goto clear_txrx_setup;
>  
>  	if (scmi_notification_init(handle))
>  		dev_err(dev, "SCMI Notifications NOT available.\n");
> @@ -1443,7 +1443,7 @@ static int scmi_probe(struct platform_device *pdev)
>  	ret = scmi_protocol_acquire(handle, SCMI_PROTOCOL_BASE);
>  	if (ret) {
>  		dev_err(dev, "unable to communicate with SCMI\n");
> -		return ret;
> +		goto notification_exit;
>  	}
>  
>  	mutex_lock(&scmi_list_mutex);
> @@ -1482,6 +1482,13 @@ static int scmi_probe(struct platform_device *pdev)
>  	}
>  
>  	return 0;
> +
> +notification_exit:
> +	scmi_notification_exit(&info->handle);
> +clear_txrx_setup:
> +	idr_for_each(&info->tx_idr, info->desc->ops->chan_free, &info->tx_idr);
> +	idr_for_each(&info->rx_idr, info->desc->ops->chan_free, &info->rx_idr);
> +	return ret;
>  }
>  

Shouldn't we also clear the internal IDRs memory allocs after these
idr_for_each() adding a couple of:

	idr_destroy(&info->tx_idr);

	idr_destroy(&info->rx_idr);

like scmi_remove() does ?

Thanks,
Cristian


From cristian.marussi at arm.com  Wed Aug  4 01:40:32 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 4 Aug 2021 09:40:32 +0100
Subject: [PATCH] firmware: arm_scmi: Free mailbox channels if probe fails
In-Reply-To: <20210804083358.GR6592@e120937-lin>
References: <1628029342-3638-1-git-send-email-rishabhb@codeaurora.org>
 <20210804083358.GR6592@e120937-lin>
Message-ID: <20210804084032.GS6592@e120937-lin>

On Wed, Aug 04, 2021 at 09:33:58AM +0100, Cristian Marussi wrote:
> On Tue, Aug 03, 2021 at 03:22:22PM -0700, Rishabh Bhatnagar wrote:
> > Mailbox channels for the base protocol are setup during probe.
> > There can be a scenario where probe fails to acquire the base
> > protocol due to a timeout leading to cleaning up of all device
> > managed memory including the scmi_mailbox structure setup during
> > mailbox_chan_setup function.
> > [   12.735104]arm-scmi soc:qcom,scmi: timed out in resp(caller: version_get+0x84/0x140)
> > [   12.735224]arm-scmi soc:qcom,scmi: unable to communicate with SCMI
> > [   12.735947]arm-scmi: probe of soc:qcom,scmi failed with error -110
> > 
> > Now when a message arrives at cpu slightly after the timeout, the mailbox
> > controller will try to call the rx_callback of the client and might end
> > up accessing freed memory.
> > [   12.758363][    C0] Call trace:
> > [   12.758367][    C0]  rx_callback+0x24/0x160
> > [   12.758372][    C0]  mbox_chan_received_data+0x44/0x94
> > [   12.758386][    C0]  __handle_irq_event_percpu+0xd4/0x240
> > This patch frees the mailbox channels setup during probe and adds some more
> > error handling in case the probe fails.
> > 
> > Change-Id: I1214ec2c4c92c4a3ca5fa73de11e0e403b13b46a
> > Signed-off-by: Rishabh Bhatnagar <rishabhb at codeaurora.org>
> 
> Hi Rishabh,
> 
> Good catch, thanks for this.
> 

Hi again,

sorry forgot one thing.

> > ---
> >  drivers/firmware/arm_scmi/driver.c | 11 +++++++++--
> >  1 file changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> > index 9b2e8d4..518c7b9 100644
> > --- a/drivers/firmware/arm_scmi/driver.c
> > +++ b/drivers/firmware/arm_scmi/driver.c
> > @@ -1430,7 +1430,7 @@ static int scmi_probe(struct platform_device *pdev)
> >  
> >  	ret = scmi_xfer_info_init(info);
> >  	if (ret)
> > -		return ret;
> > +		goto clear_txrx_setup;
> >  
> >  	if (scmi_notification_init(handle))
> >  		dev_err(dev, "SCMI Notifications NOT available.\n");
> > @@ -1443,7 +1443,7 @@ static int scmi_probe(struct platform_device *pdev)
> >  	ret = scmi_protocol_acquire(handle, SCMI_PROTOCOL_BASE);
> >  	if (ret) {
> >  		dev_err(dev, "unable to communicate with SCMI\n");
> > -		return ret;
> > +		goto notification_exit;
> >  	}
> >  
> >  	mutex_lock(&scmi_list_mutex);
> > @@ -1482,6 +1482,13 @@ static int scmi_probe(struct platform_device *pdev)
> >  	}
> >  
> >  	return 0;
> > +
> > +notification_exit:
> > +	scmi_notification_exit(&info->handle);
> > +clear_txrx_setup:
> > +	idr_for_each(&info->tx_idr, info->desc->ops->chan_free, &info->tx_idr);
> > +	idr_for_each(&info->rx_idr, info->desc->ops->chan_free, &info->rx_idr);
> > +	return ret;
> >  }
> >  
> 
> Shouldn't we also clear the internal IDRs memory allocs after these
> idr_for_each() adding a couple of:
> 
> 	idr_destroy(&info->tx_idr);
> 
> 	idr_destroy(&info->rx_idr);
> 
> like scmi_remove() does ?
> 

Maybe it could be worth at this point unifying this common "cleanup-all-channels"
logic shared between scmi_probe()-error-path and scmi_remove() into its own
helper function to call from both sites.

Thanks,
Cristian


From elver at google.com  Wed Aug  4 01:41:25 2021
From: elver at google.com (Marco Elver)
Date: Wed, 4 Aug 2021 10:41:25 +0200
Subject: [PATCH v2 2/2] kasan, slub: reset tag when printing address
In-Reply-To: <20210804082230.10837-3-Kuan-Ying.Lee@mediatek.com>
References: <20210804082230.10837-1-Kuan-Ying.Lee@mediatek.com>
 <20210804082230.10837-3-Kuan-Ying.Lee@mediatek.com>
Message-ID: <CANpmjNMAw=rcp_V+G_vjRjArj+09AkOxtC+wUNs-e1RRvfQm6w@mail.gmail.com>

On Wed, 4 Aug 2021 at 10:23, Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com> wrote:
>
> The address still includes the tags when it is printed.
> With hardware tag-based kasan enabled, we will get a
> false positive KASAN issue when we access metadata.
>
> Reset the tag before we access the metadata.
>
> Fixes: aa1ef4d7b3f6 ("kasan, mm: reset tags when accessing metadata")
> Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> Suggested-by: Marco Elver <elver at google.com>

Note, in this case Suggested-by is inappropriate, because I did not
suggest the change in any way (you already had it in v1). I just
commented on the fact that it's missing a Fixes so stable can pick it
up and some clarification.

Reviewed-by: Marco Elver <elver at google.com>

> ---
>  mm/slub.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/mm/slub.c b/mm/slub.c
> index b6c5205252eb..f77d8cd79ef7 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -576,8 +576,8 @@ static void print_section(char *level, char *text, u8 *addr,
>                           unsigned int length)
>  {
>         metadata_access_enable();
> -       print_hex_dump(level, kasan_reset_tag(text), DUMP_PREFIX_ADDRESS,
> -                       16, 1, addr, length, 1);
> +       print_hex_dump(level, text, DUMP_PREFIX_ADDRESS,
> +                       16, 1, kasan_reset_tag((void *)addr), length, 1);
>         metadata_access_disable();
>  }
>
> --
> 2.18.0


From nicolas.ferre at microchip.com  Wed Aug  4 01:43:16 2021
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Wed, 4 Aug 2021 10:43:16 +0200
Subject: [GIT PULL v2] ARM: at91: soc for 5.15
In-Reply-To: <20210804081721.11093-1-nicolas.ferre@microchip.com>
References: <20210804081721.11093-1-nicolas.ferre@microchip.com>
Message-ID: <20210804084316.12641-1-nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

Arnd, Olof,

Here are the soc changes for 5.15 which contains the introduction of our new
SoC family: the SAMA7G5.
Note that one header file is shared with the clock sub-system. We synchronized
with Stephen to make it appear in this Pull-Request.

- v1 -> v2: text of the signed tag aligned with kernel revision targeted.

Thanks, best regards,
  Nicolas

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git tags/at91-soc-5.15

for you to fetch changes up to ad9bc2e35cf575644064284943aefdde426644cc:

  ARM: at91: pm: add sama7g5 shdwc (2021-07-19 14:32:13 +0200)

----------------------------------------------------------------
AT91 soc for 5.15:

- add new SoC based on a Cortex-A7 core: the SAMA7G5 family
  - mach-at91 entry, Kconfig and header files
  - Power Management Controller (PMC) code and associated power management
    changes. Support for suspend/resume, Ultra Low Power modes and
    Backup with Memory in Self-Refresh mode.
  - Power management association with DDR controller and
    shutdown controller for addressing this variety of modes.

----------------------------------------------------------------
Claudiu Beznea (23):
      clk: at91: add register definition for sama7g5's master clock
      ARM: at91: pm: move pm_bu to soc_pm data structure
      ARM: at91: pm: move the setup of soc_pm.bu->suspended
      ARM: at91: pm: document at91_soc_pm structure
      ARM: at91: pm: check for different controllers in at91_pm_modes_init()
      ARM: at91: pm: do not initialize pdev
      ARM: at91: pm: use r7 instead of tmp1
      ARM: at91: pm: avoid push and pop on stack while memory is in self-refersh
      ARM: at91: pm: s/CONFIG_SOC_SAM9X60/CONFIG_HAVE_AT91_SAM9X60_PLL/g
      ARM: at91: pm: add support for waiting MCK1..4
      ARM: at91: sfrbu: add sfrbu registers definitions for sama7g5
      ARM: at91: ddr: add registers definitions for sama7g5's ddr
      ARM: at91: pm: add self-refresh support for sama7g5
      ARM: at91: pm: add support for MCK1..4 save/restore for ulp modes
      ARM: at91: pm: add support for 2.5V LDO regulator control
      ARM: at91: pm: wait for ddr power mode off
      ARM: at91: pm: add sama7g5 ddr controller
      ARM: at91: pm: add sama7g5 ddr phy controller
      ARM: at91: pm: save ddr phy calibration data to securam
      ARM: at91: pm: add backup mode support for SAMA7G5
      ARM: at91: pm: add sama7g5's pmc
      ARM: at91: pm: add pm support for SAMA7G5
      ARM: at91: pm: add sama7g5 shdwc

Eugen Hristev (3):
      ARM: at91: add new SoC sama7g5
      ARM: at91: debug: add sama7g5 low level debug uart
      ARM: at91: sama7: introduce sama7 SoC family

 arch/arm/Kconfig.debug               |  10 +
 arch/arm/mach-at91/Kconfig           |  18 +
 arch/arm/mach-at91/Makefile          |   1 +
 arch/arm/mach-at91/generic.h         |   2 +
 arch/arm/mach-at91/pm.c              | 343 +++++++++++----
 arch/arm/mach-at91/pm.h              |   3 +
 arch/arm/mach-at91/pm_data-offsets.c |   2 +
 arch/arm/mach-at91/pm_suspend.S      | 827 ++++++++++++++++++++++++++---------
 arch/arm/mach-at91/sama7.c           |  33 ++
 include/linux/clk/at91_pmc.h         |  26 ++
 include/soc/at91/sama7-ddr.h         |  80 ++++
 include/soc/at91/sama7-sfrbu.h       |  34 ++
 12 files changed, 1090 insertions(+), 289 deletions(-)
 create mode 100644 arch/arm/mach-at91/sama7.c
 create mode 100644 include/soc/at91/sama7-ddr.h
 create mode 100644 include/soc/at91/sama7-sfrbu.h

-- 
Nicolas Ferre


From nicolas.ferre at microchip.com  Wed Aug  4 01:46:31 2021
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Wed, 4 Aug 2021 10:46:31 +0200
Subject: [GIT PULL] ARM: at91: defconfig for 5.15
Message-ID: <20210804084631.12934-1-nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

Arnd, Olof,

Here are the defconfig changes for 5.15 which contains addition for SAMA7G5.

Thanks, best regards,
  Nicolas

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git tags/at91-defconfig-5.15

for you to fetch changes up to b62869dcd4bcf341d3750a2bcad9a80c6d5562a8:

  ARM: multi_v7_defconfig: add sama7g5 SoC (2021-07-19 15:25:42 +0200)

----------------------------------------------------------------
AT91 defconfig for 5.15:

- add defconfig entries for new SoC: SAMA7G5
  - dedicated sama7_defconfig to match the needed peripherals and
    dependencies
  - addition to the generic multi_v7_defconfig

----------------------------------------------------------------
Eugen Hristev (2):
      ARM: configs: at91: add defconfig for sama7 family of SoCs
      ARM: multi_v7_defconfig: add sama7g5 SoC

 arch/arm/configs/multi_v7_defconfig |   2 +
 arch/arm/configs/sama7_defconfig    | 209 +++++++++++++++++++++++++++++++++++
 2 files changed, 211 insertions(+)
 create mode 100644 arch/arm/configs/sama7_defconfig

-- 
Nicolas Ferre


From nicolas.ferre at microchip.com  Wed Aug  4 01:50:00 2021
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Wed, 4 Aug 2021 10:50:00 +0200
Subject: [GIT PULL] ARM: at91: dt for 5.15
Message-ID: <20210804085000.13233-1-nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

Arnd, Olof,

Here are the dt changes for 5.15 which contains addition of SAMA7G5, some
enhancements to current boards and a couple of (low priority) fixes.

Thanks, best regards,
  Nicolas

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git tags/at91-dt-5.15

for you to fetch changes up to 818c4593434e81c9971b8fc278215121622c755e:

  ARM: dts: at91: use the right property for shutdown controller (2021-08-02 12:34:09 +0200)

----------------------------------------------------------------
AT91 dt for 5.15:

- add sama7g5 SoC and associated evaluation kit, the sama7g5-ek
- adaptation of some DT for sama5d27 som1 ek, sama5d4 xplained and
  sama5d2 icp boards
- fixes to gpio and shutdown controller nodes for all boards

----------------------------------------------------------------
Claudiu Beznea (3):
      dt-bindings: atmel-sysreg: add bindings for sama7g5
      ARM: dts: at91: add pinctrl-{names, 0} for all gpios
      ARM: dts: at91: add conflict note for d3

Codrin Ciubotariu (1):
      ARM: dts: at91: sama5d2_icp: enable digital filter for I2C nodes

Eugen Hristev (3):
      dt-bindings: ARM: at91: document sama7g5ek board
      ARM: dts: at91: add sama7g5 SoC DT and sama7g5-ek
      ARM: dts: at91: sama5d27_som1_ek: enable ADC node

Ludovic Desroches (1):
      ARM: dts: at91: sama5d4_xplained: change the key code of the gpio key

Nicolas Ferre (1):
      ARM: dts: at91: use the right property for shutdown controller

Tudor Ambarus (1):
      ARM: dts: at91: sama5d4_xplained: Remove spi0 node

 .../devicetree/bindings/arm/atmel-at91.yaml        |   5 +
 .../devicetree/bindings/arm/atmel-sysregs.txt      |  14 +-
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/at91-kizbox3_common.dtsi         |   2 +-
 arch/arm/boot/dts/at91-sam9x60ek.dts               |  18 +-
 arch/arm/boot/dts/at91-sama5d27_som1_ek.dts        |   6 +-
 arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts      |   2 +-
 arch/arm/boot/dts/at91-sama5d2_icp.dts             |   8 +-
 arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts          |   2 +-
 arch/arm/boot/dts/at91-sama5d2_xplained.dts        |   2 +-
 arch/arm/boot/dts/at91-sama5d3_xplained.dts        |  31 +-
 arch/arm/boot/dts/at91-sama5d4_xplained.dts        |  32 +-
 arch/arm/boot/dts/at91-sama7g5ek.dts               | 656 +++++++++++++++
 arch/arm/boot/dts/sama7g5-pinfunc.h                | 923 +++++++++++++++++++++
 arch/arm/boot/dts/sama7g5.dtsi                     | 528 ++++++++++++
 15 files changed, 2209 insertions(+), 22 deletions(-)
 create mode 100644 arch/arm/boot/dts/at91-sama7g5ek.dts
 create mode 100644 arch/arm/boot/dts/sama7g5-pinfunc.h
 create mode 100644 arch/arm/boot/dts/sama7g5.dtsi

-- 
Nicolas Ferre


From maz at kernel.org  Wed Aug  4 01:50:08 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Aug 2021 09:50:08 +0100
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
Message-ID: <87sfzpwq4f.wl-maz@kernel.org>

On Wed, 04 Aug 2021 02:36:45 +0100,
Saravana Kannan <saravanak at google.com> wrote:

Hi Saravana,

Thanks for looking into this.

[...]

> > Saravana, could you please have a look from a fw_devlink perspective?
> 
> Sigh... I spent several hours looking at this and wrote up an analysis
> and then realized I might be looking at the wrong DT files.
> 
> Marc, can you point me to the board file in upstream that corresponds
> to the platform in which you see this issue? I'm not asking for [1],
> but the actual final .dts (not .dtsi) file that corresponds to the
> platform/board/system.

The platform I can reproduce this on is described in
arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts. It is an
intricate maze of inclusion, node merge and other DT subtleties. I
suggest you look at the decompiled version to get a view of the
result.

> Based on your error messages, it's failing for mdio at 0 which
> corresponds to ext_mdio. But none of the board dts files in upstream
> have a compatible property for "ext_mdio". Which means fw_devlink
> _should_ propagate the gpio_intc IRQ dependency all the way up to
> eth_phy.
> 
> Also, in the failing case, can you run:
> ls -ld supplier:*
> 
> in the /sys/devices/....<something>/ folder that corresponds to the
> "eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?

Here you go:

root at tiger-roach:~# find /sys/devices/ -name 'supplier*'|grep -i mdio | xargs ls -ld
lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/platform/soc/ff600000.bus/ff64c000.mdio-multiplexer/supplier:platform:ff63c000.system-controller:clock-controller -> ../../../../virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer
lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer/supplier -> ../../../platform/soc/ff600000.bus/ff63c000.bus/ff63c000.system-controller/ff63c000.system-controller:clock-controller

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From yuzenghui at huawei.com  Wed Aug  4 01:51:01 2021
From: yuzenghui at huawei.com (Zenghui Yu)
Date: Wed, 4 Aug 2021 16:51:01 +0800
Subject: [PATCH 3/5] ARM: remove zte zx platform
In-Reply-To: <20210120124812.2800027-4-arnd@kernel.org>
References: <20210120124812.2800027-1-arnd@kernel.org>
 <20210120124812.2800027-4-arnd@kernel.org>
Message-ID: <2ce5cd86-ed0d-3e5f-2ab4-717e055dfef4@huawei.com>

On 2021/1/20 20:48, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> The ZTE ZX set-top-box SoC platform was added in 2015 by Jun Nie, with
> Baoyou Xie and Shawn Guo subsequently becoming maintainers after the
> addition of the 64-bit variant.
> 
> However, the only machines that were ever supported upstream are the
> reference designs, not actual set-top-box devices that would benefit
> from this support. All ZTE set-top-boxes from the past few years seem
> to be based on third-party SoCs. While there is very little information
> about zx296702 and zx296718 on the web, I found some references to other
> chips from the same family, such as zx296716 and zx296719, which were
> never submitted for upstream support. Finally, there is no support for
> the GPU on either of them, with the lima and panfrost device drivers
> having been added after work on the zx platform had stopped.
> 
> Shawn confirmed that he has not seen any interest in this platform for
> the past four years, and that it can be removed.
> 
> Thanks to Jun and Shawn for maintaining this platform over the past
> five years.
> 
> Cc: Jun Nie <jun.nie at linaro.org>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

[...]

> diff --git a/MAINTAINERS b/MAINTAINERS
> index aeef69cbc7ec..54b5e6dee017 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2704,40 +2704,6 @@ S:	Maintained
>  F:	arch/arm/mach-pxa/include/mach/z2.h
>  F:	arch/arm/mach-pxa/z2.c
>   
> -ARM/ZTE ARCHITECTURE
> -M:	Jun Nie <jun.nie at linaro.org>
> -M:	Shawn Guo <shawnguo at kernel.org>
> -L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> -S:	Maintained

[...]

> -F:	include/dt-bindings/clock/zx2967*.h

include/dt-bindings/clock/zx296718-clock.h hadn't been removed.

> -F:	include/dt-bindings/soc/zte,*.h

include/dt-bindings/soc/zte,pm_domains.h neither.

> -DRM DRIVERS FOR ZTE ZX
> -M:	Shawn Guo <shawnguo at kernel.org>
> -L:	dri-devel at lists.freedesktop.org
> -S:	Maintained
> -T:	git git://anongit.freedesktop.org/drm/drm-misc
> -F:	Documentation/devicetree/bindings/display/zte,vou.txt
> -F:	drivers/gpu/drm/zte/

The whole zxdrm driver is still in tree, which smells like a leftover.

> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 6eecdef538bd..ec3c0cb27d1e 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -317,12 +317,6 @@ config ARCH_XGENE
>  	help
>  	  This enables support for AppliedMicro X-Gene SOC Family
>  
> -config ARCH_ZX
> -	bool "ZTE ZX SoC Family"
> -	select PINCTRL
> -	help
> -	  This enables support for ZTE ZX SoC Family

And ARCH_ZX is still selected in arm64's defconfig (which is why I
jumped in this series).


From oupton at google.com  Wed Aug  4 01:57:59 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:57:59 +0000
Subject: [PATCH v6 01/21] KVM: x86: Fix potential race in KVM_GET_CLOCK
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-2-oupton@google.com>

Sean noticed that KVM_GET_CLOCK was checking kvm_arch.use_master_clock
outside of the pvclock sync lock. This is problematic, as the clock
value written to the user may or may not actually correspond to a stable
TSC.

Fix the race by populating the entire kvm_clock_data structure behind
the pvclock_gtod_sync_lock.

Suggested-by: Sean Christopherson <seanjc at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/x86/kvm/x86.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 8cdf4ac6990b..34287c522f4e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2782,19 +2782,20 @@ static void kvm_gen_update_masterclock(struct kvm *kvm)
 #endif
 }
 
-u64 get_kvmclock_ns(struct kvm *kvm)
+static void get_kvmclock(struct kvm *kvm, struct kvm_clock_data *data)
 {
 	struct kvm_arch *ka = &kvm->arch;
 	struct pvclock_vcpu_time_info hv_clock;
 	unsigned long flags;
-	u64 ret;
 
 	spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
 	if (!ka->use_master_clock) {
 		spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
-		return get_kvmclock_base_ns() + ka->kvmclock_offset;
+		data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset;
+		return;
 	}
 
+	data->flags |= KVM_CLOCK_TSC_STABLE;
 	hv_clock.tsc_timestamp = ka->master_cycle_now;
 	hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
 	spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
@@ -2806,13 +2807,26 @@ u64 get_kvmclock_ns(struct kvm *kvm)
 		kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
 				   &hv_clock.tsc_shift,
 				   &hv_clock.tsc_to_system_mul);
-		ret = __pvclock_read_cycles(&hv_clock, rdtsc());
-	} else
-		ret = get_kvmclock_base_ns() + ka->kvmclock_offset;
+		data->clock = __pvclock_read_cycles(&hv_clock, rdtsc());
+	} else {
+		data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset;
+	}
 
 	put_cpu();
+}
 
-	return ret;
+u64 get_kvmclock_ns(struct kvm *kvm)
+{
+	struct kvm_clock_data data;
+
+	/*
+	 * Zero flags as it's accessed RMW, leave everything else uninitialized
+	 * as clock is always written and no other fields are consumed.
+	 */
+	data.flags = 0;
+
+	get_kvmclock(kvm, &data);
+	return data.clock;
 }
 
 static void kvm_setup_pvclock_page(struct kvm_vcpu *v,
@@ -6104,11 +6118,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
 	}
 	case KVM_GET_CLOCK: {
 		struct kvm_clock_data user_ns;
-		u64 now_ns;
 
-		now_ns = get_kvmclock_ns(kvm);
-		user_ns.clock = now_ns;
-		user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0;
+		/*
+		 * Zero flags as it is accessed RMW, leave everything else
+		 * uninitialized as clock is always written and no other fields
+		 * are consumed.
+		 */
+		user_ns.flags = 0;
+		get_kvmclock(kvm, &user_ns);
 		memset(&user_ns.pad, 0, sizeof(user_ns.pad));
 
 		r = -EFAULT;
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:57:58 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:57:58 +0000
Subject: [PATCH v6 00/21] KVM: Add idempotent controls for migrating system
 counter state
Message-ID: <20210804085819.846610-1-oupton@google.com>

KVM's current means of saving/restoring system counters is plagued with
temporal issues. At least on ARM64 and x86, we migrate the guest's
system counter by-value through the respective guest system register
values (cntvct_el0, ia32_tsc). Restoring system counters by-value is
brittle as the state is not idempotent: the host system counter is still
oscillating between the attempted save and restore. Furthermore, VMMs
may wish to transparently live migrate guest VMs, meaning that they
include the elapsed time due to live migration blackout in the guest
system counter view. The VMM thread could be preempted for any number of
reasons (scheduler, L0 hypervisor under nested) between the time that
it calculates the desired guest counter value and when KVM actually sets
this counter state.

Despite the value-based interface that we present to userspace, KVM
actually has idempotent guest controls by way of system counter offsets.
We can avoid all of the issues associated with a value-based interface
by abstracting these offset controls in new ioctls. This series
introduces new vCPU device attributes to provide userspace access to the
vCPU's system counter offset.

Patch 1 addresses a possible race in KVM_GET_CLOCK where
use_master_clock is read outside of the pvclock_gtod_sync_lock.

Patch 2 adopts Paolo's suggestion, augmenting the KVM_{GET,SET}_CLOCK
ioctls to provide userspace with a (host_tsc, realtime) instant. This is
essential for a VMM to perform precise migration of the guest's system
counters.

Patches 3-4 are some preparatory changes for exposing the TSC offset to
userspace. Patch 5 provides a vCPU attribute to provide userspace access
to the TSC offset.

Patches 6-7 implement a test for the new additions to
KVM_{GET,SET}_CLOCK.

Patch 8 fixes some assertions in the kvm device attribute helpers.

Patches 9-10 implement at test for the tsc offset attribute introduced in
patch 5.

Patches 11-12 lay the groundwork for patch 13, which exposes CNTVOFF_EL2
through the ONE_REG interface.

Patches 14-15 add test cases for userspace manipulation of the virtual
counter-timer.

Patches 16-17 add a vCPU attribute to adjust the host-guest offset of an
ARM vCPU, but only implements support for ECV hosts. Patches 18-19 add
support for non-ECV hosts by emulating physical counter offsetting.

Patch 20 adds test cases for adjusting the host-guest offset, and
finally patch 21 adds a test to measure the emulation overhead of
CNTPCT_EL2.

This series was tested on both an Ampere Mt. Jade and Haswell systems.
Unfortunately, the ECV portions of this series are untested, as there is
no ECV-capable hardware and the ARM fast models only partially implement
ECV.

Physical counter benchmark
--------------------------

The following data was collected by running 10000 iterations of the
benchmark test from Patch 21 on an Ampere Mt. Jade reference server, A 2S
machine with 2 80-core Ampere Altra SoCs. Measurements were collected
for both VHE and nVHE operation using the `kvm-arm.mode=` command-line
parameter.

nVHE
----

+--------------------+--------+---------+
|       Metric       | Native | Trapped |
+--------------------+--------+---------+
| Average            | 54ns   | 148ns   |
| Standard Deviation | 124ns  | 122ns   |
| 95th Percentile    | 258ns  | 348ns   |
+--------------------+--------+---------+

VHE
---

+--------------------+--------+---------+
|       Metric       | Native | Trapped |
+--------------------+--------+---------+
| Average            | 53ns   | 152ns   |
| Standard Deviation | 92ns   | 94ns    |
| 95th Percentile    | 204ns  | 307ns   |
+--------------------+--------+---------+

This series applies cleanly to kvm/queue at the following commit:

6cd974485e25 ("KVM: selftests: Add a test of an unbacked nested PI descriptor")

v1 -> v2:
  - Reimplemented as vCPU device attributes instead of a distinct ioctl.
  - Added the (realtime, host_tsc) instant support to KVM_{GET,SET}_CLOCK
  - Changed the arm64 implementation to broadcast counter
    offset values to all vCPUs in a guest. This upholds the
    architectural expectations of a consistent counter-timer across CPUs.
  - Fixed a bug with traps in VHE mode. We now configure traps on every
    transition into a guest to handle differing VMs (trapped, emulated).

v2 -> v3:
  - Added documentation for additions to KVM_{GET,SET}_CLOCK
  - Added documentation for all new vCPU attributes
  - Added documentation for suggested algorithm to migrate a guest's
    TSC(s)
  - Bug fixes throughout series
  - Rename KVM_CLOCK_REAL_TIME -> KVM_CLOCK_REALTIME

v3 -> v4:
  - Added patch to address incorrect device helper assertions (Drew)
  - Carried Drew's r-b tags where appropriate
  - x86 selftest cleanup
  - Removed stale kvm_timer_init_vhe() function
  - Removed unnecessary GUEST_DONE() from selftests

v4 -> v5:
  - Fix typo in TSC migration algorithm
  - Carry more of Drew's r-b tags
  - clean up run loop logic in counter emulation benchmark (missed from
    Drew's comments on v3)

v5 -> v6:
  - Add fix for race in KVM_GET_CLOCK (Sean)
  - Fix 32-bit build issues in series + use of uninitialized host tsc
    value (Sean)
  - General style cleanups
  - Rework ARM virtual counter offsetting to match guest behavior. Use
    the ONE_REG interface instead of a VM attribute (Marc)
  - Maintain a single host-guest counter offset, which applies to both
    physical and virtual counters
  - Dropped some of Drew's r-b tags due to nontrivial patch changes
    (sorry for the churn!)

v1: https://lore.kernel.org/kvm/20210608214742.1897483-1-oupton at google.com/
v2: https://lore.kernel.org/r/20210716212629.2232756-1-oupton at google.com
v3: https://lore.kernel.org/r/20210719184949.1385910-1-oupton at google.com
v4: https://lore.kernel.org/r/20210729001012.70394-1-oupton at google.com
v5: https://lore.kernel.org/r/20210729173300.181775-1-oupton at google.com

Oliver Upton (21):
  KVM: x86: Fix potential race in KVM_GET_CLOCK
  KVM: x86: Report host tsc and realtime values in KVM_GET_CLOCK
  KVM: x86: Take the pvclock sync lock behind the tsc_write_lock
  KVM: x86: Refactor tsc synchronization code
  KVM: x86: Expose TSC offset controls to userspace
  tools: arch: x86: pull in pvclock headers
  selftests: KVM: Add test for KVM_{GET,SET}_CLOCK
  selftests: KVM: Fix kvm device helper ioctl assertions
  selftests: KVM: Add helpers for vCPU device attributes
  selftests: KVM: Introduce system counter offset test
  KVM: arm64: Refactor update_vtimer_cntvoff()
  KVM: arm64: Separate guest/host counter offset values
  KVM: arm64: Allow userspace to configure a vCPU's virtual offset
  selftests: KVM: Add helper to check for register presence
  selftests: KVM: Add support for aarch64 to system_counter_offset_test
  arm64: cpufeature: Enumerate support for Enhanced Counter
    Virtualization
  KVM: arm64: Allow userspace to configure a guest's counter-timer
    offset
  KVM: arm64: Configure timer traps in vcpu_load() for VHE
  KVM: arm64: Emulate physical counter offsetting on non-ECV systems
  selftests: KVM: Test physical counter offsetting
  selftests: KVM: Add counter emulation benchmark

 Documentation/virt/kvm/api.rst                |  52 ++-
 Documentation/virt/kvm/devices/vcpu.rst       |  85 ++++
 Documentation/virt/kvm/locking.rst            |  11 +
 arch/arm64/include/asm/kvm_asm.h              |   2 +
 arch/arm64/include/asm/sysreg.h               |   5 +
 arch/arm64/include/uapi/asm/kvm.h             |   2 +
 arch/arm64/kernel/cpufeature.c                |  10 +
 arch/arm64/kvm/arch_timer.c                   | 224 ++++++++++-
 arch/arm64/kvm/arm.c                          |   4 +-
 arch/arm64/kvm/guest.c                        |   6 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h       |  29 ++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |   6 +
 arch/arm64/kvm/hyp/nvhe/timer-sr.c            |  16 +-
 arch/arm64/kvm/hyp/vhe/timer-sr.c             |   5 +
 arch/arm64/tools/cpucaps                      |   1 +
 arch/x86/include/asm/kvm_host.h               |   4 +
 arch/x86/include/uapi/asm/kvm.h               |   4 +
 arch/x86/kvm/x86.c                            | 364 +++++++++++++-----
 include/clocksource/arm_arch_timer.h          |   1 +
 include/kvm/arm_arch_timer.h                  |   6 +-
 include/uapi/linux/kvm.h                      |   7 +-
 tools/arch/x86/include/asm/pvclock-abi.h      |  48 +++
 tools/arch/x86/include/asm/pvclock.h          | 103 +++++
 tools/testing/selftests/kvm/.gitignore        |   3 +
 tools/testing/selftests/kvm/Makefile          |   4 +
 .../kvm/aarch64/counter_emulation_benchmark.c | 207 ++++++++++
 .../selftests/kvm/include/aarch64/processor.h |  24 ++
 .../testing/selftests/kvm/include/kvm_util.h  |  13 +
 tools/testing/selftests/kvm/lib/kvm_util.c    |  63 ++-
 .../kvm/system_counter_offset_test.c          | 211 ++++++++++
 .../selftests/kvm/x86_64/kvm_clock_test.c     | 204 ++++++++++
 31 files changed, 1581 insertions(+), 143 deletions(-)
 create mode 100644 tools/arch/x86/include/asm/pvclock-abi.h
 create mode 100644 tools/arch/x86/include/asm/pvclock.h
 create mode 100644 tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
 create mode 100644 tools/testing/selftests/kvm/system_counter_offset_test.c
 create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_clock_test.c

-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:01 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:01 +0000
Subject: [PATCH v6 03/21] KVM: x86: Take the pvclock sync lock behind the
 tsc_write_lock
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-4-oupton@google.com>

A later change requires that the pvclock sync lock be taken while
holding the tsc_write_lock. Change the locking in kvm_synchronize_tsc()
to align with the requirement to isolate the locking change to its own
commit.

Cc: Sean Christopherson <seanjc at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 Documentation/virt/kvm/locking.rst | 11 +++++++++++
 arch/x86/kvm/x86.c                 |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/locking.rst
index 8138201efb09..0bf346adac2a 100644
--- a/Documentation/virt/kvm/locking.rst
+++ b/Documentation/virt/kvm/locking.rst
@@ -36,6 +36,9 @@ On x86:
   holding kvm->arch.mmu_lock (typically with ``read_lock``, otherwise
   there's no need to take kvm->arch.tdp_mmu_pages_lock at all).
 
+- kvm->arch.tsc_write_lock is taken outside
+  kvm->arch.pvclock_gtod_sync_lock
+
 Everything else is a leaf: no other lock is taken inside the critical
 sections.
 
@@ -222,6 +225,14 @@ time it will be set using the Dirty tracking mechanism described above.
 :Comment:	'raw' because hardware enabling/disabling must be atomic /wrt
 		migration.
 
+:Name:		kvm_arch::pvclock_gtod_sync_lock
+:Type:		raw_spinlock_t
+:Arch:		x86
+:Protects:	kvm_arch::{cur_tsc_generation,cur_tsc_nsec,cur_tsc_write,
+			cur_tsc_offset,nr_vcpus_matched_tsc}
+:Comment:	'raw' because updating the kvm master clock must not be
+		preempted.
+
 :Name:		kvm_arch::tsc_write_lock
 :Type:		raw_spinlock
 :Arch:		x86
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 26f1fa263192..93b449761fbe 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2529,7 +2529,6 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
 	vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
 
 	kvm_vcpu_write_tsc_offset(vcpu, offset);
-	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
 
 	spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags);
 	if (!matched) {
@@ -2540,6 +2539,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
 
 	kvm_track_tsc_matching(vcpu);
 	spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags);
+	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
 }
 
 static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:00 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:00 +0000
Subject: [PATCH v6 02/21] KVM: x86: Report host tsc and realtime values in
 KVM_GET_CLOCK
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-3-oupton@google.com>

Handling the migration of TSCs correctly is difficult, in part because
Linux does not provide userspace with the ability to retrieve a (TSC,
realtime) clock pair for a single instant in time. In lieu of a more
convenient facility, KVM can report similar information in the kvm_clock
structure.

Provide userspace with a host TSC & realtime pair iff the realtime clock
is based on the TSC. If userspace provides KVM_SET_CLOCK with a valid
realtime value, advance the KVM clock by the amount of elapsed time. Do
not step the KVM clock backwards, though, as it is a monotonic
oscillator.

Suggested-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 Documentation/virt/kvm/api.rst  |  42 ++++++++---
 arch/x86/include/asm/kvm_host.h |   3 +
 arch/x86/kvm/x86.c              | 127 ++++++++++++++++++--------------
 include/uapi/linux/kvm.h        |   7 +-
 4 files changed, 112 insertions(+), 67 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index dae68e68ca23..8d4a3471ad9e 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -993,20 +993,34 @@ such as migration.
 When KVM_CAP_ADJUST_CLOCK is passed to KVM_CHECK_EXTENSION, it returns the
 set of bits that KVM can return in struct kvm_clock_data's flag member.
 
-The only flag defined now is KVM_CLOCK_TSC_STABLE.  If set, the returned
-value is the exact kvmclock value seen by all VCPUs at the instant
-when KVM_GET_CLOCK was called.  If clear, the returned value is simply
-CLOCK_MONOTONIC plus a constant offset; the offset can be modified
-with KVM_SET_CLOCK.  KVM will try to make all VCPUs follow this clock,
-but the exact value read by each VCPU could differ, because the host
-TSC is not stable.
+FLAGS:
+
+KVM_CLOCK_TSC_STABLE.  If set, the returned value is the exact kvmclock
+value seen by all VCPUs at the instant when KVM_GET_CLOCK was called.
+If clear, the returned value is simply CLOCK_MONOTONIC plus a constant
+offset; the offset can be modified with KVM_SET_CLOCK.  KVM will try
+to make all VCPUs follow this clock, but the exact value read by each
+VCPU could differ, because the host TSC is not stable.
+
+KVM_CLOCK_REALTIME.  If set, the `realtime` field in the kvm_clock_data
+structure is populated with the value of the host's real time
+clocksource at the instant when KVM_GET_CLOCK was called. If clear,
+the `realtime` field does not contain a value.
+
+KVM_CLOCK_HOST_TSC.  If set, the `host_tsc` field in the kvm_clock_data
+structure is populated with the value of the host's timestamp counter (TSC)
+at the instant when KVM_GET_CLOCK was called. If clear, the `host_tsc` field
+does not contain a value.
 
 ::
 
   struct kvm_clock_data {
 	__u64 clock;  /* kvmclock current value */
 	__u32 flags;
-	__u32 pad[9];
+	__u32 pad0;
+	__u64 realtime;
+	__u64 host_tsc;
+	__u32 pad[4];
   };
 
 
@@ -1023,12 +1037,22 @@ Sets the current timestamp of kvmclock to the value specified in its parameter.
 In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
 such as migration.
 
+FLAGS:
+
+KVM_CLOCK_REALTIME.  If set, KVM will compare the value of the `realtime` field
+with the value of the host's real time clocksource at the instant when
+KVM_SET_CLOCK was called. The difference in elapsed time is added to the final
+kvmclock value that will be provided to guests.
+
 ::
 
   struct kvm_clock_data {
 	__u64 clock;  /* kvmclock current value */
 	__u32 flags;
-	__u32 pad[9];
+	__u32 pad0;
+	__u64 realtime;
+	__u64 host_tsc;
+	__u32 pad[4];
   };
 
 
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 6818095dd157..d6376ca8efce 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1926,4 +1926,7 @@ int kvm_cpu_dirty_log_size(void);
 
 int alloc_all_memslots_rmaps(struct kvm *kvm);
 
+#define KVM_CLOCK_VALID_FLAGS						\
+	(KVM_CLOCK_TSC_STABLE | KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC)
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 34287c522f4e..26f1fa263192 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2804,10 +2804,20 @@ static void get_kvmclock(struct kvm *kvm, struct kvm_clock_data *data)
 	get_cpu();
 
 	if (__this_cpu_read(cpu_tsc_khz)) {
+#ifdef CONFIG_X86_64
+		struct timespec64 ts;
+
+		if (kvm_get_walltime_and_clockread(&ts, &data->host_tsc)) {
+			data->realtime = ts.tv_nsec + NSEC_PER_SEC * ts.tv_sec;
+			data->flags |= KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC;
+		} else
+#endif
+		data->host_tsc = rdtsc();
+
 		kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
 				   &hv_clock.tsc_shift,
 				   &hv_clock.tsc_to_system_mul);
-		data->clock = __pvclock_read_cycles(&hv_clock, rdtsc());
+		data->clock = __pvclock_read_cycles(&hv_clock, data->host_tsc);
 	} else {
 		data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset;
 	}
@@ -4047,7 +4057,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = KVM_SYNC_X86_VALID_FIELDS;
 		break;
 	case KVM_CAP_ADJUST_CLOCK:
-		r = KVM_CLOCK_TSC_STABLE;
+		r = KVM_CLOCK_VALID_FLAGS;
 		break;
 	case KVM_CAP_X86_DISABLE_EXITS:
 		r |=  KVM_X86_DISABLE_EXITS_HLT | KVM_X86_DISABLE_EXITS_PAUSE |
@@ -5834,6 +5844,60 @@ int kvm_arch_pm_notifier(struct kvm *kvm, unsigned long state)
 }
 #endif /* CONFIG_HAVE_KVM_PM_NOTIFIER */
 
+static int kvm_vm_ioctl_get_clock(struct kvm *kvm, void __user *argp)
+{
+	struct kvm_clock_data data;
+
+	memset(&data, 0, sizeof(data));
+	get_kvmclock(kvm, &data);
+
+	if (copy_to_user(argp, &data, sizeof(data)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int kvm_vm_ioctl_set_clock(struct kvm *kvm, void __user *argp)
+{
+	struct kvm_arch *ka = &kvm->arch;
+	struct kvm_clock_data data;
+	u64 now_raw_ns;
+
+	if (copy_from_user(&data, argp, sizeof(data)))
+		return -EFAULT;
+
+	if (data.flags & ~KVM_CLOCK_REALTIME)
+		return -EINVAL;
+
+	/*
+	 * TODO: userspace has to take care of races with VCPU_RUN, so
+	 * kvm_gen_update_masterclock() can be cut down to locked
+	 * pvclock_update_vm_gtod_copy().
+	 */
+	kvm_gen_update_masterclock(kvm);
+
+	spin_lock_irq(&ka->pvclock_gtod_sync_lock);
+	if (data.flags & KVM_CLOCK_REALTIME) {
+		u64 now_real_ns = ktime_get_real_ns();
+
+		/*
+		 * Avoid stepping the kvmclock backwards.
+		 */
+		if (now_real_ns > data.realtime)
+			data.clock += now_real_ns - data.realtime;
+	}
+
+	if (ka->use_master_clock)
+		now_raw_ns = ka->master_kernel_ns;
+	else
+		now_raw_ns = get_kvmclock_base_ns();
+	ka->kvmclock_offset = data.clock - now_raw_ns;
+	spin_unlock_irq(&ka->pvclock_gtod_sync_lock);
+
+	kvm_make_all_cpus_request(kvm, KVM_REQ_CLOCK_UPDATE);
+	return 0;
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
@@ -6077,63 +6141,12 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		break;
 	}
 #endif
-	case KVM_SET_CLOCK: {
-		struct kvm_arch *ka = &kvm->arch;
-		struct kvm_clock_data user_ns;
-		u64 now_ns;
-
-		r = -EFAULT;
-		if (copy_from_user(&user_ns, argp, sizeof(user_ns)))
-			goto out;
-
-		r = -EINVAL;
-		if (user_ns.flags)
-			goto out;
-
-		r = 0;
-		/*
-		 * TODO: userspace has to take care of races with VCPU_RUN, so
-		 * kvm_gen_update_masterclock() can be cut down to locked
-		 * pvclock_update_vm_gtod_copy().
-		 */
-		kvm_gen_update_masterclock(kvm);
-
-		/*
-		 * This pairs with kvm_guest_time_update(): when masterclock is
-		 * in use, we use master_kernel_ns + kvmclock_offset to set
-		 * unsigned 'system_time' so if we use get_kvmclock_ns() (which
-		 * is slightly ahead) here we risk going negative on unsigned
-		 * 'system_time' when 'user_ns.clock' is very small.
-		 */
-		spin_lock_irq(&ka->pvclock_gtod_sync_lock);
-		if (kvm->arch.use_master_clock)
-			now_ns = ka->master_kernel_ns;
-		else
-			now_ns = get_kvmclock_base_ns();
-		ka->kvmclock_offset = user_ns.clock - now_ns;
-		spin_unlock_irq(&ka->pvclock_gtod_sync_lock);
-
-		kvm_make_all_cpus_request(kvm, KVM_REQ_CLOCK_UPDATE);
+	case KVM_SET_CLOCK:
+		r = kvm_vm_ioctl_set_clock(kvm, argp);
 		break;
-	}
-	case KVM_GET_CLOCK: {
-		struct kvm_clock_data user_ns;
-
-		/*
-		 * Zero flags as it is accessed RMW, leave everything else
-		 * uninitialized as clock is always written and no other fields
-		 * are consumed.
-		 */
-		user_ns.flags = 0;
-		get_kvmclock(kvm, &user_ns);
-		memset(&user_ns.pad, 0, sizeof(user_ns.pad));
-
-		r = -EFAULT;
-		if (copy_to_user(argp, &user_ns, sizeof(user_ns)))
-			goto out;
-		r = 0;
+	case KVM_GET_CLOCK:
+		r = kvm_vm_ioctl_get_clock(kvm, argp);
 		break;
-	}
 	case KVM_MEMORY_ENCRYPT_OP: {
 		r = -ENOTTY;
 		if (kvm_x86_ops.mem_enc_op)
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index d9e4aabcb31a..53a49cb8616a 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1223,11 +1223,16 @@ struct kvm_irqfd {
 
 /* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags.  */
 #define KVM_CLOCK_TSC_STABLE		2
+#define KVM_CLOCK_REALTIME		(1 << 2)
+#define KVM_CLOCK_HOST_TSC		(1 << 3)
 
 struct kvm_clock_data {
 	__u64 clock;
 	__u32 flags;
-	__u32 pad[9];
+	__u32 pad0;
+	__u64 realtime;
+	__u64 host_tsc;
+	__u32 pad[4];
 };
 
 /* For KVM_CAP_SW_TLB */
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:02 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:02 +0000
Subject: [PATCH v6 04/21] KVM: x86: Refactor tsc synchronization code
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-5-oupton@google.com>

Refactor kvm_synchronize_tsc to make a new function that allows callers
to specify TSC parameters (offset, value, nanoseconds, etc.) explicitly
for the sake of participating in TSC synchronization.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/x86/kvm/x86.c | 105 ++++++++++++++++++++++++++-------------------
 1 file changed, 61 insertions(+), 44 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 93b449761fbe..91aea751d621 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2443,13 +2443,71 @@ static inline bool kvm_check_tsc_unstable(void)
 	return check_tsc_unstable();
 }
 
+/*
+ * Infers attempts to synchronize the guest's tsc from host writes. Sets the
+ * offset for the vcpu and tracks the TSC matching generation that the vcpu
+ * participates in.
+ */
+static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc,
+				  u64 ns, bool matched)
+{
+	struct kvm *kvm = vcpu->kvm;
+	bool already_matched;
+
+	lockdep_assert_held(&kvm->arch.tsc_write_lock);
+
+	already_matched =
+	       (vcpu->arch.this_tsc_generation == kvm->arch.cur_tsc_generation);
+
+	/*
+	 * We track the most recent recorded KHZ, write and time to
+	 * allow the matching interval to be extended at each write.
+	 */
+	kvm->arch.last_tsc_nsec = ns;
+	kvm->arch.last_tsc_write = tsc;
+	kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz;
+
+	vcpu->arch.last_guest_tsc = tsc;
+
+	/* Keep track of which generation this VCPU has synchronized to */
+	vcpu->arch.this_tsc_generation = kvm->arch.cur_tsc_generation;
+	vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec;
+	vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
+
+	kvm_vcpu_write_tsc_offset(vcpu, offset);
+
+	if (!matched) {
+		/*
+		 * We split periods of matched TSC writes into generations.
+		 * For each generation, we track the original measured
+		 * nanosecond time, offset, and write, so if TSCs are in
+		 * sync, we can match exact offset, and if not, we can match
+		 * exact software computation in compute_guest_tsc()
+		 *
+		 * These values are tracked in kvm->arch.cur_xxx variables.
+		 */
+		kvm->arch.cur_tsc_generation++;
+		kvm->arch.cur_tsc_nsec = ns;
+		kvm->arch.cur_tsc_write = tsc;
+		kvm->arch.cur_tsc_offset = offset;
+
+		spin_lock(&kvm->arch.pvclock_gtod_sync_lock);
+		kvm->arch.nr_vcpus_matched_tsc = 0;
+	} else if (!already_matched) {
+		spin_lock(&kvm->arch.pvclock_gtod_sync_lock);
+		kvm->arch.nr_vcpus_matched_tsc++;
+	}
+
+	kvm_track_tsc_matching(vcpu);
+	spin_unlock(&kvm->arch.pvclock_gtod_sync_lock);
+}
+
 static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
 {
 	struct kvm *kvm = vcpu->kvm;
 	u64 offset, ns, elapsed;
 	unsigned long flags;
-	bool matched;
-	bool already_matched;
+	bool matched = false;
 	bool synchronizing = false;
 
 	raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
@@ -2495,50 +2553,9 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
 			offset = kvm_compute_l1_tsc_offset(vcpu, data);
 		}
 		matched = true;
-		already_matched = (vcpu->arch.this_tsc_generation == kvm->arch.cur_tsc_generation);
-	} else {
-		/*
-		 * We split periods of matched TSC writes into generations.
-		 * For each generation, we track the original measured
-		 * nanosecond time, offset, and write, so if TSCs are in
-		 * sync, we can match exact offset, and if not, we can match
-		 * exact software computation in compute_guest_tsc()
-		 *
-		 * These values are tracked in kvm->arch.cur_xxx variables.
-		 */
-		kvm->arch.cur_tsc_generation++;
-		kvm->arch.cur_tsc_nsec = ns;
-		kvm->arch.cur_tsc_write = data;
-		kvm->arch.cur_tsc_offset = offset;
-		matched = false;
 	}
 
-	/*
-	 * We also track th most recent recorded KHZ, write and time to
-	 * allow the matching interval to be extended at each write.
-	 */
-	kvm->arch.last_tsc_nsec = ns;
-	kvm->arch.last_tsc_write = data;
-	kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz;
-
-	vcpu->arch.last_guest_tsc = data;
-
-	/* Keep track of which generation this VCPU has synchronized to */
-	vcpu->arch.this_tsc_generation = kvm->arch.cur_tsc_generation;
-	vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec;
-	vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
-
-	kvm_vcpu_write_tsc_offset(vcpu, offset);
-
-	spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags);
-	if (!matched) {
-		kvm->arch.nr_vcpus_matched_tsc = 0;
-	} else if (!already_matched) {
-		kvm->arch.nr_vcpus_matched_tsc++;
-	}
-
-	kvm_track_tsc_matching(vcpu);
-	spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags);
+	__kvm_synchronize_tsc(vcpu, offset, data, ns, matched);
 	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
 }
 
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:03 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:03 +0000
Subject: [PATCH v6 05/21] KVM: x86: Expose TSC offset controls to userspace
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-6-oupton@google.com>

To date, VMM-directed TSC synchronization and migration has been a bit
messy. KVM has some baked-in heuristics around TSC writes to infer if
the VMM is attempting to synchronize. This is problematic, as it depends
on host userspace writing to the guest's TSC within 1 second of the last
write.

A much cleaner approach to configuring the guest's views of the TSC is to
simply migrate the TSC offset for every vCPU. Offsets are idempotent,
and thus not subject to change depending on when the VMM actually
reads/writes values from/to KVM. The VMM can then read the TSC once with
KVM_GET_CLOCK to capture a (realtime, host_tsc) pair at the instant when
the guest is paused.

Cc: David Matlack <dmatlack at google.com>
Cc: Sean Christopherson <seanjc at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 Documentation/virt/kvm/devices/vcpu.rst |  57 +++++++++++++
 arch/x86/include/asm/kvm_host.h         |   1 +
 arch/x86/include/uapi/asm/kvm.h         |   4 +
 arch/x86/kvm/x86.c                      | 109 ++++++++++++++++++++++++
 4 files changed, 171 insertions(+)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 2acec3b9ef65..3b399d727c11 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -161,3 +161,60 @@ Specifies the base address of the stolen time structure for this VCPU. The
 base address must be 64 byte aligned and exist within a valid guest memory
 region. See Documentation/virt/kvm/arm/pvtime.rst for more information
 including the layout of the stolen time structure.
+
+4. GROUP: KVM_VCPU_TSC_CTRL
+===========================
+
+:Architectures: x86
+
+4.1 ATTRIBUTE: KVM_VCPU_TSC_OFFSET
+
+:Parameters: 64-bit unsigned TSC offset
+
+Returns:
+
+	 ======= ======================================
+	 -EFAULT Error reading/writing the provided
+		 parameter address.
+	 -ENXIO  Attribute not supported
+	 ======= ======================================
+
+Specifies the guest's TSC offset relative to the host's TSC. The guest's
+TSC is then derived by the following equation:
+
+  guest_tsc = host_tsc + KVM_VCPU_TSC_OFFSET
+
+This attribute is useful for the precise migration of a guest's TSC. The
+following describes a possible algorithm to use for the migration of a
+guest's TSC:
+
+From the source VMM process:
+
+1. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (t_0),
+   kvmclock nanoseconds (k_0), and realtime nanoseconds (r_0).
+
+2. Read the KVM_VCPU_TSC_OFFSET attribute for every vCPU to record the
+   guest TSC offset (off_n).
+
+3. Invoke the KVM_GET_TSC_KHZ ioctl to record the frequency of the
+   guest's TSC (freq).
+
+From the destination VMM process:
+
+4. Invoke the KVM_SET_CLOCK ioctl, providing the kvmclock nanoseconds
+   (k_0) and realtime nanoseconds (r_0) in their respective fields.
+   Ensure that the KVM_CLOCK_REALTIME flag is set in the provided
+   structure. KVM will advance the VM's kvmclock to account for elapsed
+   time since recording the clock values.
+
+5. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (t_1) and
+   kvmclock nanoseconds (k_1).
+
+6. Adjust the guest TSC offsets for every vCPU to account for (1) time
+   elapsed since recording state and (2) difference in TSCs between the
+   source and destination machine:
+
+   new_off_n = t_0 + off_n + (k_1 - k_0) * freq - t_1
+
+7. Write the KVM_VCPU_TSC_OFFSET attribute for every vCPU with the
+   respective value derived in the previous step.
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index d6376ca8efce..e9bfc00692fb 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1064,6 +1064,7 @@ struct kvm_arch {
 	u64 last_tsc_nsec;
 	u64 last_tsc_write;
 	u32 last_tsc_khz;
+	u64 last_tsc_offset;
 	u64 cur_tsc_nsec;
 	u64 cur_tsc_write;
 	u64 cur_tsc_offset;
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index a6c327f8ad9e..0b22e1e84e78 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -503,4 +503,8 @@ struct kvm_pmu_event_filter {
 #define KVM_PMU_EVENT_ALLOW 0
 #define KVM_PMU_EVENT_DENY 1
 
+/* for KVM_{GET,SET,HAS}_DEVICE_ATTR */
+#define KVM_VCPU_TSC_CTRL 0 /* control group for the timestamp counter (TSC) */
+#define   KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */
+
 #endif /* _ASM_X86_KVM_H */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 91aea751d621..3fdad71e5a36 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2466,6 +2466,7 @@ static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc,
 	kvm->arch.last_tsc_nsec = ns;
 	kvm->arch.last_tsc_write = tsc;
 	kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz;
+	kvm->arch.last_tsc_offset = offset;
 
 	vcpu->arch.last_guest_tsc = tsc;
 
@@ -4924,6 +4925,109 @@ static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+static int kvm_arch_tsc_has_attr(struct kvm_vcpu *vcpu,
+				 struct kvm_device_attr *attr)
+{
+	int r;
+
+	switch (attr->attr) {
+	case KVM_VCPU_TSC_OFFSET:
+		r = 0;
+		break;
+	default:
+		r = -ENXIO;
+	}
+
+	return r;
+}
+
+static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu,
+				 struct kvm_device_attr *attr)
+{
+	u64 __user *uaddr = (u64 __user *)attr->addr;
+	int r;
+
+	switch (attr->attr) {
+	case KVM_VCPU_TSC_OFFSET:
+		r = -EFAULT;
+		if (put_user(vcpu->arch.l1_tsc_offset, uaddr))
+			break;
+		r = 0;
+		break;
+	default:
+		r = -ENXIO;
+	}
+
+	return r;
+}
+
+static int kvm_arch_tsc_set_attr(struct kvm_vcpu *vcpu,
+				 struct kvm_device_attr *attr)
+{
+	u64 __user *uaddr = (u64 __user *)attr->addr;
+	struct kvm *kvm = vcpu->kvm;
+	int r;
+
+	switch (attr->attr) {
+	case KVM_VCPU_TSC_OFFSET: {
+		u64 offset, tsc, ns;
+		unsigned long flags;
+		bool matched;
+
+		r = -EFAULT;
+		if (get_user(offset, uaddr))
+			break;
+
+		raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
+
+		matched = (vcpu->arch.virtual_tsc_khz &&
+			   kvm->arch.last_tsc_khz == vcpu->arch.virtual_tsc_khz &&
+			   kvm->arch.last_tsc_offset == offset);
+
+		tsc = kvm_scale_tsc(vcpu, rdtsc(), vcpu->arch.l1_tsc_scaling_ratio) + offset;
+		ns = get_kvmclock_base_ns();
+
+		__kvm_synchronize_tsc(vcpu, offset, tsc, ns, matched);
+		raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
+
+		r = 0;
+		break;
+	}
+	default:
+		r = -ENXIO;
+	}
+
+	return r;
+}
+
+static int kvm_vcpu_ioctl_device_attr(struct kvm_vcpu *vcpu,
+				      unsigned int ioctl,
+				      void __user *argp)
+{
+	struct kvm_device_attr attr;
+	int r;
+
+	if (copy_from_user(&attr, argp, sizeof(attr)))
+		return -EFAULT;
+
+	if (attr.group != KVM_VCPU_TSC_CTRL)
+		return -ENXIO;
+
+	switch (ioctl) {
+	case KVM_HAS_DEVICE_ATTR:
+		r = kvm_arch_tsc_has_attr(vcpu, &attr);
+		break;
+	case KVM_GET_DEVICE_ATTR:
+		r = kvm_arch_tsc_get_attr(vcpu, &attr);
+		break;
+	case KVM_SET_DEVICE_ATTR:
+		r = kvm_arch_tsc_set_attr(vcpu, &attr);
+		break;
+	}
+
+	return r;
+}
+
 static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 				     struct kvm_enable_cap *cap)
 {
@@ -5378,6 +5482,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 		r = __set_sregs2(vcpu, u.sregs2);
 		break;
 	}
+	case KVM_HAS_DEVICE_ATTR:
+	case KVM_GET_DEVICE_ATTR:
+	case KVM_SET_DEVICE_ATTR:
+		r = kvm_vcpu_ioctl_device_attr(vcpu, ioctl, argp);
+		break;
 	default:
 		r = -EINVAL;
 	}
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:04 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:04 +0000
Subject: [PATCH v6 06/21] tools: arch: x86: pull in pvclock headers
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-7-oupton@google.com>

Copy over approximately clean versions of the pvclock headers into
tools. Reconcile headers/symbols missing in tools that are unneeded.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/arch/x86/include/asm/pvclock-abi.h |  48 +++++++++++
 tools/arch/x86/include/asm/pvclock.h     | 103 +++++++++++++++++++++++
 2 files changed, 151 insertions(+)
 create mode 100644 tools/arch/x86/include/asm/pvclock-abi.h
 create mode 100644 tools/arch/x86/include/asm/pvclock.h

diff --git a/tools/arch/x86/include/asm/pvclock-abi.h b/tools/arch/x86/include/asm/pvclock-abi.h
new file mode 100644
index 000000000000..1436226efe3e
--- /dev/null
+++ b/tools/arch/x86/include/asm/pvclock-abi.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_PVCLOCK_ABI_H
+#define _ASM_X86_PVCLOCK_ABI_H
+#ifndef __ASSEMBLY__
+
+/*
+ * These structs MUST NOT be changed.
+ * They are the ABI between hypervisor and guest OS.
+ * Both Xen and KVM are using this.
+ *
+ * pvclock_vcpu_time_info holds the system time and the tsc timestamp
+ * of the last update. So the guest can use the tsc delta to get a
+ * more precise system time.  There is one per virtual cpu.
+ *
+ * pvclock_wall_clock references the point in time when the system
+ * time was zero (usually boot time), thus the guest calculates the
+ * current wall clock by adding the system time.
+ *
+ * Protocol for the "version" fields is: hypervisor raises it (making
+ * it uneven) before it starts updating the fields and raises it again
+ * (making it even) when it is done.  Thus the guest can make sure the
+ * time values it got are consistent by checking the version before
+ * and after reading them.
+ */
+
+struct pvclock_vcpu_time_info {
+	u32   version;
+	u32   pad0;
+	u64   tsc_timestamp;
+	u64   system_time;
+	u32   tsc_to_system_mul;
+	s8    tsc_shift;
+	u8    flags;
+	u8    pad[2];
+} __attribute__((__packed__)); /* 32 bytes */
+
+struct pvclock_wall_clock {
+	u32   version;
+	u32   sec;
+	u32   nsec;
+} __attribute__((__packed__));
+
+#define PVCLOCK_TSC_STABLE_BIT	(1 << 0)
+#define PVCLOCK_GUEST_STOPPED	(1 << 1)
+/* PVCLOCK_COUNTS_FROM_ZERO broke ABI and can't be used anymore. */
+#define PVCLOCK_COUNTS_FROM_ZERO (1 << 2)
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_PVCLOCK_ABI_H */
diff --git a/tools/arch/x86/include/asm/pvclock.h b/tools/arch/x86/include/asm/pvclock.h
new file mode 100644
index 000000000000..2628f9a6330b
--- /dev/null
+++ b/tools/arch/x86/include/asm/pvclock.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_PVCLOCK_H
+#define _ASM_X86_PVCLOCK_H
+
+#include <asm/barrier.h>
+#include <asm/pvclock-abi.h>
+
+/* some helper functions for xen and kvm pv clock sources */
+u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
+u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src);
+void pvclock_set_flags(u8 flags);
+unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
+void pvclock_resume(void);
+
+void pvclock_touch_watchdogs(void);
+
+static __always_inline
+unsigned pvclock_read_begin(const struct pvclock_vcpu_time_info *src)
+{
+	unsigned version = src->version & ~1;
+	/* Make sure that the version is read before the data. */
+	rmb();
+	return version;
+}
+
+static __always_inline
+bool pvclock_read_retry(const struct pvclock_vcpu_time_info *src,
+			unsigned version)
+{
+	/* Make sure that the version is re-read after the data. */
+	rmb();
+	return version != src->version;
+}
+
+/*
+ * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
+ * yielding a 64-bit result.
+ */
+static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
+{
+	u64 product;
+#ifdef __i386__
+	u32 tmp1, tmp2;
+#else
+	unsigned long tmp;
+#endif
+
+	if (shift < 0)
+		delta >>= -shift;
+	else
+		delta <<= shift;
+
+#ifdef __i386__
+	__asm__ (
+		"mul  %5       ; "
+		"mov  %4,%%eax ; "
+		"mov  %%edx,%4 ; "
+		"mul  %5       ; "
+		"xor  %5,%5    ; "
+		"add  %4,%%eax ; "
+		"adc  %5,%%edx ; "
+		: "=A" (product), "=r" (tmp1), "=r" (tmp2)
+		: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
+#elif defined(__x86_64__)
+	__asm__ (
+		"mulq %[mul_frac] ; shrd $32, %[hi], %[lo]"
+		: [lo]"=a"(product),
+		  [hi]"=d"(tmp)
+		: "0"(delta),
+		  [mul_frac]"rm"((u64)mul_frac));
+#else
+#error implement me!
+#endif
+
+	return product;
+}
+
+static __always_inline
+u64 __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, u64 tsc)
+{
+	u64 delta = tsc - src->tsc_timestamp;
+	u64 offset = pvclock_scale_delta(delta, src->tsc_to_system_mul,
+					     src->tsc_shift);
+	return src->system_time + offset;
+}
+
+struct pvclock_vsyscall_time_info {
+	struct pvclock_vcpu_time_info pvti;
+} __attribute__((__aligned__(64)));
+
+#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info)
+
+#ifdef CONFIG_PARAVIRT_CLOCK
+void pvclock_set_pvti_cpu0_va(struct pvclock_vsyscall_time_info *pvti);
+struct pvclock_vsyscall_time_info *pvclock_get_pvti_cpu0_va(void);
+#else
+static inline struct pvclock_vsyscall_time_info *pvclock_get_pvti_cpu0_va(void)
+{
+	return NULL;
+}
+#endif
+
+#endif /* _ASM_X86_PVCLOCK_H */
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:05 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:05 +0000
Subject: [PATCH v6 07/21] selftests: KVM: Add test for KVM_{GET,SET}_CLOCK
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-8-oupton@google.com>

Add a selftest for the new KVM clock UAPI that was introduced. Ensure
that the KVM clock is consistent between userspace and the guest, and
that the difference in realtime will only ever cause the KVM clock to
advance forward.

Cc: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../testing/selftests/kvm/include/kvm_util.h  |   2 +
 .../selftests/kvm/x86_64/kvm_clock_test.c     | 204 ++++++++++++++++++
 4 files changed, 208 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_clock_test.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 36896d251977..958a809c8de4 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -11,6 +11,7 @@
 /x86_64/emulator_error_test
 /x86_64/get_cpuid_test
 /x86_64/get_msr_index_features
+/x86_64/kvm_clock_test
 /x86_64/kvm_pv_test
 /x86_64/hyperv_clock
 /x86_64/hyperv_cpuid
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index c103873531e0..0f94b18b33ce 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -46,6 +46,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/get_cpuid_test
 TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
 TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
 TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
+TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
 TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
 TEST_GEN_PROGS_x86_64 += x86_64/mmio_warning_test
 TEST_GEN_PROGS_x86_64 += x86_64/mmu_role_test
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 010b59b13917..a8ac5d52e17b 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -19,6 +19,8 @@
 #define KVM_DEV_PATH "/dev/kvm"
 #define KVM_MAX_VCPUS 512
 
+#define NSEC_PER_SEC 1000000000L
+
 /*
  * Callers of kvm_util only have an incomplete/opaque description of the
  * structure kvm_util is using to maintain the state of a VM.
diff --git a/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c b/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
new file mode 100644
index 000000000000..e0dcc27ae9f1
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021, Google LLC.
+ *
+ * Tests for adjusting the KVM clock from userspace
+ */
+#include <asm/kvm_para.h>
+#include <asm/pvclock.h>
+#include <asm/pvclock-abi.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+
+#define VCPU_ID 0
+
+struct test_case {
+	uint64_t kvmclock_base;
+	int64_t realtime_offset;
+};
+
+static struct test_case test_cases[] = {
+	{ .kvmclock_base = 0 },
+	{ .kvmclock_base = 180 * NSEC_PER_SEC },
+	{ .kvmclock_base = 0, .realtime_offset = -180 * NSEC_PER_SEC },
+	{ .kvmclock_base = 0, .realtime_offset = 180 * NSEC_PER_SEC },
+};
+
+#define GUEST_SYNC_CLOCK(__stage, __val)			\
+		GUEST_SYNC_ARGS(__stage, __val, 0, 0, 0)
+
+static void guest_main(vm_paddr_t pvti_pa, struct pvclock_vcpu_time_info *pvti)
+{
+	int i;
+
+	wrmsr(MSR_KVM_SYSTEM_TIME_NEW, pvti_pa | KVM_MSR_ENABLED);
+	for (i = 0; i < ARRAY_SIZE(test_cases); i++)
+		GUEST_SYNC_CLOCK(i, __pvclock_read_cycles(pvti, rdtsc()));
+}
+
+#define EXPECTED_FLAGS (KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC)
+
+static inline void assert_flags(struct kvm_clock_data *data)
+{
+	TEST_ASSERT((data->flags & EXPECTED_FLAGS) == EXPECTED_FLAGS,
+		    "unexpected clock data flags: %x (want set: %x)",
+		    data->flags, EXPECTED_FLAGS);
+}
+
+static void handle_sync(struct ucall *uc, struct kvm_clock_data *start,
+			struct kvm_clock_data *end)
+{
+	uint64_t obs, exp_lo, exp_hi;
+
+	obs = uc->args[2];
+	exp_lo = start->clock;
+	exp_hi = end->clock;
+
+	assert_flags(start);
+	assert_flags(end);
+
+	TEST_ASSERT(exp_lo <= obs && obs <= exp_hi,
+		    "unexpected kvm-clock value: %"PRIu64" expected range: [%"PRIu64", %"PRIu64"]",
+		    obs, exp_lo, exp_hi);
+
+	pr_info("kvm-clock value: %"PRIu64" expected range [%"PRIu64", %"PRIu64"]\n",
+		obs, exp_lo, exp_hi);
+}
+
+static void handle_abort(struct ucall *uc)
+{
+	TEST_FAIL("%s at %s:%ld", (const char *)uc->args[0],
+		  __FILE__, uc->args[1]);
+}
+
+static void setup_clock(struct kvm_vm *vm, struct test_case *test_case)
+{
+	struct kvm_clock_data data;
+
+	memset(&data, 0, sizeof(data));
+
+	data.clock = test_case->kvmclock_base;
+	if (test_case->realtime_offset) {
+		struct timespec ts;
+		int r;
+
+		data.flags |= KVM_CLOCK_REALTIME;
+		do {
+			r = clock_gettime(CLOCK_REALTIME, &ts);
+			if (!r)
+				break;
+		} while (errno == EINTR);
+
+		TEST_ASSERT(!r, "clock_gettime() failed: %d\n", r);
+
+		data.realtime = ts.tv_sec * NSEC_PER_SEC;
+		data.realtime += ts.tv_nsec;
+		data.realtime += test_case->realtime_offset;
+	}
+
+	vm_ioctl(vm, KVM_SET_CLOCK, &data);
+}
+
+static void enter_guest(struct kvm_vm *vm)
+{
+	struct kvm_clock_data start, end;
+	struct kvm_run *run;
+	struct ucall uc;
+	int i, r;
+
+	run = vcpu_state(vm, VCPU_ID);
+
+	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
+		setup_clock(vm, &test_cases[i]);
+
+		vm_ioctl(vm, KVM_GET_CLOCK, &start);
+
+		r = _vcpu_run(vm, VCPU_ID);
+		vm_ioctl(vm, KVM_GET_CLOCK, &end);
+
+		TEST_ASSERT(!r, "vcpu_run failed: %d\n", r);
+		TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
+			    "unexpected exit reason: %u (%s)",
+			    run->exit_reason, exit_reason_str(run->exit_reason));
+
+		switch (get_ucall(vm, VCPU_ID, &uc)) {
+		case UCALL_SYNC:
+			handle_sync(&uc, &start, &end);
+			break;
+		case UCALL_ABORT:
+			handle_abort(&uc);
+			return;
+		default:
+			TEST_ASSERT(0, "unhandled ucall: %ld\n",
+				    get_ucall(vm, VCPU_ID, &uc));
+		}
+	}
+}
+
+#define CLOCKSOURCE_PATH "/sys/devices/system/clocksource/clocksource0/current_clocksource"
+
+static void check_clocksource(void)
+{
+	char *clk_name;
+	struct stat st;
+	FILE *fp;
+
+	fp = fopen(CLOCKSOURCE_PATH, "r");
+	if (!fp) {
+		pr_info("failed to open clocksource file: %d; assuming TSC.\n",
+			errno);
+		return;
+	}
+
+	if (fstat(fileno(fp), &st)) {
+		pr_info("failed to stat clocksource file: %d; assuming TSC.\n",
+			errno);
+		goto out;
+	}
+
+	clk_name = malloc(st.st_size);
+	TEST_ASSERT(clk_name, "failed to allocate buffer to read file\n");
+
+	if (!fgets(clk_name, st.st_size, fp)) {
+		pr_info("failed to read clocksource file: %d; assuming TSC.\n",
+			ferror(fp));
+		goto out;
+	}
+
+	TEST_ASSERT(!strncmp(clk_name, "tsc\n", st.st_size),
+		    "clocksource not supported: %s", clk_name);
+out:
+	fclose(fp);
+}
+
+int main(void)
+{
+	vm_vaddr_t pvti_gva;
+	vm_paddr_t pvti_gpa;
+	struct kvm_vm *vm;
+	int flags;
+
+	flags = kvm_check_cap(KVM_CAP_ADJUST_CLOCK);
+	if (!(flags & KVM_CLOCK_REALTIME)) {
+		print_skip("KVM_CLOCK_REALTIME not supported; flags: %x",
+			   flags);
+		exit(KSFT_SKIP);
+	}
+
+	check_clocksource();
+
+	vm = vm_create_default(VCPU_ID, 0, guest_main);
+
+	pvti_gva = vm_vaddr_alloc(vm, getpagesize(), 0x10000);
+	pvti_gpa = addr_gva2gpa(vm, pvti_gva);
+	vcpu_args_set(vm, VCPU_ID, 2, pvti_gpa, pvti_gva);
+
+	enter_guest(vm);
+	kvm_vm_free(vm);
+}
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:06 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:06 +0000
Subject: [PATCH v6 08/21] selftests: KVM: Fix kvm device helper ioctl
 assertions
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-9-oupton@google.com>

The KVM_CREATE_DEVICE and KVM_{GET,SET}_DEVICE_ATTR ioctls are defined
to return a value of zero on success. As such, tighten the assertions in
the helper functions to only pass if the return code is zero.

Suggested-by: Andrew Jones <drjones at redhat.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/testing/selftests/kvm/lib/kvm_util.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 10a8ed691c66..0ffc2d39c80d 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1984,7 +1984,7 @@ int kvm_device_check_attr(int dev_fd, uint32_t group, uint64_t attr)
 {
 	int ret = _kvm_device_check_attr(dev_fd, group, attr);
 
-	TEST_ASSERT(ret >= 0, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno);
+	TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno);
 	return ret;
 }
 
@@ -2008,7 +2008,7 @@ int kvm_create_device(struct kvm_vm *vm, uint64_t type, bool test)
 	ret = _kvm_create_device(vm, type, test, &fd);
 
 	if (!test) {
-		TEST_ASSERT(ret >= 0,
+		TEST_ASSERT(!ret,
 			    "KVM_CREATE_DEVICE IOCTL failed, rc: %i errno: %i", ret, errno);
 		return fd;
 	}
@@ -2036,7 +2036,7 @@ int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr,
 {
 	int ret = _kvm_device_access(dev_fd, group, attr, val, write);
 
-	TEST_ASSERT(ret >= 0, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno);
+	TEST_ASSERT(!ret, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno);
 	return ret;
 }
 
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:07 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:07 +0000
Subject: [PATCH v6 09/21] selftests: KVM: Add helpers for vCPU device
 attributes
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-10-oupton@google.com>

vCPU file descriptors are abstracted away from test code in KVM
selftests, meaning that tests cannot directly access a vCPU's device
attributes. Add helpers that tests can use to get at vCPU device
attributes.

Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 .../testing/selftests/kvm/include/kvm_util.h  |  9 +++++
 tools/testing/selftests/kvm/lib/kvm_util.c    | 38 +++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index a8ac5d52e17b..1b3ef5757819 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -240,6 +240,15 @@ int _kvm_device_access(int dev_fd, uint32_t group, uint64_t attr,
 int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr,
 		      void *val, bool write);
 
+int _vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			  uint64_t attr);
+int vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			 uint64_t attr);
+int _vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			  uint64_t attr, void *val, bool write);
+int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			 uint64_t attr, void *val, bool write);
+
 const char *exit_reason_str(unsigned int exit_reason);
 
 void virt_pgd_alloc(struct kvm_vm *vm);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 0ffc2d39c80d..0fe66ca6139a 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2040,6 +2040,44 @@ int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr,
 	return ret;
 }
 
+int _vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			  uint64_t attr)
+{
+	struct vcpu *vcpu = vcpu_find(vm, vcpuid);
+
+	TEST_ASSERT(vcpu, "nonexistent vcpu id: %d", vcpuid);
+
+	return _kvm_device_check_attr(vcpu->fd, group, attr);
+}
+
+int vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+				 uint64_t attr)
+{
+	int ret = _vcpu_has_device_attr(vm, vcpuid, group, attr);
+
+	TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno);
+	return ret;
+}
+
+int _vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			     uint64_t attr, void *val, bool write)
+{
+	struct vcpu *vcpu = vcpu_find(vm, vcpuid);
+
+	TEST_ASSERT(vcpu, "nonexistent vcpu id: %d", vcpuid);
+
+	return _kvm_device_access(vcpu->fd, group, attr, val, write);
+}
+
+int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			    uint64_t attr, void *val, bool write)
+{
+	int ret = _vcpu_access_device_attr(vm, vcpuid, group, attr, val, write);
+
+	TEST_ASSERT(!ret, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno);
+	return ret;
+}
+
 /*
  * VM Dump
  *
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:08 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:08 +0000
Subject: [PATCH v6 10/21] selftests: KVM: Introduce system counter offset test
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-11-oupton@google.com>

Introduce a KVM selftest to verify that userspace manipulation of the
TSC (via the new vCPU attribute) results in the correct behavior within
the guest.

Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/system_counter_offset_test.c          | 132 ++++++++++++++++++
 3 files changed, 134 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/system_counter_offset_test.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 958a809c8de4..3d2585f0bffc 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -52,3 +52,4 @@
 /set_memory_region_test
 /steal_time
 /kvm_binary_stats_test
+/system_counter_offset_test
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 0f94b18b33ce..9f7060c02668 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -85,6 +85,7 @@ TEST_GEN_PROGS_x86_64 += memslot_perf_test
 TEST_GEN_PROGS_x86_64 += set_memory_region_test
 TEST_GEN_PROGS_x86_64 += steal_time
 TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
+TEST_GEN_PROGS_x86_64 += system_counter_offset_test
 
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c
new file mode 100644
index 000000000000..b337bbbfa41f
--- /dev/null
+++ b/tools/testing/selftests/kvm/system_counter_offset_test.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021, Google LLC.
+ *
+ * Tests for adjusting the system counter from userspace
+ */
+#include <asm/kvm_para.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+
+#define VCPU_ID 0
+
+#ifdef __x86_64__
+
+struct test_case {
+	uint64_t tsc_offset;
+};
+
+static struct test_case test_cases[] = {
+	{ 0 },
+	{ 180 * NSEC_PER_SEC },
+	{ -180 * NSEC_PER_SEC },
+};
+
+static void check_preconditions(struct kvm_vm *vm)
+{
+	if (!_vcpu_has_device_attr(vm, VCPU_ID, KVM_VCPU_TSC_CTRL, KVM_VCPU_TSC_OFFSET))
+		return;
+
+	print_skip("KVM_VCPU_TSC_OFFSET not supported; skipping test");
+	exit(KSFT_SKIP);
+}
+
+static void setup_system_counter(struct kvm_vm *vm, struct test_case *test)
+{
+	vcpu_access_device_attr(vm, VCPU_ID, KVM_VCPU_TSC_CTRL,
+				KVM_VCPU_TSC_OFFSET, &test->tsc_offset, true);
+}
+
+static uint64_t guest_read_system_counter(struct test_case *test)
+{
+	return rdtsc();
+}
+
+static uint64_t host_read_guest_system_counter(struct test_case *test)
+{
+	return rdtsc() + test->tsc_offset;
+}
+
+#else /* __x86_64__ */
+
+#error test not implemented for this architecture!
+
+#endif
+
+#define GUEST_SYNC_CLOCK(__stage, __val)			\
+		GUEST_SYNC_ARGS(__stage, __val, 0, 0, 0)
+
+static void guest_main(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
+		struct test_case *test = &test_cases[i];
+
+		GUEST_SYNC_CLOCK(i, guest_read_system_counter(test));
+	}
+}
+
+static void handle_sync(struct ucall *uc, uint64_t start, uint64_t end)
+{
+	uint64_t obs = uc->args[2];
+
+	TEST_ASSERT(start <= obs && obs <= end,
+		    "unexpected system counter value: %"PRIu64" expected range: [%"PRIu64", %"PRIu64"]",
+		    obs, start, end);
+
+	pr_info("system counter value: %"PRIu64" expected range [%"PRIu64", %"PRIu64"]\n",
+		obs, start, end);
+}
+
+static void handle_abort(struct ucall *uc)
+{
+	TEST_FAIL("%s at %s:%ld", (const char *)uc->args[0],
+		  __FILE__, uc->args[1]);
+}
+
+static void enter_guest(struct kvm_vm *vm)
+{
+	uint64_t start, end;
+	struct ucall uc;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
+		struct test_case *test = &test_cases[i];
+
+		setup_system_counter(vm, test);
+		start = host_read_guest_system_counter(test);
+		vcpu_run(vm, VCPU_ID);
+		end = host_read_guest_system_counter(test);
+
+		switch (get_ucall(vm, VCPU_ID, &uc)) {
+		case UCALL_SYNC:
+			handle_sync(&uc, start, end);
+			break;
+		case UCALL_ABORT:
+			handle_abort(&uc);
+			return;
+		default:
+			TEST_ASSERT(0, "unhandled ucall %ld\n",
+				    get_ucall(vm, VCPU_ID, &uc));
+		}
+	}
+}
+
+int main(void)
+{
+	struct kvm_vm *vm;
+
+	vm = vm_create_default(VCPU_ID, 0, guest_main);
+	check_preconditions(vm);
+	ucall_init(vm, NULL);
+
+	enter_guest(vm);
+	kvm_vm_free(vm);
+}
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:09 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:09 +0000
Subject: [PATCH v6 11/21] KVM: arm64: Refactor update_vtimer_cntvoff()
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-12-oupton@google.com>

Make the implementation of update_vtimer_cntvoff() generic w.r.t. guest
timer context and spin off into a new helper method for later use.
Require callers of this new helper method to grab the kvm lock
beforehand.

No functional change intended.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/arm64/kvm/arch_timer.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 3df67c127489..c0101db75ad4 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -747,22 +747,32 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
-/* Make the updates of cntvoff for all vtimer contexts atomic */
-static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
+/* Make offset updates for all timer contexts atomic */
+static void update_timer_offset(struct kvm_vcpu *vcpu,
+				enum kvm_arch_timers timer, u64 offset)
 {
 	int i;
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_vcpu *tmp;
 
-	mutex_lock(&kvm->lock);
+	lockdep_assert_held(&kvm->lock);
+
 	kvm_for_each_vcpu(i, tmp, kvm)
-		timer_set_offset(vcpu_vtimer(tmp), cntvoff);
+		timer_set_offset(vcpu_get_timer(tmp, timer), offset);
 
 	/*
 	 * When called from the vcpu create path, the CPU being created is not
 	 * included in the loop above, so we just set it here as well.
 	 */
-	timer_set_offset(vcpu_vtimer(vcpu), cntvoff);
+	timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
+}
+
+static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
+{
+	struct kvm *kvm = vcpu->kvm;
+
+	mutex_lock(&kvm->lock);
+	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff);
 	mutex_unlock(&kvm->lock);
 }
 
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:10 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:10 +0000
Subject: [PATCH v6 12/21] KVM: arm64: Separate guest/host counter offset values
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-13-oupton@google.com>

In some instances, a VMM may want to update the guest's counter-timer
offset in a transparent manner, meaning that changes to the hardware
value do not affect the synthetic register presented to the guest or the
VMM through said guest's architectural state. Lay the groundwork to
separate guest offset register writes from the hardware values utilized
by KVM.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/arm64/kvm/arch_timer.c  | 48 ++++++++++++++++++++++++++++++++----
 include/kvm/arm_arch_timer.h |  3 +++
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index c0101db75ad4..4c2b763a8849 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -87,6 +87,18 @@ static u64 timer_get_offset(struct arch_timer_context *ctxt)
 	struct kvm_vcpu *vcpu = ctxt->vcpu;
 
 	switch(arch_timer_ctx_index(ctxt)) {
+	case TIMER_VTIMER:
+		return ctxt->host_offset;
+	default:
+		return 0;
+	}
+}
+
+static u64 timer_get_guest_offset(struct arch_timer_context *ctxt)
+{
+	struct kvm_vcpu *vcpu = ctxt->vcpu;
+
+	switch (arch_timer_ctx_index(ctxt)) {
 	case TIMER_VTIMER:
 		return __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
 	default:
@@ -132,13 +144,31 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
 
 	switch(arch_timer_ctx_index(ctxt)) {
 	case TIMER_VTIMER:
-		__vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset;
+		ctxt->host_offset = offset;
 		break;
 	default:
 		WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
 	}
 }
 
+static void timer_set_guest_offset(struct arch_timer_context *ctxt, u64 offset)
+{
+	struct kvm_vcpu *vcpu = ctxt->vcpu;
+
+	switch (arch_timer_ctx_index(ctxt)) {
+	case TIMER_VTIMER: {
+		u64 host_offset = timer_get_offset(ctxt);
+
+		host_offset += offset - __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
+		__vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset;
+		timer_set_offset(ctxt, host_offset);
+		break;
+	}
+	default:
+		WARN_ONCE(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
+	}
+}
+
 u64 kvm_phys_timer_read(void)
 {
 	return timecounter->cc->read(timecounter->cc);
@@ -749,7 +779,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
 
 /* Make offset updates for all timer contexts atomic */
 static void update_timer_offset(struct kvm_vcpu *vcpu,
-				enum kvm_arch_timers timer, u64 offset)
+				enum kvm_arch_timers timer, u64 offset,
+				bool guest_visible)
 {
 	int i;
 	struct kvm *kvm = vcpu->kvm;
@@ -758,13 +789,20 @@ static void update_timer_offset(struct kvm_vcpu *vcpu,
 	lockdep_assert_held(&kvm->lock);
 
 	kvm_for_each_vcpu(i, tmp, kvm)
-		timer_set_offset(vcpu_get_timer(tmp, timer), offset);
+		if (guest_visible)
+			timer_set_guest_offset(vcpu_get_timer(tmp, timer),
+					       offset);
+		else
+			timer_set_offset(vcpu_get_timer(tmp, timer), offset);
 
 	/*
 	 * When called from the vcpu create path, the CPU being created is not
 	 * included in the loop above, so we just set it here as well.
 	 */
-	timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
+	if (guest_visible)
+		timer_set_guest_offset(vcpu_get_timer(vcpu, timer), offset);
+	else
+		timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
 }
 
 static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
@@ -772,7 +810,7 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
 	struct kvm *kvm = vcpu->kvm;
 
 	mutex_lock(&kvm->lock);
-	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff);
+	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, true);
 	mutex_unlock(&kvm->lock);
 }
 
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 51c19381108c..9d65d4a29f81 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -42,6 +42,9 @@ struct arch_timer_context {
 	/* Duplicated state from arch_timer.c for convenience */
 	u32				host_timer_irq;
 	u32				host_timer_irq_flags;
+
+	/* offset relative to the host's physical counter-timer */
+	u64				host_offset;
 };
 
 struct timer_map {
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:11 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:11 +0000
Subject: [PATCH v6 13/21] KVM: arm64: Allow userspace to configure a vCPU's
 virtual offset
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-14-oupton@google.com>

Allow userspace to access the guest's virtual counter-timer offset
through the ONE_REG interface. The value read or written is defined to
be an offset from the guest's physical counter-timer. Add some
documentation to clarify how a VMM should use this and the existing
CNTVCT_EL0.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 Documentation/virt/kvm/api.rst    | 10 ++++++++++
 arch/arm64/include/uapi/asm/kvm.h |  1 +
 arch/arm64/kvm/arch_timer.c       | 11 +++++++++++
 arch/arm64/kvm/guest.c            |  6 +++++-
 include/kvm/arm_arch_timer.h      |  1 +
 5 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 8d4a3471ad9e..28a65dc89985 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -2487,6 +2487,16 @@ arm64 system registers have the following id bit patterns::
      derived from the register encoding for CNTV_CVAL_EL0.  As this is
      API, it must remain this way.
 
+.. warning::
+
+     The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from
+     the guest's view of the physical counter-timer.
+
+     Userspace should use either KVM_REG_ARM_TIMER_OFFSET or
+     KVM_REG_ARM_TIMER_CVAL to pause and resume a guest's virtual
+     counter-timer. Mixed use of these registers could result in an
+     unpredictable guest counter value.
+
 arm64 firmware pseudo-registers have the following bit pattern::
 
   0x6030 0000 0014 <regno:16>
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..949a31bc10f0 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_TIMER_CTL		ARM64_SYS_REG(3, 3, 14, 3, 1)
 #define KVM_REG_ARM_TIMER_CVAL		ARM64_SYS_REG(3, 3, 14, 0, 2)
 #define KVM_REG_ARM_TIMER_CNT		ARM64_SYS_REG(3, 3, 14, 3, 2)
+#define KVM_REG_ARM_TIMER_OFFSET	ARM64_SYS_REG(3, 4, 14, 0, 3)
 
 /* KVM-as-firmware specific pseudo-registers */
 #define KVM_REG_ARM_FW			(0x0014 << KVM_REG_ARM_COPROC_SHIFT)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 4c2b763a8849..a8815b09da3e 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -868,6 +868,10 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
 		timer = vcpu_vtimer(vcpu);
 		kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value);
 		break;
+	case KVM_REG_ARM_TIMER_OFFSET:
+		timer = vcpu_vtimer(vcpu);
+		update_vtimer_cntvoff(vcpu, value);
+		break;
 	case KVM_REG_ARM_PTIMER_CTL:
 		timer = vcpu_ptimer(vcpu);
 		kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
@@ -912,6 +916,9 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
 	case KVM_REG_ARM_TIMER_CVAL:
 		return kvm_arm_timer_read(vcpu,
 					  vcpu_vtimer(vcpu), TIMER_REG_CVAL);
+	case KVM_REG_ARM_TIMER_OFFSET:
+		return kvm_arm_timer_read(vcpu,
+					  vcpu_vtimer(vcpu), TIMER_REG_OFFSET);
 	case KVM_REG_ARM_PTIMER_CTL:
 		return kvm_arm_timer_read(vcpu,
 					  vcpu_ptimer(vcpu), TIMER_REG_CTL);
@@ -949,6 +956,10 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 		val = kvm_phys_timer_read() - timer_get_offset(timer);
 		break;
 
+	case TIMER_REG_OFFSET:
+		val = timer_get_offset(timer);
+		break;
+
 	default:
 		BUG();
 	}
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 1dfb83578277..17fc06e2b422 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -591,7 +591,7 @@ static unsigned long num_core_regs(const struct kvm_vcpu *vcpu)
  * ARM64 versions of the TIMER registers, always available on arm64
  */
 
-#define NUM_TIMER_REGS 3
+#define NUM_TIMER_REGS 4
 
 static bool is_timer_reg(u64 index)
 {
@@ -599,6 +599,7 @@ static bool is_timer_reg(u64 index)
 	case KVM_REG_ARM_TIMER_CTL:
 	case KVM_REG_ARM_TIMER_CNT:
 	case KVM_REG_ARM_TIMER_CVAL:
+	case KVM_REG_ARM_TIMER_OFFSET:
 		return true;
 	}
 	return false;
@@ -614,6 +615,9 @@ static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 	uindices++;
 	if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices))
 		return -EFAULT;
+	uindices++;
+	if (put_user(KVM_REG_ARM_TIMER_OFFSET, uindices))
+		return -EFAULT;
 
 	return 0;
 }
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 9d65d4a29f81..615f9314f6a5 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -21,6 +21,7 @@ enum kvm_arch_timer_regs {
 	TIMER_REG_CVAL,
 	TIMER_REG_TVAL,
 	TIMER_REG_CTL,
+	TIMER_REG_OFFSET,
 };
 
 struct arch_timer_context {
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:12 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:12 +0000
Subject: [PATCH v6 14/21] selftests: KVM: Add helper to check for register
 presence
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-15-oupton@google.com>

The KVM_GET_REG_LIST vCPU ioctl returns a list of supported registers
for a given vCPU. Add a helper to check if a register exists in the list
of supported registers.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 .../testing/selftests/kvm/include/kvm_util.h  |  2 ++
 tools/testing/selftests/kvm/lib/kvm_util.c    | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 1b3ef5757819..077082dd2ca7 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -215,6 +215,8 @@ void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid,
 		  struct kvm_fpu *fpu);
 void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid,
 		  struct kvm_fpu *fpu);
+
+bool vcpu_has_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t reg_id);
 void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
 void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
 #ifdef __KVM_HAVE_VCPU_EVENTS
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 0fe66ca6139a..a5801d4ed37d 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1823,6 +1823,25 @@ void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu)
 		    ret, errno, strerror(errno));
 }
 
+bool vcpu_has_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t reg_id)
+{
+	struct kvm_reg_list *list;
+	bool ret = false;
+	uint64_t i;
+
+	list = vcpu_get_reg_list(vm, vcpuid);
+
+	for (i = 0; i < list->n; i++) {
+		if (list->reg[i] == reg_id) {
+			ret = true;
+			break;
+		}
+	}
+
+	free(list);
+	return ret;
+}
+
 void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg)
 {
 	int ret;
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:13 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:13 +0000
Subject: [PATCH v6 15/21] selftests: KVM: Add support for aarch64 to
 system_counter_offset_test
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-16-oupton@google.com>

KVM/arm64 now allows userspace to adjust the guest virtual counter-timer
via a vCPU register. Test that changes to the virtual counter-timer
offset result in the correct view being presented to the guest.

Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/testing/selftests/kvm/Makefile          |  1 +
 .../selftests/kvm/include/aarch64/processor.h | 12 ++++
 .../kvm/system_counter_offset_test.c          | 56 ++++++++++++++++++-
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 9f7060c02668..fab42e7c23ee 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -98,6 +98,7 @@ TEST_GEN_PROGS_aarch64 += kvm_page_table_test
 TEST_GEN_PROGS_aarch64 += set_memory_region_test
 TEST_GEN_PROGS_aarch64 += steal_time
 TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
+TEST_GEN_PROGS_aarch64 += system_counter_offset_test
 
 TEST_GEN_PROGS_s390x = s390x/memop
 TEST_GEN_PROGS_s390x += s390x/resets
diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index 27dc5c2e56b9..3168cdbae6ee 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -129,4 +129,16 @@ void vm_install_sync_handler(struct kvm_vm *vm,
 
 #define isb()	asm volatile("isb" : : : "memory")
 
+static inline uint64_t read_cntvct_ordered(void)
+{
+	uint64_t r;
+
+	__asm__ __volatile__("isb\n\t"
+			     "mrs %0, cntvct_el0\n\t"
+			     "isb\n\t"
+			     : "=r"(r));
+
+	return r;
+}
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c
index b337bbbfa41f..ac933db83d03 100644
--- a/tools/testing/selftests/kvm/system_counter_offset_test.c
+++ b/tools/testing/selftests/kvm/system_counter_offset_test.c
@@ -53,7 +53,61 @@ static uint64_t host_read_guest_system_counter(struct test_case *test)
 	return rdtsc() + test->tsc_offset;
 }
 
-#else /* __x86_64__ */
+#elif __aarch64__ /* __x86_64__ */
+
+enum arch_counter {
+	VIRTUAL,
+};
+
+struct test_case {
+	enum arch_counter counter;
+	uint64_t offset;
+};
+
+static struct test_case test_cases[] = {
+	{ .counter = VIRTUAL, .offset = 0 },
+	{ .counter = VIRTUAL, .offset = 180 * NSEC_PER_SEC },
+	{ .counter = VIRTUAL, .offset = -180 * NSEC_PER_SEC },
+};
+
+static void check_preconditions(struct kvm_vm *vm)
+{
+	if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET))
+		return;
+
+	print_skip("KVM_REG_ARM_TIMER_OFFSET not supported; skipping test");
+	exit(KSFT_SKIP);
+}
+
+static void setup_system_counter(struct kvm_vm *vm, struct test_case *test)
+{
+	struct kvm_one_reg reg = {
+		.id = KVM_REG_ARM_TIMER_OFFSET,
+		.addr = (__u64)&test->offset,
+	};
+
+	vcpu_set_reg(vm, VCPU_ID, &reg);
+}
+
+static uint64_t guest_read_system_counter(struct test_case *test)
+{
+	switch (test->counter) {
+	case VIRTUAL:
+		return read_cntvct_ordered();
+	default:
+		GUEST_ASSERT(0);
+	}
+
+	/* unreachable */
+	return 0;
+}
+
+static uint64_t host_read_guest_system_counter(struct test_case *test)
+{
+	return read_cntvct_ordered() - test->offset;
+}
+
+#else /* __aarch64__ */
 
 #error test not implemented for this architecture!
 
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:14 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:14 +0000
Subject: [PATCH v6 16/21] arm64: cpufeature: Enumerate support for Enhanced
 Counter Virtualization
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-17-oupton@google.com>

Introduce a new cpucap to indicate if the system supports full enhanced
counter virtualization (i.e. ID_AA64MMFR0_EL1.ECV==0x2).

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/arm64/include/asm/sysreg.h |  2 ++
 arch/arm64/kernel/cpufeature.c  | 10 ++++++++++
 arch/arm64/tools/cpucaps        |  1 +
 3 files changed, 13 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7b9c3acba684..4dfc44066dfb 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -847,6 +847,8 @@
 #define ID_AA64MMFR0_ASID_SHIFT		4
 #define ID_AA64MMFR0_PARANGE_SHIFT	0
 
+#define ID_AA64MMFR0_ECV_VIRT		0x1
+#define ID_AA64MMFR0_ECV_PHYS		0x2
 #define ID_AA64MMFR0_TGRAN4_NI		0xf
 #define ID_AA64MMFR0_TGRAN4_SUPPORTED	0x0
 #define ID_AA64MMFR0_TGRAN64_NI		0xf
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0ead8bfedf20..94c349e179d3 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2301,6 +2301,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
+	{
+		.desc = "Enhanced Counter Virtualization (Physical)",
+		.capability = ARM64_ECV,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.sys_reg = SYS_ID_AA64MMFR0_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR0_ECV_SHIFT,
+		.matches = has_cpuid_feature,
+		.min_field_value = ID_AA64MMFR0_ECV_PHYS,
+	},
 	{},
 };
 
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 49305c2e6dfd..d819ea614da5 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -3,6 +3,7 @@
 # Internal CPU capabilities constants, keep this list sorted
 
 BTI
+ECV
 # Unreliable: use system_supports_32bit_el0() instead.
 HAS_32BIT_EL0_DO_NOT_USE
 HAS_32BIT_EL1
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:15 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:15 +0000
Subject: [PATCH v6 17/21] KVM: arm64: Allow userspace to configure a guest's
 counter-timer offset
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-18-oupton@google.com>

Presently, KVM provides no facilities for correctly migrating a guest
that depends on the physical counter-timer. Whie most guests (barring
NV, of course) should not depend on the physical counter-timer, an
operator may wish to provide a consistent view of the physical
counter-timer across migrations.

Provide userspace with a new vCPU attribute to modify the guest
counter-timer offset. Unlike KVM_REG_ARM_TIMER_OFFSET, this attribute is
hidden from the guest's architectural state. The value offsets *both*
the virtual and physical counter-timer views for the guest. Only support
this attribute on ECV systems as ECV is required for hardware offsetting
of the physical counter-timer.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 Documentation/virt/kvm/devices/vcpu.rst |  28 ++++++
 arch/arm64/include/asm/kvm_asm.h        |   2 +
 arch/arm64/include/asm/sysreg.h         |   2 +
 arch/arm64/include/uapi/asm/kvm.h       |   1 +
 arch/arm64/kvm/arch_timer.c             | 122 +++++++++++++++++++++++-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |   6 ++
 arch/arm64/kvm/hyp/nvhe/timer-sr.c      |   5 +
 arch/arm64/kvm/hyp/vhe/timer-sr.c       |   5 +
 include/clocksource/arm_arch_timer.h    |   1 +
 9 files changed, 169 insertions(+), 3 deletions(-)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 3b399d727c11..3ba35b9d9d03 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -139,6 +139,34 @@ configured values on other VCPUs.  Userspace should configure the interrupt
 numbers on at least one VCPU after creating all VCPUs and before running any
 VCPUs.
 
+2.2. ATTRIBUTE: KVM_ARM_VCPU_TIMER_OFFSET
+-----------------------------------------
+
+:Parameters: in kvm_device_attr.addr the address for the timer offset is a
+             pointer to a __u64
+
+Returns:
+
+	 ======= ==================================
+	 -EFAULT Error reading/writing the provided
+		 parameter address
+	 -ENXIO  Timer offsetting not implemented
+	 ======= ==================================
+
+Specifies the guest's counter-timer offset from the host's virtual counter.
+The guest's physical counter value is then derived by the following
+equation:
+
+  guest_cntpct = host_cntvct - KVM_ARM_VCPU_TIMER_OFFSET
+
+The guest's virtual counter value is derived by the following equation:
+
+  guest_cntvct = host_cntvct - KVM_REG_ARM_TIMER_OFFSET
+			- KVM_ARM_VCPU_TIMER_OFFSET
+
+KVM does not allow the use of varying offset values for different vCPUs;
+the last written offset value will be broadcasted to all vCPUs in a VM.
+
 3. GROUP: KVM_ARM_VCPU_PVTIME_CTRL
 ==================================
 
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 9f0bf2109be7..ab1c8fdb0177 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -65,6 +65,7 @@
 #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize		19
 #define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp			20
 #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc			21
+#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntpoff		22
 
 #ifndef __ASSEMBLY__
 
@@ -200,6 +201,7 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
 extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
 
 extern void __kvm_timer_set_cntvoff(u64 cntvoff);
+extern void __kvm_timer_set_cntpoff(u64 cntpoff);
 
 extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 4dfc44066dfb..c34672aa65b9 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -586,6 +586,8 @@
 #define SYS_ICH_LR14_EL2		__SYS__LR8_EL2(6)
 #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
 
+#define SYS_CNTPOFF_EL2			sys_reg(3, 4, 14, 0, 6)
+
 /* VHE encodings for architectural EL0/1 system registers */
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
 #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 949a31bc10f0..15150f8224a1 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -366,6 +366,7 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_ARM_VCPU_TIMER_CTRL		1
 #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
+#define   KVM_ARM_VCPU_TIMER_OFFSET		2
 #define KVM_ARM_VCPU_PVTIME_CTRL	2
 #define   KVM_ARM_VCPU_PVTIME_IPA	0
 
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index a8815b09da3e..f15058612994 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -85,11 +85,15 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
 static u64 timer_get_offset(struct arch_timer_context *ctxt)
 {
 	struct kvm_vcpu *vcpu = ctxt->vcpu;
+	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
 
 	switch(arch_timer_ctx_index(ctxt)) {
 	case TIMER_VTIMER:
+	case TIMER_PTIMER:
 		return ctxt->host_offset;
 	default:
+		WARN_ONCE(1, "unrecognized timer %ld\n",
+			  arch_timer_ctx_index(ctxt));
 		return 0;
 	}
 }
@@ -144,6 +148,7 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
 
 	switch(arch_timer_ctx_index(ctxt)) {
 	case TIMER_VTIMER:
+	case TIMER_PTIMER:
 		ctxt->host_offset = offset;
 		break;
 	default:
@@ -572,6 +577,11 @@ static void set_cntvoff(u64 cntvoff)
 	kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff);
 }
 
+static void set_cntpoff(u64 cntpoff)
+{
+	kvm_call_hyp(__kvm_timer_set_cntpoff, cntpoff);
+}
+
 static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active)
 {
 	int r;
@@ -647,6 +657,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 	}
 
 	set_cntvoff(timer_get_offset(map.direct_vtimer));
+	if (cpus_have_const_cap(ARM64_ECV))
+		set_cntpoff(timer_get_offset(vcpu_ptimer(vcpu)));
 
 	kvm_timer_unblocking(vcpu);
 
@@ -814,6 +826,22 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
 	mutex_unlock(&kvm->lock);
 }
 
+static void update_ptimer_cntpoff(struct kvm_vcpu *vcpu, u64 cntpoff)
+{
+	struct kvm *kvm = vcpu->kvm;
+	u64 cntvoff;
+
+	mutex_lock(&kvm->lock);
+
+	/* adjustments to the physical offset also affect vtimer */
+	cntvoff = timer_get_offset(vcpu_vtimer(vcpu));
+	cntvoff += cntpoff - timer_get_offset(vcpu_ptimer(vcpu));
+
+	update_timer_offset(vcpu, TIMER_PTIMER, cntpoff, false);
+	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, false);
+	mutex_unlock(&kvm->lock);
+}
+
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
@@ -932,6 +960,29 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
 	return (u64)-1;
 }
 
+/**
+ * kvm_arm_timer_read_offset - returns the guest value of CNTVOFF_EL2.
+ * @vcpu: the vcpu pointer
+ *
+ * Computes the guest value of CNTVOFF_EL2 by subtracting the physical
+ * counter offset. Note that KVM defines CNTVOFF_EL2 as the offset from the
+ * guest's physical counter-timer, not the host's.
+ *
+ * Returns: the guest value for CNTVOFF_EL2
+ */
+static u64 kvm_arm_timer_read_offset(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+	u64 offset;
+
+	mutex_lock(&kvm->lock);
+	offset = timer_get_offset(vcpu_vtimer(vcpu)) -
+			timer_get_offset(vcpu_ptimer(vcpu));
+	mutex_unlock(&kvm->lock);
+
+	return offset;
+}
+
 static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 			      struct arch_timer_context *timer,
 			      enum kvm_arch_timer_regs treg)
@@ -957,7 +1008,7 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 		break;
 
 	case TIMER_REG_OFFSET:
-		val = timer_get_offset(timer);
+		val = kvm_arm_timer_read_offset(vcpu);
 		break;
 
 	default:
@@ -1350,6 +1401,9 @@ void kvm_timer_init_vhe(void)
 	val = read_sysreg(cnthctl_el2);
 	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
 	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
+
+	if (cpus_have_const_cap(ARM64_ECV))
+		val |= CNTHCTL_ECV;
 	write_sysreg(val, cnthctl_el2);
 }
 
@@ -1364,7 +1418,8 @@ static void set_timer_irqs(struct kvm *kvm, int vtimer_irq, int ptimer_irq)
 	}
 }
 
-int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+static int kvm_arm_timer_set_attr_irq(struct kvm_vcpu *vcpu,
+				      struct kvm_device_attr *attr)
 {
 	int __user *uaddr = (int __user *)(long)attr->addr;
 	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
@@ -1397,7 +1452,37 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	return 0;
 }
 
-int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
+					 struct kvm_device_attr *attr)
+{
+	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
+	u64 offset;
+
+	if (!cpus_have_const_cap(ARM64_ECV))
+		return -ENXIO;
+
+	if (get_user(offset, uaddr))
+		return -EFAULT;
+
+	update_ptimer_cntpoff(vcpu, offset);
+	return 0;
+}
+
+int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+{
+	switch (attr->attr) {
+	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
+	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
+		return kvm_arm_timer_set_attr_irq(vcpu, attr);
+	case KVM_ARM_VCPU_TIMER_OFFSET:
+		return kvm_arm_timer_set_attr_offset(vcpu, attr);
+	default:
+		return -ENXIO;
+	}
+}
+
+static int kvm_arm_timer_get_attr_irq(struct kvm_vcpu *vcpu,
+				      struct kvm_device_attr *attr)
 {
 	int __user *uaddr = (int __user *)(long)attr->addr;
 	struct arch_timer_context *timer;
@@ -1418,12 +1503,43 @@ int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	return put_user(irq, uaddr);
 }
 
+static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
+					 struct kvm_device_attr *attr)
+{
+	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
+	u64 offset;
+
+	if (!cpus_have_const_cap(ARM64_ECV))
+		return -ENXIO;
+
+	offset = timer_get_offset(vcpu_ptimer(vcpu));
+	return put_user(offset, uaddr);
+}
+
+int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu,
+			   struct kvm_device_attr *attr)
+{
+	switch (attr->attr) {
+	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
+	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
+		return kvm_arm_timer_get_attr_irq(vcpu, attr);
+	case KVM_ARM_VCPU_TIMER_OFFSET:
+		return kvm_arm_timer_get_attr_offset(vcpu, attr);
+	default:
+		return -ENXIO;
+	}
+}
+
 int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 {
 	switch (attr->attr) {
 	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
 	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
 		return 0;
+	case KVM_ARM_VCPU_TIMER_OFFSET:
+		if (cpus_have_const_cap(ARM64_ECV))
+			return 0;
+		break;
 	}
 
 	return -ENXIO;
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 1632f001f4ed..cfa923df3af6 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -68,6 +68,11 @@ static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt)
 	__kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1));
 }
 
+static void handle___kvm_timer_set_cntpoff(struct kvm_cpu_context *host_ctxt)
+{
+	__kvm_timer_set_cntpoff(cpu_reg(host_ctxt, 1));
+}
+
 static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt)
 {
 	u64 tmp;
@@ -197,6 +202,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_create_private_mapping),
 	HANDLE_FUNC(__pkvm_prot_finalize),
 	HANDLE_FUNC(__pkvm_mark_hyp),
+	HANDLE_FUNC(__kvm_timer_set_cntpoff),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index 9072e71693ba..5b8b4cd02506 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -15,6 +15,11 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
 	write_sysreg(cntvoff, cntvoff_el2);
 }
 
+void __kvm_timer_set_cntpoff(u64 cntpoff)
+{
+	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
+}
+
 /*
  * Should only be called on non-VHE systems.
  * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe().
diff --git a/arch/arm64/kvm/hyp/vhe/timer-sr.c b/arch/arm64/kvm/hyp/vhe/timer-sr.c
index 4cda674a8be6..231e16a071a5 100644
--- a/arch/arm64/kvm/hyp/vhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/timer-sr.c
@@ -10,3 +10,8 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
 {
 	write_sysreg(cntvoff, cntvoff_el2);
 }
+
+void __kvm_timer_set_cntpoff(u64 cntpoff)
+{
+	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
+}
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 73c7139c866f..7252ffa3d675 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -21,6 +21,7 @@
 #define CNTHCTL_EVNTEN			(1 << 2)
 #define CNTHCTL_EVNTDIR			(1 << 3)
 #define CNTHCTL_EVNTI			(0xF << 4)
+#define CNTHCTL_ECV			(1 << 12)
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:16 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:16 +0000
Subject: [PATCH v6 18/21] KVM: arm64: Configure timer traps in vcpu_load() for
 VHE
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-19-oupton@google.com>

In preparation for emulated physical counter-timer offsetting, configure
traps on every vcpu_load() for VHE systems. As before, these trap
settings do not affect host userspace, and are only active for the
guest.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/arm64/kvm/arch_timer.c  | 10 +++++++---
 arch/arm64/kvm/arm.c         |  4 +---
 include/kvm/arm_arch_timer.h |  2 --
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index f15058612994..9ead94aa867d 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -51,6 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
 static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 			      struct arch_timer_context *timer,
 			      enum kvm_arch_timer_regs treg);
+static void kvm_timer_enable_traps_vhe(void);
 
 u32 timer_get_ctl(struct arch_timer_context *ctxt)
 {
@@ -668,6 +669,9 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 
 	if (map.emul_ptimer)
 		timer_emulate(map.emul_ptimer);
+
+	if (has_vhe())
+		kvm_timer_enable_traps_vhe();
 }
 
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
@@ -1383,12 +1387,12 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
 }
 
 /*
- * On VHE system, we only need to configure the EL2 timer trap register once,
- * not for every world switch.
+ * On VHE system, we only need to configure the EL2 timer trap register on
+ * vcpu_load(), but not every world switch into the guest.
  * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
  * and this makes those bits have no effect for the host kernel execution.
  */
-void kvm_timer_init_vhe(void)
+static void kvm_timer_enable_traps_vhe(void)
 {
 	/* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
 	u32 cnthctl_shift = 10;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..47ea1e1ba80b 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1558,9 +1558,7 @@ static void cpu_hyp_reinit(void)
 
 	cpu_hyp_reset();
 
-	if (is_kernel_in_hyp_mode())
-		kvm_timer_init_vhe();
-	else
+	if (!is_kernel_in_hyp_mode())
 		cpu_init_hyp_mode();
 
 	cpu_set_hyp_vector();
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 615f9314f6a5..254653b42da0 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -87,8 +87,6 @@ u64 kvm_phys_timer_read(void);
 void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu);
 
-void kvm_timer_init_vhe(void);
-
 bool kvm_arch_timer_get_input_level(int vintid);
 
 #define vcpu_timer(v)	(&(v)->arch.timer_cpu)
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:17 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:17 +0000
Subject: [PATCH v6 19/21] KVM: arm64: Emulate physical counter offsetting on
 non-ECV systems
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-20-oupton@google.com>

Unfortunately, ECV hasn't yet arrived in any tangible hardware. At the
same time, controlling the guest view of the physical counter-timer is
useful. Support guest counter-timer offsetting on non-ECV systems by
trapping guest accesses to the physical counter-timer. Emulate reads of
the physical counter in the fast exit path.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/arm64/include/asm/sysreg.h         |  1 +
 arch/arm64/kvm/arch_timer.c             | 53 +++++++++++++++----------
 arch/arm64/kvm/hyp/include/hyp/switch.h | 29 ++++++++++++++
 arch/arm64/kvm/hyp/nvhe/timer-sr.c      | 11 ++++-
 4 files changed, 70 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index c34672aa65b9..e49790ae5da4 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -505,6 +505,7 @@
 #define SYS_AMEVCNTR0_MEM_STALL		SYS_AMEVCNTR0_EL0(3)
 
 #define SYS_CNTFRQ_EL0			sys_reg(3, 3, 14, 0, 0)
+#define SYS_CNTPCT_EL0			sys_reg(3, 3, 14, 0, 1)
 
 #define SYS_CNTP_TVAL_EL0		sys_reg(3, 3, 14, 2, 0)
 #define SYS_CNTP_CTL_EL0		sys_reg(3, 3, 14, 2, 1)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 9ead94aa867d..b7cb63acf2a0 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -51,7 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
 static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 			      struct arch_timer_context *timer,
 			      enum kvm_arch_timer_regs treg);
-static void kvm_timer_enable_traps_vhe(void);
+static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu);
 
 u32 timer_get_ctl(struct arch_timer_context *ctxt)
 {
@@ -175,6 +175,12 @@ static void timer_set_guest_offset(struct arch_timer_context *ctxt, u64 offset)
 	}
 }
 
+static bool ptimer_emulation_required(struct kvm_vcpu *vcpu)
+{
+	return timer_get_offset(vcpu_ptimer(vcpu)) &&
+			!cpus_have_const_cap(ARM64_ECV);
+}
+
 u64 kvm_phys_timer_read(void)
 {
 	return timecounter->cc->read(timecounter->cc);
@@ -184,8 +190,13 @@ static void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
 {
 	if (has_vhe()) {
 		map->direct_vtimer = vcpu_vtimer(vcpu);
-		map->direct_ptimer = vcpu_ptimer(vcpu);
-		map->emul_ptimer = NULL;
+		if (!ptimer_emulation_required(vcpu)) {
+			map->direct_ptimer = vcpu_ptimer(vcpu);
+			map->emul_ptimer = NULL;
+		} else {
+			map->direct_ptimer = NULL;
+			map->emul_ptimer = vcpu_ptimer(vcpu);
+		}
 	} else {
 		map->direct_vtimer = vcpu_vtimer(vcpu);
 		map->direct_ptimer = NULL;
@@ -671,7 +682,7 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 		timer_emulate(map.emul_ptimer);
 
 	if (has_vhe())
-		kvm_timer_enable_traps_vhe();
+		kvm_timer_enable_traps_vhe(vcpu);
 }
 
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
@@ -1392,22 +1403,29 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
  * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
  * and this makes those bits have no effect for the host kernel execution.
  */
-static void kvm_timer_enable_traps_vhe(void)
+static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu)
 {
 	/* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
 	u32 cnthctl_shift = 10;
-	u64 val;
+	u64 val, mask;
+
+	mask = CNTHCTL_EL1PCEN << cnthctl_shift;
+	mask |= CNTHCTL_EL1PCTEN << cnthctl_shift;
 
-	/*
-	 * VHE systems allow the guest direct access to the EL1 physical
-	 * timer/counter.
-	 */
 	val = read_sysreg(cnthctl_el2);
-	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
-	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
 
 	if (cpus_have_const_cap(ARM64_ECV))
 		val |= CNTHCTL_ECV;
+
+	/*
+	 * VHE systems allow the guest direct access to the EL1 physical
+	 * timer/counter if offsetting isn't requested on a non-ECV system.
+	 */
+	if (ptimer_emulation_required(vcpu))
+		val &= ~mask;
+	else
+		val |= mask;
+
 	write_sysreg(val, cnthctl_el2);
 }
 
@@ -1462,9 +1480,6 @@ static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
 	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
 	u64 offset;
 
-	if (!cpus_have_const_cap(ARM64_ECV))
-		return -ENXIO;
-
 	if (get_user(offset, uaddr))
 		return -EFAULT;
 
@@ -1513,9 +1528,6 @@ static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
 	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
 	u64 offset;
 
-	if (!cpus_have_const_cap(ARM64_ECV))
-		return -ENXIO;
-
 	offset = timer_get_offset(vcpu_ptimer(vcpu));
 	return put_user(offset, uaddr);
 }
@@ -1539,11 +1551,8 @@ int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	switch (attr->attr) {
 	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
 	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
-		return 0;
 	case KVM_ARM_VCPU_TIMER_OFFSET:
-		if (cpus_have_const_cap(ARM64_ECV))
-			return 0;
-		break;
+		return 0;
 	}
 
 	return -ENXIO;
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e4a2f295a394..abd3813a709e 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -15,6 +15,7 @@
 #include <linux/jump_label.h>
 #include <uapi/linux/psci.h>
 
+#include <kvm/arm_arch_timer.h>
 #include <kvm/arm_psci.h>
 
 #include <asm/barrier.h>
@@ -405,6 +406,31 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
 	return true;
 }
 
+static inline u64 __timer_read_cntpct(struct kvm_vcpu *vcpu)
+{
+	return __arch_counter_get_cntpct() - vcpu_ptimer(vcpu)->host_offset;
+}
+
+static inline bool __hyp_handle_counter(struct kvm_vcpu *vcpu)
+{
+	u32 sysreg;
+	int rt;
+	u64 rv;
+
+	if (kvm_vcpu_trap_get_class(vcpu) != ESR_ELx_EC_SYS64)
+		return false;
+
+	sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
+	if (sysreg != SYS_CNTPCT_EL0)
+		return false;
+
+	rt = kvm_vcpu_sys_get_rt(vcpu);
+	rv = __timer_read_cntpct(vcpu);
+	vcpu_set_reg(vcpu, rt, rv);
+	__kvm_skip_instr(vcpu);
+	return true;
+}
+
 /*
  * Return true when we were able to fixup the guest exit and should return to
  * the guest, false when we should restore the host state and return to the
@@ -439,6 +465,9 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	if (*exit_code != ARM_EXCEPTION_TRAP)
 		goto exit;
 
+	if (__hyp_handle_counter(vcpu))
+		goto guest;
+
 	if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) &&
 	    kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 &&
 	    handle_tx2_tvm(vcpu))
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index 5b8b4cd02506..67236c2e0ba7 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -44,10 +44,17 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
 
 	/*
 	 * Disallow physical timer access for the guest
-	 * Physical counter access is allowed
 	 */
 	val = read_sysreg(cnthctl_el2);
 	val &= ~CNTHCTL_EL1PCEN;
-	val |= CNTHCTL_EL1PCTEN;
+
+	/*
+	 * Disallow physical counter access for the guest if offsetting is
+	 * requested on a non-ECV system.
+	 */
+	if (vcpu_ptimer(vcpu)->host_offset && !cpus_have_const_cap(ARM64_ECV))
+		val &= ~CNTHCTL_EL1PCTEN;
+	else
+		val |= CNTHCTL_EL1PCTEN;
 	write_sysreg(val, cnthctl_el2);
 }
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:18 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:18 +0000
Subject: [PATCH v6 20/21] selftests: KVM: Test physical counter offsetting
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-21-oupton@google.com>

Test that userspace adjustment of the guest physical counter-timer
results in the correct view within the guest.

Cc: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 .../selftests/kvm/include/aarch64/processor.h | 12 +++++++
 .../kvm/system_counter_offset_test.c          | 31 +++++++++++++++++--
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index 3168cdbae6ee..7f53d90e9512 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -141,4 +141,16 @@ static inline uint64_t read_cntvct_ordered(void)
 	return r;
 }
 
+static inline uint64_t read_cntpct_ordered(void)
+{
+	uint64_t r;
+
+	__asm__ __volatile__("isb\n\t"
+			     "mrs %0, cntpct_el0\n\t"
+			     "isb\n\t"
+			     : "=r"(r));
+
+	return r;
+}
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c
index ac933db83d03..82d26a45cc48 100644
--- a/tools/testing/selftests/kvm/system_counter_offset_test.c
+++ b/tools/testing/selftests/kvm/system_counter_offset_test.c
@@ -57,6 +57,9 @@ static uint64_t host_read_guest_system_counter(struct test_case *test)
 
 enum arch_counter {
 	VIRTUAL,
+	PHYSICAL,
+	/* offset physical, read virtual */
+	PHYSICAL_READ_VIRTUAL,
 };
 
 struct test_case {
@@ -68,32 +71,54 @@ static struct test_case test_cases[] = {
 	{ .counter = VIRTUAL, .offset = 0 },
 	{ .counter = VIRTUAL, .offset = 180 * NSEC_PER_SEC },
 	{ .counter = VIRTUAL, .offset = -180 * NSEC_PER_SEC },
+	{ .counter = PHYSICAL, .offset = 0 },
+	{ .counter = PHYSICAL, .offset = 180 * NSEC_PER_SEC },
+	{ .counter = PHYSICAL, .offset = -180 * NSEC_PER_SEC },
+	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = 0 },
+	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = 180 * NSEC_PER_SEC },
+	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = -180 * NSEC_PER_SEC },
 };
 
 static void check_preconditions(struct kvm_vm *vm)
 {
-	if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET))
+	if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET) &&
+	    !_vcpu_has_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
+				   KVM_ARM_VCPU_TIMER_OFFSET))
 		return;
 
-	print_skip("KVM_REG_ARM_TIMER_OFFSET not supported; skipping test");
+	print_skip("KVM_REG_ARM_TIMER_OFFSET|KVM_ARM_VCPU_TIMER_OFFSET not supported; skipping test");
 	exit(KSFT_SKIP);
 }
 
 static void setup_system_counter(struct kvm_vm *vm, struct test_case *test)
 {
+	uint64_t cntvoff, cntpoff;
 	struct kvm_one_reg reg = {
 		.id = KVM_REG_ARM_TIMER_OFFSET,
-		.addr = (__u64)&test->offset,
+		.addr = (__u64)&cntvoff,
 	};
 
+	if (test->counter == VIRTUAL) {
+		cntvoff = test->offset;
+		cntpoff = 0;
+	} else {
+		cntvoff = 0;
+		cntpoff = test->offset;
+	}
+
 	vcpu_set_reg(vm, VCPU_ID, &reg);
+	vcpu_access_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
+				KVM_ARM_VCPU_TIMER_OFFSET, &cntpoff, true);
 }
 
 static uint64_t guest_read_system_counter(struct test_case *test)
 {
 	switch (test->counter) {
 	case VIRTUAL:
+	case PHYSICAL_READ_VIRTUAL:
 		return read_cntvct_ordered();
+	case PHYSICAL:
+		return read_cntpct_ordered();
 	default:
 		GUEST_ASSERT(0);
 	}
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug  4 01:58:19 2021
From: oupton at google.com (Oliver Upton)
Date: Wed,  4 Aug 2021 08:58:19 +0000
Subject: [PATCH v6 21/21] selftests: KVM: Add counter emulation benchmark
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <20210804085819.846610-22-oupton@google.com>

Add a test case for counter emulation on arm64. A side effect of how KVM
handles physical counter offsetting on non-ECV systems is that the
virtual counter will always hit hardware and the physical could be
emulated. Force emulation by writing a nonzero offset to the physical
counter and compare the elapsed cycles to a direct read of the hardware
register.

Reviewed-by: Ricardo Koller <ricarkol at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/aarch64/counter_emulation_benchmark.c | 207 ++++++++++++++++++
 3 files changed, 209 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 3d2585f0bffc..a5953f92f6b1 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+/aarch64/counter_emulation_benchmark
 /aarch64/debug-exceptions
 /aarch64/get-reg-list
 /aarch64/vgic_init
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index fab42e7c23ee..d24f7a914992 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -87,6 +87,7 @@ TEST_GEN_PROGS_x86_64 += steal_time
 TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
 TEST_GEN_PROGS_x86_64 += system_counter_offset_test
 
+TEST_GEN_PROGS_aarch64 += aarch64/counter_emulation_benchmark
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
 TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
diff --git a/tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c b/tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
new file mode 100644
index 000000000000..09ff79ab3d6f
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * counter_emulation_benchmark.c -- test to measure the effects of counter
+ * emulation on guest reads of the physical counter.
+ *
+ * Copyright (c) 2021, Google LLC.
+ */
+
+#define _GNU_SOURCE
+#include <asm/kvm.h>
+#include <linux/kvm.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "kvm_util.h"
+#include "processor.h"
+#include "test_util.h"
+
+#define VCPU_ID 0
+
+static struct counter_values {
+	uint64_t cntvct_start;
+	uint64_t cntpct;
+	uint64_t cntvct_end;
+} counter_values;
+
+static uint64_t nr_iterations = 1000;
+
+static void do_test(void)
+{
+	/*
+	 * Open-coded approach instead of using helper methods to keep a tight
+	 * interval around the physical counter read.
+	 */
+	asm volatile("isb\n\t"
+		     "mrs %[cntvct_start], cntvct_el0\n\t"
+		     "isb\n\t"
+		     "mrs %[cntpct], cntpct_el0\n\t"
+		     "isb\n\t"
+		     "mrs %[cntvct_end], cntvct_el0\n\t"
+		     "isb\n\t"
+		     : [cntvct_start] "=r"(counter_values.cntvct_start),
+		     [cntpct] "=r"(counter_values.cntpct),
+		     [cntvct_end] "=r"(counter_values.cntvct_end));
+}
+
+static void guest_main(void)
+{
+	int i;
+
+	for (i = 0; i < nr_iterations; i++) {
+		do_test();
+		GUEST_SYNC(i);
+	}
+
+	for (i = 0; i < nr_iterations; i++) {
+		do_test();
+		GUEST_SYNC(i);
+	}
+}
+
+static void enter_guest(struct kvm_vm *vm)
+{
+	struct ucall uc;
+
+	vcpu_ioctl(vm, VCPU_ID, KVM_RUN, NULL);
+
+	switch (get_ucall(vm, VCPU_ID, &uc)) {
+	case UCALL_SYNC:
+		break;
+	case UCALL_ABORT:
+		TEST_ASSERT(false, "%s at %s:%ld", (const char *)uc.args[0],
+			    __FILE__, uc.args[1]);
+		break;
+	default:
+		TEST_ASSERT(false, "unexpected exit: %s",
+			    exit_reason_str(vcpu_state(vm, VCPU_ID)->exit_reason));
+		break;
+	}
+}
+
+static double counter_frequency(void)
+{
+	uint32_t freq;
+
+	asm volatile("mrs %0, cntfrq_el0"
+		     : "=r" (freq));
+
+	return freq / 1000000.0;
+}
+
+static void log_csv(FILE *csv, bool trapped)
+{
+	double freq = counter_frequency();
+
+	fprintf(csv, "%s,%.02f,%lu,%lu,%lu\n",
+		trapped ? "true" : "false", freq,
+		counter_values.cntvct_start,
+		counter_values.cntpct,
+		counter_values.cntvct_end);
+}
+
+static double run_loop(struct kvm_vm *vm, FILE *csv, bool trapped)
+{
+	double avg = 0;
+	int i;
+
+	for (i = 0; i < nr_iterations; i++) {
+		uint64_t delta;
+
+		enter_guest(vm);
+		sync_global_from_guest(vm, counter_values);
+
+		if (csv)
+			log_csv(csv, trapped);
+
+		delta = counter_values.cntvct_end - counter_values.cntvct_start;
+		avg = ((avg * i) + delta) / (i + 1);
+	}
+
+	return avg;
+}
+
+static void setup_counter(struct kvm_vm *vm, uint64_t offset)
+{
+	vcpu_access_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
+				KVM_ARM_VCPU_TIMER_OFFSET, &offset,
+				true);
+}
+
+static void run_tests(struct kvm_vm *vm, FILE *csv)
+{
+	double avg_trapped, avg_native, freq;
+
+	freq = counter_frequency();
+
+	if (csv)
+		fputs("trapped,freq_mhz,cntvct_start,cntpct,cntvct_end\n", csv);
+
+	/* no physical offsetting; kvm allows reads of cntpct_el0 */
+	setup_counter(vm, 0);
+	avg_native = run_loop(vm, csv, false);
+
+	/* force emulation of the physical counter */
+	setup_counter(vm, 1);
+	avg_trapped = run_loop(vm, csv, true);
+
+	pr_info("%lu iterations: average cycles (@%.02fMHz) native: %.02f, trapped: %.02f\n",
+		nr_iterations, freq, avg_native, avg_trapped);
+}
+
+static void usage(const char *program_name)
+{
+	fprintf(stderr,
+		"Usage: %s [-h] [-o csv_file] [-n iterations]\n"
+		"  -h prints this message\n"
+		"  -n number of test iterations (default: %lu)\n"
+		"  -o csv file to write data\n",
+		program_name, nr_iterations);
+}
+
+int main(int argc, char **argv)
+{
+	struct kvm_vm *vm;
+	FILE *csv = NULL;
+	int opt;
+
+	while ((opt = getopt(argc, argv, "hn:o:")) != -1) {
+		switch (opt) {
+		case 'o':
+			csv = fopen(optarg, "w");
+			if (!csv) {
+				fprintf(stderr, "failed to open file '%s': %d\n",
+					optarg, errno);
+				exit(1);
+			}
+			break;
+		case 'n':
+			nr_iterations = strtoul(optarg, NULL, 0);
+			break;
+		default:
+			fprintf(stderr, "unrecognized option: '-%c'\n", opt);
+			/* fallthrough */
+		case 'h':
+			usage(argv[0]);
+			exit(1);
+		}
+	}
+
+	vm = vm_create_default(VCPU_ID, 0, guest_main);
+	sync_global_to_guest(vm, nr_iterations);
+	ucall_init(vm, NULL);
+
+	if (_vcpu_has_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
+				  KVM_ARM_VCPU_TIMER_OFFSET)) {
+		print_skip("KVM_ARM_VCPU_TIMER_OFFSET not supported.");
+		exit(KSFT_SKIP);
+	}
+
+	run_tests(vm, csv);
+	kvm_vm_free(vm);
+
+	if (csv)
+		fclose(csv);
+}
-- 
2.32.0.605.g8dce9f2422-goog



From shawnguo at kernel.org  Wed Aug  4 02:02:07 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 4 Aug 2021 17:02:07 +0800
Subject: [PATCH 1/2] ARM: imx_v6_v7_defconfig: Select CONFIG_KPROBES
In-Reply-To: <20210724132351.101847-1-festevam@gmail.com>
References: <20210724132351.101847-1-festevam@gmail.com>
Message-ID: <20210804090206.GA30984@dragon>

On Sat, Jul 24, 2021 at 10:23:50AM -0300, Fabio Estevam wrote:
> Building lttng-modules without CONFIG_KPROBES selected gives a build
> error.
> 
> Select CONFIG_KPROBES by default.
> 
> Signed-off-by: Fabio Estevam <festevam at gmail.com>

Applied both, thanks!


From shawnguo at kernel.org  Wed Aug  4 02:08:24 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 4 Aug 2021 17:08:24 +0800
Subject: [PATCH v9 3/3] arm64: dts: imx8mq: add mipi csi phy and csi
 bridge descriptions
In-Reply-To: <20210726082117.2423597-4-martin.kepplinger@puri.sm>
References: <20210726082117.2423597-1-martin.kepplinger@puri.sm>
 <20210726082117.2423597-4-martin.kepplinger@puri.sm>
Message-ID: <20210804090823.GB30984@dragon>

On Mon, Jul 26, 2021 at 10:21:17AM +0200, Martin Kepplinger wrote:
> Describe the 2 available CSI interfaces on the i.MX8MQ with the MIPI-CSI2
> receiver (new driver) and the CSI Bridge that provides the user buffers
> (existing driver).
> 
> An image sensor is to be connected to the MIPIs' second port, to be described
> in board files.
> 
> Signed-off-by: Martin Kepplinger <martin.kepplinger at puri.sm>

Applied, thanks!


From shawnguo at kernel.org  Wed Aug  4 02:09:11 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 4 Aug 2021 17:09:11 +0800
Subject: [PATCH v9 0/3] media: imx: add support for imx8mq MIPI RX
In-Reply-To: <YP9aujiWH2Q/ghHK@pendragon.ideasonboard.com>
References: <20210726082117.2423597-1-martin.kepplinger@puri.sm>
 <YP9aujiWH2Q/ghHK@pendragon.ideasonboard.com>
Message-ID: <20210804090910.GC30984@dragon>

On Tue, Jul 27, 2021 at 04:00:42AM +0300, Laurent Pinchart wrote:
> Hi Martin,
> 
> On Mon, Jul 26, 2021 at 10:21:14AM +0200, Martin Kepplinger wrote:
> > hi,
> > 
> > This patch series adds a driver for the i.MX8MQ CSI MIPI receiver / controller.
> > 
> > It includes the driver, the dt-bindings and the DT addition to the SoC dtsi.
> > I test it using libcamera. Thanks to Laurent who helped a lot. I'm happy for
> > any feedback,
> 
> No more feedback from me :-) I'll take patches 1/3 and 2/3 in my tree
> and send a pull request.
> 
> Shawn, could you please review 3/3 ?

Yeah, it looks good, and I just picked it up.

Shawn


From kuan-ying.lee at mediatek.com  Wed Aug  4 01:59:42 2021
From: kuan-ying.lee at mediatek.com (kuan.ying lee)
Date: Wed, 4 Aug 2021 16:59:42 +0800
Subject: [PATCH v2 2/2] kasan, slub: reset tag when printing address
In-Reply-To: <CANpmjNMAw=rcp_V+G_vjRjArj+09AkOxtC+wUNs-e1RRvfQm6w@mail.gmail.com>
References: <20210804082230.10837-1-Kuan-Ying.Lee@mediatek.com>
 <20210804082230.10837-3-Kuan-Ying.Lee@mediatek.com>
 <CANpmjNMAw=rcp_V+G_vjRjArj+09AkOxtC+wUNs-e1RRvfQm6w@mail.gmail.com>
Message-ID: <27f393ad9a926a96bfb9291b21cdd2a86ada2d4d.camel@mediatek.com>

On Wed, 2021-08-04 at 10:41 +0200, Marco Elver wrote:
> On Wed, 4 Aug 2021 at 10:23, Kuan-Ying Lee <
> Kuan-Ying.Lee at mediatek.com> wrote:
> > 
> > The address still includes the tags when it is printed.
> > With hardware tag-based kasan enabled, we will get a
> > false positive KASAN issue when we access metadata.
> > 
> > Reset the tag before we access the metadata.
> > 
> > Fixes: aa1ef4d7b3f6 ("kasan, mm: reset tags when accessing
> > metadata")
> > Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> > Suggested-by: Marco Elver <elver at google.com>
> 
> Note, in this case Suggested-by is inappropriate, because I did not
> suggest the change in any way (you already had it in v1). I just
> commented on the fact that it's missing a Fixes so stable can pick it
> up and some clarification.
> 
> Reviewed-by: Marco Elver <elver at google.com>

Got it.
I will remove it on v3.
Thanks.

> 
> > ---
> >  mm/slub.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/mm/slub.c b/mm/slub.c
> > index b6c5205252eb..f77d8cd79ef7 100644
> > --- a/mm/slub.c
> > +++ b/mm/slub.c
> > @@ -576,8 +576,8 @@ static void print_section(char *level, char
> > *text, u8 *addr,
> >                           unsigned int length)
> >  {
> >         metadata_access_enable();
> > -       print_hex_dump(level, kasan_reset_tag(text),
> > DUMP_PREFIX_ADDRESS,
> > -                       16, 1, addr, length, 1);
> > +       print_hex_dump(level, text, DUMP_PREFIX_ADDRESS,
> > +                       16, 1, kasan_reset_tag((void *)addr),
> > length, 1);
> >         metadata_access_disable();
> >  }
> > 
> > --
> > 2.18.0

From patchwork-bot+netdevbpf at kernel.org  Wed Aug  4 02:10:05 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 04 Aug 2021 09:10:05 +0000
Subject: [PATCH net-next] net: add extack arg for link ops
In-Reply-To: <20210803120250.32642-1-rocco.yue@mediatek.com>
References: <20210803120250.32642-1-rocco.yue@mediatek.com>
Message-ID: <162806820573.32022.14403323895648321150.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (refs/heads/master):

On Tue, 3 Aug 2021 20:02:50 +0800 you wrote:
> Pass extack arg to validate_linkmsg and validate_link_af callbacks.
> If a netlink attribute has a reject_message, use the extended ack
> mechanism to carry the message back to user space.
> 
> Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
> ---
>  include/net/rtnetlink.h | 3 ++-
>  net/core/rtnetlink.c    | 9 +++++----
>  net/ipv4/devinet.c      | 5 +++--
>  net/ipv6/addrconf.c     | 5 +++--
>  4 files changed, 13 insertions(+), 9 deletions(-)

Here is the summary with links:
  - [net-next] net: add extack arg for link ops
    https://git.kernel.org/netdev/net-next/c/8679c31e0284

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From Kuan-Ying.Lee at mediatek.com  Wed Aug  4 02:09:55 2021
From: Kuan-Ying.Lee at mediatek.com (Kuan-Ying Lee)
Date: Wed, 4 Aug 2021 17:09:55 +0800
Subject: [PATCH v3 0/2] kasan: reset tag when accessing invalid metadata
Message-ID: <20210804090957.12393-1-Kuan-Ying.Lee@mediatek.com>

With hardware tag-based kasan enabled, we reset the tag
when we access metadata to avoid from false alarm.

Changes since v3:
 - Remove inappropriate suggested-by

Changes since v2:
 - Refine the commit message in detail.
 - Thanks Andrey's explanation about false alarm
   of kmemleak.

Kuan-Ying Lee (2):
  kasan, kmemleak: reset tags when scanning block
  kasan, slub: reset tag when printing address

 mm/kmemleak.c | 6 +++---
 mm/slub.c     | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

-- 
2.18.0

From Kuan-Ying.Lee at mediatek.com  Wed Aug  4 02:09:57 2021
From: Kuan-Ying.Lee at mediatek.com (Kuan-Ying Lee)
Date: Wed, 4 Aug 2021 17:09:57 +0800
Subject: [PATCH v3 2/2] kasan, slub: reset tag when printing address
In-Reply-To: <20210804090957.12393-1-Kuan-Ying.Lee@mediatek.com>
References: <20210804090957.12393-1-Kuan-Ying.Lee@mediatek.com>
Message-ID: <20210804090957.12393-3-Kuan-Ying.Lee@mediatek.com>

The address still includes the tags when it is printed.
With hardware tag-based kasan enabled, we will get a
false positive KASAN issue when we access metadata.

Reset the tag before we access the metadata.

Fixes: aa1ef4d7b3f6 ("kasan, mm: reset tags when accessing metadata")
Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
Reviewed-by: Marco Elver <elver at google.com>
---
 mm/slub.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index b6c5205252eb..f77d8cd79ef7 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -576,8 +576,8 @@ static void print_section(char *level, char *text, u8 *addr,
 			  unsigned int length)
 {
 	metadata_access_enable();
-	print_hex_dump(level, kasan_reset_tag(text), DUMP_PREFIX_ADDRESS,
-			16, 1, addr, length, 1);
+	print_hex_dump(level, text, DUMP_PREFIX_ADDRESS,
+			16, 1, kasan_reset_tag((void *)addr), length, 1);
 	metadata_access_disable();
 }
 
-- 
2.18.0

From Kuan-Ying.Lee at mediatek.com  Wed Aug  4 02:09:56 2021
From: Kuan-Ying.Lee at mediatek.com (Kuan-Ying Lee)
Date: Wed, 4 Aug 2021 17:09:56 +0800
Subject: [PATCH v3 1/2] kasan, kmemleak: reset tags when scanning block
In-Reply-To: <20210804090957.12393-1-Kuan-Ying.Lee@mediatek.com>
References: <20210804090957.12393-1-Kuan-Ying.Lee@mediatek.com>
Message-ID: <20210804090957.12393-2-Kuan-Ying.Lee@mediatek.com>

Kmemleak need to scan kernel memory to check memory leak.
With hardware tag-based kasan enabled, when it scans on
the invalid slab and dereference, the issue will occur
as below.

Hardware tag-based KASAN doesn't use compiler instrumentation, we
can not use kasan_disable_current() to ignore tag check.

Based on the below report, there are 11 0xf7 granules, which amounts to
176 bytes, and the object is allocated from the kmalloc-256 cache. So
when kmemleak accesses the last 256-176 bytes, it causes faults, as
those are marked with KASAN_KMALLOC_REDZONE == KASAN_TAG_INVALID ==
0xfe.

Thus, we reset tags before accessing metadata to avoid from false positives.

[  151.905804] ==================================================================
[  151.907120] BUG: KASAN: out-of-bounds in scan_block+0x58/0x170
[  151.908773] Read at addr f7ff0000c0074eb0 by task kmemleak/138
[  151.909656] Pointer tag: [f7], memory tag: [fe]
[  151.910195]
[  151.910876] CPU: 7 PID: 138 Comm: kmemleak Not tainted 5.14.0-rc2-00001-g8cae8cd89f05-dirty #134
[  151.912085] Hardware name: linux,dummy-virt (DT)
[  151.912868] Call trace:
[  151.913211]  dump_backtrace+0x0/0x1b0
[  151.913796]  show_stack+0x1c/0x30
[  151.914248]  dump_stack_lvl+0x68/0x84
[  151.914778]  print_address_description+0x7c/0x2b4
[  151.915340]  kasan_report+0x138/0x38c
[  151.915804]  __do_kernel_fault+0x190/0x1c4
[  151.916386]  do_tag_check_fault+0x78/0x90
[  151.916856]  do_mem_abort+0x44/0xb4
[  151.917308]  el1_abort+0x40/0x60
[  151.917754]  el1h_64_sync_handler+0xb4/0xd0
[  151.918270]  el1h_64_sync+0x78/0x7c
[  151.918714]  scan_block+0x58/0x170
[  151.919157]  scan_gray_list+0xdc/0x1a0
[  151.919626]  kmemleak_scan+0x2ac/0x560
[  151.920129]  kmemleak_scan_thread+0xb0/0xe0
[  151.920635]  kthread+0x154/0x160
[  151.921115]  ret_from_fork+0x10/0x18
[  151.921717]
[  151.922077] Allocated by task 0:
[  151.922523]  kasan_save_stack+0x2c/0x60
[  151.923099]  __kasan_kmalloc+0xec/0x104
[  151.923502]  __kmalloc+0x224/0x3c4
[  151.924172]  __register_sysctl_paths+0x200/0x290
[  151.924709]  register_sysctl_table+0x2c/0x40
[  151.925175]  sysctl_init+0x20/0x34
[  151.925665]  proc_sys_init+0x3c/0x48
[  151.926136]  proc_root_init+0x80/0x9c
[  151.926547]  start_kernel+0x648/0x6a4
[  151.926987]  __primary_switched+0xc0/0xc8
[  151.927557]
[  151.927994] Freed by task 0:
[  151.928340]  kasan_save_stack+0x2c/0x60
[  151.928766]  kasan_set_track+0x2c/0x40
[  151.929173]  kasan_set_free_info+0x44/0x54
[  151.929568]  ____kasan_slab_free.constprop.0+0x150/0x1b0
[  151.930063]  __kasan_slab_free+0x14/0x20
[  151.930449]  slab_free_freelist_hook+0xa4/0x1fc
[  151.930924]  kfree+0x1e8/0x30c
[  151.931285]  put_fs_context+0x124/0x220
[  151.931731]  vfs_kern_mount.part.0+0x60/0xd4
[  151.932280]  kern_mount+0x24/0x4c
[  151.932686]  bdev_cache_init+0x70/0x9c
[  151.933122]  vfs_caches_init+0xdc/0xf4
[  151.933578]  start_kernel+0x638/0x6a4
[  151.934014]  __primary_switched+0xc0/0xc8
[  151.934478]
[  151.934757] The buggy address belongs to the object at ffff0000c0074e00
[  151.934757]  which belongs to the cache kmalloc-256 of size 256
[  151.935744] The buggy address is located 176 bytes inside of
[  151.935744]  256-byte region [ffff0000c0074e00, ffff0000c0074f00)
[  151.936702] The buggy address belongs to the page:
[  151.937378] page:(____ptrval____) refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x100074
[  151.938682] head:(____ptrval____) order:2 compound_mapcount:0 compound_pincount:0
[  151.939440] flags: 0xbfffc0000010200(slab|head|node=0|zone=2|lastcpupid=0xffff|kasantag=0x0)
[  151.940886] raw: 0bfffc0000010200 0000000000000000 dead000000000122 f5ff0000c0002300
[  151.941634] raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000
[  151.942353] page dumped because: kasan: bad access detected
[  151.942923]
[  151.943214] Memory state around the buggy address:
[  151.943896]  ffff0000c0074c00: f0 f0 f0 f0 f0 f0 f0 f0 f0 fe fe fe fe fe fe fe
[  151.944857]  ffff0000c0074d00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
[  151.945892] >ffff0000c0074e00: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 fe fe fe fe fe
[  151.946407]                                                     ^
[  151.946939]  ffff0000c0074f00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
[  151.947445]  ffff0000c0075000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  151.947999] ==================================================================
[  151.948524] Disabling lock debugging due to kernel taint
[  156.434569] kmemleak: 181 new suspected memory leaks (see /sys/kernel/debug/kmemleak)

Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Cc: Marco Elver <elver at google.com>
Cc: Andrey Konovalov <andreyknvl at gmail.com>
---
 mm/kmemleak.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 228a2fbe0657..73d46d16d575 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -290,7 +290,7 @@ static void hex_dump_object(struct seq_file *seq,
 	warn_or_seq_printf(seq, "  hex dump (first %zu bytes):\n", len);
 	kasan_disable_current();
 	warn_or_seq_hex_dump(seq, DUMP_PREFIX_NONE, HEX_ROW_SIZE,
-			     HEX_GROUP_SIZE, ptr, len, HEX_ASCII);
+			     HEX_GROUP_SIZE, kasan_reset_tag((void *)ptr), len, HEX_ASCII);
 	kasan_enable_current();
 }
 
@@ -1171,7 +1171,7 @@ static bool update_checksum(struct kmemleak_object *object)
 
 	kasan_disable_current();
 	kcsan_disable_current();
-	object->checksum = crc32(0, (void *)object->pointer, object->size);
+	object->checksum = crc32(0, kasan_reset_tag((void *)object->pointer), object->size);
 	kasan_enable_current();
 	kcsan_enable_current();
 
@@ -1246,7 +1246,7 @@ static void scan_block(void *_start, void *_end,
 			break;
 
 		kasan_disable_current();
-		pointer = *ptr;
+		pointer = *(unsigned long *)kasan_reset_tag((void *)ptr);
 		kasan_enable_current();
 
 		untagged_ptr = (unsigned long)kasan_reset_tag((void *)pointer);
-- 
2.18.0

From drjones at redhat.com  Wed Aug  4 02:14:53 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 4 Aug 2021 11:14:53 +0200
Subject: [PATCH v6 14/21] selftests: KVM: Add helper to check for
 register presence
In-Reply-To: <20210804085819.846610-15-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-15-oupton@google.com>
Message-ID: <20210804091453.u4bf75pfeyldowt5@gator.home>

On Wed, Aug 04, 2021 at 08:58:12AM +0000, Oliver Upton wrote:
> The KVM_GET_REG_LIST vCPU ioctl returns a list of supported registers
> for a given vCPU. Add a helper to check if a register exists in the list
> of supported registers.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  .../testing/selftests/kvm/include/kvm_util.h  |  2 ++
>  tools/testing/selftests/kvm/lib/kvm_util.c    | 19 +++++++++++++++++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
> index 1b3ef5757819..077082dd2ca7 100644
> --- a/tools/testing/selftests/kvm/include/kvm_util.h
> +++ b/tools/testing/selftests/kvm/include/kvm_util.h
> @@ -215,6 +215,8 @@ void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid,
>  		  struct kvm_fpu *fpu);
>  void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid,
>  		  struct kvm_fpu *fpu);
> +
> +bool vcpu_has_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t reg_id);
>  void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
>  void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
>  #ifdef __KVM_HAVE_VCPU_EVENTS
> diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
> index 0fe66ca6139a..a5801d4ed37d 100644
> --- a/tools/testing/selftests/kvm/lib/kvm_util.c
> +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
> @@ -1823,6 +1823,25 @@ void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu)
>  		    ret, errno, strerror(errno));
>  }
>  
> +bool vcpu_has_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t reg_id)
> +{
> +	struct kvm_reg_list *list;
> +	bool ret = false;
> +	uint64_t i;
> +
> +	list = vcpu_get_reg_list(vm, vcpuid);
> +
> +	for (i = 0; i < list->n; i++) {
> +		if (list->reg[i] == reg_id) {
> +			ret = true;
> +			break;
> +		}
> +	}
> +
> +	free(list);
> +	return ret;
> +}
> +
>  void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg)
>  {
>  	int ret;
> -- 
> 2.32.0.605.g8dce9f2422-goog
>

Reviewed-by: Andrew Jones <drjones at redhat.com>



From maz at kernel.org  Wed Aug  4 02:21:23 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Aug 2021 10:21:23 +0100
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>
Message-ID: <87r1f9wooc.wl-maz@kernel.org>

On Tue, 03 Aug 2021 09:35:12 +0100,
Robin Murphy <robin.murphy at arm.com> wrote:
> 
> On 2021-08-03 03:11, Sunil Muthuswamy wrote:
> >   On Saturday, July 31, 2021 2:52 AM,
> >   Marc Zyngier <maz at kernel.org> wrote:
> >> 
> >> [...]
> >> 
> >>>> I also want to understand *how* you are going to plumb this into both
> >>>> ACPI and DT, given that neither understand how to link a PCI endpoint
> >>>> to a set of RDs.
> >>>> 
> >>>> 	M.
> >>> 
> >>> One way to do this for NUMA-aware systems would be to use the NUMA
> >>> related information that is available with PCI endpoints or root complex, to
> >>> pick a Redistributor/CPU that is in the NUMA node, as specified by the PCI
> >>> endpoint/root complex. In DT PCI devices can specify this using
> >>> 'numa-node-id' and in ACPI using the '_PXM (Proximity)'. For systems that
> >>> are not NUMA-aware, we can go with *any* Redistributor/CPU.
> >> 
> >> This makes zero sense. From the point of view of a device, all the RDs
> >> should be reachable, and firmware has no say in it. Dealing with
> >> interrupt affinity is the responsibility of the endpoint driver, and
> >> NUMA affinity is only a performance optimisation.
> >> 
> >>> Is there any additional information we would be able to gather from ACPI
> >>> or DT that's not there currently, that would be useful here?
> >> 
> >> You will need some firmware information describing that a given set of
> >> devices must use the RDs for their MSIs. Just like we currently
> >> describe it in IORT for the ITS. You cannot /assume/ things. At the
> >> moment, there is nothing at all, because no-one (including Microsoft)
> >> thought it would be a good idea not to have an ITS, which is also why
> >> ACPI doesn't describe MBIs as a potential MSI provider.
> >> 
> > I am a little bit confused by your above comment. Maybe you can help me
> > understand the ask. You indicate that from the point of the view of the
> > device, all the RDs should be reachable. But, then if we define a mapping
> > between PCI endpoint and RD in the firmware, we would be doing exactly
> > the opposite. i.e. restricting the RDs that are reachable by the device. Can
> > you please clarify?

Not at all. What I am saying is that you need to describe that the
MSIs have to be routed to the RDs, and there is no way to express this
at the moment.

> > 
> > Is your concern that the device should be able to only DMA to a subset of
> > GIC Redistributor, for the MSIs? If so, in the IORT, there is "memory address
> > size limit" for both device and root complex nodes. In the implementation,
> > we can enforce that the GICR is within that range. And, if a device deviates
> > further than that (ex: by having accessibility gaps within the GICR range),
> > then that is out of scope for support.
> 
> No, please don't try to abuse the Memory Address Size Limit - that has
> far more chance of adversely affecting normal DMA operation than of
> being any use here.
> 
> I believe the point Marc was trying to make is that firmware should
> not associate a device with any one *specific* redistributor, however
> ACPI currently has no way to describe that MSIs can target
> redistributors *at all*, only ITS groups - there is no such concept as
> a "redistributor group".

Thanks Robin.

That is exactly my point. There is no linkage whatsoever between a
device generating MSIs and the redistributors. In that respect, this
is the same issue we have with DT, as none of the firmware interfaces
can currently describe MSIs directly targeting the RDs. The only way
to describe MSIs with GICv3 in ACPI is to describe an ITS, and you
cannot use the *absence* of an ITS to decide and use DirectLPIs.

Given the state of things, using DirectLPI means that you need to
extend the firmware interfaces. This means both an extension to the DT
binding, and an update to the ACPI spec. There is no way around this.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug  4 02:22:41 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed,  4 Aug 2021 18:22:41 +0900
Subject: [PATCH v4 1/4] dt-bindings: clock: Add DT bindings for PLL of Toshiba
 Visconti TMPV770x SoC
In-Reply-To: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20210804092244.390376-2-nobuhiro1.iwamatsu@toshiba.co.jp>

Add device tree bindings for PLL of Toshiba Visconti TMPV770x SoC series.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 .../clock/toshiba,tmpv770x-pipllct.yaml       | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml

diff --git a/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
new file mode 100644
index 000000000000..7b7300ce96d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/toshiba,tmpv770x-pipllct.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Toshiba Visconti5 TMPV770X PLL Controller Device Tree Bindings
+
+maintainers:
+  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+
+description:
+  Toshia Visconti5 PLL controller which supports the PLLs on TMPV770X.
+
+properties:
+  compatible:
+    const: toshiba,tmpv7708-pipllct
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+  clocks:
+    description: External reference clock (OSC2)
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    osc2_clk: osc2-clk {
+      compatible = "fixed-clock";
+      clock-frequency = <20000000>;
+      #clock-cells = <0>;
+    };
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pipllct: clock-controller at 24220000 {
+            compatible = "toshiba,tmpv7708-pipllct";
+            reg = <0 0x24220000 0 0x820>;
+            #clock-cells = <1>;
+            clocks = <&osc2_clk>;
+        };
+    };
+...
-- 
2.32.0




From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug  4 02:22:40 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed,  4 Aug 2021 18:22:40 +0900
Subject: [PATCH v4 0/4] clk: visconti: Add support common clock driver and
 reset driver
Message-ID: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>

Hi,

This series is PLL, clock and reset driver for Toshiba's ARM SoC, Visconti[0].
Since the clock driver and reset driver are provided as one function, they are
provided in cooperation with the clock driver.

This provides DT binding documentation, device driver, MAINTAINER files.

Best regards,
  Nobuhiro

[0]:
https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html

  clk: visconti: Add support common clock driver and reset driver
    v3 -> v4:
       - Remove osc2 clock's code. Move to DT.
    v2 -> v3:
       - Fix return value in visconti_register_pll().
       - Remove initialization of flags used by spin_lock_irqsave().
       - - Change function name from *7708* to *770x*.
       - Fix some coding style.
    v1 -> v2:
       - Fix warning with W=1

  dt-bindings: clock: Add DT bindings for PLL of Toshiba Visconti TMPV7708 SoC
    v3 -> v4:
       - Fix node name to clock-controller.
       - Remove osc2-clk-frequency, and this defines to DT as fixed-clock.
       - Add clocks.
    v2 -> v3:
       - Change file name.
    v1 -> v2:
       - Update subject.

  dt-bindings: clock: Add DT bindings for SMU of Toshiba Visconti TMPV7708 SoC
    v3 -> v4:
      - Move reset dt-binding header file.
      - Move clock dt-binding header file.
      - Change dt-binding header's License to 'GPL-2.0-only OR BSD-2-Clause'
      - Fix node name to clock-controller.
    v2 -> v3:
       - Change file name.
    v1 -> v2:
       - Update subject.

  MAINTAINERS: Add entries for Toshiba Visconti PLL and clock controller
    v3 -> v4:
       - no update.
    v2 -> v3:
       - Change path of DT binding files.
    v1 -> v2:
       - no update.

Nobuhiro Iwamatsu (4):
  dt-bindings: clock: Add DT bindings for PLL of Toshiba Visconti TMPV770x SoC
  dt-bindings: clock: Add DT bindings for SMU of Toshiba Visconti TMPV770x SoC
  clk: visconti: Add support common clock driver and reset driver
  MAINTAINERS: Add entries for Toshiba Visconti PLL and clock controller

 .../clock/toshiba,tmpv770x-pipllct.yaml       |  57 +++
 .../clock/toshiba,tmpv770x-pismu.yaml         |  50 +++
 MAINTAINERS                                   |   3 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/visconti/Makefile                 |   5 +
 drivers/clk/visconti/clkc-tmpv770x.c          | 232 +++++++++++
 drivers/clk/visconti/clkc.c                   | 220 +++++++++++
 drivers/clk/visconti/clkc.h                   |  75 ++++
 drivers/clk/visconti/pll-tmpv770x.c           |  85 ++++
 drivers/clk/visconti/pll.c                    | 369 ++++++++++++++++++
 drivers/clk/visconti/pll.h                    |  63 +++
 drivers/clk/visconti/reset.c                  | 111 ++++++
 drivers/clk/visconti/reset.h                  |  35 ++
 include/dt-bindings/clock/toshiba,tmpv770x.h  | 181 +++++++++
 include/dt-bindings/reset/toshiba,tmpv770x.h  |  41 ++
 15 files changed, 1528 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
 create mode 100644 drivers/clk/visconti/Makefile
 create mode 100644 drivers/clk/visconti/clkc-tmpv770x.c
 create mode 100644 drivers/clk/visconti/clkc.c
 create mode 100644 drivers/clk/visconti/clkc.h
 create mode 100644 drivers/clk/visconti/pll-tmpv770x.c
 create mode 100644 drivers/clk/visconti/pll.c
 create mode 100644 drivers/clk/visconti/pll.h
 create mode 100644 drivers/clk/visconti/reset.c
 create mode 100644 drivers/clk/visconti/reset.h
 create mode 100644 include/dt-bindings/clock/toshiba,tmpv770x.h
 create mode 100644 include/dt-bindings/reset/toshiba,tmpv770x.h

-- 
2.32.0




From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug  4 02:22:44 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed,  4 Aug 2021 18:22:44 +0900
Subject: [PATCH v4 4/4] MAINTAINERS: Add entries for Toshiba Visconti PLL and
 clock controller
In-Reply-To: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20210804092244.390376-5-nobuhiro1.iwamatsu@toshiba.co.jp>

Add entries for Toshiba Visconti PLL and clock controller binding and
driver.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bd7aff0c120f..334d482810e7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,11 +2661,14 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iwamatsu/linux-visconti.git
 F:	Documentation/devicetree/bindings/arm/toshiba.yaml
+F:	Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
+F:	Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
 F:	Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
 F:	Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
 F:	Documentation/devicetree/bindings/pinctrl/toshiba,tmpv7700-pinctrl.yaml
 F:	Documentation/devicetree/bindings/watchdog/toshiba,visconti-wdt.yaml
 F:	arch/arm64/boot/dts/toshiba/
+F:	drivers/clk/visconti/
 F:	drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
 F:	drivers/gpio/gpio-visconti.c
 F:	drivers/pinctrl/visconti/
-- 
2.32.0




From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug  4 02:22:42 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed,  4 Aug 2021 18:22:42 +0900
Subject: [PATCH v4 2/4] dt-bindings: clock: Add DT bindings for SMU of Toshiba
 Visconti TMPV770x SoC
In-Reply-To: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20210804092244.390376-3-nobuhiro1.iwamatsu@toshiba.co.jp>

Add device tree bindings for SMU (System Management Unit) controller of
Toshiba Visconti TMPV770x SoC series.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 .../clock/toshiba,tmpv770x-pismu.yaml         |  50 +++++
 include/dt-bindings/clock/toshiba,tmpv770x.h  | 181 ++++++++++++++++++
 include/dt-bindings/reset/toshiba,tmpv770x.h  |  41 ++++
 3 files changed, 272 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
 create mode 100644 include/dt-bindings/clock/toshiba,tmpv770x.h
 create mode 100644 include/dt-bindings/reset/toshiba,tmpv770x.h

diff --git a/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
new file mode 100644
index 000000000000..845a8d277965
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/toshiba,tmpv770x-pismu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Toshiba Visconti5 TMPV770x SMU controller Device Tree Bindings
+
+maintainers:
+  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+
+description:
+  Toshia Visconti5 SMU (System Management Unit) which supports the clock
+  and resets on TMPV770x.
+
+properties:
+  compatible:
+    const: toshiba,tmpv7708-pismu
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pismu: clock-controller at 24200000 {
+            compatible = "toshiba,tmpv7708-pismu";
+            reg = <0 0x24200000 0 0x2140>;
+            #clock-cells = <1>;
+            #reset-cells = <1>;
+        };
+    };
+...
diff --git a/include/dt-bindings/clock/toshiba,tmpv770x.h b/include/dt-bindings/clock/toshiba,tmpv770x.h
new file mode 100644
index 000000000000..5fce713001fd
--- /dev/null
+++ b/include/dt-bindings/clock/toshiba,tmpv770x.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_CLOCK_TOSHIBA_TMPV770X_H_
+#define _DT_BINDINGS_CLOCK_TOSHIBA_TMPV770X_H_
+
+/* PLL */
+#define TMPV770X_PLL_PIPLL0		0
+#define TMPV770X_PLL_PIPLL1		1
+#define TMPV770X_PLL_PIDNNPLL		2
+#define TMPV770X_PLL_PIETHERPLL		3
+#define TMPV770X_PLL_PIDDRCPLL		4
+#define TMPV770X_PLL_PIVOIFPLL		5
+#define TMPV770X_PLL_PIIMGERPLL		6
+#define TMPV770X_NR_PLL		7
+
+/* Clocks */
+#define TMPV770X_CLK_PIPLL1_DIV1	0
+#define TMPV770X_CLK_PIPLL1_DIV2	1
+#define TMPV770X_CLK_PIPLL1_DIV4	2
+#define TMPV770X_CLK_PIDNNPLL_DIV1	3
+#define TMPV770X_CLK_DDRC_PHY_PLL0	4
+#define TMPV770X_CLK_DDRC_PHY_PLL1	5
+#define TMPV770X_CLK_D_PHYPLL		6
+#define TMPV770X_CLK_PHY_PCIEPLL	7
+#define TMPV770X_CLK_CA53CL0		8
+#define TMPV770X_CLK_CA53CL1		9
+#define TMPV770X_CLK_PISDMAC		10
+#define TMPV770X_CLK_PIPDMAC0		11
+#define TMPV770X_CLK_PIPDMAC1		12
+#define TMPV770X_CLK_PIWRAM		13
+#define TMPV770X_CLK_DDRC0		14
+#define TMPV770X_CLK_DDRC0_SCLK		15
+#define TMPV770X_CLK_DDRC0_NCLK		16
+#define TMPV770X_CLK_DDRC0_MCLK		17
+#define TMPV770X_CLK_DDRC0_APBCLK	18
+#define TMPV770X_CLK_DDRC1		19
+#define TMPV770X_CLK_DDRC1_SCLK		20
+#define TMPV770X_CLK_DDRC1_NCLK		21
+#define TMPV770X_CLK_DDRC1_MCLK		22
+#define TMPV770X_CLK_DDRC1_APBCLK	23
+#define TMPV770X_CLK_HOX		24
+#define TMPV770X_CLK_PCIE_MSTR		25
+#define TMPV770X_CLK_PCIE_AUX		26
+#define TMPV770X_CLK_PIINTC		27
+#define TMPV770X_CLK_PIETHER_BUS	28
+#define TMPV770X_CLK_PISPI0		29
+#define TMPV770X_CLK_PISPI1		30
+#define TMPV770X_CLK_PISPI2		31
+#define TMPV770X_CLK_PISPI3		32
+#define TMPV770X_CLK_PISPI4		33
+#define TMPV770X_CLK_PISPI5		34
+#define TMPV770X_CLK_PISPI6		35
+#define TMPV770X_CLK_PIUART0		36
+#define TMPV770X_CLK_PIUART1		37
+#define TMPV770X_CLK_PIUART2		38
+#define TMPV770X_CLK_PIUART3		39
+#define TMPV770X_CLK_PII2C0		40
+#define TMPV770X_CLK_PII2C1		41
+#define TMPV770X_CLK_PII2C2		42
+#define TMPV770X_CLK_PII2C3		43
+#define TMPV770X_CLK_PII2C4		44
+#define TMPV770X_CLK_PII2C5		45
+#define TMPV770X_CLK_PII2C6		46
+#define TMPV770X_CLK_PII2C7		47
+#define TMPV770X_CLK_PII2C8		48
+#define TMPV770X_CLK_PIGPIO		49
+#define TMPV770X_CLK_PIPGM		50
+#define TMPV770X_CLK_PIPCMIF		51
+#define TMPV770X_CLK_PIPCMIF_AUDIO_O	52
+#define TMPV770X_CLK_PIPCMIF_AUDIO_I	53
+#define TMPV770X_CLK_PICMPT0		54
+#define TMPV770X_CLK_PICMPT1		55
+#define TMPV770X_CLK_PITSC		56
+#define TMPV770X_CLK_PIUWDT		57
+#define TMPV770X_CLK_PISWDT		58
+#define TMPV770X_CLK_WDTCLK		59
+#define TMPV770X_CLK_PISUBUS_150M	60
+#define TMPV770X_CLK_PISUBUS_300M	61
+#define TMPV770X_CLK_PIPMU		62
+#define TMPV770X_CLK_PIGPMU		63
+#define TMPV770X_CLK_PITMU		64
+#define TMPV770X_CLK_WRCK		65
+#define TMPV770X_CLK_PIEMM		66
+#define TMPV770X_CLK_PIMISC		67
+#define TMPV770X_CLK_PIGCOMM		68
+#define TMPV770X_CLK_PIDCOMM		69
+#define TMPV770X_CLK_PICKMON		70
+#define TMPV770X_CLK_PIMBUS		71
+#define TMPV770X_CLK_SBUSCLK		72
+#define TMPV770X_CLK_DDR0_APBCLKCLK	73
+#define TMPV770X_CLK_DDR1_APBCLKCLK	74
+#define TMPV770X_CLK_DSP0_PBCLK		75
+#define TMPV770X_CLK_DSP1_PBCLK		76
+#define TMPV770X_CLK_DSP2_PBCLK		77
+#define TMPV770X_CLK_DSP3_PBCLK		78
+#define TMPV770X_CLK_DSVIIF0_APBCLK	79
+#define TMPV770X_CLK_VIIF0_APBCLK	80
+#define TMPV770X_CLK_VIIF0_CFGCLK	81
+#define TMPV770X_CLK_VIIF1_APBCLK	82
+#define TMPV770X_CLK_VIIF1_CFGCLK	83
+#define TMPV770X_CLK_VIIF2_APBCLK	84
+#define TMPV770X_CLK_VIIF2_CFGCLK	85
+#define TMPV770X_CLK_VIIF3_APBCLK	86
+#define TMPV770X_CLK_VIIF3_CFGCLK	87
+#define TMPV770X_CLK_VIIF4_APBCLK	88
+#define TMPV770X_CLK_VIIF4_CFGCLK	89
+#define TMPV770X_CLK_VIIF5_APBCLK	90
+#define TMPV770X_CLK_VIIF5_CFGCLK	91
+#define TMPV770X_CLK_VOIF_SBUSCLK	92
+#define TMPV770X_CLK_VOIF_PROCCLK	93
+#define TMPV770X_CLK_VOIF_DPHYCFGCLK	94
+#define TMPV770X_CLK_DNN0		95
+#define TMPV770X_CLK_STMAT		96
+#define TMPV770X_CLK_HWA0		97
+#define TMPV770X_CLK_AFFINE0		98
+#define TMPV770X_CLK_HAMAT		99
+#define TMPV770X_CLK_SMLDB		100
+#define TMPV770X_CLK_HWA0_ASYNC		101
+#define TMPV770X_CLK_HWA2		102
+#define TMPV770X_CLK_FLMAT		103
+#define TMPV770X_CLK_PYRAMID		104
+#define TMPV770X_CLK_HWA2_ASYNC		105
+#define TMPV770X_CLK_DSP0		106
+#define TMPV770X_CLK_VIIFBS0		107
+#define TMPV770X_CLK_VIIFBS0_L2ISP	108
+#define TMPV770X_CLK_VIIFBS0_L1ISP	109
+#define TMPV770X_CLK_VIIFBS0_PROC	110
+#define TMPV770X_CLK_VIIFBS1		111
+#define TMPV770X_CLK_VIIFBS2		112
+#define TMPV770X_CLK_VIIFOP_MBUS	113
+#define TMPV770X_CLK_VIIFOP0_PROC	114
+#define TMPV770X_CLK_PIETHER_2P5M	115
+#define TMPV770X_CLK_PIETHER_25M	116
+#define TMPV770X_CLK_PIETHER_50M	117
+#define TMPV770X_CLK_PIETHER_125M	118
+#define TMPV770X_CLK_VOIF0_DPHYCFG	119
+#define TMPV770X_CLK_VOIF0_PROC		120
+#define TMPV770X_CLK_VOIF0_SBUS		121
+#define TMPV770X_CLK_VOIF0_DSIREF	122
+#define TMPV770X_CLK_VOIF0_PIXEL	123
+#define TMPV770X_CLK_PIREFCLK		124
+#define TMPV770X_CLK_SBUS		125
+#define TMPV770X_CLK_BUSLCK		126
+#define TMPV770X_NR_CLK			127
+
+/* Reset */
+#define TMPV770X_RESET_PIETHER_2P5M	0
+#define TMPV770X_RESET_PIETHER_25M	1
+#define TMPV770X_RESET_PIETHER_50M	2
+#define TMPV770X_RESET_PIETHER_125M	3
+#define TMPV770X_RESET_HOX		4
+#define TMPV770X_RESET_PCIE_MSTR	5
+#define TMPV770X_RESET_PCIE_AUX		6
+#define TMPV770X_RESET_PIINTC		7
+#define TMPV770X_RESET_PIETHER_BUS	8
+#define TMPV770X_RESET_PISPI0		9
+#define TMPV770X_RESET_PISPI1		10
+#define TMPV770X_RESET_PISPI2		11
+#define TMPV770X_RESET_PISPI3		12
+#define TMPV770X_RESET_PISPI4		13
+#define TMPV770X_RESET_PISPI5		14
+#define TMPV770X_RESET_PISPI6		15
+#define TMPV770X_RESET_PIUART0		16
+#define TMPV770X_RESET_PIUART1		17
+#define TMPV770X_RESET_PIUART2		18
+#define TMPV770X_RESET_PIUART3		19
+#define TMPV770X_RESET_PII2C0		20
+#define TMPV770X_RESET_PII2C1		21
+#define TMPV770X_RESET_PII2C2		22
+#define TMPV770X_RESET_PII2C3		23
+#define TMPV770X_RESET_PII2C4		24
+#define TMPV770X_RESET_PII2C5		25
+#define TMPV770X_RESET_PII2C6		26
+#define TMPV770X_RESET_PII2C7		27
+#define TMPV770X_RESET_PII2C8		28
+#define TMPV770X_RESET_PIPCMIF		29
+#define TMPV770X_RESET_PICKMON		30
+#define TMPV770X_RESET_SBUSCLK		31
+#define TMPV770X_NR_RESET		32
+
+#endif /*_DT_BINDINGS_CLOCK_TOSHIBA_TMPV770X_H_ */
diff --git a/include/dt-bindings/reset/toshiba,tmpv770x.h b/include/dt-bindings/reset/toshiba,tmpv770x.h
new file mode 100644
index 000000000000..c1007acb1941
--- /dev/null
+++ b/include/dt-bindings/reset/toshiba,tmpv770x.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_RESET_TOSHIBA_TMPV770X_H_
+#define _DT_BINDINGS_RESET_TOSHIBA_TMPV770X_H_
+
+/* Reset */
+#define TMPV770X_RESET_PIETHER_2P5M	0
+#define TMPV770X_RESET_PIETHER_25M	1
+#define TMPV770X_RESET_PIETHER_50M	2
+#define TMPV770X_RESET_PIETHER_125M	3
+#define TMPV770X_RESET_HOX		4
+#define TMPV770X_RESET_PCIE_MSTR	5
+#define TMPV770X_RESET_PCIE_AUX		6
+#define TMPV770X_RESET_PIINTC		7
+#define TMPV770X_RESET_PIETHER_BUS	8
+#define TMPV770X_RESET_PISPI0		9
+#define TMPV770X_RESET_PISPI1		10
+#define TMPV770X_RESET_PISPI2		11
+#define TMPV770X_RESET_PISPI3		12
+#define TMPV770X_RESET_PISPI4		13
+#define TMPV770X_RESET_PISPI5		14
+#define TMPV770X_RESET_PISPI6		15
+#define TMPV770X_RESET_PIUART0		16
+#define TMPV770X_RESET_PIUART1		17
+#define TMPV770X_RESET_PIUART2		18
+#define TMPV770X_RESET_PIUART3		19
+#define TMPV770X_RESET_PII2C0		20
+#define TMPV770X_RESET_PII2C1		21
+#define TMPV770X_RESET_PII2C2		22
+#define TMPV770X_RESET_PII2C3		23
+#define TMPV770X_RESET_PII2C4		24
+#define TMPV770X_RESET_PII2C5		25
+#define TMPV770X_RESET_PII2C6		26
+#define TMPV770X_RESET_PII2C7		27
+#define TMPV770X_RESET_PII2C8		28
+#define TMPV770X_RESET_PIPCMIF		29
+#define TMPV770X_RESET_PICKMON		30
+#define TMPV770X_RESET_SBUSCLK		31
+#define TMPV770X_NR_RESET		32
+
+#endif /*_DT_BINDINGS_RESET_TOSHIBA_TMPV770X_H_ */
-- 
2.32.0




From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug  4 02:22:43 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed,  4 Aug 2021 18:22:43 +0900
Subject: [PATCH v4 3/4] clk: visconti: Add support common clock driver and
 reset driver
In-Reply-To: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20210804092244.390376-4-nobuhiro1.iwamatsu@toshiba.co.jp>

Add support for common interface of the common clock and reset driver
for Toshiba Visconti5 and its SoC, TMPV7708. The PIPLLCT provides the PLL,
and the PISMU provides clock and reset functionality.
Each drivers are provided in this patch.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 drivers/clk/Makefile                 |   1 +
 drivers/clk/visconti/Makefile        |   5 +
 drivers/clk/visconti/clkc-tmpv770x.c | 232 +++++++++++++++++
 drivers/clk/visconti/clkc.c          | 220 ++++++++++++++++
 drivers/clk/visconti/clkc.h          |  75 ++++++
 drivers/clk/visconti/pll-tmpv770x.c  |  85 ++++++
 drivers/clk/visconti/pll.c           | 369 +++++++++++++++++++++++++++
 drivers/clk/visconti/pll.h           |  63 +++++
 drivers/clk/visconti/reset.c         | 111 ++++++++
 drivers/clk/visconti/reset.h         |  35 +++
 10 files changed, 1196 insertions(+)
 create mode 100644 drivers/clk/visconti/Makefile
 create mode 100644 drivers/clk/visconti/clkc-tmpv770x.c
 create mode 100644 drivers/clk/visconti/clkc.c
 create mode 100644 drivers/clk/visconti/clkc.h
 create mode 100644 drivers/clk/visconti/pll-tmpv770x.c
 create mode 100644 drivers/clk/visconti/pll.c
 create mode 100644 drivers/clk/visconti/pll.h
 create mode 100644 drivers/clk/visconti/reset.c
 create mode 100644 drivers/clk/visconti/reset.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 5f06879d7fe9..dbf70fdecfc8 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -116,6 +116,7 @@ obj-y					+= ti/
 obj-$(CONFIG_CLK_UNIPHIER)		+= uniphier/
 obj-$(CONFIG_ARCH_U8500)		+= ux500/
 obj-y					+= versatile/
+obj-$(CONFIG_ARCH_VISCONTI)		+= visconti/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_X86)			+= x86/
 endif
diff --git a/drivers/clk/visconti/Makefile b/drivers/clk/visconti/Makefile
new file mode 100644
index 000000000000..c1254fd52b31
--- /dev/null
+++ b/drivers/clk/visconti/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Makefile for Toshiba Visconti clock
+
+obj-y	+= clkc.o pll.o reset.o
+obj-y	+= pll-tmpv770x.o clkc-tmpv770x.o
diff --git a/drivers/clk/visconti/clkc-tmpv770x.c b/drivers/clk/visconti/clkc-tmpv770x.c
new file mode 100644
index 000000000000..6ee5c5179f7c
--- /dev/null
+++ b/drivers/clk/visconti/clkc-tmpv770x.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti clock controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+
+#include <dt-bindings/clock/toshiba,tmpv770x.h>
+#include <dt-bindings/reset/toshiba,tmpv770x.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include "clkc.h"
+#include "reset.h"
+
+static DEFINE_SPINLOCK(tmpv770x_clk_lock);
+static DEFINE_SPINLOCK(tmpv770x_rst_lock);
+
+static const struct visconti_fixed_clk fixed_clk_tables[] = {
+	/* PLL1 */
+	/* PICMPT0/1, PITSC, PIUWDT, PISWDT, PISBUS, PIPMU, PIGPMU, PITMU */
+	/* PIEMM, PIMISC, PIGCOMM, PIDCOMM, PIMBUS, PIGPIO, PIPGM */
+	{ TMPV770X_CLK_PIPLL1_DIV4, "pipll1_div4", "pipll1", 0, 1, 4, },
+	/* PISBUS */
+	{ TMPV770X_CLK_PIPLL1_DIV2, "pipll1_div2", "pipll1", 0, 1, 2, },
+	/* PICOBUS_CLK */
+	{ TMPV770X_CLK_PIPLL1_DIV1, "pipll1_div1", "pipll1", 0, 1, 1, },
+	/* PIDNNPLL */
+	/* CONN_CLK, PIMBUS, PICRC0/1 */
+	{ TMPV770X_CLK_PIDNNPLL_DIV1, "pidnnpll_div1", "pidnnpll", 0, 1, 1, },
+	{ TMPV770X_CLK_PIREFCLK, "pirefclk", "osc2-clk", 0, 1, 1, },
+	{ TMPV770X_CLK_WDTCLK, "wdtclk", "osc2-clk", 0, 1, 1, },
+};
+
+static const struct visconti_clk_gate_table pietherpll_clk_gate_tables[] = {
+	/* pietherpll */
+	{ TMPV770X_CLK_PIETHER_2P5M, "piether_2p5m", "pietherpll",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 4, 200,
+		TMPV770X_RESET_PIETHER_2P5M, },
+	{ TMPV770X_CLK_PIETHER_25M, "piether_25m", "pietherpll",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 5, 20,
+		TMPV770X_RESET_PIETHER_25M, },
+	{ TMPV770X_CLK_PIETHER_50M, "piether_50m", "pietherpll",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 6, 10,
+		TMPV770X_RESET_PIETHER_50M, },
+	{ TMPV770X_CLK_PIETHER_125M, "piether_125m", "pietherpll",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 7, 4,
+		TMPV770X_RESET_PIETHER_125M, },
+};
+
+static const struct visconti_clk_gate_table clk_gate_tables[] = {
+	{ TMPV770X_CLK_HOX, "hox", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x4C, 0x14C, 0, 1,
+		TMPV770X_RESET_HOX, },
+	{ TMPV770X_CLK_PCIE_MSTR, "pcie_mstr", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x38, 0x138, 0, 1,
+		TMPV770X_RESET_PCIE_MSTR, },
+	{ TMPV770X_CLK_PCIE_AUX, "pcie_aux", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x38, 0x138, 1, 24,
+		TMPV770X_RESET_PCIE_AUX, },
+	{ TMPV770X_CLK_PIINTC, "piintc", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x8, 0x108, 0, 2,
+		TMPV770X_RESET_PIINTC,},
+	{ TMPV770X_CLK_PIETHER_BUS, "piether_bus", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 0, 2,
+		TMPV770X_RESET_PIETHER_BUS, }, /* BUS_CLK */
+	{ TMPV770X_CLK_PISPI0, "pispi0", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 0, 2,
+		TMPV770X_RESET_PISPI0, },
+	{ TMPV770X_CLK_PISPI1, "pispi1", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 1, 2,
+		TMPV770X_RESET_PISPI1, },
+	{ TMPV770X_CLK_PISPI2, "pispi2", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 2, 2,
+		TMPV770X_RESET_PISPI2, },
+	{ TMPV770X_CLK_PISPI3, "pispi3", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 3, 2,
+		TMPV770X_RESET_PISPI3,},
+	{ TMPV770X_CLK_PISPI4, "pispi4", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 4, 2,
+		TMPV770X_RESET_PISPI4, },
+	{ TMPV770X_CLK_PISPI5, "pispi5", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 5, 2,
+		TMPV770X_RESET_PISPI5},
+	{ TMPV770X_CLK_PISPI6, "pispi6", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 6, 2,
+		TMPV770X_RESET_PISPI6,},
+	{ TMPV770X_CLK_PIUART0, "piuart0", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2C, 0x12C, 0, 4,
+		TMPV770X_RESET_PIUART0,},
+	{ TMPV770X_CLK_PIUART1, "piuart1", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2C, 0x12C, 1, 4,
+		TMPV770X_RESET_PIUART1, },
+	{ TMPV770X_CLK_PIUART2, "piuart2", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2C, 0x12C, 2, 4,
+		TMPV770X_RESET_PIUART2, },
+	{ TMPV770X_CLK_PIUART3, "piuart3", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2C, 0x12C, 3, 4,
+		TMPV770X_RESET_PIUART3, },
+	{ TMPV770X_CLK_PII2C0, "pii2c0", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 0, 4,
+		TMPV770X_RESET_PII2C0, },
+	{ TMPV770X_CLK_PII2C1, "pii2c1", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 1, 4,
+		TMPV770X_RESET_PII2C1, },
+	{ TMPV770X_CLK_PII2C2, "pii2c2", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 2, 4,
+		TMPV770X_RESET_PII2C2, },
+	{ TMPV770X_CLK_PII2C3, "pii2c3", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 3, 4,
+		TMPV770X_RESET_PII2C3,},
+	{ TMPV770X_CLK_PII2C4, "pii2c4", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 4, 4,
+		TMPV770X_RESET_PII2C4, },
+	{ TMPV770X_CLK_PII2C5, "pii2c5", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 5, 4,
+		TMPV770X_RESET_PII2C5, },
+	{ TMPV770X_CLK_PII2C6, "pii2c6", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 6, 4,
+		TMPV770X_RESET_PII2C6, },
+	{ TMPV770X_CLK_PII2C7, "pii2c7", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 7, 4,
+		TMPV770X_RESET_PII2C7, },
+	{ TMPV770X_CLK_PII2C8, "pii2c8", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 8, 4,
+		TMPV770X_RESET_PII2C8, },
+	/* PIPCMIF */
+	{ TMPV770X_CLK_PIPCMIF, "pipcmif", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x64, 0x164, 0, 4,
+		TMPV770X_RESET_PIPCMIF, },
+	/* PISYSTEM */
+	{ TMPV770X_CLK_WRCK, "wrck", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x68, 0x168, 9, 32,
+		-1, }, /* No reset */
+	{ TMPV770X_CLK_PICKMON, "pickmon", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x10, 0x110, 8, 4,
+		TMPV770X_RESET_PICKMON, },
+	{ TMPV770X_CLK_SBUSCLK, "sbusclk", "pipll1",
+		CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x14, 0x114, 0, 4,
+		TMPV770X_RESET_SBUSCLK, },
+};
+
+static const struct visconti_reset_data clk_reset_data[] = {
+	[TMPV770X_RESET_PIETHER_2P5M]	= { 0x434, 0x534, 4, },
+	[TMPV770X_RESET_PIETHER_25M]	= { 0x434, 0x534, 5, },
+	[TMPV770X_RESET_PIETHER_50M]	= { 0x434, 0x534, 6, },
+	[TMPV770X_RESET_PIETHER_125M]	= { 0x434, 0x534, 7, },
+	[TMPV770X_RESET_HOX]		= { 0x44C, 0x54C, 0, },
+	[TMPV770X_RESET_PCIE_MSTR]	= { 0x438, 0x538, 0, },
+	[TMPV770X_RESET_PCIE_AUX]	= { 0x438, 0x538, 1, },
+	[TMPV770X_RESET_PIINTC]		= { 0x408, 0x508, 0, },
+	[TMPV770X_RESET_PIETHER_BUS]	= { 0x434, 0x534, 0, },
+	[TMPV770X_RESET_PISPI0]		= { 0x428, 0x528, 0, },
+	[TMPV770X_RESET_PISPI1]		= { 0x428, 0x528, 1, },
+	[TMPV770X_RESET_PISPI2]		= { 0x428, 0x528, 2, },
+	[TMPV770X_RESET_PISPI3]		= { 0x428, 0x528, 3, },
+	[TMPV770X_RESET_PISPI4]		= { 0x428, 0x528, 4, },
+	[TMPV770X_RESET_PISPI5]		= { 0x428, 0x528, 5, },
+	[TMPV770X_RESET_PISPI6]		= { 0x428, 0x528, 6, },
+	[TMPV770X_RESET_PIUART0]	= { 0x42C, 0x52C, 0, },
+	[TMPV770X_RESET_PIUART1]	= { 0x42C, 0x52C, 1, },
+	[TMPV770X_RESET_PIUART2]	= { 0x42C, 0x52C, 2, },
+	[TMPV770X_RESET_PIUART3]	= { 0x42C, 0x52C, 3, },
+	[TMPV770X_RESET_PII2C0]		= { 0x430, 0x530, 0, },
+	[TMPV770X_RESET_PII2C1]		= { 0x430, 0x530, 1, },
+	[TMPV770X_RESET_PII2C2]		= { 0x430, 0x530, 2, },
+	[TMPV770X_RESET_PII2C3]		= { 0x430, 0x530, 3, },
+	[TMPV770X_RESET_PII2C4]		= { 0x430, 0x530, 4, },
+	[TMPV770X_RESET_PII2C5]		= { 0x430, 0x530, 5, },
+	[TMPV770X_RESET_PII2C6]		= { 0x430, 0x530, 6, },
+	[TMPV770X_RESET_PII2C7]		= { 0x430, 0x530, 7, },
+	[TMPV770X_RESET_PII2C8]		= { 0x430, 0x530, 8, },
+	[TMPV770X_RESET_PIPCMIF]	= { 0x464, 0x564, 0, },
+	[TMPV770X_RESET_PICKMON]	= { 0x410, 0x510, 8, },
+	[TMPV770X_RESET_SBUSCLK]	= { 0x414, 0x514, 0, },
+};
+
+static void __init tmpv770x_clkc_setup_clks(struct device_node *np)
+{
+	struct visconti_clk_provider *ctx;
+	struct regmap *regmap;
+	int ret, i;
+
+	regmap = device_node_to_regmap(np);
+	if (IS_ERR(regmap))
+		return;
+
+	ctx = visconti_init_clk(np, regmap, TMPV770X_NR_CLK);
+	if (IS_ERR(ctx))
+		return;
+
+	ret = visconti_register_reset_controller(np, regmap, clk_reset_data,
+						 TMPV770X_NR_RESET,
+						 &visconti_reset_ops,
+						 &tmpv770x_rst_lock);
+	if (ret) {
+		pr_err("Failed to register reset controller: %d\n", ret);
+		return;
+	}
+
+	for (i = 0; i < (ARRAY_SIZE(fixed_clk_tables)); i++)
+		ctx->clk_data.clks[fixed_clk_tables[i].id] =
+			clk_register_fixed_factor(NULL,
+						fixed_clk_tables[i].name,
+						fixed_clk_tables[i].parent,
+						fixed_clk_tables[i].flag,
+						fixed_clk_tables[i].mult,
+						fixed_clk_tables[i].div);
+
+	ret = visconti_clk_register_gates(ctx, clk_gate_tables,
+				    ARRAY_SIZE(clk_gate_tables), clk_reset_data,
+				    &tmpv770x_clk_lock);
+	if (ret) {
+		pr_err("Failed to register main clock gate: %d\n", ret);
+		return;
+	}
+
+	ret = visconti_clk_register_gates(ctx, pietherpll_clk_gate_tables,
+				    ARRAY_SIZE(pietherpll_clk_gate_tables),
+				    clk_reset_data, &tmpv770x_clk_lock);
+	if (ret) {
+		pr_err("Failed to register pietherpll clock gate: %d\n", ret);
+		return;
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &ctx->clk_data);
+}
+
+CLK_OF_DECLARE_DRIVER(tmpv770x_clkc, "toshiba,tmpv7708-pismu", tmpv770x_clkc_setup_clks);
diff --git a/drivers/clk/visconti/clkc.c b/drivers/clk/visconti/clkc.c
new file mode 100644
index 000000000000..32b6f6266154
--- /dev/null
+++ b/drivers/clk/visconti/clkc.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti clock controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "clkc.h"
+
+static inline struct visconti_clk_gate *to_visconti_clk_gate(struct clk_hw *hw)
+{
+	return container_of(hw, struct visconti_clk_gate, hw);
+}
+
+static int visconti_gate_clk_is_enabled(struct clk_hw *hw)
+{
+	struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
+	u32 clk = BIT(gate->ck_idx);
+	u32 val;
+
+	regmap_read(gate->regmap, gate->ckon_offset, &val);
+	return (val & clk) ? 1 : 0;
+}
+
+static void visconti_gate_clk_disable(struct clk_hw *hw)
+{
+	struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
+	u32 clk = BIT(gate->ck_idx);
+	u32 rst = BIT(gate->rs_idx);
+	unsigned long flags;
+
+	spin_lock_irqsave(gate->lock, flags);
+
+	if (visconti_gate_clk_is_enabled(hw)) {
+		spin_unlock_irqrestore(gate->lock, flags);
+		return;
+	}
+
+	/* Reset release */
+	regmap_update_bits(gate->regmap, gate->rson_offset, rst, 1);
+
+	udelay(100);
+
+	/* Disable clock */
+	regmap_update_bits(gate->regmap, gate->ckoff_offset, clk, 1);
+	spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int visconti_gate_clk_enable(struct clk_hw *hw)
+{
+	struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
+	u32 clk = BIT(gate->ck_idx);
+	u32 rst = BIT(gate->rs_idx);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(gate->lock, flags);
+
+	if (visconti_gate_clk_is_enabled(hw)) {
+		spin_unlock_irqrestore(gate->lock, flags);
+		return 0;
+	}
+
+	regmap_update_bits(gate->regmap, gate->ckon_offset, clk, 1);
+	/* Need read back */
+	regmap_read(gate->regmap, gate->ckon_offset, &val);
+
+	udelay(100);
+	/* Reset release */
+	regmap_update_bits(gate->regmap, gate->rsoff_offset, rst, 1);
+	/* Need read back */
+	regmap_read(gate->regmap, gate->ckoff_offset, &val);
+	spin_unlock_irqrestore(gate->lock, flags);
+
+	return 0;
+}
+
+static const struct clk_ops visconti_clk_gate_ops = {
+	.enable = visconti_gate_clk_enable,
+	.disable = visconti_gate_clk_disable,
+	.is_enabled = visconti_gate_clk_is_enabled,
+};
+
+static struct clk_hw *visconti_clk_register_gate(struct device *dev,
+						 const char *name,
+						 const char *parent_name,
+						 struct regmap *regmap,
+						 const struct visconti_clk_gate_table *clks,
+						 u32	rson_offset,
+						 u32	rsoff_offset,
+						 u8	rs_idx,
+						 spinlock_t *lock)
+{
+	struct visconti_clk_gate *gate;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &visconti_clk_gate_ops;
+	init.flags = clks->flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	gate->regmap = regmap;
+	gate->ckon_offset = clks->ckon_offset;
+	gate->ckoff_offset = clks->ckoff_offset;
+	gate->ck_idx = clks->ck_idx;
+	gate->rson_offset = rson_offset;
+	gate->rsoff_offset = rsoff_offset;
+	gate->rs_idx = rs_idx;
+	gate->lock = lock;
+	gate->hw.init = &init;
+
+	hw = &gate->hw;
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
+
+int visconti_clk_register_gates(struct visconti_clk_provider *data,
+				 const struct visconti_clk_gate_table *clks,
+				 int num_gate, const struct visconti_reset_data *reset,
+				 spinlock_t *lock)
+{
+	u32 rson_offset, rsoff_offset;
+	struct clk_hw *hw_clk;
+	u8 rs_idx;
+	int i;
+
+	for (i = 0; i < num_gate; i++) {
+		struct clk *clk;
+		char *div_name;
+
+		div_name = kasprintf(GFP_KERNEL, "%s_div", clks[i].name);
+		if (!div_name)
+			return -ENOMEM;
+
+		if (clks[i].rs_id >= 0) {
+			rson_offset = reset[clks[i].rs_id].rson_offset;
+			rsoff_offset = reset[clks[i].rs_id].rsoff_offset;
+			rs_idx = reset[clks[i].rs_id].rs_idx;
+		} else {
+			rson_offset = rsoff_offset = rs_idx = -1;
+		}
+
+		clk = clk_register_fixed_factor(NULL, div_name, clks[i].parent,
+						0, 1, clks[i].div);
+		if (IS_ERR(clk))
+			return PTR_ERR(clk);
+
+		hw_clk = visconti_clk_register_gate(NULL,
+						clks[i].name,
+						div_name,
+						data->regmap,
+						&clks[i],
+						rson_offset,
+						rsoff_offset,
+						rs_idx,
+						lock);
+		kfree(div_name);
+		if (IS_ERR(hw_clk)) {
+			pr_err("%s: failed to register clock %s\n",
+			       __func__, clks[i].name);
+			return PTR_ERR(hw_clk);
+		}
+
+		data->clk_data.clks[clks[i].id] = hw_clk->clk;
+	}
+
+	return 0;
+}
+
+struct visconti_clk_provider *visconti_init_clk(struct device_node *np,
+						struct regmap *regmap,
+						unsigned long nr_clks)
+{
+	struct visconti_clk_provider *ctx;
+	struct clk **clk_table;
+	int i;
+
+	ctx = kzalloc(sizeof(struct visconti_clk_provider), GFP_KERNEL);
+	if (!ctx)
+		return ERR_PTR(-ENOMEM);
+
+	clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
+	if (!clk_table)
+		goto err;
+
+	for (i = 0; i < nr_clks; ++i)
+		clk_table[i] = ERR_PTR(-ENOENT);
+	ctx->node = np;
+	ctx->regmap = regmap;
+	ctx->clk_data.clks = clk_table;
+	ctx->clk_data.clk_num = nr_clks;
+
+	return ctx;
+err:
+	kfree(ctx);
+	return ERR_PTR(-ENOMEM);
+}
diff --git a/drivers/clk/visconti/clkc.h b/drivers/clk/visconti/clkc.h
new file mode 100644
index 000000000000..4df8788d635a
--- /dev/null
+++ b/drivers/clk/visconti/clkc.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Toshiba Visconti clock controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+
+#ifndef _VISCONTI_CLKC_H_
+#define _VISCONTI_CLKC_H_
+
+#include <linux/mfd/syscon.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include "reset.h"
+
+struct visconti_clk_provider {
+	struct device_node	*node;
+	struct regmap		*regmap;
+	struct clk_onecell_data clk_data;
+};
+
+struct visconti_clk_gate_table {
+	unsigned int	id;
+	const char	*name;
+	const char	*parent;
+	u8		flags;
+	u32		ckon_offset;
+	u32		ckoff_offset;
+	u8		ck_idx;
+	unsigned int	div;
+	u8		rs_id;
+};
+
+struct visconti_fixed_clk {
+	unsigned int	id;
+	const char	*name;
+	const char	*parent;
+	unsigned long	flag;
+	unsigned int	mult;
+	unsigned int	div;
+};
+
+struct visconti_clk_gate {
+	struct clk_hw	hw;
+	struct regmap	*regmap;
+	u32		ckon_offset;
+	u32		ckoff_offset;
+	u8		ck_idx;
+	u8		flags;
+	u32		rson_offset;
+	u32		rsoff_offset;
+	u8		rs_idx;
+	spinlock_t	*lock;
+};
+
+struct visconti_clk_provider *visconti_init_clk(struct device_node *np,
+						struct regmap *regmap,
+						unsigned long nr_clks);
+int visconti_clk_register_gates(struct visconti_clk_provider *data,
+				 const struct visconti_clk_gate_table *clks,
+				 int num_gate,
+				 const struct visconti_reset_data *reset,
+				 spinlock_t *lock);
+#endif /* _VISCONTI_CLKC_H_ */
diff --git a/drivers/clk/visconti/pll-tmpv770x.c b/drivers/clk/visconti/pll-tmpv770x.c
new file mode 100644
index 000000000000..a0874cb6a67b
--- /dev/null
+++ b/drivers/clk/visconti/pll-tmpv770x.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti PLL controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+
+#include <dt-bindings/clock/toshiba,tmpv770x.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "pll.h"
+
+static DEFINE_SPINLOCK(tmpv770x_pll_lock);
+
+static const struct visconti_pll_rate_table pipll0_rates[] __initconst = {
+	VISCONTI_PLL_RATE(840000000, 0x1, 0x0, 0x1, 0x54, 0x000000, 0x2, 0x1),
+	VISCONTI_PLL_RATE(780000000, 0x1, 0x0, 0x1, 0x4E, 0x000000, 0x2, 0x1),
+	VISCONTI_PLL_RATE(600000000, 0x1, 0x0, 0x1, 0x3C, 0x000000, 0x2, 0x1),
+	{ /* sentinel */ },
+};
+
+static const struct visconti_pll_rate_table piddrcpll_rates[] __initconst = {
+	VISCONTI_PLL_RATE(780000000, 0x1, 0x0, 0x1, 0x4E, 0x000000, 0x2, 0x1),
+	VISCONTI_PLL_RATE(760000000, 0x1, 0x0, 0x1, 0x4C, 0x000000, 0x2, 0x1),
+	{ /* sentinel */ },
+};
+
+static const struct visconti_pll_rate_table pivoifpll_rates[] __initconst = {
+	VISCONTI_PLL_RATE(165000000, 0x1, 0x0, 0x1, 0x42, 0x000000, 0x4, 0x2),
+	VISCONTI_PLL_RATE(148500000, 0x1, 0x1, 0x1, 0x3B, 0x666666, 0x4, 0x2),
+	VISCONTI_PLL_RATE(96000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x2),
+	VISCONTI_PLL_RATE(74250000, 0x1, 0x1, 0x1, 0x3B, 0x666666, 0x4, 0x4),
+	VISCONTI_PLL_RATE(54000000, 0x1, 0x0, 0x1, 0x36, 0x000000, 0x5, 0x4),
+	VISCONTI_PLL_RATE(48000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x4),
+	VISCONTI_PLL_RATE(35750000, 0x1, 0x1, 0x1, 0x32, 0x0CCCCC, 0x7, 0x4),
+	{ /* sentinel */ },
+};
+
+static const struct visconti_pll_rate_table piimgerpll_rates[] __initconst = {
+	VISCONTI_PLL_RATE(165000000, 0x1, 0x0, 0x1, 0x42, 0x000000, 0x4, 0x2),
+	VISCONTI_PLL_RATE(96000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x2),
+	VISCONTI_PLL_RATE(54000000, 0x1, 0x0, 0x1, 0x36, 0x000000, 0x5, 0x4),
+	VISCONTI_PLL_RATE(48000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x4),
+	{ /* sentinel */ },
+};
+
+static const struct visconti_pll_info pll_info[] __initconst = {
+	{ TMPV770X_PLL_PIPLL0, "pipll0", "osc2-clk", 0, 0x0, pipll0_rates },
+	{ TMPV770X_PLL_PIDDRCPLL, "piddrcpll", "osc2-clk", 0, 0x500, piddrcpll_rates },
+	{ TMPV770X_PLL_PIVOIFPLL, "pivoifpll", "osc2-clk", 0, 0x600, pivoifpll_rates },
+	{ TMPV770X_PLL_PIIMGERPLL, "piimgerpll", "osc2-clk", 0, 0x700, piimgerpll_rates },
+};
+
+static void __init tmpv770x_setup_plls(struct device_node *np)
+{
+	struct visconti_pll_provider *ctx;
+	void __iomem *reg_base;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base)
+		return;
+
+	ctx = visconti_init_pll(np, reg_base, TMPV770X_NR_PLL);
+	if (IS_ERR(ctx)) {
+		iounmap(reg_base);
+		return;
+	}
+
+	ctx->clk_data.clks[TMPV770X_PLL_PIPLL1] =
+		clk_register_fixed_rate(NULL, "pipll1", NULL, 0, 600000000);
+	ctx->clk_data.clks[TMPV770X_PLL_PIDNNPLL] =
+		clk_register_fixed_rate(NULL, "pidnnpll", NULL, 0, 500000000);
+	ctx->clk_data.clks[TMPV770X_PLL_PIETHERPLL] =
+		clk_register_fixed_rate(NULL, "pietherpll", NULL, 0, 500000000);
+
+	visconti_register_plls(ctx, pll_info, ARRAY_SIZE(pll_info), &tmpv770x_pll_lock);
+}
+
+CLK_OF_DECLARE_DRIVER(tmpv770x_plls, "toshiba,tmpv7708-pipllct", tmpv770x_setup_plls);
diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c
new file mode 100644
index 000000000000..7baa9512fad9
--- /dev/null
+++ b/drivers/clk/visconti/pll.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti PLL driver
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include "pll.h"
+
+struct visconti_pll {
+	struct clk_hw	hw;
+	void __iomem	*pll_base;
+	spinlock_t	*lock;
+	int rate_count;
+	unsigned long flags;
+	const struct visconti_pll_rate_table *rate_table;
+	struct visconti_pll_provider *ctx;
+};
+
+#define PLL_CONF_REG		0x0000
+#define PLL_CTRL_REG		0x0004
+#define PLL_FRACMODE_REG	0x0010
+#define PLL_INTIN_REG		0x0014
+#define PLL_FRACIN_REG		0x0018
+#define PLL_REFDIV_REG		0x001C
+#define PLL_POSTDIV_REG		0x0020
+
+#define PLL_CONFIG_SEL		BIT(0)
+#define PLL_PLLEN		BIT(4)
+#define PLL_BYPASS		BIT(16)
+#define PLL_INTIN_MASK		GENMASK(11, 0)
+#define PLL_FRACIN_MASK		GENMASK(23, 0)
+#define PLL_REFDIV_MASK		GENMASK(5, 0)
+#define PLL_POSTDIV_MASK	GENMASK(2, 0)
+
+static inline struct visconti_pll *to_visconti_pll(struct clk_hw *hw)
+{
+	return container_of(hw, struct visconti_pll, hw);
+}
+
+static void visconti_pll_get_params(struct visconti_pll *pll,
+				    struct visconti_pll_rate_table *rate_table)
+{
+	u32 postdiv, val;
+
+	val = readl(pll->pll_base + PLL_FRACMODE_REG);
+	rate_table->dacen = (val >> 4) & 0x1;
+	rate_table->dsmen = val & 0x1;
+	rate_table->fracin = readl(pll->pll_base + PLL_FRACIN_REG) & PLL_FRACIN_MASK;
+	rate_table->intin = readl(pll->pll_base + PLL_INTIN_REG) & PLL_INTIN_MASK;
+	rate_table->refdiv = readl(pll->pll_base + PLL_REFDIV_REG) & PLL_REFDIV_MASK;
+
+	postdiv = readl(pll->pll_base + PLL_POSTDIV_REG);
+	rate_table->postdiv1 = postdiv & PLL_POSTDIV_MASK;
+	rate_table->postdiv2 = (postdiv >> 4) & PLL_POSTDIV_MASK;
+}
+
+static const struct visconti_pll_rate_table *visconti_get_pll_settings(struct visconti_pll *pll,
+								       unsigned long rate)
+{
+	const struct visconti_pll_rate_table *rate_table = pll->rate_table;
+	int i;
+
+	for (i = 0; i < pll->rate_count; i++) {
+		if (rate == rate_table[i].rate)
+			return &rate_table[i];
+	}
+
+	return NULL;
+}
+
+static unsigned long visconti_get_pll_rate_from_data(struct visconti_pll *pll,
+						     struct visconti_pll_rate_table *rate)
+{
+	const struct visconti_pll_rate_table *rate_table = pll->rate_table;
+	int i;
+
+	for (i = 0; i < pll->rate_count; i++) {
+		if (rate_table[i].dacen == rate->dacen &&
+			rate_table[i].dsmen == rate->dsmen &&
+			rate_table[i].fracin == rate->fracin &&
+			rate_table[i].intin == rate->intin &&
+			rate_table[i].refdiv == rate->refdiv &&
+			rate_table[i].postdiv1 == rate->postdiv1 &&
+			rate_table[i].postdiv2 == rate->postdiv2)
+			return rate_table[i].rate;
+	}
+
+	/* set default */
+	return rate_table[0].rate;
+}
+
+static long visconti_pll_round_rate(struct clk_hw *hw,
+			    unsigned long rate, unsigned long *prate)
+{
+	struct visconti_pll *pll = to_visconti_pll(hw);
+	const struct visconti_pll_rate_table *rate_table = pll->rate_table;
+	int i;
+
+	/* Assumming rate_table is in descending order */
+	for (i = 0; i < pll->rate_count; i++) {
+		if (rate >= rate_table[i].rate)
+			return rate_table[i].rate;
+	}
+
+	/* return minimum supported value */
+	return rate_table[i - 1].rate;
+}
+
+static unsigned long visconti_pll_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	struct visconti_pll *pll = to_visconti_pll(hw);
+	struct visconti_pll_rate_table rate_table;
+
+	memset(&rate_table, 0, sizeof(rate_table));
+	visconti_pll_get_params(pll, &rate_table);
+
+	return visconti_get_pll_rate_from_data(pll, &rate_table);
+}
+
+static int visconti_pll_set_params(struct visconti_pll *pll,
+				const struct visconti_pll_rate_table *rate_table)
+{
+	/* update pll values */
+	writel(((rate_table->dacen << 4) | rate_table->dsmen),
+			pll->pll_base + PLL_FRACMODE_REG);
+	writel(((rate_table->postdiv2 << 4) | rate_table->postdiv1),
+			pll->pll_base + PLL_POSTDIV_REG);
+	writel(rate_table->intin, pll->pll_base + PLL_INTIN_REG);
+	writel(rate_table->fracin, pll->pll_base + PLL_FRACIN_REG);
+	writel(rate_table->refdiv, pll->pll_base + PLL_REFDIV_REG);
+
+	return 0;
+}
+
+static int visconti_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct visconti_pll *pll = to_visconti_pll(hw);
+	const struct visconti_pll_rate_table *rate_table;
+
+	/* Get required rate settings from table */
+	rate_table = visconti_get_pll_settings(pll, rate);
+	if (!rate_table) {
+		pr_err("Invalid rate : %lu for pll clk %s\n",
+			parent_rate, __clk_get_name(hw->clk));
+		return -EINVAL;
+	}
+
+	return visconti_pll_set_params(pll, rate_table);
+}
+
+static int visconti_pll_is_enabled(struct clk_hw *hw)
+{
+	struct visconti_pll *pll = to_visconti_pll(hw);
+	unsigned long flags;
+	u32 reg;
+
+	spin_lock_irqsave(pll->lock, flags);
+	reg = readl(pll->pll_base + PLL_CTRL_REG);
+	spin_unlock_irqrestore(pll->lock, flags);
+
+	return (reg & PLL_PLLEN);
+}
+
+static int visconti_pll_enable(struct clk_hw *hw)
+{
+	struct visconti_pll *pll = to_visconti_pll(hw);
+	const struct visconti_pll_rate_table *rate_table = pll->rate_table;
+	unsigned long flags;
+	u32 reg;
+
+	if (visconti_pll_is_enabled(hw))
+		return 0;
+
+	spin_lock_irqsave(pll->lock, flags);
+
+	/* Change to access via register */
+	writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG);
+
+	/* Change to BYPASS mode */
+	reg = readl(pll->pll_base + PLL_CTRL_REG);
+	reg |= PLL_BYPASS;
+	writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+	/* Set DIV register .....*/
+	visconti_pll_set_params(pll, &rate_table[0]);
+
+	/* Disable  PLL register */
+	reg = readl(pll->pll_base + PLL_CTRL_REG);
+	reg &= ~PLL_PLLEN;
+	writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+	/* Wait 1us */
+	udelay(1);
+
+	/* Enable PLL register */
+	reg = readl(pll->pll_base + PLL_CTRL_REG);
+	reg |= PLL_PLLEN;
+	writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+	/* Wait 40us */
+	udelay(40);
+
+	/* Change to PLL mode */
+	reg = readl(pll->pll_base + PLL_CTRL_REG);
+	reg &= ~PLL_BYPASS;
+	writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+	spin_unlock_irqrestore(pll->lock, flags);
+
+	return 0;
+}
+
+static void visconti_pll_disable(struct clk_hw *hw)
+{
+	struct visconti_pll *pll = to_visconti_pll(hw);
+	unsigned long flags;
+	u32 reg;
+
+	if (!visconti_pll_is_enabled(hw))
+		return;
+
+	spin_lock_irqsave(pll->lock, flags);
+
+	/* Change to access via register */
+	writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG);
+
+	/* Change to BYPASS mode */
+	reg = readl(pll->pll_base + PLL_CTRL_REG);
+	reg |= PLL_BYPASS;
+	writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+	/* PLL disable */
+	reg = readl(pll->pll_base + PLL_CTRL_REG);
+	reg &= ~PLL_PLLEN;
+	writel(reg, pll->pll_base + PLL_CTRL_REG);
+
+	spin_unlock_irqrestore(pll->lock, flags);
+}
+
+static const struct clk_ops visconti_pll_ops = {
+	.enable = visconti_pll_enable,
+	.disable = visconti_pll_disable,
+	.is_enabled = visconti_pll_is_enabled,
+	.round_rate = visconti_pll_round_rate,
+	.recalc_rate = visconti_pll_recalc_rate,
+	.set_rate = visconti_pll_set_rate,
+};
+
+static struct clk *visconti_register_pll(struct visconti_pll_provider *ctx,
+					 const char *name,
+					 const char *parent_name,
+					 int offset,
+					 const struct visconti_pll_rate_table *rate_table,
+					 u8 clk_pll_flags,
+					 spinlock_t *lock)
+{
+	struct clk_init_data init;
+	struct visconti_pll *pll;
+	struct clk *pll_clk;
+	int len;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	/* Create the actual pll */
+	init.name = name;
+	init.flags = CLK_IGNORE_UNUSED;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	for (len = 0; rate_table[len].rate != 0; )
+		len++;
+	pll->rate_count = len;
+	pll->rate_table = kmemdup(rate_table,
+				  pll->rate_count * sizeof(struct visconti_pll_rate_table),
+				  GFP_KERNEL);
+	WARN(!pll->rate_table, "%s: could not allocate rate table for %s\n", __func__, name);
+
+	init.ops = &visconti_pll_ops;
+	pll->hw.init = &init;
+	pll->pll_base = ctx->reg_base + offset;
+	pll->flags = clk_pll_flags;
+	pll->lock = lock;
+	pll->ctx = ctx;
+
+	pll_clk = clk_register(NULL, &pll->hw);
+	if (IS_ERR(pll_clk)) {
+		pr_err("failed to register pll clock %s : %ld\n", name, PTR_ERR(pll_clk));
+		kfree(pll);
+	}
+
+	return pll_clk;
+}
+
+static void visconti_pll_add_lookup(struct visconti_pll_provider *ctx, struct clk *clk,
+				    unsigned int id)
+{
+	if (ctx->clk_data.clks && id)
+		ctx->clk_data.clks[id] = clk;
+}
+
+void __init visconti_register_plls(struct visconti_pll_provider *ctx,
+				   const struct visconti_pll_info *list,
+				   unsigned int nr_plls,
+				   spinlock_t *lock)
+{
+	int idx;
+
+	for (idx = 0; idx < nr_plls; idx++, list++) {
+		struct clk *clk;
+
+		clk = visconti_register_pll(ctx,
+					    list->name,
+					    list->parent,
+					    list->base_reg,
+					    list->rate_table,
+					    list->flags,
+					    lock);
+		if (IS_ERR(clk)) {
+			pr_err("failed to register clock %s\n", list->name);
+			continue;
+		}
+
+		visconti_pll_add_lookup(ctx, clk, list->id);
+	}
+}
+
+struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np,
+							void __iomem *base,
+							unsigned long nr_plls)
+{
+	struct visconti_pll_provider *ctx;
+	struct clk **clk_table;
+	int i;
+
+	ctx = kzalloc(sizeof(struct visconti_pll_provider), GFP_KERNEL);
+	if (!ctx)
+		return ERR_PTR(-ENOMEM);
+
+	clk_table = kcalloc(nr_plls, sizeof(struct clk *), GFP_KERNEL);
+	if (!clk_table)
+		goto err;
+
+	for (i = 0; i < nr_plls; ++i)
+		clk_table[i] = ERR_PTR(-ENOENT);
+
+	ctx->node = np;
+	ctx->reg_base = base;
+	ctx->clk_data.clks = clk_table;
+	ctx->clk_data.clk_num = nr_plls;
+
+	return ctx;
+
+err:
+	kfree(ctx);
+	return ERR_PTR(-ENOMEM);
+}
diff --git a/drivers/clk/visconti/pll.h b/drivers/clk/visconti/pll.h
new file mode 100644
index 000000000000..ce0ce1d8cd88
--- /dev/null
+++ b/drivers/clk/visconti/pll.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+
+#ifndef _VISCONTI_PLL_H_
+#define _VISCONTI_PLL_H_
+
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+
+struct visconti_pll_provider {
+	void __iomem *reg_base;
+	struct regmap *regmap;
+	struct clk_onecell_data clk_data;
+	struct device_node *node;
+};
+
+#define VISCONTI_PLL_RATE(_rate, _dacen, _dsmen, \
+	_refdiv, _intin, _fracin, _postdiv1, _postdiv2) \
+{				\
+	.rate = _rate,		\
+	.dacen = _dacen,	\
+	.dsmen = _dsmen,	\
+	.refdiv = _refdiv,	\
+	.intin = _intin,	\
+	.fracin = _fracin,	\
+	.postdiv1 = _postdiv1,	\
+	.postdiv2 = _postdiv2	\
+}
+
+struct visconti_pll_rate_table {
+	unsigned long rate;
+	unsigned int dacen;
+	unsigned int dsmen;
+	unsigned int refdiv;
+	unsigned long intin;
+	unsigned long fracin;
+	unsigned int postdiv1;
+	unsigned int postdiv2;
+};
+
+struct visconti_pll_info {
+	unsigned int id;
+	const char *name;
+	const char *parent;
+	u8 flags;
+	unsigned long base_reg;
+	const struct visconti_pll_rate_table *rate_table;
+};
+
+struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np,
+							void __iomem *base,
+							unsigned long nr_plls);
+void __init visconti_register_plls(struct visconti_pll_provider *ctx,
+				   const struct visconti_pll_info *list,
+				   unsigned int nr_plls, spinlock_t *lock);
+
+#endif /* _VISCONTI_PLL_H_ */
diff --git a/drivers/clk/visconti/reset.c b/drivers/clk/visconti/reset.c
new file mode 100644
index 000000000000..cfe8fde5f749
--- /dev/null
+++ b/drivers/clk/visconti/reset.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Toshiba Visconti ARM SoC reset controller
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include "reset.h"
+
+static inline struct visconti_reset *to_visconti_reset(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct visconti_reset, rcdev);
+}
+
+static int visconti_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	struct visconti_reset *reset = to_visconti_reset(rcdev);
+	const struct visconti_reset_data *data = &reset->resets[id];
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(reset->lock, flags);
+	ret = regmap_update_bits(reset->regmap, data->rson_offset, data->rs_idx, 1);
+	spin_unlock_irqrestore(reset->lock, flags);
+
+	return ret;
+}
+
+static int visconti_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	struct visconti_reset *reset = to_visconti_reset(rcdev);
+	const struct visconti_reset_data *data = &reset->resets[id];
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(reset->lock, flags);
+	ret = regmap_update_bits(reset->regmap, data->rsoff_offset, data->rs_idx, 1);
+	spin_unlock_irqrestore(reset->lock, flags);
+
+	return ret;
+}
+
+static int visconti_reset_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	visconti_reset_assert(rcdev, id);
+	udelay(1);
+	visconti_reset_deassert(rcdev, id);
+
+	return 0;
+}
+
+static int visconti_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	struct visconti_reset *reset = to_visconti_reset(rcdev);
+	const struct visconti_reset_data *data = &reset->resets[id];
+	unsigned long flags;
+	u32 reg;
+	int ret;
+
+	spin_lock_irqsave(reset->lock, flags);
+	ret = regmap_read(reset->regmap, data->rson_offset, &reg);
+	spin_unlock_irqrestore(reset->lock, flags);
+	if (ret)
+		return ret;
+
+	return !(reg & data->rs_idx);
+}
+
+const struct reset_control_ops visconti_reset_ops = {
+	.assert		= visconti_reset_assert,
+	.deassert	= visconti_reset_deassert,
+	.reset		= visconti_reset_reset,
+	.status		= visconti_reset_status,
+};
+
+int visconti_register_reset_controller(struct device_node *np, struct regmap *regmap,
+				       const struct visconti_reset_data *resets,
+				       unsigned int num_resets,
+				       const struct reset_control_ops *reset_ops,
+				       spinlock_t *lock)
+{
+	struct visconti_reset *reset;
+	int ret;
+
+	reset = kzalloc(sizeof(*reset), GFP_KERNEL);
+	if (!reset)
+		return -ENOMEM;
+
+	reset->regmap = regmap;
+	reset->resets = resets;
+	reset->rcdev.ops = reset_ops;
+	reset->rcdev.nr_resets = num_resets;
+	reset->rcdev.of_node = np;
+	reset->lock = lock;
+
+	ret = reset_controller_register(&reset->rcdev);
+	if (ret) {
+		pr_err("could not register reset controller: %d\n", ret);
+		kfree(reset);
+		return ret;
+	}
+
+	return 0;
+}
diff --git a/drivers/clk/visconti/reset.h b/drivers/clk/visconti/reset.h
new file mode 100644
index 000000000000..521305caa6fa
--- /dev/null
+++ b/drivers/clk/visconti/reset.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Toshiba ARM SoC reset controller driver
+ *
+ * Copyright (c) 2021 TOSHIBA CORPORATION
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+
+#ifndef _VISCONTI_RESET_H_
+#define _VISCONTI_RESET_H_
+
+#include <linux/reset-controller.h>
+
+struct visconti_reset_data {
+	u32	rson_offset;
+	u32	rsoff_offset;
+	u8	rs_idx;
+};
+
+struct visconti_reset {
+	struct reset_controller_dev rcdev;
+	struct regmap *regmap;
+	const struct visconti_reset_data *resets;
+	spinlock_t *lock;
+};
+
+extern const struct reset_control_ops visconti_reset_ops;
+
+int visconti_register_reset_controller(struct device_node *np, struct regmap *regmap,
+				       const struct visconti_reset_data *resets,
+				       unsigned int num_resets,
+				       const struct reset_control_ops *reset_ops,
+				       spinlock_t *lock);
+#endif /* _VISCONTI_RESET_H_ */
-- 
2.32.0




From drjones at redhat.com  Wed Aug  4 02:23:11 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 4 Aug 2021 11:23:11 +0200
Subject: [PATCH v6 11/21] KVM: arm64: Refactor update_vtimer_cntvoff()
In-Reply-To: <20210804085819.846610-12-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-12-oupton@google.com>
Message-ID: <20210804092311.yhruuke6buiblrel@gator.home>

On Wed, Aug 04, 2021 at 08:58:09AM +0000, Oliver Upton wrote:
> Make the implementation of update_vtimer_cntvoff() generic w.r.t. guest
> timer context and spin off into a new helper method for later use.
> Require callers of this new helper method to grab the kvm lock
> beforehand.
> 
> No functional change intended.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  arch/arm64/kvm/arch_timer.c | 20 +++++++++++++++-----
>  1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 3df67c127489..c0101db75ad4 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -747,22 +747,32 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
>  	return 0;
>  }
>  
> -/* Make the updates of cntvoff for all vtimer contexts atomic */
> -static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
> +/* Make offset updates for all timer contexts atomic */
> +static void update_timer_offset(struct kvm_vcpu *vcpu,
> +				enum kvm_arch_timers timer, u64 offset)
>  {
>  	int i;
>  	struct kvm *kvm = vcpu->kvm;
>  	struct kvm_vcpu *tmp;
>  
> -	mutex_lock(&kvm->lock);
> +	lockdep_assert_held(&kvm->lock);
> +
>  	kvm_for_each_vcpu(i, tmp, kvm)
> -		timer_set_offset(vcpu_vtimer(tmp), cntvoff);
> +		timer_set_offset(vcpu_get_timer(tmp, timer), offset);
>  
>  	/*
>  	 * When called from the vcpu create path, the CPU being created is not
>  	 * included in the loop above, so we just set it here as well.
>  	 */
> -	timer_set_offset(vcpu_vtimer(vcpu), cntvoff);
> +	timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
> +}
> +
> +static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +
> +	mutex_lock(&kvm->lock);
> +	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff);
>  	mutex_unlock(&kvm->lock);
>  }
>  
> -- 
> 2.32.0.605.g8dce9f2422-goog
>

Reviewed-by: Andrew Jones <drjones at redhat.com>



From shawnguo at kernel.org  Wed Aug  4 02:24:42 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 4 Aug 2021 17:24:42 +0800
Subject: [PATCH 1/5] arm64: dts: imx8mm-venice-gw700x: fix mp5416 pmic
 config
In-Reply-To: <20210727161101.32267-1-tharvey@gateworks.com>
References: <20210727161101.32267-1-tharvey@gateworks.com>
Message-ID: <20210804092441.GD30984@dragon>

On Tue, Jul 27, 2021 at 09:10:57AM -0700, Tim Harvey wrote:
> Fix various MP5416 PMIC configurations:
>  - Update regulator names per dt-bindings
>  - ensure values fit among valid register values
>  - add required regulator-max-microamp property
>  - add regulator-always-on prop
> 
> Signed-off-by: Tim Harvey <tharvey at gateworks.com>

Applied all, thanks!


From liuqi115 at huawei.com  Tue Aug  3 23:02:09 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Wed, 4 Aug 2021 14:02:09 +0800
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
Message-ID: <20210804060209.95817-1-liuqi115@huawei.com>

This patch introduce optprobe for ARM64. In optprobe, probed
instruction is replaced by a branch instruction to detour
buffer. Detour buffer contains trampoline code and a call to
optimized_callback(). optimized_callback() calls opt_pre_handler()
to execute kprobe handler.

Limitations:
- We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
guarantee the offset between probe point and kprobe pre_handler
is not larger than 128MiB.

Performance of optprobe on Hip08 platform is test using kprobe
example module[1] to analyze the latency of a kernel function,
and here is the result:

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c

kprobe before optimized:
[280709.846380] do_empty returned 0 and took 1530 ns to execute
[280709.852057] do_empty returned 0 and took 550 ns to execute
[280709.857631] do_empty returned 0 and took 440 ns to execute
[280709.863215] do_empty returned 0 and took 380 ns to execute
[280709.868787] do_empty returned 0 and took 360 ns to execute
[280709.874362] do_empty returned 0 and took 340 ns to execute
[280709.879936] do_empty returned 0 and took 320 ns to execute
[280709.885505] do_empty returned 0 and took 300 ns to execute
[280709.891075] do_empty returned 0 and took 280 ns to execute
[280709.896646] do_empty returned 0 and took 290 ns to execute
[280709.902220] do_empty returned 0 and took 290 ns to execute
[280709.907807] do_empty returned 0 and took 290 ns to execute

optprobe:
[ 2965.964572] do_empty returned 0 and took 90 ns to execute
[ 2965.969952] do_empty returned 0 and took 80 ns to execute
[ 2965.975332] do_empty returned 0 and took 70 ns to execute
[ 2965.980714] do_empty returned 0 and took 60 ns to execute
[ 2965.986128] do_empty returned 0 and took 80 ns to execute
[ 2965.991507] do_empty returned 0 and took 70 ns to execute
[ 2965.996884] do_empty returned 0 and took 70 ns to execute
[ 2966.002262] do_empty returned 0 and took 80 ns to execute
[ 2966.007642] do_empty returned 0 and took 70 ns to execute
[ 2966.013020] do_empty returned 0 and took 70 ns to execute
[ 2966.018400] do_empty returned 0 and took 70 ns to execute
[ 2966.023779] do_empty returned 0 and took 70 ns to execute
[ 2966.029158] do_empty returned 0 and took 70 ns to execute

Signed-off-by: Qi Liu <liuqi115 at huawei.com>

---

Changes since V1:
- Address the comments from Masami, checks for all branch instructions, and
use aarch64_insn_patch_text_nosync() instead of aarch64_insn_patch_text()
in each probe.
- Link: https://lore.kernel.org/lkml/20210719122417.10355-1-liuqi115 at huawei.com/

 arch/arm64/Kconfig                            |   1 +
 arch/arm64/include/asm/kprobes.h              |  23 ++
 arch/arm64/kernel/probes/Makefile             |   2 +
 arch/arm64/kernel/probes/kprobes.c            |  19 +-
 arch/arm64/kernel/probes/opt-arm64.c          | 225 ++++++++++++++++++
 .../arm64/kernel/probes/optprobe_trampoline.S |  80 +++++++
 6 files changed, 347 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/kernel/probes/opt-arm64.c
 create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5b13a932561..3532f0237c71 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -200,6 +200,7 @@ config ARM64
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_KPROBES
+	select HAVE_OPTPROBES if !RANDOMIZE_MODULE_REGION_FULL
 	select HAVE_KRETPROBES
 	select HAVE_GENERIC_VDSO
 	select IOMMU_DMA if IOMMU_SUPPORT
diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
index 5d38ff4a4806..9e1c492a0c3d 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -39,6 +39,29 @@ void arch_remove_kprobe(struct kprobe *);
 int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
 int kprobe_exceptions_notify(struct notifier_block *self,
 			     unsigned long val, void *data);
+
+#define RELATIVEJUMP_SIZE (4)
+#define MAX_COPIED_INSN	DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
+struct arch_optimized_insn {
+	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
+	/* detour code buffer */
+	kprobe_opcode_t *insn;
+};
+
+/* optinsn template addresses */
+extern __visible kprobe_opcode_t optprobe_template_entry[];
+extern __visible kprobe_opcode_t optprobe_template_val[];
+extern __visible kprobe_opcode_t optprobe_template_call[];
+extern __visible kprobe_opcode_t optprobe_template_end[];
+extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
+extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
+extern __visible kprobe_opcode_t optprobe_template_restore_end[];
+
+#define MAX_OPTIMIZED_LENGTH	4
+#define MAX_OPTINSN_SIZE				\
+	((unsigned long)optprobe_template_end -	\
+	 (unsigned long)optprobe_template_entry)
+
 void kretprobe_trampoline(void);
 void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
 
diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
index 8e4be92e25b1..52cf5d4ffe8a 100644
--- a/arch/arm64/kernel/probes/Makefile
+++ b/arch/arm64/kernel/probes/Makefile
@@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o decode-insn.o	\
 				   simulate-insn.o
 obj-$(CONFIG_UPROBES)		+= uprobes.o decode-insn.o	\
 				   simulate-insn.o
+obj-$(CONFIG_OPTPROBES)		+= opt-arm64.o			\
+				   optprobe_trampoline.o
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index 6dbcc89f6662..83755ad62abe 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -11,6 +11,7 @@
 #include <linux/kasan.h>
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
+#include <linux/moduleloader.h>
 #include <linux/sched/debug.h>
 #include <linux/set_memory.h>
 #include <linux/slab.h>
@@ -113,9 +114,21 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 
 void *alloc_insn_page(void)
 {
-	return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
-			GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
-			NUMA_NO_NODE, __builtin_return_address(0));
+	void *page;
+
+	page = module_alloc(PAGE_SIZE);
+	if (!page)
+		return NULL;
+
+	set_vm_flush_reset_perms(page);
+	/*
+	 * First make the page read-only, and only then make it executable to
+	 * prevent it from being W+X in between.
+	 */
+	set_memory_ro((unsigned long)page, 1);
+	set_memory_x((unsigned long)page, 1);
+
+	return page;
 }
 
 /* arm kprobe: install breakpoint in text */
diff --git a/arch/arm64/kernel/probes/opt-arm64.c b/arch/arm64/kernel/probes/opt-arm64.c
new file mode 100644
index 000000000000..a0302e3ad62d
--- /dev/null
+++ b/arch/arm64/kernel/probes/opt-arm64.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Code for Kernel probes Jump optimization.
+ *
+ * Copyright (C) 2021 Hisilicon Limited
+ */
+
+#include <linux/jump_label.h>
+#include <linux/kprobes.h>
+
+#include <asm/cacheflush.h>
+#include <asm/insn.h>
+#include <asm/kprobes.h>
+
+
+#define TMPL_VAL_IDX \
+	(optprobe_template_val - optprobe_template_entry)
+#define TMPL_CALL_BACK \
+	(optprobe_template_call - optprobe_template_entry)
+#define TMPL_END_IDX \
+	(optprobe_template_end - optprobe_template_entry)
+#define TMPL_RESTORE_ORIGN_INSN \
+	(optprobe_template_restore_orig_insn - optprobe_template_entry)
+#define TMPL_RESTORE_END \
+	(optprobe_template_restore_end - optprobe_template_entry)
+
+int arch_check_optimized_kprobe(struct optimized_kprobe *op)
+{
+	return 0;
+}
+
+int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
+{
+	return optinsn->insn != NULL;
+}
+
+int arch_within_optimized_kprobe(struct optimized_kprobe *op,
+				unsigned long addr)
+{
+	return ((unsigned long)op->kp.addr <= addr &&
+		(unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
+}
+
+static void
+optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
+{
+	/* This is possible if op is under delayed unoptimizing */
+	if (kprobe_disabled(&op->kp))
+		return;
+
+	preempt_disable();
+
+	if (kprobe_running()) {
+		kprobes_inc_nmissed_count(&op->kp);
+	} else {
+		__this_cpu_write(current_kprobe, &op->kp);
+		regs->pc = (unsigned long)op->kp.addr;
+		get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+		opt_pre_handler(&op->kp, regs);
+		__this_cpu_write(current_kprobe, NULL);
+	}
+
+	preempt_enable_no_resched();
+}
+NOKPROBE_SYMBOL(optimized_callback)
+
+static bool is_offset_in_range(unsigned long start, unsigned long end)
+{
+	long offset = end - start;
+
+	/*
+	 * Verify if the address gap is in 128MiB range, because this uses
+	 * a relative jump.
+	 *
+	 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
+	 * According to ARM manual, branch instruction is:
+	 *
+	 *   31  30                  25              0
+	 *  +----+---+---+---+---+---+---------------+
+	 *  |cond| 0 | 0 | 1 | 0 | 1 |     imm26     |
+	 *  +----+---+---+---+---+---+---------------+
+	 *
+	 * imm26 is a signed 26 bits integer. The real branch offset is computed
+	 * by: imm64 = SignExtend(imm26:'00', 64);
+	 *
+	 * So the maximum forward branch should be:
+	 *   (0x01ffffff << 2) = 1720x07fffffc =  0x07fffffc
+	 * The maximum backward branch should be:
+	 *   (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
+	 *
+	 * We can simply check (rel & 0xf8000003):
+	 *  if rel is positive, (rel & 0xf8000003) should be 0
+	 *  if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
+	 *  the last '3' is used for alignment checking.
+	 */
+	return (offset >= -0x08000000 && offset <= 0x07fffffc && !(offset & 0x3));
+}
+
+int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
+{
+	kprobe_opcode_t *code;
+	u32 insn;
+	int ret, i;
+	void *addrs[TMPL_END_IDX];
+	void *addr;
+
+	code = get_optinsn_slot();
+	if (!code)
+		return -ENOMEM;
+
+	if (!is_offset_in_range((unsigned long)code,
+				(unsigned long)orig->addr + 8))
+		goto error;
+
+	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
+				(unsigned long)optimized_callback))
+		goto error;
+
+	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
+				(unsigned long)op->kp.addr + 4))
+		goto error;
+
+	/* Setup template */
+	for (i = 0; i < TMPL_END_IDX; i++)
+		addrs[i] = code + i;
+
+	ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
+				      TMPL_END_IDX);
+	if (ret < 0)
+		goto error;
+
+	/* Set probe information */
+	addr = code + TMPL_VAL_IDX;
+	insn =  (unsigned long long)op & 0xffffffff;
+	aarch64_insn_patch_text(&addr, &insn, 1);
+
+	addr = addr + 4;
+	insn = ((unsigned long long)op & GENMASK_ULL(63, 32)) >> 32;
+	aarch64_insn_patch_text(&addr, &insn, 1);
+
+	addr = code + TMPL_CALL_BACK;
+	insn =  aarch64_insn_gen_branch_imm((unsigned long)addr,
+				(unsigned long)optimized_callback,
+				AARCH64_INSN_BRANCH_LINK);
+	aarch64_insn_patch_text(&addr, &insn, 1);
+
+	/* The original probed instruction */
+	addr = code + TMPL_RESTORE_ORIGN_INSN;
+	insn =  orig->opcode;
+	aarch64_insn_patch_text(&addr, &insn, 1);
+
+	/* Jump back to next instruction */
+	addr = code + TMPL_RESTORE_END;
+	insn = aarch64_insn_gen_branch_imm(
+				(unsigned long)(&code[TMPL_RESTORE_END]),
+				(unsigned long)(op->kp.addr) + 4,
+				AARCH64_INSN_BRANCH_NOLINK);
+	aarch64_insn_patch_text(&addr, &insn, 1);
+
+	flush_icache_range((unsigned long)code,
+			   (unsigned long)(&code[TMPL_END_IDX]));
+	/* Set op->optinsn.insn means prepared. */
+	op->optinsn.insn = code;
+
+	return 0;
+
+error:
+	free_optinsn_slot(code, 0);
+	return -ERANGE;
+}
+
+void arch_optimize_kprobes(struct list_head *oplist)
+{
+	struct optimized_kprobe *op, *tmp;
+
+	list_for_each_entry_safe(op, tmp, oplist, list) {
+		u32 insn;
+
+		WARN_ON(kprobe_disabled(&op->kp));
+
+		/*
+		 * Backup instructions which will be replaced
+		 * by jump address
+		 */
+		memcpy(op->optinsn.copied_insn, op->kp.addr,
+			RELATIVEJUMP_SIZE);
+		insn = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
+				(unsigned long)op->optinsn.insn,
+				AARCH64_INSN_BRANCH_NOLINK);
+
+		WARN_ON(insn == 0);
+
+		aarch64_insn_patch_text_nosync((void*)op->kp.addr, insn);
+
+		list_del_init(&op->list);
+	}
+}
+
+void arch_unoptimize_kprobe(struct optimized_kprobe *op)
+{
+	arch_arm_kprobe(&op->kp);
+}
+
+/*
+ * Recover original instructions and breakpoints from relative jumps.
+ * Caller must call with locking kprobe_mutex.
+ */
+void arch_unoptimize_kprobes(struct list_head *oplist,
+			    struct list_head *done_list)
+{
+	struct optimized_kprobe *op, *tmp;
+
+	list_for_each_entry_safe(op, tmp, oplist, list) {
+		arch_unoptimize_kprobe(op);
+		list_move(&op->list, done_list);
+	}
+}
+
+void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
+{
+	if (op->optinsn.insn) {
+		free_optinsn_slot(op->optinsn.insn, 1);
+		op->optinsn.insn = NULL;
+	}
+}
diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
new file mode 100644
index 000000000000..13729cb279b8
--- /dev/null
+++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * trampoline entry and return code for optprobes.
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+
+	.global optprobe_template_entry
+optprobe_template_entry:
+	sub sp, sp, #PT_REGS_SIZE
+	stp x0, x1, [sp, #S_X0]
+	stp x2, x3, [sp, #S_X2]
+	stp x4, x5, [sp, #S_X4]
+	stp x6, x7, [sp, #S_X6]
+	stp x8, x9, [sp, #S_X8]
+	stp x10, x11, [sp, #S_X10]
+	stp x12, x13, [sp, #S_X12]
+	stp x14, x15, [sp, #S_X14]
+	stp x16, x17, [sp, #S_X16]
+	stp x18, x19, [sp, #S_X18]
+	stp x20, x21, [sp, #S_X20]
+	stp x22, x23, [sp, #S_X22]
+	stp x24, x25, [sp, #S_X24]
+	stp x26, x27, [sp, #S_X26]
+	stp x28, x29, [sp, #S_X28]
+	add x0, sp, #PT_REGS_SIZE
+	stp lr, x0, [sp, #S_LR]
+	/*
+	 * Construct a useful saved PSTATE
+	 */
+	mrs x0, nzcv
+	mrs x1, daif
+	orr x0, x0, x1
+	mrs x1, CurrentEL
+	orr x0, x0, x1
+	mrs x1, SPSel
+	orr x0, x0, x1
+	stp xzr, x0, [sp, #S_PC]
+	/* Get parameters to optimized_callback() */
+	ldr	x0, 1f
+	mov	x1, sp
+	/* Branch to optimized_callback() */
+	.global optprobe_template_call
+optprobe_template_call:
+	nop
+        /* Restore registers */
+	ldr x0, [sp, #S_PSTATE]
+	and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
+	msr nzcv, x0
+	ldp x0, x1, [sp, #S_X0]
+	ldp x2, x3, [sp, #S_X2]
+	ldp x4, x5, [sp, #S_X4]
+	ldp x6, x7, [sp, #S_X6]
+	ldp x8, x9, [sp, #S_X8]
+	ldp x10, x11, [sp, #S_X10]
+	ldp x12, x13, [sp, #S_X12]
+	ldp x14, x15, [sp, #S_X14]
+	ldp x16, x17, [sp, #S_X16]
+	ldp x18, x19, [sp, #S_X18]
+	ldp x20, x21, [sp, #S_X20]
+	ldp x22, x23, [sp, #S_X22]
+	ldp x24, x25, [sp, #S_X24]
+	ldp x26, x27, [sp, #S_X26]
+	ldp x28, x29, [sp, #S_X28]
+	ldr lr, [sp, #S_LR]
+        add sp, sp, #PT_REGS_SIZE
+	.global optprobe_template_restore_orig_insn
+optprobe_template_restore_orig_insn:
+	nop
+	.global optprobe_template_restore_end
+optprobe_template_restore_end:
+	nop
+	.global optprobe_template_end
+optprobe_template_end:
+	.global optprobe_template_val
+optprobe_template_val:
+	1:	.long 0
+		.long 0
-- 
2.17.1



From shawnguo at kernel.org  Wed Aug  4 02:31:26 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 4 Aug 2021 17:31:26 +0800
Subject: [PATCH v10 0/3] media: imx: add support for imx8mq MIPI RX
In-Reply-To: <YQFcfbrTmGw4kZvQ@pendragon.ideasonboard.com>
References: <20210728091245.231043-1-martin.kepplinger@puri.sm>
 <YQFcfbrTmGw4kZvQ@pendragon.ideasonboard.com>
Message-ID: <20210804093125.GE30984@dragon>

On Wed, Jul 28, 2021 at 04:32:45PM +0300, Laurent Pinchart wrote:
> Hi Martin,
> 
> On Wed, Jul 28, 2021 at 11:12:42AM +0200, Martin Kepplinger wrote:
> > hi,
> > 
> > This patch series adds a driver for the i.MX8MQ CSI MIPI receiver / controller.
> > 
> > It includes the driver, the dt-bindings and the DT addition to the SoC dtsi.
> > I test it using libcamera. Thanks to Laurent who helped a lot. I'm happy for
> > any feedback,
> 
> Thank you for the series. I've submitted a pull request that contains
> patches 1/3 and 2/3.
> 
> Shawn, Sascha, how would you like to handle 3/3 ?

I picked up the 3/3 in v9, which I think is identical to this version.
Otherwise, please let me know.

Shawn


From cgel.zte at gmail.com  Wed Aug  4 02:39:07 2021
From: cgel.zte at gmail.com (cgel.zte at gmail.com)
Date: Wed,  4 Aug 2021 02:39:07 -0700
Subject: [PATCH linux-next] 'linux/tty.h' included in 'hackkit.c' is
 duplicated. It is also included in the 21th line.
Message-ID: <20210804093907.618719-1-yong.yiran@zte.com.cn>

From: yong yiran <yong.yiran at zte.com.cn>

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: yong yiran <yong.yiran at zte.com.cn>
---
 arch/arm/mach-sa1100/hackkit.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 3085f1c2e586..3fe34ee7c0ab 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -18,7 +18,6 @@
 #include <linux/serial_core.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <linux/tty.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
-- 
2.25.1



From patchwork-bot+netdevbpf at kernel.org  Wed Aug  4 02:40:07 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 04 Aug 2021 09:40:07 +0000
Subject: [PATCH net-next v2 0/4] mt7530 software fallback bridging fix
In-Reply-To: <20210803160405.3025624-1-dqfext@gmail.com>
References: <20210803160405.3025624-1-dqfext@gmail.com>
Message-ID: <162807000771.29242.1625831528843804010.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (refs/heads/master):

On Wed,  4 Aug 2021 00:04:00 +0800 you wrote:
> DSA core has gained software fallback support since commit 2f5dc00f7a3e
> ("net: bridge: switchdev: let drivers inform which bridge ports are
> offloaded"), but it does not work properly on mt7530. This patch series
> fixes the issues.
> 
> DENG Qingfang (4):
>   net: dsa: mt7530: enable assisted learning on CPU port
>   net: dsa: mt7530: use independent VLAN learning on VLAN-unaware
>     bridges
>   net: dsa: mt7530: set STP state on filter ID 1
>   net: dsa: mt7530: always install FDB entries with IVL and FID 1
> 
> [...]

Here is the summary with links:
  - [net-next,v2,1/4] net: dsa: mt7530: enable assisted learning on CPU port
    https://git.kernel.org/netdev/net-next/c/0b69c54c74bc
  - [net-next,v2,2/4] net: dsa: mt7530: use independent VLAN learning on VLAN-unaware bridges
    https://git.kernel.org/netdev/net-next/c/6087175b7991
  - [net-next,v2,3/4] net: dsa: mt7530: set STP state on filter ID 1
    https://git.kernel.org/netdev/net-next/c/a9e3f62dff3c
  - [net-next,v2,4/4] net: dsa: mt7530: always install FDB entries with IVL and FID 1
    https://git.kernel.org/netdev/net-next/c/73c447cacbbd

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From martin.kepplinger at puri.sm  Wed Aug  4 02:56:14 2021
From: martin.kepplinger at puri.sm (Martin Kepplinger)
Date: Wed, 04 Aug 2021 11:56:14 +0200
Subject: [PATCH v10 0/3] media: imx: add support for imx8mq MIPI RX
In-Reply-To: <20210804093125.GE30984@dragon>
References: <20210728091245.231043-1-martin.kepplinger@puri.sm>
 <YQFcfbrTmGw4kZvQ@pendragon.ideasonboard.com>
 <20210804093125.GE30984@dragon>
Message-ID: <bf02db8325bb799a861ff7a924ab4d7d5b1df0cc.camel@puri.sm>

Am Mittwoch, dem 04.08.2021 um 17:31 +0800 schrieb Shawn Guo:
> On Wed, Jul 28, 2021 at 04:32:45PM +0300, Laurent Pinchart wrote:
> > Hi Martin,
> > 
> > On Wed, Jul 28, 2021 at 11:12:42AM +0200, Martin Kepplinger wrote:
> > > hi,
> > > 
> > > This patch series adds a driver for the i.MX8MQ CSI MIPI receiver
> > > / controller.
> > > 
> > > It includes the driver, the dt-bindings and the DT addition to
> > > the SoC dtsi.
> > > I test it using libcamera. Thanks to Laurent who helped a lot.
> > > I'm happy for
> > > any feedback,
> > 
> > Thank you for the series. I've submitted a pull request that
> > contains
> > patches 1/3 and 2/3.
> > 
> > Shawn, Sascha, how would you like to handle 3/3 ?
> 
> I picked up the 3/3 in v9, which I think is identical to this
> version.
> Otherwise, please let me know.
> 
> Shawn

it's identical, yes. thank you very much,

                       martin



From catalin.marinas at arm.com  Wed Aug  4 03:02:32 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 4 Aug 2021 11:02:32 +0100
Subject: [PATCH v3] memblock: make memblock_find_in_range method private
In-Reply-To: <YQmT+Z9QhcwI43GK@kernel.org>
References: <20210803064218.6611-1-rppt@kernel.org>
 <20210803180526.GD5786@arm.com> <YQmT+Z9QhcwI43GK@kernel.org>
Message-ID: <20210804100231.GA4857@arm.com>

On Tue, Aug 03, 2021 at 10:07:37PM +0300, Mike Rapoport wrote:
> On Tue, Aug 03, 2021 at 07:05:26PM +0100, Catalin Marinas wrote:
> > On Tue, Aug 03, 2021 at 09:42:18AM +0300, Mike Rapoport wrote:
> > > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > > index 8490ed2917ff..0bffd2d1854f 100644
> > > --- a/arch/arm64/mm/init.c
> > > +++ b/arch/arm64/mm/init.c
> > > @@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
> > >  static void __init reserve_crashkernel(void)
> > >  {
> > >  	unsigned long long crash_base, crash_size;
> > > +	unsigned long long crash_max = arm64_dma_phys_limit;
> > >  	int ret;
> > >  
> > >  	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> > > @@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
> > >  
> > >  	crash_size = PAGE_ALIGN(crash_size);
> > >  
> > > -	if (crash_base == 0) {
> > > -		/* Current arm64 boot protocol requires 2MB alignment */
> > > -		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
> > > -				crash_size, SZ_2M);
> > > -		if (crash_base == 0) {
> > > -			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> > > -				crash_size);
> > > -			return;
> > > -		}
> > > -	} else {
> > > -		/* User specifies base address explicitly. */
> > > -		if (!memblock_is_region_memory(crash_base, crash_size)) {
> > > -			pr_warn("cannot reserve crashkernel: region is not memory\n");
> > > -			return;
> > > -		}
> > > +	/* User specifies base address explicitly. */
> > > +	if (crash_base)
> > > +		crash_max = crash_base + crash_size;
> > >  
> > > -		if (memblock_is_region_reserved(crash_base, crash_size)) {
> > > -			pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
> > > -			return;
> > > -		}
> > > -
> > > -		if (!IS_ALIGNED(crash_base, SZ_2M)) {
> > > -			pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
> > > -			return;
> > > -		}
> > > +	/* Current arm64 boot protocol requires 2MB alignment */
> > > +	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> > > +					       crash_base, crash_max);
> > > +	if (!crash_base) {
> > > +		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> > > +			crash_size);
> > > +		return;
> > >  	}
> > > -	memblock_reserve(crash_base, crash_size);
> > 
> > We'll miss a bit on debug information provided to the user in case of a
> > wrong crash_base/size option on the command line. Not sure we care much,
> > though the alignment would probably be useful (maybe we document it
> > somewhere).
> 
> It is already documented:
> 
> Documentation/admin-guide/kdump/kdump.rst:
>    On arm64, use "crashkernel=Y[@X]".  Note that the start address of
>    the kernel, X if explicitly specified, must be aligned to 2MiB (0x200000).

Thanks for the pointer.

> > What I haven't checked is whether memblock_phys_alloc_range() aims to
> > get a 2MB aligned end (size) as well. If crash_size is not 2MB aligned,
> > crash_max wouldn't be either and the above could fail. We only care
> > about the crash_base to be aligned but the memblock_phys_alloc_range()
> > doc says that both the start and size would be aligned to this.
> 
> The doc lies :)
> 
> memblock_phys_alloc_range() boils down to 
> 
> 	for_each_free_mem_range_reverse(i, nid, flags, &this_start, &this_end,
> 					NULL) {
> 
> 		/* clamp this_{start,end} to the user defined limits */
> 
> 		cand = round_down(this_end - size, align);
> 		if (cand >= this_start)
> 			return cand;
> 	}

Alright, it should work then. For arm64:

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From michael.riesch at wolfvision.net  Wed Aug  4 03:03:25 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed, 4 Aug 2021 12:03:25 +0200
Subject: [PATCH 5/5] arm64: dts: rockchip: rk3568-evb1-v10: add node for
 sd card
In-Reply-To: <2936848.7s5MMGUR32@diego>
References: <20210803185309.10013-1-michael.riesch@wolfvision.net>
 <20210803185309.10013-6-michael.riesch@wolfvision.net>
 <2936848.7s5MMGUR32@diego>
Message-ID: <ebddd74f-114f-1da4-8702-387338002551@wolfvision.net>

Hi Heiko,

On 8/3/21 10:48 PM, Heiko St?bner wrote:
> Am Dienstag, 3. August 2021, 20:53:09 CEST schrieb Michael Riesch:
>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>> ---
>>  arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
>> index 3ac70a8183c4..b0f5aa8c979c 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
>> @@ -17,6 +17,7 @@
>>  		ethernet0 = &gmac0;
>>  		ethernet1 = &gmac1;
>>  		emmc = &sdhci;
>> +		sd = &sdmmc0;
> 
> same thing as in the previous patch.
> 
> I guess you may want something like
> 
> 	mmc0 = &sdhci;
> 	mmc1 = &sdmmc0;
> 
> maybe?

Thanks for the suggestion, I'll include it in the v2.

Regards, Michael

> 
> 
> Heiko
> 
>>  	};
>>  
>>  	chosen: chosen {
>> @@ -353,6 +354,20 @@
>>  	status = "okay";
>>  };
>>  
>> +&sdmmc0 {
>> +	bus-width = <4>;
>> +	cap-sd-highspeed;
>> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>> +	disable-wp;
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
>> +	sd-uhs-sdr104;
>> +	supports-sd;
>> +	vmmc-supply = <&vcc3v3_sd>;
>> +	vqmmc-supply = <&vccio_sd>;
>> +	status = "okay";
>> +};
>> +
>>  &uart2 {
>>  	status = "okay";
>>  };
>>
> 
> 
> 
> 


From linus.walleij at linaro.org  Wed Aug  4 03:05:54 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Aug 2021 12:05:54 +0200
Subject: [PATCH 3/3] ARM: Map the lowmem and kernel separately
In-Reply-To: <20210803104932.GM22278@shell.armlinux.org.uk>
References: <20210517145719.110966-1-linus.walleij@linaro.org>
 <20210517145719.110966-4-linus.walleij@linaro.org>
 <20210730202259.dbifugsvry5vjdr7@earthen>
 <CACRpkdYAzGzqfdREogAFnyGqSnHLQmdCR=GZ=YqhzoTUA0MfCA@mail.gmail.com>
 <f3eb9c84-19c6-cba2-ffcc-2dbcb48051ad@ti.com>
 <20210803104932.GM22278@shell.armlinux.org.uk>
Message-ID: <CACRpkdaOub9EJFGy8+kWLN13wq2V_XSXrnrfxiUCvb6gdWKmBg@mail.gmail.com>

On Tue, Aug 3, 2021 at 12:49 PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:

> > It should be called on all keystone 2 platforms by default (LAPE is default mode for K2).
> >
> > Huh. Below as I remember it:
> > - K2 starts using memory window (aliased memory) at 00 8000 0000 (No IO coherency is supported)
> > - K2, early at boot, is switching to LPAE memory window 08 0000 0000 (IO coherency is supported)
> >   so all, already mapped memory, has to be fixed - phys addresses.
>
> If I remember correctly, the code that fixes that up assumes that
> (a) the kernel is mapped using section mappings in the lowmem mapping
>     at PAGE_OFFSET.._end-1
> (b) that no other RAM is mapped (iow, it's called before the kernel
>     starts building the real page mappings in paging_init()).
>
> It looks to me like Linus missed the code in arch/arm/mm/pv-fixup-asm.S
> and as the kernel is no longer mapped in the lowmem mapping, this
> likely writes a load of entries in the page tables that are random...

I looked into this!

Indeed early_mm_init() is called before paging_init() and early_mm_init()
calls lpae_pgtables_remap_asm() in pv-fixup-asm.S to add the offset
to all the section mappings over the kernel.

The section mappings we have at this point are coming from head.S,
so those get modified with the offset.

What I don't understand is what map_lowmem() was doing with the
kernel mappings on the Keystone 2 before my patch.

If it actually overwrites the kernel mapping with a new one, it will
undo what lpae_pgtables_remap_asm() has done without applying
the offset.

So I suppose map_lowmem(), due to the memory ranges passed,
would just bail the kernel mappings and leave them as-is.

Nishanth: what happens if you simply comment out map_kernel
like this?

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 7583bda5ea7d..25aa7d05a931 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1727,7 +1727,7 @@ void __init paging_init(const struct machine_desc *mdesc)
         * After this point early_alloc(), i.e. the memblock allocator, can
         * be used
         */
-       map_kernel();
+       // map_kernel();
        dma_contiguous_remap();
        early_fixmap_shutdown();
        devicemaps_init(mdesc);

Yours,
Linus Walleij


From linux at armlinux.org.uk  Wed Aug  4 03:13:58 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Aug 2021 11:13:58 +0100
Subject: [PATCH linux-next] 'linux/tty.h' included in 'hackkit.c' is
 duplicated. It is also included in the 21th line.
In-Reply-To: <20210804093907.618719-1-yong.yiran@zte.com.cn>
References: <20210804093907.618719-1-yong.yiran@zte.com.cn>
Message-ID: <20210804101358.GO22278@shell.armlinux.org.uk>

On Wed, Aug 04, 2021 at 02:39:07AM -0700, cgel.zte at gmail.com wrote:
> From: yong yiran <yong.yiran at zte.com.cn>
> 
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: yong yiran <yong.yiran at zte.com.cn>

Hi,

The commit message and summary(subject) could do with some improvement:

1) I don't think having "It is also included in the 21th line." in the
   summary adds value.

2) Maybe the summary should be

	"Remove duplicated 'linux/tty.h' include in 'hackkit.c'"

3) the commit message should say something, maybe along the lines of:

	"Remove all but the first include of linux/tty.h from hackkit.c."

Thanks.

> ---
>  arch/arm/mach-sa1100/hackkit.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
> index 3085f1c2e586..3fe34ee7c0ab 100644
> --- a/arch/arm/mach-sa1100/hackkit.c
> +++ b/arch/arm/mach-sa1100/hackkit.c
> @@ -18,7 +18,6 @@
>  #include <linux/serial_core.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/partitions.h>
> -#include <linux/tty.h>
>  #include <linux/gpio.h>
>  #include <linux/leds.h>
>  #include <linux/platform_device.h>
> -- 
> 2.25.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From drjones at redhat.com  Wed Aug  4 03:17:43 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 4 Aug 2021 12:17:43 +0200
Subject: [PATCH v6 17/21] KVM: arm64: Allow userspace to configure a
 guest's counter-timer offset
In-Reply-To: <20210804085819.846610-18-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-18-oupton@google.com>
Message-ID: <20210804101743.bgkggw7a3wbx7woi@gator.home>

On Wed, Aug 04, 2021 at 08:58:15AM +0000, Oliver Upton wrote:
> Presently, KVM provides no facilities for correctly migrating a guest
> that depends on the physical counter-timer. Whie most guests (barring
> NV, of course) should not depend on the physical counter-timer, an
> operator may wish to provide a consistent view of the physical
> counter-timer across migrations.
> 
> Provide userspace with a new vCPU attribute to modify the guest
> counter-timer offset. Unlike KVM_REG_ARM_TIMER_OFFSET, this attribute is
> hidden from the guest's architectural state. The value offsets *both*
> the virtual and physical counter-timer views for the guest. Only support
> this attribute on ECV systems as ECV is required for hardware offsetting
> of the physical counter-timer.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  Documentation/virt/kvm/devices/vcpu.rst |  28 ++++++
>  arch/arm64/include/asm/kvm_asm.h        |   2 +
>  arch/arm64/include/asm/sysreg.h         |   2 +
>  arch/arm64/include/uapi/asm/kvm.h       |   1 +
>  arch/arm64/kvm/arch_timer.c             | 122 +++++++++++++++++++++++-
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |   6 ++
>  arch/arm64/kvm/hyp/nvhe/timer-sr.c      |   5 +
>  arch/arm64/kvm/hyp/vhe/timer-sr.c       |   5 +
>  include/clocksource/arm_arch_timer.h    |   1 +
>  9 files changed, 169 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
> index 3b399d727c11..3ba35b9d9d03 100644
> --- a/Documentation/virt/kvm/devices/vcpu.rst
> +++ b/Documentation/virt/kvm/devices/vcpu.rst
> @@ -139,6 +139,34 @@ configured values on other VCPUs.  Userspace should configure the interrupt
>  numbers on at least one VCPU after creating all VCPUs and before running any
>  VCPUs.
>  
> +2.2. ATTRIBUTE: KVM_ARM_VCPU_TIMER_OFFSET
> +-----------------------------------------
> +
> +:Parameters: in kvm_device_attr.addr the address for the timer offset is a
> +             pointer to a __u64
> +
> +Returns:
> +
> +	 ======= ==================================
> +	 -EFAULT Error reading/writing the provided
> +		 parameter address
> +	 -ENXIO  Timer offsetting not implemented
> +	 ======= ==================================
> +
> +Specifies the guest's counter-timer offset from the host's virtual counter.
> +The guest's physical counter value is then derived by the following
> +equation:
> +
> +  guest_cntpct = host_cntvct - KVM_ARM_VCPU_TIMER_OFFSET
> +
> +The guest's virtual counter value is derived by the following equation:
> +
> +  guest_cntvct = host_cntvct - KVM_REG_ARM_TIMER_OFFSET
> +			- KVM_ARM_VCPU_TIMER_OFFSET
> +
> +KVM does not allow the use of varying offset values for different vCPUs;
> +the last written offset value will be broadcasted to all vCPUs in a VM.
> +
>  3. GROUP: KVM_ARM_VCPU_PVTIME_CTRL
>  ==================================
>  
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 9f0bf2109be7..ab1c8fdb0177 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -65,6 +65,7 @@
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize		19
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp			20
>  #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc			21
> +#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntpoff		22
>  
>  #ifndef __ASSEMBLY__
>  
> @@ -200,6 +201,7 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
>  extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
>  
>  extern void __kvm_timer_set_cntvoff(u64 cntvoff);
> +extern void __kvm_timer_set_cntpoff(u64 cntpoff);
>  
>  extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
>  
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 4dfc44066dfb..c34672aa65b9 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -586,6 +586,8 @@
>  #define SYS_ICH_LR14_EL2		__SYS__LR8_EL2(6)
>  #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
>  
> +#define SYS_CNTPOFF_EL2			sys_reg(3, 4, 14, 0, 6)
> +
>  /* VHE encodings for architectural EL0/1 system registers */
>  #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
>  #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index 949a31bc10f0..15150f8224a1 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -366,6 +366,7 @@ struct kvm_arm_copy_mte_tags {
>  #define KVM_ARM_VCPU_TIMER_CTRL		1
>  #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
>  #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
> +#define   KVM_ARM_VCPU_TIMER_OFFSET		2
>  #define KVM_ARM_VCPU_PVTIME_CTRL	2
>  #define   KVM_ARM_VCPU_PVTIME_IPA	0
>  
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index a8815b09da3e..f15058612994 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -85,11 +85,15 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
>  static u64 timer_get_offset(struct arch_timer_context *ctxt)
>  {
>  	struct kvm_vcpu *vcpu = ctxt->vcpu;
> +	struct arch_timer_cpu *timer = vcpu_timer(vcpu);

This new timer variable doesn't appear to get used.

>  
>  	switch(arch_timer_ctx_index(ctxt)) {
>  	case TIMER_VTIMER:
> +	case TIMER_PTIMER:
>  		return ctxt->host_offset;
>  	default:
> +		WARN_ONCE(1, "unrecognized timer %ld\n",
> +			  arch_timer_ctx_index(ctxt));
>  		return 0;
>  	}
>  }
> @@ -144,6 +148,7 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
>  
>  	switch(arch_timer_ctx_index(ctxt)) {
>  	case TIMER_VTIMER:
> +	case TIMER_PTIMER:
>  		ctxt->host_offset = offset;
>  		break;
>  	default:
> @@ -572,6 +577,11 @@ static void set_cntvoff(u64 cntvoff)
>  	kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff);
>  }
>  
> +static void set_cntpoff(u64 cntpoff)
> +{
> +	kvm_call_hyp(__kvm_timer_set_cntpoff, cntpoff);
> +}
> +
>  static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active)
>  {
>  	int r;
> @@ -647,6 +657,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
>  	}
>  
>  	set_cntvoff(timer_get_offset(map.direct_vtimer));
> +	if (cpus_have_const_cap(ARM64_ECV))
> +		set_cntpoff(timer_get_offset(vcpu_ptimer(vcpu)));
>  
>  	kvm_timer_unblocking(vcpu);
>  
> @@ -814,6 +826,22 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
>  	mutex_unlock(&kvm->lock);
>  }
>  
> +static void update_ptimer_cntpoff(struct kvm_vcpu *vcpu, u64 cntpoff)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 cntvoff;
> +
> +	mutex_lock(&kvm->lock);
> +
> +	/* adjustments to the physical offset also affect vtimer */
> +	cntvoff = timer_get_offset(vcpu_vtimer(vcpu));
> +	cntvoff += cntpoff - timer_get_offset(vcpu_ptimer(vcpu));
> +
> +	update_timer_offset(vcpu, TIMER_PTIMER, cntpoff, false);
> +	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, false);
> +	mutex_unlock(&kvm->lock);
> +}
> +
>  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
>  {
>  	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
> @@ -932,6 +960,29 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
>  	return (u64)-1;
>  }
>  
> +/**
> + * kvm_arm_timer_read_offset - returns the guest value of CNTVOFF_EL2.
> + * @vcpu: the vcpu pointer
> + *
> + * Computes the guest value of CNTVOFF_EL2 by subtracting the physical
> + * counter offset. Note that KVM defines CNTVOFF_EL2 as the offset from the
> + * guest's physical counter-timer, not the host's.
> + *
> + * Returns: the guest value for CNTVOFF_EL2
> + */
> +static u64 kvm_arm_timer_read_offset(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 offset;
> +
> +	mutex_lock(&kvm->lock);
> +	offset = timer_get_offset(vcpu_vtimer(vcpu)) -
> +			timer_get_offset(vcpu_ptimer(vcpu));
> +	mutex_unlock(&kvm->lock);
> +
> +	return offset;
> +}
> +
>  static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
>  			      struct arch_timer_context *timer,
>  			      enum kvm_arch_timer_regs treg)
> @@ -957,7 +1008,7 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
>  		break;
>  
>  	case TIMER_REG_OFFSET:
> -		val = timer_get_offset(timer);
> +		val = kvm_arm_timer_read_offset(vcpu);
>  		break;
>  
>  	default:
> @@ -1350,6 +1401,9 @@ void kvm_timer_init_vhe(void)
>  	val = read_sysreg(cnthctl_el2);
>  	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
>  	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
> +
> +	if (cpus_have_const_cap(ARM64_ECV))
> +		val |= CNTHCTL_ECV;
>  	write_sysreg(val, cnthctl_el2);
>  }
>  
> @@ -1364,7 +1418,8 @@ static void set_timer_irqs(struct kvm *kvm, int vtimer_irq, int ptimer_irq)
>  	}
>  }
>  
> -int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +static int kvm_arm_timer_set_attr_irq(struct kvm_vcpu *vcpu,
> +				      struct kvm_device_attr *attr)
>  {
>  	int __user *uaddr = (int __user *)(long)attr->addr;
>  	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
> @@ -1397,7 +1452,37 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  	return 0;
>  }
>  
> -int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
> +					 struct kvm_device_attr *attr)
> +{
> +	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +	u64 offset;
> +
> +	if (!cpus_have_const_cap(ARM64_ECV))
> +		return -ENXIO;
> +
> +	if (get_user(offset, uaddr))
> +		return -EFAULT;
> +
> +	update_ptimer_cntpoff(vcpu, offset);
> +	return 0;
> +}
> +
> +int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +{
> +	switch (attr->attr) {
> +	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> +	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> +		return kvm_arm_timer_set_attr_irq(vcpu, attr);
> +	case KVM_ARM_VCPU_TIMER_OFFSET:
> +		return kvm_arm_timer_set_attr_offset(vcpu, attr);
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
> +static int kvm_arm_timer_get_attr_irq(struct kvm_vcpu *vcpu,
> +				      struct kvm_device_attr *attr)
>  {
>  	int __user *uaddr = (int __user *)(long)attr->addr;
>  	struct arch_timer_context *timer;
> @@ -1418,12 +1503,43 @@ int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  	return put_user(irq, uaddr);
>  }
>  
> +static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
> +					 struct kvm_device_attr *attr)
> +{
> +	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +	u64 offset;
> +
> +	if (!cpus_have_const_cap(ARM64_ECV))
> +		return -ENXIO;
> +
> +	offset = timer_get_offset(vcpu_ptimer(vcpu));
> +	return put_user(offset, uaddr);
> +}
> +
> +int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu,
> +			   struct kvm_device_attr *attr)
> +{
> +	switch (attr->attr) {
> +	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> +	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> +		return kvm_arm_timer_get_attr_irq(vcpu, attr);
> +	case KVM_ARM_VCPU_TIMER_OFFSET:
> +		return kvm_arm_timer_get_attr_offset(vcpu, attr);
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
>  int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  {
>  	switch (attr->attr) {
>  	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
>  	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
>  		return 0;
> +	case KVM_ARM_VCPU_TIMER_OFFSET:
> +		if (cpus_have_const_cap(ARM64_ECV))
> +			return 0;
> +		break;
>  	}
>  
>  	return -ENXIO;
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 1632f001f4ed..cfa923df3af6 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -68,6 +68,11 @@ static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt)
>  	__kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1));
>  }
>  
> +static void handle___kvm_timer_set_cntpoff(struct kvm_cpu_context *host_ctxt)
> +{
> +	__kvm_timer_set_cntpoff(cpu_reg(host_ctxt, 1));
> +}
> +
>  static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt)
>  {
>  	u64 tmp;
> @@ -197,6 +202,7 @@ static const hcall_t host_hcall[] = {
>  	HANDLE_FUNC(__pkvm_create_private_mapping),
>  	HANDLE_FUNC(__pkvm_prot_finalize),
>  	HANDLE_FUNC(__pkvm_mark_hyp),
> +	HANDLE_FUNC(__kvm_timer_set_cntpoff),
>  };
>  
>  static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> index 9072e71693ba..5b8b4cd02506 100644
> --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> @@ -15,6 +15,11 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
>  	write_sysreg(cntvoff, cntvoff_el2);
>  }
>  
> +void __kvm_timer_set_cntpoff(u64 cntpoff)
> +{
> +	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
> +}
> +
>  /*
>   * Should only be called on non-VHE systems.
>   * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe().
> diff --git a/arch/arm64/kvm/hyp/vhe/timer-sr.c b/arch/arm64/kvm/hyp/vhe/timer-sr.c
> index 4cda674a8be6..231e16a071a5 100644
> --- a/arch/arm64/kvm/hyp/vhe/timer-sr.c
> +++ b/arch/arm64/kvm/hyp/vhe/timer-sr.c
> @@ -10,3 +10,8 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
>  {
>  	write_sysreg(cntvoff, cntvoff_el2);
>  }
> +
> +void __kvm_timer_set_cntpoff(u64 cntpoff)
> +{
> +	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
> +}
> diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
> index 73c7139c866f..7252ffa3d675 100644
> --- a/include/clocksource/arm_arch_timer.h
> +++ b/include/clocksource/arm_arch_timer.h
> @@ -21,6 +21,7 @@
>  #define CNTHCTL_EVNTEN			(1 << 2)
>  #define CNTHCTL_EVNTDIR			(1 << 3)
>  #define CNTHCTL_EVNTI			(0xF << 4)
> +#define CNTHCTL_ECV			(1 << 12)
>  
>  enum arch_timer_reg {
>  	ARCH_TIMER_REG_CTRL,
> -- 
> 2.32.0.605.g8dce9f2422-goog
>

Reviewed-by: Andrew Jones <drjones at redhat.com>



From drjones at redhat.com  Wed Aug  4 03:19:03 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 4 Aug 2021 12:19:03 +0200
Subject: [PATCH v6 12/21] KVM: arm64: Separate guest/host counter offset
 values
In-Reply-To: <20210804085819.846610-13-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-13-oupton@google.com>
Message-ID: <20210804101903.3grfwrv5mlm5sydd@gator.home>

On Wed, Aug 04, 2021 at 08:58:10AM +0000, Oliver Upton wrote:
> In some instances, a VMM may want to update the guest's counter-timer
> offset in a transparent manner, meaning that changes to the hardware
> value do not affect the synthetic register presented to the guest or the
> VMM through said guest's architectural state. Lay the groundwork to
> separate guest offset register writes from the hardware values utilized
> by KVM.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  arch/arm64/kvm/arch_timer.c  | 48 ++++++++++++++++++++++++++++++++----
>  include/kvm/arm_arch_timer.h |  3 +++
>  2 files changed, 46 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index c0101db75ad4..4c2b763a8849 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -87,6 +87,18 @@ static u64 timer_get_offset(struct arch_timer_context *ctxt)
>  	struct kvm_vcpu *vcpu = ctxt->vcpu;
>  
>  	switch(arch_timer_ctx_index(ctxt)) {
> +	case TIMER_VTIMER:
> +		return ctxt->host_offset;
> +	default:
> +		return 0;
> +	}
> +}
> +
> +static u64 timer_get_guest_offset(struct arch_timer_context *ctxt)
> +{
> +	struct kvm_vcpu *vcpu = ctxt->vcpu;
> +
> +	switch (arch_timer_ctx_index(ctxt)) {
>  	case TIMER_VTIMER:
>  		return __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
>  	default:
> @@ -132,13 +144,31 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
>  
>  	switch(arch_timer_ctx_index(ctxt)) {
>  	case TIMER_VTIMER:
> -		__vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset;
> +		ctxt->host_offset = offset;
>  		break;
>  	default:
>  		WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
>  	}
>  }
>  
> +static void timer_set_guest_offset(struct arch_timer_context *ctxt, u64 offset)
> +{
> +	struct kvm_vcpu *vcpu = ctxt->vcpu;
> +
> +	switch (arch_timer_ctx_index(ctxt)) {
> +	case TIMER_VTIMER: {
> +		u64 host_offset = timer_get_offset(ctxt);
> +
> +		host_offset += offset - __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
> +		__vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset;
> +		timer_set_offset(ctxt, host_offset);
> +		break;
> +	}
> +	default:
> +		WARN_ONCE(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
> +	}
> +}
> +
>  u64 kvm_phys_timer_read(void)
>  {
>  	return timecounter->cc->read(timecounter->cc);
> @@ -749,7 +779,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
>  
>  /* Make offset updates for all timer contexts atomic */
>  static void update_timer_offset(struct kvm_vcpu *vcpu,
> -				enum kvm_arch_timers timer, u64 offset)
> +				enum kvm_arch_timers timer, u64 offset,
> +				bool guest_visible)
>  {
>  	int i;
>  	struct kvm *kvm = vcpu->kvm;
> @@ -758,13 +789,20 @@ static void update_timer_offset(struct kvm_vcpu *vcpu,
>  	lockdep_assert_held(&kvm->lock);
>  
>  	kvm_for_each_vcpu(i, tmp, kvm)
> -		timer_set_offset(vcpu_get_timer(tmp, timer), offset);
> +		if (guest_visible)
> +			timer_set_guest_offset(vcpu_get_timer(tmp, timer),
> +					       offset);
> +		else
> +			timer_set_offset(vcpu_get_timer(tmp, timer), offset);
>  
>  	/*
>  	 * When called from the vcpu create path, the CPU being created is not
>  	 * included in the loop above, so we just set it here as well.
>  	 */
> -	timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
> +	if (guest_visible)
> +		timer_set_guest_offset(vcpu_get_timer(vcpu, timer), offset);
> +	else
> +		timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
>  }
>  
>  static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
> @@ -772,7 +810,7 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
>  	struct kvm *kvm = vcpu->kvm;
>  
>  	mutex_lock(&kvm->lock);
> -	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff);
> +	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, true);
>  	mutex_unlock(&kvm->lock);
>  }
>  
> diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
> index 51c19381108c..9d65d4a29f81 100644
> --- a/include/kvm/arm_arch_timer.h
> +++ b/include/kvm/arm_arch_timer.h
> @@ -42,6 +42,9 @@ struct arch_timer_context {
>  	/* Duplicated state from arch_timer.c for convenience */
>  	u32				host_timer_irq;
>  	u32				host_timer_irq_flags;
> +
> +	/* offset relative to the host's physical counter-timer */
> +	u64				host_offset;
>  };
>  
>  struct timer_map {
> -- 
> 2.32.0.605.g8dce9f2422-goog
>

 
Reviewed-by: Andrew Jones <drjones at redhat.com>



From drjones at redhat.com  Wed Aug  4 03:20:10 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 4 Aug 2021 12:20:10 +0200
Subject: [PATCH v6 13/21] KVM: arm64: Allow userspace to configure a
 vCPU's virtual offset
In-Reply-To: <20210804085819.846610-14-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-14-oupton@google.com>
Message-ID: <20210804102010.poou6o354rink6e4@gator.home>

On Wed, Aug 04, 2021 at 08:58:11AM +0000, Oliver Upton wrote:
> Allow userspace to access the guest's virtual counter-timer offset
> through the ONE_REG interface. The value read or written is defined to
> be an offset from the guest's physical counter-timer. Add some
> documentation to clarify how a VMM should use this and the existing
> CNTVCT_EL0.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  Documentation/virt/kvm/api.rst    | 10 ++++++++++
>  arch/arm64/include/uapi/asm/kvm.h |  1 +
>  arch/arm64/kvm/arch_timer.c       | 11 +++++++++++
>  arch/arm64/kvm/guest.c            |  6 +++++-
>  include/kvm/arm_arch_timer.h      |  1 +
>  5 files changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index 8d4a3471ad9e..28a65dc89985 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -2487,6 +2487,16 @@ arm64 system registers have the following id bit patterns::
>       derived from the register encoding for CNTV_CVAL_EL0.  As this is
>       API, it must remain this way.
>  
> +.. warning::
> +
> +     The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from
> +     the guest's view of the physical counter-timer.
> +
> +     Userspace should use either KVM_REG_ARM_TIMER_OFFSET or
> +     KVM_REG_ARM_TIMER_CVAL to pause and resume a guest's virtual
> +     counter-timer. Mixed use of these registers could result in an
> +     unpredictable guest counter value.
> +
>  arm64 firmware pseudo-registers have the following bit pattern::
>  
>    0x6030 0000 0014 <regno:16>
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index b3edde68bc3e..949a31bc10f0 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags {
>  #define KVM_REG_ARM_TIMER_CTL		ARM64_SYS_REG(3, 3, 14, 3, 1)
>  #define KVM_REG_ARM_TIMER_CVAL		ARM64_SYS_REG(3, 3, 14, 0, 2)
>  #define KVM_REG_ARM_TIMER_CNT		ARM64_SYS_REG(3, 3, 14, 3, 2)
> +#define KVM_REG_ARM_TIMER_OFFSET	ARM64_SYS_REG(3, 4, 14, 0, 3)
>  
>  /* KVM-as-firmware specific pseudo-registers */
>  #define KVM_REG_ARM_FW			(0x0014 << KVM_REG_ARM_COPROC_SHIFT)
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 4c2b763a8849..a8815b09da3e 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -868,6 +868,10 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
>  		timer = vcpu_vtimer(vcpu);
>  		kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value);
>  		break;
> +	case KVM_REG_ARM_TIMER_OFFSET:
> +		timer = vcpu_vtimer(vcpu);
> +		update_vtimer_cntvoff(vcpu, value);
> +		break;
>  	case KVM_REG_ARM_PTIMER_CTL:
>  		timer = vcpu_ptimer(vcpu);
>  		kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
> @@ -912,6 +916,9 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
>  	case KVM_REG_ARM_TIMER_CVAL:
>  		return kvm_arm_timer_read(vcpu,
>  					  vcpu_vtimer(vcpu), TIMER_REG_CVAL);
> +	case KVM_REG_ARM_TIMER_OFFSET:
> +		return kvm_arm_timer_read(vcpu,
> +					  vcpu_vtimer(vcpu), TIMER_REG_OFFSET);
>  	case KVM_REG_ARM_PTIMER_CTL:
>  		return kvm_arm_timer_read(vcpu,
>  					  vcpu_ptimer(vcpu), TIMER_REG_CTL);
> @@ -949,6 +956,10 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
>  		val = kvm_phys_timer_read() - timer_get_offset(timer);
>  		break;
>  
> +	case TIMER_REG_OFFSET:
> +		val = timer_get_offset(timer);
> +		break;
> +
>  	default:
>  		BUG();
>  	}
> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> index 1dfb83578277..17fc06e2b422 100644
> --- a/arch/arm64/kvm/guest.c
> +++ b/arch/arm64/kvm/guest.c
> @@ -591,7 +591,7 @@ static unsigned long num_core_regs(const struct kvm_vcpu *vcpu)
>   * ARM64 versions of the TIMER registers, always available on arm64
>   */
>  
> -#define NUM_TIMER_REGS 3
> +#define NUM_TIMER_REGS 4
>  
>  static bool is_timer_reg(u64 index)
>  {
> @@ -599,6 +599,7 @@ static bool is_timer_reg(u64 index)
>  	case KVM_REG_ARM_TIMER_CTL:
>  	case KVM_REG_ARM_TIMER_CNT:
>  	case KVM_REG_ARM_TIMER_CVAL:
> +	case KVM_REG_ARM_TIMER_OFFSET:
>  		return true;
>  	}
>  	return false;
> @@ -614,6 +615,9 @@ static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
>  	uindices++;
>  	if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices))
>  		return -EFAULT;
> +	uindices++;
> +	if (put_user(KVM_REG_ARM_TIMER_OFFSET, uindices))
> +		return -EFAULT;
>  
>  	return 0;
>  }
> diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
> index 9d65d4a29f81..615f9314f6a5 100644
> --- a/include/kvm/arm_arch_timer.h
> +++ b/include/kvm/arm_arch_timer.h
> @@ -21,6 +21,7 @@ enum kvm_arch_timer_regs {
>  	TIMER_REG_CVAL,
>  	TIMER_REG_TVAL,
>  	TIMER_REG_CTL,
> +	TIMER_REG_OFFSET,
>  };
>  
>  struct arch_timer_context {
> -- 
> 2.32.0.605.g8dce9f2422-goog
>

 
Reviewed-by: Andrew Jones <drjones at redhat.com>



From oupton at google.com  Wed Aug  4 03:22:26 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 4 Aug 2021 03:22:26 -0700
Subject: [PATCH v6 17/21] KVM: arm64: Allow userspace to configure a
 guest's counter-timer offset
In-Reply-To: <20210804101743.bgkggw7a3wbx7woi@gator.home>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-18-oupton@google.com>
 <20210804101743.bgkggw7a3wbx7woi@gator.home>
Message-ID: <CAOQ_Qsh9cQob1X=-39H4mMf7gYES5VnQP-t5C_R+HdRgk0WPeg@mail.gmail.com>

On Wed, Aug 4, 2021 at 3:17 AM Andrew Jones <drjones at redhat.com> wrote:
> > diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> > index a8815b09da3e..f15058612994 100644
> > --- a/arch/arm64/kvm/arch_timer.c
> > +++ b/arch/arm64/kvm/arch_timer.c
> > @@ -85,11 +85,15 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
> >  static u64 timer_get_offset(struct arch_timer_context *ctxt)
> >  {
> >       struct kvm_vcpu *vcpu = ctxt->vcpu;
> > +     struct arch_timer_cpu *timer = vcpu_timer(vcpu);
>
> This new timer variable doesn't appear to get used.

Ooops, this is stale. Thanks for catching that.

>
> Reviewed-by: Andrew Jones <drjones at redhat.com>
>

Thanks for the quick review!

--
Oliver


From drjones at redhat.com  Wed Aug  4 03:25:39 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 4 Aug 2021 12:25:39 +0200
Subject: [PATCH v6 18/21] KVM: arm64: Configure timer traps in
 vcpu_load() for VHE
In-Reply-To: <20210804085819.846610-19-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-19-oupton@google.com>
Message-ID: <20210804102539.yczeevsaqlhptgib@gator.home>

On Wed, Aug 04, 2021 at 08:58:16AM +0000, Oliver Upton wrote:
> In preparation for emulated physical counter-timer offsetting, configure
> traps on every vcpu_load() for VHE systems. As before, these trap
> settings do not affect host userspace, and are only active for the
> guest.
> 
> Suggested-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  arch/arm64/kvm/arch_timer.c  | 10 +++++++---
>  arch/arm64/kvm/arm.c         |  4 +---
>  include/kvm/arm_arch_timer.h |  2 --
>  3 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index f15058612994..9ead94aa867d 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -51,6 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
>  static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
>  			      struct arch_timer_context *timer,
>  			      enum kvm_arch_timer_regs treg);
> +static void kvm_timer_enable_traps_vhe(void);
>  
>  u32 timer_get_ctl(struct arch_timer_context *ctxt)
>  {
> @@ -668,6 +669,9 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
>  
>  	if (map.emul_ptimer)
>  		timer_emulate(map.emul_ptimer);
> +
> +	if (has_vhe())
> +		kvm_timer_enable_traps_vhe();
>  }
>  
>  bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
> @@ -1383,12 +1387,12 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>  }
>  
>  /*
> - * On VHE system, we only need to configure the EL2 timer trap register once,
> - * not for every world switch.
> + * On VHE system, we only need to configure the EL2 timer trap register on
> + * vcpu_load(), but not every world switch into the guest.
>   * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
>   * and this makes those bits have no effect for the host kernel execution.
>   */
> -void kvm_timer_init_vhe(void)
> +static void kvm_timer_enable_traps_vhe(void)
>  {
>  	/* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
>  	u32 cnthctl_shift = 10;
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e9a2b8f27792..47ea1e1ba80b 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -1558,9 +1558,7 @@ static void cpu_hyp_reinit(void)
>  
>  	cpu_hyp_reset();
>  
> -	if (is_kernel_in_hyp_mode())
> -		kvm_timer_init_vhe();
> -	else
> +	if (!is_kernel_in_hyp_mode())
>  		cpu_init_hyp_mode();
>  
>  	cpu_set_hyp_vector();
> diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
> index 615f9314f6a5..254653b42da0 100644
> --- a/include/kvm/arm_arch_timer.h
> +++ b/include/kvm/arm_arch_timer.h
> @@ -87,8 +87,6 @@ u64 kvm_phys_timer_read(void);
>  void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu);
>  void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu);
>  
> -void kvm_timer_init_vhe(void);
> -
>  bool kvm_arch_timer_get_input_level(int vintid);
>  
>  #define vcpu_timer(v)	(&(v)->arch.timer_cpu)
> -- 
> 2.32.0.605.g8dce9f2422-goog
>

Reviewed-by: Andrew Jones <drjones at redhat.com>



From linux at armlinux.org.uk  Wed Aug  4 03:36:58 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Aug 2021 11:36:58 +0100
Subject: [PATCH 3/3] ARM: Map the lowmem and kernel separately
In-Reply-To: <CACRpkdaOub9EJFGy8+kWLN13wq2V_XSXrnrfxiUCvb6gdWKmBg@mail.gmail.com>
References: <20210517145719.110966-1-linus.walleij@linaro.org>
 <20210517145719.110966-4-linus.walleij@linaro.org>
 <20210730202259.dbifugsvry5vjdr7@earthen>
 <CACRpkdYAzGzqfdREogAFnyGqSnHLQmdCR=GZ=YqhzoTUA0MfCA@mail.gmail.com>
 <f3eb9c84-19c6-cba2-ffcc-2dbcb48051ad@ti.com>
 <20210803104932.GM22278@shell.armlinux.org.uk>
 <CACRpkdaOub9EJFGy8+kWLN13wq2V_XSXrnrfxiUCvb6gdWKmBg@mail.gmail.com>
Message-ID: <20210804103658.GP22278@shell.armlinux.org.uk>

On Wed, Aug 04, 2021 at 12:05:54PM +0200, Linus Walleij wrote:
> On Tue, Aug 3, 2021 at 12:49 PM Russell King (Oracle)
> <linux at armlinux.org.uk> wrote:
> 
> > > It should be called on all keystone 2 platforms by default (LAPE is default mode for K2).
> > >
> > > Huh. Below as I remember it:
> > > - K2 starts using memory window (aliased memory) at 00 8000 0000 (No IO coherency is supported)
> > > - K2, early at boot, is switching to LPAE memory window 08 0000 0000 (IO coherency is supported)
> > >   so all, already mapped memory, has to be fixed - phys addresses.
> >
> > If I remember correctly, the code that fixes that up assumes that
> > (a) the kernel is mapped using section mappings in the lowmem mapping
> >     at PAGE_OFFSET.._end-1
> > (b) that no other RAM is mapped (iow, it's called before the kernel
> >     starts building the real page mappings in paging_init()).
> >
> > It looks to me like Linus missed the code in arch/arm/mm/pv-fixup-asm.S
> > and as the kernel is no longer mapped in the lowmem mapping, this
> > likely writes a load of entries in the page tables that are random...
> 
> I looked into this!
> 
> Indeed early_mm_init() is called before paging_init() and early_mm_init()
> calls lpae_pgtables_remap_asm() in pv-fixup-asm.S to add the offset
> to all the section mappings over the kernel.
> 
> The section mappings we have at this point are coming from head.S,
> so those get modified with the offset.
> 
> What I don't understand is what map_lowmem() was doing with the
> kernel mappings on the Keystone 2 before my patch.

Essentially, what happened with Keystone 2 is that the head.S code
does its usual thing, mapping the kernel using the physical address
that the early code is running at using section mappings, before
then switching the MMU on and running from the virtual address space.
At this point, the phys<->virt conversions work for this physical
address space (which, on Keystone 2 is the low physical space which
isn't coherent with devices.)

early_mm_init() gets called, we spot we're on Keystone 2, and we
initiate the change - the MMU needs a break-before-make for these
mappings, and as we're using these mappings to execute our code,
we have to turn the MMU off to do the update.

We update the phys<->virt conversion, and then fixup the page
tables. lpae_pgtables_remap() is passed the offset between the
low physical address and the high physical address, as well as the
low physical address of the page tables. (since when we turn the MMU
off, all we have access to are the low physical mapping.)

The structure of the LPAE page tables is:

- First 4k - L1 entries.
- Following 32k - L2 entries mapped as sections.

In pv-fixup-asm.S:

        ldr     r6, =(_end - 1)
        add     r7, r2, #0x1000
        add     r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
        add     r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER)

r7 is the low physical address in the L2 entries, r6 is the last
(inclusive) entry. Essentially, all we do is add "offset" to every
section mapping corresponding to addresses between PAGE_OFFSET and
_end.

We also do that for the boot data (two section mappings) at
FDT_FIXED_BASE, the four L1 entries, and the two TTBR physical
address register values.

> If it actually overwrites the kernel mapping with a new one, it will
> undo what lpae_pgtables_remap_asm() has done without applying
> the offset.
> 
> So I suppose map_lowmem(), due to the memory ranges passed,
> would just bail the kernel mappings and leave them as-is.

By the time map_lowmem() gets called, the phys<->virt mappings will
have been modified throughout the kernel so that virtual addresses
in the direct mapping will translate to the high physical addresses.
So, things like __pa(__init_end) in map_kernel() will translate
__init_end to the high physical address rather than the low physical
address.

My guess would be the problem is that kernel_sec_start and
kernel_sec_end are not being adjusted, and are still pointing at
the low physical addresses rather than the high ones.
Consequently, kernel_x_start and kernel_nx_end points at the low phys
space, but kernel_x_end and kernel_nx_start points to the high phys
space.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From iwona.winiarska at intel.com  Wed Aug  4 03:43:31 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Wed, 4 Aug 2021 10:43:31 +0000
Subject: [PATCH v2 12/15] hwmon: peci: Add cputemp driver
In-Reply-To: <cd7e15fb-04ba-1eb3-e6b9-43f6d904125e@roeck-us.net>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-13-iwona.winiarska@intel.com>
 <cd7e15fb-04ba-1eb3-e6b9-43f6d904125e@roeck-us.net>
Message-ID: <7271a56f22ef33cf178683456dbb7c216951018b.camel@intel.com>

On Tue, 2021-08-03 at 08:24 -0700, Guenter Roeck wrote:
> On 8/3/21 4:31 AM, Iwona Winiarska wrote:
> > Add peci-cputemp driver for Digital Thermal Sensor (DTS) thermal
> > readings of the processor package and processor cores that are
> > accessible via the PECI interface.
> > 
> > The main use case for the driver (and PECI interface) is out-of-band
> > management, where we're able to obtain the DTS readings from an external
> > entity connected with PECI, e.g. BMC on server platforms.
> > 
> > Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> > ---
> > ? MAINTAINERS????????????????? |?? 7 +
> > ? drivers/hwmon/Kconfig??????? |?? 2 +
> > ? drivers/hwmon/Makefile?????? |?? 1 +
> > ? drivers/hwmon/peci/Kconfig?? |? 18 ++
> > ? drivers/hwmon/peci/Makefile? |?? 5 +
> > ? drivers/hwmon/peci/common.h? |? 58 ++++
> > ? drivers/hwmon/peci/cputemp.c | 591 +++++++++++++++++++++++++++++++++++
> > ? 7 files changed, 682 insertions(+)
> > ? create mode 100644 drivers/hwmon/peci/Kconfig
> > ? create mode 100644 drivers/hwmon/peci/Makefile
> > ? create mode 100644 drivers/hwmon/peci/common.h
> > ? create mode 100644 drivers/hwmon/peci/cputemp.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 3f5d48e1d143..e36b5c0824e3 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -14512,6 +14512,13 @@ L:?????platform-driver-x86 at vger.kernel.org
> > ? S:????Maintained
> > ? F:????drivers/platform/x86/peaq-wmi.c
> > ? 
> > +PECI HARDWARE MONITORING DRIVERS
> > +M:?????Iwona Winiarska <iwona.winiarska at intel.com>
> > +R:?????Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > +L:?????linux-hwmon at vger.kernel.org
> > +S:?????Supported
> > +F:?????drivers/hwmon/peci/
> > +
> > ? PECI SUBSYSTEM
> > ? M:????Iwona Winiarska <iwona.winiarska at intel.com>
> > ? R:????Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> > index e3675377bc5d..61c0e3404415 100644
> > --- a/drivers/hwmon/Kconfig
> > +++ b/drivers/hwmon/Kconfig
> > @@ -1507,6 +1507,8 @@ config SENSORS_PCF8591
> > ????????? These devices are hard to detect and rarely found on mainstream
> > ????????? hardware. If unsure, say N.
> > ? 
> > +source "drivers/hwmon/peci/Kconfig"
> > +
> > ? source "drivers/hwmon/pmbus/Kconfig"
> > ? 
> > ? config SENSORS_PWM_FAN
> > diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
> > index d712c61c1f5e..f52331f212ed 100644
> > --- a/drivers/hwmon/Makefile
> > +++ b/drivers/hwmon/Makefile
> > @@ -202,6 +202,7 @@ obj-$(CONFIG_SENSORS_WM8350)????????+= wm8350-hwmon.o
> > ? obj-$(CONFIG_SENSORS_XGENE)???+= xgene-hwmon.o
> > ? 
> > ? obj-$(CONFIG_SENSORS_OCC)?????+= occ/
> > +obj-$(CONFIG_SENSORS_PECI)?????+= peci/
> > ? obj-$(CONFIG_PMBUS)???????????+= pmbus/
> > ? 
> > ? ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG
> > diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
> > new file mode 100644
> > index 000000000000..e10eed68d70a
> > --- /dev/null
> > +++ b/drivers/hwmon/peci/Kconfig
> > @@ -0,0 +1,18 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +
> > +config SENSORS_PECI_CPUTEMP
> > +???????tristate "PECI CPU temperature monitoring client"
> > +???????depends on PECI
> > +???????select SENSORS_PECI
> > +???????select PECI_CPU
> > +???????help
> > +???????? If you say yes here you get support for the generic Intel PECI
> > +???????? cputemp driver which provides Digital Thermal Sensor (DTS) thermal
> > +???????? readings of the CPU package and CPU cores that are accessible via
> > +???????? the processor PECI interface.
> > +
> > +???????? This driver can also be built as a module. If so, the module
> > +???????? will be called peci-cputemp.
> > +
> > +config SENSORS_PECI
> > +???????tristate
> > diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
> > new file mode 100644
> > index 000000000000..e8a0ada5ab1f
> > --- /dev/null
> > +++ b/drivers/hwmon/peci/Makefile
> > @@ -0,0 +1,5 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +
> > +peci-cputemp-y := cputemp.o
> > +
> > +obj-$(CONFIG_SENSORS_PECI_CPUTEMP)?????+= peci-cputemp.o
> > diff --git a/drivers/hwmon/peci/common.h b/drivers/hwmon/peci/common.h
> > new file mode 100644
> > index 000000000000..734506b0eca2
> > --- /dev/null
> > +++ b/drivers/hwmon/peci/common.h
> > @@ -0,0 +1,58 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/* Copyright (c) 2021 Intel Corporation */
> > +
> > +#include <linux/mutex.h>
> > +#include <linux/types.h>
> > +
> > +#ifndef __PECI_HWMON_COMMON_H
> > +#define __PECI_HWMON_COMMON_H
> > +
> > +#define PECI_HWMON_UPDATE_INTERVAL?????HZ
> > +
> > +/**
> > + * struct peci_sensor_state - PECI state information
> > + * @valid: flag to indicate the sensor value is valid
> > + * @last_updated: time of the last update in jiffies
> > + * @lock: mutex to protect sensor access
> > + */
> > +struct peci_sensor_state {
> > +???????bool valid;
> > +???????unsigned long last_updated;
> > +???????struct mutex lock; /* protect sensor access */
> > +};
> > +
> > +/**
> > + * struct peci_sensor_data - PECI sensor information
> > + * @value: sensor value in milli units
> > + * @state: sensor update state
> > + */
> > +
> > +struct peci_sensor_data {
> > +???????s32 value;
> > +???????struct peci_sensor_state state;
> > +};
> > +
> > +/**
> > + * peci_sensor_need_update() - check whether sensor update is needed or not
> > + * @sensor: pointer to sensor data struct
> > + *
> > + * Return: true if update is needed, false if not.
> > + */
> > +
> > +static inline bool peci_sensor_need_update(struct peci_sensor_state *state)
> > +{
> > +???????return !state->valid ||
> > +????????????? time_after(jiffies, state->last_updated +
> > PECI_HWMON_UPDATE_INTERVAL);
> > +}
> > +
> > +/**
> > + * peci_sensor_mark_updated() - mark the sensor is updated
> > + * @sensor: pointer to sensor data struct
> > + */
> > +static inline void peci_sensor_mark_updated(struct peci_sensor_state
> > *state)
> > +{
> > +???????state->valid = true;
> > +???????state->last_updated = jiffies;
> > +}
> > +
> > +#endif /* __PECI_HWMON_COMMON_H */
> > diff --git a/drivers/hwmon/peci/cputemp.c b/drivers/hwmon/peci/cputemp.c
> > new file mode 100644
> > index 000000000000..9c6858a9fb6d
> > --- /dev/null
> > +++ b/drivers/hwmon/peci/cputemp.c
> > @@ -0,0 +1,591 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +// Copyright (c) 2018-2021 Intel Corporation
> > +
> > +#include <linux/auxiliary_bus.h>
> > +#include <linux/bitfield.h>
> > +#include <linux/bitops.h>
> > +#include <linux/hwmon.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/module.h>
> > +#include <linux/peci.h>
> > +#include <linux/peci-cpu.h>
> > +#include <linux/units.h>
> > +#include <linux/x86/intel-family.h>
> > +
> > +#include "common.h"
> > +
> > +#define CORE_NUMS_MAX??????????64
> > +
> > +#define BASE_CHANNEL_NUMS??????5
> > +#define CPUTEMP_CHANNEL_NUMS???(BASE_CHANNEL_NUMS + CORE_NUMS_MAX)
> > +
> > +#define TEMP_TARGET_FAN_TEMP_MASK??????GENMASK(15, 8)
> > +#define TEMP_TARGET_REF_TEMP_MASK??????GENMASK(23, 16)
> > +#define TEMP_TARGET_TJ_OFFSET_MASK?????GENMASK(29, 24)
> > +
> > +#define DTS_MARGIN_MASK????????????????GENMASK(15, 0)
> > +#define PCS_MODULE_TEMP_MASK???GENMASK(15, 0)
> > +
> > +#define DTS_FIXED_POINT_FRACTION???????64
> > +
> > +struct resolved_cores_reg {
> > +???????u8 bus;
> > +???????u8 dev;
> > +???????u8 func;
> > +???????u8 offset;
> > +};
> > +
> > +struct cpu_info {
> > +???????struct resolved_cores_reg *reg;
> > +???????u8 min_peci_revision;
> > +};
> > +
> > +struct peci_temp_target {
> > +???????s32 tcontrol;
> > +???????s32 tthrottle;
> > +???????s32 tjmax;
> > +???????struct peci_sensor_state state;
> > +};
> > +
> > +enum peci_temp_target_type {
> > +???????tcontrol_type,
> > +???????tthrottle_type,
> > +???????tjmax_type,
> > +???????crit_hyst_type,
> > +};
> > +
> > +struct peci_cputemp {
> > +???????struct peci_device *peci_dev;
> > +???????struct device *dev;
> > +???????const char *name;
> > +???????const struct cpu_info *gen_info;
> > +???????struct {
> > +???????????????struct peci_temp_target target;
> > +???????????????struct peci_sensor_data die;
> > +???????????????struct peci_sensor_data dts;
> > +???????????????struct peci_sensor_data core[CORE_NUMS_MAX];
> > +???????} temp;
> > +???????const char **coretemp_label;
> > +???????DECLARE_BITMAP(core_mask, CORE_NUMS_MAX);
> > +};
> > +
> > +enum cputemp_channels {
> > +???????channel_die,
> > +???????channel_dts,
> > +???????channel_tcontrol,
> > +???????channel_tthrottle,
> > +???????channel_tjmax,
> > +???????channel_core,
> > +};
> > +
> > +static const char * const cputemp_label[BASE_CHANNEL_NUMS] = {
> > +???????"Die",
> > +???????"DTS",
> > +???????"Tcontrol",
> > +???????"Tthrottle",
> > +???????"Tjmax",
> > +};
> > +
> > +static int update_temp_target(struct peci_cputemp *priv)
> > +{
> > +???????s32 tthrottle_offset, tcontrol_margin;
> > +???????u32 pcs;
> > +???????int ret;
> > +
> > +???????if (!peci_sensor_need_update(&priv->temp.target.state))
> > +???????????????return 0;
> > +
> > +???????ret = peci_pcs_read(priv->peci_dev, PECI_PCS_TEMP_TARGET, 0, &pcs);
> > +???????if (ret)
> > +???????????????return ret;
> > +
> > +???????priv->temp.target.tjmax =
> > +???????????????FIELD_GET(TEMP_TARGET_REF_TEMP_MASK, pcs) *
> > MILLIDEGREE_PER_DEGREE;
> > +
> > +???????tcontrol_margin = FIELD_GET(TEMP_TARGET_FAN_TEMP_MASK, pcs);
> > +???????tcontrol_margin = sign_extend32(tcontrol_margin, 7) *
> > MILLIDEGREE_PER_DEGREE;
> > +???????priv->temp.target.tcontrol = priv->temp.target.tjmax -
> > tcontrol_margin;
> > +
> > +???????tthrottle_offset = FIELD_GET(TEMP_TARGET_TJ_OFFSET_MASK, pcs) *
> > MILLIDEGREE_PER_DEGREE;
> > +???????priv->temp.target.tthrottle = priv->temp.target.tjmax -
> > tthrottle_offset;
> > +
> > +???????peci_sensor_mark_updated(&priv->temp.target.state);
> > +
> > +???????return 0;
> > +}
> > +
> > +static int get_temp_target(struct peci_cputemp *priv, enum
> > peci_temp_target_type type, long *val)
> > +{
> > +???????int ret;
> > +
> > +???????mutex_lock(&priv->temp.target.state.lock);
> > +
> > +???????ret = update_temp_target(priv);
> > +???????if (ret)
> > +???????????????goto unlock;
> > +
> > +???????switch (type) {
> > +???????case tcontrol_type:
> > +???????????????*val = priv->temp.target.tcontrol;
> > +???????????????break;
> > +???????case tthrottle_type:
> > +???????????????*val = priv->temp.target.tthrottle;
> > +???????????????break;
> > +???????case tjmax_type:
> > +???????????????*val = priv->temp.target.tjmax;
> > +???????????????break;
> > +???????case crit_hyst_type:
> > +???????????????*val = priv->temp.target.tjmax - priv->temp.target.tcontrol;
> > +???????????????break;
> > +???????default:
> > +???????????????ret = -EOPNOTSUPP;
> > +???????????????break;
> > +???????}
> > +unlock:
> > +???????mutex_unlock(&priv->temp.target.state.lock);
> > +
> > +???????return ret;
> > +}
> > +
> > +/*
> > + * Processors return a value of DTS reading in S10.6 fixed point format
> > + * (16 bits: 10-bit signed magnitude, 6-bit fraction).
> > + * Error codes:
> > + *?? 0x8000: General sensor error
> > + *?? 0x8001: Reserved
> > + *?? 0x8002: Underflow on reading value
> > + *?? 0x8003-0x81ff: Reserved
> > + */
> > +static bool dts_valid(s32 val)
> > +{
> > +???????return val < 0x8000 || val > 0x81ff;
> > +}
> > +
> > +static s32 dts_to_millidegree(s32 val)
> > +{
> > +???????return sign_extend32(val, 15) * MILLIDEGREE_PER_DEGREE /
> > DTS_FIXED_POINT_FRACTION;
> > +}
> > +
> > +static int get_die_temp(struct peci_cputemp *priv, long *val)
> > +{
> > +???????long tjmax;
> > +???????s16 temp;
> > +???????int ret;
> > +
> > +???????mutex_lock(&priv->temp.die.state.lock);
> > +???????if (!peci_sensor_need_update(&priv->temp.die.state))
> > +???????????????goto skip_update;
> > +
> > +???????ret = peci_temp_read(priv->peci_dev, &temp);
> > +???????if (ret)
> > +???????????????goto err_unlock;
> > +
> > +???????if (!dts_valid(temp)) {
> > +???????????????ret = -EIO;
> > +???????????????goto err_unlock;
> > +???????}
> > +
> > +???????ret = get_temp_target(priv, tjmax_type, &tjmax);
> > +???????if (ret)
> > +???????????????goto err_unlock;
> > +
> > +???????priv->temp.die.value = (s32)tjmax + dts_to_millidegree(temp);
> > +
> > +???????peci_sensor_mark_updated(&priv->temp.die.state);
> > +
> > +skip_update:
> > +???????*val = priv->temp.die.value;
> > +???????mutex_unlock(&priv->temp.die.state.lock);
> > +
> > +???????return 0;
> > +
> > +err_unlock:
> > +???????mutex_unlock(&priv->temp.die.state.lock);
> > +???????return ret;
> > +}
> > +
> > +static int get_dts(struct peci_cputemp *priv, long *val)
> > +{
> > +???????s32 dts_margin;
> > +???????long tcontrol;
> > +???????u32 pcs;
> > +???????int ret;
> > +
> > +???????mutex_lock(&priv->temp.dts.state.lock);
> > +???????if (!peci_sensor_need_update(&priv->temp.dts.state))
> > +???????????????goto skip_update;
> > +
> > +???????ret = peci_pcs_read(priv->peci_dev, PECI_PCS_THERMAL_MARGIN, 0,
> > &pcs);
> > +???????if (ret)
> > +???????????????goto err_unlock;
> > +
> > +???????dts_margin = FIELD_GET(DTS_MARGIN_MASK, pcs);
> > +???????if (!dts_valid(dts_margin)) {
> > +???????????????ret = -EIO;
> > +???????????????goto err_unlock;
> > +???????}
> > +
> > +???????ret = get_temp_target(priv, tcontrol_type, &tcontrol);
> > +???????if (ret)
> > +???????????????goto err_unlock;
> > +
> > +???????/* Note that the tcontrol should be available before calling it */
> > +???????priv->temp.dts.value = (s32)tcontrol -
> > dts_to_millidegree(dts_margin);
> > +
> > +???????peci_sensor_mark_updated(&priv->temp.dts.state);
> > +
> > +skip_update:
> > +???????*val = priv->temp.dts.value;
> > +???????mutex_unlock(&priv->temp.dts.state.lock);
> > +
> > +???????return 0;
> > +
> > +err_unlock:
> > +???????mutex_unlock(&priv->temp.dts.state.lock);
> > +???????return ret;
> 
> Simplify (see below)
> 
> > +}
> > +
> > +static int get_core_temp(struct peci_cputemp *priv, int core_index, long
> > *val)
> > +{
> > +???????s32 core_dts_margin;
> > +???????long tjmax;
> > +???????u32 pcs;
> > +???????int ret;
> 
> ????????int ret = 0;
> 
> to handle simplification below.
> 
> > +
> > +???????mutex_lock(&priv->temp.core[core_index].state.lock);
> > +???????if (!peci_sensor_need_update(&priv->temp.core[core_index].state))
> > +???????????????goto skip_update;
> > +
> > +???????ret = peci_pcs_read(priv->peci_dev, PECI_PCS_MODULE_TEMP,
> > core_index, &pcs);
> > +???????if (ret)
> > +???????????????goto err_unlock;
> > +
> > +???????core_dts_margin = FIELD_GET(PCS_MODULE_TEMP_MASK, pcs);
> > +???????if (!dts_valid(core_dts_margin)) {
> > +???????????????ret = -EIO;
> > +???????????????goto err_unlock;
> > +???????}
> > +
> > +???????ret = get_temp_target(priv, tjmax_type, &tjmax);
> > +???????if (ret)
> > +???????????????goto err_unlock;
> > +
> > +???????/* Note that the tjmax should be available before calling it */
> > +???????priv->temp.core[core_index].value = (s32)tjmax +
> > dts_to_millidegree(core_dts_margin);
> > +
> > +???????peci_sensor_mark_updated(&priv->temp.core[core_index].state);
> > +
> > +skip_update:
> > +???????*val = priv->temp.core[core_index].value;
> > +???????mutex_unlock(&priv->temp.core[core_index].state.lock);
> > +
> > +???????return 0;
> > +
> > +err_unlock:
> > +???????mutex_unlock(&priv->temp.core[core_index].state.lock);
> > +???????return ret;
> 
> Simplify:
> 
> skip_update:
> ????????*val = priv->temp.core[core_index].value;
> err_unlock:
> ????????mutex_unlock(&priv->temp.core[core_index].state.lock);
> ????????return ret;

Sure, I'll use the same pattern in other places as well.

Thank you
-Iwona

> 
> > +}
> > +
> > +static int cputemp_read_string(struct device *dev, enum hwmon_sensor_types
> > type,
> > +????????????????????????????? u32 attr, int channel, const char **str)
> > +{
> > +???????struct peci_cputemp *priv = dev_get_drvdata(dev);
> > +
> > +???????if (attr != hwmon_temp_label)
> > +???????????????return -EOPNOTSUPP;
> > +
> > +???????*str = channel < channel_core ?
> > +???????????????cputemp_label[channel] : priv->coretemp_label[channel -
> > channel_core];
> > +
> > +???????return 0;
> > +}
> > +
> > +static int cputemp_read(struct device *dev, enum hwmon_sensor_types type,
> > +???????????????????????u32 attr, int channel, long *val)
> > +{
> > +???????struct peci_cputemp *priv = dev_get_drvdata(dev);
> > +
> > +???????switch (attr) {
> > +???????case hwmon_temp_input:
> > +???????????????switch (channel) {
> > +???????????????case channel_die:
> > +???????????????????????return get_die_temp(priv, val);
> > +???????????????case channel_dts:
> > +???????????????????????return get_dts(priv, val);
> > +???????????????case channel_tcontrol:
> > +???????????????????????return get_temp_target(priv, tcontrol_type, val);
> > +???????????????case channel_tthrottle:
> > +???????????????????????return get_temp_target(priv, tthrottle_type, val);
> > +???????????????case channel_tjmax:
> > +???????????????????????return get_temp_target(priv, tjmax_type, val);
> > +???????????????default:
> > +???????????????????????return get_core_temp(priv, channel - channel_core,
> > val);
> > +???????????????}
> > +???????????????break;
> > +???????case hwmon_temp_max:
> > +???????????????return get_temp_target(priv, tcontrol_type, val);
> > +???????case hwmon_temp_crit:
> > +???????????????return get_temp_target(priv, tjmax_type, val);
> > +???????case hwmon_temp_crit_hyst:
> > +???????????????return get_temp_target(priv, crit_hyst_type, val);
> > +???????default:
> > +???????????????return -EOPNOTSUPP;
> > +???????}
> > +
> > +???????return 0;
> > +}
> > +
> > +static umode_t cputemp_is_visible(const void *data, enum hwmon_sensor_types
> > type,
> > +???????????????????????????????? u32 attr, int channel)
> > +{
> > +???????const struct peci_cputemp *priv = data;
> > +
> > +???????if (channel > CPUTEMP_CHANNEL_NUMS)
> > +???????????????return 0;
> > +
> > +???????if (channel < channel_core)
> > +???????????????return 0444;
> > +
> > +???????if (test_bit(channel - channel_core, priv->core_mask))
> > +???????????????return 0444;
> > +
> > +???????return 0;
> > +}
> > +
> > +static int init_core_mask(struct peci_cputemp *priv)
> > +{
> > +???????struct peci_device *peci_dev = priv->peci_dev;
> > +???????struct resolved_cores_reg *reg = priv->gen_info->reg;
> > +???????u64 core_mask;
> > +???????u32 data;
> > +???????int ret;
> > +
> > +???????/* Get the RESOLVED_CORES register value */
> > +???????switch (peci_dev->info.model) {
> > +???????case INTEL_FAM6_ICELAKE_X:
> > +???????case INTEL_FAM6_ICELAKE_D:
> > +???????????????ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg-
> > >dev,
> > +??????????????????????????????????????????? reg->func, reg->offset + 4,
> > &data);
> > +???????????????if (ret)
> > +???????????????????????return ret;
> > +
> > +???????????????core_mask = (u64)data << 32;
> > +
> > +???????????????ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg-
> > >dev,
> > +??????????????????????????????????????????? reg->func, reg->offset, &data);
> > +???????????????if (ret)
> > +???????????????????????return ret;
> > +
> > +???????????????core_mask |= data;
> > +
> > +???????????????break;
> > +???????default:
> > +???????????????ret = peci_pci_local_read(peci_dev, reg->bus, reg->dev,
> > +???????????????????????????????????????? reg->func, reg->offset, &data);
> > +???????????????if (ret)
> > +???????????????????????return ret;
> > +
> > +???????????????core_mask = data;
> > +
> > +???????????????break;
> > +???????}
> > +
> > +???????if (!core_mask)
> > +???????????????return -EIO;
> > +
> > +???????bitmap_from_u64(priv->core_mask, core_mask);
> > +
> > +???????return 0;
> > +}
> > +
> > +static int create_temp_label(struct peci_cputemp *priv)
> > +{
> > +???????unsigned long core_max = find_last_bit(priv->core_mask,
> > CORE_NUMS_MAX);
> > +???????int i;
> > +
> > +???????priv->coretemp_label = devm_kzalloc(priv->dev, core_max *
> > sizeof(char *), GFP_KERNEL);
> > +???????if (!priv->coretemp_label)
> > +???????????????return -ENOMEM;
> > +
> > +???????for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX) {
> > +???????????????priv->coretemp_label[i] = devm_kasprintf(priv->dev,
> > GFP_KERNEL, "Core %d", i);
> > +???????????????if (!priv->coretemp_label[i])
> > +???????????????????????return -ENOMEM;
> > +???????}
> > +
> > +???????return 0;
> > +}
> > +
> > +static void check_resolved_cores(struct peci_cputemp *priv)
> > +{
> > +???????/*
> > +??????? * Failure to resolve cores is non-critical, we're still able to
> > +??????? * provide other sensor data.
> > +??????? */
> > +
> > +???????if (init_core_mask(priv))
> > +???????????????return;
> > +
> > +???????if (create_temp_label(priv))
> > +???????????????bitmap_zero(priv->core_mask, CORE_NUMS_MAX);
> > +}
> > +
> > +static void sensor_init(struct peci_cputemp *priv)
> > +{
> > +???????int i;
> > +
> > +???????mutex_init(&priv->temp.target.state.lock);
> > +???????mutex_init(&priv->temp.die.state.lock);
> > +???????mutex_init(&priv->temp.dts.state.lock);
> > +
> > +???????for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX)
> > +???????????????mutex_init(&priv->temp.core[i].state.lock);
> > +}
> > +
> > +static const struct hwmon_ops peci_cputemp_ops = {
> > +???????.is_visible = cputemp_is_visible,
> > +???????.read_string = cputemp_read_string,
> > +???????.read = cputemp_read,
> > +};
> > +
> > +static const u32 peci_cputemp_temp_channel_config[] = {
> > +???????/* Die temperature */
> > +???????HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
> > HWMON_T_CRIT_HYST,
> > +???????/* DTS margin */
> > +???????HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
> > HWMON_T_CRIT_HYST,
> > +???????/* Tcontrol temperature */
> > +???????HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_CRIT,
> > +???????/* Tthrottle temperature */
> > +???????HWMON_T_LABEL | HWMON_T_INPUT,
> > +???????/* Tjmax temperature */
> > +???????HWMON_T_LABEL | HWMON_T_INPUT,
> > +???????/* Core temperature - for all core channels */
> > +???????[channel_core ... CPUTEMP_CHANNEL_NUMS - 1] = HWMON_T_LABEL |
> > HWMON_T_INPUT,
> > +???????0
> > +};
> > +
> > +static const struct hwmon_channel_info peci_cputemp_temp_channel = {
> > +???????.type = hwmon_temp,
> > +???????.config = peci_cputemp_temp_channel_config,
> > +};
> > +
> > +static const struct hwmon_channel_info *peci_cputemp_info[] = {
> > +???????&peci_cputemp_temp_channel,
> > +???????NULL
> > +};
> > +
> > +static const struct hwmon_chip_info peci_cputemp_chip_info = {
> > +???????.ops = &peci_cputemp_ops,
> > +???????.info = peci_cputemp_info,
> > +};
> > +
> > +static int peci_cputemp_probe(struct auxiliary_device *adev,
> > +???????????????????????????? const struct auxiliary_device_id *id)
> > +{
> > +???????struct device *dev = &adev->dev;
> > +???????struct peci_device *peci_dev = to_peci_device(dev->parent);
> > +???????struct peci_cputemp *priv;
> > +???????struct device *hwmon_dev;
> > +
> > +???????priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +???????if (!priv)
> > +???????????????return -ENOMEM;
> > +
> > +???????priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_cputemp.cpu%d",
> > +?????????????????????????????????? peci_dev->info.socket_id);
> > +???????if (!priv->name)
> > +???????????????return -ENOMEM;
> > +
> > +???????priv->dev = dev;
> > +???????priv->peci_dev = peci_dev;
> > +???????priv->gen_info = (const struct cpu_info *)id->driver_data;
> > +
> > +???????/*
> > +??????? * This is just a sanity check. Since we're using commands that are
> > +??????? * guaranteed to be supported on a given platform, we should never
> > see
> > +??????? * revision lower than expected.
> > +??????? */
> > +???????if (peci_dev->info.peci_revision < priv->gen_info-
> > >min_peci_revision)
> > +???????????????dev_warn(priv->dev,
> > +??????????????????????? "Unexpected PECI revision %#x, some features may be
> > unavailable\n",
> > +??????????????????????? peci_dev->info.peci_revision);
> > +
> > +???????check_resolved_cores(priv);
> > +
> > +???????sensor_init(priv);
> > +
> > +???????hwmon_dev = devm_hwmon_device_register_with_info(priv->dev, priv-
> > >name,
> > +??????????????????????????????????????????????????????? priv,
> > &peci_cputemp_chip_info, NULL);
> > +
> > +???????return PTR_ERR_OR_ZERO(hwmon_dev);
> > +}
> > +
> > +/*
> > + * RESOLVED_CORES PCI configuration register may have different location on
> > + * different platforms.
> > + */
> > +static struct resolved_cores_reg resolved_cores_reg_hsx = {
> > +???????.bus = 1,
> > +???????.dev = 30,
> > +???????.func = 3,
> > +???????.offset = 0xb4,
> > +};
> > +
> > +static struct resolved_cores_reg resolved_cores_reg_icx = {
> > +???????.bus = 14,
> > +???????.dev = 30,
> > +???????.func = 3,
> > +???????.offset = 0xd0,
> > +};
> > +
> > +static const struct cpu_info cpu_hsx = {
> > +???????.reg????????????= &resolved_cores_reg_hsx,
> > +???????.min_peci_revision = 0x33,
> > +};
> > +
> > +static const struct cpu_info cpu_icx = {
> > +???????.reg????????????= &resolved_cores_reg_icx,
> > +???????.min_peci_revision = 0x40,
> > +};
> > +
> > +static const struct auxiliary_device_id peci_cputemp_ids[] = {
> > +???????{
> > +???????????????.name = "peci_cpu.cputemp.hsx",
> > +???????????????.driver_data = (kernel_ulong_t)&cpu_hsx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.cputemp.bdx",
> > +???????????????.driver_data = (kernel_ulong_t)&cpu_hsx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.cputemp.bdxd",
> > +???????????????.driver_data = (kernel_ulong_t)&cpu_hsx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.cputemp.skx",
> > +???????????????.driver_data = (kernel_ulong_t)&cpu_hsx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.cputemp.icx",
> > +???????????????.driver_data = (kernel_ulong_t)&cpu_icx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.cputemp.icxd",
> > +???????????????.driver_data = (kernel_ulong_t)&cpu_icx,
> > +???????},
> > +???????{ }
> > +};
> > +MODULE_DEVICE_TABLE(auxiliary, peci_cputemp_ids);
> > +
> > +static struct auxiliary_driver peci_cputemp_driver = {
> > +???????.probe??????????= peci_cputemp_probe,
> > +???????.id_table???????= peci_cputemp_ids,
> > +};
> > +
> > +module_auxiliary_driver(peci_cputemp_driver);
> > +
> > +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
> > +MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
> > +MODULE_DESCRIPTION("PECI cputemp driver");
> > +MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS(PECI_CPU);
> > 
> 


From iwona.winiarska at intel.com  Wed Aug  4 03:46:06 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Wed, 4 Aug 2021 10:46:06 +0000
Subject: [PATCH v2 13/15] hwmon: peci: Add dimmtemp driver
In-Reply-To: <20210803153937.GA337938@roeck-us.net>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-14-iwona.winiarska@intel.com>
 <20210803153937.GA337938@roeck-us.net>
Message-ID: <a576f7075625a476c613b5feb2c4c7033d6c0375.camel@intel.com>

On Tue, 2021-08-03 at 08:39 -0700, Guenter Roeck wrote:
> On Tue, Aug 03, 2021 at 01:31:32PM +0200, Iwona Winiarska wrote:
> > Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that
> > are accessible via the processor PECI interface.
> > 
> > The main use case for the driver (and PECI interface) is out-of-band
> > management, where we're able to obtain thermal readings from an external
> > entity connected with PECI, e.g. BMC on server platforms.
> > 
> > Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> > ---
> > Note that the timeout was completely removed - we're going to probe
> > for detected DIMMs every 5 seconds until we reach "stable" state of
> > either getting correct DIMM data or getting all -EINVAL (which
> > suggest that the CPU doesn't have any DIMMs).
> > 
> > ?drivers/hwmon/peci/Kconfig??? |? 13 +
> > ?drivers/hwmon/peci/Makefile?? |?? 2 +
> > ?drivers/hwmon/peci/dimmtemp.c | 614 ++++++++++++++++++++++++++++++++++
> > ?3 files changed, 629 insertions(+)
> > ?create mode 100644 drivers/hwmon/peci/dimmtemp.c
> > 
> > diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
> > index e10eed68d70a..9d32a57badfe 100644
> > --- a/drivers/hwmon/peci/Kconfig
> > +++ b/drivers/hwmon/peci/Kconfig
> > @@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP
> > ????????? This driver can also be built as a module. If so, the module
> > ????????? will be called peci-cputemp.
> > ?
> > +config SENSORS_PECI_DIMMTEMP
> > +???????tristate "PECI DIMM temperature monitoring client"
> > +???????depends on PECI
> > +???????select SENSORS_PECI
> > +???????select PECI_CPU
> > +???????help
> > +???????? If you say yes here you get support for the generic Intel PECI
> > hwmon
> > +???????? driver which provides Temperature Sensor on DIMM readings that are
> > +???????? accessible via the processor PECI interface.
> > +
> > +???????? This driver can also be built as a module. If so, the module
> > +???????? will be called peci-dimmtemp.
> > +
> > ?config SENSORS_PECI
> > ????????tristate
> > diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
> > index e8a0ada5ab1f..191cfa0227f3 100644
> > --- a/drivers/hwmon/peci/Makefile
> > +++ b/drivers/hwmon/peci/Makefile
> > @@ -1,5 +1,7 @@
> > ?# SPDX-License-Identifier: GPL-2.0-only
> > ?
> > ?peci-cputemp-y := cputemp.o
> > +peci-dimmtemp-y := dimmtemp.o
> > ?
> > ?obj-$(CONFIG_SENSORS_PECI_CPUTEMP)?????+= peci-cputemp.o
> > +obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)????+= peci-dimmtemp.o
> > diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c
> > new file mode 100644
> > index 000000000000..6264c29bb6c0
> > --- /dev/null
> > +++ b/drivers/hwmon/peci/dimmtemp.c
> > @@ -0,0 +1,614 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +// Copyright (c) 2018-2021 Intel Corporation
> > +
> > +#include <linux/auxiliary_bus.h>
> > +#include <linux/bitfield.h>
> > +#include <linux/bitops.h>
> > +#include <linux/hwmon.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/module.h>
> > +#include <linux/peci.h>
> > +#include <linux/peci-cpu.h>
> > +#include <linux/units.h>
> > +#include <linux/workqueue.h>
> > +#include <linux/x86/intel-family.h>
> > +
> > +#include "common.h"
> > +
> > +#define DIMM_MASK_CHECK_DELAY_JIFFIES??msecs_to_jiffies(5000)
> > +
> > +/* Max number of channel ranks and DIMM index per channel */
> > +#define CHAN_RANK_MAX_ON_HSX???8
> > +#define DIMM_IDX_MAX_ON_HSX????3
> > +#define CHAN_RANK_MAX_ON_BDX???4
> > +#define DIMM_IDX_MAX_ON_BDX????3
> > +#define CHAN_RANK_MAX_ON_BDXD??2
> > +#define DIMM_IDX_MAX_ON_BDXD???2
> > +#define CHAN_RANK_MAX_ON_SKX???6
> > +#define DIMM_IDX_MAX_ON_SKX????2
> > +#define CHAN_RANK_MAX_ON_ICX???8
> > +#define DIMM_IDX_MAX_ON_ICX????2
> > +#define CHAN_RANK_MAX_ON_ICXD??4
> > +#define DIMM_IDX_MAX_ON_ICXD???2
> > +
> > +#define CHAN_RANK_MAX??????????CHAN_RANK_MAX_ON_HSX
> > +#define DIMM_IDX_MAX???????????DIMM_IDX_MAX_ON_HSX
> > +#define DIMM_NUMS_MAX??????????(CHAN_RANK_MAX * DIMM_IDX_MAX)
> > +
> > +#define CPU_SEG_MASK???????????GENMASK(23, 16)
> > +#define GET_CPU_SEG(x)?????????(((x) & CPU_SEG_MASK) >> 16)
> > +#define CPU_BUS_MASK???????????GENMASK(7, 0)
> > +#define GET_CPU_BUS(x)?????????((x) & CPU_BUS_MASK)
> > +
> > +#define DIMM_TEMP_MAX??????????GENMASK(15, 8)
> > +#define DIMM_TEMP_CRIT?????????GENMASK(23, 16)
> > +#define GET_TEMP_MAX(x)????????????????(((x) & DIMM_TEMP_MAX) >> 8)
> > +#define GET_TEMP_CRIT(x)???????(((x) & DIMM_TEMP_CRIT) >> 16)
> > +
> > +struct peci_dimmtemp;
> > +
> > +struct dimm_info {
> > +???????int chan_rank_max;
> > +???????int dimm_idx_max;
> > +???????u8 min_peci_revision;
> > +???????int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order,
> > +????????????????????????????? int chan_rank, u32 *data);
> > +};
> > +
> > +struct peci_dimm_thresholds {
> > +???????long temp_max;
> > +???????long temp_crit;
> > +???????struct peci_sensor_state state;
> > +};
> > +
> > +enum peci_dimm_threshold_type {
> > +???????temp_max_type,
> > +???????temp_crit_type,
> > +};
> > +
> > +struct peci_dimmtemp {
> > +???????struct peci_device *peci_dev;
> > +???????struct device *dev;
> > +???????const char *name;
> > +???????const struct dimm_info *gen_info;
> > +???????struct delayed_work detect_work;
> > +???????struct {
> > +???????????????struct peci_sensor_data temp;
> > +???????????????struct peci_dimm_thresholds thresholds;
> > +???????} dimm[DIMM_NUMS_MAX];
> > +???????char **dimmtemp_label;
> > +???????DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX);
> > +};
> > +
> > +static u8 __dimm_temp(u32 reg, int dimm_order)
> > +{
> > +???????return (reg >> (dimm_order * 8)) & 0xff;
> > +}
> > +
> > +static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long
> > *val)
> > +{
> > +???????int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
> > +???????int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
> > +???????u32 data;
> > +???????int ret;
> 
> ????????int ret = 0;
> 
> > +
> > +???????mutex_lock(&priv->dimm[dimm_no].temp.state.lock);
> > +???????if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state))
> > +???????????????goto skip_update;
> > +
> > +???????ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP,
> > chan_rank, &data);
> > +???????if (ret) {
> > +???????????????mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
> > +???????????????return ret;
> > +???????}
> 
> ????????if (ret)
> ????????????????goto unlock;
> 
> > +
> > +???????priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) *
> > MILLIDEGREE_PER_DEGREE;
> > +
> > +???????peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state);
> > +
> > +skip_update:
> > +???????*val = priv->dimm[dimm_no].temp.value;
> 
> unlock:
> > +???????mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
> > +???????return 0;
> 
> ????????return ret;

Ack.

> 
> > +}
> > +
> > +static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
> > +{
> > +???????int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
> > +???????int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
> > +???????u32 data;
> > +???????int ret;
> > +
> > +???????if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state))
> > +???????????????return 0;
> > +
> > +???????ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank,
> > &data);
> > +???????if (ret == -ENODATA) /* Use default or previous value */
> > +???????????????return 0;
> > +???????if (ret)
> > +???????????????return ret;
> > +
> > +???????priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) *
> > MILLIDEGREE_PER_DEGREE;
> > +???????priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) *
> > MILLIDEGREE_PER_DEGREE;
> > +
> > +???????peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state);
> > +
> > +???????return 0;
> > +}
> > +
> > +static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum
> > peci_dimm_threshold_type type,
> > +????????????????????????????? int dimm_no, long *val)
> > +{
> > +???????int ret;
> > +
> > +???????mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock);
> > +???????ret = update_thresholds(priv, dimm_no);
> > +???????if (ret)
> > +???????????????goto unlock;
> > +
> > +???????switch (type) {
> > +???????case temp_max_type:
> > +???????????????*val = priv->dimm[dimm_no].thresholds.temp_max;
> > +???????????????break;
> > +???????case temp_crit_type:
> > +???????????????*val = priv->dimm[dimm_no].thresholds.temp_crit;
> > +???????????????break;
> > +???????default:
> > +???????????????ret = -EOPNOTSUPP;
> > +???????????????break;
> > +???????}
> > +unlock:
> > +???????mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock);
> > +
> > +???????return ret;
> > +}
> > +
> > +static int dimmtemp_read_string(struct device *dev,
> > +???????????????????????????????enum hwmon_sensor_types type,
> > +???????????????????????????????u32 attr, int channel, const char **str)
> > +{
> > +???????struct peci_dimmtemp *priv = dev_get_drvdata(dev);
> > +
> > +???????if (attr != hwmon_temp_label)
> > +???????????????return -EOPNOTSUPP;
> > +
> > +???????*str = (const char *)priv->dimmtemp_label[channel];
> > +
> > +???????return 0;
> > +}
> > +
> > +static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type,
> > +??????????????????????? u32 attr, int channel, long *val)
> > +{
> > +???????struct peci_dimmtemp *priv = dev_get_drvdata(dev);
> > +
> > +???????switch (attr) {
> > +???????case hwmon_temp_input:
> > +???????????????return get_dimm_temp(priv, channel, val);
> > +???????case hwmon_temp_max:
> > +???????????????return get_dimm_thresholds(priv, temp_max_type, channel,
> > val);
> > +???????case hwmon_temp_crit:
> > +???????????????return get_dimm_thresholds(priv, temp_crit_type, channel,
> > val);
> > +???????default:
> > +???????????????break;
> > +???????}
> > +
> > +???????return -EOPNOTSUPP;
> > +}
> > +
> > +static umode_t dimmtemp_is_visible(const void *data, enum
> > hwmon_sensor_types type,
> > +????????????????????????????????? u32 attr, int channel)
> > +{
> > +???????const struct peci_dimmtemp *priv = data;
> > +
> > +???????if (test_bit(channel, priv->dimm_mask))
> > +???????????????return 0444;
> > +
> > +???????return 0;
> > +}
> > +
> > +static const struct hwmon_ops peci_dimmtemp_ops = {
> > +???????.is_visible = dimmtemp_is_visible,
> > +???????.read_string = dimmtemp_read_string,
> > +???????.read = dimmtemp_read,
> > +};
> > +
> > +static int check_populated_dimms(struct peci_dimmtemp *priv)
> > +{
> > +???????int chan_rank_max = priv->gen_info->chan_rank_max;
> > +???????int dimm_idx_max = priv->gen_info->dimm_idx_max;
> > +???????u32 chan_rank_empty = 0;
> > +???????u64 dimm_mask = 0;
> > +???????int chan_rank, dimm_idx, ret;
> > +???????u32 pcs;
> > +
> > +???????BUILD_BUG_ON(CHAN_RANK_MAX > 32);
> > +???????BUILD_BUG_ON(DIMM_NUMS_MAX > 64);
> 
> I don't immediately see the value of those build bugs. What happens if
> CHAN_RANK_MAX > 32 or DIMM_NUMS_MAX > 64 ? Where do those limits come
> from ?

Supported HW doesn't come near the limit for now - it's just an "artificial"
limit imposed by variables we're using (u64 for dimm_mask and u32 for
chan_rank_empty).

> 
> > +???????if (chan_rank_max * dimm_idx_max > DIMM_NUMS_MAX) {
> > +???????????????WARN_ONCE(1, "Unsupported number of DIMMs");
> 
> Maybe display the values (chan_rank_max and dimm_idx_max).

Ok.

> 
> > +???????????????return -EINVAL;
> > +???????}
> > +
> > +???????for (chan_rank = 0; chan_rank < chan_rank_max; chan_rank++) {
> > +???????????????ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP,
> > chan_rank, &pcs);
> > +???????????????if (ret) {
> > +???????????????????????/*
> > +??????????????????????? * Overall, we expect either success or -EINVAL in
> > +??????????????????????? * order to determine whether DIMM is populated or
> > not.
> > +??????????????????????? * For anything else - we fall back to defering the
> 
> Why " - " ?

Hum... No idea after reading it now.
I'll drop it.

Thank you
-Iwona

> 
> > +??????????????????????? * detection to be performed at a later point in
> > time.
> > +??????????????????????? */
> > +???????????????????????if (ret == -EINVAL) {
> > +???????????????????????????????chan_rank_empty |= BIT(chan_rank);
> > +???????????????????????????????continue;
> > +???????????????????????}
> > +
> > +???????????????????????return -EAGAIN;
> > +???????????????}
> > +
> > +???????????????for (dimm_idx = 0; dimm_idx < dimm_idx_max; dimm_idx++)
> > +???????????????????????if (__dimm_temp(pcs, dimm_idx))
> > +???????????????????????????????dimm_mask |= BIT(chan_rank * dimm_idx_max +
> > dimm_idx);
> > +???????}
> > +
> > +???????/* If we got all -EINVALs, it means that the CPU doesn't have any
> > DIMMs. */
> > +???????if (chan_rank_empty == GENMASK(chan_rank_max - 1, 0))
> > +???????????????return -ENODEV;
> > +
> > +???????/*
> > +??????? * It's possible that memory training is not done yet. In this case
> > we
> > +??????? * defer the detection to be performed at a later point in time.
> > +??????? */
> > +???????if (!dimm_mask)
> > +???????????????return -EAGAIN;
> > +
> > +???????dev_dbg(priv->dev, "Scanned populated DIMMs: %#llx\n", dimm_mask);
> > +
> > +???????bitmap_from_u64(priv->dimm_mask, dimm_mask);
> > +
> > +???????return 0;
> > +}
> > +
> > +static int create_dimm_temp_label(struct peci_dimmtemp *priv, int chan)
> > +{
> > +???????int rank = chan / priv->gen_info->dimm_idx_max;
> > +???????int idx = chan % priv->gen_info->dimm_idx_max;
> > +
> > +???????priv->dimmtemp_label[chan] = devm_kasprintf(priv->dev, GFP_KERNEL,
> > +?????????????????????????????????????????????????? "DIMM %c%d", 'A' + rank,
> > +?????????????????????????????????????????????????? idx + 1);
> > +???????if (!priv->dimmtemp_label[chan])
> > +???????????????return -ENOMEM;
> > +
> > +???????return 0;
> > +}
> > +
> > +static const u32 peci_dimmtemp_temp_channel_config[] = {
> > +???????[0 ... DIMM_NUMS_MAX - 1] = HWMON_T_LABEL | HWMON_T_INPUT |
> > HWMON_T_MAX | HWMON_T_CRIT,
> > +???????0
> > +};
> > +
> > +static const struct hwmon_channel_info peci_dimmtemp_temp_channel = {
> > +???????.type = hwmon_temp,
> > +???????.config = peci_dimmtemp_temp_channel_config,
> > +};
> > +
> > +static const struct hwmon_channel_info *peci_dimmtemp_temp_info[] = {
> > +???????&peci_dimmtemp_temp_channel,
> > +???????NULL
> > +};
> > +
> > +static const struct hwmon_chip_info peci_dimmtemp_chip_info = {
> > +???????.ops = &peci_dimmtemp_ops,
> > +???????.info = peci_dimmtemp_temp_info,
> > +};
> > +
> > +static int create_dimm_temp_info(struct peci_dimmtemp *priv)
> > +{
> > +???????int ret, i, channels;
> > +???????struct device *dev;
> > +
> > +???????/*
> > +??????? * We expect to either find populated DIMMs and carry on with
> > creating
> > +??????? * sensors, or find out that there are no DIMMs populated.
> > +??????? * All other states mean that the platform never reached the state
> > that
> > +??????? * allows to check DIMM state - causing us to retry later on.
> > +??????? */
> > +???????ret = check_populated_dimms(priv);
> > +???????if (ret == -ENODEV) {
> > +???????????????dev_dbg(priv->dev, "No DIMMs found\n");
> > +???????????????return 0;
> > +???????} else if (ret) {
> > +???????????????schedule_delayed_work(&priv->detect_work,
> > DIMM_MASK_CHECK_DELAY_JIFFIES);
> > +???????????????dev_dbg(priv->dev, "Deferred populating DIMM temp info\n");
> > +???????????????return ret;
> > +???????}
> > +
> > +???????channels = priv->gen_info->chan_rank_max * priv->gen_info-
> > >dimm_idx_max;
> > +
> > +???????priv->dimmtemp_label = devm_kzalloc(priv->dev, channels *
> > sizeof(char *), GFP_KERNEL);
> > +???????if (!priv->dimmtemp_label)
> > +???????????????return -ENOMEM;
> > +
> > +???????for_each_set_bit(i, priv->dimm_mask, DIMM_NUMS_MAX) {
> > +???????????????ret = create_dimm_temp_label(priv, i);
> > +???????????????if (ret)
> > +???????????????????????return ret;
> > +???????????????mutex_init(&priv->dimm[i].thresholds.state.lock);
> > +???????????????mutex_init(&priv->dimm[i].temp.state.lock);
> > +???????}
> > +
> > +???????dev = devm_hwmon_device_register_with_info(priv->dev, priv->name,
> > priv,
> > +????????????????????????????????????????????????? &peci_dimmtemp_chip_info,
> > NULL);
> > +???????if (IS_ERR(dev)) {
> > +???????????????dev_err(priv->dev, "Failed to register hwmon device\n");
> > +???????????????return PTR_ERR(dev);
> > +???????}
> > +
> > +???????dev_dbg(priv->dev, "%s: sensor '%s'\n", dev_name(dev), priv->name);
> > +
> > +???????return 0;
> > +}
> > +
> > +static void create_dimm_temp_info_delayed(struct work_struct *work)
> > +{
> > +???????struct peci_dimmtemp *priv = container_of(to_delayed_work(work),
> > +???????????????????????????????????????????????? struct peci_dimmtemp,
> > +???????????????????????????????????????????????? detect_work);
> > +???????int ret;
> > +
> > +???????ret = create_dimm_temp_info(priv);
> > +???????if (ret && ret != -EAGAIN)
> > +???????????????dev_err(priv->dev, "Failed to populate DIMM temp info\n");
> > +}
> > +
> > +static void remove_delayed_work(void *_priv)
> > +{
> > +???????struct peci_dimmtemp *priv = _priv;
> > +
> > +???????cancel_delayed_work_sync(&priv->detect_work);
> > +}
> > +
> > +static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct
> > auxiliary_device_id *id)
> > +{
> > +???????struct device *dev = &adev->dev;
> > +???????struct peci_device *peci_dev = to_peci_device(dev->parent);
> > +???????struct peci_dimmtemp *priv;
> > +???????int ret;
> > +
> > +???????priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +???????if (!priv)
> > +???????????????return -ENOMEM;
> > +
> > +???????priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_dimmtemp.cpu%d",
> > +?????????????????????????????????? peci_dev->info.socket_id);
> > +???????if (!priv->name)
> > +???????????????return -ENOMEM;
> > +
> > +???????priv->dev = dev;
> > +???????priv->peci_dev = peci_dev;
> > +???????priv->gen_info = (const struct dimm_info *)id->driver_data;
> > +
> > +???????/*
> > +??????? * This is just a sanity check. Since we're using commands that are
> > +??????? * guaranteed to be supported on a given platform, we should never
> > see
> > +??????? * revision lower than expected.
> > +??????? */
> > +???????if (peci_dev->info.peci_revision < priv->gen_info-
> > >min_peci_revision)
> > +???????????????dev_warn(priv->dev,
> > +??????????????????????? "Unexpected PECI revision %#x, some features may be
> > unavailable\n",
> > +??????????????????????? peci_dev->info.peci_revision);
> > +
> > +???????INIT_DELAYED_WORK(&priv->detect_work,
> > create_dimm_temp_info_delayed);
> > +
> > +???????ret = devm_add_action_or_reset(priv->dev, remove_delayed_work,
> > priv);
> > +???????if (ret)
> > +???????????????return ret;
> > +
> > +???????ret = create_dimm_temp_info(priv);
> > +???????if (ret && ret != -EAGAIN) {
> > +???????????????dev_err(dev, "Failed to populate DIMM temp info\n");
> > +???????????????return ret;
> > +???????}
> > +
> > +???????return 0;
> > +}
> > +
> > +static int
> > +read_thresholds_hsx(struct peci_dimmtemp *priv, int dimm_order, int
> > chan_rank, u32 *data)
> > +{
> > +???????u8 dev, func;
> > +???????u16 reg;
> > +???????int ret;
> > +
> > +???????/*
> > +??????? * Device 20, Function 0: IMC 0 channel 0 -> rank 0
> > +??????? * Device 20, Function 1: IMC 0 channel 1 -> rank 1
> > +??????? * Device 21, Function 0: IMC 0 channel 2 -> rank 2
> > +??????? * Device 21, Function 1: IMC 0 channel 3 -> rank 3
> > +??????? * Device 23, Function 0: IMC 1 channel 0 -> rank 4
> > +??????? * Device 23, Function 1: IMC 1 channel 1 -> rank 5
> > +??????? * Device 24, Function 0: IMC 1 channel 2 -> rank 6
> > +??????? * Device 24, Function 1: IMC 1 channel 3 -> rank 7
> > +??????? */
> > +???????dev = 20 + chan_rank / 2 + chan_rank / 4;
> > +???????func = chan_rank % 2;
> > +???????reg = 0x120 + dimm_order * 4;
> > +
> > +???????ret = peci_pci_local_read(priv->peci_dev, 1, dev, func, reg, data);
> > +???????if (ret)
> > +???????????????return ret;
> > +
> > +???????return 0;
> > +}
> > +
> > +static int
> > +read_thresholds_bdxd(struct peci_dimmtemp *priv, int dimm_order, int
> > chan_rank, u32 *data)
> > +{
> > +???????u8 dev, func;
> > +???????u16 reg;
> > +???????int ret;
> > +
> > +???????/*
> > +??????? * Device 10, Function 2: IMC 0 channel 0 -> rank 0
> > +??????? * Device 10, Function 6: IMC 0 channel 1 -> rank 1
> > +??????? * Device 12, Function 2: IMC 1 channel 0 -> rank 2
> > +??????? * Device 12, Function 6: IMC 1 channel 1 -> rank 3
> > +??????? */
> > +???????dev = 10 + chan_rank / 2 * 2;
> > +???????func = (chan_rank % 2) ? 6 : 2;
> > +???????reg = 0x120 + dimm_order * 4;
> > +
> > +???????ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
> > +???????if (ret)
> > +???????????????return ret;
> > +
> > +???????return 0;
> > +}
> > +
> > +static int
> > +read_thresholds_skx(struct peci_dimmtemp *priv, int dimm_order, int
> > chan_rank, u32 *data)
> > +{
> > +???????u8 dev, func;
> > +???????u16 reg;
> > +???????int ret;
> > +
> > +???????/*
> > +??????? * Device 10, Function 2: IMC 0 channel 0 -> rank 0
> > +??????? * Device 10, Function 6: IMC 0 channel 1 -> rank 1
> > +??????? * Device 11, Function 2: IMC 0 channel 2 -> rank 2
> > +??????? * Device 12, Function 2: IMC 1 channel 0 -> rank 3
> > +??????? * Device 12, Function 6: IMC 1 channel 1 -> rank 4
> > +??????? * Device 13, Function 2: IMC 1 channel 2 -> rank 5
> > +??????? */
> > +???????dev = 10 + chan_rank / 3 * 2 + (chan_rank % 3 == 2 ? 1 : 0);
> > +???????func = chan_rank % 3 == 1 ? 6 : 2;
> > +???????reg = 0x120 + dimm_order * 4;
> > +
> > +???????ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
> > +???????if (ret)
> > +???????????????return ret;
> > +
> > +???????return 0;
> > +}
> > +
> > +static int
> > +read_thresholds_icx(struct peci_dimmtemp *priv, int dimm_order, int
> > chan_rank, u32 *data)
> > +{
> > +???????u32 reg_val;
> > +???????u64 offset;
> > +???????int ret;
> > +???????u8 dev;
> > +
> > +???????ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd4,
> > &reg_val);
> > +???????if (ret || !(reg_val & BIT(31)))
> > +???????????????return -ENODATA; /* Use default or previous value */
> > +
> > +???????ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd0,
> > &reg_val);
> > +???????if (ret)
> > +???????????????return -ENODATA; /* Use default or previous value */
> > +
> > +???????/*
> > +??????? * Device 26, Offset 224e0: IMC 0 channel 0 -> rank 0
> > +??????? * Device 26, Offset 264e0: IMC 0 channel 1 -> rank 1
> > +??????? * Device 27, Offset 224e0: IMC 1 channel 0 -> rank 2
> > +??????? * Device 27, Offset 264e0: IMC 1 channel 1 -> rank 3
> > +??????? * Device 28, Offset 224e0: IMC 2 channel 0 -> rank 4
> > +??????? * Device 28, Offset 264e0: IMC 2 channel 1 -> rank 5
> > +??????? * Device 29, Offset 224e0: IMC 3 channel 0 -> rank 6
> > +??????? * Device 29, Offset 264e0: IMC 3 channel 1 -> rank 7
> > +??????? */
> > +???????dev = 26 + chan_rank / 2;
> > +???????offset = 0x224e0 + dimm_order * 4 + (chan_rank % 2) * 0x4000;
> > +
> > +???????ret = peci_mmio_read(priv->peci_dev, 0, GET_CPU_SEG(reg_val),
> > GET_CPU_BUS(reg_val),
> > +??????????????????????????? dev, 0, offset, data);
> > +???????if (ret)
> > +???????????????return ret;
> > +
> > +???????return 0;
> > +}
> > +
> > +static const struct dimm_info dimm_hsx = {
> > +???????.chan_rank_max??= CHAN_RANK_MAX_ON_HSX,
> > +???????.dimm_idx_max???= DIMM_IDX_MAX_ON_HSX,
> > +???????.min_peci_revision = 0x33,
> > +???????.read_thresholds = &read_thresholds_hsx,
> > +};
> > +
> > +static const struct dimm_info dimm_bdx = {
> > +???????.chan_rank_max??= CHAN_RANK_MAX_ON_BDX,
> > +???????.dimm_idx_max???= DIMM_IDX_MAX_ON_BDX,
> > +???????.min_peci_revision = 0x33,
> > +???????.read_thresholds = &read_thresholds_hsx,
> > +};
> > +
> > +static const struct dimm_info dimm_bdxd = {
> > +???????.chan_rank_max??= CHAN_RANK_MAX_ON_BDXD,
> > +???????.dimm_idx_max???= DIMM_IDX_MAX_ON_BDXD,
> > +???????.min_peci_revision = 0x33,
> > +???????.read_thresholds = &read_thresholds_bdxd,
> > +};
> > +
> > +static const struct dimm_info dimm_skx = {
> > +???????.chan_rank_max??= CHAN_RANK_MAX_ON_SKX,
> > +???????.dimm_idx_max???= DIMM_IDX_MAX_ON_SKX,
> > +???????.min_peci_revision = 0x33,
> > +???????.read_thresholds = &read_thresholds_skx,
> > +};
> > +
> > +static const struct dimm_info dimm_icx = {
> > +???????.chan_rank_max??= CHAN_RANK_MAX_ON_ICX,
> > +???????.dimm_idx_max???= DIMM_IDX_MAX_ON_ICX,
> > +???????.min_peci_revision = 0x40,
> > +???????.read_thresholds = &read_thresholds_icx,
> > +};
> > +
> > +static const struct dimm_info dimm_icxd = {
> > +???????.chan_rank_max??= CHAN_RANK_MAX_ON_ICXD,
> > +???????.dimm_idx_max???= DIMM_IDX_MAX_ON_ICXD,
> > +???????.min_peci_revision = 0x40,
> > +???????.read_thresholds = &read_thresholds_icx,
> > +};
> > +
> > +static const struct auxiliary_device_id peci_dimmtemp_ids[] = {
> > +???????{
> > +???????????????.name = "peci_cpu.dimmtemp.hsx",
> > +???????????????.driver_data = (kernel_ulong_t)&dimm_hsx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.dimmtemp.bdx",
> > +???????????????.driver_data = (kernel_ulong_t)&dimm_bdx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.dimmtemp.bdxd",
> > +???????????????.driver_data = (kernel_ulong_t)&dimm_bdxd,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.dimmtemp.skx",
> > +???????????????.driver_data = (kernel_ulong_t)&dimm_skx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.dimmtemp.icx",
> > +???????????????.driver_data = (kernel_ulong_t)&dimm_icx,
> > +???????},
> > +???????{
> > +???????????????.name = "peci_cpu.dimmtemp.icxd",
> > +???????????????.driver_data = (kernel_ulong_t)&dimm_icxd,
> > +???????},
> > +???????{ }
> > +};
> > +MODULE_DEVICE_TABLE(auxiliary, peci_dimmtemp_ids);
> > +
> > +static struct auxiliary_driver peci_dimmtemp_driver = {
> > +???????.probe??????????= peci_dimmtemp_probe,
> > +???????.id_table???????= peci_dimmtemp_ids,
> > +};
> > +
> > +module_auxiliary_driver(peci_dimmtemp_driver);
> > +
> > +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
> > +MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
> > +MODULE_DESCRIPTION("PECI dimmtemp driver");
> > +MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS(PECI_CPU);


From lukasz.luba at arm.com  Wed Aug  4 03:51:02 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Wed, 4 Aug 2021 11:51:02 +0100
Subject: [PATCH v2] cpufreq: arm_scmi: Fix error path when allocation
 failed
In-Reply-To: <20210803224145.zyr36sliwa7a67xf@bogus>
References: <20210803090744.12143-1-lukasz.luba@arm.com>
 <20210803224145.zyr36sliwa7a67xf@bogus>
Message-ID: <34c0a16b-4f82-8c78-9e29-63d462ea68b8@arm.com>



On 8/3/21 11:41 PM, Sudeep Holla wrote:
> On Tue, Aug 03, 2021 at 10:07:44AM +0100, Lukasz Luba wrote:
>> Stop the initialization when cpumask allocation failed and return an
>> error.
>>
> 
> Good catch!
> 
> Reviewed-by: Sudeep Holla <sudeep.holla at arm.com>
> 

Thank you for the review!


From lukasz.luba at arm.com  Wed Aug  4 03:51:56 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Wed, 4 Aug 2021 11:51:56 +0100
Subject: [PATCH v2] cpufreq: arm_scmi: Fix error path when allocation
 failed
In-Reply-To: <20210804040237.ssrba26jpe572mjf@vireshk-i7>
References: <20210803090744.12143-1-lukasz.luba@arm.com>
 <20210804040237.ssrba26jpe572mjf@vireshk-i7>
Message-ID: <c0679032-6405-1eab-9e2c-ae58faa88e6b@arm.com>



On 8/4/21 5:02 AM, Viresh Kumar wrote:
> On 03-08-21, 10:07, Lukasz Luba wrote:
>> Stop the initialization when cpumask allocation failed and return an
>> error.
>>
>> Fixes: 80a064dbd556 ("scmi-cpufreq: Get opp_shared_cpus from opp-v2 for EM")
>> Signed-off-by: Lukasz Luba <lukasz.luba at arm.com>
>> ---
>> changes:
>> v2:
>> - removed dev_warn() since it's not needed in this case
>> - adjusted the patch description
>>
>>   drivers/cpufreq/scmi-cpufreq.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
>> index ec9a87ca2dbb..75f818d04b48 100644
>> --- a/drivers/cpufreq/scmi-cpufreq.c
>> +++ b/drivers/cpufreq/scmi-cpufreq.c
>> @@ -134,7 +134,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
>>   	}
>>   
>>   	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL))
>> -		ret = -ENOMEM;
>> +		return -ENOMEM;
>>   
>>   	/* Obtain CPUs that share SCMI performance controls */
>>   	ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
> 
> Applied. Thanks.
> 

Thank you for taking it.


From paul.barker at sancloud.com  Wed Aug  4 03:52:21 2021
From: paul.barker at sancloud.com (Paul Barker)
Date: Wed, 4 Aug 2021 11:52:21 +0100
Subject: [PATCH v2 0/4] Add support for the SanCloud BBE Lite
In-Reply-To: <YP/J+YC6GFeH+I5j@atomide.com>
References: <20210720083928.10404-1-paul.barker@sancloud.com>
 <YP/J+YC6GFeH+I5j@atomide.com>
Message-ID: <20210804115221.5650e440.paul.barker@sancloud.com>

On Tue, 27 Jul 2021 11:55:21 +0300
Tony Lindgren <tony at atomide.com> wrote:

> * Paul Barker <paul.barker at sancloud.com> [210720 11:40]:
> > The Lite variant of the SanCloud BeagleBone Enhanced (BBE) removes the
> > HDMI encoder, barometer and accelerometer chips and adds a Micron
> > Authenta SPI flash chip.  
> 
> Thanks applying all for v5.15 merge window.

I tested the for-next branch of linux-omap to confirm that things
worked with these patches applied. There was a NULL pointer
dereference in ptp_clock_register() during boot. The fix appears to be
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=55eac20617ca84129273ab248f4d7bfe456967de
which went into 5.14-rc2.

Merging for-next with 5.14-rc4 resulted in things working as expected.

-- 
Paul Barker
Principal Software Engineer
SanCloud Ltd
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 228 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210804/858464a7/attachment.sig>

From lorenzo.pieralisi at arm.com  Wed Aug  4 03:53:18 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 4 Aug 2021 11:53:18 +0100
Subject: [PATCH v7 5/7] PCI: cadence: Add support to configure virtual
 functions
In-Reply-To: <be907fe7-4095-e28b-5575-76629edc30f0@ti.com>
References: <20210803050310.27122-1-kishon@ti.com>
 <20210803050310.27122-6-kishon@ti.com>
 <20210803114530.GE11252@lpieralisi>
 <be907fe7-4095-e28b-5575-76629edc30f0@ti.com>
Message-ID: <20210804105318.GA31443@lpieralisi>

On Tue, Aug 03, 2021 at 08:26:42PM +0530, Kishon Vijay Abraham I wrote:
> Hi Lorenzo,
> 
> On 03/08/21 5:15 pm, Lorenzo Pieralisi wrote:
> > On Tue, Aug 03, 2021 at 10:33:08AM +0530, Kishon Vijay Abraham I wrote:
> >> Now that support for SR-IOV is added in PCIe endpoint core, add support
> >> to configure virtual functions in the Cadence PCIe EP driver.
> >>
> >> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> >> Acked-by: Tom Joseph <tjoseph at cadence.com>
> >> ---
> >>  .../pci/controller/cadence/pcie-cadence-ep.c  | 241 +++++++++++++++---
> >>  drivers/pci/controller/cadence/pcie-cadence.h |   7 +
> >>  2 files changed, 217 insertions(+), 31 deletions(-)
> >>
> >> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> >> index 912a15be8bfd..791915054ff4 100644
> >> --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> >> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> >> @@ -20,7 +20,18 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
> >>  				     struct pci_epf_header *hdr)
> >>  {
> >>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> >> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
> >>  	struct cdns_pcie *pcie = &ep->pcie;
> >> +	u32 reg;
> >> +
> >> +	if (vfn > 1) {
> >> +		dev_dbg(&epc->dev, "Only Virtual Function #1 has deviceID\n");
> >> +		return 0;
> > 
> > Shouldn't this return an error ?
> 
> Since the same function driver could be used for physical function and
> virtual function, I tried to avoid adding any additional case specific
> for virtual function in the function driver.
> 
> If we want to return an error here, then the function driver should be
> modified to not invoke writeheader for vfn > 1.

Well, I see it the other way around. If writing the header for vfn > 1
is an error it must be reported as such and handled accordingly.

As it stands - it looks like we do nothing and everything is just
fine, which is weird.

Thanks,
Lorenzo

> >> +	} else if (vfn == 1) {
> >> +		reg = cap + PCI_SRIOV_VF_DID;
> >> +		cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid);
> >> +		return 0;
> >> +	}
> >>  
> >>  	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
> >>  	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
> >> @@ -51,12 +62,14 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
> >>  				struct pci_epf_bar *epf_bar)
> >>  {
> >>  	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
> >> +	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
> >>  	struct cdns_pcie_epf *epf = &ep->epf[fn];
> >>  	struct cdns_pcie *pcie = &ep->pcie;
> >>  	dma_addr_t bar_phys = epf_bar->phys_addr;
> >>  	enum pci_barno bar = epf_bar->barno;
> >>  	int flags = epf_bar->flags;
> >>  	u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
> >> +	u32 first_vf_offset, stride;
> >>  	u64 sz;
> >>  
> >>  	/* BAR size is 2^(aperture + 7) */
> >> @@ -92,26 +105,50 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
> >>  
> >>  	addr0 = lower_32_bits(bar_phys);
> >>  	addr1 = upper_32_bits(bar_phys);
> >> +
> >> +	if (vfn == 1) {
> >> +		/* All virtual functions use the same BAR config */
> >> +		if (bar < BAR_4) {
> >> +			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn);
> >> +			b = bar;
> >> +		} else {
> >> +			reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn);
> >> +			b = bar - BAR_4;
> >> +		}
> >> +	} else if (vfn == 0) {
> >> +		/* BAR configuration for physical function */
> >> +		if (bar < BAR_4) {
> >> +			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
> >> +			b = bar;
> >> +		} else {
> >> +			reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
> >> +			b = bar - BAR_4;
> >> +		}
> >> +	}
> > 
> > Code in both branches is almost identical except for what is
> > assigned to reg, it is not fundamental but maybe it can be rewritten
> > more concisely.
> 
> okay.. let me think.
> 
> Thanks
> Kishon


From drjones at redhat.com  Wed Aug  4 04:03:17 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 4 Aug 2021 13:03:17 +0200
Subject: [PATCH v6 20/21] selftests: KVM: Test physical counter offsetting
In-Reply-To: <20210804085819.846610-21-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-21-oupton@google.com>
Message-ID: <20210804110317.z7iqgbtbiyfvy45h@gator.home>

On Wed, Aug 04, 2021 at 08:58:18AM +0000, Oliver Upton wrote:
> Test that userspace adjustment of the guest physical counter-timer
> results in the correct view within the guest.
> 
> Cc: Andrew Jones <drjones at redhat.com>
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  .../selftests/kvm/include/aarch64/processor.h | 12 +++++++
>  .../kvm/system_counter_offset_test.c          | 31 +++++++++++++++++--
>  2 files changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
> index 3168cdbae6ee..7f53d90e9512 100644
> --- a/tools/testing/selftests/kvm/include/aarch64/processor.h
> +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
> @@ -141,4 +141,16 @@ static inline uint64_t read_cntvct_ordered(void)
>  	return r;
>  }
>  
> +static inline uint64_t read_cntpct_ordered(void)
> +{
> +	uint64_t r;
> +
> +	__asm__ __volatile__("isb\n\t"
> +			     "mrs %0, cntpct_el0\n\t"
> +			     "isb\n\t"
> +			     : "=r"(r));
> +
> +	return r;
> +}
> +
>  #endif /* SELFTEST_KVM_PROCESSOR_H */
> diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c
> index ac933db83d03..82d26a45cc48 100644
> --- a/tools/testing/selftests/kvm/system_counter_offset_test.c
> +++ b/tools/testing/selftests/kvm/system_counter_offset_test.c
> @@ -57,6 +57,9 @@ static uint64_t host_read_guest_system_counter(struct test_case *test)
>  
>  enum arch_counter {
>  	VIRTUAL,
> +	PHYSICAL,
> +	/* offset physical, read virtual */
> +	PHYSICAL_READ_VIRTUAL,
>  };
>  
>  struct test_case {
> @@ -68,32 +71,54 @@ static struct test_case test_cases[] = {
>  	{ .counter = VIRTUAL, .offset = 0 },
>  	{ .counter = VIRTUAL, .offset = 180 * NSEC_PER_SEC },
>  	{ .counter = VIRTUAL, .offset = -180 * NSEC_PER_SEC },
> +	{ .counter = PHYSICAL, .offset = 0 },
> +	{ .counter = PHYSICAL, .offset = 180 * NSEC_PER_SEC },
> +	{ .counter = PHYSICAL, .offset = -180 * NSEC_PER_SEC },
> +	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = 0 },
> +	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = 180 * NSEC_PER_SEC },
> +	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = -180 * NSEC_PER_SEC },
>  };
>  
>  static void check_preconditions(struct kvm_vm *vm)
>  {
> -	if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET))
> +	if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET) &&
> +	    !_vcpu_has_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
> +				   KVM_ARM_VCPU_TIMER_OFFSET))
>  		return;
>  
> -	print_skip("KVM_REG_ARM_TIMER_OFFSET not supported; skipping test");
> +	print_skip("KVM_REG_ARM_TIMER_OFFSET|KVM_ARM_VCPU_TIMER_OFFSET not supported; skipping test");
>  	exit(KSFT_SKIP);
>  }
>  
>  static void setup_system_counter(struct kvm_vm *vm, struct test_case *test)
>  {
> +	uint64_t cntvoff, cntpoff;
>  	struct kvm_one_reg reg = {
>  		.id = KVM_REG_ARM_TIMER_OFFSET,
> -		.addr = (__u64)&test->offset,
> +		.addr = (__u64)&cntvoff,
>  	};
>  
> +	if (test->counter == VIRTUAL) {
> +		cntvoff = test->offset;
> +		cntpoff = 0;
> +	} else {
> +		cntvoff = 0;
> +		cntpoff = test->offset;
> +	}
> +
>  	vcpu_set_reg(vm, VCPU_ID, &reg);
> +	vcpu_access_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
> +				KVM_ARM_VCPU_TIMER_OFFSET, &cntpoff, true);
>  }
>  
>  static uint64_t guest_read_system_counter(struct test_case *test)
>  {
>  	switch (test->counter) {
>  	case VIRTUAL:
> +	case PHYSICAL_READ_VIRTUAL:
>  		return read_cntvct_ordered();
> +	case PHYSICAL:
> +		return read_cntpct_ordered();
>  	default:
>  		GUEST_ASSERT(0);
>  	}
> -- 
> 2.32.0.605.g8dce9f2422-goog
>

Reviewed-by: Andrew Jones <drjones at redhat.com>



From oupton at google.com  Wed Aug  4 04:05:02 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 4 Aug 2021 04:05:02 -0700
Subject: [PATCH v6 00/21] KVM: Add idempotent controls for migrating
 system counter state
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <CAOQ_QsiVNS==c-ahnKN6Jja_+FfkWEmDnQPoP9sdNWBc1m2gsg@mail.gmail.com>

On Wed, Aug 4, 2021 at 1:58 AM Oliver Upton <oupton at google.com> wrote:
>
> KVM's current means of saving/restoring system counters is plagued with
> temporal issues. At least on ARM64 and x86, we migrate the guest's
> system counter by-value through the respective guest system register
> values (cntvct_el0, ia32_tsc). Restoring system counters by-value is
> brittle as the state is not idempotent: the host system counter is still
> oscillating between the attempted save and restore. Furthermore, VMMs
> may wish to transparently live migrate guest VMs, meaning that they
> include the elapsed time due to live migration blackout in the guest
> system counter view. The VMM thread could be preempted for any number of
> reasons (scheduler, L0 hypervisor under nested) between the time that
> it calculates the desired guest counter value and when KVM actually sets
> this counter state.
>
> Despite the value-based interface that we present to userspace, KVM
> actually has idempotent guest controls by way of system counter offsets.
> We can avoid all of the issues associated with a value-based interface
> by abstracting these offset controls in new ioctls. This series
> introduces new vCPU device attributes to provide userspace access to the
> vCPU's system counter offset.
>
> Patch 1 addresses a possible race in KVM_GET_CLOCK where
> use_master_clock is read outside of the pvclock_gtod_sync_lock.
>
> Patch 2 adopts Paolo's suggestion, augmenting the KVM_{GET,SET}_CLOCK
> ioctls to provide userspace with a (host_tsc, realtime) instant. This is
> essential for a VMM to perform precise migration of the guest's system
> counters.
>
> Patches 3-4 are some preparatory changes for exposing the TSC offset to
> userspace. Patch 5 provides a vCPU attribute to provide userspace access
> to the TSC offset.
>
> Patches 6-7 implement a test for the new additions to
> KVM_{GET,SET}_CLOCK.
>
> Patch 8 fixes some assertions in the kvm device attribute helpers.
>
> Patches 9-10 implement at test for the tsc offset attribute introduced in
> patch 5.
>
> Patches 11-12 lay the groundwork for patch 13, which exposes CNTVOFF_EL2
> through the ONE_REG interface.
>
> Patches 14-15 add test cases for userspace manipulation of the virtual
> counter-timer.
>
> Patches 16-17 add a vCPU attribute to adjust the host-guest offset of an
> ARM vCPU, but only implements support for ECV hosts. Patches 18-19 add
> support for non-ECV hosts by emulating physical counter offsetting.
>
> Patch 20 adds test cases for adjusting the host-guest offset, and
> finally patch 21 adds a test to measure the emulation overhead of
> CNTPCT_EL2.
>
> This series was tested on both an Ampere Mt. Jade and Haswell systems.
> Unfortunately, the ECV portions of this series are untested, as there is
> no ECV-capable hardware and the ARM fast models only partially implement
> ECV.

Small correction: I was only using the foundation model. Apparently
the AEM FVP provides full ECV support.

>
> Physical counter benchmark
> --------------------------
>
> The following data was collected by running 10000 iterations of the
> benchmark test from Patch 21 on an Ampere Mt. Jade reference server, A 2S
> machine with 2 80-core Ampere Altra SoCs. Measurements were collected
> for both VHE and nVHE operation using the `kvm-arm.mode=` command-line
> parameter.
>
> nVHE
> ----
>
> +--------------------+--------+---------+
> |       Metric       | Native | Trapped |
> +--------------------+--------+---------+
> | Average            | 54ns   | 148ns   |
> | Standard Deviation | 124ns  | 122ns   |
> | 95th Percentile    | 258ns  | 348ns   |
> +--------------------+--------+---------+
>
> VHE
> ---
>
> +--------------------+--------+---------+
> |       Metric       | Native | Trapped |
> +--------------------+--------+---------+
> | Average            | 53ns   | 152ns   |
> | Standard Deviation | 92ns   | 94ns    |
> | 95th Percentile    | 204ns  | 307ns   |
> +--------------------+--------+---------+
>
> This series applies cleanly to kvm/queue at the following commit:
>
> 6cd974485e25 ("KVM: selftests: Add a test of an unbacked nested PI descriptor")
>
> v1 -> v2:
>   - Reimplemented as vCPU device attributes instead of a distinct ioctl.
>   - Added the (realtime, host_tsc) instant support to KVM_{GET,SET}_CLOCK
>   - Changed the arm64 implementation to broadcast counter
>     offset values to all vCPUs in a guest. This upholds the
>     architectural expectations of a consistent counter-timer across CPUs.
>   - Fixed a bug with traps in VHE mode. We now configure traps on every
>     transition into a guest to handle differing VMs (trapped, emulated).
>
> v2 -> v3:
>   - Added documentation for additions to KVM_{GET,SET}_CLOCK
>   - Added documentation for all new vCPU attributes
>   - Added documentation for suggested algorithm to migrate a guest's
>     TSC(s)
>   - Bug fixes throughout series
>   - Rename KVM_CLOCK_REAL_TIME -> KVM_CLOCK_REALTIME
>
> v3 -> v4:
>   - Added patch to address incorrect device helper assertions (Drew)
>   - Carried Drew's r-b tags where appropriate
>   - x86 selftest cleanup
>   - Removed stale kvm_timer_init_vhe() function
>   - Removed unnecessary GUEST_DONE() from selftests
>
> v4 -> v5:
>   - Fix typo in TSC migration algorithm
>   - Carry more of Drew's r-b tags
>   - clean up run loop logic in counter emulation benchmark (missed from
>     Drew's comments on v3)
>
> v5 -> v6:
>   - Add fix for race in KVM_GET_CLOCK (Sean)
>   - Fix 32-bit build issues in series + use of uninitialized host tsc
>     value (Sean)
>   - General style cleanups
>   - Rework ARM virtual counter offsetting to match guest behavior. Use
>     the ONE_REG interface instead of a VM attribute (Marc)
>   - Maintain a single host-guest counter offset, which applies to both
>     physical and virtual counters
>   - Dropped some of Drew's r-b tags due to nontrivial patch changes
>     (sorry for the churn!)
>
> v1: https://lore.kernel.org/kvm/20210608214742.1897483-1-oupton at google.com/
> v2: https://lore.kernel.org/r/20210716212629.2232756-1-oupton at google.com
> v3: https://lore.kernel.org/r/20210719184949.1385910-1-oupton at google.com
> v4: https://lore.kernel.org/r/20210729001012.70394-1-oupton at google.com
> v5: https://lore.kernel.org/r/20210729173300.181775-1-oupton at google.com
>
> Oliver Upton (21):
>   KVM: x86: Fix potential race in KVM_GET_CLOCK
>   KVM: x86: Report host tsc and realtime values in KVM_GET_CLOCK
>   KVM: x86: Take the pvclock sync lock behind the tsc_write_lock
>   KVM: x86: Refactor tsc synchronization code
>   KVM: x86: Expose TSC offset controls to userspace
>   tools: arch: x86: pull in pvclock headers
>   selftests: KVM: Add test for KVM_{GET,SET}_CLOCK
>   selftests: KVM: Fix kvm device helper ioctl assertions
>   selftests: KVM: Add helpers for vCPU device attributes
>   selftests: KVM: Introduce system counter offset test
>   KVM: arm64: Refactor update_vtimer_cntvoff()
>   KVM: arm64: Separate guest/host counter offset values
>   KVM: arm64: Allow userspace to configure a vCPU's virtual offset
>   selftests: KVM: Add helper to check for register presence
>   selftests: KVM: Add support for aarch64 to system_counter_offset_test
>   arm64: cpufeature: Enumerate support for Enhanced Counter
>     Virtualization
>   KVM: arm64: Allow userspace to configure a guest's counter-timer
>     offset
>   KVM: arm64: Configure timer traps in vcpu_load() for VHE
>   KVM: arm64: Emulate physical counter offsetting on non-ECV systems
>   selftests: KVM: Test physical counter offsetting
>   selftests: KVM: Add counter emulation benchmark
>
>  Documentation/virt/kvm/api.rst                |  52 ++-
>  Documentation/virt/kvm/devices/vcpu.rst       |  85 ++++
>  Documentation/virt/kvm/locking.rst            |  11 +
>  arch/arm64/include/asm/kvm_asm.h              |   2 +
>  arch/arm64/include/asm/sysreg.h               |   5 +
>  arch/arm64/include/uapi/asm/kvm.h             |   2 +
>  arch/arm64/kernel/cpufeature.c                |  10 +
>  arch/arm64/kvm/arch_timer.c                   | 224 ++++++++++-
>  arch/arm64/kvm/arm.c                          |   4 +-
>  arch/arm64/kvm/guest.c                        |   6 +-
>  arch/arm64/kvm/hyp/include/hyp/switch.h       |  29 ++
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            |   6 +
>  arch/arm64/kvm/hyp/nvhe/timer-sr.c            |  16 +-
>  arch/arm64/kvm/hyp/vhe/timer-sr.c             |   5 +
>  arch/arm64/tools/cpucaps                      |   1 +
>  arch/x86/include/asm/kvm_host.h               |   4 +
>  arch/x86/include/uapi/asm/kvm.h               |   4 +
>  arch/x86/kvm/x86.c                            | 364 +++++++++++++-----
>  include/clocksource/arm_arch_timer.h          |   1 +
>  include/kvm/arm_arch_timer.h                  |   6 +-
>  include/uapi/linux/kvm.h                      |   7 +-
>  tools/arch/x86/include/asm/pvclock-abi.h      |  48 +++
>  tools/arch/x86/include/asm/pvclock.h          | 103 +++++
>  tools/testing/selftests/kvm/.gitignore        |   3 +
>  tools/testing/selftests/kvm/Makefile          |   4 +
>  .../kvm/aarch64/counter_emulation_benchmark.c | 207 ++++++++++
>  .../selftests/kvm/include/aarch64/processor.h |  24 ++
>  .../testing/selftests/kvm/include/kvm_util.h  |  13 +
>  tools/testing/selftests/kvm/lib/kvm_util.c    |  63 ++-
>  .../kvm/system_counter_offset_test.c          | 211 ++++++++++
>  .../selftests/kvm/x86_64/kvm_clock_test.c     | 204 ++++++++++
>  31 files changed, 1581 insertions(+), 143 deletions(-)
>  create mode 100644 tools/arch/x86/include/asm/pvclock-abi.h
>  create mode 100644 tools/arch/x86/include/asm/pvclock.h
>  create mode 100644 tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
>  create mode 100644 tools/testing/selftests/kvm/system_counter_offset_test.c
>  create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
>
> --
> 2.32.0.605.g8dce9f2422-goog
>


From drjones at redhat.com  Wed Aug  4 04:05:31 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 4 Aug 2021 13:05:31 +0200
Subject: [PATCH v6 19/21] KVM: arm64: Emulate physical counter offsetting
 on non-ECV systems
In-Reply-To: <20210804085819.846610-20-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-20-oupton@google.com>
Message-ID: <20210804110531.x6gm2bpygg7laiau@gator.home>

On Wed, Aug 04, 2021 at 08:58:17AM +0000, Oliver Upton wrote:
> Unfortunately, ECV hasn't yet arrived in any tangible hardware. At the
> same time, controlling the guest view of the physical counter-timer is
> useful. Support guest counter-timer offsetting on non-ECV systems by
> trapping guest accesses to the physical counter-timer. Emulate reads of
> the physical counter in the fast exit path.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  arch/arm64/include/asm/sysreg.h         |  1 +
>  arch/arm64/kvm/arch_timer.c             | 53 +++++++++++++++----------
>  arch/arm64/kvm/hyp/include/hyp/switch.h | 29 ++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/timer-sr.c      | 11 ++++-
>  4 files changed, 70 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index c34672aa65b9..e49790ae5da4 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -505,6 +505,7 @@
>  #define SYS_AMEVCNTR0_MEM_STALL		SYS_AMEVCNTR0_EL0(3)
>  
>  #define SYS_CNTFRQ_EL0			sys_reg(3, 3, 14, 0, 0)
> +#define SYS_CNTPCT_EL0			sys_reg(3, 3, 14, 0, 1)
>  
>  #define SYS_CNTP_TVAL_EL0		sys_reg(3, 3, 14, 2, 0)
>  #define SYS_CNTP_CTL_EL0		sys_reg(3, 3, 14, 2, 1)
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 9ead94aa867d..b7cb63acf2a0 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -51,7 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
>  static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
>  			      struct arch_timer_context *timer,
>  			      enum kvm_arch_timer_regs treg);
> -static void kvm_timer_enable_traps_vhe(void);
> +static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu);
>  
>  u32 timer_get_ctl(struct arch_timer_context *ctxt)
>  {
> @@ -175,6 +175,12 @@ static void timer_set_guest_offset(struct arch_timer_context *ctxt, u64 offset)
>  	}
>  }
>  
> +static bool ptimer_emulation_required(struct kvm_vcpu *vcpu)
> +{
> +	return timer_get_offset(vcpu_ptimer(vcpu)) &&
> +			!cpus_have_const_cap(ARM64_ECV);

Whenever I see a static branch check and something else in the same
condition, I always wonder if we could trim a few instructions for
the static branch is false case by testing it first.

> +}
> +
>  u64 kvm_phys_timer_read(void)
>  {
>  	return timecounter->cc->read(timecounter->cc);
> @@ -184,8 +190,13 @@ static void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
>  {
>  	if (has_vhe()) {
>  		map->direct_vtimer = vcpu_vtimer(vcpu);
> -		map->direct_ptimer = vcpu_ptimer(vcpu);
> -		map->emul_ptimer = NULL;
> +		if (!ptimer_emulation_required(vcpu)) {
> +			map->direct_ptimer = vcpu_ptimer(vcpu);
> +			map->emul_ptimer = NULL;
> +		} else {
> +			map->direct_ptimer = NULL;
> +			map->emul_ptimer = vcpu_ptimer(vcpu);
> +		}
>  	} else {
>  		map->direct_vtimer = vcpu_vtimer(vcpu);
>  		map->direct_ptimer = NULL;
> @@ -671,7 +682,7 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
>  		timer_emulate(map.emul_ptimer);
>  
>  	if (has_vhe())
> -		kvm_timer_enable_traps_vhe();
> +		kvm_timer_enable_traps_vhe(vcpu);
>  }
>  
>  bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
> @@ -1392,22 +1403,29 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>   * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
>   * and this makes those bits have no effect for the host kernel execution.
>   */
> -static void kvm_timer_enable_traps_vhe(void)
> +static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu)
>  {
>  	/* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
>  	u32 cnthctl_shift = 10;
> -	u64 val;
> +	u64 val, mask;
> +
> +	mask = CNTHCTL_EL1PCEN << cnthctl_shift;
> +	mask |= CNTHCTL_EL1PCTEN << cnthctl_shift;
>  
> -	/*
> -	 * VHE systems allow the guest direct access to the EL1 physical
> -	 * timer/counter.
> -	 */
>  	val = read_sysreg(cnthctl_el2);
> -	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
> -	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
>  
>  	if (cpus_have_const_cap(ARM64_ECV))
>  		val |= CNTHCTL_ECV;
> +
> +	/*
> +	 * VHE systems allow the guest direct access to the EL1 physical
> +	 * timer/counter if offsetting isn't requested on a non-ECV system.
> +	 */
> +	if (ptimer_emulation_required(vcpu))
> +		val &= ~mask;
> +	else
> +		val |= mask;
> +
>  	write_sysreg(val, cnthctl_el2);
>  }
>  
> @@ -1462,9 +1480,6 @@ static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
>  	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
>  	u64 offset;
>  
> -	if (!cpus_have_const_cap(ARM64_ECV))
> -		return -ENXIO;
> -
>  	if (get_user(offset, uaddr))
>  		return -EFAULT;
>  
> @@ -1513,9 +1528,6 @@ static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
>  	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
>  	u64 offset;
>  
> -	if (!cpus_have_const_cap(ARM64_ECV))
> -		return -ENXIO;
> -
>  	offset = timer_get_offset(vcpu_ptimer(vcpu));
>  	return put_user(offset, uaddr);
>  }
> @@ -1539,11 +1551,8 @@ int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  	switch (attr->attr) {
>  	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
>  	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> -		return 0;
>  	case KVM_ARM_VCPU_TIMER_OFFSET:
> -		if (cpus_have_const_cap(ARM64_ECV))
> -			return 0;
> -		break;
> +		return 0;

So now, if userspace wants to know when they're using an emulated
TIMER_OFFSET vs. ECV, then they'll need to check the HWCAP. I guess
that's fair. We should update the selftest to report what it's testing
when the HWCAP is available.

>  	}
>  
>  	return -ENXIO;
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index e4a2f295a394..abd3813a709e 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -15,6 +15,7 @@
>  #include <linux/jump_label.h>
>  #include <uapi/linux/psci.h>
>  
> +#include <kvm/arm_arch_timer.h>
>  #include <kvm/arm_psci.h>
>  
>  #include <asm/barrier.h>
> @@ -405,6 +406,31 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
>  	return true;
>  }
>  
> +static inline u64 __timer_read_cntpct(struct kvm_vcpu *vcpu)
> +{
> +	return __arch_counter_get_cntpct() - vcpu_ptimer(vcpu)->host_offset;
> +}
> +
> +static inline bool __hyp_handle_counter(struct kvm_vcpu *vcpu)
> +{
> +	u32 sysreg;
> +	int rt;
> +	u64 rv;
> +
> +	if (kvm_vcpu_trap_get_class(vcpu) != ESR_ELx_EC_SYS64)
> +		return false;
> +
> +	sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
> +	if (sysreg != SYS_CNTPCT_EL0)
> +		return false;
> +
> +	rt = kvm_vcpu_sys_get_rt(vcpu);
> +	rv = __timer_read_cntpct(vcpu);
> +	vcpu_set_reg(vcpu, rt, rv);
> +	__kvm_skip_instr(vcpu);
> +	return true;
> +}
> +
>  /*
>   * Return true when we were able to fixup the guest exit and should return to
>   * the guest, false when we should restore the host state and return to the
> @@ -439,6 +465,9 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  	if (*exit_code != ARM_EXCEPTION_TRAP)
>  		goto exit;
>  
> +	if (__hyp_handle_counter(vcpu))
> +		goto guest;
> +
>  	if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) &&
>  	    kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 &&
>  	    handle_tx2_tvm(vcpu))
> diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> index 5b8b4cd02506..67236c2e0ba7 100644
> --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> @@ -44,10 +44,17 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
>  
>  	/*
>  	 * Disallow physical timer access for the guest
> -	 * Physical counter access is allowed
>  	 */
>  	val = read_sysreg(cnthctl_el2);
>  	val &= ~CNTHCTL_EL1PCEN;
> -	val |= CNTHCTL_EL1PCTEN;
> +
> +	/*
> +	 * Disallow physical counter access for the guest if offsetting is
> +	 * requested on a non-ECV system.
> +	 */
> +	if (vcpu_ptimer(vcpu)->host_offset && !cpus_have_const_cap(ARM64_ECV))

Shouldn't we expose and reuse ptimer_emulation_required() here?

> +		val &= ~CNTHCTL_EL1PCTEN;
> +	else
> +		val |= CNTHCTL_EL1PCTEN;
>  	write_sysreg(val, cnthctl_el2);
>  }
> -- 
> 2.32.0.605.g8dce9f2422-goog
>

Otherwise,

Reviewed-by: Andrew Jones <drjones at redhat.com>



From ulf.hansson at linaro.org  Wed Aug  4 04:12:31 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 4 Aug 2021 13:12:31 +0200
Subject: [PATCH 1/6] mmc: JZ4740: remove the flush_kernel_dcache_page call
 in jz4740_mmc_read_data
In-Reply-To: <20210712060928.4161649-2-hch@lst.de>
References: <20210712060928.4161649-1-hch@lst.de>
 <20210712060928.4161649-2-hch@lst.de>
Message-ID: <CAPDyKFq2hqPYR-m3+mo7Gwu1421f_faE0jRpK4nJ8CDe=jHsjw@mail.gmail.com>

On Mon, 12 Jul 2021 at 08:10, Christoph Hellwig <hch at lst.de> wrote:
>
> MIPS now implements flush_kernel_dcache_page (as an alias to
> flush_dcache_page).
>
> Signed-off-by: Christoph Hellwig <hch at lst.de>

Apologies for the delay!

Acked-by: Ulf Hansson <ulf.hansson at linaro.org>

Kind regards
Uffe


> ---
>  drivers/mmc/host/jz4740_mmc.c | 4 ----
>  1 file changed, 4 deletions(-)
>
> diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
> index 0db17bcc9c16..aa2240c83510 100644
> --- a/drivers/mmc/host/jz4740_mmc.c
> +++ b/drivers/mmc/host/jz4740_mmc.c
> @@ -578,10 +578,6 @@ static bool jz4740_mmc_read_data(struct jz4740_mmc_host *host,
>                         }
>                 }
>                 data->bytes_xfered += miter->length;
> -
> -               /* This can go away once MIPS implements
> -                * flush_kernel_dcache_page */
> -               flush_dcache_page(miter->page);
>         }
>         sg_miter_stop(miter);
>
> --
> 2.30.2
>


From ulf.hansson at linaro.org  Wed Aug  4 04:12:40 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 4 Aug 2021 13:12:40 +0200
Subject: [PATCH 2/6] mmc: mmc_spi: replace flush_kernel_dcache_page with
 flush_dcache_page
In-Reply-To: <20210712060928.4161649-3-hch@lst.de>
References: <20210712060928.4161649-1-hch@lst.de>
 <20210712060928.4161649-3-hch@lst.de>
Message-ID: <CAPDyKFpo2kjAH6tRDdo_B3JnKGvuR_+3A9Fe6bCtuP12Lfqd2w@mail.gmail.com>

On Mon, 12 Jul 2021 at 08:11, Christoph Hellwig <hch at lst.de> wrote:
>
> Pages passed to block drivers can be mapped page cache pages, so we
> must use flush_dcache_page here instead of the more limited
> flush_kernel_dcache_page that is intended for highmem pages only.
>
> Signed-off-by: Christoph Hellwig <hch at lst.de>

Apologies for the delay!

Acked-by: Ulf Hansson <ulf.hansson at linaro.org>

Kind regards
Uffe

> ---
>  drivers/mmc/host/mmc_spi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
> index 65c65bb5737f..3d28a3d3001b 100644
> --- a/drivers/mmc/host/mmc_spi.c
> +++ b/drivers/mmc/host/mmc_spi.c
> @@ -948,7 +948,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
>
>                 /* discard mappings */
>                 if (direction == DMA_FROM_DEVICE)
> -                       flush_kernel_dcache_page(sg_page(sg));
> +                       flush_dcache_page(sg_page(sg));
>                 kunmap(sg_page(sg));
>                 if (dma_dev)
>                         dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
> --
> 2.30.2
>


From catalin.marinas at arm.com  Wed Aug  4 04:14:02 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 4 Aug 2021 12:14:02 +0100
Subject: [PATCH v2 1/3] vmalloc: Choose a better start address in
 vm_area_register_early()
In-Reply-To: <0de87be6-7041-c58b-a01f-3d6e3333c6f0@huawei.com>
References: <20210720025105.103680-1-wangkefeng.wang@huawei.com>
 <20210720025105.103680-2-wangkefeng.wang@huawei.com>
 <20210801152311.GB28489@arm.com>
 <0de87be6-7041-c58b-a01f-3d6e3333c6f0@huawei.com>
Message-ID: <20210804111402.GB4857@arm.com>

On Mon, Aug 02, 2021 at 10:39:04AM +0800, Kefeng Wang wrote:
> On 2021/8/1 23:23, Catalin Marinas wrote:
> > On Tue, Jul 20, 2021 at 10:51:03AM +0800, Kefeng Wang wrote:
> > > There are some fixed locations in the vmalloc area be reserved
> > > in ARM(see iotable_init()) and ARM64(see map_kernel()), but for
> > > pcpu_page_first_chunk(), it calls vm_area_register_early() and
> > > choose VMALLOC_START as the start address of vmap area which
> > > could be conflicted with above address, then could trigger a
> > > BUG_ON in vm_area_add_early().
> > > 
> > > Let's choose the end of existing address range in vmlist as the
> > > start address instead of VMALLOC_START to avoid the BUG_ON.
> > > 
> > > Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> > > ---
> > >   mm/vmalloc.c | 8 +++++---
> > >   1 file changed, 5 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > > index d5cd52805149..a98cf97f032f 100644
> > > --- a/mm/vmalloc.c
> > > +++ b/mm/vmalloc.c
> > > @@ -2238,12 +2238,14 @@ void __init vm_area_add_early(struct vm_struct *vm)
> > >    */
> > >   void __init vm_area_register_early(struct vm_struct *vm, size_t align)
> > >   {
> > > -	static size_t vm_init_off __initdata;
> > > +	unsigned long vm_start = VMALLOC_START;
> > > +	struct vm_struct *tmp;
> > >   	unsigned long addr;
> > > -	addr = ALIGN(VMALLOC_START + vm_init_off, align);
> > > -	vm_init_off = PFN_ALIGN(addr + vm->size) - VMALLOC_START;
> > > +	for (tmp = vmlist; tmp; tmp = tmp->next)
> > > +		vm_start = (unsigned long)tmp->addr + tmp->size;
> > > +	addr = ALIGN(vm_start, align);
> > >   	vm->addr = (void *)addr;
> > >   	vm_area_add_early(vm);
> > Is there a risk of breaking other architectures? It doesn't look like to
> > me but I thought I'd ask.
> 
> Before this patch, vm_init_off is to record the offset from VMALLOC_START,
> 
> but it use VMALLOC_START as start address on the function
> vm_area_register_early()
> 
> called firstly,? this will cause the BUG_ON.
> 
> With this patch, the most important change is that we choose the start
> address via
> 
> dynamic calculate the 'start' address by traversing the list.
> 
> [wkf at localhost linux-next]$ git grep vm_area_register_early
> arch/alpha/mm/init.c: vm_area_register_early(&console_remap_vm, PAGE_SIZE);
> arch/x86/xen/p2m.c:???? vm_area_register_early(&vm, PMD_SIZE *
> PMDS_PER_MID_PAGE);
> mm/percpu.c:??? vm_area_register_early(&vm, PAGE_SIZE);
> [wkf at localhost linux-next]$ git grep vm_area_add_early
> arch/arm/mm/ioremap.c:? vm_area_add_early(vm);
> arch/arm64/mm/mmu.c:??? vm_area_add_early(vma);
> 
> x86/alpha won't call vm_area_add_early(), only arm64 could call both vm_area_add_early()
> and  vm_area_register_early() when this patchset is merged. so it won't break other architectures.

Thanks for checking.

> > Also, instead of always picking the end, could we search for a range
> > that fits?
> 
> We only need a space in vmalloc range,? using end or a range in the middle
> is not different.

I was thinking of making it more future-proof in case one registers a
vm area towards the end of the range. It's fairly easy to pick a range
in the middle now that you are adding a list traversal.

-- 
Catalin


From ulf.hansson at linaro.org  Wed Aug  4 04:24:57 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 4 Aug 2021 13:24:57 +0200
Subject: [PATCH 25/54] dt-bindings: mmc: Convert MMC Card binding to a
 schema
In-Reply-To: <20210723215724.GA2661499@robh.at.kernel.org>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-26-maxime@cerno.tech>
 <20210723215724.GA2661499@robh.at.kernel.org>
Message-ID: <CAPDyKFr8-+zqhZfALux8p6XaDbR2T-DSP=_Kx_6p_LqdCrmCAA@mail.gmail.com>

On Fri, 23 Jul 2021 at 23:57, Rob Herring <robh at kernel.org> wrote:
>
> On Wed, Jul 21, 2021 at 04:03:55PM +0200, Maxime Ripard wrote:
> > MMC Cards can have an optional Device Tree binding to add
> > non-discoverable properties.
> >
> > Now that we have the DT validation in place, let's convert the device
> > tree bindings for that driver over to a YAML schema.
> >
> > Some of these properties were already described in the MMC controller
> > binding, even though they are not generic and do not apply to any
> > device, so we took the occasion to fix this.
> >
> > Cc: linux-mmc at vger.kernel.org
> > Cc: Ulf Hansson <ulf.hansson at linaro.org>
> > Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> > ---
> >  .../devicetree/bindings/mmc/mmc-card.txt      | 30 ------------
> >  .../devicetree/bindings/mmc/mmc-card.yaml     | 48 +++++++++++++++++++
> >  .../bindings/mmc/mmc-controller.yaml          |  6 ---
> >  3 files changed, 48 insertions(+), 36 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/mmc/mmc-card.txt
> >  create mode 100644 Documentation/devicetree/bindings/mmc/mmc-card.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.txt b/Documentation/devicetree/bindings/mmc/mmc-card.txt
> > deleted file mode 100644
> > index 8d2d71758907..000000000000
> > --- a/Documentation/devicetree/bindings/mmc/mmc-card.txt
> > +++ /dev/null
> > @@ -1,30 +0,0 @@
> > -mmc-card / eMMC bindings
> > -------------------------
> > -
> > -This documents describes the devicetree bindings for a mmc-host controller
> > -child node describing a mmc-card / an eMMC, see "Use of Function subnodes"
> > -in mmc.txt
> > -
> > -Required properties:
> > --compatible : Must be "mmc-card"
> > --reg        : Must be <0>
> > -
> > -Optional properties:
> > --broken-hpi : Use this to indicate that the mmc-card has a broken hpi
> > -              implementation, and that hpi should not be used
> > -
> > -Example:
> > -
> > -&mmc2 {
> > -     pinctrl-names = "default";
> > -     pinctrl-0 = <&mmc2_pins_a>;
> > -     vmmc-supply = <&reg_vcc3v3>;
> > -     bus-width = <8>;
> > -     non-removable;
> > -
> > -     mmccard: mmccard at 0 {
> > -             reg = <0>;
> > -             compatible = "mmc-card";
> > -             broken-hpi;
> > -     };
> > -};
> > diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.yaml b/Documentation/devicetree/bindings/mmc/mmc-card.yaml
> > new file mode 100644
> > index 000000000000..aefdd8748b72
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mmc/mmc-card.yaml
> > @@ -0,0 +1,48 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/mmc/mmc-card.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: MMC Card / eMMC Generic Device Tree Bindings
> > +
> > +maintainers:
> > +  - Ulf Hansson <ulf.hansson at linaro.org>
> > +
> > +description: |
> > +  This documents describes the devicetree bindings for a mmc-host controller
> > +  child node describing a mmc-card / an eMMC.
> > +
> > +properties:
> > +  compatible:
> > +    const: mmc-card
> > +
> > +  reg:
> > +    const: 0
> > +
> > +  broken-hpi:
> > +    $ref: /schemas/types.yaml#/definitions/flag
> > +    description:
> > +      Use this to indicate that the mmc-card has a broken hpi
> > +      implementation, and that hpi should not be used.
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +
> > +additionalProperties: true
>
> Like what? If there's other properties, then there should really be a
> specific compatible.

I agree.

Maxime, thanks for working on this. I assume you will be sending a new
version that I can pick up?

[...]

Kind regards
Uffe


From frank-w at public-files.de  Wed Aug  4 04:33:16 2021
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 4 Aug 2021 13:33:16 +0200
Subject: Aw: Re:  [PATCH 0/2] Add MUSB for MT7623
In-Reply-To: <f3607979-ea50-fc1c-0afe-a55881aa24f0@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <trinity-0f9449b8-5114-46e5-9a4f-00b62155a938-1628010948338@3c-app-gmx-bs54>
 <f3607979-ea50-fc1c-0afe-a55881aa24f0@gorani.run>
Message-ID: <trinity-62b8c96c-2408-46d3-9690-e78af2f0c250-1628076795963@3c-app-gmx-bap67>

Hi,

another strange thing is, after some bootups (i boot kernel from tftp, but also on full power cycle),
musb-driver maps musb-hdrc.4.auto instead of #1

root at bpi-r2:~# dmesg | grep musb
[    5.502914] musb-hdrc musb-hdrc.4.auto: MUSB HDRC host driver
[    5.508782] musb-hdrc musb-hdrc.4.auto: new USB bus registered, assigned bus number 5

and then nothing works (no roleswitch, no power which does not work with pinctl / without regulator).
It's hard to test if things working before, do no more work if device is named differently.

maybe Min Guo can help here?

after bootup mode is b_idle in my case (currently do not change if i connect otg cable)

root at bpi-r2:~# cat /sys/devices/platform/11200000.usb/musb-hdrc.4.auto/mode
b_idle

regards Frank


From ulf.hansson at linaro.org  Wed Aug  4 04:34:44 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 4 Aug 2021 13:34:44 +0200
Subject: [PATCH] mmc: mmci: stm32: check when the voltage switch procedure
 should be done
In-Reply-To: <20210701143353.13188-1-yann.gautier@foss.st.com>
References: <20210701143353.13188-1-yann.gautier@foss.st.com>
Message-ID: <CAPDyKFoCABbyKaejhzAqM9hv7Emg4WyfbtORoW_XMnmoxKSVAQ@mail.gmail.com>

On Thu, 1 Jul 2021 at 16:34, Yann Gautier <yann.gautier at foss.st.com> wrote:
>
> From: Christophe Kerello <christophe.kerello at foss.st.com>
>
> If the card has not been power cycled, it may still be using 1.8V
> signaling. This situation is detected in mmc_sd_init_card function and
> should be handled in mmci stm32 variant.
> The host->pwr_reg variable is also correctly protected with spin locks.
>
> Fixes: 94b94a93e355 ("mmc: mmci_sdmmc: Implement signal voltage callbacks")
>
> Signed-off-by: Christophe Kerello <christophe.kerello at foss.st.com>
> Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>

Applied for fixes and by adding stable tag, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/mmci_stm32_sdmmc.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c
> index 51db30acf4dc..fdaa11f92fe6 100644
> --- a/drivers/mmc/host/mmci_stm32_sdmmc.c
> +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c
> @@ -479,8 +479,9 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host,
>         u32 status;
>         int ret = 0;
>
> -       if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
> -               spin_lock_irqsave(&host->lock, flags);
> +       spin_lock_irqsave(&host->lock, flags);
> +       if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 &&
> +           host->pwr_reg & MCI_STM32_VSWITCHEN) {
>                 mmci_write_pwrreg(host, host->pwr_reg | MCI_STM32_VSWITCH);
>                 spin_unlock_irqrestore(&host->lock, flags);
>
> @@ -492,9 +493,11 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host,
>
>                 writel_relaxed(MCI_STM32_VSWENDC | MCI_STM32_CKSTOPC,
>                                host->base + MMCICLEAR);
> +               spin_lock_irqsave(&host->lock, flags);
>                 mmci_write_pwrreg(host, host->pwr_reg &
>                                   ~(MCI_STM32_VSWITCHEN | MCI_STM32_VSWITCH));
>         }
> +       spin_unlock_irqrestore(&host->lock, flags);
>
>         return ret;
>  }
> --
> 2.17.1
>


From maz at kernel.org  Wed Aug  4 05:26:37 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed,  4 Aug 2021 13:26:37 +0100
Subject: [PATCH v2 0/2] KVM: arm64: Prevent kmemleak from accessing HYP
 data
In-Reply-To: <20210802123830.2195174-1-maz@kernel.org>
References: <20210802123830.2195174-1-maz@kernel.org>
Message-ID: <162807998838.4077325.1915601762078271589.b4-ty@kernel.org>

On Mon, 2 Aug 2021 13:38:28 +0100, Marc Zyngier wrote:
> This is a rework of the patch previously posted at [1].
> 
> The gist of the problem is that kmemleak can legitimately access data
> that has been removed from the kernel view, for two reasons:
> 
> (1) .hyp.rodata is lumped together with the BSS
> (2) there is no separation of the HYP BSS from the kernel BSS
> 
> [...]

Applied to next, thanks!

[1/2] arm64: Move .hyp.rodata outside of the _sdata.._edata range
      commit: eb48d154cd0dade56a0e244f0cfa198ea2925ed3
[2/2] KVM: arm64: Unregister HYP sections from kmemleak in protected mode
      commit: 47e6223c841e029bfc23c3ce594dac5525cebaf8

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From lukas.bulwahn at gmail.com  Wed Aug  4 05:34:24 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed,  4 Aug 2021 14:34:24 +0200
Subject: [PATCH 0/2] More (hopefully final) Kconfig clean-up after IDE removal
Message-ID: <20210804123426.16947-1-lukas.bulwahn@gmail.com>

Dear Christoph, dear Jens,

here is a follow-up to the issue of Kconfig references to obsolete IDE configs,
which I first identified and addressed in commit 094121ef815f ("arch: Kconfig:
clean up obsolete use of HAVE_IDE").

Following checkkconfigsymbols.py indications, this patch series cleans up all
references to removed IDE Kconfig symbol throughout the current kernel tree.

Pavel, Sekhar, Bartosz, you are CCed, just to let know about minor follow-up
cleanup in your files.

Christoph, please review and ack.

Jens, please pick these two further clean-up patches.


Best regards,

Lukas

Lukas Bulwahn (2):
  leds: trigger: remove reference to obsolete CONFIG_IDE_GD_ATA
  arm: davinci: remove reference to obsolete BLK_DEV_PALMCHIP_BK3710

 arch/arm/mach-davinci/board-dm644x-evm.c  | 3 +--
 arch/arm/mach-davinci/board-dm646x-evm.c  | 3 +--
 arch/arm/mach-davinci/board-neuros-osd2.c | 3 +--
 drivers/leds/trigger/Kconfig              | 2 +-
 4 files changed, 4 insertions(+), 7 deletions(-)

-- 
2.17.1



From lukas.bulwahn at gmail.com  Wed Aug  4 05:34:25 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed,  4 Aug 2021 14:34:25 +0200
Subject: [PATCH 1/2] leds: trigger: remove reference to obsolete
 CONFIG_IDE_GD_ATA
In-Reply-To: <20210804123426.16947-1-lukas.bulwahn@gmail.com>
References: <20210804123426.16947-1-lukas.bulwahn@gmail.com>
Message-ID: <20210804123426.16947-2-lukas.bulwahn@gmail.com>

Commit b7fb14d3ac63 ("ide: remove the legacy ide driver") removes the
definition of the config IDE_GD_ATA.

So, remove the obsolete reference in ./drivers/leds/trigger/Kconfig.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/leds/trigger/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig
index b77a01bd27f4..1f1d57288085 100644
--- a/drivers/leds/trigger/Kconfig
+++ b/drivers/leds/trigger/Kconfig
@@ -34,7 +34,7 @@ config LEDS_TRIGGER_ONESHOT
 
 config LEDS_TRIGGER_DISK
 	bool "LED Disk Trigger"
-	depends on IDE_GD_ATA || ATA
+	depends on ATA
 	help
 	  This allows LEDs to be controlled by disk activity.
 	  If unsure, say Y.
-- 
2.17.1



From lukas.bulwahn at gmail.com  Wed Aug  4 05:34:26 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed,  4 Aug 2021 14:34:26 +0200
Subject: [PATCH 2/2] arm: davinci: remove reference to obsolete
 BLK_DEV_PALMCHIP_BK3710
In-Reply-To: <20210804123426.16947-1-lukas.bulwahn@gmail.com>
References: <20210804123426.16947-1-lukas.bulwahn@gmail.com>
Message-ID: <20210804123426.16947-3-lukas.bulwahn@gmail.com>

Commit b7fb14d3ac63 ("ide: remove the legacy ide driver") removes the
definition of the config BLK_DEV_PALMCHIP_BK3710.

So, remove the obsolete references in the mach-davinci architecture.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 arch/arm/mach-davinci/board-dm644x-evm.c  | 3 +--
 arch/arm/mach-davinci/board-dm646x-evm.c  | 3 +--
 arch/arm/mach-davinci/board-neuros-osd2.c | 3 +--
 3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index cce3a621eb20..df6dbb3f0faf 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -834,8 +834,7 @@ static int davinci_phy_fixup(struct phy_device *phydev)
 	return 0;
 }
 
-#define HAS_ATA		(IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
-			 IS_ENABLED(CONFIG_PATA_BK3710))
+#define HAS_ATA		IS_ENABLED(CONFIG_PATA_BK3710)
 
 #define HAS_NOR		IS_ENABLED(CONFIG_MTD_PHYSMAP)
 
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index ee91d81ebbfd..744ece6b6b9a 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -151,8 +151,7 @@ static struct platform_device davinci_aemif_device = {
 	.num_resources	= ARRAY_SIZE(davinci_aemif_resources),
 };
 
-#define HAS_ATA		(IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
-			 IS_ENABLED(CONFIG_PATA_BK3710))
+#define HAS_ATA		IS_ENABLED(CONFIG_PATA_BK3710)
 
 #ifdef CONFIG_I2C
 /* CPLD Register 0 bits to control ATA */
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index b4843f68bb57..81c21fe5748a 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -164,8 +164,7 @@ static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
 	.wires		= 4,
 };
 
-#define HAS_ATA		(IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
-			 IS_ENABLED(CONFIG_PATA_BK3710))
+#define HAS_ATA		IS_ENABLED(CONFIG_PATA_BK3710)
 
 #define HAS_NAND	IS_ENABLED(CONFIG_MTD_NAND_DAVINCI)
 
-- 
2.17.1



From linus.walleij at linaro.org  Wed Aug  4 05:40:18 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Aug 2021 14:40:18 +0200
Subject: [PATCH 1/5 v2] pata: ixp4xx: Use local dev variable
In-Reply-To: <20210731213555.2965356-1-linus.walleij@linaro.org>
References: <20210731213555.2965356-1-linus.walleij@linaro.org>
Message-ID: <CACRpkdbf9TfFyObuqCzOEe_QrS=Gru8i6x-1P7v_N-a11g_iiA@mail.gmail.com>

On Sat, Jul 31, 2021 at 11:38 PM Linus Walleij <linus.walleij at linaro.org> wrote:

> Let's simplify all &pdev->dev references by creating a
> local struct device *dev variable.
>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>

I will send a pull request to the SoC tree for all of these changes
since it has effect on device trees and the like.

Jens: if you prefer to take them through your tree, just yell!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Aug  4 05:44:18 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Aug 2021 14:44:18 +0200
Subject: [GIT PULL] IXP4xx driver updates for v5.15
Message-ID: <CACRpkdZaCosXsgp02nuUbd_nEvdxm5-z0+d0oSA97UTWQ0RQQg@mail.gmail.com>

Hi SoC maintainers,

this is a set of combined driver updates for IXP4xx targeted for the
v5.15 merge window.

I am sending it to the SoC tree because of the cross-subsystem
dependencies and since the corresponding DTS changes goes
into SoC. These will be sent separately.

Note the following:

All new DT bindings in this patch set are ACKed by bindings
maintainer Rob Herring.

The new expansion bus driver goes in through the SoC tree as is
custom for bus drivers.

The watchdog maintainer has ACKed the watchdog patch, which
also briefly affects the timer driver.

The PATA changes also have some mach dependencies.
I have informed the libata maintainer that I intend to take these
through ARM SoC.
https://lore.kernel.org/linux-ide/CACRpkdbf9TfFyObuqCzOEe_QrS=Gru8i6x-1P7v_N-a11g_iiA at mail.gmail.com/

Please pull it in!

Yours,
Linus Walleij

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
tags/ixp4xx-drivers-arm-soc-v5.15-1

for you to fetch changes up to 47adef20e67d657696c953f4b8023017c6005c1b:

  pata: ixp4xx: Rewrite to use device tree (2021-08-04 12:20:44 +0200)

----------------------------------------------------------------
IXP4xx driver updates for modernizing the IXP4xx platforms,
taregeted for v5.15:

- Add DT bindings to the expansion bus and PATA libata driver.

- Add a new expansion bus driver.

- Rewrite the watchdog driver to use the watchdog core and
  spawn from the timer (clocksource) driver.

- Refactor the PATA/libata driver to probe from the device
  tree and use the expansion bus driver to manipulate chip
  select timings directly.

----------------------------------------------------------------
Linus Walleij (8):
      bus: ixp4xx: Add DT bindings for the IXP4xx expansion bus
      bus: ixp4xx: Add a driver for IXP4xx expansion bus
      watchdog: ixp4xx: Rewrite driver to use core
      pata: ixp4xx: Use local dev variable
      pata: ixp4xx: Use IS_ENABLED() to determine endianness
      pata: ixp4xx: Refer to cmd and ctl rather than csN
      pata: ixp4xx: Add DT bindings
      pata: ixp4xx: Rewrite to use device tree

 .../bindings/ata/intel,ixp4xx-compact-flash.yaml   |  61 +++
 .../bus/intel,ixp4xx-expansion-bus-controller.yaml | 168 ++++++++
 MAINTAINERS                                        |   2 +
 drivers/ata/pata_ixp4xx_cf.c                       | 264 +++++++++----
 drivers/bus/Kconfig                                |  11 +
 drivers/bus/Makefile                               |   1 +
 drivers/bus/intel-ixp4xx-eb.c                      | 429 +++++++++++++++++++++
 drivers/clocksource/timer-ixp4xx.c                 |  48 ++-
 drivers/watchdog/Kconfig                           |   1 +
 drivers/watchdog/ixp4xx_wdt.c                      | 283 ++++++--------
 include/linux/platform_data/pata_ixp4xx_cf.h       |   4 +-
 11 files changed, 1014 insertions(+), 258 deletions(-)
 create mode 100644
Documentation/devicetree/bindings/ata/intel,ixp4xx-compact-flash.yaml
 create mode 100644
Documentation/devicetree/bindings/bus/intel,ixp4xx-expansion-bus-controller.yaml
 create mode 100644 drivers/bus/intel-ixp4xx-eb.c


From andreyknvl at gmail.com  Wed Aug  4 05:44:19 2021
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Wed, 4 Aug 2021 14:44:19 +0200
Subject: [PATCH v3 1/2] kasan, kmemleak: reset tags when scanning block
In-Reply-To: <20210804090957.12393-2-Kuan-Ying.Lee@mediatek.com>
References: <20210804090957.12393-1-Kuan-Ying.Lee@mediatek.com>
 <20210804090957.12393-2-Kuan-Ying.Lee@mediatek.com>
Message-ID: <CA+fCnZfTfXt9_invV=wfyf_Z-Db_nutGjzf_MiFpnfdbm487Ww@mail.gmail.com>

On Wed, Aug 4, 2021 at 11:10 AM Kuan-Ying Lee
<Kuan-Ying.Lee at mediatek.com> wrote:
>
> Kmemleak need to scan kernel memory to check memory leak.
> With hardware tag-based kasan enabled, when it scans on
> the invalid slab and dereference, the issue will occur
> as below.
>
> Hardware tag-based KASAN doesn't use compiler instrumentation, we
> can not use kasan_disable_current() to ignore tag check.
>
> Based on the below report, there are 11 0xf7 granules, which amounts to
> 176 bytes, and the object is allocated from the kmalloc-256 cache. So
> when kmemleak accesses the last 256-176 bytes, it causes faults, as
> those are marked with KASAN_KMALLOC_REDZONE == KASAN_TAG_INVALID ==
> 0xfe.
>
> Thus, we reset tags before accessing metadata to avoid from false positives.
>
> [  151.905804] ==================================================================
> [  151.907120] BUG: KASAN: out-of-bounds in scan_block+0x58/0x170
> [  151.908773] Read at addr f7ff0000c0074eb0 by task kmemleak/138
> [  151.909656] Pointer tag: [f7], memory tag: [fe]
> [  151.910195]
> [  151.910876] CPU: 7 PID: 138 Comm: kmemleak Not tainted 5.14.0-rc2-00001-g8cae8cd89f05-dirty #134
> [  151.912085] Hardware name: linux,dummy-virt (DT)
> [  151.912868] Call trace:
> [  151.913211]  dump_backtrace+0x0/0x1b0
> [  151.913796]  show_stack+0x1c/0x30
> [  151.914248]  dump_stack_lvl+0x68/0x84
> [  151.914778]  print_address_description+0x7c/0x2b4
> [  151.915340]  kasan_report+0x138/0x38c
> [  151.915804]  __do_kernel_fault+0x190/0x1c4
> [  151.916386]  do_tag_check_fault+0x78/0x90
> [  151.916856]  do_mem_abort+0x44/0xb4
> [  151.917308]  el1_abort+0x40/0x60
> [  151.917754]  el1h_64_sync_handler+0xb4/0xd0
> [  151.918270]  el1h_64_sync+0x78/0x7c
> [  151.918714]  scan_block+0x58/0x170
> [  151.919157]  scan_gray_list+0xdc/0x1a0
> [  151.919626]  kmemleak_scan+0x2ac/0x560
> [  151.920129]  kmemleak_scan_thread+0xb0/0xe0
> [  151.920635]  kthread+0x154/0x160
> [  151.921115]  ret_from_fork+0x10/0x18
> [  151.921717]
> [  151.922077] Allocated by task 0:
> [  151.922523]  kasan_save_stack+0x2c/0x60
> [  151.923099]  __kasan_kmalloc+0xec/0x104
> [  151.923502]  __kmalloc+0x224/0x3c4
> [  151.924172]  __register_sysctl_paths+0x200/0x290
> [  151.924709]  register_sysctl_table+0x2c/0x40
> [  151.925175]  sysctl_init+0x20/0x34
> [  151.925665]  proc_sys_init+0x3c/0x48
> [  151.926136]  proc_root_init+0x80/0x9c
> [  151.926547]  start_kernel+0x648/0x6a4
> [  151.926987]  __primary_switched+0xc0/0xc8
> [  151.927557]
> [  151.927994] Freed by task 0:
> [  151.928340]  kasan_save_stack+0x2c/0x60
> [  151.928766]  kasan_set_track+0x2c/0x40
> [  151.929173]  kasan_set_free_info+0x44/0x54
> [  151.929568]  ____kasan_slab_free.constprop.0+0x150/0x1b0
> [  151.930063]  __kasan_slab_free+0x14/0x20
> [  151.930449]  slab_free_freelist_hook+0xa4/0x1fc
> [  151.930924]  kfree+0x1e8/0x30c
> [  151.931285]  put_fs_context+0x124/0x220
> [  151.931731]  vfs_kern_mount.part.0+0x60/0xd4
> [  151.932280]  kern_mount+0x24/0x4c
> [  151.932686]  bdev_cache_init+0x70/0x9c
> [  151.933122]  vfs_caches_init+0xdc/0xf4
> [  151.933578]  start_kernel+0x638/0x6a4
> [  151.934014]  __primary_switched+0xc0/0xc8
> [  151.934478]
> [  151.934757] The buggy address belongs to the object at ffff0000c0074e00
> [  151.934757]  which belongs to the cache kmalloc-256 of size 256
> [  151.935744] The buggy address is located 176 bytes inside of
> [  151.935744]  256-byte region [ffff0000c0074e00, ffff0000c0074f00)
> [  151.936702] The buggy address belongs to the page:
> [  151.937378] page:(____ptrval____) refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x100074
> [  151.938682] head:(____ptrval____) order:2 compound_mapcount:0 compound_pincount:0
> [  151.939440] flags: 0xbfffc0000010200(slab|head|node=0|zone=2|lastcpupid=0xffff|kasantag=0x0)
> [  151.940886] raw: 0bfffc0000010200 0000000000000000 dead000000000122 f5ff0000c0002300
> [  151.941634] raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000
> [  151.942353] page dumped because: kasan: bad access detected
> [  151.942923]
> [  151.943214] Memory state around the buggy address:
> [  151.943896]  ffff0000c0074c00: f0 f0 f0 f0 f0 f0 f0 f0 f0 fe fe fe fe fe fe fe
> [  151.944857]  ffff0000c0074d00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
> [  151.945892] >ffff0000c0074e00: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 fe fe fe fe fe
> [  151.946407]                                                     ^
> [  151.946939]  ffff0000c0074f00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
> [  151.947445]  ffff0000c0075000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> [  151.947999] ==================================================================
> [  151.948524] Disabling lock debugging due to kernel taint
> [  156.434569] kmemleak: 181 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
>
> Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Marco Elver <elver at google.com>
> Cc: Andrey Konovalov <andreyknvl at gmail.com>
> ---
>  mm/kmemleak.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/mm/kmemleak.c b/mm/kmemleak.c
> index 228a2fbe0657..73d46d16d575 100644
> --- a/mm/kmemleak.c
> +++ b/mm/kmemleak.c
> @@ -290,7 +290,7 @@ static void hex_dump_object(struct seq_file *seq,
>         warn_or_seq_printf(seq, "  hex dump (first %zu bytes):\n", len);
>         kasan_disable_current();
>         warn_or_seq_hex_dump(seq, DUMP_PREFIX_NONE, HEX_ROW_SIZE,
> -                            HEX_GROUP_SIZE, ptr, len, HEX_ASCII);
> +                            HEX_GROUP_SIZE, kasan_reset_tag((void *)ptr), len, HEX_ASCII);
>         kasan_enable_current();
>  }
>
> @@ -1171,7 +1171,7 @@ static bool update_checksum(struct kmemleak_object *object)
>
>         kasan_disable_current();
>         kcsan_disable_current();
> -       object->checksum = crc32(0, (void *)object->pointer, object->size);
> +       object->checksum = crc32(0, kasan_reset_tag((void *)object->pointer), object->size);
>         kasan_enable_current();
>         kcsan_enable_current();
>
> @@ -1246,7 +1246,7 @@ static void scan_block(void *_start, void *_end,
>                         break;
>
>                 kasan_disable_current();
> -               pointer = *ptr;
> +               pointer = *(unsigned long *)kasan_reset_tag((void *)ptr);
>                 kasan_enable_current();
>
>                 untagged_ptr = (unsigned long)kasan_reset_tag((void *)pointer);
> --
> 2.18.0
>

Reviewed-by: Andrey Konovalov <andreyknvl at gmail.com>


From andreyknvl at gmail.com  Wed Aug  4 05:44:22 2021
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Wed, 4 Aug 2021 14:44:22 +0200
Subject: [PATCH v3 2/2] kasan, slub: reset tag when printing address
In-Reply-To: <20210804090957.12393-3-Kuan-Ying.Lee@mediatek.com>
References: <20210804090957.12393-1-Kuan-Ying.Lee@mediatek.com>
 <20210804090957.12393-3-Kuan-Ying.Lee@mediatek.com>
Message-ID: <CA+fCnZd6d9yFZZBM-zPOC54ZiHGnCxV-XiYrCfbCTzzhRV8H1w@mail.gmail.com>

On Wed, Aug 4, 2021 at 11:10 AM Kuan-Ying Lee
<Kuan-Ying.Lee at mediatek.com> wrote:
>
> The address still includes the tags when it is printed.
> With hardware tag-based kasan enabled, we will get a
> false positive KASAN issue when we access metadata.
>
> Reset the tag before we access the metadata.
>
> Fixes: aa1ef4d7b3f6 ("kasan, mm: reset tags when accessing metadata")
> Signed-off-by: Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com>
> Reviewed-by: Marco Elver <elver at google.com>
> ---
>  mm/slub.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/mm/slub.c b/mm/slub.c
> index b6c5205252eb..f77d8cd79ef7 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -576,8 +576,8 @@ static void print_section(char *level, char *text, u8 *addr,
>                           unsigned int length)
>  {
>         metadata_access_enable();
> -       print_hex_dump(level, kasan_reset_tag(text), DUMP_PREFIX_ADDRESS,
> -                       16, 1, addr, length, 1);
> +       print_hex_dump(level, text, DUMP_PREFIX_ADDRESS,
> +                       16, 1, kasan_reset_tag((void *)addr), length, 1);
>         metadata_access_disable();
>  }
>
> --
> 2.18.0

Reviewed-by: Andrey Konovalov <andreyknvl at gmail.com>

Thanks!


From michael.riesch at wolfvision.net  Wed Aug  4 06:06:18 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed,  4 Aug 2021 15:06:18 +0200
Subject: [PATCH v2 0/7] arm64: dts: rockchip: rk3568-evb1-v10: add sd card
 support
Message-ID: <20210804130625.15449-1-michael.riesch@wolfvision.net>

Hi all,

This series enables the SD card reader on the RK3568 EVB1
and completes the support for the on-board eMMC.

As the PMU IO domains are required, the patch series that
introduces support for the RK3568 [1] has been integrated
in this series to bring this mainline.

Best regards,
Michael

[1] https://patchwork.kernel.org/project/linux-rockchip/list/?series=489383

v2:
- rename alias to match convention
- add support for rk3568 io domains

Jianqun Xu (1):
  soc: rockchip: io-domain: add rk3568 support

Michael Riesch (6):
  dt-bindings: power: add rk3568-pmu-io-domain support
  arm64: dts: rockchip: rk3568-evb1-v10: add regulators of rk809 pmic
  arm64: dts: rockchip: enable io domains for rk356x
  arm64: dts: rockchip: rk3568-evb1-v10: enable io domains
  arm64: dts: rockchip: rk3568-evb1-v10: add pinctrl and alias to emmc
    node
  arm64: dts: rockchip: rk3568-evb1-v10: add node for sd card

 .../bindings/power/rockchip-io-domain.yaml    |  30 +++
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 237 ++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |   5 +
 drivers/soc/rockchip/io-domain.c              |  88 ++++++-
 4 files changed, 352 insertions(+), 8 deletions(-)

-- 
2.20.1



From lkp at intel.com  Wed Aug  4 06:06:03 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 04 Aug 2021 21:06:03 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS a8eee86317f11e97990d755d4615c1c0db203d08
Message-ID: <610a90bb.0hh8X1ISzEPFQW4e%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: a8eee86317f11e97990d755d4615c1c0db203d08  soc: ixp4xx/qmgr: fix invalid __iomem access

elapsed time: 1320m

configs tested: 112
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210803
sh                           se7724_defconfig
sh                         microdev_defconfig
m68k                           sun3_defconfig
mips                          ath79_defconfig
openrisc                 simple_smp_defconfig
arm                        spear3xx_defconfig
powerpc                 mpc832x_mds_defconfig
mips                        qi_lb60_defconfig
arm                           u8500_defconfig
arm                     am200epdkit_defconfig
mips                        nlm_xlr_defconfig
h8300                       h8s-sim_defconfig
m68k                            q40_defconfig
arm                       cns3420vb_defconfig
arm                        mini2440_defconfig
mips                       bmips_be_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From michael.riesch at wolfvision.net  Wed Aug  4 06:06:19 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed,  4 Aug 2021 15:06:19 +0200
Subject: [PATCH v2 1/7] soc: rockchip: io-domain: add rk3568 support
In-Reply-To: <20210804130625.15449-1-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
Message-ID: <20210804130625.15449-2-michael.riesch@wolfvision.net>

From: Jianqun Xu <jay.xu at rock-chips.com>

The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.

This patch make the write to be a operation, allow rk3568 uses a private
register set function.

Since the 2.5v is not used on RK3568, so the driver only set
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode

There is not register order requirement which has been cleared by our IC
team.

Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
---
 drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
 1 file changed, 80 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
index cf8182fc3642..13c446fd33a9 100644
--- a/drivers/soc/rockchip/io-domain.c
+++ b/drivers/soc/rockchip/io-domain.c
@@ -51,13 +51,11 @@
 #define RK3399_PMUGRF_CON0_VSEL		BIT(8)
 #define RK3399_PMUGRF_VSEL_SUPPLY_NUM	9
 
-struct rockchip_iodomain;
+#define RK3568_PMU_GRF_IO_VSEL0		(0x0140)
+#define RK3568_PMU_GRF_IO_VSEL1		(0x0144)
+#define RK3568_PMU_GRF_IO_VSEL2		(0x0148)
 
-struct rockchip_iodomain_soc_data {
-	int grf_offset;
-	const char *supply_names[MAX_SUPPLIES];
-	void (*init)(struct rockchip_iodomain *iod);
-};
+struct rockchip_iodomain;
 
 struct rockchip_iodomain_supply {
 	struct rockchip_iodomain *iod;
@@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
 	int idx;
 };
 
+struct rockchip_iodomain_soc_data {
+	int grf_offset;
+	const char *supply_names[MAX_SUPPLIES];
+	void (*init)(struct rockchip_iodomain *iod);
+	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
+};
+
 struct rockchip_iodomain {
 	struct device *dev;
 	struct regmap *grf;
 	const struct rockchip_iodomain_soc_data *soc_data;
 	struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
+	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
 };
 
+static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
+{
+	struct rockchip_iodomain *iod = supply->iod;
+	u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
+	u32 val0, val1;
+	int b;
+
+	switch (supply->idx) {
+	case 0: /* pmuio1 */
+		break;
+	case 1: /* pmuio2 */
+		b = supply->idx;
+		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
+		b = supply->idx + 4;
+		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
+
+		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
+		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
+		break;
+	case 3: /* vccio2 */
+		break;
+	case 2: /* vccio1 */
+	case 4: /* vccio3 */
+	case 5: /* vccio4 */
+	case 6: /* vccio5 */
+	case 7: /* vccio6 */
+	case 8: /* vccio7 */
+		b = supply->idx - 1;
+		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
+		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
+
+		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
+		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
 static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
 				   int uV)
 {
@@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
 			return NOTIFY_BAD;
 	}
 
-	ret = rockchip_iodomain_write(supply, uV);
+	ret = supply->iod->write(supply, uV);
 	if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
 		return NOTIFY_BAD;
 
@@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
 	.init = rk3399_pmu_iodomain_init,
 };
 
+static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
+	.grf_offset = 0x140,
+	.supply_names = {
+		"pmuio1",
+		"pmuio2",
+		"vccio1",
+		"vccio2",
+		"vccio3",
+		"vccio4",
+		"vccio5",
+		"vccio6",
+		"vccio7",
+	},
+	.write = rk3568_iodomain_write,
+};
+
 static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
 	.grf_offset = 0x404,
 	.supply_names = {
@@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
 		.compatible = "rockchip,rk3399-pmu-io-voltage-domain",
 		.data = &soc_data_rk3399_pmu
 	},
+	{
+		.compatible = "rockchip,rk3568-pmu-io-voltage-domain",
+		.data = &soc_data_rk3568_pmu
+	},
 	{
 		.compatible = "rockchip,rv1108-io-voltage-domain",
 		.data = &soc_data_rv1108
@@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
 	match = of_match_node(rockchip_iodomain_match, np);
 	iod->soc_data = match->data;
 
+	if (iod->soc_data->write)
+		iod->write = iod->soc_data->write;
+	else
+		iod->write = rockchip_iodomain_write;
+
 	parent = pdev->dev.parent;
 	if (parent && parent->of_node) {
 		iod->grf = syscon_node_to_regmap(parent->of_node);
@@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
 		supply->reg = reg;
 		supply->nb.notifier_call = rockchip_iodomain_notify;
 
-		ret = rockchip_iodomain_write(supply, uV);
+		ret = iod->write(supply, uV);
 		if (ret) {
 			supply->reg = NULL;
 			goto unreg_notify;
-- 
2.20.1



From michael.riesch at wolfvision.net  Wed Aug  4 06:06:20 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed,  4 Aug 2021 15:06:20 +0200
Subject: [PATCH v2 2/7] dt-bindings: power: add rk3568-pmu-io-domain support
In-Reply-To: <20210804130625.15449-1-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
Message-ID: <20210804130625.15449-3-michael.riesch@wolfvision.net>

Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
[add soc-specific section]
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../bindings/power/rockchip-io-domain.yaml    | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.yaml b/Documentation/devicetree/bindings/power/rockchip-io-domain.yaml
index 121bec56b2b0..1727bf108979 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.yaml
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.yaml
@@ -55,6 +55,7 @@ properties:
       - rockchip,rk3368-pmu-io-voltage-domain
       - rockchip,rk3399-io-voltage-domain
       - rockchip,rk3399-pmu-io-voltage-domain
+      - rockchip,rk3568-pmu-io-voltage-domain
       - rockchip,rv1108-io-voltage-domain
       - rockchip,rv1108-pmu-io-voltage-domain
 
@@ -74,6 +75,7 @@ allOf:
   - $ref: "#/$defs/rk3368-pmu"
   - $ref: "#/$defs/rk3399"
   - $ref: "#/$defs/rk3399-pmu"
+  - $ref: "#/$defs/rk3568-pmu"
   - $ref: "#/$defs/rv1108"
   - $ref: "#/$defs/rv1108-pmu"
 
@@ -282,6 +284,34 @@ $defs:
         pmu1830-supply:
           description: The supply connected to PMUIO2_VDD.
 
+  rk3568-pmu:
+    if:
+      properties:
+        compatible:
+          contains:
+            const: rockchip,rk3568-pmu-io-voltage-domain
+
+    then:
+      properties:
+        pmuio1-supply:
+          description: The supply connected to PMUIO1.
+        pmuio2-supply:
+          description: The supply connected to PMUIO2.
+        vccio1-supply:
+          description: The supply connected to VCCIO1.
+        vccio2-supply:
+          description: The supply connected to VCCIO2.
+        vccio3-supply:
+          description: The supply connected to VCCIO3.
+        vccio4-supply:
+          description: The supply connected to VCCIO4.
+        vccio5-supply:
+          description: The supply connected to VCCIO5.
+        vccio6-supply:
+          description: The supply connected to VCCIO6.
+        vccio7-supply:
+          description: The supply connected to VCCIO7.
+
   rv1108:
     if:
       properties:
-- 
2.20.1



From michael.riesch at wolfvision.net  Wed Aug  4 06:06:21 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed,  4 Aug 2021 15:06:21 +0200
Subject: [PATCH v2 3/7] arm64: dts: rockchip: rk3568-evb1-v10: add regulators
 of rk809 pmic
In-Reply-To: <20210804130625.15449-1-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
Message-ID: <20210804130625.15449-4-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 206 ++++++++++++++++++
 1 file changed, 206 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 65e536c78d2e..f682144a1892 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -104,6 +104,203 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>;
+		rockchip,system-power-controller;
+		wakeup-source;
+
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-init-microvolt = <900000>;
+				regulator-ramp-delay = <6001>;
+				regulator-initial-mode = <0x2>;
+				regulator-name = "vdd_logic";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-init-microvolt = <900000>;
+				regulator-ramp-delay = <6001>;
+				regulator-initial-mode = <0x2>;
+				regulator-name = "vdd_gpu";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+				regulator-name = "vcc_ddr";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-init-microvolt = <900000>;
+				regulator-ramp-delay = <6001>;
+				regulator-initial-mode = <0x2>;
+				regulator-name = "vdd_npu";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_1v8";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-name = "vdda0v9_image";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-name = "vdda_0v9";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+				regulator-name = "vdda0v9_pmu";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_acodec";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vccio_sd";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-name = "vcc3v3_pmu";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca_1v8";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca1v8_pmu";
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcca1v8_image";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc_3v3";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
 &mdio0 {
 	rgmii_phy0: ethernet-phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
@@ -124,6 +321,15 @@
 	};
 };
 
+&pinctrl {
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
 &sdhci {
 	bus-width = <8>;
 	max-frequency = <200000000>;
-- 
2.20.1



From michael.riesch at wolfvision.net  Wed Aug  4 06:06:22 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed,  4 Aug 2021 15:06:22 +0200
Subject: [PATCH v2 4/7] arm64: dts: rockchip: enable io domains for rk356x
In-Reply-To: <20210804130625.15449-1-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
Message-ID: <20210804130625.15449-5-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 3e90a8832bb9..834863940eba 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -203,6 +203,11 @@
 	pmugrf: syscon at fdc20000 {
 		compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd";
 		reg = <0x0 0xfdc20000 0x0 0x10000>;
+
+		pmu_io_domains: io-domains {
+			compatible = "rockchip,rk3568-pmu-io-voltage-domain";
+			status = "disabled";
+		};
 	};
 
 	grf: syscon at fdc60000 {
-- 
2.20.1



From michael.riesch at wolfvision.net  Wed Aug  4 06:06:23 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed,  4 Aug 2021 15:06:23 +0200
Subject: [PATCH v2 5/7] arm64: dts: rockchip: rk3568-evb1-v10: enable io
 domains
In-Reply-To: <20210804130625.15449-1-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
Message-ID: <20210804130625.15449-6-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index f682144a1892..f3fd4a6813a2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -330,6 +330,19 @@
 	};
 };
 
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_1v8>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	max-frequency = <200000000>;
-- 
2.20.1



From michael.riesch at wolfvision.net  Wed Aug  4 06:06:24 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed,  4 Aug 2021 15:06:24 +0200
Subject: [PATCH v2 6/7] arm64: dts: rockchip: rk3568-evb1-v10: add pinctrl and
 alias to emmc node
In-Reply-To: <20210804130625.15449-1-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
Message-ID: <20210804130625.15449-7-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
v2:
- rename alias to match convention

 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index f3fd4a6813a2..ed96f27c64a3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -16,6 +16,7 @@
 	aliases {
 		ethernet0 = &gmac0;
 		ethernet1 = &gmac1;
+		mmc0 = &sdhci;
 	};
 
 	chosen: chosen {
@@ -347,6 +348,8 @@
 	bus-width = <8>;
 	max-frequency = <200000000>;
 	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
 	status = "okay";
 };
 
-- 
2.20.1



From michael.riesch at wolfvision.net  Wed Aug  4 06:06:25 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed,  4 Aug 2021 15:06:25 +0200
Subject: [PATCH v2 7/7] arm64: dts: rockchip: rk3568-evb1-v10: add node for sd
 card
In-Reply-To: <20210804130625.15449-1-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
Message-ID: <20210804130625.15449-8-michael.riesch@wolfvision.net>

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
v2:
- rename alias to match convention

 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index ed96f27c64a3..c4da6436059d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -17,6 +17,7 @@
 		ethernet0 = &gmac0;
 		ethernet1 = &gmac1;
 		mmc0 = &sdhci;
+		mmc1 = &sdmmc0;
 	};
 
 	chosen: chosen {
@@ -353,6 +354,20 @@
 	status = "okay";
 };
 
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	sd-uhs-sdr104;
+	supports-sd;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
 &uart2 {
 	status = "okay";
 };
-- 
2.20.1



From linus.walleij at linaro.org  Wed Aug  4 06:12:49 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 4 Aug 2021 15:12:49 +0200
Subject: [PATCH 3/3] ARM: Map the lowmem and kernel separately
In-Reply-To: <20210804103658.GP22278@shell.armlinux.org.uk>
References: <20210517145719.110966-1-linus.walleij@linaro.org>
 <20210517145719.110966-4-linus.walleij@linaro.org>
 <20210730202259.dbifugsvry5vjdr7@earthen>
 <CACRpkdYAzGzqfdREogAFnyGqSnHLQmdCR=GZ=YqhzoTUA0MfCA@mail.gmail.com>
 <f3eb9c84-19c6-cba2-ffcc-2dbcb48051ad@ti.com>
 <20210803104932.GM22278@shell.armlinux.org.uk>
 <CACRpkdaOub9EJFGy8+kWLN13wq2V_XSXrnrfxiUCvb6gdWKmBg@mail.gmail.com>
 <20210804103658.GP22278@shell.armlinux.org.uk>
Message-ID: <CACRpkdaK2utObJgfKZJW6fcu0s6wT8VLjDwYyntYPq+e5h_RQw@mail.gmail.com>

Thanks so much for explaining this Russell!

On Wed, Aug 4, 2021 at 12:37 PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:

> My guess would be the problem is that kernel_sec_start and
> kernel_sec_end are not being adjusted, and are still pointing at
> the low physical addresses rather than the high ones.
> Consequently, kernel_x_start and kernel_nx_end points at the low phys
> space, but kernel_x_end and kernel_nx_start points to the high phys
> space.

I bet this is right, I will make a patch for Nishanth to test!

Thanks a *lot* for your elaborate explanation.

Yours,
Linus Walleij


From kishon at ti.com  Wed Aug  4 06:29:09 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 4 Aug 2021 18:59:09 +0530
Subject: [PATCH v2 0/3] PCI: Add legacy interrupt support in pci-j721e
Message-ID: <20210804132912.30685-1-kishon@ti.com>

Patch series adds support for legacy interrupt in pci-j721e. There are
two HW implementations of legacy interrupt controller, one specific to
J721E and the other for J7200/AM64.

In both these implementations, the legacy interrupt is connect to pulse
interrupt of GIC and level to pulse is handled by configuring EOI
register. EOI to convert level to pulse is broken in J721E due to an
errata but is functional in J7200.

v1 of the patch series can be found @ [1]
Patch series is created on top of [2]

Changes from v1:
1) Only the legacy interrupt specific part is sent as part of this
series. Rest are split and sent as a separate series [2]
2) Created irq_chip for legacy interrupt and used it's ops for enabling,
disabling the interrupts.

[1] -> http://lore.kernel.org/r/20210325090936.9306-1-kishon at ti.com
[2] -> http://lore.kernel.org/r/20210803074932.19820-1-kishon at ti.com

Kishon Vijay Abraham I (3):
  dt-bindings: PCI: ti,j721e: Add bindings to specify legacy interrupts
  PCI: j721e: Add PCI legacy interrupt support for J721E
  PCI: j721e: Add PCI legacy interrupt support for J7200

 .../bindings/pci/ti,j721e-pci-host.yaml       |  15 ++
 drivers/pci/controller/cadence/pci-j721e.c    | 150 ++++++++++++++++++
 2 files changed, 165 insertions(+)

-- 
2.17.1



From kishon at ti.com  Wed Aug  4 06:29:10 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 4 Aug 2021 18:59:10 +0530
Subject: [PATCH v2 1/3] dt-bindings: PCI: ti,
 j721e: Add bindings to specify legacy interrupts
In-Reply-To: <20210804132912.30685-1-kishon@ti.com>
References: <20210804132912.30685-1-kishon@ti.com>
Message-ID: <20210804132912.30685-2-kishon@ti.com>

Add bindings to specify interrupt controller for legacy interrupts.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../bindings/pci/ti,j721e-pci-host.yaml           | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
index cc900202df29..f461d7b4c0cc 100644
--- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
+++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
@@ -74,6 +74,11 @@ properties:
 
   msi-map: true
 
+patternProperties:
+  "interrupt-controller":
+    type: object
+    description: interrupt controller to handle legacy interrupts.
+
 required:
   - compatible
   - reg
@@ -97,6 +102,8 @@ unevaluatedProperties: false
 
 examples:
   - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
     #include <dt-bindings/soc/ti,sci_pm_domain.h>
     #include <dt-bindings/gpio/gpio.h>
 
@@ -131,5 +138,13 @@ examples:
             ranges = <0x01000000 0x0 0x10001000  0x00 0x10001000  0x0 0x0010000>,
                      <0x02000000 0x0 0x10011000  0x00 0x10011000  0x0 0x7fef000>;
             dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
+
+
+            pcie0_intc: interrupt-controller {
+                    interrupt-controller;
+                    #interrupt-cells = <1>;
+                    interrupt-parent = <&gic500>;
+                    interrupts = <GIC_SPI 312 IRQ_TYPE_EDGE_RISING>;
+            };
         };
     };
-- 
2.17.1



From kishon at ti.com  Wed Aug  4 06:29:11 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 4 Aug 2021 18:59:11 +0530
Subject: [PATCH v2 2/3] PCI: j721e: Add PCI legacy interrupt support for J721E
In-Reply-To: <20210804132912.30685-1-kishon@ti.com>
References: <20210804132912.30685-1-kishon@ti.com>
Message-ID: <20210804132912.30685-3-kishon@ti.com>

Add PCI legacy interrupt support for J721E. J721E has a single HW
interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
The HW interrupt line connected to GIC is a pulse interrupt whereas
the legacy interrupts by definition is level interrupt. In order to
provide level interrupt functionality to edge interrupt line, PCIe
in J721E has provided IRQ_EOI register.

However due to Errata ID #i2094 ([1]), EOI feature is not enabled in HW
and only a single pulse interrupt will be generated for every
ASSERT_INTx/DEASSERT_INTx.

[1] -> J721E DRA829/TDA4VM Processors Silicon Revision 1.1/1.0 SPRZ455A ?
       DECEMBER 2020 ? REVISED AUGUST 2021
       (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf)

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 85 ++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 2ec037c43bd5..c2e7a78dc31f 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -29,6 +29,13 @@
 #define LINK_DOWN		BIT(1)
 #define J7200_LINK_DOWN		BIT(10)
 
+#define EOI_REG			0x10
+
+#define ENABLE_REG_SYS_0	0x100
+#define STATUS_REG_SYS_0	0x500
+#define STATUS_CLR_REG_SYS_0	0x700
+#define INTx_EN(num)		(1 << (num))
+
 #define J721E_PCIE_USER_CMD_STATUS	0x4
 #define LINK_TRAINING_ENABLE		BIT(0)
 
@@ -59,6 +66,7 @@ struct j721e_pcie {
 	void __iomem		*user_cfg_base;
 	void __iomem		*intd_cfg_base;
 	u32			linkdown_irq_regfield;
+	struct irq_domain	*legacy_irq_domain;
 };
 
 enum j721e_pcie_mode {
@@ -121,6 +129,79 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
 	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
 }
 
+static void j721e_pcie_v1_legacy_irq_handler(struct irq_desc *desc)
+{
+	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int i, virq;
+	u32 reg;
+
+	chained_irq_enter(chip, desc);
+
+	for (i = 0; i < PCI_NUM_INTX; i++) {
+		reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_0);
+		if (!(reg & INTx_EN(i)))
+			continue;
+
+		virq = irq_find_mapping(pcie->legacy_irq_domain, 3 - i);
+		generic_handle_irq(virq);
+		j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_0, INTx_EN(i));
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static int j721e_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+
+	return 0;
+}
+
+static const struct irq_domain_ops j721e_pcie_intx_domain_ops = {
+	.map = j721e_pcie_intx_map,
+};
+
+static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
+{
+	struct irq_domain *legacy_irq_domain;
+	struct device *dev = pcie->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *intc_node;
+	int irq, i;
+	u32 reg;
+
+	intc_node = of_get_child_by_name(node, "interrupt-controller");
+	if (!intc_node) {
+		dev_dbg(dev, "interrupt-controller node is absent. Legacy INTR not supported\n");
+		return 0;
+	}
+
+	irq = irq_of_parse_and_map(intc_node, 0);
+	if (!irq) {
+		dev_err(dev, "Failed to parse and map legacy irq\n");
+		return -EINVAL;
+	}
+	irq_set_chained_handler_and_data(irq, j721e_pcie_v1_legacy_irq_handler, pcie);
+
+	legacy_irq_domain = irq_domain_add_linear(intc_node, PCI_NUM_INTX,
+						  &j721e_pcie_intx_domain_ops, pcie);
+	if (!legacy_irq_domain) {
+		dev_err(dev, "Failed to add irq domain for legacy irqs\n");
+		return -EINVAL;
+	}
+	pcie->legacy_irq_domain = legacy_irq_domain;
+
+	for (i = 0; i < PCI_NUM_INTX; i++) {
+		reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_0);
+		reg |= INTx_EN(i);
+		j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_0, reg);
+	}
+
+	return 0;
+}
+
 static int j721e_pcie_start_link(struct cdns_pcie *cdns_pcie)
 {
 	struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
@@ -433,6 +514,10 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 			goto err_get_sync;
 		}
 
+		ret = j721e_pcie_config_legacy_irq(pcie);
+		if (ret < 0)
+			goto err_get_sync;
+
 		bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
 		if (!bridge) {
 			ret = -ENOMEM;
-- 
2.17.1



From kishon at ti.com  Wed Aug  4 06:29:12 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 4 Aug 2021 18:59:12 +0530
Subject: [PATCH v2 3/3] PCI: j721e: Add PCI legacy interrupt support for J7200
In-Reply-To: <20210804132912.30685-1-kishon@ti.com>
References: <20210804132912.30685-1-kishon@ti.com>
Message-ID: <20210804132912.30685-4-kishon@ti.com>

Add PCI legacy interrupt support for J7200. J7200 has a single HW
interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
The HW interrupt line connected to GIC is a pulse interrupt whereas
the legacy interrupts by definition is level interrupt. In order to
provide level interrupt functionality to edge interrupt line, PCIe
in J7200 has provided USER_EOI_REG register. When the SW writes to
USER_EOI_REG register after handling the interrupt, the IP checks the
state of legacy interrupt and re-triggers pulse interrupt invoking
the handler again. (Note that the errata in J721E where EOI is not
implemented is fixed in J7200).

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 77 ++++++++++++++++++++--
 1 file changed, 71 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index c2e7a78dc31f..be8464232be0 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -36,12 +36,24 @@
 #define STATUS_CLR_REG_SYS_0	0x700
 #define INTx_EN(num)		(1 << (num))
 
+#define ENABLE_REG_SYS_1	0x104
+#define STATUS_REG_SYS_1	0x504
+#define SYS1_INTx_EN(num)	(1 << (22 + (num)))
+
 #define J721E_PCIE_USER_CMD_STATUS	0x4
 #define LINK_TRAINING_ENABLE		BIT(0)
 
 #define J721E_PCIE_USER_LINKSTATUS	0x14
 #define LINK_STATUS			GENMASK(1, 0)
 
+#define USER_EOI_REG		0xC8
+enum eoi_reg {
+	EOI_DOWNSTREAM_INTERRUPT,
+	EOI_FLR_INTERRUPT,
+	EOI_LEGACY_INTERRUPT,
+	EOI_POWER_STATE_INTERRUPT,
+};
+
 enum link_status {
 	NO_RECEIVERS_DETECTED,
 	LINK_TRAINING_IN_PROGRESS,
@@ -67,6 +79,7 @@ struct j721e_pcie {
 	void __iomem		*intd_cfg_base;
 	u32			linkdown_irq_regfield;
 	struct irq_domain	*legacy_irq_domain;
+	unsigned int		is_intc_v1:1;
 };
 
 enum j721e_pcie_mode {
@@ -76,6 +89,7 @@ enum j721e_pcie_mode {
 
 struct j721e_pcie_data {
 	enum j721e_pcie_mode	mode;
+	unsigned int		is_intc_v1:1;
 	unsigned int		quirk_retrain_flag:1;
 	unsigned int		quirk_detect_quiet_flag:1;
 	u32			linkdown_irq_regfield;
@@ -129,6 +143,39 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
 	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
 }
 
+static void j721e_pcie_legacy_irq_handler(struct irq_desc *desc)
+{
+	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int i, virq;
+	u32 reg;
+
+	chained_irq_enter(chip, desc);
+
+	for (i = 0; i < PCI_NUM_INTX; i++) {
+		reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_1);
+		if (!(reg & SYS1_INTx_EN(i)))
+			continue;
+
+		virq = irq_find_mapping(pcie->legacy_irq_domain, i);
+		generic_handle_irq(virq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void j721e_pcie_irq_eoi(struct irq_data *data)
+{
+	struct j721e_pcie *pcie = irq_data_get_irq_chip_data(data);
+
+	j721e_pcie_user_writel(pcie, USER_EOI_REG, EOI_LEGACY_INTERRUPT);
+}
+
+struct irq_chip j721e_pcie_irq_chip = {
+	.name		= "J721E-PCIE-INTX",
+	.irq_eoi	= j721e_pcie_irq_eoi,
+};
+
 static void j721e_pcie_v1_legacy_irq_handler(struct irq_desc *desc)
 {
 	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
@@ -153,8 +200,14 @@ static void j721e_pcie_v1_legacy_irq_handler(struct irq_desc *desc)
 
 static int j721e_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq)
 {
-	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
-	irq_set_chip_data(irq, domain->host_data);
+	struct j721e_pcie *pcie = domain->host_data;
+
+	if (pcie->is_intc_v1)
+		irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
+	else
+		irq_set_chip_and_handler(irq, &j721e_pcie_irq_chip, handle_fasteoi_irq);
+
+	irq_set_chip_data(irq, pcie);
 
 	return 0;
 }
@@ -183,7 +236,11 @@ static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
 		dev_err(dev, "Failed to parse and map legacy irq\n");
 		return -EINVAL;
 	}
-	irq_set_chained_handler_and_data(irq, j721e_pcie_v1_legacy_irq_handler, pcie);
+
+	if (pcie->is_intc_v1)
+		irq_set_chained_handler_and_data(irq, j721e_pcie_v1_legacy_irq_handler, pcie);
+	else
+		irq_set_chained_handler_and_data(irq, j721e_pcie_legacy_irq_handler, pcie);
 
 	legacy_irq_domain = irq_domain_add_linear(intc_node, PCI_NUM_INTX,
 						  &j721e_pcie_intx_domain_ops, pcie);
@@ -194,9 +251,15 @@ static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
 	pcie->legacy_irq_domain = legacy_irq_domain;
 
 	for (i = 0; i < PCI_NUM_INTX; i++) {
-		reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_0);
-		reg |= INTx_EN(i);
-		j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_0, reg);
+		if (pcie->is_intc_v1) {
+			reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_0);
+			reg |= INTx_EN(i);
+			j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_0, reg);
+		} else {
+			reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_1);
+			reg |= SYS1_INTx_EN(i);
+			j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_1, reg);
+		}
 	}
 
 	return 0;
@@ -372,6 +435,7 @@ static const struct j721e_pcie_data j721e_pcie_rc_data = {
 	.quirk_retrain_flag = true,
 	.byte_access_allowed = false,
 	.linkdown_irq_regfield = LINK_DOWN,
+	.is_intc_v1 = true,
 };
 
 static const struct j721e_pcie_data j721e_pcie_ep_data = {
@@ -514,6 +578,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 			goto err_get_sync;
 		}
 
+		pcie->is_intc_v1 = data->is_intc_v1;
 		ret = j721e_pcie_config_legacy_irq(pcie);
 		if (ret < 0)
 			goto err_get_sync;
-- 
2.17.1



From arnd at arndb.de  Wed Aug  4 06:50:45 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 4 Aug 2021 15:50:45 +0200
Subject: [PATCH 0/4] ARM: dts: sti: remove clk_ignore_unused from bootargs
In-Reply-To: <20210803124506.23365-1-patrice.chotard@foss.st.com>
References: <20210803124506.23365-1-patrice.chotard@foss.st.com>
Message-ID: <CAK8P3a06_vUXghtvp4jTMEc4jV7RW8XmbUmgfrsoH_BSZ+awJQ@mail.gmail.com>

On Tue, Aug 3, 2021 at 2:45 PM <patrice.chotard at foss.st.com> wrote:
>
> From: Patrice Chotard <patrice.chotard at foss.st.com>
>
> Remove clk_ignore_unused from bootargs from STi boards DT.

The patches look good to me, but I'm not sure what you expect me to do
here, as you have added soc at kernel.org to Cc:, and other addresses to To:

I have dropped them from patchwork for the moment. When you want
them to be applied to the soc tree, please resend or send a pull request
to:soc at kernel.org, until then, please leave out that address so it does
not get into patchwork.

      Arnd


From Mason.Zhang at mediatek.com  Wed Aug  4 06:36:31 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Wed, 4 Aug 2021 21:36:31 +0800
Subject: [PATCH v3 0/2] spi cs_timing restructure
Message-ID: <20210804133630.18519-1-Mason.Zhang@mediatek.com>

Hello,
This patchset has restructure spi cs_timing, as we know spi core has
removed spi_set_cs_timing() API, it is a correct decision because it
asked spi devices to call it in one more time.
so we need find another way to support user set cs_timing. Actually,
spi_device set spi_delay for cs_timing is enough, and about how to
set cs_timing, just put it one the master driver.
We have test this patch in mediatek platform, it can compeletly meets
our needs.

Changed in v2:
  - fix tegra spi build err

Changed in v3:
  - merged patch2/3/4 for build pass

Mason Zhang (2):
  spi: move cs spi_delay to spi_device
  spi: modify set_cs_timing parameter

 drivers/spi/spi-mt65xx.c   | 107 +++++++++++++++++++++----------------
 drivers/spi/spi-tegra114.c |   8 +--
 drivers/spi/spi.c          |   6 +--
 include/linux/spi/spi.h    |  23 ++++----
 4 files changed, 78 insertions(+), 66 deletions(-)

-- 
2.18.0

From Mason.Zhang at mediatek.com  Wed Aug  4 06:37:47 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Wed, 4 Aug 2021 21:37:47 +0800
Subject: [PATCH v3 2/2] spi: modify set_cs_timing parameter
Message-ID: <20210804133746.6742-1-Mason.Zhang@mediatek.com>

This patch modified set_cs_timing parameter, no need pass in spi_delay
to set_cs_timing callback.
By the way, we modified the mediatek and tegra114 spi driver to fix build err.
In mediatek spi driver, We have support set absolute time not clk_count,
and call this function in prepare_message not user's API.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 drivers/spi/spi-mt65xx.c   | 107 +++++++++++++++++++++----------------
 drivers/spi/spi-tegra114.c |   8 +--
 include/linux/spi/spi.h    |   3 +-
 3 files changed, 66 insertions(+), 52 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 6f2925118b98..bb09592bc009 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -208,6 +208,65 @@ static void mtk_spi_reset(struct mtk_spi *mdata)
 	writel(reg_val, mdata->base + SPI_CMD_REG);
 }
 
+static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
+{
+	struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
+	struct spi_delay *cs_setup = &spi->cs_setup;
+	struct spi_delay *cs_hold = &spi->cs_hold;
+	struct spi_delay *cs_inactive = &spi->cs_inactive;
+	u16 setup, hold, inactive;
+	u32 reg_val;
+	int delay;
+
+	delay = spi_delay_to_ns(cs_setup, NULL);
+	if (delay < 0)
+		return delay;
+	setup = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000;
+
+	delay = spi_delay_to_ns(cs_hold, NULL);
+	if (delay < 0)
+		return delay;
+	hold = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000;
+
+	delay = spi_delay_to_ns(cs_inactive, NULL);
+	if (delay < 0)
+		return delay;
+	inactive = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000;
+
+	setup    = setup ? setup : 1;
+	hold     = hold ? hold : 1;
+	inactive = inactive ? inactive : 1;
+
+	reg_val = readl(mdata->base + SPI_CFG0_REG);
+	if (mdata->dev_comp->enhance_timing) {
+		hold = min(hold, 0xffff);
+		setup = min(setup, 0xffff);
+		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
+		reg_val |= (((hold - 1) & 0xffff)
+			   << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
+		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
+		reg_val |= (((setup - 1) & 0xffff)
+			   << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
+	} else {
+		hold = min(hold, 0xff);
+		setup = min(setup, 0xff);
+		reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
+		reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+		reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
+		reg_val |= (((setup - 1) & 0xff)
+			    << SPI_CFG0_CS_SETUP_OFFSET);
+	}
+	writel(reg_val, mdata->base + SPI_CFG0_REG);
+
+	inactive = min(inactive, 0xff);
+	reg_val = readl(mdata->base + SPI_CFG1_REG);
+	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
+	reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+	writel(reg_val, mdata->base + SPI_CFG1_REG);
+
+	return 0;
+}
+
 static int mtk_spi_prepare_message(struct spi_master *master,
 				   struct spi_message *msg)
 {
@@ -284,6 +343,8 @@ static int mtk_spi_prepare_message(struct spi_master *master,
 		<< SPI_CFG1_GET_TICK_DLY_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
 
+	/* set hw cs timing */
+	mtk_spi_set_hw_cs_timing(spi);
 	return 0;
 }
 
@@ -528,52 +589,6 @@ static bool mtk_spi_can_dma(struct spi_master *master,
 		(unsigned long)xfer->rx_buf % 4 == 0);
 }
 
-static int mtk_spi_set_hw_cs_timing(struct spi_device *spi,
-				    struct spi_delay *setup,
-				    struct spi_delay *hold,
-				    struct spi_delay *inactive)
-{
-	struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
-	u16 setup_dly, hold_dly, inactive_dly;
-	u32 reg_val;
-
-	if ((setup && setup->unit != SPI_DELAY_UNIT_SCK) ||
-	    (hold && hold->unit != SPI_DELAY_UNIT_SCK) ||
-	    (inactive && inactive->unit != SPI_DELAY_UNIT_SCK)) {
-		dev_err(&spi->dev,
-			"Invalid delay unit, should be SPI_DELAY_UNIT_SCK\n");
-		return -EINVAL;
-	}
-
-	setup_dly = setup ? setup->value : 1;
-	hold_dly = hold ? hold->value : 1;
-	inactive_dly = inactive ? inactive->value : 1;
-
-	reg_val = readl(mdata->base + SPI_CFG0_REG);
-	if (mdata->dev_comp->enhance_timing) {
-		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
-		reg_val |= (((hold_dly - 1) & 0xffff)
-			   << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
-		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
-		reg_val |= (((setup_dly - 1) & 0xffff)
-			   << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
-	} else {
-		reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
-		reg_val |= (((hold_dly - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
-		reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
-		reg_val |= (((setup_dly - 1) & 0xff)
-			    << SPI_CFG0_CS_SETUP_OFFSET);
-	}
-	writel(reg_val, mdata->base + SPI_CFG0_REG);
-
-	reg_val = readl(mdata->base + SPI_CFG1_REG);
-	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
-	reg_val |= (((inactive_dly - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
-	writel(reg_val, mdata->base + SPI_CFG1_REG);
-
-	return 0;
-}
-
 static int mtk_spi_setup(struct spi_device *spi)
 {
 	struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 5131141bbf0d..e9de1d958bbd 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -717,12 +717,12 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
 	dma_release_channel(dma_chan);
 }
 
-static int tegra_spi_set_hw_cs_timing(struct spi_device *spi,
-				      struct spi_delay *setup,
-				      struct spi_delay *hold,
-				      struct spi_delay *inactive)
+static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
 {
 	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
+	struct spi_delay *setup = &spi->cs_setup;
+	struct spi_delay *hold = &spi->cs_hold;
+	struct spi_delay *inactive = &spi->cs_inactive;
 	u8 setup_dly, hold_dly, inactive_dly;
 	u32 setup_hold;
 	u32 spi_cs_timing;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 651e19ba3415..fe027efb85c2 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -553,8 +553,7 @@ struct spi_controller {
 	 * to configure specific CS timing through spi_set_cs_timing() after
 	 * spi_setup().
 	 */
-	int (*set_cs_timing)(struct spi_device *spi, struct spi_delay *setup,
-			     struct spi_delay *hold, struct spi_delay *inactive);
+	int (*set_cs_timing)(struct spi_device *spi);
 
 	/* bidirectional bulk transfers
 	 *
-- 
2.18.0

From arnd at arndb.de  Wed Aug  4 06:55:10 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 4 Aug 2021 15:55:10 +0200
Subject: [PATCH v34 0/3] Mainline imx6 based SKOV boards
In-Reply-To: <20210804043439.11757-1-o.rempel@pengutronix.de>
References: <20210804043439.11757-1-o.rempel@pengutronix.de>
Message-ID: <CAK8P3a0285V=N5HPS5grOTQ+q1HF8J6_PsxCLgLvYMsD0hVeUg@mail.gmail.com>

On Wed, Aug 4, 2021 at 6:36 AM Oleksij Rempel <o.rempel at pengutronix.de> wrote:
>
> changes v4:
> - add vref-supply to adc at 0
> - split gpio assignment for the mdio node

Hi Oleksij,

I've dropped the series from the soc patchwork, since this looks like
something that
should go through the i.MX tree. Please make it clear from the cover
letter and from
the 'to' list what you want to happen with the patches, and who should take care
of them.

Any patches that are meant for platform maintainers should not get sent to
soc at kernel.org. If you think you need me to review the patches, you can
send them cc my personal address.

      Arnd


From arnd at kernel.org  Wed Aug  4 06:56:31 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Aug 2021 15:56:31 +0200
Subject: [GIT PULL] Fixes for omaps for v5.14-rc series
In-Reply-To: <pull-1627995895-406133@atomide.com>
References: <pull-1627995895-406133@atomide.com>
Message-ID: <162808537404.328794.8883222389640665372.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 3 Aug 2021 16:05:29 +0300, Tony Lindgren wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.14/fixes-rc5-signed
> 
> [...]

Merged into arm/fixes, thanks!

merge commit: 19c1eb3605a1bcd784726380f520925948b2962e

       Arnd


From arnd at kernel.org  Wed Aug  4 06:56:56 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Aug 2021 15:56:56 +0200
Subject: [GIT PULL] Ux500 DTS changes for the v5.15 kernel cycle
In-Reply-To: <CACRpkdbjBv5ywZZD8rK07d5sLcHsG8o4iYD-3jHO=HLg6-nKnA@mail.gmail.com>
References: <CACRpkdbjBv5ywZZD8rK07d5sLcHsG8o4iYD-3jHO=HLg6-nKnA@mail.gmail.com>
Message-ID: <162808541212.328977.8507226322336641533.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 3 Aug 2021 14:25:15 +0200, Linus Walleij wrote:
> here is a first set of DTS changes for v5.15 that would be nice if
> you could pull into the appropriate DTS branch in the SoC tree.
> 
> The details are in the signed tag, mainly some new phones,
> and some generic fixes.
> 
> Please pull it in!
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 72ee3b4dc2c8c56aca2608a0c04d0eedaf6fdc67

       Arnd


From arnd at kernel.org  Wed Aug  4 06:56:57 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Aug 2021 15:56:57 +0200
Subject: [GIT PULL] ARM: at91: dt for 5.15
In-Reply-To: <20210804085000.13233-1-nicolas.ferre@microchip.com>
References: <20210804085000.13233-1-nicolas.ferre@microchip.com>
Message-ID: <162808541220.328977.6437198660609674733.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 4 Aug 2021 10:50:00 +0200, nicolas.ferre at microchip.com wrote:
> Arnd, Olof,
> 
> Here are the dt changes for 5.15 which contains addition of SAMA7G5, some
> enhancements to current boards and a couple of (low priority) fixes.
> 
> Thanks, best regards,
>   Nicolas
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 8e816b9915a136c12ab726e92412b917d7e514f7

       Arnd


From Mason.Zhang at mediatek.com  Wed Aug  4 06:37:17 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Wed, 4 Aug 2021 21:37:17 +0800
Subject: [PATCH v3 1/2] spi: move cs spi_delay to spi_device
Message-ID: <20210804133716.32040-1-Mason.Zhang@mediatek.com>

As we know, spi core layer has removed spi_set_cs_timing() API.
So this patch moved spi_delay for cs_timing from spi_controller
to spi_device, because cs timing should be set by spi_device but
not controller.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 drivers/spi/spi.c       |  6 +++---
 include/linux/spi/spi.h | 20 +++++++++-----------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c99181165321..5d68e6cd2a18 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -842,9 +842,9 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
 	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
 	    !spi->controller->set_cs_timing) {
 		if (activate)
-			spi_delay_exec(&spi->controller->cs_setup, NULL);
+			spi_delay_exec(&spi->cs_setup, NULL);
 		else
-			spi_delay_exec(&spi->controller->cs_hold, NULL);
+			spi_delay_exec(&spi->cs_hold, NULL);
 	}
 
 	if (spi->mode & SPI_CS_HIGH)
@@ -887,7 +887,7 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
 	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
 	    !spi->controller->set_cs_timing) {
 		if (!activate)
-			spi_delay_exec(&spi->controller->cs_inactive, NULL);
+			spi_delay_exec(&spi->cs_inactive, NULL);
 	}
 }
 
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 97b8d12b5f2b..651e19ba3415 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -147,7 +147,11 @@ extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer);
  *	not using a GPIO line)
  * @word_delay: delay to be inserted between consecutive
  *	words of a transfer
- *
+ * @cs_setup: delay to be introduced by the controller after CS is asserted
+ * @cs_hold: delay to be introduced by the controller before CS is deasserted
+ * @cs_inactive: delay to be introduced by the controller after CS is
+ *	deasserted. If @cs_change_delay is used from @spi_transfer, then the
+ *	two delays will be added up.
  * @statistics: statistics for the spi_device
  *
  * A @spi_device is used to interchange data between an SPI slave
@@ -188,6 +192,10 @@ struct spi_device {
 	int			cs_gpio;	/* LEGACY: chip select gpio */
 	struct gpio_desc	*cs_gpiod;	/* chip select gpio desc */
 	struct spi_delay	word_delay; /* inter-word delay */
+	/* CS delays */
+	struct spi_delay	cs_setup;
+	struct spi_delay	cs_hold;
+	struct spi_delay	cs_inactive;
 
 	/* the statistics */
 	struct spi_statistics	statistics;
@@ -412,11 +420,6 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
  *	     controller has native support for memory like operations.
  * @unprepare_message: undo any work done by prepare_message().
  * @slave_abort: abort the ongoing transfer request on an SPI slave controller
- * @cs_setup: delay to be introduced by the controller after CS is asserted
- * @cs_hold: delay to be introduced by the controller before CS is deasserted
- * @cs_inactive: delay to be introduced by the controller after CS is
- *	deasserted. If @cs_change_delay is used from @spi_transfer, then the
- *	two delays will be added up.
  * @cs_gpios: LEGACY: array of GPIO descs to use as chip select lines; one per
  *	CS number. Any individual value may be -ENOENT for CS lines that
  *	are not GPIOs (driven by the SPI controller itself). Use the cs_gpiods
@@ -638,11 +641,6 @@ struct spi_controller {
 	/* Optimized handlers for SPI memory-like operations. */
 	const struct spi_controller_mem_ops *mem_ops;
 
-	/* CS delays */
-	struct spi_delay	cs_setup;
-	struct spi_delay	cs_hold;
-	struct spi_delay	cs_inactive;
-
 	/* gpio chip select */
 	int			*cs_gpios;
 	struct gpio_desc	**cs_gpiods;
-- 
2.18.0

From linus.walleij at linaro.org  Wed Aug  4 06:57:47 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed,  4 Aug 2021 15:57:47 +0200
Subject: [PATCH] ARM: Fix Keystone 2 kernel mapping regression
Message-ID: <20210804135747.737233-1-linus.walleij@linaro.org>

This fixes a Keystone 2 regression discovered as a side effect of
defining an passing the physical start/end sections of the kernel
to the MMU remapping code.

As the Keystone applies an offset to all physical addresses,
including those identified and patches by phys2virt, we fail to
account for this offset in the kernel_sec_start and kernel_sec_end
variables.

Further these offsets can extend into the 64bit range on LPAE
systems such as the Keystone 2.

Fix it like this:
- Extend kernel_sec_start and kernel_sec_end to be 64bit
- Add the offset also to kernel_sec_start and kernel_sec_end

As passing kernel_sec_start and kernel_sec_end as 64bit invariably
incurs endianness issues I have attempted to dry-code around
these. Please review.

Tested on the Vexpress QEMU model both with and without LPAE
enabled.

Fixes: 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel separately")
Reported-by: Nishanth Menon <nmenon at kernel.org>
Suggested-by: Russell King <linux at armlinux.org.uk>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Nishanth: Please test!
Other smart folks: please have a look at my endianness compensation
assembly.
---
 arch/arm/include/asm/memory.h |  7 ++++---
 arch/arm/kernel/head.S        | 19 ++++++++++++++++---
 arch/arm/mm/mmu.c             |  9 ++++++++-
 arch/arm/mm/pv-fixup-asm.S    |  2 +-
 4 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index cfc9dfd70aad..f673e13e0f94 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -160,10 +160,11 @@ extern unsigned long vectors_base;
 
 /*
  * Physical start and end address of the kernel sections. These addresses are
- * 2MB-aligned to match the section mappings placed over the kernel.
+ * 2MB-aligned to match the section mappings placed over the kernel. We use
+ * u64 so that LPAE mappings beyond the 32bit limit will work out as well.
  */
-extern u32 kernel_sec_start;
-extern u32 kernel_sec_end;
+extern u64 kernel_sec_start;
+extern u64 kernel_sec_end;
 
 /*
  * Physical vs virtual RAM address space conversion.  These are
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 9eb0b4dbcc12..49f5e04cf7e0 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -49,7 +49,8 @@
 
 	/*
 	 * This needs to be assigned at runtime when the linker symbols are
-	 * resolved.
+	 * resolved. These are unsigned 64bit really, but in this assembly code
+	 * We store them as 32bit.
 	 */
 	.pushsection .data
 	.align	2
@@ -57,7 +58,9 @@
 	.globl	kernel_sec_end
 kernel_sec_start:
 	.long	0
+	.long	0
 kernel_sec_end:
+	.long	0
 	.long	0
 	.popsection
 
@@ -250,7 +253,12 @@ __create_page_tables:
 	add	r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ORDER)
 	ldr	r6, =(_end - 1)
 	adr_l	r5, kernel_sec_start		@ _pa(kernel_sec_start)
-	str	r8, [r5]			@ Save physical start of kernel
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	add	r5, r5, #4			@ Move to the upper 32bit word
+	str	r8, [r5]			@ Save physical start of kernel (BE)
+#else
+	str	r8, [r5]			@ Save physical start of kernel (LE)
+#endif
 	orr	r3, r8, r7			@ Add the MMU flags
 	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
 1:	str	r3, [r0], #1 << PMD_ORDER
@@ -259,7 +267,12 @@ __create_page_tables:
 	bls	1b
 	eor	r3, r3, r7			@ Remove the MMU flags
 	adr_l	r5, kernel_sec_end		@ _pa(kernel_sec_end)
-	str	r3, [r5]			@ Save physical end of kernel
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	add	r5, r5, #4			@ Move to the upper 32bit word
+	str	r8, [r5]			@ Save physical end of kernel (BE)
+#else
+	str	r3, [r5]			@ Save physical end of kernel (LE)
+#endif
 
 #ifdef CONFIG_XIP_KERNEL
 	/*
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 7583bda5ea7d..a4e006005107 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1608,6 +1608,13 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
 	if (offset == 0)
 		return;
 
+	/*
+	 * Offset the kernel section physical offsets so that the kernel
+	 * mapping will work out later on.
+	 */
+	kernel_sec_start += offset;
+	kernel_sec_end += offset;
+
 	/*
 	 * Get the address of the remap function in the 1:1 identity
 	 * mapping setup by the early page table assembly code.  We
@@ -1716,7 +1723,7 @@ void __init paging_init(const struct machine_desc *mdesc)
 {
 	void *zero_page;
 
-	pr_debug("physical kernel sections: 0x%08x-0x%08x\n",
+	pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
 		 kernel_sec_start, kernel_sec_end);
 
 	prepare_page_table();
diff --git a/arch/arm/mm/pv-fixup-asm.S b/arch/arm/mm/pv-fixup-asm.S
index 5c5e1952000a..f8e11f7c7880 100644
--- a/arch/arm/mm/pv-fixup-asm.S
+++ b/arch/arm/mm/pv-fixup-asm.S
@@ -29,7 +29,7 @@ ENTRY(lpae_pgtables_remap_asm)
 	ldr	r6, =(_end - 1)
 	add	r7, r2, #0x1000
 	add	r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
-	add	r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER)
+	add	r7, r7, #KERNEL_OFFSET >> (SECTION_SHIFT - L2_ORDER)
 1:	ldrd	r4, r5, [r7]
 	adds	r4, r4, r0
 	adc	r5, r5, r1
-- 
2.31.1



From christianshewitt at gmail.com  Wed Aug  4 07:00:29 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed,  4 Aug 2021 14:00:29 +0000
Subject: [PATCH] arm64: dts: meson: add audio playback to nexbox-a1
Message-ID: <20210804140029.4445-1-christianshewitt@gmail.com>

Add initial support limited to HDMI i2s and SPDIF (LPCM).

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 .../boot/dts/amlogic/meson-gxm-nexbox-a1.dts  | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
index dfa7a37a1281..236c0a144142 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
@@ -10,6 +10,7 @@
 /dts-v1/;
 
 #include "meson-gxm.dtsi"
+#include <dt-bindings/sound/meson-aiu.h>
 
 / {
 	compatible = "nexbox,a1", "amlogic,s912", "amlogic,meson-gxm";
@@ -24,6 +25,13 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	spdif_dit: audio-codec-0 {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+		status = "okay";
+		sound-name-prefix = "DIT";
+	};
+
 	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x80000000>;
@@ -75,6 +83,59 @@
 			};
 		};
 	};
+
+	sound {
+		compatible = "amlogic,gx-sound-card";
+		model = "NEXBOX-A1";
+		assigned-clocks = <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>,
+				  <&clkc CLKID_MPLL2>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
+			dai-format = "i2s";
+			mclk-fs = <256>;
+
+			codec-0 {
+				sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
+			};
+		};
+
+		dai-link-3 {
+			sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
+
+			codec-0 {
+				sound-dai = <&spdif_dit>;
+			};
+		};
+
+		dai-link-4 {
+			sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
+
+			codec-0 {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&aiu {
+	status = "okay";
+	pinctrl-0 = <&spdif_out_h_pins>;
+	pinctrl-names = "default";
 };
 
 &cec_AO {
-- 
2.17.1



From arnd at arndb.de  Wed Aug  4 07:02:26 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 4 Aug 2021 16:02:26 +0200
Subject: [GIT PULL] ARM: at91: defconfig for 5.15
In-Reply-To: <20210804084631.12934-1-nicolas.ferre@microchip.com>
References: <20210804084631.12934-1-nicolas.ferre@microchip.com>
Message-ID: <CAK8P3a1Ru-qawBWtbmfJm-jiPpJTRJ9zSufXHNCZvxt1RCMFBA@mail.gmail.com>

On Wed, Aug 4, 2021 at 10:46 AM <nicolas.ferre at microchip.com> wrote:
> AT91 defconfig for 5.15:
>
> - add defconfig entries for new SoC: SAMA7G5
>   - dedicated sama7_defconfig to match the needed peripherals and
>     dependencies

I feel this needs  better description in the changelog: Why do you need another
defconfig file in addition to the existing sama5_defconfig? Are they so
different that a single config is not a good fit for both?

      Arnd


From kishon at ti.com  Wed Aug  4 07:02:44 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 4 Aug 2021 19:32:44 +0530
Subject: [PATCH v2 5/6] misc: pci_endpoint_test: Do not request or
 allocate IRQs in probe
In-Reply-To: <20210803095839.GA11252@lpieralisi>
References: <20210803074932.19820-1-kishon@ti.com>
 <20210803074932.19820-6-kishon@ti.com> <20210803095839.GA11252@lpieralisi>
Message-ID: <02c1ddb7-539e-20a0-1bef-e10e76922a0e@ti.com>

Hi Lorenzo,

On 03/08/21 3:28 pm, Lorenzo Pieralisi wrote:
> On Tue, Aug 03, 2021 at 01:19:31PM +0530, Kishon Vijay Abraham I wrote:
>> Allocation of IRQ vectors and requesting IRQ is done as part of
>> PCITEST_SET_IRQTYPE. Do not request or allocate IRQs in probe for
>> AM654 and J721E so that the user space test script has better control
>> of the devices for which the IRQs are configured. Since certain user
>> space scripts could rely on allocation of IRQ vectors during probe,
>> remove allocation of IRQs only for TI's K3 platform.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>> ---
>>  drivers/misc/pci_endpoint_test.c | 19 +++++++++++++------
>>  1 file changed, 13 insertions(+), 6 deletions(-)
> 
> I don't claim to understand the inner details of the endpoint test
> device but it looks like this approach should be redesigned.
> 
> I don't believe using devices quirks is the best approach to
> expose/remove a feature to userspace, this can soon become
> unmaintenable.
> 
> Maybe you can elaborate a bit more on what the real issue is please ?

The actual reason for introducing this patch (affects only AM654 and
J721E) is due to Errata ID #i2101 GIC: ITS Misbehavior
(https://www.ti.com/lit/er/sprz455a/sprz455a.pdf). So if more than 5
devices use GIC ITS simultaneously, GIC fails to raise interrupts.

Though this patch is not an actual workaround for the issue (the
workaround is in GIC ITS driver provided in the errata document), it
helps to keep testing PCIe RC/EP using pci-endpoint-test even when
multiple pci-epf-test endpoint devices are connected (Normal test-setup
having J721E-J721E back to back connection can support 21 pci-epf-test
devices). So this patch lets user to individually enable interrupts for
each of the devices and could disable after the interrupt test.

Since pci_endpoint_test is used only for testing PCIE RC/EP
communication and pci-endpoint-test has already implemented
PCITEST_SET_IRQTYPE for the userspace to enable interrupt, tried to not
enable the interrupts of all the devices by default in the probe (for
AM654 and J721E where this errata applies).

Thanks,
Kishon

> 
> Thanks,
> Lorenzo
> 
>> diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
>> index c7ee34013485..9740f2a0e7cd 100644
>> --- a/drivers/misc/pci_endpoint_test.c
>> +++ b/drivers/misc/pci_endpoint_test.c
>> @@ -79,6 +79,9 @@
>>  #define PCI_DEVICE_ID_RENESAS_R8A774C0		0x002d
>>  #define PCI_DEVICE_ID_RENESAS_R8A774E1		0x0025
>>  
>> +#define is_j721e_pci_dev(pdev)         \
>> +		((pdev)->device == PCI_DEVICE_ID_TI_J721E)
>> +
>>  static DEFINE_IDA(pci_endpoint_test_ida);
>>  
>>  #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
>> @@ -810,9 +813,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
>>  
>>  	pci_set_master(pdev);
>>  
>> -	if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
>> -		err = -EINVAL;
>> -		goto err_disable_irq;
>> +	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
>> +		if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
>> +			err = -EINVAL;
>> +			goto err_disable_irq;
>> +		}
>>  	}
>>  
>>  	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
>> @@ -850,9 +855,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
>>  		goto err_ida_remove;
>>  	}
>>  
>> -	if (!pci_endpoint_test_request_irq(test)) {
>> -		err = -EINVAL;
>> -		goto err_kfree_test_name;
>> +	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
>> +		if (!pci_endpoint_test_request_irq(test)) {
>> +			err = -EINVAL;
>> +			goto err_kfree_test_name;
>> +		}
>>  	}
>>  
>>  	misc_device = &test->miscdev;
>> -- 
>> 2.17.1
>>


From christianshewitt at gmail.com  Wed Aug  4 07:02:58 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed,  4 Aug 2021 14:02:58 +0000
Subject: [PATCH] arm64: dts: meson: add audio playback to vega-s95 dtsi
Message-ID: <20210804140258.4666-1-christianshewitt@gmail.com>

Add initial support limited to HDMI i2s and SPDIF (LPCM).

Tested-by: Oleg Ivanov <150balbes at yandex.ru>
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index 9b0b81f191f1..66daf3af34c3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include "meson-gxbb.dtsi"
+#include <dt-bindings/sound/meson-aiu.h>
 
 / {
 	compatible = "tronsmart,vega-s95", "amlogic,meson-gxbb";
@@ -17,6 +18,13 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	spdif_dit: audio-codec-0 {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+		status = "okay";
+		sound-name-prefix = "DIT";
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -97,6 +105,59 @@
 		clocks = <&wifi32k>;
 		clock-names = "ext_clock";
 	};
+
+	sound {
+		compatible = "amlogic,gx-sound-card";
+		model = "VEGA-S95";
+		assigned-clocks = <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>,
+				  <&clkc CLKID_MPLL2>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
+			dai-format = "i2s";
+			mclk-fs = <256>;
+
+			codec-0 {
+				sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
+			};
+		};
+
+		dai-link-3 {
+			sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
+
+			codec-0 {
+				sound-dai = <&spdif_dit>;
+			};
+		};
+
+		dai-link-4 {
+			sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
+
+			codec-0 {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&aiu {
+	status = "okay";
+	pinctrl-0 = <&spdif_out_y_pins>;
+	pinctrl-names = "default";
 };
 
 &cec_AO {
-- 
2.17.1



From arnd at kernel.org  Wed Aug  4 07:06:01 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Aug 2021 16:06:01 +0200
Subject: [GIT PULL v2] ARM: at91: soc for 5.15
In-Reply-To: <20210804084316.12641-1-nicolas.ferre@microchip.com>
References: <20210804081721.11093-1-nicolas.ferre@microchip.com>
 <20210804084316.12641-1-nicolas.ferre@microchip.com>
Message-ID: <162808595100.690655.10542947732336817960.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 4 Aug 2021 10:43:16 +0200, nicolas.ferre at microchip.com wrote:
> Arnd, Olof,
> 
> Here are the soc changes for 5.15 which contains the introduction of our new
> SoC family: the SAMA7G5.
> Note that one header file is shared with the clock sub-system. We synchronized
> with Stephen to make it appear in this Pull-Request.
> 
> - v1 -> v2: text of the signed tag aligned with kernel revision targeted.
> 
> [...]

Merged into for-next, thanks!

merge commit: 318845985fa032a865784ef5373f182fcdf037a9

       Arnd


From baruch at tkos.co.il  Wed Aug  4 07:05:05 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:05 +0300
Subject: [PATCH v2 1/6] dt-bindings: phy: qcom,qmp: Add IPQ6018 USB3 PHY
Message-ID: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>

Add compatible string for USB3 PHY in Qualcomm IPQ6018 SoC.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
index f0497b8623ad..3ae865988f04 100644
--- a/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
@@ -18,6 +18,7 @@ properties:
   compatible:
     enum:
       - qcom,ipq6018-qmp-pcie-phy
+      - qcom,ipq6018-qmp-usb3-phy
       - qcom,ipq8074-qmp-pcie-phy
       - qcom,ipq8074-qmp-usb3-phy
       - qcom,msm8996-qmp-pcie-phy
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:06 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:06 +0300
Subject: [PATCH v2 2/6] phy: qcom-qmp: add USB3 PHY support for IPQ6018
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <6eec7ef4ecd1e8360ebe8e425151121684e997ed.1628085910.git.baruch@tkos.co.il>

Initialization is identical to the IPQ8074 USB3 PHY.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index cfe359488f5c..da02279534f0 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -5225,6 +5225,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
 	}, {
 		.compatible = "qcom,ipq6018-qmp-pcie-phy",
 		.data = &ipq6018_pciephy_cfg,
+	}, {
+		.compatible = "qcom,ipq6018-qmp-usb3-phy",
+		.data = &ipq8074_usb3phy_cfg,
 	}, {
 		.compatible = "qcom,sc7180-qmp-usb3-phy",
 		.data = &sc7180_usb3phy_cfg,
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:09 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:09 +0300
Subject: [PATCH v2 5/6] dt-bindings: usb: qcom,dwc3: add binding for IPQ6018
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <24ce7c1258790b35a08e14a1e79a9447c3fed354.1628085910.git.baruch@tkos.co.il>

Add compatible string for Qualcomm IPQ6018 SoC.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
index 4e6451789806..55ed4b4c7f51 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
@@ -13,6 +13,7 @@ properties:
   compatible:
     items:
       - enum:
+          - qcom,ipq6018-dwc3
           - qcom,msm8996-dwc3
           - qcom,msm8998-dwc3
           - qcom,sc7180-dwc3
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:08 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:08 +0300
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>

From: Balaji Prakash J <bjagadee at codeaurora.org>

Set reference clock period when it differs from dwc3 default hardware
set.

Tested (USB2 only) on IPQ6010 SoC based board with 24 MHz reference
clock while hardware default is 19.2 MHz.

Signed-off-by: Balaji Prakash J <bjagadee at codeaurora.org>
[ baruch: rewrite commit message; drop GFLADJ code; remove 'quirk-' from
  property name; mention tested hardware ]
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v2:

  Remove snps,quirk-ref-clock-adjustment; not needed for tested hardware

  Rename DT property to snps,ref-clock-period (Thinh Nguyen)

  Use FIELD_PREP() (Bjorn Andersson)
---
 drivers/usb/dwc3/core.c | 29 +++++++++++++++++++++++++++++
 drivers/usb/dwc3/core.h |  6 ++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ba74ad7f6995..7ec5bfb5fc11 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -26,6 +26,7 @@
 #include <linux/acpi.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/reset.h>
+#include <linux/bitfield.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -351,6 +352,29 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
 	}
 }
 
+/**
+ * dwc3_ref_clk_period - Reference clock period configuration
+ *		Default reference clock period depends on hardware
+ *		configuration. For systems with reference clock that differs
+ *		from the default, this will set clock period in DWC3_GUCTL
+ *		register.
+ * @dwc: Pointer to our controller context structure
+ * @ref_clk_per: reference clock period in ns
+ */
+static void dwc3_ref_clk_period(struct dwc3 *dwc)
+{
+	u32 reg;
+
+	if (dwc->ref_clk_per == 0)
+		return;
+
+	reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+	reg &= ~DWC3_GUCTL_REFCLKPER_MASK;
+	reg |=  FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, dwc->ref_clk_per);
+	dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+}
+
+
 /**
  * dwc3_free_one_event_buffer - Frees one event buffer
  * @dwc: Pointer to our controller context structure
@@ -1011,6 +1035,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
 	/* Adjust Frame Length */
 	dwc3_frame_length_adjustment(dwc);
 
+	/* Adjust Reference Clock Period */
+	dwc3_ref_clk_period(dwc);
+
 	dwc3_set_incr_burst_type(dwc);
 
 	usb_phy_set_suspend(dwc->usb2_phy, 0);
@@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 				    &dwc->hsphy_interface);
 	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
 				 &dwc->fladj);
+	device_property_read_u32(dev, "snps,ref-clock-period",
+				 &dwc->ref_clk_per);
 
 	dwc->dis_metastability_quirk = device_property_read_bool(dev,
 				"snps,dis_metastability_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 5991766239ba..1e4e21ea9d97 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -386,6 +386,10 @@
 #define DWC3_GFLADJ_30MHZ_SDBND_SEL		BIT(7)
 #define DWC3_GFLADJ_30MHZ_MASK			0x3f
 
+/* Global User Control Register*/
+#define DWC3_GUCTL_REFCLKPER_MASK		0xffc00000
+#define DWC3_GUCTL_REFCLKPER_SEL		22
+
 /* Global User Control Register 2 */
 #define DWC3_GUCTL2_RST_ACTBITLATER		BIT(14)
 
@@ -969,6 +973,7 @@ struct dwc3_scratchpad_array {
  * @regs: base address for our registers
  * @regs_size: address space size
  * @fladj: frame length adjustment
+ * @ref_clk_per: reference clock period configuration
  * @irq_gadget: peripheral controller's IRQ number
  * @otg_irq: IRQ number for OTG IRQs
  * @current_otg_role: current role of operation while using the OTG block
@@ -1141,6 +1146,7 @@ struct dwc3 {
 	struct power_supply	*usb_psy;
 
 	u32			fladj;
+	u32			ref_clk_per;
 	u32			irq_gadget;
 	u32			otg_irq;
 	u32			current_otg_role;
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:07 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:07 +0300
Subject: [PATCH v2 3/6] dt-bindings: usb: dwc3: add reference clock period
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <22f62c59471e128b681a731997a9416ab2e91acf.1628085910.git.baruch@tkos.co.il>

Document the snps,ref-clock-period property that describes reference
clock period when it deviates from the default set value.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
index 41416fbd92aa..c8027d2852cd 100644
--- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
@@ -252,6 +252,15 @@ properties:
     minimum: 0
     maximum: 0x3f
 
+  snps,ref-clock-period:
+    description:
+      Value for REFCLKPER field of GUCTL register for post-silicon reference
+      clock period in nanoseconds, when the hardware set default does not match
+      the actual clock.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1
+    maximum: 0x3ff
+
   snps,rx-thr-num-pkt-prd:
     description:
       Periodic ESS RX packet threshold count (host mode only). Set this and
-- 
2.30.2



From baruch at tkos.co.il  Wed Aug  4 07:05:10 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed,  4 Aug 2021 17:05:10 +0300
Subject: [PATCH v2 6/6] arm64: qcom: ipq6018: add usb3 DT description
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <436c458546b2a783af36a190ed72ebc5c74de44e.1628085910.git.baruch@tkos.co.il>

From: Kathiravan T <kathirav at codeaurora.org>

Based on downstream codeaurora code.

Tested (USB2 only) on IPQ6010 based hardware.

Signed-off-by: Kathiravan T <kathirav at codeaurora.org>
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 arch/arm64/boot/dts/qcom/ipq6018.dtsi | 83 +++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 9fa5b028e4f3..ab701da582e5 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -524,6 +524,89 @@ qrtr_requests {
 			};
 		};
 
+		ssphy_0: ssphy at 78000 {
+			compatible = "qcom,ipq6018-qmp-usb3-phy";
+			reg = <0x0 0x78000 0x0 0x1C4>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			#clock-cells = <1>;
+			ranges;
+
+			clocks = <&gcc GCC_USB0_AUX_CLK>,
+				 <&gcc GCC_USB0_PHY_CFG_AHB_CLK>, <&xo>;
+			clock-names = "aux", "cfg_ahb", "ref";
+
+			resets = <&gcc GCC_USB0_PHY_BCR>,
+				 <&gcc GCC_USB3PHY_0_PHY_BCR>;
+			reset-names = "phy","common";
+			status = "disabled";
+
+			usb0_ssphy: lane at 78200 {
+				reg = <0x0 0x00078200 0x0 0x130>, /* Tx */
+				      <0x0 0x00078400 0x0 0x200>, /* Rx */
+				      <0x0 0x00078800 0x0 0x1F8>, /* PCS */
+				      <0x0 0x00078600 0x0 0x044>; /* PCS misc */
+				#phy-cells = <0>;
+				clocks = <&gcc GCC_USB0_PIPE_CLK>;
+				clock-names = "pipe0";
+				clock-output-names = "gcc_usb0_pipe_clk_src";
+			};
+		};
+
+		qusb_phy_0: qusb at 79000 {
+			compatible = "qcom,ipq6018-qusb2-phy";
+			reg = <0x0 0x079000 0x0 0x180>;
+			#phy-cells = <0>;
+
+			clocks = <&gcc GCC_USB0_PHY_CFG_AHB_CLK>,
+				<&xo>;
+			clock-names = "cfg_ahb", "ref";
+
+			resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
+			status = "disabled";
+		};
+
+		usb3: usb3 at 8A00000 {
+			compatible = "qcom,ipq6018-dwc3", "qcom,dwc3";
+			reg = <0x0 0x8AF8800 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			clocks = <&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
+				<&gcc GCC_USB0_MASTER_CLK>,
+				<&gcc GCC_USB0_SLEEP_CLK>,
+				<&gcc GCC_USB0_MOCK_UTMI_CLK>;
+			clock-names = "sys_noc_axi",
+				"master",
+				"sleep",
+				"mock_utmi";
+
+			assigned-clocks = <&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
+					  <&gcc GCC_USB0_MASTER_CLK>,
+					  <&gcc GCC_USB0_MOCK_UTMI_CLK>;
+			assigned-clock-rates = <133330000>,
+					       <133330000>,
+					       <20000000>;
+
+			resets = <&gcc GCC_USB0_BCR>;
+			status = "disabled";
+
+			dwc_0: dwc3 at 8A00000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x8A00000 0x0 0xcd00>;
+				interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&qusb_phy_0>, <&usb0_ssphy>;
+				phy-names = "usb2-phy", "usb3-phy";
+				tx-fifo-resize;
+				snps,is-utmi-l1-suspend;
+				snps,hird-threshold = /bits/ 8 <0x0>;
+				snps,dis_u2_susphy_quirk;
+				snps,dis_u3_susphy_quirk;
+				snps,ref-clock-period = <0x32>;
+				dr_mode = "host";
+			};
+		};
 	};
 
 	wcss: wcss-smp2p {
-- 
2.30.2



From ikjn at chromium.org  Wed Aug  4 07:06:21 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Wed, 4 Aug 2021 22:06:21 +0800
Subject: [PATCH 08/11] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <1628054384.14982.12.camel@mhfsdcap03>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
 <1627635002-24521-8-git-send-email-chunfeng.yun@mediatek.com>
 <CAATdQgDWkohpzgr=z+uzro4m9Bd=v88DNnJ-M88-5-0annhH_w@mail.gmail.com>
 <1628054384.14982.12.camel@mhfsdcap03>
Message-ID: <CAATdQgA9WeKr2UkrcAKY1rP22GtT0bMezdWkb-wyF9Yjx2p_9w@mail.gmail.com>

Hi,

On Wed, Aug 4, 2021 at 1:19 PM Chunfeng Yun <chunfeng.yun at mediatek.com> wrote:
>
> On Tue, 2021-08-03 at 14:05 +0800, Ikjoon Jang wrote:
> > Hi Chunfeng,
> >
> > On Fri, Jul 30, 2021 at 4:51 PM Chunfeng Yun <chunfeng.yun at mediatek.com> wrote:
> > >
> > > Use @bw_budget_table[] to update fs bus bandwidth due to
> > > not all microframes consume @bw_cost_per_microframe, see
> > > setup_sch_info().
> > >
> > > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > > ---
> > >  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
> > >  1 file changed, 7 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
> > > index 0bb1a6295d64..10c0f0f6461f 100644
> > > --- a/drivers/usb/host/xhci-mtk-sch.c
> > > +++ b/drivers/usb/host/xhci-mtk-sch.c
> > > @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
> > >                  * Compared with hs bus, no matter what ep type,
> > >                  * the hub will always delay one uframe to send data
> > >                  */
> > > -               for (j = 0; j < sch_ep->cs_count; j++) {
> > > -                       tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
> > > +               for (j = 0; j < sch_ep->num_budget_microframes; j++) {
> > > +                       tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j];
> > >                         if (tmp > FS_PAYLOAD_MAX)
> > >                                 return -ESCH_BW_OVERFLOW;
> > >                 }
> > > @@ -534,21 +534,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
> > >  {
> > >         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
> > >         u32 base, num_esit;
> > > -       int bw_updated;
> > >         int i, j;
> > >
> > >         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> > >
> > > -       if (used)
> > > -               bw_updated = sch_ep->bw_cost_per_microframe;
> > > -       else
> > > -               bw_updated = -sch_ep->bw_cost_per_microframe;
> > > -
> > >         for (i = 0; i < num_esit; i++) {
> > >                 base = sch_ep->offset + i * sch_ep->esit;
> > >
> > > -               for (j = 0; j < sch_ep->cs_count; j++)
> > > -                       tt->fs_bus_bw[base + j] += bw_updated;
> > > +               for (j = 0; j < sch_ep->num_budget_microframes; j++)
> > > +                       if (used)
> > > +                               tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j];
> > > +                       else
> > > +                               tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j];
> >
> > I agree that xhci-mtk-sch still has more rooms for tt periodic bandwidth
> > but I think this approach could trigger a problem.
> See updat_bus_bw(), when add fs ep's bandwidth, it uses
> bw_budget_table[], so prefer to use the same way
>
> >
> > for example, if there are two endpoints scheduled in the same u-frame index,
> > * ep1out  = iso 192bytes bw_budget_table[] = { 188, 188, 0, ...} --> y0
> > * ep2in = int 64bytes, bw_budget_table[] = { 0, 0, 64, ... }  --> y0
> >
> > (If this is possible allocation from this patch),
> > I guess xhci-mtk could have some problems on internal scheduling?
>
> Test it on dvt env. don't encounter issues;
>

As you can see In the above example, this patch starts to allow that allocation.
Do you mean that we don't have to worry about such a case (on all MTK
platforms)?

thanks

> Thanks
>
> >
> > >         }
> > >
> > >         if (used)
> >
> > > --
> > > 2.18.0
> > >
>


From arnd at kernel.org  Wed Aug  4 07:07:08 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed,  4 Aug 2021 16:07:08 +0200
Subject: [GIT PULL] IXP4xx driver updates for v5.15
In-Reply-To: <CACRpkdZaCosXsgp02nuUbd_nEvdxm5-z0+d0oSA97UTWQ0RQQg@mail.gmail.com>
References: <CACRpkdZaCosXsgp02nuUbd_nEvdxm5-z0+d0oSA97UTWQ0RQQg@mail.gmail.com>
Message-ID: <162808601953.733405.10635566719744310466.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 4 Aug 2021 14:44:18 +0200, Linus Walleij wrote:
> this is a set of combined driver updates for IXP4xx targeted for the
> v5.15 merge window.
> 
> I am sending it to the SoC tree because of the cross-subsystem
> dependencies and since the corresponding DTS changes goes
> into SoC. These will be sent separately.
> 
> Note the following:
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 775dea4deec679c24b525b258c341a45ff1de9ea

       Arnd


From linux at armlinux.org.uk  Wed Aug  4 07:10:42 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 4 Aug 2021 15:10:42 +0100
Subject: [PATCH] ARM: Fix Keystone 2 kernel mapping regression
In-Reply-To: <20210804135747.737233-1-linus.walleij@linaro.org>
References: <20210804135747.737233-1-linus.walleij@linaro.org>
Message-ID: <20210804141042.GQ22278@shell.armlinux.org.uk>

Hi Linus,

Looks fine. An improvement:

On Wed, Aug 04, 2021 at 03:57:47PM +0200, Linus Walleij wrote:
> @@ -250,7 +253,12 @@ __create_page_tables:
>  	add	r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ORDER)
>  	ldr	r6, =(_end - 1)
>  	adr_l	r5, kernel_sec_start		@ _pa(kernel_sec_start)
> -	str	r8, [r5]			@ Save physical start of kernel
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +	add	r5, r5, #4			@ Move to the upper 32bit word
> +	str	r8, [r5]			@ Save physical start of kernel (BE)

These two instructions can simply be replaced with:

	str	r8, [r5, #4]

> +#else
> +	str	r8, [r5]			@ Save physical start of kernel (LE)
> +#endif
>  	orr	r3, r8, r7			@ Add the MMU flags
>  	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
>  1:	str	r3, [r0], #1 << PMD_ORDER
> @@ -259,7 +267,12 @@ __create_page_tables:
>  	bls	1b
>  	eor	r3, r3, r7			@ Remove the MMU flags
>  	adr_l	r5, kernel_sec_end		@ _pa(kernel_sec_end)
> -	str	r3, [r5]			@ Save physical end of kernel
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +	add	r5, r5, #4			@ Move to the upper 32bit word
> +	str	r8, [r5]			@ Save physical end of kernel (BE)

Same here.

The patch can still usefully be tested by Nishanth without these
changes... it'll tell us if this was indeed the issue.

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From balbi at kernel.org  Wed Aug  4 07:11:58 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Wed, 04 Aug 2021 17:11:58 +0300
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
Message-ID: <87lf5h5mc2.fsf@kernel.org>


Hi,

Baruch Siach <baruch at tkos.co.il> writes:
> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>  				    &dwc->hsphy_interface);
>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>  				 &dwc->fladj);
> +	device_property_read_u32(dev, "snps,ref-clock-period",
> +				 &dwc->ref_clk_per);

I wonder if it would make more sense to pass an actual clock reference
here. If valid, then reconfigure the period to the value returned by
clk_get_rate(). It would avoid yet another DT binding. If we make the
clock optional, then we won't affect any other platforms. The clock
itself could be a regular fixed clock node.

-- 
balbi


From baruch at tkos.co.il  Wed Aug  4 07:22:27 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 04 Aug 2021 17:22:27 +0300
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <87lf5h5mc2.fsf@kernel.org>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org>
Message-ID: <87v94lxpb0.fsf@tarshish>

Hi Felipe,

On Wed, Aug 04 2021, Felipe Balbi wrote:
> Baruch Siach <baruch at tkos.co.il> writes:
>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>  				    &dwc->hsphy_interface);
>>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>>  				 &dwc->fladj);
>> +	device_property_read_u32(dev, "snps,ref-clock-period",
>> +				 &dwc->ref_clk_per);
>
> I wonder if it would make more sense to pass an actual clock reference
> here. If valid, then reconfigure the period to the value returned by
> clk_get_rate(). It would avoid yet another DT binding. If we make the
> clock optional, then we won't affect any other platforms. The clock
> itself could be a regular fixed clock node.

Thinh Nguyen asked to add a dedicated DT property. He explained that
clk_get_rate() does not work for PCI hosted dwc3. This is the most
complete summary of the discussion:

  https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32 at synopsys.com

baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From jbx6244 at gmail.com  Wed Aug  4 07:30:53 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Wed, 4 Aug 2021 16:30:53 +0200
Subject: [PATCH v2 7/7] arm64: dts: rockchip: rk3568-evb1-v10: add node
 for sd card
In-Reply-To: <20210804130625.15449-8-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
 <20210804130625.15449-8-michael.riesch@wolfvision.net>
Message-ID: <aa16ee55-e1de-adc8-51f0-8ceed136b911@gmail.com>

Hi Michael,

Could you add a commit message to all patches in this serie?

On 8/4/21 3:06 PM, Michael Riesch wrote:
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
> v2:
> - rename alias to match convention
> 
>  arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> index ed96f27c64a3..c4da6436059d 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> @@ -17,6 +17,7 @@
>  		ethernet0 = &gmac0;
>  		ethernet1 = &gmac1;

>  		mmc0 = &sdhci;
> +		mmc1 = &sdmmc0;

mmc aliases are sort on reg address based on availability without number
gap.

	sdmmc0: mmc at fe2b0000 {}
	sdhci: mmc at fe310000 {}

>  	};
>  
>  	chosen: chosen {
> @@ -353,6 +354,20 @@
>  	status = "okay";
>  };
>  
> +&sdmmc0 {
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
> +	disable-wp;

> +	pinctrl-names = "default";
> +	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;

pinctrl-names below pinctrl-0 like the rest of rk356x.dtsi

> +	sd-uhs-sdr104;

> +	supports-sd;

Check mmc-controller.yaml, rockchip-dw-mshc.yaml and
synopsys-dw-mshc-common.yaml for properties.

> +	vmmc-supply = <&vcc3v3_sd>;
> +	vqmmc-supply = <&vccio_sd>;
> +	status = "okay";
> +};
> +
>  &uart2 {
>  	status = "okay";
>  };
> 


From ezequiel at vanguardiasur.com.ar  Wed Aug  4 07:30:54 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 4 Aug 2021 11:30:54 -0300
Subject: [PATCH V2 00/13] soc: imx: gpcv2: support i.MX8MM
In-Reply-To: <20210506010440.7016-1-peng.fan@oss.nxp.com>
References: <20210506010440.7016-1-peng.fan@oss.nxp.com>
Message-ID: <CAAEAJfDfjkHF164x2qRnZg3e5JRN0pHjxyAq+d5+-3JFYwEEOQ@mail.gmail.com>

Hi Peng, Lucas,

On Wed, 5 May 2021 at 21:32, Peng Fan (OSS) <peng.fan at oss.nxp.com> wrote:
>
> From: Peng Fan <peng.fan at nxp.com>
>
>
> V2:
>  - Add R-b/A-b tag
>  - Merge V1 patch 13 to V2 patch 6
>  - Drop V1 patch 15
>  - Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
>  details
>  - Add explaination in patch 8 for "why the resets are not defined"
>
> This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
> minor changes from me to make it could work with i.MX BLK-CTL driver.
>
> Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
> all the patches, Jacky Bai on help debug issues.
>
> Lucas Stach (12):
>   soc: imx: gpcv2: move to more ideomatic error handling in probe
>   soc: imx: gpcv2: move domain mapping to domain driver probe
>   soc: imx: gpcv2: switch to clk_bulk_* API
>   soc: imx: gpcv2: split power up and power down sequence control
>   soc: imx: gpcv2: wait for ADB400 handshake
>   soc: imx: gpcv2: add runtime PM support for power-domains
>   soc: imx: gpcv2: allow domains without power-sequence control
>   dt-bindings: imx: gpcv2: add support for optional resets
>   soc: imx: gpcv2: add support for optional resets
>   dt-bindings: power: add defines for i.MX8MM power domains
>   soc: imx: gpcv2: add support for i.MX8MM power domains
>   soc: imx: gpcv2: Add support for missing i.MX8MM VPU/DISPMIX power
>     domains
>

It's nice to see this finally moving forward!

As you know, Hantro G2 support for i.MX8MQ (and i.MX8MP, i.MX8MM) is currently
blocked, as you have requested:

https://lore.kernel.org/driverdev-devel/5aa5700b862234895a7a6eb251ca3c80fdc1a6d3.camel at collabora.com/

So, I think we really need to include i.MX8MP and i.MX8MQ on this series.
It's been quite a while and we really need to have that. To be honest,
I fear that
if we merge this series as-is, MX8MP and MX8MP support will fall in
the oblivion,
and Hantro G2 VPU will remain unusable.

We are planning to submit Hantro G2 VP9 support soon, and we've been testing
on various platforms, but it will also be blocked by lack of power-domains.

In the future, please Cc the linux-media mailing list, as well as
Benjamin, Andrzej and myself, so we can follow this.

Thanks a lot for the hard work!
Ezequiel


From mathieu.poirier at linaro.org  Wed Aug  4 07:31:13 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 4 Aug 2021 08:31:13 -0600
Subject: [PATCH 0/2] coresight: ultrasoc: Add support for System Memory
 Buffer device
In-Reply-To: <41661d60-d8ef-9d50-57eb-8964c6f6eef8@huawei.com>
References: <20210719111737.47891-1-liuqi115@huawei.com>
 <41661d60-d8ef-9d50-57eb-8964c6f6eef8@huawei.com>
Message-ID: <CANLsYky2+D8cwquyX3iXgJtu6vND0gZZBtCL_vBobJ8pBwwvfA@mail.gmail.com>

On Wed, 4 Aug 2021 at 02:05, liuqi (BA) <liuqi115 at huawei.com> wrote:
>
> Gentle ping...
> Hi Mathieu and Suzuki, can you have a look at this patchset? thanks.
>

On August 2nd I got back to you privately saying I won't be able to
review this patchset before the last week of August or the first week
of September.  Pinging me again on it won't change that reality.

> On 2021/7/19 19:17, Qi Liu wrote:
> > This patchset add support for SMB(System Memory Buffer) device, SMB
> > obtains CPU instructions from Coresight ETM device and stores these
> > messages in system memory.
> > SMB is developed by Ultrasoc technology, which is acquired by Siemens,
> > and we still use "Ultrasoc" to name document and driver.
> >
> > Change since RFC:
> > - Move ultrasoc driver to drivers/hwtracing/coresight.
> > - Remove ultrasoc-axi-com.c, as AXI-COM doesn't need to be configured in
> >    basic tracing function.
> > - Remove ultrasoc.c as SMB does not need to register with the ultrasoc core.
> > - Address the comments from Mathieu and Suzuki.
> > - Link: https://lists.linaro.org/pipermail/coresight/2021-June/006535.html
> >
> > Qi Liu (2):
> >    Documentation: tracing: Documentation for ultrasoc SMB drivers
> >    coresight: ultrasoc: Add System Memory Buffer driver
> >
> >   .../trace/coresight/ultrasoc-trace.rst        | 193 +++++
> >   MAINTAINERS                                   |   7 +
> >   drivers/hwtracing/coresight/Kconfig           |   3 +
> >   drivers/hwtracing/coresight/Makefile          |   2 +
> >   drivers/hwtracing/coresight/ultrasoc/Kconfig  |  12 +
> >   drivers/hwtracing/coresight/ultrasoc/Makefile |   6 +
> >   .../coresight/ultrasoc/ultrasoc-smb.c         | 722 ++++++++++++++++++
> >   .../coresight/ultrasoc/ultrasoc-smb.h         | 142 ++++
> >   8 files changed, 1087 insertions(+)
> >   create mode 100644 Documentation/trace/coresight/ultrasoc-trace.rst
> >   create mode 100644 drivers/hwtracing/coresight/ultrasoc/Kconfig
> >   create mode 100644 drivers/hwtracing/coresight/ultrasoc/Makefile
> >   create mode 100644 drivers/hwtracing/coresight/ultrasoc/ultrasoc-smb.c
> >   create mode 100644 drivers/hwtracing/coresight/ultrasoc/ultrasoc-smb.h
> >
>


From balbi at kernel.org  Wed Aug  4 07:30:42 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Wed, 04 Aug 2021 17:30:42 +0300
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <87v94lxpb0.fsf@tarshish>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org> <87v94lxpb0.fsf@tarshish>
Message-ID: <87im0l5lj1.fsf@kernel.org>


Hi,

Baruch Siach <baruch at tkos.co.il> writes:
> Hi Felipe,
>
> On Wed, Aug 04 2021, Felipe Balbi wrote:
>> Baruch Siach <baruch at tkos.co.il> writes:
>>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>>  				    &dwc->hsphy_interface);
>>>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>>>  				 &dwc->fladj);
>>> +	device_property_read_u32(dev, "snps,ref-clock-period",
>>> +				 &dwc->ref_clk_per);
>>
>> I wonder if it would make more sense to pass an actual clock reference
>> here. If valid, then reconfigure the period to the value returned by
>> clk_get_rate(). It would avoid yet another DT binding. If we make the
>> clock optional, then we won't affect any other platforms. The clock
>> itself could be a regular fixed clock node.
>
> Thinh Nguyen asked to add a dedicated DT property. He explained that
> clk_get_rate() does not work for PCI hosted dwc3. This is the most
> complete summary of the discussion:

Hence the "optional" :-)

Or, perhaps, Thinh wants to use this for internal FPGA-based validation?

In that case, I'm okay with the property.

-- 
balbi


From lee.jones at linaro.org  Wed Aug  4 07:37:44 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Wed,  4 Aug 2021 15:37:44 +0100
Subject: [PATCH 1/1] mfd: simple-mfd-i2c: Add support for registering devices
 via MFD cells
Message-ID: <20210804143744.689238-1-lee.jones@linaro.org>

More devices are cropping up requiring only Regmap initialisation and
child registration functionality.  We currently only support that if
all required devices are represented by their own Device Tree nodes
complete with compatible strings.

However, not everyone is happy with adding empty nodes that provide no
additional device information into the Device Tree.

Rather than have a plethora of mostly empty, function-less drivers in
MFD, we'll support those simple cases in here instead via MFD cells.

Cc: Michael Walle <michael at walle.cc>
Cc: Mark Brown <broonie at kernel.org>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---

Michael, could you please test this on your platform to ensure I
         didn't break anything please?

 drivers/mfd/simple-mfd-i2c.c | 39 ++++++++++++++++++++++++++++--------
 drivers/mfd/simple-mfd-i2c.h | 27 +++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 8 deletions(-)
 create mode 100644 drivers/mfd/simple-mfd-i2c.h

diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 87f684cff9a17..fec3f002a9119 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -2,39 +2,62 @@
 /*
  * Simple MFD - I2C
  *
+ * Author(s):
+ * 	Michael Walle <michael at walle.cc>
+ * 	Lee Jones <lee.jones at linaro.org>
+ *
  * This driver creates a single register map with the intention for it to be
  * shared by all sub-devices.  Children can use their parent's device structure
  * (dev.parent) in order to reference it.
  *
  * Once the register map has been successfully initialised, any sub-devices
- * represented by child nodes in Device Tree will be subsequently registered.
+ * represented by child nodes in Device Tree or via the MFD cells in this file
+ * will be subsequently registered.
  */
 
 #include <linux/i2c.h>
 #include <linux/kernel.h>
+#include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/regmap.h>
 
-static const struct regmap_config simple_regmap_config = {
+#include "simple-mfd-i2c.h"
+
+static const struct regmap_config regmap_config_8r_8v = {
 	.reg_bits = 8,
 	.val_bits = 8,
 };
 
 static int simple_mfd_i2c_probe(struct i2c_client *i2c)
 {
-	const struct regmap_config *config;
+	const struct simple_mfd_data *simple_mfd_data;
+	const struct regmap_config *regmap_config;
 	struct regmap *regmap;
+	int ret;
+
+	simple_mfd_data = device_get_match_data(&i2c->dev);
 
-	config = device_get_match_data(&i2c->dev);
-	if (!config)
-		config = &simple_regmap_config;
+	if (simple_mfd_data->regmap_config)
+		regmap_config = simple_mfd_data->regmap_config;
+	else
+		regmap_config = &regmap_config_8r_8v;
 
-	regmap = devm_regmap_init_i2c(i2c, config);
+	regmap = devm_regmap_init_i2c(i2c, regmap_config);
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return devm_of_platform_populate(&i2c->dev);
+	if (!simple_mfd_data->mfd_cell)
+		return devm_of_platform_populate(&i2c->dev);
+
+	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
+				   simple_mfd_data->mfd_cell,
+				   simple_mfd_data->mfd_cell_size,
+				   NULL, 0, NULL);
+	if (!ret)
+		dev_err(&i2c->dev, "Failed to add child devices\n");
+
+	return ret;
 }
 
 static const struct of_device_id simple_mfd_i2c_of_match[] = {
diff --git a/drivers/mfd/simple-mfd-i2c.h b/drivers/mfd/simple-mfd-i2c.h
new file mode 100644
index 0000000000000..a2a0bc45b4e3b
--- /dev/null
+++ b/drivers/mfd/simple-mfd-i2c.h
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Simple MFD - I2C
+ *
+ * Author: Lee Jones <lee.jones at linaro.org>
+ *
+ * This driver creates a single register map with the intention for it to be
+ * shared by all sub-devices.  Children can use their parent's device structure
+ * (dev.parent) in order to reference it.
+ *
+ * Once the register map has been successfully initialised, any sub-devices
+ * represented by child nodes in Device Tree will be subsequently registered.
+ */
+
+#ifndef __MFD_SIMPLE_MFD_I2C_H
+#define __MFD_SIMPLE_MFD_I2C_H
+
+#include <linux/mfd/core.h>
+#include <linux/regmap.h>
+
+struct simple_mfd_data {
+	const struct regmap_config *regmap_config;
+	const struct mfd_cell *mfd_cell;
+	size_t mfd_cell_size;
+};
+
+#endif /* __MFD_SIMPLE_MFD_I2C_H */
-- 
2.32.0.554.ge1b32706d8-goog



From maz at kernel.org  Wed Aug  4 07:39:17 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Aug 2021 15:39:17 +0100
Subject: [PATCH v3 1/6] docs: staging/tee.rst: add a section on OP-TEE
 notifications
In-Reply-To: <CAHUa44HCEr_HKU0Fz10HPZYMowXVkx5JtnXMVTXd29wAv-dTCg@mail.gmail.com>
References: <20210723094422.2150313-1-jens.wiklander@linaro.org>
 <20210723094422.2150313-2-jens.wiklander@linaro.org>
 <87zgud1giz.wl-maz@kernel.org>
 <CAHUa44EhP5NCH6S27+Af8ePxAup9nJnrwGr_nMRUFumXOTh7uQ@mail.gmail.com>
 <87eebkdumr.wl-maz@kernel.org>
 <CAHUa44HCEr_HKU0Fz10HPZYMowXVkx5JtnXMVTXd29wAv-dTCg@mail.gmail.com>
Message-ID: <87lf5hw9yi.wl-maz@kernel.org>

On Tue, 27 Jul 2021 15:57:07 +0100,
Jens Wiklander <jens.wiklander at linaro.org> wrote:
> 
> On Tue, Jul 27, 2021 at 10:32 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Tue, 27 Jul 2021 08:46:39 +0100,
> > Jens Wiklander <jens.wiklander at linaro.org> wrote:
> > >
> > > On Fri, Jul 23, 2021 at 12:16 PM Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > On Fri, 23 Jul 2021 10:44:17 +0100,
> > > > Jens Wiklander <jens.wiklander at linaro.org> wrote:
> > > > >
> > > > > Adds a section on notifications used by OP-TEE, synchronous and
> > > > > asynchronous.
> > > > >
> > > > > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > > > > ---
> > > > >  Documentation/staging/tee.rst | 27 +++++++++++++++++++++++++++
> > > > >  1 file changed, 27 insertions(+)
> > > > >
> > > > > diff --git a/Documentation/staging/tee.rst b/Documentation/staging/tee.rst
> > > > > index 4d4b5f889603..37bdd097336f 100644
> > > > > --- a/Documentation/staging/tee.rst
> > > > > +++ b/Documentation/staging/tee.rst
> > > > > @@ -184,6 +184,33 @@ order to support device enumeration. In other words, OP-TEE driver invokes this
> > > > >  application to retrieve a list of Trusted Applications which can be registered
> > > > >  as devices on the TEE bus.
> > > > >
> > > > > +OP-TEE notifications
> > > > > +--------------------
> > > > > +
> > > > > +There are two kinds of notifications that secure world can use to make
> > > > > +normal world aware of some event.
> > > > > +
> > > > > +1. Synchronous notifications delivered with ``OPTEE_RPC_CMD_NOTIFICATION``
> > > > > +   using the ``OPTEE_RPC_NOTIFICATION_SEND`` parameter.
> > > > > +2. Asynchronous notifications delivered with a combination of a non-secure
> > > > > +   interrupt and a fast call from the non-secure interrupt handler.
> > > > > +
> > > > > +Synchronous notifications are limited by depending on RPC for delivery,
> > > > > +this is only usable when secure world is entered with a yielding call via
> > > > > +``OPTEE_SMC_CALL_WITH_ARG``. This excludes such notifications from secure
> > > > > +world interrupt handlers.
> > > > > +
> > > > > +An asynchronous notification is delivered via a non-secure interrupt to an
> > > > > +interrupt handler registered in the OP-TEE driver. The actual notification
> > > > > +value are retrieved with the fast call ``OPTEE_SMC_GET_ASYNC_NOTIF_VALUE``.
> > > > > +
> > > > > +One notification value ``OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF`` has a
> > > > > +special meaning. When this value is received it means that normal world is
> > > > > +supposed to make a yielding call ``OPTEE_MSG_CMD_DO_BOTTOM_HALF``. This
> > > > > +call is done from the thread assisting the interrupt handler. This is a
> > > > > +building block for OP-TEE OS in secure world to implement the top half and
> > > > > +bottom half style of device drivers.
> > > > > +
> > > >
> > > > What I find missing here is a description of the trigger for this
> > > > interrupt, and how it influences the way the kernel drivers interacts
> > > > with the secure side:
> > > >
> > > > - if it is edge triggered, this is 'fire and forget'. The interrupt
> > > >   will be consumed by the kernel handler, and whether it eventually
> > > >   calls into the secure side has no impact on the interrupt flow.
> > > >
> > > > - if it is level triggered, then the interrupt may be asserted until
> > > >   the kernel calls into the secure side, which may then drop the line
> > > >   level if no other requests are pending.
> > > >
> > > > These are evidently two very different flows, and you need to pick a
> > > > side. Note that not all interrupt controllers support both signalling
> > > > modes, so you are likely to leave something behind. Or you can try and
> > > > support both flows, but that may make the driver slightly more
> > > > complex.
> > > >
> > > > Either way, this needs specifying, here and in the DT binding.
> > >
> > > In the example I'm using a level triggered interrupt which is
> > > triggered by writing to GICD_ISPENDR by secure world. Reading of
> > > GICC_IAR should clear the interrupt,the GICv2 reference manual is
> > > quite clear on that.
> >
> > No, it merely activates it. You can't transition an interrupt from
> > pending to inactive (unless you clear it using GICD_ICPENDR). If you
> > have spotted something else in the GICv2 architecture manual, please
> > say so and I'll get it fixed 15 years after the facts. The fact that
> > GICC_IAR consumes a pending bit introduced by a write to ISPENDR is an
> > implementation detail, see below.
> 
> I was looking at figure 4-10 "Logic of the pending status of a
> level-sensitive interrupt".
> 
> >
> > It is also a flawed approach, as this behaviour is IMPDEF on GICv3
> > (see 4.5 "Shared Peripheral Interrupts" in the GICv3 arch spec). Given
> > that GICv2 is pretty much a dead horse (TFFT!), I can't see this approach
> > being successful in the long run.
> 
> OK, thanks.
> 
> >
> > > So, if I understand it correctly, it will for
> > > this purpose work in the same way as an edge triggered interrupt. If
> > > this wouldn't be the case in some configuration and the interrupt must
> > > be cleared by some other action that would be a job for the receiver
> > > of OPTEE_SMC_GET_ASYNC_NOTIF_VALUE, that is, a secure world problem.
> > > The normal world flow should be the same.
> >
> > You are assuming that the secure side will use GICD_ISPENDR, and
> > that's a leap of faith.
> 
> Not in this case with upstream OP-TEE. If we need to signal in a
> different way we can do that instead.
> What happens downstream we have no control over, but that's perhaps
> not so different from the kernel.
> 
> > An implementation should use, say, a GPIO to
> > drive the interrupt line and give it proper level semantics.
> 
> I'm not so keen on that since we often don't touch GPIO at all in
> OP-TEE and this would then mean more platform specific code. We may
> even need to synchronize some hardware access with the normal world
> and then we'd be back at square one again.

I'm trying to make a general statement here. OP-TEE may not do any of
this. Yet. Other TEE implementations may do it because there is no
free SPI in the system, for example. The problem is that interrupt
signalling is a *device* thing, even if the device is actually some SW
running on the secure side, and I would like the TEE to behave as
such.

> > > Now that we describe the interrupt configuration in device tree it
> > > must use something that mirrors the secure world expectations. I don't
> > > see a point in restricting what's allowed as long it doesn't need code
> > > changes in the kernel too. Does this make any sense?
> >
> > And that's the crucial point: what *are* the expectations of the
> > secure side?
> 
> That should be up to the OP-TEE port of that particular platform to
> decide and advise which device tree configuration to use.
> 
> > You seem to assume edge semantics, but that's unclear at
> > best.
> 
> Fair enough, edge semantics solves the problem here.
> 
> >
> > > If I just expand a bit above explaining that the interrupt handler
> > > must call OPTEE_SMC_GET_ASYNC_NOTIF_VALUE as part of clearing the
> > > interrupt even if it might be cleared anyway in some configurations.
> > > Would that make it more clear, good enough even :-) ?
> >
> > This is an interrupt, please document it in terms of interrupt
> > signalling.
> 
> In this file, Documentation/staging/tee.rst ? A pointer to a good
> example of what you're expecting would be much appreciated.
> There's also the file drivers/tee/optee/optee_smc.h, this is where the
> ABI to OP-TEE is defined.

This file is fine, but repeating in the DT binding that edge
signalling is what is expected would be good.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From semen.protsenko at linaro.org  Wed Aug  4 07:39:38 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 4 Aug 2021 17:39:38 +0300
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
Message-ID: <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>

Hi Marc,

On Fri, 30 Jul 2021 at 19:50, Marc Zyngier <maz at kernel.org> wrote:
>
> On 2021-07-30 15:49, Sam Protsenko wrote:
> > Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
> >
> > Features:
> >  * CPU: Cortex-A55 Octa (8 cores), up to 2 GHz
> >  * Memory interface: LPDDR4/4x 2 channels (12.8 GB/s)
> >  * SD/MMC: SD 3.0, eMMC5.1 DDR 8-bit
> >  * Modem: 4G LTE, 3G, GSM/GPRS/EDGE
> >  * RF: Quad GNSS, WiFi 5 (802.11ac), Bluetooth 5.0
> >  * GPU: Mali-G52 MP1
> >  * Codec: 1080p 60fps H64, HEVC, JPEG HW Codec
> >  * Display: Full HD+ (2520x1080)@60fps LCD
> >  * Camera: 16+5MP/13+8MP ISP, MIPI CSI 4/4/2, FD, DRC
> >  * Connectivity: USB 2.0 DRD, USI (SPI/UART/I2C), HSI2C, I3C, ADC,
> > Audio
> >
> > This patch adds minimal SoC support. Particular board device tree files
> > can include exynos850.dtsi file to get SoC related nodes, and then
> > reference those nodes further as needed.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> >  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
> >  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
> >  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
> >  3 files changed, 1057 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > new file mode 100644
> > index 000000000000..4cf0a22cc6db
>
> [...]
>
> > +     gic: interrupt-controller at 12a00000 {
> > +             compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
>
> One thing for sure, it cannot be both. And given that it is
> an A55-based SoC, it isn't either. It is more likely a GIC400.
>

Yes, it's GIC-400, thanks for pointing that out. Will fix that in v2.

> > +             #interrupt-cells = <3>;
> > +             #address-cells = <0>;
> > +             interrupt-controller;
> > +             reg = <0x0 0x12a01000 0x1000>,
> > +                   <0x0 0x12a02000 0x1000>,
>
> This is wrong. It is architecturally set to 8kB.
>

Nice catch! Actually there is an error (typo?) in SoC's TRM, saying
that Virtual Interface Control Register starts at 0x3000 offset (from
0x12a00000), where it obviously should be 0x4000, that's probably
where this dts error originates from. Btw, I'm also seeing the same
error in exynos7.dtsi. Though I don't have a TRM for Exynos7 SoCs, so
not sure if I should go ahead and fix that too. Anyway, for Exynos850,
I'll fix that in v2 series.

> > +                   <0x0 0x12a04000 0x2000>,
> > +                   <0x0 0x12a06000 0x2000>;
> > +             interrupts = <GIC_PPI 9
> > +                             (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
>
> 4? With 8 CPUs?
>

Will be fixed in v2, thanks.

> I also find it curious that you went through the unusual
> (and IMO confusing) effort to allocate a name to each and
> every SPI in the system, but didn't do it for any on the PPIs...
>

Yeah, after some consideration I removed the whole interrupts header
and used hard-coded values instead. I probably felt it would be right
thing to have, just because there is no public TRM for Exynos850, thus
documenting interrupts somewhere would be nice. But that reasoning is
wrong, as trying to mix that kind of documentation with code just
clutters it. The right thing to do is probably just provide a public
TRM, but that's not for me to decide, alas :) Anyway, will be fixed in
v2.

>
> > +     };
> > +
> > +     timer {
> > +             compatible = "arm,armv8-timer";
> > +             interrupts = <GIC_PPI 13
> > +                             (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> > +                          <GIC_PPI 14
> > +                             (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> > +                          <GIC_PPI 11
> > +                             (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> > +                          <GIC_PPI 10
> > +                             (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
> > +             clock-frequency = <26000000>;
>
> No, please. Fix the firmware to program CNTFRQ_EL0 on each
> and every CPU. This isn't 2012 anymore.
>

Ok, will remove that property in v2. Though it looks like CNTFRQ_EL0
register can be only changed in EL3 execution level, so I'll have to
ask the vendor to fix their BL31 or whatever. But that might take some
time, so I'll have to keep "clock-frequency" workaround in my local
tree for now, to make scheduler work.

> You are also missing the hypervisor virtual timer interrupt.
>

Checked SoC TRM, there is no PPI for hypervisor virtual timer
interrupt, and no mentioning of it at all. Likewise, I checked ARMv8
ARM and TRM, almost no description of it. Also, I checked other
platforms, and seems like everyone does the same (having only 4
interrupts). And I wasn't able to find any documentation on that, so I
guess I'll leave it as is, if you don't mind.

> > +             use-clocksource-only;
> > +             use-physical-timer;
>
> Thankfully, these two properties do not exist.
>

Yeah, that's just some leftover from vendor's kernel, overlook by
me... Will remove in v2, thanks.

> Thanks,
>
>          M.
> --
> Jazz is not dead. It just smells funny...


From jbx6244 at gmail.com  Wed Aug  4 07:41:46 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Wed, 4 Aug 2021 16:41:46 +0200
Subject: [PATCH v2 3/7] arm64: dts: rockchip: rk3568-evb1-v10: add
 regulators of rk809 pmic
In-Reply-To: <20210804130625.15449-4-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
 <20210804130625.15449-4-michael.riesch@wolfvision.net>
Message-ID: <cf4bf613-6462-fac9-824d-71375b852adf@gmail.com>

Hi Michael,

Missing commit message.

On 8/4/21 3:06 PM, Michael Riesch wrote:
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 206 ++++++++++++++++++
>  1 file changed, 206 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> index 65e536c78d2e..f682144a1892 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> @@ -104,6 +104,203 @@
>  	status = "okay";
>  };
>  
> +&i2c0 {
> +	status = "okay";
> +
> +	rk809: pmic at 20 {
> +		compatible = "rockchip,rk809";
> +		reg = <0x20>;
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
> +		#clock-cells = <1>;

> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pmic_int>;

pinctrl-names below pinctrl-0 like the rest of rk356x.dtsi

> +		rockchip,system-power-controller;
> +		wakeup-source;
> +
> +		vcc1-supply = <&vcc3v3_sys>;
> +		vcc2-supply = <&vcc3v3_sys>;
> +		vcc3-supply = <&vcc3v3_sys>;
> +		vcc4-supply = <&vcc3v3_sys>;
> +		vcc5-supply = <&vcc3v3_sys>;
> +		vcc6-supply = <&vcc3v3_sys>;
> +		vcc7-supply = <&vcc3v3_sys>;
> +		vcc8-supply = <&vcc3v3_sys>;
> +		vcc9-supply = <&vcc3v3_sys>;
> +
> +		regulators {
> +			vdd_logic: DCDC_REG1 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <500000>;
> +				regulator-max-microvolt = <1350000>;
> +				regulator-init-microvolt = <900000>;
> +				regulator-ramp-delay = <6001>;
> +				regulator-initial-mode = <0x2>;
> +				regulator-name = "vdd_logic";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdd_gpu: DCDC_REG2 {
> +				regulator-min-microvolt = <500000>;
> +				regulator-max-microvolt = <1350000>;
> +				regulator-init-microvolt = <900000>;
> +				regulator-ramp-delay = <6001>;
> +				regulator-initial-mode = <0x2>;
> +				regulator-name = "vdd_gpu";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc_ddr: DCDC_REG3 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-initial-mode = <0x2>;
> +				regulator-name = "vcc_ddr";
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +				};
> +			};
> +
> +			vdd_npu: DCDC_REG4 {

> +				regulator-min-microvolt = <500000>;
> +				regulator-max-microvolt = <1350000>;

Exception to the sort rule:
1: regulator-min-microvolt above regulator-max-microvolt

2: regulator-name above all other regulator properties.

The rest in alphabetical order.
Fix them all.

> +				regulator-init-microvolt = <900000>;
> +				regulator-ramp-delay = <6001>;
> +				regulator-initial-mode = <0x2>;
> +				regulator-name = "vdd_npu";

Add empty line between properties and a node.

> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc_1v8: DCDC_REG5 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-name = "vcc_1v8";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdda0v9_image: LDO_REG1 {
> +				regulator-min-microvolt = <900000>;
> +				regulator-max-microvolt = <900000>;
> +				regulator-name = "vdda0v9_image";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdda_0v9: LDO_REG2 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <900000>;
> +				regulator-max-microvolt = <900000>;
> +				regulator-name = "vdda_0v9";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdda0v9_pmu: LDO_REG3 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <900000>;
> +				regulator-max-microvolt = <900000>;
> +				regulator-name = "vdda0v9_pmu";
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <900000>;
> +				};
> +			};
> +
> +			vccio_acodec: LDO_REG4 {
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-name = "vccio_acodec";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vccio_sd: LDO_REG5 {
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-name = "vccio_sd";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc3v3_pmu: LDO_REG6 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-name = "vcc3v3_pmu";
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <3300000>;
> +				};
> +			};
> +
> +			vcca_1v8: LDO_REG7 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-name = "vcca_1v8";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcca1v8_pmu: LDO_REG8 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-name = "vcca1v8_pmu";
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1800000>;
> +				};
> +			};
> +
> +			vcca1v8_image: LDO_REG9 {
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-name = "vcca1v8_image";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc_3v3: SWITCH_REG1 {
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-name = "vcc_3v3";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc3v3_sd: SWITCH_REG2 {
> +				regulator-name = "vcc3v3_sd";
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +		};
> +	};
> +};
> +
>  &mdio0 {
>  	rgmii_phy0: ethernet-phy at 0 {
>  		compatible = "ethernet-phy-ieee802.3-c22";
> @@ -124,6 +321,15 @@
>  	};
>  };
>  
> +&pinctrl {
> +	pmic {
> +		pmic_int: pmic_int {
> +			rockchip,pins =
> +				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
> +		};
> +	};
> +};
> +
>  &sdhci {
>  	bus-width = <8>;
>  	max-frequency = <200000000>;
> 


From maz at kernel.org  Wed Aug  4 08:01:06 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Aug 2021 16:01:06 +0100
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
Message-ID: <87k0l1w8y5.wl-maz@kernel.org>

On Wed, 04 Aug 2021 15:39:38 +0100,
Sam Protsenko <semen.protsenko at linaro.org> wrote:

> > You are also missing the hypervisor virtual timer interrupt.
> >
> 
> Checked SoC TRM, there is no PPI for hypervisor virtual timer
> interrupt, and no mentioning of it at all. Likewise, I checked ARMv8
> ARM and TRM, almost no description of it. Also, I checked other
> platforms, and seems like everyone does the same (having only 4
> interrupts). And I wasn't able to find any documentation on that, so I
> guess I'll leave it as is, if you don't mind.

I *do* mind, and other DTs being wrong isn't a good enough excuse! ;-)

From the ARMv8 ARM (ARM DDI 0487G.b)
<quote>
D11.2.4 Timers

In an implementation of the Generic Timer that includes EL3, if EL3
can use AArch64, the following timers are implemented:

* An EL1 physical timer, that:
  - In Secure state, can be accessed from EL1.
  - In Non-secure state, can be accessed from EL1 unless those
    accesses are trapped to EL2.
    When this timer can be accessed from EL1, an EL1 control
    determines whether it can be accessed from EL0.
* A Non-secure EL2 physical timer.
* A Secure EL3 physical timer. An EL3 control determines whether this
  register is accessible from Secure EL1.
* An EL1 virtual timer.
* When FEAT_VHE is implemented, a Non-secure EL2 virtual timer.
* When FEAT_SEL2 is implemented, a Secure EL2 physical timer.
* When FEAT_SEL2 is implemented, a Secure EL2 virtual timer.
</quote>

Cortex-A55 being an ARMv8.2 implementation, it has FEAT_VHE, and thus
it does have a NS-EL2 virtual timer. This is further confirmed by the
TRM which documents CNTHV*_EL2 as valid system registers[1].

So the timer exists, the signal is routed out of the core, and it
is likely that it is connected to the GIC.

If the designers have omitted it, then it needs to be documented as
such.

Thanks,

	M.

[1] https://developer.arm.com/documentation/100442/0100/register-descriptions/aarch64-system-registers/aarch64-architectural-system-register-summary

-- 
Without deviation from the norm, progress is not possible.


From matthias.bgg at gmail.com  Wed Aug  4 08:01:08 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 17:01:08 +0200
Subject: [PATCH 0/2] Add MUSB for MT7623
In-Reply-To: <20210803151320.71531-1-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
Message-ID: <638a4526-2688-e7c6-c71e-0ebaaeb773b5@gmail.com>

Hi Sungbo,

On 03/08/2021 17:13, Sungbo Eo wrote:
> These patches add support for the MUSB controller on Mediatek MT7623.
> Tested on Mercury RUSH-318AC Wi-Fi router.
> 

Nice to see you are working on Mediatek devices.
Are you planning to add the device tree for the router to the kernel? I'd be
happy to see them submitted.

Regards,
Matthias

> I got to know this from a BPI-R2 forum post [1], and managed to make it work on OpenWrt snapshot.
> I'd like to know if this also works on BPI-R2, I can happily share the details if needed.
> And I've just copy & pasted nodes from mt2701, please let me know if I missed some big differences between SoCs...
> 
> [1] http://forum.banana-pi.org/t/bpi-r2-otg-port/10551
> 
> Sungbo Eo (2):
>   dt-bindings: usb: mtk-musb: add MT7623 compatible
>   arm: dts: mt7623: add musb device nodes
> 
>  .../bindings/usb/mediatek,musb.yaml           |  1 +
>  arch/arm/boot/dts/mt7623.dtsi                 | 34 +++++++++++++++++++
>  arch/arm/boot/dts/mt7623a.dtsi                |  4 +++
>  3 files changed, 39 insertions(+)
> 


From matthias.bgg at gmail.com  Wed Aug  4 08:01:24 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 17:01:24 +0200
Subject: [PATCH 1/2] dt-bindings: usb: mtk-musb: add MT7623 compatible
In-Reply-To: <20210803151320.71531-2-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <20210803151320.71531-2-mans0n@gorani.run>
Message-ID: <353c79de-2dab-0367-32e8-63b0fd89900d@gmail.com>



On 03/08/2021 17:13, Sungbo Eo wrote:
> Document MT7623 compatible for mtk-musb.
> 
> Signed-off-by: Sungbo Eo <mans0n at gorani.run>

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

> ---
>  Documentation/devicetree/bindings/usb/mediatek,musb.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/mediatek,musb.yaml b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
> index 84ddacfdbe9b..03d62d60ce5f 100644
> --- a/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
> +++ b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
> @@ -19,6 +19,7 @@ properties:
>        - enum:
>            - mediatek,mt8516-musb
>            - mediatek,mt2701-musb
> +          - mediatek,mt7623-musb
>        - const: mediatek,mtk-musb
>  
>    reg:
> 


From maz at kernel.org  Wed Aug  4 08:05:25 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Aug 2021 16:05:25 +0100
Subject: [PATCH v2 1/3] dt-bindings: PCI: ti,
 j721e: Add bindings to specify legacy interrupts
In-Reply-To: <20210804132912.30685-2-kishon@ti.com>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-2-kishon@ti.com>
Message-ID: <87im0lw8qy.wl-maz@kernel.org>

On Wed, 04 Aug 2021 14:29:10 +0100,
Kishon Vijay Abraham I <kishon at ti.com> wrote:
> 
> Add bindings to specify interrupt controller for legacy interrupts.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  .../bindings/pci/ti,j721e-pci-host.yaml           | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
> index cc900202df29..f461d7b4c0cc 100644
> --- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
> +++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
> @@ -74,6 +74,11 @@ properties:
>  
>    msi-map: true
>  
> +patternProperties:
> +  "interrupt-controller":
> +    type: object
> +    description: interrupt controller to handle legacy interrupts.
> +
>  required:
>    - compatible
>    - reg
> @@ -97,6 +102,8 @@ unevaluatedProperties: false
>  
>  examples:
>    - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
>      #include <dt-bindings/soc/ti,sci_pm_domain.h>
>      #include <dt-bindings/gpio/gpio.h>
>  
> @@ -131,5 +138,13 @@ examples:
>              ranges = <0x01000000 0x0 0x10001000  0x00 0x10001000  0x0 0x0010000>,
>                       <0x02000000 0x0 0x10011000  0x00 0x10011000  0x0 0x7fef000>;
>              dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
> +
> +
> +            pcie0_intc: interrupt-controller {
> +                    interrupt-controller;
> +                    #interrupt-cells = <1>;
> +                    interrupt-parent = <&gic500>;
> +                    interrupts = <GIC_SPI 312 IRQ_TYPE_EDGE_RISING>;

Are you sure about the edge signalling? How is the interrupt
retriggered when the input is still high, which could well be the case
for shared INTx?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From jbx6244 at gmail.com  Wed Aug  4 08:05:39 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Wed, 4 Aug 2021 17:05:39 +0200
Subject: [PATCH v2 4/7] arm64: dts: rockchip: enable io domains for rk356x
In-Reply-To: <20210804130625.15449-5-michael.riesch@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
 <20210804130625.15449-5-michael.riesch@wolfvision.net>
Message-ID: <6f557e45-075f-9a12-f603-cec8a4dc28a6@gmail.com>

Hi Michael,

pmu_io_domains is a sub node of pmugrf, so add it to grf.yaml as well in
a separate patch. Place document changes before driver patches for
checkpatch scripts (undocumented compatible string):
./scripts/checkpatch.pl --strict <patch1> <patch2>


  - if:
      properties:
        compatible:
          contains:
            enum:
              - rockchip,px30-pmugrf
              - rockchip,px30-grf
              - rockchip,rk3228-grf
              - rockchip,rk3288-grf
              - rockchip,rk3328-grf
              - rockchip,rk3368-pmugrf
              - rockchip,rk3368-grf
              - rockchip,rk3399-pmugrf
              - rockchip,rk3399-grf
==>
              - rockchip,rk3568-pmugrf

    then:
      properties:
        io-domains:
          type: object

          $ref: "/schemas/power/rockchip-io-domain.yaml#"

On 8/4/21 3:06 PM, Michael Riesch wrote:
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  arch/arm64/boot/dts/rockchip/rk356x.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> index 3e90a8832bb9..834863940eba 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> @@ -203,6 +203,11 @@
>  	pmugrf: syscon at fdc20000 {
>  		compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd";
>  		reg = <0x0 0xfdc20000 0x0 0x10000>;
> +
> +		pmu_io_domains: io-domains {
> +			compatible = "rockchip,rk3568-pmu-io-voltage-domain";
> +			status = "disabled";
> +		};
>  	};
>  
>  	grf: syscon at fdc60000 {
> 


From maz at kernel.org  Wed Aug  4 08:13:39 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 04 Aug 2021 16:13:39 +0100
Subject: [PATCH v2 2/3] PCI: j721e: Add PCI legacy interrupt support for
 J721E
In-Reply-To: <20210804132912.30685-3-kishon@ti.com>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-3-kishon@ti.com>
Message-ID: <87h7g5w8d8.wl-maz@kernel.org>

On Wed, 04 Aug 2021 14:29:11 +0100,
Kishon Vijay Abraham I <kishon at ti.com> wrote:
> 
> Add PCI legacy interrupt support for J721E. J721E has a single HW
> interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
> The HW interrupt line connected to GIC is a pulse interrupt whereas
> the legacy interrupts by definition is level interrupt. In order to
> provide level interrupt functionality to edge interrupt line, PCIe
> in J721E has provided IRQ_EOI register.
> 
> However due to Errata ID #i2094 ([1]), EOI feature is not enabled in HW
> and only a single pulse interrupt will be generated for every
> ASSERT_INTx/DEASSERT_INTx.

So my earlier remark stands. If you get a single edge, how do you
handle a level that is still high after having handled the interrupt
on hardware that has this bug?

> 
> [1] -> J721E DRA829/TDA4VM Processors Silicon Revision 1.1/1.0 SPRZ455A ?
>        DECEMBER 2020 ? REVISED AUGUST 2021
>        (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf)
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  drivers/pci/controller/cadence/pci-j721e.c | 85 ++++++++++++++++++++++
>  1 file changed, 85 insertions(+)
> 
> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
> index 2ec037c43bd5..c2e7a78dc31f 100644
> --- a/drivers/pci/controller/cadence/pci-j721e.c
> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> @@ -29,6 +29,13 @@
>  #define LINK_DOWN		BIT(1)
>  #define J7200_LINK_DOWN		BIT(10)
>  
> +#define EOI_REG			0x10
> +
> +#define ENABLE_REG_SYS_0	0x100
> +#define STATUS_REG_SYS_0	0x500
> +#define STATUS_CLR_REG_SYS_0	0x700
> +#define INTx_EN(num)		(1 << (num))
> +
>  #define J721E_PCIE_USER_CMD_STATUS	0x4
>  #define LINK_TRAINING_ENABLE		BIT(0)
>  
> @@ -59,6 +66,7 @@ struct j721e_pcie {
>  	void __iomem		*user_cfg_base;
>  	void __iomem		*intd_cfg_base;
>  	u32			linkdown_irq_regfield;
> +	struct irq_domain	*legacy_irq_domain;
>  };
>  
>  enum j721e_pcie_mode {
> @@ -121,6 +129,79 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
>  	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
>  }
>  
> +static void j721e_pcie_v1_legacy_irq_handler(struct irq_desc *desc)
> +{
> +	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	int i, virq;
> +	u32 reg;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	for (i = 0; i < PCI_NUM_INTX; i++) {
> +		reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_0);
> +		if (!(reg & INTx_EN(i)))
> +			continue;

Why do you need to perform multiple reads? Surely reg contains all the
bits you need, doesn't it?

> +
> +		virq = irq_find_mapping(pcie->legacy_irq_domain, 3 - i);
> +		generic_handle_irq(virq);

Please combine both lines into a single generic_handle_domain_irq()
call.

> +		j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_0, INTx_EN(i));

What is the purpose of this write? It feels like this should be a
irq_eoi callback.

> +	}
> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +static int j721e_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq)
> +{
> +	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);

An INTx interrupt is a level interrupt. Please use the corresponding flow.

> +	irq_set_chip_data(irq, domain->host_data);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops j721e_pcie_intx_domain_ops = {
> +	.map = j721e_pcie_intx_map,
> +};
> +
> +static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
> +{
> +	struct irq_domain *legacy_irq_domain;
> +	struct device *dev = pcie->dev;
> +	struct device_node *node = dev->of_node;
> +	struct device_node *intc_node;
> +	int irq, i;
> +	u32 reg;
> +
> +	intc_node = of_get_child_by_name(node, "interrupt-controller");
> +	if (!intc_node) {
> +		dev_dbg(dev, "interrupt-controller node is absent. Legacy INTR not supported\n");
> +		return 0;
> +	}
> +
> +	irq = irq_of_parse_and_map(intc_node, 0);
> +	if (!irq) {
> +		dev_err(dev, "Failed to parse and map legacy irq\n");
> +		return -EINVAL;
> +	}
> +	irq_set_chained_handler_and_data(irq, j721e_pcie_v1_legacy_irq_handler, pcie);
> +
> +	legacy_irq_domain = irq_domain_add_linear(intc_node, PCI_NUM_INTX,
> +						  &j721e_pcie_intx_domain_ops, pcie);
> +	if (!legacy_irq_domain) {
> +		dev_err(dev, "Failed to add irq domain for legacy irqs\n");
> +		return -EINVAL;
> +	}
> +	pcie->legacy_irq_domain = legacy_irq_domain;
> +
> +	for (i = 0; i < PCI_NUM_INTX; i++) {
> +		reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_0);
> +		reg |= INTx_EN(i);
> +		j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_0, reg);
> +	}

This should be moved to the irq_unmask() callback.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From matthias.bgg at gmail.com  Wed Aug  4 08:17:07 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 17:17:07 +0200
Subject: [PATCH v2] soc: mmsys: mediatek: add mask to mmsys routes
In-Reply-To: <20210729070549.5514-1-linux@fw-web.de>
References: <20210729070549.5514-1-linux@fw-web.de>
Message-ID: <e8c990b6-180d-9702-d8cc-fd1e98dfc744@gmail.com>



On 29/07/2021 09:05, Frank Wunderlich wrote:
> From: CK Hu <ck.hu at mediatek.com>
> 
> SOUT has many bits and need to be cleared before set new value.
> Write only could do the clear, but for MOUT, it clears bits that
> should not be cleared. So use a mask to reset only the needed bits.
> 
> this fixes HDMI issues on MT7623/BPI-R2 since 5.13
> 
> Fixes: 440147639ac7 ("soc: mediatek: mmsys: Use an array for setting the routing registers")
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> Signed-off-by: CK Hu <ck.hu at mediatek.com>
> Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> Reviewed-by: Hsin-Yi Wang <hsinyi at chromium.org>

My understanding is, that this does not break mt8173 and other SoCs that use the
default routing table. Correct?

Added now to v5.14-next/soc
Thanks.

> ---
> code is taken from here (upstreamed without mask part)
> https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2345186/5
> basicly CK Hu's code so i set him as author
> ---
> v2:
> - added mask to mt8183 specific table (mask=value),
>   before val was used as mask and val itself not defined,
>   breaking display on these devices
> - as changes do not add addional code only restoring same
>   behaviour for mt8183 added reviwed-by from CK Hu from v1
> ---
>  drivers/soc/mediatek/mt8183-mmsys.h |  21 +++--
>  drivers/soc/mediatek/mtk-mmsys.c    |   7 +-
>  drivers/soc/mediatek/mtk-mmsys.h    | 133 +++++++++++++++++++---------
>  3 files changed, 112 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mt8183-mmsys.h b/drivers/soc/mediatek/mt8183-mmsys.h
> index 579dfc8dc8fc..9dee485807c9 100644
> --- a/drivers/soc/mediatek/mt8183-mmsys.h
> +++ b/drivers/soc/mediatek/mt8183-mmsys.h
> @@ -28,25 +28,32 @@
>  static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
>  	{
>  		DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL_2L0,
> -		MT8183_DISP_OVL0_MOUT_EN, MT8183_OVL0_MOUT_EN_OVL0_2L
> +		MT8183_DISP_OVL0_MOUT_EN, MT8183_OVL0_MOUT_EN_OVL0_2L,
> +		MT8183_OVL0_MOUT_EN_OVL0_2L
>  	}, {
>  		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
> -		MT8183_DISP_OVL0_2L_MOUT_EN, MT8183_OVL0_2L_MOUT_EN_DISP_PATH0
> +		MT8183_DISP_OVL0_2L_MOUT_EN, MT8183_OVL0_2L_MOUT_EN_DISP_PATH0,
> +		MT8183_OVL0_2L_MOUT_EN_DISP_PATH0
>  	}, {
>  		DDP_COMPONENT_OVL_2L1, DDP_COMPONENT_RDMA1,
> -		MT8183_DISP_OVL1_2L_MOUT_EN, MT8183_OVL1_2L_MOUT_EN_RDMA1
> +		MT8183_DISP_OVL1_2L_MOUT_EN, MT8183_OVL1_2L_MOUT_EN_RDMA1,
> +		MT8183_OVL1_2L_MOUT_EN_RDMA1
>  	}, {
>  		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> -		MT8183_DISP_DITHER0_MOUT_EN, MT8183_DITHER0_MOUT_IN_DSI0
> +		MT8183_DISP_DITHER0_MOUT_EN, MT8183_DITHER0_MOUT_IN_DSI0,
> +		MT8183_DITHER0_MOUT_IN_DSI0
>  	}, {
>  		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
> -		MT8183_DISP_PATH0_SEL_IN, MT8183_DISP_PATH0_SEL_IN_OVL0_2L
> +		MT8183_DISP_PATH0_SEL_IN, MT8183_DISP_PATH0_SEL_IN_OVL0_2L,
> +		MT8183_DISP_PATH0_SEL_IN_OVL0_2L
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
> -		MT8183_DISP_DPI0_SEL_IN, MT8183_DPI0_SEL_IN_RDMA1
> +		MT8183_DISP_DPI0_SEL_IN, MT8183_DPI0_SEL_IN_RDMA1,
> +		MT8183_DPI0_SEL_IN_RDMA1
>  	}, {
>  		DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
> -		MT8183_DISP_RDMA0_SOUT_SEL_IN, MT8183_RDMA0_SOUT_COLOR0
> +		MT8183_DISP_RDMA0_SOUT_SEL_IN, MT8183_RDMA0_SOUT_COLOR0,
> +		MT8183_RDMA0_SOUT_COLOR0
>  	}
>  };
>  
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
> index 080660ef11bf..0f949896fd06 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -68,7 +68,9 @@ void mtk_mmsys_ddp_connect(struct device *dev,
>  
>  	for (i = 0; i < mmsys->data->num_routes; i++)
>  		if (cur == routes[i].from_comp && next == routes[i].to_comp) {
> -			reg = readl_relaxed(mmsys->regs + routes[i].addr) | routes[i].val;
> +			reg = readl_relaxed(mmsys->regs + routes[i].addr);
> +			reg &= ~routes[i].mask;
> +			reg |= routes[i].val;
>  			writel_relaxed(reg, mmsys->regs + routes[i].addr);
>  		}
>  }
> @@ -85,7 +87,8 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
>  
>  	for (i = 0; i < mmsys->data->num_routes; i++)
>  		if (cur == routes[i].from_comp && next == routes[i].to_comp) {
> -			reg = readl_relaxed(mmsys->regs + routes[i].addr) & ~routes[i].val;
> +			reg = readl_relaxed(mmsys->regs + routes[i].addr);
> +			reg &= ~routes[i].mask;
>  			writel_relaxed(reg, mmsys->regs + routes[i].addr);
>  		}
>  }
> diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
> index a760a34e6eca..5f3e2bf0c40b 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.h
> +++ b/drivers/soc/mediatek/mtk-mmsys.h
> @@ -35,41 +35,54 @@
>  #define RDMA0_SOUT_DSI1				0x1
>  #define RDMA0_SOUT_DSI2				0x4
>  #define RDMA0_SOUT_DSI3				0x5
> +#define RDMA0_SOUT_MASK				0x7
>  #define RDMA1_SOUT_DPI0				0x2
>  #define RDMA1_SOUT_DPI1				0x3
>  #define RDMA1_SOUT_DSI1				0x1
>  #define RDMA1_SOUT_DSI2				0x4
>  #define RDMA1_SOUT_DSI3				0x5
> +#define RDMA1_SOUT_MASK				0x7
>  #define RDMA2_SOUT_DPI0				0x2
>  #define RDMA2_SOUT_DPI1				0x3
>  #define RDMA2_SOUT_DSI1				0x1
>  #define RDMA2_SOUT_DSI2				0x4
>  #define RDMA2_SOUT_DSI3				0x5
> +#define RDMA2_SOUT_MASK				0x7
>  #define DPI0_SEL_IN_RDMA1			0x1
>  #define DPI0_SEL_IN_RDMA2			0x3
> +#define DPI0_SEL_IN_MASK			0x3
>  #define DPI1_SEL_IN_RDMA1			(0x1 << 8)
>  #define DPI1_SEL_IN_RDMA2			(0x3 << 8)
> +#define DPI1_SEL_IN_MASK			(0x3 << 8)
>  #define DSI0_SEL_IN_RDMA1			0x1
>  #define DSI0_SEL_IN_RDMA2			0x4
> +#define DSI0_SEL_IN_MASK			0x7
>  #define DSI1_SEL_IN_RDMA1			0x1
>  #define DSI1_SEL_IN_RDMA2			0x4
> +#define DSI1_SEL_IN_MASK			0x7
>  #define DSI2_SEL_IN_RDMA1			(0x1 << 16)
>  #define DSI2_SEL_IN_RDMA2			(0x4 << 16)
> +#define DSI2_SEL_IN_MASK			(0x7 << 16)
>  #define DSI3_SEL_IN_RDMA1			(0x1 << 16)
>  #define DSI3_SEL_IN_RDMA2			(0x4 << 16)
> +#define DSI3_SEL_IN_MASK			(0x7 << 16)
>  #define COLOR1_SEL_IN_OVL1			0x1
>  
>  #define OVL_MOUT_EN_RDMA			0x1
>  #define BLS_TO_DSI_RDMA1_TO_DPI1		0x8
>  #define BLS_TO_DPI_RDMA1_TO_DSI			0x2
> +#define BLS_RDMA1_DSI_DPI_MASK			0xf
>  #define DSI_SEL_IN_BLS				0x0
>  #define DPI_SEL_IN_BLS				0x0
> +#define DPI_SEL_IN_MASK				0x1
>  #define DSI_SEL_IN_RDMA				0x1
> +#define DSI_SEL_IN_MASK				0x1
>  
>  struct mtk_mmsys_routes {
>  	u32 from_comp;
>  	u32 to_comp;
>  	u32 addr;
> +	u32 mask;
>  	u32 val;
>  };
>  
> @@ -91,124 +104,164 @@ struct mtk_mmsys_driver_data {
>  static const struct mtk_mmsys_routes mmsys_default_routing_table[] = {
>  	{
>  		DDP_COMPONENT_BLS, DDP_COMPONENT_DSI0,
> -		DISP_REG_CONFIG_OUT_SEL, BLS_TO_DSI_RDMA1_TO_DPI1
> +		DISP_REG_CONFIG_OUT_SEL, BLS_RDMA1_DSI_DPI_MASK,
> +		BLS_TO_DSI_RDMA1_TO_DPI1
>  	}, {
>  		DDP_COMPONENT_BLS, DDP_COMPONENT_DSI0,
> -		DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_BLS
> +		DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_MASK,
> +		DSI_SEL_IN_BLS
>  	}, {
>  		DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0,
> -		DISP_REG_CONFIG_OUT_SEL, BLS_TO_DPI_RDMA1_TO_DSI
> +		DISP_REG_CONFIG_OUT_SEL, BLS_RDMA1_DSI_DPI_MASK,
> +		BLS_TO_DPI_RDMA1_TO_DSI
>  	}, {
>  		DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0,
> -		DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_RDMA
> +		DISP_REG_CONFIG_DSI_SEL, DSI_SEL_IN_MASK,
> +		DSI_SEL_IN_RDMA
>  	}, {
>  		DDP_COMPONENT_BLS, DDP_COMPONENT_DPI0,
> -		DISP_REG_CONFIG_DPI_SEL, DPI_SEL_IN_BLS
> +		DISP_REG_CONFIG_DPI_SEL, DPI_SEL_IN_MASK,
> +		DPI_SEL_IN_BLS
>  	}, {
>  		DDP_COMPONENT_GAMMA, DDP_COMPONENT_RDMA1,
> -		DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN, GAMMA_MOUT_EN_RDMA1
> +		DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN, GAMMA_MOUT_EN_RDMA1,
> +		GAMMA_MOUT_EN_RDMA1
>  	}, {
>  		DDP_COMPONENT_OD0, DDP_COMPONENT_RDMA0,
> -		DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD_MOUT_EN_RDMA0
> +		DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD_MOUT_EN_RDMA0,
> +		OD_MOUT_EN_RDMA0
>  	}, {
>  		DDP_COMPONENT_OD1, DDP_COMPONENT_RDMA1,
> -		DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD1_MOUT_EN_RDMA1
> +		DISP_REG_CONFIG_DISP_OD_MOUT_EN, OD1_MOUT_EN_RDMA1,
> +		OD1_MOUT_EN_RDMA1
>  	}, {
>  		DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0,
> -		DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0
> +		DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0,
> +		OVL0_MOUT_EN_COLOR0
>  	}, {
>  		DDP_COMPONENT_OVL0, DDP_COMPONENT_COLOR0,
> -		DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0
> +		DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0,
> +		COLOR0_SEL_IN_OVL0
>  	}, {
>  		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> -		DISP_REG_CONFIG_DISP_OVL_MOUT_EN, OVL_MOUT_EN_RDMA
> +		DISP_REG_CONFIG_DISP_OVL_MOUT_EN, OVL_MOUT_EN_RDMA,
> +		OVL_MOUT_EN_RDMA
>  	}, {
>  		DDP_COMPONENT_OVL1, DDP_COMPONENT_COLOR1,
> -		DISP_REG_CONFIG_DISP_OVL1_MOUT_EN, OVL1_MOUT_EN_COLOR1
> +		DISP_REG_CONFIG_DISP_OVL1_MOUT_EN, OVL1_MOUT_EN_COLOR1,
> +		OVL1_MOUT_EN_COLOR1
>  	}, {
>  		DDP_COMPONENT_OVL1, DDP_COMPONENT_COLOR1,
> -		DISP_REG_CONFIG_DISP_COLOR1_SEL_IN, COLOR1_SEL_IN_OVL1
> +		DISP_REG_CONFIG_DISP_COLOR1_SEL_IN, COLOR1_SEL_IN_OVL1,
> +		COLOR1_SEL_IN_OVL1
>  	}, {
>  		DDP_COMPONENT_RDMA0, DDP_COMPONENT_DPI0,
> -		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DPI0
> +		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
> +		RDMA0_SOUT_DPI0
>  	}, {
>  		DDP_COMPONENT_RDMA0, DDP_COMPONENT_DPI1,
> -		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DPI1
> +		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
> +		RDMA0_SOUT_DPI1
>  	}, {
>  		DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI1,
> -		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI1
> +		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
> +		RDMA0_SOUT_DSI1
>  	}, {
>  		DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI2,
> -		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI2
> +		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
> +		RDMA0_SOUT_DSI2
>  	}, {
>  		DDP_COMPONENT_RDMA0, DDP_COMPONENT_DSI3,
> -		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_DSI3
> +		DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN, RDMA0_SOUT_MASK,
> +		RDMA0_SOUT_DSI3
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
> -		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DPI0
> +		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
> +		RDMA1_SOUT_DPI0
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
> -		DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_RDMA1
> +		DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_MASK,
> +		DPI0_SEL_IN_RDMA1
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI1,
> -		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DPI1
> +		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
> +		RDMA1_SOUT_DPI1
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI1,
> -		DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_RDMA1
> +		DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_MASK,
> +		DPI1_SEL_IN_RDMA1
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI0,
> -		DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_RDMA1
> +		DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_MASK,
> +		DSI0_SEL_IN_RDMA1
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI1,
> -		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI1
> +		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
> +		RDMA1_SOUT_DSI1
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI1,
> -		DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_RDMA1
> +		DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_MASK,
> +		DSI1_SEL_IN_RDMA1
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI2,
> -		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI2
> +		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
> +		RDMA1_SOUT_DSI2
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI2,
> -		DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_RDMA1
> +		DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_MASK,
> +		DSI2_SEL_IN_RDMA1
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI3,
> -		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_DSI3
> +		DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN, RDMA1_SOUT_MASK,
> +		RDMA1_SOUT_DSI3
>  	}, {
>  		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DSI3,
> -		DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_RDMA1
> +		DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_MASK,
> +		DSI3_SEL_IN_RDMA1
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI0,
> -		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DPI0
> +		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
> +		RDMA2_SOUT_DPI0
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI0,
> -		DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_RDMA2
> +		DISP_REG_CONFIG_DPI_SEL_IN, DPI0_SEL_IN_MASK,
> +		DPI0_SEL_IN_RDMA2
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI1,
> -		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DPI1
> +		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
> +		RDMA2_SOUT_DPI1
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DPI1,
> -		DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_RDMA2
> +		DISP_REG_CONFIG_DPI_SEL_IN, DPI1_SEL_IN_MASK,
> +		DPI1_SEL_IN_RDMA2
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI0,
> -		DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_RDMA2
> +		DISP_REG_CONFIG_DSIE_SEL_IN, DSI0_SEL_IN_MASK,
> +		DSI0_SEL_IN_RDMA2
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI1,
> -		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI1
> +		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
> +		RDMA2_SOUT_DSI1
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI1,
> -		DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_RDMA2
> +		DISP_REG_CONFIG_DSIO_SEL_IN, DSI1_SEL_IN_MASK,
> +		DSI1_SEL_IN_RDMA2
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI2,
> -		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI2
> +		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
> +		RDMA2_SOUT_DSI2
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI2,
> -		DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_RDMA2
> +		DISP_REG_CONFIG_DSIE_SEL_IN, DSI2_SEL_IN_MASK,
> +		DSI2_SEL_IN_RDMA2
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI3,
> -		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_DSI3
> +		DISP_REG_CONFIG_DISP_RDMA2_SOUT, RDMA2_SOUT_MASK,
> +		RDMA2_SOUT_DSI3
>  	}, {
>  		DDP_COMPONENT_RDMA2, DDP_COMPONENT_DSI3,
> -		DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_RDMA2
> +		DISP_REG_CONFIG_DSIO_SEL_IN, DSI3_SEL_IN_MASK,
> +		DSI3_SEL_IN_RDMA2
>  	}
>  };
>  
> 


From patrice.chotard at foss.st.com  Wed Aug  4 08:25:45 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Wed, 4 Aug 2021 17:25:45 +0200
Subject: [PATCH 0/4] ARM: dts: sti: remove clk_ignore_unused from bootargs
In-Reply-To: <CAK8P3a06_vUXghtvp4jTMEc4jV7RW8XmbUmgfrsoH_BSZ+awJQ@mail.gmail.com>
References: <20210803124506.23365-1-patrice.chotard@foss.st.com>
 <CAK8P3a06_vUXghtvp4jTMEc4jV7RW8XmbUmgfrsoH_BSZ+awJQ@mail.gmail.com>
Message-ID: <09ee0256-5f51-513c-52f2-441e0e41aea9@foss.st.com>

Hi Arnd

On 8/4/21 3:50 PM, Arnd Bergmann wrote:
> On Tue, Aug 3, 2021 at 2:45 PM <patrice.chotard at foss.st.com> wrote:
>>
>> From: Patrice Chotard <patrice.chotard at foss.st.com>
>>
>> Remove clk_ignore_unused from bootargs from STi boards DT.
> 
> The patches look good to me, but I'm not sure what you expect me to do
> here, as you have added soc at kernel.org to Cc:, and other addresses to To:

Sorry, i wasn't aware that soc at kernel.org must only be used for pull request.

> 
> I have dropped them from patchwork for the moment. When you want
> them to be applied to the soc tree, please resend or send a pull request
> to:soc at kernel.org, until then, please leave out that address so it does
> not get into patchwork.
> 
>       Arnd
> 

Yes my intention is to submit a STi pull request with this patchset and another one.

Thanks
Patrice


From mathieu.poirier at linaro.org  Wed Aug  4 08:28:35 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 4 Aug 2021 09:28:35 -0600
Subject: [PATCH v5 5/5] remoteproc: mediatek: Support mt8195 scp
In-Reply-To: <20210803075922.11611-6-tinghan.shen@mediatek.com>
References: <20210803075922.11611-1-tinghan.shen@mediatek.com>
 <20210803075922.11611-6-tinghan.shen@mediatek.com>
Message-ID: <20210804152835.GA3145709@p14s>

On Tue, Aug 03, 2021 at 03:59:22PM +0800, Tinghan Shen wrote:
> The SCP clock design is changed on mt8195 that doesn't need to control
> SCP clock on kernel side.
> 
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> ---
>  drivers/remoteproc/mtk_common.h |  1 +
>  drivers/remoteproc/mtk_scp.c    | 48 +++++++++++++++++++++++++++++----
>  2 files changed, 44 insertions(+), 5 deletions(-)
>

Reviewed-by: Mathieu Poirier <mathieu.poirier at linaro.org>

> diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
> index 61901f5efa05..5ff3867c72f3 100644
> --- a/drivers/remoteproc/mtk_common.h
> +++ b/drivers/remoteproc/mtk_common.h
> @@ -72,6 +72,7 @@ struct scp_ipi_desc {
>  struct mtk_scp;
>  
>  struct mtk_scp_of_data {
> +	int (*scp_clk_get)(struct mtk_scp *scp);
>  	int (*scp_before_load)(struct mtk_scp *scp);
>  	void (*scp_irq_handler)(struct mtk_scp *scp);
>  	void (*scp_reset_assert)(struct mtk_scp *scp);
> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> index 9679cc26895e..36e48cf58ed6 100644
> --- a/drivers/remoteproc/mtk_scp.c
> +++ b/drivers/remoteproc/mtk_scp.c
> @@ -312,6 +312,32 @@ static int scp_elf_read_ipi_buf_addr(struct mtk_scp *scp,
>  	return -ENOENT;
>  }
>  
> +static int mt8183_scp_clk_get(struct mtk_scp *scp)
> +{
> +	struct device *dev = scp->dev;
> +	int ret = 0;
> +
> +	scp->clk = devm_clk_get(dev, "main");
> +	if (IS_ERR(scp->clk)) {
> +		dev_err(dev, "Failed to get clock\n");
> +		ret = PTR_ERR(scp->clk);
> +	}
> +
> +	return ret;
> +}
> +
> +static int mt8192_scp_clk_get(struct mtk_scp *scp)
> +{
> +	return mt8183_scp_clk_get(scp);
> +}
> +
> +static int mt8195_scp_clk_get(struct mtk_scp *scp)
> +{
> +	scp->clk = NULL;
> +
> +	return 0;
> +}
> +
>  static int mt8183_scp_before_load(struct mtk_scp *scp)
>  {
>  	/* Clear SCP to host interrupt */
> @@ -785,12 +811,9 @@ static int scp_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto destroy_mutex;
>  
> -	scp->clk = devm_clk_get(dev, "main");
> -	if (IS_ERR(scp->clk)) {
> -		dev_err(dev, "Failed to get clock\n");
> -		ret = PTR_ERR(scp->clk);
> +	ret = scp->data->scp_clk_get(scp);
> +	if (ret)
>  		goto release_dev_mem;
> -	}
>  
>  	/* register SCP initialization IPI */
>  	ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp);
> @@ -852,6 +875,7 @@ static int scp_remove(struct platform_device *pdev)
>  }
>  
>  static const struct mtk_scp_of_data mt8183_of_data = {
> +	.scp_clk_get = mt8183_scp_clk_get,
>  	.scp_before_load = mt8183_scp_before_load,
>  	.scp_irq_handler = mt8183_scp_irq_handler,
>  	.scp_reset_assert = mt8183_scp_reset_assert,
> @@ -864,6 +888,19 @@ static const struct mtk_scp_of_data mt8183_of_data = {
>  };
>  
>  static const struct mtk_scp_of_data mt8192_of_data = {
> +	.scp_clk_get = mt8192_scp_clk_get,
> +	.scp_before_load = mt8192_scp_before_load,
> +	.scp_irq_handler = mt8192_scp_irq_handler,
> +	.scp_reset_assert = mt8192_scp_reset_assert,
> +	.scp_reset_deassert = mt8192_scp_reset_deassert,
> +	.scp_stop = mt8192_scp_stop,
> +	.scp_da_to_va = mt8192_scp_da_to_va,
> +	.host_to_scp_reg = MT8192_GIPC_IN_SET,
> +	.host_to_scp_int_bit = MT8192_HOST_IPC_INT_BIT,
> +};
> +
> +static const struct mtk_scp_of_data mt8195_of_data = {
> +	.scp_clk_get = mt8195_scp_clk_get,
>  	.scp_before_load = mt8192_scp_before_load,
>  	.scp_irq_handler = mt8192_scp_irq_handler,
>  	.scp_reset_assert = mt8192_scp_reset_assert,
> @@ -877,6 +914,7 @@ static const struct mtk_scp_of_data mt8192_of_data = {
>  static const struct of_device_id mtk_scp_of_match[] = {
>  	{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
>  	{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
> +	{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
> -- 
> 2.18.0
> 


From matthias.bgg at gmail.com  Wed Aug  4 08:49:43 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 17:49:43 +0200
Subject: [PATCH v2] arm64: dts: mt8173: elm: Use aliases to mmc nodes
In-Reply-To: <20210726102442.2119877-1-hsinyi@chromium.org>
References: <20210726102442.2119877-1-hsinyi@chromium.org>
Message-ID: <7feeeae7-2d79-cd3f-18f2-ef0adfe3adeb@gmail.com>



On 26/07/2021 12:24, Hsin-Yi Wang wrote:
> Use aliases to mmc nodes so the partition name for eMMC and SD card will
> be consistent across boots.
> 
> Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>

applied to v5.14-next/dts64

Thanks

> ---
> v1->v2: skip unused mmc2.
> ---
>  arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
> index 21452c51a20a8..d5a2cad39c9c7 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
> @@ -10,6 +10,12 @@
>  #include "mt8173.dtsi"
>  
>  / {
> +	aliases {
> +		mmc0 = &mmc0;
> +		mmc1 = &mmc1;
> +		mmc2 = &mmc3;
> +	};
> +
>  	memory at 40000000 {
>  		device_type = "memory";
>  		reg = <0 0x40000000 0 0x80000000>;
> 


From mikelley at microsoft.com  Wed Aug  4 08:52:34 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Wed,  4 Aug 2021 08:52:34 -0700
Subject: [PATCH v12 0/5] Enable Linux guests on Hyper-V on ARM64
Message-ID: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>

This series enables Linux guests running on Hyper-V on ARM64
hardware. New ARM64-specific code in arch/arm64/hyperv initializes
Hyper-V and its hypercall mechanism.  Existing architecture
independent drivers for Hyper-V's VMbus and synthetic devices just
work when built for ARM64. Hyper-V code is built and included in
the image and modules only if CONFIG_HYPERV is enabled.

The five patches are organized as follows:

1) Add definitions and functions for making Hyper-V hypercalls
   and getting/setting virtual processor registers provided by
   Hyper-V

2) Add the function needed by the arch independent VMbus driver
   for reporting a panic to Hyper-V.

3) Add Hyper-V initialization code and utility functions that
   report Hyper-v status.

4) Export screen_info so it may be used by the Hyper-V frame buffer
   driver built as a module. It is already exported for x86,
   powerpc, and alpha architectures.

5) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.

Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
with 4K/16K/64K page size. Linux guests with this patch series
work with all three supported ARM64 page sizes.

The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
x86/x64-specific code and is not being built for ARM64. Enabling
Hyper-V vPCI devices on ARM64 is in progress via a separate set
of patches.

This patch set is based on the linux-next20210720 code tree.

Changes in v12:
* Updated hyperv_init() in Patch 3 to allow a kernel built
  with CONFIG_HYPERV to run in other environments. [Marc
  Zyngier, Mark Rutland]

Changes in v11:
* Drop the previous Patch 1 as the fixes have already been
  separately accepted upstream.
* Drop the previous Patch 3 for enabling Hyper-V enlightened
  clocks/timers.  Hyper-V is now offering the full ARM64
  architectural Generic Timer in guest VMs, so the existing
  arch_arch_timer.c driver just works. [Mark Rutland, Marc
  Zyngier]
* Simplified the previous Patch 4 and Patch 5 (now Patch 2 and 3)
  by sharing more code between the x86 and ARM64 architectures.
* Combined hyperv_early_init() and hyperv_init() into a single
  initialization function that runs as an early_initcall. This
  is possible because the Hyper-V enlightened clocks/timers
  no longer need to be initialized early in the boot sequence.

Changes in v10:
* Drop previous Patch 1 for SMCCC v1.2 HVC calls in favor of
  Sudeep Holla's patch [Mark Rutland]
* Use new helper functions in 5.13 for checking Hyper-V hypercall
  return status
* Set up per-CPU hypercall argument page that is now used by the
  Hyper-V balloon driver
* Rebase on 5.13-RC1

Changes in v9:
* Added Patch 1 to enable making an SMCCC compliant hypercall
  that returns results in other than registers X0 thru X3, per
  version 1.2 and later of the SMCCC spec.
* Using the ability to return results in registers X6 and X7,
  converted hv_get_vpreg_128() to use a "fast" hypercall that
  passes inputs and outputs in registers, and in doing so eliminated
  a lot of memory allocation complexity.
* Cleaned up some extra blank lines and use of spaces in aligning
  local variables. [Sunil Muthuswamy]
* Based on discussion about future directions, reverted the
  population of hv_vp_index array to use a cpuhp state instead
  of a hypercall, which is like it was in v7 and earlier.

Changes in v8:
* Removed a lot of code based on refactoring the boundary between
  arch independent and arch dependent code for Hyper-V, per comments
  from Arnd Bergmann. The removed code was either duplicated on
  the x86 side, or has been folded into architecture independent
  code as not really being architecture dependent.
* Added config dependency on !CONFIG_CPU_BIG_ENDIAN [Arnd Bergmann]
* Reworked the approach to Hyper-V initialization. The functionality
  is the same, but is now structured like the Xen code with an early
  init function called in setup_arch() and an early initcall to
  finish the initialization. [Arnd Bergmann]

Changes in v7:
* Separately upstreamed split of hyperv-tlfs.h into arch dependent
  and independent versions.  In this patch set, update the ARM64
  hyperv-tlfs.h to include architecture independent definitions.
  This approach eliminates a lot of lines of otherwise duplicated
  code on the ARM64 side.
* Break ARM64 mshyperv.h into smaller pieces. Have an initial
  baseline, and add code along with patches for a particular
  functional area. [Marc Zyngier]
* In mshyperv.h, use static inline functions instead of #defines
  where possible. [Arnd Bergmann]
* Use VMbus INTID obtained from ACPI DSDT instead of hardcoding.
  The STIMER INTID is still hardcoded because it is needed
  before Linux has initialized the ACPI subsystem, so it can't
  be obtained from the DSDT.  Wedging it into the GTDT seems
  dubious, so was not done. [Marc Zyngier]
* Update Hyper-V page size allocation functions to use
  alloc_page() if PAGE_SIZE == HV_HYP_PAGE_SIZE [Arnd
  Bergmann]
* Various other minor changes based on feedback and to rebase
  to latest linux-next [Marc Zyngier and Arnd Bergmann]

Changes in v6:
* Use SMCCC hypercall interface instead of direct invocation
  of HVC instruction and the Hyper-V hypercall interface
  [Marc Zyngier]
* Reimplemented functions to alloc/free Hyper-V size pages
  using kmalloc/kfree since kmalloc now guarantees alignment of
  power of 2 size allocations [Marc Zyngier]
* Export screen_info in arm64 architecture so it can be used
  by the Hyper-V buffer driver built as a module
* Renamed source file arch/arm64/hyperv/hv_init.c to hv_core.c
  to better reflect its content
* Fixed the bit position of certain feature flags presented by
  Hyper-V to the guest.  The bit positions on ARM64 don't match
  the position on x86 like originally thought.
* Minor fixups to rebase to 5.6-rc5 linux-next

Changes in v5:
* Minor fixups to rebase to 5.4-rc1 linux-next

Changes in v4:
* Moved clock-related code into an architecture independent
  Hyper-V clocksource driver that is already upstream. Clock
  related code is removed from this patch set except for the
  ARM64 specific interrupt handler. [Marc Zyngier]
* Separately upstreamed the split of mshyperv.h into arch independent
  and arch dependent portions. The arch independent portion has been
  removed from this patch set.
* Divided patch #2 of the series into multiple smaller patches
  [Marc Zyngier]
* Changed a dozen or so smaller things based on feedback
  [Marc Zyngier, Will Deacon]
* Added functions to alloc/free Hyper-V size pages for use by
  drivers for Hyper-V synthetic devices when updated to not assume
  guest page size and Hyper-v page size are the same

Changes in v3:
* Added initialization of hv_vp_index array like was recently
  added on x86 branch [KY Srinivasan]
* Changed Hyper-V ARM64 register symbols to be all uppercase 
  instead of mixed case [KY Srinivasan]
* Separated mshyperv.h into two files, one architecture
  independent and one architecture dependent. After this code
  is upstream, will make changes to the x86 code to use the
  architecture independent file and remove duplication. And
  once we have a multi-architecture Hyper-V TLFS, will do a
  separate patch to split hyperv-tlfs.h in the same way.
  [KY Srinivasan]
* Minor tweaks to rebase to latest linux-next code

Changes in v2:
* Removed patch to implement slow_virt_to_phys() on ARM64.
  Use of slow_virt_to_phys() in arch independent Hyper-V
  drivers has been eliminated by commit 6ba34171bcbd
  ("Drivers: hv: vmbus: Remove use of slow_virt_to_phys()")
* Minor tweaks to rebase to latest linux-next code


Michael Kelley (5):
  arm64: hyperv: Add Hyper-V hypercall and register access utilities
  arm64: hyperv: Add panic handler
  arm64: hyperv: Initialize hypervisor on boot
  arm64: efi: Export screen_info
  Drivers: hv: Enable Hyper-V code to be built on ARM64

 MAINTAINERS                          |   3 +
 arch/arm64/Kbuild                    |   1 +
 arch/arm64/hyperv/Makefile           |   2 +
 arch/arm64/hyperv/hv_core.c          | 181 +++++++++++++++++++++++++++++++++++
 arch/arm64/hyperv/mshyperv.c         |  87 +++++++++++++++++
 arch/arm64/include/asm/hyperv-tlfs.h |  69 +++++++++++++
 arch/arm64/include/asm/mshyperv.h    |  54 +++++++++++
 arch/arm64/kernel/efi.c              |   1 +
 drivers/hv/Kconfig                   |   5 +-
 9 files changed, 401 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/hyperv/Makefile
 create mode 100644 arch/arm64/hyperv/hv_core.c
 create mode 100644 arch/arm64/hyperv/mshyperv.c
 create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 create mode 100644 arch/arm64/include/asm/mshyperv.h

-- 
1.8.3.1



From mikelley at microsoft.com  Wed Aug  4 08:52:35 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Wed,  4 Aug 2021 08:52:35 -0700
Subject: [PATCH v12 1/5] arm64: hyperv: Add Hyper-V hypercall and register
 access utilities
In-Reply-To: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
Message-ID: <1628092359-61351-2-git-send-email-mikelley@microsoft.com>

hyperv-tlfs.h defines Hyper-V interfaces from the Hyper-V Top Level
Functional Spec (TLFS), and #includes the architecture-independent
part of hyperv-tlfs.h in include/asm-generic.  The published TLFS
is distinctly oriented to x86/x64, so the ARM64-specific
hyperv-tlfs.h includes information for ARM64 that is not yet formally
published. The TLFS is available here:

  docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs

mshyperv.h defines Linux-specific structures and routines for
interacting with Hyper-V on ARM64, and #includes the architecture-
independent part of mshyperv.h in include/asm-generic.

Use these definitions to provide utility functions to make
Hyper-V hypercalls and to get and set Hyper-V provided
registers associated with a virtual processor.

Signed-off-by: Michael Kelley <mikelley at microsoft.com>
Reviewed-by: Sunil Muthuswamy <sunilmut at microsoft.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>

---
 MAINTAINERS                          |   3 +
 arch/arm64/Kbuild                    |   1 +
 arch/arm64/hyperv/Makefile           |   2 +
 arch/arm64/hyperv/hv_core.c          | 129 +++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/hyperv-tlfs.h |  69 +++++++++++++++++++
 arch/arm64/include/asm/mshyperv.h    |  54 +++++++++++++++
 6 files changed, 258 insertions(+)
 create mode 100644 arch/arm64/hyperv/Makefile
 create mode 100644 arch/arm64/hyperv/hv_core.c
 create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 create mode 100644 arch/arm64/include/asm/mshyperv.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6993219..8f6f429 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8608,6 +8608,9 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git
 F:	Documentation/ABI/stable/sysfs-bus-vmbus
 F:	Documentation/ABI/testing/debugfs-hyperv
 F:	Documentation/networking/device_drivers/ethernet/microsoft/netvsc.rst
+F:	arch/arm64/hyperv
+F:	arch/arm64/include/asm/hyperv-tlfs.h
+F:	arch/arm64/include/asm/mshyperv.h
 F:	arch/x86/hyperv
 F:	arch/x86/include/asm/hyperv-tlfs.h
 F:	arch/x86/include/asm/mshyperv.h
diff --git a/arch/arm64/Kbuild b/arch/arm64/Kbuild
index 7b393cf..ea7ab4c 100644
--- a/arch/arm64/Kbuild
+++ b/arch/arm64/Kbuild
@@ -2,4 +2,5 @@
 obj-y			+= kernel/ mm/ net/
 obj-$(CONFIG_KVM)	+= kvm/
 obj-$(CONFIG_XEN)	+= xen/
+obj-$(subst m,y,$(CONFIG_HYPERV))	+= hyperv/
 obj-$(CONFIG_CRYPTO)	+= crypto/
diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
new file mode 100644
index 0000000..1697d30
--- /dev/null
+++ b/arch/arm64/hyperv/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y		:= hv_core.o
diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
new file mode 100644
index 0000000..4c5dc0f
--- /dev/null
+++ b/arch/arm64/hyperv/hv_core.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Low level utility routines for interacting with Hyper-V.
+ *
+ * Copyright (C) 2021, Microsoft, Inc.
+ *
+ * Author : Michael Kelley <mikelley at microsoft.com>
+ */
+
+#include <linux/types.h>
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/hyperv.h>
+#include <linux/arm-smccc.h>
+#include <linux/module.h>
+#include <asm-generic/bug.h>
+#include <asm/hyperv-tlfs.h>
+#include <asm/mshyperv.h>
+
+/*
+ * hv_do_hypercall- Invoke the specified hypercall
+ */
+u64 hv_do_hypercall(u64 control, void *input, void *output)
+{
+	struct arm_smccc_res	res;
+	u64			input_address;
+	u64			output_address;
+
+	input_address = input ? virt_to_phys(input) : 0;
+	output_address = output ? virt_to_phys(output) : 0;
+
+	arm_smccc_1_1_hvc(HV_FUNC_ID, control,
+			  input_address, output_address, &res);
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
+
+/*
+ * hv_do_fast_hypercall8 -- Invoke the specified hypercall
+ * with arguments in registers instead of physical memory.
+ * Avoids the overhead of virt_to_phys for simple hypercalls.
+ */
+
+u64 hv_do_fast_hypercall8(u16 code, u64 input)
+{
+	struct arm_smccc_res	res;
+	u64			control;
+
+	control = (u64)code | HV_HYPERCALL_FAST_BIT;
+
+	arm_smccc_1_1_hvc(HV_FUNC_ID, control, input, &res);
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(hv_do_fast_hypercall8);
+
+/*
+ * Set a single VP register to a 64-bit value.
+ */
+void hv_set_vpreg(u32 msr, u64 value)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(HV_FUNC_ID,
+		HVCALL_SET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
+			HV_HYPERCALL_REP_COMP_1,
+		HV_PARTITION_ID_SELF,
+		HV_VP_INDEX_SELF,
+		msr,
+		0,
+		value,
+		0,
+		&res);
+
+	/*
+	 * Something is fundamentally broken in the hypervisor if
+	 * setting a VP register fails. There's really no way to
+	 * continue as a guest VM, so panic.
+	 */
+	BUG_ON(!hv_result_success(res.a0));
+}
+EXPORT_SYMBOL_GPL(hv_set_vpreg);
+
+/*
+ * Get the value of a single VP register.  One version
+ * returns just 64 bits and another returns the full 128 bits.
+ * The two versions are separate to avoid complicating the
+ * calling sequence for the more frequently used 64 bit version.
+ */
+
+void hv_get_vpreg_128(u32 msr, struct hv_get_vp_registers_output *result)
+{
+	struct arm_smccc_1_2_regs args;
+	struct arm_smccc_1_2_regs res;
+
+	args.a0 = HV_FUNC_ID;
+	args.a1 = HVCALL_GET_VP_REGISTERS | HV_HYPERCALL_FAST_BIT |
+			HV_HYPERCALL_REP_COMP_1;
+	args.a2 = HV_PARTITION_ID_SELF;
+	args.a3 = HV_VP_INDEX_SELF;
+	args.a4 = msr;
+
+	/*
+	 * Use the SMCCC 1.2 interface because the results are in registers
+	 * beyond X0-X3.
+	 */
+	arm_smccc_1_2_hvc(&args, &res);
+
+	/*
+	 * Something is fundamentally broken in the hypervisor if
+	 * getting a VP register fails. There's really no way to
+	 * continue as a guest VM, so panic.
+	 */
+	BUG_ON(!hv_result_success(res.a0));
+
+	result->as64.low = res.a6;
+	result->as64.high = res.a7;
+}
+EXPORT_SYMBOL_GPL(hv_get_vpreg_128);
+
+u64 hv_get_vpreg(u32 msr)
+{
+	struct hv_get_vp_registers_output output;
+
+	hv_get_vpreg_128(msr, &output);
+
+	return output.as64.low;
+}
+EXPORT_SYMBOL_GPL(hv_get_vpreg);
diff --git a/arch/arm64/include/asm/hyperv-tlfs.h b/arch/arm64/include/asm/hyperv-tlfs.h
new file mode 100644
index 0000000..4d964a7
--- /dev/null
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file contains definitions from the Hyper-V Hypervisor Top-Level
+ * Functional Specification (TLFS):
+ * https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs
+ *
+ * Copyright (C) 2021, Microsoft, Inc.
+ *
+ * Author : Michael Kelley <mikelley at microsoft.com>
+ */
+
+#ifndef _ASM_HYPERV_TLFS_H
+#define _ASM_HYPERV_TLFS_H
+
+#include <linux/types.h>
+
+/*
+ * All data structures defined in the TLFS that are shared between Hyper-V
+ * and a guest VM use Little Endian byte ordering.  This matches the default
+ * byte ordering of Linux running on ARM64, so no special handling is required.
+ */
+
+/*
+ * These Hyper-V registers provide information equivalent to the CPUID
+ * instruction on x86/x64.
+ */
+#define HV_REGISTER_HYPERVISOR_VERSION		0x00000100 /*CPUID 0x40000002 */
+#define HV_REGISTER_FEATURES			0x00000200 /*CPUID 0x40000003 */
+#define HV_REGISTER_ENLIGHTENMENTS		0x00000201 /*CPUID 0x40000004 */
+
+/*
+ * Group C Features. See the asm-generic version of hyperv-tlfs.h
+ * for a description of Feature Groups.
+ */
+
+/* Crash MSRs available */
+#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE	BIT(8)
+
+/* STIMER direct mode is available */
+#define HV_STIMER_DIRECT_MODE_AVAILABLE		BIT(13)
+
+/*
+ * Synthetic register definitions equivalent to MSRs on x86/x64
+ */
+#define HV_REGISTER_CRASH_P0		0x00000210
+#define HV_REGISTER_CRASH_P1		0x00000211
+#define HV_REGISTER_CRASH_P2		0x00000212
+#define HV_REGISTER_CRASH_P3		0x00000213
+#define HV_REGISTER_CRASH_P4		0x00000214
+#define HV_REGISTER_CRASH_CTL		0x00000215
+
+#define HV_REGISTER_GUEST_OSID		0x00090002
+#define HV_REGISTER_VP_INDEX		0x00090003
+#define HV_REGISTER_TIME_REF_COUNT	0x00090004
+#define HV_REGISTER_REFERENCE_TSC	0x00090017
+
+#define HV_REGISTER_SINT0		0x000A0000
+#define HV_REGISTER_SCONTROL		0x000A0010
+#define HV_REGISTER_SIEFP		0x000A0012
+#define HV_REGISTER_SIMP		0x000A0013
+#define HV_REGISTER_EOM			0x000A0014
+
+#define HV_REGISTER_STIMER0_CONFIG	0x000B0000
+#define HV_REGISTER_STIMER0_COUNT	0x000B0001
+
+#include <asm-generic/hyperv-tlfs.h>
+
+#endif
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
new file mode 100644
index 0000000..20070a8
--- /dev/null
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Linux-specific definitions for managing interactions with Microsoft's
+ * Hyper-V hypervisor. The definitions in this file are specific to
+ * the ARM64 architecture.  See include/asm-generic/mshyperv.h for
+ * definitions are that architecture independent.
+ *
+ * Definitions that are specified in the Hyper-V Top Level Functional
+ * Spec (TLFS) should not go in this file, but should instead go in
+ * hyperv-tlfs.h.
+ *
+ * Copyright (C) 2021, Microsoft, Inc.
+ *
+ * Author : Michael Kelley <mikelley at microsoft.com>
+ */
+
+#ifndef _ASM_MSHYPERV_H
+#define _ASM_MSHYPERV_H
+
+#include <linux/types.h>
+#include <linux/arm-smccc.h>
+#include <asm/hyperv-tlfs.h>
+
+/*
+ * Declare calls to get and set Hyper-V VP register values on ARM64, which
+ * requires a hypercall.
+ */
+
+void hv_set_vpreg(u32 reg, u64 value);
+u64 hv_get_vpreg(u32 reg);
+void hv_get_vpreg_128(u32 reg, struct hv_get_vp_registers_output *result);
+
+static inline void hv_set_register(unsigned int reg, u64 value)
+{
+	hv_set_vpreg(reg, value);
+}
+
+static inline u64 hv_get_register(unsigned int reg)
+{
+	return hv_get_vpreg(reg);
+}
+
+/* SMCCC hypercall parameters */
+#define HV_SMCCC_FUNC_NUMBER	1
+#define HV_FUNC_ID	ARM_SMCCC_CALL_VAL(			\
+				ARM_SMCCC_STD_CALL,		\
+				ARM_SMCCC_SMC_64,		\
+				ARM_SMCCC_OWNER_VENDOR_HYP,	\
+				HV_SMCCC_FUNC_NUMBER)
+
+#include <asm-generic/mshyperv.h>
+
+#endif
-- 
1.8.3.1



From mikelley at microsoft.com  Wed Aug  4 08:52:36 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Wed,  4 Aug 2021 08:52:36 -0700
Subject: [PATCH v12 2/5] arm64: hyperv: Add panic handler
In-Reply-To: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
Message-ID: <1628092359-61351-3-git-send-email-mikelley@microsoft.com>

Add a function to inform Hyper-V about a guest panic.

This code is built only when CONFIG_HYPERV is enabled.

Signed-off-by: Michael Kelley <mikelley at microsoft.com>
Reviewed-by: Sunil Muthuswamy <sunilmut at microsoft.com>
Reviewed-by: Boqun Feng <boqun.feng at gmail.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>

---
 arch/arm64/hyperv/hv_core.c | 52 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index 4c5dc0f..b54c347 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -127,3 +127,55 @@ u64 hv_get_vpreg(u32 msr)
 	return output.as64.low;
 }
 EXPORT_SYMBOL_GPL(hv_get_vpreg);
+
+/*
+ * hyperv_report_panic - report a panic to Hyper-V.  This function uses
+ * the older version of the Hyper-V interface that admittedly doesn't
+ * pass enough information to be useful beyond just recording the
+ * occurrence of a panic. The parallel hv_kmsg_dump() uses the
+ * new interface that allows reporting 4 Kbytes of data, which is much
+ * more useful. Hyper-V on ARM64 always supports the newer interface, but
+ * we retain support for the older version because the sysadmin is allowed
+ * to disable the newer version via sysctl in case of information security
+ * concerns about the more verbose version.
+ */
+void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
+{
+	static bool	panic_reported;
+	u64		guest_id;
+
+	/* Don't report a panic to Hyper-V if we're not going to panic */
+	if (in_die && !panic_on_oops)
+		return;
+
+	/*
+	 * We prefer to report panic on 'die' chain as we have proper
+	 * registers to report, but if we miss it (e.g. on BUG()) we need
+	 * to report it on 'panic'.
+	 *
+	 * Calling code in the 'die' and 'panic' paths ensures that only
+	 * one CPU is running this code, so no atomicity is needed.
+	 */
+	if (panic_reported)
+		return;
+	panic_reported = true;
+
+	guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID);
+
+	/*
+	 * Hyper-V provides the ability to store only 5 values.
+	 * Pick the passed in error value, the guest_id, the PC,
+	 * and the SP.
+	 */
+	hv_set_vpreg(HV_REGISTER_CRASH_P0, err);
+	hv_set_vpreg(HV_REGISTER_CRASH_P1, guest_id);
+	hv_set_vpreg(HV_REGISTER_CRASH_P2, regs->pc);
+	hv_set_vpreg(HV_REGISTER_CRASH_P3, regs->sp);
+	hv_set_vpreg(HV_REGISTER_CRASH_P4, 0);
+
+	/*
+	 * Let Hyper-V know there is crash data available
+	 */
+	hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
+}
+EXPORT_SYMBOL_GPL(hyperv_report_panic);
-- 
1.8.3.1



From mikelley at microsoft.com  Wed Aug  4 08:52:37 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Wed,  4 Aug 2021 08:52:37 -0700
Subject: [PATCH v12 3/5] arm64: hyperv: Initialize hypervisor on boot
In-Reply-To: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
Message-ID: <1628092359-61351-4-git-send-email-mikelley@microsoft.com>

Add ARM64-specific code to initialize the Hyper-V
hypervisor when booting as a guest VM.

This code is built only when CONFIG_HYPERV is enabled.

Signed-off-by: Michael Kelley <mikelley at microsoft.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>

---
 arch/arm64/hyperv/Makefile   |  2 +-
 arch/arm64/hyperv/mshyperv.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/hyperv/mshyperv.c

diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
index 1697d30..87c31c0 100644
--- a/arch/arm64/hyperv/Makefile
+++ b/arch/arm64/hyperv/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-y		:= hv_core.o
+obj-y		:= hv_core.o mshyperv.o
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
new file mode 100644
index 0000000..bbbe351
--- /dev/null
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Core routines for interacting with Microsoft's Hyper-V hypervisor,
+ * including hypervisor initialization.
+ *
+ * Copyright (C) 2021, Microsoft, Inc.
+ *
+ * Author : Michael Kelley <mikelley at microsoft.com>
+ */
+
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <linux/export.h>
+#include <linux/errno.h>
+#include <linux/version.h>
+#include <linux/cpuhotplug.h>
+#include <asm/mshyperv.h>
+
+static bool hyperv_initialized;
+
+static int __init hyperv_init(void)
+{
+	struct hv_get_vp_registers_output	result;
+	u32	a, b, c, d;
+	u64	guest_id;
+	int	ret;
+
+	/*
+	 * Allow for a kernel built with CONFIG_HYPERV to be running in
+	 * a non-Hyper-V environment, including on DT instead of ACPI.
+	 * In such cases, do nothing and return success.
+	 */
+	if (acpi_disabled)
+		return 0;
+
+	if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
+		return 0;
+
+	/* Setup the guest ID */
+	guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0);
+	hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
+
+	/* Get the features and hints from Hyper-V */
+	hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
+	ms_hyperv.features = result.as32.a;
+	ms_hyperv.priv_high = result.as32.b;
+	ms_hyperv.misc_features = result.as32.c;
+
+	hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result);
+	ms_hyperv.hints = result.as32.a;
+
+	pr_info("Hyper-V: privilege flags low 0x%x, high 0x%x, hints 0x%x, misc 0x%x\n",
+		ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
+		ms_hyperv.misc_features);
+
+	/* Get information about the Hyper-V host version */
+	hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
+	a = result.as32.a;
+	b = result.as32.b;
+	c = result.as32.c;
+	d = result.as32.d;
+	pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
+		b >> 16, b & 0xFFFF, a,	d & 0xFFFFFF, c, d >> 24);
+
+	ret = hv_common_init();
+	if (ret)
+		return ret;
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm64/hyperv_init:online",
+				hv_common_cpu_init, hv_common_cpu_die);
+	if (ret < 0) {
+		hv_common_free();
+		return ret;
+	}
+
+	hyperv_initialized = true;
+	return 0;
+}
+
+early_initcall(hyperv_init);
+
+bool hv_is_hyperv_initialized(void)
+{
+	return hyperv_initialized;
+}
+EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized);
-- 
1.8.3.1



From mikelley at microsoft.com  Wed Aug  4 08:52:39 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Wed,  4 Aug 2021 08:52:39 -0700
Subject: [PATCH v12 5/5] Drivers: hv: Enable Hyper-V code to be built on ARM64
In-Reply-To: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
Message-ID: <1628092359-61351-6-git-send-email-mikelley@microsoft.com>

Update drivers/hv/Kconfig so CONFIG_HYPERV can be selected on
ARM64, causing the Hyper-V specific code to be built. Exclude the
Hyper-V enlightened clocks/timers code from being built for ARM64.

Signed-off-by: Michael Kelley <mikelley at microsoft.com>
Reviewed-by: Boqun Feng <boqun.feng at gmail.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>

---
 drivers/hv/Kconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 66c794d..e509d5d 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -4,7 +4,8 @@ menu "Microsoft Hyper-V guest support"
 
 config HYPERV
 	tristate "Microsoft Hyper-V client drivers"
-	depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
+	depends on ACPI && ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \
+		|| (ARM64 && !CPU_BIG_ENDIAN))
 	select PARAVIRT
 	select X86_HV_CALLBACK_VECTOR
 	help
@@ -12,7 +13,7 @@ config HYPERV
 	  system.
 
 config HYPERV_TIMER
-	def_bool HYPERV
+	def_bool HYPERV && X86
 
 config HYPERV_UTILS
 	tristate "Microsoft Hyper-V Utilities driver"
-- 
1.8.3.1



From mikelley at microsoft.com  Wed Aug  4 08:52:38 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Wed,  4 Aug 2021 08:52:38 -0700
Subject: [PATCH v12 4/5] arm64: efi: Export screen_info
In-Reply-To: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
Message-ID: <1628092359-61351-5-git-send-email-mikelley@microsoft.com>

The Hyper-V frame buffer driver may be built as a module, and
it needs access to screen_info. So export screen_info.

Signed-off-by: Michael Kelley <mikelley at microsoft.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Marc Zyngier <maz at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>

---
 arch/arm64/kernel/efi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index fa02efb..e1be6c4 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -55,6 +55,7 @@ static __init pteval_t create_mapping_protection(efi_memory_desc_t *md)
 
 /* we will fill this structure from the stub, so don't put it in .bss */
 struct screen_info screen_info __section(".data");
+EXPORT_SYMBOL(screen_info);
 
 int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
 {
-- 
1.8.3.1



From matthias.bgg at gmail.com  Wed Aug  4 08:56:08 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 17:56:08 +0200
Subject: [PATCH v2 2/2] arm64: dts: mt8173: elm: Use aliases to mmc nodes
In-Reply-To: <20210727111502.2506311-2-hsinyi@chromium.org>
References: <20210727111502.2506311-1-hsinyi@chromium.org>
 <20210727111502.2506311-2-hsinyi@chromium.org>
Message-ID: <044b85f1-dd05-19c9-f9ee-17e620699733@gmail.com>



On 27/07/2021 13:15, Hsin-Yi Wang wrote:
> fa2d0aa96941 ("mmc: core: Allow setting slot index via device tree alias")
> allows the use of aliases to number SD/MMC slots. This patch use aliases
> to mmc nodes so the partition name for eMMC and SD card will be consistent
> across boots.
> 
> Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
> index 21452c51a20a8..d5a2cad39c9c7 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
> @@ -10,6 +10,12 @@
>  #include "mt8173.dtsi"
>  
>  / {
> +	aliases {
> +		mmc0 = &mmc0;
> +		mmc1 = &mmc1;
> +		mmc2 = &mmc3;
> +	};

I overwrote v1 of this patch with this one. Both of the series are now in
v5.14-next/dts64

Thanks

> +
>  	memory at 40000000 {
>  		device_type = "memory";
>  		reg = <0 0x40000000 0 0x80000000>;
> 


From frank-w at public-files.de  Wed Aug  4 08:59:46 2021
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 4 Aug 2021 17:59:46 +0200
Subject: Aw: Re: [PATCH v2] soc: mmsys: mediatek: add mask to mmsys routes
In-Reply-To: <e8c990b6-180d-9702-d8cc-fd1e98dfc744@gmail.com>
References: <20210729070549.5514-1-linux@fw-web.de>
 <e8c990b6-180d-9702-d8cc-fd1e98dfc744@gmail.com>
Message-ID: <trinity-7bda902b-2c2b-4b74-99fe-9258b7ebedcf-1628092786728@3c-app-gmx-bap67>

Hi,

> Gesendet: Mittwoch, 04. August 2021 um 17:17 Uhr
> Von: "Matthias Brugger" <matthias.bgg at gmail.com>

> My understanding is, that this does not break mt8173 and other SoCs that use the
> default routing table. Correct?

i took the mask values from CK Hu's Patch, mt7623 uses this table and with it hdmi works again (was broken by the array-commit). I'm not sure on which devices Chun-Kuang has tested it, he only suggests to add the mask again from his commit to fix mt7623.

https://patchwork.kernel.org/project/linux-mediatek/patch/20210710132431.265985-1-linux at fw-web.de/#24335233

I can only test on mt7623/BPI-R2...

there is a new patchset for mt8192 which adds a new routing-table, which needs to be extended with mask values (without it wil not work, but maybe duplicate values may work):

https://patchwork.kernel.org/project/linux-mediatek/patch/1627894773-23872-3-git-send-email-yongqiang.niu at mediatek.com/

regards Frank

> Added now to v5.14-next/soc
> Thanks.

Thanks too


From catalin.marinas at arm.com  Wed Aug  4 09:10:41 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 4 Aug 2021 17:10:41 +0100
Subject: [PATCH v12 5/5] Drivers: hv: Enable Hyper-V code to be built on
 ARM64
In-Reply-To: <1628092359-61351-6-git-send-email-mikelley@microsoft.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
 <1628092359-61351-6-git-send-email-mikelley@microsoft.com>
Message-ID: <20210804161040.GC4857@arm.com>

On Wed, Aug 04, 2021 at 08:52:39AM -0700, Michael Kelley wrote:
> Update drivers/hv/Kconfig so CONFIG_HYPERV can be selected on
> ARM64, causing the Hyper-V specific code to be built. Exclude the
> Hyper-V enlightened clocks/timers code from being built for ARM64.
> 
> Signed-off-by: Michael Kelley <mikelley at microsoft.com>
> Reviewed-by: Boqun Feng <boqun.feng at gmail.com>
> Acked-by: Marc Zyngier <maz at kernel.org>
> Acked-by: Mark Rutland <mark.rutland at arm.com>
> 
> ---
>  drivers/hv/Kconfig | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> index 66c794d..e509d5d 100644
> --- a/drivers/hv/Kconfig
> +++ b/drivers/hv/Kconfig
> @@ -4,7 +4,8 @@ menu "Microsoft Hyper-V guest support"
>  
>  config HYPERV
>  	tristate "Microsoft Hyper-V client drivers"
> -	depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
> +	depends on ACPI && ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \
> +		|| (ARM64 && !CPU_BIG_ENDIAN))
>  	select PARAVIRT
>  	select X86_HV_CALLBACK_VECTOR

Does this need to be:

	select X86_HV_CALLBACK_VECTOR if X86

I haven't checked whether it gives a warning on arm64 but that symbol
doesn't exist.

Anyway, I can fix it up locally.

As an additional patch (it can be done later, once this goes upstream) I
think we should replace the depends on with a single ARCH_HAS_HYPERV.

-- 
Catalin


From grygorii.strashko at ti.com  Wed Aug  4 09:23:25 2021
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 4 Aug 2021 19:23:25 +0300
Subject: [PATCH] ARM: Fix Keystone 2 kernel mapping regression
In-Reply-To: <20210804141042.GQ22278@shell.armlinux.org.uk>
References: <20210804135747.737233-1-linus.walleij@linaro.org>
 <20210804141042.GQ22278@shell.armlinux.org.uk>
Message-ID: <bc8e70f9-2d8c-39be-63bc-3fd871d20a37@ti.com>



On 04/08/2021 17:10, Russell King (Oracle) wrote:
> Hi Linus,
> 
> Looks fine. An improvement:
> 
> On Wed, Aug 04, 2021 at 03:57:47PM +0200, Linus Walleij wrote:
>> @@ -250,7 +253,12 @@ __create_page_tables:
>>   	add	r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ORDER)
>>   	ldr	r6, =(_end - 1)
>>   	adr_l	r5, kernel_sec_start		@ _pa(kernel_sec_start)
>> -	str	r8, [r5]			@ Save physical start of kernel
>> +#ifdef CONFIG_CPU_ENDIAN_BE8
>> +	add	r5, r5, #4			@ Move to the upper 32bit word
>> +	str	r8, [r5]			@ Save physical start of kernel (BE)
> 
> These two instructions can simply be replaced with:
> 
> 	str	r8, [r5, #4]
> 
>> +#else
>> +	str	r8, [r5]			@ Save physical start of kernel (LE)
>> +#endif
>>   	orr	r3, r8, r7			@ Add the MMU flags
>>   	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
>>   1:	str	r3, [r0], #1 << PMD_ORDER
>> @@ -259,7 +267,12 @@ __create_page_tables:
>>   	bls	1b
>>   	eor	r3, r3, r7			@ Remove the MMU flags
>>   	adr_l	r5, kernel_sec_end		@ _pa(kernel_sec_end)
>> -	str	r3, [r5]			@ Save physical end of kernel
>> +#ifdef CONFIG_CPU_ENDIAN_BE8
>> +	add	r5, r5, #4			@ Move to the upper 32bit word
>> +	str	r8, [r5]			@ Save physical end of kernel (BE)
> 
> Same here.
> 
> The patch can still usefully be tested by Nishanth without these
> changes... it'll tell us if this was indeed the issue.
> 
> Thanks!
> 

with
903101cbc1f6 (HEAD -> next-master) ARM: Fix Keystone 2 kernel mapping regression
c3f7b3be172b (tag: next-20210803, linux-next/master) Add linux-next specific files for 20210803
eaf554c397cd Merge branch 'akpm/master'

can boot to console.
https://pastebin.ubuntu.com/p/fPJPQWxwkT/


-- 
Best regards,
grygorii


From catalin.marinas at arm.com  Wed Aug  4 09:25:57 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 4 Aug 2021 17:25:57 +0100
Subject: [PATCH v12 0/5] Enable Linux guests on Hyper-V on ARM64
In-Reply-To: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
Message-ID: <20210804162555.GD4857@arm.com>

On Wed, Aug 04, 2021 at 08:52:34AM -0700, Michael Kelley wrote:
> This series enables Linux guests running on Hyper-V on ARM64
> hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> Hyper-V and its hypercall mechanism.  Existing architecture
> independent drivers for Hyper-V's VMbus and synthetic devices just
> work when built for ARM64. Hyper-V code is built and included in
> the image and modules only if CONFIG_HYPERV is enabled.
[...]
> Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> with 4K/16K/64K page size. Linux guests with this patch series
> work with all three supported ARM64 page sizes.
> 
> The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> x86/x64-specific code and is not being built for ARM64. Enabling
> Hyper-V vPCI devices on ARM64 is in progress via a separate set
> of patches.
> 
> This patch set is based on the linux-next20210720 code tree.

Is it possible to rebase this on top of -rc3? Are there any
dependencies or do you plan to upstream this via a different tree?

It applies cleanly but it doesn't build for me:

In file included from arch/arm64/include/asm/mshyperv.h:52,
                 from arch/arm64/hyperv/hv_core.c:19:
include/asm-generic/mshyperv.h: In function 'hv_do_rep_hypercall':
include/asm-generic/mshyperv.h:86:3: error: implicit declaration of function 'touch_nmi_watchdog' [-Werror=implicit-function-declaration]
   86 |   touch_nmi_watchdog();
      |   ^~~~~~~~~~~~~~~~~~

A quick fix for the above was to include nmi.h in mshyperv.h.

However, the below I can't fix since there's no trace of
hv_common_init() on top of 5.14-rc3:

arch/arm64/hyperv/mshyperv.c: In function 'hyperv_init':
arch/arm64/hyperv/mshyperv.c:66:8: error: implicit declaration of function 'hv_common_init' [-Werror=implicit-function-declaration]
   66 |  ret = hv_common_init();
      |        ^~~~~~~~~~~~~~
arch/arm64/hyperv/mshyperv.c:71:5: error: 'hv_common_cpu_init' undeclared (first use in this function)
   71 |     hv_common_cpu_init, hv_common_cpu_die);
      |     ^~~~~~~~~~~~~~~~~~
arch/arm64/hyperv/mshyperv.c:71:5: note: each undeclared identifier is reported only once for each function it appears in
arch/arm64/hyperv/mshyperv.c:71:25: error: 'hv_common_cpu_die' undeclared (first use in this function)
   71 |     hv_common_cpu_init, hv_common_cpu_die);
      |                         ^~~~~~~~~~~~~~~~~
arch/arm64/hyperv/mshyperv.c:73:3: error: implicit declaration of function 'hv_common_free' [-Werror=implicit-function-declaration]
   73 |   hv_common_free();
      |   ^~~~~~~~~~~~~~

-- 
Catalin


From wei.liu at kernel.org  Wed Aug  4 09:37:09 2021
From: wei.liu at kernel.org (Wei Liu)
Date: Wed, 4 Aug 2021 16:37:09 +0000
Subject: [PATCH v12 0/5] Enable Linux guests on Hyper-V on ARM64
In-Reply-To: <20210804162555.GD4857@arm.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
 <20210804162555.GD4857@arm.com>
Message-ID: <20210804163709.afu53w5sk35k23m7@liuwe-devbox-debian-v2>

On Wed, Aug 04, 2021 at 05:25:57PM +0100, Catalin Marinas wrote:
> On Wed, Aug 04, 2021 at 08:52:34AM -0700, Michael Kelley wrote:
> > This series enables Linux guests running on Hyper-V on ARM64
> > hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> > Hyper-V and its hypercall mechanism.  Existing architecture
> > independent drivers for Hyper-V's VMbus and synthetic devices just
> > work when built for ARM64. Hyper-V code is built and included in
> > the image and modules only if CONFIG_HYPERV is enabled.
> [...]
> > Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> > with 4K/16K/64K page size. Linux guests with this patch series
> > work with all three supported ARM64 page sizes.
> > 
> > The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> > x86/x64-specific code and is not being built for ARM64. Enabling
> > Hyper-V vPCI devices on ARM64 is in progress via a separate set
> > of patches.
> > 
> > This patch set is based on the linux-next20210720 code tree.
> 
> Is it possible to rebase this on top of -rc3? Are there any
> dependencies or do you plan to upstream this via a different tree?

Some prerequisite patches are in hyperv-next.

https://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git/log/?h=hyperv-next

Wei.


From mikelley at microsoft.com  Wed Aug  4 09:39:02 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Wed, 4 Aug 2021 16:39:02 +0000
Subject: [PATCH v12 0/5] Enable Linux guests on Hyper-V on ARM64
In-Reply-To: <20210804162555.GD4857@arm.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
 <20210804162555.GD4857@arm.com>
Message-ID: <MWHPR21MB159317B1D47ED60C73B47021D7F19@MWHPR21MB1593.namprd21.prod.outlook.com>

From: Catalin Marinas <catalin.marinas at arm.com> Sent: Wednesday, August 4, 2021 9:26 AM
> 
> On Wed, Aug 04, 2021 at 08:52:34AM -0700, Michael Kelley wrote:
> > This series enables Linux guests running on Hyper-V on ARM64
> > hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> > Hyper-V and its hypercall mechanism.  Existing architecture
> > independent drivers for Hyper-V's VMbus and synthetic devices just
> > work when built for ARM64. Hyper-V code is built and included in
> > the image and modules only if CONFIG_HYPERV is enabled.
> [...]
> > Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> > with 4K/16K/64K page size. Linux guests with this patch series
> > work with all three supported ARM64 page sizes.
> >
> > The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> > x86/x64-specific code and is not being built for ARM64. Enabling
> > Hyper-V vPCI devices on ARM64 is in progress via a separate set
> > of patches.
> >
> > This patch set is based on the linux-next20210720 code tree.
> 
> Is it possible to rebase this on top of -rc3? Are there any
> dependencies or do you plan to upstream this via a different tree?
> 

There are dependencies on changes in the hyperv-next tree
(https://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git/)
which is why you are getting the build errors.  The changes
common-ized some code between the x86 side and previous
versions of this patch set (and fixed the #include nmi.h problem). 
So the code would most naturally go upstream through that tree.

Michael


> It applies cleanly but it doesn't build for me:
> 
> In file included from arch/arm64/include/asm/mshyperv.h:52,
>                  from arch/arm64/hyperv/hv_core.c:19:
> include/asm-generic/mshyperv.h: In function 'hv_do_rep_hypercall':
> include/asm-generic/mshyperv.h:86:3: error: implicit declaration of function 'touch_nmi_watchdog' [-Werror=implicit-
> function-declaration]
>    86 |   touch_nmi_watchdog();
>       |   ^~~~~~~~~~~~~~~~~~
> 
> A quick fix for the above was to include nmi.h in mshyperv.h.
> 
> However, the below I can't fix since there's no trace of
> hv_common_init() on top of 5.14-rc3:
> 
> arch/arm64/hyperv/mshyperv.c: In function 'hyperv_init':
> arch/arm64/hyperv/mshyperv.c:66:8: error: implicit declaration of function 'hv_common_init' [-Werror=implicit-function-
> declaration]
>    66 |  ret = hv_common_init();
>       |        ^~~~~~~~~~~~~~
> arch/arm64/hyperv/mshyperv.c:71:5: error: 'hv_common_cpu_init' undeclared (first use in this function)
>    71 |     hv_common_cpu_init, hv_common_cpu_die);
>       |     ^~~~~~~~~~~~~~~~~~
> arch/arm64/hyperv/mshyperv.c:71:5: note: each undeclared identifier is reported only once for each function it appears in
> arch/arm64/hyperv/mshyperv.c:71:25: error: 'hv_common_cpu_die' undeclared (first use in this function)
>    71 |     hv_common_cpu_init, hv_common_cpu_die);
>       |                         ^~~~~~~~~~~~~~~~~
> arch/arm64/hyperv/mshyperv.c:73:3: error: implicit declaration of function 'hv_common_free' [-Werror=implicit-function-
> declaration]
>    73 |   hv_common_free();
>       |   ^~~~~~~~~~~~~~
> 
> --
> Catalin


From wei.liu at kernel.org  Wed Aug  4 09:40:29 2021
From: wei.liu at kernel.org (Wei Liu)
Date: Wed, 4 Aug 2021 16:40:29 +0000
Subject: [PATCH v12 5/5] Drivers: hv: Enable Hyper-V code to be built on
 ARM64
In-Reply-To: <20210804161040.GC4857@arm.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
 <1628092359-61351-6-git-send-email-mikelley@microsoft.com>
 <20210804161040.GC4857@arm.com>
Message-ID: <20210804164029.6xmloksmssrdsmvo@liuwe-devbox-debian-v2>

On Wed, Aug 04, 2021 at 05:10:41PM +0100, Catalin Marinas wrote:
> On Wed, Aug 04, 2021 at 08:52:39AM -0700, Michael Kelley wrote:
> > Update drivers/hv/Kconfig so CONFIG_HYPERV can be selected on
> > ARM64, causing the Hyper-V specific code to be built. Exclude the
> > Hyper-V enlightened clocks/timers code from being built for ARM64.
> > 
> > Signed-off-by: Michael Kelley <mikelley at microsoft.com>
> > Reviewed-by: Boqun Feng <boqun.feng at gmail.com>
> > Acked-by: Marc Zyngier <maz at kernel.org>
> > Acked-by: Mark Rutland <mark.rutland at arm.com>
> > 
> > ---
> >  drivers/hv/Kconfig | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> > index 66c794d..e509d5d 100644
> > --- a/drivers/hv/Kconfig
> > +++ b/drivers/hv/Kconfig
> > @@ -4,7 +4,8 @@ menu "Microsoft Hyper-V guest support"
> >  
> >  config HYPERV
> >  	tristate "Microsoft Hyper-V client drivers"
> > -	depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
> > +	depends on ACPI && ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \
> > +		|| (ARM64 && !CPU_BIG_ENDIAN))
> >  	select PARAVIRT
> >  	select X86_HV_CALLBACK_VECTOR
> 
> Does this need to be:
> 
> 	select X86_HV_CALLBACK_VECTOR if X86
> 
> I haven't checked whether it gives a warning on arm64 but that symbol
> doesn't exist.
> 
> Anyway, I can fix it up locally.

I can fix it up while I queue these patches.

Wei.


From nm at ti.com  Wed Aug  4 09:40:33 2021
From: nm at ti.com (Nishanth Menon)
Date: Wed, 4 Aug 2021 11:40:33 -0500
Subject: [PATCH] ARM: Fix Keystone 2 kernel mapping regression
In-Reply-To: <20210804135747.737233-1-linus.walleij@linaro.org>
References: <20210804135747.737233-1-linus.walleij@linaro.org>
Message-ID: <20210804164033.5omplm7qs7fuxgfb@cupcake>

On 15:57-20210804, Linus Walleij wrote:
> This fixes a Keystone 2 regression discovered as a side effect of
> defining an passing the physical start/end sections of the kernel
> to the MMU remapping code.
> 
> As the Keystone applies an offset to all physical addresses,
> including those identified and patches by phys2virt, we fail to
> account for this offset in the kernel_sec_start and kernel_sec_end
> variables.
> 
> Further these offsets can extend into the 64bit range on LPAE
> systems such as the Keystone 2.
> 
> Fix it like this:
> - Extend kernel_sec_start and kernel_sec_end to be 64bit
> - Add the offset also to kernel_sec_start and kernel_sec_end
> 
> As passing kernel_sec_start and kernel_sec_end as 64bit invariably
> incurs endianness issues I have attempted to dry-code around
> these. Please review.
> 
> Tested on the Vexpress QEMU model both with and without LPAE
> enabled.
> 
> Fixes: 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel separately")
> Reported-by: Nishanth Menon <nmenon at kernel.org>
> Suggested-by: Russell King <linux at armlinux.org.uk>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> Signed-off-by: Nishanth Menon <nm at ti.com>
> Link: https://lore.kernel.org/r/20210804135747.737233-1-linus.walleij at linaro.org
> ---
> Nishanth: Please test!
> Other smart folks: please have a look at my endianness compensation
> assembly.

Russell, Linus - awesome. thanks for looking at the right problem.

test log (two k2 platforms from two generations):
Baseline(good): v5.13
k2g-evm: https://pastebin.ubuntu.com/p/xnGy9fM6mj/
k2hk-evm: https://pastebin.ubuntu.com/p/gpX6bPsF2R/

Check base(bad): v5.14-rc4
k2g-evm: 
k2hk-evm: https://pastebin.ubuntu.com/p/ht7sTjyTD2/
k2g-evm: https://pastebin.ubuntu.com/p/skf8nsGqPZ/

Check patch: v5.14-rc4 + 20210804135747.737233-1-linus.walleij at linaro.org
k2hk-evm: https://pastebin.ubuntu.com/p/ycX7bmgcyT/
k2g-evm: https://pastebin.ubuntu.com/p/FgfZSwg7fY/

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From bert at biot.com  Wed Aug  4 09:41:55 2021
From: bert at biot.com (Bert Vermeulen)
Date: Wed, 4 Aug 2021 18:41:55 +0200
Subject: [PATCH 3/5] ARM: dts: Add basic support for EcoNet EN7523
In-Reply-To: <20210730144627.GB19569@C02TD0UTHF1T.local>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-4-bert@biot.com>
 <20210730144627.GB19569@C02TD0UTHF1T.local>
Message-ID: <d0ff051b-280c-4021-f4ee-7bfda5e356d3@biot.com>

On 7/30/21 4:46 PM, Mark Rutland wrote:
> On Fri, Jul 30, 2021 at 03:45:50PM +0200, Bert Vermeulen wrote:
>> +	timer {
>> +		compatible = "arm,armv8-timer";
> 
> This should be "arm,armv7-timer".
> 
>> +		interrupt-parent = <&gic>;
>> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> 
> GICv3 doesn't have a cpumask in its PPI description, so the
> GIC_CPU_MASK_SIMPLE() bits should be removed.

Ok, will fix.

>> +		clock-frequency = <25000000>;
> 
> Please have your FW configure CNTFRQ on each CPU; the clock-frequency
> property in the DT is a workaround for broken FW, and it's *vastly*
> preferable for FW to configure this correctly (e.g. as it means VMs
> should "just work").

I've since got hold of the modified U-Boot that runs on my eval board, and 
indeed it doesn't set CNTFRQ. So the kernel does need this, for the moment.

I may get a chance to upstream support for this SoC in U-Boot, but I can't 
control what people are going to ship with their board. Is it ok to leave 
this in?


-- 
Bert Vermeulen
bert at biot.com


From mikelley at microsoft.com  Wed Aug  4 09:43:00 2021
From: mikelley at microsoft.com (Michael Kelley)
Date: Wed, 4 Aug 2021 16:43:00 +0000
Subject: [PATCH v12 5/5] Drivers: hv: Enable Hyper-V code to be built on
 ARM64
In-Reply-To: <20210804164029.6xmloksmssrdsmvo@liuwe-devbox-debian-v2>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
 <1628092359-61351-6-git-send-email-mikelley@microsoft.com>
 <20210804161040.GC4857@arm.com>
 <20210804164029.6xmloksmssrdsmvo@liuwe-devbox-debian-v2>
Message-ID: <MWHPR21MB15939FD6BE722550ED25FA5CD7F19@MWHPR21MB1593.namprd21.prod.outlook.com>

From: Wei Liu <wei.liu at kernel.org> Sent: Wednesday, August 4, 2021 9:40 AM
> 
> On Wed, Aug 04, 2021 at 05:10:41PM +0100, Catalin Marinas wrote:
> > On Wed, Aug 04, 2021 at 08:52:39AM -0700, Michael Kelley wrote:
> > > Update drivers/hv/Kconfig so CONFIG_HYPERV can be selected on
> > > ARM64, causing the Hyper-V specific code to be built. Exclude the
> > > Hyper-V enlightened clocks/timers code from being built for ARM64.
> > >
> > > Signed-off-by: Michael Kelley <mikelley at microsoft.com>
> > > Reviewed-by: Boqun Feng <boqun.feng at gmail.com>
> > > Acked-by: Marc Zyngier <maz at kernel.org>
> > > Acked-by: Mark Rutland <mark.rutland at arm.com>
> > >
> > > ---
> > >  drivers/hv/Kconfig | 5 +++--
> > >  1 file changed, 3 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> > > index 66c794d..e509d5d 100644
> > > --- a/drivers/hv/Kconfig
> > > +++ b/drivers/hv/Kconfig
> > > @@ -4,7 +4,8 @@ menu "Microsoft Hyper-V guest support"
> > >
> > >  config HYPERV
> > >  	tristate "Microsoft Hyper-V client drivers"
> > > -	depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
> > > +	depends on ACPI && ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) \
> > > +		|| (ARM64 && !CPU_BIG_ENDIAN))
> > >  	select PARAVIRT
> > >  	select X86_HV_CALLBACK_VECTOR
> >
> > Does this need to be:
> >
> > 	select X86_HV_CALLBACK_VECTOR if X86
> >
> > I haven't checked whether it gives a warning on arm64 but that symbol
> > doesn't exist.

The symbol is only referenced in code under arch/x86, so there's
no warning when building for arm64.  But yes, it would be good
hygiene to add the "if X86".

Michael

> >
> > Anyway, I can fix it up locally.
> 
> I can fix it up while I queue these patches.
> 
> Wei.






From catalin.marinas at arm.com  Wed Aug  4 09:43:58 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 4 Aug 2021 17:43:58 +0100
Subject: [PATCH v12 0/5] Enable Linux guests on Hyper-V on ARM64
In-Reply-To: <MWHPR21MB159317B1D47ED60C73B47021D7F19@MWHPR21MB1593.namprd21.prod.outlook.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
 <20210804162555.GD4857@arm.com>
 <MWHPR21MB159317B1D47ED60C73B47021D7F19@MWHPR21MB1593.namprd21.prod.outlook.com>
Message-ID: <20210804164358.GE4857@arm.com>

On Wed, Aug 04, 2021 at 04:39:02PM +0000, Michael Kelley wrote:
> From: Catalin Marinas <catalin.marinas at arm.com> Sent: Wednesday, August 4, 2021 9:26 AM
> > 
> > On Wed, Aug 04, 2021 at 08:52:34AM -0700, Michael Kelley wrote:
> > > This series enables Linux guests running on Hyper-V on ARM64
> > > hardware. New ARM64-specific code in arch/arm64/hyperv initializes
> > > Hyper-V and its hypercall mechanism.  Existing architecture
> > > independent drivers for Hyper-V's VMbus and synthetic devices just
> > > work when built for ARM64. Hyper-V code is built and included in
> > > the image and modules only if CONFIG_HYPERV is enabled.
> > [...]
> > > Hyper-V on ARM64 runs with a 4 Kbyte page size, but allows guests
> > > with 4K/16K/64K page size. Linux guests with this patch series
> > > work with all three supported ARM64 page sizes.
> > >
> > > The Hyper-V vPCI driver at drivers/pci/host/pci-hyperv.c has
> > > x86/x64-specific code and is not being built for ARM64. Enabling
> > > Hyper-V vPCI devices on ARM64 is in progress via a separate set
> > > of patches.
> > >
> > > This patch set is based on the linux-next20210720 code tree.
> > 
> > Is it possible to rebase this on top of -rc3? Are there any
> > dependencies or do you plan to upstream this via a different tree?
> 
> There are dependencies on changes in the hyperv-next tree
> (https://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git/)
> which is why you are getting the build errors.  The changes
> common-ized some code between the x86 side and previous
> versions of this patch set (and fixed the #include nmi.h problem). 
> So the code would most naturally go upstream through that tree.

In that case, for this series:

Acked-by: Catalin Marinas <catalin.marinas at arm.com>

I don't think there'd be conflicts with the arm64 changes but we can
spot them early in -next.

-- 
Catalin


From bert at biot.com  Wed Aug  4 09:43:32 2021
From: bert at biot.com (Bert Vermeulen)
Date: Wed, 4 Aug 2021 18:43:32 +0200
Subject: [PATCH 4/5] ARM: Add basic support for EcoNet EN7523 SoC
In-Reply-To: <CAK8P3a3OuJ3pMSdEA4Rt3aWvvuX2+_Bg5x7-kZ1++fvvJvgGxA@mail.gmail.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-5-bert@biot.com>
 <CAK8P3a3OuJ3pMSdEA4Rt3aWvvuX2+_Bg5x7-kZ1++fvvJvgGxA@mail.gmail.com>
Message-ID: <1e3070fe-b5da-0acc-f50b-b0986a1045cd@biot.com>

On 7/30/21 4:48 PM, Arnd Bergmann wrote:
> On Fri, Jul 30, 2021 at 3:45 PM Bert Vermeulen <bert at biot.com> wrote:
>> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
>> index 173da685a52e..1bff0aa29c07 100644
>> --- a/arch/arm/Makefile
>> +++ b/arch/arm/Makefile
>> @@ -152,6 +152,7 @@ textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
>>  textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
>>  textofs-$(CONFIG_ARCH_MESON) := 0x00208000
>>  textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
>> +textofs-$(CONFIG_ARCH_ECONET) := 0x00088000
> 
> Why is this needed?
> 
> Note also the comment directly above it exlaining
> # Text offset. This list is sorted numerically by address in order to
> # provide a means to avoid/resolve conflicts in multi-arch kernels.

I didn't make that patch, but it turns out it's needed to get PSCI working; 
detection hangs without it. That makes no sense to me, but I'll examine further.


-- 
Bert Vermeulen
bert at biot.com


From wei.liu at kernel.org  Wed Aug  4 09:58:44 2021
From: wei.liu at kernel.org (Wei Liu)
Date: Wed, 4 Aug 2021 16:58:44 +0000
Subject: [PATCH v12 0/5] Enable Linux guests on Hyper-V on ARM64
In-Reply-To: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
References: <1628092359-61351-1-git-send-email-mikelley@microsoft.com>
Message-ID: <20210804165844.5ocbkmr64gzxkqdp@liuwe-devbox-debian-v2>

On Wed, Aug 04, 2021 at 08:52:34AM -0700, Michael Kelley wrote:
> 
> Michael Kelley (5):
>   arm64: hyperv: Add Hyper-V hypercall and register access utilities
>   arm64: hyperv: Add panic handler
>   arm64: hyperv: Initialize hypervisor on boot
>   arm64: efi: Export screen_info
>   Drivers: hv: Enable Hyper-V code to be built on ARM64

Applied to hyperv-next. Thanks.

Wei.


From matthias.bgg at gmail.com  Wed Aug  4 09:58:47 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 18:58:47 +0200
Subject: [v15] dt-bindings: ARM: Mediatek: Add mmsys document binding for
 MT8192
In-Reply-To: <20210802025839.16763-1-chun-jie.chen@mediatek.com>
References: <20210802025839.16763-1-chun-jie.chen@mediatek.com>
Message-ID: <aa0602cb-c4f3-53e0-7ce4-47e9eabe84ee@gmail.com>

Hi Rob,

On 02/08/2021 04:58, Chun-Jie Chen wrote:
> This patch adds the mmsys document binding for MT8192 SoC.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
> This patch is based on 5.14-rc1 and [1].
> 
> Due to mmsys binding document has been converted to YAML format in [1],
> so resend the patch in [2].
> 
> [1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=485165
> [2] https://patchwork.kernel.org/project/linux-mediatek/patch/20210726105719.15793-3-chun-jie.chen at mediatek.com/
> ---
>  .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml         | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> index 2d4ff0ce387b..f9ffa5b703a5 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> @@ -29,6 +29,7 @@ properties:
>                - mediatek,mt8167-mmsys
>                - mediatek,mt8173-mmsys
>                - mediatek,mt8183-mmsys
> +              - mediatek,mt8192-mmsys
>                - mediatek,mt8365-mmsys
>            - const: syscon
>        - items:
> 

This patch has a dependency to [1] which you merged in your tree. Would you mind
to take this one as well?

Acked-by: Matthias Brugger <matthias.bgg at gmail.com>

Thanks,
Matthias

[1]
https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-1-fparent at baylibre.com/


From matthias.bgg at gmail.com  Wed Aug  4 10:08:47 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 19:08:47 +0200
Subject: [PATCH 3/3] soc: mediatek: mmsys: add MT8365 support
In-Reply-To: <20210519161847.3747352-3-fparent@baylibre.com>
References: <20210519161847.3747352-1-fparent@baylibre.com>
 <20210519161847.3747352-3-fparent@baylibre.com>
Message-ID: <d8c0e3c6-c7bf-251a-cdb9-7ca35d1dae13@gmail.com>

Hi Fabien,

On 19/05/2021 18:18, Fabien Parent wrote:
> Add DSI mmsys connections for the MT8365 SoC.
> 
> Signed-off-by: Fabien Parent <fparent at baylibre.com>
> ---
>  drivers/soc/mediatek/mt8365-mmsys.h | 60 +++++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c    | 11 ++++++
>  2 files changed, 71 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mt8365-mmsys.h
> 
> diff --git a/drivers/soc/mediatek/mt8365-mmsys.h b/drivers/soc/mediatek/mt8365-mmsys.h
> new file mode 100644
> index 000000000000..2475aeb79791
> --- /dev/null
> +++ b/drivers/soc/mediatek/mt8365-mmsys.h
> @@ -0,0 +1,60 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __SOC_MEDIATEK_MT8365_MMSYS_H
> +#define __SOC_MEDIATEK_MT8365_MMSYS_H
> +
> +#define MT8365_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN	0xf3c
> +#define MT8365_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL	0xf4c
> +#define MT8365_DISP_REG_CONFIG_DISP_DITHER0_MOUT_EN	0xf50
> +#define MT8365_DISP_REG_CONFIG_DISP_RDMA0_SEL_IN	0xf54
> +#define MT8365_DISP_REG_CONFIG_DISP_RDMA0_RSZ0_SEL_IN	0xf60
> +#define MT8365_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN	0xf64
> +#define MT8365_DISP_REG_CONFIG_DISP_DSI0_SEL_IN		0xf68
> +
> +#define MT8365_RDMA0_SOUT_COLOR0			0x1
> +#define MT8365_DITHER_MOUT_EN_DSI0			0x1
> +#define MT8365_DSI0_SEL_IN_DITHER			0x1
> +#define MT8365_RDMA0_SEL_IN_OVL0			0x0
> +#define MT8365_RDMA0_RSZ0_SEL_IN_RDMA0			0x0
> +#define MT8365_DISP_COLOR_SEL_IN_COLOR0			0x0
> +#define MT8365_OVL0_MOUT_PATH0_SEL			BIT(0)
> +
> +static const struct mtk_mmsys_routes mt8365_mmsys_routing_table[] = {
> +	{
> +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +		MT8365_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN,
> +		MT8365_OVL0_MOUT_PATH0_SEL

I pushed this patch to v4.15-next/soc
As we now include the mask field in mtk_mmsys_routes I updated that in the patch.
Please let me know if I screwed something up.

Regards,
Matthias

> +	},
> +	{
> +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +		MT8365_DISP_REG_CONFIG_DISP_RDMA0_SEL_IN,
> +		MT8365_RDMA0_SEL_IN_OVL0
> +	},
> +	{
> +		DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
> +		MT8365_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL,
> +		MT8365_RDMA0_SOUT_COLOR0
> +	},
> +	{
> +		DDP_COMPONENT_COLOR0, DDP_COMPONENT_CCORR,
> +		MT8365_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN,
> +		MT8365_DISP_COLOR_SEL_IN_COLOR0
> +	},
> +	{
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +		MT8365_DISP_REG_CONFIG_DISP_DITHER0_MOUT_EN,
> +		MT8365_DITHER_MOUT_EN_DSI0
> +	},
> +	{
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +		MT8365_DISP_REG_CONFIG_DISP_DSI0_SEL_IN,
> +		MT8365_DSI0_SEL_IN_DITHER
> +	},
> +	{
> +		DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
> +		MT8365_DISP_REG_CONFIG_DISP_RDMA0_RSZ0_SEL_IN,
> +		MT8365_RDMA0_RSZ0_SEL_IN_RDMA0
> +	},
> +};
> +
> +#endif /* __SOC_MEDIATEK_MT8365_MMSYS_H */
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
> index 080660ef11bf..44aff822d035 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -13,6 +13,7 @@
>  #include "mtk-mmsys.h"
>  #include "mt8167-mmsys.h"
>  #include "mt8183-mmsys.h"
> +#include "mt8365-mmsys.h"
>  
>  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
>  	.clk_driver = "clk-mt2701-mm",
> @@ -52,6 +53,12 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
>  	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
>  };
>  
> +static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
> +	.clk_driver = "clk-mt8365-mm",
> +	.routes = mt8365_mmsys_routing_table,
> +	.num_routes = ARRAY_SIZE(mt8365_mmsys_routing_table),
> +};
> +
>  struct mtk_mmsys {
>  	void __iomem *regs;
>  	const struct mtk_mmsys_driver_data *data;
> @@ -157,6 +164,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
>  		.compatible = "mediatek,mt8183-mmsys",
>  		.data = &mt8183_mmsys_driver_data,
>  	},
> +	{
> +		.compatible = "mediatek,mt8365-mmsys",
> +		.data = &mt8365_mmsys_driver_data,
> +	},
>  	{ }
>  };
>  
> 


From matthias.bgg at gmail.com  Wed Aug  4 10:12:42 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 19:12:42 +0200
Subject: [PATCH v6 2/5] pwm: mtk_disp: fix force reg to working reg.
In-Reply-To: <20210724081849.182108-3-jitao.shi@mediatek.com>
References: <20210724081849.182108-1-jitao.shi@mediatek.com>
 <20210724081849.182108-3-jitao.shi@mediatek.com>
Message-ID: <925e1dcb-1f6b-1762-8342-b102d5e928e8@gmail.com>



On 24/07/2021 10:18, Jitao Shi wrote:
> Disable reg double buffer before writing register.

The commit message does not explain why you move this from probe to pwm_config.
Can you please explain exactly why you need to do that.

Regards,
Matthias

> 
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> ---
>  drivers/pwm/pwm-mtk-disp.c | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
> index 3ade525adcc3..1070d78d4940 100644
> --- a/drivers/pwm/pwm-mtk-disp.c
> +++ b/drivers/pwm/pwm-mtk-disp.c
> @@ -128,6 +128,17 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>  		mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
>  					 mdp->data->commit_mask,
>  					 0x0);
> +	} else {
> +	/*
> +	 * For MT2701, disable double buffer before writing register
> +	 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
> +	 */
> +		mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
> +					 mdp->data->bls_debug_mask,
> +					 mdp->data->bls_debug_mask);
> +		mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
> +					 mdp->data->con0_sel,
> +					 mdp->data->con0_sel);
>  	}
>  
>  	clk_disable_unprepare(mdp->clk_mm);
> @@ -213,19 +224,6 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, mdp);
>  
> -	/*
> -	 * For MT2701, disable double buffer before writing register
> -	 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
> -	 */
> -	if (!mdp->data->has_commit) {
> -		mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
> -					 mdp->data->bls_debug_mask,
> -					 mdp->data->bls_debug_mask);
> -		mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
> -					 mdp->data->con0_sel,
> -					 mdp->data->con0_sel);
> -	}
> -
>  	return 0;
>  }
>  
> 


From matthias.bgg at gmail.com  Wed Aug  4 10:15:57 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 19:15:57 +0200
Subject: [PATCH] arm: dts: mt7623: increase passive cooling trip
In-Reply-To: <20210725163451.217610-1-linux@fw-web.de>
References: <20210725163451.217610-1-linux@fw-web.de>
Message-ID: <8122ce40-ee45-ff09-cc08-ac4d6ae2bfa5@gmail.com>



On 25/07/2021 18:34, Frank Wunderlich wrote:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> MT7623/BPI-R2 has idle temperature after bootup from 48 degrees celsius
> increase the passive trip temp threshold to not trottle CPU frequency at
> this temperature
> 
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>

pushed to v5.14-next/dts32

Thanks!

> ---
>  arch/arm/boot/dts/mt7623.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
> index b7247ab082aa..11933494e03d 100644
> --- a/arch/arm/boot/dts/mt7623.dtsi
> +++ b/arch/arm/boot/dts/mt7623.dtsi
> @@ -160,7 +160,7 @@ cpu_thermal: cpu-thermal {
>  
>  				trips {
>  					cpu_passive: cpu-passive {
> -						temperature = <47000>;
> +						temperature = <57000>;
>  						hysteresis = <2000>;
>  						type = "passive";
>  					};
> 


From robin.murphy at arm.com  Wed Aug  4 10:15:28 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:28 +0100
Subject: [PATCH v3 00/25] iommu: Refactor DMA domain strictness
Message-ID: <cover.1628094600.git.robin.murphy@arm.com>

v1: https://lore.kernel.org/linux-iommu/cover.1626888444.git.robin.murphy at arm.com/
v2: https://lore.kernel.org/linux-iommu/cover.1627468308.git.robin.murphy at arm.com/

Hi all,

Round 3, and the patch count has crept up yet again. But the overall
diffstat is even more negative, so that's good, right? :)

Once again, to driver/platform maintainers CC'd on cookie cleanup
patches this is just a heads-up and the rest of the changes should not
affect your platforms. I hope I've now fixed the silly bug which broke
bisection between patches #1 and #12 on 32-bit Arm.

The new patches are in the middle, reworking how the SMMU drivers and
io-pgtable implement non-strict mode such that the later changes fall
into place even more easily. Turns out I didn't need the major
refactoring of io-pgtable that I had in mind, and I'm almost kicking
myself that as soon as I put the option of *not* using the existing
quirk on the table, an even cleaner and more logical solution was
staring right out at me.

Due to that signifcant change and the consequent redesign of the final
patch to make dynamic switching look viable in the face of concurrency,
I have not applied the tested-by tags from v2. They were very much
appreciated though, thanks!

Proper changelogs on the individual patches this time since otherwise
I'd have lost track...

Cheers,
Robin.


CC: Marek Szyprowski <m.szyprowski at samsung.com>
CC: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
CC: Geert Uytterhoeven <geert+renesas at glider.be>
CC: Yong Wu <yong.wu at mediatek.com>
CC: Heiko Stuebner <heiko at sntech.de>
CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
CC: Maxime Ripard <mripard at kernel.org>
CC: Jean-Philippe Brucker <jean-philippe at linaro.org>
CC: Sai Praneeth Prakhya <sai.praneeth.prakhya at intel.com>

Robin Murphy (25):
  iommu: Pull IOVA cookie management into the core
  iommu/amd: Drop IOVA cookie management
  iommu/arm-smmu: Drop IOVA cookie management
  iommu/vt-d: Drop IOVA cookie management
  iommu/exynos: Drop IOVA cookie management
  iommu/ipmmu-vmsa: Drop IOVA cookie management
  iommu/mtk: Drop IOVA cookie management
  iommu/rockchip: Drop IOVA cookie management
  iommu/sprd: Drop IOVA cookie management
  iommu/sun50i: Drop IOVA cookie management
  iommu/virtio: Drop IOVA cookie management
  iommu/dma: Unexport IOVA cookie management
  iommu/dma: Remove redundant "!dev" checks
  iommu: Indicate queued flushes via gather data
  iommu/io-pgtable: Remove non-strict quirk
  iommu: Introduce explicit type for non-strict DMA domains
  iommu/amd: Prepare for multiple DMA domain types
  iommu/arm-smmu: Prepare for multiple DMA domain types
  iommu/vt-d: Prepare for multiple DMA domain types
  iommu: Express DMA strictness via the domain type
  iommu: Expose DMA domain strictness via sysfs
  iommu: Only log strictness for DMA domains
  iommu: Merge strictness and domain type configs
  iommu/dma: Factor out flush queue init
  iommu: Allow enabling non-strict mode dynamically

 .../ABI/testing/sysfs-kernel-iommu_groups     |  6 +-
 .../admin-guide/kernel-parameters.txt         |  8 +-
 drivers/iommu/Kconfig                         | 80 +++++++++----------
 drivers/iommu/amd/iommu.c                     | 22 +----
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 11 +--
 rivers/iommu/arm/arm-smmu/arm-smmu.c         | 19 ++---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c       |  9 ---
 drivers/iommu/dma-iommu.c                     | 63 +++++++++------
 drivers/iommu/exynos-iommu.c                  | 19 +----
 drivers/iommu/intel/iommu.c                   | 23 ++----
 drivers/iommu/io-pgtable-arm-v7s.c            | 12 +--
 drivers/iommu/io-pgtable-arm.c                | 12 +--
 drivers/iommu/iommu.c                         | 55 ++++++++-----
 drivers/iommu/iova.c                          | 12 ++-
 drivers/iommu/ipmmu-vmsa.c                    | 28 +------
 drivers/iommu/mtk_iommu.c                     |  7 --
 drivers/iommu/mtk_iommu_v1.c                  |  1 -
 drivers/iommu/rockchip-iommu.c                | 12 +--
 drivers/iommu/sprd-iommu.c                    |  7 --
 drivers/iommu/sun50i-iommu.c                  | 13 +--
 drivers/iommu/virtio-iommu.c                  |  8 --
 include/linux/dma-iommu.h                     |  9 ++-
 include/linux/io-pgtable.h                    |  5 --
 include/linux/iommu.h                         | 23 +++++-
 24 files changed, 187 insertions(+), 277 deletions(-)

-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:29 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:29 +0100
Subject: [PATCH v3 01/25] iommu: Pull IOVA cookie management into the core
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <46f4cda8215bd5f8a9f9fd5a4a6451805f75efa3.1628094600.git.robin.murphy@arm.com>

Now that everyone has converged on iommu-dma for IOMMU_DOMAIN_DMA
support, we can abandon the notion of drivers being responsible for the
cookie type, and consolidate all the management into the core code.

CC: Marek Szyprowski <m.szyprowski at samsung.com>
CC: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
CC: Geert Uytterhoeven <geert+renesas at glider.be>
CC: Yong Wu <yong.wu at mediatek.com>
CC: Heiko Stuebner <heiko at sntech.de>
CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
CC: Maxime Ripard <mripard at kernel.org>
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Use a simpler temporary check instead of trying to be clever with
    the error code
---
 drivers/iommu/iommu.c | 7 +++++++
 include/linux/iommu.h | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index f2cda9950bd5..b65fcc66ffa4 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -7,6 +7,7 @@
 #define pr_fmt(fmt)    "iommu: " fmt
 
 #include <linux/device.h>
+#include <linux/dma-iommu.h>
 #include <linux/kernel.h>
 #include <linux/bits.h>
 #include <linux/bug.h>
@@ -1946,6 +1947,11 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
 
+	/* Temporarily avoid -EEXIST while drivers still get their own cookies */
+	if (type == IOMMU_DOMAIN_DMA && !domain->iova_cookie && iommu_get_dma_cookie(domain)) {
+		iommu_domain_free(domain);
+		domain = NULL;
+	}
 	return domain;
 }
 
@@ -1957,6 +1963,7 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
 
 void iommu_domain_free(struct iommu_domain *domain)
 {
+	iommu_put_dma_cookie(domain);
 	domain->ops->domain_free(domain);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_free);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 4997c78e2670..141779d76035 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -40,6 +40,7 @@ struct iommu_domain;
 struct notifier_block;
 struct iommu_sva;
 struct iommu_fault_event;
+struct iommu_dma_cookie;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ	0x0
@@ -86,7 +87,7 @@ struct iommu_domain {
 	iommu_fault_handler_t handler;
 	void *handler_token;
 	struct iommu_domain_geometry geometry;
-	void *iova_cookie;
+	struct iommu_dma_cookie *iova_cookie;
 };
 
 enum iommu_cap {
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:30 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:30 +0100
Subject: [PATCH v3 02/25] iommu/amd: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <ebc82f082d5fde58557efbec66f34b1be6a12599.1628094600.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/amd/iommu.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 52fe2326042a..92f7cbe3d14a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -20,7 +20,6 @@
 #include <linux/scatterlist.h>
 #include <linux/dma-map-ops.h>
 #include <linux/dma-direct.h>
-#include <linux/dma-iommu.h>
 #include <linux/iommu-helper.h>
 #include <linux/delay.h>
 #include <linux/amd-iommu.h>
@@ -1918,16 +1917,7 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
 	domain->domain.geometry.aperture_end   = ~0ULL;
 	domain->domain.geometry.force_aperture = true;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&domain->domain) == -ENOMEM)
-		goto free_domain;
-
 	return &domain->domain;
-
-free_domain:
-	protection_domain_free(domain);
-
-	return NULL;
 }
 
 static void amd_iommu_domain_free(struct iommu_domain *dom)
@@ -1944,9 +1934,6 @@ static void amd_iommu_domain_free(struct iommu_domain *dom)
 	if (!dom)
 		return;
 
-	if (dom->type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&domain->domain);
-
 	if (domain->flags & PD_IOMMUV2_MASK)
 		free_gcr3_table(domain);
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:31 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:31 +0100
Subject: [PATCH v3 03/25] iommu/arm-smmu: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <73f9b2dc5666f145bd912a330c5785dbbe3734a7.1628094600.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  7 -------
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 15 ++++-----------
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |  9 ---------
 3 files changed, 4 insertions(+), 27 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 6346f21726f4..4c648da447bf 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1984,12 +1984,6 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 	if (!smmu_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&smmu_domain->domain)) {
-		kfree(smmu_domain);
-		return NULL;
-	}
-
 	mutex_init(&smmu_domain->init_mutex);
 	INIT_LIST_HEAD(&smmu_domain->devices);
 	spin_lock_init(&smmu_domain->devices_lock);
@@ -2021,7 +2015,6 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-	iommu_put_dma_cookie(domain);
 	free_io_pgtable_ops(smmu_domain->pgtbl_ops);
 
 	/* Free the CD and ASID, if we allocated them */
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index ac21170fa208..970d9e4dcd69 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -868,10 +868,10 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 {
 	struct arm_smmu_domain *smmu_domain;
 
-	if (type != IOMMU_DOMAIN_UNMANAGED &&
-	    type != IOMMU_DOMAIN_DMA &&
-	    type != IOMMU_DOMAIN_IDENTITY)
-		return NULL;
+	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_IDENTITY) {
+		if (using_legacy_binding || type != IOMMU_DOMAIN_DMA)
+			return NULL;
+	}
 	/*
 	 * Allocate the domain and initialise some of its data structures.
 	 * We can't really do anything meaningful until we've added a
@@ -881,12 +881,6 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 	if (!smmu_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA && (using_legacy_binding ||
-	    iommu_get_dma_cookie(&smmu_domain->domain))) {
-		kfree(smmu_domain);
-		return NULL;
-	}
-
 	mutex_init(&smmu_domain->init_mutex);
 	spin_lock_init(&smmu_domain->cb_lock);
 
@@ -901,7 +895,6 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 	 * Free the domain resources. We assume that all devices have
 	 * already been detached.
 	 */
-	iommu_put_dma_cookie(domain);
 	arm_smmu_destroy_domain_context(domain);
 	kfree(smmu_domain);
 }
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 021cf8f65ffc..b91874cb6cf3 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -10,7 +10,6 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
@@ -335,12 +334,6 @@ static struct iommu_domain *qcom_iommu_domain_alloc(unsigned type)
 	if (!qcom_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&qcom_domain->domain)) {
-		kfree(qcom_domain);
-		return NULL;
-	}
-
 	mutex_init(&qcom_domain->init_mutex);
 	spin_lock_init(&qcom_domain->pgtbl_lock);
 
@@ -351,8 +344,6 @@ static void qcom_iommu_domain_free(struct iommu_domain *domain)
 {
 	struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
 
-	iommu_put_dma_cookie(domain);
-
 	if (qcom_domain->iommu) {
 		/*
 		 * NOTE: unmap can be called after client device is powered
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:32 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:32 +0100
Subject: [PATCH v3 04/25] iommu/vt-d: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <41521d47ef64c79f5821e1595759f6482dd30528.1628094601.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/intel/iommu.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index c12cc955389a..7e168634c433 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1979,10 +1979,6 @@ static void domain_exit(struct dmar_domain *domain)
 	/* Remove associated devices and clear attached or cached domains */
 	domain_remove_dev_info(domain);
 
-	/* destroy iovas */
-	if (domain->domain.type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&domain->domain);
-
 	if (domain->pgd) {
 		struct page *freelist;
 
@@ -4544,10 +4540,6 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 			return NULL;
 		}
 
-		if (type == IOMMU_DOMAIN_DMA &&
-		    iommu_get_dma_cookie(&dmar_domain->domain))
-			return NULL;
-
 		domain = &dmar_domain->domain;
 		domain->geometry.aperture_start = 0;
 		domain->geometry.aperture_end   =
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:33 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:33 +0100
Subject: [PATCH v3 05/25] iommu/exynos: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <fc13c3abc2939825f20ba4733ac8abb90b58528f.1628094601.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

CC: Marek Szyprowski <m.szyprowski at samsung.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/exynos-iommu.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index d0fbf1d10e18..939ffa768986 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -21,7 +21,6 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
-#include <linux/dma-iommu.h>
 
 typedef u32 sysmmu_iova_t;
 typedef u32 sysmmu_pte_t;
@@ -735,20 +734,16 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
 	/* Check if correct PTE offsets are initialized */
 	BUG_ON(PG_ENT_SHIFT < 0 || !dma_dev);
 
+	if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
 	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 	if (!domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA) {
-		if (iommu_get_dma_cookie(&domain->domain) != 0)
-			goto err_pgtable;
-	} else if (type != IOMMU_DOMAIN_UNMANAGED) {
-		goto err_pgtable;
-	}
-
 	domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
 	if (!domain->pgtable)
-		goto err_dma_cookie;
+		goto err_pgtable;
 
 	domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
 	if (!domain->lv2entcnt)
@@ -779,9 +774,6 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
 	free_pages((unsigned long)domain->lv2entcnt, 1);
 err_counter:
 	free_pages((unsigned long)domain->pgtable, 2);
-err_dma_cookie:
-	if (type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&domain->domain);
 err_pgtable:
 	kfree(domain);
 	return NULL;
@@ -809,9 +801,6 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 
-	if (iommu_domain->type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(iommu_domain);
-
 	dma_unmap_single(dma_dev, virt_to_phys(domain->pgtable), LV1TABLE_SIZE,
 			 DMA_TO_DEVICE);
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:34 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:34 +0100
Subject: [PATCH v3 06/25] iommu/ipmmu-vmsa: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <b154a2f088699b739d8c4823c458bf5fc0aac2bc.1628094601.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

CC: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
CC: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/ipmmu-vmsa.c | 28 ++++------------------------
 1 file changed, 4 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 51ea6f00db2f..d38ff29a76e8 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -8,7 +8,6 @@
 
 #include <linux/bitmap.h>
 #include <linux/delay.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/export.h>
@@ -564,10 +563,13 @@ static irqreturn_t ipmmu_irq(int irq, void *dev)
  * IOMMU Operations
  */
 
-static struct iommu_domain *__ipmmu_domain_alloc(unsigned type)
+static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
 {
 	struct ipmmu_vmsa_domain *domain;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+		return NULL;
+
 	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 	if (!domain)
 		return NULL;
@@ -577,27 +579,6 @@ static struct iommu_domain *__ipmmu_domain_alloc(unsigned type)
 	return &domain->io_domain;
 }
 
-static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
-{
-	struct iommu_domain *io_domain = NULL;
-
-	switch (type) {
-	case IOMMU_DOMAIN_UNMANAGED:
-		io_domain = __ipmmu_domain_alloc(type);
-		break;
-
-	case IOMMU_DOMAIN_DMA:
-		io_domain = __ipmmu_domain_alloc(type);
-		if (io_domain && iommu_get_dma_cookie(io_domain)) {
-			kfree(io_domain);
-			io_domain = NULL;
-		}
-		break;
-	}
-
-	return io_domain;
-}
-
 static void ipmmu_domain_free(struct iommu_domain *io_domain)
 {
 	struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
@@ -606,7 +587,6 @@ static void ipmmu_domain_free(struct iommu_domain *io_domain)
 	 * Free the domain resources. We assume that all devices have already
 	 * been detached.
 	 */
-	iommu_put_dma_cookie(io_domain);
 	ipmmu_domain_destroy_context(domain);
 	free_io_pgtable_ops(domain->iop);
 	kfree(domain);
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:35 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:35 +0100
Subject: [PATCH v3 07/25] iommu/mtk: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <7c3e480fc18018ec75363579c257ff825d0ca123.1628094601.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

CC: Yong Wu <yong.wu at mediatek.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded includes
---
 drivers/iommu/mtk_iommu.c    | 7 -------
 drivers/iommu/mtk_iommu_v1.c | 1 -
 2 files changed, 8 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6f7c69688ce2..185694eb4456 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -9,7 +9,6 @@
 #include <linux/component.h>
 #include <linux/device.h>
 #include <linux/dma-direct.h>
-#include <linux/dma-iommu.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -441,17 +440,11 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
 	if (!dom)
 		return NULL;
 
-	if (iommu_get_dma_cookie(&dom->domain)) {
-		kfree(dom);
-		return NULL;
-	}
-
 	return &dom->domain;
 }
 
 static void mtk_iommu_domain_free(struct iommu_domain *domain)
 {
-	iommu_put_dma_cookie(domain);
 	kfree(to_mtk_domain(domain));
 }
 
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 778e66f5f1aa..be22fcf988ce 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -13,7 +13,6 @@
 #include <linux/component.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
-#include <linux/dma-iommu.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:37 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:37 +0100
Subject: [PATCH v3 09/25] iommu/sprd: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <5cc86b540faeb0367df9bd6901a15974f0e31c52.1628094601.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/sprd-iommu.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index 73dfd9946312..27ac818b0354 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -8,7 +8,6 @@
 
 #include <linux/clk.h>
 #include <linux/device.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/iommu.h>
@@ -144,11 +143,6 @@ static struct iommu_domain *sprd_iommu_domain_alloc(unsigned int domain_type)
 	if (!dom)
 		return NULL;
 
-	if (iommu_get_dma_cookie(&dom->domain)) {
-		kfree(dom);
-		return NULL;
-	}
-
 	spin_lock_init(&dom->pgtlock);
 
 	dom->domain.geometry.aperture_start = 0;
@@ -161,7 +155,6 @@ static void sprd_iommu_domain_free(struct iommu_domain *domain)
 {
 	struct sprd_iommu_domain *dom = to_sprd_domain(domain);
 
-	iommu_put_dma_cookie(domain);
 	kfree(dom);
 }
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:36 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:36 +0100
Subject: [PATCH v3 08/25] iommu/rockchip: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <0d25511c58981ecd0a1f3006dc1c30a73fb7d377.1628094601.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

CC: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/rockchip-iommu.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 9febfb7f3025..5cb260820eda 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -10,7 +10,6 @@
 #include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
@@ -1074,10 +1073,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 	if (!rk_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&rk_domain->domain))
-		goto err_free_domain;
-
 	/*
 	 * rk32xx iommus use a 2 level pagetable.
 	 * Each level1 (dt) and level2 (pt) table has 1024 4-byte entries.
@@ -1085,7 +1080,7 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 	 */
 	rk_domain->dt = (u32 *)get_zeroed_page(GFP_KERNEL | GFP_DMA32);
 	if (!rk_domain->dt)
-		goto err_put_cookie;
+		goto err_free_domain;
 
 	rk_domain->dt_dma = dma_map_single(dma_dev, rk_domain->dt,
 					   SPAGE_SIZE, DMA_TO_DEVICE);
@@ -1106,9 +1101,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 
 err_free_dt:
 	free_page((unsigned long)rk_domain->dt);
-err_put_cookie:
-	if (type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&rk_domain->domain);
 err_free_domain:
 	kfree(rk_domain);
 
@@ -1137,8 +1129,6 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
 			 SPAGE_SIZE, DMA_TO_DEVICE);
 	free_page((unsigned long)rk_domain->dt);
 
-	if (domain->type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&rk_domain->domain);
 	kfree(rk_domain);
 }
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:38 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:38 +0100
Subject: [PATCH v3 10/25] iommu/sun50i: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <5b0549d9f9eb0f7fa707ecdbb5d267469c0c490b.1628094601.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

CC: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/sun50i-iommu.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index 181bb1c3437c..92997021e188 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -7,7 +7,6 @@
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dma-direction.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/errno.h>
@@ -610,14 +609,10 @@ static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
 	if (!sun50i_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&sun50i_domain->domain))
-		goto err_free_domain;
-
 	sun50i_domain->dt = (u32 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
 						    get_order(DT_SIZE));
 	if (!sun50i_domain->dt)
-		goto err_put_cookie;
+		goto err_free_domain;
 
 	refcount_set(&sun50i_domain->refcnt, 1);
 
@@ -627,10 +622,6 @@ static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
 
 	return &sun50i_domain->domain;
 
-err_put_cookie:
-	if (type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&sun50i_domain->domain);
-
 err_free_domain:
 	kfree(sun50i_domain);
 
@@ -644,8 +635,6 @@ static void sun50i_iommu_domain_free(struct iommu_domain *domain)
 	free_pages((unsigned long)sun50i_domain->dt, get_order(DT_SIZE));
 	sun50i_domain->dt = NULL;
 
-	iommu_put_dma_cookie(domain);
-
 	kfree(sun50i_domain);
 }
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:39 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:39 +0100
Subject: [PATCH v3 11/25] iommu/virtio: Drop IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <6a2b1638c014db13a64cf5ee0f23c85c2688f3c4.1628094601.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/virtio-iommu.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 6abdcab7273b..80930ce04a16 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -598,12 +598,6 @@ static struct iommu_domain *viommu_domain_alloc(unsigned type)
 	spin_lock_init(&vdomain->mappings_lock);
 	vdomain->mappings = RB_ROOT_CACHED;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&vdomain->domain)) {
-		kfree(vdomain);
-		return NULL;
-	}
-
 	return &vdomain->domain;
 }
 
@@ -643,8 +637,6 @@ static void viommu_domain_free(struct iommu_domain *domain)
 {
 	struct viommu_domain *vdomain = to_viommu_domain(domain);
 
-	iommu_put_dma_cookie(domain);
-
 	/* Free all remaining mappings (size 2^64) */
 	viommu_del_mappings(vdomain, 0, 0);
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:40 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:40 +0100
Subject: [PATCH v3 12/25] iommu/dma: Unexport IOVA cookie management
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <9c989539c8465bdb34fd2f2eb49773b0b76655dd.1628094601.git.robin.murphy@arm.com>

IOVA cookies are now got and put by core code, so we no longer need to
export these to modular drivers. The export for getting MSI cookies
stays, since VFIO can still be a module, but it was already relying on
someone else putting them, so that aspect is unaffected.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/dma-iommu.c | 7 -------
 drivers/iommu/iommu.c     | 3 +--
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 98ba927aee1a..10067fbc4309 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -98,9 +98,6 @@ static struct iommu_dma_cookie *cookie_alloc(enum iommu_dma_cookie_type type)
 /**
  * iommu_get_dma_cookie - Acquire DMA-API resources for a domain
  * @domain: IOMMU domain to prepare for DMA-API usage
- *
- * IOMMU drivers should normally call this from their domain_alloc
- * callback when domain->type == IOMMU_DOMAIN_DMA.
  */
 int iommu_get_dma_cookie(struct iommu_domain *domain)
 {
@@ -113,7 +110,6 @@ int iommu_get_dma_cookie(struct iommu_domain *domain)
 
 	return 0;
 }
-EXPORT_SYMBOL(iommu_get_dma_cookie);
 
 /**
  * iommu_get_msi_cookie - Acquire just MSI remapping resources
@@ -151,8 +147,6 @@ EXPORT_SYMBOL(iommu_get_msi_cookie);
  * iommu_put_dma_cookie - Release a domain's DMA mapping resources
  * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie() or
  *          iommu_get_msi_cookie()
- *
- * IOMMU drivers should normally call this from their domain_free callback.
  */
 void iommu_put_dma_cookie(struct iommu_domain *domain)
 {
@@ -172,7 +166,6 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
 	kfree(cookie);
 	domain->iova_cookie = NULL;
 }
-EXPORT_SYMBOL(iommu_put_dma_cookie);
 
 /**
  * iommu_dma_get_resv_regions - Reserved region driver helper
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index b65fcc66ffa4..fa8109369f74 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1947,8 +1947,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
 
-	/* Temporarily avoid -EEXIST while drivers still get their own cookies */
-	if (type == IOMMU_DOMAIN_DMA && !domain->iova_cookie && iommu_get_dma_cookie(domain)) {
+	if (type == IOMMU_DOMAIN_DMA && iommu_get_dma_cookie(domain)) {
 		iommu_domain_free(domain);
 		domain = NULL;
 	}
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:41 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:41 +0100
Subject: [PATCH v3 13/25] iommu/dma: Remove redundant "!dev" checks
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <55ee4aacd23cca8f1dee99c491447ce28095e3d1.1628094601.git.robin.murphy@arm.com>

iommu_dma_init_domain() is now only called from iommu_setup_dma_ops(),
which has already assumed dev to be non-NULL.

Reviewed-by: John Garry <john.garry at huawei.com>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/dma-iommu.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 10067fbc4309..e28396cea6eb 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -363,7 +363,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 
 	init_iova_domain(iovad, 1UL << order, base_pfn);
 
-	if (!cookie->fq_domain && (!dev || !dev_is_untrusted(dev)) &&
+	if (!cookie->fq_domain && !dev_is_untrusted(dev) &&
 	    domain->ops->flush_iotlb_all && !iommu_get_dma_strict(domain)) {
 		if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
 					  iommu_dma_entry_dtor))
@@ -372,9 +372,6 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 			cookie->fq_domain = domain;
 	}
 
-	if (!dev)
-		return 0;
-
 	return iova_reserve_iommu_regions(dev, domain);
 }
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:42 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:42 +0100
Subject: [PATCH v3 14/25] iommu: Indicate queued flushes via gather data
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <8f7cd9a8114e3b3f44231849a3b46e7c75cec25e.1628094601.git.robin.murphy@arm.com>

Since iommu_iotlb_gather exists to help drivers optimise flushing for a
given unmap request, it is also the logical place to indicate whether
the unmap is strict or not, and thus help them further optimise for
whether to expect a sync or a flush_all subsequently. As part of that,
it also seems fair to make the flush queue code take responsibility for
enforcing the really subtle ordering requirement it brings, so that we
don't need to worry about forgetting that if new drivers want to add
flush queue support, and can consolidate the existing versions.

While we're adding to the kerneldoc, also fill in some info for
@freelist which was overlooked previously.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: New
---
 drivers/iommu/dma-iommu.c | 1 +
 drivers/iommu/iova.c      | 7 +++++++
 include/linux/iommu.h     | 8 +++++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index e28396cea6eb..d63b30a7dc82 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -474,6 +474,7 @@ static void __iommu_dma_unmap(struct device *dev, dma_addr_t dma_addr,
 	dma_addr -= iova_off;
 	size = iova_align(iovad, size + iova_off);
 	iommu_iotlb_gather_init(&iotlb_gather);
+	iotlb_gather.queued = cookie->fq_domain;
 
 	unmapped = iommu_unmap_fast(domain, dma_addr, size, &iotlb_gather);
 	WARN_ON(unmapped != size);
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index b6cf5f16123b..2ad73fb2e94e 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -637,6 +637,13 @@ void queue_iova(struct iova_domain *iovad,
 	unsigned long flags;
 	unsigned idx;
 
+	/*
+	 * Order against the IOMMU driver's pagetable update from unmapping
+	 * @pte, to guarantee that iova_domain_flush() observes that if called
+	 * from a different CPU before we release the lock below.
+	 */
+	smp_wmb();
+
 	spin_lock_irqsave(&fq->lock, flags);
 
 	/*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 141779d76035..f7679f6684b1 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -161,16 +161,22 @@ enum iommu_dev_features {
  * @start: IOVA representing the start of the range to be flushed
  * @end: IOVA representing the end of the range to be flushed (inclusive)
  * @pgsize: The interval at which to perform the flush
+ * @freelist: Removed pages to free after sync
+ * @queued: Indicates that the flush will be queued
  *
  * This structure is intended to be updated by multiple calls to the
  * ->unmap() function in struct iommu_ops before eventually being passed
- * into ->iotlb_sync().
+ * into ->iotlb_sync(). Drivers can add pages to @freelist to be freed after
+ * ->iotlb_sync() or ->iotlb_flush_all() have cleared all cached references to
+ * them. @queued is set to indicate when ->iotlb_flush_all() will be called
+ * later instead of ->iotlb_sync(), so drivers may optimise accordingly.
  */
 struct iommu_iotlb_gather {
 	unsigned long		start;
 	unsigned long		end;
 	size_t			pgsize;
 	struct page		*freelist;
+	bool			queued;
 };
 
 /**
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:43 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:43 +0100
Subject: [PATCH v3 15/25] iommu/io-pgtable: Remove non-strict quirk
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <5de2e87b4aa4ce499071f2f5660b24761f9c1768.1628094601.git.robin.murphy@arm.com>

IO_PGTABLE_QUIRK_NON_STRICT was never a very comfortable fit, since it's
not a quirk of the pagetable format itself. Now that we have a more
appropriate way to convey non-strict unmaps, though, this last of the
non-quirk quirks can also go, and with the flush queue code also now
enforcing its own ordering we can have a lovely cleanup all round.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: New
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  3 ---
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  3 ---
 drivers/iommu/io-pgtable-arm-v7s.c          | 12 ++----------
 drivers/iommu/io-pgtable-arm.c              | 12 ++----------
 include/linux/io-pgtable.h                  |  5 -----
 5 files changed, 4 insertions(+), 31 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 4c648da447bf..d9c93d8d193d 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2174,9 +2174,6 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain,
 		.iommu_dev	= smmu->dev,
 	};
 
-	if (!iommu_get_dma_strict(domain))
-		pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
-
 	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
 	if (!pgtbl_ops)
 		return -ENOMEM;
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 970d9e4dcd69..a325d4769c17 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -765,9 +765,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 		.iommu_dev	= smmu->dev,
 	};
 
-	if (!iommu_get_dma_strict(domain))
-		pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
-
 	if (smmu->impl && smmu->impl->init_context) {
 		ret = smmu->impl->init_context(smmu_domain, &pgtbl_cfg, dev);
 		if (ret)
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index 5db90d7ce2ec..e84478d39705 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -700,14 +700,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
 						ARM_V7S_BLOCK_SIZE(lvl + 1));
 				ptep = iopte_deref(pte[i], lvl, data);
 				__arm_v7s_free_table(ptep, lvl + 1, data);
-			} else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
-				/*
-				 * Order the PTE update against queueing the IOVA, to
-				 * guarantee that a flush callback from a different CPU
-				 * has observed it before the TLBIALL can be issued.
-				 */
-				smp_wmb();
-			} else {
+			} else if (!gather->queued) {
 				io_pgtable_tlb_add_page(iop, gather, iova, blk_size);
 			}
 			iova += blk_size;
@@ -791,8 +784,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
 
 	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
 			    IO_PGTABLE_QUIRK_NO_PERMS |
-			    IO_PGTABLE_QUIRK_ARM_MTK_EXT |
-			    IO_PGTABLE_QUIRK_NON_STRICT))
+			    IO_PGTABLE_QUIRK_ARM_MTK_EXT))
 		return NULL;
 
 	/* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 053df4048a29..48a5bd8f571d 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -638,14 +638,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 				io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
 							  ARM_LPAE_GRANULE(data));
 				__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
-			} else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
-				/*
-				 * Order the PTE update against queueing the IOVA, to
-				 * guarantee that a flush callback from a different CPU
-				 * has observed it before the TLBIALL can be issued.
-				 */
-				smp_wmb();
-			} else {
+			} else if (!gather->queued) {
 				io_pgtable_tlb_add_page(iop, gather, iova + i * size, size);
 			}
 
@@ -825,7 +818,6 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 	bool tg1;
 
 	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
-			    IO_PGTABLE_QUIRK_NON_STRICT |
 			    IO_PGTABLE_QUIRK_ARM_TTBR1 |
 			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA))
 		return NULL;
@@ -929,7 +921,7 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 	typeof(&cfg->arm_lpae_s2_cfg.vtcr) vtcr = &cfg->arm_lpae_s2_cfg.vtcr;
 
 	/* The NS quirk doesn't apply at stage 2 */
-	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_NON_STRICT))
+	if (cfg->quirks)
 		return NULL;
 
 	data = arm_lpae_alloc_pgtable(cfg);
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index c43f3b899d2a..9ba6d9ea316e 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -73,10 +73,6 @@ struct io_pgtable_cfg {
 	 *	to support up to 35 bits PA where the bit32, bit33 and bit34 are
 	 *	encoded in the bit9, bit4 and bit5 of the PTE respectively.
 	 *
-	 * IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs
-	 *	on unmap, for DMA domains using the flush queue mechanism for
-	 *	delayed invalidation.
-	 *
 	 * IO_PGTABLE_QUIRK_ARM_TTBR1: (ARM LPAE format) Configure the table
 	 *	for use in the upper half of a split address space.
 	 *
@@ -86,7 +82,6 @@ struct io_pgtable_cfg {
 	#define IO_PGTABLE_QUIRK_ARM_NS		BIT(0)
 	#define IO_PGTABLE_QUIRK_NO_PERMS	BIT(1)
 	#define IO_PGTABLE_QUIRK_ARM_MTK_EXT	BIT(3)
-	#define IO_PGTABLE_QUIRK_NON_STRICT	BIT(4)
 	#define IO_PGTABLE_QUIRK_ARM_TTBR1	BIT(5)
 	#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA	BIT(6)
 	unsigned long			quirks;
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:44 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:44 +0100
Subject: [PATCH v3 16/25] iommu: Introduce explicit type for non-strict DMA
 domains
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <20ae6dfa288ad93dcbcdd772263c23a182817296.1628094601.git.robin.murphy@arm.com>

Promote the difference between strict and non-strict DMA domains from an
internal detail to a distinct domain feature and type, to pave the road
for exposing it through the sysfs default domain interface.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/dma-iommu.c |  2 +-
 drivers/iommu/iommu.c     |  8 ++++++--
 include/linux/iommu.h     | 11 +++++++++++
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index d63b30a7dc82..207c8febdac9 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1312,7 +1312,7 @@ void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
 	 * The IOMMU core code allocates the default DMA domain, which the
 	 * underlying IOMMU driver needs to support via the dma-iommu layer.
 	 */
-	if (domain->type == IOMMU_DOMAIN_DMA) {
+	if (iommu_is_dma_domain(domain)) {
 		if (iommu_dma_init_domain(domain, dma_base, dma_limit, dev))
 			goto out_err;
 		dev->dma_ops = &iommu_dma_ops;
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index fa8109369f74..982545234cf3 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -115,6 +115,7 @@ static const char *iommu_domain_type_str(unsigned int t)
 	case IOMMU_DOMAIN_UNMANAGED:
 		return "Unmanaged";
 	case IOMMU_DOMAIN_DMA:
+	case IOMMU_DOMAIN_DMA_FQ:
 		return "Translated";
 	default:
 		return "Unknown";
@@ -552,6 +553,9 @@ static ssize_t iommu_group_show_type(struct iommu_group *group,
 		case IOMMU_DOMAIN_DMA:
 			type = "DMA\n";
 			break;
+		case IOMMU_DOMAIN_DMA_FQ:
+			type = "DMA-FQ\n";
+			break;
 		}
 	}
 	mutex_unlock(&group->mutex);
@@ -765,7 +769,7 @@ static int iommu_create_device_direct_mappings(struct iommu_group *group,
 	unsigned long pg_size;
 	int ret = 0;
 
-	if (!domain || domain->type != IOMMU_DOMAIN_DMA)
+	if (!domain || !iommu_is_dma_domain(domain))
 		return 0;
 
 	BUG_ON(!domain->pgsize_bitmap);
@@ -1947,7 +1951,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
 
-	if (type == IOMMU_DOMAIN_DMA && iommu_get_dma_cookie(domain)) {
+	if (iommu_is_dma_domain(domain) && iommu_get_dma_cookie(domain)) {
 		iommu_domain_free(domain);
 		domain = NULL;
 	}
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index f7679f6684b1..5629ae42951f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -61,6 +61,7 @@ struct iommu_domain_geometry {
 #define __IOMMU_DOMAIN_DMA_API	(1U << 1)  /* Domain for use in DMA-API
 					      implementation              */
 #define __IOMMU_DOMAIN_PT	(1U << 2)  /* Domain is identity mapped   */
+#define __IOMMU_DOMAIN_DMA_FQ	(1U << 3)  /* DMA-API uses flush queue    */
 
 /*
  * This are the possible domain-types
@@ -73,12 +74,17 @@ struct iommu_domain_geometry {
  *	IOMMU_DOMAIN_DMA	- Internally used for DMA-API implementations.
  *				  This flag allows IOMMU drivers to implement
  *				  certain optimizations for these domains
+ *	IOMMU_DOMAIN_DMA_FQ	- As above, but definitely using batched TLB
+ *				  invalidation.
  */
 #define IOMMU_DOMAIN_BLOCKED	(0U)
 #define IOMMU_DOMAIN_IDENTITY	(__IOMMU_DOMAIN_PT)
 #define IOMMU_DOMAIN_UNMANAGED	(__IOMMU_DOMAIN_PAGING)
 #define IOMMU_DOMAIN_DMA	(__IOMMU_DOMAIN_PAGING |	\
 				 __IOMMU_DOMAIN_DMA_API)
+#define IOMMU_DOMAIN_DMA_FQ	(__IOMMU_DOMAIN_PAGING |	\
+				 __IOMMU_DOMAIN_DMA_API |	\
+				 __IOMMU_DOMAIN_DMA_FQ)
 
 struct iommu_domain {
 	unsigned type;
@@ -90,6 +96,11 @@ struct iommu_domain {
 	struct iommu_dma_cookie *iova_cookie;
 };
 
+static inline bool iommu_is_dma_domain(struct iommu_domain *domain)
+{
+	return domain->type & __IOMMU_DOMAIN_DMA_API;
+}
+
 enum iommu_cap {
 	IOMMU_CAP_CACHE_COHERENCY,	/* IOMMU can enforce cache coherent DMA
 					   transactions */
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:45 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:45 +0100
Subject: [PATCH v3 17/25] iommu/amd: Prepare for multiple DMA domain types
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <51e020d80bfc7b2dcc90f78fad93faa697644723.1628094601.git.robin.murphy@arm.com>

The DMA ops reset/setup can simply be unconditional, since
iommu-dma already knows only to touch DMA domains.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/amd/iommu.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 92f7cbe3d14a..f8cd945f1776 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1706,14 +1706,9 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev)
 
 static void amd_iommu_probe_finalize(struct device *dev)
 {
-	struct iommu_domain *domain;
-
 	/* Domains are initialized for this device - have a look what we ended up with */
-	domain = iommu_get_domain_for_dev(dev);
-	if (domain->type == IOMMU_DOMAIN_DMA)
-		iommu_setup_dma_ops(dev, 0, U64_MAX);
-	else
-		set_dma_ops(dev, NULL);
+	set_dma_ops(dev, NULL);
+	iommu_setup_dma_ops(dev, 0, U64_MAX);
 }
 
 static void amd_iommu_release_device(struct device *dev)
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:46 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:46 +0100
Subject: [PATCH v3 18/25] iommu/arm-smmu: Prepare for multiple DMA domain types
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <f1f8134b2f26eeff9fb9498551e254407be358db.1628094601.git.robin.murphy@arm.com>

In preparation for the strict vs. non-strict decision for DMA domains to
be expressed in the domain type, make sure we expose our flush queue
awareness by accepting the new domain type.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 +
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index d9c93d8d193d..883a99cb10c1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1972,6 +1972,7 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 
 	if (type != IOMMU_DOMAIN_UNMANAGED &&
 	    type != IOMMU_DOMAIN_DMA &&
+	    type != IOMMU_DOMAIN_DMA_FQ &&
 	    type != IOMMU_DOMAIN_IDENTITY)
 		return NULL;
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index a325d4769c17..1d013b1d7bb2 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -866,7 +866,8 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 	struct arm_smmu_domain *smmu_domain;
 
 	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_IDENTITY) {
-		if (using_legacy_binding || type != IOMMU_DOMAIN_DMA)
+		if (using_legacy_binding ||
+		    (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_DMA_FQ))
 			return NULL;
 	}
 	/*
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:47 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:47 +0100
Subject: [PATCH v3 19/25] iommu/vt-d: Prepare for multiple DMA domain types
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <ec4e111fe28db8232ae74e0aaf07999427f98fc7.1628094601.git.robin.murphy@arm.com>

In preparation for the strict vs. non-strict decision for DMA domains
to be expressed in the domain type, make sure we expose our flush queue
awareness by accepting the new domain type, and test the specific
feature flag where we want to identify DMA domains in general. The DMA
ops reset/setup can simply be made unconditional, since iommu-dma
already knows only to touch DMA domains.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/intel/iommu.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 7e168634c433..8fc46c9d6b96 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -582,7 +582,7 @@ struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
 	int iommu_id;
 
 	/* si_domain and vm domain should not get here. */
-	if (WARN_ON(domain->domain.type != IOMMU_DOMAIN_DMA))
+	if (WARN_ON(!iommu_is_dma_domain(&domain->domain)))
 		return NULL;
 
 	for_each_domain_iommu(iommu_id, domain)
@@ -1034,7 +1034,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
 			pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
 			if (domain_use_first_level(domain)) {
 				pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US;
-				if (domain->domain.type == IOMMU_DOMAIN_DMA)
+				if (iommu_is_dma_domain(&domain->domain))
 					pteval |= DMA_FL_PTE_ACCESS;
 			}
 			if (cmpxchg64(&pte->val, 0ULL, pteval))
@@ -2345,7 +2345,7 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
 	if (domain_use_first_level(domain)) {
 		attr |= DMA_FL_PTE_XD | DMA_FL_PTE_US;
 
-		if (domain->domain.type == IOMMU_DOMAIN_DMA) {
+		if (iommu_is_dma_domain(&domain->domain)) {
 			attr |= DMA_FL_PTE_ACCESS;
 			if (prot & DMA_PTE_WRITE)
 				attr |= DMA_FL_PTE_DIRTY;
@@ -4528,6 +4528,7 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 
 	switch (type) {
 	case IOMMU_DOMAIN_DMA:
+	case IOMMU_DOMAIN_DMA_FQ:
 	case IOMMU_DOMAIN_UNMANAGED:
 		dmar_domain = alloc_domain(0);
 		if (!dmar_domain) {
@@ -5197,12 +5198,8 @@ static void intel_iommu_release_device(struct device *dev)
 
 static void intel_iommu_probe_finalize(struct device *dev)
 {
-	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
-
-	if (domain && domain->type == IOMMU_DOMAIN_DMA)
-		iommu_setup_dma_ops(dev, 0, U64_MAX);
-	else
-		set_dma_ops(dev, NULL);
+	set_dma_ops(dev, NULL);
+	iommu_setup_dma_ops(dev, 0, U64_MAX);
 }
 
 static void intel_iommu_get_resv_regions(struct device *device,
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:48 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:48 +0100
Subject: [PATCH v3 20/25] iommu: Express DMA strictness via the domain type
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <c53e43b3922fff16de031a1f35ebbab0ff4fdc0a.1628094601.git.robin.murphy@arm.com>

Eliminate the iommu_get_dma_strict() indirection and pipe the
information through the domain type from the beginning. Besides
the flow simplification this also has several nice side-effects:

 - Automatically implies strict mode for untrusted devices by
   virtue of their IOMMU_DOMAIN_DMA override.
 - Ensures that we only end up using flush queues for drivers
   which are aware of them and can actually benefit.
 - Allows us to handle flush queue init failure by falling back
   to strict mode instead of leaving it to possibly blow up later.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Remember to update iommu_def_domain_type accordingly from
    iommu_set_dma_strict() too
---
 drivers/iommu/dma-iommu.c |  9 +++++----
 drivers/iommu/iommu.c     | 14 +++++---------
 include/linux/iommu.h     |  1 -
 3 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 207c8febdac9..2e19505dddf9 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -363,13 +363,14 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 
 	init_iova_domain(iovad, 1UL << order, base_pfn);
 
-	if (!cookie->fq_domain && !dev_is_untrusted(dev) &&
-	    domain->ops->flush_iotlb_all && !iommu_get_dma_strict(domain)) {
+	if (domain->type == IOMMU_DOMAIN_DMA_FQ && !cookie->fq_domain) {
 		if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
-					  iommu_dma_entry_dtor))
+					  iommu_dma_entry_dtor)) {
 			pr_warn("iova flush queue initialization failed\n");
-		else
+			domain->type = IOMMU_DOMAIN_DMA;
+		} else {
 			cookie->fq_domain = domain;
+		}
 	}
 
 	return iova_reserve_iommu_regions(dev, domain);
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 982545234cf3..55ca5bf3cafc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -136,6 +136,9 @@ static int __init iommu_subsys_init(void)
 		}
 	}
 
+	if (!iommu_default_passthrough() && !iommu_dma_strict)
+		iommu_def_domain_type = IOMMU_DOMAIN_DMA_FQ;
+
 	pr_info("Default domain type: %s %s\n",
 		iommu_domain_type_str(iommu_def_domain_type),
 		(iommu_cmd_line & IOMMU_CMD_LINE_DMA_API) ?
@@ -355,17 +358,10 @@ early_param("iommu.strict", iommu_dma_setup);
 void iommu_set_dma_strict(void)
 {
 	iommu_dma_strict = true;
+	if (iommu_def_domain_type == IOMMU_DOMAIN_DMA_FQ)
+		iommu_def_domain_type = IOMMU_DOMAIN_DMA;
 }
 
-bool iommu_get_dma_strict(struct iommu_domain *domain)
-{
-	/* only allow lazy flushing for DMA domains */
-	if (domain->type == IOMMU_DOMAIN_DMA)
-		return iommu_dma_strict;
-	return true;
-}
-EXPORT_SYMBOL_GPL(iommu_get_dma_strict);
-
 static ssize_t iommu_group_attr_show(struct kobject *kobj,
 				     struct attribute *__attr, char *buf)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5629ae42951f..923a8d1c5e39 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -504,7 +504,6 @@ int iommu_set_pgtable_quirks(struct iommu_domain *domain,
 		unsigned long quirks);
 
 void iommu_set_dma_strict(void);
-bool iommu_get_dma_strict(struct iommu_domain *domain);
 
 extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev,
 			      unsigned long iova, int flags);
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:49 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:49 +0100
Subject: [PATCH v3 21/25] iommu: Expose DMA domain strictness via sysfs
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <fca07df20f45952ff5c19b744fc87be777259594.1628094601.git.robin.murphy@arm.com>

The sysfs interface for default domain types exists primarily so users
can choose the performance/security tradeoff relevant to their own
workload. As such, the choice between the policies for DMA domains fits
perfectly as an additional point on that scale - downgrading a
particular device from a strict default to non-strict may be enough to
let it reach the desired level of performance, while still retaining
more peace of mind than with a wide-open identity domain. Now that we've
abstracted non-strict mode as a distinct type of DMA domain, allow it to
be chosen through the user interface as well.

CC: Sai Praneeth Prakhya <sai.praneeth.prakhya at intel.com>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: John Garry <john.garry at huawei.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Summarise the implications in the documentation for completeness
---
 Documentation/ABI/testing/sysfs-kernel-iommu_groups | 6 +++++-
 drivers/iommu/iommu.c                               | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-kernel-iommu_groups b/Documentation/ABI/testing/sysfs-kernel-iommu_groups
index eae2f1c1e11e..b15af6a5bc08 100644
--- a/Documentation/ABI/testing/sysfs-kernel-iommu_groups
+++ b/Documentation/ABI/testing/sysfs-kernel-iommu_groups
@@ -42,8 +42,12 @@ Description:	/sys/kernel/iommu_groups/<grp_id>/type shows the type of default
 		========  ======================================================
 		DMA       All the DMA transactions from the device in this group
 		          are translated by the iommu.
+		DMA-FQ    As above, but using batched invalidation to lazily
+		          remove translations after use. This may offer reduced
+			  overhead at the cost of reduced memory protection.
 		identity  All the DMA transactions from the device in this group
-		          are not translated by the iommu.
+		          are not translated by the iommu. Maximum performance
+			  but zero protection.
 		auto      Change to the type the device was booted with.
 		========  ======================================================
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 55ca5bf3cafc..b141161d5bbc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3267,6 +3267,8 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
 		req_type = IOMMU_DOMAIN_IDENTITY;
 	else if (sysfs_streq(buf, "DMA"))
 		req_type = IOMMU_DOMAIN_DMA;
+	else if (sysfs_streq(buf, "DMA-FQ"))
+		req_type = IOMMU_DOMAIN_DMA_FQ;
 	else if (sysfs_streq(buf, "auto"))
 		req_type = 0;
 	else
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:50 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:50 +0100
Subject: [PATCH v3 22/25] iommu: Only log strictness for DMA domains
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <8cd363849974d02f8372b86dec5c39cc42b66c34.1628094601.git.robin.murphy@arm.com>

When passthrough is enabled, the default strictness policy becomes
irrelevant, since any subsequent runtime override to a DMA domain type
now embodies an explicit choice of strictness as well. Save on noise by
only logging the default policy when it is meaningfully in effect.

Reviewed-by: John Garry <john.garry at huawei.com>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/iommu.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index b141161d5bbc..63face36fc49 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -144,10 +144,11 @@ static int __init iommu_subsys_init(void)
 		(iommu_cmd_line & IOMMU_CMD_LINE_DMA_API) ?
 			"(set via kernel command line)" : "");
 
-	pr_info("DMA domain TLB invalidation policy: %s mode %s\n",
-		iommu_dma_strict ? "strict" : "lazy",
-		(iommu_cmd_line & IOMMU_CMD_LINE_STRICT) ?
-			"(set via kernel command line)" : "");
+	if (!iommu_default_passthrough())
+		pr_info("DMA domain TLB invalidation policy: %s mode %s\n",
+			iommu_dma_strict ? "strict" : "lazy",
+			(iommu_cmd_line & IOMMU_CMD_LINE_STRICT) ?
+				"(set via kernel command line)" : "");
 
 	return 0;
 }
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:51 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:51 +0100
Subject: [PATCH v3 23/25] iommu: Merge strictness and domain type configs
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <18f2757675b1a4d74d052b2b211e512ebf6e465e.1628094601.git.robin.murphy@arm.com>

To parallel the sysfs behaviour, merge the new build-time option
for DMA domain strictness into the default domain type choice.

Suggested-by: Joerg Roedel <joro at 8bytes.org>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Remember to update parameter documentation as well
---
 .../admin-guide/kernel-parameters.txt         |  8 +-
 drivers/iommu/Kconfig                         | 80 +++++++++----------
 drivers/iommu/iommu.c                         |  2 +-
 3 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 90b525cf0ec2..19192b39952a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2045,11 +2045,9 @@
 			1 - Strict mode.
 			  DMA unmap operations invalidate IOMMU hardware TLBs
 			  synchronously.
-			unset - Use value of CONFIG_IOMMU_DEFAULT_{LAZY,STRICT}.
-			Note: on x86, the default behaviour depends on the
-			equivalent driver-specific parameters, but a strict
-			mode explicitly specified by either method takes
-			precedence.
+			unset - Use value of CONFIG_IOMMU_DEFAULT_DMA_{LAZY,STRICT}.
+			Note: on x86, strict mode specified via one of the
+			legacy driver-specific options takes precedence.
 
 	iommu.passthrough=
 			[ARM64, X86] Configure DMA to bypass the IOMMU by default.
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c84da8205be7..6e06f876d75a 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -79,55 +79,55 @@ config IOMMU_DEBUGFS
 	  debug/iommu directory, and then populate a subdirectory with
 	  entries as required.
 
-config IOMMU_DEFAULT_PASSTHROUGH
-	bool "IOMMU passthrough by default"
-	depends on IOMMU_API
-	help
-	  Enable passthrough by default, removing the need to pass in
-	  iommu.passthrough=on or iommu=pt through command line. If this
-	  is enabled, you can still disable with iommu.passthrough=off
-	  or iommu=nopt depending on the architecture.
-
-	  If unsure, say N here.
-
 choice
-	prompt "IOMMU default DMA IOTLB invalidation mode"
-	depends on IOMMU_DMA
-
-	default IOMMU_DEFAULT_LAZY if (AMD_IOMMU || INTEL_IOMMU)
-	default IOMMU_DEFAULT_STRICT
+	prompt "IOMMU default domain type"
+	depends on IOMMU_API
+	default IOMMU_DEFAULT_DMA_LAZY if AMD_IOMMU || INTEL_IOMMU
+	default IOMMU_DEFAULT_DMA_STRICT
 	help
-	  This option allows an IOMMU DMA IOTLB invalidation mode to be
-	  chosen at build time, to override the default mode of each ARCH,
-	  removing the need to pass in kernel parameters through command line.
-	  It is still possible to provide common boot params to override this
-	  config.
+	  Choose the type of IOMMU domain used to manage DMA API usage by
+	  device drivers. The options here typically represent different
+	  levels of tradeoff between robustness/security and performance,
+	  depending on the IOMMU driver. Not all IOMMUs support all options.
+	  This choice can be overridden at boot via the command line, and for
+	  some devices also at runtime via sysfs.
 
 	  If unsure, keep the default.
 
-config IOMMU_DEFAULT_STRICT
-	bool "strict"
+config IOMMU_DEFAULT_DMA_STRICT
+	bool "Translated - Strict"
 	help
-	  For every IOMMU DMA unmap operation, the flush operation of IOTLB and
-	  the free operation of IOVA are guaranteed to be done in the unmap
-	  function.
+	  Trusted devices use translation to restrict their access to only
+	  DMA-mapped pages, with strict TLB invalidation on unmap. Equivalent
+	  to passing "iommu.passthrough=0 iommu.strict=1" on the command line.
 
-config IOMMU_DEFAULT_LAZY
-	bool "lazy"
+	  Untrusted devices always use this mode, with an additional layer of
+	  bounce-buffering such that they cannot gain access to any unrelated
+	  data within a mapped page.
+
+config IOMMU_DEFAULT_DMA_LAZY
+	bool "Translated - Lazy"
 	help
-	  Support lazy mode, where for every IOMMU DMA unmap operation, the
-	  flush operation of IOTLB and the free operation of IOVA are deferred.
-	  They are only guaranteed to be done before the related IOVA will be
-	  reused.
+	  Trusted devices use translation to restrict their access to only
+	  DMA-mapped pages, but with "lazy" batched TLB invalidation. This
+	  mode allows higher performance with some IOMMUs due to reduced TLB
+	  flushing, but at the cost of reduced isolation since devices may be
+	  able to access memory for some time after it has been unmapped.
+	  Equivalent to passing "iommu.passthrough=0 iommu.strict=0" on the
+	  command line.
 
-	  The isolation provided in this mode is not as secure as STRICT mode,
-	  such that a vulnerable time window may be created between the DMA
-	  unmap and the mappings cached in the IOMMU IOTLB or device TLB
-	  finally being invalidated, where the device could still access the
-	  memory which has already been unmapped by the device driver.
-	  However this mode may provide better performance in high throughput
-	  scenarios, and is still considerably more secure than passthrough
-	  mode or no IOMMU.
+	  If this mode is not supported by the IOMMU driver, the effective
+	  runtime default will fall back to IOMMU_DEFAULT_DMA_STRICT.
+
+config IOMMU_DEFAULT_PASSTHROUGH
+	bool "Passthrough"
+	help
+	  Trusted devices are identity-mapped, giving them unrestricted access
+	  to memory with minimal performance overhead. Equivalent to passing
+	  "iommu.passthrough=1" (historically "iommu=pt") on the command line.
+
+	  If this mode is not supported by the IOMMU driver, the effective
+	  runtime default will fall back to IOMMU_DEFAULT_DMA_STRICT.
 
 endchoice
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 63face36fc49..480ad6a538a9 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -31,7 +31,7 @@ static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 
 static unsigned int iommu_def_domain_type __read_mostly;
-static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_STRICT);
+static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);
 static u32 iommu_cmd_line __read_mostly;
 
 struct iommu_group {
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:52 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:52 +0100
Subject: [PATCH v3 24/25] iommu/dma: Factor out flush queue init
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <3b5284ee394f267ba966839173f874fc9a996bb2.1628094601.git.robin.murphy@arm.com>

Factor out flush queue setup from the initial domain init so that we
can potentially trigger it from sysfs later on in a domain's lifetime.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: John Garry <john.garry at huawei.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/dma-iommu.c | 30 ++++++++++++++++++++----------
 include/linux/dma-iommu.h |  9 ++++++---
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 2e19505dddf9..f51b8dc99ac6 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -310,6 +310,25 @@ static bool dev_is_untrusted(struct device *dev)
 	return dev_is_pci(dev) && to_pci_dev(dev)->untrusted;
 }
 
+int iommu_dma_init_fq(struct iommu_domain *domain)
+{
+	struct iommu_dma_cookie *cookie = domain->iova_cookie;
+
+	if (domain->type != IOMMU_DOMAIN_DMA_FQ)
+		return -EINVAL;
+	if (cookie->fq_domain)
+		return 0;
+
+	if (init_iova_flush_queue(&cookie->iovad, iommu_dma_flush_iotlb_all,
+				  iommu_dma_entry_dtor)) {
+		pr_warn("iova flush queue initialization failed\n");
+		domain->type = IOMMU_DOMAIN_DMA;
+		return -ENODEV;
+	}
+	cookie->fq_domain = domain;
+	return 0;
+}
+
 /**
  * iommu_dma_init_domain - Initialise a DMA mapping domain
  * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()
@@ -362,16 +381,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 	}
 
 	init_iova_domain(iovad, 1UL << order, base_pfn);
-
-	if (domain->type == IOMMU_DOMAIN_DMA_FQ && !cookie->fq_domain) {
-		if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
-					  iommu_dma_entry_dtor)) {
-			pr_warn("iova flush queue initialization failed\n");
-			domain->type = IOMMU_DOMAIN_DMA;
-		} else {
-			cookie->fq_domain = domain;
-		}
-	}
+	iommu_dma_init_fq(domain);
 
 	return iova_reserve_iommu_regions(dev, domain);
 }
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 758ca4694257..81ab647f1618 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -20,6 +20,7 @@ void iommu_put_dma_cookie(struct iommu_domain *domain);
 
 /* Setup call for arch DMA mapping code */
 void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit);
+int iommu_dma_init_fq(struct iommu_domain *domain);
 
 /* The DMA API isn't _quite_ the whole story, though... */
 /*
@@ -37,9 +38,6 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc,
 
 void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
 
-void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
-		struct iommu_domain *domain);
-
 extern bool iommu_dma_forcedac;
 
 #else /* CONFIG_IOMMU_DMA */
@@ -54,6 +52,11 @@ static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base,
 {
 }
 
+static inline int iommu_dma_init_fq(struct iommu_domain *domain)
+{
+	return -EINVAL;
+}
+
 static inline int iommu_get_dma_cookie(struct iommu_domain *domain)
 {
 	return -ENODEV;
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug  4 10:15:53 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed,  4 Aug 2021 18:15:53 +0100
Subject: [PATCH v3 25/25] iommu: Allow enabling non-strict mode dynamically
In-Reply-To: <cover.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
Message-ID: <22b044263f69e2bfe404c4379a435005ea58b3e2.1628094601.git.robin.murphy@arm.com>

Allocating and enabling a flush queue is in fact something we can
reasonably do while a DMA domain is active, without having to rebuild it
from scratch. Thus we can allow a strict -> non-strict transition from
sysfs without requiring to unbind the device's driver, which is of
particular interest to users who want to make selective relaxations to
critical devices like the one serving their root filesystem.

Disabling and draining a queue also seems technically possible to
achieve without rebuilding the whole domain, but would certainly be more
involved. Furthermore there's not such a clear use-case for tightening
up security *after* the device may already have done whatever it is that
you don't trust it not to do, so we only consider the relaxation case.

CC: Sai Praneeth Prakhya <sai.praneeth.prakhya at intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Actually think about concurrency, rework most of the fq data
    accesses to be (hopefully) safe and comment it all
---
 drivers/iommu/dma-iommu.c | 25 ++++++++++++++++++-------
 drivers/iommu/iommu.c     | 16 ++++++++++++----
 drivers/iommu/iova.c      |  9 ++++++---
 3 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index f51b8dc99ac6..6b04dc765d91 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -310,6 +310,12 @@ static bool dev_is_untrusted(struct device *dev)
 	return dev_is_pci(dev) && to_pci_dev(dev)->untrusted;
 }
 
+/*
+ * Protected from concurrent sysfs updates by the mutex of the group who owns
+ * this domain. At worst it might theoretically be able to allocate two queues
+ * and leak one if you poke sysfs to race just right with iommu_setup_dma_ops()
+ * running for the first device in the group. Don't do that.
+ */
 int iommu_dma_init_fq(struct iommu_domain *domain)
 {
 	struct iommu_dma_cookie *cookie = domain->iova_cookie;
@@ -325,7 +331,12 @@ int iommu_dma_init_fq(struct iommu_domain *domain)
 		domain->type = IOMMU_DOMAIN_DMA;
 		return -ENODEV;
 	}
-	cookie->fq_domain = domain;
+	/*
+	 * Prevent incomplete iovad->fq being observable. Pairs with path from
+	 * __iommu_dma_unmap() through iommu_dma_free_iova() to queue_iova()
+	 */
+	smp_wmb();
+	WRITE_ONCE(cookie->fq_domain, domain);
 	return 0;
 }
 
@@ -456,17 +467,17 @@ static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain,
 }
 
 static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie,
-		dma_addr_t iova, size_t size, struct page *freelist)
+		dma_addr_t iova, size_t size, struct iommu_iotlb_gather *gather)
 {
 	struct iova_domain *iovad = &cookie->iovad;
 
 	/* The MSI case is only ever cleaning up its most recent allocation */
 	if (cookie->type == IOMMU_DMA_MSI_COOKIE)
 		cookie->msi_iova -= size;
-	else if (cookie->fq_domain)	/* non-strict mode */
+	else if (gather && gather->queued)
 		queue_iova(iovad, iova_pfn(iovad, iova),
 				size >> iova_shift(iovad),
-				(unsigned long)freelist);
+				(unsigned long)gather->freelist);
 	else
 		free_iova_fast(iovad, iova_pfn(iovad, iova),
 				size >> iova_shift(iovad));
@@ -485,14 +496,14 @@ static void __iommu_dma_unmap(struct device *dev, dma_addr_t dma_addr,
 	dma_addr -= iova_off;
 	size = iova_align(iovad, size + iova_off);
 	iommu_iotlb_gather_init(&iotlb_gather);
-	iotlb_gather.queued = cookie->fq_domain;
+	iotlb_gather.queued = READ_ONCE(cookie->fq_domain);
 
 	unmapped = iommu_unmap_fast(domain, dma_addr, size, &iotlb_gather);
 	WARN_ON(unmapped != size);
 
-	if (!cookie->fq_domain)
+	if (!iotlb_gather.queued)
 		iommu_iotlb_sync(domain, &iotlb_gather);
-	iommu_dma_free_iova(cookie, dma_addr, size, iotlb_gather.freelist);
+	iommu_dma_free_iova(cookie, dma_addr, size, &iotlb_gather);
 }
 
 static void __iommu_dma_unmap_swiotlb(struct device *dev, dma_addr_t dma_addr,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 480ad6a538a9..593d4555bc57 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3203,6 +3203,13 @@ static int iommu_change_dev_def_domain(struct iommu_group *group,
 		goto out;
 	}
 
+	/* We can bring up a flush queue without tearing down the domain */
+	if (type == IOMMU_DOMAIN_DMA_FQ && prev_dom->type == IOMMU_DOMAIN_DMA) {
+		prev_dom->type = IOMMU_DOMAIN_DMA_FQ;
+		ret = iommu_dma_init_fq(prev_dom);
+		goto out;
+	}
+
 	/* Sets group->default_domain to the newly allocated domain */
 	ret = iommu_group_alloc_default_domain(dev->bus, group, type);
 	if (ret)
@@ -3243,9 +3250,9 @@ static int iommu_change_dev_def_domain(struct iommu_group *group,
 }
 
 /*
- * Changing the default domain through sysfs requires the users to ubind the
- * drivers from the devices in the iommu group. Return failure if this doesn't
- * meet.
+ * Changing the default domain through sysfs requires the users to unbind the
+ * drivers from the devices in the iommu group, except for a DMA -> DMA-FQ
+ * transition. Return failure if this isn't met.
  *
  * We need to consider the race between this and the device release path.
  * device_lock(dev) is used here to guarantee that the device release path
@@ -3321,7 +3328,8 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
 
 	/* Check if the device in the group still has a driver bound to it */
 	device_lock(dev);
-	if (device_is_bound(dev)) {
+	if (device_is_bound(dev) && !(req_type == IOMMU_DOMAIN_DMA_FQ &&
+	    group->default_domain->type == IOMMU_DOMAIN_DMA)) {
 		pr_err_ratelimited("Device is still bound to driver\n");
 		ret = -EBUSY;
 		goto out;
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index 2ad73fb2e94e..547b6243de9b 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -633,17 +633,20 @@ void queue_iova(struct iova_domain *iovad,
 		unsigned long pfn, unsigned long pages,
 		unsigned long data)
 {
-	struct iova_fq *fq = raw_cpu_ptr(iovad->fq);
+	struct iova_fq *fq;
 	unsigned long flags;
 	unsigned idx;
 
 	/*
 	 * Order against the IOMMU driver's pagetable update from unmapping
 	 * @pte, to guarantee that iova_domain_flush() observes that if called
-	 * from a different CPU before we release the lock below.
+	 * from a different CPU before we release the lock below. Full barrier
+	 * so it also pairs with iommu_dma_init_fq() to avoid seeing partially
+	 * written fq state here.
 	 */
-	smp_wmb();
+	smp_mb();
 
+	fq = raw_cpu_ptr(iovad->fq);
 	spin_lock_irqsave(&fq->lock, flags);
 
 	/*
-- 
2.25.1



From matthias.bgg at gmail.com  Wed Aug  4 10:17:08 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 19:17:08 +0200
Subject: [PATCH v3 RESEND 1/2] arm64: dts: mt8183: add mediatek, gce-events
 in mutex
In-Reply-To: <CAJMQK-hiDDH1ypoDcQYEQZ0Vq3X-mTfZbF7qfRbGtD2zBH=oxw@mail.gmail.com>
References: <20210622030741.2120393-1-hsinyi@chromium.org>
 <CAJMQK-hiDDH1ypoDcQYEQZ0Vq3X-mTfZbF7qfRbGtD2zBH=oxw@mail.gmail.com>
Message-ID: <6d7cd8ec-8a88-81bf-b4ff-60335b8b70bc@gmail.com>



On 26/07/2021 12:27, Hsin-Yi Wang wrote:
> On Tue, Jun 22, 2021 at 11:07 AM Hsin-Yi Wang <hsinyi at chromium.org> wrote:
>>
>> mediatek,gce-events is read by mutex node.
>>
>> Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
>> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> 
> Gentle ping on this series. thanks
> 

Both are pushed to v5.14-next/dts64 now. Sorry for the delay.

Matthias

>> ---
>>  arch/arm64/boot/dts/mediatek/mt8183.dtsi | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
>> index c5e822b6b77a3..cf22d71161e58 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
>> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
>> @@ -1250,6 +1250,8 @@ mutex: mutex at 14016000 {
>>                         reg = <0 0x14016000 0 0x1000>;
>>                         interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_LOW>;
>>                         power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
>> +                       mediatek,gce-events = <CMDQ_EVENT_MUTEX_STREAM_DONE0>,
>> +                                             <CMDQ_EVENT_MUTEX_STREAM_DONE1>;
>>                 };
>>
>>                 larb0: larb at 14017000 {
>> --
>> 2.32.0.288.g62a8d224e6-goog
>>


From matthias.bgg at gmail.com  Wed Aug  4 10:19:38 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 4 Aug 2021 19:19:38 +0200
Subject: [PATCH v4 1/2] arm64: dts: mt8183: kukui: Use aliases to mmc nodes
In-Reply-To: <CAGXv+5EVcSyfG1Fk6PZOnWUZo85brf_cneW7iob4Z5gnjFca7Q@mail.gmail.com>
References: <20210728040710.2891955-1-hsinyi@chromium.org>
 <CAGXv+5EVcSyfG1Fk6PZOnWUZo85brf_cneW7iob4Z5gnjFca7Q@mail.gmail.com>
Message-ID: <fb0d8da4-6d0f-b10b-a207-af234d47b171@gmail.com>



On 29/07/2021 11:58, Chen-Yu Tsai wrote:
> On Wed, Jul 28, 2021 at 12:07 PM Hsin-Yi Wang <hsinyi at chromium.org> wrote:
>>
>> With commit 1796164fac7e ("dt-bindings: mmc: document alias support"),
>> a way to specify fixed index numbers was provided. This patch use aliases
>> to mmc nodes so the partition name for eMMC and SD card will be consistent
>> across boots.
>>
>> Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
>> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
>> Tested-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
>> ---
>> v3->v4: change commit message based on review in v3.
> 
> Thanks for following up. My reviewed-by is still valid for both patches.
> 

Sorry for the confusion on this series. I now took this version into
v5.14-next/dts64

Thanks


From linux at roeck-us.net  Wed Aug  4 10:33:35 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 4 Aug 2021 10:33:35 -0700
Subject: [PATCH v2 13/15] hwmon: peci: Add dimmtemp driver
In-Reply-To: <a576f7075625a476c613b5feb2c4c7033d6c0375.camel@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-14-iwona.winiarska@intel.com>
 <20210803153937.GA337938@roeck-us.net>
 <a576f7075625a476c613b5feb2c4c7033d6c0375.camel@intel.com>
Message-ID: <ff8f8b20-33af-08a0-6036-03429bf69730@roeck-us.net>

On 8/4/21 3:46 AM, Winiarska, Iwona wrote:
> On Tue, 2021-08-03 at 08:39 -0700, Guenter Roeck wrote:
>> On Tue, Aug 03, 2021 at 01:31:32PM +0200, Iwona Winiarska wrote:
>>> Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that
>>> are accessible via the processor PECI interface.
>>>
>>> The main use case for the driver (and PECI interface) is out-of-band
>>> management, where we're able to obtain thermal readings from an external
>>> entity connected with PECI, e.g. BMC on server platforms.
>>>
>>> Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>>> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
>>> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
>>> ---
>>> Note that the timeout was completely removed - we're going to probe
>>> for detected DIMMs every 5 seconds until we reach "stable" state of
>>> either getting correct DIMM data or getting all -EINVAL (which
>>> suggest that the CPU doesn't have any DIMMs).
>>>
>>>  ?drivers/hwmon/peci/Kconfig??? |? 13 +
>>>  ?drivers/hwmon/peci/Makefile?? |?? 2 +
>>>  ?drivers/hwmon/peci/dimmtemp.c | 614 ++++++++++++++++++++++++++++++++++
>>>  ?3 files changed, 629 insertions(+)
>>>  ?create mode 100644 drivers/hwmon/peci/dimmtemp.c
>>>
>>> diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
>>> index e10eed68d70a..9d32a57badfe 100644
>>> --- a/drivers/hwmon/peci/Kconfig
>>> +++ b/drivers/hwmon/peci/Kconfig
>>> @@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP
>>>  ????????? This driver can also be built as a module. If so, the module
>>>  ????????? will be called peci-cputemp.
>>>   
>>> +config SENSORS_PECI_DIMMTEMP
>>> +???????tristate "PECI DIMM temperature monitoring client"
>>> +???????depends on PECI
>>> +???????select SENSORS_PECI
>>> +???????select PECI_CPU
>>> +???????help
>>> +???????? If you say yes here you get support for the generic Intel PECI
>>> hwmon
>>> +???????? driver which provides Temperature Sensor on DIMM readings that are
>>> +???????? accessible via the processor PECI interface.
>>> +
>>> +???????? This driver can also be built as a module. If so, the module
>>> +???????? will be called peci-dimmtemp.
>>> +
>>>  ?config SENSORS_PECI
>>>  ????????tristate
>>> diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
>>> index e8a0ada5ab1f..191cfa0227f3 100644
>>> --- a/drivers/hwmon/peci/Makefile
>>> +++ b/drivers/hwmon/peci/Makefile
>>> @@ -1,5 +1,7 @@
>>>  ?# SPDX-License-Identifier: GPL-2.0-only
>>>   
>>>  ?peci-cputemp-y := cputemp.o
>>> +peci-dimmtemp-y := dimmtemp.o
>>>   
>>>  ?obj-$(CONFIG_SENSORS_PECI_CPUTEMP)?????+= peci-cputemp.o
>>> +obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)????+= peci-dimmtemp.o
>>> diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c
>>> new file mode 100644
>>> index 000000000000..6264c29bb6c0
>>> --- /dev/null
>>> +++ b/drivers/hwmon/peci/dimmtemp.c
>>> @@ -0,0 +1,614 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +// Copyright (c) 2018-2021 Intel Corporation
>>> +
>>> +#include <linux/auxiliary_bus.h>
>>> +#include <linux/bitfield.h>
>>> +#include <linux/bitops.h>
>>> +#include <linux/hwmon.h>
>>> +#include <linux/jiffies.h>
>>> +#include <linux/module.h>
>>> +#include <linux/peci.h>
>>> +#include <linux/peci-cpu.h>
>>> +#include <linux/units.h>
>>> +#include <linux/workqueue.h>
>>> +#include <linux/x86/intel-family.h>
>>> +
>>> +#include "common.h"
>>> +
>>> +#define DIMM_MASK_CHECK_DELAY_JIFFIES??msecs_to_jiffies(5000)
>>> +
>>> +/* Max number of channel ranks and DIMM index per channel */
>>> +#define CHAN_RANK_MAX_ON_HSX???8
>>> +#define DIMM_IDX_MAX_ON_HSX????3
>>> +#define CHAN_RANK_MAX_ON_BDX???4
>>> +#define DIMM_IDX_MAX_ON_BDX????3
>>> +#define CHAN_RANK_MAX_ON_BDXD??2
>>> +#define DIMM_IDX_MAX_ON_BDXD???2
>>> +#define CHAN_RANK_MAX_ON_SKX???6
>>> +#define DIMM_IDX_MAX_ON_SKX????2
>>> +#define CHAN_RANK_MAX_ON_ICX???8
>>> +#define DIMM_IDX_MAX_ON_ICX????2
>>> +#define CHAN_RANK_MAX_ON_ICXD??4
>>> +#define DIMM_IDX_MAX_ON_ICXD???2
>>> +
>>> +#define CHAN_RANK_MAX??????????CHAN_RANK_MAX_ON_HSX
>>> +#define DIMM_IDX_MAX???????????DIMM_IDX_MAX_ON_HSX
>>> +#define DIMM_NUMS_MAX??????????(CHAN_RANK_MAX * DIMM_IDX_MAX)
>>> +
>>> +#define CPU_SEG_MASK???????????GENMASK(23, 16)
>>> +#define GET_CPU_SEG(x)?????????(((x) & CPU_SEG_MASK) >> 16)
>>> +#define CPU_BUS_MASK???????????GENMASK(7, 0)
>>> +#define GET_CPU_BUS(x)?????????((x) & CPU_BUS_MASK)
>>> +
>>> +#define DIMM_TEMP_MAX??????????GENMASK(15, 8)
>>> +#define DIMM_TEMP_CRIT?????????GENMASK(23, 16)
>>> +#define GET_TEMP_MAX(x)????????????????(((x) & DIMM_TEMP_MAX) >> 8)
>>> +#define GET_TEMP_CRIT(x)???????(((x) & DIMM_TEMP_CRIT) >> 16)
>>> +
>>> +struct peci_dimmtemp;
>>> +
>>> +struct dimm_info {
>>> +???????int chan_rank_max;
>>> +???????int dimm_idx_max;
>>> +???????u8 min_peci_revision;
>>> +???????int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order,
>>> +????????????????????????????? int chan_rank, u32 *data);
>>> +};
>>> +
>>> +struct peci_dimm_thresholds {
>>> +???????long temp_max;
>>> +???????long temp_crit;
>>> +???????struct peci_sensor_state state;
>>> +};
>>> +
>>> +enum peci_dimm_threshold_type {
>>> +???????temp_max_type,
>>> +???????temp_crit_type,
>>> +};
>>> +
>>> +struct peci_dimmtemp {
>>> +???????struct peci_device *peci_dev;
>>> +???????struct device *dev;
>>> +???????const char *name;
>>> +???????const struct dimm_info *gen_info;
>>> +???????struct delayed_work detect_work;
>>> +???????struct {
>>> +???????????????struct peci_sensor_data temp;
>>> +???????????????struct peci_dimm_thresholds thresholds;
>>> +???????} dimm[DIMM_NUMS_MAX];
>>> +???????char **dimmtemp_label;
>>> +???????DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX);
>>> +};
>>> +
>>> +static u8 __dimm_temp(u32 reg, int dimm_order)
>>> +{
>>> +???????return (reg >> (dimm_order * 8)) & 0xff;
>>> +}
>>> +
>>> +static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long
>>> *val)
>>> +{
>>> +???????int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
>>> +???????int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
>>> +???????u32 data;
>>> +???????int ret;
>>
>>  ????????int ret = 0;
>>
>>> +
>>> +???????mutex_lock(&priv->dimm[dimm_no].temp.state.lock);
>>> +???????if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state))
>>> +???????????????goto skip_update;
>>> +
>>> +???????ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP,
>>> chan_rank, &data);
>>> +???????if (ret) {
>>> +???????????????mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
>>> +???????????????return ret;
>>> +???????}
>>
>>  ????????if (ret)
>>  ????????????????goto unlock;
>>
>>> +
>>> +???????priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) *
>>> MILLIDEGREE_PER_DEGREE;
>>> +
>>> +???????peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state);
>>> +
>>> +skip_update:
>>> +???????*val = priv->dimm[dimm_no].temp.value;
>>
>> unlock:
>>> +???????mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
>>> +???????return 0;
>>
>>  ????????return ret;
> 
> Ack.
> 
>>
>>> +}
>>> +
>>> +static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
>>> +{
>>> +???????int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
>>> +???????int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
>>> +???????u32 data;
>>> +???????int ret;
>>> +
>>> +???????if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state))
>>> +???????????????return 0;
>>> +
>>> +???????ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank,
>>> &data);
>>> +???????if (ret == -ENODATA) /* Use default or previous value */
>>> +???????????????return 0;
>>> +???????if (ret)
>>> +???????????????return ret;
>>> +
>>> +???????priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) *
>>> MILLIDEGREE_PER_DEGREE;
>>> +???????priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) *
>>> MILLIDEGREE_PER_DEGREE;
>>> +
>>> +???????peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state);
>>> +
>>> +???????return 0;
>>> +}
>>> +
>>> +static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum
>>> peci_dimm_threshold_type type,
>>> +????????????????????????????? int dimm_no, long *val)
>>> +{
>>> +???????int ret;
>>> +
>>> +???????mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock);
>>> +???????ret = update_thresholds(priv, dimm_no);
>>> +???????if (ret)
>>> +???????????????goto unlock;
>>> +
>>> +???????switch (type) {
>>> +???????case temp_max_type:
>>> +???????????????*val = priv->dimm[dimm_no].thresholds.temp_max;
>>> +???????????????break;
>>> +???????case temp_crit_type:
>>> +???????????????*val = priv->dimm[dimm_no].thresholds.temp_crit;
>>> +???????????????break;
>>> +???????default:
>>> +???????????????ret = -EOPNOTSUPP;
>>> +???????????????break;
>>> +???????}
>>> +unlock:
>>> +???????mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock);
>>> +
>>> +???????return ret;
>>> +}
>>> +
>>> +static int dimmtemp_read_string(struct device *dev,
>>> +???????????????????????????????enum hwmon_sensor_types type,
>>> +???????????????????????????????u32 attr, int channel, const char **str)
>>> +{
>>> +???????struct peci_dimmtemp *priv = dev_get_drvdata(dev);
>>> +
>>> +???????if (attr != hwmon_temp_label)
>>> +???????????????return -EOPNOTSUPP;
>>> +
>>> +???????*str = (const char *)priv->dimmtemp_label[channel];
>>> +
>>> +???????return 0;
>>> +}
>>> +
>>> +static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type,
>>> +??????????????????????? u32 attr, int channel, long *val)
>>> +{
>>> +???????struct peci_dimmtemp *priv = dev_get_drvdata(dev);
>>> +
>>> +???????switch (attr) {
>>> +???????case hwmon_temp_input:
>>> +???????????????return get_dimm_temp(priv, channel, val);
>>> +???????case hwmon_temp_max:
>>> +???????????????return get_dimm_thresholds(priv, temp_max_type, channel,
>>> val);
>>> +???????case hwmon_temp_crit:
>>> +???????????????return get_dimm_thresholds(priv, temp_crit_type, channel,
>>> val);
>>> +???????default:
>>> +???????????????break;
>>> +???????}
>>> +
>>> +???????return -EOPNOTSUPP;
>>> +}
>>> +
>>> +static umode_t dimmtemp_is_visible(const void *data, enum
>>> hwmon_sensor_types type,
>>> +????????????????????????????????? u32 attr, int channel)
>>> +{
>>> +???????const struct peci_dimmtemp *priv = data;
>>> +
>>> +???????if (test_bit(channel, priv->dimm_mask))
>>> +???????????????return 0444;
>>> +
>>> +???????return 0;
>>> +}
>>> +
>>> +static const struct hwmon_ops peci_dimmtemp_ops = {
>>> +???????.is_visible = dimmtemp_is_visible,
>>> +???????.read_string = dimmtemp_read_string,
>>> +???????.read = dimmtemp_read,
>>> +};
>>> +
>>> +static int check_populated_dimms(struct peci_dimmtemp *priv)
>>> +{
>>> +???????int chan_rank_max = priv->gen_info->chan_rank_max;
>>> +???????int dimm_idx_max = priv->gen_info->dimm_idx_max;
>>> +???????u32 chan_rank_empty = 0;
>>> +???????u64 dimm_mask = 0;
>>> +???????int chan_rank, dimm_idx, ret;
>>> +???????u32 pcs;
>>> +
>>> +???????BUILD_BUG_ON(CHAN_RANK_MAX > 32);
>>> +???????BUILD_BUG_ON(DIMM_NUMS_MAX > 64);
>>
>> I don't immediately see the value of those build bugs. What happens if
>> CHAN_RANK_MAX > 32 or DIMM_NUMS_MAX > 64 ? Where do those limits come
>> from ?
> 
> Supported HW doesn't come near the limit for now - it's just an "artificial"
> limit imposed by variables we're using (u64 for dimm_mask and u32 for
> chan_rank_empty).
> 

Please use a value derived from the size of those variables for the check
to clarify and explain the constraints.

Thanks,
Guenter


From sashal at kernel.org  Wed Aug  4 10:41:25 2021
From: sashal at kernel.org (Sasha Levin)
Date: Wed, 4 Aug 2021 13:41:25 -0400
Subject: [PATCH AUTOSEL 4.19 5/6] mt7530 fix mt7530_fdb_write vid missing
 ivl bit
In-Reply-To: <e1508978-8f0e-40a6-baa8-3d3bc4c82811@gmail.com>
References: <20210727132015.835651-1-sashal@kernel.org>
 <20210727132015.835651-5-sashal@kernel.org>
 <e1508978-8f0e-40a6-baa8-3d3bc4c82811@gmail.com>
Message-ID: <YQrRRar2TymxP2WP@sashalap>

On Sat, Jul 31, 2021 at 03:27:04PM +0200, Eric Woudstra wrote:
>
>A few days after this patch, I send in another as it needs a fix. If you apply this patch, please also apply the other: set ivl bit only for vid larger than 1.

Looks like the fix didn't make it yet, so I'll drop this one for now.

-- 
Thanks,
Sasha


From zweiss at equinix.com  Wed Aug  4 10:52:04 2021
From: zweiss at equinix.com (Zev Weiss)
Date: Wed, 4 Aug 2021 17:52:04 +0000
Subject: [PATCH 13/14] docs: hwmon: Document PECI drivers
In-Reply-To: <ea5621698508a800cea59b5533f8845b9f0befc6.camel@intel.com>
References: <20210712220447.957418-1-iwona.winiarska@intel.com>
 <20210712220447.957418-14-iwona.winiarska@intel.com>
 <20210727225808.GU8018@packtop>
 <ea5621698508a800cea59b5533f8845b9f0befc6.camel@intel.com>
Message-ID: <20210804175203.GY8018@packtop>

On Mon, Aug 02, 2021 at 06:37:30AM CDT, Winiarska, Iwona wrote:
>On Tue, 2021-07-27 at 22:58 +0000, Zev Weiss wrote:
>> On Mon, Jul 12, 2021 at 05:04:46PM CDT, Iwona Winiarska wrote:
>> > From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>> >
>> > Add documentation for peci-cputemp driver that provides DTS thermal
>> > readings for CPU packages and CPU cores and peci-dimmtemp driver that
>> > provides DTS thermal readings for DIMMs.
>> >
>> > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>> > Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
>> > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
>> > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
>> > ---
>> > Documentation/hwmon/index.rst???????? |? 2 +
>> > Documentation/hwmon/peci-cputemp.rst? | 93 +++++++++++++++++++++++++++
>> > Documentation/hwmon/peci-dimmtemp.rst | 58 +++++++++++++++++
>> > MAINTAINERS?????????????????????????? |? 2 +
>> > 4 files changed, 155 insertions(+)
>> > create mode 100644 Documentation/hwmon/peci-cputemp.rst
>> > create mode 100644 Documentation/hwmon/peci-dimmtemp.rst
>> >
>> > diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
>> > index bc01601ea81a..cc76b5b3f791 100644
>> > --- a/Documentation/hwmon/index.rst
>> > +++ b/Documentation/hwmon/index.rst
>> > @@ -154,6 +154,8 @@ Hardware Monitoring Kernel Drivers
>> > ?? pcf8591
>> > ?? pim4328
>> > ?? pm6764tr
>> > +?? peci-cputemp
>> > +?? peci-dimmtemp
>> > ?? pmbus
>> > ?? powr1220
>> > ?? pxe1610
>> > diff --git a/Documentation/hwmon/peci-cputemp.rst
>> > b/Documentation/hwmon/peci-cputemp.rst
>> > new file mode 100644
>> > index 000000000000..d3a218ba810a
>> > --- /dev/null
>> > +++ b/Documentation/hwmon/peci-cputemp.rst
>> > @@ -0,0 +1,93 @@
>> > +.. SPDX-License-Identifier: GPL-2.0-only
>> > +
>> > +Kernel driver peci-cputemp
>> > +==========================
>> > +
>> > +Supported chips:
>> > +???????One of Intel server CPUs listed below which is connected to a PECI
>> > bus.
>> > +???????????????* Intel Xeon E5/E7 v3 server processors
>> > +???????????????????????Intel Xeon E5-14xx v3 family
>> > +???????????????????????Intel Xeon E5-24xx v3 family
>> > +???????????????????????Intel Xeon E5-16xx v3 family
>> > +???????????????????????Intel Xeon E5-26xx v3 family
>> > +???????????????????????Intel Xeon E5-46xx v3 family
>> > +???????????????????????Intel Xeon E7-48xx v3 family
>> > +???????????????????????Intel Xeon E7-88xx v3 family
>> > +???????????????* Intel Xeon E5/E7 v4 server processors
>> > +???????????????????????Intel Xeon E5-16xx v4 family
>> > +???????????????????????Intel Xeon E5-26xx v4 family
>> > +???????????????????????Intel Xeon E5-46xx v4 family
>> > +???????????????????????Intel Xeon E7-48xx v4 family
>> > +???????????????????????Intel Xeon E7-88xx v4 family
>> > +???????????????* Intel Xeon Scalable server processors
>> > +???????????????????????Intel Xeon D family
>> > +???????????????????????Intel Xeon Bronze family
>> > +???????????????????????Intel Xeon Silver family
>> > +???????????????????????Intel Xeon Gold family
>> > +???????????????????????Intel Xeon Platinum family
>> > +
>> > +???????Datasheet: Available from http://www.intel.com/design/literature.htm
>> > +
>> > +Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>> > +
>> > +Description
>> > +-----------
>> > +
>> > +This driver implements a generic PECI hwmon feature which provides Digital
>> > +Thermal Sensor (DTS) thermal readings of the CPU package and CPU cores that
>> > are
>> > +accessible via the processor PECI interface.
>> > +
>> > +All temperature values are given in millidegree Celsius and will be
>> > measurable
>> > +only when the target CPU is powered on.
>> > +
>> > +Sysfs interface
>> > +-------------------
>> > +
>> > +=======================
>> > =======================================================
>> > +temp1_label????????????"Die"
>> > +temp1_input????????????Provides current die temperature of the CPU package.
>> > +temp1_max??????????????Provides thermal control temperature of the CPU
>> > package
>> > +???????????????????????which is also known as Tcontrol.
>> > +temp1_crit?????????????Provides shutdown temperature of the CPU package
>> > which
>> > +???????????????????????is also known as the maximum processor junction
>> > +???????????????????????temperature, Tjmax or Tprochot.
>> > +temp1_crit_hyst????????????????Provides the hysteresis value from Tcontrol
>> > to Tjmax of
>> > +???????????????????????the CPU package.
>> > +
>> > +temp2_label????????????"DTS"
>> > +temp2_input????????????Provides current DTS temperature of the CPU package.
>>
>> Would this be a good place to note the slightly counter-intuitive nature
>> of DTS readings?? i.e. add something along the lines of "The DTS sensor
>> produces a delta relative to Tjmax, so negative values are normal and
>> values approaching zero are hot."? (In my experience people who aren't
>> already familiar with it tend to think something's wrong when a CPU
>> temperature reading shows -50C.)
>
>I believe that what you're referring to is a result of "GetTemp", and we're
>using it to calculate "Die" sensor values (temp1).
>The sensor value is absolute - we don't expose "raw" thermal sensor value
>(delta) anywhere.
>
>DTS sensor is exposing temperature value scaled to fit DTS 2.0 thermal profile:
>https://www.intel.com/content/www/us/en/processors/xeon/scalable/xeon-scalable-thermal-guide.html
>(section 5.2.3.2)
>
>Similar to "Die" sensor - it's also exposed in absolute form.
>
>I'll try to change description to avoid confusion.
>

When I tested the patch series by applying it to my OpenBMC kernel, the
temp2_input sysfs file produced negative numbers (as has been the case
with previous iterations of the PECI patchset).  Is that expected?  From
what Guenter has said it sounds like that's going to need to change so
that the temperature readings are all in "normal" millidegrees C
(that is, relative to the freezing point of water).


Zev


From linux at roeck-us.net  Wed Aug  4 11:05:48 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 4 Aug 2021 11:05:48 -0700
Subject: [PATCH 13/14] docs: hwmon: Document PECI drivers
In-Reply-To: <20210804175203.GY8018@packtop>
References: <20210712220447.957418-1-iwona.winiarska@intel.com>
 <20210712220447.957418-14-iwona.winiarska@intel.com>
 <20210727225808.GU8018@packtop>
 <ea5621698508a800cea59b5533f8845b9f0befc6.camel@intel.com>
 <20210804175203.GY8018@packtop>
Message-ID: <4e840768-0315-6241-e988-9a3165a31a86@roeck-us.net>

On 8/4/21 10:52 AM, Zev Weiss wrote:
> On Mon, Aug 02, 2021 at 06:37:30AM CDT, Winiarska, Iwona wrote:
>> On Tue, 2021-07-27 at 22:58 +0000, Zev Weiss wrote:
>>> On Mon, Jul 12, 2021 at 05:04:46PM CDT, Iwona Winiarska wrote:
>>>> From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>>>>
>>>> Add documentation for peci-cputemp driver that provides DTS thermal
>>>> readings for CPU packages and CPU cores and peci-dimmtemp driver that
>>>> provides DTS thermal readings for DIMMs.
>>>>
>>>> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>>>> Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
>>>> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
>>>> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
>>>> ---
>>>> Documentation/hwmon/index.rst???????? |? 2 +
>>>> Documentation/hwmon/peci-cputemp.rst? | 93 +++++++++++++++++++++++++++
>>>> Documentation/hwmon/peci-dimmtemp.rst | 58 +++++++++++++++++
>>>> MAINTAINERS?????????????????????????? |? 2 +
>>>> 4 files changed, 155 insertions(+)
>>>> create mode 100644 Documentation/hwmon/peci-cputemp.rst
>>>> create mode 100644 Documentation/hwmon/peci-dimmtemp.rst
>>>>
>>>> diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
>>>> index bc01601ea81a..cc76b5b3f791 100644
>>>> --- a/Documentation/hwmon/index.rst
>>>> +++ b/Documentation/hwmon/index.rst
>>>> @@ -154,6 +154,8 @@ Hardware Monitoring Kernel Drivers
>>>>  ?? pcf8591
>>>>  ?? pim4328
>>>>  ?? pm6764tr
>>>> +?? peci-cputemp
>>>> +?? peci-dimmtemp
>>>>  ?? pmbus
>>>>  ?? powr1220
>>>>  ?? pxe1610
>>>> diff --git a/Documentation/hwmon/peci-cputemp.rst
>>>> b/Documentation/hwmon/peci-cputemp.rst
>>>> new file mode 100644
>>>> index 000000000000..d3a218ba810a
>>>> --- /dev/null
>>>> +++ b/Documentation/hwmon/peci-cputemp.rst
>>>> @@ -0,0 +1,93 @@
>>>> +.. SPDX-License-Identifier: GPL-2.0-only
>>>> +
>>>> +Kernel driver peci-cputemp
>>>> +==========================
>>>> +
>>>> +Supported chips:
>>>> +???????One of Intel server CPUs listed below which is connected to a PECI
>>>> bus.
>>>> +???????????????* Intel Xeon E5/E7 v3 server processors
>>>> +???????????????????????Intel Xeon E5-14xx v3 family
>>>> +???????????????????????Intel Xeon E5-24xx v3 family
>>>> +???????????????????????Intel Xeon E5-16xx v3 family
>>>> +???????????????????????Intel Xeon E5-26xx v3 family
>>>> +???????????????????????Intel Xeon E5-46xx v3 family
>>>> +???????????????????????Intel Xeon E7-48xx v3 family
>>>> +???????????????????????Intel Xeon E7-88xx v3 family
>>>> +???????????????* Intel Xeon E5/E7 v4 server processors
>>>> +???????????????????????Intel Xeon E5-16xx v4 family
>>>> +???????????????????????Intel Xeon E5-26xx v4 family
>>>> +???????????????????????Intel Xeon E5-46xx v4 family
>>>> +???????????????????????Intel Xeon E7-48xx v4 family
>>>> +???????????????????????Intel Xeon E7-88xx v4 family
>>>> +???????????????* Intel Xeon Scalable server processors
>>>> +???????????????????????Intel Xeon D family
>>>> +???????????????????????Intel Xeon Bronze family
>>>> +???????????????????????Intel Xeon Silver family
>>>> +???????????????????????Intel Xeon Gold family
>>>> +???????????????????????Intel Xeon Platinum family
>>>> +
>>>> +???????Datasheet: Available from http://www.intel.com/design/literature.htm
>>>> +
>>>> +Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>>>> +
>>>> +Description
>>>> +-----------
>>>> +
>>>> +This driver implements a generic PECI hwmon feature which provides Digital
>>>> +Thermal Sensor (DTS) thermal readings of the CPU package and CPU cores that
>>>> are
>>>> +accessible via the processor PECI interface.
>>>> +
>>>> +All temperature values are given in millidegree Celsius and will be
>>>> measurable
>>>> +only when the target CPU is powered on.
>>>> +
>>>> +Sysfs interface
>>>> +-------------------
>>>> +
>>>> +=======================
>>>> =======================================================
>>>> +temp1_label????????????"Die"
>>>> +temp1_input????????????Provides current die temperature of the CPU package.
>>>> +temp1_max??????????????Provides thermal control temperature of the CPU
>>>> package
>>>> +???????????????????????which is also known as Tcontrol.
>>>> +temp1_crit?????????????Provides shutdown temperature of the CPU package
>>>> which
>>>> +???????????????????????is also known as the maximum processor junction
>>>> +???????????????????????temperature, Tjmax or Tprochot.
>>>> +temp1_crit_hyst????????????????Provides the hysteresis value from Tcontrol
>>>> to Tjmax of
>>>> +???????????????????????the CPU package.
>>>> +
>>>> +temp2_label????????????"DTS"
>>>> +temp2_input????????????Provides current DTS temperature of the CPU package.
>>>
>>> Would this be a good place to note the slightly counter-intuitive nature
>>> of DTS readings?? i.e. add something along the lines of "The DTS sensor
>>> produces a delta relative to Tjmax, so negative values are normal and
>>> values approaching zero are hot."? (In my experience people who aren't
>>> already familiar with it tend to think something's wrong when a CPU
>>> temperature reading shows -50C.)
>>
>> I believe that what you're referring to is a result of "GetTemp", and we're
>> using it to calculate "Die" sensor values (temp1).
>> The sensor value is absolute - we don't expose "raw" thermal sensor value
>> (delta) anywhere.
>>
>> DTS sensor is exposing temperature value scaled to fit DTS 2.0 thermal profile:
>> https://www.intel.com/content/www/us/en/processors/xeon/scalable/xeon-scalable-thermal-guide.html
>> (section 5.2.3.2)
>>
>> Similar to "Die" sensor - it's also exposed in absolute form.
>>
>> I'll try to change description to avoid confusion.
>>
> 
> When I tested the patch series by applying it to my OpenBMC kernel, the
> temp2_input sysfs file produced negative numbers (as has been the case
> with previous iterations of the PECI patchset).  Is that expected?  From
> what Guenter has said it sounds like that's going to need to change so
> that the temperature readings are all in "normal" millidegrees C
> (that is, relative to the freezing point of water).
> 

Correct, the temperature is expected to be reported in millidegrees C
per hwmon ABI. Everything else is unacceptable. That makes me wonder what
"raw" and "absolute" means. Negative numbers suggest that, whatever is
reported today, it is not millidegrees C.

Guenter


From broonie at kernel.org  Wed Aug  4 11:17:10 2021
From: broonie at kernel.org (Mark Brown)
Date: Wed,  4 Aug 2021 19:17:10 +0100
Subject: [PATCH] arm64: entry: Add SYM_CODE annotation for __bad_stack
Message-ID: <20210804181710.19059-1-broonie@kernel.org>

When converting arm64 to modern assembler annotations __bad_stack was left
as a raw local label without annotations. While this will have little if
any practical impact at present it may cause issues in the future if we
start using the annotations for things like reliable stack trace. Add
SYM_CODE annotations to fix this.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/entry.S | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 923ee2ac85fd..572f72f20646 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -535,12 +535,13 @@ SYM_CODE_START(vectors)
 SYM_CODE_END(vectors)
 
 #ifdef CONFIG_VMAP_STACK
+SYM_CODE_START_LOCAL(__bad_stack)
 	/*
 	 * We detected an overflow in kernel_ventry, which switched to the
 	 * overflow stack. Stash the exception regs, and head to our overflow
 	 * handler.
 	 */
-__bad_stack:
+
 	/* Restore the original x0 value */
 	mrs	x0, tpidrro_el0
 
@@ -560,6 +561,7 @@ __bad_stack:
 	/* Time to die */
 	bl	handle_bad_stack
 	ASM_BUG()
+SYM_CODE_END(__bad_stack)
 #endif /* CONFIG_VMAP_STACK */
 
 
-- 
2.20.1



From saravanak at google.com  Wed Aug  4 11:20:52 2021
From: saravanak at google.com (Saravana Kannan)
Date: Wed, 4 Aug 2021 11:20:52 -0700
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <87sfzpwq4f.wl-maz@kernel.org>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
Message-ID: <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>

On Wed, Aug 4, 2021 at 1:50 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Wed, 04 Aug 2021 02:36:45 +0100,
> Saravana Kannan <saravanak at google.com> wrote:
>
> Hi Saravana,
>
> Thanks for looking into this.

You are welcome. I just don't want people to think fw_devlink is broken :)

>
> [...]
>
> > > Saravana, could you please have a look from a fw_devlink perspective?
> >
> > Sigh... I spent several hours looking at this and wrote up an analysis
> > and then realized I might be looking at the wrong DT files.
> >
> > Marc, can you point me to the board file in upstream that corresponds
> > to the platform in which you see this issue? I'm not asking for [1],
> > but the actual final .dts (not .dtsi) file that corresponds to the
> > platform/board/system.
>
> The platform I can reproduce this on is described in
> arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts. It is an
> intricate maze of inclusion, node merge and other DT subtleties. I
> suggest you look at the decompiled version to get a view of the
> result.

Thanks. After decompiling it, it looks something like (stripped a
bunch of reg and address properties and added the labels back):

eth_phy: mdio-multiplexer at 4c000 {
        compatible = "amlogic,g12a-mdio-mux";
        clocks = <0x02 0x13 0x1e 0x02 0xb1>;
        clock-names = "pclk\0clkin0\0clkin1";
        mdio-parent-bus = <0x22>;

        ext_mdio: mdio at 0 {
                reg = <0x00>;

                ethernet-phy at 0 {
                        max-speed = <0x3e8>;
                        interrupt-parent = <0x23>;
                        interrupts = <0x1a 0x08>;
                        phandle = <0x16>;
                };
        };

        int_mdio: mdio at 1 {
                ...
        }
}

And phandle 0x23 refers to the gpio_intc interrupt controller with the
modular driver.

> > Based on your error messages, it's failing for mdio at 0 which
> > corresponds to ext_mdio. But none of the board dts files in upstream
> > have a compatible property for "ext_mdio". Which means fw_devlink
> > _should_ propagate the gpio_intc IRQ dependency all the way up to
> > eth_phy.
> >
> > Also, in the failing case, can you run:
> > ls -ld supplier:*
> >
> > in the /sys/devices/....<something>/ folder that corresponds to the
> > "eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?
>
> Here you go:
>
> root at tiger-roach:~# find /sys/devices/ -name 'supplier*'|grep -i mdio | xargs ls -ld
> lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/platform/soc/ff600000.bus/ff64c000.mdio-multiplexer/supplier:platform:ff63c000.system-controller:clock-controller -> ../../../../virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer

As we discussed over chat, this was taken after the mdio-multiplexer
driver "successfully" probes this device. This will cause
SYNC_STATE_ONLY device links created by fw_devlink to be deleted
(because they are useless after a device probes). So, this doesn't
show the info I was hoping to demonstrate.

In any case, one can see that fw_devlink properly created the device
link for the clocks dependency. So fw_devlink is parsing this node
properly. But it doesn't create a similar probe order enforcing device
link between the mdio-multiplexer and the gpio_intc because the
dependency is only present in a grand child DT node (ethernet-phy at 0
under ext_mdio). So fw_devlink is working as intended.

I spent several hours squinting at the code/DT yesterday. Here's what
is going on and causing the problem:

The failing driver in this case is
drivers/net/mdio/mdio-mux-meson-g12a.c. And the only DT node it's
handling is what I pasted above in this email. In the failure case,
the call flow is something like this:

g12a_mdio_mux_probe()
-> mdio_mux_init()
-> of_mdiobus_register(ext_mdio DT node)
-> of_mdiobus_register_phy(ext_mdio DT node)
-> several calls deep fwnode_mdiobus_phy_device_register(ethernet_phy DT node)
-> Tried to get the IRQ listed in ethernet_phy and fails with
-EPROBE_DEFER because the IRQ driver isn't loaded yet.

The error is propagated correctly all the way up to of_mdiobus_register(), but
mdio_mux_init() ignores the -EPROBE_DEFER from of_mdiobus_register() and just
continues on with the rest of the stuff and returns success as long as
one of the child nodes (in this case int_mdio) succeeds.

Since the probe returns 0 without really succeeding, networking stuff
just fails badly after this. So, IMO, the real problem is with
mdio_mux_init() not propagating up the -EPROBE_DEFER. I gave Marc a
quick hack (pasted at the end of this email) to test my theory and he
confirmed that it fixes the issue (a few deferred probes later, things
work properly).

Andrew, I don't see any good reason for mdio_mux_init() not
propagating the errors up correctly (at least for EPROBE_DEFER). I'll
send a patch to fix this. Please let me know if there's a reason it
has to stay as-is.

-Saravana

index 110e4ee85785..d973a267151f 100644
--- a/drivers/net/mdio/mdio-mux.c
+++ b/drivers/net/mdio/mdio-mux.c
@@ -170,6 +170,9 @@ int mdio_mux_init(struct device *dev,
                                child_bus_node);
                        mdiobus_free(cb->mii_bus);
                        devm_kfree(dev, cb);
+                       /* Not a final fix. I think it can cause UAF issues. */
+                       mdio_mux_uninit(pb);
+                       return r;
                } else {
                        cb->next = pb->children;
                        pb->children = cb;


From tzimmermann at suse.de  Wed Aug  4 11:30:41 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Wed, 4 Aug 2021 20:30:41 +0200
Subject: [PATCH v2 11/14] drm/tilcdc: Convert to Linux IRQ interfaces
In-Reply-To: <YQlZ+EQVbO9N3Mla@ravnborg.org>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-12-tzimmermann@suse.de> <YQlZ+EQVbO9N3Mla@ravnborg.org>
Message-ID: <896793e5-f5a8-fe74-1d8f-3dd1450d3fae@suse.de>

Hi

Am 03.08.21 um 17:00 schrieb Sam Ravnborg:
> Hi Thomas,
> 
> On Tue, Aug 03, 2021 at 11:07:01AM +0200, Thomas Zimmermann wrote:
>> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
>> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
>> don't benefit from using it.
>>
>> DRM IRQ callbacks are now being called directly or inlined.
>>
>> Calls to platform_get_irq() can fail with a negative errno code.
>> Abort initialization in this case. The DRM IRQ midlayer does not
>> handle this case correctly.
> 
> I cannot see why the irq_enabled flag is needed here, and the changelog
> do not help me.
> What do I miss?

That's a good point. Usually, only the DRM IRQ helpers use irq_enabled 
in struct drm_device. It'll become legacy and we can ignore it for the 
driver conversion.

The exception is tilcdc, which also uses irq_enabled to make its error 
rollback work correctly. So I duplicated the state in the local private 
structure.

I'll add this explanation to the commit message.

Best regards
Thomas

> 
> 	Sam
> 
> 
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>> ---
>>   drivers/gpu/drm/tilcdc/tilcdc_drv.c | 51 ++++++++++++++++++++++-------
>>   drivers/gpu/drm/tilcdc/tilcdc_drv.h |  3 ++
>>   2 files changed, 43 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
>> index f1d3a9f919fd..6b03f89a98d4 100644
>> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
>> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
>> @@ -20,7 +20,6 @@
>>   #include <drm/drm_fourcc.h>
>>   #include <drm/drm_gem_cma_helper.h>
>>   #include <drm/drm_gem_framebuffer_helper.h>
>> -#include <drm/drm_irq.h>
>>   #include <drm/drm_mm.h>
>>   #include <drm/drm_probe_helper.h>
>>   #include <drm/drm_vblank.h>
>> @@ -124,6 +123,39 @@ static int cpufreq_transition(struct notifier_block *nb,
>>   }
>>   #endif
>>   
>> +static irqreturn_t tilcdc_irq(int irq, void *arg)
>> +{
>> +	struct drm_device *dev = arg;
>> +	struct tilcdc_drm_private *priv = dev->dev_private;
>> +
>> +	return tilcdc_crtc_irq(priv->crtc);
>> +}
>> +
>> +static int tilcdc_irq_install(struct drm_device *dev, unsigned int irq)
>> +{
>> +	struct tilcdc_drm_private *priv = dev->dev_private;
>> +	int ret;
>> +
>> +	ret = request_irq(irq, tilcdc_irq, 0, dev->driver->name, dev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	priv->irq_enabled = false;
>> +
>> +	return 0;
>> +}
>> +
>> +static void tilcdc_irq_uninstall(struct drm_device *dev)
>> +{
>> +	struct tilcdc_drm_private *priv = dev->dev_private;
>> +
>> +	if (!priv->irq_enabled)
>> +		return;
>> +
>> +	free_irq(priv->irq, dev);
>> +	priv->irq_enabled = false;
>> +}
>> +
>>   /*
>>    * DRM operations:
>>    */
>> @@ -145,7 +177,7 @@ static void tilcdc_fini(struct drm_device *dev)
>>   		drm_dev_unregister(dev);
>>   
>>   	drm_kms_helper_poll_fini(dev);
>> -	drm_irq_uninstall(dev);
>> +	tilcdc_irq_uninstall(dev);
>>   	drm_mode_config_cleanup(dev);
>>   
>>   	if (priv->clk)
>> @@ -336,7 +368,12 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
>>   		goto init_failed;
>>   	}
>>   
>> -	ret = drm_irq_install(ddev, platform_get_irq(pdev, 0));
>> +	ret = platform_get_irq(pdev, 0);
>> +	if (ret < 0)
>> +		goto init_failed;
>> +	priv->irq = ret;
>> +
>> +	ret = tilcdc_irq_install(ddev, priv->irq);
>>   	if (ret < 0) {
>>   		dev_err(dev, "failed to install IRQ handler\n");
>>   		goto init_failed;
>> @@ -360,13 +397,6 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev)
>>   	return ret;
>>   }
>>   
>> -static irqreturn_t tilcdc_irq(int irq, void *arg)
>> -{
>> -	struct drm_device *dev = arg;
>> -	struct tilcdc_drm_private *priv = dev->dev_private;
>> -	return tilcdc_crtc_irq(priv->crtc);
>> -}
>> -
>>   #if defined(CONFIG_DEBUG_FS)
>>   static const struct {
>>   	const char *name;
>> @@ -454,7 +484,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
>>   
>>   static const struct drm_driver tilcdc_driver = {
>>   	.driver_features    = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
>> -	.irq_handler        = tilcdc_irq,
>>   	DRM_GEM_CMA_DRIVER_OPS,
>>   #ifdef CONFIG_DEBUG_FS
>>   	.debugfs_init       = tilcdc_debugfs_init,
>> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
>> index d29806ca8817..b818448c83f6 100644
>> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
>> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
>> @@ -46,6 +46,8 @@ struct tilcdc_drm_private {
>>   	struct clk *clk;         /* functional clock */
>>   	int rev;                 /* IP revision */
>>   
>> +	unsigned int irq;
>> +
>>   	/* don't attempt resolutions w/ higher W * H * Hz: */
>>   	uint32_t max_bandwidth;
>>   	/*
>> @@ -82,6 +84,7 @@ struct tilcdc_drm_private {
>>   
>>   	bool is_registered;
>>   	bool is_componentized;
>> +	bool irq_enabled;
>>   };
>>   
>>   /* Sub-module for display.  Since we don't know at compile time what panels
>> -- 
>> 2.32.0

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Felix Imend?rffer

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210804/2153ae40/attachment.sig>

From sam at ravnborg.org  Wed Aug  4 11:33:30 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Wed, 4 Aug 2021 20:33:30 +0200
Subject: [PATCH v2 11/14] drm/tilcdc: Convert to Linux IRQ interfaces
In-Reply-To: <896793e5-f5a8-fe74-1d8f-3dd1450d3fae@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-12-tzimmermann@suse.de>
 <YQlZ+EQVbO9N3Mla@ravnborg.org>
 <896793e5-f5a8-fe74-1d8f-3dd1450d3fae@suse.de>
Message-ID: <YQrdelvqiiv6On8r@ravnborg.org>

Hi Thomas,
On Wed, Aug 04, 2021 at 08:30:41PM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 03.08.21 um 17:00 schrieb Sam Ravnborg:
> > Hi Thomas,
> > 
> > On Tue, Aug 03, 2021 at 11:07:01AM +0200, Thomas Zimmermann wrote:
> > > Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> > > IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> > > don't benefit from using it.
> > > 
> > > DRM IRQ callbacks are now being called directly or inlined.
> > > 
> > > Calls to platform_get_irq() can fail with a negative errno code.
> > > Abort initialization in this case. The DRM IRQ midlayer does not
> > > handle this case correctly.
> > 
> > I cannot see why the irq_enabled flag is needed here, and the changelog
> > do not help me.
> > What do I miss?
> 
> That's a good point. Usually, only the DRM IRQ helpers use irq_enabled in
> struct drm_device. It'll become legacy and we can ignore it for the driver
> conversion.
> 
> The exception is tilcdc, which also uses irq_enabled to make its error
> rollback work correctly. So I duplicated the state in the local private
> structure.
> 
> I'll add this explanation to the commit message.
With this added:
Acked-by: Sam Ravnborg <sam at ravnborg.org>


From krzysztof.kozlowski at canonical.com  Wed Aug  4 11:36:40 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 4 Aug 2021 20:36:40 +0200
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
Message-ID: <bf21badb-804f-45f0-c02b-80ff57ab9931@canonical.com>

On 04/08/2021 16:39, Sam Protsenko wrote:
> Hi Marc,
> 
> On Fri, 30 Jul 2021 at 19:50, Marc Zyngier <maz at kernel.org> wrote:
>>
>> On 2021-07-30 15:49, Sam Protsenko wrote:
>>> Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
>>>
>>> Features:
>>>  * CPU: Cortex-A55 Octa (8 cores), up to 2 GHz
>>>  * Memory interface: LPDDR4/4x 2 channels (12.8 GB/s)
>>>  * SD/MMC: SD 3.0, eMMC5.1 DDR 8-bit
>>>  * Modem: 4G LTE, 3G, GSM/GPRS/EDGE
>>>  * RF: Quad GNSS, WiFi 5 (802.11ac), Bluetooth 5.0
>>>  * GPU: Mali-G52 MP1
>>>  * Codec: 1080p 60fps H64, HEVC, JPEG HW Codec
>>>  * Display: Full HD+ (2520x1080)@60fps LCD
>>>  * Camera: 16+5MP/13+8MP ISP, MIPI CSI 4/4/2, FD, DRC
>>>  * Connectivity: USB 2.0 DRD, USI (SPI/UART/I2C), HSI2C, I3C, ADC,
>>> Audio
>>>
>>> This patch adds minimal SoC support. Particular board device tree files
>>> can include exynos850.dtsi file to get SoC related nodes, and then
>>> reference those nodes further as needed.
>>>
>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>> ---
>>>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
>>>  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
>>>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
>>>  3 files changed, 1057 insertions(+)
>>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
>>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
>>>
>>> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>> b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>> new file mode 100644
>>> index 000000000000..4cf0a22cc6db
>>
>> [...]
>>
>>> +     gic: interrupt-controller at 12a00000 {
>>> +             compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
>>
>> One thing for sure, it cannot be both. And given that it is
>> an A55-based SoC, it isn't either. It is more likely a GIC400.
>>
> 
> Yes, it's GIC-400, thanks for pointing that out. Will fix that in v2.
> 
>>> +             #interrupt-cells = <3>;
>>> +             #address-cells = <0>;
>>> +             interrupt-controller;
>>> +             reg = <0x0 0x12a01000 0x1000>,
>>> +                   <0x0 0x12a02000 0x1000>,
>>
>> This is wrong. It is architecturally set to 8kB.
>>
> 
> Nice catch! Actually there is an error (typo?) in SoC's TRM, saying
> that Virtual Interface Control Register starts at 0x3000 offset (from
> 0x12a00000), where it obviously should be 0x4000, that's probably
> where this dts error originates from. Btw, I'm also seeing the same
> error in exynos7.dtsi.

What's the error exactly? The "Virtual interface control register"
offset (3rd region) is set properly to 0x4000 on Exynos7. Also one for
the Exynos5433 looks correct.

> Though I don't have a TRM for Exynos7 SoCs, so
> not sure if I should go ahead and fix that too. Anyway, for Exynos850,
> I'll fix that in v2 series.


However while we are at addresses - why are you using address-cells 2?
It adds everywhere additional 0x0 before actual address.


Best regards,
Krzysztof


From semen.protsenko at linaro.org  Wed Aug  4 11:37:24 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 4 Aug 2021 21:37:24 +0300
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <87k0l1w8y5.wl-maz@kernel.org>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
 <87k0l1w8y5.wl-maz@kernel.org>
Message-ID: <CAPLW+4mMF9B2BiY2hTgHz5=DNbDJZ7TDzt=Xefb5tDKwQhpEew@mail.gmail.com>

On Wed, 4 Aug 2021 at 18:01, Marc Zyngier <maz at kernel.org> wrote:
>
> On Wed, 04 Aug 2021 15:39:38 +0100,
> Sam Protsenko <semen.protsenko at linaro.org> wrote:
>
> > > You are also missing the hypervisor virtual timer interrupt.
> > >
> >
> > Checked SoC TRM, there is no PPI for hypervisor virtual timer
> > interrupt, and no mentioning of it at all. Likewise, I checked ARMv8
> > ARM and TRM, almost no description of it. Also, I checked other
> > platforms, and seems like everyone does the same (having only 4
> > interrupts). And I wasn't able to find any documentation on that, so I
> > guess I'll leave it as is, if you don't mind.
>
> I *do* mind, and other DTs being wrong isn't a good enough excuse! ;-)
>
> From the ARMv8 ARM (ARM DDI 0487G.b)
> <quote>
> D11.2.4 Timers
>
> In an implementation of the Generic Timer that includes EL3, if EL3
> can use AArch64, the following timers are implemented:
>
> * An EL1 physical timer, that:
>   - In Secure state, can be accessed from EL1.
>   - In Non-secure state, can be accessed from EL1 unless those
>     accesses are trapped to EL2.
>     When this timer can be accessed from EL1, an EL1 control
>     determines whether it can be accessed from EL0.
> * A Non-secure EL2 physical timer.
> * A Secure EL3 physical timer. An EL3 control determines whether this
>   register is accessible from Secure EL1.
> * An EL1 virtual timer.
> * When FEAT_VHE is implemented, a Non-secure EL2 virtual timer.
> * When FEAT_SEL2 is implemented, a Secure EL2 physical timer.
> * When FEAT_SEL2 is implemented, a Secure EL2 virtual timer.
> </quote>
>
> Cortex-A55 being an ARMv8.2 implementation, it has FEAT_VHE, and thus
> it does have a NS-EL2 virtual timer. This is further confirmed by the
> TRM which documents CNTHV*_EL2 as valid system registers[1].
>
> So the timer exists, the signal is routed out of the core, and it
> is likely that it is connected to the GIC.
>
> If the designers have omitted it, then it needs to be documented as
> such.
>

Ok, I've checked thoroughly all docs again, and it seems like there is
no dedicated PPI number for this "EL2 Hypervisor Virtual Timer" in
Exynos850 SoC. The timer instance itself might exist of course, but
interrupt line is probably wasn't connected to GIC by SoC designers,
at least it's not documented.

Moreover, from [1,2] it looks like if it were existing it would have
been PPI=12 (INTID=28). But in GIC-400 TRM this PPI is assigned to
"Legacy FIQ signal", and all there is no PPI for Hypervisor Virtual
Timer documented there as well. In Exynos850 TRM the source for this
PPI's interrupt source is marked as "-", which means it's not used.

So if you know something that I don't know -- please point me out the
doc where this PPI line is documented. Otherwise I can add the comment
to device tree, stating that this interrupt line is not present in
SoC's GIC, i.e. something like this:

8<------------------------------------------------------------------------------->8
    timer {
        compatible = "arm,armv8-timer";
        interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) |
                      IRQ_TYPE_LEVEL_LOW)>,
                 <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) |
                      IRQ_TYPE_LEVEL_LOW)>,
                 <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) |
                      IRQ_TYPE_LEVEL_LOW)>,
                 <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) |
                      IRQ_TYPE_LEVEL_LOW)>;
        /* Hypervisor Virtual Timer PPI is not present in this SoC GIC */
    };
8<------------------------------------------------------------------------------->8

Is that ok with you?

[1] https://developer.arm.com/documentation/102379/0000/The-processor-timers?lang=en
[2] https://gem5.googlesource.com/public/gem5/+/refs/heads/master/src/arch/arm/fastmodel/CortexA76/FastModelCortexA76.py#150

> Thanks,
>
>         M.
>
> [1] https://developer.arm.com/documentation/100442/0100/register-descriptions/aarch64-system-registers/aarch64-architectural-system-register-summary
>
> --
> Without deviation from the norm, progress is not possible.


From michael.riesch at wolfvision.net  Wed Aug  4 11:49:45 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed, 4 Aug 2021 20:49:45 +0200
Subject: [PATCH v2 7/7] arm64: dts: rockchip: rk3568-evb1-v10: add node
 for sd card
In-Reply-To: <aa16ee55-e1de-adc8-51f0-8ceed136b911@gmail.com>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
 <20210804130625.15449-8-michael.riesch@wolfvision.net>
 <aa16ee55-e1de-adc8-51f0-8ceed136b911@gmail.com>
Message-ID: <68c6c548-ff07-da79-f75c-afb6a9846932@wolfvision.net>

Hi Johan,

Thanks for your comments, I'll try to implement the requested changes
and prepare a v3 tomorrow.

On 8/4/21 4:30 PM, Johan Jonker wrote:
> Hi Michael,
> 
> Could you add a commit message to all patches in this serie?

Well the short commit message (i.e., the subject line) pretty much wraps
it all up in my opinion, hence no need for an extended commit message.
Is there anything in particular you would like to see or have explained
that requires an extended message? I would like to refrain from adding
an extended commit message just for the sake of having one.

> On 8/4/21 3:06 PM, Michael Riesch wrote:
>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>> ---
>> v2:
>> - rename alias to match convention
>>
>>  arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
>> index ed96f27c64a3..c4da6436059d 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
>> @@ -17,6 +17,7 @@
>>  		ethernet0 = &gmac0;
>>  		ethernet1 = &gmac1;
> 
>>  		mmc0 = &sdhci;
>> +		mmc1 = &sdmmc0;
> 
> mmc aliases are sort on reg address based on availability without number
> gap.
> 
> 	sdmmc0: mmc at fe2b0000 {}
> 	sdhci: mmc at fe310000 {}

I'll turn these around.

>>  	};
>>  
>>  	chosen: chosen {
>> @@ -353,6 +354,20 @@
>>  	status = "okay";
>>  };
>>  
>> +&sdmmc0 {
>> +	bus-width = <4>;
>> +	cap-sd-highspeed;
>> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>> +	disable-wp;
> 
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
> 
> pinctrl-names below pinctrl-0 like the rest of rk356x.dtsi

OK!

>> +	sd-uhs-sdr104;
> 
>> +	supports-sd;
> 
> Check mmc-controller.yaml, rockchip-dw-mshc.yaml and
> synopsys-dw-mshc-common.yaml for properties.

I am afraid I don't quite follow. What exactly should I check? I am
pretty sure that the properties I used are described in the mentioned
yaml files.

Regards, Michael

> 
>> +	vmmc-supply = <&vcc3v3_sd>;
>> +	vqmmc-supply = <&vccio_sd>;
>> +	status = "okay";
>> +};
>> +
>>  &uart2 {
>>  	status = "okay";
>>  };
>>


From s-anna at ti.com  Wed Aug  4 11:50:08 2021
From: s-anna at ti.com (Suman Anna)
Date: Wed, 4 Aug 2021 13:50:08 -0500
Subject: [PATCH v2] dt-bindings: soc: ti: pruss: Add dma-coherent property
Message-ID: <20210804185008.30096-1-s-anna@ti.com>

Update the PRUSS schema file to include the dma-coherent property
that indicates the coherency of the IP. The PRUSS IPs on 66AK2G
SoCs do use this property.

The new added dma-coherent property is a required property _only_
for 66AK2G SoCs and is not required/applicable for other SoCs, so
the binding is backward compatible for other SoCs. This update is
being done before the corresponding dts nodes can be added for 66AK2G
SoCs.

Signed-off-by: Suman Anna <s-anna at ti.com>
Reviewed-by: Grygorii Strashko <grygorii.strashko at ti.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
v2: 
 - No code changes, only updated the patch description (added 2nd para) to 
   address Rob's review comments
 - Picked up review tags
 - Patch is still on top of AM64 ICSSG binding update patch [1]
v1: https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20210730031901.26243-1-s-anna at ti.com/

[1] https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210623165032.31223-2-s-anna at ti.com/

 .../devicetree/bindings/soc/ti/ti,pruss.yaml  | 37 +++++++++++++------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
index 47d7fd24bc56..9d128b9e7deb 100644
--- a/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
+++ b/Documentation/devicetree/bindings/soc/ti/ti,pruss.yaml
@@ -85,6 +85,8 @@ properties:
   dma-ranges:
     maxItems: 1
 
+  dma-coherent: true
+
   power-domains:
     description: |
       This property is as per sci-pm-domain.txt.
@@ -324,18 +326,29 @@ additionalProperties: false
 # - interrupt-controller
 # - pru
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - ti,k2g-pruss
-          - ti,am654-icssg
-          - ti,j721e-icssg
-          - ti,am642-icssg
-then:
-  required:
-    - power-domains
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - ti,k2g-pruss
+              - ti,am654-icssg
+              - ti,j721e-icssg
+              - ti,am642-icssg
+    then:
+      required:
+        - power-domains
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - ti,k2g-pruss
+    then:
+      required:
+        - dma-coherent
 
 examples:
   - |
-- 
2.32.0



From heiko at sntech.de  Wed Aug  4 11:52:39 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 04 Aug 2021 20:52:39 +0200
Subject: [PATCH v3 01/25] iommu: Pull IOVA cookie management into the core
In-Reply-To: <46f4cda8215bd5f8a9f9fd5a4a6451805f75efa3.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <46f4cda8215bd5f8a9f9fd5a4a6451805f75efa3.1628094600.git.robin.murphy@arm.com>
Message-ID: <2535689.1BCLMh4Saa@diego>

Am Mittwoch, 4. August 2021, 19:15:29 CEST schrieb Robin Murphy:
> Now that everyone has converged on iommu-dma for IOMMU_DOMAIN_DMA
> support, we can abandon the notion of drivers being responsible for the
> cookie type, and consolidate all the management into the core code.
> 
> CC: Marek Szyprowski <m.szyprowski at samsung.com>
> CC: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
> CC: Geert Uytterhoeven <geert+renesas at glider.be>
> CC: Yong Wu <yong.wu at mediatek.com>
> CC: Heiko Stuebner <heiko at sntech.de>
> CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
> CC: Maxime Ripard <mripard at kernel.org>
> Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

On a Rockchip rk3288 (arm32), rk3399 (arm64) and px30 (arm64)
with the graphics pipeline using the iommu

Tested-by: Heiko Stuebner <heiko at sntech.de>


Heiko

> 
> ---
> 
> v3: Use a simpler temporary check instead of trying to be clever with
>     the error code
> ---
>  drivers/iommu/iommu.c | 7 +++++++
>  include/linux/iommu.h | 3 ++-
>  2 files changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index f2cda9950bd5..b65fcc66ffa4 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -7,6 +7,7 @@
>  #define pr_fmt(fmt)    "iommu: " fmt
>  
>  #include <linux/device.h>
> +#include <linux/dma-iommu.h>
>  #include <linux/kernel.h>
>  #include <linux/bits.h>
>  #include <linux/bug.h>
> @@ -1946,6 +1947,11 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
>  	/* Assume all sizes by default; the driver may override this later */
>  	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
>  
> +	/* Temporarily avoid -EEXIST while drivers still get their own cookies */
> +	if (type == IOMMU_DOMAIN_DMA && !domain->iova_cookie && iommu_get_dma_cookie(domain)) {
> +		iommu_domain_free(domain);
> +		domain = NULL;
> +	}
>  	return domain;
>  }
>  
> @@ -1957,6 +1963,7 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
>  
>  void iommu_domain_free(struct iommu_domain *domain)
>  {
> +	iommu_put_dma_cookie(domain);
>  	domain->ops->domain_free(domain);
>  }
>  EXPORT_SYMBOL_GPL(iommu_domain_free);
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 4997c78e2670..141779d76035 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -40,6 +40,7 @@ struct iommu_domain;
>  struct notifier_block;
>  struct iommu_sva;
>  struct iommu_fault_event;
> +struct iommu_dma_cookie;
>  
>  /* iommu fault flags */
>  #define IOMMU_FAULT_READ	0x0
> @@ -86,7 +87,7 @@ struct iommu_domain {
>  	iommu_fault_handler_t handler;
>  	void *handler_token;
>  	struct iommu_domain_geometry geometry;
> -	void *iova_cookie;
> +	struct iommu_dma_cookie *iova_cookie;
>  };
>  
>  enum iommu_cap {
> 






From heiko at sntech.de  Wed Aug  4 11:53:36 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 04 Aug 2021 20:53:36 +0200
Subject: [PATCH v3 08/25] iommu/rockchip: Drop IOVA cookie management
In-Reply-To: <0d25511c58981ecd0a1f3006dc1c30a73fb7d377.1628094601.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <0d25511c58981ecd0a1f3006dc1c30a73fb7d377.1628094601.git.robin.murphy@arm.com>
Message-ID: <4512656.mogB4TqSGs@diego>

Am Mittwoch, 4. August 2021, 19:15:36 CEST schrieb Robin Murphy:
> The core code bakes its own cookies now.
> 
> CC: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>


On a Rockchip rk3288 (arm32), rk3399 (arm64) and px30 (arm64)
with the graphics pipeline using the iommu

Tested-by: Heiko Stuebner <heiko at sntech.de>
Acked-by: Heiko Stuebner <heiko at sntech.de>


Works now nicely on both arm32 and arm64


Thanks
Heiko


> 
> ---
> 
> v3: Also remove unneeded include
> ---
>  drivers/iommu/rockchip-iommu.c | 12 +-----------
>  1 file changed, 1 insertion(+), 11 deletions(-)
> 
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 9febfb7f3025..5cb260820eda 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -10,7 +10,6 @@
>  #include <linux/compiler.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> -#include <linux/dma-iommu.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/errno.h>
>  #include <linux/interrupt.h>
> @@ -1074,10 +1073,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
>  	if (!rk_domain)
>  		return NULL;
>  
> -	if (type == IOMMU_DOMAIN_DMA &&
> -	    iommu_get_dma_cookie(&rk_domain->domain))
> -		goto err_free_domain;
> -
>  	/*
>  	 * rk32xx iommus use a 2 level pagetable.
>  	 * Each level1 (dt) and level2 (pt) table has 1024 4-byte entries.
> @@ -1085,7 +1080,7 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
>  	 */
>  	rk_domain->dt = (u32 *)get_zeroed_page(GFP_KERNEL | GFP_DMA32);
>  	if (!rk_domain->dt)
> -		goto err_put_cookie;
> +		goto err_free_domain;
>  
>  	rk_domain->dt_dma = dma_map_single(dma_dev, rk_domain->dt,
>  					   SPAGE_SIZE, DMA_TO_DEVICE);
> @@ -1106,9 +1101,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
>  
>  err_free_dt:
>  	free_page((unsigned long)rk_domain->dt);
> -err_put_cookie:
> -	if (type == IOMMU_DOMAIN_DMA)
> -		iommu_put_dma_cookie(&rk_domain->domain);
>  err_free_domain:
>  	kfree(rk_domain);
>  
> @@ -1137,8 +1129,6 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
>  			 SPAGE_SIZE, DMA_TO_DEVICE);
>  	free_page((unsigned long)rk_domain->dt);
>  
> -	if (domain->type == IOMMU_DOMAIN_DMA)
> -		iommu_put_dma_cookie(&rk_domain->domain);
>  	kfree(rk_domain);
>  }
>  
> 






From heiko at sntech.de  Wed Aug  4 11:57:19 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 04 Aug 2021 20:57:19 +0200
Subject: [PATCH v2 7/7] arm64: dts: rockchip: rk3568-evb1-v10: add node
 for sd card
In-Reply-To: <68c6c548-ff07-da79-f75c-afb6a9846932@wolfvision.net>
References: <20210804130625.15449-1-michael.riesch@wolfvision.net>
 <aa16ee55-e1de-adc8-51f0-8ceed136b911@gmail.com>
 <68c6c548-ff07-da79-f75c-afb6a9846932@wolfvision.net>
Message-ID: <36612273.XM6RcZxFsP@diego>

Hi Michael,

Am Mittwoch, 4. August 2021, 20:49:45 CEST schrieb Michael Riesch:
> Hi Johan,
> 
> Thanks for your comments, I'll try to implement the requested changes
> and prepare a v3 tomorrow.
> 
> On 8/4/21 4:30 PM, Johan Jonker wrote:
> > Hi Michael,
> > 
> > Could you add a commit message to all patches in this serie?
> 
> Well the short commit message (i.e., the subject line) pretty much wraps
> it all up in my opinion, hence no need for an extended commit message.
> Is there anything in particular you would like to see or have explained
> that requires an extended message? I would like to refrain from adding
> an extended commit message just for the sake of having one.

it's just a matter of style, and yes having a non-empty commit message
is preferred in most parts of the kernel.

Even if it's just a simple one-liner ;-), for example

"Enable the sdmmc node on the rk3568-evb1 with the 4 lanes connected on it"


Heiko

> 
> > On 8/4/21 3:06 PM, Michael Riesch wrote:
> >> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> >> ---
> >> v2:
> >> - rename alias to match convention
> >>
> >>  arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 15 +++++++++++++++
> >>  1 file changed, 15 insertions(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> >> index ed96f27c64a3..c4da6436059d 100644
> >> --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> >> +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
> >> @@ -17,6 +17,7 @@
> >>  		ethernet0 = &gmac0;
> >>  		ethernet1 = &gmac1;
> > 
> >>  		mmc0 = &sdhci;
> >> +		mmc1 = &sdmmc0;
> > 
> > mmc aliases are sort on reg address based on availability without number
> > gap.
> > 
> > 	sdmmc0: mmc at fe2b0000 {}
> > 	sdhci: mmc at fe310000 {}
> 
> I'll turn these around.
> 
> >>  	};
> >>  
> >>  	chosen: chosen {
> >> @@ -353,6 +354,20 @@
> >>  	status = "okay";
> >>  };
> >>  
> >> +&sdmmc0 {
> >> +	bus-width = <4>;
> >> +	cap-sd-highspeed;
> >> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
> >> +	disable-wp;
> > 
> >> +	pinctrl-names = "default";
> >> +	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
> > 
> > pinctrl-names below pinctrl-0 like the rest of rk356x.dtsi
> 
> OK!
> 
> >> +	sd-uhs-sdr104;
> > 
> >> +	supports-sd;
> > 
> > Check mmc-controller.yaml, rockchip-dw-mshc.yaml and
> > synopsys-dw-mshc-common.yaml for properties.
> 
> I am afraid I don't quite follow. What exactly should I check? I am
> pretty sure that the properties I used are described in the mentioned
> yaml files.
> 
> Regards, Michael
> 
> > 
> >> +	vmmc-supply = <&vcc3v3_sd>;
> >> +	vqmmc-supply = <&vccio_sd>;
> >> +	status = "okay";
> >> +};
> >> +
> >>  &uart2 {
> >>  	status = "okay";
> >>  };
> >>
> 






From s-anna at ti.com  Wed Aug  4 12:17:22 2021
From: s-anna at ti.com (Suman Anna)
Date: Wed, 4 Aug 2021 14:17:22 -0500
Subject: [PATCH v2 1/5] remoteproc: Add support for detach-only during
 shutdown
In-Reply-To: <20210803162311.GB3091608@p14s>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-2-s-anna@ti.com> <20210802184431.GC3051951@p14s>
 <cd399fef-6db7-72eb-933f-7454a043ed14@ti.com> <20210803162311.GB3091608@p14s>
Message-ID: <7e264184-60ea-a035-7bd3-1fc2c76a160d@ti.com>

Hi Mathieu,

On 8/3/21 11:23 AM, Mathieu Poirier wrote:
> Good morning,
> 
> On Mon, Aug 02, 2021 at 06:21:38PM -0500, Suman Anna wrote:
>> Hi Mathieu,
>>
>> On 8/2/21 1:44 PM, Mathieu Poirier wrote:
>>> On Fri, Jul 23, 2021 at 05:02:44PM -0500, Suman Anna wrote:
>>>> The remoteproc core has support for both stopping and detaching a
>>>> remote processor that was attached to previously, through both the
>>>> remoteproc sysfs and cdev interfaces. The rproc_shutdown() though
>>>> unconditionally only uses the stop functionality at present. This
>>>> may not be the default desired functionality for all the remoteproc
>>>> platform drivers.
>>>>
>>>> Enhance the remoteproc core logic to key off the presence of the
>>>> .stop() ops and allow the individual remoteproc drivers to continue
>>>> to use the standard rproc_add() and rproc_del() API. This allows
>>>> the remoteproc drivers to only do detach if supported when the driver
>>>> is uninstalled, and the remote processor continues to run undisturbed
>>>> even after the driver removal.
>>>>
>>>> Signed-off-by: Suman Anna <s-anna at ti.com>
>>>> ---
>>>> v2: Addressed various review comments from v1
>>>>  - Reworked the logic to not use remoteproc detach_on_shutdown and
>>>>    rely only on rproc callback ops
>>>>  - Updated the last para of the patch description
>>>> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-3-s-anna at ti.com/
>>>>
>>>>  drivers/remoteproc/remoteproc_cdev.c  | 7 +++++++
>>>>  drivers/remoteproc/remoteproc_core.c  | 5 ++++-
>>>>  drivers/remoteproc/remoteproc_sysfs.c | 6 ++++++
>>>>  3 files changed, 17 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c
>>>> index 4ad98b0b8caa..16c932beed88 100644
>>>> --- a/drivers/remoteproc/remoteproc_cdev.c
>>>> +++ b/drivers/remoteproc/remoteproc_cdev.c
>>>> @@ -42,6 +42,13 @@ static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_
>>>>  		    rproc->state != RPROC_ATTACHED)
>>>>  			return -EINVAL;
>>>>  
>>>> +		if (rproc->state == RPROC_ATTACHED &&
>>>
>>> This is already checked just above.
>>>
>>>> +		    !rproc->ops->stop) {
>>
>> Well, this is checking for both conditions, and not just the stop ops
>> independently. We expect to have .stop() defined normally for both regular
>> remoteproc mode and attached mode where you want to stop (and not detach), but
>> as you can see, I am supporting only detach and so will not have .stop() defined
>>  with RPROC_ATTACHED.
>>
>>>
>>> This is checked in rproc_stop() where -EINVAL is returned if ops::stop has not
>>> been provided.
>>
>> rproc_shutdown() actually doesn't return any status, so all its internal
>> checking gets ignored and a success is returned today.
>>
> 
> That is correct, and I have suggested to add a return value in my previous
> review.

Yeah ok. I can add a separate patch fixing that, and couple of these checks then
become redundant.

> 
>>>
>>>> +			dev_err(&rproc->dev,
>>>> +				"stop not supported for this rproc, use detach\n");
>>>
>>> The standard error message from the shell should be enough here, the same way it
>>> is enough when the "start" and "stop" scenarios fail.
>>
>> Thought this was a bit more informative, but sure this trace can be dropped.
>>
>>>
>>>> +			return -EINVAL;
>>>> +		}
>>>> +
>>>>  		rproc_shutdown(rproc);
>>>>  	} else if (!strncmp(cmd, "detach", len)) {
>>>>  		if (rproc->state != RPROC_ATTACHED)
>>>> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
>>>> index 7de5905d276a..ab9e52180b04 100644
>>>> --- a/drivers/remoteproc/remoteproc_core.c
>>>> +++ b/drivers/remoteproc/remoteproc_core.c
>>>> @@ -2075,7 +2075,10 @@ void rproc_shutdown(struct rproc *rproc)
>>>>  	if (!atomic_dec_and_test(&rproc->power))
>>>>  		goto out;
>>>>  
>>>> -	ret = rproc_stop(rproc, false);
>>>> +	if (rproc->state == RPROC_ATTACHED && !rproc->ops->stop)
>>>> +		ret = __rproc_detach(rproc);
>>>> +	else
>>>> +		ret = rproc_stop(rproc, false);
>>>
>>> As I indicated in my last review I think rproc_shutdown() and rproc_del() should
>>> be decoupled and the right call made in the platform drivers based on the state
>>> of the remote processor.  
>>
>> We have various remoteproc API provided in pairs - rproc_alloc()/rproc_free(),
>> rproc_add()/rproc_del(), rproc_boot()/rproc_shutdown() and
>> rproc_attach()/rproc_detach(). The drivers are configuring conditions for
>> auto-boot and RPROC_DETACHED. The reason they are coupled is primarily because
>> of the auto-boot done during rproc_add(). And we handle the RPROC_DETACHED case
>> just as well in rproc_boot().
>>
> 
> The difference with rproc_boot() is that we are checking only the state of the
> remoteproc, everything else related to the remote processor operations is
> seamlessly handles by the state machine.  It is also tied to the
> rproc_trigger_auto_boot() mechanic - decoupling that would be messy without
> bringing any advantages other than keeping with a semantic symmetry.

Most of this is actually tied to auto_boot if you think about it, not just the
rproc state. If we have auto_boot set to false, then rproc_add() would not do
anything, and the decision to start or attach can either be done through the
sysfs/cdev or a kernel remoteproc or some consumer driver. And the state machine
is getting influenced by this flag. auto-boot is a very useful feature.

You are asking is to do things differently between the regular start/stop case
and attach/detach case ignoring the auto-boot. The semantic symmetry actually
makes it easier to follow the state machine given that there are some internal
reference counts as well.

Note that we also have the devres API, and rproc_alloc()/rproc_free() and
rproc_add()/rproc_del() form the main remoteproc subsystem API. The drivers
would end up using matching calls if we don't have auto_boot.

> 
>> While what you have suggested works, but I am not quite convinced on this
>> asymmetric usage, and why this state-machine logic should be split between the
>> core and remoteproc drivers differently between attach and detach. To me,
>> calling rproc_detach() in remoteproc drivers would have made sense only if they
>> are also calling rproc_attach().
> 
> As pointed out above I see rproc_boot() as a special case but if that really
> concerns you I'm open to consider patches that will take rproc_attach() out of
> rproc_boot(). 
> 

We are talking about a bigger behavioral change to remoteproc core here. So I
would definitely want to hear from others as well on this before we spend any
time reworking code.

Meanwhile, how do I take this series forward? One option I can probably do is
turn off auto-boot for early-boot case in my drivers and do the matching
attach/detach.

regards
Suman

>>
>>
>> Conditions such as the above make the core code
>>> brittle, difficult to understand and tedious to maintain.
>>
>> The logic I have added actually makes rproc_shutdown behavior to be on par with
>> the rproc_boot().
>>
>> regards
>> Suman
>>
>>>
>>> Thanks,
>>> Mathieu
>>>
>>>>  	if (ret) {
>>>>  		atomic_inc(&rproc->power);
>>>>  		goto out;
>>>> diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
>>>> index ea8b89f97d7b..133e766f38d4 100644
>>>> --- a/drivers/remoteproc/remoteproc_sysfs.c
>>>> +++ b/drivers/remoteproc/remoteproc_sysfs.c
>>>> @@ -206,6 +206,12 @@ static ssize_t state_store(struct device *dev,
>>>>  		    rproc->state != RPROC_ATTACHED)
>>>>  			return -EINVAL;
>>>>  
>>>> +		if (rproc->state == RPROC_ATTACHED &&
>>>> +		    !rproc->ops->stop) {
>>>> +			dev_err(&rproc->dev, "stop not supported for this rproc, use detach\n");
>>>> +			return -EINVAL;
>>>> +		}
>>>> +
>>>>  		rproc_shutdown(rproc);
>>>>  	} else if (sysfs_streq(buf, "detach")) {
>>>>  		if (rproc->state != RPROC_ATTACHED)
>>>> -- 
>>>> 2.32.0
>>>>
>>



From raagjadav at gmail.com  Wed Aug  4 12:24:44 2021
From: raagjadav at gmail.com (Raag Jadav)
Date: Thu,  5 Aug 2021 00:54:44 +0530
Subject: [PATCH v2 0/2] fix eeprom entries for ls1046afrwy and ls1046ardb
Message-ID: <1628105086-8172-1-git-send-email-raagjadav@gmail.com>

This series fixes eeprom entries for ls1046afrwy and ls1046ardb boards.

Changes since v1:
- Update patch description.
- Add bindings for ON Semi CAT24C04 and CAT24C05 eeproms.

Raag Jadav (2):
  arm64: dts: ls1046a: fix eeprom entries
  dt-bindings: at24: add ON Semi CAT24C04 and CAT24C05

 Documentation/devicetree/bindings/eeprom/at24.yaml | 6 ++++++
 arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +-------
 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts  | 7 +------
 3 files changed, 8 insertions(+), 13 deletions(-)

-- 
2.7.4



From raagjadav at gmail.com  Wed Aug  4 12:24:45 2021
From: raagjadav at gmail.com (Raag Jadav)
Date: Thu,  5 Aug 2021 00:54:45 +0530
Subject: [PATCH v2 1/2] arm64: dts: ls1046a: fix eeprom entries
In-Reply-To: <1628105086-8172-1-git-send-email-raagjadav@gmail.com>
References: <1628105086-8172-1-git-send-email-raagjadav@gmail.com>
Message-ID: <1628105086-8172-2-git-send-email-raagjadav@gmail.com>

ls1046afrwy and ls1046ardb boards have CAT24C04[1] and CAT24C05[2]
eeproms respectively. Both are 4Kb (512 bytes) in size,
and compatible with AT24C04[3].
Remove multi-address entries, as both the boards have a single chip each.

[1] https://www.onsemi.com/pdf/datasheet/cat24c01-d.pdf
[2] https://www.onsemi.com/pdf/datasheet/cat24c03-d.pdf
[3] https://ww1.microchip.com/downloads/en/DeviceDoc/doc0180.pdf

Signed-off-by: Raag Jadav <raagjadav at gmail.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +-------
 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts  | 7 +------
 2 files changed, 2 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
index db3d303..6d22efb 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
@@ -83,15 +83,9 @@
 			};
 
 			eeprom at 52 {
-				compatible = "atmel,24c512";
+				compatible = "onnn,cat24c04", "atmel,24c04";
 				reg = <0x52>;
 			};
-
-			eeprom at 53 {
-				compatible = "atmel,24c512";
-				reg = <0x53>;
-			};
-
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
index 60acdf0..7025aad 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
@@ -59,14 +59,9 @@
 	};
 
 	eeprom at 52 {
-		compatible = "atmel,24c512";
+		compatible = "onnn,cat24c05", "atmel,24c04";
 		reg = <0x52>;
 	};
-
-	eeprom at 53 {
-		compatible = "atmel,24c512";
-		reg = <0x53>;
-	};
 };
 
 &i2c3 {
-- 
2.7.4



From raagjadav at gmail.com  Wed Aug  4 12:24:46 2021
From: raagjadav at gmail.com (Raag Jadav)
Date: Thu,  5 Aug 2021 00:54:46 +0530
Subject: [PATCH v2 2/2] dt-bindings: at24: add ON Semi CAT24C04 and CAT24C05
In-Reply-To: <1628105086-8172-1-git-send-email-raagjadav@gmail.com>
References: <1628105086-8172-1-git-send-email-raagjadav@gmail.com>
Message-ID: <1628105086-8172-3-git-send-email-raagjadav@gmail.com>

Add bindings for ON Semi CAT24C04 and CAT24C05 eeproms,
which are compatible with Atmel AT24C04.

Signed-off-by: Raag Jadav <raagjadav at gmail.com>
---
 Documentation/devicetree/bindings/eeprom/at24.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/eeprom/at24.yaml b/Documentation/devicetree/bindings/eeprom/at24.yaml
index 914a423..4c5396a 100644
--- a/Documentation/devicetree/bindings/eeprom/at24.yaml
+++ b/Documentation/devicetree/bindings/eeprom/at24.yaml
@@ -98,6 +98,12 @@ properties:
           - const: nxp,se97b
           - const: atmel,24c02
       - items:
+          - const: onnn,cat24c04
+          - const: atmel,24c04
+      - items:
+          - const: onnn,cat24c05
+          - const: atmel,24c04
+      - items:
           - const: renesas,r1ex24002
           - const: atmel,24c02
       - items:
-- 
2.7.4



From bjorn.andersson at linaro.org  Wed Aug  4 12:30:42 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Wed,  4 Aug 2021 12:30:42 -0700
Subject: [PATCH] arm64: defconfig: Enable Qualcomm MSM8996 CPU clock driver
Message-ID: <20210804193042.1155398-1-bjorn.andersson@linaro.org>

The MSM8996 supports CPU frequency scaling, so enable the clock driver
for this.

Signed-off-by: Bjorn Andersson <bjorn.andersson at linaro.org>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c7cf0d1ad34e..3bf6f8a86aae 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -974,6 +974,7 @@ CONFIG_TI_SCI_CLK=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_QCOM_A53PLL=y
 CONFIG_QCOM_CLK_APCS_MSM8916=y
+CONFIG_QCOM_CLK_APCC_MSM8996=y
 CONFIG_QCOM_CLK_SMD_RPM=y
 CONFIG_QCOM_CLK_RPMH=y
 CONFIG_IPQ_GCC_8074=y
-- 
2.29.2



From linus.walleij at linaro.org  Wed Aug  4 12:27:59 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed,  4 Aug 2021 21:27:59 +0200
Subject: [PATCH v2] ARM: Fix Keystone 2 kernel mapping regression
Message-ID: <20210804192759.750112-1-linus.walleij@linaro.org>

This fixes a Keystone 2 regression discovered as a side effect of
defining an passing the physical start/end sections of the kernel
to the MMU remapping code.

As the Keystone applies an offset to all physical addresses,
including those identified and patches by phys2virt, we fail to
account for this offset in the kernel_sec_start and kernel_sec_end
variables.

Further these offsets can extend into the 64bit range on LPAE
systems such as the Keystone 2.

Fix it like this:
- Extend kernel_sec_start and kernel_sec_end to be 64bit
- Add the offset also to kernel_sec_start and kernel_sec_end

As passing kernel_sec_start and kernel_sec_end as 64bit invariably
incurs BE8 endianness issues I have attempted to dry-code around
these.

Tested on the Vexpress QEMU model both with and without LPAE
enabled.

Fixes: 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel separately")
Reported-by: Nishanth Menon <nmenon at kernel.org>
Suggested-by: Russell King <linux at armlinux.org.uk>
Tested-by: Grygorii Strashko <grygorii.strashko at ti.com>
Tested-by: Nishanth Menon <nmenon at kernel.org>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
ChangeLog v1->v2:
- Better assembly, pass the #4 addition along in the str instruction
  str r8, [r5, #4]
- Collect Tested-by tags from successful boot tests on Keystone 2.
- I will put this into Russell's patch tracker immediately.
---
 arch/arm/include/asm/memory.h |  7 ++++---
 arch/arm/kernel/head.S        | 17 ++++++++++++++---
 arch/arm/mm/mmu.c             |  9 ++++++++-
 arch/arm/mm/pv-fixup-asm.S    |  2 +-
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index cfc9dfd70aad..f673e13e0f94 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -160,10 +160,11 @@ extern unsigned long vectors_base;
 
 /*
  * Physical start and end address of the kernel sections. These addresses are
- * 2MB-aligned to match the section mappings placed over the kernel.
+ * 2MB-aligned to match the section mappings placed over the kernel. We use
+ * u64 so that LPAE mappings beyond the 32bit limit will work out as well.
  */
-extern u32 kernel_sec_start;
-extern u32 kernel_sec_end;
+extern u64 kernel_sec_start;
+extern u64 kernel_sec_end;
 
 /*
  * Physical vs virtual RAM address space conversion.  These are
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 9eb0b4dbcc12..b6fc92d4cf23 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -49,7 +49,8 @@
 
 	/*
 	 * This needs to be assigned at runtime when the linker symbols are
-	 * resolved.
+	 * resolved. These are unsigned 64bit really, but in this assembly code
+	 * We store them as 32bit.
 	 */
 	.pushsection .data
 	.align	2
@@ -57,7 +58,9 @@
 	.globl	kernel_sec_end
 kernel_sec_start:
 	.long	0
+	.long	0
 kernel_sec_end:
+	.long	0
 	.long	0
 	.popsection
 
@@ -250,7 +253,11 @@ __create_page_tables:
 	add	r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ORDER)
 	ldr	r6, =(_end - 1)
 	adr_l	r5, kernel_sec_start		@ _pa(kernel_sec_start)
-	str	r8, [r5]			@ Save physical start of kernel
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	str	r8, [r5, #4]			@ Save physical start of kernel (BE)
+#else
+	str	r8, [r5]			@ Save physical start of kernel (LE)
+#endif
 	orr	r3, r8, r7			@ Add the MMU flags
 	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
 1:	str	r3, [r0], #1 << PMD_ORDER
@@ -259,7 +266,11 @@ __create_page_tables:
 	bls	1b
 	eor	r3, r3, r7			@ Remove the MMU flags
 	adr_l	r5, kernel_sec_end		@ _pa(kernel_sec_end)
-	str	r3, [r5]			@ Save physical end of kernel
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	str	r8, [r5, #4]			@ Save physical end of kernel (BE)
+#else
+	str	r3, [r5]			@ Save physical end of kernel (LE)
+#endif
 
 #ifdef CONFIG_XIP_KERNEL
 	/*
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 7583bda5ea7d..a4e006005107 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1608,6 +1608,13 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
 	if (offset == 0)
 		return;
 
+	/*
+	 * Offset the kernel section physical offsets so that the kernel
+	 * mapping will work out later on.
+	 */
+	kernel_sec_start += offset;
+	kernel_sec_end += offset;
+
 	/*
 	 * Get the address of the remap function in the 1:1 identity
 	 * mapping setup by the early page table assembly code.  We
@@ -1716,7 +1723,7 @@ void __init paging_init(const struct machine_desc *mdesc)
 {
 	void *zero_page;
 
-	pr_debug("physical kernel sections: 0x%08x-0x%08x\n",
+	pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
 		 kernel_sec_start, kernel_sec_end);
 
 	prepare_page_table();
diff --git a/arch/arm/mm/pv-fixup-asm.S b/arch/arm/mm/pv-fixup-asm.S
index 5c5e1952000a..f8e11f7c7880 100644
--- a/arch/arm/mm/pv-fixup-asm.S
+++ b/arch/arm/mm/pv-fixup-asm.S
@@ -29,7 +29,7 @@ ENTRY(lpae_pgtables_remap_asm)
 	ldr	r6, =(_end - 1)
 	add	r7, r2, #0x1000
 	add	r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
-	add	r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER)
+	add	r7, r7, #KERNEL_OFFSET >> (SECTION_SHIFT - L2_ORDER)
 1:	ldrd	r4, r5, [r7]
 	adds	r4, r4, r0
 	adc	r5, r5, r1
-- 
2.31.1



From konrad.dybcio at somainline.org  Wed Aug  4 12:46:29 2021
From: konrad.dybcio at somainline.org (Konrad Dybcio)
Date: Wed, 4 Aug 2021 21:46:29 +0200
Subject: [PATCH] arm64: defconfig: Enable Qualcomm MSM8996 CPU clock driver
In-Reply-To: <20210804193042.1155398-1-bjorn.andersson@linaro.org>
References: <20210804193042.1155398-1-bjorn.andersson@linaro.org>
Message-ID: <bd464d12-6d1c-fff0-9119-fe4ff9d3c5ba@somainline.org>


On 04.08.2021 21:30, Bjorn Andersson wrote:
> The MSM8996 supports CPU frequency scaling, so enable the clock driver
> for this.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson at linaro.org>

Acked-by: Konrad Dybcio <konrad.dybcio at somainline.org>


> ---
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index c7cf0d1ad34e..3bf6f8a86aae 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -974,6 +974,7 @@ CONFIG_TI_SCI_CLK=y
>  CONFIG_COMMON_CLK_QCOM=y
>  CONFIG_QCOM_A53PLL=y
>  CONFIG_QCOM_CLK_APCS_MSM8916=y
> +CONFIG_QCOM_CLK_APCC_MSM8996=y
>  CONFIG_QCOM_CLK_SMD_RPM=y
>  CONFIG_QCOM_CLK_RPMH=y
>  CONFIG_IPQ_GCC_8074=y


From sunilmut at microsoft.com  Wed Aug  4 13:10:43 2021
From: sunilmut at microsoft.com (Sunil Muthuswamy)
Date: Wed, 4 Aug 2021 20:10:43 +0000
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <87r1f9wooc.wl-maz@kernel.org>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com> <87r1f9wooc.wl-maz@kernel.org>
Message-ID: <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>

On Wednesday, August 4, 2021 2:21 AM,
Marc Zyngier <maz at kernel.org> wrote:
>
> On Tue, 03 Aug 2021 09:35:12 +0100,
> Robin Murphy <robin.murphy at arm.com> wrote:
> >
> > On 2021-08-03 03:11, Sunil Muthuswamy wrote:
> > >   On Saturday, July 31, 2021 2:52 AM,
> > >   Marc Zyngier <maz at kernel.org> wrote:
> > >>
> > >> [...]
> > >>
> > >>>> I also want to understand *how* you are going to plumb this into both
> > >>>> ACPI and DT, given that neither understand how to link a PCI endpoint
> > >>>> to a set of RDs.
> > >>>>
> > >>>> 	M.
> > >>>
> > >>> One way to do this for NUMA-aware systems would be to use the NUMA
> > >>> related information that is available with PCI endpoints or root complex, to
> > >>> pick a Redistributor/CPU that is in the NUMA node, as specified by the PCI
> > >>> endpoint/root complex. In DT PCI devices can specify this using
> > >>> 'numa-node-id' and in ACPI using the '_PXM (Proximity)'. For systems that
> > >>> are not NUMA-aware, we can go with *any* Redistributor/CPU.
> > >>
> > >> This makes zero sense. From the point of view of a device, all the RDs
> > >> should be reachable, and firmware has no say in it. Dealing with
> > >> interrupt affinity is the responsibility of the endpoint driver, and
> > >> NUMA affinity is only a performance optimisation.
> > >>
> > >>> Is there any additional information we would be able to gather from ACPI
> > >>> or DT that's not there currently, that would be useful here?
> > >>
> > >> You will need some firmware information describing that a given set of
> > >> devices must use the RDs for their MSIs. Just like we currently
> > >> describe it in IORT for the ITS. You cannot /assume/ things. At the
> > >> moment, there is nothing at all, because no-one (including Microsoft)
> > >> thought it would be a good idea not to have an ITS, which is also why
> > >> ACPI doesn't describe MBIs as a potential MSI provider.
> > >>
> > > I am a little bit confused by your above comment. Maybe you can help me
> > > understand the ask. You indicate that from the point of the view of the
> > > device, all the RDs should be reachable. But, then if we define a mapping
> > > between PCI endpoint and RD in the firmware, we would be doing exactly
> > > the opposite. i.e. restricting the RDs that are reachable by the device. Can
> > > you please clarify?
> 
> Not at all. What I am saying is that you need to describe that the
> MSIs have to be routed to the RDs, and there is no way to express this
> at the moment.
> 
> > >
> > > Is your concern that the device should be able to only DMA to a subset of
> > > GIC Redistributor, for the MSIs? If so, in the IORT, there is "memory address
> > > size limit" for both device and root complex nodes. In the implementation,
> > > we can enforce that the GICR is within that range. And, if a device deviates
> > > further than that (ex: by having accessibility gaps within the GICR range),
> > > then that is out of scope for support.
> >
> > No, please don't try to abuse the Memory Address Size Limit - that has
> > far more chance of adversely affecting normal DMA operation than of
> > being any use here.
> >
> > I believe the point Marc was trying to make is that firmware should
> > not associate a device with any one *specific* redistributor, however
> > ACPI currently has no way to describe that MSIs can target
> > redistributors *at all*, only ITS groups - there is no such concept as
> > a "redistributor group".
> 
> Thanks Robin.
> 
> That is exactly my point. There is no linkage whatsoever between a
> device generating MSIs and the redistributors. In that respect, this
> is the same issue we have with DT, as none of the firmware interfaces
> can currently describe MSIs directly targeting the RDs. The only way
> to describe MSIs with GICv3 in ACPI is to describe an ITS, and you
> cannot use the *absence* of an ITS to decide and use DirectLPIs.
> 
> Given the state of things, using DirectLPI means that you need to
> extend the firmware interfaces. This means both an extension to the DT
> binding, and an update to the ACPI spec. There is no way around this.
> 
> Thanks,
> 
> 	M.
> 
Thanks Marc and Robin for clarifying. I see and understand the point
about having explicit MSI mappings in the firmware specification for
Direct LPIs for generic hardware support.

Hey Mark, would you be willing to consider a scoped down implementation of
GIC Direct LPI with just an IRQ chip implementation and no
Direct LPI PCI-MSI IRQ chip. This will allow a MSI provider (such as Hyper-V vPCI) to
provide a PCI-MSI IRQ chip on top of the Direct LPI IRQ chip and enable
PCI-MSI scenarios, and avoid building in assumptions in other cases (like PCI) where
firmware specification is not available.
- This scoped down implementation would allow Microsoft to build virtual
PCI on top, to enable our business needs.
- If there's a need for a generic support for a Direct LPI PCI MSI IRQ, that could
drive firmware revision efforts, and we are happy to assist there.

Looking forward to hearing back.

Thanks,
Sunil


From cristian.marussi at arm.com  Wed Aug  4 13:57:15 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 4 Aug 2021 21:57:15 +0100
Subject: [PATCH v2] firmware: arm_scmi: Free mailbox channels if probe
 fails
In-Reply-To: <1628099499-27394-1-git-send-email-rishabhb@codeaurora.org>
References: <1628099499-27394-1-git-send-email-rishabhb@codeaurora.org>
Message-ID: <20210804205715.GT6592@e120937-lin>

On Wed, Aug 04, 2021 at 10:51:39AM -0700, Rishabh Bhatnagar wrote:
> Mailbox channels for the base protocol are setup during probe.
> There can be a scenario where probe fails to acquire the base
> protocol due to a timeout leading to cleaning up of all device
> managed memory including the scmi_mailbox structure setup during
> mailbox_chan_setup function.
> [   12.735104]arm-scmi soc:qcom,scmi: timed out in resp(caller: version_get+0x84/0x140)
> [   12.735224]arm-scmi soc:qcom,scmi: unable to communicate with SCMI
> [   12.735947]arm-scmi: probe of soc:qcom,scmi failed with error -110
> 
> Now when a message arrives at cpu slightly after the timeout, the mailbox
> controller will try to call the rx_callback of the client and might end
> up accessing freed memory.
> [   12.758363][    C0] Call trace:
> [   12.758367][    C0]  rx_callback+0x24/0x160
> [   12.758372][    C0]  mbox_chan_received_data+0x44/0x94
> [   12.758386][    C0]  __handle_irq_event_percpu+0xd4/0x240
> This patch frees the mailbox channels setup during probe and adds some more
> error handling in case the probe fails.
> 
> Signed-off-by: Rishabh Bhatnagar <rishabhb at codeaurora.org>
> ---

Hi,

>  drivers/firmware/arm_scmi/driver.c | 35 ++++++++++++++++++++++++-----------
>  1 file changed, 24 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 9b2e8d4..aab2ac1 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -1390,6 +1390,21 @@ void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table)
>  	mutex_unlock(&scmi_requested_devices_mtx);
>  }
>  
> +static int cleanup_txrx_channels(struct scmi_info *info)
> +{
> +	int ret;
> +	struct idr *idr = &info->tx_idr;
> +
> +	ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
> +	idr_destroy(&info->tx_idr);
> +
> +	idr = &info->rx_idr;
> +	ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
> +	idr_destroy(&info->rx_idr);
> +
> +	return ret;
> +}
> +

Sorry for being pedantic but the preferred naming for the function
should be scmi_cleanup_txrx_channels()

>  static int scmi_probe(struct platform_device *pdev)
>  {
>  	int ret;
> @@ -1430,7 +1445,7 @@ static int scmi_probe(struct platform_device *pdev)
>  
>  	ret = scmi_xfer_info_init(info);
>  	if (ret)
> -		return ret;
> +		goto clear_txrx_setup;
>  
>  	if (scmi_notification_init(handle))
>  		dev_err(dev, "SCMI Notifications NOT available.\n");
> @@ -1443,7 +1458,7 @@ static int scmi_probe(struct platform_device *pdev)
>  	ret = scmi_protocol_acquire(handle, SCMI_PROTOCOL_BASE);
>  	if (ret) {
>  		dev_err(dev, "unable to communicate with SCMI\n");
> -		return ret;
> +		goto notification_exit;
>  	}
>  
>  	mutex_lock(&scmi_list_mutex);
> @@ -1482,6 +1497,12 @@ static int scmi_probe(struct platform_device *pdev)
>  	}
>  
>  	return 0;
> +
> +notification_exit:
> +	scmi_notification_exit(&info->handle);
> +clear_txrx_setup:
> +	cleanup_txrx_channels(info);
> +	return ret;
>  }
>  
>  void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id)
> @@ -1493,7 +1514,6 @@ static int scmi_remove(struct platform_device *pdev)
>  {
>  	int ret = 0, id;
>  	struct scmi_info *info = platform_get_drvdata(pdev);
> -	struct idr *idr = &info->tx_idr;
>  	struct device_node *child;
>  
>  	mutex_lock(&scmi_list_mutex);
> @@ -1517,14 +1537,7 @@ static int scmi_remove(struct platform_device *pdev)
>  	idr_destroy(&info->active_protocols);
>  
>  	/* Safe to free channels since no more users */
> -	ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
> -	idr_destroy(&info->tx_idr);
> -
> -	idr = &info->rx_idr;
> -	ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
> -	idr_destroy(&info->rx_idr);
> -
> -	return ret;
> +	return cleanup_txrx_channels(info);
>  }
>  

Maybe also a Fixes: tag could be appropriate, but I'm not so sure you
could easily identify one common commit to use given that notifications
have been added later and the code around scmi_protocol_acquire() has
been changed recently too. (in such a case just ignore the Fixes tag
suggestion)

Other than the above remarks,

Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>

Thanks,
Cristian


From martin.blumenstingl at googlemail.com  Wed Aug  4 14:03:57 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Wed, 4 Aug 2021 23:03:57 +0200
Subject: [PATCH v3 2/2] remoteproc: meson-mx-ao-arc: Add a driver for the
 AO ARC remote procesor
In-Reply-To: <20210728175823.GA2766167@p14s>
References: <20210717234859.351911-1-martin.blumenstingl@googlemail.com>
 <20210717234859.351911-3-martin.blumenstingl@googlemail.com>
 <20210728175823.GA2766167@p14s>
Message-ID: <CAFBinCB0-bAa7Y+YhscczarGrGuio37F8vRyfW6U2DiiDAvr-g@mail.gmail.com>

Hi Mathieu,

thanks for taking the time to look into this!

(I will address any of your comments that I am not mentioning in this
email anymore. Thanks a lot for the suggestions!)

On Wed, Jul 28, 2021 at 7:58 PM Mathieu Poirier
<mathieu.poirier at linaro.org> wrote:
[...]
> > +     writel(FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
> > +                            priv->sram_pa >> 14),
> Indentation problem
The idea here is to align priv->sram_pa with AO_REMAP_REG0... which
are both arguments to FIELD_PREP
Maybe using something like this will make that easier to read:
    tmp = FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
                                     priv->sram_pa >> 14);
    writel(tmp, priv->remap_base + AO_REMAP_REG0);

What do you think: leave it as is or use a separate variable?

[...]
> > +     usleep_range(10, 100);
>
> I've seen this kind of mysterious timeouts in other patchset based vendor trees.
> You likely don't know why it is needed so I won't ask.
unfortunately this is also the case here

[...]
> > +     priv->arc_reset = devm_reset_control_get_exclusive(dev, NULL);
> > +     if (IS_ERR(priv->arc_reset)) {
>
> Function __reset_control_get() in __devm_reset_control_get() can return NULL so
> this should be IS_ERR_OR_NULL().
The logic in there is: return optional ? NULL : ERR_PTR(-...);
I am requesting a mandatory reset line here, so reset core will never
return NULL
See also [0]

For this reason I am not planning to change this

[...]
> This driver is squeaky clean. With the above:
>
> Reviewed-by: Mathieu Poirier <mathieu.poirier at linaro.org>
awesome, thank you!


Best regards,
Martin


[0] https://elixir.bootlin.com/linux/v5.14-rc4/source/include/linux/reset.h#L227


From semen.protsenko at linaro.org  Wed Aug  4 14:30:34 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 5 Aug 2021 00:30:34 +0300
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <bf21badb-804f-45f0-c02b-80ff57ab9931@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
 <bf21badb-804f-45f0-c02b-80ff57ab9931@canonical.com>
Message-ID: <CAPLW+4nY=hozOR+B_0sPZODrk9PXaXg+NB-9pVhDbAjEy7yjhg@mail.gmail.com>

On Wed, 4 Aug 2021 at 21:36, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 04/08/2021 16:39, Sam Protsenko wrote:
> > Hi Marc,
> >
> > On Fri, 30 Jul 2021 at 19:50, Marc Zyngier <maz at kernel.org> wrote:
> >>
> >> On 2021-07-30 15:49, Sam Protsenko wrote:
> >>> Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
> >>>
> >>> Features:
> >>>  * CPU: Cortex-A55 Octa (8 cores), up to 2 GHz
> >>>  * Memory interface: LPDDR4/4x 2 channels (12.8 GB/s)
> >>>  * SD/MMC: SD 3.0, eMMC5.1 DDR 8-bit
> >>>  * Modem: 4G LTE, 3G, GSM/GPRS/EDGE
> >>>  * RF: Quad GNSS, WiFi 5 (802.11ac), Bluetooth 5.0
> >>>  * GPU: Mali-G52 MP1
> >>>  * Codec: 1080p 60fps H64, HEVC, JPEG HW Codec
> >>>  * Display: Full HD+ (2520x1080)@60fps LCD
> >>>  * Camera: 16+5MP/13+8MP ISP, MIPI CSI 4/4/2, FD, DRC
> >>>  * Connectivity: USB 2.0 DRD, USI (SPI/UART/I2C), HSI2C, I3C, ADC,
> >>> Audio
> >>>
> >>> This patch adds minimal SoC support. Particular board device tree files
> >>> can include exynos850.dtsi file to get SoC related nodes, and then
> >>> reference those nodes further as needed.
> >>>
> >>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> >>> ---
> >>>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
> >>>  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
> >>>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
> >>>  3 files changed, 1057 insertions(+)
> >>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
> >>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
> >>>
> >>> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >>> b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >>> new file mode 100644
> >>> index 000000000000..4cf0a22cc6db
> >>
> >> [...]
> >>
> >>> +     gic: interrupt-controller at 12a00000 {
> >>> +             compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
> >>
> >> One thing for sure, it cannot be both. And given that it is
> >> an A55-based SoC, it isn't either. It is more likely a GIC400.
> >>
> >
> > Yes, it's GIC-400, thanks for pointing that out. Will fix that in v2.
> >
> >>> +             #interrupt-cells = <3>;
> >>> +             #address-cells = <0>;
> >>> +             interrupt-controller;
> >>> +             reg = <0x0 0x12a01000 0x1000>,
> >>> +                   <0x0 0x12a02000 0x1000>,
> >>
> >> This is wrong. It is architecturally set to 8kB.
> >>
> >
> > Nice catch! Actually there is an error (typo?) in SoC's TRM, saying
> > that Virtual Interface Control Register starts at 0x3000 offset (from
> > 0x12a00000), where it obviously should be 0x4000, that's probably
> > where this dts error originates from. Btw, I'm also seeing the same
> > error in exynos7.dtsi.
>
> What's the error exactly? The "Virtual interface control register"
> offset (3rd region) is set properly to 0x4000 on Exynos7. Also one for
> the Exynos5433 looks correct.
>

The issue is that 2nd region's size is 0x1000, but it must be 0x2000.
It's defined by GIC-400 architecture, as I understand. Please look at
[1], table 3-1 has very specific offsets and sizes for each functional
block, and each particular SoC must adhere to that spec. So having
0x1000 for 2nd region can't be correct. And because exynos7.dtsi has
GIC-400 as well, and 0x1000 is specified there for 2nd region size
too, so I presume there is the same mistake there.

Can you please check the TRM for Exynos7 SoC (if you have one in your
possession), and see if there is a typo there? E.g. in case of
Exynos850 TRM I can see that in "Register Map Summary" section the
offset for the first register (GICH_HCR) in "Virtual Interface Control
Register" region is specified as 0x3000, where it should be 0x4000, so
it's probably a typo. But the register description is correct, saying
that: "Address = Base Address + 0x4000".

[1] https://developer.arm.com/documentation/ddi0471/b/programmers-model/gic-400-register-map

> > Though I don't have a TRM for Exynos7 SoCs, so
> > not sure if I should go ahead and fix that too. Anyway, for Exynos850,
> > I'll fix that in v2 series.
>
>
> However while we are at addresses - why are you using address-cells 2?
> It adds everywhere additional 0x0 before actual address.
>

Right. For "cpus" node I'll change the address-cells to 1 in my v2
series. I'll keep address-cells=2 for the root node, but I'm going to
encapsulate some nodes into soc node (as you suggested earlier), where
I'll make address-cells=1. That's pretty much how it's done in
exynos7.dtsi and in exynos5433.dtsi, so I guess that's should be fine
(to get rid of superfluous 0x0 and conform with other Exynos DTs)?

>
> Best regards,
> Krzysztof


From saravanak at google.com  Wed Aug  4 14:47:24 2021
From: saravanak at google.com (Saravana Kannan)
Date: Wed, 4 Aug 2021 14:47:24 -0700
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
Message-ID: <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>

On Wed, Aug 4, 2021 at 11:20 AM Saravana Kannan <saravanak at google.com> wrote:
>
> On Wed, Aug 4, 2021 at 1:50 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Wed, 04 Aug 2021 02:36:45 +0100,
> > Saravana Kannan <saravanak at google.com> wrote:
> >
> > Hi Saravana,
> >
> > Thanks for looking into this.
>
> You are welcome. I just don't want people to think fw_devlink is broken :)
>
> >
> > [...]
> >
> > > > Saravana, could you please have a look from a fw_devlink perspective?
> > >
> > > Sigh... I spent several hours looking at this and wrote up an analysis
> > > and then realized I might be looking at the wrong DT files.
> > >
> > > Marc, can you point me to the board file in upstream that corresponds
> > > to the platform in which you see this issue? I'm not asking for [1],
> > > but the actual final .dts (not .dtsi) file that corresponds to the
> > > platform/board/system.
> >
> > The platform I can reproduce this on is described in
> > arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts. It is an
> > intricate maze of inclusion, node merge and other DT subtleties. I
> > suggest you look at the decompiled version to get a view of the
> > result.
>
> Thanks. After decompiling it, it looks something like (stripped a
> bunch of reg and address properties and added the labels back):
>
> eth_phy: mdio-multiplexer at 4c000 {
>         compatible = "amlogic,g12a-mdio-mux";
>         clocks = <0x02 0x13 0x1e 0x02 0xb1>;
>         clock-names = "pclk\0clkin0\0clkin1";
>         mdio-parent-bus = <0x22>;
>
>         ext_mdio: mdio at 0 {
>                 reg = <0x00>;
>
>                 ethernet-phy at 0 {
>                         max-speed = <0x3e8>;
>                         interrupt-parent = <0x23>;
>                         interrupts = <0x1a 0x08>;
>                         phandle = <0x16>;
>                 };
>         };
>
>         int_mdio: mdio at 1 {
>                 ...
>         }
> }
>
> And phandle 0x23 refers to the gpio_intc interrupt controller with the
> modular driver.
>
> > > Based on your error messages, it's failing for mdio at 0 which
> > > corresponds to ext_mdio. But none of the board dts files in upstream
> > > have a compatible property for "ext_mdio". Which means fw_devlink
> > > _should_ propagate the gpio_intc IRQ dependency all the way up to
> > > eth_phy.
> > >
> > > Also, in the failing case, can you run:
> > > ls -ld supplier:*
> > >
> > > in the /sys/devices/....<something>/ folder that corresponds to the
> > > "eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?
> >
> > Here you go:
> >
> > root at tiger-roach:~# find /sys/devices/ -name 'supplier*'|grep -i mdio | xargs ls -ld
> > lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/platform/soc/ff600000.bus/ff64c000.mdio-multiplexer/supplier:platform:ff63c000.system-controller:clock-controller -> ../../../../virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer
>
> As we discussed over chat, this was taken after the mdio-multiplexer
> driver "successfully" probes this device. This will cause
> SYNC_STATE_ONLY device links created by fw_devlink to be deleted
> (because they are useless after a device probes). So, this doesn't
> show the info I was hoping to demonstrate.
>
> In any case, one can see that fw_devlink properly created the device
> link for the clocks dependency. So fw_devlink is parsing this node
> properly. But it doesn't create a similar probe order enforcing device
> link between the mdio-multiplexer and the gpio_intc because the
> dependency is only present in a grand child DT node (ethernet-phy at 0
> under ext_mdio). So fw_devlink is working as intended.
>
> I spent several hours squinting at the code/DT yesterday. Here's what
> is going on and causing the problem:
>
> The failing driver in this case is
> drivers/net/mdio/mdio-mux-meson-g12a.c. And the only DT node it's
> handling is what I pasted above in this email. In the failure case,
> the call flow is something like this:
>
> g12a_mdio_mux_probe()
> -> mdio_mux_init()
> -> of_mdiobus_register(ext_mdio DT node)
> -> of_mdiobus_register_phy(ext_mdio DT node)
> -> several calls deep fwnode_mdiobus_phy_device_register(ethernet_phy DT node)
> -> Tried to get the IRQ listed in ethernet_phy and fails with
> -EPROBE_DEFER because the IRQ driver isn't loaded yet.
>
> The error is propagated correctly all the way up to of_mdiobus_register(), but
> mdio_mux_init() ignores the -EPROBE_DEFER from of_mdiobus_register() and just
> continues on with the rest of the stuff and returns success as long as
> one of the child nodes (in this case int_mdio) succeeds.
>
> Since the probe returns 0 without really succeeding, networking stuff
> just fails badly after this. So, IMO, the real problem is with
> mdio_mux_init() not propagating up the -EPROBE_DEFER. I gave Marc a
> quick hack (pasted at the end of this email) to test my theory and he
> confirmed that it fixes the issue (a few deferred probes later, things
> work properly).
>
> Andrew, I don't see any good reason for mdio_mux_init() not
> propagating the errors up correctly (at least for EPROBE_DEFER). I'll
> send a patch to fix this. Please let me know if there's a reason it
> has to stay as-is.

I sent out the proper fix as a series:
https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t

Marc, can you give it a shot please?

-Saravana

>
> -Saravana
>
> index 110e4ee85785..d973a267151f 100644
> --- a/drivers/net/mdio/mdio-mux.c
> +++ b/drivers/net/mdio/mdio-mux.c
> @@ -170,6 +170,9 @@ int mdio_mux_init(struct device *dev,
>                                 child_bus_node);
>                         mdiobus_free(cb->mii_bus);
>                         devm_kfree(dev, cb);
> +                       /* Not a final fix. I think it can cause UAF issues. */
> +                       mdio_mux_uninit(pb);
> +                       return r;
>                 } else {
>                         cb->next = pb->children;
>                         pb->children = cb;


From martin.blumenstingl at googlemail.com  Wed Aug  4 14:58:23 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Wed, 4 Aug 2021 23:58:23 +0200
Subject: [PATCHv2 1/4] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <CAFBinCAohjxcsY3D1rdAiYVGL+==cnjzZxg1GmYxSNVhxSTDoA@mail.gmail.com>
References: <20210716103651.1455-1-linux.amoon@gmail.com>
 <20210716103651.1455-2-linux.amoon@gmail.com>
 <CAFBinCDeqauw_V-Vn9cat9HaCXj6HEMz6G+G+VbqCNtGEFGYzg@mail.gmail.com>
 <CANAwSgQ5PDGUWMH-jxnz5wwutUVniTn7RAe=4J=8-jbmqxYRRg@mail.gmail.com>
 <CAFBinCBhg+dije+3DvV_V_kqHv9q+r4EPxXCYFti6KuA4mK7KQ@mail.gmail.com>
 <CANAwSgT9-5zGr67aGzBmW6WDBfeiAvjv_zv2UbRC+YbgAGg==A@mail.gmail.com>
 <CAFBinCCGA0b=LVjbQood+iN+DHLodY0RJ-GrSOcgdzrDFJ25pQ@mail.gmail.com>
 <CAFBinCAohjxcsY3D1rdAiYVGL+==cnjzZxg1GmYxSNVhxSTDoA@mail.gmail.com>
Message-ID: <CAFBinCAP_DDvPLn4h1yQKEdU_x1ovokHUTPeq3vNV_sDF8PcWg@mail.gmail.com>

On Sun, Jul 18, 2021 at 9:09 PM Martin Blumenstingl
<martin.blumenstingl at googlemail.com> wrote:
>
> Hi Anand,
>
> On Sun, Jul 18, 2021 at 4:01 PM Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
> [...]
> > > From the schematics [1]
> > > https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20160226.pdf
> > >
> > > You could find references to PWREN  <--- GPIOAO.BIT5
> > > The second reference is USB HOST Power Switch
> > > The third reference is USB HOST POWER.
> > >
> > > Hope I am clean in my thought process now.
> > Can you please point out the page numbers for me?
> >
> > What I am seeing on page 1 is:
> > GPIOAO_5 (called GPIOAO.BIT5) is connected as an INPUT to the USB_OTG
> > PWREN signal (that's the green box with the label "USB_OTG.SchDoc"
> > above it).
> I unfortunately missed your question on IRC on this topic:
> <armoon> xdarklight: just want to understand the confusion on PWREN,
> either is INPUT / OTPUT to usb hub am I correct
> My understanding of the INPUT/OUTPUT direction in the Odroid-C1
> schematics (which you linked) above is that the arrow direction shows
> whether it's an input or output.
> For example (all on page one):
> - HDMI_HPD is an input to the Meson8b SoC, arrow direction is: HDMI => S805
> - IR_IN is an input to the Meson8b SoC, arrow direction is: S805 <=
> GPIOAO.BIT7 IR_IN
> - PWM is an output, arrow direction is: S805 => PWM.C VCCK_PWM
> - 3.3V/1.8V switch for the SD card is an output, arrow direction is:
> S805 => GPIOAO.BIT3 TF_3V3N_1V8_EN
>
> That tells me: the arrow direction shows which connections are inputs
> or outputs.
> Some pins can be input and output at the same time (HDMI_CEC). But
> let's keep it simple for now any only look at inputs/output.
>
> Based on this information I am looking at the arrow direction for
> USB_OTG: GPIOAO.BIT5 PWREN <= S805
> So this confirms that GPIOAO_5 is an output to the SoC.
> Please note though that this part is not linked with any USB host
> connector, it's only linked to the USB OTG path.
>
> For the next part the S805 SoC is not involved:
> USB1 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> USB2 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> This tells me that the PWREN signal for the two USB_HOST_PWR_SW (USB
> host power switches / current limiters) is driven by the GL852G USB
> hub.
Hardkernel team responded on the Odroid forums to the request from Anand:
"Power-Enable signal to the USB load switch ICs is connected to the
USB hub controller.
It is not connected the CPU GPIO."

The regulator from Anand's patch is therefore connected to the micro USB port.
This means that the patch needs updating in case Anand wants to have
it included.


Best regards,
Martin


[0] https://forum.odroid.com/viewtopic.php?p=332217#p332217


From oupton at google.com  Wed Aug  4 15:03:21 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 4 Aug 2021 15:03:21 -0700
Subject: [PATCH v6 00/21] KVM: Add idempotent controls for migrating
 system counter state
In-Reply-To: <CAOQ_QsiVNS==c-ahnKN6Jja_+FfkWEmDnQPoP9sdNWBc1m2gsg@mail.gmail.com>
References: <20210804085819.846610-1-oupton@google.com>
 <CAOQ_QsiVNS==c-ahnKN6Jja_+FfkWEmDnQPoP9sdNWBc1m2gsg@mail.gmail.com>
Message-ID: <CAOQ_Qsh9wzP301xdfbwBcFXHBoYkf9PCY-+mrfmfwVWL4UexGw@mail.gmail.com>

On Wed, Aug 4, 2021 at 4:05 AM Oliver Upton <oupton at google.com> wrote:
>
> On Wed, Aug 4, 2021 at 1:58 AM Oliver Upton <oupton at google.com> wrote:
> >
> > KVM's current means of saving/restoring system counters is plagued with
> > temporal issues. At least on ARM64 and x86, we migrate the guest's
> > system counter by-value through the respective guest system register
> > values (cntvct_el0, ia32_tsc). Restoring system counters by-value is
> > brittle as the state is not idempotent: the host system counter is still
> > oscillating between the attempted save and restore. Furthermore, VMMs
> > may wish to transparently live migrate guest VMs, meaning that they
> > include the elapsed time due to live migration blackout in the guest
> > system counter view. The VMM thread could be preempted for any number of
> > reasons (scheduler, L0 hypervisor under nested) between the time that
> > it calculates the desired guest counter value and when KVM actually sets
> > this counter state.
> >
> > Despite the value-based interface that we present to userspace, KVM
> > actually has idempotent guest controls by way of system counter offsets.
> > We can avoid all of the issues associated with a value-based interface
> > by abstracting these offset controls in new ioctls. This series
> > introduces new vCPU device attributes to provide userspace access to the
> > vCPU's system counter offset.
> >
> > Patch 1 addresses a possible race in KVM_GET_CLOCK where
> > use_master_clock is read outside of the pvclock_gtod_sync_lock.
> >
> > Patch 2 adopts Paolo's suggestion, augmenting the KVM_{GET,SET}_CLOCK
> > ioctls to provide userspace with a (host_tsc, realtime) instant. This is
> > essential for a VMM to perform precise migration of the guest's system
> > counters.
> >
> > Patches 3-4 are some preparatory changes for exposing the TSC offset to
> > userspace. Patch 5 provides a vCPU attribute to provide userspace access
> > to the TSC offset.
> >
> > Patches 6-7 implement a test for the new additions to
> > KVM_{GET,SET}_CLOCK.
> >
> > Patch 8 fixes some assertions in the kvm device attribute helpers.
> >
> > Patches 9-10 implement at test for the tsc offset attribute introduced in
> > patch 5.
> >
> > Patches 11-12 lay the groundwork for patch 13, which exposes CNTVOFF_EL2
> > through the ONE_REG interface.
> >
> > Patches 14-15 add test cases for userspace manipulation of the virtual
> > counter-timer.
> >
> > Patches 16-17 add a vCPU attribute to adjust the host-guest offset of an
> > ARM vCPU, but only implements support for ECV hosts. Patches 18-19 add
> > support for non-ECV hosts by emulating physical counter offsetting.
> >
> > Patch 20 adds test cases for adjusting the host-guest offset, and
> > finally patch 21 adds a test to measure the emulation overhead of
> > CNTPCT_EL2.
> >
> > This series was tested on both an Ampere Mt. Jade and Haswell systems.
> > Unfortunately, the ECV portions of this series are untested, as there is
> > no ECV-capable hardware and the ARM fast models only partially implement
> > ECV.
>
> Small correction: I was only using the foundation model. Apparently
> the AEM FVP provides full ECV support.

Ok. I've now tested this series on the FVP Base RevC fast model at v8.6 +
ECV=2. Passes on VHE, fails on nVHE.

I'll respin this series with the fix for nVHE+ECV soon.

--
Thanks,
Oliver

>
> >
> > Physical counter benchmark
> > --------------------------
> >
> > The following data was collected by running 10000 iterations of the
> > benchmark test from Patch 21 on an Ampere Mt. Jade reference server, A 2S
> > machine with 2 80-core Ampere Altra SoCs. Measurements were collected
> > for both VHE and nVHE operation using the `kvm-arm.mode=` command-line
> > parameter.
> >
> > nVHE
> > ----
> >
> > +--------------------+--------+---------+
> > |       Metric       | Native | Trapped |
> > +--------------------+--------+---------+
> > | Average            | 54ns   | 148ns   |
> > | Standard Deviation | 124ns  | 122ns   |
> > | 95th Percentile    | 258ns  | 348ns   |
> > +--------------------+--------+---------+
> >
> > VHE
> > ---
> >
> > +--------------------+--------+---------+
> > |       Metric       | Native | Trapped |
> > +--------------------+--------+---------+
> > | Average            | 53ns   | 152ns   |
> > | Standard Deviation | 92ns   | 94ns    |
> > | 95th Percentile    | 204ns  | 307ns   |
> > +--------------------+--------+---------+
> >
> > This series applies cleanly to kvm/queue at the following commit:
> >
> > 6cd974485e25 ("KVM: selftests: Add a test of an unbacked nested PI descriptor")
> >
> > v1 -> v2:
> >   - Reimplemented as vCPU device attributes instead of a distinct ioctl.
> >   - Added the (realtime, host_tsc) instant support to KVM_{GET,SET}_CLOCK
> >   - Changed the arm64 implementation to broadcast counter
> >     offset values to all vCPUs in a guest. This upholds the
> >     architectural expectations of a consistent counter-timer across CPUs.
> >   - Fixed a bug with traps in VHE mode. We now configure traps on every
> >     transition into a guest to handle differing VMs (trapped, emulated).
> >
> > v2 -> v3:
> >   - Added documentation for additions to KVM_{GET,SET}_CLOCK
> >   - Added documentation for all new vCPU attributes
> >   - Added documentation for suggested algorithm to migrate a guest's
> >     TSC(s)
> >   - Bug fixes throughout series
> >   - Rename KVM_CLOCK_REAL_TIME -> KVM_CLOCK_REALTIME
> >
> > v3 -> v4:
> >   - Added patch to address incorrect device helper assertions (Drew)
> >   - Carried Drew's r-b tags where appropriate
> >   - x86 selftest cleanup
> >   - Removed stale kvm_timer_init_vhe() function
> >   - Removed unnecessary GUEST_DONE() from selftests
> >
> > v4 -> v5:
> >   - Fix typo in TSC migration algorithm
> >   - Carry more of Drew's r-b tags
> >   - clean up run loop logic in counter emulation benchmark (missed from
> >     Drew's comments on v3)
> >
> > v5 -> v6:
> >   - Add fix for race in KVM_GET_CLOCK (Sean)
> >   - Fix 32-bit build issues in series + use of uninitialized host tsc
> >     value (Sean)
> >   - General style cleanups
> >   - Rework ARM virtual counter offsetting to match guest behavior. Use
> >     the ONE_REG interface instead of a VM attribute (Marc)
> >   - Maintain a single host-guest counter offset, which applies to both
> >     physical and virtual counters
> >   - Dropped some of Drew's r-b tags due to nontrivial patch changes
> >     (sorry for the churn!)
> >
> > v1: https://lore.kernel.org/kvm/20210608214742.1897483-1-oupton at google.com/
> > v2: https://lore.kernel.org/r/20210716212629.2232756-1-oupton at google.com
> > v3: https://lore.kernel.org/r/20210719184949.1385910-1-oupton at google.com
> > v4: https://lore.kernel.org/r/20210729001012.70394-1-oupton at google.com
> > v5: https://lore.kernel.org/r/20210729173300.181775-1-oupton at google.com
> >
> > Oliver Upton (21):
> >   KVM: x86: Fix potential race in KVM_GET_CLOCK
> >   KVM: x86: Report host tsc and realtime values in KVM_GET_CLOCK
> >   KVM: x86: Take the pvclock sync lock behind the tsc_write_lock
> >   KVM: x86: Refactor tsc synchronization code
> >   KVM: x86: Expose TSC offset controls to userspace
> >   tools: arch: x86: pull in pvclock headers
> >   selftests: KVM: Add test for KVM_{GET,SET}_CLOCK
> >   selftests: KVM: Fix kvm device helper ioctl assertions
> >   selftests: KVM: Add helpers for vCPU device attributes
> >   selftests: KVM: Introduce system counter offset test
> >   KVM: arm64: Refactor update_vtimer_cntvoff()
> >   KVM: arm64: Separate guest/host counter offset values
> >   KVM: arm64: Allow userspace to configure a vCPU's virtual offset
> >   selftests: KVM: Add helper to check for register presence
> >   selftests: KVM: Add support for aarch64 to system_counter_offset_test
> >   arm64: cpufeature: Enumerate support for Enhanced Counter
> >     Virtualization
> >   KVM: arm64: Allow userspace to configure a guest's counter-timer
> >     offset
> >   KVM: arm64: Configure timer traps in vcpu_load() for VHE
> >   KVM: arm64: Emulate physical counter offsetting on non-ECV systems
> >   selftests: KVM: Test physical counter offsetting
> >   selftests: KVM: Add counter emulation benchmark
> >
> >  Documentation/virt/kvm/api.rst                |  52 ++-
> >  Documentation/virt/kvm/devices/vcpu.rst       |  85 ++++
> >  Documentation/virt/kvm/locking.rst            |  11 +
> >  arch/arm64/include/asm/kvm_asm.h              |   2 +
> >  arch/arm64/include/asm/sysreg.h               |   5 +
> >  arch/arm64/include/uapi/asm/kvm.h             |   2 +
> >  arch/arm64/kernel/cpufeature.c                |  10 +
> >  arch/arm64/kvm/arch_timer.c                   | 224 ++++++++++-
> >  arch/arm64/kvm/arm.c                          |   4 +-
> >  arch/arm64/kvm/guest.c                        |   6 +-
> >  arch/arm64/kvm/hyp/include/hyp/switch.h       |  29 ++
> >  arch/arm64/kvm/hyp/nvhe/hyp-main.c            |   6 +
> >  arch/arm64/kvm/hyp/nvhe/timer-sr.c            |  16 +-
> >  arch/arm64/kvm/hyp/vhe/timer-sr.c             |   5 +
> >  arch/arm64/tools/cpucaps                      |   1 +
> >  arch/x86/include/asm/kvm_host.h               |   4 +
> >  arch/x86/include/uapi/asm/kvm.h               |   4 +
> >  arch/x86/kvm/x86.c                            | 364 +++++++++++++-----
> >  include/clocksource/arm_arch_timer.h          |   1 +
> >  include/kvm/arm_arch_timer.h                  |   6 +-
> >  include/uapi/linux/kvm.h                      |   7 +-
> >  tools/arch/x86/include/asm/pvclock-abi.h      |  48 +++
> >  tools/arch/x86/include/asm/pvclock.h          | 103 +++++
> >  tools/testing/selftests/kvm/.gitignore        |   3 +
> >  tools/testing/selftests/kvm/Makefile          |   4 +
> >  .../kvm/aarch64/counter_emulation_benchmark.c | 207 ++++++++++
> >  .../selftests/kvm/include/aarch64/processor.h |  24 ++
> >  .../testing/selftests/kvm/include/kvm_util.h  |  13 +
> >  tools/testing/selftests/kvm/lib/kvm_util.c    |  63 ++-
> >  .../kvm/system_counter_offset_test.c          | 211 ++++++++++
> >  .../selftests/kvm/x86_64/kvm_clock_test.c     | 204 ++++++++++
> >  31 files changed, 1581 insertions(+), 143 deletions(-)
> >  create mode 100644 tools/arch/x86/include/asm/pvclock-abi.h
> >  create mode 100644 tools/arch/x86/include/asm/pvclock.h
> >  create mode 100644 tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
> >  create mode 100644 tools/testing/selftests/kvm/system_counter_offset_test.c
> >  create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
> >
> > --
> > 2.32.0.605.g8dce9f2422-goog
> >


From nm at ti.com  Wed Aug  4 15:19:58 2021
From: nm at ti.com (Nishanth Menon)
Date: Wed, 4 Aug 2021 17:19:58 -0500
Subject: [PATCH v2] ARM: Fix Keystone 2 kernel mapping regression
In-Reply-To: <20210804192759.750112-1-linus.walleij@linaro.org>
References: <20210804192759.750112-1-linus.walleij@linaro.org>
Message-ID: <20210804221958.mxhwa2jj2l65gvru@nintendo>

On 21:27-20210804, Linus Walleij wrote:
> This fixes a Keystone 2 regression discovered as a side effect of
> defining an passing the physical start/end sections of the kernel
> to the MMU remapping code.
> 
> As the Keystone applies an offset to all physical addresses,
> including those identified and patches by phys2virt, we fail to
> account for this offset in the kernel_sec_start and kernel_sec_end
> variables.
> 
> Further these offsets can extend into the 64bit range on LPAE
> systems such as the Keystone 2.
> 
> Fix it like this:
> - Extend kernel_sec_start and kernel_sec_end to be 64bit
> - Add the offset also to kernel_sec_start and kernel_sec_end
> 
> As passing kernel_sec_start and kernel_sec_end as 64bit invariably
> incurs BE8 endianness issues I have attempted to dry-code around
> these.
> 
> Tested on the Vexpress QEMU model both with and without LPAE
> enabled.
> 
> Fixes: 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel separately")
> Reported-by: Nishanth Menon <nmenon at kernel.org>
> Suggested-by: Russell King <linux at armlinux.org.uk>
> Tested-by: Grygorii Strashko <grygorii.strashko at ti.com>
> Tested-by: Nishanth Menon <nmenon at kernel.org>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> Signed-off-by: Nishanth Menon <nm at ti.com>
> Link: https://lore.kernel.org/r/20210804192759.750112-1-linus.walleij at linaro.org
> ---
> ChangeLog v1->v2:
> - Better assembly, pass the #4 addition along in the str instruction
>   str r8, [r5, #4]
> - Collect Tested-by tags from successful boot tests on Keystone 2.
> - I will put this into Russell's patch tracker immediately.
> ---

Recheck still looks good:
k2g-ice: https://pastebin.ubuntu.com/p/xchg8F6T8z/
k2g-evm: https://pastebin.ubuntu.com/p/zrJCQhVdrk/
k2hk-evm: https://pastebin.ubuntu.com/p/zj5qwkNppv/


Thanks.
-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From bjorn.andersson at linaro.org  Wed Aug  4 15:23:54 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Wed, 4 Aug 2021 17:23:54 -0500
Subject: [PATCH v3] drivers/soc: Remove all strcpy() uses
In-Reply-To: <20210801131958.6144-1-len.baker@gmx.com>
References: <20210801131958.6144-1-len.baker@gmx.com>
Message-ID: <YQsTesvLfAwd8z5B@builder.lan>

On Sun 01 Aug 08:19 CDT 2021, Len Baker wrote:

> strcpy() performs no bounds checking on the destination buffer. This
> could result in linear overflows beyond the end of the buffer, leading
> to all kinds of misbehaviors. The safe replacement is strscpy().
> 

While this is true, are any of these uses of strcpy affected by its
shortcomings?

> Moreover, when the size of the destination buffer cannot be obtained
> using "sizeof", use the memcpy function instead of strscpy.
> 

This is not why you're using memcpy, you're using it because you _know_
how many bytes should be copied - because you just did a strlen() and
allocated that amount of space.

> Signed-off-by: Len Baker <len.baker at gmx.com>
> ---
> This is a task of the KSPP [1]
> 
> [1] https://github.com/KSPP/linux/issues/88
> 
> Changelog v1 -> v2
> - Change the "area_name_size" variable for a shorter name (Geert
>   Uytterhoeven).
> - Add the "Reviewed-by: Geert Uytterhoeven" tag.
> - Use the memcpy function instead of strscpy function when the
>   size of the destination buffer cannot be obtained with "sizeof"
>   (David Laight, Robin Murphy).
> 
> Changelog v2 -> v3
> - Remove the "Reviewed-by: Geert Uytterhoeven" tag since the code
>   has changed after the v1 review (use of memcpy instead of
>   strscpy).
> 
>  drivers/soc/qcom/pdr_interface.c    | 13 +++++++------
>  drivers/soc/renesas/r8a779a0-sysc.c |  6 ++++--
>  drivers/soc/renesas/rcar-sysc.c     |  6 ++++--
>  drivers/soc/ti/knav_dma.c           |  2 +-
>  4 files changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c
> index 915d5bc3d46e..cf119fde749d 100644
> --- a/drivers/soc/qcom/pdr_interface.c
> +++ b/drivers/soc/qcom/pdr_interface.c
> @@ -131,7 +131,7 @@ static int pdr_register_listener(struct pdr_handle *pdr,
>  		return ret;
> 
>  	req.enable = enable;
> -	strcpy(req.service_path, pds->service_path);
> +	strscpy(req.service_path, pds->service_path, sizeof(req.service_path));
> 
>  	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
>  			       &txn, SERVREG_REGISTER_LISTENER_REQ,
> @@ -257,7 +257,7 @@ static int pdr_send_indack_msg(struct pdr_handle *pdr, struct pdr_service *pds,
>  		return ret;
> 
>  	req.transaction_id = tid;
> -	strcpy(req.service_path, pds->service_path);
> +	strscpy(req.service_path, pds->service_path, sizeof(req.service_path));
> 
>  	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
>  			       &txn, SERVREG_SET_ACK_REQ,
> @@ -406,7 +406,7 @@ static int pdr_locate_service(struct pdr_handle *pdr, struct pdr_service *pds)
>  		return -ENOMEM;
> 
>  	/* Prepare req message */
> -	strcpy(req.service_name, pds->service_name);
> +	strscpy(req.service_name, pds->service_name, sizeof(req.service_name));
>  	req.domain_offset_valid = true;
>  	req.domain_offset = 0;
> 
> @@ -531,8 +531,8 @@ struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr,
>  		return ERR_PTR(-ENOMEM);
> 
>  	pds->service = SERVREG_NOTIFIER_SERVICE;
> -	strcpy(pds->service_name, service_name);
> -	strcpy(pds->service_path, service_path);
> +	strscpy(pds->service_name, service_name, sizeof(pds->service_name));
> +	strscpy(pds->service_path, service_path, sizeof(pds->service_path));
>  	pds->need_locator_lookup = true;
> 
>  	mutex_lock(&pdr->list_lock);
> @@ -587,7 +587,8 @@ int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds)
>  			break;
> 
>  		/* Prepare req message */
> -		strcpy(req.service_path, pds->service_path);
> +		strscpy(req.service_path, pds->service_path,
> +			sizeof(req.service_path));

There's no need to break this line.

Thanks,
Bjorn

>  		addr = pds->addr;
>  		break;
>  	}
> diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
> index d464ffa1be33..7410b9fa9846 100644
> --- a/drivers/soc/renesas/r8a779a0-sysc.c
> +++ b/drivers/soc/renesas/r8a779a0-sysc.c
> @@ -404,19 +404,21 @@ static int __init r8a779a0_sysc_pd_init(void)
>  	for (i = 0; i < info->num_areas; i++) {
>  		const struct r8a779a0_sysc_area *area = &info->areas[i];
>  		struct r8a779a0_sysc_pd *pd;
> +		size_t n;
> 
>  		if (!area->name) {
>  			/* Skip NULLified area */
>  			continue;
>  		}
> 
> -		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
> +		n = strlen(area->name) + 1;
> +		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
>  		if (!pd) {
>  			error = -ENOMEM;
>  			goto out_put;
>  		}
> 
> -		strcpy(pd->name, area->name);
> +		memcpy(pd->name, area->name, n);
>  		pd->genpd.name = pd->name;
>  		pd->pdr = area->pdr;
>  		pd->flags = area->flags;
> diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
> index 53387a72ca00..b0a80de34c98 100644
> --- a/drivers/soc/renesas/rcar-sysc.c
> +++ b/drivers/soc/renesas/rcar-sysc.c
> @@ -396,19 +396,21 @@ static int __init rcar_sysc_pd_init(void)
>  	for (i = 0; i < info->num_areas; i++) {
>  		const struct rcar_sysc_area *area = &info->areas[i];
>  		struct rcar_sysc_pd *pd;
> +		size_t n;
> 
>  		if (!area->name) {
>  			/* Skip NULLified area */
>  			continue;
>  		}
> 
> -		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
> +		n = strlen(area->name) + 1;
> +		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
>  		if (!pd) {
>  			error = -ENOMEM;
>  			goto out_put;
>  		}
> 
> -		strcpy(pd->name, area->name);
> +		memcpy(pd->name, area->name, n);
>  		pd->genpd.name = pd->name;
>  		pd->ch.chan_offs = area->chan_offs;
>  		pd->ch.chan_bit = area->chan_bit;
> diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c
> index 591d14ebcb11..5f9816d317a5 100644
> --- a/drivers/soc/ti/knav_dma.c
> +++ b/drivers/soc/ti/knav_dma.c
> @@ -691,7 +691,7 @@ static int dma_init(struct device_node *cloud, struct device_node *dma_node)
>  	dma->max_rx_flow = max_rx_flow;
>  	dma->max_tx_chan = min(max_tx_chan, max_tx_sched);
>  	atomic_set(&dma->ref_count, 0);
> -	strcpy(dma->name, node->name);
> +	strscpy(dma->name, node->name, sizeof(dma->name));
>  	spin_lock_init(&dma->lock);
> 
>  	for (i = 0; i < dma->max_tx_chan; i++) {
> --
> 2.25.1
> 


From bjorn.andersson at linaro.org  Wed Aug  4 15:34:43 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Wed, 4 Aug 2021 17:34:43 -0500
Subject: [PATCH v3] drivers/soc: Remove all strcpy() uses
In-Reply-To: <20210801131958.6144-1-len.baker@gmx.com>
References: <20210801131958.6144-1-len.baker@gmx.com>
Message-ID: <YQsWA0iyol+EWoPd@builder.lan>

On Sun 01 Aug 08:19 CDT 2021, Len Baker wrote:

> strcpy() performs no bounds checking on the destination buffer. This
> could result in linear overflows beyond the end of the buffer, leading
> to all kinds of misbehaviors. The safe replacement is strscpy().
> 
> Moreover, when the size of the destination buffer cannot be obtained
> using "sizeof", use the memcpy function instead of strscpy.
> 
> Signed-off-by: Len Baker <len.baker at gmx.com>

Forgot one thing, it's unclear who should pick this patch up and there's
definitely a chance that it will cause merge conflicts regardless of
whom of us end up picking it.

Could you please split it so that the qcom, renesas and ti pieces can be
picked up by respective maintainer?

Thanks,
Bjorn

> ---
> This is a task of the KSPP [1]
> 
> [1] https://github.com/KSPP/linux/issues/88
> 
> Changelog v1 -> v2
> - Change the "area_name_size" variable for a shorter name (Geert
>   Uytterhoeven).
> - Add the "Reviewed-by: Geert Uytterhoeven" tag.
> - Use the memcpy function instead of strscpy function when the
>   size of the destination buffer cannot be obtained with "sizeof"
>   (David Laight, Robin Murphy).
> 
> Changelog v2 -> v3
> - Remove the "Reviewed-by: Geert Uytterhoeven" tag since the code
>   has changed after the v1 review (use of memcpy instead of
>   strscpy).
> 
>  drivers/soc/qcom/pdr_interface.c    | 13 +++++++------
>  drivers/soc/renesas/r8a779a0-sysc.c |  6 ++++--
>  drivers/soc/renesas/rcar-sysc.c     |  6 ++++--
>  drivers/soc/ti/knav_dma.c           |  2 +-
>  4 files changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c
> index 915d5bc3d46e..cf119fde749d 100644
> --- a/drivers/soc/qcom/pdr_interface.c
> +++ b/drivers/soc/qcom/pdr_interface.c
> @@ -131,7 +131,7 @@ static int pdr_register_listener(struct pdr_handle *pdr,
>  		return ret;
> 
>  	req.enable = enable;
> -	strcpy(req.service_path, pds->service_path);
> +	strscpy(req.service_path, pds->service_path, sizeof(req.service_path));
> 
>  	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
>  			       &txn, SERVREG_REGISTER_LISTENER_REQ,
> @@ -257,7 +257,7 @@ static int pdr_send_indack_msg(struct pdr_handle *pdr, struct pdr_service *pds,
>  		return ret;
> 
>  	req.transaction_id = tid;
> -	strcpy(req.service_path, pds->service_path);
> +	strscpy(req.service_path, pds->service_path, sizeof(req.service_path));
> 
>  	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
>  			       &txn, SERVREG_SET_ACK_REQ,
> @@ -406,7 +406,7 @@ static int pdr_locate_service(struct pdr_handle *pdr, struct pdr_service *pds)
>  		return -ENOMEM;
> 
>  	/* Prepare req message */
> -	strcpy(req.service_name, pds->service_name);
> +	strscpy(req.service_name, pds->service_name, sizeof(req.service_name));
>  	req.domain_offset_valid = true;
>  	req.domain_offset = 0;
> 
> @@ -531,8 +531,8 @@ struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr,
>  		return ERR_PTR(-ENOMEM);
> 
>  	pds->service = SERVREG_NOTIFIER_SERVICE;
> -	strcpy(pds->service_name, service_name);
> -	strcpy(pds->service_path, service_path);
> +	strscpy(pds->service_name, service_name, sizeof(pds->service_name));
> +	strscpy(pds->service_path, service_path, sizeof(pds->service_path));
>  	pds->need_locator_lookup = true;
> 
>  	mutex_lock(&pdr->list_lock);
> @@ -587,7 +587,8 @@ int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds)
>  			break;
> 
>  		/* Prepare req message */
> -		strcpy(req.service_path, pds->service_path);
> +		strscpy(req.service_path, pds->service_path,
> +			sizeof(req.service_path));
>  		addr = pds->addr;
>  		break;
>  	}
> diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
> index d464ffa1be33..7410b9fa9846 100644
> --- a/drivers/soc/renesas/r8a779a0-sysc.c
> +++ b/drivers/soc/renesas/r8a779a0-sysc.c
> @@ -404,19 +404,21 @@ static int __init r8a779a0_sysc_pd_init(void)
>  	for (i = 0; i < info->num_areas; i++) {
>  		const struct r8a779a0_sysc_area *area = &info->areas[i];
>  		struct r8a779a0_sysc_pd *pd;
> +		size_t n;
> 
>  		if (!area->name) {
>  			/* Skip NULLified area */
>  			continue;
>  		}
> 
> -		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
> +		n = strlen(area->name) + 1;
> +		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
>  		if (!pd) {
>  			error = -ENOMEM;
>  			goto out_put;
>  		}
> 
> -		strcpy(pd->name, area->name);
> +		memcpy(pd->name, area->name, n);
>  		pd->genpd.name = pd->name;
>  		pd->pdr = area->pdr;
>  		pd->flags = area->flags;
> diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
> index 53387a72ca00..b0a80de34c98 100644
> --- a/drivers/soc/renesas/rcar-sysc.c
> +++ b/drivers/soc/renesas/rcar-sysc.c
> @@ -396,19 +396,21 @@ static int __init rcar_sysc_pd_init(void)
>  	for (i = 0; i < info->num_areas; i++) {
>  		const struct rcar_sysc_area *area = &info->areas[i];
>  		struct rcar_sysc_pd *pd;
> +		size_t n;
> 
>  		if (!area->name) {
>  			/* Skip NULLified area */
>  			continue;
>  		}
> 
> -		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
> +		n = strlen(area->name) + 1;
> +		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
>  		if (!pd) {
>  			error = -ENOMEM;
>  			goto out_put;
>  		}
> 
> -		strcpy(pd->name, area->name);
> +		memcpy(pd->name, area->name, n);
>  		pd->genpd.name = pd->name;
>  		pd->ch.chan_offs = area->chan_offs;
>  		pd->ch.chan_bit = area->chan_bit;
> diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c
> index 591d14ebcb11..5f9816d317a5 100644
> --- a/drivers/soc/ti/knav_dma.c
> +++ b/drivers/soc/ti/knav_dma.c
> @@ -691,7 +691,7 @@ static int dma_init(struct device_node *cloud, struct device_node *dma_node)
>  	dma->max_rx_flow = max_rx_flow;
>  	dma->max_tx_chan = min(max_tx_chan, max_tx_sched);
>  	atomic_set(&dma->ref_count, 0);
> -	strcpy(dma->name, node->name);
> +	strscpy(dma->name, node->name, sizeof(dma->name));
>  	spin_lock_init(&dma->lock);
> 
>  	for (i = 0; i < dma->max_tx_chan; i++) {
> --
> 2.25.1
> 


From linus.walleij at linaro.org  Wed Aug  4 16:01:58 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 5 Aug 2021 01:01:58 +0200
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
Message-ID: <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>

On Thu, Jul 29, 2021 at 11:43 AM Chen-Yu Tsai <wenst at chromium.org> wrote:
> On Thu, Jul 29, 2021 at 4:23 PM zhiyong.tao <zhiyong.tao at mediatek.com> wrote:

> > The rsel actual bias resistance of each setting is different in
> > different IC. we think that the define "MTK_PULL_SET_RSEL_000" is more
> > common for all different IC.
>
> I see. I personally prefer having things clearly described. I can
> understand this might be an extra burden to support different chips
> with different parameters, though this should be fairly straightforward
> with lookup tables tied to the compatible strings.
>
> Let's see if Rob and Linus have anything to add.

Not much. We have "soft pushed" for this to be described as generic
as possible, using SI units (ohms). But we also allow vendor-specific
numbers in this attribute. Especially when reverse engineering SoCs
that the contributor don't really have specs on (example M1 Mac).

The intent with the SI units is especially for people like you folks working
with Chromium to be able to use different SoCs and not feel lost
to a forest of different ways of doing things and associated
mistakes because vendors have hopelessly idiomatic pin configs.

Yours,
Linus Walleij


From lkp at intel.com  Wed Aug  4 16:03:54 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 07:03:54 +0800
Subject: [nomadik:ixp4xx-drivers-arm-soc-v5.15] BUILD SUCCESS
 47adef20e67d657696c953f4b8023017c6005c1b
Message-ID: <610b1cda.Rdm2/GtttXKb6+0k%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-drivers-arm-soc-v5.15
branch HEAD: 47adef20e67d657696c953f4b8023017c6005c1b  pata: ixp4xx: Rewrite to use device tree

elapsed time: 727m

configs tested: 180
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
riscv                    nommu_k210_defconfig
h8300                     edosk2674_defconfig
powerpc                 linkstation_defconfig
riscv                            alldefconfig
powerpc                 mpc832x_mds_defconfig
arc                        nsim_700_defconfig
powerpc                       ppc64_defconfig
arm                        magician_defconfig
riscv             nommu_k210_sdcard_defconfig
xtensa                              defconfig
mips                   sb1250_swarm_defconfig
powerpc                         ps3_defconfig
arm                          moxart_defconfig
arm                     eseries_pxa_defconfig
powerpc                     redwood_defconfig
parisc                           alldefconfig
sh                        edosk7760_defconfig
powerpc                     powernv_defconfig
sh                          kfr2r09_defconfig
powerpc                          g5_defconfig
powerpc                 canyonlands_defconfig
m68k                        stmark2_defconfig
powerpc                      cm5200_defconfig
arm                            xcep_defconfig
powerpc                      acadia_defconfig
sh                   rts7751r2dplus_defconfig
arm                       omap2plus_defconfig
arm                       aspeed_g5_defconfig
openrisc                            defconfig
arm                        mini2440_defconfig
sh                   sh7724_generic_defconfig
sh                          sdk7780_defconfig
powerpc                        warp_defconfig
powerpc                        icon_defconfig
sh                           se7206_defconfig
ia64                                defconfig
arm                           spitz_defconfig
arm                         vf610m4_defconfig
xtensa                          iss_defconfig
powerpc                 mpc836x_rdk_defconfig
riscv                            allyesconfig
mips                        maltaup_defconfig
arm                            hisi_defconfig
arm                          badge4_defconfig
arm                           corgi_defconfig
sh                          rsk7269_defconfig
powerpc                    adder875_defconfig
um                           x86_64_defconfig
sh                        sh7757lcr_defconfig
powerpc                     ep8248e_defconfig
sh                   sh7770_generic_defconfig
arm                         palmz72_defconfig
mips                          ath79_defconfig
arm                        spear3xx_defconfig
powerpc                    amigaone_defconfig
powerpc                      mgcoge_defconfig
mips                       bmips_be_defconfig
parisc                           allyesconfig
sh                          polaris_defconfig
sh                               j2_defconfig
arm                        vexpress_defconfig
ia64                      gensparse_defconfig
sh                     sh7710voipgw_defconfig
mips                        workpad_defconfig
mips                      fuloong2e_defconfig
powerpc                 mpc8560_ads_defconfig
m68k                       m5249evb_defconfig
riscv                    nommu_virt_defconfig
arm                           viper_defconfig
nds32                               defconfig
powerpc                     pq2fads_defconfig
xtensa                    xip_kc705_defconfig
m68k                        m5307c3_defconfig
arm                         mv78xx0_defconfig
arm                             pxa_defconfig
mips                     loongson2k_defconfig
mips                     loongson1b_defconfig
arm                          gemini_defconfig
powerpc                      pasemi_defconfig
mips                          rm200_defconfig
sparc                            alldefconfig
mips                         mpc30x_defconfig
sh                        dreamcast_defconfig
powerpc                     tqm5200_defconfig
riscv                               defconfig
arm                          imote2_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug  4 16:03:56 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 07:03:56 +0800
Subject: [nomadik:ixp4xx-net-arnd] BUILD SUCCESS
 3a5e743fe812ba5929ce714f23d2e45a92b5f7f2
Message-ID: <610b1cdc.pHAXqe8x8ZXpdw3h%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-net-arnd
branch HEAD: 3a5e743fe812ba5929ce714f23d2e45a92b5f7f2  ARM: dts: Add PTP timesource to the IXP456x

elapsed time: 727m

configs tested: 138
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
riscv                    nommu_k210_defconfig
h8300                     edosk2674_defconfig
powerpc                 linkstation_defconfig
riscv                            alldefconfig
powerpc                 mpc832x_mds_defconfig
arc                        nsim_700_defconfig
powerpc                         ps3_defconfig
arm                          moxart_defconfig
arm                     eseries_pxa_defconfig
powerpc                     redwood_defconfig
parisc                           alldefconfig
sh                        edosk7760_defconfig
powerpc                      cm5200_defconfig
arm                            xcep_defconfig
powerpc                      acadia_defconfig
sh                   rts7751r2dplus_defconfig
sh                   sh7724_generic_defconfig
sh                          sdk7780_defconfig
powerpc                        warp_defconfig
powerpc                        icon_defconfig
powerpc                 mpc836x_rdk_defconfig
riscv                            allyesconfig
mips                        maltaup_defconfig
arm                            hisi_defconfig
arm                          badge4_defconfig
powerpc                     ep8248e_defconfig
sh                   sh7770_generic_defconfig
arm                           spitz_defconfig
arm                         palmz72_defconfig
mips                          ath79_defconfig
arm                        spear3xx_defconfig
powerpc                    amigaone_defconfig
powerpc                      mgcoge_defconfig
mips                       bmips_be_defconfig
parisc                           allyesconfig
nds32                               defconfig
powerpc                     pq2fads_defconfig
xtensa                    xip_kc705_defconfig
m68k                        m5307c3_defconfig
arm                         mv78xx0_defconfig
arm                          gemini_defconfig
powerpc                      pasemi_defconfig
mips                          rm200_defconfig
sparc                            alldefconfig
mips                         mpc30x_defconfig
sh                        dreamcast_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug  4 16:04:00 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 07:04:00 +0800
Subject: [nomadik:ux500-codina-v5.14-rc1] BUILD SUCCESS
 677469a1178eaea3cd0f038cec9f8fd279def36b
Message-ID: <610b1ce0.DTUHBjV426/FC4yv%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-codina-v5.14-rc1
branch HEAD: 677469a1178eaea3cd0f038cec9f8fd279def36b  brcmfmac: firmware: Print helpful FW load info

elapsed time: 727m

configs tested: 128
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
riscv                    nommu_k210_defconfig
h8300                     edosk2674_defconfig
powerpc                 linkstation_defconfig
riscv                            alldefconfig
powerpc                 mpc832x_mds_defconfig
arc                        nsim_700_defconfig
powerpc                         ps3_defconfig
arm                          moxart_defconfig
arm                     eseries_pxa_defconfig
powerpc                     redwood_defconfig
parisc                           alldefconfig
sh                        edosk7760_defconfig
sh                   sh7724_generic_defconfig
sh                          sdk7780_defconfig
powerpc                        warp_defconfig
powerpc                        icon_defconfig
powerpc                 mpc836x_rdk_defconfig
riscv                            allyesconfig
mips                        maltaup_defconfig
arm                            hisi_defconfig
arm                          badge4_defconfig
powerpc                     ep8248e_defconfig
sh                   sh7770_generic_defconfig
arm                           spitz_defconfig
arm                         palmz72_defconfig
mips                          ath79_defconfig
arm                        spear3xx_defconfig
powerpc                    amigaone_defconfig
powerpc                      mgcoge_defconfig
mips                       bmips_be_defconfig
parisc                           allyesconfig
nds32                               defconfig
powerpc                     pq2fads_defconfig
xtensa                    xip_kc705_defconfig
m68k                        m5307c3_defconfig
arm                         mv78xx0_defconfig
arm                          gemini_defconfig
powerpc                      pasemi_defconfig
mips                          rm200_defconfig
sparc                            alldefconfig
mips                         mpc30x_defconfig
sh                        dreamcast_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug  4 16:03:58 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 07:03:58 +0800
Subject: [nomadik:ux500-gavini-v5.14-rc1] BUILD SUCCESS
 9428e22a17145ed6c3d931b5f2dbe21467117018
Message-ID: <610b1cde.lKeJCYOPAmqo8ZpY%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-gavini-v5.14-rc1
branch HEAD: 9428e22a17145ed6c3d931b5f2dbe21467117018  brcmfmac: firmware: Fix firmware loading

elapsed time: 727m

configs tested: 98
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
arc                      axs103_smp_defconfig
riscv                            alldefconfig
ia64                         bigsur_defconfig
sh                           sh2007_defconfig
arm                      integrator_defconfig
sh                        edosk7705_defconfig
m68k                          hp300_defconfig
xtensa                         virt_defconfig
sh                          polaris_defconfig
arm                       spear13xx_defconfig
mips                       lemote2f_defconfig
powerpc                     akebono_defconfig
arm                         orion5x_defconfig
mips                           ci20_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From joel at jms.id.au  Wed Aug  4 17:28:02 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 5 Aug 2021 00:28:02 +0000
Subject: [PATCH 6/6] ARM: dts: aspeed: Add Facebook Fuji (AST2600) BMC
In-Reply-To: <20210728233755.17963-7-rentao.bupt@gmail.com>
References: <20210728233755.17963-1-rentao.bupt@gmail.com>
 <20210728233755.17963-7-rentao.bupt@gmail.com>
Message-ID: <CACPK8XemZkV7nK_b4883DN+dJKhL=tXfqK6=DpHQe=fZRu_ETQ@mail.gmail.com>

On Wed, 28 Jul 2021 at 23:38, <rentao.bupt at gmail.com> wrote:
>
> From: Tao Ren <rentao.bupt at gmail.com>
>
> Add initial version of device tree for Facebook Fuji (AST2600) BMC.

I like to read what kind of platform the BMC is going into if you can
add that detail, but it's not essential.

> +&spi1 {
> +       status = "okay";
> +
> +       /*
> +        * Customize spi1 flash memory size to 32MB (maximum flash size on
> +        * the bus) to save vmalloc space.
> +        */
> +       reg = < 0x1e630000 0xc4
> +               0x30000000 0x2000000 >;

Which driver supports this?

It would be great to see Facebook work to get the SPI NOR driver for
the ast2600 merged to mainline.

I doubt the IBM team will get to this, as we are using eMMC instead.

> +
> +       flash at 0 {
> +               status = "okay";
> +               m25p,fast-read;
> +               label = "spi1.0";
> +               spi-max-frequency = <5000000>;
> +
> +               partitions {
> +                       compatible = "fixed-partitions";
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +
> +                       flash1 at 0 {
> +                               reg = <0x0 0x2000000>;
> +                               label = "system-flash";
> +                       };
> +               };
> +       };
> +};

> +&ehci1 {
> +       status = "okay";
> +};

Have you verified that USB works with mainline? I've had reports of it
working on 5.8 but it seems to have regressed as of v5.10.


> +&mdio1 {
> +       status = "okay";
> +
> +       ethphy3: ethernet-phy at 13 {
> +               compatible = "ethernet-phy-ieee802.3-c22";
> +               reg = <0x0d>;
> +       };
> +};
> +
> +&mac3 {
> +       phy-handle = <&ethphy3>;

status = okay?

You should specify the pinmux too I think, even if the default happens
to work, so that other devices cannot claim the pins.

Cheers,

Joel


From rentao.bupt at gmail.com  Wed Aug  4 18:19:51 2021
From: rentao.bupt at gmail.com (Tao Ren)
Date: Wed, 4 Aug 2021 18:19:51 -0700
Subject: [PATCH 6/6] ARM: dts: aspeed: Add Facebook Fuji (AST2600) BMC
In-Reply-To: <CACPK8XemZkV7nK_b4883DN+dJKhL=tXfqK6=DpHQe=fZRu_ETQ@mail.gmail.com>
References: <20210728233755.17963-1-rentao.bupt@gmail.com>
 <20210728233755.17963-7-rentao.bupt@gmail.com>
 <CACPK8XemZkV7nK_b4883DN+dJKhL=tXfqK6=DpHQe=fZRu_ETQ@mail.gmail.com>
Message-ID: <20210805011951.GA28444@taoren-ubuntu-R90MNF91>

On Thu, Aug 05, 2021 at 12:28:02AM +0000, Joel Stanley wrote:
> On Wed, 28 Jul 2021 at 23:38, <rentao.bupt at gmail.com> wrote:
> >
> > From: Tao Ren <rentao.bupt at gmail.com>
> >
> > Add initial version of device tree for Facebook Fuji (AST2600) BMC.
> 
> I like to read what kind of platform the BMC is going into if you can
> add that detail, but it's not essential.

Sure. I will add more details in v2.
 
> > +&spi1 {
> > +       status = "okay";
> > +
> > +       /*
> > +        * Customize spi1 flash memory size to 32MB (maximum flash size on
> > +        * the bus) to save vmalloc space.
> > +        */
> > +       reg = < 0x1e630000 0xc4
> > +               0x30000000 0x2000000 >;
> 
> Which driver supports this?
> 
> It would be great to see Facebook work to get the SPI NOR driver for
> the ast2600 merged to mainline.
> 
> I doubt the IBM team will get to this, as we are using eMMC instead.

Ah, I just checked aspeed-g6.dtsi (ast2600-spi) in mainline and I thought
the driver patches were also upstreamed. Let me remove the entry for now,
and will add it back when the driver is ready.

> 
> > +
> > +       flash at 0 {
> > +               status = "okay";
> > +               m25p,fast-read;
> > +               label = "spi1.0";
> > +               spi-max-frequency = <5000000>;
> > +
> > +               partitions {
> > +                       compatible = "fixed-partitions";
> > +                       #address-cells = <1>;
> > +                       #size-cells = <1>;
> > +
> > +                       flash1 at 0 {
> > +                               reg = <0x0 0x2000000>;
> > +                               label = "system-flash";
> > +                       };
> > +               };
> > +       };
> > +};
> 
> > +&ehci1 {
> > +       status = "okay";
> > +};
> 
> Have you verified that USB works with mainline? I've had reports of it
> working on 5.8 but it seems to have regressed as of v5.10.

It stopped working on ASPEED since commit 280a9045bb18 ("ehci: fix EHCI
host controller initialization sequence"): ehci_handshake() returns
error because HCHalted bit EHCI24[12] stays at 1.

I have a dirty hack in my tree (ignoring the halt bit) and it "works" on
AST2500 and AST2600. Let me send an email to openbmc and aspeed email
groups to see if anyone has more context.

Meanwhile, should I delete the entry until the fix is ready in driver?
 
> > +&mdio1 {
> > +       status = "okay";
> > +
> > +       ethphy3: ethernet-phy at 13 {
> > +               compatible = "ethernet-phy-ieee802.3-c22";
> > +               reg = <0x0d>;
> > +       };
> > +};
> > +
> > +&mac3 {
> > +       phy-handle = <&ethphy3>;
> 
> status = okay?
> 
> You should specify the pinmux too I think, even if the default happens
> to work, so that other devices cannot claim the pins.

status is set in ast2600 common dtsi, but let me set it here to avoid
confusion. Will update pinmux in v2. Thanks.

> 
> Cheers,
> 
> Joel

Cheers,

Tao


From lkp at intel.com  Wed Aug  4 18:29:05 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 09:29:05 +0800
Subject: [soc:at91/dt] BUILD SUCCESS 818c4593434e81c9971b8fc278215121622c755e
Message-ID: <610b3ee1.iystiDHamr86afZs%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git at91/dt
branch HEAD: 818c4593434e81c9971b8fc278215121622c755e  ARM: dts: at91: use the right property for shutdown controller

elapsed time: 2810m

configs tested: 195
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210803
i386                 randconfig-c001-20210805
sh                           se7751_defconfig
arc                    vdk_hs38_smp_defconfig
m68k                       bvme6000_defconfig
arm                         mv78xx0_defconfig
powerpc                     kmeter1_defconfig
sh                     sh7710voipgw_defconfig
arc                          axs101_defconfig
sh                           se7750_defconfig
arc                     haps_hs_smp_defconfig
xtensa                          iss_defconfig
mips                            gpr_defconfig
ia64                                defconfig
x86_64                            allnoconfig
riscv                               defconfig
arm                         nhk8815_defconfig
arm                  colibri_pxa300_defconfig
arm                     davinci_all_defconfig
sh                         apsh4a3a_defconfig
riscv                            allyesconfig
powerpc                     powernv_defconfig
mips                         bigsur_defconfig
openrisc                 simple_smp_defconfig
arm                        spear3xx_defconfig
arc                          axs103_defconfig
sh                           se7724_defconfig
m68k                         apollo_defconfig
arm                       cns3420vb_defconfig
arm                          iop32x_defconfig
mips                 decstation_r4k_defconfig
arm                        trizeps4_defconfig
arm                          gemini_defconfig
sh                   sh7770_generic_defconfig
sh                           se7343_defconfig
sh                           se7722_defconfig
arm                     eseries_pxa_defconfig
sh                          r7780mp_defconfig
sh                            titan_defconfig
sh                        sh7763rdp_defconfig
sh                         microdev_defconfig
powerpc                      ppc64e_defconfig
powerpc                       holly_defconfig
arm                        multi_v5_defconfig
arm                            mps2_defconfig
m68k                          hp300_defconfig
xtensa                         virt_defconfig
sh                          polaris_defconfig
arm                       spear13xx_defconfig
mips                       lemote2f_defconfig
powerpc                    socrates_defconfig
mips                      fuloong2e_defconfig
mips                      malta_kvm_defconfig
sh                          sdk7786_defconfig
powerpc                     tqm8541_defconfig
arm                        vexpress_defconfig
arm                       multi_v4t_defconfig
arm                      integrator_defconfig
riscv                    nommu_k210_defconfig
arm                          badge4_defconfig
arm                              alldefconfig
powerpc                     akebono_defconfig
arm                         orion5x_defconfig
mips                           ci20_defconfig
powerpc                 xes_mpc85xx_defconfig
m68k                        mvme16x_defconfig
mips                       rbtx49xx_defconfig
powerpc                     ksi8560_defconfig
arm                       imx_v6_v7_defconfig
powerpc                      bamboo_defconfig
arm                          ixp4xx_defconfig
powerpc                      ppc44x_defconfig
powerpc                  iss476-smp_defconfig
s390                             alldefconfig
m68k                            mac_defconfig
sh                   rts7751r2dplus_defconfig
nds32                             allnoconfig
powerpc                    klondike_defconfig
mips                       bmips_be_defconfig
riscv                             allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a012-20210802
i386                 randconfig-a011-20210802
i386                 randconfig-a015-20210802
i386                 randconfig-a013-20210802
i386                 randconfig-a014-20210802
i386                 randconfig-a016-20210802
riscv                    nommu_virt_defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-c001-20210803
x86_64               randconfig-c001-20210802
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a002-20210802
x86_64               randconfig-a004-20210802
x86_64               randconfig-a006-20210802
x86_64               randconfig-a003-20210802
x86_64               randconfig-a001-20210802
x86_64               randconfig-a005-20210802
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From mans0n at gorani.run  Wed Aug  4 18:34:35 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Thu, 5 Aug 2021 10:34:35 +0900
Subject: Aw: Re: [PATCH 0/2] Add MUSB for MT7623
In-Reply-To: <trinity-8910c659-6e4e-4979-a6d0-eaf5b8bee213-1628064668849@3c-app-gmx-bap67>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <trinity-0f9449b8-5114-46e5-9a4f-00b62155a938-1628010948338@3c-app-gmx-bs54>
 <f3607979-ea50-fc1c-0afe-a55881aa24f0@gorani.run>
 <trinity-8910c659-6e4e-4979-a6d0-eaf5b8bee213-1628064668849@3c-app-gmx-bap67>
Message-ID: <a6f4d24f-c79b-35e4-43fb-90eb75623dc2@gorani.run>

On 2021-08-04 17:11, Frank Wunderlich wrote:
>> Gesendet: Mittwoch, 04. August 2021 um 02:14 Uhr
>> Von: "Sungbo Eo" <mans0n at gorani.run>
> 
>>> thanks for working on it. do both otg-roles (host/client) work on your device?
>>
>> Yes, I tested it with host mode and device mode.
>> I also tried manual role-switch via sysfs and it worked with some prior setup.
>> Note that my device has a USB Type-A connector and not micro B, so I can't help with id pin stuff...
> 
>>> but usb-stick is not powered (led of the stick is off) and of course i see no mass-storage device.
>>
>> I observed the same symptom (but different error log).
>>
>> [    2.722253] musb-hdrc musb-hdrc.1.auto: VBUS_ERROR in a_idle (80, <SessEnd), retry #0, port1 00000104
>>
>> In my case adding `regulator-always-on;` in the regulator node solved the problem temporarily.
>> But after that I switched to relying on pinctrl.
> 
> i've found out that usb-stick is powered if i first connect otg-cable and then the stick to the cable...regulator always on does not change anything for me (only supporess "disabling vusb" message on boot). traceback on poweroff is still there.

I tried to reproduce your usb-conn-gpio message on my machine but I failed.
Probably because my USB port does not have ID pin...

Currently OpenWrt does not enable CONFIG_POWER_RESET_MT6323 so I was not aware of the poweroff error.
After I enabled it I got the same error and I could not resolve it... I'd better disable it for now.

> 
> role switch happen on inserting stick into cable, not before (insert cable into r2) as i expected.
> 
> need to figure out which CONFIG options i need to get USB-Stick as mass storage working.

Do you mean that vbus turns on but your usb stick is not detected?
Does that change if you use `dr_mode = "host"`?

> 
> i wonder why it works on your board without the vusb/connector subnodes

Do you mean vbus subnode in musb or vusb subnode in pmic?
I've never used vusb node, it did not affect me in any way.
When I used usb_vbus regulator node to enable vbus line, it did not turn on the line unless I added `regulator-always-on`...
It seems the connector node is not really required for me.

> 
>> +&pio {
>> +       musb_pins: musb {
>> +               pins-musb {
>> +                       pinmux = <MT7623_PIN_237_EXT_SDIO2_FUNC_DRV_VBUS>;
>> +               };
>> +       };
>> +};
> 
> imho it's the same gpio used for regulator, right? whats the difference?
> i tried this instead of the regulator-node => not powered (cable first, then stick).

I don't really know how it does work, but for me it does turn on vbus in host mode and turn it off in device mode.
I imagined DRV_VBUS setup will make the musb controller itself (and not kernel) control the line as needed, but it's just my guess.

> 
>> +&usb3 {
>> +       pinctrl-names = "default";
>> +       pinctrl-0 = <&musb_pins>;
>> +       status = "okay";
>> +
>> +       dr_mode = "host";
>> +
>> +       connector {
>> +               compatible = "usb-a-connector";
>> +       };
>> +};
>>
>> root at OpenWrt:~# lsusb -t
>> /:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=musb-hdrc/1p, 480M
>>     |__ Port 1: Dev 2, If 0, Class=, Driver=usb-storage, 480M
>> /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci-mtk/1p, 5000M
>> /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci-mtk/1p, 480M
>>


From mans0n at gorani.run  Wed Aug  4 18:36:46 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Thu, 5 Aug 2021 10:36:46 +0900
Subject: [PATCH 0/2] Add MUSB for MT7623
In-Reply-To: <638a4526-2688-e7c6-c71e-0ebaaeb773b5@gmail.com>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <638a4526-2688-e7c6-c71e-0ebaaeb773b5@gmail.com>
Message-ID: <77ec6aa3-95b8-3328-1587-ca4eaa4c1ef1@gorani.run>

Hi Matthias,
Thanks for your kind review.

On 2021-08-05 00:01, Matthias Brugger wrote:
> Hi Sungbo,
> 
> On 03/08/2021 17:13, Sungbo Eo wrote:
>> These patches add support for the MUSB controller on Mediatek MT7623.
>> Tested on Mercury RUSH-318AC Wi-Fi router.
>>
> 
> Nice to see you are working on Mediatek devices.
> Are you planning to add the device tree for the router to the kernel? I'd be
> happy to see them submitted.

Actually I've never thought about it.
My router device is not for public sale, and the device might have been
locked up in recent versions, so I don't think anyone can ever use it
for that specific model.
Come to think of it, I've tried another model before, which is more in
public, I might submit its device tree if it gets ready someday.

Thanks.

> 
> Regards,
> Matthias
> 
>> I got to know this from a BPI-R2 forum post [1], and managed to make it work on OpenWrt snapshot.
>> I'd like to know if this also works on BPI-R2, I can happily share the details if needed.
>> And I've just copy & pasted nodes from mt2701, please let me know if I missed some big differences between SoCs...
>>
>> [1] http://forum.banana-pi.org/t/bpi-r2-otg-port/10551
>>
>> Sungbo Eo (2):
>>   dt-bindings: usb: mtk-musb: add MT7623 compatible
>>   arm: dts: mt7623: add musb device nodes
>>
>>  .../bindings/usb/mediatek,musb.yaml           |  1 +
>>  arch/arm/boot/dts/mt7623.dtsi                 | 34 +++++++++++++++++++
>>  arch/arm/boot/dts/mt7623a.dtsi                |  4 +++
>>  3 files changed, 39 insertions(+)
>>


From joel at jms.id.au  Wed Aug  4 18:37:29 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 5 Aug 2021 01:37:29 +0000
Subject: [PATCH 6/6] ARM: dts: aspeed: Add Facebook Fuji (AST2600) BMC
In-Reply-To: <20210805011951.GA28444@taoren-ubuntu-R90MNF91>
References: <20210728233755.17963-1-rentao.bupt@gmail.com>
 <20210728233755.17963-7-rentao.bupt@gmail.com>
 <CACPK8XemZkV7nK_b4883DN+dJKhL=tXfqK6=DpHQe=fZRu_ETQ@mail.gmail.com>
 <20210805011951.GA28444@taoren-ubuntu-R90MNF91>
Message-ID: <CACPK8XcwsOa5NzsUZeiv5qdWV5H6HBa7WK+cwbnqayP4zhoNkg@mail.gmail.com>

On Thu, 5 Aug 2021 at 01:20, Tao Ren <rentao.bupt at gmail.com> wrote:
>
> On Thu, Aug 05, 2021 at 12:28:02AM +0000, Joel Stanley wrote:
> > On Wed, 28 Jul 2021 at 23:38, <rentao.bupt at gmail.com> wrote:
> > >
> > > From: Tao Ren <rentao.bupt at gmail.com>
> > >
> > > Add initial version of device tree for Facebook Fuji (AST2600) BMC.
> >
> > I like to read what kind of platform the BMC is going into if you can
> > add that detail, but it's not essential.
>
> Sure. I will add more details in v2.
>
> > > +&spi1 {
> > > +       status = "okay";
> > > +
> > > +       /*
> > > +        * Customize spi1 flash memory size to 32MB (maximum flash size on
> > > +        * the bus) to save vmalloc space.
> > > +        */
> > > +       reg = < 0x1e630000 0xc4
> > > +               0x30000000 0x2000000 >;
> >
> > Which driver supports this?
> >
> > It would be great to see Facebook work to get the SPI NOR driver for
> > the ast2600 merged to mainline.
> >
> > I doubt the IBM team will get to this, as we are using eMMC instead.
>
> Ah, I just checked aspeed-g6.dtsi (ast2600-spi) in mainline and I thought
> the driver patches were also upstreamed. Let me remove the entry for now,
> and will add it back when the driver is ready.

If it helps you, I don't mind it staying in your dts. I would like to
see some effort on the driver though.

>
> >
> > > +
> > > +       flash at 0 {
> > > +               status = "okay";
> > > +               m25p,fast-read;
> > > +               label = "spi1.0";
> > > +               spi-max-frequency = <5000000>;
> > > +
> > > +               partitions {
> > > +                       compatible = "fixed-partitions";
> > > +                       #address-cells = <1>;
> > > +                       #size-cells = <1>;
> > > +
> > > +                       flash1 at 0 {
> > > +                               reg = <0x0 0x2000000>;
> > > +                               label = "system-flash";
> > > +                       };
> > > +               };
> > > +       };
> > > +};
> >
> > > +&ehci1 {
> > > +       status = "okay";
> > > +};
> >
> > Have you verified that USB works with mainline? I've had reports of it
> > working on 5.8 but it seems to have regressed as of v5.10.
>
> It stopped working on ASPEED since commit 280a9045bb18 ("ehci: fix EHCI
> host controller initialization sequence"): ehci_handshake() returns
> error because HCHalted bit EHCI24[12] stays at 1.
>
> I have a dirty hack in my tree (ignoring the halt bit) and it "works" on
> AST2500 and AST2600. Let me send an email to openbmc and aspeed email
> groups to see if anyone has more context.

We discovered the same, except in my testing it wasn't actually
"working" on my EVB. I have a A3 EVB on my desk and when plugging in a
USB key nothing happened.

>
> Meanwhile, should I delete the entry until the fix is ready in driver?

Again, leave it in I think.

>
> > > +&mdio1 {
> > > +       status = "okay";
> > > +
> > > +       ethphy3: ethernet-phy at 13 {
> > > +               compatible = "ethernet-phy-ieee802.3-c22";
> > > +               reg = <0x0d>;
> > > +       };
> > > +};
> > > +
> > > +&mac3 {
> > > +       phy-handle = <&ethphy3>;
> >
> > status = okay?
> >
> > You should specify the pinmux too I think, even if the default happens
> > to work, so that other devices cannot claim the pins.
>
> status is set in ast2600 common dtsi, but let me set it here to avoid
> confusion. Will update pinmux in v2. Thanks.

Are you looking at mainline? I think it's disabled by default there:

https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/aspeed-g6.dtsi#L246

>
> >
> > Cheers,
> >
> > Joel
>
> Cheers,
>
> Tao


From mhiramat at kernel.org  Wed Aug  4 18:54:01 2021
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Thu, 5 Aug 2021 10:54:01 +0900
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210804060209.95817-1-liuqi115@huawei.com>
References: <20210804060209.95817-1-liuqi115@huawei.com>
Message-ID: <20210805105401.4acd3217c566b4e3933f355c@kernel.org>

On Wed, 4 Aug 2021 14:02:09 +0800
Qi Liu <liuqi115 at huawei.com> wrote:

> This patch introduce optprobe for ARM64. In optprobe, probed
> instruction is replaced by a branch instruction to detour
> buffer. Detour buffer contains trampoline code and a call to
> optimized_callback(). optimized_callback() calls opt_pre_handler()
> to execute kprobe handler.
> 
> Limitations:
> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
> guarantee the offset between probe point and kprobe pre_handler
> is not larger than 128MiB.
> 
> Performance of optprobe on Hip08 platform is test using kprobe
> example module[1] to analyze the latency of a kernel function,
> and here is the result:
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> 
> kprobe before optimized:
> [280709.846380] do_empty returned 0 and took 1530 ns to execute
> [280709.852057] do_empty returned 0 and took 550 ns to execute
> [280709.857631] do_empty returned 0 and took 440 ns to execute
> [280709.863215] do_empty returned 0 and took 380 ns to execute
> [280709.868787] do_empty returned 0 and took 360 ns to execute
> [280709.874362] do_empty returned 0 and took 340 ns to execute
> [280709.879936] do_empty returned 0 and took 320 ns to execute
> [280709.885505] do_empty returned 0 and took 300 ns to execute
> [280709.891075] do_empty returned 0 and took 280 ns to execute
> [280709.896646] do_empty returned 0 and took 290 ns to execute
> [280709.902220] do_empty returned 0 and took 290 ns to execute
> [280709.907807] do_empty returned 0 and took 290 ns to execute
> 
> optprobe:
> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> [ 2966.029158] do_empty returned 0 and took 70 ns to execute
> 
> Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> 
> ---
> 
> Changes since V1:
> - Address the comments from Masami, checks for all branch instructions, and
> use aarch64_insn_patch_text_nosync() instead of aarch64_insn_patch_text()
> in each probe.

Is it safe for the multicore system? If it is safe because it modifies
just one instruction (modifying 32bit in atomic), I understand it.
BTW, anyway, you should use _nosync() variant in arch_prepare_optimized_kprobe()
too, beacause the optprobe insn buffer is not touched until the probed instruction
is optimized by br.

[...]
> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
> +{
> +	kprobe_opcode_t *code;
> +	u32 insn;
> +	int ret, i;
> +	void *addrs[TMPL_END_IDX];
> +	void *addr;
> +
> +	code = get_optinsn_slot();
> +	if (!code)
> +		return -ENOMEM;
> +
> +	if (!is_offset_in_range((unsigned long)code,
> +				(unsigned long)orig->addr + 8))
> +		goto error;
> +
> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
> +				(unsigned long)optimized_callback))
> +		goto error;
> +
> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
> +				(unsigned long)op->kp.addr + 4))
> +		goto error;
> +
> +	/* Setup template */
> +	for (i = 0; i < TMPL_END_IDX; i++)
> +		addrs[i] = code + i;
> +
> +	ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
> +				      TMPL_END_IDX);

You should use aarch64_insn_patch_text_nosync() here (and all the
aarch64_insn_patch_text() in this function too), because the insn
buffer must not executed until the probe point is optimized.

> +	if (ret < 0)
> +		goto error;
> +
> +	/* Set probe information */
> +	addr = code + TMPL_VAL_IDX;
> +	insn =  (unsigned long long)op & 0xffffffff;
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	addr = addr + 4;
> +	insn = ((unsigned long long)op & GENMASK_ULL(63, 32)) >> 32;
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	addr = code + TMPL_CALL_BACK;
> +	insn =  aarch64_insn_gen_branch_imm((unsigned long)addr,
> +				(unsigned long)optimized_callback,
> +				AARCH64_INSN_BRANCH_LINK);
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	/* The original probed instruction */
> +	addr = code + TMPL_RESTORE_ORIGN_INSN;
> +	insn =  orig->opcode;
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	/* Jump back to next instruction */
> +	addr = code + TMPL_RESTORE_END;
> +	insn = aarch64_insn_gen_branch_imm(
> +				(unsigned long)(&code[TMPL_RESTORE_END]),
> +				(unsigned long)(op->kp.addr) + 4,
> +				AARCH64_INSN_BRANCH_NOLINK);
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	flush_icache_range((unsigned long)code,
> +			   (unsigned long)(&code[TMPL_END_IDX]));
> +	/* Set op->optinsn.insn means prepared. */
> +	op->optinsn.insn = code;
> +
> +	return 0;

Thank you,



-- 
Masami Hiramatsu <mhiramat at kernel.org>


From rentao.bupt at gmail.com  Wed Aug  4 19:09:46 2021
From: rentao.bupt at gmail.com (Tao Ren)
Date: Wed, 4 Aug 2021 19:09:46 -0700
Subject: [PATCH 6/6] ARM: dts: aspeed: Add Facebook Fuji (AST2600) BMC
In-Reply-To: <CACPK8XcwsOa5NzsUZeiv5qdWV5H6HBa7WK+cwbnqayP4zhoNkg@mail.gmail.com>
References: <20210728233755.17963-1-rentao.bupt@gmail.com>
 <20210728233755.17963-7-rentao.bupt@gmail.com>
 <CACPK8XemZkV7nK_b4883DN+dJKhL=tXfqK6=DpHQe=fZRu_ETQ@mail.gmail.com>
 <20210805011951.GA28444@taoren-ubuntu-R90MNF91>
 <CACPK8XcwsOa5NzsUZeiv5qdWV5H6HBa7WK+cwbnqayP4zhoNkg@mail.gmail.com>
Message-ID: <20210805020946.GA29371@taoren-ubuntu-R90MNF91>

On Thu, Aug 05, 2021 at 01:37:29AM +0000, Joel Stanley wrote:
> On Thu, 5 Aug 2021 at 01:20, Tao Ren <rentao.bupt at gmail.com> wrote:
> >
> > On Thu, Aug 05, 2021 at 12:28:02AM +0000, Joel Stanley wrote:
> > > On Wed, 28 Jul 2021 at 23:38, <rentao.bupt at gmail.com> wrote:
> > > >
> > > > From: Tao Ren <rentao.bupt at gmail.com>
> > > >
> > > > Add initial version of device tree for Facebook Fuji (AST2600) BMC.
> > >
> > > I like to read what kind of platform the BMC is going into if you can
> > > add that detail, but it's not essential.
> >
> > Sure. I will add more details in v2.
> >
> > > > +&spi1 {
> > > > +       status = "okay";
> > > > +
> > > > +       /*
> > > > +        * Customize spi1 flash memory size to 32MB (maximum flash size on
> > > > +        * the bus) to save vmalloc space.
> > > > +        */
> > > > +       reg = < 0x1e630000 0xc4
> > > > +               0x30000000 0x2000000 >;
> > >
> > > Which driver supports this?
> > >
> > > It would be great to see Facebook work to get the SPI NOR driver for
> > > the ast2600 merged to mainline.
> > >
> > > I doubt the IBM team will get to this, as we are using eMMC instead.
> >
> > Ah, I just checked aspeed-g6.dtsi (ast2600-spi) in mainline and I thought
> > the driver patches were also upstreamed. Let me remove the entry for now,
> > and will add it back when the driver is ready.
> 
> If it helps you, I don't mind it staying in your dts. I would like to
> see some effort on the driver though.
> 
> >
> > >
> > > > +
> > > > +       flash at 0 {
> > > > +               status = "okay";
> > > > +               m25p,fast-read;
> > > > +               label = "spi1.0";
> > > > +               spi-max-frequency = <5000000>;
> > > > +
> > > > +               partitions {
> > > > +                       compatible = "fixed-partitions";
> > > > +                       #address-cells = <1>;
> > > > +                       #size-cells = <1>;
> > > > +
> > > > +                       flash1 at 0 {
> > > > +                               reg = <0x0 0x2000000>;
> > > > +                               label = "system-flash";
> > > > +                       };
> > > > +               };
> > > > +       };
> > > > +};
> > >
> > > > +&ehci1 {
> > > > +       status = "okay";
> > > > +};
> > >
> > > Have you verified that USB works with mainline? I've had reports of it
> > > working on 5.8 but it seems to have regressed as of v5.10.
> >
> > It stopped working on ASPEED since commit 280a9045bb18 ("ehci: fix EHCI
> > host controller initialization sequence"): ehci_handshake() returns
> > error because HCHalted bit EHCI24[12] stays at 1.
> >
> > I have a dirty hack in my tree (ignoring the halt bit) and it "works" on
> > AST2500 and AST2600. Let me send an email to openbmc and aspeed email
> > groups to see if anyone has more context.
> 
> We discovered the same, except in my testing it wasn't actually
> "working" on my EVB. I have a A3 EVB on my desk and when plugging in a
> USB key nothing happened.

We have a non-removable USB device on Fuji (AST2600) BMC and it can be
enumerated successfully (after applying the hack). Let me vist the lab
and plug a USB key to CMM (AST2500) BMC sometime next week. Will collect
results and send out email then.

> 
> >
> > Meanwhile, should I delete the entry until the fix is ready in driver?
> 
> Again, leave it in I think.
> 
> >
> > > > +&mdio1 {
> > > > +       status = "okay";
> > > > +
> > > > +       ethphy3: ethernet-phy at 13 {
> > > > +               compatible = "ethernet-phy-ieee802.3-c22";
> > > > +               reg = <0x0d>;
> > > > +       };
> > > > +};
> > > > +
> > > > +&mac3 {
> > > > +       phy-handle = <&ethphy3>;
> > >
> > > status = okay?
> > >
> > > You should specify the pinmux too I think, even if the default happens
> > > to work, so that other devices cannot claim the pins.
> >
> > status is set in ast2600 common dtsi, but let me set it here to avoid
> > confusion. Will update pinmux in v2. Thanks.
> 
> Are you looking at mainline? I think it's disabled by default there:
> 
> https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/aspeed-g6.dtsi#L246

Sorry for the confusion, Joel. I mean the device is enabled in
"ast2600-facebook-netbmc-common.dtsi" (patch #3 in the series). Do we
still need to set status to "okay" explicitly in platform dts (to avoid
confusion)?

&mac3 {
        status = "okay";
        phy-mode = "rgmii";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rgmii4_default>;
};


> 
> >
> > >
> > > Cheers,
> > >
> > > Joel
> >
> > Cheers,
> >
> > Tao


From joel at jms.id.au  Wed Aug  4 19:17:13 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 5 Aug 2021 02:17:13 +0000
Subject: [PATCH 6/6] ARM: dts: aspeed: Add Facebook Fuji (AST2600) BMC
In-Reply-To: <20210805020946.GA29371@taoren-ubuntu-R90MNF91>
References: <20210728233755.17963-1-rentao.bupt@gmail.com>
 <20210728233755.17963-7-rentao.bupt@gmail.com>
 <CACPK8XemZkV7nK_b4883DN+dJKhL=tXfqK6=DpHQe=fZRu_ETQ@mail.gmail.com>
 <20210805011951.GA28444@taoren-ubuntu-R90MNF91>
 <CACPK8XcwsOa5NzsUZeiv5qdWV5H6HBa7WK+cwbnqayP4zhoNkg@mail.gmail.com>
 <20210805020946.GA29371@taoren-ubuntu-R90MNF91>
Message-ID: <CACPK8XfewBvd4BLgkgkC0DBzVk5pmV4ZTVaVt=otrKfqJ6m5Lg@mail.gmail.com>

On Thu, 5 Aug 2021 at 02:09, Tao Ren <rentao.bupt at gmail.com> wrote:
>
> On Thu, Aug 05, 2021 at 01:37:29AM +0000, Joel Stanley wrote:
> > On Thu, 5 Aug 2021 at 01:20, Tao Ren <rentao.bupt at gmail.com> wrote:
> > > > > +&ehci1 {
> > > > > +       status = "okay";
> > > > > +};
> > > >
> > > > Have you verified that USB works with mainline? I've had reports of it
> > > > working on 5.8 but it seems to have regressed as of v5.10.
> > >
> > > It stopped working on ASPEED since commit 280a9045bb18 ("ehci: fix EHCI
> > > host controller initialization sequence"): ehci_handshake() returns
> > > error because HCHalted bit EHCI24[12] stays at 1.
> > >
> > > I have a dirty hack in my tree (ignoring the halt bit) and it "works" on
> > > AST2500 and AST2600. Let me send an email to openbmc and aspeed email
> > > groups to see if anyone has more context.
> >
> > We discovered the same, except in my testing it wasn't actually
> > "working" on my EVB. I have a A3 EVB on my desk and when plugging in a
> > USB key nothing happened.
>
> We have a non-removable USB device on Fuji (AST2600) BMC and it can be
> enumerated successfully (after applying the hack). Let me vist the lab
> and plug a USB key to CMM (AST2500) BMC sometime next week. Will collect
> results and send out email then.

Thanks!

> > > status is set in ast2600 common dtsi, but let me set it here to avoid
> > > confusion. Will update pinmux in v2. Thanks.
> >
> > Are you looking at mainline? I think it's disabled by default there:
> >
> > https://elixir.bootlin.com/linux/latest/source/arch/arm/boot/dts/aspeed-g6.dtsi#L246
>
> Sorry for the confusion, Joel. I mean the device is enabled in
> "ast2600-facebook-netbmc-common.dtsi" (patch #3 in the series). Do we
> still need to set status to "okay" explicitly in platform dts (to avoid
> confusion)?

I see, thanks for explaining. It's a downside of the device tree
bindings for the ethernet device.

Given you will be the one working with the board, I think it's up to
you how you lay it out. You could choose to add a comment to the
platform dts, or put the hunk you currently have in the common.dtsi in
the platform.

>
> &mac3 {
>         status = "okay";
>         phy-mode = "rgmii";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_rgmii4_default>;
> };


From cgel.zte at gmail.com  Wed Aug  4 19:30:39 2021
From: cgel.zte at gmail.com (cgel.zte at gmail.com)
Date: Wed,  4 Aug 2021 19:30:39 -0700
Subject: [PATCH linux-next] ARM:sa1100/hackkit:Remove duplicated 'linux/tty.h'
 include in 'hackkit.c'
Message-ID: <20210805023039.625968-1-yong.yiran@zte.com.cn>

From: yong yiran <yong.yiran at zte.com.cn>

'linux/tty.h' included in 'hackkit.c' is duplicated.
Remove all but the first include of linux/tty.h from hackkit.c.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: yong yiran <yong.yiran at zte.com.cn>
---
 arch/arm/mach-sa1100/hackkit.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 3085f1c2e586..3fe34ee7c0ab 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -18,7 +18,6 @@
 #include <linux/serial_core.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <linux/tty.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
-- 
2.25.1



From lkp at intel.com  Wed Aug  4 19:45:09 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 10:45:09 +0800
Subject: [soc:for-next] BUILD SUCCESS b37e897eb18e97486357d6d1c58ce0e92d42bd19
Message-ID: <610b50b5.nH4IOInPxYRrxKiS%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: b37e897eb18e97486357d6d1c58ce0e92d42bd19  soc: document merges

elapsed time: 721m

configs tested: 132
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210805
arm                     eseries_pxa_defconfig
powerpc                      walnut_defconfig
mips                 decstation_r4k_defconfig
m68k                          multi_defconfig
arm                              alldefconfig
arm                             pxa_defconfig
powerpc                      ep88xc_defconfig
sh                           se7751_defconfig
sh                         apsh4a3a_defconfig
mips                        bcm47xx_defconfig
mips                           ip32_defconfig
powerpc                      pcm030_defconfig
arm                            pleb_defconfig
arm                           u8500_defconfig
arm                         palmz72_defconfig
sh                           se7343_defconfig
powerpc                     kilauea_defconfig
powerpc                      cm5200_defconfig
arm                            xcep_defconfig
mips                             allmodconfig
powerpc                      acadia_defconfig
sh                   rts7751r2dplus_defconfig
arm                          gemini_defconfig
mips                          malta_defconfig
alpha                            allyesconfig
powerpc                     tqm8548_defconfig
sh                          rsk7201_defconfig
openrisc                  or1klitex_defconfig
powerpc                    amigaone_defconfig
m68k                          atari_defconfig
arm                      jornada720_defconfig
arm                        spear3xx_defconfig
m68k                        m5307c3_defconfig
sh                             sh03_defconfig
mips                      bmips_stb_defconfig
arm                        mini2440_defconfig
arm                        trizeps4_defconfig
sh                        edosk7705_defconfig
mips                        workpad_defconfig
mips                      fuloong2e_defconfig
powerpc                 mpc8560_ads_defconfig
m68k                       m5249evb_defconfig
riscv                    nommu_virt_defconfig
arm                           viper_defconfig
powerpc                   bluestone_defconfig
mips                           rs90_defconfig
arm                         lpc32xx_defconfig
arm                        neponset_defconfig
powerpc                     tqm5200_defconfig
riscv                               defconfig
arm                          imote2_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a001-20210804

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug  4 19:44:58 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 10:44:58 +0800
Subject: [soc:arm/drivers] BUILD SUCCESS
 775dea4deec679c24b525b258c341a45ff1de9ea
Message-ID: <610b50aa.pySGnXRT2z/S9OxN%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/drivers
branch HEAD: 775dea4deec679c24b525b258c341a45ff1de9ea  Merge tag 'ixp4xx-drivers-arm-soc-v5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik into arm/drivers

elapsed time: 721m

configs tested: 135
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210805
powerpc                       ppc64_defconfig
arm                        magician_defconfig
riscv             nommu_k210_sdcard_defconfig
xtensa                              defconfig
mips                   sb1250_swarm_defconfig
powerpc                     powernv_defconfig
sh                          kfr2r09_defconfig
powerpc                          g5_defconfig
powerpc                 canyonlands_defconfig
m68k                        stmark2_defconfig
arm                       omap2plus_defconfig
arm                       aspeed_g5_defconfig
openrisc                            defconfig
arm                        mini2440_defconfig
sh                           se7206_defconfig
ia64                                defconfig
arm                           spitz_defconfig
arm                         vf610m4_defconfig
xtensa                          iss_defconfig
arm                           corgi_defconfig
sh                          rsk7269_defconfig
powerpc                    adder875_defconfig
um                           x86_64_defconfig
sh                        sh7757lcr_defconfig
sh                          polaris_defconfig
sh                               j2_defconfig
arm                        vexpress_defconfig
ia64                      gensparse_defconfig
sh                     sh7710voipgw_defconfig
mips                        workpad_defconfig
mips                      fuloong2e_defconfig
powerpc                 mpc8560_ads_defconfig
m68k                       m5249evb_defconfig
riscv                    nommu_virt_defconfig
arm                           viper_defconfig
arm                             pxa_defconfig
mips                     loongson2k_defconfig
parisc                           alldefconfig
mips                     loongson1b_defconfig
powerpc                     tqm5200_defconfig
riscv                               defconfig
arm                          imote2_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug  4 19:44:55 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 10:44:55 +0800
Subject: [soc:arm/dt] BUILD SUCCESS
 8e816b9915a136c12ab726e92412b917d7e514f7
Message-ID: <610b50a7.advyVKzt3q0b/yHi%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/dt
branch HEAD: 8e816b9915a136c12ab726e92412b917d7e514f7  Merge tag 'at91-dt-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux into arm/dt

elapsed time: 721m

configs tested: 135
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210805
powerpc                       ppc64_defconfig
arm                        magician_defconfig
riscv             nommu_k210_sdcard_defconfig
xtensa                              defconfig
mips                   sb1250_swarm_defconfig
powerpc                     powernv_defconfig
sh                          kfr2r09_defconfig
powerpc                          g5_defconfig
powerpc                 canyonlands_defconfig
m68k                        stmark2_defconfig
arm                       omap2plus_defconfig
arm                       aspeed_g5_defconfig
openrisc                            defconfig
arm                        mini2440_defconfig
sh                           se7206_defconfig
ia64                                defconfig
arm                           spitz_defconfig
arm                         vf610m4_defconfig
xtensa                          iss_defconfig
arm                           corgi_defconfig
sh                          rsk7269_defconfig
powerpc                    adder875_defconfig
um                           x86_64_defconfig
sh                        sh7757lcr_defconfig
sh                          polaris_defconfig
sh                               j2_defconfig
arm                        vexpress_defconfig
ia64                      gensparse_defconfig
sh                     sh7710voipgw_defconfig
mips                        workpad_defconfig
mips                      fuloong2e_defconfig
powerpc                 mpc8560_ads_defconfig
m68k                       m5249evb_defconfig
riscv                    nommu_virt_defconfig
arm                           viper_defconfig
arm                             pxa_defconfig
mips                     loongson2k_defconfig
parisc                           alldefconfig
mips                     loongson1b_defconfig
powerpc                     tqm5200_defconfig
riscv                               defconfig
arm                          imote2_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug  4 19:45:06 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 10:45:06 +0800
Subject: [soc:arm/soc] BUILD SUCCESS 318845985fa032a865784ef5373f182fcdf037a9
Message-ID: <610b50b2.p1HLawxFAurGLC0f%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/soc
branch HEAD: 318845985fa032a865784ef5373f182fcdf037a9  Merge tag 'at91-soc-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux into arm/soc

elapsed time: 721m

configs tested: 135
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210805
powerpc                       ppc64_defconfig
arm                        magician_defconfig
riscv             nommu_k210_sdcard_defconfig
xtensa                              defconfig
mips                   sb1250_swarm_defconfig
powerpc                     powernv_defconfig
sh                          kfr2r09_defconfig
powerpc                          g5_defconfig
powerpc                 canyonlands_defconfig
m68k                        stmark2_defconfig
arm                       omap2plus_defconfig
arm                       aspeed_g5_defconfig
openrisc                            defconfig
arm                        mini2440_defconfig
sh                           se7206_defconfig
ia64                                defconfig
arm                           spitz_defconfig
arm                         vf610m4_defconfig
xtensa                          iss_defconfig
arm                           corgi_defconfig
sh                          rsk7269_defconfig
powerpc                    adder875_defconfig
um                           x86_64_defconfig
sh                        sh7757lcr_defconfig
sh                          polaris_defconfig
sh                               j2_defconfig
arm                        vexpress_defconfig
ia64                      gensparse_defconfig
sh                     sh7710voipgw_defconfig
mips                        workpad_defconfig
mips                      fuloong2e_defconfig
powerpc                 mpc8560_ads_defconfig
m68k                       m5249evb_defconfig
riscv                    nommu_virt_defconfig
arm                           viper_defconfig
arm                             pxa_defconfig
mips                     loongson2k_defconfig
parisc                           alldefconfig
mips                     loongson1b_defconfig
powerpc                     tqm5200_defconfig
riscv                               defconfig
arm                          imote2_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug  4 19:45:03 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 05 Aug 2021 10:45:03 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS 19c1eb3605a1bcd784726380f520925948b2962e
Message-ID: <610b50af.mtNs9gkZG4w8E11K%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 19c1eb3605a1bcd784726380f520925948b2962e  Merge tag 'omap-for-v5.14/fixes-rc5-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/fixes

elapsed time: 721m

configs tested: 95
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210805
arm                             pxa_defconfig
powerpc                      ep88xc_defconfig
sh                           se7751_defconfig
sh                         apsh4a3a_defconfig
mips                        bcm47xx_defconfig
mips                           ip32_defconfig
powerpc                   bluestone_defconfig
mips                           rs90_defconfig
arm                         lpc32xx_defconfig
arm                        neponset_defconfig
powerpc                     tqm5200_defconfig
riscv                               defconfig
arm                          imote2_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a015-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a005-20210804

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From aisheng.dong at nxp.com  Wed Aug  4 20:32:02 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 11:32:02 +0800
Subject: [PATCH v3 1/5] remoteproc: fix the wrong default value of is_iomem
Message-ID: <20210805033206.1295269-1-aisheng.dong@nxp.com>

Currently the is_iomem is a random value in the stack which may
be default to true even on those platforms that not use iomem to
store firmware.

Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Fixes: 40df0a91b2a5 ("remoteproc: add is_iomem to da_to_va")
Reviewed-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
v2->v3:
 * no changes
v1->v2:
 * update rproc_copy_segment as well
---
 drivers/remoteproc/remoteproc_coredump.c   | 2 +-
 drivers/remoteproc/remoteproc_elf_loader.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_coredump.c b/drivers/remoteproc/remoteproc_coredump.c
index aee657cc08c6..c892f433a323 100644
--- a/drivers/remoteproc/remoteproc_coredump.c
+++ b/drivers/remoteproc/remoteproc_coredump.c
@@ -152,8 +152,8 @@ static void rproc_copy_segment(struct rproc *rproc, void *dest,
 			       struct rproc_dump_segment *segment,
 			       size_t offset, size_t size)
 {
+	bool is_iomem = false;
 	void *ptr;
-	bool is_iomem;
 
 	if (segment->dump) {
 		segment->dump(rproc, segment, dest, offset, size);
diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index e8078efb3dec..3cd1798f17a3 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -178,8 +178,8 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
 		u64 filesz = elf_phdr_get_p_filesz(class, phdr);
 		u64 offset = elf_phdr_get_p_offset(class, phdr);
 		u32 type = elf_phdr_get_p_type(class, phdr);
+		bool is_iomem = false;
 		void *ptr;
-		bool is_iomem;
 
 		if (type != PT_LOAD)
 			continue;
-- 
2.25.1



From aisheng.dong at nxp.com  Wed Aug  4 20:32:03 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 11:32:03 +0800
Subject: [PATCH v3 2/5] remoteproc: imx_rproc: fix TCM io memory type
In-Reply-To: <20210805033206.1295269-1-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
Message-ID: <20210805033206.1295269-2-aisheng.dong@nxp.com>

is_iomem was introduced in the commit 40df0a91b2a5 ("remoteproc: add
is_iomem to da_to_va"), but the driver seemed missed to provide the io
type correctly.
This patch updates remoteproc driver to indicate the TCM on IMX are io
memories. Without the change, remoteproc kick will fail.

Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Peng Fan <peng.fan at nxp.com>
Fixes: 79806d32d5aa ("remoteproc: imx_rproc: support i.MX8MN/P")
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
ChangeLog:
v2->v3:
 * fix commit message typo and drop imx8ulp fixes tag
   Patch content unchanged.
v1->v2:
 * using ioremap_wc for non TCM memory
---
 drivers/remoteproc/imx_rproc.c | 35 ++++++++++++++++++++--------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index d88f76f5305e..71dcc6dd32e4 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -71,6 +71,7 @@ struct imx_rproc_mem {
 /* att flags */
 /* M4 own area. Can be mapped at probe */
 #define ATT_OWN		BIT(1)
+#define ATT_IOMEM	BIT(2)
 
 /* address translation table */
 struct imx_rproc_att {
@@ -117,7 +118,7 @@ struct imx_rproc {
 static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
 	/* dev addr , sys addr  , size	    , flags */
 	/* ITCM   */
-	{ 0x00000000, 0x007E0000, 0x00020000, ATT_OWN },
+	{ 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
 	/* OCRAM_S */
 	{ 0x00180000, 0x00180000, 0x00009000, 0 },
 	/* OCRAM */
@@ -131,7 +132,7 @@ static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
 	/* DDR (Code) - alias */
 	{ 0x10000000, 0x40000000, 0x0FFE0000, 0 },
 	/* DTCM */
-	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
+	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM },
 	/* OCRAM_S - alias */
 	{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
 	/* OCRAM */
@@ -147,7 +148,7 @@ static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
 static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
 	/* dev addr , sys addr  , size	    , flags */
 	/* TCML - alias */
-	{ 0x00000000, 0x007e0000, 0x00020000, 0 },
+	{ 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM},
 	/* OCRAM_S */
 	{ 0x00180000, 0x00180000, 0x00008000, 0 },
 	/* OCRAM */
@@ -159,9 +160,9 @@ static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
 	/* DDR (Code) - alias */
 	{ 0x10000000, 0x80000000, 0x0FFE0000, 0 },
 	/* TCML */
-	{ 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN },
+	{ 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN  | ATT_IOMEM},
 	/* TCMU */
-	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
+	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN  | ATT_IOMEM},
 	/* OCRAM_S */
 	{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
 	/* OCRAM */
@@ -199,12 +200,12 @@ static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
 	/* OCRAM_PXP (Code) - alias */
 	{ 0x00940000, 0x00940000, 0x00008000, 0 },
 	/* TCML (Code) */
-	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
+	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
 	/* DDR (Code) - alias, first part of DDR (Data) */
 	{ 0x10000000, 0x80000000, 0x0FFF0000, 0 },
 
 	/* TCMU (Data) */
-	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
+	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
 	/* OCRAM (Data) */
 	{ 0x20200000, 0x00900000, 0x00020000, 0 },
 	/* OCRAM_EPDC (Data) */
@@ -218,18 +219,18 @@ static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
 static const struct imx_rproc_att imx_rproc_att_imx6sx[] = {
 	/* dev addr , sys addr  , size	    , flags */
 	/* TCML (M4 Boot Code) - alias */
-	{ 0x00000000, 0x007F8000, 0x00008000, 0 },
+	{ 0x00000000, 0x007F8000, 0x00008000, ATT_IOMEM },
 	/* OCRAM_S (Code) */
 	{ 0x00180000, 0x008F8000, 0x00004000, 0 },
 	/* OCRAM_S (Code) - alias */
 	{ 0x00180000, 0x008FC000, 0x00004000, 0 },
 	/* TCML (Code) */
-	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
+	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
 	/* DDR (Code) - alias, first part of DDR (Data) */
 	{ 0x10000000, 0x80000000, 0x0FFF8000, 0 },
 
 	/* TCMU (Data) */
-	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
+	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
 	/* OCRAM_S (Data) - alias? */
 	{ 0x208F8000, 0x008F8000, 0x00004000, 0 },
 	/* DDR (Data) */
@@ -341,7 +342,7 @@ static int imx_rproc_stop(struct rproc *rproc)
 }
 
 static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
-			       size_t len, u64 *sys)
+			       size_t len, u64 *sys, bool *is_iomem)
 {
 	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
 	int i;
@@ -354,6 +355,8 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
 			unsigned int offset = da - att->da;
 
 			*sys = att->sa + offset;
+			if (is_iomem)
+				*is_iomem = att->flags & ATT_IOMEM;
 			return 0;
 		}
 	}
@@ -377,7 +380,7 @@ static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *i
 	 * On device side we have many aliases, so we need to convert device
 	 * address (M4) to system bus address first.
 	 */
-	if (imx_rproc_da_to_sys(priv, da, len, &sys))
+	if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem))
 		return NULL;
 
 	for (i = 0; i < IMX_RPROC_MEM_MAX; i++) {
@@ -553,8 +556,12 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
 		if (b >= IMX_RPROC_MEM_MAX)
 			break;
 
-		priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
-						     att->sa, att->size);
+		if (att->flags & ATT_IOMEM)
+			priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
+							     att->sa, att->size);
+		else
+			priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
+								att->sa, att->size);
 		if (!priv->mem[b].cpu_addr) {
 			dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa);
 			return -ENOMEM;
-- 
2.25.1



From aisheng.dong at nxp.com  Wed Aug  4 20:32:04 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 11:32:04 +0800
Subject: [PATCH v3 3/5] remoteproc: imx_rproc: fix ignoring mapping vdev
 regions
In-Reply-To: <20210805033206.1295269-1-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
Message-ID: <20210805033206.1295269-3-aisheng.dong@nxp.com>

vdev regions are typically named vdev0buffer, vdev0ring0, vdev0ring1 and
etc. Change to strncmp to cover them all.

Fixes: 8f2d8961640f ("remoteproc: imx_rproc: ignore mapping vdev regions")
Reviewed-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
v1->v3:
 * no changes
---
 drivers/remoteproc/imx_rproc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 71dcc6dd32e4..abfeac0b1738 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -582,8 +582,8 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
 		struct resource res;
 
 		node = of_parse_phandle(np, "memory-region", a);
-		/* Not map vdev region */
-		if (!strcmp(node->name, "vdev"))
+		/* Not map vdevbuffer, vdevring region */
+		if (!strncmp(node->name, "vdev", strlen("vdev")))
 			continue;
 		err = of_address_to_resource(node, 0, &res);
 		if (err) {
-- 
2.25.1



From aisheng.dong at nxp.com  Wed Aug  4 20:32:05 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 11:32:05 +0800
Subject: [PATCH v3 4/5] remoteproc: imx_rproc: fix rsc-table name
In-Reply-To: <20210805033206.1295269-1-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
Message-ID: <20210805033206.1295269-4-aisheng.dong@nxp.com>

Usually the dash '-'  is preferred in node name.
So far, not dts in upstream kernel, so we just update node name
in driver.

Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Fixes: 5e4c1243071d ("remoteproc: imx_rproc: support remote cores booted before Linux Kernel")
Reviewed-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
v1->v3:
 * no changes
---
 drivers/remoteproc/imx_rproc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index abfeac0b1738..ff620688fad9 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -604,7 +604,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
 		}
 		priv->mem[b].sys_addr = res.start;
 		priv->mem[b].size = resource_size(&res);
-		if (!strcmp(node->name, "rsc_table"))
+		if (!strcmp(node->name, "rsc-table"))
 			priv->rsc_table = priv->mem[b].cpu_addr;
 		b++;
 	}
-- 
2.25.1



From aisheng.dong at nxp.com  Wed Aug  4 20:32:06 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 11:32:06 +0800
Subject: [PATCH v3 5/5] remoteproc: imx_rproc: change to ioremap_wc for dram
In-Reply-To: <20210805033206.1295269-1-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
Message-ID: <20210805033206.1295269-5-aisheng.dong@nxp.com>

DRAM is not io memory, so changed to ioremap_wc. This is also
aligned with core io accessories. e.g. memcpy/memset and cpu direct
access.

Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
v2->v3:
 * patch content unchanged.
   Only drop the wrong tag in v2
   Tested on MX8MQ and MX8MP, MX7ULP.
v1->v2:
 * new patch
---
 drivers/remoteproc/imx_rproc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index ff620688fad9..4ae416ba5080 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -597,7 +597,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
 			break;
 
 		/* Not use resource version, because we might share region */
-		priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
+		priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, res.start, resource_size(&res));
 		if (!priv->mem[b].cpu_addr) {
 			dev_err(dev, "failed to remap %pr\n", &res);
 			return -ENOMEM;
-- 
2.25.1



From aisheng.dong at nxp.com  Wed Aug  4 20:35:44 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 11:35:44 +0800
Subject: [PATCH 0/2] rtc: add imx rpmsg rtc support
Message-ID: <20210805033546.1390950-1-aisheng.dong@nxp.com>

Add imx rpmsg rtc driver support

The driver needs cowork with pm rpmsg on imx7ulp but no compilation
dependency.

Dong Aisheng (2):
  ARM: dts: imx7ulp: add cm4 support
  rtc: imx-rpmsg: Add i.MX RPMSG RTC support

 arch/arm/boot/dts/imx7ulp-evk-m4.dtsi |  48 ++++
 arch/arm/boot/dts/imx7ulp-evk.dts     |   1 +
 arch/arm/boot/dts/imx7ulp.dtsi        |   7 +
 drivers/rtc/Kconfig                   |  10 +
 drivers/rtc/Makefile                  |   1 +
 drivers/rtc/rtc-imx-rpmsg.c           | 301 ++++++++++++++++++++++++++
 include/linux/firmware/imx/rpmsg.h    |  37 ++++
 7 files changed, 405 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx7ulp-evk-m4.dtsi
 create mode 100644 drivers/rtc/rtc-imx-rpmsg.c
 create mode 100644 include/linux/firmware/imx/rpmsg.h

-- 
2.25.1



From aisheng.dong at nxp.com  Wed Aug  4 20:35:45 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 11:35:45 +0800
Subject: [PATCH 1/2] ARM: dts: imx7ulp: add cm4 support
In-Reply-To: <20210805033546.1390950-1-aisheng.dong@nxp.com>
References: <20210805033546.1390950-1-aisheng.dong@nxp.com>
Message-ID: <20210805033546.1390950-2-aisheng.dong@nxp.com>

Add cm4 remoteproc which supports rpmsg naming service with
two vdevs and two pairs of vrings. The vdevbuffer region is
not required.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Alessandro Zummo <a.zummo at towertech.it>
Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
 arch/arm/boot/dts/imx7ulp-evk-m4.dtsi | 48 +++++++++++++++++++++++++++
 arch/arm/boot/dts/imx7ulp-evk.dts     |  1 +
 arch/arm/boot/dts/imx7ulp.dtsi        |  7 ++++
 3 files changed, 56 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx7ulp-evk-m4.dtsi

diff --git a/arch/arm/boot/dts/imx7ulp-evk-m4.dtsi b/arch/arm/boot/dts/imx7ulp-evk-m4.dtsi
new file mode 100644
index 000000000000..abef0e6a2f25
--- /dev/null
+++ b/arch/arm/boot/dts/imx7ulp-evk-m4.dtsi
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ *   Dong Aisheng <aisheng.dong at nxp.com>
+ */
+
+/ {
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vdev0vring0: vdev0vring0 at 9ff00000 {
+			reg = <0x9ff00000 0x8000>;
+			no-map;
+		};
+
+		vdev0vring1: vdev0vring1 at 9ff08000 {
+			reg = <0x9ff08000 0x8000>;
+			no-map;
+		};
+
+		vdev1vring0: vdev1vring0 at 9ff10000 {
+			reg = <0x9ff10000 0x8000>;
+			no-map;
+		};
+
+		vdev1vring1: vdev1vring1 at 9ff18000 {
+			reg = <0x9ff18000 0x8000>;
+			no-map;
+		};
+
+		rsc_table: rsc-table at 1fff8000{
+			reg = <0x1fff8000 0x1000>;
+			no-map;
+		};
+	};
+
+	imx7ulp-cm4 {
+		compatible = "fsl,imx7ulp-cm4";
+		mbox-names = "tx", "rx", "rxdb";
+		mboxes = <&mu 0 1
+			  &mu 1 1
+			  &mu 3 1>;
+		memory-region = <&vdev0vring0>, <&vdev0vring1>,
+				<&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx7ulp-evk.dts b/arch/arm/boot/dts/imx7ulp-evk.dts
index eff51e113db4..5d08bdad4c07 100644
--- a/arch/arm/boot/dts/imx7ulp-evk.dts
+++ b/arch/arm/boot/dts/imx7ulp-evk.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "imx7ulp.dtsi"
+#include "imx7ulp-evk-m4.dtsi"
 
 / {
 	model = "NXP i.MX7ULP EVK";
diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi
index a917b363da25..b4568eb49f2c 100644
--- a/arch/arm/boot/dts/imx7ulp.dtsi
+++ b/arch/arm/boot/dts/imx7ulp.dtsi
@@ -122,6 +122,13 @@ edma1: dma-controller at 40080000 {
 				 <&pcc2 IMX7ULP_CLK_DMA_MUX1>;
 		};
 
+		mu: mailbox at 40220000 {
+			compatible = "fsl,imx7ulp-mu";
+			reg = <0x40220000 0x1000>;
+			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <2>;
+		};
+
 		crypto: crypto at 40240000 {
 			compatible = "fsl,sec-v4.0";
 			#address-cells = <1>;
-- 
2.25.1



From aisheng.dong at nxp.com  Wed Aug  4 20:35:46 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 11:35:46 +0800
Subject: [PATCH 2/2] rtc: imx-rpmsg: Add i.MX RPMSG RTC support
In-Reply-To: <20210805033546.1390950-1-aisheng.dong@nxp.com>
References: <20210805033546.1390950-1-aisheng.dong@nxp.com>
Message-ID: <20210805033546.1390950-3-aisheng.dong@nxp.com>

Add i.MX RPMSG RTC support.

Cc: Alessandro Zummo <a.zummo at towertech.it>
Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
 drivers/rtc/Kconfig                |  10 +
 drivers/rtc/Makefile               |   1 +
 drivers/rtc/rtc-imx-rpmsg.c        | 301 +++++++++++++++++++++++++++++
 include/linux/firmware/imx/rpmsg.h |  37 ++++
 4 files changed, 349 insertions(+)
 create mode 100644 drivers/rtc/rtc-imx-rpmsg.c
 create mode 100644 include/linux/firmware/imx/rpmsg.h

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 12153d5801ce..f0e6c4dd8965 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1763,6 +1763,16 @@ config RTC_DRV_SNVS
 	   This driver can also be built as a module, if so, the module
 	   will be called "rtc-snvs".
 
+config RTC_DRV_IMX_RPMSG
+	tristate "NXP RPMSG RTC support"
+	select RPMSG_VIRTIO
+	depends on ARCH_MXC || COMPILE_TEST
+	depends on IMX_REMOTEPROC
+	depends on OF
+	help
+	   If you say yes here you get support for the NXP RPMSG
+	   RTC module.
+
 config RTC_DRV_IMX_SC
 	depends on IMX_SCU
 	depends on HAVE_ARM_SMCCC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2dd0dd956b0e..9cebfddcc245 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_RTC_DRV_GOLDFISH)	+= rtc-goldfish.o
 obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
 obj-$(CONFIG_RTC_DRV_HYM8563)	+= rtc-hym8563.o
 obj-$(CONFIG_RTC_DRV_IMXDI)	+= rtc-imxdi.o
+obj-$(CONFIG_RTC_DRV_IMX_RPMSG)	+= rtc-imx-rpmsg.o
 obj-$(CONFIG_RTC_DRV_IMX_SC)	+= rtc-imx-sc.o
 obj-$(CONFIG_RTC_DRV_ISL12022)	+= rtc-isl12022.o
 obj-$(CONFIG_RTC_DRV_ISL12026)	+= rtc-isl12026.o
diff --git a/drivers/rtc/rtc-imx-rpmsg.c b/drivers/rtc/rtc-imx-rpmsg.c
new file mode 100644
index 000000000000..0d6d4b18159e
--- /dev/null
+++ b/drivers/rtc/rtc-imx-rpmsg.c
@@ -0,0 +1,301 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2017-2021 NXP
+ */
+
+#include <linux/firmware/imx/rpmsg.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_qos.h>
+#include <linux/rpmsg.h>
+#include <linux/rtc.h>
+
+#define RPMSG_TIMEOUT 1000
+
+#define RTC_RPMSG_SEND		0x0
+#define RTC_RPMSG_RECEIVE	0x1
+#define RTC_RPMSG_NOTIFY	0x2
+
+enum rtc_rpmsg_cmd {
+	RTC_RPMSG_SET_TIME,
+	RTC_RPMSG_GET_TIME,
+	RTC_RPMSG_SET_ALARM,
+	RTC_RPMSG_GET_ALARM,
+	RTC_RPMSG_ENABLE_ALARM,
+};
+
+struct rtc_rpmsg_data {
+	struct imx_rpmsg_head header;
+	u8 reserved0;
+	union {
+		u8 reserved1;
+		u8 ret;
+	};
+	union {
+		u32 reserved2;
+		u32 sec;
+	};
+	union {
+		u8 enable;
+		u8 reserved3;
+	};
+	union {
+		u8 pending;
+		u8 reserved4;
+	};
+} __packed;
+
+struct rtc_rpmsg_info {
+	struct rpmsg_device *rpdev;
+	struct rtc_rpmsg_data *msg;
+	struct pm_qos_request pm_qos_req;
+	struct completion cmd_complete;
+	struct mutex lock;
+	struct rtc_device *rtc;
+};
+
+static int rtc_send_message(struct rtc_rpmsg_info *info,
+			    struct rtc_rpmsg_data *msg, bool ack)
+{
+	struct device *dev = &info->rpdev->dev;
+	int err;
+
+	mutex_lock(&info->lock);
+
+	cpu_latency_qos_add_request(&info->pm_qos_req, 0);
+	reinit_completion(&info->cmd_complete);
+
+	err = rpmsg_send(info->rpdev->ept, (void *)msg, sizeof(*msg));
+	if (err) {
+		dev_err(dev, "rpmsg send failed: %d\n", err);
+		goto err_out;
+	}
+
+	if (ack) {
+		err = wait_for_completion_timeout(&info->cmd_complete,
+						  msecs_to_jiffies(RPMSG_TIMEOUT));
+		if (!err) {
+			dev_err(dev, "rpmsg send timeout\n");
+			err = -ETIMEDOUT;
+			goto err_out;
+		}
+
+		if (info->msg->ret != 0) {
+			dev_err(dev, "rpmsg not ack %d\n", info->msg->ret);
+			err = -EINVAL;
+			goto err_out;
+		}
+
+		err = 0;
+	}
+
+err_out:
+	cpu_latency_qos_remove_request(&info->pm_qos_req);
+	mutex_unlock(&info->lock);
+
+	return err;
+}
+
+static int imx_rpmsg_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
+	struct rtc_rpmsg_data msg;
+	int ret;
+
+	msg.header.cate = IMX_RPMSG_RTC;
+	msg.header.major = IMX_RMPSG_MAJOR;
+	msg.header.minor = IMX_RMPSG_MINOR;
+	msg.header.type = RTC_RPMSG_SEND;
+	msg.header.cmd = RTC_RPMSG_GET_TIME;
+
+	ret = rtc_send_message(rtc_rpmsg, &msg, true);
+	if (ret)
+		return ret;
+
+	rtc_time64_to_tm(rtc_rpmsg->msg->sec, tm);
+
+	return 0;
+}
+
+static int imx_rpmsg_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
+	struct rtc_rpmsg_data msg;
+	unsigned long time;
+	int ret;
+
+	time = rtc_tm_to_time64(tm);
+
+	msg.header.cate = IMX_RPMSG_RTC;
+	msg.header.major = IMX_RMPSG_MAJOR;
+	msg.header.minor = IMX_RMPSG_MINOR;
+	msg.header.type = RTC_RPMSG_SEND;
+	msg.header.cmd = RTC_RPMSG_SET_TIME;
+	msg.sec = time;
+
+	ret = rtc_send_message(rtc_rpmsg, &msg, true);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int imx_rpmsg_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
+	struct rtc_rpmsg_data msg;
+	int ret;
+
+	msg.header.cate = IMX_RPMSG_RTC;
+	msg.header.major = IMX_RMPSG_MAJOR;
+	msg.header.minor = IMX_RMPSG_MINOR;
+	msg.header.type = RTC_RPMSG_SEND;
+	msg.header.cmd = RTC_RPMSG_GET_ALARM;
+
+	ret = rtc_send_message(rtc_rpmsg, &msg, true);
+	if (ret)
+		return ret;
+
+	rtc_time64_to_tm(rtc_rpmsg->msg->sec, &alrm->time);
+	alrm->pending = rtc_rpmsg->msg->pending;
+
+	return 0;
+}
+
+static int imx_rpmsg_rtc_alarm_irq_enable(struct device *dev,
+	unsigned int enable)
+{
+	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
+	struct rtc_rpmsg_data msg;
+	int ret;
+
+	msg.header.cate = IMX_RPMSG_RTC;
+	msg.header.major = IMX_RMPSG_MAJOR;
+	msg.header.minor = IMX_RMPSG_MINOR;
+	msg.header.type = RTC_RPMSG_SEND;
+	msg.header.cmd = RTC_RPMSG_ENABLE_ALARM;
+	msg.enable = enable;
+
+	ret = rtc_send_message(rtc_rpmsg, &msg, true);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int imx_rpmsg_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
+	struct rtc_rpmsg_data msg;
+	unsigned long time;
+	int ret;
+
+	time = rtc_tm_to_time64(&alrm->time);
+
+	msg.header.cate = IMX_RPMSG_RTC;
+	msg.header.major = IMX_RMPSG_MAJOR;
+	msg.header.minor = IMX_RMPSG_MINOR;
+	msg.header.type = RTC_RPMSG_SEND;
+	msg.header.cmd = RTC_RPMSG_SET_ALARM;
+	msg.sec = time;
+	msg.enable = alrm->enabled;
+
+	ret = rtc_send_message(rtc_rpmsg, &msg, true);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct rtc_class_ops imx_rpmsg_rtc_ops = {
+	.read_time = imx_rpmsg_rtc_read_time,
+	.set_time = imx_rpmsg_rtc_set_time,
+	.read_alarm = imx_rpmsg_rtc_read_alarm,
+	.set_alarm = imx_rpmsg_rtc_set_alarm,
+	.alarm_irq_enable = imx_rpmsg_rtc_alarm_irq_enable,
+};
+
+static int rtc_rpmsg_probe(struct rpmsg_device *rpdev)
+{
+	struct device *dev = &rpdev->dev;
+	struct rtc_rpmsg_info *rtc_rpmsg;
+
+	dev_info(dev, "new channel: 0x%x -> 0x%x\n", rpdev->src, rpdev->dst);
+
+	rtc_rpmsg = devm_kzalloc(dev, sizeof(*rtc_rpmsg), GFP_KERNEL);
+	if (!rtc_rpmsg)
+		return -ENOMEM;
+
+	rtc_rpmsg->rpdev = rpdev;
+	mutex_init(&rtc_rpmsg->lock);
+	init_completion(&rtc_rpmsg->cmd_complete);
+
+	dev_set_drvdata(dev, rtc_rpmsg);
+
+	device_init_wakeup(dev, true);
+
+	rtc_rpmsg->rtc = devm_rtc_device_register(dev, "rtc-rpmsg",
+						  &imx_rpmsg_rtc_ops,
+						  THIS_MODULE);
+	if (IS_ERR(rtc_rpmsg->rtc)) {
+		dev_err(dev, "failed to register rtc rpmsg: %ld\n", PTR_ERR(rtc_rpmsg->rtc));
+		return PTR_ERR(rtc_rpmsg->rtc);
+	}
+
+	return 0;
+}
+
+static void rtc_rpmsg_remove(struct rpmsg_device *rpdev)
+{
+	dev_info(&rpdev->dev, "rtc rpmsg driver is removed\n");
+}
+
+static int rtc_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
+			void *priv, u32 src)
+{
+	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(&rpdev->dev);
+	struct rtc_rpmsg_data *msg = (struct rtc_rpmsg_data *)data;
+
+	rtc_rpmsg->msg = msg;
+
+	if (msg->header.type == RTC_RPMSG_RECEIVE)
+		complete(&rtc_rpmsg->cmd_complete);
+	else if (msg->header.type == RTC_RPMSG_NOTIFY)
+		rtc_update_irq(rtc_rpmsg->rtc, 1, RTC_IRQF);
+	else
+		dev_err(&rpdev->dev, "wrong command type!\n");
+
+	return 0;
+}
+
+static const struct rpmsg_device_id rtc_rpmsg_id_table[] = {
+	{ .name	= "rpmsg-rtc-channel" },
+	{ },
+};
+
+static struct rpmsg_driver rtc_rpmsg_driver = {
+	.drv.name	= "imx_rtc_rpmsg",
+	.probe		= rtc_rpmsg_probe,
+	.remove		= rtc_rpmsg_remove,
+	.callback	= rtc_rpmsg_cb,
+	.id_table	= rtc_rpmsg_id_table,
+};
+
+/*
+ * imx m4 has a limitation that we can't read data during ns process.
+ * So register rtc a little bit late as rtc core will read data during
+ * register process
+ */
+static int __init rtc_rpmsg_init(void)
+{
+	return register_rpmsg_driver(&rtc_rpmsg_driver);
+}
+late_initcall(rtc_rpmsg_init);
+
+MODULE_AUTHOR("Dong Aisheng <aisheng.dong at nxp.com>");
+MODULE_DESCRIPTION("NXP i.MX RPMSG RTC Driver");
+MODULE_ALIAS("platform:imx_rtc_rpmsg");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/firmware/imx/rpmsg.h b/include/linux/firmware/imx/rpmsg.h
new file mode 100644
index 000000000000..20bcce23c917
--- /dev/null
+++ b/include/linux/firmware/imx/rpmsg.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2019-2021 NXP.
+ */
+
+#ifndef __LINUX_IMX_RPMSG_H__
+#define __LINUX_IMX_RPMSG_H__
+
+#include <linux/types.h>
+
+/*
+ * Global header file for iMX RPMSG
+ */
+
+/* Category define */
+#define IMX_RMPSG_LIFECYCLE     1
+#define IMX_RPMSG_PMIC          2
+#define IMX_RPMSG_AUDIO         3
+#define IMX_RPMSG_KEY           4
+#define IMX_RPMSG_GPIO          5
+#define IMX_RPMSG_RTC           6
+#define IMX_RPMSG_SENSOR        7
+
+/* rpmsg version */
+#define IMX_RMPSG_MAJOR         1
+#define IMX_RMPSG_MINOR         0
+
+struct imx_rpmsg_head {
+	u8 cate;
+	u8 major;
+	u8 minor;
+	u8 type;
+	u8 cmd;
+	u8 reserved[5];
+} __packed;
+
+#endif /* __LINUX_IMX_RPMSG_H__ */
-- 
2.25.1



From samuel at sholland.org  Wed Aug  4 21:57:14 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  4 Aug 2021 23:57:14 -0500
Subject: [PATCH v2 1/3] dt-bindings: watchdog: sunxi: Add compatible for R329
Message-ID: <20210805045716.46141-1-samuel@sholland.org>

On existing SoCs, the watchdog has a single clock input: HOSC (OSC24M)
divided by 750.  However, starting with R329, LOSC (OSC32k) is added as
an alternative clock source, with a bit to switch between them.

Since 24 MHz / 750 == 32 kHz, not 32.768 kHz, the hardware adjusts the
cycle counts to keep the timeouts independent of the clock source. This
keeps the programming interface backward-compatible.

R329 also adds two new registers, to allow software to immediately drive
the SoC reset signal.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
Changes v1 to v2:
 - Switch from enum to const
 - Add descriptions to "clocks" items

 .../watchdog/allwinner,sun4i-a10-wdt.yaml     | 32 ++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
index 9aa3c313c49f..8fa5b0d32381 100644
--- a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
+++ b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
@@ -24,6 +24,7 @@ properties:
               - allwinner,sun50i-a100-wdt
               - allwinner,sun50i-h6-wdt
               - allwinner,sun50i-h616-wdt
+              - allwinner,sun50i-r329-wdt
           - const: allwinner,sun6i-a31-wdt
       - items:
           - const: allwinner,suniv-f1c100s-wdt
@@ -33,7 +34,18 @@ properties:
     maxItems: 1
 
   clocks:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
+    items:
+      - description: High-frequency oscillator input, divided internally
+      - description: Low-frequency oscillator input, only found on some variants
+
+  clock-names:
+    minItems: 1
+    maxItems: 2
+    items:
+      - const: hosc
+      - const: losc
 
   interrupts:
     maxItems: 1
@@ -44,6 +56,24 @@ required:
   - clocks
   - interrupts
 
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - allwinner,sun50i-r329-wdt
+
+then:
+  properties:
+    clocks:
+      minItems: 2
+
+    clock-names:
+      minItems: 2
+
+  required:
+    - clock-names
+
 unevaluatedProperties: false
 
 examples:
-- 
2.31.1



From samuel at sholland.org  Wed Aug  4 21:57:15 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  4 Aug 2021 23:57:15 -0500
Subject: [PATCH v2 2/3] dt-bindings: watchdog: sunxi: Add compatible for D1
In-Reply-To: <20210805045716.46141-1-samuel@sholland.org>
References: <20210805045716.46141-1-samuel@sholland.org>
Message-ID: <20210805045716.46141-2-samuel@sholland.org>

D1 keeps the same register layout and clock sources as the R329, but it
adds a key field which must be set to update the watchdog's "CFG" and
"MODE" registers. Therefore it is not backward-compatible.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Samuel Holland <samuel at sholland.org>
---
Changes v1 to v2:
 - None.

 .../devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml   | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
index 8fa5b0d32381..6ef5e7caae80 100644
--- a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
+++ b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
@@ -29,6 +29,7 @@ properties:
       - items:
           - const: allwinner,suniv-f1c100s-wdt
           - const: allwinner,sun4i-a10-wdt
+      - const: allwinner,sun20i-d1-wdt
 
   reg:
     maxItems: 1
@@ -61,6 +62,7 @@ if:
     compatible:
       contains:
         enum:
+          - allwinner,sun20i-d1-wdt
           - allwinner,sun50i-r329-wdt
 
 then:
-- 
2.31.1



From samuel at sholland.org  Wed Aug  4 21:57:16 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  4 Aug 2021 23:57:16 -0500
Subject: [PATCH v2 3/3] watchdog: sunxi_wdt: Add support for D1
In-Reply-To: <20210805045716.46141-1-samuel@sholland.org>
References: <20210805045716.46141-1-samuel@sholland.org>
Message-ID: <20210805045716.46141-3-samuel@sholland.org>

D1 adds a key field to the "CFG" and "MODE" registers, that must be set
to change the other bits. Add logic to set the key when updating those
registers.

Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Signed-off-by: Samuel Holland <samuel at sholland.org>
---
Changes v1 to v2:
 - None.

 drivers/watchdog/sunxi_wdt.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
index b50757882a98..6cf82922d3fb 100644
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -48,6 +48,7 @@ struct sunxi_wdt_reg {
 	u8 wdt_timeout_shift;
 	u8 wdt_reset_mask;
 	u8 wdt_reset_val;
+	u32 wdt_key_val;
 };
 
 struct sunxi_wdt_dev {
@@ -91,12 +92,14 @@ static int sunxi_wdt_restart(struct watchdog_device *wdt_dev,
 	val = readl(wdt_base + regs->wdt_cfg);
 	val &= ~(regs->wdt_reset_mask);
 	val |= regs->wdt_reset_val;
+	val |= regs->wdt_key_val;
 	writel(val, wdt_base + regs->wdt_cfg);
 
 	/* Set lowest timeout and enable watchdog */
 	val = readl(wdt_base + regs->wdt_mode);
 	val &= ~(WDT_TIMEOUT_MASK << regs->wdt_timeout_shift);
 	val |= WDT_MODE_EN;
+	val |= regs->wdt_key_val;
 	writel(val, wdt_base + regs->wdt_mode);
 
 	/*
@@ -109,6 +112,7 @@ static int sunxi_wdt_restart(struct watchdog_device *wdt_dev,
 		mdelay(5);
 		val = readl(wdt_base + regs->wdt_mode);
 		val |= WDT_MODE_EN;
+		val |= regs->wdt_key_val;
 		writel(val, wdt_base + regs->wdt_mode);
 	}
 	return 0;
@@ -141,6 +145,7 @@ static int sunxi_wdt_set_timeout(struct watchdog_device *wdt_dev,
 	reg = readl(wdt_base + regs->wdt_mode);
 	reg &= ~(WDT_TIMEOUT_MASK << regs->wdt_timeout_shift);
 	reg |= wdt_timeout_map[timeout] << regs->wdt_timeout_shift;
+	reg |= regs->wdt_key_val;
 	writel(reg, wdt_base + regs->wdt_mode);
 
 	sunxi_wdt_ping(wdt_dev);
@@ -154,7 +159,7 @@ static int sunxi_wdt_stop(struct watchdog_device *wdt_dev)
 	void __iomem *wdt_base = sunxi_wdt->wdt_base;
 	const struct sunxi_wdt_reg *regs = sunxi_wdt->wdt_regs;
 
-	writel(0, wdt_base + regs->wdt_mode);
+	writel(regs->wdt_key_val, wdt_base + regs->wdt_mode);
 
 	return 0;
 }
@@ -176,11 +181,13 @@ static int sunxi_wdt_start(struct watchdog_device *wdt_dev)
 	reg = readl(wdt_base + regs->wdt_cfg);
 	reg &= ~(regs->wdt_reset_mask);
 	reg |= regs->wdt_reset_val;
+	reg |= regs->wdt_key_val;
 	writel(reg, wdt_base + regs->wdt_cfg);
 
 	/* Enable watchdog */
 	reg = readl(wdt_base + regs->wdt_mode);
 	reg |= WDT_MODE_EN;
+	reg |= regs->wdt_key_val;
 	writel(reg, wdt_base + regs->wdt_mode);
 
 	return 0;
@@ -220,9 +227,20 @@ static const struct sunxi_wdt_reg sun6i_wdt_reg = {
 	.wdt_reset_val = 0x01,
 };
 
+static const struct sunxi_wdt_reg sun20i_wdt_reg = {
+	.wdt_ctrl = 0x10,
+	.wdt_cfg = 0x14,
+	.wdt_mode = 0x18,
+	.wdt_timeout_shift = 4,
+	.wdt_reset_mask = 0x03,
+	.wdt_reset_val = 0x01,
+	.wdt_key_val = 0x16aa0000,
+};
+
 static const struct of_device_id sunxi_wdt_dt_ids[] = {
 	{ .compatible = "allwinner,sun4i-a10-wdt", .data = &sun4i_wdt_reg },
 	{ .compatible = "allwinner,sun6i-a31-wdt", .data = &sun6i_wdt_reg },
+	{ .compatible = "allwinner,sun20i-d1-wdt", .data = &sun20i_wdt_reg },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids);
-- 
2.31.1



From vkoul at kernel.org  Wed Aug  4 22:32:11 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 5 Aug 2021 11:02:11 +0530
Subject: [PATCH] arm64: defconfig: Enable Qualcomm MSM8996 CPU clock driver
In-Reply-To: <20210804193042.1155398-1-bjorn.andersson@linaro.org>
References: <20210804193042.1155398-1-bjorn.andersson@linaro.org>
Message-ID: <YQt327OiY9QJ6Wjn@matsya>

On 04-08-21, 12:30, Bjorn Andersson wrote:
> The MSM8996 supports CPU frequency scaling, so enable the clock driver
> for this.

Reviewed-by: Vinod Koul <vkoul at kernel.org>

-- 
~Vinod


From ikjn at chromium.org  Wed Aug  4 22:37:47 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Thu,  5 Aug 2021 13:37:47 +0800
Subject: [PATCH] usb: xhci-mtk: Do not use xhci's virt_dev in drop_endpoint
Message-ID: <20210805133731.1.Icc0f080e75b1312692d4c7c7d25e7df9fe1a05c2@changeid>

xhci-mtk depends on xhci's internal virt_dev when it retrieves its
internal data from usb_host_endpoint both in add_endpoint and
drop_endpoint callbacks. But when setup packet was retired by
transaction errors in xhci_setup_device() path, a virt_dev for the slot
is newly created with real_port 0. This leads to xhci-mtks's NULL pointer
dereference from drop_endpoint callback as xhci-mtk assumes that virt_dev's
real_port is always started from one. The similar problems were addressed
by [1] but that can't cover the failure cases from setup_device.

This patch drops the usages of xhci's virt_dev in xhci-mtk's drop_endpoint
callback by adopting rhashtable for searching mtk's schedule entity
from a given usb_host_endpoint pointer instead of searching a linked list.
So mtk's drop_endpoint callback doesn't have to rely on virt_dev at all.

[1] https://lore.kernel.org/r/1617179142-2681-2-git-send-email-chunfeng.yun at mediatek.com

Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
---

 drivers/usb/host/xhci-mtk-sch.c | 140 ++++++++++++++++++--------------
 drivers/usb/host/xhci-mtk.h     |  15 ++--
 2 files changed, 86 insertions(+), 69 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index cffcaf4dfa9f..f9b4d27ce449 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -80,7 +80,7 @@ decode_ep(struct usb_host_endpoint *ep, enum usb_device_speed speed)
 		interval /= 1000;
 	}
 
-	snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s\n",
+	snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s",
 		 usb_speed_string(speed), usb_endpoint_num(epd),
 		 usb_endpoint_dir_in(epd) ? "in" : "out",
 		 usb_ep_type_string(usb_endpoint_type(epd)),
@@ -129,6 +129,12 @@ get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
 	int bw_index;
 
 	virt_dev = xhci->devs[udev->slot_id];
+	if (WARN_ONCE(!virt_dev, "xhci-mtk: usb %s has no virt_dev\n",
+				dev_name(&udev->dev)))
+		return NULL;
+	if (WARN_ONCE(!virt_dev->real_port, "xhci-mtk: usb %s has invalid port number\n",
+			dev_name(&udev->dev)))
+		return NULL;
 
 	if (udev->speed >= USB_SPEED_SUPER) {
 		if (usb_endpoint_dir_out(&ep->desc))
@@ -194,7 +200,6 @@ static struct mu3h_sch_tt *find_tt(struct usb_device *udev)
 			}
 			return ERR_PTR(-ENOMEM);
 		}
-		INIT_LIST_HEAD(&tt->ep_list);
 		*ptt = tt;
 	}
 
@@ -224,7 +229,7 @@ static void drop_tt(struct usb_device *udev)
 	}
 
 	tt = *ptt;
-	if (!tt || !list_empty(&tt->ep_list))
+	if (!tt || tt->nr_eps > 0)
 		return;		/* never allocated , or still in use*/
 
 	*ptt = NULL;
@@ -236,13 +241,19 @@ static void drop_tt(struct usb_device *udev)
 	}
 }
 
-static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
-	struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
+static struct mu3h_sch_ep_info *create_sch_ep(struct xhci_hcd_mtk *mtk,
+		struct usb_device *udev, struct usb_host_endpoint *ep,
+		struct xhci_ep_ctx *ep_ctx)
 {
 	struct mu3h_sch_ep_info *sch_ep;
 	struct mu3h_sch_tt *tt = NULL;
 	u32 len_bw_budget_table;
 	size_t mem_size;
+	struct mu3h_sch_bw_info *bw_info;
+
+	bw_info = get_bw_info(mtk, udev, ep);
+	if (!bw_info)
+		return ERR_PTR(-ENODEV);
 
 	if (is_fs_or_ls(udev->speed))
 		len_bw_budget_table = TT_MICROFRAMES_MAX;
@@ -266,11 +277,10 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
 		}
 	}
 
+	sch_ep->bw_info = bw_info;
 	sch_ep->sch_tt = tt;
 	sch_ep->ep = ep;
 	sch_ep->speed = udev->speed;
-	INIT_LIST_HEAD(&sch_ep->endpoint);
-	INIT_LIST_HEAD(&sch_ep->tt_endpoint);
 
 	return sch_ep;
 }
@@ -552,9 +562,9 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	}
 
 	if (used)
-		list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list);
-	else
-		list_del(&sch_ep->tt_endpoint);
+		tt->nr_eps++;
+	else if (!WARN_ONCE(tt->nr_eps < 1, "unbalanced sch_tt's ep count"))
+		tt->nr_eps--;
 }
 
 static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw,
@@ -585,9 +595,9 @@ static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
 	return boundary;
 }
 
-static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
-			struct mu3h_sch_ep_info *sch_ep)
+static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 {
+	struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info;
 	const u32 esit_boundary = get_esit_boundary(sch_ep);
 	const u32 bw_boundary = get_bw_boundary(sch_ep->speed);
 	u32 offset;
@@ -633,23 +643,33 @@ static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
 	return load_ep_bw(sch_bw, sch_ep, true);
 }
 
-static void destroy_sch_ep(struct usb_device *udev,
-	struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
+static const struct rhashtable_params sch_ep_table_param = {
+	.key_len	= sizeof(struct usb_host_endpoint *),
+	.key_offset	= offsetof(struct mu3h_sch_ep_info, ep),
+	.head_offset	= offsetof(struct mu3h_sch_ep_info, ep_link),
+};
+
+static void destroy_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
+			   struct mu3h_sch_ep_info *sch_ep)
 {
 	/* only release ep bw check passed by check_sch_bw() */
 	if (sch_ep->allocated)
-		load_ep_bw(sch_bw, sch_ep, false);
+		load_ep_bw(sch_ep->bw_info, sch_ep, false);
 
 	if (sch_ep->sch_tt)
 		drop_tt(udev);
 
 	list_del(&sch_ep->endpoint);
+	rhashtable_remove_fast(&mtk->sch_ep_table, &sch_ep->ep_link,
+				sch_ep_table_param);
 	kfree(sch_ep);
 }
 
-static bool need_bw_sch(struct usb_host_endpoint *ep,
-	enum usb_device_speed speed, int has_tt)
+static bool need_bw_sch(struct usb_device *udev,
+			struct usb_host_endpoint *ep)
 {
+	bool has_tt = udev->tt && udev->tt->hub->parent;
+
 	/* only for periodic endpoints */
 	if (usb_endpoint_xfer_control(&ep->desc)
 		|| usb_endpoint_xfer_bulk(&ep->desc))
@@ -660,7 +680,7 @@ static bool need_bw_sch(struct usb_host_endpoint *ep,
 	 * a TT are also ignored, root-hub will schedule them directly,
 	 * but need set @bpkts field of endpoint context to 1.
 	 */
-	if (is_fs_or_ls(speed) && !has_tt)
+	if (is_fs_or_ls(udev->speed) && !has_tt)
 		return false;
 
 	/* skip endpoint with zero maxpkt */
@@ -675,7 +695,12 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 	struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd);
 	struct mu3h_sch_bw_info *sch_array;
 	int num_usb_bus;
-	int i;
+	int ret;
+
+	/* mu3h_sch_ep_info table, 'usb_host_endpoint*' as a key */
+	ret = rhashtable_init(&mtk->sch_ep_table, &sch_ep_table_param);
+	if (ret)
+		return ret;
 
 	/* ss IN and OUT are separated */
 	num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports;
@@ -684,9 +709,6 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 	if (sch_array == NULL)
 		return -ENOMEM;
 
-	for (i = 0; i < num_usb_bus; i++)
-		INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
-
 	mtk->sch_array = sch_array;
 
 	INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
@@ -696,6 +718,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 
 void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk)
 {
+	rhashtable_destroy(&mtk->sch_ep_table);
 	kfree(mtk->sch_array);
 }
 
@@ -713,9 +736,7 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 	ep_index = xhci_get_endpoint_index(&ep->desc);
 	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
 
-	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
-
-	if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info)) {
+	if (!need_bw_sch(udev, ep)) {
 		/*
 		 * set @bpkts to 1 if it is LS or FS periodic endpoint, and its
 		 * device does not connected through an external HS hub
@@ -727,14 +748,22 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 		return 0;
 	}
 
-	sch_ep = create_sch_ep(udev, ep, ep_ctx);
+	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
+
+	sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx);
 	if (IS_ERR_OR_NULL(sch_ep))
 		return -ENOMEM;
 
+	if (rhashtable_insert_fast(&mtk->sch_ep_table, &sch_ep->ep_link,
+				   sch_ep_table_param))
+		return -EEXIST;
+
 	setup_sch_info(ep_ctx, sch_ep);
 
 	list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list);
 
+	xhci_dbg(xhci, "added sch_ep %p : %p\n", sch_ep, ep);
+
 	return 0;
 }
 
@@ -743,25 +772,20 @@ static void drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 {
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct xhci_virt_device *virt_dev;
-	struct mu3h_sch_bw_info *sch_bw;
-	struct mu3h_sch_ep_info *sch_ep, *tmp;
-
-	virt_dev = xhci->devs[udev->slot_id];
-
-	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
+	struct mu3h_sch_ep_info *sch_ep;
+	void *key = ep;
 
-	if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info))
+	if (!need_bw_sch(udev, ep))
 		return;
 
-	sch_bw = get_bw_info(mtk, udev, ep);
+	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
 
-	list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) {
-		if (sch_ep->ep == ep) {
-			destroy_sch_ep(udev, sch_bw, sch_ep);
-			break;
-		}
-	}
+	sch_ep = rhashtable_lookup_fast(&mtk->sch_ep_table, &key,
+					sch_ep_table_param);
+	if (sch_ep)
+		destroy_sch_ep(mtk, udev, sch_ep);
+	else
+		xhci_dbg(xhci, "ep %p is not on the bw table\n", ep);
 }
 
 int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
@@ -769,30 +793,22 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 	struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
-	struct mu3h_sch_bw_info *sch_bw;
-	struct mu3h_sch_ep_info *sch_ep, *tmp;
+	struct mu3h_sch_ep_info *sch_ep;
 	int ret;
 
 	xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
 
 	list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) {
-		sch_bw = get_bw_info(mtk, udev, sch_ep->ep);
+		struct xhci_ep_ctx *ep_ctx;
+		struct usb_host_endpoint *ep = sch_ep->ep;
+		unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
 
-		ret = check_sch_bw(sch_bw, sch_ep);
+		ret = check_sch_bw(sch_ep);
 		if (ret) {
 			xhci_err(xhci, "Not enough bandwidth! (%s)\n",
 				 sch_error_string(-ret));
 			return -ENOSPC;
 		}
-	}
-
-	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
-		struct xhci_ep_ctx *ep_ctx;
-		struct usb_host_endpoint *ep = sch_ep->ep;
-		unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
-
-		sch_bw = get_bw_info(mtk, udev, ep);
-		list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
 
 		ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
 		ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(sch_ep->pkts)
@@ -806,22 +822,23 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 			sch_ep->offset, sch_ep->repeat);
 	}
 
-	return xhci_check_bandwidth(hcd, udev);
+	ret = xhci_check_bandwidth(hcd, udev);
+	if (!ret)
+		INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
+
+	return ret;
 }
 
 void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 {
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct mu3h_sch_bw_info *sch_bw;
 	struct mu3h_sch_ep_info *sch_ep, *tmp;
 
 	xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
 
-	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
-		sch_bw = get_bw_info(mtk, udev, sch_ep->ep);
-		destroy_sch_ep(udev, sch_bw, sch_ep);
-	}
+	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint)
+		destroy_sch_ep(mtk, udev, sch_ep);
 
 	xhci_reset_bandwidth(hcd, udev);
 }
@@ -850,8 +867,7 @@ int xhci_mtk_drop_ep(struct usb_hcd *hcd, struct usb_device *udev,
 	if (ret)
 		return ret;
 
-	if (ep->hcpriv)
-		drop_ep_quirk(hcd, udev, ep);
+	drop_ep_quirk(hcd, udev, ep);
 
 	return 0;
 }
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index ace432356c41..ddcf25524f67 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -10,6 +10,7 @@
 #define _XHCI_MTK_H_
 
 #include <linux/clk.h>
+#include <linux/rhashtable.h>
 
 #include "xhci.h"
 
@@ -25,36 +26,34 @@
 
 /**
  * @fs_bus_bw: array to keep track of bandwidth already used for FS
- * @ep_list: Endpoints using this TT
+ * @nr_eps: number of endpoints using this TT
  */
 struct mu3h_sch_tt {
 	u32 fs_bus_bw[XHCI_MTK_MAX_ESIT];
-	struct list_head ep_list;
+	int nr_eps;
 };
 
 /**
  * struct mu3h_sch_bw_info: schedule information for bandwidth domain
  *
  * @bus_bw: array to keep track of bandwidth already used at each uframes
- * @bw_ep_list: eps in the bandwidth domain
  *
  * treat a HS root port as a bandwidth domain, but treat a SS root port as
  * two bandwidth domains, one for IN eps and another for OUT eps.
  */
 struct mu3h_sch_bw_info {
 	u32 bus_bw[XHCI_MTK_MAX_ESIT];
-	struct list_head bw_ep_list;
 };
 
 /**
  * struct mu3h_sch_ep_info: schedule information for endpoint
  *
+ * @bw_info: bandwidth domain which this endpoint belongs
  * @esit: unit is 125us, equal to 2 << Interval field in ep-context
  * @num_budget_microframes: number of continuous uframes
  *		(@repeat==1) scheduled within the interval
  * @bw_cost_per_microframe: bandwidth cost per microframe
- * @endpoint: linked into bandwidth domain which it belongs to
- * @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to
+ * @endpoint: linked into bw_ep_chk_list, used by check_bandwidth hook
  * @sch_tt: mu3h_sch_tt linked into
  * @ep_type: endpoint type
  * @maxpkt: max packet size of endpoint
@@ -82,11 +81,12 @@ struct mu3h_sch_ep_info {
 	u32 num_budget_microframes;
 	u32 bw_cost_per_microframe;
 	struct list_head endpoint;
-	struct list_head tt_endpoint;
+	struct mu3h_sch_bw_info *bw_info;
 	struct mu3h_sch_tt *sch_tt;
 	u32 ep_type;
 	u32 maxpkt;
 	struct usb_host_endpoint *ep;
+	struct rhash_head ep_link;
 	enum usb_device_speed speed;
 	bool allocated;
 	/*
@@ -134,6 +134,7 @@ struct xhci_hcd_mtk {
 	struct device *dev;
 	struct usb_hcd *hcd;
 	struct mu3h_sch_bw_info *sch_array;
+	struct rhashtable sch_ep_table;
 	struct list_head bw_ep_chk_list;
 	struct mu3c_ippc_regs __iomem *ippc_regs;
 	int num_u2_ports;
-- 
2.32.0.554.ge1b32706d8-goog



From mason.zhang at mediatek.com  Wed Aug  4 22:23:13 2021
From: mason.zhang at mediatek.com (Mason Zhang)
Date: Thu, 5 Aug 2021 13:23:13 +0800
Subject: [PATCH v2 4/4] spi: tegra114: Fix set_cs_timing param
In-Reply-To: <20210803141045.GN4668@sirena.org.uk>
References: <20210803102517.20944-1-Mason.Zhang@mediatek.com>
 <20210803141045.GN4668@sirena.org.uk>
Message-ID: <1628140993.20108.4.camel@mbjsdccf07>

On Tue, 2021-08-03 at 15:10 +0100, Mark Brown wrote:
> On Tue, Aug 03, 2021 at 06:25:18PM +0800, Mason Zhang wrote:
> > This patch fixed set_cs_timing param, because cs timing delay has
> > been moved to spi_device.
> > 
> > Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
> > ---
> >  drivers/spi/spi-tegra114.c | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> Each individual patch in the series needs to be buildable by itself, if
> an earlier commit in the series causes things to fail to build then that
> commit needs to be improved so that this doesn't happen.  This supports
> things like bisection.
> 
> Please also look into how you're sending serieses, these patches aren't
> threaded together as normal and there's a weird "***" in the subject of
> the first patch.


Dear Mark:

	Thanks for your suggestions, I have merged patch 2/3/4 in one patch to
ensure it can be built by itself.
	And I have updated the patch v3, and removed the *** int the first
patch.


Thanks
Mason

From ikjn at chromium.org  Wed Aug  4 22:39:57 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Thu,  5 Aug 2021 13:39:57 +0800
Subject: [PATCH] usb: xhci-mtk: relax TT periodic bandwidth allocation
Message-ID: <20210805133937.1.Ia8174b875bc926c12ce427a5a1415dea31cc35ae@changeid>

Currently xhci-mtk needs software-managed bandwidth allocation for
periodic endpoints, it allocates the microframe index for the first
start-split packet for each endpoint. As this index allocation logic
should avoid the conflicts with other full/low-speed periodic endpoints,
it uses the worst case byte budgets on high-speed bus bandwidth
For example, for an isochronos IN endpoint with 192 bytes budget,
it will consume the whole 4 u-frames(188 * 4) while the actual
full-speed bus budget should be just 192bytes.

This patch changes the low/full-speed bandwidth allocation logic
to use "approximate" best case budget for lower speed bandwidth
management. For the same endpoint from the above example, the
approximate best case budget is now reduced to (188 * 2) bytes.

Without this patch, many usb audio headsets with 3 interfaces
(audio input, audio output, and HID) cannot be configured
on xhci-mtk.

Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
---

 drivers/usb/host/xhci-mtk-sch.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index f9b4d27ce449..46cbf5d54f4f 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -459,16 +459,17 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 	u32 num_esit, tmp;
 	int base;
 	int i, j;
+	u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
 
 	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
+
+	if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
+		offset++;
+
 	for (i = 0; i < num_esit; i++) {
 		base = offset + i * sch_ep->esit;
 
-		/*
-		 * Compared with hs bus, no matter what ep type,
-		 * the hub will always delay one uframe to send data
-		 */
-		for (j = 0; j < sch_ep->cs_count; j++) {
+		for (j = 0; j < uframes; j++) {
 			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
 			if (tmp > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
@@ -546,6 +547,8 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	u32 base, num_esit;
 	int bw_updated;
 	int i, j;
+	int offset = sch_ep->offset;
+	u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
 
 	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
 
@@ -554,10 +557,13 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	else
 		bw_updated = -sch_ep->bw_cost_per_microframe;
 
+	if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
+		offset++;
+
 	for (i = 0; i < num_esit; i++) {
-		base = sch_ep->offset + i * sch_ep->esit;
+		base = offset + i * sch_ep->esit;
 
-		for (j = 0; j < sch_ep->cs_count; j++)
+		for (j = 0; j < uframes; j++)
 			tt->fs_bus_bw[base + j] += bw_updated;
 	}
 
-- 
2.32.0.554.ge1b32706d8-goog



From dafna.hirschfeld at collabora.com  Wed Aug  4 23:06:07 2021
From: dafna.hirschfeld at collabora.com (Dafna Hirschfeld)
Date: Thu, 5 Aug 2021 08:06:07 +0200
Subject: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on
In-Reply-To: <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>
Message-ID: <8fe5ac46-a9db-710e-a6d1-856805ab2773@collabora.com>



On 02.08.21 14:12, Eizan Miyamoto wrote:
> Up until this change, many errors were logged but ignored when powering
> on clocks inside mtk_mdp_core. This change tries to do a better job at
> propagating errors back to the power management framework.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
> 
> (no changes since v1)
> 
>   drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 25 ++++++++++++-----
>   drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 +-
>   drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 27 ++++++++++++++-----
>   3 files changed, 39 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index b3426a551bea..76e295c8d9bc 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -13,10 +13,9 @@
>   
>   #include "mtk_mdp_comp.h"
>   
> -
> -void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
> +int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>   {
> -	int i, err;
> +	int i, err, status;
>   
>   	if (comp->larb_dev) {
>   		err = mtk_smi_larb_get(comp->larb_dev);
> @@ -30,11 +29,23 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>   		if (IS_ERR(comp->clk[i]))
>   			continue;
>   		err = clk_prepare_enable(comp->clk[i]);
> -		if (err)
> -			dev_err(dev,
> -			"failed to enable clock, err %d. type:%d i:%d\n",
> -				err, comp->type, i);
> +		if (err) {
> +			status = err;
> +			dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
> +			goto err_clk_prepare_enable;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_clk_prepare_enable:
> +	for (--i; i >= 0; i--) {
> +		if (IS_ERR(comp->clk[i]))
> +			continue;
> +		clk_disable_unprepare(comp->clk[i]);
>   	}
> +
> +	return status;

There is an API function clk_bulk_prepare_enable to prepare and enable an array of clks
so you can just use it.

>   }
>   
>   void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> index 7897766c96bb..92ab5249bcad 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> @@ -41,7 +41,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>   		      struct mtk_mdp_comp *comp,
>   		      enum mtk_mdp_comp_type comp_type);
>   void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
> -void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
> +int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
>   void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
>   
>   
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index 976aa1f4829b..412bbec0f735 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -52,13 +52,28 @@ static const struct of_device_id mtk_mdp_of_ids[] = {
>   };
>   MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids);
>   
> -static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
> +static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
>   {
> -	struct device *dev = &mdp->pdev->dev;
>   	struct mtk_mdp_comp *comp_node;
> +	int status;
> +	struct device *dev = &mdp->pdev->dev;
> +	int err;
>   
> -	list_for_each_entry(comp_node, &mdp->comp_list, node)
> -		mtk_mdp_comp_clock_on(dev, comp_node);
> +	list_for_each_entry(comp_node, &mdp->comp_list, node) {
> +		err = mtk_mdp_comp_clock_on(dev, comp_node);
> +		if (err) {
> +			status = err;

You can get rid of the new var 'status' and just return ret in case of error

> +			goto err_mtk_mdp_comp_clock_on;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_mtk_mdp_comp_clock_on:
> +	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
> +		mtk_mdp_comp_clock_off(dev, comp_node);
> +
> +	return status;
>   }
>   
>   static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
> @@ -274,9 +289,7 @@ static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
>   {
>   	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
>   
> -	mtk_mdp_clock_on(mdp);
> -
> -	return 0;
> +	return mtk_mdp_clock_on(mdp);
>   }
>   
>   static int __maybe_unused mtk_mdp_suspend(struct device *dev)
> 


From oupton at google.com  Wed Aug  4 23:27:48 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 4 Aug 2021 23:27:48 -0700
Subject: [PATCH v6 19/21] KVM: arm64: Emulate physical counter offsetting
 on non-ECV systems
In-Reply-To: <20210804110531.x6gm2bpygg7laiau@gator.home>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-20-oupton@google.com>
 <20210804110531.x6gm2bpygg7laiau@gator.home>
Message-ID: <CAOQ_QsgzsS1iMPQ8t+-ivjiTWJbbOQ2k_AmBHar3NqKJ=YydsA@mail.gmail.com>

Hi Drew,

On Wed, Aug 4, 2021 at 4:05 AM Andrew Jones <drjones at redhat.com> wrote:
> > +static bool ptimer_emulation_required(struct kvm_vcpu *vcpu)
> > +{
> > +     return timer_get_offset(vcpu_ptimer(vcpu)) &&
> > +                     !cpus_have_const_cap(ARM64_ECV);
>
> Whenever I see a static branch check and something else in the same
> condition, I always wonder if we could trim a few instructions for
> the static branch is false case by testing it first.

Good point, I'll reclaim those few cycles in the next spin ;-)

> > @@ -1539,11 +1551,8 @@ int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> >       switch (attr->attr) {
> >       case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> >       case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> > -             return 0;
> >       case KVM_ARM_VCPU_TIMER_OFFSET:
> > -             if (cpus_have_const_cap(ARM64_ECV))
> > -                     return 0;
> > -             break;
> > +             return 0;
>
> So now, if userspace wants to know when they're using an emulated
> TIMER_OFFSET vs. ECV, then they'll need to check the HWCAP. I guess
> that's fair. We should update the selftest to report what it's testing
> when the HWCAP is available.
>

Hmm...

I hadn't yet wired up the ECV cpufeature bits to an ELF HWCAP, but
this point is a bit interesting. I can see the argument being made
that we shouldn't have two ELF HWCAP bits for ECV (depending on
partial or full ECV support). ECV=0x1 is most certainly of interest to
userspace, since self-synchronized views of the counter are then
available. However, ECV=0x2 is purely of interest to EL2.

What if we only had only one ELF HWCAP bit for ECV >= 0x1? We could
let userspace read ID_AA64MMFR0_EL1.ECV if it really needs to know
about ECV = 0x2.

> > +     if (vcpu_ptimer(vcpu)->host_offset && !cpus_have_const_cap(ARM64_ECV))
>
> Shouldn't we expose and reuse ptimer_emulation_required() here?
>

Agreed, makes it much cleaner.

> > +             val &= ~CNTHCTL_EL1PCTEN;
> > +     else
> > +             val |= CNTHCTL_EL1PCTEN;
> >       write_sysreg(val, cnthctl_el2);
> >  }
> > --
> > 2.32.0.605.g8dce9f2422-goog
> >
>
> Otherwise,
>
> Reviewed-by: Andrew Jones <drjones at redhat.com>
>

Thanks!

--
Oliver


From narmstrong at baylibre.com  Wed Aug  4 23:31:06 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 5 Aug 2021 08:31:06 +0200
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
Message-ID: <4e98d876-330f-21a4-846e-94e1f01f0eed@baylibre.com>

Hi Saravana,

On 04/08/2021 23:47, Saravana Kannan wrote:
> On Wed, Aug 4, 2021 at 11:20 AM Saravana Kannan <saravanak at google.com> wrote:
>>
>> On Wed, Aug 4, 2021 at 1:50 AM Marc Zyngier <maz at kernel.org> wrote:
>>>
>>> On Wed, 04 Aug 2021 02:36:45 +0100,
>>> Saravana Kannan <saravanak at google.com> wrote:
>>>
>>> Hi Saravana,
>>>
>>> Thanks for looking into this.
>>
>> You are welcome. I just don't want people to think fw_devlink is broken :)
>>
>>>
>>> [...]
>>>
>>>>> Saravana, could you please have a look from a fw_devlink perspective?
>>>>
>>>> Sigh... I spent several hours looking at this and wrote up an analysis
>>>> and then realized I might be looking at the wrong DT files.
>>>>
>>>> Marc, can you point me to the board file in upstream that corresponds
>>>> to the platform in which you see this issue? I'm not asking for [1],
>>>> but the actual final .dts (not .dtsi) file that corresponds to the
>>>> platform/board/system.
>>>
>>> The platform I can reproduce this on is described in
>>> arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts. It is an
>>> intricate maze of inclusion, node merge and other DT subtleties. I
>>> suggest you look at the decompiled version to get a view of the
>>> result.
>>
>> Thanks. After decompiling it, it looks something like (stripped a
>> bunch of reg and address properties and added the labels back):
>>
>> eth_phy: mdio-multiplexer at 4c000 {
>>         compatible = "amlogic,g12a-mdio-mux";
>>         clocks = <0x02 0x13 0x1e 0x02 0xb1>;
>>         clock-names = "pclk\0clkin0\0clkin1";
>>         mdio-parent-bus = <0x22>;
>>
>>         ext_mdio: mdio at 0 {
>>                 reg = <0x00>;
>>
>>                 ethernet-phy at 0 {
>>                         max-speed = <0x3e8>;
>>                         interrupt-parent = <0x23>;
>>                         interrupts = <0x1a 0x08>;
>>                         phandle = <0x16>;
>>                 };
>>         };
>>
>>         int_mdio: mdio at 1 {
>>                 ...
>>         }
>> }
>>
>> And phandle 0x23 refers to the gpio_intc interrupt controller with the
>> modular driver.
>>
>>>> Based on your error messages, it's failing for mdio at 0 which
>>>> corresponds to ext_mdio. But none of the board dts files in upstream
>>>> have a compatible property for "ext_mdio". Which means fw_devlink
>>>> _should_ propagate the gpio_intc IRQ dependency all the way up to
>>>> eth_phy.
>>>>
>>>> Also, in the failing case, can you run:
>>>> ls -ld supplier:*
>>>>
>>>> in the /sys/devices/....<something>/ folder that corresponds to the
>>>> "eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?
>>>
>>> Here you go:
>>>
>>> root at tiger-roach:~# find /sys/devices/ -name 'supplier*'|grep -i mdio | xargs ls -ld
>>> lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/platform/soc/ff600000.bus/ff64c000.mdio-multiplexer/supplier:platform:ff63c000.system-controller:clock-controller -> ../../../../virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer
>>
>> As we discussed over chat, this was taken after the mdio-multiplexer
>> driver "successfully" probes this device. This will cause
>> SYNC_STATE_ONLY device links created by fw_devlink to be deleted
>> (because they are useless after a device probes). So, this doesn't
>> show the info I was hoping to demonstrate.
>>
>> In any case, one can see that fw_devlink properly created the device
>> link for the clocks dependency. So fw_devlink is parsing this node
>> properly. But it doesn't create a similar probe order enforcing device
>> link between the mdio-multiplexer and the gpio_intc because the
>> dependency is only present in a grand child DT node (ethernet-phy at 0
>> under ext_mdio). So fw_devlink is working as intended.
>>
>> I spent several hours squinting at the code/DT yesterday. Here's what
>> is going on and causing the problem:
>>
>> The failing driver in this case is
>> drivers/net/mdio/mdio-mux-meson-g12a.c. And the only DT node it's
>> handling is what I pasted above in this email. In the failure case,
>> the call flow is something like this:
>>
>> g12a_mdio_mux_probe()
>> -> mdio_mux_init()
>> -> of_mdiobus_register(ext_mdio DT node)
>> -> of_mdiobus_register_phy(ext_mdio DT node)
>> -> several calls deep fwnode_mdiobus_phy_device_register(ethernet_phy DT node)
>> -> Tried to get the IRQ listed in ethernet_phy and fails with
>> -EPROBE_DEFER because the IRQ driver isn't loaded yet.
>>
>> The error is propagated correctly all the way up to of_mdiobus_register(), but
>> mdio_mux_init() ignores the -EPROBE_DEFER from of_mdiobus_register() and just
>> continues on with the rest of the stuff and returns success as long as
>> one of the child nodes (in this case int_mdio) succeeds.
>>
>> Since the probe returns 0 without really succeeding, networking stuff
>> just fails badly after this. So, IMO, the real problem is with
>> mdio_mux_init() not propagating up the -EPROBE_DEFER. I gave Marc a
>> quick hack (pasted at the end of this email) to test my theory and he
>> confirmed that it fixes the issue (a few deferred probes later, things
>> work properly).
>>
>> Andrew, I don't see any good reason for mdio_mux_init() not
>> propagating the errors up correctly (at least for EPROBE_DEFER). I'll
>> send a patch to fix this. Please let me know if there's a reason it
>> has to stay as-is.
> 
> I sent out the proper fix as a series:
> https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t

Thanks a lot for digging here and providing the appropriate fixes !

Neil

> 
> Marc, can you give it a shot please?
> 
> -Saravana
> 
>>
>> -Saravana
>>
>> index 110e4ee85785..d973a267151f 100644
>> --- a/drivers/net/mdio/mdio-mux.c
>> +++ b/drivers/net/mdio/mdio-mux.c
>> @@ -170,6 +170,9 @@ int mdio_mux_init(struct device *dev,
>>                                 child_bus_node);
>>                         mdiobus_free(cb->mii_bus);
>>                         devm_kfree(dev, cb);
>> +                       /* Not a final fix. I think it can cause UAF issues. */
>> +                       mdio_mux_uninit(pb);
>> +                       return r;
>>                 } else {
>>                         cb->next = pb->children;
>>                         pb->children = cb;



From dafna.hirschfeld at collabora.com  Wed Aug  4 23:40:51 2021
From: dafna.hirschfeld at collabora.com (Dafna Hirschfeld)
Date: Thu, 5 Aug 2021 08:40:51 +0200
Subject: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components
In-Reply-To: <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
Message-ID: <0aff1abb-734f-c714-6ecc-c906862255c3@collabora.com>



On 02.08.21 14:12, Eizan Miyamoto wrote:
> Broadly, this patch (1) adds a driver for various MTK MDP components to
> go alongside the main MTK MDP driver, and (2) hooks them all together
> using the component framework.
> 
> (1) Up until now, the MTK MDP driver controls 8 devices in the device
> tree on its own. When running tests for the hardware video decoder, we
> found that the iommus and LARBs were not being properly configured. To
> configure them, a driver for each be added to mtk_mdp_comp so that
> mtk_iommu_add_device() can (eventually) be called from dma_configure()
> inside really_probe().
> 
> (2) The integration into the component framework allows us to defer the
> registration with the v4l2 subsystem until all the MDP-related devices
> have been probed, so that the relevant device node does not become
> available until initialization of all the components is complete.
> 
> Some notes about how the component framework has been integrated:
> 
> - The driver for the rdma0 component serves double duty as the "master"
>    (aggregate) driver as well as a component driver. This is a non-ideal
>    compromise until a better solution is developed. This device is
>    differentiated from the rest by checking for a "mediatek,vpu" property
>    in the device node.
> 
> - The list of mdp components remains hard-coded as mtk_mdp_comp_dt_ids[]
>    in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
>    mtk_mdp_comp.c. This unfortunate duplication of information is
>    addressed in a following patch in this series.
> 
> - The component driver calls component_add() for each device that is
>    probed.
> 
> - In mtk_mdp_probe (the "master" device), we scan the device tree for
>    any matching nodes against mtk_mdp_comp_dt_ids, and add component
>    matches for them. The match criteria is a matching device node
>    pointer.
> 
> - When the set of components devices that have been probed corresponds
>    with the list that is generated by the "master", the callback to
>    mtk_mdp_master_bind() is made, which then calls the component bind
>    functions.
> 
> - Inside mtk_mdp_master_bind(), once all the component bind functions
>    have been called, we can then register our device to the v4l2
>    subsystem.
> 
> - The call to pm_runtime_enable() in the master device is called after
>    all the components have been registered by their bind() functions
>    called by mtk_mtp_master_bind(). As a result, the list of components
>    will not change while power management callbacks mtk_mdp_suspend()/
>    resume() are accessing the list of components.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
> 
> (no changes since v1)
> 
>   drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 143 ++++++++++++--
>   drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  25 +--
>   drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 174 +++++++++++++-----
>   drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   1 +
>   4 files changed, 252 insertions(+), 91 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 76e295c8d9bc..7a0e3acffab9 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -5,13 +5,50 @@
>    */
>   
>   #include <linux/clk.h>
> +#include <linux/component.h>
>   #include <linux/device.h>
>   #include <linux/of.h>
> +#include <linux/module.h>
>   #include <linux/of_address.h>
>   #include <linux/of_platform.h>
>   #include <soc/mediatek/smi.h>
>   
>   #include "mtk_mdp_comp.h"
> +#include "mtk_mdp_core.h"
> +
> +/**
> + * enum mtk_mdp_comp_type - the MDP component
> + * @MTK_MDP_RDMA:		Read DMA
> + * @MTK_MDP_RSZ:		Reszer
> + * @MTK_MDP_WDMA:		Write DMA
> + * @MTK_MDP_WROT:		Write DMA with rotation
> + * @MTK_MDP_COMP_TYPE_MAX:	Placeholder for num elems in this enum
> + */
> +enum mtk_mdp_comp_type {
> +	MTK_MDP_RDMA,
> +	MTK_MDP_RSZ,
> +	MTK_MDP_WDMA,
> +	MTK_MDP_WROT,
> +	MTK_MDP_COMP_TYPE_MAX,
> +};
> +
> +static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
> +	{
> +		.compatible = "mediatek,mt8173-mdp-rdma",
> +		.data = (void *)MTK_MDP_RDMA
> +	}, {
> +		.compatible = "mediatek,mt8173-mdp-rsz",
> +		.data = (void *)MTK_MDP_RSZ
> +	}, {
> +		.compatible = "mediatek,mt8173-mdp-wdma",
> +		.data = (void *)MTK_MDP_WDMA
> +	}, {
> +		.compatible = "mediatek,mt8173-mdp-wrot",
> +		.data = (void *)MTK_MDP_WROT
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
>   
>   int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>   {
> @@ -20,9 +57,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
>   	if (comp->larb_dev) {
>   		err = mtk_smi_larb_get(comp->larb_dev);
>   		if (err)
> -			dev_err(dev,
> -				"failed to get larb, err %d. type:%d\n",
> -				err, comp->type);
> +			dev_err(dev, "failed to get larb, err %d.\n", err);
>   	}
>   
>   	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
> @@ -62,17 +97,41 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
>   		mtk_smi_larb_put(comp->larb_dev);
>   }
>   
> -int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
> -		      struct mtk_mdp_comp *comp,
> -		      enum mtk_mdp_comp_type comp_type)
> +static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
> +	struct mtk_mdp_dev *mdp = data;
> +
> +	mtk_mdp_register_component(mdp, comp);
> +
> +	return 0;
> +}
> +
> +static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
> +			   void *data)
> +{
> +	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
> +	struct mtk_mdp_dev *mdp = data;
> +
> +	mtk_mdp_unregister_component(mdp, comp);
> +}
> +
> +static const struct component_ops mtk_mdp_component_ops = {
> +	.bind   = mtk_mdp_comp_bind,
> +	.unbind = mtk_mdp_comp_unbind,
> +};
> +
> +int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)

This function can be static

>   {
>   	struct device_node *larb_node;
>   	struct platform_device *larb_pdev;
>   	int ret;
>   	int i;
> +	struct device_node *node = dev->of_node;
> +	enum mtk_mdp_comp_type comp_type =
> +		 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
>   
> -	comp->dev_node = of_node_get(node);
> -	comp->type = comp_type;
> +	INIT_LIST_HEAD(&comp->node);
>   
>   	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
>   		comp->clk[i] = of_clk_get(node, i);

that iteration can be replaced with clk_bulk_get

> @@ -80,19 +139,17 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>   			if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
>   				dev_err(dev, "Failed to get clock\n");
>   			ret = PTR_ERR(comp->clk[i]);
> -			goto put_dev;
> +			goto err;
>   		}
>   
>   		/* Only RDMA needs two clocks */
> -		if (comp->type != MTK_MDP_RDMA)
> +		if (comp_type != MTK_MDP_RDMA)
>   			break;
>   	}
>   
>   	/* Only DMA capable components need the LARB property */
>   	comp->larb_dev = NULL;
> -	if (comp->type != MTK_MDP_RDMA &&
> -	    comp->type != MTK_MDP_WDMA &&
> -	    comp->type != MTK_MDP_WROT)
> +	if (comp_type != MTK_MDP_RDMA && comp_type != MTK_MDP_WDMA && comp_type != MTK_MDP_WROT)
>   		return 0;
>   
>   	larb_node = of_parse_phandle(node, "mediatek,larb", 0);
> @@ -100,7 +157,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>   		dev_err(dev,
>   			"Missing mediadek,larb phandle in %pOF node\n", node);
>   		ret = -EINVAL;
> -		goto put_dev;
> +		goto err;
>   	}
>   
>   	larb_pdev = of_find_device_by_node(larb_node);
> @@ -108,7 +165,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>   		dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
>   		of_node_put(larb_node);
>   		ret = -EPROBE_DEFER;
> -		goto put_dev;
> +		goto err;
>   	}
>   	of_node_put(larb_node);
>   
> @@ -116,13 +173,59 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
>   
>   	return 0;
>   
> -put_dev:
> -	of_node_put(comp->dev_node);
> -
> +err:
>   	return ret;
>   }
>   
> -void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
> +static int mtk_mdp_comp_probe(struct platform_device *pdev)
>   {
> -	of_node_put(comp->dev_node);
> +	struct device *dev = &pdev->dev;
> +	struct device_node *vpu_node;
> +	int status;
> +	struct mtk_mdp_comp *comp;
> +
> +	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> +	if (vpu_node) {
> +		of_node_put(vpu_node);
> +		/*
> +		 * The device tree node with a mediatek,vpu property is deemed
> +		 * the MDP "master" device, we don't want to add a component
> +		 * for it in this function because the initialization for the
> +		 * master is done elsewhere.
> +		 */
> +		dev_info(dev, "vpu node found, not probing\n");
> +		return -ENODEV;
> +	}
> +
> +	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
> +	if (!comp)
> +		return -ENOMEM;
> +
> +	status = mtk_mdp_comp_init(comp, dev);
> +	if (status) {
> +		dev_err(dev, "Failed to initialize component: %d\n", status);
> +		return status;
> +	}
> +
> +	dev_set_drvdata(dev, comp);
> +
> +	return component_add(dev, &mtk_mdp_component_ops);
>   }
> +
> +static int mtk_mdp_comp_remove(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +
> +	component_del(dev, &mtk_mdp_component_ops);
> +	return 0;
> +}
> +
> +struct platform_driver mtk_mdp_component_driver = {
> +	.probe          = mtk_mdp_comp_probe,
> +	.remove         = mtk_mdp_comp_remove,
> +	.driver         = {
> +		.name   = "mediatek-mdp-comp",
> +		.owner  = THIS_MODULE,
> +		.of_match_table = mtk_mdp_comp_driver_dt_match,
> +	},
> +};
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> index 92ab5249bcad..df5fc4c94f90 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> @@ -7,42 +7,23 @@
>   #ifndef __MTK_MDP_COMP_H__
>   #define __MTK_MDP_COMP_H__
>   
> -/**
> - * enum mtk_mdp_comp_type - the MDP component
> - * @MTK_MDP_RDMA:	Read DMA
> - * @MTK_MDP_RSZ:	Riszer
> - * @MTK_MDP_WDMA:	Write DMA
> - * @MTK_MDP_WROT:	Write DMA with rotation
> - */
> -enum mtk_mdp_comp_type {
> -	MTK_MDP_RDMA,
> -	MTK_MDP_RSZ,
> -	MTK_MDP_WDMA,
> -	MTK_MDP_WROT,
> -};
> -
>   /**
>    * struct mtk_mdp_comp - the MDP's function component data
>    * @node:	list node to track sibing MDP components
> - * @dev_node:	component device node
>    * @clk:	clocks required for component
>    * @larb_dev:	SMI device required for component
> - * @type:	component type
>    */
>   struct mtk_mdp_comp {
>   	struct list_head	node;
> -	struct device_node	*dev_node;
>   	struct clk		*clk[2];
>   	struct device		*larb_dev;
> -	enum mtk_mdp_comp_type	type;
>   };
>   
> -int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
> -		      struct mtk_mdp_comp *comp,
> -		      enum mtk_mdp_comp_type comp_type);
> -void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
> +int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
> +
>   int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
>   void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
>   
> +extern struct platform_driver mtk_mdp_component_driver;
>   
>   #endif /* __MTK_MDP_COMP_H__ */
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index 412bbec0f735..b813a822439a 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -6,6 +6,7 @@
>    */
>   
>   #include <linux/clk.h>
> +#include <linux/component.h>
>   #include <linux/device.h>
>   #include <linux/errno.h>
>   #include <linux/interrupt.h>
> @@ -19,6 +20,7 @@
>   #include <linux/workqueue.h>
>   #include <soc/mediatek/smi.h>
>   
> +#include "mtk_mdp_comp.h"
>   #include "mtk_mdp_core.h"
>   #include "mtk_mdp_m2m.h"
>   #include "mtk_vpu.h"
> @@ -32,16 +34,12 @@ module_param(mtk_mdp_dbg_level, int, 0644);
>   static const struct of_device_id mtk_mdp_comp_dt_ids[] = {
>   	{
>   		.compatible = "mediatek,mt8173-mdp-rdma",
> -		.data = (void *)MTK_MDP_RDMA
>   	}, {
>   		.compatible = "mediatek,mt8173-mdp-rsz",
> -		.data = (void *)MTK_MDP_RSZ
>   	}, {
>   		.compatible = "mediatek,mt8173-mdp-wdma",
> -		.data = (void *)MTK_MDP_WDMA
>   	}, {
>   		.compatible = "mediatek,mt8173-mdp-wrot",
> -		.data = (void *)MTK_MDP_WROT
>   	},
>   	{ },
>   };
> @@ -106,6 +104,63 @@ static void mtk_mdp_reset_handler(void *priv)
>   	queue_work(mdp->wdt_wq, &mdp->wdt_work);
>   }
>   
> +static int compare_of(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static void release_of(struct device *dev, void *data)
> +{
> +	of_node_put(data);
> +}
> +
> +static int mtk_mdp_master_bind(struct device *dev)
> +{
> +	int status;
> +	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> +
> +	mtk_mdp_register_component(mdp, &mdp->comp_self);
> +
> +	status = component_bind_all(dev, mdp);
> +	if (status) {
> +		dev_err(dev, "Failed to bind all components: %d\n", status);
> +		goto err_component_bind_all;
> +	}
> +
> +	status = mtk_mdp_register_m2m_device(mdp);
> +	if (status) {
> +		dev_err(dev, "Failed to register m2m device: %d\n", status);
> +		goto err_mtk_mdp_register_m2m_device;
> +	}
> +
> +	pm_runtime_enable(dev);
> +
> +	return 0;
> +
> +err_mtk_mdp_register_m2m_device:
> +	component_unbind_all(dev, mdp);
> +
> +err_component_bind_all:
> +	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
> +
> +	return status;
> +}
> +
> +static void mtk_mdp_master_unbind(struct device *dev)
> +{
> +	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> +
> +	pm_runtime_disable(dev);
> +	mtk_mdp_unregister_m2m_device(mdp);
> +	component_unbind_all(dev, mdp);
> +	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
> +}
> +
> +static const struct component_master_ops mtk_mdp_com_ops = {
> +	.bind		= mtk_mdp_master_bind,
> +	.unbind		= mtk_mdp_master_unbind,
> +};
> +
>   void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
>   				struct mtk_mdp_comp *comp)
>   {
> @@ -123,8 +178,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>   	struct mtk_mdp_dev *mdp;
>   	struct device *dev = &pdev->dev;
>   	struct device_node *node, *parent;
> -	struct mtk_mdp_comp *comp, *comp_temp;
> -	int ret = 0;
> +	int i, ret = 0;
> +	struct component_match *match = NULL;
>   
>   	mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
>   	if (!mdp)
> @@ -149,36 +204,43 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>   	}
>   
>   	/* Iterate over sibling MDP function blocks */
> +	i = 0;
>   	for_each_child_of_node(parent, node) {
> -		const struct of_device_id *of_id;
> -		enum mtk_mdp_comp_type comp_type;
> +		struct platform_device *pdev;
>   
> -		of_id = of_match_node(mtk_mdp_comp_dt_ids, node);
> -		if (!of_id)
> +		if (!of_match_node(mtk_mdp_comp_dt_ids, node))
>   			continue;
>   
> -		if (!of_device_is_available(node)) {
> -			dev_err(dev, "Skipping disabled component %pOF\n",
> -				node);
> +		if (!of_device_is_available(node))
>   			continue;
> -		}
> -
> -		comp_type = (enum mtk_mdp_comp_type)of_id->data;
>   
> -		comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
> -		if (!comp) {
> -			ret = -ENOMEM;
> -			of_node_put(node);
> -			goto err_comp;
> +		pdev = of_find_device_by_node(node);
> +		if (!pdev) {
> +			dev_warn(dev, "Unable to find comp device %s\n",
> +				 node->full_name);
> +			continue;
>   		}
>   
> -		ret = mtk_mdp_comp_init(dev, node, comp, comp_type);
> -		if (ret) {
> -			of_node_put(node);
> -			goto err_comp;
> +		/*
> +		 * Do not add a match for my own (rdma0) device node.
> +		 * I will be managing it directly instead using comp_self.
> +		 */
> +		if (&pdev->dev != dev) {
> +			dev_dbg(dev, "adding match %d for: %pOF\n", i++, node);
> +			component_match_add_release(dev, &match, release_of,
> +						    compare_of,
> +						    of_node_get(node));
>   		}
> +	}
>   
> -		mtk_mdp_register_component(mdp, comp);
> +	/*
> +	 * Create a component for myself so that clocks can be toggled in
> +	 * clock_on().
> +	 */
> +	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
> +	if (ret) {
> +		dev_err(dev, "Failed to initialize component\n");
> +		goto err_comp;
>   	}
>   
>   	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
> @@ -203,18 +265,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>   		goto err_dev_register;
>   	}
>   
> -	ret = mtk_mdp_register_m2m_device(mdp);
> -	if (ret) {
> -		v4l2_err(&mdp->v4l2_dev, "Failed to init mem2mem device\n");
> -		goto err_m2m_register;
> -	}
> -
>   	mdp->vpu_dev = vpu_get_plat_device(pdev);
>   	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
>   				  VPU_RST_MDP);
>   	if (ret) {
>   		dev_err(&pdev->dev, "Failed to register reset handler\n");
> -		goto err_m2m_register;
> +		goto err_wdt_reg;
>   	}
>   
>   	platform_set_drvdata(pdev, mdp);
> @@ -222,15 +278,25 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>   	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
>   	if (ret) {
>   		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
> -		goto err_m2m_register;
> +		goto err_set_max_seg_size;
> +	}
> +
> +	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
> +	if (ret) {
> +		dev_err(dev, "Component master add failed\n");
> +		goto err_component_master_add;
>   	}
>   
> -	pm_runtime_enable(dev);
>   	dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);
>   
>   	return 0;
>   
> -err_m2m_register:
> +err_component_master_add:
> +	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> +
> +err_set_max_seg_size:
> +
> +err_wdt_reg:
>   	v4l2_device_unregister(&mdp->v4l2_dev);
>   
>   err_dev_register:
> @@ -242,11 +308,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>   err_alloc_job_wq:
>   
>   err_comp:
> -	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
> -		mtk_mdp_unregister_component(mdp, comp);
> -		mtk_mdp_comp_deinit(dev, comp);
> -	}
> -
>   	dev_dbg(dev, "err %d\n", ret);
>   	return ret;
>   }
> @@ -254,11 +315,10 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>   static int mtk_mdp_remove(struct platform_device *pdev)
>   {
>   	struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
> -	struct mtk_mdp_comp *comp, *comp_temp;
>   
> -	pm_runtime_disable(&pdev->dev);
> +	component_master_del(&pdev->dev, &mtk_mdp_com_ops);
> +
>   	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> -	mtk_mdp_unregister_m2m_device(mdp);
>   	v4l2_device_unregister(&mdp->v4l2_dev);
>   
>   	flush_workqueue(mdp->wdt_wq);
> @@ -267,10 +327,8 @@ static int mtk_mdp_remove(struct platform_device *pdev)
>   	flush_workqueue(mdp->job_wq);
>   	destroy_workqueue(mdp->job_wq);
>   
> -	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
> -		mtk_mdp_unregister_component(mdp, comp);
> -		mtk_mdp_comp_deinit(&pdev->dev, comp);
> -	}
> +	if (!list_empty(&mdp->comp_list))
> +		dev_warn(&pdev->dev, "not all components removed\n");
>   
>   	dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
>   	return 0;
> @@ -323,7 +381,25 @@ static struct platform_driver mtk_mdp_driver = {
>   	}
>   };
>   
> -module_platform_driver(mtk_mdp_driver);
> +static struct platform_driver * const mtk_mdp_drivers[] = {
> +	&mtk_mdp_driver,
> +	&mtk_mdp_component_driver,
> +};
> +
> +static int __init mtk_mdp_init(void)
> +{
> +	return platform_register_drivers(mtk_mdp_drivers,
> +					 ARRAY_SIZE(mtk_mdp_drivers));
> +}
> +
> +static void __exit mtk_mdp_exit(void)
> +{
> +	platform_unregister_drivers(mtk_mdp_drivers,
> +				    ARRAY_SIZE(mtk_mdp_drivers));
> +}
> +
> +module_init(mtk_mdp_init);
> +module_exit(mtk_mdp_exit);
>   
>   MODULE_AUTHOR("Houlong Wei <houlong.wei at mediatek.com>");
>   MODULE_DESCRIPTION("Mediatek image processor driver");
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> index a6e6dc36307b..8a52539b15d4 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> @@ -155,6 +155,7 @@ struct mtk_mdp_dev {
>   	struct mtk_mdp_variant		*variant;
>   	u16				id;
>   	struct list_head		comp_list;
> +	struct mtk_mdp_comp		comp_self;
>   	struct v4l2_m2m_dev		*m2m_dev;
>   	struct list_head		ctx_list;
>   	struct video_device		*vdev;
> 


From clin at suse.com  Wed Aug  4 23:54:21 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:21 +0800
Subject: [PATCH 0/8] arm64: dts: initial NXP S32G2 support
Message-ID: <20210805065429.27485-1-clin@suse.com>

Hello,

Here I'd like to propose a patchset, which is initial upstream support for NXP
S32G2. S32G is a processor family developed by NXP for automotive solutions,
such as vehicle networking and automotive high-performance processing. This
series focuses on S32G2, which is the latest generation we can find at the
moment. As the first round to support S32G2, this patchset only enables basic
components and interfaces the SoC must have while kernel booting, which aims
to have minimum hardware enablement for these two boards, S32G-VNP-EVB and
S32G-VNP-RDB2. The concepts of how these boards work are originated from the
downstream kernel tree[1] developed by NXP, which provides lots of details
about the SoC S32G274A and its integrated boards. This series has been
verified with downstream ATF[2] & U-Boot[3] based on the ATF boot flow.

Thanks,
Chester

[1] https://source.codeaurora.org/external/autobsps32/linux/
[2] https://source.codeaurora.org/external/autobsps32/arm-trusted-firmware/
[3] https://source.codeaurora.org/external/autobsps32/u-boot/

Chester Lin (8):
  dt-bindings: arm: fsl: add NXP S32G2 boards
  dt-bindings: serial: fsl-linflexuart: convert to json-schema format
  dt-bindings: serial: fsl-linflexuart: Add compatible for S32G2
  arm64: dts: add NXP S32G2 support
  arm64: dts: s32g2: add serial/uart support
  arm64: dts: s32g2: add VNP-EVB and VNP-RDB2 support
  arm64: dts: s32g2: add memory nodes for evb and rdb2
  MAINTAINERS: Add an entry for NXP S32G2 boards

 .../devicetree/bindings/arm/fsl.yaml          |   7 +
 .../bindings/serial/fsl,s32-linflexuart.txt   |  22 ---
 .../bindings/serial/fsl,s32-linflexuart.yaml  |  66 +++++++++
 MAINTAINERS                                   |   6 +
 arch/arm64/boot/dts/freescale/Makefile        |   2 +
 arch/arm64/boot/dts/freescale/s32g2.dtsi      | 129 ++++++++++++++++++
 .../arm64/boot/dts/freescale/s32g274a-evb.dts |  29 ++++
 .../boot/dts/freescale/s32g274a-rdb2.dts      |  33 +++++
 8 files changed, 272 insertions(+), 22 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
 create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-evb.dts
 create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts

-- 
2.30.0



From clin at suse.com  Wed Aug  4 23:54:22 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:22 +0800
Subject: [PATCH 1/8] dt-bindings: arm: fsl: add NXP S32G2 boards
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210805065429.27485-2-clin@suse.com>

Add bindings for S32G2's evaluation board (S32G-VNP-EVB) and reference
design 2 board ( S32G-VNP-RDB2).

Signed-off-by: Chester Lin <clin at suse.com>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index e2097011c4b0..3914aa09e503 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -983,6 +983,13 @@ properties:
           - const: solidrun,lx2160a-cex7
           - const: fsl,lx2160a
 
+      - description: S32G2 based Boards
+        items:
+          - enum:
+              - fsl,s32g274a-evb
+              - fsl,s32g274a-rdb2
+          - const: fsl,s32g2
+
       - description: S32V234 based Boards
         items:
           - enum:
-- 
2.30.0



From clin at suse.com  Wed Aug  4 23:54:23 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:23 +0800
Subject: [PATCH 2/8] dt-bindings: serial: fsl-linflexuart: convert to
 json-schema format
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210805065429.27485-3-clin@suse.com>

Convert the FSL LINFlexD UART binding to json-schema.

Signed-off-by: Chester Lin <clin at suse.com>
---
 .../bindings/serial/fsl,s32-linflexuart.txt   | 22 ---------
 .../bindings/serial/fsl,s32-linflexuart.yaml  | 48 +++++++++++++++++++
 2 files changed, 48 insertions(+), 22 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
 create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml

diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
deleted file mode 100644
index f1bbe0826be5..000000000000
--- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-* Freescale LINFlexD UART
-
-The LINFlexD controller implements several LIN protocol versions, as well as
-support for full-duplex UART communication through 8-bit and 9-bit frames.
-
-See chapter 47 ("LINFlexD") in the reference manual[1].
-
-Required properties:
-- compatible :
-  - "fsl,s32v234-linflexuart" for LINFlexD configured in UART mode, which
-    is compatible with the one integrated on S32V234 SoC
-- reg : Address and length of the register set for the device
-- interrupts : Should contain uart interrupt
-
-Example:
-uart0: serial at 40053000 {
-	compatible = "fsl,s32v234-linflexuart";
-	reg = <0x0 0x40053000 0x0 0x1000>;
-	interrupts = <0 59 4>;
-};
-
-[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM
diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
new file mode 100644
index 000000000000..acfe34706ccb
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/serial/fsl,s32-linflexuart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale LINFlexD UART
+
+description: |
+  The LINFlexD controller implements several LIN protocol versions, as well
+  as support for full-duplex UART communication through 8-bit and 9-bit
+  frames. See chapter 47 ("LINFlexD") in the reference manual
+  https://www.nxp.com/webapp/Download?colCode=S32V234RM.
+
+maintainers:
+  - Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+  - Rob Herring <robh at kernel.org>
+
+allOf:
+  - $ref: "serial.yaml"
+
+properties:
+  compatible:
+    description: The LINFlexD controller on S32V234 SoC, which can be
+      configured in UART mode.
+    items:
+      - const: fsl,s32v234-linflexuart
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    serial at 40053000 {
+        compatible = "fsl,s32v234-linflexuart";
+        reg = <0x40053000 0x1000>;
+        interrupts = <0 59 4>;
+    };
-- 
2.30.0



From clin at suse.com  Wed Aug  4 23:54:24 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:24 +0800
Subject: [PATCH 3/8] dt-bindings: serial: fsl-linflexuart: Add compatible for
 S32G2
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210805065429.27485-4-clin@suse.com>

Add a compatible string for the uart binding of NXP S32G2 platforms. Here
we use "s32v234-linflexuart" as fallback since the current linflexuart
driver still works on S32G2.

Signed-off-by: Chester Lin <clin at suse.com>
---
 .../bindings/serial/fsl,s32-linflexuart.yaml  | 26 ++++++++++++++++---
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
index acfe34706ccb..e731f3f6cea4 100644
--- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
+++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
@@ -21,10 +21,20 @@ allOf:
 
 properties:
   compatible:
-    description: The LINFlexD controller on S32V234 SoC, which can be
-      configured in UART mode.
-    items:
-      - const: fsl,s32v234-linflexuart
+    minItems: 1
+    maxItems: 2
+    oneOf:
+      - description: The LINFlexD controller on S32G2 SoC, which can be
+          configured in UART mode.
+        items:
+          - enum:
+              - fsl,s32g2-linflexuart
+          - const: fsl,s32v234-linflexuart
+
+      - description: The LINFlexD controller on S32V234 SoC, which can be
+          configured in UART mode.
+        items:
+          - const: fsl,s32v234-linflexuart
 
   reg:
     maxItems: 1
@@ -41,8 +51,16 @@ unevaluatedProperties: false
 
 examples:
   - |
+    /* S32V234 */
     serial at 40053000 {
         compatible = "fsl,s32v234-linflexuart";
         reg = <0x40053000 0x1000>;
         interrupts = <0 59 4>;
     };
+
+    /* S32G2 */
+    serial at 401c8000 {
+        compatible = "fsl,s32g2-linflexuart", "fsl,s32v234-linflexuart";
+        reg = <0x401c8000 0x3000>;
+        interrupts = <0 82 1>;
+    };
-- 
2.30.0



From clin at suse.com  Wed Aug  4 23:54:25 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:25 +0800
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210805065429.27485-5-clin@suse.com>

Add an initial dtsi file for generic SoC features of NXP S32G2.

Signed-off-by: Chester Lin <clin at suse.com>
---
 arch/arm64/boot/dts/freescale/s32g2.dtsi | 98 ++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi

diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
new file mode 100644
index 000000000000..3321819c1a2d
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2021 SUSE LLC
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "fsl,s32g2";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0>;
+			enable-method = "psci";
+			next-level-cache = <&cluster0_l2>;
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x1>;
+			enable-method = "psci";
+			next-level-cache = <&cluster0_l2>;
+		};
+
+		cpu2: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x100>;
+			enable-method = "psci";
+			next-level-cache = <&cluster1_l2>;
+		};
+
+		cpu3: cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x101>;
+			enable-method = "psci";
+			next-level-cache = <&cluster1_l2>;
+		};
+
+		cluster0_l2: l2-cache0 {
+			compatible = "cache";
+		};
+
+		cluster1_l2: l2-cache1 {
+			compatible = "cache";
+		};
+	};
+
+	pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ranges;
+
+		gic: interrupt-controller at 50800000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0 0x50800000 0 0x10000>,
+			      <0 0x50880000 0 0x200000>,
+			      <0 0x50400000 0 0x2000>,
+			      <0 0x50410000 0 0x2000>,
+			      <0 0x50420000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+						 IRQ_TYPE_LEVEL_HIGH)>;
+		};
+	};
+};
-- 
2.30.0



From clin at suse.com  Wed Aug  4 23:54:26 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:26 +0800
Subject: [PATCH 5/8] arm64: dts: s32g2: add serial/uart support
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210805065429.27485-6-clin@suse.com>

Add serial/uart support for NXP S32G2.

Signed-off-by: Chester Lin <clin at suse.com>
---
 arch/arm64/boot/dts/freescale/s32g2.dtsi | 31 ++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
index 3321819c1a2d..0076eacad8a6 100644
--- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 /*
  * Copyright (c) 2021 SUSE LLC
+ * Copyright 2017-2020 NXP
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -11,6 +12,12 @@ / {
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -82,6 +89,30 @@ soc {
 
 		ranges;
 
+		uart0: serial at 401c8000 {
+			compatible = "fsl,s32g2-linflexuart",
+				     "fsl,s32v234-linflexuart";
+			reg = <0 0x401c8000 0 0x3000>;
+			interrupts = <GIC_SPI 82 IRQ_TYPE_EDGE_RISING>;
+			status = "disabled";
+		};
+
+		uart1: serial at 401cc000 {
+			compatible = "fsl,s32g2-linflexuart",
+				     "fsl,s32v234-linflexuart";
+			reg = <0 0x401cc000 0 0x3000>;
+			interrupts = <GIC_SPI 83 IRQ_TYPE_EDGE_RISING>;
+			status = "disabled";
+		};
+
+		uart2: serial at 402bc000 {
+			compatible = "fsl,s32g2-linflexuart",
+				     "fsl,s32v234-linflexuart";
+			reg = <0 0x402bc000 0 0x3000>;
+			interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
+			status = "disabled";
+		};
+
 		gic: interrupt-controller at 50800000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
-- 
2.30.0



From clin at suse.com  Wed Aug  4 23:54:27 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:27 +0800
Subject: [PATCH 6/8] arm64: dts: s32g2: add VNP-EVB and VNP-RDB2 support
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210805065429.27485-7-clin@suse.com>

Add initial device-trees of NXP S32G2's Evaluation Board (S32G-VNP-EVB)
and Reference Design 2 Board (S32G-VNP-RDB2).

Signed-off-by: Chester Lin <clin at suse.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  2 ++
 .../arm64/boot/dts/freescale/s32g274a-evb.dts | 21 ++++++++++++++++
 .../boot/dts/freescale/s32g274a-rdb2.dts      | 25 +++++++++++++++++++
 3 files changed, 48 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-evb.dts
 create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 4b4785d86324..2886ddd42894 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -67,4 +67,6 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-ai_ml.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
 
+dtb-$(CONFIG_ARCH_S32) += s32g274a-evb.dtb
+dtb-$(CONFIG_ARCH_S32) += s32g274a-rdb2.dtb
 dtb-$(CONFIG_ARCH_S32) += s32v234-evb.dtb
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
new file mode 100644
index 000000000000..a1ae5031730a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2021 SUSE LLC
+ */
+
+/dts-v1/;
+
+#include "s32g2.dtsi"
+
+/ {
+	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
+	compatible = "fsl,s32g274a-evb", "fsl,s32g2";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
new file mode 100644
index 000000000000..b2faae306b70
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright (c) 2021 SUSE LLC
+ */
+
+/dts-v1/;
+
+#include "s32g2.dtsi"
+
+/ {
+	model = "NXP S32G2 Reference Design 2 (S32G-VNP-RDB2)";
+	compatible = "fsl,s32g274a-rdb2", "fsl,s32g2";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
-- 
2.30.0



From clin at suse.com  Wed Aug  4 23:54:28 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:28 +0800
Subject: [PATCH 7/8] arm64: dts: s32g2: add memory nodes for evb and rdb2
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210805065429.27485-8-clin@suse.com>

Add memory nodes for S32G-VNP-EVB and S32G-VNP-RDB2 since they have fixed
RAM size.

Signed-off-by: Chester Lin <clin at suse.com>
---
 arch/arm64/boot/dts/freescale/s32g274a-evb.dts  | 8 ++++++++
 arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts | 8 ++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
index a1ae5031730a..cd41f0af5dd8 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 /*
  * Copyright (c) 2021 SUSE LLC
+ * Copyright 2019-2020 NXP
  */
 
 /dts-v1/;
@@ -14,6 +15,13 @@ / {
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		/* 4GB RAM */
+		reg = <0 0x80000000 0 0x80000000>,
+		      <8 0x80000000 0 0x80000000>;
+	};
 };
 
 &uart0 {
diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
index b2faae306b70..8fbbf3b45eb8 100644
--- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
+++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 /*
  * Copyright (c) 2021 SUSE LLC
+ * Copyright 2019-2020 NXP
  */
 
 /dts-v1/;
@@ -14,6 +15,13 @@ / {
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		/* 4GB RAM */
+		reg = <0 0x80000000 0 0x80000000>,
+		      <8 0x80000000 0 0x80000000>;
+	};
 };
 
 &uart0 {
-- 
2.30.0



From clin at suse.com  Wed Aug  4 23:54:29 2021
From: clin at suse.com (Chester Lin)
Date: Thu,  5 Aug 2021 14:54:29 +0800
Subject: [PATCH 8/8] MAINTAINERS: Add an entry for NXP S32G2 boards
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210805065429.27485-9-clin@suse.com>

Add a new entry for the maintenance of NXP S32G2 DT files.

Signed-off-by: Chester Lin <clin at suse.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 36aee8517ab0..3c6ba6cefd8f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2281,6 +2281,12 @@ F:	arch/arm/boot/dts/nuvoton-wpcm450*
 F:	arch/arm/mach-npcm/wpcm450.c
 F:	drivers/*/*wpcm*
 
+ARM/NXP S32G2 ARCHITECTURE
+M:	Chester Lin <clin at suse.com>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	arch/arm64/boot/dts/freescale/s32g2*
+
 ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
 L:	openmoko-kernel at lists.openmoko.org (subscribers-only)
 S:	Orphan
-- 
2.30.0



From baruch at tkos.co.il  Wed Aug  4 23:58:57 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Thu, 05 Aug 2021 09:58:57 +0300
Subject: [PATCH v2 0/6] arm64: IPQ6018 PCIe support
In-Reply-To: <cover.1620203062.git.baruch@tkos.co.il>
References: <cover.1620203062.git.baruch@tkos.co.il>
Message-ID: <87o8acxtqm.fsf@tarshish>

Hi Lorenzo, Rob, Krzysztof,

On Wed, May 05 2021, Baruch Siach wrote:
> This series adds support for the single PCIe lane on IPQ6018 SoCs. The code is 
> ported from downstream Codeaurora v5.4 kernel. The main difference from 
> downstream code is the split of PCIe registers configuration from .init to 
> .post_init, since it requires phy_power_on().
>
> Tested on IPQ6010 based hardware.

It's been 3 months with no comment. Would you consider applying the dwc
part (patches #1 and #2) for the v5.15 merge window?

I tested the patches here successfully on top of v5.14-rc4.

Thanks,
baruch

>
> Changes in v2:
>
>   * Add patch moving GEN3_RELATED macros to a common header
>
>   * Drop ATU configuration from pcie-qcom
>
>   * Remove local definition of common registers
>
>   * Use bulk clk and reset APIs
>
>   * Remove msi-parent from device-tree
>
> Baruch Siach (3):
>   PCI: dwc: tegra: move GEN3_RELATED DBI register to common header
>   dt-bindings: phy: qcom,qmp: Add IPQ60xx PCIe PHY bindings
>   dt-bindings: pci: qcom: Document PCIe bindings for IPQ6018 SoC
>
> Selvam Sathappan Periakaruppan (3):
>   PCI: qcom: add support for IPQ60xx PCIe controller
>   phy: qcom-qmp: add QMP V2 PCIe PHY support for ipq60xx
>   arm64: dts: ipq6018: Add pcie support
>
>  .../devicetree/bindings/pci/qcom,pcie.txt     |  24 +++
>  .../devicetree/bindings/phy/qcom,qmp-phy.yaml |  25 +++
>  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  99 ++++++++++++
>  drivers/pci/controller/dwc/pcie-designware.h  |   7 +
>  drivers/pci/controller/dwc/pcie-qcom.c        | 150 ++++++++++++++++++
>  drivers/pci/controller/dwc/pcie-tegra194.c    |   6 -
>  drivers/phy/qualcomm/phy-qcom-qmp.c           | 147 +++++++++++++++++
>  drivers/phy/qualcomm/phy-qcom-qmp.h           | 132 +++++++++++++++
>  8 files changed, 584 insertions(+), 6 deletions(-)


-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From michael at walle.cc  Thu Aug  5 00:05:57 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 05 Aug 2021 09:05:57 +0200
Subject: [PATCH 1/1] mfd: simple-mfd-i2c: Add support for registering
 devices via MFD cells
In-Reply-To: <20210804143744.689238-1-lee.jones@linaro.org>
References: <20210804143744.689238-1-lee.jones@linaro.org>
Message-ID: <328e69d4d6d57b101af1ab1346b0809f@walle.cc>

Hi Lee,

Am 2021-08-04 16:37, schrieb Lee Jones:
> More devices are cropping up requiring only Regmap initialisation and
> child registration functionality.  We currently only support that if
> all required devices are represented by their own Device Tree nodes
> complete with compatible strings.
> 
> However, not everyone is happy with adding empty nodes that provide no
> additional device information into the Device Tree.
> 
> Rather than have a plethora of mostly empty, function-less drivers in
> MFD, we'll support those simple cases in here instead via MFD cells.
> 
> Cc: Michael Walle <michael at walle.cc>
> Cc: Mark Brown <broonie at kernel.org>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---
> 
> Michael, could you please test this on your platform to ensure I
>          didn't break anything please?
> 

I'm getting a null pointer dereference.

[..]

>  static int simple_mfd_i2c_probe(struct i2c_client *i2c)
>  {
> -	const struct regmap_config *config;
> +	const struct simple_mfd_data *simple_mfd_data;
> +	const struct regmap_config *regmap_config;
>  	struct regmap *regmap;
> +	int ret;
> +
> +	simple_mfd_data = device_get_match_data(&i2c->dev);
> 
> -	config = device_get_match_data(&i2c->dev);
> -	if (!config)
> -		config = &simple_regmap_config;
> +	if (simple_mfd_data->regmap_config)

simple_mfd_data might be NULL.

> +		regmap_config = simple_mfd_data->regmap_config;
> +	else
> +		regmap_config = &regmap_config_8r_8v;
> 
> -	regmap = devm_regmap_init_i2c(i2c, config);
> +	regmap = devm_regmap_init_i2c(i2c, regmap_config);
>  	if (IS_ERR(regmap))
>  		return PTR_ERR(regmap);
> 
> -	return devm_of_platform_populate(&i2c->dev);
> +	if (!simple_mfd_data->mfd_cell)

likewise

> +		return devm_of_platform_populate(&i2c->dev);
> +
> +	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
> +				   simple_mfd_data->mfd_cell,
> +				   simple_mfd_data->mfd_cell_size,
> +				   NULL, 0, NULL);
> +	if (!ret)
> +		dev_err(&i2c->dev, "Failed to add child devices\n");
> +
> +	return ret;
>  }

-michael


From krzysztof.kozlowski at canonical.com  Thu Aug  5 00:17:14 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 5 Aug 2021 09:17:14 +0200
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <CAPLW+4nY=hozOR+B_0sPZODrk9PXaXg+NB-9pVhDbAjEy7yjhg@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
 <bf21badb-804f-45f0-c02b-80ff57ab9931@canonical.com>
 <CAPLW+4nY=hozOR+B_0sPZODrk9PXaXg+NB-9pVhDbAjEy7yjhg@mail.gmail.com>
Message-ID: <e264f96e-a230-456b-08a5-dbe3a31bdb43@canonical.com>

On 04/08/2021 23:30, Sam Protsenko wrote:
>>>
>>> Nice catch! Actually there is an error (typo?) in SoC's TRM, saying
>>> that Virtual Interface Control Register starts at 0x3000 offset (from
>>> 0x12a00000), where it obviously should be 0x4000, that's probably
>>> where this dts error originates from. Btw, I'm also seeing the same
>>> error in exynos7.dtsi.
>>
>> What's the error exactly? The "Virtual interface control register"
>> offset (3rd region) is set properly to 0x4000 on Exynos7. Also one for
>> the Exynos5433 looks correct.
>>
> 
> The issue is that 2nd region's size is 0x1000, but it must be 0x2000.
> It's defined by GIC-400 architecture, as I understand. Please look at
> [1], table 3-1 has very specific offsets and sizes for each functional
> block, and each particular SoC must adhere to that spec. So having
> 0x1000 for 2nd region can't be correct. And because exynos7.dtsi has
> GIC-400 as well, and 0x1000 is specified there for 2nd region size
> too, so I presume there is the same mistake there.

I understand, the range length has indeed same mistake. However it does
not matter that much There are no registers pass 0x10C (so pass 0x1000).
This address space is not used.

> Can you please check the TRM for Exynos7 SoC (if you have one in your
> possession), and see if there is a typo there? E.g. in case of
> Exynos850 TRM I can see that in "Register Map Summary" section the
> offset for the first register (GICH_HCR) in "Virtual Interface Control
> Register" region is specified as 0x3000, where it should be 0x4000, so
> it's probably a typo. But the register description is correct, saying
> that: "Address = Base Address + 0x4000".

The starting addresses of each registers range is different issue and
this one matters. Except same typo as you say, all looks good - they
start at 0x4000.

> 
> [1] https://developer.arm.com/documentation/ddi0471/b/programmers-model/gic-400-register-map

> 
>>> Though I don't have a TRM for Exynos7 SoCs, so
>>> not sure if I should go ahead and fix that too. Anyway, for Exynos850,
>>> I'll fix that in v2 series.
>>
>>
>> However while we are at addresses - why are you using address-cells 2?
>> It adds everywhere additional 0x0 before actual address.
>>
> 
> Right. For "cpus" node I'll change the address-cells to 1 in my v2
> series. I'll keep address-cells=2 for the root node, but I'm going to
> encapsulate some nodes into soc node (as you suggested earlier), where
> I'll make address-cells=1. That's pretty much how it's done in
> exynos7.dtsi and in exynos5433.dtsi, so I guess that's should be fine
> (to get rid of superfluous 0x0 and conform with other Exynos DTs)?

Yes, thanks.


Best regards,
Krzysztof


From m.szyprowski at samsung.com  Thu Aug  5 00:18:50 2021
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Thu, 5 Aug 2021 09:18:50 +0200
Subject: [PATCH v3 01/25] iommu: Pull IOVA cookie management into the core
In-Reply-To: <46f4cda8215bd5f8a9f9fd5a4a6451805f75efa3.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <CGME20210804171613eucas1p2a1884dfd6436605d8aa58ca106a59804@eucas1p2.samsung.com>
 <46f4cda8215bd5f8a9f9fd5a4a6451805f75efa3.1628094600.git.robin.murphy@arm.com>
Message-ID: <6bfafe1c-fc8f-8836-fb80-c6a61788ddc8@samsung.com>


On 04.08.2021 19:15, Robin Murphy wrote:
> Now that everyone has converged on iommu-dma for IOMMU_DOMAIN_DMA
> support, we can abandon the notion of drivers being responsible for the
> cookie type, and consolidate all the management into the core code.
>
> CC: Marek Szyprowski <m.szyprowski at samsung.com>
> CC: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
> CC: Geert Uytterhoeven <geert+renesas at glider.be>
> CC: Yong Wu <yong.wu at mediatek.com>
> CC: Heiko Stuebner <heiko at sntech.de>
> CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
> CC: Maxime Ripard <mripard at kernel.org>
> Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
>
> ---
>
> v3: Use a simpler temporary check instead of trying to be clever with
>      the error code
> ---
>   drivers/iommu/iommu.c | 7 +++++++
>   include/linux/iommu.h | 3 ++-
>   2 files changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index f2cda9950bd5..b65fcc66ffa4 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -7,6 +7,7 @@
>   #define pr_fmt(fmt)    "iommu: " fmt
>   
>   #include <linux/device.h>
> +#include <linux/dma-iommu.h>
>   #include <linux/kernel.h>
>   #include <linux/bits.h>
>   #include <linux/bug.h>
> @@ -1946,6 +1947,11 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
>   	/* Assume all sizes by default; the driver may override this later */
>   	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
>   
> +	/* Temporarily avoid -EEXIST while drivers still get their own cookies */
> +	if (type == IOMMU_DOMAIN_DMA && !domain->iova_cookie && iommu_get_dma_cookie(domain)) {
> +		iommu_domain_free(domain);
> +		domain = NULL;
> +	}
>   	return domain;
>   }
>   
> @@ -1957,6 +1963,7 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
>   
>   void iommu_domain_free(struct iommu_domain *domain)
>   {
> +	iommu_put_dma_cookie(domain);
>   	domain->ops->domain_free(domain);
>   }
>   EXPORT_SYMBOL_GPL(iommu_domain_free);
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 4997c78e2670..141779d76035 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -40,6 +40,7 @@ struct iommu_domain;
>   struct notifier_block;
>   struct iommu_sva;
>   struct iommu_fault_event;
> +struct iommu_dma_cookie;
>   
>   /* iommu fault flags */
>   #define IOMMU_FAULT_READ	0x0
> @@ -86,7 +87,7 @@ struct iommu_domain {
>   	iommu_fault_handler_t handler;
>   	void *handler_token;
>   	struct iommu_domain_geometry geometry;
> -	void *iova_cookie;
> +	struct iommu_dma_cookie *iova_cookie;
>   };
>   
>   enum iommu_cap {

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



From m.szyprowski at samsung.com  Thu Aug  5 00:19:23 2021
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Thu, 5 Aug 2021 09:19:23 +0200
Subject: [PATCH v3 05/25] iommu/exynos: Drop IOVA cookie management
In-Reply-To: <fc13c3abc2939825f20ba4733ac8abb90b58528f.1628094601.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <CGME20210804171621eucas1p2753f1185eb87c4a137e99e1ac2cc10d3@eucas1p2.samsung.com>
 <fc13c3abc2939825f20ba4733ac8abb90b58528f.1628094601.git.robin.murphy@arm.com>
Message-ID: <28ba8847-b441-2937-7f9e-8b117abb6295@samsung.com>


On 04.08.2021 19:15, Robin Murphy wrote:
> The core code bakes its own cookies now.
>
> CC: Marek Szyprowski <m.szyprowski at samsung.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Acked-by: Marek Szyprowski <m.szyprowski at samsung.com>

Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>

> ---
>
> v3: Also remove unneeded include
> ---
>   drivers/iommu/exynos-iommu.c | 19 ++++---------------
>   1 file changed, 4 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index d0fbf1d10e18..939ffa768986 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -21,7 +21,6 @@
>   #include <linux/platform_device.h>
>   #include <linux/pm_runtime.h>
>   #include <linux/slab.h>
> -#include <linux/dma-iommu.h>
>   
>   typedef u32 sysmmu_iova_t;
>   typedef u32 sysmmu_pte_t;
> @@ -735,20 +734,16 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
>   	/* Check if correct PTE offsets are initialized */
>   	BUG_ON(PG_ENT_SHIFT < 0 || !dma_dev);
>   
> +	if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED)
> +		return NULL;
> +
>   	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
>   	if (!domain)
>   		return NULL;
>   
> -	if (type == IOMMU_DOMAIN_DMA) {
> -		if (iommu_get_dma_cookie(&domain->domain) != 0)
> -			goto err_pgtable;
> -	} else if (type != IOMMU_DOMAIN_UNMANAGED) {
> -		goto err_pgtable;
> -	}
> -
>   	domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
>   	if (!domain->pgtable)
> -		goto err_dma_cookie;
> +		goto err_pgtable;
>   
>   	domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
>   	if (!domain->lv2entcnt)
> @@ -779,9 +774,6 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
>   	free_pages((unsigned long)domain->lv2entcnt, 1);
>   err_counter:
>   	free_pages((unsigned long)domain->pgtable, 2);
> -err_dma_cookie:
> -	if (type == IOMMU_DOMAIN_DMA)
> -		iommu_put_dma_cookie(&domain->domain);
>   err_pgtable:
>   	kfree(domain);
>   	return NULL;
> @@ -809,9 +801,6 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
>   
>   	spin_unlock_irqrestore(&domain->lock, flags);
>   
> -	if (iommu_domain->type == IOMMU_DOMAIN_DMA)
> -		iommu_put_dma_cookie(iommu_domain);
> -
>   	dma_unmap_single(dma_dev, virt_to_phys(domain->pgtable), LV1TABLE_SIZE,
>   			 DMA_TO_DEVICE);
>   

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



From krzysztof.kozlowski at canonical.com  Thu Aug  5 00:21:10 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu,  5 Aug 2021 09:21:10 +0200
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address range
 on Exynos7
Message-ID: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>

The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF (by
ARM).

Reported-by: Sam Protsenko <semen.protsenko at linaro.org>
Reported-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos7.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index 8b06397ba6e7..c73a597ca66e 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -137,7 +137,7 @@ gic: interrupt-controller at 11001000 {
 			#address-cells = <0>;
 			interrupt-controller;
 			reg =	<0x11001000 0x1000>,
-				<0x11002000 0x1000>,
+				<0x11002000 0x2000>,
 				<0x11004000 0x2000>,
 				<0x11006000 0x2000>;
 		};
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Thu Aug  5 00:25:25 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu,  5 Aug 2021 09:25:25 +0200
Subject: [PATCH 1/8] ARM: dts: exynos: add CPU topology to Exynos3250
In-Reply-To: <20210731092409.31496-1-krzysztof.kozlowski@canonical.com>
References: <20210731092409.31496-1-krzysztof.kozlowski@canonical.com>
Message-ID: <162814831970.6166.12328372184939604484.b4-ty@canonical.com>

On Sat, 31 Jul 2021 11:24:02 +0200, Krzysztof Kozlowski wrote:
> Describe Exynos3250 CPU topology.

Applied, thanks!

[1/8] ARM: dts: exynos: add CPU topology to Exynos3250
      commit: a2798e309f3c67ab69073582dc4b8102a9013e25
[2/8] ARM: dts: exynos: add CPU topology to Exynos4210
      commit: 900dd07d13e46b2937522ac7cc46a9ceb49284b6
[3/8] ARM: dts: exynos: add CPU topology to Exynos4412
      commit: 1fb5b5b0dc491613eaa42bc39457589bfcb2b2b9
[4/8] ARM: dts: exynos: add CPU topology to Exynos5250
      commit: fc6d5c9953757c61042676db9bb32ecd7af958f3
[5/8] ARM: dts: exynos: add CPU topology to Exynos5260
      commit: fa0c56dbc3a1b116d280c3a3a97052ea38e4ea2b
[6/8] ARM: dts: exynos: add CPU topology to Exynos5420
      commit: a73d3069f6f7717bbd31a2fcfe8ddb3d98076b1d
[7/8] ARM: dts: exynos: add CPU topology to Exynos5422
      commit: 6cad6db75231a18f25dc7d610d5a0683160ac545
[8/8] arm64: dts: exynos: add CPU topology to Exynos5433
      commit: 0cdcca7ec37cfe54cd2f0668eddcf5aef87a05e3

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From maz at kernel.org  Thu Aug  5 00:30:30 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 05 Aug 2021 08:30:30 +0100
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <e264f96e-a230-456b-08a5-dbe3a31bdb43@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
 <bf21badb-804f-45f0-c02b-80ff57ab9931@canonical.com>
 <CAPLW+4nY=hozOR+B_0sPZODrk9PXaXg+NB-9pVhDbAjEy7yjhg@mail.gmail.com>
 <e264f96e-a230-456b-08a5-dbe3a31bdb43@canonical.com>
Message-ID: <87zgtwbb6x.wl-maz@kernel.org>

On Thu, 05 Aug 2021 08:17:14 +0100,
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
> 
> On 04/08/2021 23:30, Sam Protsenko wrote:
> >>>
> >>> Nice catch! Actually there is an error (typo?) in SoC's TRM, saying
> >>> that Virtual Interface Control Register starts at 0x3000 offset (from
> >>> 0x12a00000), where it obviously should be 0x4000, that's probably
> >>> where this dts error originates from. Btw, I'm also seeing the same
> >>> error in exynos7.dtsi.
> >>
> >> What's the error exactly? The "Virtual interface control register"
> >> offset (3rd region) is set properly to 0x4000 on Exynos7. Also one for
> >> the Exynos5433 looks correct.
> >>
> > 
> > The issue is that 2nd region's size is 0x1000, but it must be 0x2000.
> > It's defined by GIC-400 architecture, as I understand. Please look at
> > [1], table 3-1 has very specific offsets and sizes for each functional
> > block, and each particular SoC must adhere to that spec. So having
> > 0x1000 for 2nd region can't be correct. And because exynos7.dtsi has
> > GIC-400 as well, and 0x1000 is specified there for 2nd region size
> > too, so I presume there is the same mistake there.
> 
> I understand, the range length has indeed same mistake. However it does
> not matter that much There are no registers pass 0x10C (so pass 0x1000).
> This address space is not used.

I have no idea which spec you are looking at, but the GICv2
architecture (of which GIC400 is an implementation) definitely has a
register in the second 4kB page of the CPU interface. It contains the
GICC_DIR register, which is used to deactivate an interrupt when
EOIMode==1.

Linux actively uses it when started at EL2.

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzysztof.kozlowski at canonical.com  Thu Aug  5 00:35:12 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 5 Aug 2021 09:35:12 +0200
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <87zgtwbb6x.wl-maz@kernel.org>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
 <bf21badb-804f-45f0-c02b-80ff57ab9931@canonical.com>
 <CAPLW+4nY=hozOR+B_0sPZODrk9PXaXg+NB-9pVhDbAjEy7yjhg@mail.gmail.com>
 <e264f96e-a230-456b-08a5-dbe3a31bdb43@canonical.com>
 <87zgtwbb6x.wl-maz@kernel.org>
Message-ID: <f9b233bb-628f-1a0f-468c-8a6c7d2b23a4@canonical.com>

On 05/08/2021 09:30, Marc Zyngier wrote:
> On Thu, 05 Aug 2021 08:17:14 +0100,
> Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 04/08/2021 23:30, Sam Protsenko wrote:
>>>>>
>>>>> Nice catch! Actually there is an error (typo?) in SoC's TRM, saying
>>>>> that Virtual Interface Control Register starts at 0x3000 offset (from
>>>>> 0x12a00000), where it obviously should be 0x4000, that's probably
>>>>> where this dts error originates from. Btw, I'm also seeing the same
>>>>> error in exynos7.dtsi.
>>>>
>>>> What's the error exactly? The "Virtual interface control register"
>>>> offset (3rd region) is set properly to 0x4000 on Exynos7. Also one for
>>>> the Exynos5433 looks correct.
>>>>
>>>
>>> The issue is that 2nd region's size is 0x1000, but it must be 0x2000.
>>> It's defined by GIC-400 architecture, as I understand. Please look at
>>> [1], table 3-1 has very specific offsets and sizes for each functional
>>> block, and each particular SoC must adhere to that spec. So having
>>> 0x1000 for 2nd region can't be correct. And because exynos7.dtsi has
>>> GIC-400 as well, and 0x1000 is specified there for 2nd region size
>>> too, so I presume there is the same mistake there.
>>
>> I understand, the range length has indeed same mistake. However it does
>> not matter that much There are no registers pass 0x10C (so pass 0x1000).
>> This address space is not used.
> 
> I have no idea which spec you are looking at, but the GICv2
> architecture (of which GIC400 is an implementation) definitely has a
> register in the second 4kB page of the CPU interface. It contains the
> GICC_DIR register, which is used to deactivate an interrupt when
> EOIMode==1.
> 
> Linux actively uses it when started at EL2.

I was checking Exynos TRM and it seems it has one more bug... The ARM
datasheet [1] indeed mentions GICC_DIR at 0x1000. I'll add "Fixes" tag
to my fix for Exynos7.

https://developer.arm.com/documentation/ddi0471/b/programmers-model/cpu-interface-register-summary



Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Aug  5 00:36:47 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 5 Aug 2021 09:36:47 +0200
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
Message-ID: <b0d6ff2a-24af-96c1-62a1-8b920c63e05a@canonical.com>

On 05/08/2021 09:21, Krzysztof Kozlowski wrote:
> The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF (by
> ARM).
> 

I underestimated the issue - this is actually bug as there is a GICC_DIR
register at offset 0x1000. Therefore:

Fixes: b9024cbc937d ("arm64: dts: Add initial device tree support for exynos7")

> Reported-by: Sam Protsenko <semen.protsenko at linaro.org>
> Reported-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  arch/arm64/boot/dts/exynos/exynos7.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> index 8b06397ba6e7..c73a597ca66e 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> @@ -137,7 +137,7 @@ gic: interrupt-controller at 11001000 {
>  			#address-cells = <0>;
>  			interrupt-controller;
>  			reg =	<0x11001000 0x1000>,
> -				<0x11002000 0x1000>,
> +				<0x11002000 0x2000>,
>  				<0x11004000 0x2000>,
>  				<0x11006000 0x2000>;
>  		};
> 


Best regards,
Krzysztof


From lkp at intel.com  Thu Aug  5 00:37:29 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 5 Aug 2021 15:37:29 +0800
Subject: [PATCH v3 02/25] iommu/amd: Drop IOVA cookie management
In-Reply-To: <ebc82f082d5fde58557efbec66f34b1be6a12599.1628094600.git.robin.murphy@arm.com>
References: <ebc82f082d5fde58557efbec66f34b1be6a12599.1628094600.git.robin.murphy@arm.com>
Message-ID: <202108051548.0vHec4lm-lkp@intel.com>

Hi Robin,

I love your patch! Yet something to improve:

[auto build test ERROR on iommu/next]
[also build test ERROR on rockchip/for-next sunxi/sunxi/for-next linus/master v5.14-rc4 next-20210804]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Robin-Murphy/iommu-Refactor-DMA-domain-strictness/20210805-011913
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/33b83e4adc16220361ed42c229e8cd37f8a2a3aa
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Robin-Murphy/iommu-Refactor-DMA-domain-strictness/20210805-011913
        git checkout 33b83e4adc16220361ed42c229e8cd37f8a2a3aa
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/iommu/amd/iommu.c: In function 'amd_iommu_probe_finalize':
>> drivers/iommu/amd/iommu.c:1757:3: error: implicit declaration of function 'iommu_setup_dma_ops'; did you mean 'arch_setup_dma_ops'? [-Werror=implicit-function-declaration]
    1757 |   iommu_setup_dma_ops(dev, 0, U64_MAX);
         |   ^~~~~~~~~~~~~~~~~~~
         |   arch_setup_dma_ops
   cc1: some warnings being treated as errors


vim +1757 drivers/iommu/amd/iommu.c

1ac4cbbc5eb56d arch/x86/kernel/amd_iommu.c Joerg Roedel          2008-12-10  1749  
dce8d6964ebdb3 drivers/iommu/amd_iommu.c   Joerg Roedel          2020-04-29  1750  static void amd_iommu_probe_finalize(struct device *dev)
dce8d6964ebdb3 drivers/iommu/amd_iommu.c   Joerg Roedel          2020-04-29  1751  {
dce8d6964ebdb3 drivers/iommu/amd_iommu.c   Joerg Roedel          2020-04-29  1752  	struct iommu_domain *domain;
ac1534a55d1e87 drivers/iommu/amd_iommu.c   Joerg Roedel          2012-06-21  1753  
07ee86948c9111 drivers/iommu/amd_iommu.c   Joerg Roedel          2015-05-28  1754  	/* Domains are initialized for this device - have a look what we ended up with */
07ee86948c9111 drivers/iommu/amd_iommu.c   Joerg Roedel          2015-05-28  1755  	domain = iommu_get_domain_for_dev(dev);
57f9842e488406 drivers/iommu/amd_iommu.c   Joerg Roedel          2020-04-29  1756  	if (domain->type == IOMMU_DOMAIN_DMA)
ac6d704679d343 drivers/iommu/amd/iommu.c   Jean-Philippe Brucker 2021-06-18 @1757  		iommu_setup_dma_ops(dev, 0, U64_MAX);
d6177a6556f853 drivers/iommu/amd/iommu.c   Jean-Philippe Brucker 2021-04-22  1758  	else
d6177a6556f853 drivers/iommu/amd/iommu.c   Jean-Philippe Brucker 2021-04-22  1759  		set_dma_ops(dev, NULL);
e275a2a0fc9e21 arch/x86/kernel/amd_iommu.c Joerg Roedel          2008-12-10  1760  }
e275a2a0fc9e21 arch/x86/kernel/amd_iommu.c Joerg Roedel          2008-12-10  1761  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 65630 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210805/558fae21/attachment-0001.gz>

From maz at kernel.org  Thu Aug  5 00:39:20 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 05 Aug 2021 08:39:20 +0100
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <CAPLW+4mMF9B2BiY2hTgHz5=DNbDJZ7TDzt=Xefb5tDKwQhpEew@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
 <87k0l1w8y5.wl-maz@kernel.org>
 <CAPLW+4mMF9B2BiY2hTgHz5=DNbDJZ7TDzt=Xefb5tDKwQhpEew@mail.gmail.com>
Message-ID: <87y29gbas7.wl-maz@kernel.org>

On Wed, 04 Aug 2021 19:37:24 +0100,
Sam Protsenko <semen.protsenko at linaro.org> wrote:
> 
> On Wed, 4 Aug 2021 at 18:01, Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Wed, 04 Aug 2021 15:39:38 +0100,
> > Sam Protsenko <semen.protsenko at linaro.org> wrote:
> >
> > > > You are also missing the hypervisor virtual timer interrupt.
> > > >
> > >
> > > Checked SoC TRM, there is no PPI for hypervisor virtual timer
> > > interrupt, and no mentioning of it at all. Likewise, I checked ARMv8
> > > ARM and TRM, almost no description of it. Also, I checked other
> > > platforms, and seems like everyone does the same (having only 4
> > > interrupts). And I wasn't able to find any documentation on that, so I
> > > guess I'll leave it as is, if you don't mind.
> >
> > I *do* mind, and other DTs being wrong isn't a good enough excuse! ;-)
> >
> > From the ARMv8 ARM (ARM DDI 0487G.b)
> > <quote>
> > D11.2.4 Timers
> >
> > In an implementation of the Generic Timer that includes EL3, if EL3
> > can use AArch64, the following timers are implemented:
> >
> > * An EL1 physical timer, that:
> >   - In Secure state, can be accessed from EL1.
> >   - In Non-secure state, can be accessed from EL1 unless those
> >     accesses are trapped to EL2.
> >     When this timer can be accessed from EL1, an EL1 control
> >     determines whether it can be accessed from EL0.
> > * A Non-secure EL2 physical timer.
> > * A Secure EL3 physical timer. An EL3 control determines whether this
> >   register is accessible from Secure EL1.
> > * An EL1 virtual timer.
> > * When FEAT_VHE is implemented, a Non-secure EL2 virtual timer.
> > * When FEAT_SEL2 is implemented, a Secure EL2 physical timer.
> > * When FEAT_SEL2 is implemented, a Secure EL2 virtual timer.
> > </quote>
> >
> > Cortex-A55 being an ARMv8.2 implementation, it has FEAT_VHE, and thus
> > it does have a NS-EL2 virtual timer. This is further confirmed by the
> > TRM which documents CNTHV*_EL2 as valid system registers[1].
> >
> > So the timer exists, the signal is routed out of the core, and it
> > is likely that it is connected to the GIC.
> >
> > If the designers have omitted it, then it needs to be documented as
> > such.
> >
> 
> Ok, I've checked thoroughly all docs again, and it seems like there is
> no dedicated PPI number for this "EL2 Hypervisor Virtual Timer" in
> Exynos850 SoC. The timer instance itself might exist of course, but
> interrupt line is probably wasn't connected to GIC by SoC designers,
> at least it's not documented.

Can you try and check this? You can directly program the virtual timer
so that it has a pending interrupt, and then check the pending
register on the same CPU to see if there is anything appearing there.

> Moreover, from [1,2] it looks like if it were existing it would have
> been PPI=12 (INTID=28). But in GIC-400 TRM this PPI is assigned to
> "Legacy FIQ signal",

No. That's only if you set the bypass bits in GICD_CTLR, which nobody
with half a brain would consider doing.

> and all there is no PPI for Hypervisor Virtual
> Timer documented there as well. In Exynos850 TRM the source for this
> PPI's interrupt source is marked as "-", which means it's not used.
>
> So if you know something that I don't know -- please point me out the
> doc where this PPI line is documented. Otherwise I can add the comment
> to device tree, stating that this interrupt line is not present in
> SoC's GIC, i.e. something like this:
> 
> 8<------------------------------------------------------------------------------->8
>     timer {
>         compatible = "arm,armv8-timer";
>         interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) |
>                       IRQ_TYPE_LEVEL_LOW)>,
>                  <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) |
>                       IRQ_TYPE_LEVEL_LOW)>,
>                  <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) |
>                       IRQ_TYPE_LEVEL_LOW)>,
>                  <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) |
>                       IRQ_TYPE_LEVEL_LOW)>;
>         /* Hypervisor Virtual Timer PPI is not present in this SoC GIC */
>     };
> 8<------------------------------------------------------------------------------->8
> 
> Is that ok with you?

I'd rather you verify the above first. And if you can't, I'd like a
comment that is a bit more explicit:

/* The vendor couldn't be bothered to wire the EL2 Virtual Timers */

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From lee.jones at linaro.org  Thu Aug  5 00:40:05 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 5 Aug 2021 08:40:05 +0100
Subject: [PATCH 1/1] mfd: simple-mfd-i2c: Add support for registering
 devices via MFD cells
In-Reply-To: <328e69d4d6d57b101af1ab1346b0809f@walle.cc>
References: <20210804143744.689238-1-lee.jones@linaro.org>
 <328e69d4d6d57b101af1ab1346b0809f@walle.cc>
Message-ID: <YQuV1bhnv5QHGqNR@google.com>

On Thu, 05 Aug 2021, Michael Walle wrote:

> Hi Lee,
> 
> Am 2021-08-04 16:37, schrieb Lee Jones:
> > More devices are cropping up requiring only Regmap initialisation and
> > child registration functionality.  We currently only support that if
> > all required devices are represented by their own Device Tree nodes
> > complete with compatible strings.
> > 
> > However, not everyone is happy with adding empty nodes that provide no
> > additional device information into the Device Tree.
> > 
> > Rather than have a plethora of mostly empty, function-less drivers in
> > MFD, we'll support those simple cases in here instead via MFD cells.
> > 
> > Cc: Michael Walle <michael at walle.cc>
> > Cc: Mark Brown <broonie at kernel.org>
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> > ---
> > 
> > Michael, could you please test this on your platform to ensure I
> >          didn't break anything please?
> > 
> 
> I'm getting a null pointer dereference.

Perfect.  Will fix.

Thanks for testing.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From qiangqing.zhang at nxp.com  Thu Aug  5 00:46:12 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Thu,  5 Aug 2021 15:46:12 +0800
Subject: [PATCH net-next 0/3] net: fec: add support to select wakeup irq source
Message-ID: <20210805074615.29096-1-qiangqing.zhang@nxp.com>

This patch set intends to add support to select wakeup irq source.

Joakim Zhang (3):
  dt-bindings: net: fsl,fec: add "fsl,wakeup-irq" property
  net: fec: add support to select wakeup irq source
  arm64: dts: imx8m: add "fsl,wakeup-irq" property for FEC

 .../devicetree/bindings/net/fsl,fec.yaml          |  7 +++++++
 arch/arm64/boot/dts/freescale/imx8mm.dtsi         |  1 +
 arch/arm64/boot/dts/freescale/imx8mn.dtsi         |  1 +
 arch/arm64/boot/dts/freescale/imx8mp.dtsi         |  1 +
 arch/arm64/boot/dts/freescale/imx8mq.dtsi         |  1 +
 drivers/net/ethernet/freescale/fec.h              |  1 +
 drivers/net/ethernet/freescale/fec_main.c         | 15 +++++++++++----
 7 files changed, 23 insertions(+), 4 deletions(-)

-- 
2.17.1



From qiangqing.zhang at nxp.com  Thu Aug  5 00:46:13 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Thu,  5 Aug 2021 15:46:13 +0800
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
Message-ID: <20210805074615.29096-2-qiangqing.zhang@nxp.com>

Add "fsl,wakeup-irq" property for FEC controller to select wakeup irq
source.

Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
---
 Documentation/devicetree/bindings/net/fsl,fec.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/fsl,fec.yaml b/Documentation/devicetree/bindings/net/fsl,fec.yaml
index eca41443fcce..d83f2103c1e6 100644
--- a/Documentation/devicetree/bindings/net/fsl,fec.yaml
+++ b/Documentation/devicetree/bindings/net/fsl,fec.yaml
@@ -164,6 +164,13 @@ properties:
       req_gpr is the gpr register offset for ENET stop request.
       req_bit is the gpr bit offset for ENET stop request.
 
+  fsl,wakeup-irq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      The property defines the wakeup irq index in enet irq source, the default
+      value is 0 if not specified.
+    enum: [0, 1, 2, 3]
+
   mdio:
     type: object
     description:
-- 
2.17.1



From qiangqing.zhang at nxp.com  Thu Aug  5 00:46:14 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Thu,  5 Aug 2021 15:46:14 +0800
Subject: [PATCH net-next 2/3] net: fec: add support to select wakeup irq source
In-Reply-To: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
Message-ID: <20210805074615.29096-3-qiangqing.zhang@nxp.com>

The FEC driver default treats irq[0] as wakeup source, but this situation
changed on i.MX8M SoCs, this patch adds support to select wakeup irq
source with "fsl,wakeup-irq" property.

Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
---
 drivers/net/ethernet/freescale/fec.h      |  1 +
 drivers/net/ethernet/freescale/fec_main.c | 15 +++++++++++----
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index ae3259164395..fe4dfe2d25ea 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -578,6 +578,7 @@ struct fec_enet_private {
 	bool	bufdesc_ex;
 	int	pause_flag;
 	int	wol_flag;
+	int     wake_irq;
 	u32	quirks;
 
 	struct	napi_struct napi;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 1201c13afa6f..c422a309d33c 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2878,12 +2878,12 @@ fec_enet_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
 	device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC);
 	if (device_may_wakeup(&ndev->dev)) {
 		fep->wol_flag |= FEC_WOL_FLAG_ENABLE;
-		if (fep->irq[0] > 0)
-			enable_irq_wake(fep->irq[0]);
+		if (fep->wake_irq > 0)
+			enable_irq_wake(fep->wake_irq);
 	} else {
 		fep->wol_flag &= (~FEC_WOL_FLAG_ENABLE);
-		if (fep->irq[0] > 0)
-			disable_irq_wake(fep->irq[0]);
+		if (fep->wake_irq > 0)
+			disable_irq_wake(fep->wake_irq);
 	}
 
 	return 0;
@@ -3935,6 +3935,13 @@ fec_probe(struct platform_device *pdev)
 		fep->irq[i] = irq;
 	}
 
+	/* Get wakeup irq */
+	ret = of_property_read_u32(np, "fsl,wakeup-irq", &irq);
+	if (!ret && irq >= 0 && irq < irq_cnt)
+		fep->wake_irq = fep->irq[irq];
+	else
+		fep->wake_irq = fep->irq[0];
+
 	ret = fec_enet_mii_init(pdev);
 	if (ret)
 		goto failed_mii_init;
-- 
2.17.1



From qiangqing.zhang at nxp.com  Thu Aug  5 00:46:15 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Thu,  5 Aug 2021 15:46:15 +0800
Subject: [PATCH net-next 3/3] arm64: dts: imx8m: add "fsl,
 wakeup-irq" property for FEC
In-Reply-To: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
Message-ID: <20210805074615.29096-4-qiangqing.zhang@nxp.com>

Add "fsl,wakeup-irq" property for FEC to provide wakeup irq source.

Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 1 +
 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 1 +
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 1 +
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 1 +
 4 files changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 1608a48495b6..11aac9209944 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -948,6 +948,7 @@
 				nvmem-cell-names = "mac-address";
 				nvmem_macaddr_swap;
 				fsl,stop-mode = <&gpr 0x10 3>;
+				fsl,wakeup-irq = <2>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index e6de293865b0..2c921ba519dd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -951,6 +951,7 @@
 				nvmem-cell-names = "mac-address";
 				nvmem_macaddr_swap;
 				fsl,stop-mode = <&gpr 0x10 3>;
+				fsl,wakeup-irq = <2>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index f4eaab3ecf03..ce4efe0a9bca 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -814,6 +814,7 @@
 				nvmem-cells = <&eth_mac1>;
 				nvmem-cell-names = "mac-address";
 				fsl,stop-mode = <&gpr 0x10 3>;
+				fsl,wakeup-irq = <2>;
 				nvmem_macaddr_swap;
 				status = "disabled";
 			};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 91df9c5350ae..d7b68630098b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1191,6 +1191,7 @@
 				nvmem-cell-names = "mac-address";
 				nvmem_macaddr_swap;
 				fsl,stop-mode = <&iomuxc_gpr 0x10 3>;
+				fsl,wakeup-irq = <2>;
 				status = "disabled";
 			};
 		};
-- 
2.17.1



From jirislaby at kernel.org  Thu Aug  5 00:47:12 2021
From: jirislaby at kernel.org (Jiri Slaby)
Date: Thu, 5 Aug 2021 09:47:12 +0200
Subject: [PATCH printk v1 10/10] serial: 8250: implement write_atomic
In-Reply-To: <YQlNtr7TNAWtB8XF@smile.fi.intel.com>
References: <20210803131301.5588-1-john.ogness@linutronix.de>
 <20210803131301.5588-11-john.ogness@linutronix.de>
 <YQlNtr7TNAWtB8XF@smile.fi.intel.com>
Message-ID: <931ebc1a-3cc9-677c-44c3-7cbd645eb4f4@kernel.org>

On 03. 08. 21, 16:07, Andy Shevchenko wrote:
> On Tue, Aug 03, 2021 at 03:19:01PM +0206, John Ogness wrote:
>> Implement an NMI-safe write_atomic() console function in order to
>> support synchronous console printing.
>>
>> Since interrupts need to be disabled during transmit, all usage of
>> the IER register is wrapped with access functions that use the
>> printk cpulock to synchronize register access while tracking the
>> state of the interrupts. This is necessary because write_atomic()
>> can be called from an NMI context that has preempted write_atomic().
> 
> ...
> 
>> +static inline void serial8250_set_IER(struct uart_8250_port *up,
>> +				      unsigned char ier)
>> +{
>> +	struct uart_port *port = &up->port;
>> +	unsigned long flags;
>> +	bool is_console;
> 
>> +	is_console = uart_console(port);
>> +
>> +	if (is_console)
>> +		console_atomic_cpu_lock(flags);
>> +
>> +	serial_out(up, UART_IER, ier);
>> +
>> +	if (is_console)
>> +		console_atomic_cpu_unlock(flags);
> 
> I would rewrite it as
> 
> 	if (uart_console()) {
> 		console_atomic_cpu_lock(flags);
> 		serial_out(up, UART_IER, ier);
> 		console_atomic_cpu_unlock(flags);
> 	} else {
> 		serial_out(up, UART_IER, ier);
> 	}
> 
> No additional variable, easier to get the algorithm on the first glance, less
> error prone.

Yes, the original is terrible.

Another option:

bool locked = console_atomic_cpu_lock(flags, uart_console());
serial_out(up, UART_IER, ier);
console_atomic_cpu_unlock(flags, locked);


Which makes console_atomic_cpu_lock to lock only if second parameter is 
true and return its value too.

BTW I actually don't know what console_atomic_cpu_lock does to think 
about it more as I was not CCed, and neither lore sees the other patches:
https://lore.kernel.org/linux-mips/20210803131301.5588-1-john.ogness at linutronix.de/

thanks,
-- 
js
suse labs


From krzk at kernel.org  Thu Aug  5 00:49:51 2021
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 5 Aug 2021 09:49:51 +0200
Subject: [PATCH 8/8] MAINTAINERS: Add an entry for NXP S32G2 boards
In-Reply-To: <20210805065429.27485-9-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-9-clin@suse.com>
Message-ID: <32310c2a-9800-8b04-b6ac-d8ada044c0f8@kernel.org>

On 05/08/2021 08:54, Chester Lin wrote:
> Add a new entry for the maintenance of NXP S32G2 DT files.
> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  MAINTAINERS | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 36aee8517ab0..3c6ba6cefd8f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2281,6 +2281,12 @@ F:	arch/arm/boot/dts/nuvoton-wpcm450*
>  F:	arch/arm/mach-npcm/wpcm450.c
>  F:	drivers/*/*wpcm*
>  
> +ARM/NXP S32G2 ARCHITECTURE
> +M:	Chester Lin <clin at suse.com>
> +L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> +S:	Maintained
> +F:	arch/arm64/boot/dts/freescale/s32g2*

I support the idea of sub-sub-architecture maintainers but I think idea
of in-file addresses was preferred:
https://lore.kernel.org/lkml/20200830122922.3884-1-shawnguo at kernel.org/


Best regards,
Krzysztof


From lee.jones at linaro.org  Thu Aug  5 00:50:31 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Thu,  5 Aug 2021 08:50:31 +0100
Subject: [PATCH 2/3] reboot: Export reboot_mode
In-Reply-To: <20210805075032.723037-1-lee.jones@linaro.org>
References: <20210805075032.723037-1-lee.jones@linaro.org>
Message-ID: <20210805075032.723037-3-lee.jones@linaro.org>

From: Elliot Berman <eberman at codeaurora.org>

Export reboot_mode to support kernel modules wishing to modify reboot_mode.

Signed-off-by: Elliot Berman <eberman at codeaurora.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>
Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 kernel/reboot.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/reboot.c b/kernel/reboot.c
index a6ad5eb2fa733..7ca414aa070b6 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -32,7 +32,9 @@ EXPORT_SYMBOL(cad_pid);
 #define DEFAULT_REBOOT_MODE
 #endif
 enum reboot_mode reboot_mode DEFAULT_REBOOT_MODE;
+EXPORT_SYMBOL_GPL(reboot_mode);
 enum reboot_mode panic_reboot_mode = REBOOT_UNDEFINED;
+EXPORT_SYMBOL_GPL(panic_reboot_mode);
 
 /*
  * This variable is used privately to keep track of whether or not
-- 
2.32.0.605.g8dce9f2422-goog



From lee.jones at linaro.org  Thu Aug  5 00:50:32 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Thu,  5 Aug 2021 08:50:32 +0100
Subject: [PATCH 3/3] power: reset: Enable tristate on restart power-off driver
In-Reply-To: <20210805075032.723037-1-lee.jones@linaro.org>
References: <20210805075032.723037-1-lee.jones@linaro.org>
Message-ID: <20210805075032.723037-4-lee.jones@linaro.org>

From: Elliot Berman <eberman at codeaurora.org>

Since reboot_mode is an exported symbol, restart power-off driver can be
compiled as module.

Signed-off-by: Elliot Berman <eberman at codeaurora.org>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
Acked-by: Sebastian Reichel <sre at kernel.org>
---
 drivers/power/reset/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 4d1192062508d..e155b2e2a75c4 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -192,7 +192,7 @@ config POWER_RESET_REGULATOR
 	  power regulator defined in the devicetree.
 
 config POWER_RESET_RESTART
-	bool "Restart power-off driver"
+	tristate "Restart power-off driver"
 	help
 	  Some boards don't actually have the ability to power off.
 	  Instead they restart, and u-boot holds the SoC until the
-- 
2.32.0.605.g8dce9f2422-goog



From michal.simek at xilinx.com  Thu Aug  5 00:52:33 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Thu, 5 Aug 2021 09:52:33 +0200
Subject: [PATCH 4/4] arm: dts: zynq: Replace 'io-standard' with
 'power-source' property
In-Reply-To: <CAL_Jsq+281knebcN--jQgYWtDQO4OV6ZO5CvnYpaYqrAaiGmPQ@mail.gmail.com>
References: <1626868353-96475-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <1626868353-96475-5-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <YQMIhBPwcNw1YqMq@robh.at.kernel.org>
 <bc5185eb-8051-89ca-4a5f-c4e5fc90a7f2@xilinx.com>
 <CAL_Jsq+281knebcN--jQgYWtDQO4OV6ZO5CvnYpaYqrAaiGmPQ@mail.gmail.com>
Message-ID: <fd759de0-d74f-3aa1-ad46-e3ee7f7f7e3f@xilinx.com>



On 8/2/21 7:29 PM, Rob Herring wrote:
> On Thu, Jul 29, 2021 at 10:59 PM Michal Simek <michal.simek at xilinx.com> wrote:
>>
>>
>>
>> On 7/29/21 9:59 PM, Rob Herring wrote:
>>> On Wed, Jul 21, 2021 at 05:22:33PM +0530, Sai Krishna Potthuri wrote:
>>>> Replace 'io-standard' property with 'power-source' property in all zynq dts
>>>> files to be in sync with Zynq pinctrl driver.
>>>>
>>>> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
>>>> ---
>>>>  arch/arm/boot/dts/zynq-ebaz4205.dts |  8 ++++----
>>>>  arch/arm/boot/dts/zynq-microzed.dts |  2 +-
>>>>  arch/arm/boot/dts/zynq-zc702.dts    | 20 ++++++++++----------
>>>>  arch/arm/boot/dts/zynq-zc706.dts    | 18 +++++++++---------
>>>>  4 files changed, 24 insertions(+), 24 deletions(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/zynq-ebaz4205.dts b/arch/arm/boot/dts/zynq-ebaz4205.dts
>>>> index b0b836aedd76..be7eae611fb7 100644
>>>> --- a/arch/arm/boot/dts/zynq-ebaz4205.dts
>>>> +++ b/arch/arm/boot/dts/zynq-ebaz4205.dts
>>>> @@ -57,7 +57,7 @@
>>>>
>>>>              conf {
>>>>                      groups = "gpio0_20_grp", "gpio0_32_grp";
>>>> -                    io-standard = <3>;
>>>> +                    power-source = <3>;
>>>
>>> This will break using a new DT with a kernel without patch 3.
>>>
>>
>> What do you suggest? Not to update any old DT?
> 
> Your options are don't change the dts files, patch 3 needs to go to
> stable kernels, or you document the breakage (if you don't care).

There is no intention to go to stable kernel and I don't think this is
stable material. Linus has applied 3 patches and this one should go via
my tree. It means I will make sure that this DT change will be in the
tree when pinctrl changes are applied.

Thanks,
Michal


From islituo at gmail.com  Thu Aug  5 00:55:35 2021
From: islituo at gmail.com (Tuo Li)
Date: Thu,  5 Aug 2021 00:55:35 -0700
Subject: [PATCH] media: s5p-mfc: fix possible null-pointer dereference in
 s5p_mfc_probe()
Message-ID: <20210805075535.116097-1-islituo@gmail.com>

The variable pdev is assigned to dev->plat_dev, and dev->plat_dev is 
checked in:
  if (!dev->plat_dev)

This indicates both dev->plat_dev and pdev can be NULL. If so, the 
function dev_err() is called to print error infomation.
  dev_err(&pdev->dev, "No platform data specified\n");

However, &pdev->dev is an illegal address, and it is dereferenced in 
dev_err().

To fix this possible null-pointer dereference, replace dev_err() with 
mfc_err().

Reported-by: TOTE Robot <oslab at tsinghua.edu.cn>
Signed-off-by: Tuo Li <islituo at gmail.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index eba2b9f040df..c763c0a03140 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1283,7 +1283,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
 	spin_lock_init(&dev->condlock);
 	dev->plat_dev = pdev;
 	if (!dev->plat_dev) {
-		dev_err(&pdev->dev, "No platform data specified\n");
+		mfc_err("No platform data specified\n");
 		return -ENODEV;
 	}
 
-- 
2.25.1



From lee.jones at linaro.org  Thu Aug  5 00:57:13 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 5 Aug 2021 08:57:13 +0100
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build
 as a module
In-Reply-To: <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
References: <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
Message-ID: <YQuZ2cKVE+3Os25Z@google.com>

On Wed, 04 Aug 2021, Saravana Kannan wrote:

> On Wed, Aug 4, 2021 at 11:20 AM Saravana Kannan <saravanak at google.com> wrote:
> >
> > On Wed, Aug 4, 2021 at 1:50 AM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Wed, 04 Aug 2021 02:36:45 +0100,
> > > Saravana Kannan <saravanak at google.com> wrote:
> > >
> > > Hi Saravana,
> > >
> > > Thanks for looking into this.
> >
> > You are welcome. I just don't want people to think fw_devlink is broken :)
> >
> > >
> > > [...]
> > >
> > > > > Saravana, could you please have a look from a fw_devlink perspective?
> > > >
> > > > Sigh... I spent several hours looking at this and wrote up an analysis
> > > > and then realized I might be looking at the wrong DT files.
> > > >
> > > > Marc, can you point me to the board file in upstream that corresponds
> > > > to the platform in which you see this issue? I'm not asking for [1],
> > > > but the actual final .dts (not .dtsi) file that corresponds to the
> > > > platform/board/system.
> > >
> > > The platform I can reproduce this on is described in
> > > arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts. It is an
> > > intricate maze of inclusion, node merge and other DT subtleties. I
> > > suggest you look at the decompiled version to get a view of the
> > > result.
> >
> > Thanks. After decompiling it, it looks something like (stripped a
> > bunch of reg and address properties and added the labels back):
> >
> > eth_phy: mdio-multiplexer at 4c000 {
> >         compatible = "amlogic,g12a-mdio-mux";
> >         clocks = <0x02 0x13 0x1e 0x02 0xb1>;
> >         clock-names = "pclk\0clkin0\0clkin1";
> >         mdio-parent-bus = <0x22>;
> >
> >         ext_mdio: mdio at 0 {
> >                 reg = <0x00>;
> >
> >                 ethernet-phy at 0 {
> >                         max-speed = <0x3e8>;
> >                         interrupt-parent = <0x23>;
> >                         interrupts = <0x1a 0x08>;
> >                         phandle = <0x16>;
> >                 };
> >         };
> >
> >         int_mdio: mdio at 1 {
> >                 ...
> >         }
> > }
> >
> > And phandle 0x23 refers to the gpio_intc interrupt controller with the
> > modular driver.
> >
> > > > Based on your error messages, it's failing for mdio at 0 which
> > > > corresponds to ext_mdio. But none of the board dts files in upstream
> > > > have a compatible property for "ext_mdio". Which means fw_devlink
> > > > _should_ propagate the gpio_intc IRQ dependency all the way up to
> > > > eth_phy.
> > > >
> > > > Also, in the failing case, can you run:
> > > > ls -ld supplier:*
> > > >
> > > > in the /sys/devices/....<something>/ folder that corresponds to the
> > > > "eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?
> > >
> > > Here you go:
> > >
> > > root at tiger-roach:~# find /sys/devices/ -name 'supplier*'|grep -i mdio | xargs ls -ld
> > > lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/platform/soc/ff600000.bus/ff64c000.mdio-multiplexer/supplier:platform:ff63c000.system-controller:clock-controller -> ../../../../virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer
> >
> > As we discussed over chat, this was taken after the mdio-multiplexer
> > driver "successfully" probes this device. This will cause
> > SYNC_STATE_ONLY device links created by fw_devlink to be deleted
> > (because they are useless after a device probes). So, this doesn't
> > show the info I was hoping to demonstrate.
> >
> > In any case, one can see that fw_devlink properly created the device
> > link for the clocks dependency. So fw_devlink is parsing this node
> > properly. But it doesn't create a similar probe order enforcing device
> > link between the mdio-multiplexer and the gpio_intc because the
> > dependency is only present in a grand child DT node (ethernet-phy at 0
> > under ext_mdio). So fw_devlink is working as intended.
> >
> > I spent several hours squinting at the code/DT yesterday. Here's what
> > is going on and causing the problem:
> >
> > The failing driver in this case is
> > drivers/net/mdio/mdio-mux-meson-g12a.c. And the only DT node it's
> > handling is what I pasted above in this email. In the failure case,
> > the call flow is something like this:
> >
> > g12a_mdio_mux_probe()
> > -> mdio_mux_init()
> > -> of_mdiobus_register(ext_mdio DT node)
> > -> of_mdiobus_register_phy(ext_mdio DT node)
> > -> several calls deep fwnode_mdiobus_phy_device_register(ethernet_phy DT node)
> > -> Tried to get the IRQ listed in ethernet_phy and fails with
> > -EPROBE_DEFER because the IRQ driver isn't loaded yet.
> >
> > The error is propagated correctly all the way up to of_mdiobus_register(), but
> > mdio_mux_init() ignores the -EPROBE_DEFER from of_mdiobus_register() and just
> > continues on with the rest of the stuff and returns success as long as
> > one of the child nodes (in this case int_mdio) succeeds.
> >
> > Since the probe returns 0 without really succeeding, networking stuff
> > just fails badly after this. So, IMO, the real problem is with
> > mdio_mux_init() not propagating up the -EPROBE_DEFER. I gave Marc a
> > quick hack (pasted at the end of this email) to test my theory and he
> > confirmed that it fixes the issue (a few deferred probes later, things
> > work properly).
> >
> > Andrew, I don't see any good reason for mdio_mux_init() not
> > propagating the errors up correctly (at least for EPROBE_DEFER). I'll
> > send a patch to fix this. Please let me know if there's a reason it
> > has to stay as-is.
> 
> I sent out the proper fix as a series:
> https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
> 
> Marc, can you give it a shot please?
> 
> -Saravana

Superstar!  Thanks for taking the time to rectify this for all of us.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From chihhao.chen at mediatek.com  Thu Aug  5 00:54:01 2021
From: chihhao.chen at mediatek.com (chihhao.chen at mediatek.com)
Date: Thu, 5 Aug 2021 15:54:01 +0800
Subject: [PATCH] ALSA: usb-audio: fix incorrect clock source setting
In-Reply-To: <CAEsQvctJDnsaRTXAGAJ6==juKazoo2=AJrWabLzqE=jCfg5EEA@mail.gmail.com>
References: <CAEsQvctJDnsaRTXAGAJ6==juKazoo2=AJrWabLzqE=jCfg5EEA@mail.gmail.com>
Message-ID: <20210805075401.21170-1-chihhao.chen@mediatek.com>

From: chihhao chen <chihhao.chen at mediatek.com>

Hi Geraldo Nascimento,

For echo test, it means we use this earphone to receive and play sounds at the same time.
We found in this case serious noise problem happens.

Log as follows with your patch
<6>[  175.960387][T401365] __uac_clock_find_source: Clock Selector 0xc has pin 2 selected
<6>[  175.966980][T401365] __uac_clock_find_source: Clock Selector 0xb has pin 2 selected
<6>[  176.026251][T400354] __uac_clock_find_source: Clock Selector 0xc has pin 1 selected
<6>[  176.032406][T400354] __uac_clock_find_source: Clock Selector 0xb has pin 1 selected

There is no noise and I think this should be a firmware bug.

Thanks
Chihhao

From liuqi115 at huawei.com  Thu Aug  5 01:01:23 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Thu, 5 Aug 2021 16:01:23 +0800
Subject: [PATCH 0/2] coresight: ultrasoc: Add support for System Memory
 Buffer device
In-Reply-To: <CANLsYky2+D8cwquyX3iXgJtu6vND0gZZBtCL_vBobJ8pBwwvfA@mail.gmail.com>
References: <20210719111737.47891-1-liuqi115@huawei.com>
 <41661d60-d8ef-9d50-57eb-8964c6f6eef8@huawei.com>
 <CANLsYky2+D8cwquyX3iXgJtu6vND0gZZBtCL_vBobJ8pBwwvfA@mail.gmail.com>
Message-ID: <78495198-9b9d-20ce-030b-6243426c8a47@huawei.com>



On 2021/8/4 22:31, Mathieu Poirier wrote:
> On Wed, 4 Aug 2021 at 02:05, liuqi (BA) <liuqi115 at huawei.com> wrote:
>>
>> Gentle ping...
>> Hi Mathieu and Suzuki, can you have a look at this patchset? thanks.
>>
> 
> On August 2nd I got back to you privately saying I won't be able to
> review this patchset before the last week of August or the first week
> of September.  Pinging me again on it won't change that reality.
> 
Hi Mathieu,

Sorry for pinging again as I didn't see that email, perhaps because it 
is not captured to my coresight subfolder by my mailbox filtering rule 
:(. I'll wait patiently for your reply.

Thanks,
Qi

>> On 2021/7/19 19:17, Qi Liu wrote:
>>> This patchset add support for SMB(System Memory Buffer) device, SMB
>>> obtains CPU instructions from Coresight ETM device and stores these
>>> messages in system memory.
>>> SMB is developed by Ultrasoc technology, which is acquired by Siemens,
>>> and we still use "Ultrasoc" to name document and driver.
>>>
>>> Change since RFC:
>>> - Move ultrasoc driver to drivers/hwtracing/coresight.
>>> - Remove ultrasoc-axi-com.c, as AXI-COM doesn't need to be configured in
>>>     basic tracing function.
>>> - Remove ultrasoc.c as SMB does not need to register with the ultrasoc core.
>>> - Address the comments from Mathieu and Suzuki.
>>> - Link: https://lists.linaro.org/pipermail/coresight/2021-June/006535.html
>>>
>>> Qi Liu (2):
>>>     Documentation: tracing: Documentation for ultrasoc SMB drivers
>>>     coresight: ultrasoc: Add System Memory Buffer driver
>>>
>>>    .../trace/coresight/ultrasoc-trace.rst        | 193 +++++
>>>    MAINTAINERS                                   |   7 +
>>>    drivers/hwtracing/coresight/Kconfig           |   3 +
>>>    drivers/hwtracing/coresight/Makefile          |   2 +
>>>    drivers/hwtracing/coresight/ultrasoc/Kconfig  |  12 +
>>>    drivers/hwtracing/coresight/ultrasoc/Makefile |   6 +
>>>    .../coresight/ultrasoc/ultrasoc-smb.c         | 722 ++++++++++++++++++
>>>    .../coresight/ultrasoc/ultrasoc-smb.h         | 142 ++++
>>>    8 files changed, 1087 insertions(+)
>>>    create mode 100644 Documentation/trace/coresight/ultrasoc-trace.rst
>>>    create mode 100644 drivers/hwtracing/coresight/ultrasoc/Kconfig
>>>    create mode 100644 drivers/hwtracing/coresight/ultrasoc/Makefile
>>>    create mode 100644 drivers/hwtracing/coresight/ultrasoc/ultrasoc-smb.c
>>>    create mode 100644 drivers/hwtracing/coresight/ultrasoc/ultrasoc-smb.h
>>>
>>
> .
> 



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:15 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:15 +0100
Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
Message-ID: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>

Hi,

The series adds support to IORT RMR nodes specified in IORT
Revision E.b -ARM DEN 0049E[0]. RMR nodes are used to describe
memory ranges that are used by endpoints and require a unity
mapping in SMMU.

We have faced issues with 3408iMR RAID controller cards which
fail to boot when SMMU is enabled. This is because these
controllers make use of host memory for various caching related
purposes and when SMMU is enabled the iMR firmware fails to 
access these memory regions as there is no mapping for them.
IORT RMR provides a way for UEFI to describe and report these
memory regions so that the kernel can make a unity mapping for
these in SMMU.

Change History: 

v6 --> v7

The only change from v6 is the fix pointed out by Steve to
the SMMUv2 SMR bypass install in patch #8.

Thanks to the Tested-by tags by Laurentiu with SMMUv2 and
Hanjun/Huiqiang with SMMUv3 for v6. I haven't added the tags
yet as the series still needs more review[1].

Feedback and tests on this series is very much appreciated.

v5 --> v6
- Addressed comments from Robin & Lorenzo.
  : Moved iort_parse_rmr() to acpi_iort_init() from
    iort_init_platform_devices().
  : Removed use of struct iort_rmr_entry during the initial
    parse. Using struct iommu_resv_region instead.
  : Report RMR address alignment and overlap errors, but continue.
  : Reworked arm_smmu_init_bypass_stes() (patch # 6).
- Updated SMMUv2 bypass SMR code. Thanks to Jon N (patch #8).
- Set IOMMU protection flags(IOMMU_CACHE, IOMMU_MMIO) based
  on Type of RMR region. Suggested by Jon N.

Thanks,
Shameer
[0] https://developer.arm.com/documentation/den0049/latest/
[1] https://lore.kernel.org/linux-acpi/20210716083442.1708-1-shameerali.kolothum.thodi at huawei.com/T/#m043c95b869973a834b2fd57f3e1ed0325c84f3b7
------
v4 --> v5
 -Added a fw_data union to struct iommu_resv_region and removed
  struct iommu_rmr (Based on comments from Joerg/Robin).
 -Added iommu_put_rmrs() to release mem.
 -Thanks to Steve for verifying on SMMUv2, but not added the Tested-by
  yet because of the above changes.

v3 -->v4
-Included the SMMUv2 SMR bypass install changes suggested by
 Steve(patch #7)
-As per Robin's comments, RMR reserve implementation is now
 more generic  (patch #8) and dropped v3 patches 8 and 10.
-Rebase to 5.13-rc1

RFC v2 --> v3
 -Dropped RFC tag as the ACPICA header changes are now ready to be
  part of 5.13[0]. But this series still has a dependency on that patch.
 -Added IORT E.b related changes(node flags, _DSM function 5 checks for
  PCIe).
 -Changed RMR to stream id mapping from M:N to M:1 as per the spec and
  discussion here[1].
 -Last two patches add support for SMMUv2(Thanks to Jon Nettleton!)
------

Jon Nettleton (1):
  iommu/arm-smmu: Get associated RMR info and install bypass SMR

Shameer Kolothum (8):
  iommu: Introduce a union to struct iommu_resv_region
  ACPI/IORT: Add support for RMR node parsing
  iommu/dma: Introduce generic helper to retrieve RMR info
  ACPI/IORT: Add a helper to retrieve RMR memory regions
  iommu/arm-smmu-v3: Introduce strtab init helper
  iommu/arm-smmu-v3: Refactor?arm_smmu_init_bypass_stes() to force
    bypass
  iommu/arm-smmu-v3: Get associated RMR info and install bypass STE
  iommu/dma: Reserve any RMR regions associated with a dev

 drivers/acpi/arm64/iort.c                   | 172 +++++++++++++++++++-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  76 +++++++--
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  48 ++++++
 drivers/iommu/dma-iommu.c                   |  89 +++++++++-
 include/linux/acpi_iort.h                   |   7 +
 include/linux/dma-iommu.h                   |  13 ++
 include/linux/iommu.h                       |  11 ++
 7 files changed, 393 insertions(+), 23 deletions(-)

-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:16 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:16 +0100
Subject: [PATCH v7 1/9] iommu: Introduce a union to struct iommu_resv_region
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-2-shameerali.kolothum.thodi@huawei.com>

A union is introduced to struct iommu_resv_region to hold
any firmware specific data. This is in preparation to add
support for IORT RMR reserve regions and the union now holds
the RMR specific information.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 include/linux/iommu.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 32d448050bf7..bd0e4641c569 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -114,6 +114,13 @@ enum iommu_resv_type {
 	IOMMU_RESV_SW_MSI,
 };
 
+struct iommu_iort_rmr_data {
+#define IOMMU_RMR_REMAP_PERMITTED	(1 << 0)
+	u32 flags;
+	u32 sid;	/* Stream Id associated with RMR entry */
+	void *smmu;	/* Associated IORT SMMU node pointer */
+};
+
 /**
  * struct iommu_resv_region - descriptor for a reserved memory region
  * @list: Linked list pointers
@@ -121,6 +128,7 @@ enum iommu_resv_type {
  * @length: Length of the region in bytes
  * @prot: IOMMU Protection flags (READ/WRITE/...)
  * @type: Type of the reserved region
+ * @rmr: ACPI IORT RMR specific data
  */
 struct iommu_resv_region {
 	struct list_head	list;
@@ -128,6 +136,9 @@ struct iommu_resv_region {
 	size_t			length;
 	int			prot;
 	enum iommu_resv_type	type;
+	union {
+		struct iommu_iort_rmr_data rmr;
+	} fw_data;
 };
 
 /**
-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:17 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:17 +0100
Subject: [PATCH v7 2/9] ACPI/IORT: Add support for RMR node parsing
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-3-shameerali.kolothum.thodi@huawei.com>

Add support for parsing RMR node information from ACPI.

Find the associated streamid and smmu node info from the
RMR node and populate a linked list with RMR memory
descriptors.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/acpi/arm64/iort.c | 134 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 133 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 3b23fb775ac4..d76ba46ebe67 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -40,6 +40,8 @@ struct iort_fwnode {
 static LIST_HEAD(iort_fwnode_list);
 static DEFINE_SPINLOCK(iort_fwnode_lock);
 
+static LIST_HEAD(iort_rmr_list);	/* list of RMR regions from ACPI */
+
 /**
  * iort_set_fwnode() - Create iort_fwnode and use it to register
  *		       iommu data in the iort_fwnode_list
@@ -393,7 +395,8 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
 		if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
 		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
 		    node->type == ACPI_IORT_NODE_SMMU_V3 ||
-		    node->type == ACPI_IORT_NODE_PMCG) {
+		    node->type == ACPI_IORT_NODE_PMCG ||
+		    node->type == ACPI_IORT_NODE_RMR) {
 			*id_out = map->output_base;
 			return parent;
 		}
@@ -1566,6 +1569,134 @@ static void __init iort_enable_acs(struct acpi_iort_node *iort_node)
 #else
 static inline void iort_enable_acs(struct acpi_iort_node *iort_node) { }
 #endif
+static void iort_rmr_desc_check_overlap(struct acpi_iort_rmr_desc *desc, u32 count)
+{
+	int i, j;
+
+	for (i = 0; i < count; i++) {
+		u64 end, start = desc[i].base_address, length = desc[i].length;
+
+		end = start + length - 1;
+
+		/* Check for address overlap */
+		for (j = i + 1; j < count; j++) {
+			u64 e_start = desc[j].base_address;
+			u64 e_end = e_start + desc[j].length - 1;
+
+			if (start <= e_end && end >= e_start)
+				pr_err(FW_BUG "RMR descriptor[0x%llx - 0x%llx] overlaps, continue anyway\n",
+				       start, end);
+		}
+	}
+}
+
+static void __init iort_node_get_rmr_info(struct acpi_iort_node *iort_node)
+{
+	struct acpi_iort_node *smmu;
+	struct acpi_iort_rmr *rmr;
+	struct acpi_iort_rmr_desc *rmr_desc;
+	u32 map_count = iort_node->mapping_count;
+	u32 sid;
+	int i;
+
+	if (!iort_node->mapping_offset || map_count != 1) {
+		pr_err(FW_BUG "Invalid ID mapping, skipping RMR node %p\n",
+		       iort_node);
+		return;
+	}
+
+	/* Retrieve associated smmu and stream id */
+	smmu = iort_node_get_id(iort_node, &sid, 0);
+	if (!smmu) {
+		pr_err(FW_BUG "Invalid SMMU reference, skipping RMR node %p\n",
+		       iort_node);
+		return;
+	}
+
+	/* Retrieve RMR data */
+	rmr = (struct acpi_iort_rmr *)iort_node->node_data;
+	if (!rmr->rmr_offset || !rmr->rmr_count) {
+		pr_err(FW_BUG "Invalid RMR descriptor array, skipping RMR node %p\n",
+		       iort_node);
+		return;
+	}
+
+	rmr_desc = ACPI_ADD_PTR(struct acpi_iort_rmr_desc, iort_node,
+				rmr->rmr_offset);
+
+	iort_rmr_desc_check_overlap(rmr_desc, rmr->rmr_count);
+
+	for (i = 0; i < rmr->rmr_count; i++, rmr_desc++) {
+		struct iommu_resv_region *region;
+		enum iommu_resv_type type;
+		int prot = IOMMU_READ | IOMMU_WRITE;
+		u64 addr = rmr_desc->base_address, size = rmr_desc->length;
+
+		if (!IS_ALIGNED(addr, SZ_64K) || !IS_ALIGNED(size, SZ_64K)) {
+			/* PAGE align base addr and size */
+			addr &= PAGE_MASK;
+			size = PAGE_ALIGN(size + offset_in_page(rmr_desc->base_address));
+
+			pr_err(FW_BUG "RMR descriptor[0x%llx - 0x%llx] not aligned to 64K, continue with [0x%llx - 0x%llx]\n",
+			       rmr_desc->base_address,
+			       rmr_desc->base_address + rmr_desc->length - 1,
+			       addr, addr + size - 1);
+		}
+		if (rmr->flags & IOMMU_RMR_REMAP_PERMITTED) {
+			type = IOMMU_RESV_DIRECT_RELAXABLE;
+			/*
+			 * Set IOMMU_CACHE as IOMMU_RESV_DIRECT_RELAXABLE is
+			 * normally used for allocated system memory that is
+			 * then used for device specific reserved regions.
+			 */
+			prot |= IOMMU_CACHE;
+		} else {
+			type = IOMMU_RESV_DIRECT;
+			/*
+			 * Set IOMMU_MMIO as IOMMU_RESV_DIRECT is normally used
+			 * for device memory like MSI doorbell.
+			 */
+			prot |= IOMMU_MMIO;
+		}
+
+		region = iommu_alloc_resv_region(addr, size, prot, type);
+		if (region) {
+			region->fw_data.rmr.flags = rmr->flags;
+			region->fw_data.rmr.sid = sid;
+			region->fw_data.rmr.smmu = smmu;
+			list_add_tail(&region->list, &iort_rmr_list);
+		}
+	}
+}
+
+static void __init iort_parse_rmr(void)
+{
+	struct acpi_iort_node *iort_node, *iort_end;
+	struct acpi_table_iort *iort;
+	int i;
+
+	if (iort_table->revision < 3)
+		return;
+
+	iort = (struct acpi_table_iort *)iort_table;
+
+	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				 iort->node_offset);
+	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
+				iort_table->length);
+
+	for (i = 0; i < iort->node_count; i++) {
+		if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND,
+			       "IORT node pointer overflows, bad table!\n"))
+			return;
+
+		if (iort_node->type == ACPI_IORT_NODE_RMR)
+			iort_node_get_rmr_info(iort_node);
+
+		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
+					 iort_node->length);
+	}
+}
 
 static void __init iort_init_platform_devices(void)
 {
@@ -1636,6 +1767,7 @@ void __init acpi_iort_init(void)
 	}
 
 	iort_init_platform_devices();
+	iort_parse_rmr();
 }
 
 #ifdef CONFIG_ZONE_DMA
-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:18 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:18 +0100
Subject: [PATCH v7 3/9] iommu/dma: Introduce generic helper to retrieve RMR
 info
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-4-shameerali.kolothum.thodi@huawei.com>

Reserved Memory Regions(RMR) associated with an IOMMU can be
described through ACPI IORT tables in systems with devices
that require a unity mapping or bypass for those
regions.

Introduce a generic interface so that IOMMU drivers can retrieve
and set up necessary mappings.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/dma-iommu.c | 29 +++++++++++++++++++++++++++++
 include/linux/dma-iommu.h | 13 +++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 98ba927aee1a..2fa2445e9070 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -174,6 +174,35 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
 }
 EXPORT_SYMBOL(iommu_put_dma_cookie);
 
+/**
+ *
+ * iommu_dma_get_rmrs - Retrieve Reserved Memory Regions(RMRs) associated
+ *                      with a given IOMMU
+ * @iommu_fwnode: fwnode associated with IOMMU
+ * @list: RMR list to be populated
+ *
+ */
+int iommu_dma_get_rmrs(struct fwnode_handle *iommu_fwnode,
+		       struct list_head *list)
+{
+	return -EINVAL;
+}
+EXPORT_SYMBOL(iommu_dma_get_rmrs);
+
+/**
+ *
+ * iommu_dma_put_rmrs - Release Reserved Memory Regions(RMRs) associated
+ *                      with a given IOMMU
+ * @iommu_fwnode: fwnode associated with IOMMU
+ * @list: RMR list
+ *
+ */
+void iommu_dma_put_rmrs(struct fwnode_handle *iommu_fwnode,
+			struct list_head *list)
+{
+}
+EXPORT_SYMBOL(iommu_dma_put_rmrs);
+
 /**
  * iommu_dma_get_resv_regions - Reserved region driver helper
  * @dev: Device from iommu_get_resv_regions()
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 758ca4694257..3b7b2d096c6e 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -42,12 +42,16 @@ void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
 
 extern bool iommu_dma_forcedac;
 
+int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
+void iommu_dma_put_rmrs(struct fwnode_handle *iommu, struct list_head *list);
+
 #else /* CONFIG_IOMMU_DMA */
 
 struct iommu_domain;
 struct msi_desc;
 struct msi_msg;
 struct device;
+struct fwnode_handle;
 
 static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base,
 				       u64 dma_limit)
@@ -83,5 +87,14 @@ static inline void iommu_dma_get_resv_regions(struct device *dev, struct list_he
 {
 }
 
+static int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list)
+{
+	return -ENODEV;
+}
+
+static void iommu_dma_put_rmrs(struct fwnode_handle *iommu, struct list_head *list)
+{
+}
+
 #endif	/* CONFIG_IOMMU_DMA */
 #endif	/* __DMA_IOMMU_H */
-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:19 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:19 +0100
Subject: [PATCH v7 4/9] ACPI/IORT: Add a helper to retrieve RMR memory regions
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-5-shameerali.kolothum.thodi@huawei.com>

Add a helper function (iort_iommu_get_rmrs()) that retrieves RMR
memory descriptors associated with a given IOMMU. This will be used
by IOMMU drivers to setup necessary mappings.

Invoke it from the generic helper iommu_dma_get_rmrs().

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/acpi/arm64/iort.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/iommu/dma-iommu.c |  4 ++++
 include/linux/acpi_iort.h |  7 +++++++
 3 files changed, 49 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index d76ba46ebe67..3c32d62e63b6 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -809,6 +809,42 @@ static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev)
 	return NULL;
 }
 
+/**
+ * iort_iommu_get_rmrs() - Helper to retrieve RMR info associated with IOMMU
+ * @iommu_fwnode: fwnode for the IOMMU
+ * @head: RMR list head to be populated
+ *
+ * Returns: 0 on success, <0 failure. Please note, we will keep the already
+ *          allocated RMR reserve regions in case of a kmemdup()
+ *          failure.
+ */
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+			struct list_head *head)
+{
+	struct iommu_resv_region *e;
+	struct acpi_iort_node *iommu;
+	int rmrs = 0;
+
+	iommu = iort_get_iort_node(iommu_fwnode);
+	if (!iommu || list_empty(&iort_rmr_list))
+		return -ENODEV;
+
+	list_for_each_entry(e, &iort_rmr_list, list) {
+		struct iommu_resv_region *region;
+
+		if (e->fw_data.rmr.smmu != iommu)
+			continue;
+
+		region = kmemdup(e, sizeof(*region), GFP_KERNEL);
+		if (region) {
+			list_add_tail(&region->list, head);
+			rmrs++;
+		}
+	}
+
+	return (rmrs == 0) ? -ENODEV : 0;
+}
+
 /**
  * iort_iommu_msi_get_resv_regions - Reserved region driver helper
  * @dev: Device from iommu_get_resv_regions()
@@ -1041,6 +1077,8 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
 { return 0; }
 int iort_iommu_configure_id(struct device *dev, const u32 *input_id)
 { return -ENODEV; }
+int iort_iommu_get_rmrs(struct fwnode_handle *fwnode, struct list_head *head)
+{ return -ENODEV; }
 #endif
 
 static int nc_dma_get_range(struct device *dev, u64 *size)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 2fa2445e9070..1b6e27475279 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -185,6 +185,9 @@ EXPORT_SYMBOL(iommu_put_dma_cookie);
 int iommu_dma_get_rmrs(struct fwnode_handle *iommu_fwnode,
 		       struct list_head *list)
 {
+	if (!is_of_node(iommu_fwnode))
+		return iort_iommu_get_rmrs(iommu_fwnode, list);
+
 	return -EINVAL;
 }
 EXPORT_SYMBOL(iommu_dma_get_rmrs);
@@ -200,6 +203,7 @@ EXPORT_SYMBOL(iommu_dma_get_rmrs);
 void iommu_dma_put_rmrs(struct fwnode_handle *iommu_fwnode,
 			struct list_head *list)
 {
+	generic_iommu_put_resv_regions(iommu_fwnode->dev, list);
 }
 EXPORT_SYMBOL(iommu_dma_put_rmrs);
 
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index f1f0842a2cb2..d8c030c103f5 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -38,6 +38,8 @@ int iort_dma_get_ranges(struct device *dev, u64 *size);
 int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
 int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+			struct list_head *list);
 #else
 static inline void acpi_iort_init(void) { }
 static inline u32 iort_msi_map_id(struct device *dev, u32 id)
@@ -57,6 +59,11 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
 
 static inline phys_addr_t acpi_iort_dma_get_max_cpu_address(void)
 { return PHYS_ADDR_MAX; }
+
+static inline
+int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
+			struct list_head *list)
+{ return -ENODEV; }
 #endif
 
 #endif /* __ACPI_IORT_H__ */
-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:20 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:20 +0100
Subject: [PATCH v7 5/9] iommu/arm-smmu-v3: Introduce strtab init helper
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-6-shameerali.kolothum.thodi@huawei.com>

Introduce a helper to check the sid range and to init the l2 strtab
entries(bypass). This will be useful when we have to initialize the
l2 strtab with bypass for RMR SIDs.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 28 +++++++++++----------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 235f9bdaeaf2..31940e53c675 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2518,6 +2518,19 @@ static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
 	return sid < limit;
 }
 
+static int arm_smmu_init_sid_strtab(struct arm_smmu_device *smmu, u32 sid)
+{
+	/* Check the SIDs are in range of the SMMU and our stream table */
+	if (!arm_smmu_sid_in_range(smmu, sid))
+		return -ERANGE;
+
+	/* Ensure l2 strtab is initialised */
+	if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB)
+		return arm_smmu_init_l2_strtab(smmu, sid);
+
+	return 0;
+}
+
 static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
 				  struct arm_smmu_master *master)
 {
@@ -2541,20 +2554,9 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
 		new_stream->id = sid;
 		new_stream->master = master;
 
-		/*
-		 * Check the SIDs are in range of the SMMU and our stream table
-		 */
-		if (!arm_smmu_sid_in_range(smmu, sid)) {
-			ret = -ERANGE;
+		ret = arm_smmu_init_sid_strtab(smmu, sid);
+		if (ret)
 			break;
-		}
-
-		/* Ensure l2 strtab is initialised */
-		if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
-			ret = arm_smmu_init_l2_strtab(smmu, sid);
-			if (ret)
-				break;
-		}
 
 		/* Insert into SID tree */
 		new_node = &(smmu->streams.rb_node);
-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:21 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:21 +0100
Subject: [PATCH v7 6/9] =?UTF-8?q?iommu/arm-smmu-v3:=20Refactor=C2=A0arm?=
 =?UTF-8?q?=5Fsmmu=5Finit=5Fbypass=5Fstes()=20to=20force=20bypass?=
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-7-shameerali.kolothum.thodi@huawei.com>

By default,?disable_bypass flag is set and any dev without
an iommu domain installs?STE with CFG_ABORT during
arm_smmu_init_bypass_stes(). Introduce a "force" flag and
move the STE update logic to?arm_smmu_init_bypass_stes()
so that we can force it to install?CFG_BYPASS STE for specific
SIDs.

This will be?useful?in follow-up?patch to install bypass
for IORT RMR SIDs.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 31940e53c675..85f6f1925a36 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1357,12 +1357,21 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
 		arm_smmu_cmdq_issue_cmd(smmu, &prefetch_cmd);
 }
 
-static void arm_smmu_init_bypass_stes(__le64 *strtab, unsigned int nent)
+static void arm_smmu_init_bypass_stes(__le64 *strtab, unsigned int nent, bool force)
 {
 	unsigned int i;
+	u64 val = STRTAB_STE_0_V;
+
+	if (disable_bypass && !force)
+		val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_ABORT);
+	else
+		val |= FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_BYPASS);
 
 	for (i = 0; i < nent; ++i) {
-		arm_smmu_write_strtab_ent(NULL, -1, strtab);
+		strtab[0] = cpu_to_le64(val);
+		strtab[1] = cpu_to_le64(FIELD_PREP(STRTAB_STE_1_SHCFG,
+						   STRTAB_STE_1_SHCFG_INCOMING));
+		strtab[2] = 0;
 		strtab += STRTAB_STE_DWORDS;
 	}
 }
@@ -1390,7 +1399,7 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
 		return -ENOMEM;
 	}
 
-	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT);
+	arm_smmu_init_bypass_stes(desc->l2ptr, 1 << STRTAB_SPLIT, false);
 	arm_smmu_write_strtab_l1_desc(strtab, desc);
 	return 0;
 }
@@ -3042,7 +3051,7 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
 	reg |= FIELD_PREP(STRTAB_BASE_CFG_LOG2SIZE, smmu->sid_bits);
 	cfg->strtab_base_cfg = reg;
 
-	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents);
+	arm_smmu_init_bypass_stes(strtab, cfg->num_l1_ents, false);
 	return 0;
 }
 
-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:22 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:22 +0100
Subject: [PATCH v7 7/9] iommu/arm-smmu-v3: Get associated RMR info and install
 bypass STE
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-8-shameerali.kolothum.thodi@huawei.com>

Check if there is any RMR info associated?with the devices behind
the SMMUv3 and if any, install bypass STEs for them. This is to
keep any ongoing traffic associated with these devices alive
when we enable/reset SMMUv3 during probe().

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 31 +++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 85f6f1925a36..1165605d6f7a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3760,6 +3760,34 @@ static void __iomem *arm_smmu_ioremap(struct device *dev, resource_size_t start,
 	return devm_ioremap_resource(dev, &res);
 }
 
+static void arm_smmu_rmr_install_bypass_ste(struct arm_smmu_device *smmu)
+{
+	struct list_head rmr_list;
+	struct iommu_resv_region *e;
+	int ret;
+
+	INIT_LIST_HEAD(&rmr_list);
+	if (iommu_dma_get_rmrs(dev_fwnode(smmu->dev), &rmr_list))
+		return;
+
+	list_for_each_entry(e, &rmr_list, list) {
+		__le64 *step;
+		u32 sid = e->fw_data.rmr.sid;
+
+		ret = arm_smmu_init_sid_strtab(smmu, sid);
+		if (ret) {
+			dev_err(smmu->dev, "RMR SID(0x%x) bypass failed\n",
+				sid);
+			continue;
+		}
+
+		step = arm_smmu_get_step_for_sid(smmu, sid);
+		arm_smmu_init_bypass_stes(step, 1, true);
+	}
+
+	iommu_dma_put_rmrs(dev_fwnode(smmu->dev), &rmr_list);
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	int irq, ret;
@@ -3841,6 +3869,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Record our private device structure */
 	platform_set_drvdata(pdev, smmu);
 
+	/* Check for RMRs and install bypass STEs if any */
+	arm_smmu_rmr_install_bypass_ste(smmu);
+
 	/* Reset the device */
 	ret = arm_smmu_device_reset(smmu, bypass);
 	if (ret)
-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:23 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:23 +0100
Subject: [PATCH v7 8/9] iommu/arm-smmu: Get associated RMR info and install
 bypass SMR
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-9-shameerali.kolothum.thodi@huawei.com>

From: Jon Nettleton <jon at solid-run.com>

Check if there is any RMR info associated with the devices behind
the SMMU and if any, install bypass SMRs for them. This is to
keep any ongoing traffic associated with these devices alive
when we enable/reset SMMU during probe().

Signed-off-by: Jon Nettleton <jon at solid-run.com>
Signed-off-by: Steven Price <steven.price at arm.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 48 +++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index f22dbeb1e510..315feab9e85b 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -2063,6 +2063,50 @@ err_reset_platform_ops: __maybe_unused;
 	return err;
 }
 
+static void arm_smmu_rmr_install_bypass_smr(struct arm_smmu_device *smmu)
+{
+	struct list_head rmr_list;
+	struct iommu_resv_region *e;
+	int i, cnt = 0;
+	u32 reg;
+
+	INIT_LIST_HEAD(&rmr_list);
+	if (iommu_dma_get_rmrs(dev_fwnode(smmu->dev), &rmr_list))
+		return;
+
+	/*
+	 * Rather than trying to look at existing mappings that
+	 * are setup by the firmware and then invalidate the ones
+	 * that do no have matching RMR entries, just disable the
+	 * SMMU until it gets enabled again in the reset routine.
+	 */
+	reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sCR0);
+	reg |= ARM_SMMU_sCR0_CLIENTPD;
+	arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sCR0, reg);
+
+	list_for_each_entry(e, &rmr_list, list) {
+		u32 sid = e->fw_data.rmr.sid;
+
+		i = arm_smmu_find_sme(smmu, sid, ~0);
+		if (i < 0)
+			continue;
+		if (smmu->s2crs[i].count == 0) {
+			smmu->smrs[i].id = sid;
+			smmu->smrs[i].mask = 0;
+			smmu->smrs[i].valid = true;
+		}
+		smmu->s2crs[i].count++;
+		smmu->s2crs[i].type = S2CR_TYPE_BYPASS;
+		smmu->s2crs[i].privcfg = S2CR_PRIVCFG_DEFAULT;
+
+		cnt++;
+	}
+
+	dev_notice(smmu->dev, "\tpreserved %d boot mapping%s\n", cnt,
+		   cnt == 1 ? "" : "s");
+	iommu_dma_put_rmrs(dev_fwnode(smmu->dev), &rmr_list);
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -2189,6 +2233,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, smmu);
+
+	/* Check for RMRs and install bypass SMRs if any */
+	arm_smmu_rmr_install_bypass_smr(smmu);
+
 	arm_smmu_device_reset(smmu);
 	arm_smmu_test_smr_masks(smmu);
 
-- 
2.17.1



From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 01:07:24 2021
From: shameerali.kolothum.thodi at huawei.com (Shameer Kolothum)
Date: Thu, 5 Aug 2021 09:07:24 +0100
Subject: [PATCH v7 9/9] iommu/dma: Reserve any RMR regions associated with a
 dev
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805080724.480-10-shameerali.kolothum.thodi@huawei.com>

Get ACPI IORT RMR regions associated with a dev reserved
so that there is a unity mapping for them in SMMU.

Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
 drivers/iommu/dma-iommu.c | 56 +++++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 1b6e27475279..c1ae0c3d4b33 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -207,22 +207,68 @@ void iommu_dma_put_rmrs(struct fwnode_handle *iommu_fwnode,
 }
 EXPORT_SYMBOL(iommu_dma_put_rmrs);
 
+static bool iommu_dma_dev_has_rmr(struct iommu_fwspec *fwspec,
+				  struct iommu_resv_region *e)
+{
+	int i;
+
+	for (i = 0; i < fwspec->num_ids; i++) {
+		if (e->fw_data.rmr.sid == fwspec->ids[i])
+			return true;
+	}
+
+	return false;
+}
+
+static void iommu_dma_get_rmr_resv_regions(struct device *dev,
+					   struct list_head *list)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct list_head rmr_list;
+	struct iommu_resv_region *rmr, *tmp;
+
+	INIT_LIST_HEAD(&rmr_list);
+	if (iommu_dma_get_rmrs(fwspec->iommu_fwnode, &rmr_list))
+		return;
+
+	if (dev_is_pci(dev)) {
+		struct pci_dev *pdev = to_pci_dev(dev);
+		struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
+
+		if (!host->preserve_config)
+			return;
+	}
+
+	list_for_each_entry_safe(rmr, tmp, &rmr_list, list) {
+		if (!iommu_dma_dev_has_rmr(fwspec, rmr))
+			continue;
+
+		/* Remove from iommu RMR list and add to dev resv_regions */
+		list_del_init(&rmr->list);
+		list_add_tail(&rmr->list, list);
+	}
+
+	iommu_dma_put_rmrs(fwspec->iommu_fwnode, &rmr_list);
+}
+
 /**
  * iommu_dma_get_resv_regions - Reserved region driver helper
  * @dev: Device from iommu_get_resv_regions()
  * @list: Reserved region list from iommu_get_resv_regions()
  *
  * IOMMU drivers can use this to implement their .get_resv_regions callback
- * for general non-IOMMU-specific reservations. Currently, this covers GICv3
- * ITS region reservation on ACPI based ARM platforms that may require HW MSI
- * reservation.
+ * for general non-IOMMU-specific reservations. Currently this covers,
+ *  -GICv3 ITS region reservation on ACPI based ARM platforms that may
+ *   require HW MSI reservation.
+ *  -Any ACPI IORT RMR memory range reservations (IORT spec rev E.b)
  */
 void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
 {
 
-	if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode))
+	if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode)) {
 		iort_iommu_msi_get_resv_regions(dev, list);
-
+		iommu_dma_get_rmr_resv_regions(dev, list);
+	}
 }
 EXPORT_SYMBOL(iommu_dma_get_resv_regions);
 
-- 
2.17.1



From alexandre.belloni at bootlin.com  Thu Aug  5 01:13:40 2021
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Thu, 5 Aug 2021 10:13:40 +0200
Subject: [PATCH 2/2] rtc: imx-rpmsg: Add i.MX RPMSG RTC support
In-Reply-To: <20210805033546.1390950-3-aisheng.dong@nxp.com>
References: <20210805033546.1390950-1-aisheng.dong@nxp.com>
 <20210805033546.1390950-3-aisheng.dong@nxp.com>
Message-ID: <YQudtCoUhjZYEt/l@piout.net>

Hello,

On 05/08/2021 11:35:46+0800, Dong Aisheng wrote:
> Add i.MX RPMSG RTC support.
> 

You definitively need to elaborate why this is necessary and why
rtc-imx-sc.c has not been reused. I'm not going to take a new driver for
each version of the CM4 firmware.

> Cc: Alessandro Zummo <a.zummo at towertech.it>
> Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> ---
>  drivers/rtc/Kconfig                |  10 +
>  drivers/rtc/Makefile               |   1 +
>  drivers/rtc/rtc-imx-rpmsg.c        | 301 +++++++++++++++++++++++++++++
>  include/linux/firmware/imx/rpmsg.h |  37 ++++
>  4 files changed, 349 insertions(+)
>  create mode 100644 drivers/rtc/rtc-imx-rpmsg.c
>  create mode 100644 include/linux/firmware/imx/rpmsg.h
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 12153d5801ce..f0e6c4dd8965 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1763,6 +1763,16 @@ config RTC_DRV_SNVS
>  	   This driver can also be built as a module, if so, the module
>  	   will be called "rtc-snvs".
>  
> +config RTC_DRV_IMX_RPMSG
> +	tristate "NXP RPMSG RTC support"
> +	select RPMSG_VIRTIO
> +	depends on ARCH_MXC || COMPILE_TEST
> +	depends on IMX_REMOTEPROC
> +	depends on OF
> +	help
> +	   If you say yes here you get support for the NXP RPMSG
> +	   RTC module.
> +
>  config RTC_DRV_IMX_SC
>  	depends on IMX_SCU
>  	depends on HAVE_ARM_SMCCC
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 2dd0dd956b0e..9cebfddcc245 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -72,6 +72,7 @@ obj-$(CONFIG_RTC_DRV_GOLDFISH)	+= rtc-goldfish.o
>  obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
>  obj-$(CONFIG_RTC_DRV_HYM8563)	+= rtc-hym8563.o
>  obj-$(CONFIG_RTC_DRV_IMXDI)	+= rtc-imxdi.o
> +obj-$(CONFIG_RTC_DRV_IMX_RPMSG)	+= rtc-imx-rpmsg.o
>  obj-$(CONFIG_RTC_DRV_IMX_SC)	+= rtc-imx-sc.o
>  obj-$(CONFIG_RTC_DRV_ISL12022)	+= rtc-isl12022.o
>  obj-$(CONFIG_RTC_DRV_ISL12026)	+= rtc-isl12026.o
> diff --git a/drivers/rtc/rtc-imx-rpmsg.c b/drivers/rtc/rtc-imx-rpmsg.c
> new file mode 100644
> index 000000000000..0d6d4b18159e
> --- /dev/null
> +++ b/drivers/rtc/rtc-imx-rpmsg.c
> @@ -0,0 +1,301 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright 2017-2021 NXP
> + */
> +
> +#include <linux/firmware/imx/rpmsg.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/pm_qos.h>
> +#include <linux/rpmsg.h>
> +#include <linux/rtc.h>
> +
> +#define RPMSG_TIMEOUT 1000
> +
> +#define RTC_RPMSG_SEND		0x0
> +#define RTC_RPMSG_RECEIVE	0x1
> +#define RTC_RPMSG_NOTIFY	0x2
> +
> +enum rtc_rpmsg_cmd {
> +	RTC_RPMSG_SET_TIME,
> +	RTC_RPMSG_GET_TIME,
> +	RTC_RPMSG_SET_ALARM,
> +	RTC_RPMSG_GET_ALARM,
> +	RTC_RPMSG_ENABLE_ALARM,
> +};
> +
> +struct rtc_rpmsg_data {
> +	struct imx_rpmsg_head header;
> +	u8 reserved0;
> +	union {
> +		u8 reserved1;
> +		u8 ret;
> +	};
> +	union {
> +		u32 reserved2;
> +		u32 sec;
> +	};
> +	union {
> +		u8 enable;
> +		u8 reserved3;
> +	};
> +	union {
> +		u8 pending;
> +		u8 reserved4;
> +	};
> +} __packed;
> +
> +struct rtc_rpmsg_info {
> +	struct rpmsg_device *rpdev;
> +	struct rtc_rpmsg_data *msg;
> +	struct pm_qos_request pm_qos_req;
> +	struct completion cmd_complete;
> +	struct mutex lock;
> +	struct rtc_device *rtc;
> +};
> +
> +static int rtc_send_message(struct rtc_rpmsg_info *info,
> +			    struct rtc_rpmsg_data *msg, bool ack)
> +{
> +	struct device *dev = &info->rpdev->dev;
> +	int err;
> +
> +	mutex_lock(&info->lock);
> +
> +	cpu_latency_qos_add_request(&info->pm_qos_req, 0);
> +	reinit_completion(&info->cmd_complete);
> +
> +	err = rpmsg_send(info->rpdev->ept, (void *)msg, sizeof(*msg));
> +	if (err) {
> +		dev_err(dev, "rpmsg send failed: %d\n", err);
> +		goto err_out;
> +	}
> +
> +	if (ack) {
> +		err = wait_for_completion_timeout(&info->cmd_complete,
> +						  msecs_to_jiffies(RPMSG_TIMEOUT));
> +		if (!err) {
> +			dev_err(dev, "rpmsg send timeout\n");
> +			err = -ETIMEDOUT;
> +			goto err_out;
> +		}
> +
> +		if (info->msg->ret != 0) {
> +			dev_err(dev, "rpmsg not ack %d\n", info->msg->ret);
> +			err = -EINVAL;
> +			goto err_out;
> +		}
> +
> +		err = 0;
> +	}
> +
> +err_out:
> +	cpu_latency_qos_remove_request(&info->pm_qos_req);
> +	mutex_unlock(&info->lock);
> +
> +	return err;
> +}
> +
> +static int imx_rpmsg_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> +	struct rtc_rpmsg_data msg;
> +	int ret;
> +
> +	msg.header.cate = IMX_RPMSG_RTC;
> +	msg.header.major = IMX_RMPSG_MAJOR;
> +	msg.header.minor = IMX_RMPSG_MINOR;
> +	msg.header.type = RTC_RPMSG_SEND;
> +	msg.header.cmd = RTC_RPMSG_GET_TIME;
> +
> +	ret = rtc_send_message(rtc_rpmsg, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	rtc_time64_to_tm(rtc_rpmsg->msg->sec, tm);
> +
> +	return 0;
> +}
> +
> +static int imx_rpmsg_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> +	struct rtc_rpmsg_data msg;
> +	unsigned long time;
> +	int ret;
> +
> +	time = rtc_tm_to_time64(tm);
> +
> +	msg.header.cate = IMX_RPMSG_RTC;
> +	msg.header.major = IMX_RMPSG_MAJOR;
> +	msg.header.minor = IMX_RMPSG_MINOR;
> +	msg.header.type = RTC_RPMSG_SEND;
> +	msg.header.cmd = RTC_RPMSG_SET_TIME;
> +	msg.sec = time;
> +
> +	ret = rtc_send_message(rtc_rpmsg, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int imx_rpmsg_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> +	struct rtc_rpmsg_data msg;
> +	int ret;
> +
> +	msg.header.cate = IMX_RPMSG_RTC;
> +	msg.header.major = IMX_RMPSG_MAJOR;
> +	msg.header.minor = IMX_RMPSG_MINOR;
> +	msg.header.type = RTC_RPMSG_SEND;
> +	msg.header.cmd = RTC_RPMSG_GET_ALARM;
> +
> +	ret = rtc_send_message(rtc_rpmsg, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	rtc_time64_to_tm(rtc_rpmsg->msg->sec, &alrm->time);
> +	alrm->pending = rtc_rpmsg->msg->pending;
> +
> +	return 0;
> +}
> +
> +static int imx_rpmsg_rtc_alarm_irq_enable(struct device *dev,
> +	unsigned int enable)
> +{
> +	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> +	struct rtc_rpmsg_data msg;
> +	int ret;
> +
> +	msg.header.cate = IMX_RPMSG_RTC;
> +	msg.header.major = IMX_RMPSG_MAJOR;
> +	msg.header.minor = IMX_RMPSG_MINOR;
> +	msg.header.type = RTC_RPMSG_SEND;
> +	msg.header.cmd = RTC_RPMSG_ENABLE_ALARM;
> +	msg.enable = enable;
> +
> +	ret = rtc_send_message(rtc_rpmsg, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int imx_rpmsg_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> +	struct rtc_rpmsg_data msg;
> +	unsigned long time;
> +	int ret;
> +
> +	time = rtc_tm_to_time64(&alrm->time);
> +
> +	msg.header.cate = IMX_RPMSG_RTC;
> +	msg.header.major = IMX_RMPSG_MAJOR;
> +	msg.header.minor = IMX_RMPSG_MINOR;
> +	msg.header.type = RTC_RPMSG_SEND;
> +	msg.header.cmd = RTC_RPMSG_SET_ALARM;
> +	msg.sec = time;
> +	msg.enable = alrm->enabled;
> +
> +	ret = rtc_send_message(rtc_rpmsg, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static const struct rtc_class_ops imx_rpmsg_rtc_ops = {
> +	.read_time = imx_rpmsg_rtc_read_time,
> +	.set_time = imx_rpmsg_rtc_set_time,
> +	.read_alarm = imx_rpmsg_rtc_read_alarm,
> +	.set_alarm = imx_rpmsg_rtc_set_alarm,
> +	.alarm_irq_enable = imx_rpmsg_rtc_alarm_irq_enable,
> +};
> +
> +static int rtc_rpmsg_probe(struct rpmsg_device *rpdev)
> +{
> +	struct device *dev = &rpdev->dev;
> +	struct rtc_rpmsg_info *rtc_rpmsg;
> +
> +	dev_info(dev, "new channel: 0x%x -> 0x%x\n", rpdev->src, rpdev->dst);
> +
> +	rtc_rpmsg = devm_kzalloc(dev, sizeof(*rtc_rpmsg), GFP_KERNEL);
> +	if (!rtc_rpmsg)
> +		return -ENOMEM;
> +
> +	rtc_rpmsg->rpdev = rpdev;
> +	mutex_init(&rtc_rpmsg->lock);
> +	init_completion(&rtc_rpmsg->cmd_complete);
> +
> +	dev_set_drvdata(dev, rtc_rpmsg);
> +
> +	device_init_wakeup(dev, true);
> +
> +	rtc_rpmsg->rtc = devm_rtc_device_register(dev, "rtc-rpmsg",
> +						  &imx_rpmsg_rtc_ops,
> +						  THIS_MODULE);
> +	if (IS_ERR(rtc_rpmsg->rtc)) {
> +		dev_err(dev, "failed to register rtc rpmsg: %ld\n", PTR_ERR(rtc_rpmsg->rtc));
> +		return PTR_ERR(rtc_rpmsg->rtc);
> +	}
> +
> +	return 0;
> +}
> +
> +static void rtc_rpmsg_remove(struct rpmsg_device *rpdev)
> +{
> +	dev_info(&rpdev->dev, "rtc rpmsg driver is removed\n");
> +}
> +
> +static int rtc_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
> +			void *priv, u32 src)
> +{
> +	struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(&rpdev->dev);
> +	struct rtc_rpmsg_data *msg = (struct rtc_rpmsg_data *)data;
> +
> +	rtc_rpmsg->msg = msg;
> +
> +	if (msg->header.type == RTC_RPMSG_RECEIVE)
> +		complete(&rtc_rpmsg->cmd_complete);
> +	else if (msg->header.type == RTC_RPMSG_NOTIFY)
> +		rtc_update_irq(rtc_rpmsg->rtc, 1, RTC_IRQF);
> +	else
> +		dev_err(&rpdev->dev, "wrong command type!\n");
> +
> +	return 0;
> +}
> +
> +static const struct rpmsg_device_id rtc_rpmsg_id_table[] = {
> +	{ .name	= "rpmsg-rtc-channel" },
> +	{ },
> +};
> +
> +static struct rpmsg_driver rtc_rpmsg_driver = {
> +	.drv.name	= "imx_rtc_rpmsg",
> +	.probe		= rtc_rpmsg_probe,
> +	.remove		= rtc_rpmsg_remove,
> +	.callback	= rtc_rpmsg_cb,
> +	.id_table	= rtc_rpmsg_id_table,
> +};
> +
> +/*
> + * imx m4 has a limitation that we can't read data during ns process.
> + * So register rtc a little bit late as rtc core will read data during
> + * register process
> + */
> +static int __init rtc_rpmsg_init(void)
> +{
> +	return register_rpmsg_driver(&rtc_rpmsg_driver);
> +}
> +late_initcall(rtc_rpmsg_init);
> +
> +MODULE_AUTHOR("Dong Aisheng <aisheng.dong at nxp.com>");
> +MODULE_DESCRIPTION("NXP i.MX RPMSG RTC Driver");
> +MODULE_ALIAS("platform:imx_rtc_rpmsg");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/firmware/imx/rpmsg.h b/include/linux/firmware/imx/rpmsg.h
> new file mode 100644
> index 000000000000..20bcce23c917
> --- /dev/null
> +++ b/include/linux/firmware/imx/rpmsg.h
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2019-2021 NXP.
> + */
> +
> +#ifndef __LINUX_IMX_RPMSG_H__
> +#define __LINUX_IMX_RPMSG_H__
> +
> +#include <linux/types.h>
> +
> +/*
> + * Global header file for iMX RPMSG
> + */
> +
> +/* Category define */
> +#define IMX_RMPSG_LIFECYCLE     1
> +#define IMX_RPMSG_PMIC          2
> +#define IMX_RPMSG_AUDIO         3
> +#define IMX_RPMSG_KEY           4
> +#define IMX_RPMSG_GPIO          5
> +#define IMX_RPMSG_RTC           6
> +#define IMX_RPMSG_SENSOR        7
> +
> +/* rpmsg version */
> +#define IMX_RMPSG_MAJOR         1
> +#define IMX_RMPSG_MINOR         0
> +
> +struct imx_rpmsg_head {
> +	u8 cate;
> +	u8 major;
> +	u8 minor;
> +	u8 type;
> +	u8 cmd;
> +	u8 reserved[5];
> +} __packed;
> +
> +#endif /* __LINUX_IMX_RPMSG_H__ */
> -- 
> 2.25.1
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From john.ogness at linutronix.de  Thu Aug  5 01:26:38 2021
From: john.ogness at linutronix.de (John Ogness)
Date: Thu, 05 Aug 2021 10:32:38 +0206
Subject: [PATCH printk v1 10/10] serial: 8250: implement write_atomic
In-Reply-To: <931ebc1a-3cc9-677c-44c3-7cbd645eb4f4@kernel.org>
References: <20210803131301.5588-1-john.ogness@linutronix.de>
 <20210803131301.5588-11-john.ogness@linutronix.de>
 <YQlNtr7TNAWtB8XF@smile.fi.intel.com>
 <931ebc1a-3cc9-677c-44c3-7cbd645eb4f4@kernel.org>
Message-ID: <87k0l0wb41.fsf@jogness.linutronix.de>

On 2021-08-05, Jiri Slaby <jirislaby at kernel.org> wrote:
> On 03. 08. 21, 16:07, Andy Shevchenko wrote:
>> On Tue, Aug 03, 2021 at 03:19:01PM +0206, John Ogness wrote:
>>> Implement an NMI-safe write_atomic() console function in order to
>>> support synchronous console printing.
>>>
>>> Since interrupts need to be disabled during transmit, all usage of
>>> the IER register is wrapped with access functions that use the
>>> printk cpulock to synchronize register access while tracking the
>>> state of the interrupts. This is necessary because write_atomic()
>>> can be called from an NMI context that has preempted write_atomic().
>> 
>> ...
>> 
>>> +static inline void serial8250_set_IER(struct uart_8250_port *up,
>>> +				      unsigned char ier)
>>> +{
>>> +	struct uart_port *port = &up->port;
>>> +	unsigned long flags;
>>> +	bool is_console;
>> 
>>> +	is_console = uart_console(port);
>>> +
>>> +	if (is_console)
>>> +		console_atomic_cpu_lock(flags);
>>> +
>>> +	serial_out(up, UART_IER, ier);
>>> +
>>> +	if (is_console)
>>> +		console_atomic_cpu_unlock(flags);
>> 
>> I would rewrite it as
>> 
>> 	if (uart_console()) {
>> 		console_atomic_cpu_lock(flags);
>> 		serial_out(up, UART_IER, ier);
>> 		console_atomic_cpu_unlock(flags);
>> 	} else {
>> 		serial_out(up, UART_IER, ier);
>> 	}

Some locations have more than just 1 line of code in between
lock/unlock. I agree this looks better, but am unsure how much
copy/paste code is acceptable.

>> No additional variable, easier to get the algorithm on the first
>> glance, less error prone.
>
> Yes, the original is terrible.
>
> Another option:
>
> bool locked = console_atomic_cpu_lock(flags, uart_console());
> serial_out(up, UART_IER, ier);
> console_atomic_cpu_unlock(flags, locked);
>
> Which makes console_atomic_cpu_lock to lock only if second parameter
> is true and return its value too.

I am not sure how common such semantics for lock/unlock functions
are. But since this pattern, using uart_console(), will most likely be a
common pattern for atomic consoles, I can see how this will be useful.

I will choose one of these 2 suggestions for v2. Thanks.

> BTW I actually don't know what console_atomic_cpu_lock does to think 
> about it more as I was not CCed, and neither lore sees the other patches:
> https://lore.kernel.org/linux-mips/20210803131301.5588-1-john.ogness at linutronix.de/

Only the lkml mailing list saw the full series:

https://lore.kernel.org/lkml/20210803131301.5588-1-john.ogness at linutronix.de/

John Ogness


From maz at kernel.org  Thu Aug  5 01:35:17 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 05 Aug 2021 09:35:17 +0100
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>
 <87r1f9wooc.wl-maz@kernel.org>
 <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>
Message-ID: <87wnp0b86y.wl-maz@kernel.org>

On Wed, 04 Aug 2021 21:10:43 +0100,
Sunil Muthuswamy <sunilmut at microsoft.com> wrote:
> 
> Thanks Marc and Robin for clarifying. I see and understand the point
> about having explicit MSI mappings in the firmware specification for
> Direct LPIs for generic hardware support.
> 
> Hey Mark

I assume this is for me?

> would you be willing to consider a scoped down implementation of GIC
> Direct LPI with just an IRQ chip implementation and no Direct LPI
> PCI-MSI IRQ chip.

Could you please clarify? If you are not implementing MSIs, how can a
device signal LPIs? At the end of the day, something has to write into
the RD, and it isn't going to happen by sheer magic.

> This will allow a MSI provider (such as Hyper-V vPCI) to provide a
> PCI-MSI IRQ chip on top of the Direct LPI IRQ chip and enable
> PCI-MSI scenarios, and avoid building in assumptions in other cases
> (like PCI) where firmware specification is not available.

I really don't get what you are suggesting. Could you please describe
what you have in mind?

	M.

-- 
Without deviation from the norm, progress is not possible.


From tony at atomide.com  Thu Aug  5 01:46:42 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu,  5 Aug 2021 11:46:42 +0300
Subject: [GIT PULL 1/3] SoC changes for omaps for v5.15
Message-ID: <pull-1628153040-834155@atomide.com>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/soc-signed

for you to fetch changes up to 8d5a937f10ed091e14fc57a4158f59983e2934cf:

  MAINTAINERS: Adopt SanCloud dts files as supported (2021-07-27 11:54:52 +0300)

----------------------------------------------------------------
SoC changes for omaps for v5.15

Update MAINTAINERS for SanCloud devices and drop unused old Kconfig

----------------------------------------------------------------
Paul Barker (1):
      MAINTAINERS: Adopt SanCloud dts files as supported

Peter Robinson (1):
      arm: omap2: Drop MACH_OMAP3517EVM entry

 MAINTAINERS                 | 6 ++++++
 arch/arm/mach-omap2/Kconfig | 5 -----
 2 files changed, 6 insertions(+), 5 deletions(-)


From tony at atomide.com  Thu Aug  5 01:46:43 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu,  5 Aug 2021 11:46:43 +0300
Subject: [GIT PULL 2/3] Driver changes for ti-sysc for v5.15
In-Reply-To: <pull-1628153040-834155@atomide.com>
References: <pull-1628153040-834155@atomide.com>
Message-ID: <pull-1628153040-834155@atomide.com-2>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/ti-sysc-signed

for you to fetch changes up to fdc07ca0724dd8ad00c22909a1464dc73ed6783e:

  Merge branch 'omap-for-v5.14/ti-sysc' into omap-for-v5.15/ti-sysc (2021-07-27 12:02:24 +0300)

----------------------------------------------------------------
Driver changes for ti-sysc for v5.15

Few ti-sysc changes to handle quirk for McASP SIDLE mode, correct
documentation for sysc_ioremap(), and start using
pm_runtime_resume_and_get().

----------------------------------------------------------------
Lee Jones (1):
      bus: ti-sysc: Correct misdocumentation of 'sysc_ioremap()'

Peter Ujfalusi (1):
      bus: ti-sysc: Add quirk for OMAP4 McASP to disable SIDLE mode

Tony Lindgren (1):
      Merge branch 'omap-for-v5.14/ti-sysc' into omap-for-v5.15/ti-sysc

Zhang Qilong (1):
      bus: ti-sysc: using pm_runtime_resume_and_get instead of pm_runtime_get_sync

 drivers/bus/ti-sysc.c | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)


From tony at atomide.com  Thu Aug  5 01:46:44 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu,  5 Aug 2021 11:46:44 +0300
Subject: [GIT PULL 3/3] Devicetree changes for omaps for v5.15
In-Reply-To: <pull-1628153040-834155@atomide.com>
References: <pull-1628153040-834155@atomide.com>
Message-ID: <pull-1628153040-834155@atomide.com-3>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/dt-signed

for you to fetch changes up to 8c054cd2818ea08555efe24a2ffde330833c2f3f:

  ARM: dts: am57xx: Add PRUSS MDIO controller nodes (2021-08-03 15:25:14 +0300)

----------------------------------------------------------------
Devicetree changes for omaps for v5.15

Devicetree changes for omaps to configure more devices, and
add support for new SoC variants and devices:

- Add add gpio-line-names for am335x-boneblue

- Add support for dra762 abz package

- Two patches for McASP support on omap4

- Three patches to add support for am335x-sancloud-bbe-lite

- A series of changes to configure PRUSS for am3/4/5

----------------------------------------------------------------
Andrew F. Davis (1):
      ARM: dts: am4372: Add PRUSS MDIO controller node

David Lechner (1):
      ARM: dts: am335x-boneblue: add gpio-line-names

Lokesh Vutla (1):
      ARM: dts: Add support for dra762 abz package

Paul Barker (3):
      ARM: dts: am335x-boneblack: Extract HDMI config
      ARM: dts: am335x-sancloud-bbe: Extract common code
      ARM: dts: am335x-sancloud-bbe-lite: New devicetree

Peter Ujfalusi (2):
      ARM: dts: omap4-l4-abe: Correct sidle modes for McASP
      ARM: dts: omap4-l4-abe: Add McASP configuration

Suman Anna (10):
      ARM: dts: am33xx-l4: Add PRUSS node
      ARM: dts: am33xx-l4: Add PRUSS MDIO controller node
      ARM: dts: am335x-bone-common: Enable PRU-ICSS node
      ARM: dts: am335x-evm: Enable PRU-ICSS module
      ARM: dts: am335x-evmsk: Enable PRU-ICSS module
      ARM: dts: am335x-icev2: Enable PRU-ICSS module
      ARM: dts: am4372: Add the PRU-ICSS1 DT node
      ARM: dts: am4372: Add the PRU-ICSS0 DT node
      ARM: dts: am57xx: Add PRU-ICSS nodes
      ARM: dts: am57xx: Add PRUSS MDIO controller nodes

 arch/arm/boot/dts/Makefile                        |   1 +
 arch/arm/boot/dts/am335x-bone-common.dtsi         |   4 +
 arch/arm/boot/dts/am335x-boneblack-common.dtsi    | 135 ----------------
 arch/arm/boot/dts/am335x-boneblack-hdmi.dtsi      | 141 +++++++++++++++++
 arch/arm/boot/dts/am335x-boneblack-wireless.dts   |   1 +
 arch/arm/boot/dts/am335x-boneblack.dts            |   1 +
 arch/arm/boot/dts/am335x-boneblue.dts             | 143 ++++++++++++++++-
 arch/arm/boot/dts/am335x-evm.dts                  |   4 +
 arch/arm/boot/dts/am335x-evmsk.dts                |   4 +
 arch/arm/boot/dts/am335x-icev2.dts                |   4 +
 arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi |  96 ++++++++++++
 arch/arm/boot/dts/am335x-sancloud-bbe-lite.dts    |  50 ++++++
 arch/arm/boot/dts/am335x-sancloud-bbe.dts         |  92 +----------
 arch/arm/boot/dts/am33xx-l4.dtsi                  |  82 ++++++++++
 arch/arm/boot/dts/am4372.dtsi                     | 165 ++++++++++++++++++++
 arch/arm/boot/dts/am437x-cm-t43.dts               |   4 +
 arch/arm/boot/dts/am437x-gp-evm.dts               |   4 +
 arch/arm/boot/dts/am437x-idk-evm.dts              |   4 +
 arch/arm/boot/dts/am437x-sk-evm.dts               |   4 +
 arch/arm/boot/dts/am43x-epos-evm.dts              |   4 +
 arch/arm/boot/dts/am57-pruss.dtsi                 | 178 +++++++++++++++++++++-
 arch/arm/boot/dts/am571x-idk.dts                  |   8 +
 arch/arm/boot/dts/am572x-idk.dts                  |   8 +
 arch/arm/boot/dts/am5748.dtsi                     |   6 +-
 arch/arm/boot/dts/am574x-idk.dts                  |  10 +-
 arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi   |   8 +
 arch/arm/boot/dts/am57xx-cl-som-am57x.dts         |   8 +
 arch/arm/boot/dts/dra74x-p.dtsi                   |  27 ++++
 arch/arm/boot/dts/dra76x.dtsi                     |  12 --
 arch/arm/boot/dts/omap4-l4-abe.dtsi               |  38 ++---
 30 files changed, 981 insertions(+), 265 deletions(-)
 create mode 100644 arch/arm/boot/dts/am335x-boneblack-hdmi.dtsi
 create mode 100644 arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi
 create mode 100644 arch/arm/boot/dts/am335x-sancloud-bbe-lite.dts
 create mode 100644 arch/arm/boot/dts/dra74x-p.dtsi


From tony at atomide.com  Thu Aug  5 01:48:08 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 5 Aug 2021 11:48:08 +0300
Subject: [PATCH v2 0/4] Add support for the SanCloud BBE Lite
In-Reply-To: <20210804115221.5650e440.paul.barker@sancloud.com>
References: <20210720083928.10404-1-paul.barker@sancloud.com>
 <YP/J+YC6GFeH+I5j@atomide.com>
 <20210804115221.5650e440.paul.barker@sancloud.com>
Message-ID: <YQulyGLNNkyYcBSY@atomide.com>

* Paul Barker <paul.barker at sancloud.com> [210804 10:52]:
> On Tue, 27 Jul 2021 11:55:21 +0300
> Tony Lindgren <tony at atomide.com> wrote:
> 
> > * Paul Barker <paul.barker at sancloud.com> [210720 11:40]:
> > > The Lite variant of the SanCloud BeagleBone Enhanced (BBE) removes the
> > > HDMI encoder, barometer and accelerometer chips and adds a Micron
> > > Authenta SPI flash chip.  
> > 
> > Thanks applying all for v5.15 merge window.
> 
> I tested the for-next branch of linux-omap to confirm that things
> worked with these patches applied. There was a NULL pointer
> dereference in ptp_clock_register() during boot. The fix appears to be
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=55eac20617ca84129273ab248f4d7bfe456967de
> which went into 5.14-rc2.

Yeah so it seems, too bad it was not there for -rc1 already.

> Merging for-next with 5.14-rc4 resulted in things working as expected.

OK thanks for checking.

Regards,

Tony


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210805/b066000c/attachment-0001.sig>

From dongas86 at gmail.com  Thu Aug  5 01:48:55 2021
From: dongas86 at gmail.com (Dong Aisheng)
Date: Thu, 5 Aug 2021 16:48:55 +0800
Subject: [PATCH 2/2] rtc: imx-rpmsg: Add i.MX RPMSG RTC support
In-Reply-To: <YQudtCoUhjZYEt/l@piout.net>
References: <20210805033546.1390950-1-aisheng.dong@nxp.com>
 <20210805033546.1390950-3-aisheng.dong@nxp.com> <YQudtCoUhjZYEt/l@piout.net>
Message-ID: <CAA+hA=TOTQRC46xeKwkK=tYTuWH4m2+XvTHt_cTqHXWWhfB0eQ@mail.gmail.com>

Hi Alexandre,

On Thu, Aug 5, 2021 at 4:13 PM Alexandre Belloni
<alexandre.belloni at bootlin.com> wrote:
>
> Hello,
>
> On 05/08/2021 11:35:46+0800, Dong Aisheng wrote:
> > Add i.MX RPMSG RTC support.
> >
>
> You definitively need to elaborate why this is necessary and why
> rtc-imx-sc.c has not been reused. I'm not going to take a new driver for
> each version of the CM4 firmware.

rtc-imx-sc is based on SCU protocol and only used on SCU firmware
based platforms
like mx8qm/qxp platforms.

rtc-imx-rpmsg is based on rpmsg/virtio and could be used on the rest
of the imx platforms
with MCore firmware like mx6/mx7ulp/imx8m/imx8ulp.

They're totally different protocols and based on different frameworks.

Regards
Aisheng

>
> > Cc: Alessandro Zummo <a.zummo at towertech.it>
> > Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
> > Cc: Shawn Guo <shawnguo at kernel.org>
> > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> > ---
> >  drivers/rtc/Kconfig                |  10 +
> >  drivers/rtc/Makefile               |   1 +
> >  drivers/rtc/rtc-imx-rpmsg.c        | 301 +++++++++++++++++++++++++++++
> >  include/linux/firmware/imx/rpmsg.h |  37 ++++
> >  4 files changed, 349 insertions(+)
> >  create mode 100644 drivers/rtc/rtc-imx-rpmsg.c
> >  create mode 100644 include/linux/firmware/imx/rpmsg.h
> >
> > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> > index 12153d5801ce..f0e6c4dd8965 100644
> > --- a/drivers/rtc/Kconfig
> > +++ b/drivers/rtc/Kconfig
> > @@ -1763,6 +1763,16 @@ config RTC_DRV_SNVS
> >          This driver can also be built as a module, if so, the module
> >          will be called "rtc-snvs".
> >
> > +config RTC_DRV_IMX_RPMSG
> > +     tristate "NXP RPMSG RTC support"
> > +     select RPMSG_VIRTIO
> > +     depends on ARCH_MXC || COMPILE_TEST
> > +     depends on IMX_REMOTEPROC
> > +     depends on OF
> > +     help
> > +        If you say yes here you get support for the NXP RPMSG
> > +        RTC module.
> > +
> >  config RTC_DRV_IMX_SC
> >       depends on IMX_SCU
> >       depends on HAVE_ARM_SMCCC
> > diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> > index 2dd0dd956b0e..9cebfddcc245 100644
> > --- a/drivers/rtc/Makefile
> > +++ b/drivers/rtc/Makefile
> > @@ -72,6 +72,7 @@ obj-$(CONFIG_RTC_DRV_GOLDFISH)      += rtc-goldfish.o
> >  obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
> >  obj-$(CONFIG_RTC_DRV_HYM8563)        += rtc-hym8563.o
> >  obj-$(CONFIG_RTC_DRV_IMXDI)  += rtc-imxdi.o
> > +obj-$(CONFIG_RTC_DRV_IMX_RPMSG)      += rtc-imx-rpmsg.o
> >  obj-$(CONFIG_RTC_DRV_IMX_SC) += rtc-imx-sc.o
> >  obj-$(CONFIG_RTC_DRV_ISL12022)       += rtc-isl12022.o
> >  obj-$(CONFIG_RTC_DRV_ISL12026)       += rtc-isl12026.o
> > diff --git a/drivers/rtc/rtc-imx-rpmsg.c b/drivers/rtc/rtc-imx-rpmsg.c
> > new file mode 100644
> > index 000000000000..0d6d4b18159e
> > --- /dev/null
> > +++ b/drivers/rtc/rtc-imx-rpmsg.c
> > @@ -0,0 +1,301 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright 2017-2021 NXP
> > + */
> > +
> > +#include <linux/firmware/imx/rpmsg.h>
> > +#include <linux/init.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/pm_qos.h>
> > +#include <linux/rpmsg.h>
> > +#include <linux/rtc.h>
> > +
> > +#define RPMSG_TIMEOUT 1000
> > +
> > +#define RTC_RPMSG_SEND               0x0
> > +#define RTC_RPMSG_RECEIVE    0x1
> > +#define RTC_RPMSG_NOTIFY     0x2
> > +
> > +enum rtc_rpmsg_cmd {
> > +     RTC_RPMSG_SET_TIME,
> > +     RTC_RPMSG_GET_TIME,
> > +     RTC_RPMSG_SET_ALARM,
> > +     RTC_RPMSG_GET_ALARM,
> > +     RTC_RPMSG_ENABLE_ALARM,
> > +};
> > +
> > +struct rtc_rpmsg_data {
> > +     struct imx_rpmsg_head header;
> > +     u8 reserved0;
> > +     union {
> > +             u8 reserved1;
> > +             u8 ret;
> > +     };
> > +     union {
> > +             u32 reserved2;
> > +             u32 sec;
> > +     };
> > +     union {
> > +             u8 enable;
> > +             u8 reserved3;
> > +     };
> > +     union {
> > +             u8 pending;
> > +             u8 reserved4;
> > +     };
> > +} __packed;
> > +
> > +struct rtc_rpmsg_info {
> > +     struct rpmsg_device *rpdev;
> > +     struct rtc_rpmsg_data *msg;
> > +     struct pm_qos_request pm_qos_req;
> > +     struct completion cmd_complete;
> > +     struct mutex lock;
> > +     struct rtc_device *rtc;
> > +};
> > +
> > +static int rtc_send_message(struct rtc_rpmsg_info *info,
> > +                         struct rtc_rpmsg_data *msg, bool ack)
> > +{
> > +     struct device *dev = &info->rpdev->dev;
> > +     int err;
> > +
> > +     mutex_lock(&info->lock);
> > +
> > +     cpu_latency_qos_add_request(&info->pm_qos_req, 0);
> > +     reinit_completion(&info->cmd_complete);
> > +
> > +     err = rpmsg_send(info->rpdev->ept, (void *)msg, sizeof(*msg));
> > +     if (err) {
> > +             dev_err(dev, "rpmsg send failed: %d\n", err);
> > +             goto err_out;
> > +     }
> > +
> > +     if (ack) {
> > +             err = wait_for_completion_timeout(&info->cmd_complete,
> > +                                               msecs_to_jiffies(RPMSG_TIMEOUT));
> > +             if (!err) {
> > +                     dev_err(dev, "rpmsg send timeout\n");
> > +                     err = -ETIMEDOUT;
> > +                     goto err_out;
> > +             }
> > +
> > +             if (info->msg->ret != 0) {
> > +                     dev_err(dev, "rpmsg not ack %d\n", info->msg->ret);
> > +                     err = -EINVAL;
> > +                     goto err_out;
> > +             }
> > +
> > +             err = 0;
> > +     }
> > +
> > +err_out:
> > +     cpu_latency_qos_remove_request(&info->pm_qos_req);
> > +     mutex_unlock(&info->lock);
> > +
> > +     return err;
> > +}
> > +
> > +static int imx_rpmsg_rtc_read_time(struct device *dev, struct rtc_time *tm)
> > +{
> > +     struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> > +     struct rtc_rpmsg_data msg;
> > +     int ret;
> > +
> > +     msg.header.cate = IMX_RPMSG_RTC;
> > +     msg.header.major = IMX_RMPSG_MAJOR;
> > +     msg.header.minor = IMX_RMPSG_MINOR;
> > +     msg.header.type = RTC_RPMSG_SEND;
> > +     msg.header.cmd = RTC_RPMSG_GET_TIME;
> > +
> > +     ret = rtc_send_message(rtc_rpmsg, &msg, true);
> > +     if (ret)
> > +             return ret;
> > +
> > +     rtc_time64_to_tm(rtc_rpmsg->msg->sec, tm);
> > +
> > +     return 0;
> > +}
> > +
> > +static int imx_rpmsg_rtc_set_time(struct device *dev, struct rtc_time *tm)
> > +{
> > +     struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> > +     struct rtc_rpmsg_data msg;
> > +     unsigned long time;
> > +     int ret;
> > +
> > +     time = rtc_tm_to_time64(tm);
> > +
> > +     msg.header.cate = IMX_RPMSG_RTC;
> > +     msg.header.major = IMX_RMPSG_MAJOR;
> > +     msg.header.minor = IMX_RMPSG_MINOR;
> > +     msg.header.type = RTC_RPMSG_SEND;
> > +     msg.header.cmd = RTC_RPMSG_SET_TIME;
> > +     msg.sec = time;
> > +
> > +     ret = rtc_send_message(rtc_rpmsg, &msg, true);
> > +     if (ret)
> > +             return ret;
> > +
> > +     return 0;
> > +}
> > +
> > +static int imx_rpmsg_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> > +{
> > +     struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> > +     struct rtc_rpmsg_data msg;
> > +     int ret;
> > +
> > +     msg.header.cate = IMX_RPMSG_RTC;
> > +     msg.header.major = IMX_RMPSG_MAJOR;
> > +     msg.header.minor = IMX_RMPSG_MINOR;
> > +     msg.header.type = RTC_RPMSG_SEND;
> > +     msg.header.cmd = RTC_RPMSG_GET_ALARM;
> > +
> > +     ret = rtc_send_message(rtc_rpmsg, &msg, true);
> > +     if (ret)
> > +             return ret;
> > +
> > +     rtc_time64_to_tm(rtc_rpmsg->msg->sec, &alrm->time);
> > +     alrm->pending = rtc_rpmsg->msg->pending;
> > +
> > +     return 0;
> > +}
> > +
> > +static int imx_rpmsg_rtc_alarm_irq_enable(struct device *dev,
> > +     unsigned int enable)
> > +{
> > +     struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> > +     struct rtc_rpmsg_data msg;
> > +     int ret;
> > +
> > +     msg.header.cate = IMX_RPMSG_RTC;
> > +     msg.header.major = IMX_RMPSG_MAJOR;
> > +     msg.header.minor = IMX_RMPSG_MINOR;
> > +     msg.header.type = RTC_RPMSG_SEND;
> > +     msg.header.cmd = RTC_RPMSG_ENABLE_ALARM;
> > +     msg.enable = enable;
> > +
> > +     ret = rtc_send_message(rtc_rpmsg, &msg, true);
> > +     if (ret)
> > +             return ret;
> > +
> > +     return 0;
> > +}
> > +
> > +static int imx_rpmsg_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> > +{
> > +     struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(dev);
> > +     struct rtc_rpmsg_data msg;
> > +     unsigned long time;
> > +     int ret;
> > +
> > +     time = rtc_tm_to_time64(&alrm->time);
> > +
> > +     msg.header.cate = IMX_RPMSG_RTC;
> > +     msg.header.major = IMX_RMPSG_MAJOR;
> > +     msg.header.minor = IMX_RMPSG_MINOR;
> > +     msg.header.type = RTC_RPMSG_SEND;
> > +     msg.header.cmd = RTC_RPMSG_SET_ALARM;
> > +     msg.sec = time;
> > +     msg.enable = alrm->enabled;
> > +
> > +     ret = rtc_send_message(rtc_rpmsg, &msg, true);
> > +     if (ret)
> > +             return ret;
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct rtc_class_ops imx_rpmsg_rtc_ops = {
> > +     .read_time = imx_rpmsg_rtc_read_time,
> > +     .set_time = imx_rpmsg_rtc_set_time,
> > +     .read_alarm = imx_rpmsg_rtc_read_alarm,
> > +     .set_alarm = imx_rpmsg_rtc_set_alarm,
> > +     .alarm_irq_enable = imx_rpmsg_rtc_alarm_irq_enable,
> > +};
> > +
> > +static int rtc_rpmsg_probe(struct rpmsg_device *rpdev)
> > +{
> > +     struct device *dev = &rpdev->dev;
> > +     struct rtc_rpmsg_info *rtc_rpmsg;
> > +
> > +     dev_info(dev, "new channel: 0x%x -> 0x%x\n", rpdev->src, rpdev->dst);
> > +
> > +     rtc_rpmsg = devm_kzalloc(dev, sizeof(*rtc_rpmsg), GFP_KERNEL);
> > +     if (!rtc_rpmsg)
> > +             return -ENOMEM;
> > +
> > +     rtc_rpmsg->rpdev = rpdev;
> > +     mutex_init(&rtc_rpmsg->lock);
> > +     init_completion(&rtc_rpmsg->cmd_complete);
> > +
> > +     dev_set_drvdata(dev, rtc_rpmsg);
> > +
> > +     device_init_wakeup(dev, true);
> > +
> > +     rtc_rpmsg->rtc = devm_rtc_device_register(dev, "rtc-rpmsg",
> > +                                               &imx_rpmsg_rtc_ops,
> > +                                               THIS_MODULE);
> > +     if (IS_ERR(rtc_rpmsg->rtc)) {
> > +             dev_err(dev, "failed to register rtc rpmsg: %ld\n", PTR_ERR(rtc_rpmsg->rtc));
> > +             return PTR_ERR(rtc_rpmsg->rtc);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void rtc_rpmsg_remove(struct rpmsg_device *rpdev)
> > +{
> > +     dev_info(&rpdev->dev, "rtc rpmsg driver is removed\n");
> > +}
> > +
> > +static int rtc_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
> > +                     void *priv, u32 src)
> > +{
> > +     struct rtc_rpmsg_info *rtc_rpmsg = dev_get_drvdata(&rpdev->dev);
> > +     struct rtc_rpmsg_data *msg = (struct rtc_rpmsg_data *)data;
> > +
> > +     rtc_rpmsg->msg = msg;
> > +
> > +     if (msg->header.type == RTC_RPMSG_RECEIVE)
> > +             complete(&rtc_rpmsg->cmd_complete);
> > +     else if (msg->header.type == RTC_RPMSG_NOTIFY)
> > +             rtc_update_irq(rtc_rpmsg->rtc, 1, RTC_IRQF);
> > +     else
> > +             dev_err(&rpdev->dev, "wrong command type!\n");
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct rpmsg_device_id rtc_rpmsg_id_table[] = {
> > +     { .name = "rpmsg-rtc-channel" },
> > +     { },
> > +};
> > +
> > +static struct rpmsg_driver rtc_rpmsg_driver = {
> > +     .drv.name       = "imx_rtc_rpmsg",
> > +     .probe          = rtc_rpmsg_probe,
> > +     .remove         = rtc_rpmsg_remove,
> > +     .callback       = rtc_rpmsg_cb,
> > +     .id_table       = rtc_rpmsg_id_table,
> > +};
> > +
> > +/*
> > + * imx m4 has a limitation that we can't read data during ns process.
> > + * So register rtc a little bit late as rtc core will read data during
> > + * register process
> > + */
> > +static int __init rtc_rpmsg_init(void)
> > +{
> > +     return register_rpmsg_driver(&rtc_rpmsg_driver);
> > +}
> > +late_initcall(rtc_rpmsg_init);
> > +
> > +MODULE_AUTHOR("Dong Aisheng <aisheng.dong at nxp.com>");
> > +MODULE_DESCRIPTION("NXP i.MX RPMSG RTC Driver");
> > +MODULE_ALIAS("platform:imx_rtc_rpmsg");
> > +MODULE_LICENSE("GPL");
> > diff --git a/include/linux/firmware/imx/rpmsg.h b/include/linux/firmware/imx/rpmsg.h
> > new file mode 100644
> > index 000000000000..20bcce23c917
> > --- /dev/null
> > +++ b/include/linux/firmware/imx/rpmsg.h
> > @@ -0,0 +1,37 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (C) 2019-2021 NXP.
> > + */
> > +
> > +#ifndef __LINUX_IMX_RPMSG_H__
> > +#define __LINUX_IMX_RPMSG_H__
> > +
> > +#include <linux/types.h>
> > +
> > +/*
> > + * Global header file for iMX RPMSG
> > + */
> > +
> > +/* Category define */
> > +#define IMX_RMPSG_LIFECYCLE     1
> > +#define IMX_RPMSG_PMIC          2
> > +#define IMX_RPMSG_AUDIO         3
> > +#define IMX_RPMSG_KEY           4
> > +#define IMX_RPMSG_GPIO          5
> > +#define IMX_RPMSG_RTC           6
> > +#define IMX_RPMSG_SENSOR        7
> > +
> > +/* rpmsg version */
> > +#define IMX_RMPSG_MAJOR         1
> > +#define IMX_RMPSG_MINOR         0
> > +
> > +struct imx_rpmsg_head {
> > +     u8 cate;
> > +     u8 major;
> > +     u8 minor;
> > +     u8 type;
> > +     u8 cmd;
> > +     u8 reserved[5];
> > +} __packed;
> > +
> > +#endif /* __LINUX_IMX_RPMSG_H__ */
> > --
> > 2.25.1
> >
>
> --
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com


From song.bao.hua at hisilicon.com  Thu Aug  5 01:55:27 2021
From: song.bao.hua at hisilicon.com (Song Bao Hua (Barry Song))
Date: Thu, 5 Aug 2021 08:55:27 +0000
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210804060209.95817-1-liuqi115@huawei.com>
References: <20210804060209.95817-1-liuqi115@huawei.com>
Message-ID: <e59357e126e34a6d97a55113483746f8@hisilicon.com>



> -----Original Message-----
> From: liuqi (BA)
> Sent: Wednesday, August 4, 2021 6:02 PM
> To: catalin.marinas at arm.com; will at kernel.org; naveen.n.rao at linux.ibm.com;
> anil.s.keshavamurthy at intel.com; davem at davemloft.net; mhiramat at kernel.org;
> linux-arm-kernel at lists.infradead.org
> Cc: Song Bao Hua (Barry Song) <song.bao.hua at hisilicon.com>; Zengtao (B)
> <prime.zeng at hisilicon.com>; robin.murphy at arm.com; Fangjian (Jay)
> <f.fangjian at huawei.com>; liuqi (BA) <liuqi115 at huawei.com>; Linuxarm
> <linuxarm at huawei.com>; linux-kernel at vger.kernel.org
> Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
> 
> This patch introduce optprobe for ARM64. In optprobe, probed
> instruction is replaced by a branch instruction to detour
> buffer. Detour buffer contains trampoline code and a call to
> optimized_callback(). optimized_callback() calls opt_pre_handler()
> to execute kprobe handler.
> 
> Limitations:
> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
> guarantee the offset between probe point and kprobe pre_handler
> is not larger than 128MiB.
> 
> Performance of optprobe on Hip08 platform is test using kprobe
> example module[1] to analyze the latency of a kernel function,
> and here is the result:
> 
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sa
> mples/kprobes/kretprobe_example.c
> 
> kprobe before optimized:
> [280709.846380] do_empty returned 0 and took 1530 ns to execute
> [280709.852057] do_empty returned 0 and took 550 ns to execute
> [280709.857631] do_empty returned 0 and took 440 ns to execute
> [280709.863215] do_empty returned 0 and took 380 ns to execute
> [280709.868787] do_empty returned 0 and took 360 ns to execute
> [280709.874362] do_empty returned 0 and took 340 ns to execute
> [280709.879936] do_empty returned 0 and took 320 ns to execute
> [280709.885505] do_empty returned 0 and took 300 ns to execute
> [280709.891075] do_empty returned 0 and took 280 ns to execute
> [280709.896646] do_empty returned 0 and took 290 ns to execute
> [280709.902220] do_empty returned 0 and took 290 ns to execute
> [280709.907807] do_empty returned 0 and took 290 ns to execute
> 
> optprobe:
> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> [ 2966.029158] do_empty returned 0 and took 70 ns to execute
> 
> Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> 
> ---
> 
> Changes since V1:
> - Address the comments from Masami, checks for all branch instructions, and
> use aarch64_insn_patch_text_nosync() instead of aarch64_insn_patch_text()
> in each probe.
> - Link:
> https://lore.kernel.org/lkml/20210719122417.10355-1-liuqi115 at huawei.com/
> 
>  arch/arm64/Kconfig                            |   1 +
>  arch/arm64/include/asm/kprobes.h              |  23 ++
>  arch/arm64/kernel/probes/Makefile             |   2 +
>  arch/arm64/kernel/probes/kprobes.c            |  19 +-
>  arch/arm64/kernel/probes/opt-arm64.c          | 225 ++++++++++++++++++
>  .../arm64/kernel/probes/optprobe_trampoline.S |  80 +++++++
>  6 files changed, 347 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm64/kernel/probes/opt-arm64.c
>  create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b5b13a932561..3532f0237c71 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -200,6 +200,7 @@ config ARM64
>  	select HAVE_STACKPROTECTOR
>  	select HAVE_SYSCALL_TRACEPOINTS
>  	select HAVE_KPROBES
> +	select HAVE_OPTPROBES if !RANDOMIZE_MODULE_REGION_FULL

Any negative side effect if we optprobe doesn't apply and we fall
back to normal kprobe?

I mean, normal kprobe without this patch vs. fallback to kprobe
from optprobe with this patch, any penalty in latency from
optprobe?

If no penalty, I'd rather we remove the dependency of
RANDOMIZE_MODULE_REGION_FULL since you mentioned
nokaslr will always make optprobe work. I assume
in those tests you enabled RANDOMIZE_MODULE_REGION_FULL?

We can mention those issues in commit log rather than statically
depending on a kconfig option.

>  	select HAVE_KRETPROBES
>  	select HAVE_GENERIC_VDSO
>  	select IOMMU_DMA if IOMMU_SUPPORT
> diff --git a/arch/arm64/include/asm/kprobes.h
> b/arch/arm64/include/asm/kprobes.h
> index 5d38ff4a4806..9e1c492a0c3d 100644
> --- a/arch/arm64/include/asm/kprobes.h
> +++ b/arch/arm64/include/asm/kprobes.h
> @@ -39,6 +39,29 @@ void arch_remove_kprobe(struct kprobe *);
>  int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
>  int kprobe_exceptions_notify(struct notifier_block *self,
>  			     unsigned long val, void *data);
> +
> +#define RELATIVEJUMP_SIZE (4)
> +#define MAX_COPIED_INSN	DIV_ROUND_UP(RELATIVEJUMP_SIZE,
> sizeof(kprobe_opcode_t))
> +struct arch_optimized_insn {
> +	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
> +	/* detour code buffer */
> +	kprobe_opcode_t *insn;
> +};
> +
> +/* optinsn template addresses */
> +extern __visible kprobe_opcode_t optprobe_template_entry[];
> +extern __visible kprobe_opcode_t optprobe_template_val[];
> +extern __visible kprobe_opcode_t optprobe_template_call[];
> +extern __visible kprobe_opcode_t optprobe_template_end[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_end[];
> +
> +#define MAX_OPTIMIZED_LENGTH	4
> +#define MAX_OPTINSN_SIZE				\
> +	((unsigned long)optprobe_template_end -	\
> +	 (unsigned long)optprobe_template_entry)
> +
>  void kretprobe_trampoline(void);
>  void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
> 
> diff --git a/arch/arm64/kernel/probes/Makefile
> b/arch/arm64/kernel/probes/Makefile
> index 8e4be92e25b1..52cf5d4ffe8a 100644
> --- a/arch/arm64/kernel/probes/Makefile
> +++ b/arch/arm64/kernel/probes/Makefile
> @@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o decode-insn.o	\
>  				   simulate-insn.o
>  obj-$(CONFIG_UPROBES)		+= uprobes.o decode-insn.o	\
>  				   simulate-insn.o
> +obj-$(CONFIG_OPTPROBES)		+= opt-arm64.o			\
> +				   optprobe_trampoline.o
> diff --git a/arch/arm64/kernel/probes/kprobes.c
> b/arch/arm64/kernel/probes/kprobes.c
> index 6dbcc89f6662..83755ad62abe 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> @@ -11,6 +11,7 @@
>  #include <linux/kasan.h>
>  #include <linux/kernel.h>
>  #include <linux/kprobes.h>
> +#include <linux/moduleloader.h>
>  #include <linux/sched/debug.h>
>  #include <linux/set_memory.h>
>  #include <linux/slab.h>
> @@ -113,9 +114,21 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
> 
>  void *alloc_insn_page(void)
>  {
> -	return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
> -			GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
> -			NUMA_NO_NODE, __builtin_return_address(0));
> +	void *page;
> +
> +	page = module_alloc(PAGE_SIZE);
> +	if (!page)
> +		return NULL;
> +
> +	set_vm_flush_reset_perms(page);
> +	/*
> +	 * First make the page read-only, and only then make it executable to
> +	 * prevent it from being W+X in between.
> +	 */
> +	set_memory_ro((unsigned long)page, 1);
> +	set_memory_x((unsigned long)page, 1);
> +
> +	return page;
>  }
> 
>  /* arm kprobe: install breakpoint in text */
> diff --git a/arch/arm64/kernel/probes/opt-arm64.c
> b/arch/arm64/kernel/probes/opt-arm64.c
> new file mode 100644
> index 000000000000..a0302e3ad62d
> --- /dev/null
> +++ b/arch/arm64/kernel/probes/opt-arm64.c
> @@ -0,0 +1,225 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Code for Kernel probes Jump optimization.
> + *
> + * Copyright (C) 2021 Hisilicon Limited
> + */
> +
> +#include <linux/jump_label.h>
> +#include <linux/kprobes.h>
> +
> +#include <asm/cacheflush.h>
> +#include <asm/insn.h>
> +#include <asm/kprobes.h>
> +
> +
> +#define TMPL_VAL_IDX \
> +	(optprobe_template_val - optprobe_template_entry)
> +#define TMPL_CALL_BACK \
> +	(optprobe_template_call - optprobe_template_entry)
> +#define TMPL_END_IDX \
> +	(optprobe_template_end - optprobe_template_entry)
> +#define TMPL_RESTORE_ORIGN_INSN \
> +	(optprobe_template_restore_orig_insn - optprobe_template_entry)
> +#define TMPL_RESTORE_END \
> +	(optprobe_template_restore_end - optprobe_template_entry)
> +
> +int arch_check_optimized_kprobe(struct optimized_kprobe *op)
> +{
> +	return 0;
> +}
> +
> +int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
> +{
> +	return optinsn->insn != NULL;
> +}
> +
> +int arch_within_optimized_kprobe(struct optimized_kprobe *op,
> +				unsigned long addr)
> +{
> +	return ((unsigned long)op->kp.addr <= addr &&
> +		(unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
> +}
> +
> +static void
> +optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
> +{
> +	/* This is possible if op is under delayed unoptimizing */
> +	if (kprobe_disabled(&op->kp))
> +		return;
> +
> +	preempt_disable();
> +
> +	if (kprobe_running()) {
> +		kprobes_inc_nmissed_count(&op->kp);
> +	} else {
> +		__this_cpu_write(current_kprobe, &op->kp);
> +		regs->pc = (unsigned long)op->kp.addr;
> +		get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
> +		opt_pre_handler(&op->kp, regs);
> +		__this_cpu_write(current_kprobe, NULL);
> +	}
> +
> +	preempt_enable_no_resched();
> +}
> +NOKPROBE_SYMBOL(optimized_callback)
> +
> +static bool is_offset_in_range(unsigned long start, unsigned long end)
> +{
> +	long offset = end - start;
> +
> +	/*
> +	 * Verify if the address gap is in 128MiB range, because this uses
> +	 * a relative jump.
> +	 *
> +	 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
> +	 * According to ARM manual, branch instruction is:
> +	 *
> +	 *   31  30                  25              0
> +	 *  +----+---+---+---+---+---+---------------+
> +	 *  |cond| 0 | 0 | 1 | 0 | 1 |     imm26     |
> +	 *  +----+---+---+---+---+---+---------------+
> +	 *
> +	 * imm26 is a signed 26 bits integer. The real branch offset is computed
> +	 * by: imm64 = SignExtend(imm26:'00', 64);
> +	 *
> +	 * So the maximum forward branch should be:
> +	 *   (0x01ffffff << 2) = 1720x07fffffc =  0x07fffffc
> +	 * The maximum backward branch should be:
> +	 *   (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
> +	 *
> +	 * We can simply check (rel & 0xf8000003):
> +	 *  if rel is positive, (rel & 0xf8000003) should be 0
> +	 *  if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
> +	 *  the last '3' is used for alignment checking.
> +	 */
> +	return (offset >= -0x08000000 && offset <= 0x07fffffc && !(offset & 0x3));
> +}
> +
> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe
> *orig)
> +{
> +	kprobe_opcode_t *code;
> +	u32 insn;
> +	int ret, i;
> +	void *addrs[TMPL_END_IDX];
> +	void *addr;
> +
> +	code = get_optinsn_slot();
> +	if (!code)
> +		return -ENOMEM;
> +
> +	if (!is_offset_in_range((unsigned long)code,
> +				(unsigned long)orig->addr + 8))
> +		goto error;
> +
> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
> +				(unsigned long)optimized_callback))
> +		goto error;
> +
> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
> +				(unsigned long)op->kp.addr + 4))
> +		goto error;
> +
> +	/* Setup template */
> +	for (i = 0; i < TMPL_END_IDX; i++)
> +		addrs[i] = code + i;
> +
> +	ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
> +				      TMPL_END_IDX);
> +	if (ret < 0)
> +		goto error;
> +
> +	/* Set probe information */
> +	addr = code + TMPL_VAL_IDX;
> +	insn =  (unsigned long long)op & 0xffffffff;
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	addr = addr + 4;
> +	insn = ((unsigned long long)op & GENMASK_ULL(63, 32)) >> 32;
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	addr = code + TMPL_CALL_BACK;
> +	insn =  aarch64_insn_gen_branch_imm((unsigned long)addr,
> +				(unsigned long)optimized_callback,
> +				AARCH64_INSN_BRANCH_LINK);
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	/* The original probed instruction */
> +	addr = code + TMPL_RESTORE_ORIGN_INSN;
> +	insn =  orig->opcode;
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	/* Jump back to next instruction */
> +	addr = code + TMPL_RESTORE_END;
> +	insn = aarch64_insn_gen_branch_imm(
> +				(unsigned long)(&code[TMPL_RESTORE_END]),
> +				(unsigned long)(op->kp.addr) + 4,
> +				AARCH64_INSN_BRANCH_NOLINK);
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	flush_icache_range((unsigned long)code,
> +			   (unsigned long)(&code[TMPL_END_IDX]));
> +	/* Set op->optinsn.insn means prepared. */
> +	op->optinsn.insn = code;
> +
> +	return 0;
> +
> +error:
> +	free_optinsn_slot(code, 0);
> +	return -ERANGE;
> +}
> +
> +void arch_optimize_kprobes(struct list_head *oplist)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		u32 insn;
> +
> +		WARN_ON(kprobe_disabled(&op->kp));
> +
> +		/*
> +		 * Backup instructions which will be replaced
> +		 * by jump address
> +		 */
> +		memcpy(op->optinsn.copied_insn, op->kp.addr,
> +			RELATIVEJUMP_SIZE);
> +		insn = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
> +				(unsigned long)op->optinsn.insn,
> +				AARCH64_INSN_BRANCH_NOLINK);
> +
> +		WARN_ON(insn == 0);
> +
> +		aarch64_insn_patch_text_nosync((void*)op->kp.addr, insn);
> +
> +		list_del_init(&op->list);
> +	}
> +}
> +
> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
> +{
> +	arch_arm_kprobe(&op->kp);
> +}
> +
> +/*
> + * Recover original instructions and breakpoints from relative jumps.
> + * Caller must call with locking kprobe_mutex.
> + */
> +void arch_unoptimize_kprobes(struct list_head *oplist,
> +			    struct list_head *done_list)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		arch_unoptimize_kprobe(op);
> +		list_move(&op->list, done_list);
> +	}
> +}
> +
> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
> +{
> +	if (op->optinsn.insn) {
> +		free_optinsn_slot(op->optinsn.insn, 1);
> +		op->optinsn.insn = NULL;
> +	}
> +}
> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S
> b/arch/arm64/kernel/probes/optprobe_trampoline.S
> new file mode 100644
> index 000000000000..13729cb279b8
> --- /dev/null
> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
> @@ -0,0 +1,80 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * trampoline entry and return code for optprobes.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/assembler.h>
> +
> +	.global optprobe_template_entry
> +optprobe_template_entry:
> +	sub sp, sp, #PT_REGS_SIZE
> +	stp x0, x1, [sp, #S_X0]
> +	stp x2, x3, [sp, #S_X2]
> +	stp x4, x5, [sp, #S_X4]
> +	stp x6, x7, [sp, #S_X6]
> +	stp x8, x9, [sp, #S_X8]
> +	stp x10, x11, [sp, #S_X10]
> +	stp x12, x13, [sp, #S_X12]
> +	stp x14, x15, [sp, #S_X14]
> +	stp x16, x17, [sp, #S_X16]
> +	stp x18, x19, [sp, #S_X18]
> +	stp x20, x21, [sp, #S_X20]
> +	stp x22, x23, [sp, #S_X22]
> +	stp x24, x25, [sp, #S_X24]
> +	stp x26, x27, [sp, #S_X26]
> +	stp x28, x29, [sp, #S_X28]
> +	add x0, sp, #PT_REGS_SIZE
> +	stp lr, x0, [sp, #S_LR]
> +	/*
> +	 * Construct a useful saved PSTATE
> +	 */
> +	mrs x0, nzcv
> +	mrs x1, daif
> +	orr x0, x0, x1
> +	mrs x1, CurrentEL
> +	orr x0, x0, x1
> +	mrs x1, SPSel
> +	orr x0, x0, x1
> +	stp xzr, x0, [sp, #S_PC]
> +	/* Get parameters to optimized_callback() */
> +	ldr	x0, 1f
> +	mov	x1, sp
> +	/* Branch to optimized_callback() */
> +	.global optprobe_template_call
> +optprobe_template_call:
> +	nop
> +        /* Restore registers */
> +	ldr x0, [sp, #S_PSTATE]
> +	and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
> +	msr nzcv, x0
> +	ldp x0, x1, [sp, #S_X0]
> +	ldp x2, x3, [sp, #S_X2]
> +	ldp x4, x5, [sp, #S_X4]
> +	ldp x6, x7, [sp, #S_X6]
> +	ldp x8, x9, [sp, #S_X8]
> +	ldp x10, x11, [sp, #S_X10]
> +	ldp x12, x13, [sp, #S_X12]
> +	ldp x14, x15, [sp, #S_X14]
> +	ldp x16, x17, [sp, #S_X16]
> +	ldp x18, x19, [sp, #S_X18]
> +	ldp x20, x21, [sp, #S_X20]
> +	ldp x22, x23, [sp, #S_X22]
> +	ldp x24, x25, [sp, #S_X24]
> +	ldp x26, x27, [sp, #S_X26]
> +	ldp x28, x29, [sp, #S_X28]
> +	ldr lr, [sp, #S_LR]
> +        add sp, sp, #PT_REGS_SIZE
> +	.global optprobe_template_restore_orig_insn
> +optprobe_template_restore_orig_insn:
> +	nop
> +	.global optprobe_template_restore_end
> +optprobe_template_restore_end:
> +	nop
> +	.global optprobe_template_end
> +optprobe_template_end:
> +	.global optprobe_template_val
> +optprobe_template_val:
> +	1:	.long 0
> +		.long 0
> --
> 2.17.1


Thanks
Barry



From dillon.minfei at gmail.com  Thu Aug  5 01:55:23 2021
From: dillon.minfei at gmail.com (Dillon Min)
Date: Thu, 5 Aug 2021 16:55:23 +0800
Subject: [PATCH v4 0/3] Add ilitek ili9341 panel driver
In-Reply-To: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
References: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
Message-ID: <CAL9mu0+P4U+2tyA7CGCcP6riWXzKSpCWpNxKi3MvTt8Abiwtow@mail.gmail.com>

Hi All

Just a gentle ping, thanks.

Best regards.
Dillon

On Sat, 24 Jul 2021 at 11:44, <dillon.minfei at gmail.com> wrote:
>
> From: Dillon Min <dillon.minfei at gmail.com>
>
> Since the st,sf-tc240t-9370-t dts binding already exist in stm32f429-disco.dts
> but, the panel driver didn't get accepted from mainline. it's time to submit
> patch fot it.
>
> This driver can support two different interface by different dts bindings:
> - spi+dpi, use spi to configure register, dpi for graphic data.
>   st,sf-tc240t-9370-t
> - only spi, just like tiny/ili9341.c (actually, this part is copy from tiny)
>   adafruit,yx240qv29
>
> I was submited the first patch last year, you can find it at [1].
> this patch has one major difference from that one, which is replace the low
> level communication way, from spi_sync() to mipi_dbi_{command,
> command_stackbuf}() interface, referred from Linus's patch [2].
>
> both the two dpi/dbi interface was tested on stm32f429-disco board, if anyone
> want to verify this patch, you need apply the clk patch for this board first,
> you can get it from [3].
>
> [1] "drm/panel: Add ilitek ili9341 panel driver"
> https://lore.kernel.org/lkml/1590378348-8115-7-git-send-email-dillon.minfei at gmail.com/
>
> [2] "drm/panel: s6e63m0: Switch to DBI abstraction for SPI"
> https://lore.kernel.org/dri-devel/20210611214243.669892-1-linus.walleij at linaro.org/
>
> [3]
> https://lore.kernel.org/lkml/1590378348-8115-6-git-send-email-dillon.minfei at gmail.com/
>
> v4:
> - fix m68k-allmodconfig build error which reported by lkp, thanks.
> - add Copyright 2018 David Lechner <david at lechnology.com>.
> v3 link:
> https://lore.kernel.org/lkml/1627013203-23099-1-git-send-email-dillon.minfei at gmail.com/
>
> v3:
> - add Fixes tags.
> - collect reviewed-by tags from linus and jagan.
> - replace DRM_ERROR() with dev_err() or drm_err().
> - remove kernel-doc markers from struct ili9341_config{}.
> - reorder include headers.
> - remove the struct device *dev from struct ili9341{}.
> - restructure the ili9341_probe() function, add two ili9341_{dbi,dpi)_probe()
>   to make it more readable according to jagan's suggestion, thanks.
>
> for the full drm driver exist in drm/panel need Sam and Laurent's feedback.
> so, not cover this part at this time, will be update later.
>
> v2 link:
> https://lore.kernel.org/lkml/1626853288-31223-1-git-send-email-dillon.minfei at gmail.com/
>
> v2:
> - replace vcc regulator to bulk regulators in driver, from linus suggestion.
> - fix dtbs_check warnings on ili9341 dts binding check.
> - add bulk regulation node in ilitek,ili9341.yaml.
> v1 link:
> https://lore.kernel.org/lkml/1626430843-23823-1-git-send-email-dillon.minfei at gmail.com/
>
> Dillon Min (3):
>   dt-bindings: display: panel: Add ilitek ili9341 panel bindings
>   ARM: dts: stm32: fix dtbs_check warning on ili9341 dts binding
>   drm/panel: Add ilitek ili9341 panel driver
>
>  .../bindings/display/panel/ilitek,ili9341.yaml     |  78 ++
>  arch/arm/boot/dts/stm32f429-disco.dts              |   2 +-
>  drivers/gpu/drm/panel/Kconfig                      |  12 +
>  drivers/gpu/drm/panel/Makefile                     |   1 +
>  drivers/gpu/drm/panel/panel-ilitek-ili9341.c       | 792 +++++++++++++++++++++
>  5 files changed, 884 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
>  create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c
>
> --
> 1.9.1
>


From lee.jones at linaro.org  Thu Aug  5 01:56:11 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Thu,  5 Aug 2021 09:56:11 +0100
Subject: [PATCH v2 1/1] mfd: simple-mfd-i2c: Add support for registering
 devices via MFD cells
Message-ID: <20210805085611.864188-1-lee.jones@linaro.org>

More devices are cropping up requiring only Regmap initialisation and
child registration functionality.  We currently only support that if
all required devices are represented by their own Device Tree nodes
complete with compatible strings.

However, not everyone is happy with adding empty nodes that provide no
additional device information into the Device Tree.

Rather than have a plethora of mostly empty, function-less drivers in
MFD, we'll support those simple cases in here instead via MFD cells.

Cc: Michael Walle <michael at walle.cc>
Cc: Mark Brown <broonie at kernel.org>
Cc: Alistair Francis <alistair23 at gmail.com>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
v2:
 - Check for empty of_device_id .data entry 

 drivers/mfd/simple-mfd-i2c.c | 41 +++++++++++++++++++++++++++++-------
 drivers/mfd/simple-mfd-i2c.h | 32 ++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 8 deletions(-)
 create mode 100644 drivers/mfd/simple-mfd-i2c.h

diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 87f684cff9a17..583e8c7924af0 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -2,39 +2,64 @@
 /*
  * Simple MFD - I2C
  *
+ * Author(s):
+ * 	Michael Walle <michael at walle.cc>
+ * 	Lee Jones <lee.jones at linaro.org>
+ *
  * This driver creates a single register map with the intention for it to be
  * shared by all sub-devices.  Children can use their parent's device structure
  * (dev.parent) in order to reference it.
  *
  * Once the register map has been successfully initialised, any sub-devices
- * represented by child nodes in Device Tree will be subsequently registered.
+ * represented by child nodes in Device Tree or via the MFD cells in this file
+ * will be subsequently registered.
  */
 
 #include <linux/i2c.h>
 #include <linux/kernel.h>
+#include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/regmap.h>
 
-static const struct regmap_config simple_regmap_config = {
+#include "simple-mfd-i2c.h"
+
+static const struct regmap_config regmap_config_8r_8v = {
 	.reg_bits = 8,
 	.val_bits = 8,
 };
 
 static int simple_mfd_i2c_probe(struct i2c_client *i2c)
 {
-	const struct regmap_config *config;
+	const struct simple_mfd_data *simple_mfd_data;
+	const struct regmap_config *regmap_config;
 	struct regmap *regmap;
+	int ret;
+
+	simple_mfd_data = device_get_match_data(&i2c->dev);
 
-	config = device_get_match_data(&i2c->dev);
-	if (!config)
-		config = &simple_regmap_config;
+	/* If no regmap_config is specified, use the default 8reg and 8val bits */
+	if (!simple_mfd_data || !simple_mfd_data->regmap_config)
+		regmap_config = &regmap_config_8r_8v;
+	else
+		regmap_config = simple_mfd_data->regmap_config;
 
-	regmap = devm_regmap_init_i2c(i2c, config);
+	regmap = devm_regmap_init_i2c(i2c, regmap_config);
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return devm_of_platform_populate(&i2c->dev);
+	/* If no MFD cells are spedified, use register the DT child nodes instead */
+	if (!simple_mfd_data || !simple_mfd_data->mfd_cell)
+		return devm_of_platform_populate(&i2c->dev);
+
+	ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
+				   simple_mfd_data->mfd_cell,
+				   simple_mfd_data->mfd_cell_size,
+				   NULL, 0, NULL);
+	if (!ret)
+		dev_err(&i2c->dev, "Failed to add child devices\n");
+
+	return ret;
 }
 
 static const struct of_device_id simple_mfd_i2c_of_match[] = {
diff --git a/drivers/mfd/simple-mfd-i2c.h b/drivers/mfd/simple-mfd-i2c.h
new file mode 100644
index 0000000000000..7cb2bdd347d97
--- /dev/null
+++ b/drivers/mfd/simple-mfd-i2c.h
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Simple MFD - I2C
+ *
+ * Author: Lee Jones <lee.jones at linaro.org>
+ *
+ * This driver creates a single register map with the intention for it to be
+ * shared by all sub-devices.  Children can use their parent's device structure
+ * (dev.parent) in order to reference it.
+ *
+ * This driver creates a single register map with the intention for it to be
+ * shared by all sub-devices.  Children can use their parent's device structure
+ * (dev.parent) in order to reference it.
+ *
+ * Once the register map has been successfully initialised, any sub-devices
+ * represented by child nodes in Device Tree or via the MFD cells in the
+ * associated C file will be subsequently registered.
+ */
+
+#ifndef __MFD_SIMPLE_MFD_I2C_H
+#define __MFD_SIMPLE_MFD_I2C_H
+
+#include <linux/mfd/core.h>
+#include <linux/regmap.h>
+
+struct simple_mfd_data {
+	const struct regmap_config *regmap_config;
+	const struct mfd_cell *mfd_cell;
+	size_t mfd_cell_size;
+};
+
+#endif /* __MFD_SIMPLE_MFD_I2C_H */
-- 
2.32.0.605.g8dce9f2422-goog



From f.fainelli at gmail.com  Thu Aug  5 01:57:01 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 5 Aug 2021 01:57:01 -0700
Subject: [PATCH v4 0/4] ARM: dts: NSP: add Meraki MX64/MX65 series
In-Reply-To: <20210625095000.3358973-1-mnhagan88@gmail.com>
References: <20210625095000.3358973-1-mnhagan88@gmail.com>
Message-ID: <fefad5f1-a2be-0feb-6170-d1bf5a1d86a2@gmail.com>



On 6/25/2021 2:49 AM, Matthew Hagan wrote:
> Changes from v2:
>   - Introduce boards to Makefile in same patch as the board dts is added
>     (Vladimir Oltean)
>   - Use alphabetical ordering for labels (Vladimir Oltean)
>   - Remove address-cells and size-cells in qca8337 switch nodes (Vladimir
>     Oltean)
>   - Remove "cpu" labels from switch nodes' CPU ports (Vladimir Oltean)
>   - Various LED fixes, utilising dt-bindings/leds/common.h and correctly
>     specifying LEDs in the form "led-N" and with the color/function/
>     function-enumerator properties.
>   - Fix PWM LEDs and corresponding pinctrl bindings. (Vladimir Oltean)
> 
> The following changes were submitted as a separate series:
>   - Introduce patches to disable QSPI by default and enable where used
>     (Vladimir Oltean)
>   - Move mdio at 18032000 node from board related file to SoC (Vladimir
>     Oltean)
>   - In addition to above, relocate mdio-mux to bcm-nsp.dtsi and fix
>     the resulting usb3_phy issues
> 
> Changes from v3:
>   - Sort labels on mx64 a0 dts files into alphabetical order as well
>   - move include directives for input/input.h and leds/common.h to
>     bcm958625-mx6x-common.dtsi
>   - Whitespace fixes in bcm958625-mx6x-common.dtsi
>   - rename "senao_nvram" partition to "nvram"
> 
> Matthew Hagan (4):
>    ARM: dts: NSP: Add common bindings for MX64/MX65
>    ARM: dts: NSP: Add DT files for Meraki MX64 series
>    ARM: dts: NSP: Add DT files for Meraki MX65 series
>    dt-bindings: arm: bcm: NSP: add Meraki MX64/MX65

Matt, should I be expecting a v5 based on Arnd's comments?
-- 
Florian


From dillon.minfei at gmail.com  Thu Aug  5 01:59:27 2021
From: dillon.minfei at gmail.com (Dillon Min)
Date: Thu, 5 Aug 2021 16:59:27 +0800
Subject: [PATCH v2 0/9] Add support for DMA2D of STMicroelectronics STM32
 Soc series
In-Reply-To: <1626341068-20253-1-git-send-email-dillon.minfei@gmail.com>
References: <1626341068-20253-1-git-send-email-dillon.minfei@gmail.com>
Message-ID: <CAL9mu0LKkL29md9KSzVkacujUo2xRoAsJ6zHDkJJ=svB9GwkaQ@mail.gmail.com>

Hi Hans,

Just a gentle ping, could you help to take a look at patch (6 ~ 9) of
this v2 series.
Thanks.

Best Regards
Dillon

On Thu, 15 Jul 2021 at 17:24, <dillon.minfei at gmail.com> wrote:
>
> From: Dillon Min <dillon.minfei at gmail.com>
>
> This patchset introduces a basic support for DMA2D Interface
> of STMicroelectronics STM32 SoC series.
>
> This first basic support implements R2M, M2M, M2M_PFC
> M2M_BLEND support will be added later on.
>
> This has been tested on STM32469-DISCO board.
>
> history
>
> v2:
> - update v4l2-compliance to SHA: a4f2e3a6f306 2021-07-13 08:04:15
>   the test results at below [1].
> - introduce Documentation/userspace-api/media/drivers/stm32-uapi.rst
>   to explain the detail of dma2d's ioctl.
> - reserved 16 ioctls from v4l2-controls.h for stm32, introduce stm32-media.h.
> - collect Reviewed-by tag from Rob Herring.
> - update dma2d driver from Hans's review. the details can be found
>   at related patches.
> v1 link:
> https://lore.kernel.org/lkml/1621508727-24486-1-git-send-email-dillon.minfei at gmail.com/
>
> v1:
> The commit based on kernel(master): c3d0e3fd41b7f0f5d5d5b6022ab7e813f04ea727
>
> Note for v4l2-compliance tool on nu-mmu platform:
> I add two change based on v4l-utils since commit:
> f0c7e3d71eaf4182bae7eb3ee0e43b4eeb047ea9
>
> - change fork() to vfork() in v4l2-test-controls.cpp
>   since no-mmu platform don't include fork().
>
> - bypass VIDIOC_QUERYCAP nullptr check
>   I'm not sure if this is the bug from my cross compile tool
>   which created by buildroot. user area's nullptr can't be
>   detected by kernel side, i was try to add access_ok()
>   in v4l2-ioctl.c, but no help
>
>   If this case must be fixed, i will continue to debug it.
>   the error log:
>   ...
>   fail: v4l2-compliance.cpp(623): doioctl(node, VIDIOC_QUERYCAP, nullptr) !=
>   EFAULT
>   ..
>
> My changes on v4l2-compliance:
>
> diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp
> b/utils/v4l2-compliance/v4l2-compliance.cpp
> index 90a5036..a25fe4f 100644
> --- a/utils/v4l2-compliance/v4l2-compliance.cpp
> +++ b/utils/v4l2-compliance/v4l2-compliance.cpp
> @@ -620,7 +620,7 @@ static int testCap(struct node *node)
>
>         memset(&vcap, 0xff, sizeof(vcap));
>         // Must always be there
> -       fail_on_test(doioctl(node, VIDIOC_QUERYCAP, nullptr) != EFAULT);
> +       //fail_on_test(doioctl(node, VIDIOC_QUERYCAP, nullptr) != EFAULT);
>         fail_on_test(doioctl(node, VIDIOC_QUERYCAP, &vcap));
>         fail_on_test(check_ustring(vcap.driver, sizeof(vcap.driver)));
>         fail_on_test(check_ustring(vcap.card, sizeof(vcap.card)));
>
> with v4l2-compliance test log (with above modification):
> since the stm32f469-disco ram limitation, there are 25 failed on
> dma_alloc_coherent()
>
> Really appreciate if someone can help to test this patch on the STM32429I-EVAL
> evaluation board (https://www.st.com/en/evaluation-tools/stm32429i-eval.html)
> 8M x 32-bit SDRAM, 1M x 16-bit SRAM and 8M x 16-bit NOR Flash
>
> / # free
>             total       used       free     shared    buffers     cached
> Mem:        15604       6104       9500     0         0           2488
> -/+ buffers/cache:      3616       11988
>
> [1] v4l2-compliance test result:
>
> ./v4l2-compliance -s -f -d /dev/video0 &
> [1] 34 ./v4l2-compliance -s -f -d /dev/video0
> / # v4l2-compliance 1.21.0-4831, 32 bits, 32-bit time_t
> v4l2-compliance SHA: a4f2e3a6f306 2021-07-13 08:04:15
>
> Compliance test for stm-dma2d device /dev/video0:
>
> Driver Info:
>         Driver name      : stm-dma2d
>         Card type        : stm-dma2d
>         Bus info         : platform:stm-dma2d
>         Driver version   : 5.14.0
>         Capabilities     : 0x84208000
>                 Video Memory-to-Memory
>                 Streaming
>                 Extended Pix Format
>                 Device Capabilities
>         Device Caps      : 0x04208000
>                 Video Memory-to-Memory
>                 Streaming
>                 Extended Pix Format
>
> Required ioctls:
>         test VIDIOC_QUERYCAP: OK
>         test invalid ioctls: OK
>
> Allow for multiple opens:
>         test second /dev/video0 open: OK
>         test VIDIOC_QUERYCAP: OK
>         test VIDIOC_G/S_PRIORITY: OK
>         test for unlimited opens: OK
>
> Debug ioctls:
>         test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
>         test VIDIOC_LOG_STATUS: OK (Not Supported)
>
> Input ioctls:
>         test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
>         test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>         test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
>         test VIDIOC_ENUMAUDIO: OK (Not Supported)
>         test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
>         test VIDIOC_G/S_AUDIO: OK (Not Supported)
>         Inputs: 0 Audio Inputs: 0 Tuners: 0
>
> Output ioctls:
>         test VIDIOC_G/S_MODULATOR: OK (Not Supported)
>         test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>         test VIDIOC_ENUMAUDOUT: OK (Not Supported)
>         test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
>         test VIDIOC_G/S_AUDOUT: OK (Not Supported)
>         Outputs: 0 Audio Outputs: 0 Modulators: 0
>
> Input/Output configuration ioctls:
>         test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
>         test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
>         test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
>         test VIDIOC_G/S_EDID: OK (Not Supported)[
>
> Control ioctls:
>  test VIDIOC_QUERY_EX _CTRL/QUERY ENU: 55.029750] stm-dma2d 4002b000.dma2d: Format not supported: ????, use the default.
> OK
>         test VIDIOC_QUERYCTRL: OK
>         test VIDIOC_G[S_CTRL: OK
>         test VIDIOC_G/S/TRY_EXT_CTRLS  OK
>         test VI I C_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
>         test 55DIOC_G/S_JP.784007] stm-dma2d 4002b000.dma2d: Format not supported: ????, use the default.
> EGCOMP: OK (Not Supported)
>         Standard Controls: 2 Private[Controls: 2
>
> For a  ioctls:
>         5est VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK0m
>         test VI.IOC_G/S_PAR5: OK (Not 50538] stm-dma2d 4002b000.dma2d: Format not supported: ????, use the default.
> Supported)
>         test VIDIOC_G_FBUF: OK (Not Supported)
>         test[V DIOC_G_FM : OK
>         test VID5OC_T7Y_FMT: OK
> .316175] stm-dma2d 4002b000.dma2d: Format not supported: ????, use the default.
>         test VIDIOC_S_FMT: OK
>         test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
>         test Cropping: OK (Not Supported)
>         test Composing: OK (Not Supported)
>         test Scaling: OK
>
> Codec ioctls:
>         test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
>         test VIDIOC_G_ENC_INDEX: OK (Not Supported)
>         test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
>
> Buffer ioctls:
>         test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
>         test VIDIOC_EXPBUF: OK
>         test Requests: OK (Not Supported)
>
> Test input 0:
>
> Streaming ioctls:
>         test read/write: OK (Not Supported)
>         test blocking wait: OK
> [   59.905900] use of bytesused == 0 is deprecated and will be removed in the future,
> [   60.665190] use the actual size instead.
>         Video Capture: Captured 58 buffers
>         test MMAP (no poll): OK
>         Video Capture: Captured 58 buffers
>         test MMAP (select): OK
>         Video Capture: Captured 58 buffers
>         test MMAP (epoll): OK
>         test USERPTR (no poll): OK (Not Supported)
>         test USERPTR (select): OK (Not Supported)
>         test DMABUF: Cannot test, specify --expbuf-device
>
> Stream using all formats:
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 1x1 -> BA24 (32-bit ARGB 8-8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 1x1 -> RGB3 (24-bit RGB 8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 1x1 -> RGBP (16-bit RGB 5-6-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 1x1 -> AR15 (16-bit ARGB 1-5-5-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 1x1 -> AR12 (16-bit ARGB 4-4-4-4) 1x1: OK
> [   83.015780] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -323584 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         BA24 (32-bit ARGB 8-8-8-8) 16383x65535 -> BA24 (32-bit ARGB 8-8-8-8) 16383x65535: FAIL
> [   83.959807] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -323584 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         BA24 (32-bit ARGB[8-8-8-8) 16383x 553  -> RGB3 (24- it R8B 8-8-84 16383x65535: FAIL
> .899851] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -323584 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         BA24 (32-bit ARGB 8-8-8-8)[16383x65535 -> RGBP (16-bit RGB  -6-5) 16383x65535: FA L
> 85.848108] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -323584 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         BA24 (32-bit ARGB 8-8-8-8) 16383x65535 -> AR15 (16-bit ARGB 1-5-5-5) 16[83x65535: F IL
>   86.802223] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -323584 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         BA24 (32-bit ARGB 8-8-8-8) 16383x65535 -> AR12 (16-bit ARGB 4-4-4-4) 16383x65535: FAIL
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 240x320 -> BA24 (32-bit ARGB 8-8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 240x320 -> RGB3 (24-bit RGB 8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 240x320 -> RGBP (16-bit RGB 5-6-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 240x320 -> AR15 (16-bit ARGB 1-5-5-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         BA24 (32-bit ARGB 8-8-8-8) 240x320 -> AR12 (16-bit ARGB 4-4-4-4) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 1x1 -> BA24 (32-bit ARGB 8-8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 1x1 -> RGB3 (24-bit RGB 8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 1x1 -> RGBP (16-bit RGB 5-6-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 1x1 -> AR15 (16-bit ARGB 1-5-5-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 1x1 -> AR12 (16-bit[ARGB 4-4-4-4) 1x1: OK
>   89.086437] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -1073983488 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         RGB3 (24-bi[  GB 8-8-8) 16383x65535  > BA24 (32-bit A GB 8-8-8-8) 16383965505: FA.L
> 030474] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -1073983488 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
> 978755] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -1073983488 failed035: 31mFAIL
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         RGB3 (24-bit RGB [-8-8) 16383 65535 -> RGBP (16-bit RGB 5-6-5) 16383x65535: FA L
> 91.923561] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -1073983488 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         RGB3 (24-bit RGB 8-8-8) 16383x65535 -> AR15 (16-bit ARGB 1-5-5-5) 16383x65535: FAIL
> [   92.885742] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size -1073983488 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         RGB3 (24-bit RGB 8-8-8) 16383x65535 -> AR12 (16-bit ARGB 4-4-4-4) 16383x65535: FAIL
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 240x320 -> BA24 (32-bit ARGB 8-8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 240x320 -> RGB3 (24-bit RGB 8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 240x320 -> RGBP (16-bit RGB 5-6-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 240x320 -> AR15 (16-bit ARGB 1-5-5-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGB3 (24-bit RGB 8-8-8) 240x320 -> AR12 (16-bit ARGB 4-4-4-4) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 1x1 -> BA24 (32-bit ARGB 8-8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 1x1 -> RGB3 (24-bit RGB 8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 1x1 -> RGBP (16-bit RGB 5-6-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 1x1 -> AR15 (16-bit ARGB 1-5-5-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 1x1 -> AR12 (16-bit AR[B 4-4-4-4) 1x1: OK
>   95.008330] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
> 50176] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed83x95535: FAIL
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         RGBP (16-bit RGB 5-6-[) 16383x65535 -> R B3 (24-bit RG  8-8-8) 16383x65535: FAIL9[0m
> 6.895671] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         RGBP (16-bit RGB 5-6-5) 16383x65535 -> RGBP (16-bit RGB 5-6-5) 16383x65535: FAIL
> [   97.851563] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         RGBP (16-bit [GB 5 6-5) 16383x6553  -> AR15 (16-bit ARGB 1-5-5-5) 16383x69535: FAIL.
>                                                                                             791193] stm-dma2d 4002b000.dma2d: dma_alloc_coherd
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         RGBP (16-bit RGB 5-6-5) 16383x65535 -> AR12 (16-bit ARGB 4-4-4-4) 16383x65535: FAIL
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 240x320 -> BA24 (32-bit ARGB 8-8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 240x320 -> RGB3 (24-bit RGB 8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 240x320 -> RGBP (16-bit RGB 5-6-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 240x320 -> AR15 (16-bit ARGB 1-5-5-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         RGBP (16-bit RGB 5-6-5) 240x320 -> AR12 (16-bit ARGB 4-4-4-4) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 1x1 -> BA24 (32-bit ARGB 8-8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 1x1 -> RGB3 (24-bit RGB 8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 1x1 -> RGBP (16-bit RGB 5-6-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 1x1 -> AR15 (16-bit ARGB 1-5-5-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 1x1 -[ AR12 (16-bit  RGB 4-4-4-4) 1x1: OK
> 100.827052] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR15 (16-bit ARGB 1-5-5-5) 16383[655 5 -> BA24 (32-bit ARGB 8-8-8-8)  6383x65535: F0IL0m
> .764900] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR15 (16-bit ARGB 1-5-5-5)[163 3x65535 -> RGB3 (24- it RGB 8-8-8) 16383x65535: AIL0[0m
> 2.704672] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR15 (16-bit ARGB 1-5-5-5) 16383x65535 -> RGBP (16-bit RGB 5-6-5) 16383x65535: FAIL
> [  103.656921] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR15 (16-bit ARGB 1-5-5-5) 16383x65535[-> AR15 (16-bit ARGB 1 5-5-5) 16383x65535: FAIL
> 104.596785] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR15 (16-bit ARGB 1-5-5-5) 16383x65535 -> AR12 (16-bit ARGB 4-4-4-4) 16383x65535: FAIL
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 240x320 -> BA24 (32-bit ARGB 8-8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 240x320 -> RGB3 (24-bit RGB 8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 240x320 -> RGBP (16-bit RGB 5-6-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 240x320 -> AR15 (16-bit ARGB 1-5-5-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR15 (16-bit ARGB 1-5-5-5) 240x320 -> AR12 (16-bit ARGB 4-4-4-4) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 1x1 -> BA24 (32-bit ARGB 8-8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 1x1 -> RGB3 (24-bit RGB 8-8-8) 1x1: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 1x1 -> RGBP (16-bit RGB 5-6-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 1x1 -> AR15 (16-bit ARGB 1-5-5-5) 1x1: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 1x1 -> AR12 (16-bit ARGB[4- -4-4) 1x1: OK
>  106.636958] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR12 (16-bit ARGB[4-4-4-4) 16383x65535 -> BA24 (32-bit ARGB 8 8-8-8) 16383x65535:  [1;31mFAIL
> 107.578517] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR12 (16-bit ARGB 4-4-[  ) 16383x65535 1> R0B3 (24-bit RGB 8-8-88 16383x65535: FAIL
> .527898] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR12 (16-bit ARGB 4-4-4-4) 16383x65535 -> RGBP (16-bit RGB 5-6-5) 16383x65535: FAIL
> [  109.495892] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR12 (16-bit ARGB 4-4-4-4) 1638[x65535 -> AR15 (16-bit ARGB 1-5-5-5) 16383x6 535: FAIL
> 110.449341] stm-dma2d 4002b000.dma2d: dma_alloc_coherent of size 2147323904 failed
>                 fail: v4l2-test-buffers.cpp(1300): q.reqbufs(node, 2)
>         AR12 (16-bit ARGB 4-4-4-4) 16383x65535 -> AR12 (16-bit ARGB 4-4-4-4) 16383x65535: FAIL
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 240x320 -> BA24 (32-bit ARGB 8-8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 240x320 -> RGB3 (24-bit RGB 8-8-8) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 240x320 -> RGBP (16-bit RGB 5-6-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 240x320 -> AR15 (16-bit ARGB 1-5-5-5) 240x320: OK
>         Video Capture: Captured 8 buffers
>         AR12 (16-bit ARGB 4-4-4-4) 240x320 -> AR12 (16-bit ARGB 4-4-4-4) 240x320: OK
> Total for stm-dma2d device /dev/video0: 127, Succeeded: 102, Failed: 25, Warnings: 0
>
> [1] Done                   ./v4l2-compliance -s -f -d /dev/video0
> *** BLURB HERE ***
>
> Dillon Min (9):
>   media: admin-guide: add stm32-dma2d description
>   media: dt-bindings: media: add document for STM32 DMA2d bindings
>   clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after
>     kernel startup
>   ARM: dts: stm32: Enable DMA2D support on STM32F429 MCU
>   ARM: dts: stm32: Enable DMA2D on STM32F469-DISCO board
>   media: v4l2-mem2mem: add v4l2_m2m_get_unmapped_area for no-mmu
>     platform
>   media: docs: add doc for the stm32 dma2d driver
>   media: v4l: uapi: Add user control base for stm32 dma2d controls
>   media: stm32-dma2d: STM32 DMA2D driver
>
>  .../admin-guide/media/platform-cardlist.rst        |   1 +
>  .../devicetree/bindings/media/st,stm32-dma2d.yaml  |  71 ++
>  .../userspace-api/media/drivers/index.rst          |   1 +
>  .../userspace-api/media/drivers/stm32-uapi.rst     |  22 +
>  arch/arm/boot/dts/stm32f429.dtsi                   |  10 +
>  arch/arm/boot/dts/stm32f469-disco.dts              |   4 +
>  drivers/clk/clk-stm32f4.c                          |   7 +-
>  drivers/media/platform/Kconfig                     |   9 +
>  drivers/media/platform/Makefile                    |   1 +
>  drivers/media/platform/stm32/Makefile              |   2 +
>  drivers/media/platform/stm32/dma2d/dma2d-hw.c      | 143 ++++
>  drivers/media/platform/stm32/dma2d/dma2d-regs.h    | 113 +++
>  drivers/media/platform/stm32/dma2d/dma2d.c         | 796 +++++++++++++++++++++
>  drivers/media/platform/stm32/dma2d/dma2d.h         | 136 ++++
>  drivers/media/v4l2-core/v4l2-mem2mem.c             |  21 +
>  include/media/v4l2-mem2mem.h                       |   5 +
>  include/uapi/linux/stm32-media.h                   |  12 +
>  include/uapi/linux/v4l2-controls.h                 |   5 +
>  18 files changed, 1355 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/media/st,stm32-dma2d.yaml
>  create mode 100644 Documentation/userspace-api/media/drivers/stm32-uapi.rst
>  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d-hw.c
>  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d-regs.h
>  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d.c
>  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d.h
>  create mode 100644 include/uapi/linux/stm32-media.h
>
> --
> 2.7.4
>


From matthias.bgg at gmail.com  Thu Aug  5 02:02:18 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Thu, 5 Aug 2021 11:02:18 +0200
Subject: [PATCH v4 1/3] arm: dts: mt8135: Move pinfunc to
 include/dt-bindings/pinctrl
In-Reply-To: <20210804044033.3047296-1-hsinyi@chromium.org>
References: <20210804044033.3047296-1-hsinyi@chromium.org>
Message-ID: <d48087c2-ddff-0c58-c7e6-a0ba526a393f@gmail.com>

Hi Linus,

On 04/08/2021 06:40, Hsin-Yi Wang wrote:
> Move mt8135-pinfunc.h into include/dt-bindings/pinctrl so that we can
> include it in yaml examples.
> 
> Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
> ---
>  arch/arm/boot/dts/mt8135.dtsi                                   | 2 +-
>  .../boot/dts => include/dt-bindings/pinctrl}/mt8135-pinfunc.h   | 0
>  2 files changed, 1 insertion(+), 1 deletion(-)
>  rename {arch/arm/boot/dts => include/dt-bindings/pinctrl}/mt8135-pinfunc.h (100%)
> 

If that's fine with you, I'll take patch 1+2 through my tree. IMHO the best for
patch 3 would be to go through your tree.

Sounds good?

Regards,
Matthias

> diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi
> index 0e4e835026db0..a031b36363187 100644
> --- a/arch/arm/boot/dts/mt8135.dtsi
> +++ b/arch/arm/boot/dts/mt8135.dtsi
> @@ -9,7 +9,7 @@
>  #include <dt-bindings/interrupt-controller/irq.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  #include <dt-bindings/reset/mt8135-resets.h>
> -#include "mt8135-pinfunc.h"
> +#include <dt-bindings/pinctrl/mt8135-pinfunc.h>
>  
>  / {
>  	#address-cells = <2>;
> diff --git a/arch/arm/boot/dts/mt8135-pinfunc.h b/include/dt-bindings/pinctrl/mt8135-pinfunc.h
> similarity index 100%
> rename from arch/arm/boot/dts/mt8135-pinfunc.h
> rename to include/dt-bindings/pinctrl/mt8135-pinfunc.h
> 


From mchehab+huawei at kernel.org  Thu Aug  5 02:04:38 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Thu,  5 Aug 2021 11:04:38 +0200
Subject: [PATCH] arm64: dts: HiSilicon: hi3660: address a PCI warning
Message-ID: <498ca4c17f018a234817cccd35cdaba3e3884b42.1628154271.git.mchehab+huawei@kernel.org>

When the driver is registered, it produces a warning when
registering the PCI bridge:

	[    5.363450] pci_bus 0000:00: root bus resource [bus 00-01]
	[    5.396998] pci_bus 0000:01: busn_res: can not insert [bus 01-ff] under [bus 00-01] (conflicts with (null) [bus 00-01])
	[    5.284831] pci 0000:00:00.0: PCI bridge to [bus 01-ff]

The reason is that the bus-range is wrong. Address it.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index f1ec87c05842..cf2079590ad8 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -1002,7 +1002,7 @@ pcie at f4000000 {
 			      <0x0 0xf3f20000 0x0 0x40000>,
 			      <0x0 0xf5000000 0x0 0x2000>;
 			reg-names = "dbi", "apb", "phy", "config";
-			bus-range = <0x0  0x1>;
+			bus-range = <0x0  0xff>;
 			#address-cells = <3>;
 			#size-cells = <2>;
 			device_type = "pci";
-- 
2.31.1



From f.fainelli at gmail.com  Thu Aug  5 02:08:16 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 5 Aug 2021 02:08:16 -0700
Subject: [PATCH 2/9] ARM: dts: bcm2711: fix MDIO #address- and #size-cells
In-Reply-To: <1627820932-7247-3-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
 <1627820932-7247-3-git-send-email-stefan.wahren@i2se.com>
Message-ID: <4ebd90ac-2845-2ad8-5f77-6ec44cbfc6b7@gmail.com>



On 8/1/2021 5:28 AM, Stefan Wahren wrote:
> The values of #address-cells and #size-cells are swapped. Fix this
> and avoid the following DT schema warnings for mdio at e14:
> 
>   #address-cells:0:0: 1 was expected
>   #size-cells:0:0: 0 was expected
> 
> Fixes: be8af7a9e3cc ("ARM: dts: bcm2711-rpi-4: Enable GENET support")
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>

Yes this was definitively an error thanks!

> ---
>   arch/arm/boot/dts/bcm2711.dtsi | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
> index afe0ef8..55022fc 100644
> --- a/arch/arm/boot/dts/bcm2711.dtsi
> +++ b/arch/arm/boot/dts/bcm2711.dtsi
> @@ -532,8 +532,8 @@
>   				compatible = "brcm,genet-mdio-v5";
>   				reg = <0xe14 0x8>;
>   				reg-names = "mdio";
> -				#address-cells = <0x0>;
> -				#size-cells = <0x1>;
> +				#address-cells = <0x1>;
> +				#size-cells = <0x0>;
>   			};
>   		};
>   	};
> 

-- 
Florian


From linus.walleij at linaro.org  Thu Aug  5 02:08:51 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 5 Aug 2021 11:08:51 +0200
Subject: [PATCH v4 1/3] dt-bindings: display: panel: Add ilitek ili9341
 panel bindings
In-Reply-To: <1627098243-2742-2-git-send-email-dillon.minfei@gmail.com>
References: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
 <1627098243-2742-2-git-send-email-dillon.minfei@gmail.com>
Message-ID: <CACRpkdYEWDKrcUGcnDLKrx7+cGH4BvKLC0du1wYpkXTiJwn8_g@mail.gmail.com>

On Sat, Jul 24, 2021 at 5:44 AM <dillon.minfei at gmail.com> wrote:

> From: Dillon Min <dillon.minfei at gmail.com>
>
> Add documentation for "ilitek,ili9341" panel.
>
> Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Link: https://lore.kernel.org/lkml/1626853288-31223-2-git-send-email-dillon.minfei at gmail.com/

Patch applied to drm-misc-next.

Thanks for working on this!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Thu Aug  5 02:10:33 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 5 Aug 2021 11:10:33 +0200
Subject: [PATCH v4 3/3] drm/panel: Add ilitek ili9341 panel driver
In-Reply-To: <1627098243-2742-4-git-send-email-dillon.minfei@gmail.com>
References: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
 <1627098243-2742-4-git-send-email-dillon.minfei@gmail.com>
Message-ID: <CACRpkdYzrpHgDCW2UXNnFk-NpC_yM5xeSe_jBDJMGa6==5SHXw@mail.gmail.com>

On Sat, Jul 24, 2021 at 5:44 AM <dillon.minfei at gmail.com> wrote:

> From: Dillon Min <dillon.minfei at gmail.com>
>
> This driver combines tiny/ili9341.c mipi_dbi_interface driver
> with mipi_dpi_interface driver, can support ili9341 with serial
> mode and parallel rgb interface mode by different dts bindings.
>
> Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
> Reported-by: kernel test robot <lkp at intel.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>
> ---
> v4:
> - fix m68k-allmodconfig build error which reported by lkp, thanks.
> - add Copyright 2018 David Lechner <david at lechnology.com>.

Patch applied to drm-misc-next

Thanks for working on this driver!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Thu Aug  5 02:11:31 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 5 Aug 2021 11:11:31 +0200
Subject: [PATCH v4 2/3] ARM: dts: stm32: fix dtbs_check warning on ili9341
 dts binding
In-Reply-To: <1627098243-2742-3-git-send-email-dillon.minfei@gmail.com>
References: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
 <1627098243-2742-3-git-send-email-dillon.minfei@gmail.com>
Message-ID: <CACRpkdYReUdg_7oSTqcsA_+9tS9w6MH90=KV1rGyr4YWT=NW-w@mail.gmail.com>

On Sat, Jul 24, 2021 at 5:44 AM <dillon.minfei at gmail.com> wrote:

> From: Dillon Min <dillon.minfei at gmail.com>
>
> Since the compatible string defined from ilitek,ili9341.yaml is
> "st,sf-tc240t-9370-t", "ilitek,ili9341"
>
> so, append "ilitek,ili9341" to avoid the below dtbs_check warning.
>
> arch/arm/boot/dts/stm32f429-disco.dt.yaml: display at 1: compatible:
> ['st,sf-tc240t-9370-t'] is too short
>
> Fixes: a726e2f000ec ("ARM: dts: stm32: enable ltdc binding with ili9341, gyro l3gd20 on stm32429-disco board")
> Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
> Reported-by: kernel test robot <lkp at intel.com>
> ---
> v4: no change.

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Please funnel this patch through the STM and ARM SoC tree.

Yours,
Linus Walleij


From aisheng.dong at nxp.com  Thu Aug  5 02:12:17 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 17:12:17 +0800
Subject: [PATCH 1/2] arm64: dts: imx8mq: add remoteproc m4 support
Message-ID: <20210805091218.1626290-1-aisheng.dong@nxp.com>

Add cm4 remoteproc which supports rpmsg naming service.
It needs vdevbuffer and a pair of vrings and 16MB reserved memory.

Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  1 +
 .../boot/dts/freescale/imx8mq-evk-rpmsg.dts   | 72 +++++++++++++++++++
 2 files changed, 73 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq-evk-rpmsg.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 4b4785d86324..687ad9d68a85 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -49,6 +49,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mn-var-som-symphony.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk-rpmsg.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-hummingboard-pulse.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-kontron-pitx-imx8m.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-devkit.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk-rpmsg.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk-rpmsg.dts
new file mode 100644
index 000000000000..4a8911087e5f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk-rpmsg.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2019-2021 NXP
+ */
+
+#include "imx8mq-evk.dts"
+
+/ {
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		vdev0vring0: vdev0vring0 at b8000000 {
+			reg = <0 0xb8000000 0 0x8000>;
+			no-map;
+		};
+
+		vdev0vring1: vdev0vring1 at b8008000 {
+			reg = <0 0xb8008000 0 0x8000>;
+			no-map;
+		};
+
+		rsc_table: rsc-table at b80ff000 {
+			reg = <0 0xb80ff000 0 0x1000>;
+			no-map;
+		};
+
+		vdevbuffer: vdevbuffer at b8400000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0xb8400000 0 0x100000>;
+			no-map;
+		};
+
+		remoteproc at 80000000 {
+			reg = <0 0x80000000 0 0x1000000>;
+			no-map;
+		};
+	};
+
+	imx8mq-cm4 {
+		compatible = "fsl,imx8mq-cm4";
+		clocks = <&clk IMX8MQ_CLK_M4_DIV>;
+		mbox-names = "tx", "rx", "rxdb";
+		mboxes = <&mu 0 1
+			  &mu 1 1
+			  &mu 3 1>;
+		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
+				<&rsc_table>;
+		syscon = <&src>;
+	};
+};
+
+/*
+ * Below devices are allocated on remoteproc
+ */
+
+&i2c2 {
+	status = "disabled";
+};
+
+&pwm4 {
+	status = "disabled";
+};
+
+&tmu {
+	status = "disabled";
+};
+
+&uart2 {
+	status = "disabled";
+};
-- 
2.25.1



From aisheng.dong at nxp.com  Thu Aug  5 02:12:18 2021
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Thu,  5 Aug 2021 17:12:18 +0800
Subject: [PATCH 2/2] arm64: dts: imx8mp: add remoteproc m7 support
In-Reply-To: <20210805091218.1626290-1-aisheng.dong@nxp.com>
References: <20210805091218.1626290-1-aisheng.dong@nxp.com>
Message-ID: <20210805091218.1626290-2-aisheng.dong@nxp.com>

Add cm7 remoteproc which supports rpmsg naming service.
It needs vdevbuffer and a pair of vrings and 16MB reserved memory.

Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  1 +
 .../boot/dts/freescale/imx8mp-evk-rpmsg.dts   | 78 +++++++++++++++++++
 2 files changed, 79 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mp-evk-rpmsg.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 687ad9d68a85..e5f4d5779afe 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -47,6 +47,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mn-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-ddr4-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-var-som-symphony.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk-rpmsg.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk-rpmsg.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk-rpmsg.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk-rpmsg.dts
new file mode 100644
index 000000000000..35c0a8d5501e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk-rpmsg.dts
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include "imx8mp-evk.dts"
+
+/ {
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		vdev0vring0: vdev0vring0 at 55000000 {
+			reg = <0 0x55000000 0 0x8000>;
+			no-map;
+		};
+
+		vdev0vring1: vdev0vring1 at 55008000 {
+			reg = <0 0x55008000 0 0x8000>;
+			no-map;
+		};
+
+		rsc_table: rsc-table at 550ff000 {
+			reg = <0 0x550ff000 0 0x1000>;
+			no-map;
+		};
+
+		vdevbuffer: vdevbuffer at 55400000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x55400000 0 0x100000>;
+			no-map;
+		};
+
+		remoteproc at 80000000 {
+			reg = <0 0x80000000 0 0x1000000>;
+			no-map;
+		};
+	};
+
+	imx8mp-cm7 {
+		compatible = "fsl,imx8mp-cm7";
+		clocks = <&clk IMX8MP_CLK_M7_DIV>;
+		mbox-names = "tx", "rx", "rxdb";
+		mboxes = <&mu 0 1
+			  &mu 1 1
+			  &mu 3 1>;
+		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
+				<&rsc_table>;
+	};
+};
+
+/*
+ * Below devices are allocated on remoteproc
+ */
+&ecspi2 {
+	status = "disabled";
+};
+
+&flexcan1 {
+	status = "disabled";
+};
+
+&flexspi {
+	status = "disabled";
+};
+
+&i2c3 {
+	status = "disabled";
+};
+
+&pwm4 {
+	status = "disabled";
+};
+
+&uart4 {
+	status = "disabled";
+};
-- 
2.25.1



From yoshihiro.shimoda.uh at renesas.com  Thu Aug  5 02:15:15 2021
From: yoshihiro.shimoda.uh at renesas.com (Yoshihiro Shimoda)
Date: Thu, 5 Aug 2021 09:15:15 +0000
Subject: [PATCH v3 01/25] iommu: Pull IOVA cookie management into the core
In-Reply-To: <46f4cda8215bd5f8a9f9fd5a4a6451805f75efa3.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <46f4cda8215bd5f8a9f9fd5a4a6451805f75efa3.1628094600.git.robin.murphy@arm.com>
Message-ID: <TY2PR01MB36926E2F76FDEFD87564C3B3D8F29@TY2PR01MB3692.jpnprd01.prod.outlook.com>

Hi Robin,

> From: Robin Murphy, Sent: Thursday, August 5, 2021 2:15 AM
> 
> Now that everyone has converged on iommu-dma for IOMMU_DOMAIN_DMA
> support, we can abandon the notion of drivers being responsible for the
> cookie type, and consolidate all the management into the core code.
> 
> CC: Marek Szyprowski <m.szyprowski at samsung.com>
> CC: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
> CC: Geert Uytterhoeven <geert+renesas at glider.be>
> CC: Yong Wu <yong.wu at mediatek.com>
> CC: Heiko Stuebner <heiko at sntech.de>
> CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
> CC: Maxime Ripard <mripard at kernel.org>
> Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Thank you for the patch!
I tested on my environment (r8a77951-salvator-xs),
and I didn't observe any regression. So,

Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>

Best regards,
Yoshihiro Shimoda



From yoshihiro.shimoda.uh at renesas.com  Thu Aug  5 02:15:20 2021
From: yoshihiro.shimoda.uh at renesas.com (Yoshihiro Shimoda)
Date: Thu, 5 Aug 2021 09:15:20 +0000
Subject: [PATCH v3 06/25] iommu/ipmmu-vmsa: Drop IOVA cookie management
In-Reply-To: <b154a2f088699b739d8c4823c458bf5fc0aac2bc.1628094601.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <b154a2f088699b739d8c4823c458bf5fc0aac2bc.1628094601.git.robin.murphy@arm.com>
Message-ID: <TY2PR01MB36924CFFCC20B9E3CC7BB594D8F29@TY2PR01MB3692.jpnprd01.prod.outlook.com>

Hi Robin,

> From: Robin Murphy, Sent: Thursday, August 5, 2021 2:16 AM
> 
> The core code bakes its own cookies now.
> 
> CC: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
> CC: Geert Uytterhoeven <geert+renesas at glider.be>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Thank you for the patch!
I tested on my environment (r8a77951-salvator-xs),
and I didn't observe any regression. So,

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>

Best regards,
Yoshihiro Shimoda



From tsbogend at alpha.franken.de  Thu Aug  5 02:12:18 2021
From: tsbogend at alpha.franken.de (Thomas Bogendoerfer)
Date: Thu, 5 Aug 2021 11:12:18 +0200
Subject: [PATCH v2] arch: vdso: remove if-conditionals of
 $(c-gettimeofday-y)
In-Reply-To: <20210731060020.12913-1-masahiroy@kernel.org>
References: <20210731060020.12913-1-masahiroy@kernel.org>
Message-ID: <20210805091218.GD5979@alpha.franken.de>

On Sat, Jul 31, 2021 at 03:00:20PM +0900, Masahiro Yamada wrote:
> arm, arm64, csky, mips, powerpc always select GENERIC_GETTIMEOFDAY,
> hence $(gettimeofday-y) never becomes empty.
> 
> riscv conditionally selects GENERIC_GETTIMEOFDAY when MMU=y && 64BIT=y,
> but arch/riscv/kernel/vdso/vgettimeofday.o is built only under that
> condition. So, you can always define CFLAGS_vgettimeofday.o
> 
> Remove all the meaningless conditionals.
> 
> Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> ---
> 
> Changes in v2:
>   - Fix csky as well
> 
>  [..]
>  arch/mips/vdso/Makefile             |  2 --

Acked-by: Thomas Bogendoerfer <tsbogend at alpha.franken.de>

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]


From f.fainelli at gmail.com  Thu Aug  5 02:18:11 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 5 Aug 2021 02:18:11 -0700
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <20210805074615.29096-2-qiangqing.zhang@nxp.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
Message-ID: <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>



On 8/5/2021 12:46 AM, Joakim Zhang wrote:
> Add "fsl,wakeup-irq" property for FEC controller to select wakeup irq
> source.
> 
> Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
> Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>

Why are not you making use of the standard interrupts-extended property 
which allows different interrupt lines to be originating from different 
interrupt controllers, e.g.:

interrupts-extended = <&gic GIC_SPI 112 4>, <&wakeup_intc 0>;
-- 
Florian


From dillon.minfei at gmail.com  Thu Aug  5 02:19:41 2021
From: dillon.minfei at gmail.com (Dillon Min)
Date: Thu, 5 Aug 2021 17:19:41 +0800
Subject: [PATCH v4 2/3] ARM: dts: stm32: fix dtbs_check warning on ili9341
 dts binding
In-Reply-To: <CACRpkdYReUdg_7oSTqcsA_+9tS9w6MH90=KV1rGyr4YWT=NW-w@mail.gmail.com>
References: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
 <1627098243-2742-3-git-send-email-dillon.minfei@gmail.com>
 <CACRpkdYReUdg_7oSTqcsA_+9tS9w6MH90=KV1rGyr4YWT=NW-w@mail.gmail.com>
Message-ID: <CAL9mu0LfcLS1iNQnamxA_oTrxu8eEBpUm+u92V2d9-8qz6hvow@mail.gmail.com>

Hi Linus

Thanks.

On Thu, 5 Aug 2021 at 17:11, Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Sat, Jul 24, 2021 at 5:44 AM <dillon.minfei at gmail.com> wrote:
>
> > From: Dillon Min <dillon.minfei at gmail.com>
> >
> > Since the compatible string defined from ilitek,ili9341.yaml is
> > "st,sf-tc240t-9370-t", "ilitek,ili9341"
> >
> > so, append "ilitek,ili9341" to avoid the below dtbs_check warning.
> >
> > arch/arm/boot/dts/stm32f429-disco.dt.yaml: display at 1: compatible:
> > ['st,sf-tc240t-9370-t'] is too short
> >
> > Fixes: a726e2f000ec ("ARM: dts: stm32: enable ltdc binding with ili9341, gyro l3gd20 on stm32429-disco board")
> > Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
> > Reported-by: kernel test robot <lkp at intel.com>
> > ---
> > v4: no change.
>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>
> Please funnel this patch through the STM and ARM SoC tree.

Sure, I will let Alex know. Thanks for your help on this driver.

Hi Alex,
Should I send v5 with Linus's Reviewed-by tag on this patch? thanks.

Best Regards
Dillon

>
> Yours,
> Linus Walleij


From liuqi115 at huawei.com  Thu Aug  5 02:25:17 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Thu, 5 Aug 2021 17:25:17 +0800
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210805105401.4acd3217c566b4e3933f355c@kernel.org>
References: <20210804060209.95817-1-liuqi115@huawei.com>
 <20210805105401.4acd3217c566b4e3933f355c@kernel.org>
Message-ID: <d3e0c9ee-19b5-8042-d251-05348e8ac49e@huawei.com>


Hi Masami,

On 2021/8/5 9:54, Masami Hiramatsu wrote:
> On Wed, 4 Aug 2021 14:02:09 +0800
> Qi Liu <liuqi115 at huawei.com> wrote:
> 
>> This patch introduce optprobe for ARM64. In optprobe, probed
>> instruction is replaced by a branch instruction to detour
>> buffer. Detour buffer contains trampoline code and a call to
>> optimized_callback(). optimized_callback() calls opt_pre_handler()
>> to execute kprobe handler.
>>
>> Limitations:
>> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
>> guarantee the offset between probe point and kprobe pre_handler
>> is not larger than 128MiB.
>>
>> Performance of optprobe on Hip08 platform is test using kprobe
>> example module[1] to analyze the latency of a kernel function,
>> and here is the result:
>>
>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
>>
>> kprobe before optimized:
>> [280709.846380] do_empty returned 0 and took 1530 ns to execute
>> [280709.852057] do_empty returned 0 and took 550 ns to execute
>> [280709.857631] do_empty returned 0 and took 440 ns to execute
>> [280709.863215] do_empty returned 0 and took 380 ns to execute
>> [280709.868787] do_empty returned 0 and took 360 ns to execute
>> [280709.874362] do_empty returned 0 and took 340 ns to execute
>> [280709.879936] do_empty returned 0 and took 320 ns to execute
>> [280709.885505] do_empty returned 0 and took 300 ns to execute
>> [280709.891075] do_empty returned 0 and took 280 ns to execute
>> [280709.896646] do_empty returned 0 and took 290 ns to execute
>> [280709.902220] do_empty returned 0 and took 290 ns to execute
>> [280709.907807] do_empty returned 0 and took 290 ns to execute
>>
>> optprobe:
>> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
>> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
>> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
>> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
>> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
>> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
>> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
>> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
>> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
>> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
>> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
>> [ 2966.023779] do_empty returned 0 and took 70 ns to execute
>> [ 2966.029158] do_empty returned 0 and took 70 ns to execute
>>
>> Signed-off-by: Qi Liu <liuqi115 at huawei.com>
>>
>> ---
>>
>> Changes since V1:
>> - Address the comments from Masami, checks for all branch instructions, and
>> use aarch64_insn_patch_text_nosync() instead of aarch64_insn_patch_text()
>> in each probe.
> 
> Is it safe for the multicore system? If it is safe because it modifies
> just one instruction (modifying 32bit in atomic), I understand it.

Seems raw_spin_lock_irqsave is used in aarch64_insn_patch_text_nosync() 
and spinlock could support a protection in multicore system.
> BTW, anyway, you should use _nosync() variant in arch_prepare_optimized_kprobe()
> too, beacause the optprobe insn buffer is not touched until the probed instruction
> is optimized by br.
> 
Yes, sounds resonable.
> [...]
>> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
>> +{
>> +	kprobe_opcode_t *code;
>> +	u32 insn;
>> +	int ret, i;
>> +	void *addrs[TMPL_END_IDX];
>> +	void *addr;
>> +
>> +	code = get_optinsn_slot();
>> +	if (!code)
>> +		return -ENOMEM;
>> +
>> +	if (!is_offset_in_range((unsigned long)code,
>> +				(unsigned long)orig->addr + 8))
>> +		goto error;
>> +
>> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
>> +				(unsigned long)optimized_callback))
>> +		goto error;
>> +
>> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
>> +				(unsigned long)op->kp.addr + 4))
>> +		goto error;
>> +
>> +	/* Setup template */
>> +	for (i = 0; i < TMPL_END_IDX; i++)
>> +		addrs[i] = code + i;
>> +
>> +	ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
>> +				      TMPL_END_IDX);
> 
> You should use aarch64_insn_patch_text_nosync() here (and all the
> aarch64_insn_patch_text() in this function too), because the insn
> buffer must not executed until the probe point is optimized.
> 
aarch64_insn_patch_text() could patch multi instructions to code[] each 
time and aarch64_insn_patch_text_nosync() could only patch one 
instruction each time, so maybe aarch64_insn_patch_text() is better here.

I'll replace other aarch64_insn_patch_text() in this function.

Thanks,
Qi

>> +	if (ret < 0)
>> +		goto error;
>> +
>> +	/* Set probe information */
>> +	addr = code + TMPL_VAL_IDX;
>> +	insn =  (unsigned long long)op & 0xffffffff;
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	addr = addr + 4;
>> +	insn = ((unsigned long long)op & GENMASK_ULL(63, 32)) >> 32;
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	addr = code + TMPL_CALL_BACK;
>> +	insn =  aarch64_insn_gen_branch_imm((unsigned long)addr,
>> +				(unsigned long)optimized_callback,
>> +				AARCH64_INSN_BRANCH_LINK);
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	/* The original probed instruction */
>> +	addr = code + TMPL_RESTORE_ORIGN_INSN;
>> +	insn =  orig->opcode;
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	/* Jump back to next instruction */
>> +	addr = code + TMPL_RESTORE_END;
>> +	insn = aarch64_insn_gen_branch_imm(
>> +				(unsigned long)(&code[TMPL_RESTORE_END]),
>> +				(unsigned long)(op->kp.addr) + 4,
>> +				AARCH64_INSN_BRANCH_NOLINK);
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	flush_icache_range((unsigned long)code,
>> +			   (unsigned long)(&code[TMPL_END_IDX]));
>> +	/* Set op->optinsn.insn means prepared. */
>> +	op->optinsn.insn = code;
>> +
>> +	return 0;
> 
> Thank you,
> 
> 
> 



From alim.akhtar at samsung.com  Thu Aug  5 02:26:14 2021
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 5 Aug 2021 14:56:14 +0530
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <b0d6ff2a-24af-96c1-62a1-8b920c63e05a@canonical.com>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
 <CGME20210805073653epcas5p21b4c2358b7de2b3c21dbc357af957137@epcas5p2.samsung.com>
 <b0d6ff2a-24af-96c1-62a1-8b920c63e05a@canonical.com>
Message-ID: <03d701d789db$f275d290$d76177b0$@samsung.com>

Hi Krzysztof,

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Sent: 05 August 2021 13:07
> To: Rob Herring <robh+dt at kernel.org>; devicetree at vger.kernel.org; linux-
> arm-kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
> kernel at vger.kernel.org
> Cc: Alim Akhtar <alim.akhtar at samsung.com>; Chanwoo Choi
> <cw00.choi at samsung.com>; Pankaj Dubey <pankaj.dubey at samsung.com>;
> Sam Protsenko <semen.protsenko at linaro.org>; Marc Zyngier
> <maz at kernel.org>
> Subject: Re: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
> range on Exynos7
> 
> On 05/08/2021 09:21, Krzysztof Kozlowski wrote:
> > The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF
> > (by ARM).
> >
> 
Looking at DDI0471B_gic400_r0p1_trm.pdf, CPU interface range is 0x0000 ~ 0x10000

> I underestimated the issue - this is actually bug as there is a GICC_DIR
> register at offset 0x1000. Therefore:
> 
Looking at the exynos7 and exynos5433 UMs looks like GICC_DIR is at offset 0x2100 (from 0x1100_0000 GIC base)
It is possible for you to cross check once?

> Fixes: b9024cbc937d ("arm64: dts: Add initial device tree support for
> exynos7")
> 
> > Reported-by: Sam Protsenko <semen.protsenko at linaro.org>
> > Reported-by: Marc Zyngier <maz at kernel.org>
> > Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > ---
> >  arch/arm64/boot/dts/exynos/exynos7.dtsi | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > index 8b06397ba6e7..c73a597ca66e 100644
> > --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > @@ -137,7 +137,7 @@ gic: interrupt-controller at 11001000 {
> >  			#address-cells = <0>;
> >  			interrupt-controller;
> >  			reg =	<0x11001000 0x1000>,
> > -				<0x11002000 0x1000>,
> > +				<0x11002000 0x2000>,
> >  				<0x11004000 0x2000>,
> >  				<0x11006000 0x2000>;
> >  		};
> >
> 
> 
> Best regards,
> Krzysztof



From peng.fan at oss.nxp.com  Thu Aug  5 02:35:21 2021
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 5 Aug 2021 09:35:21 +0000
Subject: [PATCH v2 00/18] i.MX8MM GPC improvements and BLK_CTRL driver
In-Reply-To: <20210721204703.1424034-1-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB27565479FD5C0FF9414F5EF788F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 00/18] i.MX8MM GPC improvements and BLK_CTRL driver
> 
> Hi all,
> 
> second revision of the GPC improvements and BLK_CTRL driver to make use
> of all the power-domains on the i.MX8MM. I'm not going to repeat the full
> blurb from the v1 cover letter here, but if you are not familiar with i.MX8MM
> power domains, it may be worth a read.
> 
> This 2nd revision fixes the DT bindings to be valid yaml, some small failure
> path issues and most importantly the interaction with system
> suspend/resume. With the previous version some of the power domains
> would not come up correctly after a suspend/resume cycle.

Thanks for the work. I gave a test, boot and suspend/resume work with display.

Tested-by: Peng Fan <peng.fan at nxp.com>

> 
> Updated testing git trees here, disclaimer still applies:
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.pen
> gutronix.de%2Fcgit%2Flst%2Flinux%2Flog%2F%3Fh%3Dimx8m-power-domai
> ns&amp;data=04%7C01%7Cpeng.fan%40nxp.com%7C3ef1698b8c53454da41
> 808d94c88b577%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63
> 7624972323848567%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMD
> AiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata
> =PbhVVIqDcUMtMmurwpp2PoSYaAzXgRKVvBccd%2BL26oc%3D&amp;reserv
> ed=0
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.pen
> gutronix.de%2Fcgit%2Flst%2Flinux%2Flog%2F%3Fh%3Dimx8m-power-domai
> ns-testing&amp;data=04%7C01%7Cpeng.fan%40nxp.com%7C3ef1698b8c534
> 54da41808d94c88b577%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C
> 0%7C637624972323848567%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4w
> LjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&a
> mp;sdata=rAuBbsQ5%2FpZJhuocWmapgNwERxat0IQsRfBiQpeJzuk%3D&amp;
> reserved=0
> 
> Regards,
> Lucas
> 
> Frieder Schrempf (1):
>   arm64: dts: imx8mm: Add GPU nodes for 2D and 3D core
> 
> Lucas Stach (15):
>   Revert "soc: imx: gpcv2: move reset assert after requesting domain
>     power up"
>   soc: imx: gpcv2: add lockdep annotation
>   soc: imx: gpcv2: add domain option to keep domain clocks enabled
>   soc: imx: gpcv2: keep i.MX8M* bus clocks enabled
>   soc: imx: gpcv2: support system suspend/resume
>   dt-bindings: soc: add binding for i.MX8MM VPU blk-ctrl
>   dt-bindings: power: imx8mm: add defines for VPU blk-ctrl domains
>   soc: imx: add i.MX8M blk-ctrl driver
>   dt-bindings: soc: add binding for i.MX8MM DISP blk-ctrl
>   dt-bindings: power: imx8mm: add defines for DISP blk-ctrl domains
>   soc: imx: imx8m-blk-ctrl: add DISP blk-ctrl
>   arm64: dts: imx8mm: add GPC node
>   arm64: dts: imx8mm: put USB controllers into power-domains
>   arm64: dts: imx8mm: add VPU blk-ctrl
>   arm64: dts: imx8mm: add DISP blk-ctrl
> 
> Marek Vasut (2):
>   soc: imx: gpcv2: Turn domain->pgc into bitfield
>   soc: imx: gpcv2: Set both GPC_PGC_nCTRL(GPU_2D|GPU_3D) for MX8MM
> GPU
>     domain
> 
>  .../soc/imx/fsl,imx8mm-disp-blk-ctrl.yaml     |  94 ++++
>  .../soc/imx/fsl,imx8mm-vpu-blk-ctrl.yaml      |  76 +++
>  arch/arm64/boot/dts/freescale/imx8mm.dtsi     | 180 ++++++
>  drivers/soc/imx/Makefile                      |   1 +
>  drivers/soc/imx/gpcv2.c                       | 130 +++--
>  drivers/soc/imx/imx8m-blk-ctrl.c              | 525
> ++++++++++++++++++
>  include/dt-bindings/power/imx8mm-power.h      |   9 +
>  7 files changed, 974 insertions(+), 41 deletions(-)  create mode 100644
> Documentation/devicetree/bindings/soc/imx/fsl,imx8mm-disp-blk-ctrl.yaml
>  create mode 100644
> Documentation/devicetree/bindings/soc/imx/fsl,imx8mm-vpu-blk-ctrl.yaml
>  create mode 100644 drivers/soc/imx/imx8m-blk-ctrl.c
> 
> --
> 2.30.2



From peng.fan at nxp.com  Thu Aug  5 02:37:05 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:37:05 +0000
Subject: [PATCH v2 01/18] Revert "soc: imx: gpcv2: move reset assert after
 requesting domain power up"
In-Reply-To: <20210721204703.1424034-2-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-2-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB27561A52BED707E2E3F2758488F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 01/18] Revert "soc: imx: gpcv2: move reset assert after
> requesting domain power up"
> 
> This reverts commit a77ebdd9f553. It turns out that the VPU domain has no
> different requirements, even though the downstream ATF implementation
> seems to suggest otherwise. Powering on the domain with the reset asserted
> works fine. As the changed sequence has caused sporadic issues with the GPU
> domains, just revert the change to go back to the working sequence.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Acked-by: Peng Fan <peng.fan at nxp.com>

> ---
>  drivers/soc/imx/gpcv2.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index
> 34a9ac1f2b9b..8b7a01773aec 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -244,6 +244,8 @@ static int imx_pgc_power_up(struct
> generic_pm_domain *genpd)
>  		goto out_regulator_disable;
>  	}
> 
> +	reset_control_assert(domain->reset);
> +
>  	if (domain->bits.pxx) {
>  		/* request the domain to power up */
>  		regmap_update_bits(domain->regmap,
> GPC_PU_PGC_SW_PUP_REQ, @@ -266,8 +268,6 @@ static int
> imx_pgc_power_up(struct generic_pm_domain *genpd)
>  				  GPC_PGC_CTRL_PCR);
>  	}
> 
> -	reset_control_assert(domain->reset);
> -
>  	/* delay for reset to propagate */
>  	udelay(5);
> 
> --
> 2.30.2



From peng.fan at nxp.com  Thu Aug  5 02:37:29 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:37:29 +0000
Subject: [PATCH v2 02/18] soc: imx: gpcv2: Turn domain->pgc into bitfield
In-Reply-To: <20210721204703.1424034-3-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-3-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB2756945BBA671843C1E561B688F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 02/18] soc: imx: gpcv2: Turn domain->pgc into bitfield
> 
> From: Marek Vasut <marex at denx.de>
> 
> There is currently the MX8MM GPU domain, which is in fact a composite
> domain for both GPU2D and GPU3D. To correctly configure this domain, it is
> necessary to control both GPC_PGC_nCTRL(GPU_2D) and
> GPC_PGC_nCTRL(GPU_3D) at the same time. This is currently not possible.
> 
> Turn the domain->pgc from value into bitfield and use for_each_set_bit() to
> iterate over all bits set in domain->pgc when configuring GPC_PGC_nCTRL
> register array. This way it is possible to configure all GPC_PGC_nCTRL registers
> required in a particular domain.
> 
> This is a preparatory patch, no functional change.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

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

> ---
> v2 (Lucas Stach):
> - rebase on top of reverted reset sequence change
> - also convert i.MX8MN domains
> ---
>  drivers/soc/imx/gpcv2.c | 72 ++++++++++++++++++++++-------------------
>  1 file changed, 38 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index
> 8b7a01773aec..c7826ce92f0d 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -192,7 +192,7 @@ struct imx_pgc_domain {
>  	struct clk_bulk_data *clks;
>  	int num_clks;
> 
> -	unsigned int pgc;
> +	unsigned long pgc;
> 
>  	const struct {
>  		u32 pxx;
> @@ -220,7 +220,7 @@ to_imx_pgc_domain(struct generic_pm_domain
> *genpd)  static int imx_pgc_power_up(struct generic_pm_domain *genpd)
> {
>  	struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd);
> -	u32 reg_val;
> +	u32 reg_val, pgc;
>  	int ret;
> 
>  	ret = pm_runtime_get_sync(domain->dev); @@ -264,8 +264,10 @@
> static int imx_pgc_power_up(struct generic_pm_domain *genpd)
>  		}
> 
>  		/* disable power control */
> -		regmap_clear_bits(domain->regmap,
> GPC_PGC_CTRL(domain->pgc),
> -				  GPC_PGC_CTRL_PCR);
> +		for_each_set_bit(pgc, &domain->pgc, 32) {
> +			regmap_clear_bits(domain->regmap, GPC_PGC_CTRL(pgc),
> +					  GPC_PGC_CTRL_PCR);
> +		}
>  	}
> 
>  	/* delay for reset to propagate */
> @@ -311,7 +313,7 @@ static int imx_pgc_power_up(struct
> generic_pm_domain *genpd)  static int imx_pgc_power_down(struct
> generic_pm_domain *genpd)  {
>  	struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd);
> -	u32 reg_val;
> +	u32 reg_val, pgc;
>  	int ret;
> 
>  	/* Enable reset clocks for all devices in the domain */ @@ -338,8
> +340,10 @@ static int imx_pgc_power_down(struct generic_pm_domain
> *genpd)
> 
>  	if (domain->bits.pxx) {
>  		/* enable power control */
> -		regmap_update_bits(domain->regmap,
> GPC_PGC_CTRL(domain->pgc),
> -				   GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
> +		for_each_set_bit(pgc, &domain->pgc, 32) {
> +			regmap_update_bits(domain->regmap, GPC_PGC_CTRL(pgc),
> +					   GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
> +		}
> 
>  		/* request the domain to power down */
>  		regmap_update_bits(domain->regmap,
> GPC_PU_PGC_SW_PDN_REQ, @@ -389,7 +393,7 @@ static const struct
> imx_pgc_domain imx7_pgc_domains[] = {
>  			.map = IMX7_MIPI_PHY_A_CORE_DOMAIN,
>  		},
>  		.voltage   = 1000000,
> -		.pgc	   = IMX7_PGC_MIPI,
> +		.pgc	   = BIT(IMX7_PGC_MIPI),
>  	},
> 
>  	[IMX7_POWER_DOMAIN_PCIE_PHY] = {
> @@ -401,7 +405,7 @@ static const struct imx_pgc_domain
> imx7_pgc_domains[] = {
>  			.map = IMX7_PCIE_PHY_A_CORE_DOMAIN,
>  		},
>  		.voltage   = 1000000,
> -		.pgc	   = IMX7_PGC_PCIE,
> +		.pgc	   = BIT(IMX7_PGC_PCIE),
>  	},
> 
>  	[IMX7_POWER_DOMAIN_USB_HSIC_PHY] = {
> @@ -413,7 +417,7 @@ static const struct imx_pgc_domain
> imx7_pgc_domains[] = {
>  			.map = IMX7_USB_HSIC_PHY_A_CORE_DOMAIN,
>  		},
>  		.voltage   = 1200000,
> -		.pgc	   = IMX7_PGC_USB_HSIC,
> +		.pgc	   = BIT(IMX7_PGC_USB_HSIC),
>  	},
>  };
> 
> @@ -448,7 +452,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.pxx = IMX8M_MIPI_SW_Pxx_REQ,
>  			.map = IMX8M_MIPI_A53_DOMAIN,
>  		},
> -		.pgc	   = IMX8M_PGC_MIPI,
> +		.pgc	   = BIT(IMX8M_PGC_MIPI),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_PCIE1] = {
> @@ -459,7 +463,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.pxx = IMX8M_PCIE1_SW_Pxx_REQ,
>  			.map = IMX8M_PCIE1_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8M_PGC_PCIE1,
> +		.pgc   = BIT(IMX8M_PGC_PCIE1),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_USB_OTG1] = {
> @@ -470,7 +474,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.pxx = IMX8M_OTG1_SW_Pxx_REQ,
>  			.map = IMX8M_OTG1_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8M_PGC_OTG1,
> +		.pgc   = BIT(IMX8M_PGC_OTG1),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_USB_OTG2] = {
> @@ -481,7 +485,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.pxx = IMX8M_OTG2_SW_Pxx_REQ,
>  			.map = IMX8M_OTG2_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8M_PGC_OTG2,
> +		.pgc   = BIT(IMX8M_PGC_OTG2),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_DDR1] = {
> @@ -492,7 +496,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.pxx = IMX8M_DDR1_SW_Pxx_REQ,
>  			.map = IMX8M_DDR2_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8M_PGC_DDR1,
> +		.pgc   = BIT(IMX8M_PGC_DDR1),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_GPU] = {
> @@ -505,7 +509,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.hskreq = IMX8M_GPU_HSK_PWRDNREQN,
>  			.hskack = IMX8M_GPU_HSK_PWRDNACKN,
>  		},
> -		.pgc   = IMX8M_PGC_GPU,
> +		.pgc   = BIT(IMX8M_PGC_GPU),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_VPU] = {
> @@ -518,7 +522,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.hskreq = IMX8M_VPU_HSK_PWRDNREQN,
>  			.hskack = IMX8M_VPU_HSK_PWRDNACKN,
>  		},
> -		.pgc   = IMX8M_PGC_VPU,
> +		.pgc   = BIT(IMX8M_PGC_VPU),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_DISP] = {
> @@ -531,7 +535,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.hskreq = IMX8M_DISP_HSK_PWRDNREQN,
>  			.hskack = IMX8M_DISP_HSK_PWRDNACKN,
>  		},
> -		.pgc   = IMX8M_PGC_DISP,
> +		.pgc   = BIT(IMX8M_PGC_DISP),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_MIPI_CSI1] = {
> @@ -542,7 +546,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.pxx = IMX8M_MIPI_CSI1_SW_Pxx_REQ,
>  			.map = IMX8M_MIPI_CSI1_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8M_PGC_MIPI_CSI1,
> +		.pgc   = BIT(IMX8M_PGC_MIPI_CSI1),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_MIPI_CSI2] = {
> @@ -553,7 +557,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.pxx = IMX8M_MIPI_CSI2_SW_Pxx_REQ,
>  			.map = IMX8M_MIPI_CSI2_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8M_PGC_MIPI_CSI2,
> +		.pgc   = BIT(IMX8M_PGC_MIPI_CSI2),
>  	},
> 
>  	[IMX8M_POWER_DOMAIN_PCIE2] = {
> @@ -564,7 +568,7 @@ static const struct imx_pgc_domain
> imx8m_pgc_domains[] = {
>  			.pxx = IMX8M_PCIE2_SW_Pxx_REQ,
>  			.map = IMX8M_PCIE2_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8M_PGC_PCIE2,
> +		.pgc   = BIT(IMX8M_PGC_PCIE2),
>  	},
>  };
> 
> @@ -627,7 +631,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.pxx = IMX8MM_PCIE_SW_Pxx_REQ,
>  			.map = IMX8MM_PCIE_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8MM_PGC_PCIE,
> +		.pgc   = BIT(IMX8MM_PGC_PCIE),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_OTG1] = {
> @@ -638,7 +642,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.pxx = IMX8MM_OTG1_SW_Pxx_REQ,
>  			.map = IMX8MM_OTG1_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8MM_PGC_OTG1,
> +		.pgc   = BIT(IMX8MM_PGC_OTG1),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_OTG2] = {
> @@ -649,7 +653,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.pxx = IMX8MM_OTG2_SW_Pxx_REQ,
>  			.map = IMX8MM_OTG2_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8MM_PGC_OTG2,
> +		.pgc   = BIT(IMX8MM_PGC_OTG2),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_GPUMIX] = {
> @@ -662,7 +666,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskreq = IMX8MM_GPUMIX_HSK_PWRDNREQN,
>  			.hskack = IMX8MM_GPUMIX_HSK_PWRDNACKN,
>  		},
> -		.pgc   = IMX8MM_PGC_GPUMIX,
> +		.pgc   = BIT(IMX8MM_PGC_GPUMIX),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_GPU] = {
> @@ -675,7 +679,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskreq = IMX8MM_GPU_HSK_PWRDNREQN,
>  			.hskack = IMX8MM_GPU_HSK_PWRDNACKN,
>  		},
> -		.pgc   = IMX8MM_PGC_GPU2D,
> +		.pgc   = BIT(IMX8MM_PGC_GPU2D),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_VPUMIX] = {
> @@ -688,7 +692,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskreq = IMX8MM_VPUMIX_HSK_PWRDNREQN,
>  			.hskack = IMX8MM_VPUMIX_HSK_PWRDNACKN,
>  		},
> -		.pgc   = IMX8MM_PGC_VPUMIX,
> +		.pgc   = BIT(IMX8MM_PGC_VPUMIX),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_VPUG1] = {
> @@ -699,7 +703,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.pxx = IMX8MM_VPUG1_SW_Pxx_REQ,
>  			.map = IMX8MM_VPUG1_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8MM_PGC_VPUG1,
> +		.pgc   = BIT(IMX8MM_PGC_VPUG1),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_VPUG2] = {
> @@ -710,7 +714,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.pxx = IMX8MM_VPUG2_SW_Pxx_REQ,
>  			.map = IMX8MM_VPUG2_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8MM_PGC_VPUG2,
> +		.pgc   = BIT(IMX8MM_PGC_VPUG2),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_VPUH1] = {
> @@ -721,7 +725,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.pxx = IMX8MM_VPUH1_SW_Pxx_REQ,
>  			.map = IMX8MM_VPUH1_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8MM_PGC_VPUH1,
> +		.pgc   = BIT(IMX8MM_PGC_VPUH1),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_DISPMIX] = {
> @@ -734,7 +738,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskreq = IMX8MM_DISPMIX_HSK_PWRDNREQN,
>  			.hskack = IMX8MM_DISPMIX_HSK_PWRDNACKN,
>  		},
> -		.pgc   = IMX8MM_PGC_DISPMIX,
> +		.pgc   = BIT(IMX8MM_PGC_DISPMIX),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_MIPI] = {
> @@ -745,7 +749,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.pxx = IMX8MM_MIPI_SW_Pxx_REQ,
>  			.map = IMX8MM_MIPI_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8MM_PGC_MIPI,
> +		.pgc   = BIT(IMX8MM_PGC_MIPI),
>  	},
>  };
> 
> @@ -812,7 +816,7 @@ static const struct imx_pgc_domain
> imx8mn_pgc_domains[] = {
>  			.pxx = IMX8MN_OTG1_SW_Pxx_REQ,
>  			.map = IMX8MN_OTG1_A53_DOMAIN,
>  		},
> -		.pgc   = IMX8MN_PGC_OTG1,
> +		.pgc   = BIT(IMX8MN_PGC_OTG1),
>  	},
> 
>  	[IMX8MN_POWER_DOMAIN_GPUMIX] = {
> @@ -825,7 +829,7 @@ static const struct imx_pgc_domain
> imx8mn_pgc_domains[] = {
>  			.hskreq = IMX8MN_GPUMIX_HSK_PWRDNREQN,
>  			.hskack = IMX8MN_GPUMIX_HSK_PWRDNACKN,
>  		},
> -		.pgc   = IMX8MN_PGC_GPUMIX,
> +		.pgc   = BIT(IMX8MN_PGC_GPUMIX),
>  	},
>  };
> 
> --
> 2.30.2



From peng.fan at nxp.com  Thu Aug  5 02:37:43 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:37:43 +0000
Subject: [PATCH v2 03/18] soc: imx: gpcv2: Set both
 GPC_PGC_nCTRL(GPU_2D|GPU_3D) for MX8MM GPU domain
In-Reply-To: <20210721204703.1424034-4-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-4-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB2756697B31528A9FFF21628E88F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> GPC_PGC_nCTRL(GPU_2D|GPU_3D) for MX8MM GPU domain
> 
> From: Marek Vasut <marex at denx.de>
> 
> To bring up the MX8MM GPU domain, it is necessary to configure both
> GPC_PGC_nCTRL(GPU_2D) and GPC_PGC_nCTRL(GPU_3D) registers. Without
> this configuration, the system might hang on boot when bringing up the GPU
> power domain. This is sporadically observed on multiple disparate systems.
> 
> Add the GPU3D bit into MX8MM GPU domain pgc bitfield, so that both
> GPC_PGC_nCTRL(GPU_2D) and GPC_PGC_nCTRL(GPU_3D) registers are
> configured when bringing up the GPU domain. This fixes the sporadic hang.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

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

> ---
>  drivers/soc/imx/gpcv2.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index
> c7826ce92f0d..2c43e74db0be 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -679,7 +679,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskreq = IMX8MM_GPU_HSK_PWRDNREQN,
>  			.hskack = IMX8MM_GPU_HSK_PWRDNACKN,
>  		},
> -		.pgc   = BIT(IMX8MM_PGC_GPU2D),
> +		.pgc   = BIT(IMX8MM_PGC_GPU2D) |
> BIT(IMX8MM_PGC_GPU3D),
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_VPUMIX] = {
> --
> 2.30.2



From alexandre.torgue at foss.st.com  Thu Aug  5 02:37:16 2021
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Thu, 5 Aug 2021 11:37:16 +0200
Subject: [PATCH v4 2/3] ARM: dts: stm32: fix dtbs_check warning on ili9341
 dts binding
In-Reply-To: <CAL9mu0LfcLS1iNQnamxA_oTrxu8eEBpUm+u92V2d9-8qz6hvow@mail.gmail.com>
References: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
 <1627098243-2742-3-git-send-email-dillon.minfei@gmail.com>
 <CACRpkdYReUdg_7oSTqcsA_+9tS9w6MH90=KV1rGyr4YWT=NW-w@mail.gmail.com>
 <CAL9mu0LfcLS1iNQnamxA_oTrxu8eEBpUm+u92V2d9-8qz6hvow@mail.gmail.com>
Message-ID: <ecffd445-7f18-518f-2093-19e393588c1e@foss.st.com>

Hi Dillon

On 8/5/21 11:19 AM, Dillon Min wrote:
> Hi Linus
> 
> Thanks.
> 
> On Thu, 5 Aug 2021 at 17:11, Linus Walleij <linus.walleij at linaro.org> wrote:
>>
>> On Sat, Jul 24, 2021 at 5:44 AM <dillon.minfei at gmail.com> wrote:
>>
>>> From: Dillon Min <dillon.minfei at gmail.com>
>>>
>>> Since the compatible string defined from ilitek,ili9341.yaml is
>>> "st,sf-tc240t-9370-t", "ilitek,ili9341"
>>>
>>> so, append "ilitek,ili9341" to avoid the below dtbs_check warning.
>>>
>>> arch/arm/boot/dts/stm32f429-disco.dt.yaml: display at 1: compatible:
>>> ['st,sf-tc240t-9370-t'] is too short
>>>
>>> Fixes: a726e2f000ec ("ARM: dts: stm32: enable ltdc binding with ili9341, gyro l3gd20 on stm32429-disco board")
>>> Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
>>> Reported-by: kernel test robot <lkp at intel.com>
>>> ---
>>> v4: no change.
>>
>> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>>
>> Please funnel this patch through the STM and ARM SoC tree.
> 
> Sure, I will let Alex know. Thanks for your help on this driver.
> 
> Hi Alex,
> Should I send v5 with Linus's Reviewed-by tag on this patch? thanks.

No, I'll do it.

cheers
alex

> 
> Best Regards
> Dillon
> 
>>
>> Yours,
>> Linus Walleij



From robin.murphy at arm.com  Thu Aug  5 02:37:58 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 5 Aug 2021 10:37:58 +0100
Subject: [PATCH v3 02/25] iommu/amd: Drop IOVA cookie management
In-Reply-To: <ebc82f082d5fde58557efbec66f34b1be6a12599.1628094600.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <ebc82f082d5fde58557efbec66f34b1be6a12599.1628094600.git.robin.murphy@arm.com>
Message-ID: <44f5c699-1177-7f1d-479e-59a8a42efab6@arm.com>

On 2021-08-04 18:15, Robin Murphy wrote:
> The core code bakes its own cookies now.
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> 
> ---
> 
> v3: Also remove unneeded include
> ---
>   drivers/iommu/amd/iommu.c | 13 -------------
>   1 file changed, 13 deletions(-)
> 
> diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
> index 52fe2326042a..92f7cbe3d14a 100644
> --- a/drivers/iommu/amd/iommu.c
> +++ b/drivers/iommu/amd/iommu.c
> @@ -20,7 +20,6 @@
>   #include <linux/scatterlist.h>
>   #include <linux/dma-map-ops.h>
>   #include <linux/dma-direct.h>
> -#include <linux/dma-iommu.h>

Oh dear, how embarrassing... I went through all the drivers making that 
decision based on iommu_dma* references but totally forgot about 
iommu_setup_dma_ops() here. And then of course fell into the trap of 
"such a minor change I don't need to re-rest it" hubris... sigh, roll 
back to v2 for this one.

Apologies,
Robin.

>   #include <linux/iommu-helper.h>
>   #include <linux/delay.h>
>   #include <linux/amd-iommu.h>
> @@ -1918,16 +1917,7 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
>   	domain->domain.geometry.aperture_end   = ~0ULL;
>   	domain->domain.geometry.force_aperture = true;
>   
> -	if (type == IOMMU_DOMAIN_DMA &&
> -	    iommu_get_dma_cookie(&domain->domain) == -ENOMEM)
> -		goto free_domain;
> -
>   	return &domain->domain;
> -
> -free_domain:
> -	protection_domain_free(domain);
> -
> -	return NULL;
>   }
>   
>   static void amd_iommu_domain_free(struct iommu_domain *dom)
> @@ -1944,9 +1934,6 @@ static void amd_iommu_domain_free(struct iommu_domain *dom)
>   	if (!dom)
>   		return;
>   
> -	if (dom->type == IOMMU_DOMAIN_DMA)
> -		iommu_put_dma_cookie(&domain->domain);
> -
>   	if (domain->flags & PD_IOMMUV2_MASK)
>   		free_gcr3_table(domain);
>   
> 


From peng.fan at nxp.com  Thu Aug  5 02:38:22 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:38:22 +0000
Subject: [PATCH v2 04/18] soc: imx: gpcv2: add lockdep annotation
In-Reply-To: <20210721204703.1424034-5-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-5-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB275692C3F495C3777646925188F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 04/18] soc: imx: gpcv2: add lockdep annotation
> 
> Some of the GPCv2 power domains are nested inside each other without
> visibility to lockdep at the genpd level, as they are in separate driver instances
> and don't have a parent/child power-domain relationship.
> 
> Add a subclass annotation to the nested domains to let lockdep know that it is
> okay to take the genpd lock in a nested fashion.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

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

> ---
>  drivers/soc/imx/gpcv2.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index
> 2c43e74db0be..35f26f57d1ac 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -898,6 +898,10 @@ static int imx_pgc_domain_probe(struct
> platform_device *pdev)
>  		goto out_domain_unmap;
>  	}
> 
> +	if (IS_ENABLED(CONFIG_LOCKDEP) &&
> +	    of_property_read_bool(domain->dev->of_node, "power-domains"))
> +		lockdep_set_subclass(&domain->genpd.mlock, 1);
> +
>  	ret = of_genpd_add_provider_simple(domain->dev->of_node,
>  					   &domain->genpd);
>  	if (ret) {
> --
> 2.30.2



From peng.fan at nxp.com  Thu Aug  5 02:38:57 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:38:57 +0000
Subject: [PATCH v2 05/18] soc: imx: gpcv2: add domain option to keep
 domain clocks enabled
In-Reply-To: <20210721204703.1424034-6-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-6-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB27566D344BC0A3D5BB936EA288F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 05/18] soc: imx: gpcv2: add domain option to keep
> domain clocks enabled
> 
> Some of the MIX domains are using clocks to drive the bus bridges. Those
> must be enabled at all times, as long as the domain is powered up and they
> don't have any other consumer than the power domain. Add an option to
> keep the clocks attached to a domain enabled as long as the domain is power
> up and only disable them after the domain is powered down.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

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

> ---
>  drivers/soc/imx/gpcv2.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index
> 35f26f57d1ac..c3b1d2580963 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -202,6 +202,7 @@ struct imx_pgc_domain {
>  	} bits;
> 
>  	const int voltage;
> +	const bool keep_clocks;
>  	struct device *dev;
>  };
> 
> @@ -295,7 +296,8 @@ static int imx_pgc_power_up(struct
> generic_pm_domain *genpd)
>  	}
> 
>  	/* Disable reset clocks for all devices in the domain */
> -	clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
> +	if (!domain->keep_clocks)
> +		clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
> 
>  	return 0;
> 
> @@ -317,10 +319,12 @@ static int imx_pgc_power_down(struct
> generic_pm_domain *genpd)
>  	int ret;
> 
>  	/* Enable reset clocks for all devices in the domain */
> -	ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
> -	if (ret) {
> -		dev_err(domain->dev, "failed to enable reset clocks\n");
> -		return ret;
> +	if (!domain->keep_clocks) {
> +		ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
> +		if (ret) {
> +			dev_err(domain->dev, "failed to enable reset clocks\n");
> +			return ret;
> +		}
>  	}
> 
>  	/* request the ADB400 to power down */
> --
> 2.30.2



From peng.fan at nxp.com  Thu Aug  5 02:39:16 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:39:16 +0000
Subject: [PATCH v2 06/18] soc: imx: gpcv2: keep i.MX8M* bus clocks enabled
In-Reply-To: <20210721204703.1424034-7-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-7-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB27567190A8281EFE73920DE988F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 06/18] soc: imx: gpcv2: keep i.MX8M* bus clocks enabled
> 
> Annotate the domains with bus clocks to keep those clocks enabled as long as
> the domain is active.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

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

> ---
>  drivers/soc/imx/gpcv2.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index
> c3b1d2580963..c48f37f203ab 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -625,6 +625,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskreq = IMX8MM_HSIO_HSK_PWRDNREQN,
>  			.hskack = IMX8MM_HSIO_HSK_PWRDNACKN,
>  		},
> +		.keep_clocks = true,
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_PCIE] = {
> @@ -671,6 +672,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskack = IMX8MM_GPUMIX_HSK_PWRDNACKN,
>  		},
>  		.pgc   = BIT(IMX8MM_PGC_GPUMIX),
> +		.keep_clocks = true,
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_GPU] = {
> @@ -697,6 +699,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskack = IMX8MM_VPUMIX_HSK_PWRDNACKN,
>  		},
>  		.pgc   = BIT(IMX8MM_PGC_VPUMIX),
> +		.keep_clocks = true,
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_VPUG1] = {
> @@ -743,6 +746,7 @@ static const struct imx_pgc_domain
> imx8mm_pgc_domains[] = {
>  			.hskack = IMX8MM_DISPMIX_HSK_PWRDNACKN,
>  		},
>  		.pgc   = BIT(IMX8MM_PGC_DISPMIX),
> +		.keep_clocks = true,
>  	},
> 
>  	[IMX8MM_POWER_DOMAIN_MIPI] = {
> @@ -810,6 +814,7 @@ static const struct imx_pgc_domain
> imx8mn_pgc_domains[] = {
>  			.hskreq = IMX8MN_HSIO_HSK_PWRDNREQN,
>  			.hskack = IMX8MN_HSIO_HSK_PWRDNACKN,
>  		},
> +		.keep_clocks = true,
>  	},
> 
>  	[IMX8MN_POWER_DOMAIN_OTG1] = {
> --
> 2.30.2



From leo.yan at linaro.org  Thu Aug  5 02:40:24 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Thu, 5 Aug 2021 17:40:24 +0800
Subject: [PATCH 3/6] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <9156d7a1-3676-ab98-2c38-26f9765b845c@arm.com>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-4-james.clark@arm.com>
 <CAJ9a7Vjz_CMugYrLcAqr_aFsK6jYcqR3xLwJUi9KTXB3aPjnEQ@mail.gmail.com>
 <20210731063731.GC7437@leoy-ThinkPad-X240s>
 <9156d7a1-3676-ab98-2c38-26f9765b845c@arm.com>
Message-ID: <20210805094024.GA19058@leoy-ThinkPad-X240s>

On Tue, Aug 03, 2021 at 01:34:36PM +0100, James Clark wrote:
> 
> On 31/07/2021 07:37, Leo Yan wrote:
> >>> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> >>> index 85168d87b2d7..65a863bdf5cc 100644
> >>> --- a/tools/perf/arch/arm/util/cs-etm.c
> >>> +++ b/tools/perf/arch/arm/util/cs-etm.c
> >>> @@ -53,6 +53,7 @@ static const char *metadata_etmv4_ro[CS_ETMV4_PRIV_MAX] = {
> >>>         [CS_ETMV4_TRCIDR2]              = "trcidr/trcidr2",
> >>>         [CS_ETMV4_TRCIDR8]              = "trcidr/trcidr8",
> >>>         [CS_ETMV4_TRCAUTHSTATUS]        = "mgmt/trcauthstatus",
> >>> +       [CS_ETE_TRCDEVARCH]             = "mgmt/trcdevarch"
> > ETMv4 supports TRCDEVARCH, so I think it's good to use the naming
> > "CS_ETMV4_TRCDEVARCH"?
> > 
> 
> Based on the other discussions do you still think I should do this?

No, don't need to add TRCDEVARCH for ETMv4 anymore.

> As part of the new magic number I moved it into a new enum so it
> might be clearer now?

Regard ETMv4 and ETE use the different decoder types from OpenCSD, you
could add a new magic number and new enum for ETE.  It would be easier
for later extension for ETMv4 and ETE separately if decoder requires
to pass more config info.

Thanks,
Leo


From lorenzo.pieralisi at arm.com  Thu Aug  5 02:42:37 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 5 Aug 2021 10:42:37 +0100
Subject: [PATCH v2 0/6] arm64: IPQ6018 PCIe support
In-Reply-To: <87o8acxtqm.fsf@tarshish>
References: <cover.1620203062.git.baruch@tkos.co.il> <87o8acxtqm.fsf@tarshish>
Message-ID: <20210805094237.GA18330@lpieralisi>

On Thu, Aug 05, 2021 at 09:58:57AM +0300, Baruch Siach wrote:
> Hi Lorenzo, Rob, Krzysztof,
> 
> On Wed, May 05 2021, Baruch Siach wrote:
> > This series adds support for the single PCIe lane on IPQ6018 SoCs. The code is 
> > ported from downstream Codeaurora v5.4 kernel. The main difference from 
> > downstream code is the split of PCIe registers configuration from .init to 
> > .post_init, since it requires phy_power_on().
> >
> > Tested on IPQ6010 based hardware.
> 
> It's been 3 months with no comment. Would you consider applying the dwc
> part (patches #1 and #2) for the v5.15 merge window?
> 
> I tested the patches here successfully on top of v5.14-rc4.

You need an ACK from the respective drivers maintainers. We look into
overall pci/controller drivers structure and common code, it is up
to drivers maintainers to review and ACK your patches, I will certainly
pick them up when that's done.

Thanks,
Lorenzo

> Thanks,
> baruch
> 
> >
> > Changes in v2:
> >
> >   * Add patch moving GEN3_RELATED macros to a common header
> >
> >   * Drop ATU configuration from pcie-qcom
> >
> >   * Remove local definition of common registers
> >
> >   * Use bulk clk and reset APIs
> >
> >   * Remove msi-parent from device-tree
> >
> > Baruch Siach (3):
> >   PCI: dwc: tegra: move GEN3_RELATED DBI register to common header
> >   dt-bindings: phy: qcom,qmp: Add IPQ60xx PCIe PHY bindings
> >   dt-bindings: pci: qcom: Document PCIe bindings for IPQ6018 SoC
> >
> > Selvam Sathappan Periakaruppan (3):
> >   PCI: qcom: add support for IPQ60xx PCIe controller
> >   phy: qcom-qmp: add QMP V2 PCIe PHY support for ipq60xx
> >   arm64: dts: ipq6018: Add pcie support
> >
> >  .../devicetree/bindings/pci/qcom,pcie.txt     |  24 +++
> >  .../devicetree/bindings/phy/qcom,qmp-phy.yaml |  25 +++
> >  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  99 ++++++++++++
> >  drivers/pci/controller/dwc/pcie-designware.h  |   7 +
> >  drivers/pci/controller/dwc/pcie-qcom.c        | 150 ++++++++++++++++++
> >  drivers/pci/controller/dwc/pcie-tegra194.c    |   6 -
> >  drivers/phy/qualcomm/phy-qcom-qmp.c           | 147 +++++++++++++++++
> >  drivers/phy/qualcomm/phy-qcom-qmp.h           | 132 +++++++++++++++
> >  8 files changed, 584 insertions(+), 6 deletions(-)
> 
> 
> -- 
>                                                      ~. .~   Tk Open Systems
> =}------------------------------------------------ooO--U--Ooo------------{=
>    - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From krzysztof.kozlowski at canonical.com  Thu Aug  5 02:43:39 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 5 Aug 2021 11:43:39 +0200
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <03d701d789db$f275d290$d76177b0$@samsung.com>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
 <CGME20210805073653epcas5p21b4c2358b7de2b3c21dbc357af957137@epcas5p2.samsung.com>
 <b0d6ff2a-24af-96c1-62a1-8b920c63e05a@canonical.com>
 <03d701d789db$f275d290$d76177b0$@samsung.com>
Message-ID: <7c019443-6153-f059-418b-3b268750f7a8@canonical.com>

On 05/08/2021 11:26, Alim Akhtar wrote:
> Hi Krzysztof,
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> Sent: 05 August 2021 13:07
>> To: Rob Herring <robh+dt at kernel.org>; devicetree at vger.kernel.org; linux-
>> arm-kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
>> kernel at vger.kernel.org
>> Cc: Alim Akhtar <alim.akhtar at samsung.com>; Chanwoo Choi
>> <cw00.choi at samsung.com>; Pankaj Dubey <pankaj.dubey at samsung.com>;
>> Sam Protsenko <semen.protsenko at linaro.org>; Marc Zyngier
>> <maz at kernel.org>
>> Subject: Re: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
>> range on Exynos7
>>
>> On 05/08/2021 09:21, Krzysztof Kozlowski wrote:
>>> The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF
>>> (by ARM).
>>>
>>
> Looking at DDI0471B_gic400_r0p1_trm.pdf, CPU interface range is 0x0000 ~ 0x10000
> 
>> I underestimated the issue - this is actually bug as there is a GICC_DIR
>> register at offset 0x1000. Therefore:
>>
> Looking at the exynos7 and exynos5433 UMs looks like GICC_DIR is at offset 0x2100 (from 0x1100_0000 GIC base)
> It is possible for you to cross check once?
> 

That's a mistake in Exynos manual. GICC_DIR is at 0x1000:
https://developer.arm.com/documentation/ddi0471/b/programmers-model/cpu-interface-register-summary

We have discussion here:
https://lore.kernel.org/linux-samsung-soc/0277c701-cc25-cdc5-d3b9-cf2cc2ba4de5 at canonical.com/T/#m1ced9a28bed27f5cf74e281fb68efe1b57d5609e

Range of 0x10000 is definitely wrong as it overlaps with two other
ranges.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Aug  5 02:44:56 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 5 Aug 2021 11:44:56 +0200
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <7c019443-6153-f059-418b-3b268750f7a8@canonical.com>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
 <CGME20210805073653epcas5p21b4c2358b7de2b3c21dbc357af957137@epcas5p2.samsung.com>
 <b0d6ff2a-24af-96c1-62a1-8b920c63e05a@canonical.com>
 <03d701d789db$f275d290$d76177b0$@samsung.com>
 <7c019443-6153-f059-418b-3b268750f7a8@canonical.com>
Message-ID: <4fc60199-44cd-41ea-9178-92b131d21b73@canonical.com>

On 05/08/2021 11:43, Krzysztof Kozlowski wrote:
> On 05/08/2021 11:26, Alim Akhtar wrote:
>> Hi Krzysztof,
>>
>>> -----Original Message-----
>>> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>> Sent: 05 August 2021 13:07
>>> To: Rob Herring <robh+dt at kernel.org>; devicetree at vger.kernel.org; linux-
>>> arm-kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
>>> kernel at vger.kernel.org
>>> Cc: Alim Akhtar <alim.akhtar at samsung.com>; Chanwoo Choi
>>> <cw00.choi at samsung.com>; Pankaj Dubey <pankaj.dubey at samsung.com>;
>>> Sam Protsenko <semen.protsenko at linaro.org>; Marc Zyngier
>>> <maz at kernel.org>
>>> Subject: Re: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
>>> range on Exynos7
>>>
>>> On 05/08/2021 09:21, Krzysztof Kozlowski wrote:
>>>> The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF
>>>> (by ARM).
>>>>
>>>
>> Looking at DDI0471B_gic400_r0p1_trm.pdf, CPU interface range is 0x0000 ~ 0x10000
>>
>>> I underestimated the issue - this is actually bug as there is a GICC_DIR
>>> register at offset 0x1000. Therefore:
>>>
>> Looking at the exynos7 and exynos5433 UMs looks like GICC_DIR is at offset 0x2100 (from 0x1100_0000 GIC base)
>> It is possible for you to cross check once?
>>
> 
> That's a mistake in Exynos manual. GICC_DIR is at 0x1000:

0x1000 from CPU base offset, so 0x3000 from GIC base.

> https://developer.arm.com/documentation/ddi0471/b/programmers-model/cpu-interface-register-summary
> 
> We have discussion here:
> https://lore.kernel.org/linux-samsung-soc/0277c701-cc25-cdc5-d3b9-cf2cc2ba4de5 at canonical.com/T/#m1ced9a28bed27f5cf74e281fb68efe1b57d5609e
> 
> Range of 0x10000 is definitely wrong as it overlaps with two other
> ranges.


Best regards,
Krzysztof


From peng.fan at nxp.com  Thu Aug  5 02:47:35 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:47:35 +0000
Subject: [PATCH v2 07/18] soc: imx: gpcv2: support system suspend/resume
In-Reply-To: <20210721204703.1424034-8-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-8-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB2756154A5BD71E51DCF0203888F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 07/18] soc: imx: gpcv2: support system suspend/resume
> 
> Our usage of runtime PM to control the hierarchy of power domains is slightly
> unusual and means that powering up a domain may fail in early system
> resume, as runtime PM is still disallowed at this stage.
> 
> However the system suspend/resume path takes care of powering down/up
> the power domains in the order defined by the device parent/child and
> power-domain provider/consumer hierarachy. So we can just runtime resume
> all our power-domain devices to allow the power-up to work properly in the
> resume path. System suspend will still disable all domains as intended.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Acked-by: Peng Fan <peng.fan at nxp.com>

> ---
>  drivers/soc/imx/gpcv2.c | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index
> c48f37f203ab..57ed0a6bfb13 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -947,6 +947,36 @@ static int imx_pgc_domain_remove(struct
> platform_device *pdev)
>  	return 0;
>  }
> 
> +#ifdef CONFIG_PM_SLEEP
> +static int imx_pgc_domain_suspend(struct device *dev) {
> +	int ret;
> +
> +	/*
> +	 * This may look strange, but is done so the generic PM_SLEEP code
> +	 * can power down our domain and more importantly power it up again
> +	 * after resume, without tripping over our usage of runtime PM to
> +	 * power up/down the nested domains.
> +	 */
> +	ret = pm_runtime_get_sync(dev);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(dev);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_pgc_domain_resume(struct device *dev) {
> +	return pm_runtime_put(dev);
> +}
> +#endif
> +
> +static const struct dev_pm_ops imx_pgc_domain_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(imx_pgc_domain_suspend,
> imx_pgc_domain_resume)
> +};
> +
>  static const struct platform_device_id imx_pgc_domain_id[] = {
>  	{ "imx-pgc-domain", },
>  	{ },
> @@ -955,6 +985,7 @@ static const struct platform_device_id
> imx_pgc_domain_id[] = {  static struct platform_driver
> imx_pgc_domain_driver = {
>  	.driver = {
>  		.name = "imx-pgc",
> +		.pm = &imx_pgc_domain_pm_ops,
>  	},
>  	.probe    = imx_pgc_domain_probe,
>  	.remove   = imx_pgc_domain_remove,
> --
> 2.30.2



From peng.fan at nxp.com  Thu Aug  5 02:53:38 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:53:38 +0000
Subject: [PATCH v2 13/18] soc: imx: imx8m-blk-ctrl: add DISP blk-ctrl
In-Reply-To: <20210721204703.1424034-14-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-14-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB2756A63D0670BBCE0D790D5188F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 13/18] soc: imx: imx8m-blk-ctrl: add DISP blk-ctrl
> 
> This adds the description for the i.MX8MM disp blk-ctrl.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

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

> ---
>  drivers/soc/imx/imx8m-blk-ctrl.c | 70
> ++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
> 
> diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c
> b/drivers/soc/imx/imx8m-blk-ctrl.c
> index 3dd17b903636..32eab800a3c6 100644
> --- a/drivers/soc/imx/imx8m-blk-ctrl.c
> +++ b/drivers/soc/imx/imx8m-blk-ctrl.c
> @@ -433,11 +433,81 @@ static const struct imx8m_blk_ctrl_data
> imx8m_vpu_blk_ctl_dev_data = {
>  	.num_domains = ARRAY_SIZE(imx8m_vpu_blk_ctl_domain_data),
>  };
> 
> +static int imx8mm_disp_power_notifier(struct notifier_block *nb,
> +				      unsigned long action, void *data) {
> +	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
> +						 power_nb);
> +
> +	if (action != GENPD_NOTIFY_ON && action !=
> GENPD_NOTIFY_PRE_OFF)
> +		return NOTIFY_OK;
> +
> +	/* Enable bus clock and deassert bus reset */
> +	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(12));
> +	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(6));
> +
> +	/*
> +	 * On power up we have no software backchannel to the GPC to
> +	 * wait for the ADB handshake to happen, so we just delay for a
> +	 * bit. On power down the GPC driver waits for the handshake.
> +	 */
> +	if (action == GENPD_NOTIFY_ON)
> +		udelay(5);
> +
> +
> +	return NOTIFY_OK;
> +}
> +
> +static const struct imx8m_blk_ctrl_domain_data
> imx8m_disp_blk_ctl_domain_data[] = {
> +	[IMX8MM_DISPBLK_CSI_BRIDGE] = {
> +		.name = "dispblk-csi-bridge",
> +		.clk_names = (const char *[]){ "csi-bridge-axi", "csi-bridge-apb",
> +					       "csi-bridge-core", },
> +		.num_clks = 3,
> +		.gpc_name = "csi-bridge",
> +		.rst_mask = BIT(0) | BIT(1) | BIT(2),
> +		.clk_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5),
> +	},
> +	[IMX8MM_DISPBLK_LCDIF] = {
> +		.name = "dispblk-lcdif",
> +		.clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", },
> +		.num_clks = 3,
> +		.gpc_name = "lcdif",
> +		.clk_mask = BIT(6) | BIT(7),
> +	},
> +	[IMX8MM_DISPBLK_MIPI_DSI] = {
> +		.name = "dispblk-mipi-dsi",
> +		.clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", },
> +		.num_clks = 2,
> +		.gpc_name = "mipi-dsi",
> +		.rst_mask = BIT(5),
> +		.clk_mask = BIT(8) | BIT(9),
> +	},
> +	[IMX8MM_DISPBLK_MIPI_CSI] = {
> +		.name = "dispblk-mipi-csi",
> +		.clk_names = (const char *[]){ "csi-aclk", "csi-pclk" },
> +		.num_clks = 2,
> +		.gpc_name = "mipi-csi",
> +		.rst_mask = BIT(3) | BIT(4),
> +		.clk_mask = BIT(10) | BIT(11),
> +	},
> +};
> +
> +static const struct imx8m_blk_ctrl_data imx8m_disp_blk_ctl_dev_data = {
> +	.max_reg = 0x2c,
> +	.power_notifier_fn = imx8mm_disp_power_notifier,
> +	.domains = imx8m_disp_blk_ctl_domain_data,
> +	.num_domains = ARRAY_SIZE(imx8m_disp_blk_ctl_domain_data),
> +};
> +
>  static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
>  	{
>  		.compatible = "fsl,imx8mm-vpu-blk-ctrl",
>  		.data = &imx8m_vpu_blk_ctl_dev_data
>  	}, {
> +		.compatible = "fsl,imx8mm-disp-blk-ctrl",
> +		.data = &imx8m_disp_blk_ctl_dev_data
> +	} ,{
>  		/* Sentinel */
>  	}
>  };
> --
> 2.30.2



From peng.fan at nxp.com  Thu Aug  5 02:54:26 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:54:26 +0000
Subject: [PATCH v2 14/18] arm64: dts: imx8mm: add GPC node
In-Reply-To: <20210721204703.1424034-15-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-15-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB27563F7D8CDF210F52220C5D88F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 14/18] arm64: dts: imx8mm: add GPC node
> 
> Add the DT node for the GPC, including all the PGC power domains, some of
> them are not fully functional yet, as they require interaction with the blk-ctrls
> to properly power up/down the peripherals.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

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

> ---
>  arch/arm64/boot/dts/freescale/imx8mm.dtsi | 107
> ++++++++++++++++++++++
>  1 file changed, 107 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> index a27e02bee6b4..1cdb475b5895 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> @@ -7,6 +7,8 @@
>  #include <dt-bindings/gpio/gpio.h>
>  #include <dt-bindings/input/input.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/power/imx8mm-power.h>
> +#include <dt-bindings/reset/imx8mq-reset.h>
>  #include <dt-bindings/thermal/thermal.h>
> 
>  #include "imx8mm-pinfunc.h"
> @@ -600,6 +602,111 @@ src: reset-controller at 30390000 {
>  				interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
>  				#reset-cells = <1>;
>  			};
> +
> +			gpc: gpc at 303a0000 {
> +				compatible = "fsl,imx8mm-gpc";
> +				reg = <0x303a0000 0x10000>;
> +				interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
> +				interrupt-parent = <&gic>;
> +				interrupt-controller;
> +				#interrupt-cells = <3>;
> +
> +				pgc {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +
> +					pgc_hsiomix: power-domain at 0 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_HSIOMIX>;
> +						clocks = <&clk IMX8MM_CLK_USB_BUS>;
> +						assigned-clocks = <&clk
> IMX8MM_CLK_USB_BUS>;
> +						assigned-clock-parents = <&clk
> IMX8MM_SYS_PLL2_500M>;
> +					};
> +
> +					pgc_pcie: power-domain at 1 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_PCIE>;
> +						power-domains = <&pgc_hsiomix>;
> +						clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>;
> +					};
> +
> +					pgc_otg1: power-domain at 2 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_OTG1>;
> +						power-domains = <&pgc_hsiomix>;
> +					};
> +
> +					pgc_otg2: power-domain at 3 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_OTG2>;
> +						power-domains = <&pgc_hsiomix>;
> +					};
> +
> +					pgc_gpumix: power-domain at 4 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_GPUMIX>;
> +						clocks = <&clk
> IMX8MM_CLK_GPU_BUS_ROOT>,
> +							 <&clk IMX8MM_CLK_GPU_AHB>;
> +						assigned-clocks = <&clk
> IMX8MM_CLK_GPU_AXI>,
> +								  <&clk IMX8MM_CLK_GPU_AHB>;
> +						assigned-clock-parents = <&clk
> IMX8MM_SYS_PLL1_800M>,
> +									 <&clk
> IMX8MM_SYS_PLL1_800M>;
> +						assigned-clock-rates = <800000000>,
> <400000000>;
> +					};
> +
> +					pgc_gpu: power-domain at 5 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_GPU>;
> +						clocks = <&clk IMX8MM_CLK_GPU_AHB>,
> +							 <&clk IMX8MM_CLK_GPU_BUS_ROOT>,
> +							 <&clk IMX8MM_CLK_GPU2D_ROOT>,
> +							 <&clk IMX8MM_CLK_GPU3D_ROOT>;
> +						resets = <&src IMX8MQ_RESET_GPU_RESET>;
> +						power-domains = <&pgc_gpumix>;
> +					};
> +
> +					pgc_vpumix: power-domain at 6 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_VPUMIX>;
> +						clocks = <&clk
> IMX8MM_CLK_VPU_DEC_ROOT>;
> +						assigned-clocks = <&clk
> IMX8MM_CLK_VPU_BUS>;
> +						assigned-clock-parents = <&clk
> IMX8MM_SYS_PLL1_800M>;
> +						resets = <&src IMX8MQ_RESET_VPU_RESET>;
> +					};
> +
> +					pgc_vpu_g1: power-domain at 7 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_VPUG1>;
> +					};
> +
> +					pgc_vpu_g2: power-domain at 8 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_VPUG2>;
> +					};
> +
> +					pgc_vpu_h1: power-domain at 9 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_VPUH1>;
> +					};
> +
> +					pgc_dispmix: power-domain at 10 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_DISPMIX>;
> +						clocks = <&clk
> IMX8MM_CLK_DISP_APB_ROOT>,
> +							 <&clk IMX8MM_CLK_DISP_AXI_ROOT>;
> +						assigned-clocks = <&clk
> IMX8MM_CLK_DISP_AXI>,
> +								  <&clk IMX8MM_CLK_DISP_APB>;
> +						assigned-clock-parents = <&clk
> IMX8MM_SYS_PLL2_1000M>,
> +									 <&clk
> IMX8MM_SYS_PLL1_800M>;
> +						assigned-clock-rates = <500000000>,
> <200000000>;
> +					};
> +
> +					pgc_mipi: power-domain at 11 {
> +						#power-domain-cells = <0>;
> +						reg = <IMX8MM_POWER_DOMAIN_MIPI>;
> +					};
> +				};
> +			};
>  		};
> 
>  		aips2: bus at 30400000 {
> --
> 2.30.2



From peng.fan at nxp.com  Thu Aug  5 02:54:49 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:54:49 +0000
Subject: [PATCH v2 10/18] soc: imx: add i.MX8M blk-ctrl driver
In-Reply-To: <20210721204703.1424034-11-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <20210721204703.1424034-11-l.stach@pengutronix.de>
Message-ID: <AM5PR0402MB275692FAFE859A8042D2F66E88F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v2 10/18] soc: imx: add i.MX8M blk-ctrl driver
> 
> This adds a driver for the blk-ctrl blocks found in the i.MX8M* line of SoCs.
> The blk-ctrl is a top-level peripheral located in the various *MIX power
> domains and interacts with the GPC power controller to provide the
> peripherals in the power domain access to the NoC and ensures that those
> peripherals are properly reset when their respective power domain is brought
> back to life.
> 
> Software needs to do different things to make the bus handshake happen
> after the the GPC *MIX domain is power up and before it is powered down.
> As the requirements are quite different between the various blk-ctrls there is
> a callback function provided to hook in the proper sequence.
> 
> The peripheral domains are quite uniform, they handle the soft clock enables
> and resets in the blk-ctrl address space and sequencing with the upstream
> GPC power domains.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

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

> ---
> This commit includes the full code to drive the VPUMIX domain on the
> i.MX8MM, as the skeleton driver would probably be harder to review without
> the context provided by one blk-ctrl implementation. Other blk-ctrl
> implementations will follow, based on this overall structure.
> ---
>  drivers/soc/imx/Makefile         |   1 +
>  drivers/soc/imx/imx8m-blk-ctrl.c | 455
> +++++++++++++++++++++++++++++++
>  2 files changed, 456 insertions(+)
>  create mode 100644 drivers/soc/imx/imx8m-blk-ctrl.c
> 
> diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile index
> 078dc918f4f3..8a707077914c 100644
> --- a/drivers/soc/imx/Makefile
> +++ b/drivers/soc/imx/Makefile
> @@ -5,3 +5,4 @@ endif
>  obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
>  obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
>  obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
> +obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
> diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c
> b/drivers/soc/imx/imx8m-blk-ctrl.c
> new file mode 100644
> index 000000000000..3dd17b903636
> --- /dev/null
> +++ b/drivers/soc/imx/imx8m-blk-ctrl.c
> @@ -0,0 +1,455 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * Copyright 2021 Pengutronix, Lucas Stach <kernel at pengutronix.de>  */
> +
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/clk.h>
> +
> +#include <dt-bindings/power/imx8mm-power.h>
> +
> +#define BLK_SFT_RSTN	0x0
> +#define BLK_CLK_EN	0x4
> +
> +struct imx8m_blk_ctrl_domain;
> +
> +struct imx8m_blk_ctrl {
> +	struct device *dev;
> +	struct notifier_block power_nb;
> +	struct device *bus_power_dev;
> +	struct regmap *regmap;
> +	struct imx8m_blk_ctrl_domain *domains;
> +	struct genpd_onecell_data onecell_data; };
> +
> +struct imx8m_blk_ctrl_domain_data {
> +	const char *name;
> +	const char **clk_names;
> +	int num_clks;
> +	const char *gpc_name;
> +	u32 rst_mask;
> +	u32 clk_mask;
> +};
> +
> +#define DOMAIN_MAX_CLKS 3
> +
> +struct imx8m_blk_ctrl_domain {
> +	struct generic_pm_domain genpd;
> +	const struct imx8m_blk_ctrl_domain_data *data;
> +	struct clk_bulk_data clks[DOMAIN_MAX_CLKS];
> +	struct device *power_dev;
> +	struct imx8m_blk_ctrl *bc;
> +};
> +
> +struct imx8m_blk_ctrl_data {
> +	int max_reg;
> +	notifier_fn_t power_notifier_fn;
> +	const struct imx8m_blk_ctrl_domain_data *domains;
> +	int num_domains;
> +};
> +
> +static inline struct imx8m_blk_ctrl_domain *
> +to_imx8m_blk_ctrl_domain(struct generic_pm_domain *genpd) {
> +	return container_of(genpd, struct imx8m_blk_ctrl_domain, genpd); }
> +
> +static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd) {
> +	struct imx8m_blk_ctrl_domain *domain =
> to_imx8m_blk_ctrl_domain(genpd);
> +	const struct imx8m_blk_ctrl_domain_data *data = domain->data;
> +	struct imx8m_blk_ctrl *bc = domain->bc;
> +	int ret;
> +
> +	/* make sure bus domain is awake */
> +	ret = pm_runtime_get_sync(bc->bus_power_dev);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(bc->bus_power_dev);
> +		dev_err(bc->dev, "failed to power up bus domain\n");
> +		return ret;
> +	}
> +
> +	/* put devices into reset */
> +	regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask);
> +
> +	/* enable upstream and blk-ctrl clocks to allow reset to propagate */
> +	ret = clk_bulk_prepare_enable(data->num_clks, domain->clks);
> +	if (ret) {
> +		dev_err(bc->dev, "failed to enable clocks\n");
> +		goto bus_put;
> +	}
> +	regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask);
> +
> +	/* power up upstream GPC domain */
> +	ret = pm_runtime_get_sync(domain->power_dev);
> +	if (ret < 0) {
> +		dev_err(bc->dev, "failed to power up peripheral domain\n");
> +		goto clk_disable;
> +	}
> +
> +	/* wait for reset to propagate */
> +	udelay(5);
> +
> +	/* release reset */
> +	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask);
> +
> +	/* disable upstream clocks */
> +	clk_bulk_disable_unprepare(data->num_clks, domain->clks);
> +
> +	return 0;
> +
> +clk_disable:
> +	clk_bulk_disable_unprepare(data->num_clks, domain->clks);
> +bus_put:
> +	pm_runtime_put(bc->bus_power_dev);
> +
> +	return ret;
> +}
> +
> +static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd) {
> +	struct imx8m_blk_ctrl_domain *domain =
> to_imx8m_blk_ctrl_domain(genpd);
> +	const struct imx8m_blk_ctrl_domain_data *data = domain->data;
> +	struct imx8m_blk_ctrl *bc = domain->bc;
> +
> +	/* put devices into reset and disable clocks */
> +	regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask);
> +	regmap_clear_bits(bc->regmap, BLK_CLK_EN, data->clk_mask);
> +
> +	/* power down upstream GPC domain */
> +	pm_runtime_put(domain->power_dev);
> +
> +	/* allow bus domain to suspend */
> +	pm_runtime_put(bc->bus_power_dev);
> +
> +	return 0;
> +}
> +
> +static struct generic_pm_domain *
> +imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data) {
> +	struct genpd_onecell_data *onecell_data = data;
> +	unsigned int index = args->args[0];
> +
> +	if (args->args_count != 1 ||
> +	    index > onecell_data->num_domains)
> +		return ERR_PTR(-EINVAL);
> +
> +	return onecell_data->domains[index];
> +}
> +
> +static struct lock_class_key blk_ctrl_genpd_lock_class;
> +
> +static int imx8m_blk_ctrl_probe(struct platform_device *pdev) {
> +	const struct imx8m_blk_ctrl_data *bc_data;
> +	struct device *dev = &pdev->dev;
> +	struct imx8m_blk_ctrl *bc;
> +	void __iomem *base;
> +	int i, ret;
> +
> +	struct regmap_config regmap_config = {
> +		.reg_bits	= 32,
> +		.val_bits	= 32,
> +		.reg_stride	= 4,
> +	};
> +
> +	bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL);
> +	if (!bc)
> +		return -ENOMEM;
> +
> +	bc->dev = dev;
> +
> +	bc_data = of_device_get_match_data(dev);
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	regmap_config.max_register = bc_data->max_reg;
> +	bc->regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
> +	if (IS_ERR(bc->regmap))
> +		return dev_err_probe(dev, PTR_ERR(bc->regmap),
> +				     "failed to init regmap \n");
> +
> +	bc->domains = devm_kcalloc(dev, bc_data->num_domains,
> +				    sizeof(struct imx8m_blk_ctrl_domain),
> +				    GFP_KERNEL);
> +	if (!bc->domains)
> +		return -ENOMEM;
> +
> +	bc->onecell_data.num_domains = bc_data->num_domains;
> +	bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
> +	bc->onecell_data.domains =
> +		devm_kcalloc(dev, bc_data->num_domains,
> +			     sizeof(struct generic_pm_domain *), GFP_KERNEL);
> +	if (!bc->onecell_data.domains)
> +		return -ENOMEM;
> +
> +	bc->bus_power_dev = genpd_dev_pm_attach_by_name(dev, "bus");
> +	if (IS_ERR(bc->bus_power_dev))
> +		return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev),
> +				     "failed to attach power domain\n");
> +
> +	for (i = 0; i < bc_data->num_domains; i++) {
> +		const struct imx8m_blk_ctrl_domain_data *data =
> &bc_data->domains[i];
> +		struct imx8m_blk_ctrl_domain *domain = &bc->domains[i];
> +		int j;
> +
> +		domain->data = data;
> +
> +		for (j = 0; j < data->num_clks; j++)
> +			domain->clks[j].id = data->clk_names[j];
> +
> +		ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks);
> +		if (ret) {
> +			dev_err_probe(dev, ret, "failed to get clock\n");
> +			goto cleanup_pds;
> +		}
> +
> +		domain->power_dev =
> +			dev_pm_domain_attach_by_name(dev, data->gpc_name);
> +		if (IS_ERR(domain->power_dev)) {
> +			dev_err_probe(dev, PTR_ERR(domain->power_dev),
> +				      "failed to attach power domain\n");
> +			ret = PTR_ERR(domain->power_dev);
> +			goto cleanup_pds;
> +		}
> +
> +		domain->genpd.name = data->name;
> +		domain->genpd.power_on = imx8m_blk_ctrl_power_on;
> +		domain->genpd.power_off = imx8m_blk_ctrl_power_off;
> +		domain->bc = bc;
> +
> +		ret = pm_genpd_init(&domain->genpd, NULL, true);
> +		if (ret) {
> +			dev_err_probe(dev, ret, "failed to init power domain\n");
> +			dev_pm_domain_detach(domain->power_dev, true);
> +			goto cleanup_pds;
> +		}
> +
> +		/*
> +		 * We use runtime PM to trigger power on/off of the upstream GPC
> +		 * domain, as a strict hierarchical parent/child power domain
> +		 * setup doesn't allow us to meet the sequencing requirements.
> +		 * This means we have nested locking of genpd locks, without the
> +		 * nesting being visible at the genpd level, so we need a
> +		 * separate lock class to make lockdep aware of the fact that
> +		 * this are separate domain locks that can be nested without a
> +		 * self-deadlock.
> +		 */
> +		lockdep_set_class(&domain->genpd.mlock,
> +				  &blk_ctrl_genpd_lock_class);
> +
> +		bc->onecell_data.domains[i] = &domain->genpd;
> +	}
> +
> +	ret = of_genpd_add_provider_onecell(dev->of_node,
> &bc->onecell_data);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "failed to add power domain provider\n");
> +		goto cleanup_pds;
> +	}
> +
> +	bc->power_nb.notifier_call = bc_data->power_notifier_fn;
> +	ret = dev_pm_genpd_add_notifier(bc->bus_power_dev,
> &bc->power_nb);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "failed to add power notifier\n");
> +		goto cleanup_provider;
> +	}
> +
> +	dev_set_drvdata(dev, bc);
> +
> +	return 0;
> +
> +cleanup_provider:
> +	of_genpd_del_provider(dev->of_node);
> +cleanup_pds:
> +	for (i--; i >= 0; i--) {
> +		pm_genpd_remove(&bc->domains[i].genpd);
> +		dev_pm_domain_detach(bc->domains[i].power_dev, true);
> +	}
> +
> +	dev_pm_domain_detach(bc->bus_power_dev, true);
> +
> +	return ret;
> +}
> +
> +static int imx8m_blk_ctrl_remove(struct platform_device *pdev) {
> +	struct imx8m_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
> +	int i;
> +
> +	of_genpd_del_provider(pdev->dev.of_node);
> +
> +	for (i = 0; bc->onecell_data.num_domains; i++) {
> +		struct imx8m_blk_ctrl_domain *domain = &bc->domains[i];
> +
> +		pm_genpd_remove(&domain->genpd);
> +		dev_pm_domain_detach(domain->power_dev, true);
> +	}
> +
> +	dev_pm_genpd_remove_notifier(bc->bus_power_dev);
> +
> +	dev_pm_domain_detach(bc->bus_power_dev, true);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int imx8m_blk_ctrl_suspend(struct device *dev) {
> +	struct imx8m_blk_ctrl *bc = dev_get_drvdata(dev);
> +	int ret, i;
> +
> +	/*
> +	 * This may look strange, but is done so the generic PM_SLEEP code
> +	 * can power down our domains and more importantly power them up
> again
> +	 * after resume, without tripping over our usage of runtime PM to
> +	 * control the upstream GPC domains. Things happen in the right order
> +	 * in the system suspend/resume paths due to the device parent/child
> +	 * hierarchy.
> +	 */
> +	ret = pm_runtime_get_sync(bc->bus_power_dev);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(bc->bus_power_dev);
> +		return ret;
> +	}
> +
> +	for (i = 0; i < bc->onecell_data.num_domains; i++) {
> +		struct imx8m_blk_ctrl_domain *domain = &bc->domains[i];
> +
> +		ret = pm_runtime_get_sync(domain->power_dev);
> +		if (ret < 0) {
> +			pm_runtime_put_noidle(domain->power_dev);
> +			goto out_fail;
> +		}
> +	}
> +
> +	return 0;
> +
> +out_fail:
> +	for (i--; i >= 0; i--)
> +		pm_runtime_put(bc->domains[i].power_dev);
> +
> +	pm_runtime_put(bc->bus_power_dev);
> +
> +	return ret;
> +}
> +
> +static int imx8m_blk_ctrl_resume(struct device *dev) {
> +	struct imx8m_blk_ctrl *bc = dev_get_drvdata(dev);
> +	int i;
> +
> +	for (i = 0; i < bc->onecell_data.num_domains; i++)
> +		pm_runtime_put(bc->domains[i].power_dev);
> +
> +	pm_runtime_put(bc->bus_power_dev);
> +
> +	return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops imx8m_blk_ctrl_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(imx8m_blk_ctrl_suspend,
> imx8m_blk_ctrl_resume)
> +};
> +
> +static int imx8mm_vpu_power_notifier(struct notifier_block *nb,
> +				     unsigned long action, void *data) {
> +	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
> +						 power_nb);
> +
> +	if (action != GENPD_NOTIFY_ON && action !=
> GENPD_NOTIFY_PRE_OFF)
> +		return NOTIFY_OK;
> +
> +	/*
> +	 * The ADB in the VPUMIX domain has no separate reset and clock
> +	 * enable bits, but is ungated together with the VPU clocks. To
> +	 * allow the handshake with the GPC to progress we put the VPUs
> +	 * in reset and ungate the clocks.
> +	 */
> +	regmap_clear_bits(bc->regmap, BLK_SFT_RSTN,
> +			  BIT(0) | BIT(1) | BIT(2));
> +	regmap_set_bits(bc->regmap, BLK_CLK_EN,
> +			BIT(0) | BIT(1) | BIT(2));
> +
> +	if (action == GENPD_NOTIFY_ON) {
> +		/*
> +		 * On power up we have no software backchannel to the GPC to
> +		 * wait for the ADB handshake to happen, so we just delay for a
> +		 * bit. On power down the GPC driver waits for the handshake.
> +		 */
> +		udelay(5);
> +
> +		/* set "fuse" bits to enable the VPUs */
> +		regmap_set_bits(bc->regmap, 0x8, 0xffffffff);
> +		regmap_set_bits(bc->regmap, 0xc, 0xffffffff);
> +		regmap_set_bits(bc->regmap, 0x10, 0xffffffff);
> +		regmap_set_bits(bc->regmap, 0x14, 0xffffffff);
> +	}
> +
> +	return NOTIFY_OK;
> +}
> +
> +static const struct imx8m_blk_ctrl_domain_data
> imx8m_vpu_blk_ctl_domain_data[] = {
> +	[IMX8MM_VPUBLK_PD_G1] = {
> +		.name = "vpublk-g1",
> +		.clk_names = (const char *[]){ "g1", },
> +		.num_clks = 1,
> +		.gpc_name = "g1",
> +		.rst_mask = BIT(1),
> +		.clk_mask = BIT(1),
> +	},
> +	[IMX8MM_VPUBLK_PD_G2] = {
> +		.name = "vpublk-g2",
> +		.clk_names = (const char *[]){ "g2", },
> +		.num_clks = 1,
> +		.gpc_name = "g2",
> +		.rst_mask = BIT(0),
> +		.clk_mask = BIT(0),
> +	},
> +	[IMX8MM_VPUBLK_PD_H1] = {
> +		.name = "vpublk-h1",
> +		.clk_names = (const char *[]){ "h1", },
> +		.num_clks = 1,
> +		.gpc_name = "h1",
> +		.rst_mask = BIT(2),
> +		.clk_mask = BIT(2),
> +	},
> +};
> +
> +static const struct imx8m_blk_ctrl_data imx8m_vpu_blk_ctl_dev_data = {
> +	.max_reg = 0x18,
> +	.power_notifier_fn = imx8mm_vpu_power_notifier,
> +	.domains = imx8m_vpu_blk_ctl_domain_data,
> +	.num_domains = ARRAY_SIZE(imx8m_vpu_blk_ctl_domain_data),
> +};
> +
> +static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
> +	{
> +		.compatible = "fsl,imx8mm-vpu-blk-ctrl",
> +		.data = &imx8m_vpu_blk_ctl_dev_data
> +	}, {
> +		/* Sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match);
> +
> +static struct platform_driver imx8m_blk_ctrl_driver = {
> +	.probe = imx8m_blk_ctrl_probe,
> +	.remove = imx8m_blk_ctrl_remove,
> +	.driver = {
> +		.name = "imx8m-blk-ctrl",
> +		.pm = &imx8m_blk_ctrl_pm_ops,
> +		.of_match_table = imx8m_blk_ctrl_of_match,
> +	},
> +};
> +module_platform_driver(imx8m_blk_ctrl_driver);
> --
> 2.30.2



From peng.fan at oss.nxp.com  Thu Aug  5 02:57:10 2021
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 5 Aug 2021 09:57:10 +0000
Subject: [PATCH v3 5/5] remoteproc: imx_rproc: change to ioremap_wc for
 dram
In-Reply-To: <20210805033206.1295269-5-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
 <20210805033206.1295269-5-aisheng.dong@nxp.com>
Message-ID: <AM5PR0402MB275630A505C7828931043F1988F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v3 5/5] remoteproc: imx_rproc: change to ioremap_wc for
> dram
> 
> DRAM is not io memory, so changed to ioremap_wc. This is also aligned with
> core io accessories. e.g. memcpy/memset and cpu direct access.
> 
> Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>

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

> ---
> v2->v3:
>  * patch content unchanged.
>    Only drop the wrong tag in v2
>    Tested on MX8MQ and MX8MP, MX7ULP.
> v1->v2:
>  * new patch
> ---
>  drivers/remoteproc/imx_rproc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c
> b/drivers/remoteproc/imx_rproc.c index ff620688fad9..4ae416ba5080
> 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -597,7 +597,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
>  			break;
> 
>  		/* Not use resource version, because we might share region */
> -		priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, res.start,
> resource_size(&res));
> +		priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
> res.start,
> +resource_size(&res));
>  		if (!priv->mem[b].cpu_addr) {
>  			dev_err(dev, "failed to remap %pr\n", &res);
>  			return -ENOMEM;
> --
> 2.25.1



From peng.fan at oss.nxp.com  Thu Aug  5 02:58:30 2021
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Thu, 5 Aug 2021 09:58:30 +0000
Subject: [PATCH v3 1/5] remoteproc: fix the wrong default value of is_iomem
In-Reply-To: <20210805033206.1295269-1-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
Message-ID: <AM5PR0402MB2756C145CA9BEF87B3A70CEA88F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v3 1/5] remoteproc: fix the wrong default value of is_iomem
> 
> Currently the is_iomem is a random value in the stack which may be default
> to true even on those platforms that not use iomem to store firmware.
> 
> Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Fixes: 40df0a91b2a5 ("remoteproc: add is_iomem to da_to_va")
> Reviewed-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>

Tested-by: Peng Fan <peng.fan at nxp.com>
with https://patchwork.kernel.org/project/linux-remoteproc/patch/20210629014752.5659-1-peng.fan at oss.nxp.com/

> ---
> v2->v3:
>  * no changes
> v1->v2:
>  * update rproc_copy_segment as well
> ---
>  drivers/remoteproc/remoteproc_coredump.c   | 2 +-
>  drivers/remoteproc/remoteproc_elf_loader.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/remoteproc/remoteproc_coredump.c
> b/drivers/remoteproc/remoteproc_coredump.c
> index aee657cc08c6..c892f433a323 100644
> --- a/drivers/remoteproc/remoteproc_coredump.c
> +++ b/drivers/remoteproc/remoteproc_coredump.c
> @@ -152,8 +152,8 @@ static void rproc_copy_segment(struct rproc *rproc,
> void *dest,
>  			       struct rproc_dump_segment *segment,
>  			       size_t offset, size_t size)
>  {
> +	bool is_iomem = false;
>  	void *ptr;
> -	bool is_iomem;
> 
>  	if (segment->dump) {
>  		segment->dump(rproc, segment, dest, offset, size); diff --git
> a/drivers/remoteproc/remoteproc_elf_loader.c
> b/drivers/remoteproc/remoteproc_elf_loader.c
> index e8078efb3dec..3cd1798f17a3 100644
> --- a/drivers/remoteproc/remoteproc_elf_loader.c
> +++ b/drivers/remoteproc/remoteproc_elf_loader.c
> @@ -178,8 +178,8 @@ int rproc_elf_load_segments(struct rproc *rproc,
> const struct firmware *fw)
>  		u64 filesz = elf_phdr_get_p_filesz(class, phdr);
>  		u64 offset = elf_phdr_get_p_offset(class, phdr);
>  		u32 type = elf_phdr_get_p_type(class, phdr);
> +		bool is_iomem = false;
>  		void *ptr;
> -		bool is_iomem;
> 
>  		if (type != PT_LOAD)
>  			continue;
> --
> 2.25.1



From peng.fan at nxp.com  Thu Aug  5 02:59:00 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:59:00 +0000
Subject: [PATCH v3 2/5] remoteproc: imx_rproc: fix TCM io memory type
In-Reply-To: <20210805033206.1295269-2-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
 <20210805033206.1295269-2-aisheng.dong@nxp.com>
Message-ID: <AM5PR0402MB2756DE75C3231A0A15F7742788F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v3 2/5] remoteproc: imx_rproc: fix TCM io memory type
> 
> is_iomem was introduced in the commit 40df0a91b2a5 ("remoteproc: add
> is_iomem to da_to_va"), but the driver seemed missed to provide the io type
> correctly.
> This patch updates remoteproc driver to indicate the TCM on IMX are io
> memories. Without the change, remoteproc kick will fail.
> 
> Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Peng Fan <peng.fan at nxp.com>
> Fixes: 79806d32d5aa ("remoteproc: imx_rproc: support i.MX8MN/P")
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>

Tested-by: Peng Fan <peng.fan at nxp.com>

> ---
> ChangeLog:
> v2->v3:
>  * fix commit message typo and drop imx8ulp fixes tag
>    Patch content unchanged.
> v1->v2:
>  * using ioremap_wc for non TCM memory
> ---
>  drivers/remoteproc/imx_rproc.c | 35 ++++++++++++++++++++--------------
>  1 file changed, 21 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c
> b/drivers/remoteproc/imx_rproc.c index d88f76f5305e..71dcc6dd32e4
> 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -71,6 +71,7 @@ struct imx_rproc_mem {
>  /* att flags */
>  /* M4 own area. Can be mapped at probe */
>  #define ATT_OWN		BIT(1)
> +#define ATT_IOMEM	BIT(2)
> 
>  /* address translation table */
>  struct imx_rproc_att {
> @@ -117,7 +118,7 @@ struct imx_rproc {
>  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
>  	/* dev addr , sys addr  , size	    , flags */
>  	/* ITCM   */
> -	{ 0x00000000, 0x007E0000, 0x00020000, ATT_OWN },
> +	{ 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
>  	/* OCRAM_S */
>  	{ 0x00180000, 0x00180000, 0x00009000, 0 },
>  	/* OCRAM */
> @@ -131,7 +132,7 @@ static const struct imx_rproc_att
> imx_rproc_att_imx8mn[] = {
>  	/* DDR (Code) - alias */
>  	{ 0x10000000, 0x40000000, 0x0FFE0000, 0 },
>  	/* DTCM */
> -	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
> +	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM },
>  	/* OCRAM_S - alias */
>  	{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
>  	/* OCRAM */
> @@ -147,7 +148,7 @@ static const struct imx_rproc_att
> imx_rproc_att_imx8mn[] = {  static const struct imx_rproc_att
> imx_rproc_att_imx8mq[] = {
>  	/* dev addr , sys addr  , size	    , flags */
>  	/* TCML - alias */
> -	{ 0x00000000, 0x007e0000, 0x00020000, 0 },
> +	{ 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM},
>  	/* OCRAM_S */
>  	{ 0x00180000, 0x00180000, 0x00008000, 0 },
>  	/* OCRAM */
> @@ -159,9 +160,9 @@ static const struct imx_rproc_att
> imx_rproc_att_imx8mq[] = {
>  	/* DDR (Code) - alias */
>  	{ 0x10000000, 0x80000000, 0x0FFE0000, 0 },
>  	/* TCML */
> -	{ 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN },
> +	{ 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN  | ATT_IOMEM},
>  	/* TCMU */
> -	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
> +	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN  | ATT_IOMEM},
>  	/* OCRAM_S */
>  	{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
>  	/* OCRAM */
> @@ -199,12 +200,12 @@ static const struct imx_rproc_att
> imx_rproc_att_imx7d[] = {
>  	/* OCRAM_PXP (Code) - alias */
>  	{ 0x00940000, 0x00940000, 0x00008000, 0 },
>  	/* TCML (Code) */
> -	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
> +	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
>  	/* DDR (Code) - alias, first part of DDR (Data) */
>  	{ 0x10000000, 0x80000000, 0x0FFF0000, 0 },
> 
>  	/* TCMU (Data) */
> -	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
> +	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
>  	/* OCRAM (Data) */
>  	{ 0x20200000, 0x00900000, 0x00020000, 0 },
>  	/* OCRAM_EPDC (Data) */
> @@ -218,18 +219,18 @@ static const struct imx_rproc_att
> imx_rproc_att_imx7d[] = {  static const struct imx_rproc_att
> imx_rproc_att_imx6sx[] = {
>  	/* dev addr , sys addr  , size	    , flags */
>  	/* TCML (M4 Boot Code) - alias */
> -	{ 0x00000000, 0x007F8000, 0x00008000, 0 },
> +	{ 0x00000000, 0x007F8000, 0x00008000, ATT_IOMEM },
>  	/* OCRAM_S (Code) */
>  	{ 0x00180000, 0x008F8000, 0x00004000, 0 },
>  	/* OCRAM_S (Code) - alias */
>  	{ 0x00180000, 0x008FC000, 0x00004000, 0 },
>  	/* TCML (Code) */
> -	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
> +	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
>  	/* DDR (Code) - alias, first part of DDR (Data) */
>  	{ 0x10000000, 0x80000000, 0x0FFF8000, 0 },
> 
>  	/* TCMU (Data) */
> -	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
> +	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
>  	/* OCRAM_S (Data) - alias? */
>  	{ 0x208F8000, 0x008F8000, 0x00004000, 0 },
>  	/* DDR (Data) */
> @@ -341,7 +342,7 @@ static int imx_rproc_stop(struct rproc *rproc)  }
> 
>  static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
> -			       size_t len, u64 *sys)
> +			       size_t len, u64 *sys, bool *is_iomem)
>  {
>  	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
>  	int i;
> @@ -354,6 +355,8 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv,
> u64 da,
>  			unsigned int offset = da - att->da;
> 
>  			*sys = att->sa + offset;
> +			if (is_iomem)
> +				*is_iomem = att->flags & ATT_IOMEM;
>  			return 0;
>  		}
>  	}
> @@ -377,7 +380,7 @@ static void *imx_rproc_da_to_va(struct rproc *rproc,
> u64 da, size_t len, bool *i
>  	 * On device side we have many aliases, so we need to convert device
>  	 * address (M4) to system bus address first.
>  	 */
> -	if (imx_rproc_da_to_sys(priv, da, len, &sys))
> +	if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem))
>  		return NULL;
> 
>  	for (i = 0; i < IMX_RPROC_MEM_MAX; i++) { @@ -553,8 +556,12 @@
> static int imx_rproc_addr_init(struct imx_rproc *priv,
>  		if (b >= IMX_RPROC_MEM_MAX)
>  			break;
> 
> -		priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
> -						     att->sa, att->size);
> +		if (att->flags & ATT_IOMEM)
> +			priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
> +							     att->sa, att->size);
> +		else
> +			priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
> +								att->sa, att->size);
>  		if (!priv->mem[b].cpu_addr) {
>  			dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size,
> att->sa);
>  			return -ENOMEM;
> --
> 2.25.1



From peng.fan at nxp.com  Thu Aug  5 02:59:15 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:59:15 +0000
Subject: [PATCH v3 3/5] remoteproc: imx_rproc: fix ignoring mapping vdev
 regions
In-Reply-To: <20210805033206.1295269-3-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
 <20210805033206.1295269-3-aisheng.dong@nxp.com>
Message-ID: <AM5PR0402MB2756ABF6B242CBB3F4FF10AE88F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v3 3/5] remoteproc: imx_rproc: fix ignoring mapping vdev
> regions
> 
> vdev regions are typically named vdev0buffer, vdev0ring0, vdev0ring1 and etc.
> Change to strncmp to cover them all.
> 
> Fixes: 8f2d8961640f ("remoteproc: imx_rproc: ignore mapping vdev regions")
> Reviewed-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>

Tested-by: Peng Fan <peng.fan at nxp.com>

> ---
> v1->v3:
>  * no changes
> ---
>  drivers/remoteproc/imx_rproc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c
> b/drivers/remoteproc/imx_rproc.c index 71dcc6dd32e4..abfeac0b1738
> 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -582,8 +582,8 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
>  		struct resource res;
> 
>  		node = of_parse_phandle(np, "memory-region", a);
> -		/* Not map vdev region */
> -		if (!strcmp(node->name, "vdev"))
> +		/* Not map vdevbuffer, vdevring region */
> +		if (!strncmp(node->name, "vdev", strlen("vdev")))
>  			continue;
>  		err = of_address_to_resource(node, 0, &res);
>  		if (err) {
> --
> 2.25.1



From peng.fan at nxp.com  Thu Aug  5 02:59:30 2021
From: peng.fan at nxp.com (Peng Fan)
Date: Thu, 5 Aug 2021 09:59:30 +0000
Subject: [PATCH v3 4/5] remoteproc: imx_rproc: fix rsc-table name
In-Reply-To: <20210805033206.1295269-4-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
 <20210805033206.1295269-4-aisheng.dong@nxp.com>
Message-ID: <AM5PR0402MB2756860A9D2C7C9D00447C7588F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>

> Subject: [PATCH v3 4/5] remoteproc: imx_rproc: fix rsc-table name
> 
> Usually the dash '-'  is preferred in node name.
> So far, not dts in upstream kernel, so we just update node name in driver.
> 
> Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Fixes: 5e4c1243071d ("remoteproc: imx_rproc: support remote cores booted
> before Linux Kernel")
> Reviewed-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>

Tested-by: Peng Fan <peng.fan at nxp.com>

> ---
> v1->v3:
>  * no changes
> ---
>  drivers/remoteproc/imx_rproc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c
> b/drivers/remoteproc/imx_rproc.c index abfeac0b1738..ff620688fad9
> 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -604,7 +604,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
>  		}
>  		priv->mem[b].sys_addr = res.start;
>  		priv->mem[b].size = resource_size(&res);
> -		if (!strcmp(node->name, "rsc_table"))
> +		if (!strcmp(node->name, "rsc-table"))
>  			priv->rsc_table = priv->mem[b].cpu_addr;
>  		b++;
>  	}
> --
> 2.25.1



From alim.akhtar at samsung.com  Thu Aug  5 02:54:32 2021
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 5 Aug 2021 15:24:32 +0530
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <4fc60199-44cd-41ea-9178-92b131d21b73@canonical.com>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
 <CGME20210805073653epcas5p21b4c2358b7de2b3c21dbc357af957137@epcas5p2.samsung.com>
 <b0d6ff2a-24af-96c1-62a1-8b920c63e05a@canonical.com>
 <03d701d789db$f275d290$d76177b0$@samsung.com>
 <7c019443-6153-f059-418b-3b268750f7a8@canonical.com>
 <4fc60199-44cd-41ea-9178-92b131d21b73@canonical.com>
Message-ID: <040901d789df$e5af4420$b10dcc60$@samsung.com>



> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Sent: 05 August 2021 15:15
> To: Alim Akhtar <alim.akhtar at samsung.com>; 'Rob Herring'
> <robh+dt at kernel.org>; devicetree at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
> kernel at vger.kernel.org
> Cc: 'Chanwoo Choi' <cw00.choi at samsung.com>; 'Pankaj Dubey'
> <pankaj.dubey at samsung.com>; 'Sam Protsenko'
> <semen.protsenko at linaro.org>; 'Marc Zyngier' <maz at kernel.org>
> Subject: Re: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
> range on Exynos7
> 
> On 05/08/2021 11:43, Krzysztof Kozlowski wrote:
> > On 05/08/2021 11:26, Alim Akhtar wrote:
> >> Hi Krzysztof,
> >>
> >>> -----Original Message-----
> >>> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >>> Sent: 05 August 2021 13:07
> >>> To: Rob Herring <robh+dt at kernel.org>; devicetree at vger.kernel.org;
> >>> linux- arm-kernel at lists.infradead.org;
> >>> linux-samsung-soc at vger.kernel.org; linux- kernel at vger.kernel.org
> >>> Cc: Alim Akhtar <alim.akhtar at samsung.com>; Chanwoo Choi
> >>> <cw00.choi at samsung.com>; Pankaj Dubey
> <pankaj.dubey at samsung.com>;
> >>> Sam Protsenko <semen.protsenko at linaro.org>; Marc Zyngier
> >>> <maz at kernel.org>
> >>> Subject: Re: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces
> >>> address range on Exynos7
> >>>
> >>> On 05/08/2021 09:21, Krzysztof Kozlowski wrote:
> >>>> The GIC-400 CPU interfaces address range is defined as
> >>>> 0x2000-0x3FFF (by ARM).
> >>>>
> >>>
> >> Looking at DDI0471B_gic400_r0p1_trm.pdf, CPU interface range is
> >> 0x0000 ~ 0x10000
> >>
> >>> I underestimated the issue - this is actually bug as there is a
> >>> GICC_DIR register at offset 0x1000. Therefore:
> >>>
> >> Looking at the exynos7 and exynos5433 UMs looks like GICC_DIR is at
> >> offset 0x2100 (from 0x1100_0000 GIC base) It is possible for you to cross
> check once?
> >>
> >
> > That's a mistake in Exynos manual. GICC_DIR is at 0x1000:
> 
> 0x1000 from CPU base offset, so 0x3000 from GIC base.
> 
> > https://developer.arm.com/documentation/ddi0471/b/programmers-
> model/cp
> > u-interface-register-summary
> >
> > We have discussion here:
> > https://lore.kernel.org/linux-samsung-soc/0277c701-cc25-cdc5-d3b9-cf2c
> >
> c2ba4de5 at canonical.com/T/#m1ced9a28bed27f5cf74e281fb68efe1b57d5609
> e
Thanks for pointing to this discussion, I missed this.
Agreed.
Feel Free to add
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

> >
> > Range of 0x10000 is definitely wrong as it overlaps with two other
> > ranges.
> 
> 
> Best regards,
> Krzysztof



From maz at kernel.org  Thu Aug  5 03:01:11 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 05 Aug 2021 11:01:11 +0100
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <03d701d789db$f275d290$d76177b0$@samsung.com>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
 <CGME20210805073653epcas5p21b4c2358b7de2b3c21dbc357af957137@epcas5p2.samsung.com>
 <b0d6ff2a-24af-96c1-62a1-8b920c63e05a@canonical.com>
 <03d701d789db$f275d290$d76177b0$@samsung.com>
Message-ID: <87tuk4b47s.wl-maz@kernel.org>

On Thu, 05 Aug 2021 10:26:14 +0100,
"Alim Akhtar" <alim.akhtar at samsung.com> wrote:
> 
> Hi Krzysztof,
> 
> > -----Original Message-----
> > From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > Sent: 05 August 2021 13:07
> > To: Rob Herring <robh+dt at kernel.org>; devicetree at vger.kernel.org; linux-
> > arm-kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
> > kernel at vger.kernel.org
> > Cc: Alim Akhtar <alim.akhtar at samsung.com>; Chanwoo Choi
> > <cw00.choi at samsung.com>; Pankaj Dubey <pankaj.dubey at samsung.com>;
> > Sam Protsenko <semen.protsenko at linaro.org>; Marc Zyngier
> > <maz at kernel.org>
> > Subject: Re: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
> > range on Exynos7
> > 
> > On 05/08/2021 09:21, Krzysztof Kozlowski wrote:
> > > The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF
> > > (by ARM).
> > >
> > 
> Looking at DDI0471B_gic400_r0p1_trm.pdf, CPU interface range is
> 0x0000 ~ 0x10000

I don't where you are getting this range from. The only 64kB range I'm
aware of is the optional integration trick to cope with 64kB pages
that was documented in the initial SBSA spec. The HW itself only
decodes 8kB for the CPU interface.

	M.

-- 
Without deviation from the norm, progress is not possible.


From michael at walle.cc  Thu Aug  5 03:01:15 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 05 Aug 2021 12:01:15 +0200
Subject: [PATCH v2 1/1] mfd: simple-mfd-i2c: Add support for registering
 devices via MFD cells
In-Reply-To: <20210805085611.864188-1-lee.jones@linaro.org>
References: <20210805085611.864188-1-lee.jones@linaro.org>
Message-ID: <ce1b71f317bff2dbcbf558e989b76087@walle.cc>

Am 2021-08-05 10:56, schrieb Lee Jones:
> More devices are cropping up requiring only Regmap initialisation and
> child registration functionality.  We currently only support that if
> all required devices are represented by their own Device Tree nodes
> complete with compatible strings.
> 
> However, not everyone is happy with adding empty nodes that provide no
> additional device information into the Device Tree.
> 
> Rather than have a plethora of mostly empty, function-less drivers in
> MFD, we'll support those simple cases in here instead via MFD cells.
> 
> Cc: Michael Walle <michael at walle.cc>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Alistair Francis <alistair23 at gmail.com>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>

Tested-by: Michael Walle <michael at walle.cc>

-michael


From andy.shevchenko at gmail.com  Thu Aug  5 03:16:14 2021
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Thu, 5 Aug 2021 13:16:14 +0300
Subject: [PATCH v4 0/3] Add ilitek ili9341 panel driver
In-Reply-To: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
References: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
Message-ID: <CAHp75Vc5fJM-UiBiosAiTraq=6P0AFefmw1rmtFcvyWVb6rfLA@mail.gmail.com>

On Sat, Jul 24, 2021 at 6:46 AM <dillon.minfei at gmail.com> wrote:
>
> From: Dillon Min <dillon.minfei at gmail.com>
>
> Since the st,sf-tc240t-9370-t dts binding already exist in stm32f429-disco.dts
> but, the panel driver didn't get accepted from mainline. it's time to submit
> patch fot it.
>
> This driver can support two different interface by different dts bindings:
> - spi+dpi, use spi to configure register, dpi for graphic data.
>   st,sf-tc240t-9370-t
> - only spi, just like tiny/ili9341.c (actually, this part is copy from tiny)
>   adafruit,yx240qv29

...

> I was submited the first patch last year, you can find it at [1].

submitted

> this patch has one major difference from that one, which is replace the low
> level communication way, from spi_sync() to mipi_dbi_{command,
> command_stackbuf}() interface, referred from Linus's patch [2].

Can you shed a light on the road map here.
I have the SPI panel (tiny) based on the ILI9341 and I'm using
actually mi0283qt driver. With yours we will have 3 (three!) drivers
for the same chip. I really do not want this. Without road map on the
prospective of these all drivers, NAK.

-- 
With Best Regards,
Andy Shevchenko


From frieder.schrempf at kontron.de  Thu Aug  5 03:18:22 2021
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Thu, 5 Aug 2021 12:18:22 +0200
Subject: [PATCH v2 00/18] i.MX8MM GPC improvements and BLK_CTRL driver
In-Reply-To: <20210721204703.1424034-1-l.stach@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
Message-ID: <818b52fe-8fa6-b47a-6dde-783ac378c603@kontron.de>

On 21.07.21 22:46, Lucas Stach wrote:
> Hi all,
> 
> second revision of the GPC improvements and BLK_CTRL driver to make use
> of all the power-domains on the i.MX8MM. I'm not going to repeat the full
> blurb from the v1 cover letter here, but if you are not familiar with
> i.MX8MM power domains, it may be worth a read.
> 
> This 2nd revision fixes the DT bindings to be valid yaml, some small
> failure path issues and most importantly the interaction with system
> suspend/resume. With the previous version some of the power domains
> would not come up correctly after a suspend/resume cycle.
> 
> Updated testing git trees here, disclaimer still applies:
> https://git.pengutronix.de/cgit/lst/linux/log/?h=imx8m-power-domains
> https://git.pengutronix.de/cgit/lst/linux/log/?h=imx8m-power-domains-testing

I finally did some tests on my side using USB, GPU and DSI (no PCIe, VPU, CSI so far) and the results are promising. Thanks for the effort!

I will try to run some more automated suspend/resume and reboot test cycles over the weekend and report the results here afterwards.


From john.garry at huawei.com  Thu Aug  5 03:22:15 2021
From: john.garry at huawei.com (John Garry)
Date: Thu, 5 Aug 2021 11:22:15 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Remove some unneeded init in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
References: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
Message-ID: <bebc7b1b-e60c-d5e6-812a-63580d7029cc@huawei.com>

On 21/06/2021 17:36, John Garry wrote:
> Members of struct "llq" will be zero-inited, apart from member max_n_shift.
> But we write llq.val straight after the init, so it was pointless to zero
> init those other members. As such, separately init member max_n_shift
> only.
> 
> In addition, struct "head" is initialised to "llq" only so that member
> max_n_shift is set. But that member is never referenced for "head", so
> remove any init there.
> 
> Removing these initializations is seen as a small performance optimisation,
> as this code is (very) hot path.
> 

Hi Will,

Any chance you can pick up this small optimisation?

Cheers

> Signed-off-by: John Garry <john.garry at huawei.com>
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 54b2f27b81d4..8a8ad49bb7fd 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -727,11 +727,11 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
>   	unsigned long flags;
>   	bool owner;
>   	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
> -	struct arm_smmu_ll_queue llq = {
> -		.max_n_shift = cmdq->q.llq.max_n_shift,
> -	}, head = llq;
> +	struct arm_smmu_ll_queue llq, head;
>   	int ret = 0;
>   
> +	llq.max_n_shift = cmdq->q.llq.max_n_shift;
> +
>   	/* 1. Allocate some space in the queue */
>   	local_irq_save(flags);
>   	llq.val = READ_ONCE(cmdq->q.llq.val);
> 



From dillon.minfei at gmail.com  Thu Aug  5 03:42:20 2021
From: dillon.minfei at gmail.com (Dillon Min)
Date: Thu, 5 Aug 2021 18:42:20 +0800
Subject: [PATCH v4 0/3] Add ilitek ili9341 panel driver
In-Reply-To: <CAHp75Vc5fJM-UiBiosAiTraq=6P0AFefmw1rmtFcvyWVb6rfLA@mail.gmail.com>
References: <1627098243-2742-1-git-send-email-dillon.minfei@gmail.com>
 <CAHp75Vc5fJM-UiBiosAiTraq=6P0AFefmw1rmtFcvyWVb6rfLA@mail.gmail.com>
Message-ID: <CAL9mu0+_fTTS8rBv63-PQ0H1M=yg4EtZwYXqORNRhHL0U8_KxA@mail.gmail.com>

Hi Andy

Thanks for your question.

On Thu, 5 Aug 2021 at 18:16, Andy Shevchenko <andy.shevchenko at gmail.com> wrote:
>
> On Sat, Jul 24, 2021 at 6:46 AM <dillon.minfei at gmail.com> wrote:
> >
> > From: Dillon Min <dillon.minfei at gmail.com>
> >
> > Since the st,sf-tc240t-9370-t dts binding already exist in stm32f429-disco.dts
> > but, the panel driver didn't get accepted from mainline. it's time to submit
> > patch fot it.
> >
> > This driver can support two different interface by different dts bindings:
> > - spi+dpi, use spi to configure register, dpi for graphic data.
> >   st,sf-tc240t-9370-t
> > - only spi, just like tiny/ili9341.c (actually, this part is copy from tiny)
> >   adafruit,yx240qv29
>
> ...
>
> > I was submited the first patch last year, you can find it at [1].
>
> submitted

Thanks.

>
> > this patch has one major difference from that one, which is replace the low
> > level communication way, from spi_sync() to mipi_dbi_{command,
> > command_stackbuf}() interface, referred from Linus's patch [2].
>
> Can you shed a light on the road map here.

Personally, I'd like to merge tiny/mi0283qt.c, tiny/ili9341.c(already
done) into this driver later
(keep original author, copyright, dts compatible string).
then remove these two drivers under tiny, but it's up to Sam and
Laurent agreement.

For long term, just like Peter suggested, let all panel based on
ili9xxx with single-dbi or dbi & dpi interface to be supported by
single ilitek-ili9xxx.c, something like panel/panel-simple.c
 (panel/panel-ilitek-ili9322c, tiny/ili9225.c, tiny/ili9486.c,
tiny/mi0283qt.c, etc).
it's also needs maintainers permission.

> I have the SPI panel (tiny) based on the ILI9341 and I'm using
> actually mi0283qt driver. With yours we will have 3 (three!) drivers
> for the same chip. I really do not want this. Without road map on the
> prospective of these all drivers, NAK.

Yes, it will make users confused if there are three different drivers
for the same chip.
I'll continue to work on this driver.

Thanks again for point this out.

Best Regards
Dillon

>
> --
> With Best Regards,
> Andy Shevchenko


From cristian.marussi at arm.com  Thu Aug  5 03:54:27 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Thu, 5 Aug 2021 11:54:27 +0100
Subject: [PATCH v3] firmware: arm_scmi: Free mailbox channels if probe
 fails
In-Reply-To: <1628111999-21595-1-git-send-email-rishabhb@codeaurora.org>
References: <1628111999-21595-1-git-send-email-rishabhb@codeaurora.org>
Message-ID: <20210805105427.GU6592@e120937-lin>

On Wed, Aug 04, 2021 at 02:19:59PM -0700, Rishabh Bhatnagar wrote:
> Mailbox channels for the base protocol are setup during probe.
> There can be a scenario where probe fails to acquire the base
> protocol due to a timeout leading to cleaning up of all device
> managed memory including the scmi_mailbox structure setup during
> mailbox_chan_setup function.
> [   12.735104]arm-scmi soc:qcom,scmi: timed out in resp(caller: version_get+0x84/0x140)
> [   12.735224]arm-scmi soc:qcom,scmi: unable to communicate with SCMI
> [   12.735947]arm-scmi: probe of soc:qcom,scmi failed with error -110
> 
> Now when a message arrives at cpu slightly after the timeout, the mailbox
> controller will try to call the rx_callback of the client and might end
> up accessing freed memory.
> [   12.758363][    C0] Call trace:
> [   12.758367][    C0]  rx_callback+0x24/0x160
> [   12.758372][    C0]  mbox_chan_received_data+0x44/0x94
> [   12.758386][    C0]  __handle_irq_event_percpu+0xd4/0x240
> This patch frees the mailbox channels setup during probe and adds some more
> error handling in case the probe fails.
> 
> Signed-off-by: Rishabh Bhatnagar <rishabhb at codeaurora.org>
> ---
>  drivers/firmware/arm_scmi/driver.c | 35 ++++++++++++++++++++++++-----------
>  1 file changed, 24 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index 9b2e8d4..ead3bd3 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -1390,6 +1390,21 @@ void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table)
>  	mutex_unlock(&scmi_requested_devices_mtx);
>  }
>  

Hi,

> +static int scmi_cleanup_txrx_channels(struct scmi_info *info)
> +{
> +	int ret;
> +	struct idr *idr = &info->tx_idr;
> +
> +	ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
> +	idr_destroy(&info->tx_idr);
> +
> +	idr = &info->rx_idr;
> +	ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
> +	idr_destroy(&info->rx_idr);
> +
> +	return ret;
> +}
> +
>  static int scmi_probe(struct platform_device *pdev)
>  {
>  	int ret;
> @@ -1430,7 +1445,7 @@ static int scmi_probe(struct platform_device *pdev)
>  
>  	ret = scmi_xfer_info_init(info);
>  	if (ret)
> -		return ret;
> +		goto clear_txrx_setup;
>  
>  	if (scmi_notification_init(handle))
>  		dev_err(dev, "SCMI Notifications NOT available.\n");
> @@ -1443,7 +1458,7 @@ static int scmi_probe(struct platform_device *pdev)
>  	ret = scmi_protocol_acquire(handle, SCMI_PROTOCOL_BASE);
>  	if (ret) {
>  		dev_err(dev, "unable to communicate with SCMI\n");
> -		return ret;
> +		goto notification_exit;
>  	}
>  
>  	mutex_lock(&scmi_list_mutex);
> @@ -1482,6 +1497,12 @@ static int scmi_probe(struct platform_device *pdev)
>  	}
>  
>  	return 0;
> +
> +notification_exit:
> +	scmi_notification_exit(&info->handle);
> +clear_txrx_setup:
> +	scmi_cleanup_txrx_channels(info);
> +	return ret;
>  }
>  
>  void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id)
> @@ -1493,7 +1514,6 @@ static int scmi_remove(struct platform_device *pdev)
>  {
>  	int ret = 0, id;
>  	struct scmi_info *info = platform_get_drvdata(pdev);
> -	struct idr *idr = &info->tx_idr;
>  	struct device_node *child;
>  
>  	mutex_lock(&scmi_list_mutex);
> @@ -1517,14 +1537,7 @@ static int scmi_remove(struct platform_device *pdev)
>  	idr_destroy(&info->active_protocols);
>  
>  	/* Safe to free channels since no more users */
> -	ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
> -	idr_destroy(&info->tx_idr);
> -
> -	idr = &info->rx_idr;
> -	ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
> -	idr_destroy(&info->rx_idr);
> -
> -	return ret;
> +	return scmi_cleanup_txrx_channels(info);
>  }
>  

Looks good to me.

Reviewed-by: Cristian Marussi <cristian.marussi at arm.com>
Tested-by: Cristian Marussi <cristian.marussi at arm.com>
(Re-tested on for-next/scmi on top of virtio-scmi series)

Thanks,
Cristian


From lorenzo.pieralisi at arm.com  Thu Aug  5 03:59:08 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 5 Aug 2021 11:59:08 +0100
Subject: [PATCH v5 2/3] PCI: visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <20210723221421.113575-3-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210723221421.113575-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210723221421.113575-3-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20210805105908.GA19244@lpieralisi>

On Sat, Jul 24, 2021 at 07:14:20AM +0900, Nobuhiro Iwamatsu wrote:
> Add support to PCIe RC controller on Toshiba Visconti ARM SoCs. PCIe
> controller is based of Synopsys DesignWare PCIe core.
> 
> This patch does not yet use the clock framework to control the clock.
> This will be replaced in the future.

This is not relevant information. I expect the commit log to describe
the change and the reasons behind the choices.

Speaking of which, I'd like to understand what

> This patch does not yet use the clock framework to control the clock.

means and why it can't be done within this series.

> Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> 
> ---
>  drivers/pci/controller/dwc/Kconfig         |   9 +
>  drivers/pci/controller/dwc/Makefile        |   1 +
>  drivers/pci/controller/dwc/pcie-visconti.c | 333 +++++++++++++++++++++
>  3 files changed, 343 insertions(+)
>  create mode 100644 drivers/pci/controller/dwc/pcie-visconti.c
> 
> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> index 423d35872ce4..7c3dcb86fcad 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -286,6 +286,15 @@ config PCIE_TEGRA194_EP
>  	  in order to enable device-specific features PCIE_TEGRA194_EP must be
>  	  selected. This uses the DesignWare core.
>  
> +config PCIE_VISCONTI_HOST
> +	bool "Toshiba Visconti PCIe controllers"
> +	depends on ARCH_VISCONTI || COMPILE_TEST
> +	depends on PCI_MSI_IRQ_DOMAIN
> +	select PCIE_DW_HOST
> +	help
> +	  Say Y here if you want PCIe controller support on Toshiba Visconti SoC.
> +	  This driver supports TMPV7708 SoC.
> +
>  config PCIE_UNIPHIER
>  	bool "Socionext UniPhier PCIe host controllers"
>  	depends on ARCH_UNIPHIER || COMPILE_TEST
> diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> index eca805c1a023..0b569d54deb3 100644
> --- a/drivers/pci/controller/dwc/Makefile
> +++ b/drivers/pci/controller/dwc/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
>  obj-$(CONFIG_PCI_MESON) += pci-meson.o
>  obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
>  obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
> +obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o
>  
>  # The following drivers are for devices that use the generic ACPI
>  # pci_root.c driver but don't support standard ECAM config access.
> diff --git a/drivers/pci/controller/dwc/pcie-visconti.c b/drivers/pci/controller/dwc/pcie-visconti.c
> new file mode 100644
> index 000000000000..f01a670cdf5d
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-visconti.c
> @@ -0,0 +1,333 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * DWC PCIe RC driver for Toshiba Visconti ARM SoC
> + *
> + * Copyright (C) 2021 Toshiba Electronic Device & Storage Corporation
> + * Copyright (C) 2021 TOSHIBA CORPORATION
> + *
> + * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/interrupt.h>
> +#include <linux/init.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/of_platform.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/resource.h>
> +#include <linux/types.h>
> +
> +#include "pcie-designware.h"
> +#include "../../pci.h"
> +
> +struct visconti_pcie {
> +	struct dw_pcie pci;
> +	void __iomem *ulreg_base;
> +	void __iomem *smu_base;
> +	void __iomem *mpu_base;
> +	struct clk *refclk;
> +	struct clk *coreclk;
> +	struct clk *auxclk;
> +};
> +
> +#define PCIE_UL_REG_S_PCIE_MODE		0x00F4
> +#define  PCIE_UL_REG_S_PCIE_MODE_EP	0x00
> +#define  PCIE_UL_REG_S_PCIE_MODE_RC	0x04
> +
> +#define PCIE_UL_REG_S_PERSTN_CTRL	0x00F8
> +#define  PCIE_UL_IOM_PCIE_PERSTN_I_EN	BIT(3)
> +#define  PCIE_UL_DIRECT_PERSTN_EN	BIT(2)
> +#define  PCIE_UL_PERSTN_OUT		BIT(1)
> +#define  PCIE_UL_DIRECT_PERSTN		BIT(0)
> +#define  PCIE_UL_REG_S_PERSTN_CTRL_INIT	(PCIE_UL_IOM_PCIE_PERSTN_I_EN | \
> +					 PCIE_UL_DIRECT_PERSTN_EN | \
> +					 PCIE_UL_DIRECT_PERSTN)
> +
> +#define PCIE_UL_REG_S_PHY_INIT_02	0x0104
> +#define  PCIE_UL_PHY0_SRAM_EXT_LD_DONE	BIT(0)
> +
> +#define PCIE_UL_REG_S_PHY_INIT_03	0x0108
> +#define  PCIE_UL_PHY0_SRAM_INIT_DONE	BIT(0)
> +
> +#define PCIE_UL_REG_S_INT_EVENT_MASK1	0x0138
> +#define  PCIE_UL_CFG_PME_INT		BIT(0)
> +#define  PCIE_UL_CFG_LINK_EQ_REQ_INT	BIT(1)
> +#define  PCIE_UL_EDMA_INT0		BIT(2)
> +#define  PCIE_UL_EDMA_INT1		BIT(3)
> +#define  PCIE_UL_EDMA_INT2		BIT(4)
> +#define  PCIE_UL_EDMA_INT3		BIT(5)
> +#define  PCIE_UL_S_INT_EVENT_MASK1_ALL  (PCIE_UL_CFG_PME_INT | \
> +					 PCIE_UL_CFG_LINK_EQ_REQ_INT | \
> +					 PCIE_UL_EDMA_INT0 | \
> +					 PCIE_UL_EDMA_INT1 | \
> +					 PCIE_UL_EDMA_INT2 | \
> +					 PCIE_UL_EDMA_INT3)
> +
> +#define PCIE_UL_REG_S_SB_MON		0x0198
> +#define PCIE_UL_REG_S_SIG_MON		0x019C
> +#define  PCIE_UL_CORE_RST_N_MON		BIT(0)
> +
> +#define PCIE_UL_REG_V_SII_DBG_00	0x0844
> +#define PCIE_UL_REG_V_SII_GEN_CTRL_01	0x0860
> +#define  PCIE_UL_APP_LTSSM_ENABLE	BIT(0)
> +
> +#define PCIE_UL_REG_V_PHY_ST_00		0x0864
> +#define  PCIE_UL_SMLH_LINK_UP		BIT(0)
> +
> +#define PCIE_UL_REG_V_PHY_ST_02		0x0868
> +#define  PCIE_UL_S_DETECT_ACT		0x01
> +#define  PCIE_UL_S_L0			0x11
> +
> +#define PISMU_CKON_PCIE			0x0038
> +#define  PISMU_CKON_PCIE_AUX_CLK	BIT(1)
> +#define  PISMU_CKON_PCIE_MSTR_ACLK	BIT(0)
> +
> +#define PISMU_RSOFF_PCIE		0x0538
> +#define  PISMU_RSOFF_PCIE_ULREG_RST_N	BIT(1)
> +#define  PISMU_RSOFF_PCIE_PWR_UP_RST_N	BIT(0)
> +
> +#define PCIE_MPU_REG_MP_EN		0x0
> +#define  MPU_MP_EN_DISABLE		BIT(0)
> +
> +/* Access registers in PCIe ulreg */
> +static void visconti_ulreg_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
> +{
> +	writel_relaxed(val, pcie->ulreg_base + reg);
> +}
> +
> +static u32 visconti_ulreg_readl(struct visconti_pcie *pcie, u32 reg)
> +{
> +	return readl_relaxed(pcie->ulreg_base + reg);
> +}
> +
> +/* Access registers in PCIe smu */
> +static void visconti_smu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
> +{
> +	writel_relaxed(val, pcie->smu_base + reg);
> +}
> +
> +/* Access registers in PCIe mpu */
> +static void visconti_mpu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
> +{
> +	writel_relaxed(val, pcie->mpu_base + reg);
> +}
> +
> +static u32 visconti_mpu_readl(struct visconti_pcie *pcie, u32 reg)
> +{
> +	return readl_relaxed(pcie->mpu_base + reg);
> +}
> +
> +static int visconti_pcie_link_up(struct dw_pcie *pci)
> +{
> +	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
> +	void __iomem *addr = pcie->ulreg_base;
> +	u32 val = readl_relaxed(addr + PCIE_UL_REG_V_PHY_ST_02);
> +
> +	return !!(val & PCIE_UL_S_L0);
> +}
> +
> +static int visconti_pcie_start_link(struct dw_pcie *pci)
> +{
> +	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
> +	void __iomem *addr = pcie->ulreg_base;
> +	u32 val;
> +	int ret;
> +
> +	visconti_ulreg_writel(pcie, PCIE_UL_APP_LTSSM_ENABLE,
> +			      PCIE_UL_REG_V_SII_GEN_CTRL_01);
> +
> +	ret = readl_relaxed_poll_timeout(addr + PCIE_UL_REG_V_PHY_ST_02,
> +					 val, (val & PCIE_UL_S_L0),
> +					 90000, 100000);
> +	if (ret)
> +		return ret;
> +
> +	visconti_ulreg_writel(pcie, PCIE_UL_S_INT_EVENT_MASK1_ALL,
> +			      PCIE_UL_REG_S_INT_EVENT_MASK1);
> +
> +	if (dw_pcie_link_up(pci)) {
> +		val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
> +		visconti_mpu_writel(pcie, val & ~MPU_MP_EN_DISABLE,
> +				    PCIE_MPU_REG_MP_EN);
> +	}
> +
> +	return 0;
> +}
> +
> +static void visconti_pcie_stop_link(struct dw_pcie *pci)
> +{
> +	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
> +	u32 val;
> +
> +	val = visconti_ulreg_readl(pcie, PCIE_UL_REG_V_SII_GEN_CTRL_01);
> +	val &= ~PCIE_UL_APP_LTSSM_ENABLE;
> +	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_V_SII_GEN_CTRL_01);
> +
> +	val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
> +	visconti_mpu_writel(pcie, val | MPU_MP_EN_DISABLE, PCIE_MPU_REG_MP_EN);
> +}
> +
> +/*
> + * In this SoC specification, the CPU bus outputs the offset value from
> + * 0x40000000 to the PCIE bus, so 0x40000000 is subtracted from the CPU
> + * bus address. This 0x40000000 is also based on io_base from DT.
> + */
> +static u64 visconti_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 cpu_addr)
> +{
> +	struct pcie_port *pp = &pci->pp;
> +
> +	return cpu_addr & ~pp->io_base;
> +}
> +
> +static const struct dw_pcie_ops dw_pcie_ops = {
> +	.cpu_addr_fixup = visconti_pcie_cpu_addr_fixup,
> +	.link_up = visconti_pcie_link_up,
> +	.start_link = visconti_pcie_start_link,
> +	.stop_link = visconti_pcie_stop_link,
> +};
> +
> +static int visconti_pcie_host_init(struct pcie_port *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
> +	void __iomem *addr;
> +	int err;
> +	u32 val;
> +
> +	visconti_smu_writel(pcie,
> +			    PISMU_CKON_PCIE_AUX_CLK | PISMU_CKON_PCIE_MSTR_ACLK,
> +			    PISMU_CKON_PCIE);
> +	ndelay(250);
> +
> +	visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_ULREG_RST_N,
> +			    PISMU_RSOFF_PCIE);
> +	visconti_ulreg_writel(pcie, PCIE_UL_REG_S_PCIE_MODE_RC,
> +			      PCIE_UL_REG_S_PCIE_MODE);
> +
> +	val = PCIE_UL_REG_S_PERSTN_CTRL_INIT;
> +	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
> +	udelay(100);
> +
> +	val |= PCIE_UL_PERSTN_OUT;
> +	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
> +	udelay(100);
> +
> +	visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_PWR_UP_RST_N,
> +			    PISMU_RSOFF_PCIE);
> +
> +	addr = pcie->ulreg_base + PCIE_UL_REG_S_PHY_INIT_03;
> +	err = readl_relaxed_poll_timeout(addr, val,
> +					 (val & PCIE_UL_PHY0_SRAM_INIT_DONE),
> +					 100, 1000);
> +	if (err)
> +		return err;
> +
> +	visconti_ulreg_writel(pcie, PCIE_UL_PHY0_SRAM_EXT_LD_DONE,
> +			      PCIE_UL_REG_S_PHY_INIT_02);
> +
> +	addr = pcie->ulreg_base + PCIE_UL_REG_S_SIG_MON;
> +	return readl_relaxed_poll_timeout(addr, val,
> +					  (val & PCIE_UL_CORE_RST_N_MON), 100,
> +					  1000);
> +}
> +
> +static const struct dw_pcie_host_ops visconti_pcie_host_ops = {
> +	.host_init = visconti_pcie_host_init,
> +};
> +
> +static int visconti_get_resources(struct platform_device *pdev,
> +				  struct visconti_pcie *pcie)
> +{
> +	struct device *dev = &pdev->dev;
> +
> +	pcie->ulreg_base = devm_platform_ioremap_resource_byname(pdev, "ulreg");
> +	if (IS_ERR(pcie->ulreg_base))
> +		return PTR_ERR(pcie->ulreg_base);
> +
> +	pcie->smu_base = devm_platform_ioremap_resource_byname(pdev, "smu");
> +	if (IS_ERR(pcie->smu_base))
> +		return PTR_ERR(pcie->smu_base);
> +
> +	pcie->mpu_base = devm_platform_ioremap_resource_byname(pdev, "mpu");
> +	if (IS_ERR(pcie->mpu_base))
> +		return PTR_ERR(pcie->mpu_base);
> +
> +	pcie->refclk = devm_clk_get(dev, "ref");
> +	if (IS_ERR(pcie->refclk))
> +		return dev_err_probe(dev, PTR_ERR(pcie->refclk),
> +				     "Failed to get ref clock\n");
> +
> +	pcie->coreclk = devm_clk_get(dev, "core");
> +	if (IS_ERR(pcie->coreclk))
> +		return dev_err_probe(dev, PTR_ERR(pcie->coreclk),
> +				     "Failed to get core clock\n");
> +
> +	pcie->auxclk = devm_clk_get(dev, "aux");
> +	if (IS_ERR(pcie->auxclk))
> +		return dev_err_probe(dev, PTR_ERR(pcie->auxclk),
> +				     "Failed to get aux clock\n");
> +
> +	return 0;
> +}
> +
> +static int
> +visconti_add_pcie_port(struct visconti_pcie *pcie, struct platform_device *pdev)

Nit: don't split lines like this, it is better to keep return value
type and function name in one single line.

Do it like this:

static int visconti_add_pcie_port(struct visconti_pcie *pcie,
 				  struct platform_device *pdev)

Lorenzo

> +{
> +	struct dw_pcie *pci = &pcie->pci;
> +	struct pcie_port *pp = &pci->pp;
> +	struct device *dev = &pdev->dev;
> +
> +	pp->irq = platform_get_irq_byname(pdev, "intr");
> +	if (pp->irq < 0) {
> +		dev_err(dev, "Interrupt intr is missing");
> +		return pp->irq;
> +	}
> +
> +	pp->ops = &visconti_pcie_host_ops;
> +
> +	return dw_pcie_host_init(pp);
> +}
> +
> +static int visconti_pcie_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct visconti_pcie *pcie;
> +	struct dw_pcie *pci;
> +	int ret;
> +
> +	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	pci = &pcie->pci;
> +	pci->dev = dev;
> +	pci->ops = &dw_pcie_ops;
> +
> +	ret = visconti_get_resources(pdev, pcie);
> +	if (ret)
> +		return ret;
> +
> +	platform_set_drvdata(pdev, pcie);
> +
> +	return visconti_add_pcie_port(pcie, pdev);
> +}
> +
> +static const struct of_device_id visconti_pcie_match[] = {
> +	{ .compatible = "toshiba,visconti-pcie" },
> +	{},
> +};
> +
> +static struct platform_driver visconti_pcie_driver = {
> +	.probe = visconti_pcie_probe,
> +	.driver = {
> +		.name = "visconti-pcie",
> +		.of_match_table = visconti_pcie_match,
> +		.suppress_bind_attrs = true,
> +	},
> +};
> +
> +builtin_platform_driver(visconti_pcie_driver);
> -- 
> 2.32.0
> 
> 


From leo.yan at linaro.org  Thu Aug  5 03:59:26 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Thu, 5 Aug 2021 18:59:26 +0800
Subject: [PATCH 5/6] perf cs-etm: Create ETE decoder
In-Reply-To: <654cf3ae-325b-49c9-a9d0-ebf704a83d6f@arm.com>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-6-james.clark@arm.com>
 <20210731072341.GE7437@leoy-ThinkPad-X240s>
 <654cf3ae-325b-49c9-a9d0-ebf704a83d6f@arm.com>
Message-ID: <20210805105926.GA22454@leoy-ThinkPad-X240s>

On Tue, Aug 03, 2021 at 02:09:38PM +0100, James Clark wrote:

[...]

> >> -static enum _ocsd_arch_version cs_etm_decoder__get_arch_ver(u32 reg_idr1)
> >> +static enum _ocsd_arch_version cs_etm_decoder__get_arch_ver(u32 reg_idr1, u32 reg_devarch)
> >>  {
> >> +	/* ETE has to be v9 so set arch version to v8.3+ (ARCH__AA64) */
> >> +	if (cs_etm__is_ete(reg_devarch))
> >> +		return ARCH_AA64;
> >> +
> > 
> > Based on values used in below change, I think we can unify the ETM
> > versio number like:
> > 
> >   ARCH_V8R3 : REVISION, bits[19:16] is 0x3
> >   ARCH_V8R4 : REVISION, bits[19:16] is 0x4
> >   ARCH_V8R5 : REVISION, bits[19:16] is 0x5
> 
> Do you mean make this change in OpenCSD? At the moment it understands these
> values so I'm not sure if the extra ones would be useful:

Yes.  As Mike said, these new macros will cause big changes in OpenCSD,
so I don't have strong opinion to add more macros for tracer versions.

> >> +struct cs_ete_trace_params {
> >> +	struct cs_etmv4_trace_params base_params;
> >> +	u32 reg_devarch;
> > 
> > As we have said, can we directly support ETMv4.5, so that it can
> > smoothly support ETE features?  If so, we don't need to add a new
> > structure "cs_ete_trace_params" at here.
> > 
> 
> I think with the new magic number change this is more likely to stay,
> what are your thoughts?

Agreed.  Just wander if need to define the struct cs_ete_trace_params
as below?

  struct cs_ete_trace_params {
          u32 reg_idr0;
          u32 reg_idr1;
          u32 reg_idr2;
          u32 reg_idr8;
          u32 reg_configr;
          u32 reg_traceidr;
          u32 reg_devarch;
  }

> >> +
> >> +#define TRCDEVARCH_ARCHPART_SHIFT 0
> >> +#define TRCDEVARCH_ARCHPART_MASK  GENMASK(11, 0)
> >> +#define TRCDEVARCH_ARCHPART(x)    (((x) & TRCDEVARCH_ARCHPART_MASK) >> TRCDEVARCH_ARCHPART_SHIFT)
> >> +
> >> +#define TRCDEVARCH_ARCHVER_SHIFT 12
> >> +#define TRCDEVARCH_ARCHVER_MASK  GENMASK(15, 12)
> >> +#define TRCDEVARCH_ARCHVER(x)    (((x) & TRCDEVARCH_ARCHVER_MASK) >> TRCDEVARCH_ARCHVER_SHIFT)
> >> +
> >> +bool cs_etm__is_ete(u32 trcdevarch)
> >> +{
> >> +	/*
> >> +	 * ETE if ARCHVER is 5 (ARCHVER is 4 for ETM) and ARCHPART is 0xA13.
> >> +	 * See ETM_DEVARCH_ETE_ARCH in coresight-etm4x.h
> >> +	 */
> >> +	return TRCDEVARCH_ARCHVER(trcdevarch) == 5 && TRCDEVARCH_ARCHPART(trcdevarch) == 0xA13;
> > 
> > I think this is incorrect.
> > 
> > Here should check the bit field "REVISION, bits[19:16]".  If it's
> > field value is >= 5, then we can say it supports ETE.  I checked the
> > spec for ETMv4.4 and ETMv4.6, both use the same values for the
> > Bits[15:12] = 0x4, so the architecture ID is same for ETMv4.x IPs.
> > 
> 
> I tried to copy this as closely as possible from the ETE driver. See in coresight-etm4x.h
> 
> 	#define ETM_DEVARCH_ETE_ARCH						\
> 		(ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETE | ETM_DEVARCH_PRESENT) 
> 
> Where ETM_DEVARCH_ARCHID_ETE is ARCHVER == 5 and ARCHPART == 0xA13. I didn't check 
> ETM_DEVARCH_ARCHITECT_ARM because I thought that wouldn't be necessary. If we want to make
> the change do detect >= 5 then I think this should be made in the driver first. @Suzuki,
> what do you think?

The tracer has two fields:

- ARCHID bits[15:12]
- REVISION, bits[19:16]

For ETE its ARCHID[15:12] is 0x5 and ETMv4.x's ARCHID[15:12] is 0x4.
So checking ARCHID[15:12] is the right way to distinguish if the
tracer is ETE and creates corresponding decoder for it.

When reviewed this patch I assumed we also need to create ETE decoder
if ETMv4.x has supported packet extension.  As Mike confirmed, all
ETMv4.x tracers keep to use existed way to create decoder; so it's not
necessary to check REVISION bit field.

So please ignore my this comment.

Thanks,
Leo


From lee.jones at linaro.org  Thu Aug  5 04:03:28 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 5 Aug 2021 12:03:28 +0100
Subject: [PATCH v2 1/1] mfd: simple-mfd-i2c: Add support for registering
 devices via MFD cells
In-Reply-To: <ce1b71f317bff2dbcbf558e989b76087@walle.cc>
References: <20210805085611.864188-1-lee.jones@linaro.org>
 <ce1b71f317bff2dbcbf558e989b76087@walle.cc>
Message-ID: <YQvFgMcwv7J5x2L4@google.com>

On Thu, 05 Aug 2021, Michael Walle wrote:

> Am 2021-08-05 10:56, schrieb Lee Jones:
> > More devices are cropping up requiring only Regmap initialisation and
> > child registration functionality.  We currently only support that if
> > all required devices are represented by their own Device Tree nodes
> > complete with compatible strings.
> > 
> > However, not everyone is happy with adding empty nodes that provide no
> > additional device information into the Device Tree.
> > 
> > Rather than have a plethora of mostly empty, function-less drivers in
> > MFD, we'll support those simple cases in here instead via MFD cells.
> > 
> > Cc: Michael Walle <michael at walle.cc>
> > Cc: Mark Brown <broonie at kernel.org>
> > Cc: Alistair Francis <alistair23 at gmail.com>
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> 
> Tested-by: Michael Walle <michael at walle.cc>

Good man.  Thank you Michael.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From alim.akhtar at samsung.com  Thu Aug  5 03:51:29 2021
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 5 Aug 2021 16:21:29 +0530
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <87tuk4b47s.wl-maz@kernel.org>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
 <CGME20210805073653epcas5p21b4c2358b7de2b3c21dbc357af957137@epcas5p2.samsung.com>
 <b0d6ff2a-24af-96c1-62a1-8b920c63e05a@canonical.com>
 <03d701d789db$f275d290$d76177b0$@samsung.com> <87tuk4b47s.wl-maz@kernel.org>
Message-ID: <044601d789e7$da54a4f0$8efdeed0$@samsung.com>



> -----Original Message-----
> From: Marc Zyngier <maz at kernel.org>
> Sent: 05 August 2021 15:31
> To: Alim Akhtar <alim.akhtar at samsung.com>
> Cc: 'Krzysztof Kozlowski' <krzysztof.kozlowski at canonical.com>; 'Rob
Herring'
> <robh+dt at kernel.org>; devicetree at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
> kernel at vger.kernel.org; 'Chanwoo Choi' <cw00.choi at samsung.com>;
> 'Pankaj Dubey' <pankaj.dubey at samsung.com>; 'Sam Protsenko'
> <semen.protsenko at linaro.org>
> Subject: Re: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces
address
> range on Exynos7
> 
> On Thu, 05 Aug 2021 10:26:14 +0100,
> "Alim Akhtar" <alim.akhtar at samsung.com> wrote:
> >
> > Hi Krzysztof,
> >
> > > -----Original Message-----
> > > From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > > Sent: 05 August 2021 13:07
> > > To: Rob Herring <robh+dt at kernel.org>; devicetree at vger.kernel.org;
> > > linux- arm-kernel at lists.infradead.org;
> > > linux-samsung-soc at vger.kernel.org; linux- kernel at vger.kernel.org
> > > Cc: Alim Akhtar <alim.akhtar at samsung.com>; Chanwoo Choi
> > > <cw00.choi at samsung.com>; Pankaj Dubey
> <pankaj.dubey at samsung.com>;
> > > Sam Protsenko <semen.protsenko at linaro.org>; Marc Zyngier
> > > <maz at kernel.org>
> > > Subject: Re: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces
> > > address range on Exynos7
> > >
> > > On 05/08/2021 09:21, Krzysztof Kozlowski wrote:
> > > > The GIC-400 CPU interfaces address range is defined as
> > > > 0x2000-0x3FFF (by ARM).
> > > >
> > >
> > Looking at DDI0471B_gic400_r0p1_trm.pdf, CPU interface range is
> > 0x0000 ~ 0x10000
> 
> I don't where you are getting this range from. The only 64kB range I'm
aware
> of is the optional integration trick to cope with 64kB pages that was
> documented in the initial SBSA spec. The HW itself only decodes 8kB for
the
> CPU interface.
> 
There was a typo in above range, thanks for the clarification. Got it.

> 	M.
> 
> --
> Without deviation from the norm, progress is not possible.



From gregkh at linuxfoundation.org  Thu Aug  5 04:16:35 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 5 Aug 2021 13:16:35 +0200
Subject: [PATCH] ARM: mmp: Fix failure to remove sram device
In-Reply-To: <20210726200158.3442800-1-u.kleine-koenig@pengutronix.de>
References: <20210726200158.3442800-1-u.kleine-koenig@pengutronix.de>
Message-ID: <YQvIk0fzn0Y/8yLM@kroah.com>

On Mon, Jul 26, 2021 at 10:01:58PM +0200, Uwe Kleine-K?nig wrote:
> Make sure in .probe() to set driver data before the function is left to
> make it possible in .remove() to undo the actions done.
> 
> This fixes a potential memory leak and stops returning an error code in
> .remove() that is ignored by the driver core anyhow.
> 
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> ---
>  arch/arm/mach-mmp/sram.c | 22 ++++++++++++----------
>  1 file changed, 12 insertions(+), 10 deletions(-)

Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From will at kernel.org  Thu Aug  5 04:21:14 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 5 Aug 2021 12:21:14 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Remove some unneeded init in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <bebc7b1b-e60c-d5e6-812a-63580d7029cc@huawei.com>
References: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
 <bebc7b1b-e60c-d5e6-812a-63580d7029cc@huawei.com>
Message-ID: <20210805112114.GA1029@willie-the-truck>

On Thu, Aug 05, 2021 at 11:22:15AM +0100, John Garry wrote:
> On 21/06/2021 17:36, John Garry wrote:
> > Members of struct "llq" will be zero-inited, apart from member max_n_shift.
> > But we write llq.val straight after the init, so it was pointless to zero
> > init those other members. As such, separately init member max_n_shift
> > only.
> > 
> > In addition, struct "head" is initialised to "llq" only so that member
> > max_n_shift is set. But that member is never referenced for "head", so
> > remove any init there.
> > 
> > Removing these initializations is seen as a small performance optimisation,
> > as this code is (very) hot path.
> > 
> 
> Hi Will,
> 
> Any chance you can pick up this small optimisation?

Yup! I've actually queued it locally, but I may end up asking Joerg to take
it directly depending on what else I queue for 5.15. So far, most of the
SMMU stuff is all part of wider refactorings.

Cheers,

Will


From robin.murphy at arm.com  Thu Aug  5 04:24:33 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 5 Aug 2021 12:24:33 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Remove some unneeded init in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
References: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
Message-ID: <ee1f3ab5-3acc-f442-f2d2-898cf88bc447@arm.com>

On 2021-06-21 17:36, John Garry wrote:
> Members of struct "llq" will be zero-inited, apart from member max_n_shift.
> But we write llq.val straight after the init, so it was pointless to zero
> init those other members. As such, separately init member max_n_shift
> only.
> 
> In addition, struct "head" is initialised to "llq" only so that member
> max_n_shift is set. But that member is never referenced for "head", so
> remove any init there.
> 
> Removing these initializations is seen as a small performance optimisation,
> as this code is (very) hot path.

I looked at this and immediately thought "surely the compiler can see 
that all the prod/cons/val fields are written anyway and elide the 
initialisation?", so I dumped the before and after disassembly, and... oh.

You should probably clarify that it's zero-initialising all the 
cacheline padding which is both pointless and painful. With that,

Reviewed-by: Robin Murphy <robin.murphy at arm.com>

However, having looked this closely I'm now tangentially wondering why 
max_n_shift isn't inside the padded union? It's read at the same time as 
both prod and cons by queue_has_space(), and never updated, so there 
doesn't appear to be any benefit to it being in a separate cacheline all 
by itself, and llq is already twice as big as it needs to be. Sorting 
that would also be a good opportunity to store the value of interest in 
its appropriate form so we're not needlessly recalculating 1 << shift 
every flippin' time...

Robin.

> Signed-off-by: John Garry <john.garry at huawei.com>
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 54b2f27b81d4..8a8ad49bb7fd 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -727,11 +727,11 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
>   	unsigned long flags;
>   	bool owner;
>   	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
> -	struct arm_smmu_ll_queue llq = {
> -		.max_n_shift = cmdq->q.llq.max_n_shift,
> -	}, head = llq;
> +	struct arm_smmu_ll_queue llq, head;
>   	int ret = 0;
>   
> +	llq.max_n_shift = cmdq->q.llq.max_n_shift;
> +
>   	/* 1. Allocate some space in the queue */
>   	local_irq_save(flags);
>   	llq.val = READ_ONCE(cmdq->q.llq.val);
> 


From lorenzo.pieralisi at arm.com  Thu Aug  5 04:26:39 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 5 Aug 2021 12:26:39 +0100
Subject: [PATCH v2 5/6] misc: pci_endpoint_test: Do not request or
 allocate IRQs in probe
In-Reply-To: <02c1ddb7-539e-20a0-1bef-e10e76922a0e@ti.com>
References: <20210803074932.19820-1-kishon@ti.com>
 <20210803074932.19820-6-kishon@ti.com>
 <20210803095839.GA11252@lpieralisi>
 <02c1ddb7-539e-20a0-1bef-e10e76922a0e@ti.com>
Message-ID: <20210805112639.GA20438@lpieralisi>

On Wed, Aug 04, 2021 at 07:32:44PM +0530, Kishon Vijay Abraham I wrote:
> Hi Lorenzo,
> 
> On 03/08/21 3:28 pm, Lorenzo Pieralisi wrote:
> > On Tue, Aug 03, 2021 at 01:19:31PM +0530, Kishon Vijay Abraham I wrote:
> >> Allocation of IRQ vectors and requesting IRQ is done as part of
> >> PCITEST_SET_IRQTYPE. Do not request or allocate IRQs in probe for
> >> AM654 and J721E so that the user space test script has better control
> >> of the devices for which the IRQs are configured. Since certain user
> >> space scripts could rely on allocation of IRQ vectors during probe,
> >> remove allocation of IRQs only for TI's K3 platform.
> >>
> >> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> >> ---
> >>  drivers/misc/pci_endpoint_test.c | 19 +++++++++++++------
> >>  1 file changed, 13 insertions(+), 6 deletions(-)
> > 
> > I don't claim to understand the inner details of the endpoint test
> > device but it looks like this approach should be redesigned.
> > 
> > I don't believe using devices quirks is the best approach to
> > expose/remove a feature to userspace, this can soon become
> > unmaintenable.
> > 
> > Maybe you can elaborate a bit more on what the real issue is please ?
> 
> The actual reason for introducing this patch (affects only AM654 and
> J721E) is due to Errata ID #i2101 GIC: ITS Misbehavior
> (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf). So if more than 5
> devices use GIC ITS simultaneously, GIC fails to raise interrupts.
> 
> Though this patch is not an actual workaround for the issue (the
> workaround is in GIC ITS driver provided in the errata document), it
> helps to keep testing PCIe RC/EP using pci-endpoint-test even when
> multiple pci-epf-test endpoint devices are connected (Normal test-setup
> having J721E-J721E back to back connection can support 21 pci-epf-test
> devices). So this patch lets user to individually enable interrupts for
> each of the devices and could disable after the interrupt test.
> 
> Since pci_endpoint_test is used only for testing PCIE RC/EP
> communication and pci-endpoint-test has already implemented
> PCITEST_SET_IRQTYPE for the userspace to enable interrupt, tried to not
> enable the interrupts of all the devices by default in the probe (for
> AM654 and J721E where this errata applies).

I understand - what I am asking is:

is it possible, instead of applying this patch, to make

pci_endpoint_test_alloc_irq_vectors() and pci_endpoint_test_request_irq()

fail in the target platforms instead of preventing to call them ?

My worry is that you may end up with more corner cases in the future
and peppering code with is_() calls to work around them which does
not look right.

Thanks,
Lorenzo

> Thanks,
> Kishon
> 
> > 
> > Thanks,
> > Lorenzo
> > 
> >> diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
> >> index c7ee34013485..9740f2a0e7cd 100644
> >> --- a/drivers/misc/pci_endpoint_test.c
> >> +++ b/drivers/misc/pci_endpoint_test.c
> >> @@ -79,6 +79,9 @@
> >>  #define PCI_DEVICE_ID_RENESAS_R8A774C0		0x002d
> >>  #define PCI_DEVICE_ID_RENESAS_R8A774E1		0x0025
> >>  
> >> +#define is_j721e_pci_dev(pdev)         \
> >> +		((pdev)->device == PCI_DEVICE_ID_TI_J721E)
> >> +
> >>  static DEFINE_IDA(pci_endpoint_test_ida);
> >>  
> >>  #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
> >> @@ -810,9 +813,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
> >>  
> >>  	pci_set_master(pdev);
> >>  
> >> -	if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
> >> -		err = -EINVAL;
> >> -		goto err_disable_irq;
> >> +	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
> >> +		if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
> >> +			err = -EINVAL;
> >> +			goto err_disable_irq;
> >> +		}
> >>  	}
> >>  
> >>  	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
> >> @@ -850,9 +855,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
> >>  		goto err_ida_remove;
> >>  	}
> >>  
> >> -	if (!pci_endpoint_test_request_irq(test)) {
> >> -		err = -EINVAL;
> >> -		goto err_kfree_test_name;
> >> +	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
> >> +		if (!pci_endpoint_test_request_irq(test)) {
> >> +			err = -EINVAL;
> >> +			goto err_kfree_test_name;
> >> +		}
> >>  	}
> >>  
> >>  	misc_device = &test->miscdev;
> >> -- 
> >> 2.17.1
> >>


From semen.protsenko at linaro.org  Thu Aug  5 04:26:36 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 5 Aug 2021 14:26:36 +0300
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4m5LWr5hQi9P8ywZbhNyj8Fwdkk4B_O_YgM_DthWSG9BA@mail.gmail.com>

Hi Krzysztof,

On Thu, 5 Aug 2021 at 10:22, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF (by
> ARM).
>
> Reported-by: Sam Protsenko <semen.protsenko at linaro.org>
> Reported-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  arch/arm64/boot/dts/exynos/exynos7.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> index 8b06397ba6e7..c73a597ca66e 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> @@ -137,7 +137,7 @@ gic: interrupt-controller at 11001000 {
>                         #address-cells = <0>;
>                         interrupt-controller;
>                         reg =   <0x11001000 0x1000>,
> -                               <0x11002000 0x1000>,
> +                               <0x11002000 0x2000>,
>                                 <0x11004000 0x2000>,
>                                 <0x11006000 0x2000>;
>                 };
> --
> 2.30.2
>


From lee.jones at linaro.org  Thu Aug  5 04:41:27 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 5 Aug 2021 12:41:27 +0100
Subject: [PATCH] mfd: Don't use irq_create_mapping() to resolve a mapping
In-Reply-To: <20210725180754.250163-1-maz@kernel.org>
References: <20210725180754.250163-1-maz@kernel.org>
Message-ID: <YQvOZy48/DBzA5ao@google.com>

On Sun, 25 Jul 2021, Marc Zyngier wrote:

> Although irq_create_mapping() is able to deal with duplicate
> mappings, it really isn't supposed to be a substitute for
> irq_find_mapping(), and can result in allocations that take place
> in atomic context if the mapping didn't exist.
> 
> Fix the handful of MFD drivers that use irq_create_mapping() in
> interrupt context by using irq_find_mapping() instead.
> 
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Lee Jones <lee.jones at linaro.org>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  drivers/mfd/ab8500-core.c | 2 +-
>  drivers/mfd/stmpe.c       | 4 ++--
>  drivers/mfd/tc3589x.c     | 2 +-
>  drivers/mfd/wm8994-irq.c  | 2 +-
>  4 files changed, 5 insertions(+), 5 deletions(-)

Applied, thanks.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From michael.riesch at wolfvision.net  Thu Aug  5 05:01:00 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu,  5 Aug 2021 14:01:00 +0200
Subject: [PATCH v3 0/7] arm64: dts: rockchip: rk3568-evb1-v10: add sd card
 support
Message-ID: <20210805120107.27007-1-michael.riesch@wolfvision.net>

Hi all,

This series enables the SD card reader on the RK3568 EVB1
and completes the support for the on-board eMMC.

As the PMU IO domains are required, the patch series that
introduces support for the RK3568 PMU IO domains [1] has been
revised and integrated in this series.
Additionally, the required voltage regulators of the RK809
PMIC are enabled.

Best regards,
Michael

[1] https://patchwork.kernel.org/project/linux-rockchip/list/?series=489383

v3:
- clean up device tree properties and sort alphabetically

v2:
- rename alias to match convention
- add support for rk3568 io domains

Jianqun Xu (1):
  soc: rockchip: io-domain: add rk3568 support

Michael Riesch (6):
  dt-bindings: power: add rk3568-pmu-io-domain support
  arm64: dts: rockchip: enable io domains for rk356x
  arm64: dts: rockchip: rk3568-evb1-v10: enable io domains
  arm64: dts: rockchip: rk3568-evb1-v10: add regulators of rk809 pmic
  arm64: dts: rockchip: rk3568-evb1-v10: add node for sd card
  arm64: dts: rockchip: rk3568-evb1-v10: add pinctrl and alias to emmc
    node

 .../bindings/power/rockchip-io-domain.yaml    |  30 +++
 .../devicetree/bindings/soc/rockchip/grf.yaml |   1 +
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 251 ++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |   5 +
 drivers/soc/rockchip/io-domain.c              |  88 +++++-
 5 files changed, 367 insertions(+), 8 deletions(-)

-- 
2.17.1



From michael.riesch at wolfvision.net  Thu Aug  5 05:01:01 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu,  5 Aug 2021 14:01:01 +0200
Subject: [PATCH v3 1/7] dt-bindings: power: add rk3568-pmu-io-domain support
In-Reply-To: <20210805120107.27007-1-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
Message-ID: <20210805120107.27007-2-michael.riesch@wolfvision.net>

Add binding for the RK3568 along a SoC-specific description of
voltage supplies.

Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
[add soc-specific section]
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
v3:
- add missing compatible for the rk3568 to grf.yaml

 .../bindings/power/rockchip-io-domain.yaml    | 30 +++++++++++++++++++
 .../devicetree/bindings/soc/rockchip/grf.yaml |  1 +
 2 files changed, 31 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.yaml b/Documentation/devicetree/bindings/power/rockchip-io-domain.yaml
index 121bec56b2b0..1727bf108979 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.yaml
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.yaml
@@ -55,6 +55,7 @@ properties:
       - rockchip,rk3368-pmu-io-voltage-domain
       - rockchip,rk3399-io-voltage-domain
       - rockchip,rk3399-pmu-io-voltage-domain
+      - rockchip,rk3568-pmu-io-voltage-domain
       - rockchip,rv1108-io-voltage-domain
       - rockchip,rv1108-pmu-io-voltage-domain
 
@@ -74,6 +75,7 @@ allOf:
   - $ref: "#/$defs/rk3368-pmu"
   - $ref: "#/$defs/rk3399"
   - $ref: "#/$defs/rk3399-pmu"
+  - $ref: "#/$defs/rk3568-pmu"
   - $ref: "#/$defs/rv1108"
   - $ref: "#/$defs/rv1108-pmu"
 
@@ -282,6 +284,34 @@ $defs:
         pmu1830-supply:
           description: The supply connected to PMUIO2_VDD.
 
+  rk3568-pmu:
+    if:
+      properties:
+        compatible:
+          contains:
+            const: rockchip,rk3568-pmu-io-voltage-domain
+
+    then:
+      properties:
+        pmuio1-supply:
+          description: The supply connected to PMUIO1.
+        pmuio2-supply:
+          description: The supply connected to PMUIO2.
+        vccio1-supply:
+          description: The supply connected to VCCIO1.
+        vccio2-supply:
+          description: The supply connected to VCCIO2.
+        vccio3-supply:
+          description: The supply connected to VCCIO3.
+        vccio4-supply:
+          description: The supply connected to VCCIO4.
+        vccio5-supply:
+          description: The supply connected to VCCIO5.
+        vccio6-supply:
+          description: The supply connected to VCCIO6.
+        vccio7-supply:
+          description: The supply connected to VCCIO7.
+
   rv1108:
     if:
       properties:
diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
index fa010df51a5c..dfebf425ca49 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
+++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
@@ -208,6 +208,7 @@ allOf:
               - rockchip,rk3368-pmugrf
               - rockchip,rk3399-grf
               - rockchip,rk3399-pmugrf
+              - rockchip,rk3568-pmugrf
               - rockchip,rv1108-grf
               - rockchip,rv1108-pmugrf
 
-- 
2.17.1



From michael.riesch at wolfvision.net  Thu Aug  5 05:01:02 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu,  5 Aug 2021 14:01:02 +0200
Subject: [PATCH v3 2/7] soc: rockchip: io-domain: add rk3568 support
In-Reply-To: <20210805120107.27007-1-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
Message-ID: <20210805120107.27007-3-michael.riesch@wolfvision.net>

From: Jianqun Xu <jay.xu at rock-chips.com>

The io-domain registers on RK3568 SoCs have three separated bits to
enable/disable the 1.8v/2.5v/3.3v power.

This patch make the write to be a operation, allow rk3568 uses a private
register set function.

Since the 2.5v is not used on RK3568, so the driver only set
1.8v [enable] + 3.3v [disable] for 1.8v mode
1.8v [disable] + 3.3v [enable] for 3.3v mode

There is not register order requirement which has been cleared by our IC
team.

Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
---
 drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
 1 file changed, 80 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
index cf8182fc3642..13c446fd33a9 100644
--- a/drivers/soc/rockchip/io-domain.c
+++ b/drivers/soc/rockchip/io-domain.c
@@ -51,13 +51,11 @@
 #define RK3399_PMUGRF_CON0_VSEL		BIT(8)
 #define RK3399_PMUGRF_VSEL_SUPPLY_NUM	9
 
-struct rockchip_iodomain;
+#define RK3568_PMU_GRF_IO_VSEL0		(0x0140)
+#define RK3568_PMU_GRF_IO_VSEL1		(0x0144)
+#define RK3568_PMU_GRF_IO_VSEL2		(0x0148)
 
-struct rockchip_iodomain_soc_data {
-	int grf_offset;
-	const char *supply_names[MAX_SUPPLIES];
-	void (*init)(struct rockchip_iodomain *iod);
-};
+struct rockchip_iodomain;
 
 struct rockchip_iodomain_supply {
 	struct rockchip_iodomain *iod;
@@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
 	int idx;
 };
 
+struct rockchip_iodomain_soc_data {
+	int grf_offset;
+	const char *supply_names[MAX_SUPPLIES];
+	void (*init)(struct rockchip_iodomain *iod);
+	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
+};
+
 struct rockchip_iodomain {
 	struct device *dev;
 	struct regmap *grf;
 	const struct rockchip_iodomain_soc_data *soc_data;
 	struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
+	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
 };
 
+static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
+{
+	struct rockchip_iodomain *iod = supply->iod;
+	u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
+	u32 val0, val1;
+	int b;
+
+	switch (supply->idx) {
+	case 0: /* pmuio1 */
+		break;
+	case 1: /* pmuio2 */
+		b = supply->idx;
+		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
+		b = supply->idx + 4;
+		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
+
+		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
+		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
+		break;
+	case 3: /* vccio2 */
+		break;
+	case 2: /* vccio1 */
+	case 4: /* vccio3 */
+	case 5: /* vccio4 */
+	case 6: /* vccio5 */
+	case 7: /* vccio6 */
+	case 8: /* vccio7 */
+		b = supply->idx - 1;
+		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
+		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
+
+		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
+		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
 static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
 				   int uV)
 {
@@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
 			return NOTIFY_BAD;
 	}
 
-	ret = rockchip_iodomain_write(supply, uV);
+	ret = supply->iod->write(supply, uV);
 	if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
 		return NOTIFY_BAD;
 
@@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
 	.init = rk3399_pmu_iodomain_init,
 };
 
+static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
+	.grf_offset = 0x140,
+	.supply_names = {
+		"pmuio1",
+		"pmuio2",
+		"vccio1",
+		"vccio2",
+		"vccio3",
+		"vccio4",
+		"vccio5",
+		"vccio6",
+		"vccio7",
+	},
+	.write = rk3568_iodomain_write,
+};
+
 static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
 	.grf_offset = 0x404,
 	.supply_names = {
@@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
 		.compatible = "rockchip,rk3399-pmu-io-voltage-domain",
 		.data = &soc_data_rk3399_pmu
 	},
+	{
+		.compatible = "rockchip,rk3568-pmu-io-voltage-domain",
+		.data = &soc_data_rk3568_pmu
+	},
 	{
 		.compatible = "rockchip,rv1108-io-voltage-domain",
 		.data = &soc_data_rv1108
@@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
 	match = of_match_node(rockchip_iodomain_match, np);
 	iod->soc_data = match->data;
 
+	if (iod->soc_data->write)
+		iod->write = iod->soc_data->write;
+	else
+		iod->write = rockchip_iodomain_write;
+
 	parent = pdev->dev.parent;
 	if (parent && parent->of_node) {
 		iod->grf = syscon_node_to_regmap(parent->of_node);
@@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
 		supply->reg = reg;
 		supply->nb.notifier_call = rockchip_iodomain_notify;
 
-		ret = rockchip_iodomain_write(supply, uV);
+		ret = iod->write(supply, uV);
 		if (ret) {
 			supply->reg = NULL;
 			goto unreg_notify;
-- 
2.17.1



From michael.riesch at wolfvision.net  Thu Aug  5 05:01:04 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu,  5 Aug 2021 14:01:04 +0200
Subject: [PATCH v3 4/7] arm64: dts: rockchip: rk3568-evb1-v10: enable io
 domains
In-Reply-To: <20210805120107.27007-1-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
Message-ID: <20210805120107.27007-5-michael.riesch@wolfvision.net>

Enable the PMU IO domains in the device tree for the RK3568 EVB1.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 65e536c78d2e..287b58aa6a77 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -124,6 +124,19 @@
 	};
 };
 
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_1v8>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	max-frequency = <200000000>;
-- 
2.17.1



From michael.riesch at wolfvision.net  Thu Aug  5 05:01:03 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu,  5 Aug 2021 14:01:03 +0200
Subject: [PATCH v3 3/7] arm64: dts: rockchip: enable io domains for rk356x
In-Reply-To: <20210805120107.27007-1-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
Message-ID: <20210805120107.27007-4-michael.riesch@wolfvision.net>

Enable the PMU IO domains for the RK3566 and the RK3568.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 3e90a8832bb9..834863940eba 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -203,6 +203,11 @@
 	pmugrf: syscon at fdc20000 {
 		compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd";
 		reg = <0x0 0xfdc20000 0x0 0x10000>;
+
+		pmu_io_domains: io-domains {
+			compatible = "rockchip,rk3568-pmu-io-voltage-domain";
+			status = "disabled";
+		};
 	};
 
 	grf: syscon at fdc60000 {
-- 
2.17.1



From michael.riesch at wolfvision.net  Thu Aug  5 05:01:05 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu,  5 Aug 2021 14:01:05 +0200
Subject: [PATCH v3 5/7] arm64: dts: rockchip: rk3568-evb1-v10: add regulators
 of rk809 pmic
In-Reply-To: <20210805120107.27007-1-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
Message-ID: <20210805120107.27007-6-michael.riesch@wolfvision.net>

Add the regulators of the RK809 PMIC to the device tree of the
RK3568 EVB1.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
v3:
- sort device tree properties alphabetically

 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 221 ++++++++++++++++++
 1 file changed, 221 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 287b58aa6a77..92af4ce89b70 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -104,6 +104,218 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>;
+		rockchip,system-power-controller;
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+		wakeup-source;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-name = "vdd_gpu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-name = "vdd_npu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-name = "vdda0v9_image";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-name = "vcca_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-name = "vcca1v8_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-name = "vcca1v8_image";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
 &mdio0 {
 	rgmii_phy0: ethernet-phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
@@ -124,6 +336,15 @@
 	};
 };
 
+&pinctrl {
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
 &pmu_io_domains {
 	pmuio1-supply = <&vcc3v3_pmu>;
 	pmuio2-supply = <&vcc3v3_pmu>;
-- 
2.17.1



From michael.riesch at wolfvision.net  Thu Aug  5 05:01:06 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu,  5 Aug 2021 14:01:06 +0200
Subject: [PATCH v3 6/7] arm64: dts: rockchip: rk3568-evb1-v10: add node for sd
 card
In-Reply-To: <20210805120107.27007-1-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
Message-ID: <20210805120107.27007-7-michael.riesch@wolfvision.net>

Add the SD card reader to the device tree of the RK3568 EVB1.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
v3:
- clean up device tree properties and sort alphabetically
- revise alias

 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 92af4ce89b70..1c34d529b771 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -16,6 +16,7 @@
 	aliases {
 		ethernet0 = &gmac0;
 		ethernet1 = &gmac1;
+		mmc0 = &sdmmc0;
 	};
 
 	chosen: chosen {
@@ -365,6 +366,19 @@
 	status = "okay";
 };
 
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
 &uart2 {
 	status = "okay";
 };
-- 
2.17.1



From michael.riesch at wolfvision.net  Thu Aug  5 05:01:07 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu,  5 Aug 2021 14:01:07 +0200
Subject: [PATCH v3 7/7] arm64: dts: rockchip: rk3568-evb1-v10: add pinctrl and
 alias to emmc node
In-Reply-To: <20210805120107.27007-1-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
Message-ID: <20210805120107.27007-8-michael.riesch@wolfvision.net>

Since the EMMC pins can be used for other functions as well, we need to
configure the pinctrl.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
v3:
- revise alias

 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 1c34d529b771..1bc79e95b2fb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -17,6 +17,7 @@
 		ethernet0 = &gmac0;
 		ethernet1 = &gmac1;
 		mmc0 = &sdmmc0;
+		mmc1 = &sdhci;
 	};
 
 	chosen: chosen {
@@ -363,6 +364,8 @@
 	bus-width = <8>;
 	max-frequency = <200000000>;
 	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
 	status = "okay";
 };
 
-- 
2.17.1



From gregkh at linuxfoundation.org  Thu Aug  5 05:17:57 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 5 Aug 2021 14:17:57 +0200
Subject: [PATCH v2 00/15] Introduce PECI subsystem
In-Reply-To: <20210803113134.2262882-1-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
Message-ID: <YQvW9Ua2PpuDQnji@kroah.com>

On Tue, Aug 03, 2021 at 01:31:19PM +0200, Iwona Winiarska wrote:
> Hi Greg,
> 
> This is a second round of patches introducing PECI subsystem.
> I don't think it is ready to be applied right away (we're still
> missing r-b's), but I hope we have chance to complete discussion in
> the 5.15 development cycle. I would appreciate if you could take
> a look.

I will wait to review this when you all feel it is ready so as to not
waste my time finding things that you already know need to be resolved.

thanks,

greg k-h


From robin.murphy at arm.com  Thu Aug  5 05:18:38 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 5 Aug 2021 13:18:38 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Remove some unneeded init in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <ee1f3ab5-3acc-f442-f2d2-898cf88bc447@arm.com>
References: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
 <ee1f3ab5-3acc-f442-f2d2-898cf88bc447@arm.com>
Message-ID: <b1f8e29d-13a1-a564-42ec-02fcb0160dd1@arm.com>

On 2021-08-05 12:24, Robin Murphy wrote:
> On 2021-06-21 17:36, John Garry wrote:
>> Members of struct "llq" will be zero-inited, apart from member 
>> max_n_shift.
>> But we write llq.val straight after the init, so it was pointless to zero
>> init those other members. As such, separately init member max_n_shift
>> only.
>>
>> In addition, struct "head" is initialised to "llq" only so that member
>> max_n_shift is set. But that member is never referenced for "head", so
>> remove any init there.
>>
>> Removing these initializations is seen as a small performance 
>> optimisation,
>> as this code is (very) hot path.
> 
> I looked at this and immediately thought "surely the compiler can see 
> that all the prod/cons/val fields are written anyway and elide the 
> initialisation?", so I dumped the before and after disassembly, and... oh.
> 
> You should probably clarify that it's zero-initialising all the 
> cacheline padding which is both pointless and painful. With that,
> 
> Reviewed-by: Robin Murphy <robin.murphy at arm.com>
> 
> However, having looked this closely I'm now tangentially wondering why 
> max_n_shift isn't inside the padded union? It's read at the same time as 
> both prod and cons by queue_has_space(), and never updated, so there 
> doesn't appear to be any benefit to it being in a separate cacheline all 
> by itself, and llq is already twice as big as it needs to be. Sorting 
> that would also be a good opportunity to store the value of interest in 
> its appropriate form so we're not needlessly recalculating 1 << shift 
> every flippin' time...

...on which note, how about something like this on top?

(untested since I don't have any SMMUv3 hardware to hand)

Robin.

----->8-----
Subject: [PATCH] iommu/arm-smmu-v3: Improve arm_smmu_ll_queue efficiency

Once initialised, max_n_shift is only ever read at the same time as
accessing prod or cons, thus should not have any impact on contention
to justify keeping it in its own separate cacheline. Move it inside the
padding union to halve the size of struct arm_smmu_ll_queue. Even then,
though, there are a couple more spots in the command issuing path where
we could do without the overhead of zeroing even one cache line worth of
padding, so avoid implicit initialisation of those temporary structures
as was done at the top level in arm_smmu_cmdq_issue_cmdlist().

Furthermore, the shift value is only directly relevant for initially
setting up the relevant queue base register; all we care about after
that is the number of entries, so store that value instead once a
queue is initialised and avoid needlessly recalculating it everywhere.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 35 +++++++++++----------
  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 29 ++++++++++-------
  2 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 47610dc5d920..bc55217d6d61 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -111,7 +111,7 @@ static bool queue_has_space(struct arm_smmu_ll_queue 
*q, u32 n)
  	cons = Q_IDX(q, q->cons);

  	if (Q_WRP(q, q->prod) == Q_WRP(q, q->cons))
-		space = (1 << q->max_n_shift) - (prod - cons);
+		space = q->nents - (prod - cons);
  	else
  		space = cons - prod;

@@ -517,10 +517,11 @@ static void 
__arm_smmu_cmdq_poll_set_valid_map(struct arm_smmu_cmdq *cmdq,
  					       u32 sprod, u32 eprod, bool set)
  {
  	u32 swidx, sbidx, ewidx, ebidx;
-	struct arm_smmu_ll_queue llq = {
-		.max_n_shift	= cmdq->q.llq.max_n_shift,
-		.prod		= sprod,
-	};
+	struct arm_smmu_ll_queue llq;
+
+	/* Avoid zero-initialising all the padding */;
+	llq.nents = cmdq->q.llq.nents;
+	llq.prod = sprod;

  	ewidx = BIT_WORD(Q_IDX(&llq, eprod));
  	ebidx = Q_IDX(&llq, eprod) % BITS_PER_LONG;
@@ -696,10 +697,11 @@ static void arm_smmu_cmdq_write_entries(struct 
arm_smmu_cmdq *cmdq, u64 *cmds,
  					u32 prod, int n)
  {
  	int i;
-	struct arm_smmu_ll_queue llq = {
-		.max_n_shift	= cmdq->q.llq.max_n_shift,
-		.prod		= prod,
-	};
+	struct arm_smmu_ll_queue llq;
+
+	/* Avoid zero-initialising all the padding */;
+	llq.nents = cmdq->q.llq.nents;
+	llq.prod = prod;

  	for (i = 0; i < n; ++i) {
  		u64 *cmd = &cmds[i * CMDQ_ENT_DWORDS];
@@ -736,7 +738,7 @@ static int arm_smmu_cmdq_issue_cmdlist(struct 
arm_smmu_device *smmu,
  	struct arm_smmu_ll_queue llq, head;
  	int ret = 0;

-	llq.max_n_shift = cmdq->q.llq.max_n_shift;
+	llq.nents = cmdq->q.llq.nents;

  	/* 1. Allocate some space in the queue */
  	local_irq_save(flags);
@@ -2845,16 +2847,18 @@ static int arm_smmu_init_one_queue(struct 
arm_smmu_device *smmu,
  				   unsigned long cons_off,
  				   size_t dwords, const char *name)
  {
+	u32 max_n_shift = q->llq.max_n_shift;
  	size_t qsz;

  	do {
-		qsz = ((1 << q->llq.max_n_shift) * dwords) << 3;
+		q->llq.nents = 1 << max_n_shift;
+		qsz = q->llq.nents * dwords * sizeof(u64);
  		q->base = dmam_alloc_coherent(smmu->dev, qsz, &q->base_dma,
  					      GFP_KERNEL);
  		if (q->base || qsz < PAGE_SIZE)
  			break;

-		q->llq.max_n_shift--;
+		max_n_shift--;
  	} while (1);

  	if (!q->base) {
@@ -2866,7 +2870,7 @@ static int arm_smmu_init_one_queue(struct 
arm_smmu_device *smmu,

  	if (!WARN_ON(q->base_dma & (qsz - 1))) {
  		dev_info(smmu->dev, "allocated %u entries for %s\n",
-			 1 << q->llq.max_n_shift, name);
+			 q->llq.nents, name);
  	}

  	q->prod_reg	= page + prod_off;
@@ -2875,7 +2879,7 @@ static int arm_smmu_init_one_queue(struct 
arm_smmu_device *smmu,

  	q->q_base  = Q_BASE_RWA;
  	q->q_base |= q->base_dma & Q_BASE_ADDR_MASK;
-	q->q_base |= FIELD_PREP(Q_BASE_LOG2SIZE, q->llq.max_n_shift);
+	q->q_base |= FIELD_PREP(Q_BASE_LOG2SIZE, max_n_shift);

  	q->llq.prod = q->llq.cons = 0;
  	return 0;
@@ -2891,13 +2895,12 @@ static int arm_smmu_cmdq_init(struct 
arm_smmu_device *smmu)
  {
  	int ret = 0;
  	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
-	unsigned int nents = 1 << cmdq->q.llq.max_n_shift;
  	atomic_long_t *bitmap;

  	atomic_set(&cmdq->owner_prod, 0);
  	atomic_set(&cmdq->lock, 0);

-	bitmap = (atomic_long_t *)bitmap_zalloc(nents, GFP_KERNEL);
+	bitmap = (atomic_long_t *)bitmap_zalloc(cmdq->q.llq.nents, GFP_KERNEL);
  	if (!bitmap) {
  		dev_err(smmu->dev, "failed to allocate cmdq bitmap\n");
  		ret = -ENOMEM;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 4cb136f07914..bc13952ad445 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -166,8 +166,8 @@
  #define ARM_SMMU_MEMATTR_DEVICE_nGnRE	0x1
  #define ARM_SMMU_MEMATTR_OIWB		0xf

-#define Q_IDX(llq, p)			((p) & ((1 << (llq)->max_n_shift) - 1))
-#define Q_WRP(llq, p)			((p) & (1 << (llq)->max_n_shift))
+#define Q_IDX(llq, p)			((p) & ((llq)->nents - 1))
+#define Q_WRP(llq, p)			((p) & (llq)->nents)
  #define Q_OVERFLOW_FLAG			(1U << 31)
  #define Q_OVF(p)			((p) & Q_OVERFLOW_FLAG)
  #define Q_ENT(q, p)			((q)->base +			\
@@ -505,18 +505,25 @@ struct arm_smmu_cmdq_ent {

  struct arm_smmu_ll_queue {
  	union {
-		u64			val;
-		struct {
-			u32		prod;
-			u32		cons;
+		struct{
+			union {
+				u64	val;
+				struct {
+					u32 prod;
+					u32 cons;
+				};
+				struct {
+					atomic_t prod;
+					atomic_t cons;
+				} atomic;
+			};
+			union {
+				u32	max_n_shift;
+				u32	nents;
+			};
  		};
-		struct {
-			atomic_t	prod;
-			atomic_t	cons;
-		} atomic;
  		u8			__pad[SMP_CACHE_BYTES];
  	} ____cacheline_aligned_in_smp;
-	u32				max_n_shift;
  };

  struct arm_smmu_queue {
-- 
2.25.1


From robin.murphy at arm.com  Thu Aug  5 05:25:33 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 5 Aug 2021 13:25:33 +0100
Subject: [PATCH v2] ARM: Fix Keystone 2 kernel mapping regression
In-Reply-To: <20210804192759.750112-1-linus.walleij@linaro.org>
References: <20210804192759.750112-1-linus.walleij@linaro.org>
Message-ID: <b828494f-6c7c-c860-44cd-74f50a6427b3@arm.com>

On 2021-08-04 20:27, Linus Walleij wrote:
> This fixes a Keystone 2 regression discovered as a side effect of
> defining an passing the physical start/end sections of the kernel
> to the MMU remapping code.
> 
> As the Keystone applies an offset to all physical addresses,
> including those identified and patches by phys2virt, we fail to
> account for this offset in the kernel_sec_start and kernel_sec_end
> variables.
> 
> Further these offsets can extend into the 64bit range on LPAE
> systems such as the Keystone 2.
> 
> Fix it like this:
> - Extend kernel_sec_start and kernel_sec_end to be 64bit
> - Add the offset also to kernel_sec_start and kernel_sec_end
> 
> As passing kernel_sec_start and kernel_sec_end as 64bit invariably
> incurs BE8 endianness issues I have attempted to dry-code around
> these.
> 
> Tested on the Vexpress QEMU model both with and without LPAE
> enabled.
> 
> Fixes: 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel separately")
> Reported-by: Nishanth Menon <nmenon at kernel.org>
> Suggested-by: Russell King <linux at armlinux.org.uk>
> Tested-by: Grygorii Strashko <grygorii.strashko at ti.com>
> Tested-by: Nishanth Menon <nmenon at kernel.org>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> ChangeLog v1->v2:
> - Better assembly, pass the #4 addition along in the str instruction
>    str r8, [r5, #4]
> - Collect Tested-by tags from successful boot tests on Keystone 2.
> - I will put this into Russell's patch tracker immediately.
> ---
>   arch/arm/include/asm/memory.h |  7 ++++---
>   arch/arm/kernel/head.S        | 17 ++++++++++++++---
>   arch/arm/mm/mmu.c             |  9 ++++++++-
>   arch/arm/mm/pv-fixup-asm.S    |  2 +-
>   4 files changed, 27 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> index cfc9dfd70aad..f673e13e0f94 100644
> --- a/arch/arm/include/asm/memory.h
> +++ b/arch/arm/include/asm/memory.h
> @@ -160,10 +160,11 @@ extern unsigned long vectors_base;
>   
>   /*
>    * Physical start and end address of the kernel sections. These addresses are
> - * 2MB-aligned to match the section mappings placed over the kernel.
> + * 2MB-aligned to match the section mappings placed over the kernel. We use
> + * u64 so that LPAE mappings beyond the 32bit limit will work out as well.
>    */
> -extern u32 kernel_sec_start;
> -extern u32 kernel_sec_end;
> +extern u64 kernel_sec_start;
> +extern u64 kernel_sec_end;
>   
>   /*
>    * Physical vs virtual RAM address space conversion.  These are
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 9eb0b4dbcc12..b6fc92d4cf23 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -49,7 +49,8 @@
>   
>   	/*
>   	 * This needs to be assigned at runtime when the linker symbols are
> -	 * resolved.
> +	 * resolved. These are unsigned 64bit really, but in this assembly code
> +	 * We store them as 32bit.
>   	 */
>   	.pushsection .data
>   	.align	2
> @@ -57,7 +58,9 @@
>   	.globl	kernel_sec_end
>   kernel_sec_start:
>   	.long	0
> +	.long	0
>   kernel_sec_end:
> +	.long	0
>   	.long	0
>   	.popsection
>   
> @@ -250,7 +253,11 @@ __create_page_tables:
>   	add	r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ORDER)
>   	ldr	r6, =(_end - 1)
>   	adr_l	r5, kernel_sec_start		@ _pa(kernel_sec_start)
> -	str	r8, [r5]			@ Save physical start of kernel
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +	str	r8, [r5, #4]			@ Save physical start of kernel (BE)
> +#else
> +	str	r8, [r5]			@ Save physical start of kernel (LE)
> +#endif
>   	orr	r3, r8, r7			@ Add the MMU flags
>   	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
>   1:	str	r3, [r0], #1 << PMD_ORDER
> @@ -259,7 +266,11 @@ __create_page_tables:
>   	bls	1b
>   	eor	r3, r3, r7			@ Remove the MMU flags
>   	adr_l	r5, kernel_sec_end		@ _pa(kernel_sec_end)
> -	str	r3, [r5]			@ Save physical end of kernel
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +	str	r8, [r5, #4]			@ Save physical end of kernel (BE)

For the benefit of the one person who tries running a BE kernel about 3 
years from now, that probably wants to be r3 ;)

Robin.

> +#else
> +	str	r3, [r5]			@ Save physical end of kernel (LE)
> +#endif
>   
>   #ifdef CONFIG_XIP_KERNEL
>   	/*
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index 7583bda5ea7d..a4e006005107 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -1608,6 +1608,13 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
>   	if (offset == 0)
>   		return;
>   
> +	/*
> +	 * Offset the kernel section physical offsets so that the kernel
> +	 * mapping will work out later on.
> +	 */
> +	kernel_sec_start += offset;
> +	kernel_sec_end += offset;
> +
>   	/*
>   	 * Get the address of the remap function in the 1:1 identity
>   	 * mapping setup by the early page table assembly code.  We
> @@ -1716,7 +1723,7 @@ void __init paging_init(const struct machine_desc *mdesc)
>   {
>   	void *zero_page;
>   
> -	pr_debug("physical kernel sections: 0x%08x-0x%08x\n",
> +	pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
>   		 kernel_sec_start, kernel_sec_end);
>   
>   	prepare_page_table();
> diff --git a/arch/arm/mm/pv-fixup-asm.S b/arch/arm/mm/pv-fixup-asm.S
> index 5c5e1952000a..f8e11f7c7880 100644
> --- a/arch/arm/mm/pv-fixup-asm.S
> +++ b/arch/arm/mm/pv-fixup-asm.S
> @@ -29,7 +29,7 @@ ENTRY(lpae_pgtables_remap_asm)
>   	ldr	r6, =(_end - 1)
>   	add	r7, r2, #0x1000
>   	add	r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
> -	add	r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER)
> +	add	r7, r7, #KERNEL_OFFSET >> (SECTION_SHIFT - L2_ORDER)
>   1:	ldrd	r4, r5, [r7]
>   	adds	r4, r4, r0
>   	adc	r5, r5, r1
> 


From a-govindraju at ti.com  Thu Aug  5 05:32:31 2021
From: a-govindraju at ti.com (Aswath Govindraju)
Date: Thu, 5 Aug 2021 18:02:31 +0530
Subject: [PATCH v2 0/6] CAN: Add support for CAN in AM65,J721e and AM64
In-Reply-To: <20210802124509.z23lfg7xxkqaakbo@truce>
References: <20210726101012.26983-1-a-govindraju@ti.com>
 <20210802124509.z23lfg7xxkqaakbo@truce>
Message-ID: <36011cee-f617-02ed-7446-c297ba65e6bf@ti.com>

Hi,

On 02/08/21 6:15 pm, Nishanth Menon wrote:
> On 15:40-20210726, Aswath Govindraju wrote:
>> The following series of patches add support for CAN in SoC's AM65, J721e
>> and AM64.
>>
>> This patch series is dependent on [1] and [2] and I have requested for an
>> immutable tag from the Marc Kleine-Budde(maintainer of net tree).
>>
>> [1] - https://lore.kernel.org/patchwork/patch/1423048/
>> [2] - https://www.spinics.net/lists/linux-can/msg08108.html
>>
>> changes since v1 -
>> - changed the message ram configuration to use the maximum value
>>   in each field, for better performance.
>>
>> Aswath Govindraju (3):
>>   arm64: dts: ti: am654-base-board: Disable mcan nodes
>>   arm64: dts: ti: k3-am64-main: Add support for MCAN
>>   arm64: dts: ti: k3-am642-evm/sk: Add support for main domain mcan
>>     nodes in EVM and disable them on SK
>>
>> Faiz Abbas (3):
>>   arm64: dts: ti: k3-am65-mcu: Add Support for MCAN
>>   arm64: dts: ti: k3-j721e: Add support for MCAN nodes
>>   arm64: dts: ti: k3-j721e-common-proc-board: Add support for mcu_mcan
>>     nodes
> 
> I noticed in my checkup: https://pastebin.ubuntu.com/p/zSk39M943N/
> warnings with dtbs_check, I think the bindings need a little more help
> here (please also notice the iot platform warnings getting introduced).
> 

Jan,

Can you please point me to the schematics for iot platform? Also, is CAN
subsystem brought out on the iot platform boards?

> Since we are still working on the bindings[1], lets clean that up
> before we consider the dts addition. I suspect we need to cook this
> more towards the next cycle.
> 
> [1] https://lore.kernel.org/patchwork/patch/1470806/
> 

Nishanth,

Sorry for not taking of this earlier. I'll try to get everything ready
for next release.

Thanks,
Aswath



From jan.kiszka at siemens.com  Thu Aug  5 05:40:07 2021
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Thu, 5 Aug 2021 14:40:07 +0200
Subject: [PATCH v2 0/6] CAN: Add support for CAN in AM65,J721e and AM64
In-Reply-To: <36011cee-f617-02ed-7446-c297ba65e6bf@ti.com>
References: <20210726101012.26983-1-a-govindraju@ti.com>
 <20210802124509.z23lfg7xxkqaakbo@truce>
 <36011cee-f617-02ed-7446-c297ba65e6bf@ti.com>
Message-ID: <35b0e2dc-0591-0a2f-8e3d-4177792a13fa@siemens.com>

On 05.08.21 14:32, Aswath Govindraju wrote:
> Hi,
> 
> On 02/08/21 6:15 pm, Nishanth Menon wrote:
>> On 15:40-20210726, Aswath Govindraju wrote:
>>> The following series of patches add support for CAN in SoC's AM65, J721e
>>> and AM64.
>>>
>>> This patch series is dependent on [1] and [2] and I have requested for an
>>> immutable tag from the Marc Kleine-Budde(maintainer of net tree).
>>>
>>> [1] - https://lore.kernel.org/patchwork/patch/1423048/
>>> [2] - https://www.spinics.net/lists/linux-can/msg08108.html
>>>
>>> changes since v1 -
>>> - changed the message ram configuration to use the maximum value
>>>   in each field, for better performance.
>>>
>>> Aswath Govindraju (3):
>>>   arm64: dts: ti: am654-base-board: Disable mcan nodes
>>>   arm64: dts: ti: k3-am64-main: Add support for MCAN
>>>   arm64: dts: ti: k3-am642-evm/sk: Add support for main domain mcan
>>>     nodes in EVM and disable them on SK
>>>
>>> Faiz Abbas (3):
>>>   arm64: dts: ti: k3-am65-mcu: Add Support for MCAN
>>>   arm64: dts: ti: k3-j721e: Add support for MCAN nodes
>>>   arm64: dts: ti: k3-j721e-common-proc-board: Add support for mcu_mcan
>>>     nodes
>>
>> I noticed in my checkup: https://pastebin.ubuntu.com/p/zSk39M943N/
>> warnings with dtbs_check, I think the bindings need a little more help
>> here (please also notice the iot platform warnings getting introduced).
>>
> 
> Jan,
> 
> Can you please point me to the schematics for iot platform? Also, is CAN
> subsystem brought out on the iot platform boards?

Schematics aren't publicly available. If you have specific questions, I
may help, though.

CAN is not in use yet (not connected AFAIK).

Jan

> 
>> Since we are still working on the bindings[1], lets clean that up
>> before we consider the dts addition. I suspect we need to cook this
>> more towards the next cycle.
>>
>> [1] https://lore.kernel.org/patchwork/patch/1470806/
>>
> 
> Nishanth,
> 
> Sorry for not taking of this earlier. I'll try to get everything ready
> for next release.
> 
> Thanks,
> Aswath
> 

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


From a-govindraju at ti.com  Thu Aug  5 05:44:07 2021
From: a-govindraju at ti.com (Aswath Govindraju)
Date: Thu, 5 Aug 2021 18:14:07 +0530
Subject: [PATCH v2 0/6] CAN: Add support for CAN in AM65,J721e and AM64
In-Reply-To: <35b0e2dc-0591-0a2f-8e3d-4177792a13fa@siemens.com>
References: <20210726101012.26983-1-a-govindraju@ti.com>
 <20210802124509.z23lfg7xxkqaakbo@truce>
 <36011cee-f617-02ed-7446-c297ba65e6bf@ti.com>
 <35b0e2dc-0591-0a2f-8e3d-4177792a13fa@siemens.com>
Message-ID: <cfd7df02-37ed-6286-0232-2e92bf1f67b4@ti.com>

Hi Jan,

On 05/08/21 6:10 pm, Jan Kiszka wrote:
> On 05.08.21 14:32, Aswath Govindraju wrote:
>> Hi,
>>
>> On 02/08/21 6:15 pm, Nishanth Menon wrote:
>>> On 15:40-20210726, Aswath Govindraju wrote:
>>>> The following series of patches add support for CAN in SoC's AM65, J721e
>>>> and AM64.
>>>>
>>>> This patch series is dependent on [1] and [2] and I have requested for an
>>>> immutable tag from the Marc Kleine-Budde(maintainer of net tree).
>>>>
>>>> [1] - https://lore.kernel.org/patchwork/patch/1423048/
>>>> [2] - https://www.spinics.net/lists/linux-can/msg08108.html
>>>>
>>>> changes since v1 -
>>>> - changed the message ram configuration to use the maximum value
>>>>   in each field, for better performance.
>>>>
>>>> Aswath Govindraju (3):
>>>>   arm64: dts: ti: am654-base-board: Disable mcan nodes
>>>>   arm64: dts: ti: k3-am64-main: Add support for MCAN
>>>>   arm64: dts: ti: k3-am642-evm/sk: Add support for main domain mcan
>>>>     nodes in EVM and disable them on SK
>>>>
>>>> Faiz Abbas (3):
>>>>   arm64: dts: ti: k3-am65-mcu: Add Support for MCAN
>>>>   arm64: dts: ti: k3-j721e: Add support for MCAN nodes
>>>>   arm64: dts: ti: k3-j721e-common-proc-board: Add support for mcu_mcan
>>>>     nodes
>>>
>>> I noticed in my checkup: https://pastebin.ubuntu.com/p/zSk39M943N/
>>> warnings with dtbs_check, I think the bindings need a little more help
>>> here (please also notice the iot platform warnings getting introduced).
>>>
>>
>> Jan,
>>
>> Can you please point me to the schematics for iot platform? Also, is CAN
>> subsystem brought out on the iot platform boards?
> 
> Schematics aren't publicly available. If you have specific questions, I
> may help, though.
> 
> CAN is not in use yet (not connected AFAIK).
> 

Thank you for clarifying this. I will disable the CAN DT nodes in
k3-am65-iot2050-common.dtsi in my respin.

Thanks,
Aswath

> Jan
> 
>>
>>> Since we are still working on the bindings[1], lets clean that up
>>> before we consider the dts addition. I suspect we need to cook this
>>> more towards the next cycle.
>>>
>>> [1] https://lore.kernel.org/patchwork/patch/1470806/
>>>
>>
>> Nishanth,
>>
>> Sorry for not taking of this earlier. I'll try to get everything ready
>> for next release.
>>
>> Thanks,
>> Aswath
>>
> 



From wangkefeng.wang at huawei.com  Thu Aug  5 05:46:20 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Thu, 5 Aug 2021 20:46:20 +0800
Subject: [PATCH v2 1/3] vmalloc: Choose a better start address in
 vm_area_register_early()
In-Reply-To: <20210804111402.GB4857@arm.com>
References: <20210720025105.103680-1-wangkefeng.wang@huawei.com>
 <20210720025105.103680-2-wangkefeng.wang@huawei.com>
 <20210801152311.GB28489@arm.com>
 <0de87be6-7041-c58b-a01f-3d6e3333c6f0@huawei.com>
 <20210804111402.GB4857@arm.com>
Message-ID: <d2280ab3-2c31-7525-b03d-b4717273b2c3@huawei.com>


On 2021/8/4 19:14, Catalin Marinas wrote:
> On Mon, Aug 02, 2021 at 10:39:04AM +0800, Kefeng Wang wrote:
>> On 2021/8/1 23:23, Catalin Marinas wrote:
>>> On Tue, Jul 20, 2021 at 10:51:03AM +0800, Kefeng Wang wrote:
>>>> There are some fixed locations in the vmalloc area be reserved
>>>> in ARM(see iotable_init()) and ARM64(see map_kernel()), but for
>>>> pcpu_page_first_chunk(), it calls vm_area_register_early() and
>>>> choose VMALLOC_START as the start address of vmap area which
>>>> could be conflicted with above address, then could trigger a
>>>> BUG_ON in vm_area_add_early().
>>>>
>>>> Let's choose the end of existing address range in vmlist as the
>>>> start address instead of VMALLOC_START to avoid the BUG_ON.
>>>>
>>>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>>>> ---
>>>>    mm/vmalloc.c | 8 +++++---
>>>>    1 file changed, 5 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
>>>> index d5cd52805149..a98cf97f032f 100644
>>>> --- a/mm/vmalloc.c
>>>> +++ b/mm/vmalloc.c
>>>> @@ -2238,12 +2238,14 @@ void __init vm_area_add_early(struct vm_struct *vm)
>>>>     */
>>>>    void __init vm_area_register_early(struct vm_struct *vm, size_t align)
>>>>    {
>>>> -	static size_t vm_init_off __initdata;
>>>> +	unsigned long vm_start = VMALLOC_START;
>>>> +	struct vm_struct *tmp;
>>>>    	unsigned long addr;
>>>> -	addr = ALIGN(VMALLOC_START + vm_init_off, align);
>>>> -	vm_init_off = PFN_ALIGN(addr + vm->size) - VMALLOC_START;
>>>> +	for (tmp = vmlist; tmp; tmp = tmp->next)
>>>> +		vm_start = (unsigned long)tmp->addr + tmp->size;
>>>> +	addr = ALIGN(vm_start, align);
>>>>    	vm->addr = (void *)addr;
>>>>    	vm_area_add_early(vm);
>>> Is there a risk of breaking other architectures? It doesn't look like to
>>> me but I thought I'd ask.
>> Before this patch, vm_init_off is to record the offset from VMALLOC_START,
>>
>> but it use VMALLOC_START as start address on the function
>> vm_area_register_early()
>>
>> called firstly,? this will cause the BUG_ON.
>>
>> With this patch, the most important change is that we choose the start
>> address via
>>
>> dynamic calculate the 'start' address by traversing the list.
>>
>> [wkf at localhost linux-next]$ git grep vm_area_register_early
>> arch/alpha/mm/init.c: vm_area_register_early(&console_remap_vm, PAGE_SIZE);
>> arch/x86/xen/p2m.c:???? vm_area_register_early(&vm, PMD_SIZE *
>> PMDS_PER_MID_PAGE);
>> mm/percpu.c:??? vm_area_register_early(&vm, PAGE_SIZE);
>> [wkf at localhost linux-next]$ git grep vm_area_add_early
>> arch/arm/mm/ioremap.c:? vm_area_add_early(vm);
>> arch/arm64/mm/mmu.c:??? vm_area_add_early(vma);
>>
>> x86/alpha won't call vm_area_add_early(), only arm64 could call both vm_area_add_early()
>> and  vm_area_register_early() when this patchset is merged. so it won't break other architectures.
> Thanks for checking.
>
>>> Also, instead of always picking the end, could we search for a range
>>> that fits?
>> We only need a space in vmalloc range,? using end or a range in the middle
>> is not different.
> I was thinking of making it more future-proof in case one registers a
> vm area towards the end of the range. It's fairly easy to pick a range
> in the middle now that you are adding a list traversal.
ok,? will chose a suitable hole in the vmalloc range.
>


From jan.kiszka at siemens.com  Thu Aug  5 05:49:10 2021
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Thu, 5 Aug 2021 14:49:10 +0200
Subject: [PATCH v2 0/6] CAN: Add support for CAN in AM65,J721e and AM64
In-Reply-To: <cfd7df02-37ed-6286-0232-2e92bf1f67b4@ti.com>
References: <20210726101012.26983-1-a-govindraju@ti.com>
 <20210802124509.z23lfg7xxkqaakbo@truce>
 <36011cee-f617-02ed-7446-c297ba65e6bf@ti.com>
 <35b0e2dc-0591-0a2f-8e3d-4177792a13fa@siemens.com>
 <cfd7df02-37ed-6286-0232-2e92bf1f67b4@ti.com>
Message-ID: <caa97a4e-5e84-2aa6-3a4c-3bbe29fb7a58@siemens.com>

On 05.08.21 14:44, Aswath Govindraju wrote:
> Hi Jan,
> 
> On 05/08/21 6:10 pm, Jan Kiszka wrote:
>> On 05.08.21 14:32, Aswath Govindraju wrote:
>>> Hi,
>>>
>>> On 02/08/21 6:15 pm, Nishanth Menon wrote:
>>>> On 15:40-20210726, Aswath Govindraju wrote:
>>>>> The following series of patches add support for CAN in SoC's AM65, J721e
>>>>> and AM64.
>>>>>
>>>>> This patch series is dependent on [1] and [2] and I have requested for an
>>>>> immutable tag from the Marc Kleine-Budde(maintainer of net tree).
>>>>>
>>>>> [1] - https://lore.kernel.org/patchwork/patch/1423048/
>>>>> [2] - https://www.spinics.net/lists/linux-can/msg08108.html
>>>>>
>>>>> changes since v1 -
>>>>> - changed the message ram configuration to use the maximum value
>>>>>   in each field, for better performance.
>>>>>
>>>>> Aswath Govindraju (3):
>>>>>   arm64: dts: ti: am654-base-board: Disable mcan nodes
>>>>>   arm64: dts: ti: k3-am64-main: Add support for MCAN
>>>>>   arm64: dts: ti: k3-am642-evm/sk: Add support for main domain mcan
>>>>>     nodes in EVM and disable them on SK
>>>>>
>>>>> Faiz Abbas (3):
>>>>>   arm64: dts: ti: k3-am65-mcu: Add Support for MCAN
>>>>>   arm64: dts: ti: k3-j721e: Add support for MCAN nodes
>>>>>   arm64: dts: ti: k3-j721e-common-proc-board: Add support for mcu_mcan
>>>>>     nodes
>>>>
>>>> I noticed in my checkup: https://pastebin.ubuntu.com/p/zSk39M943N/
>>>> warnings with dtbs_check, I think the bindings need a little more help
>>>> here (please also notice the iot platform warnings getting introduced).
>>>>
>>>
>>> Jan,
>>>
>>> Can you please point me to the schematics for iot platform? Also, is CAN
>>> subsystem brought out on the iot platform boards?
>>
>> Schematics aren't publicly available. If you have specific questions, I
>> may help, though.
>>
>> CAN is not in use yet (not connected AFAIK).
>>
> 
> Thank you for clarifying this. I will disable the CAN DT nodes in
> k3-am65-iot2050-common.dtsi in my respin.
> 

That is not a problem for the current design, so you can go ahead with it.

Current defconfig - though not yet upstream based - can be found at [1].
The CAN subsystem is enabled, but not the AM65x CAN driver.

Jan

[1]
https://github.com/siemens/meta-iot2050/tree/master/recipes-kernel/linux/files

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux


From james.clark at arm.com  Thu Aug  5 05:56:33 2021
From: james.clark at arm.com (James Clark)
Date: Thu,  5 Aug 2021 13:56:33 +0100
Subject: [PATCH v2 0/1] perf tools: Warning fixes
Message-ID: <20210805125634.873368-1-james.clark@arm.com>

Changes since v1:
 * Remove first 5 patches as they have been applied to perf/core
 * Add Leo's kernel symbols suggestion and reviewed by tag
 * Add reference to debuginfod as suggested by Arnaldo
 
 Applies to perf/core f3c33cbd92

James Clark (1):
  perf cs-etm: Add warnings for missing DSOs

 tools/perf/util/cs-etm.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

-- 
2.23.0



From james.clark at arm.com  Thu Aug  5 05:56:34 2021
From: james.clark at arm.com (James Clark)
Date: Thu,  5 Aug 2021 13:56:34 +0100
Subject: [PATCH v2 1/1] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <20210805125634.873368-1-james.clark@arm.com>
References: <20210805125634.873368-1-james.clark@arm.com>
Message-ID: <20210805125634.873368-2-james.clark@arm.com>

Currently decode will silently fail if no binary data is available for
the decode. This is made worse if only partial data is available because
the decode will appear to work, but any trace from that missing DSO will
silently not be generated.

Add a UI popup once if there is any data missing, and then warn in the
bottom left for each individual DSO that's missing.

Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/perf/util/cs-etm.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index f4b2bff533f3..b59d234e437d 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -716,8 +716,17 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
 
 	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
 
-	if (len <= 0)
+	if (len <= 0) {
+		ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from the traced system.\n"
+				 "              Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols.\n");
+		if (!al.map->dso->auxtrace_warned) {
+			pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
+				    address,
+				    al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
+			al.map->dso->auxtrace_warned = true;
+		}
 		return 0;
+	}
 
 	return len;
 }
-- 
2.23.0



From james.clark at arm.com  Thu Aug  5 05:59:49 2021
From: james.clark at arm.com (James Clark)
Date: Thu, 5 Aug 2021 13:59:49 +0100
Subject: [RFC PATCH 6/6] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <20210803140122.GC247709@leoy-ThinkPad-X240s>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-7-james.clark@arm.com>
 <20210802154145.GC148327@leoy-ThinkPad-X240s> <YQlDefz+g45dqFsP@kernel.org>
 <20210803140122.GC247709@leoy-ThinkPad-X240s>
Message-ID: <b03f9794-ff84-c869-0370-e8f13c577ed5@arm.com>



On 03/08/2021 15:01, Leo Yan wrote:
>> one can also use debuginfod-client, which, as time passes, probably will
>> be the main way of finding DSOs now that we have build-ids in
>> PERF_RECORD_MMAP2 and debuginfod servers such as:
>>
>> export DEBUGINFOD_URLS=https://debuginfod.fedoraproject.org/
> If so, maybe should use more general description for missing DSO.
> 
>> https://fedoraproject.org/wiki/Debuginfod
>>  
>>> With this improvement, the patch looks good to me:
>>>
>>> Reviewed-by: Leo Yan <leo.yan at linaro.org>
>> Does this apply to the other 5 patches in this series?
> I finished to reivew patches 01, 04, 05, 06/06, so my review tag can
> apply on these patches.  Current patch 06/06 needs James to improve for
> the comments.

Thanks for the reviews, I've submitted v2.

I also had a play around with debuginfod, it looks promising.
Especially if it's integrated with perf report, which I assume is the plan?

Thanks
James


From james.clark at arm.com  Thu Aug  5 06:03:53 2021
From: james.clark at arm.com (James Clark)
Date: Thu,  5 Aug 2021 14:03:53 +0100
Subject: [PATCH v3 0/1] perf tools: Warning fixes
Message-ID: <20210805130354.878120-1-james.clark@arm.com>

Changes since v2:
   Add Leo's reviewed by tag that I missed
   
James Clark (1):
  perf cs-etm: Add warnings for missing DSOs

 tools/perf/util/cs-etm.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

-- 
2.23.0



From james.clark at arm.com  Thu Aug  5 06:03:54 2021
From: james.clark at arm.com (James Clark)
Date: Thu,  5 Aug 2021 14:03:54 +0100
Subject: [PATCH v3 1/1] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <20210805130354.878120-1-james.clark@arm.com>
References: <20210805130354.878120-1-james.clark@arm.com>
Message-ID: <20210805130354.878120-2-james.clark@arm.com>

Currently decode will silently fail if no binary data is available for
the decode. This is made worse if only partial data is available because
the decode will appear to work, but any trace from that missing DSO will
silently not be generated.

Add a UI popup once if there is any data missing, and then warn in the
bottom left for each individual DSO that's missing.

Reviewed-by: Leo Yan <leo.yan at linaro.org>
Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/perf/util/cs-etm.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index f4b2bff533f3..b59d234e437d 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -716,8 +716,17 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
 
 	len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size);
 
-	if (len <= 0)
+	if (len <= 0) {
+		ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from the traced system.\n"
+				 "              Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols.\n");
+		if (!al.map->dso->auxtrace_warned) {
+			pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n",
+				    address,
+				    al.map->dso->long_name ? al.map->dso->long_name : "Unknown");
+			al.map->dso->auxtrace_warned = true;
+		}
 		return 0;
+	}
 
 	return len;
 }
-- 
2.23.0



From pgwipeout at gmail.com  Thu Aug  5 06:05:53 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 5 Aug 2021 09:05:53 -0400
Subject: [PATCH v3 2/7] soc: rockchip: io-domain: add rk3568 support
In-Reply-To: <20210805120107.27007-3-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
 <20210805120107.27007-3-michael.riesch@wolfvision.net>
Message-ID: <CAMdYzYrpXs_vY6OxqL54xFsKu0TJu_G5myTTfOA8nAygkUJN5g@mail.gmail.com>

On Thu, Aug 5, 2021 at 8:01 AM Michael Riesch
<michael.riesch at wolfvision.net> wrote:
>
> From: Jianqun Xu <jay.xu at rock-chips.com>
>
> The io-domain registers on RK3568 SoCs have three separated bits to
> enable/disable the 1.8v/2.5v/3.3v power.
>
> This patch make the write to be a operation, allow rk3568 uses a private
> register set function.
>
> Since the 2.5v is not used on RK3568, so the driver only set
> 1.8v [enable] + 3.3v [disable] for 1.8v mode
> 1.8v [disable] + 3.3v [enable] for 3.3v mode
>
> There is not register order requirement which has been cleared by our IC
> team.

Tested on Quartz64 Model A, Quartz64 Model B.
Tested-by: Peter Geis <pgwipeout at gmail.com>

>
> Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
> ---
>  drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
>  1 file changed, 80 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
> index cf8182fc3642..13c446fd33a9 100644
> --- a/drivers/soc/rockchip/io-domain.c
> +++ b/drivers/soc/rockchip/io-domain.c
> @@ -51,13 +51,11 @@
>  #define RK3399_PMUGRF_CON0_VSEL                BIT(8)
>  #define RK3399_PMUGRF_VSEL_SUPPLY_NUM  9
>
> -struct rockchip_iodomain;
> +#define RK3568_PMU_GRF_IO_VSEL0                (0x0140)
> +#define RK3568_PMU_GRF_IO_VSEL1                (0x0144)
> +#define RK3568_PMU_GRF_IO_VSEL2                (0x0148)
>
> -struct rockchip_iodomain_soc_data {
> -       int grf_offset;
> -       const char *supply_names[MAX_SUPPLIES];
> -       void (*init)(struct rockchip_iodomain *iod);
> -};
> +struct rockchip_iodomain;
>
>  struct rockchip_iodomain_supply {
>         struct rockchip_iodomain *iod;
> @@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
>         int idx;
>  };
>
> +struct rockchip_iodomain_soc_data {
> +       int grf_offset;
> +       const char *supply_names[MAX_SUPPLIES];
> +       void (*init)(struct rockchip_iodomain *iod);
> +       int (*write)(struct rockchip_iodomain_supply *supply, int uV);
> +};
> +
>  struct rockchip_iodomain {
>         struct device *dev;
>         struct regmap *grf;
>         const struct rockchip_iodomain_soc_data *soc_data;
>         struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
> +       int (*write)(struct rockchip_iodomain_supply *supply, int uV);
>  };
>
> +static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
> +{
> +       struct rockchip_iodomain *iod = supply->iod;
> +       u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
> +       u32 val0, val1;
> +       int b;
> +
> +       switch (supply->idx) {
> +       case 0: /* pmuio1 */
> +               break;
> +       case 1: /* pmuio2 */
> +               b = supply->idx;
> +               val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
> +               b = supply->idx + 4;
> +               val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
> +
> +               regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
> +               regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
> +               break;
> +       case 3: /* vccio2 */
> +               break;
> +       case 2: /* vccio1 */
> +       case 4: /* vccio3 */
> +       case 5: /* vccio4 */
> +       case 6: /* vccio5 */
> +       case 7: /* vccio6 */
> +       case 8: /* vccio7 */
> +               b = supply->idx - 1;
> +               val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
> +               val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
> +
> +               regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
> +               regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
> +               break;
> +       default:
> +               return -EINVAL;
> +       };
> +
> +       return 0;
> +}
> +
>  static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
>                                    int uV)
>  {
> @@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
>                         return NOTIFY_BAD;
>         }
>
> -       ret = rockchip_iodomain_write(supply, uV);
> +       ret = supply->iod->write(supply, uV);
>         if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
>                 return NOTIFY_BAD;
>
> @@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
>         .init = rk3399_pmu_iodomain_init,
>  };
>
> +static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
> +       .grf_offset = 0x140,
> +       .supply_names = {
> +               "pmuio1",
> +               "pmuio2",
> +               "vccio1",
> +               "vccio2",
> +               "vccio3",
> +               "vccio4",
> +               "vccio5",
> +               "vccio6",
> +               "vccio7",
> +       },
> +       .write = rk3568_iodomain_write,
> +};
> +
>  static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
>         .grf_offset = 0x404,
>         .supply_names = {
> @@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
>                 .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
>                 .data = &soc_data_rk3399_pmu
>         },
> +       {
> +               .compatible = "rockchip,rk3568-pmu-io-voltage-domain",
> +               .data = &soc_data_rk3568_pmu
> +       },
>         {
>                 .compatible = "rockchip,rv1108-io-voltage-domain",
>                 .data = &soc_data_rv1108
> @@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>         match = of_match_node(rockchip_iodomain_match, np);
>         iod->soc_data = match->data;
>
> +       if (iod->soc_data->write)
> +               iod->write = iod->soc_data->write;
> +       else
> +               iod->write = rockchip_iodomain_write;
> +
>         parent = pdev->dev.parent;
>         if (parent && parent->of_node) {
>                 iod->grf = syscon_node_to_regmap(parent->of_node);
> @@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>                 supply->reg = reg;
>                 supply->nb.notifier_call = rockchip_iodomain_notify;
>
> -               ret = rockchip_iodomain_write(supply, uV);
> +               ret = iod->write(supply, uV);
>                 if (ret) {
>                         supply->reg = NULL;
>                         goto unreg_notify;
> --
> 2.17.1
>


From lee.jones at linaro.org  Thu Aug  5 06:13:40 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 5 Aug 2021 14:13:40 +0100
Subject: [RFC v2 2/4] mfd: Add Rockchip rk817 battery charger support
In-Reply-To: <20210726190130.1973-3-macroalpha82@gmail.com>
References: <20210726190130.1973-1-macroalpha82@gmail.com>
 <20210726190130.1973-3-macroalpha82@gmail.com>
Message-ID: <YQvkBAaFHIGtvmKz@google.com>

On Mon, 26 Jul 2021, Chris Morgan wrote:

> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Add rk817 charger support cell to rk808 mfd driver.
> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
> ---
>  drivers/mfd/rk808.c       | 16 ++++++-
>  include/linux/mfd/rk808.h | 87 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 102 insertions(+), 1 deletion(-)

For my own reference (apply this as-is to your sign-off block):

  Acked-for-MFD-by: Lee Jones <lee.jones at linaro.org>

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From dafna.hirschfeld at collabora.com  Thu Aug  5 06:22:03 2021
From: dafna.hirschfeld at collabora.com (Dafna Hirschfeld)
Date: Thu, 5 Aug 2021 15:22:03 +0200
Subject: [PATCH v7 04/12] iommu/mediatek: Add device_link between the
 consumer and the larb devices
In-Reply-To: <20210730025238.22456-5-yong.wu@mediatek.com>
References: <20210730025238.22456-1-yong.wu@mediatek.com>
 <20210730025238.22456-5-yong.wu@mediatek.com>
Message-ID: <3f359c03-df44-2410-3172-2f17e620cada@collabora.com>



On 30.07.21 04:52, Yong Wu wrote:
> MediaTek IOMMU-SMI diagram is like below. all the consumer connect with
> smi-larb, then connect with smi-common.
> 
>          M4U
>           |
>      smi-common
>           |
>    -------------
>    |         |    ...
>    |         |
> larb1     larb2
>    |         |
> vdec       venc
> 
> When the consumer works, it should enable the smi-larb's power which
> also need enable the smi-common's power firstly.
> 
> Thus, First of all, use the device link connect the consumer and the
> smi-larbs. then add device link between the smi-larb and smi-common.
> 
> This patch adds device_link between the consumer and the larbs.
> 
> When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling
> pm_runtime_xx to keep the original status of clocks. It can avoid two
> issues:
> 1) Display HW show fastlogo abnormally reported in [1]. At the beggining,
> all the clocks are enabled before entering kernel, but the clocks for
> display HW(always in larb0) will be gated after clk_enable and clk_disable
> called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock
> operation happened before display driver probe. At that time, the display
> HW will be abnormal.
> 
> 2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip
> pm_runtime_xx to avoid the deadlock.
> 
> Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then
> device_link_removed should be added explicitly.
> 
> [1] https://lore.kernel.org/linux-mediatek/1564213888.22908.4.camel at mhfsdcap03/
> [2] https://lore.kernel.org/patchwork/patch/1086569/
> 
> Suggested-by: Tomasz Figa <tfiga at chromium.org>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Tested-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com> # on mt8173

Hi, unfortunately, I have to take back the Tested-by tag.
I am now testing the mtk-vcodec with latest kernel + patches sent from the mailing list:
https://gitlab.collabora.com/eballetbo/linux/-/commits/topic/chromeos/chromeos-5.14
which includes this patchset.

On chromeos I open a video conference with googl-meet which cause the mtk-vcodec vp8 encoder to run.
If I kill it with `killall -9 chrome` I get some page fault messages from the iommu:

[  837.255952] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.265696] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.282367] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.299028] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.315683] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.332345] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.349004] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.365665] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.382329] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
[  837.400002] mtk-iommu 10205000.iommu: fault type=0x5 iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read

In addition, running the encoder tests from the shell:

sudo --user=#1000 /usr/local/libexec/chrome-binary-tests/video_encode_accelerator_tests --gtest_filter=VideoEncoderTest.FlushAtEndOfStream_Multiple*  --codec=vp8 /usr/local/share/tast/data/chromiumos/tast/local/bundles/cros/video/data/tulip2-320x180.yuv --disable_validator

At some point it fails with the error

[ 5472.161821] [MTK_V4L2][ERROR] mtk_vcodec_wait_for_done_ctx:32: [290] ctx->type=1, cmd=1, wait_event_interruptible_timeout time=1000ms out 0 0!
[ 5472.174678] [MTK_VCODEC][ERROR][290]: vp8_enc_encode_frame() irq_status=0 failed
[ 5472.182687] [MTK_V4L2][ERROR] mtk_venc_worker:1239: venc_if_encode failed=-5


If you have any idea of what might be the problem or how to debug?

Thanks,
Dafna

> ---
>   drivers/iommu/mtk_iommu.c    | 22 ++++++++++++++++++++++
>   drivers/iommu/mtk_iommu_v1.c | 20 +++++++++++++++++++-
>   2 files changed, 41 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index a02dde094788..ee742900cf4b 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -571,22 +571,44 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
>   {
>   	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>   	struct mtk_iommu_data *data;
> +	struct device_link *link;
> +	struct device *larbdev;
> +	unsigned int larbid;
>   
>   	if (!fwspec || fwspec->ops != &mtk_iommu_ops)
>   		return ERR_PTR(-ENODEV); /* Not a iommu client device */
>   
>   	data = dev_iommu_priv_get(dev);
>   
> +	/*
> +	 * Link the consumer device with the smi-larb device(supplier)
> +	 * The device in each a larb is a independent HW. thus only link
> +	 * one larb here.
> +	 */
> +	larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
> +	larbdev = data->larb_imu[larbid].dev;
> +	link = device_link_add(dev, larbdev,
> +			       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
> +	if (!link)
> +		dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
>   	return &data->iommu;
>   }
>   
>   static void mtk_iommu_release_device(struct device *dev)
>   {
>   	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> +	struct mtk_iommu_data *data;
> +	struct device *larbdev;
> +	unsigned int larbid;
>   
>   	if (!fwspec || fwspec->ops != &mtk_iommu_ops)
>   		return;
>   
> +	data = dev_iommu_priv_get(dev);
> +	larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
> +	larbdev = data->larb_imu[larbid].dev;
> +	device_link_remove(dev, larbdev);
> +
>   	iommu_fwspec_free(dev);
>   }
>   
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index c259433f1130..806d4200665b 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -424,7 +424,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
>   	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
>   	struct of_phandle_args iommu_spec;
>   	struct mtk_iommu_data *data;
> -	int err, idx = 0;
> +	int err, idx = 0, larbid;
> +	struct device_link *link;
> +	struct device *larbdev;
>   
>   	/*
>   	 * In the deferred case, free the existed fwspec if the dev already has,
> @@ -454,6 +456,14 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
>   
>   	data = dev_iommu_priv_get(dev);
>   
> +	/* Link the consumer device with the smi-larb device(supplier) */
> +	larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
> +	larbdev = data->larb_imu[larbid].dev;
> +	link = device_link_add(dev, larbdev,
> +			       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
> +	if (!link)
> +		dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
> +
>   	return &data->iommu;
>   }
>   
> @@ -474,10 +484,18 @@ static void mtk_iommu_probe_finalize(struct device *dev)
>   static void mtk_iommu_release_device(struct device *dev)
>   {
>   	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> +	struct mtk_iommu_data *data;
> +	struct device *larbdev;
> +	unsigned int larbid;
>   
>   	if (!fwspec || fwspec->ops != &mtk_iommu_ops)
>   		return;
>   
> +	data = dev_iommu_priv_get(dev);
> +	larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
> +	larbdev = data->larb_imu[larbid].dev;
> +	device_link_remove(dev, larbdev);
> +
>   	iommu_fwspec_free(dev);
>   }
>   
> 


From ardb at kernel.org  Thu Aug  5 06:22:32 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 5 Aug 2021 15:22:32 +0200
Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <CAMj1kXHNjeDb2HuPeV_6Er4oALVKFz+g=gQ_0rf+JW22NxqqTA@mail.gmail.com>

On Thu, 5 Aug 2021 at 10:10, Shameer Kolothum
<shameerali.kolothum.thodi at huawei.com> wrote:
>
> Hi,
>
> The series adds support to IORT RMR nodes specified in IORT
> Revision E.b -ARM DEN 0049E[0]. RMR nodes are used to describe
> memory ranges that are used by endpoints and require a unity
> mapping in SMMU.
>
> We have faced issues with 3408iMR RAID controller cards which
> fail to boot when SMMU is enabled. This is because these
> controllers make use of host memory for various caching related
> purposes and when SMMU is enabled the iMR firmware fails to
> access these memory regions as there is no mapping for them.
> IORT RMR provides a way for UEFI to describe and report these
> memory regions so that the kernel can make a unity mapping for
> these in SMMU.
>

Does this mean we are ignoring the RMR memory ranges, and exposing the
entire physical address space to devices using the stream IDs in
question?


> Change History:
>
> v6 --> v7
>
> The only change from v6 is the fix pointed out by Steve to
> the SMMUv2 SMR bypass install in patch #8.
>
> Thanks to the Tested-by tags by Laurentiu with SMMUv2 and
> Hanjun/Huiqiang with SMMUv3 for v6. I haven't added the tags
> yet as the series still needs more review[1].
>
> Feedback and tests on this series is very much appreciated.
>
> v5 --> v6
> - Addressed comments from Robin & Lorenzo.
>   : Moved iort_parse_rmr() to acpi_iort_init() from
>     iort_init_platform_devices().
>   : Removed use of struct iort_rmr_entry during the initial
>     parse. Using struct iommu_resv_region instead.
>   : Report RMR address alignment and overlap errors, but continue.
>   : Reworked arm_smmu_init_bypass_stes() (patch # 6).
> - Updated SMMUv2 bypass SMR code. Thanks to Jon N (patch #8).
> - Set IOMMU protection flags(IOMMU_CACHE, IOMMU_MMIO) based
>   on Type of RMR region. Suggested by Jon N.
>
> Thanks,
> Shameer
> [0] https://developer.arm.com/documentation/den0049/latest/
> [1] https://lore.kernel.org/linux-acpi/20210716083442.1708-1-shameerali.kolothum.thodi at huawei.com/T/#m043c95b869973a834b2fd57f3e1ed0325c84f3b7
> ------
> v4 --> v5
>  -Added a fw_data union to struct iommu_resv_region and removed
>   struct iommu_rmr (Based on comments from Joerg/Robin).
>  -Added iommu_put_rmrs() to release mem.
>  -Thanks to Steve for verifying on SMMUv2, but not added the Tested-by
>   yet because of the above changes.
>
> v3 -->v4
> -Included the SMMUv2 SMR bypass install changes suggested by
>  Steve(patch #7)
> -As per Robin's comments, RMR reserve implementation is now
>  more generic  (patch #8) and dropped v3 patches 8 and 10.
> -Rebase to 5.13-rc1
>
> RFC v2 --> v3
>  -Dropped RFC tag as the ACPICA header changes are now ready to be
>   part of 5.13[0]. But this series still has a dependency on that patch.
>  -Added IORT E.b related changes(node flags, _DSM function 5 checks for
>   PCIe).
>  -Changed RMR to stream id mapping from M:N to M:1 as per the spec and
>   discussion here[1].
>  -Last two patches add support for SMMUv2(Thanks to Jon Nettleton!)
> ------
>
> Jon Nettleton (1):
>   iommu/arm-smmu: Get associated RMR info and install bypass SMR
>
> Shameer Kolothum (8):
>   iommu: Introduce a union to struct iommu_resv_region
>   ACPI/IORT: Add support for RMR node parsing
>   iommu/dma: Introduce generic helper to retrieve RMR info
>   ACPI/IORT: Add a helper to retrieve RMR memory regions
>   iommu/arm-smmu-v3: Introduce strtab init helper
>   iommu/arm-smmu-v3: Refactor arm_smmu_init_bypass_stes() to force
>     bypass
>   iommu/arm-smmu-v3: Get associated RMR info and install bypass STE
>   iommu/dma: Reserve any RMR regions associated with a dev
>
>  drivers/acpi/arm64/iort.c                   | 172 +++++++++++++++++++-
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  76 +++++++--
>  drivers/iommu/arm/arm-smmu/arm-smmu.c       |  48 ++++++
>  drivers/iommu/dma-iommu.c                   |  89 +++++++++-
>  include/linux/acpi_iort.h                   |   7 +
>  include/linux/dma-iommu.h                   |  13 ++
>  include/linux/iommu.h                       |  11 ++
>  7 files changed, 393 insertions(+), 23 deletions(-)
>
> --
> 2.17.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From shameerali.kolothum.thodi at huawei.com  Thu Aug  5 06:35:06 2021
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Thu, 5 Aug 2021 13:35:06 +0000
Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
In-Reply-To: <CAMj1kXHNjeDb2HuPeV_6Er4oALVKFz+g=gQ_0rf+JW22NxqqTA@mail.gmail.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <CAMj1kXHNjeDb2HuPeV_6Er4oALVKFz+g=gQ_0rf+JW22NxqqTA@mail.gmail.com>
Message-ID: <8df7fc81b00142b68126efd3c700a579@huawei.com>



> -----Original Message-----
> From: Ard Biesheuvel [mailto:ardb at kernel.org]
> Sent: 05 August 2021 14:23
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: Linux ARM <linux-arm-kernel at lists.infradead.org>; ACPI Devel Maling List
> <linux-acpi at vger.kernel.org>; Linux IOMMU
> <iommu at lists.linux-foundation.org>; Linuxarm <linuxarm at huawei.com>;
> Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>; Joerg Roedel
> <joro at 8bytes.org>; Robin Murphy <robin.murphy at arm.com>; Will Deacon
> <will at kernel.org>; wanghuiqiang <wanghuiqiang at huawei.com>; Guohanjun
> (Hanjun Guo) <guohanjun at huawei.com>; Steven Price
> <steven.price at arm.com>; Sami Mujawar <Sami.Mujawar at arm.com>; Jon
> Nettleton <jon at solid-run.com>; Eric Auger <eric.auger at redhat.com>;
> yangyicong <yangyicong at huawei.com>
> Subject: Re: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
> 
> On Thu, 5 Aug 2021 at 10:10, Shameer Kolothum
> <shameerali.kolothum.thodi at huawei.com> wrote:
> >
> > Hi,
> >
> > The series adds support to IORT RMR nodes specified in IORT
> > Revision E.b -ARM DEN 0049E[0]. RMR nodes are used to describe
> > memory ranges that are used by endpoints and require a unity
> > mapping in SMMU.
> >
> > We have faced issues with 3408iMR RAID controller cards which
> > fail to boot when SMMU is enabled. This is because these
> > controllers make use of host memory for various caching related
> > purposes and when SMMU is enabled the iMR firmware fails to
> > access these memory regions as there is no mapping for them.
> > IORT RMR provides a way for UEFI to describe and report these
> > memory regions so that the kernel can make a unity mapping for
> > these in SMMU.
> >
> 
> Does this mean we are ignoring the RMR memory ranges, and exposing the
> entire physical address space to devices using the stream IDs in
> question?

Nope. RMR node is used to describe the memory ranges used by end points
behind SMMU. And this information is used to create 1 : 1 mappings for those
ranges in SMMU. Anything outside those ranges will result in translation
fault(if there are no other dynamic DMA mappings).

Thanks,
Shameer

> 
> > Change History:
> >
> > v6 --> v7
> >
> > The only change from v6 is the fix pointed out by Steve to
> > the SMMUv2 SMR bypass install in patch #8.
> >
> > Thanks to the Tested-by tags by Laurentiu with SMMUv2 and
> > Hanjun/Huiqiang with SMMUv3 for v6. I haven't added the tags
> > yet as the series still needs more review[1].
> >
> > Feedback and tests on this series is very much appreciated.
> >
> > v5 --> v6
> > - Addressed comments from Robin & Lorenzo.
> >   : Moved iort_parse_rmr() to acpi_iort_init() from
> >     iort_init_platform_devices().
> >   : Removed use of struct iort_rmr_entry during the initial
> >     parse. Using struct iommu_resv_region instead.
> >   : Report RMR address alignment and overlap errors, but continue.
> >   : Reworked arm_smmu_init_bypass_stes() (patch # 6).
> > - Updated SMMUv2 bypass SMR code. Thanks to Jon N (patch #8).
> > - Set IOMMU protection flags(IOMMU_CACHE, IOMMU_MMIO) based
> >   on Type of RMR region. Suggested by Jon N.
> >
> > Thanks,
> > Shameer
> > [0] https://developer.arm.com/documentation/den0049/latest/
> > [1]
> https://lore.kernel.org/linux-acpi/20210716083442.1708-1-shameerali.koloth
> um.thodi at huawei.com/T/#m043c95b869973a834b2fd57f3e1ed0325c84f3b7
> > ------
> > v4 --> v5
> >  -Added a fw_data union to struct iommu_resv_region and removed
> >   struct iommu_rmr (Based on comments from Joerg/Robin).
> >  -Added iommu_put_rmrs() to release mem.
> >  -Thanks to Steve for verifying on SMMUv2, but not added the Tested-by
> >   yet because of the above changes.
> >
> > v3 -->v4
> > -Included the SMMUv2 SMR bypass install changes suggested by
> >  Steve(patch #7)
> > -As per Robin's comments, RMR reserve implementation is now
> >  more generic  (patch #8) and dropped v3 patches 8 and 10.
> > -Rebase to 5.13-rc1
> >
> > RFC v2 --> v3
> >  -Dropped RFC tag as the ACPICA header changes are now ready to be
> >   part of 5.13[0]. But this series still has a dependency on that patch.
> >  -Added IORT E.b related changes(node flags, _DSM function 5 checks for
> >   PCIe).
> >  -Changed RMR to stream id mapping from M:N to M:1 as per the spec and
> >   discussion here[1].
> >  -Last two patches add support for SMMUv2(Thanks to Jon Nettleton!)
> > ------
> >
> > Jon Nettleton (1):
> >   iommu/arm-smmu: Get associated RMR info and install bypass SMR
> >
> > Shameer Kolothum (8):
> >   iommu: Introduce a union to struct iommu_resv_region
> >   ACPI/IORT: Add support for RMR node parsing
> >   iommu/dma: Introduce generic helper to retrieve RMR info
> >   ACPI/IORT: Add a helper to retrieve RMR memory regions
> >   iommu/arm-smmu-v3: Introduce strtab init helper
> >   iommu/arm-smmu-v3: Refactor arm_smmu_init_bypass_stes() to force
> >     bypass
> >   iommu/arm-smmu-v3: Get associated RMR info and install bypass STE
> >   iommu/dma: Reserve any RMR regions associated with a dev
> >
> >  drivers/acpi/arm64/iort.c                   | 172
> +++++++++++++++++++-
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  76 +++++++--
> >  drivers/iommu/arm/arm-smmu/arm-smmu.c       |  48 ++++++
> >  drivers/iommu/dma-iommu.c                   |  89 +++++++++-
> >  include/linux/acpi_iort.h                   |   7 +
> >  include/linux/dma-iommu.h                   |  13 ++
> >  include/linux/iommu.h                       |  11 ++
> >  7 files changed, 393 insertions(+), 23 deletions(-)
> >
> > --
> > 2.17.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

From catalin.marinas at arm.com  Thu Aug  5 06:38:56 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu,  5 Aug 2021 14:38:56 +0100
Subject: [PATCH 0/4] arm64: entry: rework user return handling
In-Reply-To: <20210802140733.52716-1-mark.rutland@arm.com>
References: <20210802140733.52716-1-mark.rutland@arm.com>
Message-ID: <162817061093.16854.7299387625427703505.b4-ty@arm.com>

On Mon, 2 Aug 2021 15:07:29 +0100, Mark Rutland wrote:
> These patches (based on v5.14-rc3) rework the arm64 entry code,
> converting the bulk of `ret_to_user` and `work_pending` assembly code to
> C. This simplifies the code, and ensure that for each exception there is
> a single assembly<->c transition, which may make it easier to handle
> backtracing in future if metadata is necessary.
> 
> The bulk of the additions are comments added in patch 2, which clarify
> the semantics of some helpers functions used during entry/exit.
> 
> [...]

Applied to arm64 (for-next/entry). There was a small conflict in entry.S
with the changes from the for-next/mte branch - clear_mte_async_tcf
macro call moved around. I also fixed the typos that Joey mentioned.

Please have a look to make sure everthing is still ok. Thanks!

[1/4] arm64: entry: consolidate entry/exit helpers
      https://git.kernel.org/arm64/c/46a2b02d232e
[2/4] arm64: entry: clarify entry/exit helpers
      https://git.kernel.org/arm64/c/bc29b71f53b1
[3/4] arm64: entry: move bulk of ret_to_user to C
      https://git.kernel.org/arm64/c/4d1c2ee2709f
[4/4] arm64: entry: call exit_to_user_mode() from C
      https://git.kernel.org/arm64/c/e130338eed5d

-- 
Catalin



From john.garry at huawei.com  Thu Aug  5 06:40:05 2021
From: john.garry at huawei.com (John Garry)
Date: Thu, 5 Aug 2021 14:40:05 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Remove some unneeded init in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <ee1f3ab5-3acc-f442-f2d2-898cf88bc447@arm.com>
References: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
 <ee1f3ab5-3acc-f442-f2d2-898cf88bc447@arm.com>
Message-ID: <45a8af4f-4202-ecd8-0882-507acf9b2eb2@huawei.com>

On 05/08/2021 12:24, Robin Murphy wrote:
> On 2021-06-21 17:36, John Garry wrote:
>> Members of struct "llq" will be zero-inited, apart from member 
>> max_n_shift.
>> But we write llq.val straight after the init, so it was pointless to zero
>> init those other members. As such, separately init member max_n_shift
>> only.
>>
>> In addition, struct "head" is initialised to "llq" only so that member
>> max_n_shift is set. But that member is never referenced for "head", so
>> remove any init there.
>>
>> Removing these initializations is seen as a small performance 
>> optimisation,
>> as this code is (very) hot path.
> 
> I looked at this and immediately thought "surely the compiler can see 
> that all the prod/cons/val fields are written anyway and elide the 
> initialisation?", so I dumped the before and after disassembly, and... oh.
> 
> You should probably clarify that it's zero-initialising all the 
> cacheline padding which is both pointless and painful. With that,
> 
> Reviewed-by: Robin Murphy <robin.murphy at arm.com>
> 
> However, having looked this closely I'm now tangentially wondering why 
> max_n_shift isn't inside the padded union? It's read at the same time as 
> both prod and cons by queue_has_space(), and never updated, so there 
> doesn't appear to be any benefit to it being in a separate cacheline all 
> by itself, and llq is already twice as big as it needs to be.

I think that the problem is if the prod+cons 64b value and the shift are 
on the same cacheline, then we have a chance of accessing a stale 
cacheline twice:

static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
				       u64 *cmds, int n, bool sync)
{
	u64 cmd_sync[CMDQ_ENT_DWORDS];
	u32 prod;
	unsigned long flags;
	bool owner;
	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
	struct arm_smmu_ll_queue llq = {
		.max_n_shift = cmdq->q.llq.max_n_shift,	// here
	}, head = llq;
	int ret = 0;

	/* 1. Allocate some space in the queue */
	local_irq_save(flags);
	llq.val = READ_ONCE(cmdq->q.llq.val);	// and again here


since cmdq->q.llq is per-SMMU. If max_n_shift is on a separate 
cacheline, then it should never be stale.

I suppose they could be combined into a smaller sub-struct and loaded in 
a single operation, but it looks messy, and prob without much gain.

Thanks,
John

> Sorting 
> that would also be a good opportunity to store the value of interest in 
> its appropriate form so we're not needlessly recalculating 1 << shift 
> every flippin' time...
> 
> Robin.
> 
>> Signed-off-by: John Garry <john.garry at huawei.com>
>>
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
>> b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index 54b2f27b81d4..8a8ad49bb7fd 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -727,11 +727,11 @@ static int arm_smmu_cmdq_issue_cmdlist(struct 
>> arm_smmu_device *smmu,
>> ????? unsigned long flags;
>> ????? bool owner;
>> ????? struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
>> -??? struct arm_smmu_ll_queue llq = {
>> -??????? .max_n_shift = cmdq->q.llq.max_n_shift,
>> -??? }, head = llq;
>> +??? struct arm_smmu_ll_queue llq, head;
>> ????? int ret = 0;
>> +??? llq.max_n_shift = cmdq->q.llq.max_n_shift;
>> +
>> ????? /* 1. Allocate some space in the queue */
>> ????? local_irq_save(flags);
>> ????? llq.val = READ_ONCE(cmdq->q.llq.val);
>>
> .



From pzimmermann at dh-electronics.com  Thu Aug  5 06:50:35 2021
From: pzimmermann at dh-electronics.com (Pascal Zimmermann)
Date: Thu, 5 Aug 2021 15:50:35 +0200
Subject: [PATCH] ARM: imx_v6_v7_defconfig: enable driver of the LTC3676 PMIC
Message-ID: <20210805135035.124938-1-pzimmermann@dh-electronics.com>

The LTC3676 is a PMIC which is used on some i.MX6 based boards (like the
DHCOM i.MX6 Quad SoM), it was first used on the GW Ventana board, enable
LTC3676 driver in imx_v6_v7_defconfig.

Fixes: e3946fe805053 ("ARM: dts: add Gateworks Ventana support")
Signed-off-by: Pascal Zimmermann <pzimmermann at dh-electronics.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
Cc: Fabio Estevam <festevam at denx.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Marek Vasut <marex at denx.de>
Cc: kernel at dh-electronics.com
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 079fcd8d1d11..f94e3d11c3e9 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -252,6 +252,7 @@ CONFIG_REGULATOR_DA9052=y
 CONFIG_REGULATOR_DA9062=y
 CONFIG_REGULATOR_DA9063=y
 CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_LTC3676=y
 CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_REGULATOR_PFUZE100=y
-- 
2.11.0



From ardb at kernel.org  Thu Aug  5 07:09:00 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 5 Aug 2021 16:09:00 +0200
Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
In-Reply-To: <8df7fc81b00142b68126efd3c700a579@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <CAMj1kXHNjeDb2HuPeV_6Er4oALVKFz+g=gQ_0rf+JW22NxqqTA@mail.gmail.com>
 <8df7fc81b00142b68126efd3c700a579@huawei.com>
Message-ID: <CAMj1kXHTdDWz14B5Smzfmj5NQqCTTsgFjam6EevvOwFKLsmJzw@mail.gmail.com>

On Thu, 5 Aug 2021 at 15:35, Shameerali Kolothum Thodi
<shameerali.kolothum.thodi at huawei.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Ard Biesheuvel [mailto:ardb at kernel.org]
> > Sent: 05 August 2021 14:23
> > To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> > Cc: Linux ARM <linux-arm-kernel at lists.infradead.org>; ACPI Devel Maling List
> > <linux-acpi at vger.kernel.org>; Linux IOMMU
> > <iommu at lists.linux-foundation.org>; Linuxarm <linuxarm at huawei.com>;
> > Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>; Joerg Roedel
> > <joro at 8bytes.org>; Robin Murphy <robin.murphy at arm.com>; Will Deacon
> > <will at kernel.org>; wanghuiqiang <wanghuiqiang at huawei.com>; Guohanjun
> > (Hanjun Guo) <guohanjun at huawei.com>; Steven Price
> > <steven.price at arm.com>; Sami Mujawar <Sami.Mujawar at arm.com>; Jon
> > Nettleton <jon at solid-run.com>; Eric Auger <eric.auger at redhat.com>;
> > yangyicong <yangyicong at huawei.com>
> > Subject: Re: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
> >
> > On Thu, 5 Aug 2021 at 10:10, Shameer Kolothum
> > <shameerali.kolothum.thodi at huawei.com> wrote:
> > >
> > > Hi,
> > >
> > > The series adds support to IORT RMR nodes specified in IORT
> > > Revision E.b -ARM DEN 0049E[0]. RMR nodes are used to describe
> > > memory ranges that are used by endpoints and require a unity
> > > mapping in SMMU.
> > >
> > > We have faced issues with 3408iMR RAID controller cards which
> > > fail to boot when SMMU is enabled. This is because these
> > > controllers make use of host memory for various caching related
> > > purposes and when SMMU is enabled the iMR firmware fails to
> > > access these memory regions as there is no mapping for them.
> > > IORT RMR provides a way for UEFI to describe and report these
> > > memory regions so that the kernel can make a unity mapping for
> > > these in SMMU.
> > >
> >
> > Does this mean we are ignoring the RMR memory ranges, and exposing the
> > entire physical address space to devices using the stream IDs in
> > question?
>
> Nope. RMR node is used to describe the memory ranges used by end points
> behind SMMU. And this information is used to create 1 : 1 mappings for those
> ranges in SMMU. Anything outside those ranges will result in translation
> fault(if there are no other dynamic DMA mappings).
>

Excellent! It was not obvious to me from looking at the patches, so I
had to ask.

Thanks,
Ard.

>
> >
> > > Change History:
> > >
> > > v6 --> v7
> > >
> > > The only change from v6 is the fix pointed out by Steve to
> > > the SMMUv2 SMR bypass install in patch #8.
> > >
> > > Thanks to the Tested-by tags by Laurentiu with SMMUv2 and
> > > Hanjun/Huiqiang with SMMUv3 for v6. I haven't added the tags
> > > yet as the series still needs more review[1].
> > >
> > > Feedback and tests on this series is very much appreciated.
> > >
> > > v5 --> v6
> > > - Addressed comments from Robin & Lorenzo.
> > >   : Moved iort_parse_rmr() to acpi_iort_init() from
> > >     iort_init_platform_devices().
> > >   : Removed use of struct iort_rmr_entry during the initial
> > >     parse. Using struct iommu_resv_region instead.
> > >   : Report RMR address alignment and overlap errors, but continue.
> > >   : Reworked arm_smmu_init_bypass_stes() (patch # 6).
> > > - Updated SMMUv2 bypass SMR code. Thanks to Jon N (patch #8).
> > > - Set IOMMU protection flags(IOMMU_CACHE, IOMMU_MMIO) based
> > >   on Type of RMR region. Suggested by Jon N.
> > >
> > > Thanks,
> > > Shameer
> > > [0] https://developer.arm.com/documentation/den0049/latest/
> > > [1]
> > https://lore.kernel.org/linux-acpi/20210716083442.1708-1-shameerali.koloth
> > um.thodi at huawei.com/T/#m043c95b869973a834b2fd57f3e1ed0325c84f3b7
> > > ------
> > > v4 --> v5
> > >  -Added a fw_data union to struct iommu_resv_region and removed
> > >   struct iommu_rmr (Based on comments from Joerg/Robin).
> > >  -Added iommu_put_rmrs() to release mem.
> > >  -Thanks to Steve for verifying on SMMUv2, but not added the Tested-by
> > >   yet because of the above changes.
> > >
> > > v3 -->v4
> > > -Included the SMMUv2 SMR bypass install changes suggested by
> > >  Steve(patch #7)
> > > -As per Robin's comments, RMR reserve implementation is now
> > >  more generic  (patch #8) and dropped v3 patches 8 and 10.
> > > -Rebase to 5.13-rc1
> > >
> > > RFC v2 --> v3
> > >  -Dropped RFC tag as the ACPICA header changes are now ready to be
> > >   part of 5.13[0]. But this series still has a dependency on that patch.
> > >  -Added IORT E.b related changes(node flags, _DSM function 5 checks for
> > >   PCIe).
> > >  -Changed RMR to stream id mapping from M:N to M:1 as per the spec and
> > >   discussion here[1].
> > >  -Last two patches add support for SMMUv2(Thanks to Jon Nettleton!)
> > > ------
> > >
> > > Jon Nettleton (1):
> > >   iommu/arm-smmu: Get associated RMR info and install bypass SMR
> > >
> > > Shameer Kolothum (8):
> > >   iommu: Introduce a union to struct iommu_resv_region
> > >   ACPI/IORT: Add support for RMR node parsing
> > >   iommu/dma: Introduce generic helper to retrieve RMR info
> > >   ACPI/IORT: Add a helper to retrieve RMR memory regions
> > >   iommu/arm-smmu-v3: Introduce strtab init helper
> > >   iommu/arm-smmu-v3: Refactor arm_smmu_init_bypass_stes() to force
> > >     bypass
> > >   iommu/arm-smmu-v3: Get associated RMR info and install bypass STE
> > >   iommu/dma: Reserve any RMR regions associated with a dev
> > >
> > >  drivers/acpi/arm64/iort.c                   | 172
> > +++++++++++++++++++-
> > >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  76 +++++++--
> > >  drivers/iommu/arm/arm-smmu/arm-smmu.c       |  48 ++++++
> > >  drivers/iommu/dma-iommu.c                   |  89 +++++++++-
> > >  include/linux/acpi_iort.h                   |   7 +
> > >  include/linux/dma-iommu.h                   |  13 ++
> > >  include/linux/iommu.h                       |  11 ++
> > >  7 files changed, 393 insertions(+), 23 deletions(-)
> > >
> > > --
> > > 2.17.1
> > >
> > >
> > > _______________________________________________
> > > linux-arm-kernel mailing list
> > > linux-arm-kernel at lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From alexandre.torgue at foss.st.com  Thu Aug  5 07:29:20 2021
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Thu, 5 Aug 2021 16:29:20 +0200
Subject: [PATCH 1/7] dt-bindings: pinctrl: stm32: add new compatible for
 STM32MP135 SoC
In-Reply-To: <20210723132810.25728-2-alexandre.torgue@foss.st.com>
References: <20210723132810.25728-1-alexandre.torgue@foss.st.com>
 <20210723132810.25728-2-alexandre.torgue@foss.st.com>
Message-ID: <1d7fe9a6-bf37-e8ca-1bc3-fda536a10359@foss.st.com>

Hi Linus

On 7/23/21 3:28 PM, Alexandre Torgue wrote:
> New compatible to manage ball out and pin muxing of STM32MP135 SoC.
> 
> Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
> index 72877544ca78..dfee6d38a701 100644
> --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
> @@ -24,6 +24,7 @@ properties:
>         - st,stm32f746-pinctrl
>         - st,stm32f769-pinctrl
>         - st,stm32h743-pinctrl
> +      - st,stm32mp135-pinctrl
>         - st,stm32mp157-pinctrl
>         - st,stm32mp157-z-pinctrl
>   
> 

If you are ok with this patch, can I take it in my tree to avoid yaml 
validation issue ? If you disagree I'll wait the next cycle to take DT 
patches.

cheers
alex


From robin.murphy at arm.com  Thu Aug  5 07:41:57 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 5 Aug 2021 15:41:57 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Remove some unneeded init in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <45a8af4f-4202-ecd8-0882-507acf9b2eb2@huawei.com>
References: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
 <ee1f3ab5-3acc-f442-f2d2-898cf88bc447@arm.com>
 <45a8af4f-4202-ecd8-0882-507acf9b2eb2@huawei.com>
Message-ID: <577a625a-4fc5-7402-8e4f-4e0e5be93144@arm.com>

On 2021-08-05 14:40, John Garry wrote:
> On 05/08/2021 12:24, Robin Murphy wrote:
>> On 2021-06-21 17:36, John Garry wrote:
>>> Members of struct "llq" will be zero-inited, apart from member 
>>> max_n_shift.
>>> But we write llq.val straight after the init, so it was pointless to 
>>> zero
>>> init those other members. As such, separately init member max_n_shift
>>> only.
>>>
>>> In addition, struct "head" is initialised to "llq" only so that member
>>> max_n_shift is set. But that member is never referenced for "head", so
>>> remove any init there.
>>>
>>> Removing these initializations is seen as a small performance 
>>> optimisation,
>>> as this code is (very) hot path.
>>
>> I looked at this and immediately thought "surely the compiler can see 
>> that all the prod/cons/val fields are written anyway and elide the 
>> initialisation?", so I dumped the before and after disassembly, and... 
>> oh.
>>
>> You should probably clarify that it's zero-initialising all the 
>> cacheline padding which is both pointless and painful. With that,
>>
>> Reviewed-by: Robin Murphy <robin.murphy at arm.com>
>>
>> However, having looked this closely I'm now tangentially wondering why 
>> max_n_shift isn't inside the padded union? It's read at the same time 
>> as both prod and cons by queue_has_space(), and never updated, so 
>> there doesn't appear to be any benefit to it being in a separate 
>> cacheline all by itself, and llq is already twice as big as it needs 
>> to be.
> 
> I think that the problem is if the prod+cons 64b value and the shift are 
> on the same cacheline, then we have a chance of accessing a stale 
> cacheline twice:
> 
> static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
>  ?????????????????????? u64 *cmds, int n, bool sync)
> {
>  ????u64 cmd_sync[CMDQ_ENT_DWORDS];
>  ????u32 prod;
>  ????unsigned long flags;
>  ????bool owner;
>  ????struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
>  ????struct arm_smmu_ll_queue llq = {
>  ??????? .max_n_shift = cmdq->q.llq.max_n_shift,??? // here
>  ????}, head = llq;
>  ????int ret = 0;
> 
>  ????/* 1. Allocate some space in the queue */
>  ????local_irq_save(flags);
>  ????llq.val = READ_ONCE(cmdq->q.llq.val);??? // and again here
> 
> 
> since cmdq->q.llq is per-SMMU. If max_n_shift is on a separate 
> cacheline, then it should never be stale.

Ah, right, even though the accesses are always going to be close 
together, I suppose it could still technically cause some false sharing 
if someone else is trying to update prod at exactly the right time. I 
guess that might be why we need the explicit padding there in the first 
place, it's just a shame that it ends up wasting even more space with 
implicit padding at the end too (and I have a vague memory that trying 
to force member alignment and structure packing at the same time doesn't 
work well). Oh well.

> I suppose they could be combined into a smaller sub-struct and loaded in 
> a single operation, but it looks messy, and prob without much gain.

Indeed I wouldn't say that saving memory is the primary concern here, 
and any more convoluted code is hardly going to help performance. Plus 
it still wouldn't help the other cases where we're just copying the size 
into a fake queue to do some prod arithmetic - I hadn't fully clocked 
what was going on there when I skimmed through things earlier.

Disregarding the bogus layout change, though, do you reckon the rest of 
my idea makes sense?

Cheers,
Robin.


From andrzej.p at collabora.com  Thu Aug  5 07:42:39 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:39 +0200
Subject: [PATCH v3 03/10] hantro: Simplify postprocessor
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-4-andrzej.p@collabora.com>

From: Ezequiel Garcia <ezequiel at collabora.com>

Add a 'postprocessed' boolean property to struct hantro_fmt
to signal that a format is produced by the post-processor.
This will allow to introduce the G2 post-processor in a simple way.

Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
---
 drivers/staging/media/hantro/hantro.h          | 2 ++
 drivers/staging/media/hantro/hantro_postproc.c | 8 +-------
 drivers/staging/media/hantro/imx8m_vpu_hw.c    | 1 +
 drivers/staging/media/hantro/rockchip_vpu_hw.c | 1 +
 drivers/staging/media/hantro/sama5d4_vdec_hw.c | 1 +
 5 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
index c2e01959dc00..dd5e56765d4e 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/staging/media/hantro/hantro.h
@@ -263,6 +263,7 @@ struct hantro_ctx {
  * @max_depth:	Maximum depth, for bitstream formats
  * @enc_fmt:	Format identifier for encoder registers.
  * @frmsize:	Supported range of frame sizes (only for bitstream formats).
+ * @postprocessed: Indicates if this format needs the post-processor.
  */
 struct hantro_fmt {
 	char *name;
@@ -272,6 +273,7 @@ struct hantro_fmt {
 	int max_depth;
 	enum hantro_enc_fmt enc_fmt;
 	struct v4l2_frmsize_stepwise frmsize;
+	bool postprocessed;
 };
 
 struct hantro_reg {
diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/staging/media/hantro/hantro_postproc.c
index 882fb8bc5ddd..4549aec08feb 100644
--- a/drivers/staging/media/hantro/hantro_postproc.c
+++ b/drivers/staging/media/hantro/hantro_postproc.c
@@ -53,15 +53,9 @@ const struct hantro_postproc_regs hantro_g1_postproc_regs = {
 bool hantro_needs_postproc(const struct hantro_ctx *ctx,
 			   const struct hantro_fmt *fmt)
 {
-	struct hantro_dev *vpu = ctx->dev;
-
 	if (ctx->is_encoder)
 		return false;
-
-	if (!vpu->variant->postproc_fmts)
-		return false;
-
-	return fmt->fourcc != V4L2_PIX_FMT_NV12;
+	return fmt->postprocessed;
 }
 
 static void hantro_postproc_g1_enable(struct hantro_ctx *ctx)
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index 22fa7d2f3b64..02e61438220a 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -82,6 +82,7 @@ static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = {
 	{
 		.fourcc = V4L2_PIX_FMT_YUYV,
 		.codec_mode = HANTRO_MODE_NONE,
+		.postprocessed = true,
 	},
 };
 
diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c
index 6c1ad5534ce5..f372f767d4ff 100644
--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
+++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c
@@ -62,6 +62,7 @@ static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = {
 	{
 		.fourcc = V4L2_PIX_FMT_YUYV,
 		.codec_mode = HANTRO_MODE_NONE,
+		.postprocessed = true,
 	},
 };
 
diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
index f3fecc7248c4..b2fc1c5613e1 100644
--- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c
+++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
@@ -15,6 +15,7 @@ static const struct hantro_fmt sama5d4_vdec_postproc_fmts[] = {
 	{
 		.fourcc = V4L2_PIX_FMT_YUYV,
 		.codec_mode = HANTRO_MODE_NONE,
+		.postprocessed = true,
 	},
 };
 
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:40 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:40 +0200
Subject: [PATCH v3 04/10] hantro: Add quirk for NV12/NV12_4L4 capture format
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-5-andrzej.p@collabora.com>

From: Ezequiel Garcia <ezequiel at collabora.com>

The G2 core decoder engine produces NV12_4L4 format,
which is a simple NV12 4x4 tiled format. The driver currently
hides this format by always enabling the post-processor engine,
and therefore offering NV12 directly.

This is done without using the logic in hantro_postproc.c
and therefore makes it difficult to add VP9 cleanly.

Since fixing this is not easy, add a small quirk to force
NV12 if HEVC was configured, but otherwise declare NV12_4L4
as the pixel format in imx8mq_vpu_g2_variant.dec_fmts.

This will be used by the VP9 decoder which will be added soon.

Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
---
 drivers/staging/media/hantro/hantro_v4l2.c  | 14 ++++++++++++++
 drivers/staging/media/hantro/imx8m_vpu_hw.c |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
index bcb0bdff4a9a..d1f060c55fed 100644
--- a/drivers/staging/media/hantro/hantro_v4l2.c
+++ b/drivers/staging/media/hantro/hantro_v4l2.c
@@ -150,6 +150,20 @@ static int vidioc_enum_fmt(struct file *file, void *priv,
 	unsigned int num_fmts, i, j = 0;
 	bool skip_mode_none;
 
+	/*
+	 * The HEVC decoder on the G2 core needs a little quirk to offer NV12
+	 * only on the capture side. Once the post-processor logic is used,
+	 * we will be able to expose NV12_4L4 and NV12 as the other cases,
+	 * and therefore remove this quirk.
+	 */
+	if (capture && ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) {
+		if (f->index == 0) {
+			f->pixelformat = V4L2_PIX_FMT_NV12;
+			return 0;
+		}
+		return -EINVAL;
+	}
+
 	/*
 	 * When dealing with an encoder:
 	 *  - on the capture side we want to filter out all MODE_NONE formats.
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index 02e61438220a..a40b161e5956 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -134,7 +134,7 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {
 
 static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
 	{
-		.fourcc = V4L2_PIX_FMT_NV12,
+		.fourcc = V4L2_PIX_FMT_NV12_4L4,
 		.codec_mode = HANTRO_MODE_NONE,
 	},
 	{
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:36 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:36 +0200
Subject: [PATCH v3 00/10] VP9 codec V4L2 control interface
Message-ID: <20210805144246.11998-1-andrzej.p@collabora.com>

Dear all,

This patch series adds VP9 codec V4L2 control interface and two drivers
using the new controls. It is a follow-up of previous RFC v2 series [1].

In this new iteration, we've implemented VP9 hardware decoding on two devices:
Rockchip VDEC and Hantro G2, and tested on RK3399, i.MX8MQ and i.MX8MP.
The i.MX8M driver needs proper power domains support, though, which is a
subject of a different effort, but in all 3 cases we were able to run the
drivers.

GStreamer support is also available, the needed changes have been submitted
by Daniel Almeida [2]. This MR is ready to be merged, and just needs the
VP9 V4L2 controls to be merged and released.

Both rkvdec and hantro drivers are passing a significant number of VP9 tests
using Fluster[3]. There are still a few tests that are not passing, due to
dynamic frame resize (not yet supported by V4L2) and small size videos
(due to IP block limitations).

The series adds the VP9 codec V4L2 control API as uAPI, so it aims at being
merged without passing through staging, as agreed[4]. The ABI has been checked
for padding and verified to contain no holes. Please note, though,
that I kindly ask not to merge this until Nicolas Dufresne reviews it.

[1] https://patchwork.linuxtv.org/project/linux-media/cover/20210505123836.9573-1-andrzej.p at collabora.com/
[2] https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2144
[3] https://github.com/fluendo/fluster
[4] https://lore.kernel.org/linux-media/b8f83c93-67fd-09f5-9314-15746cbfdc61 at xs4all.nl/

Changes related to the RFC v2:

- added another driver including a postprocessor to de-tile
        codec-specific tiling
- reworked uAPI structs layout to follow VP8 style
- changed validation of loop filter params
- changed validation of segmentation params
- changed validation of VP9 frame params
- removed level lookup array from loop filter struct
        (can be computed by drivers)
- renamed some enum values to match the spec more closely
- V4L2 VP9 library changed the 'eob' member of
        'struct v4l2_vp9_frame_symbol_counts' so that it is an array
        of pointers instead of an array of pointers to arrays
        (IPs such as g2 creatively pass parts of the 'eob' counts in
        the 'coeff' counts)
- factored out several repeated portions of code
- minor nitpicks and cleanups

The series depends on the YUV tiled format support prepared by Ezequiel:
https://patchwork.linuxtv.org/project/linux-media/list/?series=6049.

Andrzej Pietrasiewicz (4):
  media: uapi: Add VP9 stateless decoder controls
  media: Add VP9 v4l2 library
  media: hantro: Prepare for other G2 codecs
  media: hantro: Support VP9 on the G2 core

Boris Brezillon (1):
  media: rkvdec: Add the VP9 backend

Ezequiel Garcia (5):
  hantro: postproc: Fix motion vector space size
  hantro: postproc: Introduce struct hantro_postproc_ops
  hantro: Simplify postprocessor
  hantro: Add quirk for NV12/NV12_4L4 capture format
  media: hantro: Support NV12 on the G2 core

 .../userspace-api/media/v4l/biblio.rst        |   10 +
 .../media/v4l/ext-ctrls-codec-stateless.rst   |  545 +++++
 .../media/v4l/pixfmt-compressed.rst           |   15 +
 .../media/v4l/vidioc-g-ext-ctrls.rst          |    8 +
 .../media/v4l/vidioc-queryctrl.rst            |   12 +
 .../media/videodev2.h.rst.exceptions          |    2 +
 drivers/media/v4l2-core/Kconfig               |    4 +
 drivers/media/v4l2-core/Makefile              |    1 +
 drivers/media/v4l2-core/v4l2-ctrls-core.c     |  174 ++
 drivers/media/v4l2-core/v4l2-ctrls-defs.c     |    8 +
 drivers/media/v4l2-core/v4l2-ioctl.c          |    1 +
 drivers/media/v4l2-core/v4l2-vp9.c            | 1850 +++++++++++++++++
 drivers/staging/media/hantro/Kconfig          |    1 +
 drivers/staging/media/hantro/Makefile         |    7 +-
 drivers/staging/media/hantro/hantro.h         |   40 +-
 drivers/staging/media/hantro/hantro_drv.c     |   18 +-
 drivers/staging/media/hantro/hantro_g2.c      |   27 +
 .../staging/media/hantro/hantro_g2_hevc_dec.c |   31 -
 drivers/staging/media/hantro/hantro_g2_regs.h |  104 +
 .../staging/media/hantro/hantro_g2_vp9_dec.c  |  978 +++++++++
 drivers/staging/media/hantro/hantro_hw.h      |   83 +-
 .../staging/media/hantro/hantro_postproc.c    |   79 +-
 drivers/staging/media/hantro/hantro_v4l2.c    |   20 +
 drivers/staging/media/hantro/hantro_vp9.c     |  240 +++
 drivers/staging/media/hantro/hantro_vp9.h     |  103 +
 drivers/staging/media/hantro/imx8m_vpu_hw.c   |   38 +-
 .../staging/media/hantro/rockchip_vpu_hw.c    |    7 +-
 .../staging/media/hantro/sama5d4_vdec_hw.c    |    3 +-
 drivers/staging/media/rkvdec/Kconfig          |    1 +
 drivers/staging/media/rkvdec/Makefile         |    2 +-
 drivers/staging/media/rkvdec/rkvdec-vp9.c     | 1078 ++++++++++
 drivers/staging/media/rkvdec/rkvdec.c         |   52 +-
 drivers/staging/media/rkvdec/rkvdec.h         |   12 +-
 include/media/v4l2-ctrls.h                    |    4 +
 include/media/v4l2-vp9.h                      |  182 ++
 include/uapi/linux/v4l2-controls.h            |  433 ++++
 include/uapi/linux/videodev2.h                |    6 +
 37 files changed, 6108 insertions(+), 71 deletions(-)
 create mode 100644 drivers/media/v4l2-core/v4l2-vp9.c
 create mode 100644 drivers/staging/media/hantro/hantro_g2.c
 create mode 100644 drivers/staging/media/hantro/hantro_g2_vp9_dec.c
 create mode 100644 drivers/staging/media/hantro/hantro_vp9.c
 create mode 100644 drivers/staging/media/hantro/hantro_vp9.h
 create mode 100644 drivers/staging/media/rkvdec/rkvdec-vp9.c
 create mode 100644 include/media/v4l2-vp9.h


base-commit: bfee75f73c37a2f46a6326eaa06f5db701f76f01
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:37 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:37 +0200
Subject: [PATCH v3 01/10] hantro: postproc: Fix motion vector space size
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-2-andrzej.p@collabora.com>

From: Ezequiel Garcia <ezequiel at collabora.com>

When the post-processor hardware block is enabled, the driver
allocates an internal queue of buffers for the decoder enginer,
and uses the vb2 queue for the post-processor engine.

For instance, on a G1 core, the decoder engine produces NV12 buffers
and the post-processor engine can produce YUY2 buffers. The decoder
engine expects motion vectors to be appended to the NV12 buffers,
but this is only required for CODECs that need motion vectors,
such as H.264.

Fix the post-processor logic accordingly.

Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
---
 drivers/staging/media/hantro/hantro_postproc.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/staging/media/hantro/hantro_postproc.c
index ed8916c950a4..07842152003f 100644
--- a/drivers/staging/media/hantro/hantro_postproc.c
+++ b/drivers/staging/media/hantro/hantro_postproc.c
@@ -132,9 +132,10 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)
 	unsigned int num_buffers = cap_queue->num_buffers;
 	unsigned int i, buf_size;
 
-	buf_size = ctx->dst_fmt.plane_fmt[0].sizeimage +
-		   hantro_h264_mv_size(ctx->dst_fmt.width,
-				       ctx->dst_fmt.height);
+	buf_size = ctx->dst_fmt.plane_fmt[0].sizeimage;
+	if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
+		buf_size += hantro_h264_mv_size(ctx->dst_fmt.width,
+						ctx->dst_fmt.height);
 
 	for (i = 0; i < num_buffers; ++i) {
 		struct hantro_aux_buf *priv = &ctx->postproc.dec_q[i];
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:38 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:38 +0200
Subject: [PATCH v3 02/10] hantro: postproc: Introduce struct
 hantro_postproc_ops
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-3-andrzej.p@collabora.com>

From: Ezequiel Garcia <ezequiel at collabora.com>

Turns out the post-processor block on the G2 core is substantially
different from the one on the G1 core. Introduce hantro_postproc_ops
with .enable and .disable methods, which will allow to support
the G2 post-processor cleanly.

Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
---
 drivers/staging/media/hantro/hantro.h         |  5 +--
 drivers/staging/media/hantro/hantro_hw.h      | 13 +++++++-
 .../staging/media/hantro/hantro_postproc.c    | 33 ++++++++++++++-----
 drivers/staging/media/hantro/imx8m_vpu_hw.c   |  2 +-
 .../staging/media/hantro/rockchip_vpu_hw.c    |  6 ++--
 .../staging/media/hantro/sama5d4_vdec_hw.c    |  2 +-
 6 files changed, 44 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
index c2e2dca38628..c2e01959dc00 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/staging/media/hantro/hantro.h
@@ -28,6 +28,7 @@
 
 struct hantro_ctx;
 struct hantro_codec_ops;
+struct hantro_postproc_ops;
 
 #define HANTRO_JPEG_ENCODER	BIT(0)
 #define HANTRO_ENCODERS		0x0000ffff
@@ -59,6 +60,7 @@ struct hantro_irq {
  * @num_dec_fmts:		Number of decoder formats.
  * @postproc_fmts:		Post-processor formats.
  * @num_postproc_fmts:		Number of post-processor formats.
+ * @postproc_ops:		Post-processor ops.
  * @codec:			Supported codecs
  * @codec_ops:			Codec ops.
  * @init:			Initialize hardware, optional.
@@ -69,7 +71,6 @@ struct hantro_irq {
  * @num_clocks:			number of clocks in the array
  * @reg_names:			array of register range names
  * @num_regs:			number of register range names in the array
- * @postproc_regs:		&struct hantro_postproc_regs pointer
  */
 struct hantro_variant {
 	unsigned int enc_offset;
@@ -80,6 +81,7 @@ struct hantro_variant {
 	unsigned int num_dec_fmts;
 	const struct hantro_fmt *postproc_fmts;
 	unsigned int num_postproc_fmts;
+	const struct hantro_postproc_ops *postproc_ops;
 	unsigned int codec;
 	const struct hantro_codec_ops *codec_ops;
 	int (*init)(struct hantro_dev *vpu);
@@ -90,7 +92,6 @@ struct hantro_variant {
 	int num_clocks;
 	const char * const *reg_names;
 	int num_regs;
-	const struct hantro_postproc_regs *postproc_regs;
 };
 
 /**
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index df7b5e3a57b9..4323e63dfbfc 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -170,6 +170,17 @@ struct hantro_postproc_ctx {
 	struct hantro_aux_buf dec_q[VB2_MAX_FRAME];
 };
 
+/**
+ * struct hantro_postproc_ops - post-processor operations
+ *
+ * @enable:	Enable the post-processor block. Optional.
+ * @disable:	Disable the post-processor block. Optional.
+ */
+struct hantro_postproc_ops {
+	void (*enable)(struct hantro_ctx *ctx);
+	void (*disable)(struct hantro_ctx *ctx);
+};
+
 /**
  * struct hantro_codec_ops - codec mode specific operations
  *
@@ -217,7 +228,7 @@ extern const struct hantro_variant rk3328_vpu_variant;
 extern const struct hantro_variant rk3399_vpu_variant;
 extern const struct hantro_variant sama5d4_vdec_variant;
 
-extern const struct hantro_postproc_regs hantro_g1_postproc_regs;
+extern const struct hantro_postproc_ops hantro_g1_postproc_ops;
 
 extern const u32 hantro_vp8_dec_mc_filter[8][6];
 
diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/staging/media/hantro/hantro_postproc.c
index 07842152003f..882fb8bc5ddd 100644
--- a/drivers/staging/media/hantro/hantro_postproc.c
+++ b/drivers/staging/media/hantro/hantro_postproc.c
@@ -15,14 +15,14 @@
 #define HANTRO_PP_REG_WRITE(vpu, reg_name, val) \
 { \
 	hantro_reg_write(vpu, \
-			 &(vpu)->variant->postproc_regs->reg_name, \
+			 &hantro_g1_postproc_regs.reg_name, \
 			 val); \
 }
 
 #define HANTRO_PP_REG_WRITE_S(vpu, reg_name, val) \
 { \
 	hantro_reg_write_s(vpu, \
-			   &(vpu)->variant->postproc_regs->reg_name, \
+			   &hantro_g1_postproc_regs.reg_name, \
 			   val); \
 }
 
@@ -64,16 +64,13 @@ bool hantro_needs_postproc(const struct hantro_ctx *ctx,
 	return fmt->fourcc != V4L2_PIX_FMT_NV12;
 }
 
-void hantro_postproc_enable(struct hantro_ctx *ctx)
+static void hantro_postproc_g1_enable(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
 	struct vb2_v4l2_buffer *dst_buf;
 	u32 src_pp_fmt, dst_pp_fmt;
 	dma_addr_t dst_dma;
 
-	if (!vpu->variant->postproc_regs)
-		return;
-
 	/* Turn on pipeline mode. Must be done first. */
 	HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x1);
 
@@ -154,12 +151,30 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)
 	return 0;
 }
 
+static void hantro_postproc_g1_disable(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+
+	HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x0);
+}
+
 void hantro_postproc_disable(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
 
-	if (!vpu->variant->postproc_regs)
-		return;
+	if (vpu->variant->postproc_ops && vpu->variant->postproc_ops->disable)
+		vpu->variant->postproc_ops->disable(ctx);
+}
 
-	HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x0);
+void hantro_postproc_enable(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+
+	if (vpu->variant->postproc_ops && vpu->variant->postproc_ops->enable)
+		vpu->variant->postproc_ops->enable(ctx);
 }
+
+const struct hantro_postproc_ops hantro_g1_postproc_ops = {
+	.enable = hantro_postproc_g1_enable,
+	.disable = hantro_postproc_g1_disable,
+};
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index ea919bfb9891..22fa7d2f3b64 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -262,7 +262,7 @@ const struct hantro_variant imx8mq_vpu_variant = {
 	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
 	.postproc_fmts = imx8m_vpu_postproc_fmts,
 	.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),
-	.postproc_regs = &hantro_g1_postproc_regs,
+	.postproc_ops = &hantro_g1_postproc_ops,
 	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
 		 HANTRO_H264_DECODER,
 	.codec_ops = imx8mq_vpu_codec_ops,
diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c
index d4f52957cc53..6c1ad5534ce5 100644
--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c
+++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c
@@ -460,7 +460,7 @@ const struct hantro_variant rk3036_vpu_variant = {
 	.num_dec_fmts = ARRAY_SIZE(rk3066_vpu_dec_fmts),
 	.postproc_fmts = rockchip_vpu1_postproc_fmts,
 	.num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
-	.postproc_regs = &hantro_g1_postproc_regs,
+	.postproc_ops = &hantro_g1_postproc_ops,
 	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
 		 HANTRO_H264_DECODER,
 	.codec_ops = rk3036_vpu_codec_ops,
@@ -485,7 +485,7 @@ const struct hantro_variant rk3066_vpu_variant = {
 	.num_dec_fmts = ARRAY_SIZE(rk3066_vpu_dec_fmts),
 	.postproc_fmts = rockchip_vpu1_postproc_fmts,
 	.num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
-	.postproc_regs = &hantro_g1_postproc_regs,
+	.postproc_ops = &hantro_g1_postproc_ops,
 	.codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
 		 HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
 	.codec_ops = rk3066_vpu_codec_ops,
@@ -505,7 +505,7 @@ const struct hantro_variant rk3288_vpu_variant = {
 	.num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts),
 	.postproc_fmts = rockchip_vpu1_postproc_fmts,
 	.num_postproc_fmts = ARRAY_SIZE(rockchip_vpu1_postproc_fmts),
-	.postproc_regs = &hantro_g1_postproc_regs,
+	.postproc_ops = &hantro_g1_postproc_ops,
 	.codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
 		 HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
 	.codec_ops = rk3288_vpu_codec_ops,
diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
index 9c3b8cd0b239..f3fecc7248c4 100644
--- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c
+++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c
@@ -100,7 +100,7 @@ const struct hantro_variant sama5d4_vdec_variant = {
 	.num_dec_fmts = ARRAY_SIZE(sama5d4_vdec_fmts),
 	.postproc_fmts = sama5d4_vdec_postproc_fmts,
 	.num_postproc_fmts = ARRAY_SIZE(sama5d4_vdec_postproc_fmts),
-	.postproc_regs = &hantro_g1_postproc_regs,
+	.postproc_ops = &hantro_g1_postproc_ops,
 	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
 		 HANTRO_H264_DECODER,
 	.codec_ops = sama5d4_vdec_codec_ops,
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:43 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:43 +0200
Subject: [PATCH v3 07/10] media: rkvdec: Add the VP9 backend
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-8-andrzej.p@collabora.com>

From: Boris Brezillon <boris.brezillon at collabora.com>

The Rockchip VDEC supports VP9 profile 0 up to 4096x2304 at 30fps. Add
a backend for this new format.

Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu at collabora.com>
Co-developed-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
---
 drivers/staging/media/rkvdec/Kconfig      |    1 +
 drivers/staging/media/rkvdec/Makefile     |    2 +-
 drivers/staging/media/rkvdec/rkvdec-vp9.c | 1078 +++++++++++++++++++++
 drivers/staging/media/rkvdec/rkvdec.c     |   52 +-
 drivers/staging/media/rkvdec/rkvdec.h     |   12 +-
 5 files changed, 1137 insertions(+), 8 deletions(-)
 create mode 100644 drivers/staging/media/rkvdec/rkvdec-vp9.c

diff --git a/drivers/staging/media/rkvdec/Kconfig b/drivers/staging/media/rkvdec/Kconfig
index c02199b5e0fd..dc7292f346fa 100644
--- a/drivers/staging/media/rkvdec/Kconfig
+++ b/drivers/staging/media/rkvdec/Kconfig
@@ -9,6 +9,7 @@ config VIDEO_ROCKCHIP_VDEC
 	select VIDEOBUF2_VMALLOC
 	select V4L2_MEM2MEM_DEV
 	select V4L2_H264
+	select V4L2_VP9
 	help
 	  Support for the Rockchip Video Decoder IP present on Rockchip SoCs,
 	  which accelerates video decoding.
diff --git a/drivers/staging/media/rkvdec/Makefile b/drivers/staging/media/rkvdec/Makefile
index c08fed0a39f9..cb86b429cfaa 100644
--- a/drivers/staging/media/rkvdec/Makefile
+++ b/drivers/staging/media/rkvdec/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rockchip-vdec.o
 
-rockchip-vdec-y += rkvdec.o rkvdec-h264.o
+rockchip-vdec-y += rkvdec.o rkvdec-h264.o rkvdec-vp9.o
diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/staging/media/rkvdec/rkvdec-vp9.c
new file mode 100644
index 000000000000..e8b3a5c3d0f4
--- /dev/null
+++ b/drivers/staging/media/rkvdec/rkvdec-vp9.c
@@ -0,0 +1,1078 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Video Decoder VP9 backend
+ *
+ * Copyright (C) 2019 Collabora, Ltd.
+ *	Boris Brezillon <boris.brezillon at collabora.com>
+ * Copyright (C) 2021 Collabora, Ltd.
+ *	Andrzej Pietrasiewicz <andrzej.p at collabora.com>
+ *
+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
+ *	Alpha Lin <Alpha.Lin at rock-chips.com>
+ */
+
+/*
+ * For following the vp9 spec please start reading this driver
+ * code from rkvdec_vp9_run() followed by rkvdec_vp9_done().
+ */
+
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-vp9.h>
+
+#include "rkvdec.h"
+#include "rkvdec-regs.h"
+
+#define RKVDEC_VP9_PROBE_SIZE		4864
+#define RKVDEC_VP9_COUNT_SIZE		13232
+#define RKVDEC_VP9_MAX_SEGMAP_SIZE	73728
+
+struct rkvdec_vp9_intra_mode_probs {
+	u8 y_mode[105];
+	u8 uv_mode[23];
+};
+
+struct rkvdec_vp9_intra_only_frame_probs {
+	u8 coef_intra[4][2][128];
+	struct rkvdec_vp9_intra_mode_probs intra_mode[10];
+};
+
+struct rkvdec_vp9_inter_frame_probs {
+	u8 y_mode[4][9];
+	u8 comp_mode[5];
+	u8 comp_ref[5];
+	u8 single_ref[5][2];
+	u8 inter_mode[7][3];
+	u8 interp_filter[4][2];
+	u8 padding0[11];
+	u8 coef[2][4][2][128];
+	u8 uv_mode_0_2[3][9];
+	u8 padding1[5];
+	u8 uv_mode_3_5[3][9];
+	u8 padding2[5];
+	u8 uv_mode_6_8[3][9];
+	u8 padding3[5];
+	u8 uv_mode_9[9];
+	u8 padding4[7];
+	u8 padding5[16];
+	struct {
+		u8 joint[3];
+		u8 sign[2];
+		u8 classes[2][10];
+		u8 class0_bit[2];
+		u8 bits[2][10];
+		u8 class0_fr[2][2][3];
+		u8 fr[2][3];
+		u8 class0_hp[2];
+		u8 hp[2];
+	} mv;
+};
+
+struct rkvdec_vp9_probs {
+	u8 partition[16][3];
+	u8 pred[3];
+	u8 tree[7];
+	u8 skip[3];
+	u8 tx32[2][3];
+	u8 tx16[2][2];
+	u8 tx8[2][1];
+	u8 is_inter[4];
+	/* 128 bit alignment */
+	u8 padding0[3];
+	union {
+		struct rkvdec_vp9_inter_frame_probs inter;
+		struct rkvdec_vp9_intra_only_frame_probs intra_only;
+	};
+};
+
+/* Data structure describing auxiliary buffer format. */
+struct rkvdec_vp9_priv_tbl {
+	struct rkvdec_vp9_probs probs;
+	u8 segmap[2][RKVDEC_VP9_MAX_SEGMAP_SIZE];
+};
+
+struct rkvdec_vp9_refs_counts {
+	u32 eob[2];
+	u32 coeff[3];
+};
+
+struct rkvdec_vp9_inter_frame_symbol_counts {
+	u32 partition[16][4];
+	u32 skip[3][2];
+	u32 inter[4][2];
+	u32 tx32p[2][4];
+	u32 tx16p[2][4];
+	u32 tx8p[2][2];
+	u32 y_mode[4][10];
+	u32 uv_mode[10][10];
+	u32 comp[5][2];
+	u32 comp_ref[5][2];
+	u32 single_ref[5][2][2];
+	u32 mv_mode[7][4];
+	u32 filter[4][3];
+	u32 mv_joint[4];
+	u32 sign[2][2];
+	/* add 1 element for align */
+	u32 classes[2][11 + 1];
+	u32 class0[2][2];
+	u32 bits[2][10][2];
+	u32 class0_fp[2][2][4];
+	u32 fp[2][4];
+	u32 class0_hp[2][2];
+	u32 hp[2][2];
+	struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6];
+};
+
+struct rkvdec_vp9_intra_frame_symbol_counts {
+	u32 partition[4][4][4];
+	u32 skip[3][2];
+	u32 intra[4][2];
+	u32 tx32p[2][4];
+	u32 tx16p[2][4];
+	u32 tx8p[2][2];
+	struct rkvdec_vp9_refs_counts ref_cnt[2][4][2][6][6];
+};
+
+struct rkvdec_vp9_run {
+	struct rkvdec_run base;
+	const struct v4l2_ctrl_vp9_frame *decode_params;
+};
+
+struct rkvdec_vp9_frame_info {
+	u32 valid : 1;
+	u32 segmapid : 1;
+	u32 frame_context_idx : 2;
+	u32 reference_mode : 2;
+	u32 tx_mode : 3;
+	u32 interpolation_filter : 3;
+	u32 flags;
+	u64 timestamp;
+	struct v4l2_vp9_segmentation seg;
+	struct v4l2_vp9_loop_filter lf;
+};
+
+struct rkvdec_vp9_ctx {
+	struct rkvdec_aux_buf priv_tbl;
+	struct rkvdec_aux_buf count_tbl;
+	struct v4l2_vp9_frame_symbol_counts inter_cnts;
+	struct v4l2_vp9_frame_symbol_counts intra_cnts;
+	struct v4l2_vp9_frame_context probability_tables;
+	struct v4l2_vp9_frame_context frame_context[4];
+	struct rkvdec_vp9_frame_info cur;
+	struct rkvdec_vp9_frame_info last;
+};
+
+static void write_coeff_plane(const u8 coef[6][6][3], u8 *coeff_plane)
+{
+	unsigned int idx = 0, byte_count = 0;
+	int k, m, n;
+	u8 p;
+
+	for (k = 0; k < 6; k++) {
+		for (m = 0; m < 6; m++) {
+			for (n = 0; n < 3; n++) {
+				p = coef[k][m][n];
+				coeff_plane[idx++] = p;
+				byte_count++;
+				if (byte_count == 27) {
+					idx += 5;
+					byte_count = 0;
+				}
+			}
+		}
+	}
+}
+
+static void init_intra_only_probs(struct rkvdec_ctx *ctx,
+				  const struct rkvdec_vp9_run *run)
+{
+	const struct v4l2_ctrl_vp9_frame *dec_params;
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu;
+	struct rkvdec_vp9_intra_only_frame_probs *rkprobs;
+	const struct v4l2_vp9_frame_context *probs;
+	unsigned int i, j, k, m;
+
+	rkprobs = &tbl->probs.intra_only;
+	dec_params = run->decode_params;
+	probs = &vp9_ctx->probability_tables;
+
+	/*
+	 * intra only 149 x 128 bits ,aligned to 152 x 128 bits coeff related
+	 * prob 64 x 128 bits
+	 */
+	for (i = 0; i < ARRAY_SIZE(probs->coef); i++) {
+		for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++)
+			write_coeff_plane(probs->coef[i][j][0],
+					  rkprobs->coef_intra[i][j]);
+	}
+
+	/* intra mode prob  80 x 128 bits */
+	for (i = 0; i < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob); i++) {
+		unsigned int byte_count = 0;
+		int idx = 0;
+
+		/* vp9_kf_y_mode_prob */
+		for (j = 0; j < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob[0]); j++) {
+			for (k = 0; k < ARRAY_SIZE(v4l2_vp9_kf_y_mode_prob[0][0]);
+			     k++) {
+				u8 val = v4l2_vp9_kf_y_mode_prob[i][j][k];
+
+				rkprobs->intra_mode[i].y_mode[idx++] = val;
+				byte_count++;
+				if (byte_count == 27) {
+					byte_count = 0;
+					idx += 5;
+				}
+			}
+		}
+
+		idx = 0;
+		if (i < 4) {
+			for (m = 0; m < (i < 3 ? 23 : 21); m++) {
+				const u8 *ptr = (const u8 *)v4l2_vp9_kf_uv_mode_prob;
+
+				rkprobs->intra_mode[i].uv_mode[idx++] = ptr[i * 23 + m];
+			}
+		}
+	}
+}
+
+static void init_inter_probs(struct rkvdec_ctx *ctx,
+			     const struct rkvdec_vp9_run *run)
+{
+	const struct v4l2_ctrl_vp9_frame *dec_params;
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu;
+	struct rkvdec_vp9_inter_frame_probs *rkprobs;
+	const struct v4l2_vp9_frame_context *probs;
+	unsigned int i, j, k;
+
+	rkprobs = &tbl->probs.inter;
+	dec_params = run->decode_params;
+	probs = &vp9_ctx->probability_tables;
+
+	/*
+	 * inter probs
+	 * 151 x 128 bits, aligned to 152 x 128 bits
+	 * inter only
+	 * intra_y_mode & inter_block info 6 x 128 bits
+	 */
+
+	memcpy(rkprobs->y_mode, probs->y_mode, sizeof(rkprobs->y_mode));
+	memcpy(rkprobs->comp_mode, probs->comp_mode,
+	       sizeof(rkprobs->comp_mode));
+	memcpy(rkprobs->comp_ref, probs->comp_ref,
+	       sizeof(rkprobs->comp_ref));
+	memcpy(rkprobs->single_ref, probs->single_ref,
+	       sizeof(rkprobs->single_ref));
+	memcpy(rkprobs->inter_mode, probs->inter_mode,
+	       sizeof(rkprobs->inter_mode));
+	memcpy(rkprobs->interp_filter, probs->interp_filter,
+	       sizeof(rkprobs->interp_filter));
+
+	/* 128 x 128 bits coeff related */
+	for (i = 0; i < ARRAY_SIZE(probs->coef); i++) {
+		for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++) {
+			for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); k++)
+				write_coeff_plane(probs->coef[i][j][k],
+						  rkprobs->coef[k][i][j]);
+		}
+	}
+
+	/* intra uv mode 6 x 128 */
+	memcpy(rkprobs->uv_mode_0_2, &probs->uv_mode[0],
+	       sizeof(rkprobs->uv_mode_0_2));
+	memcpy(rkprobs->uv_mode_3_5, &probs->uv_mode[3],
+	       sizeof(rkprobs->uv_mode_3_5));
+	memcpy(rkprobs->uv_mode_6_8, &probs->uv_mode[6],
+	       sizeof(rkprobs->uv_mode_6_8));
+	memcpy(rkprobs->uv_mode_9, &probs->uv_mode[9],
+	       sizeof(rkprobs->uv_mode_9));
+
+	/* mv related 6 x 128 */
+	memcpy(rkprobs->mv.joint, probs->mv.joint,
+	       sizeof(rkprobs->mv.joint));
+	memcpy(rkprobs->mv.sign, probs->mv.sign,
+	       sizeof(rkprobs->mv.sign));
+	memcpy(rkprobs->mv.classes, probs->mv.classes,
+	       sizeof(rkprobs->mv.classes));
+	memcpy(rkprobs->mv.class0_bit, probs->mv.class0_bit,
+	       sizeof(rkprobs->mv.class0_bit));
+	memcpy(rkprobs->mv.bits, probs->mv.bits,
+	       sizeof(rkprobs->mv.bits));
+	memcpy(rkprobs->mv.class0_fr, probs->mv.class0_fr,
+	       sizeof(rkprobs->mv.class0_fr));
+	memcpy(rkprobs->mv.fr, probs->mv.fr,
+	       sizeof(rkprobs->mv.fr));
+	memcpy(rkprobs->mv.class0_hp, probs->mv.class0_hp,
+	       sizeof(rkprobs->mv.class0_hp));
+	memcpy(rkprobs->mv.hp, probs->mv.hp,
+	       sizeof(rkprobs->mv.hp));
+}
+
+static void init_probs(struct rkvdec_ctx *ctx,
+		       const struct rkvdec_vp9_run *run)
+{
+	const struct v4l2_ctrl_vp9_frame *dec_params;
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	struct rkvdec_vp9_priv_tbl *tbl = vp9_ctx->priv_tbl.cpu;
+	struct rkvdec_vp9_probs *rkprobs = &tbl->probs;
+	const struct v4l2_vp9_segmentation *seg;
+	const struct v4l2_vp9_frame_context *probs;
+	bool intra_only;
+
+	dec_params = run->decode_params;
+	probs = &vp9_ctx->probability_tables;
+	seg = &dec_params->seg;
+
+	memset(rkprobs, 0, sizeof(*rkprobs));
+
+	intra_only = !!(dec_params->flags &
+			(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
+			 V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
+
+	/* sb info  5 x 128 bit */
+	memcpy(rkprobs->partition,
+	       intra_only ? v4l2_vp9_kf_partition_probs : probs->partition,
+	       sizeof(rkprobs->partition));
+
+	memcpy(rkprobs->pred, seg->pred_probs, sizeof(rkprobs->pred));
+	memcpy(rkprobs->tree, seg->tree_probs, sizeof(rkprobs->tree));
+	memcpy(rkprobs->skip, probs->skip, sizeof(rkprobs->skip));
+	memcpy(rkprobs->tx32, probs->tx32, sizeof(rkprobs->tx32));
+	memcpy(rkprobs->tx16, probs->tx16, sizeof(rkprobs->tx16));
+	memcpy(rkprobs->tx8, probs->tx8, sizeof(rkprobs->tx8));
+	memcpy(rkprobs->is_inter, probs->is_inter, sizeof(rkprobs->is_inter));
+
+	if (intra_only)
+		init_intra_only_probs(ctx, run);
+	else
+		init_inter_probs(ctx, run);
+}
+
+struct rkvdec_vp9_ref_reg {
+	u32 reg_frm_size;
+	u32 reg_hor_stride;
+	u32 reg_y_stride;
+	u32 reg_yuv_stride;
+	u32 reg_ref_base;
+};
+
+static struct rkvdec_vp9_ref_reg ref_regs[] = {
+	{
+		.reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(0),
+		.reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(0),
+		.reg_y_stride = RKVDEC_VP9_LAST_FRAME_YSTRIDE,
+		.reg_yuv_stride = RKVDEC_VP9_LAST_FRAME_YUVSTRIDE,
+		.reg_ref_base = RKVDEC_REG_VP9_LAST_FRAME_BASE,
+	},
+	{
+		.reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(1),
+		.reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(1),
+		.reg_y_stride = RKVDEC_VP9_GOLDEN_FRAME_YSTRIDE,
+		.reg_yuv_stride = 0,
+		.reg_ref_base = RKVDEC_REG_VP9_GOLDEN_FRAME_BASE,
+	},
+	{
+		.reg_frm_size = RKVDEC_REG_VP9_FRAME_SIZE(2),
+		.reg_hor_stride = RKVDEC_VP9_HOR_VIRSTRIDE(2),
+		.reg_y_stride = RKVDEC_VP9_ALTREF_FRAME_YSTRIDE,
+		.reg_yuv_stride = 0,
+		.reg_ref_base = RKVDEC_REG_VP9_ALTREF_FRAME_BASE,
+	}
+};
+
+static struct rkvdec_decoded_buffer *
+get_ref_buf(struct rkvdec_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp)
+{
+	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
+	struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
+	int buf_idx;
+
+	/*
+	 * If a ref is unused or invalid, address of current destination
+	 * buffer is returned.
+	 */
+	buf_idx = vb2_find_timestamp(cap_q, timestamp, 0);
+	if (buf_idx < 0)
+		return vb2_to_rkvdec_decoded_buf(&dst->vb2_buf);
+
+	return vb2_to_rkvdec_decoded_buf(vb2_get_buffer(cap_q, buf_idx));
+}
+
+static dma_addr_t get_mv_base_addr(struct rkvdec_decoded_buffer *buf)
+{
+	unsigned int aligned_pitch, aligned_height, yuv_len;
+
+	aligned_height = round_up(buf->vp9.height, 64);
+	aligned_pitch = round_up(buf->vp9.width * buf->vp9.bit_depth, 512) / 8;
+	yuv_len = (aligned_height * aligned_pitch * 3) / 2;
+
+	return vb2_dma_contig_plane_dma_addr(&buf->base.vb.vb2_buf, 0) +
+	       yuv_len;
+}
+
+static void config_ref_registers(struct rkvdec_ctx *ctx,
+				 const struct rkvdec_vp9_run *run,
+				 struct rkvdec_decoded_buffer *ref_buf,
+				 struct rkvdec_vp9_ref_reg *ref_reg)
+{
+	unsigned int aligned_pitch, aligned_height, y_len, yuv_len;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+
+	aligned_height = round_up(ref_buf->vp9.height, 64);
+	writel_relaxed(RKVDEC_VP9_FRAMEWIDTH(ref_buf->vp9.width) |
+		       RKVDEC_VP9_FRAMEHEIGHT(ref_buf->vp9.height),
+		       rkvdec->regs + ref_reg->reg_frm_size);
+
+	writel_relaxed(vb2_dma_contig_plane_dma_addr(&ref_buf->base.vb.vb2_buf, 0),
+		       rkvdec->regs + ref_reg->reg_ref_base);
+
+	if (&ref_buf->base.vb == run->base.bufs.dst)
+		return;
+
+	aligned_pitch = round_up(ref_buf->vp9.width * ref_buf->vp9.bit_depth, 512) / 8;
+	y_len = aligned_height * aligned_pitch;
+	yuv_len = (y_len * 3) / 2;
+
+	writel_relaxed(RKVDEC_HOR_Y_VIRSTRIDE(aligned_pitch / 16) |
+		       RKVDEC_HOR_UV_VIRSTRIDE(aligned_pitch / 16),
+		       rkvdec->regs + ref_reg->reg_hor_stride);
+	writel_relaxed(RKVDEC_VP9_REF_YSTRIDE(y_len / 16),
+		       rkvdec->regs + ref_reg->reg_y_stride);
+
+	if (!ref_reg->reg_yuv_stride)
+		return;
+
+	writel_relaxed(RKVDEC_VP9_REF_YUVSTRIDE(yuv_len / 16),
+		       rkvdec->regs + ref_reg->reg_yuv_stride);
+}
+
+static void config_seg_registers(struct rkvdec_ctx *ctx, unsigned int segid)
+{
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	const struct v4l2_vp9_segmentation *seg;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	s16 feature_val;
+	int feature_id;
+	u32 val = 0;
+
+	seg = vp9_ctx->last.valid ? &vp9_ctx->last.seg : &vp9_ctx->cur.seg;
+	feature_id = V4L2_VP9_SEG_LVL_ALT_Q;
+	if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
+		feature_val = seg->feature_data[segid][feature_id];
+		val |= RKVDEC_SEGID_FRAME_QP_DELTA_EN(1) |
+		       RKVDEC_SEGID_FRAME_QP_DELTA(feature_val);
+	}
+
+	feature_id = V4L2_VP9_SEG_LVL_ALT_L;
+	if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
+		feature_val = seg->feature_data[segid][feature_id];
+		val |= RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE_EN(1) |
+		       RKVDEC_SEGID_FRAME_LOOPFILTER_VALUE(feature_val);
+	}
+
+	feature_id = V4L2_VP9_SEG_LVL_REF_FRAME;
+	if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid)) {
+		feature_val = seg->feature_data[segid][feature_id];
+		val |= RKVDEC_SEGID_REFERINFO_EN(1) |
+		       RKVDEC_SEGID_REFERINFO(feature_val);
+	}
+
+	feature_id = V4L2_VP9_SEG_LVL_SKIP;
+	if (v4l2_vp9_seg_feat_enabled(seg->feature_enabled, feature_id, segid))
+		val |= RKVDEC_SEGID_FRAME_SKIP_EN(1);
+
+	if (!segid &&
+	    (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE))
+		val |= RKVDEC_SEGID_ABS_DELTA(1);
+
+	writel_relaxed(val, rkvdec->regs + RKVDEC_VP9_SEGID_GRP(segid));
+}
+
+static void update_dec_buf_info(struct rkvdec_decoded_buffer *buf,
+				const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	buf->vp9.width = dec_params->frame_width_minus_1 + 1;
+	buf->vp9.height = dec_params->frame_height_minus_1 + 1;
+	buf->vp9.bit_depth = dec_params->bit_depth;
+}
+
+static void update_ctx_cur_info(struct rkvdec_vp9_ctx *vp9_ctx,
+				struct rkvdec_decoded_buffer *buf,
+				const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	vp9_ctx->cur.valid = true;
+	vp9_ctx->cur.reference_mode = dec_params->reference_mode;
+	vp9_ctx->cur.tx_mode = dec_params->tx_mode;
+	vp9_ctx->cur.interpolation_filter = dec_params->interpolation_filter;
+	vp9_ctx->cur.flags = dec_params->flags;
+	vp9_ctx->cur.timestamp = buf->base.vb.vb2_buf.timestamp;
+	vp9_ctx->cur.seg = dec_params->seg;
+	vp9_ctx->cur.lf = dec_params->lf;
+}
+
+static void update_ctx_last_info(struct rkvdec_vp9_ctx *vp9_ctx)
+{
+	vp9_ctx->last = vp9_ctx->cur;
+}
+
+static void config_registers(struct rkvdec_ctx *ctx,
+			     const struct rkvdec_vp9_run *run)
+{
+	unsigned int y_len, uv_len, yuv_len, bit_depth, aligned_height, aligned_pitch, stream_len;
+	const struct v4l2_ctrl_vp9_frame *dec_params;
+	struct rkvdec_decoded_buffer *ref_bufs[3];
+	struct rkvdec_decoded_buffer *dst, *last, *mv_ref;
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	u32 val, last_frame_info = 0;
+	const struct v4l2_vp9_segmentation *seg;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	dma_addr_t addr;
+	bool intra_only;
+	unsigned int i;
+
+	dec_params = run->decode_params;
+	dst = vb2_to_rkvdec_decoded_buf(&run->base.bufs.dst->vb2_buf);
+	ref_bufs[0] = get_ref_buf(ctx, &dst->base.vb, dec_params->last_frame_ts);
+	ref_bufs[1] = get_ref_buf(ctx, &dst->base.vb, dec_params->golden_frame_ts);
+	ref_bufs[2] = get_ref_buf(ctx, &dst->base.vb, dec_params->alt_frame_ts);
+
+	if (vp9_ctx->last.valid)
+		last = get_ref_buf(ctx, &dst->base.vb, vp9_ctx->last.timestamp);
+	else
+		last = dst;
+
+	update_dec_buf_info(dst, dec_params);
+	update_ctx_cur_info(vp9_ctx, dst, dec_params);
+	seg = &dec_params->seg;
+
+	intra_only = !!(dec_params->flags &
+			(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
+			 V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
+
+	writel_relaxed(RKVDEC_MODE(RKVDEC_MODE_VP9),
+		       rkvdec->regs + RKVDEC_REG_SYSCTRL);
+
+	bit_depth = dec_params->bit_depth;
+	aligned_height = round_up(ctx->decoded_fmt.fmt.pix_mp.height, 64);
+
+	aligned_pitch = round_up(ctx->decoded_fmt.fmt.pix_mp.width *
+				 bit_depth,
+				 512) / 8;
+	y_len = aligned_height * aligned_pitch;
+	uv_len = y_len / 2;
+	yuv_len = y_len + uv_len;
+
+	writel_relaxed(RKVDEC_Y_HOR_VIRSTRIDE(aligned_pitch / 16) |
+		       RKVDEC_UV_HOR_VIRSTRIDE(aligned_pitch / 16),
+		       rkvdec->regs + RKVDEC_REG_PICPAR);
+	writel_relaxed(RKVDEC_Y_VIRSTRIDE(y_len / 16),
+		       rkvdec->regs + RKVDEC_REG_Y_VIRSTRIDE);
+	writel_relaxed(RKVDEC_YUV_VIRSTRIDE(yuv_len / 16),
+		       rkvdec->regs + RKVDEC_REG_YUV_VIRSTRIDE);
+
+	stream_len = vb2_get_plane_payload(&run->base.bufs.src->vb2_buf, 0);
+	writel_relaxed(RKVDEC_STRM_LEN(stream_len),
+		       rkvdec->regs + RKVDEC_REG_STRM_LEN);
+
+	/*
+	 * Reset count buffer, because decoder only output intra related syntax
+	 * counts when decoding intra frame, but update entropy need to update
+	 * all the probabilities.
+	 */
+	if (intra_only)
+		memset(vp9_ctx->count_tbl.cpu, 0, vp9_ctx->count_tbl.size);
+
+	vp9_ctx->cur.segmapid = vp9_ctx->last.segmapid;
+	if (!intra_only &&
+	    !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
+	    (!(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED) ||
+	     (seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP)))
+		vp9_ctx->cur.segmapid++;
+
+	for (i = 0; i < ARRAY_SIZE(ref_bufs); i++)
+		config_ref_registers(ctx, run, ref_bufs[i], &ref_regs[i]);
+
+	for (i = 0; i < 8; i++)
+		config_seg_registers(ctx, i);
+
+	writel_relaxed(RKVDEC_VP9_TX_MODE(dec_params->tx_mode) |
+		       RKVDEC_VP9_FRAME_REF_MODE(dec_params->reference_mode),
+		       rkvdec->regs + RKVDEC_VP9_CPRHEADER_CONFIG);
+
+	if (!intra_only) {
+		const struct v4l2_vp9_loop_filter *lf;
+		s8 delta;
+
+		if (vp9_ctx->last.valid)
+			lf = &vp9_ctx->last.lf;
+		else
+			lf = &vp9_ctx->cur.lf;
+
+		val = 0;
+		for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++) {
+			delta = lf->ref_deltas[i];
+			val |= RKVDEC_REF_DELTAS_LASTFRAME(i, delta);
+		}
+
+		writel_relaxed(val,
+			       rkvdec->regs + RKVDEC_VP9_REF_DELTAS_LASTFRAME);
+
+		for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++) {
+			delta = lf->mode_deltas[i];
+			last_frame_info |= RKVDEC_MODE_DELTAS_LASTFRAME(i,
+									delta);
+		}
+	}
+
+	if (vp9_ctx->last.valid && !intra_only &&
+	    vp9_ctx->last.seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED)
+		last_frame_info |= RKVDEC_SEG_EN_LASTFRAME;
+
+	if (vp9_ctx->last.valid &&
+	    vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME)
+		last_frame_info |= RKVDEC_LAST_SHOW_FRAME;
+
+	if (vp9_ctx->last.valid &&
+	    vp9_ctx->last.flags &
+	    (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY))
+		last_frame_info |= RKVDEC_LAST_INTRA_ONLY;
+
+	if (vp9_ctx->last.valid &&
+	    last->vp9.width == dst->vp9.width &&
+	    last->vp9.height == dst->vp9.height)
+		last_frame_info |= RKVDEC_LAST_WIDHHEIGHT_EQCUR;
+
+	writel_relaxed(last_frame_info,
+		       rkvdec->regs + RKVDEC_VP9_INFO_LASTFRAME);
+
+	writel_relaxed(stream_len - dec_params->compressed_header_size -
+		       dec_params->uncompressed_header_size,
+		       rkvdec->regs + RKVDEC_VP9_LASTTILE_SIZE);
+
+	for (i = 0; !intra_only && i < ARRAY_SIZE(ref_bufs); i++) {
+		unsigned int refw = ref_bufs[i]->vp9.width;
+		unsigned int refh = ref_bufs[i]->vp9.height;
+		u32 hscale, vscale;
+
+		hscale = (refw << 14) /	dst->vp9.width;
+		vscale = (refh << 14) / dst->vp9.height;
+		writel_relaxed(RKVDEC_VP9_REF_HOR_SCALE(hscale) |
+			       RKVDEC_VP9_REF_VER_SCALE(vscale),
+			       rkvdec->regs + RKVDEC_VP9_REF_SCALE(i));
+	}
+
+	addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 0);
+	writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_DECOUT_BASE);
+	addr = vb2_dma_contig_plane_dma_addr(&run->base.bufs.src->vb2_buf, 0);
+	writel_relaxed(addr, rkvdec->regs + RKVDEC_REG_STRM_RLC_BASE);
+	writel_relaxed(vp9_ctx->priv_tbl.dma +
+		       offsetof(struct rkvdec_vp9_priv_tbl, probs),
+		       rkvdec->regs + RKVDEC_REG_CABACTBL_PROB_BASE);
+	writel_relaxed(vp9_ctx->count_tbl.dma,
+		       rkvdec->regs + RKVDEC_REG_VP9COUNT_BASE);
+
+	writel_relaxed(vp9_ctx->priv_tbl.dma +
+		       offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
+		       (RKVDEC_VP9_MAX_SEGMAP_SIZE * vp9_ctx->cur.segmapid),
+		       rkvdec->regs + RKVDEC_REG_VP9_SEGIDCUR_BASE);
+	writel_relaxed(vp9_ctx->priv_tbl.dma +
+		       offsetof(struct rkvdec_vp9_priv_tbl, segmap) +
+		       (RKVDEC_VP9_MAX_SEGMAP_SIZE * (!vp9_ctx->cur.segmapid)),
+		       rkvdec->regs + RKVDEC_REG_VP9_SEGIDLAST_BASE);
+
+	if (!intra_only &&
+	    !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
+	    vp9_ctx->last.valid)
+		mv_ref = last;
+	else
+		mv_ref = dst;
+
+	writel_relaxed(get_mv_base_addr(mv_ref),
+		       rkvdec->regs + RKVDEC_VP9_REF_COLMV_BASE);
+
+	writel_relaxed(ctx->decoded_fmt.fmt.pix_mp.width |
+		       (ctx->decoded_fmt.fmt.pix_mp.height << 16),
+		       rkvdec->regs + RKVDEC_REG_PERFORMANCE_CYCLE);
+}
+
+static int validate_dec_params(struct rkvdec_ctx *ctx,
+			       const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	unsigned int aligned_width, aligned_height;
+
+	/* We only support profile 0. */
+	if (dec_params->profile != 0) {
+		dev_err(ctx->dev->dev, "unsupported profile %d\n",
+			dec_params->profile);
+		return -EINVAL;
+	}
+
+	aligned_width = round_up(dec_params->frame_width_minus_1 + 1, 64);
+	aligned_height = round_up(dec_params->frame_height_minus_1 + 1, 64);
+
+	/*
+	 * Userspace should update the capture/decoded format when the
+	 * resolution changes.
+	 */
+	if (aligned_width != ctx->decoded_fmt.fmt.pix_mp.width ||
+	    aligned_height != ctx->decoded_fmt.fmt.pix_mp.height) {
+		dev_err(ctx->dev->dev,
+			"unexpected bitstream resolution %dx%d\n",
+			dec_params->frame_width_minus_1 + 1,
+			dec_params->frame_height_minus_1 + 1);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rkvdec_vp9_run_preamble(struct rkvdec_ctx *ctx,
+				   struct rkvdec_vp9_run *run)
+{
+	const struct v4l2_ctrl_vp9_frame *dec_params;
+	const struct v4l2_ctrl_vp9_compressed_hdr_probs *prob_updates;
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	struct v4l2_ctrl *ctrl;
+	unsigned int fctx_idx;
+	int ret;
+
+	/* v4l2-specific stuff */
+	rkvdec_run_preamble(ctx, &run->base);
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl,
+			      V4L2_CID_STATELESS_VP9_FRAME);
+	if (WARN_ON(!ctrl))
+		return -EINVAL;
+	dec_params = ctrl->p_cur.p;
+
+	ret = validate_dec_params(ctx, dec_params);
+	if (ret)
+		return ret;
+
+	run->decode_params = dec_params;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS);
+	if (WARN_ON(!ctrl))
+		return -EINVAL;
+	prob_updates = ctrl->p_cur.p;
+
+	/*
+	 * vp9 stuff
+	 *
+	 * by this point the userspace has done all parts of 6.2 uncompressed_header()
+	 * except this fragment:
+	 * if ( FrameIsIntra || error_resilient_mode ) {
+	 *	setup_past_independence ( )
+	 *	if ( frame_type == KEY_FRAME || error_resilient_mode == 1 ||
+	 *	     reset_frame_context == 3 ) {
+	 *		for ( i = 0; i < 4; i ++ ) {
+	 *			save_probs( i )
+	 *		}
+	 *	} else if ( reset_frame_context == 2 ) {
+	 *		save_probs( frame_context_idx )
+	 *	}
+	 *	frame_context_idx = 0
+	 * }
+	 */
+	fctx_idx = v4l2_vp9_reset_frame_ctx(dec_params, vp9_ctx->frame_context);
+	vp9_ctx->cur.frame_context_idx = fctx_idx;
+
+	/* 6.1 frame(sz): load_probs() and load_probs2() */
+	vp9_ctx->probability_tables = vp9_ctx->frame_context[fctx_idx];
+
+	/*
+	 * The userspace has also performed 6.3 compressed_header(), but handling the
+	 * probs in a special way. All probs which need updating, except MV-related,
+	 * have been read from the bitstream and translated through inv_map_table[],
+	 * but no 6.3.6 inv_recenter_nonneg(v, m) has been performed. The values passed
+	 * by userspace are either translated values (there are no 0 values in
+	 * inv_map_table[]), or zero to indicate no update. All MV-related probs which need
+	 * updating have been read from the bitstream and (mv_prob << 1) | 1 has been
+	 * performed. The values passed by userspace are either new values
+	 * to replace old ones (the above mentioned shift and bitwise or never result in
+	 * a zero) or zero to indicate no update.
+	 * fw_update_probs() performs actual probs updates or leaves probs as-is
+	 * for values for which a zero was passed from userspace.
+	 */
+	v4l2_vp9_fw_update_probs(&vp9_ctx->probability_tables, prob_updates, dec_params);
+
+	return 0;
+}
+
+static int rkvdec_vp9_run(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_vp9_run run = { };
+	int ret;
+
+	ret = rkvdec_vp9_run_preamble(ctx, &run);
+	if (ret) {
+		rkvdec_run_postamble(ctx, &run.base);
+		return ret;
+	}
+
+	/* Prepare probs. */
+	init_probs(ctx, &run);
+
+	/* Configure hardware registers. */
+	config_registers(ctx, &run);
+
+	rkvdec_run_postamble(ctx, &run.base);
+
+	schedule_delayed_work(&rkvdec->watchdog_work, msecs_to_jiffies(2000));
+
+	writel(1, rkvdec->regs + RKVDEC_REG_PREF_LUMA_CACHE_COMMAND);
+	writel(1, rkvdec->regs + RKVDEC_REG_PREF_CHR_CACHE_COMMAND);
+
+	writel(0xe, rkvdec->regs + RKVDEC_REG_STRMD_ERR_EN);
+	/* Start decoding! */
+	writel(RKVDEC_INTERRUPT_DEC_E | RKVDEC_CONFIG_DEC_CLK_GATE_E |
+	       RKVDEC_TIMEOUT_E | RKVDEC_BUF_EMPTY_E,
+	       rkvdec->regs + RKVDEC_REG_INTERRUPT);
+
+	return 0;
+}
+
+#define copy_tx_and_skip(p1, p2)				\
+do {								\
+	memcpy((p1)->tx8, (p2)->tx8, sizeof((p1)->tx8));	\
+	memcpy((p1)->tx16, (p2)->tx16, sizeof((p1)->tx16));	\
+	memcpy((p1)->tx32, (p2)->tx32, sizeof((p1)->tx32));	\
+	memcpy((p1)->skip, (p2)->skip, sizeof((p1)->skip));	\
+} while (0)
+
+static void rkvdec_vp9_done(struct rkvdec_ctx *ctx,
+			    struct vb2_v4l2_buffer *src_buf,
+			    struct vb2_v4l2_buffer *dst_buf,
+			    enum vb2_buffer_state result)
+{
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	unsigned int fctx_idx;
+
+	/* v4l2-specific stuff */
+	if (result == VB2_BUF_STATE_ERROR)
+		goto out_update_last;
+
+	/*
+	 * vp9 stuff
+	 *
+	 * 6.1.2 refresh_probs()
+	 *
+	 * In the spec a complementary condition goes last in 6.1.2 refresh_probs(),
+	 * but it makes no sense to perform all the activities from the first "if"
+	 * there if we actually are not refreshing the frame context. On top of that,
+	 * because of 6.2 uncompressed_header() whenever error_resilient_mode == 1,
+	 * refresh_frame_context == 0. Consequently, if we don't jump to out_update_last
+	 * it means error_resilient_mode must be 0.
+	 */
+	if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX))
+		goto out_update_last;
+
+	fctx_idx = vp9_ctx->cur.frame_context_idx;
+
+	if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE)) {
+		/* error_resilient_mode == 0 && frame_parallel_decoding_mode == 0 */
+		struct v4l2_vp9_frame_context *probs = &vp9_ctx->probability_tables;
+		bool frame_is_intra = vp9_ctx->cur.flags &
+		    (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY);
+		struct tx_and_skip {
+			u8 tx8[2][1];
+			u8 tx16[2][2];
+			u8 tx32[2][3];
+			u8 skip[3];
+		} _tx_skip, *tx_skip = &_tx_skip;
+		struct v4l2_vp9_frame_symbol_counts *counts;
+
+		/* buffer the forward-updated TX and skip probs */
+		if (frame_is_intra)
+			copy_tx_and_skip(tx_skip, probs);
+
+		/* 6.1.2 refresh_probs(): load_probs() and load_probs2() */
+		*probs = vp9_ctx->frame_context[fctx_idx];
+
+		/* if FrameIsIntra then undo the effect of load_probs2() */
+		if (frame_is_intra)
+			copy_tx_and_skip(probs, tx_skip);
+
+		counts = frame_is_intra ? &vp9_ctx->intra_cnts : &vp9_ctx->inter_cnts;
+		v4l2_vp9_adapt_coef_probs(probs, counts,
+					  !vp9_ctx->last.valid ||
+					  vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME,
+					  frame_is_intra);
+		if (!frame_is_intra) {
+			const struct rkvdec_vp9_inter_frame_symbol_counts *inter_cnts;
+			u32 classes[2][11];
+			int i;
+
+			inter_cnts = vp9_ctx->count_tbl.cpu;
+			for (i = 0; i < ARRAY_SIZE(classes); ++i)
+				memcpy(classes[i], inter_cnts->classes[i], sizeof(classes[0]));
+			counts->classes = &classes;
+
+			/* load_probs2() already done */
+			v4l2_vp9_adapt_noncoef_probs(&vp9_ctx->probability_tables, counts,
+						     vp9_ctx->cur.reference_mode,
+						     vp9_ctx->cur.interpolation_filter,
+						     vp9_ctx->cur.tx_mode, vp9_ctx->cur.flags);
+		}
+	}
+
+	/* 6.1.2 refresh_probs(): save_probs(fctx_idx) */
+	vp9_ctx->frame_context[fctx_idx] = vp9_ctx->probability_tables;
+
+out_update_last:
+	update_ctx_last_info(vp9_ctx);
+}
+
+static void rkvdec_init_v4l2_vp9_count_tbl(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	struct rkvdec_vp9_intra_frame_symbol_counts *intra_cnts = vp9_ctx->count_tbl.cpu;
+	struct rkvdec_vp9_inter_frame_symbol_counts *inter_cnts = vp9_ctx->count_tbl.cpu;
+	int i, j, k, l, m;
+
+	vp9_ctx->inter_cnts.partition = &inter_cnts->partition;
+	vp9_ctx->inter_cnts.skip = &inter_cnts->skip;
+	vp9_ctx->inter_cnts.intra_inter = &inter_cnts->inter;
+	vp9_ctx->inter_cnts.tx32p = &inter_cnts->tx32p;
+	vp9_ctx->inter_cnts.tx16p = &inter_cnts->tx16p;
+	vp9_ctx->inter_cnts.tx8p = &inter_cnts->tx8p;
+
+	vp9_ctx->intra_cnts.partition = (u32 (*)[16][4])(&intra_cnts->partition);
+	vp9_ctx->intra_cnts.skip = &intra_cnts->skip;
+	vp9_ctx->intra_cnts.intra_inter = &intra_cnts->intra;
+	vp9_ctx->intra_cnts.tx32p = &intra_cnts->tx32p;
+	vp9_ctx->intra_cnts.tx16p = &intra_cnts->tx16p;
+	vp9_ctx->intra_cnts.tx8p = &intra_cnts->tx8p;
+
+	vp9_ctx->inter_cnts.y_mode = &inter_cnts->y_mode;
+	vp9_ctx->inter_cnts.uv_mode = &inter_cnts->uv_mode;
+	vp9_ctx->inter_cnts.comp = &inter_cnts->comp;
+	vp9_ctx->inter_cnts.comp_ref = &inter_cnts->comp_ref;
+	vp9_ctx->inter_cnts.single_ref = &inter_cnts->single_ref;
+	vp9_ctx->inter_cnts.mv_mode = &inter_cnts->mv_mode;
+	vp9_ctx->inter_cnts.filter = &inter_cnts->filter;
+	vp9_ctx->inter_cnts.mv_joint = &inter_cnts->mv_joint;
+	vp9_ctx->inter_cnts.sign = &inter_cnts->sign;
+	/*
+	 * rk hardware actually uses "u32 classes[2][11 + 1];"
+	 * instead of "u32 classes[2][11];", so this must be explicitly
+	 * copied into vp9_ctx->classes when passing the data to the
+	 * vp9 library function
+	 */
+	vp9_ctx->inter_cnts.class0 = &inter_cnts->class0;
+	vp9_ctx->inter_cnts.bits = &inter_cnts->bits;
+	vp9_ctx->inter_cnts.class0_fp = &inter_cnts->class0_fp;
+	vp9_ctx->inter_cnts.fp = &inter_cnts->fp;
+	vp9_ctx->inter_cnts.class0_hp = &inter_cnts->class0_hp;
+	vp9_ctx->inter_cnts.hp = &inter_cnts->hp;
+
+#define INNERMOST_LOOP \
+	do {										\
+		for (m = 0; m < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0][0][0]); ++m) {\
+			vp9_ctx->inter_cnts.coeff[i][j][k][l][m] =			\
+				&inter_cnts->ref_cnt[k][i][j][l][m].coeff;		\
+			vp9_ctx->inter_cnts.eob[i][j][k][l][m][0] =			\
+				&inter_cnts->ref_cnt[k][i][j][l][m].eob[0];		\
+			vp9_ctx->inter_cnts.eob[i][j][k][l][m][1] =			\
+				&inter_cnts->ref_cnt[k][i][j][l][m].eob[1];		\
+											\
+			vp9_ctx->intra_cnts.coeff[i][j][k][l][m] =			\
+				&intra_cnts->ref_cnt[k][i][j][l][m].coeff;		\
+			vp9_ctx->intra_cnts.eob[i][j][k][l][m][0] =			\
+				&intra_cnts->ref_cnt[k][i][j][l][m].eob[0];		\
+			vp9_ctx->intra_cnts.eob[i][j][k][l][m][1] =			\
+				&intra_cnts->ref_cnt[k][i][j][l][m].eob[1];		\
+		}									\
+	} while (0)
+
+	for (i = 0; i < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff); ++i)
+		for (j = 0; j < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0]); ++j)
+			for (k = 0; k < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0]); ++k)
+				for (l = 0; l < ARRAY_SIZE(vp9_ctx->inter_cnts.coeff[0][0][0]); ++l)
+					INNERMOST_LOOP;
+#undef INNERMOST_LOOP
+}
+
+static int rkvdec_vp9_start(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_dev *rkvdec = ctx->dev;
+	struct rkvdec_vp9_priv_tbl *priv_tbl;
+	struct rkvdec_vp9_ctx *vp9_ctx;
+	unsigned char *count_tbl;
+	int ret;
+
+	vp9_ctx = kzalloc(sizeof(*vp9_ctx), GFP_KERNEL);
+	if (!vp9_ctx)
+		return -ENOMEM;
+
+	ctx->priv = vp9_ctx;
+
+	priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
+				      &vp9_ctx->priv_tbl.dma, GFP_KERNEL);
+	if (!priv_tbl) {
+		ret = -ENOMEM;
+		goto err_free_ctx;
+	}
+
+	vp9_ctx->priv_tbl.size = sizeof(*priv_tbl);
+	vp9_ctx->priv_tbl.cpu = priv_tbl;
+	memset(priv_tbl, 0, sizeof(*priv_tbl));
+
+	count_tbl = dma_alloc_coherent(rkvdec->dev, RKVDEC_VP9_COUNT_SIZE,
+				       &vp9_ctx->count_tbl.dma, GFP_KERNEL);
+	if (!count_tbl) {
+		ret = -ENOMEM;
+		goto err_free_priv_tbl;
+	}
+
+	vp9_ctx->count_tbl.size = RKVDEC_VP9_COUNT_SIZE;
+	vp9_ctx->count_tbl.cpu = count_tbl;
+	memset(count_tbl, 0, sizeof(*count_tbl));
+	rkvdec_init_v4l2_vp9_count_tbl(ctx);
+
+	return 0;
+
+err_free_priv_tbl:
+	dma_free_coherent(rkvdec->dev, vp9_ctx->priv_tbl.size,
+			  vp9_ctx->priv_tbl.cpu, vp9_ctx->priv_tbl.dma);
+
+err_free_ctx:
+	kfree(vp9_ctx);
+	return ret;
+}
+
+static void rkvdec_vp9_stop(struct rkvdec_ctx *ctx)
+{
+	struct rkvdec_vp9_ctx *vp9_ctx = ctx->priv;
+	struct rkvdec_dev *rkvdec = ctx->dev;
+
+	dma_free_coherent(rkvdec->dev, vp9_ctx->count_tbl.size,
+			  vp9_ctx->count_tbl.cpu, vp9_ctx->count_tbl.dma);
+	dma_free_coherent(rkvdec->dev, vp9_ctx->priv_tbl.size,
+			  vp9_ctx->priv_tbl.cpu, vp9_ctx->priv_tbl.dma);
+	kfree(vp9_ctx);
+}
+
+static int rkvdec_vp9_adjust_fmt(struct rkvdec_ctx *ctx,
+				 struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
+
+	fmt->num_planes = 1;
+	if (!fmt->plane_fmt[0].sizeimage)
+		fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * 2;
+	return 0;
+}
+
+const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops = {
+	.adjust_fmt = rkvdec_vp9_adjust_fmt,
+	.start = rkvdec_vp9_start,
+	.stop = rkvdec_vp9_stop,
+	.run = rkvdec_vp9_run,
+	.done = rkvdec_vp9_done,
+};
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c
index 7131156c1f2c..9553d66e6325 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -99,10 +99,30 @@ static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
 	.num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs),
 };
 
-static const u32 rkvdec_h264_decoded_fmts[] = {
+static const u32 rkvdec_h264_vp9_decoded_fmts[] = {
 	V4L2_PIX_FMT_NV12,
 };
 
+static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = {
+	{
+		.cfg.id = V4L2_CID_STATELESS_VP9_FRAME,
+	},
+	{
+		.cfg.id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS,
+	},
+	{
+		.cfg.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+		.cfg.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+		.cfg.max = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+		.cfg.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+	},
+};
+
+static const struct rkvdec_ctrls rkvdec_vp9_ctrls = {
+	.ctrls = rkvdec_vp9_ctrl_descs,
+	.num_ctrls = ARRAY_SIZE(rkvdec_vp9_ctrl_descs),
+};
+
 static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
 	{
 		.fourcc = V4L2_PIX_FMT_H264_SLICE,
@@ -116,8 +136,23 @@ static const struct rkvdec_coded_fmt_desc rkvdec_coded_fmts[] = {
 		},
 		.ctrls = &rkvdec_h264_ctrls,
 		.ops = &rkvdec_h264_fmt_ops,
-		.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts),
-		.decoded_fmts = rkvdec_h264_decoded_fmts,
+		.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
+		.decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_VP9_FRAME,
+		.frmsize = {
+			.min_width = 64,
+			.max_width = 4096,
+			.step_width = 64,
+			.min_height = 64,
+			.max_height = 2304,
+			.step_height = 64,
+		},
+		.ctrls = &rkvdec_vp9_ctrls,
+		.ops = &rkvdec_vp9_fmt_ops,
+		.num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_vp9_decoded_fmts),
+		.decoded_fmts = rkvdec_h264_vp9_decoded_fmts,
 	}
 };
 
@@ -319,7 +354,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
 	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
 	const struct rkvdec_coded_fmt_desc *desc;
 	struct v4l2_format *cap_fmt;
-	struct vb2_queue *peer_vq;
+	struct vb2_queue *peer_vq, *vq;
 	int ret;
 
 	/*
@@ -331,6 +366,15 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
 	if (vb2_is_busy(peer_vq))
 		return -EBUSY;
 
+	/*
+	 * Some codecs like VP9 can contain dynamic resolution changes which
+	 * are currently not supported by the V4L2 API or driver, so return
+	 * an error if userspace tries to reconfigure the output format.
+	 */
+	vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	if (vb2_is_busy(vq))
+		return -EINVAL;
+
 	ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_output_fmt);
 	if (ret)
 		return ret;
diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h
index 52ac3874c5e5..2f4ea1786b93 100644
--- a/drivers/staging/media/rkvdec/rkvdec.h
+++ b/drivers/staging/media/rkvdec/rkvdec.h
@@ -42,14 +42,18 @@ struct rkvdec_run {
 
 struct rkvdec_vp9_decoded_buffer_info {
 	/* Info needed when the decoded frame serves as a reference frame. */
-	u16 width;
-	u16 height;
-	u32 bit_depth : 4;
+	unsigned short width;
+	unsigned short height;
+	unsigned int bit_depth : 4;
 };
 
 struct rkvdec_decoded_buffer {
 	/* Must be the first field in this struct. */
 	struct v4l2_m2m_buffer base;
+
+	union {
+		struct rkvdec_vp9_decoded_buffer_info vp9;
+	};
 };
 
 static inline struct rkvdec_decoded_buffer *
@@ -116,4 +120,6 @@ void rkvdec_run_preamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
 void rkvdec_run_postamble(struct rkvdec_ctx *ctx, struct rkvdec_run *run);
 
 extern const struct rkvdec_coded_fmt_ops rkvdec_h264_fmt_ops;
+extern const struct rkvdec_coded_fmt_ops rkvdec_vp9_fmt_ops;
+
 #endif /* RKVDEC_H_ */
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:44 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:44 +0200
Subject: [PATCH v3 08/10] media: hantro: Prepare for other G2 codecs
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-9-andrzej.p@collabora.com>

VeriSilicon Hantro G2 core supports other codecs besides hevc.
Factor out some common code in preparation for vp9 support.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
---
 drivers/staging/media/hantro/Makefile         |  1 +
 drivers/staging/media/hantro/hantro.h         |  7 +++++
 drivers/staging/media/hantro/hantro_g2.c      | 27 ++++++++++++++++
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 31 -------------------
 drivers/staging/media/hantro/hantro_g2_regs.h |  7 +++++
 drivers/staging/media/hantro/hantro_hw.h      |  2 ++
 6 files changed, 44 insertions(+), 31 deletions(-)
 create mode 100644 drivers/staging/media/hantro/hantro_g2.c

diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile
index 90036831fec4..fe6d84871d07 100644
--- a/drivers/staging/media/hantro/Makefile
+++ b/drivers/staging/media/hantro/Makefile
@@ -12,6 +12,7 @@ hantro-vpu-y += \
 		hantro_g1_mpeg2_dec.o \
 		hantro_g2_hevc_dec.o \
 		hantro_g1_vp8_dec.o \
+		hantro_g2.o \
 		rockchip_vpu2_hw_jpeg_enc.o \
 		rockchip_vpu2_hw_h264_dec.o \
 		rockchip_vpu2_hw_mpeg2_dec.o \
diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
index dd5e56765d4e..d91eb2b1c509 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/staging/media/hantro/hantro.h
@@ -369,6 +369,13 @@ static inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg)
 	writel(val, vpu->dec_base + reg);
 }
 
+static inline void hantro_write_addr(struct hantro_dev *vpu,
+				     unsigned long offset,
+				     dma_addr_t addr)
+{
+	vdpu_write(vpu, addr & 0xffffffff, offset);
+}
+
 static inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg)
 {
 	u32 val = readl(vpu->dec_base + reg);
diff --git a/drivers/staging/media/hantro/hantro_g2.c b/drivers/staging/media/hantro/hantro_g2.c
new file mode 100644
index 000000000000..5f7bb27913de
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_g2.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hantro VPU codec driver
+ *
+ * Copyright (C) 2021 Collabora Ltd, Andrzej Pietrasiewicz <andrzej.p at collabora.com>
+ */
+
+#include "hantro_hw.h"
+#include "hantro_g2_regs.h"
+
+void hantro_g2_check_idle(struct hantro_dev *vpu)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		u32 status;
+
+		/* Make sure the VPU is idle */
+		status = vdpu_read(vpu, G2_REG_INTERRUPT);
+		if (status & G2_REG_INTERRUPT_DEC_E) {
+			dev_warn(vpu->dev, "device still running, aborting");
+			status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS;
+			vdpu_write(vpu, status, G2_REG_INTERRUPT);
+		}
+	}
+}
+
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 340efb57fd18..226cecda9495 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -8,20 +8,6 @@
 #include "hantro_hw.h"
 #include "hantro_g2_regs.h"
 
-#define HEVC_DEC_MODE	0xC
-
-#define BUS_WIDTH_32		0
-#define BUS_WIDTH_64		1
-#define BUS_WIDTH_128		2
-#define BUS_WIDTH_256		3
-
-static inline void hantro_write_addr(struct hantro_dev *vpu,
-				     unsigned long offset,
-				     dma_addr_t addr)
-{
-	vdpu_write(vpu, addr & 0xffffffff, offset);
-}
-
 static void prepare_tile_info_buffer(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
@@ -516,23 +502,6 @@ static void set_buffers(struct hantro_ctx *ctx)
 	hantro_write_addr(vpu, G2_TILE_BSD, ctx->hevc_dec.tile_bsd.dma);
 }
 
-static void hantro_g2_check_idle(struct hantro_dev *vpu)
-{
-	int i;
-
-	for (i = 0; i < 3; i++) {
-		u32 status;
-
-		/* Make sure the VPU is idle */
-		status = vdpu_read(vpu, G2_REG_INTERRUPT);
-		if (status & G2_REG_INTERRUPT_DEC_E) {
-			dev_warn(vpu->dev, "device still running, aborting");
-			status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS;
-			vdpu_write(vpu, status, G2_REG_INTERRUPT);
-		}
-	}
-}
-
 int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h
index bb22fa921914..0ac0ba375e80 100644
--- a/drivers/staging/media/hantro/hantro_g2_regs.h
+++ b/drivers/staging/media/hantro/hantro_g2_regs.h
@@ -27,6 +27,13 @@
 #define G2_REG_INTERRUPT_DEC_IRQ_DIS	BIT(4)
 #define G2_REG_INTERRUPT_DEC_E		BIT(0)
 
+#define HEVC_DEC_MODE			0xc
+
+#define BUS_WIDTH_32			0
+#define BUS_WIDTH_64			1
+#define BUS_WIDTH_128			2
+#define BUS_WIDTH_256			3
+
 #define g2_strm_swap		G2_DEC_REG(2, 28, 0xf)
 #define g2_dirmv_swap		G2_DEC_REG(2, 20, 0xf)
 
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 4323e63dfbfc..42b3f3961f75 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -308,4 +308,6 @@ void hantro_vp8_dec_exit(struct hantro_ctx *ctx);
 void hantro_vp8_prob_update(struct hantro_ctx *ctx,
 			    const struct v4l2_ctrl_vp8_frame *hdr);
 
+void hantro_g2_check_idle(struct hantro_dev *vpu);
+
 #endif /* HANTRO_HW_H_ */
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:41 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:41 +0200
Subject: [PATCH v3 05/10] media: uapi: Add VP9 stateless decoder controls
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-6-andrzej.p@collabora.com>

Add the VP9 stateless decoder controls plus the documentation that goes
with it.

Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
Co-developed-by: Ezequiel Garcia <ezequiel at collabora.com>
Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu at collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
Co-developed-by: Daniel Almeida <daniel.almeida at collabora.com>
Signed-off-by: Daniel Almeida <daniel.almeida at collabora.com>
---
 .../userspace-api/media/v4l/biblio.rst        |  10 +
 .../media/v4l/ext-ctrls-codec-stateless.rst   | 545 ++++++++++++++++++
 .../media/v4l/pixfmt-compressed.rst           |  15 +
 .../media/v4l/vidioc-g-ext-ctrls.rst          |   8 +
 .../media/v4l/vidioc-queryctrl.rst            |  12 +
 .../media/videodev2.h.rst.exceptions          |   2 +
 drivers/media/v4l2-core/v4l2-ctrls-core.c     | 174 ++++++
 drivers/media/v4l2-core/v4l2-ctrls-defs.c     |   8 +
 drivers/media/v4l2-core/v4l2-ioctl.c          |   1 +
 include/media/v4l2-ctrls.h                    |   4 +
 include/uapi/linux/v4l2-controls.h            | 433 ++++++++++++++
 include/uapi/linux/videodev2.h                |   6 +
 12 files changed, 1218 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/biblio.rst b/Documentation/userspace-api/media/v4l/biblio.rst
index 7b8e6738ff9e..9cd18c153d19 100644
--- a/Documentation/userspace-api/media/v4l/biblio.rst
+++ b/Documentation/userspace-api/media/v4l/biblio.rst
@@ -417,3 +417,13 @@ VP8
 :title:     RFC 6386: "VP8 Data Format and Decoding Guide"
 
 :author:    J. Bankoski et al.
+
+.. _vp9:
+
+VP9
+===
+
+
+:title:     VP9 Bitstream & Decoding Process Specification
+
+:author:    Adrian Grange (Google), Peter de Rivaz (Argon Design), Jonathan Hunt (Argon Design)
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
index 72f5e85b4f34..af06d46e5993 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
@@ -1458,3 +1458,548 @@ FWHT Flags
 .. raw:: latex
 
     \normalsize
+
+.. _v4l2-codec-stateless-vp9:
+
+``V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS (struct)``
+    Stores VP9 probabilities updates as parsed from the current compressed frame
+    header. A value of zero in an array element means no update of the relevant
+    probability. Motion vector-related updates contain a new value or zero. All
+    other updates contain values translated with inv_map_table[] (see 6.3.5 in
+    :ref:`vp9`).
+
+.. c:type:: v4l2_ctrl_vp9_compressed_hdr_probs
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}|
+
+.. flat-table:: struct v4l2_ctrl_vp9_compressed_hdr_probs
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``tx8[2][1]``
+      - TX 8x8 probabilities delta.
+    * - __u8
+      - ``tx16[2][2]``
+      - TX 16x16 probabilities delta.
+    * - __u8
+      - ``tx32[2][3]``
+      - TX 32x32 probabilities delta.
+    * - __u8
+      - ``coef[4][2][2][6][6][3]``
+      - Coefficient probabilities delta.
+    * - __u8
+      - ``skip[3]``
+      - Skip probabilities delta.
+    * - __u8
+      - ``inter_mode[7][3]``
+      - Inter prediction mode probabilities delta.
+    * - __u8
+      - ``interp_filter[4][2]``
+      - Interpolation filter probabilities delta.
+    * - __u8
+      - ``is_inter[4]``
+      - Is inter-block probabilities delta.
+    * - __u8
+      - ``comp_mode[5]``
+      - Compound prediction mode probabilities delta.
+    * - __u8
+      - ``single_ref[5][2]``
+      - Single reference probabilities delta.
+    * - __u8
+      - ``comp_ref[5]``
+      - Compound reference probabilities delta.
+    * - __u8
+      - ``y_mode[4][9]``
+      - Y prediction mode probabilities delta.
+    * - __u8
+      - ``uv_mode[10][9]``
+      - UV prediction mode probabilities delta.
+    * - __u8
+      - ``partition[16][3]``
+      - Partition probabilities delta.
+    * - __u8
+      - ``mv.joint[3]``
+      - Motion vector joint probabilities delta.
+    * - __u8
+      - ``mv.sign[2]``
+      - Motion vector sign probabilities delta.
+    * - __u8
+      - ``mv.classes[2][10]``
+      - Motion vector class probabilities delta.
+    * - __u8
+      - ``mv.class0_bit[2]``
+      - Motion vector class0 bit probabilities delta.
+    * - __u8
+      - ``mv.bits[2][10]``
+      - Motion vector bits probabilities delta.
+    * - __u8
+      - ``mv.class0_fr[2][2][3]``
+      - Motion vector class0 fractional bit probabilities delta.
+    * - __u8
+      - ``mv.fr[2][3]``
+      - Motion vector fractional bit probabilities delta.
+    * - __u8
+      - ``mv.class0_hp[2]``
+      - Motion vector class0 high precision fractional bit probabilities delta.
+    * - __u8
+      - ``mv.hp[2]``
+      - Motion vector high precision fractional bit probabilities delta.
+
+``V4L2_CID_STATELESS_VP9_FRAME (struct)``
+    Specifies the frame parameters for the associated VP9 frame decode request.
+    This includes the necessary parameters for configuring a stateless hardware
+    decoding pipeline for VP9. The bitstream parameters are defined according
+    to :ref:`vp9`.
+
+.. c:type:: v4l2_ctrl_vp9_frame
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_ctrl_vp9_frame
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - struct :c:type:`v4l2_vp9_loop_filter`
+      - ``lf``
+      - Loop filter parameters. See struct :c:type:`v4l2_vp9_loop_filter` for more details.
+    * - struct :c:type:`v4l2_vp9_quantization`
+      - ``quant``
+      - Quantization parameters. See :c:type:`v4l2_vp9_quantization` for more details.
+    * - struct :c:type:`v4l2_vp9_segmentation`
+      - ``seg``
+      - Segmentation parameters. See :c:type:`v4l2_vp9_segmentation` for more details.
+    * - __u32
+      - ``flags``
+      - Combination of V4L2_VP9_FRAME_FLAG_* flags. See :c:type:`v4l2_vp9_frame_flags`.
+    * - __u16
+      - ``compressed_header_size``
+      - Compressed header size in bytes.
+    * - __u16
+      - ``uncompressed_header_size``
+      - Uncompressed header size in bytes.
+    * - __u16
+      - ``frame_width_minus_1``
+      - Add 1 to get the frame width expressed in pixels. See section 7.2.3 in :ref:`vp9`.
+    * - __u16
+      - ``frame_height_minus_1``
+      - Add 1 to get the frame height expressed in pixels. See section 7.2.3 in :ref:`vp9`.
+    * - __u16
+      - ``render_width_minus_1``
+      - Add 1 to get the expected render width expressed in pixels. This is
+        not used during the decoding process but might be used by HW scalers to
+        prepare a frame that's ready for scanout. See section 7.2.4 in :ref:`vp9`.
+    * - __u16
+      - render_height_minus_1
+      - Add 1 to get the expected render height expressed in pixels. This is
+        not used during the decoding process but might be used by HW scalers to
+        prepare a frame that's ready for scanout. See section 7.2.4 in :ref:`vp9`.
+    * - __u64
+      - ``last_frame_ts``
+      - "last" reference buffer timestamp.
+	The timestamp refers to the ``timestamp`` field in
+        struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+        function to convert the struct :c:type:`timeval` in struct
+        :c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``golden_frame_ts``
+      - "golden" reference buffer timestamp.
+	The timestamp refers to the ``timestamp`` field in
+        struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+        function to convert the struct :c:type:`timeval` in struct
+        :c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``alt_frame_ts``
+      - "alt" reference buffer timestamp.
+	The timestamp refers to the ``timestamp`` field in
+        struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+        function to convert the struct :c:type:`timeval` in struct
+        :c:type:`v4l2_buffer` to a __u64.
+    * - __u8
+      - ``ref_frame_sign_bias``
+      - a bitfield specifying whether the sign bias is set for a given
+        reference frame. See :c:type:`v4l2_vp9_ref_frame_sign_bias` for more details.
+    * - __u8
+      - ``reset_frame_context``
+      - specifies whether the frame context should be reset to default values. See
+        :c:type:`v4l2_vp9_reset_frame_context` for more details.
+    * - __u8
+      - ``frame_context_idx``
+      - Frame context that should be used/updated.
+    * - __u8
+      - ``profile``
+      - VP9 profile. Can be 0, 1, 2 or 3.
+    * - __u8
+      - ``bit_depth``
+      - Component depth in bits. Can be 8, 10 or 12. Note that not all profiles
+        support 10 and/or 12 bits depths.
+    * - __u8
+      - ``interpolation_filter``
+      - Specifies the filter selection used for performing inter prediction. See
+        :c:type:`v4l2_vp9_interpolation_filter` for more details.
+    * - __u8
+      - ``tile_cols_log2``
+      - Specifies the base 2 logarithm of the width of each tile (where the
+        width is measured in units of 8x8 blocks). Shall be less than or equal
+        to 6.
+    * - __u8
+      - ``tile_rows_log2``
+      - Specifies the base 2 logarithm of the height of each tile (where the
+        height is measured in units of 8x8 blocks).
+    * - __u8
+      - ``tx_mode``
+      - Specifies the TX mode. See :c:type:`v4l2_vp9_tx_mode` for more details.
+    * - __u8
+      - ``reference_mode``
+      - Specifies the type of inter prediction to be used. See
+        :c:type:`v4l2_vp9_reference_mode` for more details.
+    * - __u8
+      - ``reserved[6]``
+      - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_vp9_frame_flags
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_frame_flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_FRAME_FLAG_KEY_FRAME``
+      - The frame is a key frame.
+    * - ``V4L2_VP9_FRAME_FLAG_SHOW_FRAME``
+      - The frame should be displayed.
+    * - ``V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT``
+      - The decoding should be error resilient.
+    * - ``V4L2_VP9_FRAME_FLAG_INTRA_ONLY``
+      - The frame does not reference other frames.
+    * - ``V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV``
+      - The frame can use high precision motion vectors.
+    * - ``V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX``
+      - Frame context should be updated after decoding.
+    * - ``V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE``
+      - Parallel decoding is used.
+    * - ``V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING``
+      - Vertical subsampling is enabled.
+    * - ``V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING``
+      - Horizontal subsampling is enabled.
+    * - ``V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING``
+      - The full UV range is used.
+
+.. c:type:: v4l2_vp9_tx_mode
+
+See section '7.3.1 Tx mode semantics' of the VP9 specification for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_tx_mode
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_TX_MODE_ONLY_4X4``
+      - Transform size is 4x4.
+    * - ``V4L2_VP9_TX_MODE_ALLOW_8X8``
+      - Transform size can be up to 8x8.
+    * - ``V4L2_VP9_TX_MODE_ALLOW_16X16``
+      - Transform size can be up to 16x16.
+    * - ``V4L2_VP9_TX_MODE_ALLOW_32X32``
+      - transform size can be up to 32x32.
+    * - ``V4L2_VP9_TX_MODE_SELECT``
+      - Bitstream contains the transform size for each block.
+
+.. c:type:: v4l2_vp9_reference_mode
+
+See section '7.3.6 Frame reference mode semantics' of the VP9 specification for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_reference_mode
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE``
+      - Indicates that all the inter blocks use only a single reference frame
+        to generate motion compensated prediction.
+    * - ``V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE``
+      - Requires all the inter blocks to use compound mode. Single reference
+        frame prediction is not allowed.
+    * - ``V4L2_VP9_REFERENCE_MODE_SELECT``
+      - Allows each individual inter block to select between single and
+        compound prediction modes.
+
+.. c:type:: v4l2_vp9_interpolation_filter
+
+See section '7.2.7 Interpolation filter semantics' of the VP9 specification
+for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_interpolation_filter
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP``
+      - Eight tap filter.
+    * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH``
+      - Eight tap smooth filter.
+    * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP``
+      - Eeight tap sharp filter.
+    * - ``V4L2_VP9_INTERP_FILTER_BILINEAR``
+      - Bilinear filter.
+    * - ``V4L2_VP9_INTERP_FILTER_SWITCHABLE``
+      - Filter selection is signaled at the block level.
+
+.. c:type:: v4l2_vp9_reset_frame_context
+
+See section '7.2 Uncompressed header semantics' of the VP9 specification
+for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_reset_frame_context
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_RESET_FRAME_CTX_NONE``
+      - Do not reset any frame context.
+    * - ``V4L2_VP9_RESET_FRAME_CTX_SPEC``
+      - Reset the frame context pointed to by
+        :c:type:`v4l2_ctrl_vp9_frame`.frame_context_idx.
+    * - ``V4L2_VP9_RESET_FRAME_CTX_ALL``
+      - Reset all frame contexts.
+
+.. c:type:: v4l2_vp9_intra_prediction_mode
+
+See section '7.4.5 Intra frame mode info semantics' for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_intra_prediction_mode
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_INTRA_PRED_MODE_DC_PRED``
+      - DC intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_V_PRED``
+      - Vertical intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_H_PRED``
+      - Horizontal intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_D45_PRED``
+      - D45 intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_D135_PRED``
+      - D135 intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_D117_PRED``
+      - D117 intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_D153_PRED``
+      - D153 intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_D207_PRED``
+      - D207 intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_D63_PRED``
+      - D63 intra prediction.
+    * - ``V4L2_VP9_INTRA_PRED_MODE_TM_PRED``
+      - True motion intra prediction.
+
+.. c:type:: v4l2_vp9_segmentation
+
+Encodes the quantization parameters. See section '7.2.10 Segmentation
+params syntax' of the VP9 specification for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp9_segmentation
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``feature_data[8][4]``
+      - Data attached to each feature. Data entry is only valid if the feature
+        is enabled.
+    * - __u8
+      - ``feature_enabled[8]``
+      - Bitmask defining which features are enabled in each segment.
+    * - __u8
+      - ``tree_probs[7]``
+      - Specifies the probability values to be used when decoding a Segment-ID.
+        See '5.15. Segmentation map' section of :ref:`vp9` for more details.
+    * - __u8
+      - ``pred_probs[3]``
+      - Specifies the probability values to be used when decoding a
+        Predicted-Segment-ID. See '6.4.14. Get segment id syntax'
+        section of :ref:`vp9` for more details.
+    * - __u8
+      - ``flags``
+      - Combination of V4L2_VP9_SEGMENTATION_FLAG_* flags. See
+        :c:type:`v4l2_vp9_segmentation_flags`.
+    * - __u8
+      - ``reserved[5]``
+      - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_vp9_segment_feature
+
+Segment feature IDs. See section '7.2.10 Segmentation params syntax' of the
+VP9 specification for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_segment_feature
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_SEG_LVL_ALT_Q``
+      - Quantizer segment feature.
+    * - ``V4L2_VP9_SEG_LVL_ALT_L``
+      - Loop filter segment feature.
+    * - ``V4L2_VP9_SEG_LVL_REF_FRAME``
+      - Reference frame segment feature.
+    * - ``V4L2_VP9_SEG_LVL_SKIP``
+      - Skip segment feature.
+    * - ``V4L2_VP9_SEG_LVL_MAX``
+      - Number of segment features.
+
+.. c:type:: v4l2_vp9_segmentation_flags
+
+Those are the flags that may be passed to &v4l2_vp9_segmentation.flags. See
+section '7.2.10 Segmentation params syntax' of the VP9 specification for
+more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_segmentation_flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_SEGMENTATION_FLAG_ENABLED``
+      - Indicates that this frame makes use of the segmentation tool.
+    * - ``V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP``
+      - Indicates that the segmentation map should be updated during the
+        decoding of this frame.
+    * - ``V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE``
+      - Indicates that the updates to the segmentation map are coded
+        relative to the existing segmentation map.
+    * - ``V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA``
+      - Indicates that new parameters are about to be specified for each
+        segment.
+    * - ``V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE``
+      - Indicates that the segmentation parameters represent the actual values
+        to be used.
+
+.. c:type:: v4l2_vp9_quantization
+
+Encodes the quantization parameters. See section '7.2.9 Quantization params
+syntax' of the VP9 specification for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp9_quantization
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``base_q_idx``
+      - Indicates the base frame qindex.
+    * - __s8
+      - ``delta_q_y_dc``
+      - Indicates the Y DC quantizer relative to base_q_idx.
+    * - __s8
+      - ``delta_q_uv_dc``
+      - Indicates the UV DC quantizer relative to base_q_idx.
+    * - __s8
+      - ``delta_q_uv_ac``
+      - Indicates the UV AC quantizer relative to base_q_idx.
+    * - __u8
+      - ``reserved[4]``
+      - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_vp9_loop_filter
+
+This structure contains all loop filter related parameters. See sections
+'7.2.8 Loop filter semantics' of the VP9 specification for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp9_loop_filter
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __s8
+      - ``ref_deltas[4]``
+      - Contains the adjustment needed for the filter level based on the chosen
+        reference frame.
+    * - __s8
+      - ``mode_deltas[2]``
+      - Contains the adjustment needed for the filter level based on the chosen
+        mode.
+    * - __u8
+      - ``level``
+      - Indicates the loop filter strength.
+    * - __u8
+      - ``sharpness``
+      - Indicates the sharpness level.
+    * - __u8
+      - ``flags``
+      - Combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags.
+        See :c:type:`v4l2_vp9_loop_filter_flags`.
+    * - __u8
+      - ``reserved[7]``
+      - Applications and drivers must set this to zero.
+
+
+.. c:type:: v4l2_vp9_loop_filter_flags
+
+Those are the flags that may be passed. See section '7.2.8 Loop filter
+semantics' of the VP9 specification for more details.
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: enum v4l2_vp9_loop_filter_flags
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 2
+
+    * - ``V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED``
+      - When set, the filter level depends on the mode and reference frame used
+        to predict a block.
+    * - ``V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE``
+      - When set, the bitstream contains additional syntax elements that
+        specify which mode and reference frame deltas are to be updated.
diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
index 0ede39907ee2..1b20f48a24b9 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
@@ -172,6 +172,21 @@ Compressed Formats
       - VP9 compressed video frame. The encoder generates one
 	compressed frame per buffer, and the decoder requires one
 	compressed frame per buffer.
+    * .. _V4L2-PIX-FMT-VP9-FRAME:
+
+      - ``V4L2_PIX_FMT_VP9_FRAME``
+      - 'VP9F'
+      - VP9 parsed frame, including the frame header, as extracted from the container.
+	This format is adapted for stateless video decoders that implement a
+	VP9 pipeline with the :ref:`stateless_decoder`.
+	Metadata associated with the frame to decode is required to be passed
+	through the ``V4L2_CID_STATELESS_VP9_FRAME`` and
+	the ``V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS`` controls.
+	See the :ref:`associated Codec Control IDs <v4l2-codec-stateless-vp9>`.
+	Exactly one output and one capture buffer must be provided for use with
+	this pixel format. The output buffer must contain the appropriate number
+	of macroblocks to decode a full corresponding frame to the matching
+	capture buffer.
     * .. _V4L2-PIX-FMT-HEVC:
 
       - ``V4L2_PIX_FMT_HEVC``
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
index 2d6bc8d94380..258895ff0c71 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
@@ -233,6 +233,14 @@ still cause this situation.
       - ``p_mpeg2_quantisation``
       - A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_quantisation`. Valid if this control is
         of type ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION``.
+    * - struct :c:type:`v4l2_ctrl_vp9_compressed_hdr_probs` *
+      - ``p_vp9_compressed_hdr_probs``
+      - A pointer to a struct :c:type:`v4l2_ctrl_vp9_compressed_hdr_probs`. Valid if this
+        control is of type ``V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS``.
+    * - struct :c:type:`v4l2_ctrl_vp9_frame` *
+      - ``p_vp9_frame``
+      - A pointer to a struct :c:type:`v4l2_ctrl_vp9_frame`. Valid if this
+        control is of type ``V4L2_CTRL_TYPE_VP9_FRAME``.
     * - struct :c:type:`v4l2_ctrl_hdr10_cll_info` *
       - ``p_hdr10_cll``
       - A pointer to a struct :c:type:`v4l2_ctrl_hdr10_cll_info`. Valid if this control is
diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
index f9ecf6276129..e0c6a5d9ff6b 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
@@ -507,6 +507,18 @@ See also the examples in :ref:`control`.
       - n/a
       - A struct :c:type:`v4l2_ctrl_hevc_decode_params`, containing HEVC
 	decoding parameters for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_vp9_compressed_hdr_probs`, containing VP9
+	probabilities updates for stateless video decoders.
+    * - ``V4L2_CTRL_TYPE_VP9_FRAME``
+      - n/a
+      - n/a
+      - n/a
+      - A struct :c:type:`v4l2_ctrl_vp9_frame`, containing VP9
+	frame decode parameters for stateless video decoders.
 
 .. raw:: latex
 
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
index eb0b1cd37abd..129ef3edfa73 100644
--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -149,6 +149,8 @@ replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_FWHT_PARAMS :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_VP8_FRAME :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS :c:type:`v4l2_ctrl_type`
+replace symbol V4L2_CTRL_TYPE_VP9_FRAME :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_HDR10_CLL_INFO :c:type:`v4l2_ctrl_type`
 replace symbol V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY :c:type:`v4l2_ctrl_type`
 
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index c4b5082849b6..ed9cf298a83a 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -283,6 +283,12 @@ static void std_log(const struct v4l2_ctrl *ctrl)
 	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
 		pr_cont("MPEG2_PICTURE");
 		break;
+	case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS:
+		pr_cont("VP9_COMPRESSED_HDR_PROBS");
+		break;
+	case V4L2_CTRL_TYPE_VP9_FRAME:
+		pr_cont("VP9_FRAME");
+		break;
 	default:
 		pr_cont("unknown type %d", ctrl->type);
 		break;
@@ -317,6 +323,162 @@ static void std_log(const struct v4l2_ctrl *ctrl)
 #define zero_reserved(s) \
 	memset(&(s).reserved, 0, sizeof((s).reserved))
 
+static int
+validate_vp9_lf_params(struct v4l2_vp9_loop_filter *lf)
+{
+	unsigned int i;
+
+	if (lf->flags & ~(V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED |
+			  V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE))
+		return -EINVAL;
+
+	/* That all values are in the accepted range. */
+	if (lf->level > GENMASK(5, 0))
+		return -EINVAL;
+
+	if (lf->sharpness > GENMASK(2, 0))
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++)
+		if (lf->ref_deltas[i] < -63 || lf->ref_deltas[i] > 63)
+			return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++)
+		if (lf->mode_deltas[i] < -63 || lf->mode_deltas[i] > 63)
+			return -EINVAL;
+
+	zero_reserved(*lf);
+	return 0;
+}
+
+static int
+validate_vp9_quant_params(struct v4l2_vp9_quantization *quant)
+{
+	if (quant->delta_q_y_dc < -15 || quant->delta_q_y_dc > 15 ||
+	    quant->delta_q_uv_dc < -15 || quant->delta_q_uv_dc > 15 ||
+	    quant->delta_q_uv_ac < -15 || quant->delta_q_uv_ac > 15)
+		return -EINVAL;
+
+	zero_reserved(*quant);
+	return 0;
+}
+
+static int
+validate_vp9_seg_params(struct v4l2_vp9_segmentation *seg)
+{
+	unsigned int i, j;
+
+	if (seg->flags & ~(V4L2_VP9_SEGMENTATION_FLAG_ENABLED |
+			   V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP |
+			   V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE |
+			   V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA |
+			   V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE))
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(seg->feature_enabled); i++) {
+		if (seg->feature_enabled[i] &
+		    ~V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK)
+			return -EINVAL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(seg->feature_data); i++) {
+		const int range[] = { 255, 63, 3, 0 };
+
+		for (j = 0; j < ARRAY_SIZE(seg->feature_data[j]); j++) {
+			if (seg->feature_data[i][j] < -range[j] ||
+			    seg->feature_data[i][j] > range[j])
+				return -EINVAL;
+		}
+	}
+
+	zero_reserved(*seg);
+	return 0;
+}
+
+static int
+validate_vp9_frame(struct v4l2_ctrl_vp9_frame *frame)
+{
+	int ret;
+
+	/* Make sure we're not passed invalid flags. */
+	if (frame->flags & ~(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
+		  V4L2_VP9_FRAME_FLAG_SHOW_FRAME |
+		  V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT |
+		  V4L2_VP9_FRAME_FLAG_INTRA_ONLY |
+		  V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV |
+		  V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX |
+		  V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE |
+		  V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
+		  V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING |
+		  V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING))
+		return -EINVAL;
+
+	if (frame->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT &&
+	    frame->flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX)
+		return -EINVAL;
+
+	if (frame->profile > V4L2_VP9_PROFILE_MAX)
+		return -EINVAL;
+
+	if (frame->reset_frame_context > V4L2_VP9_RESET_FRAME_CTX_ALL)
+		return -EINVAL;
+
+	if (frame->frame_context_idx >= V4L2_VP9_NUM_FRAME_CTX)
+		return -EINVAL;
+
+	/*
+	 * Profiles 0 and 1 only support 8-bit depth, profiles 2 and 3 only 10
+	 * and 12 bit depths.
+	 */
+	if ((frame->profile < 2 && frame->bit_depth != 8) ||
+	    (frame->profile >= 2 &&
+	     (frame->bit_depth != 10 && frame->bit_depth != 12)))
+		return -EINVAL;
+
+	/* Profile 0 and 2 only accept YUV 4:2:0. */
+	if ((frame->profile == 0 || frame->profile == 2) &&
+	    (!(frame->flags & V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING) ||
+	     !(frame->flags & V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING)))
+		return -EINVAL;
+
+	/* Profile 1 and 3 only accept YUV 4:2:2, 4:4:0 and 4:4:4. */
+	if ((frame->profile == 1 || frame->profile == 3) &&
+	    ((frame->flags & V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING) &&
+	     (frame->flags & V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING)))
+		return -EINVAL;
+
+	if (frame->interpolation_filter > V4L2_VP9_INTERP_FILTER_SWITCHABLE)
+		return -EINVAL;
+
+	/*
+	 * According to the spec, tile_cols_log2 shall be less than or equal
+	 * to 6.
+	 */
+	if (frame->tile_cols_log2 > 6)
+		return -EINVAL;
+
+	if (frame->tx_mode > V4L2_VP9_TX_MODE_SELECT)
+		return -EINVAL;
+
+	if (frame->reference_mode > V4L2_VP9_REFERENCE_MODE_SELECT)
+		return -EINVAL;
+
+	ret = validate_vp9_lf_params(&frame->lf);
+	if (ret)
+		return ret;
+
+	ret = validate_vp9_quant_params(&frame->quant);
+	if (ret)
+		return ret;
+
+	ret = validate_vp9_seg_params(&frame->seg);
+	if (ret)
+		return ret;
+
+	zero_reserved(*frame);
+	return 0;
+}
+
 /*
  * Compound controls validation requires setting unused fields/flags to zero
  * in order to properly detect unchanged controls with std_equal's memcmp.
@@ -687,6 +849,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 
 		break;
 
+	case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS:
+		break;
+
+	case V4L2_CTRL_TYPE_VP9_FRAME:
+		return validate_vp9_frame(p);
+
 	case V4L2_CTRL_TYPE_AREA:
 		area = p;
 		if (!area->width || !area->height)
@@ -1249,6 +1417,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 	case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY:
 		elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display);
 		break;
+	case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS:
+		elem_size = sizeof(struct v4l2_ctrl_vp9_compressed_hdr_probs);
+		break;
+	case V4L2_CTRL_TYPE_VP9_FRAME:
+		elem_size = sizeof(struct v4l2_ctrl_vp9_frame);
+		break;
 	case V4L2_CTRL_TYPE_AREA:
 		elem_size = sizeof(struct v4l2_area);
 		break;
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index 421300e13a41..d383c438156f 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -1175,6 +1175,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_STATELESS_MPEG2_SEQUENCE:			return "MPEG-2 Sequence Header";
 	case V4L2_CID_STATELESS_MPEG2_PICTURE:			return "MPEG-2 Picture Header";
 	case V4L2_CID_STATELESS_MPEG2_QUANTISATION:		return "MPEG-2 Quantisation Matrices";
+	case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS:	return "VP9 Probabilities Updates";
+	case V4L2_CID_STATELESS_VP9_FRAME:			return "VP9 Frame Decode Parameters";
 
 	/* Colorimetry controls */
 	/* Keep the order of the 'case's the same as in v4l2-controls.h! */
@@ -1493,6 +1495,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:
 		*type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS;
 		break;
+	case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS:
+		*type = V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS;
+		break;
+	case V4L2_CID_STATELESS_VP9_FRAME:
+		*type = V4L2_CTRL_TYPE_VP9_FRAME;
+		break;
 	case V4L2_CID_UNIT_CELL_SIZE:
 		*type = V4L2_CTRL_TYPE_AREA;
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index ec6fc1ef291e..7a5e8120d733 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1394,6 +1394,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
 		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;
 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
+		case V4L2_PIX_FMT_VP9_FRAME:    descr = "VP9 Frame"; break;
 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
 		case V4L2_PIX_FMT_HEVC_SLICE:	descr = "HEVC Parsed Slice Data"; break;
 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 575b59fbac77..3ea4386ebd91 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -50,6 +50,8 @@ struct video_device;
  * @p_h264_decode_params:	Pointer to a struct v4l2_ctrl_h264_decode_params.
  * @p_h264_pred_weights:	Pointer to a struct v4l2_ctrl_h264_pred_weights.
  * @p_vp8_frame:		Pointer to a VP8 frame params structure.
+ * @p_vp9_compressed_hdr_probs:	Pointer to a VP9 frame compressed header probs structure.
+ * @p_vp9_frame:		Pointer to a VP9 frame params structure.
  * @p_hevc_sps:			Pointer to an HEVC sequence parameter set structure.
  * @p_hevc_pps:			Pointer to an HEVC picture parameter set structure.
  * @p_hevc_slice_params:	Pointer to an HEVC slice parameters structure.
@@ -80,6 +82,8 @@ union v4l2_ctrl_ptr {
 	struct v4l2_ctrl_hevc_sps *p_hevc_sps;
 	struct v4l2_ctrl_hevc_pps *p_hevc_pps;
 	struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
+	struct v4l2_ctrl_vp9_compressed_hdr_probs *p_vp9_compressed_hdr_probs;
+	struct v4l2_ctrl_vp9_frame *p_vp9_frame;
 	struct v4l2_ctrl_hdr10_cll_info *p_hdr10_cll;
 	struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
 	struct v4l2_area *p_area;
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 5532b5f68493..8f8c3c1ad885 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -2010,6 +2010,439 @@ struct v4l2_ctrl_hdr10_mastering_display {
 	__u32 min_display_mastering_luminance;
 };
 
+/* Stateless VP9 controls */
+
+/**
+ * enum v4l2_vp9_loop_filter_flags - VP9 loop filter flags
+ *
+ * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED: the filter level depends on
+ *	the mode and reference frame used to predict a block
+ * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE: the bitstream contains additional
+ *	syntax elements that specify which mode and reference frame deltas are to be updated
+ *
+ * Those are the flags that may be passed to &v4l2_vp9_loop_filter.flags. See
+ * section '7.2.8 Loop filter semantics' of the VP9 specification for more
+ * details.
+ */
+enum v4l2_vp9_loop_filter_flags {
+	V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED = 1 << 0,
+	V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE = 1 << 1,
+};
+
+/**
+ * struct v4l2_vp9_loop_filter - VP9 loop filter parameters
+ *
+ * @ref_deltas: contains the adjustment needed for the filter level based on the chosen
+ *	reference frame. If this syntax element is not present in the bitstream, users
+ *	should pass its last value.
+ * @mode_deltas: contains the adjustment needed for the filter level based on the chosen mode.
+ *	If this syntax element is not present in the bitstream, users
+ *	should pass its last value.
+ * @level: indicates the loop filter strength
+ * @sharpness: indicates the sharpness level
+ * @flags: combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * This structure contains all loop filter related parameters. See sections
+ * '7.2.8 Loop filter semantics' of the VP9 specification for more details.
+ */
+struct v4l2_vp9_loop_filter {
+	__s8 ref_deltas[4];
+	__s8 mode_deltas[2];
+	__u8 level;
+	__u8 sharpness;
+	__u8 flags;
+	__u8 reserved[7];
+};
+
+/**
+ * struct v4l2_vp9_quantization - VP9 quantization parameters
+ *
+ * @base_q_idx: indicates the base frame qindex
+ * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx
+ * @delta_q_uv_dc: indicates the UV DC quantizer relative to base_q_idx
+ * @delta_q_uv_ac: indicates the UV AC quantizer relative to base_q_idx
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * Encodes the quantization parameters. See section '7.2.9 Quantization params
+ * syntax' of the VP9 specification for more details.
+ */
+struct v4l2_vp9_quantization {
+	__u8 base_q_idx;
+	__s8 delta_q_y_dc;
+	__s8 delta_q_uv_dc;
+	__s8 delta_q_uv_ac;
+	__u8 reserved[4];
+};
+
+/**
+ * enum v4l2_vp9_segmentation_flags - VP9 segmentation flags
+ *
+ * @V4L2_VP9_SEGMENTATION_FLAG_ENABLED: indicates that this frame makes use of
+ *	the segmentation tool
+ * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP: indicates that the segmentation map
+ *	should be updated during the decoding of this frame
+ * @V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE: indicates that the updates to
+ *	the segmentation map are coded relative to the existing segmentation map
+ * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA: indicates that new parameters are
+ *	about to be specified for each segment
+ * @V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE: indicates that the
+ *	segmentation parameters represent the actual values to be used
+ *
+ * Those are the flags that may be passed to &v4l2_vp9_segmentation.flags. See
+ * section '7.2.10 Segmentation params syntax' of the VP9 specification for
+ * more details.
+ */
+enum v4l2_vp9_segmentation_flags {
+	V4L2_VP9_SEGMENTATION_FLAG_ENABLED = 1 << 0,
+	V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP = 1 << 1,
+	V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE = 1 << 2,
+	V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA = 1 << 3,
+	V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE = 1 << 4,
+};
+
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id)	(1 << (id))
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK	0xf
+
+/**
+ * enum v4l2_vp9_segment_feature - VP9 segment feature IDs
+ *
+ * @V4L2_VP9_SEG_LVL_ALT_Q: quantizer segment feature
+ * @V4L2_VP9_SEG_LVL_ALT_L: loop filter segment feature
+ * @V4L2_VP9_SEG_LVL_REF_FRAME reference frame segment feature
+ * @V4L2_VP9_SEG_LVL_SKIP: skip segment feature
+ * @V4L2_VP9_SEG_LVV_MAX: number of segment features
+ *
+ * Segment feature IDs. See section '7.2.10 Segmentation params syntax' of the
+ * VP9 specification for more details.
+ */
+enum v4l2_vp9_segment_feature {
+	V4L2_VP9_SEG_LVL_ALT_Q,
+	V4L2_VP9_SEG_LVL_ALT_L,
+	V4L2_VP9_SEG_LVL_REF_FRAME,
+	V4L2_VP9_SEG_LVL_SKIP,
+	V4L2_VP9_SEG_LVL_MAX,
+};
+
+/**
+ * struct v4l2_vp9_segmentation - VP9 segmentation parameters
+ *
+ * @feature_data: data attached to each feature. Data entry is only valid if the feature is enabled
+ * @feature_enabled: bitmask defining which features are enabled in each segment
+ * @tree_probs: specifies the probability values to be used when
+ *	decoding a Segment-ID. See '5.15. Segmentation map' section of the VP9 specification
+ *	for more details.
+ * @pred_probs: specifies the probability values to be used when decoding a
+ *	Predicted-Segment-ID. See '6.4.14. Get segment id syntax' section of :ref:`vp9`
+ *	for more details.
+ * @flags: combination of V4L2_VP9_SEGMENTATION_FLAG_* flags
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * Encodes the quantization parameters. See section '7.2.10 Segmentation params syntax' of
+ * the VP9 specification for more details.
+ */
+struct v4l2_vp9_segmentation {
+	__s16 feature_data[8][4];
+	__u8 feature_enabled[8];
+	__u8 tree_probs[7];
+	__u8 pred_probs[3];
+	__u8 flags;
+	__u8 reserved[5];
+};
+
+/**
+ * enum v4l2_vp9_intra_prediction_mode - VP9 Intra prediction modes
+ *
+ * @V4L2_VP9_INTRA_PRED_MODE_DC_PRED: DC intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_V_PRED: vertical intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_H_PRED: horizontal intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_D45_PRED: D45 intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_D135_PRED: D135 intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_D117_PRED: D117 intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_D153_PRED: D153 intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_D207_PRED: D207 intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_D63_PRED: D63 intra prediction
+ * @V4L2_VP9_INTRA_PRED_MODE_TM_PRED: True Motion intra prediction
+ *
+ * See section '7.4.5 Intra frame mode info semantics' for more details.
+ */
+enum v4l2_vp9_intra_prediction_mode {
+	V4L2_VP9_INTRA_PRED_MODE_DC_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_V_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_H_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_D45_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_D135_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_D117_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_D153_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_D207_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_D63_PRED,
+	V4L2_VP9_INTRA_PRED_MODE_TM_PRED,
+};
+
+/**
+ * enum v4l2_vp9_reset_frame_context - Valid values for
+ *			&v4l2_ctrl_vp9_frame->reset_frame_context
+ *
+ * @V4L2_VP9_RESET_FRAME_CTX_NONE: don't reset any frame context
+ * @V4L2_VP9_RESET_FRAME_CTX_SPEC: reset the frame context pointed by
+ *	&v4l2_ctrl_vp9_frame.frame_context_idx
+ * @V4L2_VP9_RESET_FRAME_CTX_ALL: reset all frame contexts
+ *
+ * See section '7.2 Uncompressed header semantics' of the VP9 specification for more details.
+ */
+enum v4l2_vp9_reset_frame_context {
+	V4L2_VP9_RESET_FRAME_CTX_NONE,
+	V4L2_VP9_RESET_FRAME_CTX_SPEC,
+	V4L2_VP9_RESET_FRAME_CTX_ALL,
+};
+
+/**
+ * enum v4l2_vp9_interpolation_filter - VP9 interpolation filter types
+ *
+ * @V4L2_VP9_INTERP_FILTER_EIGHTTAP: eight tap filter
+ * @V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH: eight tap smooth filter
+ * @V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP: eight tap sharp filter
+ * @V4L2_VP9_INTERP_FILTER_BILINEAR: bilinear filter
+ * @V4L2_VP9_INTERP_FILTER_SWITCHABLE: filter selection is signaled at the block level
+ *
+ * See section '7.2.7 Interpolation filter semantics' of the VP9 specification
+ * for more details.
+ */
+enum v4l2_vp9_interpolation_filter {
+	V4L2_VP9_INTERP_FILTER_EIGHTTAP,
+	V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH,
+	V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP,
+	V4L2_VP9_INTERP_FILTER_BILINEAR,
+	V4L2_VP9_INTERP_FILTER_SWITCHABLE,
+};
+
+/**
+ * enum v4l2_vp9_reference_mode - VP9 reference modes
+ *
+ * @V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE: indicates that all the inter blocks use only a
+ *	single reference frame to generate motion compensated prediction
+ * @V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE: requires all the inter blocks to use compound mode.
+ *	Single reference frame prediction is not allowed
+ * @V4L2_VP9_REFERENCE_MODE_SELECT: allows each individual inter block to select between single
+ *	and compound prediction modes
+ *
+ * See section '7.3.6 Frame reference mode semantics' of the VP9 specification
+ * for more details.
+ */
+enum v4l2_vp9_reference_mode {
+	V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE,
+	V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE,
+	V4L2_VP9_REFERENCE_MODE_SELECT,
+};
+
+/**
+ * enum v4l2_vp9_tx_mode - VP9 TX modes
+ *
+ * @V4L2_VP9_TX_MODE_ONLY_4X4: transform size is 4x4
+ * @V4L2_VP9_TX_MODE_ALLOW_8X8: transform size can be up to 8x8
+ * @V4L2_VP9_TX_MODE_ALLOW_16X16: transform size can be up to 16x16
+ * @V4L2_VP9_TX_MODE_ALLOW_32X32: transform size can be up to 32x32
+ * @V4L2_VP9_TX_MODE_SELECT: bitstream contains the transform size for each block
+ *
+ * See section '7.3.1 Tx mode semantics' of the VP9 specification for more details.
+ */
+enum v4l2_vp9_tx_mode {
+	V4L2_VP9_TX_MODE_ONLY_4X4,
+	V4L2_VP9_TX_MODE_ALLOW_8X8,
+	V4L2_VP9_TX_MODE_ALLOW_16X16,
+	V4L2_VP9_TX_MODE_ALLOW_32X32,
+	V4L2_VP9_TX_MODE_SELECT,
+};
+
+/**
+ * enum v4l2_vp9_frame_flags - VP9 frame flags
+ * @V4L2_VP9_FRAME_FLAG_KEY_FRAME: the frame is a key frame
+ * @V4L2_VP9_FRAME_FLAG_SHOW_FRAME: the frame should be displayed
+ * @V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT: the decoding should be error resilient
+ * @V4L2_VP9_FRAME_FLAG_INTRA_ONLY: the frame does not reference other frames
+ * @V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV: the frame can use high precision motion vectors
+ * @V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX: frame context should be updated after decoding
+ * @V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE: parallel decoding is used
+ * @V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING: vertical subsampling is enabled
+ * @V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING: horizontal subsampling is enabled
+ * @V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING: full UV range is used
+ *
+ * Check the VP9 specification for more details.
+ */
+enum v4l2_vp9_frame_flags {
+	V4L2_VP9_FRAME_FLAG_KEY_FRAME = 1 << 0,
+	V4L2_VP9_FRAME_FLAG_SHOW_FRAME = 1 << 1,
+	V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT = 1 << 2,
+	V4L2_VP9_FRAME_FLAG_INTRA_ONLY = 1 << 3,
+	V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV = 1 << 4,
+	V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX = 1 << 5,
+	V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE = 1 << 6,
+	V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING = 1 << 7,
+	V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING = 1 << 8,
+	V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING = 1 << 9,
+};
+
+/**
+ * enum v4l2_vp9_ref_frame_sign_bias - Whether ref_frame_sign_bias is 1 for a given reference frame
+ * @V4L2_VP9_SIGN_BIAS_LAST: ref_frame_sign_bias is 1 for the "last" reference frame
+ * @V4L2_VP9_SIGN_BIAS_GOLDEN: ref_frame_sign_bias is 1 for the "golden" reference frame
+ * @V4L2_VP9_SIGN_BIAS_ALT: ref_frame_sign_bias is 1 for the "alt" reference frame
+ */
+
+enum v4l2_vp9_ref_frame_sign_bias {
+	V4L2_VP9_SIGN_BIAS_LAST,
+	V4L2_VP9_SIGN_BIAS_GOLDEN,
+	V4L2_VP9_SIGN_BIAS_ALT,
+};
+
+#define V4L2_VP9_PROFILE_MAX		3
+
+#define V4L2_CID_STATELESS_VP9_FRAME	(V4L2_CID_CODEC_STATELESS_BASE + 300)
+/**
+ * struct v4l2_ctrl_vp9_frame - VP9 frame decoding control
+ *
+ * @lf: loop filter parameters. See &v4l2_vp9_loop_filter for more details
+ * @quant: quantization parameters. See &v4l2_vp9_quantization for more details
+ * @seg: segmentation parameters. See &v4l2_vp9_segmentation for more details
+ * @flags: combination of V4L2_VP9_FRAME_FLAG_* flags
+ * @compressed_header_size: compressed header size in bytes
+ * @uncompressed_header_size: uncompressed header size in bytes
+ * @frame_width_minus_1: add 1 to it and you'll get the frame width expressed in pixels
+ * @frame_height_minus_1: add 1 to it and you'll get the frame height expressed in pixels
+ * @render_width_minus_1: add 1 to it and you'll get the expected render width expressed in
+ *	pixels. This is not used during the decoding process but might be used by HW scalers
+ *	to prepare a frame that's ready for scanout
+ * @render_height_minus_1: add 1 to it and you'll get the expected render height expressed in
+ *	pixels. This is not used during the decoding process but might be used by HW scalers
+ *	to prepare a frame that's ready for scanout
+ * @last_frame_ts: "last" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @golden_frame_ts: "golden" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @alt_frame_ts: "alt" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @ref_frame_sign_bias: a bitfield specifying whether the sign bias is set for a given
+ *	reference frame. See &v4l2_vp9_ref_frame_sign_bias for more details.
+ * @reset_frame_context: specifies whether the frame context should be reset to default values.
+ *	See &v4l2_vp9_reset_frame_context for more details
+ * @frame_context_idx: frame context that should be used/updated
+ * @profile: VP9 profile. Can be 0, 1, 2 or 3
+ * @bit_depth: bits per components. Can be 8, 10 or 12. Note that not all profiles support
+ *	10 and/or 12 bits depths
+ * @interpolation_filter: specifies the filter selection used for performing inter prediction.
+ *	See &v4l2_vp9_interpolation_filter for more details
+ * @tile_cols_log2: specifies the base 2 logarithm of the width of each tile (where the width
+ *	is measured in units of 8x8 blocks). Shall be less than or equal to 6
+ * @tile_rows_log2: specifies the base 2 logarithm of the height of each tile (where the height
+ *	is measured in units of 8x8 blocks)
+ * @tx_mode: specifies the TX mode. See &v4l2_vp9_tx_mode for more details
+ * @reference_mode: specifies the type of inter prediction to be used. See
+ *	&v4l2_vp9_reference_mode for more details
+ * @reserved: padding field. Should be zeroed by applications.
+ */
+struct v4l2_ctrl_vp9_frame {
+	struct v4l2_vp9_loop_filter lf;
+	struct v4l2_vp9_quantization quant;
+	struct v4l2_vp9_segmentation seg;
+	__u32 flags;
+	__u16 compressed_header_size;
+	__u16 uncompressed_header_size;
+	__u16 frame_width_minus_1;
+	__u16 frame_height_minus_1;
+	__u16 render_width_minus_1;
+	__u16 render_height_minus_1;
+	__u64 last_frame_ts;
+	__u64 golden_frame_ts;
+	__u64 alt_frame_ts;
+	__u8 ref_frame_sign_bias;
+	__u8 reset_frame_context;
+	__u8 frame_context_idx;
+	__u8 profile;
+	__u8 bit_depth;
+	__u8 interpolation_filter;
+	__u8 tile_cols_log2;
+	__u8 tile_rows_log2;
+	__u8 tx_mode;
+	__u8 reference_mode;
+	__u8 reserved[6];
+};
+
+#define V4L2_VP9_NUM_FRAME_CTX	4
+
+/**
+ * struct v4l2_vp9_mv_compressed_hdr_probs - VP9 Motion vector probability updates
+ * @joint: motion vector joint probability updates
+ * @sign: motion vector sign probability updates
+ * @classes: motion vector class probability updates
+ * @class0_bit: motion vector class0 bit probability updates
+ * @bits: motion vector bits probability updates
+ * @class0_fr: motion vector class0 fractional bit probability updates
+ * @fr: motion vector fractional bit probability updates
+ * @class0_hp: motion vector class0 high precision fractional bit probability updates
+ * @hp: motion vector high precision fractional bit probability updates
+ *
+ * This structure contains new values of motion vector probabilities.
+ * A value of zero in an array element means there is no update of the relevant probability.
+ * See `struct v4l2_vp9_prob_updates` for details.
+ */
+struct v4l2_vp9_mv_compressed_hdr_probs {
+	__u8 joint[3];
+	__u8 sign[2];
+	__u8 classes[2][10];
+	__u8 class0_bit[2];
+	__u8 bits[2][10];
+	__u8 class0_fr[2][2][3];
+	__u8 fr[2][3];
+	__u8 class0_hp[2];
+	__u8 hp[2];
+};
+
+#define V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS	(V4L2_CID_CODEC_STATELESS_BASE + 301)
+/**
+ * struct v4l2_ctrl_vp9_compressed_hdr_probs - VP9 probability updates control
+ * @tx8: TX 8x8 probability updates
+ * @tx16: TX 16x16 probability updates
+ * @tx32: TX 32x32 probability updates
+ * @coef: coefficient probability updates
+ * @skip: skip probability updates
+ * @inter_mode: inter mode probability updates
+ * @interp_filter: interpolation filter probability updates
+ * @is_inter: is inter-block probability updates
+ * @comp_mode: compound prediction mode probability updates
+ * @single_ref: single ref probability updates
+ * @comp_ref: compound ref probability updates
+ * @y_mode: Y prediction mode probability updates
+ * @uv_mode: UV prediction mode probability updates
+ * @partition: partition probability updates
+ * @mv: motion vector probability updates
+ *
+ * This structure holds the probabilities update as parsed in the compressed
+ * header (Spec 6.3). These values represent the value of probability update after
+ * being translated with inv_map_table[] (see 6.3.5). A value of zero in an array element
+ * means that there is no update of the relevant probability.
+ */
+struct v4l2_ctrl_vp9_compressed_hdr_probs {
+	__u8 tx8[2][1];
+	__u8 tx16[2][2];
+	__u8 tx32[2][3];
+	__u8 coef[4][2][2][6][6][3];
+	__u8 skip[3];
+	__u8 inter_mode[7][3];
+	__u8 interp_filter[4][2];
+	__u8 is_inter[4];
+	__u8 comp_mode[5];
+	__u8 single_ref[5][2];
+	__u8 comp_ref[5];
+	__u8 y_mode[4][9];
+	__u8 uv_mode[10][9];
+	__u8 partition[16][3];
+
+	struct v4l2_vp9_mv_compressed_hdr_probs mv;
+};
+
 /* MPEG-compression definitions kept for backwards compatibility */
 #ifndef __KERNEL__
 #define V4L2_CTRL_CLASS_MPEG            V4L2_CTRL_CLASS_CODEC
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 58392dcd3bf5..4abe4362519e 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -703,6 +703,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_VP8      v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
 #define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') /* VP8 parsed frame */
 #define V4L2_PIX_FMT_VP9      v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
+#define V4L2_PIX_FMT_VP9_FRAME v4l2_fourcc('V', 'P', '9', 'F') /* VP9 parsed frame */
 #define V4L2_PIX_FMT_HEVC     v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */
 #define V4L2_PIX_FMT_FWHT     v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */
 #define V4L2_PIX_FMT_FWHT_STATELESS     v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */
@@ -1755,6 +1756,8 @@ struct v4l2_ext_control {
 		struct v4l2_ctrl_mpeg2_sequence __user *p_mpeg2_sequence;
 		struct v4l2_ctrl_mpeg2_picture __user *p_mpeg2_picture;
 		struct v4l2_ctrl_mpeg2_quantisation __user *p_mpeg2_quantisation;
+		struct v4l2_ctrl_vp9_compressed_hdr_probs __user *p_vp9_compressed_hdr_probs;
+		struct v4l2_ctrl_vp9_frame __user *p_vp9_frame;
 		void __user *ptr;
 	};
 } __attribute__ ((packed));
@@ -1819,6 +1822,9 @@ enum v4l2_ctrl_type {
 	V4L2_CTRL_TYPE_MPEG2_QUANTISATION   = 0x0250,
 	V4L2_CTRL_TYPE_MPEG2_SEQUENCE       = 0x0251,
 	V4L2_CTRL_TYPE_MPEG2_PICTURE        = 0x0252,
+
+	V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS	= 0x0260,
+	V4L2_CTRL_TYPE_VP9_FRAME		= 0x0261,
 };
 
 /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:42 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:42 +0200
Subject: [PATCH v3 06/10] media: Add VP9 v4l2 library
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-7-andrzej.p@collabora.com>

Provide code common to vp9 drivers in one central location.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
---
 drivers/media/v4l2-core/Kconfig    |    4 +
 drivers/media/v4l2-core/Makefile   |    1 +
 drivers/media/v4l2-core/v4l2-vp9.c | 1850 ++++++++++++++++++++++++++++
 include/media/v4l2-vp9.h           |  182 +++
 4 files changed, 2037 insertions(+)
 create mode 100644 drivers/media/v4l2-core/v4l2-vp9.c
 create mode 100644 include/media/v4l2-vp9.h

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 02dc1787e953..6ee75c6c820e 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -52,6 +52,10 @@ config V4L2_JPEG_HELPER
 config V4L2_H264
 	tristate
 
+# Used by drivers that need v4l2-vp9.ko
+config V4L2_VP9
+	tristate
+
 # Used by drivers that need v4l2-mem2mem.ko
 config V4L2_MEM2MEM_DEV
 	tristate
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 66a78c556c98..83fac5c746f5 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_VIDEO_TUNER) += tuner.o
 
 obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
 obj-$(CONFIG_V4L2_H264) += v4l2-h264.o
+obj-$(CONFIG_V4L2_VP9) += v4l2-vp9.o
 
 obj-$(CONFIG_V4L2_FLASH_LED_CLASS) += v4l2-flash-led-class.o
 
diff --git a/drivers/media/v4l2-core/v4l2-vp9.c b/drivers/media/v4l2-core/v4l2-vp9.c
new file mode 100644
index 000000000000..3fbb8649dd9b
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-vp9.c
@@ -0,0 +1,1850 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * V4L2 VP9 helpers.
+ *
+ * Copyright (C) 2021 Collabora, Ltd.
+ *
+ * Author: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
+ */
+
+#include <linux/module.h>
+
+#include <media/v4l2-vp9.h>
+
+const u8 v4l2_vp9_kf_y_mode_prob[10][10][9] = {
+	{
+		/* above = dc */
+		{ 137,  30,  42, 148, 151, 207,  70,  52,  91 }, /*left = dc  */
+		{  92,  45, 102, 136, 116, 180,  74,  90, 100 }, /*left = v   */
+		{  73,  32,  19, 187, 222, 215,  46,  34, 100 }, /*left = h   */
+		{  91,  30,  32, 116, 121, 186,  93,  86,  94 }, /*left = d45 */
+		{  72,  35,  36, 149,  68, 206,  68,  63, 105 }, /*left = d135*/
+		{  73,  31,  28, 138,  57, 124,  55, 122, 151 }, /*left = d117*/
+		{  67,  23,  21, 140, 126, 197,  40,  37, 171 }, /*left = d153*/
+		{  86,  27,  28, 128, 154, 212,  45,  43,  53 }, /*left = d207*/
+		{  74,  32,  27, 107,  86, 160,  63, 134, 102 }, /*left = d63 */
+		{  59,  67,  44, 140, 161, 202,  78,  67, 119 }, /*left = tm  */
+	}, {  /* above = v */
+		{  63,  36, 126, 146, 123, 158,  60,  90,  96 }, /*left = dc  */
+		{  43,  46, 168, 134, 107, 128,  69, 142,  92 }, /*left = v   */
+		{  44,  29,  68, 159, 201, 177,  50,  57,  77 }, /*left = h   */
+		{  58,  38,  76, 114,  97, 172,  78, 133,  92 }, /*left = d45 */
+		{  46,  41,  76, 140,  63, 184,  69, 112,  57 }, /*left = d135*/
+		{  38,  32,  85, 140,  46, 112,  54, 151, 133 }, /*left = d117*/
+		{  39,  27,  61, 131, 110, 175,  44,  75, 136 }, /*left = d153*/
+		{  52,  30,  74, 113, 130, 175,  51,  64,  58 }, /*left = d207*/
+		{  47,  35,  80, 100,  74, 143,  64, 163,  74 }, /*left = d63 */
+		{  36,  61, 116, 114, 128, 162,  80, 125,  82 }, /*left = tm  */
+	}, {  /* above = h */
+		{  82,  26,  26, 171, 208, 204,  44,  32, 105 }, /*left = dc  */
+		{  55,  44,  68, 166, 179, 192,  57,  57, 108 }, /*left = v   */
+		{  42,  26,  11, 199, 241, 228,  23,  15,  85 }, /*left = h   */
+		{  68,  42,  19, 131, 160, 199,  55,  52,  83 }, /*left = d45 */
+		{  58,  50,  25, 139, 115, 232,  39,  52, 118 }, /*left = d135*/
+		{  50,  35,  33, 153, 104, 162,  64,  59, 131 }, /*left = d117*/
+		{  44,  24,  16, 150, 177, 202,  33,  19, 156 }, /*left = d153*/
+		{  55,  27,  12, 153, 203, 218,  26,  27,  49 }, /*left = d207*/
+		{  53,  49,  21, 110, 116, 168,  59,  80,  76 }, /*left = d63 */
+		{  38,  72,  19, 168, 203, 212,  50,  50, 107 }, /*left = tm  */
+	}, {  /* above = d45 */
+		{ 103,  26,  36, 129, 132, 201,  83,  80,  93 }, /*left = dc  */
+		{  59,  38,  83, 112, 103, 162,  98, 136,  90 }, /*left = v   */
+		{  62,  30,  23, 158, 200, 207,  59,  57,  50 }, /*left = h   */
+		{  67,  30,  29,  84,  86, 191, 102,  91,  59 }, /*left = d45 */
+		{  60,  32,  33, 112,  71, 220,  64,  89, 104 }, /*left = d135*/
+		{  53,  26,  34, 130,  56, 149,  84, 120, 103 }, /*left = d117*/
+		{  53,  21,  23, 133, 109, 210,  56,  77, 172 }, /*left = d153*/
+		{  77,  19,  29, 112, 142, 228,  55,  66,  36 }, /*left = d207*/
+		{  61,  29,  29,  93,  97, 165,  83, 175, 162 }, /*left = d63 */
+		{  47,  47,  43, 114, 137, 181, 100,  99,  95 }, /*left = tm  */
+	}, {  /* above = d135 */
+		{  69,  23,  29, 128,  83, 199,  46,  44, 101 }, /*left = dc  */
+		{  53,  40,  55, 139,  69, 183,  61,  80, 110 }, /*left = v   */
+		{  40,  29,  19, 161, 180, 207,  43,  24,  91 }, /*left = h   */
+		{  60,  34,  19, 105,  61, 198,  53,  64,  89 }, /*left = d45 */
+		{  52,  31,  22, 158,  40, 209,  58,  62,  89 }, /*left = d135*/
+		{  44,  31,  29, 147,  46, 158,  56, 102, 198 }, /*left = d117*/
+		{  35,  19,  12, 135,  87, 209,  41,  45, 167 }, /*left = d153*/
+		{  55,  25,  21, 118,  95, 215,  38,  39,  66 }, /*left = d207*/
+		{  51,  38,  25, 113,  58, 164,  70,  93,  97 }, /*left = d63 */
+		{  47,  54,  34, 146, 108, 203,  72, 103, 151 }, /*left = tm  */
+	}, {  /* above = d117 */
+		{  64,  19,  37, 156,  66, 138,  49,  95, 133 }, /*left = dc  */
+		{  46,  27,  80, 150,  55, 124,  55, 121, 135 }, /*left = v   */
+		{  36,  23,  27, 165, 149, 166,  54,  64, 118 }, /*left = h   */
+		{  53,  21,  36, 131,  63, 163,  60, 109,  81 }, /*left = d45 */
+		{  40,  26,  35, 154,  40, 185,  51,  97, 123 }, /*left = d135*/
+		{  35,  19,  34, 179,  19,  97,  48, 129, 124 }, /*left = d117*/
+		{  36,  20,  26, 136,  62, 164,  33,  77, 154 }, /*left = d153*/
+		{  45,  18,  32, 130,  90, 157,  40,  79,  91 }, /*left = d207*/
+		{  45,  26,  28, 129,  45, 129,  49, 147, 123 }, /*left = d63 */
+		{  38,  44,  51, 136,  74, 162,  57,  97, 121 }, /*left = tm  */
+	}, {  /* above = d153 */
+		{  75,  17,  22, 136, 138, 185,  32,  34, 166 }, /*left = dc  */
+		{  56,  39,  58, 133, 117, 173,  48,  53, 187 }, /*left = v   */
+		{  35,  21,  12, 161, 212, 207,  20,  23, 145 }, /*left = h   */
+		{  56,  29,  19, 117, 109, 181,  55,  68, 112 }, /*left = d45 */
+		{  47,  29,  17, 153,  64, 220,  59,  51, 114 }, /*left = d135*/
+		{  46,  16,  24, 136,  76, 147,  41,  64, 172 }, /*left = d117*/
+		{  34,  17,  11, 108, 152, 187,  13,  15, 209 }, /*left = d153*/
+		{  51,  24,  14, 115, 133, 209,  32,  26, 104 }, /*left = d207*/
+		{  55,  30,  18, 122,  79, 179,  44,  88, 116 }, /*left = d63 */
+		{  37,  49,  25, 129, 168, 164,  41,  54, 148 }, /*left = tm  */
+	}, {  /* above = d207 */
+		{  82,  22,  32, 127, 143, 213,  39,  41,  70 }, /*left = dc  */
+		{  62,  44,  61, 123, 105, 189,  48,  57,  64 }, /*left = v   */
+		{  47,  25,  17, 175, 222, 220,  24,  30,  86 }, /*left = h   */
+		{  68,  36,  17, 106, 102, 206,  59,  74,  74 }, /*left = d45 */
+		{  57,  39,  23, 151,  68, 216,  55,  63,  58 }, /*left = d135*/
+		{  49,  30,  35, 141,  70, 168,  82,  40, 115 }, /*left = d117*/
+		{  51,  25,  15, 136, 129, 202,  38,  35, 139 }, /*left = d153*/
+		{  68,  26,  16, 111, 141, 215,  29,  28,  28 }, /*left = d207*/
+		{  59,  39,  19, 114,  75, 180,  77, 104,  42 }, /*left = d63 */
+		{  40,  61,  26, 126, 152, 206,  61,  59,  93 }, /*left = tm  */
+	}, {  /* above = d63 */
+		{  78,  23,  39, 111, 117, 170,  74, 124,  94 }, /*left = dc  */
+		{  48,  34,  86, 101,  92, 146,  78, 179, 134 }, /*left = v   */
+		{  47,  22,  24, 138, 187, 178,  68,  69,  59 }, /*left = h   */
+		{  56,  25,  33, 105, 112, 187,  95, 177, 129 }, /*left = d45 */
+		{  48,  31,  27, 114,  63, 183,  82, 116,  56 }, /*left = d135*/
+		{  43,  28,  37, 121,  63, 123,  61, 192, 169 }, /*left = d117*/
+		{  42,  17,  24, 109,  97, 177,  56,  76, 122 }, /*left = d153*/
+		{  58,  18,  28, 105, 139, 182,  70,  92,  63 }, /*left = d207*/
+		{  46,  23,  32,  74,  86, 150,  67, 183,  88 }, /*left = d63 */
+		{  36,  38,  48,  92, 122, 165,  88, 137,  91 }, /*left = tm  */
+	}, {  /* above = tm */
+		{  65,  70,  60, 155, 159, 199,  61,  60,  81 }, /*left = dc  */
+		{  44,  78, 115, 132, 119, 173,  71, 112,  93 }, /*left = v   */
+		{  39,  38,  21, 184, 227, 206,  42,  32,  64 }, /*left = h   */
+		{  58,  47,  36, 124, 137, 193,  80,  82,  78 }, /*left = d45 */
+		{  49,  50,  35, 144,  95, 205,  63,  78,  59 }, /*left = d135*/
+		{  41,  53,  52, 148,  71, 142,  65, 128,  51 }, /*left = d117*/
+		{  40,  36,  28, 143, 143, 202,  40,  55, 137 }, /*left = d153*/
+		{  52,  34,  29, 129, 183, 227,  42,  35,  43 }, /*left = d207*/
+		{  42,  44,  44, 104, 105, 164,  64, 130,  80 }, /*left = d63 */
+		{  43,  81,  53, 140, 169, 204,  68,  84,  72 }, /*left = tm  */
+	}
+};
+EXPORT_SYMBOL_GPL(v4l2_vp9_kf_y_mode_prob);
+
+const u8 v4l2_vp9_kf_partition_probs[16][3] = {
+	/* 8x8 -> 4x4 */
+	{ 158,  97,  94 },	/* a/l both not split   */
+	{  93,  24,  99 },	/* a split, l not split */
+	{  85, 119,  44 },	/* l split, a not split */
+	{  62,  59,  67 },	/* a/l both split       */
+	/* 16x16 -> 8x8 */
+	{ 149,  53,  53 },	/* a/l both not split   */
+	{  94,  20,  48 },	/* a split, l not split */
+	{  83,  53,  24 },	/* l split, a not split */
+	{  52,  18,  18 },	/* a/l both split       */
+	/* 32x32 -> 16x16 */
+	{ 150,  40,  39 },	/* a/l both not split   */
+	{  78,  12,  26 },	/* a split, l not split */
+	{  67,  33,  11 },	/* l split, a not split */
+	{  24,   7,   5 },	/* a/l both split       */
+	/* 64x64 -> 32x32 */
+	{ 174,  35,  49 },	/* a/l both not split   */
+	{  68,  11,  27 },	/* a split, l not split */
+	{  57,  15,   9 },	/* l split, a not split */
+	{  12,   3,   3 },	/* a/l both split       */
+};
+EXPORT_SYMBOL_GPL(v4l2_vp9_kf_partition_probs);
+
+const u8 v4l2_vp9_kf_uv_mode_prob[10][9] = {
+	{ 144,  11,  54, 157, 195, 130,  46,  58, 108 },  /* y = dc   */
+	{ 118,  15, 123, 148, 131, 101,  44,  93, 131 },  /* y = v    */
+	{ 113,  12,  23, 188, 226, 142,  26,  32, 125 },  /* y = h    */
+	{ 120,  11,  50, 123, 163, 135,  64,  77, 103 },  /* y = d45  */
+	{ 113,   9,  36, 155, 111, 157,  32,  44, 161 },  /* y = d135 */
+	{ 116,   9,  55, 176,  76,  96,  37,  61, 149 },  /* y = d117 */
+	{ 115,   9,  28, 141, 161, 167,  21,  25, 193 },  /* y = d153 */
+	{ 120,  12,  32, 145, 195, 142,  32,  38,  86 },  /* y = d207 */
+	{ 116,  12,  64, 120, 140, 125,  49, 115, 121 },  /* y = d63  */
+	{ 102,  19,  66, 162, 182, 122,  35,  59, 128 }   /* y = tm   */
+};
+EXPORT_SYMBOL_GPL(v4l2_vp9_kf_uv_mode_prob);
+
+const struct v4l2_vp9_frame_context v4l2_vp9_default_probs = {
+	.tx8 = {
+		{ 100 },
+		{  66 },
+	},
+	.tx16 = {
+		{ 20, 152 },
+		{ 15, 101 },
+	},
+	.tx32 = {
+		{ 3, 136, 37 },
+		{ 5,  52, 13 },
+	},
+	.coef = {
+		{ /* tx = 4x4 */
+			{ /* block Type 0 */
+				{ /* Intra */
+					{ /* Coeff Band 0 */
+						{ 195,  29, 183 },
+						{  84,  49, 136 },
+						{   8,  42,  71 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  31, 107, 169 },
+						{  35,  99, 159 },
+						{  17,  82, 140 },
+						{   8,  66, 114 },
+						{   2,  44,  76 },
+						{   1,  19,  32 },
+					},
+					{ /* Coeff Band 2 */
+						{  40, 132, 201 },
+						{  29, 114, 187 },
+						{  13,  91, 157 },
+						{   7,  75, 127 },
+						{   3,  58,  95 },
+						{   1,  28,  47 },
+					},
+					{ /* Coeff Band 3 */
+						{  69, 142, 221 },
+						{  42, 122, 201 },
+						{  15,  91, 159 },
+						{   6,  67, 121 },
+						{   1,  42,  77 },
+						{   1,  17,  31 },
+					},
+					{ /* Coeff Band 4 */
+						{ 102, 148, 228 },
+						{  67, 117, 204 },
+						{  17,  82, 154 },
+						{   6,  59, 114 },
+						{   2,  39,  75 },
+						{   1,  15,  29 },
+					},
+					{ /* Coeff Band 5 */
+						{ 156,  57, 233 },
+						{ 119,  57, 212 },
+						{  58,  48, 163 },
+						{  29,  40, 124 },
+						{  12,  30,  81 },
+						{   3,  12,  31 }
+					},
+				},
+				{ /* Inter */
+					{ /* Coeff Band 0 */
+						{ 191, 107, 226 },
+						{ 124, 117, 204 },
+						{  25,  99, 155 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  29, 148, 210 },
+						{  37, 126, 194 },
+						{   8,  93, 157 },
+						{   2,  68, 118 },
+						{   1,  39,  69 },
+						{   1,  17,  33 },
+					},
+					{ /* Coeff Band 2 */
+						{  41, 151, 213 },
+						{  27, 123, 193 },
+						{   3,  82, 144 },
+						{   1,  58, 105 },
+						{   1,  32,  60 },
+						{   1,  13,  26 },
+					},
+					{ /* Coeff Band 3 */
+						{  59, 159, 220 },
+						{  23, 126, 198 },
+						{   4,  88, 151 },
+						{   1,  66, 114 },
+						{   1,  38,  71 },
+						{   1,  18,  34 },
+					},
+					{ /* Coeff Band 4 */
+						{ 114, 136, 232 },
+						{  51, 114, 207 },
+						{  11,  83, 155 },
+						{   3,  56, 105 },
+						{   1,  33,  65 },
+						{   1,  17,  34 },
+					},
+					{ /* Coeff Band 5 */
+						{ 149,  65, 234 },
+						{ 121,  57, 215 },
+						{  61,  49, 166 },
+						{  28,  36, 114 },
+						{  12,  25,  76 },
+						{   3,  16,  42 },
+					},
+				},
+			},
+			{ /* block Type 1 */
+				{ /* Intra */
+					{ /* Coeff Band 0 */
+						{ 214,  49, 220 },
+						{ 132,  63, 188 },
+						{  42,  65, 137 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  85, 137, 221 },
+						{ 104, 131, 216 },
+						{  49, 111, 192 },
+						{  21,  87, 155 },
+						{   2,  49,  87 },
+						{   1,  16,  28 },
+					},
+					{ /* Coeff Band 2 */
+						{  89, 163, 230 },
+						{  90, 137, 220 },
+						{  29, 100, 183 },
+						{  10,  70, 135 },
+						{   2,  42,  81 },
+						{   1,  17,  33 },
+					},
+					{ /* Coeff Band 3 */
+						{ 108, 167, 237 },
+						{  55, 133, 222 },
+						{  15,  97, 179 },
+						{   4,  72, 135 },
+						{   1,  45,  85 },
+						{   1,  19,  38 },
+					},
+					{ /* Coeff Band 4 */
+						{ 124, 146, 240 },
+						{  66, 124, 224 },
+						{  17,  88, 175 },
+						{   4,  58, 122 },
+						{   1,  36,  75 },
+						{   1,  18,  37 },
+					},
+					{ /* Coeff Band 5 */
+						{ 141,  79, 241 },
+						{ 126,  70, 227 },
+						{  66,  58, 182 },
+						{  30,  44, 136 },
+						{  12,  34,  96 },
+						{   2,  20,  47 },
+					},
+				},
+				{ /* Inter */
+					{ /* Coeff Band 0 */
+						{ 229,  99, 249 },
+						{ 143, 111, 235 },
+						{  46, 109, 192 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  82, 158, 236 },
+						{  94, 146, 224 },
+						{  25, 117, 191 },
+						{   9,  87, 149 },
+						{   3,  56,  99 },
+						{   1,  33,  57 },
+					},
+					{ /* Coeff Band 2 */
+						{  83, 167, 237 },
+						{  68, 145, 222 },
+						{  10, 103, 177 },
+						{   2,  72, 131 },
+						{   1,  41,  79 },
+						{   1,  20,  39 },
+					},
+					{ /* Coeff Band 3 */
+						{  99, 167, 239 },
+						{  47, 141, 224 },
+						{  10, 104, 178 },
+						{   2,  73, 133 },
+						{   1,  44,  85 },
+						{   1,  22,  47 },
+					},
+					{ /* Coeff Band 4 */
+						{ 127, 145, 243 },
+						{  71, 129, 228 },
+						{  17,  93, 177 },
+						{   3,  61, 124 },
+						{   1,  41,  84 },
+						{   1,  21,  52 },
+					},
+					{ /* Coeff Band 5 */
+						{ 157,  78, 244 },
+						{ 140,  72, 231 },
+						{  69,  58, 184 },
+						{  31,  44, 137 },
+						{  14,  38, 105 },
+						{   8,  23,  61 },
+					},
+				},
+			},
+		},
+		{ /* tx = 8x8 */
+			{ /* block Type 0 */
+				{ /* Intra */
+					{ /* Coeff Band 0 */
+						{ 125,  34, 187 },
+						{  52,  41, 133 },
+						{   6,  31,  56 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  37, 109, 153 },
+						{  51, 102, 147 },
+						{  23,  87, 128 },
+						{   8,  67, 101 },
+						{   1,  41,  63 },
+						{   1,  19,  29 },
+					},
+					{ /* Coeff Band 2 */
+						{  31, 154, 185 },
+						{  17, 127, 175 },
+						{   6,  96, 145 },
+						{   2,  73, 114 },
+						{   1,  51,  82 },
+						{   1,  28,  45 },
+					},
+					{ /* Coeff Band 3 */
+						{  23, 163, 200 },
+						{  10, 131, 185 },
+						{   2,  93, 148 },
+						{   1,  67, 111 },
+						{   1,  41,  69 },
+						{   1,  14,  24 },
+					},
+					{ /* Coeff Band 4 */
+						{  29, 176, 217 },
+						{  12, 145, 201 },
+						{   3, 101, 156 },
+						{   1,  69, 111 },
+						{   1,  39,  63 },
+						{   1,  14,  23 },
+					},
+					{ /* Coeff Band 5 */
+						{  57, 192, 233 },
+						{  25, 154, 215 },
+						{   6, 109, 167 },
+						{   3,  78, 118 },
+						{   1,  48,  69 },
+						{   1,  21,  29 },
+					},
+				},
+				{ /* Inter */
+					{ /* Coeff Band 0 */
+						{ 202, 105, 245 },
+						{ 108, 106, 216 },
+						{  18,  90, 144 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  33, 172, 219 },
+						{  64, 149, 206 },
+						{  14, 117, 177 },
+						{   5,  90, 141 },
+						{   2,  61,  95 },
+						{   1,  37,  57 },
+					},
+					{ /* Coeff Band 2 */
+						{  33, 179, 220 },
+						{  11, 140, 198 },
+						{   1,  89, 148 },
+						{   1,  60, 104 },
+						{   1,  33,  57 },
+						{   1,  12,  21 },
+					},
+					{ /* Coeff Band 3 */
+						{  30, 181, 221 },
+						{   8, 141, 198 },
+						{   1,  87, 145 },
+						{   1,  58, 100 },
+						{   1,  31,  55 },
+						{   1,  12,  20 },
+					},
+					{ /* Coeff Band 4 */
+						{  32, 186, 224 },
+						{   7, 142, 198 },
+						{   1,  86, 143 },
+						{   1,  58, 100 },
+						{   1,  31,  55 },
+						{   1,  12,  22 },
+					},
+					{ /* Coeff Band 5 */
+						{  57, 192, 227 },
+						{  20, 143, 204 },
+						{   3,  96, 154 },
+						{   1,  68, 112 },
+						{   1,  42,  69 },
+						{   1,  19,  32 },
+					},
+				},
+			},
+			{ /* block Type 1 */
+				{ /* Intra */
+					{ /* Coeff Band 0 */
+						{ 212,  35, 215 },
+						{ 113,  47, 169 },
+						{  29,  48, 105 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  74, 129, 203 },
+						{ 106, 120, 203 },
+						{  49, 107, 178 },
+						{  19,  84, 144 },
+						{   4,  50,  84 },
+						{   1,  15,  25 },
+					},
+					{ /* Coeff Band 2 */
+						{  71, 172, 217 },
+						{  44, 141, 209 },
+						{  15, 102, 173 },
+						{   6,  76, 133 },
+						{   2,  51,  89 },
+						{   1,  24,  42 },
+					},
+					{ /* Coeff Band 3 */
+						{  64, 185, 231 },
+						{  31, 148, 216 },
+						{   8, 103, 175 },
+						{   3,  74, 131 },
+						{   1,  46,  81 },
+						{   1,  18,  30 },
+					},
+					{ /* Coeff Band 4 */
+						{  65, 196, 235 },
+						{  25, 157, 221 },
+						{   5, 105, 174 },
+						{   1,  67, 120 },
+						{   1,  38,  69 },
+						{   1,  15,  30 },
+					},
+					{ /* Coeff Band 5 */
+						{  65, 204, 238 },
+						{  30, 156, 224 },
+						{   7, 107, 177 },
+						{   2,  70, 124 },
+						{   1,  42,  73 },
+						{   1,  18,  34 },
+					},
+				},
+				{ /* Inter */
+					{ /* Coeff Band 0 */
+						{ 225,  86, 251 },
+						{ 144, 104, 235 },
+						{  42,  99, 181 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  85, 175, 239 },
+						{ 112, 165, 229 },
+						{  29, 136, 200 },
+						{  12, 103, 162 },
+						{   6,  77, 123 },
+						{   2,  53,  84 },
+					},
+					{ /* Coeff Band 2 */
+						{  75, 183, 239 },
+						{  30, 155, 221 },
+						{   3, 106, 171 },
+						{   1,  74, 128 },
+						{   1,  44,  76 },
+						{   1,  17,  28 },
+					},
+					{ /* Coeff Band 3 */
+						{  73, 185, 240 },
+						{  27, 159, 222 },
+						{   2, 107, 172 },
+						{   1,  75, 127 },
+						{   1,  42,  73 },
+						{   1,  17,  29 },
+					},
+					{ /* Coeff Band 4 */
+						{  62, 190, 238 },
+						{  21, 159, 222 },
+						{   2, 107, 172 },
+						{   1,  72, 122 },
+						{   1,  40,  71 },
+						{   1,  18,  32 },
+					},
+					{ /* Coeff Band 5 */
+						{  61, 199, 240 },
+						{  27, 161, 226 },
+						{   4, 113, 180 },
+						{   1,  76, 129 },
+						{   1,  46,  80 },
+						{   1,  23,  41 },
+					},
+				},
+			},
+		},
+		{ /* tx = 16x16 */
+			{ /* block Type 0 */
+				{ /* Intra */
+					{ /* Coeff Band 0 */
+						{   7,  27, 153 },
+						{   5,  30,  95 },
+						{   1,  16,  30 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  50,  75, 127 },
+						{  57,  75, 124 },
+						{  27,  67, 108 },
+						{  10,  54,  86 },
+						{   1,  33,  52 },
+						{   1,  12,  18 },
+					},
+					{ /* Coeff Band 2 */
+						{  43, 125, 151 },
+						{  26, 108, 148 },
+						{   7,  83, 122 },
+						{   2,  59,  89 },
+						{   1,  38,  60 },
+						{   1,  17,  27 },
+					},
+					{ /* Coeff Band 3 */
+						{  23, 144, 163 },
+						{  13, 112, 154 },
+						{   2,  75, 117 },
+						{   1,  50,  81 },
+						{   1,  31,  51 },
+						{   1,  14,  23 },
+					},
+					{ /* Coeff Band 4 */
+						{  18, 162, 185 },
+						{   6, 123, 171 },
+						{   1,  78, 125 },
+						{   1,  51,  86 },
+						{   1,  31,  54 },
+						{   1,  14,  23 },
+					},
+					{ /* Coeff Band 5 */
+						{  15, 199, 227 },
+						{   3, 150, 204 },
+						{   1,  91, 146 },
+						{   1,  55,  95 },
+						{   1,  30,  53 },
+						{   1,  11,  20 },
+					}
+				},
+				{ /* Inter */
+					{ /* Coeff Band 0 */
+						{  19,  55, 240 },
+						{  19,  59, 196 },
+						{   3,  52, 105 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  41, 166, 207 },
+						{ 104, 153, 199 },
+						{  31, 123, 181 },
+						{  14, 101, 152 },
+						{   5,  72, 106 },
+						{   1,  36,  52 },
+					},
+					{ /* Coeff Band 2 */
+						{  35, 176, 211 },
+						{  12, 131, 190 },
+						{   2,  88, 144 },
+						{   1,  60, 101 },
+						{   1,  36,  60 },
+						{   1,  16,  28 },
+					},
+					{ /* Coeff Band 3 */
+						{  28, 183, 213 },
+						{   8, 134, 191 },
+						{   1,  86, 142 },
+						{   1,  56,  96 },
+						{   1,  30,  53 },
+						{   1,  12,  20 },
+					},
+					{ /* Coeff Band 4 */
+						{  20, 190, 215 },
+						{   4, 135, 192 },
+						{   1,  84, 139 },
+						{   1,  53,  91 },
+						{   1,  28,  49 },
+						{   1,  11,  20 },
+					},
+					{ /* Coeff Band 5 */
+						{  13, 196, 216 },
+						{   2, 137, 192 },
+						{   1,  86, 143 },
+						{   1,  57,  99 },
+						{   1,  32,  56 },
+						{   1,  13,  24 },
+					},
+				},
+			},
+			{ /* block Type 1 */
+				{ /* Intra */
+					{ /* Coeff Band 0 */
+						{ 211,  29, 217 },
+						{  96,  47, 156 },
+						{  22,  43,  87 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  78, 120, 193 },
+						{ 111, 116, 186 },
+						{  46, 102, 164 },
+						{  15,  80, 128 },
+						{   2,  49,  76 },
+						{   1,  18,  28 },
+					},
+					{ /* Coeff Band 2 */
+						{  71, 161, 203 },
+						{  42, 132, 192 },
+						{  10,  98, 150 },
+						{   3,  69, 109 },
+						{   1,  44,  70 },
+						{   1,  18,  29 },
+					},
+					{ /* Coeff Band 3 */
+						{  57, 186, 211 },
+						{  30, 140, 196 },
+						{   4,  93, 146 },
+						{   1,  62, 102 },
+						{   1,  38,  65 },
+						{   1,  16,  27 },
+					},
+					{ /* Coeff Band 4 */
+						{  47, 199, 217 },
+						{  14, 145, 196 },
+						{   1,  88, 142 },
+						{   1,  57,  98 },
+						{   1,  36,  62 },
+						{   1,  15,  26 },
+					},
+					{ /* Coeff Band 5 */
+						{  26, 219, 229 },
+						{   5, 155, 207 },
+						{   1,  94, 151 },
+						{   1,  60, 104 },
+						{   1,  36,  62 },
+						{   1,  16,  28 },
+					}
+				},
+				{ /* Inter */
+					{ /* Coeff Band 0 */
+						{ 233,  29, 248 },
+						{ 146,  47, 220 },
+						{  43,  52, 140 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{ 100, 163, 232 },
+						{ 179, 161, 222 },
+						{  63, 142, 204 },
+						{  37, 113, 174 },
+						{  26,  89, 137 },
+						{  18,  68,  97 },
+					},
+					{ /* Coeff Band 2 */
+						{  85, 181, 230 },
+						{  32, 146, 209 },
+						{   7, 100, 164 },
+						{   3,  71, 121 },
+						{   1,  45,  77 },
+						{   1,  18,  30 },
+					},
+					{ /* Coeff Band 3 */
+						{  65, 187, 230 },
+						{  20, 148, 207 },
+						{   2,  97, 159 },
+						{   1,  68, 116 },
+						{   1,  40,  70 },
+						{   1,  14,  29 },
+					},
+					{ /* Coeff Band 4 */
+						{  40, 194, 227 },
+						{   8, 147, 204 },
+						{   1,  94, 155 },
+						{   1,  65, 112 },
+						{   1,  39,  66 },
+						{   1,  14,  26 },
+					},
+					{ /* Coeff Band 5 */
+						{  16, 208, 228 },
+						{   3, 151, 207 },
+						{   1,  98, 160 },
+						{   1,  67, 117 },
+						{   1,  41,  74 },
+						{   1,  17,  31 },
+					},
+				},
+			},
+		},
+		{ /* tx = 32x32 */
+			{ /* block Type 0 */
+				{ /* Intra */
+					{ /* Coeff Band 0 */
+						{  17,  38, 140 },
+						{   7,  34,  80 },
+						{   1,  17,  29 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  37,  75, 128 },
+						{  41,  76, 128 },
+						{  26,  66, 116 },
+						{  12,  52,  94 },
+						{   2,  32,  55 },
+						{   1,  10,  16 },
+					},
+					{ /* Coeff Band 2 */
+						{  50, 127, 154 },
+						{  37, 109, 152 },
+						{  16,  82, 121 },
+						{   5,  59,  85 },
+						{   1,  35,  54 },
+						{   1,  13,  20 },
+					},
+					{ /* Coeff Band 3 */
+						{  40, 142, 167 },
+						{  17, 110, 157 },
+						{   2,  71, 112 },
+						{   1,  44,  72 },
+						{   1,  27,  45 },
+						{   1,  11,  17 },
+					},
+					{ /* Coeff Band 4 */
+						{  30, 175, 188 },
+						{   9, 124, 169 },
+						{   1,  74, 116 },
+						{   1,  48,  78 },
+						{   1,  30,  49 },
+						{   1,  11,  18 },
+					},
+					{ /* Coeff Band 5 */
+						{  10, 222, 223 },
+						{   2, 150, 194 },
+						{   1,  83, 128 },
+						{   1,  48,  79 },
+						{   1,  27,  45 },
+						{   1,  11,  17 },
+					},
+				},
+				{ /* Inter */
+					{ /* Coeff Band 0 */
+						{  36,  41, 235 },
+						{  29,  36, 193 },
+						{  10,  27, 111 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  85, 165, 222 },
+						{ 177, 162, 215 },
+						{ 110, 135, 195 },
+						{  57, 113, 168 },
+						{  23,  83, 120 },
+						{  10,  49,  61 },
+					},
+					{ /* Coeff Band 2 */
+						{  85, 190, 223 },
+						{  36, 139, 200 },
+						{   5,  90, 146 },
+						{   1,  60, 103 },
+						{   1,  38,  65 },
+						{   1,  18,  30 },
+					},
+					{ /* Coeff Band 3 */
+						{  72, 202, 223 },
+						{  23, 141, 199 },
+						{   2,  86, 140 },
+						{   1,  56,  97 },
+						{   1,  36,  61 },
+						{   1,  16,  27 },
+					},
+					{ /* Coeff Band 4 */
+						{  55, 218, 225 },
+						{  13, 145, 200 },
+						{   1,  86, 141 },
+						{   1,  57,  99 },
+						{   1,  35,  61 },
+						{   1,  13,  22 },
+					},
+					{ /* Coeff Band 5 */
+						{  15, 235, 212 },
+						{   1, 132, 184 },
+						{   1,  84, 139 },
+						{   1,  57,  97 },
+						{   1,  34,  56 },
+						{   1,  14,  23 },
+					},
+				},
+			},
+			{ /* block Type 1 */
+				{ /* Intra */
+					{ /* Coeff Band 0 */
+						{ 181,  21, 201 },
+						{  61,  37, 123 },
+						{  10,  38,  71 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{  47, 106, 172 },
+						{  95, 104, 173 },
+						{  42,  93, 159 },
+						{  18,  77, 131 },
+						{   4,  50,  81 },
+						{   1,  17,  23 },
+					},
+					{ /* Coeff Band 2 */
+						{  62, 147, 199 },
+						{  44, 130, 189 },
+						{  28, 102, 154 },
+						{  18,  75, 115 },
+						{   2,  44,  65 },
+						{   1,  12,  19 },
+					},
+					{ /* Coeff Band 3 */
+						{  55, 153, 210 },
+						{  24, 130, 194 },
+						{   3,  93, 146 },
+						{   1,  61,  97 },
+						{   1,  31,  50 },
+						{   1,  10,  16 },
+					},
+					{ /* Coeff Band 4 */
+						{  49, 186, 223 },
+						{  17, 148, 204 },
+						{   1,  96, 142 },
+						{   1,  53,  83 },
+						{   1,  26,  44 },
+						{   1,  11,  17 },
+					},
+					{ /* Coeff Band 5 */
+						{  13, 217, 212 },
+						{   2, 136, 180 },
+						{   1,  78, 124 },
+						{   1,  50,  83 },
+						{   1,  29,  49 },
+						{   1,  14,  23 },
+					},
+				},
+				{ /* Inter */
+					{ /* Coeff Band 0 */
+						{ 197,  13, 247 },
+						{  82,  17, 222 },
+						{  25,  17, 162 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+						{   0,   0,   0 },
+					},
+					{ /* Coeff Band 1 */
+						{ 126, 186, 247 },
+						{ 234, 191, 243 },
+						{ 176, 177, 234 },
+						{ 104, 158, 220 },
+						{  66, 128, 186 },
+						{  55,  90, 137 },
+					},
+					{ /* Coeff Band 2 */
+						{ 111, 197, 242 },
+						{  46, 158, 219 },
+						{   9, 104, 171 },
+						{   2,  65, 125 },
+						{   1,  44,  80 },
+						{   1,  17,  91 },
+					},
+					{ /* Coeff Band 3 */
+						{ 104, 208, 245 },
+						{  39, 168, 224 },
+						{   3, 109, 162 },
+						{   1,  79, 124 },
+						{   1,  50, 102 },
+						{   1,  43, 102 },
+					},
+					{ /* Coeff Band 4 */
+						{  84, 220, 246 },
+						{  31, 177, 231 },
+						{   2, 115, 180 },
+						{   1,  79, 134 },
+						{   1,  55,  77 },
+						{   1,  60,  79 },
+					},
+					{ /* Coeff Band 5 */
+						{  43, 243, 240 },
+						{   8, 180, 217 },
+						{   1, 115, 166 },
+						{   1,  84, 121 },
+						{   1,  51,  67 },
+						{   1,  16,   6 },
+					},
+				},
+			},
+		},
+	},
+
+	.skip = { 192, 128, 64 },
+	.inter_mode = {
+		{  2, 173, 34 },
+		{  7, 145, 85 },
+		{  7, 166, 63 },
+		{  7,  94, 66 },
+		{  8,  64, 46 },
+		{ 17,  81, 31 },
+		{ 25,  29, 30 },
+	},
+	.interp_filter = {
+		{ 235, 162 },
+		{  36, 255 },
+		{  34,   3 },
+		{ 149, 144 },
+	},
+	.is_inter = { 9, 102, 187, 225 },
+	.comp_mode = { 239, 183, 119, 96, 41 },
+	.single_ref = {
+		{  33,  16 },
+		{  77,  74 },
+		{ 142, 142 },
+		{ 172, 170 },
+		{ 238, 247 },
+	},
+	.comp_ref = { 50, 126, 123, 221, 226 },
+	.y_mode = {
+		{  65,  32, 18, 144, 162, 194, 41, 51, 98 },
+		{ 132,  68, 18, 165, 217, 196, 45, 40, 78 },
+		{ 173,  80, 19, 176, 240, 193, 64, 35, 46 },
+		{ 221, 135, 38, 194, 248, 121, 96, 85, 29 },
+	},
+	.uv_mode = {
+		{ 120,   7,  76, 176, 208, 126,  28,  54, 103 } /* y = dc */,
+		{  48,  12, 154, 155, 139,  90,  34, 117, 119 } /* y = v */,
+		{  67,   6,  25, 204, 243, 158,  13,  21,  96 } /* y = h */,
+		{  97,   5,  44, 131, 176, 139,  48,  68,  97 } /* y = d45 */,
+		{  83,   5,  42, 156, 111, 152,  26,  49, 152 } /* y = d135 */,
+		{  80,   5,  58, 178,  74,  83,  33,  62, 145 } /* y = d117 */,
+		{  86,   5,  32, 154, 192, 168,  14,  22, 163 } /* y = d153 */,
+		{  85,   5,  32, 156, 216, 148,  19,  29,  73 } /* y = d207 */,
+		{  77,   7,  64, 116, 132, 122,  37, 126, 120 } /* y = d63 */,
+		{ 101,  21, 107, 181, 192, 103,  19,  67, 125 } /* y = tm */
+	},
+	.partition = {
+		/* 8x8 -> 4x4 */
+		{ 199, 122, 141 } /* a/l both not split */,
+		{ 147,  63, 159 } /* a split, l not split */,
+		{ 148, 133, 118 } /* l split, a not split */,
+		{ 121, 104, 114 } /* a/l both split */,
+		/* 16x16 -> 8x8 */
+		{ 174,  73,  87 } /* a/l both not split */,
+		{  92,  41,  83 } /* a split, l not split */,
+		{  82,  99,  50 } /* l split, a not split */,
+		{  53,  39,  39 } /* a/l both split */,
+		/* 32x32 -> 16x16 */
+		{ 177,  58,  59 } /* a/l both not split */,
+		{  68,  26,  63 } /* a split, l not split */,
+		{  52,  79,  25 } /* l split, a not split */,
+		{  17,  14,  12 } /* a/l both split */,
+		/* 64x64 -> 32x32 */
+		{ 222,  34,  30 } /* a/l both not split */,
+		{  72,  16,  44 } /* a split, l not split */,
+		{  58,  32,  12 } /* l split, a not split */,
+		{  10,   7,   6 } /* a/l both split */,
+	},
+
+	.mv = {
+		.joint = { 32, 64, 96 },
+		.sign = { 128, 128 },
+		.classes = {
+			{ 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 },
+			{ 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 },
+		},
+		.class0_bit = { 216, 208 },
+		.bits = {
+			{ 136, 140, 148, 160, 176, 192, 224, 234, 234, 240},
+			{ 136, 140, 148, 160, 176, 192, 224, 234, 234, 240},
+		},
+		.class0_fr = {
+			{
+				{ 128, 128, 64 },
+				{  96, 112, 64 },
+			},
+			{
+				{ 128, 128, 64 },
+				{  96, 112, 64 },
+			},
+		},
+		.fr = {
+			{ 64, 96, 64 },
+			{ 64, 96, 64 },
+		},
+		.class0_hp = { 160, 160 },
+		.hp = { 128, 128 },
+	},
+};
+EXPORT_SYMBOL_GPL(v4l2_vp9_default_probs);
+
+static u32 fastdiv(u32 dividend, u16 divisor)
+{
+#define DIV_INV(d)	((u32)(((1ULL << 32) + ((d) - 1)) / (d)))
+#define DIVS_INV(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9)	\
+	DIV_INV(d0), DIV_INV(d1), DIV_INV(d2), DIV_INV(d3),	\
+	DIV_INV(d4), DIV_INV(d5), DIV_INV(d6), DIV_INV(d7),	\
+	DIV_INV(d8), DIV_INV(d9)
+
+	static const u32 inv[] = {
+		DIV_INV(2), DIV_INV(3), DIV_INV(4), DIV_INV(5),
+		DIV_INV(6), DIV_INV(7), DIV_INV(8), DIV_INV(9),
+		DIVS_INV(10, 11, 12, 13, 14, 15, 16, 17, 18, 19),
+		DIVS_INV(20, 21, 22, 23, 24, 25, 26, 27, 28, 29),
+		DIVS_INV(30, 31, 32, 33, 34, 35, 36, 37, 38, 39),
+		DIVS_INV(40, 41, 42, 43, 44, 45, 46, 47, 48, 49),
+		DIVS_INV(50, 51, 52, 53, 54, 55, 56, 57, 58, 59),
+		DIVS_INV(60, 61, 62, 63, 64, 65, 66, 67, 68, 69),
+		DIVS_INV(70, 71, 72, 73, 74, 75, 76, 77, 78, 79),
+		DIVS_INV(80, 81, 82, 83, 84, 85, 86, 87, 88, 89),
+		DIVS_INV(90, 91, 92, 93, 94, 95, 96, 97, 98, 99),
+		DIVS_INV(100, 101, 102, 103, 104, 105, 106, 107, 108, 109),
+		DIVS_INV(110, 111, 112, 113, 114, 115, 116, 117, 118, 119),
+		DIVS_INV(120, 121, 122, 123, 124, 125, 126, 127, 128, 129),
+		DIVS_INV(130, 131, 132, 133, 134, 135, 136, 137, 138, 139),
+		DIVS_INV(140, 141, 142, 143, 144, 145, 146, 147, 148, 149),
+		DIVS_INV(150, 151, 152, 153, 154, 155, 156, 157, 158, 159),
+		DIVS_INV(160, 161, 162, 163, 164, 165, 166, 167, 168, 169),
+		DIVS_INV(170, 171, 172, 173, 174, 175, 176, 177, 178, 179),
+		DIVS_INV(180, 181, 182, 183, 184, 185, 186, 187, 188, 189),
+		DIVS_INV(190, 191, 192, 193, 194, 195, 196, 197, 198, 199),
+		DIVS_INV(200, 201, 202, 203, 204, 205, 206, 207, 208, 209),
+		DIVS_INV(210, 211, 212, 213, 214, 215, 216, 217, 218, 219),
+		DIVS_INV(220, 221, 222, 223, 224, 225, 226, 227, 228, 229),
+		DIVS_INV(230, 231, 232, 233, 234, 235, 236, 237, 238, 239),
+		DIVS_INV(240, 241, 242, 243, 244, 245, 246, 247, 248, 249),
+		DIV_INV(250), DIV_INV(251), DIV_INV(252), DIV_INV(253),
+		DIV_INV(254), DIV_INV(255), DIV_INV(256),
+	};
+
+	if (divisor == 0)
+		return 0;
+	else if (divisor == 1)
+		return dividend;
+
+	if (WARN_ON(divisor - 2 >= ARRAY_SIZE(inv)))
+		return dividend;
+
+	return ((u64)dividend * inv[divisor - 2]) >> 32;
+}
+
+/* 6.3.6 inv_recenter_nonneg(v, m) */
+static int inv_recenter_nonneg(int v, int m)
+{
+	if (v > 2 * m)
+		return v;
+
+	if (v & 1)
+		return m - ((v + 1) >> 1);
+
+	return m + (v >> 1);
+}
+
+/*
+ * part of 6.3.5 inv_remap_prob(deltaProb, prob)
+ * delta = inv_map_table[deltaProb] done by userspace
+ */
+static int update_prob(int delta, int prob)
+{
+	if (!delta)
+		return prob;
+
+	return prob <= 128 ?
+		1 + inv_recenter_nonneg(delta, prob - 1) :
+		255 - inv_recenter_nonneg(delta, 255 - prob);
+}
+
+/* Counterpart to 6.3.2 tx_mode_probs() */
+static void update_tx_probs(struct v4l2_vp9_frame_context *probs,
+			    const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(probs->tx8); i++) {
+		u8 *p8x8 = probs->tx8[i];
+		u8 *p16x16 = probs->tx16[i];
+		u8 *p32x32 = probs->tx32[i];
+		const u8 *d8x8 = deltas->tx8[i];
+		const u8 *d16x16 = deltas->tx16[i];
+		const u8 *d32x32 = deltas->tx32[i];
+
+		p8x8[0] = update_prob(d8x8[0], p8x8[0]);
+		p16x16[0] = update_prob(d16x16[0], p16x16[0]);
+		p16x16[1] = update_prob(d16x16[1], p16x16[1]);
+		p32x32[0] = update_prob(d32x32[0], p32x32[0]);
+		p32x32[1] = update_prob(d32x32[1], p32x32[1]);
+		p32x32[2] = update_prob(d32x32[2], p32x32[2]);
+	}
+}
+
+#define BAND_6(band) ((band) == 0 ? 3 : 6)
+
+static void update_coeff(const u8 deltas[6][6][3], u8 probs[6][6][3])
+{
+	int l, m, n;
+
+	for (l = 0; l < 6; l++)
+		for (m = 0; m < BAND_6(l); m++) {
+			u8 *p = probs[l][m];
+			const u8 *d = deltas[l][m];
+
+			for (n = 0; n < 3; n++)
+				p[n] = update_prob(d[n], p[n]);
+		}
+}
+
+/* Counterpart to 6.3.7 read_coef_probs() */
+static void update_coef_probs(struct v4l2_vp9_frame_context *probs,
+			      const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas,
+			      const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	int i, j, k;
+
+	for (i = 0; i < ARRAY_SIZE(probs->coef); i++) {
+		for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++)
+			for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); k++)
+				update_coeff(deltas->coef[i][j][k], probs->coef[i][j][k]);
+
+		if (dec_params->tx_mode == i)
+			break;
+	}
+}
+
+/* Counterpart to 6.3.8 read_skip_prob() */
+static void update_skip_probs(struct v4l2_vp9_frame_context *probs,
+			      const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(probs->skip); i++)
+		probs->skip[i] = update_prob(deltas->skip[i], probs->skip[i]);
+}
+
+/* Counterpart to 6.3.9 read_inter_mode_probs() */
+static void update_inter_mode_probs(struct v4l2_vp9_frame_context *probs,
+				    const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(probs->inter_mode); i++) {
+		u8 *p = probs->inter_mode[i];
+		const u8 *d = deltas->inter_mode[i];
+
+		p[0] = update_prob(d[0], p[0]);
+		p[1] = update_prob(d[1], p[1]);
+		p[2] = update_prob(d[2], p[2]);
+	}
+}
+
+/* Counterpart to 6.3.10 read_interp_filter_probs() */
+static void update_interp_filter_probs(struct v4l2_vp9_frame_context *probs,
+				       const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(probs->interp_filter); i++) {
+		u8 *p = probs->interp_filter[i];
+		const u8 *d = deltas->interp_filter[i];
+
+		p[0] = update_prob(d[0], p[0]);
+		p[1] = update_prob(d[1], p[1]);
+	}
+}
+
+/* Counterpart to 6.3.11 read_is_inter_probs() */
+static void update_is_inter_probs(struct v4l2_vp9_frame_context *probs,
+				  const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(probs->is_inter); i++)
+		probs->is_inter[i] = update_prob(deltas->is_inter[i], probs->is_inter[i]);
+}
+
+/* 6.3.12 frame_reference_mode() done entirely in userspace */
+
+/* Counterpart to 6.3.13 frame_reference_mode_probs() */
+static void
+update_frame_reference_mode_probs(enum v4l2_vp9_reference_mode reference_mode,
+				  struct v4l2_vp9_frame_context *probs,
+				  const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas)
+{
+	int i;
+
+	if (reference_mode == V4L2_VP9_REFERENCE_MODE_SELECT)
+		for (i = 0; i < ARRAY_SIZE(probs->comp_mode); i++)
+			probs->comp_mode[i] = update_prob(deltas->comp_mode[i],
+							  probs->comp_mode[i]);
+
+	if (reference_mode != V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE)
+		for (i = 0; i < ARRAY_SIZE(probs->single_ref); i++) {
+			u8 *p = probs->single_ref[i];
+			const u8 *d = deltas->single_ref[i];
+
+			p[0] = update_prob(d[0], p[0]);
+			p[1] = update_prob(d[1], p[1]);
+		}
+
+	if (reference_mode != V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE)
+		for (i = 0; i < ARRAY_SIZE(probs->comp_ref); i++)
+			probs->comp_ref[i] = update_prob(deltas->comp_ref[i], probs->comp_ref[i]);
+}
+
+/* Counterpart to 6.3.14 read_y_mode_probs() */
+static void update_y_mode_probs(struct v4l2_vp9_frame_context *probs,
+				const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas)
+{
+	int i, j;
+
+	for (i = 0; i < ARRAY_SIZE(probs->y_mode); i++)
+		for (j = 0; j < ARRAY_SIZE(probs->y_mode[0]); ++j)
+			probs->y_mode[i][j] =
+				update_prob(deltas->y_mode[i][j], probs->y_mode[i][j]);
+}
+
+/* Counterpart to 6.3.15 read_partition_probs() */
+static void update_partition_probs(struct v4l2_vp9_frame_context *probs,
+				   const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas)
+{
+	int i, j;
+
+	for (i = 0; i < 4; i++)
+		for (j = 0; j < 4; j++) {
+			u8 *p = probs->partition[i * 4 + j];
+			const u8 *d = deltas->partition[i * 4 + j];
+
+			p[0] = update_prob(d[0], p[0]);
+			p[1] = update_prob(d[1], p[1]);
+			p[2] = update_prob(d[2], p[2]);
+		}
+}
+
+static inline int update_mv_prob(int delta, int prob)
+{
+	if (!delta)
+		return prob;
+
+	return delta;
+}
+
+/* Counterpart to 6.3.16 mv_probs() */
+static void update_mv_probs(struct v4l2_vp9_frame_context *probs,
+			    const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas,
+			    const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	u8 *p = probs->mv.joint;
+	const u8 *d = deltas->mv.joint;
+	unsigned int i, j;
+
+	p[0] = update_mv_prob(d[0], p[0]);
+	p[1] = update_mv_prob(d[1], p[1]);
+	p[2] = update_mv_prob(d[2], p[2]);
+
+	for (i = 0; i < ARRAY_SIZE(probs->mv.sign); i++) {
+		p = probs->mv.sign;
+		d = deltas->mv.sign;
+		p[i] = update_mv_prob(d[i], p[i]);
+
+		p = probs->mv.classes[i];
+		d = deltas->mv.classes[i];
+		for (j = 0; j < ARRAY_SIZE(probs->mv.classes[0]); j++)
+			p[j] = update_mv_prob(d[j], p[j]);
+
+		p = probs->mv.class0_bit;
+		d = deltas->mv.class0_bit;
+		p[i] = update_mv_prob(d[i], p[i]);
+
+		p = probs->mv.bits[i];
+		d = deltas->mv.bits[i];
+		for (j = 0; j < ARRAY_SIZE(probs->mv.bits[0]); j++)
+			p[j] = update_mv_prob(d[j], p[j]);
+
+		for (j = 0; j < ARRAY_SIZE(probs->mv.class0_fr[0]); j++) {
+			p = probs->mv.class0_fr[i][j];
+			d = deltas->mv.class0_fr[i][j];
+
+			p[0] = update_mv_prob(d[0], p[0]);
+			p[1] = update_mv_prob(d[1], p[1]);
+			p[2] = update_mv_prob(d[2], p[2]);
+		}
+
+		p = probs->mv.fr[i];
+		d = deltas->mv.fr[i];
+		for (j = 0; j < ARRAY_SIZE(probs->mv.fr[i]); j++)
+			p[j] = update_mv_prob(d[j], p[j]);
+
+		if (dec_params->flags & V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV) {
+			p = probs->mv.class0_hp;
+			d = deltas->mv.class0_hp;
+			p[i] = update_mv_prob(d[i], p[i]);
+
+			p = probs->mv.hp;
+			d = deltas->mv.hp;
+			p[i] = update_mv_prob(d[i], p[i]);
+		}
+	}
+}
+
+/* Counterpart to 6.3 compressed_header(), but parsing has been done in userspace. */
+void v4l2_vp9_fw_update_probs(struct v4l2_vp9_frame_context *probs,
+			      const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas,
+			      const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	if (dec_params->tx_mode == V4L2_VP9_TX_MODE_SELECT)
+		update_tx_probs(probs, deltas);
+
+	update_coef_probs(probs, deltas, dec_params);
+
+	update_skip_probs(probs, deltas);
+
+	if (dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME ||
+	    dec_params->flags & V4L2_VP9_FRAME_FLAG_INTRA_ONLY)
+		return;
+
+	update_inter_mode_probs(probs, deltas);
+
+	if (dec_params->interpolation_filter == V4L2_VP9_INTERP_FILTER_SWITCHABLE)
+		update_interp_filter_probs(probs, deltas);
+
+	update_is_inter_probs(probs, deltas);
+
+	update_frame_reference_mode_probs(dec_params->reference_mode, probs, deltas);
+
+	update_y_mode_probs(probs, deltas);
+
+	update_partition_probs(probs, deltas);
+
+	update_mv_probs(probs, deltas, dec_params);
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_fw_update_probs);
+
+u8 v4l2_vp9_reset_frame_ctx(const struct v4l2_ctrl_vp9_frame *dec_params,
+			    struct v4l2_vp9_frame_context *frame_context)
+{
+	int i;
+
+	u8 fctx_idx = dec_params->frame_context_idx;
+
+	if (dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME ||
+	    dec_params->flags & V4L2_VP9_FRAME_FLAG_INTRA_ONLY ||
+	    dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) {
+		/*
+		 * setup_past_independence()
+		 * We do nothing here. Instead of storing default probs in some intermediate
+		 * location and then copying from that location to appropriate contexts
+		 * in save_probs() below, we skip that step and save default probs directly
+		 * to appropriate contexts.
+		 */
+		if (dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME ||
+		    dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT ||
+		    dec_params->reset_frame_context == V4L2_VP9_RESET_FRAME_CTX_ALL)
+			for (i = 0; i < 4; ++i)
+				/* save_probs(i) */
+				memcpy(&frame_context[i], &v4l2_vp9_default_probs,
+				       sizeof(v4l2_vp9_default_probs));
+		else if (dec_params->reset_frame_context == V4L2_VP9_RESET_FRAME_CTX_SPEC)
+			/* save_probs(fctx_idx) */
+			memcpy(&frame_context[fctx_idx], &v4l2_vp9_default_probs,
+			       sizeof(v4l2_vp9_default_probs));
+		fctx_idx = 0;
+	}
+
+	return fctx_idx;
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_reset_frame_ctx);
+
+/* 8.4.1 Merge prob process */
+static u8 merge_prob(u8 pre_prob, u32 ct0, u32 ct1, u16 count_sat, u32 max_update_factor)
+{
+	u32 den, prob, count, factor;
+
+	den = ct0 + ct1;
+	if (!den) {
+		/*
+		 * prob = 128, count = 0, update_factor = 0
+		 * Round2's argument: pre_prob * 256
+		 * (pre_prob * 256 + 128) >> 8 == pre_prob
+		 */
+		return pre_prob;
+	}
+
+	prob = clamp(((ct0 << 8) + (den >> 1)) / den, (u32)1, (u32)255);
+	count = min_t(u32, den, count_sat);
+	factor = fastdiv(max_update_factor * count, count_sat);
+
+	/*
+	 * Round2(pre_prob * (256 - factor) + prob * factor, 8)
+	 * Round2(pre_prob * 256 + (prob - pre_prob) * factor, 8)
+	 * (pre_prob * 256 >> 8) + (((prob - pre_prob) * factor + 128) >> 8)
+	 */
+	return pre_prob + (((prob - pre_prob) * factor + 128) >> 8);
+}
+
+static inline u8 noncoef_merge_prob(u8 pre_prob, u32 ct0, u32 ct1)
+{
+	return merge_prob(pre_prob, ct0, ct1, 20, 128);
+}
+
+/* 8.4.2 Merge probs process */
+/*
+ * merge_probs() is a recursive function in the spec. We avoid recursion in the kernel.
+ * That said, the "tree" parameter of merge_probs() controls how deep the recursion goes.
+ * It turns out that in all cases the recursive calls boil down to a short-ish series
+ * of merge_prob() invocations (note no "s").
+ *
+ * Variant A
+ * ---------
+ * merge_probs(small_token_tree, 2):
+ *	merge_prob(p[1], c[0], c[1] + c[2])
+ *	merge_prob(p[2], c[1], c[2])
+ *
+ * Variant B
+ * ---------
+ * merge_probs(binary_tree, 0) or
+ * merge_probs(tx_size_8_tree, 0):
+ *	merge_prob(p[0], c[0], c[1])
+ *
+ * Variant C
+ * ---------
+ * merge_probs(inter_mode_tree, 0):
+ *	merge_prob(p[0], c[2], c[1] + c[0] + c[3])
+ *	merge_prob(p[1], c[0], c[1] + c[3])
+ *	merge_prob(p[2], c[1], c[3])
+ *
+ * Variant D
+ * ---------
+ * merge_probs(intra_mode_tree, 0):
+ *	merge_prob(p[0], c[0], c[1] + ... + c[9])
+ *	merge_prob(p[1], c[9], c[1] + ... + c[8])
+ *	merge_prob(p[2], c[1], c[2] + ... + c[8])
+ *	merge_prob(p[3], c[2] + c[4] + c[5], c[3] + c[8] + c[6] + c[7])
+ *	merge_prob(p[4], c[2], c[4] + c[5])
+ *	merge_prob(p[5], c[4], c[5])
+ *	merge_prob(p[6], c[3], c[8] + c[6] + c[7])
+ *	merge_prob(p[7], c[8], c[6] + c[7])
+ *	merge_prob(p[8], c[6], c[7])
+ *
+ * Variant E
+ * ---------
+ * merge_probs(partition_tree, 0) or
+ * merge_probs(tx_size_32_tree, 0) or
+ * merge_probs(mv_joint_tree, 0) or
+ * merge_probs(mv_fr_tree, 0):
+ *	merge_prob(p[0], c[0], c[1] + c[2] + c[3])
+ *	merge_prob(p[1], c[1], c[2] + c[3])
+ *	merge_prob(p[2], c[2], c[3])
+ *
+ * Variant F
+ * ---------
+ * merge_probs(interp_filter_tree, 0) or
+ * merge_probs(tx_size_16_tree, 0):
+ *	merge_prob(p[0], c[0], c[1] + c[2])
+ *	merge_prob(p[1], c[1], c[2])
+ *
+ * Variant G
+ * ---------
+ * merge_probs(mv_class_tree, 0):
+ *	merge_prob(p[0], c[0], c[1] + ... + c[10])
+ *	merge_prob(p[1], c[1], c[2] + ... + c[10])
+ *	merge_prob(p[2], c[2] + c[3], c[4] + ... + c[10])
+ *	merge_prob(p[3], c[2], c[3])
+ *	merge_prob(p[4], c[4] + c[5], c[6] + ... + c[10])
+ *	merge_prob(p[5], c[4], c[5])
+ *	merge_prob(p[6], c[6], c[7] + ... + c[10])
+ *	merge_prob(p[7], c[7] + c[8], c[9] + c[10])
+ *	merge_prob(p[8], c[7], c[8])
+ *	merge_prob(p[9], c[9], [10])
+ */
+
+static inline void merge_probs_variant_a(u8 *p, const u32 *c, u16 count_sat, u32 update_factor)
+{
+	p[1] = merge_prob(p[1], c[0], c[1] + c[2], count_sat, update_factor);
+	p[2] = merge_prob(p[2], c[1], c[2], count_sat, update_factor);
+}
+
+static inline void merge_probs_variant_b(u8 *p, const u32 *c, u16 count_sat, u32 update_factor)
+{
+	p[0] = merge_prob(p[0], c[0], c[1], count_sat, update_factor);
+}
+
+static inline void merge_probs_variant_c(u8 *p, const u32 *c)
+{
+	p[0] = noncoef_merge_prob(p[0], c[2], c[1] + c[0] + c[3]);
+	p[1] = noncoef_merge_prob(p[1], c[0], c[1] + c[3]);
+	p[2] = noncoef_merge_prob(p[2], c[1], c[3]);
+}
+
+static void merge_probs_variant_d(u8 *p, const u32 *c)
+{
+	u32 sum = 0, s2;
+
+	sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
+
+	p[0] = noncoef_merge_prob(p[0], c[0], sum);
+	sum -= c[9];
+	p[1] = noncoef_merge_prob(p[1], c[9], sum);
+	sum -= c[1];
+	p[2] = noncoef_merge_prob(p[2], c[1], sum);
+	s2 = c[2] + c[4] + c[5];
+	sum -= s2;
+	p[3] = noncoef_merge_prob(p[3], s2, sum);
+	s2 -= c[2];
+	p[4] = noncoef_merge_prob(p[4], c[2], s2);
+	p[5] = noncoef_merge_prob(p[5], c[4], c[5]);
+	sum -= c[3];
+	p[6] = noncoef_merge_prob(p[6], c[3], sum);
+	sum -= c[8];
+	p[7] = noncoef_merge_prob(p[7], c[8], sum);
+	p[8] = noncoef_merge_prob(p[8], c[6], c[7]);
+}
+
+static inline void merge_probs_variant_e(u8 *p, const u32 *c)
+{
+	p[0] = noncoef_merge_prob(p[0], c[0], c[1] + c[2] + c[3]);
+	p[1] = noncoef_merge_prob(p[1], c[1], c[2] + c[3]);
+	p[2] = noncoef_merge_prob(p[2], c[2], c[3]);
+}
+
+static inline void merge_probs_variant_f(u8 *p, const u32 *c)
+{
+	p[0] = noncoef_merge_prob(p[0], c[0], c[1] + c[2]);
+	p[1] = noncoef_merge_prob(p[1], c[1], c[2]);
+}
+
+static void merge_probs_variant_g(u8 *p, const u32 *c)
+{
+	u32 sum;
+
+	sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10];
+	p[0] = noncoef_merge_prob(p[0], c[0], sum);
+	sum -= c[1];
+	p[1] = noncoef_merge_prob(p[1], c[1], sum);
+	sum -= c[2] + c[3];
+	p[2] = noncoef_merge_prob(p[2], c[2] + c[3], sum);
+	p[3] = noncoef_merge_prob(p[3], c[2], c[3]);
+	sum -= c[4] + c[5];
+	p[4] = noncoef_merge_prob(p[4], c[4] + c[5], sum);
+	p[5] = noncoef_merge_prob(p[5], c[4], c[5]);
+	sum -= c[6];
+	p[6] = noncoef_merge_prob(p[6], c[6], sum);
+	p[7] = noncoef_merge_prob(p[7], c[7] + c[8], c[9] + c[10]);
+	p[8] = noncoef_merge_prob(p[8], c[7], c[8]);
+	p[9] = noncoef_merge_prob(p[9], c[9], c[10]);
+}
+
+/* 8.4.3 Coefficient probability adaptation process */
+static inline void adapt_probs_variant_a_coef(u8 *p, const u32 *c, u32 update_factor)
+{
+	merge_probs_variant_a(p, c, 24, update_factor);
+}
+
+static inline void adapt_probs_variant_b_coef(u8 *p, const u32 *c, u32 update_factor)
+{
+	merge_probs_variant_b(p, c, 24, update_factor);
+}
+
+static void _adapt_coeff(unsigned int i, unsigned int j, unsigned int k,
+			 struct v4l2_vp9_frame_context *probs,
+			 const struct v4l2_vp9_frame_symbol_counts *counts,
+			 u32 uf)
+{
+	s32 l, m;
+
+	for (l = 0; l < ARRAY_SIZE(probs->coef[0][0][0]); l++) {
+		for (m = 0; m < BAND_6(l); m++) {
+			u8 *p = probs->coef[i][j][k][l][m];
+			const u32 counts_more_coefs[2] = {
+				*counts->eob[i][j][k][l][m][1],
+				*counts->eob[i][j][k][l][m][0] - *counts->eob[i][j][k][l][m][1],
+			};
+
+			adapt_probs_variant_a_coef(p, *counts->coeff[i][j][k][l][m], uf);
+			adapt_probs_variant_b_coef(p, counts_more_coefs, uf);
+		}
+	}
+}
+
+static void _adapt_coef_probs(struct v4l2_vp9_frame_context *probs,
+			      const struct v4l2_vp9_frame_symbol_counts *counts,
+			      unsigned int uf)
+{
+	unsigned int i, j, k;
+
+	for (i = 0; i < ARRAY_SIZE(probs->coef); i++)
+		for (j = 0; j < ARRAY_SIZE(probs->coef[0]); j++)
+			for (k = 0; k < ARRAY_SIZE(probs->coef[0][0]); k++)
+				_adapt_coeff(i, j, k, probs, counts, uf);
+}
+
+void v4l2_vp9_adapt_coef_probs(struct v4l2_vp9_frame_context *probs,
+			       struct v4l2_vp9_frame_symbol_counts *counts,
+			       bool use_128,
+			       bool frame_is_intra)
+{
+	if (frame_is_intra) {
+		_adapt_coef_probs(probs, counts, 112);
+	} else {
+		if (use_128)
+			_adapt_coef_probs(probs, counts, 128);
+		else
+			_adapt_coef_probs(probs, counts, 112);
+	}
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_adapt_coef_probs);
+
+/* 8.4.4 Non coefficient probability adaptation process, adapt_probs() */
+static inline void adapt_probs_variant_b(u8 *p, const u32 *c)
+{
+	merge_probs_variant_b(p, c, 20, 128);
+}
+
+static inline void adapt_probs_variant_c(u8 *p, const u32 *c)
+{
+	merge_probs_variant_c(p, c);
+}
+
+static inline void adapt_probs_variant_d(u8 *p, const u32 *c)
+{
+	merge_probs_variant_d(p, c);
+}
+
+static inline void adapt_probs_variant_e(u8 *p, const u32 *c)
+{
+	merge_probs_variant_e(p, c);
+}
+
+static inline void adapt_probs_variant_f(u8 *p, const u32 *c)
+{
+	merge_probs_variant_f(p, c);
+}
+
+static inline void adapt_probs_variant_g(u8 *p, const u32 *c)
+{
+	merge_probs_variant_g(p, c);
+}
+
+/* 8.4.4 Non coefficient probability adaptation process, adapt_prob() */
+static inline u8 adapt_prob(u8 prob, const u32 counts[2])
+{
+	return noncoef_merge_prob(prob, counts[0], counts[1]);
+}
+
+/* 8.4.4 Non coefficient probability adaptation process */
+void v4l2_vp9_adapt_noncoef_probs(struct v4l2_vp9_frame_context *probs,
+				  struct v4l2_vp9_frame_symbol_counts *counts,
+				  u8 reference_mode, u8 interpolation_filter, u8 tx_mode,
+				  u32 flags)
+{
+	unsigned int i, j;
+
+	for (i = 0; i < ARRAY_SIZE(probs->is_inter); i++)
+		probs->is_inter[i] = adapt_prob(probs->is_inter[i], (*counts->intra_inter)[i]);
+
+	for (i = 0; i < ARRAY_SIZE(probs->comp_mode); i++)
+		probs->comp_mode[i] = adapt_prob(probs->comp_mode[i], (*counts->comp)[i]);
+
+	for (i = 0; i < ARRAY_SIZE(probs->comp_ref); i++)
+		probs->comp_ref[i] = adapt_prob(probs->comp_ref[i], (*counts->comp_ref)[i]);
+
+	if (reference_mode != V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE)
+		for (i = 0; i < ARRAY_SIZE(probs->single_ref); i++)
+			for (j = 0; j < ARRAY_SIZE(probs->single_ref[0]); j++)
+				probs->single_ref[i][j] = adapt_prob(probs->single_ref[i][j],
+								     (*counts->single_ref)[i][j]);
+
+	for (i = 0; i < ARRAY_SIZE(probs->inter_mode); i++)
+		adapt_probs_variant_c(probs->inter_mode[i], (*counts->mv_mode)[i]);
+
+	for (i = 0; i < ARRAY_SIZE(probs->y_mode); i++)
+		adapt_probs_variant_d(probs->y_mode[i], (*counts->y_mode)[i]);
+
+	for (i = 0; i < ARRAY_SIZE(probs->uv_mode); i++)
+		adapt_probs_variant_d(probs->uv_mode[i], (*counts->uv_mode)[i]);
+
+	for (i = 0; i < ARRAY_SIZE(probs->partition); i++)
+		adapt_probs_variant_e(probs->partition[i], (*counts->partition)[i]);
+
+	for (i = 0; i < ARRAY_SIZE(probs->skip); i++)
+		probs->skip[i] = adapt_prob(probs->skip[i], (*counts->skip)[i]);
+
+	if (interpolation_filter == V4L2_VP9_INTERP_FILTER_SWITCHABLE)
+		for (i = 0; i < ARRAY_SIZE(probs->interp_filter); i++)
+			adapt_probs_variant_f(probs->interp_filter[i], (*counts->filter)[i]);
+
+	if (tx_mode == V4L2_VP9_TX_MODE_SELECT)
+		for (i = 0; i < ARRAY_SIZE(probs->tx8); i++) {
+			adapt_probs_variant_b(probs->tx8[i], (*counts->tx8p)[i]);
+			adapt_probs_variant_f(probs->tx16[i], (*counts->tx16p)[i]);
+			adapt_probs_variant_e(probs->tx32[i], (*counts->tx32p)[i]);
+		}
+
+	adapt_probs_variant_e(probs->mv.joint, *counts->mv_joint);
+
+	for (i = 0; i < ARRAY_SIZE(probs->mv.sign); i++) {
+		probs->mv.sign[i] = adapt_prob(probs->mv.sign[i], (*counts->sign)[i]);
+
+		adapt_probs_variant_g(probs->mv.classes[i], (*counts->classes)[i]);
+
+		probs->mv.class0_bit[i] = adapt_prob(probs->mv.class0_bit[i], (*counts->class0)[i]);
+
+		for (j = 0; j < ARRAY_SIZE(probs->mv.bits[0]); j++)
+			probs->mv.bits[i][j] = adapt_prob(probs->mv.bits[i][j],
+							  (*counts->bits)[i][j]);
+
+		for (j = 0; j < ARRAY_SIZE(probs->mv.class0_fr[0]); j++)
+			adapt_probs_variant_e(probs->mv.class0_fr[i][j],
+					      (*counts->class0_fp)[i][j]);
+
+		adapt_probs_variant_e(probs->mv.fr[i], (*counts->fp)[i]);
+
+		if (!(flags & V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV))
+			continue;
+
+		probs->mv.class0_hp[i] = adapt_prob(probs->mv.class0_hp[i],
+						    (*counts->class0_hp)[i]);
+
+		probs->mv.hp[i] = adapt_prob(probs->mv.hp[i], (*counts->hp)[i]);
+	}
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_adapt_noncoef_probs);
+
+bool
+v4l2_vp9_seg_feat_enabled(const u8 *feature_enabled,
+			  enum v4l2_vp9_segment_feature feature,
+			  unsigned int segid)
+{
+	u8 mask = V4L2_VP9_SEGMENT_FEATURE_ENABLED(feature);
+
+	return !!(feature_enabled[segid] & mask);
+}
+EXPORT_SYMBOL_GPL(v4l2_vp9_seg_feat_enabled);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("V4L2 VP9 Helpers");
+MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p at collabora.com>");
diff --git a/include/media/v4l2-vp9.h b/include/media/v4l2-vp9.h
new file mode 100644
index 000000000000..920a8533360d
--- /dev/null
+++ b/include/media/v4l2-vp9.h
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Helper functions for vp9 codecs.
+ *
+ * Copyright (c) 2021 Collabora, Ltd.
+ *
+ * Author: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
+ */
+
+#ifndef _MEDIA_V4L2_VP9_H
+#define _MEDIA_V4L2_VP9_H
+
+#include <media/v4l2-ctrls.h>
+
+/**
+ * struct v4l2_vp9_frame_mv_context - motion vector-related probabilities
+ *
+ * A member of v4l2_vp9_frame_context.
+ */
+struct v4l2_vp9_frame_mv_context {
+	u8 joint[3];
+	u8 sign[2];
+	u8 classes[2][10];
+	u8 class0_bit[2];
+	u8 bits[2][10];
+	u8 class0_fr[2][2][3];
+	u8 fr[2][3];
+	u8 class0_hp[2];
+	u8 hp[2];
+};
+
+/**
+ * struct v4l2_vp9_frame_context - frame probabilities, including motion-vector related
+ *
+ * Drivers which need to keep track of frame context(s) can use this struct.
+ * The members correspond to probability tables, which are specified only implicitly in the
+ * vp9 spec. Section 10.5 "Default probability tables" contains all the types of involved
+ * tables, i.e. the actual tables are of the same kind, and when they are reset (which is
+ * mandated by the spec sometimes) they are overwritten with values from the default tables.
+ */
+struct v4l2_vp9_frame_context {
+	u8 tx8[2][1];
+	u8 tx16[2][2];
+	u8 tx32[2][3];
+	u8 coef[4][2][2][6][6][3];
+	u8 skip[3];
+	u8 inter_mode[7][3];
+	u8 interp_filter[4][2];
+	u8 is_inter[4];
+	u8 comp_mode[5];
+	u8 single_ref[5][2];
+	u8 comp_ref[5];
+	u8 y_mode[4][9];
+	u8 uv_mode[10][9];
+	u8 partition[16][3];
+
+	struct v4l2_vp9_frame_mv_context mv;
+};
+
+/**
+ * struct v4l2_vp9_frame_symbol_counts - pointers to arrays of symbol counts
+ *
+ * The fields correspond to what is specified in section 8.3 "Clear counts process" of the spec.
+ * Different pieces of hardware can report the counts in different order, so we cannot rely on
+ * simply overlaying a struct on a relevant block of memory. Instead we provide pointers to
+ * arrays or array of pointers to arrays in case of coeff, or array of pointers for eob.
+ */
+struct v4l2_vp9_frame_symbol_counts {
+	u32 (*partition)[16][4];
+	u32 (*skip)[3][2];
+	u32 (*intra_inter)[4][2];
+	u32 (*tx32p)[2][4];
+	u32 (*tx16p)[2][4];
+	u32 (*tx8p)[2][2];
+	u32 (*y_mode)[4][10];
+	u32 (*uv_mode)[10][10];
+	u32 (*comp)[5][2];
+	u32 (*comp_ref)[5][2];
+	u32 (*single_ref)[5][2][2];
+	u32 (*mv_mode)[7][4];
+	u32 (*filter)[4][3];
+	u32 (*mv_joint)[4];
+	u32 (*sign)[2][2];
+	u32 (*classes)[2][11];
+	u32 (*class0)[2][2];
+	u32 (*bits)[2][10][2];
+	u32 (*class0_fp)[2][2][4];
+	u32 (*fp)[2][4];
+	u32 (*class0_hp)[2][2];
+	u32 (*hp)[2][2];
+	u32 (*coeff[4][2][2][6][6])[3];
+	u32 *eob[4][2][2][6][6][2];
+};
+
+extern const u8 v4l2_vp9_kf_y_mode_prob[10][10][9]; /* Section 10.4 of the spec */
+extern const u8 v4l2_vp9_kf_partition_probs[16][3]; /* Section 10.4 of the spec */
+extern const u8 v4l2_vp9_kf_uv_mode_prob[10][9]; /* Section 10.4 of the spec */
+extern const struct v4l2_vp9_frame_context v4l2_vp9_default_probs; /* Section 10.5 of the spec */
+
+/**
+ * v4l2_vp9_fw_update_probs() - Perform forward update of vp9 probabilities
+ *
+ * @probs: current probabilities values
+ * @deltas: delta values from compressed header
+ * @dec_params: vp9 frame decoding parameters
+ *
+ * This function performs forward updates of probabilities for the vp9 boolean decoder.
+ * The frame header can contain a directive to update the probabilities (deltas), if so, then
+ * the deltas are provided in the header, too. The userspace parses those and passes the said
+ * deltas struct to the kernel.
+ */
+void v4l2_vp9_fw_update_probs(struct v4l2_vp9_frame_context *probs,
+			      const struct v4l2_ctrl_vp9_compressed_hdr_probs *deltas,
+			      const struct v4l2_ctrl_vp9_frame *dec_params);
+
+/**
+ * v4l2_vp9_reset_frame_ctx() - Reset appropriate frame context
+ *
+ * @dec_params: vp9 frame decoding parameters
+ * @frame_context: array of the 4 frame contexts
+ *
+ * This function resets appropriate frame contexts, based on what's in dec_params.
+ *
+ * Returns the frame context index after the update, which might be reset to zero if
+ * mandated by the spec.
+ */
+u8 v4l2_vp9_reset_frame_ctx(const struct v4l2_ctrl_vp9_frame *dec_params,
+			    struct v4l2_vp9_frame_context *frame_context);
+
+/**
+ * v4l2_vp9_adapt_coef_probs() - Perform backward update of vp9 coefficients probabilities
+ *
+ * @probs: current probabilities values
+ * @counts: values of symbol counts after the current frame has been decoded
+ * @use_128: flag to request that 128 is used as update factor if true, otherwise 112 is used
+ * @frame_is_intra: flag indicating that FrameIsIntra is true
+ *
+ * This function performs backward updates of coefficients probabilities for the vp9 boolean
+ * decoder. After a frame has been decoded the counts of how many times a given symbol has
+ * occurred are known and are used to update the probability of each symbol.
+ */
+void v4l2_vp9_adapt_coef_probs(struct v4l2_vp9_frame_context *probs,
+			       struct v4l2_vp9_frame_symbol_counts *counts,
+			       bool use_128,
+			       bool frame_is_intra);
+
+/**
+ * v4l2_vp9_adapt_coef_probs() - Perform backward update of vp9 non-coefficients probabilities
+ *
+ * @probs: current probabilities values
+ * @counts: values of symbol counts after the current frame has been decoded
+ * @reference_mode: specifies the type of inter prediction to be used. See
+ *	&v4l2_vp9_reference_mode for more details
+ * @interpolation_filter: specifies the filter selection used for performing inter prediction.
+ *	See &v4l2_vp9_interpolation_filter for more details
+ * @tx_mode: specifies the TX mode. See &v4l2_vp9_tx_mode for more details
+ * @flags: combination of V4L2_VP9_FRAME_FLAG_* flags
+ *
+ * This function performs backward updates of non-coefficients probabilities for the vp9 boolean
+ * decoder. After a frame has been decoded the counts of how many times a given symbol has
+ * occurred are known and are used to update the probability of each symbol.
+ */
+void v4l2_vp9_adapt_noncoef_probs(struct v4l2_vp9_frame_context *probs,
+				  struct v4l2_vp9_frame_symbol_counts *counts,
+				  u8 reference_mode, u8 interpolation_filter, u8 tx_mode,
+				  u32 flags);
+
+/**
+ * v4l2_vp9_seg_feat_enabled() - Check if a segmentation feature is enabled
+ *
+ * @feature_enabled: array of 8-bit flags (for all segments)
+ * @feature: id of the feature to check
+ * @segid: id of the segment to look up
+ *
+ * This function returns true if a given feature is active in a given segment.
+ */
+bool
+v4l2_vp9_seg_feat_enabled(const u8 *feature_enabled,
+			  enum v4l2_vp9_segment_feature feature,
+			  unsigned int segid);
+
+#endif /* _MEDIA_V4L2_VP9_H */
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:46 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:46 +0200
Subject: [PATCH v3 10/10] media: hantro: Support NV12 on the G2 core
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-11-andrzej.p@collabora.com>

From: Ezequiel Garcia <ezequiel at collabora.com>

The G2 decoder block produces NV12 4x4 tiled format (NV12_4L4).
Enable the G2 post-processor block, in order to produce regular NV12.

The logic in hantro_postproc.c is leveraged to take care of allocating
the extra buffers and configure the post-processor, which is
significantly simpler than the one on the G1.

Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
---
 .../staging/media/hantro/hantro_g2_vp9_dec.c  |  6 ++--
 drivers/staging/media/hantro/hantro_hw.h      |  1 +
 .../staging/media/hantro/hantro_postproc.c    | 31 +++++++++++++++++++
 drivers/staging/media/hantro/imx8m_vpu_hw.c   | 11 +++++++
 4 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/hantro/hantro_g2_vp9_dec.c b/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
index 45a7be4a43fa..23463f2c10f4 100644
--- a/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
@@ -152,7 +152,7 @@ static void config_output(struct hantro_ctx *ctx,
 	hantro_reg_write(ctx->dev, &g2_out_dis, 0);
 	hantro_reg_write(ctx->dev, &g2_output_format, 0);
 
-	luma_addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 0);
+	luma_addr = hantro_get_dec_buf_addr(ctx, &dst->base.vb.vb2_buf);
 	hantro_write_addr(ctx->dev, G2_ADDR_DST, luma_addr);
 
 	chroma_addr = luma_addr + chroma_offset(ctx, dec_params);
@@ -191,7 +191,7 @@ static void config_ref(struct hantro_ctx *ctx,
 	hantro_reg_write(ctx->dev, &ref_reg->hor_scale, (refw << 14) / dst->vp9.width);
 	hantro_reg_write(ctx->dev, &ref_reg->ver_scale, (refh << 14) / dst->vp9.height);
 
-	luma_addr = vb2_dma_contig_plane_dma_addr(&buf->base.vb.vb2_buf, 0);
+	luma_addr = hantro_get_dec_buf_addr(ctx, &buf->base.vb.vb2_buf);
 	hantro_write_addr(ctx->dev, ref_reg->y_base, luma_addr);
 
 	chroma_addr = luma_addr + chroma_offset(ctx, dec_params);
@@ -236,7 +236,7 @@ static void config_ref_registers(struct hantro_ctx *ctx,
 	config_ref(ctx, dst, &ref_regs[1], dec_params, dec_params->golden_frame_ts);
 	config_ref(ctx, dst, &ref_regs[2], dec_params, dec_params->alt_frame_ts);
 
-	mv_addr = vb2_dma_contig_plane_dma_addr(&mv_ref->base.vb.vb2_buf, 0) +
+	mv_addr = hantro_get_dec_buf_addr(ctx, &mv_ref->base.vb.vb2_buf) +
 		  mv_offset(ctx, dec_params);
 	hantro_write_addr(ctx->dev, G2_REG_DMV_REF(0), mv_addr);
 
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 2961d399fd60..3d4a5dc1e6d5 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -274,6 +274,7 @@ extern const struct hantro_variant rk3399_vpu_variant;
 extern const struct hantro_variant sama5d4_vdec_variant;
 
 extern const struct hantro_postproc_ops hantro_g1_postproc_ops;
+extern const struct hantro_postproc_ops hantro_g2_postproc_ops;
 
 extern const u32 hantro_vp8_dec_mc_filter[8][6];
 
diff --git a/drivers/staging/media/hantro/hantro_postproc.c b/drivers/staging/media/hantro/hantro_postproc.c
index 4549aec08feb..bc94bf46d218 100644
--- a/drivers/staging/media/hantro/hantro_postproc.c
+++ b/drivers/staging/media/hantro/hantro_postproc.c
@@ -11,6 +11,7 @@
 #include "hantro.h"
 #include "hantro_hw.h"
 #include "hantro_g1_regs.h"
+#include "hantro_g2_regs.h"
 
 #define HANTRO_PP_REG_WRITE(vpu, reg_name, val) \
 { \
@@ -99,6 +100,21 @@ static void hantro_postproc_g1_enable(struct hantro_ctx *ctx)
 	HANTRO_PP_REG_WRITE(vpu, display_width, ctx->dst_fmt.width);
 }
 
+static void hantro_postproc_g2_enable(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct vb2_v4l2_buffer *dst_buf;
+	size_t chroma_offset = ctx->dst_fmt.width * ctx->dst_fmt.height;
+	dma_addr_t dst_dma;
+
+	dst_buf = hantro_get_dst_buf(ctx);
+	dst_dma = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+
+	hantro_write_addr(vpu, G2_RASTER_SCAN, dst_dma);
+	hantro_write_addr(vpu, G2_RASTER_SCAN_CHR, dst_dma + chroma_offset);
+	hantro_reg_write(vpu, &g2_out_rs_e, 1);
+}
+
 void hantro_postproc_free(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
@@ -127,6 +143,9 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)
 	if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
 		buf_size += hantro_h264_mv_size(ctx->dst_fmt.width,
 						ctx->dst_fmt.height);
+	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME)
+		buf_size += hantro_vp9_mv_size(ctx->dst_fmt.width,
+					       ctx->dst_fmt.height);
 
 	for (i = 0; i < num_buffers; ++i) {
 		struct hantro_aux_buf *priv = &ctx->postproc.dec_q[i];
@@ -152,6 +171,13 @@ static void hantro_postproc_g1_disable(struct hantro_ctx *ctx)
 	HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x0);
 }
 
+static void hantro_postproc_g2_disable(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+
+	hantro_reg_write(vpu, &g2_out_rs_e, 0);
+}
+
 void hantro_postproc_disable(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
@@ -172,3 +198,8 @@ const struct hantro_postproc_ops hantro_g1_postproc_ops = {
 	.enable = hantro_postproc_g1_enable,
 	.disable = hantro_postproc_g1_disable,
 };
+
+const struct hantro_postproc_ops hantro_g2_postproc_ops = {
+	.enable = hantro_postproc_g2_enable,
+	.disable = hantro_postproc_g2_disable,
+};
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index 455a107ffb02..1a43f6fceef9 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -132,6 +132,14 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {
 	},
 };
 
+static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.codec_mode = HANTRO_MODE_NONE,
+		.postprocessed = true,
+	},
+};
+
 static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
 	{
 		.fourcc = V4L2_PIX_FMT_NV12_4L4,
@@ -301,6 +309,9 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
 	.dec_offset = 0x0,
 	.dec_fmts = imx8m_vpu_g2_dec_fmts,
 	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts),
+	.postproc_fmts = imx8m_vpu_g2_postproc_fmts,
+	.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_g2_postproc_fmts),
+	.postproc_ops = &hantro_g2_postproc_ops,
 	.codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,
 	.codec_ops = imx8mq_vpu_g2_codec_ops,
 	.init = imx8mq_vpu_hw_init,
-- 
2.17.1



From andrzej.p at collabora.com  Thu Aug  5 07:42:45 2021
From: andrzej.p at collabora.com (Andrzej Pietrasiewicz)
Date: Thu,  5 Aug 2021 16:42:45 +0200
Subject: [PATCH v3 09/10] media: hantro: Support VP9 on the G2 core
In-Reply-To: <20210805144246.11998-1-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
Message-ID: <20210805144246.11998-10-andrzej.p@collabora.com>

VeriSilicon Hantro G2 core supports VP9 codec.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
---
 drivers/staging/media/hantro/Kconfig          |   1 +
 drivers/staging/media/hantro/Makefile         |   6 +-
 drivers/staging/media/hantro/hantro.h         |  26 +
 drivers/staging/media/hantro/hantro_drv.c     |  18 +-
 drivers/staging/media/hantro/hantro_g2_regs.h |  97 ++
 .../staging/media/hantro/hantro_g2_vp9_dec.c  | 978 ++++++++++++++++++
 drivers/staging/media/hantro/hantro_hw.h      |  67 ++
 drivers/staging/media/hantro/hantro_v4l2.c    |   6 +
 drivers/staging/media/hantro/hantro_vp9.c     | 240 +++++
 drivers/staging/media/hantro/hantro_vp9.h     | 103 ++
 drivers/staging/media/hantro/imx8m_vpu_hw.c   |  22 +-
 11 files changed, 1560 insertions(+), 4 deletions(-)
 create mode 100644 drivers/staging/media/hantro/hantro_g2_vp9_dec.c
 create mode 100644 drivers/staging/media/hantro/hantro_vp9.c
 create mode 100644 drivers/staging/media/hantro/hantro_vp9.h

diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig
index 20b1f6d7b69c..00a57d88c92e 100644
--- a/drivers/staging/media/hantro/Kconfig
+++ b/drivers/staging/media/hantro/Kconfig
@@ -9,6 +9,7 @@ config VIDEO_HANTRO
 	select VIDEOBUF2_VMALLOC
 	select V4L2_MEM2MEM_DEV
 	select V4L2_H264
+	select V4L2_VP9
 	help
 	  Support for the Hantro IP based Video Processing Units present on
 	  Rockchip and NXP i.MX8M SoCs, which accelerate video and image
diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile
index fe6d84871d07..28af0a1ee4bf 100644
--- a/drivers/staging/media/hantro/Makefile
+++ b/drivers/staging/media/hantro/Makefile
@@ -10,9 +10,10 @@ hantro-vpu-y += \
 		hantro_g1.o \
 		hantro_g1_h264_dec.o \
 		hantro_g1_mpeg2_dec.o \
-		hantro_g2_hevc_dec.o \
 		hantro_g1_vp8_dec.o \
 		hantro_g2.o \
+		hantro_g2_hevc_dec.o \
+		hantro_g2_vp9_dec.o \
 		rockchip_vpu2_hw_jpeg_enc.o \
 		rockchip_vpu2_hw_h264_dec.o \
 		rockchip_vpu2_hw_mpeg2_dec.o \
@@ -21,7 +22,8 @@ hantro-vpu-y += \
 		hantro_h264.o \
 		hantro_hevc.o \
 		hantro_mpeg2.o \
-		hantro_vp8.o
+		hantro_vp8.o \
+		hantro_vp9.o
 
 hantro-vpu-$(CONFIG_VIDEO_HANTRO_IMX8M) += \
 		imx8m_vpu_hw.o
diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
index d91eb2b1c509..1e8c1a6e3eb0 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/staging/media/hantro/hantro.h
@@ -36,6 +36,7 @@ struct hantro_postproc_ops;
 #define HANTRO_VP8_DECODER	BIT(17)
 #define HANTRO_H264_DECODER	BIT(18)
 #define HANTRO_HEVC_DECODER	BIT(19)
+#define HANTRO_VP9_DECODER	BIT(20)
 #define HANTRO_DECODERS		0xffff0000
 
 /**
@@ -110,6 +111,7 @@ enum hantro_codec_mode {
 	HANTRO_MODE_MPEG2_DEC,
 	HANTRO_MODE_VP8_DEC,
 	HANTRO_MODE_HEVC_DEC,
+	HANTRO_MODE_VP9_DEC,
 };
 
 /*
@@ -223,6 +225,7 @@ struct hantro_dev {
  * @mpeg2_dec:		MPEG-2-decoding context.
  * @vp8_dec:		VP8-decoding context.
  * @hevc_dec:		HEVC-decoding context.
+ * @vp9_dec:		VP9-decoding context.
  */
 struct hantro_ctx {
 	struct hantro_dev *dev;
@@ -250,6 +253,7 @@ struct hantro_ctx {
 		struct hantro_mpeg2_dec_hw_ctx mpeg2_dec;
 		struct hantro_vp8_dec_hw_ctx vp8_dec;
 		struct hantro_hevc_dec_hw_ctx hevc_dec;
+		struct hantro_vp9_dec_hw_ctx vp9_dec;
 	};
 };
 
@@ -299,6 +303,22 @@ struct hantro_postproc_regs {
 	struct hantro_reg display_width;
 };
 
+struct hantro_vp9_decoded_buffer_info {
+	/* Info needed when the decoded frame serves as a reference frame. */
+	unsigned short width;
+	unsigned short height;
+	u32 bit_depth : 4;
+};
+
+struct hantro_decoded_buffer {
+	/* Must be the first field in this struct. */
+	struct v4l2_m2m_buffer base;
+
+	union {
+		struct hantro_vp9_decoded_buffer_info vp9;
+	};
+};
+
 /* Logging helpers */
 
 /**
@@ -436,6 +456,12 @@ hantro_get_dec_buf_addr(struct hantro_ctx *ctx, struct vb2_buffer *vb)
 	return vb2_dma_contig_plane_dma_addr(vb, 0);
 }
 
+static inline struct hantro_decoded_buffer *
+vb2_to_hantro_decoded_buf(struct vb2_buffer *buf)
+{
+	return container_of(buf, struct hantro_decoded_buffer, base.vb.vb2_buf);
+}
+
 void hantro_postproc_disable(struct hantro_ctx *ctx);
 void hantro_postproc_enable(struct hantro_ctx *ctx);
 void hantro_postproc_free(struct hantro_ctx *ctx);
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index 8a2edd67f2c6..0d1f3914f670 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -232,7 +232,7 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
 	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
 	dst_vq->drv_priv = ctx;
 	dst_vq->ops = &hantro_queue_ops;
-	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+	dst_vq->buf_struct_size = sizeof(struct hantro_decoded_buffer);
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	dst_vq->lock = &ctx->dev->vpu_mutex;
 	dst_vq->dev = ctx->dev->v4l2_dev.dev;
@@ -266,6 +266,12 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
 		if (sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED)
 			/* No scaling support */
 			return -EINVAL;
+	} else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
+		const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
+
+		/* We only support profile 0 */
+		if (dec_params->profile != 0)
+			return -EINVAL;
 	}
 	return 0;
 }
@@ -459,6 +465,16 @@ static const struct hantro_ctrl controls[] = {
 			.step = 1,
 			.ops = &hantro_hevc_ctrl_ops,
 		},
+	}, {
+		.codec = HANTRO_VP9_DECODER,
+		.cfg = {
+			.id = V4L2_CID_STATELESS_VP9_FRAME,
+		},
+	}, {
+		.codec = HANTRO_VP9_DECODER,
+		.cfg = {
+			.id = V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS,
+		},
 	},
 };
 
diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h
index 0ac0ba375e80..21ca21648614 100644
--- a/drivers/staging/media/hantro/hantro_g2_regs.h
+++ b/drivers/staging/media/hantro/hantro_g2_regs.h
@@ -28,6 +28,7 @@
 #define G2_REG_INTERRUPT_DEC_E		BIT(0)
 
 #define HEVC_DEC_MODE			0xc
+#define VP9_DEC_MODE			0xd
 
 #define BUS_WIDTH_32			0
 #define BUS_WIDTH_64			1
@@ -49,6 +50,7 @@
 #define g2_pic_height_in_cbs	G2_DEC_REG(4, 6,  0x1fff)
 #define g2_num_ref_frames	G2_DEC_REG(4, 0,  0x1f)
 
+#define g2_start_bit		G2_DEC_REG(5, 25, 0x7f)
 #define g2_scaling_list_e	G2_DEC_REG(5, 24, 0x1)
 #define g2_cb_qp_offset		G2_DEC_REG(5, 19, 0x1f)
 #define g2_cr_qp_offset		G2_DEC_REG(5, 14, 0x1f)
@@ -84,6 +86,7 @@
 #define g2_bit_depth_y_minus8	G2_DEC_REG(8, 6,  0x3)
 #define g2_bit_depth_c_minus8	G2_DEC_REG(8, 4,  0x3)
 #define g2_output_8_bits	G2_DEC_REG(8, 3,  0x1)
+#define g2_output_format	G2_DEC_REG(8, 0,  0x7)
 
 #define g2_refidx1_active	G2_DEC_REG(9, 19, 0x1f)
 #define g2_refidx0_active	G2_DEC_REG(9, 14, 0x1f)
@@ -96,6 +99,14 @@
 #define g2_tile_e		G2_DEC_REG(10, 1,  0x1)
 #define g2_entropy_sync_e	G2_DEC_REG(10, 0,  0x1)
 
+#define vp9_transform_mode	G2_DEC_REG(11, 27, 0x7)
+#define vp9_filt_sharpness	G2_DEC_REG(11, 21, 0x7)
+#define vp9_mcomp_filt_type	G2_DEC_REG(11,  8, 0x7)
+#define vp9_high_prec_mv_e	G2_DEC_REG(11,  7, 0x1)
+#define vp9_comp_pred_mode	G2_DEC_REG(11,  4, 0x3)
+#define vp9_gref_sign_bias	G2_DEC_REG(11,  2, 0x1)
+#define vp9_aref_sign_bias	G2_DEC_REG(11,  0, 0x1)
+
 #define g2_refer_lterm_e	G2_DEC_REG(12, 16, 0xffff)
 #define g2_min_cb_size		G2_DEC_REG(12, 13, 0x7)
 #define g2_max_cb_size		G2_DEC_REG(12, 10, 0x7)
@@ -154,6 +165,50 @@
 #define g2_partial_ctb_y	G2_DEC_REG(20, 30, 0x1)
 #define g2_pic_width_4x4	G2_DEC_REG(20, 16, 0xfff)
 #define g2_pic_height_4x4	G2_DEC_REG(20, 0,  0xfff)
+
+#define vp9_qp_delta_y_dc	G2_DEC_REG(13, 23, 0x3f)
+#define vp9_qp_delta_ch_dc	G2_DEC_REG(13, 17, 0x3f)
+#define vp9_qp_delta_ch_ac	G2_DEC_REG(13, 11, 0x3f)
+#define vp9_last_sign_bias	G2_DEC_REG(13, 10, 0x1)
+#define vp9_lossless_e		G2_DEC_REG(13,  9, 0x1)
+#define vp9_comp_pred_var_ref1	G2_DEC_REG(13,  7, 0x3)
+#define vp9_comp_pred_var_ref0	G2_DEC_REG(13,  5, 0x3)
+#define vp9_comp_pred_fixed_ref	G2_DEC_REG(13,  3, 0x3)
+#define vp9_segment_temp_upd_e	G2_DEC_REG(13,  2, 0x1)
+#define vp9_segment_upd_e	G2_DEC_REG(13,  1, 0x1)
+#define vp9_segment_e		G2_DEC_REG(13,  0, 0x1)
+
+#define vp9_filt_level		G2_DEC_REG(14, 18, 0x3f)
+#define vp9_refpic_seg0		G2_DEC_REG(14, 15, 0x7)
+#define vp9_skip_seg0		G2_DEC_REG(14, 14, 0x1)
+#define vp9_filt_level_seg0	G2_DEC_REG(14,  8, 0x3f)
+#define vp9_quant_seg0		G2_DEC_REG(14,  0, 0xff)
+
+#define vp9_refpic_seg1		G2_DEC_REG(15, 15, 0x7)
+#define vp9_skip_seg1		G2_DEC_REG(15, 14, 0x1)
+#define vp9_filt_level_seg1	G2_DEC_REG(15,  8, 0x3f)
+#define vp9_quant_seg1		G2_DEC_REG(15,  0, 0xff)
+
+#define vp9_refpic_seg2		G2_DEC_REG(16, 15, 0x7)
+#define vp9_skip_seg2		G2_DEC_REG(16, 14, 0x1)
+#define vp9_filt_level_seg2	G2_DEC_REG(16,  8, 0x3f)
+#define vp9_quant_seg2		G2_DEC_REG(16,  0, 0xff)
+
+#define vp9_refpic_seg3		G2_DEC_REG(17, 15, 0x7)
+#define vp9_skip_seg3		G2_DEC_REG(17, 14, 0x1)
+#define vp9_filt_level_seg3	G2_DEC_REG(17,  8, 0x3f)
+#define vp9_quant_seg3		G2_DEC_REG(17,  0, 0xff)
+
+#define vp9_refpic_seg4		G2_DEC_REG(18, 15, 0x7)
+#define vp9_skip_seg4		G2_DEC_REG(18, 14, 0x1)
+#define vp9_filt_level_seg4	G2_DEC_REG(18,  8, 0x3f)
+#define vp9_quant_seg4		G2_DEC_REG(18,  0, 0xff)
+
+#define vp9_refpic_seg5		G2_DEC_REG(19, 15, 0x7)
+#define vp9_skip_seg5		G2_DEC_REG(19, 14, 0x1)
+#define vp9_filt_level_seg5	G2_DEC_REG(19,  8, 0x3f)
+#define vp9_quant_seg5		G2_DEC_REG(19,  0, 0xff)
+
 #define hevc_cur_poc_00		G2_DEC_REG(46, 24, 0xff)
 #define hevc_cur_poc_01		G2_DEC_REG(46, 16, 0xff)
 #define hevc_cur_poc_02		G2_DEC_REG(46, 8,  0xff)
@@ -174,6 +229,44 @@
 #define hevc_cur_poc_14		G2_DEC_REG(49, 8,  0xff)
 #define hevc_cur_poc_15		G2_DEC_REG(49, 0,  0xff)
 
+#define vp9_refpic_seg6		G2_DEC_REG(31, 15, 0x7)
+#define vp9_skip_seg6		G2_DEC_REG(31, 14, 0x1)
+#define vp9_filt_level_seg6	G2_DEC_REG(31,  8, 0x3f)
+#define vp9_quant_seg6		G2_DEC_REG(31,  0, 0xff)
+
+#define vp9_refpic_seg7		G2_DEC_REG(32, 15, 0x7)
+#define vp9_skip_seg7		G2_DEC_REG(32, 14, 0x1)
+#define vp9_filt_level_seg7	G2_DEC_REG(32,  8, 0x3f)
+#define vp9_quant_seg7		G2_DEC_REG(32,  0, 0xff)
+
+#define vp9_lref_width		G2_DEC_REG(33, 16, 0xffff)
+#define vp9_lref_height		G2_DEC_REG(33,  0, 0xffff)
+
+#define vp9_gref_width		G2_DEC_REG(34, 16, 0xffff)
+#define vp9_gref_height		G2_DEC_REG(34,  0, 0xffff)
+
+#define vp9_aref_width		G2_DEC_REG(35, 16, 0xffff)
+#define vp9_aref_height		G2_DEC_REG(35,  0, 0xffff)
+
+#define vp9_lref_hor_scale	G2_DEC_REG(36, 16, 0xffff)
+#define vp9_lref_ver_scale	G2_DEC_REG(36,  0, 0xffff)
+
+#define vp9_gref_hor_scale	G2_DEC_REG(37, 16, 0xffff)
+#define vp9_gref_ver_scale	G2_DEC_REG(37,  0, 0xffff)
+
+#define vp9_aref_hor_scale	G2_DEC_REG(38, 16, 0xffff)
+#define vp9_aref_ver_scale	G2_DEC_REG(38,  0, 0xffff)
+
+#define vp9_filt_ref_adj_0	G2_DEC_REG(46, 24, 0x7f)
+#define vp9_filt_ref_adj_1	G2_DEC_REG(46, 16, 0x7f)
+#define vp9_filt_ref_adj_2	G2_DEC_REG(46,  8, 0x7f)
+#define vp9_filt_ref_adj_3	G2_DEC_REG(46,  0, 0x7f)
+
+#define vp9_filt_mb_adj_0	G2_DEC_REG(47, 24, 0x7f)
+#define vp9_filt_mb_adj_1	G2_DEC_REG(47, 16, 0x7f)
+#define vp9_filt_mb_adj_2	G2_DEC_REG(47,  8, 0x7f)
+#define vp9_filt_mb_adj_3	G2_DEC_REG(47,  0, 0x7f)
+
 #define g2_apf_threshold	G2_DEC_REG(55, 0, 0xffff)
 
 #define g2_clk_gate_e		G2_DEC_REG(58, 16, 0x1)
@@ -186,6 +279,8 @@
 
 #define G2_ADDR_DST		(G2_SWREG(65))
 #define G2_REG_ADDR_REF(i)	(G2_SWREG(67)  + ((i) * 0x8))
+#define VP9_ADDR_SEGMENT_WRITE	(G2_SWREG(79))
+#define VP9_ADDR_SEGMENT_READ	(G2_SWREG(81))
 #define G2_ADDR_DST_CHR		(G2_SWREG(99))
 #define G2_REG_CHR_REF(i)	(G2_SWREG(101) + ((i) * 0x8))
 #define G2_ADDR_DST_MV		(G2_SWREG(133))
@@ -193,6 +288,8 @@
 #define G2_ADDR_TILE_SIZE	(G2_SWREG(167))
 #define G2_ADDR_STR		(G2_SWREG(169))
 #define HEVC_SCALING_LIST	(G2_SWREG(171))
+#define VP9_ADDR_CTR		(G2_SWREG(171))
+#define VP9_ADDR_PROBS		(G2_SWREG(173))
 #define G2_RASTER_SCAN		(G2_SWREG(175))
 #define G2_RASTER_SCAN_CHR	(G2_SWREG(177))
 #define G2_TILE_FILTER		(G2_SWREG(179))
diff --git a/drivers/staging/media/hantro/hantro_g2_vp9_dec.c b/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
new file mode 100644
index 000000000000..45a7be4a43fa
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
@@ -0,0 +1,978 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hantro VP9 codec driver
+ *
+ * Copyright (C) 2021 Collabora Ltd.
+ */
+#include "media/videobuf2-core.h"
+#include "media/videobuf2-dma-contig.h"
+#include "media/videobuf2-v4l2.h"
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-vp9.h>
+
+#include "hantro.h"
+#include "hantro_vp9.h"
+#include "hantro_g2_regs.h"
+
+#define G2_ALIGN 16
+
+enum hantro_ref_frames {
+	INTRA_FRAME = 0,
+	LAST_FRAME = 1,
+	GOLDEN_FRAME = 2,
+	ALTREF_FRAME = 3,
+	MAX_REF_FRAMES = 4
+};
+
+static int start_prepare_run(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame **dec_params)
+{
+	const struct v4l2_ctrl_vp9_compressed_hdr_probs *prob_updates;
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	struct v4l2_ctrl *ctrl;
+	unsigned int fctx_idx;
+
+	/* v4l2-specific stuff */
+	hantro_start_prepare_run(ctx);
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_handler, V4L2_CID_STATELESS_VP9_FRAME);
+	if (WARN_ON(!ctrl))
+		return -EINVAL;
+	*dec_params = ctrl->p_cur.p;
+
+	ctrl = v4l2_ctrl_find(&ctx->ctrl_handler, V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS);
+	if (WARN_ON(!ctrl))
+		return -EINVAL;
+	prob_updates = ctrl->p_cur.p;
+
+	/*
+	 * vp9 stuff
+	 *
+	 * by this point the userspace has done all parts of 6.2 uncompressed_header()
+	 * except this fragment:
+	 * if ( FrameIsIntra || error_resilient_mode ) {
+	 *	setup_past_independence ( )
+	 *	if ( frame_type == KEY_FRAME || error_resilient_mode == 1 ||
+	 *	     reset_frame_context == 3 ) {
+	 *		for ( i = 0; i < 4; i ++ ) {
+	 *			save_probs( i )
+	 *		}
+	 *	} else if ( reset_frame_context == 2 ) {
+	 *		save_probs( frame_context_idx )
+	 *	}
+	 *	frame_context_idx = 0
+	 * }
+	 */
+	fctx_idx = v4l2_vp9_reset_frame_ctx(*dec_params, vp9_ctx->frame_context);
+	vp9_ctx->cur.frame_context_idx = fctx_idx;
+
+	/* 6.1 frame(sz): load_probs() and load_probs2() */
+	vp9_ctx->probability_tables = vp9_ctx->frame_context[fctx_idx];
+
+	/*
+	 * The userspace has also performed 6.3 compressed_header(), but handling the
+	 * probs in a special way. All probs which need updating, except MV-related,
+	 * have been read from the bitstream and translated through inv_map_table[],
+	 * but no 6.3.6 inv_recenter_nonneg(v, m) has been performed. The values passed
+	 * by userspace are either translated values (there are no 0 values in
+	 * inv_map_table[]), or zero to indicate no update. All MV-related probs which need
+	 * updating have been read from the bitstream and (mv_prob << 1) | 1 has been
+	 * performed. The values passed by userspace are either new values
+	 * to replace old ones (the above mentioned shift and bitwise or never result in
+	 * a zero) or zero to indicate no update.
+	 * fw_update_probs() performs actual probs updates or leaves probs as-is
+	 * for values for which a zero was passed from userspace.
+	 */
+	v4l2_vp9_fw_update_probs(&vp9_ctx->probability_tables, prob_updates, *dec_params);
+
+	return 0;
+}
+
+static size_t chroma_offset(const struct hantro_ctx *ctx,
+			    const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	int bytes_per_pixel = dec_params->bit_depth == 8 ? 1 : 2;
+
+	return ctx->src_fmt.width * ctx->src_fmt.height * bytes_per_pixel;
+}
+
+static size_t mv_offset(const struct hantro_ctx *ctx,
+			const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	size_t cr_offset = chroma_offset(ctx, dec_params);
+
+	return ALIGN((cr_offset * 3) / 2, G2_ALIGN);
+}
+
+static struct hantro_decoded_buffer *
+get_ref_buf(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 timestamp)
+{
+	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
+	struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
+	int buf_idx;
+
+	/*
+	 * If a ref is unused or invalid, address of current destination
+	 * buffer is returned.
+	 */
+	buf_idx = vb2_find_timestamp(cap_q, timestamp, 0);
+	if (buf_idx < 0)
+		return vb2_to_hantro_decoded_buf(&dst->vb2_buf);
+
+	return vb2_to_hantro_decoded_buf(vb2_get_buffer(cap_q, buf_idx));
+}
+
+static void update_dec_buf_info(struct hantro_decoded_buffer *buf,
+				const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	buf->vp9.width = dec_params->frame_width_minus_1 + 1;
+	buf->vp9.height = dec_params->frame_height_minus_1 + 1;
+	buf->vp9.bit_depth = dec_params->bit_depth;
+}
+
+static void update_ctx_cur_info(struct hantro_vp9_dec_hw_ctx *vp9_ctx,
+				struct hantro_decoded_buffer *buf,
+				const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	vp9_ctx->cur.valid = true;
+	vp9_ctx->cur.reference_mode = dec_params->reference_mode;
+	vp9_ctx->cur.tx_mode = dec_params->tx_mode;
+	vp9_ctx->cur.interpolation_filter = dec_params->interpolation_filter;
+	vp9_ctx->cur.flags = dec_params->flags;
+	vp9_ctx->cur.timestamp = buf->base.vb.vb2_buf.timestamp;
+}
+
+static void config_output(struct hantro_ctx *ctx,
+			  struct hantro_decoded_buffer *dst,
+			  const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	dma_addr_t luma_addr, chroma_addr, mv_addr;
+
+	hantro_reg_write(ctx->dev, &g2_out_dis, 0);
+	hantro_reg_write(ctx->dev, &g2_output_format, 0);
+
+	luma_addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 0);
+	hantro_write_addr(ctx->dev, G2_ADDR_DST, luma_addr);
+
+	chroma_addr = luma_addr + chroma_offset(ctx, dec_params);
+	hantro_write_addr(ctx->dev, G2_ADDR_DST_CHR, chroma_addr);
+
+	mv_addr = luma_addr + mv_offset(ctx, dec_params);
+	hantro_write_addr(ctx->dev, G2_ADDR_DST_MV, mv_addr);
+}
+
+struct hantro_vp9_ref_reg {
+	const struct hantro_reg width;
+	const struct hantro_reg height;
+	const struct hantro_reg hor_scale;
+	const struct hantro_reg ver_scale;
+	u32 y_base;
+	u32 c_base;
+};
+
+static void config_ref(struct hantro_ctx *ctx,
+		       struct hantro_decoded_buffer *dst,
+		       const struct hantro_vp9_ref_reg *ref_reg,
+		       const struct v4l2_ctrl_vp9_frame *dec_params,
+		       u64 ref_ts)
+{
+	struct hantro_decoded_buffer *buf;
+	dma_addr_t luma_addr, chroma_addr;
+	u32 refw, refh;
+
+	buf = get_ref_buf(ctx, &dst->base.vb, ref_ts);
+	refw = buf->vp9.width;
+	refh = buf->vp9.height;
+
+	hantro_reg_write(ctx->dev, &ref_reg->width, refw);
+	hantro_reg_write(ctx->dev, &ref_reg->height, refh);
+
+	hantro_reg_write(ctx->dev, &ref_reg->hor_scale, (refw << 14) / dst->vp9.width);
+	hantro_reg_write(ctx->dev, &ref_reg->ver_scale, (refh << 14) / dst->vp9.height);
+
+	luma_addr = vb2_dma_contig_plane_dma_addr(&buf->base.vb.vb2_buf, 0);
+	hantro_write_addr(ctx->dev, ref_reg->y_base, luma_addr);
+
+	chroma_addr = luma_addr + chroma_offset(ctx, dec_params);
+	hantro_write_addr(ctx->dev, ref_reg->c_base, chroma_addr);
+}
+
+static void config_ref_registers(struct hantro_ctx *ctx,
+				 const struct v4l2_ctrl_vp9_frame *dec_params,
+				 struct hantro_decoded_buffer *dst,
+				 struct hantro_decoded_buffer *mv_ref)
+{
+	static const struct hantro_vp9_ref_reg ref_regs[] = {
+		{
+			/* Last */
+			.width = vp9_lref_width,
+			.height = vp9_lref_height,
+			.hor_scale = vp9_lref_hor_scale,
+			.ver_scale = vp9_lref_ver_scale,
+			.y_base = G2_REG_ADDR_REF(0),
+			.c_base = G2_REG_CHR_REF(0),
+		}, {
+			/* Golden */
+			.width = vp9_gref_width,
+			.height = vp9_gref_height,
+			.hor_scale = vp9_gref_hor_scale,
+			.ver_scale = vp9_gref_ver_scale,
+			.y_base = G2_REG_ADDR_REF(4),
+			.c_base = G2_REG_CHR_REF(4),
+		}, {
+			/* Altref */
+			.width = vp9_aref_width,
+			.height = vp9_aref_height,
+			.hor_scale = vp9_aref_hor_scale,
+			.ver_scale = vp9_aref_ver_scale,
+			.y_base = G2_REG_ADDR_REF(5),
+			.c_base = G2_REG_CHR_REF(5),
+		},
+	};
+	dma_addr_t mv_addr;
+
+	config_ref(ctx, dst, &ref_regs[0], dec_params, dec_params->last_frame_ts);
+	config_ref(ctx, dst, &ref_regs[1], dec_params, dec_params->golden_frame_ts);
+	config_ref(ctx, dst, &ref_regs[2], dec_params, dec_params->alt_frame_ts);
+
+	mv_addr = vb2_dma_contig_plane_dma_addr(&mv_ref->base.vb.vb2_buf, 0) +
+		  mv_offset(ctx, dec_params);
+	hantro_write_addr(ctx->dev, G2_REG_DMV_REF(0), mv_addr);
+
+	hantro_reg_write(ctx->dev, &vp9_last_sign_bias,
+			 dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_LAST ? 1 : 0);
+
+	hantro_reg_write(ctx->dev, &vp9_gref_sign_bias,
+			 dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_GOLDEN ? 1 : 0);
+
+	hantro_reg_write(ctx->dev, &vp9_aref_sign_bias,
+			 dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_ALT ? 1 : 0);
+}
+
+static void recompute_tile_info(unsigned short *tile_info, unsigned int tiles, unsigned int sbs)
+{
+	int i;
+	unsigned int accumulated = 0;
+	unsigned int next_accumulated;
+
+	for (i = 1; i <= tiles; ++i) {
+		next_accumulated = i * sbs / tiles;
+		*tile_info++ = next_accumulated - accumulated;
+		accumulated = next_accumulated;
+	}
+}
+
+static void
+recompute_tile_rc_info(struct hantro_ctx *ctx,
+		       unsigned int tile_r, unsigned int tile_c,
+		       unsigned int sbs_r, unsigned int sbs_c)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+
+	recompute_tile_info(vp9_ctx->tile_r_info, tile_r, sbs_r);
+	recompute_tile_info(vp9_ctx->tile_c_info, tile_c, sbs_c);
+
+	vp9_ctx->last_tile_r = tile_r;
+	vp9_ctx->last_tile_c = tile_c;
+	vp9_ctx->last_sbs_r = sbs_r;
+	vp9_ctx->last_sbs_c = sbs_c;
+}
+
+static inline unsigned int first_tile_row(unsigned int tile_r, unsigned int sbs_r)
+{
+	if (tile_r == sbs_r + 1)
+		return 1;
+
+	if (tile_r == sbs_r + 2)
+		return 2;
+
+	return 0;
+}
+
+static void
+fill_tile_info(struct hantro_ctx *ctx,
+	       unsigned int tile_r, unsigned int tile_c,
+	       unsigned int sbs_r, unsigned int sbs_c,
+	       unsigned short *tile_mem)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	unsigned int i, j;
+	bool first = true;
+
+	for (i = first_tile_row(tile_r, sbs_r); i < tile_r; ++i) {
+		unsigned short r_info = vp9_ctx->tile_r_info[i];
+
+		if (first) {
+			if (i > 0)
+				r_info += vp9_ctx->tile_r_info[0];
+			if (i == 2)
+				r_info += vp9_ctx->tile_r_info[1];
+			first = false;
+		}
+		for (j = 0; j < tile_c; ++j) {
+			*tile_mem++ = vp9_ctx->tile_c_info[j];
+			*tile_mem++ = r_info;
+		}
+	}
+}
+
+static void
+config_tiles(struct hantro_ctx *ctx,
+	     const struct v4l2_ctrl_vp9_frame *dec_params,
+	     struct hantro_decoded_buffer *dst)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	struct hantro_aux_buf *misc = &vp9_ctx->misc;
+	struct hantro_aux_buf *tile_edge = &vp9_ctx->tile_edge;
+	dma_addr_t addr;
+	unsigned short *tile_mem;
+
+	addr = misc->dma + vp9_ctx->tile_info_offset;
+	hantro_write_addr(ctx->dev, G2_ADDR_TILE_SIZE, addr);
+
+	tile_mem = misc->cpu + vp9_ctx->tile_info_offset;
+	if (dec_params->tile_cols_log2 || dec_params->tile_rows_log2) {
+		unsigned int tile_r = (1 << dec_params->tile_rows_log2);
+		unsigned int tile_c = (1 << dec_params->tile_cols_log2);
+		unsigned int sbs_r = hantro_vp9_num_sbs(dst->vp9.height);
+		unsigned int sbs_c = hantro_vp9_num_sbs(dst->vp9.width);
+
+		if (tile_r != vp9_ctx->last_tile_r || tile_c != vp9_ctx->last_tile_c ||
+		    sbs_r != vp9_ctx->last_sbs_r || sbs_c != vp9_ctx->last_sbs_c)
+			recompute_tile_rc_info(ctx, tile_r, tile_c, sbs_r, sbs_c);
+
+		fill_tile_info(ctx, tile_r, tile_c, sbs_r, sbs_c, tile_mem);
+
+		hantro_reg_write(ctx->dev, &g2_tile_e, 1);
+		hantro_reg_write(ctx->dev, &g2_num_tile_cols, tile_c);
+		hantro_reg_write(ctx->dev, &g2_num_tile_rows, tile_r);
+
+		addr = tile_edge->dma;
+		hantro_write_addr(ctx->dev, G2_TILE_FILTER, addr);
+
+		addr = tile_edge->dma + vp9_ctx->bsd_ctrl_offset;
+		hantro_write_addr(ctx->dev, G2_TILE_BSD, addr);
+	} else {
+		tile_mem[0] = hantro_vp9_num_sbs(dst->vp9.width);
+		tile_mem[1] = hantro_vp9_num_sbs(dst->vp9.height);
+
+		hantro_reg_write(ctx->dev, &g2_tile_e, 0);
+		hantro_reg_write(ctx->dev, &g2_num_tile_cols, 1);
+		hantro_reg_write(ctx->dev, &g2_num_tile_rows, 1);
+	}
+}
+
+static void
+update_feat_and_flag(struct hantro_vp9_dec_hw_ctx *vp9_ctx,
+		     const struct v4l2_vp9_segmentation *seg,
+		     enum v4l2_vp9_segment_feature feature,
+		     unsigned int segid)
+{
+	u8 mask = V4L2_VP9_SEGMENT_FEATURE_ENABLED(feature);
+
+	vp9_ctx->feature_data[segid][feature] = seg->feature_data[segid][feature];
+	vp9_ctx->feature_enabled[segid] &= ~mask;
+	vp9_ctx->feature_enabled[segid] |= (seg->feature_enabled[segid] & mask);
+}
+
+static inline s16 clip3(s16 x, s16 y, s16 z)
+{
+	return (z < x) ? x : (z > y) ? y : z;
+}
+
+static s16 feat_val_clip3(s16 feat_val, s16 feature_data, bool absolute, u8 clip)
+{
+	if (absolute)
+		return feature_data;
+
+	return clip3(0, 255, feat_val + feature_data);
+}
+
+static void config_segment(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	const struct v4l2_vp9_segmentation *seg;
+	s16 feat_val;
+	unsigned char feat_id;
+	unsigned int segid;
+	bool segment_enabled, absolute, update_data;
+
+	static const struct hantro_reg seg_regs[8][V4L2_VP9_SEG_LVL_MAX] = {
+		{ vp9_quant_seg0, vp9_filt_level_seg0, vp9_refpic_seg0, vp9_skip_seg0 },
+		{ vp9_quant_seg1, vp9_filt_level_seg1, vp9_refpic_seg1, vp9_skip_seg1 },
+		{ vp9_quant_seg2, vp9_filt_level_seg2, vp9_refpic_seg2, vp9_skip_seg2 },
+		{ vp9_quant_seg3, vp9_filt_level_seg3, vp9_refpic_seg3, vp9_skip_seg3 },
+		{ vp9_quant_seg4, vp9_filt_level_seg4, vp9_refpic_seg4, vp9_skip_seg4 },
+		{ vp9_quant_seg5, vp9_filt_level_seg5, vp9_refpic_seg5, vp9_skip_seg5 },
+		{ vp9_quant_seg6, vp9_filt_level_seg6, vp9_refpic_seg6, vp9_skip_seg6 },
+		{ vp9_quant_seg7, vp9_filt_level_seg7, vp9_refpic_seg7, vp9_skip_seg7 },
+	};
+
+	segment_enabled = !!(dec_params->seg.flags & V4L2_VP9_SEGMENTATION_FLAG_ENABLED);
+	hantro_reg_write(ctx->dev, &vp9_segment_e, segment_enabled);
+	hantro_reg_write(ctx->dev, &vp9_segment_upd_e,
+			 !!(dec_params->seg.flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP));
+	hantro_reg_write(ctx->dev, &vp9_segment_temp_upd_e,
+			 !!(dec_params->seg.flags & V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE));
+
+	seg = &dec_params->seg;
+	absolute = !!(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE);
+	update_data = !!(seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA);
+
+	for (segid = 0; segid < 8; ++segid) {
+		/* Quantizer segment feature */
+		feat_id = V4L2_VP9_SEG_LVL_ALT_Q;
+		feat_val = dec_params->quant.base_q_idx;
+		if (segment_enabled) {
+			if (update_data)
+				update_feat_and_flag(vp9_ctx, seg, feat_id, segid);
+			if (v4l2_vp9_seg_feat_enabled(vp9_ctx->feature_enabled, feat_id, segid))
+				feat_val = feat_val_clip3(feat_val,
+							  vp9_ctx->feature_data[segid][feat_id],
+							  absolute, 255);
+		}
+		hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], feat_val);
+
+		/* Loop filter segment feature */
+		feat_id = V4L2_VP9_SEG_LVL_ALT_L;
+		feat_val = dec_params->lf.level;
+		if (segment_enabled) {
+			if (update_data)
+				update_feat_and_flag(vp9_ctx, seg, feat_id, segid);
+			if (v4l2_vp9_seg_feat_enabled(vp9_ctx->feature_enabled, feat_id, segid))
+				feat_val = feat_val_clip3(feat_val,
+							  vp9_ctx->feature_data[segid][feat_id],
+							  absolute, 63);
+		}
+		hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], feat_val);
+
+		/* Reference frame segment feature */
+		feat_id = V4L2_VP9_SEG_LVL_REF_FRAME;
+		feat_val = 0;
+		if (segment_enabled) {
+			if (update_data)
+				update_feat_and_flag(vp9_ctx, seg, feat_id, segid);
+			if (!(dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
+			    v4l2_vp9_seg_feat_enabled(vp9_ctx->feature_enabled, feat_id, segid))
+				feat_val = vp9_ctx->feature_data[segid][feat_id] + 1;
+		}
+		hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], feat_val);
+
+		/* Skip segment feature */
+		feat_id = V4L2_VP9_SEG_LVL_SKIP;
+		feat_val = 0;
+		if (segment_enabled) {
+			if (update_data)
+				update_feat_and_flag(vp9_ctx, seg, feat_id, segid);
+			feat_val = v4l2_vp9_seg_feat_enabled(vp9_ctx->feature_enabled,
+							     feat_id, segid) ? 1 : 0;
+		}
+		hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], feat_val);
+	}
+}
+
+static void config_loop_filter(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	bool d = dec_params->lf.flags & V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED;
+
+	hantro_reg_write(ctx->dev, &vp9_filt_level, dec_params->lf.level);
+	hantro_reg_write(ctx->dev, &g2_out_filtering_dis, dec_params->lf.level == 0);
+	hantro_reg_write(ctx->dev, &vp9_filt_sharpness, dec_params->lf.sharpness);
+
+	hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_0, d ? dec_params->lf.ref_deltas[0] : 0);
+	hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_1, d ? dec_params->lf.ref_deltas[1] : 0);
+	hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_2, d ? dec_params->lf.ref_deltas[2] : 0);
+	hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_3, d ? dec_params->lf.ref_deltas[3] : 0);
+	hantro_reg_write(ctx->dev, &vp9_filt_mb_adj_0, d ? dec_params->lf.mode_deltas[0] : 0);
+	hantro_reg_write(ctx->dev, &vp9_filt_mb_adj_1, d ? dec_params->lf.mode_deltas[1] : 0);
+}
+
+static void config_picture_dimensions(struct hantro_ctx *ctx, struct hantro_decoded_buffer *dst)
+{
+	u32 pic_w_4x4, pic_h_4x4;
+
+	hantro_reg_write(ctx->dev, &g2_pic_width_in_cbs, (dst->vp9.width + 7) / 8);
+	hantro_reg_write(ctx->dev, &g2_pic_height_in_cbs, (dst->vp9.height + 7) / 8);
+	pic_w_4x4 = roundup(dst->vp9.width, 8) >> 2;
+	pic_h_4x4 = roundup(dst->vp9.height, 8) >> 2;
+	hantro_reg_write(ctx->dev, &g2_pic_width_4x4, pic_w_4x4);
+	hantro_reg_write(ctx->dev, &g2_pic_height_4x4, pic_h_4x4);
+}
+
+static void
+config_bit_depth(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	hantro_reg_write(ctx->dev, &g2_bit_depth_y_minus8, dec_params->bit_depth - 8);
+	hantro_reg_write(ctx->dev, &g2_bit_depth_c_minus8, dec_params->bit_depth - 8);
+}
+
+static inline bool is_lossless(const struct v4l2_vp9_quantization *quant)
+{
+	return quant->base_q_idx == 0 && quant->delta_q_uv_ac == 0 &&
+	       quant->delta_q_uv_dc == 0 && quant->delta_q_y_dc == 0;
+}
+
+static void
+config_quant(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	hantro_reg_write(ctx->dev, &vp9_qp_delta_y_dc, dec_params->quant.delta_q_y_dc);
+	hantro_reg_write(ctx->dev, &vp9_qp_delta_ch_dc, dec_params->quant.delta_q_uv_dc);
+	hantro_reg_write(ctx->dev, &vp9_qp_delta_ch_ac, dec_params->quant.delta_q_uv_ac);
+	hantro_reg_write(ctx->dev, &vp9_lossless_e, is_lossless(&dec_params->quant));
+}
+
+static u32
+hantro_interp_filter_from_v4l2(enum v4l2_vp9_interpolation_filter interpolation_filter)
+{
+	switch (interpolation_filter) {
+	case V4L2_VP9_INTERP_FILTER_EIGHTTAP:
+		return 0x1;
+	case V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH:
+		return 0;
+	case V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP:
+		return 0x2;
+	case V4L2_VP9_INTERP_FILTER_BILINEAR:
+		return 0x3;
+	case V4L2_VP9_INTERP_FILTER_SWITCHABLE:
+		return 0x4;
+	}
+
+	return 0;
+}
+
+static void
+config_others(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params,
+	      bool intra_only, bool resolution_change)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+
+	hantro_reg_write(ctx->dev, &g2_idr_pic_e, intra_only);
+
+	hantro_reg_write(ctx->dev, &vp9_transform_mode, dec_params->tx_mode);
+
+	hantro_reg_write(ctx->dev, &vp9_mcomp_filt_type, intra_only ?
+		0 : hantro_interp_filter_from_v4l2(dec_params->interpolation_filter));
+
+	hantro_reg_write(ctx->dev, &vp9_high_prec_mv_e,
+			 !!(dec_params->flags & V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV));
+
+	hantro_reg_write(ctx->dev, &vp9_comp_pred_mode, dec_params->reference_mode);
+
+	hantro_reg_write(ctx->dev, &g2_tempor_mvp_e,
+			 !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
+			 !(dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
+			 !(vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
+			 !(dec_params->flags & V4L2_VP9_FRAME_FLAG_INTRA_ONLY) &&
+			 !resolution_change &&
+			 vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_SHOW_FRAME
+	);
+
+	hantro_reg_write(ctx->dev, &g2_write_mvs_e,
+			 !(dec_params->flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME));
+}
+
+static void
+config_compound_reference(struct hantro_ctx *ctx,
+			  const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	u32 comp_fixed_ref, comp_var_ref[2];
+	bool last_ref_frame_sign_bias;
+	bool golden_ref_frame_sign_bias;
+	bool alt_ref_frame_sign_bias;
+	bool comp_ref_allowed = 0;
+
+	comp_fixed_ref = 0;
+	comp_var_ref[0] = 0;
+	comp_var_ref[1] = 0;
+
+	last_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_LAST;
+	golden_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_GOLDEN;
+	alt_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_ALT;
+
+	/* 6.3.12 Frame reference mode syntax */
+	comp_ref_allowed |= golden_ref_frame_sign_bias != last_ref_frame_sign_bias;
+	comp_ref_allowed |= alt_ref_frame_sign_bias != last_ref_frame_sign_bias;
+
+	if (comp_ref_allowed) {
+		if (last_ref_frame_sign_bias ==
+		    golden_ref_frame_sign_bias) {
+			comp_fixed_ref = ALTREF_FRAME;
+			comp_var_ref[0] = LAST_FRAME;
+			comp_var_ref[1] = GOLDEN_FRAME;
+		} else if (last_ref_frame_sign_bias ==
+			   alt_ref_frame_sign_bias) {
+			comp_fixed_ref = GOLDEN_FRAME;
+			comp_var_ref[0] = LAST_FRAME;
+			comp_var_ref[1] = ALTREF_FRAME;
+		} else {
+			comp_fixed_ref = LAST_FRAME;
+			comp_var_ref[0] = GOLDEN_FRAME;
+			comp_var_ref[1] = ALTREF_FRAME;
+		}
+	}
+
+	hantro_reg_write(ctx->dev, &vp9_comp_pred_fixed_ref, comp_fixed_ref);
+	hantro_reg_write(ctx->dev, &vp9_comp_pred_var_ref0, comp_var_ref[0]);
+	hantro_reg_write(ctx->dev, &vp9_comp_pred_var_ref1, comp_var_ref[1]);
+}
+
+#define INNER_LOOP \
+do {									\
+	for (m = 0; m < ARRAY_SIZE(adaptive->coef[0][0][0][0]); ++m) {	\
+		memcpy(adaptive->coef[i][j][k][l][m],			\
+		       probs->coef[i][j][k][l][m],			\
+		       sizeof(probs->coef[i][j][k][l][m]));		\
+									\
+		adaptive->coef[i][j][k][l][m][3] = 0;			\
+	}								\
+} while (0)
+
+static void config_probs(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	struct hantro_aux_buf *misc = &vp9_ctx->misc;
+	struct hantro_g2_all_probs *all_probs = misc->cpu;
+	struct hantro_g2_probs *adaptive;
+	struct hantro_g2_mv_probs *mv;
+	const struct v4l2_vp9_segmentation *seg = &dec_params->seg;
+	const struct v4l2_vp9_frame_context *probs = &vp9_ctx->probability_tables;
+	int i, j, k, l, m;
+
+	for (i = 0; i < ARRAY_SIZE(all_probs->kf_y_mode_prob); ++i)
+		for (j = 0; j < ARRAY_SIZE(all_probs->kf_y_mode_prob[0]); ++j) {
+			memcpy(all_probs->kf_y_mode_prob[i][j],
+			       v4l2_vp9_kf_y_mode_prob[i][j],
+			       ARRAY_SIZE(all_probs->kf_y_mode_prob[i][j]));
+
+			all_probs->kf_y_mode_prob_tail[i][j][0] =
+				v4l2_vp9_kf_y_mode_prob[i][j][8];
+		}
+
+	memcpy(all_probs->mb_segment_tree_probs, seg->tree_probs,
+	       sizeof(all_probs->mb_segment_tree_probs));
+
+	memcpy(all_probs->segment_pred_probs, seg->pred_probs,
+	       sizeof(all_probs->segment_pred_probs));
+
+	for (i = 0; i < ARRAY_SIZE(all_probs->kf_uv_mode_prob); ++i) {
+		memcpy(all_probs->kf_uv_mode_prob[i], v4l2_vp9_kf_uv_mode_prob[i],
+		       ARRAY_SIZE(all_probs->kf_uv_mode_prob[i]));
+
+		all_probs->kf_uv_mode_prob_tail[i][0] = v4l2_vp9_kf_uv_mode_prob[i][8];
+	}
+
+	adaptive = &all_probs->probs;
+
+	for (i = 0; i < ARRAY_SIZE(adaptive->inter_mode); ++i) {
+		memcpy(adaptive->inter_mode[i], probs->inter_mode[i],
+		       sizeof(probs->inter_mode));
+
+		adaptive->inter_mode[i][3] = 0;
+	}
+
+	memcpy(adaptive->is_inter, probs->is_inter, sizeof(adaptive->is_inter));
+
+	for (i = 0; i < ARRAY_SIZE(adaptive->uv_mode); ++i) {
+		memcpy(adaptive->uv_mode[i], probs->uv_mode[i],
+		       sizeof(adaptive->uv_mode[i]));
+		adaptive->uv_mode_tail[i][0] = probs->uv_mode[i][8];
+	}
+
+	memcpy(adaptive->tx8, probs->tx8, sizeof(adaptive->tx8));
+	memcpy(adaptive->tx16, probs->tx16, sizeof(adaptive->tx16));
+	memcpy(adaptive->tx32, probs->tx32, sizeof(adaptive->tx32));
+
+	for (i = 0; i < ARRAY_SIZE(adaptive->y_mode); ++i) {
+		memcpy(adaptive->y_mode[i], probs->y_mode[i],
+		       ARRAY_SIZE(adaptive->y_mode[i]));
+
+		adaptive->y_mode_tail[i][0] = probs->y_mode[i][8];
+	}
+
+	for (i = 0; i < ARRAY_SIZE(adaptive->partition[0]); ++i) {
+		memcpy(adaptive->partition[0][i], v4l2_vp9_kf_partition_probs[i],
+		       sizeof(v4l2_vp9_kf_partition_probs[i]));
+
+		adaptive->partition[0][i][3] = 0;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(adaptive->partition[1]); ++i) {
+		memcpy(adaptive->partition[1][i], probs->partition[i],
+		       sizeof(probs->partition[i]));
+
+		adaptive->partition[1][i][3] = 0;
+	}
+
+	memcpy(adaptive->interp_filter, probs->interp_filter,
+	       sizeof(adaptive->interp_filter));
+
+	memcpy(adaptive->comp_mode, probs->comp_mode, sizeof(adaptive->comp_mode));
+
+	memcpy(adaptive->skip, probs->skip, sizeof(adaptive->skip));
+
+	mv = &adaptive->mv;
+
+	memcpy(mv->joint, probs->mv.joint, sizeof(mv->joint));
+	memcpy(mv->sign, probs->mv.sign, sizeof(mv->sign));
+	memcpy(mv->class0_bit, probs->mv.class0_bit, sizeof(mv->class0_bit));
+	memcpy(mv->fr, probs->mv.fr, sizeof(mv->fr));
+	memcpy(mv->class0_hp, probs->mv.class0_hp, sizeof(mv->class0_hp));
+	memcpy(mv->hp, probs->mv.hp, sizeof(mv->hp));
+	memcpy(mv->classes, probs->mv.classes, sizeof(mv->classes));
+	memcpy(mv->class0_fr, probs->mv.class0_fr, sizeof(mv->class0_fr));
+	memcpy(mv->bits, probs->mv.bits, sizeof(mv->bits));
+
+	memcpy(adaptive->single_ref, probs->single_ref, sizeof(adaptive->single_ref));
+
+	memcpy(adaptive->comp_ref, probs->comp_ref, sizeof(adaptive->comp_ref));
+
+	for (i = 0; i < ARRAY_SIZE(adaptive->coef); ++i)
+		for (j = 0; j < ARRAY_SIZE(adaptive->coef[0]); ++j)
+			for (k = 0; k < ARRAY_SIZE(adaptive->coef[0][0]); ++k)
+				for (l = 0; l < ARRAY_SIZE(adaptive->coef[0][0][0]); ++l)
+					INNER_LOOP;
+
+	hantro_write_addr(ctx->dev, VP9_ADDR_PROBS, misc->dma);
+}
+
+static void config_counts(struct hantro_ctx *ctx)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
+	struct hantro_aux_buf *misc = &vp9_dec->misc;
+	dma_addr_t addr = misc->dma + vp9_dec->ctx_counters_offset;
+
+	hantro_write_addr(ctx->dev, VP9_ADDR_CTR, addr);
+}
+
+static void config_seg_map(struct hantro_ctx *ctx,
+			   const struct v4l2_ctrl_vp9_frame *dec_params,
+			   bool intra_only, bool update_map)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	struct hantro_aux_buf *segment_map = &vp9_ctx->segment_map;
+	dma_addr_t addr;
+
+	if (intra_only ||
+	    (dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT)) {
+		memset(segment_map->cpu, 0, segment_map->size);
+		memset(vp9_ctx->feature_data, 0, sizeof(vp9_ctx->feature_data));
+		memset(vp9_ctx->feature_enabled, 0, sizeof(vp9_ctx->feature_enabled));
+	}
+
+	addr = segment_map->dma + vp9_ctx->active_segment * vp9_ctx->segment_map_size;
+	hantro_write_addr(ctx->dev, VP9_ADDR_SEGMENT_READ, addr);
+
+	addr = segment_map->dma + (1 - vp9_ctx->active_segment) * vp9_ctx->segment_map_size;
+	hantro_write_addr(ctx->dev, VP9_ADDR_SEGMENT_WRITE, addr);
+
+	if (update_map)
+		vp9_ctx->active_segment = 1 - vp9_ctx->active_segment;
+}
+
+static void
+config_source(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params,
+	      struct vb2_v4l2_buffer *vb2_src)
+{
+	dma_addr_t stream_base, tmp_addr;
+	unsigned int headres_size;
+	u32 src_len, start_bit, src_buf_len;
+
+	headres_size = dec_params->uncompressed_header_size
+		     + dec_params->compressed_header_size;
+
+	stream_base = vb2_dma_contig_plane_dma_addr(&vb2_src->vb2_buf, 0);
+	hantro_write_addr(ctx->dev, G2_ADDR_STR, stream_base);
+
+	tmp_addr = stream_base + headres_size;
+	start_bit = (tmp_addr & 0xf) * 8;
+	hantro_reg_write(ctx->dev, &g2_start_bit, start_bit);
+
+	src_len = vb2_get_plane_payload(&vb2_src->vb2_buf, 0);
+	src_len += start_bit / 8 - headres_size;
+	hantro_reg_write(ctx->dev, &g2_stream_len, src_len);
+
+	tmp_addr &= ~0xf;
+	hantro_reg_write(ctx->dev, &g2_strm_start_offset, tmp_addr - stream_base);
+	src_buf_len = vb2_plane_size(&vb2_src->vb2_buf, 0);
+	hantro_reg_write(ctx->dev, &g2_strm_buffer_len, src_buf_len);
+}
+
+static void
+config_registers(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params,
+		 struct vb2_v4l2_buffer *vb2_src, struct vb2_v4l2_buffer *vb2_dst)
+{
+	struct hantro_decoded_buffer *dst, *last, *mv_ref;
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	const struct v4l2_vp9_segmentation *seg;
+	bool intra_only, resolution_change;
+
+	/* vp9 stuff */
+	dst = vb2_to_hantro_decoded_buf(&vb2_dst->vb2_buf);
+
+	if (vp9_ctx->last.valid)
+		last = get_ref_buf(ctx, &dst->base.vb, vp9_ctx->last.timestamp);
+	else
+		last = dst;
+
+	update_dec_buf_info(dst, dec_params);
+	update_ctx_cur_info(vp9_ctx, dst, dec_params);
+	seg = &dec_params->seg;
+
+	intra_only = !!(dec_params->flags &
+			(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
+			V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
+
+	if (!intra_only &&
+	    !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
+	    vp9_ctx->last.valid)
+		mv_ref = last;
+	else
+		mv_ref = dst;
+
+	resolution_change = dst->vp9.width != last->vp9.width ||
+			    dst->vp9.height != last->vp9.height;
+
+	/* configure basic registers */
+	hantro_reg_write(ctx->dev, &g2_mode, VP9_DEC_MODE);
+	hantro_reg_write(ctx->dev, &g2_strm_swap, 0xf);
+	hantro_reg_write(ctx->dev, &g2_dirmv_swap, 0xf);
+	hantro_reg_write(ctx->dev, &g2_compress_swap, 0xf);
+	hantro_reg_write(ctx->dev, &g2_buswidth, BUS_WIDTH_128);
+	hantro_reg_write(ctx->dev, &g2_max_burst, 16);
+	hantro_reg_write(ctx->dev, &g2_apf_threshold, 8);
+	hantro_reg_write(ctx->dev, &g2_ref_compress_bypass, 1);
+	hantro_reg_write(ctx->dev, &g2_clk_gate_e, 1);
+	hantro_reg_write(ctx->dev, &g2_max_cb_size, 6);
+	hantro_reg_write(ctx->dev, &g2_min_cb_size, 3);
+
+	config_output(ctx, dst, dec_params);
+
+	if (!intra_only)
+		config_ref_registers(ctx, dec_params, dst, mv_ref);
+
+	config_tiles(ctx, dec_params, dst);
+	config_segment(ctx, dec_params);
+	config_loop_filter(ctx, dec_params);
+	config_picture_dimensions(ctx, dst);
+	config_bit_depth(ctx, dec_params);
+	config_quant(ctx, dec_params);
+	config_others(ctx, dec_params, intra_only, resolution_change);
+	config_compound_reference(ctx, dec_params);
+	config_probs(ctx, dec_params);
+	config_counts(ctx);
+	config_seg_map(ctx, dec_params, intra_only,
+		       seg->flags & V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP);
+	config_source(ctx, dec_params, vb2_src);
+}
+
+int hantro_g2_vp9_dec_run(struct hantro_ctx *ctx)
+{
+	const struct v4l2_ctrl_vp9_frame *decode_params;
+	struct vb2_v4l2_buffer *src;
+	struct vb2_v4l2_buffer *dst;
+	int ret;
+
+	hantro_g2_check_idle(ctx->dev);
+
+	ret = start_prepare_run(ctx, &decode_params);
+	if (ret) {
+		hantro_end_prepare_run(ctx);
+		return ret;
+	}
+
+	src = hantro_get_src_buf(ctx);
+	dst = hantro_get_dst_buf(ctx);
+
+	config_registers(ctx, decode_params, src, dst);
+
+	hantro_end_prepare_run(ctx);
+
+	vdpu_write(ctx->dev, G2_REG_INTERRUPT_DEC_E, G2_REG_INTERRUPT);
+
+	return 0;
+}
+
+#define copy_tx_and_skip(p1, p2)				\
+do {								\
+	memcpy((p1)->tx8, (p2)->tx8, sizeof((p1)->tx8));	\
+	memcpy((p1)->tx16, (p2)->tx16, sizeof((p1)->tx16));	\
+	memcpy((p1)->tx32, (p2)->tx32, sizeof((p1)->tx32));	\
+	memcpy((p1)->skip, (p2)->skip, sizeof((p1)->skip));	\
+} while (0)
+
+void hantro_g2_vp9_dec_done(struct hantro_ctx *ctx)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	unsigned int fctx_idx;
+
+	if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX))
+		goto out_update_last;
+
+	fctx_idx = vp9_ctx->cur.frame_context_idx;
+
+	if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE)) {
+		/* error_resilient_mode == 0 && frame_parallel_decoding_mode == 0 */
+		struct v4l2_vp9_frame_context *probs = &vp9_ctx->probability_tables;
+		bool frame_is_intra = vp9_ctx->cur.flags &
+		    (V4L2_VP9_FRAME_FLAG_KEY_FRAME | V4L2_VP9_FRAME_FLAG_INTRA_ONLY);
+		struct tx_and_skip {
+			u8 tx8[2][1];
+			u8 tx16[2][2];
+			u8 tx32[2][3];
+			u8 skip[3];
+		} _tx_skip, *tx_skip = &_tx_skip;
+		struct v4l2_vp9_frame_symbol_counts *counts;
+		struct symbol_counts *hantro_cnts;
+		u32 tx16p[2][4];
+		int i;
+
+		/* buffer the forward-updated TX and skip probs */
+		if (frame_is_intra)
+			copy_tx_and_skip(tx_skip, probs);
+
+		/* 6.1.2 refresh_probs(): load_probs() and load_probs2() */
+		*probs = vp9_ctx->frame_context[fctx_idx];
+
+		/* if FrameIsIntra then undo the effect of load_probs2() */
+		if (frame_is_intra)
+			copy_tx_and_skip(probs, tx_skip);
+
+		counts = &vp9_ctx->cnts;
+		hantro_cnts = vp9_ctx->misc.cpu + vp9_ctx->ctx_counters_offset;
+		for (i = 0; i < ARRAY_SIZE(tx16p); ++i) {
+			memcpy(tx16p[i],
+			       hantro_cnts->tx16x16_count[i],
+			       sizeof(hantro_cnts->tx16x16_count[0]));
+			tx16p[i][3] = 0;
+		}
+		counts->tx16p = &tx16p;
+
+		v4l2_vp9_adapt_coef_probs(probs, counts,
+					  !vp9_ctx->last.valid ||
+					  vp9_ctx->last.flags & V4L2_VP9_FRAME_FLAG_KEY_FRAME,
+					  frame_is_intra);
+
+		if (!frame_is_intra) {
+			/* load_probs2() already done */
+			u32 mv_mode[7][4];
+
+			for (i = 0; i < ARRAY_SIZE(mv_mode); ++i) {
+				mv_mode[i][0] = hantro_cnts->inter_mode_counts[i][1][0];
+				mv_mode[i][1] = hantro_cnts->inter_mode_counts[i][2][0];
+				mv_mode[i][2] = hantro_cnts->inter_mode_counts[i][0][0];
+				mv_mode[i][3] = hantro_cnts->inter_mode_counts[i][2][1];
+			}
+			counts->mv_mode = &mv_mode;
+			v4l2_vp9_adapt_noncoef_probs(&vp9_ctx->probability_tables, counts,
+						     vp9_ctx->cur.reference_mode,
+						     vp9_ctx->cur.interpolation_filter,
+						     vp9_ctx->cur.tx_mode, vp9_ctx->cur.flags);
+		}
+	}
+
+	vp9_ctx->frame_context[fctx_idx] = vp9_ctx->probability_tables;
+
+out_update_last:
+	vp9_ctx->last = vp9_ctx->cur;
+}
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 42b3f3961f75..2961d399fd60 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/v4l2-controls.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-vp9.h>
 #include <media/videobuf2-core.h>
 
 #define DEC_8190_ALIGN_MASK	0x07U
@@ -161,6 +162,50 @@ struct hantro_vp8_dec_hw_ctx {
 	struct hantro_aux_buf prob_tbl;
 };
 
+struct hantro_vp9_frame_info {
+	u32 valid : 1;
+	u32 frame_context_idx : 2;
+	u32 reference_mode : 2;
+	u32 tx_mode : 3;
+	u32 interpolation_filter : 3;
+	u32 flags;
+	u64 timestamp;
+};
+
+#define MAX_SB_COLS	64
+#define MAX_SB_ROWS	34
+
+/**
+ * struct hantro_vp9_dec_hw_ctx
+ *
+ */
+struct hantro_vp9_dec_hw_ctx {
+	struct hantro_aux_buf tile_edge;
+	struct hantro_aux_buf segment_map;
+	struct hantro_aux_buf misc;
+	struct v4l2_vp9_frame_symbol_counts cnts;
+	struct v4l2_vp9_frame_context probability_tables;
+	struct v4l2_vp9_frame_context frame_context[4];
+	struct hantro_vp9_frame_info cur;
+	struct hantro_vp9_frame_info last;
+
+	unsigned int bsd_ctrl_offset;
+	unsigned int segment_map_size;
+	unsigned int ctx_counters_offset;
+	unsigned int tile_info_offset;
+
+	unsigned short tile_r_info[MAX_SB_ROWS];
+	unsigned short tile_c_info[MAX_SB_COLS];
+	unsigned int last_tile_r;
+	unsigned int last_tile_c;
+	unsigned int last_sbs_r;
+	unsigned int last_sbs_c;
+
+	unsigned int active_segment;
+	u8 feature_enabled[8];
+	s16 feature_data[8][4];
+};
+
 /**
  * struct hantro_postproc_ctx
  *
@@ -267,6 +312,24 @@ void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
 size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps);
 size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps);
 
+static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
+{
+	return (dimension + 63) / 64;
+}
+
+static inline size_t
+hantro_vp9_mv_size(unsigned int width, unsigned int height)
+{
+	int num_ctbs;
+
+	/*
+	 * There can be up to (CTBs x 64) number of blocks,
+	 * and the motion vector for each block needs 16 bytes.
+	 */
+	num_ctbs = hantro_vp9_num_sbs(width) * hantro_vp9_num_sbs(height);
+	return (num_ctbs * 64) * 16;
+}
+
 static inline size_t
 hantro_h264_mv_size(unsigned int width, unsigned int height)
 {
@@ -308,6 +371,10 @@ void hantro_vp8_dec_exit(struct hantro_ctx *ctx);
 void hantro_vp8_prob_update(struct hantro_ctx *ctx,
 			    const struct v4l2_ctrl_vp8_frame *hdr);
 
+int hantro_g2_vp9_dec_run(struct hantro_ctx *ctx);
+void hantro_g2_vp9_dec_done(struct hantro_ctx *ctx);
+int hantro_vp9_dec_init(struct hantro_ctx *ctx);
+void hantro_vp9_dec_exit(struct hantro_ctx *ctx);
 void hantro_g2_check_idle(struct hantro_dev *vpu);
 
 #endif /* HANTRO_HW_H_ */
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
index d1f060c55fed..e4b0645ba6fc 100644
--- a/drivers/staging/media/hantro/hantro_v4l2.c
+++ b/drivers/staging/media/hantro/hantro_v4l2.c
@@ -299,6 +299,11 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
 			pix_mp->plane_fmt[0].sizeimage +=
 				hantro_h264_mv_size(pix_mp->width,
 						    pix_mp->height);
+		else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME &&
+			 !hantro_needs_postproc(ctx, fmt))
+			pix_mp->plane_fmt[0].sizeimage +=
+				hantro_vp9_mv_size(pix_mp->width,
+						   pix_mp->height);
 	} else if (!pix_mp->plane_fmt[0].sizeimage) {
 		/*
 		 * For coded formats the application can specify
@@ -407,6 +412,7 @@ hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc)
 	case V4L2_PIX_FMT_VP8_FRAME:
 	case V4L2_PIX_FMT_H264_SLICE:
 	case V4L2_PIX_FMT_HEVC_SLICE:
+	case V4L2_PIX_FMT_VP9_FRAME:
 		ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true;
 		break;
 	default:
diff --git a/drivers/staging/media/hantro/hantro_vp9.c b/drivers/staging/media/hantro/hantro_vp9.c
new file mode 100644
index 000000000000..566cd376c097
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_vp9.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hantro VP9 codec driver
+ *
+ * Copyright (C) 2021 Collabora Ltd.
+ */
+
+#include <linux/types.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "hantro.h"
+#include "hantro_hw.h"
+#include "hantro_vp9.h"
+
+#define POW2(x) (1 << (x))
+
+#define MAX_LOG2_TILE_COLUMNS 6
+#define MAX_NUM_TILE_COLS POW2(MAX_LOG2_TILE_COLUMNS)
+#define MAX_TILE_COLS 20
+#define MAX_TILE_ROWS 22
+
+static size_t hantro_vp9_tile_filter_size(unsigned int height)
+{
+	u32 h, height32, size;
+
+	h = roundup(height, 8);
+
+	height32 = roundup(h, 64);
+	size = 24 * height32 * (MAX_NUM_TILE_COLS - 1); /* luma: 8, chroma: 8 + 8 */
+
+	return size;
+}
+
+static size_t hantro_vp9_bsd_control_size(unsigned int height)
+{
+	u32 h, height32;
+
+	h = roundup(height, 8);
+	height32 = roundup(h, 64);
+
+	return 16 * (height32 / 4) * (MAX_NUM_TILE_COLS - 1);
+}
+
+static size_t hantro_vp9_segment_map_size(unsigned int width, unsigned int height)
+{
+	u32 w, h;
+	int num_ctbs;
+
+	w = roundup(width, 8);
+	h = roundup(height, 8);
+	num_ctbs = ((w + 63) / 64) * ((h + 63) / 64);
+
+	return num_ctbs * 32;
+}
+
+static inline size_t hantro_vp9_prob_tab_size(void)
+{
+	return roundup(sizeof(struct hantro_g2_all_probs), 16);
+}
+
+static inline size_t hantro_vp9_count_tab_size(void)
+{
+	return roundup(sizeof(struct symbol_counts), 16);
+}
+
+static inline size_t hantro_vp9_tile_info_size(void)
+{
+	return roundup((MAX_TILE_COLS * MAX_TILE_ROWS * 4 * sizeof(u16) + 15 + 16) & ~0xf, 16);
+}
+
+static void *get_coeffs_arr(struct symbol_counts *cnts, int i, int j, int k, int l, int m)
+{
+	if (i == 0)
+		return &cnts->count_coeffs[j][k][l][m];
+
+	if (i == 1)
+		return &cnts->count_coeffs8x8[j][k][l][m];
+
+	if (i == 2)
+		return &cnts->count_coeffs16x16[j][k][l][m];
+
+	if (i == 3)
+		return &cnts->count_coeffs32x32[j][k][l][m];
+
+	return NULL;
+}
+
+static void *get_eobs1(struct symbol_counts *cnts, int i, int j, int k, int l, int m)
+{
+	if (i == 0)
+		return &cnts->count_coeffs[j][k][l][m][3];
+
+	if (i == 1)
+		return &cnts->count_coeffs8x8[j][k][l][m][3];
+
+	if (i == 2)
+		return &cnts->count_coeffs16x16[j][k][l][m][3];
+
+	if (i == 3)
+		return &cnts->count_coeffs32x32[j][k][l][m][3];
+
+	return NULL;
+}
+
+#define INNER_LOOP \
+	do {										\
+		for (m = 0; m < ARRAY_SIZE(vp9_ctx->cnts.coeff[i][0][0][0]); ++m) {	\
+			vp9_ctx->cnts.coeff[i][j][k][l][m] =				\
+				get_coeffs_arr(cnts, i, j, k, l, m);			\
+			vp9_ctx->cnts.eob[i][j][k][l][m][0] =				\
+				&cnts->count_eobs[i][j][k][l][m];			\
+			vp9_ctx->cnts.eob[i][j][k][l][m][1] =				\
+				get_eobs1(cnts, i, j, k, l, m);				\
+		}									\
+	} while (0)
+
+static void init_v4l2_vp9_count_tbl(struct hantro_ctx *ctx)
+{
+	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
+	struct symbol_counts *cnts = vp9_ctx->misc.cpu + vp9_ctx->ctx_counters_offset;
+	int i, j, k, l, m;
+
+	vp9_ctx->cnts.partition = &cnts->partition_counts;
+	vp9_ctx->cnts.skip = &cnts->mbskip_count;
+	vp9_ctx->cnts.intra_inter = &cnts->intra_inter_count;
+	vp9_ctx->cnts.tx32p = &cnts->tx32x32_count;
+	/*
+	 * g2 hardware uses tx16x16_count[2][3], while the api
+	 * expects tx16p[2][4], so this must be explicitly copied
+	 * into vp9_ctx->cnts.tx16p when passing the data to the
+	 * vp9 library function
+	 */
+	vp9_ctx->cnts.tx8p = &cnts->tx8x8_count;
+
+	vp9_ctx->cnts.y_mode = &cnts->sb_ymode_counts;
+	vp9_ctx->cnts.uv_mode = &cnts->uv_mode_counts;
+	vp9_ctx->cnts.comp = &cnts->comp_inter_count;
+	vp9_ctx->cnts.comp_ref = &cnts->comp_ref_count;
+	vp9_ctx->cnts.single_ref = &cnts->single_ref_count;
+	vp9_ctx->cnts.filter = &cnts->switchable_interp_counts;
+	vp9_ctx->cnts.mv_joint = &cnts->mv_counts.joints;
+	vp9_ctx->cnts.sign = &cnts->mv_counts.sign;
+	vp9_ctx->cnts.classes = &cnts->mv_counts.classes;
+	vp9_ctx->cnts.class0 = &cnts->mv_counts.class0;
+	vp9_ctx->cnts.bits = &cnts->mv_counts.bits;
+	vp9_ctx->cnts.class0_fp = &cnts->mv_counts.class0_fp;
+	vp9_ctx->cnts.fp = &cnts->mv_counts.fp;
+	vp9_ctx->cnts.class0_hp = &cnts->mv_counts.class0_hp;
+	vp9_ctx->cnts.hp = &cnts->mv_counts.hp;
+
+	for (i = 0; i < ARRAY_SIZE(vp9_ctx->cnts.coeff); ++i)
+		for (j = 0; j < ARRAY_SIZE(vp9_ctx->cnts.coeff[i]); ++j)
+			for (k = 0; k < ARRAY_SIZE(vp9_ctx->cnts.coeff[i][0]); ++k)
+				for (l = 0; l < ARRAY_SIZE(vp9_ctx->cnts.coeff[i][0][0]); ++l)
+					INNER_LOOP;
+}
+
+int hantro_vp9_dec_init(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	const struct hantro_variant *variant = vpu->variant;
+	struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
+	struct hantro_aux_buf *tile_edge = &vp9_dec->tile_edge;
+	struct hantro_aux_buf *segment_map = &vp9_dec->segment_map;
+	struct hantro_aux_buf *misc = &vp9_dec->misc;
+	u32 i, max_width, max_height, size;
+
+	if (variant->num_dec_fmts < 1)
+		return -EINVAL;
+
+	for (i = 0; i < variant->num_dec_fmts; ++i)
+		if (variant->dec_fmts[i].fourcc == V4L2_PIX_FMT_VP9_FRAME)
+			break;
+
+	if (i == variant->num_dec_fmts)
+		return -EINVAL;
+
+	max_width = vpu->variant->dec_fmts[i].frmsize.max_width;
+	max_height = vpu->variant->dec_fmts[i].frmsize.max_height;
+
+	size = hantro_vp9_tile_filter_size(max_height);
+	vp9_dec->bsd_ctrl_offset = size;
+	size += hantro_vp9_bsd_control_size(max_height);
+
+	tile_edge->cpu = dma_alloc_coherent(vpu->dev, size, &tile_edge->dma, GFP_KERNEL);
+	if (!tile_edge->cpu)
+		return -ENOMEM;
+
+	tile_edge->size = size;
+	memset(tile_edge->cpu, 0, size);
+
+	size = hantro_vp9_segment_map_size(max_width, max_height);
+	vp9_dec->segment_map_size = size;
+	size *= 2; /* we need two areas of this size, used alternately */
+
+	segment_map->cpu = dma_alloc_coherent(vpu->dev, size, &segment_map->dma, GFP_KERNEL);
+	if (!segment_map->cpu)
+		goto err_segment_map;
+
+	segment_map->size = size;
+	memset(segment_map->cpu, 0, size);
+
+	size = hantro_vp9_prob_tab_size();
+	vp9_dec->ctx_counters_offset = size;
+	size += hantro_vp9_count_tab_size();
+	vp9_dec->tile_info_offset = size;
+	size += hantro_vp9_tile_info_size();
+
+	misc->cpu = dma_alloc_coherent(vpu->dev, size, &misc->dma, GFP_KERNEL);
+	if (!misc->cpu)
+		goto err_misc;
+
+	misc->size = size;
+	memset(misc->cpu, 0, size);
+
+	init_v4l2_vp9_count_tbl(ctx);
+
+	return 0;
+
+err_misc:
+	dma_free_coherent(vpu->dev, segment_map->size, segment_map->cpu, segment_map->dma);
+
+err_segment_map:
+	dma_free_coherent(vpu->dev, tile_edge->size, tile_edge->cpu, tile_edge->dma);
+
+	return -ENOMEM;
+}
+
+void hantro_vp9_dec_exit(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
+	struct hantro_aux_buf *tile_edge = &vp9_dec->tile_edge;
+	struct hantro_aux_buf *segment_map = &vp9_dec->segment_map;
+	struct hantro_aux_buf *misc = &vp9_dec->misc;
+
+	dma_free_coherent(vpu->dev, misc->size, misc->cpu, misc->dma);
+	dma_free_coherent(vpu->dev, segment_map->size, segment_map->cpu, segment_map->dma);
+	dma_free_coherent(vpu->dev, tile_edge->size, tile_edge->cpu, tile_edge->dma);
+}
diff --git a/drivers/staging/media/hantro/hantro_vp9.h b/drivers/staging/media/hantro/hantro_vp9.h
new file mode 100644
index 000000000000..c7f4bd3ff8dd
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_vp9.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Hantro VP9 codec driver
+ *
+ * Copyright (C) 2021 Collabora Ltd.
+ */
+
+struct hantro_g2_mv_probs {
+	u8 joint[3];
+	u8 sign[2];
+	u8 class0_bit[2][1];
+	u8 fr[2][3];
+	u8 class0_hp[2];
+	u8 hp[2];
+	u8 classes[2][10];
+	u8 class0_fr[2][2][3];
+	u8 bits[2][10];
+};
+
+struct hantro_g2_probs {
+	u8 inter_mode[7][4];
+	u8 is_inter[4];
+	u8 uv_mode[10][8];
+	u8 tx8[2][1];
+	u8 tx16[2][2];
+	u8 tx32[2][3];
+	u8 y_mode_tail[4][1];
+	u8 y_mode[4][8];
+	u8 partition[2][16][4]; /* [keyframe][][], [inter][][] */
+	u8 uv_mode_tail[10][1];
+	u8 interp_filter[4][2];
+	u8 comp_mode[5];
+	u8 skip[3];
+
+	u8 pad1[1];
+
+	struct hantro_g2_mv_probs mv;
+
+	u8 single_ref[5][2];
+	u8 comp_ref[5];
+
+	u8 pad2[17];
+
+	u8 coef[4][2][2][6][6][4];
+};
+
+struct hantro_g2_all_probs {
+	u8 kf_y_mode_prob[10][10][8];
+
+	u8 kf_y_mode_prob_tail[10][10][1];
+	u8 ref_pred_probs[3];
+	u8 mb_segment_tree_probs[7];
+	u8 segment_pred_probs[3];
+	u8 ref_scores[4];
+	u8 prob_comppred[2];
+
+	u8 pad1[9];
+
+	u8 kf_uv_mode_prob[10][8];
+	u8 kf_uv_mode_prob_tail[10][1];
+
+	u8 pad2[6];
+
+	struct hantro_g2_probs probs;
+};
+
+struct mv_counts {
+	u32 joints[4];
+	u32 sign[2][2];
+	u32 classes[2][11];
+	u32 class0[2][2];
+	u32 bits[2][10][2];
+	u32 class0_fp[2][2][4];
+	u32 fp[2][4];
+	u32 class0_hp[2][2];
+	u32 hp[2][2];
+};
+
+struct symbol_counts {
+	u32 inter_mode_counts[7][3][2];
+	u32 sb_ymode_counts[4][10];
+	u32 uv_mode_counts[10][10];
+	u32 partition_counts[16][4];
+	u32 switchable_interp_counts[4][3];
+	u32 intra_inter_count[4][2];
+	u32 comp_inter_count[5][2];
+	u32 single_ref_count[5][2][2];
+	u32 comp_ref_count[5][2];
+	u32 tx32x32_count[2][4];
+	u32 tx16x16_count[2][3];
+	u32 tx8x8_count[2][2];
+	u32 mbskip_count[3][2];
+
+	struct mv_counts mv_counts;
+
+	u32 count_coeffs[2][2][6][6][4];
+	u32 count_coeffs8x8[2][2][6][6][4];
+	u32 count_coeffs16x16[2][2][6][6][4];
+	u32 count_coeffs32x32[2][2][6][6][4];
+
+	u32 count_eobs[4][2][2][6][6];
+};
+
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index a40b161e5956..455a107ffb02 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -150,6 +150,19 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
 			.step_height = MB_DIM,
 		},
 	},
+	{
+		.fourcc = V4L2_PIX_FMT_VP9_FRAME,
+		.codec_mode = HANTRO_MODE_VP9_DEC,
+		.max_depth = 2,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 3840,
+			.step_width = MB_DIM,
+			.min_height = 48,
+			.max_height = 2160,
+			.step_height = MB_DIM,
+		},
+	},
 };
 
 static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)
@@ -241,6 +254,13 @@ static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
 		.init = hantro_hevc_dec_init,
 		.exit = hantro_hevc_dec_exit,
 	},
+	[HANTRO_MODE_VP9_DEC] = {
+		.run = hantro_g2_vp9_dec_run,
+		.done = hantro_g2_vp9_dec_done,
+		.reset = imx8m_vpu_g2_reset,
+		.init = hantro_vp9_dec_init,
+		.exit = hantro_vp9_dec_exit,
+	},
 };
 
 /*
@@ -281,7 +301,7 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
 	.dec_offset = 0x0,
 	.dec_fmts = imx8m_vpu_g2_dec_fmts,
 	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts),
-	.codec = HANTRO_HEVC_DECODER,
+	.codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,
 	.codec_ops = imx8mq_vpu_g2_codec_ops,
 	.init = imx8mq_vpu_hw_init,
 	.runtime_resume = imx8mq_runtime_resume,
-- 
2.17.1



From pbrobinson at gmail.com  Thu Aug  5 08:04:30 2021
From: pbrobinson at gmail.com (Peter Robinson)
Date: Thu, 5 Aug 2021 16:04:30 +0100
Subject: [PATCH 1/3] arm: omap2: Drop MACH_OMAP3517EVM entry
In-Reply-To: <YP/Epx04Za2wiSlt@atomide.com>
References: <20210613125105.786984-1-pbrobinson@gmail.com>
 <YP/Epx04Za2wiSlt@atomide.com>
Message-ID: <CALeDE9OC+OAuGaNM+iEO44bg+QAdjTE3NQkSdLLZUb-OXeo4Xg@mail.gmail.com>

Hi Tony,

> * Peter Robinson <pbrobinson at gmail.com> [210613 15:51]:
> > The MACH_OMAP3517EVM was added back in commit 549f95ed2016 due to
> > being used by the ASoC driver, but this driver was dropped in
> > commit 2c2596f3ab25 as the audio for this board had been moved to
> > a simple-audio-card configuration so MACH_OMAP3517EVM is now
> > properly unuused and can be dropped.
>
> Applying into omap-for-v5.15/soc thanks.

Was that all 3 of the series or just this one patch, I only see the
one for your 5.15 PR.

Regards,
Peter


From john.garry at huawei.com  Thu Aug  5 08:16:02 2021
From: john.garry at huawei.com (John Garry)
Date: Thu, 5 Aug 2021 16:16:02 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Remove some unneeded init in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <577a625a-4fc5-7402-8e4f-4e0e5be93144@arm.com>
References: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
 <ee1f3ab5-3acc-f442-f2d2-898cf88bc447@arm.com>
 <45a8af4f-4202-ecd8-0882-507acf9b2eb2@huawei.com>
 <577a625a-4fc5-7402-8e4f-4e0e5be93144@arm.com>
Message-ID: <44c5e07b-e663-5b96-a142-ec25666e2a14@huawei.com>

On 05/08/2021 15:41, Robin Murphy wrote:
>> I suppose they could be combined into a smaller sub-struct and loaded 
>> in a single operation, but it looks messy, and prob without much gain.
> 
> Indeed I wouldn't say that saving memory is the primary concern here, 
> and any more convoluted code is hardly going to help performance. Plus 
> it still wouldn't help the other cases where we're just copying the size 
> into a fake queue to do some prod arithmetic - I hadn't fully clocked 
> what was going on there when I skimmed through things earlier.
> 
> Disregarding the bogus layout change, though, do you reckon the rest of 
> my idea makes sense?

I tried the similar change to avoid zero-init the padding in 
arm_smmu_cmdq_write_entries() and the 
_arm_smmu_cmdq_poll_set_valid_map(), but the disassembly was the same. 
So the compiler must have got smart there.

But for the original change in this patch, it did make a difference. 
It's nice to remove what was a memcpy:

     1770: a9077eff stp xzr, xzr, [x23, #112]
}, head = llq;
     1774: 94000000 bl 0 <memcpy>

And performance was very fractionally better.

As for pre-evaluating "nents", I'm not sure how much that can help, but 
I am not too optimistic. I can try some testing when I get a chance. 
Having said that, I would need to check the disassembly also.

Thanks,
John


From semen.protsenko at linaro.org  Thu Aug  5 08:30:23 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 5 Aug 2021 18:30:23 +0300
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <87y29gbas7.wl-maz@kernel.org>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
 <87k0l1w8y5.wl-maz@kernel.org>
 <CAPLW+4mMF9B2BiY2hTgHz5=DNbDJZ7TDzt=Xefb5tDKwQhpEew@mail.gmail.com>
 <87y29gbas7.wl-maz@kernel.org>
Message-ID: <CAPLW+4nCfSBfwMcemaVvU5MgBACgnhXaW9eAAjw66G6Zhz2Gbw@mail.gmail.com>

On Thu, 5 Aug 2021 at 10:39, Marc Zyngier <maz at kernel.org> wrote:
>
> On Wed, 04 Aug 2021 19:37:24 +0100,
> Sam Protsenko <semen.protsenko at linaro.org> wrote:
> >
> > On Wed, 4 Aug 2021 at 18:01, Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Wed, 04 Aug 2021 15:39:38 +0100,
> > > Sam Protsenko <semen.protsenko at linaro.org> wrote:
> > >
> > > > > You are also missing the hypervisor virtual timer interrupt.
> > > > >
> > > >
> > > > Checked SoC TRM, there is no PPI for hypervisor virtual timer
> > > > interrupt, and no mentioning of it at all. Likewise, I checked ARMv8
> > > > ARM and TRM, almost no description of it. Also, I checked other
> > > > platforms, and seems like everyone does the same (having only 4
> > > > interrupts). And I wasn't able to find any documentation on that, so I
> > > > guess I'll leave it as is, if you don't mind.
> > >
> > > I *do* mind, and other DTs being wrong isn't a good enough excuse! ;-)
> > >
> > > From the ARMv8 ARM (ARM DDI 0487G.b)
> > > <quote>
> > > D11.2.4 Timers
> > >
> > > In an implementation of the Generic Timer that includes EL3, if EL3
> > > can use AArch64, the following timers are implemented:
> > >
> > > * An EL1 physical timer, that:
> > >   - In Secure state, can be accessed from EL1.
> > >   - In Non-secure state, can be accessed from EL1 unless those
> > >     accesses are trapped to EL2.
> > >     When this timer can be accessed from EL1, an EL1 control
> > >     determines whether it can be accessed from EL0.
> > > * A Non-secure EL2 physical timer.
> > > * A Secure EL3 physical timer. An EL3 control determines whether this
> > >   register is accessible from Secure EL1.
> > > * An EL1 virtual timer.
> > > * When FEAT_VHE is implemented, a Non-secure EL2 virtual timer.
> > > * When FEAT_SEL2 is implemented, a Secure EL2 physical timer.
> > > * When FEAT_SEL2 is implemented, a Secure EL2 virtual timer.
> > > </quote>
> > >
> > > Cortex-A55 being an ARMv8.2 implementation, it has FEAT_VHE, and thus
> > > it does have a NS-EL2 virtual timer. This is further confirmed by the
> > > TRM which documents CNTHV*_EL2 as valid system registers[1].
> > >
> > > So the timer exists, the signal is routed out of the core, and it
> > > is likely that it is connected to the GIC.
> > >
> > > If the designers have omitted it, then it needs to be documented as
> > > such.
> > >
> >
> > Ok, I've checked thoroughly all docs again, and it seems like there is
> > no dedicated PPI number for this "EL2 Hypervisor Virtual Timer" in
> > Exynos850 SoC. The timer instance itself might exist of course, but
> > interrupt line is probably wasn't connected to GIC by SoC designers,
> > at least it's not documented.
>
> Can you try and check this? You can directly program the virtual timer
> so that it has a pending interrupt, and then check the pending
> register on the same CPU to see if there is anything appearing there.
>
> > Moreover, from [1,2] it looks like if it were existing it would have
> > been PPI=12 (INTID=28). But in GIC-400 TRM this PPI is assigned to
> > "Legacy FIQ signal",
>
> No. That's only if you set the bypass bits in GICD_CTLR, which nobody
> with half a brain would consider doing.
>
> > and all there is no PPI for Hypervisor Virtual
> > Timer documented there as well. In Exynos850 TRM the source for this
> > PPI's interrupt source is marked as "-", which means it's not used.
> >
> > So if you know something that I don't know -- please point me out the
> > doc where this PPI line is documented. Otherwise I can add the comment
> > to device tree, stating that this interrupt line is not present in
> > SoC's GIC, i.e. something like this:
> >
> > 8<------------------------------------------------------------------------------->8
> >     timer {
> >         compatible = "arm,armv8-timer";
> >         interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) |
> >                       IRQ_TYPE_LEVEL_LOW)>,
> >                  <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) |
> >                       IRQ_TYPE_LEVEL_LOW)>,
> >                  <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) |
> >                       IRQ_TYPE_LEVEL_LOW)>,
> >                  <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) |
> >                       IRQ_TYPE_LEVEL_LOW)>;
> >         /* Hypervisor Virtual Timer PPI is not present in this SoC GIC */
> >     };
> > 8<------------------------------------------------------------------------------->8
> >
> > Is that ok with you?
>
> I'd rather you verify the above first. And if you can't, I'd like a
> comment that is a bit more explicit:
>

I'm afraid I won't be able to verify your idea: seems like CNTHV_EL2
can be only modified (or read) in EL2. I tried to read that reg
anyway, which unsurprisingly resulted in el1_undef() BUG. The kernel
on my board is running in EL1, and I don't have access to the source
code for EL3 bootloaders. I have the source code for the last
bootloader, but it's already running in EL1.

> /* The vendor couldn't be bothered to wire the EL2 Virtual Timers */
>

I'll add the comment as you suggested. I propose we come back to this
issue later, either when the need for HV timer arises or when I have
some means to test your theory about existing PPI.

Thanks!

> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


From matthias.bgg at gmail.com  Thu Aug  5 08:35:09 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Thu, 5 Aug 2021 17:35:09 +0200
Subject: [v14 02/21] dt-bindings: ARM: Mediatek: Add mmsys document
 binding for MT8192
In-Reply-To: <162740843452.2368309.13157283201271440368@swboyd.mtv.corp.google.com>
References: <20210726105719.15793-1-chun-jie.chen@mediatek.com>
 <20210726105719.15793-3-chun-jie.chen@mediatek.com>
 <162740843452.2368309.13157283201271440368@swboyd.mtv.corp.google.com>
Message-ID: <b98aeeee-c544-3025-cc06-ec04be7ab638@gmail.com>



On 27/07/2021 19:53, Stephen Boyd wrote:
> Quoting Chun-Jie Chen (2021-07-26 03:57:00)
>> This patch adds the mmsys document binding for MT8192 SoC.
>>
>> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
>> Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
>> Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
>> Acked-by: Rob Herring <robh at kernel.org>
>> ---
> 
> Applied to clk-next
> 

Please drop this patch. The mmsys binding will change to yaml in this merge
window and this will create a merge conflict.

Thanks,
Matthias


From matthias.bgg at gmail.com  Thu Aug  5 08:41:04 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Thu, 5 Aug 2021 17:41:04 +0200
Subject: [v12 02/20] dt-bindings: ARM: Mediatek: Add mmsys document
 binding for MT8192
In-Reply-To: <15d27282-54b2-2cfe-7f44-2df3be11dd40@gmail.com>
References: <20210705033824.1934-1-chun-jie.chen@mediatek.com>
 <20210705033824.1934-3-chun-jie.chen@mediatek.com>
 <564fa3c8-1d85-5e98-f3f9-f83cb17e905a@gmail.com>
 <15d27282-54b2-2cfe-7f44-2df3be11dd40@gmail.com>
Message-ID: <e3210d22-7960-f8e4-c12d-d49ac5465463@gmail.com>

On 05/07/2021 17:45, Matthias Brugger wrote:
> On 05/07/2021 17:40, Matthias Brugger wrote:
>>
>>
>> On 05/07/2021 05:38, Chun-Jie Chen wrote:
>>> This patch adds the mmsys document binding for MT8192 SoC.
>>>
>>> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
>>
>> Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
>>
> 
> Of course, that's not what we need here...
> 
> Now pushed to v5.14-tmp/dts64 until v5.14-rc1 is released.
> 

Given that the change to yaml was taken by Rob Herring I drop this patch from my
queue.

Regards,
Matthias

> Thanks!
> Matthias
> 
>>> ---
>>>  .../devicetree/bindings/arm/mediatek/mediatek,mmsys.txt          | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
>>> index 78c50733985c..9712a6831fab 100644
>>> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
>>> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
>>> @@ -16,6 +16,7 @@ Required Properties:
>>>  	- "mediatek,mt8167-mmsys", "syscon"
>>>  	- "mediatek,mt8173-mmsys", "syscon"
>>>  	- "mediatek,mt8183-mmsys", "syscon"
>>> +	- "mediatek,mt8192-mmsys", "syscon"
>>>  - #clock-cells: Must be 1
>>>  
>>>  For the clock control, the mmsys controller uses the common clk binding from
>>>
> 



From matthias.bgg at gmail.com  Thu Aug  5 08:43:20 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Thu, 5 Aug 2021 17:43:20 +0200
Subject: [v6 1/2] arm64: dts: mediatek: Add mt8192 clock controllers
In-Reply-To: <20210727023205.20319-2-chun-jie.chen@mediatek.com>
References: <20210727023205.20319-1-chun-jie.chen@mediatek.com>
 <20210727023205.20319-2-chun-jie.chen@mediatek.com>
Message-ID: <c9c0bd84-5c62-d64b-efad-7d374f751a73@gmail.com>



On 27/07/2021 04:32, Chun-Jie Chen wrote:
> Add clock controller nodes for SoC mt8192
> 
> Signed-off-by: Weiyi Lu <weiyi.lu at mediatek.com>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt8192.dtsi | 163 +++++++++++++++++++++++
>  1 file changed, 163 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> index 9757138a8bbd..c7c7d4e017ae 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> @@ -5,6 +5,7 @@
>   */
>  
>  /dts-v1/;
> +#include <dt-bindings/clock/mt8192-clk.h>

I'd need a stable branch from Stephen to be able to take this one. Otherwise
we'll need to wait for v5.15-rc1 to be published before I can take them without
compile errors.

Regards,
Matthias

>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  #include <dt-bindings/interrupt-controller/irq.h>
>  #include <dt-bindings/pinctrl/mt8192-pinfunc.h>
> @@ -257,6 +258,24 @@
>  			};
>  		};
>  
> +		topckgen: syscon at 10000000 {
> +			compatible = "mediatek,mt8192-topckgen", "syscon";
> +			reg = <0 0x10000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		infracfg: syscon at 10001000 {
> +			compatible = "mediatek,mt8192-infracfg", "syscon";
> +			reg = <0 0x10001000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		pericfg: syscon at 10003000 {
> +			compatible = "mediatek,mt8192-pericfg", "syscon";
> +			reg = <0 0x10003000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		pio: pinctrl at 10005000 {
>  			compatible = "mediatek,mt8192-pinctrl";
>  			reg = <0 0x10005000 0 0x1000>,
> @@ -282,6 +301,12 @@
>  			#interrupt-cells = <2>;
>  		};
>  
> +		apmixedsys: syscon at 1000c000 {
> +			compatible = "mediatek,mt8192-apmixedsys", "syscon";
> +			reg = <0 0x1000c000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		systimer: timer at 10017000 {
>  			compatible = "mediatek,mt8192-timer",
>  				     "mediatek,mt6765-timer";
> @@ -291,6 +316,12 @@
>  			clock-names = "clk13m";
>  		};
>  
> +		scp_adsp: clock-controller at 10720000 {
> +			compatible = "mediatek,mt8192-scp_adsp";
> +			reg = <0 0x10720000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		uart0: serial at 11002000 {
>  			compatible = "mediatek,mt8192-uart",
>  				     "mediatek,mt6577-uart";
> @@ -311,6 +342,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_c: clock-controller at 11007000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_c";
> +			reg = <0 0x11007000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		spi0: spi at 1100a000 {
>  			compatible = "mediatek,mt8192-spi",
>  				     "mediatek,mt6765-spi";
> @@ -436,6 +473,12 @@
>  			status = "disable";
>  		};
>  
> +		audsys: clock-controller at 11210000 {
> +			compatible = "mediatek,mt8192-audsys", "syscon";
> +			reg = <0 0x11210000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c3: i2c3 at 11cb0000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11cb0000 0 0x1000>,
> @@ -449,6 +492,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_e: clock-controller at 11cb1000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_e";
> +			reg = <0 0x11cb1000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c7: i2c7 at 11d00000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11d00000 0 0x1000>,
> @@ -488,6 +537,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_s: clock-controller at 11d03000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_s";
> +			reg = <0 0x11d03000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c1: i2c1 at 11d20000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11d20000 0 0x1000>,
> @@ -527,6 +582,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_ws: clock-controller at 11d23000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_ws";
> +			reg = <0 0x11d23000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c5: i2c5 at 11e00000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11e00000 0 0x1000>,
> @@ -540,6 +601,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_w: clock-controller at 11e01000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_w";
> +			reg = <0 0x11e01000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c0: i2c0 at 11f00000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11f00000 0 0x1000>,
> @@ -565,5 +632,101 @@
>  			#size-cells = <0>;
>  			status = "disabled";
>  		};
> +
> +		imp_iic_wrap_n: clock-controller at 11f02000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_n";
> +			reg = <0 0x11f02000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		msdc_top: clock-controller at 11f10000 {
> +			compatible = "mediatek,mt8192-msdc_top";
> +			reg = <0 0x11f10000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		msdc: clock-controller at 11f60000 {
> +			compatible = "mediatek,mt8192-msdc";
> +			reg = <0 0x11f60000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		mfgcfg: clock-controller at 13fbf000 {
> +			compatible = "mediatek,mt8192-mfgcfg";
> +			reg = <0 0x13fbf000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		mmsys: syscon at 14000000 {
> +			compatible = "mediatek,mt8192-mmsys", "syscon";
> +			reg = <0 0x14000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		imgsys: clock-controller at 15020000 {
> +			compatible = "mediatek,mt8192-imgsys";
> +			reg = <0 0x15020000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		imgsys2: clock-controller at 15820000 {
> +			compatible = "mediatek,mt8192-imgsys2";
> +			reg = <0 0x15820000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		vdecsys_soc: clock-controller at 1600f000 {
> +			compatible = "mediatek,mt8192-vdecsys_soc";
> +			reg = <0 0x1600f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		vdecsys: clock-controller at 1602f000 {
> +			compatible = "mediatek,mt8192-vdecsys";
> +			reg = <0 0x1602f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		vencsys: clock-controller at 17000000 {
> +			compatible = "mediatek,mt8192-vencsys";
> +			reg = <0 0x17000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		camsys: clock-controller at 1a000000 {
> +			compatible = "mediatek,mt8192-camsys";
> +			reg = <0 0x1a000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		camsys_rawa: clock-controller at 1a04f000 {
> +			compatible = "mediatek,mt8192-camsys_rawa";
> +			reg = <0 0x1a04f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		camsys_rawb: clock-controller at 1a06f000 {
> +			compatible = "mediatek,mt8192-camsys_rawb";
> +			reg = <0 0x1a06f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		camsys_rawc: clock-controller at 1a08f000 {
> +			compatible = "mediatek,mt8192-camsys_rawc";
> +			reg = <0 0x1a08f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		ipesys: clock-controller at 1b000000 {
> +			compatible = "mediatek,mt8192-ipesys";
> +			reg = <0 0x1b000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		mdpsys: clock-controller at 1f000000 {
> +			compatible = "mediatek,mt8192-mdpsys";
> +			reg = <0 0x1f000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
>  	};
>  };
> 


From lorenzo.pieralisi at arm.com  Thu Aug  5 08:43:49 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 5 Aug 2021 16:43:49 +0100
Subject: [PATCH v7 4/9] ACPI/IORT: Add a helper to retrieve RMR memory
 regions
In-Reply-To: <20210805080724.480-5-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <20210805080724.480-5-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805154349.GA23085@lpieralisi>

On Thu, Aug 05, 2021 at 09:07:19AM +0100, Shameer Kolothum wrote:
> Add a helper function (iort_iommu_get_rmrs()) that retrieves RMR
> memory descriptors associated with a given IOMMU. This will be used
> by IOMMU drivers to setup necessary mappings.
> 
> Invoke it from the generic helper iommu_dma_get_rmrs().
> 
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  drivers/acpi/arm64/iort.c | 38 ++++++++++++++++++++++++++++++++++++++
>  drivers/iommu/dma-iommu.c |  4 ++++
>  include/linux/acpi_iort.h |  7 +++++++
>  3 files changed, 49 insertions(+)

Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>

> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index d76ba46ebe67..3c32d62e63b6 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -809,6 +809,42 @@ static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev)
>  	return NULL;
>  }
>  
> +/**
> + * iort_iommu_get_rmrs() - Helper to retrieve RMR info associated with IOMMU
> + * @iommu_fwnode: fwnode for the IOMMU
> + * @head: RMR list head to be populated
> + *
> + * Returns: 0 on success, <0 failure. Please note, we will keep the already
> + *          allocated RMR reserve regions in case of a kmemdup()
> + *          failure.
> + */
> +int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
> +			struct list_head *head)
> +{
> +	struct iommu_resv_region *e;
> +	struct acpi_iort_node *iommu;
> +	int rmrs = 0;
> +
> +	iommu = iort_get_iort_node(iommu_fwnode);
> +	if (!iommu || list_empty(&iort_rmr_list))
> +		return -ENODEV;
> +
> +	list_for_each_entry(e, &iort_rmr_list, list) {
> +		struct iommu_resv_region *region;
> +
> +		if (e->fw_data.rmr.smmu != iommu)
> +			continue;
> +
> +		region = kmemdup(e, sizeof(*region), GFP_KERNEL);
> +		if (region) {
> +			list_add_tail(&region->list, head);
> +			rmrs++;
> +		}
> +	}
> +
> +	return (rmrs == 0) ? -ENODEV : 0;
> +}
> +
>  /**
>   * iort_iommu_msi_get_resv_regions - Reserved region driver helper
>   * @dev: Device from iommu_get_resv_regions()
> @@ -1041,6 +1077,8 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
>  { return 0; }
>  int iort_iommu_configure_id(struct device *dev, const u32 *input_id)
>  { return -ENODEV; }
> +int iort_iommu_get_rmrs(struct fwnode_handle *fwnode, struct list_head *head)
> +{ return -ENODEV; }
>  #endif
>  
>  static int nc_dma_get_range(struct device *dev, u64 *size)
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index 2fa2445e9070..1b6e27475279 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -185,6 +185,9 @@ EXPORT_SYMBOL(iommu_put_dma_cookie);
>  int iommu_dma_get_rmrs(struct fwnode_handle *iommu_fwnode,
>  		       struct list_head *list)
>  {
> +	if (!is_of_node(iommu_fwnode))
> +		return iort_iommu_get_rmrs(iommu_fwnode, list);
> +
>  	return -EINVAL;
>  }
>  EXPORT_SYMBOL(iommu_dma_get_rmrs);
> @@ -200,6 +203,7 @@ EXPORT_SYMBOL(iommu_dma_get_rmrs);
>  void iommu_dma_put_rmrs(struct fwnode_handle *iommu_fwnode,
>  			struct list_head *list)
>  {
> +	generic_iommu_put_resv_regions(iommu_fwnode->dev, list);
>  }
>  EXPORT_SYMBOL(iommu_dma_put_rmrs);
>  
> diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
> index f1f0842a2cb2..d8c030c103f5 100644
> --- a/include/linux/acpi_iort.h
> +++ b/include/linux/acpi_iort.h
> @@ -38,6 +38,8 @@ int iort_dma_get_ranges(struct device *dev, u64 *size);
>  int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
>  int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head);
>  phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
> +int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
> +			struct list_head *list);
>  #else
>  static inline void acpi_iort_init(void) { }
>  static inline u32 iort_msi_map_id(struct device *dev, u32 id)
> @@ -57,6 +59,11 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
>  
>  static inline phys_addr_t acpi_iort_dma_get_max_cpu_address(void)
>  { return PHYS_ADDR_MAX; }
> +
> +static inline
> +int iort_iommu_get_rmrs(struct fwnode_handle *iommu_fwnode,
> +			struct list_head *list)
> +{ return -ENODEV; }
>  #endif
>  
>  #endif /* __ACPI_IORT_H__ */
> -- 
> 2.17.1
> 


From matthias.bgg at gmail.com  Thu Aug  5 08:44:42 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Thu, 5 Aug 2021 17:44:42 +0200
Subject: [v6 2/2] arm64: dts: mediatek: Correct UART0 bus clock of MT8192
In-Reply-To: <a48525422d4c953a2dac2a907895c20b9fd6d232.camel@mediatek.com>
References: <20210727023205.20319-1-chun-jie.chen@mediatek.com>
 <20210727023205.20319-3-chun-jie.chen@mediatek.com>
 <CAATdQgC-X6pijkgTBsWJJKp__J6N=7JNKHQJmOMvTAjivwPM5w@mail.gmail.com>
 <a48525422d4c953a2dac2a907895c20b9fd6d232.camel@mediatek.com>
Message-ID: <913973ef-e3ee-5015-a010-b436fe620e1c@gmail.com>



On 30/07/2021 04:43, Chun-Jie Chen wrote:
> On Wed, 2021-07-28 at 14:14 +0800, Ikjoon Jang wrote:
>> Hi,
>>
>> On Tue, Jul 27, 2021 at 10:43 AM Chun-Jie Chen
>> <chun-jie.chen at mediatek.com> wrote:
>>>
>>> infra_uart0 clock is the real one what uart0 uses as bus clock.
>>>
>>> Signed-off-by: Weiyi Lu <weiyi.lu at mediatek.com>
>>> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
>>> ---
>>>  arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
>>> b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
>>> index c7c7d4e017ae..9810f1d441da 100644
>>> --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
>>> +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
>>> @@ -327,7 +327,7 @@
>>>                                      "mediatek,mt6577-uart";
>>>                         reg = <0 0x11002000 0 0x1000>;
>>>                         interrupts = <GIC_SPI 109
>>> IRQ_TYPE_LEVEL_HIGH 0>;
>>> -                       clocks = <&clk26m>, <&clk26m>;
>>> +                       clocks = <&clk26m>, <&infracfg
>>> CLK_INFRA_UART0>;
>>>                         clock-names = "baud", "bus";
>>>                         status = "disabled";
>>>                 };
>>
>> There're many other nodes still having only clk26m. Will you update
>> them too?
>>
> 
> Others will be updated by IP owner.
> 

As it seems we will have some time before this can be merged, could you help
work with the other IP owners to get one big patch that updates all clocks?

Thanks a lot,
Matthias

> Best Regards,
> Chun-Jie
> 
>>> --
>>> 2.18.0
>>> _______________________________________________
>>> Linux-mediatek mailing list
>>> Linux-mediatek at lists.infradead.org
>>>
> https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!1bIz6X2EiFbigCImzQmbqtezIFfl1LRBuPOYTqBdl5wfx8b-zp0zQP68R7RhaIcAAXXF$
>>>  


From maz at kernel.org  Thu Aug  5 08:50:24 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 05 Aug 2021 16:50:24 +0100
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <CAPLW+4nCfSBfwMcemaVvU5MgBACgnhXaW9eAAjw66G6Zhz2Gbw@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <15871f8ced3c757fad1ab3b6e62c4e64@misterjones.org>
 <CAPLW+4=v4bDcuxGVqs06mobGj34At4cD+vg48b4dPujarS07Tg@mail.gmail.com>
 <87k0l1w8y5.wl-maz@kernel.org>
 <CAPLW+4mMF9B2BiY2hTgHz5=DNbDJZ7TDzt=Xefb5tDKwQhpEew@mail.gmail.com>
 <87y29gbas7.wl-maz@kernel.org>
 <CAPLW+4nCfSBfwMcemaVvU5MgBACgnhXaW9eAAjw66G6Zhz2Gbw@mail.gmail.com>
Message-ID: <87sfznc2m7.wl-maz@kernel.org>

On Thu, 05 Aug 2021 16:30:23 +0100,
Sam Protsenko <semen.protsenko at linaro.org> wrote:
> 
> On Thu, 5 Aug 2021 at 10:39, Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Wed, 04 Aug 2021 19:37:24 +0100,
> > Sam Protsenko <semen.protsenko at linaro.org> wrote:
> > >
> > > On Wed, 4 Aug 2021 at 18:01, Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > On Wed, 04 Aug 2021 15:39:38 +0100,
> > > > Sam Protsenko <semen.protsenko at linaro.org> wrote:
> > > >
> > > > > > You are also missing the hypervisor virtual timer interrupt.
> > > > > >
> > > > >
> > > > > Checked SoC TRM, there is no PPI for hypervisor virtual timer
> > > > > interrupt, and no mentioning of it at all. Likewise, I checked ARMv8
> > > > > ARM and TRM, almost no description of it. Also, I checked other
> > > > > platforms, and seems like everyone does the same (having only 4
> > > > > interrupts). And I wasn't able to find any documentation on that, so I
> > > > > guess I'll leave it as is, if you don't mind.
> > > >
> > > > I *do* mind, and other DTs being wrong isn't a good enough excuse! ;-)
> > > >
> > > > From the ARMv8 ARM (ARM DDI 0487G.b)
> > > > <quote>
> > > > D11.2.4 Timers
> > > >
> > > > In an implementation of the Generic Timer that includes EL3, if EL3
> > > > can use AArch64, the following timers are implemented:
> > > >
> > > > * An EL1 physical timer, that:
> > > >   - In Secure state, can be accessed from EL1.
> > > >   - In Non-secure state, can be accessed from EL1 unless those
> > > >     accesses are trapped to EL2.
> > > >     When this timer can be accessed from EL1, an EL1 control
> > > >     determines whether it can be accessed from EL0.
> > > > * A Non-secure EL2 physical timer.
> > > > * A Secure EL3 physical timer. An EL3 control determines whether this
> > > >   register is accessible from Secure EL1.
> > > > * An EL1 virtual timer.
> > > > * When FEAT_VHE is implemented, a Non-secure EL2 virtual timer.
> > > > * When FEAT_SEL2 is implemented, a Secure EL2 physical timer.
> > > > * When FEAT_SEL2 is implemented, a Secure EL2 virtual timer.
> > > > </quote>
> > > >
> > > > Cortex-A55 being an ARMv8.2 implementation, it has FEAT_VHE, and thus
> > > > it does have a NS-EL2 virtual timer. This is further confirmed by the
> > > > TRM which documents CNTHV*_EL2 as valid system registers[1].
> > > >
> > > > So the timer exists, the signal is routed out of the core, and it
> > > > is likely that it is connected to the GIC.
> > > >
> > > > If the designers have omitted it, then it needs to be documented as
> > > > such.
> > > >
> > >
> > > Ok, I've checked thoroughly all docs again, and it seems like there is
> > > no dedicated PPI number for this "EL2 Hypervisor Virtual Timer" in
> > > Exynos850 SoC. The timer instance itself might exist of course, but
> > > interrupt line is probably wasn't connected to GIC by SoC designers,
> > > at least it's not documented.
> >
> > Can you try and check this? You can directly program the virtual timer
> > so that it has a pending interrupt, and then check the pending
> > register on the same CPU to see if there is anything appearing there.
> >
> > > Moreover, from [1,2] it looks like if it were existing it would have
> > > been PPI=12 (INTID=28). But in GIC-400 TRM this PPI is assigned to
> > > "Legacy FIQ signal",
> >
> > No. That's only if you set the bypass bits in GICD_CTLR, which nobody
> > with half a brain would consider doing.
> >
> > > and all there is no PPI for Hypervisor Virtual
> > > Timer documented there as well. In Exynos850 TRM the source for this
> > > PPI's interrupt source is marked as "-", which means it's not used.
> > >
> > > So if you know something that I don't know -- please point me out the
> > > doc where this PPI line is documented. Otherwise I can add the comment
> > > to device tree, stating that this interrupt line is not present in
> > > SoC's GIC, i.e. something like this:
> > >
> > > 8<------------------------------------------------------------------------------->8
> > >     timer {
> > >         compatible = "arm,armv8-timer";
> > >         interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) |
> > >                       IRQ_TYPE_LEVEL_LOW)>,
> > >                  <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) |
> > >                       IRQ_TYPE_LEVEL_LOW)>,
> > >                  <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) |
> > >                       IRQ_TYPE_LEVEL_LOW)>,
> > >                  <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) |
> > >                       IRQ_TYPE_LEVEL_LOW)>;
> > >         /* Hypervisor Virtual Timer PPI is not present in this SoC GIC */
> > >     };
> > > 8<------------------------------------------------------------------------------->8
> > >
> > > Is that ok with you?
> >
> > I'd rather you verify the above first. And if you can't, I'd like a
> > comment that is a bit more explicit:
> >
> 
> I'm afraid I won't be able to verify your idea: seems like CNTHV_EL2
> can be only modified (or read) in EL2. I tried to read that reg
> anyway, which unsurprisingly resulted in el1_undef() BUG. The kernel
> on my board is running in EL1, and I don't have access to the source
> code for EL3 bootloaders. I have the source code for the last
> bootloader, but it's already running in EL1.

Excellent. Yet another half-usable machine on the block. Just what we
need.

> 
> > /* The vendor couldn't be bothered to wire the EL2 Virtual Timers */
> >
> 
> I'll add the comment as you suggested. I propose we come back to this
> issue later, either when the need for HV timer arises or when I have
> some means to test your theory about existing PPI.

If you depend on the vendor to get EL2 access, it is a lost cause,
unfortunately.

	M.

-- 
Without deviation from the norm, progress is not possible.


From claudiu.beznea at microchip.com  Thu Aug  5 08:53:50 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 5 Aug 2021 18:53:50 +0300
Subject: [PATCH 0/7] ARM: dts: at91: add Exegin Q5xR5 and CalAmp LMU5000
Message-ID: <20210805155357.594414-1-claudiu.beznea@microchip.com>

Hi,

This series adds support for Exegin Q5xR5 and CalAmp LMU5000 boards
which were maintained up to this moment, separatelly, in OpenWrt tree.
With these patches the support for these boards will be included in
upstream kernel and there will be no need to forward port the proper
patches in OpenWrt every time the OpenWrt kernel version is changed.

Thank you,
Claudiu Beznea

Adam Porter (1):
  ARM: dts: at91: add CalAmp LMU5000 board

Claudiu Beznea (5):
  ARM: dts: at91: at91sam9260: add pinctrl label
  dt-bindings: add vendor prefix for exegin
  dt-bindings: ARM: at91: document exegin q5xr5 board
  dt-bindings: add vendor prefix for calamp
  dt-bindings: ARM: at91: document CalAmp LMU5000 board

Owen Kirby (1):
  ARM: dts: at91: add Exegin Q5xR5 board

 .../devicetree/bindings/arm/atmel-at91.yaml   |  12 ++
 .../devicetree/bindings/vendor-prefixes.yaml  |   4 +
 arch/arm/boot/dts/Makefile                    |   2 +
 arch/arm/boot/dts/at91-lmu5000.dts            | 148 +++++++++++++
 arch/arm/boot/dts/at91-q5xr5.dts              | 200 ++++++++++++++++++
 arch/arm/boot/dts/at91sam9260.dtsi            |   2 +-
 6 files changed, 367 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/at91-lmu5000.dts
 create mode 100644 arch/arm/boot/dts/at91-q5xr5.dts

-- 
2.25.1



From claudiu.beznea at microchip.com  Thu Aug  5 08:53:51 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 5 Aug 2021 18:53:51 +0300
Subject: [PATCH 1/7] ARM: dts: at91: at91sam9260: add pinctrl label
In-Reply-To: <20210805155357.594414-1-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
Message-ID: <20210805155357.594414-2-claudiu.beznea@microchip.com>

Add label for pinctrl node.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91sam9260.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index 019f1c3d4d30..7368347c9357 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -166,7 +166,7 @@ tcb1: timer at fffdc000 {
 				clock-names = "t0_clk", "t1_clk", "t2_clk", "slow_clk";
 			};
 
-			pinctrl at fffff400 {
+			pinctrl: pinctrl at fffff400 {
 				#address-cells = <1>;
 				#size-cells = <1>;
 				compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
-- 
2.25.1



From claudiu.beznea at microchip.com  Thu Aug  5 08:53:52 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 5 Aug 2021 18:53:52 +0300
Subject: [PATCH 2/7] dt-bindings: add vendor prefix for exegin
In-Reply-To: <20210805155357.594414-1-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
Message-ID: <20210805155357.594414-3-claudiu.beznea@microchip.com>

Add vendor prefix for Exegin Technologies Limited.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 07fb0d25fc15..2fa00c7b7ee2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -391,6 +391,8 @@ patternProperties:
     description: Exar Corporation
   "^excito,.*":
     description: Excito
+  "^exegin,.*":
+    description: Exegin Technologies Limited
   "^ezchip,.*":
     description: EZchip Semiconductor
   "^facebook,.*":
-- 
2.25.1



From claudiu.beznea at microchip.com  Thu Aug  5 08:53:53 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 5 Aug 2021 18:53:53 +0300
Subject: [PATCH 3/7] dt-bindings: ARM: at91: document exegin q5xr5 board
In-Reply-To: <20210805155357.594414-1-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
Message-ID: <20210805155357.594414-4-claudiu.beznea@microchip.com>

Document Exegin Q5xR5 board.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index fba071b9af1d..a9ab18510fef 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -126,6 +126,12 @@ properties:
           - const: atmel,sama5d3
           - const: atmel,sama5
 
+      - description: CalAmp LMU5000 board
+        items:
+          - const: calamp,lmu5000
+          - const: atmel,at91sam9g20
+          - const: atmel,at91sam9
+
       - items:
           - enum:
               - atmel,sama5d31
-- 
2.25.1



From claudiu.beznea at microchip.com  Thu Aug  5 08:53:54 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 5 Aug 2021 18:53:54 +0300
Subject: [PATCH 4/7] ARM: dts: at91: add Exegin Q5xR5 board
In-Reply-To: <20210805155357.594414-1-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
Message-ID: <20210805155357.594414-5-claudiu.beznea@microchip.com>

From: Owen Kirby <osk at exegin.com>

Add Exegin Q5xR5. The base device tree is from OpenWrt tree and with
the addition of this patch there will be no need to maintain it
separatelly in OpenWrt.

[osk: original author of patch in OpenWrt]
Signed-off-by: Owen Kirby <osk at exegin.com>
[claudiu.beznea: use "&<label> {" syntax, sorted nodes in alphabetical
 order, adapted flash to new support in kernel 5.14, use proper
 compatibles according to kernel 5.14, use macros instead of
 hardcoded numbers for pinctrl phandles and for all pinctrl references,
 add pinctrl-names, pinctrl-X where necessaray]
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/Makefile       |   1 +
 arch/arm/boot/dts/at91-q5xr5.dts | 200 +++++++++++++++++++++++++++++++
 2 files changed, 201 insertions(+)
 create mode 100644 arch/arm/boot/dts/at91-q5xr5.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 63b60f571035..34f6ead22048 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -40,6 +40,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
 	at91-kizboxmini-base.dtb \
 	at91-kizboxmini-mb.dtb \
 	at91-kizboxmini-rd.dtb \
+	at91-q5xr5.dtb \
 	at91-smartkiz.dtb \
 	at91-wb45n.dtb \
 	at91sam9g15ek.dtb \
diff --git a/arch/arm/boot/dts/at91-q5xr5.dts b/arch/arm/boot/dts/at91-q5xr5.dts
new file mode 100644
index 000000000000..4866f1c6ccf9
--- /dev/null
+++ b/arch/arm/boot/dts/at91-q5xr5.dts
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Device Tree file for Exegin Q5xR5 board
+ *
+ * Copyright (C) 2014 Owen Kirby <osk at exegin.com>
+ */
+
+/dts-v1/;
+#include "at91sam9g20.dtsi"
+
+/ {
+	model = "Exegin Q5x (rev5)";
+	compatible = "exegin,q5xr5", "atmel,at91sam9g20", "atmel,at91sam9";
+
+	chosen {
+		bootargs = "console=ttyS0,115200 rootfstype=squashfs,jffs2";
+	};
+
+	memory {
+		reg = <0x20000000 0x0>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		main_clock: clock at 0 {
+			compatible = "atmel,osc", "fixed-clock";
+			clock-frequency = <18432000>;
+		};
+
+		slow_xtal {
+			clock-frequency = <32768>;
+		};
+
+		main_xtal {
+			clock-frequency = <18432000>;
+		};
+	};
+};
+
+&dbgu {
+	status = "okay";
+};
+
+&ebi {
+	status = "okay";
+
+	flash: flash at 0 {
+		compatible = "cfi-flash";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x0 0x1000000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			kernel at 0 {
+				label = "kernel";
+				reg = <0x0 0x200000>;
+			};
+
+			rootfs at 200000 {
+				label = "rootfs";
+				reg = <0x200000 0x600000>;
+			};
+		};
+	};
+};
+
+&macb0 {
+	phy-mode = "mii";
+	status = "okay";
+};
+
+&pinctrl {
+	board {
+		pinctrl_pck0_as_mck: pck0_as_mck {
+			atmel,pins = <AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+		};
+	};
+
+	spi0 {
+		pinctrl_spi0: spi0-0 {
+			atmel,pins =
+				<AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE
+				 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE
+				 AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+
+		pinctrl_spi0_npcs0: spi0_npcs0 {
+			atmel,pins = <AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+
+		pinctrl_spi0_npcs1: spi0_npcs1 {
+			atmel,pins = <AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+		};
+	};
+
+	spi1 {
+		pinctrl_spi1: spi1-0 {
+			atmel,pins =
+				<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE
+				 AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE
+				 AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+
+		pinctrl_spi1_npcs0: spi1_npcs0 {
+			atmel,pins = <AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+
+		pinctrl_spi1_npcs1: spi1_npcs1 {
+			atmel,pins = <AT91_PIOC 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+		};
+	};
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi0 &pinctrl_spi0_npcs0 &pinctrl_spi0_npcs1>;
+	cs-gpios = <&pioA 3 GPIO_ACTIVE_HIGH>, <&pioC 11 GPIO_ACTIVE_LOW>, <0>, <0>;
+	status = "okay";
+
+	m25p80 at 0 {
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		at91boot at 0 {
+			label = "at91boot";
+			reg = <0x0 0x4000>;
+		};
+
+		uenv at 4000 {
+			label = "uboot-env";
+			reg = <0x4000 0x4000>;
+		};
+
+		uboot at 8000 {
+			label = "uboot";
+			reg = <0x8000 0x3E000>;
+		};
+	};
+
+	spidev at 1 {
+		compatible = "spidev";
+		spi-max-frequency = <2000000>;
+		reg = <1>;
+	};
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1 &pinctrl_spi1_npcs0 &pinctrl_spi1_npcs1>;
+	cs-gpios = <&pioB 3 GPIO_ACTIVE_HIGH>, <&pioC 5 GPIO_ACTIVE_LOW>, <0>, <0>;
+	status = "okay";
+
+	spidev at 0 {
+		compatible = "spidev";
+		spi-max-frequency = <2000000>;
+		reg = <0>;
+	};
+
+	spidev at 1 {
+		compatible = "spidev";
+		spi-max-frequency = <2000000>;
+		reg = <1>;
+	};
+};
+
+&usart0 {
+	pinctrl-0 =
+		<&pinctrl_usart0
+		 &pinctrl_usart0_rts
+		 &pinctrl_usart0_cts
+		 &pinctrl_usart0_dtr_dsr
+		 &pinctrl_usart0_dcd
+		 &pinctrl_usart0_ri>;
+	status = "okay";
+};
+
+&usb0 {
+	num-ports = <2>;
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
+
+&watchdog {
+	status = "okay";
+};
+
-- 
2.25.1



From claudiu.beznea at microchip.com  Thu Aug  5 08:53:55 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 5 Aug 2021 18:53:55 +0300
Subject: [PATCH 5/7] dt-bindings: add vendor prefix for calamp
In-Reply-To: <20210805155357.594414-1-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
Message-ID: <20210805155357.594414-6-claudiu.beznea@microchip.com>

Add vendor prefix for CalAmp Corp.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 2fa00c7b7ee2..61fe4778498d 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -191,6 +191,8 @@ patternProperties:
     description: B&R Industrial Automation GmbH
   "^bticino,.*":
     description: Bticino International
+  "^calamp,.*":
+    description: CalAmp Corp.
   "^calaosystems,.*":
     description: CALAO Systems SAS
   "^calxeda,.*":
-- 
2.25.1



From claudiu.beznea at microchip.com  Thu Aug  5 08:53:56 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 5 Aug 2021 18:53:56 +0300
Subject: [PATCH 6/7] dt-bindings: ARM: at91: document CalAmp LMU5000 board
In-Reply-To: <20210805155357.594414-1-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
Message-ID: <20210805155357.594414-7-claudiu.beznea@microchip.com>

Document CalAmp LMU5000.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index a9ab18510fef..08efb259a947 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -132,6 +132,12 @@ properties:
           - const: atmel,at91sam9g20
           - const: atmel,at91sam9
 
+      - description: Exegin Q5xR5 board
+        items:
+          - const: exegin,q5xr5
+          - const: atmel,at91sam9g20
+          - const: atmel,at91sam9
+
       - items:
           - enum:
               - atmel,sama5d31
-- 
2.25.1



From claudiu.beznea at microchip.com  Thu Aug  5 08:53:57 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 5 Aug 2021 18:53:57 +0300
Subject: [PATCH 7/7] ARM: dts: at91: add CalAmp LMU5000 board
In-Reply-To: <20210805155357.594414-1-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
Message-ID: <20210805155357.594414-8-claudiu.beznea@microchip.com>

From: Adam Porter <porter.adam at gmail.com>

Add CalAmp LMU5000 board. The base device tree is from OpenWrt tree and
with the addition of this patch there will be no need to maintain it
separatelly in OpenWrt.

[porter.adam: original author of patch in OpenWrt]
Signed-off-by: Adam Porter <porter.adam at gmail.com>
[claudiu.beznea: fixed compilation warnings, use &<lable> syntax,
 sorted nodes in alphabetical order, adapted flash to new support
 in kernel 5.14, use proper compatibles according to kernel 5.14,
 use macros instead of hard coded numbers for pinctrl phandles and
 for all pinctrl references, add pinctrl-names, pinctrl-X where
 necessary]
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/Makefile         |   1 +
 arch/arm/boot/dts/at91-lmu5000.dts | 148 +++++++++++++++++++++++++++++
 2 files changed, 149 insertions(+)
 create mode 100644 arch/arm/boot/dts/at91-lmu5000.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 34f6ead22048..07be55262516 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -25,6 +25,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
 	usb_a9263.dtb \
 	at91-foxg20.dtb \
 	at91-kizbox.dtb \
+	at91-lmu5000.dtb \
 	at91sam9g20ek.dtb \
 	at91sam9g20ek_2mmc.dtb \
 	tny_a9g20.dtb \
diff --git a/arch/arm/boot/dts/at91-lmu5000.dts b/arch/arm/boot/dts/at91-lmu5000.dts
new file mode 100644
index 000000000000..6a52728cc98f
--- /dev/null
+++ b/arch/arm/boot/dts/at91-lmu5000.dts
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Device Tree file for CalAmp LMU5000 board
+ *
+ * Copyright (C) 2013 Adam Porter <porter.adam at gmail.com>
+ */
+
+/dts-v1/;
+#include "at91sam9g20.dtsi"
+
+/ {
+	model = "CalAmp LMU5000";
+	compatible = "calamp,lmu5000", "atmel,at91sam9g20", "atmel,at91sam9";
+
+	chosen {
+		bootargs = "mem=64M console=ttyS0,115200 rootfstype=jffs2";
+	};
+
+	memory {
+		reg = <0x20000000 0x4000000>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		main_clock: clock at 0 {
+			compatible = "atmel,osc", "fixed-clock";
+			clock-frequency = <18432000>;
+		};
+	};
+};
+
+&dbgu {
+	status = "okay";
+};
+
+&ebi {
+	status = "okay";
+
+	nand_controller: nand-controller {
+		pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>;
+		pinctrl-names = "default";
+		status = "okay";
+
+		nand at 3 {
+			reg = <0x3 0x0 0x800000>;
+			rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>;
+			cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>;
+			nand-bus-width = <8>;
+			nand-ecc-mode = "soft";
+			nand-on-flash-bbt;
+			label = "atmel_nand";
+			status = "okay";
+
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				kernel at 0 {
+					label = "kernel";
+					reg = <0x0 0x400000>;
+				};
+
+				rootfs at 400000 {
+					label = "rootfs";
+					reg = <0x400000 0x3C00000>;
+				};
+
+				user1 at 4000000 {
+					label = "user1";
+					reg = <0x4000000 0x2000000>;
+				};
+
+				user2 at 6000000 {
+					label = "user2";
+					reg = <0x6000000 0x2000000>;
+				};
+			};
+		};
+	};
+};
+
+&macb0 {
+	phy-mode = "mii";
+	status = "okay";
+};
+
+&pinctrl {
+	board {
+		pinctrl_pck0_as_mck: pck0_as_mck {
+			atmel,pins = <AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+		};
+	};
+
+	usb0 {
+		pinctrl_usb1_vbus_gpio: usb0_vbus_gpio {
+			atmel,pins = <AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+		};
+	};
+};
+
+&ssc0 {
+	status = "okay";
+	pinctrl-0 = <&pinctrl_ssc0_tx>;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&usart0 {
+	pinctrl-0 =
+		<&pinctrl_usart0
+		 &pinctrl_usart0_rts
+		 &pinctrl_usart0_cts
+		 &pinctrl_usart0_dtr_dsr
+		 &pinctrl_usart0_dcd
+		 &pinctrl_usart0_ri>;
+	status = "okay";
+};
+
+&usart2 {
+	status = "okay";
+};
+
+&usb0 {
+	num-ports = <2>;
+	status = "okay";
+};
+
+&usb1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb1_vbus_gpio>;
+	atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "okay";
+};
+
-- 
2.25.1



From lorenzo.pieralisi at arm.com  Thu Aug  5 09:03:19 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 5 Aug 2021 17:03:19 +0100
Subject: [PATCH v7 2/9] ACPI/IORT: Add support for RMR node parsing
In-Reply-To: <20210805080724.480-3-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <20210805080724.480-3-shameerali.kolothum.thodi@huawei.com>
Message-ID: <20210805160319.GB23085@lpieralisi>

On Thu, Aug 05, 2021 at 09:07:17AM +0100, Shameer Kolothum wrote:

[...]

> +static void __init iort_node_get_rmr_info(struct acpi_iort_node *iort_node)
> +{
> +	struct acpi_iort_node *smmu;
> +	struct acpi_iort_rmr *rmr;
> +	struct acpi_iort_rmr_desc *rmr_desc;
> +	u32 map_count = iort_node->mapping_count;
> +	u32 sid;
> +	int i;
> +
> +	if (!iort_node->mapping_offset || map_count != 1) {
> +		pr_err(FW_BUG "Invalid ID mapping, skipping RMR node %p\n",
> +		       iort_node);
> +		return;
> +	}
> +
> +	/* Retrieve associated smmu and stream id */
> +	smmu = iort_node_get_id(iort_node, &sid, 0);
> +	if (!smmu) {
> +		pr_err(FW_BUG "Invalid SMMU reference, skipping RMR node %p\n",
> +		       iort_node);
> +		return;
> +	}
> +
> +	/* Retrieve RMR data */
> +	rmr = (struct acpi_iort_rmr *)iort_node->node_data;
> +	if (!rmr->rmr_offset || !rmr->rmr_count) {
> +		pr_err(FW_BUG "Invalid RMR descriptor array, skipping RMR node %p\n",
> +		       iort_node);
> +		return;
> +	}
> +
> +	rmr_desc = ACPI_ADD_PTR(struct acpi_iort_rmr_desc, iort_node,
> +				rmr->rmr_offset);
> +
> +	iort_rmr_desc_check_overlap(rmr_desc, rmr->rmr_count);
> +
> +	for (i = 0; i < rmr->rmr_count; i++, rmr_desc++) {
> +		struct iommu_resv_region *region;
> +		enum iommu_resv_type type;
> +		int prot = IOMMU_READ | IOMMU_WRITE;
> +		u64 addr = rmr_desc->base_address, size = rmr_desc->length;
> +
> +		if (!IS_ALIGNED(addr, SZ_64K) || !IS_ALIGNED(size, SZ_64K)) {
> +			/* PAGE align base addr and size */
> +			addr &= PAGE_MASK;
> +			size = PAGE_ALIGN(size + offset_in_page(rmr_desc->base_address));
> +
> +			pr_err(FW_BUG "RMR descriptor[0x%llx - 0x%llx] not aligned to 64K, continue with [0x%llx - 0x%llx]\n",
> +			       rmr_desc->base_address,
> +			       rmr_desc->base_address + rmr_desc->length - 1,
> +			       addr, addr + size - 1);
> +		}
> +		if (rmr->flags & IOMMU_RMR_REMAP_PERMITTED) {
> +			type = IOMMU_RESV_DIRECT_RELAXABLE;
> +			/*
> +			 * Set IOMMU_CACHE as IOMMU_RESV_DIRECT_RELAXABLE is
> +			 * normally used for allocated system memory that is
> +			 * then used for device specific reserved regions.
> +			 */
> +			prot |= IOMMU_CACHE;
> +		} else {
> +			type = IOMMU_RESV_DIRECT;
> +			/*
> +			 * Set IOMMU_MMIO as IOMMU_RESV_DIRECT is normally used
> +			 * for device memory like MSI doorbell.
> +			 */
> +			prot |= IOMMU_MMIO;
> +		}

On the prot value assignment based on the remapping flag, I'd like to
hear Robin/Joerg's opinion, I'd avoid being in a situation where
"normally" this would work but then we have to quirk it.

Is this a valid assumption _always_ ?

Thanks,
Lorenzo

> +
> +		region = iommu_alloc_resv_region(addr, size, prot, type);
> +		if (region) {
> +			region->fw_data.rmr.flags = rmr->flags;
> +			region->fw_data.rmr.sid = sid;
> +			region->fw_data.rmr.smmu = smmu;
> +			list_add_tail(&region->list, &iort_rmr_list);
> +		}
> +	}
> +}
> +
> +static void __init iort_parse_rmr(void)
> +{
> +	struct acpi_iort_node *iort_node, *iort_end;
> +	struct acpi_table_iort *iort;
> +	int i;
> +
> +	if (iort_table->revision < 3)
> +		return;
> +
> +	iort = (struct acpi_table_iort *)iort_table;
> +
> +	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
> +				 iort->node_offset);
> +	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
> +				iort_table->length);
> +
> +	for (i = 0; i < iort->node_count; i++) {
> +		if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND,
> +			       "IORT node pointer overflows, bad table!\n"))
> +			return;
> +
> +		if (iort_node->type == ACPI_IORT_NODE_RMR)
> +			iort_node_get_rmr_info(iort_node);
> +
> +		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
> +					 iort_node->length);
> +	}
> +}
>  
>  static void __init iort_init_platform_devices(void)
>  {
> @@ -1636,6 +1767,7 @@ void __init acpi_iort_init(void)
>  	}
>  
>  	iort_init_platform_devices();
> +	iort_parse_rmr();
>  }
>  
>  #ifdef CONFIG_ZONE_DMA
> -- 
> 2.17.1
> 


From mathieu.poirier at linaro.org  Thu Aug  5 09:15:06 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 5 Aug 2021 10:15:06 -0600
Subject: [PATCH v3 2/2] remoteproc: meson-mx-ao-arc: Add a driver for the
 AO ARC remote procesor
In-Reply-To: <CAFBinCB0-bAa7Y+YhscczarGrGuio37F8vRyfW6U2DiiDAvr-g@mail.gmail.com>
References: <20210717234859.351911-1-martin.blumenstingl@googlemail.com>
 <20210717234859.351911-3-martin.blumenstingl@googlemail.com>
 <20210728175823.GA2766167@p14s>
 <CAFBinCB0-bAa7Y+YhscczarGrGuio37F8vRyfW6U2DiiDAvr-g@mail.gmail.com>
Message-ID: <20210805161506.GA3205691@p14s>

On Wed, Aug 04, 2021 at 11:03:57PM +0200, Martin Blumenstingl wrote:
> Hi Mathieu,
> 
> thanks for taking the time to look into this!
> 
> (I will address any of your comments that I am not mentioning in this
> email anymore. Thanks a lot for the suggestions!)
> 
> On Wed, Jul 28, 2021 at 7:58 PM Mathieu Poirier
> <mathieu.poirier at linaro.org> wrote:
> [...]
> > > +     writel(FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
> > > +                            priv->sram_pa >> 14),
> > Indentation problem
> The idea here is to align priv->sram_pa with AO_REMAP_REG0... which
> are both arguments to FIELD_PREP

Right, this is what I would have expected.  When I applied the patch on my side
"priv->sram_pa ..." was aligned wiht the 'M' of "AO_REMAP_ ...".  

> Maybe using something like this will make that easier to read:
>     tmp = FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
>                                      priv->sram_pa >> 14);
>     writel(tmp, priv->remap_base + AO_REMAP_REG0);

I think the main problem is that
AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU is simply too long.  I
suggest making is shorter and add a comment to describe exactly what it does.

> 
> What do you think: leave it as is or use a separate variable?
> 
> [...]
> > > +     usleep_range(10, 100);
> >
> > I've seen this kind of mysterious timeouts in other patchset based vendor trees.
> > You likely don't know why it is needed so I won't ask.
> unfortunately this is also the case here
> 
> [...]
> > > +     priv->arc_reset = devm_reset_control_get_exclusive(dev, NULL);
> > > +     if (IS_ERR(priv->arc_reset)) {
> >
> > Function __reset_control_get() in __devm_reset_control_get() can return NULL so
> > this should be IS_ERR_OR_NULL().
> The logic in there is: return optional ? NULL : ERR_PTR(-...);

Ok, so you meant to do that.  And I just checked reset_control_reset() and it does
account for a NULL parameter.  I'm good with this one but add a comment to
make sure future readers don't think you've omitted to properly deal with the
NULL return value.

> I am requesting a mandatory reset line here, so reset core will never
> return NULL
> See also [0]

Indeed, I've read that too.  Nonetheless __reset_control_get() can return NULL
by way of __reset_control_get_from_lookup().

> 
> For this reason I am not planning to change this
> 
> [...]
> > This driver is squeaky clean. With the above:
> >
> > Reviewed-by: Mathieu Poirier <mathieu.poirier at linaro.org>
> awesome, thank you!
> 
> 
> Best regards,
> Martin
> 
> 
> [0] https://elixir.bootlin.com/linux/v5.14-rc4/source/include/linux/reset.h#L227


From robin.murphy at arm.com  Thu Aug  5 09:27:36 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 5 Aug 2021 17:27:36 +0100
Subject: [PATCH v3 2/7] soc: rockchip: io-domain: add rk3568 support
In-Reply-To: <20210805120107.27007-3-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
 <20210805120107.27007-3-michael.riesch@wolfvision.net>
Message-ID: <8008800c-c518-30d4-edcf-57566e7a1251@arm.com>

On 2021-08-05 13:01, Michael Riesch wrote:
> From: Jianqun Xu <jay.xu at rock-chips.com>
> 
> The io-domain registers on RK3568 SoCs have three separated bits to
> enable/disable the 1.8v/2.5v/3.3v power.
> 
> This patch make the write to be a operation, allow rk3568 uses a private
> register set function.
> 
> Since the 2.5v is not used on RK3568, so the driver only set

FWIW, this seems at odds with what the first paragraph says - can anyone 
clarify what exactly "not used" means here? Is it that the I/O domain 
controller has been redesigned to support more than two logic levels on 
the new generation of SoCs, but RK3568's I/O pads still only physically 
support 1.8v and 3.3v; or is it that it *can* support 2.5v as well but 
no currently-known RK3568-based designs use that?

In the former case it's just a wording issue in the commit message, but 
in the latter it's arguably worth implementing support now for the sake 
of future compatibility.

Robin.

> 1.8v [enable] + 3.3v [disable] for 1.8v mode
> 1.8v [disable] + 3.3v [enable] for 3.3v mode
> 
> There is not register order requirement which has been cleared by our IC
> team.
> 
> Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
> ---
>   drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
>   1 file changed, 80 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
> index cf8182fc3642..13c446fd33a9 100644
> --- a/drivers/soc/rockchip/io-domain.c
> +++ b/drivers/soc/rockchip/io-domain.c
> @@ -51,13 +51,11 @@
>   #define RK3399_PMUGRF_CON0_VSEL		BIT(8)
>   #define RK3399_PMUGRF_VSEL_SUPPLY_NUM	9
>   
> -struct rockchip_iodomain;
> +#define RK3568_PMU_GRF_IO_VSEL0		(0x0140)
> +#define RK3568_PMU_GRF_IO_VSEL1		(0x0144)
> +#define RK3568_PMU_GRF_IO_VSEL2		(0x0148)
>   
> -struct rockchip_iodomain_soc_data {
> -	int grf_offset;
> -	const char *supply_names[MAX_SUPPLIES];
> -	void (*init)(struct rockchip_iodomain *iod);
> -};
> +struct rockchip_iodomain;
>   
>   struct rockchip_iodomain_supply {
>   	struct rockchip_iodomain *iod;
> @@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
>   	int idx;
>   };
>   
> +struct rockchip_iodomain_soc_data {
> +	int grf_offset;
> +	const char *supply_names[MAX_SUPPLIES];
> +	void (*init)(struct rockchip_iodomain *iod);
> +	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
> +};
> +
>   struct rockchip_iodomain {
>   	struct device *dev;
>   	struct regmap *grf;
>   	const struct rockchip_iodomain_soc_data *soc_data;
>   	struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
> +	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
>   };
>   
> +static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
> +{
> +	struct rockchip_iodomain *iod = supply->iod;
> +	u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
> +	u32 val0, val1;
> +	int b;
> +
> +	switch (supply->idx) {
> +	case 0: /* pmuio1 */
> +		break;
> +	case 1: /* pmuio2 */
> +		b = supply->idx;
> +		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
> +		b = supply->idx + 4;
> +		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
> +
> +		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
> +		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
> +		break;
> +	case 3: /* vccio2 */
> +		break;
> +	case 2: /* vccio1 */
> +	case 4: /* vccio3 */
> +	case 5: /* vccio4 */
> +	case 6: /* vccio5 */
> +	case 7: /* vccio6 */
> +	case 8: /* vccio7 */
> +		b = supply->idx - 1;
> +		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
> +		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
> +
> +		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
> +		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
> +		break;
> +	default:
> +		return -EINVAL;
> +	};
> +
> +	return 0;
> +}
> +
>   static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
>   				   int uV)
>   {
> @@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
>   			return NOTIFY_BAD;
>   	}
>   
> -	ret = rockchip_iodomain_write(supply, uV);
> +	ret = supply->iod->write(supply, uV);
>   	if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
>   		return NOTIFY_BAD;
>   
> @@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
>   	.init = rk3399_pmu_iodomain_init,
>   };
>   
> +static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
> +	.grf_offset = 0x140,
> +	.supply_names = {
> +		"pmuio1",
> +		"pmuio2",
> +		"vccio1",
> +		"vccio2",
> +		"vccio3",
> +		"vccio4",
> +		"vccio5",
> +		"vccio6",
> +		"vccio7",
> +	},
> +	.write = rk3568_iodomain_write,
> +};
> +
>   static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
>   	.grf_offset = 0x404,
>   	.supply_names = {
> @@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
>   		.compatible = "rockchip,rk3399-pmu-io-voltage-domain",
>   		.data = &soc_data_rk3399_pmu
>   	},
> +	{
> +		.compatible = "rockchip,rk3568-pmu-io-voltage-domain",
> +		.data = &soc_data_rk3568_pmu
> +	},
>   	{
>   		.compatible = "rockchip,rv1108-io-voltage-domain",
>   		.data = &soc_data_rv1108
> @@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>   	match = of_match_node(rockchip_iodomain_match, np);
>   	iod->soc_data = match->data;
>   
> +	if (iod->soc_data->write)
> +		iod->write = iod->soc_data->write;
> +	else
> +		iod->write = rockchip_iodomain_write;
> +
>   	parent = pdev->dev.parent;
>   	if (parent && parent->of_node) {
>   		iod->grf = syscon_node_to_regmap(parent->of_node);
> @@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>   		supply->reg = reg;
>   		supply->nb.notifier_call = rockchip_iodomain_notify;
>   
> -		ret = rockchip_iodomain_write(supply, uV);
> +		ret = iod->write(supply, uV);
>   		if (ret) {
>   			supply->reg = NULL;
>   			goto unreg_notify;
> 


From jon at solid-run.com  Thu Aug  5 09:31:47 2021
From: jon at solid-run.com (Jon Nettleton)
Date: Thu, 5 Aug 2021 18:31:47 +0200
Subject: [PATCH v7 2/9] ACPI/IORT: Add support for RMR node parsing
In-Reply-To: <20210805160319.GB23085@lpieralisi>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <20210805080724.480-3-shameerali.kolothum.thodi@huawei.com>
 <20210805160319.GB23085@lpieralisi>
Message-ID: <CABdtJHuhpnASw8NQb7dRo42Z5NqOzvtvjoyndsJ2jd+Qvsq7vQ@mail.gmail.com>

On Thu, Aug 5, 2021 at 6:03 PM Lorenzo Pieralisi
<lorenzo.pieralisi at arm.com> wrote:
>
> On Thu, Aug 05, 2021 at 09:07:17AM +0100, Shameer Kolothum wrote:
>
> [...]
>
> > +static void __init iort_node_get_rmr_info(struct acpi_iort_node *iort_node)
> > +{
> > +     struct acpi_iort_node *smmu;
> > +     struct acpi_iort_rmr *rmr;
> > +     struct acpi_iort_rmr_desc *rmr_desc;
> > +     u32 map_count = iort_node->mapping_count;
> > +     u32 sid;
> > +     int i;
> > +
> > +     if (!iort_node->mapping_offset || map_count != 1) {
> > +             pr_err(FW_BUG "Invalid ID mapping, skipping RMR node %p\n",
> > +                    iort_node);
> > +             return;
> > +     }
> > +
> > +     /* Retrieve associated smmu and stream id */
> > +     smmu = iort_node_get_id(iort_node, &sid, 0);
> > +     if (!smmu) {
> > +             pr_err(FW_BUG "Invalid SMMU reference, skipping RMR node %p\n",
> > +                    iort_node);
> > +             return;
> > +     }
> > +
> > +     /* Retrieve RMR data */
> > +     rmr = (struct acpi_iort_rmr *)iort_node->node_data;
> > +     if (!rmr->rmr_offset || !rmr->rmr_count) {
> > +             pr_err(FW_BUG "Invalid RMR descriptor array, skipping RMR node %p\n",
> > +                    iort_node);
> > +             return;
> > +     }
> > +
> > +     rmr_desc = ACPI_ADD_PTR(struct acpi_iort_rmr_desc, iort_node,
> > +                             rmr->rmr_offset);
> > +
> > +     iort_rmr_desc_check_overlap(rmr_desc, rmr->rmr_count);
> > +
> > +     for (i = 0; i < rmr->rmr_count; i++, rmr_desc++) {
> > +             struct iommu_resv_region *region;
> > +             enum iommu_resv_type type;
> > +             int prot = IOMMU_READ | IOMMU_WRITE;
> > +             u64 addr = rmr_desc->base_address, size = rmr_desc->length;
> > +
> > +             if (!IS_ALIGNED(addr, SZ_64K) || !IS_ALIGNED(size, SZ_64K)) {
> > +                     /* PAGE align base addr and size */
> > +                     addr &= PAGE_MASK;
> > +                     size = PAGE_ALIGN(size + offset_in_page(rmr_desc->base_address));
> > +
> > +                     pr_err(FW_BUG "RMR descriptor[0x%llx - 0x%llx] not aligned to 64K, continue with [0x%llx - 0x%llx]\n",
> > +                            rmr_desc->base_address,
> > +                            rmr_desc->base_address + rmr_desc->length - 1,
> > +                            addr, addr + size - 1);
> > +             }
> > +             if (rmr->flags & IOMMU_RMR_REMAP_PERMITTED) {
> > +                     type = IOMMU_RESV_DIRECT_RELAXABLE;
> > +                     /*
> > +                      * Set IOMMU_CACHE as IOMMU_RESV_DIRECT_RELAXABLE is
> > +                      * normally used for allocated system memory that is
> > +                      * then used for device specific reserved regions.
> > +                      */
> > +                     prot |= IOMMU_CACHE;
> > +             } else {
> > +                     type = IOMMU_RESV_DIRECT;
> > +                     /*
> > +                      * Set IOMMU_MMIO as IOMMU_RESV_DIRECT is normally used
> > +                      * for device memory like MSI doorbell.
> > +                      */
> > +                     prot |= IOMMU_MMIO;
> > +             }
>
> On the prot value assignment based on the remapping flag, I'd like to
> hear Robin/Joerg's opinion, I'd avoid being in a situation where
> "normally" this would work but then we have to quirk it.
>
> Is this a valid assumption _always_ ?

These assumptions were made based on the historic use cases I could
find reading the history.  There aren't many known examples "in the wild"
because so far we haven't had a mechanism other than quirks based
around device-tree implementations.

Ultimately I believe the proper solution will need to be another flag
in the RMR table that specifies the type of memory an RMR Node
describes, not just the base and length.

-Jon

>
> Thanks,
> Lorenzo
>
> > +
> > +             region = iommu_alloc_resv_region(addr, size, prot, type);
> > +             if (region) {
> > +                     region->fw_data.rmr.flags = rmr->flags;
> > +                     region->fw_data.rmr.sid = sid;
> > +                     region->fw_data.rmr.smmu = smmu;
> > +                     list_add_tail(&region->list, &iort_rmr_list);
> > +             }
> > +     }
> > +}
> > +
> > +static void __init iort_parse_rmr(void)
> > +{
> > +     struct acpi_iort_node *iort_node, *iort_end;
> > +     struct acpi_table_iort *iort;
> > +     int i;
> > +
> > +     if (iort_table->revision < 3)
> > +             return;
> > +
> > +     iort = (struct acpi_table_iort *)iort_table;
> > +
> > +     iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
> > +                              iort->node_offset);
> > +     iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
> > +                             iort_table->length);
> > +
> > +     for (i = 0; i < iort->node_count; i++) {
> > +             if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND,
> > +                            "IORT node pointer overflows, bad table!\n"))
> > +                     return;
> > +
> > +             if (iort_node->type == ACPI_IORT_NODE_RMR)
> > +                     iort_node_get_rmr_info(iort_node);
> > +
> > +             iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
> > +                                      iort_node->length);
> > +     }
> > +}
> >
> >  static void __init iort_init_platform_devices(void)
> >  {
> > @@ -1636,6 +1767,7 @@ void __init acpi_iort_init(void)
> >       }
> >
> >       iort_init_platform_devices();
> > +     iort_parse_rmr();
> >  }
> >
> >  #ifdef CONFIG_ZONE_DMA
> > --
> > 2.17.1
> >


From mathieu.poirier at linaro.org  Thu Aug  5 09:34:21 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 5 Aug 2021 10:34:21 -0600
Subject: [PATCH v3 2/5] remoteproc: imx_rproc: fix TCM io memory type
In-Reply-To: <AM5PR0402MB2756DE75C3231A0A15F7742788F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
 <20210805033206.1295269-2-aisheng.dong@nxp.com>
 <AM5PR0402MB2756DE75C3231A0A15F7742788F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>
Message-ID: <20210805163421.GB3205691@p14s>

On Thu, Aug 05, 2021 at 09:59:00AM +0000, Peng Fan wrote:
> > Subject: [PATCH v3 2/5] remoteproc: imx_rproc: fix TCM io memory type
> > 
> > is_iomem was introduced in the commit 40df0a91b2a5 ("remoteproc: add
> > is_iomem to da_to_va"), but the driver seemed missed to provide the io type
> > correctly.
> > This patch updates remoteproc driver to indicate the TCM on IMX are io
> > memories. Without the change, remoteproc kick will fail.
> > 
> > Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
> > Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> > Cc: Peng Fan <peng.fan at nxp.com>
> > Fixes: 79806d32d5aa ("remoteproc: imx_rproc: support i.MX8MN/P")
> > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>

Peng added his RB tag during V2 but it wasn't carried here.

> 
> Tested-by: Peng Fan <peng.fan at nxp.com>
> 
> > ---
> > ChangeLog:
> > v2->v3:
> >  * fix commit message typo and drop imx8ulp fixes tag
> >    Patch content unchanged.
> > v1->v2:
> >  * using ioremap_wc for non TCM memory
> > ---
> >  drivers/remoteproc/imx_rproc.c | 35 ++++++++++++++++++++--------------
> >  1 file changed, 21 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/remoteproc/imx_rproc.c
> > b/drivers/remoteproc/imx_rproc.c index d88f76f5305e..71dcc6dd32e4
> > 100644
> > --- a/drivers/remoteproc/imx_rproc.c
> > +++ b/drivers/remoteproc/imx_rproc.c
> > @@ -71,6 +71,7 @@ struct imx_rproc_mem {
> >  /* att flags */
> >  /* M4 own area. Can be mapped at probe */
> >  #define ATT_OWN		BIT(1)
> > +#define ATT_IOMEM	BIT(2)
> > 
> >  /* address translation table */
> >  struct imx_rproc_att {
> > @@ -117,7 +118,7 @@ struct imx_rproc {
> >  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
> >  	/* dev addr , sys addr  , size	    , flags */
> >  	/* ITCM   */
> > -	{ 0x00000000, 0x007E0000, 0x00020000, ATT_OWN },
> > +	{ 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
> >  	/* OCRAM_S */
> >  	{ 0x00180000, 0x00180000, 0x00009000, 0 },
> >  	/* OCRAM */
> > @@ -131,7 +132,7 @@ static const struct imx_rproc_att
> > imx_rproc_att_imx8mn[] = {
> >  	/* DDR (Code) - alias */
> >  	{ 0x10000000, 0x40000000, 0x0FFE0000, 0 },
> >  	/* DTCM */
> > -	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
> > +	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM },
> >  	/* OCRAM_S - alias */
> >  	{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
> >  	/* OCRAM */
> > @@ -147,7 +148,7 @@ static const struct imx_rproc_att
> > imx_rproc_att_imx8mn[] = {  static const struct imx_rproc_att
> > imx_rproc_att_imx8mq[] = {
> >  	/* dev addr , sys addr  , size	    , flags */
> >  	/* TCML - alias */
> > -	{ 0x00000000, 0x007e0000, 0x00020000, 0 },
> > +	{ 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM},
> >  	/* OCRAM_S */
> >  	{ 0x00180000, 0x00180000, 0x00008000, 0 },
> >  	/* OCRAM */
> > @@ -159,9 +160,9 @@ static const struct imx_rproc_att
> > imx_rproc_att_imx8mq[] = {
> >  	/* DDR (Code) - alias */
> >  	{ 0x10000000, 0x80000000, 0x0FFE0000, 0 },
> >  	/* TCML */
> > -	{ 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN },
> > +	{ 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN  | ATT_IOMEM},
> >  	/* TCMU */
> > -	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
> > +	{ 0x20000000, 0x00800000, 0x00020000, ATT_OWN  | ATT_IOMEM},
> >  	/* OCRAM_S */
> >  	{ 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
> >  	/* OCRAM */
> > @@ -199,12 +200,12 @@ static const struct imx_rproc_att
> > imx_rproc_att_imx7d[] = {
> >  	/* OCRAM_PXP (Code) - alias */
> >  	{ 0x00940000, 0x00940000, 0x00008000, 0 },
> >  	/* TCML (Code) */
> > -	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
> > +	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
> >  	/* DDR (Code) - alias, first part of DDR (Data) */
> >  	{ 0x10000000, 0x80000000, 0x0FFF0000, 0 },
> > 
> >  	/* TCMU (Data) */
> > -	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
> > +	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
> >  	/* OCRAM (Data) */
> >  	{ 0x20200000, 0x00900000, 0x00020000, 0 },
> >  	/* OCRAM_EPDC (Data) */
> > @@ -218,18 +219,18 @@ static const struct imx_rproc_att
> > imx_rproc_att_imx7d[] = {  static const struct imx_rproc_att
> > imx_rproc_att_imx6sx[] = {
> >  	/* dev addr , sys addr  , size	    , flags */
> >  	/* TCML (M4 Boot Code) - alias */
> > -	{ 0x00000000, 0x007F8000, 0x00008000, 0 },
> > +	{ 0x00000000, 0x007F8000, 0x00008000, ATT_IOMEM },
> >  	/* OCRAM_S (Code) */
> >  	{ 0x00180000, 0x008F8000, 0x00004000, 0 },
> >  	/* OCRAM_S (Code) - alias */
> >  	{ 0x00180000, 0x008FC000, 0x00004000, 0 },
> >  	/* TCML (Code) */
> > -	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
> > +	{ 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
> >  	/* DDR (Code) - alias, first part of DDR (Data) */
> >  	{ 0x10000000, 0x80000000, 0x0FFF8000, 0 },
> > 
> >  	/* TCMU (Data) */
> > -	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
> > +	{ 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
> >  	/* OCRAM_S (Data) - alias? */
> >  	{ 0x208F8000, 0x008F8000, 0x00004000, 0 },
> >  	/* DDR (Data) */
> > @@ -341,7 +342,7 @@ static int imx_rproc_stop(struct rproc *rproc)  }
> > 
> >  static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
> > -			       size_t len, u64 *sys)
> > +			       size_t len, u64 *sys, bool *is_iomem)
> >  {
> >  	const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> >  	int i;
> > @@ -354,6 +355,8 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv,
> > u64 da,
> >  			unsigned int offset = da - att->da;
> > 
> >  			*sys = att->sa + offset;
> > +			if (is_iomem)
> > +				*is_iomem = att->flags & ATT_IOMEM;
> >  			return 0;
> >  		}
> >  	}
> > @@ -377,7 +380,7 @@ static void *imx_rproc_da_to_va(struct rproc *rproc,
> > u64 da, size_t len, bool *i
> >  	 * On device side we have many aliases, so we need to convert device
> >  	 * address (M4) to system bus address first.
> >  	 */
> > -	if (imx_rproc_da_to_sys(priv, da, len, &sys))
> > +	if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem))
> >  		return NULL;
> > 
> >  	for (i = 0; i < IMX_RPROC_MEM_MAX; i++) { @@ -553,8 +556,12 @@
> > static int imx_rproc_addr_init(struct imx_rproc *priv,
> >  		if (b >= IMX_RPROC_MEM_MAX)
> >  			break;
> > 
> > -		priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
> > -						     att->sa, att->size);
> > +		if (att->flags & ATT_IOMEM)
> > +			priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
> > +							     att->sa, att->size);
> > +		else
> > +			priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
> > +								att->sa, att->size);
> >  		if (!priv->mem[b].cpu_addr) {
> >  			dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size,
> > att->sa);
> >  			return -ENOMEM;
> > --
> > 2.25.1
> 


From mathieu.poirier at linaro.org  Thu Aug  5 09:36:32 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 5 Aug 2021 10:36:32 -0600
Subject: [PATCH v3 5/5] remoteproc: imx_rproc: change to ioremap_wc for
 dram
In-Reply-To: <AM5PR0402MB275630A505C7828931043F1988F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
 <20210805033206.1295269-5-aisheng.dong@nxp.com>
 <AM5PR0402MB275630A505C7828931043F1988F29@AM5PR0402MB2756.eurprd04.prod.outlook.com>
Message-ID: <20210805163632.GC3205691@p14s>

On Thu, Aug 05, 2021 at 09:57:10AM +0000, Peng Fan (OSS) wrote:
> > Subject: [PATCH v3 5/5] remoteproc: imx_rproc: change to ioremap_wc for
> > dram
> > 
> > DRAM is not io memory, so changed to ioremap_wc. This is also aligned with
> > core io accessories. e.g. memcpy/memset and cpu direct access.
> > 
> > Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
> > Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> > Cc: Peng Fan <peng.fan at nxp.com>
> > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> 
> Reviewed-by: Peng Fan <peng.fan at nxp.com>
>

Did you test this one as well?

> > ---
> > v2->v3:
> >  * patch content unchanged.
> >    Only drop the wrong tag in v2
> >    Tested on MX8MQ and MX8MP, MX7ULP.
> > v1->v2:
> >  * new patch
> > ---
> >  drivers/remoteproc/imx_rproc.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/remoteproc/imx_rproc.c
> > b/drivers/remoteproc/imx_rproc.c index ff620688fad9..4ae416ba5080
> > 100644
> > --- a/drivers/remoteproc/imx_rproc.c
> > +++ b/drivers/remoteproc/imx_rproc.c
> > @@ -597,7 +597,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
> >  			break;
> > 
> >  		/* Not use resource version, because we might share region */
> > -		priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, res.start,
> > resource_size(&res));
> > +		priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
> > res.start,
> > +resource_size(&res));
> >  		if (!priv->mem[b].cpu_addr) {
> >  			dev_err(dev, "failed to remap %pr\n", &res);
> >  			return -ENOMEM;
> > --
> > 2.25.1
> 


From mathieu.poirier at linaro.org  Thu Aug  5 09:37:23 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 5 Aug 2021 10:37:23 -0600
Subject: [PATCH v3 1/5] remoteproc: fix the wrong default value of is_iomem
In-Reply-To: <20210805033206.1295269-1-aisheng.dong@nxp.com>
References: <20210805033206.1295269-1-aisheng.dong@nxp.com>
Message-ID: <20210805163723.GD3205691@p14s>

Please respin this set with all the RB and TB tags.

Thanks,
Mathieu

On Thu, Aug 05, 2021 at 11:32:02AM +0800, Dong Aisheng wrote:
> Currently the is_iomem is a random value in the stack which may
> be default to true even on those platforms that not use iomem to
> store firmware.
> 
> Cc: Bjorn Andersson <bjorn.andersson at linaro.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Fixes: 40df0a91b2a5 ("remoteproc: add is_iomem to da_to_va")
> Reviewed-by: Peng Fan <peng.fan at nxp.com>
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> ---
> v2->v3:
>  * no changes
> v1->v2:
>  * update rproc_copy_segment as well
> ---
>  drivers/remoteproc/remoteproc_coredump.c   | 2 +-
>  drivers/remoteproc/remoteproc_elf_loader.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/remoteproc/remoteproc_coredump.c b/drivers/remoteproc/remoteproc_coredump.c
> index aee657cc08c6..c892f433a323 100644
> --- a/drivers/remoteproc/remoteproc_coredump.c
> +++ b/drivers/remoteproc/remoteproc_coredump.c
> @@ -152,8 +152,8 @@ static void rproc_copy_segment(struct rproc *rproc, void *dest,
>  			       struct rproc_dump_segment *segment,
>  			       size_t offset, size_t size)
>  {
> +	bool is_iomem = false;
>  	void *ptr;
> -	bool is_iomem;
>  
>  	if (segment->dump) {
>  		segment->dump(rproc, segment, dest, offset, size);
> diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
> index e8078efb3dec..3cd1798f17a3 100644
> --- a/drivers/remoteproc/remoteproc_elf_loader.c
> +++ b/drivers/remoteproc/remoteproc_elf_loader.c
> @@ -178,8 +178,8 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
>  		u64 filesz = elf_phdr_get_p_filesz(class, phdr);
>  		u64 offset = elf_phdr_get_p_offset(class, phdr);
>  		u32 type = elf_phdr_get_p_type(class, phdr);
> +		bool is_iomem = false;
>  		void *ptr;
> -		bool is_iomem;
>  
>  		if (type != PT_LOAD)
>  			continue;
> -- 
> 2.25.1
> 


From mathieu.poirier at linaro.org  Thu Aug  5 09:39:43 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 5 Aug 2021 10:39:43 -0600
Subject: [PATCH 1/2] arm64: dts: imx8mq: add remoteproc m4 support
In-Reply-To: <20210805091218.1626290-1-aisheng.dong@nxp.com>
References: <20210805091218.1626290-1-aisheng.dong@nxp.com>
Message-ID: <20210805163943.GE3205691@p14s>

Same for this set - I need Peng to add his RB _and_ TB tags to it before I
consider for review.  Also, please start adding cover letters to your patchsets.

Thanks,
Mathieu

On Thu, Aug 05, 2021 at 05:12:17PM +0800, Dong Aisheng wrote:
> Add cm4 remoteproc which supports rpmsg naming service.
> It needs vdevbuffer and a pair of vrings and 16MB reserved memory.
> 
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/Makefile        |  1 +
>  .../boot/dts/freescale/imx8mq-evk-rpmsg.dts   | 72 +++++++++++++++++++
>  2 files changed, 73 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mq-evk-rpmsg.dts
> 
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 4b4785d86324..687ad9d68a85 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -49,6 +49,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mn-var-som-symphony.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb
> +dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk-rpmsg.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mq-hummingboard-pulse.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mq-kontron-pitx-imx8m.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-devkit.dtb
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk-rpmsg.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk-rpmsg.dts
> new file mode 100644
> index 000000000000..4a8911087e5f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk-rpmsg.dts
> @@ -0,0 +1,72 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright 2019-2021 NXP
> + */
> +
> +#include "imx8mq-evk.dts"
> +
> +/ {
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		vdev0vring0: vdev0vring0 at b8000000 {
> +			reg = <0 0xb8000000 0 0x8000>;
> +			no-map;
> +		};
> +
> +		vdev0vring1: vdev0vring1 at b8008000 {
> +			reg = <0 0xb8008000 0 0x8000>;
> +			no-map;
> +		};
> +
> +		rsc_table: rsc-table at b80ff000 {
> +			reg = <0 0xb80ff000 0 0x1000>;
> +			no-map;
> +		};
> +
> +		vdevbuffer: vdevbuffer at b8400000 {
> +			compatible = "shared-dma-pool";
> +			reg = <0 0xb8400000 0 0x100000>;
> +			no-map;
> +		};
> +
> +		remoteproc at 80000000 {
> +			reg = <0 0x80000000 0 0x1000000>;
> +			no-map;
> +		};
> +	};
> +
> +	imx8mq-cm4 {
> +		compatible = "fsl,imx8mq-cm4";
> +		clocks = <&clk IMX8MQ_CLK_M4_DIV>;
> +		mbox-names = "tx", "rx", "rxdb";
> +		mboxes = <&mu 0 1
> +			  &mu 1 1
> +			  &mu 3 1>;
> +		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
> +				<&rsc_table>;
> +		syscon = <&src>;
> +	};
> +};
> +
> +/*
> + * Below devices are allocated on remoteproc
> + */
> +
> +&i2c2 {
> +	status = "disabled";
> +};
> +
> +&pwm4 {
> +	status = "disabled";
> +};
> +
> +&tmu {
> +	status = "disabled";
> +};
> +
> +&uart2 {
> +	status = "disabled";
> +};
> -- 
> 2.25.1
> 


From mhiramat at kernel.org  Thu Aug  5 09:44:35 2021
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Fri, 6 Aug 2021 01:44:35 +0900
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <d3e0c9ee-19b5-8042-d251-05348e8ac49e@huawei.com>
References: <20210804060209.95817-1-liuqi115@huawei.com>
 <20210805105401.4acd3217c566b4e3933f355c@kernel.org>
 <d3e0c9ee-19b5-8042-d251-05348e8ac49e@huawei.com>
Message-ID: <20210806014435.a1b6d7900e0e72599a8e325f@kernel.org>

On Thu, 5 Aug 2021 17:25:17 +0800
"liuqi (BA)" <liuqi115 at huawei.com> wrote:

> 
> Hi Masami,
> 
> On 2021/8/5 9:54, Masami Hiramatsu wrote:
> > On Wed, 4 Aug 2021 14:02:09 +0800
> > Qi Liu <liuqi115 at huawei.com> wrote:
> > 
> >> This patch introduce optprobe for ARM64. In optprobe, probed
> >> instruction is replaced by a branch instruction to detour
> >> buffer. Detour buffer contains trampoline code and a call to
> >> optimized_callback(). optimized_callback() calls opt_pre_handler()
> >> to execute kprobe handler.
> >>
> >> Limitations:
> >> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
> >> guarantee the offset between probe point and kprobe pre_handler
> >> is not larger than 128MiB.
> >>
> >> Performance of optprobe on Hip08 platform is test using kprobe
> >> example module[1] to analyze the latency of a kernel function,
> >> and here is the result:
> >>
> >> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> >>
> >> kprobe before optimized:
> >> [280709.846380] do_empty returned 0 and took 1530 ns to execute
> >> [280709.852057] do_empty returned 0 and took 550 ns to execute
> >> [280709.857631] do_empty returned 0 and took 440 ns to execute
> >> [280709.863215] do_empty returned 0 and took 380 ns to execute
> >> [280709.868787] do_empty returned 0 and took 360 ns to execute
> >> [280709.874362] do_empty returned 0 and took 340 ns to execute
> >> [280709.879936] do_empty returned 0 and took 320 ns to execute
> >> [280709.885505] do_empty returned 0 and took 300 ns to execute
> >> [280709.891075] do_empty returned 0 and took 280 ns to execute
> >> [280709.896646] do_empty returned 0 and took 290 ns to execute
> >> [280709.902220] do_empty returned 0 and took 290 ns to execute
> >> [280709.907807] do_empty returned 0 and took 290 ns to execute
> >>
> >> optprobe:
> >> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> >> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> >> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> >> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> >> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> >> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> >> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> >> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> >> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> >> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> >> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> >> [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> >> [ 2966.029158] do_empty returned 0 and took 70 ns to execute
> >>
> >> Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> >>
> >> ---
> >>
> >> Changes since V1:
> >> - Address the comments from Masami, checks for all branch instructions, and
> >> use aarch64_insn_patch_text_nosync() instead of aarch64_insn_patch_text()
> >> in each probe.
> > 
> > Is it safe for the multicore system? If it is safe because it modifies
> > just one instruction (modifying 32bit in atomic), I understand it.
> 
> Seems raw_spin_lock_irqsave is used in aarch64_insn_patch_text_nosync() 
> and spinlock could support a protection in multicore system.

No, that is not what I meant. stop_machine() will ensure that the all other
cores parking in the safe area, so the target instruction will never be
executed while modifying the code.
Even if you use the spinlock, other cores don't stop unless it tries
to lock the same spinlock. And they are possible to execute the instruction
which you are modifying.

> > BTW, anyway, you should use _nosync() variant in arch_prepare_optimized_kprobe()
> > too, beacause the optprobe insn buffer is not touched until the probed instruction
> > is optimized by br.
> > 
> Yes, sounds resonable.
> > [...]
> >> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
> >> +{
> >> +	kprobe_opcode_t *code;
> >> +	u32 insn;
> >> +	int ret, i;
> >> +	void *addrs[TMPL_END_IDX];
> >> +	void *addr;
> >> +
> >> +	code = get_optinsn_slot();
> >> +	if (!code)
> >> +		return -ENOMEM;
> >> +
> >> +	if (!is_offset_in_range((unsigned long)code,
> >> +				(unsigned long)orig->addr + 8))
> >> +		goto error;
> >> +
> >> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
> >> +				(unsigned long)optimized_callback))
> >> +		goto error;
> >> +
> >> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
> >> +				(unsigned long)op->kp.addr + 4))
> >> +		goto error;
> >> +
> >> +	/* Setup template */
> >> +	for (i = 0; i < TMPL_END_IDX; i++)
> >> +		addrs[i] = code + i;
> >> +
> >> +	ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
> >> +				      TMPL_END_IDX);
> > 
> > You should use aarch64_insn_patch_text_nosync() here (and all the
> > aarch64_insn_patch_text() in this function too), because the insn
> > buffer must not executed until the probe point is optimized.
> > 
> aarch64_insn_patch_text() could patch multi instructions to code[] each 
> time and aarch64_insn_patch_text_nosync() could only patch one 
> instruction each time,

Ah, right. 

> so maybe aarch64_insn_patch_text() is better here.
> 
> I'll replace other aarch64_insn_patch_text() in this function.

Could you see x86 optprobe code what it does?
I prepare another writable buffer and build the trampoline code
on it. Finally patch the code on the insn buffer at once.
You can do the same thing here.

Thank you,

> 
> Thanks,
> Qi
> 
> >> +	if (ret < 0)
> >> +		goto error;
> >> +
> >> +	/* Set probe information */
> >> +	addr = code + TMPL_VAL_IDX;
> >> +	insn =  (unsigned long long)op & 0xffffffff;
> >> +	aarch64_insn_patch_text(&addr, &insn, 1);
> >> +
> >> +	addr = addr + 4;
> >> +	insn = ((unsigned long long)op & GENMASK_ULL(63, 32)) >> 32;
> >> +	aarch64_insn_patch_text(&addr, &insn, 1);
> >> +
> >> +	addr = code + TMPL_CALL_BACK;
> >> +	insn =  aarch64_insn_gen_branch_imm((unsigned long)addr,
> >> +				(unsigned long)optimized_callback,
> >> +				AARCH64_INSN_BRANCH_LINK);
> >> +	aarch64_insn_patch_text(&addr, &insn, 1);
> >> +
> >> +	/* The original probed instruction */
> >> +	addr = code + TMPL_RESTORE_ORIGN_INSN;
> >> +	insn =  orig->opcode;
> >> +	aarch64_insn_patch_text(&addr, &insn, 1);
> >> +
> >> +	/* Jump back to next instruction */
> >> +	addr = code + TMPL_RESTORE_END;
> >> +	insn = aarch64_insn_gen_branch_imm(
> >> +				(unsigned long)(&code[TMPL_RESTORE_END]),
> >> +				(unsigned long)(op->kp.addr) + 4,
> >> +				AARCH64_INSN_BRANCH_NOLINK);
> >> +	aarch64_insn_patch_text(&addr, &insn, 1);
> >> +
> >> +	flush_icache_range((unsigned long)code,
> >> +			   (unsigned long)(&code[TMPL_END_IDX]));
> >> +	/* Set op->optinsn.insn means prepared. */
> >> +	op->optinsn.insn = code;
> >> +
> >> +	return 0;
> > 
> > Thank you,
> > 
> > 
> > 
> 


-- 
Masami Hiramatsu <mhiramat at kernel.org>


From catalin.marinas at arm.com  Thu Aug  5 10:03:18 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 5 Aug 2021 18:03:18 +0100
Subject: [RFC V2 01/10] mm/mmap: Dynamically initialize protection_map[]
In-Reply-To: <1627281445-12445-2-git-send-email-anshuman.khandual@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-2-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210805170318.GB6719@arm.com>

On Mon, Jul 26, 2021 at 12:07:16PM +0530, Anshuman Khandual wrote:
> The protection_map[] elements (__PXXX and __SXXX) might sometimes contain
> runtime variables in certain platforms like arm64 preventing a successful
> build because of the current static initialization. So it just defers the
> initialization until mmmap_init() via a new helper init_protection_map().
> 
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  mm/mmap.c | 26 ++++++++++++++++++++++----
>  1 file changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/mm/mmap.c b/mm/mmap.c
> index ca54d36..a95b078 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -100,10 +100,7 @@ static void unmap_region(struct mm_struct *mm,
>   *								w: (no) no
>   *								x: (yes) yes
>   */
> -pgprot_t protection_map[16] __ro_after_init = {
> -	__P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
> -	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
> -};
> +pgprot_t protection_map[16] __ro_after_init;

Mips, x86, sparc, arm32, m68k all adjust protection_map[] during boot.
Could we do something similar here and avoid changing the generic code?

-- 
Catalin


From catalin.marinas at arm.com  Thu Aug  5 10:05:40 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 5 Aug 2021 18:05:40 +0100
Subject: [RFC V2 02/10] arm64/mm: Consolidate TCR_EL1 fields
In-Reply-To: <1627281445-12445-3-git-send-email-anshuman.khandual@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-3-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210805170540.GC6719@arm.com>

On Mon, Jul 26, 2021 at 12:07:17PM +0530, Anshuman Khandual wrote:
> This renames and moves SYS_TCR_EL1_TCMA1 and SYS_TCR_EL1_TCMA0 definitions
> into pgtable-hwdef.h thus consolidating all TCR fields in a single header.
> This does not cause any functional change.
> 
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

Not sure how we ended up with TCR definitions in two places.

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Aug  5 10:06:00 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 5 Aug 2021 18:06:00 +0100
Subject: [RFC V2 03/10] arm64/mm: Add FEAT_LPA2 specific TCR_EL1.DS field
In-Reply-To: <1627281445-12445-4-git-send-email-anshuman.khandual@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-4-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210805170559.GD6719@arm.com>

On Mon, Jul 26, 2021 at 12:07:18PM +0530, Anshuman Khandual wrote:
> As per ARM ARM (0487G.A) TCR_EL1.DS fields controls whether 52 bit input
> and output address get supported on 4K and 16K page size configuration,
> when FEAT_LPA2 is known to have been implemented. This adds TCR_DS field
> definition which would be used when FEAT_LPA2 gets enabled.
> 
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Aug  5 10:06:36 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 5 Aug 2021 18:06:36 +0100
Subject: [RFC V2 04/10] arm64/mm: Add FEAT_LPA2 specific
 ID_AA64MMFR0.TGRAN[2]
In-Reply-To: <1627281445-12445-5-git-send-email-anshuman.khandual@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-5-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210805170636.GE6719@arm.com>

On Mon, Jul 26, 2021 at 12:07:19PM +0530, Anshuman Khandual wrote:
> PAGE_SIZE support is tested against possible minimum and maximum values for
> its respective ID_AA64MMFR0.TGRAN field, depending on whether it is signed
> or unsigned. But then FEAT_LPA2 implementation needs to be validated for 4K
> and 16K page sizes via feature specific ID_AA64MMFR0.TGRAN values. Hence it
> adds FEAT_LPA2 specific ID_AA64MMFR0.TGRAN[2] values per ARM ARM (0487G.A).
> 
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From mcroce at linux.microsoft.com  Thu Aug  5 10:10:59 2021
From: mcroce at linux.microsoft.com (Matteo Croce)
Date: Thu,  5 Aug 2021 19:10:59 +0200
Subject: [RFT net-next 0/2] stmmac: recycle SKB
Message-ID: <20210805171101.13776-1-mcroce@linux.microsoft.com>

From: Matteo Croce <mcroce at microsoft.com>

I have two patches to enable SKB recycling in stmmac. Unfortunately the
only stmmac hardware I have behave very bad, so I can't do decent
performance tests.
Can I get some feedback for this series?


Matteo Croce (2):
  stmmac: use build_skb()
  stmmac: skb recycling

 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

-- 
2.31.1



From mcroce at linux.microsoft.com  Thu Aug  5 10:11:00 2021
From: mcroce at linux.microsoft.com (Matteo Croce)
Date: Thu,  5 Aug 2021 19:11:00 +0200
Subject: [RFT net-next 1/2] stmmac: use build_skb()
In-Reply-To: <20210805171101.13776-1-mcroce@linux.microsoft.com>
References: <20210805171101.13776-1-mcroce@linux.microsoft.com>
Message-ID: <20210805171101.13776-2-mcroce@linux.microsoft.com>

From: Matteo Croce <mcroce at microsoft.com>

Signed-off-by: Matteo Croce <mcroce at microsoft.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a2aa75cb184e..30a0d915cd4b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5208,7 +5208,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 			/* XDP program may expand or reduce tail */
 			buf1_len = xdp.data_end - xdp.data;
 
-			skb = napi_alloc_skb(&ch->rx_napi, buf1_len);
+			skb = build_skb(xdp.data_hard_start, PAGE_SIZE);
 			if (!skb) {
 				priv->dev->stats.rx_dropped++;
 				count++;
@@ -5216,11 +5216,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 			}
 
 			/* XDP program may adjust header */
-			skb_copy_to_linear_data(skb, xdp.data, buf1_len);
+			skb_reserve(skb, buf->page_offset);
 			skb_put(skb, buf1_len);
 
-			/* Data payload copied into SKB, page ready for recycle */
-			page_pool_recycle_direct(rx_q->page_pool, buf->page);
+			page_pool_release_page(rx_q->page_pool, buf->page);
 			buf->page = NULL;
 		} else if (buf1_len) {
 			dma_sync_single_for_cpu(priv->device, buf->addr,
-- 
2.31.1



From mcroce at linux.microsoft.com  Thu Aug  5 10:11:01 2021
From: mcroce at linux.microsoft.com (Matteo Croce)
Date: Thu,  5 Aug 2021 19:11:01 +0200
Subject: [RFT net-next 2/2] stmmac: skb recycling
In-Reply-To: <20210805171101.13776-1-mcroce@linux.microsoft.com>
References: <20210805171101.13776-1-mcroce@linux.microsoft.com>
Message-ID: <20210805171101.13776-3-mcroce@linux.microsoft.com>

From: Matteo Croce <mcroce at microsoft.com>

Signed-off-by: Matteo Croce <mcroce at microsoft.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 30a0d915cd4b..2c48f1b5e9e9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5219,7 +5219,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 			skb_reserve(skb, buf->page_offset);
 			skb_put(skb, buf1_len);
 
-			page_pool_release_page(rx_q->page_pool, buf->page);
+			skb_mark_for_recycle(skb, buf->page, rx_q->page_pool);
 			buf->page = NULL;
 		} else if (buf1_len) {
 			dma_sync_single_for_cpu(priv->device, buf->addr,
@@ -5229,7 +5229,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 					priv->dma_buf_sz);
 
 			/* Data payload appended into SKB */
-			page_pool_release_page(rx_q->page_pool, buf->page);
+			page_pool_store_mem_info(buf->page, rx_q->page_pool);
 			buf->page = NULL;
 		}
 
@@ -5241,7 +5241,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 					priv->dma_buf_sz);
 
 			/* Data payload appended into SKB */
-			page_pool_release_page(rx_q->page_pool, buf->sec_page);
+			page_pool_store_mem_info(buf->sec_page, rx_q->page_pool);
 			buf->sec_page = NULL;
 		}
 
-- 
2.31.1



From jason-jh.lin at mediatek.com  Thu Aug  5 10:13:46 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 01:13:46 +0800
Subject: [PATCH v3 4/4] dt-bindings: mediatek: display: add mt8195 SoC binding
In-Reply-To: <20210805171346.24249-1-jason-jh.lin@mediatek.com>
References: <20210805171346.24249-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805171346.24249-5-jason-jh.lin@mediatek.com>

1. Add mt8195 SoC binding to AAL, CCORR, COLOR, DITHER, GAMMA, MERGE,
   MUTEX, OVL and RDMA yaml schema.

2. Add MERGE additional property description for mt8195
- async clock
- fifo setting enable
- reset controller

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,aal.yaml        |  1 +
 .../display/mediatek/mediatek,ccorr.yaml      |  5 +++
 .../display/mediatek/mediatek,color.yaml      |  1 +
 .../display/mediatek/mediatek,dither.yaml     |  5 +++
 .../display/mediatek/mediatek,gamma.yaml      |  5 +++
 .../display/mediatek/mediatek,merge.yaml      | 40 +++++++++++++++++++
 .../display/mediatek/mediatek,mutex.yaml      |  2 +
 .../display/mediatek/mediatek,ovl.yaml        |  5 +++
 .../display/mediatek/mediatek,rdma.yaml       |  2 +
 9 files changed, 66 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
index 7be772d77e36..e1820238db43 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -25,6 +25,7 @@ properties:
           - enum:
               - mediatek,mt2712-disp-aal
               - mediatek,mt8183-disp-aal
+              - mediatek,mt8195-disp-aal
           - enum:
               - mediatek,mt8173-disp-aal
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
index 5a1c27d6b3e2..4c556a2bc64a 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -21,6 +21,11 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8183-disp-ccorr
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ccorr
+          - enum:
+              - mediatek,mt8183-disp-ccorr
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
index 9a3edf6f0b8e..a13096196a0c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -35,6 +35,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8183-disp-color
+              - mediatek,mt8195-disp-color
           - enum:
               - mediatek,mt8173-disp-color
   reg:
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
index 20419f876410..e89fe7393291 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -22,6 +22,11 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8183-disp-dither
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-dither
+          - enum:
+              - mediatek,mt8183-disp-dither
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
index e2a1fc218e4f..dc78d6d05dee 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -23,6 +23,11 @@ properties:
           - const: mediatek,mt8173-disp-gamma
       - items:
           - const: mediatek,mt8183-disp-gamma
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-gamma
+          - enum:
+              - mediatek,mt8183-disp-gamma
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 4cdce11d7fcd..1a27b037086b 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -21,6 +21,8 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8173-disp-merge
+      - items:
+          - const: mediatek,mt8195-disp-merge
 
   reg:
     maxItems: 1
@@ -36,6 +38,31 @@ properties:
   clocks:
     items:
       - description: MERGE Clock
+      - description: MERGE Async Clock
+          Controlling the synchronous process between MERGE and other display function
+          blocks cross clock domain.
+
+  mediatek,merge-fifo-en:
+      description:
+	    The setting of merge fifo is mainly provided for the display latency buffer.
+        to ensure that the back-end panel display data will not be underrun,
+        a little more data is needed in the fifo. According to the merge fifo settings,
+        when the water level is detected to be insufficient, it will trigger RDMA sending
+        ultra and preulra command to SMI to speed up the data rate.
+      type: boolean
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+  resets:
+    description: reset controller
+      See Documentation/devicetree/bindings/reset/reset.txt for details.
 
 required:
   - compatible
@@ -55,3 +82,16 @@ examples:
         clocks = <&mmsys CLK_MM_DISP_MERGE>;
     };
 
+    merge5: disp_vpp_merge5 at 1c110000 {
+        compatible = "mediatek,mt8195-disp-merge";
+        reg = <0 0x1c110000 0 0x1000>;
+        interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+                 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+        clock-names = "merge","merge_async";
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+        mediatek,merge-fifo-en = <1>;
+        resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
index aaba6bbfb4da..0dced7a53329 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -30,6 +30,8 @@ properties:
           - const: mediatek,mt8173-disp-mutex
       - items:
           - const: mediatek,mt8183-disp-mutex
+      - items:
+          - const: mediatek,mt8195-disp-mutex
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 833b0ca09b21..1973eee4244f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -31,6 +31,11 @@ properties:
               - mediatek,mt2712-disp-ovl
           - enum:
               - mediatek,mt2701-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ovl
+          - enum:
+              - mediatek,mt8183-disp-ovl
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
index ce3bcca30609..847bc55252ca 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -27,6 +27,8 @@ properties:
           - const: mediatek,mt8173-disp-rdma
       - items:
           - const: mediatek,mt8183-disp-rdma
+      - items:
+          - const: mediatek,mt8195-disp-rdma
       - items:
           - enum:
               - mediatek,mt7623-disp-rdma
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 10:13:42 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 01:13:42 +0800
Subject: [PATCH v3 0/4] add mt8195 SoC DRM binding
Message-ID: <20210805171346.24249-1-jason-jh.lin@mediatek.com>

Change in v3:
- slpit each display function block to individual taml file.

Change in v2:
- add power-domain property into mediatek,mmsys.yaml
  and modify commit message.

jason-jh.lin (4):
  dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
  dt-bindings: mediatek: display: split each block to individual yaml
  dt-bindings: mediatek: add mediatek,dsc.yaml for mt8195 SoC binding
  dt-bindings: mediatek: display: add mt8195 SoC binding

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |   8 +
 .../display/mediatek/mediatek,aal.yaml        |  76 ++++++
 .../display/mediatek/mediatek,ccorr.yaml      |  74 ++++++
 .../display/mediatek/mediatek,color.yaml      |  85 +++++++
 .../display/mediatek/mediatek,disp.txt        | 219 ------------------
 .../display/mediatek/mediatek,dither.yaml     |  75 ++++++
 .../display/mediatek/mediatek,dsc.yaml        |  69 ++++++
 .../display/mediatek/mediatek,gamma.yaml      |  76 ++++++
 .../display/mediatek/mediatek,merge.yaml      |  97 ++++++++
 .../display/mediatek/mediatek,mutex.yaml      |  79 +++++++
 .../display/mediatek/mediatek,od.yaml         |  52 +++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  86 +++++++
 .../display/mediatek/mediatek,ovl.yaml        | 101 ++++++++
 .../display/mediatek/mediatek,rdma.yaml       | 112 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  56 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  59 +++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
 17 files changed, 1191 insertions(+), 219 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml

-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 10:13:44 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 01:13:44 +0800
Subject: [PATCH v3 2/4] dt-bindings: mediatek: display: split each block to
 individual yaml
In-Reply-To: <20210805171346.24249-1-jason-jh.lin@mediatek.com>
References: <20210805171346.24249-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805171346.24249-3-jason-jh.lin@mediatek.com>

1. Remove mediatek,dislpay.txt
2. Split each display function block to individual yaml file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,aal.yaml        |  75 ++++++
 .../display/mediatek/mediatek,ccorr.yaml      |  69 ++++++
 .../display/mediatek/mediatek,color.yaml      |  84 +++++++
 .../display/mediatek/mediatek,disp.txt        | 219 ------------------
 .../display/mediatek/mediatek,dither.yaml     |  70 ++++++
 .../display/mediatek/mediatek,gamma.yaml      |  71 ++++++
 .../display/mediatek/mediatek,merge.yaml      |  57 +++++
 .../display/mediatek/mediatek,mutex.yaml      |  77 ++++++
 .../display/mediatek/mediatek,od.yaml         |  52 +++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  86 +++++++
 .../display/mediatek/mediatek,ovl.yaml        |  96 ++++++++
 .../display/mediatek/mediatek,rdma.yaml       | 110 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  56 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  59 +++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
 15 files changed, 1048 insertions(+), 219 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
new file mode 100644
index 000000000000..7be772d77e36
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display adaptive ambient light processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display adaptive ambient light processor, namely AAL,
+  is responsible for backlight power saving and sunlight visibility improving.
+  AAL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-aal
+      - items:
+          - enum:
+              - mediatek,mt2712-disp-aal
+              - mediatek,mt8183-disp-aal
+          - enum:
+              - mediatek,mt8173-disp-aal
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: AAL Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    aal at 14015000 {
+        compatible = "mediatek,mt8173-disp-aal";
+        reg = <0 0x14015000 0 0x1000>;
+        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_AAL>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..5a1c27d6b3e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek Ddsplay color correction
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display color correction, namely CCORR, reproduces correct color
+  on panels with different color gamut.
+  CCORR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ccorr
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: CCORR Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ccorr0: ccorr at 1400f000 {
+        compatible = "mediatek,mt8183-disp-ccorr";
+        reg = <0 0x1400f000 0 0x1000>;
+        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+    }
+;
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
new file mode 100644
index 000000000000..9a3edf6f0b8e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display color processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek color processor, namely COLOR, provides hue, luma and
+  saturation adjustments to get better picture quality and to have one panel
+  resemble the other in their output characteristics.
+  COLOR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-color
+      - items:
+          - const: mediatek,mt8167-disp-color
+      - items:
+          - const: mediatek,mt8173-disp-color
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-color
+              - mediatek,mt2712-disp-color
+          - enum:
+              - mediatek,mt2701-disp-color
+      - items:
+          - enum:
+              - mediatek,mt8183-disp-color
+          - enum:
+              - mediatek,mt8173-disp-color
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: COLOR Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    color0: color at 14013000 {
+        compatible = "mediatek,mt8173-disp-color";
+        reg = <0 0x14013000 0 0x1000>;
+        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
deleted file mode 100644
index fbb59c9ddda6..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ /dev/null
@@ -1,219 +0,0 @@
-Mediatek display subsystem
-==========================
-
-The Mediatek display subsystem consists of various DISP function blocks in the
-MMSYS register space. The connections between them can be configured by output
-and input selectors in the MMSYS_CONFIG register space. Pixel clock and start
-of frame signal are distributed to the other function blocks by a DISP_MUTEX
-function block.
-
-All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
-For a description of the MMSYS_CONFIG binding, see
-Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt.
-
-DISP function blocks
-====================
-
-A display stream starts at a source function block that reads pixel data from
-memory and ends with a sink function block that drives pixels on a display
-interface, or writes pixels back to memory. All DISP function blocks have
-their own register space, interrupt, and clock gate. The blocks that can
-access memory additionally have to list the IOMMU and local arbiter they are
-connected to.
-
-For a description of the display interface sink function blocks, see
-Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
-Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
-
-Required properties (all function blocks):
-- compatible: "mediatek,<chip>-disp-<function>", one of
-	"mediatek,<chip>-disp-ovl"   		- overlay (4 layers, blending, csc)
-	"mediatek,<chip>-disp-ovl-2l"           - overlay (2 layers, blending, csc)
-	"mediatek,<chip>-disp-rdma"  		- read DMA / line buffer
-	"mediatek,<chip>-disp-wdma"  		- write DMA
-	"mediatek,<chip>-disp-ccorr"            - color correction
-	"mediatek,<chip>-disp-color" 		- color processor
-	"mediatek,<chip>-disp-dither"           - dither
-	"mediatek,<chip>-disp-aal"   		- adaptive ambient light controller
-	"mediatek,<chip>-disp-gamma" 		- gamma correction
-	"mediatek,<chip>-disp-merge" 		- merge streams from two RDMA sources
-	"mediatek,<chip>-disp-postmask" 	- control round corner for display frame
-	"mediatek,<chip>-disp-split" 		- split stream to two encoders
-	"mediatek,<chip>-disp-ufoe"  		- data compression engine
-	"mediatek,<chip>-dsi"        		- DSI controller, see mediatek,dsi.txt
-	"mediatek,<chip>-dpi"        		- DPI controller, see mediatek,dpi.txt
-	"mediatek,<chip>-disp-mutex" 		- display mutex
-	"mediatek,<chip>-disp-od"    		- overdrive
-  the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
-- reg: Physical base address and length of the function block register space
-- interrupts: The interrupt signal from the function block (required, except for
-  merge and split function blocks).
-- clocks: device clocks
-  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-  For most function blocks this is just a single clock input. Only the DSI and
-  DPI controller nodes have multiple clock inputs. These are documented in
-  mediatek,dsi.txt and mediatek,dpi.txt, respectively.
-  An exception is that the mt8183 mutex is always free running with no clocks property.
-
-Required properties (DMA function blocks):
-- compatible: Should be one of
-	"mediatek,<chip>-disp-ovl"
-	"mediatek,<chip>-disp-rdma"
-	"mediatek,<chip>-disp-wdma"
-  the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-- iommus: Should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-
-Optional properties (RDMA function blocks):
-- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
-  property to the corresponding rdma
-  the value is the Max value which defined in hardware data sheet.
-  mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
-  mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
-  mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
-
-Examples:
-
-mmsys: clock-controller at 14000000 {
-	compatible = "mediatek,mt8173-mmsys", "syscon";
-	reg = <0 0x14000000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	#clock-cells = <1>;
-};
-
-ovl0: ovl at 1400c000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400c000 0 0x1000>;
-	interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL0>;
-	iommus = <&iommu M4U_PORT_DISP_OVL0>;
-	mediatek,larb = <&larb0>;
-};
-
-ovl1: ovl at 1400d000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400d000 0 0x1000>;
-	interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL1>;
-	iommus = <&iommu M4U_PORT_DISP_OVL1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma0: rdma at 1400e000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400e000 0 0x1000>;
-	interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-	mediatek,larb = <&larb0>;
-	mediatek,rdma-fifosize = <8192>;
-};
-
-rdma1: rdma at 1400f000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400f000 0 0x1000>;
-	interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma2: rdma at 14010000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x14010000 0 0x1000>;
-	interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA2>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA2>;
-	mediatek,larb = <&larb4>;
-};
-
-wdma0: wdma at 14011000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14011000 0 0x1000>;
-	interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-	mediatek,larb = <&larb0>;
-};
-
-wdma1: wdma at 14012000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14012000 0 0x1000>;
-	interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-color0: color at 14013000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14013000 0 0x1000>;
-	interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR0>;
-};
-
-color1: color at 14014000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14014000 0 0x1000>;
-	interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR1>;
-};
-
-aal at 14015000 {
-	compatible = "mediatek,mt8173-disp-aal";
-	reg = <0 0x14015000 0 0x1000>;
-	interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_AAL>;
-};
-
-gamma at 14016000 {
-	compatible = "mediatek,mt8173-disp-gamma";
-	reg = <0 0x14016000 0 0x1000>;
-	interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_GAMMA>;
-};
-
-ufoe at 1401a000 {
-	compatible = "mediatek,mt8173-disp-ufoe";
-	reg = <0 0x1401a000 0 0x1000>;
-	interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_UFOE>;
-};
-
-dsi0: dsi at 1401b000 {
-	/* See mediatek,dsi.txt for details */
-};
-
-dpi0: dpi at 1401d000 {
-	/* See mediatek,dpi.txt for details */
-};
-
-mutex: mutex at 14020000 {
-	compatible = "mediatek,mt8173-disp-mutex";
-	reg = <0 0x14020000 0 0x1000>;
-	interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_MUTEX_32K>;
-};
-
-od at 14023000 {
-	compatible = "mediatek,mt8173-disp-od";
-	reg = <0 0x14023000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OD>;
-};
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
new file mode 100644
index 000000000000..20419f876410
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display dither processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display dither processor, namely DITHER, works by approximating
+  unavailable colors with available colors and by mixing and matching available
+  colors to mimic unavailable ones.
+  DITHER device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-dither
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: DITHER Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dither0: dither at 14012000 {
+        compatible = "mediatek,mt8183-disp-dither";
+        reg = <0 0x14012000 0 0x1000>;
+        interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_DITHER0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
new file mode 100644
index 000000000000..e2a1fc218e4f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,gamma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display gamma correction
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display gamma correction, namely GAMMA, provides a nonlinear operation
+  used to adjust luminance in??display system.
+  GAMMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-gamma
+      - items:
+          - const: mediatek,mt8183-disp-gamma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: GAMMA Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    gamma at 14016000 {
+        compatible = "mediatek,mt8173-disp-gamma";
+        reg = <0 0x14016000 0 0x1000>;
+        interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
new file mode 100644
index 000000000000..4cdce11d7fcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,merge.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display merge
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display merge engine is used to merge two slice-per-line inputs
+  into one side-by-side output.
+  MERGE device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-merge
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MERGE Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    merge at 14017000 {
+        compatible = "mediatek,mt8173-disp-merge";
+        reg = <0 0x14017000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_MERGE>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
new file mode 100644
index 000000000000..aaba6bbfb4da
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display mutex
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display mutex is used to send the triggers signals called
+  Start Of Frame (SOF)/ Error Of Frame (EOF) to each sub-modules on the
+  display data path.
+  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-mutex
+      - items:
+          - const: mediatek,mt2712-disp-mutex
+      - items:
+          - const: mediatek,mt8167-disp-mutex
+      - items:
+          - const: mediatek,mt8173-disp-mutex
+      - items:
+          - const: mediatek,mt8183-disp-mutex
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MUTEX Clock
+
+  mediatek,gce-events:
+    description:
+      The event id which is mapping to the specific hardware event signal to gce.
+      The event id is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    mutex: mutex at 14020000 {
+        compatible = "mediatek,mt8173-disp-mutex";
+        reg = <0 0x14020000 0 0x1000>;
+        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_MUTEX_32K>;
+        mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+                              <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
new file mode 100644
index 000000000000..bcf3fddd9231
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,od.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overdirve
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overdrive, namely OD, increases the transition values
+  of pixels between consecutive frames to make LCD rotate faster.
+  OD device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2712-disp-od
+      - items:
+          - const: mediatek,mt8173-disp-od
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    od at 14023000 {
+        compatible = "mediatek,mt8173-disp-od";
+        reg = <0 0x14023000 0 0x1000>;
+        clocks = <&mmsys CLK_MM_DISP_OD>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
new file mode 100644
index 000000000000..6255074bf415
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl-2l.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overlay 2 layer
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overlay provides 2 more layer for OVL.
+  OVL-2L device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ovl-2l
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL-2L Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl_2l0: ovl at 14009000 {
+        compatible = "mediatek,mt8183-disp-ovl-2l";
+        reg = <0 0x14009000 0 0x1000>;
+        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
+        iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
new file mode 100644
index 000000000000..833b0ca09b21
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overlay
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overlay, namely OVL, can do alpha blending from the memory.
+  OVL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-ovl
+      - items:
+          - const: mediatek,mt8173-disp-ovl
+      - items:
+          - const: mediatek,mt8183-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-ovl
+              - mediatek,mt2712-disp-ovl
+          - enum:
+              - mediatek,mt2701-disp-ovl
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommu
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl0: ovl at 1400c000 {
+        compatible = "mediatek,mt8173-disp-ovl";
+        reg = <0 0x1400c000 0 0x1000>;
+        interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0>;
+        iommus = <&iommu M4U_PORT_DISP_OVL0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
new file mode 100644
index 000000000000..ce3bcca30609
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display RDMA
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-rdma
+      - items:
+          - const: mediatek,mt8173-disp-rdma
+      - items:
+          - const: mediatek,mt8183-disp-rdma
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-rdma
+              - mediatek,mt2712-disp-rdma
+          - enum:
+              - mediatek,mt2701-disp-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,rdma-fifo-size:
+    description:
+      rdma fifo size may be different even in same SOC, add this property to the
+      corresponding rdma.
+      The value below is the Max value which defined in hardware data sheet
+      mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
+      mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
+      mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8192, 5120, 2048]
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    rdma0: rdma at 1400e000 {
+        compatible = "mediatek,mt8173-disp-rdma";
+        reg = <0 0x1400e000 0 0x1000>;
+        interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_RDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_RDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,rdma-fifosize = <8192>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
new file mode 100644
index 000000000000..d751e0a0c3a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,split.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display split
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display split engine is used to split stream to two encoders.
+  SPLIT device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-split
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: SPLIT Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    split0: split at 14018000 {
+        compatible = "mediatek,mt8173-disp-split";
+        reg = <0 0x14018000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
new file mode 100644
index 000000000000..d0249333a2bd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ufoe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display UFOe
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The Mediatek display UFOe stands for Unified Frame Optimization engine.
+  UFOe can cut the data rate for DSI port which may lead to reduce power consumption.
+  UFOe device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-ufoe
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: UFOe Clock
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ufoe at 1401a000 {
+        compatible = "mediatek,mt8173-disp-ufoe";
+        reg = <0 0x1401a000 0 0x1000>;
+        interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_UFOE>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..d7a3ba497fb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display WDMA
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display WDMA stands for Write Direct Memory Access.
+  It can write the data in display pipeline into DRAM.
+  WDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-wdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: WDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    wdma0: wdma at 14011000 {
+        compatible = "mediatek,mt8173-disp-wdma";
+        reg = <0 0x14011000 0 0x1000>;
+        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+    };
+
-- 
2.18.0

From robin.murphy at arm.com  Thu Aug  5 10:14:52 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 5 Aug 2021 18:14:52 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Remove some unneeded init in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <44c5e07b-e663-5b96-a142-ec25666e2a14@huawei.com>
References: <1624293394-202509-1-git-send-email-john.garry@huawei.com>
 <ee1f3ab5-3acc-f442-f2d2-898cf88bc447@arm.com>
 <45a8af4f-4202-ecd8-0882-507acf9b2eb2@huawei.com>
 <577a625a-4fc5-7402-8e4f-4e0e5be93144@arm.com>
 <44c5e07b-e663-5b96-a142-ec25666e2a14@huawei.com>
Message-ID: <2af4315a-c02a-2185-93a2-b07a891314a6@arm.com>

On 2021-08-05 16:16, John Garry wrote:
> On 05/08/2021 15:41, Robin Murphy wrote:
>>> I suppose they could be combined into a smaller sub-struct and loaded 
>>> in a single operation, but it looks messy, and prob without much gain.
>>
>> Indeed I wouldn't say that saving memory is the primary concern here, 
>> and any more convoluted code is hardly going to help performance. Plus 
>> it still wouldn't help the other cases where we're just copying the 
>> size into a fake queue to do some prod arithmetic - I hadn't fully 
>> clocked what was going on there when I skimmed through things earlier.
>>
>> Disregarding the bogus layout change, though, do you reckon the rest 
>> of my idea makes sense?
> 
> I tried the similar change to avoid zero-init the padding in 
> arm_smmu_cmdq_write_entries() and the 
> _arm_smmu_cmdq_poll_set_valid_map(), but the disassembly was the same. 
> So the compiler must have got smart there.

Yeah, in my build __arm_smmu_cmdq_poll_set_valid_map() only uses 32 
bytes of stack, so clearly it's managed to see through the macro magic 
once queue_inc_prod_n() is inlined and elide the whole struct. 
arm_smmu_cmdq_write_entries() is inlined already, but logically must be 
the same deal since it's a similarly inlined queue_inc_prod_n().

However, that may all change if different compiler flags or a different 
compiler lead to different inlining decisions, so I'd argue that if this 
can matter anywhere then it's worth treating consistently everywhere.

> But for the original change in this patch, it did make a difference. 
> It's nice to remove what was a memcpy:
> 
>  ??? 1770: a9077eff stp xzr, xzr, [x23, #112]
> }, head = llq;
>  ??? 1774: 94000000 bl 0 <memcpy>
> 
> And performance was very fractionally better.

Heh, mine was this beauty:

         struct arm_smmu_ll_queue llq = {
     17d4:       a9017f7f        stp     xzr, xzr, [x27, #16]
     17d8:       a9027f7f        stp     xzr, xzr, [x27, #32]
     17dc:       a9037f7f        stp     xzr, xzr, [x27, #48]
     17e0:       a9047f7f        stp     xzr, xzr, [x27, #64]
         }, head = llq;
     17e4:       b900c340        str     w0, [x26, #192]
{
     17e8:       290d0be1        stp     w1, w2, [sp, #104]
         }, head = llq;
     17ec:       a9440f62        ldp     x2, x3, [x27, #64]
     17f0:       a9007f5f        stp     xzr, xzr, [x26]
     17f4:       a9017f5f        stp     xzr, xzr, [x26, #16]
     17f8:       a9027f5f        stp     xzr, xzr, [x26, #32]
     17fc:       a9037f5f        stp     xzr, xzr, [x26, #48]
     1800:       a9040f42        stp     x2, x3, [x26, #64]
         struct arm_smmu_ll_queue llq = {
     1804:       a9057f7f        stp     xzr, xzr, [x27, #80]
         }, head = llq;
     1808:       a9057f5f        stp     xzr, xzr, [x26, #80]
         struct arm_smmu_ll_queue llq = {
     180c:       a9067f7f        stp     xzr, xzr, [x27, #96]
         }, head = llq;
     1810:       a9067f5f        stp     xzr, xzr, [x26, #96]
         struct arm_smmu_ll_queue llq = {
     1814:       a9077f7f        stp     xzr, xzr, [x27, #112]
         }, head = llq;
     1818:       a9077f5f        stp     xzr, xzr, [x26, #112]
         struct arm_smmu_ll_queue llq = {
     181c:       a9087f5f        stp     xzr, xzr, [x26, #128]

> As for pre-evaluating "nents", I'm not sure how much that can help, but 
> I am not too optimistic. I can try some testing when I get a chance. 
> Having said that, I would need to check the disassembly also.

It'll just turn MOV,LDR,LSL sequences into plain LDRs - a small saving 
but with no real downside, and a third of it is in the place where doing 
less work matters most:

add/remove: 0/0 grow/shrink: 0/8 up/down: 0/-100 (-100)
Function                                     old     new   delta
arm_smmu_priq_thread                         532     528      -4
arm_smmu_evtq_thread                         368     364      -4
arm_smmu_device_probe                       4564    4556      -8
__arm_smmu_cmdq_poll_set_valid_map.isra      316     308      -8
arm_smmu_init_one_queue.isra                 320     308     -12
queue_remove_raw                             192     176     -16
arm_smmu_gerror_handler                      752     736     -16
arm_smmu_cmdq_issue_cmdlist                 1812    1780     -32
Total: Before=23776, After=23676, chg -0.42%


Robin.


From catalin.marinas at arm.com  Thu Aug  5 10:23:15 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 5 Aug 2021 18:23:15 +0100
Subject: [RFC V2 10/10] arm64/mm: Enable CONFIG_ARM64_PA_BITS_52 on
 CONFIG_ARM64_[4K|16K]_PAGES
In-Reply-To: <1627281445-12445-11-git-send-email-anshuman.khandual@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-11-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210805172314.GF6719@arm.com>

On Mon, Jul 26, 2021 at 12:07:25PM +0530, Anshuman Khandual wrote:
> All required FEAT_LPA2 components for 52 bit PA range are already in place.
> Just enable CONFIG_ARM64_PA_BITS_52 on 4K and 16K pages which would select
> CONFIG_ARM64_PA_BITS_52_LPA2 activating 52 bit PA range via FEAT_LPA2.
> 
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 1999ac6..ce139415 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -952,9 +952,9 @@ config ARM64_PA_BITS_48
>  
>  config ARM64_PA_BITS_52
>  	bool "52-bit (ARMv8.2)"
> -	depends on ARM64_64K_PAGES
>  	depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
>  	select ARM64_PA_BITS_52_LPA if ARM64_64K_PAGES
> +	select ARM64_PA_BITS_52_LPA2 if (ARM64_4K_PAGES  || ARM64_16K_PAGES)
>  	help
>  	  Enable support for a 52-bit physical address space, introduced as
>  	  part of the ARMv8.2-LPA extension.

If you do it this way, the text here needs updating and the 8.2
architecture version removed.

-- 
Catalin


From dqfext at gmail.com  Thu Aug  5 10:23:14 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Fri,  6 Aug 2021 01:23:14 +0800
Subject: [PATCH net-next] net: dsa: mt7530: drop untagged frames on VLAN-aware
 ports without PVID
Message-ID: <20210805172315.362165-1-dqfext@gmail.com>

The driver currently still accepts untagged frames on VLAN-aware ports
without PVID. Use PVC.ACC_FRM to drop untagged frames in that case.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 drivers/net/dsa/mt7530.c | 32 ++++++++++++++++++++++++++++++--
 drivers/net/dsa/mt7530.h |  7 +++++++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 385e169080d9..df167f0529bb 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1257,9 +1257,11 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
 		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
 			   MT7530_PORT_FALLBACK_MODE);
 
-	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
+	mt7530_rmw(priv, MT7530_PVC_P(port),
+		   VLAN_ATTR_MASK | PVC_EG_TAG_MASK | ACC_FRM_MASK,
 		   VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
-		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
+		   MT7530_VLAN_ACC_ALL);
 
 	/* Set PVID to 0 */
 	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
@@ -1297,6 +1299,11 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
 			   MT7530_PORT_SECURITY_MODE);
 		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
 			   G0_PORT_VID(priv->ports[port].pvid));
+
+		/* Only accept tagged frames if PVID is not set */
+		if (!priv->ports[port].pvid)
+			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
+				   MT7530_VLAN_ACC_TAGGED);
 	}
 
 	/* Set the port as a user port which is to be able to recognize VID
@@ -1624,11 +1631,26 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
 	if (pvid) {
 		priv->ports[port].pvid = vlan->vid;
 
+		/* Accept all frames if PVID is set */
+		mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
+			   MT7530_VLAN_ACC_ALL);
+
 		/* Only configure PVID if VLAN filtering is enabled */
 		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
 			mt7530_rmw(priv, MT7530_PPBV1_P(port),
 				   G0_PORT_VID_MASK,
 				   G0_PORT_VID(vlan->vid));
+	} else if (priv->ports[port].pvid == vlan->vid) {
+		/* This VLAN is overwritten without PVID, so unset it */
+		priv->ports[port].pvid = G0_PORT_VID_DEF;
+
+		/* Only accept tagged frames if the port is VLAN-aware */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
+			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
+				   MT7530_VLAN_ACC_TAGGED);
+
+		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
+			   G0_PORT_VID_DEF);
 	}
 
 	mutex_unlock(&priv->reg_mutex);
@@ -1654,6 +1676,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
 	 */
 	if (priv->ports[port].pvid == vlan->vid) {
 		priv->ports[port].pvid = G0_PORT_VID_DEF;
+
+		/* Only accept tagged frames if the port is VLAN-aware */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
+			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
+				   MT7530_VLAN_ACC_TAGGED);
+
 		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
 			   G0_PORT_VID_DEF);
 	}
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 4a91d80f51bb..fe4cd2ac26d0 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -238,6 +238,7 @@ enum mt7530_port_mode {
 #define  PVC_EG_TAG_MASK		PVC_EG_TAG(7)
 #define  VLAN_ATTR(x)			(((x) & 0x3) << 6)
 #define  VLAN_ATTR_MASK			VLAN_ATTR(3)
+#define  ACC_FRM_MASK			GENMASK(1, 0)
 
 enum mt7530_vlan_port_eg_tag {
 	MT7530_VLAN_EG_DISABLED = 0,
@@ -249,6 +250,12 @@ enum mt7530_vlan_port_attr {
 	MT7530_VLAN_TRANSPARENT = 3,
 };
 
+enum mt7530_vlan_port_acc_frm {
+	MT7530_VLAN_ACC_ALL = 0,
+	MT7530_VLAN_ACC_TAGGED = 1,
+	MT7530_VLAN_ACC_UNTAGGED = 2,
+};
+
 #define  STAG_VPID			(((x) & 0xffff) << 16)
 
 /* Register for port port-and-protocol based vlan 1 control */
-- 
2.25.1



From jason-jh.lin at mediatek.com  Thu Aug  5 10:13:45 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 01:13:45 +0800
Subject: [PATCH v3 3/4] dt-bindings: mediatek: add mediatek,
 dsc.yaml for mt8195 SoC binding
In-Reply-To: <20210805171346.24249-1-jason-jh.lin@mediatek.com>
References: <20210805171346.24249-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805171346.24249-4-jason-jh.lin@mediatek.com>

1. Add mediatek,dsc.yaml to describe DSC module in details.
2. Add mt8195 SoC binding to mediatek,dsc.yaml.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,dsc.yaml        | 69 +++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
new file mode 100644
index 000000000000..f94a95c6a1c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display DSC controller
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The DSC standard is a specification of the algorithms used for
+  compressing and decompressing image display streams, including
+  the specification of the syntax and semantics of the compressed
+  video bit stream. DSC is designed for real-time systems with
+  real-time compression, transmission, decompression and Display.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-disp-dsc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: DSC Wrapper Clock
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  mediatek,gce-client-reg:
+      description:
+        The register of display function block to be set by gce. There are 4 arguments,
+        such as gce node, subsys id, offset and register size. The subsys id that is
+        mapping to the register of display function blocks is defined in the gce header
+        include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+      $ref: /schemas/types.yaml#/definitions/phandle-array
+      maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dsc0: disp_dsc_wrap at 1c009000 {
+        compatible = "mediatek,mt8195-disp-dsc";
+        reg = <0 0x1c009000 0 0x1000>;
+        interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+        clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+    };
+
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 10:13:43 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 01:13:43 +0800
Subject: [PATCH v3 1/4] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC
 binding
In-Reply-To: <20210805171346.24249-1-jason-jh.lin@mediatek.com>
References: <20210805171346.24249-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805171346.24249-2-jason-jh.lin@mediatek.com>

1. There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195.
   Each of them is bound to a display pipeline, so add their
   definition in mtk-mmsys documentation with 2 compatibles.

2. Add description for power-domain property.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
this patch is base on [1][2]

[1] dt-bindings: arm: mediatek: mmsys: convert to YAML format
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-1-fparent at baylibre.com/
[2] dt-bindings: arm: mediatek: mmsys: add MT8365 SoC binding
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-2-fparent at baylibre.com/
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml  | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 2d4ff0ce387b..68cb330d7595 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -30,6 +30,8 @@ properties:
               - mediatek,mt8173-mmsys
               - mediatek,mt8183-mmsys
               - mediatek,mt8365-mmsys
+              - mediatek,mt8195-vdosys0
+              - mediatek,mt8195-vdosys1
           - const: syscon
       - items:
           - const: mediatek,mt7623-mmsys
@@ -39,6 +41,12 @@ properties:
   reg:
     maxItems: 1
 
+  power-domains:
+    description:
+      A phandle and PM domain specifier as defined by bindings
+      of the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
   "#clock-cells":
     const: 1
 
-- 
2.18.0

From catalin.marinas at arm.com  Thu Aug  5 10:25:50 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 5 Aug 2021 18:25:50 +0100
Subject: [RFC V2 05/10] arm64/mm: Add CONFIG_ARM64_PA_BITS_52_[LPA|LPA2]
In-Reply-To: <1627281445-12445-6-git-send-email-anshuman.khandual@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-6-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210805172550.GG6719@arm.com>

On Mon, Jul 26, 2021 at 12:07:20PM +0530, Anshuman Khandual wrote:
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b5b13a9..1999ac6 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -934,6 +934,12 @@ config ARM64_VA_BITS
>  	default 48 if ARM64_VA_BITS_48
>  	default 52 if ARM64_VA_BITS_52
>  
> +config ARM64_PA_BITS_52_LPA
> +	bool
> +
> +config ARM64_PA_BITS_52_LPA2
> +	bool
> +
>  choice
>  	prompt "Physical address space size"
>  	default ARM64_PA_BITS_48
> @@ -948,6 +954,7 @@ config ARM64_PA_BITS_52
>  	bool "52-bit (ARMv8.2)"
>  	depends on ARM64_64K_PAGES
>  	depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
> +	select ARM64_PA_BITS_52_LPA if ARM64_64K_PAGES
>  	help
>  	  Enable support for a 52-bit physical address space, introduced as
>  	  part of the ARMv8.2-LPA extension.

Do we actually need to bother with LPA, LPA2 options? We could just add
an extra defined(ARM64_64K_PAGES) in places, it may be easier to follow
in a few years time when we won't remember what LPA or LPA2 was. I
haven't got to the rest of the patches but it may just be simpler to
define the shifts separately for 52-bit based on 4K/16K/64K and ignore
the LPA/LPA2 distinction altogether (we'll still keep it for CPUID
checking though).

-- 
Catalin


From mathieu.poirier at linaro.org  Thu Aug  5 10:35:06 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 5 Aug 2021 11:35:06 -0600
Subject: [PATCH v2 1/5] remoteproc: Add support for detach-only during
 shutdown
In-Reply-To: <7e264184-60ea-a035-7bd3-1fc2c76a160d@ti.com>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-2-s-anna@ti.com>
 <20210802184431.GC3051951@p14s>
 <cd399fef-6db7-72eb-933f-7454a043ed14@ti.com>
 <20210803162311.GB3091608@p14s>
 <7e264184-60ea-a035-7bd3-1fc2c76a160d@ti.com>
Message-ID: <20210805173506.GF3205691@p14s>

On Wed, Aug 04, 2021 at 02:17:22PM -0500, Suman Anna wrote:
> Hi Mathieu,
> 
> On 8/3/21 11:23 AM, Mathieu Poirier wrote:
> > Good morning,
> > 
> > On Mon, Aug 02, 2021 at 06:21:38PM -0500, Suman Anna wrote:
> >> Hi Mathieu,
> >>
> >> On 8/2/21 1:44 PM, Mathieu Poirier wrote:
> >>> On Fri, Jul 23, 2021 at 05:02:44PM -0500, Suman Anna wrote:
> >>>> The remoteproc core has support for both stopping and detaching a
> >>>> remote processor that was attached to previously, through both the
> >>>> remoteproc sysfs and cdev interfaces. The rproc_shutdown() though
> >>>> unconditionally only uses the stop functionality at present. This
> >>>> may not be the default desired functionality for all the remoteproc
> >>>> platform drivers.
> >>>>
> >>>> Enhance the remoteproc core logic to key off the presence of the
> >>>> .stop() ops and allow the individual remoteproc drivers to continue
> >>>> to use the standard rproc_add() and rproc_del() API. This allows
> >>>> the remoteproc drivers to only do detach if supported when the driver
> >>>> is uninstalled, and the remote processor continues to run undisturbed
> >>>> even after the driver removal.
> >>>>
> >>>> Signed-off-by: Suman Anna <s-anna at ti.com>
> >>>> ---
> >>>> v2: Addressed various review comments from v1
> >>>>  - Reworked the logic to not use remoteproc detach_on_shutdown and
> >>>>    rely only on rproc callback ops
> >>>>  - Updated the last para of the patch description
> >>>> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-3-s-anna at ti.com/
> >>>>
> >>>>  drivers/remoteproc/remoteproc_cdev.c  | 7 +++++++
> >>>>  drivers/remoteproc/remoteproc_core.c  | 5 ++++-
> >>>>  drivers/remoteproc/remoteproc_sysfs.c | 6 ++++++
> >>>>  3 files changed, 17 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c
> >>>> index 4ad98b0b8caa..16c932beed88 100644
> >>>> --- a/drivers/remoteproc/remoteproc_cdev.c
> >>>> +++ b/drivers/remoteproc/remoteproc_cdev.c
> >>>> @@ -42,6 +42,13 @@ static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_
> >>>>  		    rproc->state != RPROC_ATTACHED)
> >>>>  			return -EINVAL;
> >>>>  
> >>>> +		if (rproc->state == RPROC_ATTACHED &&
> >>>
> >>> This is already checked just above.
> >>>
> >>>> +		    !rproc->ops->stop) {
> >>
> >> Well, this is checking for both conditions, and not just the stop ops
> >> independently. We expect to have .stop() defined normally for both regular
> >> remoteproc mode and attached mode where you want to stop (and not detach), but
> >> as you can see, I am supporting only detach and so will not have .stop() defined
> >>  with RPROC_ATTACHED.
> >>
> >>>
> >>> This is checked in rproc_stop() where -EINVAL is returned if ops::stop has not
> >>> been provided.
> >>
> >> rproc_shutdown() actually doesn't return any status, so all its internal
> >> checking gets ignored and a success is returned today.
> >>
> > 
> > That is correct, and I have suggested to add a return value in my previous
> > review.
> 
> Yeah ok. I can add a separate patch fixing that, and couple of these checks then
> become redundant.
> 
> > 
> >>>
> >>>> +			dev_err(&rproc->dev,
> >>>> +				"stop not supported for this rproc, use detach\n");
> >>>
> >>> The standard error message from the shell should be enough here, the same way it
> >>> is enough when the "start" and "stop" scenarios fail.
> >>
> >> Thought this was a bit more informative, but sure this trace can be dropped.
> >>
> >>>
> >>>> +			return -EINVAL;
> >>>> +		}
> >>>> +
> >>>>  		rproc_shutdown(rproc);
> >>>>  	} else if (!strncmp(cmd, "detach", len)) {
> >>>>  		if (rproc->state != RPROC_ATTACHED)
> >>>> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> >>>> index 7de5905d276a..ab9e52180b04 100644
> >>>> --- a/drivers/remoteproc/remoteproc_core.c
> >>>> +++ b/drivers/remoteproc/remoteproc_core.c
> >>>> @@ -2075,7 +2075,10 @@ void rproc_shutdown(struct rproc *rproc)
> >>>>  	if (!atomic_dec_and_test(&rproc->power))
> >>>>  		goto out;
> >>>>  
> >>>> -	ret = rproc_stop(rproc, false);
> >>>> +	if (rproc->state == RPROC_ATTACHED && !rproc->ops->stop)
> >>>> +		ret = __rproc_detach(rproc);
> >>>> +	else
> >>>> +		ret = rproc_stop(rproc, false);
> >>>
> >>> As I indicated in my last review I think rproc_shutdown() and rproc_del() should
> >>> be decoupled and the right call made in the platform drivers based on the state
> >>> of the remote processor.  
> >>
> >> We have various remoteproc API provided in pairs - rproc_alloc()/rproc_free(),
> >> rproc_add()/rproc_del(), rproc_boot()/rproc_shutdown() and
> >> rproc_attach()/rproc_detach(). The drivers are configuring conditions for
> >> auto-boot and RPROC_DETACHED. The reason they are coupled is primarily because
> >> of the auto-boot done during rproc_add(). And we handle the RPROC_DETACHED case
> >> just as well in rproc_boot().
> >>
> > 
> > The difference with rproc_boot() is that we are checking only the state of the
> > remoteproc, everything else related to the remote processor operations is
> > seamlessly handles by the state machine.  It is also tied to the
> > rproc_trigger_auto_boot() mechanic - decoupling that would be messy without
> > bringing any advantages other than keeping with a semantic symmetry.
> 
> Most of this is actually tied to auto_boot if you think about it, not just the
> rproc state. If we have auto_boot set to false, then rproc_add() would not do
> anything, and the decision to start or attach can either be done through the
> sysfs/cdev or a kernel remoteproc or some consumer driver. And the state machine
> is getting influenced by this flag. auto-boot is a very useful feature.
> 
> You are asking is to do things differently between the regular start/stop case
> and attach/detach case ignoring the auto-boot. The semantic symmetry actually
> makes it easier to follow the state machine given that there are some internal
> reference counts as well.

I am definitely not asking to ignore the auto-boot flag.  All I said is that I
did not split the semantic in rproc_boot() because of the auto-boot flag and the
mechanic to handle it.

> 
> Note that we also have the devres API, and rproc_alloc()/rproc_free() and
> rproc_add()/rproc_del() form the main remoteproc subsystem API. The drivers
> would end up using matching calls if we don't have auto_boot.
> 
> > 
> >> While what you have suggested works, but I am not quite convinced on this
> >> asymmetric usage, and why this state-machine logic should be split between the
> >> core and remoteproc drivers differently between attach and detach. To me,
> >> calling rproc_detach() in remoteproc drivers would have made sense only if they
> >> are also calling rproc_attach().
> > 
> > As pointed out above I see rproc_boot() as a special case but if that really
> > concerns you I'm open to consider patches that will take rproc_attach() out of
> > rproc_boot(). 
> > 
> 
> We are talking about a bigger behavioral change to remoteproc core here. So I
> would definitely want to hear from others as well on this before we spend any
> time reworking code.
> 
> Meanwhile, how do I take this series forward? One option I can probably do is
> turn off auto-boot for early-boot case in my drivers and do the matching
> attach/detach.
>

I don't think there is a need to turn off auto-boot for early boot, rproc_boot()
will to the right thing.

As for the way forward, the easiest way I see is to call either rproc_shutdown()
or rproc_detach() based on rproc->state in rproc_del().  That will work with
devm_rproc_remove() and it is still possible for platorm drivers to explicitly
call rproc_shutdown() before rproc_del() to force a remote processor that was
attached to be switched off when the driver is removed.

That is all the time I had for remoteproc - I am officially away for the next two weeks.  

Thanks,
Mathieu

> regards
> Suman
> 
> >>
> >>
> >> Conditions such as the above make the core code
> >>> brittle, difficult to understand and tedious to maintain.
> >>
> >> The logic I have added actually makes rproc_shutdown behavior to be on par with
> >> the rproc_boot().
> >>
> >> regards
> >> Suman
> >>
> >>>
> >>> Thanks,
> >>> Mathieu
> >>>
> >>>>  	if (ret) {
> >>>>  		atomic_inc(&rproc->power);
> >>>>  		goto out;
> >>>> diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
> >>>> index ea8b89f97d7b..133e766f38d4 100644
> >>>> --- a/drivers/remoteproc/remoteproc_sysfs.c
> >>>> +++ b/drivers/remoteproc/remoteproc_sysfs.c
> >>>> @@ -206,6 +206,12 @@ static ssize_t state_store(struct device *dev,
> >>>>  		    rproc->state != RPROC_ATTACHED)
> >>>>  			return -EINVAL;
> >>>>  
> >>>> +		if (rproc->state == RPROC_ATTACHED &&
> >>>> +		    !rproc->ops->stop) {
> >>>> +			dev_err(&rproc->dev, "stop not supported for this rproc, use detach\n");
> >>>> +			return -EINVAL;
> >>>> +		}
> >>>> +
> >>>>  		rproc_shutdown(rproc);
> >>>>  	} else if (sysfs_streq(buf, "detach")) {
> >>>>  		if (rproc->state != RPROC_ATTACHED)
> >>>> -- 
> >>>> 2.32.0
> >>>>
> >>
> 


From piyush.mehta at xilinx.com  Thu Aug  5 10:42:16 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Thu, 5 Aug 2021 23:12:16 +0530
Subject: [PATCH V2 0/3] gpio: modepin: Add driver support for modepin GPIO
 controller
Message-ID: <20210805174219.3000667-1-piyush.mehta@xilinx.com>

This patch adds support for the zynqmp modepin GPIO controller and
documented for the same. GPIO modepin driver set and get the value and
status of the PS_MODE pin, based on device-tree pin configuration.
These four-bits boot-mode pins are dedicated configurable as input/output.
After the stabilization of the system,these mode pins are sampled.

To access GPIO pins, added Xilinx ZynqMP firmware MDIO API support to
set and get PS_MODE pins value and status. These APIs are interface
APIs, between the mode pin controller driver and low-level API.

---
Changes in v2:
- Added Xilinx ZynqMP firmware MMIO API support to set and get pin
  value and status.
- DT Documentation- Addressed review comments: Update commit message
- Modepin driver- Addressed review comments:
  - Update APIs
  - Removed unwanted variables
  - Handle return path for probe function

Review Comments:
https://lore.kernel.org/linux-arm-kernel/20210624205055.GA1961487 at robh.at.kernel.org/T/#u
---

Piyush Mehta (3):
  firmware: zynqmp: Add MMIO read and write support for PS_MODE pin
  dt-bindings: gpio: zynqmp: Add binding documentation for modepin
  gpio: modepin: Add driver support for modepin GPIO controller

 .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    |  41 ++++++
 drivers/firmware/xilinx/zynqmp.c                   |  46 ++++++
 drivers/gpio/Kconfig                               |  12 ++
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-zynqmp-modepin.c                 | 158 +++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h               |  14 ++
 6 files changed, 272 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
 create mode 100644 drivers/gpio/gpio-zynqmp-modepin.c

-- 
2.7.4



From piyush.mehta at xilinx.com  Thu Aug  5 10:42:17 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Thu, 5 Aug 2021 23:12:17 +0530
Subject: [PATCH V2 1/3] firmware: zynqmp: Add MMIO read and write support for
 PS_MODE pin
In-Reply-To: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
Message-ID: <20210805174219.3000667-2-piyush.mehta@xilinx.com>

Add Xilinx ZynqMP firmware MMIO APIs support to set and get PS_MODE
pins value and status. These APIs create an interface path between
mode pin controller driver and low-level API to access GPIO pins.

Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
---
Changes in v2:
- Added Xilinx ZynqMP firmware MMIO API support to set and get pin
  value and status.
---
 drivers/firmware/xilinx/zynqmp.c     | 46 ++++++++++++++++++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h | 14 +++++++++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 15b13832..0234423 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -28,6 +28,13 @@
 /* Max HashMap Order for PM API feature check (1<<7 = 128) */
 #define PM_API_FEATURE_CHECK_MAX_ORDER  7
 
+/* CRL registers and bitfields */
+#define CRL_APB_BASE			0xFF5E0000U
+/* BOOT_PIN_CTRL- Used to control the mode pins after boot */
+#define CRL_APB_BOOT_PIN_CTRL		(CRL_APB_BASE + (0x250U))
+/* BOOT_PIN_CTRL_MASK- out_val[11:8], out_en[3:0] */
+#define CRL_APB_BOOTPIN_CTRL_MASK	0xF0FU
+
 static bool feature_check_enabled;
 static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER);
 
@@ -926,6 +933,45 @@ int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
 EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_config);
 
 /**
+ * zynqmp_pm_bootmode_read() - PM Config API for read bootpin status
+ * @ps_mode: Returned output value of ps_mode
+ *
+ * This API function is to be used for notify the power management controller
+ * to read bootpin status.
+ *
+ * Return: status, either success or error+reason
+ */
+unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode)
+{
+	unsigned int ret;
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+
+	ret = zynqmp_pm_invoke_fn(PM_MMIO_READ, CRL_APB_BOOT_PIN_CTRL, 0,
+				  0, 0, ret_payload);
+
+	*ps_mode = ret_payload[1];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_read);
+
+/**
+ * zynqmp_pm_bootmode_write() - PM Config API for Configure bootpin
+ * @ps_mode: Value to be written to the bootpin ctrl register
+ *
+ * This API function is to be used for notify the power management controller
+ * to configure bootpin.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+int zynqmp_pm_bootmode_write(u32 ps_mode)
+{
+	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, CRL_APB_BOOT_PIN_CTRL,
+				   CRL_APB_BOOTPIN_CTRL_MASK, ps_mode, 0, NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write);
+
+/**
  * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
  *			       master has initialized its own power management
  *
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 9d1a5c1..dc6f39f 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -68,6 +68,8 @@ enum pm_api_id {
 	PM_SET_REQUIREMENT = 15,
 	PM_RESET_ASSERT = 17,
 	PM_RESET_GET_STATUS = 18,
+	PM_MMIO_WRITE = 19,
+	PM_MMIO_READ = 20,
 	PM_PM_INIT_FINALIZE = 21,
 	PM_FPGA_LOAD = 22,
 	PM_FPGA_GET_STATUS = 23,
@@ -386,6 +388,8 @@ int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type);
 int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
 			   const enum zynqmp_pm_reset_action assert_flag);
 int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status);
+unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode);
+int zynqmp_pm_bootmode_write(u32 ps_mode);
 int zynqmp_pm_init_finalize(void);
 int zynqmp_pm_set_suspend_mode(u32 mode);
 int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
@@ -515,6 +519,16 @@ static inline int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset,
 	return -ENODEV;
 }
 
+static inline unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode)
+{
+	return -ENODEV;
+}
+
+static inline int zynqmp_pm_bootmode_write(u32 ps_mode)
+{
+	return -ENODEV;
+}
+
 static inline int zynqmp_pm_init_finalize(void)
 {
 	return -ENODEV;
-- 
2.7.4



From piyush.mehta at xilinx.com  Thu Aug  5 10:42:18 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Thu, 5 Aug 2021 23:12:18 +0530
Subject: [PATCH V2 2/3] dt-bindings: gpio: zynqmp: Add binding documentation
 for modepin
In-Reply-To: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
Message-ID: <20210805174219.3000667-3-piyush.mehta@xilinx.com>

This patch adds DT binding document for zynqmp modepin GPIO controller.
Modepin GPIO controller has four GPIO pins which can be configurable
as input or output.

Modepin driver is a bridge between the peripheral driver and GPIO pins.
It has set and get APIs for accessing GPIO pins, based on the device-tree
entry of reset-gpio property in the peripheral driver, every pin can be
configured as input/output and trigger GPIO pin.

For more information please refer zynqMp TRM link:
Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
Chapter 2: Signals, Interfaces, and Pins
Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE

Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
---
Changes in v2:
- Addressed review comments: Update commit message

https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736
---
 .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml

diff --git a/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
new file mode 100644
index 0000000..39d78f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: ZynqMP Mode Pin GPIO controller
+
+description:
+  PS_MODE is 4-bits boot mode pins sampled on POR deassertion. Mode Pin
+  GPIO controller with configurable from numbers of pins (from 0 to 3 per
+  PS_MODE). Every pin can be configured as input/output.
+
+maintainers:
+  - Piyush Mehta <piyush.mehta at xilinx.com>
+
+properties:
+  compatible:
+    const: xlnx,zynqmp-gpio-modepin
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    modepin_gpio: gpio {
+        compatible = "xlnx,zynqmp-gpio-modepin";
+        gpio-controller;
+        #gpio-cells = <2>;
+    };
+
+...
-- 
2.7.4



From piyush.mehta at xilinx.com  Thu Aug  5 10:42:19 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Thu, 5 Aug 2021 23:12:19 +0530
Subject: [PATCH V2 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
Message-ID: <20210805174219.3000667-4-piyush.mehta@xilinx.com>

This patch adds driver support for the zynqmp modepin GPIO controller.
GPIO modepin driver set and get the value and status of the PS_MODE pin,
based on device-tree pin configuration. These four mode pins are
configurable as input/output. The mode pin has a control register, which
have lower four-bits [0:3] are configurable as input/output, next four-bits
can be used for reading the data  as input[4:7], and next setting the
output pin state output[8:11].

Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
---
Changes in v2:
- Modepin driver- Addressed review comments:
  - Update APIs
  - Removed unwanted variables
  - Handle return path for probe function

https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#m276c8a5c52f8dc1ed1cd91a2d660f78d498e4ae5
---
 drivers/gpio/Kconfig               |  12 +++
 drivers/gpio/Makefile              |   1 +
 drivers/gpio/gpio-zynqmp-modepin.c | 158 +++++++++++++++++++++++++++++++++++++
 3 files changed, 171 insertions(+)
 create mode 100644 drivers/gpio/gpio-zynqmp-modepin.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index fab5710..90a3a3d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -755,6 +755,18 @@ config GPIO_ZYNQ
 	help
 	  Say yes here to support Xilinx Zynq GPIO controller.
 
+config GPIO_ZYNQMP_MODEPIN
+	tristate "ZynqMP ps-mode pin gpio configuration driver"
+	depends on ZYNQMP_FIRMWARE
+	default ZYNQMP_FIRMWARE
+	help
+	  Say yes here to support the ZynqMP ps-mode pin gpio configuration
+	  driver.
+
+	  This ps-mode pin gpio driver is based on GPIO framework, PS_MODE
+	  is 4-bits boot mode pins. It sets and gets the status of
+	  the ps-mode pin. Every pin can be configured as input/output.
+
 config GPIO_LOONGSON1
 	tristate "Loongson1 GPIO support"
 	depends on MACH_LOONGSON32
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 32a3265..978dc4595 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -183,3 +183,4 @@ obj-$(CONFIG_GPIO_XRA1403)		+= gpio-xra1403.o
 obj-$(CONFIG_GPIO_XTENSA)		+= gpio-xtensa.o
 obj-$(CONFIG_GPIO_ZEVIO)		+= gpio-zevio.o
 obj-$(CONFIG_GPIO_ZYNQ)			+= gpio-zynq.o
+obj-$(CONFIG_GPIO_ZYNQMP_MODEPIN)	+= gpio-zynqmp-modepin.o
diff --git a/drivers/gpio/gpio-zynqmp-modepin.c b/drivers/gpio/gpio-zynqmp-modepin.c
new file mode 100644
index 0000000..99c69df
--- /dev/null
+++ b/drivers/gpio/gpio-zynqmp-modepin.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the ps-mode pin configuration.
+ *
+ * Copyright (c) 2021 Xilinx, Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/firmware/xlnx-zynqmp.h>
+
+/* 4-bit boot mode pins */
+#define MODE_PINS			4
+
+/**
+ * modepin_gpio_get_value - Get the state of the specified pin of GPIO device
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ *
+ * This function reads the state of the specified pin of the GPIO device.
+ *
+ * Return: 0 if the pin is low, 1 if pin is high, -EINVAL wrong pin configured
+ *         or error value.
+ */
+static int modepin_gpio_get_value(struct gpio_chip *chip, unsigned int pin)
+{
+	u32 regval = 0;
+	int ret;
+
+	ret = zynqmp_pm_bootmode_read(&regval);
+	if (ret) {
+		pr_err("modepin: get value err %d\n", ret);
+		return ret;
+	}
+
+	return !!(regval & BIT(pin + 8));
+}
+
+/**
+ * modepin_gpio_set_value - Modify the state of the pin with specified value
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ * @state:	value used to modify the state of the specified pin
+ *
+ * This function reads the state of the specified pin of the GPIO device, mask
+ * with the capture state of GPIO pin, and update pin of GPIO device.
+ *
+ * Return:	None.
+ */
+static void modepin_gpio_set_value(struct gpio_chip *chip, unsigned int pin,
+				   int state)
+{
+	u32 bootpin_val = 0;
+	int ret;
+
+	ret = zynqmp_pm_bootmode_read(&bootpin_val);
+	if (ret)
+		pr_err("modepin: get value err %d\n", ret);
+
+	if (state)
+		bootpin_val |= BIT(pin + 8);
+	else
+		bootpin_val &= ~BIT(pin + 8);
+
+	/* Configure bootpin value */
+	ret = zynqmp_pm_bootmode_write(bootpin_val);
+	if (ret)
+		pr_err("modepin: %s failed\n", __func__);
+}
+
+/**
+ * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ *
+ * Return: 0 always
+ */
+static int modepin_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
+{
+	return 0;
+}
+
+/**
+ * modepin_gpio_dir_out - Set the direction of the specified GPIO pin as output
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ * @state:	value to be written to specified pin
+ *
+ * Return: 0 always
+ */
+static int modepin_gpio_dir_out(struct gpio_chip *chip, unsigned int pin,
+				int state)
+{
+	return 0;
+}
+
+/**
+ * modepin_gpio_probe - Initialization method for modepin_gpio
+ * @pdev:		platform device instance
+ *
+ * Return: 0 on success, negative error otherwise.
+ */
+static int modepin_gpio_probe(struct platform_device *pdev)
+{
+	struct gpio_chip *chip;
+	int status;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, chip);
+
+	/* configure the gpio chip */
+	chip->base = -1;
+	chip->ngpio = MODE_PINS;
+	chip->owner = THIS_MODULE;
+	chip->parent = &pdev->dev;
+	chip->get = modepin_gpio_get_value;
+	chip->set = modepin_gpio_set_value;
+	chip->direction_input = modepin_gpio_dir_in;
+	chip->direction_output = modepin_gpio_dir_out;
+	chip->label = dev_name(&pdev->dev);
+
+	/* modepin gpio registration */
+	status = devm_gpiochip_add_data(&pdev->dev, chip, chip);
+	if (status)
+		return dev_err_probe(&pdev->dev, status,
+			      "Failed to add GPIO chip\n");
+
+	return status;
+}
+
+static const struct of_device_id modepin_platform_id[] = {
+	{ .compatible = "xlnx,zynqmp-gpio-modepin", },
+	{ }
+};
+
+static struct platform_driver modepin_platform_driver = {
+	.driver = {
+		.name = "modepin-gpio",
+		.of_match_table = modepin_platform_id,
+	},
+	.probe = modepin_gpio_probe,
+};
+
+module_platform_driver(modepin_platform_driver);
+
+MODULE_AUTHOR("Piyush Mehta <piyush.mehta at xilinx.com>");
+MODULE_DESCRIPTION("ZynqMP Boot PS_MODE Configuration");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



From linux.amoon at gmail.com  Thu Aug  5 11:18:20 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Thu, 5 Aug 2021 23:48:20 +0530
Subject: [PATCHv2 1/4] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <CAFBinCAP_DDvPLn4h1yQKEdU_x1ovokHUTPeq3vNV_sDF8PcWg@mail.gmail.com>
References: <20210716103651.1455-1-linux.amoon@gmail.com>
 <20210716103651.1455-2-linux.amoon@gmail.com>
 <CAFBinCDeqauw_V-Vn9cat9HaCXj6HEMz6G+G+VbqCNtGEFGYzg@mail.gmail.com>
 <CANAwSgQ5PDGUWMH-jxnz5wwutUVniTn7RAe=4J=8-jbmqxYRRg@mail.gmail.com>
 <CAFBinCBhg+dije+3DvV_V_kqHv9q+r4EPxXCYFti6KuA4mK7KQ@mail.gmail.com>
 <CANAwSgT9-5zGr67aGzBmW6WDBfeiAvjv_zv2UbRC+YbgAGg==A@mail.gmail.com>
 <CAFBinCCGA0b=LVjbQood+iN+DHLodY0RJ-GrSOcgdzrDFJ25pQ@mail.gmail.com>
 <CAFBinCAohjxcsY3D1rdAiYVGL+==cnjzZxg1GmYxSNVhxSTDoA@mail.gmail.com>
 <CAFBinCAP_DDvPLn4h1yQKEdU_x1ovokHUTPeq3vNV_sDF8PcWg@mail.gmail.com>
Message-ID: <CANAwSgS2vi7hZqX0LWxNTvk-3aN=n1fEErj4Zt0_4CCpZGyRkg@mail.gmail.com>

Hi Martin,

On Thu, 5 Aug 2021 at 03:28, Martin Blumenstingl
<martin.blumenstingl at googlemail.com> wrote:
>
> On Sun, Jul 18, 2021 at 9:09 PM Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
> >
> > Hi Anand,
> >
> > On Sun, Jul 18, 2021 at 4:01 PM Martin Blumenstingl
> > <martin.blumenstingl at googlemail.com> wrote:
> > [...]
> > > > From the schematics [1]
> > > > https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20160226.pdf
> > > >
> > > > You could find references to PWREN  <--- GPIOAO.BIT5
> > > > The second reference is USB HOST Power Switch
> > > > The third reference is USB HOST POWER.
> > > >
> > > > Hope I am clean in my thought process now.
> > > Can you please point out the page numbers for me?
> > >
> > > What I am seeing on page 1 is:
> > > GPIOAO_5 (called GPIOAO.BIT5) is connected as an INPUT to the USB_OTG
> > > PWREN signal (that's the green box with the label "USB_OTG.SchDoc"
> > > above it).
> > I unfortunately missed your question on IRC on this topic:
> > <armoon> xdarklight: just want to understand the confusion on PWREN,
> > either is INPUT / OTPUT to usb hub am I correct
> > My understanding of the INPUT/OUTPUT direction in the Odroid-C1
> > schematics (which you linked) above is that the arrow direction shows
> > whether it's an input or output.
> > For example (all on page one):
> > - HDMI_HPD is an input to the Meson8b SoC, arrow direction is: HDMI => S805
> > - IR_IN is an input to the Meson8b SoC, arrow direction is: S805 <=
> > GPIOAO.BIT7 IR_IN
> > - PWM is an output, arrow direction is: S805 => PWM.C VCCK_PWM
> > - 3.3V/1.8V switch for the SD card is an output, arrow direction is:
> > S805 => GPIOAO.BIT3 TF_3V3N_1V8_EN
> >
> > That tells me: the arrow direction shows which connections are inputs
> > or outputs.
> > Some pins can be input and output at the same time (HDMI_CEC). But
> > let's keep it simple for now any only look at inputs/output.
> >
> > Based on this information I am looking at the arrow direction for
> > USB_OTG: GPIOAO.BIT5 PWREN <= S805
> > So this confirms that GPIOAO_5 is an output to the SoC.
> > Please note though that this part is not linked with any USB host
> > connector, it's only linked to the USB OTG path.
> >
> > For the next part the S805 SoC is not involved:
> > USB1 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> > USB2 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> > This tells me that the PWREN signal for the two USB_HOST_PWR_SW (USB
> > host power switches / current limiters) is driven by the GL852G USB
> > hub.
> Hardkernel team responded on the Odroid forums to the request from Anand:
> "Power-Enable signal to the USB load switch ICs is connected to the
> USB hub controller.
> It is not connected the CPU GPIO."
>
> The regulator from Anand's patch is therefore connected to the micro USB port.
> This means that the patch needs updating in case Anand wants to have
> it included.
>

Yes, I will send a corrected version of the patches soon.

>
> Best regards,
> Martin
>
>
> [0] https://forum.odroid.com/viewtopic.php?p=332217#p332217

Thanks
-Anand


From laurentiu.tudor at nxp.com  Thu Aug  5 11:37:18 2021
From: laurentiu.tudor at nxp.com (Laurentiu Tudor)
Date: Thu, 5 Aug 2021 21:37:18 +0300
Subject: [PATCH v7 2/9] ACPI/IORT: Add support for RMR node parsing
In-Reply-To: <20210805160319.GB23085@lpieralisi>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <20210805080724.480-3-shameerali.kolothum.thodi@huawei.com>
 <20210805160319.GB23085@lpieralisi>
Message-ID: <610d523d-6bc0-bead-4bc0-00a4d95658a9@nxp.com>



On 8/5/2021 7:03 PM, Lorenzo Pieralisi wrote:
> On Thu, Aug 05, 2021 at 09:07:17AM +0100, Shameer Kolothum wrote:
> 
> [...]
> 
>> +static void __init iort_node_get_rmr_info(struct acpi_iort_node *iort_node)
>> +{
>> +	struct acpi_iort_node *smmu;
>> +	struct acpi_iort_rmr *rmr;
>> +	struct acpi_iort_rmr_desc *rmr_desc;
>> +	u32 map_count = iort_node->mapping_count;
>> +	u32 sid;
>> +	int i;
>> +
>> +	if (!iort_node->mapping_offset || map_count != 1) {
>> +		pr_err(FW_BUG "Invalid ID mapping, skipping RMR node %p\n",
>> +		       iort_node);
>> +		return;
>> +	}
>> +
>> +	/* Retrieve associated smmu and stream id */
>> +	smmu = iort_node_get_id(iort_node, &sid, 0);
>> +	if (!smmu) {
>> +		pr_err(FW_BUG "Invalid SMMU reference, skipping RMR node %p\n",
>> +		       iort_node);
>> +		return;
>> +	}
>> +
>> +	/* Retrieve RMR data */
>> +	rmr = (struct acpi_iort_rmr *)iort_node->node_data;
>> +	if (!rmr->rmr_offset || !rmr->rmr_count) {
>> +		pr_err(FW_BUG "Invalid RMR descriptor array, skipping RMR node %p\n",
>> +		       iort_node);
>> +		return;
>> +	}
>> +
>> +	rmr_desc = ACPI_ADD_PTR(struct acpi_iort_rmr_desc, iort_node,
>> +				rmr->rmr_offset);
>> +
>> +	iort_rmr_desc_check_overlap(rmr_desc, rmr->rmr_count);
>> +
>> +	for (i = 0; i < rmr->rmr_count; i++, rmr_desc++) {
>> +		struct iommu_resv_region *region;
>> +		enum iommu_resv_type type;
>> +		int prot = IOMMU_READ | IOMMU_WRITE;
>> +		u64 addr = rmr_desc->base_address, size = rmr_desc->length;
>> +
>> +		if (!IS_ALIGNED(addr, SZ_64K) || !IS_ALIGNED(size, SZ_64K)) {
>> +			/* PAGE align base addr and size */
>> +			addr &= PAGE_MASK;
>> +			size = PAGE_ALIGN(size + offset_in_page(rmr_desc->base_address));
>> +
>> +			pr_err(FW_BUG "RMR descriptor[0x%llx - 0x%llx] not aligned to 64K, continue with [0x%llx - 0x%llx]\n",
>> +			       rmr_desc->base_address,
>> +			       rmr_desc->base_address + rmr_desc->length - 1,
>> +			       addr, addr + size - 1);
>> +		}
>> +		if (rmr->flags & IOMMU_RMR_REMAP_PERMITTED) {
>> +			type = IOMMU_RESV_DIRECT_RELAXABLE;
>> +			/*
>> +			 * Set IOMMU_CACHE as IOMMU_RESV_DIRECT_RELAXABLE is
>> +			 * normally used for allocated system memory that is
>> +			 * then used for device specific reserved regions.
>> +			 */
>> +			prot |= IOMMU_CACHE;
>> +		} else {
>> +			type = IOMMU_RESV_DIRECT;
>> +			/*
>> +			 * Set IOMMU_MMIO as IOMMU_RESV_DIRECT is normally used
>> +			 * for device memory like MSI doorbell.
>> +			 */
>> +			prot |= IOMMU_MMIO;
>> +		}
> 
> On the prot value assignment based on the remapping flag, I'd like to
> hear Robin/Joerg's opinion, I'd avoid being in a situation where
> "normally" this would work but then we have to quirk it.
> 
> Is this a valid assumption _always_ ?

I think we enable quite a bit of platforms with this assumption, so IMHO
it's a fair compromise for now. As per Jon's comment and oob
discussions, in the long run the spec should probably be updated to
include a way of explicitly specifying memory attributes.

---
Thanks & Best Regards, Laurentiu

> 
>> +
>> +		region = iommu_alloc_resv_region(addr, size, prot, type);
>> +		if (region) {
>> +			region->fw_data.rmr.flags = rmr->flags;
>> +			region->fw_data.rmr.sid = sid;
>> +			region->fw_data.rmr.smmu = smmu;
>> +			list_add_tail(&region->list, &iort_rmr_list);
>> +		}
>> +	}
>> +}
>> +
>> +static void __init iort_parse_rmr(void)
>> +{
>> +	struct acpi_iort_node *iort_node, *iort_end;
>> +	struct acpi_table_iort *iort;
>> +	int i;
>> +
>> +	if (iort_table->revision < 3)
>> +		return;
>> +
>> +	iort = (struct acpi_table_iort *)iort_table;
>> +
>> +	iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
>> +				 iort->node_offset);
>> +	iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
>> +				iort_table->length);
>> +
>> +	for (i = 0; i < iort->node_count; i++) {
>> +		if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND,
>> +			       "IORT node pointer overflows, bad table!\n"))
>> +			return;
>> +
>> +		if (iort_node->type == ACPI_IORT_NODE_RMR)
>> +			iort_node_get_rmr_info(iort_node);
>> +
>> +		iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
>> +					 iort_node->length);
>> +	}
>> +}
>>  
>>  static void __init iort_init_platform_devices(void)
>>  {
>> @@ -1636,6 +1767,7 @@ void __init acpi_iort_init(void)
>>  	}
>>  
>>  	iort_init_platform_devices();
>> +	iort_parse_rmr();
>>  }
>>  
>>  #ifdef CONFIG_ZONE_DMA
>> -- 
>> 2.17.1
>>
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.linuxfoundation.org%2Fmailman%2Flistinfo%2Fiommu&amp;data=04%7C01%7Claurentiu.tudor%40nxp.com%7Cb020e5093dee4374ee0b08d9582a9238%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637637762131278563%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=8Q%2Fu5qawL94YhbKLujOAlJjTVEWZircjviccWnnqPxs%3D&amp;reserved=0
> 


From geraldogabriel at gmail.com  Thu Aug  5 08:50:58 2021
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Thu, 5 Aug 2021 15:50:58 +0000
Subject: [PATCH] ALSA: usb-audio: fix incorrect clock source setting
In-Reply-To: <20210805075401.21170-1-chihhao.chen@mediatek.com>
References: <CAEsQvctJDnsaRTXAGAJ6==juKazoo2=AJrWabLzqE=jCfg5EEA@mail.gmail.com>
 <20210805075401.21170-1-chihhao.chen@mediatek.com>
Message-ID: <CAEsQvcsvbJdgvAOxkv_kbLohGi676Zrgz4XSFW2o3CWU3Q68Dg@mail.gmail.com>

On Thu, Aug 5, 2021 at 7:54 AM <chihhao.chen at mediatek.com> wrote:
>
> From: chihhao chen <chihhao.chen at mediatek.com>
>
> Hi Geraldo Nascimento,

Hi Chihhao Chen!

>
> For echo test, it means we use this earphone to receive and play sounds at the same time.
> We found in this case serious noise problem happens.
>

That's what I understood initially, and only a little later I became
afraid echo test was the name of the debugging technique you used :)

Thanks for the clarification.

> Log as follows with your patch
> <6>[  175.960387][T401365] __uac_clock_find_source: Clock Selector 0xc has pin 2 selected
> <6>[  175.966980][T401365] __uac_clock_find_source: Clock Selector 0xb has pin 2 selected
> <6>[  176.026251][T400354] __uac_clock_find_source: Clock Selector 0xc has pin 1 selected
> <6>[  176.032406][T400354] __uac_clock_find_source: Clock Selector 0xb has pin 1 selected
>
> There is no noise and I think this should be a firmware bug.

>From the log I'm afraid my worst assumptions were right.

Regardless of which Clock Selector we want to set, the firmware will
always set them both.

We should contact Samsung now that we have at least a sketch of a bug report...

Thanks,
Geraldo Nascimento

>
> Thanks
> Chihhao
>


From frieder.schrempf at kontron.de  Thu Aug  5 11:56:55 2021
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Thu, 5 Aug 2021 20:56:55 +0200
Subject: [PATCH v2 00/18] i.MX8MM GPC improvements and BLK_CTRL driver
In-Reply-To: <818b52fe-8fa6-b47a-6dde-783ac378c603@kontron.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <818b52fe-8fa6-b47a-6dde-783ac378c603@kontron.de>
Message-ID: <8de1cd0a-4d91-60e2-61e6-9f903bbf546b@kontron.de>

On 05.08.21 12:18, Frieder Schrempf wrote:
> On 21.07.21 22:46, Lucas Stach wrote:
>> Hi all,
>>
>> second revision of the GPC improvements and BLK_CTRL driver to make use
>> of all the power-domains on the i.MX8MM. I'm not going to repeat the full
>> blurb from the v1 cover letter here, but if you are not familiar with
>> i.MX8MM power domains, it may be worth a read.
>>
>> This 2nd revision fixes the DT bindings to be valid yaml, some small
>> failure path issues and most importantly the interaction with system
>> suspend/resume. With the previous version some of the power domains
>> would not come up correctly after a suspend/resume cycle.
>>
>> Updated testing git trees here, disclaimer still applies:
>> https://git.pengutronix.de/cgit/lst/linux/log/?h=imx8m-power-domains
>> https://git.pengutronix.de/cgit/lst/linux/log/?h=imx8m-power-domains-testing
> 
> I finally did some tests on my side using USB, GPU and DSI (no PCIe, VPU, CSI so far) and the results are promising. Thanks for the effort!
> 
> I will try to run some more automated suspend/resume and reboot test cycles over the weekend and report the results here afterwards.
> 

Unfortunately I got some results sooner than I had hoped. I set up a simple loop to suspend/resume every few seconds and on the first run it took around 2-3 hours for the device to lock up on resume. On the second run it took less than half an hour. I had glmark2-es2-drm running in the background, but it looks like it crashed at some point before the lockup occurred.

Of course this could also be unrelated and caused by some peripheral driver or something but the first suspicion is definitely the power domains.

If you have any suggestions for which debug options to enable or where to add some printks, please let me know. If I do another run I would like to make sure that the resulting logs are helpful for debugging.

And I would appreciate if someone else could try to reproduce this problem on his/her side. I use this simple script for testing:

#!/bin/sh

glmark2-es2-drm &

while true;
do
    echo +10 > /sys/class/rtc/rtc0/wakealarm
    echo mem > /sys/power/state
    sleep 5
done;


From rafael at kernel.org  Thu Aug  5 12:02:19 2021
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 5 Aug 2021 21:02:19 +0200
Subject: [PATCH v2 3/3] ACPI: Add memory semantics to acpi_os_map_memory()
In-Reply-To: <20210803091605.GA9637@lpieralisi>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-4-lorenzo.pieralisi@arm.com>
 <20210802164622.GJ18685@arm.com> <20210803091605.GA9637@lpieralisi>
Message-ID: <CAJZ5v0jikZd_SMZxL0SAwVGH_-h8C9aUPH9LoG-PUFUZG3eLjA@mail.gmail.com>

On Tue, Aug 3, 2021 at 11:16 AM Lorenzo Pieralisi
<lorenzo.pieralisi at arm.com> wrote:
>
> On Mon, Aug 02, 2021 at 05:46:22PM +0100, Catalin Marinas wrote:
> > On Mon, Aug 02, 2021 at 04:23:59PM +0100, Lorenzo Pieralisi wrote:
> > > The memory attributes attached to memory regions depend on architecture
> > > specific mappings.
> > >
> > > For some memory regions, the attributes specified by firmware (eg
> > > uncached) are not sufficient to determine how a memory region should be
> > > mapped by an OS (for instance a region that is define as uncached in
> > > firmware can be mapped as Normal or Device memory on arm64) and
> > > therefore the OS must be given control on how to map the region to match
> > > the expected mapping behaviour (eg if a mapping is requested with memory
> > > semantics, it must allow unaligned accesses).
> > >
> > > Rework acpi_os_map_memory() and acpi_os_ioremap() back-end to split
> > > them into two separate code paths:
> > >
> > > acpi_os_memmap() -> memory semantics
> > > acpi_os_ioremap() -> MMIO semantics
> > >
> > > The split allows the architectural implementation back-ends to detect
> > > the default memory attributes required by the mapping in question
> > > (ie the mapping API defines the semantics memory vs MMIO) and map the
> > > memory accordingly.
> > >
> > > Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702 at arm.com
> > > Tested-by: Hanjun Guo <guohanjun at huawei.com>
> > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > > Acked-by: Ard Biesheuvel <ardb at kernel.org>
> > > Cc: Ard Biesheuvel <ardb at kernel.org>
> > > Cc: Will Deacon <will at kernel.org>
> > > Cc: Hanjun Guo <guohanjun at huawei.com>
> > > Cc: Sudeep Holla <sudeep.holla at arm.com>
> > > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > > Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
> >
> > For the arm64 bits:
> >
> > Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> >
> > I presume this will get merged via the ACPI tree?
>
> Thank you, I don't know what's the best option in Rafael's opinion
> (of course if he is OK with the patches which are mostly touching
> ACPI code).

Well, I can apply them.

I'll queue them up tomorrow, but next week I'm on vacation, so they
will show up in linux-next after -rc6.  Hopefully, that's not too
late.


From zi.yan at sent.com  Thu Aug  5 12:02:40 2021
From: zi.yan at sent.com (Zi Yan)
Date: Thu,  5 Aug 2021 15:02:40 -0400
Subject: [RFC PATCH 02/15] arch: mm: rename FORCE_MAX_ZONEORDER to
 ARCH_FORCE_MAX_ORDER
In-Reply-To: <20210805190253.2795604-1-zi.yan@sent.com>
References: <20210805190253.2795604-1-zi.yan@sent.com>
Message-ID: <20210805190253.2795604-3-zi.yan@sent.com>

From: Zi Yan <ziy at nvidia.com>

This Kconfig option is used by individual arch to set its desired
MAX_ORDER. Rename it to reflect its actual use.

Signed-off-by: Zi Yan <ziy at nvidia.com>
Cc: Vineet Gupta <vgupta at synopsys.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Guo Ren <guoren at kernel.org>
Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Thomas Bogendoerfer <tsbogend at alpha.franken.de>
Cc: Ley Foon Tan <ley.foon.tan at intel.com>
Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Yoshinori Sato <ysato at users.sourceforge.jp>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: Chris Zankel <chris at zankel.net>
Cc: linux-snps-arc at lists.infradead.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-oxnas at groups.io
Cc: linux-csky at vger.kernel.org
Cc: linux-ia64 at vger.kernel.org
Cc: linux-m68k at lists.linux-m68k.org
Cc: linux-mips at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-sh at vger.kernel.org
Cc: sparclinux at vger.kernel.org
Cc: linux-xtensa at linux-xtensa.org
Cc: linux-mm at kvack.org
Cc: linux-kernel at vger.kernel.org
---
 arch/arc/Kconfig                             | 2 +-
 arch/arm/Kconfig                             | 2 +-
 arch/arm/configs/imx_v6_v7_defconfig         | 2 +-
 arch/arm/configs/milbeaut_m10v_defconfig     | 2 +-
 arch/arm/configs/oxnas_v6_defconfig          | 2 +-
 arch/arm/configs/sama7_defconfig             | 2 +-
 arch/arm64/Kconfig                           | 2 +-
 arch/csky/Kconfig                            | 2 +-
 arch/ia64/Kconfig                            | 2 +-
 arch/ia64/include/asm/sparsemem.h            | 6 +++---
 arch/m68k/Kconfig.cpu                        | 2 +-
 arch/mips/Kconfig                            | 2 +-
 arch/nios2/Kconfig                           | 2 +-
 arch/powerpc/Kconfig                         | 2 +-
 arch/powerpc/configs/85xx/ge_imp3a_defconfig | 2 +-
 arch/powerpc/configs/fsl-emb-nonhw.config    | 2 +-
 arch/sh/configs/ecovec24_defconfig           | 2 +-
 arch/sh/mm/Kconfig                           | 2 +-
 arch/sparc/Kconfig                           | 2 +-
 arch/xtensa/Kconfig                          | 2 +-
 include/linux/mmzone.h                       | 4 ++--
 21 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index b5bf68e74732..923ea4c31e59 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -583,7 +583,7 @@ config ARC_BUILTIN_DTB_NAME
 
 endmenu	 # "ARC Architecture Configuration"
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	default "12" if ARC_HUGEPAGE_16M
 	default "11"
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2fb7012c3246..286854318fe5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1523,7 +1523,7 @@ config ARM_MODULE_PLTS
 	  Disabling this is usually safe for small single-platform
 	  configurations. If unsure, say y.
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	default "12" if SOC_AM33XX
 	default "9" if SA1111
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 079fcd8d1d11..802310d3ebf5 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -34,7 +34,7 @@ CONFIG_PCI_IMX6=y
 CONFIG_SMP=y
 CONFIG_ARM_PSCI=y
 CONFIG_HIGHMEM=y
-CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_ARCH_FORCE_MAX_ORDER=14
 CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
 CONFIG_KEXEC=y
 CONFIG_CPU_FREQ=y
diff --git a/arch/arm/configs/milbeaut_m10v_defconfig b/arch/arm/configs/milbeaut_m10v_defconfig
index 7c07f9893a0f..06967243f74d 100644
--- a/arch/arm/configs/milbeaut_m10v_defconfig
+++ b/arch/arm/configs/milbeaut_m10v_defconfig
@@ -26,7 +26,7 @@ CONFIG_THUMB2_KERNEL=y
 # CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11 is not set
 # CONFIG_ARM_PATCH_IDIV is not set
 CONFIG_HIGHMEM=y
-CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_ARCH_FORCE_MAX_ORDER=12
 CONFIG_SECCOMP=y
 CONFIG_KEXEC=y
 CONFIG_EFI=y
diff --git a/arch/arm/configs/oxnas_v6_defconfig b/arch/arm/configs/oxnas_v6_defconfig
index cae0db6b4eaf..df8462272446 100644
--- a/arch/arm/configs/oxnas_v6_defconfig
+++ b/arch/arm/configs/oxnas_v6_defconfig
@@ -17,7 +17,7 @@ CONFIG_MACH_OX820=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
 CONFIG_CMA=y
-CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_ARCH_FORCE_MAX_ORDER=12
 CONFIG_SECCOMP=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 938aae4bd80b..f8683b87cb27 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -22,7 +22,7 @@ CONFIG_ATMEL_CLOCKSOURCE_TCB=y
 # CONFIG_CACHE_L2X0 is not set
 # CONFIG_ARM_PATCH_IDIV is not set
 # CONFIG_CPU_SW_DOMAIN_PAN is not set
-CONFIG_FORCE_MAX_ZONEORDER=15
+CONFIG_ARCH_FORCE_MAX_ORDER=15
 CONFIG_UACCESS_WITH_MEMCPY=y
 # CONFIG_ATAGS is not set
 CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel"
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5b13a932561..972d81f6bb2c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1152,7 +1152,7 @@ config XEN
 	help
 	  Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64.
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int
 	default "14" if ARM64_64K_PAGES
 	default "12" if ARM64_16K_PAGES
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
index 2716f6395ba7..0fd2333226b7 100644
--- a/arch/csky/Kconfig
+++ b/arch/csky/Kconfig
@@ -307,7 +307,7 @@ config HIGHMEM
 	select KMAP_LOCAL
 	default y
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	default "11"
 
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 4993c7ac7ff6..d1bd010ee7a5 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -200,7 +200,7 @@ config IA64_CYCLONE
 	  Say Y here to enable support for IBM EXA Cyclone time source.
 	  If you're unsure, answer N.
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "MAX_ORDER (11 - 17)"  if !HUGETLB_PAGE
 	range 11 17  if !HUGETLB_PAGE
 	default "17" if HUGETLB_PAGE
diff --git a/arch/ia64/include/asm/sparsemem.h b/arch/ia64/include/asm/sparsemem.h
index 42ed5248fae9..84e8ce387b69 100644
--- a/arch/ia64/include/asm/sparsemem.h
+++ b/arch/ia64/include/asm/sparsemem.h
@@ -11,10 +11,10 @@
 
 #define SECTION_SIZE_BITS	(30)
 #define MAX_PHYSMEM_BITS	(50)
-#ifdef CONFIG_FORCE_MAX_ZONEORDER
-#if ((CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS)
+#ifdef CONFIG_ARCH_FORCE_MAX_ORDER
+#if ((CONFIG_ARCH_FORCE_MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS)
 #undef SECTION_SIZE_BITS
-#define SECTION_SIZE_BITS (CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT)
+#define SECTION_SIZE_BITS (CONFIG_ARCH_FORCE_MAX_ORDER - 1 + PAGE_SHIFT)
 #endif
 #endif
 
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu
index 29e946394fdb..c39157f3dd87 100644
--- a/arch/m68k/Kconfig.cpu
+++ b/arch/m68k/Kconfig.cpu
@@ -408,7 +408,7 @@ config SINGLE_MEMORY_CHUNK
 	  order" to save memory that could be wasted for unused memory map.
 	  Say N if not sure.
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order" if ADVANCED
 	depends on !SINGLE_MEMORY_CHUNK
 	default "11"
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 6dfb27d531dd..0998f671ed7e 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2284,7 +2284,7 @@ config PAGE_SIZE_64KB
 
 endchoice
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	range 14 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB
 	default "14" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index c24955c81c92..e5c300198e1f 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -50,7 +50,7 @@ menu "Kernel features"
 
 source "kernel/Kconfig.hz"
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	range 9 20
 	default "11"
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2e213ec6ec05..5edb48b363c4 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -810,7 +810,7 @@ config DATA_SHIFT
 	  in that case. If PIN_TLB is selected, it must be aligned to 8M as
 	  8M pages will be pinned.
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	range 8 9 if PPC64 && PPC_64K_PAGES
 	default "9" if PPC64 && PPC_64K_PAGES
diff --git a/arch/powerpc/configs/85xx/ge_imp3a_defconfig b/arch/powerpc/configs/85xx/ge_imp3a_defconfig
index f29c166998af..e7672c186325 100644
--- a/arch/powerpc/configs/85xx/ge_imp3a_defconfig
+++ b/arch/powerpc/configs/85xx/ge_imp3a_defconfig
@@ -30,7 +30,7 @@ CONFIG_PREEMPT=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_MATH_EMULATION=y
-CONFIG_FORCE_MAX_ZONEORDER=17
+CONFIG_ARCH_FORCE_MAX_ORDER=17
 CONFIG_PCI=y
 CONFIG_PCIEPORTBUS=y
 CONFIG_PCI_MSI=y
diff --git a/arch/powerpc/configs/fsl-emb-nonhw.config b/arch/powerpc/configs/fsl-emb-nonhw.config
index df37efed0aec..521e7a530888 100644
--- a/arch/powerpc/configs/fsl-emb-nonhw.config
+++ b/arch/powerpc/configs/fsl-emb-nonhw.config
@@ -41,7 +41,7 @@ CONFIG_FIXED_PHY=y
 CONFIG_FONT_8x16=y
 CONFIG_FONT_8x8=y
 CONFIG_FONTS=y
-CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_ARCH_FORCE_MAX_ORDER=13
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAME_WARN=1024
 CONFIG_FTL=y
diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig
index 03cb916819fa..4c09ca308d43 100644
--- a/arch/sh/configs/ecovec24_defconfig
+++ b/arch/sh/configs/ecovec24_defconfig
@@ -8,7 +8,7 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_CPU_SUBTYPE_SH7724=y
-CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_ARCH_FORCE_MAX_ORDER=12
 CONFIG_MEMORY_SIZE=0x10000000
 CONFIG_FLATMEM_MANUAL=y
 CONFIG_SH_ECOVEC=y
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index ba569cfb4368..411fdc0901f7 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -18,7 +18,7 @@ config PAGE_OFFSET
 	default "0x80000000" if MMU
 	default "0x00000000"
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	range 9 64 if PAGE_SIZE_16KB
 	default "9" if PAGE_SIZE_16KB
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index f0c0f955e169..2206c99612ed 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -273,7 +273,7 @@ config ARCH_SPARSEMEM_ENABLE
 config ARCH_SPARSEMEM_DEFAULT
 	def_bool y if SPARC64
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	default "13"
 	help
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index b843902ad9fd..90784aa68cf8 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -709,7 +709,7 @@ config HIGHMEM
 
 	  If unsure, say Y.
 
-config FORCE_MAX_ZONEORDER
+config ARCH_FORCE_MAX_ORDER
 	int "Maximum zone order"
 	default "11"
 	help
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index c1d914a72489..98e3297b9e09 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -24,10 +24,10 @@
 #include <asm/page.h>
 
 /* Free memory management - zoned buddy allocator.  */
-#ifndef CONFIG_FORCE_MAX_ZONEORDER
+#ifndef CONFIG_ARCH_FORCE_MAX_ORDER
 #define MAX_ORDER 11
 #else
-#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
+#define MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
 #endif
 #define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))
 
-- 
2.30.2



From zi.yan at sent.com  Thu Aug  5 12:02:52 2021
From: zi.yan at sent.com (Zi Yan)
Date: Thu,  5 Aug 2021 15:02:52 -0400
Subject: [RFC PATCH 14/15] mm: introduce MIN_MAX_ORDER to replace MAX_ORDER as
 compile time constant.
In-Reply-To: <20210805190253.2795604-1-zi.yan@sent.com>
References: <20210805190253.2795604-1-zi.yan@sent.com>
Message-ID: <20210805190253.2795604-15-zi.yan@sent.com>

From: Zi Yan <ziy at nvidia.com>

For other MAX_ORDER uses (described below), there is no need or too much
hassle to convert certain static array to dynamic ones. Add
MIN_MAX_ORDER to serve as compile time constant in place of MAX_ORDER.

ARM64 hypervisor maintains its own free page list and does not import
any core kernel symbols, so soon-to-be runtime variable MAX_ORDER is not
accessible in ARM64 hypervisor code. Also there is no need to allocating
very large pages.

In SLAB/SLOB/SLUB, 2-D array kmalloc_caches uses MAX_ORDER in its second
dimension. It is too much hassle to allocate memory for kmalloc_caches
before any proper memory allocator is set up.

Signed-off-by: Zi Yan <ziy at nvidia.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Christoph Lameter <cl at linux.com>
Cc: Vlastimil Babka <vbabka at suse.cz>
Cc: Quentin Perret <qperret at google.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-mm at kvack.org
Cc: linux-kernel at vger.kernel.org
---
 arch/arm64/kvm/hyp/include/nvhe/gfp.h | 2 +-
 arch/arm64/kvm/hyp/nvhe/page_alloc.c  | 3 ++-
 include/linux/mmzone.h                | 3 +++
 include/linux/slab.h                  | 8 ++++----
 mm/slab.c                             | 2 +-
 mm/slub.c                             | 7 ++++---
 6 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
index fb0f523d1492..c774b4a98336 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
@@ -16,7 +16,7 @@ struct hyp_pool {
 	 * API at EL2.
 	 */
 	hyp_spinlock_t lock;
-	struct list_head free_area[MAX_ORDER];
+	struct list_head free_area[MIN_MAX_ORDER];
 	phys_addr_t range_start;
 	phys_addr_t range_end;
 	unsigned short max_order;
diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
index 41fc25bdfb34..a1cc1b648de0 100644
--- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
+++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
@@ -226,7 +226,8 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
 	int i;
 
 	hyp_spin_lock_init(&pool->lock);
-	pool->max_order = min(MAX_ORDER, get_order(nr_pages << PAGE_SHIFT));
+
+	pool->max_order = min(MIN_MAX_ORDER, get_order(nr_pages << PAGE_SHIFT));
 	for (i = 0; i < pool->max_order; i++)
 		INIT_LIST_HEAD(&pool->free_area[i]);
 	pool->range_start = phys;
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 09aafc05aef4..379dada82d4b 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -27,11 +27,14 @@
 #ifndef CONFIG_ARCH_FORCE_MAX_ORDER
 #ifdef CONFIG_SET_MAX_ORDER
 #define MAX_ORDER CONFIG_SET_MAX_ORDER
+#define MIN_MAX_ORDER CONFIG_SET_MAX_ORDER
 #else
 #define MAX_ORDER 11
+#define MIN_MAX_ORDER MAX_ORDER
 #endif /* CONFIG_SET_MAX_ORDER */
 #else
 #define MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
+#define MIN_MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
 #endif /* CONFIG_ARCH_FORCE_MAX_ORDER */
 #define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))
 
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 2c0d80cca6b8..d8747c158db6 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -244,8 +244,8 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
  * to do various tricks to work around compiler limitations in order to
  * ensure proper constant folding.
  */
-#define KMALLOC_SHIFT_HIGH	((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
-				(MAX_ORDER + PAGE_SHIFT - 1) : 25)
+#define KMALLOC_SHIFT_HIGH	((MIN_MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
+				(MIN_MAX_ORDER + PAGE_SHIFT - 1) : 25)
 #define KMALLOC_SHIFT_MAX	KMALLOC_SHIFT_HIGH
 #ifndef KMALLOC_SHIFT_LOW
 #define KMALLOC_SHIFT_LOW	5
@@ -258,7 +258,7 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
  * (PAGE_SIZE*2).  Larger requests are passed to the page allocator.
  */
 #define KMALLOC_SHIFT_HIGH	(PAGE_SHIFT + 1)
-#define KMALLOC_SHIFT_MAX	(MAX_ORDER + PAGE_SHIFT - 1)
+#define KMALLOC_SHIFT_MAX	(MIN_MAX_ORDER + PAGE_SHIFT - 1)
 #ifndef KMALLOC_SHIFT_LOW
 #define KMALLOC_SHIFT_LOW	3
 #endif
@@ -271,7 +271,7 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
  * be allocated from the same page.
  */
 #define KMALLOC_SHIFT_HIGH	PAGE_SHIFT
-#define KMALLOC_SHIFT_MAX	(MAX_ORDER + PAGE_SHIFT - 1)
+#define KMALLOC_SHIFT_MAX	(MIN_MAX_ORDER + PAGE_SHIFT - 1)
 #ifndef KMALLOC_SHIFT_LOW
 #define KMALLOC_SHIFT_LOW	3
 #endif
diff --git a/mm/slab.c b/mm/slab.c
index d0f725637663..0041de8ec0e9 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -466,7 +466,7 @@ static int __init slab_max_order_setup(char *str)
 {
 	get_option(&str, &slab_max_order);
 	slab_max_order = slab_max_order < 0 ? 0 :
-				min(slab_max_order, MAX_ORDER - 1);
+				min(slab_max_order, MIN_MAX_ORDER - 1);
 	slab_max_order_set = true;
 
 	return 1;
diff --git a/mm/slub.c b/mm/slub.c
index b6c5205252eb..228e4a77c678 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3564,8 +3564,9 @@ static inline int calculate_order(unsigned int size)
 	/*
 	 * Doh this slab cannot be placed using slub_max_order.
 	 */
-	order = slab_order(size, 1, MAX_ORDER, 1);
-	if (order < MAX_ORDER)
+
+	order = slab_order(size, 1, MIN_MAX_ORDER, 1);
+	if (order < MIN_MAX_ORDER)
 		return order;
 	return -ENOSYS;
 }
@@ -4079,7 +4080,7 @@ __setup("slub_min_order=", setup_slub_min_order);
 static int __init setup_slub_max_order(char *str)
 {
 	get_option(&str, (int *)&slub_max_order);
-	slub_max_order = min(slub_max_order, (unsigned int)MAX_ORDER - 1);
+	slub_max_order = min(slub_max_order, (unsigned int)MIN_MAX_ORDER - 1);
 
 	return 1;
 }
-- 
2.30.2



From bgolaszewski at baylibre.com  Thu Aug  5 12:08:52 2021
From: bgolaszewski at baylibre.com (Bartosz Golaszewski)
Date: Thu, 5 Aug 2021 21:08:52 +0200
Subject: [PATCH v2 2/2] dt-bindings: at24: add ON Semi CAT24C04 and
 CAT24C05
In-Reply-To: <1628105086-8172-3-git-send-email-raagjadav@gmail.com>
References: <1628105086-8172-1-git-send-email-raagjadav@gmail.com>
 <1628105086-8172-3-git-send-email-raagjadav@gmail.com>
Message-ID: <CAMpxmJXsOHR0xTsMNqdqydboRiaj7iRnCSQT98uGX2woUUPVEA@mail.gmail.com>

On Wed, Aug 4, 2021 at 9:25 PM Raag Jadav <raagjadav at gmail.com> wrote:
>
> Add bindings for ON Semi CAT24C04 and CAT24C05 eeproms,
> which are compatible with Atmel AT24C04.
>
> Signed-off-by: Raag Jadav <raagjadav at gmail.com>
> ---
>  Documentation/devicetree/bindings/eeprom/at24.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/eeprom/at24.yaml b/Documentation/devicetree/bindings/eeprom/at24.yaml
> index 914a423..4c5396a 100644
> --- a/Documentation/devicetree/bindings/eeprom/at24.yaml
> +++ b/Documentation/devicetree/bindings/eeprom/at24.yaml
> @@ -98,6 +98,12 @@ properties:
>            - const: nxp,se97b
>            - const: atmel,24c02
>        - items:
> +          - const: onnn,cat24c04
> +          - const: atmel,24c04
> +      - items:
> +          - const: onnn,cat24c05
> +          - const: atmel,24c04
> +      - items:
>            - const: renesas,r1ex24002
>            - const: atmel,24c02
>        - items:
> --
> 2.7.4
>

Applied, thanks!

Bartosz


From bgolaszewski at baylibre.com  Thu Aug  5 12:17:20 2021
From: bgolaszewski at baylibre.com (Bartosz Golaszewski)
Date: Thu, 5 Aug 2021 21:17:20 +0200
Subject: [PATCH v6 0/9] ASPEED sgpio driver enhancement.
In-Reply-To: <CACPK8XdfisvSzr3uWYmfd+u1UtM5+cyMBMvcDZJ+jQ38A1BSXg@mail.gmail.com>
References: <20210712100317.23298-1-steven_lee@aspeedtech.com>
 <CAMpxmJXfUterUdaGHOJT5hwcVJ+3cqgSQVdp-6Atuyyo36FxfQ@mail.gmail.com>
 <20210723031615.GA10457@aspeedtech.com>
 <CAMpxmJU4jN-hpNYPLHLbjx4uZ6vDqcyuMVQXhHg1BWXOqyS22A@mail.gmail.com>
 <58256e8f-6c9a-4ad4-b51e-4048b6feb42a@www.fastmail.com>
 <CACPK8XdfisvSzr3uWYmfd+u1UtM5+cyMBMvcDZJ+jQ38A1BSXg@mail.gmail.com>
Message-ID: <CAMpxmJVHEj12D0RsV51YnKeD9OZUZzve2--pM9vWbBSZdrz7dA@mail.gmail.com>

On Tue, Aug 3, 2021 at 7:58 AM Joel Stanley <joel at jms.id.au> wrote:
>
> On Tue, 3 Aug 2021 at 04:49, Andrew Jeffery <andrew at aj.id.au> wrote:
> > On Fri, 23 Jul 2021, at 17:00, Bartosz Golaszewski wrote:
> > > Joel, Andrew: can I take the GPIO patches through the GPIO tree and
> > > you'll take the ARM patches separately into v5.15?
> >
> > I think that should be okay. I'll poke Joel.
>
> Yes, that's fine. I have merged the first four patches into the aspeed tree.
>
> Cheers,
>
> Joel

Thanks, I applied patches 5-9 to the GPIO tree.

Bart


From lkp at intel.com  Thu Aug  5 12:29:25 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 6 Aug 2021 03:29:25 +0800
Subject: [PATCH v3 04/10] hantro: Add quirk for NV12/NV12_4L4 capture
 format
In-Reply-To: <20210805144246.11998-5-andrzej.p@collabora.com>
References: <20210805144246.11998-5-andrzej.p@collabora.com>
Message-ID: <202108060354.a1d3wFC7-lkp@intel.com>

Hi Andrzej,

I love your patch! Yet something to improve:

[auto build test ERROR on bfee75f73c37a2f46a6326eaa06f5db701f76f01]

url:    https://github.com/0day-ci/linux/commits/Andrzej-Pietrasiewicz/VP9-codec-V4L2-control-interface/20210805-224717
base:   bfee75f73c37a2f46a6326eaa06f5db701f76f01
config: m68k-allmodconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/16e1c749ce0c829d7984d7c3b43d4f01cc27232d
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Andrzej-Pietrasiewicz/VP9-codec-V4L2-control-interface/20210805-224717
        git checkout 16e1c749ce0c829d7984d7c3b43d4f01cc27232d
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash drivers/staging/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/staging/media/hantro/imx8m_vpu_hw.c:137:13: error: 'V4L2_PIX_FMT_NV12_4L4' undeclared here (not in a function); did you mean 'V4L2_PIX_FMT_NV12M'?
     137 |   .fourcc = V4L2_PIX_FMT_NV12_4L4,
         |             ^~~~~~~~~~~~~~~~~~~~~
         |             V4L2_PIX_FMT_NV12M


vim +137 drivers/staging/media/hantro/imx8m_vpu_hw.c

   134	
   135	static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {
   136		{
 > 137			.fourcc = V4L2_PIX_FMT_NV12_4L4,
   138			.codec_mode = HANTRO_MODE_NONE,
   139		},
   140		{
   141			.fourcc = V4L2_PIX_FMT_HEVC_SLICE,
   142			.codec_mode = HANTRO_MODE_HEVC_DEC,
   143			.max_depth = 2,
   144			.frmsize = {
   145				.min_width = 48,
   146				.max_width = 3840,
   147				.step_width = MB_DIM,
   148				.min_height = 48,
   149				.max_height = 2160,
   150				.step_height = MB_DIM,
   151			},
   152		},
   153	};
   154	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 60698 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210806/4772aa79/attachment-0001.gz>

From dmitry.baryshkov at linaro.org  Thu Aug  5 13:37:32 2021
From: dmitry.baryshkov at linaro.org (Dmitry Baryshkov)
Date: Thu, 5 Aug 2021 23:37:32 +0300
Subject: [PATCH] drm/aperture: Pass DRM driver structure instead of driver
 name
In-Reply-To: <20210629135833.22679-1-tzimmermann@suse.de>
References: <20210629135833.22679-1-tzimmermann@suse.de>
Message-ID: <ba6a19fb-2d52-340a-649f-211e4cf7c8fb@linaro.org>

On 29/06/2021 16:58, Thomas Zimmermann wrote:
> Print the name of the DRM driver when taking over fbdev devices. Makes
> the output to dmesg more consistent. Note that the driver name is only
> used for printing a string to the kernel log. No UAPI is affected by this
> change.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> ---

[...]

>   drivers/gpu/drm/msm/msm_fbdev.c               |  2 +-

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>

>   drivers/gpu/drm/nouveau/nouveau_drm.c         |  2 +-
>   drivers/gpu/drm/qxl/qxl_drv.c                 |  2 +-
>   drivers/gpu/drm/radeon/radeon_drv.c           |  2 +-
>   drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |  2 +-
>   drivers/gpu/drm/sun4i/sun4i_drv.c             |  2 +-
>   drivers/gpu/drm/tegra/drm.c                   |  2 +-
>   drivers/gpu/drm/tiny/cirrus.c                 |  2 +-
>   drivers/gpu/drm/vboxvideo/vbox_drv.c          |  2 +-
>   drivers/gpu/drm/vc4/vc4_drv.c                 |  2 +-
>   drivers/gpu/drm/virtio/virtgpu_drv.c          |  2 +-
>   drivers/gpu/drm/vmwgfx/vmwgfx_drv.c           |  2 +-
>   include/drm/drm_aperture.h                    | 14 +++++++++-----
>   23 files changed, 43 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 6f30c525caac..accf9c1b967a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -1278,7 +1278,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
>   #endif
>   
>   	/* Get rid of things like offb */
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "amdgpudrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &amdgpu_kms_driver);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
> index dab0a1f0983b..31925ae3ab72 100644
> --- a/drivers/gpu/drm/armada/armada_drv.c
> +++ b/drivers/gpu/drm/armada/armada_drv.c
> @@ -95,7 +95,7 @@ static int armada_drm_bind(struct device *dev)
>   	}
>   
>   	/* Remove early framebuffers */
> -	ret = drm_aperture_remove_framebuffers(false, "armada-drm-fb");
> +	ret = drm_aperture_remove_framebuffers(false, &armada_drm_driver);
>   	if (ret) {
>   		dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n",
>   			__func__, ret);
> diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
> index 5aa452b4efe6..86d5cd7b6318 100644
> --- a/drivers/gpu/drm/ast/ast_drv.c
> +++ b/drivers/gpu/drm/ast/ast_drv.c
> @@ -100,7 +100,7 @@ static int ast_remove_conflicting_framebuffers(struct pci_dev *pdev)
>   	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
>   #endif
>   
> -	return drm_aperture_remove_conflicting_framebuffers(base, size, primary, "astdrmfb");
> +	return drm_aperture_remove_conflicting_framebuffers(base, size, primary, &ast_driver);
>   }
>   
>   static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
> index c828cadbabff..0d232b44ecd7 100644
> --- a/drivers/gpu/drm/bochs/bochs_drv.c
> +++ b/drivers/gpu/drm/bochs/bochs_drv.c
> @@ -110,7 +110,7 @@ static int bochs_pci_probe(struct pci_dev *pdev,
>   		return -ENOMEM;
>   	}
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "bochsdrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &bochs_driver);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c
> index 9335d9d6cf9a..9ac39cf11694 100644
> --- a/drivers/gpu/drm/drm_aperture.c
> +++ b/drivers/gpu/drm/drm_aperture.c
> @@ -33,6 +33,10 @@
>    *
>    * .. code-block:: c
>    *
> + *	static const struct drm_driver example_driver = {
> + *		...
> + *	};
> + *
>    *	static int remove_conflicting_framebuffers(struct pci_dev *pdev)
>    *	{
>    *		bool primary = false;
> @@ -46,7 +50,7 @@
>    *	#endif
>    *
>    *		return drm_aperture_remove_conflicting_framebuffers(base, size, primary,
> - *		                                                    "example driver");
> + *		                                                    &example_driver);
>    *	}
>    *
>    *	static int probe(struct pci_dev *pdev)
> @@ -274,7 +278,7 @@ static void drm_aperture_detach_drivers(resource_size_t base, resource_size_t si
>    * @base: the aperture's base address in physical memory
>    * @size: aperture size in bytes
>    * @primary: also kick vga16fb if present
> - * @name: requesting driver name
> + * @req_driver: requesting DRM driver
>    *
>    * This function removes graphics device drivers which use memory range described by
>    * @base and @size.
> @@ -283,7 +287,7 @@ static void drm_aperture_detach_drivers(resource_size_t base, resource_size_t si
>    * 0 on success, or a negative errno code otherwise
>    */
>   int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size,
> -						 bool primary, const char *name)
> +						 bool primary, const struct drm_driver *req_driver)
>   {
>   #if IS_REACHABLE(CONFIG_FB)
>   	struct apertures_struct *a;
> @@ -296,7 +300,7 @@ int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_
>   	a->ranges[0].base = base;
>   	a->ranges[0].size = size;
>   
> -	ret = remove_conflicting_framebuffers(a, name, primary);
> +	ret = remove_conflicting_framebuffers(a, req_driver->name, primary);
>   	kfree(a);
>   
>   	if (ret)
> @@ -312,7 +316,7 @@ EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers);
>   /**
>    * drm_aperture_remove_conflicting_pci_framebuffers - remove existing framebuffers for PCI devices
>    * @pdev: PCI device
> - * @name: requesting driver name
> + * @req_driver: requesting DRM driver
>    *
>    * This function removes graphics device drivers using memory range configured
>    * for any of @pdev's memory bars. The function assumes that PCI device with
> @@ -321,7 +325,8 @@ EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers);
>    * Returns:
>    * 0 on success, or a negative errno code otherwise
>    */
> -int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name)
> +int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
> +						     const struct drm_driver *req_driver)
>   {
>   	resource_size_t base, size;
>   	int bar, ret = 0;
> @@ -339,7 +344,7 @@ int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const
>   	 * otherwise the vga fbdev driver falls over.
>   	 */
>   #if IS_REACHABLE(CONFIG_FB)
> -	ret = remove_conflicting_pci_framebuffers(pdev, name);
> +	ret = remove_conflicting_pci_framebuffers(pdev, req_driver->name);
>   #endif
>   	if (ret == 0)
>   		ret = vga_remove_vgacon(pdev);
> diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> index f4bc5386574a..6f0297b854f2 100644
> --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c
> @@ -314,7 +314,7 @@ static int hibmc_pci_probe(struct pci_dev *pdev,
>   	struct drm_device *dev;
>   	int ret;
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "hibmcdrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &hibmc_driver);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> index eb06c92c4bfd..cd818a629183 100644
> --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c
> @@ -82,7 +82,7 @@ static int hyperv_setup_gen1(struct hyperv_drm_device *hv)
>   		return -ENODEV;
>   	}
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "hypervdrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &hyperv_driver);
>   	if (ret) {
>   		drm_err(dev, "Not able to remove boot fb\n");
>   		return ret;
> @@ -127,7 +127,7 @@ static int hyperv_setup_gen2(struct hyperv_drm_device *hv,
>   	drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base,
>   						     screen_info.lfb_size,
>   						     false,
> -						     "hypervdrmfb");
> +						     &hyperv_driver);
>   
>   	hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024;
>   
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 850b499c71c8..62327c15f457 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -562,7 +562,7 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
>   	if (ret)
>   		goto err_perf;
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "inteldrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, dev_priv->drm.driver);
>   	if (ret)
>   		goto err_ggtt;
>   
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index a7388bf7c838..3d0ccc7eef1b 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -285,7 +285,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>   	 * Remove early framebuffers (ie. simplefb). The framebuffer can be
>   	 * located anywhere in RAM
>   	 */
> -	ret = drm_aperture_remove_framebuffers(false, "meson-drm-fb");
> +	ret = drm_aperture_remove_framebuffers(false, &meson_driver);
>   	if (ret)
>   		goto free_drm;
>   
> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
> index a701d9563257..36d1bfb3213f 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_drv.c
> +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
> @@ -342,7 +342,7 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>   	struct drm_device *dev;
>   	int ret;
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "mgag200drmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &mgag200_driver);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
> index 227404077e39..67fae60f2fa5 100644
> --- a/drivers/gpu/drm/msm/msm_fbdev.c
> +++ b/drivers/gpu/drm/msm/msm_fbdev.c
> @@ -169,7 +169,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
>   	}
>   
>   	/* the fw fb could be anywhere in memory */
> -	ret = drm_aperture_remove_framebuffers(false, "msm");
> +	ret = drm_aperture_remove_framebuffers(false, dev->driver);
>   	if (ret)
>   		goto fini;
>   
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
> index a616cf4573b8..df8a2d92f473 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> @@ -738,7 +738,7 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
>   	nvkm_device_del(&device);
>   
>   	/* Remove conflicting drivers (vesafb, efifb etc). */
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "nouveaufb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver_pci);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
> index 854e6c5a563f..31f4c86ceb99 100644
> --- a/drivers/gpu/drm/qxl/qxl_drv.c
> +++ b/drivers/gpu/drm/qxl/qxl_drv.c
> @@ -95,7 +95,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>   	if (ret)
>   		return ret;
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "qxl");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &qxl_driver);
>   	if (ret)
>   		goto disable_pci;
>   
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
> index 8cd135fa6dcd..82ee8244c9b3 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -330,7 +330,7 @@ static int radeon_pci_probe(struct pci_dev *pdev,
>   		return -EPROBE_DEFER;
>   
>   	/* Get rid of things like offb */
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "radeondrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &kms_driver);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index b730b8d5d949..17a189bb6bbc 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -116,7 +116,7 @@ static int rockchip_drm_bind(struct device *dev)
>   	int ret;
>   
>   	/* Remove existing drivers that may own the framebuffer memory. */
> -	ret = drm_aperture_remove_framebuffers(false, "rockchip-drm-fb");
> +	ret = drm_aperture_remove_framebuffers(false, &rockchip_drm_driver);
>   	if (ret) {
>   		DRM_DEV_ERROR(dev,
>   			      "Failed to remove existing framebuffers - %d.\n",
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
> index af335f58bdfc..6bc1c8d6d43b 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -100,7 +100,7 @@ static int sun4i_drv_bind(struct device *dev)
>   	drm->irq_enabled = true;
>   
>   	/* Remove early framebuffers (ie. simplefb) */
> -	ret = drm_aperture_remove_framebuffers(false, "sun4i-drm-fb");
> +	ret = drm_aperture_remove_framebuffers(false, &sun4i_drv_driver);
>   	if (ret)
>   		goto cleanup_mode_config;
>   
> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> index f96c237b2242..2c8fc14bba1f 100644
> --- a/drivers/gpu/drm/tegra/drm.c
> +++ b/drivers/gpu/drm/tegra/drm.c
> @@ -1204,7 +1204,7 @@ static int host1x_drm_probe(struct host1x_device *dev)
>   
>   	drm_mode_config_reset(drm);
>   
> -	err = drm_aperture_remove_framebuffers(false, "tegradrmfb");
> +	err = drm_aperture_remove_framebuffers(false, &tegra_drm_driver);
>   	if (err < 0)
>   		goto hub;
>   
> diff --git a/drivers/gpu/drm/tiny/cirrus.c b/drivers/gpu/drm/tiny/cirrus.c
> index 42611dacde88..a8b476a59c0d 100644
> --- a/drivers/gpu/drm/tiny/cirrus.c
> +++ b/drivers/gpu/drm/tiny/cirrus.c
> @@ -550,7 +550,7 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
>   	struct cirrus_device *cirrus;
>   	int ret;
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "cirrusdrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &cirrus_driver);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> index 6d4b32da9866..879a2445cc44 100644
> --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c
> +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c
> @@ -43,7 +43,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>   	if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
>   		return -ENODEV;
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "vboxvideodrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index 8a60fb8ad370..73335feb712f 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -265,7 +265,7 @@ static int vc4_drm_bind(struct device *dev)
>   	if (ret)
>   		goto unbind_all;
>   
> -	ret = drm_aperture_remove_framebuffers(false, "vc4drmfb");
> +	ret = drm_aperture_remove_framebuffers(false, &vc4_drm_driver);
>   	if (ret)
>   		goto unbind_all;
>   
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
> index ca77edbc5ea0..ed85a7863256 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drv.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
> @@ -57,7 +57,7 @@ static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vd
>   		 vga ? "virtio-vga" : "virtio-gpu-pci",
>   		 pname);
>   	if (vga) {
> -		ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "virtiodrmfb");
> +		ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
>   		if (ret)
>   			return ret;
>   	}
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> index 086dc75e7b42..40864ce19ae1 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> @@ -1574,7 +1574,7 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>   	struct vmw_private *vmw;
>   	int ret;
>   
> -	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "svgadrmfb");
> +	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
>   	if (ret)
>   		return ret;
>   
> diff --git a/include/drm/drm_aperture.h b/include/drm/drm_aperture.h
> index 6c148078780c..7096703c3949 100644
> --- a/include/drm/drm_aperture.h
> +++ b/include/drm/drm_aperture.h
> @@ -6,20 +6,22 @@
>   #include <linux/types.h>
>   
>   struct drm_device;
> +struct drm_driver;
>   struct pci_dev;
>   
>   int devm_aperture_acquire_from_firmware(struct drm_device *dev, resource_size_t base,
>   					resource_size_t size);
>   
>   int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size,
> -						 bool primary, const char *name);
> +						 bool primary, const struct drm_driver *req_driver);
>   
> -int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name);
> +int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
> +						     const struct drm_driver *req_driver);
>   
>   /**
>    * drm_aperture_remove_framebuffers - remove all existing framebuffers
>    * @primary: also kick vga16fb if present
> - * @name: requesting driver name
> + * @req_driver: requesting DRM driver
>    *
>    * This function removes all graphics device drivers. Use this function on systems
>    * that can have their framebuffer located anywhere in memory.
> @@ -27,9 +29,11 @@ int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const
>    * Returns:
>    * 0 on success, or a negative errno code otherwise
>    */
> -static inline int drm_aperture_remove_framebuffers(bool primary, const char *name)
> +static inline int
> +drm_aperture_remove_framebuffers(bool primary, const struct drm_driver *req_driver)
>   {
> -	return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, primary, name);
> +	return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, primary,
> +							    req_driver);
>   }
>   
>   #endif
> 


-- 
With best wishes
Dmitry


From jason-jh.lin at mediatek.com  Thu Aug  5 13:54:54 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Fri, 6 Aug 2021 04:54:54 +0800
Subject: [PATCH v5 5/6] drm/mediatek: add DSC support for mt8195
In-Reply-To: <CAAOTY_-54wi6Ujvynyex30wY7vn_sV_=R5T3CBj77iYCCGQvGg@mail.gmail.com>
References: <20210729170737.21424-1-jason-jh.lin@mediatek.com>
 <20210729170737.21424-6-jason-jh.lin@mediatek.com>
 <CAAOTY_-54wi6Ujvynyex30wY7vn_sV_=R5T3CBj77iYCCGQvGg@mail.gmail.com>
Message-ID: <85d2ecb557a418d5f2154be8a53a239f0ea82ff3.camel@mediatek.com>

Hi CK,

On Sat, 2021-07-31 at 07:11 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?7?30? ?? ??1:07???
> > 
> > Add DSC into mtk_drm_ddp_comp to support for mt8195.
> > 
> > DSC is designed for real-time systems with real-time compression,
> > transmission, decompression and display.
> > The DSC standard is a specification of the algorithms used for
> > compressing and decompressing image display streams, including
> > the specification of the syntax and semantics of the compressed
> > video bit stream.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> > This patch is base on [1]
> > 
> > [1]add mt8195 SoC DRM binding
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597__;!!CTRNKA9wMg0ARbw!yW7OLcmG5NUkhK7gDxpSuiBPXTW3QQQ__H78vj20PuPuz37kA6ixuMCBoUy6Wq1ohY03$
> >  
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 46
> > +++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  2 +
> >  3 files changed, 49 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 75bc00e17fc4..6f4a9b8c9914 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -65,6 +65,12 @@
> >  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
> >  #define DITHER_ADD_RSHIFT_G(x)                 (((x) & 0x7) << 0)
> > 
> > +#define DISP_REG_DSC_CON                       0x0000
> > +#define DSC_EN                                 BIT(0)
> > +#define DSC_DUAL_INOUT                         BIT(2)
> > +#define DSC_BYPASS                             BIT(4)
> > +#define DSC_UFOE_SEL                           BIT(16)
> > +
> >  struct mtk_ddp_comp_dev {
> >         struct clk *clk;
> >         void __iomem *regs;
> > @@ -246,6 +252,35 @@ static void mtk_dither_stop(struct device
> > *dev)
> >         writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
> >  }
> > 
> > +static void mtk_dsc_config(struct device *dev, unsigned int w,
> > +                          unsigned int h, unsigned int vrefresh,
> > +                          unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       /* dsc bypass mode */
> > +       mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg,
> > priv->regs,
> > +                          DISP_REG_DSC_CON, DSC_BYPASS);
> > +       mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, 
> > priv->regs,
> > +                          DISP_REG_DSC_CON, DSC_UFOE_SEL);
> > +       mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv-
> > >cmdq_reg, priv->regs,
> > +                          DISP_REG_DSC_CON, DSC_DUAL_INOUT);
> > +}
> > +
> > +static void mtk_dsc_start(struct device *dev)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       writel_relaxed(DSC_EN, &priv->regs + DISP_REG_DSC_CON);
> > +}
> > +
> > +static void mtk_dsc_stop(struct device *dev)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
> > +}
> > +
> >  static const struct mtk_ddp_comp_funcs ddp_aal = {
> >         .clk_enable = mtk_ddp_clk_enable,
> >         .clk_disable = mtk_ddp_clk_disable,
> > @@ -284,6 +319,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi
> > = {
> >         .stop = mtk_dpi_stop,
> >  };
> > 
> > +static const struct mtk_ddp_comp_funcs ddp_dsc = {
> > +       .clk_enable = mtk_ddp_clk_enable,
> > +       .clk_disable = mtk_ddp_clk_disable,
> > +       .config = mtk_dsc_config,
> > +       .start = mtk_dsc_start,
> > +       .stop = mtk_dsc_stop,
> > +};
> > +
> >  static const struct mtk_ddp_comp_funcs ddp_dsi = {
> >         .start = mtk_dsi_ddp_start,
> >         .stop = mtk_dsi_ddp_stop,
> > @@ -356,6 +399,7 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >         [MTK_DISP_MUTEX] = "mutex",
> >         [MTK_DISP_OD] = "od",
> >         [MTK_DISP_BLS] = "bls",
> > +       [MTK_DISP_DSC] = "dsc",
> 
> Would you please send a patch to make alphabetic order then apply
> this patch?
> 
OK, I'll send that.

> >  };
> > 
> >  struct mtk_ddp_comp_match {
> > @@ -374,6 +418,8 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >         [DDP_COMPONENT_DITHER]  = { MTK_DISP_DITHER,    0,
> > &ddp_dither },
> >         [DDP_COMPONENT_DPI0]    = { MTK_DPI,            0, &ddp_dpi
> > },
> >         [DDP_COMPONENT_DPI1]    = { MTK_DPI,            1, &ddp_dpi
> > },
> > +       [DDP_COMPONENT_DSC0]    = { MTK_DISP_DSC,       0, &ddp_dsc
> > },
> > +       [DDP_COMPONENT_DSC1]    = { MTK_DISP_DSC,       1, &ddp_dsc
> > },
> >         [DDP_COMPONENT_DSI0]    = { MTK_DSI,            0, &ddp_dsi
> > },
> >         [DDP_COMPONENT_DSI1]    = { MTK_DSI,            1, &ddp_dsi
> > },
> >         [DDP_COMPONENT_DSI2]    = { MTK_DSI,            2, &ddp_dsi
> > },
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index bb914d976cf5..661fb620e266 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -34,6 +34,7 @@ enum mtk_ddp_comp_type {
> >         MTK_DISP_MUTEX,
> >         MTK_DISP_OD,
> >         MTK_DISP_BLS,
> > +       MTK_DISP_DSC,
> 
> Ditto.
> 
> >         MTK_DDP_COMP_TYPE_MAX,
> >  };
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index d6f6d1bdad85..0f6bb4bdc58a 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -446,6 +446,8 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >           .data = (void *)MTK_DISP_GAMMA, },
> >         { .compatible = "mediatek,mt8183-disp-dither",
> >           .data = (void *)MTK_DISP_DITHER },
> > +       { .compatible = "mediatek,mt8195-disp-dsc",
> > +         .data = (void *)MTK_DISP_DSC },
> 
> I would like you move this patch before the patch "add mediatek-drm
> of
> vdosys0 support for mt8195" and move this part into that patch.
> 
> Regards,
> Chun-Kuang.
> 
OK, I'll move this part.

Regards,
Jason-JH.Lin

> >         { .compatible = "mediatek,mt8173-disp-ufoe",
> >           .data = (void *)MTK_DISP_UFOE },
> >         { .compatible = "mediatek,mt2701-dsi",
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From jason-jh.lin at mediatek.com  Thu Aug  5 13:52:21 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 04:52:21 +0800
Subject: [PATCH v6 2/7] soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
In-Reply-To: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805205226.24880-3-jason-jh.lin@mediatek.com>

Add mt8195 vdosys0 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is base on [1]

[1] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-2-jason-jh.lin at mediatek.com/
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 96 ++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 11 +++
 include/linux/soc/mediatek/mtk-mmsys.h |  9 +++
 3 files changed, 116 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
new file mode 100644
index 000000000000..9339a786ec5d
--- /dev/null
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
+#define __SOC_MEDIATEK_MT8195_MMSYS_H
+
+#define MT8195_VDO0_OVL_MOUT_EN					0xf14
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
+
+#define MT8195_VDO0_SEL_IN					0xf34
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		(0 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		(1 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		(2 << 0)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		(0 << 4)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		(1 << 4)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		(0 << 5)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		(1 << 5)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		(0 << 8)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		(1 << 8)
+#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		(0 << 9)
+#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		(0 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			(1 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		(2 << 12)
+#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			(0 << 16)
+#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			(1 << 16)
+#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			(0 << 17)
+#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			(1 << 17)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			(0 << 20)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			(1 << 20)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		(0 << 21)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		(1 << 21)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			(0 << 22)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_VPP_MERGE			(1 << 22)
+
+#define MT8195_VDO0_SEL_OUT					0xf38
+#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		(0 << 0)
+#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			(1 << 0)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		(0 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			(1 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		(2 << 1)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			(0 << 4)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			(1 << 4)
+#define MT8195_SOUT_VPP_MERGE_TO_DSI1				(0 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			(1 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			(2 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(3 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			(4 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			(0 << 11)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA0			(1 << 11)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			(0 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		(1 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			(2 << 12)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			(0 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			(1 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(3 << 16)
+
+static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
+	}
+};
+
+#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 080660ef11bf..1fb241750897 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -13,6 +13,7 @@
 #include "mtk-mmsys.h"
 #include "mt8167-mmsys.h"
 #include "mt8183-mmsys.h"
+#include "mt8195-mmsys.h"
 
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.clk_driver = "clk-mt2701-mm",
@@ -52,6 +53,12 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.clk_driver = "clk-mt8195-vdo0",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
@@ -157,6 +164,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8183-mmsys",
 		.data = &mt8183_mmsys_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys0",
+		.data = &mt8195_vdosys0_driver_data,
+	},
 	{ }
 };
 
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 2228bf6133da..01bedfb08094 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -39,6 +39,15 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_UFOE,
 	DDP_COMPONENT_WDMA0,
 	DDP_COMPONENT_WDMA1,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_MERGE1,
+	DDP_COMPONENT_MERGE2,
+	DDP_COMPONENT_MERGE3,
+	DDP_COMPONENT_MERGE4,
+	DDP_COMPONENT_MERGE5,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_DSC1,
+	DDP_COMPONENT_DP_INTF0,
 	DDP_COMPONENT_ID_MAX,
 };
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 13:52:26 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 04:52:26 +0800
Subject: [PATCH v6 7/7] drm/mediatek: add mediatek-drm of vdosys0 support for
 mt8195
In-Reply-To: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805205226.24880-8-jason-jh.lin@mediatek.com>

Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is base on [1]

[1] dt-bindings: mediatek: display: add mt8195 SoC binding
https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-5-jason-jh.lin at mediatek.com/
---
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  6 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 28 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 728aaadfea8c..00e9827acefe 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -355,6 +355,10 @@ static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
 	.fifo_size = 5 * SZ_1K,
 };
 
+static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
+	.fifo_size = 1920,
+};
+
 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt2701-disp-rdma",
 	  .data = &mt2701_rdma_driver_data},
@@ -362,6 +366,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	  .data = &mt8173_rdma_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = &mt8183_rdma_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = &mt8195_rdma_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 5eb9c0a04447..9aebf73144c6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -147,6 +147,19 @@ static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
 	DDP_COMPONENT_DPI0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
+	DDP_COMPONENT_OVL0,
+	DDP_COMPONENT_RDMA0,
+	DDP_COMPONENT_COLOR0,
+	DDP_COMPONENT_CCORR,
+	DDP_COMPONENT_AAL0,
+	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_DP_INTF0,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -186,6 +199,11 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.main_path = mt8195_mtk_ddp_main,
+	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+};
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
@@ -406,10 +424,14 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8183-disp-dither",
 	  .data = (void *)MTK_DISP_DITHER },
+	{ .compatible = "mediatek,mt8195-disp-dsc",
+	  .data = (void *)MTK_DISP_DSC },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
+	{ .compatible = "mediatek,mt8195-disp-merge",
+	  .data = (void *)MTK_DISP_MERGE },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -418,6 +440,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8173-disp-od",
 	  .data = (void *)MTK_DISP_OD },
 	{ .compatible = "mediatek,mt2701-disp-ovl",
@@ -438,6 +462,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8173-disp-ufoe",
 	  .data = (void *)MTK_DISP_UFOE },
 	{ .compatible = "mediatek,mt8173-disp-wdma",
@@ -468,6 +494,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
 	  .data = &mt8173_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8183-mmsys",
 	  .data = &mt8183_mmsys_driver_data},
+	{.compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 13:52:20 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 04:52:20 +0800
Subject: [PATCH v6 1/7] arm64: dts: mt8195: add display node for vdosys0
In-Reply-To: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805205226.24880-2-jason-jh.lin@mediatek.com>

Add display node for vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is based on [1][2][3][4]

[1]arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
[2]arm64: dts: mt8195: add IOMMU and smi nodes
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
[3]arm64: dts: mt8195: add gce node
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210705053429.4380-4-jason-jh.lin at mediatek.com/
[4]add mt8195 SoC DRM binding
https://patchwork.kernel.org/project/linux-mediatek/list/?series=527069
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 112 +++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 04d3e95175fa..4fa47cb2bede 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1155,9 +1155,121 @@
 			#clock-cells = <1>;
 		};
 
+		ovl0: disp_ovl at 1c000000 {
+			compatible = "mediatek,mt8195-disp-ovl",
+				     "mediatek,mt8183-disp-ovl";
+			reg = <0 0x1c000000 0 0x1000>;
+			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_OVL0_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x0000 0x1000>;
+		};
+
+		rdma0: disp_rdma at 1c002000 {
+			compatible = "mediatek,mt8195-disp-rdma";
+			reg = <0 0x1c002000 0 0x1000>;
+			interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_RDMA0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x2000 0x1000>;
+		};
+
+		color0: disp_color at 1c003000 {
+			compatible = "mediatek,mt8195-disp-color",
+				     "mediatek,mt8173-disp-color";
+			reg = <0 0x1c003000 0 0x1000>;
+			interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_COLOR0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x3000 0x1000>;
+		};
+
+		ccorr0: disp_ccorr at 1c004000 {
+			compatible = "mediatek,mt8195-disp-ccorr",
+				     "mediatek,mt8183-disp-ccorr";
+			reg = <0 0x1c004000 0 0x1000>;
+			interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_CCORR0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x4000 0x1000>;
+		};
+
+		aal0: disp_aal at 1c005000 {
+			compatible = "mediatek,mt8195-disp-aal",
+				     "mediatek,mt8173-disp-aal";
+			reg = <0 0x1c005000 0 0x1000>;
+			interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_AAL0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x5000 0x1000>;
+		};
+
+		gamma0: disp_gamma at 1c006000 {
+			compatible = "mediatek,mt8195-disp-gamma",
+				     "mediatek,mt8173-disp-gamma";
+			reg = <0 0x1c006000 0 0x1000>;
+			interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_GAMMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x6000 0x1000>;
+		};
+
+		dither0: disp_dither at 1c007000 {
+			compatible = "mediatek,mt8195-disp-dither",
+				     "mediatek,mt8183-disp-dither";
+			reg = <0 0x1c007000 0 0x1000>;
+			interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_DITHER0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x7000 0x1000>;
+		};
+
+		dsc0: disp_dsc_wrap at 1c009000 {
+			compatible = "mediatek,mt8195-disp-dsc";
+			reg = <0 0x1c009000 0 0x1000>;
+			interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+		};
+
+		merge0: disp_vpp_merge0 at 1c014000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c014000 0 0x1000>;
+			interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_VPP_MERGE0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c01XXXX 0x4000 0x1000>;
+		};
+
+		mutex: disp_mutex0 at 1c016000 {
+			compatible = "mediatek,mt8195-disp-mutex";
+			reg = <0 0x1c016000 0 0x1000>;
+			reg-names = "vdo0_mutex";
+			interrupts = <GIC_SPI 658 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_MUTEX0>;
+			clock-names = "vdo0_mutex";
+			mediatek,gce-events =
+				 <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;
+		};
+
 		vdosys0: syscon at 1c01a000 {
 			compatible = "mediatek,mt8195-vdosys0", "syscon";
 			reg = <0 0x1c01a000 0 0x1000>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			mboxes = <&gce1 0 CMDQ_THR_PRIO_4>;
 			#clock-cells = <1>;
 		};
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 13:52:19 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 04:52:19 +0800
Subject: [PATCH v6 0/7] Add Mediatek Soc DRM (vdosys0) support for mt8195
Message-ID: <20210805205226.24880-1-jason-jh.lin@mediatek.com>

The hardware path of vdosys0 with eDP panel output need to go through
by several modules, such as, OVL, RDMA, COLOR, CCORR, AAL, GAMMA,
DITHER, DSC and MERGE.

Change in v6:
- adjust alphabetic order for mediatek-drm
- move the patch that add mt8195 support for mediatek-drm as the lastest patch
- add MERGE define for const varriable 

Change in v5:
- add power-domain property into vdosys0 and vdosys1 dts node.
- add MT8195 prifix and remove unused VDO1 define in mt8195-mmsys.h

Change in v4:
- extract dt-binding patches to another patch series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597
- squash DSC module into mtk_drm_ddp_comp.c
- add coment and simplify MERGE config function

Change in v3:
- change mmsys and display dt-bindings document from txt to yaml
- add MERGE additional description in display dt-bindings document
- fix mboxes-cells number of vdosys0 node in dts
- drop mutex eof convert define
- remove pm_runtime apis in DSC and MERGE
- change DSC and MERGE enum to alphabetic order

Change in v2:
- add DSC yaml file
- add mt8195 drm driver porting parts in to one patch
- remove useless define, variable, structure member and function
- simplify DSC and MERGE file and switch threre order

jason-jh.lin (7):
  arm64: dts: mt8195: add display node for vdosys0
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
  soc: mediatek: add mtk-mutex support for mt8195 vdosys0
  drm/mediatek: adjust to the alphabetic order for mediatek-drm
  drm/mediatek: add DSC support for mediatek-drm
  drm/mediatek: add MERGE support for mediatek-drm
  drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

 arch/arm64/boot/dts/mediatek/mt8195.dtsi    | 112 +++++++++
 drivers/gpu/drm/mediatek/Makefile           |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 263 ++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c    |   6 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 242 +++++++++++-------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  24 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 108 +++++---
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
 drivers/soc/mediatek/mt8195-mmsys.h         |  96 +++++++
 drivers/soc/mediatek/mtk-mmsys.c            |  11 +
 drivers/soc/mediatek/mtk-mutex.c            |  93 ++++++-
 include/linux/soc/mediatek/mtk-mmsys.h      |   9 +
 13 files changed, 825 insertions(+), 149 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 13:52:25 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 04:52:25 +0800
Subject: [PATCH v6 6/7] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805205226.24880-7-jason-jh.lin@mediatek.com>

Add MERGE engine file:
MERGE module is used to merge two slice-per-line inputs
into one side-by-side output.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is base on [1]

[1] dt-bindings: mediatek: display: add mt8195 SoC binding
https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-5-jason-jh.lin at mediatek.com/
---
 drivers/gpu/drm/mediatek/Makefile           |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 263 ++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   4 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
 6 files changed, 277 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index dc54a7a69005..538e0087a44c 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -3,6 +3,7 @@
 mediatek-drm-y := mtk_disp_ccorr.o \
 		  mtk_disp_color.o \
 		  mtk_disp_gamma.o \
+		  mtk_disp_merge.o \
 		  mtk_disp_ovl.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index cafd9df2d63b..f407cd9d873e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -46,6 +46,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
 void mtk_gamma_start(struct device *dev);
 void mtk_gamma_stop(struct device *dev);
 
+int mtk_merge_clk_enable(struct device *dev);
+void mtk_merge_clk_disable(struct device *dev);
+void mtk_merge_config(struct device *dev, unsigned int width,
+		      unsigned int height, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start(struct device *dev);
+void mtk_merge_stop(struct device *dev);
+
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
 void mtk_ovl_bypass_shadow(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
new file mode 100644
index 000000000000..f3d262792054
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_disp_drv.h"
+
+#define DISP_REG_MERGE_CTRL		0x000
+#define MERGE_EN			1
+#define DISP_REG_MERGE_CFG_0		0x010
+#define DISP_REG_MERGE_CFG_4		0x020
+#define DISP_REG_MERGE_CFG_10		0x038
+/* no swap */
+#define SWAP_MODE			0
+#define FLD_SWAP_MODE			GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_12		0x040
+#define CFG_10_10_1PI_2PO_BUF_MODE	6
+#define CFG_10_10_2PI_2PO_BUF_MODE	8
+#define FLD_CFG_MERGE_MODE		GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_24		0x070
+#define DISP_REG_MERGE_CFG_25		0x074
+#define DISP_REG_MERGE_CFG_36		0x0a0
+#define ULTRA_EN			1
+#define PREULTRA_EN			1
+#define HALT_FOR_DVFS_EN		0
+#define FLD_ULTRA_EN			GENMASK(0, 0)
+#define FLD_PREULTRA_EN			GENMASK(4, 4)
+#define FLD_HALT_FOR_DVFS_EN		GENMASK(8, 8)
+#define DISP_REG_MERGE_CFG_37		0x0a4
+/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
+#define BUFFER_MODE			3
+#define FLD_BUFFER_MODE			GENMASK(1, 0)
+#define DISP_REG_MERGE_CFG_38		0x0a8
+#define FLD_VDE_BLOCK_ULTRA		GENMASK(0, 0)
+#define FLD_VALID_TH_BLOCK_ULTRA	GENMASK(4, 4)
+#define FLD_ULTRA_FIFO_VALID_TH		GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_39		0x0ac
+#define FLD_NVDE_FORCE_PREULTRA		GENMASK(8, 8)
+#define FLD_NVALID_TH_FORCE_PREULTRA	GENMASK(12, 12)
+#define FLD_PREULTRA_FIFO_VALID_TH	GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_40		0x0b0
+/* 6 us, 600M pixel/sec */
+#define ULTRA_TH_LOW			(6 * 600)
+/* 8 us, 600M pixel/sec */
+#define ULTRA_TH_HIGH			(8 * 600)
+#define FLD_ULTRA_TH_LOW		GENMASK(15, 0)
+#define FLD_ULTRA_TH_HIGH		GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_41		0x0b4
+/* 8 us, 600M pixel/sec */
+#define PREULTRA_TH_LOW			(8 * 600)
+/* 9 us, 600M pixel/sec */
+#define PREULTRA_TH_HIGH		(9 * 600)
+#define FLD_PREULTRA_TH_LOW		GENMASK(15, 0)
+#define FLD_PREULTRA_TH_HIGH		GENMASK(31, 16)
+
+struct mtk_disp_merge {
+	void __iomem *regs;
+	struct clk *clk;
+	struct clk *async_clk;
+	struct cmdq_client_reg		cmdq_reg;
+	bool				fifo_en;
+};
+
+void mtk_merge_start(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
+				   struct cmdq_pkt *handle)
+{
+	mtk_ddp_write_mask(handle, ULTRA_EN | PREULTRA_EN << 4 | HALT_FOR_DVFS_EN << 8,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_36,
+			   FLD_ULTRA_EN | FLD_PREULTRA_EN | FLD_HALT_FOR_DVFS_EN);
+
+	mtk_ddp_write_mask(handle, BUFFER_MODE,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_37,
+			   FLD_BUFFER_MODE);
+
+	mtk_ddp_write_mask(handle, 0,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_38,
+			   FLD_VDE_BLOCK_ULTRA | FLD_VALID_TH_BLOCK_ULTRA |
+			   FLD_ULTRA_FIFO_VALID_TH);
+
+	mtk_ddp_write_mask(handle, 0,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_39,
+			   FLD_NVDE_FORCE_PREULTRA | FLD_NVALID_TH_FORCE_PREULTRA |
+			   FLD_PREULTRA_FIFO_VALID_TH);
+
+	mtk_ddp_write_mask(handle, ULTRA_TH_LOW | ULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_40,
+			   FLD_ULTRA_TH_LOW | FLD_ULTRA_TH_HIGH);
+
+	mtk_ddp_write_mask(handle, PREULTRA_TH_LOW | PREULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_41,
+			   FLD_PREULTRA_TH_LOW | FLD_PREULTRA_TH_HIGH);
+}
+
+void mtk_merge_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *handle)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+	unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
+
+	if (!h || !w) {
+		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
+		return;
+	}
+
+	if (priv->fifo_en) {
+		mtk_merge_fifo_setting(priv, handle);
+		mode = CFG_10_10_2PI_2PO_BUF_MODE;
+	}
+
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_0);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_4);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_24);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_25);
+	mtk_ddp_write_mask(handle, SWAP_MODE, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
+	mtk_ddp_write_mask(handle, mode, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_12, FLD_CFG_MERGE_MODE);
+}
+
+int mtk_merge_clk_enable(struct device *dev)
+{
+	int ret = 0;
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		pr_err("merge clk prepare enable failed\n");
+
+	if (priv->async_clk) {
+		ret = clk_prepare_enable(priv->async_clk);
+		if (ret)
+			pr_err("async clk prepare enable failed\n");
+	}
+
+	return ret;
+}
+
+void mtk_merge_clk_disable(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	if (priv->async_clk)
+		clk_disable_unprepare(priv->async_clk);
+
+	clk_disable_unprepare(priv->clk);
+}
+
+static int mtk_disp_merge_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return 0;
+}
+
+static void mtk_disp_merge_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+}
+
+static const struct component_ops mtk_disp_merge_component_ops = {
+	.bind	= mtk_disp_merge_bind,
+	.unbind = mtk_disp_merge_unbind,
+};
+
+static int mtk_disp_merge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct mtk_disp_merge *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap merge\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get merge clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	priv->async_clk = of_clk_get(dev->of_node, 1);
+	if (IS_ERR(priv->async_clk)) {
+		ret = PTR_ERR(priv->async_clk);
+		dev_dbg(dev, "No merge async clock: %d\n", ret);
+		priv->async_clk = NULL;
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+	priv->fifo_en = of_property_read_bool(dev->of_node,
+					      "mediatek,merge-fifo-en");
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_disp_merge_component_ops);
+	if (ret != 0)
+		dev_err(dev, "Failed to add component: %d\n", ret);
+
+	return ret;
+}
+
+static int mtk_disp_merge_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_disp_merge_component_ops);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_disp_merge_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-merge", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
+
+struct platform_driver mtk_disp_merge_driver = {
+	.probe = mtk_disp_merge_probe,
+	.remove = mtk_disp_merge_remove,
+	.driver = {
+		.name = "mediatek-disp-merge",
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_disp_merge_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 560be6bc9d0e..b42a47c06956 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -25,6 +25,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_DITHER,
 	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
+	MTK_DISP_MERGE,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a95dc1006b82..5eb9c0a04447 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -532,13 +532,14 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
-		 * Currently only the CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
+		 * Currently only the CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
 		 * blocks have separate component platform drivers and initialize their own
 		 * DDP component structure. The others are initialized here.
 		 */
 		if (comp_type == MTK_DISP_CCORR ||
 		    comp_type == MTK_DISP_COLOR ||
 		    comp_type == MTK_DISP_GAMMA ||
+		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
@@ -639,6 +640,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ccorr_driver,
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
+	&mtk_disp_merge_driver,
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 637f5669e895..0fa417219a69 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -49,6 +49,7 @@ struct mtk_drm_private {
 extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
+extern struct platform_driver mtk_disp_merge_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 13:52:22 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 04:52:22 +0800
Subject: [PATCH v6 3/7] soc: mediatek: add mtk-mutex support for mt8195 vdosys0
In-Reply-To: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805205226.24880-4-jason-jh.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is base on [1]

[1] dt-bindings: mediatek: display: add mt8195 SoC binding
https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-5-jason-jh.lin at mediatek.com/
---
 drivers/soc/mediatek/mtk-mutex.c | 93 ++++++++++++++++++++++++++++++--
 1 file changed, 90 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2e4bcc300576..cb8bbf7f3fd8 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -17,6 +17,9 @@
 #define MT8183_MUTEX0_MOD0			0x30
 #define MT8183_MUTEX0_SOF0			0x2c
 
+#define MT8195_DISP_MUTEX0_MOD0			0x30
+#define MT8195_DISP_MUTEX0_SOF			0x2c
+
 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
@@ -67,6 +70,36 @@
 #define MT8173_MUTEX_MOD_DISP_PWM1		24
 #define MT8173_MUTEX_MOD_DISP_OD		25
 
+#define MT8195_MUTEX_MOD_DISP_OVL0		0
+#define MT8195_MUTEX_MOD_DISP_WDMA0		1
+#define MT8195_MUTEX_MOD_DISP_RDMA0		2
+#define MT8195_MUTEX_MOD_DISP_COLOR0		3
+#define MT8195_MUTEX_MOD_DISP_CCORR0		4
+#define MT8195_MUTEX_MOD_DISP_AAL0		5
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
+#define MT8195_MUTEX_MOD_DISP_DITHER0		7
+#define MT8195_MUTEX_MOD_DISP_DSI0		8
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
+#define MT8195_MUTEX_MOD_DISP_OVL1		10
+#define MT8195_MUTEX_MOD_DISP_WDMA1		11
+#define MT8195_MUTEX_MOD_DISP_RDMA1		12
+#define MT8195_MUTEX_MOD_DISP_COLOR1		13
+#define MT8195_MUTEX_MOD_DISP_CCORR1		14
+#define MT8195_MUTEX_MOD_DISP_AAL1		15
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
+#define MT8195_MUTEX_MOD_DISP_DITHER1		17
+#define MT8195_MUTEX_MOD_DISP_DSI1		18
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
+#define MT8195_MUTEX_MOD_DISP_PWM0		27
+#define MT8195_MUTEX_MOD_DISP_PWM1		28
+
 #define MT2712_MUTEX_MOD_DISP_PWM2		10
 #define MT2712_MUTEX_MOD_DISP_OVL0		11
 #define MT2712_MUTEX_MOD_DISP_OVL1		12
@@ -101,12 +134,27 @@
 #define MT2712_MUTEX_SOF_DSI3			6
 #define MT8167_MUTEX_SOF_DPI0			2
 #define MT8167_MUTEX_SOF_DPI1			3
+
 #define MT8183_MUTEX_SOF_DSI0			1
 #define MT8183_MUTEX_SOF_DPI0			2
 
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
 
+#define MT8195_MUTEX_SOF_DSI0			1
+#define MT8195_MUTEX_SOF_DSI1			2
+#define MT8195_MUTEX_SOF_DP_INTF0		3
+#define MT8195_MUTEX_SOF_DP_INTF1		4
+#define MT8195_MUTEX_SOF_DPI0			6 /* for HDMI_TX */
+#define MT8195_MUTEX_SOF_DPI1			5 /* for digital video out */
+
+#define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_SOF_DSI0 << 7)
+#define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_SOF_DSI1 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_INTF0 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_INTF1 << 7)
+#define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_SOF_DPI0 << 7)
+#define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_SOF_DPI1 << 7)
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -120,6 +168,9 @@ enum mtk_mutex_sof_id {
 	MUTEX_SOF_DPI1,
 	MUTEX_SOF_DSI2,
 	MUTEX_SOF_DSI3,
+	MUTEX_SOF_DP_INTF0,
+	MUTEX_SOF_DP_INTF1,
+	DDP_MUTEX_SOF_MAX,
 };
 
 struct mtk_mutex_data {
@@ -214,7 +265,22 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
+	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
+	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
+	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
+	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
+	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
+	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
+	[DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
+	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
+	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
+	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
+	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
+};
+
+static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
@@ -224,7 +290,7 @@ static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
 };
 
-static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
@@ -232,12 +298,24 @@ static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 };
 
 /* Add EOF setting so overlay hardware can receive frame done irq */
-static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
 };
 
+static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
+	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
+	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
+	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
+	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
+	[MUTEX_SOF_DP_INTF0] =
+		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
+	[MUTEX_SOF_DP_INTF1] =
+		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -275,6 +353,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.no_clk = true,
 };
 
+static const struct mtk_mutex_data mt8195_mutex_driver_data = {
+	.mutex_mod = mt8195_mutex_mod,
+	.mutex_sof = mt8195_mutex_sof,
+	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
+};
+
 struct mtk_mutex *mtk_mutex_get(struct device *dev)
 {
 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
@@ -507,6 +592,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
 	  .data = &mt8173_mutex_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = &mt8183_mutex_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = &mt8195_mutex_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 13:52:24 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 04:52:24 +0800
Subject: [PATCH v6 5/7] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805205226.24880-6-jason-jh.lin@mediatek.com>

DSC is designed for real-time systems with real-time compression,
transmission, decompression and display.
The DSC standard is a specification of the algorithms used for
compressing and decompressing image display streams, including
the specification of the syntax and semantics of the compressed
video bit stream.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is base on [1]

[1] dt-bindings: mediatek: add mediatek, dsc.yaml for mt8195 SoC binding
https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-4-jason-jh.lin at mediatek.com/
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 62 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 2 files changed, 63 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 328ee19f931e..24c7b004fe4d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -43,6 +43,12 @@
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_DSC_CON			0x0000
+#define DSC_EN					BIT(0)
+#define DSC_DUAL_INOUT				BIT(2)
+#define DSC_BYPASS				BIT(4)
+#define DSC_UFOE_SEL				BIT(16)
+
 #define DISP_REG_OD_EN				0x0000
 #define DISP_REG_OD_CFG				0x0020
 #define OD_RELAYMODE				BIT(0)
@@ -209,6 +215,35 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc,
 			      DISP_DITHERING, cmdq_pkt);
 }
 
+static void mtk_dsc_config(struct device *dev, unsigned int w,
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* dsc bypass mode */
+	mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_BYPASS);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_UFOE_SEL);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_DUAL_INOUT);
+}
+
+static void mtk_dsc_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(DSC_EN, &priv->regs + DISP_REG_DSC_CON);
+}
+
+static void mtk_dsc_stop(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
+}
+
 static void mtk_od_config(struct device *dev, unsigned int w,
 			  unsigned int h, unsigned int vrefresh,
 			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -272,6 +307,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = {
 	.stop = mtk_dpi_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_dsc = {
+	.clk_enable = mtk_ddp_clk_enable,
+	.clk_disable = mtk_ddp_clk_disable,
+	.config = mtk_dsc_config,
+	.start = mtk_dsc_start,
+	.stop = mtk_dsc_stop,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_dsi = {
 	.start = mtk_dsi_ddp_start,
 	.stop = mtk_dsi_ddp_stop,
@@ -286,6 +329,14 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
 	.stop = mtk_gamma_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_merge = {
+	.clk_enable = mtk_merge_clk_enable,
+	.clk_disable = mtk_merge_clk_disable,
+	.start = mtk_merge_start,
+	.stop = mtk_merge_stop,
+	.config = mtk_merge_config,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_od = {
 	.clk_enable = mtk_ddp_clk_enable,
 	.clk_disable = mtk_ddp_clk_disable,
@@ -333,7 +384,9 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_CCORR] = "ccorr",
 	[MTK_DISP_COLOR] = "color",
 	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MERGE] = "merge",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
@@ -362,11 +415,19 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DITHER]	= { MTK_DISP_DITHER,	0, &ddp_dither },
 	[DDP_COMPONENT_DPI0]	= { MTK_DPI,		0, &ddp_dpi },
 	[DDP_COMPONENT_DPI1]	= { MTK_DPI,		1, &ddp_dpi },
+	[DDP_COMPONENT_DSC0]	= { MTK_DISP_DSC,	0, &ddp_dsc },
+	[DDP_COMPONENT_DSC1]	= { MTK_DISP_DSC,	1, &ddp_dsc },
 	[DDP_COMPONENT_DSI0]	= { MTK_DSI,		0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]	= { MTK_DSI,		1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]	= { MTK_DSI,		2, &ddp_dsi },
 	[DDP_COMPONENT_DSI3]	= { MTK_DSI,		3, &ddp_dsi },
 	[DDP_COMPONENT_GAMMA]	= { MTK_DISP_GAMMA,	0, &ddp_gamma },
+	[DDP_COMPONENT_MERGE0]	= { MTK_DISP_MERGE,	0, &ddp_merge },
+	[DDP_COMPONENT_MERGE1]	= { MTK_DISP_MERGE,	1, &ddp_merge },
+	[DDP_COMPONENT_MERGE2]	= { MTK_DISP_MERGE,	2, &ddp_merge },
+	[DDP_COMPONENT_MERGE3]	= { MTK_DISP_MERGE,	3, &ddp_merge },
+	[DDP_COMPONENT_MERGE4]	= { MTK_DISP_MERGE,	4, &ddp_merge },
+	[DDP_COMPONENT_MERGE5]	= { MTK_DISP_MERGE,	5, &ddp_merge },
 	[DDP_COMPONENT_OD0]	= { MTK_DISP_OD,	0, &ddp_od },
 	[DDP_COMPONENT_OD1]	= { MTK_DISP_OD,	1, &ddp_od },
 	[DDP_COMPONENT_OVL0]	= { MTK_DISP_OVL,	0, &ddp_ovl },
@@ -497,6 +558,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
+	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index d317b944df66..560be6bc9d0e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_CCORR,
 	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
+	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 13:52:23 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 6 Aug 2021 04:52:23 +0800
Subject: [PATCH v6 4/7] drm/mediatek: adjust to the alphabetic order for
 mediatek-drm
In-Reply-To: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
Message-ID: <20210805205226.24880-5-jason-jh.lin@mediatek.com>

1. Adjust to the alphabetic order for the define, function, struct
   and array in mediatek-drm driver
2. Remove the unsed define in mtk_drm_ddp_comp.c

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 180 +++++++++-----------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  22 +--
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  76 ++++-----
 3 files changed, 133 insertions(+), 145 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 75bc00e17fc4..328ee19f931e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -20,50 +20,36 @@
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_crtc.h"
 
-#define DISP_OD_EN				0x0000
-#define DISP_OD_INTEN				0x0008
-#define DISP_OD_INTSTA				0x000c
-#define DISP_OD_CFG				0x0020
-#define DISP_OD_SIZE				0x0030
-#define DISP_DITHER_5				0x0114
-#define DISP_DITHER_7				0x011c
-#define DISP_DITHER_15				0x013c
-#define DISP_DITHER_16				0x0140
-
-#define DISP_REG_UFO_START			0x0000
-
-#define DISP_AAL_EN				0x0000
-#define DISP_AAL_SIZE				0x0030
+#define DISP_REG_AAL_EN				0x0000
+#define AAL_EN					BIT(0)
+#define DISP_REG_AAL_SIZE			0x0030
 
-#define DISP_DITHER_EN				0x0000
+#define DISP_REG_DITHER_EN			0x0000
 #define DITHER_EN				BIT(0)
-#define DISP_DITHER_CFG				0x0020
+#define DISP_REG_DITHER_CFG			0x0020
 #define DITHER_RELAY_MODE			BIT(0)
 #define DITHER_ENGINE_EN			BIT(1)
-#define DISP_DITHER_SIZE			0x0030
-
-#define LUT_10BIT_MASK				0x03ff
-
-#define OD_RELAYMODE				BIT(0)
-
-#define UFO_BYPASS				BIT(2)
-
-#define AAL_EN					BIT(0)
-
 #define DISP_DITHERING				BIT(2)
+#define DISP_REG_DITHER_SIZE			0x0030
+#define DISP_REG_DITHER_5			0x0114
+#define DISP_REG_DITHER_7			0x011c
+#define DISP_REG_DITHER_15			0x013c
 #define DITHER_LSB_ERR_SHIFT_R(x)		(((x) & 0x7) << 28)
-#define DITHER_OVFLW_BIT_R(x)			(((x) & 0x7) << 24)
 #define DITHER_ADD_LSHIFT_R(x)			(((x) & 0x7) << 20)
-#define DITHER_ADD_RSHIFT_R(x)			(((x) & 0x7) << 16)
 #define DITHER_NEW_BIT_MODE			BIT(0)
+#define DISP_REG_DITHER_16			0x0140
 #define DITHER_LSB_ERR_SHIFT_B(x)		(((x) & 0x7) << 28)
-#define DITHER_OVFLW_BIT_B(x)			(((x) & 0x7) << 24)
 #define DITHER_ADD_LSHIFT_B(x)			(((x) & 0x7) << 20)
-#define DITHER_ADD_RSHIFT_B(x)			(((x) & 0x7) << 16)
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
-#define DITHER_OVFLW_BIT_G(x)			(((x) & 0x7) << 8)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
-#define DITHER_ADD_RSHIFT_G(x)			(((x) & 0x7) << 0)
+
+#define DISP_REG_OD_EN				0x0000
+#define DISP_REG_OD_CFG				0x0020
+#define OD_RELAYMODE				BIT(0)
+#define DISP_REG_OD_SIZE			0x0030
+
+#define DISP_REG_UFO_START			0x0000
+#define UFO_BYPASS				BIT(2)
 
 struct mtk_ddp_comp_dev {
 	struct clk *clk;
@@ -116,20 +102,6 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 #endif
 }
 
-static int mtk_ddp_clk_enable(struct device *dev)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	return clk_prepare_enable(priv->clk);
-}
-
-static void mtk_ddp_clk_disable(struct device *dev)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	clk_disable_unprepare(priv->clk);
-}
-
 void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 			   unsigned int bpc, unsigned int cfg,
 			   unsigned int dither_en, struct cmdq_pkt *cmdq_pkt)
@@ -139,55 +111,35 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 		return;
 
 	if (bpc >= MTK_MIN_BPC) {
-		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
-		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
+		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_5);
+		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_7);
 		mtk_ddp_write(cmdq_pkt,
 			      DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
 			      DITHER_NEW_BIT_MODE,
-			      cmdq_reg, regs, DISP_DITHER_15);
+			      cmdq_reg, regs, DISP_REG_DITHER_15);
 		mtk_ddp_write(cmdq_pkt,
 			      DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
 			      DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
-			      cmdq_reg, regs, DISP_DITHER_16);
+			      cmdq_reg, regs, DISP_REG_DITHER_16);
 		mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg);
 	}
 }
 
-static void mtk_dither_set(struct device *dev, unsigned int bpc,
-		    unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
-			      DISP_DITHERING, cmdq_pkt);
-}
-
-static void mtk_od_config(struct device *dev, unsigned int w,
-			  unsigned int h, unsigned int vrefresh,
-			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE);
-	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG);
-	mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
-}
-
-static void mtk_od_start(struct device *dev)
+static int mtk_ddp_clk_enable(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(1, priv->regs + DISP_OD_EN);
+	return clk_prepare_enable(priv->clk);
 }
 
-static void mtk_ufoe_start(struct device *dev)
+static void mtk_ddp_clk_disable(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
+	clk_disable_unprepare(priv->clk);
 }
 
 static void mtk_aal_config(struct device *dev, unsigned int w,
@@ -196,7 +148,7 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_AAL_SIZE);
 }
 
 static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
@@ -210,14 +162,14 @@ static void mtk_aal_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(AAL_EN, priv->regs + DISP_AAL_EN);
+	writel(AAL_EN, priv->regs + DISP_REG_AAL_EN);
 }
 
 static void mtk_aal_stop(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, priv->regs + DISP_AAL_EN);
+	writel_relaxed(0x0, priv->regs + DISP_REG_AAL_EN);
 }
 
 static void mtk_dither_config(struct device *dev, unsigned int w,
@@ -226,9 +178,11 @@ static void mtk_dither_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_DITHER_SIZE);
-	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, DISP_DITHER_CFG);
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_DITHER_CFG,
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_DITHER_SIZE);
+	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_DITHER_CFG);
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
 			      DITHER_ENGINE_EN, cmdq_pkt);
 }
 
@@ -236,14 +190,48 @@ static void mtk_dither_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
+	writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
 }
 
 static void mtk_dither_stop(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
+	writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
+}
+
+static void mtk_dither_set(struct device *dev, unsigned int bpc,
+			   unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
+			      DISP_DITHERING, cmdq_pkt);
+}
+
+static void mtk_od_config(struct device *dev, unsigned int w,
+			  unsigned int h, unsigned int vrefresh,
+			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
+	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
+	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
+}
+
+static void mtk_od_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel(1, priv->regs + DISP_REG_OD_EN);
+}
+
+static void mtk_ufoe_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
 }
 
 static const struct mtk_ddp_comp_funcs ddp_aal = {
@@ -340,22 +328,22 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
 };
 
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
+	[MTK_DISP_AAL] = "aal",
+	[MTK_DISP_BLS] = "bls",
+	[MTK_DISP_CCORR] = "ccorr",
+	[MTK_DISP_COLOR] = "color",
+	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
 	[MTK_DISP_OVL_2L] = "ovl-2l",
+	[MTK_DISP_PWM] = "pwm",
 	[MTK_DISP_RDMA] = "rdma",
-	[MTK_DISP_WDMA] = "wdma",
-	[MTK_DISP_COLOR] = "color",
-	[MTK_DISP_CCORR] = "ccorr",
-	[MTK_DISP_AAL] = "aal",
-	[MTK_DISP_GAMMA] = "gamma",
-	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_UFOE] = "ufoe",
-	[MTK_DSI] = "dsi",
+	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
-	[MTK_DISP_PWM] = "pwm",
-	[MTK_DISP_MUTEX] = "mutex",
-	[MTK_DISP_OD] = "od",
-	[MTK_DISP_BLS] = "bls",
+	[MTK_DSI] = "dsi",
 };
 
 struct mtk_ddp_comp_match {
@@ -509,12 +497,12 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
-	    type == MTK_DPI ||
-	    type == MTK_DSI ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
-	    type == MTK_DISP_RDMA)
+	    type == MTK_DISP_RDMA ||
+	    type == MTK_DPI ||
+	    type == MTK_DSI)
 		return 0;
 
 	priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index bb914d976cf5..d317b944df66 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -18,22 +18,22 @@ struct mtk_plane_state;
 struct drm_crtc_state;
 
 enum mtk_ddp_comp_type {
-	MTK_DISP_OVL,
-	MTK_DISP_OVL_2L,
-	MTK_DISP_RDMA,
-	MTK_DISP_WDMA,
-	MTK_DISP_COLOR,
+	MTK_DISP_AAL,
+	MTK_DISP_BLS,
 	MTK_DISP_CCORR,
+	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
-	MTK_DISP_AAL,
 	MTK_DISP_GAMMA,
-	MTK_DISP_UFOE,
-	MTK_DSI,
-	MTK_DPI,
-	MTK_DISP_PWM,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-	MTK_DISP_BLS,
+	MTK_DISP_OVL,
+	MTK_DISP_OVL_2L,
+	MTK_DISP_PWM,
+	MTK_DISP_RDMA,
+	MTK_DISP_UFOE,
+	MTK_DISP_WDMA,
+	MTK_DPI,
+	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b46bdb8985da..a95dc1006b82 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -396,50 +396,20 @@ static const struct component_master_ops mtk_drm_ops = {
 };
 
 static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
-	{ .compatible = "mediatek,mt2701-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8173-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8183-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
-	  .data = (void *)MTK_DISP_OVL_2L },
-	{ .compatible = "mediatek,mt2701-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8173-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8183-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8173-disp-wdma",
-	  .data = (void *)MTK_DISP_WDMA },
+	{ .compatible = "mediatek,mt8173-disp-aal",
+	  .data = (void *)MTK_DISP_AAL},
 	{ .compatible = "mediatek,mt8183-disp-ccorr",
 	  .data = (void *)MTK_DISP_CCORR },
 	{ .compatible = "mediatek,mt2701-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8173-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
-	{ .compatible = "mediatek,mt8173-disp-aal",
-	  .data = (void *)MTK_DISP_AAL},
+	{ .compatible = "mediatek,mt8183-disp-dither",
+	  .data = (void *)MTK_DISP_DITHER },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
-	{ .compatible = "mediatek,mt8183-disp-dither",
-	  .data = (void *)MTK_DISP_DITHER },
-	{ .compatible = "mediatek,mt8173-disp-ufoe",
-	  .data = (void *)MTK_DISP_UFOE },
-	{ .compatible = "mediatek,mt2701-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt8173-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt8183-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt2701-dpi",
-	  .data = (void *)MTK_DPI },
-	{ .compatible = "mediatek,mt8173-dpi",
-	  .data = (void *)MTK_DPI },
-	{ .compatible = "mediatek,mt8183-dpi",
-	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -448,12 +418,42 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8173-disp-od",
+	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt2701-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8173-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8183-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
+	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt2701-disp-pwm",
 	  .data = (void *)MTK_DISP_BLS },
 	{ .compatible = "mediatek,mt8173-disp-pwm",
 	  .data = (void *)MTK_DISP_PWM },
-	{ .compatible = "mediatek,mt8173-disp-od",
-	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt2701-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8173-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8183-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8173-disp-ufoe",
+	  .data = (void *)MTK_DISP_UFOE },
+	{ .compatible = "mediatek,mt8173-disp-wdma",
+	  .data = (void *)MTK_DISP_WDMA },
+	{ .compatible = "mediatek,mt2701-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8173-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8183-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt2701-dsi",
+	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8173-dsi",
+	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8183-dsi",
+	  .data = (void *)MTK_DSI },
 	{ }
 };
 
@@ -542,8 +542,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
-		    comp_type == MTK_DSI ||
-		    comp_type == MTK_DPI) {
+		    comp_type == MTK_DPI ||
+		    comp_type == MTK_DSI) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, compare_of,
-- 
2.18.0

From jason-jh.lin at mediatek.com  Thu Aug  5 14:04:50 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Fri, 6 Aug 2021 05:04:50 +0800
Subject: [PATCH v5 6/6] drm/mediatek: add MERGE support for mt8195
In-Reply-To: <CAAOTY_9QqpLU+aPki1-RPy-CZB766nWnNEAagVpc=Dp7gfqdQw@mail.gmail.com>
References: <20210729170737.21424-1-jason-jh.lin@mediatek.com>
 <20210729170737.21424-7-jason-jh.lin@mediatek.com>
 <CAAOTY_9QqpLU+aPki1-RPy-CZB766nWnNEAagVpc=Dp7gfqdQw@mail.gmail.com>
Message-ID: <2017561ce3256ff4b28e30924cdcf1186858ca19.camel@mediatek.com>

Hi CK,

On Sun, 2021-08-01 at 08:33 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?7?30? ?? ??1:07???
> > 
> > Add MERGE module file:
> > 
> > MERGE module is used to merge two slice-per-line inputs
> > into one side-by-side output.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> > This patch is base on [1]
> > 
> > [1]add mt8195 SoC DRM binding
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597__;!!CTRNKA9wMg0ARbw!zkeg4-APhameNaE5ILtNBNC9h9LCu6aupI26bYErBmwbBg7YGwLZqihxn9hUl4SkJpfD$
> >  
> > ---
> >  drivers/gpu/drm/mediatek/Makefile           |   1 +
> >  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
> >  drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 277
> > ++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  16 ++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   6 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
> >  7 files changed, 309 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > 
> > diff --git a/drivers/gpu/drm/mediatek/Makefile
> > b/drivers/gpu/drm/mediatek/Makefile
> > index dc54a7a69005..538e0087a44c 100644
> > --- a/drivers/gpu/drm/mediatek/Makefile
> > +++ b/drivers/gpu/drm/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >  mediatek-drm-y := mtk_disp_ccorr.o \
> >                   mtk_disp_color.o \
> >                   mtk_disp_gamma.o \
> > +                 mtk_disp_merge.o \
> >                   mtk_disp_ovl.o \
> >                   mtk_disp_rdma.o \
> >                   mtk_drm_crtc.o \
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > index cafd9df2d63b..f407cd9d873e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > @@ -46,6 +46,14 @@ void mtk_gamma_set_common(void __iomem *regs,
> > struct drm_crtc_state *state);
> >  void mtk_gamma_start(struct device *dev);
> >  void mtk_gamma_stop(struct device *dev);
> > 
> > +int mtk_merge_clk_enable(struct device *dev);
> > +void mtk_merge_clk_disable(struct device *dev);
> > +void mtk_merge_config(struct device *dev, unsigned int width,
> > +                     unsigned int height, unsigned int vrefresh,
> > +                     unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> > +void mtk_merge_start(struct device *dev);
> > +void mtk_merge_stop(struct device *dev);
> > +
> >  void mtk_ovl_bgclr_in_on(struct device *dev);
> >  void mtk_ovl_bgclr_in_off(struct device *dev);
> >  void mtk_ovl_bypass_shadow(struct device *dev);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > new file mode 100644
> > index 000000000000..594d76ccd205
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > @@ -0,0 +1,277 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/component.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/soc/mediatek/mtk-cmdq.h>
> > +
> > +#include "mtk_drm_ddp_comp.h"
> > +#include "mtk_drm_drv.h"
> > +#include "mtk_disp_drv.h"
> > +
> > +#define DISP_REG_MERGE_CTRL            0x000
> > +#define FLD_MERGE_EN BIT(0)
> > +#define FLD_MERGE_RST BIT(4)
> > +#define FLD_MERGE_LR_SWAP BIT(8)
> > +#define FLD_MERGE_DCM_DIS BIT(12)
> > +
> > +#define DISP_MERGE_CFG_0               0x010
> > +#define DISP_MERGE_CFG_4               0x020
> > +#define DISP_MERGE_CFG_10              0x038
> > +#define DISP_MERGE_CFG_12              0x040
> > +#define CFG_10_10_1PI_2PO_BUF_MODE     6
> > +#define CFG_10_10_2PI_2PO_BUF_MODE     8
> > +#define DISP_MERGE_CFG_24              0x070
> > +#define DISP_MERGE_CFG_25              0x074
> > +
> > +#define DISP_MERGE_CFG_36              0x0a0
> > +#define DISP_MERGE_CFG_36_FLD_ULTRA_EN GENMASK(0, 0)
> > +#define DISP_MERGE_CFG_36_FLD_PREULTRA_EN GENMASK(4, 4)
> > +#define DISP_MERGE_CFG_36_FLD_HALT_FOR_DVFS_EN GENMASK(8, 8)
> > +#define DISP_MERGE_CFG_37              0x0a4
> > +#define DISP_MERGE_CFG_37_FLD_BUFFER_MODE GENMASK(1, 0)
> > +#define DISP_MERGE_CFG_38              0x0a8
> > +#define DISP_MERGE_CFG_38_FLD_VDE_BLOCK_ULTRA GENMASK(0, 0)
> > +#define DISP_MERGE_CFG_38_FLD_VALID_TH_BLOCK_ULTRA GENMASK(4, 4)
> > +#define DISP_MERGE_CFG_38_FLD_ULTRA_FIFO_VALID_TH GENMASK(31, 16)
> > +#define DISP_MERGE_CFG_39              0x0ac
> > +#define DISP_MERGE_CFG_39_FLD_NVDE_FORCE_PREULTRA GENMASK(8, 8)
> > +#define DISP_MERGE_CFG_39_FLD_NVALID_TH_FORCE_PREULTRA GENMASK(12,
> > 12)
> > +#define DISP_MERGE_CFG_39_FLD_PREULTRA_FIFO_VALID_TH GENMASK(31,
> > 16)
> > +#define DISP_MERGE_CFG_40              0x0b0
> > +#define DISP_MERGE_CFG_40_FLD_ULTRA_TH_LOW GENMASK(15, 0)
> > +#define DISP_MERGE_CFG_40_FLD_ULTRA_TH_HIGH GENMASK(31, 16)
> > +#define DISP_MERGE_CFG_41              0x0b4
> > +#define DISP_MERGE_CFG_41_FLD_PREULTRA_TH_LOW GENMASK(15, 0)
> > +#define DISP_MERGE_CFG_41_FLD_PREULTRA_TH_HIGH GENMASK(31, 16)
> > +
> > +struct mtk_disp_merge {
> > +       void __iomem *regs;
> > +       struct clk *clk;
> > +       struct clk *async_clk;
> > +       struct cmdq_client_reg          cmdq_reg;
> > +       bool                            fifo_en;
> > +};
> > +
> > +void mtk_merge_start(struct device *dev)
> > +{
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +
> > +       mtk_ddp_write(NULL, 0x1, &priv->cmdq_reg, priv->regs,
> > DISP_REG_MERGE_CTRL);
> 
> writel.

I'll fix this.

> 
> > +}
> > +
> > +void mtk_merge_stop(struct device *dev)
> > +{
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +
> > +       mtk_ddp_write(NULL, 0x0, &priv->cmdq_reg, priv->regs,
> > DISP_REG_MERGE_CTRL);
> 
> Ditto.
> 
I'll fix this.

> > +}
> > +
> > +static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
> > +                                  struct cmdq_pkt *handle)
> > +{
> > +       unsigned int ultra_en = 1;
> > +       unsigned int preultra_en = 1;
> > +       unsigned int halt_for_dvfs_en = 0;
> 
> All these are constant, so use #define instead of variable.
> 
I'll fix this.

> > +       /*
> > +        * 0 : Off
> > +        * 1 : SRAM 0
> > +        * 2 : SRAM 1
> > +        * 3 : SRAM 0 + SRAM 1
> > +        */
> > +       unsigned int buffer_mode = 3;
> 
> Ditto.
> 
I'll fix this.

> > +       /* 6 us, 600M pixel/sec */
> > +       unsigned int ultra_th_low = 6 * 600;
> > +       /* 8 us, 600M pixel/sec */
> > +       unsigned int ultra_th_high = 8 * 600;
> > +       /* 8 us, 600M pixel/sec */
> > +       unsigned int preultra_th_low = 8 * 600;
> > +       /* 9 us, 600M pixel/sec */
> > +       unsigned int preultra_th_high = 9 * 600;
> 
> Why 6us ~ 9us?. Why 600M pixel/sec?
> 
6us~9us is the experirence value from designer.
The maximum frequency value of mmsys clk is 594MHz, so designer take
600M pixel/sec to evaluate the ultra and preulta of buffer fifo
approximately.

> > +
> > +       mtk_ddp_write_mask(handle, ultra_en << 0 | preultra_en << 4
> > | halt_for_dvfs_en << 8,
> 
> Remove '<< 0'
> 
I'll remove them.

> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_MERGE_CFG_36,
> > +                          DISP_MERGE_CFG_36_FLD_ULTRA_EN |
> > DISP_MERGE_CFG_36_FLD_PREULTRA_EN |
> > +                          DISP_MERGE_CFG_36_FLD_HALT_FOR_DVFS_EN);
> > +
> > +       mtk_ddp_write_mask(handle, buffer_mode << 0,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_MERGE_CFG_37,
> > +                          DISP_MERGE_CFG_37_FLD_BUFFER_MODE);
> > +
> > +       mtk_ddp_write_mask(handle, 0,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_MERGE_CFG_38,
> > +                          DISP_MERGE_CFG_38_FLD_VDE_BLOCK_ULTRA |
> > +                          DISP_MERGE_CFG_38_FLD_VALID_TH_BLOCK_ULT
> > RA |
> > +                          DISP_MERGE_CFG_38_FLD_ULTRA_FIFO_VALID_T
> > H);
> > +
> > +       mtk_ddp_write_mask(handle, 0,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_MERGE_CFG_39,
> > +                          DISP_MERGE_CFG_39_FLD_NVDE_FORCE_PREULTR
> > A |
> > +                          DISP_MERGE_CFG_39_FLD_NVALID_TH_FORCE_PR
> > EULTRA |
> > +                          DISP_MERGE_CFG_39_FLD_PREULTRA_FIFO_VALI
> > D_TH);
> > +
> > +       mtk_ddp_write_mask(handle, ultra_th_low << 0 |
> > ultra_th_high << 16,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_MERGE_CFG_40,
> > +                          DISP_MERGE_CFG_40_FLD_ULTRA_TH_LOW |
> > +                          DISP_MERGE_CFG_40_FLD_ULTRA_TH_HIGH);
> > +
> > +       mtk_ddp_write_mask(handle, preultra_th_low << 0 |
> > preultra_th_high << 16,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_MERGE_CFG_41,
> > +                          DISP_MERGE_CFG_41_FLD_PREULTRA_TH_LOW |
> > +                          DISP_MERGE_CFG_41_FLD_PREULTRA_TH_HIGH);
> > +}
> > +
> > +void mtk_merge_config(struct device *dev, unsigned int w,
> > +                     unsigned int h, unsigned int vrefresh,
> > +                     unsigned int bpc, struct cmdq_pkt *handle)
> > +{
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +       unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
> > +
> > +       if (!h || !w) {
> > +               pr_err("%s: input width(%d) or height(%d) is
> > invalid\n",
> 
> dev_err.
> 
> > +                      __func__, w, h);
> 
> one line.
> 
I'll fix this.

> > +               return;
> > +       }
> > +
> > +       if (priv->fifo_en) {
> > +               mtk_merge_fifo_setting(priv, handle);
> > +               mode = CFG_10_10_2PI_2PO_BUF_MODE;
> > +       }
> > +
> > +       mtk_ddp_write(handle, (h << 16 | w), &priv->cmdq_reg, priv-
> > >regs,
> 
> Remove parentheses of (h << 16 | w).

I'll remove this.

> 
> > +                     DISP_MERGE_CFG_0);
> > +       mtk_ddp_write(handle, (h << 16 | w), &priv->cmdq_reg, priv-
> > >regs,
> > +                     DISP_MERGE_CFG_4);
> > +       mtk_ddp_write(handle, (h << 16 | w), &priv->cmdq_reg, priv-
> > >regs,
> > +                     DISP_MERGE_CFG_24);
> > +       mtk_ddp_write(handle, (h << 16 | w), &priv->cmdq_reg, priv-
> > >regs,
> > +                     DISP_MERGE_CFG_25);
> > +       /* no swap */
> > +       mtk_ddp_write_mask(handle, 0, &priv->cmdq_reg, priv->regs,
> > +                          DISP_MERGE_CFG_10, 0x1f);
> 
> Symbolize 0x1f.

I'll fix this.

> 
> > +       mtk_ddp_write_mask(handle, mode, &priv->cmdq_reg, priv-
> > >regs,
> > +                          DISP_MERGE_CFG_12, 0x1f);
> 
> Ditto.

I'll fix this.

> 
> > +}
> > +
> > +int mtk_merge_clk_enable(struct device *dev)
> > +{
> > +       int ret = 0;
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +
> > +       ret = clk_prepare_enable(priv->clk);
> > +       if (ret)
> > +               pr_err("merge clk prepare enable failed\n");
> > +
> > +       if (priv->async_clk) {
> > +               ret = clk_prepare_enable(priv->async_clk);
> > +               if (ret)
> > +                       pr_err("async clk prepare enable
> > failed\n");
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +void mtk_merge_clk_disable(struct device *dev)
> > +{
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +
> > +       if (priv->async_clk)
> > +               clk_disable_unprepare(priv->async_clk);
> > +
> > +       clk_disable_unprepare(priv->clk);
> > +}
> > +
> > +static int mtk_disp_merge_bind(struct device *dev, struct device
> > *master,
> > +                              void *data)
> > +{
> > +       return 0;
> > +}
> > +
> > +static void mtk_disp_merge_unbind(struct device *dev, struct
> > device *master,
> > +                                 void *data)
> > +{
> > +}
> > +
> > +static const struct component_ops mtk_disp_merge_component_ops = {
> > +       .bind   = mtk_disp_merge_bind,
> > +       .unbind = mtk_disp_merge_unbind,
> > +};
> > +
> > +static int mtk_disp_merge_probe(struct platform_device *pdev)
> > +{
> > +       struct device *dev = &pdev->dev;
> > +       struct resource *res;
> > +       struct mtk_disp_merge *priv;
> > +       int ret;
> > +
> > +       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +       if (!priv)
> > +               return -ENOMEM;
> > +
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       priv->regs = devm_ioremap_resource(dev, res);
> > +       if (IS_ERR(priv->regs)) {
> > +               dev_err(dev, "failed to ioremap merge\n");
> > +               return PTR_ERR(priv->regs);
> > +       }
> > +
> > +       priv->clk = devm_clk_get(dev, NULL);
> > +       if (IS_ERR(priv->clk)) {
> > +               dev_err(dev, "failed to get merge clk\n");
> > +               return PTR_ERR(priv->clk);
> > +       }
> > +
> > +       priv->async_clk = of_clk_get(dev->of_node, 1);
> > +       if (IS_ERR(priv->async_clk)) {
> > +               ret = PTR_ERR(priv->async_clk);
> > +               dev_dbg(dev, "No merge async clock: %d\n", ret);
> > +               priv->async_clk = NULL;
> > +       }
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +       ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
> > +       if (ret)
> > +               dev_dbg(dev, "get mediatek,gce-client-reg
> > fail!\n");
> > +#endif
> > +
> > +       priv->fifo_en = of_property_read_bool(dev->of_node,
> > +                                             "mediatek,merge-fifo-
> > en");
> > +
> > +       platform_set_drvdata(pdev, priv);
> > +
> > +       ret = component_add(dev, &mtk_disp_merge_component_ops);
> > +       if (ret != 0)
> > +               dev_err(dev, "Failed to add component: %d\n", ret);
> > +
> > +       return ret;
> > +}
> > +
> > +static int mtk_disp_merge_remove(struct platform_device *pdev)
> > +{
> > +       component_del(&pdev->dev, &mtk_disp_merge_component_ops);
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id mtk_disp_merge_driver_dt_match[]
> > = {
> > +       { .compatible = "mediatek,mt8195-disp-merge", },
> > +       {},
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
> > +
> > +struct platform_driver mtk_disp_merge_driver = {
> > +       .probe = mtk_disp_merge_probe,
> > +       .remove = mtk_disp_merge_remove,
> > +       .driver = {
> > +               .name = "mediatek-disp-merge",
> > +               .owner = THIS_MODULE,
> > +               .of_match_table = mtk_disp_merge_driver_dt_match,
> > +       },
> > +};
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 6f4a9b8c9914..a037b564052e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -376,6 +376,14 @@ static const struct mtk_ddp_comp_funcs
> > ddp_rdma = {
> >         .layer_config = mtk_rdma_layer_config,
> >  };
> > 
> > +static const struct mtk_ddp_comp_funcs ddp_merge = {
> > +       .clk_enable = mtk_merge_clk_enable,
> > +       .clk_disable = mtk_merge_clk_disable,
> > +       .start = mtk_merge_start,
> > +       .stop = mtk_merge_stop,
> > +       .config = mtk_merge_config,
> > +};
> > +
> >  static const struct mtk_ddp_comp_funcs ddp_ufoe = {
> >         .clk_enable = mtk_ddp_clk_enable,
> >         .clk_disable = mtk_ddp_clk_disable,
> > @@ -400,6 +408,7 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >         [MTK_DISP_OD] = "od",
> >         [MTK_DISP_BLS] = "bls",
> >         [MTK_DISP_DSC] = "dsc",
> > +       [MTK_DISP_MERGE] = "merge",
> >  };
> > 
> >  struct mtk_ddp_comp_match {
> > @@ -425,6 +434,12 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >         [DDP_COMPONENT_DSI2]    = { MTK_DSI,            2, &ddp_dsi
> > },
> >         [DDP_COMPONENT_DSI3]    = { MTK_DSI,            3, &ddp_dsi
> > },
> >         [DDP_COMPONENT_GAMMA]   = { MTK_DISP_GAMMA,     0,
> > &ddp_gamma },
> > +       [DDP_COMPONENT_MERGE0]  = { MTK_DISP_MERGE,     0,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE1]  = { MTK_DISP_MERGE,     1,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE2]  = { MTK_DISP_MERGE,     2,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE3]  = { MTK_DISP_MERGE,     3,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE4]  = { MTK_DISP_MERGE,     4,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE5]  = { MTK_DISP_MERGE,     5,
> > &ddp_merge },
> >         [DDP_COMPONENT_OD0]     = { MTK_DISP_OD,        0, &ddp_od
> > },
> >         [DDP_COMPONENT_OD1]     = { MTK_DISP_OD,        1, &ddp_od
> > },
> >         [DDP_COMPONENT_OVL0]    = { MTK_DISP_OVL,       0, &ddp_ovl
> > },
> > @@ -557,6 +572,7 @@ int mtk_ddp_comp_init(struct device_node *node,
> > struct mtk_ddp_comp *comp,
> >             type == MTK_DISP_GAMMA ||
> >             type == MTK_DPI ||
> >             type == MTK_DSI ||
> > +           type == MTK_DISP_MERGE ||
> >             type == MTK_DISP_OVL ||
> >             type == MTK_DISP_OVL_2L ||
> >             type == MTK_DISP_PWM ||
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index 661fb620e266..0afd78c0bc92 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -35,6 +35,7 @@ enum mtk_ddp_comp_type {
> >         MTK_DISP_OD,
> >         MTK_DISP_BLS,
> >         MTK_DISP_DSC,
> > +       MTK_DISP_MERGE,
> >         MTK_DDP_COMP_TYPE_MAX,
> >  };
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index 0f6bb4bdc58a..53e0de3f17d7 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -448,6 +448,8 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >           .data = (void *)MTK_DISP_DITHER },
> >         { .compatible = "mediatek,mt8195-disp-dsc",
> >           .data = (void *)MTK_DISP_DSC },
> > +       { .compatible = "mediatek,mt8195-disp-merge",
> > +         .data = (void *)MTK_DISP_MERGE },
> 
> Move this patch before the patch "add mediatek-drm of vdosys0 support
> for mt8195" and move this part into that patch.
> 
> Regards,
> Chun-Kuang.
> 
I'll move this part.

Regards,
Jason-JH.Lin

> >         { .compatible = "mediatek,mt8173-disp-ufoe",
> >           .data = (void *)MTK_DISP_UFOE },
> >         { .compatible = "mediatek,mt2701-dsi",
> > @@ -558,13 +560,14 @@ static int mtk_drm_probe(struct
> > platform_device *pdev)
> >                 private->comp_node[comp_id] = of_node_get(node);
> > 
> >                 /*
> > -                * Currently only the CCORR, COLOR, GAMMA, OVL,
> > RDMA, DSI, and DPI
> > +                * Currently only the CCORR, COLOR, GAMMA, MERGE,
> > OVL, RDMA, DSI, and DPI
> >                  * blocks have separate component platform drivers
> > and initialize their own
> >                  * DDP component structure. The others are
> > initialized here.
> >                  */
> >                 if (comp_type == MTK_DISP_CCORR ||
> >                     comp_type == MTK_DISP_COLOR ||
> >                     comp_type == MTK_DISP_GAMMA ||
> > +                   comp_type == MTK_DISP_MERGE ||
> >                     comp_type == MTK_DISP_OVL ||
> >                     comp_type == MTK_DISP_OVL_2L ||
> >                     comp_type == MTK_DISP_RDMA ||
> > @@ -665,6 +668,7 @@ static struct platform_driver * const
> > mtk_drm_drivers[] = {
> >         &mtk_disp_ccorr_driver,
> >         &mtk_disp_color_driver,
> >         &mtk_disp_gamma_driver,
> > +       &mtk_disp_merge_driver,
> >         &mtk_disp_ovl_driver,
> >         &mtk_disp_rdma_driver,
> >         &mtk_dpi_driver,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > index 637f5669e895..0fa417219a69 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > @@ -49,6 +49,7 @@ struct mtk_drm_private {
> >  extern struct platform_driver mtk_disp_ccorr_driver;
> >  extern struct platform_driver mtk_disp_color_driver;
> >  extern struct platform_driver mtk_disp_gamma_driver;
> > +extern struct platform_driver mtk_disp_merge_driver;
> >  extern struct platform_driver mtk_disp_ovl_driver;
> >  extern struct platform_driver mtk_disp_rdma_driver;
> >  extern struct platform_driver mtk_dpi_driver;
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From jeremy.linton at arm.com  Thu Aug  5 14:11:57 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu,  5 Aug 2021 16:11:57 -0500
Subject: [PATCH 0/3] CM4 ACPI PCIe quirk
Message-ID: <20210805211200.491275-1-jeremy.linton@arm.com>

The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
standard because its PCIe config space isn't ECAM compliant and is
split into two parts. One part for the root port registers and a
moveable window which points at a given device's 4K config space.
Thus it doesn't have a MCFG (and really any MCFG provided would be
nonsense anyway). As linux doesn't support the PCIe SMCCC standard
we key off a linux specific host bridge _DSD to add custom ECAM
ops and cfgres. The cfg op selects between those two regions, as
well as disallowing problematic accesses, particularly if the link
is down because there isn't an attached device.

Jeremy Linton (3):
  PCI: brcmstb: Break register definitions into separate header
  PCI: brcmstb: Add ACPI config space quirk
  PCI/ACPI: Add new quirk detection, enable bcm2711

 drivers/acpi/pci_mcfg.c                    |  14 ++
 drivers/pci/controller/Makefile            |   1 +
 drivers/pci/controller/pcie-brcmstb-acpi.c |  77 +++++++++
 drivers/pci/controller/pcie-brcmstb.c      | 179 +-------------------
 drivers/pci/controller/pcie-brcmstb.h      | 182 +++++++++++++++++++++
 include/linux/pci-ecam.h                   |   1 +
 6 files changed, 276 insertions(+), 178 deletions(-)
 create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
 create mode 100644 drivers/pci/controller/pcie-brcmstb.h

-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug  5 14:12:00 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu,  5 Aug 2021 16:12:00 -0500
Subject: [PATCH 3/3] PCI/ACPI: Add new quirk detection, enable bcm2711
In-Reply-To: <20210805211200.491275-1-jeremy.linton@arm.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
Message-ID: <20210805211200.491275-4-jeremy.linton@arm.com>

Now that we have a bcm2711 quirk, we need to be able to
detect it when the MCFG is missing. Use a namespace
property as an alternative to the MCFG OEM.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/acpi/pci_mcfg.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
index 53cab975f612..7d77fc72c2a4 100644
--- a/drivers/acpi/pci_mcfg.c
+++ b/drivers/acpi/pci_mcfg.c
@@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
 	ALTRA_ECAM_QUIRK(1, 13),
 	ALTRA_ECAM_QUIRK(1, 14),
 	ALTRA_ECAM_QUIRK(1, 15),
+
+	{ "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
+	  DEFINE_RES_MEM(0xFD500000, 0xA000) },
 };
 
 static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
@@ -198,8 +201,19 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
 	u16 segment = root->segment;
 	struct resource *bus_range = &root->secondary;
 	struct mcfg_fixup *f;
+	const char *soc;
 	int i;
 
+	/*
+	 * This could be a machine with a PCI/SMC conduit,
+	 * which means it doens't have MCFG. Get the machineid from
+	 * the namespace definition instead.
+	 */
+	if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
+					 "linux,pcie-quirk", &soc)) {
+		memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
+	}
+
 	for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
 		if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
 			if (f->cfgres.start)
-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug  5 14:11:58 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu,  5 Aug 2021 16:11:58 -0500
Subject: [PATCH 1/3] PCI: brcmstb: Break register definitions into separate
 header
In-Reply-To: <20210805211200.491275-1-jeremy.linton@arm.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
Message-ID: <20210805211200.491275-2-jeremy.linton@arm.com>

We are about to create a standalone ACPI quirk module for the
bcmstb controller. Lets move the register definitions into a separate
file so they can be shared between the APCI quirk and the normal
host bridge driver.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 179 +------------------------
 drivers/pci/controller/pcie-brcmstb.h | 182 ++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 178 deletions(-)
 create mode 100644 drivers/pci/controller/pcie-brcmstb.h

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 08bc788d9422..916de435ced9 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -31,192 +31,15 @@
 #include <linux/types.h>
 
 #include "../pci.h"
-
-/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
-#define BRCM_PCIE_CAP_REGS				0x00ac
-
-/* Broadcom STB PCIe Register Offsets */
-#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1				0x0188
-#define  PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK	0xc
-#define  PCIE_RC_CFG_VENDOR_SPCIFIC_REG1_LITTLE_ENDIAN			0x0
-
-#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
-#define  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK	0xffffff
-
-#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY			0x04dc
-#define  PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK	0xc00
-
-#define PCIE_RC_DL_MDIO_ADDR				0x1100
-#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
-#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
-
-#define PCIE_MISC_MISC_CTRL				0x4008
-#define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK		0x1000
-#define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK	0x2000
-#define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK	0x300000
-
-#define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK		0xf8000000
-#define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK		0x07c00000
-#define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK		0x0000001f
-#define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
-#define PCIE_MEM_WIN0_LO(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
-#define PCIE_MEM_WIN0_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 8)
-
-#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
-#define  PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK		0x1f
-
-#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
-#define  PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK		0x1f
-#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
-
-#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
-#define  PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK		0x1f
-
-#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
-#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
-
-#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
-#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_32		0xffe06540
-#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_8		0xfff86540
-
-#define PCIE_MISC_PCIE_CTRL				0x4064
-#define  PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK	0x1
-#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK		0x4
-
-#define PCIE_MISC_PCIE_STATUS				0x4068
-#define  PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK		0x80
-#define  PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK	0x20
-#define  PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK	0x10
-#define  PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK	0x40
-
-#define PCIE_MISC_REVISION				0x406c
-#define  BRCM_PCIE_HW_REV_33				0x0303
-#define  BRCM_PCIE_HW_REV_3_20				0x0320
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT		0x4070
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK	0xfff00000
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK	0xfff0
-#define PCIE_MEM_WIN0_BASE_LIMIT(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI			0x4080
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK	0xff
-#define PCIE_MEM_WIN0_BASE_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI			0x4084
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK	0xff
-#define PCIE_MEM_WIN0_LIMIT_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
-
-#define PCIE_MISC_HARD_PCIE_HARD_DEBUG					0x4204
-#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
-#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
-
-
-#define PCIE_INTR2_CPU_BASE		0x4300
-#define PCIE_MSI_INTR2_BASE		0x4500
-/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
-#define  MSI_INT_STATUS			0x0
-#define  MSI_INT_CLR			0x8
-#define  MSI_INT_MASK_SET		0x10
-#define  MSI_INT_MASK_CLR		0x14
-
-#define PCIE_EXT_CFG_DATA				0x8000
-#define PCIE_EXT_CFG_INDEX				0x9000
-
-#define  PCIE_RGR1_SW_INIT_1_PERST_MASK			0x1
-#define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT		0x0
-
-#define RGR1_SW_INIT_1_INIT_GENERIC_MASK		0x2
-#define RGR1_SW_INIT_1_INIT_GENERIC_SHIFT		0x1
-#define RGR1_SW_INIT_1_INIT_7278_MASK			0x1
-#define RGR1_SW_INIT_1_INIT_7278_SHIFT			0x0
-
-/* PCIe parameters */
-#define BRCM_NUM_PCIE_OUT_WINS		0x4
-#define BRCM_INT_PCI_MSI_NR		32
-#define BRCM_INT_PCI_MSI_LEGACY_NR	8
-#define BRCM_INT_PCI_MSI_SHIFT		0
-
-/* MSI target adresses */
-#define BRCM_MSI_TARGET_ADDR_LT_4GB	0x0fffffffcULL
-#define BRCM_MSI_TARGET_ADDR_GT_4GB	0xffffffffcULL
-
-/* MDIO registers */
-#define MDIO_PORT0			0x0
-#define MDIO_DATA_MASK			0x7fffffff
-#define MDIO_PORT_MASK			0xf0000
-#define MDIO_REGAD_MASK			0xffff
-#define MDIO_CMD_MASK			0xfff00000
-#define MDIO_CMD_READ			0x1
-#define MDIO_CMD_WRITE			0x0
-#define MDIO_DATA_DONE_MASK		0x80000000
-#define MDIO_RD_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 1 : 0)
-#define MDIO_WT_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 0 : 1)
-#define SSC_REGS_ADDR			0x1100
-#define SET_ADDR_OFFSET			0x1f
-#define SSC_CNTL_OFFSET			0x2
-#define SSC_CNTL_OVRD_EN_MASK		0x8000
-#define SSC_CNTL_OVRD_VAL_MASK		0x4000
-#define SSC_STATUS_OFFSET		0x1
-#define SSC_STATUS_SSC_MASK		0x400
-#define SSC_STATUS_PLL_LOCK_MASK	0x800
-#define PCIE_BRCM_MAX_MEMC		3
-
-#define IDX_ADDR(pcie)			(pcie->reg_offsets[EXT_CFG_INDEX])
-#define DATA_ADDR(pcie)			(pcie->reg_offsets[EXT_CFG_DATA])
-#define PCIE_RGR1_SW_INIT_1(pcie)	(pcie->reg_offsets[RGR1_SW_INIT_1])
-
-/* Rescal registers */
-#define PCIE_DVT_PMU_PCIE_PHY_CTRL				0xc700
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS			0x3
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK		0x4
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT	0x2
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK		0x2
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT		0x1
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK		0x1
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT		0x0
+#include "pcie-brcmstb.h"
 
 /* Forward declarations */
-struct brcm_pcie;
 static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val);
 
-enum {
-	RGR1_SW_INIT_1,
-	EXT_CFG_INDEX,
-	EXT_CFG_DATA,
-};
-
-enum {
-	RGR1_SW_INIT_1_INIT_MASK,
-	RGR1_SW_INIT_1_INIT_SHIFT,
-};
-
-enum pcie_type {
-	GENERIC,
-	BCM4908,
-	BCM7278,
-	BCM2711,
-};
-
-struct pcie_cfg_data {
-	const int *offsets;
-	const enum pcie_type type;
-	void (*perst_set)(struct brcm_pcie *pcie, u32 val);
-	void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
-};
-
 static const int pcie_offsets[] = {
 	[RGR1_SW_INIT_1] = 0x9210,
 	[EXT_CFG_INDEX]  = 0x9000,
diff --git a/drivers/pci/controller/pcie-brcmstb.h b/drivers/pci/controller/pcie-brcmstb.h
new file mode 100644
index 000000000000..b732a0ec56a0
--- /dev/null
+++ b/drivers/pci/controller/pcie-brcmstb.h
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (C) 2009 - 2021 Broadcom */
+
+/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
+#define BRCM_PCIE_CAP_REGS				0x00ac
+
+/* Broadcom STB PCIe Register Offsets */
+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1				0x0188
+#define  PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK	0xc
+#define  PCIE_RC_CFG_VENDOR_SPCIFIC_REG1_LITTLE_ENDIAN			0x0
+
+#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
+#define  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK	0xffffff
+
+#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY			0x04dc
+#define  PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK	0xc00
+
+#define PCIE_RC_DL_MDIO_ADDR				0x1100
+#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
+#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
+
+#define PCIE_MISC_MISC_CTRL				0x4008
+#define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK		0x1000
+#define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK	0x2000
+#define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK	0x300000
+
+#define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK		0xf8000000
+#define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK		0x07c00000
+#define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK		0x0000001f
+#define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
+#define PCIE_MEM_WIN0_LO(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
+#define PCIE_MEM_WIN0_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 8)
+
+#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
+#define  PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK		0x1f
+
+#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
+#define  PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK		0x1f
+#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
+
+#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
+#define  PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK		0x1f
+
+#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
+#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
+
+#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
+#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_32		0xffe06540
+#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_8		0xfff86540
+
+#define PCIE_MISC_PCIE_CTRL				0x4064
+#define  PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK	0x1
+#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK		0x4
+
+#define PCIE_MISC_PCIE_STATUS				0x4068
+#define  PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK		0x80
+#define  PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK	0x20
+#define  PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK	0x10
+#define  PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK	0x40
+
+#define PCIE_MISC_REVISION				0x406c
+#define  BRCM_PCIE_HW_REV_33				0x0303
+#define  BRCM_PCIE_HW_REV_3_20				0x0320
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT		0x4070
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK	0xfff00000
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK	0xfff0
+#define PCIE_MEM_WIN0_BASE_LIMIT(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI			0x4080
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK	0xff
+#define PCIE_MEM_WIN0_BASE_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI			0x4084
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK	0xff
+#define PCIE_MEM_WIN0_LIMIT_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
+
+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG					0x4204
+#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
+#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
+
+
+#define PCIE_INTR2_CPU_BASE		0x4300
+#define PCIE_MSI_INTR2_BASE		0x4500
+/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
+#define  MSI_INT_STATUS			0x0
+#define  MSI_INT_CLR			0x8
+#define  MSI_INT_MASK_SET		0x10
+#define  MSI_INT_MASK_CLR		0x14
+
+#define PCIE_EXT_CFG_DATA				0x8000
+#define PCIE_EXT_CFG_INDEX				0x9000
+
+#define  PCIE_RGR1_SW_INIT_1_PERST_MASK			0x1
+#define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT		0x0
+
+#define RGR1_SW_INIT_1_INIT_GENERIC_MASK		0x2
+#define RGR1_SW_INIT_1_INIT_GENERIC_SHIFT		0x1
+#define RGR1_SW_INIT_1_INIT_7278_MASK			0x1
+#define RGR1_SW_INIT_1_INIT_7278_SHIFT			0x0
+
+/* PCIe parameters */
+#define BRCM_NUM_PCIE_OUT_WINS		0x4
+#define BRCM_INT_PCI_MSI_NR		32
+#define BRCM_INT_PCI_MSI_LEGACY_NR	8
+#define BRCM_INT_PCI_MSI_SHIFT		0
+
+/* MSI target addresses */
+#define BRCM_MSI_TARGET_ADDR_LT_4GB	0x0fffffffcULL
+#define BRCM_MSI_TARGET_ADDR_GT_4GB	0xffffffffcULL
+
+/* MDIO registers */
+#define MDIO_PORT0			0x0
+#define MDIO_DATA_MASK			0x7fffffff
+#define MDIO_PORT_MASK			0xf0000
+#define MDIO_REGAD_MASK			0xffff
+#define MDIO_CMD_MASK			0xfff00000
+#define MDIO_CMD_READ			0x1
+#define MDIO_CMD_WRITE			0x0
+#define MDIO_DATA_DONE_MASK		0x80000000
+#define MDIO_RD_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 1 : 0)
+#define MDIO_WT_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 0 : 1)
+#define SSC_REGS_ADDR			0x1100
+#define SET_ADDR_OFFSET			0x1f
+#define SSC_CNTL_OFFSET			0x2
+#define SSC_CNTL_OVRD_EN_MASK		0x8000
+#define SSC_CNTL_OVRD_VAL_MASK		0x4000
+#define SSC_STATUS_OFFSET		0x1
+#define SSC_STATUS_SSC_MASK		0x400
+#define SSC_STATUS_PLL_LOCK_MASK	0x800
+#define PCIE_BRCM_MAX_MEMC		3
+
+#define IDX_ADDR(pcie)			(pcie->reg_offsets[EXT_CFG_INDEX])
+#define DATA_ADDR(pcie)			(pcie->reg_offsets[EXT_CFG_DATA])
+#define PCIE_RGR1_SW_INIT_1(pcie)	(pcie->reg_offsets[RGR1_SW_INIT_1])
+
+/* Rescal registers */
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL				0xc700
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS			0x3
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK		0x4
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT	0x2
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK		0x2
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT		0x1
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK		0x1
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT		0x0
+
+/* Forward declarations */
+struct brcm_pcie;
+
+enum {
+	RGR1_SW_INIT_1,
+	EXT_CFG_INDEX,
+	EXT_CFG_DATA,
+};
+
+enum {
+	RGR1_SW_INIT_1_INIT_MASK,
+	RGR1_SW_INIT_1_INIT_SHIFT,
+};
+
+enum pcie_type {
+	GENERIC,
+	BCM4908,
+	BCM7278,
+	BCM2711,
+};
+
+struct pcie_cfg_data {
+	const int *offsets;
+	const enum pcie_type type;
+	void (*perst_set)(struct brcm_pcie *pcie, u32 val);
+	void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
+};
-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug  5 14:11:59 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu,  5 Aug 2021 16:11:59 -0500
Subject: [PATCH 2/3] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210805211200.491275-1-jeremy.linton@arm.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
Message-ID: <20210805211200.491275-3-jeremy.linton@arm.com>

The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
standard because its PCIe config space isn't ECAM compliant and is
split into two parts. One part for the root port registers and a
moveable window which points at a given device's 4K config space.
Thus it doesn't have a MCFG (and really any MCFG provided would be
nonsense anyway). As Linux doesn't support the PCIe SMCCC standard
we key off a Linux specific host bridge _DSD to add custom ECAM
ops and cfgres. The cfg op selects between those two regions, as
well as disallowing problematic accesses, particularly if the link
is down because there isn't an attached device.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/pci/controller/Makefile            |  1 +
 drivers/pci/controller/pcie-brcmstb-acpi.c | 77 ++++++++++++++++++++++
 include/linux/pci-ecam.h                   |  1 +
 3 files changed, 79 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c

diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index aaf30b3dcc14..65aa6fd3ed89 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
 obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
 obj-$(CONFIG_ARM64) += pci-thunder-pem.o
 obj-$(CONFIG_ARM64) += pci-xgene.o
+obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
 endif
 endif
diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
new file mode 100644
index 000000000000..76944876155f
--- /dev/null
+++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ACPI quirks for Brcm2711 PCIe host controller
+ * As used on the Raspberry Pi Compute Module 4
+ *
+ * Copyright (C) 2021 Arm Ltd.
+ */
+
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/pci-acpi.h>
+#include <linux/pci-ecam.h>
+#include "../pci.h"
+#include "pcie-brcmstb.h"
+
+static int brcm_acpi_init(struct pci_config_window *cfg)
+{
+	/*
+	 * This platform doesn't technically have anything that could be called
+	 * ECAM. Its config region has root port specific registers between
+	 * standard PCIe defined config registers. Thus the region setup by the
+	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
+	 * but the footprint isn't a nice power of 2 (40k). For purposes of
+	 * mapping the config region we are just going to squash the standard
+	 * and nonstandard registers together rather than mapping them
+	 * separately. This code simply honors the quirk provided base+size
+	 * instead.
+	 */
+	iounmap(cfg->win);
+	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
+	if (!cfg->win)
+		goto err_exit;
+
+	/* MSI is nonstandard as well */
+	pci_no_msi();
+
+	return 0;
+err_exit:
+	dev_err(cfg->parent, "PCI: Failed to remap config\n");
+	return -ENOMEM;
+}
+
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus, unsigned int devfn,
+					int where)
+{
+	struct pci_config_window *cfg = bus->sysdata;
+	void __iomem *base = cfg->win;
+	int idx;
+	u32 up;
+
+	/* Accesses to the RC go right to the RC registers if slot==0 */
+	if (pci_is_root_bus(bus))
+		return PCI_SLOT(devfn) ? NULL : base + where;
+
+	/* Assure link up before sending request */
+	up = readl(base + PCIE_MISC_PCIE_STATUS);
+	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+		return NULL;
+
+	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+		return NULL;
+
+	/* For devices, write to the config space index register */
+	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
+	writel(idx, base + PCIE_EXT_CFG_INDEX);
+	return base + PCIE_EXT_CFG_DATA + where;
+}
+
+const struct pci_ecam_ops bcm2711_pcie_ops = {
+	.init		= brcm_acpi_init,
+	.bus_shift	= 1,
+	.pci_ops	= {
+		.map_bus	= brcm_pcie_map_conf2,
+		.read		= pci_generic_config_read,
+		.write		= pci_generic_config_write,
+	}
+};
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index adea5a4771cf..a5de0285bb7f 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
 extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
 extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
 extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
+extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
 #endif
 
 #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
-- 
2.31.1



From iwona.winiarska at intel.com  Thu Aug  5 14:42:04 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Thu, 5 Aug 2021 21:42:04 +0000
Subject: [PATCH 13/14] docs: hwmon: Document PECI drivers
In-Reply-To: <4e840768-0315-6241-e988-9a3165a31a86@roeck-us.net>
References: <20210712220447.957418-1-iwona.winiarska@intel.com>
 <20210712220447.957418-14-iwona.winiarska@intel.com>
 <20210727225808.GU8018@packtop>
 <ea5621698508a800cea59b5533f8845b9f0befc6.camel@intel.com>
 <20210804175203.GY8018@packtop>
 <4e840768-0315-6241-e988-9a3165a31a86@roeck-us.net>
Message-ID: <6891496eabcc6f9cacec4fea505fb757ea9c11fc.camel@intel.com>

On Wed, 2021-08-04 at 11:05 -0700, Guenter Roeck wrote:
> On 8/4/21 10:52 AM, Zev Weiss wrote:
> > On Mon, Aug 02, 2021 at 06:37:30AM CDT, Winiarska, Iwona wrote:
> > > On Tue, 2021-07-27 at 22:58 +0000, Zev Weiss wrote:
> > > > On Mon, Jul 12, 2021 at 05:04:46PM CDT, Iwona Winiarska wrote:
> > > > > From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > > > 
> > > > > Add documentation for peci-cputemp driver that provides DTS thermal
> > > > > readings for CPU packages and CPU cores and peci-dimmtemp driver that
> > > > > provides DTS thermal readings for DIMMs.
> > > > > 
> > > > > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > > > Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > > > > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > > > > Reviewed-by: Pierre-Louis Bossart
> > > > > <pierre-louis.bossart at linux.intel.com>
> > > > > ---
> > > > > Documentation/hwmon/index.rst???????? |? 2 +
> > > > > Documentation/hwmon/peci-cputemp.rst? | 93 +++++++++++++++++++++++++++
> > > > > Documentation/hwmon/peci-dimmtemp.rst | 58 +++++++++++++++++
> > > > > MAINTAINERS?????????????????????????? |? 2 +
> > > > > 4 files changed, 155 insertions(+)
> > > > > create mode 100644 Documentation/hwmon/peci-cputemp.rst
> > > > > create mode 100644 Documentation/hwmon/peci-dimmtemp.rst
> > > > > 
> > > > > diff --git a/Documentation/hwmon/index.rst
> > > > > b/Documentation/hwmon/index.rst
> > > > > index bc01601ea81a..cc76b5b3f791 100644
> > > > > --- a/Documentation/hwmon/index.rst
> > > > > +++ b/Documentation/hwmon/index.rst
> > > > > @@ -154,6 +154,8 @@ Hardware Monitoring Kernel Drivers
> > > > > ??? pcf8591
> > > > > ??? pim4328
> > > > > ??? pm6764tr
> > > > > +?? peci-cputemp
> > > > > +?? peci-dimmtemp
> > > > > ??? pmbus
> > > > > ??? powr1220
> > > > > ??? pxe1610
> > > > > diff --git a/Documentation/hwmon/peci-cputemp.rst
> > > > > b/Documentation/hwmon/peci-cputemp.rst
> > > > > new file mode 100644
> > > > > index 000000000000..d3a218ba810a
> > > > > --- /dev/null
> > > > > +++ b/Documentation/hwmon/peci-cputemp.rst
> > > > > @@ -0,0 +1,93 @@
> > > > > +.. SPDX-License-Identifier: GPL-2.0-only
> > > > > +
> > > > > +Kernel driver peci-cputemp
> > > > > +==========================
> > > > > +
> > > > > +Supported chips:
> > > > > +???????One of Intel server CPUs listed below which is connected to a
> > > > > PECI
> > > > > bus.
> > > > > +???????????????* Intel Xeon E5/E7 v3 server processors
> > > > > +???????????????????????Intel Xeon E5-14xx v3 family
> > > > > +???????????????????????Intel Xeon E5-24xx v3 family
> > > > > +???????????????????????Intel Xeon E5-16xx v3 family
> > > > > +???????????????????????Intel Xeon E5-26xx v3 family
> > > > > +???????????????????????Intel Xeon E5-46xx v3 family
> > > > > +???????????????????????Intel Xeon E7-48xx v3 family
> > > > > +???????????????????????Intel Xeon E7-88xx v3 family
> > > > > +???????????????* Intel Xeon E5/E7 v4 server processors
> > > > > +???????????????????????Intel Xeon E5-16xx v4 family
> > > > > +???????????????????????Intel Xeon E5-26xx v4 family
> > > > > +???????????????????????Intel Xeon E5-46xx v4 family
> > > > > +???????????????????????Intel Xeon E7-48xx v4 family
> > > > > +???????????????????????Intel Xeon E7-88xx v4 family
> > > > > +???????????????* Intel Xeon Scalable server processors
> > > > > +???????????????????????Intel Xeon D family
> > > > > +???????????????????????Intel Xeon Bronze family
> > > > > +???????????????????????Intel Xeon Silver family
> > > > > +???????????????????????Intel Xeon Gold family
> > > > > +???????????????????????Intel Xeon Platinum family
> > > > > +
> > > > > +???????Datasheet: Available from
> > > > > http://www.intel.com/design/literature.htm
> > > > > +
> > > > > +Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > > > +
> > > > > +Description
> > > > > +-----------
> > > > > +
> > > > > +This driver implements a generic PECI hwmon feature which provides
> > > > > Digital
> > > > > +Thermal Sensor (DTS) thermal readings of the CPU package and CPU
> > > > > cores that
> > > > > are
> > > > > +accessible via the processor PECI interface.
> > > > > +
> > > > > +All temperature values are given in millidegree Celsius and will be
> > > > > measurable
> > > > > +only when the target CPU is powered on.
> > > > > +
> > > > > +Sysfs interface
> > > > > +-------------------
> > > > > +
> > > > > +=======================
> > > > > =======================================================
> > > > > +temp1_label????????????"Die"
> > > > > +temp1_input????????????Provides current die temperature of the CPU
> > > > > package.
> > > > > +temp1_max??????????????Provides thermal control temperature of the
> > > > > CPU
> > > > > package
> > > > > +???????????????????????which is also known as Tcontrol.
> > > > > +temp1_crit?????????????Provides shutdown temperature of the CPU
> > > > > package
> > > > > which
> > > > > +???????????????????????is also known as the maximum processor
> > > > > junction
> > > > > +???????????????????????temperature, Tjmax or Tprochot.
> > > > > +temp1_crit_hyst????????????????Provides the hysteresis value from
> > > > > Tcontrol
> > > > > to Tjmax of
> > > > > +???????????????????????the CPU package.
> > > > > +
> > > > > +temp2_label????????????"DTS"
> > > > > +temp2_input????????????Provides current DTS temperature of the CPU
> > > > > package.
> > > > 
> > > > Would this be a good place to note the slightly counter-intuitive nature
> > > > of DTS readings?? i.e. add something along the lines of "The DTS sensor
> > > > produces a delta relative to Tjmax, so negative values are normal and
> > > > values approaching zero are hot."? (In my experience people who aren't
> > > > already familiar with it tend to think something's wrong when a CPU
> > > > temperature reading shows -50C.)
> > > 
> > > I believe that what you're referring to is a result of "GetTemp", and
> > > we're
> > > using it to calculate "Die" sensor values (temp1).
> > > The sensor value is absolute - we don't expose "raw" thermal sensor value
> > > (delta) anywhere.
> > > 
> > > DTS sensor is exposing temperature value scaled to fit DTS 2.0 thermal
> > > profile:
> > > https://www.intel.com/content/www/us/en/processors/xeon/scalable/xeon-scalable-thermal-guide.html
> > > (section 5.2.3.2)
> > > 
> > > Similar to "Die" sensor - it's also exposed in absolute form.
> > > 
> > > I'll try to change description to avoid confusion.
> > > 
> > 
> > When I tested the patch series by applying it to my OpenBMC kernel, the
> > temp2_input sysfs file produced negative numbers (as has been the case
> > with previous iterations of the PECI patchset).? Is that expected?? From
> > what Guenter has said it sounds like that's going to need to change so
> > that the temperature readings are all in "normal" millidegrees C
> > (that is, relative to the freezing point of water).
> > 
> 
> Correct, the temperature is expected to be reported in millidegrees C
> per hwmon ABI. Everything else is unacceptable. That makes me wonder what
> "raw" and "absolute" means. Negative numbers suggest that, whatever is
> reported today, it is not millidegrees C.

Let's say we have two values: "base" and "delta". Both are in milidegrees C.
"absolute" means that the sensor value exposed to userspace is calculated as:
base - delta (or base + delta, depending on sensor).
"relative" would mean that we expose "delta" to userspace as sensor value.

For peci-cputemp (and dimmtemp) we're exposing sensors in "absolute" form.

I contacted Zev and we found that the platform he uses has a different format
for the "raw" value ("delta" in the example above) of this particular sensor
(S8.8 instead of S10.6), which means that we're subtracting significantly larger
number than we should, resulting in sensor going into negative.

On the platform I'm using for development purpose, sampling Die and DTS values
returned:
Die 26344
DTS 26329

The platform that Zev used is currently not supported by peci-cpu, however, I
went through the specs, and it looks like some of the older supported platforms
are also using S8.8.
I'll fix this in v3.

Thanks
-Iwona

> 
> Guenter


From iwona.winiarska at intel.com  Thu Aug  5 14:48:31 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Thu, 5 Aug 2021 21:48:31 +0000
Subject: [PATCH v2 13/15] hwmon: peci: Add dimmtemp driver
In-Reply-To: <ff8f8b20-33af-08a0-6036-03429bf69730@roeck-us.net>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-14-iwona.winiarska@intel.com>
 <20210803153937.GA337938@roeck-us.net>
 <a576f7075625a476c613b5feb2c4c7033d6c0375.camel@intel.com>
 <ff8f8b20-33af-08a0-6036-03429bf69730@roeck-us.net>
Message-ID: <941c59624b65c727f828b2b30a8b64c3067ff7c9.camel@intel.com>

On Wed, 2021-08-04 at 10:33 -0700, Guenter Roeck wrote:
> On 8/4/21 3:46 AM, Winiarska, Iwona wrote:
> > On Tue, 2021-08-03 at 08:39 -0700, Guenter Roeck wrote:
> > > On Tue, Aug 03, 2021 at 01:31:32PM +0200, Iwona Winiarska wrote:
> > > > Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that
> > > > are accessible via the processor PECI interface.
> > > > 
> > > > The main use case for the driver (and PECI interface) is out-of-band
> > > > management, where we're able to obtain thermal readings from an external
> > > > entity connected with PECI, e.g. BMC on server platforms.
> > > > 
> > > > Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > > > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> > > > ---
> > > > Note that the timeout was completely removed - we're going to probe
> > > > for detected DIMMs every 5 seconds until we reach "stable" state of
> > > > either getting correct DIMM data or getting all -EINVAL (which
> > > > suggest that the CPU doesn't have any DIMMs).
> > > > 
> > > > ??drivers/hwmon/peci/Kconfig??? |? 13 +
> > > > ??drivers/hwmon/peci/Makefile?? |?? 2 +
> > > > ??drivers/hwmon/peci/dimmtemp.c | 614 ++++++++++++++++++++++++++++++++++
> > > > ??3 files changed, 629 insertions(+)
> > > > ??create mode 100644 drivers/hwmon/peci/dimmtemp.c
> > > > 
> > > > diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
> > > > index e10eed68d70a..9d32a57badfe 100644
> > > > --- a/drivers/hwmon/peci/Kconfig
> > > > +++ b/drivers/hwmon/peci/Kconfig
> > > > @@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP
> > > > ?????????? This driver can also be built as a module. If so, the module
> > > > ?????????? will be called peci-cputemp.
> > > > ? 
> > > > +config SENSORS_PECI_DIMMTEMP
> > > > +???????tristate "PECI DIMM temperature monitoring client"
> > > > +???????depends on PECI
> > > > +???????select SENSORS_PECI
> > > > +???????select PECI_CPU
> > > > +???????help
> > > > +???????? If you say yes here you get support for the generic Intel PECI
> > > > hwmon
> > > > +???????? driver which provides Temperature Sensor on DIMM readings that
> > > > are
> > > > +???????? accessible via the processor PECI interface.
> > > > +
> > > > +???????? This driver can also be built as a module. If so, the module
> > > > +???????? will be called peci-dimmtemp.
> > > > +
> > > > ??config SENSORS_PECI
> > > > ?????????tristate
> > > > diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
> > > > index e8a0ada5ab1f..191cfa0227f3 100644
> > > > --- a/drivers/hwmon/peci/Makefile
> > > > +++ b/drivers/hwmon/peci/Makefile
> > > > @@ -1,5 +1,7 @@
> > > > ??# SPDX-License-Identifier: GPL-2.0-only
> > > > ? 
> > > > ??peci-cputemp-y := cputemp.o
> > > > +peci-dimmtemp-y := dimmtemp.o
> > > > ? 
> > > > ??obj-$(CONFIG_SENSORS_PECI_CPUTEMP)?????+= peci-cputemp.o
> > > > +obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)????+= peci-dimmtemp.o
> > > > diff --git a/drivers/hwmon/peci/dimmtemp.c
> > > > b/drivers/hwmon/peci/dimmtemp.c
> > > > new file mode 100644
> > > > index 000000000000..6264c29bb6c0
> > > > --- /dev/null
> > > > +++ b/drivers/hwmon/peci/dimmtemp.c
> > > > @@ -0,0 +1,614 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > +// Copyright (c) 2018-2021 Intel Corporation
> > > > +
> > > > +#include <linux/auxiliary_bus.h>
> > > > +#include <linux/bitfield.h>
> > > > +#include <linux/bitops.h>
> > > > +#include <linux/hwmon.h>
> > > > +#include <linux/jiffies.h>
> > > > +#include <linux/module.h>
> > > > +#include <linux/peci.h>
> > > > +#include <linux/peci-cpu.h>
> > > > +#include <linux/units.h>
> > > > +#include <linux/workqueue.h>
> > > > +#include <linux/x86/intel-family.h>
> > > > +
> > > > +#include "common.h"
> > > > +
> > > > +#define DIMM_MASK_CHECK_DELAY_JIFFIES??msecs_to_jiffies(5000)
> > > > +
> > > > +/* Max number of channel ranks and DIMM index per channel */
> > > > +#define CHAN_RANK_MAX_ON_HSX???8
> > > > +#define DIMM_IDX_MAX_ON_HSX????3
> > > > +#define CHAN_RANK_MAX_ON_BDX???4
> > > > +#define DIMM_IDX_MAX_ON_BDX????3
> > > > +#define CHAN_RANK_MAX_ON_BDXD??2
> > > > +#define DIMM_IDX_MAX_ON_BDXD???2
> > > > +#define CHAN_RANK_MAX_ON_SKX???6
> > > > +#define DIMM_IDX_MAX_ON_SKX????2
> > > > +#define CHAN_RANK_MAX_ON_ICX???8
> > > > +#define DIMM_IDX_MAX_ON_ICX????2
> > > > +#define CHAN_RANK_MAX_ON_ICXD??4
> > > > +#define DIMM_IDX_MAX_ON_ICXD???2
> > > > +
> > > > +#define CHAN_RANK_MAX??????????CHAN_RANK_MAX_ON_HSX
> > > > +#define DIMM_IDX_MAX???????????DIMM_IDX_MAX_ON_HSX
> > > > +#define DIMM_NUMS_MAX??????????(CHAN_RANK_MAX * DIMM_IDX_MAX)
> > > > +
> > > > +#define CPU_SEG_MASK???????????GENMASK(23, 16)
> > > > +#define GET_CPU_SEG(x)?????????(((x) & CPU_SEG_MASK) >> 16)
> > > > +#define CPU_BUS_MASK???????????GENMASK(7, 0)
> > > > +#define GET_CPU_BUS(x)?????????((x) & CPU_BUS_MASK)
> > > > +
> > > > +#define DIMM_TEMP_MAX??????????GENMASK(15, 8)
> > > > +#define DIMM_TEMP_CRIT?????????GENMASK(23, 16)
> > > > +#define GET_TEMP_MAX(x)????????????????(((x) & DIMM_TEMP_MAX) >> 8)
> > > > +#define GET_TEMP_CRIT(x)???????(((x) & DIMM_TEMP_CRIT) >> 16)
> > > > +
> > > > +struct peci_dimmtemp;
> > > > +
> > > > +struct dimm_info {
> > > > +???????int chan_rank_max;
> > > > +???????int dimm_idx_max;
> > > > +???????u8 min_peci_revision;
> > > > +???????int (*read_thresholds)(struct peci_dimmtemp *priv, int
> > > > dimm_order,
> > > > +????????????????????????????? int chan_rank, u32 *data);
> > > > +};
> > > > +
> > > > +struct peci_dimm_thresholds {
> > > > +???????long temp_max;
> > > > +???????long temp_crit;
> > > > +???????struct peci_sensor_state state;
> > > > +};
> > > > +
> > > > +enum peci_dimm_threshold_type {
> > > > +???????temp_max_type,
> > > > +???????temp_crit_type,
> > > > +};
> > > > +
> > > > +struct peci_dimmtemp {
> > > > +???????struct peci_device *peci_dev;
> > > > +???????struct device *dev;
> > > > +???????const char *name;
> > > > +???????const struct dimm_info *gen_info;
> > > > +???????struct delayed_work detect_work;
> > > > +???????struct {
> > > > +???????????????struct peci_sensor_data temp;
> > > > +???????????????struct peci_dimm_thresholds thresholds;
> > > > +???????} dimm[DIMM_NUMS_MAX];
> > > > +???????char **dimmtemp_label;
> > > > +???????DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX);
> > > > +};
> > > > +
> > > > +static u8 __dimm_temp(u32 reg, int dimm_order)
> > > > +{
> > > > +???????return (reg >> (dimm_order * 8)) & 0xff;
> > > > +}
> > > > +
> > > > +static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long
> > > > *val)
> > > > +{
> > > > +???????int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
> > > > +???????int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
> > > > +???????u32 data;
> > > > +???????int ret;
> > > 
> > > ?????????int ret = 0;
> > > 
> > > > +
> > > > +???????mutex_lock(&priv->dimm[dimm_no].temp.state.lock);
> > > > +???????if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state))
> > > > +???????????????goto skip_update;
> > > > +
> > > > +???????ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP,
> > > > chan_rank, &data);
> > > > +???????if (ret) {
> > > > +???????????????mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
> > > > +???????????????return ret;
> > > > +???????}
> > > 
> > > ?????????if (ret)
> > > ?????????????????goto unlock;
> > > 
> > > > +
> > > > +???????priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) *
> > > > MILLIDEGREE_PER_DEGREE;
> > > > +
> > > > +???????peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state);
> > > > +
> > > > +skip_update:
> > > > +???????*val = priv->dimm[dimm_no].temp.value;
> > > 
> > > unlock:
> > > > +???????mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
> > > > +???????return 0;
> > > 
> > > ?????????return ret;
> > 
> > Ack.
> > 
> > > 
> > > > +}
> > > > +
> > > > +static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
> > > > +{
> > > > +???????int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
> > > > +???????int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
> > > > +???????u32 data;
> > > > +???????int ret;
> > > > +
> > > > +???????if (!peci_sensor_need_update(&priv-
> > > > >dimm[dimm_no].thresholds.state))
> > > > +???????????????return 0;
> > > > +
> > > > +???????ret = priv->gen_info->read_thresholds(priv, dimm_order,
> > > > chan_rank,
> > > > &data);
> > > > +???????if (ret == -ENODATA) /* Use default or previous value */
> > > > +???????????????return 0;
> > > > +???????if (ret)
> > > > +???????????????return ret;
> > > > +
> > > > +???????priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) *
> > > > MILLIDEGREE_PER_DEGREE;
> > > > +???????priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) *
> > > > MILLIDEGREE_PER_DEGREE;
> > > > +
> > > > +???????peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state);
> > > > +
> > > > +???????return 0;
> > > > +}
> > > > +
> > > > +static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum
> > > > peci_dimm_threshold_type type,
> > > > +????????????????????????????? int dimm_no, long *val)
> > > > +{
> > > > +???????int ret;
> > > > +
> > > > +???????mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock);
> > > > +???????ret = update_thresholds(priv, dimm_no);
> > > > +???????if (ret)
> > > > +???????????????goto unlock;
> > > > +
> > > > +???????switch (type) {
> > > > +???????case temp_max_type:
> > > > +???????????????*val = priv->dimm[dimm_no].thresholds.temp_max;
> > > > +???????????????break;
> > > > +???????case temp_crit_type:
> > > > +???????????????*val = priv->dimm[dimm_no].thresholds.temp_crit;
> > > > +???????????????break;
> > > > +???????default:
> > > > +???????????????ret = -EOPNOTSUPP;
> > > > +???????????????break;
> > > > +???????}
> > > > +unlock:
> > > > +???????mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock);
> > > > +
> > > > +???????return ret;
> > > > +}
> > > > +
> > > > +static int dimmtemp_read_string(struct device *dev,
> > > > +???????????????????????????????enum hwmon_sensor_types type,
> > > > +???????????????????????????????u32 attr, int channel, const char **str)
> > > > +{
> > > > +???????struct peci_dimmtemp *priv = dev_get_drvdata(dev);
> > > > +
> > > > +???????if (attr != hwmon_temp_label)
> > > > +???????????????return -EOPNOTSUPP;
> > > > +
> > > > +???????*str = (const char *)priv->dimmtemp_label[channel];
> > > > +
> > > > +???????return 0;
> > > > +}
> > > > +
> > > > +static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types
> > > > type,
> > > > +??????????????????????? u32 attr, int channel, long *val)
> > > > +{
> > > > +???????struct peci_dimmtemp *priv = dev_get_drvdata(dev);
> > > > +
> > > > +???????switch (attr) {
> > > > +???????case hwmon_temp_input:
> > > > +???????????????return get_dimm_temp(priv, channel, val);
> > > > +???????case hwmon_temp_max:
> > > > +???????????????return get_dimm_thresholds(priv, temp_max_type, channel,
> > > > val);
> > > > +???????case hwmon_temp_crit:
> > > > +???????????????return get_dimm_thresholds(priv, temp_crit_type,
> > > > channel,
> > > > val);
> > > > +???????default:
> > > > +???????????????break;
> > > > +???????}
> > > > +
> > > > +???????return -EOPNOTSUPP;
> > > > +}
> > > > +
> > > > +static umode_t dimmtemp_is_visible(const void *data, enum
> > > > hwmon_sensor_types type,
> > > > +????????????????????????????????? u32 attr, int channel)
> > > > +{
> > > > +???????const struct peci_dimmtemp *priv = data;
> > > > +
> > > > +???????if (test_bit(channel, priv->dimm_mask))
> > > > +???????????????return 0444;
> > > > +
> > > > +???????return 0;
> > > > +}
> > > > +
> > > > +static const struct hwmon_ops peci_dimmtemp_ops = {
> > > > +???????.is_visible = dimmtemp_is_visible,
> > > > +???????.read_string = dimmtemp_read_string,
> > > > +???????.read = dimmtemp_read,
> > > > +};
> > > > +
> > > > +static int check_populated_dimms(struct peci_dimmtemp *priv)
> > > > +{
> > > > +???????int chan_rank_max = priv->gen_info->chan_rank_max;
> > > > +???????int dimm_idx_max = priv->gen_info->dimm_idx_max;
> > > > +???????u32 chan_rank_empty = 0;
> > > > +???????u64 dimm_mask = 0;
> > > > +???????int chan_rank, dimm_idx, ret;
> > > > +???????u32 pcs;
> > > > +
> > > > +???????BUILD_BUG_ON(CHAN_RANK_MAX > 32);
> > > > +???????BUILD_BUG_ON(DIMM_NUMS_MAX > 64);
> > > 
> > > I don't immediately see the value of those build bugs. What happens if
> > > CHAN_RANK_MAX > 32 or DIMM_NUMS_MAX > 64 ? Where do those limits come
> > > from ?
> > 
> > Supported HW doesn't come near the limit for now - it's just an "artificial"
> > limit imposed by variables we're using (u64 for dimm_mask and u32 for
> > chan_rank_empty).
> > 
> 
> Please use a value derived from the size of those variables for the check
> to clarify and explain the constraints.

Sure, I'll use BITS_PER_TYPE.

Thanks
-Iwona

> 
> Thanks,
> Guenter


From saravanak at google.com  Thu Aug  5 14:51:52 2021
From: saravanak at google.com (Saravana Kannan)
Date: Thu, 5 Aug 2021 14:51:52 -0700
Subject: [PATCH] clk: rk3308: make ddrphy4x clock critical
In-Reply-To: <16392318.geO5KgaWL5@diego>
References: <BYAPR20MB24886765F888A9705CBEB70789E39@BYAPR20MB2488.namprd20.prod.outlook.com>
 <162758560739.714452.5782743329332725952@swboyd.mtv.corp.google.com>
 <CAGETcx8YYrkCV0UObtOqHUnS29Q-raC54KUh14wqyBDMJ4e46g@mail.gmail.com>
 <16392318.geO5KgaWL5@diego>
Message-ID: <CAGETcx-H1U3YPq+Uh4PuKygTut3n0V4Y_YNSdr4JoJexA+KrtA@mail.gmail.com>

On Mon, Aug 2, 2021 at 12:26 PM Heiko St?bner <heiko at sntech.de> wrote:
>
> Hi Saravana,
>
> Am Montag, 2. August 2021, 20:24:56 CEST schrieb Saravana Kannan:
> > On Thu, Jul 29, 2021 at 12:06 PM Stephen Boyd <sboyd at kernel.org> wrote:
> > >
> > > Quoting Heiko St?bner (2021-07-28 02:53:54)
> > > > Am Dienstag, 27. Juli 2021, 03:08:10 CEST schrieb Stephen Boyd:
> > > > > Quoting Yunhao Tian (2021-07-21 05:48:16)
> > > > > > Currently, no driver support for DDR memory controller (DMC) is present,
> > > > > > as a result, no driver is explicitly consuming the ddrphy clock. This means
> > > > > > that VPLL1 (parent of ddr clock) will be shutdown if we enable
> > > > > > and then disable any child clock of VPLL1 (e.g. SCLK_I2S0_8CH_TX).
> > > > > > If VPLL1 is disabled, the whole system will freeze, because the DDR
> > > > > > controller will lose its clock. So, it's necessary to prevent VPLL1 from
> > > > > > shutting down, by marking the ddrphy4x CLK_IS_CRITICAL.
> > > > > >
> > > > > > This bug was discovered when I was porting rockchip_i2s_tdm driver to
> > > > > > mainline kernel from Rockchip 4.4 kernel. I guess that other Rockchip
> > > > > > SoCs without DMC driver may need the same patch. If this applies to
> > > > > > other devices, please let us know.
> > > > > >
> > > > > > Signed-off-by: Yunhao Tian <t123yh at outlook.com>
> > > > > > ---
> > > > > >  drivers/clk/rockchip/clk-rk3308.c | 2 +-
> > > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/drivers/clk/rockchip/clk-rk3308.c b/drivers/clk/rockchip/clk-rk3308.c
> > > > > > index 2c3bd0c749f2..6be077166330 100644
> > > > > > --- a/drivers/clk/rockchip/clk-rk3308.c
> > > > > > +++ b/drivers/clk/rockchip/clk-rk3308.c
> > > > > > @@ -564,7 +564,7 @@ static struct rockchip_clk_branch rk3308_clk_branches[] __initdata = {
> > > > > >         COMPOSITE(SCLK_DDRCLK, "clk_ddrphy4x_src", mux_dpll_vpll0_vpll1_p, CLK_IGNORE_UNUSED,
> > > > > >                         RK3308_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 3, DFLAGS,
> > > > > >                         RK3308_CLKGATE_CON(0), 10, GFLAGS),
> > > > > > -       GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", CLK_IGNORE_UNUSED,
> > > > > > +       GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", CLK_IGNORE_UNUSED | CLK_IS_CRITICAL,
> > > > >
> > > > > Is it not enabled by default?
> > > >
> > > > All gates are enabled by default, but this gate shares a common parent
> > > > tree down to a pll, so if another leaf-user is disabling their part, this
> > > > untracked clock would get disabled as well.
> > >
> > > Right, this problem is cropping up in different places for various
> > > drivers.
> > >
> > > >
> > > > On that note, I remember a sort of CLK_HANDOFF was planned way back
> > > > in the past, meaning clock is critical until a driver picks it up, after this the
> > > > driver is responsible for it. Did that get any momentum?
> > > >
> > >
> > > Last I saw Saravana sent a patch to sort of connect CLK_HANDOFF to
> > > device driver sync_state() callback. I think we need to at least stash
> > > away that a clk is enabled at boot and then figure out how to tie in
> > > sync_state and/or something else.
> >
> > Yeah, my clk_sync_state() series should do that. I'll get back on that
> > patch this week or next.
> >
> > Yunhao,
> >
> > Is there at least some DT device that consumes the DDR phy clock? Can
> > you point me to the DT for this board (not the SoC) so I can take a
> > look at it later?
>
> Not for the rk3308. If you're looking for live-examples of handoff clocks,
> I can provide another examples though:
>
>
> rockchip/clk-rk3288.c - pclk_rkpwm (in the separate critical clock list) ... with
> arch/arm/boot/dts/rk3288.dtsi - clock is supplying pwm nodes.
>
> As the comment in the clock driver suggests (line 850), some boards use
> pwm-regulators for central components. The pwm-regulators are configured
> at boot already, so the clock shouldn't be disabled till the pwm-regulator takes
> over.

If you can reproduce the issue on your end if you remove the
pclk_rkpwm clock from the critical clock list, then can you try this
series?
https://lore.kernel.org/lkml/20210407034456.516204-1-saravanak at google.com/

It should keep the pclk_rkpwm clock on till all the consumers of the
clock have probed. And after that it'll actually allow the clock to be
turned off instead of keeping it on forever.

-Saravana


From strit at manjaro.org  Thu Aug  5 15:04:27 2021
From: strit at manjaro.org (Dan Johansen)
Date: Fri,  6 Aug 2021 00:04:27 +0200
Subject: [PATCH] arm64: dts: rockchip: Setup USB typec port as datarole on
Message-ID: <20210805220426.2693062-1-strit@manjaro.org>

Some chargers try to put the charged device into device data
role. Before this commit this condition caused the tcpm state machine to
issue a hard reset due to a capability missmatch.

Signed-off-by: Dan Johansen <strit at manjaro.org>
---
 arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
index 2b5f001ff4a6..2115e03a59d7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
@@ -711,7 +711,7 @@ fusb0: fusb30x at 22 {
 
 		connector {
 			compatible = "usb-c-connector";
-			data-role = "host";
+			data-role = "dual";
 			label = "USB-C";
 			op-sink-microwatt = <1000000>;
 			power-role = "dual";
-- 
2.32.0



From daniel at makrotopia.org  Thu Aug  5 15:23:30 2021
From: daniel at makrotopia.org (Daniel Golle)
Date: Thu, 5 Aug 2021 23:23:30 +0100
Subject: [PATCH] ARM: kirkwood: add missing <linux/if_ether.h> for ETH_ALEN
Message-ID: <YQxk4jrbm31NM1US@makrotopia.org>

After commit 83216e3988cd1 ("of: net: pass the dst buffer to
of_get_mac_address()") build fails for kirkwood as ETH_ALEN is not
defined.

arch/arm/mach-mvebu/kirkwood.c: In function 'kirkwood_dt_eth_fixup':
arch/arm/mach-mvebu/kirkwood.c:87:13: error: 'ETH_ALEN' undeclared (first use in this function); did you mean 'ESTALE'?
   u8 tmpmac[ETH_ALEN];
             ^~~~~~~~
             ESTALE
arch/arm/mach-mvebu/kirkwood.c:87:13: note: each undeclared identifier is reported only once for each function it appears in
arch/arm/mach-mvebu/kirkwood.c:87:6: warning: unused variable 'tmpmac' [-Wunused-variable]
   u8 tmpmac[ETH_ALEN];
      ^~~~~~
make[5]: *** [scripts/Makefile.build:262: arch/arm/mach-mvebu/kirkwood.o] Error 1
make[5]: *** Waiting for unfinished jobs....

Add missing #include <linux/if_ether.h> to fix this.

Cc: David S. Miller <davem at davemloft.net>
Cc: Andrew Lunn <andrew at lunn.ch>
Cc: Michael Walle <michael at walle.cc>
Reported-by: https://buildbot.openwrt.org/master/images/#/builders/56/builds/220/steps/44/logs/stdio
Fixes: 83216e3988cd1 ("of: net: pass the dst buffer to of_get_mac_address()")
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 arch/arm/mach-mvebu/kirkwood.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c
index 06b1706595f4c..a493a896e6ee3 100644
--- a/arch/arm/mach-mvebu/kirkwood.c
+++ b/arch/arm/mach-mvebu/kirkwood.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mbus.h>
+#include <linux/if_ether.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_net.h>
-- 
2.32.0



From rentao.bupt at gmail.com  Thu Aug  5 15:28:12 2021
From: rentao.bupt at gmail.com (rentao.bupt at gmail.com)
Date: Thu,  5 Aug 2021 15:28:12 -0700
Subject: [PATCH v2 0/6] ARM: dts: Add Facebook AST2600 BMCs
Message-ID: <20210805222818.8391-1-rentao.bupt@gmail.com>

From: Tao Ren <rentao.bupt at gmail.com>

The patch series introuces 3 new BMC platforms for the Facebook's next
generation switch platforms: Cloudripper, Elbert and Fuji.

Patch #1 adds dtsi file to describe the fixed flash layout of 128MB mtd
device. The flash layout is used by all the 3 AST2600 BMC as well as
Wedge400 (AST2500).

Patch #2 simplies Wedge400 dts by including the flash layout dtsi.

Patch #3 adds common dtsi which is included by all the new Facebook
AST2600 Network BMC platforms.

Patch #4 adds the device tree for Facebook Cloudripper (AST2600) BMC.

Patch #5 adds the device tree for Facebook Elbert (AST2600) BMC.

Patch #6 adds the device tree for Facebook Fuji (AST2600) BMC.

Tao Ren (6):
  ARM: dts: Add Facebook BMC 128MB flash layout
  ARM: dts: aspeed: wedge400: Use common flash layout
  ARM: dts: aspeed: Common dtsi for Facebook AST2600 Network BMCs
  ARM: dts: aspeed: Add Facebook Cloudripper (AST2600) BMC
  ARM: dts: aspeed: Add Facebook Elbert (AST2600) BMC
  ARM: dts: aspeed: Add Facebook Fuji (AST2600) BMC

 arch/arm/boot/dts/Makefile                    |    3 +
 .../dts/aspeed-bmc-facebook-cloudripper.dts   |  539 +++++++
 .../boot/dts/aspeed-bmc-facebook-elbert.dts   |  185 +++
 .../arm/boot/dts/aspeed-bmc-facebook-fuji.dts | 1251 +++++++++++++++++
 .../boot/dts/aspeed-bmc-facebook-wedge400.dts |   48 +-
 .../dts/ast2600-facebook-netbmc-common.dtsi   |  169 +++
 .../dts/facebook-bmc-flash-layout-128.dtsi    |   60 +
 7 files changed, 2208 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-elbert.dts
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts
 create mode 100644 arch/arm/boot/dts/ast2600-facebook-netbmc-common.dtsi
 create mode 100644 arch/arm/boot/dts/facebook-bmc-flash-layout-128.dtsi

-- 
2.17.1



From konrad.dybcio at somainline.org  Thu Aug  5 15:28:10 2021
From: konrad.dybcio at somainline.org (Konrad Dybcio)
Date: Fri,  6 Aug 2021 00:28:10 +0200
Subject: [PATCH] ARM: dts: Add MDM9607, PM8019 and Quectel EG25-G DTS files
Message-ID: <20210805222812.40731-1-konrad.dybcio@somainline.org>

Add base DTS files for MDM9607 SoC, PM8019 PMIC and Quectel
EG25-G USB LTE modem, used in devices like the Pine64 PinePhone.

Signed-off-by: Konrad Dybcio <konrad.dybcio at somainline.org>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/qcom-mdm9607-quectel-eg25-g.dts  | 186 ++++
 arch/arm/boot/dts/qcom-mdm9607.dtsi           | 889 ++++++++++++++++++
 arch/arm/boot/dts/qcom-pm8019.dtsi            | 100 ++
 4 files changed, 1176 insertions(+)
 create mode 100644 arch/arm/boot/dts/qcom-mdm9607-quectel-eg25-g.dts
 create mode 100644 arch/arm/boot/dts/qcom-mdm9607.dtsi
 create mode 100644 arch/arm/boot/dts/qcom-pm8019.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 863347b6b65e..f309490f74ec 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -933,6 +933,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
 	qcom-ipq4019-ap.dk07.1-c2.dtb \
 	qcom-ipq8064-ap148.dtb \
 	qcom-ipq8064-rb3011.dtb \
+	qcom-mdm9607-quectel-eg25-g.dtb \
 	qcom-msm8660-surf.dtb \
 	qcom-msm8960-cdp.dtb \
 	qcom-msm8974-fairphone-fp2.dtb \
diff --git a/arch/arm/boot/dts/qcom-mdm9607-quectel-eg25-g.dts b/arch/arm/boot/dts/qcom-mdm9607-quectel-eg25-g.dts
new file mode 100644
index 000000000000..2d574884e8aa
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-mdm9607-quectel-eg25-g.dts
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio at somainline.org>
+ */
+#include "qcom-mdm9607.dtsi"
+#include "qcom-pm8019.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+/ {
+	model = "Quectel EG25-G Modem";
+	compatible = "quectel,eg25-g", "qcom,mdm9607";
+	qcom,msm-id = <290 0x10000>, <296 0x10000>, <297 0x10000>, <298 0x10000>, <299 0x10000>;
+	qcom,board-id = <8 0>;
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x0>;
+	};
+
+	usb_extcon: usb-extcon {
+		compatible = "linux,extcon-usb-gpio";
+		vbus-gpio = <&pm8019_mpps 2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbdet_mpp>;
+	};
+};
+
+&blsp1_i2c2 {
+	status = "okay";
+};
+
+&blsp1_i2c4 {
+	status = "okay";
+
+	/delete-property/ pinctrl-names;
+	/delete-property/ pinctrl-0;
+};
+
+&blsp1_uart2 {
+	status = "okay";
+};
+
+&blsp1_uart3 {
+	status = "okay";
+};
+
+/* Debug UART */
+&blsp1_uart5 {
+	status = "okay";
+};
+
+&nand {
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition at 27a0000 {
+			label = "recovery";
+			reg = <0x27a0000 0x7c0000>;
+		};
+
+		partition at 2f60000 {
+			label = "modem";
+			reg = <0x2f60000 0x3580000>;
+		};
+
+		partition at 6580000 {
+			label = "recoveryfs";
+			reg = <0x6580000 0x1440000>;
+		};
+
+		partition at 79c0000 {
+			label = "usr_data";
+			reg = <0x79c0000 0x3d80000>;
+		};
+
+		partition at b7c0000 {
+			label = "system";
+			reg = <0xb7c0000 0x4840000>;
+		};
+	};
+};
+
+&pm8019_mpps {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb_mpp>;
+
+	usb_mpp: usb-mpp {
+		pins = "mpp1";
+		function = "digital";
+		bias-pull-up = <10000>;
+
+		power-source = <3>; /* 1.8V (L11) */
+	};
+
+	usbdet_mpp: usbdet-mpp {
+		pins = "mpp2";
+		function = "digital";
+		bias-disable;
+	};
+};
+
+/* NAND ID: 0x1590aaad | 256MiB | 4-bit ECC */
+&qpic_nand {
+	/*
+	 * This can only be enabled after interconnect lands, otherwise the SoC
+	 * absolutely loses its mind and randomly drops registers, leading to
+	 * null pointer exceptions!
+	 */
+	status = "disabled";
+};
+
+&qpic_bam {
+	status = "okay";
+};
+
+&tlmm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&undocumented_tlmm_gpios>;
+
+	undocumented_tlmm_gpios: undocumented-tlmm-gpios {
+		undocumented-gpio18 {
+			pins = "gpio18";
+			function = "gpio";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+
+		undocumented-gpio19 {
+			pins = "gpio19";
+			function = "gpio";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+
+		undocumented-gpio24 {
+			pins = "gpio24";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+		};
+
+		wakeup-in-n {
+			pins = "gpio25";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		undocumented-gpio55 {
+			pins = "gpio55";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+			output-low;
+		};
+
+		undocumented-gpio56 {
+			pins = "gpio56";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+			input-low;
+		};
+
+		undocumented-gpio57 {
+			pins = "gpio57";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+			output-low;
+		};
+	};
+};
+
+&usb {
+	status = "okay";
+	extcon = <&usb_extcon>, <&usb_extcon>;
+};
+
+&usb_hs_phy {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom-mdm9607.dtsi b/arch/arm/boot/dts/qcom-mdm9607.dtsi
new file mode 100644
index 000000000000..f1b11af2be8f
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-mdm9607.dtsi
@@ -0,0 +1,889 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Konrad Dybcio
+ */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/qcom,gcc-mdm9607.h>
+#include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/gpio/gpio.h>
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&intc>;
+
+	clocks {
+		xo_board: xo-board {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <19200000>;
+			clock-output-names = "xo_board";
+		};
+
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+		};
+
+		nand_clk_dummy: nand-clk-dummy {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32000>;
+		};
+	};
+
+	chosen { };
+
+	cpus {
+		#size-cells = <0>;
+		#address-cells = <1>;
+
+		CPU0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+		};
+	};
+
+	firmware {
+		scm: scm {
+			compatible = "qcom,scm-mdm9607", "qcom,scm";
+			clocks = <&gcc GCC_CRYPTO_CLK>,
+				 <&gcc GCC_CRYPTO_AXI_CLK>,
+				 <&gcc GCC_CRYPTO_AHB_CLK>;
+			clock-names = "core", "bus", "iface";
+			#reset-cells = <1>;
+
+			qcom,dload-mode = <&tcsr 0x6100>;
+		};
+	};
+
+	pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <GIC_PPI 8 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	pps: pps {
+		compatible = "pps-gpio";
+		gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pps_gpio>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		mpss_mem: memory at 82a00000 {
+			reg = <0x82a00000 0x5000000>;
+			no-map;
+		};
+
+		cnss_debug_mem: memory at 87a00000 {
+			reg = <0x87a00000 0x200000>;
+			no-map;
+		};
+
+		external_image_mem: memory at 87c00000 {
+			reg = <0x87c00000 0x100000>;
+			no-map;
+		};
+
+		smem_region: smem at 87d00000 {
+			reg = <0x87d00000 0x100000>;
+			no-map;
+		};
+
+		/*
+		 * This region is originally a part of external_image_mem
+		 * (which on downstream includes smem, how horrific!) and we
+		 * strictly have to protect it. Not doing so will cause an
+		 * imprecise external abort, probably induced by the firmware.
+		 */
+		firmware_region: memory at 87e00000 {
+			reg = <0x87e00000 0x200000>;
+			no-map;
+		};
+
+		qseecom_mem: memory at 8f800000 {
+			reg = <0x8f800000 0x100000>;
+			no-map;
+		};
+
+		mba_mem: memory at 8f900000 {
+			reg = <0x8f900000 0x100000>;
+			no-map;
+		};
+
+		audio_mem: memory at 8fc00000 {
+			reg = <0x8fc00000 0x400000>;
+			no-map;
+		};
+	};
+
+	smd {
+		compatible = "qcom,smd";
+
+		rpm {
+			interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
+			qcom,ipc = <&apcs 8 0>;
+			qcom,smd-edge = <15>;
+
+			rpm_requests: rpm-requests {
+				compatible = "qcom,rpm-msm8916";
+				qcom,smd-channels = "rpm_requests";
+
+				rpmcc: clock-controller {
+					compatible = "qcom,rpmcc-mdm9607", "qcom,rpmcc";
+					#clock-cells = <1>;
+				};
+
+				rpmpd: power-controller {
+					compatible = "qcom,mdm9607-rpmpd";
+					#power-domain-cells = <1>;
+					operating-points-v2 = <&rpmpd_opp_table>;
+
+					rpmpd_opp_table: opp-table {
+						compatible = "operating-points-v2";
+
+						rpmpd_opp_ret: opp1 {
+							opp-level = <RPM_SMD_LEVEL_RETENTION>;
+						};
+
+						rpmpd_opp_ret_plus: opp2 {
+							opp-level = <RPM_SMD_LEVEL_RETENTION_PLUS>;
+						};
+
+						rpmpd_opp_min_svs: opp3 {
+							opp-level = <RPM_SMD_LEVEL_MIN_SVS>;
+						};
+
+						rpmpd_opp_low_svs: opp4 {
+							opp-level = <RPM_SMD_LEVEL_LOW_SVS>;
+						};
+
+						rpmpd_opp_svs: opp5 {
+							opp-level = <RPM_SMD_LEVEL_SVS>;
+						};
+
+						rpmpd_opp_svs_plus: opp6 {
+							opp-level = <RPM_SMD_LEVEL_SVS_PLUS>;
+						};
+
+						rpmpd_opp_nom: opp7 {
+							opp-level = <RPM_SMD_LEVEL_NOM>;
+						};
+
+						rpmpd_opp_nom_plus: opp8 {
+							opp-level = <RPM_SMD_LEVEL_NOM_PLUS>;
+						};
+
+						rpmpd_opp_turbo: opp9 {
+							opp-level = <RPM_SMD_LEVEL_TURBO>;
+						};
+					};
+				};
+			};
+		};
+	};
+
+	smem {
+		compatible = "qcom,smem";
+
+		memory-region = <&smem_region>;
+		qcom,rpm-msg-ram = <&rpm_msg_ram>;
+
+		hwlocks = <&tcsr_mutex 3>;
+	};
+
+	soc: soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		rng at 22000 {
+			compatible = "qcom,prng";
+			reg = <0x00022000 0x140>;
+			clocks = <&gcc GCC_PRNG_AHB_CLK>;
+			clock-names = "core";
+		};
+
+		rpm_msg_ram: memory at 60000 {
+			compatible = "qcom,rpm-msg-ram";
+			reg = <0x00060000 0x8000>;
+		};
+
+		usb_hs_phy: phy at 6c000 {
+			compatible = "qcom,usb-hs-28nm-mdm9607";
+			reg = <0x0006c000 0x200>;
+			#phy-cells = <0>;
+			clocks = <&xo_board>, <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>,
+					<&gcc GCC_USB2A_PHY_SLEEP_CLK>;
+			clock-names = "ref", "ahb", "sleep";
+			resets = <&gcc QUSB2_PHY_BCR>, <&gcc USB2_HS_PHY_ONLY_BCR>;
+			reset-names = "phy", "por";
+			status = "disabled";
+		};
+
+		qfprom: qfprom at a4000 {
+			compatible = "qcom,qfprom";
+			reg = <0x000a4000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			tsens_caldata: calib at 228 {
+				reg = <0x228 0xc>;
+			};
+		};
+
+		tsens: thermal-sensor at 4a9000 {
+			compatible = "qcom,mdm9607-tsens", "qcom,tsens-v0_1";
+			reg = <0x004a9000 0x1000>, /* TM */
+			      <0x004a8000 0x1000>; /* SROT */
+			nvmem-cells = <&tsens_caldata>;
+			nvmem-cell-names = "calib";
+			#qcom,sensors = <5>;
+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "uplow";
+			#thermal-sensor-cells = <1>;
+		};
+
+		cryptobam: dma at 704000 {
+			compatible = "qcom,bam-v1.7.0";
+			reg = <0x00704000 0x20000>;
+			interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_CRYPTO_AHB_CLK>;
+			clock-names = "bam_clk";
+			#dma-cells = <1>;
+			qcom,ee = <1>;
+			qcom,controlled-remotely;
+			status = "disabled";
+		};
+
+		crypto: crypto at 73a000 {
+			compatible = "qcom,crypto-v5.1";
+			reg = <0x0073a000 0x20000>;
+			clocks = <&gcc GCC_CRYPTO_AHB_CLK>,
+				 <&gcc GCC_CRYPTO_AXI_CLK>,
+				 <&gcc GCC_CRYPTO_CLK>;
+			clock-names = "iface", "bus", "core";
+			dmas = <&cryptobam 2>, <&cryptobam 3>;
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		restart at 4ab000 {
+			compatible = "qcom,pshold";
+			reg = <0x004ab000 0x4>;
+		};
+
+		tlmm: pinctrl at 1000000 {
+			compatible = "qcom,mdm9607-pinctrl";
+			reg = <0x01000000 0x300000>;
+			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			gpio-ranges = <&tlmm 0 0 80>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			blsp1_uart3_default: blsp1-uart3-default {
+				/* TX, RX, CTS_N, RTS_N */
+				pins = "gpio0", "gpio1", "gpio2", "gpio3";
+				function = "blsp_uart3";
+				drive-strength = <2>;
+				bias-disable;
+			};
+
+			blsp1_uart3_sleep: blsp1-uart3-sleep {
+				pins = "gpio0", "gpio1", "gpio2", "gpio3";
+				function = "gpio";
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+
+			blsp1_uart2_default: blsp1-uart2-default {
+				/* TX, RX */
+				pins = "gpio4", "gpio5";
+				function = "blsp_uart2";
+				drive-strength = <2>;
+				bias-disable;
+			};
+
+			blsp1_uart2_sleep: blsp1-uart2-sleep {
+				pins = "gpio4", "gpio5";
+				function = "gpio";
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+
+			blsp1_i2c2_default: blsp1-i2c2-default {
+				pins = "gpio6", "gpio7";
+				function = "blsp_i2c2";
+				drive-strength = <2>;
+				bias-disable;
+			};
+
+			blsp1_i2c2_sleep: blsp1-i2c2-sleep {
+				pins = "gpio6", "gpio7";
+				function = "blsp_i2c2";
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+
+			blsp1_uart5_default: blsp1-uart5-default {
+				/* TX, RX, CTS_N, RTS_N */
+				pins = "gpio8", "gpio9", "gpio10", "gpio11";
+				function = "blsp_uart5";
+				drive-strength = <2>;
+				bias-disable;
+			};
+
+			blsp1_uart5_sleep: blsp1-uart5-sleep {
+				pins = "gpio8", "gpio9", "gpio10", "gpio11";
+				function = "gpio";
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+
+			can_reset_default: can-reset-default {
+				pins = "gpio11";
+				function = "gpio";
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			can_reset_sleep: can-reset-sleep {
+				pins = "gpio11";
+				function = "gpio";
+				drive-strength = <2>;
+				bias-pull-up;
+				output-high;
+			};
+
+			blsp1_i2c4_default: blsp1-i2c4-default {
+				pins = "gpio18", "gpio19";
+				function = "blsp_i2c4";
+				drive-strength = <2>;
+				bias-disable;
+			};
+
+			blsp1_i2c4_sleep: blsp1-i2c4-sleep {
+				pins = "gpio18", "gpio19";
+				function = "blsp_i2c4";
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+
+			blsp1_spi6_default: blsp1-spi6-default {
+				spi {
+					pins = "gpio20", "gpio21", "gpio23";
+					function = "blsp_spi6";
+					drive-strength = <12>;
+					bias-disable;
+				};
+
+				cs {
+					pins = "gpio22";
+					function = "blsp_spi6";
+					drive-strength = <2>;
+					bias-disable;
+				};
+			};
+
+			blsp1_spi6_sleep: blsp1-spi6-sleep {
+				spi {
+					pins = "gpio20", "gpio21", "gpio23";
+					function = "gpio";
+					drive-strength = <2>;
+					bias-pull-down;
+				};
+
+				cs {
+					pins = "gpio22";
+					function = "gpio";
+					drive-strength = <2>;
+					bias-disable;
+				};
+			};
+
+			pmx_pri_mi2s_active: pri-mi2s-active {
+				ws {
+					pins = "gpio20";
+					function = "pri_mi2s_ws_a";
+					drive-strength = <8>;
+					bias-disable;
+					output-high;
+				};
+
+				din {
+					pins = "gpio21";
+					function = "pri_mi2s_data0_a";
+					drive-strength = <8>;
+					bias-disable;
+				};
+
+				dout {
+					pins = "gpio22";
+					function = "pri_mi2s_data1_a";
+					drive-strength = <8>;
+					bias-disable;
+					output-high;
+				};
+
+				sck {
+					pins = "gpio23";
+					function = "pri_mi2s_sck_a";
+					drive-strength = <8>;
+					bias-disable;
+					output-high;
+				};
+			};
+
+			codec_reset_active: codec-reset-default {
+				pins = "gpio26";
+				drive-strength = <8>;
+				bias-disable;
+				output-high;
+			};
+
+			codec_reset_sleep: codec-reset-sleep {
+				pins = "gpio26";
+				drive-strength = <2>;
+				bias-pull-down;
+			};
+
+			ntn_rst_default: ntn-rst-default {
+				pins = "gpio30";
+				drive-strength = <16>;
+				bias-pull-up;
+				output-high;
+			};
+
+			sleep_ind_active: sleep-ind-active {
+				pins = "gpio42";
+				function = "gpio";
+				drive-strength = <2>;
+				bias-disable;
+				output-low;
+			};
+
+			sleep_ind_sleep: sleep-ind-sleep {
+				pins = "gpio42";
+				function = "gpio";
+				drive-strength = <2>;
+				bias-disable;
+				output-high;
+			};
+
+			pps_gpio: pps-gpio-n {
+				pins = "gpio53";
+				function = "nav_tsync_out_a";
+				bias-pull-down;
+			};
+
+			sdc1_wlan_gpio_active: sdc1-wlan-gpio-active {
+				pins = "gpio54";
+				function = "gpio";
+				drive-strength = <8>;
+				bias-pull-up;
+				output-high;
+			};
+
+			sdc1_wlan_gpio_sleep: sdc1-wlan-gpio-sleep {
+				pins = "gpio54";
+				function = "gpio";
+				drive-strength = <2>;
+				bias-disable;
+				output-low;
+			};
+
+			pmx_sec_mi2s_active: sec-mi2s-active {
+				din {
+					pins = "gpio76";
+					function = "sec_mi2s";
+					drive-strength = <8>;
+					bias-disable;
+				};
+
+				dout {
+					pins = "gpio77";
+					function = "sec_mi2s";
+					drive-strength = <8>;
+					bias-disable;
+					output-high;
+				};
+
+				sck {
+					pins = "gpio78";
+					function = "sec_mi2s";
+					drive-strength = <8>;
+					bias-disable;
+					output-high;
+				};
+
+				ws {
+					pins = "gpio79";
+					function = "sec_mi2s";
+					drive-strength = <8>;
+					bias-disable;
+					output-high;
+				};
+			};
+		};
+
+		gcc: clock-controller at 1800000 {
+			compatible = "qcom,gcc-mdm9607";
+			reg = <0x01800000 0x80000>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+			clock-names = "xo",
+				      "sleep_clk";
+			clocks = <&xo_board>, <&sleep_clk>;
+
+			assigned-clocks = <&gcc APSS_AHB_CLK_SRC>,
+							<&gcc PCNOC_BFDCD_CLK_SRC>;
+			assigned-clock-rates = <19200000>, <50000000>;
+		};
+
+		tcsr_mutex: syscon at 1905000 {
+			compatible = "qcom,tcsr-mutex";
+			reg = <0x01905000 0x20000>;
+			#hwlock-cells = <1>;
+		};
+
+		tcsr: syscon at 1937000 {
+			compatible = "qcom,tcsr-msm8916", "syscon";
+			reg = <0x01937000 0x30000>;
+		};
+
+		spmi_bus: spmi at 200f000 {
+			compatible = "qcom,spmi-pmic-arb";
+			reg = <0x0200f000 0x001000>,
+			      <0x02400000 0x800000>,
+			      <0x02c00000 0x800000>,
+			      <0x03800000 0x200000>,
+			      <0x0200a000 0x002100>;
+			reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+			interrupt-names = "periph_irq";
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			qcom,ee = <0>;
+			qcom,channel = <0>;
+			#address-cells = <2>;
+			#size-cells = <0>;
+			interrupt-controller;
+			#interrupt-cells = <4>;
+		};
+
+		blsp1_dma: dma-controller at 7884000 {
+			compatible = "qcom,bam-v1.7.0";
+			reg = <0x07884000 0x23000>;
+			interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "bam_clk";
+			#dma-cells = <1>;
+			qcom,ee = <0>;
+		};
+
+		blsp1_uart2: serial at 78b0000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x078b0000 0x200>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			pinctrl-names = "default", "sleep";
+			pinctrl-0 = <&blsp1_uart2_default>;
+			pinctrl-1 = <&blsp1_uart2_sleep>;
+			/* TODO: no explicit DMA? */
+			status = "disabled";
+		};
+
+		blsp1_uart3: serial at 78b1000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x078b1000 0x200>;
+			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_UART3_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			pinctrl-names = "default", "sleep";
+			pinctrl-0 = <&blsp1_uart3_default>;
+			pinctrl-1 = <&blsp1_uart3_sleep>;
+			dmas = <&blsp1_dma 4>, <&blsp1_dma 5>;
+			dma-names = "tx", "rx";
+			status = "disabled";
+		};
+
+		blsp1_uart5: serial at 78b3000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x078b3000 0x200>;
+			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_UART5_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			pinctrl-names = "default", "sleep";
+			pinctrl-0 = <&blsp1_uart5_default>;
+			pinctrl-1 = <&blsp1_uart5_sleep>;
+			dmas = <&blsp1_dma 8>, <&blsp1_dma 9>;
+			dma-names = "tx", "rx";
+			status = "disabled";
+		};
+
+		blsp1_i2c2: i2c at 78b6000 {
+			compatible = "qcom,i2c-qup-v2.1.1";
+			reg = <0x078b6000 0x600>;
+			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			clock-frequency = <400000>;
+			pinctrl-names = "default", "sleep";
+			pinctrl-0 = <&blsp1_i2c2_default>;
+			pinctrl-1 = <&blsp1_i2c2_sleep>;
+			dmas = <&blsp1_dma 14>, <&blsp1_dma 15>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		blsp1_i2c4: i2c at 78b8000 {
+			compatible = "qcom,i2c-qup-v2.1.1";
+			reg = <0x078b8000 0x600>;
+			interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			clock-frequency = <400000>;
+			pinctrl-names = "default", "sleep";
+			pinctrl-0 = <&blsp1_i2c4_default>;
+			pinctrl-1 = <&blsp1_i2c4_sleep>;
+			dmas = <&blsp1_dma 18>, <&blsp1_dma 19>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		blsp1_spi6: spi at 78ba000 {
+			compatible = "qcom,spi-qup-v2.2.1";
+			reg = <0x078ba000 0x600>;
+			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_QUP6_SPI_APPS_CLK>,
+					 <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			pinctrl-names = "default", "sleep";
+			pinctrl-0 = <&blsp1_spi6_default>;
+			pinctrl-1 = <&blsp1_spi6_sleep>;
+			dmas = <&blsp1_dma 22>, <&blsp1_dma 23>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		usb: usb at 78d9000 {
+			compatible = "qcom,ci-hdrc";
+			reg = <0x078d9000 0x200>,
+			      <0x078d9200 0x200>;
+			interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_USB_HS_AHB_CLK>,
+				 <&gcc GCC_USB_HS_SYSTEM_CLK>;
+			clock-names = "iface", "core";
+			assigned-clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>;
+			assigned-clock-rates = <69500000>;
+			resets = <&gcc USB_HS_BCR>;
+			reset-names = "core";
+			phy_type = "ulpi";
+			/* We don't want the modem to be the boss. */
+			dr_mode = "peripheral";
+			hnp-disable;
+			srp-disable;
+			adp-disable;
+			ahb-burst-config = <0>;
+			phy-names = "usb-phy";
+			phys = <&usb_hs_phy>;
+			status = "disabled";
+			#reset-cells = <1>;
+		};
+
+		qpic_bam: dma-controller at 7984000 {
+			compatible = "qcom,bam-v1.7.0";
+			reg = <0x07984000 0x1a000>;
+			interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&rpmcc RPM_SMD_QPIC_CLK>;
+			clock-names = "bam_clk";
+			#dma-cells = <1>;
+			qcom,ee = <0>;
+			status = "disabled";
+		};
+
+		qpic_nand: nand at 79b0000 {
+			compatible = "qcom,ipq4019-nand";
+			reg = <0x079b0000 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&rpmcc RPM_SMD_QPIC_CLK>, <&nand_clk_dummy>;
+			clock-names = "core", "aon";
+
+			dmas = <&qpic_bam 0>,
+			       <&qpic_bam 1>,
+			       <&qpic_bam 2>;
+			dma-names = "tx", "rx", "cmd";
+			status = "disabled";
+
+			nand: nand at 0 {
+				reg = <0>;
+
+				nand-ecc-strength = <4>;
+				nand-ecc-step-size = <512>;
+				nand-bus-width = <8>;
+			};
+		};
+
+		imem: imem at 8600000 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0x08600000 0x1000>;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			reboot-mode at 65c {
+				compatible = "syscon-reboot-mode";
+				offset = <0x65c>;
+			};
+
+			pil-reloc at 94c {
+				compatible = "qcom,pil-reloc-info";
+				reg = <0x94c 0xc8>;
+			};
+		};
+
+		intc: interrupt-controller at b000000 {
+			compatible = "qcom,msm-qgic2";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x0b000000 0x1000>,
+			      <0x0b002000 0x1000>;
+		};
+
+		/*
+		 * Yeah.. about that.. MDM9607 seems to
+		 * have 2 separate mailboxes: this one for
+		 * the usual IPC things and the one above
+		 * just for ARM frequency voting.
+		 */
+		apcs: syscon at b011000 {
+			compatible = "syscon";
+			reg = <0x0b011000 0x1000>;
+		};
+
+		timer at b020000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0b020000 0x1000>;
+			clock-frequency = <19200000>;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			frame at b021000 {
+				frame-number = <0>;
+				interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+						<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b021000 0x1000>,
+					<0x0b022000 0x1000>;
+			};
+			frame at b023000 {
+				frame-number = <1>;
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b023000 0x1000>;
+				status = "disabled";
+			};
+			frame at b024000 {
+				frame-number = <2>;
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b024000 0x1000>;
+				status = "disabled";
+			};
+			frame at b025000 {
+				frame-number = <3>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b025000 0x1000>;
+				status = "disabled";
+			};
+			frame at b026000 {
+				frame-number = <4>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b026000 0x1000>;
+				status = "disabled";
+			};
+			frame at b027000 {
+				frame-number = <5>;
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b027000 0x1000>;
+				status = "disabled";
+			};
+			frame at b028000 {
+				frame-number = <6>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b028000 0x1000>;
+				status = "disabled";
+			};
+			frame at b029000 {
+				frame-number = <7>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				reg = <0x0b029000 0x1000>;
+				status = "disabled";
+			};
+		};
+	};
+
+	smp2p-modem {
+		compatible = "qcom,smp2p";
+		qcom,smem = <435>, <428>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>;
+
+		qcom,ipc = <&apcs 8 14>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <1>;
+
+		modem_smp2p_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		modem_smp2p_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smsm {
+		compatible = "qcom,smsm";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,ipc-1 = <&apcs 8 13>;
+
+		apps_smsm: apps at 0 {
+			reg = <0>;
+
+			#qcom,smem-state-cells = <1>;
+		};
+
+		modem_smsm: modem at 1 {
+			reg = <1>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/qcom-pm8019.dtsi b/arch/arm/boot/dts/qcom-pm8019.dtsi
new file mode 100644
index 000000000000..0827d06a1f75
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-pm8019.dtsi
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Konrad Dybcio
+ */
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+
+	pm8019_0: pmic at 0 {
+		compatible = "qcom,pm8019", "qcom,spmi-pmic";
+		reg = <0x0 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pm8019_vadc: adc at 3100 {
+			compatible = "qcom,spmi-vadc";
+			reg = <0x3100>;
+			interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			#io-channel-cells = <1>;
+
+			adc-chan at 0 {
+				reg = <VADC_USBIN>;
+				qcom,pre-scaling = <1 10>;
+			};
+			adc-chan at 7 {
+				reg = <VADC_VSYS>;
+				qcom,pre-scaling = <1 3>;
+			};
+			adc-chan at 8 {
+				reg = <VADC_DIE_TEMP>;
+			};
+			adc-chan at 9 {
+				reg = <VADC_REF_625MV>;
+			};
+			adc-chan at a {
+				reg = <VADC_REF_1250MV>;
+			};
+			adc-chan at e {
+				reg = <VADC_GND_REF>;
+			};
+			adc-chan at f {
+				reg = <VADC_VDD_VADC>;
+			};
+		};
+
+		rtc at 6000 {
+			compatible = "qcom,pm8941-rtc";
+			reg = <0x6000>;
+			reg-names = "rtc", "alarm";
+			interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
+		};
+
+		pm8019_mpps: mpps at a000 {
+			compatible = "qcom,pm8019-mpp";
+			reg = <0xa000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <0 0xa0 0 IRQ_TYPE_NONE>,
+				     <0 0xa1 0 IRQ_TYPE_NONE>,
+				     <0 0xa2 0 IRQ_TYPE_NONE>,
+				     <0 0xa3 0 IRQ_TYPE_NONE>,
+					 <0 0xa4 0 IRQ_TYPE_NONE>,
+					 <0 0xa5 0 IRQ_TYPE_NONE>;
+		};
+
+		pm8019_gpios: gpios at c000 {
+			compatible = "qcom,pm8019-gpio";
+			reg = <0xc000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupts = <0 0xc0 0 IRQ_TYPE_NONE>,
+				     <0 0xc1 0 IRQ_TYPE_NONE>,
+				     <0 0xc2 0 IRQ_TYPE_NONE>,
+				     <0 0xc3 0 IRQ_TYPE_NONE>,
+					 <0 0xc4 0 IRQ_TYPE_NONE>,
+					 <0 0xc5 0 IRQ_TYPE_NONE>;
+		};
+	};
+
+	pm8019_1: pmic at 1 {
+		compatible = "qcom,pm8019", "qcom,spmi-pmic";
+		reg = <0x1 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pm8019_vib: vibrator at c000 {
+			compatible = "qcom,pm8916-vib";
+			reg = <0xc000>;
+			status = "disabled";
+		};
+
+		pm8019_spmi_regulators: regulators {
+			compatible = "qcom,pm8019-regulators";
+		};
+	};
+};
-- 
2.32.0



From rentao.bupt at gmail.com  Thu Aug  5 15:28:13 2021
From: rentao.bupt at gmail.com (rentao.bupt at gmail.com)
Date: Thu,  5 Aug 2021 15:28:13 -0700
Subject: [PATCH v2 1/6] ARM: dts: Add Facebook BMC 128MB flash layout
In-Reply-To: <20210805222818.8391-1-rentao.bupt@gmail.com>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
Message-ID: <20210805222818.8391-2-rentao.bupt@gmail.com>

From: Tao Ren <rentao.bupt at gmail.com>

This is the layout used by Facebook BMC systems. It describes the fixed
flash layout of a 128MB mtd device.

Signed-off-by: Tao Ren <rentao.bupt at gmail.com>
---
 Changes in v2:
  - None.

 .../dts/facebook-bmc-flash-layout-128.dtsi    | 60 +++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 arch/arm/boot/dts/facebook-bmc-flash-layout-128.dtsi

diff --git a/arch/arm/boot/dts/facebook-bmc-flash-layout-128.dtsi b/arch/arm/boot/dts/facebook-bmc-flash-layout-128.dtsi
new file mode 100644
index 000000000000..7f3652dea550
--- /dev/null
+++ b/arch/arm/boot/dts/facebook-bmc-flash-layout-128.dtsi
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2020 Facebook Inc.
+
+partitions {
+	compatible = "fixed-partitions";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	/*
+	 * u-boot partition: 896KB.
+	 */
+	u-boot at 0 {
+		reg = <0x0 0xe0000>;
+		label = "u-boot";
+	};
+
+	/*
+	 * u-boot environment variables: 64KB.
+	 */
+	u-boot-env at e0000 {
+		reg = <0xe0000 0x10000>;
+		label = "env";
+	};
+
+	/*
+	 * image metadata partition (64KB), used by Facebook internal
+	 * tools.
+	 */
+	image-meta at f0000 {
+		reg = <0xf0000 0x10000>;
+		label = "meta";
+	};
+
+	/*
+	 * FIT image: 119 MB.
+	 */
+	fit at 100000 {
+		reg = <0x100000 0x7700000>;
+		label = "fit";
+	};
+
+	/*
+	 * "data0" partition (8MB) is used by Facebook BMC platforms as
+	 * persistent data store.
+	 */
+	data0 at 7800000 {
+		reg = <0x7800000 0x800000>;
+		label = "data0";
+	};
+
+	/*
+	 * Although the master partition can be created by enabling
+	 * MTD_PARTITIONED_MASTER option, below "flash0" partition is
+	 * explicitly created to avoid breaking legacy applications.
+	 */
+	flash0 at 0 {
+		reg = <0x0 0x8000000>;
+		label = "flash0";
+	};
+};
-- 
2.17.1



From rentao.bupt at gmail.com  Thu Aug  5 15:28:14 2021
From: rentao.bupt at gmail.com (rentao.bupt at gmail.com)
Date: Thu,  5 Aug 2021 15:28:14 -0700
Subject: [PATCH v2 2/6] ARM: dts: aspeed: wedge400: Use common flash layout
In-Reply-To: <20210805222818.8391-1-rentao.bupt@gmail.com>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
Message-ID: <20210805222818.8391-3-rentao.bupt@gmail.com>

From: Tao Ren <rentao.bupt at gmail.com>

Simplify wedge400 flash layout by using the common layout defined in
"facebook-bmc-flash-layout-128.dtsi".

Signed-off-by: Tao Ren <rentao.bupt at gmail.com>
---
 Changes in v2:
  - None.

 .../boot/dts/aspeed-bmc-facebook-wedge400.dts | 48 +------------------
 1 file changed, 1 insertion(+), 47 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts
index 63a3dd548f30..a901c8be49b9 100644
--- a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts
@@ -91,53 +91,7 @@
  * Both firmware flashes are 128MB on Wedge400 BMC.
  */
 &fmc_flash0 {
-	partitions {
-		compatible = "fixed-partitions";
-		#address-cells = <1>;
-		#size-cells = <1>;
-
-		/*
-		 * u-boot partition: 384KB.
-		 */
-		u-boot at 0 {
-			reg = <0x0 0x60000>;
-			label = "u-boot";
-		};
-
-		/*
-		 * u-boot environment variables: 128KB.
-		 */
-		u-boot-env at 60000 {
-			reg = <0x60000 0x20000>;
-			label = "env";
-		};
-
-		/*
-		 * FIT image: 123.5 MB.
-		 */
-		fit at 80000 {
-			reg = <0x80000 0x7b80000>;
-			label = "fit";
-		};
-
-		/*
-		 * "data0" partition (4MB) is reserved for persistent
-		 * data store.
-		 */
-		data0 at 7c00000 {
-			reg = <0x7c00000 0x400000>;
-			label = "data0";
-		};
-
-		/*
-		 * "flash0" partition (covering the entire flash) is
-		 * explicitly created to avoid breaking legacy applications.
-		 */
-		flash0 at 0 {
-			reg = <0x0 0x8000000>;
-			label = "flash0";
-		};
-	};
+#include "facebook-bmc-flash-layout-128.dtsi"
 };
 
 &fmc_flash1 {
-- 
2.17.1



From rentao.bupt at gmail.com  Thu Aug  5 15:28:15 2021
From: rentao.bupt at gmail.com (rentao.bupt at gmail.com)
Date: Thu,  5 Aug 2021 15:28:15 -0700
Subject: [PATCH v2 3/6] ARM: dts: aspeed: Common dtsi for Facebook AST2600
 Network BMCs
In-Reply-To: <20210805222818.8391-1-rentao.bupt@gmail.com>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
Message-ID: <20210805222818.8391-4-rentao.bupt@gmail.com>

From: Tao Ren <rentao.bupt at gmail.com>

This common descirption is included by all Facebook AST2600 Network BMC
platforms to minimize duplicated device entries across Facebook Network
BMC device trees.

Signed-off-by: Tao Ren <rentao.bupt at gmail.com>
---
 Changes in v2:
  - "mac3" is removed from the dtsi (moved to platform dts files).

 .../dts/ast2600-facebook-netbmc-common.dtsi   | 169 ++++++++++++++++++
 1 file changed, 169 insertions(+)
 create mode 100644 arch/arm/boot/dts/ast2600-facebook-netbmc-common.dtsi

diff --git a/arch/arm/boot/dts/ast2600-facebook-netbmc-common.dtsi b/arch/arm/boot/dts/ast2600-facebook-netbmc-common.dtsi
new file mode 100644
index 000000000000..051de5bec345
--- /dev/null
+++ b/arch/arm/boot/dts/ast2600-facebook-netbmc-common.dtsi
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2020 Facebook Inc.
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+	aliases {
+		mmc0 = &emmc;
+		spi1 = &spi1;
+		spi2 = &spi_gpio;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,9600n8 root=/dev/ram rw vmalloc=640M";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x80000000>;
+	};
+
+	/*
+	 * GPIO-based SPI Master is required to access SPI TPM, because
+	 * full-duplex SPI transactions are not supported by ASPEED SPI
+	 * Controllers.
+	 */
+	spi_gpio: spi-gpio {
+		status = "okay";
+		compatible = "spi-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		gpio-sck = <&gpio0 ASPEED_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
+		gpio-mosi = <&gpio0 ASPEED_GPIO(X, 4) GPIO_ACTIVE_HIGH>;
+		gpio-miso = <&gpio0 ASPEED_GPIO(X, 5) GPIO_ACTIVE_HIGH>;
+
+		tpmdev at 0 {
+			compatible = "tcg,tpm_tis-spi";
+			spi-max-frequency = <33000000>;
+			reg = <0>;
+		};
+	};
+};
+
+&fmc {
+	status = "okay";
+
+	flash at 0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "spi0.0";
+
+#include "facebook-bmc-flash-layout-128.dtsi"
+	};
+
+	flash at 1 {
+		status = "okay";
+		m25p,fast-read;
+		label = "spi0.1";
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			flash1 at 0 {
+				reg = <0x0 0x8000000>;
+				label = "flash1";
+			};
+		};
+	};
+};
+
+&spi1 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&wdt1 {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+};
+
+&i2c4 {
+	status = "okay";
+};
+
+&i2c5 {
+	status = "okay";
+};
+
+&i2c6 {
+	status = "okay";
+};
+
+&i2c7 {
+	status = "okay";
+};
+
+&i2c8 {
+	status = "okay";
+};
+
+&i2c9 {
+	status = "okay";
+};
+
+&i2c10 {
+	status = "okay";
+};
+
+&i2c12 {
+	status = "okay";
+};
+
+&i2c13 {
+	status = "okay";
+};
+
+&i2c15 {
+	status = "okay";
+};
+
+&vhub {
+	status = "okay";
+};
+
+&emmc_controller {
+	status = "okay";
+};
+
+&emmc {
+	status = "okay";
+
+	non-removable;
+	max-frequency = <25000000>;
+	bus-width = <4>;
+};
+
+&rtc {
+	status = "okay";
+};
-- 
2.17.1



From rentao.bupt at gmail.com  Thu Aug  5 15:28:16 2021
From: rentao.bupt at gmail.com (rentao.bupt at gmail.com)
Date: Thu,  5 Aug 2021 15:28:16 -0700
Subject: [PATCH v2 4/6] ARM: dts: aspeed: Add Facebook Cloudripper (AST2600)
 BMC
In-Reply-To: <20210805222818.8391-1-rentao.bupt@gmail.com>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
Message-ID: <20210805222818.8391-5-rentao.bupt@gmail.com>

From: Tao Ren <rentao.bupt at gmail.com>

Add initial version of device tree for Facebook Cloudripper (AST2600) BMC.

Cloudripper is Facebook's next generation switch platform with an AST2600
BMC integrated for health monitoring purpose.

Signed-off-by: Tao Ren <rentao.bupt at gmail.com>
---
 Changes in v2:
  - added more notes about the new platform in patch description.
  - "spi1" was removed as the driver is not ready.
  - "mac3" properties were updated with pinctrl, and etc.

 arch/arm/boot/dts/Makefile                    |   1 +
 .../dts/aspeed-bmc-facebook-cloudripper.dts   | 539 ++++++++++++++++++
 2 files changed, 540 insertions(+)
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 90aed2c2959a..74c760038f28 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1409,6 +1409,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-arm-stardragon4800-rep2.dtb \
 	aspeed-bmc-asrock-e3c246d4i.dtb \
 	aspeed-bmc-bytedance-g220a.dtb \
+	aspeed-bmc-facebook-cloudripper.dtb \
 	aspeed-bmc-facebook-cmm.dtb \
 	aspeed-bmc-facebook-galaxy100.dtb \
 	aspeed-bmc-facebook-minipack.dtb \
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
new file mode 100644
index 000000000000..01ec3ce0a29d
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
@@ -0,0 +1,539 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2020 Facebook Inc.
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include "ast2600-facebook-netbmc-common.dtsi"
+
+/ {
+	model = "Facebook Cloudripper BMC";
+	compatible = "facebook,cloudripper-bmc", "aspeed,ast2600";
+
+	aliases {
+		/*
+		 * PCA9548 (1-0070) provides 8 channels connecting to
+		 * SMB (Switch Main Board).
+		 */
+		i2c16 = &imux16;
+		i2c17 = &imux17;
+		i2c18 = &imux18;
+		i2c19 = &imux19;
+		i2c20 = &imux20;
+		i2c21 = &imux21;
+		i2c22 = &imux22;
+		i2c23 = &imux23;
+
+		/*
+		 * PCA9548 (2-0070) provides 8 channels connecting to
+		 * SCM (System Controller Module).
+		 */
+		i2c24 = &imux24;
+		i2c25 = &imux25;
+		i2c26 = &imux26;
+		i2c27 = &imux27;
+		i2c28 = &imux28;
+		i2c29 = &imux29;
+		i2c30 = &imux30;
+		i2c31 = &imux31;
+
+		/*
+		 * PCA9548 (3-0070) provides 8 channels connecting to
+		 * SMB (Switch Main Board).
+		 */
+		i2c32 = &imux32;
+		i2c33 = &imux33;
+		i2c34 = &imux34;
+		i2c35 = &imux35;
+		i2c36 = &imux36;
+		i2c37 = &imux37;
+		i2c38 = &imux38;
+		i2c39 = &imux39;
+
+		/*
+		 * PCA9548 (8-0070) provides 8 channels connecting to
+		 * PDB (Power Delivery Board).
+		 */
+		i2c40 = &imux40;
+		i2c41 = &imux41;
+		i2c42 = &imux42;
+		i2c43 = &imux43;
+		i2c44 = &imux44;
+		i2c45 = &imux45;
+		i2c46 = &imux46;
+		i2c47 = &imux47;
+
+		/*
+		 * PCA9548 (15-0076) provides 8 channels connecting to
+		 * FCM (Fan Controller Module).
+		 */
+		i2c48 = &imux48;
+		i2c49 = &imux49;
+		i2c50 = &imux50;
+		i2c51 = &imux51;
+		i2c52 = &imux52;
+		i2c53 = &imux53;
+		i2c54 = &imux54;
+		i2c55 = &imux55;
+	};
+
+	spi_gpio: spi-gpio {
+		num-chipselects = <2>;
+		cs-gpios = <&gpio0 ASPEED_GPIO(X, 0) GPIO_ACTIVE_LOW>,
+			   <&gpio0 ASPEED_GPIO(X, 1) GPIO_ACTIVE_HIGH>;
+
+		eeprom at 1 {
+			compatible = "atmel,at93c46d";
+			spi-max-frequency = <250000>;
+			data-size = <16>;
+			spi-cs-high;
+			reg = <1>;
+		};
+	};
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&mdio1 {
+	status = "okay";
+};
+
+&mdio3 {
+	status = "okay";
+
+	ethphy1: ethernet-phy at 13 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0d>;
+	};
+};
+
+&mac3 {
+	status = "okay";
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii4_default>;
+};
+
+&i2c0 {
+	multi-master;
+	bus-frequency = <1000000>;
+};
+
+&i2c1 {
+	/*
+	 * PCA9548 (1-0070) provides 8 channels connecting to SMB (Switch
+	 * Main Board).
+	 */
+	i2c-switch at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+		i2c-mux-idle-disconnect;
+
+		imux16: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		imux17: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		imux18: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		imux19: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		imux20: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux21: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux22: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux23: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+&i2c2 {
+	/*
+	 * PCA9548 (2-0070) provides 8 channels connecting to SCM (System
+	 * Controller Module).
+	 */
+	i2c-switch at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+		i2c-mux-idle-disconnect;
+
+		imux24: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		imux25: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		imux26: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		imux27: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		imux28: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux29: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux30: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux31: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+&i2c3 {
+	/*
+	 * PCA9548 (3-0070) provides 8 channels connecting to SMB (Switch
+	 * Main Board).
+	 */
+	i2c-switch at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+		i2c-mux-idle-disconnect;
+
+		imux32: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		imux33: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		imux34: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		imux35: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		imux36: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux37: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux38: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux39: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+&i2c6 {
+	lp5012 at 14 {
+		compatible = "ti,lp5012";
+		reg = <0x14>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		multi-led at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			color = <LED_COLOR_ID_MULTI>;
+			function = LED_FUNCTION_ACTIVITY;
+			label = "sys";
+
+			led at 0 {
+				reg = <0>;
+				color = <LED_COLOR_ID_RED>;
+			};
+
+			led at 1 {
+				reg = <1>;
+				color = <LED_COLOR_ID_BLUE>;
+			};
+
+			led at 2 {
+				reg = <2>;
+				color = <LED_COLOR_ID_GREEN>;
+			};
+		};
+
+		multi-led at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			color = <LED_COLOR_ID_MULTI>;
+			function = LED_FUNCTION_ACTIVITY;
+			label = "fan";
+
+			led at 0 {
+				reg = <0>;
+				color = <LED_COLOR_ID_RED>;
+			};
+
+			led at 1 {
+				reg = <1>;
+				color = <LED_COLOR_ID_BLUE>;
+			};
+
+			led at 2 {
+				reg = <2>;
+				color = <LED_COLOR_ID_GREEN>;
+			};
+		};
+
+		multi-led at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			color = <LED_COLOR_ID_MULTI>;
+			function = LED_FUNCTION_ACTIVITY;
+			label = "psu";
+
+			led at 0 {
+				reg = <0>;
+				color = <LED_COLOR_ID_RED>;
+			};
+
+			led at 1 {
+				reg = <1>;
+				color = <LED_COLOR_ID_BLUE>;
+			};
+
+			led at 2 {
+				reg = <2>;
+				color = <LED_COLOR_ID_GREEN>;
+			};
+		};
+
+		multi-led at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			color = <LED_COLOR_ID_MULTI>;
+			function = LED_FUNCTION_ACTIVITY;
+			label = "scm";
+
+			led at 0 {
+				reg = <0>;
+				color = <LED_COLOR_ID_RED>;
+			};
+
+			led at 1 {
+				reg = <1>;
+				color = <LED_COLOR_ID_BLUE>;
+			};
+
+			led at 2 {
+				reg = <2>;
+				color = <LED_COLOR_ID_GREEN>;
+			};
+		};
+	};
+};
+
+&i2c8 {
+	/*
+	 * PCA9548 (8-0070) provides 8 channels connecting to PDB (Power
+	 * Delivery Board).
+	 */
+	i2c-switch at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+		i2c-mux-idle-disconnect;
+
+		imux40: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		imux41: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		imux42: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		imux43: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		imux44: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux45: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux46: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux47: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+
+	};
+};
+
+&i2c15 {
+	/*
+	 * PCA9548 (15-0076) provides 8 channels connecting to FCM (Fan
+	 * Controller Module).
+	 */
+	i2c-switch at 76 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x76>;
+		i2c-mux-idle-disconnect;
+
+		imux48: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		imux49: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		imux50: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		imux51: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		imux52: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux53: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux54: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux55: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+	};
+};
-- 
2.17.1



From rentao.bupt at gmail.com  Thu Aug  5 15:28:18 2021
From: rentao.bupt at gmail.com (rentao.bupt at gmail.com)
Date: Thu,  5 Aug 2021 15:28:18 -0700
Subject: [PATCH v2 6/6] ARM: dts: aspeed: Add Facebook Fuji (AST2600) BMC
In-Reply-To: <20210805222818.8391-1-rentao.bupt@gmail.com>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
Message-ID: <20210805222818.8391-7-rentao.bupt@gmail.com>

From: Tao Ren <rentao.bupt at gmail.com>

Add initial version of device tree for Facebook Fuji (AST2600) BMC.

Fuji is Facebook's next generation switch platform with an AST2600 BMC
integrated for health monitoring purpose.

Signed-off-by: Tao Ren <rentao.bupt at gmail.com>
---
 Changes in v2:
  - added more notes about the new platform in patch description.
  - "spi1" was removed as the driver is not ready.
  - "mac3" properties were updated with pinctrl, and etc.

 arch/arm/boot/dts/Makefile                    |    1 +
 .../arm/boot/dts/aspeed-bmc-facebook-fuji.dts | 1251 +++++++++++++++++
 2 files changed, 1252 insertions(+)
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7cbb982a7c8b..9765e2ff5bfe 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1412,6 +1412,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-facebook-cloudripper.dtb \
 	aspeed-bmc-facebook-cmm.dtb \
 	aspeed-bmc-facebook-elbert.dtb \
+	aspeed-bmc-facebook-fuji.dtb \
 	aspeed-bmc-facebook-galaxy100.dtb \
 	aspeed-bmc-facebook-minipack.dtb \
 	aspeed-bmc-facebook-tiogapass.dtb \
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts
new file mode 100644
index 000000000000..af58a73bbc49
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts
@@ -0,0 +1,1251 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2020 Facebook Inc.
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include "ast2600-facebook-netbmc-common.dtsi"
+
+/ {
+	model = "Facebook Fuji BMC";
+	compatible = "facebook,fuji-bmc", "aspeed,ast2600";
+
+	aliases {
+		/*
+		 * PCA9548 (2-0070) provides 8 channels connecting to
+		 * SCM (System Controller Module).
+		 */
+		i2c16 = &imux16;
+		i2c17 = &imux17;
+		i2c18 = &imux18;
+		i2c19 = &imux19;
+		i2c20 = &imux20;
+		i2c21 = &imux21;
+		i2c22 = &imux22;
+		i2c23 = &imux23;
+
+		/*
+		 * PCA9548 (8-0070) provides 8 channels connecting to
+		 * SMB (Switch Main Board).
+		 */
+		i2c24 = &imux24;
+		i2c25 = &imux25;
+		i2c26 = &imux26;
+		i2c27 = &imux27;
+		i2c28 = &imux28;
+		i2c29 = &imux29;
+		i2c30 = &imux30;
+		i2c31 = &imux31;
+
+		/*
+		 * PCA9548 (11-0077) provides 8 channels connecting to
+		 * SMB (Switch Main Board).
+		 */
+		i2c40 = &imux40;
+		i2c41 = &imux41;
+		i2c42 = &imux42;
+		i2c43 = &imux43;
+		i2c44 = &imux44;
+		i2c45 = &imux45;
+		i2c46 = &imux46;
+		i2c47 = &imux47;
+
+		/*
+		 * PCA9548 (24-0071) provides 8 channels connecting to
+		 * PDB-Left.
+		 */
+		i2c48 = &imux48;
+		i2c49 = &imux49;
+		i2c50 = &imux50;
+		i2c51 = &imux51;
+		i2c52 = &imux52;
+		i2c53 = &imux53;
+		i2c54 = &imux54;
+		i2c55 = &imux55;
+
+		/*
+		 * PCA9548 (25-0072) provides 8 channels connecting to
+		 * PDB-Right.
+		 */
+		i2c56 = &imux56;
+		i2c57 = &imux57;
+		i2c58 = &imux58;
+		i2c59 = &imux59;
+		i2c60 = &imux60;
+		i2c61 = &imux61;
+		i2c62 = &imux62;
+		i2c63 = &imux63;
+
+		/*
+		 * PCA9548 (26-0076) provides 8 channels connecting to
+		 * FCM1.
+		 */
+		i2c64 = &imux64;
+		i2c65 = &imux65;
+		i2c66 = &imux66;
+		i2c67 = &imux67;
+		i2c68 = &imux68;
+		i2c69 = &imux69;
+		i2c70 = &imux70;
+		i2c71 = &imux71;
+
+		/*
+		 * PCA9548 (27-0076) provides 8 channels connecting to
+		 * FCM2.
+		 */
+		i2c72 = &imux72;
+		i2c73 = &imux73;
+		i2c74 = &imux74;
+		i2c75 = &imux75;
+		i2c76 = &imux76;
+		i2c77 = &imux77;
+		i2c78 = &imux78;
+		i2c79 = &imux79;
+
+		/*
+		 * PCA9548 (40-0076) provides 8 channels connecting to
+		 * PIM1.
+		 */
+		i2c80 = &imux80;
+		i2c81 = &imux81;
+		i2c82 = &imux82;
+		i2c83 = &imux83;
+		i2c84 = &imux84;
+		i2c85 = &imux85;
+		i2c86 = &imux86;
+		i2c87 = &imux87;
+
+		/*
+		 * PCA9548 (41-0076) provides 8 channels connecting to
+		 * PIM2.
+		 */
+		i2c88 = &imux88;
+		i2c89 = &imux89;
+		i2c90 = &imux90;
+		i2c91 = &imux91;
+		i2c92 = &imux92;
+		i2c93 = &imux93;
+		i2c94 = &imux94;
+		i2c95 = &imux95;
+
+		/*
+		 * PCA9548 (42-0076) provides 8 channels connecting to
+		 * PIM3.
+		 */
+		i2c96 = &imux96;
+		i2c97 = &imux97;
+		i2c98 = &imux98;
+		i2c99 = &imux99;
+		i2c100 = &imux100;
+		i2c101 = &imux101;
+		i2c102 = &imux102;
+		i2c103 = &imux103;
+
+		/*
+		 * PCA9548 (43-0076) provides 8 channels connecting to
+		 * PIM4.
+		 */
+		i2c104 = &imux104;
+		i2c105 = &imux105;
+		i2c106 = &imux106;
+		i2c107 = &imux107;
+		i2c108 = &imux108;
+		i2c109 = &imux109;
+		i2c110 = &imux110;
+		i2c111 = &imux111;
+
+		/*
+		 * PCA9548 (44-0076) provides 8 channels connecting to
+		 * PIM5.
+		 */
+		i2c112 = &imux112;
+		i2c113 = &imux113;
+		i2c114 = &imux114;
+		i2c115 = &imux115;
+		i2c116 = &imux116;
+		i2c117 = &imux117;
+		i2c118 = &imux118;
+		i2c119 = &imux119;
+
+		/*
+		 * PCA9548 (45-0076) provides 8 channels connecting to
+		 * PIM6.
+		 */
+		i2c120 = &imux120;
+		i2c121 = &imux121;
+		i2c122 = &imux122;
+		i2c123 = &imux123;
+		i2c124 = &imux124;
+		i2c125 = &imux125;
+		i2c126 = &imux126;
+		i2c127 = &imux127;
+
+		/*
+		 * PCA9548 (46-0076) provides 8 channels connecting to
+		 * PIM7.
+		 */
+		i2c128 = &imux128;
+		i2c129 = &imux129;
+		i2c130 = &imux130;
+		i2c131 = &imux131;
+		i2c132 = &imux132;
+		i2c133 = &imux133;
+		i2c134 = &imux134;
+		i2c135 = &imux135;
+
+		/*
+		 * PCA9548 (47-0076) provides 8 channels connecting to
+		 * PIM8.
+		 */
+		i2c136 = &imux136;
+		i2c137 = &imux137;
+		i2c138 = &imux138;
+		i2c139 = &imux139;
+		i2c140 = &imux140;
+		i2c141 = &imux141;
+		i2c142 = &imux142;
+		i2c143 = &imux143;
+	};
+
+	spi_gpio: spi-gpio {
+		num-chipselects = <3>;
+		cs-gpios = <&gpio0 ASPEED_GPIO(X, 0) GPIO_ACTIVE_LOW>,
+			   <0>,	/* device reg=<1> does not exist */
+			   <&gpio0 ASPEED_GPIO(X, 2) GPIO_ACTIVE_HIGH>;
+
+		eeprom at 2 {
+			compatible = "atmel,at93c46d";
+			spi-max-frequency = <250000>;
+			data-size = <16>;
+			spi-cs-high;
+			reg = <2>;
+		};
+	};
+};
+
+&i2c0 {
+	multi-master;
+	bus-frequency = <1000000>;
+};
+
+&i2c2 {
+	/*
+	 * PCA9548 (2-0070) provides 8 channels connecting to SCM (System
+	 * Controller Module).
+	 */
+	i2c-switch at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+		i2c-mux-idle-disconnect;
+
+		imux16: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			adm1278 at 10 {
+				compatible = "adi,adm1278";
+				reg = <0x10>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				shunt-resistor-micro-ohms = <1500>;
+			};
+		};
+
+		imux17: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		imux18: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		imux19: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		imux20: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux21: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux22: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux23: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+&i2c8 {
+	/*
+	 * PCA9548 (8-0070) provides 8 channels connecting to SMB (Switch
+	 * Main Board).
+	 */
+	i2c-switch at 70 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+		i2c-mux-idle-disconnect;
+
+		imux24: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			i2c-switch at 71 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x71>;
+				i2c-mux-idle-disconnect;
+
+				imux48: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux49: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux50: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+
+					lp5012 at 14 {
+						compatible = "ti,lp5012";
+						reg = <0x14>;
+						#address-cells = <1>;
+						#size-cells = <0>;
+
+						multi-led at 0 {
+							#address-cells = <1>;
+							#size-cells = <0>;
+							reg = <0>;
+							color = <LED_COLOR_ID_MULTI>;
+							function = LED_FUNCTION_ACTIVITY;
+							label = "sys";
+
+							led at 0 {
+								reg = <0>;
+								color = <LED_COLOR_ID_RED>;
+							};
+
+							led at 1 {
+								reg = <1>;
+								color = <LED_COLOR_ID_BLUE>;
+							};
+
+							led at 2 {
+								reg = <2>;
+								color = <LED_COLOR_ID_GREEN>;
+							};
+						};
+
+						multi-led at 1 {
+							#address-cells = <1>;
+							#size-cells = <0>;
+							reg = <1>;
+							color = <LED_COLOR_ID_MULTI>;
+							function = LED_FUNCTION_ACTIVITY;
+							label = "fan";
+
+							led at 0 {
+								reg = <0>;
+								color = <LED_COLOR_ID_RED>;
+							};
+
+							led at 1 {
+								reg = <1>;
+								color = <LED_COLOR_ID_BLUE>;
+							};
+
+							led at 2 {
+								reg = <2>;
+								color = <LED_COLOR_ID_GREEN>;
+							};
+						};
+
+						multi-led at 2 {
+							#address-cells = <1>;
+							#size-cells = <0>;
+							reg = <2>;
+							color = <LED_COLOR_ID_MULTI>;
+							function = LED_FUNCTION_ACTIVITY;
+							label = "psu";
+
+							led at 0 {
+								reg = <0>;
+								color = <LED_COLOR_ID_RED>;
+							};
+
+							led at 1 {
+								reg = <1>;
+								color = <LED_COLOR_ID_BLUE>;
+							};
+
+							led at 2 {
+								reg = <2>;
+								color = <LED_COLOR_ID_GREEN>;
+							};
+						};
+
+						multi-led at 3 {
+							#address-cells = <1>;
+							#size-cells = <0>;
+							reg = <3>;
+							color = <LED_COLOR_ID_MULTI>;
+							function = LED_FUNCTION_ACTIVITY;
+							label = "smb";
+
+							led at 0 {
+								reg = <0>;
+								color = <LED_COLOR_ID_RED>;
+							};
+
+							led at 1 {
+								reg = <1>;
+								color = <LED_COLOR_ID_BLUE>;
+							};
+
+							led at 2 {
+								reg = <2>;
+								color = <LED_COLOR_ID_GREEN>;
+							};
+						};
+					};
+				};
+
+				imux51: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux52: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux53: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux54: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux55: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux25: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			i2c-switch at 72 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x72>;
+				i2c-mux-idle-disconnect;
+
+				imux56: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux57: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux58: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux59: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux60: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux61: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux62: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux63: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux26: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux64: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux65: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux66: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux67: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+
+					adm1278 at 10 {
+						compatible = "adi,adm1278";
+						reg = <0x10>;
+						#address-cells = <1>;
+						#size-cells = <0>;
+						shunt-resistor-micro-ohms = <250>;
+					};
+				};
+
+				imux68: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux69: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux70: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux71: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux27: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux72: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux73: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux74: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux75: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+
+					adm1278 at 10 {
+						compatible = "adi,adm1278";
+						reg = <0x10>;
+						#address-cells = <1>;
+						#size-cells = <0>;
+						shunt-resistor-micro-ohms = <250>;
+					};
+				};
+
+				imux76: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux77: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux78: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux79: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux28: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux29: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux30: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux31: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+
+	};
+};
+
+&i2c11 {
+	status = "okay";
+
+	/*
+	 * PCA9548 (11-0077) provides 8 channels connecting to SMB (Switch
+	 * Main Board).
+	 */
+	i2c-switch at 77 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x77>;
+		i2c-mux-idle-disconnect;
+
+		imux40: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux80: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux81: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux82: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux83: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux84: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux85: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux86: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux87: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux41: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux88: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux89: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux90: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux91: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux92: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux93: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux94: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux95: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux42: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux96: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux97: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux98: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux99: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux100: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux101: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux102: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux103: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux43: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux104: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux105: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux106: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux107: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux108: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux109: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux110: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux111: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux44: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux112: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux113: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux114: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux115: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux116: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux117: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux118: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux119: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux45: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux120: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux121: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux122: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux123: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux124: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux125: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux126: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux127: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux46: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux128: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux129: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux130: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux131: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux132: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux133: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux134: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux135: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+		imux47: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+
+			i2c-switch at 76 {
+				compatible = "nxp,pca9548";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x76>;
+				i2c-mux-idle-disconnect;
+
+				imux136: i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+				};
+
+				imux137: i2c at 1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <1>;
+				};
+
+				imux138: i2c at 2 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <2>;
+				};
+
+				imux139: i2c at 3 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <3>;
+				};
+
+				imux140: i2c at 4 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <4>;
+				};
+
+				imux141: i2c at 5 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <5>;
+				};
+
+				imux142: i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <6>;
+				};
+
+				imux143: i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <7>;
+				};
+			};
+
+		};
+
+	};
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&mdio1 {
+	status = "okay";
+
+	ethphy3: ethernet-phy at 13 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0d>;
+	};
+};
+
+&mac3 {
+	status = "okay";
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii4_default>;
+};
-- 
2.17.1



From rentao.bupt at gmail.com  Thu Aug  5 15:28:17 2021
From: rentao.bupt at gmail.com (rentao.bupt at gmail.com)
Date: Thu,  5 Aug 2021 15:28:17 -0700
Subject: [PATCH v2 5/6] ARM: dts: aspeed: Add Facebook Elbert (AST2600) BMC
In-Reply-To: <20210805222818.8391-1-rentao.bupt@gmail.com>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
Message-ID: <20210805222818.8391-6-rentao.bupt@gmail.com>

From: Tao Ren <rentao.bupt at gmail.com>

Add initial version of device tree for Facebook Elbert (AST2600) BMC.

Elbert is Facebook's next generation switch platform with an AST2600 BMC
integrated for health monitoring purpose.

Signed-off-by: Tao Ren <rentao.bupt at gmail.com>
---
 Changes in v2:
  - added more notes about the new platform in patch description.
  - "mac3" was disabled (because it was removed from Facebook AST2600
    NetBMC common dtsi). Will add "mac3" back when "fixed-link" is
    supported in the MAC driver.

 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/aspeed-bmc-facebook-elbert.dts   | 185 ++++++++++++++++++
 2 files changed, 186 insertions(+)
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-elbert.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 74c760038f28..7cbb982a7c8b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1411,6 +1411,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-bytedance-g220a.dtb \
 	aspeed-bmc-facebook-cloudripper.dtb \
 	aspeed-bmc-facebook-cmm.dtb \
+	aspeed-bmc-facebook-elbert.dtb \
 	aspeed-bmc-facebook-galaxy100.dtb \
 	aspeed-bmc-facebook-minipack.dtb \
 	aspeed-bmc-facebook-tiogapass.dtb \
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-elbert.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-elbert.dts
new file mode 100644
index 000000000000..27b43fe099f1
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-elbert.dts
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2020 Facebook Inc.
+
+/dts-v1/;
+
+#include "ast2600-facebook-netbmc-common.dtsi"
+
+/ {
+	model = "Facebook Elbert BMC";
+	compatible = "facebook,elbert-bmc", "aspeed,ast2600";
+
+	aliases {
+		serial0 = &uart5;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+
+		/*
+		 * 8 child channels of PCA9548 2-0075.
+		 */
+		i2c16 = &imux16;
+		i2c17 = &imux17;
+		i2c18 = &imux18;
+		i2c19 = &imux19;
+		i2c20 = &imux20;
+		i2c21 = &imux21;
+		i2c22 = &imux22;
+		i2c23 = &imux23;
+
+		/*
+		 * 8 child channels of PCA9548 5-0075.
+		 */
+		i2c24 = &imux24;
+		i2c25 = &imux25;
+		i2c26 = &imux26;
+		i2c27 = &imux27;
+		i2c28 = &imux28;
+		i2c29 = &imux29;
+		i2c30 = &imux30;
+		i2c31 = &imux31;
+	};
+
+	chosen {
+		stdout-path = &uart5;
+	};
+
+	spi_gpio: spi-gpio {
+		num-chipselects = <1>;
+		cs-gpios = <&gpio0 ASPEED_GPIO(X, 0) GPIO_ACTIVE_LOW>;
+	};
+};
+
+&lpc_ctrl {
+	status = "okay";
+};
+
+&kcs2 {
+	status = "okay";
+	aspeed,lpc-io-reg = <0xca8>;
+};
+
+&kcs3 {
+	status = "okay";
+	aspeed,lpc-io-reg = <0xca2>;
+};
+
+&i2c2 {
+	i2c-switch at 75 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+		i2c-mux-idle-disconnect;
+
+		imux16: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		imux17: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		imux18: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		imux19: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		imux20: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux21: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux22: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux23: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+&i2c5 {
+	i2c-switch at 75 {
+		compatible = "nxp,pca9548";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x75>;
+		i2c-mux-idle-disconnect;
+
+		imux24: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		imux25: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		imux26: i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		imux27: i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		imux28: i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		imux29: i2c at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		imux30: i2c at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		imux31: i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+&i2c11 {
+	status = "okay";
+};
-- 
2.17.1



From semen.protsenko at linaro.org  Thu Aug  5 16:06:41 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 6 Aug 2021 02:06:41 +0300
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <455cfb5e-dff7-a5c0-3875-49abe3e900f3@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <455cfb5e-dff7-a5c0-3875-49abe3e900f3@canonical.com>
Message-ID: <CAPLW+4nDS0atrbUFagDA0W_Ky5MvOiY+N+NQoQ+me4pndp_iWg@mail.gmail.com>

On Sat, 31 Jul 2021 at 12:03, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 30/07/2021 16:49, Sam Protsenko wrote:
> > Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
> >
> > Features:
> >  * CPU: Cortex-A55 Octa (8 cores), up to 2 GHz
> >  * Memory interface: LPDDR4/4x 2 channels (12.8 GB/s)
> >  * SD/MMC: SD 3.0, eMMC5.1 DDR 8-bit
> >  * Modem: 4G LTE, 3G, GSM/GPRS/EDGE
> >  * RF: Quad GNSS, WiFi 5 (802.11ac), Bluetooth 5.0
> >  * GPU: Mali-G52 MP1
> >  * Codec: 1080p 60fps H64, HEVC, JPEG HW Codec
> >  * Display: Full HD+ (2520x1080)@60fps LCD
> >  * Camera: 16+5MP/13+8MP ISP, MIPI CSI 4/4/2, FD, DRC
> >  * Connectivity: USB 2.0 DRD, USI (SPI/UART/I2C), HSI2C, I3C, ADC, Audio
>
> Please document first the features you add (and are working) and
> afterwards mention all others capabilities.
>

I'll remove SoC features, as it's easy to find and it's not needed in
commit message anyway. Instead I'll describe which features (nodes)
are added in DT by this commit.

> >
> > This patch adds minimal SoC support. Particular board device tree files
> > can include exynos850.dtsi file to get SoC related nodes, and then
> > reference those nodes further as needed.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> >  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
> >  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
> >  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
>
> Not buildable. Missing Makefile, missing DTS. Please submit with initial
> DTS, otherwise no one is able to verify it even compiles.
>

This device is not available for purchase yet. I'll send the patch for
board dts once it's announced. I can do all the testing for now, if
you have any specific requests. Would it be possible for us to review
and apply only SoC support for now? Will send v2 soon...

> >  3 files changed, 1057 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > new file mode 100644
> > index 000000000000..4cf0a22cc6db
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > @@ -0,0 +1,782 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
> > + *
> > + * Copyright (C) 2017 Samsung Electronics Co., Ltd.
> > + * Copyright (C) 2021 Linaro Ltd.
> > + *
> > + * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
> > + * tree nodes in this file.
> > + */
> > +
> > +#include <dt-bindings/interrupt-controller/exynos850.h>
> > +
> > +/ {
> > +     /* ALIVE */
> > +     pinctrl at 11850000 {
> > +             gpa0: gpa0 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
>
> That's odd a little, why three cells? How this would be used/referenced?
>

Fixed. You are right, irq_domain_xlate_twocell() is used in
pinctrl-exynos.c. Btw, that fixed the use-case when gpX is specified
as interrupt-parrent for other nodes.

> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                         <GIC_SPI INTREQ__ALIVE_EINT0 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT1 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT2 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT3 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT4 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT5 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT6 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT7 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpa1: gpa1 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                         <GIC_SPI INTREQ__ALIVE_EINT8 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT9 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT10 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT11 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT12 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT13 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT14 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT15 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpa2: gpa2 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                         <GIC_SPI INTREQ__ALIVE_EINT16 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT17 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT18 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT19 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT20 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT21 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT22 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT23 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpa3: gpa3 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                         <GIC_SPI INTREQ__ALIVE_EINT24 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT25 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT26 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT27 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT28 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT29 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT30 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT31 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpa4: gpa4 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                         <GIC_SPI INTREQ__ALIVE_EINT32 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT33 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT34 IRQ_TYPE_LEVEL_HIGH>,
> > +                         <GIC_SPI INTREQ__ALIVE_EINT35 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpq0: gpq0 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             /* USI_PERI_UART_DBG */
> > +             uart0_bus: uart0-bus {
> > +                     samsung,pins = "gpq0-0", "gpq0-1";
> > +                     samsung,pin-function = <2>;
>
> EXYNOS_PIN_FUNC_2
>

Done, thanks.

> > +                     samsung,pin-pud = <0>;
>
> EXYNOS_PIN_PULL_xx?
>

Yes, replaced pin-pud values with these constants, thanks. Won't touch
pin-drv properties, though, as different domains have different
meanings for the same values, so don't want to introduce the whole
bunch of consts.

> > +             };
> > +
> > +             decon_f_te_on: decon_f_te_on {
>
> 1. Where is it used?
> 2. Use hyphens in node names.
> Please build it with W=1 and fix the warnings.
>

decon* nodes seem like leftover from vendor kernel. Those are not
connected anywhere on my board, so I removed those nodes.

Also fixed node names as you suggested, and fixed all stuff found with
W=1 build, thanks for reminding me that.

> > +                     samsung,pins = "gpa4-1";
>
> Order the nodes based on first pin name, so:
> i2c5_bus
> i2c6_bus
> decon_f_te_on
> uart0_bus
>

Done. Also rearranged the nodes in that way for other pinctrl domains.

> > +                     samsung,pin-function = <0xf>;
> > +             };
> > +
> > +             decon_f_te_off: decon_f_te_off {
>
> Where is it used?
>

Removed, as explained above.

> > +                     samsung,pins = "gpa4-1";
> > +                     samsung,pin-function = <0x0>;
> > +             };
> > +
> > +             /* I2C_5 | CAM_PMIC_I2C */
>
> This comment is confusing. I2C-5 is obvious from node name and label.
> CAM_PMIC_I2C does not look like property of SoC but board.
>

Yeah, unfortunately this confusing I2C naming (CAM_PMIC_I2C and
MOTOR_I2C) actually comes from TRM and SoC schematic symbol. So in
Device Tree it's called just i2c5 and i2c6 (because it's a regular I2C
really), but in TRM it's a mix of both names. I guess it's just a poor
pin function naming, done by SoC designers.

That said, I suggest changing these comments to something like this:

    /* I2C5 (also called CAM_PMIC_I2C in TRM) */
    /* I2C6 (also called MOTOR_I2C in TRM) */

> > +             i2c5_bus: i2c5-bus {
> > +                     samsung,pins = "gpa3-5", "gpa3-6";
> > +                     samsung,pin-function = <3>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             /* I2C_6 | MOTOR_I2C */
> > +             i2c6_bus: i2c6-bus {
> > +                     samsung,pins = "gpa3-7", "gpa4-0";
> > +                     samsung,pin-function = <3>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +     };
> > +
> > +     /* CMGP */
> > +     pinctrl at 11c30000 {
> > +             gpm0: gpm0 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                       <GIC_SPI INTREQ__CMGP_EXT_INTM00 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpm1: gpm1 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                       <GIC_SPI INTREQ__CMGP_EXT_INTM01 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpm2: gpm2 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                       <GIC_SPI INTREQ__CMGP_EXT_INTM02 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpm3: gpm3 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                       <GIC_SPI INTREQ__CMGP_EXT_INTM03 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpm4: gpm4 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                       <GIC_SPI INTREQ__CMGP_EXT_INTM04 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             gpm5: gpm5 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts =
> > +                       <GIC_SPI INTREQ__CMGP_EXT_INTM05 IRQ_TYPE_LEVEL_HIGH>;
> > +             };
> > +
> > +             /* usi_cmgp00 */
> > +             hsi2c3_bus: hsi2c3-bus {
> > +                     samsung,pins = "gpm0-0", "gpm1-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             /* usi_cmgp01 */
> > +             hsi2c4_bus: hsi2c4-bus {
> > +                     samsung,pins = "gpm4-0", "gpm5-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             /* spi usi_cmgp00 */
> > +             spi1_bus: spi1-bus {
> > +                     samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             spi1_cs: spi1-cs {
> > +                     samsung,pins = "gpm3-0";
> > +                     samsung,pin-function = <1>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             spi1_cs_func: spi1-cs-func {
> > +                     samsung,pins = "gpm3-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             /* spi usi_cmgp01 */
> > +             spi2_bus: spi2-bus {
> > +                     samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             spi2_cs: spi2-cs {
> > +                     samsung,pins = "gpm7-0";
> > +                     samsung,pin-function = <1>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             spi2_cs_func: spi2-cs-func {
> > +                     samsung,pins = "gpm7-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             /* usi_cmgp00_uart */
> > +             uart1_bus_single: uart1-bus {
> > +                     samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +             };
> > +
> > +             uart1_bus_dual: uart1-bus-dual {
> > +                     samsung,pins = "gpm0-0", "gpm1-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +             };
> > +
> > +             /* usi_cmgp01_uart */
> > +             uart2_bus_single: uart2-bus {
> > +                     samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +             };
> > +
> > +             uart2_bus_dual: uart2-bus-dual {
> > +                     samsung,pins = "gpm4-0", "gpm5-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +             };
> > +     };
> > +
> > +     /* AUD */
> > +     pinctrl at 14a60000 {
> > +             gpb0: gpb0 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             gpb1: gpb1 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             aud_codec_mclk: aud-codec-mclk {
> > +                     samsung,pins = "gpb0-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <1>;
> > +             };
> > +
> > +             aud_codec_mclk_idle: aud-codec-mclk-idle {
> > +                     samsung,pins = "gpb0-0";
> > +                     samsung,pin-function = <0>;
> > +                     samsung,pin-pud = <1>;
> > +             };
> > +
> > +             aud_i2s0_bus: aud-i2s0-bus {
> > +                     samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <1>;
> > +             };
> > +
> > +             aud_i2s0_idle: aud-i2s0-idle {
> > +                     samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
> > +                     samsung,pin-function = <0>;
> > +                     samsung,pin-pud = <1>;
> > +             };
> > +
> > +             aud_i2s1_bus: aud-i2s1-bus {
> > +                     samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <1>;
> > +             };
> > +
> > +             aud_i2s1_idle: aud-i2s1-idle {
> > +                     samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
> > +                     samsung,pin-function = <0>;
> > +                     samsung,pin-pud = <1>;
> > +             };
> > +
> > +             aud_fm_bus: aud-fm-bus {
> > +                     samsung,pins = "gpb1-4";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <1>;
> > +             };
> > +
> > +             aud_fm_idle: aud-fm-idle {
> > +                     samsung,pins = "gpb1-4";
> > +                     samsung,pin-function = <0>;
> > +                     samsung,pin-pud = <1>;
> > +             };
> > +     };
> > +
> > +     /* HSI */
> > +     pinctrl at 13430000 {
> > +             gpf2: gpf2 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             sd2_clk: sd2-clk {
> > +                     samsung,pins = "gpf2-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sd2_cmd: sd2-cmd {
> > +                     samsung,pins = "gpf2-1";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <2>;
> > +              };
> > +
> > +             sd2_bus1: sd2-bus-width1 {
> > +                     samsung,pins = "gpf2-2";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sd2_bus4: sd2-bus-width4 {
> > +                     samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sd2_clk_fast_slew_rate_1x: sd2-clk_fast_slew_rate_1x {
> > +                     samsung,pins = "gpf2-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             sd2_clk_fast_slew_rate_1_5x: sd2-clk_fast_slew_rate_1_5x {
> > +                     samsung,pins = "gpf2-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <1>;
> > +             };
> > +
> > +             sd2_clk_fast_slew_rate_2x: sd2-clk_fast_slew_rate_2x {
> > +                     samsung,pins = "gpf2-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sd2_clk_fast_slew_rate_2_5x: sd2-clk_fast_slew_rate_2_5x {
> > +                     samsung,pins = "gpf2-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +
> > +             sd2_clk_fast_slew_rate_3x: sd2-clk_fast_slew_rate_3x {
> > +                     samsung,pins = "gpf2-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <4>;
> > +             };
> > +
> > +             sd2_clk_fast_slew_rate_4x: sd2-clk_fast_slew_rate_4x {
> > +                     samsung,pins = "gpf2-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <5>;
> > +             };
> > +
> > +             sd2_pins_as_pdn: sd2-pins-as-pdn {
> > +                     samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
> > +                                    "gpf2-4", "gpf2-5";
> > +                     samsung,pin-function = <0>;
> > +                     samsung,pin-pud = <2>;
> > +             };
> > +
>
> No need for blank line.
>

Fixed.

> > +     };
> > +
> > +     /* CORE */
> > +     pinctrl at 12070000 {
> > +             gpf0: gpf0 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             sd0_clk: sd0-clk {
> > +                     samsung,pins = "gpf0-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +
> > +             sd0_cmd: sd0-cmd {
> > +                     samsung,pins = "gpf0-1";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +
> > +             sd0_rdqs: sd0-rdqs {
> > +                     samsung,pins = "gpf0-2";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <1>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +
> > +             sd0_nreset: sd0-nreset {
> > +                     samsung,pins = "gpf0-3";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +
> > +             sd0_clk_fast_slew_rate_1x: sd0-clk_fast_slew_rate_1x {
> > +                     samsung,pins = "gpf0-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <1>;
> > +             };
> > +
> > +             sd0_clk_fast_slew_rate_2x: sd0-clk_fast_slew_rate_2x {
> > +                     samsung,pins = "gpf0-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sd0_clk_fast_slew_rate_3x: sd0-clk_fast_slew_rate_3x {
> > +                     samsung,pins = "gpf0-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sd0_clk_fast_slew_rate_4x: sd0-clk_fast_slew_rate_4x {
> > +                     samsung,pins = "gpf0-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +
> > +             gpf1: gpf1 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             sd0_bus1: sd0-bus-width1 {
> > +                     samsung,pins = "gpf1-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +
> > +             sd0_bus4: sd0-bus-width4 {
> > +                     samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +
> > +             sd0_bus8: sd0-bus-width8 {
> > +                     samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <3>;
> > +             };
> > +     };
> > +
> > +     /* PERI */
> > +     pinctrl at 139b0000 {
> > +             gpg0: gpg0 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             gpp0: gpp0 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +             gpp1: gpp1 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             gpp2: gpp2 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             gpg1: gpg1 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             gpg2: gpg2 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             gpg3: gpg3 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             gpc0: gpc0 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             gpc1: gpc1 {
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +
> > +                     interrupt-controller;
> > +                     #interrupt-cells = <2>;
> > +             };
> > +
> > +             xclkout: xclkout {
> > +                     samsung,pins = "gpq0-2";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +             };
> > +
> > +             /* usi_hsi2c_0 */
>
> Comment seems to duplicate node name/label.
>

I think the comment is useful, maybe just designed poorly. It's
pointing out that this HS-I2C block is based on USI IP-core. Basically
we have 7 USI blocks in this SoC:
  - 5 USIs that pre-defined: HSI2C0, HSI2C1, HSI2C2, UART0 and SPI0;
although AFAIU they can be changed via System Register as well, but
seems like nobody does that
  - 2 USIs from CMGP blocks (CMGP0 and CMGP1), which are actually configurable

I will revise all such comments like this, just to show those blocks
are based on USI design:

    /* USI: HSI2C0 */

At least when I was bringing up this board, I was really confused for
long time about this USI business. So I'm sure some kind of comments
might be actually helpful. And that's one reason to keep
exynos850-usi.dtsi file: although I removed it for now, squashing it
into exynos850.dtsi, I think it might be a good idea to bring that
back once all USI nodes are described. Just thinking aloud :)

> > +             hsi2c0_bus: hsi2c0-bus {
> > +                     samsung,pins = "gpc1-0", "gpc1-1";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             /* usi_hsi2c_1 */
> > +             hsi2c1_bus: hsi2c1-bus {
> > +                     samsung,pins = "gpc1-2", "gpc1-3";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             /* usi_hsi2c_2 */
> > +             hsi2c2_bus: hsi2c2-bus {
> > +                     samsung,pins = "gpc1-4", "gpc1-5";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             /* usi_spi_0 */
> > +             spi0_bus: spi0-bus {
> > +                     samsung,pins = "gpp2-0", "gpp2-2", "gpp2-3";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             spi0_cs: spi0-cs {
> > +                     samsung,pins = "gpp2-1";
> > +                     samsung,pin-function = <1>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             spi0_cs_func: spi0-cs-func {
> > +                     samsung,pins = "gpp2-1";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             i2c0_bus: i2c0-bus {
> > +                     samsung,pins = "gpp0-0", "gpp0-1";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             i2c1_bus: i2c1-bus {
> > +                     samsung,pins = "gpp0-2", "gpp0-3";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             i2c2_bus: i2c2-bus {
> > +                     samsung,pins = "gpp0-4", "gpp0-5";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             i2c3_bus: i2c3-bus {
> > +                     samsung,pins = "gpp1-0", "gpp1-1";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             i2c4_bus: i2c4-bus {
> > +                     samsung,pins = "gpp1-2", "gpp1-3";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <3>;
> > +                     samsung,pin-drv = <0>;
> > +             };
> > +
> > +             fm_lna_en: fm-lna-en {
> > +                     samsung,pins = "gpg2-3";
> > +                     samsung,pin-function = <1>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-val = <0>;
> > +             };
> > +
> > +             sensor_mclk0_in: sensor-mclk0-in {
> > +                     samsung,pins = "gpc0-0";
> > +                     samsung,pin-function = <0>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sensor_mclk0_out: sensor-mclk0-out {
> > +                     samsung,pins = "gpc0-0";
> > +                     samsung,pin-function = <1>;
> > +                     samsung,pin-pud = <1>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sensor_mclk0_fn: sensor-mclk0-fn {
>
> No, seriously. What sensor is it? In SoC?
>

In this context, "sensor" stands for "camera". Of course, it resides
(or rather *may* reside) outside of the SoC. This is just useful pin
configuration for camera master clock lines (3 of them). On schematic
those 3 lines are grouped into "MCLK" block, and those pins main
function is CAM_MCLK. I guess it makes sense to keep those
definitions, as I doubt somebody would actually consider using those
lines for somthing else. Or I can remove all those sensor*
definitions, if you'd like, then those can be added later, when camera
support cames in.

> > +                     samsung,pins = "gpc0-0";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sensor_mclk1_in: sensor-mclk1-in {
> > +                     samsung,pins = "gpc0-1";
> > +                     samsung,pin-function = <0>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sensor_mclk1_out: sensor-mclk1-out {
> > +                     samsung,pins = "gpc0-1";
> > +                     samsung,pin-function = <1>;
> > +                     samsung,pin-pud = <1>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sensor_mclk1_fn: sensor-mclk1-fn {
> > +                     samsung,pins = "gpc0-1";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sensor_mclk2_in: sensor-mclk2-in {
> > +                     samsung,pins = "gpc0-2";
> > +                     samsung,pin-function = <0>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sensor_mclk2_out: sensor-mclk2-out {
> > +                     samsung,pins = "gpc0-2";
> > +                     samsung,pin-function = <1>;
> > +                     samsung,pin-pud = <1>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +
> > +             sensor_mclk2_fn: sensor-mclk2-fn {
> > +                     samsung,pins = "gpc0-2";
> > +                     samsung,pin-function = <2>;
> > +                     samsung,pin-pud = <0>;
> > +                     samsung,pin-drv = <2>;
> > +             };
> > +     };
> > +};
> > diff --git a/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi b/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
> > new file mode 100644
> > index 000000000000..fb243e0a6260
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
> > @@ -0,0 +1,30 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Samsung's Exynos850 SoC USI device tree source
> > + *
> > + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
> > + * Copyright (C) 2021 Linaro Ltd.
> > + *
> > + * Samsung's Exynos850 SoC USI channels are listed in this file as device tree
> > + * nodes.
>
> Why here not in exynos850.dtsi?
>

Yeah, you're right. As it's only serial_0 for now, I've moved that
into exynos850.dtsi and removed exynos850-usi.dtsi.

> > + */
> > +
> > +#include <dt-bindings/clock/exynos850.h>
> > +
> > +/ {
> > +     aliases {
> > +             uart0 = &serial_0;
> > +     };
> > +
> > +     /* USI_UART */
> > +     serial_0: uart at 13820000 {
>
> This should ne in soc node.
>

Done.

> > +             compatible = "samsung,exynos850-uart";
> > +             reg = <0x0 0x13820000 0x100>;
> > +             interrupts = <GIC_SPI INTREQ__UART IRQ_TYPE_LEVEL_HIGH>;
> > +             pinctrl-names = "default";
> > +             pinctrl-0 = <&uart0_bus>;
> > +             clocks = <&clock GATE_UART_QCH>, <&clock DOUT_UART>;
> > +             clock-names = "gate_uart_clk0", "uart";
> > +             status = "disabled";
> > +     };
> > +};
> > diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> > new file mode 100644
> > index 000000000000..ed2d1c8ae0c3
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> > @@ -0,0 +1,245 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Samsung Exynos850 SoC device tree source
> > + *
> > + * Copyright (C) 2018 Samsung Electronics Co., Ltd.
> > + * Copyright (C) 2021 Linaro Ltd.
> > + *
> > + * Samsung Exynos850 SoC device nodes are listed in this file.
> > + * Exynos based board files can include this file and provide
> > + * values for board specific bindings.
> > + */
> > +
> > +#include <dt-bindings/interrupt-controller/exynos850.h>
> > +#include <dt-bindings/clock/exynos850.h>
> > +#include "exynos850-pinctrl.dtsi"
> > +#include "exynos850-usi.dtsi"
> > +
> > +/ {
>
> Add a comment like:
> /* Also known under engineering name exynos3830 */
>

Sure.

> > +     compatible = "samsung,exynos850";
>
> Undocumented compatible. Checkpatch should complain.
>

It actually doesn't, though it does complain about other undocumented
compatibles. I understand that it should be documented in
samsung-boards.yaml, but is it ok with you if I do that later, when
adding some actual board's dts? Just don't want to have two patches
for that.

> > +     interrupt-parent = <&gic>;
> > +     #address-cells = <2>;
> > +     #size-cells = <1>;
> > +
> > +     aliases {
> > +             pinctrl0 = &pinctrl_0;
> > +             pinctrl1 = &pinctrl_1;
> > +             pinctrl2 = &pinctrl_2;
> > +             pinctrl3 = &pinctrl_3;
> > +             pinctrl4 = &pinctrl_4;
> > +             pinctrl5 = &pinctrl_5;
> > +     };
> > +
> > +     cpus {
> > +             #address-cells = <2>;
> > +             #size-cells = <0>;
> > +
> > +             cpu-map {
> > +                     cluster0 {
> > +                             core0 {
> > +                                     cpu = <&cpu0>;
> > +                             };
> > +                             core1 {
> > +                                     cpu = <&cpu1>;
> > +                             };
> > +                             core2 {
> > +                                     cpu = <&cpu2>;
> > +                             };
> > +                             core3 {
> > +                                     cpu = <&cpu3>;
> > +                             };
> > +                     };
> > +
> > +                     cluster1 {
> > +                             core0 {
> > +                                     cpu = <&cpu4>;
> > +                             };
> > +                             core1 {
> > +                                     cpu = <&cpu5>;
> > +                             };
> > +                             core2 {
> > +                                     cpu = <&cpu6>;
> > +                             };
> > +                             core3 {
> > +                                     cpu = <&cpu7>;
> > +                             };
> > +                     };
> > +             };
> > +
> > +             cpu0: cpu at 0000 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a55", "arm,armv8";
> > +                     reg = <0x0 0x0000>;
>
> reg = <0x0 0x0>;
> (in following places similarly)
>

Done, and also fixed @0000 stuff, while at it.

> > +                     enable-method = "psci";
> > +             };
> > +             cpu1: cpu at 0001 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a55", "arm,armv8";
> > +                     reg = <0x0 0x0001>;
> > +                     enable-method = "psci";
> > +             };
> > +             cpu2: cpu at 0002 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a55", "arm,armv8";
> > +                     reg = <0x0 0x0002>;
> > +                     enable-method = "psci";
> > +             };
> > +             cpu3: cpu at 0003 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a55", "arm,armv8";
> > +                     reg = <0x0 0x0003>;
> > +                     enable-method = "psci";
> > +             };
> > +             cpu4: cpu at 0004 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a55", "arm,armv8";
> > +                     reg = <0x0 0x0100>;
> > +                     enable-method = "psci";
> > +             };
> > +             cpu5: cpu at 0005 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a55", "arm,armv8";
> > +                     reg = <0x0 0x0101>;
> > +                     enable-method = "psci";
> > +             };
> > +             cpu6: cpu at 0006 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a55", "arm,armv8";
> > +                     reg = <0x0 0x0102>;
> > +                     enable-method = "psci";
> > +             };
> > +             cpu7: cpu at 0007 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a55", "arm,armv8";
> > +                     reg = <0x0 0x0103>;
> > +                     enable-method = "psci";
> > +             };
> > +     };
> > +
> > +     psci {
> > +             compatible = "arm,psci-1.0";
> > +             method = "smc";
> > +     };
> > +
> > +     gic: interrupt-controller at 12a00000 {
> > +             compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
> > +             #interrupt-cells = <3>;
> > +             #address-cells = <0>;
> > +             interrupt-controller;
> > +             reg = <0x0 0x12a01000 0x1000>,
> > +                   <0x0 0x12a02000 0x1000>,
> > +                   <0x0 0x12a04000 0x2000>,
> > +                   <0x0 0x12a06000 0x2000>;
> > +             interrupts = <GIC_PPI 9
> > +                             (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> > +     };
> > +
> > +     timer {
> > +             compatible = "arm,armv8-timer";
> > +             interrupts = <GIC_PPI 13
> > +                             (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> > +                          <GIC_PPI 14
> > +                             (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> > +                          <GIC_PPI 11
> > +                             (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> > +                          <GIC_PPI 10
> > +                             (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
> > +             clock-frequency = <26000000>;
> > +             use-clocksource-only;
> > +             use-physical-timer;
> > +     };
> > +
>
> All below should be under soc node.
>

Done.

> Please don't write new DTS/DTSI from scratch but use exynos5433.dtsi as
> template/example.
>

Well, I didn't implement that from scratch :) As you probably figured,
I reworked the vendor's dts (heavily, that is). But yeah, I definitely
re-checked with existing DTs this time (exynos5433 and exynos7
mostly), and tried to follow best practices.

> > +     clock: clock-controller at 0x120e0000 {
> > +             compatible = "samsung,exynos850-clock";
> > +             reg = <0x0 0x120e0000 0x8000>;
> > +             #clock-cells = <1>;
> > +     };
> > +
> > +     /* ALIVE */
> > +     pinctrl_0: pinctrl at 11850000 {
> > +             compatible = "samsung,exynos850-pinctrl";
> > +             reg = <0x0 0x11850000 0x1000>;
> > +             interrupts = <GIC_SPI INTREQ__ALIVE_EINT0 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT1 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT2 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT3 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT4 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT5 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT6 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT7 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT8 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT9 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT10 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT11 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT12 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT13 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT14 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT15 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT16 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT17 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT18 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT19 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT20 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT21 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT22 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT23 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT24 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT25 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT26 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT27 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT28 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT29 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT30 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI INTREQ__ALIVE_EINT31 IRQ_TYPE_LEVEL_HIGH>;
> > +
> > +             wakeup-interrupt-controller {
> > +                     compatible = "samsung,exynos7-wakeup-eint";
> > +             };
> > +     };
> > +
> > +     /* CMGP */
> > +     pinctrl_1: pinctrl at 11c30000 {
> > +             compatible = "samsung,exynos850-pinctrl";
> > +             reg = <0x0 0x11c30000 0x1000>;
> > +             interrupts =
> > +                     <GIC_SPI INTREQ__CMGP_EXT_INTM00 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI INTREQ__CMGP_EXT_INTM01 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI INTREQ__CMGP_EXT_INTM02 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI INTREQ__CMGP_EXT_INTM03 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI INTREQ__CMGP_EXT_INTM04 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI INTREQ__CMGP_EXT_INTM05 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI INTREQ__CMGP_EXT_INTM06 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI INTREQ__CMGP_EXT_INTM07 IRQ_TYPE_LEVEL_HIGH>;
> > +
> > +             wakeup-interrupt-controller {
> > +                     compatible = "samsung,exynos7-wakeup-eint";
> > +             };
> > +     };
> > +
> > +     /* AUD */
> > +     pinctrl_2: pinctrl at 14a60000 {
> > +             compatible = "samsung,exynos850-pinctrl";
> > +             reg = <0x0 0x14a60000 0x1000>;
> > +     };
> > +
> > +     /* HSI */
> > +     pinctrl_3: pinctrl at 13430000 {
> > +             compatible = "samsung,exynos850-pinctrl";
> > +             reg = <0x0 0x13430000 0x1000>;
> > +             interrupts = <GIC_SPI INTREQ__GPIO_HSI IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     /* CORE */
> > +     pinctrl_4: pinctrl at 12070000 {
> > +             compatible = "samsung,exynos850-pinctrl";
> > +             reg = <0x0 0x12070000 0x1000>;
> > +             interrupts = <GIC_SPI INTREQ__GPIO_CORE IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     /* PERI */
> > +     pinctrl_5: pinctrl at 139b0000 {
> > +             compatible = "samsung,exynos850-pinctrl";
> > +             reg = <0x0 0x139b0000 0x1000>;
> > +             interrupts = <GIC_SPI INTREQ__GPIO_PERI IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +};
> >
>
>
> Best regards,
> Krzysztof


From s-anna at ti.com  Thu Aug  5 16:27:47 2021
From: s-anna at ti.com (Suman Anna)
Date: Thu, 5 Aug 2021 18:27:47 -0500
Subject: [PATCH v2 1/5] remoteproc: Add support for detach-only during
 shutdown
In-Reply-To: <20210805173506.GF3205691@p14s>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-2-s-anna@ti.com> <20210802184431.GC3051951@p14s>
 <cd399fef-6db7-72eb-933f-7454a043ed14@ti.com> <20210803162311.GB3091608@p14s>
 <7e264184-60ea-a035-7bd3-1fc2c76a160d@ti.com> <20210805173506.GF3205691@p14s>
Message-ID: <f7f6d096-3fea-47d4-b482-b874cb3db851@ti.com>

On 8/5/21 12:35 PM, Mathieu Poirier wrote:
> On Wed, Aug 04, 2021 at 02:17:22PM -0500, Suman Anna wrote:
>> Hi Mathieu,
>>
>> On 8/3/21 11:23 AM, Mathieu Poirier wrote:
>>> Good morning,
>>>
>>> On Mon, Aug 02, 2021 at 06:21:38PM -0500, Suman Anna wrote:
>>>> Hi Mathieu,
>>>>
>>>> On 8/2/21 1:44 PM, Mathieu Poirier wrote:
>>>>> On Fri, Jul 23, 2021 at 05:02:44PM -0500, Suman Anna wrote:
>>>>>> The remoteproc core has support for both stopping and detaching a
>>>>>> remote processor that was attached to previously, through both the
>>>>>> remoteproc sysfs and cdev interfaces. The rproc_shutdown() though
>>>>>> unconditionally only uses the stop functionality at present. This
>>>>>> may not be the default desired functionality for all the remoteproc
>>>>>> platform drivers.
>>>>>>
>>>>>> Enhance the remoteproc core logic to key off the presence of the
>>>>>> .stop() ops and allow the individual remoteproc drivers to continue
>>>>>> to use the standard rproc_add() and rproc_del() API. This allows
>>>>>> the remoteproc drivers to only do detach if supported when the driver
>>>>>> is uninstalled, and the remote processor continues to run undisturbed
>>>>>> even after the driver removal.
>>>>>>
>>>>>> Signed-off-by: Suman Anna <s-anna at ti.com>
>>>>>> ---
>>>>>> v2: Addressed various review comments from v1
>>>>>>  - Reworked the logic to not use remoteproc detach_on_shutdown and
>>>>>>    rely only on rproc callback ops
>>>>>>  - Updated the last para of the patch description
>>>>>> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-3-s-anna at ti.com/
>>>>>>
>>>>>>  drivers/remoteproc/remoteproc_cdev.c  | 7 +++++++
>>>>>>  drivers/remoteproc/remoteproc_core.c  | 5 ++++-
>>>>>>  drivers/remoteproc/remoteproc_sysfs.c | 6 ++++++
>>>>>>  3 files changed, 17 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c
>>>>>> index 4ad98b0b8caa..16c932beed88 100644
>>>>>> --- a/drivers/remoteproc/remoteproc_cdev.c
>>>>>> +++ b/drivers/remoteproc/remoteproc_cdev.c
>>>>>> @@ -42,6 +42,13 @@ static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_
>>>>>>  		    rproc->state != RPROC_ATTACHED)
>>>>>>  			return -EINVAL;
>>>>>>  
>>>>>> +		if (rproc->state == RPROC_ATTACHED &&
>>>>>
>>>>> This is already checked just above.
>>>>>
>>>>>> +		    !rproc->ops->stop) {
>>>>
>>>> Well, this is checking for both conditions, and not just the stop ops
>>>> independently. We expect to have .stop() defined normally for both regular
>>>> remoteproc mode and attached mode where you want to stop (and not detach), but
>>>> as you can see, I am supporting only detach and so will not have .stop() defined
>>>>  with RPROC_ATTACHED.
>>>>
>>>>>
>>>>> This is checked in rproc_stop() where -EINVAL is returned if ops::stop has not
>>>>> been provided.
>>>>
>>>> rproc_shutdown() actually doesn't return any status, so all its internal
>>>> checking gets ignored and a success is returned today.
>>>>
>>>
>>> That is correct, and I have suggested to add a return value in my previous
>>> review.
>>
>> Yeah ok. I can add a separate patch fixing that, and couple of these checks then
>> become redundant.
>>
>>>
>>>>>
>>>>>> +			dev_err(&rproc->dev,
>>>>>> +				"stop not supported for this rproc, use detach\n");
>>>>>
>>>>> The standard error message from the shell should be enough here, the same way it
>>>>> is enough when the "start" and "stop" scenarios fail.
>>>>
>>>> Thought this was a bit more informative, but sure this trace can be dropped.
>>>>
>>>>>
>>>>>> +			return -EINVAL;
>>>>>> +		}
>>>>>> +
>>>>>>  		rproc_shutdown(rproc);
>>>>>>  	} else if (!strncmp(cmd, "detach", len)) {
>>>>>>  		if (rproc->state != RPROC_ATTACHED)
>>>>>> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
>>>>>> index 7de5905d276a..ab9e52180b04 100644
>>>>>> --- a/drivers/remoteproc/remoteproc_core.c
>>>>>> +++ b/drivers/remoteproc/remoteproc_core.c
>>>>>> @@ -2075,7 +2075,10 @@ void rproc_shutdown(struct rproc *rproc)
>>>>>>  	if (!atomic_dec_and_test(&rproc->power))
>>>>>>  		goto out;
>>>>>>  
>>>>>> -	ret = rproc_stop(rproc, false);
>>>>>> +	if (rproc->state == RPROC_ATTACHED && !rproc->ops->stop)
>>>>>> +		ret = __rproc_detach(rproc);
>>>>>> +	else
>>>>>> +		ret = rproc_stop(rproc, false);
>>>>>
>>>>> As I indicated in my last review I think rproc_shutdown() and rproc_del() should
>>>>> be decoupled and the right call made in the platform drivers based on the state
>>>>> of the remote processor.  
>>>>
>>>> We have various remoteproc API provided in pairs - rproc_alloc()/rproc_free(),
>>>> rproc_add()/rproc_del(), rproc_boot()/rproc_shutdown() and
>>>> rproc_attach()/rproc_detach(). The drivers are configuring conditions for
>>>> auto-boot and RPROC_DETACHED. The reason they are coupled is primarily because
>>>> of the auto-boot done during rproc_add(). And we handle the RPROC_DETACHED case
>>>> just as well in rproc_boot().
>>>>
>>>
>>> The difference with rproc_boot() is that we are checking only the state of the
>>> remoteproc, everything else related to the remote processor operations is
>>> seamlessly handles by the state machine.  It is also tied to the
>>> rproc_trigger_auto_boot() mechanic - decoupling that would be messy without
>>> bringing any advantages other than keeping with a semantic symmetry.
>>
>> Most of this is actually tied to auto_boot if you think about it, not just the
>> rproc state. If we have auto_boot set to false, then rproc_add() would not do
>> anything, and the decision to start or attach can either be done through the
>> sysfs/cdev or a kernel remoteproc or some consumer driver. And the state machine
>> is getting influenced by this flag. auto-boot is a very useful feature.
>>
>> You are asking is to do things differently between the regular start/stop case
>> and attach/detach case ignoring the auto-boot. The semantic symmetry actually
>> makes it easier to follow the state machine given that there are some internal
>> reference counts as well.
> 
> I am definitely not asking to ignore the auto-boot flag.  All I said is that I
> did not split the semantic in rproc_boot() because of the auto-boot flag and the
> mechanic to handle it.
> 
>>
>> Note that we also have the devres API, and rproc_alloc()/rproc_free() and
>> rproc_add()/rproc_del() form the main remoteproc subsystem API. The drivers
>> would end up using matching calls if we don't have auto_boot.
>>
>>>
>>>> While what you have suggested works, but I am not quite convinced on this
>>>> asymmetric usage, and why this state-machine logic should be split between the
>>>> core and remoteproc drivers differently between attach and detach. To me,
>>>> calling rproc_detach() in remoteproc drivers would have made sense only if they
>>>> are also calling rproc_attach().
>>>
>>> As pointed out above I see rproc_boot() as a special case but if that really
>>> concerns you I'm open to consider patches that will take rproc_attach() out of
>>> rproc_boot(). 
>>>
>>
>> We are talking about a bigger behavioral change to remoteproc core here. So I
>> would definitely want to hear from others as well on this before we spend any
>> time reworking code.
>>
>> Meanwhile, how do I take this series forward? One option I can probably do is
>> turn off auto-boot for early-boot case in my drivers and do the matching
>> attach/detach.
>>
> 
> I don't think there is a need to turn off auto-boot for early boot, rproc_boot()
> will to the right thing.
> 
> As for the way forward, the easiest way I see is to call either rproc_shutdown()
> or rproc_detach() based on rproc->state in rproc_del().  That will work with
> devm_rproc_remove() and it is still possible for platorm drivers to explicitly
> call rproc_shutdown() before rproc_del() to force a remote processor that was
> attached to be switched off when the driver is removed.
> 
> That is all the time I had for remoteproc - I am officially away for the next two weeks.  

Yeah, I can make these modification. Let me spin a v3 with this, most probably
waiting for you when you come back :)

regards
Suman

> 
> Thanks,
> Mathieu
> 
>> regards
>> Suman
>>
>>>>
>>>>
>>>> Conditions such as the above make the core code
>>>>> brittle, difficult to understand and tedious to maintain.
>>>>
>>>> The logic I have added actually makes rproc_shutdown behavior to be on par with
>>>> the rproc_boot().
>>>>
>>>> regards
>>>> Suman
>>>>
>>>>>
>>>>> Thanks,
>>>>> Mathieu
>>>>>
>>>>>>  	if (ret) {
>>>>>>  		atomic_inc(&rproc->power);
>>>>>>  		goto out;
>>>>>> diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
>>>>>> index ea8b89f97d7b..133e766f38d4 100644
>>>>>> --- a/drivers/remoteproc/remoteproc_sysfs.c
>>>>>> +++ b/drivers/remoteproc/remoteproc_sysfs.c
>>>>>> @@ -206,6 +206,12 @@ static ssize_t state_store(struct device *dev,
>>>>>>  		    rproc->state != RPROC_ATTACHED)
>>>>>>  			return -EINVAL;
>>>>>>  
>>>>>> +		if (rproc->state == RPROC_ATTACHED &&
>>>>>> +		    !rproc->ops->stop) {
>>>>>> +			dev_err(&rproc->dev, "stop not supported for this rproc, use detach\n");
>>>>>> +			return -EINVAL;
>>>>>> +		}
>>>>>> +
>>>>>>  		rproc_shutdown(rproc);
>>>>>>  	} else if (sysfs_streq(buf, "detach")) {
>>>>>>  		if (rproc->state != RPROC_ATTACHED)
>>>>>> -- 
>>>>>> 2.32.0
>>>>>>
>>>>
>>



From sboyd at kernel.org  Thu Aug  5 16:49:52 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 16:49:52 -0700
Subject: [v14 02/21] dt-bindings: ARM: Mediatek: Add mmsys document
 binding for MT8192
In-Reply-To: <b98aeeee-c544-3025-cc06-ec04be7ab638@gmail.com>
References: <20210726105719.15793-1-chun-jie.chen@mediatek.com>
 <20210726105719.15793-3-chun-jie.chen@mediatek.com>
 <162740843452.2368309.13157283201271440368@swboyd.mtv.corp.google.com>
 <b98aeeee-c544-3025-cc06-ec04be7ab638@gmail.com>
Message-ID: <162820739221.19113.17602385426851379006@swboyd.mtv.corp.google.com>

Quoting Matthias Brugger (2021-08-05 08:35:09)
> 
> 
> On 27/07/2021 19:53, Stephen Boyd wrote:
> > Quoting Chun-Jie Chen (2021-07-26 03:57:00)
> >> This patch adds the mmsys document binding for MT8192 SoC.
> >>
> >> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> >> Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> >> Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
> >> Acked-by: Rob Herring <robh at kernel.org>
> >> ---
> > 
> > Applied to clk-next
> > 
> 
> Please drop this patch. The mmsys binding will change to yaml in this merge
> window and this will create a merge conflict.
> 

It is particularly difficult to resolve? linux-next maintainers seem to
have resolved it so I'm not very concerned.

https://lore.kernel.org/r/20210728124304.1199-1-broonie at kernel.org


From anitha.chrisanthus at intel.com  Thu Aug  5 16:59:50 2021
From: anitha.chrisanthus at intel.com (Chrisanthus, Anitha)
Date: Thu, 5 Aug 2021 23:59:50 +0000
Subject: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
In-Reply-To: <4dbc29d7-5f88-e3ac-5dab-e2dc5c6a703e@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <YQlbFjbrnyeWv7QP@ravnborg.org>
 <BY5PR11MB41822706053ADEE927E34E628CF09@BY5PR11MB4182.namprd11.prod.outlook.com>
 <4dbc29d7-5f88-e3ac-5dab-e2dc5c6a703e@suse.de>
Message-ID: <BY5PR11MB4182FBA1D240321F7D9BEC7D8CF29@BY5PR11MB4182.namprd11.prod.outlook.com>

Hi Thomas,

> -----Original Message-----
> From: Thomas Zimmermann <tzimmermann at suse.de>
> Sent: Wednesday, August 4, 2021 12:11 AM
> To: Chrisanthus, Anitha <anitha.chrisanthus at intel.com>; Sam Ravnborg
> <sam at ravnborg.org>
> Cc: daniel at ffwll.ch; airlied at linux.ie; alexander.deucher at amd.com;
> christian.koenig at amd.com; liviu.dudau at arm.com; brian.starkey at arm.com;
> bbrezillon at kernel.org; nicolas.ferre at microchip.com;
> maarten.lankhorst at linux.intel.com; mripard at kernel.org; stefan at agner.ch;
> alison.wang at nxp.com; patrik.r.jakobsson at gmail.com; robdclark at gmail.com;
> Dea, Edmund J <edmund.j.dea at intel.com>; sean at poorly.run;
> shawnguo at kernel.org; s.hauer at pengutronix.de; kernel at pengutronix.de;
> jyri.sarha at iki.fi; tomba at kernel.org; Dan.Sneddon at microchip.com;
> tomi.valkeinen at ideasonboard.com; amd-gfx at lists.freedesktop.org; dri-
> devel at lists.freedesktop.org; linux-arm-kernel at lists.infradead.org; linux-arm-
> msm at vger.kernel.org; freedreno at lists.freedesktop.org
> Subject: Re: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
> 
> Hi
> 
> Am 03.08.21 um 20:36 schrieb Chrisanthus, Anitha:
> > Hi Thomas,
> > Can you please hold off on applying the kmb patch, I am seeing some issues
> while testing. Modetest works, but video playback only plays once, and it fails
> the second time with this patch.
> 
> Sounds a bit like the testing issue at [1]. For testing, you need the
> latest drm-misc-next or drm-tip. Specifically, you need commit
> 1e4cd78ed493 ("drm: Don't test for IRQ support in VBLANK ioctls").


You are right, with the above patch video plays fine. It's all good now! Sorry about the confusion.
> 
> Let me know whether this works for you.
> 
> Best regards
> Thomas
> 
> [1] https://patchwork.freedesktop.org/patch/447057/?series=93078&rev=1
> 
> >
> > Thanks,
> > Anitha
> >
> >
> >> -----Original Message-----
> >> From: Sam Ravnborg <sam at ravnborg.org>
> >> Sent: Tuesday, August 3, 2021 8:05 AM
> >> To: Thomas Zimmermann <tzimmermann at suse.de>
> >> Cc: daniel at ffwll.ch; airlied at linux.ie; alexander.deucher at amd.com;
> >> christian.koenig at amd.com; liviu.dudau at arm.com;
> brian.starkey at arm.com;
> >> bbrezillon at kernel.org; nicolas.ferre at microchip.com;
> >> maarten.lankhorst at linux.intel.com; mripard at kernel.org;
> stefan at agner.ch;
> >> alison.wang at nxp.com; patrik.r.jakobsson at gmail.com; Chrisanthus, Anitha
> >> <anitha.chrisanthus at intel.com>; robdclark at gmail.com; Dea, Edmund J
> >> <edmund.j.dea at intel.com>; sean at poorly.run; shawnguo at kernel.org;
> >> s.hauer at pengutronix.de; kernel at pengutronix.de; jyri.sarha at iki.fi;
> >> tomba at kernel.org; Dan.Sneddon at microchip.com;
> >> tomi.valkeinen at ideasonboard.com; amd-gfx at lists.freedesktop.org; dri-
> >> devel at lists.freedesktop.org; linux-arm-kernel at lists.infradead.org; linux-
> arm-
> >> msm at vger.kernel.org; freedreno at lists.freedesktop.org
> >> Subject: Re: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
> >>
> >> Hi Thomas,
> >>
> >> On Tue, Aug 03, 2021 at 11:06:50AM +0200, Thomas Zimmermann wrote:
> >>> DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
> >>> the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
> >>> IRQ interfaces.
> >>>
> >>> DRM provides IRQ helpers for setting up, receiving and removing IRQ
> >>> handlers. It's an abstraction over plain Linux functions. The code
> >>> is mid-layerish with several callbacks to hook into the rsp drivers.
> >>> Old UMS driver have their interrupts enabled via ioctl, so these
> >>> abstractions makes some sense. Modern KMS manage all their interrupts
> >>> internally. Using the DRM helpers adds indirection without benefits.
> >>>
> >>> Most KMS drivers already use Linux IRQ functions instead of DRM's
> >>> abstraction layer. Patches 1 to 12 convert the remaining ones.
> >>> The patches also resolve a bug for devices without assigned interrupt
> >>> number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
> >>> not detect if the device has no interrupt assigned.
> >>>
> >>> Patch 13 removes an unused function.
> >>>
> >>> Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
> >>> the old non-KMS drivers still use the functionality.
> >>>
> >>> v2:
> >>> 	* drop IRQ_NOTCONNECTED test from atmel-hlcdc (Sam)
> >>> 	* use devm_request_irq() in atmel-hlcdc (Sam)
> >>> 	* unify variable names in arm/hlcdc (Sam)
> >>>
> >>> Thomas Zimmermann (14):
> >>
> >> The following patches are all:
> >> Acked-by: Sam Ravnborg <sam at ravnborg.org>
> >>
> >>>    drm/fsl-dcu: Convert to Linux IRQ interfaces
> >>>    drm/gma500: Convert to Linux IRQ interfaces
> >>>    drm/kmb: Convert to Linux IRQ interfaces
> >>>    drm/msm: Convert to Linux IRQ interfaces
> >>>    drm/mxsfb: Convert to Linux IRQ interfaces
> >>>    drm/tidss: Convert to Linux IRQ interfaces
> >>>    drm/vc4: Convert to Linux IRQ interfaces
> >>>    drm: Remove unused devm_drm_irq_install()
> >>
> >> The remaining patches I either skipped or already had a feedback from
> >> me or I asked a question.
> >>
> >> 	Sam
> 
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 N?rnberg, Germany
> (HRB 36809, AG N?rnberg)
> Gesch?ftsf?hrer: Felix Imend?rffer


From olteanv at gmail.com  Thu Aug  5 17:17:40 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Fri, 6 Aug 2021 03:17:40 +0300
Subject: [PATCH net-next] net: dsa: mt7530: drop untagged frames on
 VLAN-aware ports without PVID
In-Reply-To: <20210805172315.362165-1-dqfext@gmail.com>
References: <20210805172315.362165-1-dqfext@gmail.com>
Message-ID: <20210806001740.cayorz3vlfrvk75l@skbuf>

On Fri, Aug 06, 2021 at 01:23:14AM +0800, DENG Qingfang wrote:
> @@ -1624,11 +1631,26 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
>  	if (pvid) {
>  		priv->ports[port].pvid = vlan->vid;
>  
> +		/* Accept all frames if PVID is set */
> +		mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
> +			   MT7530_VLAN_ACC_ALL);
> +
>  		/* Only configure PVID if VLAN filtering is enabled */
>  		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
>  			mt7530_rmw(priv, MT7530_PPBV1_P(port),
>  				   G0_PORT_VID_MASK,
>  				   G0_PORT_VID(vlan->vid));
> +	} else if (priv->ports[port].pvid == vlan->vid) {
> +		/* This VLAN is overwritten without PVID, so unset it */
> +		priv->ports[port].pvid = G0_PORT_VID_DEF;
> +
> +		/* Only accept tagged frames if the port is VLAN-aware */
> +		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
> +			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
> +				   MT7530_VLAN_ACC_TAGGED);
> +
> +		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
> +			   G0_PORT_VID_DEF);
>  	}
>  
>  	mutex_unlock(&priv->reg_mutex);

Good catch with this condition, sja1105 and ocelot are buggy in this
regard, it seems, probably others too. Need to fix them. Although
honestly I would probably rather spend the time patching the bridge
already to not accept duplicate VLAN entries from user space, just with
different flags, it's just too complex to handle the overwrites everywhere...
Plus, bridge accepting duplicate VLANs means we cannot refcount them on
DSA and CPU ports at the cross-chip level, which in turn means we can
never delete them from those ports.

Anyhow, enough rambling.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From sboyd at kernel.org  Thu Aug  5 17:26:16 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 17:26:16 -0700
Subject: About clk maintainership [Was: Re: [PULL] Add variants of
 devm_clk_get for prepared and enabled clocks enabled clocks]
In-Reply-To: <20210803104012.wf2buscbukxufesl@pengutronix.de>
References: <20210723091331.wl33wtcvvnejuhau@pengutronix.de>
 <20210728202547.7uvfwflpruku7yps@pengutronix.de>
 <20210728204033.GF22278@shell.armlinux.org.uk>
 <162771727997.714452.2303764341103276867@swboyd.mtv.corp.google.com>
 <20210731120004.i3affxw7upl5y4c5@pengutronix.de>
 <20210802094810.GJ22278@shell.armlinux.org.uk>
 <20210802152755.ibisunvibmwhiyry@pengutronix.de>
 <20210802163824.GK22278@shell.armlinux.org.uk>
 <162797831443.714452.3551045763456936564@swboyd.mtv.corp.google.com>
 <20210803104012.wf2buscbukxufesl@pengutronix.de>
Message-ID: <162820957661.19113.17221558053361108175@swboyd.mtv.corp.google.com>

Quoting Uwe Kleine-K?nig (2021-08-03 03:40:12)
> On Tue, Aug 03, 2021 at 01:11:54AM -0700, Stephen Boyd wrote:
> > 
> > Maybe this series would be more compelling if those various drivers that
> > are hand rolling the devm action were converted to the consolidated
> > official devm function. The truth is it's already happening in various
> > subsystems so consolidating that logic into one place would be a win
> > code size wise and very hard to ignore.
> > 
> > Doing
> > 
> >  $ git grep devm_add_action | grep clk
> > 
> > seems to catch quite a few of them.
> 
> Another upside is that grepping for these drivers with a potential for
> further improvement become easier to grep for as
> devm_clk_get_{prepared,enabled} is a much better hint :-)

Sorry, but that's a pretty weak argument. I'd think grepping for the
absence of pm_ops in drivers would be the same hint.

> 
> The changes to these drivers probably won't go through a clk tree, so
> adding these patches before adding devm_clk_get_enabled() would only
> help for the warm and cozy feeling that it is right to do so, correct?

It isn't to feel warm and cozy. It's to demonstrate the need for
consolidating code. Converting the i2c and spi drivers to use this is
actively damaging the cause though. Those driver frameworks are more
likely to encourage proper power management around bus transfers, so
converting them to use the devm API moves them away from power
management, not closer to it.

This proves why this topic is always contentious. It's too easy to
blindly convert drivers to get the clk and leave it enabled forever and
then they never use power management. The janitors win and nobody else.

Is there some way to avoid that trap? Maybe through some combination of
a device PM function that indicates the driver has no runtime PM
callbacks (pm_runtime_no_callbacks() perhaps?) and
devm_clk_get_enabled() checking for that and returning the clk only when
that call has been made (i.e. pm_runtime_has_no_callbacks())? This
approach would fail to catch the case where system wide suspend/resume
could turn the clk off but the driver doesn't do it. I'm not sure how
much we care about that case though.

> 
> As my focus is limited to (mostly) drivers/pwm and I already have quite
> some other patch quests on my list:

Don't we all? :)


From sboyd at kernel.org  Thu Aug  5 17:30:19 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 17:30:19 -0700
Subject: [PATCH v4 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <20210802144529.1520-4-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
 <20210802144529.1520-4-pali@kernel.org>
Message-ID: <162820981926.19113.12529765873453602213@swboyd.mtv.corp.google.com>

> diff --git a/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> new file mode 100644
> index 000000000000..5ef04f3affda
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> @@ -0,0 +1,49 @@
> +# SPDX-License-Identifier: GPL-2.0
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/marvell,armada-3700-uart-clock#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +title: Marvell Armada 3720 UART clocks

Please add a newline here

> +properties:
> +  compatible:
> +    const: marvell,armada-3700-uart-clock

Please add a newline here

> +  reg:
> +    items:
> +      - description: UART Clock Control Register
> +      - description: UART 2 Baud Rate Divisor Register

Please add a newline here

> +  clocks:
> +    description: |
> +      List of parent clocks suitable for UART from following set:
> +        "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal"
> +      UART clock can use one from this set and when more are provided
> +      then kernel would choose and configure the most suitable one.
> +      It is suggest to specify at least one TBG clock to achieve
> +      baudrates above 230400 and also to specify clock which bootloader
> +      used for UART (most probably xtal) for smooth boot log on UART.

Please use items and const like clock-names for the clocks property. The
description makes me feel like the DT is configuring the choices
available. Ideally, the clocks and clock-names properties are fixed in
length and never change unless the compatible changes.

Please add a newline here

> +  clock-names:
> +    items:
> +      - const: TBG-A-P
> +      - const: TBG-B-P
> +      - const: TBG-A-S
> +      - const: TBG-B-S
> +      - const: xtal
> +    minItems: 1
> +    maxItems: 5

Please add a newline here

> +  '#clock-cells':
> +    const: 1

Please add a newline here

> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - '#clock-cells'

Please add a newline here

> +additionalProperties: false

Please add a newline here

> +examples:
> +  - |
> +    uartclk: uartclk at 12000 {
> +      compatible = "marvell,armada-3700-uart-clock";
> +      reg = <0x12010 0x4>, <0x12210 0x4>;
> +      clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>, <&xtalclk>;
> +      clock-names = "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal";
> +      #clock-cells = <1>;
> +    };


From quanyang.wang at windriver.com  Thu Aug  5 17:41:41 2021
From: quanyang.wang at windriver.com (quanyang.wang)
Date: Fri, 6 Aug 2021 08:41:41 +0800
Subject: [PATCH] spi: spi-zynq-qspi: use wait_for_completion_timeout to
 make zynq_qspi_exec_mem_op not interruptible
In-Reply-To: <20210730031753.1317917-1-quanyang.wang@windriver.com>
References: <20210730031753.1317917-1-quanyang.wang@windriver.com>
Message-ID: <e639bfc1-ce6f-c5d3-6412-70d03706127d@windriver.com>

ping.

On 7/30/21 11:17 AM, quanyang.wang at windriver.com wrote:
> From: Quanyang Wang <quanyang.wang at windriver.com>
> 
> The function wait_for_completion_interruptible_timeout will return
> -ERESTARTSYS immediately when receiving SIGKILL signal which is sent
> by "jffs2_gcd_mtd" during umounting jffs2. This will break the SPI memory
> operation because the data transmitting may begin before the command or
> address transmitting completes. Use wait_for_completion_timeout to prevent
> the process from being interruptible.
> 
> Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller")
> Signed-off-by: Quanyang Wang <quanyang.wang at windriver.com>
> ---
>   drivers/spi/spi-zynq-qspi.c | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
> index 9262c6418463..cfa222c9bd5e 100644
> --- a/drivers/spi/spi-zynq-qspi.c
> +++ b/drivers/spi/spi-zynq-qspi.c
> @@ -545,7 +545,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
>   		zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
>   		zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
>   				ZYNQ_QSPI_IXR_RXTX_MASK);
> -		if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion,
> +		if (!wait_for_completion_timeout(&xqspi->data_completion,
>   							       msecs_to_jiffies(1000)))
>   			err = -ETIMEDOUT;
>   	}
> @@ -563,7 +563,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
>   		zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
>   		zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
>   				ZYNQ_QSPI_IXR_RXTX_MASK);
> -		if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion,
> +		if (!wait_for_completion_timeout(&xqspi->data_completion,
>   							       msecs_to_jiffies(1000)))
>   			err = -ETIMEDOUT;
>   	}
> @@ -579,7 +579,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
>   		zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
>   		zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
>   				ZYNQ_QSPI_IXR_RXTX_MASK);
> -		if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion,
> +		if (!wait_for_completion_timeout(&xqspi->data_completion,
>   							       msecs_to_jiffies(1000)))
>   			err = -ETIMEDOUT;
>   
> @@ -603,7 +603,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
>   		zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
>   		zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
>   				ZYNQ_QSPI_IXR_RXTX_MASK);
> -		if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion,
> +		if (!wait_for_completion_timeout(&xqspi->data_completion,
>   							       msecs_to_jiffies(1000)))
>   			err = -ETIMEDOUT;
>   	}
> 


From broonie at kernel.org  Thu Aug  5 17:47:51 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 6 Aug 2021 01:47:51 +0100
Subject: [PATCH] spi: spi-zynq-qspi: use wait_for_completion_timeout to
 make zynq_qspi_exec_mem_op not interruptible
In-Reply-To: <e639bfc1-ce6f-c5d3-6412-70d03706127d@windriver.com>
References: <20210730031753.1317917-1-quanyang.wang@windriver.com>
 <e639bfc1-ce6f-c5d3-6412-70d03706127d@windriver.com>
Message-ID: <20210806004751.GU26252@sirena.org.uk>

On Fri, Aug 06, 2021 at 08:41:41AM +0800, quanyang.wang wrote:
> ping.

Please don't send content free pings and please allow a reasonable time
for review.  People get busy, go on holiday, attend conferences and so 
on so unless there is some reason for urgency (like critical bug fixes)
please allow at least a couple of weeks for review.  If there have been
review comments then people may be waiting for those to be addressed.

Sending content free pings adds to the mail volume (if they are seen at
all) which is often the problem and since they can't be reviewed
directly if something has gone wrong you'll have to resend the patches
anyway, so sending again is generally a better approach though there are
some other maintainers who like them - if in doubt look at how patches
for the subsystem are normally handled.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210806/332a75b2/attachment.sig>

From broonie at kernel.org  Thu Aug  5 17:47:44 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri,  6 Aug 2021 01:47:44 +0100
Subject: [PATCH 1/3] spi: move cs spi_delay to spi_device
In-Reply-To: <20210719091611.15303-1-mason.zhang@mediatek.com>
References: <20210719091611.15303-1-mason.zhang@mediatek.com>
Message-ID: <162821082762.19049.12115037494826323107.b4-ty@kernel.org>

On Mon, 19 Jul 2021 17:16:12 +0800, Mason Zhang wrote:
> As we know, spi core layer has removed spi_set_cs_timing() API.
> So this patch moved spi_delay for cs_timing from spi_controller
> to spi_device, because cs timing should be set by spi_device but
> not controller.

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/3] spi: move cs spi_delay to spi_device
      commit: 8c33ebfeeb597ea953df93f84ea25482d29c664f

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Thu Aug  5 17:47:45 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri,  6 Aug 2021 01:47:45 +0100
Subject: [PATCH 2/3] spi: modify set_cs_timing parameter
In-Reply-To: <20210719091642.24633-1-mason.zhang@mediatek.com>
References: <20210719091642.24633-1-mason.zhang@mediatek.com>
Message-ID: <162821082762.19049.15691152650066711280.b4-ty@kernel.org>

On Mon, 19 Jul 2021 17:16:43 +0800, Mason Zhang wrote:
> No need pass in spi_delay to set_cs_timing callback.

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[2/3] spi: modify set_cs_timing parameter
      commit: 04e6bb0d6bb127bac929fb35edd2dd01613c9520

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Thu Aug  5 17:47:46 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri,  6 Aug 2021 01:47:46 +0100
Subject: [PATCH v3 2/2] spi: modify set_cs_timing parameter
In-Reply-To: <20210804133746.6742-1-Mason.Zhang@mediatek.com>
References: <20210804133746.6742-1-Mason.Zhang@mediatek.com>
Message-ID: <162821082763.19049.17106859300843537737.b4-ty@kernel.org>

On Wed, 4 Aug 2021 21:37:47 +0800, Mason Zhang wrote:
> This patch modified set_cs_timing parameter, no need pass in spi_delay
> to set_cs_timing callback.
> By the way, we modified the mediatek and tegra114 spi driver to fix build err.
> In mediatek spi driver, We have support set absolute time not clk_count,
> and call this function in prepare_message not user's API.
> 
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[2/2] spi: modify set_cs_timing parameter
      commit: 04e6bb0d6bb127bac929fb35edd2dd01613c9520

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Thu Aug  5 17:47:47 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri,  6 Aug 2021 01:47:47 +0100
Subject: [PATCH v3 1/2] spi: move cs spi_delay to spi_device
In-Reply-To: <20210804133716.32040-1-Mason.Zhang@mediatek.com>
References: <20210804133716.32040-1-Mason.Zhang@mediatek.com>
Message-ID: <162821082762.19049.10460753888752180575.b4-ty@kernel.org>

On Wed, 4 Aug 2021 21:37:17 +0800, Mason Zhang wrote:
> As we know, spi core layer has removed spi_set_cs_timing() API.
> So this patch moved spi_delay for cs_timing from spi_controller
> to spi_device, because cs timing should be set by spi_device but
> not controller.
> 
> 
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/2] spi: move cs spi_delay to spi_device
      commit: 8c33ebfeeb597ea953df93f84ea25482d29c664f

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From geraldogabriel at gmail.com  Thu Aug  5 15:03:39 2021
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Thu, 5 Aug 2021 22:03:39 +0000
Subject: [PATCH] ALSA: usb-audio: fix incorrect clock source setting
In-Reply-To: <CAEsQvcvJeAXoVE9FE9vsKNvXMaQYgHZBoPyKfZLT=UA-4BMe_Q@mail.gmail.com>
References: <CAEsQvctJDnsaRTXAGAJ6==juKazoo2=AJrWabLzqE=jCfg5EEA@mail.gmail.com>
 <20210805075401.21170-1-chihhao.chen@mediatek.com>
 <CAEsQvcsvbJdgvAOxkv_kbLohGi676Zrgz4XSFW2o3CWU3Q68Dg@mail.gmail.com>
 <CAEsQvcvJeAXoVE9FE9vsKNvXMaQYgHZBoPyKfZLT=UA-4BMe_Q@mail.gmail.com>
Message-ID: <CAEsQvcvArDwA9aeAm-FN6f9-G0HM0tNDRxXvX9roFQ1koqQKrg@mail.gmail.com>

Chihhao Chen,

Since you're the one with the hardware I believe the bug report for
Samsung should be done by your side.

Maybe Takashi Iwai has somebody in mind that develops audio code for
Samsung and has already contributed to ALSA?

It's best if Takashi Iwai helps you out, and you take the shortcut to
the corporate structure, otherwise the importance of our findings may
be underestimated.

Chihhao Chen, please include the following link in your bug report to
Samsung: https://lore.kernel.org/patchwork/patch/1466711/

I'd politely remind them that the headset requires a very specific
quirk to work with recent Linux, that the patch has entered Linux-Next
however it's a workaround because the headset is apparently breaking
UAC compliance when it sets both Clock Selectors at the same time,
regardless of what Clock Selector we tell it to set via USB Control
Message.

But you're free to do as you wish. I'm sure you'll be fine.

Good luck,
Geraldo Nascimento

On Thu, Aug 5, 2021 at 11:31 PM Geraldo Nascimento
<geraldogabriel at gmail.com> wrote:
>
> Em Qui, 5 de ago de 2021 12:50, Geraldo Nascimento <geraldogabriel at gmail.com> escreveu:
>>
>> > There is no noise and I think this should be a firmware bug.
>
>
> The fact that there's no noise during the echo test itself doesn't mean it's not a firmware bug.
>
> It may just mean the MIC is able to support both 48KHz and 96KHz.
>
> Because from the log we see both Clock Selectors end up selected to pin 1.
>
> Thank you,
> Geraldo Nascimento


From sboyd at kernel.org  Thu Aug  5 18:10:10 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 18:10:10 -0700
Subject: [PATCH v1 1/6] clk: divider: Implement and wire up
 .determine_rate by default
In-Reply-To: <20210702225145.2643303-2-martin.blumenstingl@googlemail.com>
References: <20210702225145.2643303-1-martin.blumenstingl@googlemail.com>
 <20210702225145.2643303-2-martin.blumenstingl@googlemail.com>
Message-ID: <162821221001.19113.3440053309060770787@swboyd.mtv.corp.google.com>

Quoting Martin Blumenstingl (2021-07-02 15:51:40)
> .determine_rate is meant to replace .round_rate. The former comes with a
> benefit which is especially relevant on 32-bit systems: since
> .determine_rate uses an "unsigned long" (compared to a "signed long"
> which is used by .round_rate) the maximum value on 32-bit systems
> increases from 2^31 (or approx. 2.14GHz) to 2^32 (or approx. 4.29GHz).
> 
> Implement .determine_rate in addition to .round_rate so drivers that are
> using clk_divider_{ro_,}ops can benefit from this by default. Keep the
> .round_rate callback for now since some drivers rely on
> clk_divider_ops.round_rate being implemented.
> 
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Aug  5 18:10:18 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 18:10:18 -0700
Subject: [PATCH v1 3/6] clk: bcm2835: Switch to clk_divider.determine_rate
In-Reply-To: <20210702225145.2643303-4-martin.blumenstingl@googlemail.com>
References: <20210702225145.2643303-1-martin.blumenstingl@googlemail.com>
 <20210702225145.2643303-4-martin.blumenstingl@googlemail.com>
Message-ID: <162821221874.19113.16738014912388895260@swboyd.mtv.corp.google.com>

Quoting Martin Blumenstingl (2021-07-02 15:51:42)
> .determine_rate is meant to replace .round_rate in CCF in the future.
> Switch over to .determine_rate now that clk_divider_ops has gained
> support for that.
> 
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> Cc: Nicolas Saenz Julienne <nsaenz at kernel.org>
> Cc: Florian Fainelli <f.fainelli at gmail.com>
> Cc: Ray Jui <rjui at broadcom.com>
> Cc: Scott Branden <sbranden at broadcom.com>
> Cc: bcm-kernel-feedback-list at broadcom.com
> Cc: linux-rpi-kernel at lists.infradead.org
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Aug  5 18:10:26 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 18:10:26 -0700
Subject: [PATCH v1 4/6] clk: stm32f4: Switch to clk_divider.determine_rate
In-Reply-To: <20210702225145.2643303-5-martin.blumenstingl@googlemail.com>
References: <20210702225145.2643303-1-martin.blumenstingl@googlemail.com>
 <20210702225145.2643303-5-martin.blumenstingl@googlemail.com>
Message-ID: <162821222682.19113.14294600581719716007@swboyd.mtv.corp.google.com>

Quoting Martin Blumenstingl (2021-07-02 15:51:43)
> .determine_rate is meant to replace .round_rate in CCF in the future.
> Switch over to .determine_rate now that clk_divider_ops has gained
> support for that.
> 
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Aug  5 18:10:41 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 18:10:41 -0700
Subject: [PATCH v1 5/6] clk: stm32h7: Switch to clk_divider.determine_rate
In-Reply-To: <20210702225145.2643303-6-martin.blumenstingl@googlemail.com>
References: <20210702225145.2643303-1-martin.blumenstingl@googlemail.com>
 <20210702225145.2643303-6-martin.blumenstingl@googlemail.com>
Message-ID: <162821224129.19113.5484324790744582709@swboyd.mtv.corp.google.com>

Quoting Martin Blumenstingl (2021-07-02 15:51:44)
> .determine_rate is meant to replace .round_rate in CCF in the future.
> Switch over to .determine_rate now that clk_divider_ops has gained
> support for that.
> 
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Aug  5 18:10:49 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 18:10:49 -0700
Subject: [PATCH v1 6/6] clk: stm32mp1: Switch to clk_divider.determine_rate
In-Reply-To: <20210702225145.2643303-7-martin.blumenstingl@googlemail.com>
References: <20210702225145.2643303-1-martin.blumenstingl@googlemail.com>
 <20210702225145.2643303-7-martin.blumenstingl@googlemail.com>
Message-ID: <162821224952.19113.2518483135031133024@swboyd.mtv.corp.google.com>

Quoting Martin Blumenstingl (2021-07-02 15:51:45)
> .determine_rate is meant to replace .round_rate in CCF in the future.
> Switch over to .determine_rate now that clk_divider_ops has gained
> support for that.
> 
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Aug  5 18:12:31 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 05 Aug 2021 18:12:31 -0700
Subject: [PATCH 1/1] clk: imx6q: fix uart earlycon unwork
In-Reply-To: <20210702085438.1988087-1-aisheng.dong@nxp.com>
References: <20210702085438.1988087-1-aisheng.dong@nxp.com>
Message-ID: <162821235155.19113.8776442287518434596@swboyd.mtv.corp.google.com>

Quoting Dong Aisheng (2021-07-02 01:54:38)
> The earlycon depends on the bootloader setup UART clocks being retained.
> There're actually two uart clocks (ipg, per) on MX6QDL,
> but the 'Fixes' commit change to register only one which means
> another clock may be disabled during booting phase
> and result in the earlycon unwork.
> 
> Cc: stable at vger.kernel.org # v5.10+
> Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> ---

Applied to clk-fixes


From pcc at google.com  Thu Aug  5 18:48:16 2021
From: pcc at google.com (Peter Collingbourne)
Date: Thu, 5 Aug 2021 18:48:16 -0700
Subject: [PATCH v2] arm64: allow TCR_EL1.TBID0 to be configured
In-Reply-To: <20210729174409.GC31848@arm.com>
References: <20210622051204.3682580-1-pcc@google.com>
 <20210727165109.GB13920@arm.com>
 <CAMn1gO7DcY4tWu0Q7XsZAt-pEmD-4S64sMzu_gARH7Pvc8sP8g@mail.gmail.com>
 <20210728164219.GC7408@arm.com>
 <CAMn1gO4zkXBdW-qzY+15Q=Pk7E-x3vR-PXmKRakyE4Wr87Xhdg@mail.gmail.com>
 <20210729174409.GC31848@arm.com>
Message-ID: <CAMn1gO52j=m=vxdh2GFLH57pcPmqoorXQsT9YM7jWNGFL4wr9Q@mail.gmail.com>

On Thu, Jul 29, 2021 at 10:44 AM Catalin Marinas
<catalin.marinas at arm.com> wrote:
>
> On Wed, Jul 28, 2021 at 04:50:07PM -0700, Peter Collingbourne wrote:
> > On Wed, Jul 28, 2021 at 9:42 AM Catalin Marinas <catalin.marinas at arm.com> wrote:
> > > On Tue, Jul 27, 2021 at 03:00:10PM -0700, Peter Collingbourne wrote:
> > > > On Tue, Jul 27, 2021 at 9:51 AM Catalin Marinas <catalin.marinas at arm.com> wrote:
> > > > > On Mon, Jun 21, 2021 at 10:12:04PM -0700, Peter Collingbourne wrote:
> > > > > > Introduce a command line flag that controls whether TCR_EL1.TBID0
> > > > > > is set at boot time. Since this is a change to the userspace ABI the
> > > > > > option defaults to off for now, although it seems likely that we'll
> > > > > > be able to change the default at some future point.
> > > > > >
> > > > > > Setting TCR_EL1.TBID0 increases the number of signature bits used by
> > > > > > the pointer authentication instructions for instruction addresses by 8,
> > > > > > which improves the security of pointer authentication, but it also has
> > > > > > the consequence of changing the operation of the branch instructions
> > > > > > so that they no longer ignore the top byte of the target address but
> > > > > > instead fault if they are non-zero.
> > > > >
> > > > > I'm a bit uneasy about the ABI change and not so keen on constraining
> > > > > the ABI through the kernel command line. Ideally we should make this an
> > > > > opt-in per application (prctl()) but that has some aspects to address
> > > >
> > > > This doesn't necessarily need to be the end state, we can enhance this
> > > > based on need. For example, we could choose to take this patch now and
> > > > later implement the per-process opt-in where the default is controlled
> > > > by the command line.
> > >
> > > What's the risk of an application becoming reliant on the new mode
> > > (TBID0) and breaking with the old one? Probably very small but I haven't
> > > figured out if it's zero. Depending on whether we have PAC or PAC2 (the
> > > latter came with 8.6 but optional in 8.3) with TBID0, there are some
> > > differences on how the PAC/AUT instructions work and the code generated
> > > (XOR with the top bits).
> >
> > I think it would be quite small. On Android, at least to begin with
> > there would be a mixture of devices with different TBID0 settings
> > (devices without PAC support and devices with older kernels would all
> > have this disabled), so I think it would be difficult for an
> > application to depend on it being enabled.
> >
> > > > Or just implement the software-only per-process
> > > > TBID0 almost-disablement which would be much simpler than doing it in
> > > > hardware, if that is enough to satisfy future needs.
> > >
> > > I don't entirely follow this.
> >
> > Sorry, I was referring to my earlier proposal for recovering from
> > tagged PC in the kernel by clearing the tag bits:
> > https://lore.kernel.org/linux-arm-kernel/CAMn1gO7+_JhTUw2gS6jnyRV+TCqprmpuCAfee3RCAhNjoVyy9w at mail.gmail.com/
>
> Ah, sorry, I missed this one (or just paged it out entirely over the
> holiday).
>
> > > > Otherwise we risk adding "unused" complexity to the kernel that we can
> > > > never remove due to API stability guarantees.
> > >
> > > We've had other debates over the years and, in general, if a kernel
> > > change causes apps to break, we'd have to keep the original behaviour.
> > > Are there any plans to fix the JITs tools you discovered?
> >
> > Yes, we would definitely want to fix the JIT issue in the Android
> > platform before rolling out a forward PAC ABI. This would be separate
> > from fixing apps, which would need to opt into MTE (or address tagging
> > via the target API level) anyway. But if it turns out that there are
> > too many apps with these JITs that use MTE or address tagging, I think
> > we would need to come back to the kernel to figure out some way to let
> > these programs run.
>
> OK, I guess we don't yet have a clear view on how many such apps are
> affected.
>
> > > Talking to Will about this he was wondering whether we could make TBID0
> > > on by default and clear the tag in PC if we take a fault (on tagged PC),
> > > restarting the context. PAC shouldn't be affected since we would only
> > > branch to an authenticated (PAC code removed) pointer. If this works,
> > > we'd only affect performance slightly on such apps but don't completely
> > > break them.
> >
> > Right, this sounds exactly like my earlier proposal.
>
> Indeed. Something I haven't figured out yet is whether such handling in
> the kernel would weaken PAC. For example, following a failed AUT (the
> old style which does not trap), the resulting address would cause a
> translation fault. Would the kernel clearing the top byte result in a
> potentially valid address?

Yes, as I mentioned in my earlier message, without enhanced PAC2 the
error code will go to bit 61 or 62, and those would be cleared by the
kernel in the almost-disablement mode. So instruction PAC would be
ineffective on CPUs without that feature.

With enhanced PAC2 and without FPAC the computed PAC will be XORed
with the pointer, so you still have a chance of faulting on a
corrupted pointer (if the PAC bits below 55 do not match) -- basically
the same chance as if TBID0 were disabled.

> > > > > first: (a) this bit is permitted to be cached in the TLB so we'd need
> > > > > some TLBI when setting it (and a clarification in the specs that it is
> > > > > tagged by ASID/VMID, probably fine) and (b) we'd need to context-switch
> > > > > TCR_EL1, with a small performance penalty (I don't think it's
> > > > > significant but worth testing).
> > > >
> > > > So TLBI all of the CPUs on prctl() and context-switch TCR_EL1? I
> > > > thought there would be DOS concerns with the first part of that?
> > >
> > > The DoS problem appears if we need to issue an IPI to all CPUs (like
> > > stop_machine). The TLBI with broadcast handled in hardware should be OK
> > > as it's targeted to a specific ASID. But this would have to be issued
> >
> > I see -- I hadn't realised that this instruction is implemented as a
> > broadcast. So we would just need to issue the instruction from any CPU
> > and we should be good.
>
> Well, as long as it's single-threaded when the prctl() is issued. If
> there are multiple threads, we'd have to synchronise all the CPUs. Such
> requirement is probably not a big deal anyway as it affects the return
> addresses, so it would have to be done early.
>
> > > before any app threads are started, otherwise we'd need to synchronise
> > > TCR_EL1. Given that TBID0 toggling affects PAC, this can only be done
> >
> > Right, so this would be different from everything currently in
> > tagged_addr_ctrl because it would be per-process rather than
> > per-thread. So if this were a true TBID0 control we may even want it
> > as a separate prctl() since there are certainly use cases for changing
> > the other bits of tagged_addr_ctrl while the other threads are
> > running.
>
> Since it's permitted to be cached in the TLB, switching it between
> threads would require TLBI on each switch, so not feasible.
>
> How early is the prctl(PR_TAGGED_ADDR_ENABLE) called? Anyway, it
> probably makes more sense to have a separate control since TBID0 is not
> necessarily linked to hwasan or MTE. We'd want more PAC bits even if
> hwasan or MTE are not deployed.

The prctl is called before any threads are created, so it would be
feasible to turn on TBID0 there as well. Agreed about the separate
control.

> > > safely very early in the application before return addresses get a PAC
> > > code.
> >
> > Right, so maybe the "almost-disablement" would work better since all
> > of the signatures would then still be valid, and you could even have
> > different settings for different threads if you wanted to (e.g. if you
> > arranged to run legacy code only on a specific thread).
>
> Yes, if (a) it doesn't weaken PAC and (b) there are no future plans to
> use code TBI as trapping would make it slower.

As mentioned above it does weaken it, but only on certain CPUs.
According to their technical reference manuals, Cortex-A78C implements
enhanced PAC2, and Cortex-A710 implements both that and FPAC. So the
only publicly known CPU where the almost-disablement would also weaken
PAC is the Apple M1, which doesn't implement FPAC or enhanced PAC2.

I wouldn't put much weight on the fact that PAC is weakened though
anyway -- this mode would just be a way to get legacy applications
running even if slower/less secure.

> I think we need to decide whether full TBI would be any useful going
> forward. One comment from Szabolcs on the previous version was that
> "data only tbi is a more complicated concept than plain tbi". Are there
> any tooling plans to benefit from code TBI? Or any use-cases that would
> be affected? For example, if we decide mmap() to return tagged pointers
> (with a new flag), would JITs want to benefit?

At least on the Android side we have no plans to use those bits, not
even for debugging tools like HWASan. Indeed we would much rather put
those bits to use for PAC. I suppose that it's possible that JITs may
want to use them, but that's not something that we would want to
support on Android. And if such a JIT is portable to Apple platforms
it would need an alternative code path to avoid using the bits anyway
due to TBID0 being enabled on those platforms.

> If we need both data and code TBI to coexist, we should look into a
> per-process control.

It doesn't seem necessary at this point IMHO.

So can we start with the patch that makes this a boot-time control for now?

Peter


From zhang.lyra at gmail.com  Thu Aug  5 19:15:16 2021
From: zhang.lyra at gmail.com (Chunyan Zhang)
Date: Fri, 6 Aug 2021 10:15:16 +0800
Subject: [PATCH v3 09/25] iommu/sprd: Drop IOVA cookie management
In-Reply-To: <5cc86b540faeb0367df9bd6901a15974f0e31c52.1628094601.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <5cc86b540faeb0367df9bd6901a15974f0e31c52.1628094601.git.robin.murphy@arm.com>
Message-ID: <CABOV4+VPX-RK-mz-GDZLD_qNDxmBSc3hQGLkvj4NKP6sGOLSxQ@mail.gmail.com>

On Thu, Aug 5, 2021 at 1:18 AM Robin Murphy <robin.murphy at arm.com> wrote:
>
> The core code bakes its own cookies now.
>
> CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Thank you for the patch!

Acked-by: Chunyan Zhang <zhang.lyra at gmail.com>

>
> ---
>
> v3: Also remove unneeded include
> ---
>  drivers/iommu/sprd-iommu.c | 7 -------
>  1 file changed, 7 deletions(-)
>
> diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
> index 73dfd9946312..27ac818b0354 100644
> --- a/drivers/iommu/sprd-iommu.c
> +++ b/drivers/iommu/sprd-iommu.c
> @@ -8,7 +8,6 @@
>
>  #include <linux/clk.h>
>  #include <linux/device.h>
> -#include <linux/dma-iommu.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/errno.h>
>  #include <linux/iommu.h>
> @@ -144,11 +143,6 @@ static struct iommu_domain *sprd_iommu_domain_alloc(unsigned int domain_type)
>         if (!dom)
>                 return NULL;
>
> -       if (iommu_get_dma_cookie(&dom->domain)) {
> -               kfree(dom);
> -               return NULL;
> -       }
> -
>         spin_lock_init(&dom->pgtlock);
>
>         dom->domain.geometry.aperture_start = 0;
> @@ -161,7 +155,6 @@ static void sprd_iommu_domain_free(struct iommu_domain *domain)
>  {
>         struct sprd_iommu_domain *dom = to_sprd_domain(domain);
>
> -       iommu_put_dma_cookie(domain);
>         kfree(dom);
>  }
>
> --
> 2.25.1
>


From nobuhiro1.iwamatsu at toshiba.co.jp  Thu Aug  5 19:30:17 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Fri, 6 Aug 2021 11:30:17 +0900
Subject: [PATCH v5 2/3] PCI: visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <20210805105908.GA19244@lpieralisi>
References: <20210723221421.113575-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210723221421.113575-3-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210805105908.GA19244@lpieralisi>
Message-ID: <20210806023017.jtd3uk3p7fgupy4m@toshiba.co.jp>

Hi,

Thank you for your review.

On Thu, Aug 05, 2021 at 11:59:08AM +0100, Lorenzo Pieralisi wrote:
> On Sat, Jul 24, 2021 at 07:14:20AM +0900, Nobuhiro Iwamatsu wrote:
> > Add support to PCIe RC controller on Toshiba Visconti ARM SoCs. PCIe
> > controller is based of Synopsys DesignWare PCIe core.
> > 
> > This patch does not yet use the clock framework to control the clock.
> > This will be replaced in the future.
> 
> This is not relevant information. I expect the commit log to describe
> the change and the reasons behind the choices.

OK, I will drop this sentence.

> 
> Speaking of which, I'd like to understand what
> 
> > This patch does not yet use the clock framework to control the clock.
> 
> means and why it can't be done within this series.

Visconti5 has a clock control IP, but the driver for this is still under
development and has not been applied into mainline. Instead, the clock
for this driver is running using DT's fixed-clock. This will be
replaced by a clock driver.

> 
> > Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
> > Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> > 
> > ---
> >  drivers/pci/controller/dwc/Kconfig         |   9 +
> >  drivers/pci/controller/dwc/Makefile        |   1 +
> >  drivers/pci/controller/dwc/pcie-visconti.c | 333 +++++++++++++++++++++
> >  3 files changed, 343 insertions(+)
> >  create mode 100644 drivers/pci/controller/dwc/pcie-visconti.c
> > 

<snip>

> > +
> > +static int
> > +visconti_add_pcie_port(struct visconti_pcie *pcie, struct platform_device *pdev)
> 
> Nit: don't split lines like this, it is better to keep return value
> type and function name in one single line.
> 
> Do it like this:
> 
> static int visconti_add_pcie_port(struct visconti_pcie *pcie,
>  				  struct platform_device *pdev)
> 

OK, I will fix in v6.

> Lorenzo
> 


Best regards,
  Nobuhiro



From dqfext at gmail.com  Thu Aug  5 19:34:23 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Fri,  6 Aug 2021 10:34:23 +0800
Subject: [PATCH net-next] net: dsa: mt7530: drop untagged frames on
 VLAN-aware ports without PVID
In-Reply-To: <20210806001740.cayorz3vlfrvk75l@skbuf>
References: <20210805172315.362165-1-dqfext@gmail.com>
 <20210806001740.cayorz3vlfrvk75l@skbuf>
Message-ID: <20210806023423.519560-1-dqfext@gmail.com>

On Fri, Aug 06, 2021 at 03:17:40AM +0300, Vladimir Oltean wrote:
> 
> Good catch with this condition, sja1105 and ocelot are buggy in this
> regard, it seems, probably others too. Need to fix them. Although
> honestly I would probably rather spend the time patching the bridge
> already to not accept duplicate VLAN entries from user space, just with
> different flags, it's just too complex to handle the overwrites everywhere...
> Plus, bridge accepting duplicate VLANs means we cannot refcount them on
> DSA and CPU ports at the cross-chip level, which in turn means we can
> never delete them from those ports.
> 
> Anyhow, enough rambling.
> 
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

Please allow me to send a v2. This sets the CPU port's PVID to 0
on boot, which causes some undefined behaviour..


From Christine.Zhu at mediatek.com  Thu Aug  5 19:36:04 2021
From: Christine.Zhu at mediatek.com (Christine Zhu)
Date: Fri, 6 Aug 2021 10:36:04 +0800
Subject: [v8,0/2] watchdog: mt8195: add wdt support
Message-ID: <20210806023606.16867-1-Christine.Zhu@mediatek.com>

Supports MT8195 watchdog device. Supports MT8195 watchdog reset-controller feature.

Change since v7:
  -remove "[v7,1/3] dt-bindings: mediatek: mt8195: update mtk-wdt document", because the patch has been applied.

Change since v6:
  -move the reset-controller header file to 'include/dt-bindings/reset', in order to be consistent with [1]
   [1] https://patchwork.kernel.org/project/linux-mediatek/patch/20210714121116.v2.1.I514d9aafff3a062f751b37d3fea7402f67595b86 at changeid/

Change since v5:
  -fix author and license in [v5,2/3].

Change since v4:
  -fix name formatting in Signed-off-bys and author in [v4,3/3].

Change since v3:
  -fix name formatting in Signed-off-bys and author for all the patches.

Change since v2:
  -fix typos in [v2,0/3] [v2,1/3] [v2,2/3].

Change since v1:
  -Remove the unneeded tag in [v1,1/3] [v1,2/3] [v1,3/3]
  -Add of_device_id of MT8195 in [v1,3/3]
  -use more proper prefixes, such as "dt-bindings: mediatek: mt8195:"
  -provide more information in the cover letter

Christine Zhu (2):
  dt-bindings: reset: mt8195: add toprgu reset-controller header file
  watchdog: mediatek: mt8195: add wdt support

 drivers/watchdog/mtk_wdt.c                |  6 +++++
 include/dt-bindings/reset/mt8195-resets.h | 29 +++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt8195-resets.h

--
2.18.0


From Christine.Zhu at mediatek.com  Thu Aug  5 19:36:06 2021
From: Christine.Zhu at mediatek.com (Christine Zhu)
Date: Fri, 6 Aug 2021 10:36:06 +0800
Subject: [v8,2/2] watchdog: mediatek: mt8195: add wdt support
In-Reply-To: <20210806023606.16867-1-Christine.Zhu@mediatek.com>
References: <20210806023606.16867-1-Christine.Zhu@mediatek.com>
Message-ID: <20210806023606.16867-3-Christine.Zhu@mediatek.com>

Support MT8195 watchdog device.

Signed-off-by: Christine Zhu <Christine.Zhu at mediatek.com>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/watchdog/mtk_wdt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index 16b6aff324a7..796fbb048cbe 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -12,6 +12,7 @@
 #include <dt-bindings/reset-controller/mt2712-resets.h>
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include <dt-bindings/reset-controller/mt8192-resets.h>
+#include <dt-bindings/reset/mt8195-resets.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/init.h>
@@ -82,6 +83,10 @@ static const struct mtk_wdt_data mt8192_data = {
 	.toprgu_sw_rst_num = MT8192_TOPRGU_SW_RST_NUM,
 };
 
+static const struct mtk_wdt_data mt8195_data = {
+	.toprgu_sw_rst_num = MT8195_TOPRGU_SW_RST_NUM,
+};
+
 static int toprgu_reset_update(struct reset_controller_dev *rcdev,
 			       unsigned long id, bool assert)
 {
@@ -408,6 +413,7 @@ static const struct of_device_id mtk_wdt_dt_ids[] = {
 	{ .compatible = "mediatek,mt6589-wdt" },
 	{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
 	{ .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
+	{ .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
-- 
2.18.0

From Christine.Zhu at mediatek.com  Thu Aug  5 19:36:05 2021
From: Christine.Zhu at mediatek.com (Christine Zhu)
Date: Fri, 6 Aug 2021 10:36:05 +0800
Subject: [v8,
 1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header
 file
In-Reply-To: <20210806023606.16867-1-Christine.Zhu@mediatek.com>
References: <20210806023606.16867-1-Christine.Zhu@mediatek.com>
Message-ID: <20210806023606.16867-2-Christine.Zhu@mediatek.com>

Add toprgu reset-controller header file for MT8195 platform.

Signed-off-by: Christine Zhu <Christine.Zhu at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 include/dt-bindings/reset/mt8195-resets.h | 29 +++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt8195-resets.h

diff --git a/include/dt-bindings/reset/mt8195-resets.h b/include/dt-bindings/reset/mt8195-resets.h
new file mode 100644
index 000000000000..a26bccc8b957
--- /dev/null
+++ b/include/dt-bindings/reset/mt8195-resets.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)*/
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Christine Zhu <christine.zhu at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8195
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8195
+
+#define MT8195_TOPRGU_CONN_MCU_SW_RST          0
+#define MT8195_TOPRGU_INFRA_GRST_SW_RST        1
+#define MT8195_TOPRGU_APU_SW_RST               2
+#define MT8195_TOPRGU_INFRA_AO_GRST_SW_RST     6
+#define MT8195_TOPRGU_MMSYS_SW_RST             7
+#define MT8195_TOPRGU_MFG_SW_RST               8
+#define MT8195_TOPRGU_VENC_SW_RST              9
+#define MT8195_TOPRGU_VDEC_SW_RST              10
+#define MT8195_TOPRGU_IMG_SW_RST               11
+#define MT8195_TOPRGU_APMIXEDSYS_SW_RST        13
+#define MT8195_TOPRGU_AUDIO_SW_RST             14
+#define MT8195_TOPRGU_CAMSYS_SW_RST            15
+#define MT8195_TOPRGU_EDPTX_SW_RST             16
+#define MT8195_TOPRGU_ADSPSYS_SW_RST           21
+#define MT8195_TOPRGU_DPTX_SW_RST              22
+#define MT8195_TOPRGU_SPMI_MST_SW_RST          23
+
+#define MT8195_TOPRGU_SW_RST_NUM               16
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
-- 
2.18.0

From jiapeng.chong at linux.alibaba.com  Thu Aug  5 19:57:44 2021
From: jiapeng.chong at linux.alibaba.com (Jiapeng Chong)
Date: Fri,  6 Aug 2021 10:57:44 +0800
Subject: [PATCH] drm/rockchip: dsi: make hstt_table static
Message-ID: <1628218664-14230-1-git-send-email-jiapeng.chong@linux.alibaba.com>

This symbol is not used outside of dw-mipi-dsi-rockchip.c, so marks
it static.

Fix the following sparse warning:

drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c:646:13: warning: symbol
'hstt_table' was not declared. Should it be static?

Reported-by: Abaci Robot <abaci at linux.alibaba.com>
Signed-off-by: Jiapeng Chong <jiapeng.chong at linux.alibaba.com>
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index a2262be..12fa3db 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -643,7 +643,7 @@ struct hstt {
 }
 
 /* Table A-3 High-Speed Transition Times */
-struct hstt hstt_table[] = {
+static struct hstt hstt_table[] = {
 	HSTT(  90,  32, 20,  26, 13),
 	HSTT( 100,  35, 23,  28, 14),
 	HSTT( 110,  32, 22,  26, 13),
-- 
1.8.3.1



From linux at roeck-us.net  Thu Aug  5 20:02:31 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 5 Aug 2021 20:02:31 -0700
Subject: [v8, 1/2] dt-bindings: reset: mt8195: add toprgu reset-controller
 header file
In-Reply-To: <20210806023606.16867-2-Christine.Zhu@mediatek.com>
References: <20210806023606.16867-1-Christine.Zhu@mediatek.com>
 <20210806023606.16867-2-Christine.Zhu@mediatek.com>
Message-ID: <daa97d7e-2184-0b1e-3afd-c357b022c966@roeck-us.net>

On 8/5/21 7:36 PM, Christine Zhu wrote:
> Add toprgu reset-controller header file for MT8195 platform.
> 
> Signed-off-by: Christine Zhu <Christine.Zhu at mediatek.com>
> Acked-by: Rob Herring <robh at kernel.org>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
>   include/dt-bindings/reset/mt8195-resets.h | 29 +++++++++++++++++++++++
>   1 file changed, 29 insertions(+)
>   create mode 100644 include/dt-bindings/reset/mt8195-resets.h
> 
> diff --git a/include/dt-bindings/reset/mt8195-resets.h b/include/dt-bindings/reset/mt8195-resets.h
> new file mode 100644
> index 000000000000..a26bccc8b957
> --- /dev/null
> +++ b/include/dt-bindings/reset/mt8195-resets.h
> @@ -0,0 +1,29 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)*/
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Author: Christine Zhu <christine.zhu at mediatek.com>
> + */
> +
> +#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8195
> +#define _DT_BINDINGS_RESET_CONTROLLER_MT8195
> +
> +#define MT8195_TOPRGU_CONN_MCU_SW_RST          0
> +#define MT8195_TOPRGU_INFRA_GRST_SW_RST        1
> +#define MT8195_TOPRGU_APU_SW_RST               2
> +#define MT8195_TOPRGU_INFRA_AO_GRST_SW_RST     6
> +#define MT8195_TOPRGU_MMSYS_SW_RST             7
> +#define MT8195_TOPRGU_MFG_SW_RST               8
> +#define MT8195_TOPRGU_VENC_SW_RST              9
> +#define MT8195_TOPRGU_VDEC_SW_RST              10
> +#define MT8195_TOPRGU_IMG_SW_RST               11
> +#define MT8195_TOPRGU_APMIXEDSYS_SW_RST        13
> +#define MT8195_TOPRGU_AUDIO_SW_RST             14
> +#define MT8195_TOPRGU_CAMSYS_SW_RST            15
> +#define MT8195_TOPRGU_EDPTX_SW_RST             16
> +#define MT8195_TOPRGU_ADSPSYS_SW_RST           21
> +#define MT8195_TOPRGU_DPTX_SW_RST              22
> +#define MT8195_TOPRGU_SPMI_MST_SW_RST          23
> +
> +#define MT8195_TOPRGU_SW_RST_NUM               16
> +
> +#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
> 



From dqfext at gmail.com  Thu Aug  5 20:47:11 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Fri,  6 Aug 2021 11:47:11 +0800
Subject: [PATCH net-next v2] net: dsa: mt7530: drop untagged frames on
 VLAN-aware ports without PVID
Message-ID: <20210806034713.734853-1-dqfext@gmail.com>

The driver currently still accepts untagged frames on VLAN-aware ports
without PVID. Use PVC.ACC_FRM to drop untagged frames in that case.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
v1 -> v2: Avoid setting PVID to 0 on the CPU port.

 drivers/net/dsa/mt7530.c | 32 ++++++++++++++++++++++++++++++--
 drivers/net/dsa/mt7530.h |  7 +++++++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 385e169080d9..07db71f129ee 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1257,9 +1257,11 @@ mt7530_port_set_vlan_unaware(struct dsa_switch *ds, int port)
 		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK,
 			   MT7530_PORT_FALLBACK_MODE);
 
-	mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK,
+	mt7530_rmw(priv, MT7530_PVC_P(port),
+		   VLAN_ATTR_MASK | PVC_EG_TAG_MASK | ACC_FRM_MASK,
 		   VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
-		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+		   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT) |
+		   MT7530_VLAN_ACC_ALL);
 
 	/* Set PVID to 0 */
 	mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
@@ -1297,6 +1299,11 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port)
 			   MT7530_PORT_SECURITY_MODE);
 		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
 			   G0_PORT_VID(priv->ports[port].pvid));
+
+		/* Only accept tagged frames if PVID is not set */
+		if (!priv->ports[port].pvid)
+			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
+				   MT7530_VLAN_ACC_TAGGED);
 	}
 
 	/* Set the port as a user port which is to be able to recognize VID
@@ -1624,11 +1631,26 @@ mt7530_port_vlan_add(struct dsa_switch *ds, int port,
 	if (pvid) {
 		priv->ports[port].pvid = vlan->vid;
 
+		/* Accept all frames if PVID is set */
+		mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
+			   MT7530_VLAN_ACC_ALL);
+
 		/* Only configure PVID if VLAN filtering is enabled */
 		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
 			mt7530_rmw(priv, MT7530_PPBV1_P(port),
 				   G0_PORT_VID_MASK,
 				   G0_PORT_VID(vlan->vid));
+	} else if (vlan->vid && priv->ports[port].pvid == vlan->vid) {
+		/* This VLAN is overwritten without PVID, so unset it */
+		priv->ports[port].pvid = G0_PORT_VID_DEF;
+
+		/* Only accept tagged frames if the port is VLAN-aware */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
+			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
+				   MT7530_VLAN_ACC_TAGGED);
+
+		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
+			   G0_PORT_VID_DEF);
 	}
 
 	mutex_unlock(&priv->reg_mutex);
@@ -1654,6 +1676,12 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port,
 	 */
 	if (priv->ports[port].pvid == vlan->vid) {
 		priv->ports[port].pvid = G0_PORT_VID_DEF;
+
+		/* Only accept tagged frames if the port is VLAN-aware */
+		if (dsa_port_is_vlan_filtering(dsa_to_port(ds, port)))
+			mt7530_rmw(priv, MT7530_PVC_P(port), ACC_FRM_MASK,
+				   MT7530_VLAN_ACC_TAGGED);
+
 		mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK,
 			   G0_PORT_VID_DEF);
 	}
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 4a91d80f51bb..fe4cd2ac26d0 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -238,6 +238,7 @@ enum mt7530_port_mode {
 #define  PVC_EG_TAG_MASK		PVC_EG_TAG(7)
 #define  VLAN_ATTR(x)			(((x) & 0x3) << 6)
 #define  VLAN_ATTR_MASK			VLAN_ATTR(3)
+#define  ACC_FRM_MASK			GENMASK(1, 0)
 
 enum mt7530_vlan_port_eg_tag {
 	MT7530_VLAN_EG_DISABLED = 0,
@@ -249,6 +250,12 @@ enum mt7530_vlan_port_attr {
 	MT7530_VLAN_TRANSPARENT = 3,
 };
 
+enum mt7530_vlan_port_acc_frm {
+	MT7530_VLAN_ACC_ALL = 0,
+	MT7530_VLAN_ACC_TAGGED = 1,
+	MT7530_VLAN_ACC_UNTAGGED = 2,
+};
+
 #define  STAG_VPID			(((x) & 0xffff) << 16)
 
 /* Register for port port-and-protocol based vlan 1 control */
-- 
2.25.1



From dqfext at gmail.com  Thu Aug  5 21:05:27 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Fri,  6 Aug 2021 12:05:27 +0800
Subject: [PATCH net] net: dsa: mt7530: add the missing RxUnicast MIB counter
Message-ID: <20210806040528.735606-1-dqfext@gmail.com>

Add the missing RxUnicast counter.

Fixes: b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 switch")
Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 drivers/net/dsa/mt7530.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 385e169080d9..9d7c52172af5 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -47,6 +47,7 @@ static const struct mt7530_mib_desc mt7530_mib[] = {
 	MIB_DESC(2, 0x48, "TxBytes"),
 	MIB_DESC(1, 0x60, "RxDrop"),
 	MIB_DESC(1, 0x64, "RxFiltering"),
+	MIB_DESC(1, 0x68, "RxUnicast"),
 	MIB_DESC(1, 0x6c, "RxMulticast"),
 	MIB_DESC(1, 0x70, "RxBroadcast"),
 	MIB_DESC(1, 0x74, "RxAlignErr"),
-- 
2.25.1



From tzungbi at google.com  Thu Aug  5 21:15:16 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:16 +0800
Subject: [PATCH v7 00/14] media: mtk-vcodec: support for MT8183 decoder
Message-ID: <20210806041530.4170869-1-tzungbi@google.com>

This series adds support for the stateless API into mtk-vcodec, by first
separating the stateful ops into their own source file, and introducing
a new set of ops suitable for stateless decoding. As such, support for
stateful decoders should remain completely unaffected.

This series has been tested with both MT8183 and MT8173. Decoding was
working for both chips, and in the case of MT8173 no regression has been
spotted.

Patches 1-5 fix a few compliance issues with the decoder and encoder, most
notably by adding support for the START and STOP command for the latter. These
patches were last up until v4 but have been moved to the beginning so they can
be applied sooner.

Patches 6-9 separates the "stateful" part of the driver into its own file and
add support for the new firmware and pixel format used by MT8183.

Patches 10-14 add support for H.264 stateless decoding and MT8183.

Note that a few checkpatch issues have been left unadressed on purpose:
* Conversion from e.g. uint32_t to u32 can't be done without breaking
  consistency. This should be done by a driver-wide patch.
* Some macro warning suggesting parentheses for parameters expanded as struct
  members, which is obviously not applicable here.
* Warnings about adding new files without an update the MAINTAINERS, which is
  irrelevant as the new files are already covered by the existing wildcards.

Changes since v6:
(https://patchwork.linuxtv.org/project/linux-media/cover/20210705053258.1614177-1-acourbot at chromium.org/)
* Fix errors from 'checkpatch.pl --strict'.
* Fix missing kerneldoc issue.
* Fix wrong device minor number reference.

Changes since v5:
* Rebased against latest media tree.
* Applied most suggestions of `checkpatch.pl --strict`. Some proposed fixes were
  not applied because they would require a larger refactoring (i.e. large-scale
  type changes) of the code.
* Applied Reviewed-by and fix suggestions from Tzung-bi.
* Check for ABORT state in vidioc_encoder_cmd.

Changes since v4:
* Reorganized fixup patches first.
* Select MEDIA_CONTROLLER_REQUEST_API.
* Properly capitalize MM21's format description string.
* Reorganize stateless code as suggested by Hans.
* Fix compilation errors when DEBUG is defined.
* Merge double-free fixup patch into the patch that introduced the issue.

Changes since v3:
* Stop checking that controls are set for every request.
* Add V4L2_CID_STATELESS_H264_START_CODE control.
* Stop mapping OUTPUT buffers and getting the NAL type from them, use the
  nal_ref_idc field instead.
* Make V4L2_CID_MIN_BUFFERS_FOR_CAPTURE control stateful-only.
* Set vb2_buffer's field to V4L2_FIELD_NONE in buffer validation hook.

Changes since v2:
* Add follow-up patches fixing support for START/STOP commands for the
  encoder, and stateful decoder.

Alexandre Courbot (8):
  media: mtk-vcodec: vdec: use helpers in VIDIOC_(TRY_)DECODER_CMD
  media: mtk-vcodec: vdec: clamp OUTPUT resolution to hardware limits
  media: mtk-vcodec: make flush buffer reusable by encoder
  media: mtk-vcodec: venc: support START and STOP commands
  media: mtk-vcodec: vdec: handle firmware version field
  media: mtk-vcodec: support version 2 of decoder firmware ABI
  media: add Mediatek's MM21 format
  dt-bindings: media: document mediatek,mt8183-vcodec-dec

Hirokazu Honda (1):
  media: mtk-vcodec: vdec: Support H264 profile control

Yunfei Dong (5):
  media: mtk-vcodec: vdec: move stateful ops into their own file
  media: mtk-vcodec: vdec: support stateless API
  media: mtk-vcodec: vdec: support stateless H.264 decoding
  media: mtk-vcodec: vdec: add media device if using stateless api
  media: mtk-vcodec: enable MT8183 decoder

 .../bindings/media/mediatek-vcodec.txt        |   1 +
 .../media/v4l/pixfmt-reserved.rst             |   7 +
 drivers/media/platform/Kconfig                |   3 +
 drivers/media/platform/mtk-vcodec/Makefile    |   3 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 820 +++---------------
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |  25 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  68 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      | 628 ++++++++++++++
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 360 ++++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  58 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 140 ++-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |   6 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 774 +++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   3 +
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  23 +-
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  43 +-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |   5 +
 drivers/media/v4l2-core/v4l2-ioctl.c          |   1 +
 include/uapi/linux/videodev2.h                |   1 +
 20 files changed, 2241 insertions(+), 729 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c

-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:17 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:17 +0800
Subject: [PATCH v7 01/14] media: mtk-vcodec: vdec: Support H264 profile control
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-2-tzungbi@google.com>

From: Hirokazu Honda <hiroh at chromium.org>

Add H264 profiles supported by the MediaTek 8173 decoder.

Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
[acourbot: fix commit log a bit, move to mtk_vcodec_dec.c]
Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 56d86e59421e..8df8bcfe5e9c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -1421,6 +1421,16 @@ int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
 				V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
 				V4L2_MPEG_VIDEO_VP9_PROFILE_0,
 				0, V4L2_MPEG_VIDEO_VP9_PROFILE_0);
+	/*
+	 * H264. Baseline / Extended decoding is not supported.
+	 */
+	v4l2_ctrl_new_std_menu(&ctx->ctrl_hdl,
+			       &mtk_vcodec_dec_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+			       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+			       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
+			       V4L2_MPEG_VIDEO_H264_PROFILE_MAIN);
 
 	if (ctx->ctrl_hdl.error) {
 		mtk_v4l2_err("Adding control failed %d",
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:18 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:18 +0800
Subject: [PATCH v7 02/14] media: mtk-vcodec: vdec: use helpers in
 VIDIOC_(TRY_)DECODER_CMD
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-3-tzungbi@google.com>

From: Alexandre Courbot <acourbot at chromium.org>

Let's use the dedicated helpers to make sure we get the expected
behavior and remove redundant code.

Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 8df8bcfe5e9c..1a633b485a69 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -484,18 +484,7 @@ static void mtk_vdec_worker(struct work_struct *work)
 static int vidioc_try_decoder_cmd(struct file *file, void *priv,
 				struct v4l2_decoder_cmd *cmd)
 {
-	switch (cmd->cmd) {
-	case V4L2_DEC_CMD_STOP:
-	case V4L2_DEC_CMD_START:
-		if (cmd->flags != 0) {
-			mtk_v4l2_err("cmd->flags=%u", cmd->flags);
-			return -EINVAL;
-		}
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
+	return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd);
 }
 
 
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:19 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:19 +0800
Subject: [PATCH v7 03/14] media: mtk-vcodec: vdec: clamp OUTPUT resolution to
 hardware limits
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-4-tzungbi@google.com>

From: Alexandre Courbot <acourbot at chromium.org>

Calling S_FMT or TRY_FMT on the OUTPUT queue should adjust the
resolution to the limits supported by the hardware. Until now this was
only done on the CAPTURE queue, which could make clients believe that
unsupported resolutions can be used when they set the coded size on the
OUTPUT queue.

In the case of the stateless decoder, the problem was even bigger since
subsequently calling G_FMT on the CAPTURE queue would result in the
unclamped resolution being returned, further inducing the client into
error.

Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 1a633b485a69..16e057f73789 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -649,19 +649,17 @@ static int vidioc_try_fmt(struct v4l2_format *f,
 
 	pix_fmt_mp->field = V4L2_FIELD_NONE;
 
+	pix_fmt_mp->width =
+		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, MTK_VDEC_MAX_W);
+	pix_fmt_mp->height =
+		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, MTK_VDEC_MAX_H);
+
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		pix_fmt_mp->num_planes = 1;
 		pix_fmt_mp->plane_fmt[0].bytesperline = 0;
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		int tmp_w, tmp_h;
 
-		pix_fmt_mp->height = clamp(pix_fmt_mp->height,
-					MTK_VDEC_MIN_H,
-					MTK_VDEC_MAX_H);
-		pix_fmt_mp->width = clamp(pix_fmt_mp->width,
-					MTK_VDEC_MIN_W,
-					MTK_VDEC_MAX_W);
-
 		/*
 		 * Find next closer width align 64, heign align 64, size align
 		 * 64 rectangle
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:20 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:20 +0800
Subject: [PATCH v7 04/14] media: mtk-vcodec: make flush buffer reusable by
 encoder
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-5-tzungbi@google.com>

From: Alexandre Courbot <acourbot at chromium.org>

The flush buffer is a special buffer that tells the decoder driver to
send an empty CAPTURE frame to the client with V4L2_BUF_FLAG_LAST set.

We need similar functionality for the encoder ; however currently the
flush buffer depends on decoder-specific structures and thus cannot be
reused with the encoder.

Fix this by testing for this buffer by its VB2 address, and not through
a dedicated flag stored in a higher-level decoder structure. This also
allows us to remove said flag and simplify the code a bit.

Since the flush buffer should never be used in the stateless decoder,
also add safeguards to check against it.

Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 24 +++++++++----------
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |  2 --
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 12 +---------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  6 +++--
 4 files changed, 16 insertions(+), 28 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 16e057f73789..7edd6266dc6a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -368,8 +368,6 @@ static void mtk_vdec_worker(struct work_struct *work)
 		return;
 	}
 
-	src_buf_info = container_of(src_buf, struct mtk_video_dec_buf,
-				    m2m_buf.vb);
 	dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf,
 				    m2m_buf.vb);
 
@@ -390,7 +388,7 @@ static void mtk_vdec_worker(struct work_struct *work)
 			pfb->base_y.va, &pfb->base_y.dma_addr,
 			&pfb->base_c.dma_addr, pfb->base_y.size);
 
-	if (src_buf_info->lastframe) {
+	if (src_buf == &ctx->empty_flush_buf.vb) {
 		mtk_v4l2_debug(1, "Got empty flush input buffer.");
 		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 
@@ -411,6 +409,10 @@ static void mtk_vdec_worker(struct work_struct *work)
 		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 		return;
 	}
+
+	src_buf_info = container_of(src_buf, struct mtk_video_dec_buf,
+				    m2m_buf.vb);
+
 	buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
 	buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
 	buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused;
@@ -514,8 +516,7 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
 			mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
 			return 0;
 		}
-		v4l2_m2m_buf_queue(ctx->m2m_ctx,
-				   &ctx->empty_flush_buf->m2m_buf.vb);
+		v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
 		v4l2_m2m_try_schedule(ctx->m2m_ctx);
 		break;
 
@@ -1122,7 +1123,6 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
 	unsigned int dpbsize = 1, i = 0;
 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
-	struct mtk_video_dec_buf *buf = NULL;
 	struct mtk_q_data *dst_q_data;
 
 	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p",
@@ -1132,6 +1132,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
 	 * check if this buffer is ready to be used after decode
 	 */
 	if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		struct mtk_video_dec_buf *buf;
+
 		vb2_v4l2 = to_vb2_v4l2_buffer(vb);
 		buf = container_of(vb2_v4l2, struct mtk_video_dec_buf,
 				   m2m_buf.vb);
@@ -1161,8 +1163,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
 		mtk_v4l2_err("No src buffer");
 		return;
 	}
-	buf = container_of(src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
-	if (buf->lastframe) {
+
+	if (src_buf == &ctx->empty_flush_buf.vb) {
 		/* This shouldn't happen. Just in case. */
 		mtk_v4l2_err("Invalid flush buffer.");
 		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
@@ -1267,8 +1269,6 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
 	if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		buf->used = false;
 		buf->queued_in_v4l2 = false;
-	} else {
-		buf->lastframe = false;
 	}
 
 	return 0;
@@ -1294,9 +1294,7 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
 
 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
-			struct mtk_video_dec_buf *buf_info = container_of(
-				 src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
-			if (!buf_info->lastframe)
+			if (src_buf != &ctx->empty_flush_buf.vb)
 				v4l2_m2m_buf_done(src_buf,
 						VB2_BUF_STATE_ERROR);
 		}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index cf26b6c1486a..1f8b7300dce6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -40,7 +40,6 @@ struct vdec_fb {
  * @queued_in_vb2:	Capture buffer is queue in vb2
  * @queued_in_v4l2:	Capture buffer is in v4l2 driver, but not in vb2
  *			queue yet
- * @lastframe:		Intput buffer is last buffer - EOS
  * @error:		An unrecoverable error occurs on this buffer.
  * @frame_buffer:	Decode status, and buffer information of Capture buffer
  *
@@ -52,7 +51,6 @@ struct mtk_video_dec_buf {
 	bool	used;
 	bool	queued_in_vb2;
 	bool	queued_in_v4l2;
-	bool	lastframe;
 	bool	error;
 	struct vdec_fb	frame_buffer;
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index f87dc47d9e63..5ce7f1b83e4e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -81,21 +81,14 @@ static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
 	struct mtk_vcodec_ctx *ctx = NULL;
-	struct mtk_video_dec_buf *mtk_buf = NULL;
 	int ret = 0;
 	struct vb2_queue *src_vq;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
-	mtk_buf = kzalloc(sizeof(*mtk_buf), GFP_KERNEL);
-	if (!mtk_buf) {
-		kfree(ctx);
-		return -ENOMEM;
-	}
 
 	mutex_lock(&dev->dev_mutex);
-	ctx->empty_flush_buf = mtk_buf;
 	ctx->id = dev->id_counter++;
 	v4l2_fh_init(&ctx->fh, video_devdata(file));
 	file->private_data = &ctx->fh;
@@ -121,8 +114,7 @@ static int fops_vcodec_open(struct file *file)
 	}
 	src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 				V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
-	ctx->empty_flush_buf->m2m_buf.vb.vb2_buf.vb2_queue = src_vq;
-	ctx->empty_flush_buf->lastframe = true;
+	ctx->empty_flush_buf.vb.vb2_buf.vb2_queue = src_vq;
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
@@ -162,7 +154,6 @@ static int fops_vcodec_open(struct file *file)
 err_ctrls_setup:
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
-	kfree(ctx->empty_flush_buf);
 	kfree(ctx);
 	mutex_unlock(&dev->dev_mutex);
 
@@ -193,7 +184,6 @@ static int fops_vcodec_release(struct file *file)
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 
 	list_del_init(&ctx->list);
-	kfree(ctx->empty_flush_buf);
 	kfree(ctx);
 	mutex_unlock(&dev->dev_mutex);
 	return 0;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index c6c7672fecfb..cad52d8b1463 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -13,6 +13,7 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
 #include "mtk_vcodec_util.h"
 
@@ -249,7 +250,8 @@ struct vdec_pic_info {
  * @decode_work: worker for the decoding
  * @encode_work: worker for the encoding
  * @last_decoded_picinfo: pic information get from latest decode
- * @empty_flush_buf: a fake size-0 capture buffer that indicates flush
+ * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Only
+ *		     to be used with encoder and stateful decoder.
  *
  * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
@@ -288,7 +290,7 @@ struct mtk_vcodec_ctx {
 	struct work_struct decode_work;
 	struct work_struct encode_work;
 	struct vdec_pic_info last_decoded_picinfo;
-	struct mtk_video_dec_buf *empty_flush_buf;
+	struct v4l2_m2m_buffer empty_flush_buf;
 
 	enum v4l2_colorspace colorspace;
 	enum v4l2_ycbcr_encoding ycbcr_enc;
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:21 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:21 +0800
Subject: [PATCH v7 05/14] media: mtk-vcodec: venc: support START and STOP
 commands
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-6-tzungbi@google.com>

From: Alexandre Courbot <acourbot at chromium.org>

The V4L2 encoder specification requires encoders to support the
V4L2_ENC_CMD_START and V4L2_ENC_CMD_STOP commands. Add support for these
to the mtk-vcodec encoder by reusing the same flush buffer as used by
the decoder driver.

Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
[hsinyi: fix double-free issue if flush buffer was not dequeued by the
time streamoff is called]
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 140 +++++++++++++++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |   6 +-
 3 files changed, 140 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index cad52d8b1463..cb248d8daa7b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -252,6 +252,7 @@ struct vdec_pic_info {
  * @last_decoded_picinfo: pic information get from latest decode
  * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Only
  *		     to be used with encoder and stateful decoder.
+ * @is_flushing: set to true if flushing is in progress.
  *
  * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
@@ -291,6 +292,7 @@ struct mtk_vcodec_ctx {
 	struct work_struct encode_work;
 	struct vdec_pic_info last_decoded_picinfo;
 	struct v4l2_m2m_buffer empty_flush_buf;
+	bool is_flushing;
 
 	enum v4l2_colorspace colorspace;
 	enum v4l2_ycbcr_encoding ycbcr_enc;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 416f356af363..efa53ea573a2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -672,6 +672,7 @@ static int vidioc_venc_dqbuf(struct file *file, void *priv,
 			     struct v4l2_buffer *buf)
 {
 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
+	int ret;
 
 	if (ctx->state == MTK_STATE_ABORT) {
 		mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
@@ -679,7 +680,83 @@ static int vidioc_venc_dqbuf(struct file *file, void *priv,
 		return -EIO;
 	}
 
-	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+	ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+	if (ret)
+		return ret;
+
+	/*
+	 * Complete flush if the user dequeued the 0-payload LAST buffer.
+	 * We check the payload because a buffer with the LAST flag can also
+	 * be seen during resolution changes. If we happen to be flushing at
+	 * that time, the last buffer before the resolution changes could be
+	 * misinterpreted for the buffer generated by the flush and terminate
+	 * it earlier than we want.
+	 */
+	if (!V4L2_TYPE_IS_OUTPUT(buf->type) &&
+	    buf->flags & V4L2_BUF_FLAG_LAST &&
+	    buf->m.planes[0].bytesused == 0 &&
+	    ctx->is_flushing) {
+		/*
+		 * Last CAPTURE buffer is dequeued, we can allow another flush
+		 * to take place.
+		 */
+		ctx->is_flushing = false;
+	}
+
+	return 0;
+}
+
+static int vidioc_encoder_cmd(struct file *file, void *priv,
+			      struct v4l2_encoder_cmd *cmd)
+{
+	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
+	struct vb2_queue *src_vq, *dst_vq;
+	int ret;
+
+	if (ctx->state == MTK_STATE_ABORT) {
+		mtk_v4l2_err("[%d] Call to CMD after unrecoverable error",
+			     ctx->id);
+		return -EIO;
+	}
+
+	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, priv, cmd);
+	if (ret)
+		return ret;
+
+	/* Calling START or STOP is invalid if a flush is in progress */
+	if (ctx->is_flushing)
+		return -EBUSY;
+
+	mtk_v4l2_debug(1, "encoder cmd=%u", cmd->cmd);
+
+	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
+				 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	switch (cmd->cmd) {
+	case V4L2_ENC_CMD_STOP:
+		src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
+					 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+		if (!vb2_is_streaming(src_vq)) {
+			mtk_v4l2_debug(1, "Output stream is off. No need to flush.");
+			return 0;
+		}
+		if (!vb2_is_streaming(dst_vq)) {
+			mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
+			return 0;
+		}
+		ctx->is_flushing = true;
+		v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
+		v4l2_m2m_try_schedule(ctx->m2m_ctx);
+		break;
+
+	case V4L2_ENC_CMD_START:
+		vb2_clear_last_buffer_dequeued(dst_vq);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 const struct v4l2_ioctl_ops mtk_venc_ioctl_ops = {
@@ -715,6 +792,9 @@ const struct v4l2_ioctl_ops mtk_venc_ioctl_ops = {
 
 	.vidioc_g_selection		= vidioc_venc_g_selection,
 	.vidioc_s_selection		= vidioc_venc_s_selection,
+
+	.vidioc_encoder_cmd		= vidioc_encoder_cmd,
+	.vidioc_try_encoder_cmd		= v4l2_m2m_ioctl_try_encoder_cmd,
 };
 
 static int vb2ops_venc_queue_setup(struct vb2_queue *vq,
@@ -882,9 +962,38 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
 			dst_buf->vb2_buf.planes[0].bytesused = 0;
 			v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
 		}
+		/* STREAMOFF on the CAPTURE queue completes any ongoing flush */
+		if (ctx->is_flushing) {
+			struct v4l2_m2m_buffer *b, *n;
+
+			mtk_v4l2_debug(1, "STREAMOFF called while flushing");
+			/*
+			 * STREAMOFF could be called before the flush buffer is
+			 * dequeued. Check whether empty flush buf is still in
+			 * queue before removing it.
+			 */
+			v4l2_m2m_for_each_src_buf_safe(ctx->m2m_ctx, b, n) {
+				if (b == &ctx->empty_flush_buf) {
+					v4l2_m2m_src_buf_remove_by_buf(ctx->m2m_ctx, &b->vb);
+					break;
+				}
+			}
+			ctx->is_flushing = false;
+		}
 	} else {
-		while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)))
-			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+		while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
+			if (src_buf != &ctx->empty_flush_buf.vb)
+				v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+		}
+		if (ctx->is_flushing) {
+			/*
+			 * If we are in the middle of a flush, put the flush
+			 * buffer back into the queue so the next CAPTURE
+			 * buffer gets returned with the LAST flag set.
+			 */
+			v4l2_m2m_buf_queue(ctx->m2m_ctx,
+					   &ctx->empty_flush_buf.vb);
+		}
 	}
 
 	if ((q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
@@ -984,12 +1093,15 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
 {
 	struct venc_enc_param enc_prm;
 	struct vb2_v4l2_buffer *vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
-	struct mtk_video_enc_buf *mtk_buf =
-			container_of(vb2_v4l2, struct mtk_video_enc_buf,
-				     m2m_buf.vb);
-
+	struct mtk_video_enc_buf *mtk_buf;
 	int ret = 0;
 
+	/* Don't upcast the empty flush buffer */
+	if (vb2_v4l2 == &ctx->empty_flush_buf.vb)
+		return 0;
+
+	mtk_buf = container_of(vb2_v4l2, struct mtk_video_enc_buf, m2m_buf.vb);
+
 	memset(&enc_prm, 0, sizeof(enc_prm));
 	if (mtk_buf->param_change == MTK_ENCODE_PARAM_NONE)
 		return 0;
@@ -1075,6 +1187,20 @@ static void mtk_venc_worker(struct work_struct *work)
 	}
 
 	src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+
+	/*
+	 * If we see the flush buffer, send an empty buffer with the LAST flag
+	 * to the client. is_flushing will be reset at the time the buffer
+	 * is dequeued.
+	 */
+	if (src_buf == &ctx->empty_flush_buf.vb) {
+		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
+		dst_buf->flags |= V4L2_BUF_FLAG_LAST;
+		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+		v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
+		return;
+	}
+
 	memset(&frm_buf, 0, sizeof(frm_buf));
 	for (i = 0; i < src_buf->vb2_buf.num_planes ; i++) {
 		frm_buf.fb_addr[i].dma_addr =
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 45d1870c83dd..4167e865b23f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -131,6 +131,7 @@ static int fops_vcodec_open(struct file *file)
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
 	struct mtk_vcodec_ctx *ctx = NULL;
 	int ret = 0;
+	struct vb2_queue *src_vq;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
@@ -157,13 +158,16 @@ static int fops_vcodec_open(struct file *file)
 		goto err_ctrls_setup;
 	}
 	ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_enc, ctx,
-				&mtk_vcodec_enc_queue_init);
+					 &mtk_vcodec_enc_queue_init);
 	if (IS_ERR((__force void *)ctx->m2m_ctx)) {
 		ret = PTR_ERR((__force void *)ctx->m2m_ctx);
 		mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)",
 				ret);
 		goto err_m2m_ctx_init;
 	}
+	src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
+				 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+	ctx->empty_flush_buf.vb.vb2_buf.vb2_queue = src_vq;
 	mtk_vcodec_enc_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:22 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:22 +0800
Subject: [PATCH v7 06/14] media: mtk-vcodec: vdec: move stateful ops into
 their own file
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-7-tzungbi@google.com>

From: Yunfei Dong <yunfei.dong at mediatek.com>

We are planning to add support for stateless decoders to this driver.
Part of the driver will be shared between stateful and stateless
codecs, but a few ops need to be specialized for both. Extract the
stateful part of the driver and move it into its own file, accessible
through ops that the common driver parts can call.

This patch only moves code around and introduces a set of abstractions ;
the behavior of the driver should not be changed in any way. Changes to
code styling has been done to accommodate 'checkpatch.pl --strict'.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
[acourbot: refactor, cleanup and split]
Co-developed-by: Alexandre Courbot <acourbot at chromium.org>
Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
[tzungbi: fix errors from 'checkpatch.pl --strict']
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 737 ++----------------
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |  15 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  10 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      | 627 +++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  41 +
 6 files changed, 750 insertions(+), 681 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 4618d43dbbc8..9c3cbb5b800e 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -11,6 +11,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
 		mtk_vcodec_dec.o \
+		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_pm.o \
 
 mtk-vcodec-enc-y := venc/venc_vp8_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 7edd6266dc6a..a220532802f9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -16,68 +16,18 @@
 #include "vdec_drv_if.h"
 #include "mtk_vcodec_dec_pm.h"
 
-#define OUT_FMT_IDX	0
-#define CAP_FMT_IDX	3
-
-#define MTK_VDEC_MIN_W	64U
-#define MTK_VDEC_MIN_H	64U
 #define DFT_CFG_WIDTH	MTK_VDEC_MIN_W
 #define DFT_CFG_HEIGHT	MTK_VDEC_MIN_H
 
-static const struct mtk_video_fmt mtk_video_formats[] = {
-	{
-		.fourcc = V4L2_PIX_FMT_H264,
-		.type = MTK_FMT_DEC,
-		.num_planes = 1,
-		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_VP8,
-		.type = MTK_FMT_DEC,
-		.num_planes = 1,
-		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_VP9,
-		.type = MTK_FMT_DEC,
-		.num_planes = 1,
-		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_MT21C,
-		.type = MTK_FMT_FRAME,
-		.num_planes = 2,
-	},
-};
-
-static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
-	{
-		.fourcc	= V4L2_PIX_FMT_H264,
-		.stepwise = {  MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
-				MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
-	},
-	{
-		.fourcc	= V4L2_PIX_FMT_VP8,
-		.stepwise = {  MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
-				MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_VP9,
-		.stepwise = {  MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
-				MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
-	},
-};
-
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
-
-static const struct mtk_video_fmt *mtk_vdec_find_format(struct v4l2_format *f)
+static const struct mtk_video_fmt *
+mtk_vdec_find_format(struct v4l2_format *f,
+		     const struct mtk_vcodec_dec_pdata *dec_pdata)
 {
 	const struct mtk_video_fmt *fmt;
 	unsigned int k;
 
-	for (k = 0; k < NUM_FORMATS; k++) {
-		fmt = &mtk_video_formats[k];
+	for (k = 0; k < dec_pdata->num_formats; k++) {
+		fmt = &dec_pdata->vdec_formats[k];
 		if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
 			return fmt;
 	}
@@ -94,395 +44,6 @@ static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
 	return &ctx->q_data[MTK_Q_DATA_DST];
 }
 
-/*
- * This function tries to clean all display buffers, the buffers will return
- * in display order.
- * Note the buffers returned from codec driver may still be in driver's
- * reference list.
- */
-static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
-{
-	struct vdec_fb *disp_frame_buffer = NULL;
-	struct mtk_video_dec_buf *dstbuf;
-	struct vb2_v4l2_buffer *vb;
-
-	mtk_v4l2_debug(3, "[%d]", ctx->id);
-	if (vdec_if_get_param(ctx,
-			GET_PARAM_DISP_FRAME_BUFFER,
-			&disp_frame_buffer)) {
-		mtk_v4l2_err("[%d]Cannot get param : GET_PARAM_DISP_FRAME_BUFFER",
-			ctx->id);
-		return NULL;
-	}
-
-	if (disp_frame_buffer == NULL) {
-		mtk_v4l2_debug(3, "No display frame buffer");
-		return NULL;
-	}
-
-	dstbuf = container_of(disp_frame_buffer, struct mtk_video_dec_buf,
-				frame_buffer);
-	vb = &dstbuf->m2m_buf.vb;
-	mutex_lock(&ctx->lock);
-	if (dstbuf->used) {
-		vb2_set_plane_payload(&vb->vb2_buf, 0,
-				      ctx->picinfo.fb_sz[0]);
-		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
-			vb2_set_plane_payload(&vb->vb2_buf, 1,
-					      ctx->picinfo.fb_sz[1]);
-
-		mtk_v4l2_debug(2,
-				"[%d]status=%x queue id=%d to done_list %d",
-				ctx->id, disp_frame_buffer->status,
-				vb->vb2_buf.index,
-				dstbuf->queued_in_vb2);
-
-		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
-		ctx->decoded_frame_cnt++;
-	}
-	mutex_unlock(&ctx->lock);
-	return &vb->vb2_buf;
-}
-
-/*
- * This function tries to clean all capture buffers that are not used as
- * reference buffers by codec driver any more
- * In this case, we need re-queue buffer to vb2 buffer if user space
- * already returns this buffer to v4l2 or this buffer is just the output of
- * previous sps/pps/resolution change decode, or do nothing if user
- * space still owns this buffer
- */
-static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
-{
-	struct mtk_video_dec_buf *dstbuf;
-	struct vdec_fb *free_frame_buffer = NULL;
-	struct vb2_v4l2_buffer *vb;
-
-	if (vdec_if_get_param(ctx,
-				GET_PARAM_FREE_FRAME_BUFFER,
-				&free_frame_buffer)) {
-		mtk_v4l2_err("[%d] Error!! Cannot get param", ctx->id);
-		return NULL;
-	}
-	if (free_frame_buffer == NULL) {
-		mtk_v4l2_debug(3, " No free frame buffer");
-		return NULL;
-	}
-
-	mtk_v4l2_debug(3, "[%d] tmp_frame_addr = 0x%p",
-			ctx->id, free_frame_buffer);
-
-	dstbuf = container_of(free_frame_buffer, struct mtk_video_dec_buf,
-				frame_buffer);
-	vb = &dstbuf->m2m_buf.vb;
-
-	mutex_lock(&ctx->lock);
-	if (dstbuf->used) {
-		if ((dstbuf->queued_in_vb2) &&
-		    (dstbuf->queued_in_v4l2) &&
-		    (free_frame_buffer->status == FB_ST_FREE)) {
-			/*
-			 * After decode sps/pps or non-display buffer, we don't
-			 * need to return capture buffer to user space, but
-			 * just re-queue this capture buffer to vb2 queue.
-			 * This reduce overheads that dq/q unused capture
-			 * buffer. In this case, queued_in_vb2 = true.
-			 */
-			mtk_v4l2_debug(2,
-				"[%d]status=%x queue id=%d to rdy_queue %d",
-				ctx->id, free_frame_buffer->status,
-				vb->vb2_buf.index,
-				dstbuf->queued_in_vb2);
-			v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
-		} else if (!dstbuf->queued_in_vb2 && dstbuf->queued_in_v4l2) {
-			/*
-			 * If buffer in v4l2 driver but not in vb2 queue yet,
-			 * and we get this buffer from free_list, it means
-			 * that codec driver do not use this buffer as
-			 * reference buffer anymore. We should q buffer to vb2
-			 * queue, so later work thread could get this buffer
-			 * for decode. In this case, queued_in_vb2 = false
-			 * means this buffer is not from previous decode
-			 * output.
-			 */
-			mtk_v4l2_debug(2,
-					"[%d]status=%x queue id=%d to rdy_queue",
-					ctx->id, free_frame_buffer->status,
-					vb->vb2_buf.index);
-			v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
-			dstbuf->queued_in_vb2 = true;
-		} else {
-			/*
-			 * Codec driver do not need to reference this capture
-			 * buffer and this buffer is not in v4l2 driver.
-			 * Then we don't need to do any thing, just add log when
-			 * we need to debug buffer flow.
-			 * When this buffer q from user space, it could
-			 * directly q to vb2 buffer
-			 */
-			mtk_v4l2_debug(3, "[%d]status=%x err queue id=%d %d %d",
-					ctx->id, free_frame_buffer->status,
-					vb->vb2_buf.index,
-					dstbuf->queued_in_vb2,
-					dstbuf->queued_in_v4l2);
-		}
-		dstbuf->used = false;
-	}
-	mutex_unlock(&ctx->lock);
-	return &vb->vb2_buf;
-}
-
-static void clean_display_buffer(struct mtk_vcodec_ctx *ctx)
-{
-	struct vb2_buffer *framptr;
-
-	do {
-		framptr = get_display_buffer(ctx);
-	} while (framptr);
-}
-
-static void clean_free_buffer(struct mtk_vcodec_ctx *ctx)
-{
-	struct vb2_buffer *framptr;
-
-	do {
-		framptr = get_free_buffer(ctx);
-	} while (framptr);
-}
-
-static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_ctx *ctx)
-{
-	static const struct v4l2_event ev_src_ch = {
-		.type = V4L2_EVENT_SOURCE_CHANGE,
-		.u.src_change.changes =
-		V4L2_EVENT_SRC_CH_RESOLUTION,
-	};
-
-	mtk_v4l2_debug(1, "[%d]", ctx->id);
-	v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
-}
-
-static void mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
-{
-	bool res_chg;
-	int ret = 0;
-
-	ret = vdec_if_decode(ctx, NULL, NULL, &res_chg);
-	if (ret)
-		mtk_v4l2_err("DecodeFinal failed, ret=%d", ret);
-
-	clean_display_buffer(ctx);
-	clean_free_buffer(ctx);
-}
-
-static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
-				unsigned int pixelformat)
-{
-	const struct mtk_video_fmt *fmt;
-	struct mtk_q_data *dst_q_data;
-	unsigned int k;
-
-	dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
-	for (k = 0; k < NUM_FORMATS; k++) {
-		fmt = &mtk_video_formats[k];
-		if (fmt->fourcc == pixelformat) {
-			mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)",
-				dst_q_data->fmt->fourcc, pixelformat);
-			dst_q_data->fmt = fmt;
-			return;
-		}
-	}
-
-	mtk_v4l2_err("Cannot get fourcc(%d), using init value", pixelformat);
-}
-
-static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx)
-{
-	unsigned int dpbsize = 0;
-	int ret;
-
-	if (vdec_if_get_param(ctx,
-				GET_PARAM_PIC_INFO,
-				&ctx->last_decoded_picinfo)) {
-		mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR",
-				ctx->id);
-		return -EINVAL;
-	}
-
-	if (ctx->last_decoded_picinfo.pic_w == 0 ||
-		ctx->last_decoded_picinfo.pic_h == 0 ||
-		ctx->last_decoded_picinfo.buf_w == 0 ||
-		ctx->last_decoded_picinfo.buf_h == 0) {
-		mtk_v4l2_err("Cannot get correct pic info");
-		return -EINVAL;
-	}
-
-	if (ctx->last_decoded_picinfo.cap_fourcc != ctx->picinfo.cap_fourcc &&
-		ctx->picinfo.cap_fourcc != 0)
-		mtk_vdec_update_fmt(ctx, ctx->picinfo.cap_fourcc);
-
-	if ((ctx->last_decoded_picinfo.pic_w == ctx->picinfo.pic_w) ||
-	    (ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h))
-		return 0;
-
-	mtk_v4l2_debug(1,
-			"[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)",
-			ctx->id, ctx->last_decoded_picinfo.pic_w,
-			ctx->last_decoded_picinfo.pic_h,
-			ctx->picinfo.pic_w, ctx->picinfo.pic_h,
-			ctx->last_decoded_picinfo.buf_w,
-			ctx->last_decoded_picinfo.buf_h);
-
-	ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
-	if (dpbsize == 0)
-		mtk_v4l2_err("Incorrect dpb size, ret=%d", ret);
-
-	ctx->dpb_size = dpbsize;
-
-	return ret;
-}
-
-static void mtk_vdec_worker(struct work_struct *work)
-{
-	struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx,
-				decode_work);
-	struct mtk_vcodec_dev *dev = ctx->dev;
-	struct vb2_v4l2_buffer *src_buf, *dst_buf;
-	struct mtk_vcodec_mem buf;
-	struct vdec_fb *pfb;
-	bool res_chg = false;
-	int ret;
-	struct mtk_video_dec_buf *dst_buf_info, *src_buf_info;
-
-	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
-	if (src_buf == NULL) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		mtk_v4l2_debug(1, "[%d] src_buf empty!!", ctx->id);
-		return;
-	}
-
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-	if (dst_buf == NULL) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id);
-		return;
-	}
-
-	dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf,
-				    m2m_buf.vb);
-
-	pfb = &dst_buf_info->frame_buffer;
-	pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
-	pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
-	pfb->base_y.size = ctx->picinfo.fb_sz[0];
-
-	pfb->base_c.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 1);
-	pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 1);
-	pfb->base_c.size = ctx->picinfo.fb_sz[1];
-	pfb->status = 0;
-	mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id);
-
-	mtk_v4l2_debug(3,
-			"id=%d Framebuf  pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx",
-			dst_buf->vb2_buf.index, pfb,
-			pfb->base_y.va, &pfb->base_y.dma_addr,
-			&pfb->base_c.dma_addr, pfb->base_y.size);
-
-	if (src_buf == &ctx->empty_flush_buf.vb) {
-		mtk_v4l2_debug(1, "Got empty flush input buffer.");
-		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-
-		/* update dst buf status */
-		dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
-		mutex_lock(&ctx->lock);
-		dst_buf_info->used = false;
-		mutex_unlock(&ctx->lock);
-
-		vdec_if_decode(ctx, NULL, NULL, &res_chg);
-		clean_display_buffer(ctx);
-		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
-		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
-			vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
-		dst_buf->flags |= V4L2_BUF_FLAG_LAST;
-		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
-		clean_free_buffer(ctx);
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		return;
-	}
-
-	src_buf_info = container_of(src_buf, struct mtk_video_dec_buf,
-				    m2m_buf.vb);
-
-	buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
-	buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
-	buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused;
-	if (!buf.va) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		mtk_v4l2_err("[%d] id=%d src_addr is NULL!!",
-				ctx->id, src_buf->vb2_buf.index);
-		return;
-	}
-	mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
-			ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
-	dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
-	dst_buf->timecode = src_buf->timecode;
-	mutex_lock(&ctx->lock);
-	dst_buf_info->used = true;
-	mutex_unlock(&ctx->lock);
-	src_buf_info->used = true;
-
-	ret = vdec_if_decode(ctx, &buf, pfb, &res_chg);
-
-	if (ret) {
-		mtk_v4l2_err(
-			" <===[%d], src_buf[%d] sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>",
-			ctx->id,
-			src_buf->vb2_buf.index,
-			buf.size,
-			src_buf->vb2_buf.timestamp,
-			dst_buf->vb2_buf.index,
-			ret, res_chg);
-		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-		if (ret == -EIO) {
-			mutex_lock(&ctx->lock);
-			src_buf_info->error = true;
-			mutex_unlock(&ctx->lock);
-		}
-		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
-	} else if (!res_chg) {
-		/*
-		 * we only return src buffer with VB2_BUF_STATE_DONE
-		 * when decode success without resolution change
-		 */
-		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
-	}
-
-	dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
-	clean_display_buffer(ctx);
-	clean_free_buffer(ctx);
-
-	if (!ret && res_chg) {
-		mtk_vdec_pic_info_update(ctx);
-		/*
-		 * On encountering a resolution change in the stream.
-		 * The driver must first process and decode all
-		 * remaining buffers from before the resolution change
-		 * point, so call flush decode here
-		 */
-		mtk_vdec_flush_decoder(ctx);
-		/*
-		 * After all buffers containing decoded frames from
-		 * before the resolution change point ready to be
-		 * dequeued on the CAPTURE queue, the driver sends a
-		 * V4L2_EVENT_SOURCE_CHANGE event for source change
-		 * type V4L2_EVENT_SRC_CH_RESOLUTION
-		 */
-		mtk_vdec_queue_res_chg_event(ctx);
-	}
-	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-}
-
 static int vidioc_try_decoder_cmd(struct file *file, void *priv,
 				struct v4l2_decoder_cmd *cmd)
 {
@@ -551,10 +112,12 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
 {
 	struct mtk_q_data *q_data;
 
+	ctx->dev->vdec_pdata->init_vdec_params(ctx);
+
 	ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
 	ctx->fh.m2m_ctx = ctx->m2m_ctx;
 	ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
-	INIT_WORK(&ctx->decode_work, mtk_vdec_worker);
+	INIT_WORK(&ctx->decode_work, ctx->dev->vdec_pdata->worker);
 	ctx->colorspace = V4L2_COLORSPACE_REC709;
 	ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
 	ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
@@ -564,7 +127,7 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
 	memset(q_data, 0, sizeof(struct mtk_q_data));
 	q_data->visible_width = DFT_CFG_WIDTH;
 	q_data->visible_height = DFT_CFG_HEIGHT;
-	q_data->fmt = &mtk_video_formats[OUT_FMT_IDX];
+	q_data->fmt = ctx->dev->vdec_pdata->default_out_fmt;
 	q_data->field = V4L2_FIELD_NONE;
 
 	q_data->sizeimage[0] = DFT_CFG_WIDTH * DFT_CFG_HEIGHT;
@@ -576,7 +139,7 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
 	q_data->visible_height = DFT_CFG_HEIGHT;
 	q_data->coded_width = DFT_CFG_WIDTH;
 	q_data->coded_height = DFT_CFG_HEIGHT;
-	q_data->fmt = &mtk_video_formats[CAP_FMT_IDX];
+	q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
 	q_data->field = V4L2_FIELD_NONE;
 
 	v4l_bound_align_image(&q_data->coded_width,
@@ -710,11 +273,14 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
 	const struct mtk_video_fmt *fmt;
+	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
+	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
 
-	fmt = mtk_vdec_find_format(f);
+	fmt = mtk_vdec_find_format(f, dec_pdata);
 	if (!fmt) {
-		f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc;
-		fmt = mtk_vdec_find_format(f);
+		f->fmt.pix.pixelformat =
+			ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc;
+		fmt = mtk_vdec_find_format(f, dec_pdata);
 	}
 
 	return vidioc_try_fmt(f, fmt);
@@ -725,11 +291,14 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
 {
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 	const struct mtk_video_fmt *fmt;
+	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
+	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
 
-	fmt = mtk_vdec_find_format(f);
+	fmt = mtk_vdec_find_format(f, dec_pdata);
 	if (!fmt) {
-		f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc;
-		fmt = mtk_vdec_find_format(f);
+		f->fmt.pix.pixelformat =
+			ctx->q_data[MTK_Q_DATA_SRC].fmt->fourcc;
+		fmt = mtk_vdec_find_format(f, dec_pdata);
 	}
 
 	if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
@@ -819,6 +388,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 	struct mtk_q_data *q_data;
 	int ret = 0;
 	const struct mtk_video_fmt *fmt;
+	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
 
 	mtk_v4l2_debug(3, "[%d]", ctx->id);
 
@@ -847,16 +417,16 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		ret = -EBUSY;
 	}
 
-	fmt = mtk_vdec_find_format(f);
+	fmt = mtk_vdec_find_format(f, dec_pdata);
 	if (fmt == NULL) {
 		if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 			f->fmt.pix.pixelformat =
-				mtk_video_formats[OUT_FMT_IDX].fourcc;
-			fmt = mtk_vdec_find_format(f);
+				dec_pdata->default_out_fmt->fourcc;
+			fmt = mtk_vdec_find_format(f, dec_pdata);
 		} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 			f->fmt.pix.pixelformat =
-				mtk_video_formats[CAP_FMT_IDX].fourcc;
-			fmt = mtk_vdec_find_format(f);
+				dec_pdata->default_cap_fmt->fourcc;
+			fmt = mtk_vdec_find_format(f, dec_pdata);
 		}
 	}
 	if (fmt == NULL)
@@ -893,16 +463,17 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 {
 	int i = 0;
 	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
+	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
 
 	if (fsize->index != 0)
 		return -EINVAL;
 
-	for (i = 0; i < NUM_SUPPORTED_FRAMESIZE; ++i) {
-		if (fsize->pixel_format != mtk_vdec_framesizes[i].fourcc)
+	for (i = 0; i < dec_pdata->num_framesizes; ++i) {
+		if (fsize->pixel_format != dec_pdata->vdec_framesizes[i].fourcc)
 			continue;
 
 		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-		fsize->stepwise = mtk_vdec_framesizes[i].stepwise;
+		fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise;
 		if (!(ctx->dev->dec_capability &
 				VCODEC_CAPABILITY_4K_DISABLED)) {
 			mtk_v4l2_debug(3, "4K is enabled");
@@ -925,16 +496,20 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 	return -EINVAL;
 }
 
-static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue)
+static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
+			   bool output_queue)
 {
+	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
+	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
 	const struct mtk_video_fmt *fmt;
 	int i, j = 0;
 
-	for (i = 0; i < NUM_FORMATS; i++) {
-		if (output_queue && (mtk_video_formats[i].type != MTK_FMT_DEC))
+	for (i = 0; i < dec_pdata->num_formats; i++) {
+		if (output_queue &&
+		    dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
 			continue;
 		if (!output_queue &&
-			(mtk_video_formats[i].type != MTK_FMT_FRAME))
+		    dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
 			continue;
 
 		if (j == f->index)
@@ -942,10 +517,10 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue)
 		++j;
 	}
 
-	if (i == NUM_FORMATS)
+	if (i == dec_pdata->num_formats)
 		return -EINVAL;
 
-	fmt = &mtk_video_formats[i];
+	fmt = &dec_pdata->vdec_formats[i];
 	f->pixelformat = fmt->fourcc;
 	f->flags = fmt->flags;
 
@@ -955,13 +530,13 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue)
 static int vidioc_vdec_enum_fmt_vid_cap(struct file *file, void *priv,
 					struct v4l2_fmtdesc *f)
 {
-	return vidioc_enum_fmt(f, false);
+	return vidioc_enum_fmt(f, priv, false);
 }
 
 static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv,
 					struct v4l2_fmtdesc *f)
 {
-	return vidioc_enum_fmt(f, true);
+	return vidioc_enum_fmt(f, priv, true);
 }
 
 static int vidioc_vdec_g_fmt(struct file *file, void *priv,
@@ -1052,11 +627,9 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv,
 	return 0;
 }
 
-static int vb2ops_vdec_queue_setup(struct vb2_queue *vq,
-				unsigned int *nbuffers,
-				unsigned int *nplanes,
-				unsigned int sizes[],
-				struct device *alloc_devs[])
+int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+			    unsigned int *nplanes, unsigned int sizes[],
+			    struct device *alloc_devs[])
 {
 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
 	struct mtk_q_data *q_data;
@@ -1076,7 +649,7 @@ static int vb2ops_vdec_queue_setup(struct vb2_queue *vq,
 		}
 	} else {
 		if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-			*nplanes = 2;
+			*nplanes = q_data->fmt->num_planes;
 		else
 			*nplanes = 1;
 
@@ -1092,7 +665,7 @@ static int vb2ops_vdec_queue_setup(struct vb2_queue *vq,
 	return 0;
 }
 
-static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
+int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
 {
 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct mtk_q_data *q_data;
@@ -1114,129 +687,7 @@ static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
 	return 0;
 }
 
-static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *src_buf;
-	struct mtk_vcodec_mem src_mem;
-	bool res_chg = false;
-	int ret = 0;
-	unsigned int dpbsize = 1, i = 0;
-	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-	struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
-	struct mtk_q_data *dst_q_data;
-
-	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p",
-			ctx->id, vb->vb2_queue->type,
-			vb->index, vb);
-	/*
-	 * check if this buffer is ready to be used after decode
-	 */
-	if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
-		struct mtk_video_dec_buf *buf;
-
-		vb2_v4l2 = to_vb2_v4l2_buffer(vb);
-		buf = container_of(vb2_v4l2, struct mtk_video_dec_buf,
-				   m2m_buf.vb);
-		mutex_lock(&ctx->lock);
-		if (!buf->used) {
-			v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
-			buf->queued_in_vb2 = true;
-			buf->queued_in_v4l2 = true;
-		} else {
-			buf->queued_in_vb2 = false;
-			buf->queued_in_v4l2 = true;
-		}
-		mutex_unlock(&ctx->lock);
-		return;
-	}
-
-	v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
-
-	if (ctx->state != MTK_STATE_INIT) {
-		mtk_v4l2_debug(3, "[%d] already init driver %d",
-				ctx->id, ctx->state);
-		return;
-	}
-
-	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
-	if (!src_buf) {
-		mtk_v4l2_err("No src buffer");
-		return;
-	}
-
-	if (src_buf == &ctx->empty_flush_buf.vb) {
-		/* This shouldn't happen. Just in case. */
-		mtk_v4l2_err("Invalid flush buffer.");
-		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-		return;
-	}
-
-	src_mem.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
-	src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
-	src_mem.size = (size_t)src_buf->vb2_buf.planes[0].bytesused;
-	mtk_v4l2_debug(2,
-			"[%d] buf id=%d va=%p dma=%pad size=%zx",
-			ctx->id, src_buf->vb2_buf.index,
-			src_mem.va, &src_mem.dma_addr,
-			src_mem.size);
-
-	ret = vdec_if_decode(ctx, &src_mem, NULL, &res_chg);
-	if (ret || !res_chg) {
-		/*
-		 * fb == NULL means to parse SPS/PPS header or
-		 * resolution info in src_mem. Decode can fail
-		 * if there is no SPS header or picture info
-		 * in bs
-		 */
-
-		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-		if (ret == -EIO) {
-			mtk_v4l2_err("[%d] Unrecoverable error in vdec_if_decode.",
-					ctx->id);
-			ctx->state = MTK_STATE_ABORT;
-			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
-		} else {
-			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
-		}
-		mtk_v4l2_debug(ret ? 0 : 1,
-			       "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d",
-			       ctx->id, src_buf->vb2_buf.index,
-			       src_mem.size, ret, res_chg);
-		return;
-	}
-
-	if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
-		mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR",
-				ctx->id);
-		return;
-	}
-
-	ctx->last_decoded_picinfo = ctx->picinfo;
-	dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
-	for (i = 0; i < dst_q_data->fmt->num_planes; i++) {
-		dst_q_data->sizeimage[i] = ctx->picinfo.fb_sz[i];
-		dst_q_data->bytesperline[i] = ctx->picinfo.buf_w;
-	}
-
-	mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
-			ctx->id,
-			ctx->picinfo.buf_w, ctx->picinfo.buf_h,
-			ctx->picinfo.pic_w, ctx->picinfo.pic_h,
-			dst_q_data->sizeimage[0],
-			dst_q_data->sizeimage[1]);
-
-	ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
-	if (dpbsize == 0)
-		mtk_v4l2_err("[%d] GET_PARAM_DPB_SIZE fail=%d", ctx->id, ret);
-
-	ctx->dpb_size = dpbsize;
-	ctx->state = MTK_STATE_HEADER;
-	mtk_v4l2_debug(1, "[%d] dpbsize=%d", ctx->id, ctx->dpb_size);
-
-	mtk_vdec_queue_res_chg_event(ctx);
-}
-
-static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
+void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
 {
 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct vb2_v4l2_buffer *vb2_v4l2;
@@ -1259,7 +710,7 @@ static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
 	}
 }
 
-static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
+int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
 					struct vb2_v4l2_buffer, vb2_buf);
@@ -1274,7 +725,7 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
 	return 0;
 }
 
-static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
+int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
 
@@ -1284,10 +735,11 @@ static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
 	return 0;
 }
 
-static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
+void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
 {
 	struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL;
 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
+	int ret;
 
 	mtk_v4l2_debug(3, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d",
 			ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt);
@@ -1319,7 +771,9 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
 				ctx->last_decoded_picinfo.buf_w,
 				ctx->last_decoded_picinfo.buf_h);
 
-		mtk_vdec_flush_decoder(ctx);
+		ret = ctx->dev->vdec_pdata->flush_decoder(ctx);
+		if (ret)
+			mtk_v4l2_err("DecodeFinal failed, ret=%d", ret);
 	}
 	ctx->state = MTK_STATE_FLUSH;
 
@@ -1366,85 +820,12 @@ static void m2mops_vdec_job_abort(void *priv)
 	ctx->state = MTK_STATE_ABORT;
 }
 
-static int mtk_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
-	int ret = 0;
-
-	switch (ctrl->id) {
-	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
-		if (ctx->state >= MTK_STATE_HEADER) {
-			ctrl->val = ctx->dpb_size;
-		} else {
-			mtk_v4l2_debug(0, "Seqinfo not ready");
-			ctrl->val = 0;
-		}
-		break;
-	default:
-		ret = -EINVAL;
-	}
-	return ret;
-}
-
-static const struct v4l2_ctrl_ops mtk_vcodec_dec_ctrl_ops = {
-	.g_volatile_ctrl = mtk_vdec_g_v_ctrl,
-};
-
-int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
-{
-	struct v4l2_ctrl *ctrl;
-
-	v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 1);
-
-	ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl,
-				&mtk_vcodec_dec_ctrl_ops,
-				V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
-				0, 32, 1, 1);
-	ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-	v4l2_ctrl_new_std_menu(&ctx->ctrl_hdl,
-				&mtk_vcodec_dec_ctrl_ops,
-				V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
-				V4L2_MPEG_VIDEO_VP9_PROFILE_0,
-				0, V4L2_MPEG_VIDEO_VP9_PROFILE_0);
-	/*
-	 * H264. Baseline / Extended decoding is not supported.
-	 */
-	v4l2_ctrl_new_std_menu(&ctx->ctrl_hdl,
-			       &mtk_vcodec_dec_ctrl_ops,
-			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,
-			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
-			       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
-			       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
-			       V4L2_MPEG_VIDEO_H264_PROFILE_MAIN);
-
-	if (ctx->ctrl_hdl.error) {
-		mtk_v4l2_err("Adding control failed %d",
-				ctx->ctrl_hdl.error);
-		return ctx->ctrl_hdl.error;
-	}
-
-	v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
-	return 0;
-}
-
 const struct v4l2_m2m_ops mtk_vdec_m2m_ops = {
 	.device_run	= m2mops_vdec_device_run,
 	.job_ready	= m2mops_vdec_job_ready,
 	.job_abort	= m2mops_vdec_job_abort,
 };
 
-static const struct vb2_ops mtk_vdec_vb2_ops = {
-	.queue_setup	= vb2ops_vdec_queue_setup,
-	.buf_prepare	= vb2ops_vdec_buf_prepare,
-	.buf_queue	= vb2ops_vdec_buf_queue,
-	.wait_prepare	= vb2_ops_wait_prepare,
-	.wait_finish	= vb2_ops_wait_finish,
-	.buf_init	= vb2ops_vdec_buf_init,
-	.buf_finish	= vb2ops_vdec_buf_finish,
-	.start_streaming	= vb2ops_vdec_start_streaming,
-	.stop_streaming	= vb2ops_vdec_stop_streaming,
-};
-
 const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = {
 	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
 	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
@@ -1491,7 +872,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
 	src_vq->io_modes	= VB2_DMABUF | VB2_MMAP;
 	src_vq->drv_priv	= ctx;
 	src_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
-	src_vq->ops		= &mtk_vdec_vb2_ops;
+	src_vq->ops		= ctx->dev->vdec_pdata->vdec_vb2_ops;
 	src_vq->mem_ops		= &vb2_dma_contig_memops;
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	src_vq->lock		= &ctx->dev->dev_mutex;
@@ -1506,7 +887,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
 	dst_vq->io_modes	= VB2_DMABUF | VB2_MMAP;
 	dst_vq->drv_priv	= ctx;
 	dst_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
-	dst_vq->ops		= &mtk_vdec_vb2_ops;
+	dst_vq->ops		= ctx->dev->vdec_pdata->vdec_vb2_ops;
 	dst_vq->mem_ops		= &vb2_dma_contig_memops;
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	dst_vq->lock		= &ctx->dev->dev_mutex;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 1f8b7300dce6..76856c0b2db8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -16,6 +16,8 @@
 #define VCODEC_DEC_4K_CODED_HEIGHT	2304U
 #define MTK_VDEC_MAX_W	2048U
 #define MTK_VDEC_MAX_H	1088U
+#define MTK_VDEC_MIN_W	64U
+#define MTK_VDEC_MIN_H	64U
 
 #define MTK_VDEC_IRQ_STATUS_DEC_SUCCESS        0x10000
 
@@ -71,7 +73,18 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
 			   struct vb2_queue *dst_vq);
 void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx);
 void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx);
-int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx);
+
+/*
+ * VB2 ops
+ */
+int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+			    unsigned int *nplanes, unsigned int sizes[],
+			    struct device *alloc_devs[]);
+int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb);
+void vb2ops_vdec_buf_finish(struct vb2_buffer *vb);
+int vb2ops_vdec_buf_init(struct vb2_buffer *vb);
+int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count);
+void vb2ops_vdec_stop_streaming(struct vb2_queue *q);
 
 
 #endif /* _MTK_VCODEC_DEC_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 5ce7f1b83e4e..1460951f302c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -99,7 +99,7 @@ static int fops_vcodec_open(struct file *file)
 	mutex_init(&ctx->lock);
 
 	ctx->type = MTK_INST_DECODER;
-	ret = mtk_vcodec_dec_ctrls_setup(ctx);
+	ret = dev->vdec_pdata->ctrls_setup(ctx);
 	if (ret) {
 		mtk_v4l2_err("Failed to setup mt vcodec controls");
 		goto err_ctrls_setup;
@@ -214,6 +214,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&dev->ctx_list);
 	dev->plat_dev = pdev;
 
+	dev->vdec_pdata = of_device_get_match_data(&pdev->dev);
 	if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vpu",
 				  &rproc_phandle)) {
 		fw_type = VPU;
@@ -341,8 +342,13 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	return ret;
 }
 
+extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata;
+
 static const struct of_device_id mtk_vcodec_match[] = {
-	{.compatible = "mediatek,mt8173-vcodec-dec",},
+	{
+		.compatible = "mediatek,mt8173-vcodec-dec",
+		.data = &mtk_vdec_8173_pdata,
+	},
 	{},
 };
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
new file mode 100644
index 000000000000..d77a7688688a
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -0,0 +1,627 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_intr.h"
+#include "mtk_vcodec_util.h"
+#include "mtk_vcodec_dec_pm.h"
+#include "vdec_drv_if.h"
+
+static const struct mtk_video_fmt mtk_video_formats[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_H264,
+		.type = MTK_FMT_DEC,
+		.num_planes = 1,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_VP8,
+		.type = MTK_FMT_DEC,
+		.num_planes = 1,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_VP9,
+		.type = MTK_FMT_DEC,
+		.num_planes = 1,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_MT21C,
+		.type = MTK_FMT_FRAME,
+		.num_planes = 2,
+	},
+};
+
+#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
+#define DEFAULT_OUT_FMT_IDX 0
+#define DEFAULT_CAP_FMT_IDX 3
+
+static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_H264,
+		.stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
+			      MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_VP8,
+		.stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
+			      MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_VP9,
+		.stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
+			      MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
+	},
+};
+
+#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
+
+/*
+ * This function tries to clean all display buffers, the buffers will return
+ * in display order.
+ * Note the buffers returned from codec driver may still be in driver's
+ * reference list.
+ */
+static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_fb *disp_frame_buffer = NULL;
+	struct mtk_video_dec_buf *dstbuf;
+	struct vb2_v4l2_buffer *vb;
+
+	mtk_v4l2_debug(3, "[%d]", ctx->id);
+	if (vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER,
+			      &disp_frame_buffer)) {
+		mtk_v4l2_err("[%d]Cannot get param : GET_PARAM_DISP_FRAME_BUFFER", ctx->id);
+		return NULL;
+	}
+
+	if (!disp_frame_buffer) {
+		mtk_v4l2_debug(3, "No display frame buffer");
+		return NULL;
+	}
+
+	dstbuf = container_of(disp_frame_buffer, struct mtk_video_dec_buf,
+			      frame_buffer);
+	vb = &dstbuf->m2m_buf.vb;
+	mutex_lock(&ctx->lock);
+	if (dstbuf->used) {
+		vb2_set_plane_payload(&vb->vb2_buf, 0, ctx->picinfo.fb_sz[0]);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			vb2_set_plane_payload(&vb->vb2_buf, 1,
+					      ctx->picinfo.fb_sz[1]);
+
+		mtk_v4l2_debug(2, "[%d]status=%x queue id=%d to done_list %d",
+			       ctx->id, disp_frame_buffer->status,
+			       vb->vb2_buf.index, dstbuf->queued_in_vb2);
+
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
+		ctx->decoded_frame_cnt++;
+	}
+	mutex_unlock(&ctx->lock);
+	return &vb->vb2_buf;
+}
+
+/*
+ * This function tries to clean all capture buffers that are not used as
+ * reference buffers by codec driver any more
+ * In this case, we need re-queue buffer to vb2 buffer if user space
+ * already returns this buffer to v4l2 or this buffer is just the output of
+ * previous sps/pps/resolution change decode, or do nothing if user
+ * space still owns this buffer
+ */
+static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_video_dec_buf *dstbuf;
+	struct vdec_fb *free_frame_buffer = NULL;
+	struct vb2_v4l2_buffer *vb;
+
+	if (vdec_if_get_param(ctx, GET_PARAM_FREE_FRAME_BUFFER,
+			      &free_frame_buffer)) {
+		mtk_v4l2_err("[%d] Error!! Cannot get param", ctx->id);
+		return NULL;
+	}
+	if (!free_frame_buffer) {
+		mtk_v4l2_debug(3, " No free frame buffer");
+		return NULL;
+	}
+
+	mtk_v4l2_debug(3, "[%d] tmp_frame_addr = 0x%p", ctx->id,
+		       free_frame_buffer);
+
+	dstbuf = container_of(free_frame_buffer, struct mtk_video_dec_buf,
+			      frame_buffer);
+	vb = &dstbuf->m2m_buf.vb;
+
+	mutex_lock(&ctx->lock);
+	if (dstbuf->used) {
+		if (dstbuf->queued_in_vb2 && dstbuf->queued_in_v4l2 &&
+		    free_frame_buffer->status == FB_ST_FREE) {
+			/*
+			 * After decode sps/pps or non-display buffer, we don't
+			 * need to return capture buffer to user space, but
+			 * just re-queue this capture buffer to vb2 queue.
+			 * This reduce overheads that dq/q unused capture
+			 * buffer. In this case, queued_in_vb2 = true.
+			 */
+			mtk_v4l2_debug(2, "[%d]status=%x queue id=%d to rdy_queue %d",
+				       ctx->id, free_frame_buffer->status,
+				       vb->vb2_buf.index, dstbuf->queued_in_vb2);
+			v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+		} else if (!dstbuf->queued_in_vb2 && dstbuf->queued_in_v4l2) {
+			/*
+			 * If buffer in v4l2 driver but not in vb2 queue yet,
+			 * and we get this buffer from free_list, it means
+			 * that codec driver do not use this buffer as
+			 * reference buffer anymore. We should q buffer to vb2
+			 * queue, so later work thread could get this buffer
+			 * for decode. In this case, queued_in_vb2 = false
+			 * means this buffer is not from previous decode
+			 * output.
+			 */
+			mtk_v4l2_debug(2,
+				       "[%d]status=%x queue id=%d to rdy_queue",
+				       ctx->id, free_frame_buffer->status,
+				       vb->vb2_buf.index);
+			v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+			dstbuf->queued_in_vb2 = true;
+		} else {
+			/*
+			 * Codec driver do not need to reference this capture
+			 * buffer and this buffer is not in v4l2 driver.
+			 * Then we don't need to do any thing, just add log when
+			 * we need to debug buffer flow.
+			 * When this buffer q from user space, it could
+			 * directly q to vb2 buffer
+			 */
+			mtk_v4l2_debug(3, "[%d]status=%x err queue id=%d %d %d",
+				       ctx->id, free_frame_buffer->status,
+				       vb->vb2_buf.index, dstbuf->queued_in_vb2,
+				       dstbuf->queued_in_v4l2);
+		}
+		dstbuf->used = false;
+	}
+	mutex_unlock(&ctx->lock);
+	return &vb->vb2_buf;
+}
+
+static void clean_display_buffer(struct mtk_vcodec_ctx *ctx)
+{
+	while (get_display_buffer(ctx))
+		;
+}
+
+static void clean_free_buffer(struct mtk_vcodec_ctx *ctx)
+{
+	while (get_free_buffer(ctx))
+		;
+}
+
+static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_ctx *ctx)
+{
+	static const struct v4l2_event ev_src_ch = {
+		.type = V4L2_EVENT_SOURCE_CHANGE,
+		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
+	};
+
+	mtk_v4l2_debug(1, "[%d]", ctx->id);
+	v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
+}
+
+static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
+{
+	bool res_chg;
+	int ret;
+
+	ret = vdec_if_decode(ctx, NULL, NULL, &res_chg);
+	if (ret)
+		mtk_v4l2_err("DecodeFinal failed, ret=%d", ret);
+
+	clean_display_buffer(ctx);
+	clean_free_buffer(ctx);
+
+	return 0;
+}
+
+static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
+				unsigned int pixelformat)
+{
+	const struct mtk_video_fmt *fmt;
+	struct mtk_q_data *dst_q_data;
+	unsigned int k;
+
+	dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
+	for (k = 0; k < NUM_FORMATS; k++) {
+		fmt = &mtk_video_formats[k];
+		if (fmt->fourcc == pixelformat) {
+			mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)",
+				       dst_q_data->fmt->fourcc, pixelformat);
+			dst_q_data->fmt = fmt;
+			return;
+		}
+	}
+
+	mtk_v4l2_err("Cannot get fourcc(%d), using init value", pixelformat);
+}
+
+static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx)
+{
+	unsigned int dpbsize = 0;
+	int ret;
+
+	if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO,
+			      &ctx->last_decoded_picinfo)) {
+		mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id);
+		return -EINVAL;
+	}
+
+	if (ctx->last_decoded_picinfo.pic_w == 0 ||
+	    ctx->last_decoded_picinfo.pic_h == 0 ||
+	    ctx->last_decoded_picinfo.buf_w == 0 ||
+	    ctx->last_decoded_picinfo.buf_h == 0) {
+		mtk_v4l2_err("Cannot get correct pic info");
+		return -EINVAL;
+	}
+
+	if (ctx->last_decoded_picinfo.cap_fourcc != ctx->picinfo.cap_fourcc &&
+	    ctx->picinfo.cap_fourcc != 0)
+		mtk_vdec_update_fmt(ctx, ctx->picinfo.cap_fourcc);
+
+	if (ctx->last_decoded_picinfo.pic_w == ctx->picinfo.pic_w ||
+	    ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h)
+		return 0;
+
+	mtk_v4l2_debug(1, "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", ctx->id,
+		       ctx->last_decoded_picinfo.pic_w,
+		       ctx->last_decoded_picinfo.pic_h, ctx->picinfo.pic_w,
+		       ctx->picinfo.pic_h, ctx->last_decoded_picinfo.buf_w,
+		       ctx->last_decoded_picinfo.buf_h);
+
+	ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
+	if (dpbsize == 0)
+		mtk_v4l2_err("Incorrect dpb size, ret=%d", ret);
+
+	ctx->dpb_size = dpbsize;
+
+	return ret;
+}
+
+static void mtk_vdec_worker(struct work_struct *work)
+{
+	struct mtk_vcodec_ctx *ctx =
+		container_of(work, struct mtk_vcodec_ctx, decode_work);
+	struct mtk_vcodec_dev *dev = ctx->dev;
+	struct vb2_v4l2_buffer *src_buf, *dst_buf;
+	struct mtk_vcodec_mem buf;
+	struct vdec_fb *pfb;
+	bool res_chg = false;
+	int ret;
+	struct mtk_video_dec_buf *dst_buf_info, *src_buf_info;
+
+	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+	if (!src_buf) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_debug(1, "[%d] src_buf empty!!", ctx->id);
+		return;
+	}
+
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	if (!dst_buf) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id);
+		return;
+	}
+
+	dst_buf_info =
+		container_of(dst_buf, struct mtk_video_dec_buf, m2m_buf.vb);
+
+	pfb = &dst_buf_info->frame_buffer;
+	pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
+	pfb->base_y.dma_addr =
+		vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+	pfb->base_y.size = ctx->picinfo.fb_sz[0];
+
+	pfb->base_c.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 1);
+	pfb->base_c.dma_addr =
+		vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 1);
+	pfb->base_c.size = ctx->picinfo.fb_sz[1];
+	pfb->status = 0;
+	mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id);
+
+	mtk_v4l2_debug(3,
+		       "id=%d Framebuf  pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx",
+		       dst_buf->vb2_buf.index, pfb, pfb->base_y.va,
+		       &pfb->base_y.dma_addr, &pfb->base_c.dma_addr, pfb->base_y.size);
+
+	if (src_buf == &ctx->empty_flush_buf.vb) {
+		mtk_v4l2_debug(1, "Got empty flush input buffer.");
+		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+
+		/* update dst buf status */
+		dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+		mutex_lock(&ctx->lock);
+		dst_buf_info->used = false;
+		mutex_unlock(&ctx->lock);
+
+		vdec_if_decode(ctx, NULL, NULL, &res_chg);
+		clean_display_buffer(ctx);
+		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
+		dst_buf->flags |= V4L2_BUF_FLAG_LAST;
+		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+		clean_free_buffer(ctx);
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		return;
+	}
+
+	src_buf_info =
+		container_of(src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
+
+	buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
+	buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+	buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused;
+	if (!buf.va) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", ctx->id,
+			     src_buf->vb2_buf.index);
+		return;
+	}
+	mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
+		       ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
+	dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
+	dst_buf->timecode = src_buf->timecode;
+	mutex_lock(&ctx->lock);
+	dst_buf_info->used = true;
+	mutex_unlock(&ctx->lock);
+	src_buf_info->used = true;
+
+	ret = vdec_if_decode(ctx, &buf, pfb, &res_chg);
+
+	if (ret) {
+		mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>",
+			     ctx->id, src_buf->vb2_buf.index, buf.size,
+			     src_buf->vb2_buf.timestamp, dst_buf->vb2_buf.index, ret, res_chg);
+		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+		if (ret == -EIO) {
+			mutex_lock(&ctx->lock);
+			src_buf_info->error = true;
+			mutex_unlock(&ctx->lock);
+		}
+		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+	} else if (!res_chg) {
+		/*
+		 * we only return src buffer with VB2_BUF_STATE_DONE
+		 * when decode success without resolution change
+		 */
+		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+	}
+
+	dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+	clean_display_buffer(ctx);
+	clean_free_buffer(ctx);
+
+	if (!ret && res_chg) {
+		mtk_vdec_pic_info_update(ctx);
+		/*
+		 * On encountering a resolution change in the stream.
+		 * The driver must first process and decode all
+		 * remaining buffers from before the resolution change
+		 * point, so call flush decode here
+		 */
+		mtk_vdec_flush_decoder(ctx);
+		/*
+		 * After all buffers containing decoded frames from
+		 * before the resolution change point ready to be
+		 * dequeued on the CAPTURE queue, the driver sends a
+		 * V4L2_EVENT_SOURCE_CHANGE event for source change
+		 * type V4L2_EVENT_SRC_CH_RESOLUTION
+		 */
+		mtk_vdec_queue_res_chg_event(ctx);
+	}
+	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+}
+
+static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *src_buf;
+	struct mtk_vcodec_mem src_mem;
+	bool res_chg = false;
+	int ret;
+	unsigned int dpbsize = 1, i;
+	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct mtk_q_data *dst_q_data;
+
+	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
+		       vb->vb2_queue->type, vb->index, vb);
+	/*
+	 * check if this buffer is ready to be used after decode
+	 */
+	if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		struct mtk_video_dec_buf *buf;
+
+		vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+		buf = container_of(vb2_v4l2, struct mtk_video_dec_buf,
+				   m2m_buf.vb);
+		mutex_lock(&ctx->lock);
+		if (!buf->used) {
+			v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
+			buf->queued_in_vb2 = true;
+			buf->queued_in_v4l2 = true;
+		} else {
+			buf->queued_in_vb2 = false;
+			buf->queued_in_v4l2 = true;
+		}
+		mutex_unlock(&ctx->lock);
+		return;
+	}
+
+	v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
+
+	if (ctx->state != MTK_STATE_INIT) {
+		mtk_v4l2_debug(3, "[%d] already init driver %d", ctx->id,
+			       ctx->state);
+		return;
+	}
+
+	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+	if (!src_buf) {
+		mtk_v4l2_err("No src buffer");
+		return;
+	}
+
+	if (src_buf == &ctx->empty_flush_buf.vb) {
+		/* This shouldn't happen. Just in case. */
+		mtk_v4l2_err("Invalid flush buffer.");
+		v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+		return;
+	}
+
+	src_mem.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
+	src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+	src_mem.size = (size_t)src_buf->vb2_buf.planes[0].bytesused;
+	mtk_v4l2_debug(2, "[%d] buf id=%d va=%p dma=%pad size=%zx", ctx->id,
+		       src_buf->vb2_buf.index, src_mem.va, &src_mem.dma_addr,
+		       src_mem.size);
+
+	ret = vdec_if_decode(ctx, &src_mem, NULL, &res_chg);
+	if (ret || !res_chg) {
+		/*
+		 * fb == NULL means to parse SPS/PPS header or
+		 * resolution info in src_mem. Decode can fail
+		 * if there is no SPS header or picture info
+		 * in bs
+		 */
+
+		src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+		if (ret == -EIO) {
+			mtk_v4l2_err("[%d] Unrecoverable error in vdec_if_decode.", ctx->id);
+			ctx->state = MTK_STATE_ABORT;
+			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+		} else {
+			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+		}
+		mtk_v4l2_debug(ret ? 0 : 1,
+			       "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d",
+			       ctx->id, src_buf->vb2_buf.index, src_mem.size, ret, res_chg);
+		return;
+	}
+
+	if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
+		mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id);
+		return;
+	}
+
+	ctx->last_decoded_picinfo = ctx->picinfo;
+	dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
+	for (i = 0; i < dst_q_data->fmt->num_planes; i++) {
+		dst_q_data->sizeimage[i] = ctx->picinfo.fb_sz[i];
+		dst_q_data->bytesperline[i] = ctx->picinfo.buf_w;
+	}
+
+	mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
+		       ctx->id, ctx->picinfo.buf_w, ctx->picinfo.buf_h, ctx->picinfo.pic_w,
+		       ctx->picinfo.pic_h, dst_q_data->sizeimage[0], dst_q_data->sizeimage[1]);
+
+	ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
+	if (dpbsize == 0)
+		mtk_v4l2_err("[%d] GET_PARAM_DPB_SIZE fail=%d", ctx->id, ret);
+
+	ctx->dpb_size = dpbsize;
+	ctx->state = MTK_STATE_HEADER;
+	mtk_v4l2_debug(1, "[%d] dpbsize=%d", ctx->id, ctx->dpb_size);
+
+	mtk_vdec_queue_res_chg_event(ctx);
+}
+
+static int mtk_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
+	int ret = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+		if (ctx->state >= MTK_STATE_HEADER) {
+			ctrl->val = ctx->dpb_size;
+		} else {
+			mtk_v4l2_debug(0, "Seqinfo not ready");
+			ctrl->val = 0;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops mtk_vcodec_dec_ctrl_ops = {
+	.g_volatile_ctrl = mtk_vdec_g_v_ctrl,
+};
+
+static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
+{
+	struct v4l2_ctrl *ctrl;
+
+	v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 1);
+
+	ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl, &mtk_vcodec_dec_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 0, 32, 1, 1);
+	ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	v4l2_ctrl_new_std_menu(&ctx->ctrl_hdl, &mtk_vcodec_dec_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+			       V4L2_MPEG_VIDEO_VP9_PROFILE_0, 0,
+			       V4L2_MPEG_VIDEO_VP9_PROFILE_0);
+	/*
+	 * H264. Baseline / Extended decoding is not supported.
+	 */
+	v4l2_ctrl_new_std_menu(&ctx->ctrl_hdl, &mtk_vcodec_dec_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+			       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+			       BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
+			       V4L2_MPEG_VIDEO_H264_PROFILE_MAIN);
+
+	if (ctx->ctrl_hdl.error) {
+		mtk_v4l2_err("Adding control failed %d", ctx->ctrl_hdl.error);
+		return ctx->ctrl_hdl.error;
+	}
+
+	v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
+	return 0;
+}
+
+static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
+{
+}
+
+static struct vb2_ops mtk_vdec_frame_vb2_ops = {
+	.queue_setup = vb2ops_vdec_queue_setup,
+	.buf_prepare = vb2ops_vdec_buf_prepare,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = vb2ops_vdec_start_streaming,
+
+	.buf_queue = vb2ops_vdec_stateful_buf_queue,
+	.buf_init = vb2ops_vdec_buf_init,
+	.buf_finish = vb2ops_vdec_buf_finish,
+	.stop_streaming = vb2ops_vdec_stop_streaming,
+};
+
+const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
+	.init_vdec_params = mtk_init_vdec_params,
+	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
+	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
+	.vdec_formats = mtk_video_formats,
+	.num_formats = NUM_FORMATS,
+	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
+	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.vdec_framesizes = mtk_vdec_framesizes,
+	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.worker = mtk_vdec_worker,
+	.flush_decoder = mtk_vdec_flush_decoder,
+};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index cb248d8daa7b..a3c401022567 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -310,6 +310,45 @@ enum mtk_chip {
 	MTK_MT8192,
 };
 
+/**
+ * struct mtk_vcodec_dec_pdata - compatible data for each IC
+ * @init_vdec_params: init vdec params
+ * @ctrls_setup: init vcodec dec ctrls
+ * @worker: worker to start a decode job
+ * @flush_decoder: function that flushes the decoder
+ *
+ * @vdec_vb2_ops: struct vb2_ops
+ *
+ * @vdec_formats: supported video decoder formats
+ * @num_formats: count of video decoder formats
+ * @default_out_fmt: default output buffer format
+ * @default_cap_fmt: default capture buffer format
+ *
+ * @vdec_framesizes: supported video decoder frame sizes
+ * @num_framesizes: count of video decoder frame sizes
+ *
+ * @uses_stateless_api: whether the decoder uses the stateless API with requests
+ */
+
+struct mtk_vcodec_dec_pdata {
+	void (*init_vdec_params)(struct mtk_vcodec_ctx *ctx);
+	int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx);
+	void (*worker)(struct work_struct *work);
+	int (*flush_decoder)(struct mtk_vcodec_ctx *ctx);
+
+	struct vb2_ops *vdec_vb2_ops;
+
+	const struct mtk_video_fmt *vdec_formats;
+	const int num_formats;
+	const struct mtk_video_fmt *default_out_fmt;
+	const struct mtk_video_fmt *default_cap_fmt;
+
+	const struct mtk_codec_framesizes *vdec_framesizes;
+	const int num_framesizes;
+
+	bool uses_stateless_api;
+};
+
 /**
  * struct mtk_vcodec_enc_pdata - compatible data for each IC
  *
@@ -353,6 +392,7 @@ struct mtk_vcodec_enc_pdata {
  * @curr_ctx: The context that is waiting for codec hardware
  *
  * @reg_base: Mapped address of MTK Vcodec registers.
+ * @vdec_pdata: decoder IC-specific data
  * @venc_pdata: encoder IC-specific data
  *
  * @fw_handler: used to communicate with the firmware.
@@ -388,6 +428,7 @@ struct mtk_vcodec_dev {
 	spinlock_t irqlock;
 	struct mtk_vcodec_ctx *curr_ctx;
 	void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE];
+	const struct mtk_vcodec_dec_pdata *vdec_pdata;
 	const struct mtk_vcodec_enc_pdata *venc_pdata;
 
 	struct mtk_vcodec_fw *fw_handler;
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:23 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:23 +0800
Subject: [PATCH v7 07/14] media: mtk-vcodec: vdec: handle firmware version
 field
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-8-tzungbi@google.com>

From: Alexandre Courbot <acourbot at chromium.org>

Firmwares for decoders newer than MT8173 will include an ABI version
number in their initialization ack message. Add the capacity to manage
it and make initialization fail if the firmware ABI is of a version that
we don't support.

For MT8173, this ABI version field does not exist ; thus ignore it on
this chip. There should only be one firmware version available for it
anyway.

Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  4 ++++
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  5 +++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 21 +++++++++++++++++--
 4 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index d77a7688688a..bef49244e61b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -613,6 +613,7 @@ static struct vb2_ops mtk_vdec_frame_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
+	.chip = MTK_MT8173,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index a3c401022567..17c960aa5262 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -327,6 +327,8 @@ enum mtk_chip {
  * @vdec_framesizes: supported video decoder frame sizes
  * @num_framesizes: count of video decoder frame sizes
  *
+ * @chip: chip this decoder is compatible with
+ *
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
  */
 
@@ -346,6 +348,8 @@ struct mtk_vcodec_dec_pdata {
 	const struct mtk_codec_framesizes *vdec_framesizes;
 	const int num_framesizes;
 
+	enum mtk_chip chip;
+
 	bool uses_stateless_api;
 };
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 68e8d5cb16d7..236bd32dcacc 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -83,12 +83,17 @@ struct vdec_ap_ipi_dec_start {
  * @status	: VPU exeuction result
  * @ap_inst_addr	: AP vcodec_vpu_inst instance address
  * @vpu_inst_addr	: VPU decoder instance address
+ * @vdec_abi_version:	ABI version of the firmware. Kernel can use it to
+ *			ensure that it is compatible with the firmware.
+ *			This field is not valid for MT8173 and must not be
+ *			accessed for this chip.
  */
 struct vdec_vpu_ipi_init_ack {
 	uint32_t msg_id;
 	int32_t status;
 	uint64_t ap_inst_addr;
 	uint32_t vpu_inst_addr;
+	uint32_t vdec_abi_version;
 };
 
 #endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 58b0e6fa8fd2..203089213e67 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -24,6 +24,22 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	vpu->inst_addr = msg->vpu_inst_addr;
 
 	mtk_vcodec_debug(vpu, "- vpu_inst_addr = 0x%x", vpu->inst_addr);
+
+	/* Firmware version field does not exist on MT8173. */
+	if (vpu->ctx->dev->vdec_pdata->chip == MTK_MT8173)
+		return;
+
+	/* Check firmware version. */
+	mtk_vcodec_debug(vpu, "firmware version 0x%x\n", msg->vdec_abi_version);
+	switch (msg->vdec_abi_version) {
+	case 1:
+		break;
+	default:
+		mtk_vcodec_err(vpu, "unhandled firmware version 0x%x\n",
+			       msg->vdec_abi_version);
+		vpu->failure = 1;
+		break;
+	}
 }
 
 /*
@@ -44,6 +60,9 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 
 	mtk_vcodec_debug(vpu, "+ id=%X", msg->msg_id);
 
+	vpu->failure = msg->status;
+	vpu->signaled = 1;
+
 	if (msg->status == 0) {
 		switch (msg->msg_id) {
 		case VPU_IPIMSG_DEC_INIT_ACK:
@@ -63,8 +82,6 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 	}
 
 	mtk_vcodec_debug(vpu, "- id=%X", msg->msg_id);
-	vpu->failure = msg->status;
-	vpu->signaled = 1;
 }
 
 static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:24 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:24 +0800
Subject: [PATCH v7 08/14] media: mtk-vcodec: support version 2 of decoder
 firmware ABI
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-9-tzungbi@google.com>

From: Alexandre Courbot <acourbot at chromium.org>

Add support for decoder firmware version 2, which makes the kernel
responsible for managing the VSI context and is used for stateless
codecs.

Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 18 +++++++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 28 +++++++++++++++----
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  5 ++++
 3 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 236bd32dcacc..5f45a537beb4 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -29,11 +29,15 @@ enum vdec_ipi_msgid {
 /**
  * struct vdec_ap_ipi_cmd - generic AP to VPU ipi command format
  * @msg_id	: vdec_ipi_msgid
- * @vpu_inst_addr	: VPU decoder instance address
+ * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
+ * @inst_id     : instance ID. Used if the ABI version >= 2.
  */
 struct vdec_ap_ipi_cmd {
 	uint32_t msg_id;
-	uint32_t vpu_inst_addr;
+	union {
+		uint32_t vpu_inst_addr;
+		uint32_t inst_id;
+	};
 };
 
 /**
@@ -63,7 +67,8 @@ struct vdec_ap_ipi_init {
 /**
  * struct vdec_ap_ipi_dec_start - for AP_IPIMSG_DEC_START
  * @msg_id	: AP_IPIMSG_DEC_START
- * @vpu_inst_addr	: VPU decoder instance address
+ * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
+ * @inst_id     : instance ID. Used if the ABI version >= 2.
  * @data	: Header info
  *	H264 decoder [0]:buf_sz [1]:nal_start
  *	VP8 decoder  [0]:width/height
@@ -72,7 +77,10 @@ struct vdec_ap_ipi_init {
  */
 struct vdec_ap_ipi_dec_start {
 	uint32_t msg_id;
-	uint32_t vpu_inst_addr;
+	union {
+		uint32_t vpu_inst_addr;
+		uint32_t inst_id;
+	};
 	uint32_t data[3];
 	uint32_t reserved;
 };
@@ -87,6 +95,7 @@ struct vdec_ap_ipi_dec_start {
  *			ensure that it is compatible with the firmware.
  *			This field is not valid for MT8173 and must not be
  *			accessed for this chip.
+ * @inst_id     : instance ID. Valid only if the ABI version >= 2.
  */
 struct vdec_vpu_ipi_init_ack {
 	uint32_t msg_id;
@@ -94,6 +103,7 @@ struct vdec_vpu_ipi_init_ack {
 	uint64_t ap_inst_addr;
 	uint32_t vpu_inst_addr;
 	uint32_t vdec_abi_version;
+	uint32_t inst_id;
 };
 
 #endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 203089213e67..5dffc459a33d 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -25,18 +25,30 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 
 	mtk_vcodec_debug(vpu, "- vpu_inst_addr = 0x%x", vpu->inst_addr);
 
+	/* Set default ABI version if dealing with unversioned firmware. */
+	vpu->fw_abi_version = 0;
+	/*
+	 * Instance ID is only used if ABI version >= 2. Initialize it with
+	 * garbage by default.
+	 */
+	vpu->inst_id = 0xdeadbeef;
+
 	/* Firmware version field does not exist on MT8173. */
 	if (vpu->ctx->dev->vdec_pdata->chip == MTK_MT8173)
 		return;
 
 	/* Check firmware version. */
-	mtk_vcodec_debug(vpu, "firmware version 0x%x\n", msg->vdec_abi_version);
-	switch (msg->vdec_abi_version) {
+	vpu->fw_abi_version = msg->vdec_abi_version;
+	mtk_vcodec_debug(vpu, "firmware version 0x%x\n", vpu->fw_abi_version);
+	switch (vpu->fw_abi_version) {
 	case 1:
 		break;
+	case 2:
+		vpu->inst_id = msg->inst_id;
+		break;
 	default:
 		mtk_vcodec_err(vpu, "unhandled firmware version 0x%x\n",
-			       msg->vdec_abi_version);
+			       vpu->fw_abi_version);
 		vpu->failure = 1;
 		break;
 	}
@@ -113,7 +125,10 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id)
 
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_id = msg_id;
-	msg.vpu_inst_addr = vpu->inst_addr;
+	if (vpu->fw_abi_version < 2)
+		msg.vpu_inst_addr = vpu->inst_addr;
+	else
+		msg.inst_id = vpu->inst_id;
 
 	err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err);
@@ -163,7 +178,10 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_id = AP_IPIMSG_DEC_START;
-	msg.vpu_inst_addr = vpu->inst_addr;
+	if (vpu->fw_abi_version < 2)
+		msg.vpu_inst_addr = vpu->inst_addr;
+	else
+		msg.inst_id = vpu->inst_id;
 
 	for (i = 0; i < len; i++)
 		msg.data[i] = data[i];
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index 85224eb7e34b..c2ed5b6cab8b 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -18,6 +18,9 @@ struct mtk_vcodec_ctx;
  *                for control and info share
  * @failure     : VPU execution result status, 0: success, others: fail
  * @inst_addr	: VPU decoder instance address
+ * @fw_abi_version : ABI version of the firmware.
+ * @inst_id	: if fw_abi_version >= 2, contains the instance ID to be given
+ *                in place of inst_addr in messages.
  * @signaled    : 1 - Host has received ack message from VPU, 0 - not received
  * @ctx         : context for v4l2 layer integration
  * @dev		: platform device of VPU
@@ -29,6 +32,8 @@ struct vdec_vpu_inst {
 	void *vsi;
 	int32_t failure;
 	uint32_t inst_addr;
+	uint32_t fw_abi_version;
+	uint32_t inst_id;
 	unsigned int signaled;
 	struct mtk_vcodec_ctx *ctx;
 	wait_queue_head_t wq;
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:25 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:25 +0800
Subject: [PATCH v7 09/14] media: add Mediatek's MM21 format
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-10-tzungbi@google.com>

From: Alexandre Courbot <acourbot at chromium.org>

Add Mediatek's non-compressed 8 bit block video mode. This format is
produced by the MT8183 codec and can be converted to a non-proprietary
format by the MDP3 component.

Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 Documentation/userspace-api/media/v4l/pixfmt-reserved.rst | 7 +++++++
 drivers/media/v4l2-core/v4l2-ioctl.c                      | 1 +
 include/uapi/linux/videodev2.h                            | 1 +
 3 files changed, 9 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
index 0b879c0da713..42357b0b3535 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
@@ -246,6 +246,13 @@ please make a proposal on the linux-media mailing list.
 	It is an opaque intermediate format and the MDP hardware must be
 	used to convert ``V4L2_PIX_FMT_MT21C`` to ``V4L2_PIX_FMT_NV12M``,
 	``V4L2_PIX_FMT_YUV420M`` or ``V4L2_PIX_FMT_YVU420``.
+    * .. _V4L2-PIX-FMT-MM21:
+
+      - ``V4L2_PIX_FMT_MM21``
+      - 'MM21'
+      - Non-compressed, tiled two-planar format used by Mediatek MT8183.
+	This is an opaque intermediate format and the MDP3 hardware can be
+	used to convert it to other formats.
     * .. _V4L2-PIX-FMT-SUNXI-TILED-NV12:
 
       - ``V4L2_PIX_FMT_SUNXI_TILED_NV12``
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 05d5db3d85e5..b394a2b7cfd7 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1346,6 +1346,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 	case V4L2_PIX_FMT_TM6000:	descr = "A/V + VBI Mux Packet"; break;
 	case V4L2_PIX_FMT_CIT_YYVYUY:	descr = "GSPCA CIT YYVYUY"; break;
 	case V4L2_PIX_FMT_KONICA420:	descr = "GSPCA KONICA420"; break;
+	case V4L2_PIX_FMT_MM21:		descr = "Mediatek 8-bit Block Format"; break;
 	case V4L2_PIX_FMT_HSV24:	descr = "24-bit HSV 8-8-8"; break;
 	case V4L2_PIX_FMT_HSV32:	descr = "32-bit XHSV 8-8-8-8"; break;
 	case V4L2_SDR_FMT_CU8:		descr = "Complex U8"; break;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 9260791b8438..bc1dc5adc071 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -733,6 +733,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_Y12I     v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */
 #define V4L2_PIX_FMT_Z16      v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */
 #define V4L2_PIX_FMT_MT21C    v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode  */
+#define V4L2_PIX_FMT_MM21     v4l2_fourcc('M', 'M', '2', '1') /* Mediatek 8-bit block mode, two non-contiguous planes */
 #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
 #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */
 #define V4L2_PIX_FMT_CNF4     v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:26 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:26 +0800
Subject: [PATCH v7 10/14] media: mtk-vcodec: vdec: support stateless API
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-11-tzungbi@google.com>

From: Yunfei Dong <yunfei.dong at mediatek.com>

Support the stateless codec API that will be used by MT8183.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
[acourbot: refactor, cleanup and split]
Co-developed-by: Alexandre Courbot <acourbot at chromium.org>
Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |  66 +++-
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   8 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 360 ++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   3 +
 5 files changed, 434 insertions(+), 4 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 9c3cbb5b800e..4ba93d838ab6 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -12,6 +12,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec_vpu_if.o \
 		mtk_vcodec_dec.o \
 		mtk_vcodec_dec_stateful.o \
+		mtk_vcodec_dec_stateless.o \
 		mtk_vcodec_dec_pm.o \
 
 mtk-vcodec-enc-y := venc/venc_vp8_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index a220532802f9..2b334a8a81c6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -47,7 +47,14 @@ static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
 static int vidioc_try_decoder_cmd(struct file *file, void *priv,
 				struct v4l2_decoder_cmd *cmd)
 {
-	return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd);
+	struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
+
+	/* Use M2M stateless helper if relevant */
+	if (ctx->dev->vdec_pdata->uses_stateless_api)
+		return v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv,
+								cmd);
+	else
+		return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd);
 }
 
 
@@ -62,6 +69,10 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
 	if (ret)
 		return ret;
 
+	/* Use M2M stateless helper if relevant */
+	if (ctx->dev->vdec_pdata->uses_stateless_api)
+		return v4l2_m2m_ioctl_stateless_decoder_cmd(file, priv, cmd);
+
 	mtk_v4l2_debug(1, "decoder cmd=%u", cmd->cmd);
 	dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 				V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
@@ -401,7 +412,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 	 * Setting OUTPUT format after OUTPUT buffers are allocated is invalid
 	 * if using the stateful API.
 	 */
-	if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
+	if (!dec_pdata->uses_stateless_api &&
+	    f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
 	    vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
 		mtk_v4l2_err("out_q_ctx buffers already requested");
 		ret = -EBUSY;
@@ -444,6 +456,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		ctx->quantization = pix_mp->quantization;
 		ctx->xfer_func = pix_mp->xfer_func;
 
+		ctx->current_codec = fmt->fourcc;
 		if (ctx->state == MTK_STATE_FREE) {
 			ret = vdec_if_init(ctx, q_data->fmt->fourcc);
 			if (ret) {
@@ -455,6 +468,48 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		}
 	}
 
+	/*
+	 * If using the stateless API, S_FMT should have the effect of setting
+	 * the CAPTURE queue resolution no matter which queue it was called on.
+	 */
+	if (dec_pdata->uses_stateless_api) {
+		ctx->picinfo.pic_w = pix_mp->width;
+		ctx->picinfo.pic_h = pix_mp->height;
+
+		ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
+		if (ret) {
+			mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
+				     ctx->id);
+			return -EINVAL;
+		}
+
+		ctx->last_decoded_picinfo = ctx->picinfo;
+
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) {
+			ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
+				ctx->picinfo.fb_sz[0] +
+				ctx->picinfo.fb_sz[1];
+			ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
+				ctx->picinfo.buf_w;
+		} else {
+			ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
+				ctx->picinfo.fb_sz[0];
+			ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
+				ctx->picinfo.buf_w;
+			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] =
+				ctx->picinfo.fb_sz[1];
+			ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] =
+				ctx->picinfo.buf_w;
+		}
+
+		ctx->q_data[MTK_Q_DATA_DST].coded_width = ctx->picinfo.buf_w;
+		ctx->q_data[MTK_Q_DATA_DST].coded_height = ctx->picinfo.buf_h;
+		mtk_v4l2_debug(2, "[%d] vdec_if_init() num_plane = %d wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
+			       ctx->id, pix_mp->num_planes, ctx->picinfo.buf_w, ctx->picinfo.buf_h,
+			       ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+			       ctx->q_data[MTK_Q_DATA_DST].sizeimage[0],
+			       ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]);
+	}
 	return 0;
 }
 
@@ -746,9 +801,14 @@ void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
 
 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
-			if (src_buf != &ctx->empty_flush_buf.vb)
+			if (src_buf != &ctx->empty_flush_buf.vb) {
+				struct media_request *req =
+					src_buf->vb2_buf.req_obj.req;
 				v4l2_m2m_buf_done(src_buf,
 						VB2_BUF_STATE_ERROR);
+				if (req)
+					v4l2_ctrl_request_complete(req, &ctx->ctrl_hdl);
+			}
 		}
 		return;
 	}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 76856c0b2db8..9fbd24186c1a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -44,6 +44,7 @@ struct vdec_fb {
  *			queue yet
  * @error:		An unrecoverable error occurs on this buffer.
  * @frame_buffer:	Decode status, and buffer information of Capture buffer
+ * @bs_buffer:	Output buffer info
  *
  * Note : These status information help us track and debug buffer state
  */
@@ -54,11 +55,16 @@ struct mtk_video_dec_buf {
 	bool	queued_in_vb2;
 	bool	queued_in_v4l2;
 	bool	error;
-	struct vdec_fb	frame_buffer;
+
+	union {
+		struct vdec_fb	frame_buffer;
+		struct mtk_vcodec_mem	bs_buffer;
+	};
 };
 
 extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops;
 extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
+extern const struct media_device_ops mtk_vcodec_media_ops;
 
 
 /*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
new file mode 100644
index 000000000000..8f4a1f0a0769
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -0,0 +1,360 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <linux/module.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_intr.h"
+#include "mtk_vcodec_util.h"
+#include "mtk_vcodec_dec_pm.h"
+#include "vdec_drv_if.h"
+
+/**
+ * struct mtk_stateless_control  - CID control type
+ * @cfg: control configuration
+ * @codec_type: codec type (V4L2 pixel format) for CID control type
+ */
+struct mtk_stateless_control {
+	struct v4l2_ctrl_config cfg;
+	int codec_type;
+};
+
+static const struct mtk_stateless_control mtk_stateless_controls[] = {
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_H264_SPS,
+		},
+		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_H264_PPS,
+		},
+		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_H264_SCALING_MATRIX,
+		},
+		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS,
+		},
+		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+			.def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN,
+			.max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+			.menu_skip_mask =
+				BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+				BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
+		},
+		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_H264_DECODE_MODE,
+			.min = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
+			.def = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
+			.max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
+		},
+		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_H264_START_CODE,
+			.min = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
+			.def = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
+			.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
+		},
+		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	}
+};
+
+#define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
+
+static const struct mtk_video_fmt mtk_video_formats[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_H264_SLICE,
+		.type = MTK_FMT_DEC,
+		.num_planes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_MM21,
+		.type = MTK_FMT_FRAME,
+		.num_planes = 2,
+	},
+};
+
+#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
+#define DEFAULT_OUT_FMT_IDX    0
+#define DEFAULT_CAP_FMT_IDX    1
+
+static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
+	{
+		.fourcc	= V4L2_PIX_FMT_H264_SLICE,
+		.stepwise = {  MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
+				MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
+	},
+};
+
+#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
+
+static void mtk_vdec_stateless_set_dst_payload(struct mtk_vcodec_ctx *ctx,
+					       struct vdec_fb *fb)
+{
+	struct mtk_video_dec_buf *vdec_frame_buf =
+		container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+	struct vb2_v4l2_buffer *vb = &vdec_frame_buf->m2m_buf.vb;
+	unsigned int cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+
+	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
+		unsigned int cap_c_size =
+			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+
+		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+	}
+}
+
+static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx,
+					   struct vb2_v4l2_buffer *vb2_v4l2)
+{
+	struct mtk_video_dec_buf *framebuf =
+		container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
+	struct vdec_fb *pfb = &framebuf->frame_buffer;
+	struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
+
+	pfb = &framebuf->frame_buffer;
+	pfb->base_y.va = NULL;
+	pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+	pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
+		pfb->base_c.va = NULL;
+		pfb->base_c.dma_addr =
+			vb2_dma_contig_plane_dma_addr(dst_buf, 1);
+		pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+	}
+	mtk_v4l2_debug(1, "id=%d Framebuf  pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx frame_count = %d",
+		       dst_buf->index, pfb, pfb->base_y.va, &pfb->base_y.dma_addr,
+		       &pfb->base_c.dma_addr, pfb->base_y.size, ctx->decoded_frame_cnt);
+
+	return pfb;
+}
+
+static void vb2ops_vdec_buf_request_complete(struct vb2_buffer *vb)
+{
+	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl);
+}
+
+static void mtk_vdec_worker(struct work_struct *work)
+{
+	struct mtk_vcodec_ctx *ctx =
+		container_of(work, struct mtk_vcodec_ctx, decode_work);
+	struct mtk_vcodec_dev *dev = ctx->dev;
+	struct vb2_v4l2_buffer *vb2_v4l2_src, *vb2_v4l2_dst;
+	struct vb2_buffer *vb2_src;
+	struct mtk_vcodec_mem *bs_src;
+	struct mtk_video_dec_buf *dec_buf_src;
+	struct media_request *src_buf_req;
+	struct vdec_fb *dst_buf;
+	bool res_chg = false;
+	int ret;
+
+	vb2_v4l2_src = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+	if (!vb2_v4l2_src) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_debug(1, "[%d] no available source buffer", ctx->id);
+		return;
+	}
+
+	vb2_v4l2_dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	if (!vb2_v4l2_dst) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_debug(1, "[%d] no available destination buffer", ctx->id);
+		return;
+	}
+
+	vb2_src = &vb2_v4l2_src->vb2_buf;
+	dec_buf_src = container_of(vb2_v4l2_src, struct mtk_video_dec_buf,
+				   m2m_buf.vb);
+	bs_src = &dec_buf_src->bs_buffer;
+
+	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
+		       vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
+
+	bs_src->va = NULL;
+	bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
+	bs_src->size = (size_t)vb2_src->planes[0].bytesused;
+
+	mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
+		       ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src);
+	/* Apply request controls. */
+	src_buf_req = vb2_src->req_obj.req;
+	if (src_buf_req)
+		v4l2_ctrl_request_setup(src_buf_req, &ctx->ctrl_hdl);
+	else
+		mtk_v4l2_err("vb2 buffer media request is NULL");
+
+	dst_buf = vdec_get_cap_buffer(ctx, vb2_v4l2_dst);
+	v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true);
+	ret = vdec_if_decode(ctx, bs_src, dst_buf, &res_chg);
+	if (ret) {
+		mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>",
+			     ctx->id, vb2_src->index, bs_src->size,
+			     vb2_src->timestamp, ret, res_chg);
+		if (ret == -EIO) {
+			mutex_lock(&ctx->lock);
+			dec_buf_src->error = true;
+			mutex_unlock(&ctx->lock);
+		}
+	}
+
+	mtk_vdec_stateless_set_dst_payload(ctx, dst_buf);
+
+	v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx,
+					 ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+
+	v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+}
+
+static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
+{
+	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
+
+	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id, vb->vb2_queue->type, vb->index, vb);
+
+	mutex_lock(&ctx->lock);
+	v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
+	mutex_unlock(&ctx->lock);
+	if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return;
+
+	/* If an OUTPUT buffer, we may need to update the state */
+	if (ctx->state == MTK_STATE_INIT) {
+		ctx->state = MTK_STATE_HEADER;
+		mtk_v4l2_debug(1, "Init driver from init to header.");
+	} else {
+		mtk_v4l2_debug(3, "[%d] already init driver %d", ctx->id, ctx->state);
+	}
+}
+
+static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
+{
+	bool res_chg;
+
+	return vdec_if_decode(ctx, NULL, NULL, &res_chg);
+}
+
+static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
+{
+	unsigned int i;
+
+	v4l2_ctrl_handler_init(&ctx->ctrl_hdl, NUM_CTRLS);
+	if (ctx->ctrl_hdl.error) {
+		mtk_v4l2_err("v4l2_ctrl_handler_init failed\n");
+		return ctx->ctrl_hdl.error;
+	}
+
+	for (i = 0; i < NUM_CTRLS; i++) {
+		struct v4l2_ctrl_config cfg = mtk_stateless_controls[i].cfg;
+
+		v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &cfg, NULL);
+		if (ctx->ctrl_hdl.error) {
+			mtk_v4l2_err("Adding control %d failed %d", i, ctx->ctrl_hdl.error);
+			return ctx->ctrl_hdl.error;
+		}
+	}
+
+	v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
+
+	return 0;
+}
+
+static int fops_media_request_validate(struct media_request *mreq)
+{
+	const unsigned int buffer_cnt = vb2_request_buffer_cnt(mreq);
+
+	switch (buffer_cnt) {
+	case 1:
+		/* We expect exactly one buffer with the request */
+		break;
+	case 0:
+		mtk_v4l2_debug(1, "No buffer provided with the request");
+		return -ENOENT;
+	default:
+		mtk_v4l2_debug(1, "Too many buffers (%d) provided with the request",
+			       buffer_cnt);
+		return -EINVAL;
+	}
+
+	return vb2_request_validate(mreq);
+}
+
+const struct media_device_ops mtk_vcodec_media_ops = {
+	.req_validate	= fops_media_request_validate,
+	.req_queue	= v4l2_m2m_request_queue,
+};
+
+static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
+{
+	struct vb2_queue *src_vq;
+
+	src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
+				 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+
+	/* Support request api for output plane */
+	src_vq->supports_requests = true;
+	src_vq->requires_requests = true;
+}
+
+static int vb2ops_vdec_out_buf_validate(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+	vbuf->field = V4L2_FIELD_NONE;
+	return 0;
+}
+
+static struct vb2_ops mtk_vdec_request_vb2_ops = {
+	.queue_setup	= vb2ops_vdec_queue_setup,
+	.wait_prepare	= vb2_ops_wait_prepare,
+	.wait_finish	= vb2_ops_wait_finish,
+	.start_streaming	= vb2ops_vdec_start_streaming,
+	.stop_streaming	= vb2ops_vdec_stop_streaming,
+
+	.buf_queue	= vb2ops_vdec_stateless_buf_queue,
+	.buf_out_validate = vb2ops_vdec_out_buf_validate,
+	.buf_init	= vb2ops_vdec_buf_init,
+	.buf_prepare	= vb2ops_vdec_buf_prepare,
+	.buf_finish	= vb2ops_vdec_buf_finish,
+	.buf_request_complete = vb2ops_vdec_buf_request_complete,
+};
+
+const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
+	.chip = MTK_MT8183,
+	.init_vdec_params = mtk_init_vdec_params,
+	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
+	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
+	.vdec_formats = mtk_video_formats,
+	.num_formats = NUM_FORMATS,
+	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
+	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.vdec_framesizes = mtk_vdec_framesizes,
+	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.uses_stateless_api = true,
+	.worker = mtk_vdec_worker,
+	.flush_decoder = mtk_vdec_flush_decoder,
+};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 17c960aa5262..8fb333a99a40 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -253,6 +253,7 @@ struct vdec_pic_info {
  * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Only
  *		     to be used with encoder and stateful decoder.
  * @is_flushing: set to true if flushing is in progress.
+ * @current_codec: current set input codec, in V4L2 pixel format
  *
  * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
@@ -294,6 +295,8 @@ struct mtk_vcodec_ctx {
 	struct v4l2_m2m_buffer empty_flush_buf;
 	bool is_flushing;
 
+	u32 current_codec;
+
 	enum v4l2_colorspace colorspace;
 	enum v4l2_ycbcr_encoding ycbcr_enc;
 	enum v4l2_quantization quantization;
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:27 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:27 +0800
Subject: [PATCH v7 11/14] media: mtk-vcodec: vdec: support stateless H.264
 decoding
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-12-tzungbi@google.com>

From: Yunfei Dong <yunfei.dong at mediatek.com>

Add support for H.264 decoding using the stateless API, as supported by
MT8183. This support takes advantage of the V4L2 H.264 reference list
builders.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
[acourbot: refactor, cleanup and split]
Co-developed-by: Alexandre Courbot <acourbot at chromium.org>
Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
[tzungbi: fix missing kerneldoc issue]
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/media/platform/Kconfig                |   1 +
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 774 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   3 +
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 5 files changed, 780 insertions(+)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 157c924686e4..ae1468aa1b4e 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -314,6 +314,7 @@ config VIDEO_MEDIATEK_VCODEC
 	select V4L2_MEM2MEM_DEV
 	select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU
 	select VIDEO_MEDIATEK_VCODEC_SCP if MTK_SCP
+	select V4L2_H264
 	help
 	  Mediatek video codec driver provides HW capability to
 	  encode and decode in a range of video formats on MT8173
diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 4ba93d838ab6..ca8e9e7a9c4e 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
 mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
 		vdec/vdec_vp9_if.o \
+		vdec/vdec_h264_req_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
new file mode 100644
index 000000000000..2396b9a6d6e5
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -0,0 +1,774 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-h264.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+
+#define BUF_PREDICTION_SZ			(64 * 4096)
+#define MB_UNIT_LEN				16
+
+/* get used parameters for sps/pps */
+#define GET_MTK_VDEC_FLAG(cond, flag) \
+	{ dst_param->cond = ((src_param->flags & (flag)) ? (1) : (0)); }
+#define GET_MTK_VDEC_PARAM(param) \
+	{ dst_param->param = src_param->param; }
+/* motion vector size (bytes) for every macro block */
+#define HW_MB_STORE_SZ				64
+
+#define H264_MAX_FB_NUM				17
+#define H264_MAX_MV_NUM				32
+#define HDR_PARSING_BUF_SZ			1024
+
+/**
+ * struct mtk_h264_dpb_info  - h264 dpb information
+ * @y_dma_addr: Y bitstream physical address
+ * @c_dma_addr: CbCr bitstream physical address
+ * @reference_flag: reference picture flag (short/long term reference picture)
+ * @field: field picture flag
+ */
+struct mtk_h264_dpb_info {
+	dma_addr_t y_dma_addr;
+	dma_addr_t c_dma_addr;
+	int reference_flag;
+	int field;
+};
+
+/*
+ * struct mtk_h264_sps_param  - parameters for sps
+ */
+struct mtk_h264_sps_param {
+	unsigned char chroma_format_idc;
+	unsigned char bit_depth_luma_minus8;
+	unsigned char bit_depth_chroma_minus8;
+	unsigned char log2_max_frame_num_minus4;
+	unsigned char pic_order_cnt_type;
+	unsigned char log2_max_pic_order_cnt_lsb_minus4;
+	unsigned char max_num_ref_frames;
+	unsigned char separate_colour_plane_flag;
+	unsigned short pic_width_in_mbs_minus1;
+	unsigned short pic_height_in_map_units_minus1;
+	unsigned int max_frame_nums;
+	unsigned char qpprime_y_zero_transform_bypass_flag;
+	unsigned char delta_pic_order_always_zero_flag;
+	unsigned char frame_mbs_only_flag;
+	unsigned char mb_adaptive_frame_field_flag;
+	unsigned char direct_8x8_inference_flag;
+	unsigned char reserved[3];
+};
+
+/*
+ * struct mtk_h264_pps_param  - parameters for pps
+ */
+struct mtk_h264_pps_param {
+	unsigned char num_ref_idx_l0_default_active_minus1;
+	unsigned char num_ref_idx_l1_default_active_minus1;
+	unsigned char weighted_bipred_idc;
+	char pic_init_qp_minus26;
+	char chroma_qp_index_offset;
+	char second_chroma_qp_index_offset;
+	unsigned char entropy_coding_mode_flag;
+	unsigned char pic_order_present_flag;
+	unsigned char deblocking_filter_control_present_flag;
+	unsigned char constrained_intra_pred_flag;
+	unsigned char weighted_pred_flag;
+	unsigned char redundant_pic_cnt_present_flag;
+	unsigned char transform_8x8_mode_flag;
+	unsigned char scaling_matrix_present_flag;
+	unsigned char reserved[2];
+};
+
+struct slice_api_h264_scaling_matrix {
+	unsigned char scaling_list_4x4[6][16];
+	unsigned char scaling_list_8x8[6][64];
+};
+
+struct slice_h264_dpb_entry {
+	unsigned long long reference_ts;
+	unsigned short frame_num;
+	unsigned short pic_num;
+	/* Note that field is indicated by v4l2_buffer.field */
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
+};
+
+/*
+ * struct slice_api_h264_decode_param - parameters for decode.
+ */
+struct slice_api_h264_decode_param {
+	struct slice_h264_dpb_entry dpb[16];
+	unsigned short num_slices;
+	unsigned short nal_ref_idc;
+	unsigned char ref_pic_list_p0[32];
+	unsigned char ref_pic_list_b0[32];
+	unsigned char ref_pic_list_b1[32];
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
+};
+
+/*
+ * struct mtk_h264_dec_slice_param  - parameters for decode current frame
+ */
+struct mtk_h264_dec_slice_param {
+	struct mtk_h264_sps_param			sps;
+	struct mtk_h264_pps_param			pps;
+	struct slice_api_h264_scaling_matrix		scaling_matrix;
+	struct slice_api_h264_decode_param		decode_params;
+	struct mtk_h264_dpb_info h264_dpb_info[16];
+};
+
+/**
+ * struct h264_fb - h264 decode frame buffer information
+ * @vdec_fb_va  : virtual address of struct vdec_fb
+ * @y_fb_dma    : dma address of Y frame buffer (luma)
+ * @c_fb_dma    : dma address of C frame buffer (chroma)
+ * @poc         : picture order count of frame buffer
+ * @reserved    : for 8 bytes alignment
+ */
+struct h264_fb {
+	u64 vdec_fb_va;
+	u64 y_fb_dma;
+	u64 c_fb_dma;
+	s32 poc;
+	u32 reserved;
+};
+
+/**
+ * struct vdec_h264_dec_info - decode information
+ * @dpb_sz		: decoding picture buffer size
+ * @resolution_changed  : resoltion change happen
+ * @realloc_mv_buf	: flag to notify driver to re-allocate mv buffer
+ * @cap_num_planes	: number planes of capture buffer
+ * @bs_dma		: Input bit-stream buffer dma address
+ * @y_fb_dma		: Y frame buffer dma address
+ * @c_fb_dma		: C frame buffer dma address
+ * @vdec_fb_va		: VDEC frame buffer struct virtual address
+ */
+struct vdec_h264_dec_info {
+	u32 dpb_sz;
+	u32 resolution_changed;
+	u32 realloc_mv_buf;
+	u32 cap_num_planes;
+	u64 bs_dma;
+	u64 y_fb_dma;
+	u64 c_fb_dma;
+	u64 vdec_fb_va;
+};
+
+/**
+ * struct vdec_h264_vsi - shared memory for decode information exchange
+ *                        between VPU and Host.
+ *                        The memory is allocated by VPU then mapping to Host
+ *                        in vpu_dec_init() and freed in vpu_dec_deinit()
+ *                        by VPU.
+ *                        AP-W/R : AP is writer/reader on this item
+ *                        VPU-W/R: VPU is write/reader on this item
+ * @pred_buf_dma : HW working predication buffer dma address (AP-W, VPU-R)
+ * @mv_buf_dma   : HW working motion vector buffer dma address (AP-W, VPU-R)
+ * @dec          : decode information (AP-R, VPU-W)
+ * @pic          : picture information (AP-R, VPU-W)
+ * @crop         : crop information (AP-R, VPU-W)
+ * @h264_slice_param : the parameters that hardware use to decode
+ */
+struct vdec_h264_vsi {
+	u64 pred_buf_dma;
+	u64 mv_buf_dma[H264_MAX_MV_NUM];
+	struct vdec_h264_dec_info dec;
+	struct vdec_pic_info pic;
+	struct v4l2_rect crop;
+	struct mtk_h264_dec_slice_param h264_slice_params;
+};
+
+/**
+ * struct vdec_h264_slice_inst - h264 decoder instance
+ * @num_nalu : how many nalus be decoded
+ * @ctx      : point to mtk_vcodec_ctx
+ * @pred_buf : HW working predication buffer
+ * @mv_buf   : HW working motion vector buffer
+ * @vpu      : VPU instance
+ * @vsi_ctx  : Local VSI data for this decoding context
+ * @h264_slice_param : the parameters that hardware use to decode
+ * @dpb : decoded picture buffer used to store reference buffer information
+ */
+struct vdec_h264_slice_inst {
+	unsigned int num_nalu;
+	struct mtk_vcodec_ctx *ctx;
+	struct mtk_vcodec_mem pred_buf;
+	struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM];
+	struct vdec_vpu_inst vpu;
+	struct vdec_h264_vsi vsi_ctx;
+	struct mtk_h264_dec_slice_param h264_slice_param;
+
+	struct v4l2_h264_dpb_entry dpb[16];
+};
+
+static void *get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
+
+	return ctrl->p_cur.p;
+}
+
+static void get_h264_dpb_list(struct vdec_h264_slice_inst *inst,
+			      struct mtk_h264_dec_slice_param *slice_param)
+{
+	struct vb2_queue *vq;
+	struct vb2_buffer *vb;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	u64 index;
+
+	vq = v4l2_m2m_get_vq(inst->ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+	for (index = 0; index < ARRAY_SIZE(slice_param->decode_params.dpb); index++) {
+		const struct slice_h264_dpb_entry *dpb;
+		int vb2_index;
+
+		dpb = &slice_param->decode_params.dpb[index];
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
+			slice_param->h264_dpb_info[index].reference_flag = 0;
+			continue;
+		}
+
+		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
+		if (vb2_index < 0) {
+			mtk_vcodec_err(inst, "Reference invalid: dpb_index(%lld) reference_ts(%lld)",
+				       index, dpb->reference_ts);
+			continue;
+		}
+		/* 1 for short term reference, 2 for long term reference */
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+			slice_param->h264_dpb_info[index].reference_flag = 1;
+		else
+			slice_param->h264_dpb_info[index].reference_flag = 2;
+
+		vb = vq->bufs[vb2_index];
+		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
+		slice_param->h264_dpb_info[index].field = vb2_v4l2->field;
+
+		slice_param->h264_dpb_info[index].y_dma_addr =
+			vb2_dma_contig_plane_dma_addr(vb, 0);
+		if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
+			slice_param->h264_dpb_info[index].c_dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 1);
+		}
+	}
+}
+
+static void get_h264_sps_parameters(struct mtk_h264_sps_param *dst_param,
+				    const struct v4l2_ctrl_h264_sps *src_param)
+{
+	GET_MTK_VDEC_PARAM(chroma_format_idc);
+	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
+	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
+	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
+	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
+	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
+	GET_MTK_VDEC_PARAM(max_num_ref_frames);
+	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
+	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
+
+	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
+			  V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
+	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
+			  V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
+	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
+			  V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
+			  V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
+			  V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
+			  V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+}
+
+static void get_h264_pps_parameters(struct mtk_h264_pps_param *dst_param,
+				    const struct v4l2_ctrl_h264_pps *src_param)
+{
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
+	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
+	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
+	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
+	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
+
+	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
+			  V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+	GET_MTK_VDEC_FLAG(pic_order_present_flag,
+			  V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+	GET_MTK_VDEC_FLAG(weighted_pred_flag,
+			  V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
+			  V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
+			  V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
+			  V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
+			  V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
+			  V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
+}
+
+static void
+get_h264_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
+			const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
+{
+	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
+	       sizeof(dst_matrix->scaling_list_4x4));
+
+	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
+	       sizeof(dst_matrix->scaling_list_8x8));
+}
+
+static void
+get_h264_decode_parameters(struct slice_api_h264_decode_param *dst_params,
+			   const struct v4l2_ctrl_h264_decode_params *src_params,
+			   const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
+		struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
+		const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
+
+		dst_entry->reference_ts = src_entry->reference_ts;
+		dst_entry->frame_num = src_entry->frame_num;
+		dst_entry->pic_num = src_entry->pic_num;
+		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
+		dst_entry->bottom_field_order_cnt =
+			src_entry->bottom_field_order_cnt;
+		dst_entry->flags = src_entry->flags;
+	}
+
+	/*
+	 * num_slices is a leftover from the old H.264 support and is ignored
+	 * by the firmware.
+	 */
+	dst_params->num_slices = 0;
+	dst_params->nal_ref_idc = src_params->nal_ref_idc;
+	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
+	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
+	dst_params->flags = src_params->flags;
+}
+
+static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
+			    const struct v4l2_h264_dpb_entry *b)
+{
+	return a->top_field_order_cnt == b->top_field_order_cnt &&
+	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
+}
+
+/*
+ * Move DPB entries of dec_param that refer to a frame already existing in dpb
+ * into the already existing slot in dpb, and move other entries into new slots.
+ *
+ * This function is an adaptation of the similarly-named function in
+ * hantro_h264.c.
+ */
+static void update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
+		       struct v4l2_h264_dpb_entry *dpb)
+{
+	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	unsigned int i, j;
+
+	/* Disable all entries by default, and mark the ones in use. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
+			set_bit(i, in_use);
+		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
+	}
+
+	/* Try to match new DPB entries with existing ones by their POCs. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+
+		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+			continue;
+
+		/*
+		 * To cut off some comparisons, iterate only on target DPB
+		 * entries were already used.
+		 */
+		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
+			struct v4l2_h264_dpb_entry *cdpb;
+
+			cdpb = &dpb[j];
+			if (!dpb_entry_match(cdpb, ndpb))
+				continue;
+
+			*cdpb = *ndpb;
+			set_bit(j, used);
+			/* Don't reiterate on this one. */
+			clear_bit(j, in_use);
+			break;
+		}
+
+		if (j == ARRAY_SIZE(dec_param->dpb))
+			set_bit(i, new);
+	}
+
+	/* For entries that could not be matched, use remaining free slots. */
+	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+		struct v4l2_h264_dpb_entry *cdpb;
+
+		/*
+		 * Both arrays are of the same sizes, so there is no way
+		 * we can end up with no space in target array, unless
+		 * something is buggy.
+		 */
+		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
+		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
+			return;
+
+		cdpb = &dpb[j];
+		*cdpb = *ndpb;
+		set_bit(j, used);
+	}
+}
+
+/*
+ * The firmware expects unused reflist entries to have the value 0x20.
+ */
+static void fixup_ref_list(u8 *ref_list, size_t num_valid)
+{
+	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
+}
+
+static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
+{
+	const struct v4l2_ctrl_h264_decode_params *dec_params =
+		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	const struct v4l2_ctrl_h264_sps *sps =
+		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
+	const struct v4l2_ctrl_h264_pps *pps =
+		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
+	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix =
+		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param;
+	struct v4l2_h264_reflist_builder reflist_builder;
+	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
+	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
+	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
+
+	update_dpb(dec_params, inst->dpb);
+
+	get_h264_sps_parameters(&slice_param->sps, sps);
+	get_h264_pps_parameters(&slice_param->pps, pps);
+	get_h264_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
+	get_h264_decode_parameters(&slice_param->decode_params, dec_params,
+				   inst->dpb);
+	get_h264_dpb_list(inst, slice_param);
+
+	/* Build the reference lists */
+	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
+				       inst->dpb);
+	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
+	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
+	/* Adapt the built lists to the firmware's expectations */
+	fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+
+	memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
+	       sizeof(inst->vsi_ctx.h264_slice_params));
+}
+
+static unsigned int get_mv_buf_size(unsigned int width, unsigned int height)
+{
+	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
+
+	return HW_MB_STORE_SZ * unit_size;
+}
+
+static int allocate_predication_buf(struct vdec_h264_slice_inst *inst)
+{
+	int err;
+
+	inst->pred_buf.size = BUF_PREDICTION_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, &inst->pred_buf);
+	if (err) {
+		mtk_vcodec_err(inst, "failed to allocate ppl buf");
+		return err;
+	}
+
+	inst->vsi_ctx.pred_buf_dma = inst->pred_buf.dma_addr;
+	return 0;
+}
+
+static void free_predication_buf(struct vdec_h264_slice_inst *inst)
+{
+	struct mtk_vcodec_mem *mem = &inst->pred_buf;
+
+	mtk_vcodec_debug_enter(inst);
+
+	inst->vsi_ctx.pred_buf_dma = 0;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+}
+
+static int alloc_mv_buf(struct vdec_h264_slice_inst *inst,
+			struct vdec_pic_info *pic)
+{
+	int i;
+	int err;
+	struct mtk_vcodec_mem *mem = NULL;
+	unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
+
+	mtk_v4l2_debug(3, "size = 0x%lx", buf_sz);
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+		mem->size = buf_sz;
+		err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+		if (err) {
+			mtk_vcodec_err(inst, "failed to allocate mv buf");
+			return err;
+		}
+		inst->vsi_ctx.mv_buf_dma[i] = mem->dma_addr;
+	}
+
+	return 0;
+}
+
+static void free_mv_buf(struct vdec_h264_slice_inst *inst)
+{
+	int i;
+	struct mtk_vcodec_mem *mem;
+
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		inst->vsi_ctx.mv_buf_dma[i] = 0;
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+	}
+}
+
+static void get_pic_info(struct vdec_h264_slice_inst *inst,
+			 struct vdec_pic_info *pic)
+{
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+
+	ctx->picinfo.buf_w = (ctx->picinfo.pic_w + 15) & 0xFFFFFFF0;
+	ctx->picinfo.buf_h = (ctx->picinfo.pic_h + 31) & 0xFFFFFFE0;
+	ctx->picinfo.fb_sz[0] = ctx->picinfo.buf_w * ctx->picinfo.buf_h;
+	ctx->picinfo.fb_sz[1] = ctx->picinfo.fb_sz[0] >> 1;
+	inst->vsi_ctx.dec.cap_num_planes =
+		ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
+
+	*pic = ctx->picinfo;
+	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+			 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+	mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0],
+			 ctx->picinfo.fb_sz[1]);
+
+	if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w ||
+	    ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) {
+		inst->vsi_ctx.dec.resolution_changed = true;
+		if (ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w ||
+		    ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h)
+			inst->vsi_ctx.dec.realloc_mv_buf = true;
+
+		mtk_v4l2_debug(1, "ResChg: (%d %d) : old(%d, %d) -> new(%d, %d)",
+			       inst->vsi_ctx.dec.resolution_changed,
+			       inst->vsi_ctx.dec.realloc_mv_buf,
+			       ctx->last_decoded_picinfo.pic_w,
+			       ctx->last_decoded_picinfo.pic_h,
+			       ctx->picinfo.pic_w, ctx->picinfo.pic_h);
+	}
+}
+
+static void get_crop_info(struct vdec_h264_slice_inst *inst, struct v4l2_rect *cr)
+{
+	cr->left = inst->vsi_ctx.crop.left;
+	cr->top = inst->vsi_ctx.crop.top;
+	cr->width = inst->vsi_ctx.crop.width;
+	cr->height = inst->vsi_ctx.crop.height;
+
+	mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static void get_dpb_size(struct vdec_h264_slice_inst *inst, unsigned int *dpb_sz)
+{
+	*dpb_sz = inst->vsi_ctx.dec.dpb_sz;
+	mtk_vcodec_debug(inst, "sz=%d", *dpb_sz);
+}
+
+static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_h264_slice_inst *inst;
+	int err;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+
+	inst->vpu.id = SCP_IPI_VDEC_H264;
+	inst->vpu.ctx = ctx;
+
+	err = vpu_dec_init(&inst->vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "vdec_h264 init err=%d", err);
+		goto error_free_inst;
+	}
+
+	memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
+	inst->vsi_ctx.dec.resolution_changed = true;
+	inst->vsi_ctx.dec.realloc_mv_buf = true;
+
+	err = allocate_predication_buf(inst);
+	if (err)
+		goto error_deinit;
+
+	mtk_vcodec_debug(inst, "struct size = %d,%d,%d,%d\n",
+			 sizeof(struct mtk_h264_sps_param),
+			 sizeof(struct mtk_h264_pps_param),
+			 sizeof(struct mtk_h264_dec_slice_param),
+			 sizeof(struct mtk_h264_dpb_info));
+
+	mtk_vcodec_debug(inst, "H264 Instance >> %p", inst);
+
+	ctx->drv_handle = inst;
+	return 0;
+
+error_deinit:
+	vpu_dec_deinit(&inst->vpu);
+
+error_free_inst:
+	kfree(inst);
+	return err;
+}
+
+static void vdec_h264_slice_deinit(void *h_vdec)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	mtk_vcodec_debug_enter(inst);
+
+	vpu_dec_deinit(&inst->vpu);
+	free_predication_buf(inst);
+	free_mv_buf(inst);
+
+	kfree(inst);
+}
+
+static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+				  struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+	const struct v4l2_ctrl_h264_decode_params *dec_params =
+		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	u32 data[2];
+	u64 y_fb_dma;
+	u64 c_fb_dma;
+	int err;
+
+	/* bs NULL means flush decoder */
+	if (!bs)
+		return vpu_dec_reset(vpu);
+
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+
+	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
+			 ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
+
+	inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr;
+	inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
+	inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
+	inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
+
+	get_vdec_decode_parameters(inst);
+	data[0] = bs->size;
+	/*
+	 * Reconstruct the first byte of the NAL unit, as the firmware requests
+	 * that information to be passed even though it is present in the stream
+	 * itself...
+	 */
+	data[1] = (dec_params->nal_ref_idc << 5) |
+		  ((dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC)
+			? 0x5 : 0x1);
+
+	*res_chg = inst->vsi_ctx.dec.resolution_changed;
+	if (*res_chg) {
+		mtk_vcodec_debug(inst, "- resolution changed -");
+		if (inst->vsi_ctx.dec.realloc_mv_buf) {
+			err = alloc_mv_buf(inst, &inst->ctx->picinfo);
+			inst->vsi_ctx.dec.realloc_mv_buf = false;
+			if (err)
+				goto err_free_fb_out;
+		}
+		*res_chg = false;
+	}
+
+	memcpy(inst->vpu.vsi, &inst->vsi_ctx, sizeof(inst->vsi_ctx));
+	err = vpu_dec_start(vpu, data, 2);
+	if (err)
+		goto err_free_fb_out;
+
+	/* wait decoder done interrupt */
+	err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
+					   MTK_INST_IRQ_RECEIVED,
+					   WAIT_INTR_TIMEOUT_MS);
+	if (err)
+		goto err_free_fb_out;
+	vpu_dec_end(vpu);
+
+	memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
+	mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu);
+	return 0;
+
+err_free_fb_out:
+	mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err);
+	return err;
+}
+
+static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type, void *out)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		get_pic_info(inst, out);
+		break;
+
+	case GET_PARAM_DPB_SIZE:
+		get_dpb_size(inst, out);
+		break;
+
+	case GET_PARAM_CROP_INFO:
+		get_crop_info(inst, out);
+		break;
+
+	default:
+		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+const struct vdec_common_if vdec_h264_slice_if = {
+	.init		= vdec_h264_slice_init,
+	.decode		= vdec_h264_slice_decode,
+	.get_param	= vdec_h264_slice_get_param,
+	.deinit		= vdec_h264_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index b18743b906ea..42008243ceac 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -19,6 +19,9 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 	int ret = 0;
 
 	switch (fourcc) {
+	case V4L2_PIX_FMT_H264_SLICE:
+		ctx->dec_if = &vdec_h264_slice_if;
+		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
 		break;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index ec8f4e8d3d23..d467e8af4a84 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -55,6 +55,7 @@ struct vdec_fb_node {
 };
 
 extern const struct vdec_common_if vdec_h264_if;
+extern const struct vdec_common_if vdec_h264_slice_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp9_if;
 
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:28 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:28 +0800
Subject: [PATCH v7 12/14] media: mtk-vcodec: vdec: add media device if using
 stateless api
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-13-tzungbi@google.com>

From: Yunfei Dong <yunfei.dong at mediatek.com>

The stateless API requires a media device for issuing requests. Add one
if we are being instantiated as a stateless decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
[acourbot: refactor, cleanup and split]
Co-developed-by: Alexandre Courbot <acourbot at chromium.org>
Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
[tzungbi: fix wrong device minor number reference]
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/media/platform/Kconfig                |  2 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 41 ++++++++++++++++++-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  2 +
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index ae1468aa1b4e..aa277a19e275 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -315,6 +315,8 @@ config VIDEO_MEDIATEK_VCODEC
 	select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU
 	select VIDEO_MEDIATEK_VCODEC_SCP if MTK_SCP
 	select V4L2_H264
+	select MEDIA_CONTROLLER
+	select MEDIA_CONTROLLER_REQUEST_API
 	help
 	  Mediatek video codec driver provides HW capability to
 	  encode and decode in a range of video formats on MT8173
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 1460951f302c..fe345aab9853 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -14,6 +14,7 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
+#include <media/v4l2-device.h>
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_dec.h"
@@ -316,18 +317,47 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_event_workq;
 	}
 
+	if (dev->vdec_pdata->uses_stateless_api) {
+		dev->mdev_dec.dev = &pdev->dev;
+		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
+			sizeof(dev->mdev_dec.model));
+
+		media_device_init(&dev->mdev_dec);
+		dev->mdev_dec.ops = &mtk_vcodec_media_ops;
+		dev->v4l2_dev.mdev = &dev->mdev_dec;
+
+		ret = v4l2_m2m_register_media_controller(dev->m2m_dev_dec, dev->vfd_dec,
+							 MEDIA_ENT_F_PROC_VIDEO_DECODER);
+		if (ret) {
+			mtk_v4l2_err("Failed to register media controller");
+			goto err_reg_cont;
+		}
+
+		ret = media_device_register(&dev->mdev_dec);
+		if (ret) {
+			mtk_v4l2_err("Failed to register media device");
+			goto err_media_reg;
+		}
+
+		mtk_v4l2_debug(0, "media registered as /dev/media%d", vfd_dec->minor);
+	}
 	ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 0);
 	if (ret) {
 		mtk_v4l2_err("Failed to register video device");
 		goto err_dec_reg;
 	}
 
-	mtk_v4l2_debug(0, "decoder registered as /dev/video%d",
-		vfd_dec->num);
+	mtk_v4l2_debug(0, "decoder registered as /dev/video%d", vfd_dec->minor);
 
 	return 0;
 
 err_dec_reg:
+	if (dev->vdec_pdata->uses_stateless_api)
+		media_device_unregister(&dev->mdev_dec);
+err_media_reg:
+	if (dev->vdec_pdata->uses_stateless_api)
+		v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
+err_reg_cont:
 	destroy_workqueue(dev->decode_workqueue);
 err_event_workq:
 	v4l2_m2m_release(dev->m2m_dev_dec);
@@ -360,6 +390,13 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 
 	flush_workqueue(dev->decode_workqueue);
 	destroy_workqueue(dev->decode_workqueue);
+
+	if (media_devnode_is_registered(dev->mdev_dec.devnode)) {
+		media_device_unregister(&dev->mdev_dec);
+		v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
+		media_device_cleanup(&dev->mdev_dec);
+	}
+
 	if (dev->m2m_dev_dec)
 		v4l2_m2m_release(dev->m2m_dev_dec);
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 8fb333a99a40..d4f840a7bbcb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -389,6 +389,7 @@ struct mtk_vcodec_enc_pdata {
  * struct mtk_vcodec_dev - driver data
  * @v4l2_dev: V4L2 device to register video devices for.
  * @vfd_dec: Video device for decoder
+ * @mdev_dec: Media device for decoder
  * @vfd_enc: Video device for encoder.
  *
  * @m2m_dev_dec: m2m device for decoder
@@ -426,6 +427,7 @@ struct mtk_vcodec_enc_pdata {
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
 	struct video_device *vfd_dec;
+	struct media_device mdev_dec;
 	struct video_device *vfd_enc;
 
 	struct v4l2_m2m_dev *m2m_dev_dec;
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:29 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:29 +0800
Subject: [PATCH v7 13/14] dt-bindings: media: document mediatek,
 mt8183-vcodec-dec
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-14-tzungbi@google.com>

From: Alexandre Courbot <acourbot at chromium.org>

MT8183's decoder is instantiated similarly to MT8173's.

Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
index ad1321e5a22d..c44a6e6943af 100644
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
@@ -10,6 +10,7 @@ Required properties:
   "mediatek,mt8183-vcodec-enc" for MT8183 encoder.
   "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
   "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
+  "mediatek,mt8183-vcodec-dec" for MT8183 decoder.
 - reg : Physical base address of the video codec registers and length of
   memory mapped region.
 - interrupts : interrupt number to the cpu.
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Thu Aug  5 21:15:30 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri,  6 Aug 2021 12:15:30 +0800
Subject: [PATCH v7 14/14] media: mtk-vcodec: enable MT8183 decoder
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <20210806041530.4170869-15-tzungbi@google.com>

From: Yunfei Dong <yunfei.dong at mediatek.com>

Now that all the supporting blocks are present, enable decoder for
MT8183.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
[acourbot: refactor, cleanup and split]
Co-developed-by: Alexandre Courbot <acourbot at chromium.org>
Signed-off-by: Alexandre Courbot <acourbot at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index fe345aab9853..36ae3e6017f0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -373,12 +373,17 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 }
 
 extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata;
+extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata;
 
 static const struct of_device_id mtk_vcodec_match[] = {
 	{
 		.compatible = "mediatek,mt8173-vcodec-dec",
 		.data = &mtk_vdec_8173_pdata,
 	},
+	{
+		.compatible = "mediatek,mt8183-vcodec-dec",
+		.data = &mtk_vdec_8183_pdata,
+	},
 	{},
 };
 
-- 
2.32.0.605.g8dce9f2422-goog



From fido_max at inbox.ru  Thu Aug  5 21:37:39 2021
From: fido_max at inbox.ru (Maxim Kochetkov)
Date: Fri, 6 Aug 2021 07:37:39 +0300
Subject: [PATCH v4] soc: fsl: qe: convert QE interrupt controller to
 platform_device
In-Reply-To: <CAGETcx8QC+AMXvmk4RB=LGp00QLVVX4uCeeruAjFnGq_irMh4Q@mail.gmail.com>
References: <20210803113538.560277-1-fido_max@inbox.ru>
 <CAGETcx8QC+AMXvmk4RB=LGp00QLVVX4uCeeruAjFnGq_irMh4Q@mail.gmail.com>
Message-ID: <dff603dc-9038-71cb-bfcb-5abc24f17109@inbox.ru>

03.08.2021 20:51, Saravana Kannan wrote:
>> So lets convert this driver to simple platform_device with probe().
>> Also use platform_get_ and devm_ family function to get/allocate
>> resources and drop unused .compatible = "qeic".
> Yes, please!

Should I totally drop { .type = "qeic"}, or keep?


From saravanak at google.com  Thu Aug  5 21:39:42 2021
From: saravanak at google.com (Saravana Kannan)
Date: Thu, 5 Aug 2021 21:39:42 -0700
Subject: [PATCH v4] soc: fsl: qe: convert QE interrupt controller to
 platform_device
In-Reply-To: <dff603dc-9038-71cb-bfcb-5abc24f17109@inbox.ru>
References: <20210803113538.560277-1-fido_max@inbox.ru>
 <CAGETcx8QC+AMXvmk4RB=LGp00QLVVX4uCeeruAjFnGq_irMh4Q@mail.gmail.com>
 <dff603dc-9038-71cb-bfcb-5abc24f17109@inbox.ru>
Message-ID: <CAGETcx-evuv-A+A5v3-ubFZNvn_i+QSvg+tSW0OOgAd82-pytg@mail.gmail.com>

On Thu, Aug 5, 2021 at 9:35 PM Maxim Kochetkov <fido_max at inbox.ru> wrote:
>
> 03.08.2021 20:51, Saravana Kannan wrote:
> >> So lets convert this driver to simple platform_device with probe().
> >> Also use platform_get_ and devm_ family function to get/allocate
> >> resources and drop unused .compatible = "qeic".
> > Yes, please!
>
> Should I totally drop { .type = "qeic"}, or keep?

Sorry for the confusion. My "Yes, please"!" was a show of support for
switching this to a proper platform driver. Not a response to that
specific question.

I didn't look at the code/DT close enough to know/care about the "type" part.

-Saravana


From christophe.leroy at csgroup.eu  Thu Aug  5 21:53:47 2021
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 6 Aug 2021 06:53:47 +0200
Subject: [PATCH v4] soc: fsl: qe: convert QE interrupt controller to
 platform_device
In-Reply-To: <CAGETcx-evuv-A+A5v3-ubFZNvn_i+QSvg+tSW0OOgAd82-pytg@mail.gmail.com>
References: <20210803113538.560277-1-fido_max@inbox.ru>
 <CAGETcx8QC+AMXvmk4RB=LGp00QLVVX4uCeeruAjFnGq_irMh4Q@mail.gmail.com>
 <dff603dc-9038-71cb-bfcb-5abc24f17109@inbox.ru>
 <CAGETcx-evuv-A+A5v3-ubFZNvn_i+QSvg+tSW0OOgAd82-pytg@mail.gmail.com>
Message-ID: <dc3411e9-d1e0-8a23-5d9b-1aee3880b4f7@csgroup.eu>



Le 06/08/2021 ? 06:39, Saravana Kannan a ?crit?:
> On Thu, Aug 5, 2021 at 9:35 PM Maxim Kochetkov <fido_max at inbox.ru> wrote:
>>
>> 03.08.2021 20:51, Saravana Kannan wrote:
>>>> So lets convert this driver to simple platform_device with probe().
>>>> Also use platform_get_ and devm_ family function to get/allocate
>>>> resources and drop unused .compatible = "qeic".
>>> Yes, please!
>>
>> Should I totally drop { .type = "qeic"}, or keep?
> 
> Sorry for the confusion. My "Yes, please"!" was a show of support for
> switching this to a proper platform driver. Not a response to that
> specific question.
> 
> I didn't look at the code/DT close enough to know/care about the "type" part.
> 

As far as I understand, Leo told it needs to remain, based on his answer below:

"From the original code, this should be type = "qeic".  It is not
defined in current binding but probably needed for backward
compatibility."


Christophe


From michal.simek at xilinx.com  Thu Aug  5 22:49:02 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri, 6 Aug 2021 07:49:02 +0200
Subject: [PATCH V2 1/3] firmware: zynqmp: Add MMIO read and write support
 for PS_MODE pin
In-Reply-To: <20210805174219.3000667-2-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-2-piyush.mehta@xilinx.com>
Message-ID: <2cef2e97-18f8-9765-2600-27aa219fb2b2@xilinx.com>



On 8/5/21 7:42 PM, Piyush Mehta wrote:
> Add Xilinx ZynqMP firmware MMIO APIs support to set and get PS_MODE
> pins value and status. These APIs create an interface path between
> mode pin controller driver and low-level API to access GPIO pins.
> 
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> ---
> Changes in v2:
> - Added Xilinx ZynqMP firmware MMIO API support to set and get pin
>   value and status.
> ---
>  drivers/firmware/xilinx/zynqmp.c     | 46 ++++++++++++++++++++++++++++++++++++
>  include/linux/firmware/xlnx-zynqmp.h | 14 +++++++++++
>  2 files changed, 60 insertions(+)
> 
> diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
> index 15b13832..0234423 100644
> --- a/drivers/firmware/xilinx/zynqmp.c
> +++ b/drivers/firmware/xilinx/zynqmp.c
> @@ -28,6 +28,13 @@
>  /* Max HashMap Order for PM API feature check (1<<7 = 128) */
>  #define PM_API_FEATURE_CHECK_MAX_ORDER  7
>  
> +/* CRL registers and bitfields */
> +#define CRL_APB_BASE			0xFF5E0000U
> +/* BOOT_PIN_CTRL- Used to control the mode pins after boot */
> +#define CRL_APB_BOOT_PIN_CTRL		(CRL_APB_BASE + (0x250U))
> +/* BOOT_PIN_CTRL_MASK- out_val[11:8], out_en[3:0] */
> +#define CRL_APB_BOOTPIN_CTRL_MASK	0xF0FU
> +
>  static bool feature_check_enabled;
>  static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER);
>  
> @@ -926,6 +933,45 @@ int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
>  EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_config);
>  
>  /**
> + * zynqmp_pm_bootmode_read() - PM Config API for read bootpin status
> + * @ps_mode: Returned output value of ps_mode
> + *
> + * This API function is to be used for notify the power management controller
> + * to read bootpin status.
> + *
> + * Return: status, either success or error+reason
> + */
> +unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode)
> +{
> +	unsigned int ret;
> +	u32 ret_payload[PAYLOAD_ARG_CNT];
> +
> +	ret = zynqmp_pm_invoke_fn(PM_MMIO_READ, CRL_APB_BOOT_PIN_CTRL, 0,
> +				  0, 0, ret_payload);
> +
> +	*ps_mode = ret_payload[1];
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_read);
> +
> +/**
> + * zynqmp_pm_bootmode_write() - PM Config API for Configure bootpin
> + * @ps_mode: Value to be written to the bootpin ctrl register
> + *
> + * This API function is to be used for notify the power management controller
> + * to configure bootpin.
> + *
> + * Return: Returns status, either success or error+reason
> + */
> +int zynqmp_pm_bootmode_write(u32 ps_mode)
> +{
> +	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, CRL_APB_BOOT_PIN_CTRL,
> +				   CRL_APB_BOOTPIN_CTRL_MASK, ps_mode, 0, NULL);
> +}
> +EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write);
> +
> +/**
>   * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
>   *			       master has initialized its own power management
>   *
> diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
> index 9d1a5c1..dc6f39f 100644
> --- a/include/linux/firmware/xlnx-zynqmp.h
> +++ b/include/linux/firmware/xlnx-zynqmp.h
> @@ -68,6 +68,8 @@ enum pm_api_id {
>  	PM_SET_REQUIREMENT = 15,
>  	PM_RESET_ASSERT = 17,
>  	PM_RESET_GET_STATUS = 18,
> +	PM_MMIO_WRITE = 19,
> +	PM_MMIO_READ = 20,
>  	PM_PM_INIT_FINALIZE = 21,
>  	PM_FPGA_LOAD = 22,
>  	PM_FPGA_GET_STATUS = 23,
> @@ -386,6 +388,8 @@ int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type);
>  int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
>  			   const enum zynqmp_pm_reset_action assert_flag);
>  int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status);
> +unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode);
> +int zynqmp_pm_bootmode_write(u32 ps_mode);
>  int zynqmp_pm_init_finalize(void);
>  int zynqmp_pm_set_suspend_mode(u32 mode);
>  int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
> @@ -515,6 +519,16 @@ static inline int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset,
>  	return -ENODEV;
>  }
>  
> +static inline unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode)
> +{
> +	return -ENODEV;
> +}
> +
> +static inline int zynqmp_pm_bootmode_write(u32 ps_mode)
> +{
> +	return -ENODEV;
> +}
> +
>  static inline int zynqmp_pm_init_finalize(void)
>  {
>  	return -ENODEV;
> 

Acked-by: Michal Simek <michal.simek at xilinx.com>

Thanks,
Michal


From tony at atomide.com  Thu Aug  5 23:49:20 2021
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 6 Aug 2021 09:49:20 +0300
Subject: [PATCH 1/3] arm: omap2: Drop MACH_OMAP3517EVM entry
In-Reply-To: <CALeDE9OC+OAuGaNM+iEO44bg+QAdjTE3NQkSdLLZUb-OXeo4Xg@mail.gmail.com>
References: <20210613125105.786984-1-pbrobinson@gmail.com>
 <YP/Epx04Za2wiSlt@atomide.com>
 <CALeDE9OC+OAuGaNM+iEO44bg+QAdjTE3NQkSdLLZUb-OXeo4Xg@mail.gmail.com>
Message-ID: <YQzbcLAU0aAvYhjY@atomide.com>

* Peter Robinson <pbrobinson at gmail.com> [210805 15:05]:
> Hi Tony,
> 
> > * Peter Robinson <pbrobinson at gmail.com> [210613 15:51]:
> > > The MACH_OMAP3517EVM was added back in commit 549f95ed2016 due to
> > > being used by the ASoC driver, but this driver was dropped in
> > > commit 2c2596f3ab25 as the audio for this board had been moved to
> > > a simple-audio-card configuration so MACH_OMAP3517EVM is now
> > > properly unuused and can be dropped.
> >
> > Applying into omap-for-v5.15/soc thanks.
> 
> Was that all 3 of the series or just this one patch, I only see the
> one for your 5.15 PR.

Oops, sorry about that, and thanks for checking. I'm applying patches
currently with a combination of my old tagged email approach, and
switching over to applying using b4. Looks like I did not use b4
here and missed the rest of the series.

The missing patches are now applied into omap-for-v5.15/soc.

Regards,

Tony


From michael at walle.cc  Fri Aug  6 00:21:17 2021
From: michael at walle.cc (Michael Walle)
Date: Fri, 06 Aug 2021 09:21:17 +0200
Subject: [PATCH] ARM: kirkwood: add missing <linux/if_ether.h> for ETH_ALEN
In-Reply-To: <YQxk4jrbm31NM1US@makrotopia.org>
References: <YQxk4jrbm31NM1US@makrotopia.org>
Message-ID: <cde9de20efd3a75561080751766edbec@walle.cc>

Hi,

Am 2021-08-06 00:23, schrieb Daniel Golle:
> After commit 83216e3988cd1 ("of: net: pass the dst buffer to
> of_get_mac_address()") build fails for kirkwood as ETH_ALEN is not
> defined.
> 
> arch/arm/mach-mvebu/kirkwood.c: In function 'kirkwood_dt_eth_fixup':
> arch/arm/mach-mvebu/kirkwood.c:87:13: error: 'ETH_ALEN' undeclared
> (first use in this function); did you mean 'ESTALE'?
>    u8 tmpmac[ETH_ALEN];
>              ^~~~~~~~
>              ESTALE
> arch/arm/mach-mvebu/kirkwood.c:87:13: note: each undeclared identifier
> is reported only once for each function it appears in
> arch/arm/mach-mvebu/kirkwood.c:87:6: warning: unused variable 'tmpmac'
> [-Wunused-variable]
>    u8 tmpmac[ETH_ALEN];
>       ^~~~~~
> make[5]: *** [scripts/Makefile.build:262:
> arch/arm/mach-mvebu/kirkwood.o] Error 1
> make[5]: *** Waiting for unfinished jobs....
> 
> Add missing #include <linux/if_ether.h> to fix this.
> 
> Cc: David S. Miller <davem at davemloft.net>
> Cc: Andrew Lunn <andrew at lunn.ch>
> Cc: Michael Walle <michael at walle.cc>
> Reported-by:
> https://buildbot.openwrt.org/master/images/#/builders/56/builds/220/steps/44/logs/stdio
> Fixes: 83216e3988cd1 ("of: net: pass the dst buffer to 
> of_get_mac_address()")
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>

What kernel is this? I've just tested with this exact commit as
base and it compiles just fine.

I'm not saying including the file is wrong, but it seems it isn't
needed in the upstream kernel and I don't know if it qualifies for
the stable queue therefore.

-michael


From patrice.chotard at foss.st.com  Fri Aug  6 00:45:12 2021
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Fri, 6 Aug 2021 09:45:12 +0200
Subject: [GIT PULL] STi DT update for v5.15 #1
Message-ID: <1d95209f-9cb4-47a3-2696-7a93df7cdc05@foss.st.com>

Hi

This STi DT update is dedicated for v5.15. 
It provides mainly clocks update and introduces a new board.

Thanks
Patrice

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pchotard/sti.git tags/sti-dt-for-v5.15-round1

for you to fetch changes up to f9807f9cb396544ab6bdb4f4451505211ca602f7:

  ARM: dts: sti: remove clk_ignore_unused from bootargs for stih410-b2260 (2021-08-06 09:30:03 +0200)

----------------------------------------------------------------
Highlights:
-----------
  - Introduce 4KOpen STiH418-b2264 board
  - Remove clk_ignore_unused from STi boards DT
  - Remove clock-output-names and clk_critical properties
  - Update some clock compatible

----------------------------------------------------------------
Alain Volmat (13):
      ARM: dts: sti: update flexgen compatible within stih418-clock
      ARM: dts: sti: update flexgen compatible within stih407-clock
      ARM: dts: sti: update flexgen compatible within stih410-clock
      ARM: dts: sti: update clkgen-pll entries in stih407-clock
      ARM: dts: sti: update clkgen-pll entries in stih410-clock
      ARM: dts: sti: update clkgen-pll entries in stih418-clock
      ARM: dts: sti: update clkgen-fsyn entries in stih407-clock
      ARM: dts: sti: update clkgen-fsyn entries in stih410-clock
      ARM: dts: sti: update clkgen-fsyn entries in stih418-clock
      ARM: dts: sti: add the spinor controller node within stih407-family
      ARM: dts: sti: disable rng11 on the stih418 platform
      ARM: dts: sti: add the thermal sensor node within stih418
      ARM: dts: sti: Introduce 4KOpen (stih418-b2264) board

Patrice Chotard (4):
      ARM: dts: sti: remove clk_ignore_unused from bootargs for stih407-b2120
      ARM: dts: sti: remove clk_ignore_unused from bootargs for stih410-b2120
      ARM: dts: sti: remove clk_ignore_unused from bootargs for stih418-b2199
      ARM: dts: sti: remove clk_ignore_unused from bootargs for stih410-b2260

 arch/arm/boot/dts/Makefile            |   3 +-
 arch/arm/boot/dts/stih407-b2120.dts   |   1 -
 arch/arm/boot/dts/stih407-clock.dtsi  | 128 +++-------------------------
 arch/arm/boot/dts/stih407-family.dtsi |  15 ++++
 arch/arm/boot/dts/stih410-b2120.dts   |   1 -
 arch/arm/boot/dts/stih410-b2260.dts   |   1 -
 arch/arm/boot/dts/stih410-clock.dtsi  | 138 +++----------------------------
 arch/arm/boot/dts/stih418-b2199.dts   |   1 -
 arch/arm/boot/dts/stih418-b2264.dts   | 151 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/stih418-clock.dtsi  | 136 +++---------------------------
 arch/arm/boot/dts/stih418.dtsi        |  12 +++
 11 files changed, 215 insertions(+), 372 deletions(-)
 create mode 100644 arch/arm/boot/dts/stih418-b2264.dts


From krzysztof.kozlowski at canonical.com  Fri Aug  6 00:48:47 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 6 Aug 2021 09:48:47 +0200
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <CAPLW+4nDS0atrbUFagDA0W_Ky5MvOiY+N+NQoQ+me4pndp_iWg@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <455cfb5e-dff7-a5c0-3875-49abe3e900f3@canonical.com>
 <CAPLW+4nDS0atrbUFagDA0W_Ky5MvOiY+N+NQoQ+me4pndp_iWg@mail.gmail.com>
Message-ID: <68734f6c-fc76-595c-8d34-8924dbbbb845@canonical.com>

On 06/08/2021 01:06, Sam Protsenko wrote:
> On Sat, 31 Jul 2021 at 12:03, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
> 
>>>
>>> This patch adds minimal SoC support. Particular board device tree files
>>> can include exynos850.dtsi file to get SoC related nodes, and then
>>> reference those nodes further as needed.
>>>
>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>> ---
>>>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
>>>  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
>>>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
>>
>> Not buildable. Missing Makefile, missing DTS. Please submit with initial
>> DTS, otherwise no one is able to verify it even compiles.
>>
> 
> This device is not available for purchase yet. I'll send the patch for
> board dts once it's announced. I can do all the testing for now, if
> you have any specific requests. Would it be possible for us to review
> and apply only SoC support for now? Will send v2 soon...

What you propose is equal to adding a driver (C source code) without
ability to compile it. What's the point of having it in the kernel? It's
unverifiable, unbuildable and unusable.

We can review the DTSI however merging has to be with a DTS. Usually the
SoC vendor adds first an evalkit (e.g. SMDK board). Maybe you have one
for Exynos850? Otherwise if you cannot disclose the actual board, the
DTSI will have to wait. You can submit drivers, though.

> 
>>>  3 files changed, 1057 insertions(+)
>>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
>>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
>>>
>>> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>> new file mode 100644
>>> index 000000000000..4cf0a22cc6db
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>> @@ -0,0 +1,782 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
>>> + *
>>> + * Copyright (C) 2017 Samsung Electronics Co., Ltd.
>>> + * Copyright (C) 2021 Linaro Ltd.
>>> + *
>>> + * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
>>> + * tree nodes in this file.
>>> + */
>>> +
>>> +#include <dt-bindings/interrupt-controller/exynos850.h>
>>> +
>>> +/ {
>>> +     /* ALIVE */
>>> +     pinctrl at 11850000 {
>>> +             gpa0: gpa0 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>
>> That's odd a little, why three cells? How this would be used/referenced?
>>
> 
> Fixed. You are right, irq_domain_xlate_twocell() is used in
> pinctrl-exynos.c. Btw, that fixed the use-case when gpX is specified
> as interrupt-parrent for other nodes.
> 
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT0 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT1 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT2 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT3 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT4 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT5 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT6 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT7 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpa1: gpa1 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT8 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT9 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT10 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT11 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT12 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT13 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT14 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT15 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpa2: gpa2 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT16 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT17 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT18 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT19 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT20 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT21 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT22 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT23 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpa3: gpa3 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT24 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT25 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT26 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT27 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT28 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT29 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT30 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT31 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpa4: gpa4 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT32 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT33 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT34 IRQ_TYPE_LEVEL_HIGH>,
>>> +                         <GIC_SPI INTREQ__ALIVE_EINT35 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpq0: gpq0 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             /* USI_PERI_UART_DBG */
>>> +             uart0_bus: uart0-bus {
>>> +                     samsung,pins = "gpq0-0", "gpq0-1";
>>> +                     samsung,pin-function = <2>;
>>
>> EXYNOS_PIN_FUNC_2
>>
> 
> Done, thanks.
> 
>>> +                     samsung,pin-pud = <0>;
>>
>> EXYNOS_PIN_PULL_xx?
>>
> 
> Yes, replaced pin-pud values with these constants, thanks. Won't touch
> pin-drv properties, though, as different domains have different
> meanings for the same values, so don't want to introduce the whole
> bunch of consts.
> 
>>> +             };
>>> +
>>> +             decon_f_te_on: decon_f_te_on {
>>
>> 1. Where is it used?
>> 2. Use hyphens in node names.
>> Please build it with W=1 and fix the warnings.
>>
> 
> decon* nodes seem like leftover from vendor kernel. Those are not
> connected anywhere on my board, so I removed those nodes.
> 
> Also fixed node names as you suggested, and fixed all stuff found with
> W=1 build, thanks for reminding me that.
> 
>>> +                     samsung,pins = "gpa4-1";
>>
>> Order the nodes based on first pin name, so:
>> i2c5_bus
>> i2c6_bus
>> decon_f_te_on
>> uart0_bus
>>
> 
> Done. Also rearranged the nodes in that way for other pinctrl domains.
> 
>>> +                     samsung,pin-function = <0xf>;
>>> +             };
>>> +
>>> +             decon_f_te_off: decon_f_te_off {
>>
>> Where is it used?
>>
> 
> Removed, as explained above.
> 
>>> +                     samsung,pins = "gpa4-1";
>>> +                     samsung,pin-function = <0x0>;
>>> +             };
>>> +
>>> +             /* I2C_5 | CAM_PMIC_I2C */
>>
>> This comment is confusing. I2C-5 is obvious from node name and label.
>> CAM_PMIC_I2C does not look like property of SoC but board.
>>
> 
> Yeah, unfortunately this confusing I2C naming (CAM_PMIC_I2C and
> MOTOR_I2C) actually comes from TRM and SoC schematic symbol.

Schematic symbol of SoC? Interesting document... What do you have there?
Internals of SoC?


> So in
> Device Tree it's called just i2c5 and i2c6 (because it's a regular I2C
> really), but in TRM it's a mix of both names. I guess it's just a poor
> pin function naming, done by SoC designers.
> 
> That said, I suggest changing these comments to something like this:
> 
>     /* I2C5 (also called CAM_PMIC_I2C in TRM) */
>     /* I2C6 (also called MOTOR_I2C in TRM) */

OK, assuming that by TRM you mean Exynos850 TRM.

> 
>>> +             i2c5_bus: i2c5-bus {
>>> +                     samsung,pins = "gpa3-5", "gpa3-6";
>>> +                     samsung,pin-function = <3>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             /* I2C_6 | MOTOR_I2C */
>>> +             i2c6_bus: i2c6-bus {
>>> +                     samsung,pins = "gpa3-7", "gpa4-0";
>>> +                     samsung,pin-function = <3>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +     };
>>> +
>>> +     /* CMGP */
>>> +     pinctrl at 11c30000 {
>>> +             gpm0: gpm0 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM00 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpm1: gpm1 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM01 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpm2: gpm2 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM02 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpm3: gpm3 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM03 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpm4: gpm4 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM04 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             gpm5: gpm5 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <3>;
>>> +                     interrupt-parent = <&gic>;
>>> +                     interrupts =
>>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM05 IRQ_TYPE_LEVEL_HIGH>;
>>> +             };
>>> +
>>> +             /* usi_cmgp00 */
>>> +             hsi2c3_bus: hsi2c3-bus {
>>> +                     samsung,pins = "gpm0-0", "gpm1-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             /* usi_cmgp01 */
>>> +             hsi2c4_bus: hsi2c4-bus {
>>> +                     samsung,pins = "gpm4-0", "gpm5-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             /* spi usi_cmgp00 */
>>> +             spi1_bus: spi1-bus {
>>> +                     samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             spi1_cs: spi1-cs {
>>> +                     samsung,pins = "gpm3-0";
>>> +                     samsung,pin-function = <1>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             spi1_cs_func: spi1-cs-func {
>>> +                     samsung,pins = "gpm3-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             /* spi usi_cmgp01 */
>>> +             spi2_bus: spi2-bus {
>>> +                     samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             spi2_cs: spi2-cs {
>>> +                     samsung,pins = "gpm7-0";
>>> +                     samsung,pin-function = <1>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             spi2_cs_func: spi2-cs-func {
>>> +                     samsung,pins = "gpm7-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             /* usi_cmgp00_uart */
>>> +             uart1_bus_single: uart1-bus {
>>> +                     samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +             };
>>> +
>>> +             uart1_bus_dual: uart1-bus-dual {
>>> +                     samsung,pins = "gpm0-0", "gpm1-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +             };
>>> +
>>> +             /* usi_cmgp01_uart */
>>> +             uart2_bus_single: uart2-bus {
>>> +                     samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +             };
>>> +
>>> +             uart2_bus_dual: uart2-bus-dual {
>>> +                     samsung,pins = "gpm4-0", "gpm5-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +             };
>>> +     };
>>> +
>>> +     /* AUD */
>>> +     pinctrl at 14a60000 {
>>> +             gpb0: gpb0 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             gpb1: gpb1 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             aud_codec_mclk: aud-codec-mclk {
>>> +                     samsung,pins = "gpb0-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <1>;
>>> +             };
>>> +
>>> +             aud_codec_mclk_idle: aud-codec-mclk-idle {
>>> +                     samsung,pins = "gpb0-0";
>>> +                     samsung,pin-function = <0>;
>>> +                     samsung,pin-pud = <1>;
>>> +             };
>>> +
>>> +             aud_i2s0_bus: aud-i2s0-bus {
>>> +                     samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <1>;
>>> +             };
>>> +
>>> +             aud_i2s0_idle: aud-i2s0-idle {
>>> +                     samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
>>> +                     samsung,pin-function = <0>;
>>> +                     samsung,pin-pud = <1>;
>>> +             };
>>> +
>>> +             aud_i2s1_bus: aud-i2s1-bus {
>>> +                     samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <1>;
>>> +             };
>>> +
>>> +             aud_i2s1_idle: aud-i2s1-idle {
>>> +                     samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
>>> +                     samsung,pin-function = <0>;
>>> +                     samsung,pin-pud = <1>;
>>> +             };
>>> +
>>> +             aud_fm_bus: aud-fm-bus {
>>> +                     samsung,pins = "gpb1-4";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <1>;
>>> +             };
>>> +
>>> +             aud_fm_idle: aud-fm-idle {
>>> +                     samsung,pins = "gpb1-4";
>>> +                     samsung,pin-function = <0>;
>>> +                     samsung,pin-pud = <1>;
>>> +             };
>>> +     };
>>> +
>>> +     /* HSI */
>>> +     pinctrl at 13430000 {
>>> +             gpf2: gpf2 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             sd2_clk: sd2-clk {
>>> +                     samsung,pins = "gpf2-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sd2_cmd: sd2-cmd {
>>> +                     samsung,pins = "gpf2-1";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <2>;
>>> +              };
>>> +
>>> +             sd2_bus1: sd2-bus-width1 {
>>> +                     samsung,pins = "gpf2-2";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sd2_bus4: sd2-bus-width4 {
>>> +                     samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sd2_clk_fast_slew_rate_1x: sd2-clk_fast_slew_rate_1x {
>>> +                     samsung,pins = "gpf2-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             sd2_clk_fast_slew_rate_1_5x: sd2-clk_fast_slew_rate_1_5x {
>>> +                     samsung,pins = "gpf2-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <1>;
>>> +             };
>>> +
>>> +             sd2_clk_fast_slew_rate_2x: sd2-clk_fast_slew_rate_2x {
>>> +                     samsung,pins = "gpf2-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sd2_clk_fast_slew_rate_2_5x: sd2-clk_fast_slew_rate_2_5x {
>>> +                     samsung,pins = "gpf2-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>> +             sd2_clk_fast_slew_rate_3x: sd2-clk_fast_slew_rate_3x {
>>> +                     samsung,pins = "gpf2-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <4>;
>>> +             };
>>> +
>>> +             sd2_clk_fast_slew_rate_4x: sd2-clk_fast_slew_rate_4x {
>>> +                     samsung,pins = "gpf2-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <5>;
>>> +             };
>>> +
>>> +             sd2_pins_as_pdn: sd2-pins-as-pdn {
>>> +                     samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
>>> +                                    "gpf2-4", "gpf2-5";
>>> +                     samsung,pin-function = <0>;
>>> +                     samsung,pin-pud = <2>;
>>> +             };
>>> +
>>
>> No need for blank line.
>>
> 
> Fixed.
> 
>>> +     };
>>> +
>>> +     /* CORE */
>>> +     pinctrl at 12070000 {
>>> +             gpf0: gpf0 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             sd0_clk: sd0-clk {
>>> +                     samsung,pins = "gpf0-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>> +             sd0_cmd: sd0-cmd {
>>> +                     samsung,pins = "gpf0-1";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>> +             sd0_rdqs: sd0-rdqs {
>>> +                     samsung,pins = "gpf0-2";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <1>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>> +             sd0_nreset: sd0-nreset {
>>> +                     samsung,pins = "gpf0-3";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>> +             sd0_clk_fast_slew_rate_1x: sd0-clk_fast_slew_rate_1x {
>>> +                     samsung,pins = "gpf0-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <1>;
>>> +             };
>>> +
>>> +             sd0_clk_fast_slew_rate_2x: sd0-clk_fast_slew_rate_2x {
>>> +                     samsung,pins = "gpf0-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sd0_clk_fast_slew_rate_3x: sd0-clk_fast_slew_rate_3x {
>>> +                     samsung,pins = "gpf0-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sd0_clk_fast_slew_rate_4x: sd0-clk_fast_slew_rate_4x {
>>> +                     samsung,pins = "gpf0-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>> +             gpf1: gpf1 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             sd0_bus1: sd0-bus-width1 {
>>> +                     samsung,pins = "gpf1-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>> +             sd0_bus4: sd0-bus-width4 {
>>> +                     samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>> +             sd0_bus8: sd0-bus-width8 {
>>> +                     samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +     };
>>> +
>>> +     /* PERI */
>>> +     pinctrl at 139b0000 {
>>> +             gpg0: gpg0 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             gpp0: gpp0 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +             gpp1: gpp1 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             gpp2: gpp2 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             gpg1: gpg1 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             gpg2: gpg2 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             gpg3: gpg3 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             gpc0: gpc0 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             gpc1: gpc1 {
>>> +                     gpio-controller;
>>> +                     #gpio-cells = <2>;
>>> +
>>> +                     interrupt-controller;
>>> +                     #interrupt-cells = <2>;
>>> +             };
>>> +
>>> +             xclkout: xclkout {
>>> +                     samsung,pins = "gpq0-2";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +             };
>>> +
>>> +             /* usi_hsi2c_0 */
>>
>> Comment seems to duplicate node name/label.
>>
> 
> I think the comment is useful, maybe just designed poorly. It's
> pointing out that this HS-I2C block is based on USI IP-core. Basically
> we have 7 USI blocks in this SoC:
>   - 5 USIs that pre-defined: HSI2C0, HSI2C1, HSI2C2, UART0 and SPI0;
> although AFAIU they can be changed via System Register as well, but
> seems like nobody does that
>   - 2 USIs from CMGP blocks (CMGP0 and CMGP1), which are actually configurable
> 
> I will revise all such comments like this, just to show those blocks
> are based on USI design:
> 
>     /* USI: HSI2C0 */

OK

> 
> At least when I was bringing up this board, I was really confused for
> long time about this USI business. So I'm sure some kind of comments
> might be actually helpful. And that's one reason to keep
> exynos850-usi.dtsi file: although I removed it for now, squashing it
> into exynos850.dtsi, I think it might be a good idea to bring that
> back once all USI nodes are described. Just thinking aloud :)
> 
>>> +             hsi2c0_bus: hsi2c0-bus {
>>> +                     samsung,pins = "gpc1-0", "gpc1-1";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             /* usi_hsi2c_1 */
>>> +             hsi2c1_bus: hsi2c1-bus {
>>> +                     samsung,pins = "gpc1-2", "gpc1-3";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             /* usi_hsi2c_2 */
>>> +             hsi2c2_bus: hsi2c2-bus {
>>> +                     samsung,pins = "gpc1-4", "gpc1-5";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             /* usi_spi_0 */
>>> +             spi0_bus: spi0-bus {
>>> +                     samsung,pins = "gpp2-0", "gpp2-2", "gpp2-3";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             spi0_cs: spi0-cs {
>>> +                     samsung,pins = "gpp2-1";
>>> +                     samsung,pin-function = <1>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             spi0_cs_func: spi0-cs-func {
>>> +                     samsung,pins = "gpp2-1";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             i2c0_bus: i2c0-bus {
>>> +                     samsung,pins = "gpp0-0", "gpp0-1";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             i2c1_bus: i2c1-bus {
>>> +                     samsung,pins = "gpp0-2", "gpp0-3";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             i2c2_bus: i2c2-bus {
>>> +                     samsung,pins = "gpp0-4", "gpp0-5";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             i2c3_bus: i2c3-bus {
>>> +                     samsung,pins = "gpp1-0", "gpp1-1";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             i2c4_bus: i2c4-bus {
>>> +                     samsung,pins = "gpp1-2", "gpp1-3";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <3>;
>>> +                     samsung,pin-drv = <0>;
>>> +             };
>>> +
>>> +             fm_lna_en: fm-lna-en {
>>> +                     samsung,pins = "gpg2-3";
>>> +                     samsung,pin-function = <1>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-val = <0>;
>>> +             };
>>> +
>>> +             sensor_mclk0_in: sensor-mclk0-in {
>>> +                     samsung,pins = "gpc0-0";
>>> +                     samsung,pin-function = <0>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sensor_mclk0_out: sensor-mclk0-out {
>>> +                     samsung,pins = "gpc0-0";
>>> +                     samsung,pin-function = <1>;
>>> +                     samsung,pin-pud = <1>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sensor_mclk0_fn: sensor-mclk0-fn {
>>
>> No, seriously. What sensor is it? In SoC?
>>
> 
> In this context, "sensor" stands for "camera". Of course, it resides
> (or rather *may* reside) outside of the SoC. This is just useful pin
> configuration for camera master clock lines (3 of them). On schematic
> those 3 lines are grouped into "MCLK" block, and those pins main
> function is CAM_MCLK. I guess it makes sense to keep those
> definitions, as I doubt somebody would actually consider using those
> lines for somthing else. Or I can remove all those sensor*
> definitions, if you'd like, then those can be added later, when camera
> support cames in.

Hmmm, indeed we define in pinctrl useful typical functions and I
understand this one is such. Let's keep them then.

> 
>>> +                     samsung,pins = "gpc0-0";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sensor_mclk1_in: sensor-mclk1-in {
>>> +                     samsung,pins = "gpc0-1";
>>> +                     samsung,pin-function = <0>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sensor_mclk1_out: sensor-mclk1-out {
>>> +                     samsung,pins = "gpc0-1";
>>> +                     samsung,pin-function = <1>;
>>> +                     samsung,pin-pud = <1>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sensor_mclk1_fn: sensor-mclk1-fn {
>>> +                     samsung,pins = "gpc0-1";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sensor_mclk2_in: sensor-mclk2-in {
>>> +                     samsung,pins = "gpc0-2";
>>> +                     samsung,pin-function = <0>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sensor_mclk2_out: sensor-mclk2-out {
>>> +                     samsung,pins = "gpc0-2";
>>> +                     samsung,pin-function = <1>;
>>> +                     samsung,pin-pud = <1>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +
>>> +             sensor_mclk2_fn: sensor-mclk2-fn {
>>> +                     samsung,pins = "gpc0-2";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <0>;
>>> +                     samsung,pin-drv = <2>;
>>> +             };
>>> +     };
>>> +};
>>> diff --git a/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi b/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
>>> new file mode 100644
>>> index 000000000000..fb243e0a6260
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
>>> @@ -0,0 +1,30 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Samsung's Exynos850 SoC USI device tree source
>>> + *
>>> + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
>>> + * Copyright (C) 2021 Linaro Ltd.
>>> + *
>>> + * Samsung's Exynos850 SoC USI channels are listed in this file as device tree
>>> + * nodes.
>>
>> Why here not in exynos850.dtsi?
>>
> 
> Yeah, you're right. As it's only serial_0 for now, I've moved that
> into exynos850.dtsi and removed exynos850-usi.dtsi.
> 
>>> + */
>>> +
>>> +#include <dt-bindings/clock/exynos850.h>
>>> +
>>> +/ {
>>> +     aliases {
>>> +             uart0 = &serial_0;
>>> +     };
>>> +
>>> +     /* USI_UART */
>>> +     serial_0: uart at 13820000 {
>>
>> This should ne in soc node.
>>
> 
> Done.
> 
>>> +             compatible = "samsung,exynos850-uart";
>>> +             reg = <0x0 0x13820000 0x100>;
>>> +             interrupts = <GIC_SPI INTREQ__UART IRQ_TYPE_LEVEL_HIGH>;
>>> +             pinctrl-names = "default";
>>> +             pinctrl-0 = <&uart0_bus>;
>>> +             clocks = <&clock GATE_UART_QCH>, <&clock DOUT_UART>;
>>> +             clock-names = "gate_uart_clk0", "uart";
>>> +             status = "disabled";
>>> +     };
>>> +};
>>> diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
>>> new file mode 100644
>>> index 000000000000..ed2d1c8ae0c3
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
>>> @@ -0,0 +1,245 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Samsung Exynos850 SoC device tree source
>>> + *
>>> + * Copyright (C) 2018 Samsung Electronics Co., Ltd.
>>> + * Copyright (C) 2021 Linaro Ltd.
>>> + *
>>> + * Samsung Exynos850 SoC device nodes are listed in this file.
>>> + * Exynos based board files can include this file and provide
>>> + * values for board specific bindings.
>>> + */
>>> +
>>> +#include <dt-bindings/interrupt-controller/exynos850.h>
>>> +#include <dt-bindings/clock/exynos850.h>
>>> +#include "exynos850-pinctrl.dtsi"
>>> +#include "exynos850-usi.dtsi"
>>> +
>>> +/ {
>>
>> Add a comment like:
>> /* Also known under engineering name exynos3830 */
>>
> 
> Sure.
> 
>>> +     compatible = "samsung,exynos850";
>>
>> Undocumented compatible. Checkpatch should complain.
>>
> 
> It actually doesn't, though it does complain about other undocumented
> compatibles. I understand that it should be documented in
> samsung-boards.yaml, but is it ok with you if I do that later, when
> adding some actual board's dts? Just don't want to have two patches
> for that.

We're back to the first question - it needs to come with DTS and then
you document both compatibles.

Best regards,
Krzysztof


From alistair23 at gmail.com  Fri Aug  6 01:19:00 2021
From: alistair23 at gmail.com (Alistair Francis)
Date: Fri, 6 Aug 2021 18:19:00 +1000
Subject: [PATCH v2 1/1] mfd: simple-mfd-i2c: Add support for registering
 devices via MFD cells
In-Reply-To: <20210805085611.864188-1-lee.jones@linaro.org>
References: <20210805085611.864188-1-lee.jones@linaro.org>
Message-ID: <CAKmqyKMPg8kikB7Ym6qc+VYAwt0DvyXK+xqu3SwgJwcaCyUrbA@mail.gmail.com>

On Thu, Aug 5, 2021 at 6:56 PM Lee Jones <lee.jones at linaro.org> wrote:
>
> More devices are cropping up requiring only Regmap initialisation and
> child registration functionality.  We currently only support that if
> all required devices are represented by their own Device Tree nodes
> complete with compatible strings.
>
> However, not everyone is happy with adding empty nodes that provide no
> additional device information into the Device Tree.
>
> Rather than have a plethora of mostly empty, function-less drivers in
> MFD, we'll support those simple cases in here instead via MFD cells.
>
> Cc: Michael Walle <michael at walle.cc>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Alistair Francis <alistair23 at gmail.com>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---
> v2:
>  - Check for empty of_device_id .data entry
>
>  drivers/mfd/simple-mfd-i2c.c | 41 +++++++++++++++++++++++++++++-------
>  drivers/mfd/simple-mfd-i2c.h | 32 ++++++++++++++++++++++++++++
>  2 files changed, 65 insertions(+), 8 deletions(-)
>  create mode 100644 drivers/mfd/simple-mfd-i2c.h
>
> diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
> index 87f684cff9a17..583e8c7924af0 100644
> --- a/drivers/mfd/simple-mfd-i2c.c
> +++ b/drivers/mfd/simple-mfd-i2c.c
> @@ -2,39 +2,64 @@
>  /*
>   * Simple MFD - I2C
>   *
> + * Author(s):
> + *     Michael Walle <michael at walle.cc>
> + *     Lee Jones <lee.jones at linaro.org>
> + *
>   * This driver creates a single register map with the intention for it to be
>   * shared by all sub-devices.  Children can use their parent's device structure
>   * (dev.parent) in order to reference it.
>   *
>   * Once the register map has been successfully initialised, any sub-devices
> - * represented by child nodes in Device Tree will be subsequently registered.
> + * represented by child nodes in Device Tree or via the MFD cells in this file
> + * will be subsequently registered.
>   */
>
>  #include <linux/i2c.h>
>  #include <linux/kernel.h>
> +#include <linux/mfd/core.h>
>  #include <linux/module.h>
>  #include <linux/of_platform.h>
>  #include <linux/regmap.h>
>
> -static const struct regmap_config simple_regmap_config = {
> +#include "simple-mfd-i2c.h"
> +
> +static const struct regmap_config regmap_config_8r_8v = {
>         .reg_bits = 8,
>         .val_bits = 8,
>  };
>
>  static int simple_mfd_i2c_probe(struct i2c_client *i2c)
>  {
> -       const struct regmap_config *config;
> +       const struct simple_mfd_data *simple_mfd_data;
> +       const struct regmap_config *regmap_config;
>         struct regmap *regmap;
> +       int ret;
> +
> +       simple_mfd_data = device_get_match_data(&i2c->dev);
>
> -       config = device_get_match_data(&i2c->dev);
> -       if (!config)
> -               config = &simple_regmap_config;
> +       /* If no regmap_config is specified, use the default 8reg and 8val bits */
> +       if (!simple_mfd_data || !simple_mfd_data->regmap_config)
> +               regmap_config = &regmap_config_8r_8v;
> +       else
> +               regmap_config = simple_mfd_data->regmap_config;
>
> -       regmap = devm_regmap_init_i2c(i2c, config);
> +       regmap = devm_regmap_init_i2c(i2c, regmap_config);
>         if (IS_ERR(regmap))
>                 return PTR_ERR(regmap);
>
> -       return devm_of_platform_populate(&i2c->dev);
> +       /* If no MFD cells are spedified, use register the DT child nodes instead */
> +       if (!simple_mfd_data || !simple_mfd_data->mfd_cell)
> +               return devm_of_platform_populate(&i2c->dev);
> +
> +       ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
> +                                  simple_mfd_data->mfd_cell,
> +                                  simple_mfd_data->mfd_cell_size,
> +                                  NULL, 0, NULL);
> +       if (!ret)

Shouldn't this be `if (ret)` instead?

With that changed this works for me as well:

Reviewed-by: Alistair Francis <alistair at alistair23.me>
Tested-by: Alistair Francis <alistair at alistair23.me>

Alistair

> +               dev_err(&i2c->dev, "Failed to add child devices\n");
> +
> +       return ret;
>  }
>
>  static const struct of_device_id simple_mfd_i2c_of_match[] = {
> diff --git a/drivers/mfd/simple-mfd-i2c.h b/drivers/mfd/simple-mfd-i2c.h
> new file mode 100644
> index 0000000000000..7cb2bdd347d97
> --- /dev/null
> +++ b/drivers/mfd/simple-mfd-i2c.h
> @@ -0,0 +1,32 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Simple MFD - I2C
> + *
> + * Author: Lee Jones <lee.jones at linaro.org>
> + *
> + * This driver creates a single register map with the intention for it to be
> + * shared by all sub-devices.  Children can use their parent's device structure
> + * (dev.parent) in order to reference it.
> + *
> + * This driver creates a single register map with the intention for it to be
> + * shared by all sub-devices.  Children can use their parent's device structure
> + * (dev.parent) in order to reference it.
> + *
> + * Once the register map has been successfully initialised, any sub-devices
> + * represented by child nodes in Device Tree or via the MFD cells in the
> + * associated C file will be subsequently registered.
> + */
> +
> +#ifndef __MFD_SIMPLE_MFD_I2C_H
> +#define __MFD_SIMPLE_MFD_I2C_H
> +
> +#include <linux/mfd/core.h>
> +#include <linux/regmap.h>
> +
> +struct simple_mfd_data {
> +       const struct regmap_config *regmap_config;
> +       const struct mfd_cell *mfd_cell;
> +       size_t mfd_cell_size;
> +};
> +
> +#endif /* __MFD_SIMPLE_MFD_I2C_H */
> --
> 2.32.0.605.g8dce9f2422-goog
>


From monstr at monstr.eu  Fri Aug  6 01:23:28 2021
From: monstr at monstr.eu (Michal Simek)
Date: Fri, 6 Aug 2021 10:23:28 +0200
Subject: [PATCH v2 00/33] arm64: zynqmp: Extend board description
In-Reply-To: <cover.1623684253.git.michal.simek@xilinx.com>
References: <cover.1623684253.git.michal.simek@xilinx.com>
Message-ID: <4380bec9-a451-52fe-a49f-e305821f7ee9@monstr.eu>



On 6/14/21 5:25 PM, Michal Simek wrote:
> Hi,
> 
> over years couple of drivers were upstream and it is time to sync it up.
> On the top of it also adding new Kria boards which are using new overlay
> infrastructure which check if that overlays can be applied to base DT file.
> 
> Thanks,
> Michal
> 
> Changes in v2:
> - Add reviewed-by from Laurent
> - New patch in the series
> - New patch in the series
> - Use sugar syntax - reported by Geert
> - Update copyright years
> - Fix SD3.0 comment alignment
> - Remove one newline from Makefile
> 
> Amit Kumar Mahapatra (1):
>   arm64: zynqmp: Do not duplicate flash partition label property
> 
> Michal Simek (29):
>   arm64: zynqmp: Disable CCI by default
>   arm64: zynqmp: Enable fpd_dma for zcu104 platforms
>   arm64: zynqmp: Fix irps5401 device nodes
>   arm64: zynqmp: Add pinctrl description for all boards
>   arm64: zynqmp: Correct zcu111 psgtr description
>   arm64: zynqmp: Wire psgtr for zc1751-xm015
>   arm64: zynqmp: Correct psgtr description for zcu100-revC
>   arm64: zynqmp: Add phy description for usb3.0
>   arm64: zynqmp: Disable WP on zcu111
>   arm64: zynqmp: Add missing mio-bank properties to dc1 and dc5
>   arm64: zynqmp: Wire DP and DPDMA for dc1/dc4
>   arm64: zynqmp: Enable nand driver for dc2 and dc3
>   arm64: zynqmp: Remove additional newline
>   arm64: zynqmp: Move clock node to zynqmp-clk-ccf.dtsi
>   arm64: zynqmp: Add nvmem alises for eeproms
>   arm64: zynqmp: List reset property for ethernet phy
>   arm64: zynqmp: Remove can aliases from zc1751
>   arm64: zynqmp: Move DP nodes to the end of file on zcu106
>   arm64: zynqmp: Add note about UHS mode on some boards
>   arm64: zynqmp: Remove information about dma clock on zcu106
>   arm64: zynqmp: Wire qspi on multiple boards
>   arm64: zynqmp: Move rtc to different location on zcu104-revA
>   arm64: zynqmp: Add reset description for sata
>   arm64: zynqmp: Sync psgtr node location with zcu104-revA
>   arm64: zynqmp: Remove description for 8T49N287 and si5382 chips
>   arm64: zynqmp: Add support for zcu102-rev1.1 board
>   arm64: zynqmp: Enable xlnx,zynqmp-dwc3 driver for xilinx boards
>   arm64: zynqmp: Add psgtr description to zc1751 dc1 board
>   arm64: zynqmp: Add support for Xilinx Kria SOM board
> 
> Mounika Grace Akula (1):
>   arm64: zynqmp: Add reset-on-timeout to all boards and modify default
>     timeout value
> 
> Srinivas Neeli (1):
>   arm64: zynqmp: Update rtc calibration value
> 
> Stefano Stabellini (1):
>   arm64: zynqmp: Add missing SMID for pcie to zynqmp.dtsi
> 
>  .../devicetree/bindings/arm/xilinx.yaml       |  32 ++
>  arch/arm64/boot/dts/xilinx/Makefile           |  11 +
>  .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  13 +-
>  .../boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts  | 335 +++++++++++++++++
>  .../boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts  | 318 ++++++++++++++++
>  .../boot/dts/xilinx/zynqmp-sm-k26-revA.dts    | 289 +++++++++++++++
>  .../boot/dts/xilinx/zynqmp-smk-k26-revA.dts   |  21 ++
>  .../boot/dts/xilinx/zynqmp-zc1232-revA.dts    |  16 +-
>  .../boot/dts/xilinx/zynqmp-zc1254-revA.dts    |  16 +-
>  .../dts/xilinx/zynqmp-zc1751-xm015-dc1.dts    | 298 ++++++++++++++-
>  .../dts/xilinx/zynqmp-zc1751-xm016-dc2.dts    | 342 +++++++++++++++++-
>  .../dts/xilinx/zynqmp-zc1751-xm017-dc3.dts    |  23 +-
>  .../dts/xilinx/zynqmp-zc1751-xm018-dc4.dts    |  24 +-
>  .../dts/xilinx/zynqmp-zc1751-xm019-dc5.dts    | 330 ++++++++++++++++-
>  .../boot/dts/xilinx/zynqmp-zcu100-revC.dts    | 264 +++++++++++++-
>  .../boot/dts/xilinx/zynqmp-zcu102-rev1.1.dts  |  15 +
>  .../boot/dts/xilinx/zynqmp-zcu102-revA.dts    | 321 +++++++++++++++-
>  .../boot/dts/xilinx/zynqmp-zcu102-revB.dts    |   3 +-
>  .../boot/dts/xilinx/zynqmp-zcu104-revA.dts    | 292 ++++++++++++++-
>  .../boot/dts/xilinx/zynqmp-zcu104-revC.dts    | 250 ++++++++++++-
>  .../boot/dts/xilinx/zynqmp-zcu106-revA.dts    | 341 ++++++++++++++++-
>  .../boot/dts/xilinx/zynqmp-zcu111-revA.dts    | 275 +++++++++++++-
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  99 +++--
>  23 files changed, 3833 insertions(+), 95 deletions(-)
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.1.dts
> 

Applied 1-30, 32.

31 and 33 requires newer version.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs





From pali at kernel.org  Fri Aug  6 01:28:18 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 6 Aug 2021 10:28:18 +0200
Subject: [PATCH v4 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell,armada-3700-uart-clock
In-Reply-To: <162820981926.19113.12529765873453602213@swboyd.mtv.corp.google.com>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
 <20210802144529.1520-4-pali@kernel.org>
 <162820981926.19113.12529765873453602213@swboyd.mtv.corp.google.com>
Message-ID: <20210806082818.k3awj72j2yb2bbhe@pali>

On Thursday 05 August 2021 17:30:19 Stephen Boyd wrote:
> > diff --git a/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> > new file mode 100644
> > index 000000000000..5ef04f3affda
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> > @@ -0,0 +1,49 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/clock/marvell,armada-3700-uart-clock#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +title: Marvell Armada 3720 UART clocks
> 
> Please add a newline here
> 
> > +properties:
> > +  compatible:
> > +    const: marvell,armada-3700-uart-clock
> 
> Please add a newline here
> 
> > +  reg:
> > +    items:
> > +      - description: UART Clock Control Register
> > +      - description: UART 2 Baud Rate Divisor Register
> 
> Please add a newline here
> 
> > +  clocks:
> > +    description: |
> > +      List of parent clocks suitable for UART from following set:
> > +        "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal"
> > +      UART clock can use one from this set and when more are provided
> > +      then kernel would choose and configure the most suitable one.
> > +      It is suggest to specify at least one TBG clock to achieve
> > +      baudrates above 230400 and also to specify clock which bootloader
> > +      used for UART (most probably xtal) for smooth boot log on UART.
> 
> Please use items and const like clock-names for the clocks property.

It is already there, see below.

> The description makes me feel like the DT is configuring the choices
> available.

See description. It is kernel (driver) who is choosing one clock from
the set and then configure it a UART clock.

> Ideally, the clocks and clock-names properties are fixed in
> length and never change unless the compatible changes.
> 
> Please add a newline here
> 
> > +  clock-names:
> > +    items:
> > +      - const: TBG-A-P
> > +      - const: TBG-B-P
> > +      - const: TBG-A-S
> > +      - const: TBG-B-S
> > +      - const: xtal
> > +    minItems: 1
> > +    maxItems: 5
> 
> Please add a newline here
> 
> > +  '#clock-cells':
> > +    const: 1
> 
> Please add a newline here
> 
> > +required:
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +  - '#clock-cells'
> 
> Please add a newline here
> 
> > +additionalProperties: false
> 
> Please add a newline here
> 
> > +examples:
> > +  - |
> > +    uartclk: uartclk at 12000 {
> > +      compatible = "marvell,armada-3700-uart-clock";
> > +      reg = <0x12010 0x4>, <0x12210 0x4>;
> > +      clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>, <&xtalclk>;
> > +      clock-names = "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal";
> > +      #clock-cells = <1>;
> > +    };


From krzysztof.kozlowski at canonical.com  Fri Aug  6 01:26:35 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri,  6 Aug 2021 10:26:35 +0200
Subject: [PATCH] arm64: dts: synaptics: remove unused DTSI for AS370
Message-ID: <20210806082635.20239-1-krzysztof.kozlowski@canonical.com>

The as370.dtsi for Synaptics AS370 SoC does not have a user (DTS board
file), is uncompilable and untestable.  It was added back in 2018.  No
user appeared since that time, so assume it won't be added.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/arm/syna.txt          |   4 -
 arch/arm64/boot/dts/synaptics/as370.dtsi      | 173 ------------------
 2 files changed, 177 deletions(-)
 delete mode 100644 arch/arm64/boot/dts/synaptics/as370.dtsi

diff --git a/Documentation/devicetree/bindings/arm/syna.txt b/Documentation/devicetree/bindings/arm/syna.txt
index d8b48f2edf1b..851f48ead927 100644
--- a/Documentation/devicetree/bindings/arm/syna.txt
+++ b/Documentation/devicetree/bindings/arm/syna.txt
@@ -18,10 +18,6 @@ stable binding/ABI.
 
 ---------------------------------------------------------------
 
-Boards with the Synaptics AS370 SoC shall have the following properties:
-  Required root node property:
-    compatible: "syna,as370"
-
 Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500
 shall have the following properties:
 
diff --git a/arch/arm64/boot/dts/synaptics/as370.dtsi b/arch/arm64/boot/dts/synaptics/as370.dtsi
deleted file mode 100644
index 4bb5d650df9c..000000000000
--- a/arch/arm64/boot/dts/synaptics/as370.dtsi
+++ /dev/null
@@ -1,173 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (C) 2018 Synaptics Incorporated
- *
- * Author: Jisheng Zhang <jszhang at kernel.org>
- */
-
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-
-/ {
-	compatible = "syna,as370";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	psci {
-		compatible = "arm,psci-1.0";
-		method = "smc";
-	};
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		cpu0: cpu at 0 {
-			compatible = "arm,cortex-a53";
-			device_type = "cpu";
-			reg = <0x0>;
-			enable-method = "psci";
-			next-level-cache = <&l2>;
-			cpu-idle-states = <&CPU_SLEEP_0>;
-		};
-
-		cpu1: cpu at 1 {
-			compatible = "arm,cortex-a53";
-			device_type = "cpu";
-			reg = <0x1>;
-			enable-method = "psci";
-			next-level-cache = <&l2>;
-			cpu-idle-states = <&CPU_SLEEP_0>;
-		};
-
-		cpu2: cpu at 2 {
-			compatible = "arm,cortex-a53";
-			device_type = "cpu";
-			reg = <0x2>;
-			enable-method = "psci";
-			next-level-cache = <&l2>;
-			cpu-idle-states = <&CPU_SLEEP_0>;
-		};
-
-		cpu3: cpu at 3 {
-			compatible = "arm,cortex-a53";
-			device_type = "cpu";
-			reg = <0x3>;
-			enable-method = "psci";
-			next-level-cache = <&l2>;
-			cpu-idle-states = <&CPU_SLEEP_0>;
-		};
-
-		l2: cache {
-			compatible = "cache";
-		};
-
-		idle-states {
-			entry-method = "psci";
-			CPU_SLEEP_0: cpu-sleep-0 {
-				compatible = "arm,idle-state";
-				local-timer-stop;
-				arm,psci-suspend-param = <0x0010000>;
-				entry-latency-us = <75>;
-				exit-latency-us = <155>;
-				min-residency-us = <1000>;
-			};
-		};
-	};
-
-	osc: osc {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <25000000>;
-	};
-
-	pmu {
-		compatible = "arm,cortex-a53-pmu";
-		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-affinity = <&cpu0>,
-				     <&cpu1>,
-				     <&cpu2>,
-				     <&cpu3>;
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
-	};
-
-	soc at f7000000 {
-		compatible = "simple-bus";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges = <0 0 0xf7000000 0x1000000>;
-
-		gic: interrupt-controller at 901000 {
-			compatible = "arm,gic-400";
-			#interrupt-cells = <3>;
-			interrupt-controller;
-			reg = <0x901000 0x1000>,
-			      <0x902000 0x2000>,
-			      <0x904000 0x2000>,
-			      <0x906000 0x2000>;
-			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-		};
-
-		apb at e80000 {
-			compatible = "simple-bus";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges = <0 0xe80000 0x10000>;
-
-			uart0: serial at c00 {
-				compatible = "snps,dw-apb-uart";
-				reg = <0xc00 0x100>;
-				interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&osc>;
-				reg-shift = <2>;
-				status = "disabled";
-			};
-
-			gpio0: gpio at 1800 {
-				compatible = "snps,dw-apb-gpio";
-				reg = <0x1800 0x400>;
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				porta: gpio-port at 0 {
-					compatible = "snps,dw-apb-gpio-port";
-					gpio-controller;
-					#gpio-cells = <2>;
-					ngpios = <32>;
-					reg = <0>;
-					interrupt-controller;
-					#interrupt-cells = <2>;
-					interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
-				};
-			};
-
-			gpio1: gpio at 2000 {
-				compatible = "snps,dw-apb-gpio";
-				reg = <0x2000 0x400>;
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				portb: gpio-port at 1 {
-					compatible = "snps,dw-apb-gpio-port";
-					gpio-controller;
-					#gpio-cells = <2>;
-					ngpios = <32>;
-					reg = <0>;
-					interrupt-controller;
-					#interrupt-cells = <2>;
-					interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
-				};
-			};
-		};
-	};
-};
-- 
2.30.2



From michal.simek at xilinx.com  Fri Aug  6 01:42:29 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri,  6 Aug 2021 10:42:29 +0200
Subject: [PATCH] arm64: zynqmp: Remove not documented is-dual property
Message-ID: <876c53b92f99623bae45d5c0c5ae79ee3e24f745.1628239345.git.michal.simek@xilinx.com>

Remove is-dual not documented property and also update comment about QSPI
sizes to reflect dual configuration as 16MB + 16MB.
Only single configuration is supported now.

Reported-by: Quanyang Wang <quanyang.wang at windriver.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts | 3 +--
 arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts | 3 +--
 arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts | 3 +--
 3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
index becfc23a5610..3d8d14ef1ede 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
@@ -937,9 +937,8 @@ &psgtr {
 
 &qspi {
 	status = "okay";
-	is-dual = <1>;
 	flash at 0 {
-		compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
+		compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
index d2219373580a..057c04352591 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
@@ -931,9 +931,8 @@ &psgtr {
 
 &qspi {
 	status = "okay";
-	is-dual = <1>;
 	flash at 0 {
-		compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
+		compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
index dac5ba67a160..e1fff62a4cd5 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
@@ -773,9 +773,8 @@ &psgtr {
 
 &qspi {
 	status = "okay";
-	is-dual = <1>;
 	flash at 0 {
-		compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
+		compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0x0>;
-- 
2.32.0



From michal.simek at xilinx.com  Fri Aug  6 01:58:29 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri,  6 Aug 2021 10:58:29 +0200
Subject: [PATCH] arm64: zynqmp: Fix serial compatible string
Message-ID: <89b36e0a6187cc6b05b27a035efdf79173bd4486.1628240307.git.michal.simek@xilinx.com>

Based on commit 65a2c14d4f00 ("dt-bindings: serial: convert Cadence UART
bindings to YAML") compatible string should look like differently that's
why fix it to be aligned with dt binding.

Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 6f0fcec28ae2..b5fde9dddca5 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -786,7 +786,7 @@ ttc3: timer at ff140000 {
 		};
 
 		uart0: serial at ff000000 {
-			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
+			compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupts = <0 21 4>;
@@ -796,7 +796,7 @@ uart0: serial at ff000000 {
 		};
 
 		uart1: serial at ff010000 {
-			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
+			compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupts = <0 22 4>;
-- 
2.32.0



From paul.barker at sancloud.com  Fri Aug  6 01:59:06 2021
From: paul.barker at sancloud.com (Paul Barker)
Date: Fri,  6 Aug 2021 09:59:06 +0100
Subject: [PATCH 1/2] ARM: dts: am335x-sancloud-bbe: Fix missing pinctrl refs
Message-ID: <20210806085907.14615-1-paul.barker@sancloud.com>

pinctrl settings for the USB hub, barometer & accelerometer need to be
referenced from the relevant nodes to work.

Signed-off-by: Paul Barker <paul.barker at sancloud.com>
---
 arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi | 2 ++
 arch/arm/boot/dts/am335x-sancloud-bbe.dts         | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi b/arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi
index 627c18d23f94..55952fe8687c 100644
--- a/arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi
+++ b/arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi
@@ -58,6 +58,8 @@ &cpsw_port1 {
 
 &i2c0 {
 	usb2512b: usb-hub at 2c {
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_hub_ctrl>;
 		compatible = "microchip,usb2512b";
 		reg = <0x2c>;
 		reset-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/am335x-sancloud-bbe.dts b/arch/arm/boot/dts/am335x-sancloud-bbe.dts
index 2a0ac9f5dda7..efbe93135dbe 100644
--- a/arch/arm/boot/dts/am335x-sancloud-bbe.dts
+++ b/arch/arm/boot/dts/am335x-sancloud-bbe.dts
@@ -32,6 +32,8 @@ AM33XX_PADCONF(AM335X_PIN_GPMC_A10, PIN_INPUT, MUX_MODE7)     /* gpmc_a10.gpio1_
 
 &i2c0 {
 	lps331ap: barometer at 5c {
+		pinctrl-names = "default";
+		pinctrl-0 = <&lps3331ap_pins>;
 		compatible = "st,lps331ap-press";
 		st,drdy-int-pin = <1>;
 		reg = <0x5c>;
@@ -40,6 +42,8 @@ lps331ap: barometer at 5c {
 	};
 
 	mpu6050: accelerometer at 68 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&mpu6050_pins>;
 		compatible = "invensense,mpu6050";
 		reg = <0x68>;
 		interrupt-parent = <&gpio0>;
-- 
2.31.1



From paul.barker at sancloud.com  Fri Aug  6 01:59:07 2021
From: paul.barker at sancloud.com (Paul Barker)
Date: Fri,  6 Aug 2021 09:59:07 +0100
Subject: [PATCH 2/2] ARM: dts: am335x-sancloud-bbe: Drop usb wifi comment
In-Reply-To: <20210806085907.14615-1-paul.barker@sancloud.com>
References: <20210806085907.14615-1-paul.barker@sancloud.com>
Message-ID: <20210806085907.14615-2-paul.barker@sancloud.com>

The wifi chip on USB port 4 may not be present on all BBE variants.

Signed-off-by: Paul Barker <paul.barker at sancloud.com>
---
 arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi b/arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi
index 55952fe8687c..f9b7e774ac48 100644
--- a/arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi
+++ b/arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi
@@ -63,6 +63,5 @@ usb2512b: usb-hub at 2c {
 		compatible = "microchip,usb2512b";
 		reg = <0x2c>;
 		reset-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
-		/* wifi on port 4 */
 	};
 };
-- 
2.31.1



From will at kernel.org  Fri Aug  6 02:09:07 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 6 Aug 2021 10:09:07 +0100
Subject: [PATCH] arm64: entry: Add SYM_CODE annotation for __bad_stack
In-Reply-To: <20210804181710.19059-1-broonie@kernel.org>
References: <20210804181710.19059-1-broonie@kernel.org>
Message-ID: <20210806090907.GA2254@willie-the-truck>

On Wed, Aug 04, 2021 at 07:17:10PM +0100, Mark Brown wrote:
> When converting arm64 to modern assembler annotations __bad_stack was left
> as a raw local label without annotations. While this will have little if
> any practical impact at present it may cause issues in the future if we
> start using the annotations for things like reliable stack trace. Add
> SYM_CODE annotations to fix this.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/kernel/entry.S | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 923ee2ac85fd..572f72f20646 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -535,12 +535,13 @@ SYM_CODE_START(vectors)
>  SYM_CODE_END(vectors)
>  
>  #ifdef CONFIG_VMAP_STACK
> +SYM_CODE_START_LOCAL(__bad_stack)
>  	/*
>  	 * We detected an overflow in kernel_ventry, which switched to the
>  	 * overflow stack. Stash the exception regs, and head to our overflow
>  	 * handler.
>  	 */
> -__bad_stack:
> +
>  	/* Restore the original x0 value */
>  	mrs	x0, tpidrro_el0
>  
> @@ -560,6 +561,7 @@ __bad_stack:
>  	/* Time to die */
>  	bl	handle_bad_stack
>  	ASM_BUG()
> +SYM_CODE_END(__bad_stack)
>  #endif /* CONFIG_VMAP_STACK */

Acked-by: Will Deacon <will at kernel.org>

Will


From john.garry at huawei.com  Fri Aug  6 02:15:32 2021
From: john.garry at huawei.com (John Garry)
Date: Fri, 6 Aug 2021 10:15:32 +0100
Subject: [PATCH v3 23/25] iommu: Merge strictness and domain type configs
In-Reply-To: <18f2757675b1a4d74d052b2b211e512ebf6e465e.1628094601.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <18f2757675b1a4d74d052b2b211e512ebf6e465e.1628094601.git.robin.murphy@arm.com>
Message-ID: <3f383bf0-621a-9e3d-3c49-3e50c498b9f8@huawei.com>

On 04/08/2021 18:15, Robin Murphy wrote:
> To parallel the sysfs behaviour, merge the new build-time option
> for DMA domain strictness into the default domain type choice.
> 
> Suggested-by: Joerg Roedel<joro at 8bytes.org>
> Reviewed-by: Lu Baolu<baolu.lu at linux.intel.com>
> Reviewed-by: Jean-Philippe Brucker<jean-philippe at linaro.org>
> Signed-off-by: Robin Murphy<robin.murphy at arm.com>

Reviewed-by: John Garry <john.garry at huawei.com>


From heiko at sntech.de  Fri Aug  6 02:18:06 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 06 Aug 2021 11:18:06 +0200
Subject: [PATCH v3 2/7] soc: rockchip: io-domain: add rk3568 support
In-Reply-To: <8008800c-c518-30d4-edcf-57566e7a1251@arm.com>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
 <20210805120107.27007-3-michael.riesch@wolfvision.net>
 <8008800c-c518-30d4-edcf-57566e7a1251@arm.com>
Message-ID: <3206032.SvYEEZNnvj@diego>

Hi Robin,

Am Donnerstag, 5. August 2021, 18:27:36 CEST schrieb Robin Murphy:
> On 2021-08-05 13:01, Michael Riesch wrote:
> > From: Jianqun Xu <jay.xu at rock-chips.com>
> > 
> > The io-domain registers on RK3568 SoCs have three separated bits to
> > enable/disable the 1.8v/2.5v/3.3v power.
> > 
> > This patch make the write to be a operation, allow rk3568 uses a private
> > register set function.
> > 
> > Since the 2.5v is not used on RK3568, so the driver only set
> 
> FWIW, this seems at odds with what the first paragraph says - can anyone 
> clarify what exactly "not used" means here? Is it that the I/O domain 
> controller has been redesigned to support more than two logic levels on 
> the new generation of SoCs, but RK3568's I/O pads still only physically 
> support 1.8v and 3.3v; or is it that it *can* support 2.5v as well but 
> no currently-known RK3568-based designs use that?
> 
> In the former case it's just a wording issue in the commit message, but 
> in the latter it's arguably worth implementing support now for the sake 
> of future compatibility.

I hadn't looked that deeply into the rk356x io-domain config, but at least
on a register level in the TRM it seems there are separate bits for
"3.3V control", "2.5V control", "1.8V control" [0] for each io-domain.

Of course the documentation is otherwise somewhat sparse.

Maybe Jay or Kever [added] can explain a bit more about the 3 voltage
levels.


In general though, I tend to find the approach good enough for now.

Especially as the io-domain stuff is always said to "can cause damage
to the soc if used incorrectly" and it looks like nobody (including
Rockchip) seems to have actual hardware using these 2.5V levels right now.

So having code in there that no-one ever tested doesn't feel too good ;-)

Adding this later when needed should be somewhat easy, as it really only
needs adding of handling that 3rd control bit per domain.


Heiko



[0] what happens if none of the 3 is active? ;-)


> 
> Robin.
> 
> > 1.8v [enable] + 3.3v [disable] for 1.8v mode
> > 1.8v [disable] + 3.3v [enable] for 3.3v mode
> > 
> > There is not register order requirement which has been cleared by our IC
> > team.
> > 
> > Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
> > ---
> >   drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
> >   1 file changed, 80 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
> > index cf8182fc3642..13c446fd33a9 100644
> > --- a/drivers/soc/rockchip/io-domain.c
> > +++ b/drivers/soc/rockchip/io-domain.c
> > @@ -51,13 +51,11 @@
> >   #define RK3399_PMUGRF_CON0_VSEL		BIT(8)
> >   #define RK3399_PMUGRF_VSEL_SUPPLY_NUM	9
> >   
> > -struct rockchip_iodomain;
> > +#define RK3568_PMU_GRF_IO_VSEL0		(0x0140)
> > +#define RK3568_PMU_GRF_IO_VSEL1		(0x0144)
> > +#define RK3568_PMU_GRF_IO_VSEL2		(0x0148)
> >   
> > -struct rockchip_iodomain_soc_data {
> > -	int grf_offset;
> > -	const char *supply_names[MAX_SUPPLIES];
> > -	void (*init)(struct rockchip_iodomain *iod);
> > -};
> > +struct rockchip_iodomain;
> >   
> >   struct rockchip_iodomain_supply {
> >   	struct rockchip_iodomain *iod;
> > @@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
> >   	int idx;
> >   };
> >   
> > +struct rockchip_iodomain_soc_data {
> > +	int grf_offset;
> > +	const char *supply_names[MAX_SUPPLIES];
> > +	void (*init)(struct rockchip_iodomain *iod);
> > +	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
> > +};
> > +
> >   struct rockchip_iodomain {
> >   	struct device *dev;
> >   	struct regmap *grf;
> >   	const struct rockchip_iodomain_soc_data *soc_data;
> >   	struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
> > +	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
> >   };
> >   
> > +static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
> > +{
> > +	struct rockchip_iodomain *iod = supply->iod;
> > +	u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
> > +	u32 val0, val1;
> > +	int b;
> > +
> > +	switch (supply->idx) {
> > +	case 0: /* pmuio1 */
> > +		break;
> > +	case 1: /* pmuio2 */
> > +		b = supply->idx;
> > +		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
> > +		b = supply->idx + 4;
> > +		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
> > +
> > +		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
> > +		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
> > +		break;
> > +	case 3: /* vccio2 */
> > +		break;
> > +	case 2: /* vccio1 */
> > +	case 4: /* vccio3 */
> > +	case 5: /* vccio4 */
> > +	case 6: /* vccio5 */
> > +	case 7: /* vccio6 */
> > +	case 8: /* vccio7 */
> > +		b = supply->idx - 1;
> > +		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
> > +		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
> > +
> > +		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
> > +		regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	};
> > +
> > +	return 0;
> > +}
> > +
> >   static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
> >   				   int uV)
> >   {
> > @@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
> >   			return NOTIFY_BAD;
> >   	}
> >   
> > -	ret = rockchip_iodomain_write(supply, uV);
> > +	ret = supply->iod->write(supply, uV);
> >   	if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
> >   		return NOTIFY_BAD;
> >   
> > @@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
> >   	.init = rk3399_pmu_iodomain_init,
> >   };
> >   
> > +static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
> > +	.grf_offset = 0x140,
> > +	.supply_names = {
> > +		"pmuio1",
> > +		"pmuio2",
> > +		"vccio1",
> > +		"vccio2",
> > +		"vccio3",
> > +		"vccio4",
> > +		"vccio5",
> > +		"vccio6",
> > +		"vccio7",
> > +	},
> > +	.write = rk3568_iodomain_write,
> > +};
> > +
> >   static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
> >   	.grf_offset = 0x404,
> >   	.supply_names = {
> > @@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
> >   		.compatible = "rockchip,rk3399-pmu-io-voltage-domain",
> >   		.data = &soc_data_rk3399_pmu
> >   	},
> > +	{
> > +		.compatible = "rockchip,rk3568-pmu-io-voltage-domain",
> > +		.data = &soc_data_rk3568_pmu
> > +	},
> >   	{
> >   		.compatible = "rockchip,rv1108-io-voltage-domain",
> >   		.data = &soc_data_rv1108
> > @@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
> >   	match = of_match_node(rockchip_iodomain_match, np);
> >   	iod->soc_data = match->data;
> >   
> > +	if (iod->soc_data->write)
> > +		iod->write = iod->soc_data->write;
> > +	else
> > +		iod->write = rockchip_iodomain_write;
> > +
> >   	parent = pdev->dev.parent;
> >   	if (parent && parent->of_node) {
> >   		iod->grf = syscon_node_to_regmap(parent->of_node);
> > @@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
> >   		supply->reg = reg;
> >   		supply->nb.notifier_call = rockchip_iodomain_notify;
> >   
> > -		ret = rockchip_iodomain_write(supply, uV);
> > +		ret = iod->write(supply, uV);
> >   		if (ret) {
> >   			supply->reg = NULL;
> >   			goto unreg_notify;
> > 
> 






From lorenzo.pieralisi at arm.com  Fri Aug  6 02:39:54 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri,  6 Aug 2021 10:39:54 +0100
Subject: [PATCH v11 0/4] PCI: mediatek: Spilt PCIe node to comply with
 hardware design
In-Reply-To: <20210719073456.28666-1-chuanjia.liu@mediatek.com>
References: <20210719073456.28666-1-chuanjia.liu@mediatek.com>
Message-ID: <162824274659.11010.3812952145024175369.b4-ty@arm.com>

On Mon, 19 Jul 2021 15:34:52 +0800, Chuanjia Liu wrote:
> There are two independent PCIe controllers in MT2712 and MT7622 platform.
> Each of them should contain an independent MSI domain.
> 
> In old dts architecture, MSI domain will be inherited from the root bridge,
> and all of the devices will share the same MSI domain.Hence that,
> the PCIe devices will not work properly if the irq number
> which required is more than 32.
> 
> [...]

Applied patches 1-2 to pci/mediatek (we don't merge dts changes), thanks!

[1/2] dt-bindings: PCI: mediatek: Update the Device tree bindings
      https://git.kernel.org/lpieralisi/pci/c/9c23251640
[2/2] PCI: mediatek: Add new method to get shared pcie-cfg base address and parse node
      https://git.kernel.org/lpieralisi/pci/c/302e503e08

Thanks,
Lorenzo


From christianshewitt at gmail.com  Fri Aug  6 02:40:05 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Fri,  6 Aug 2021 09:40:05 +0000
Subject: [PATCH] drm/meson: fix colour distortion from HDR set during vendor
 u-boot
Message-ID: <20210806094005.7136-1-christianshewitt@gmail.com>

Add support for the OSD1 HDR registers so meson DRM can handle the HDR
properties set by Amlogic u-boot on G12A and newer devices which result
in blue/green/pink colour distortion to display output.

This takes the original patch submissions from Mathias [0] and [1] with
corrections for formatting and the missing description and attribution
needed for merge.

[0] https://lore.kernel.org/linux-amlogic/59dfd7e6-fc91-3d61-04c4-94e078a3188c at baylibre.com/T/
[1] https://lore.kernel.org/linux-amlogic/CAOKfEHBx_fboUqkENEMd-OC-NSrf46nto+vDLgvgttzPe99kXg at mail.gmail.com/T/#u

Fixes: 728883948b0d ("drm/meson: Add G12A Support for VIU setup")
Suggested-by: Mathias Steiger <mathias.steiger at googlemail.com>
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Neil Armstrong<narmstrong at baylibre.com>
Tested-by: Philip Milev <milev.philip at gmail.com>
---
 drivers/gpu/drm/meson/meson_registers.h | 5 +++++
 drivers/gpu/drm/meson/meson_viu.c       | 7 ++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index 446e7961da48..0f3cafab8860 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -634,6 +634,11 @@
 #define VPP_WRAP_OSD3_MATRIX_PRE_OFFSET2 0x3dbc
 #define VPP_WRAP_OSD3_MATRIX_EN_CTRL 0x3dbd
 
+/* osd1 HDR */
+#define OSD1_HDR2_CTRL 0x38a0
+#define OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN       BIT(13)
+#define OSD1_HDR2_CTRL_REG_ONLY_MAT            BIT(16)
+
 /* osd2 scaler */
 #define OSD2_VSC_PHASE_STEP 0x3d00
 #define OSD2_VSC_INI_PHASE 0x3d01
diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index aede0c67a57f..259f3e6bec90 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -425,9 +425,14 @@ void meson_viu_init(struct meson_drm *priv)
 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
 	    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
 		meson_viu_load_matrix(priv);
-	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
+	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
 		meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff,
 					       true);
+		/* fix green/pink color distortion from vendor u-boot */
+		writel_bits_relaxed(OSD1_HDR2_CTRL_REG_ONLY_MAT |
+				OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN, 0,
+				priv->io_base + _REG(OSD1_HDR2_CTRL));
+	}
 
 	/* Initialize OSD1 fifo control register */
 	reg = VIU_OSD_DDR_PRIORITY_URGENT |
-- 
2.17.1



From james.clark at arm.com  Fri Aug  6 02:43:25 2021
From: james.clark at arm.com (James Clark)
Date: Fri, 6 Aug 2021 10:43:25 +0100
Subject: [PATCH 6/6] perf cs-etm: Print the decoder name
In-Reply-To: <20210731073037.GF7437@leoy-ThinkPad-X240s>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-7-james.clark@arm.com>
 <20210731073037.GF7437@leoy-ThinkPad-X240s>
Message-ID: <077ebe58-f692-9adb-9cb5-ed35a9b508c1@arm.com>



On 31/07/2021 08:30, Leo Yan wrote:
>> @@ -658,7 +658,7 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
>>  
>>  		return 0;
>>  	} else if (d_params->operation == CS_ETM_OPERATION_PRINT) {
>> -		if (ocsd_dt_create_decoder(decoder->dcd_tree, decoder_name,
>> +		if (ocsd_dt_create_decoder(decoder->dcd_tree, decoder->decoder_name,
>>  					   OCSD_CREATE_FLG_PACKET_PROC,
>>  					   trace_config, &csid))
>>  			return -1;
>> @@ -790,3 +790,8 @@ void cs_etm_decoder__free(struct cs_etm_decoder *decoder)
>>  	decoder->dcd_tree = NULL;
>>  	free(decoder);
>>  }
>> +
>> +const char *cs_etm_decoder__get_name(struct cs_etm_decoder *decoder)
>> +{
>> +	return decoder->decoder_name;
>> +}
> Maybe can consider to place this function into the header file with
> "static inline" specifier.

I tried this, but because the struct is defined in the .c file it can't
be done without moving the struct to the header. It's also only used
for the --dump-raw-trace path so performance isn't critical anyway.

James

> 
> Either way, this patch looks good to me:
> 
> Reviewed-by: Leo Yan <leo.yan at linaro.org>
> 


From jay.xu at rock-chips.com  Fri Aug  6 02:46:05 2021
From: jay.xu at rock-chips.com (jay.xu at rock-chips.com)
Date: Fri, 6 Aug 2021 17:46:05 +0800
Subject: [PATCH v3 2/7] soc: rockchip: io-domain: add rk3568 support
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>, 
 <20210805120107.27007-3-michael.riesch@wolfvision.net>, 
 <8008800c-c518-30d4-edcf-57566e7a1251@arm.com>, 
 <3206032.SvYEEZNnvj@diego>
Message-ID: <2021080617460178513151@rock-chips.com>

Hi Heiko and Robin

--------------
jay.xu at rock-chips.com
>Hi Robin,
>
>Am Donnerstag, 5. August 2021, 18:27:36 CEST schrieb Robin Murphy:
>> On 2021-08-05 13:01, Michael Riesch wrote:
>> > From: Jianqun Xu <jay.xu at rock-chips.com>
>> >
>> > The io-domain registers on RK3568 SoCs have three separated bits to
>> > enable/disable the 1.8v/2.5v/3.3v power.
>> >
>> > This patch make the write to be a operation, allow rk3568 uses a private
>> > register set function.
>> >
>> > Since the 2.5v is not used on RK3568, so the driver only set
>>
>> FWIW, this seems at odds with what the first paragraph says - can anyone
>> clarify what exactly "not used" means here? Is it that the I/O domain
>> controller has been redesigned to support more than two logic levels on
>> the new generation of SoCs, but RK3568's I/O pads still only physically
>> support 1.8v and 3.3v; or is it that it *can* support 2.5v as well but
>> no currently-known RK3568-based designs use that?
>>
>> In the former case it's just a wording issue in the commit message, but
>> in the latter it's arguably worth implementing support now for the sake
>> of future compatibility.
>
>I hadn't looked that deeply into the rk356x io-domain config, but at least
>on a register level in the TRM it seems there are separate bits for
>"3.3V control", "2.5V control", "1.8V control" [0] for each io-domain.
>
>Of course the documentation is otherwise somewhat sparse.
>
>Maybe Jay or Kever [added] can explain a bit more about the 3 voltage
>levels.
>
>
>In general though, I tend to find the approach good enough for now.
>
>Especially as the io-domain stuff is always said to "can cause damage
>to the soc if used incorrectly" and it looks like nobody (including
>Rockchip) seems to have actual hardware using these 2.5V levels right now.
>
>So having code in there that no-one ever tested doesn't feel too good ;-)
> 
yes

about the 3bit

case ? ? V33 ?V25 ?V18 ? ? ? result
0 ? ? ? ? ?0 ? ? ?0 ? ? ? 0 ? ? ? ? ? IO safe, but cannot work
1 ? ? ? ? ?0 ? ? ?0 ? ? ? 1 ? ? ? ? ? IO require 1.8V, should < 1.98V, otherwise IO may damage
2 ? ? ? ? ?0 ? ? ?1 ? ? ? 0 ? ? ? ? ? IO require 2.5V, should < 2.75V, otherwise IO may damage
3 ? ? ? ? ?0 ? ? ?1 ? ? ? 1 ? ? ? ? ? Invalid state, should avoid
4 ? ? ? ? ?1 ? ? ?0 ? ? ? 0 ? ? ? ? ??IO require 3.3V, should < 3.63V, otherwise IO may damage
5 ? ? ? ? ?1 ? ? ?0 ? ? ? 1 ? ? ? ? ??IO require 1.8V, should < 1.98V, otherwise IO may damage
6 ? ? ? ? ?1 ? ? ?1 ? ? ? 0 ? ? ? ? ? IO require 2.5V, should < 2.75V, otherwise IO may damage
7 ? ? ? ? ?1 ? ? ?1 ? ? ? 1 ? ? ? ? ? Invalid state, should avoid

>Adding this later when needed should be somewhat easy, as it really only
>needs adding of handling that 3rd control bit per domain.
>
>
>Heiko
>
>
>
>[0] what happens if none of the 3 is active? ;-)
>
>
>>
>> Robin.
>>
>> > 1.8v [enable] + 3.3v [disable] for 1.8v mode
>> > 1.8v [disable] + 3.3v [enable] for 3.3v mode
>> >
>> > There is not register order requirement which has been cleared by our IC
>> > team.
>> >
>> > Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
>> > ---
>> >?? drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
>> >?? 1 file changed, 80 insertions(+), 8 deletions(-)
>> >
>> > diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
>> > index cf8182fc3642..13c446fd33a9 100644
>> > --- a/drivers/soc/rockchip/io-domain.c
>> > +++ b/drivers/soc/rockchip/io-domain.c
>> > @@ -51,13 +51,11 @@
>> >?? #define RK3399_PMUGRF_CON0_VSEL	BIT(8)
>> >?? #define RK3399_PMUGRF_VSEL_SUPPLY_NUM	9
>> >??
>> > -struct rockchip_iodomain;
>> > +#define RK3568_PMU_GRF_IO_VSEL0	(0x0140)
>> > +#define RK3568_PMU_GRF_IO_VSEL1	(0x0144)
>> > +#define RK3568_PMU_GRF_IO_VSEL2	(0x0148)
>> >??
>> > -struct rockchip_iodomain_soc_data {
>> > -	int grf_offset;
>> > -	const char *supply_names[MAX_SUPPLIES];
>> > -	void (*init)(struct rockchip_iodomain *iod);
>> > -};
>> > +struct rockchip_iodomain;
>> >??
>> >?? struct rockchip_iodomain_supply {
>> >?? struct rockchip_iodomain *iod;
>> > @@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
>> >?? int idx;
>> >?? };
>> >??
>> > +struct rockchip_iodomain_soc_data {
>> > +	int grf_offset;
>> > +	const char *supply_names[MAX_SUPPLIES];
>> > +	void (*init)(struct rockchip_iodomain *iod);
>> > +	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
>> > +};
>> > +
>> >?? struct rockchip_iodomain {
>> >?? struct device *dev;
>> >?? struct regmap *grf;
>> >?? const struct rockchip_iodomain_soc_data *soc_data;
>> >?? struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
>> > +	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
>> >?? };
>> >??
>> > +static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
>> > +{
>> > +	struct rockchip_iodomain *iod = supply->iod;
>> > +	u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
>> > +	u32 val0, val1;
>> > +	int b;
>> > +
>> > +	switch (supply->idx) {
>> > +	case 0: /* pmuio1 */
>> > +	break;
>> > +	case 1: /* pmuio2 */
>> > +	b = supply->idx;
>> > +	val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
>> > +	b = supply->idx + 4;
>> > +	val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
>> > +
>> > +	regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
>> > +	regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
>> > +	break;
>> > +	case 3: /* vccio2 */
>> > +	break;
>> > +	case 2: /* vccio1 */
>> > +	case 4: /* vccio3 */
>> > +	case 5: /* vccio4 */
>> > +	case 6: /* vccio5 */
>> > +	case 7: /* vccio6 */
>> > +	case 8: /* vccio7 */
>> > +	b = supply->idx - 1;
>> > +	val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
>> > +	val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
>> > +
>> > +	regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
>> > +	regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
>> > +	break;
>> > +	default:
>> > +	return -EINVAL;
>> > +	};
>> > +
>> > +	return 0;
>> > +}
>> > +
>> >?? static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
>> >?? ?? int uV)
>> >?? {
>> > @@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
>> >?? return NOTIFY_BAD;
>> >?? }
>> >??
>> > -	ret = rockchip_iodomain_write(supply, uV);
>> > +	ret = supply->iod->write(supply, uV);
>> >?? if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
>> >?? return NOTIFY_BAD;
>> >??
>> > @@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
>> >?? .init = rk3399_pmu_iodomain_init,
>> >?? };
>> >??
>> > +static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
>> > +	.grf_offset = 0x140,
>> > +	.supply_names = {
>> > +	"pmuio1",
>> > +	"pmuio2",
>> > +	"vccio1",
>> > +	"vccio2",
>> > +	"vccio3",
>> > +	"vccio4",
>> > +	"vccio5",
>> > +	"vccio6",
>> > +	"vccio7",
>> > +	},
>> > +	.write = rk3568_iodomain_write,
>> > +};
>> > +
>> >?? static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
>> >?? .grf_offset = 0x404,
>> >?? .supply_names = {
>> > @@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
>> >?? .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
>> >?? .data = &soc_data_rk3399_pmu
>> >?? },
>> > +	{
>> > +	.compatible = "rockchip,rk3568-pmu-io-voltage-domain",
>> > +	.data = &soc_data_rk3568_pmu
>> > +	},
>> >?? {
>> >?? .compatible = "rockchip,rv1108-io-voltage-domain",
>> >?? .data = &soc_data_rv1108
>> > @@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>> >?? match = of_match_node(rockchip_iodomain_match, np);
>> >?? iod->soc_data = match->data;
>> >??
>> > +	if (iod->soc_data->write)
>> > +	iod->write = iod->soc_data->write;
>> > +	else
>> > +	iod->write = rockchip_iodomain_write;
>> > +
>> >?? parent = pdev->dev.parent;
>> >?? if (parent && parent->of_node) {
>> >?? iod->grf = syscon_node_to_regmap(parent->of_node);
>> > @@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>> >?? supply->reg = reg;
>> >?? supply->nb.notifier_call = rockchip_iodomain_notify;
>> >??
>> > -	ret = rockchip_iodomain_write(supply, uV);
>> > +	ret = iod->write(supply, uV);
>> >?? if (ret) {
>> >?? supply->reg = NULL;
>> >?? goto unreg_notify;
>> >
>>
>
>
>
>
>
>
>

From michal.simek at xilinx.com  Fri Aug  6 03:05:02 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri,  6 Aug 2021 12:05:02 +0200
Subject: [PATCH] arm64: zynqmp: Enable gpio and qspi for zc1275-revA
Message-ID: <839d833133318feeb2755c4431204b0ef4788cce.1628244299.git.michal.simek@xilinx.com>

Add missing gpio and qspio for zc1275-revA board.

Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 .../boot/dts/xilinx/zynqmp-zc1275-revA.dts     | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
index 66a90483b004..e971ba8c1418 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZC1275
  *
- * (C) Copyright 2017 - 2019, Xilinx, Inc.
+ * (C) Copyright 2017 - 2021, Xilinx, Inc.
  *
  * Michal Simek <michal.simek at xilinx.com>
  * Siva Durga Prasad Paladugu <sivadur at xilinx.com>
@@ -20,6 +20,7 @@ / {
 	aliases {
 		serial0 = &uart0;
 		serial1 = &dcc;
+		spi0 = &qspi;
 	};
 
 	chosen {
@@ -37,6 +38,21 @@ &dcc {
 	status = "okay";
 };
 
+&gpio {
+	status = "okay";
+};
+
+&qspi {
+	status = "okay";
+	flash at 0 {
+		compatible = "m25p80", "jedec,spi-nor";
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <108000000>;
+	};
+};
+
 &uart0 {
 	status = "okay";
 };
-- 
2.32.0



From michal.simek at xilinx.com  Fri Aug  6 03:12:06 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri,  6 Aug 2021 12:12:06 +0200
Subject: [PATCH v3 0/2] arm64: zynqmp: Extend board description
Message-ID: <cover.1628244703.git.michal.simek@xilinx.com>

Hi,

over years couple of drivers were upstream and it is time to sync it up.
On the top of it also adding new Kria boards which are using new overlay
infrastructure which check if that overlays can be applied to base DT file.

These two patches weren't applied the part of v2 series.
https://lore.kernel.org/linux-devicetree/cover.1623684253.git.michal.simek at xilinx.com/

Thanks,
Michal

Changes in v3:
- usb node name fix, remove undocumented properties reported by Michael Tretter
- Also remove status property from dwc3_0/1 nodes reported by Michael
  Tretter
- Move USB3 PHY properties from DWC3 node to USB node - reported by Manish
  Narani
- Fix led node name
- Fix compatible string for xlnx,zynqmp-sk-kv260-revA/Y/Z
- Fix headers alignment
- Move USB3 PHY properties from DWC3 node to USB node - reported by Manish
  Narani
- Change dtb names generated with dtbo
- Fix emmc comment style
-

Changes in v2:
- New patch in the series
- Use sugar syntax - reported by Geert
- Update copyright years
- Fix SD3.0 comment alignment
- Remove one newline from Makefile

Michal Simek (2):
  arm64: zynqmp: Enable xlnx,zynqmp-dwc3 driver for xilinx boards
  arm64: zynqmp: Add support for Xilinx Kria SOM board

 .../devicetree/bindings/arm/xilinx.yaml       |  31 ++
 arch/arm64/boot/dts/xilinx/Makefile           |  13 +
 .../boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts  | 335 ++++++++++++++++++
 .../boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts  | 318 +++++++++++++++++
 .../boot/dts/xilinx/zynqmp-sm-k26-revA.dts    | 289 +++++++++++++++
 .../boot/dts/xilinx/zynqmp-smk-k26-revA.dts   |  21 ++
 .../dts/xilinx/zynqmp-zc1751-xm015-dc1.dts    |   8 +-
 .../dts/xilinx/zynqmp-zc1751-xm016-dc2.dts    |   7 +
 .../dts/xilinx/zynqmp-zc1751-xm017-dc3.dts    |  14 +
 .../boot/dts/xilinx/zynqmp-zcu100-revC.dts    |  14 +-
 .../boot/dts/xilinx/zynqmp-zcu102-revA.dts    |   8 +-
 .../boot/dts/xilinx/zynqmp-zcu104-revA.dts    |   8 +-
 .../boot/dts/xilinx/zynqmp-zcu104-revC.dts    |   8 +-
 .../boot/dts/xilinx/zynqmp-zcu106-revA.dts    |   8 +-
 .../boot/dts/xilinx/zynqmp-zcu111-revA.dts    |   8 +-
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  60 +++-
 16 files changed, 1129 insertions(+), 21 deletions(-)
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts

-- 
2.32.0



From michal.simek at xilinx.com  Fri Aug  6 03:12:07 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri,  6 Aug 2021 12:12:07 +0200
Subject: [PATCH v3 1/2] arm64: zynqmp: Enable xlnx,
 zynqmp-dwc3 driver for xilinx boards
In-Reply-To: <cover.1628244703.git.michal.simek@xilinx.com>
References: <cover.1628244703.git.michal.simek@xilinx.com>
Message-ID: <640a3bc0dc3e32560d3e84c2f78b5ae561396eb0.1628244703.git.michal.simek@xilinx.com>

The commit 84770f028fab ("usb: dwc3: Add driver for Xilinx platforms")
finally add proper support for Xilinx dwc3 driver. This patch is adding DT
description for it.

Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

Changes in v3:
- usb node name fix, remove undocumented properties reported by Michael Tretter
- Also remove status property from dwc3_0/1 nodes reported by Michael
  Tretter
- Move USB3 PHY properties from DWC3 node to USB node - reported by Manish
  Narani

Changes in v2:
- New patch in the series

 .../dts/xilinx/zynqmp-zc1751-xm015-dc1.dts    |  8 ++-
 .../dts/xilinx/zynqmp-zc1751-xm016-dc2.dts    |  7 +++
 .../dts/xilinx/zynqmp-zc1751-xm017-dc3.dts    | 14 +++++
 .../boot/dts/xilinx/zynqmp-zcu100-revC.dts    | 14 ++++-
 .../boot/dts/xilinx/zynqmp-zcu102-revA.dts    |  8 ++-
 .../boot/dts/xilinx/zynqmp-zcu104-revA.dts    |  8 ++-
 .../boot/dts/xilinx/zynqmp-zcu104-revC.dts    |  8 ++-
 .../boot/dts/xilinx/zynqmp-zcu106-revA.dts    |  8 ++-
 .../boot/dts/xilinx/zynqmp-zcu111-revA.dts    |  8 ++-
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 60 +++++++++++++++----
 10 files changed, 122 insertions(+), 21 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
index d93fe2efa39d..b05be2552826 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
@@ -27,6 +27,7 @@ aliases {
 		rtc0 = &rtc;
 		serial0 = &uart0;
 		spi0 = &qspi;
+		usb0 = &usb0;
 	};
 
 	chosen {
@@ -404,9 +405,14 @@ &usb0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb0_default>;
-	dr_mode = "host";
 	phy-names = "usb3-phy";
 	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+	snps,usb3_lpm_capable;
 	maximum-speed = "super-speed";
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
index cd61550c52e5..938b76bd0527 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
@@ -26,6 +26,7 @@ aliases {
 		serial1 = &uart1;
 		spi0 = &spi0;
 		spi1 = &spi1;
+		usb0 = &usb1;
 	};
 
 	chosen {
@@ -479,7 +480,13 @@ &usb1 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb1_default>;
+};
+
+&dwc3_1 {
+	status = "okay";
 	dr_mode = "host";
+	snps,usb3_lpm_capable;
+	maximum-speed = "super-speed";
 };
 
 &uart0 {
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
index ba7f1f21c579..4394ec3b6a23 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
@@ -24,6 +24,8 @@ aliases {
 		rtc0 = &rtc;
 		serial0 = &uart0;
 		serial1 = &uart1;
+		usb0 = &usb0;
+		usb1 = &usb1;
 	};
 
 	chosen {
@@ -147,11 +149,23 @@ &uart1 {
 
 &usb0 {
 	status = "okay";
+};
+
+&dwc3_0 {
+	status = "okay";
 	dr_mode = "host";
+	snps,usb3_lpm_capable;
+	maximum-speed = "super-speed";
 };
 
 /* ULPI SMSC USB3320 */
 &usb1 {
 	status = "okay";
+};
+
+&dwc3_1 {
+	status = "okay";
 	dr_mode = "host";
+	snps,usb3_lpm_capable;
+	maximum-speed = "super-speed";
 };
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
index 80415e202814..f6aad4159ccd 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
@@ -30,6 +30,8 @@ aliases {
 		serial2 = &dcc;
 		spi0 = &spi0;
 		spi1 = &spi1;
+		usb0 = &usb0;
+		usb1 = &usb1;
 		mmc0 = &sdhci0;
 		mmc1 = &sdhci1;
 	};
@@ -537,9 +539,13 @@ &usb0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb0_default>;
-	dr_mode = "peripheral";
 	phy-names = "usb3-phy";
 	phys = <&psgtr 2 PHY_TYPE_USB3 0 0>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "peripheral";
 	maximum-speed = "super-speed";
 };
 
@@ -548,9 +554,13 @@ &usb1 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb1_default>;
-	dr_mode = "host";
 	phy-names = "usb3-phy";
 	phys = <&psgtr 3 PHY_TYPE_USB3 1 0>;
+};
+
+&dwc3_1 {
+	status = "okay";
+	dr_mode = "host";
 	maximum-speed = "super-speed";
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
index 3d8d14ef1ede..7b9a88b125d1 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
@@ -31,6 +31,7 @@ aliases {
 		serial1 = &uart1;
 		serial2 = &dcc;
 		spi0 = &qspi;
+		usb0 = &usb0;
 	};
 
 	chosen {
@@ -997,9 +998,14 @@ &usb0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb0_default>;
-	dr_mode = "host";
 	phy-names = "usb3-phy";
 	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+	snps,usb3_lpm_capable;
 	maximum-speed = "super-speed";
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
index 86fff3632c7d..bd8f20f3223d 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
@@ -29,6 +29,7 @@ aliases {
 		serial1 = &uart1;
 		serial2 = &dcc;
 		spi0 = &qspi;
+		usb0 = &usb0;
 	};
 
 	chosen {
@@ -481,9 +482,14 @@ &usb0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb0_default>;
-	dr_mode = "host";
 	phy-names = "usb3-phy";
 	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+	snps,usb3_lpm_capable;
 	maximum-speed = "super-speed";
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
index 2a872d439804..96feaad30166 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
@@ -29,6 +29,7 @@ aliases {
 		serial1 = &uart1;
 		serial2 = &dcc;
 		spi0 = &qspi;
+		usb0 = &usb0;
 	};
 
 	chosen {
@@ -493,9 +494,14 @@ &usb0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb0_default>;
-	dr_mode = "host";
 	phy-names = "usb3-phy";
 	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+	snps,usb3_lpm_capable;
 	maximum-speed = "super-speed";
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
index 057c04352591..20b7c75bb1d3 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
@@ -31,6 +31,7 @@ aliases {
 		serial1 = &uart1;
 		serial2 = &dcc;
 		spi0 = &qspi;
+		usb0 = &usb0;
 	};
 
 	chosen {
@@ -990,9 +991,14 @@ &usb0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb0_default>;
-	dr_mode = "host";
 	phy-names = "usb3-phy";
 	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+	snps,usb3_lpm_capable;
 	maximum-speed = "super-speed";
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
index e1fff62a4cd5..e36df6adbeee 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
@@ -30,6 +30,7 @@ aliases {
 		serial0 = &uart0;
 		serial1 = &dcc;
 		spi0 = &qspi;
+		usb0 = &usb0;
 	};
 
 	chosen {
@@ -827,9 +828,14 @@ &usb0 {
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usb0_default>;
-	dr_mode = "host";
 	phy-names = "usb3-phy";
 	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+	snps,usb3_lpm_capable;
 	maximum-speed = "super-speed";
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index b5fde9dddca5..74e66443e4ce 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP
  *
- * (C) Copyright 2014 - 2019, Xilinx, Inc.
+ * (C) Copyright 2014 - 2021, Xilinx, Inc.
  *
  * Michal Simek <michal.simek at xilinx.com>
  *
@@ -805,24 +805,58 @@ uart1: serial at ff010000 {
 			power-domains = <&zynqmp_firmware PD_UART_1>;
 		};
 
-		usb0: usb at fe200000 {
-			compatible = "snps,dwc3";
+		usb0: usb at ff9d0000 {
+			#address-cells = <2>;
+			#size-cells = <2>;
 			status = "disabled";
-			interrupt-parent = <&gic>;
-			interrupts = <0 65 4>;
-			reg = <0x0 0xfe200000 0x0 0x40000>;
-			clock-names = "clk_xin", "clk_ahb";
+			compatible = "xlnx,zynqmp-dwc3";
+			reg = <0x0 0xff9d0000 0x0 0x100>;
+			clock-names = "bus_clk", "ref_clk";
 			power-domains = <&zynqmp_firmware PD_USB_0>;
+			resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>,
+				 <&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>,
+				 <&zynqmp_reset ZYNQMP_RESET_USB0_APB>;
+			reset-names = "usb_crst", "usb_hibrst", "usb_apbrst";
+			ranges;
+
+			dwc3_0: usb at fe200000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0xfe200000 0x0 0x40000>;
+				interrupt-parent = <&gic>;
+				interrupt-names = "dwc_usb3", "otg";
+				interrupts = <0 65 4>, <0 69 4>;
+				#stream-id-cells = <1>;
+				iommus = <&smmu 0x860>;
+				snps,quirk-frame-length-adjustment = <0x20>;
+				/* dma-coherent; */
+			};
 		};
 
-		usb1: usb at fe300000 {
-			compatible = "snps,dwc3";
+		usb1: usb at ff9e0000 {
+			#address-cells = <2>;
+			#size-cells = <2>;
 			status = "disabled";
-			interrupt-parent = <&gic>;
-			interrupts = <0 70 4>;
-			reg = <0x0 0xfe300000 0x0 0x40000>;
-			clock-names = "clk_xin", "clk_ahb";
+			compatible = "xlnx,zynqmp-dwc3";
+			reg = <0x0 0xff9e0000 0x0 0x100>;
+			clock-names = "bus_clk", "ref_clk";
 			power-domains = <&zynqmp_firmware PD_USB_1>;
+			resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>,
+				 <&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>,
+				 <&zynqmp_reset ZYNQMP_RESET_USB1_APB>;
+			reset-names = "usb_crst", "usb_hibrst", "usb_apbrst";
+			ranges;
+
+			dwc3_1: usb at fe300000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0xfe300000 0x0 0x40000>;
+				interrupt-parent = <&gic>;
+				interrupt-names = "dwc_usb3", "otg";
+				interrupts = <0 70 4>, <0 74 4>;
+				#stream-id-cells = <1>;
+				iommus = <&smmu 0x861>;
+				snps,quirk-frame-length-adjustment = <0x20>;
+				/* dma-coherent; */
+			};
 		};
 
 		watchdog0: watchdog at fd4d0000 {
-- 
2.32.0



From michal.simek at xilinx.com  Fri Aug  6 03:12:08 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri,  6 Aug 2021 12:12:08 +0200
Subject: [PATCH v3 2/2] arm64: zynqmp: Add support for Xilinx Kria SOM board
In-Reply-To: <cover.1628244703.git.michal.simek@xilinx.com>
References: <cover.1628244703.git.michal.simek@xilinx.com>
Message-ID: <e780a2fef00e78c44c21cf3b918631bf20262688.1628244703.git.michal.simek@xilinx.com>

There are couple of revisions of SOMs (k26) and associated carrier cards
(kv260).
SOM itself has two major versions:
sm-k26 - SOM with EMMC
smk-k26 - SOM without EMMC used on starter kit with preprogrammed firmware
in QSPI.

SOMs are describing only devices available on the SOM or connections which
are described in specification (for example UART, fwuen).

Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

Changes in v3:
- Fix led node name
- Fix compatible string for xlnx,zynqmp-sk-kv260-revA/Y/Z
- Fix headers alignment
- Move USB3 PHY properties from DWC3 node to USB node - reported by Manish
  Narani
- Change dtb names generated with dtbo
- Fix emmc comment style
-

Changes in v2:
- Use sugar syntax - reported by Geert
- Update copyright years
- Fix SD3.0 comment alignment
- Remove one newline from Makefile

https://www.xilinx.com/products/som/kria.html
---
 .../devicetree/bindings/arm/xilinx.yaml       |  31 ++
 arch/arm64/boot/dts/xilinx/Makefile           |  13 +
 .../boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts  | 335 ++++++++++++++++++
 .../boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts  | 318 +++++++++++++++++
 .../boot/dts/xilinx/zynqmp-sm-k26-revA.dts    | 289 +++++++++++++++
 .../boot/dts/xilinx/zynqmp-smk-k26-revA.dts   |  21 ++
 6 files changed, 1007 insertions(+)
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts

diff --git a/Documentation/devicetree/bindings/arm/xilinx.yaml b/Documentation/devicetree/bindings/arm/xilinx.yaml
index a0b1ae6e3e71..31b86a6363b8 100644
--- a/Documentation/devicetree/bindings/arm/xilinx.yaml
+++ b/Documentation/devicetree/bindings/arm/xilinx.yaml
@@ -116,6 +116,37 @@ properties:
           - const: xlnx,zynqmp-zcu111
           - const: xlnx,zynqmp
 
+      - description: Xilinx Kria SOMs
+        items:
+          - const: xlnx,zynqmp-sm-k26-rev1
+          - const: xlnx,zynqmp-sm-k26-revB
+          - const: xlnx,zynqmp-sm-k26-revA
+          - const: xlnx,zynqmp-sm-k26
+          - const: xlnx,zynqmp
+
+      - description: Xilinx Kria SOMs (starter)
+        items:
+          - const: xlnx,zynqmp-smk-k26-rev1
+          - const: xlnx,zynqmp-smk-k26-revB
+          - const: xlnx,zynqmp-smk-k26-revA
+          - const: xlnx,zynqmp-smk-k26
+          - const: xlnx,zynqmp
+
+      - description: Xilinx Kria Carrier Cards (revA/Y/Z)
+        items:
+          - const: xlnx,zynqmp-sk-kv260-revA
+          - const: xlnx,zynqmp-sk-kv260-revY
+          - const: xlnx,zynqmp-sk-kv260-revZ
+          - const: xlnx,zynqmp-sk-k260
+          - const: xlnx,zynqmp
+
+      - description: Xilinx Kria Carrier Cards (rev1/B)
+        items:
+          - const: xlnx,zynqmp-sk-kv260-rev1
+          - const: xlnx,zynqmp-sk-kv260-revB
+          - const: xlnx,zynqmp-sk-k260
+          - const: xlnx,zynqmp
+
 additionalProperties: true
 
 ...
diff --git a/arch/arm64/boot/dts/xilinx/Makefile b/arch/arm64/boot/dts/xilinx/Makefile
index 083ed52337fd..4e159540d031 100644
--- a/arch/arm64/boot/dts/xilinx/Makefile
+++ b/arch/arm64/boot/dts/xilinx/Makefile
@@ -17,3 +17,16 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu104-revA.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu104-revC.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu106-revA.dtb
 dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu111-revA.dtb
+
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA.dtb
+
+sm-k26-revA-sck-kv-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo
+sm-k26-revA-sck-kv-g-revB-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo
+smk-k26-revA-sm-k26-revA-sck-kv-g-revA-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo
+smk-k26-revA-sm-k26-revA-sck-kv-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo
+
+dtb-$(CONFIG_ARCH_ZYNQMP) += sm-k26-revA-sck-kv-g-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += sm-k26-revA-sck-kv-g-revB.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += smk-k26-revA-sm-k26-revA-sck-kv-g-revA.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP) += smk-k26-revA-sm-k26-revA-sck-kv-g-revB.dtb
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
new file mode 100644
index 000000000000..22602d8c33f8
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for KV260 revA Carrier Card
+ *
+ * (C) Copyright 2020 - 2021, Xilinx, Inc.
+ *
+ * SD level shifter:
+ * "A" ? A01 board un-modified (NXP)
+ * "Y" ? A01 board modified with legacy interposer (Nexperia)
+ * "Z" ? A01 board modified with Diode interposer
+ *
+ * Michal Simek <michal.simek at xilinx.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "xlnx,zynqmp-sk-kv260-revA",
+		     "xlnx,zynqmp-sk-kv260-revY",
+		     "xlnx,zynqmp-sk-kv260-revZ",
+		     "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp";
+};
+
+&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c1_default>;
+	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
+	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+
+	u14: ina260 at 40 { /* u14 */
+		compatible = "ti,ina260";
+		#io-channel-cells = <1>;
+		label = "ina260-u14";
+		reg = <0x40>;
+	};
+	/* u27 - 0xe0 - STDP4320 DP/HDMI splitter */
+};
+
+&amba {
+	ina260-u14 {
+		compatible = "iio-hwmon";
+		io-channels = <&u14 0>, <&u14 1>, <&u14 2>;
+	};
+
+	si5332_0: si5332_0 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+	};
+
+	si5332_1: si5332_1 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+
+	si5332_2: si5332_2 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
+	};
+
+	si5332_3: si5332_3 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+
+	si5332_4: si5332_4 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+	};
+
+	si5332_5: si5332_5 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <27000000>;
+	};
+};
+
+/* DP/USB 3.0 and SATA */
+&psgtr {
+	status = "okay";
+	/* pcie, usb3, sata */
+	clocks = <&si5332_5>, <&si5332_4>, <&si5332_0>;
+	clock-names = "ref0", "ref1", "ref2";
+};
+
+&sata {
+	status = "okay";
+	/* SATA OOB timing settings */
+	ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
+	ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
+	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
+	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	phy-names = "sata-phy";
+	phys = <&psgtr 3 PHY_TYPE_SATA 1 2>;
+};
+
+&zynqmp_dpsub {
+	status = "disabled";
+	phy-names = "dp-phy0", "dp-phy1";
+	phys = <&psgtr 1 PHY_TYPE_DP 0 0>, <&psgtr 0 PHY_TYPE_DP 1 0>;
+};
+
+&zynqmp_dpdma {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb0_default>;
+	phy-names = "usb3-phy";
+	phys = <&psgtr 2 PHY_TYPE_USB3 0 1>;
+	usbhub: usb5744 { /* u43 */
+		compatible = "microchip,usb5744";
+		reset-gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+	snps,usb3_lpm_capable;
+	maximum-speed = "super-speed";
+};
+
+&sdhci1 { /* on CC with tuned parameters */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdhci1_default>;
+	/*
+	 * SD 3.0 requires level shifter and this property
+	 * should be removed if the board has level shifter and
+	 * need to work in UHS mode
+	 */
+	no-1-8-v;
+	disable-wp;
+	xlnx,mio-bank = <1>;
+};
+
+&gem3 { /* required by spec */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gem3_default>;
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+
+	mdio: mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reset-gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+		reset-delay-us = <2>;
+
+		phy0: ethernet-phy at 1 {
+			#phy-cells = <1>;
+			reg = <1>;
+			ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+			ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
+			ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+			ti,dp83867-rxctrl-strap-quirk;
+		};
+	};
+};
+
+&pinctrl0 { /* required by spec */
+	status = "okay";
+
+	pinctrl_uart1_default: uart1-default {
+		conf {
+			groups = "uart1_9_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+			drive-strength = <12>;
+		};
+
+		conf-rx {
+			pins = "MIO37";
+			bias-high-impedance;
+		};
+
+		conf-tx {
+			pins = "MIO36";
+			bias-disable;
+		};
+
+		mux {
+			groups = "uart1_9_grp";
+			function = "uart1";
+		};
+	};
+
+	pinctrl_i2c1_default: i2c1-default {
+		conf {
+			groups = "i2c1_6_grp";
+			bias-pull-up;
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		mux {
+			groups = "i2c1_6_grp";
+			function = "i2c1";
+		};
+	};
+
+	pinctrl_i2c1_gpio: i2c1-gpio {
+		conf {
+			groups = "gpio0_24_grp", "gpio0_25_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		mux {
+			groups = "gpio0_24_grp", "gpio0_25_grp";
+			function = "gpio0";
+		};
+	};
+
+	pinctrl_gem3_default: gem3-default {
+		conf {
+			groups = "ethernet3_0_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		conf-rx {
+			pins = "MIO70", "MIO72", "MIO74";
+			bias-high-impedance;
+			low-power-disable;
+		};
+
+		conf-bootstrap {
+			pins = "MIO71", "MIO73", "MIO75";
+			bias-disable;
+			low-power-disable;
+		};
+
+		conf-tx {
+			pins = "MIO64", "MIO65", "MIO66",
+				"MIO67", "MIO68", "MIO69";
+			bias-disable;
+			low-power-enable;
+		};
+
+		conf-mdio {
+			groups = "mdio3_0_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+			bias-disable;
+		};
+
+		mux-mdio {
+			function = "mdio3";
+			groups = "mdio3_0_grp";
+		};
+
+		mux {
+			function = "ethernet3";
+			groups = "ethernet3_0_grp";
+		};
+	};
+
+	pinctrl_usb0_default: usb0-default {
+		conf {
+			groups = "usb0_0_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		conf-rx {
+			pins = "MIO52", "MIO53", "MIO55";
+			bias-high-impedance;
+		};
+
+		conf-tx {
+			pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59",
+			"MIO60", "MIO61", "MIO62", "MIO63";
+			bias-disable;
+		};
+
+		mux {
+			groups = "usb0_0_grp";
+			function = "usb0";
+		};
+	};
+
+	pinctrl_sdhci1_default: sdhci1-default {
+		conf {
+			groups = "sdio1_0_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+			bias-disable;
+		};
+
+		conf-cd {
+			groups = "sdio1_cd_0_grp";
+			bias-high-impedance;
+			bias-pull-up;
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		mux-cd {
+			groups = "sdio1_cd_0_grp";
+			function = "sdio1_cd";
+		};
+
+		mux {
+			groups = "sdio1_0_grp";
+			function = "sdio1";
+		};
+	};
+};
+
+&uart1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1_default>;
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
new file mode 100644
index 000000000000..df054e152a77
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
@@ -0,0 +1,318 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for KV260 revA Carrier Card
+ *
+ * (C) Copyright 2020 - 2021, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek at xilinx.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "xlnx,zynqmp-sk-kv260-rev1",
+		     "xlnx,zynqmp-sk-kv260-revB",
+		     "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp";
+};
+
+&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c1_default>;
+	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
+	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+
+	u14: ina260 at 40 { /* u14 */
+		compatible = "ti,ina260";
+		#io-channel-cells = <1>;
+		label = "ina260-u14";
+		reg = <0x40>;
+	};
+	usbhub: usb5744 at 2d { /* u43 */
+		compatible = "microchip,usb5744";
+		reg = <0x2d>;
+		reset-gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
+	};
+	/* u27 - 0xe0 - STDP4320 DP/HDMI splitter */
+};
+
+&amba {
+	ina260-u14 {
+		compatible = "iio-hwmon";
+		io-channels = <&u14 0>, <&u14 1>, <&u14 2>;
+	};
+
+	si5332_0: si5332_0 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+	};
+
+	si5332_1: si5332_1 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <25000000>;
+	};
+
+	si5332_2: si5332_2 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
+	};
+
+	si5332_3: si5332_3 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+	};
+
+	si5332_4: si5332_4 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+	};
+
+	si5332_5: si5332_5 { /* u17 */
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <27000000>;
+	};
+};
+
+/* DP/USB 3.0 */
+&psgtr {
+	status = "okay";
+	/* pcie, usb3, sata */
+	clocks = <&si5332_5>, <&si5332_4>, <&si5332_0>;
+	clock-names = "ref0", "ref1", "ref2";
+};
+
+&zynqmp_dpsub {
+	status = "disabled";
+	phy-names = "dp-phy0", "dp-phy1";
+	phys = <&psgtr 1 PHY_TYPE_DP 0 0>, <&psgtr 0 PHY_TYPE_DP 1 0>;
+};
+
+&zynqmp_dpdma {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb0_default>;
+	phy-names = "usb3-phy";
+	phys = <&psgtr 2 PHY_TYPE_USB3 0 1>;
+};
+
+&dwc3_0 {
+	status = "okay";
+	dr_mode = "host";
+	snps,usb3_lpm_capable;
+	maximum-speed = "super-speed";
+};
+
+&sdhci1 { /* on CC with tuned parameters */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdhci1_default>;
+	/*
+	 * SD 3.0 requires level shifter and this property
+	 * should be removed if the board has level shifter and
+	 * need to work in UHS mode
+	 */
+	no-1-8-v;
+	disable-wp;
+	xlnx,mio-bank = <1>;
+	clk-phase-sd-hs = <126>, <60>;
+	clk-phase-uhs-sdr25 = <120>, <60>;
+	clk-phase-uhs-ddr50 = <126>, <48>;
+};
+
+&gem3 { /* required by spec */
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gem3_default>;
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii-id";
+
+	mdio: mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reset-gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+		reset-delay-us = <2>;
+
+		phy0: ethernet-phy at 1 {
+			#phy-cells = <1>;
+			reg = <1>;
+			ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+			ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
+			ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+			ti,dp83867-rxctrl-strap-quirk;
+		};
+	};
+};
+
+&pinctrl0 { /* required by spec */
+	status = "okay";
+
+	pinctrl_uart1_default: uart1-default {
+		conf {
+			groups = "uart1_9_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+			drive-strength = <12>;
+		};
+
+		conf-rx {
+			pins = "MIO37";
+			bias-high-impedance;
+		};
+
+		conf-tx {
+			pins = "MIO36";
+			bias-disable;
+		};
+
+		mux {
+			groups = "uart1_9_grp";
+			function = "uart1";
+		};
+	};
+
+	pinctrl_i2c1_default: i2c1-default {
+		conf {
+			groups = "i2c1_6_grp";
+			bias-pull-up;
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		mux {
+			groups = "i2c1_6_grp";
+			function = "i2c1";
+		};
+	};
+
+	pinctrl_i2c1_gpio: i2c1-gpio {
+		conf {
+			groups = "gpio0_24_grp", "gpio0_25_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		mux {
+			groups = "gpio0_24_grp", "gpio0_25_grp";
+			function = "gpio0";
+		};
+	};
+
+	pinctrl_gem3_default: gem3-default {
+		conf {
+			groups = "ethernet3_0_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		conf-rx {
+			pins = "MIO70", "MIO72", "MIO74";
+			bias-high-impedance;
+			low-power-disable;
+		};
+
+		conf-bootstrap {
+			pins = "MIO71", "MIO73", "MIO75";
+			bias-disable;
+			low-power-disable;
+		};
+
+		conf-tx {
+			pins = "MIO64", "MIO65", "MIO66",
+				"MIO67", "MIO68", "MIO69";
+			bias-disable;
+			low-power-enable;
+		};
+
+		conf-mdio {
+			groups = "mdio3_0_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+			bias-disable;
+		};
+
+		mux-mdio {
+			function = "mdio3";
+			groups = "mdio3_0_grp";
+		};
+
+		mux {
+			function = "ethernet3";
+			groups = "ethernet3_0_grp";
+		};
+	};
+
+	pinctrl_usb0_default: usb0-default {
+		conf {
+			groups = "usb0_0_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		conf-rx {
+			pins = "MIO52", "MIO53", "MIO55";
+			bias-high-impedance;
+		};
+
+		conf-tx {
+			pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59",
+			"MIO60", "MIO61", "MIO62", "MIO63";
+			bias-disable;
+		};
+
+		mux {
+			groups = "usb0_0_grp";
+			function = "usb0";
+		};
+	};
+
+	pinctrl_sdhci1_default: sdhci1-default {
+		conf {
+			groups = "sdio1_0_grp";
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+			bias-disable;
+		};
+
+		conf-cd {
+			groups = "sdio1_cd_0_grp";
+			bias-high-impedance;
+			bias-pull-up;
+			slew-rate = <SLEW_RATE_SLOW>;
+			power-source = <IO_STANDARD_LVCMOS18>;
+		};
+
+		mux-cd {
+			groups = "sdio1_cd_0_grp";
+			function = "sdio1_cd";
+		};
+
+		mux {
+			groups = "sdio1_0_grp";
+			function = "sdio1";
+		};
+	};
+};
+
+&uart1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1_default>;
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
new file mode 100644
index 000000000000..550b389153e6
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Xilinx ZynqMP SM-K26 rev1/B/A
+ *
+ * (C) Copyright 2020 - 2021, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek at xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+
+/ {
+	model = "ZynqMP SM-K26 Rev1/B/A";
+	compatible = "xlnx,zynqmp-sm-k26-rev1", "xlnx,zynqmp-sm-k26-revB",
+		     "xlnx,zynqmp-sm-k26-revA", "xlnx,zynqmp-sm-k26",
+		     "xlnx,zynqmp";
+
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		mmc0 = &sdhci0;
+		mmc1 = &sdhci1;
+		nvmem0 = &eeprom;
+		nvmem1 = &eeprom_cc;
+		rtc0 = &rtc;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &dcc;
+		spi0 = &qspi;
+		spi1 = &spi0;
+		spi2 = &spi1;
+		usb0 = &usb0;
+		usb1 = &usb1;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial1:115200n8";
+	};
+
+	memory at 0 {
+		device_type = "memory"; /* 4GB */
+		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+		fwuen {
+			label = "fwuen";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		ds35-led {
+			label = "heartbeat";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		ds36-led {
+			label = "vbus_det";
+			gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+};
+
+&uart1 { /* MIO36/MIO37 */
+	status = "okay";
+};
+
+&qspi { /* MIO 0-5 - U143 */
+	status = "okay";
+	flash at 0 { /* MT25QU512A */
+		compatible = "mt25qu512a", "jedec,spi-nor"; /* 64MB */
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <40000000>; /* 40MHz */
+		partition at 0 {
+			label = "Image Selector";
+			reg = <0x0 0x80000>; /* 512KB */
+			read-only;
+			lock;
+		};
+		partition at 80000 {
+			label = "Image Selector Golden";
+			reg = <0x80000 0x80000>; /* 512KB */
+			read-only;
+			lock;
+		};
+		partition at 100000 {
+			label = "Persistent Register";
+			reg = <0x100000 0x20000>; /* 128KB */
+		};
+		partition at 120000 {
+			label = "Persistent Register Backup";
+			reg = <0x120000 0x20000>; /* 128KB */
+		};
+		partition at 140000 {
+			label = "Open_1";
+			reg = <0x140000 0xC0000>; /* 768KB */
+		};
+		partition at 200000 {
+			label = "Image A (FSBL, PMU, ATF, U-Boot)";
+			reg = <0x200000 0xD00000>; /* 13MB */
+		};
+		partition at f00000 {
+			label = "ImgSel Image A Catch";
+			reg = <0xF00000 0x80000>; /* 512KB */
+			read-only;
+			lock;
+		};
+		partition at f80000 {
+			label = "Image B (FSBL, PMU, ATF, U-Boot)";
+			reg = <0xF80000 0xD00000>; /* 13MB */
+		};
+		partition at 1c80000 {
+			label = "ImgSel Image B Catch";
+			reg = <0x1C80000 0x80000>; /* 512KB */
+			read-only;
+			lock;
+		};
+		partition at 1d00000 {
+			label = "Open_2";
+			reg = <0x1D00000 0x100000>; /* 1MB */
+		};
+		partition at 1e00000 {
+			label = "Recovery Image";
+			reg = <0x1E00000 0x200000>; /* 2MB */
+			read-only;
+			lock;
+		};
+		partition at 2000000 {
+			label = "Recovery Image Backup";
+			reg = <0x2000000 0x200000>; /* 2MB */
+			read-only;
+			lock;
+		};
+		partition at 2200000 {
+			label = "U-Boot storage variables";
+			reg = <0x2200000 0x20000>; /* 128KB */
+		};
+		partition at 2220000 {
+			label = "U-Boot storage variables backup";
+			reg = <0x2220000 0x20000>; /* 128KB */
+		};
+		partition at 2240000 {
+			label = "SHA256";
+			reg = <0x2240000 0x10000>; /* 256B but 64KB sector */
+			read-only;
+			lock;
+		};
+		partition at 2250000 {
+			label = "User";
+			reg = <0x2250000 0x1db0000>; /* 29.5 MB */
+		};
+	};
+};
+
+&sdhci0 { /* MIO13-23 - 16GB emmc MTFC16GAPALBH-IT - U133A */
+	status = "okay";
+	non-removable;
+	disable-wp;
+	bus-width = <8>;
+	xlnx,mio-bank = <0>;
+};
+
+&spi1 { /* MIO6, 9-11 */
+	status = "okay";
+	label = "TPM";
+	num-cs = <1>;
+	tpm at 0 { /* slm9670 - U144 */
+		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+		reg = <0>;
+		spi-max-frequency = <18500000>;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
+	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+
+	eeprom: eeprom at 50 { /* u46 - also at address 0x58 */
+		compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
+		reg = <0x50>;
+		/* WP pin EE_WP_EN connected to slg7x644092 at 68 */
+	};
+
+	eeprom_cc: eeprom at 51 { /* required by spec - also at address 0x59 */
+		compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
+		reg = <0x51>;
+	};
+
+	/* da9062 at 30 - u170 - also at address 0x31 */
+	/* da9131 at 33 - u167 */
+	da9131: pmic at 33 {
+		compatible = "dlg,da9131";
+		reg = <0x33>;
+		regulators {
+			da9131_buck1: buck1 {
+				regulator-name = "da9131_buck1";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+			da9131_buck2: buck2 {
+				regulator-name = "da9131_buck2";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
+
+	/* da9130 at 32 - u166 */
+	da9130: pmic at 32 {
+		compatible = "dlg,da9130";
+		reg = <0x32>;
+		regulators {
+			da9130_buck1: buck1 {
+				regulator-name = "da9130_buck1";
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
+
+	/* slg7x644091 at 70 - u168 NOT accessible due to address conflict with stdp4320 */
+	/*
+	 * stdp4320 - u27 FW has below two issues to be fixed in next board revision.
+	 * Device acknowledging to addresses 0x5C, 0x5D, 0x70, 0x72, 0x76.
+	 * Address conflict with slg7x644091 at 70 making both the devices NOT accessible.
+	 * With the FW fix, stdp4320 should respond to address 0x73 only.
+	 */
+	/* slg7x644092 at 68 - u169 */
+	/* Also connected via JA1C as C23/C24 */
+};
+
+&gpio {
+	status = "okay";
+	gpio-line-names = "QSPI_CLK", "QSPI_DQ1", "QSPI_DQ2", "QSPI_DQ3", "QSPI_DQ0", /* 0 - 4 */
+			  "QSPI_CS_B", "SPI_CLK", "LED1", "LED2", "SPI_CS_B", /* 5 - 9 */
+			  "SPI_MISO", "SPI_MOSI", "FWUEN", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */
+			  "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */
+			  "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST", "I2C1_SCL", /* 20 - 24 */
+			  "I2C1_SDA", "", "", "", "", /* 25 - 29 */
+			  "", "", "", "", "", /* 30 - 34 */
+			  "", "", "", "", "", /* 35 - 39 */
+			  "", "", "", "", "", /* 40 - 44 */
+			  "", "", "", "", "", /* 45 - 49 */
+			  "", "", "", "", "", /* 50 - 54 */
+			  "", "", "", "", "", /* 55 - 59 */
+			  "", "", "", "", "", /* 60 - 64 */
+			  "", "", "", "", "", /* 65 - 69 */
+			  "", "", "", "", "", /* 70 - 74 */
+			  "", "", "", /* 75 - 77, MIO end and EMIO start */
+			  "", "", /* 78 - 79 */
+			  "", "", "", "", "", /* 80 - 84 */
+			  "", "", "", "", "", /* 85 - 89 */
+			  "", "", "", "", "", /* 90 - 94 */
+			  "", "", "", "", "", /* 95 - 99 */
+			  "", "", "", "", "", /* 100 - 104 */
+			  "", "", "", "", "", /* 105 - 109 */
+			  "", "", "", "", "", /* 110 - 114 */
+			  "", "", "", "", "", /* 115 - 119 */
+			  "", "", "", "", "", /* 120 - 124 */
+			  "", "", "", "", "", /* 125 - 129 */
+			  "", "", "", "", "", /* 130 - 134 */
+			  "", "", "", "", "", /* 135 - 139 */
+			  "", "", "", "", "", /* 140 - 144 */
+			  "", "", "", "", "", /* 145 - 149 */
+			  "", "", "", "", "", /* 150 - 154 */
+			  "", "", "", "", "", /* 155 - 159 */
+			  "", "", "", "", "", /* 160 - 164 */
+			  "", "", "", "", "", /* 165 - 169 */
+			  "", "", "", ""; /* 170 - 174 */
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
new file mode 100644
index 000000000000..c70966c1f344
--- /dev/null
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Xilinx ZynqMP SMK-K26 rev1/B/A
+ *
+ * (C) Copyright 2020 - 2021, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek at xilinx.com>
+ */
+
+#include "zynqmp-sm-k26-revA.dts"
+
+/ {
+	model = "ZynqMP SMK-K26 Rev1/B/A";
+	compatible = "xlnx,zynqmp-smk-k26-rev1", "xlnx,zynqmp-smk-k26-revB",
+		     "xlnx,zynqmp-smk-k26-revA", "xlnx,zynqmp-smk-k26",
+		     "xlnx,zynqmp";
+};
+
+&sdhci0 {
+	status = "disabled";
+};
-- 
2.32.0



From michal.simek at xilinx.com  Fri Aug  6 03:14:23 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri,  6 Aug 2021 12:14:23 +0200
Subject: [PATCH] arm64: zynqmp: Wire psgtr for zc1751-xm013
Message-ID: <8c78625f08c16385a4798e0a62d20df7491ac00e.1628244860.git.michal.simek@xilinx.com>

Add psgtr description for SATA and USB.

Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

Based on https://lore.kernel.org/r/cover.1628244703.git.michal.simek at xilinx.com
---
 .../dts/xilinx/zynqmp-zc1751-xm017-dc3.dts    | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
index 4394ec3b6a23..381cc682cef9 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
@@ -11,6 +11,7 @@
 
 #include "zynqmp.dtsi"
 #include "zynqmp-clk-ccf.dtsi"
+#include <dt-bindings/phy/phy.h>
 
 / {
 	model = "ZynqMP zc1751-xm017-dc3 RevA";
@@ -37,6 +38,18 @@ memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
 	};
+
+	clock_si5338_2: clk26 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+	};
+
+	clock_si5338_3: clk125 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <125000000>;
+	};
 };
 
 &fpd_dma_chan1 {
@@ -116,6 +129,13 @@ &nand0 {
 	num-cs = <2>;
 };
 
+&psgtr {
+	status = "okay";
+	/* usb3, sata */
+	clocks = <&clock_si5338_2>, <&clock_si5338_3>;
+	clock-names = "ref2", "ref3";
+};
+
 &rtc {
 	status = "okay";
 };
@@ -131,6 +151,8 @@ &sata {
 	ceva,p1-comwake-params = /bits/ 8 <0x06 0x19 0x08 0x0E>;
 	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
 	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
+	phy-names = "sata-phy";
+	phys = <&psgtr 2 PHY_TYPE_SATA 0 3>;
 };
 
 &sdhci1 { /* emmc with some settings */
@@ -149,6 +171,8 @@ &uart1 {
 
 &usb0 {
 	status = "okay";
+	phy-names = "usb3-phy";
+	phys = <&psgtr 0 PHY_TYPE_USB3 0 2>;
 };
 
 &dwc3_0 {
@@ -161,6 +185,8 @@ &dwc3_0 {
 /* ULPI SMSC USB3320 */
 &usb1 {
 	status = "okay";
+	phy-names = "usb3-phy";
+	phys = <&psgtr 3 PHY_TYPE_USB3 1 2>;
 };
 
 &dwc3_1 {
-- 
2.32.0



From monstr at monstr.eu  Fri Aug  6 03:25:21 2021
From: monstr at monstr.eu (Michal Simek)
Date: Fri, 6 Aug 2021 12:25:21 +0200
Subject: [PATCH] reset: reset-zynqmp: Fixed the argument data type
In-Reply-To: <925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek@xilinx.com>
References: <925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek@xilinx.com>
Message-ID: <CAHTX3d+OaDuh5d=LCCQTapSkfEosyCFWrStbjBwySgK47Q4YQA@mail.gmail.com>

Hi Philipp,

st 23. 6. 2021 v 13:46 odes?latel Michal Simek <michal.simek at xilinx.com> napsal:
>
> From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
>
> This patch changes the data type of the variable 'val' from
> int to u32.
>
> Addresses-Coverity: argument of type "int *" is incompatible with parameter of type "u32 *"
> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
>  drivers/reset/reset-zynqmp.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
> index daa425e74c96..59dc0ff9af9e 100644
> --- a/drivers/reset/reset-zynqmp.c
> +++ b/drivers/reset/reset-zynqmp.c
> @@ -53,7 +53,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
>                                unsigned long id)
>  {
>         struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
> -       int val, err;
> +       int err;
> +       u32 val;
>
>         err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val);
>         if (err)
> --
> 2.32.0
>

Can you please take a look at this patch?

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From robin.murphy at arm.com  Fri Aug  6 03:27:58 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 6 Aug 2021 11:27:58 +0100
Subject: [PATCH v3 2/7] soc: rockchip: io-domain: add rk3568 support
In-Reply-To: <2021080617460178513151@rock-chips.com>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
 <20210805120107.27007-3-michael.riesch@wolfvision.net>
 <8008800c-c518-30d4-edcf-57566e7a1251@arm.com> <3206032.SvYEEZNnvj@diego>
 <2021080617460178513151@rock-chips.com>
Message-ID: <41dbf032-c852-fbe4-befd-3dc89b24f4c9@arm.com>

On 2021-08-06 10:46, jay.xu at rock-chips.com wrote:
> Hi Heiko and Robin
> 
> --------------
> jay.xu at rock-chips.com
>> Hi Robin,
>>
>> Am Donnerstag, 5. August 2021, 18:27:36 CEST schrieb Robin Murphy:
>>> On 2021-08-05 13:01, Michael Riesch wrote:
>>>> From: Jianqun Xu <jay.xu at rock-chips.com>
>>>>
>>>> The io-domain registers on RK3568 SoCs have three separated bits to
>>>> enable/disable the 1.8v/2.5v/3.3v power.
>>>>
>>>> This patch make the write to be a operation, allow rk3568 uses a private
>>>> register set function.
>>>>
>>>> Since the 2.5v is not used on RK3568, so the driver only set
>>>
>>> FWIW, this seems at odds with what the first paragraph says - can anyone
>>> clarify what exactly "not used" means here? Is it that the I/O domain
>>> controller has been redesigned to support more than two logic levels on
>>> the new generation of SoCs, but RK3568's I/O pads still only physically
>>> support 1.8v and 3.3v; or is it that it *can* support 2.5v as well but
>>> no currently-known RK3568-based designs use that?
>>>
>>> In the former case it's just a wording issue in the commit message, but
>>> in the latter it's arguably worth implementing support now for the sake
>>> of future compatibility.
>>
>> I hadn't looked that deeply into the rk356x io-domain config, but at least
>> on a register level in the TRM it seems there are separate bits for
>> "3.3V control", "2.5V control", "1.8V control" [0] for each io-domain.
>>
>> Of course the documentation is otherwise somewhat sparse.
>>
>> Maybe Jay or Kever [added] can explain a bit more about the 3 voltage
>> levels.
>>
>>
>> In general though, I tend to find the approach good enough for now.
>>
>> Especially as the io-domain stuff is always said to "can cause damage
>> to the soc if used incorrectly" and it looks like nobody (including
>> Rockchip) seems to have actual hardware using these 2.5V levels right now.
>>
>> So having code in there that no-one ever tested doesn't feel too good ;-)
>>
> yes
> 
> about the 3bit
> 
> case ? ? V33 ?V25 ?V18 ? ? ? result
> 0 ? ? ? ? ?0 ? ? ?0 ? ? ? 0 ? ? ? ? ? IO safe, but cannot work
> 1 ? ? ? ? ?0 ? ? ?0 ? ? ? 1 ? ? ? ? ? IO require 1.8V, should < 1.98V, otherwise IO may damage
> 2 ? ? ? ? ?0 ? ? ?1 ? ? ? 0 ? ? ? ? ? IO require 2.5V, should < 2.75V, otherwise IO may damage
> 3 ? ? ? ? ?0 ? ? ?1 ? ? ? 1 ? ? ? ? ? Invalid state, should avoid
> 4 ? ? ? ? ?1 ? ? ?0 ? ? ? 0 ? ? ? ? ??IO require 3.3V, should < 3.63V, otherwise IO may damage
> 5 ? ? ? ? ?1 ? ? ?0 ? ? ? 1 ? ? ? ? ??IO require 1.8V, should < 1.98V, otherwise IO may damage
> 6 ? ? ? ? ?1 ? ? ?1 ? ? ? 0 ? ? ? ? ? IO require 2.5V, should < 2.75V, otherwise IO may damage
> 7 ? ? ? ? ?1 ? ? ?1 ? ? ? 1 ? ? ? ? ? Invalid state, should avoid

Thanks Jay, that's useful to know.

Fair enough if it's the case that 2.5V mode hasn't been validated with 
the BSP kernel either - I'd have no objection to clarifying the commit 
message that way instead, I'm just a curious reviewer who noticed some 
ambiguity :)

>> Adding this later when needed should be somewhat easy, as it really only
>> needs adding of handling that 3rd control bit per domain.

I'm mostly just thinking ahead a year or two when board designers have 
ventured further away from the reference design and *are* using 2.5V 
external components, then a user puts an older stable mainline kernel on 
their board and starts tearing their hair out trying to figure out why 
things are flaky. For instance I recall from my RK3328 box that if the 
I/O domain setting for the GMAC is too high for the actual supply 
voltage (such that it never detects MDIO responses from the external 
phy) you end up getting an utterly nonsensical DMA error. In that case I 
eventually figured out (by chance) that it was because I didn't have the 
I/O domain driver enabled in my config, but it would be a whole other 
level of frustration if the driver appeared to be working but was 
quietly doing the wrong thing.

Cheers,
Robin.

>>
>>
>> Heiko
>>
>>
>>
>> [0] what happens if none of the 3 is active? ;-)
>>
>>
>>>
>>> Robin.
>>>
>>>> 1.8v [enable] + 3.3v [disable] for 1.8v mode
>>>> 1.8v [disable] + 3.3v [enable] for 3.3v mode
>>>>
>>>> There is not register order requirement which has been cleared by our IC
>>>> team.
>>>>
>>>> Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
>>>> ---
>>>>  ?? drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
>>>>  ?? 1 file changed, 80 insertions(+), 8 deletions(-)
>>>>
>>>> diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
>>>> index cf8182fc3642..13c446fd33a9 100644
>>>> --- a/drivers/soc/rockchip/io-domain.c
>>>> +++ b/drivers/soc/rockchip/io-domain.c
>>>> @@ -51,13 +51,11 @@
>>>>  ?? #define RK3399_PMUGRF_CON0_VSEL	BIT(8)
>>>>  ?? #define RK3399_PMUGRF_VSEL_SUPPLY_NUM	9
>>>>    
>>>> -struct rockchip_iodomain;
>>>> +#define RK3568_PMU_GRF_IO_VSEL0	(0x0140)
>>>> +#define RK3568_PMU_GRF_IO_VSEL1	(0x0144)
>>>> +#define RK3568_PMU_GRF_IO_VSEL2	(0x0148)
>>>>    
>>>> -struct rockchip_iodomain_soc_data {
>>>> -	int grf_offset;
>>>> -	const char *supply_names[MAX_SUPPLIES];
>>>> -	void (*init)(struct rockchip_iodomain *iod);
>>>> -};
>>>> +struct rockchip_iodomain;
>>>>    
>>>>  ?? struct rockchip_iodomain_supply {
>>>>  ?? struct rockchip_iodomain *iod;
>>>> @@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
>>>>  ?? int idx;
>>>>  ?? };
>>>>    
>>>> +struct rockchip_iodomain_soc_data {
>>>> +	int grf_offset;
>>>> +	const char *supply_names[MAX_SUPPLIES];
>>>> +	void (*init)(struct rockchip_iodomain *iod);
>>>> +	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
>>>> +};
>>>> +
>>>>  ?? struct rockchip_iodomain {
>>>>  ?? struct device *dev;
>>>>  ?? struct regmap *grf;
>>>>  ?? const struct rockchip_iodomain_soc_data *soc_data;
>>>>  ?? struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
>>>> +	int (*write)(struct rockchip_iodomain_supply *supply, int uV);
>>>>  ?? };
>>>>    
>>>> +static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
>>>> +{
>>>> +	struct rockchip_iodomain *iod = supply->iod;
>>>> +	u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
>>>> +	u32 val0, val1;
>>>> +	int b;
>>>> +
>>>> +	switch (supply->idx) {
>>>> +	case 0: /* pmuio1 */
>>>> +	break;
>>>> +	case 1: /* pmuio2 */
>>>> +	b = supply->idx;
>>>> +	val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
>>>> +	b = supply->idx + 4;
>>>> +	val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
>>>> +
>>>> +	regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
>>>> +	regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
>>>> +	break;
>>>> +	case 3: /* vccio2 */
>>>> +	break;
>>>> +	case 2: /* vccio1 */
>>>> +	case 4: /* vccio3 */
>>>> +	case 5: /* vccio4 */
>>>> +	case 6: /* vccio5 */
>>>> +	case 7: /* vccio6 */
>>>> +	case 8: /* vccio7 */
>>>> +	b = supply->idx - 1;
>>>> +	val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
>>>> +	val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
>>>> +
>>>> +	regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
>>>> +	regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
>>>> +	break;
>>>> +	default:
>>>> +	return -EINVAL;
>>>> +	};
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>>  ?? static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
>>>>  ?? ?? int uV)
>>>>  ?? {
>>>> @@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
>>>>  ?? return NOTIFY_BAD;
>>>>  ?? }
>>>>    
>>>> -	ret = rockchip_iodomain_write(supply, uV);
>>>> +	ret = supply->iod->write(supply, uV);
>>>>  ?? if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
>>>>  ?? return NOTIFY_BAD;
>>>>    
>>>> @@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
>>>>  ?? .init = rk3399_pmu_iodomain_init,
>>>>  ?? };
>>>>    
>>>> +static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
>>>> +	.grf_offset = 0x140,
>>>> +	.supply_names = {
>>>> +	"pmuio1",
>>>> +	"pmuio2",
>>>> +	"vccio1",
>>>> +	"vccio2",
>>>> +	"vccio3",
>>>> +	"vccio4",
>>>> +	"vccio5",
>>>> +	"vccio6",
>>>> +	"vccio7",
>>>> +	},
>>>> +	.write = rk3568_iodomain_write,
>>>> +};
>>>> +
>>>>  ?? static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
>>>>  ?? .grf_offset = 0x404,
>>>>  ?? .supply_names = {
>>>> @@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
>>>>  ?? .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
>>>>  ?? .data = &soc_data_rk3399_pmu
>>>>  ?? },
>>>> +	{
>>>> +	.compatible = "rockchip,rk3568-pmu-io-voltage-domain",
>>>> +	.data = &soc_data_rk3568_pmu
>>>> +	},
>>>>  ?? {
>>>>  ?? .compatible = "rockchip,rv1108-io-voltage-domain",
>>>>  ?? .data = &soc_data_rv1108
>>>> @@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>>>>  ?? match = of_match_node(rockchip_iodomain_match, np);
>>>>  ?? iod->soc_data = match->data;
>>>>    
>>>> +	if (iod->soc_data->write)
>>>> +	iod->write = iod->soc_data->write;
>>>> +	else
>>>> +	iod->write = rockchip_iodomain_write;
>>>> +
>>>>  ?? parent = pdev->dev.parent;
>>>>  ?? if (parent && parent->of_node) {
>>>>  ?? iod->grf = syscon_node_to_regmap(parent->of_node);
>>>> @@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>>>>  ?? supply->reg = reg;
>>>>  ?? supply->nb.notifier_call = rockchip_iodomain_notify;
>>>>    
>>>> -	ret = rockchip_iodomain_write(supply, uV);
>>>> +	ret = iod->write(supply, uV);
>>>>  ?? if (ret) {
>>>>  ?? supply->reg = NULL;
>>>>  ?? goto unreg_notify;
>>>>
>>>
>>
>>
>>
>>
>>
>>
>>
> 


From monstr at monstr.eu  Fri Aug  6 03:28:16 2021
From: monstr at monstr.eu (Michal Simek)
Date: Fri, 6 Aug 2021 12:28:16 +0200
Subject: [PATCH v3 0/2] PCI: xilinx-nwl: Add clock handling
In-Reply-To: <cover.1624618100.git.michal.simek@xilinx.com>
References: <cover.1624618100.git.michal.simek@xilinx.com>
Message-ID: <CAHTX3dL5qTaB+YFPXiDYQAcDD_L9mYu_zAY=zV_2kXMsOR=YAA@mail.gmail.com>

Hi Bjorn and Krzysztof,

p? 25. 6. 2021 v 12:48 odes?latel Michal Simek <michal.simek at xilinx.com> napsal:
>
> Hi,
>
> this small series add support for enabling PCIe reference clock by driver.
>
> Thanks,
> Michal
>
> Changes in v3:
> - use PCIe instead of pcie
> - add stable cc
> - update commit message - reported by Krzysztof
>
> Changes in v2:
> - new patch in this series because I found that it has never been sent
> - Update commit message - reported by Krzysztof
> - Check return value from clk_prepare_enable() - reported by Krzysztof
>
> Hyun Kwon (1):
>   PCI: xilinx-nwl: Enable the clock through CCF
>
> Michal Simek (1):
>   dt-bindings: pci: xilinx-nwl: Document optional clock property
>
>  .../devicetree/bindings/pci/xilinx-nwl-pcie.txt      |  1 +
>  drivers/pci/controller/pcie-xilinx-nwl.c             | 12 ++++++++++++
>  2 files changed, 13 insertions(+)
>
> --
> 2.32.0
>

Can you please take a look at this series?

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From michal.simek at xilinx.com  Fri Aug  6 03:32:36 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri,  6 Aug 2021 12:32:36 +0200
Subject: [PATCH] firmware: xilinx: Fix incorrect names in kernel-doc
Message-ID: <a81edd4fc6cff4bd7e4984fceda941b9e9ab01bf.1628245954.git.michal.simek@xilinx.com>

There are some c&p issues reported by kernel-doc as:
drivers/firmware/xilinx/zynqmp.c:676: warning: expecting prototype for
zynqmp_pm_write_ggs(). Prototype was for zynqmp_pm_read_ggs() instead
drivers/firmware/xilinx/zynqmp.c:710: warning: expecting prototype for
zynqmp_pm_write_pggs(). Prototype was for zynqmp_pm_read_pggs() instead
drivers/firmware/xilinx/zynqmp.c:1023: warning: expecting prototype for
zynqmp_pm_aes(). Prototype was for zynqmp_pm_aes_engine() instead

Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 drivers/firmware/xilinx/zynqmp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 15b138326ecc..a9849e298d7f 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -664,7 +664,7 @@ int zynqmp_pm_write_ggs(u32 index, u32 value)
 EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs);
 
 /**
- * zynqmp_pm_write_ggs() - PM API for reading global general storage (ggs)
+ * zynqmp_pm_read_ggs() - PM API for reading global general storage (ggs)
  * @index:	GGS register index
  * @value:	Register value to be written
  *
@@ -697,7 +697,7 @@ int zynqmp_pm_write_pggs(u32 index, u32 value)
 EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs);
 
 /**
- * zynqmp_pm_write_pggs() - PM API for reading persistent global general
+ * zynqmp_pm_read_pggs() - PM API for reading persistent global general
  *			     storage (pggs)
  * @index:	PGGS register index
  * @value:	Register value to be written
@@ -1012,7 +1012,7 @@ int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities,
 EXPORT_SYMBOL_GPL(zynqmp_pm_set_requirement);
 
 /**
- * zynqmp_pm_aes - Access AES hardware to encrypt/decrypt the data using
+ * zynqmp_pm_aes_engine - Access AES hardware to encrypt/decrypt the data using
  * AES-GCM core.
  * @address:	Address of the AesParams structure.
  * @out:	Returned output value
-- 
2.32.0



From monstr at monstr.eu  Fri Aug  6 03:37:07 2021
From: monstr at monstr.eu (Michal Simek)
Date: Fri, 6 Aug 2021 12:37:07 +0200
Subject: [V2][PATCH] drm: xlnx: zynqmp: release reset to DP controller
 before accessing DP registers
In-Reply-To: <YFquZaW4JTTM7ogS@pendragon.ideasonboard.com>
References: <20210323025501.1568039-1-quanyang.wang@windriver.com>
 <YFquZaW4JTTM7ogS@pendragon.ideasonboard.com>
Message-ID: <CAHTX3d+uZsqevn0+7Lo+z62mk-1+S7n7VuO-QU8Q1Y-gP0Ugyw@mail.gmail.com>

Hi,

st 24. 3. 2021 v 4:15 odes?latel Laurent Pinchart
<laurent.pinchart at ideasonboard.com> napsal:
>
> Hi Quanyang,
>
> Thank you for the patch.
>
> On Tue, Mar 23, 2021 at 10:55:01AM +0800, quanyang.wang at windriver.com wrote:
> > From: Quanyang Wang <quanyang.wang at windriver.com>
> >
> > When insmod zynqmp-dpsub.ko after rmmod it, system will hang with the
> > error log as below:
> >
> > root at xilinx-zynqmp:~# insmod zynqmp-dpsub.ko
> > [   88.391289] [drm] Initialized zynqmp-dpsub 1.0.0 20130509 for fd4a0000.display on minor 0
> > [   88.529906] Console: switching to colour frame buffer device 128x48
> > [   88.549402] zynqmp-dpsub fd4a0000.display: [drm] fb0: zynqmp-dpsubdrm frame buffer device
> > [   88.571624] zynqmp-dpsub fd4a0000.display: ZynqMP DisplayPort Subsystem driver probed
> > root at xilinx-zynqmp:~# rmmod zynqmp_dpsub
> > [   94.023404] Console: switching to colour dummy device 80x25
> > root at xilinx-zynqmp:~# insmod zynqmp-dpsub.ko
> >       <hang here>
> >
> > This is because that in zynqmp_dp_probe it tries to access some DP
> > registers while the DP controller is still in the reset state. When
> > running "rmmod zynqmp_dpsub", zynqmp_dp_reset(dp, true) in
> > zynqmp_dp_phy_exit is called to force the DP controller into the reset
> > state. Then insmod will call zynqmp_dp_probe to program the DP registers,
> > but at this moment the DP controller hasn't been brought out of the reset
> > state yet since the function zynqmp_dp_reset(dp, false) is called later and
> > this will result the system hang.
> >
> > Releasing the reset to DP controller before any read/write operation to it
> > will fix this issue. And for symmetry, move zynqmp_dp_reset() call from
> > zynqmp_dp_phy_exit() to zynqmp_dp_remove().
> >
> > Signed-off-by: Quanyang Wang <quanyang.wang at windriver.com>
>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Can someone pick this patch?

Thanks,
Michal


From matthias.bgg at gmail.com  Fri Aug  6 03:42:31 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 6 Aug 2021 12:42:31 +0200
Subject: [PATCH] mmc: mediatek: add wait dma stop done flow
In-Reply-To: <20210806023055.29524-1-derong.liu@mediatek.com>
References: <20210806023055.29524-1-derong.liu@mediatek.com>
Message-ID: <dae1e028-d817-aba3-cc11-546a07865cda@gmail.com>

Thanks for your patch.

On 06/08/2021 04:30, Derong Liu wrote:
> From: mtk13858 <derong.liu at mediatek.com>
> 
> it needs to wait for dma stop done after set dma stop.
> 

Please provide a better commit message. Which bug do you see on which SoC? Are
you sure you can apply that to all SoC without breaking stuff?

> Signed-off-by: mtk13858 <derong.liu at mediatek.com>

Full name please.

Regards,
Matthias

> ---
>  drivers/mmc/host/mtk-sd.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 4dfc246c5f95..1dfd2842471b 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -2339,6 +2339,8 @@ static void msdc_cqe_disable(struct mmc_host *mmc, bool recovery)
>  	if (recovery) {
>  		sdr_set_field(host->base + MSDC_DMA_CTRL,
>  			      MSDC_DMA_CTRL_STOP, 1);
> +		while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS)
> +			cpu_relax();
>  		msdc_reset_hw(host);
>  	}
>  }
> 


From laurent.pinchart at ideasonboard.com  Fri Aug  6 03:43:37 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 6 Aug 2021 13:43:37 +0300
Subject: [V2][PATCH] drm: xlnx: zynqmp: release reset to DP controller
 before accessing DP registers
In-Reply-To: <CAHTX3d+uZsqevn0+7Lo+z62mk-1+S7n7VuO-QU8Q1Y-gP0Ugyw@mail.gmail.com>
References: <20210323025501.1568039-1-quanyang.wang@windriver.com>
 <YFquZaW4JTTM7ogS@pendragon.ideasonboard.com>
 <CAHTX3d+uZsqevn0+7Lo+z62mk-1+S7n7VuO-QU8Q1Y-gP0Ugyw@mail.gmail.com>
Message-ID: <YQ0SWXvWZ5THf+vM@pendragon.ideasonboard.com>

Hi Michale,

On Fri, Aug 06, 2021 at 12:37:07PM +0200, Michal Simek wrote:
> st 24. 3. 2021 v 4:15 odes?latel Laurent Pinchart napsal:
> > On Tue, Mar 23, 2021 at 10:55:01AM +0800, quanyang.wang at windriver.com wrote:
> > > From: Quanyang Wang <quanyang.wang at windriver.com>
> > >
> > > When insmod zynqmp-dpsub.ko after rmmod it, system will hang with the
> > > error log as below:
> > >
> > > root at xilinx-zynqmp:~# insmod zynqmp-dpsub.ko
> > > [   88.391289] [drm] Initialized zynqmp-dpsub 1.0.0 20130509 for fd4a0000.display on minor 0
> > > [   88.529906] Console: switching to colour frame buffer device 128x48
> > > [   88.549402] zynqmp-dpsub fd4a0000.display: [drm] fb0: zynqmp-dpsubdrm frame buffer device
> > > [   88.571624] zynqmp-dpsub fd4a0000.display: ZynqMP DisplayPort Subsystem driver probed
> > > root at xilinx-zynqmp:~# rmmod zynqmp_dpsub
> > > [   94.023404] Console: switching to colour dummy device 80x25
> > > root at xilinx-zynqmp:~# insmod zynqmp-dpsub.ko
> > >       <hang here>
> > >
> > > This is because that in zynqmp_dp_probe it tries to access some DP
> > > registers while the DP controller is still in the reset state. When
> > > running "rmmod zynqmp_dpsub", zynqmp_dp_reset(dp, true) in
> > > zynqmp_dp_phy_exit is called to force the DP controller into the reset
> > > state. Then insmod will call zynqmp_dp_probe to program the DP registers,
> > > but at this moment the DP controller hasn't been brought out of the reset
> > > state yet since the function zynqmp_dp_reset(dp, false) is called later and
> > > this will result the system hang.
> > >
> > > Releasing the reset to DP controller before any read/write operation to it
> > > will fix this issue. And for symmetry, move zynqmp_dp_reset() call from
> > > zynqmp_dp_phy_exit() to zynqmp_dp_remove().
> > >
> > > Signed-off-by: Quanyang Wang <quanyang.wang at windriver.com>
> >
> > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> 
> Can someone pick this patch?

I have it in my tree with a set of other changes, I intend to send a
pull request today.

-- 
Regards,

Laurent Pinchart


From pgwipeout at gmail.com  Fri Aug  6 03:57:49 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Fri, 6 Aug 2021 06:57:49 -0400
Subject: [PATCH v3 2/7] soc: rockchip: io-domain: add rk3568 support
In-Reply-To: <41dbf032-c852-fbe4-befd-3dc89b24f4c9@arm.com>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
 <20210805120107.27007-3-michael.riesch@wolfvision.net>
 <8008800c-c518-30d4-edcf-57566e7a1251@arm.com>
 <3206032.SvYEEZNnvj@diego> <2021080617460178513151@rock-chips.com>
 <41dbf032-c852-fbe4-befd-3dc89b24f4c9@arm.com>
Message-ID: <CAMdYzYpw7RP+jbP_0HkVwAF8=b_k0oeti+h9214NtnjSfvT_ww@mail.gmail.com>

On Fri, Aug 6, 2021 at 6:28 AM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2021-08-06 10:46, jay.xu at rock-chips.com wrote:
> > Hi Heiko and Robin
> >
> > --------------
> > jay.xu at rock-chips.com
> >> Hi Robin,
> >>
> >> Am Donnerstag, 5. August 2021, 18:27:36 CEST schrieb Robin Murphy:
> >>> On 2021-08-05 13:01, Michael Riesch wrote:
> >>>> From: Jianqun Xu <jay.xu at rock-chips.com>
> >>>>
> >>>> The io-domain registers on RK3568 SoCs have three separated bits to
> >>>> enable/disable the 1.8v/2.5v/3.3v power.
> >>>>
> >>>> This patch make the write to be a operation, allow rk3568 uses a private
> >>>> register set function.
> >>>>
> >>>> Since the 2.5v is not used on RK3568, so the driver only set
> >>>
> >>> FWIW, this seems at odds with what the first paragraph says - can anyone
> >>> clarify what exactly "not used" means here? Is it that the I/O domain
> >>> controller has been redesigned to support more than two logic levels on
> >>> the new generation of SoCs, but RK3568's I/O pads still only physically
> >>> support 1.8v and 3.3v; or is it that it *can* support 2.5v as well but
> >>> no currently-known RK3568-based designs use that?
> >>>
> >>> In the former case it's just a wording issue in the commit message, but
> >>> in the latter it's arguably worth implementing support now for the sake
> >>> of future compatibility.
> >>
> >> I hadn't looked that deeply into the rk356x io-domain config, but at least
> >> on a register level in the TRM it seems there are separate bits for
> >> "3.3V control", "2.5V control", "1.8V control" [0] for each io-domain.
> >>
> >> Of course the documentation is otherwise somewhat sparse.
> >>
> >> Maybe Jay or Kever [added] can explain a bit more about the 3 voltage
> >> levels.
> >>
> >>
> >> In general though, I tend to find the approach good enough for now.
> >>
> >> Especially as the io-domain stuff is always said to "can cause damage
> >> to the soc if used incorrectly" and it looks like nobody (including
> >> Rockchip) seems to have actual hardware using these 2.5V levels right now.
> >>
> >> So having code in there that no-one ever tested doesn't feel too good ;-)
> >>
> > yes
> >
> > about the 3bit
> >
> > case     V33  V25  V18       result
> > 0          0      0       0           IO safe, but cannot work
> > 1          0      0       1           IO require 1.8V, should < 1.98V, otherwise IO may damage
> > 2          0      1       0           IO require 2.5V, should < 2.75V, otherwise IO may damage
> > 3          0      1       1           Invalid state, should avoid
> > 4          1      0       0           IO require 3.3V, should < 3.63V, otherwise IO may damage
> > 5          1      0       1           IO require 1.8V, should < 1.98V, otherwise IO may damage
> > 6          1      1       0           IO require 2.5V, should < 2.75V, otherwise IO may damage
> > 7          1      1       1           Invalid state, should avoid
>
> Thanks Jay, that's useful to know.
>
> Fair enough if it's the case that 2.5V mode hasn't been validated with
> the BSP kernel either - I'd have no objection to clarifying the commit
> message that way instead, I'm just a curious reviewer who noticed some
> ambiguity :)
>
> >> Adding this later when needed should be somewhat easy, as it really only
> >> needs adding of handling that 3rd control bit per domain.
>
> I'm mostly just thinking ahead a year or two when board designers have
> ventured further away from the reference design and *are* using 2.5V
> external components, then a user puts an older stable mainline kernel on
> their board and starts tearing their hair out trying to figure out why
> things are flaky. For instance I recall from my RK3328 box that if the
> I/O domain setting for the GMAC is too high for the actual supply
> voltage (such that it never detects MDIO responses from the external
> phy) you end up getting an utterly nonsensical DMA error. In that case I
> eventually figured out (by chance) that it was because I didn't have the
> I/O domain driver enabled in my config, but it would be a whole other
> level of frustration if the driver appeared to be working but was
> quietly doing the wrong thing.

I too have experienced the joys of io-domains breaking things.
Perhaps the driver should warn when the voltages aren't expected,
instead of when they are simply too high.

>
> Cheers,
> Robin.
>
> >>
> >>
> >> Heiko
> >>
> >>
> >>
> >> [0] what happens if none of the 3 is active? ;-)
> >>
> >>
> >>>
> >>> Robin.
> >>>
> >>>> 1.8v [enable] + 3.3v [disable] for 1.8v mode
> >>>> 1.8v [disable] + 3.3v [enable] for 3.3v mode
> >>>>
> >>>> There is not register order requirement which has been cleared by our IC
> >>>> team.
> >>>>
> >>>> Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
> >>>> ---
> >>>>     drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
> >>>>     1 file changed, 80 insertions(+), 8 deletions(-)
> >>>>
> >>>> diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
> >>>> index cf8182fc3642..13c446fd33a9 100644
> >>>> --- a/drivers/soc/rockchip/io-domain.c
> >>>> +++ b/drivers/soc/rockchip/io-domain.c
> >>>> @@ -51,13 +51,11 @@
> >>>>     #define RK3399_PMUGRF_CON0_VSEL        BIT(8)
> >>>>     #define RK3399_PMUGRF_VSEL_SUPPLY_NUM  9
> >>>>
> >>>> -struct rockchip_iodomain;
> >>>> +#define RK3568_PMU_GRF_IO_VSEL0   (0x0140)
> >>>> +#define RK3568_PMU_GRF_IO_VSEL1   (0x0144)
> >>>> +#define RK3568_PMU_GRF_IO_VSEL2   (0x0148)
> >>>>
> >>>> -struct rockchip_iodomain_soc_data {
> >>>> -  int grf_offset;
> >>>> -  const char *supply_names[MAX_SUPPLIES];
> >>>> -  void (*init)(struct rockchip_iodomain *iod);
> >>>> -};
> >>>> +struct rockchip_iodomain;
> >>>>
> >>>>     struct rockchip_iodomain_supply {
> >>>>     struct rockchip_iodomain *iod;
> >>>> @@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
> >>>>     int idx;
> >>>>     };
> >>>>
> >>>> +struct rockchip_iodomain_soc_data {
> >>>> +  int grf_offset;
> >>>> +  const char *supply_names[MAX_SUPPLIES];
> >>>> +  void (*init)(struct rockchip_iodomain *iod);
> >>>> +  int (*write)(struct rockchip_iodomain_supply *supply, int uV);
> >>>> +};
> >>>> +
> >>>>     struct rockchip_iodomain {
> >>>>     struct device *dev;
> >>>>     struct regmap *grf;
> >>>>     const struct rockchip_iodomain_soc_data *soc_data;
> >>>>     struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
> >>>> +  int (*write)(struct rockchip_iodomain_supply *supply, int uV);
> >>>>     };
> >>>>
> >>>> +static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
> >>>> +{
> >>>> +  struct rockchip_iodomain *iod = supply->iod;
> >>>> +  u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
> >>>> +  u32 val0, val1;
> >>>> +  int b;
> >>>> +
> >>>> +  switch (supply->idx) {
> >>>> +  case 0: /* pmuio1 */
> >>>> +  break;
> >>>> +  case 1: /* pmuio2 */
> >>>> +  b = supply->idx;
> >>>> +  val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
> >>>> +  b = supply->idx + 4;
> >>>> +  val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
> >>>> +
> >>>> +  regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
> >>>> +  regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
> >>>> +  break;
> >>>> +  case 3: /* vccio2 */
> >>>> +  break;
> >>>> +  case 2: /* vccio1 */
> >>>> +  case 4: /* vccio3 */
> >>>> +  case 5: /* vccio4 */
> >>>> +  case 6: /* vccio5 */
> >>>> +  case 7: /* vccio6 */
> >>>> +  case 8: /* vccio7 */
> >>>> +  b = supply->idx - 1;
> >>>> +  val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
> >>>> +  val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
> >>>> +
> >>>> +  regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
> >>>> +  regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
> >>>> +  break;
> >>>> +  default:
> >>>> +  return -EINVAL;
> >>>> +  };
> >>>> +
> >>>> +  return 0;
> >>>> +}
> >>>> +
> >>>>     static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
> >>>>        int uV)
> >>>>     {
> >>>> @@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
> >>>>     return NOTIFY_BAD;
> >>>>     }
> >>>>
> >>>> -  ret = rockchip_iodomain_write(supply, uV);
> >>>> +  ret = supply->iod->write(supply, uV);
> >>>>     if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
> >>>>     return NOTIFY_BAD;
> >>>>
> >>>> @@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
> >>>>     .init = rk3399_pmu_iodomain_init,
> >>>>     };
> >>>>
> >>>> +static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
> >>>> +  .grf_offset = 0x140,
> >>>> +  .supply_names = {
> >>>> +  "pmuio1",
> >>>> +  "pmuio2",
> >>>> +  "vccio1",
> >>>> +  "vccio2",
> >>>> +  "vccio3",
> >>>> +  "vccio4",
> >>>> +  "vccio5",
> >>>> +  "vccio6",
> >>>> +  "vccio7",
> >>>> +  },
> >>>> +  .write = rk3568_iodomain_write,
> >>>> +};
> >>>> +
> >>>>     static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
> >>>>     .grf_offset = 0x404,
> >>>>     .supply_names = {
> >>>> @@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
> >>>>     .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
> >>>>     .data = &soc_data_rk3399_pmu
> >>>>     },
> >>>> +  {
> >>>> +  .compatible = "rockchip,rk3568-pmu-io-voltage-domain",
> >>>> +  .data = &soc_data_rk3568_pmu
> >>>> +  },
> >>>>     {
> >>>>     .compatible = "rockchip,rv1108-io-voltage-domain",
> >>>>     .data = &soc_data_rv1108
> >>>> @@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
> >>>>     match = of_match_node(rockchip_iodomain_match, np);
> >>>>     iod->soc_data = match->data;
> >>>>
> >>>> +  if (iod->soc_data->write)
> >>>> +  iod->write = iod->soc_data->write;
> >>>> +  else
> >>>> +  iod->write = rockchip_iodomain_write;
> >>>> +
> >>>>     parent = pdev->dev.parent;
> >>>>     if (parent && parent->of_node) {
> >>>>     iod->grf = syscon_node_to_regmap(parent->of_node);
> >>>> @@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
> >>>>     supply->reg = reg;
> >>>>     supply->nb.notifier_call = rockchip_iodomain_notify;
> >>>>
> >>>> -  ret = rockchip_iodomain_write(supply, uV);
> >>>> +  ret = iod->write(supply, uV);
> >>>>     if (ret) {
> >>>>     supply->reg = NULL;
> >>>>     goto unreg_notify;
> >>>>
> >>>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >


From alexandre.torgue at foss.st.com  Fri Aug  6 03:58:17 2021
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Fri, 6 Aug 2021 12:58:17 +0200
Subject: [GIT PULL] STM32 DT changes for v5.15 #1
Message-ID: <e4f0bea3-4065-38d5-f1b2-007e4094c4a8@foss.st.com>

Hi ARM SoC maintainers,

Please consider this first round of STM32 DT updates for v5.15. A small 
PR containing mainly dtbs_check warnings fix for ST and DH boards.

regards
Alex

The following changes since commit 15f68f027ebd961b99a1c420f96ff3838c5e4450:

   ARM: dts: stm32: Fix touchscreen IRQ line assignment on DHCOM 
(2021-07-30 15:34:51 +0200)

are available in the Git repository at:

   git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git 
tags/stm32-dt-for-v5.15-1

for you to fetch changes up to 1e6bc5987a5252948e3411e5a2dbb434fd1ea107:

   ARM: dts: stm32: Update AV96 adv7513 node per dtbs_check (2021-07-30 
15:38:11 +0200)

----------------------------------------------------------------
STM32 DT for v5.15, round 1

Highlights:
----------

-MPU:
  - ST boards:
   - Add coporcessor detach mailbox on ED and DKx boards
   - Fix dtbs_check SAI warnings

  - DH boards:
   -Fix some dtbs_check warnings: usb, backlight, hdmi

----------------------------------------------------------------
Arnaud Pouliquen (2):
       ARM: dts: stm32: Add coprocessor detach mbox on stm32mp157c-ed1 board
       ARM: dts: stm32: Add coprocessor detach mbox on stm32mp15x-dkx boards

Marek Vasut (5):
       ARM: dts: stm32: Set {bitclock,frame}-master phandles on DHCOM SoM
       ARM: dts: stm32: Add backlight and panel supply on DHCOM SoM
       ARM: dts: stm32: Add usbphyc_port1 supply on DHCOM SoM
       ARM: dts: stm32: Set {bitclock,frame}-master phandles on ST DKx
       ARM: dts: stm32: Update AV96 adv7513 node per dtbs_check

  arch/arm/boot/dts/stm32mp157c-ed1.dts              |  4 ++--
  arch/arm/boot/dts/stm32mp15xx-dhcom-drc02.dtsi     |  4 ++++
  arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi      | 25 
++++++++++++++++++----
  arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi |  6 ++----
  arch/arm/boot/dts/stm32mp15xx-dkx.dtsi             | 12 +++++------
  5 files changed, 35 insertions(+), 16 deletions(-)


From patchwork-bot+netdevbpf at kernel.org  Fri Aug  6 04:10:05 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 06 Aug 2021 11:10:05 +0000
Subject: [PATCH net] net: dsa: mt7530: add the missing RxUnicast MIB
 counter
In-Reply-To: <20210806040528.735606-1-dqfext@gmail.com>
References: <20210806040528.735606-1-dqfext@gmail.com>
Message-ID: <162824820567.31954.9014839863327381261.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (refs/heads/master):

On Fri,  6 Aug 2021 12:05:27 +0800 you wrote:
> Add the missing RxUnicast counter.
> 
> Fixes: b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 switch")
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
>  drivers/net/dsa/mt7530.c | 1 +
>  1 file changed, 1 insertion(+)

Here is the summary with links:
  - [net] net: dsa: mt7530: add the missing RxUnicast MIB counter
    https://git.kernel.org/netdev/net/c/aff51c5da320

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Fri Aug  6 04:10:06 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 06 Aug 2021 11:10:06 +0000
Subject: [PATCH net-next v2] net: dsa: mt7530: drop untagged frames on
 VLAN-aware ports without PVID
In-Reply-To: <20210806034713.734853-1-dqfext@gmail.com>
References: <20210806034713.734853-1-dqfext@gmail.com>
Message-ID: <162824820631.31954.9293662469034354478.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (refs/heads/master):

On Fri,  6 Aug 2021 11:47:11 +0800 you wrote:
> The driver currently still accepts untagged frames on VLAN-aware ports
> without PVID. Use PVC.ACC_FRM to drop untagged frames in that case.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
> v1 -> v2: Avoid setting PVID to 0 on the CPU port.
> 
> [...]

Here is the summary with links:
  - [net-next,v2] net: dsa: mt7530: drop untagged frames on VLAN-aware ports without PVID
    https://git.kernel.org/netdev/net-next/c/8fbebef80107

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From matthias.bgg at gmail.com  Fri Aug  6 04:28:21 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 6 Aug 2021 13:28:21 +0200
Subject: [PATCH v6 2/7] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys0
In-Reply-To: <20210805205226.24880-3-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-3-jason-jh.lin@mediatek.com>
Message-ID: <28cc4599-6eda-4784-3d8f-4570c9ab60e8@gmail.com>

Hi Jason,

On 05/08/2021 22:52, jason-jh.lin wrote:
> Add mt8195 vdosys0 clock driver name and routing table to
> the driver data of mtk-mmsys.
> 

I'd like to see the implementation of vdosys1 as well, to better understand why
we need two compatibles.

> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> This patch is base on [1]
> 
> [1] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-2-jason-jh.lin at mediatek.com/

Please add the binding description to this series.

> ---
>  drivers/soc/mediatek/mt8195-mmsys.h    | 96 ++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c       | 11 +++
>  include/linux/soc/mediatek/mtk-mmsys.h |  9 +++
>  3 files changed, 116 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h
> 
> diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
> new file mode 100644
> index 000000000000..9339a786ec5d
> --- /dev/null
> +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> @@ -0,0 +1,96 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
> +#define __SOC_MEDIATEK_MT8195_MMSYS_H
> +
> +#define MT8195_VDO0_OVL_MOUT_EN					0xf14
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
> +
> +#define MT8195_VDO0_SEL_IN					0xf34
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		(0 << 0)
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		(1 << 0)
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		(2 << 0)
> +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		(0 << 4)
> +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		(1 << 4)
> +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		(0 << 5)
> +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		(1 << 5)
> +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		(0 << 8)
> +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		(1 << 8)
> +#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		(0 << 9)
> +#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		(0 << 12)
> +#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			(1 << 12)
> +#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		(2 << 12)
> +#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			(0 << 16)
> +#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			(1 << 16)
> +#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			(0 << 17)
> +#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			(1 << 17)
> +#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			(0 << 20)
> +#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			(1 << 20)
> +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		(0 << 21)
> +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		(1 << 21)
> +#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			(0 << 22)
> +#define MT8195_SEL_IN_DISP_WDMA0_FROM_VPP_MERGE			(1 << 22)
> +
> +#define MT8195_VDO0_SEL_OUT					0xf38
> +#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		(0 << 0)
> +#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			(1 << 0)
> +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		(0 << 1)
> +#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			(1 << 1)
> +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		(2 << 1)
> +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			(0 << 4)
> +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			(1 << 4)
> +#define MT8195_SOUT_VPP_MERGE_TO_DSI1				(0 << 8)
> +#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			(1 << 8)
> +#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			(2 << 8)
> +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(3 << 8)
> +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			(4 << 8)
> +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			(0 << 11)
> +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA0			(1 << 11)
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			(0 << 12)
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		(1 << 12)
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			(2 << 12)
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			(0 << 16)
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			(1 << 16)
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 << 16)
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(3 << 16)
> +
> +static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
> +	{
> +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0

Please update the struct to the new version that includes a mask field.

Regards,
Matthias


From vkoul at kernel.org  Fri Aug  6 04:30:01 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:00:01 +0530
Subject: [PATCH 4/7] dt-bindings: phy: imx8mq-usb-phy: convert to json
 schema
In-Reply-To: <20210715082536.1882077-5-aisheng.dong@nxp.com>
References: <20210715082536.1882077-1-aisheng.dong@nxp.com>
 <20210715082536.1882077-5-aisheng.dong@nxp.com>
Message-ID: <YQ0dOQteW4/2MPfZ@matsya>

On 15-07-21, 16:25, Dong Aisheng wrote:
> Convert to jason schema.

Applied, thanks

-- 
~Vinod


From will at kernel.org  Fri Aug  6 04:31:03 2021
From: will at kernel.org (Will Deacon)
Date: Fri,  6 Aug 2021 12:31:03 +0100
Subject: [PATCH 0/4] Fix racing TLBI with ASID/VMID reallocation
Message-ID: <20210806113109.2475-1-will@kernel.org>

Hi all,

While reviewing Shameer's reworked VMID allocator [1] and discussing
with Marc, we spotted a race between TLB invalidation (which typically
takes an ASID or VMID argument) and reallocation of ASID/VMID for the
context being targetted.

The first patch spells out an example with try_to_unmap_one() in a
comment, which Catalin has kindly modelled in TLA+ at [2].

Although I'm posting all this together for ease of review, the intention
is that the first patch will go via arm64 with the latter going via kvm.

Cheers,

Will

[1] https://lore.kernel.org/r/20210729104009.382-1-shameerali.kolothum.thodi at huawei.com
[2] https://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/kernel-tla.git/commit/

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Jade Alglave <jade.alglave at arm.com>
Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Cc: <kvmarm at lists.cs.columbia.edu>
Cc: <linux-arch at vger.kernel.org>

--->8

Marc Zyngier (3):
  KVM: arm64: Move kern_hyp_va() usage in __load_guest_stage2() into the
    callers
  KVM: arm64: Convert the host S2 over to __load_guest_stage2()
  KVM: arm64: Upgrade VMID accesses to {READ,WRITE}_ONCE

Will Deacon (1):
  arm64: mm: Fix TLBI vs ASID rollover

 arch/arm64/include/asm/kvm_mmu.h              | 17 ++++++-----
 arch/arm64/include/asm/mmu.h                  | 29 ++++++++++++++++---
 arch/arm64/include/asm/tlbflush.h             | 11 +++----
 arch/arm64/kvm/arm.c                          |  2 +-
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         |  6 ++--
 arch/arm64/kvm/hyp/nvhe/switch.c              |  4 ++-
 arch/arm64/kvm/hyp/nvhe/tlb.c                 |  2 +-
 arch/arm64/kvm/hyp/vhe/switch.c               |  2 +-
 arch/arm64/kvm/hyp/vhe/tlb.c                  |  2 +-
 arch/arm64/kvm/mmu.c                          |  2 +-
 11 files changed, 52 insertions(+), 27 deletions(-)

-- 
2.32.0.605.g8dce9f2422-goog



From will at kernel.org  Fri Aug  6 04:31:04 2021
From: will at kernel.org (Will Deacon)
Date: Fri,  6 Aug 2021 12:31:04 +0100
Subject: [PATCH 1/4] arm64: mm: Fix TLBI vs ASID rollover
In-Reply-To: <20210806113109.2475-1-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
Message-ID: <20210806113109.2475-2-will@kernel.org>

When switching to an 'mm_struct' for the first time following an ASID
rollover, a new ASID may be allocated and assigned to 'mm->context.id'.
This reassignment can happen concurrently with other operations on the
mm, such as unmapping pages and subsequently issuing TLB invalidation.

Consequently, we need to ensure that (a) accesses to 'mm->context.id'
are atomic and (b) all page-table updates made prior to a TLBI using the
old ASID are guaranteed to be visible to CPUs running with the new ASID.

This was found by inspection after reviewing the VMID changes from
Shameer but it looks like a real (yet hard to hit) bug.

Cc: <stable at vger.kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Jade Alglave <jade.alglave at arm.com>
Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Signed-off-by: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/mmu.h      | 29 +++++++++++++++++++++++++----
 arch/arm64/include/asm/tlbflush.h | 11 ++++++-----
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 75beffe2ee8a..e9c30859f80c 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -27,11 +27,32 @@ typedef struct {
 } mm_context_t;
 
 /*
- * This macro is only used by the TLBI and low-level switch_mm() code,
- * neither of which can race with an ASID change. We therefore don't
- * need to reload the counter using atomic64_read().
+ * We use atomic64_read() here because the ASID for an 'mm_struct' can
+ * be reallocated when scheduling one of its threads following a
+ * rollover event (see new_context() and flush_context()). In this case,
+ * a concurrent TLBI (e.g. via try_to_unmap_one() and ptep_clear_flush())
+ * may use a stale ASID. This is fine in principle as the new ASID is
+ * guaranteed to be clean in the TLB, but the TLBI routines have to take
+ * care to handle the following race:
+ *
+ *    CPU 0                    CPU 1                          CPU 2
+ *
+ *    // ptep_clear_flush(mm)
+ *    xchg_relaxed(pte, 0)
+ *    DSB ISHST
+ *    old = ASID(mm)
+ *         |                                                  <rollover>
+ *         |                   new = new_context(mm)
+ *         \-----------------> atomic_set(mm->context.id, new)
+ *                             cpu_switch_mm(mm)
+ *                             // Hardware walk of pte using new ASID
+ *    TLBI(old)
+ *
+ * In this scenario, the barrier on CPU 0 and the dependency on CPU 1
+ * ensure that the page-table walker on CPU 1 *must* see the invalid PTE
+ * written by CPU 0.
  */
-#define ASID(mm)	((mm)->context.id.counter & 0xffff)
+#define ASID(mm)	(atomic64_read(&(mm)->context.id) & 0xffff)
 
 static inline bool arm64_kernel_unmapped_at_el0(void)
 {
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index cc3f5a33ff9c..36f02892e1df 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -245,9 +245,10 @@ static inline void flush_tlb_all(void)
 
 static inline void flush_tlb_mm(struct mm_struct *mm)
 {
-	unsigned long asid = __TLBI_VADDR(0, ASID(mm));
+	unsigned long asid;
 
 	dsb(ishst);
+	asid = __TLBI_VADDR(0, ASID(mm));
 	__tlbi(aside1is, asid);
 	__tlbi_user(aside1is, asid);
 	dsb(ish);
@@ -256,9 +257,10 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
 static inline void flush_tlb_page_nosync(struct vm_area_struct *vma,
 					 unsigned long uaddr)
 {
-	unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm));
+	unsigned long addr;
 
 	dsb(ishst);
+	addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm));
 	__tlbi(vale1is, addr);
 	__tlbi_user(vale1is, addr);
 }
@@ -283,9 +285,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
 {
 	int num = 0;
 	int scale = 0;
-	unsigned long asid = ASID(vma->vm_mm);
-	unsigned long addr;
-	unsigned long pages;
+	unsigned long asid, addr, pages;
 
 	start = round_down(start, stride);
 	end = round_up(end, stride);
@@ -305,6 +305,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
 	}
 
 	dsb(ishst);
+	asid = ASID(vma->vm_mm);
 
 	/*
 	 * When the CPU does not support TLB range operations, flush the TLB
-- 
2.32.0.605.g8dce9f2422-goog



From will at kernel.org  Fri Aug  6 04:31:05 2021
From: will at kernel.org (Will Deacon)
Date: Fri,  6 Aug 2021 12:31:05 +0100
Subject: [PATCH] of: restricted dma: Don't fail device probe on rmem init
 failure
In-Reply-To: <20210806113109.2475-1-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
Message-ID: <20210806113109.2475-3-will@kernel.org>

If CONFIG_DMA_RESTRICTED_POOL=n then probing a device with a reference
to a "restricted-dma-pool" will fail with a reasonably cryptic error:

  | pci-host-generic: probe of 10000.pci failed with error -22

Print a more helpful message in this case and try to continue probing
the device as we do if the kernel doesn't have the restricted DMA patches
applied or either CONFIG_OF_ADDRESS or CONFIG_HAS_DMA =n.

Cc: Claire Chang <tientzu at chromium.org>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Robin Murphy <robin.murphy at arm.com>
Cc: Christoph Hellwig <hch at lst.de>
Cc: Rob Herring <robh+dt at kernel.org>
Signed-off-by: Will Deacon <will at kernel.org>
---
 drivers/of/address.c    | 8 ++++----
 drivers/of/device.c     | 2 +-
 drivers/of/of_private.h | 8 +++-----
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 973257434398..f6bf4b423c2a 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -997,7 +997,7 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map)
 	return ret;
 }
 
-int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
+void of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
 {
 	struct device_node *node, *of_node = dev->of_node;
 	int count, i;
@@ -1022,11 +1022,11 @@ int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np)
 		 */
 		if (of_device_is_compatible(node, "restricted-dma-pool") &&
 		    of_device_is_available(node))
-			return of_reserved_mem_device_init_by_idx(dev, of_node,
-								  i);
+			break;
 	}
 
-	return 0;
+	if (i != count && of_reserved_mem_device_init_by_idx(dev, of_node, i))
+		dev_warn(dev, "failed to initialise \"restricted-dma-pool\" memory node\n");
 }
 #endif /* CONFIG_HAS_DMA */
 
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 2defdca418ec..258a2b099410 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -166,7 +166,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np,
 	arch_setup_dma_ops(dev, dma_start, size, iommu, coherent);
 
 	if (!iommu)
-		return of_dma_set_restricted_buffer(dev, np);
+		of_dma_set_restricted_buffer(dev, np);
 
 	return 0;
 }
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index f557bd22b0cf..bc883f69496b 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -163,18 +163,16 @@ struct bus_dma_region;
 #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_HAS_DMA)
 int of_dma_get_range(struct device_node *np,
 		const struct bus_dma_region **map);
-int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np);
+void of_dma_set_restricted_buffer(struct device *dev, struct device_node *np);
 #else
 static inline int of_dma_get_range(struct device_node *np,
 		const struct bus_dma_region **map)
 {
 	return -ENODEV;
 }
-static inline int of_dma_set_restricted_buffer(struct device *dev,
-					       struct device_node *np)
+static inline void of_dma_set_restricted_buffer(struct device *dev,
+						struct device_node *np)
 {
-	/* Do nothing, successfully. */
-	return 0;
 }
 #endif
 
-- 
2.32.0.605.g8dce9f2422-goog



From will at kernel.org  Fri Aug  6 04:31:06 2021
From: will at kernel.org (Will Deacon)
Date: Fri,  6 Aug 2021 12:31:06 +0100
Subject: [PATCH 2/4] KVM: arm64: Move kern_hyp_va() usage in
 __load_guest_stage2() into the callers
In-Reply-To: <20210806113109.2475-1-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
Message-ID: <20210806113109.2475-4-will@kernel.org>

From: Marc Zyngier <maz at kernel.org>

It is a bit awkward to use kern_hyp_va() in __load_guest_stage2(),
specially as the helper is shared between VHE and nVHE.

Instead, move the use of kern_hyp_va() in the nVHE code, and
pass a pointer to the kvm->arch structure instead. Although
this may look a bit awkward, it allows for some further simplification.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Jade Alglave <jade.alglave at arm.com>
Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/kvm_mmu.h | 5 +++--
 arch/arm64/kvm/hyp/nvhe/switch.c | 4 +++-
 arch/arm64/kvm/hyp/nvhe/tlb.c    | 2 +-
 arch/arm64/kvm/hyp/vhe/switch.c  | 2 +-
 arch/arm64/kvm/hyp/vhe/tlb.c     | 2 +-
 5 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index b52c5c4b9a3d..05e089653a1a 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -280,9 +280,10 @@ static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long
 	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
 }
 
-static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu)
+static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
+						struct kvm_arch *arch)
 {
-	__load_stage2(mmu, kern_hyp_va(mmu->arch)->vtcr);
+	__load_stage2(mmu, arch->vtcr);
 }
 
 static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu)
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index f7af9688c1f7..e50a49082923 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -170,6 +170,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *host_ctxt;
 	struct kvm_cpu_context *guest_ctxt;
+	struct kvm_s2_mmu *mmu;
 	bool pmu_switch_needed;
 	u64 exit_code;
 
@@ -213,7 +214,8 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 	__sysreg32_restore_state(vcpu);
 	__sysreg_restore_state_nvhe(guest_ctxt);
 
-	__load_guest_stage2(kern_hyp_va(vcpu->arch.hw_mmu));
+	mmu = kern_hyp_va(vcpu->arch.hw_mmu);
+	__load_guest_stage2(mmu, kern_hyp_va(mmu->arch));
 	__activate_traps(vcpu);
 
 	__hyp_vgic_restore_state(vcpu);
diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c
index 38ed0f6f2703..76229407d8f0 100644
--- a/arch/arm64/kvm/hyp/nvhe/tlb.c
+++ b/arch/arm64/kvm/hyp/nvhe/tlb.c
@@ -39,7 +39,7 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
 	 * ensuring that we always have an ISB, but not two ISBs back
 	 * to back.
 	 */
-	__load_guest_stage2(mmu);
+	__load_guest_stage2(mmu, kern_hyp_va(mmu->arch));
 	asm(ALTERNATIVE("isb", "nop", ARM64_WORKAROUND_SPECULATIVE_AT));
 }
 
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index b3229924d243..0cb7523a501a 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -128,7 +128,7 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
 	 * __load_guest_stage2 configures stage 2 translation, and
 	 * __activate_traps clear HCR_EL2.TGE (among other things).
 	 */
-	__load_guest_stage2(vcpu->arch.hw_mmu);
+	__load_guest_stage2(vcpu->arch.hw_mmu, vcpu->arch.hw_mmu->arch);
 	__activate_traps(vcpu);
 
 	__kvm_adjust_pc(vcpu);
diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
index 66f17349f0c3..5e9fb3989e0b 100644
--- a/arch/arm64/kvm/hyp/vhe/tlb.c
+++ b/arch/arm64/kvm/hyp/vhe/tlb.c
@@ -53,7 +53,7 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu,
 	 * place before clearing TGE. __load_guest_stage2() already
 	 * has an ISB in order to deal with this.
 	 */
-	__load_guest_stage2(mmu);
+	__load_guest_stage2(mmu, mmu->arch);
 	val = read_sysreg(hcr_el2);
 	val &= ~HCR_TGE;
 	write_sysreg(val, hcr_el2);
-- 
2.32.0.605.g8dce9f2422-goog



From will at kernel.org  Fri Aug  6 04:31:07 2021
From: will at kernel.org (Will Deacon)
Date: Fri,  6 Aug 2021 12:31:07 +0100
Subject: [PATCH 3/4] KVM: arm64: Convert the host S2 over to
 __load_guest_stage2()
In-Reply-To: <20210806113109.2475-1-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
Message-ID: <20210806113109.2475-5-will@kernel.org>

From: Marc Zyngier <maz at kernel.org>

The protected mode relies on a separate helper to load the
S2 context. Move over to the __load_guest_stage2() helper
instead.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Jade Alglave <jade.alglave at arm.com>
Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/kvm_mmu.h              | 11 +++--------
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         |  2 +-
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 05e089653a1a..934ef0deff9f 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -267,9 +267,10 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
  * Must be called from hyp code running at EL2 with an updated VTTBR
  * and interrupts disabled.
  */
-static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long vtcr)
+static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
+						struct kvm_arch *arch)
 {
-	write_sysreg(vtcr, vtcr_el2);
+	write_sysreg(arch->vtcr, vtcr_el2);
 	write_sysreg(kvm_get_vttbr(mmu), vttbr_el2);
 
 	/*
@@ -280,12 +281,6 @@ static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long
 	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
 }
 
-static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
-						struct kvm_arch *arch)
-{
-	__load_stage2(mmu, arch->vtcr);
-}
-
 static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu)
 {
 	return container_of(mmu->arch, struct kvm, arch);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 9c227d87c36d..a910648bc71b 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -29,7 +29,7 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
 static __always_inline void __load_host_stage2(void)
 {
 	if (static_branch_likely(&kvm_protected_mode_initialized))
-		__load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr);
+		__load_guest_stage2(&host_kvm.arch.mmu, &host_kvm.arch);
 	else
 		write_sysreg(0, vttbr_el2);
 }
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index d938ce95d3bd..d4e74ca7f876 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -126,7 +126,7 @@ int __pkvm_prot_finalize(void)
 	kvm_flush_dcache_to_poc(params, sizeof(*params));
 
 	write_sysreg(params->hcr_el2, hcr_el2);
-	__load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr);
+	__load_guest_stage2(&host_kvm.arch.mmu, &host_kvm.arch);
 
 	/*
 	 * Make sure to have an ISB before the TLB maintenance below but only
-- 
2.32.0.605.g8dce9f2422-goog



From will at kernel.org  Fri Aug  6 04:31:08 2021
From: will at kernel.org (Will Deacon)
Date: Fri,  6 Aug 2021 12:31:08 +0100
Subject: [PATCH 4/4] KVM: arm64: Upgrade VMID accesses to {READ,WRITE}_ONCE
In-Reply-To: <20210806113109.2475-1-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
Message-ID: <20210806113109.2475-6-will@kernel.org>

From: Marc Zyngier <maz at kernel.org>

Since TLB invalidation can run in parallel with VMID allocation,
we need to be careful and avoid any sort of load/store tearing.
Use {READ,WRITE}_ONCE consistently to avoid any surprise.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Jade Alglave <jade.alglave at arm.com>
Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/kvm_mmu.h      | 7 ++++++-
 arch/arm64/kvm/arm.c                  | 2 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c | 4 ++--
 arch/arm64/kvm/mmu.c                  | 2 +-
 4 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 934ef0deff9f..5828dd8fa738 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -252,6 +252,11 @@ static inline int kvm_write_guest_lock(struct kvm *kvm, gpa_t gpa,
 
 #define kvm_phys_to_vttbr(addr)		phys_to_ttbr(addr)
 
+/*
+ * When this is (directly or indirectly) used on the TLB invalidation
+ * path, we rely on a previously issued DSB so that page table updates
+ * and VMID reads are correctly ordered.
+ */
 static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
 {
 	struct kvm_vmid *vmid = &mmu->vmid;
@@ -259,7 +264,7 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
 	u64 cnp = system_supports_cnp() ? VTTBR_CNP_BIT : 0;
 
 	baddr = mmu->pgd_phys;
-	vmid_field = (u64)vmid->vmid << VTTBR_VMID_SHIFT;
+	vmid_field = (u64)READ_ONCE(vmid->vmid) << VTTBR_VMID_SHIFT;
 	return kvm_phys_to_vttbr(baddr) | vmid_field | cnp;
 }
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..658f76067f46 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -571,7 +571,7 @@ static void update_vmid(struct kvm_vmid *vmid)
 		kvm_call_hyp(__kvm_flush_vm_context);
 	}
 
-	vmid->vmid = kvm_next_vmid;
+	WRITE_ONCE(vmid->vmid, kvm_next_vmid);
 	kvm_next_vmid++;
 	kvm_next_vmid &= (1 << kvm_get_vmid_bits()) - 1;
 
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index d4e74ca7f876..55ae97a144b8 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -109,8 +109,8 @@ int kvm_host_prepare_stage2(void *pgt_pool_base)
 	mmu->pgd_phys = __hyp_pa(host_kvm.pgt.pgd);
 	mmu->arch = &host_kvm.arch;
 	mmu->pgt = &host_kvm.pgt;
-	mmu->vmid.vmid_gen = 0;
-	mmu->vmid.vmid = 0;
+	WRITE_ONCE(mmu->vmid.vmid_gen, 0);
+	WRITE_ONCE(mmu->vmid.vmid, 0);
 
 	return 0;
 }
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 3155c9e778f0..b1a6eaec28ff 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -485,7 +485,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
 	mmu->arch = &kvm->arch;
 	mmu->pgt = pgt;
 	mmu->pgd_phys = __pa(pgt->pgd);
-	mmu->vmid.vmid_gen = 0;
+	WRITE_ONCE(mmu->vmid.vmid_gen, 0);
 	return 0;
 
 out_destroy_pgtable:
-- 
2.32.0.605.g8dce9f2422-goog



From claudiu.beznea at microchip.com  Fri Aug  6 04:29:57 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 6 Aug 2021 14:29:57 +0300
Subject: [PATCH 0/4] mmc: pwrseq: sd8787: add support for selectable
Message-ID: <20210806113001.821660-1-claudiu.beznea@microchip.com>

Hi,

This series adds support for selecting the delay b/w reset and power
lines on pwrseq-sd8787. With this the driver could also be used by
other devices (e.g. WILC1000/WILC3000 which needs a delay of 5ms). Along
with this added the DT bindings for WILC3000 device present on
SAMA5D27 WLSOM1 board.

Thank you,
Claudiu Beznea

Claudiu Beznea (3):
  dt-bindings: mmc: pwrseq-sd8787: add binding for delay b/w reset and
    power
  mmc: pwrseq: sd8787: add support for specifying the delay b/w power
    and reset
  mmc: pwrseq: add wilc1000_sdio dependency for pwrseq_sd8787

Eugen Hristev (1):
  ARM: dts: at91: sama5d27_wlsom1: add wifi device

 .../bindings/mmc/mmc-pwrseq-sd8787.yaml       |  4 ++
 arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi   | 72 +++++++++++++++++++
 drivers/mmc/core/Kconfig                      |  2 +-
 drivers/mmc/core/pwrseq_sd8787.c              | 11 ++-
 4 files changed, 87 insertions(+), 2 deletions(-)

-- 
2.25.1



From claudiu.beznea at microchip.com  Fri Aug  6 04:29:58 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 6 Aug 2021 14:29:58 +0300
Subject: [PATCH 1/4] dt-bindings: mmc: pwrseq-sd8787: add binding for delay
 b/w reset and power
In-Reply-To: <20210806113001.821660-1-claudiu.beznea@microchip.com>
References: <20210806113001.821660-1-claudiu.beznea@microchip.com>
Message-ID: <20210806113001.821660-2-claudiu.beznea@microchip.com>

Add documentation for binding that specifies the delay that should
be introduced b/w reset and power lines when powering up the device.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
index e0169a285aa2..4b1e89750e94 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
@@ -23,6 +23,10 @@ properties:
     description:
       contains a reset GPIO specifier with the default active state
 
+  reset-power-delay-ms:
+    description:
+      Delay in ms between powerdown and reset gpios
+
 required:
   - compatible
   - powerdown-gpios
-- 
2.25.1



From claudiu.beznea at microchip.com  Fri Aug  6 04:29:59 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 6 Aug 2021 14:29:59 +0300
Subject: [PATCH 2/4] mmc: pwrseq: sd8787: add support for specifying the delay
 b/w power and reset
In-Reply-To: <20210806113001.821660-1-claudiu.beznea@microchip.com>
References: <20210806113001.821660-1-claudiu.beznea@microchip.com>
Message-ID: <20210806113001.821660-3-claudiu.beznea@microchip.com>

Add support to be able to specify the delay to be introduced b/w
power and reset lines on power up sequence. With this, the driver
could also be used by other WiFi chips (e.g. WILC1000/WILC3000
devices that need a delay of 5ms b/w power and reset line for
a proper powering up sequence).

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 drivers/mmc/core/pwrseq_sd8787.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
index 68a826f1c0a1..a554eefdf1b1 100644
--- a/drivers/mmc/core/pwrseq_sd8787.c
+++ b/drivers/mmc/core/pwrseq_sd8787.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -27,6 +28,7 @@ struct mmc_pwrseq_sd8787 {
 	struct mmc_pwrseq pwrseq;
 	struct gpio_desc *reset_gpio;
 	struct gpio_desc *pwrdn_gpio;
+	u32 reset_pwrdwn_delay_ms;
 };
 
 #define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
@@ -37,7 +39,7 @@ static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
 
 	gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
 
-	msleep(300);
+	msleep(pwrseq->reset_pwrdwn_delay_ms);
 	gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
 }
 
@@ -64,6 +66,7 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
 {
 	struct mmc_pwrseq_sd8787 *pwrseq;
 	struct device *dev = &pdev->dev;
+	int ret;
 
 	pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
 	if (!pwrseq)
@@ -77,6 +80,12 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
 	if (IS_ERR(pwrseq->reset_gpio))
 		return PTR_ERR(pwrseq->reset_gpio);
 
+	ret = device_property_read_u32(dev, "reset-power-delay-ms",
+				       &pwrseq->reset_pwrdwn_delay_ms);
+	/* Keep compatibility with old devices. */
+	if (ret)
+		pwrseq->reset_pwrdwn_delay_ms = 300;
+
 	pwrseq->pwrseq.dev = dev;
 	pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
 	pwrseq->pwrseq.owner = THIS_MODULE;
-- 
2.25.1



From claudiu.beznea at microchip.com  Fri Aug  6 04:30:00 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 6 Aug 2021 14:30:00 +0300
Subject: [PATCH 3/4] mmc: pwrseq: add wilc1000_sdio dependency for
 pwrseq_sd8787
In-Reply-To: <20210806113001.821660-1-claudiu.beznea@microchip.com>
References: <20210806113001.821660-1-claudiu.beznea@microchip.com>
Message-ID: <20210806113001.821660-4-claudiu.beznea@microchip.com>

pwseq_sd8787 could also be used with wilc1000_sdio driver. Add
a dependency for this.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 drivers/mmc/core/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index ae8b69aee619..6f25c34e4fec 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -15,7 +15,7 @@ config PWRSEQ_EMMC
 
 config PWRSEQ_SD8787
 	tristate "HW reset support for SD8787 BT + Wifi module"
-	depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO)
+	depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO || WILC1000_SDIO)
 	help
 	  This selects hardware reset support for the SD8787 BT + Wifi
 	  module. By default this option is set to n.
-- 
2.25.1



From claudiu.beznea at microchip.com  Fri Aug  6 04:30:01 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 6 Aug 2021 14:30:01 +0300
Subject: [PATCH 4/4] ARM: dts: at91: sama5d27_wlsom1: add wifi device
In-Reply-To: <20210806113001.821660-1-claudiu.beznea@microchip.com>
References: <20210806113001.821660-1-claudiu.beznea@microchip.com>
Message-ID: <20210806113001.821660-5-claudiu.beznea@microchip.com>

From: Eugen Hristev <eugen.hristev at microchip.com>

SAMA5D27 WLSOM1 boards has a WILC3000 device soldered. Add proper
device tree nodes for this.

[eugen.hristev: original author of this code]
Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
[nicolas.ferre: original author of this code]
Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
[claudiu.beznea: adapt for mmc-pwrseq-sd8787, commit message]
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi | 72 +++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
index 025a78310e3a..de8bb3439aef 100644
--- a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
+++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
@@ -30,6 +30,16 @@ main_xtal {
 			clock-frequency = <24000000>;
 		};
 	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-sd8787";
+		reset-gpios = <&pioA PIN_PA27 GPIO_ACTIVE_HIGH>;
+		powerdown-gpios = <&pioA PIN_PA29 GPIO_ACTIVE_HIGH>;
+		reset-power-delay-ms = <5>;
+		pinctrl-0 = <&pinctrl_wilc_pwrseq>;
+		pinctrl-names = "default";
+		status = "okay";
+	};
 };
 
 &flx1 {
@@ -310,5 +320,67 @@ pinctrl_qspi1_default: qspi1_default {
 			 <PIN_PB10__QSPI1_IO3>;
 		bias-pull-up;
 	};
+
+	pinctrl_sdmmc1_default: sdmmc1_default {
+		cmd-data {
+			pinmux = <PIN_PA28__SDMMC1_CMD>,
+				 <PIN_PA18__SDMMC1_DAT0>,
+				 <PIN_PA19__SDMMC1_DAT1>,
+				 <PIN_PA20__SDMMC1_DAT2>,
+				 <PIN_PA21__SDMMC1_DAT3>;
+			bias-disable;
+		};
+
+		conf-ck {
+			pinmux = <PIN_PA22__SDMMC1_CK>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_wilc_default: wilc_default {
+		conf-irq {
+			pinmux = <PIN_PB25__GPIO>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_wilc_pwrseq: wilc_pwrseq {
+		conf-ce-nrst {
+			pinmux = <PIN_PA27__GPIO>,
+				 <PIN_PA29__GPIO>;
+			bias-disable;
+		};
+
+		conf-rtcclk {
+			pinmux = <PIN_PB13__PCK1>;
+			bias-disable;
+		};
+	};
+};
+
+&sdmmc1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	no-1-8-v;
+	non-removable;
+	status = "okay";
+
+	wilc: wilc at 0 {
+		reg = <0>;
+		bus-width = <4>;
+		compatible = "microchip,wilc3000", "microchip,wilc1000";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_wilc_default>;
+		irq-gpios = <&pioA PIN_PB25 GPIO_ACTIVE_LOW>;
+		clocks = <&pmc PMC_TYPE_SYSTEM 9>;
+		clock-names = "rtc";
+		assigned-clocks = <&pmc PMC_TYPE_SYSTEM 9>;
+		assigned-clock-rates = <32768>;
+		status = "okay";
+	};
 };
 
-- 
2.25.1



From will at kernel.org  Fri Aug  6 04:34:14 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 6 Aug 2021 12:34:14 +0100
Subject: [PATCH] of: restricted dma: Don't fail device probe on rmem init
 failure
In-Reply-To: <20210806113109.2475-3-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
 <20210806113109.2475-3-will@kernel.org>
Message-ID: <20210806113414.GA2531@willie-the-truck>

On Fri, Aug 06, 2021 at 12:31:05PM +0100, Will Deacon wrote:
> If CONFIG_DMA_RESTRICTED_POOL=n then probing a device with a reference
> to a "restricted-dma-pool" will fail with a reasonably cryptic error:
> 
>   | pci-host-generic: probe of 10000.pci failed with error -22
> 
> Print a more helpful message in this case and try to continue probing
> the device as we do if the kernel doesn't have the restricted DMA patches
> applied or either CONFIG_OF_ADDRESS or CONFIG_HAS_DMA =n.
> 
> Cc: Claire Chang <tientzu at chromium.org>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: Robin Murphy <robin.murphy at arm.com>
> Cc: Christoph Hellwig <hch at lst.de>
> Cc: Rob Herring <robh+dt at kernel.org>
> Signed-off-by: Will Deacon <will at kernel.org>
> ---
>  drivers/of/address.c    | 8 ++++----
>  drivers/of/device.c     | 2 +-
>  drivers/of/of_private.h | 8 +++-----
>  3 files changed, 8 insertions(+), 10 deletions(-)

Sorry, didn't mean to send this patch a second time, it was still kicking
around in my tree from yesterday and I accidentally picked it up when
sending my TLBI series.

Please ignore.

Will


From stefan.wahren at i2se.com  Fri Aug  6 04:40:04 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Fri, 6 Aug 2021 13:40:04 +0200
Subject: [PATCH 0/3] CM4 ACPI PCIe quirk
In-Reply-To: <20210805211200.491275-1-jeremy.linton@arm.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
Message-ID: <1e7d639e-112b-892c-4279-23af82ea004e@i2se.com>

Hi Jeremy,

Am 05.08.21 um 23:11 schrieb Jeremy Linton:
> The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
> standard because its PCIe config space isn't ECAM compliant and is
> split into two parts. One part for the root port registers and a
> moveable window which points at a given device's 4K config space.
> Thus it doesn't have a MCFG (and really any MCFG provided would be
> nonsense anyway). As linux doesn't support the PCIe SMCCC standard
> we key off a linux specific host bridge _DSD to add custom ECAM
> ops and cfgres. The cfg op selects between those two regions, as
> well as disallowing problematic accesses, particularly if the link
> is down because there isn't an attached device.

i just want to inform you, that i recently submitted the inital patch
series for DT support regarding CM4 [1].

I left out anything related to PCIe (including downstream changes to
pcie-brcmstb).

Best regards
Stefan

[1] - https://marc.info/?l=linux-arm-kernel&m=162782110325813&w=2




From lee.jones at linaro.org  Fri Aug  6 04:41:38 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 6 Aug 2021 12:41:38 +0100
Subject: [PATCH v2 1/1] mfd: simple-mfd-i2c: Add support for registering
 devices via MFD cells
In-Reply-To: <CAKmqyKMPg8kikB7Ym6qc+VYAwt0DvyXK+xqu3SwgJwcaCyUrbA@mail.gmail.com>
References: <20210805085611.864188-1-lee.jones@linaro.org>
 <CAKmqyKMPg8kikB7Ym6qc+VYAwt0DvyXK+xqu3SwgJwcaCyUrbA@mail.gmail.com>
Message-ID: <YQ0f8hJSuLqR3SGQ@google.com>

On Fri, 06 Aug 2021, Alistair Francis wrote:

> On Thu, Aug 5, 2021 at 6:56 PM Lee Jones <lee.jones at linaro.org> wrote:
> >
> > More devices are cropping up requiring only Regmap initialisation and
> > child registration functionality.  We currently only support that if
> > all required devices are represented by their own Device Tree nodes
> > complete with compatible strings.
> >
> > However, not everyone is happy with adding empty nodes that provide no
> > additional device information into the Device Tree.
> >
> > Rather than have a plethora of mostly empty, function-less drivers in
> > MFD, we'll support those simple cases in here instead via MFD cells.
> >
> > Cc: Michael Walle <michael at walle.cc>
> > Cc: Mark Brown <broonie at kernel.org>
> > Cc: Alistair Francis <alistair23 at gmail.com>
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> > ---
> > v2:
> >  - Check for empty of_device_id .data entry
> >
> >  drivers/mfd/simple-mfd-i2c.c | 41 +++++++++++++++++++++++++++++-------
> >  drivers/mfd/simple-mfd-i2c.h | 32 ++++++++++++++++++++++++++++
> >  2 files changed, 65 insertions(+), 8 deletions(-)
> >  create mode 100644 drivers/mfd/simple-mfd-i2c.h
> >
> > diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
> > index 87f684cff9a17..583e8c7924af0 100644
> > --- a/drivers/mfd/simple-mfd-i2c.c
> > +++ b/drivers/mfd/simple-mfd-i2c.c
> > @@ -2,39 +2,64 @@
> >  /*
> >   * Simple MFD - I2C
> >   *
> > + * Author(s):
> > + *     Michael Walle <michael at walle.cc>
> > + *     Lee Jones <lee.jones at linaro.org>
> > + *
> >   * This driver creates a single register map with the intention for it to be
> >   * shared by all sub-devices.  Children can use their parent's device structure
> >   * (dev.parent) in order to reference it.
> >   *
> >   * Once the register map has been successfully initialised, any sub-devices
> > - * represented by child nodes in Device Tree will be subsequently registered.
> > + * represented by child nodes in Device Tree or via the MFD cells in this file
> > + * will be subsequently registered.
> >   */
> >
> >  #include <linux/i2c.h>
> >  #include <linux/kernel.h>
> > +#include <linux/mfd/core.h>
> >  #include <linux/module.h>
> >  #include <linux/of_platform.h>
> >  #include <linux/regmap.h>
> >
> > -static const struct regmap_config simple_regmap_config = {
> > +#include "simple-mfd-i2c.h"
> > +
> > +static const struct regmap_config regmap_config_8r_8v = {
> >         .reg_bits = 8,
> >         .val_bits = 8,
> >  };
> >
> >  static int simple_mfd_i2c_probe(struct i2c_client *i2c)
> >  {
> > -       const struct regmap_config *config;
> > +       const struct simple_mfd_data *simple_mfd_data;
> > +       const struct regmap_config *regmap_config;
> >         struct regmap *regmap;
> > +       int ret;
> > +
> > +       simple_mfd_data = device_get_match_data(&i2c->dev);
> >
> > -       config = device_get_match_data(&i2c->dev);
> > -       if (!config)
> > -               config = &simple_regmap_config;
> > +       /* If no regmap_config is specified, use the default 8reg and 8val bits */
> > +       if (!simple_mfd_data || !simple_mfd_data->regmap_config)
> > +               regmap_config = &regmap_config_8r_8v;
> > +       else
> > +               regmap_config = simple_mfd_data->regmap_config;
> >
> > -       regmap = devm_regmap_init_i2c(i2c, config);
> > +       regmap = devm_regmap_init_i2c(i2c, regmap_config);
> >         if (IS_ERR(regmap))
> >                 return PTR_ERR(regmap);
> >
> > -       return devm_of_platform_populate(&i2c->dev);
> > +       /* If no MFD cells are spedified, use register the DT child nodes instead */
> > +       if (!simple_mfd_data || !simple_mfd_data->mfd_cell)
> > +               return devm_of_platform_populate(&i2c->dev);
> > +
> > +       ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
> > +                                  simple_mfd_data->mfd_cell,
> > +                                  simple_mfd_data->mfd_cell_size,
> > +                                  NULL, 0, NULL);
> > +       if (!ret)
> 
> Shouldn't this be `if (ret)` instead?
> 
> With that changed this works for me as well:

You're right.  Will fix.

> Reviewed-by: Alistair Francis <alistair at alistair23.me>
> Tested-by: Alistair Francis <alistair at alistair23.me>

Thanks.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From icenowy at aosc.io  Fri Aug  6 04:48:33 2021
From: icenowy at aosc.io (Icenowy Zheng)
Date: Fri, 06 Aug 2021 19:48:33 +0800
Subject: [linux-sunxi] Re: [PATCH 52/54] arm64: dts: allwinner: Remove
 regulator-ramp-delay
In-Reply-To: <20210722081616.arxwrn5krbaocymf@gilmour>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-53-maxime@cerno.tech>
 <5469a059-dad1-38d2-9ea4-f1b5fa9ac616@sholland.org>
 <20210722081616.arxwrn5krbaocymf@gilmour>
Message-ID: <68e4820ead3107aa4e80dcaf9243bd11de5fce98.camel@aosc.io>

? 2021-07-22???? 10:16 +0200?Maxime Ripard???
> On Thu, Jul 22, 2021 at 12:55:53AM -0500, Samuel Holland wrote:
> > On 7/21/21 9:04 AM, Maxime Ripard wrote:
> > > The regulator-ramp-delay property isn't documented in the binding
> > > for
> > > the AXP806, and it's ignored by the driver. Remove those
> > > properties.
> > 
> > This is a generic regulator property, parsed by
> > of_get_regulation_constraints, which is called by
> > regulator_of_get_init_data in the regulator core. And it appears in
> > bindings/regulator/regulator.yaml. I believe the binding needs to be
> > fixed, not the device trees.
> 
> It's indeed parsed by the regulator framework, but then it calls into
> the driver if that property is set using set_ramp_delay if it's set.

Not only is it used for set_ramp_delay, but it's also used to calculate
a post-change delay, see the following position (it can be overrided by
a custom set_voltage_time in the driver):

https://elixir.bootlin.com/linux/latest/source/drivers/regulator/core.c#L3339

> 
> https://elixir.bootlin.com/linux/latest/source/drivers/regulator/core.c#L1378
> 
> We don't set that hook for the AXP806 DCDC-A and DCDC-E regulators
> (that
> use AXP_DESC_RANGES) at all:
> 
> https://elixir.bootlin.com/linux/latest/source/drivers/regulator/axp20x-regulator.c#L343
> 
> And the only implementation we have (set for AXP_DESC and AXP_DESC_IO)
> works only for the AXP209:
> 
> https://elixir.bootlin.com/linux/latest/source/drivers/regulator/axp20x-regulator.c#L368
> 
> So, it just looks like those properties have never been tested since
> they were just ignored.
> 
> Maxime
> 



From leo.yan at linaro.org  Fri Aug  6 04:52:00 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Fri, 6 Aug 2021 19:52:00 +0800
Subject: [PATCH 6/6] perf cs-etm: Print the decoder name
In-Reply-To: <077ebe58-f692-9adb-9cb5-ed35a9b508c1@arm.com>
References: <20210721090706.21523-1-james.clark@arm.com>
 <20210721090706.21523-7-james.clark@arm.com>
 <20210731073037.GF7437@leoy-ThinkPad-X240s>
 <077ebe58-f692-9adb-9cb5-ed35a9b508c1@arm.com>
Message-ID: <20210806115200.GD68808@leoy-ThinkPad-X240s>

On Fri, Aug 06, 2021 at 10:43:25AM +0100, James Clark wrote:
> On 31/07/2021 08:30, Leo Yan wrote:
> >> @@ -658,7 +658,7 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
> >>  
> >>  		return 0;
> >>  	} else if (d_params->operation == CS_ETM_OPERATION_PRINT) {
> >> -		if (ocsd_dt_create_decoder(decoder->dcd_tree, decoder_name,
> >> +		if (ocsd_dt_create_decoder(decoder->dcd_tree, decoder->decoder_name,
> >>  					   OCSD_CREATE_FLG_PACKET_PROC,
> >>  					   trace_config, &csid))
> >>  			return -1;
> >> @@ -790,3 +790,8 @@ void cs_etm_decoder__free(struct cs_etm_decoder *decoder)
> >>  	decoder->dcd_tree = NULL;
> >>  	free(decoder);
> >>  }
> >> +
> >> +const char *cs_etm_decoder__get_name(struct cs_etm_decoder *decoder)
> >> +{
> >> +	return decoder->decoder_name;
> >> +}
> > Maybe can consider to place this function into the header file with
> > "static inline" specifier.
> 
> I tried this, but because the struct is defined in the .c file it can't
> be done without moving the struct to the header. It's also only used
> for the --dump-raw-trace path so performance isn't critical anyway.

It's fine to keep current patch, and thanks for trying.


From catalin.marinas at arm.com  Fri Aug  6 04:59:28 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 6 Aug 2021 12:59:28 +0100
Subject: [PATCH 1/4] arm64: mm: Fix TLBI vs ASID rollover
In-Reply-To: <20210806113109.2475-2-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
 <20210806113109.2475-2-will@kernel.org>
Message-ID: <20210806115927.GJ6719@arm.com>

On Fri, Aug 06, 2021 at 12:31:04PM +0100, Will Deacon wrote:
> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> index 75beffe2ee8a..e9c30859f80c 100644
> --- a/arch/arm64/include/asm/mmu.h
> +++ b/arch/arm64/include/asm/mmu.h
> @@ -27,11 +27,32 @@ typedef struct {
>  } mm_context_t;
>  
>  /*
> - * This macro is only used by the TLBI and low-level switch_mm() code,
> - * neither of which can race with an ASID change. We therefore don't
> - * need to reload the counter using atomic64_read().
> + * We use atomic64_read() here because the ASID for an 'mm_struct' can
> + * be reallocated when scheduling one of its threads following a
> + * rollover event (see new_context() and flush_context()). In this case,
> + * a concurrent TLBI (e.g. via try_to_unmap_one() and ptep_clear_flush())
> + * may use a stale ASID. This is fine in principle as the new ASID is
> + * guaranteed to be clean in the TLB, but the TLBI routines have to take
> + * care to handle the following race:
> + *
> + *    CPU 0                    CPU 1                          CPU 2
> + *
> + *    // ptep_clear_flush(mm)
> + *    xchg_relaxed(pte, 0)
> + *    DSB ISHST
> + *    old = ASID(mm)

We'd need specs clarified (ARM ARM, cat model) that the DSB ISHST is
sufficient to order the pte write with the subsequent ASID read.
Otherwise the patch looks fine to me:

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From vkoul at kernel.org  Fri Aug  6 04:59:55 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 17:29:55 +0530
Subject: [PATCH v4 1/3] dt-bindings: phy: mediatek: tphy: add support
 hardware version 3
In-Reply-To: <1627028562-23584-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1627028562-23584-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YQ0kO7ZWO3y0Xmne@matsya>

On 23-07-21, 16:22, Chunfeng Yun wrote:
> The PHYA architecture is updated, and doesn't support slew rate
> calibration anymore on 7nm or advanced process, add a new version
> number to support it.
> Due to the FreqMeter bank is not used but reserved, it's backward
> with v2 until now.
> For mt8195, no function changes when use generic v2 or v3 compatible,
> but prefer to use v3's compatible, it will not waste the time to
> calibrate the slew rate, and also correspond with hardware version.

Applied all, thanks

-- 
~Vinod


From wens at csie.org  Fri Aug  6 05:05:56 2021
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 6 Aug 2021 20:05:56 +0800
Subject: [linux-sunxi] Re: [PATCH 52/54] arm64: dts: allwinner: Remove
 regulator-ramp-delay
In-Reply-To: <68e4820ead3107aa4e80dcaf9243bd11de5fce98.camel@aosc.io>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-53-maxime@cerno.tech>
 <5469a059-dad1-38d2-9ea4-f1b5fa9ac616@sholland.org>
 <20210722081616.arxwrn5krbaocymf@gilmour>
 <68e4820ead3107aa4e80dcaf9243bd11de5fce98.camel@aosc.io>
Message-ID: <CAGb2v65dAAc274JiZyTswuqGHn1tE9urJpTBv=is2CG1UT2CTA@mail.gmail.com>

On Fri, Aug 6, 2021 at 7:49 PM Icenowy Zheng <icenowy at aosc.io> wrote:
>
> ? 2021-07-22???? 10:16 +0200?Maxime Ripard???
> > On Thu, Jul 22, 2021 at 12:55:53AM -0500, Samuel Holland wrote:
> > > On 7/21/21 9:04 AM, Maxime Ripard wrote:
> > > > The regulator-ramp-delay property isn't documented in the binding
> > > > for
> > > > the AXP806, and it's ignored by the driver. Remove those
> > > > properties.
> > >
> > > This is a generic regulator property, parsed by
> > > of_get_regulation_constraints, which is called by
> > > regulator_of_get_init_data in the regulator core. And it appears in
> > > bindings/regulator/regulator.yaml. I believe the binding needs to be
> > > fixed, not the device trees.
> >
> > It's indeed parsed by the regulator framework, but then it calls into
> > the driver if that property is set using set_ramp_delay if it's set.
>
> Not only is it used for set_ramp_delay, but it's also used to calculate
> a post-change delay, see the following position (it can be overrided by
> a custom set_voltage_time in the driver):
>
> https://elixir.bootlin.com/linux/latest/source/drivers/regulator/core.c#L3339

Having just dug through the regulator core code at work, I agree.

Furthermore, the commit log for this addition specifically mentions the
reason for adding this property is to provide a (guessed) ramp rate for
the core to do a proper delay for the regulator to ramp up, not to set
the actual ramp rate in hardware.


ChenYu


[1] https://git.kernel.org/torvalds/c/fe79ea577be81e1e71642826ab00e676dc59c194

> >
> > https://elixir.bootlin.com/linux/latest/source/drivers/regulator/core.c#L1378
> >
> > We don't set that hook for the AXP806 DCDC-A and DCDC-E regulators
> > (that
> > use AXP_DESC_RANGES) at all:
> >
> > https://elixir.bootlin.com/linux/latest/source/drivers/regulator/axp20x-regulator.c#L343
> >
> > And the only implementation we have (set for AXP_DESC and AXP_DESC_IO)
> > works only for the AXP209:
> >
> > https://elixir.bootlin.com/linux/latest/source/drivers/regulator/axp20x-regulator.c#L368
> >
> > So, it just looks like those properties have never been tested since
> > they were just ignored.
> >
> > Maxime
> >
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/68e4820ead3107aa4e80dcaf9243bd11de5fce98.camel%40aosc.io.


From semen.protsenko at linaro.org  Fri Aug  6 05:07:05 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 6 Aug 2021 15:07:05 +0300
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <68734f6c-fc76-595c-8d34-8924dbbbb845@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <455cfb5e-dff7-a5c0-3875-49abe3e900f3@canonical.com>
 <CAPLW+4nDS0atrbUFagDA0W_Ky5MvOiY+N+NQoQ+me4pndp_iWg@mail.gmail.com>
 <68734f6c-fc76-595c-8d34-8924dbbbb845@canonical.com>
Message-ID: <CAPLW+4n_JKj5xeBHXONcv__vyAFvx3fhXoxJa17NTHK1RSJFJw@mail.gmail.com>

On Fri, 6 Aug 2021 at 10:49, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 06/08/2021 01:06, Sam Protsenko wrote:
> > On Sat, 31 Jul 2021 at 12:03, Krzysztof Kozlowski
> > <krzysztof.kozlowski at canonical.com> wrote:
> >
> >>>
> >>> This patch adds minimal SoC support. Particular board device tree files
> >>> can include exynos850.dtsi file to get SoC related nodes, and then
> >>> reference those nodes further as needed.
> >>>
> >>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> >>> ---
> >>>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
> >>>  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
> >>>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
> >>
> >> Not buildable. Missing Makefile, missing DTS. Please submit with initial
> >> DTS, otherwise no one is able to verify it even compiles.
> >>
> >
> > This device is not available for purchase yet. I'll send the patch for
> > board dts once it's announced. I can do all the testing for now, if
> > you have any specific requests. Would it be possible for us to review
> > and apply only SoC support for now? Will send v2 soon...
>
> What you propose is equal to adding a driver (C source code) without
> ability to compile it. What's the point of having it in the kernel? It's
> unverifiable, unbuildable and unusable.
>

Yes, I understand. That's adding code with no users, and it's not a
good practice.

> We can review the DTSI however merging has to be with a DTS. Usually the
> SoC vendor adds first an evalkit (e.g. SMDK board). Maybe you have one
> for Exynos850? Otherwise if you cannot disclose the actual board, the
> DTSI will have to wait. You can submit drivers, though.
>

Sure, let's go this way. I'll send v2 soon. Improving patches and
having Reviewed-by tag for those would good enough for me at this
point. I'll continue to prepare another Exynos850 related patches
until the actual board is announced, like proper clock driver, reset,
MMC, etc. Is it ok if I send those for a review too (so I can fix all
issues ahead)? And should I maybe add RFC tag for those?

Anyway, once the board is out, I'll re-send this series including
board's dts, as you suggested. Good thing is, I'll have some time to
address any outstanding issues by that time, hopefully.

Thanks!

> >
> >>>  3 files changed, 1057 insertions(+)
> >>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
> >>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
> >>>
> >>> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >>> new file mode 100644
> >>> index 000000000000..4cf0a22cc6db
> >>> --- /dev/null
> >>> +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >>> @@ -0,0 +1,782 @@
> >>> +// SPDX-License-Identifier: GPL-2.0
> >>> +/*
> >>> + * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
> >>> + *
> >>> + * Copyright (C) 2017 Samsung Electronics Co., Ltd.
> >>> + * Copyright (C) 2021 Linaro Ltd.
> >>> + *
> >>> + * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
> >>> + * tree nodes in this file.
> >>> + */
> >>> +
> >>> +#include <dt-bindings/interrupt-controller/exynos850.h>
> >>> +
> >>> +/ {
> >>> +     /* ALIVE */
> >>> +     pinctrl at 11850000 {
> >>> +             gpa0: gpa0 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>
> >> That's odd a little, why three cells? How this would be used/referenced?
> >>
> >
> > Fixed. You are right, irq_domain_xlate_twocell() is used in
> > pinctrl-exynos.c. Btw, that fixed the use-case when gpX is specified
> > as interrupt-parrent for other nodes.
> >
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT0 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT1 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT2 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT3 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT4 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT5 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT6 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT7 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpa1: gpa1 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT8 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT9 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT10 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT11 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT12 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT13 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT14 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT15 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpa2: gpa2 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT16 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT17 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT18 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT19 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT20 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT21 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT22 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT23 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpa3: gpa3 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT24 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT25 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT26 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT27 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT28 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT29 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT30 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT31 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpa4: gpa4 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT32 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT33 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT34 IRQ_TYPE_LEVEL_HIGH>,
> >>> +                         <GIC_SPI INTREQ__ALIVE_EINT35 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpq0: gpq0 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             /* USI_PERI_UART_DBG */
> >>> +             uart0_bus: uart0-bus {
> >>> +                     samsung,pins = "gpq0-0", "gpq0-1";
> >>> +                     samsung,pin-function = <2>;
> >>
> >> EXYNOS_PIN_FUNC_2
> >>
> >
> > Done, thanks.
> >
> >>> +                     samsung,pin-pud = <0>;
> >>
> >> EXYNOS_PIN_PULL_xx?
> >>
> >
> > Yes, replaced pin-pud values with these constants, thanks. Won't touch
> > pin-drv properties, though, as different domains have different
> > meanings for the same values, so don't want to introduce the whole
> > bunch of consts.
> >
> >>> +             };
> >>> +
> >>> +             decon_f_te_on: decon_f_te_on {
> >>
> >> 1. Where is it used?
> >> 2. Use hyphens in node names.
> >> Please build it with W=1 and fix the warnings.
> >>
> >
> > decon* nodes seem like leftover from vendor kernel. Those are not
> > connected anywhere on my board, so I removed those nodes.
> >
> > Also fixed node names as you suggested, and fixed all stuff found with
> > W=1 build, thanks for reminding me that.
> >
> >>> +                     samsung,pins = "gpa4-1";
> >>
> >> Order the nodes based on first pin name, so:
> >> i2c5_bus
> >> i2c6_bus
> >> decon_f_te_on
> >> uart0_bus
> >>
> >
> > Done. Also rearranged the nodes in that way for other pinctrl domains.
> >
> >>> +                     samsung,pin-function = <0xf>;
> >>> +             };
> >>> +
> >>> +             decon_f_te_off: decon_f_te_off {
> >>
> >> Where is it used?
> >>
> >
> > Removed, as explained above.
> >
> >>> +                     samsung,pins = "gpa4-1";
> >>> +                     samsung,pin-function = <0x0>;
> >>> +             };
> >>> +
> >>> +             /* I2C_5 | CAM_PMIC_I2C */
> >>
> >> This comment is confusing. I2C-5 is obvious from node name and label.
> >> CAM_PMIC_I2C does not look like property of SoC but board.
> >>
> >
> > Yeah, unfortunately this confusing I2C naming (CAM_PMIC_I2C and
> > MOTOR_I2C) actually comes from TRM and SoC schematic symbol.
>
> Schematic symbol of SoC? Interesting document... What do you have there?
> Internals of SoC?
>

Yeah, of course schematic symbol can't be considered a document :)
What I meant was it might be confusing for users to see one bus name
in TRM and schematics, and another one in device tree.

>
> > So in
> > Device Tree it's called just i2c5 and i2c6 (because it's a regular I2C
> > really), but in TRM it's a mix of both names. I guess it's just a poor
> > pin function naming, done by SoC designers.
> >
> > That said, I suggest changing these comments to something like this:
> >
> >     /* I2C5 (also called CAM_PMIC_I2C in TRM) */
> >     /* I2C6 (also called MOTOR_I2C in TRM) */
>
> OK, assuming that by TRM you mean Exynos850 TRM.
>
> >
> >>> +             i2c5_bus: i2c5-bus {
> >>> +                     samsung,pins = "gpa3-5", "gpa3-6";
> >>> +                     samsung,pin-function = <3>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             /* I2C_6 | MOTOR_I2C */
> >>> +             i2c6_bus: i2c6-bus {
> >>> +                     samsung,pins = "gpa3-7", "gpa4-0";
> >>> +                     samsung,pin-function = <3>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +     };
> >>> +
> >>> +     /* CMGP */
> >>> +     pinctrl at 11c30000 {
> >>> +             gpm0: gpm0 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM00 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpm1: gpm1 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM01 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpm2: gpm2 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM02 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpm3: gpm3 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM03 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpm4: gpm4 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM04 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             gpm5: gpm5 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <3>;
> >>> +                     interrupt-parent = <&gic>;
> >>> +                     interrupts =
> >>> +                       <GIC_SPI INTREQ__CMGP_EXT_INTM05 IRQ_TYPE_LEVEL_HIGH>;
> >>> +             };
> >>> +
> >>> +             /* usi_cmgp00 */
> >>> +             hsi2c3_bus: hsi2c3-bus {
> >>> +                     samsung,pins = "gpm0-0", "gpm1-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             /* usi_cmgp01 */
> >>> +             hsi2c4_bus: hsi2c4-bus {
> >>> +                     samsung,pins = "gpm4-0", "gpm5-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             /* spi usi_cmgp00 */
> >>> +             spi1_bus: spi1-bus {
> >>> +                     samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             spi1_cs: spi1-cs {
> >>> +                     samsung,pins = "gpm3-0";
> >>> +                     samsung,pin-function = <1>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             spi1_cs_func: spi1-cs-func {
> >>> +                     samsung,pins = "gpm3-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             /* spi usi_cmgp01 */
> >>> +             spi2_bus: spi2-bus {
> >>> +                     samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             spi2_cs: spi2-cs {
> >>> +                     samsung,pins = "gpm7-0";
> >>> +                     samsung,pin-function = <1>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             spi2_cs_func: spi2-cs-func {
> >>> +                     samsung,pins = "gpm7-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             /* usi_cmgp00_uart */
> >>> +             uart1_bus_single: uart1-bus {
> >>> +                     samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +             };
> >>> +
> >>> +             uart1_bus_dual: uart1-bus-dual {
> >>> +                     samsung,pins = "gpm0-0", "gpm1-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +             };
> >>> +
> >>> +             /* usi_cmgp01_uart */
> >>> +             uart2_bus_single: uart2-bus {
> >>> +                     samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +             };
> >>> +
> >>> +             uart2_bus_dual: uart2-bus-dual {
> >>> +                     samsung,pins = "gpm4-0", "gpm5-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +             };
> >>> +     };
> >>> +
> >>> +     /* AUD */
> >>> +     pinctrl at 14a60000 {
> >>> +             gpb0: gpb0 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             gpb1: gpb1 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             aud_codec_mclk: aud-codec-mclk {
> >>> +                     samsung,pins = "gpb0-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +             };
> >>> +
> >>> +             aud_codec_mclk_idle: aud-codec-mclk-idle {
> >>> +                     samsung,pins = "gpb0-0";
> >>> +                     samsung,pin-function = <0>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +             };
> >>> +
> >>> +             aud_i2s0_bus: aud-i2s0-bus {
> >>> +                     samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +             };
> >>> +
> >>> +             aud_i2s0_idle: aud-i2s0-idle {
> >>> +                     samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
> >>> +                     samsung,pin-function = <0>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +             };
> >>> +
> >>> +             aud_i2s1_bus: aud-i2s1-bus {
> >>> +                     samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +             };
> >>> +
> >>> +             aud_i2s1_idle: aud-i2s1-idle {
> >>> +                     samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
> >>> +                     samsung,pin-function = <0>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +             };
> >>> +
> >>> +             aud_fm_bus: aud-fm-bus {
> >>> +                     samsung,pins = "gpb1-4";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +             };
> >>> +
> >>> +             aud_fm_idle: aud-fm-idle {
> >>> +                     samsung,pins = "gpb1-4";
> >>> +                     samsung,pin-function = <0>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +             };
> >>> +     };
> >>> +
> >>> +     /* HSI */
> >>> +     pinctrl at 13430000 {
> >>> +             gpf2: gpf2 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             sd2_clk: sd2-clk {
> >>> +                     samsung,pins = "gpf2-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sd2_cmd: sd2-cmd {
> >>> +                     samsung,pins = "gpf2-1";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +              };
> >>> +
> >>> +             sd2_bus1: sd2-bus-width1 {
> >>> +                     samsung,pins = "gpf2-2";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sd2_bus4: sd2-bus-width4 {
> >>> +                     samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sd2_clk_fast_slew_rate_1x: sd2-clk_fast_slew_rate_1x {
> >>> +                     samsung,pins = "gpf2-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             sd2_clk_fast_slew_rate_1_5x: sd2-clk_fast_slew_rate_1_5x {
> >>> +                     samsung,pins = "gpf2-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <1>;
> >>> +             };
> >>> +
> >>> +             sd2_clk_fast_slew_rate_2x: sd2-clk_fast_slew_rate_2x {
> >>> +                     samsung,pins = "gpf2-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sd2_clk_fast_slew_rate_2_5x: sd2-clk_fast_slew_rate_2_5x {
> >>> +                     samsung,pins = "gpf2-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +
> >>> +             sd2_clk_fast_slew_rate_3x: sd2-clk_fast_slew_rate_3x {
> >>> +                     samsung,pins = "gpf2-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <4>;
> >>> +             };
> >>> +
> >>> +             sd2_clk_fast_slew_rate_4x: sd2-clk_fast_slew_rate_4x {
> >>> +                     samsung,pins = "gpf2-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <5>;
> >>> +             };
> >>> +
> >>> +             sd2_pins_as_pdn: sd2-pins-as-pdn {
> >>> +                     samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
> >>> +                                    "gpf2-4", "gpf2-5";
> >>> +                     samsung,pin-function = <0>;
> >>> +                     samsung,pin-pud = <2>;
> >>> +             };
> >>> +
> >>
> >> No need for blank line.
> >>
> >
> > Fixed.
> >
> >>> +     };
> >>> +
> >>> +     /* CORE */
> >>> +     pinctrl at 12070000 {
> >>> +             gpf0: gpf0 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             sd0_clk: sd0-clk {
> >>> +                     samsung,pins = "gpf0-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +
> >>> +             sd0_cmd: sd0-cmd {
> >>> +                     samsung,pins = "gpf0-1";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +
> >>> +             sd0_rdqs: sd0-rdqs {
> >>> +                     samsung,pins = "gpf0-2";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +
> >>> +             sd0_nreset: sd0-nreset {
> >>> +                     samsung,pins = "gpf0-3";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +
> >>> +             sd0_clk_fast_slew_rate_1x: sd0-clk_fast_slew_rate_1x {
> >>> +                     samsung,pins = "gpf0-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <1>;
> >>> +             };
> >>> +
> >>> +             sd0_clk_fast_slew_rate_2x: sd0-clk_fast_slew_rate_2x {
> >>> +                     samsung,pins = "gpf0-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sd0_clk_fast_slew_rate_3x: sd0-clk_fast_slew_rate_3x {
> >>> +                     samsung,pins = "gpf0-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sd0_clk_fast_slew_rate_4x: sd0-clk_fast_slew_rate_4x {
> >>> +                     samsung,pins = "gpf0-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +
> >>> +             gpf1: gpf1 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             sd0_bus1: sd0-bus-width1 {
> >>> +                     samsung,pins = "gpf1-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +
> >>> +             sd0_bus4: sd0-bus-width4 {
> >>> +                     samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +
> >>> +             sd0_bus8: sd0-bus-width8 {
> >>> +                     samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <3>;
> >>> +             };
> >>> +     };
> >>> +
> >>> +     /* PERI */
> >>> +     pinctrl at 139b0000 {
> >>> +             gpg0: gpg0 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             gpp0: gpp0 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +             gpp1: gpp1 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             gpp2: gpp2 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             gpg1: gpg1 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             gpg2: gpg2 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             gpg3: gpg3 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             gpc0: gpc0 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             gpc1: gpc1 {
> >>> +                     gpio-controller;
> >>> +                     #gpio-cells = <2>;
> >>> +
> >>> +                     interrupt-controller;
> >>> +                     #interrupt-cells = <2>;
> >>> +             };
> >>> +
> >>> +             xclkout: xclkout {
> >>> +                     samsung,pins = "gpq0-2";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +             };
> >>> +
> >>> +             /* usi_hsi2c_0 */
> >>
> >> Comment seems to duplicate node name/label.
> >>
> >
> > I think the comment is useful, maybe just designed poorly. It's
> > pointing out that this HS-I2C block is based on USI IP-core. Basically
> > we have 7 USI blocks in this SoC:
> >   - 5 USIs that pre-defined: HSI2C0, HSI2C1, HSI2C2, UART0 and SPI0;
> > although AFAIU they can be changed via System Register as well, but
> > seems like nobody does that
> >   - 2 USIs from CMGP blocks (CMGP0 and CMGP1), which are actually configurable
> >
> > I will revise all such comments like this, just to show those blocks
> > are based on USI design:
> >
> >     /* USI: HSI2C0 */
>
> OK
>
> >
> > At least when I was bringing up this board, I was really confused for
> > long time about this USI business. So I'm sure some kind of comments
> > might be actually helpful. And that's one reason to keep
> > exynos850-usi.dtsi file: although I removed it for now, squashing it
> > into exynos850.dtsi, I think it might be a good idea to bring that
> > back once all USI nodes are described. Just thinking aloud :)
> >
> >>> +             hsi2c0_bus: hsi2c0-bus {
> >>> +                     samsung,pins = "gpc1-0", "gpc1-1";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             /* usi_hsi2c_1 */
> >>> +             hsi2c1_bus: hsi2c1-bus {
> >>> +                     samsung,pins = "gpc1-2", "gpc1-3";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             /* usi_hsi2c_2 */
> >>> +             hsi2c2_bus: hsi2c2-bus {
> >>> +                     samsung,pins = "gpc1-4", "gpc1-5";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             /* usi_spi_0 */
> >>> +             spi0_bus: spi0-bus {
> >>> +                     samsung,pins = "gpp2-0", "gpp2-2", "gpp2-3";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             spi0_cs: spi0-cs {
> >>> +                     samsung,pins = "gpp2-1";
> >>> +                     samsung,pin-function = <1>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             spi0_cs_func: spi0-cs-func {
> >>> +                     samsung,pins = "gpp2-1";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             i2c0_bus: i2c0-bus {
> >>> +                     samsung,pins = "gpp0-0", "gpp0-1";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             i2c1_bus: i2c1-bus {
> >>> +                     samsung,pins = "gpp0-2", "gpp0-3";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             i2c2_bus: i2c2-bus {
> >>> +                     samsung,pins = "gpp0-4", "gpp0-5";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             i2c3_bus: i2c3-bus {
> >>> +                     samsung,pins = "gpp1-0", "gpp1-1";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             i2c4_bus: i2c4-bus {
> >>> +                     samsung,pins = "gpp1-2", "gpp1-3";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <3>;
> >>> +                     samsung,pin-drv = <0>;
> >>> +             };
> >>> +
> >>> +             fm_lna_en: fm-lna-en {
> >>> +                     samsung,pins = "gpg2-3";
> >>> +                     samsung,pin-function = <1>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-val = <0>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk0_in: sensor-mclk0-in {
> >>> +                     samsung,pins = "gpc0-0";
> >>> +                     samsung,pin-function = <0>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk0_out: sensor-mclk0-out {
> >>> +                     samsung,pins = "gpc0-0";
> >>> +                     samsung,pin-function = <1>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk0_fn: sensor-mclk0-fn {
> >>
> >> No, seriously. What sensor is it? In SoC?
> >>
> >
> > In this context, "sensor" stands for "camera". Of course, it resides
> > (or rather *may* reside) outside of the SoC. This is just useful pin
> > configuration for camera master clock lines (3 of them). On schematic
> > those 3 lines are grouped into "MCLK" block, and those pins main
> > function is CAM_MCLK. I guess it makes sense to keep those
> > definitions, as I doubt somebody would actually consider using those
> > lines for somthing else. Or I can remove all those sensor*
> > definitions, if you'd like, then those can be added later, when camera
> > support cames in.
>
> Hmmm, indeed we define in pinctrl useful typical functions and I
> understand this one is such. Let's keep them then.
>
> >
> >>> +                     samsung,pins = "gpc0-0";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk1_in: sensor-mclk1-in {
> >>> +                     samsung,pins = "gpc0-1";
> >>> +                     samsung,pin-function = <0>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk1_out: sensor-mclk1-out {
> >>> +                     samsung,pins = "gpc0-1";
> >>> +                     samsung,pin-function = <1>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk1_fn: sensor-mclk1-fn {
> >>> +                     samsung,pins = "gpc0-1";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk2_in: sensor-mclk2-in {
> >>> +                     samsung,pins = "gpc0-2";
> >>> +                     samsung,pin-function = <0>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk2_out: sensor-mclk2-out {
> >>> +                     samsung,pins = "gpc0-2";
> >>> +                     samsung,pin-function = <1>;
> >>> +                     samsung,pin-pud = <1>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +
> >>> +             sensor_mclk2_fn: sensor-mclk2-fn {
> >>> +                     samsung,pins = "gpc0-2";
> >>> +                     samsung,pin-function = <2>;
> >>> +                     samsung,pin-pud = <0>;
> >>> +                     samsung,pin-drv = <2>;
> >>> +             };
> >>> +     };
> >>> +};
> >>> diff --git a/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi b/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
> >>> new file mode 100644
> >>> index 000000000000..fb243e0a6260
> >>> --- /dev/null
> >>> +++ b/arch/arm64/boot/dts/exynos/exynos850-usi.dtsi
> >>> @@ -0,0 +1,30 @@
> >>> +// SPDX-License-Identifier: GPL-2.0
> >>> +/*
> >>> + * Samsung's Exynos850 SoC USI device tree source
> >>> + *
> >>> + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
> >>> + * Copyright (C) 2021 Linaro Ltd.
> >>> + *
> >>> + * Samsung's Exynos850 SoC USI channels are listed in this file as device tree
> >>> + * nodes.
> >>
> >> Why here not in exynos850.dtsi?
> >>
> >
> > Yeah, you're right. As it's only serial_0 for now, I've moved that
> > into exynos850.dtsi and removed exynos850-usi.dtsi.
> >
> >>> + */
> >>> +
> >>> +#include <dt-bindings/clock/exynos850.h>
> >>> +
> >>> +/ {
> >>> +     aliases {
> >>> +             uart0 = &serial_0;
> >>> +     };
> >>> +
> >>> +     /* USI_UART */
> >>> +     serial_0: uart at 13820000 {
> >>
> >> This should ne in soc node.
> >>
> >
> > Done.
> >
> >>> +             compatible = "samsung,exynos850-uart";
> >>> +             reg = <0x0 0x13820000 0x100>;
> >>> +             interrupts = <GIC_SPI INTREQ__UART IRQ_TYPE_LEVEL_HIGH>;
> >>> +             pinctrl-names = "default";
> >>> +             pinctrl-0 = <&uart0_bus>;
> >>> +             clocks = <&clock GATE_UART_QCH>, <&clock DOUT_UART>;
> >>> +             clock-names = "gate_uart_clk0", "uart";
> >>> +             status = "disabled";
> >>> +     };
> >>> +};
> >>> diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> >>> new file mode 100644
> >>> index 000000000000..ed2d1c8ae0c3
> >>> --- /dev/null
> >>> +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> >>> @@ -0,0 +1,245 @@
> >>> +// SPDX-License-Identifier: GPL-2.0
> >>> +/*
> >>> + * Samsung Exynos850 SoC device tree source
> >>> + *
> >>> + * Copyright (C) 2018 Samsung Electronics Co., Ltd.
> >>> + * Copyright (C) 2021 Linaro Ltd.
> >>> + *
> >>> + * Samsung Exynos850 SoC device nodes are listed in this file.
> >>> + * Exynos based board files can include this file and provide
> >>> + * values for board specific bindings.
> >>> + */
> >>> +
> >>> +#include <dt-bindings/interrupt-controller/exynos850.h>
> >>> +#include <dt-bindings/clock/exynos850.h>
> >>> +#include "exynos850-pinctrl.dtsi"
> >>> +#include "exynos850-usi.dtsi"
> >>> +
> >>> +/ {
> >>
> >> Add a comment like:
> >> /* Also known under engineering name exynos3830 */
> >>
> >
> > Sure.
> >
> >>> +     compatible = "samsung,exynos850";
> >>
> >> Undocumented compatible. Checkpatch should complain.
> >>
> >
> > It actually doesn't, though it does complain about other undocumented
> > compatibles. I understand that it should be documented in
> > samsung-boards.yaml, but is it ok with you if I do that later, when
> > adding some actual board's dts? Just don't want to have two patches
> > for that.
>
> We're back to the first question - it needs to come with DTS and then
> you document both compatibles.
>
> Best regards,
> Krzysztof


From icenowy at aosc.io  Fri Aug  6 05:09:11 2021
From: icenowy at aosc.io (Icenowy Zheng)
Date: Fri, 06 Aug 2021 20:09:11 +0800
Subject: =?US-ASCII?Q?Re=3A_=5Blinux-sunxi=5D_Re=3A_=5BPATCH_52/54=5D_arm64=3A_?=
 =?US-ASCII?Q?dts=3A_allwinner=3A_Remove_regulator-ramp-delay?=
In-Reply-To: <CAGb2v65dAAc274JiZyTswuqGHn1tE9urJpTBv=is2CG1UT2CTA@mail.gmail.com>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-53-maxime@cerno.tech>
 <5469a059-dad1-38d2-9ea4-f1b5fa9ac616@sholland.org>
 <20210722081616.arxwrn5krbaocymf@gilmour>
 <68e4820ead3107aa4e80dcaf9243bd11de5fce98.camel@aosc.io>
 <CAGb2v65dAAc274JiZyTswuqGHn1tE9urJpTBv=is2CG1UT2CTA@mail.gmail.com>
Message-ID: <0308F3FA-B5DE-4FFC-AD22-4F5E94CDF466@aosc.io>



? 2021?8?6? GMT+08:00 ??8:05:56, Chen-Yu Tsai <wens at csie.org> ??:
>On Fri, Aug 6, 2021 at 7:49 PM Icenowy Zheng <icenowy at aosc.io> wrote:
>>
>> ? 2021-07-22???? 10:16 +0200?Maxime Ripard???
>> > On Thu, Jul 22, 2021 at 12:55:53AM -0500, Samuel Holland wrote:
>> > > On 7/21/21 9:04 AM, Maxime Ripard wrote:
>> > > > The regulator-ramp-delay property isn't documented in the binding
>> > > > for
>> > > > the AXP806, and it's ignored by the driver. Remove those
>> > > > properties.
>> > >
>> > > This is a generic regulator property, parsed by
>> > > of_get_regulation_constraints, which is called by
>> > > regulator_of_get_init_data in the regulator core. And it appears in
>> > > bindings/regulator/regulator.yaml. I believe the binding needs to be
>> > > fixed, not the device trees.
>> >
>> > It's indeed parsed by the regulator framework, but then it calls into
>> > the driver if that property is set using set_ramp_delay if it's set.
>>
>> Not only is it used for set_ramp_delay, but it's also used to calculate
>> a post-change delay, see the following position (it can be overrided by
>> a custom set_voltage_time in the driver):
>>
>> https://elixir.bootlin.com/linux/latest/source/drivers/regulator/core.c#L3339
>
>Having just dug through the regulator core code at work, I agree.
>
>Furthermore, the commit log for this addition specifically mentions the
>reason for adding this property is to provide a (guessed) ramp rate for
>the core to do a proper delay for the regulator to ramp up, not to set
>the actual ramp rate in hardware.

Well we must agree that we have some more suitable property that delays
for a constant span, see lines below in the function I mentioned.

>
>
>ChenYu
>
>
>[1] https://git.kernel.org/torvalds/c/fe79ea577be81e1e71642826ab00e676dc59c194
>
>> >
>> > https://elixir.bootlin.com/linux/latest/source/drivers/regulator/core.c#L1378
>> >
>> > We don't set that hook for the AXP806 DCDC-A and DCDC-E regulators
>> > (that
>> > use AXP_DESC_RANGES) at all:
>> >
>> > https://elixir.bootlin.com/linux/latest/source/drivers/regulator/axp20x-regulator.c#L343
>> >
>> > And the only implementation we have (set for AXP_DESC and AXP_DESC_IO)
>> > works only for the AXP209:
>> >
>> > https://elixir.bootlin.com/linux/latest/source/drivers/regulator/axp20x-regulator.c#L368
>> >
>> > So, it just looks like those properties have never been tested since
>> > they were just ignored.
>> >
>> > Maxime
>> >
>>
>> --
>> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
>> To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/68e4820ead3107aa4e80dcaf9243bd11de5fce98.camel%40aosc.io.
>


From herbert at gondor.apana.org.au  Fri Aug  6 05:14:52 2021
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 6 Aug 2021 20:14:52 +0800
Subject: [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver
In-Reply-To: <20210731204845.21196-1-andre.przywara@arm.com>
References: <20210731204845.21196-1-andre.przywara@arm.com>
Message-ID: <20210806121452.GC25554@gondor.apana.org.au>

On Sat, Jul 31, 2021 at 09:48:43PM +0100, Andre Przywara wrote:
> The "Arm True Random Number Generator Firmware Interface"[1] provides
> an SMCCC based interface to a true hardware random number generator.
> So far we are using that in arch_get_random_seed(), but it might be
> useful to expose the entropy through the /dev/hwrng device as well. This
> allows to assess the quality of the implementation, by using "rngtest"
> from the rng-tools package, for example.
> 
> Patch 1 creates a platform device, triggered by the previous discovery
> of the SMCCC TRNG service.
> Patch 2 implements a hw_random platform driver, which is instantiated
> through this said platform device.
> 
> The driver can be loaded as module, or built into the kernel.
> 
> [1] https://developer.arm.com/documentation/den0098/latest/
> 
> Changelog v3 ... v4:
> - drop pointless driver loading message
> - drop unneeded init() routine
> 
> Changelog v2 ... v3:
> - split platform device and driver
> 
> Changelog v1 ... v2:
> - fix building as a module
> - de-register device upon exit
> - mention module name in Kconfig
> 
> Andre Przywara (2):
>   firmware: smccc: Register smccc_trng platform device
>   hwrng: Add Arm SMCCC TRNG based driver
> 
>  drivers/char/hw_random/Kconfig          |  14 +++
>  drivers/char/hw_random/Makefile         |   1 +
>  drivers/char/hw_random/arm_smccc_trng.c | 123 ++++++++++++++++++++++++
>  drivers/firmware/smccc/smccc.c          |  17 ++++
>  4 files changed, 155 insertions(+)
>  create mode 100644 drivers/char/hw_random/arm_smccc_trng.c

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From matthias.bgg at gmail.com  Fri Aug  6 05:20:21 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 6 Aug 2021 14:20:21 +0200
Subject: [PATCH v2 07/14] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys1
In-Reply-To: <48be9a4ebb455737bfd640c6339f2ce05d02d4cd.camel@mediatek.com>
References: <20210722094551.15255-1-nancy.lin@mediatek.com>
 <20210722094551.15255-8-nancy.lin@mediatek.com>
 <CAFqH_53UpoChfrhXf41YRMGGPzjC9N2g3yNQQxc-J=7uPE44Cw@mail.gmail.com>
 <48be9a4ebb455737bfd640c6339f2ce05d02d4cd.camel@mediatek.com>
Message-ID: <6c1891ed-178e-b589-1630-93d528276b17@gmail.com>



On 28/07/2021 07:34, Nancy.Lin wrote:
> Hi Enric,
> 
> Thanks for your review.
> 
> On Fri, 2021-07-23 at 13:05 +0200, Enric Balletbo Serra wrote:
>> Hi Nancy,
>>
>> Thank you for your patch.
>>
>> Missatge de Nancy.Lin <nancy.lin at mediatek.com> del dia dj., 22 de
>> jul.
>> 2021 a les 11:45:
>>>
>>> Add mt8195 vdosys1 clock driver name and routing table to
>>> the driver data of mtk-mmsys.
>>>
>>> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
>>> ---
>>>  drivers/soc/mediatek/mt8195-mmsys.h    | 83
>>> ++++++++++++++++++++++++--
>>>  drivers/soc/mediatek/mtk-mmsys.c       | 10 ++++
>>>  include/linux/soc/mediatek/mtk-mmsys.h |  2 +
>>>  3 files changed, 90 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
>>> b/drivers/soc/mediatek/mt8195-mmsys.h
>>> index 73e9e8286d50..104ba575f765 100644
>>> --- a/drivers/soc/mediatek/mt8195-mmsys.h
>>> +++ b/drivers/soc/mediatek/mt8195-mmsys.h
>>> @@ -64,16 +64,16 @@
>>>  #define SOUT_TO_VPP_MERGE0_P1_SEL                              (1
>>> << 0)
>>>
>>>  #define
>>> MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL                      0xf40
>>> -#define SOUT_TO_HDR_VDO_FE0                                    (0
>>> << 0)
>>
>> This definition was introduced in this patch [1] that didn't land
>> yet.
>> And you're removing it now. Could you sync with Jason and only
>> introduce the bits that are needed for your patches. Also all the
>> comments I made to the Jason's patch apply here.
>>
>> [1] 
>> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210723090233.24007-3-jason-jh.lin at mediatek.com/__;!!CTRNKA9wMg0ARbw!0rDdPxfBPcZC9icK37sCxT55RMqwRngO0BF4-uDwgYZP7UwQkx7iidkINqLBb7yi$
>>  
>>
> OK, I will sync with Jason and modify it.
> 
>>> +#define SOUT_TO_MIXER_IN1_SEL                                  (1
>>> << 0)
>>>
>>>  #define
>>> MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL                      0xf44
>>> -#define SOUT_TO_HDR_VDO_FE1                                    (0
>>> << 0)
>>> +#define SOUT_TO_MIXER_IN2_SEL                                  (1
>>> << 0)
>>>
>>>  #define
>>> MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL                      0xf48
>>> -#define SOUT_TO_HDR_GFX_FE0                                    (0
>>> << 0)
>>> +#define SOUT_TO_MIXER_IN3_SEL                                  (1
>>> << 0)
>>>
>>>  #define
>>> MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL                      0xf4c
>>> -#define SOUT_TO_HDR_GFX_FE1                                    (0
>>> << 0)
>>> +#define SOUT_TO_MIXER_IN4_SEL                                  (1
>>> << 0)
>>>
>>>  #define
>>> MT8195_VDO1_MIXER_IN1_SOUT_SEL                         0xf58
>>>  #define MIXER_IN1_SOUT_TO_DISP_MIXER                           (0
>>> << 0)
>>> @@ -88,7 +88,7 @@
>>>  #define MIXER_IN4_SOUT_TO_DISP_MIXER                           (0
>>> << 0)
>>>
>>>  #define
>>> MT8195_VDO1_MIXER_OUT_SOUT_SEL                         0xf34
>>> -#define MIXER_SOUT_TO_HDR_VDO_BE0                              (0
>>> << 0)
>>> +#define MIXER_SOUT_TO_MERGE4_ASYNC_SEL                         (1
>>> << 0)
>>>
>>>  #define
>>> MT8195_VDO1_MERGE4_SOUT_SEL                            0xf18
>>>  #define MERGE4_SOUT_TO_VDOSYS0                                 (0
>>> << 0)
>>> @@ -185,6 +185,79 @@ static const struct mtk_mmsys_routes
>>> mmsys_mt8195_routing_table[] = {
>>>         }, {
>>>                 DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
>>>                 MT8195_VDO0_SEL_OUT,
>>> SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_VPP_MERGE0_P0_SEL_IN,
>>> VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_VPP_MERGE0_P1_SEL_IN,
>>> VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_VPP_MERGE1_P0_SEL_IN,
>>> VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL,
>>> SOUT_TO_MIXER_IN1_SEL
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL,
>>> SOUT_TO_MIXER_IN2_SEL
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL,
>>> SOUT_TO_MIXER_IN3_SEL
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL,
>>> SOUT_TO_MIXER_IN4_SEL
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MIXER_OUT_SOUT_SEL,
>>> MIXER_SOUT_TO_MERGE4_ASYNC_SEL
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MIXER_IN1_SEL_IN,
>>> MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MIXER_IN2_SEL_IN,
>>> MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MIXER_IN3_SEL_IN,
>>> MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MIXER_IN4_SEL_IN,
>>> MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MIXER_SOUT_SEL_IN,
>>> MIXER_SOUT_SEL_IN_FROM_DISP_MIXER
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
>>> +               MT8195_VDO1_MERGE4_ASYNC_SEL_IN,
>>> MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
>>> +               MT8195_VDO1_DISP_DPI1_SEL_IN,
>>> DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
>>> +               MT8195_VDO1_MERGE4_SOUT_SEL,
>>> MERGE4_SOUT_TO_DPI1_SEL
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
>>> +               MT8195_VDO1_DISP_DP_INTF0_SEL_IN,
>>> +               DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT
>>> +       },
>>> +       {
>>> +               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
>>> +               MT8195_VDO1_MERGE4_SOUT_SEL,
>>> MERGE4_SOUT_TO_DP_INTF0_SEL
>>>         }
>>>  };
>>>
>>> diff --git a/drivers/soc/mediatek/mtk-mmsys.c
>>> b/drivers/soc/mediatek/mtk-mmsys.c
>>> index 1fb241750897..9e31aad6c5c8 100644
>>> --- a/drivers/soc/mediatek/mtk-mmsys.c
>>> +++ b/drivers/soc/mediatek/mtk-mmsys.c
>>> @@ -59,6 +59,12 @@ static const struct mtk_mmsys_driver_data
>>> mt8195_vdosys0_driver_data = {
>>>         .num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
>>>  };
>>>
>>> +static const struct mtk_mmsys_driver_data
>>> mt8195_vdosys1_driver_data = {
>>> +       .clk_driver = "clk-mt8195-vdo1",
>>> +       .routes = mmsys_mt8195_routing_table,
>>> +       .num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
>>> +};
>>> +
>>>  struct mtk_mmsys {
>>>         void __iomem *regs;
>>>         const struct mtk_mmsys_driver_data *data;
>>> @@ -168,6 +174,10 @@ static const struct of_device_id
>>> of_match_mtk_mmsys[] = {
>>>                 .compatible = "mediatek,mt8195-vdosys0",
>>>                 .data = &mt8195_vdosys0_driver_data,
>>>         },
>>> +       {
>>> +               .compatible = "mediatek,mt8195-vdosys1",
>>
>> Why do you need a second compatible, isn't this the same IP block? I
>> mean, I understand that you have 2 mmsys blocks, but both are the
>> same
>> IP block, right? or are they different?
>>
>> Thanks,
>>   Enric
>>
> They(vdosys0 and vdosys1) are different IP block.
> 

Please explain in what they are different. From what I see, you use the same
routing table for both compatibles and only register another platform device for
a second clock. Is that correct?

Regards,
Matthias

>>> +               .data = &mt8195_vdosys1_driver_data,
>>> +       },
>>>         { }
>>>  };
>>>
>>> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
>>> b/include/linux/soc/mediatek/mtk-mmsys.h
>>> index 34cb605e5df9..338c71570aeb 100644
>>> --- a/include/linux/soc/mediatek/mtk-mmsys.h
>>> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
>>> @@ -49,6 +49,8 @@ enum mtk_ddp_comp_id {
>>>         DDP_COMPONENT_DSC1,
>>>         DDP_COMPONENT_DSC1_VIRTUAL0,
>>>         DDP_COMPONENT_DP_INTF0,
>>> +       DDP_COMPONENT_DP_INTF1,
>>> +       DDP_COMPONENT_PSEUDO_OVL,
>>>         DDP_COMPONENT_ID_MAX,
>>>  };
>>>
>>> --
>>> 2.18.0
>>>


From shameerali.kolothum.thodi at huawei.com  Fri Aug  6 05:24:36 2021
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Fri, 6 Aug 2021 12:24:36 +0000
Subject: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU schedule out
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
 <20210803114034.GB30853@willie-the-truck>
 <ee2863107d614ef8a36006b5aa912eca@huawei.com>
 <20210803153036.GA31125@willie-the-truck> 
Message-ID: <b2146ea5db47485f8410a4c1ab0c15fe@huawei.com>



> -----Original Message-----
> From: Shameerali Kolothum Thodi
> Sent: 03 August 2021 16:57
> To: 'Will Deacon' <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org; maz at kernel.org; catalin.marinas at arm.com;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Linuxarm
> <linuxarm at huawei.com>
> Subject: RE: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU
> schedule out
> 
> 
> 
> > -----Original Message-----
> > From: Will Deacon [mailto:will at kernel.org]
> > Sent: 03 August 2021 16:31
> > To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> > Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> > linux-kernel at vger.kernel.org; maz at kernel.org; catalin.marinas at arm.com;
> > james.morse at arm.com; julien.thierry.kdev at gmail.com;
> > suzuki.poulose at arm.com; jean-philippe at linaro.org;
> > Alexandru.Elisei at arm.com; qperret at google.com; Linuxarm
> > <linuxarm at huawei.com>
> > Subject: Re: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU
> > schedule out
> >
> > On Tue, Aug 03, 2021 at 12:55:25PM +0000, Shameerali Kolothum Thodi
> > wrote:
> > > > > diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
> > > > > index 5584e84aed95..5fd51f5445c1 100644
> > > > > --- a/arch/arm64/kvm/vmid.c
> > > > > +++ b/arch/arm64/kvm/vmid.c
> > > > > @@ -116,6 +116,12 @@ static u64 new_vmid(struct kvm_vmid
> > > > *kvm_vmid)
> > > > >  	return idx2vmid(vmid) | generation;
> > > > >  }
> > > > >
> > > > > +/* Call with preemption disabled */
> > > > > +void kvm_arm_vmid_clear_active(void)
> > > > > +{
> > > > > +	atomic64_set(this_cpu_ptr(&active_vmids), 0);
> > > > > +}
> > > >
> > > > I think this is very broken, as it will force everybody to take the
> > > > slow-path when they see an active_vmid of 0.
> > >
> > > Yes. I have seen that happening in my test setup.
> >
> > Why didn't you say so?!
> 
> Sorry. I thought of getting some performance numbers with and
> without this patch and measure the impact. But didn't quite get time
> to finish it yet.

These are some test numbers with and without this patch, run on two
different test setups.


a)Test Setup -1
-----------------------

Platform: HiSilicon D06 with 128 CPUs, VMID bits = 16
Run 128 VMs concurrently each with 2 vCPUs. Each Guest will execute hackbench
5 times before exiting.

Measurements taken avg. of 10 Runs.

Image : 5.14-rc3
---------------------------
  Time(s)       44.43813888
  No. of exits    145,348,264

Image: 5.14-rc3 + vmid-v3
----------------------------------------
  Time(s)        46.59789034
  No. of exits     133,587,307

%diff against 5.14-rc3
  Time: 4.8% more
  Exits: 8% less 

Image: 5.14-rc3 + vmid-v3 + Without active_asid clear
---------------------------------------------------------------------------
  Time(s)         44.5031782
  No. of exits      144,443,188

%diff against 5.14-rc3
  Time: 0.15% more
  Exits: 2.42% less

b)Test Setup -2
-----------------------

Platform: HiSilicon D06 + Kernel with maxcpus set to 8 and VMID bits set to 4.
Run 40 VMs concurrently each with 2 vCPUs. Each Guest will execute hackbench
5 times before exiting.

Measurements taken avg. of 10 Runs.

Image : 5.14-rc3-vmid4bit
------------------------------------
  Time(s)        46.19963266
  No. of exits     23,699,546

Image: 5.14-rc3-vmid4bit + vmid-v3
---------------------------------------------------
  Time(s)          45.83307736
  No. of exits      23,260,203

%diff against 5.14-rc3-vmid4bit
  Time: 0.8% less
  Exits: 1.85% less 

Image: 5.14-rc3-vmid4bit + vmid-v3 + Without active_asid clear
-----------------------------------------------------------------------------------------
  Time(s)           44.5031782
  No. of exits        144,443,188

%diff against 5.14-rc3-vmid4bit
  Time: 1.05% less
  Exits: 2.06% less

As expected, the active_asid clear on schedule out is not helping.
But without this patch, the numbers seems to be better than the
vanilla kernel when we force the setup(cpus=8, vmd=4bits)
to perform rollover.

Please let me know your thoughts.

Thanks,
Shameer

> 
> >
> > > > It also doesn't solve the issue I mentioned before, as an active_vmid of 0
> > > > means that the reserved vmid is preserved.
> > > >
> > > > Needs more thought...
> > >
> > > How about we clear all the active_vmids in kvm_arch_free_vm() if it
> > > matches the kvm_vmid->id ? But we may have to hold the lock
> > > there
> >
> > I think we have to be really careful not to run into the "suspended
> > animation" problem described in ae120d9edfe9 ("ARM: 7767/1: let the ASID
> > allocator handle suspended animation") if we go down this road.
> 
> 
> Ok. I will go through that.
> 
> > Maybe something along the lines of:
> >
> > ROLLOVER
> >
> >   * Take lock
> >   * Inc generation
> >     => This will force everybody down the slow path
> >   * Record active VMIDs
> >   * Broadcast TLBI
> >     => Only active VMIDs can be dirty
> >     => Reserve active VMIDs and mark as allocated
> >
> > VCPU SCHED IN
> >
> >   * Set active VMID
> >   * Check generation
> >   * If mismatch then:
> >         * Take lock
> >         * Try to match a reserved VMID
> >         * If no reserved VMID, allocate new
> >
> > VCPU SCHED OUT
> >
> >   * Clear active VMID
> >
> > but I'm not daft enough to think I got it right first time. I think it
> > needs both implementing *and* modelling in TLA+ before we merge it!
> >
> 
> Ok. I need some time to digest the above first :).
> 
> On another note, how serious do you think is the problem of extra
> reservation of the VMID space? Just wondering if we can skip this
> patch for now or not..
> 
> Thanks,
> Shameer


From krzysztof.kozlowski at canonical.com  Fri Aug  6 05:32:00 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 6 Aug 2021 14:32:00 +0200
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <CAPLW+4n_JKj5xeBHXONcv__vyAFvx3fhXoxJa17NTHK1RSJFJw@mail.gmail.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <455cfb5e-dff7-a5c0-3875-49abe3e900f3@canonical.com>
 <CAPLW+4nDS0atrbUFagDA0W_Ky5MvOiY+N+NQoQ+me4pndp_iWg@mail.gmail.com>
 <68734f6c-fc76-595c-8d34-8924dbbbb845@canonical.com>
 <CAPLW+4n_JKj5xeBHXONcv__vyAFvx3fhXoxJa17NTHK1RSJFJw@mail.gmail.com>
Message-ID: <b753796c-2ce6-4166-7c20-289e950237ad@canonical.com>

On 06/08/2021 14:07, Sam Protsenko wrote:
> On Fri, 6 Aug 2021 at 10:49, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 06/08/2021 01:06, Sam Protsenko wrote:
>>> On Sat, 31 Jul 2021 at 12:03, Krzysztof Kozlowski
>>> <krzysztof.kozlowski at canonical.com> wrote:
>>>
>>>>>
>>>>> This patch adds minimal SoC support. Particular board device tree files
>>>>> can include exynos850.dtsi file to get SoC related nodes, and then
>>>>> reference those nodes further as needed.
>>>>>
>>>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>>>> ---
>>>>>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
>>>>>  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
>>>>>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
>>>>
>>>> Not buildable. Missing Makefile, missing DTS. Please submit with initial
>>>> DTS, otherwise no one is able to verify it even compiles.
>>>>
>>>
>>> This device is not available for purchase yet. I'll send the patch for
>>> board dts once it's announced. I can do all the testing for now, if
>>> you have any specific requests. Would it be possible for us to review
>>> and apply only SoC support for now? Will send v2 soon...
>>
>> What you propose is equal to adding a driver (C source code) without
>> ability to compile it. What's the point of having it in the kernel? It's
>> unverifiable, unbuildable and unusable.
>>
> 
> Yes, I understand. That's adding code with no users, and it's not a
> good practice.
> 
>> We can review the DTSI however merging has to be with a DTS. Usually the
>> SoC vendor adds first an evalkit (e.g. SMDK board). Maybe you have one
>> for Exynos850? Otherwise if you cannot disclose the actual board, the
>> DTSI will have to wait. You can submit drivers, though.
>>
> 
> Sure, let's go this way. I'll send v2 soon. Improving patches and
> having Reviewed-by tag for those would good enough for me at this
> point. I'll continue to prepare another Exynos850 related patches
> until the actual board is announced, like proper clock driver, reset,
> MMC, etc. Is it ok if I send those for a review too (so I can fix all
> issues ahead)?

Sure, prepare all necessary drivers earlier. I suspect clocks will be a
real pain because of significant changes modeled in vendor kernel. I
remember Pawe? Chmiel (+Cc) was doing something for these:
https://github.com/PabloPL/linux/tree/exynos7420

I mentioned before - you should also modify the chipid driver. Check
also other drivers in drivers/soc/samsung, although some are needed only
for suspend&resume.

BTW, Pawe?,
How is your Exynos7420 progress? :)

> And should I maybe add RFC tag for those?

No need. Drivers can be merged before DTS users.

Best regards,
Krzysztof


From vkoul at kernel.org  Fri Aug  6 05:39:19 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:09:19 +0530
Subject: [PATCH 3/3] phy: intel: Add Thunder Bay eMMC PHY support
In-Reply-To: <20210730063309.8194-4-rashmi.a@intel.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-4-rashmi.a@intel.com>
Message-ID: <YQ0td9y5+RNFxWZs@matsya>

On 30-07-21, 12:03, rashmi.a at intel.com wrote:

> diff --git a/drivers/phy/intel/Kconfig b/drivers/phy/intel/Kconfig
> index ac42bb2fb394..18a3cc5b98c0 100644
> --- a/drivers/phy/intel/Kconfig
> +++ b/drivers/phy/intel/Kconfig
> @@ -46,3 +46,13 @@ config PHY_INTEL_LGM_EMMC
>  	select GENERIC_PHY
>  	help
>  	  Enable this to support the Intel EMMC PHY
> +
> +config PHY_INTEL_THUNDERBAY_EMMC

Alphabetical sort please

> +        tristate "Intel Thunder Bay eMMC PHY driver"
> +        depends on OF && (ARCH_THUNDERBAY || COMPILE_TEST)
> +        select GENERIC_PHY
> +        help
> +	  This option enables support for Intel Thunder Bay SoC eMMC PHY.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called phy-intel-thunderbay-emmc.ko.
> diff --git a/drivers/phy/intel/Makefile b/drivers/phy/intel/Makefile
> index 14550981a707..6a4db3ee7393 100644
> --- a/drivers/phy/intel/Makefile
> +++ b/drivers/phy/intel/Makefile
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC)	+= phy-intel-keembay-emmc.o
> +obj-$(CONFIG_PHY_INTEL_THUNDERBAY_EMMC)	+= phy-intel-thunderbay-emmc.o

here as well

> +static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on)
> +{
> +	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
> +	unsigned int freqsel = FREQSEL_200M_170M;
> +	unsigned long rate;
> +	static int lock;
> +	u32 val;
> +	int ret;
> +
> +	/* Disable DLL */
> +	rate = clk_get_rate(tbh_phy->emmcclk);
> +	switch (rate) {
> +	case 200000000:
> +	/* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0 */
> +		update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x0);

pls keep the same indent for comment and code!

> +		break;
> +	/* dll lock not required for other frequencies */
> +	case 50000000 ... 52000000:
> +	case 400000:
> +	default:
> +		break;
> +	}
> +
> +	if (!power_on)
> +		return 0;

should this not be the first thing you check...

> +
> +	rate = clk_get_rate(tbh_phy->emmcclk);
> +	switch (rate) {
> +	case 170000001 ... 200000000:
> +		freqsel = FREQSEL_200M_170M;
> +		break;
> +	case 140000001 ... 170000000:
> +		freqsel = FREQSEL_170M_140M;
> +		break;
> +	case 110000001 ... 140000000:
> +		freqsel = FREQSEL_140M_110M;
> +		break;
> +	case 80000001 ... 110000000:
> +		freqsel = FREQSEL_110M_80M;
> +		break;
> +	case 50000000 ... 80000000:
> +		freqsel = FREQSEL_80M_50M;
> +		break;
> +	case 250000001 ... 275000000:
> +		freqsel = FREQSEL_275M_250M;
> +		break;
> +	case 225000001 ... 250000000:
> +		freqsel = FREQSEL_250M_225M;
> +		break;
> +	case 200000001 ... 225000000:
> +		freqsel = FREQSEL_225M_200M;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	if (rate > 200000000)
> +	/* only the upper limit is considered as the clock rate may fall low during init */
> +		dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);

here as well! (checkpatch --strict should have told you so)

> +static int thunderbay_emmc_phy_power_on(struct phy *phy)
> +{
> +	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
> +	unsigned long rate;
> +
> +	/* Overwrite capability bits configurable in bootloader */
> +	update_reg(tbh_phy, CTRL_CFG_0,
> +		   SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_0,
> +		   SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1);
> +	update_reg(tbh_phy, CTRL_CFG_1,
> +		   SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1);
> +
> +	if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) {
> +	/* Indicates initialization, so settings to be done for init , same as 400KHZ setting */
> +		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, SEL_DLY_TXCLK_SHIFT, 0x1);

inconsistent indent here too!

> +		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, SEL_DLY_RXCLK_SHIFT, 0x1);
> +		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, ITAP_DLY_ENA_SHIFT, 0x0);
> +		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, ITAP_DLY_SEL_SHIFT, 0x0);
> +		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, OTAP_DLY_ENA_SHIFT, 0x0);
> +		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, OTAP_DLY_SEL_SHIFT, 0);
> +		update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, DLL_TRIM_ICP_SHIFT, 0);
> +		update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1);
> +
> +	} else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) {
> +		/* Indicates actual clock setting */
> +		rate = clk_get_rate(tbh_phy->emmcclk);
> +		switch (rate) {
> +		case 200000000:
> +			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
> +				   SEL_DLY_TXCLK_SHIFT, 0x0);
> +			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
> +				   SEL_DLY_RXCLK_SHIFT, 0x0);
> +			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
> +				   ITAP_DLY_ENA_SHIFT, 0x0);
> +			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
> +				   ITAP_DLY_SEL_SHIFT, 0x0);
> +			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
> +				   OTAP_DLY_ENA_SHIFT, 0x1);
> +			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
> +				   OTAP_DLY_SEL_SHIFT, 2);
> +			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
> +				   DLL_TRIM_ICP_SHIFT, 0x8);
> +			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
> +				   DR_TY_SHIFT, 0x1);
> +			/* For HS400 only */
> +			update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK,
> +				   SEL_STRB_SHIFT, STRB);
> +			break;

pls give a empty line after break, helps to read the code

-- 
~Vinod


From will at kernel.org  Fri Aug  6 05:42:42 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 6 Aug 2021 13:42:42 +0100
Subject: [PATCH 1/4] arm64: mm: Fix TLBI vs ASID rollover
In-Reply-To: <20210806115927.GJ6719@arm.com>
References: <20210806113109.2475-1-will@kernel.org>
 <20210806113109.2475-2-will@kernel.org>
 <20210806115927.GJ6719@arm.com>
Message-ID: <20210806124241.GA2814@willie-the-truck>

On Fri, Aug 06, 2021 at 12:59:28PM +0100, Catalin Marinas wrote:
> On Fri, Aug 06, 2021 at 12:31:04PM +0100, Will Deacon wrote:
> > diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> > index 75beffe2ee8a..e9c30859f80c 100644
> > --- a/arch/arm64/include/asm/mmu.h
> > +++ b/arch/arm64/include/asm/mmu.h
> > @@ -27,11 +27,32 @@ typedef struct {
> >  } mm_context_t;
> >  
> >  /*
> > - * This macro is only used by the TLBI and low-level switch_mm() code,
> > - * neither of which can race with an ASID change. We therefore don't
> > - * need to reload the counter using atomic64_read().
> > + * We use atomic64_read() here because the ASID for an 'mm_struct' can
> > + * be reallocated when scheduling one of its threads following a
> > + * rollover event (see new_context() and flush_context()). In this case,
> > + * a concurrent TLBI (e.g. via try_to_unmap_one() and ptep_clear_flush())
> > + * may use a stale ASID. This is fine in principle as the new ASID is
> > + * guaranteed to be clean in the TLB, but the TLBI routines have to take
> > + * care to handle the following race:
> > + *
> > + *    CPU 0                    CPU 1                          CPU 2
> > + *
> > + *    // ptep_clear_flush(mm)
> > + *    xchg_relaxed(pte, 0)
> > + *    DSB ISHST
> > + *    old = ASID(mm)
> 
> We'd need specs clarified (ARM ARM, cat model) that the DSB ISHST is
> sufficient to order the pte write with the subsequent ASID read.

Although I agree that the cat model needs updating and also that the Arm
ARM isn't helpful by trying to define DMB and DSB at the same time, it
does clearly state the following:

  // B2-149
  | A DSB instruction executed by a PE, PEe, completes when all of the
  | following apply:
  |
  | * All explicit memory accesses of the required access types appearing
  |   in program order before the DSB are complete for the set of observers
  |   in the required shareability domain.

  [...]

  // B2-150
  | In addition, no instruction that appears in program order after the
  | DSB instruction can alter any state of the system or perform any part
  | of its functionality until the DSB completes other than:
  |
  | * Being fetched from memory and decoded.
  | * Reading the general-purpose, SIMD and floating-point, Special-purpose,
  |   or System registers that are directly or indirectly read without
  |   causing side-effects.

Which means that the ASID read cannot return its data before the DSB ISHST
has completed and the DSB ISHST cannot complete until the PTE write has
completed.

> Otherwise the patch looks fine to me:
> 
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

Thanks! Do you want to queue it for 5.15? I don't think there's a need to
rush it into 5.14 given that we don't have any evidence of it happening
in practice.

Will


From linuc.decode at gmail.com  Fri Aug  6 05:44:06 2021
From: linuc.decode at gmail.com (Linu Cherian)
Date: Fri, 6 Aug 2021 18:14:06 +0530
Subject: [PATCH 07/10] arm64: Add erratum detection for TRBE overwrite in
 FILL mode
In-Reply-To: <20210728135217.591173-8-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-8-suzuki.poulose@arm.com>
Message-ID: <CAAHhmWj=dTkobukjRYmdsP_BwmVwKQrcecH4=0kOjtgo8axVaQ@mail.gmail.com>

Hi Suzuki,

On Wed, Jul 28, 2021 at 7:23 PM Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>
> Arm Neoverse-N2 and the Cortex-A710 cores are affected
> by a CPU erratum where the TRBE will overwrite the trace buffer
> in FILL mode. The TRBE doesn't stop (as expected in FILL mode)
> when it reaches the limit and wraps to the base to continue
> writing upto 3 cache lines. This will overwrite any trace that
> was written previously.
>
> Add the Neoverse-N2 erratumi(#2139208) and Cortex-A710 erratum
> (#2119858) to the  detection logic.
>
> This will be used by the TRBE driver in later patches to work
> around the issue. The detection has been kept with the core
> arm64 errata framework list to make sure :
>   - We don't duplicate the framework in TRBE driver
>   - The errata detection is advertised like the rest
>     of the CPU errata.
>
> Note that the Kconfig entries will be added after we have added
> the work around in the TRBE driver, which depends on the cpucap
> from here.
>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Mike Leach <mike.leach at linaro.org>
> cc: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
>  arch/arm64/kernel/cpu_errata.c | 25 +++++++++++++++++++++++++
>  arch/arm64/tools/cpucaps       |  1 +
>  2 files changed, 26 insertions(+)
>
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index e2c20c036442..ccd757373f36 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -340,6 +340,18 @@ static const struct midr_range erratum_1463225[] = {
>  };
>  #endif
>
> +#ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
> +static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
> +#ifdef CONFIG_ARM64_ERRATUM_2139208
> +       MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_2119858
> +       MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> +#endif
> +       {},
> +};
> +#endif /* CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE */
> +
>  const struct arm64_cpu_capabilities arm64_errata[] = {
>  #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
>         {
> @@ -533,6 +545,19 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>                 .capability = ARM64_WORKAROUND_NVIDIA_CARMEL_CNP,
>                 ERRATA_MIDR_ALL_VERSIONS(MIDR_NVIDIA_CARMEL),
>         },
> +#endif
> +#ifdef CONFIG_ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
> +       {
> +               /*
> +                * The erratum work around is handled within the TRBE
> +                * driver and can be applied per-cpu. So, we can allow
> +                * a late CPU to come online with this erratum.
> +                */
> +               .desc = "ARM erratum 2119858 or 2139208",
> +               .capability = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
> +               .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
> +               CAP_MIDR_RANGE_LIST(trbe_overwrite_fill_mode_cpus),
> +       },
>  #endif
>         {
>         }
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 49305c2e6dfd..1ccb92165bd8 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -53,6 +53,7 @@ WORKAROUND_1418040
>  WORKAROUND_1463225
>  WORKAROUND_1508412
>  WORKAROUND_1542419
> +WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>  WORKAROUND_CAVIUM_23154
>  WORKAROUND_CAVIUM_27456
>  WORKAROUND_CAVIUM_30115

We need to keep this list sorted ?

> --
> 2.24.1
>
> _______________________________________________
> CoreSight mailing list
> CoreSight at lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/coresight


From krzysztof.kozlowski at canonical.com  Fri Aug  6 05:48:11 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 6 Aug 2021 14:48:11 +0200
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <b753796c-2ce6-4166-7c20-289e950237ad@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <455cfb5e-dff7-a5c0-3875-49abe3e900f3@canonical.com>
 <CAPLW+4nDS0atrbUFagDA0W_Ky5MvOiY+N+NQoQ+me4pndp_iWg@mail.gmail.com>
 <68734f6c-fc76-595c-8d34-8924dbbbb845@canonical.com>
 <CAPLW+4n_JKj5xeBHXONcv__vyAFvx3fhXoxJa17NTHK1RSJFJw@mail.gmail.com>
 <b753796c-2ce6-4166-7c20-289e950237ad@canonical.com>
Message-ID: <bb08f7a4-1da9-fb20-f091-6a3c37a1f898@canonical.com>

On 06/08/2021 14:32, Krzysztof Kozlowski wrote:
> On 06/08/2021 14:07, Sam Protsenko wrote:
>> On Fri, 6 Aug 2021 at 10:49, Krzysztof Kozlowski
>> <krzysztof.kozlowski at canonical.com> wrote:
>>>
>>> On 06/08/2021 01:06, Sam Protsenko wrote:
>>>> On Sat, 31 Jul 2021 at 12:03, Krzysztof Kozlowski
>>>> <krzysztof.kozlowski at canonical.com> wrote:
>>>>
>>>>>>
>>>>>> This patch adds minimal SoC support. Particular board device tree files
>>>>>> can include exynos850.dtsi file to get SoC related nodes, and then
>>>>>> reference those nodes further as needed.
>>>>>>
>>>>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>>>>> ---
>>>>>>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
>>>>>>  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
>>>>>>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
>>>>>
>>>>> Not buildable. Missing Makefile, missing DTS. Please submit with initial
>>>>> DTS, otherwise no one is able to verify it even compiles.
>>>>>
>>>>
>>>> This device is not available for purchase yet. I'll send the patch for
>>>> board dts once it's announced. I can do all the testing for now, if
>>>> you have any specific requests. Would it be possible for us to review
>>>> and apply only SoC support for now? Will send v2 soon...
>>>
>>> What you propose is equal to adding a driver (C source code) without
>>> ability to compile it. What's the point of having it in the kernel? It's
>>> unverifiable, unbuildable and unusable.
>>>
>>
>> Yes, I understand. That's adding code with no users, and it's not a
>> good practice.
>>
>>> We can review the DTSI however merging has to be with a DTS. Usually the
>>> SoC vendor adds first an evalkit (e.g. SMDK board). Maybe you have one
>>> for Exynos850? Otherwise if you cannot disclose the actual board, the
>>> DTSI will have to wait. You can submit drivers, though.
>>>
>>
>> Sure, let's go this way. I'll send v2 soon. Improving patches and
>> having Reviewed-by tag for those would good enough for me at this
>> point. I'll continue to prepare another Exynos850 related patches
>> until the actual board is announced, like proper clock driver, reset,
>> MMC, etc. Is it ok if I send those for a review too (so I can fix all
>> issues ahead)?
> 
> Sure, prepare all necessary drivers earlier. I suspect clocks will be a
> real pain because of significant changes modeled in vendor kernel. I
> remember Pawe? Chmiel (+Cc) was doing something for these:
> https://github.com/PabloPL/linux/tree/exynos7420
> 
> I mentioned before - you should also modify the chipid driver. Check
> also other drivers in drivers/soc/samsung, although some are needed only
> for suspend&resume.
> 

You can also take a look at Exynos8895 efforts:
https://github.com/ivoszbg/linux/commits/for-upstream/exynos8895

Since knowledge, datasheets and efforts are quite spread all over, I
keep track of some work here:
https://exynos.wiki.kernel.org/community


Best regards,
Krzysztof


From vkoul at kernel.org  Fri Aug  6 05:48:20 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:18:20 +0530
Subject: [PATCH v2 0/6] arm64: IPQ6018 PCIe support
In-Reply-To: <20210805094237.GA18330@lpieralisi>
References: <cover.1620203062.git.baruch@tkos.co.il> <87o8acxtqm.fsf@tarshish>
 <20210805094237.GA18330@lpieralisi>
Message-ID: <YQ0vlNekc289LqJl@matsya>

On 05-08-21, 10:42, Lorenzo Pieralisi wrote:
> On Thu, Aug 05, 2021 at 09:58:57AM +0300, Baruch Siach wrote:
> > Hi Lorenzo, Rob, Krzysztof,
> > 
> > On Wed, May 05 2021, Baruch Siach wrote:
> > > This series adds support for the single PCIe lane on IPQ6018 SoCs. The code is 
> > > ported from downstream Codeaurora v5.4 kernel. The main difference from 
> > > downstream code is the split of PCIe registers configuration from .init to 
> > > .post_init, since it requires phy_power_on().
> > >
> > > Tested on IPQ6010 based hardware.
> > 
> > It's been 3 months with no comment. Would you consider applying the dwc
> > part (patches #1 and #2) for the v5.15 merge window?
> > 
> > I tested the patches here successfully on top of v5.14-rc4.
> 
> You need an ACK from the respective drivers maintainers. We look into
> overall pci/controller drivers structure and common code, it is up
> to drivers maintainers to review and ACK your patches, I will certainly
> pick them up when that's done.

Also is there any dependency b/w various pieces, if not consider sending
patches to respective subsystems...

Too many patch series these days are adding cross subsystem stuff even
if there are no dependencies. Yes it all needs to come together to work
but that does not require a common series to be posted!

-- 
~Vinod


From catalin.marinas at arm.com  Fri Aug  6 05:49:44 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 6 Aug 2021 13:49:44 +0100
Subject: [PATCH 1/4] arm64: mm: Fix TLBI vs ASID rollover
In-Reply-To: <20210806124241.GA2814@willie-the-truck>
References: <20210806113109.2475-1-will@kernel.org>
 <20210806113109.2475-2-will@kernel.org>
 <20210806115927.GJ6719@arm.com>
 <20210806124241.GA2814@willie-the-truck>
Message-ID: <20210806124944.GK6719@arm.com>

On Fri, Aug 06, 2021 at 01:42:42PM +0100, Will Deacon wrote:
> On Fri, Aug 06, 2021 at 12:59:28PM +0100, Catalin Marinas wrote:
> > On Fri, Aug 06, 2021 at 12:31:04PM +0100, Will Deacon wrote:
> > > diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> > > index 75beffe2ee8a..e9c30859f80c 100644
> > > --- a/arch/arm64/include/asm/mmu.h
> > > +++ b/arch/arm64/include/asm/mmu.h
> > > @@ -27,11 +27,32 @@ typedef struct {
> > >  } mm_context_t;
> > >  
> > >  /*
> > > - * This macro is only used by the TLBI and low-level switch_mm() code,
> > > - * neither of which can race with an ASID change. We therefore don't
> > > - * need to reload the counter using atomic64_read().
> > > + * We use atomic64_read() here because the ASID for an 'mm_struct' can
> > > + * be reallocated when scheduling one of its threads following a
> > > + * rollover event (see new_context() and flush_context()). In this case,
> > > + * a concurrent TLBI (e.g. via try_to_unmap_one() and ptep_clear_flush())
> > > + * may use a stale ASID. This is fine in principle as the new ASID is
> > > + * guaranteed to be clean in the TLB, but the TLBI routines have to take
> > > + * care to handle the following race:
> > > + *
> > > + *    CPU 0                    CPU 1                          CPU 2
> > > + *
> > > + *    // ptep_clear_flush(mm)
> > > + *    xchg_relaxed(pte, 0)
> > > + *    DSB ISHST
> > > + *    old = ASID(mm)
> > 
> > We'd need specs clarified (ARM ARM, cat model) that the DSB ISHST is
> > sufficient to order the pte write with the subsequent ASID read.
> 
> Although I agree that the cat model needs updating and also that the Arm
> ARM isn't helpful by trying to define DMB and DSB at the same time, it
> does clearly state the following:
> 
>   // B2-149
>   | A DSB instruction executed by a PE, PEe, completes when all of the
>   | following apply:
>   |
>   | * All explicit memory accesses of the required access types appearing
>   |   in program order before the DSB are complete for the set of observers
>   |   in the required shareability domain.
> 
>   [...]
> 
>   // B2-150
>   | In addition, no instruction that appears in program order after the
>   | DSB instruction can alter any state of the system or perform any part
>   | of its functionality until the DSB completes other than:
>   |
>   | * Being fetched from memory and decoded.
>   | * Reading the general-purpose, SIMD and floating-point, Special-purpose,
>   |   or System registers that are directly or indirectly read without
>   |   causing side-effects.
> 
> Which means that the ASID read cannot return its data before the DSB ISHST
> has completed and the DSB ISHST cannot complete until the PTE write has
> completed.

Thanks for the explanation.

> > Otherwise the patch looks fine to me:
> > 
> > Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
> 
> Thanks! Do you want to queue it for 5.15? I don't think there's a need to
> rush it into 5.14 given that we don't have any evidence of it happening
> in practice.

Happy to queue it for 5.15.

-- 
Catalin


From rafael at kernel.org  Fri Aug  6 06:03:17 2021
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Fri, 6 Aug 2021 15:03:17 +0200
Subject: [PATCH v2] memblock: make memblock_find_in_range method private
In-Reply-To: <20210802063737.22733-1-rppt@kernel.org>
References: <20210802063737.22733-1-rppt@kernel.org>
Message-ID: <CAJZ5v0gPEcEy4T8EGCMOw6w+RfU6PBV4EAU+BVHzkTuB1NUjCQ@mail.gmail.com>

On Mon, Aug 2, 2021 at 8:37 AM Mike Rapoport <rppt at kernel.org> wrote:
>
> From: Mike Rapoport <rppt at linux.ibm.com>
>
> There are a lot of uses of memblock_find_in_range() along with
> memblock_reserve() from the times memblock allocation APIs did not exist.
>
> memblock_find_in_range() is the very core of memblock allocations, so any
> future changes to its internal behaviour would mandate updates of all the
> users outside memblock.
>
> Replace the calls to memblock_find_in_range() with an equivalent calls to
> memblock_phys_alloc() and memblock_phys_alloc_range() and make
> memblock_find_in_range() private method of memblock.
>
> This simplifies the callers, ensures that (unlikely) errors in
> memblock_reserve() are handled and improves maintainability of
> memblock_find_in_range().
>
> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>

For the ACPI part:

Acked-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>

> ---
> v2: don't change error message in arm::reserve_crashkernel(), per Russell
> v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org
>
>  arch/arm/kernel/setup.c           | 18 +++++--------
>  arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
>  arch/arm64/mm/init.c              | 36 ++++++++-----------------
>  arch/mips/kernel/setup.c          | 14 +++++-----
>  arch/riscv/mm/init.c              | 44 ++++++++++---------------------
>  arch/s390/kernel/setup.c          | 10 ++++---
>  arch/x86/kernel/aperture_64.c     |  5 ++--
>  arch/x86/mm/init.c                | 21 +++++++++------
>  arch/x86/mm/numa.c                |  5 ++--
>  arch/x86/mm/numa_emulation.c      |  5 ++--
>  arch/x86/realmode/init.c          |  2 +-
>  drivers/acpi/tables.c             |  5 ++--
>  drivers/base/arch_numa.c          |  5 +---
>  drivers/of/of_reserved_mem.c      | 12 ++++++---
>  include/linux/memblock.h          |  2 --
>  mm/memblock.c                     |  2 +-
>  16 files changed, 78 insertions(+), 117 deletions(-)
>
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index f97eb2371672..67f5421b2af7 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
>                 unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
>                 if (crash_max > lowmem_max)
>                         crash_max = lowmem_max;
> -               crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
> -                                                   crash_size, CRASH_ALIGN);
> +
> +               crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> +                                                      CRASH_ALIGN, crash_max);
>                 if (!crash_base) {
>                         pr_err("crashkernel reservation failed - No suitable area found.\n");
>                         return;
>                 }
>         } else {
> +               unsigned long long crash_max = crash_base + crash_size;
>                 unsigned long long start;
>
> -               start = memblock_find_in_range(crash_base,
> -                                              crash_base + crash_size,
> -                                              crash_size, SECTION_SIZE);
> +               start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
> +                                                 crash_base, crash_max);
>                 if (start != crash_base) {
>                         pr_err("crashkernel reservation failed - memory is in use.\n");
>                         return;
>                 }
>         }
>
> -       ret = memblock_reserve(crash_base, crash_size);
> -       if (ret < 0) {
> -               pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
> -                       (unsigned long)crash_base);
> -               return;
> -       }
> -
>         pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
>                 (unsigned long)(crash_size >> 20),
>                 (unsigned long)(crash_base >> 20),
> diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c
> index d654921dd09b..578670e3f608 100644
> --- a/arch/arm64/kvm/hyp/reserved_mem.c
> +++ b/arch/arm64/kvm/hyp/reserved_mem.c
> @@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
>          * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
>          */
>         hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
> -       hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> -                                             ALIGN(hyp_mem_size, PMD_SIZE),
> -                                             PMD_SIZE);
> +       hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
> +                                          PMD_SIZE);
>         if (!hyp_mem_base)
> -               hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> -                                                     hyp_mem_size, PAGE_SIZE);
> +               hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
>         else
>                 hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
>
> @@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
>                 kvm_err("Failed to reserve hyp memory\n");
>                 return;
>         }
> -       memblock_reserve(hyp_mem_base, hyp_mem_size);
>
>         kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
>                  hyp_mem_base);
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 8490ed2917ff..d566478a06dd 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>  static void __init reserve_crashkernel(void)
>  {
>         unsigned long long crash_base, crash_size;
> +       unsigned long crash_max = arm64_dma_phys_limit;
>         int ret;
>
>         ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> @@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
>
>         crash_size = PAGE_ALIGN(crash_size);
>
> -       if (crash_base == 0) {
> -               /* Current arm64 boot protocol requires 2MB alignment */
> -               crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
> -                               crash_size, SZ_2M);
> -               if (crash_base == 0) {
> -                       pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> -                               crash_size);
> -                       return;
> -               }
> -       } else {
> -               /* User specifies base address explicitly. */
> -               if (!memblock_is_region_memory(crash_base, crash_size)) {
> -                       pr_warn("cannot reserve crashkernel: region is not memory\n");
> -                       return;
> -               }
> +       /* User specifies base address explicitly. */
> +       if (crash_base)
> +               crash_max = crash_base + crash_size;
>
> -               if (memblock_is_region_reserved(crash_base, crash_size)) {
> -                       pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
> -                       return;
> -               }
> -
> -               if (!IS_ALIGNED(crash_base, SZ_2M)) {
> -                       pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
> -                       return;
> -               }
> +       /* Current arm64 boot protocol requires 2MB alignment */
> +       crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> +                                              crash_base, crash_max);
> +       if (!crash_base) {
> +               pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> +                       crash_size);
> +               return;
>         }
> -       memblock_reserve(crash_base, crash_size);
>
>         pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>                 crash_base, crash_base + crash_size, crash_size >> 20);
> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> index 23a140327a0b..f979adfd4fc2 100644
> --- a/arch/mips/kernel/setup.c
> +++ b/arch/mips/kernel/setup.c
> @@ -452,8 +452,9 @@ static void __init mips_parse_crashkernel(void)
>                 return;
>
>         if (crash_base <= 0) {
> -               crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX,
> -                                                       crash_size, CRASH_ALIGN);
> +               crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> +                                                      CRASH_ALIGN,
> +                                                      CRASH_ADDR_MAX);
>                 if (!crash_base) {
>                         pr_warn("crashkernel reservation failed - No suitable area found.\n");
>                         return;
> @@ -461,8 +462,9 @@ static void __init mips_parse_crashkernel(void)
>         } else {
>                 unsigned long long start;
>
> -               start = memblock_find_in_range(crash_base, crash_base + crash_size,
> -                                               crash_size, 1);
> +               start = memblock_phys_alloc_range(crash_size, 1,
> +                                                 crash_base,
> +                                                 crash_base + crash_size);
>                 if (start != crash_base) {
>                         pr_warn("Invalid memory region reserved for crash kernel\n");
>                         return;
> @@ -656,10 +658,6 @@ static void __init arch_mem_init(char **cmdline_p)
>         mips_reserve_vmcore();
>
>         mips_parse_crashkernel();
> -#ifdef CONFIG_KEXEC
> -       if (crashk_res.start != crashk_res.end)
> -               memblock_reserve(crashk_res.start, resource_size(&crashk_res));
> -#endif
>         device_tree_init();
>
>         /*
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index a14bf3910eec..88649337c568 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -812,38 +812,22 @@ static void __init reserve_crashkernel(void)
>
>         crash_size = PAGE_ALIGN(crash_size);
>
> -       if (crash_base == 0) {
> -               /*
> -                * Current riscv boot protocol requires 2MB alignment for
> -                * RV64 and 4MB alignment for RV32 (hugepage size)
> -                */
> -               crash_base = memblock_find_in_range(search_start, search_end,
> -                                                   crash_size, PMD_SIZE);
> -
> -               if (crash_base == 0) {
> -                       pr_warn("crashkernel: couldn't allocate %lldKB\n",
> -                               crash_size >> 10);
> -                       return;
> -               }
> -       } else {
> -               /* User specifies base address explicitly. */
> -               if (!memblock_is_region_memory(crash_base, crash_size)) {
> -                       pr_warn("crashkernel: requested region is not memory\n");
> -                       return;
> -               }
> -
> -               if (memblock_is_region_reserved(crash_base, crash_size)) {
> -                       pr_warn("crashkernel: requested region is reserved\n");
> -                       return;
> -               }
> -
> +       if (crash_base) {
> +               search_start = crash_base;
> +               search_end = crash_base + crash_size;
> +       }
>
> -               if (!IS_ALIGNED(crash_base, PMD_SIZE)) {
> -                       pr_warn("crashkernel: requested region is misaligned\n");
> -                       return;
> -               }
> +       /*
> +        * Current riscv boot protocol requires 2MB alignment for
> +        * RV64 and 4MB alignment for RV32 (hugepage size)
> +        */
> +       crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
> +                                              search_start, search_end);
> +       if (crash_base == 0) {
> +               pr_warn("crashkernel: couldn't allocate %lldKB\n",
> +                       crash_size >> 10);
> +               return;
>         }
> -       memblock_reserve(crash_base, crash_size);
>
>         pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n",
>                 crash_base, crash_base + crash_size, crash_size >> 20);
> diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
> index ff0f9e838916..3d9efee0f43c 100644
> --- a/arch/s390/kernel/setup.c
> +++ b/arch/s390/kernel/setup.c
> @@ -626,8 +626,9 @@ static void __init reserve_crashkernel(void)
>                         return;
>                 }
>                 low = crash_base ?: low;
> -               crash_base = memblock_find_in_range(low, high, crash_size,
> -                                                   KEXEC_CRASH_MEM_ALIGN);
> +               crash_base = memblock_phys_alloc_range(crash_size,
> +                                                      KEXEC_CRASH_MEM_ALIGN,
> +                                                      low, high);
>         }
>
>         if (!crash_base) {
> @@ -636,14 +637,15 @@ static void __init reserve_crashkernel(void)
>                 return;
>         }
>
> -       if (register_memory_notifier(&kdump_mem_nb))
> +       if (register_memory_notifier(&kdump_mem_nb)) {
> +               memblock_free(crash_base, crash_size);
>                 return;
> +       }
>
>         if (!OLDMEM_BASE && MACHINE_IS_VM)
>                 diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
>         crashk_res.start = crash_base;
>         crashk_res.end = crash_base + crash_size - 1;
> -       memblock_remove(crash_base, crash_size);
>         pr_info("Reserving %lluMB of memory at %lluMB "
>                 "for crashkernel (System RAM: %luMB)\n",
>                 crash_size >> 20, crash_base >> 20,
> diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
> index 294ed4392a0e..10562885f5fc 100644
> --- a/arch/x86/kernel/aperture_64.c
> +++ b/arch/x86/kernel/aperture_64.c
> @@ -109,14 +109,13 @@ static u32 __init allocate_aperture(void)
>          * memory. Unfortunately we cannot move it up because that would
>          * make the IOMMU useless.
>          */
> -       addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR,
> -                                     aper_size, aper_size);
> +       addr = memblock_phys_alloc_range(aper_size, aper_size,
> +                                        GART_MIN_ADDR, GART_MAX_ADDR);
>         if (!addr) {
>                 pr_err("Cannot allocate aperture memory hole [mem %#010lx-%#010lx] (%uKB)\n",
>                        addr, addr + aper_size - 1, aper_size >> 10);
>                 return 0;
>         }
> -       memblock_reserve(addr, aper_size);
>         pr_info("Mapping aperture over RAM [mem %#010lx-%#010lx] (%uKB)\n",
>                 addr, addr + aper_size - 1, aper_size >> 10);
>         register_nosave_region(addr >> PAGE_SHIFT,
> diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
> index 75ef19aa8903..1152a29ce109 100644
> --- a/arch/x86/mm/init.c
> +++ b/arch/x86/mm/init.c
> @@ -26,6 +26,7 @@
>  #include <asm/pti.h>
>  #include <asm/text-patching.h>
>  #include <asm/memtype.h>
> +#include <xen/xen.h>
>
>  /*
>   * We need to define the tracepoints somewhere, and tlb.c
> @@ -127,14 +128,12 @@ __ref void *alloc_low_pages(unsigned int num)
>                 unsigned long ret = 0;
>
>                 if (min_pfn_mapped < max_pfn_mapped) {
> -                       ret = memblock_find_in_range(
> +                       ret = memblock_phys_alloc_range(
> +                                       PAGE_SIZE * num, PAGE_SIZE,
>                                         min_pfn_mapped << PAGE_SHIFT,
> -                                       max_pfn_mapped << PAGE_SHIFT,
> -                                       PAGE_SIZE * num , PAGE_SIZE);
> +                                       max_pfn_mapped << PAGE_SHIFT);
>                 }
> -               if (ret)
> -                       memblock_reserve(ret, PAGE_SIZE * num);
> -               else if (can_use_brk_pgt)
> +               if (!ret && can_use_brk_pgt)
>                         ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE));
>
>                 if (!ret)
> @@ -610,9 +609,15 @@ static void __init memory_map_top_down(unsigned long map_start,
>         unsigned long addr;
>         unsigned long mapped_ram_size = 0;
>
> +       real_end = ALIGN_DOWN(map_end, PMD_SIZE);
> +
>         /* xen has big range in reserved near end of ram, skip it at first.*/
> -       addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE);
> -       real_end = addr + PMD_SIZE;
> +       if (xen_domain()) {
> +               addr = memblock_phys_alloc_range(PMD_SIZE, PMD_SIZE,
> +                                                map_start, map_end);
> +               memblock_free(addr, PMD_SIZE);
> +               real_end = addr + PMD_SIZE;
> +       }
>
>         /* step_size need to be small so pgt_buf from BRK could cover it */
>         step_size = PMD_SIZE;
> diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
> index e94da744386f..a1b5c71099e6 100644
> --- a/arch/x86/mm/numa.c
> +++ b/arch/x86/mm/numa.c
> @@ -376,15 +376,14 @@ static int __init numa_alloc_distance(void)
>         cnt++;
>         size = cnt * cnt * sizeof(numa_distance[0]);
>
> -       phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
> -                                     size, PAGE_SIZE);
> +       phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0,
> +                                        PFN_PHYS(max_pfn_mapped));
>         if (!phys) {
>                 pr_warn("Warning: can't allocate distance table!\n");
>                 /* don't retry until explicitly reset */
>                 numa_distance = (void *)1LU;
>                 return -ENOMEM;
>         }
> -       memblock_reserve(phys, size);
>
>         numa_distance = __va(phys);
>         numa_distance_cnt = cnt;
> diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
> index 87d77cc52f86..737491b13728 100644
> --- a/arch/x86/mm/numa_emulation.c
> +++ b/arch/x86/mm/numa_emulation.c
> @@ -447,13 +447,12 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
>         if (numa_dist_cnt) {
>                 u64 phys;
>
> -               phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
> -                                             phys_size, PAGE_SIZE);
> +               phys = memblock_phys_alloc_range(phys_size, PAGE_SIZE, 0,
> +                                                PFN_PHYS(max_pfn_mapped));
>                 if (!phys) {
>                         pr_warn("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
>                         goto no_emu;
>                 }
> -               memblock_reserve(phys, phys_size);
>                 phys_dist = __va(phys);
>
>                 for (i = 0; i < numa_dist_cnt; i++)
> diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
> index 6534c92d0f83..31b5856010cb 100644
> --- a/arch/x86/realmode/init.c
> +++ b/arch/x86/realmode/init.c
> @@ -28,7 +28,7 @@ void __init reserve_real_mode(void)
>         WARN_ON(slab_is_available());
>
>         /* Has to be under 1M so we can execute real-mode AP code. */
> -       mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
> +       mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
>         if (!mem)
>                 pr_info("No sub-1M memory is available for the trampoline\n");
>         else
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index a37a1532a575..f9383736fa0f 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -583,8 +583,8 @@ void __init acpi_table_upgrade(void)
>         }
>
>         acpi_tables_addr =
> -               memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
> -                                      all_tables_size, PAGE_SIZE);
> +               memblock_phys_alloc_range(all_tables_size, PAGE_SIZE,
> +                                         0, ACPI_TABLE_UPGRADE_MAX_PHYS);
>         if (!acpi_tables_addr) {
>                 WARN_ON(1);
>                 return;
> @@ -599,7 +599,6 @@ void __init acpi_table_upgrade(void)
>          * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
>          * works fine.
>          */
> -       memblock_reserve(acpi_tables_addr, all_tables_size);
>         arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
>
>         /*
> diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
> index 4cc4e117727d..46c503486e96 100644
> --- a/drivers/base/arch_numa.c
> +++ b/drivers/base/arch_numa.c
> @@ -279,13 +279,10 @@ static int __init numa_alloc_distance(void)
>         int i, j;
>
>         size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
> -       phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
> -                                     size, PAGE_SIZE);
> +       phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, PFN_PHYS(max_pfn));
>         if (WARN_ON(!phys))
>                 return -ENOMEM;
>
> -       memblock_reserve(phys, size);
> -
>         numa_distance = __va(phys);
>         numa_distance_cnt = nr_node_ids;
>
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> index fd3964d24224..59c1390cdf42 100644
> --- a/drivers/of/of_reserved_mem.c
> +++ b/drivers/of/of_reserved_mem.c
> @@ -33,18 +33,22 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
>         phys_addr_t *res_base)
>  {
>         phys_addr_t base;
> +       int err = 0;
>
>         end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
>         align = !align ? SMP_CACHE_BYTES : align;
> -       base = memblock_find_in_range(start, end, size, align);
> +       base = memblock_phys_alloc_range(size, align, start, end);
>         if (!base)
>                 return -ENOMEM;
>
>         *res_base = base;
> -       if (nomap)
> -               return memblock_mark_nomap(base, size);
> +       if (nomap) {
> +               err = memblock_mark_nomap(base, size);
> +               if (err)
> +                       memblock_free(base, size);
> +       }
>
> -       return memblock_reserve(base, size);
> +       return err;
>  }
>
>  /*
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index 4a53c3ca86bd..b066024c62e3 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -99,8 +99,6 @@ void memblock_discard(void);
>  static inline void memblock_discard(void) {}
>  #endif
>
> -phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
> -                                  phys_addr_t size, phys_addr_t align);
>  void memblock_allow_resize(void);
>  int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
>  int memblock_add(phys_addr_t base, phys_addr_t size);
> diff --git a/mm/memblock.c b/mm/memblock.c
> index de7b553baa50..28a813d9e955 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -315,7 +315,7 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
>   * Return:
>   * Found address on success, 0 on failure.
>   */
> -phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
> +static phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
>                                         phys_addr_t end, phys_addr_t size,
>                                         phys_addr_t align)
>  {
>
> base-commit: ff1176468d368232b684f75e82563369208bc371
> --
> 2.28.0
>


From vkoul at kernel.org  Fri Aug  6 06:05:09 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:35:09 +0530
Subject: [PATCH v2 1/6] dt-bindings: phy: qcom,qmp: Add IPQ6018 USB3 PHY
In-Reply-To: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
Message-ID: <YQ0zhaTVI8KVNpVR@matsya>

On 04-08-21, 17:05, Baruch Siach wrote:
> Add compatible string for USB3 PHY in Qualcomm IPQ6018 SoC.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Fri Aug  6 06:05:23 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Fri, 6 Aug 2021 18:35:23 +0530
Subject: [PATCH v2 2/6] phy: qcom-qmp: add USB3 PHY support for IPQ6018
In-Reply-To: <6eec7ef4ecd1e8360ebe8e425151121684e997ed.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <6eec7ef4ecd1e8360ebe8e425151121684e997ed.1628085910.git.baruch@tkos.co.il>
Message-ID: <YQ0zk44peRTsbLnu@matsya>

On 04-08-21, 17:05, Baruch Siach wrote:
> Initialization is identical to the IPQ8074 USB3 PHY.

Applied, thanks

-- 
~Vinod


From ulf.hansson at linaro.org  Fri Aug  6 06:06:00 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Fri, 6 Aug 2021 15:06:00 +0200
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <20210730063309.8194-3-rashmi.a@intel.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
Message-ID: <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>

On Fri, 30 Jul 2021 at 08:33, <rashmi.a at intel.com> wrote:
>
> From: Rashmi A <rashmi.a at intel.com>
>
> Intel Thunder Bay SoC eMMC controller is based on Arasan
> eMMC 5.1 host controller IP
>
> Signed-off-by: Rashmi A <rashmi.a at intel.com>
> Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>

Rashmi, is it safe to apply this separately from the phy driver/dt
changes? Then I can queue this via my mmc tree, if you like.

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci-of-arasan.c | 29 ++++++++++++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
> index 839965f7c717..6f202fb7a546 100644
> --- a/drivers/mmc/host/sdhci-of-arasan.c
> +++ b/drivers/mmc/host/sdhci-of-arasan.c
> @@ -185,6 +185,13 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = {
>         .hiword_update = false,
>  };
>
> +static const struct sdhci_arasan_soc_ctl_map thunderbay_soc_ctl_map = {
> +       .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
> +       .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
> +       .support64b = { .reg = 0x4, .width = 1, .shift = 24 },
> +       .hiword_update = false,
> +};
> +
>  static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = {
>         .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
>         .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
> @@ -430,6 +437,15 @@ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = {
>                         SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
>  };
>
> +static const struct sdhci_pltfm_data sdhci_arasan_thunderbay_pdata = {
> +       .ops = &sdhci_arasan_cqe_ops,
> +       .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
> +       .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
> +               SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
> +               SDHCI_QUIRK2_STOP_WITH_TC |
> +               SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400,
> +};
> +
>  #ifdef CONFIG_PM_SLEEP
>  /**
>   * sdhci_arasan_suspend - Suspend method for the driver
> @@ -1098,6 +1114,12 @@ static struct sdhci_arasan_of_data sdhci_arasan_generic_data = {
>         .clk_ops = &arasan_clk_ops,
>  };
>
> +static const struct sdhci_arasan_of_data sdhci_arasan_thunderbay_data = {
> +       .soc_ctl_map = &thunderbay_soc_ctl_map,
> +       .pdata = &sdhci_arasan_thunderbay_pdata,
> +       .clk_ops = &arasan_clk_ops,
> +};
> +
>  static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = {
>         .ops = &sdhci_arasan_cqe_ops,
>         .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
> @@ -1231,6 +1253,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
>                 .compatible = "intel,keembay-sdhci-5.1-sdio",
>                 .data = &intel_keembay_sdio_data,
>         },
> +       {
> +               .compatible = "intel,thunderbay-sdhci-5.1",
> +               .data = &sdhci_arasan_thunderbay_data,
> +       },
>         /* Generic compatible below here */
>         {
>                 .compatible = "arasan,sdhci-8.9a",
> @@ -1582,7 +1608,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
>
>         if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
>             of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
> -           of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {
> +           of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio") ||
> +           of_device_is_compatible(np, "intel,thunderbay-sdhci-5.1")) {
>                 sdhci_arasan_update_clockmultiplier(host, 0x0);
>                 sdhci_arasan_update_support64b(host, 0x0);
>
> --
> 2.17.1
>


From lingshan.zhu at intel.com  Fri Aug  6 06:37:45 2021
From: lingshan.zhu at intel.com (Zhu Lingshan)
Date: Fri,  6 Aug 2021 21:37:45 +0800
Subject: [PATCH V10 01/18] perf/core: Use static_call to optimize
 perf_guest_info_callbacks
In-Reply-To: <20210806133802.3528-1-lingshan.zhu@intel.com>
References: <20210806133802.3528-1-lingshan.zhu@intel.com>
Message-ID: <20210806133802.3528-2-lingshan.zhu@intel.com>

From: Like Xu <like.xu at linux.intel.com>

For "struct perf_guest_info_callbacks", the two fields "is_in_guest"
and "is_user_mode" are replaced with a new multiplexed member named
"state", and the "get_guest_ip" field will be renamed to "get_ip".

For arm64, xen and kvm/x86, the application of DEFINE_STATIC_CALL_RET0
could make all that perf_guest_cbs stuff suck less. For arm, csky, nds32,
and riscv, just applied some renamed refactoring.

Cc: Will Deacon <will at kernel.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Guo Ren <guoren at kernel.org>
Cc: Nick Hu <nickhu at andestech.com>
Cc: Paul Walmsley <paul.walmsley at sifive.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-csky at vger.kernel.org
Cc: linux-riscv at lists.infradead.org
Cc: xen-devel at lists.xenproject.org
Suggested-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Original-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Signed-off-by: Like Xu <like.xu at linux.intel.com>
Signed-off-by: Zhu Lingshan <lingshan.zhu at intel.com>
Reviewed-by: Boris Ostrovsky <boris.ostrvsky at oracle.com>
Acked-by: Peter Zijlstra (Intel) <peterz at infradead.org>
---
 arch/arm/kernel/perf_callchain.c   | 16 +++++++-----
 arch/arm64/kernel/perf_callchain.c | 29 +++++++++++++++++-----
 arch/arm64/kvm/perf.c              | 22 ++++++++---------
 arch/csky/kernel/perf_callchain.c  |  4 +--
 arch/nds32/kernel/perf_event_cpu.c | 16 +++++++-----
 arch/riscv/kernel/perf_callchain.c |  4 +--
 arch/x86/events/core.c             | 39 ++++++++++++++++++++++++------
 arch/x86/events/intel/core.c       |  7 +++---
 arch/x86/include/asm/kvm_host.h    |  2 +-
 arch/x86/kvm/pmu.c                 |  2 +-
 arch/x86/kvm/x86.c                 | 37 +++++++++++++++-------------
 arch/x86/xen/pmu.c                 | 33 ++++++++++---------------
 include/linux/perf_event.h         | 12 ++++++---
 kernel/events/core.c               |  9 +++++++
 14 files changed, 144 insertions(+), 88 deletions(-)

diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c
index 3b69a76d341e..1ce30f86d6c7 100644
--- a/arch/arm/kernel/perf_callchain.c
+++ b/arch/arm/kernel/perf_callchain.c
@@ -64,7 +64,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 {
 	struct frame_tail __user *tail;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (perf_guest_cbs && perf_guest_cbs->state()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -100,7 +100,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
 {
 	struct stackframe fr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (perf_guest_cbs && perf_guest_cbs->state()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -111,8 +111,8 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	if (perf_guest_cbs && perf_guest_cbs->state())
+		return perf_guest_cbs->get_ip();
 
 	return instruction_pointer(regs);
 }
@@ -120,9 +120,13 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
 	int misc = 0;
+	unsigned int state = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (perf_guest_cbs)
+		state = perf_guest_cbs->state();
+
+	if (perf_guest_cbs && state) {
+		if (state & PERF_GUEST_USER)
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 4a72c2727309..1b344e23fd2f 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2015 ARM Limited
  */
 #include <linux/perf_event.h>
+#include <linux/static_call.h>
 #include <linux/uaccess.h>
 
 #include <asm/pointer_auth.h>
@@ -99,10 +100,25 @@ compat_user_backtrace(struct compat_frame_tail __user *tail,
 }
 #endif /* CONFIG_COMPAT */
 
+DEFINE_STATIC_CALL_RET0(arm64_guest_state, *(perf_guest_cbs->state));
+DEFINE_STATIC_CALL_RET0(arm64_guest_get_ip, *(perf_guest_cbs->get_ip));
+
+void arch_perf_update_guest_cbs(void)
+{
+	static_call_update(arm64_guest_state, (void *)&__static_call_return0);
+	static_call_update(arm64_guest_get_ip, (void *)&__static_call_return0);
+
+	if (perf_guest_cbs && perf_guest_cbs->state)
+		static_call_update(arm64_guest_state, perf_guest_cbs->state);
+
+	if (perf_guest_cbs && perf_guest_cbs->get_ip)
+		static_call_update(arm64_guest_get_ip, perf_guest_cbs->get_ip);
+}
+
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (static_call(arm64_guest_state)()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -149,7 +165,7 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 {
 	struct stackframe frame;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (static_call(arm64_guest_state)()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -160,8 +176,8 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	if (static_call(arm64_guest_state)())
+		return static_call(arm64_guest_get_ip)();
 
 	return instruction_pointer(regs);
 }
@@ -169,9 +185,10 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
 	int misc = 0;
+	unsigned int guest = static_call(arm64_guest_state)();
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (guest) {
+		if (guest & PERF_GUEST_USER)
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 151c31fb9860..8a3387e58f42 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -13,21 +13,20 @@
 
 DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
 
-static int kvm_is_in_guest(void)
-{
-        return kvm_get_running_vcpu() != NULL;
-}
-
-static int kvm_is_user_mode(void)
+static unsigned int kvm_guest_state(void)
 {
 	struct kvm_vcpu *vcpu;
+	unsigned int state = 0;
+
+	if (kvm_get_running_vcpu())
+		state |= PERF_GUEST_ACTIVE;
 
 	vcpu = kvm_get_running_vcpu();
 
-	if (vcpu)
-		return !vcpu_mode_priv(vcpu);
+	if (vcpu && !vcpu_mode_priv(vcpu))
+		state |= PERF_GUEST_USER;
 
-	return 0;
+	return state;
 }
 
 static unsigned long kvm_get_guest_ip(void)
@@ -43,9 +42,8 @@ static unsigned long kvm_get_guest_ip(void)
 }
 
 static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.is_in_guest	= kvm_is_in_guest,
-	.is_user_mode	= kvm_is_user_mode,
-	.get_guest_ip	= kvm_get_guest_ip,
+	.state		= kvm_guest_state,
+	.get_ip		= kvm_get_guest_ip,
 };
 
 int kvm_perf_init(void)
diff --git a/arch/csky/kernel/perf_callchain.c b/arch/csky/kernel/perf_callchain.c
index ab55e98ee8f6..3e42239dd1b2 100644
--- a/arch/csky/kernel/perf_callchain.c
+++ b/arch/csky/kernel/perf_callchain.c
@@ -89,7 +89,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 	unsigned long fp = 0;
 
 	/* C-SKY does not support virtualization. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+	if (perf_guest_cbs && perf_guest_cbs->state())
 		return;
 
 	fp = regs->regs[4];
@@ -113,7 +113,7 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 	struct stackframe fr;
 
 	/* C-SKY does not support virtualization. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (perf_guest_cbs && perf_guest_cbs->state()) {
 		pr_warn("C-SKY does not support perf in guest mode!");
 		return;
 	}
diff --git a/arch/nds32/kernel/perf_event_cpu.c b/arch/nds32/kernel/perf_event_cpu.c
index 0ce6f9f307e6..1dc32ba842ce 100644
--- a/arch/nds32/kernel/perf_event_cpu.c
+++ b/arch/nds32/kernel/perf_event_cpu.c
@@ -1371,7 +1371,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 
 	leaf_fp = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (perf_guest_cbs && perf_guest_cbs->state()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -1481,7 +1481,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 {
 	struct stackframe fr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (perf_guest_cbs && perf_guest_cbs->state()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -1494,8 +1494,8 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
 	/* However, NDS32 does not support virtualization */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	if (perf_guest_cbs && perf_guest_cbs->state())
+		return perf_guest_cbs->get_ip();
 
 	return instruction_pointer(regs);
 }
@@ -1503,10 +1503,14 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
 	int misc = 0;
+	unsigned int state = 0;
+
+	if (perf_guest_cbs)
+		state = perf_guest_cbs->state();
 
 	/* However, NDS32 does not support virtualization */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (perf_guest_cbs && state) {
+		if (state & PERF_GUEST_USER)
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
index 0bb1854dce83..ea63f70cae5d 100644
--- a/arch/riscv/kernel/perf_callchain.c
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -59,7 +59,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 	unsigned long fp = 0;
 
 	/* RISC-V does not support perf in guest mode. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+	if (perf_guest_cbs && perf_guest_cbs->state())
 		return;
 
 	fp = regs->s0;
@@ -79,7 +79,7 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
 	/* RISC-V does not support perf in guest mode. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (perf_guest_cbs && perf_guest_cbs->state()) {
 		pr_warn("RISC-V does not support perf in guest mode!");
 		return;
 	}
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 1eb45139fcc6..9a908631f6cc 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -90,6 +90,28 @@ DEFINE_STATIC_CALL_NULL(x86_pmu_pebs_aliases, *x86_pmu.pebs_aliases);
  */
 DEFINE_STATIC_CALL_RET0(x86_pmu_guest_get_msrs, *x86_pmu.guest_get_msrs);
 
+DEFINE_STATIC_CALL_RET0(x86_guest_state, *(perf_guest_cbs->state));
+DEFINE_STATIC_CALL_RET0(x86_guest_get_ip, *(perf_guest_cbs->get_ip));
+DEFINE_STATIC_CALL_RET0(x86_guest_handle_intel_pt_intr, *(perf_guest_cbs->handle_intel_pt_intr));
+
+void arch_perf_update_guest_cbs(void)
+{
+	static_call_update(x86_guest_state, (void *)&__static_call_return0);
+	static_call_update(x86_guest_get_ip, (void *)&__static_call_return0);
+	static_call_update(x86_guest_handle_intel_pt_intr, (void *)&__static_call_return0);
+
+	if (perf_guest_cbs && perf_guest_cbs->state)
+		static_call_update(x86_guest_state, perf_guest_cbs->state);
+
+	if (perf_guest_cbs && perf_guest_cbs->get_ip)
+		static_call_update(x86_guest_get_ip, perf_guest_cbs->get_ip);
+
+	if (perf_guest_cbs && perf_guest_cbs->handle_intel_pt_intr) {
+		static_call_update(x86_guest_handle_intel_pt_intr,
+				   perf_guest_cbs->handle_intel_pt_intr);
+	}
+}
+
 u64 __read_mostly hw_cache_event_ids
 				[PERF_COUNT_HW_CACHE_MAX]
 				[PERF_COUNT_HW_CACHE_OP_MAX]
@@ -2764,7 +2786,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
 	struct unwind_state state;
 	unsigned long addr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (static_call(x86_guest_state)()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2867,7 +2889,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 	struct stack_frame frame;
 	const struct stack_frame __user *fp;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (static_call(x86_guest_state)()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2944,18 +2966,21 @@ static unsigned long code_segment_base(struct pt_regs *regs)
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	unsigned long ip = static_call(x86_guest_get_ip)();
+
+	if (likely(!ip))
+		ip = regs->ip + code_segment_base(regs);
 
-	return regs->ip + code_segment_base(regs);
+	return ip;
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
+	unsigned int guest = static_call(x86_guest_state)();
 	int misc = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (guest) {
+		if (guest & PERF_GUEST_USER)
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index fca7a6e2242f..fb1bd7a0e1a6 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2782,6 +2782,8 @@ static void intel_pmu_reset(void)
 	local_irq_restore(flags);
 }
 
+DECLARE_STATIC_CALL(x86_guest_handle_intel_pt_intr, *(perf_guest_cbs->handle_intel_pt_intr));
+
 static int handle_pmi_common(struct pt_regs *regs, u64 status)
 {
 	struct perf_sample_data data;
@@ -2852,10 +2854,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
 	 */
 	if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) {
 		handled++;
-		if (unlikely(perf_guest_cbs && perf_guest_cbs->is_in_guest() &&
-			perf_guest_cbs->handle_intel_pt_intr))
-			perf_guest_cbs->handle_intel_pt_intr();
-		else
+		if (!static_call(x86_guest_handle_intel_pt_intr)())
 			intel_pt_interrupt();
 	}
 
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 974cbfb1eefe..128e2dd9c944 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1884,7 +1884,7 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu);
 int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
 void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu);
 
-int kvm_is_in_guest(void);
+unsigned int kvm_guest_state(void);
 
 void __user *__x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa,
 				     u32 size);
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 827886c12c16..2dcbd1b30004 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -87,7 +87,7 @@ static void kvm_perf_overflow_intr(struct perf_event *perf_event,
 		 * woken up. So we should wake it, but this is impossible from
 		 * NMI context. Do it from irq work instead.
 		 */
-		if (!kvm_is_in_guest())
+		if (!kvm_guest_state())
 			irq_work_queue(&pmc_to_pmu(pmc)->irq_work);
 		else
 			kvm_make_request(KVM_REQ_PMI, pmc->vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e5d5c5ed7dd4..efd11702465c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8268,44 +8268,47 @@ static void kvm_timer_init(void)
 DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
 EXPORT_PER_CPU_SYMBOL_GPL(current_vcpu);
 
-int kvm_is_in_guest(void)
+unsigned int kvm_guest_state(void)
 {
-	return __this_cpu_read(current_vcpu) != NULL;
-}
-
-static int kvm_is_user_mode(void)
-{
-	int user_mode = 3;
+	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
+	unsigned int state = 0;
 
-	if (__this_cpu_read(current_vcpu))
-		user_mode = static_call(kvm_x86_get_cpl)(__this_cpu_read(current_vcpu));
+	if (vcpu) {
+		state |= PERF_GUEST_ACTIVE;
+		if (static_call(kvm_x86_get_cpl)(vcpu))
+			state |= PERF_GUEST_USER;
+	}
 
-	return user_mode != 0;
+	return state;
 }
 
-static unsigned long kvm_get_guest_ip(void)
+static unsigned long kvm_guest_get_ip(void)
 {
+	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
 	unsigned long ip = 0;
 
-	if (__this_cpu_read(current_vcpu))
-		ip = kvm_rip_read(__this_cpu_read(current_vcpu));
+	if (vcpu)
+		ip = kvm_rip_read(vcpu);
 
 	return ip;
 }
 
-static void kvm_handle_intel_pt_intr(void)
+static unsigned int kvm_handle_intel_pt_intr(void)
 {
 	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
 
+	if (!vcpu)
+		return 0;
+
 	kvm_make_request(KVM_REQ_PMI, vcpu);
 	__set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT,
 			(unsigned long *)&vcpu->arch.pmu.global_status);
+	return 1;
 }
 
 static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.is_in_guest		= kvm_is_in_guest,
-	.is_user_mode		= kvm_is_user_mode,
-	.get_guest_ip		= kvm_get_guest_ip,
+	.state			= kvm_guest_state,
+	.get_ip			= kvm_guest_get_ip,
 	.handle_intel_pt_intr	= kvm_handle_intel_pt_intr,
 };
 
diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
index e13b0b49fcdf..85c6e6f6f422 100644
--- a/arch/x86/xen/pmu.c
+++ b/arch/x86/xen/pmu.c
@@ -413,34 +413,28 @@ int pmu_apic_update(uint32_t val)
 }
 
 /* perf callbacks */
-static int xen_is_in_guest(void)
+static unsigned int xen_guest_state(void)
 {
 	const struct xen_pmu_data *xenpmu_data = get_xenpmu_data();
+	unsigned int state = 0;
 
 	if (!xenpmu_data) {
 		pr_warn_once("%s: pmudata not initialized\n", __func__);
-		return 0;
+		return state;
 	}
 
 	if (!xen_initial_domain() || (xenpmu_data->domain_id >= DOMID_SELF))
-		return 0;
+		return state;
 
-	return 1;
-}
+	state |= PERF_GUEST_ACTIVE;
 
-static int xen_is_user_mode(void)
-{
-	const struct xen_pmu_data *xenpmu_data = get_xenpmu_data();
+	if (xenpmu_data->pmu.pmu_flags & PMU_SAMPLE_PV) {
+		if (xenpmu_data->pmu.pmu_flags & PMU_SAMPLE_USER)
+			state |= PERF_GUEST_USER;
+	} else if (xenpmu_data->pmu.r.regs.cpl & 3)
+			state |= PERF_GUEST_USER;
 
-	if (!xenpmu_data) {
-		pr_warn_once("%s: pmudata not initialized\n", __func__);
-		return 0;
-	}
-
-	if (xenpmu_data->pmu.pmu_flags & PMU_SAMPLE_PV)
-		return (xenpmu_data->pmu.pmu_flags & PMU_SAMPLE_USER);
-	else
-		return !!(xenpmu_data->pmu.r.regs.cpl & 3);
+	return state;
 }
 
 static unsigned long xen_get_guest_ip(void)
@@ -456,9 +450,8 @@ static unsigned long xen_get_guest_ip(void)
 }
 
 static struct perf_guest_info_callbacks xen_guest_cbs = {
-	.is_in_guest            = xen_is_in_guest,
-	.is_user_mode           = xen_is_user_mode,
-	.get_guest_ip           = xen_get_guest_ip,
+	.state                  = xen_guest_state,
+	.get_ip			= xen_get_guest_ip,
 };
 
 /* Convert registers from Xen's format to Linux' */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2d510ad750ed..e823677a214c 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -26,11 +26,13 @@
 # include <asm/local64.h>
 #endif
 
+#define PERF_GUEST_ACTIVE	0x01
+#define PERF_GUEST_USER	0x02
+
 struct perf_guest_info_callbacks {
-	int				(*is_in_guest)(void);
-	int				(*is_user_mode)(void);
-	unsigned long			(*get_guest_ip)(void);
-	void				(*handle_intel_pt_intr)(void);
+	unsigned int			(*state)(void);
+	unsigned long			(*get_ip)(void);
+	unsigned int			(*handle_intel_pt_intr)(void);
 };
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
@@ -1237,6 +1239,8 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 				 u16 flags);
 
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
+extern void __weak arch_perf_update_guest_cbs(void);
+
 extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 464917096e73..e466fc8176e1 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6489,9 +6489,18 @@ static void perf_pending_event(struct irq_work *entry)
  */
 struct perf_guest_info_callbacks *perf_guest_cbs;
 
+/* explicitly use __weak to fix duplicate symbol error */
+void __weak arch_perf_update_guest_cbs(void)
+{
+}
+
 int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
+	if (WARN_ON_ONCE(perf_guest_cbs))
+		return -EBUSY;
+
 	perf_guest_cbs = cbs;
+	arch_perf_update_guest_cbs();
 	return 0;
 }
 EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
-- 
2.27.0



From qperret at google.com  Fri Aug  6 06:40:00 2021
From: qperret at google.com (Quentin Perret)
Date: Fri, 6 Aug 2021 14:40:00 +0100
Subject: [PATCH 3/4] KVM: arm64: Convert the host S2 over to
 __load_guest_stage2()
In-Reply-To: <20210806113109.2475-5-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
 <20210806113109.2475-5-will@kernel.org>
Message-ID: <YQ07sPoa4ACizYrp@google.com>

On Friday 06 Aug 2021 at 12:31:07 (+0100), Will Deacon wrote:
> From: Marc Zyngier <maz at kernel.org>
> 
> The protected mode relies on a separate helper to load the
> S2 context. Move over to the __load_guest_stage2() helper
> instead.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Jade Alglave <jade.alglave at arm.com>
> Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_mmu.h              | 11 +++--------
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 +-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         |  2 +-
>  3 files changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index 05e089653a1a..934ef0deff9f 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -267,9 +267,10 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
>   * Must be called from hyp code running at EL2 with an updated VTTBR
>   * and interrupts disabled.
>   */
> -static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long vtcr)
> +static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
> +						struct kvm_arch *arch)
>  {
> -	write_sysreg(vtcr, vtcr_el2);
> +	write_sysreg(arch->vtcr, vtcr_el2);
>  	write_sysreg(kvm_get_vttbr(mmu), vttbr_el2);
>  
>  	/*
> @@ -280,12 +281,6 @@ static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long
>  	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
>  }
>  
> -static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
> -						struct kvm_arch *arch)
> -{
> -	__load_stage2(mmu, arch->vtcr);
> -}
> -
>  static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu)
>  {
>  	return container_of(mmu->arch, struct kvm, arch);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 9c227d87c36d..a910648bc71b 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -29,7 +29,7 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
>  static __always_inline void __load_host_stage2(void)
>  {
>  	if (static_branch_likely(&kvm_protected_mode_initialized))
> -		__load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr);
> +		__load_guest_stage2(&host_kvm.arch.mmu, &host_kvm.arch);
>  	else
>  		write_sysreg(0, vttbr_el2);
>  }
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index d938ce95d3bd..d4e74ca7f876 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -126,7 +126,7 @@ int __pkvm_prot_finalize(void)
>  	kvm_flush_dcache_to_poc(params, sizeof(*params));
>  
>  	write_sysreg(params->hcr_el2, hcr_el2);
> -	__load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr);
> +	__load_guest_stage2(&host_kvm.arch.mmu, &host_kvm.arch);

Nit: clearly we're not loading a guest stage-2 here, so maybe the
function should take a more generic name?

Thanks,
Quentin


From james.clark at arm.com  Fri Aug  6 06:41:00 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:00 +0100
Subject: [PATCH v2 0/9] Support ETE decoding
Message-ID: <20210806134109.1182235-1-james.clark@arm.com>

Changes since v1:
 * Re-implement with a new magic number instead of piggybacking on ETMv4
 * Improve comments and function name around cs_etm_decoder__get_etmv4_arch_ver()
 * Add a warning for unrecognised magic numbers
 * Split typo fix into new commit
 * Add Leo's reviewed-by tags
 * Create a new struct for ETE config (cs_ete_trace_params) instead of re-using ETMv4 config

Applies to perf/core f3c33cbd922
Also available at https://gitlab.arm.com/linux-arm/linux-jc/-/tree/james-ete-v2

James Clark (9):
  perf cs-etm: Refactor initialisation of decoder params.
  perf cs-etm: Initialise architecture based on TRCIDR1
  perf cs-etm: Refactor out ETMv4 header saving
  perf cs-etm: Save TRCDEVARCH register
  perf cs-etm: Fix typo
  perf cs-etm: Update OpenCSD decoder for ETE
  perf cs-etm: Create ETE decoder
  perf cs-etm: Print the decoder name
  perf cs-etm: Show a warning for an unknown magic number

 tools/build/feature/test-libopencsd.c         |   4 +-
 tools/perf/arch/arm/util/cs-etm.c             |  97 ++++++++----
 .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 148 ++++++++----------
 .../perf/util/cs-etm-decoder/cs-etm-decoder.h |  13 ++
 tools/perf/util/cs-etm.c                      |  43 ++++-
 tools/perf/util/cs-etm.h                      |  10 ++
 6 files changed, 200 insertions(+), 115 deletions(-)

-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:01 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:01 +0100
Subject: [PATCH v2 1/9] perf cs-etm: Refactor initialisation of decoder params.
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-2-james.clark@arm.com>

The initialisation of the decoder params is duplicated between
creation of the packet printer and packet decoder. Put them both
into one function so that future changes only need to be made in one
place.

Reviewed-by: Leo Yan <leo.yan at linaro.org>
Signed-off-by: James Clark <james.clark at arm.com>
---
 .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 99 +++++--------------
 1 file changed, 25 insertions(+), 74 deletions(-)

diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 84cca3fc05a5..187c038caa19 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -227,55 +227,6 @@ cs_etm_decoder__init_raw_frame_logging(
 }
 #endif
 
-static int cs_etm_decoder__create_packet_printer(struct cs_etm_decoder *decoder,
-						 const char *decoder_name,
-						 void *trace_config)
-{
-	u8 csid;
-
-	if (ocsd_dt_create_decoder(decoder->dcd_tree, decoder_name,
-				   OCSD_CREATE_FLG_PACKET_PROC,
-				   trace_config, &csid))
-		return -1;
-
-	if (ocsd_dt_set_pkt_protocol_printer(decoder->dcd_tree, csid, 0))
-		return -1;
-
-	return 0;
-}
-
-static int
-cs_etm_decoder__create_etm_packet_printer(struct cs_etm_trace_params *t_params,
-					  struct cs_etm_decoder *decoder)
-{
-	const char *decoder_name;
-	ocsd_etmv3_cfg config_etmv3;
-	ocsd_etmv4_cfg trace_config_etmv4;
-	void *trace_config;
-
-	switch (t_params->protocol) {
-	case CS_ETM_PROTO_ETMV3:
-	case CS_ETM_PROTO_PTM:
-		cs_etm_decoder__gen_etmv3_config(t_params, &config_etmv3);
-		decoder_name = (t_params->protocol == CS_ETM_PROTO_ETMV3) ?
-							OCSD_BUILTIN_DCD_ETMV3 :
-							OCSD_BUILTIN_DCD_PTM;
-		trace_config = &config_etmv3;
-		break;
-	case CS_ETM_PROTO_ETMV4i:
-		cs_etm_decoder__gen_etmv4_config(t_params, &trace_config_etmv4);
-		decoder_name = OCSD_BUILTIN_DCD_ETMV4I;
-		trace_config = &trace_config_etmv4;
-		break;
-	default:
-		return -1;
-	}
-
-	return cs_etm_decoder__create_packet_printer(decoder,
-						     decoder_name,
-						     trace_config);
-}
-
 static ocsd_datapath_resp_t
 cs_etm_decoder__do_soft_timestamp(struct cs_etm_queue *etmq,
 				  struct cs_etm_packet_queue *packet_queue,
@@ -632,9 +583,10 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer(
 	return resp;
 }
 
-static int cs_etm_decoder__create_etm_packet_decoder(
-					struct cs_etm_trace_params *t_params,
-					struct cs_etm_decoder *decoder)
+static int
+cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
+				   struct cs_etm_trace_params *t_params,
+				   struct cs_etm_decoder *decoder)
 {
 	const char *decoder_name;
 	ocsd_etmv3_cfg config_etmv3;
@@ -660,31 +612,30 @@ static int cs_etm_decoder__create_etm_packet_decoder(
 		return -1;
 	}
 
-	if (ocsd_dt_create_decoder(decoder->dcd_tree,
-				     decoder_name,
-				     OCSD_CREATE_FLG_FULL_DECODER,
-				     trace_config, &csid))
-		return -1;
+	if (d_params->operation == CS_ETM_OPERATION_DECODE) {
+		if (ocsd_dt_create_decoder(decoder->dcd_tree,
+					   decoder_name,
+					   OCSD_CREATE_FLG_FULL_DECODER,
+					   trace_config, &csid))
+			return -1;
 
-	if (ocsd_dt_set_gen_elem_outfn(decoder->dcd_tree,
-				       cs_etm_decoder__gen_trace_elem_printer,
-				       decoder))
-		return -1;
+		if (ocsd_dt_set_gen_elem_outfn(decoder->dcd_tree,
+					       cs_etm_decoder__gen_trace_elem_printer,
+					       decoder))
+			return -1;
 
-	return 0;
-}
+		return 0;
+	} else if (d_params->operation == CS_ETM_OPERATION_PRINT) {
+		if (ocsd_dt_create_decoder(decoder->dcd_tree, decoder_name,
+					   OCSD_CREATE_FLG_PACKET_PROC,
+					   trace_config, &csid))
+			return -1;
 
-static int
-cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
-				   struct cs_etm_trace_params *t_params,
-				   struct cs_etm_decoder *decoder)
-{
-	if (d_params->operation == CS_ETM_OPERATION_PRINT)
-		return cs_etm_decoder__create_etm_packet_printer(t_params,
-								 decoder);
-	else if (d_params->operation == CS_ETM_OPERATION_DECODE)
-		return cs_etm_decoder__create_etm_packet_decoder(t_params,
-								 decoder);
+		if (ocsd_dt_set_pkt_protocol_printer(decoder->dcd_tree, csid, 0))
+			return -1;
+
+		return 0;
+	}
 
 	return -1;
 }
-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:02 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:02 +0100
Subject: [PATCH v2 2/9] perf cs-etm: Initialise architecture based on TRCIDR1
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-3-james.clark@arm.com>

Currently the architecture is hard coded as ARCH_V8, but from ETMv4.4
onwards this should be ARCH_AA64.

Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 187c038caa19..787b19642e78 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -126,6 +126,20 @@ static int cs_etm_decoder__gen_etmv3_config(struct cs_etm_trace_params *params,
 	return 0;
 }
 
+#define TRCIDR1_TRCARCHMIN_SHIFT 4
+#define TRCIDR1_TRCARCHMIN_MASK  GENMASK(7, 4)
+#define TRCIDR1_TRCARCHMIN(x)    (((x) & TRCIDR1_TRCARCHMIN_MASK) >> TRCIDR1_TRCARCHMIN_SHIFT)
+static enum _ocsd_arch_version cs_etm_decoder__get_etmv4_arch_ver(u32 reg_idr1)
+{
+	/*
+	 * For ETMv4 if the trace minor version is 4 or more then we can assume
+	 * the architecture is ARCH_AA64 rather than just V8.
+	 * ARCH_V8 = V8 architecture
+	 * ARCH_AA64 = Min v8r3 plus additional AA64 PE features
+	 */
+	return TRCIDR1_TRCARCHMIN(reg_idr1) >= 4 ? ARCH_AA64 : ARCH_V8;
+}
+
 static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params,
 					     ocsd_etmv4_cfg *config)
 {
@@ -140,7 +154,7 @@ static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params,
 	config->reg_idr11 = 0;
 	config->reg_idr12 = 0;
 	config->reg_idr13 = 0;
-	config->arch_ver = ARCH_V8;
+	config->arch_ver = cs_etm_decoder__get_etmv4_arch_ver(params->etmv4.reg_idr1);
 	config->core_prof = profile_CortexA;
 }
 
-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:03 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:03 +0100
Subject: [PATCH v2 3/9] perf cs-etm: Refactor out ETMv4 header saving
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-4-james.clark@arm.com>

Extract a function for saving the ETMv4 header because this will be used
for ETE in a later commit.

Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/perf/arch/arm/util/cs-etm.c | 46 +++++++++++++++----------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 85168d87b2d7..ecb6fa55a210 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -607,6 +607,28 @@ static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
 	return val;
 }
 
+static void cs_etm_save_etmv4_header(__u64 data[], struct auxtrace_record *itr, int cpu)
+{
+	struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr);
+	struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
+
+	/* Get trace configuration register */
+	data[CS_ETMV4_TRCCONFIGR] = cs_etmv4_get_config(itr);
+	/* Get traceID from the framework */
+	data[CS_ETMV4_TRCTRACEIDR] = coresight_get_trace_id(cpu);
+	/* Get read-only information from sysFS */
+	data[CS_ETMV4_TRCIDR0] = cs_etm_get_ro(cs_etm_pmu, cpu,
+					       metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
+	data[CS_ETMV4_TRCIDR1] = cs_etm_get_ro(cs_etm_pmu, cpu,
+					       metadata_etmv4_ro[CS_ETMV4_TRCIDR1]);
+	data[CS_ETMV4_TRCIDR2] = cs_etm_get_ro(cs_etm_pmu, cpu,
+					       metadata_etmv4_ro[CS_ETMV4_TRCIDR2]);
+	data[CS_ETMV4_TRCIDR8] = cs_etm_get_ro(cs_etm_pmu, cpu,
+					       metadata_etmv4_ro[CS_ETMV4_TRCIDR8]);
+	data[CS_ETMV4_TRCAUTHSTATUS] = cs_etm_get_ro(cs_etm_pmu, cpu,
+						     metadata_etmv4_ro[CS_ETMV4_TRCAUTHSTATUS]);
+}
+
 static void cs_etm_get_metadata(int cpu, u32 *offset,
 				struct auxtrace_record *itr,
 				struct perf_record_auxtrace_info *info)
@@ -620,29 +642,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
 	/* first see what kind of tracer this cpu is affined to */
 	if (cs_etm_is_etmv4(itr, cpu)) {
 		magic = __perf_cs_etmv4_magic;
-		/* Get trace configuration register */
-		info->priv[*offset + CS_ETMV4_TRCCONFIGR] =
-						cs_etmv4_get_config(itr);
-		/* Get traceID from the framework */
-		info->priv[*offset + CS_ETMV4_TRCTRACEIDR] =
-						coresight_get_trace_id(cpu);
-		/* Get read-only information from sysFS */
-		info->priv[*offset + CS_ETMV4_TRCIDR0] =
-			cs_etm_get_ro(cs_etm_pmu, cpu,
-				      metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
-		info->priv[*offset + CS_ETMV4_TRCIDR1] =
-			cs_etm_get_ro(cs_etm_pmu, cpu,
-				      metadata_etmv4_ro[CS_ETMV4_TRCIDR1]);
-		info->priv[*offset + CS_ETMV4_TRCIDR2] =
-			cs_etm_get_ro(cs_etm_pmu, cpu,
-				      metadata_etmv4_ro[CS_ETMV4_TRCIDR2]);
-		info->priv[*offset + CS_ETMV4_TRCIDR8] =
-			cs_etm_get_ro(cs_etm_pmu, cpu,
-				      metadata_etmv4_ro[CS_ETMV4_TRCIDR8]);
-		info->priv[*offset + CS_ETMV4_TRCAUTHSTATUS] =
-			cs_etm_get_ro(cs_etm_pmu, cpu,
-				      metadata_etmv4_ro
-				      [CS_ETMV4_TRCAUTHSTATUS]);
+		cs_etm_save_etmv4_header(&info->priv[*offset], itr, cpu);
 
 		/* How much space was used */
 		increment = CS_ETMV4_PRIV_MAX;
-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:04 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:04 +0100
Subject: [PATCH v2 4/9] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-5-james.clark@arm.com>

When ETE is present save the TRCDEVARCH register and set a new magic
number. It will be used to configure the decoder in a later commit.

Old versions of perf will not be able to open files with this new magic
number, but old files will still work with newer versions of perf.

Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/perf/arch/arm/util/cs-etm.c | 49 +++++++++++++++++++++++++++----
 tools/perf/util/cs-etm.c          | 16 ++++++++--
 tools/perf/util/cs-etm.h          | 10 +++++++
 3 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index ecb6fa55a210..e3500b79d972 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -47,15 +47,17 @@ static const char *metadata_etmv3_ro[CS_ETM_PRIV_MAX] = {
 	[CS_ETM_ETMIDR]		= "mgmt/etmidr",
 };
 
-static const char *metadata_etmv4_ro[CS_ETMV4_PRIV_MAX] = {
+static const char * const metadata_etmv4_ro[] = {
 	[CS_ETMV4_TRCIDR0]		= "trcidr/trcidr0",
 	[CS_ETMV4_TRCIDR1]		= "trcidr/trcidr1",
 	[CS_ETMV4_TRCIDR2]		= "trcidr/trcidr2",
 	[CS_ETMV4_TRCIDR8]		= "trcidr/trcidr8",
 	[CS_ETMV4_TRCAUTHSTATUS]	= "mgmt/trcauthstatus",
+	[CS_ETE_TRCDEVARCH]		= "mgmt/trcdevarch"
 };
 
 static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu);
+static bool cs_etm_is_ete(struct auxtrace_record *itr, int cpu);
 
 static int cs_etm_set_context_id(struct auxtrace_record *itr,
 				 struct evsel *evsel, int cpu)
@@ -533,7 +535,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 		      struct evlist *evlist __maybe_unused)
 {
 	int i;
-	int etmv3 = 0, etmv4 = 0;
+	int etmv3 = 0, etmv4 = 0, ete = 0;
 	struct perf_cpu_map *event_cpus = evlist->core.cpus;
 	struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL);
 
@@ -544,7 +546,9 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 			    !cpu_map__has(online_cpus, i))
 				continue;
 
-			if (cs_etm_is_etmv4(itr, i))
+			if (cs_etm_is_ete(itr, i))
+				ete++;
+			else if (cs_etm_is_etmv4(itr, i))
 				etmv4++;
 			else
 				etmv3++;
@@ -555,7 +559,9 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 			if (!cpu_map__has(online_cpus, i))
 				continue;
 
-			if (cs_etm_is_etmv4(itr, i))
+			if (cs_etm_is_ete(itr, i))
+				ete++;
+			else if (cs_etm_is_etmv4(itr, i))
 				etmv4++;
 			else
 				etmv3++;
@@ -565,6 +571,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 	perf_cpu_map__put(online_cpus);
 
 	return (CS_ETM_HEADER_SIZE +
+	       (ete   * CS_ETE_PRIV_SIZE) +
 	       (etmv4 * CS_ETMV4_PRIV_SIZE) +
 	       (etmv3 * CS_ETMV3_PRIV_SIZE));
 }
@@ -607,6 +614,27 @@ static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
 	return val;
 }
 
+#define TRCDEVARCH_ARCHPART_SHIFT 0
+#define TRCDEVARCH_ARCHPART_MASK  GENMASK(11, 0)
+#define TRCDEVARCH_ARCHPART(x)    (((x) & TRCDEVARCH_ARCHPART_MASK) >> TRCDEVARCH_ARCHPART_SHIFT)
+
+#define TRCDEVARCH_ARCHVER_SHIFT 12
+#define TRCDEVARCH_ARCHVER_MASK  GENMASK(15, 12)
+#define TRCDEVARCH_ARCHVER(x)    (((x) & TRCDEVARCH_ARCHVER_MASK) >> TRCDEVARCH_ARCHVER_SHIFT)
+
+static bool cs_etm_is_ete(struct auxtrace_record *itr, int cpu)
+{
+	struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr);
+	struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
+	int trcdevarch = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETE_TRCDEVARCH]);
+
+	/*
+	 * ETE if ARCHVER is 5 (ARCHVER is 4 for ETM) and ARCHPART is 0xA13.
+	 * See ETM_DEVARCH_ETE_ARCH in coresight-etm4x.h
+	 */
+	return TRCDEVARCH_ARCHVER(trcdevarch) == 5 && TRCDEVARCH_ARCHPART(trcdevarch) == 0xA13;
+}
+
 static void cs_etm_save_etmv4_header(__u64 data[], struct auxtrace_record *itr, int cpu)
 {
 	struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr);
@@ -640,7 +668,18 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
 	struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
 
 	/* first see what kind of tracer this cpu is affined to */
-	if (cs_etm_is_etmv4(itr, cpu)) {
+	if (cs_etm_is_ete(itr, cpu)) {
+		magic = __perf_cs_ete_magic;
+		/* ETE uses the same registers as ETMv4 plus TRCDEVARCH */
+		cs_etm_save_etmv4_header(&info->priv[*offset], itr, cpu);
+		info->priv[*offset + CS_ETE_TRCDEVARCH] =
+			cs_etm_get_ro(cs_etm_pmu, cpu,
+				      metadata_etmv4_ro[CS_ETE_TRCDEVARCH]);
+
+		/* How much space was used */
+		increment = CS_ETE_PRIV_MAX;
+		nr_trc_params = CS_ETE_PRIV_MAX - CS_ETM_COMMON_BLK_MAX_V1;
+	} else if (cs_etm_is_etmv4(itr, cpu)) {
 		magic = __perf_cs_etmv4_magic;
 		cs_etm_save_etmv4_header(&info->priv[*offset], itr, cpu);
 
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index f4b2bff533f3..d540512a3c96 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2512,6 +2512,7 @@ static const char * const cs_etmv4_priv_fmts[] = {
 	[CS_ETMV4_TRCIDR2]	= "	TRCIDR2			       %llx\n",
 	[CS_ETMV4_TRCIDR8]	= "	TRCIDR8			       %llx\n",
 	[CS_ETMV4_TRCAUTHSTATUS] = "	TRCAUTHSTATUS		       %llx\n",
+	[CS_ETE_TRCDEVARCH]	= "	TRCDEVARCH                     %llx\n"
 };
 
 static const char * const param_unk_fmt =
@@ -2571,10 +2572,15 @@ static int cs_etm__print_cpu_metadata_v1(__u64 *val, int *offset)
 			else
 				fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
 		}
-	} else if (magic == __perf_cs_etmv4_magic) {
+	} else if (magic == __perf_cs_etmv4_magic || magic == __perf_cs_ete_magic) {
+		/*
+		 * ETE and ETMv4 can be printed in the same block because the number of parameters
+		 * is saved and they share the list of parameter names. ETE is also only supported
+		 * in V1 files.
+		 */
 		for (j = 0; j < total_params; j++, i++) {
 			/* if newer record - could be excess params */
-			if (j >= CS_ETMV4_PRIV_MAX)
+			if (j >= CS_ETE_PRIV_MAX)
 				fprintf(stdout, param_unk_fmt, j, val[i]);
 			else
 				fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
@@ -2943,6 +2949,12 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
 
 			/* The traceID is our handle */
 			trcidr_idx = CS_ETMV4_TRCTRACEIDR;
+		} else if (ptr[i] == __perf_cs_ete_magic) {
+			metadata[j] =
+				cs_etm__create_meta_blk(ptr, &i, CS_ETE_PRIV_MAX, -1);
+
+			/* ETE shares first part of metadata with ETMv4 */
+			trcidr_idx = CS_ETMV4_TRCTRACEIDR;
 		}
 
 		if (!metadata[j]) {
diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
index d65c7b19407d..08b84c21f065 100644
--- a/tools/perf/util/cs-etm.h
+++ b/tools/perf/util/cs-etm.h
@@ -76,6 +76,14 @@ enum {
 /* define fixed version 0 length - allow new format reader to read old files. */
 #define CS_ETMV4_NR_TRC_PARAMS_V0 (CS_ETMV4_TRCAUTHSTATUS - CS_ETMV4_TRCCONFIGR + 1)
 
+/* ETE metadata is ETMv4 plus TRCDEVARCH register and doesn't support header V0 since it was
+ * added in header V1
+ */
+enum {
+	CS_ETE_TRCDEVARCH = CS_ETMV4_PRIV_MAX,
+	CS_ETE_PRIV_MAX
+};
+
 /*
  * ETMv3 exception encoding number:
  * See Embedded Trace Macrocell specification (ARM IHI 0014Q)
@@ -187,8 +195,10 @@ struct cs_etm_packet_queue {
 
 #define __perf_cs_etmv3_magic 0x3030303030303030ULL
 #define __perf_cs_etmv4_magic 0x4040404040404040ULL
+#define __perf_cs_ete_magic   0x5050505050505050ULL
 #define CS_ETMV3_PRIV_SIZE (CS_ETM_PRIV_MAX * sizeof(u64))
 #define CS_ETMV4_PRIV_SIZE (CS_ETMV4_PRIV_MAX * sizeof(u64))
+#define CS_ETE_PRIV_SIZE (CS_ETE_PRIV_MAX * sizeof(u64))
 
 #ifdef HAVE_CSTRACE_SUPPORT
 int cs_etm__process_auxtrace_info(union perf_event *event,
-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:05 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:05 +0100
Subject: [PATCH v2 5/9] perf cs-etm: Fix typo
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-6-james.clark@arm.com>

TRCIRD2 should be TRCIDR2

Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/perf/arch/arm/util/cs-etm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index e3500b79d972..515aae470e23 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -75,7 +75,7 @@ static int cs_etm_set_context_id(struct auxtrace_record *itr,
 	if (!cs_etm_is_etmv4(itr, cpu))
 		goto out;
 
-	/* Get a handle on TRCIRD2 */
+	/* Get a handle on TRCIDR2 */
 	snprintf(path, PATH_MAX, "cpu%d/%s",
 		 cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR2]);
 	err = perf_pmu__scan_file(cs_etm_pmu, path, "%x", &val);
-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:06 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:06 +0100
Subject: [PATCH v2 6/9] perf cs-etm: Update OpenCSD decoder for ETE
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-7-james.clark@arm.com>

OpenCSD v1.1.1 has a bug fix for the installation of the ETE decoder
headers. This also means that including headers separately for each
decoder is unnecessary so remove these.

Reviewed-by: Leo Yan <leo.yan at linaro.org>
Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/build/feature/test-libopencsd.c           | 4 ++--
 tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 2 --
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/tools/build/feature/test-libopencsd.c b/tools/build/feature/test-libopencsd.c
index 52c790b0317b..eb6303ff446e 100644
--- a/tools/build/feature/test-libopencsd.c
+++ b/tools/build/feature/test-libopencsd.c
@@ -4,9 +4,9 @@
 /*
  * Check OpenCSD library version is sufficient to provide required features
  */
-#define OCSD_MIN_VER ((1 << 16) | (0 << 8) | (0))
+#define OCSD_MIN_VER ((1 << 16) | (1 << 8) | (1))
 #if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER)
-#error "OpenCSD >= 1.0.0 is required"
+#error "OpenCSD >= 1.1.1 is required"
 #endif
 
 int main(void)
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 787b19642e78..12cee321fbf2 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -13,8 +13,6 @@
 #include <linux/zalloc.h>
 #include <stdlib.h>
 #include <opencsd/c_api/opencsd_c_api.h>
-#include <opencsd/etmv4/trc_pkt_types_etmv4.h>
-#include <opencsd/ocsd_if_types.h>
 
 #include "cs-etm.h"
 #include "cs-etm-decoder.h"
-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:07 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:07 +0100
Subject: [PATCH v2 7/9] perf cs-etm: Create ETE decoder
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-8-james.clark@arm.com>

If the magic number indicates ETE instantiate a OCSD_BUILTIN_DCD_ETE
decoder instead of OCSD_BUILTIN_DCD_ETMV4I. ETE is the new trace feature
for Armv9.

Testing performed
=================

* Old files with v0 and v1 headers for ETMv4 still open correctly
* New files with new magic number open on new versions of perf
* New files with new magic number fail to open on old versions of perf
* Decoding with the ETE decoder results in the same output as the ETMv4
  decoder as long as there are no new ETE packet types

Signed-off-by: James Clark <james.clark at arm.com>
---
 .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 20 +++++++++++++++++++
 .../perf/util/cs-etm-decoder/cs-etm-decoder.h | 12 +++++++++++
 tools/perf/util/cs-etm.c                      | 18 +++++++++++++++++
 3 files changed, 50 insertions(+)

diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 12cee321fbf2..3071e5deddcc 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -156,6 +156,20 @@ static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params,
 	config->core_prof = profile_CortexA;
 }
 
+static void cs_etm_decoder__gen_ete_config(struct cs_etm_trace_params *params,
+					   ocsd_ete_cfg *config)
+{
+	config->reg_configr = params->ete.reg_configr;
+	config->reg_traceidr = params->ete.reg_traceidr;
+	config->reg_idr0 = params->ete.reg_idr0;
+	config->reg_idr1 = params->ete.reg_idr1;
+	config->reg_idr2 = params->ete.reg_idr2;
+	config->reg_idr8 = params->ete.reg_idr8;
+	config->reg_devarch = params->ete.reg_devarch;
+	config->arch_ver = ARCH_AA64;
+	config->core_prof = profile_CortexA;
+}
+
 static void cs_etm_decoder__print_str_cb(const void *p_context,
 					 const char *msg,
 					 const int str_len)
@@ -603,6 +617,7 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
 	const char *decoder_name;
 	ocsd_etmv3_cfg config_etmv3;
 	ocsd_etmv4_cfg trace_config_etmv4;
+	ocsd_ete_cfg trace_config_ete;
 	void *trace_config;
 	u8 csid;
 
@@ -620,6 +635,11 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
 		decoder_name = OCSD_BUILTIN_DCD_ETMV4I;
 		trace_config = &trace_config_etmv4;
 		break;
+	case CS_ETM_PROTO_ETE:
+		cs_etm_decoder__gen_ete_config(t_params, &trace_config_ete);
+		decoder_name = OCSD_BUILTIN_DCD_ETE;
+		trace_config = &trace_config_ete;
+		break;
 	default:
 		return -1;
 	}
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
index 11f3391d06f2..0102ece5ca3e 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
@@ -37,11 +37,22 @@ struct cs_etmv4_trace_params {
 	u32 reg_traceidr;
 };
 
+struct cs_ete_trace_params {
+	u32 reg_idr0;
+	u32 reg_idr1;
+	u32 reg_idr2;
+	u32 reg_idr8;
+	u32 reg_configr;
+	u32 reg_traceidr;
+	u32 reg_devarch;
+};
+
 struct cs_etm_trace_params {
 	int protocol;
 	union {
 		struct cs_etmv3_trace_params etmv3;
 		struct cs_etmv4_trace_params etmv4;
+		struct cs_ete_trace_params ete;
 	};
 };
 
@@ -65,6 +76,7 @@ enum {
 	CS_ETM_PROTO_ETMV4i,
 	CS_ETM_PROTO_ETMV4d,
 	CS_ETM_PROTO_PTM,
+	CS_ETM_PROTO_ETE
 };
 
 enum cs_etm_decoder_operation {
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index d540512a3c96..e5649e9ea140 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -460,6 +460,21 @@ static void cs_etm__set_trace_param_etmv4(struct cs_etm_trace_params *t_params,
 	t_params[idx].etmv4.reg_traceidr = metadata[idx][CS_ETMV4_TRCTRACEIDR];
 }
 
+static void cs_etm__set_trace_param_ete(struct cs_etm_trace_params *t_params,
+					  struct cs_etm_auxtrace *etm, int idx)
+{
+	u64 **metadata = etm->metadata;
+
+	t_params[idx].protocol = CS_ETM_PROTO_ETE;
+	t_params[idx].ete.reg_idr0 = metadata[idx][CS_ETMV4_TRCIDR0];
+	t_params[idx].ete.reg_idr1 = metadata[idx][CS_ETMV4_TRCIDR1];
+	t_params[idx].ete.reg_idr2 = metadata[idx][CS_ETMV4_TRCIDR2];
+	t_params[idx].ete.reg_idr8 = metadata[idx][CS_ETMV4_TRCIDR8];
+	t_params[idx].ete.reg_configr = metadata[idx][CS_ETMV4_TRCCONFIGR];
+	t_params[idx].ete.reg_traceidr = metadata[idx][CS_ETMV4_TRCTRACEIDR];
+	t_params[idx].ete.reg_devarch = metadata[idx][CS_ETE_TRCDEVARCH];
+}
+
 static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params,
 				     struct cs_etm_auxtrace *etm,
 				     int decoders)
@@ -479,6 +494,9 @@ static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params,
 		case __perf_cs_etmv4_magic:
 			cs_etm__set_trace_param_etmv4(t_params, etm, i);
 			break;
+		case __perf_cs_ete_magic:
+			cs_etm__set_trace_param_ete(t_params, etm, i);
+			break;
 		default:
 			return -EINVAL;
 		}
-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:08 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:08 +0100
Subject: [PATCH v2 8/9] perf cs-etm: Print the decoder name
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-9-james.clark@arm.com>

Use the real name of the decoder instead of hard-coding "ETM" to avoid
confusion when the trace is ETE. This also now distinguishes between
ETMv3 and ETMv4.

Reviewed-by: Leo Yan <leo.yan at linaro.org>
Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 17 +++++++++++------
 tools/perf/util/cs-etm-decoder/cs-etm-decoder.h |  1 +
 tools/perf/util/cs-etm.c                        |  4 ++--
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 3071e5deddcc..29a23fa16aff 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -37,6 +37,7 @@ struct cs_etm_decoder {
 	dcd_tree_handle_t dcd_tree;
 	cs_etm_mem_cb_type mem_access;
 	ocsd_datapath_resp_t prev_return;
+	const char *decoder_name;
 };
 
 static u32
@@ -614,7 +615,6 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
 				   struct cs_etm_trace_params *t_params,
 				   struct cs_etm_decoder *decoder)
 {
-	const char *decoder_name;
 	ocsd_etmv3_cfg config_etmv3;
 	ocsd_etmv4_cfg trace_config_etmv4;
 	ocsd_ete_cfg trace_config_ete;
@@ -625,19 +625,19 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
 	case CS_ETM_PROTO_ETMV3:
 	case CS_ETM_PROTO_PTM:
 		cs_etm_decoder__gen_etmv3_config(t_params, &config_etmv3);
-		decoder_name = (t_params->protocol == CS_ETM_PROTO_ETMV3) ?
+		decoder->decoder_name = (t_params->protocol == CS_ETM_PROTO_ETMV3) ?
 							OCSD_BUILTIN_DCD_ETMV3 :
 							OCSD_BUILTIN_DCD_PTM;
 		trace_config = &config_etmv3;
 		break;
 	case CS_ETM_PROTO_ETMV4i:
 		cs_etm_decoder__gen_etmv4_config(t_params, &trace_config_etmv4);
-		decoder_name = OCSD_BUILTIN_DCD_ETMV4I;
+		decoder->decoder_name = OCSD_BUILTIN_DCD_ETMV4I;
 		trace_config = &trace_config_etmv4;
 		break;
 	case CS_ETM_PROTO_ETE:
 		cs_etm_decoder__gen_ete_config(t_params, &trace_config_ete);
-		decoder_name = OCSD_BUILTIN_DCD_ETE;
+		decoder->decoder_name = OCSD_BUILTIN_DCD_ETE;
 		trace_config = &trace_config_ete;
 		break;
 	default:
@@ -646,7 +646,7 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
 
 	if (d_params->operation == CS_ETM_OPERATION_DECODE) {
 		if (ocsd_dt_create_decoder(decoder->dcd_tree,
-					   decoder_name,
+					   decoder->decoder_name,
 					   OCSD_CREATE_FLG_FULL_DECODER,
 					   trace_config, &csid))
 			return -1;
@@ -658,7 +658,7 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
 
 		return 0;
 	} else if (d_params->operation == CS_ETM_OPERATION_PRINT) {
-		if (ocsd_dt_create_decoder(decoder->dcd_tree, decoder_name,
+		if (ocsd_dt_create_decoder(decoder->dcd_tree, decoder->decoder_name,
 					   OCSD_CREATE_FLG_PACKET_PROC,
 					   trace_config, &csid))
 			return -1;
@@ -790,3 +790,8 @@ void cs_etm_decoder__free(struct cs_etm_decoder *decoder)
 	decoder->dcd_tree = NULL;
 	free(decoder);
 }
+
+const char *cs_etm_decoder__get_name(struct cs_etm_decoder *decoder)
+{
+	return decoder->decoder_name;
+}
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
index 0102ece5ca3e..92a855fbe5b8 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
@@ -104,5 +104,6 @@ int cs_etm_decoder__get_packet(struct cs_etm_packet_queue *packet_queue,
 			       struct cs_etm_packet *packet);
 
 int cs_etm_decoder__reset(struct cs_etm_decoder *decoder);
+const char *cs_etm_decoder__get_name(struct cs_etm_decoder *decoder);
 
 #endif /* INCLUDE__CS_ETM_DECODER_H__ */
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index e5649e9ea140..788ad5a099f6 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -537,8 +537,8 @@ static void cs_etm__dump_event(struct cs_etm_queue *etmq,
 
 	fprintf(stdout, "\n");
 	color_fprintf(stdout, color,
-		     ". ... CoreSight ETM Trace data: size %zu bytes\n",
-		     buffer->size);
+		     ". ... CoreSight %s Trace data: size %zu bytes\n",
+		     cs_etm_decoder__get_name(etmq->decoder), buffer->size);
 
 	do {
 		size_t consumed;
-- 
2.28.0



From james.clark at arm.com  Fri Aug  6 06:41:09 2021
From: james.clark at arm.com (James Clark)
Date: Fri,  6 Aug 2021 14:41:09 +0100
Subject: [PATCH v2 9/9] perf cs-etm: Show a warning for an unknown magic number
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210806134109.1182235-10-james.clark@arm.com>

Currently perf reports "Cannot allocate memory" which isn't very helpful
for a potentially user facing issue. If we add a new magic number in
the future, perf will be able to report unrecognised magic numbers.

Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/perf/util/cs-etm.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 788ad5a099f6..5b276bdb96a6 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -2973,6 +2973,11 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
 
 			/* ETE shares first part of metadata with ETMv4 */
 			trcidr_idx = CS_ETMV4_TRCTRACEIDR;
+		} else {
+			ui__error("CS ETM Trace: Unrecognised magic number %#"PRIx64". File could be from a newer version of perf.\n",
+				  ptr[i]);
+			err = -EINVAL;
+			goto err_free_metadata;
 		}
 
 		if (!metadata[j]) {
-- 
2.28.0



From will at kernel.org  Fri Aug  6 06:53:32 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 6 Aug 2021 14:53:32 +0100
Subject: [GIT PULL] arm64 fixes for -rc5
Message-ID: <20210806135331.GA2951@willie-the-truck>

Hi Linus,

Please pull these arm64 fixes for -rc5. It's all pretty minor but the
main fix is sorting out how we deal with return values from 32-bit system
calls as audit expects error codes to be sign-extended to 64 bits

Brief summary in the tag.

Cheers,

Will

--->8

The following changes since commit d8a719059b9dc963aa190598778ac804ff3e6a87:

  Revert "mm/pgtable: add stubs for {pmd/pub}_{set/clear}_huge" (2021-07-21 11:28:09 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to 0c32706dac1b0a72713184246952ab0f54327c21:

  arm64: stacktrace: avoid tracing arch_stack_walk() (2021-08-03 10:39:35 +0100)

----------------------------------------------------------------
arm64 fixes for -rc5

- Fix extension/truncation of return values from 32-bit system calls

- Fix interaction between unwinding and tracing

- Fix spurious toolchain warning emitted during make

- Fix Kconfig help text for RANDOMIZE_MODULE_REGION_FULL

----------------------------------------------------------------
Barry Song (1):
      arm64: fix the doc of RANDOMIZE_MODULE_REGION_FULL

Mark Rutland (3):
      arm64: fix compat syscall return truncation
      arm64: stacktrace: fix comment
      arm64: stacktrace: avoid tracing arch_stack_walk()

Masahiro Yamada (1):
      arm64: move warning about toolchains to archprepare

 arch/arm64/Kconfig                  |  9 ++++++---
 arch/arm64/Makefile                 | 21 ++++++++++++---------
 arch/arm64/include/asm/ptrace.h     | 12 +++++++++++-
 arch/arm64/include/asm/stacktrace.h |  2 +-
 arch/arm64/include/asm/syscall.h    | 19 ++++++++++---------
 arch/arm64/kernel/kaslr.c           |  4 +++-
 arch/arm64/kernel/ptrace.c          |  2 +-
 arch/arm64/kernel/signal.c          |  3 ++-
 arch/arm64/kernel/stacktrace.c      |  2 +-
 arch/arm64/kernel/syscall.c         |  9 +++------
 10 files changed, 50 insertions(+), 33 deletions(-)


From qperret at google.com  Fri Aug  6 07:24:56 2021
From: qperret at google.com (Quentin Perret)
Date: Fri, 6 Aug 2021 15:24:56 +0100
Subject: [PATCH 4/4] KVM: arm64: Upgrade VMID accesses to {READ,WRITE}_ONCE
In-Reply-To: <20210806113109.2475-6-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
 <20210806113109.2475-6-will@kernel.org>
Message-ID: <YQ1GOAqlG9+25XS4@google.com>

On Friday 06 Aug 2021 at 12:31:08 (+0100), Will Deacon wrote:
> From: Marc Zyngier <maz at kernel.org>
> 
> Since TLB invalidation can run in parallel with VMID allocation,
> we need to be careful and avoid any sort of load/store tearing.
> Use {READ,WRITE}_ONCE consistently to avoid any surprise.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Jade Alglave <jade.alglave at arm.com>
> Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_mmu.h      | 7 ++++++-
>  arch/arm64/kvm/arm.c                  | 2 +-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 4 ++--
>  arch/arm64/kvm/mmu.c                  | 2 +-
>  4 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index 934ef0deff9f..5828dd8fa738 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -252,6 +252,11 @@ static inline int kvm_write_guest_lock(struct kvm *kvm, gpa_t gpa,
>  
>  #define kvm_phys_to_vttbr(addr)		phys_to_ttbr(addr)
>  
> +/*
> + * When this is (directly or indirectly) used on the TLB invalidation
> + * path, we rely on a previously issued DSB so that page table updates
> + * and VMID reads are correctly ordered.
> + */
>  static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
>  {
>  	struct kvm_vmid *vmid = &mmu->vmid;
> @@ -259,7 +264,7 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
>  	u64 cnp = system_supports_cnp() ? VTTBR_CNP_BIT : 0;
>  
>  	baddr = mmu->pgd_phys;
> -	vmid_field = (u64)vmid->vmid << VTTBR_VMID_SHIFT;
> +	vmid_field = (u64)READ_ONCE(vmid->vmid) << VTTBR_VMID_SHIFT;
>  	return kvm_phys_to_vttbr(baddr) | vmid_field | cnp;
>  }
>  
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e9a2b8f27792..658f76067f46 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -571,7 +571,7 @@ static void update_vmid(struct kvm_vmid *vmid)
>  		kvm_call_hyp(__kvm_flush_vm_context);
>  	}
>  
> -	vmid->vmid = kvm_next_vmid;
> +	WRITE_ONCE(vmid->vmid, kvm_next_vmid);
>  	kvm_next_vmid++;
>  	kvm_next_vmid &= (1 << kvm_get_vmid_bits()) - 1;
>  
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index d4e74ca7f876..55ae97a144b8 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -109,8 +109,8 @@ int kvm_host_prepare_stage2(void *pgt_pool_base)
>  	mmu->pgd_phys = __hyp_pa(host_kvm.pgt.pgd);
>  	mmu->arch = &host_kvm.arch;
>  	mmu->pgt = &host_kvm.pgt;
> -	mmu->vmid.vmid_gen = 0;
> -	mmu->vmid.vmid = 0;
> +	WRITE_ONCE(mmu->vmid.vmid_gen, 0);
> +	WRITE_ONCE(mmu->vmid.vmid, 0);

I'm guessing it should be safe to omit those? But they certainly don't
harm and can serve as documentation anyway, so:

Reviewed-by: Quentin Perret <qperret at google.com>

Thanks,
Quentin

>  
>  	return 0;
>  }
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 3155c9e778f0..b1a6eaec28ff 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -485,7 +485,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
>  	mmu->arch = &kvm->arch;
>  	mmu->pgt = pgt;
>  	mmu->pgd_phys = __pa(pgt->pgd);
> -	mmu->vmid.vmid_gen = 0;
> +	WRITE_ONCE(mmu->vmid.vmid_gen, 0);
>  	return 0;
>  
>  out_destroy_pgtable:
> -- 
> 2.32.0.605.g8dce9f2422-goog
> 


From arnd at kernel.org  Fri Aug  6 07:26:26 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Fri, 6 Aug 2021 16:26:26 +0200
Subject: [GIT PULL] ARM: SoC fixes for v5.14, part 2
Message-ID: <CAK8P3a1u+0tJUqnSOWmC5ixdeGGoBb+mVv30rc65Bjy7a1Wo7w@mail.gmail.com>

The following changes since commit c500bee1c5b2f1d59b1081ac879d73268ab0ff17:

  Linux 5.14-rc4 (2021-08-01 17:04:17 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
tags/soc-fixes-5.14-2

for you to fetch changes up to 19c1eb3605a1bcd784726380f520925948b2962e:

  Merge tag 'omap-for-v5.14/fixes-rc5-signed' of
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into
arm/fixes (2021-08-03 17:05:36 +0200)

----------------------------------------------------------------
ARM: SoC fixes for v5.14, part 2

Lots of small fixes for Arm SoCs this time, nothing
too worrying:

 - omap/beaglebone boot regression fix in gpt12 timer

 - revert for i.mx8 soc driver breaking as a platform_driver

 - kexec/kdump fixes for op-tee

 - various fixes for incorrect DT settings on imx, mvebu, omap,
   stm32, and tegra causing problems.

 - device tree fixes for static checks in nomadik, versatile, stm32

 - code fixes for issues found in build testing and with static
   checking on tegra, ixp4xx, imx, omap

Signed-off-by: Arnd Bergmann <arnd at arndb.de>

----------------------------------------------------------------
Allen Pais (2):
      optee: fix tee out of memory failure seen during kexec reboot
      firmware: tee_bnxt: Release TEE shm, session, and context during kexec

Arnd Bergmann (10):
      Merge tag 'tegra-for-5.14-rc3-arm64-dt' of
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into
arm/fixes
      ARM: ixp4xx: fix compile-testing soc drivers
      ARM: ixp4xx: goramo_mlr depends on old PCI driver
      Merge tag 'imx-fixes-5.14' of
git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into
arm/fixes
      Merge tag 'tee-kexec-fixes-for-v5.14' of
git://git.linaro.org:/people/jens.wiklander/linux-tee into arm/fixes
      Merge tag 'stm32-dt-for-v5.14-fixes-1' of
git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32 into
arm/fixes
      Merge tag 'mvebu-fixes-5.14-1' of
git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu into
arm/fixes
      soc: ixp4xx: fix printing resources
      soc: ixp4xx/qmgr: fix invalid __iomem access
      Merge tag 'omap-for-v5.14/fixes-rc5-signed' of
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into
arm/fixes

Colin Ian King (1):
      ARM: imx: fix missing 3rd argument in macro imx_mmdc_perf_init

Dario Binacchi (1):
      ARM: dts: am437x-l4: fix typo in can at 0 node

Dave Gerlach (1):
      ARM: dts: am43x-epos-evm: Reduce i2c0 bus speed for tps65218

Dmitry Osipenko (1):
      soc/tegra: Make regulator couplers depend on CONFIG_REGULATOR

Fabio Estevam (1):
      ARM: imx: common: Move prototype outside the SMP block

H. Nikolaus Schaller (1):
      omap5-board-common: remove not physically existing vdds_1v8_main
fixed-regulator

Jens Wiklander (1):
      tee: add tee_shm_alloc_kernel_buf()

Kevin Hilman (1):
      bus: ti-sysc: AM3: RNG is GP only

Lucas Stach (1):
      Revert "soc: imx8m: change to use platform driver"

Marek Vasut (4):
      ARM: dts: imx: Swap M53Menlo pinctrl_power_button/pinctrl_power_out pins
      ARM: dts: stm32: Prefer HW RTC on DHCOM SoM
      ARM: dts: stm32: Disable LAN8710 EDPD on DHCOM
      ARM: dts: stm32: Fix touchscreen IRQ line assignment on DHCOM

Maxime Chevallier (1):
      ARM: dts: imx6qdl-sr-som: Increase the PHY reset duration to 10ms

Michael Walle (1):
      arm64: dts: ls1028: sl28: fix networking for variant 2

Oleksandr Suvorov (1):
      ARM: dts: colibri-imx6ull: limit SDIO clock to 25MHz

Pali Roh?r (1):
      arm64: dts: armada-3720-turris-mox: remove mrvl,i2c-fast-mode

Sudeep Holla (1):
      ARM: dts: nomadik: Fix up interrupt controller node names

Sumit Garg (1):
      tee: Correct inappropriate usage of TEE_SHM_DMA_BUF flag

Tero Kristo (1):
      ARM: omap2+: hwmod: fix potential NULL pointer access

Tony Lindgren (2):
      bus: ti-sysc: Fix gpt12 system timer issue with reserved status
      Merge branch 'fixes-v5.14' into fixes

Tyler Hicks (4):
      optee: Fix memory leak when failing to register shm pages
      optee: Refuse to load the driver under the kdump kernel
      optee: Clear stale cache entries during initialization
      tpm_ftpm_tee: Free and unregister TEE shared memory during kexec

Vidya Sagar (1):
      arm64: tegra: Enable SMMU support for PCIe on Tegra194

Vladimir Oltean (2):
      arm64: dts: ls1028a: fix node name for the sysclk
      arm64: dts: armada-3720-turris-mox: fixed indices for the SDHC controllers

Yang Yingliang (2):
      ARM: imx: add missing iounmap()
      ARM: imx: add missing clk_disable_unprepare()

 arch/arm/boot/dts/am437x-l4.dtsi                   |  2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts               |  2 +-
 arch/arm/boot/dts/imx53-m53menlo.dts               |  4 +-
 arch/arm/boot/dts/imx6qdl-sr-som.dtsi              |  8 ++-
 arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi        |  1 +
 arch/arm/boot/dts/omap5-board-common.dtsi          |  9 +--
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi         |  4 +-
 arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi      | 24 ++++---
 arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi       |  5 +-
 arch/arm/mach-imx/common.h                         |  2 +-
 arch/arm/mach-imx/mmdc.c                           | 17 ++++-
 arch/arm/mach-ixp4xx/Kconfig                       |  1 +
 arch/arm/mach-omap2/omap_hwmod.c                   | 10 ++-
 .../freescale/fsl-ls1028a-kontron-sl28-var2.dts    |  2 +
 arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi     |  2 +-
 .../boot/dts/marvell/armada-3720-turris-mox.dts    |  3 +
 arch/arm64/boot/dts/nvidia/tegra194.dtsi           | 60 ++++++++++++++--
 drivers/bus/ti-sysc.c                              | 22 ++++--
 drivers/char/tpm/tpm_ftpm_tee.c                    |  8 +--
 drivers/firmware/broadcom/tee_bnxt_fw.c            | 14 +++-
 drivers/soc/Makefile                               |  2 +-
 drivers/soc/imx/soc-imx8m.c                        | 84 ++++------------------
 drivers/soc/ixp4xx/ixp4xx-npe.c                    | 12 ++--
 drivers/soc/ixp4xx/ixp4xx-qmgr.c                   | 10 +--
 drivers/soc/tegra/Kconfig                          |  6 +-
 drivers/tee/optee/call.c                           | 38 ++++++++--
 drivers/tee/optee/core.c                           | 43 ++++++++++-
 drivers/tee/optee/optee_private.h                  |  1 +
 drivers/tee/optee/rpc.c                            |  5 +-
 drivers/tee/optee/shm_pool.c                       | 20 ++++--
 drivers/tee/tee_shm.c                              | 20 +++++-
 include/linux/tee_drv.h                            |  2 +
 32 files changed, 292 insertions(+), 151 deletions(-)


From matthias.bgg at gmail.com  Fri Aug  6 08:17:09 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 6 Aug 2021 17:17:09 +0200
Subject: [PATCH v4 1/1] arm64: dts: mediatek: add MT6779 spi master dts
 node
In-Reply-To: <20210624021137.11513-1-mason.zhang@mediatek.com>
References: <20210624021137.11513-1-mason.zhang@mediatek.com>
Message-ID: <358eca25-34b5-bf12-67aa-98491bbcc9d2@gmail.com>



On 24/06/2021 04:11, Mason Zhang wrote:
> From: Mason Zhang <Mason.Zhang at mediatek.com>
> 
> This patch add spi master dts node for MT6779 SOC.
> 
> Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt6779.dtsi | 112 +++++++++++++++++++++++
>  1 file changed, 112 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
> index 370f309d32de..c81e76865d1b 100644
> --- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
> @@ -219,6 +219,118 @@
>  			status = "disabled";
>  		};
>  
> +		spi0: spi0 at 1100a000 {
> +			compatible = "mediatek,mt6779-spi",
> +				     "mediatek,mt6765-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			mediatek,pad-select = <0>;

pad-select should be part of board DTS.

> +			reg = <0 0x1100a000 0 0x1000>;
> +			interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_LOW 0>;
> +			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D2>,
> +				<&topckgen CLK_TOP_SPI>,
> +				<&infracfg_ao CLK_INFRA_SPI0>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";

Should be disabled by default and enabled in board DTS.

> +		};

This gives me the following warning:
arch/arm64/boot/dts/mediatek/mt6779.dtsi:145.4-27: Warning
(interrupts_property): /soc/spi0 at 1100a000:#interrupt-cells: size is (16),
expected multiple of 12

arch/arm64/boot/dts/mediatek/mt6779.dtsi:145.4-27: Warning
(interrupts_property): /soc/spi1 at 11010000:#interrupt-cells: size is (16),
expected multiple of 12

arch/arm64/boot/dts/mediatek/mt6779.dtsi:145.4-27: Warning
(interrupts_property): /soc/spi2 at 11012000:#interrupt-cells: size is (16),
expected multiple of 12

arch/arm64/boot/dts/mediatek/mt6779.dtsi:145.4-27: Warning
(interrupts_property): /soc/spi3 at 11013000:#interrupt-cells: size is (16),
expected multiple of 12

arch/arm64/boot/dts/mediatek/mt6779.dtsi:145.4-27: Warning
(interrupts_property): /soc/spi4 at 11018000:#interrupt-cells: size is (16),
expected multiple of 12

arch/arm64/boot/dts/mediatek/mt6779.dtsi:145.4-27: Warning
(interrupts_property): /soc/spi5 at 11019000:#interrupt-cells: size is (16),
expected multiple of 12

arch/arm64/boot/dts/mediatek/mt6779.dtsi:145.4-27: Warning
(interrupts_property): /soc/spi6 at 1101d000:#interrupt-cells: size is (16),
expected multiple of 12

arch/arm64/boot/dts/mediatek/mt6779.dtsi:145.4-27: Warning
(interrupts_property): /soc/spi7 at 1101e000:#interrupt-cells: size is (16),
expected multiple of 12


Regards,
Matthias

> +
> +		spi1: spi1 at 11010000 {
> +			compatible = "mediatek,mt6779-spi",
> +				     "mediatek,mt6765-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			mediatek,pad-select = <0>;
> +			reg = <0 0x11010000 0 0x1000>;
> +			interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_LOW 0>;
> +			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D2>,
> +				<&topckgen CLK_TOP_SPI>,
> +				<&infracfg_ao CLK_INFRA_SPI1>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";
> +		};
> +
> +		spi2: spi2 at 11012000 {
> +			compatible = "mediatek,mt6779-spi",
> +				     "mediatek,mt6765-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			mediatek,pad-select = <0>;
> +			reg = <0 0x11012000 0 0x1000>;
> +			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW 0>;
> +			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D2>,
> +				 <&topckgen CLK_TOP_SPI>,
> +				<&infracfg_ao CLK_INFRA_SPI2>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";
> +		};
> +
> +		spi3: spi3 at 11013000 {
> +			compatible = "mediatek,mt6779-spi",
> +				     "mediatek,mt6765-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			mediatek,pad-select = <0>;
> +			reg = <0 0x11013000 0 0x1000>;
> +			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_LOW 0>;
> +			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D2>,
> +				 <&topckgen CLK_TOP_SPI>,
> +				 <&infracfg_ao CLK_INFRA_SPI3>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";
> +		};
> +
> +		spi4: spi4 at 11018000 {
> +			compatible = "mediatek,mt6779-spi",
> +				     "mediatek,mt6765-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			mediatek,pad-select = <0>;
> +			reg = <0 0x11018000 0 0x1000>;
> +			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_LOW 0>;
> +			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D2>,
> +				 <&topckgen CLK_TOP_SPI>,
> +				 <&infracfg_ao CLK_INFRA_SPI4>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";
> +		};
> +
> +		spi5: spi5 at 11019000 {
> +			compatible = "mediatek,mt6779-spi",
> +				     "mediatek,mt6765-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			mediatek,pad-select = <0>;
> +			reg = <0 0x11019000 0 0x1000>;
> +			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_LOW 0>;
> +			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D2>,
> +				<&topckgen CLK_TOP_SPI>,
> +				<&infracfg_ao CLK_INFRA_SPI5>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";
> +		};
> +
> +		spi6: spi6 at 1101d000 {
> +			compatible = "mediatek,mt6779-spi",
> +				     "mediatek,mt6765-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			mediatek,pad-select = <0>;
> +			reg = <0 0x1101d000 0 0x1000>;
> +			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_LOW 0>;
> +			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D2>,
> +				 <&topckgen CLK_TOP_SPI>,
> +				 <&infracfg_ao CLK_INFRA_SPI6>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";
> +		};
> +
> +		spi7: spi7 at 1101e000 {
> +			compatible = "mediatek,mt6779-spi",
> +				     "mediatek,mt6765-spi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			mediatek,pad-select = <0>;
> +			reg = <0 0x1101e000 0 0x1000>;
> +			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_LOW 0>;
> +			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D2>,
> +				 <&topckgen CLK_TOP_SPI>,
> +				 <&infracfg_ao CLK_INFRA_SPI7>;
> +			clock-names = "parent-clk", "sel-clk", "spi-clk";
> +		};
> +
>  		audio: clock-controller at 11210000 {
>  			compatible = "mediatek,mt6779-audio", "syscon";
>  			reg = <0 0x11210000 0 0x1000>;
> 


From semen.protsenko at linaro.org  Fri Aug  6 08:21:38 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:38 +0300
Subject: [PATCH v2 0/8] Add minimal support for Exynos850 SoC
Message-ID: <20210806152146.16107-1-semen.protsenko@linaro.org>

This patch series adds initial platform support for Samsung Exynos850
SoC [1]. With this patchset it's possible to run the kernel with BusyBox
rootfs as a RAM disk. More advanced platform support (like MMC driver
additions) will be added later. The idea is to keep the first submission
minimal to ease the review, and then build up on top of that.

[1] https://www.samsung.com/semiconductor/minisite/exynos/products/mobileprocessor/exynos-850/

Changes in v2:
 * Rebased on top of current linux-mainline
 * Removed patch ("pinctrl: samsung: Fix pinctrl bank pin count"); it
   was sent separately, as it's an independent fix
 * Made the patch ("dt-bindings: pinctrl: samsung: Add Exynos850 doc")
   to be the first in series
 * Removed patch ("MAINTAINERS: Changes in v2"); will add that later,
   when proper clock driver is implemented
 * Removed patch ("dt-bindings: clock: Add bindings for Exynos850 clock
   controller"); will add clock bindings later, when proper clock driver
   is implemented
 * Removed patch ("dt-bindings: interrupt-controller: Add IRQ constants
   for Exynos850"), and used hard-coded IRQ numbers in dts instead
 * See also changes in each particular patch

Sam Protsenko (8):
  dt-bindings: pinctrl: samsung: Add Exynos850 doc
  pinctrl: samsung: Add Exynos850 SoC specific data
  dt-bindings: serial: samsung: Add Exynos850 doc
  tty: serial: samsung: Init USI to keep clocks running
  tty: serial: samsung: Fix driver data macros style
  tty: serial: samsung: Add Exynos850 SoC data
  clk: samsung: Add Exynos850 clock driver stub
  arm64: dts: exynos: Add Exynos850 SoC support

 .../bindings/pinctrl/samsung-pinctrl.txt      |   1 +
 .../bindings/serial/samsung_uart.yaml         |   1 +
 .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos850.dtsi     | 256 ++++++
 drivers/clk/samsung/Makefile                  |   1 +
 drivers/clk/samsung/clk-exynos850.c           |  64 ++
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 116 +++
 drivers/pinctrl/samsung/pinctrl-exynos.h      |  29 +
 drivers/pinctrl/samsung/pinctrl-samsung.c     |   2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |   1 +
 drivers/tty/serial/samsung_tty.c              |  49 +-
 include/linux/serial_s3c.h                    |   9 +
 12 files changed, 1274 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
 create mode 100644 drivers/clk/samsung/clk-exynos850.c

-- 
2.30.2



From semen.protsenko at linaro.org  Fri Aug  6 08:21:39 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:39 +0300
Subject: [PATCH v2 1/8] dt-bindings: pinctrl: samsung: Add Exynos850 doc
In-Reply-To: <20210806152146.16107-1-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
Message-ID: <20210806152146.16107-2-semen.protsenko@linaro.org>

Document compatible string for Exynos850 SoC. Nothing else is changed,
as Exynos850 SoC uses already existing samsung pinctrl driver.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - This patch was made the first in the series

 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 38a1416fd2cd..e7a1b1880375 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -22,6 +22,7 @@ Required Properties:
   - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
   - "samsung,exynos5433-pinctrl": for Exynos5433 compatible pin-controller.
   - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
+  - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
-- 
2.30.2



From semen.protsenko at linaro.org  Fri Aug  6 08:21:40 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:40 +0300
Subject: [PATCH v2 2/8] pinctrl: samsung: Add Exynos850 SoC specific data
In-Reply-To: <20210806152146.16107-1-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
Message-ID: <20210806152146.16107-3-semen.protsenko@linaro.org>

Add Samsung Exynos850 SoC specific data to enable pinctrl support for
all platforms based on Exynos850.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Removed .suspend/.resume callbacks, as retention registers are not
    implemented yet for Exynos850
  - Removed .eint_gpio_init for AUD domain, as there are no external
    interrupts available for that domain

 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 116 ++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-exynos.h      |  29 +++++
 drivers/pinctrl/samsung/pinctrl-samsung.c     |   2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |   1 +
 4 files changed, 148 insertions(+)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index b6e56422a700..3157bdf0233c 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -40,6 +40,24 @@ static const struct samsung_pin_bank_type exynos5433_bank_type_alive = {
 	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
 };
 
+/*
+ * Bank type for non-alive type. Bit fields:
+ * CON: 4, DAT: 1, PUD: 4, DRV: 4, CONPDN: 2, PUDPDN: 4
+ */
+static struct samsung_pin_bank_type exynos850_bank_type_off  = {
+	.fld_width = { 4, 1, 4, 4, 2, 4, },
+	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
+};
+
+/*
+ * Bank type for alive type. Bit fields:
+ * CON: 4, DAT: 1, PUD: 4, DRV: 4
+ */
+static struct samsung_pin_bank_type exynos850_bank_type_alive = {
+	.fld_width = { 4, 1, 4, 4, },
+	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
+};
+
 /* Pad retention control code for accessing PMU regmap */
 static atomic_t exynos_shared_retention_refcnt;
 
@@ -422,3 +440,101 @@ const struct samsung_pinctrl_of_match_data exynos7_of_data __initconst = {
 	.ctrl		= exynos7_pin_ctrl,
 	.num_ctrl	= ARRAY_SIZE(exynos7_pin_ctrl),
 };
+
+/* pin banks of exynos850 pin-controller 0 (ALIVE) */
+static struct samsung_pin_bank_data exynos850_pin_banks0[] = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS9_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
+	EXYNOS9_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
+	EXYNOS9_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
+	EXYNOS9_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
+	EXYNOS9_PIN_BANK_EINTW(4, 0x080, "gpa4", 0x10),
+	EXYNOS9_PIN_BANK_EINTN(3, 0x0A0, "gpq0"),
+};
+
+/* pin banks of exynos850 pin-controller 1 (CMGP) */
+static struct samsung_pin_bank_data exynos850_pin_banks1[] = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS9_PIN_BANK_EINTW(1, 0x000, "gpm0", 0x00),
+	EXYNOS9_PIN_BANK_EINTW(1, 0x020, "gpm1", 0x04),
+	EXYNOS9_PIN_BANK_EINTW(1, 0x040, "gpm2", 0x08),
+	EXYNOS9_PIN_BANK_EINTW(1, 0x060, "gpm3", 0x0C),
+	EXYNOS9_PIN_BANK_EINTW(1, 0x080, "gpm4", 0x10),
+	EXYNOS9_PIN_BANK_EINTW(1, 0x0A0, "gpm5", 0x14),
+	EXYNOS9_PIN_BANK_EINTW(1, 0x0C0, "gpm6", 0x18),
+	EXYNOS9_PIN_BANK_EINTW(1, 0x0E0, "gpm7", 0x1C),
+};
+
+/* pin banks of exynos850 pin-controller 2 (AUD) */
+static struct samsung_pin_bank_data exynos850_pin_banks2[] = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS9_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00),
+	EXYNOS9_PIN_BANK_EINTG(5, 0x020, "gpb1", 0x04),
+};
+
+/* pin banks of exynos850 pin-controller 3 (HSI) */
+static struct samsung_pin_bank_data exynos850_pin_banks3[] = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS9_PIN_BANK_EINTG(6, 0x000, "gpf2", 0x00),
+};
+
+/* pin banks of exynos850 pin-controller 4 (CORE) */
+static struct samsung_pin_bank_data exynos850_pin_banks4[] = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS9_PIN_BANK_EINTG(4, 0x000, "gpf0", 0x00),
+	EXYNOS9_PIN_BANK_EINTG(8, 0x020, "gpf1", 0x04),
+};
+
+/* pin banks of exynos850 pin-controller 5 (PERI) */
+static struct samsung_pin_bank_data exynos850_pin_banks5[] = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS9_PIN_BANK_EINTG(2, 0x000, "gpg0", 0x00),
+	EXYNOS9_PIN_BANK_EINTG(6, 0x020, "gpp0", 0x04),
+	EXYNOS9_PIN_BANK_EINTG(4, 0x040, "gpp1", 0x08),
+	EXYNOS9_PIN_BANK_EINTG(4, 0x060, "gpp2", 0x0C),
+	EXYNOS9_PIN_BANK_EINTG(8, 0x080, "gpg1", 0x10),
+	EXYNOS9_PIN_BANK_EINTG(8, 0x0A0, "gpg2", 0x14),
+	EXYNOS9_PIN_BANK_EINTG(1, 0x0C0, "gpg3", 0x18),
+	EXYNOS9_PIN_BANK_EINTG(3, 0x0E0, "gpc0", 0x1C),
+	EXYNOS9_PIN_BANK_EINTG(6, 0x100, "gpc1", 0x20),
+};
+
+static const struct samsung_pin_ctrl exynos850_pin_ctrl[] __initconst = {
+	{
+		/* pin-controller instance 0 ALIVE data */
+		.pin_banks	= exynos850_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks0),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.eint_wkup_init = exynos_eint_wkup_init,
+	}, {
+		/* pin-controller instance 1 CMGP data */
+		.pin_banks	= exynos850_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks1),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.eint_wkup_init = exynos_eint_wkup_init,
+	}, {
+		/* pin-controller instance 2 AUD data */
+		.pin_banks	= exynos850_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks2),
+	}, {
+		/* pin-controller instance 3 HSI data */
+		.pin_banks	= exynos850_pin_banks3,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks3),
+		.eint_gpio_init = exynos_eint_gpio_init,
+	}, {
+		/* pin-controller instance 4 CORE data */
+		.pin_banks	= exynos850_pin_banks4,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks4),
+		.eint_gpio_init = exynos_eint_gpio_init,
+	}, {
+		/* pin-controller instance 5 PERI data */
+		.pin_banks	= exynos850_pin_banks5,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks5),
+		.eint_gpio_init = exynos_eint_gpio_init,
+	},
+};
+
+const struct samsung_pinctrl_of_match_data exynos850_of_data __initconst = {
+	.ctrl		= exynos850_pin_ctrl,
+	.num_ctrl	= ARRAY_SIZE(exynos850_pin_ctrl),
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
index da1ec13697e7..595086f2d5dd 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.h
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
@@ -108,6 +108,35 @@
 		.pctl_res_idx   = pctl_idx,			\
 	}							\
 
+#define EXYNOS9_PIN_BANK_EINTN(pins, reg, id)			\
+	{							\
+		.type		= &exynos850_bank_type_alive,	\
+		.pctl_offset	= reg,				\
+		.nr_pins	= pins,				\
+		.eint_type	= EINT_TYPE_NONE,		\
+		.name		= id				\
+	}
+
+#define EXYNOS9_PIN_BANK_EINTG(pins, reg, id, offs)		\
+	{							\
+		.type		= &exynos850_bank_type_off,	\
+		.pctl_offset	= reg,				\
+		.nr_pins	= pins,				\
+		.eint_type	= EINT_TYPE_GPIO,		\
+		.eint_offset	= offs,				\
+		.name		= id				\
+	}
+
+#define EXYNOS9_PIN_BANK_EINTW(pins, reg, id, offs)		\
+	{							\
+		.type		= &exynos850_bank_type_alive,	\
+		.pctl_offset	= reg,				\
+		.nr_pins	= pins,				\
+		.eint_type	= EINT_TYPE_WKUP,		\
+		.eint_offset	= offs,				\
+		.name		= id				\
+	}
+
 /**
  * struct exynos_weint_data: irq specific data for all the wakeup interrupts
  * generated by the external wakeup interrupt controller.
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 2975b4369f32..2a0fc63516f1 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1264,6 +1264,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = &exynos5433_of_data },
 	{ .compatible = "samsung,exynos7-pinctrl",
 		.data = &exynos7_of_data },
+	{ .compatible = "samsung,exynos850-pinctrl",
+		.data = &exynos850_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index de44f8ec330b..4c2149e9c544 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -339,6 +339,7 @@ extern const struct samsung_pinctrl_of_match_data exynos5410_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos5420_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos5433_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
-- 
2.30.2



From semen.protsenko at linaro.org  Fri Aug  6 08:21:41 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:41 +0300
Subject: [PATCH v2 3/8] dt-bindings: serial: samsung: Add Exynos850 doc
In-Reply-To: <20210806152146.16107-1-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
Message-ID: <20210806152146.16107-4-semen.protsenko@linaro.org>

Add compatible string for Exynos850 SoC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - None

 Documentation/devicetree/bindings/serial/samsung_uart.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
index f064e5b76cf1..2940afb874b3 100644
--- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml
+++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
@@ -26,6 +26,7 @@ properties:
           - samsung,s3c6400-uart
           - samsung,s5pv210-uart
           - samsung,exynos4210-uart
+          - samsung,exynos850-uart
 
   reg:
     maxItems: 1
-- 
2.30.2



From semen.protsenko at linaro.org  Fri Aug  6 08:21:42 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:42 +0300
Subject: [PATCH v2 4/8] tty: serial: samsung: Init USI to keep clocks running
In-Reply-To: <20210806152146.16107-1-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
Message-ID: <20210806152146.16107-5-semen.protsenko@linaro.org>

UART block is a part of USI (Universal Serial Interface) IP-core in
Samsung SoCs since Exynos9810 (e.g. in Exynos850). USI allows one to
enable one of three types of serial interface: UART, SPI or I2C. That's
possible because USI shares almost all internal circuits within each
protocol. USI also provides some additional registers so it's possible
to configure it.

One USI register called USI_OPTION has reset value of 0x0. Because of
this the clock gating behavior is controlled by hardware (HWACG =
Hardware Auto Clock Gating), which simply means the serial won't work
after reset as is. In order to make it work, USI_OPTION[2:1] bits must
be set to 0b01, so that HWACG is controlled manually (by software).
Bits meaning:
  - CLKREQ_ON = 1: clock is continuously provided to IP
  - CLKSTOP_ON = 0: drive IP_CLKREQ to High (needs to be set along with
                    CLKREQ_ON = 1)

USI is not present on older chips, like s3c2410, s3c2412, s3c2440,
s3c6400, s5pv210, exynos5433, exynos4210. So the new boolean field
'.has_usi' was added to struct s3c24xx_uart_info. USI registers will be
only actually accessed when '.has_usi' field is set to "1".

This feature is needed for further serial enablement on Exynos850, but
some other new Exynos chips (like Exynos9810) may benefit from this
feature as well.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Non-intrusive modification of USI registers
  - Improved comments
  - Rearranged USI register definitions to conform with existing style

 drivers/tty/serial/samsung_tty.c | 32 +++++++++++++++++++++++++++++++-
 include/linux/serial_s3c.h       |  9 +++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 9fbc61151c2e..b8034c1168e0 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -65,6 +65,7 @@ enum s3c24xx_port_type {
 struct s3c24xx_uart_info {
 	char			*name;
 	enum s3c24xx_port_type	type;
+	unsigned int		has_usi;
 	unsigned int		port_type;
 	unsigned int		fifosize;
 	unsigned long		rx_fifomask;
@@ -1352,6 +1353,28 @@ static int apple_s5l_serial_startup(struct uart_port *port)
 	return ret;
 }
 
+static void exynos_usi_init(struct uart_port *port)
+{
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+	struct s3c24xx_uart_info *info = ourport->info;
+	unsigned int val;
+
+	if (!info->has_usi)
+		return;
+
+	/* Clear the software reset of USI block (it's set at startup) */
+	val = rd_regl(port, USI_CON);
+	val &= ~USI_CON_RESET_MASK;
+	wr_regl(port, USI_CON, val);
+	udelay(1);
+
+	/* Continuously provide the clock to USI IP w/o gating (for Rx mode) */
+	val = rd_regl(port, USI_OPTION);
+	val &= ~USI_OPTION_HWACG_MASK;
+	val |= USI_OPTION_HWACG_CLKREQ_ON;
+	wr_regl(port, USI_OPTION, val);
+}
+
 /* power power management control */
 
 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
@@ -1379,6 +1402,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
 		if (!IS_ERR(ourport->baudclk))
 			clk_prepare_enable(ourport->baudclk);
 
+		exynos_usi_init(port);
 		break;
 	default:
 		dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level);
@@ -2102,6 +2126,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 	if (ret)
 		pr_warn("uart: failed to enable baudclk\n");
 
+	exynos_usi_init(port);
+
 	/* Keep all interrupts masked and cleared */
 	switch (ourport->info->type) {
 	case TYPE_S3C6400:
@@ -2750,10 +2776,11 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 #endif
 
 #if defined(CONFIG_ARCH_EXYNOS)
-#define EXYNOS_COMMON_SERIAL_DRV_DATA				\
+#define EXYNOS_COMMON_SERIAL_DRV_DATA_USI(_has_usi)		\
 	.info = &(struct s3c24xx_uart_info) {			\
 		.name		= "Samsung Exynos UART",	\
 		.type		= TYPE_S3C6400,			\
+		.has_usi	= _has_usi,			\
 		.port_type	= PORT_S3C6400,			\
 		.has_divslot	= 1,				\
 		.rx_fifomask	= S5PV210_UFSTAT_RXMASK,	\
@@ -2773,6 +2800,9 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 		.has_fracval	= 1,				\
 	}							\
 
+#define EXYNOS_COMMON_SERIAL_DRV_DATA				\
+	EXYNOS_COMMON_SERIAL_DRV_DATA_USI(0)
+
 static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
 	EXYNOS_COMMON_SERIAL_DRV_DATA,
 	.fifosize = { 256, 64, 16, 16 },
diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h
index f6c3323fc4c5..cf0de4a86640 100644
--- a/include/linux/serial_s3c.h
+++ b/include/linux/serial_s3c.h
@@ -27,6 +27,15 @@
 #define S3C2410_UERSTAT	  (0x14)
 #define S3C2410_UFSTAT	  (0x18)
 #define S3C2410_UMSTAT	  (0x1C)
+#define USI_CON		  (0xC4)
+#define USI_OPTION	  (0xC8)
+
+#define USI_CON_RESET			(1<<0)
+#define USI_CON_RESET_MASK		(1<<0)
+
+#define USI_OPTION_HWACG_CLKREQ_ON	(1<<1)
+#define USI_OPTION_HWACG_CLKSTOP_ON	(1<<2)
+#define USI_OPTION_HWACG_MASK		(3<<1)
 
 #define S3C2410_LCON_CFGMASK	  ((0xF<<3)|(0x3))
 
-- 
2.30.2



From semen.protsenko at linaro.org  Fri Aug  6 08:21:43 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:43 +0300
Subject: [PATCH v2 5/8] tty: serial: samsung: Fix driver data macros style
In-Reply-To: <20210806152146.16107-1-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
Message-ID: <20210806152146.16107-6-semen.protsenko@linaro.org>

Make checkpatch happy by fixing this error:

    ERROR: Macros with complex values should be enclosed in parentheses

Although this change is made to keep macros consistent with consequent
patches (adding driver data for new SoC), it's intentionally added as a
separate patch to ease possible porting efforts in future.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Added Reviewed-by tag by Krzysztof Kozlowski

 drivers/tty/serial/samsung_tty.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index b8034c1168e0..130bdc978e93 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -2816,8 +2816,8 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
 #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
 #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data)
 #else
-#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
-#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL
+#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
+#define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
 #endif
 
 #ifdef CONFIG_ARCH_APPLE
-- 
2.30.2



From semen.protsenko at linaro.org  Fri Aug  6 08:21:44 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:44 +0300
Subject: [PATCH v2 6/8] tty: serial: samsung: Add Exynos850 SoC data
In-Reply-To: <20210806152146.16107-1-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
Message-ID: <20210806152146.16107-7-semen.protsenko@linaro.org>

Add serial driver data for Exynos850 SoC. This driver data is basically
reusing EXYNOS_COMMON_SERIAL_DRV_DATA, which is common for all Exynos
chips, but also enables USI init, which was added in previous commit:
"tty: serial: samsung: Init USI to keep clocks running".

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Fixed default fifo sizes

 drivers/tty/serial/samsung_tty.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 130bdc978e93..a069e7bb858f 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -2813,11 +2813,19 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
 	.fifosize = { 64, 256, 16, 256 },
 };
 
+static struct s3c24xx_serial_drv_data exynos850_serial_drv_data = {
+	EXYNOS_COMMON_SERIAL_DRV_DATA_USI(1),
+	.fifosize = { 256, 64, 64, 64 },
+};
+
 #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
 #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data)
+#define EXYNOS850_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos850_serial_drv_data)
+
 #else
 #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
 #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
+#define EXYNOS850_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
 #endif
 
 #ifdef CONFIG_ARCH_APPLE
@@ -2873,6 +2881,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
 	}, {
 		.name		= "s5l-uart",
 		.driver_data	= S5L_SERIAL_DRV_DATA,
+	}, {
+		.name		= "exynos850-uart",
+		.driver_data	= EXYNOS850_SERIAL_DRV_DATA,
 	},
 	{ },
 };
@@ -2896,6 +2907,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = {
 		.data = (void *)EXYNOS5433_SERIAL_DRV_DATA },
 	{ .compatible = "apple,s5l-uart",
 		.data = (void *)S5L_SERIAL_DRV_DATA },
+	{ .compatible = "samsung,exynos850-uart",
+		.data = (void *)EXYNOS850_SERIAL_DRV_DATA },
 	{},
 };
 MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
-- 
2.30.2



From semen.protsenko at linaro.org  Fri Aug  6 08:21:45 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:45 +0300
Subject: [PATCH v2 7/8] clk: samsung: Add Exynos850 clock driver stub
In-Reply-To: <20210806152146.16107-1-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
Message-ID: <20210806152146.16107-8-semen.protsenko@linaro.org>

For now it's just a stub driver to make the serial driver work. Later it
will be implemented properly. This driver doesn't really change clocks,
only registers the UART clock as a fixed-rate clock. Without this clock
driver the UART driver won't work, as it's trying to obtain "uart" clock
and fails if it's not able to.

In order to get a functional serial console we have to implement that
minimal clock driver with "uart" clock. It's not necessary to actually
configure clocks, as those are already configured in bootloader, so
kernel can rely on that for now.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
  - Used hard coded clock indexes, as clock bindings were removed; will
    add clock bindings back (reimplemented) once proper clock driver is
    ready
  - Removed .data = 0 for exynos850-oscclk, as it's in BSS section
  - Removed comma for terminator {}
  - Made exynos850_clk_init() static
  - Removed checking np for NULL, as it's already done in of_iomap()

 drivers/clk/samsung/Makefile        |  1 +
 drivers/clk/samsung/clk-exynos850.c | 64 +++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-exynos850.c

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 028b2e27a37e..c46cf11e4d0b 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos5433.o
 obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
 obj-$(CONFIG_EXYNOS_CLKOUT)	+= clk-exynos-clkout.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
 obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
 obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
 obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
new file mode 100644
index 000000000000..36c7c7fe7cf0
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos850.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Common Clock Framework support for Exynos850 SoC.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "clk.h"
+
+/* Will be extracted to bindings header once proper clk driver is implemented */
+#define OSCCLK		1
+#define DOUT_UART	2
+#define CLK_NR_CLKS	3
+
+/* Fixed rate clocks generated outside the SoC */
+static struct samsung_fixed_rate_clock exynos850_fixed_rate_ext_clks[] __initdata = {
+	FRATE(OSCCLK, "fin_pll", NULL, 0, 26000000),
+};
+
+/*
+ * Model the UART clock as a fixed-rate clock for now, to make serial driver
+ * work. This clock is already configured in the bootloader.
+ */
+static const struct samsung_fixed_rate_clock exynos850_peri_clks[] __initconst = {
+	FRATE(DOUT_UART, "DOUT_UART", NULL, 0, 200000000),
+};
+
+static const struct of_device_id ext_clk_match[] __initconst = {
+	{ .compatible = "samsung,exynos850-oscclk" },
+	{}
+};
+
+static void __init exynos850_clk_init(struct device_node *np)
+{
+	void __iomem *reg_base;
+	struct samsung_clk_provider *ctx;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base)
+		panic("%s: failed to map registers\n", __func__);
+
+	ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
+	if (!ctx)
+		panic("%s: unable to allocate ctx\n", __func__);
+
+	samsung_clk_of_register_fixed_ext(ctx,
+			exynos850_fixed_rate_ext_clks,
+			ARRAY_SIZE(exynos850_fixed_rate_ext_clks),
+			ext_clk_match);
+
+	samsung_clk_register_fixed_rate(ctx, exynos850_peri_clks,
+			ARRAY_SIZE(exynos850_peri_clks));
+
+	samsung_clk_of_add_provider(np, ctx);
+}
+
+CLK_OF_DECLARE(exynos850_clk, "samsung,exynos850-clock", exynos850_clk_init);
-- 
2.30.2



From semen.protsenko at linaro.org  Fri Aug  6 08:21:46 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri,  6 Aug 2021 18:21:46 +0300
Subject: [PATCH v2 8/8] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <20210806152146.16107-1-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
Message-ID: <20210806152146.16107-9-semen.protsenko@linaro.org>

Samsung Exynos850 is ARMv8-based mobile-oriented SoC.

This patch adds minimal SoC support by including next Device Tree nodes:

1. Octa cores (Cortex-A55), supporting PSCI v1.0
2. ARM architecture timer (armv8-timer)
3. Interrupt controller (GIC-400)
4. Clock controller node (using stub driver for now)
5. Pinctrl nodes for GPIO
6. Serial node

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v2:
 * Commit message:
   - Documented added dts features instead of CPU features

 * exynos850-usi.dtsi:
   - Removed, moved everything to exynos850.dtsi

 * exynos850.dtsi:
   - Root node:
     - Added comment about engineering name (Exynos3830)
     - Renamed pinctrl nodes, adding domain names
     - Used hard coded IRQ numbers instead of named constants everywhere
     - Added soc node, moved next nodes there: gic, clock, pinctrls and
       serial
     - Used address-cells=1 for soc node and removed unneeded 0x0 from
       reg properties
     - Moved exynos850-pinctrl.dtsi include line to the end of
       exynos850.dtsi
     - Coding style fixes
   - cpus:
     - Used address-cells=1 for cpus node
     - Renamed cpu at 0001 to cpu at 1, and so on
     - Left only "arm,cortex-a55" for cpus compatible
     - Renamed reg = <0x0001> to <0x1> for cpus
   - armv8 timer:
     - Add comment about missing HV timer IRQ to armv8 timer node
     - Removed not existing properties from armv8 timer node
     - Fixed cpu number in CPU_MASK()
     - Removed obsolete clock-frequency property
   - GIC:
     - Fixed GIC type to be GIC-400
     - Fixed size of GIC's 2nd region to be 0x2000
   - serial node:
     - Hard coded clock number for serial_0 for now; will replace with
       named const once proper clock driver is implemented
     - Removed gate_uart_clk0 clock from serial_0, as that clock is not
       supported in serial driver anyway (yet)
   - clock node:
     - Fixed clock controller node name (@0x12.. -> @12..)

 * exynos850-pinctrl.dtsi:
   - Referenced pinctrl nodes instead of defining those again in root node
   - Fixed interrupt-cells (3 -> 2)
   - Fixed USI related comments for pin config nodes
   - Removed decon_f_te_* and fm_lna_en nodes (won't be used)
   - Reordered pin config nodes by pin numbers
   - Improved all comments
   - Used existing named constants for pin-function and pin-pud
   - Fixed node names (used hyphens instead of underscore)
   - Fixed warnings found in W=1 build

 .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos850.dtsi     | 256 ++++++
 2 files changed, 1004 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi

diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
new file mode 100644
index 000000000000..ba5d5f33e2f6
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
@@ -0,0 +1,748 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (C) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
+ * tree nodes in this file.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_alive {
+	gpa0: gpa0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa1: gpa1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa2: gpa2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa3: gpa3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa4: gpa4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpq0: gpq0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* I2C5 (also called CAM_PMIC_I2C in TRM) */
+	i2c5_bus: i2c5-bus {
+		samsung,pins = "gpa3-5", "gpa3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* I2C6 (also called MOTOR_I2C in TRM) */
+	i2c6_bus: i2c6-bus {
+		samsung,pins = "gpa3-7", "gpa4-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI: UART */
+	uart0_bus: uart0-bus {
+		samsung,pins = "gpq0-0", "gpq0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+};
+
+&pinctrl_cmgp {
+	gpm0: gpm0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm1: gpm1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm2: gpm2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm3: gpm3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm4: gpm4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm5: gpm5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	/* USI_CMGP0: HSI2C function */
+	hsi2c3_bus: hsi2c3-bus {
+		samsung,pins = "gpm0-0", "gpm1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI_CMGP0: UART function (4 pins, Auto Flow Control) */
+	uart1_bus_single: uart1-bus {
+		samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP0: UART function (2 pins, Non-Auto Flow Control) */
+	uart1_bus_dual: uart1-bus-dual {
+		samsung,pins = "gpm0-0", "gpm1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP0: SPI function */
+	spi1_bus: spi1-bus {
+		samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi1_cs: spi1-cs {
+		samsung,pins = "gpm3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi1_cs_func: spi1-cs-func {
+		samsung,pins = "gpm3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI_CMGP1: HSI2C function */
+	hsi2c4_bus: hsi2c4-bus {
+		samsung,pins = "gpm4-0", "gpm5-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI_CMGP1: UART function (4 pins, Auto Flow Control) */
+	uart2_bus_single: uart2-bus {
+		samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP1: UART function (2 pins, Non-Auto Flow Control) */
+	uart2_bus_dual: uart2-bus-dual {
+		samsung,pins = "gpm4-0", "gpm5-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP1: SPI function */
+	spi2_bus: spi2-bus {
+		samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi2_cs: spi2-cs {
+		samsung,pins = "gpm7-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi2_cs_func: spi2-cs-func {
+		samsung,pins = "gpm7-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+};
+
+&pinctrl_aud {
+	gpb0: gpb0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	aud_codec_mclk: aud-codec-mclk {
+		samsung,pins = "gpb0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_codec_mclk_idle: aud-codec-mclk-idle {
+		samsung,pins = "gpb0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s0_bus: aud-i2s0-bus {
+		samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s0_idle: aud-i2s0-idle {
+		samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s1_bus: aud-i2s1-bus {
+		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s1_idle: aud-i2s1-idle {
+		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_fm_bus: aud-fm-bus {
+		samsung,pins = "gpb1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_fm_idle: aud-fm-idle {
+		samsung,pins = "gpb1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+};
+
+&pinctrl_hsi {
+	gpf2: gpf2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sd2_clk: sd2-clk {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_clk_fast_slew_rate_1x: sd2-clk-fast-slew-rate-1x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	sd2_clk_fast_slew_rate_1_5x: sd2-clk-fast-slew-rate-1-5x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <1>;
+	};
+
+	sd2_clk_fast_slew_rate_2x: sd2-clk-fast-slew-rate-2x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_clk_fast_slew_rate_2_5x: sd2-clk-fast-slew-rate-2-5x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_clk_fast_slew_rate_3x: sd2-clk-fast-slew-rate-3x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <4>;
+	};
+
+	sd2_clk_fast_slew_rate_4x: sd2-clk-fast-slew-rate-4x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <5>;
+	};
+
+	sd2_cmd: sd2-cmd {
+		samsung,pins = "gpf2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <2>;
+	 };
+
+	sd2_bus1: sd2-bus-width1 {
+		samsung,pins = "gpf2-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_bus4: sd2-bus-width4 {
+		samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_pins_as_pdn: sd2-pins-as-pdn {
+		samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+			       "gpf2-4", "gpf2-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+};
+
+&pinctrl_core {
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sd0_clk: sd0-clk {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_clk_fast_slew_rate_1x: sd0-clk-fast-slew-rate-1x {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <1>;
+	};
+
+	sd0_clk_fast_slew_rate_2x: sd0-clk-fast-slew-rate-2x {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd0_clk_fast_slew_rate_3x: sd0-clk-fast-slew-rate-3x {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd0_clk_fast_slew_rate_4x: sd0-clk-fast-slew-rate-4x {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_cmd: sd0-cmd {
+		samsung,pins = "gpf0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_rdqs: sd0-rdqs {
+		samsung,pins = "gpf0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_nreset: sd0-nreset {
+		samsung,pins = "gpf0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus1: sd0-bus-width1 {
+		samsung,pins = "gpf1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus4: sd0-bus-width4 {
+		samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus8: sd0-bus-width8 {
+		samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+};
+
+&pinctrl_peri {
+	gpg0: gpg0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp0: gpp0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+	gpp1: gpp1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp2: gpp2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc0: gpc0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc1: gpc1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* USI: HSI2C0 */
+	hsi2c0_bus: hsi2c0-bus {
+		samsung,pins = "gpc1-0", "gpc1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI: HSI2C1 */
+	hsi2c1_bus: hsi2c1-bus {
+		samsung,pins = "gpc1-2", "gpc1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI: HSI2C2 */
+	hsi2c2_bus: hsi2c2-bus {
+		samsung,pins = "gpc1-4", "gpc1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI: SPI */
+	spi0_bus: spi0-bus {
+		samsung,pins = "gpp2-0", "gpp2-2", "gpp2-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi0_cs: spi0-cs {
+		samsung,pins = "gpp2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi0_cs_func: spi0-cs-func {
+		samsung,pins = "gpp2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c0_bus: i2c0-bus {
+		samsung,pins = "gpp0-0", "gpp0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c1_bus: i2c1-bus {
+		samsung,pins = "gpp0-2", "gpp0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c2_bus: i2c2-bus {
+		samsung,pins = "gpp0-4", "gpp0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c3_bus: i2c3-bus {
+		samsung,pins = "gpp1-0", "gpp1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c4_bus: i2c4-bus {
+		samsung,pins = "gpp1-2", "gpp1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	sensor_mclk0_in: sensor-mclk0-in {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk0_out: sensor-mclk0-out {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk0_fn: sensor-mclk0-fn {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk1_in: sensor-mclk1-in {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk1_out: sensor-mclk1-out {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk1_fn: sensor-mclk1-fn {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk2_in: sensor-mclk2-in {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk2_out: sensor-mclk2-out {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk2_fn: sensor-mclk2-fn {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	xclkout: xclkout {
+		samsung,pins = "gpq0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
new file mode 100644
index 000000000000..9d8c1402685e
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung Exynos850 SoC device tree source
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Samsung Exynos850 SoC device nodes are listed in this file.
+ * Exynos based board files can include this file and provide
+ * values for board specific bindings.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	/* Also known under engineering name Exynos3830 */
+	compatible = "samsung,exynos850";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	aliases {
+		pinctrl0 = &pinctrl_alive;
+		pinctrl1 = &pinctrl_cmgp;
+		pinctrl2 = &pinctrl_aud;
+		pinctrl3 = &pinctrl_hsi;
+		pinctrl4 = &pinctrl_core;
+		pinctrl5 = &pinctrl_peri;
+		serial0 = &serial_0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+				core2 {
+					cpu = <&cpu2>;
+				};
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+				core1 {
+					cpu = <&cpu5>;
+				};
+				core2 {
+					cpu = <&cpu6>;
+				};
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0>;
+			enable-method = "psci";
+		};
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x1>;
+			enable-method = "psci";
+		};
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x2>;
+			enable-method = "psci";
+		};
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x3>;
+			enable-method = "psci";
+		};
+		cpu4: cpu at 4 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+		};
+		cpu5: cpu at 5 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x101>;
+			enable-method = "psci";
+		};
+		cpu6: cpu at 6 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x102>;
+			enable-method = "psci";
+		};
+		cpu7: cpu at 7 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x103>;
+			enable-method = "psci";
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		/* Hypervisor Virtual Timer interrupt is not wired to GIC */
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) |
+					  IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x0 0x20000000>;
+
+		gic: interrupt-controller at 12a01000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			reg = <0x12a01000 0x1000>,
+			      <0x12a02000 0x2000>,
+			      <0x12a04000 0x2000>,
+			      <0x12a06000 0x2000>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) |
+						 IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		clock: clock-controller at 120e0000 {
+			compatible = "samsung,exynos850-clock";
+			reg = <0x120e0000 0x8000>;
+			#clock-cells = <1>;
+		};
+
+		pinctrl_alive: pinctrl at 11850000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x11850000 0x1000>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos7-wakeup-eint";
+			};
+		};
+
+		pinctrl_cmgp: pinctrl at 11c30000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x11c30000 0x1000>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos7-wakeup-eint";
+			};
+		};
+
+		pinctrl_aud: pinctrl at 14a60000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x14a60000 0x1000>;
+		};
+
+		pinctrl_hsi: pinctrl at 13430000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x13430000 0x1000>;
+			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_core: pinctrl at 12070000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x12070000 0x1000>;
+			interrupts = <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_peri: pinctrl at 139b0000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x139b0000 0x1000>;
+			interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		/* USI: UART */
+		serial_0: uart at 13820000 {
+			compatible = "samsung,exynos850-uart";
+			reg = <0x13820000 0x100>;
+			interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_bus>;
+			clocks = <&clock 2>;
+			clock-names = "uart";
+			status = "disabled";
+		};
+	};
+};
+
+#include "exynos850-pinctrl.dtsi"
-- 
2.30.2



From matthias.bgg at gmail.com  Fri Aug  6 08:30:35 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 6 Aug 2021 17:30:35 +0200
Subject: [PATCH v2 08/14] soc: mediatek: add mtk-mmsys config API for
 mt8195 vdosys1
In-Reply-To: <20210722094551.15255-9-nancy.lin@mediatek.com>
References: <20210722094551.15255-1-nancy.lin@mediatek.com>
 <20210722094551.15255-9-nancy.lin@mediatek.com>
Message-ID: <b71be855-b1a5-af6c-3000-59e6e42c0a79@gmail.com>



On 22/07/2021 11:45, Nancy.Lin wrote:
> Add mmsys config API.

This patch is doing a lot of things, it adds a "config" and it adds cmdq
support. Please explain better in the commit message what the config is for.
Please add comments to the different values of struct mtk_mmsys_config.

I understand that cmdq is optional, so please make addition to cmdq a separate
patch.
I'm a bit puzzled about that fact, can you please explain who you get the HW to
behave the same way when you write the same value and offset to mmsys-regs and
via cmdq.

Thanks,
Matthias

> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/soc/mediatek/mt8195-mmsys.h    | 38 ++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c       | 50 ++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.h       | 10 ++++++
>  include/linux/soc/mediatek/mtk-mmsys.h | 18 ++++++++++
>  4 files changed, 116 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
> index 104ba575f765..4bdb2087250c 100644
> --- a/drivers/soc/mediatek/mt8195-mmsys.h
> +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> @@ -154,6 +154,18 @@
>  #define DISP_DP_INTF0_SEL_IN_FROM_VDO0_MERGE_DL_ASYNC_MOUT	(1 << 0)
>  #define DISP_DP_INTF0_SEL_IN_FROM_VDO0_DSC_DL_ASYNC_MOUT	(2 << 0)
>  
> +#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD	0xe30
> +#define MT8195_VDO1_MERGE1_ASYNC_CFG_WD	0xe40
> +#define MT8195_VDO1_MERGE2_ASYNC_CFG_WD	0xe50
> +#define MT8195_VDO1_MERGE3_ASYNC_CFG_WD	0xe60
> +#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD	0xe70
> +#define MT8195_VDO1_HDR_TOP_CFG		0xd00
> +#define MT8195_VDO1_MIXER_IN1_ALPHA	0xd30
> +#define MT8195_VDO1_MIXER_IN2_ALPHA	0xd34
> +#define MT8195_VDO1_MIXER_IN3_ALPHA	0xd38
> +#define MT8195_VDO1_MIXER_IN4_ALPHA	0xd3c
> +#define MT8195_VDO1_MIXER_IN4_PAD	0xd4c
> +
>  static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
>  	{
>  		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> @@ -261,4 +273,30 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
>  	}
>  };
>  
> +static const struct mtk_mmsys_config mmsys_mt8195_config_table[] = {
> +	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> +	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> +	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> +	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> +	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> +	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> +	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> +	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> +	{ MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> +	{ MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(8, 0), 0},
> +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(24, 16), 16},
> +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(8, 0), 0},
> +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(24, 16), 16},
> +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(8, 0), 0},
> +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(24, 16), 16},
> +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(8, 0), 0},
> +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(24, 16), 16},
> +	{ MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(4, 4), 4},
> +	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 1, MT8195_VDO1_HDR_TOP_CFG, GENMASK(20, 20), 20},
> +	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 2, MT8195_VDO1_HDR_TOP_CFG, GENMASK(21, 21), 21},
> +	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 3, MT8195_VDO1_HDR_TOP_CFG, GENMASK(22, 22), 22},
> +	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 4, MT8195_VDO1_HDR_TOP_CFG, GENMASK(23, 23), 23},
> +};
> +
>  #endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
> index 9e31aad6c5c8..d0f4a407f8f8 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -63,10 +63,13 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
>  	.clk_driver = "clk-mt8195-vdo1",
>  	.routes = mmsys_mt8195_routing_table,
>  	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
> +	.config = mmsys_mt8195_config_table,
> +	.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
>  };
>  
>  struct mtk_mmsys {
>  	void __iomem *regs;
> +	struct cmdq_client_reg cmdq_base;
>  	const struct mtk_mmsys_driver_data *data;
>  };
>  
> @@ -104,6 +107,47 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
>  
> +void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
> +			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt)
> +{
> +	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
> +	const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
> +	u32 reg_val;
> +	u32 mask;
> +	u32 offset;
> +	int i;
> +
> +	if (!mmsys->data->num_configs)
> +		return;
> +
> +	for (i = 0; i < mmsys->data->num_configs; i++)
> +		if (config == mmsys_config[i].config && id == mmsys_config[i].id)
> +			break;
> +
> +	if (i == mmsys->data->num_configs)
> +		return;
> +
> +	offset = mmsys_config[i].addr;
> +	mask = mmsys_config[i].mask;
> +	reg_val = val << mmsys_config[i].shift;
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	if (cmdq_pkt && mmsys->cmdq_base.size) {
> +		cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
> +				    mmsys->cmdq_base.offset + offset, reg_val,
> +				    mask);
> +	} else {
> +#endif
> +		u32 tmp = readl(mmsys->regs + offset);
> +
> +		tmp = (tmp & ~mask) | reg_val;
> +		writel(tmp, mmsys->regs + offset);
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	}
> +#endif
> +}
> +EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
> +
>  static int mtk_mmsys_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -124,6 +168,12 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
>  	}
>  
>  	mmsys->data = of_device_get_match_data(&pdev->dev);
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
> +	if (ret)
> +		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
> +#endif
>  	platform_set_drvdata(pdev, mmsys);
>  
>  	clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver,
> diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
> index a760a34e6eca..084b1f5f3c88 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.h
> +++ b/drivers/soc/mediatek/mtk-mmsys.h
> @@ -73,10 +73,20 @@ struct mtk_mmsys_routes {
>  	u32 val;
>  };
>  
> +struct mtk_mmsys_config {
> +	enum mtk_mmsys_config_type config;
> +	u32 id;
> +	u32 addr;
> +	u32 mask;
> +	u32 shift;
> +};
> +
>  struct mtk_mmsys_driver_data {
>  	const char *clk_driver;
>  	const struct mtk_mmsys_routes *routes;
>  	const unsigned int num_routes;
> +	const struct mtk_mmsys_config *config;
> +	const unsigned int num_configs;
>  };
>  
>  /*
> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
> index 338c71570aeb..ba3925661cc9 100644
> --- a/include/linux/soc/mediatek/mtk-mmsys.h
> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> @@ -6,6 +6,10 @@
>  #ifndef __MTK_MMSYS_H
>  #define __MTK_MMSYS_H
>  
> +#include <linux/mailbox_controller.h>
> +#include <linux/mailbox/mtk-cmdq-mailbox.h>
> +#include <linux/soc/mediatek/mtk-cmdq.h>
> +
>  enum mtk_ddp_comp_id;
>  struct device;
>  
> @@ -54,6 +58,17 @@ enum mtk_ddp_comp_id {
>  	DDP_COMPONENT_ID_MAX,
>  };
>  
> +enum mtk_mmsys_config_type {
> +	MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
> +	MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
> +	MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH,
> +	MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT,
> +	MMSYS_CONFIG_HDR_ALPHA_SEL,
> +	MMSYS_CONFIG_MIXER_IN_ALPHA_ODD,
> +	MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN,
> +	MMSYS_CONFIG_MIXER_IN_CH_SWAP,
> +};
> +
>  void mtk_mmsys_ddp_connect(struct device *dev,
>  			   enum mtk_ddp_comp_id cur,
>  			   enum mtk_ddp_comp_id next);
> @@ -62,4 +77,7 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
>  			      enum mtk_ddp_comp_id cur,
>  			      enum mtk_ddp_comp_id next);
>  
> +void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
> +			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt);
> +
>  #endif /* __MTK_MMSYS_H */
> 


From matthias.bgg at gmail.com  Fri Aug  6 08:43:56 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 6 Aug 2021 17:43:56 +0200
Subject: [PATCH v2 1/7] arm64: dts: mediatek: Move reset controller
 constants into common location
In-Reply-To: <20210714121116.v2.1.I514d9aafff3a062f751b37d3fea7402f67595b86@changeid>
References: <20210714101141.2089082-1-enric.balletbo@collabora.com>
 <20210714121116.v2.1.I514d9aafff3a062f751b37d3fea7402f67595b86@changeid>
Message-ID: <1127dad2-4ee9-4e22-fb15-8412ac59a394@gmail.com>



On 14/07/2021 12:11, Enric Balletbo i Serra wrote:
> The DT binding includes for reset controllers are located in
> include/dt-bindings/reset/. Move the Mediatek reset constants in there.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

> ---
> 
> Changes in v2:
> - Fix build test ERROR Reported-by: kernel test robot <lkp at intel.com>
> 
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi                    | 2 +-
>  drivers/watchdog/mtk_wdt.c                                  | 6 +++---
>  .../dt-bindings/{reset-controller => reset}/mt2712-resets.h | 0
>  .../dt-bindings/{reset-controller => reset}/mt8183-resets.h | 0
>  .../dt-bindings/{reset-controller => reset}/mt8192-resets.h | 0
>  5 files changed, 4 insertions(+), 4 deletions(-)
>  rename include/dt-bindings/{reset-controller => reset}/mt2712-resets.h (100%)
>  rename include/dt-bindings/{reset-controller => reset}/mt8183-resets.h (100%)
>  rename include/dt-bindings/{reset-controller => reset}/mt8192-resets.h (100%)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> index 96473d88f391..4ef0b5b23047 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> @@ -11,7 +11,7 @@
>  #include <dt-bindings/interrupt-controller/irq.h>
>  #include <dt-bindings/memory/mt8183-larb-port.h>
>  #include <dt-bindings/power/mt8183-power.h>
> -#include <dt-bindings/reset-controller/mt8183-resets.h>
> +#include <dt-bindings/reset/mt8183-resets.h>
>  #include <dt-bindings/phy/phy.h>
>  #include <dt-bindings/thermal/thermal.h>
>  #include "mt8183-pinfunc.h"
> diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
> index 16b6aff324a7..6986bc740465 100644
> --- a/drivers/watchdog/mtk_wdt.c
> +++ b/drivers/watchdog/mtk_wdt.c
> @@ -9,9 +9,9 @@
>   * Based on sunxi_wdt.c
>   */
>  
> -#include <dt-bindings/reset-controller/mt2712-resets.h>
> -#include <dt-bindings/reset-controller/mt8183-resets.h>
> -#include <dt-bindings/reset-controller/mt8192-resets.h>
> +#include <dt-bindings/reset/mt2712-resets.h>
> +#include <dt-bindings/reset/mt8183-resets.h>
> +#include <dt-bindings/reset/mt8192-resets.h>
>  #include <linux/delay.h>
>  #include <linux/err.h>
>  #include <linux/init.h>
> diff --git a/include/dt-bindings/reset-controller/mt2712-resets.h b/include/dt-bindings/reset/mt2712-resets.h
> similarity index 100%
> rename from include/dt-bindings/reset-controller/mt2712-resets.h
> rename to include/dt-bindings/reset/mt2712-resets.h
> diff --git a/include/dt-bindings/reset-controller/mt8183-resets.h b/include/dt-bindings/reset/mt8183-resets.h
> similarity index 100%
> rename from include/dt-bindings/reset-controller/mt8183-resets.h
> rename to include/dt-bindings/reset/mt8183-resets.h
> diff --git a/include/dt-bindings/reset-controller/mt8192-resets.h b/include/dt-bindings/reset/mt8192-resets.h
> similarity index 100%
> rename from include/dt-bindings/reset-controller/mt8192-resets.h
> rename to include/dt-bindings/reset/mt8192-resets.h
> 


From catalin.marinas at arm.com  Fri Aug  6 09:04:16 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri,  6 Aug 2021 17:04:16 +0100
Subject: [PATCH] arm64: entry: Add SYM_CODE annotation for __bad_stack
In-Reply-To: <20210804181710.19059-1-broonie@kernel.org>
References: <20210804181710.19059-1-broonie@kernel.org>
Message-ID: <162826584979.7468.10159380996347088124.b4-ty@arm.com>

On Wed, 4 Aug 2021 19:17:10 +0100, Mark Brown wrote:
> When converting arm64 to modern assembler annotations __bad_stack was left
> as a raw local label without annotations. While this will have little if
> any practical impact at present it may cause issues in the future if we
> start using the annotations for things like reliable stack trace. Add
> SYM_CODE annotations to fix this.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: entry: Add SYM_CODE annotation for __bad_stack
      https://git.kernel.org/arm64/c/ede3241a5f23

-- 
Catalin



From catalin.marinas at arm.com  Fri Aug  6 09:04:27 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri,  6 Aug 2021 17:04:27 +0100
Subject: (subset) [PATCH 0/4] Fix racing TLBI with ASID/VMID reallocation
In-Reply-To: <20210806113109.2475-1-will@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
Message-ID: <162826584979.7468.15328966135917852100.b4-ty@arm.com>

On Fri, 6 Aug 2021 12:31:03 +0100, Will Deacon wrote:
> While reviewing Shameer's reworked VMID allocator [1] and discussing
> with Marc, we spotted a race between TLB invalidation (which typically
> takes an ASID or VMID argument) and reallocation of ASID/VMID for the
> context being targetted.
> 
> The first patch spells out an example with try_to_unmap_one() in a
> comment, which Catalin has kindly modelled in TLA+ at [2].
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/4] arm64: mm: Fix TLBI vs ASID rollover
      https://git.kernel.org/arm64/c/5e10f9887ed8

-- 
Catalin



From linuc.decode at gmail.com  Fri Aug  6 09:09:43 2021
From: linuc.decode at gmail.com (Linu Cherian)
Date: Fri, 6 Aug 2021 21:39:43 +0530
Subject: [PATCH 08/10] coresight: trbe: Workaround TRBE errat overwrite in
 FILL mode
In-Reply-To: <20210728135217.591173-9-suzuki.poulose@arm.com>
References: <20210728135217.591173-1-suzuki.poulose@arm.com>
 <20210728135217.591173-9-suzuki.poulose@arm.com>
Message-ID: <CAAHhmWjR6XYo5j_h3jfLsmWzqD9i9L-pHq=zrrdrw9YTXmuCqg@mail.gmail.com>

Hi Suzuki,

On Wed, Jul 28, 2021 at 7:23 PM Suzuki K Poulose <suzuki.poulose at arm.com> wrote:
>
> ARM Neoverse-N2 (#2139208) and Cortex-A710(##2119858) suffers from
> an erratum, which when triggered, might cause the TRBE to overwrite
> the trace data already collected in FILL mode, in the event of a WRAP.
> i.e, the TRBE doesn't stop writing the data, instead wraps to the base
> and could write upto 3 cache line size worth trace. Thus, this could
> corrupt the trace at the "BASE" pointer.
>
> The workaround is to program the write pointer 256bytes from the
> base, such that if the erratum is triggered, it doesn't overwrite
> the trace data that was captured. This skipped region could be
> padded with ignore packets at the end of the session, so that
> the decoder sees a continuous buffer with some padding at the
> beginning.

Just trying to understand,
Is there a possibility that lost data results in partial trace packets
towards the end of the buffer ? Or its always guaranteed that
trace packet end is always aligned with buffer end/limit ?
Thinking of a case when formatting is disabled.

The trace data written at the base is considered
> lost as the limit could have been in the middle of the perf
> ring buffer, and jumping to the "base" is not acceptable.
> We set the flags already to indicate that some amount of trace
> was lost during the FILL event IRQ. So this is fine.
>
> One important change with the work around is, we program the
> TRBBASER_EL1 to current page where we are allowed to write.
> Otherwise, it could overwrite a region that may be consumed
> by the perf. Towards this, we always make sure that the
> "handle->head" and thus the trbe_write is PAGE_SIZE aligned,
> so that we can set the BASE to the PAGE base and move the
> TRBPTR to the 256bytes offset.
>
> Cc: Mike Leach <mike.leach at linaro.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-trbe.c | 111 +++++++++++++++++--
>  1 file changed, 102 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 9ea28813182b..cd997ed5d918 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -17,6 +17,7 @@
>
>  #include <asm/barrier.h>
>  #include <asm/cputype.h>
> +#include <asm/cpufeature.h>
>
>  #include "coresight-self-hosted-trace.h"
>  #include "coresight-trbe.h"
> @@ -84,9 +85,17 @@ struct trbe_buf {
>   * per TRBE instance, we keep track of the list of errata that
>   * affects the given instance of the TRBE.
>   */
> -#define TRBE_ERRATA_MAX                        0
> +#define TRBE_WORKAROUND_OVERWRITE_FILL_MODE    0
> +#define TRBE_ERRATA_MAX                                1
> +
> +/*
> + * Safe limit for the number of bytes that may be overwritten
> + * when the erratum is triggered.
> + */
> +#define TRBE_WORKAROUND_OVERWRITE_FILL_MODE_SKIP       256
>
>  static unsigned long trbe_errata_cpucaps[TRBE_ERRATA_MAX] = {
> +       [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>  };
>
>  /*
> @@ -531,10 +540,13 @@ static enum trbe_fault_action trbe_get_fault_act(u64 trbsr)
>         if ((ec == TRBE_EC_STAGE1_ABORT) || (ec == TRBE_EC_STAGE2_ABORT))
>                 return TRBE_FAULT_ACT_FATAL;
>
> -       if (is_trbe_wrap(trbsr) && (ec == TRBE_EC_OTHERS) && (bsc == TRBE_BSC_FILLED)) {
> -               if (get_trbe_write_pointer() == get_trbe_base_pointer())
> -                       return TRBE_FAULT_ACT_WRAP;
> -       }
> +       /*
> +        * It is not necessary to verify the TRBPTR == TRBBASER to detect
> +        * a FILL event. Moreover, CPU errata could make this check invalid.
> +        */
> +       if (is_trbe_wrap(trbsr) && (ec == TRBE_EC_OTHERS) && (bsc == TRBE_BSC_FILLED))
> +               return TRBE_FAULT_ACT_WRAP;
> +
>         return TRBE_FAULT_ACT_SPURIOUS;
>  }
>
> @@ -544,6 +556,7 @@ static unsigned long trbe_get_trace_size(struct perf_output_handle *handle,
>  {
>         u64 write;
>         u64 start_off, end_off;
> +       u64 size;
>
>         /*
>          * If the TRBE has wrapped around the write pointer has
> @@ -559,7 +572,18 @@ static unsigned long trbe_get_trace_size(struct perf_output_handle *handle,
>
>         if (WARN_ON_ONCE(end_off < start_off))
>                 return 0;
> -       return (end_off - start_off);
> +
> +       size = end_off - start_off;
> +       /*
> +        * If the TRBE is affected by the following erratum, we must fill
> +        * the space we skipped with IGNORE packets. And we are always
> +        * guaranteed to have at least a PAGE_SIZE space in the buffer.
> +        */
> +       if (trbe_has_erratum(TRBE_WORKAROUND_OVERWRITE_FILL_MODE, buf->cpudata) &&
> +           !WARN_ON(size < TRBE_WORKAROUND_OVERWRITE_FILL_MODE_SKIP))
> +               __trbe_pad_buf(buf, start_off, TRBE_WORKAROUND_OVERWRITE_FILL_MODE_SKIP);
> +
> +       return size;
>  }
>
>  static void *arm_trbe_alloc_buffer(struct coresight_device *csdev,
> @@ -704,20 +728,73 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
>         return size;
>  }
>
> +
> +static int trbe_apply_work_around_before_enable(struct trbe_buf *buf)
> +{
> +       /*
> +        * TRBE_WORKAROUND_OVERWRITE_FILL_MODE causes the TRBE to overwrite a few cache
> +        * line size from the "TRBBASER_EL1" in the event of a "FILL".
> +        * Thus, we could loose some amount of the trace at the base.
> +        *
> +        * To work around this:
> +        * - Software must leave 256bytes of space from the base, so that
> +        *   the trace collected now is not overwritten.
> +        * - Fill the first 256bytes with IGNORE packets for the decoder
> +        *   to ignore at the end of the session, so that the decoder ignores
> +        *   this gap.
> +        *
> +        * This also means that, the TRBE driver must set the TRBBASER_EL1
> +        * such that, when the erratum is triggered, it doesn't overwrite
> +        * the "area" outside the area marked by (handle->head, +size).
> +        * So, we make sure that the handle->head is always PAGE aligned,
> +        * by tweaking the required alignment for the TRBE (trbe_align).
> +        * And when we enable the TRBE,
> +        *
> +        *   - move the TRBPTR_EL1 to 256bytes past the starting point.
> +        *     So that any trace collected in this run is not overwritten.
> +        *
> +        *   - set the TRBBASER_EL1 to the original trbe_write. This will
> +        *     ensure that, if the TRBE hits the erratum, it would only
> +        *     write within the region allowed for the TRBE.
> +        *
> +        * At the trace collection time, we always pad the skipped bytes
> +        * with IGNORE packets to make sure the decoder doesn't see any
> +        * overwritten packets.
> +        */
> +       if (trbe_has_erratum(TRBE_WORKAROUND_OVERWRITE_FILL_MODE, buf->cpudata)) {
> +               if (WARN_ON(!IS_ALIGNED(buf->trbe_write, PAGE_SIZE)))
> +                       return -EINVAL;
> +               buf->trbe_hw_base = buf->trbe_write;
> +               buf->trbe_write += TRBE_WORKAROUND_OVERWRITE_FILL_MODE_SKIP;
> +       }
> +
> +       return 0;
> +}
> +
>  static int __arm_trbe_enable(struct trbe_buf *buf,
>                              struct perf_output_handle *handle)
>  {
> +       int ret = 0;
> +
>         buf->trbe_limit = compute_trbe_buffer_limit(handle);
>         buf->trbe_write = buf->trbe_base + PERF_IDX2OFF(handle->head, buf);
>         if (buf->trbe_limit == buf->trbe_base) {
> -               trbe_stop_and_truncate_event(handle);
> -               return -ENOSPC;
> +               ret = -ENOSPC;
> +               goto err;
>         }
>         /* Set the base of the TRBE to the buffer base */
>         buf->trbe_hw_base = buf->trbe_base;
> +
> +       ret = trbe_apply_work_around_before_enable(buf);
> +       if (ret)
> +               goto err;
> +
>         *this_cpu_ptr(buf->cpudata->drvdata->handle) = handle;
>         trbe_enable_hw(buf);
>         return 0;
> +err:
> +       trbe_stop_and_truncate_event(handle);
> +       return ret;
>  }
>
>  static int arm_trbe_enable(struct coresight_device *csdev, u32 mode, void *data)
> @@ -1003,7 +1080,23 @@ static void arm_trbe_probe_cpu(void *info)
>                 pr_err("Unsupported alignment on cpu %d\n", cpu);
>                 goto cpu_clear;
>         }
> -       cpudata->trbe_align = cpudata->trbe_hw_align;
> +
> +       /*
> +        * If the TRBE is affected by erratum TRBE_WORKAROUND_OVERWRITE_FILL_MODE,
> +        * we must always program the TBRPTR_EL1, 256bytes from a page
> +        * boundary, with TRBBASER_EL1 set to the page, to prevent
> +        * TRBE over-writing 256bytes at TRBBASER_EL1 on FILL event.
> +        *
> +        * Thus make sure we always align our write pointer to a PAGE_SIZE,
> +        * which also guarantees that we have at least a PAGE_SIZE space in
> +        * the buffer (TRBLIMITR is PAGE aligned) and thus we can skip
> +        * the required bytes at the base.
> +        */
> +       if (trbe_has_erratum(TRBE_WORKAROUND_OVERWRITE_FILL_MODE, cpudata))
> +               cpudata->trbe_align = PAGE_SIZE;
> +       else
> +               cpudata->trbe_align = cpudata->trbe_hw_align;
> +
>         cpudata->trbe_flag = get_trbe_flag_update(trbidr);
>         cpudata->cpu = cpu;
>         cpudata->drvdata = drvdata;
> --
> 2.24.1
>
> _______________________________________________
> CoreSight mailing list
> CoreSight at lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/coresight


From chunkuang.hu at kernel.org  Fri Aug  6 09:44:45 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sat, 7 Aug 2021 00:44:45 +0800
Subject: [PATCH v6 5/7] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20210805205226.24880-6-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-6-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY__f9TmyUaZe8O5aAfebftJc2B7BWchhZ8DWk+SWKTDF-w@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?6? ?? ??4:52???
>
> DSC is designed for real-time systems with real-time compression,
> transmission, decompression and display.
> The DSC standard is a specification of the algorithms used for
> compressing and decompressing image display streams, including
> the specification of the syntax and semantics of the compressed
> video bit stream.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> This patch is base on [1]
>
> [1] dt-bindings: mediatek: add mediatek, dsc.yaml for mt8195 SoC binding
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-4-jason-jh.lin at mediatek.com/
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 62 +++++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
>  2 files changed, 63 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 328ee19f931e..24c7b004fe4d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -43,6 +43,12 @@
>  #define DITHER_LSB_ERR_SHIFT_G(x)              (((x) & 0x7) << 12)
>  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
>
> +#define DISP_REG_DSC_CON                       0x0000
> +#define DSC_EN                                 BIT(0)
> +#define DSC_DUAL_INOUT                         BIT(2)
> +#define DSC_BYPASS                             BIT(4)
> +#define DSC_UFOE_SEL                           BIT(16)
> +
>  #define DISP_REG_OD_EN                         0x0000
>  #define DISP_REG_OD_CFG                                0x0020
>  #define OD_RELAYMODE                           BIT(0)
> @@ -209,6 +215,35 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc,
>                               DISP_DITHERING, cmdq_pkt);
>  }
>
> +static void mtk_dsc_config(struct device *dev, unsigned int w,
> +                          unsigned int h, unsigned int vrefresh,
> +                          unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       /* dsc bypass mode */
> +       mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs,
> +                          DISP_REG_DSC_CON, DSC_BYPASS);
> +       mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs,
> +                          DISP_REG_DSC_CON, DSC_UFOE_SEL);
> +       mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs,
> +                          DISP_REG_DSC_CON, DSC_DUAL_INOUT);
> +}
> +
> +static void mtk_dsc_start(struct device *dev)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       writel_relaxed(DSC_EN, &priv->regs + DISP_REG_DSC_CON);
> +}
> +
> +static void mtk_dsc_stop(struct device *dev)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
> +}
> +
>  static void mtk_od_config(struct device *dev, unsigned int w,
>                           unsigned int h, unsigned int vrefresh,
>                           unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> @@ -272,6 +307,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = {
>         .stop = mtk_dpi_stop,
>  };
>
> +static const struct mtk_ddp_comp_funcs ddp_dsc = {
> +       .clk_enable = mtk_ddp_clk_enable,
> +       .clk_disable = mtk_ddp_clk_disable,
> +       .config = mtk_dsc_config,
> +       .start = mtk_dsc_start,
> +       .stop = mtk_dsc_stop,
> +};
> +
>  static const struct mtk_ddp_comp_funcs ddp_dsi = {
>         .start = mtk_dsi_ddp_start,
>         .stop = mtk_dsi_ddp_stop,
> @@ -286,6 +329,14 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
>         .stop = mtk_gamma_stop,
>  };
>
> +static const struct mtk_ddp_comp_funcs ddp_merge = {
> +       .clk_enable = mtk_merge_clk_enable,
> +       .clk_disable = mtk_merge_clk_disable,
> +       .start = mtk_merge_start,
> +       .stop = mtk_merge_stop,
> +       .config = mtk_merge_config,
> +};

Move the merge modification to the patch of merge.

> +
>  static const struct mtk_ddp_comp_funcs ddp_od = {
>         .clk_enable = mtk_ddp_clk_enable,
>         .clk_disable = mtk_ddp_clk_disable,
> @@ -333,7 +384,9 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>         [MTK_DISP_CCORR] = "ccorr",
>         [MTK_DISP_COLOR] = "color",
>         [MTK_DISP_DITHER] = "dither",
> +       [MTK_DISP_DSC] = "dsc",
>         [MTK_DISP_GAMMA] = "gamma",
> +       [MTK_DISP_MERGE] = "merge",

Ditto.

>         [MTK_DISP_MUTEX] = "mutex",
>         [MTK_DISP_OD] = "od",
>         [MTK_DISP_OVL] = "ovl",
> @@ -362,11 +415,19 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>         [DDP_COMPONENT_DITHER]  = { MTK_DISP_DITHER,    0, &ddp_dither },
>         [DDP_COMPONENT_DPI0]    = { MTK_DPI,            0, &ddp_dpi },
>         [DDP_COMPONENT_DPI1]    = { MTK_DPI,            1, &ddp_dpi },
> +       [DDP_COMPONENT_DSC0]    = { MTK_DISP_DSC,       0, &ddp_dsc },
> +       [DDP_COMPONENT_DSC1]    = { MTK_DISP_DSC,       1, &ddp_dsc },
>         [DDP_COMPONENT_DSI0]    = { MTK_DSI,            0, &ddp_dsi },
>         [DDP_COMPONENT_DSI1]    = { MTK_DSI,            1, &ddp_dsi },
>         [DDP_COMPONENT_DSI2]    = { MTK_DSI,            2, &ddp_dsi },
>         [DDP_COMPONENT_DSI3]    = { MTK_DSI,            3, &ddp_dsi },
>         [DDP_COMPONENT_GAMMA]   = { MTK_DISP_GAMMA,     0, &ddp_gamma },
> +       [DDP_COMPONENT_MERGE0]  = { MTK_DISP_MERGE,     0, &ddp_merge },
> +       [DDP_COMPONENT_MERGE1]  = { MTK_DISP_MERGE,     1, &ddp_merge },
> +       [DDP_COMPONENT_MERGE2]  = { MTK_DISP_MERGE,     2, &ddp_merge },
> +       [DDP_COMPONENT_MERGE3]  = { MTK_DISP_MERGE,     3, &ddp_merge },
> +       [DDP_COMPONENT_MERGE4]  = { MTK_DISP_MERGE,     4, &ddp_merge },
> +       [DDP_COMPONENT_MERGE5]  = { MTK_DISP_MERGE,     5, &ddp_merge },

Ditto.

>         [DDP_COMPONENT_OD0]     = { MTK_DISP_OD,        0, &ddp_od },
>         [DDP_COMPONENT_OD1]     = { MTK_DISP_OD,        1, &ddp_od },
>         [DDP_COMPONENT_OVL0]    = { MTK_DISP_OVL,       0, &ddp_ovl },
> @@ -497,6 +558,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>             type == MTK_DISP_CCORR ||
>             type == MTK_DISP_COLOR ||
>             type == MTK_DISP_GAMMA ||
> +           type == MTK_DISP_MERGE ||

Ditto.

Regards,
Chun-Kuang.

>             type == MTK_DISP_OVL ||
>             type == MTK_DISP_OVL_2L ||
>             type == MTK_DISP_PWM ||
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index d317b944df66..560be6bc9d0e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
>         MTK_DISP_CCORR,
>         MTK_DISP_COLOR,
>         MTK_DISP_DITHER,
> +       MTK_DISP_DSC,
>         MTK_DISP_GAMMA,
>         MTK_DISP_MUTEX,
>         MTK_DISP_OD,
> --
> 2.18.0
>


From chunkuang.hu at kernel.org  Fri Aug  6 09:57:39 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sat, 7 Aug 2021 00:57:39 +0800
Subject: [PATCH v6 7/7] drm/mediatek: add mediatek-drm of vdosys0 support
 for mt8195
In-Reply-To: <20210805205226.24880-8-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-8-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY__RgqdMfE5w4VK7cdZkZNEY0=sqFsuAUeQTPQfte2fYXQ@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?6? ?? ??4:52???
>
> Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.
>

Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> This patch is base on [1]
>
> [1] dt-bindings: mediatek: display: add mt8195 SoC binding
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-5-jason-jh.lin at mediatek.com/
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  6 +++++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 28 ++++++++++++++++++++++++
>  2 files changed, 34 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 728aaadfea8c..00e9827acefe 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -355,6 +355,10 @@ static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
>         .fifo_size = 5 * SZ_1K,
>  };
>
> +static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
> +       .fifo_size = 1920,
> +};
> +
>  static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
>         { .compatible = "mediatek,mt2701-disp-rdma",
>           .data = &mt2701_rdma_driver_data},
> @@ -362,6 +366,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
>           .data = &mt8173_rdma_driver_data},
>         { .compatible = "mediatek,mt8183-disp-rdma",
>           .data = &mt8183_rdma_driver_data},
> +       { .compatible = "mediatek,mt8195-disp-rdma",
> +         .data = &mt8195_rdma_driver_data},
>         {},
>  };
>  MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 5eb9c0a04447..9aebf73144c6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -147,6 +147,19 @@ static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
>         DDP_COMPONENT_DPI0,
>  };
>
> +static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
> +       DDP_COMPONENT_OVL0,
> +       DDP_COMPONENT_RDMA0,
> +       DDP_COMPONENT_COLOR0,
> +       DDP_COMPONENT_CCORR,
> +       DDP_COMPONENT_AAL0,
> +       DDP_COMPONENT_GAMMA,
> +       DDP_COMPONENT_DITHER,
> +       DDP_COMPONENT_DSC0,
> +       DDP_COMPONENT_MERGE0,
> +       DDP_COMPONENT_DP_INTF0,
> +};
> +
>  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
>         .main_path = mt2701_mtk_ddp_main,
>         .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
> @@ -186,6 +199,11 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
>         .ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
>  };
>
> +static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
> +       .main_path = mt8195_mtk_ddp_main,
> +       .main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
> +};
> +
>  static int mtk_drm_kms_init(struct drm_device *drm)
>  {
>         struct mtk_drm_private *private = drm->dev_private;
> @@ -406,10 +424,14 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DISP_COLOR },
>         { .compatible = "mediatek,mt8183-disp-dither",
>           .data = (void *)MTK_DISP_DITHER },
> +       { .compatible = "mediatek,mt8195-disp-dsc",
> +         .data = (void *)MTK_DISP_DSC },
>         { .compatible = "mediatek,mt8173-disp-gamma",
>           .data = (void *)MTK_DISP_GAMMA, },
>         { .compatible = "mediatek,mt8183-disp-gamma",
>           .data = (void *)MTK_DISP_GAMMA, },
> +       { .compatible = "mediatek,mt8195-disp-merge",
> +         .data = (void *)MTK_DISP_MERGE },
>         { .compatible = "mediatek,mt2701-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt2712-disp-mutex",
> @@ -418,6 +440,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt8183-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
> +       { .compatible = "mediatek,mt8195-disp-mutex",
> +         .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt8173-disp-od",
>           .data = (void *)MTK_DISP_OD },
>         { .compatible = "mediatek,mt2701-disp-ovl",
> @@ -438,6 +462,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DISP_RDMA },
>         { .compatible = "mediatek,mt8183-disp-rdma",
>           .data = (void *)MTK_DISP_RDMA },
> +       { .compatible = "mediatek,mt8195-disp-rdma",
> +         .data = (void *)MTK_DISP_RDMA },
>         { .compatible = "mediatek,mt8173-disp-ufoe",
>           .data = (void *)MTK_DISP_UFOE },
>         { .compatible = "mediatek,mt8173-disp-wdma",
> @@ -468,6 +494,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
>           .data = &mt8173_mmsys_driver_data},
>         { .compatible = "mediatek,mt8183-mmsys",
>           .data = &mt8183_mmsys_driver_data},
> +       {.compatible = "mediatek,mt8195-vdosys0",
> +         .data = &mt8195_vdosys0_driver_data},
>         { }
>  };
>  MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
> --
> 2.18.0
>


From semen.protsenko at linaro.org  Fri Aug  6 09:57:43 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 6 Aug 2021 19:57:43 +0300
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <bb08f7a4-1da9-fb20-f091-6a3c37a1f898@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <455cfb5e-dff7-a5c0-3875-49abe3e900f3@canonical.com>
 <CAPLW+4nDS0atrbUFagDA0W_Ky5MvOiY+N+NQoQ+me4pndp_iWg@mail.gmail.com>
 <68734f6c-fc76-595c-8d34-8924dbbbb845@canonical.com>
 <CAPLW+4n_JKj5xeBHXONcv__vyAFvx3fhXoxJa17NTHK1RSJFJw@mail.gmail.com>
 <b753796c-2ce6-4166-7c20-289e950237ad@canonical.com>
 <bb08f7a4-1da9-fb20-f091-6a3c37a1f898@canonical.com>
Message-ID: <CAPLW+4=7n3a2FL9YHYj8dPn+2obFLHvW6DpsDjnG-bxX9--HbQ@mail.gmail.com>

On Fri, 6 Aug 2021 at 15:48, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 06/08/2021 14:32, Krzysztof Kozlowski wrote:
> > On 06/08/2021 14:07, Sam Protsenko wrote:
> >> On Fri, 6 Aug 2021 at 10:49, Krzysztof Kozlowski
> >> <krzysztof.kozlowski at canonical.com> wrote:
> >>>
> >>> On 06/08/2021 01:06, Sam Protsenko wrote:
> >>>> On Sat, 31 Jul 2021 at 12:03, Krzysztof Kozlowski
> >>>> <krzysztof.kozlowski at canonical.com> wrote:
> >>>>
> >>>>>>
> >>>>>> This patch adds minimal SoC support. Particular board device tree files
> >>>>>> can include exynos850.dtsi file to get SoC related nodes, and then
> >>>>>> reference those nodes further as needed.
> >>>>>>
> >>>>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> >>>>>> ---
> >>>>>>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
> >>>>>>  arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
> >>>>>>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
> >>>>>
> >>>>> Not buildable. Missing Makefile, missing DTS. Please submit with initial
> >>>>> DTS, otherwise no one is able to verify it even compiles.
> >>>>>
> >>>>
> >>>> This device is not available for purchase yet. I'll send the patch for
> >>>> board dts once it's announced. I can do all the testing for now, if
> >>>> you have any specific requests. Would it be possible for us to review
> >>>> and apply only SoC support for now? Will send v2 soon...
> >>>
> >>> What you propose is equal to adding a driver (C source code) without
> >>> ability to compile it. What's the point of having it in the kernel? It's
> >>> unverifiable, unbuildable and unusable.
> >>>
> >>
> >> Yes, I understand. That's adding code with no users, and it's not a
> >> good practice.
> >>
> >>> We can review the DTSI however merging has to be with a DTS. Usually the
> >>> SoC vendor adds first an evalkit (e.g. SMDK board). Maybe you have one
> >>> for Exynos850? Otherwise if you cannot disclose the actual board, the
> >>> DTSI will have to wait. You can submit drivers, though.
> >>>
> >>
> >> Sure, let's go this way. I'll send v2 soon. Improving patches and
> >> having Reviewed-by tag for those would good enough for me at this
> >> point. I'll continue to prepare another Exynos850 related patches
> >> until the actual board is announced, like proper clock driver, reset,
> >> MMC, etc. Is it ok if I send those for a review too (so I can fix all
> >> issues ahead)?
> >
> > Sure, prepare all necessary drivers earlier. I suspect clocks will be a
> > real pain because of significant changes modeled in vendor kernel. I
> > remember Pawe? Chmiel (+Cc) was doing something for these:
> > https://github.com/PabloPL/linux/tree/exynos7420
> >
> > I mentioned before - you should also modify the chipid driver. Check
> > also other drivers in drivers/soc/samsung, although some are needed only
> > for suspend&resume.
> >

Yes, in due course... There won't be much problems with chip-id
driver. But pretty much all platform drivers depend on clk, and that
one I'm afraid I'll have to implement from scratch. Will take me a
while, as vendor's codebase for clk driver is huge and depend on
another huge non-upstreamable abstraction layer framework they have,
and also they have kind of strange home brewed composite clocks...
Anyway, that's what I'm going to look into next.

Btw, I just sent v2 :)

>
> You can also take a look at Exynos8895 efforts:
> https://github.com/ivoszbg/linux/commits/for-upstream/exynos8895
>
> Since knowledge, datasheets and efforts are quite spread all over, I
> keep track of some work here:
> https://exynos.wiki.kernel.org/community
>

Thanks, Krzysztof! I'm sure that info will help a lot with further
work, like clock driver.

>
> Best regards,
> Krzysztof


From chunkuang.hu at kernel.org  Fri Aug  6 10:10:53 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sat, 7 Aug 2021 01:10:53 +0800
Subject: [PATCH v6 6/7] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20210805205226.24880-7-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-7-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_9PRNyoegE2QewoKHCR3mfP9Szh3JMW4bL1WcRcC4Yk3A@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?6? ?? ??4:52???
>
> Add MERGE engine file:
> MERGE module is used to merge two slice-per-line inputs
> into one side-by-side output.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> This patch is base on [1]
>
> [1] dt-bindings: mediatek: display: add mt8195 SoC binding
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-5-jason-jh.lin at mediatek.com/
> ---
>  drivers/gpu/drm/mediatek/Makefile           |   1 +
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 263 ++++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   4 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
>  6 files changed, 277 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
>
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index dc54a7a69005..538e0087a44c 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -3,6 +3,7 @@
>  mediatek-drm-y := mtk_disp_ccorr.o \
>                   mtk_disp_color.o \
>                   mtk_disp_gamma.o \
> +                 mtk_disp_merge.o \
>                   mtk_disp_ovl.o \
>                   mtk_disp_rdma.o \
>                   mtk_drm_crtc.o \
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index cafd9df2d63b..f407cd9d873e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -46,6 +46,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
>  void mtk_gamma_start(struct device *dev);
>  void mtk_gamma_stop(struct device *dev);
>
> +int mtk_merge_clk_enable(struct device *dev);
> +void mtk_merge_clk_disable(struct device *dev);
> +void mtk_merge_config(struct device *dev, unsigned int width,
> +                     unsigned int height, unsigned int vrefresh,
> +                     unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> +void mtk_merge_start(struct device *dev);
> +void mtk_merge_stop(struct device *dev);
> +
>  void mtk_ovl_bgclr_in_on(struct device *dev);
>  void mtk_ovl_bgclr_in_off(struct device *dev);
>  void mtk_ovl_bypass_shadow(struct device *dev);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> new file mode 100644
> index 000000000000..f3d262792054
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> @@ -0,0 +1,263 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/soc/mediatek/mtk-cmdq.h>
> +
> +#include "mtk_drm_ddp_comp.h"
> +#include "mtk_drm_drv.h"
> +#include "mtk_disp_drv.h"
> +
> +#define DISP_REG_MERGE_CTRL            0x000
> +#define MERGE_EN                       1

One more indent for the bitwise value.

> +#define DISP_REG_MERGE_CFG_0           0x010
> +#define DISP_REG_MERGE_CFG_4           0x020
> +#define DISP_REG_MERGE_CFG_10          0x038
> +/* no swap */
> +#define SWAP_MODE                      0
> +#define FLD_SWAP_MODE                  GENMASK(4, 0)
> +#define DISP_REG_MERGE_CFG_12          0x040
> +#define CFG_10_10_1PI_2PO_BUF_MODE     6
> +#define CFG_10_10_2PI_2PO_BUF_MODE     8
> +#define FLD_CFG_MERGE_MODE             GENMASK(4, 0)
> +#define DISP_REG_MERGE_CFG_24          0x070
> +#define DISP_REG_MERGE_CFG_25          0x074
> +#define DISP_REG_MERGE_CFG_36          0x0a0
> +#define ULTRA_EN                       1
> +#define PREULTRA_EN                    1
> +#define HALT_FOR_DVFS_EN               0
> +#define FLD_ULTRA_EN                   GENMASK(0, 0)
> +#define FLD_PREULTRA_EN                        GENMASK(4, 4)
> +#define FLD_HALT_FOR_DVFS_EN           GENMASK(8, 8)
> +#define DISP_REG_MERGE_CFG_37          0x0a4
> +/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
> +#define BUFFER_MODE                    3
> +#define FLD_BUFFER_MODE                        GENMASK(1, 0)
> +#define DISP_REG_MERGE_CFG_38          0x0a8
> +#define FLD_VDE_BLOCK_ULTRA            GENMASK(0, 0)
> +#define FLD_VALID_TH_BLOCK_ULTRA       GENMASK(4, 4)
> +#define FLD_ULTRA_FIFO_VALID_TH                GENMASK(31, 16)
> +#define DISP_REG_MERGE_CFG_39          0x0ac
> +#define FLD_NVDE_FORCE_PREULTRA                GENMASK(8, 8)
> +#define FLD_NVALID_TH_FORCE_PREULTRA   GENMASK(12, 12)
> +#define FLD_PREULTRA_FIFO_VALID_TH     GENMASK(31, 16)
> +#define DISP_REG_MERGE_CFG_40          0x0b0
> +/* 6 us, 600M pixel/sec */
> +#define ULTRA_TH_LOW                   (6 * 600)
> +/* 8 us, 600M pixel/sec */
> +#define ULTRA_TH_HIGH                  (8 * 600)
> +#define FLD_ULTRA_TH_LOW               GENMASK(15, 0)
> +#define FLD_ULTRA_TH_HIGH              GENMASK(31, 16)
> +#define DISP_REG_MERGE_CFG_41          0x0b4
> +/* 8 us, 600M pixel/sec */
> +#define PREULTRA_TH_LOW                        (8 * 600)
> +/* 9 us, 600M pixel/sec */

Add comment that "6 us ~ 9us is experience value and max mmsys clock
frequency is 594MHz", and I think you should use 594 instead of 600.

Regards,
Chun-Kuang.

> +#define PREULTRA_TH_HIGH               (9 * 600)
> +#define FLD_PREULTRA_TH_LOW            GENMASK(15, 0)
> +#define FLD_PREULTRA_TH_HIGH           GENMASK(31, 16)
> +
> +struct mtk_disp_merge {
> +       void __iomem *regs;
> +       struct clk *clk;
> +       struct clk *async_clk;
> +       struct cmdq_client_reg          cmdq_reg;
> +       bool                            fifo_en;
> +};
> +
> +void mtk_merge_start(struct device *dev)
> +{
> +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +
> +       writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
> +}
> +
> +void mtk_merge_stop(struct device *dev)
> +{
> +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +
> +       writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
> +}
> +
> +static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
> +                                  struct cmdq_pkt *handle)
> +{
> +       mtk_ddp_write_mask(handle, ULTRA_EN | PREULTRA_EN << 4 | HALT_FOR_DVFS_EN << 8,
> +                          &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_36,
> +                          FLD_ULTRA_EN | FLD_PREULTRA_EN | FLD_HALT_FOR_DVFS_EN);
> +
> +       mtk_ddp_write_mask(handle, BUFFER_MODE,
> +                          &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_37,
> +                          FLD_BUFFER_MODE);
> +
> +       mtk_ddp_write_mask(handle, 0,
> +                          &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_38,
> +                          FLD_VDE_BLOCK_ULTRA | FLD_VALID_TH_BLOCK_ULTRA |
> +                          FLD_ULTRA_FIFO_VALID_TH);
> +
> +       mtk_ddp_write_mask(handle, 0,
> +                          &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_39,
> +                          FLD_NVDE_FORCE_PREULTRA | FLD_NVALID_TH_FORCE_PREULTRA |
> +                          FLD_PREULTRA_FIFO_VALID_TH);
> +
> +       mtk_ddp_write_mask(handle, ULTRA_TH_LOW | ULTRA_TH_HIGH << 16,
> +                          &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_40,
> +                          FLD_ULTRA_TH_LOW | FLD_ULTRA_TH_HIGH);
> +
> +       mtk_ddp_write_mask(handle, PREULTRA_TH_LOW | PREULTRA_TH_HIGH << 16,
> +                          &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_41,
> +                          FLD_PREULTRA_TH_LOW | FLD_PREULTRA_TH_HIGH);
> +}
> +
> +void mtk_merge_config(struct device *dev, unsigned int w,
> +                     unsigned int h, unsigned int vrefresh,
> +                     unsigned int bpc, struct cmdq_pkt *handle)
> +{
> +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +       unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
> +
> +       if (!h || !w) {
> +               dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
> +               return;
> +       }
> +
> +       if (priv->fifo_en) {
> +               mtk_merge_fifo_setting(priv, handle);
> +               mode = CFG_10_10_2PI_2PO_BUF_MODE;
> +       }
> +
> +       mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
> +                     DISP_REG_MERGE_CFG_0);
> +       mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
> +                     DISP_REG_MERGE_CFG_4);
> +       mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
> +                     DISP_REG_MERGE_CFG_24);
> +       mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
> +                     DISP_REG_MERGE_CFG_25);
> +       mtk_ddp_write_mask(handle, SWAP_MODE, &priv->cmdq_reg, priv->regs,
> +                          DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
> +       mtk_ddp_write_mask(handle, mode, &priv->cmdq_reg, priv->regs,
> +                          DISP_REG_MERGE_CFG_12, FLD_CFG_MERGE_MODE);
> +}
> +
> +int mtk_merge_clk_enable(struct device *dev)
> +{
> +       int ret = 0;
> +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +
> +       ret = clk_prepare_enable(priv->clk);
> +       if (ret)
> +               pr_err("merge clk prepare enable failed\n");
> +
> +       if (priv->async_clk) {
> +               ret = clk_prepare_enable(priv->async_clk);
> +               if (ret)
> +                       pr_err("async clk prepare enable failed\n");
> +       }
> +
> +       return ret;
> +}
> +
> +void mtk_merge_clk_disable(struct device *dev)
> +{
> +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +
> +       if (priv->async_clk)
> +               clk_disable_unprepare(priv->async_clk);
> +
> +       clk_disable_unprepare(priv->clk);
> +}
> +
> +static int mtk_disp_merge_bind(struct device *dev, struct device *master,
> +                              void *data)
> +{
> +       return 0;
> +}
> +
> +static void mtk_disp_merge_unbind(struct device *dev, struct device *master,
> +                                 void *data)
> +{
> +}
> +
> +static const struct component_ops mtk_disp_merge_component_ops = {
> +       .bind   = mtk_disp_merge_bind,
> +       .unbind = mtk_disp_merge_unbind,
> +};
> +
> +static int mtk_disp_merge_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct resource *res;
> +       struct mtk_disp_merge *priv;
> +       int ret;
> +
> +       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       priv->regs = devm_ioremap_resource(dev, res);
> +       if (IS_ERR(priv->regs)) {
> +               dev_err(dev, "failed to ioremap merge\n");
> +               return PTR_ERR(priv->regs);
> +       }
> +
> +       priv->clk = devm_clk_get(dev, NULL);
> +       if (IS_ERR(priv->clk)) {
> +               dev_err(dev, "failed to get merge clk\n");
> +               return PTR_ERR(priv->clk);
> +       }
> +
> +       priv->async_clk = of_clk_get(dev->of_node, 1);
> +       if (IS_ERR(priv->async_clk)) {
> +               ret = PTR_ERR(priv->async_clk);
> +               dev_dbg(dev, "No merge async clock: %d\n", ret);
> +               priv->async_clk = NULL;
> +       }
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +       ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
> +       if (ret)
> +               dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
> +#endif
> +
> +       priv->fifo_en = of_property_read_bool(dev->of_node,
> +                                             "mediatek,merge-fifo-en");
> +
> +       platform_set_drvdata(pdev, priv);
> +
> +       ret = component_add(dev, &mtk_disp_merge_component_ops);
> +       if (ret != 0)
> +               dev_err(dev, "Failed to add component: %d\n", ret);
> +
> +       return ret;
> +}
> +
> +static int mtk_disp_merge_remove(struct platform_device *pdev)
> +{
> +       component_del(&pdev->dev, &mtk_disp_merge_component_ops);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id mtk_disp_merge_driver_dt_match[] = {
> +       { .compatible = "mediatek,mt8195-disp-merge", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
> +
> +struct platform_driver mtk_disp_merge_driver = {
> +       .probe = mtk_disp_merge_probe,
> +       .remove = mtk_disp_merge_remove,
> +       .driver = {
> +               .name = "mediatek-disp-merge",
> +               .owner = THIS_MODULE,
> +               .of_match_table = mtk_disp_merge_driver_dt_match,
> +       },
> +};
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 560be6bc9d0e..b42a47c06956 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -25,6 +25,7 @@ enum mtk_ddp_comp_type {
>         MTK_DISP_DITHER,
>         MTK_DISP_DSC,
>         MTK_DISP_GAMMA,
> +       MTK_DISP_MERGE,
>         MTK_DISP_MUTEX,
>         MTK_DISP_OD,
>         MTK_DISP_OVL,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index a95dc1006b82..5eb9c0a04447 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -532,13 +532,14 @@ static int mtk_drm_probe(struct platform_device *pdev)
>                 private->comp_node[comp_id] = of_node_get(node);
>
>                 /*
> -                * Currently only the CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
> +                * Currently only the CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
>                  * blocks have separate component platform drivers and initialize their own
>                  * DDP component structure. The others are initialized here.
>                  */
>                 if (comp_type == MTK_DISP_CCORR ||
>                     comp_type == MTK_DISP_COLOR ||
>                     comp_type == MTK_DISP_GAMMA ||
> +                   comp_type == MTK_DISP_MERGE ||
>                     comp_type == MTK_DISP_OVL ||
>                     comp_type == MTK_DISP_OVL_2L ||
>                     comp_type == MTK_DISP_RDMA ||
> @@ -639,6 +640,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
>         &mtk_disp_ccorr_driver,
>         &mtk_disp_color_driver,
>         &mtk_disp_gamma_driver,
> +       &mtk_disp_merge_driver,
>         &mtk_disp_ovl_driver,
>         &mtk_disp_rdma_driver,
>         &mtk_dpi_driver,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> index 637f5669e895..0fa417219a69 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> @@ -49,6 +49,7 @@ struct mtk_drm_private {
>  extern struct platform_driver mtk_disp_ccorr_driver;
>  extern struct platform_driver mtk_disp_color_driver;
>  extern struct platform_driver mtk_disp_gamma_driver;
> +extern struct platform_driver mtk_disp_merge_driver;
>  extern struct platform_driver mtk_disp_ovl_driver;
>  extern struct platform_driver mtk_disp_rdma_driver;
>  extern struct platform_driver mtk_dpi_driver;
> --
> 2.18.0
>


From matthias.bgg at gmail.com  Fri Aug  6 10:33:54 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 6 Aug 2021 19:33:54 +0200
Subject: [PATCH v2 7/7] drm/mediatek: mtk_dsi: Reset the dsi0 hardware
In-Reply-To: <20210714121116.v2.7.Idbb4727ddf00ba2fe796b630906baff10d994d89@changeid>
References: <20210714101141.2089082-1-enric.balletbo@collabora.com>
 <20210714121116.v2.7.Idbb4727ddf00ba2fe796b630906baff10d994d89@changeid>
Message-ID: <07319ed2-aed9-cbd7-06aa-6603a9bd4567@gmail.com>



On 14/07/2021 12:11, Enric Balletbo i Serra wrote:
> Reset dsi0 HW to default when power on. This prevents to have different
> settingbetween the bootloader and the kernel.

settings between the...

> 
> As not all Mediatek boards have the reset consumer configured in their
> board description, also is not needed on all of them, the reset is optional,
> so the change is compatible with all boards.
> 
> Cc: Jitao Shi <jitao.shi at mediatek.com>
> Suggested-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

> ---
> 
> (no changes since v1)
> 
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index ae403c67cbd9..d8b81e2ab841 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -11,6 +11,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
> +#include <linux/reset.h>
>  
>  #include <video/mipi_display.h>
>  #include <video/videomode.h>
> @@ -980,8 +981,10 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>  	struct mtk_dsi *dsi = dev_get_drvdata(dev);
>  
>  	ret = mtk_dsi_encoder_init(drm, dsi);
> +	if (ret)
> +		return ret;
>  
> -	return ret;
> +	return device_reset_optional(dev);
>  }
>  
>  static void mtk_dsi_unbind(struct device *dev, struct device *master,
> 


From matthias.bgg at gmail.com  Fri Aug  6 10:34:46 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 6 Aug 2021 19:34:46 +0200
Subject: [PATCH v2 6/7] soc: mediatek: mmsys: Add reset controller support
In-Reply-To: <20210714121116.v2.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d@changeid>
References: <20210714101141.2089082-1-enric.balletbo@collabora.com>
 <20210714121116.v2.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d@changeid>
Message-ID: <91bee4b6-2b43-e4ef-52ab-72e4e0b0c7b3@gmail.com>



On 14/07/2021 12:11, Enric Balletbo i Serra wrote:
> Among other features the mmsys driver should implement a reset
> controller to be able to reset different bits from their space.
> 
> Cc: Jitao Shi <jitao.shi at mediatek.com>
> Suggested-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>

I'm happy to take this, as soon as we have the updated binding description.

Regards,
Matthias

> ---
> 
> (no changes since v1)
> 
>  drivers/soc/mediatek/mtk-mmsys.c | 69 ++++++++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.h |  2 +
>  2 files changed, 71 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
> index e681029fe804..6ac4deff0164 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -4,10 +4,12 @@
>   * Author: James Liao <jamesjj.liao at mediatek.com>
>   */
>  
> +#include <linux/delay.h>
>  #include <linux/device.h>
>  #include <linux/io.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> +#include <linux/reset-controller.h>
>  #include <linux/soc/mediatek/mtk-mmsys.h>
>  
>  #include "mtk-mmsys.h"
> @@ -55,6 +57,8 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
>  struct mtk_mmsys {
>  	void __iomem *regs;
>  	const struct mtk_mmsys_driver_data *data;
> +	spinlock_t lock; /* protects mmsys_sw_rst_b reg */
> +	struct reset_controller_dev rcdev;
>  };
>  
>  void mtk_mmsys_ddp_connect(struct device *dev,
> @@ -91,6 +95,59 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
>  
> +static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
> +				  bool assert)
> +{
> +	struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
> +	unsigned long flags;
> +	u32 reg;
> +	int i;
> +
> +	spin_lock_irqsave(&mmsys->lock, flags);
> +
> +	reg = readl_relaxed(mmsys->regs + MMSYS_SW0_RST_B);
> +
> +	if (assert)
> +		reg &= ~BIT(id);
> +	else
> +		reg |= BIT(id);
> +
> +	writel_relaxed(reg, mmsys->regs + MMSYS_SW0_RST_B);
> +
> +	spin_unlock_irqrestore(&mmsys->lock, flags);
> +
> +	return 0;
> +}
> +
> +static int mtk_mmsys_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> +	return mtk_mmsys_reset_update(rcdev, id, true);
> +}
> +
> +static int mtk_mmsys_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> +	return mtk_mmsys_reset_update(rcdev, id, false);
> +}
> +
> +static int mtk_mmsys_reset(struct reset_controller_dev *rcdev, unsigned long id)
> +{
> +	int ret;
> +
> +	ret = mtk_mmsys_reset_assert(rcdev, id);
> +	if (ret)
> +		return ret;
> +
> +	usleep_range(1000, 1100);
> +
> +	return mtk_mmsys_reset_deassert(rcdev, id);
> +}
> +
> +static const struct reset_control_ops mtk_mmsys_reset_ops = {
> +	.assert = mtk_mmsys_reset_assert,
> +	.deassert = mtk_mmsys_reset_deassert,
> +	.reset = mtk_mmsys_reset,
> +};
> +
>  static int mtk_mmsys_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -111,6 +168,18 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	spin_lock_init(&mmsys->lock);
> +
> +	mmsys->rcdev.owner = THIS_MODULE;
> +	mmsys->rcdev.nr_resets = 32;
> +	mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
> +	mmsys->rcdev.of_node = pdev->dev.of_node;
> +	ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Couldn't register mmsys reset controller: %d\n", ret);
> +		return ret;
> +	}
> +
>  	mmsys->data = of_device_get_match_data(&pdev->dev);
>  	platform_set_drvdata(pdev, mmsys);
>  
> diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
> index 11388961dded..f9f9e12ceab8 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.h
> +++ b/drivers/soc/mediatek/mtk-mmsys.h
> @@ -66,6 +66,8 @@
>  #define DPI_SEL_IN_BLS				0x0
>  #define DSI_SEL_IN_RDMA				0x1
>  
> +#define MMSYS_SW0_RST_B				0x140
> +
>  struct mtk_mmsys_routes {
>  	u32 from_comp;
>  	u32 to_comp;
> 


From sboyd at kernel.org  Fri Aug  6 10:49:19 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 06 Aug 2021 10:49:19 -0700
Subject: [PATCH v10 4/5] spmi: mediatek: Add support for MT8195
In-Reply-To: <1627972461-2627-5-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
 <1627972461-2627-5-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <162827215909.1975443.852277412377742323@swboyd.mtv.corp.google.com>

Quoting Hsin-Hsiung Wang (2021-08-02 23:34:20)
> From: Henry Chen <henryc.chen at mediatek.com>
> 
> Add spmi support for MT8195.
> 
> Signed-off-by: Henry Chen <henryc.chen at mediatek.com>

Missing Signed-off-by from hsin-hsiung.wang here

> ---
> changes since v9:
> - No change.
> ---
>  drivers/spmi/spmi-mtk-pmif.c | 90 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 90 insertions(+)
> 
> diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
> index 94c45d46ab0c..0c320801c9d5 100644
> --- a/drivers/spmi/spmi-mtk-pmif.c
> +++ b/drivers/spmi/spmi-mtk-pmif.c
> @@ -348,6 +427,14 @@ static const struct pmif_data mt6873_pmif_arb = {
>         .soc_chan = 2,
>  };
>  
> +static const struct pmif_data mt8195_pmif_arb[] = {

This is an array of type pmif_data.

> +       {
> +               .regs = mt8195_regs,
> +               .spmimst_regs = mt8195_spmi_regs,
> +               .soc_chan = 2,
> +       },
> +};
> +
>  static int mtk_spmi_probe(struct platform_device *pdev)
>  {
>         struct pmif *arb;
> @@ -444,6 +531,9 @@ static const struct of_device_id mtk_spmi_match_table[] = {
>         {
>                 .compatible = "mediatek,mt6873-spmi",
>                 .data = &mt6873_pmif_arb,

mt6873_pmif_arb is not an array, see the context header above.

How does this work? Has this been tested?

> +       }, {
> +               .compatible = "mediatek,mt8195-spmi",
> +               .data = &mt8195_pmif_arb,
>         }, {
>                 /* sentinel */
>         },
> -- 
> 2.18.0
>


From oupton at google.com  Fri Aug  6 11:18:55 2021
From: oupton at google.com (Oliver Upton)
Date: Fri,  6 Aug 2021 18:18:55 +0000
Subject: [PATCH] clocksource/arm_arch_timer: Fix masking for high freq counters
Message-ID: <20210806181855.2841629-1-oupton@google.com>

Unfortunately, the architecture provides no means to determine the bit
width of the system counter. However, we do know the following from the
specification:

 - the system counter is at least 56 bits wide
 - Roll-over time of not less than 40 years

To date, the arch timer driver has depended on the first property,
assuming any system counter to be 56 bits wide and masking off the rest.
However, combining a narrow clocksource mask with a high frequency
counter could result in prematurely wrapping the system counter by a
significant margin. For example, a 56 bit wide, 1GHz system counter
would wrap in a mere 2.28 years!

This is a problem for two reasons: v8.6+ implementations are required to
provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
implementers may select a counter frequency of their choosing.

Fix the issue by deriving a valid clock mask based on the second
property from above. Set the floor at 56 bits, since we know no system
counter is narrower than that.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Oliver Upton <oupton at google.com>
---
This patch was tested with QEMU, tweaked to provide a 1GHz system
counter frequency, as I could not easily figure out how to tweak the
base FVP to provide a 1GHz counter.

Parent commit: 0c32706dac1b ("arm64: stacktrace: avoid tracing arch_stack_walk()")

 drivers/clocksource/arm_arch_timer.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index be6d741d404c..8c41626a4c8a 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -52,6 +52,12 @@
 #define CNTV_TVAL	0x38
 #define CNTV_CTL	0x3c
 
+/*
+ * The minimum amount of time a generic timer is guaranteed to not roll over
+ * (40 years)
+ */
+#define MIN_ROLLOVER_SECS	(40ULL * 365 * 24 * 3600)
+
 static unsigned arch_timers_present __initdata;
 
 static void __iomem *arch_counter_base __ro_after_init;
@@ -1004,9 +1010,24 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 	return &arch_timer_kvm_info;
 }
 
+/*
+ * Makes an educated guess at a valid counter width based on the Generic Timer
+ * specification. Of note:
+ *   1) the Generic Timer is at least 56 bits wide
+ *   2) a roll-over time of not less than 40 years
+ */
+static int __init arch_counter_get_width(void)
+{
+	u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_get_cntfrq();
+
+	/* guarantee the returned width is within the valid range */
+	return max(56, min(64, ilog2(min_cycles)));
+}
+
 static void __init arch_counter_register(unsigned type)
 {
 	u64 start_count;
+	int width;
 
 	/* Register the CP15 based counter if we have one */
 	if (type & ARCH_TIMER_TYPE_CP15) {
@@ -1031,6 +1052,10 @@ static void __init arch_counter_register(unsigned type)
 		arch_timer_read_counter = arch_counter_get_cntvct_mem;
 	}
 
+	width = arch_counter_get_width();
+	clocksource_counter.mask = CLOCKSOURCE_MASK(width);
+	cyclecounter.mask = CLOCKSOURCE_MASK(width);
+
 	if (!arch_counter_suspend_stop)
 		clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 	start_count = arch_timer_read_counter();
@@ -1040,8 +1065,7 @@ static void __init arch_counter_register(unsigned type)
 	timecounter_init(&arch_timer_kvm_info.timecounter,
 			 &cyclecounter, start_count);
 
-	/* 56 bits minimum, so we assume worst case rollover */
-	sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
+	sched_clock_register(arch_timer_read_counter, width, arch_timer_rate);
 }
 
 static void arch_timer_stop(struct clock_event_device *clk)
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Fri Aug  6 11:21:26 2021
From: oupton at google.com (Oliver Upton)
Date: Fri,  6 Aug 2021 18:21:26 +0000
Subject: [RESEND PATCH] clocksource/arm_arch_timer: Fix masking for high freq
 counters
Message-ID: <20210806182126.2842876-1-oupton@google.com>

Unfortunately, the architecture provides no means to determine the bit
width of the system counter. However, we do know the following from the
specification:

 - the system counter is at least 56 bits wide
 - Roll-over time of not less than 40 years

To date, the arch timer driver has depended on the first property,
assuming any system counter to be 56 bits wide and masking off the rest.
However, combining a narrow clocksource mask with a high frequency
counter could result in prematurely wrapping the system counter by a
significant margin. For example, a 56 bit wide, 1GHz system counter
would wrap in a mere 2.28 years!

This is a problem for two reasons: v8.6+ implementations are required to
provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
implementers may select a counter frequency of their choosing.

Fix the issue by deriving a valid clock mask based on the second
property from above. Set the floor at 56 bits, since we know no system
counter is narrower than that.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Oliver Upton <oupton at google.com>
---
This patch was tested with QEMU, tweaked to provide a 1GHz system
counter frequency, as I could not easily figure out how to tweak the
base FVP to provide a 1GHz counter.

Parent commit: 0c32706dac1b ("arm64: stacktrace: avoid tracing arch_stack_walk()")

 drivers/clocksource/arm_arch_timer.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index be6d741d404c..8c41626a4c8a 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -52,6 +52,12 @@
 #define CNTV_TVAL	0x38
 #define CNTV_CTL	0x3c
 
+/*
+ * The minimum amount of time a generic timer is guaranteed to not roll over
+ * (40 years)
+ */
+#define MIN_ROLLOVER_SECS	(40ULL * 365 * 24 * 3600)
+
 static unsigned arch_timers_present __initdata;
 
 static void __iomem *arch_counter_base __ro_after_init;
@@ -1004,9 +1010,24 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 	return &arch_timer_kvm_info;
 }
 
+/*
+ * Makes an educated guess at a valid counter width based on the Generic Timer
+ * specification. Of note:
+ *   1) the Generic Timer is at least 56 bits wide
+ *   2) a roll-over time of not less than 40 years
+ */
+static int __init arch_counter_get_width(void)
+{
+	u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_get_cntfrq();
+
+	/* guarantee the returned width is within the valid range */
+	return max(56, min(64, ilog2(min_cycles)));
+}
+
 static void __init arch_counter_register(unsigned type)
 {
 	u64 start_count;
+	int width;
 
 	/* Register the CP15 based counter if we have one */
 	if (type & ARCH_TIMER_TYPE_CP15) {
@@ -1031,6 +1052,10 @@ static void __init arch_counter_register(unsigned type)
 		arch_timer_read_counter = arch_counter_get_cntvct_mem;
 	}
 
+	width = arch_counter_get_width();
+	clocksource_counter.mask = CLOCKSOURCE_MASK(width);
+	cyclecounter.mask = CLOCKSOURCE_MASK(width);
+
 	if (!arch_counter_suspend_stop)
 		clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 	start_count = arch_timer_read_counter();
@@ -1040,8 +1065,7 @@ static void __init arch_counter_register(unsigned type)
 	timecounter_init(&arch_timer_kvm_info.timecounter,
 			 &cyclecounter, start_count);
 
-	/* 56 bits minimum, so we assume worst case rollover */
-	sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
+	sched_clock_register(arch_timer_read_counter, width, arch_timer_rate);
 }
 
 static void arch_timer_stop(struct clock_event_device *clk)
-- 
2.32.0.605.g8dce9f2422-goog



From acme at kernel.org  Fri Aug  6 11:36:37 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Fri, 6 Aug 2021 15:36:37 -0300
Subject: [RFC PATCH 6/6] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <b03f9794-ff84-c869-0370-e8f13c577ed5@arm.com>
References: <20210729155805.2830-1-james.clark@arm.com>
 <20210729155805.2830-7-james.clark@arm.com>
 <20210802154145.GC148327@leoy-ThinkPad-X240s>
 <YQlDefz+g45dqFsP@kernel.org>
 <20210803140122.GC247709@leoy-ThinkPad-X240s>
 <b03f9794-ff84-c869-0370-e8f13c577ed5@arm.com>
Message-ID: <YQ2BNSpxCfG7IL70@kernel.org>

Em Thu, Aug 05, 2021 at 01:59:49PM +0100, James Clark escreveu:
> 
> 
> On 03/08/2021 15:01, Leo Yan wrote:
> >> one can also use debuginfod-client, which, as time passes, probably will
> >> be the main way of finding DSOs now that we have build-ids in
> >> PERF_RECORD_MMAP2 and debuginfod servers such as:
> >>
> >> export DEBUGINFOD_URLS=https://debuginfod.fedoraproject.org/
> > If so, maybe should use more general description for missing DSO.
> > 
> >> https://fedoraproject.org/wiki/Debuginfod
> >>  
> >>> With this improvement, the patch looks good to me:
> >>>
> >>> Reviewed-by: Leo Yan <leo.yan at linaro.org>
> >> Does this apply to the other 5 patches in this series?
> > I finished to reivew patches 01, 04, 05, 06/06, so my review tag can
> > apply on these patches.  Current patch 06/06 needs James to improve for
> > the comments.
> 
> Thanks for the reviews, I've submitted v2.
> 
> I also had a play around with debuginfod, it looks promising.
> Especially if it's integrated with perf report, which I assume is the plan?

Yeah, code is needed for that in the underlying symbols library so that
we can tune its usage, i.e. the threshold of samples to trigger asking
for the auto-download of debuginfo files.

- Arnaldo


From acme at kernel.org  Fri Aug  6 11:39:28 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Fri, 6 Aug 2021 15:39:28 -0300
Subject: [PATCH v3 1/1] perf cs-etm: Add warnings for missing DSOs
In-Reply-To: <20210805130354.878120-2-james.clark@arm.com>
References: <20210805130354.878120-1-james.clark@arm.com>
 <20210805130354.878120-2-james.clark@arm.com>
Message-ID: <YQ2B4N5ULNdiuwTx@kernel.org>

Em Thu, Aug 05, 2021 at 02:03:54PM +0100, James Clark escreveu:
> Currently decode will silently fail if no binary data is available for
> the decode. This is made worse if only partial data is available because
> the decode will appear to work, but any trace from that missing DSO will
> silently not be generated.
> 
> Add a UI popup once if there is any data missing, and then warn in the
> bottom left for each individual DSO that's missing.
> 
> Reviewed-by: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: James Clark <james.clark at arm.com>

Thanks, applied.

- Arnaldo



From torvalds at linux-foundation.org  Fri Aug  6 11:40:33 2021
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Fri, 6 Aug 2021 11:40:33 -0700
Subject: [GIT PULL] arm64 fixes for -rc5
In-Reply-To: <20210806135331.GA2951@willie-the-truck>
References: <20210806135331.GA2951@willie-the-truck>
Message-ID: <CAHk-=whNiAtCUqeCAcq+GKjmOXFfLCYA84TpeeL2085c+BdmQQ@mail.gmail.com>

On Fri, Aug 6, 2021 at 6:53 AM Will Deacon <will at kernel.org> wrote:
>
> Please pull these arm64 fixes for -rc5. It's all pretty minor but the
> main fix is sorting out how we deal with return values from 32-bit system
> calls as audit expects error codes to be sign-extended to 64 bits

I've pulled this, but that change looks _really_ odd.

First you seem to intentionally *zero-extend* the error value when you
actually set it in pt_regs, and then you sign-extend them when reading
them.

So the rules seem entirely arbitrary: oen place says "upper 32 bits
need to be clear" and another place says "upper 32 bits need to be
sign-extended".

Why this insanity? Why not make the rule be that the upper 32 bits are
always just sign-extended?

           Linus


From pr-tracker-bot at kernel.org  Fri Aug  6 11:48:08 2021
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 06 Aug 2021 18:48:08 +0000
Subject: [GIT PULL] arm64 fixes for -rc5
In-Reply-To: <20210806135331.GA2951@willie-the-truck>
References: <20210806135331.GA2951@willie-the-truck>
Message-ID: <162827568831.18689.10193362789451281830.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 6 Aug 2021 14:53:32 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/73f25536f27182ae3dcf4c0b91b1280cbbac7be3

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From pr-tracker-bot at kernel.org  Fri Aug  6 11:48:10 2021
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 06 Aug 2021 18:48:10 +0000
Subject: [GIT PULL] ARM: SoC fixes for v5.14, part 2
In-Reply-To: <CAK8P3a1u+0tJUqnSOWmC5ixdeGGoBb+mVv30rc65Bjy7a1Wo7w@mail.gmail.com>
References: <CAK8P3a1u+0tJUqnSOWmC5ixdeGGoBb+mVv30rc65Bjy7a1Wo7w@mail.gmail.com>
Message-ID: <162827569077.18689.14862501008139983565.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 6 Aug 2021 16:26:26 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-5.14-2

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/3dc064d29dfbaee66a08ff1cfbb2dff4439302fe

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From nathan at kernel.org  Fri Aug  6 12:13:40 2021
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri,  6 Aug 2021 12:13:40 -0700
Subject: [PATCH] net: ethernet: stmmac: Do not use unreachable() in
 ipq806x_gmac_probe()
Message-ID: <20210806191339.576318-1-nathan@kernel.org>

When compiling with clang in certain configurations, an objtool warning
appears:

drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.o: warning: objtool:
ipq806x_gmac_probe() falls through to next function phy_modes()

This happens because the unreachable annotation in the third switch
statement is not eliminated. The compiler should know that the first
default case would prevent the second and third from being reached as
the comment notes but sanitizer options can make it harder for the
compiler to reason this out.

Help the compiler out by eliminating the unreachable() annotation and
unifying the default case error handling so that there is no objtool
warning, the meaning of the code stays the same, and there is less
duplication.

Reported-by: Sami Tolvanen <samitolvanen at google.com>
Tested-by: Sami Tolvanen <samitolvanen at google.com>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 .../ethernet/stmicro/stmmac/dwmac-ipq806x.c    | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
index 28dd0ed85a82..f7dc8458cde8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -289,10 +289,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
 		val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
 		break;
 	default:
-		dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
-			phy_modes(gmac->phy_mode));
-		err = -EINVAL;
-		goto err_remove_config_dt;
+		goto err_unsupported_phy;
 	}
 	regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
 
@@ -309,10 +306,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
 			NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
 		break;
 	default:
-		dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
-			phy_modes(gmac->phy_mode));
-		err = -EINVAL;
-		goto err_remove_config_dt;
+		goto err_unsupported_phy;
 	}
 	regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
 
@@ -329,8 +323,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
 				NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
 		break;
 	default:
-		/* We don't get here; the switch above will have errored out */
-		unreachable();
+		goto err_unsupported_phy;
 	}
 	regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
 
@@ -361,6 +354,11 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_unsupported_phy:
+	dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
+		phy_modes(gmac->phy_mode));
+	err = -EINVAL;
+
 err_remove_config_dt:
 	stmmac_remove_config_dt(pdev, plat_dat);
 

base-commit: 8fbebef80107d779b8e356cf60323454a4099d76
-- 
2.33.0.rc0



From sunilmut at microsoft.com  Fri Aug  6 12:14:13 2021
From: sunilmut at microsoft.com (Sunil Muthuswamy)
Date: Fri, 6 Aug 2021 19:14:13 +0000
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <87wnp0b86y.wl-maz@kernel.org>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>	<87r1f9wooc.wl-maz@kernel.org>
 <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87wnp0b86y.wl-maz@kernel.org>
Message-ID: <MW4PR21MB2002ABD170CC9786CDF5D493C0F39@MW4PR21MB2002.namprd21.prod.outlook.com>

On Thursday, August 5, 2021 1:35 AM,
Marc Zyngier <maz at kernel.org> wrote:
[...]
> > Hey Mark
> 
> I assume this is for me?
> 
Yes, sorry.

> > would you be willing to consider a scoped down implementation of GIC
> > Direct LPI with just an IRQ chip implementation and no Direct LPI
> > PCI-MSI IRQ chip.
> 
> Could you please clarify? If you are not implementing MSIs, how can a
> device signal LPIs? At the end of the day, something has to write into
> the RD, and it isn't going to happen by sheer magic.
> 
> > This will allow a MSI provider (such as Hyper-V vPCI) to provide a
> > PCI-MSI IRQ chip on top of the Direct LPI IRQ chip and enable
> > PCI-MSI scenarios, and avoid building in assumptions in other cases
> > (like PCI) where firmware specification is not available.
> 
> I really don't get what you are suggesting. Could you please describe
> what you have in mind?
> 
The suggestion was to *not* implement the PCI-MSI IRQ chip in the
Direct LPI GIC implementation, but let the endpoint/specific
implementation provide for the MSI IRQ chip.

For example, the Hyper-V vPCI module does implement a PCI-MSI IRQ
chip (refer to 'hv_pcie_init_irq_domain'). Microsoft Hypervisor
provides/virtualizes the MSI address to be used for Hyper-V vPCI. The
Hypervisor might be using the ITS in the background, but it expects
the device to be programmed with the MSI address that it provides.
And, the Hypervisor takes care of routing the interrupt to the guest.
This is done by the Hyper-V vPCI MSI IRQ chip (refer to
hv_msi_irq_chip) compose MSI message.

Today, for X64, Hyper-V vPCI PCI-MSI irq chip parents itself to the
architectural 'x86_vector_domain'. The suggestion here was to see
if we can support a similar setup for ARM, where the Hyper-V vPCI
PCI-MSI irq chip can parent itself to the 'Direct LPI arch IRQ chip'
(to be implemented).

The arch Direct LPI arch IRQ chip is needed to enable LPIs, invalidate
the LPI configuration (GICR_INVLPIR et. al. ) and allocate LPI IRQs from
the LPI interrupt namespace (i.e. 8192-<num LPIS>).

Happy to expand on this further, if the above is not clear.

Thanks,
Sunil



From alexandre.belloni at bootlin.com  Fri Aug  6 12:38:03 2021
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Fri, 6 Aug 2021 21:38:03 +0200
Subject: [PATCH v2 2/3] rtc: Add support for the MSTAR MSC313 RTC
In-Reply-To: <20210801160921.233081-3-romain.perier@gmail.com>
References: <20210801160921.233081-1-romain.perier@gmail.com>
 <20210801160921.233081-3-romain.perier@gmail.com>
Message-ID: <YQ2Pm7nrEFmdS6Ky@piout.net>

Hello,

On 01/08/2021 18:09:20+0200, Romain Perier wrote:
> +static int msc313_rtc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct msc313_rtc *priv;
> +	int ret;
> +	int irq;
> +	unsigned long rate;
> +	u16 reg;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(priv->rtc_base))
> +		return PTR_ERR(priv->rtc_base);
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0)
> +		return -EINVAL;
> +
> +	priv->rtc_dev = devm_rtc_allocate_device(dev);
> +	if (IS_ERR(priv->rtc_dev))
> +		return PTR_ERR(priv->rtc_dev);
> +
> +	priv->rtc_dev->ops = &msc313_rtc_ops;
> +	priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000;

I'm pretty sure this doesn't fit in this RTC registers, you should
probably leave range_min to 0 (i.e. not set it at all).

> +	priv->rtc_dev->range_max = U32_MAX - 1; /* 2106-02-07 06:28:14 */

I guess this one should be U32_MAX
> +
> +	ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
> +			       dev_name(&pdev->dev), &pdev->dev);
> +	if (ret) {
> +		dev_err(dev, "Could not request IRQ\n");
> +		return ret;
> +	}
> +
> +	priv->clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(priv->clk)) {
> +		dev_err(dev, "No input reference clock\n");
> +		return PTR_ERR(priv->clk);
> +	}
> +
> +	ret = clk_prepare_enable(priv->clk);
> +	if (ret) {
> +		dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, priv->clk);
> +	if (ret)
> +		return ret;
> +
> +	rate = clk_get_rate(priv->clk);
> +	writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
> +	writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
> +
> +	reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +	reg |= CNT_EN_BIT;
> +	writew(reg, priv->rtc_base + REG_RTC_CTRL);
> +

If on POR, CNT_EN_BIT is not set, then it would be nice to use that to
know whether the RTC is properly set. You can then check CNT_EN_BIT in
.read_time and return -EINVAL if it is not set. Then you can set the bit
in .set_time. It is anyway useless to let the RTC running if it is not
set.

> +	platform_set_drvdata(pdev, priv);
> +
> +	return devm_rtc_register_device(priv->rtc_dev);
> +}
> +
> +static const struct of_device_id msc313_rtc_of_match_table[] = {
> +	{ .compatible = "mstar,msc313-rtc" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, ms_rtc_of_match_table);
> +
> +static struct platform_driver msc313_rtc_driver = {
> +	.probe = msc313_rtc_probe,
> +	.driver = {
> +		.name = "msc313-rtc",
> +		.of_match_table = msc313_rtc_of_match_table,
> +	},
> +};
> +
> +module_platform_driver(msc313_rtc_driver);
> +
> +MODULE_AUTHOR("Daniel Palmer <daniel at thingy.jp>");
> +MODULE_AUTHOR("Romain Perier <romain.perier at gmail.com>");
> +MODULE_DESCRIPTION("MStar RTC Driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.30.2
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From robh+dt at kernel.org  Fri Aug  6 12:47:50 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 13:47:50 -0600
Subject: [PATCH v2 1/6] PCI: dwc: tegra: move GEN3_RELATED DBI register to
 common header
In-Reply-To: <c15ac1443ec765e32a2801241dcd8e924abc769b.1620203062.git.baruch@tkos.co.il>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <c15ac1443ec765e32a2801241dcd8e924abc769b.1620203062.git.baruch@tkos.co.il>
Message-ID: <CAL_Jsq+SBRP4n-0Q9RShxj2Od-EGpBURNUZo8fLnscOY-m7SmA@mail.gmail.com>

On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
>
> These are common dwc macros that will be used for other platforms.
>
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
>  drivers/pci/controller/dwc/pcie-designware.h | 6 ++++++
>  drivers/pci/controller/dwc/pcie-tegra194.c   | 6 ------
>  2 files changed, 6 insertions(+), 6 deletions(-)

Reviewed-by: Rob Herring <robh at kernel.org>


From robh+dt at kernel.org  Fri Aug  6 12:59:44 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 13:59:44 -0600
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
Message-ID: <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>

On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
>
> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>
> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> platform.
>
> The code is based on downstream Codeaurora kernel v5.4. Split out the
> DBI registers access part from .init into .post_init. DBI registers are
> only accessible after phy_power_on().
>
> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
> v2:
>   * Drop ATU configuration; rely on common code instead
>
>   * Use more common register macros
>
>   * Use bulk clk and reset APIs
> ---
>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
>  drivers/pci/controller/dwc/pcie-qcom.c       | 150 +++++++++++++++++++
>  2 files changed, 151 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index ceb359b6e6a6..346462c74a3e 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -76,6 +76,7 @@
>
>  #define GEN3_RELATED_OFF                       0x890
>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL   BIT(0)
> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS    BIT(13)
>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE       BIT(16)
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK  GENMASK(25, 24)
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 8a7a300163e5..93766aee3e7c 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -52,6 +52,10 @@
>  #define PCIE20_PARF_DBI_BASE_ADDR              0x168
>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16C
>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL       0x174
> +#define AHB_CLK_EN                             BIT(0)
> +#define MSTR_AXI_CLK_EN                                BIT(1)
> +#define BYPASS                                 BIT(4)
> +
>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT      0x178
>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2   0x1A8
>  #define PCIE20_PARF_LTSSM                      0x1B0
> @@ -94,6 +98,12 @@
>  #define SLV_ADDR_SPACE_SZ                      0x10000000
>
>  #define PCIE20_LNK_CONTROL2_LINK_STATUS2       0xa0
> +#define PCIE_CAP_CURR_DEEMPHASIS               BIT(16)

Isn't this a standard register field?

> +#define SPEED_GEN1                             0x1
> +#define SPEED_GEN2                             0x2
> +#define SPEED_GEN3                             0x3

And these?

There's already some common DWC code for setting the link speed.

> +#define AXI_CLK_RATE                           200000000
> +#define RCHNG_CLK_RATE                         100000000
>
>  #define DEVICE_TYPE_RC                         0x4
>
> @@ -168,6 +178,11 @@ struct qcom_pcie_resources_2_7_0 {
>         struct clk *pipe_clk;
>  };
>
> +struct qcom_pcie_resources_2_9_0 {
> +       struct clk_bulk_data clks[5];
> +       struct reset_control *rst;
> +};
> +
>  union qcom_pcie_resources {
>         struct qcom_pcie_resources_1_0_0 v1_0_0;
>         struct qcom_pcie_resources_2_1_0 v2_1_0;
> @@ -175,6 +190,7 @@ union qcom_pcie_resources {
>         struct qcom_pcie_resources_2_3_3 v2_3_3;
>         struct qcom_pcie_resources_2_4_0 v2_4_0;
>         struct qcom_pcie_resources_2_7_0 v2_7_0;
> +       struct qcom_pcie_resources_2_9_0 v2_9_0;
>  };
>
>  struct qcom_pcie;
> @@ -1266,6 +1282,130 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
>         clk_disable_unprepare(res->pipe_clk);
>  }
>
> +static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
> +{
> +       struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +       struct dw_pcie *pci = pcie->pci;
> +       struct device *dev = pci->dev;
> +       int ret;
> +
> +       res->clks[0].id = "iface";
> +       res->clks[1].id = "axi_m";
> +       res->clks[2].id = "axi_s";
> +       res->clks[3].id = "axi_bridge";
> +       res->clks[4].id = "rchng";
> +
> +       ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
> +       if (ret < 0)
> +               return ret;
> +
> +       res->rst = devm_reset_control_array_get_exclusive(dev);
> +       if (IS_ERR(res->rst))
> +               return PTR_ERR(res->rst);
> +
> +       return 0;
> +}
> +
> +static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
> +{
> +       struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +
> +       clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
> +}
> +
> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
> +{
> +       struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +       struct device *dev = pcie->pci->dev;
> +       int ret;
> +
> +       ret = reset_control_assert(res->rst);
> +       if (ret) {
> +               dev_err(dev, "reset assert failed (%d)\n", ret);
> +               return ret;
> +       }
> +
> +       usleep_range(2000, 2500);
> +
> +       ret = reset_control_deassert(res->rst);
> +       if (ret) {
> +               dev_err(dev, "reset deassert failed (%d)\n", ret);
> +               return ret;
> +       }
> +
> +       /*
> +        * Don't have a way to see if the reset has completed.
> +        * Wait for some time.
> +        */
> +       usleep_range(2000, 2500);
> +
> +       ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
> +       if (ret)
> +               goto err_reset;
> +
> +       return 0;
> +
> +       /*
> +        * Not checking for failure, will anyway return
> +        * the original failure in 'ret'.
> +        */
> +err_reset:
> +       reset_control_assert(res->rst);
> +
> +       return ret;
> +}
> +
> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
> +{
> +       struct dw_pcie *pci = pcie->pci;
> +       u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> +       u32 val;
> +       int i;
> +
> +       writel(SLV_ADDR_SPACE_SZ,
> +               pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
> +
> +       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> +       val &= ~BIT(0);
> +       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> +
> +       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> +
> +       writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
> +       writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
> +               pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> +       writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
> +               | GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
> +               pci->dbi_base + GEN3_RELATED_OFF);
> +
> +       writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
> +               | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
> +               AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
> +               pcie->parf + PCIE20_PARF_SYS_CTRL);
> +
> +       writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
> +
> +       dw_pcie_dbi_ro_wr_en(pci);
> +       writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
> +
> +       /* Configure PCIe link capabilities for ASPM */
> +       val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
> +       val &= ~PCI_EXP_LNKCAP_ASPMS;
> +       writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
> +
> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> +                       PCI_EXP_DEVCTL2);
> +
> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);

Doesn't this overwrite the prior register write?

> +
> +       for (i = 0;i < 256;i++)
> +               writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
> +                               + (4 * i));
> +
> +       return 0;
> +}
> +
>  static int qcom_pcie_link_up(struct dw_pcie *pci)
>  {
>         u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> @@ -1456,6 +1596,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
>         .config_sid = qcom_pcie_config_sid_sm8250,
>  };
>
> +/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
> +static const struct qcom_pcie_ops ops_2_9_0 = {
> +       .get_resources = qcom_pcie_get_resources_2_9_0,
> +       .init = qcom_pcie_init_2_9_0,
> +       .post_init = qcom_pcie_post_init_2_9_0,
> +       .deinit = qcom_pcie_deinit_2_9_0,
> +       .ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
> +};
> +
>  static const struct dw_pcie_ops dw_pcie_ops = {
>         .link_up = qcom_pcie_link_up,
>         .start_link = qcom_pcie_start_link,
> @@ -1555,6 +1704,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>         { .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },
>         { .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 },
>         { .compatible = "qcom,pcie-sm8250", .data = &ops_1_9_0 },
> +       { .compatible = "qcom,pcie-ipq6018", .data = &ops_2_9_0 },
>         { }
>  };
>
> --
> 2.30.2
>


From miquel.raynal at bootlin.com  Fri Aug  6 13:02:57 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri,  6 Aug 2021 22:02:57 +0200
Subject: [PATCH] mtd: rawnand: remove never changed ret variable
In-Reply-To: <20210803113300.24230-1-wangborong@cdjrlc.com>
Message-ID: <20210806200257.393527-1-miquel.raynal@bootlin.com>

On Tue, 2021-08-03 at 11:33:00 UTC, Jason Wang wrote:
> The ret variable used for returning value in the function
> `meson_nfc_rw_cmd_prepare_and_execute` is never change after initialising.
> Therefore, we can remove it safely and return 0 at the end of the function.
> 
> Signed-off-by: Jason Wang <wangborong at cdjrlc.com>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel


From pawel.mikolaj.chmiel at gmail.com  Fri Aug  6 13:32:16 2021
From: pawel.mikolaj.chmiel at gmail.com (=?UTF-8?Q?Pawe=c5=82_Chmiel?=)
Date: Fri, 6 Aug 2021 22:32:16 +0200
Subject: [PATCH 12/12] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <b753796c-2ce6-4166-7c20-289e950237ad@canonical.com>
References: <20210730144922.29111-1-semen.protsenko@linaro.org>
 <20210730144922.29111-13-semen.protsenko@linaro.org>
 <455cfb5e-dff7-a5c0-3875-49abe3e900f3@canonical.com>
 <CAPLW+4nDS0atrbUFagDA0W_Ky5MvOiY+N+NQoQ+me4pndp_iWg@mail.gmail.com>
 <68734f6c-fc76-595c-8d34-8924dbbbb845@canonical.com>
 <CAPLW+4n_JKj5xeBHXONcv__vyAFvx3fhXoxJa17NTHK1RSJFJw@mail.gmail.com>
 <b753796c-2ce6-4166-7c20-289e950237ad@canonical.com>
Message-ID: <50f84842-c397-8012-af95-e9d9fce53162@gmail.com>

W dniu 06.08.2021 o?14:32, Krzysztof Kozlowski pisze:
> On 06/08/2021 14:07, Sam Protsenko wrote:
>> On Fri, 6 Aug 2021 at 10:49, Krzysztof Kozlowski
>> <krzysztof.kozlowski at canonical.com> wrote:
>>>
>>> On 06/08/2021 01:06, Sam Protsenko wrote:
>>>> On Sat, 31 Jul 2021 at 12:03, Krzysztof Kozlowski
>>>> <krzysztof.kozlowski at canonical.com> wrote:
>>>>
>>>>>>
>>>>>> This patch adds minimal SoC support. Particular board device tree files
>>>>>> can include exynos850.dtsi file to get SoC related nodes, and then
>>>>>> reference those nodes further as needed.
>>>>>>
>>>>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>>>>> ---
>>>>>>   .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 782 ++++++++++++++++++
>>>>>>   arch/arm64/boot/dts/exynos/exynos850-usi.dtsi |  30 +
>>>>>>   arch/arm64/boot/dts/exynos/exynos850.dtsi     | 245 ++++++
>>>>>
>>>>> Not buildable. Missing Makefile, missing DTS. Please submit with initial
>>>>> DTS, otherwise no one is able to verify it even compiles.
>>>>>
>>>>
>>>> This device is not available for purchase yet. I'll send the patch for
>>>> board dts once it's announced. I can do all the testing for now, if
>>>> you have any specific requests. Would it be possible for us to review
>>>> and apply only SoC support for now? Will send v2 soon...
>>>
>>> What you propose is equal to adding a driver (C source code) without
>>> ability to compile it. What's the point of having it in the kernel? It's
>>> unverifiable, unbuildable and unusable.
>>>
>>
>> Yes, I understand. That's adding code with no users, and it's not a
>> good practice.
>>
>>> We can review the DTSI however merging has to be with a DTS. Usually the
>>> SoC vendor adds first an evalkit (e.g. SMDK board). Maybe you have one
>>> for Exynos850? Otherwise if you cannot disclose the actual board, the
>>> DTSI will have to wait. You can submit drivers, though.
>>>
>>
>> Sure, let's go this way. I'll send v2 soon. Improving patches and
>> having Reviewed-by tag for those would good enough for me at this
>> point. I'll continue to prepare another Exynos850 related patches
>> until the actual board is announced, like proper clock driver, reset,
>> MMC, etc. Is it ok if I send those for a review too (so I can fix all
>> issues ahead)?
> 
> Sure, prepare all necessary drivers earlier. I suspect clocks will be a
> real pain because of significant changes modeled in vendor kernel. I
> remember Pawe? Chmiel (+Cc) was doing something for these:
> https://github.com/PabloPL/linux/tree/exynos7420
> 
> I mentioned before - you should also modify the chipid driver. Check
> also other drivers in drivers/soc/samsung, although some are needed only
> for suspend&resume.
> 
> BTW, Pawe?,
> How is your Exynos7420 progress? :)
Hi

Sadly i had to postpone it for a while. Maybe will have more time now to 
get back to it.

About clock driver. In vendor sources there is clk driver with something 
called virtual clocks (different than real ones). That driver calls 
another driver called pwrcal, responsible for real manipulation of 
clocks in hardware. This one has info about real clocks and also 
additional info about for example rate for some of them, which is read 
from binary from memory, by another driver called ect_parser in case of 
devices at which i did looked.

In my case i was able to find some more info about real clocks there - 
for example register names and offsets 
https://github.com/krzk/linux-vendor-backup/blob/mokee/android-3.18-samsung-galaxy-s7-sm-g930f-exynos8890/drivers/soc/samsung/pwrcal/S5E8890/S5E8890-cmusfr.h 
and some clocks hierarchy info inside 
https://github.com/krzk/linux-vendor-backup/blob/mokee/android-3.18-samsung-galaxy-s7-sm-g930f-exynos8890/drivers/soc/samsung/pwrcal/S5E8890/S5E8890-cmu.c 
but there was still many info missing.

Finding a way (which could be applied to other Exynos SOC) to "convert" 
or use that vendor code and turn it into mainline driver, especially 
without TRM which is not available for all/most of them, would be great.

I'm wondering if Exynos850 device has the same issue as on 7420 (and 
probably 8890/7578 and maybe also other 64 bit Exynos devices) - broken 
firmware. For example i had to specify in dts timer clock frequency, on 
few devices there is also a problem with timer registers not properly 
configured by FW, which probably won't be fixed by vendor and patches 
with workaround for it in kernel were rejected :/.
> 
>> And should I maybe add RFC tag for those?
> 
> No need. Drivers can be merged before DTS users.
> 
> Best regards,
> Krzysztof
> 



From robh at kernel.org  Fri Aug  6 13:37:37 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 14:37:37 -0600
Subject: [PATCH 01/11] dt-bindings: usb: mtk-xhci: add support property
 'tpl-support'
In-Reply-To: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YQ2dkcKiXxIHLCOT@robh.at.kernel.org>

On Fri, Jul 30, 2021 at 04:49:52PM +0800, Chunfeng Yun wrote:
> Add property 'tpl-support' to support targeted peripheral list
> for USB-IF Embedded Host Compliance Test

Given you have to configure the TPL somehow, how is this useful to be in 
DT? And no, that's not a suggestion to put all the TPL config into DT.

> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> index 240882b12565..49729aab6d1a 100644
> --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> @@ -115,6 +115,8 @@ properties:
>  
>    usb2-lpm-disable: true
>  
> +  tpl-support: true
> +
>    imod-interval-ns:
>      description:
>        Interrupt moderation interval value, it is 8 times as much as that
> -- 
> 2.18.0
> 
> 


From robh at kernel.org  Fri Aug  6 13:41:10 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 14:41:10 -0600
Subject: [PATCH 02/11] dt-bindings: usb: mtk-xhci: add optional property
 to disable usb2 ports
In-Reply-To: <1627635002-24521-2-git-send-email-chunfeng.yun@mediatek.com>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
 <1627635002-24521-2-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YQ2eZkqb++K3K5NN@robh.at.kernel.org>

On Fri, Jul 30, 2021 at 04:49:53PM +0800, Chunfeng Yun wrote:
> Add support to disable specific usb2 host ports, it's useful when
> a usb2 port is disabled on some platforms, but enabled on others for
> the same SoC, another case is that the different package may support
> different number of ports.
> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> index 49729aab6d1a..61a0e550b5d6 100644
> --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> @@ -154,6 +154,11 @@ properties:
>      description: The mask to disable u3ports, bit0 for u3port0,
>        bit1 for u3port1, ... etc
>  
> +  mediatek,u2p-dis-msk:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: The mask to disable u2ports, bit0 for u2port0,
> +      bit1 for u2port1, ... etc

You already have this property in the parent node, right? Why are we 
duplicating it in both places?

Rob


From robh at kernel.org  Fri Aug  6 13:43:20 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 14:43:20 -0600
Subject: [PATCH 03/11] dt-bindings: usb: mtk-xhci: add compatible for
 mt8195
In-Reply-To: <1627635002-24521-3-git-send-email-chunfeng.yun@mediatek.com>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
 <1627635002-24521-3-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YQ2e6AGFi7beqp6Q@robh.at.kernel.org>

On Fri, Jul 30, 2021 at 04:49:54PM +0800, Chunfeng Yun wrote:
> There are 4 USB controllers on MT8195, the controllers (IP1~IP3,
> exclude IP0) have a wrong default SOF/ITP interval which is
> calculated from the frame counter clock 24Mhz by default, but
> in fact, the frame counter clock is 48Mhz, so we should set
> the accurate interval according to 48Mhz. Here add a new compatible
> for MT8195, it's also supported in driver. But the first controller
> (IP0) has no such issue, we prefer to use generic compatible,
> e.g. mt8192's compatible.

That only works until you find some 8195 bug common to all instances. 
Can't you read the clock frequency?

> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> index 61a0e550b5d6..753e043e5327 100644
> --- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
> @@ -31,6 +31,7 @@ properties:
>            - mediatek,mt8173-xhci
>            - mediatek,mt8183-xhci
>            - mediatek,mt8192-xhci
> +          - mediatek,mt8195-xhci
>        - const: mediatek,mtk-xhci
>  
>    reg:
> -- 
> 2.18.0
> 
> 


From mnhagan88 at gmail.com  Fri Aug  6 13:44:31 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Fri,  6 Aug 2021 21:44:31 +0100
Subject: [PATCH v5 0/5] ARM: dts: NSP: add Meraki MX64/MX65 series
Message-ID: <20210806204446.2981299-1-mnhagan88@gmail.com>

Changes from v2:
  - Introduce boards to Makefile in same patch as the board dts is added
    (Vladimir Oltean)
  - Use alphabetical ordering for labels (Vladimir Oltean)
  - Remove address-cells and size-cells in qca8337 switch nodes (Vladimir
    Oltean)
  - Remove "cpu" labels from switch nodes' CPU ports (Vladimir Oltean)
  - Various LED fixes, utilising dt-bindings/leds/common.h and correctly
    specifying LEDs in the form "led-N" and with the color/function/
    function-enumerator properties.
  - Fix PWM LEDs and corresponding pinctrl bindings. (Vladimir Oltean)

The following changes were submitted as a separate series:
  - Introduce patches to disable QSPI by default and enable where used
    (Vladimir Oltean)
  - Move mdio at 18032000 node from board related file to SoC (Vladimir
    Oltean)
  - In addition to above, relocate mdio-mux to bcm-nsp.dtsi and fix
    the resulting usb3_phy issues

Changes from v3:
  - Sort labels on mx64 a0 dts files into alphabetical order as well
  - move include directives for input/input.h and leds/common.h to
    bcm958625-mx6x-common.dtsi
  - Whitespace fixes in bcm958625-mx6x-common.dtsi
  - rename "senao_nvram" partition to "nvram" 

Changes from v4:
  - Move chosen and memory nodes from bcm958625-mx6x-common.dtsi to
    each .dts file (Arnd Bergmann).
  - Append [@<unit-address>] to memory nodes.
  - Create Ax stepping-specific dtsi for Ax devices (Arnd Bergmann).
  - Append read-only property to at24 eeprom node.
  - Remove L2 properties which should be defined at platform-level.
  - Correct NAND node names.

Matthew Hagan (5):
  ARM: dts: NSP: Add common bindings for MX64/MX65
  ARM: dts: NSP: Add Ax stepping modifications
  ARM: dts: NSP: Add DT files for Meraki MX64 series
  ARM: dts: NSP: Add DT files for Meraki MX65 series
  dt-bindings: arm: bcm: NSP: add Meraki MX64/MX65

 .../devicetree/bindings/arm/bcm/brcm,nsp.yaml |   6 +
 arch/arm/boot/dts/Makefile                    |   6 +
 arch/arm/boot/dts/bcm-nsp-ax.dtsi             |  71 +++++
 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 279 ++++++++++++++++++
 .../boot/dts/bcm958625-meraki-kingpin.dtsi    | 163 ++++++++++
 .../arm/boot/dts/bcm958625-meraki-mx64-a0.dts |  25 ++
 arch/arm/boot/dts/bcm958625-meraki-mx64.dts   |  24 ++
 .../boot/dts/bcm958625-meraki-mx64w-a0.dts    |  33 +++
 arch/arm/boot/dts/bcm958625-meraki-mx64w.dts  |  32 ++
 arch/arm/boot/dts/bcm958625-meraki-mx65.dts   |  24 ++
 arch/arm/boot/dts/bcm958625-meraki-mx65w.dts  |  32 ++
 .../dts/bcm958625-meraki-mx6x-common.dtsi     | 129 ++++++++
 12 files changed, 824 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm-nsp-ax.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64w.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx65.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx65w.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi

-- 
2.26.3



From mnhagan88 at gmail.com  Fri Aug  6 13:44:32 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Fri,  6 Aug 2021 21:44:32 +0100
Subject: [PATCH v5 1/5] ARM: dts: NSP: Add common bindings for MX64/MX65
In-Reply-To: <20210806204446.2981299-1-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
Message-ID: <20210806204446.2981299-2-mnhagan88@gmail.com>

These bindings are required for all Meraki MX64/MX65 devices. These
common bindings include memory (2GB), PWM LEDs, AMAC, I2C (AT24), NAND
partitions, EHCI, OHCI and pinctrl.

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 .../dts/bcm958625-meraki-mx6x-common.dtsi     | 129 ++++++++++++++++++
 1 file changed, 129 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi

diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
new file mode 100644
index 000000000000..bcdd38954f1d
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Common Bindings for Cisco Meraki MX64 (Kingpin) and MX65 (Alamo) devices.
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+#include "bcm-nsp.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	pwm-leds {
+		compatible = "pwm-leds";
+
+		led-1 {
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_RED>;
+			pwms = <&pwm 1 50000>;
+			max-brightness = <255>;
+		};
+
+		led-2 {
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_GREEN>;
+			pwms = <&pwm 2 50000>;
+			max-brightness = <255>;
+		};
+
+		led-3 {
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_BLUE>;
+			pwms = <&pwm 3 50000>;
+			max-brightness = <255>;
+		};
+	};
+};
+
+&amac2 {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	at24 at 50 {
+		compatible = "atmel,24c64";
+		reg = <0x50>;
+		pagesize = <32>;
+		read-only;
+	};
+};
+
+&nand_controller {
+	nand at 0 {
+		compatible = "brcm,nandcs";
+		reg = <0>;
+		nand-on-flash-bbt;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		nand-ecc-strength = <24>;
+		nand-ecc-step-size = <1024>;
+
+		brcm,nand-oob-sector-size = <27>;
+
+		partition at 0 {
+			label = "u-boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition at 80000 {
+			label = "shmoo";
+			reg = <0x80000 0x80000>;
+			read-only;
+		};
+
+		partition at 100000 {
+			label = "bootkernel1";
+			reg = <0x100000 0x300000>;
+		};
+
+		partition at 400000 {
+			label = "nvram";
+			reg = <0x400000 0x100000>;
+		};
+
+		partition at 500000 {
+			label = "bootkernel2";
+			reg = <0x500000 0x300000>;
+		};
+
+		partition at 800000 {
+			label = "ubi";
+			reg = <0x800000 0x3f700000>;
+		};
+	};
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm_leds>;
+
+	pwm_leds: pwm_leds {
+		function = "pwm";
+		groups = "pwm1_grp", "pwm2_grp", "pwm3_grp";
+	};
+};
+
+&pwm {
+	status = "okay";
+	#pwm-cells = <2>;
+};
+
+&uart0 {
+	clock-frequency = <62500000>;
+	status = "okay";
+};
-- 
2.26.3



From mnhagan88 at gmail.com  Fri Aug  6 13:44:33 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Fri,  6 Aug 2021 21:44:33 +0100
Subject: [PATCH v5 2/5] ARM: dts: NSP: Add Ax stepping modifications
In-Reply-To: <20210806204446.2981299-1-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
Message-ID: <20210806204446.2981299-3-mnhagan88@gmail.com>

While uncommon, some Ax NSP SoCs exist in the wild. This stepping
requires a modified secondary CPU boot-reg and removal of DMA coherency
properties. Without these modifications, the secondary CPU will be
inactive and many peripherals will exhibit undefined behaviour.

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm-nsp-ax.dtsi | 70 +++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm-nsp-ax.dtsi

diff --git a/arch/arm/boot/dts/bcm-nsp-ax.dtsi b/arch/arm/boot/dts/bcm-nsp-ax.dtsi
new file mode 100644
index 000000000000..a21e275935ce
--- /dev/null
+++ b/arch/arm/boot/dts/bcm-nsp-ax.dtsi
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Broadcom Northstar Plus Ax stepping-specific bindings.
+ * Notable differences from B0+ are the secondary-boot-reg and
+ * lack of DMA coherency.
+ */
+
+&cpu1 {
+	secondary-boot-reg = <0xffff042c>;
+};
+
+&dma {
+	/delete-property/ dma-coherent;
+};
+
+&sdio {
+	/delete-property/ dma-coherent;
+};
+
+&amac0 {
+	/delete-property/ dma-coherent;
+};
+
+&amac1 {
+	/delete-property/ dma-coherent;
+};
+
+&amac2 {
+	/delete-property/ dma-coherent;
+};
+
+&ehci0 {
+	/delete-property/ dma-coherent;
+};
+
+&mailbox {
+	/delete-property/ dma-coherent;
+};
+
+&xhci {
+	/delete-property/ dma-coherent;
+};
+
+&ehci0 {
+	/delete-property/ dma-coherent;
+};
+
+&ohci0 {
+	/delete-property/ dma-coherent;
+};
+
+&i2c0 {
+	/delete-property/ dma-coherent;
+};
+
+&sata {
+	/delete-property/ dma-coherent;
+};
+
+&pcie0 {
+	/delete-property/ dma-coherent;
+};
+
+&pcie1 {
+	/delete-property/ dma-coherent;
+};
+
+&pcie2 {
+	/delete-property/ dma-coherent;
+};
-- 
2.26.3



From mnhagan88 at gmail.com  Fri Aug  6 13:44:34 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Fri,  6 Aug 2021 21:44:34 +0100
Subject: [PATCH v5 3/5] ARM: dts: NSP: Add DT files for Meraki MX64 series
In-Reply-To: <20210806204446.2981299-1-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
Message-ID: <20210806204446.2981299-4-mnhagan88@gmail.com>

MX64 & MX64W Hardware info:
  - CPU: Broadcom BCM58625 Cortex A9 @ 1200Mhz
  - RAM: 2 GB (4 x 4Gb SK Hynix H5TC4G83CFR)
  - Storage: 1 GB (Micron MT29F8G08ABACA)
  - Networking: BCM58625 internal switch (5x 1GbE ports)
  - USB: 1x USB2.0
  - Serial: Internal header
  - WLAN(MX64W only): 2x Broadcom BCM43520KMLG on the PCI bus

This patch adds the Meraki MX64 series-specific bindings. Since some
devices make use of the older A0 SoC, changes need to be made to
accommodate this case, including removal of coherency options and
modification to the secondary-boot-reg.

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/Makefile                    |   4 +
 .../boot/dts/bcm958625-meraki-kingpin.dtsi    | 163 ++++++++++++++++++
 .../arm/boot/dts/bcm958625-meraki-mx64-a0.dts |  25 +++
 arch/arm/boot/dts/bcm958625-meraki-mx64.dts   |  24 +++
 .../boot/dts/bcm958625-meraki-mx64w-a0.dts    |  33 ++++
 arch/arm/boot/dts/bcm958625-meraki-mx64w.dts  |  32 ++++
 6 files changed, 281 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64w.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 863347b6b65e..17f7bdab50ef 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -155,6 +155,10 @@ dtb-$(CONFIG_ARCH_BCM_NSP) += \
 	bcm958525xmc.dtb \
 	bcm958622hr.dtb \
 	bcm958623hr.dtb \
+	bcm958625-meraki-mx64.dtb \
+	bcm958625-meraki-mx64-a0.dtb \
+	bcm958625-meraki-mx64w.dtb \
+	bcm958625-meraki-mx64w-a0.dtb \
 	bcm958625hr.dtb \
 	bcm988312hr.dtb \
 	bcm958625k.dtb
diff --git a/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
new file mode 100644
index 000000000000..7c487c74fd10
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Device Tree Bindings for Cisco Meraki MX64 series (Kingpin).
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+#include "bcm958625-meraki-mx6x-common.dtsi"
+
+/ {
+
+	keys {
+		compatible = "gpio-keys-polled";
+		autorepeat;
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			linux,code = <KEY_RESTART>;
+			gpios = <&gpioa 6 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			/* green:lan1-left */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <0>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 19 GPIO_ACTIVE_LOW>;
+		};
+
+		led-1 {
+			/* green:lan1-right */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <1>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 18 GPIO_ACTIVE_LOW>;
+		};
+
+		led-2 {
+			/* green:lan2-left */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <2>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 24 GPIO_ACTIVE_LOW>;
+		};
+
+		led-3 {
+			/* green:lan2-right */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <3>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 20 GPIO_ACTIVE_LOW>;
+		};
+
+		led-4 {
+			/* green:lan3-left */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <4>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 26 GPIO_ACTIVE_LOW>;
+		};
+
+		led-5 {
+			/* green:lan3-right */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <5>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 25 GPIO_ACTIVE_LOW>;
+		};
+
+		led-6 {
+			/* green:lan4-left */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <6>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 28 GPIO_ACTIVE_LOW>;
+		};
+
+		led-7 {
+			/* green:lan4-right */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <7>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 27 GPIO_ACTIVE_LOW>;
+		};
+
+		led-8 {
+			/* green:wan-left */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <8>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 30 GPIO_ACTIVE_LOW>;
+		};
+
+		led-9 {
+			/* green:wan-right */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <9>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 29 GPIO_ACTIVE_LOW>;
+		};
+
+		led-a {
+			/* amber:power */
+			function = LED_FUNCTION_POWER;
+			color = <LED_COLOR_ID_AMBER>;
+			gpios = <&gpioa 0 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		led-b {
+			/* white:status */
+			function = LED_FUNCTION_STATUS;
+			color = <LED_COLOR_ID_WHITE>;
+			gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&srab {
+	compatible = "brcm,bcm58625-srab", "brcm,nsp-srab";
+	status = "okay";
+
+	ports {
+		port at 0 {
+			label = "lan1";
+			reg = <0>;
+		};
+
+		port at 1 {
+			label = "lan2";
+			reg = <1>;
+		};
+
+		port at 2 {
+			label = "lan3";
+			reg = <2>;
+		};
+
+		port at 3 {
+			label = "lan4";
+			reg = <3>;
+		};
+
+		port at 4 {
+			label = "wan";
+			reg = <4>;
+		};
+
+		port at 8 {
+			ethernet = <&amac2>;
+			reg = <8>;
+			fixed-link {
+				speed = <1000>;
+				full-duplex;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts b/arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts
new file mode 100644
index 000000000000..9944566c1195
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Device Tree Bindings for Cisco Meraki MX64 with A0 SoC.
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm958625-meraki-kingpin.dtsi"
+#include "bcm-nsp-ax.dtsi"
+
+/ {
+	model = "Cisco Meraki MX64(A0)";
+	compatible = "meraki,mx64-a0", "brcm,bcm58625", "brcm,nsp";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x80000000>;
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx64.dts b/arch/arm/boot/dts/bcm958625-meraki-mx64.dts
new file mode 100644
index 000000000000..06939438e874
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Device Tree Bindings for Cisco Meraki MX64 with B0+ SoC.
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm958625-meraki-kingpin.dtsi"
+
+/ {
+	model = "Cisco Meraki MX64";
+	compatible = "meraki,mx64", "brcm,bcm58625", "brcm,nsp";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x80000000>;
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts b/arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts
new file mode 100644
index 000000000000..112fddb1eed8
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Device Tree Bindings for Cisco Meraki MX64W with A0 SoC.
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm958625-meraki-kingpin.dtsi"
+#include "bcm-nsp-ax.dtsi"
+
+/ {
+	model = "Cisco Meraki MX64W(A0)";
+	compatible = "meraki,mx64w-a0", "brcm,bcm58625", "brcm,nsp";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x80000000>;
+	};
+};
+
+&pcie0 {
+	status = "okay";
+};
+
+&pcie1 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx64w.dts b/arch/arm/boot/dts/bcm958625-meraki-mx64w.dts
new file mode 100644
index 000000000000..de2e367c3e78
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64w.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Device Tree Bindings for Cisco Meraki MX64W with B0+ SoC.
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm958625-meraki-kingpin.dtsi"
+
+/ {
+	model = "Cisco Meraki MX64W";
+	compatible = "meraki,mx64w", "brcm,bcm58625", "brcm,nsp";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x80000000>;
+	};
+};
+
+&pcie0 {
+	status = "okay";
+};
+
+&pcie1 {
+	status = "okay";
+};
-- 
2.26.3



From mnhagan88 at gmail.com  Fri Aug  6 13:44:35 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Fri,  6 Aug 2021 21:44:35 +0100
Subject: [PATCH v5 4/5] ARM: dts: NSP: Add DT files for Meraki MX65 series
In-Reply-To: <20210806204446.2981299-1-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
Message-ID: <20210806204446.2981299-5-mnhagan88@gmail.com>

MX65 & MX65W Hardware info:
  - CPU: Broadcom BCM58625 Cortex A9 @ 1200Mhz
  - RAM: 2 GB (4 x 4Gb SK Hynix H5TC4G83CFR)
  - Storage: 1 GB (Micron MT29F8G08ABACA)
  - Networking: BCM58625 switch (2x 1GbE ports)
    2x Qualcomm QCA8337 switches (10x 1GbE ports total)
  - PSE: Broadcom BCM59111KMLG connected to LAN ports 11 & 12
  - USB: 1x USB2.0
  - Serial: Internal header
  - WLAN(MX65W Only): 2x Broadcom BCM43520KMLG on the PCI bus.

Note that a driver and firmware image for the BCM59111 PSE has been
released under GPL, but this is not present in the kernel.

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/Makefile                    |   2 +
 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 279 ++++++++++++++++++
 arch/arm/boot/dts/bcm958625-meraki-mx65.dts   |  24 ++
 arch/arm/boot/dts/bcm958625-meraki-mx65w.dts  |  32 ++
 4 files changed, 337 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx65.dts
 create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx65w.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 17f7bdab50ef..3586b540e3b6 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -159,6 +159,8 @@ dtb-$(CONFIG_ARCH_BCM_NSP) += \
 	bcm958625-meraki-mx64-a0.dtb \
 	bcm958625-meraki-mx64w.dtb \
 	bcm958625-meraki-mx64w-a0.dtb \
+	bcm958625-meraki-mx65.dtb \
+	bcm958625-meraki-mx65w.dtb \
 	bcm958625hr.dtb \
 	bcm988312hr.dtb \
 	bcm958625k.dtb
diff --git a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
new file mode 100644
index 000000000000..8860f2fefc63
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Device Tree Bindings for Cisco Meraki MX65 series (Alamo).
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+#include "bcm958625-meraki-mx6x-common.dtsi"
+
+/ {
+	keys {
+		compatible = "gpio-keys-polled";
+		autorepeat;
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			linux,code = <KEY_RESTART>;
+			gpios = <&gpioa 8 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			/* green:wan1-left */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <0>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 25 GPIO_ACTIVE_LOW>;
+		};
+
+		led-1 {
+			/* green:wan1-right */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <1>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 24 GPIO_ACTIVE_LOW>;
+		};
+
+		led-2 {
+			/* green:wan2-left */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <2>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 27 GPIO_ACTIVE_LOW>;
+		};
+
+		led-3 {
+			/* green:wan2-right */
+			function = LED_FUNCTION_ACTIVITY;
+			function-enumerator = <3>;
+			color = <LED_COLOR_ID_GREEN>;
+			gpios = <&gpioa 26 GPIO_ACTIVE_LOW>;
+		};
+
+		led-4 {
+			/* amber:power */
+			function = LED_FUNCTION_POWER;
+			color = <LED_COLOR_ID_AMBER>;
+			gpios = <&gpioa 3 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		led-5 {
+			/* white:status */
+			function = LED_FUNCTION_STATUS;
+			color = <LED_COLOR_ID_WHITE>;
+			gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	mdio-mii-mux {
+		compatible = "mdio-mux-mmioreg";
+		reg = <0x1803f1c0 0x4>;
+		mux-mask = <0x2000>;
+		mdio-parent-bus = <&mdio_ext>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mdio at 0 {
+			reg = <0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			phy_port6: phy at 0 {
+				reg = <0>;
+			};
+
+			phy_port7: phy at 1 {
+				reg = <1>;
+			};
+
+			phy_port8: phy at 2 {
+				reg = <2>;
+			};
+
+			phy_port9: phy at 3 {
+				reg = <3>;
+			};
+
+			phy_port10: phy at 4 {
+				reg = <4>;
+			};
+
+			switch at 10 {
+				compatible = "qca,qca8337";
+				reg = <0x10>;
+				dsa,member = <1 0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					port at 0 {
+						reg = <0>;
+						ethernet = <&sgmii1>;
+						phy-mode = "sgmii";
+						fixed-link {
+							speed = <1000>;
+							full-duplex;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						label = "lan8";
+						phy-handle = <&phy_port6>;
+					};
+
+					port at 2 {
+						reg = <2>;
+						label = "lan9";
+						phy-handle = <&phy_port7>;
+					};
+
+					port at 3 {
+						reg = <3>;
+						label = "lan10";
+						phy-handle = <&phy_port8>;
+					};
+
+					port at 4 {
+						reg = <4>;
+						label = "lan11";
+						phy-handle = <&phy_port9>;
+					};
+
+					port at 5 {
+						reg = <5>;
+						label = "lan12";
+						phy-handle = <&phy_port10>;
+					};
+				};
+			};
+		};
+
+		mdio-mii at 2000 {
+			reg = <0x2000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			phy_port1: phy at 0 {
+				reg = <0>;
+			};
+
+			phy_port2: phy at 1 {
+				reg = <1>;
+			};
+
+			phy_port3: phy at 2 {
+				reg = <2>;
+			};
+
+			phy_port4: phy at 3 {
+				reg = <3>;
+			};
+
+			phy_port5: phy at 4 {
+				reg = <4>;
+			};
+
+			switch at 10 {
+				compatible = "qca,qca8337";
+				reg = <0x10>;
+				dsa,member = <2 0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					port at 0 {
+						reg = <0>;
+						ethernet = <&sgmii0>;
+						phy-mode = "sgmii";
+						fixed-link {
+							speed = <1000>;
+							full-duplex;
+						};
+					};
+
+					port at 1 {
+						reg = <1>;
+						label = "lan3";
+						phy-handle = <&phy_port1>;
+					};
+
+					port at 2 {
+						reg = <2>;
+						label = "lan4";
+						phy-handle = <&phy_port2>;
+					};
+
+					port at 3 {
+						reg = <3>;
+						label = "lan5";
+						phy-handle = <&phy_port3>;
+					};
+
+					port at 4 {
+						reg = <4>;
+						label = "lan6";
+						phy-handle = <&phy_port4>;
+					};
+
+					port at 5 {
+						reg = <5>;
+						label = "lan7";
+						phy-handle = <&phy_port5>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&srab {
+	compatible = "brcm,bcm58625-srab", "brcm,nsp-srab";
+	status = "okay";
+	dsa,member = <0 0>;
+
+	ports {
+		port at 0 {
+			label = "wan1";
+			reg = <0>;
+		};
+
+		port at 1 {
+			label = "wan2";
+			reg = <1>;
+		};
+
+		sgmii0: port at 4 {
+			label = "sw0";
+			reg = <4>;
+			fixed-link {
+				speed = <1000>;
+				full-duplex;
+			};
+		};
+
+		sgmii1: port at 5 {
+			label = "sw1";
+			reg = <5>;
+			fixed-link {
+				speed = <1000>;
+				full-duplex;
+			};
+		};
+
+		port at 8 {
+			ethernet = <&amac2>;
+			reg = <8>;
+			fixed-link {
+				speed = <1000>;
+				full-duplex;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx65.dts b/arch/arm/boot/dts/bcm958625-meraki-mx65.dts
new file mode 100644
index 000000000000..d1b684dcdbfa
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx65.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Device Tree Bindings for Cisco Meraki MX65.
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm958625-meraki-alamo.dtsi"
+
+/ {
+	model = "Cisco Meraki MX65";
+	compatible = "meraki,mx65", "brcm,bcm58625", "brcm,nsp";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x80000000>;
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx65w.dts b/arch/arm/boot/dts/bcm958625-meraki-mx65w.dts
new file mode 100644
index 000000000000..a2165aba3676
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx65w.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Device Tree Bindings for Cisco Meraki MX65W.
+ *
+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88 at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm958625-meraki-alamo.dtsi"
+
+/ {
+	model = "Cisco Meraki MX65W";
+	compatible = "meraki,mx65w", "brcm,bcm58625", "brcm,nsp";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x80000000>;
+	};
+};
+
+&pcie0 {
+	status = "okay";
+};
+
+&pcie1 {
+	status = "okay";
+};
-- 
2.26.3



From mnhagan88 at gmail.com  Fri Aug  6 13:44:36 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Fri,  6 Aug 2021 21:44:36 +0100
Subject: [PATCH v5 5/5] dt-bindings: arm: bcm: NSP: add Meraki MX64/MX65
In-Reply-To: <20210806204446.2981299-1-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
Message-ID: <20210806204446.2981299-6-mnhagan88@gmail.com>

Add bindings for the Meraki MX64/MX65 series.

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml b/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml
index 78dfa315f3d0..7d184ba7d180 100644
--- a/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml
+++ b/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml
@@ -62,6 +62,12 @@ properties:
           - enum:
               - brcm,bcm958625hr
               - brcm,bcm958625k
+              - meraki,mx64
+              - meraki,mx64-a0
+              - meraki,mx64w
+              - meraki,mx64w-a0
+              - meraki,mx65
+              - meraki,mx65w
           - const: brcm,bcm58625
           - const: brcm,nsp
 
-- 
2.26.3



From robh at kernel.org  Fri Aug  6 13:52:41 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 14:52:41 -0600
Subject: [PATCH 3/5] ARM: dts: Add basic support for EcoNet EN7523
In-Reply-To: <20210730145901.GC19569@C02TD0UTHF1T.local>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-4-bert@biot.com>
 <20210730145901.GC19569@C02TD0UTHF1T.local>
Message-ID: <YQ2hGd1cERLbfjJ6@robh.at.kernel.org>

On Fri, Jul 30, 2021 at 03:59:01PM +0100, Mark Rutland wrote:
> On Fri, Jul 30, 2021 at 03:45:50PM +0200, Bert Vermeulen wrote:
> > From: John Crispin <john at phrozen.org>
> > 
> > Add basic support for EcoNet EN7523, enough for booting to console.
> > 
> > The UART is basically 8250-compatible, except for the clock selection.
> > A clock-frequency value is synthesized to get this to run at 115200 bps.
> > 
> > Signed-off-by: John Crispin <john at phrozen.org>
> > Signed-off-by: Bert Vermeulen <bert at biot.com>
> > ---
> >  arch/arm/boot/dts/Makefile       |   2 +
> >  arch/arm/boot/dts/en7523-evb.dts |  17 ++++
> >  arch/arm/boot/dts/en7523.dtsi    | 128 +++++++++++++++++++++++++++++++
> >  3 files changed, 147 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/en7523-evb.dts
> >  create mode 100644 arch/arm/boot/dts/en7523.dtsi
> > 
> 
> > +	cpus {
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> 
> > +		cpu0: cpu at 0 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x0>;
> > +			enable-method = "psci";
> > +			clock-frequency = <80000000>;
> > +			next-level-cache = <&L2_0>;
> > +
> > +		};
> 
> > +	gic: interrupt-controller at 09000000 {
> > +		compatible = "arm,gic-v3";
> > +		interrupt-controller;
> > +		#interrupt-cells = <3>;
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		reg = <0x09000000 0x20000>,
> > +			  <0x09080000 0x80000>;
> > +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
> > +
> > +		its: gic-its at 09020000 {
> > +			compatible = "arm,gic-v3-its";
> > +			msi-controller;
> > +			#msi-cell = <1>;
> 
> Missing 's' here for '#msi-cells'.

No need for a human to be checking this, the DT schemas will check this. 
Please run 'make dtbs_checks' on this. New platforms should be free of 
warnings ideally.

Rob


From robh at kernel.org  Fri Aug  6 13:59:44 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 14:59:44 -0600
Subject: [PATCH 3/5] ARM: dts: Add basic support for EcoNet EN7523
In-Reply-To: <d0ff051b-280c-4021-f4ee-7bfda5e356d3@biot.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-4-bert@biot.com>
 <20210730144627.GB19569@C02TD0UTHF1T.local>
 <d0ff051b-280c-4021-f4ee-7bfda5e356d3@biot.com>
Message-ID: <YQ2iwIcSuDwcw/s5@robh.at.kernel.org>

On Wed, Aug 04, 2021 at 06:41:55PM +0200, Bert Vermeulen wrote:
> On 7/30/21 4:46 PM, Mark Rutland wrote:
> > On Fri, Jul 30, 2021 at 03:45:50PM +0200, Bert Vermeulen wrote:
> > > +	timer {
> > > +		compatible = "arm,armv8-timer";
> > 
> > This should be "arm,armv7-timer".
> > 
> > > +		interrupt-parent = <&gic>;
> > > +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> > > +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> > > +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> > > +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> > 
> > GICv3 doesn't have a cpumask in its PPI description, so the
> > GIC_CPU_MASK_SIMPLE() bits should be removed.
> 
> Ok, will fix.
> 
> > > +		clock-frequency = <25000000>;
> > 
> > Please have your FW configure CNTFRQ on each CPU; the clock-frequency
> > property in the DT is a workaround for broken FW, and it's *vastly*
> > preferable for FW to configure this correctly (e.g. as it means VMs
> > should "just work").
> 
> I've since got hold of the modified U-Boot that runs on my eval board, and
> indeed it doesn't set CNTFRQ. So the kernel does need this, for the moment.

Can't you write CNTFRQ in the u-boot shell/script?

> I may get a chance to upstream support for this SoC in U-Boot, but I can't
> control what people are going to ship with their board. Is it ok to leave
> this in?

If they want a working upstream Linux, then you can control it.

I seem to recall this being rejected in other cases. That may have been 
on v8 which has taken stricter stances (but arguably any new v7 stuff 
should too).

Rob


From robh at kernel.org  Fri Aug  6 14:02:58 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:02:58 -0600
Subject: [PATCH 1/5] dt-bindings: Add vendor prefix for EcoNet
In-Reply-To: <20210730134552.853350-2-bert@biot.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-2-bert@biot.com>
Message-ID: <YQ2jgnAvtMNyx2c/@robh.at.kernel.org>

On Fri, 30 Jul 2021 15:45:48 +0200, Bert Vermeulen wrote:
> From: John Crispin <john at phrozen.org>
> 
> Add vendor prefix "econet" for EcoNet.
> 
> Signed-off-by: John Crispin <john at phrozen.org>
> Signed-off-by: Bert Vermeulen <bert at biot.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

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


From robh at kernel.org  Fri Aug  6 14:04:41 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:04:41 -0600
Subject: [PATCH 2/5] dt-bindings: arm: econet: Add binding for EN7523 SoC
 and EVB
In-Reply-To: <20210730134552.853350-3-bert@biot.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-3-bert@biot.com>
Message-ID: <YQ2j6fOetplrlMnj@robh.at.kernel.org>

On Fri, Jul 30, 2021 at 03:45:49PM +0200, Bert Vermeulen wrote:
> From: John Crispin <john at phrozen.org>
> 
> Add devicetree binding for Econet EN7523 SoC and evaluation board.
> 
> Signed-off-by: John Crispin <john at phrozen.org>
> Signed-off-by: Bert Vermeulen <bert at biot.com>
> ---
>  .../devicetree/bindings/arm/econet.yaml       | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/econet.yaml
> 
> diff --git a/Documentation/devicetree/bindings/arm/econet.yaml b/Documentation/devicetree/bindings/arm/econet.yaml
> new file mode 100644
> index 000000000000..39128f959fef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/econet.yaml
> @@ -0,0 +1,27 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/arm/econet.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: EcoNet SoC based Platforms Device Tree Bindings
> +
> +maintainers:
> +  - Felix Fietkau <nbd at nbd.name>
> +  - John Crispin <john at phrozen.org>

Blank line

> +description: |

Don't need '|' if no formatting to maintain.

> +  Boards with an EcoNet SoC shall have the following properties.
> +
> +properties:
> +  $nodename:
> +    const: '/'
> +  compatible:
> +    oneOf:

Expecting other SoCs soonish? If not, drop 'oneOf'.

> +      - items:
> +          - enum:
> +              - econet,en7523-evb
> +          - const: econet,en7523
> +
> +additionalProperties: true
> +
> +...
> -- 
> 2.25.1
> 
> 


From robh at kernel.org  Fri Aug  6 14:11:45 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:11:45 -0600
Subject: [PATCH 4/9] dt-bindings: display: bcm2835: add optional property
 power-domains
In-Reply-To: <1627820932-7247-5-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
 <1627820932-7247-5-git-send-email-stefan.wahren@i2se.com>
Message-ID: <YQ2lkWoeq9D/yOc6@robh.at.kernel.org>

On Sun, Aug 01, 2021 at 02:28:47PM +0200, Stefan Wahren wrote:
> The Raspberry Pi boards with BCM283x needs control of the power domains
> to get display components running. So add this as an optional property
> in order to avoid such DT schema warnings:
> 
> hdmi at 7e902000: 'power-domains' does not match any of the regexes: ...

You're adding it because it is in use but failed to be documented, not 
to avoid warnings. The warning is just the symptom of that.

> 
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> ---
>  Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml | 3 +++
>  Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml | 3 +++
>  Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml  | 3 +++
>  Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml  | 3 +++
>  4 files changed, 12 insertions(+)

In any case,

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


From robh at kernel.org  Fri Aug  6 14:12:16 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:12:16 -0600
Subject: [PATCH 6/9] dt-bindings: arm: bcm2835: Add Raspberry Pi Compute
 Module 4
In-Reply-To: <1627820932-7247-7-git-send-email-stefan.wahren@i2se.com>
References: <1627820932-7247-1-git-send-email-stefan.wahren@i2se.com>
 <1627820932-7247-7-git-send-email-stefan.wahren@i2se.com>
Message-ID: <YQ2lsAbidGvP3Lub@robh.at.kernel.org>

On Sun, 01 Aug 2021 14:28:49 +0200, Stefan Wahren wrote:
> Add the Raspberry Pi Compute Module 4 to DT schema.
> 
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> ---
>  Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From sebastian.reichel at collabora.com  Fri Aug  6 14:33:43 2021
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 6 Aug 2021 23:33:43 +0200
Subject: [PATCH 28/54] dt-bindings: power: supply: axp20x: Add AXP803
 compatible
In-Reply-To: <20210721140424.725744-29-maxime@cerno.tech>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-29-maxime@cerno.tech>
Message-ID: <20210806213343.ha2jvludgengcp2m@earth.universe>

Hi,

On Wed, Jul 21, 2021 at 04:03:58PM +0200, Maxime Ripard wrote:
> The AXP803 compatible was introduced recently with a fallback to the
> AXP813, but it was never documented.
> 
> Cc: Chen-Yu Tsai <wens at csie.org>
> Cc: linux-pm at vger.kernel.org
> Cc: Sebastian Reichel <sre at kernel.org>
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> ---

Thanks, queued.

-- Sebastian

>  .../supply/x-powers,axp20x-ac-power-supply.yaml    | 11 +++++++----
>  .../x-powers,axp20x-battery-power-supply.yaml      | 11 +++++++----
>  .../supply/x-powers,axp20x-usb-power-supply.yaml   | 14 +++++++++-----
>  3 files changed, 23 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-ac-power-supply.yaml b/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-ac-power-supply.yaml
> index dcda6660b8ed..de6a23aee977 100644
> --- a/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-ac-power-supply.yaml
> +++ b/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-ac-power-supply.yaml
> @@ -21,10 +21,13 @@ allOf:
>  
>  properties:
>    compatible:
> -    enum:
> -      - x-powers,axp202-ac-power-supply
> -      - x-powers,axp221-ac-power-supply
> -      - x-powers,axp813-ac-power-supply
> +    oneOf:
> +      - const: x-powers,axp202-ac-power-supply
> +      - const: x-powers,axp221-ac-power-supply
> +      - items:
> +          - const: x-powers,axp803-ac-power-supply
> +          - const: x-powers,axp813-ac-power-supply
> +      - const: x-powers,axp813-ac-power-supply
>  
>  required:
>    - compatible
> diff --git a/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml b/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml
> index 86e8a713d4e2..d1f0df123a5a 100644
> --- a/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml
> +++ b/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml
> @@ -19,10 +19,13 @@ allOf:
>  
>  properties:
>    compatible:
> -    enum:
> -      - x-powers,axp209-battery-power-supply
> -      - x-powers,axp221-battery-power-supply
> -      - x-powers,axp813-battery-power-supply
> +    oneOf:
> +      - const: x-powers,axp202-battery-power-supply
> +      - const: x-powers,axp221-battery-power-supply
> +      - items:
> +          - const: x-powers,axp803-battery-power-supply
> +          - const: x-powers,axp813-battery-power-supply
> +      - const: x-powers,axp813-battery-power-supply
>  
>  required:
>    - compatible
> diff --git a/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-usb-power-supply.yaml b/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-usb-power-supply.yaml
> index 61f1b320c157..0c371b55c9e1 100644
> --- a/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-usb-power-supply.yaml
> +++ b/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-usb-power-supply.yaml
> @@ -20,11 +20,15 @@ allOf:
>  
>  properties:
>    compatible:
> -    enum:
> -      - x-powers,axp202-usb-power-supply
> -      - x-powers,axp221-usb-power-supply
> -      - x-powers,axp223-usb-power-supply
> -      - x-powers,axp813-usb-power-supply
> +    oneOf:
> +      - enum:
> +          - x-powers,axp202-usb-power-supply
> +          - x-powers,axp221-usb-power-supply
> +          - x-powers,axp223-usb-power-supply
> +          - x-powers,axp813-usb-power-supply
> +      - items:
> +          - const: x-powers,axp803-usb-power-supply
> +          - const: x-powers,axp813-usb-power-supply
>  
>  
>  required:
> -- 
> 2.31.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210806/ad29ef39/attachment.sig>

From sebastian.reichel at collabora.com  Fri Aug  6 14:34:02 2021
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 6 Aug 2021 23:34:02 +0200
Subject: [PATCH 29/54] dt-bindings: power: supply: axp20x-battery: Add
 AXP209 compatible
In-Reply-To: <20210721140424.725744-30-maxime@cerno.tech>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-30-maxime@cerno.tech>
Message-ID: <20210806213402.xvp7oucjio7xmq6c@earth.universe>

Hi,

On Wed, Jul 21, 2021 at 04:03:59PM +0200, Maxime Ripard wrote:
> The AXP209 compatible was used in Device Trees and the driver, but it
> was never documented.
> 
> Cc: Chen-Yu Tsai <wens at csie.org>
> Cc: linux-pm at vger.kernel.org
> Cc: Sebastian Reichel <sre at kernel.org>
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> ---

Thanks, queued.

-- Sebastian

>  .../power/supply/x-powers,axp20x-battery-power-supply.yaml       | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml b/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml
> index d1f0df123a5a..d055428ae39f 100644
> --- a/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml
> +++ b/Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml
> @@ -21,6 +21,7 @@ properties:
>    compatible:
>      oneOf:
>        - const: x-powers,axp202-battery-power-supply
> +      - const: x-powers,axp209-battery-power-supply
>        - const: x-powers,axp221-battery-power-supply
>        - items:
>            - const: x-powers,axp803-battery-power-supply
> -- 
> 2.31.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210806/e1b584ba/attachment.sig>

From robh at kernel.org  Fri Aug  6 14:37:13 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:37:13 -0600
Subject: [PATCH v2 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC
 devicetree bindings documentation
In-Reply-To: <20210801160921.233081-2-romain.perier@gmail.com>
References: <20210801160921.233081-1-romain.perier@gmail.com>
 <20210801160921.233081-2-romain.perier@gmail.com>
Message-ID: <YQ2riRW1hZmn6x4B@robh.at.kernel.org>

On Sun, Aug 01, 2021 at 06:09:19PM +0200, Romain Perier wrote:
> This adds the documentation for the devicetree bindings of the Mstar
> MSC313e RTC driver, found from MSC313e SoCs and newer.
> 
> Signed-off-by: Romain Perier <romain.perier at gmail.com>
> ---
>  .../bindings/rtc/mstar,msc313-rtc.yaml        | 49 +++++++++++++++++++
>  1 file changed, 49 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> new file mode 100644
> index 000000000000..62bc12b1feb6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> @@ -0,0 +1,49 @@
> +# SPDX-License-Identifier: GPL-2.0

As checkpatch.pl will tell you, should be dual licensed.

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/rtc/mstar,msc313-rtc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mstar MSC313e RTC Device Tree Bindings
> +
> +allOf:
> +  - $ref: "rtc.yaml#"
> +
> +maintainers:
> +  - Daniel Palmer <daniel at 0x0f.com>
> +  - Romain Perier <romain.perier at gmail.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - mstar,msc313-rtc
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  start-year: true
> +
> +  clocks:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    rtc at 2400 {
> +        compatible = "mstar,msc313-rtc";
> +        reg = <0x2400 0x40>;
> +        clocks = <&xtal_div2>;
> +        interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
> +    };
> +...
> -- 
> 2.30.2
> 
> 


From robh at kernel.org  Fri Aug  6 14:39:01 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:39:01 -0600
Subject: [PATCH v5 1/2] dt-bindings: drm/bridge: anx7625: add
 force_dsi_end_without_null
In-Reply-To: <20210802010711.169080-2-jitao.shi@mediatek.com>
References: <20210802010711.169080-1-jitao.shi@mediatek.com>
 <20210802010711.169080-2-jitao.shi@mediatek.com>
Message-ID: <YQ2r9ZJHLdiN5/BZ@robh.at.kernel.org>

On Mon, Aug 02, 2021 at 09:07:10AM +0800, Jitao Shi wrote:
> The force_dsi_end_without_null requires the dsi host ent at
> the same time in line.
> 
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> ---
>  .../bindings/display/bridge/analogix,anx7625.yaml           | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> index ab48ab2f4240..8b868a6a3d60 100644
> --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml
> @@ -43,6 +43,11 @@ properties:
>    vdd33-supply:
>      description: Regulator that provides the supply 3.3V power.
>  
> +  force_dsi_end_without_null:
> +    description: |
> +      Requires the dsi host send the dsi packets on all lanes aligned
> +      at the end.

Can't this be implied from the compatible string if it is a property of 
this chip? 



From robh at kernel.org  Fri Aug  6 14:39:36 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:39:36 -0600
Subject: [PATCH 04/17] dt-bindings: rtc: sun6i: add compatible string for
 R329 RTC
In-Reply-To: <20210802062212.73220-5-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-5-icenowy@sipeed.com>
Message-ID: <YQ2sGGFqmDLroBtI@robh.at.kernel.org>

On Mon, 02 Aug 2021 14:21:59 +0800, Icenowy Zheng wrote:
> Allwinner R329 has a RTC similar to previous ones, capable of
> controlling LOSC and IOSC and with only one alarm.
> 
> Add a compatible string for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  .../devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml    | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 

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


From robh at kernel.org  Fri Aug  6 14:40:43 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:40:43 -0600
Subject: [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO
 and R-PIO
In-Reply-To: <20210802062212.73220-7-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-7-icenowy@sipeed.com>
Message-ID: <YQ2sW6ulsvlPluMC@robh.at.kernel.org>

On Mon, 02 Aug 2021 14:22:01 +0800, Icenowy Zheng wrote:
> Allwinner R329 have two pin controllers similar to previous Allwinner
> SoCs, PIO and R-PIO.
> 
> Add compatible strings for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  .../bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml         | 4 ++++
>  1 file changed, 4 insertions(+)
> 

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


From robh at kernel.org  Fri Aug  6 14:41:03 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:41:03 -0600
Subject: [PATCH 09/17] dt-bindings: clock: sunxi-ng: add compatibles for
 R329 CCUs
In-Reply-To: <20210802062212.73220-10-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-10-icenowy@sipeed.com>
Message-ID: <YQ2sbzC7ZzxUsktv@robh.at.kernel.org>

On Mon, 02 Aug 2021 14:22:04 +0800, Icenowy Zheng wrote:
> R329 has a CPUX CCU and a R-CCU.
> 
> Add compatible strings for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  .../devicetree/bindings/clock/allwinner,sun4i-a10-ccu.yaml    | 4 ++++
>  1 file changed, 4 insertions(+)
> 

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


From robh at kernel.org  Fri Aug  6 14:42:02 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:42:02 -0600
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <20210802062212.73220-11-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-11-icenowy@sipeed.com>
Message-ID: <YQ2sqouVblVWMbye@robh.at.kernel.org>

On Mon, Aug 02, 2021 at 02:22:05PM +0800, Icenowy Zheng wrote:
> Allwinner R329 has clock controls in PRCM, like other new Allwinner
> SoCs.
> 
> Add support for them.
> 
> This driver is added before the main CCU because PLLs are controlled by
> R-CCU on R329.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig                  |   5 +
>  drivers/clk/sunxi-ng/Makefile                 |   1 +
>  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 ++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
>  include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
>  include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 ++

These 2 belong in the binding patch.

>  6 files changed, 470 insertions(+)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
>  create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h


From robh at kernel.org  Fri Aug  6 14:42:31 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:42:31 -0600
Subject: [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
In-Reply-To: <20210802062212.73220-12-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-12-icenowy@sipeed.com>
Message-ID: <YQ2sxynJYuMEBNRD@robh.at.kernel.org>

On Mon, Aug 02, 2021 at 02:22:06PM +0800, Icenowy Zheng wrote:
> Allwinner R329 has a CCU that is similar to the H616 one, but it's cut
> down and have PLLs moved out.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig                |   5 +
>  drivers/clk/sunxi-ng/Makefile               |   1 +
>  drivers/clk/sunxi-ng/ccu-sun50i-r329.c      | 526 ++++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-r329.h      |  32 ++
>  include/dt-bindings/clock/sun50i-r329-ccu.h |  73 +++
>  include/dt-bindings/reset/sun50i-r329-ccu.h |  45 ++

Same here.

>  6 files changed, 682 insertions(+)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
>  create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h


From robh at kernel.org  Fri Aug  6 14:42:46 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:42:46 -0600
Subject: [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC
 compatible string
In-Reply-To: <20210802062212.73220-13-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-13-icenowy@sipeed.com>
Message-ID: <YQ2s1gUHJJjaizsC@robh.at.kernel.org>

On Mon, 02 Aug 2021 14:22:07 +0800, Icenowy Zheng wrote:
> R329 SoC has two MMC controllers similar to ones in the previous
> Allwinner SoCs. However, as R329 has no eMMC controller, the two MMC
> controllers look like a mixture of previous SoCs' ordinary MMC
> controller and eMMC controller.
> 
> Add a compatible string for R329 MMC controllers.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  .../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml         | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From robh at kernel.org  Fri Aug  6 14:43:11 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:43:11 -0600
Subject: [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings
 for Sipeed MaixSense
In-Reply-To: <20210802062212.73220-15-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-15-icenowy@sipeed.com>
Message-ID: <YQ2s762cl83X7go1@robh.at.kernel.org>

On Mon, 02 Aug 2021 14:22:09 +0800, Icenowy Zheng wrote:
> Sipeed MaixSense is an Allwinner R329 development kit based on Maix IIA
> SoM.
> 
> Add compatible strings for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

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


From robh at kernel.org  Fri Aug  6 14:47:28 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 6 Aug 2021 15:47:28 -0600
Subject: [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement
 from mtk-mdp
In-Reply-To: <20210802220943.v6.9.If10dbdfade9f48710e485efe79e53e6e65144a2f@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.9.If10dbdfade9f48710e485efe79e53e6e65144a2f@changeid>
Message-ID: <YQ2t8DMqz/Ju1Qng@robh.at.kernel.org>

On Mon, 02 Aug 2021 22:12:15 +1000, Eizan Miyamoto wrote:
> It is no longer needed by the mtk-mdp driver
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
> 
> (no changes since v1)
> 
>  Documentation/devicetree/bindings/media/mediatek-mdp.txt | 3 ---
>  1 file changed, 3 deletions(-)
> 

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


From helgaas at kernel.org  Fri Aug  6 15:12:56 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 6 Aug 2021 17:12:56 -0500
Subject: [PATCH 3/3] PCI/ACPI: Add new quirk detection, enable bcm2711
In-Reply-To: <20210805211200.491275-4-jeremy.linton@arm.com>
Message-ID: <20210806221256.GA1891371@bjorn-Precision-5520>

In subject, this or similar would match history:

  PCI/ACPI: Add Broadcom bcm2711 MCFG quirk

On Thu, Aug 05, 2021 at 04:12:00PM -0500, Jeremy Linton wrote:
> Now that we have a bcm2711 quirk, we need to be able to
> detect it when the MCFG is missing. Use a namespace
> property as an alternative to the MCFG OEM.

Rewrap to use ~75 columns.

Mention the DT namespace property here.

> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  drivers/acpi/pci_mcfg.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
> index 53cab975f612..7d77fc72c2a4 100644
> --- a/drivers/acpi/pci_mcfg.c
> +++ b/drivers/acpi/pci_mcfg.c
> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>  	ALTRA_ECAM_QUIRK(1, 13),
>  	ALTRA_ECAM_QUIRK(1, 14),
>  	ALTRA_ECAM_QUIRK(1, 15),
> +
> +	{ "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
> +	  DEFINE_RES_MEM(0xFD500000, 0xA000) },
>  };
>  
>  static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
> @@ -198,8 +201,19 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
>  	u16 segment = root->segment;
>  	struct resource *bus_range = &root->secondary;
>  	struct mcfg_fixup *f;
> +	const char *soc;
>  	int i;
>  
> +	/*
> +	 * This could be a machine with a PCI/SMC conduit,
> +	 * which means it doens't have MCFG. Get the machineid from
> +	 * the namespace definition instead.

s/SMC/SMCCC/ ?  Cover letter uses SMCCC (not sure it's relevant anyway)
s/doens't/doesn't/

Rewrap comment to use ~80 columns.

Seems pretty reasonable that a platform without standard ECAM might
not have MCFG, since MCFG basically implies ECAM.

Is "linux,pcie-quirk" the right property to look for?  It doesn't
sound very generic, and it doesn't sound like anything related to
ECAM.  Is it new?  I don't see it in the tree yet.  Should it be in
Documentation/devicetree/bindings/pci/pci.txt so we don't get a
different property name for every new platform?

> +	 */
> +	if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
> +					 "linux,pcie-quirk", &soc)) {
> +		memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
> +	}
> +
>  	for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
>  		if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
>  			if (f->cfgres.start)
> -- 
> 2.31.1
> 


From helgaas at kernel.org  Fri Aug  6 15:21:51 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 6 Aug 2021 17:21:51 -0500
Subject: [PATCH 2/3] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210805211200.491275-3-jeremy.linton@arm.com>
Message-ID: <20210806222151.GA1892781@bjorn-Precision-5520>

On Thu, Aug 05, 2021 at 04:11:59PM -0500, Jeremy Linton wrote:
> The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
> standard because its PCIe config space isn't ECAM compliant and is
> split into two parts. One part for the root port registers and a
> moveable window which points at a given device's 4K config space.
> Thus it doesn't have a MCFG (and really any MCFG provided would be
> nonsense anyway). As Linux doesn't support the PCIe SMCCC standard
> we key off a Linux specific host bridge _DSD to add custom ECAM
> ops and cfgres. The cfg op selects between those two regions, as
> well as disallowing problematic accesses, particularly if the link
> is down because there isn't an attached device.

I'm not sure SMCCC is *really* relevant here.  If it is, an expansion
of the acronym and a link to a spec would be helpful.

But AFAICT the only important thing here is that it doesn't have
standard ECAM, and we're going to work around that.

I don't see anything about _DSD in this series.

> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  drivers/pci/controller/Makefile            |  1 +
>  drivers/pci/controller/pcie-brcmstb-acpi.c | 77 ++++++++++++++++++++++
>  include/linux/pci-ecam.h                   |  1 +
>  3 files changed, 79 insertions(+)
>  create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
> 
> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> index aaf30b3dcc14..65aa6fd3ed89 100644
> --- a/drivers/pci/controller/Makefile
> +++ b/drivers/pci/controller/Makefile
> @@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
>  obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
>  obj-$(CONFIG_ARM64) += pci-thunder-pem.o
>  obj-$(CONFIG_ARM64) += pci-xgene.o
> +obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
>  endif
>  endif
> diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
> new file mode 100644
> index 000000000000..76944876155f
> --- /dev/null
> +++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
> @@ -0,0 +1,77 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * ACPI quirks for Brcm2711 PCIe host controller
> + * As used on the Raspberry Pi Compute Module 4
> + *
> + * Copyright (C) 2021 Arm Ltd.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/pci.h>
> +#include <linux/pci-acpi.h>

Do we use something from pci-acpi.h?

> +#include <linux/pci-ecam.h>
> +#include "../pci.h"
> +#include "pcie-brcmstb.h"
> +
> +static int brcm_acpi_init(struct pci_config_window *cfg)
> +{
> +	/*
> +	 * This platform doesn't technically have anything that could be called
> +	 * ECAM. Its config region has root port specific registers between
> +	 * standard PCIe defined config registers. Thus the region setup by the
> +	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
> +	 * but the footprint isn't a nice power of 2 (40k). For purposes of
> +	 * mapping the config region we are just going to squash the standard
> +	 * and nonstandard registers together rather than mapping them
> +	 * separately. This code simply honors the quirk provided base+size
> +	 * instead.
> +	 */
> +	iounmap(cfg->win);
> +	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
> +	if (!cfg->win)
> +		goto err_exit;
> +
> +	/* MSI is nonstandard as well */
> +	pci_no_msi();
> +
> +	return 0;
> +err_exit:
> +	dev_err(cfg->parent, "PCI: Failed to remap config\n");
> +	return -ENOMEM;
> +}
> +
> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus, unsigned int devfn,
> +					int where)

Rewrap to fit in 80 columns.  81 is just ... weird :)

> +{
> +	struct pci_config_window *cfg = bus->sysdata;
> +	void __iomem *base = cfg->win;
> +	int idx;
> +	u32 up;
> +
> +	/* Accesses to the RC go right to the RC registers if slot==0 */
> +	if (pci_is_root_bus(bus))
> +		return PCI_SLOT(devfn) ? NULL : base + where;
> +
> +	/* Assure link up before sending request */
> +	up = readl(base + PCIE_MISC_PCIE_STATUS);
> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
> +		return NULL;
> +
> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
> +		return NULL;

What happens if the link goes down here?  Hopefully that's a
recoverable error?

> +	/* For devices, write to the config space index register */
> +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
> +	writel(idx, base + PCIE_EXT_CFG_INDEX);
> +	return base + PCIE_EXT_CFG_DATA + where;
> +}
> +
> +const struct pci_ecam_ops bcm2711_pcie_ops = {
> +	.init		= brcm_acpi_init,
> +	.bus_shift	= 1,
> +	.pci_ops	= {
> +		.map_bus	= brcm_pcie_map_conf2,
> +		.read		= pci_generic_config_read,
> +		.write		= pci_generic_config_write,
> +	}
> +};
> diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
> index adea5a4771cf..a5de0285bb7f 100644
> --- a/include/linux/pci-ecam.h
> +++ b/include/linux/pci-ecam.h
> @@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
>  extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
>  extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
>  extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
> +extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
>  #endif
>  
>  #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
> -- 
> 2.31.1
> 


From robh at kernel.org  Fri Aug  6 15:51:20 2021
From: robh at kernel.org (Rob Herring)
Date: Fri,  6 Aug 2021 16:51:20 -0600
Subject: [PATCH v9 0/3] arm64 userspace counter support
Message-ID: <20210806225123.1958497-1-robh@kernel.org>

Will, Mark,

This depends on:

https://lore.kernel.org/lkml/20210728230230.1911468-1-robh at kernel.org/

Go review that first, thanks!

Another version of arm64 userspace counter access support. This is just the
Arm bits as Arnaldo asked to send the tools bits separately.

The Arm implementation departs from the x86 implementation by requiring
the user to always explicitly request user access (via attr.config1) and
only enables access for task bound events. Rather than trying to lock
down the access as the x86 implementation has been doing, we can start
with only a limited use case enabled and later expand it if needed.

This originally resurrected Raphael's series[1] to enable userspace counter
access on arm64. My previous versions are here[2][3][4][5][6][7][8][9].

Changes in v9:
 - Reworked x86 and perf core to handle user access tracking and call
   .event_mapped() and .event_unmapped() on the CPU with the event like
   other changes to events.
 - Use sysctl instead of sysfs to disable user access.

Changes in v8:
 - Restrict user access to thread bound events which simplifies the
   implementation. A couple of perf core changes (patches 1 and 2) are
   needed to do this.
 - Always require the user to request userspace access.

Changes in v7:
 - Handling of dirty counter leakage and reworking of context switch and
   user access enabling. The .sched_task hook and undef instruction handler
   are now utilized. (Patch 3)
 - Add a userspace disable switch like x86. (Patch 5)

Changes in v6:
 - Reworking of the handling of 64-bit counters and user access. There's
   a new config1 flag to request user access. This takes priority over
   the 64-bit flag and the user will get the maximum size the h/w
   supports without chaining.
 - The libperf evsel mmap struct is stored in its own xyarray
 - New tests for user 64-bit and 32-bit counters
 - Rebase to v5.12-rc2

Changes in v5:
 - Limit enabling/disabling access to CPUs associated with the PMU
   (supported_cpus) and with the mm_struct matching current->active_mm.
   The x86 method of using mm_cpumask doesn't work for arm64 as it is not
   updated.
 - Only set cap_user_rdpmc if event is on current cpu. See patch 2.
 - Create an mmap for every event in an evsel. This results in some changes
   to the libperf mmap API from the last version.
 - Rebase to v5.11-rc2

Changes in v4:
 - Dropped 'arm64: pmu: Add hook to handle pmu-related undefined instructions'.
   The onus is on userspace to pin itself to a homogeneous subset of CPUs
   and avoid any aborts on heterogeneous systems, so the hook is not needed.
 - Make perf_evsel__mmap() take pages rather than bytes for size
 - Fix building arm64 heterogeneous test.

Changes in v3:
 - Dropped removing x86 rdpmc test until libperf tests can run via 'perf test'
 - Added verbose prints for tests
 - Split adding perf_evsel__mmap() to separate patch

The following changes to the arm64 support have been made compared to
Raphael's last version:

The major change is support for heterogeneous systems with some
restrictions. Specifically, userspace must pin itself to like CPUs, open
a specific PMU by type, and use h/w specific events. The tests have been
reworked to demonstrate this.

Chained events are not supported. The problem with supporting chained
events was there's no way to distinguish between a chained event and a
native 64-bit counter. We could add some flag, but do self monitoring
processes really need that? Native 64-bit counters are supported if the
PMU h/w has support. As there's already an explicit ABI to request 64-bit
counters, userspace can request 64-bit counters and if user
access is not enabled, then it must retry with 32-bit counters.

Prior versions broke the build on arm32 (surprisingly never caught by
0-day). As a result, event_mapped and event_unmapped implementations have
been moved into the arm64 code.

There was a bug in that pmc_width was not set in the user page. The tests
now check for this.

The documentation has been converted to rST. I've added sections on
chained events and heterogeneous.

Rob

[1] https://lore.kernel.org/r/20190822144220.27860-1-raphael.gault at arm.com/
[2] https://lore.kernel.org/r/20200707205333.624938-1-robh at kernel.org/
[3] https://lore.kernel.org/r/20200828205614.3391252-1-robh at kernel.org/
[4] https://lore.kernel.org/r/20200911215118.2887710-1-robh at kernel.org/
[5] https://lore.kernel.org/r/20201001140116.651970-1-robh at kernel.org/
[6] https://lore.kernel.org/r/20210114020605.3943992-1-robh at kernel.org/
[7] https://lore.kernel.org/r/20210311000837.3630499-1-robh at kernel.org/
[8] https://lore.kernel.org/r/20210420031511.2348977-1-robh at kernel.org/
[9] https://lore.kernel.org/r/20210517195405.3079458-1-robh at kernel.org/

Raphael Gault (1):
  Documentation: arm64: Document PMU counters access from userspace

Rob Herring (2):
  arm64: perf: Add userspace counter access disable switch
  arm64: perf: Enable PMU counter userspace access for perf event

 Documentation/arm64/perf.rst   |  68 ++++++++++++++-
 arch/arm64/kernel/perf_event.c | 154 +++++++++++++++++++++++++++++++--
 include/linux/perf/arm_pmu.h   |   6 ++
 3 files changed, 219 insertions(+), 9 deletions(-)

-- 
2.30.2



From robh at kernel.org  Fri Aug  6 15:51:21 2021
From: robh at kernel.org (Rob Herring)
Date: Fri,  6 Aug 2021 16:51:21 -0600
Subject: [PATCH v9 1/3] arm64: perf: Add userspace counter access disable
 switch
In-Reply-To: <20210806225123.1958497-1-robh@kernel.org>
References: <20210806225123.1958497-1-robh@kernel.org>
Message-ID: <20210806225123.1958497-2-robh@kernel.org>

Like x86, some users may want to disable userspace PMU counter
altogether. Add a sysctl 'perf_user_access' file to control userspace
counter access. The default is '0' which is disabled. Writing '1'
enables access.

Note that x86 also supports writing '2' to globally enable user access.
As there's not existing userspace support to worry about, this shouldn't
be necessary for Arm. It could be added later if the need arises.

Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Jiri Olsa <jolsa at redhat.com>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: linux-perf-users at vger.kernel.org
Signed-off-by: Rob Herring <robh at kernel.org>
---
v9:
 - Use sysctl instead of sysfs attr
 - Default to disabled
v8:
 - New patch

---
 arch/arm64/kernel/perf_event.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index d07788dad388..74f77b68f5f0 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -286,6 +286,21 @@ static const struct attribute_group armv8_pmuv3_events_attr_group = {
 PMU_FORMAT_ATTR(event, "config:0-15");
 PMU_FORMAT_ATTR(long, "config1:0");
 
+static int sysctl_perf_user_access __read_mostly;
+
+static struct ctl_table armv8_pmu_sysctl_table[] = {
+	{
+		.procname       = "perf_user_access",
+		.data		= &sysctl_perf_user_access,
+		.maxlen		= sizeof(unsigned int),
+		.mode           = 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= SYSCTL_ONE,
+	},
+	{ }
+};
+
 static inline bool armv8pmu_event_is_64bit(struct perf_event *event)
 {
 	return event->attr.config1 & 0x1;
@@ -1136,6 +1151,8 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = caps ?
 			caps : &armv8_pmuv3_caps_attr_group;
 
+	register_sysctl("kernel", armv8_pmu_sysctl_table);
+
 	return 0;
 }
 
-- 
2.30.2



From robh at kernel.org  Fri Aug  6 15:51:22 2021
From: robh at kernel.org (Rob Herring)
Date: Fri,  6 Aug 2021 16:51:22 -0600
Subject: [PATCH v9 2/3] arm64: perf: Enable PMU counter userspace access for
 perf event
In-Reply-To: <20210806225123.1958497-1-robh@kernel.org>
References: <20210806225123.1958497-1-robh@kernel.org>
Message-ID: <20210806225123.1958497-3-robh@kernel.org>

Arm PMUs can support direct userspace access of counters which allows for
low overhead (i.e. no syscall) self-monitoring of tasks. The same feature
exists on x86 called 'rdpmc'. Unlike x86, userspace access will only be
enabled for thread bound events. This could be extended if needed, but
simplifies the implementation and reduces the chances for any
information leaks (which the x86 implementation suffers from).

When an event is capable of userspace access and has been mmapped, userspace
access is enabled when the event is scheduled on a CPU's PMU. There's some
additional overhead clearing counters when disabled in order to prevent
leaking disabled counter data from other tasks.

Unlike x86, enabling of userspace access must be requested with a new
attr bit: config1:1. If the user requests userspace access and 64-bit
counters, then chaining will be disabled and the user will get the
maximum size counter the underlying h/w can support. The modes for
config1 are as follows:

config1 = 0 : user access disabled and always 32-bit
config1 = 1 : user access disabled and always 64-bit (using chaining if needed)
config1 = 2 : user access enabled and always 32-bit
config1 = 3 : user access enabled and counter size matches underlying counter.

Based on work by Raphael Gault <raphael.gault at arm.com>, but has been
completely re-written.

Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Jiri Olsa <jolsa at redhat.com>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Signed-off-by: Rob Herring <robh at kernel.org>

---
v9:
 - Enabling/disabling of user access is now controlled in .start() and
   mmap hooks which are now called on CPUs that the event is on.
   Depends on rework of perf core and x86 RDPMC code posted here:
   https://lore.kernel.org/lkml/20210728230230.1911468-1-robh at kernel.org/

v8:
 - Rework user access tracking and enabling to be done on task
   context changes using sched_task() hook. This avoids the need for any
   IPIs, mm_switch hooks or undef instr handler.
 - Only support user access when explicitly requested on open and
   only for a thread bound events. This avoids some of the information
   leaks x86 has and simplifies the implementation.

v7:
 - Clear disabled counters when user access is enabled for a task to
   avoid leaking other tasks counter data.
 - Rework context switch handling utilizing sched_task callback
 - Add armv8pmu_event_can_chain() helper
 - Rework config1 flags handling structure
 - Use ARMV8_IDX_CYCLE_COUNTER_USER define for remapped user cycle
   counter index

v6:
 - Add new attr.config1 rdpmc bit for userspace to hint it wants
   userspace access when also requesting 64-bit counters.

v5:
 - Only set cap_user_rdpmc if event is on current cpu
 - Limit enabling/disabling access to CPUs associated with the PMU
   (supported_cpus) and with the mm_struct matching current->active_mm.

v2:
 - Move mapped/unmapped into arm64 code. Fixes arm32.
 - Rebase on cap_user_time_short changes

Changes from Raphael's v4:
  - Drop homogeneous check
  - Disable access for chained counters
  - Set pmc_width in user page
---
 arch/arm64/kernel/perf_event.c | 137 +++++++++++++++++++++++++++++++--
 include/linux/perf/arm_pmu.h   |   6 ++
 2 files changed, 135 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 74f77b68f5f0..66d8bf62e99c 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -285,6 +285,7 @@ static const struct attribute_group armv8_pmuv3_events_attr_group = {
 
 PMU_FORMAT_ATTR(event, "config:0-15");
 PMU_FORMAT_ATTR(long, "config1:0");
+PMU_FORMAT_ATTR(rdpmc, "config1:1");
 
 static int sysctl_perf_user_access __read_mostly;
 
@@ -306,9 +307,15 @@ static inline bool armv8pmu_event_is_64bit(struct perf_event *event)
 	return event->attr.config1 & 0x1;
 }
 
+static inline bool armv8pmu_event_want_user_access(struct perf_event *event)
+{
+	return event->attr.config1 & 0x2;
+}
+
 static struct attribute *armv8_pmuv3_format_attrs[] = {
 	&format_attr_event.attr,
 	&format_attr_long.attr,
+	&format_attr_rdpmc.attr,
 	NULL,
 };
 
@@ -377,7 +384,7 @@ static const struct attribute_group armv8_pmuv3_caps_attr_group = {
  */
 #define	ARMV8_IDX_CYCLE_COUNTER	0
 #define	ARMV8_IDX_COUNTER0	1
-
+#define	ARMV8_IDX_CYCLE_COUNTER_USER	32
 
 /*
  * We unconditionally enable ARMv8.5-PMU long event counter support
@@ -389,6 +396,15 @@ static bool armv8pmu_has_long_event(struct arm_pmu *cpu_pmu)
 	return (cpu_pmu->pmuver >= ID_AA64DFR0_PMUVER_8_5);
 }
 
+static inline bool armv8pmu_event_can_chain(struct perf_event *event)
+{
+	struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+
+	return !(event->hw.flags & PERF_EVENT_FLAG_USER_READ_CNT) &&
+	       armv8pmu_event_is_64bit(event) &&
+	       !armv8pmu_has_long_event(cpu_pmu);
+}
+
 /*
  * We must chain two programmable counters for 64 bit events,
  * except when we have allocated the 64bit cycle counter (for CPU
@@ -398,11 +414,9 @@ static bool armv8pmu_has_long_event(struct arm_pmu *cpu_pmu)
 static inline bool armv8pmu_event_is_chained(struct perf_event *event)
 {
 	int idx = event->hw.idx;
-	struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
 
 	return !WARN_ON(idx < 0) &&
-	       armv8pmu_event_is_64bit(event) &&
-	       !armv8pmu_has_long_event(cpu_pmu) &&
+	       armv8pmu_event_can_chain(event) &&
 	       (idx != ARMV8_IDX_CYCLE_COUNTER);
 }
 
@@ -733,6 +747,35 @@ static inline u32 armv8pmu_getreset_flags(void)
 	return value;
 }
 
+static void armv8pmu_disable_user_access(void)
+{
+	write_sysreg(0, pmuserenr_el0);
+}
+
+static void armv8pmu_enable_user_access(struct arm_pmu *cpu_pmu)
+{
+	struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
+
+	if (!sysctl_perf_user_access)
+		return;
+
+	if (!bitmap_empty(cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS)) {
+		int i;
+		/* Don't need to clear assigned counters. */
+		bitmap_xor(cpuc->dirty_mask, cpuc->dirty_mask, cpuc->used_mask, ARMPMU_MAX_HWEVENTS);
+
+		for_each_set_bit(i, cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS) {
+			if (i == ARMV8_IDX_CYCLE_COUNTER)
+				write_sysreg(0, pmccntr_el0);
+			else
+				armv8pmu_write_evcntr(i, 0);
+		}
+		bitmap_zero(cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS);
+	}
+
+	write_sysreg(ARMV8_PMU_USERENR_ER | ARMV8_PMU_USERENR_CR, pmuserenr_el0);
+}
+
 static void armv8pmu_enable_event(struct perf_event *event)
 {
 	/*
@@ -776,6 +819,16 @@ static void armv8pmu_disable_event(struct perf_event *event)
 
 static void armv8pmu_start(struct arm_pmu *cpu_pmu)
 {
+	if (sysctl_perf_user_access) {
+		struct perf_cpu_context *cpuctx = this_cpu_ptr(cpu_pmu->pmu.pmu_cpu_context);
+		struct perf_event_context *task_ctx = cpuctx->task_ctx;
+		if (atomic_read(&cpuctx->ctx.nr_user) ||
+		    (task_ctx && atomic_read(&task_ctx->nr_user)))
+			armv8pmu_enable_user_access(cpu_pmu);
+		else
+			armv8pmu_disable_user_access();
+	}
+
 	/* Enable all counters */
 	armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMU_PMCR_E);
 }
@@ -893,13 +946,16 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
 	if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) {
 		if (!test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask))
 			return ARMV8_IDX_CYCLE_COUNTER;
+		else if (armv8pmu_event_is_64bit(event) &&
+			   armv8pmu_event_want_user_access(event) &&
+			   !armv8pmu_has_long_event(cpu_pmu))
+				return -EAGAIN;
 	}
 
 	/*
 	 * Otherwise use events counters
 	 */
-	if (armv8pmu_event_is_64bit(event) &&
-	    !armv8pmu_has_long_event(cpu_pmu))
+	if (armv8pmu_event_can_chain(event))
 		return	armv8pmu_get_chain_idx(cpuc, cpu_pmu);
 	else
 		return armv8pmu_get_single_idx(cpuc, cpu_pmu);
@@ -911,8 +967,44 @@ static void armv8pmu_clear_event_idx(struct pmu_hw_events *cpuc,
 	int idx = event->hw.idx;
 
 	clear_bit(idx, cpuc->used_mask);
-	if (armv8pmu_event_is_chained(event))
+	set_bit(idx, cpuc->dirty_mask);
+	if (armv8pmu_event_is_chained(event)) {
 		clear_bit(idx - 1, cpuc->used_mask);
+		set_bit(idx - 1, cpuc->dirty_mask);
+	}
+}
+
+static int armv8pmu_access_event_idx(struct perf_event *event)
+{
+	if (!sysctl_perf_user_access ||
+	    !(event->hw.flags & PERF_EVENT_FLAG_USER_READ_CNT))
+		return 0;
+
+	/*
+	 * We remap the cycle counter index to 32 to
+	 * match the offset applied to the rest of
+	 * the counter indices.
+	 */
+	if (event->hw.idx == ARMV8_IDX_CYCLE_COUNTER)
+		return ARMV8_IDX_CYCLE_COUNTER_USER;
+
+	return event->hw.idx;
+}
+
+static void armv8pmu_event_mapped(struct perf_event *event)
+{
+	if (atomic_read(&event->ctx->nr_user) != 1)
+		return;
+
+	armv8pmu_enable_user_access(to_arm_pmu(event->pmu));
+}
+
+static void armv8pmu_event_unmapped(struct perf_event *event)
+{
+	if (atomic_read(&event->ctx->nr_user) != 1)
+		return;
+
+	armv8pmu_disable_user_access();
 }
 
 /*
@@ -1008,9 +1100,22 @@ static int __armv8_pmuv3_map_event(struct perf_event *event,
 				       &armv8_pmuv3_perf_cache_map,
 				       ARMV8_PMU_EVTYPE_EVENT);
 
-	if (armv8pmu_event_is_64bit(event))
+	/*
+	 * At this point, the counter is not assigned. If a 64-bit counter is
+	 * requested, we must make sure the h/w has 64-bit counters if we set
+	 * the event size to 64-bit because chaining is not supported with
+	 * userspace access. This may still fail later on if the CPU cycle
+	 * counter is in use.
+	 */
+	if (armv8pmu_event_is_64bit(event) &&
+	    (!armv8pmu_event_want_user_access(event) ||
+	     armv8pmu_has_long_event(armpmu) || (hw_event_id == ARMV8_PMUV3_PERFCTR_CPU_CYCLES)))
 		event->hw.flags |= ARMPMU_EVT_64BIT;
 
+	/* Userspace counter access only enabled if requested and a per task event */
+	if (sysctl_perf_user_access && armv8pmu_event_want_user_access(event) && event->hw.target)
+		event->hw.flags |= PERF_EVENT_FLAG_USER_READ_CNT;
+
 	/* Only expose micro/arch events supported by this PMU */
 	if ((hw_event_id > 0) && (hw_event_id < ARMV8_PMUV3_MAX_COMMON_EVENTS)
 	    && test_bit(hw_event_id, armpmu->pmceid_bitmap)) {
@@ -1142,6 +1247,10 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
 	cpu_pmu->set_event_filter	= armv8pmu_set_event_filter;
 	cpu_pmu->filter_match		= armv8pmu_filter_match;
 
+	cpu_pmu->pmu.event_idx		= armv8pmu_access_event_idx;
+	cpu_pmu->pmu.event_mapped	= armv8pmu_event_mapped;
+	cpu_pmu->pmu.event_unmapped	= armv8pmu_event_unmapped;
+
 	cpu_pmu->name			= name;
 	cpu_pmu->map_event		= map_event;
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = events ?
@@ -1318,6 +1427,18 @@ void arch_perf_update_userpage(struct perf_event *event,
 	userpg->cap_user_time = 0;
 	userpg->cap_user_time_zero = 0;
 	userpg->cap_user_time_short = 0;
+	userpg->cap_user_rdpmc = !!userpg->index;
+
+	if (userpg->cap_user_rdpmc) {
+		struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+
+		if (armv8pmu_event_is_64bit(event) &&
+		    (armv8pmu_has_long_event(cpu_pmu) ||
+		     (userpg->index == ARMV8_IDX_CYCLE_COUNTER_USER)))
+			userpg->pmc_width = 64;
+		else
+			userpg->pmc_width = 32;
+	}
 
 	do {
 		rd = sched_clock_read_begin(&seq);
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 505480217cf1..46f09c8d7e9a 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -54,6 +54,12 @@ struct pmu_hw_events {
 	 */
 	DECLARE_BITMAP(used_mask, ARMPMU_MAX_HWEVENTS);
 
+	/*
+	 * A 1 bit for an index indicates that the counter has been used for
+	 * an event and has not been cleared.
+	 */
+	DECLARE_BITMAP(dirty_mask, ARMPMU_MAX_HWEVENTS);
+
 	/*
 	 * Hardware lock to serialize accesses to PMU registers. Needed for the
 	 * read/modify/write sequences.
-- 
2.30.2



From robh at kernel.org  Fri Aug  6 15:51:23 2021
From: robh at kernel.org (Rob Herring)
Date: Fri,  6 Aug 2021 16:51:23 -0600
Subject: [PATCH v9 3/3] Documentation: arm64: Document PMU counters access
 from userspace
In-Reply-To: <20210806225123.1958497-1-robh@kernel.org>
References: <20210806225123.1958497-1-robh@kernel.org>
Message-ID: <20210806225123.1958497-4-robh@kernel.org>

From: Raphael Gault <raphael.gault at arm.com>

Add documentation to describe the access to the pmu hardware counters from
userspace.

Signed-off-by: Raphael Gault <raphael.gault at arm.com>
Signed-off-by: Rob Herring <robh at kernel.org>
---
v9:
 - No change
v8:
 - Reword that config1:1 must always be set to request user access
v7:
 - Merge into existing arm64 perf.rst
v6:
  - Update the chained event section with attr.config1 details
v2:
  - Update links to test examples

Changes from Raphael's v4:
  - Convert to rSt
  - Update chained event status
  - Add section for heterogeneous systems
---
 Documentation/arm64/perf.rst | 68 +++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/perf.rst b/Documentation/arm64/perf.rst
index b567f177d385..fa8706df2281 100644
--- a/Documentation/arm64/perf.rst
+++ b/Documentation/arm64/perf.rst
@@ -2,7 +2,10 @@
 
 .. _perf_index:
 
-=====================
+====
+Perf
+====
+
 Perf Event Attributes
 =====================
 
@@ -88,3 +91,66 @@ exclude_host. However when using !exclude_hv there is a small blackout
 window at the guest entry/exit where host events are not captured.
 
 On VHE systems there are no blackout windows.
+
+Perf Userspace PMU Hardware Counter Access
+==========================================
+
+Overview
+--------
+The perf userspace tool relies on the PMU to monitor events. It offers an
+abstraction layer over the hardware counters since the underlying
+implementation is cpu-dependent.
+Arm64 allows userspace tools to have access to the registers storing the
+hardware counters' values directly.
+
+This targets specifically self-monitoring tasks in order to reduce the overhead
+by directly accessing the registers without having to go through the kernel.
+
+How-to
+------
+The focus is set on the armv8 PMUv3 which makes sure that the access to the pmu
+registers is enabled and that the userspace has access to the relevant
+information in order to use them.
+
+In order to have access to the hardware counter it is necessary to open the
+event using the perf tool interface with config1:1 attr bit set: the
+sys_perf_event_open syscall returns a fd which can subsequently be used
+with the mmap syscall in order to retrieve a page of memory containing
+information about the event. The PMU driver uses this page to expose to
+the user the hardware counter's index and other necessary data. Using
+this index enables the user to access the PMU registers using the `mrs`
+instruction.
+
+The userspace access is supported in libperf using the perf_evsel__mmap()
+and perf_evsel__read() functions. See `tools/lib/perf/tests/test-evsel.c`_ for
+an example.
+
+About heterogeneous systems
+---------------------------
+On heterogeneous systems such as big.LITTLE, userspace PMU counter access can
+only be enabled when the tasks are pinned to a homogeneous subset of cores and
+the corresponding PMU instance is opened by specifying the 'type' attribute.
+The use of generic event types is not supported in this case.
+
+Have a look at `tools/perf/arch/arm64/tests/user-events.c`_ for an example. It
+can be run using the perf tool to check that the access to the registers works
+correctly from userspace:
+
+.. code-block:: sh
+
+  perf test -v user
+
+About chained events and 64-bit counters
+----------------------------------------
+Chained events are not supported in conjunction with userspace counter
+access. If a 64-bit counter is requested (attr.config1:0) with userspace
+access (attr.config1:1 set), then counter chaining will be disabled. The
+'pmc_width' in the user page will indicate the actual width of the
+counter which could be only 32-bits depending on the event and PMU
+features.
+
+.. Links
+.. _tools/perf/arch/arm64/tests/user-events.c:
+   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/arch/arm64/tests/user-events.c
+.. _tools/lib/perf/tests/test-evsel.c:
+   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/perf/tests/test-evsel.c
-- 
2.30.2



From leoyang.li at nxp.com  Fri Aug  6 16:42:06 2021
From: leoyang.li at nxp.com (Leo Li)
Date: Fri, 6 Aug 2021 23:42:06 +0000
Subject: [PATCH v4] soc: fsl: qe: convert QE interrupt controller to
 platform_device
In-Reply-To: <20210803113538.560277-1-fido_max@inbox.ru>
References: <20210803113538.560277-1-fido_max@inbox.ru>
Message-ID: <AS8PR04MB89468FF7C9C43EF2D70FF0608FF39@AS8PR04MB8946.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Maxim Kochetkov <fido_max at inbox.ru>
> Sent: Tuesday, August 3, 2021 6:36 AM
> To: linuxppc-dev at lists.ozlabs.org
> Cc: Qiang Zhao <qiang.zhao at nxp.com>; Leo Li <leoyang.li at nxp.com>;
> gregkh at linuxfoundation.org; saravanak at google.com; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Maxim Kochetkov
> <fido_max at inbox.ru>; kernel test robot <lkp at intel.com>; Dan Carpenter
> <dan.carpenter at oracle.com>
> Subject: [PATCH v4] soc: fsl: qe: convert QE interrupt controller to
> platform_device
> 
> Since 5.13 QE's ucc nodes can't get interrupts from devicetree:
> 
> 	ucc at 2000 {
> 		cell-index = <1>;
> 		reg = <0x2000 0x200>;
> 		interrupts = <32>;
> 		interrupt-parent = <&qeic>;
> 	};
> 
> Now fw_devlink expects driver to create and probe a struct device for
> interrupt controller.
> 
> So lets convert this driver to simple platform_device with probe().
> Also use platform_get_ and devm_ family function to get/allocate resources
> and drop unused .compatible = "qeic".
> 
> [1] -
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.k
> ernel.org%2Flkml%2FCAGETcx9PiX%3D%3DmLxB9PO8Myyk6u2vhPVwTMsA
> 5NkD-
> ywH5xhusw%40mail.gmail.com&amp;data=04%7C01%7Cleoyang.li%40nxp.co
> m%7C1833b32e26de4ed7ef7908d956728eae%7C686ea1d3bc2b4c6fa92cd99c5
> c301635%7C0%7C0%7C637635872281355718%7CUnknown%7CTWFpbGZsb3d
> 8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%
> 3D%7C1000&amp;sdata=HrivK73GYFAwygPz24JtO%2BTdkicCVYXOl3uywjOqS
> %2BA%3D&amp;reserved=0
> Fixes: e590474768f1 ("driver core: Set fw_devlink=on by default")
> Fixes: ea718c699055 ("Revert "Revert "driver core: Set fw_devlink=on by
> default""")
> Signed-off-by: Maxim Kochetkov <fido_max at inbox.ru>
> Reported-by: kernel test robot <lkp at intel.com>
> Reported-by: Dan Carpenter <dan.carpenter at oracle.com>

Applied to fix.  Thanks.

> ---
>  drivers/soc/fsl/qe/qe_ic.c | 75 ++++++++++++++++++++++----------------
>  1 file changed, 44 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c index
> 3f711c1a0996..e710d554425d 100644
> --- a/drivers/soc/fsl/qe/qe_ic.c
> +++ b/drivers/soc/fsl/qe/qe_ic.c
> @@ -23,6 +23,7 @@
>  #include <linux/signal.h>
>  #include <linux/device.h>
>  #include <linux/spinlock.h>
> +#include <linux/platform_device.h>
>  #include <asm/irq.h>
>  #include <asm/io.h>
>  #include <soc/fsl/qe/qe.h>
> @@ -404,41 +405,40 @@ static void qe_ic_cascade_muxed_mpic(struct
> irq_desc *desc)
>  	chip->irq_eoi(&desc->irq_data);
>  }
> 
> -static void __init qe_ic_init(struct device_node *node)
> +static int qe_ic_init(struct platform_device *pdev)
>  {
> +	struct device *dev = &pdev->dev;
>  	void (*low_handler)(struct irq_desc *desc);
>  	void (*high_handler)(struct irq_desc *desc);
>  	struct qe_ic *qe_ic;
> -	struct resource res;
> -	u32 ret;
> +	struct resource *res;
> +	struct device_node *node = pdev->dev.of_node;
> 
> -	ret = of_address_to_resource(node, 0, &res);
> -	if (ret)
> -		return;
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (res == NULL) {
> +		dev_err(dev, "no memory resource defined\n");
> +		return -ENODEV;
> +	}
> 
> -	qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
> +	qe_ic = devm_kzalloc(dev, sizeof(*qe_ic), GFP_KERNEL);
>  	if (qe_ic == NULL)
> -		return;
> +		return -ENOMEM;
> 
> -	qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
> -					       &qe_ic_host_ops, qe_ic);
> -	if (qe_ic->irqhost == NULL) {
> -		kfree(qe_ic);
> -		return;
> +	qe_ic->regs = devm_ioremap(dev, res->start, resource_size(res));
> +	if (qe_ic->regs == NULL) {
> +		dev_err(dev, "failed to ioremap() registers\n");
> +		return -ENODEV;
>  	}
> 
> -	qe_ic->regs = ioremap(res.start, resource_size(&res));
> -
>  	qe_ic->hc_irq = qe_ic_irq_chip;
> 
> -	qe_ic->virq_high = irq_of_parse_and_map(node, 0);
> -	qe_ic->virq_low = irq_of_parse_and_map(node, 1);
> +	qe_ic->virq_high = platform_get_irq(pdev, 0);
> +	qe_ic->virq_low = platform_get_irq(pdev, 1);
> 
> -	if (!qe_ic->virq_low) {
> -		printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
> -		kfree(qe_ic);
> -		return;
> +	if (qe_ic->virq_low < 0) {
> +		return -ENODEV;
>  	}
> +
>  	if (qe_ic->virq_high != qe_ic->virq_low) {
>  		low_handler = qe_ic_cascade_low;
>  		high_handler = qe_ic_cascade_high;
> @@ -447,6 +447,13 @@ static void __init qe_ic_init(struct device_node
> *node)
>  		high_handler = NULL;
>  	}
> 
> +	qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
> +					       &qe_ic_host_ops, qe_ic);
> +	if (qe_ic->irqhost == NULL) {
> +		dev_err(dev, "failed to add irq domain\n");
> +		return -ENODEV;
> +	}
> +
>  	qe_ic_write(qe_ic->regs, QEIC_CICR, 0);
> 
>  	irq_set_handler_data(qe_ic->virq_low, qe_ic); @@ -456,20 +463,26
> @@ static void __init qe_ic_init(struct device_node *node)
>  		irq_set_handler_data(qe_ic->virq_high, qe_ic);
>  		irq_set_chained_handler(qe_ic->virq_high, high_handler);
>  	}
> +	return 0;
>  }
> +static const struct of_device_id qe_ic_ids[] = {
> +	{ .compatible = "fsl,qe-ic"},
> +	{ .type = "qeic"},
> +	{},
> +};
> 
> -static int __init qe_ic_of_init(void)
> +static struct platform_driver qe_ic_driver =
>  {
> -	struct device_node *np;
> +	.driver	= {
> +		.name		= "qe-ic",
> +		.of_match_table	= qe_ic_ids,
> +	},
> +	.probe	= qe_ic_init,
> +};
> 
> -	np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
> -	if (!np) {
> -		np = of_find_node_by_type(NULL, "qeic");
> -		if (!np)
> -			return -ENODEV;
> -	}
> -	qe_ic_init(np);
> -	of_node_put(np);
> +static int __init qe_ic_of_init(void)
> +{
> +	platform_driver_register(&qe_ic_driver);
>  	return 0;
>  }
>  subsys_initcall(qe_ic_of_init);
> --
> 2.31.1



From leoyang.li at nxp.com  Fri Aug  6 16:46:03 2021
From: leoyang.li at nxp.com (Li Yang)
Date: Fri, 6 Aug 2021 18:46:03 -0500
Subject: [PATCH v2 1/2] arm64: dts: ls1046a: fix eeprom entries
In-Reply-To: <1628105086-8172-2-git-send-email-raagjadav@gmail.com>
References: <1628105086-8172-1-git-send-email-raagjadav@gmail.com>
 <1628105086-8172-2-git-send-email-raagjadav@gmail.com>
Message-ID: <CADRPPNTkdLEwSa2Bg1enzWBpcGco6twcQwvk_QqDXa=V1foBLg@mail.gmail.com>

On Wed, Aug 4, 2021 at 4:32 PM Raag Jadav <raagjadav at gmail.com> wrote:
>
> ls1046afrwy and ls1046ardb boards have CAT24C04[1] and CAT24C05[2]
> eeproms respectively. Both are 4Kb (512 bytes) in size,
> and compatible with AT24C04[3].
> Remove multi-address entries, as both the boards have a single chip each.
>
> [1] https://www.onsemi.com/pdf/datasheet/cat24c01-d.pdf
> [2] https://www.onsemi.com/pdf/datasheet/cat24c03-d.pdf
> [3] https://ww1.microchip.com/downloads/en/DeviceDoc/doc0180.pdf
>
> Signed-off-by: Raag Jadav <raagjadav at gmail.com>

Acked-by: Li Yang <leoyang.li at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 8 +-------
>  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts  | 7 +------
>  2 files changed, 2 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> index db3d303..6d22efb 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
> @@ -83,15 +83,9 @@
>                         };
>
>                         eeprom at 52 {
> -                               compatible = "atmel,24c512";
> +                               compatible = "onnn,cat24c04", "atmel,24c04";
>                                 reg = <0x52>;
>                         };
> -
> -                       eeprom at 53 {
> -                               compatible = "atmel,24c512";
> -                               reg = <0x53>;
> -                       };
> -
>                 };
>         };
>  };
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> index 60acdf0..7025aad 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
> @@ -59,14 +59,9 @@
>         };
>
>         eeprom at 52 {
> -               compatible = "atmel,24c512";
> +               compatible = "onnn,cat24c05", "atmel,24c04";
>                 reg = <0x52>;
>         };
> -
> -       eeprom at 53 {
> -               compatible = "atmel,24c512";
> -               reg = <0x53>;
> -       };
>  };
>
>  &i2c3 {
> --
> 2.7.4
>


From saravanak at google.com  Fri Aug  6 16:55:48 2021
From: saravanak at google.com (Saravana Kannan)
Date: Fri, 6 Aug 2021 16:55:48 -0700
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <4e98d876-330f-21a4-846e-94e1f01f0eed@baylibre.com>
References: <20201020072532.949137-1-narmstrong@baylibre.com>
 <20201020072532.949137-2-narmstrong@baylibre.com>
 <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <4e98d876-330f-21a4-846e-94e1f01f0eed@baylibre.com>
Message-ID: <CAGETcx95gQ4820Xz+MCxFS4Bi6yiHsfro2vdc2EqqrQNZ6caRg@mail.gmail.com>

On Wed, Aug 4, 2021 at 11:31 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi Saravana,
>
> On 04/08/2021 23:47, Saravana Kannan wrote:
> > On Wed, Aug 4, 2021 at 11:20 AM Saravana Kannan <saravanak at google.com> wrote:
> >>
> >> On Wed, Aug 4, 2021 at 1:50 AM Marc Zyngier <maz at kernel.org> wrote:
> >>>
> >>> On Wed, 04 Aug 2021 02:36:45 +0100,
> >>> Saravana Kannan <saravanak at google.com> wrote:
> >>>
> >>> Hi Saravana,
> >>>
> >>> Thanks for looking into this.
> >>
> >> You are welcome. I just don't want people to think fw_devlink is broken :)
> >>
> >>>
> >>> [...]
> >>>
> >>>>> Saravana, could you please have a look from a fw_devlink perspective?
> >>>>
> >>>> Sigh... I spent several hours looking at this and wrote up an analysis
> >>>> and then realized I might be looking at the wrong DT files.
> >>>>
> >>>> Marc, can you point me to the board file in upstream that corresponds
> >>>> to the platform in which you see this issue? I'm not asking for [1],
> >>>> but the actual final .dts (not .dtsi) file that corresponds to the
> >>>> platform/board/system.
> >>>
> >>> The platform I can reproduce this on is described in
> >>> arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts. It is an
> >>> intricate maze of inclusion, node merge and other DT subtleties. I
> >>> suggest you look at the decompiled version to get a view of the
> >>> result.
> >>
> >> Thanks. After decompiling it, it looks something like (stripped a
> >> bunch of reg and address properties and added the labels back):
> >>
> >> eth_phy: mdio-multiplexer at 4c000 {
> >>         compatible = "amlogic,g12a-mdio-mux";
> >>         clocks = <0x02 0x13 0x1e 0x02 0xb1>;
> >>         clock-names = "pclk\0clkin0\0clkin1";
> >>         mdio-parent-bus = <0x22>;
> >>
> >>         ext_mdio: mdio at 0 {
> >>                 reg = <0x00>;
> >>
> >>                 ethernet-phy at 0 {
> >>                         max-speed = <0x3e8>;
> >>                         interrupt-parent = <0x23>;
> >>                         interrupts = <0x1a 0x08>;
> >>                         phandle = <0x16>;
> >>                 };
> >>         };
> >>
> >>         int_mdio: mdio at 1 {
> >>                 ...
> >>         }
> >> }
> >>
> >> And phandle 0x23 refers to the gpio_intc interrupt controller with the
> >> modular driver.
> >>
> >>>> Based on your error messages, it's failing for mdio at 0 which
> >>>> corresponds to ext_mdio. But none of the board dts files in upstream
> >>>> have a compatible property for "ext_mdio". Which means fw_devlink
> >>>> _should_ propagate the gpio_intc IRQ dependency all the way up to
> >>>> eth_phy.
> >>>>
> >>>> Also, in the failing case, can you run:
> >>>> ls -ld supplier:*
> >>>>
> >>>> in the /sys/devices/....<something>/ folder that corresponds to the
> >>>> "eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?
> >>>
> >>> Here you go:
> >>>
> >>> root at tiger-roach:~# find /sys/devices/ -name 'supplier*'|grep -i mdio | xargs ls -ld
> >>> lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/platform/soc/ff600000.bus/ff64c000.mdio-multiplexer/supplier:platform:ff63c000.system-controller:clock-controller -> ../../../../virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer
> >>
> >> As we discussed over chat, this was taken after the mdio-multiplexer
> >> driver "successfully" probes this device. This will cause
> >> SYNC_STATE_ONLY device links created by fw_devlink to be deleted
> >> (because they are useless after a device probes). So, this doesn't
> >> show the info I was hoping to demonstrate.
> >>
> >> In any case, one can see that fw_devlink properly created the device
> >> link for the clocks dependency. So fw_devlink is parsing this node
> >> properly. But it doesn't create a similar probe order enforcing device
> >> link between the mdio-multiplexer and the gpio_intc because the
> >> dependency is only present in a grand child DT node (ethernet-phy at 0
> >> under ext_mdio). So fw_devlink is working as intended.
> >>
> >> I spent several hours squinting at the code/DT yesterday. Here's what
> >> is going on and causing the problem:
> >>
> >> The failing driver in this case is
> >> drivers/net/mdio/mdio-mux-meson-g12a.c. And the only DT node it's
> >> handling is what I pasted above in this email. In the failure case,
> >> the call flow is something like this:
> >>
> >> g12a_mdio_mux_probe()
> >> -> mdio_mux_init()
> >> -> of_mdiobus_register(ext_mdio DT node)
> >> -> of_mdiobus_register_phy(ext_mdio DT node)
> >> -> several calls deep fwnode_mdiobus_phy_device_register(ethernet_phy DT node)
> >> -> Tried to get the IRQ listed in ethernet_phy and fails with
> >> -EPROBE_DEFER because the IRQ driver isn't loaded yet.
> >>
> >> The error is propagated correctly all the way up to of_mdiobus_register(), but
> >> mdio_mux_init() ignores the -EPROBE_DEFER from of_mdiobus_register() and just
> >> continues on with the rest of the stuff and returns success as long as
> >> one of the child nodes (in this case int_mdio) succeeds.
> >>
> >> Since the probe returns 0 without really succeeding, networking stuff
> >> just fails badly after this. So, IMO, the real problem is with
> >> mdio_mux_init() not propagating up the -EPROBE_DEFER. I gave Marc a
> >> quick hack (pasted at the end of this email) to test my theory and he
> >> confirmed that it fixes the issue (a few deferred probes later, things
> >> work properly).
> >>
> >> Andrew, I don't see any good reason for mdio_mux_init() not
> >> propagating the errors up correctly (at least for EPROBE_DEFER). I'll
> >> send a patch to fix this. Please let me know if there's a reason it
> >> has to stay as-is.
> >
> > I sent out the proper fix as a series:
> > https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
>
> Thanks a lot for digging here and providing the appropriate fixes !

You are welcome!

Btw, 'm too lazy to download the mbox for your original patch
(justifiably not cc'ed in it) and reply to it. I made this comment
earlier too.

Can you please use the IRQCHIP_PLATFORM_DRIVER_BEGIN and
IRQCHIP_PLATFORM_DRIVER_END macros? They avoid boilerplate code every
irqchip driver has to implement, adds some restrictions to avoid
unbinding these drivers/unloading these modules, and also makes it
easy to convert from IRQCHIP_DECLARE to a platform driver. It'll also
allow you to drop the of_irq_find_parent() call in your probe.

Cheers,
Saravana

>
> Neil
>
> >
> > Marc, can you give it a shot please?
> >
> > -Saravana
> >
> >>
> >> -Saravana
> >>
> >> index 110e4ee85785..d973a267151f 100644
> >> --- a/drivers/net/mdio/mdio-mux.c
> >> +++ b/drivers/net/mdio/mdio-mux.c
> >> @@ -170,6 +170,9 @@ int mdio_mux_init(struct device *dev,
> >>                                 child_bus_node);
> >>                         mdiobus_free(cb->mii_bus);
> >>                         devm_kfree(dev, cb);
> >> +                       /* Not a final fix. I think it can cause UAF issues. */
> >> +                       mdio_mux_uninit(pb);
> >> +                       return r;
> >>                 } else {
> >>                         cb->next = pb->children;
> >>                         pb->children = cb;
>


From linux at armlinux.org.uk  Fri Aug  6 17:31:35 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sat, 7 Aug 2021 01:31:35 +0100
Subject: [PATCH v2] memblock: make memblock_find_in_range method private
In-Reply-To: <20210802063737.22733-1-rppt@kernel.org>
References: <20210802063737.22733-1-rppt@kernel.org>
Message-ID: <20210807003134.GR22278@shell.armlinux.org.uk>

On Mon, Aug 02, 2021 at 09:37:37AM +0300, Mike Rapoport wrote:
> From: Mike Rapoport <rppt at linux.ibm.com>
> 
> There are a lot of uses of memblock_find_in_range() along with
> memblock_reserve() from the times memblock allocation APIs did not exist.
> 
> memblock_find_in_range() is the very core of memblock allocations, so any
> future changes to its internal behaviour would mandate updates of all the
> users outside memblock.
> 
> Replace the calls to memblock_find_in_range() with an equivalent calls to
> memblock_phys_alloc() and memblock_phys_alloc_range() and make
> memblock_find_in_range() private method of memblock.
> 
> This simplifies the callers, ensures that (unlikely) errors in
> memblock_reserve() are handled and improves maintainability of
> memblock_find_in_range().
> 
> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
Acked-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From jeremy.linton at arm.com  Fri Aug  6 17:34:56 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri, 6 Aug 2021 19:34:56 -0500
Subject: [PATCH 3/3] PCI/ACPI: Add new quirk detection, enable bcm2711
In-Reply-To: <20210806221256.GA1891371@bjorn-Precision-5520>
References: <20210806221256.GA1891371@bjorn-Precision-5520>
Message-ID: <5f4f484b-9eef-2722-405d-a7ff6259aa0f@arm.com>

Hi,

Thanks for looking at this.

On 8/6/21 5:12 PM, Bjorn Helgaas wrote:
> In subject, this or similar would match history:
> 
>    PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
> 
> On Thu, Aug 05, 2021 at 04:12:00PM -0500, Jeremy Linton wrote:
>> Now that we have a bcm2711 quirk, we need to be able to
>> detect it when the MCFG is missing. Use a namespace
>> property as an alternative to the MCFG OEM.
> 
> Rewrap to use ~75 columns.
> 
> Mention the DT namespace property here.
> 
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>>   drivers/acpi/pci_mcfg.c | 14 ++++++++++++++
>>   1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
>> index 53cab975f612..7d77fc72c2a4 100644
>> --- a/drivers/acpi/pci_mcfg.c
>> +++ b/drivers/acpi/pci_mcfg.c
>> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>>   	ALTRA_ECAM_QUIRK(1, 13),
>>   	ALTRA_ECAM_QUIRK(1, 14),
>>   	ALTRA_ECAM_QUIRK(1, 15),
>> +
>> +	{ "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
>> +	  DEFINE_RES_MEM(0xFD500000, 0xA000) },
>>   };
>>   
>>   static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
>> @@ -198,8 +201,19 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
>>   	u16 segment = root->segment;
>>   	struct resource *bus_range = &root->secondary;
>>   	struct mcfg_fixup *f;
>> +	const char *soc;
>>   	int i;
>>   
>> +	/*
>> +	 * This could be a machine with a PCI/SMC conduit,
>> +	 * which means it doens't have MCFG. Get the machineid from
>> +	 * the namespace definition instead.
> 
> s/SMC/SMCCC/ ?  Cover letter uses SMCCC (not sure it's relevant anyway)
> s/doens't/doesn't/
> 
> Rewrap comment to use ~80 columns.
> 
> Seems pretty reasonable that a platform without standard ECAM might
> not have MCFG, since MCFG basically implies ECAM.


Sure, on all the above comments.

> 
> Is "linux,pcie-quirk" the right property to look for?  It doesn't
> sound very generic, and it doesn't sound like anything related to
> ECAM.  Is it new?  I don't see it in the tree yet.  Should it be in
> Documentation/devicetree/bindings/pci/pci.txt so we don't get a
> different property name for every new platform?

Yes, I made it up. Someone else commented about the "linux," partially 
because it should be "linux-" to conform with 
https://github.com/UEFI/DSD-Guide. But also in the same context of it 
being linux specific.  I think that guide is where it should end up, 
rather than the devicetree bindings.

I guess we can request addition to the uefi- but that seems like a 
mistake this is really (hopefully?) a Linux specific properly as other 
OS's will simply use the SMC. I think we could request another prefix if 
we come up with a good one and think it belongs in that guide.




> 
>> +	 */
>> +	if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
>> +					 "linux,pcie-quirk", &soc)) {
>> +		memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
>> +	}
>> +
>>   	for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
>>   		if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
>>   			if (f->cfgres.start)
>> -- 
>> 2.31.1
>>



From valentin.schneider at arm.com  Fri Aug  6 17:58:03 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sat,  7 Aug 2021 01:58:03 +0100
Subject: [PATCH v2 0/4] rcu, arm64: PREEMPT_RT fixlets
Message-ID: <20210807005807.1083943-1-valentin.schneider@arm.com>

Hi folks,

this is v2 of:

  https://lore.kernel.org/lkml/20210721115118.729943-1-valentin.schneider at arm.com/

respun from Frederic and Paul's helpful feedback. Tested atop v5.14-rc4-rt6 with
the v1 patches reverted. There, commit 

  d76e0926d835 ("rcu/nocb: Use the rcuog CPU's ->nocb_timer")

prevents the NOCB offload warning from firing if there are no NOCB CPUs (which
is sensible). Adding a single NOCB CPU brings the warning back, which patch 3
fixes.

Note that patches 2 & 4 are already in v5.14-rc4-rt6, but still apply against
mainline.

Revisions
=========

v1 -> v2
++++++++

o Rebased and tested against v5.14-rc4-rt6
o Picked rcutorture patch from
  https://lore.kernel.org/lkml/20210803225437.3612591-2-valentin.schneider at arm.com/
o Added a local_lock to protect NOCB offload state under PREEMPT_RT (Frederic,
  Paul)

Valentin Schneider (4):
  rcutorture: Don't disable softirqs with preemption disabled when
    PREEMPT_RT
  sched: Introduce is_pcpu_safe()
  rcu/nocb: Protect NOCB state via local_lock() under PREEMPT_RT
  arm64: mm: Make arch_faults_on_old_pte() check for migratability

 arch/arm64/include/asm/pgtable.h |  2 +-
 include/linux/sched.h            | 10 ++++
 kernel/rcu/rcutorture.c          |  2 +
 kernel/rcu/tree.c                |  4 ++
 kernel/rcu/tree.h                |  4 ++
 kernel/rcu/tree_plugin.h         | 82 ++++++++++++++++++++++++++++----
 6 files changed, 94 insertions(+), 10 deletions(-)

--
2.25.1



From valentin.schneider at arm.com  Fri Aug  6 17:58:04 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sat,  7 Aug 2021 01:58:04 +0100
Subject: [PATCH v2 1/4] rcutorture: Don't disable softirqs with preemption
 disabled when PREEMPT_RT
In-Reply-To: <20210807005807.1083943-1-valentin.schneider@arm.com>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
Message-ID: <20210807005807.1083943-2-valentin.schneider@arm.com>

Running RCU torture with CONFIG_PREEMPT_RT under v5.14-rc4-rt6 triggers:

[    8.755472] DEBUG_LOCKS_WARN_ON(this_cpu_read(softirq_ctrl.cnt))
[    8.755482] WARNING: CPU: 1 PID: 137 at kernel/softirq.c:172 __local_bh_disable_ip (kernel/softirq.c:172 (discriminator 31))
[    8.755500] Modules linked in:
[    8.755506] CPU: 1 PID: 137 Comm: rcu_torture_rea Not tainted 5.14.0-rc4-rt6 #171
[    8.755514] Hardware name: ARM Juno development board (r0) (DT)
[    8.755518] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
[    8.755622] Call trace:
[    8.755624] __local_bh_disable_ip (kernel/softirq.c:172 (discriminator 31))
[    8.755633] rcutorture_one_extend (kernel/rcu/rcutorture.c:1453)
[    8.755640] rcu_torture_one_read (kernel/rcu/rcutorture.c:1601 kernel/rcu/rcutorture.c:1645)
[    8.755645] rcu_torture_reader (kernel/rcu/rcutorture.c:1737)
[    8.755650] kthread (kernel/kthread.c:327)
[    8.755656] ret_from_fork (arch/arm64/kernel/entry.S:783)
[    8.755663] irq event stamp: 11959
[    8.755666] hardirqs last enabled at (11959): __rcu_read_unlock (kernel/rcu/tree_plugin.h:695 kernel/rcu/tree_plugin.h:451)
[    8.755675] hardirqs last disabled at (11958): __rcu_read_unlock (kernel/rcu/tree_plugin.h:661 kernel/rcu/tree_plugin.h:451)
[    8.755683] softirqs last enabled at (11950): __local_bh_enable_ip (./arch/arm64/include/asm/irqflags.h:85 kernel/softirq.c:261)
[    8.755692] softirqs last disabled at (11942): rcutorture_one_extend (./include/linux/bottom_half.h:19 kernel/rcu/rcutorture.c:1441)

Per this warning, softirqs cannot be disabled in a non-preemptible region
under CONFIG_PREEMPT_RT. Adjust RCU torture accordingly.

Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
---
 kernel/rcu/rcutorture.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index eecd1caef71d..4f3db1d3170d 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1548,6 +1548,8 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
 	 * them on non-RT.
 	 */
 	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
+		/* Can't disable bh in atomic context under PREEMPT_RT */
+		mask &= ~(RCUTORTURE_RDR_ATOM_BH | RCUTORTURE_RDR_ATOM_RBH);
 		/*
 		 * Can't release the outermost rcu lock in an irq disabled
 		 * section without preemption also being disabled, if irqs
-- 
2.25.1



From valentin.schneider at arm.com  Fri Aug  6 17:58:05 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sat,  7 Aug 2021 01:58:05 +0100
Subject: [PATCH v2 2/4] sched: Introduce is_pcpu_safe()
In-Reply-To: <20210807005807.1083943-1-valentin.schneider@arm.com>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
Message-ID: <20210807005807.1083943-3-valentin.schneider@arm.com>

Some areas use preempt_disable() + preempt_enable() to safely access
per-CPU data. The PREEMPT_RT folks have shown this can also be done by
keeping preemption enabled and instead disabling migration (and acquiring a
sleepable lock, if relevant).

Introduce a helper which checks whether the current task can safely access
per-CPU data, IOW if the task's context guarantees the accesses will target
a single CPU. This accounts for preemption, CPU affinity, and migrate
disable - note that the CPU affinity check also mandates the presence of
PF_NO_SETAFFINITY, as otherwise userspace could concurrently render the
upcoming per-CPU access(es) unsafe.

Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
---
 include/linux/sched.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index debc960f41e3..b77d65f677f6 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
 #endif
 }
 
+/* Is the current task guaranteed not to be migrated elsewhere? */
+static inline bool is_pcpu_safe(void)
+{
+#ifdef CONFIG_SMP
+	return !preemptible() || is_percpu_thread() || current->migration_disabled;
+#else
+	return true;
+#endif
+}
+
 /* Per-process atomic flags. */
 #define PFA_NO_NEW_PRIVS		0	/* May not gain new privileges. */
 #define PFA_SPREAD_PAGE			1	/* Spread page cache over cpuset */
-- 
2.25.1



From valentin.schneider at arm.com  Fri Aug  6 17:58:07 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sat,  7 Aug 2021 01:58:07 +0100
Subject: [PATCH v2 4/4] arm64: mm: Make arch_faults_on_old_pte() check for
 migratability
In-Reply-To: <20210807005807.1083943-1-valentin.schneider@arm.com>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
Message-ID: <20210807005807.1083943-5-valentin.schneider@arm.com>

Running v5.13-rt1 on my arm64 Juno board triggers:

[   30.430643] WARNING: CPU: 4 PID: 1 at arch/arm64/include/asm/pgtable.h:985 do_set_pte (./arch/arm64/include/asm/pgtable.h:985 ./arch/arm64/include/asm/pgtable.h:997 mm/memory.c:3830)
[   30.430669] Modules linked in:
[   30.430679] CPU: 4 PID: 1 Comm: init Tainted: G        W         5.13.0-rt1-00002-gcb994ad7c570 #35
[   30.430690] Hardware name: ARM Juno development board (r0) (DT)
[   30.430695] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
[   30.430874] Call trace:
[   30.430878] do_set_pte (./arch/arm64/include/asm/pgtable.h:985 ./arch/arm64/include/asm/pgtable.h:997 mm/memory.c:3830)
[   30.430886] filemap_map_pages (mm/filemap.c:3222)
[   30.430895] __handle_mm_fault (mm/memory.c:4006 mm/memory.c:4020 mm/memory.c:4153 mm/memory.c:4412 mm/memory.c:4547)
[   30.430904] handle_mm_fault (mm/memory.c:4645)
[   30.430912] do_page_fault (arch/arm64/mm/fault.c:507 arch/arm64/mm/fault.c:607)
[   30.430925] do_translation_fault (arch/arm64/mm/fault.c:692)
[   30.430936] do_mem_abort (arch/arm64/mm/fault.c:821)
[   30.430946] el0_ia (arch/arm64/kernel/entry-common.c:324)
[   30.430959] el0_sync_handler (arch/arm64/kernel/entry-common.c:431)
[   30.430967] el0_sync (arch/arm64/kernel/entry.S:744)
[   30.430977] irq event stamp: 1228384
[   30.430981] hardirqs last enabled at (1228383): lock_page_memcg (mm/memcontrol.c:2005 (discriminator 1))
[   30.430993] hardirqs last disabled at (1228384): el1_dbg (arch/arm64/kernel/entry-common.c:144 arch/arm64/kernel/entry-common.c:234)
[   30.431007] softirqs last enabled at (1228260): __local_bh_enable_ip (./arch/arm64/include/asm/irqflags.h:85 kernel/softirq.c:262)
[   30.431022] softirqs last disabled at (1228232): fpsimd_restore_current_state (./include/linux/bottom_half.h:19 arch/arm64/kernel/fpsimd.c:183 arch/arm64/kernel/fpsimd.c:1182)

CONFIG_PREEMPT_RT turns the PTE lock into a sleepable spinlock. Since
acquiring such a lock also disables migration, any per-CPU access done
under the lock remains safe even if preemptible.

This affects:

  filemap_map_pages()
  `\
    do_set_pte()
    `\
      arch_wants_old_prefaulted_pte()

which checks preemptible() to figure out if the output of
cpu_has_hw_af() (IOW the underlying CPU) will remain stable for the
subsequent operations. Make it use is_pcpu_safe() instead.

Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index f09bf5c02891..767a064bedde 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -995,7 +995,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
  */
 static inline bool arch_faults_on_old_pte(void)
 {
-	WARN_ON(preemptible());
+	WARN_ON(!is_pcpu_safe());
 
 	return !cpu_has_hw_af();
 }
-- 
2.25.1



From valentin.schneider at arm.com  Fri Aug  6 17:58:06 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sat,  7 Aug 2021 01:58:06 +0100
Subject: [PATCH v2 3/4] rcu/nocb: Protect NOCB state via local_lock() under
 PREEMPT_RT
In-Reply-To: <20210807005807.1083943-1-valentin.schneider@arm.com>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
Message-ID: <20210807005807.1083943-4-valentin.schneider@arm.com>

Warning
=======

Running v5.13-rt1 on my arm64 Juno board triggers:

[    0.156302] =============================
[    0.160416] WARNING: suspicious RCU usage
[    0.164529] 5.13.0-rt1 #20 Not tainted
[    0.168300] -----------------------------
[    0.172409] kernel/rcu/tree_plugin.h:69 Unsafe read of RCU_NOCB offloaded state!
[    0.179920]
[    0.179920] other info that might help us debug this:
[    0.179920]
[    0.188037]
[    0.188037] rcu_scheduler_active = 1, debug_locks = 1
[    0.194677] 3 locks held by rcuc/0/11:
[    0.198448] #0: ffff00097ef10cf8 ((softirq_ctrl.lock).lock){+.+.}-{2:2}, at: __local_bh_disable_ip (./include/linux/rcupdate.h:662 kernel/softirq.c:171)
[    0.208709] #1: ffff80001205e5f0 (rcu_read_lock){....}-{1:2}, at: rt_spin_lock (kernel/locking/spinlock_rt.c:43 (discriminator 4))
[    0.217134] #2: ffff80001205e5f0 (rcu_read_lock){....}-{1:2}, at: __local_bh_disable_ip (kernel/softirq.c:169)
[    0.226428]
[    0.226428] stack backtrace:
[    0.230889] CPU: 0 PID: 11 Comm: rcuc/0 Not tainted 5.13.0-rt1 #20
[    0.237100] Hardware name: ARM Juno development board (r0) (DT)
[    0.243041] Call trace:
[    0.245497] dump_backtrace (arch/arm64/kernel/stacktrace.c:163)
[    0.249185] show_stack (arch/arm64/kernel/stacktrace.c:219)
[    0.252522] dump_stack (lib/dump_stack.c:122)
[    0.255947] lockdep_rcu_suspicious (kernel/locking/lockdep.c:6439)
[    0.260328] rcu_rdp_is_offloaded (kernel/rcu/tree_plugin.h:69 kernel/rcu/tree_plugin.h:58)
[    0.264537] rcu_core (kernel/rcu/tree.c:2332 kernel/rcu/tree.c:2398 kernel/rcu/tree.c:2777)
[    0.267786] rcu_cpu_kthread (./include/linux/bottom_half.h:32 kernel/rcu/tree.c:2876)
[    0.271644] smpboot_thread_fn (kernel/smpboot.c:165 (discriminator 3))
[    0.275767] kthread (kernel/kthread.c:321)
[    0.279013] ret_from_fork (arch/arm64/kernel/entry.S:1005)

In this case, this is the RCU core kthread accessing the local CPU's
rdp. Before that, rcu_cpu_kthread() invokes local_bh_disable().

Under !CONFIG_PREEMPT_RT (and rcutree.use_softirq=0), this ends up
incrementing the preempt_count, which satisfies the "local non-preemptible
read" of rcu_rdp_is_offloaded().

Under CONFIG_PREEMPT_RT however, this becomes

  local_lock(&softirq_ctrl.lock)

which, under the same config, is migrate_disable() + rt_spin_lock(). As
pointed out by Frederic, this is not sufficient to safely access an rdp's
offload state, as the RCU core kthread can be preempted by a kworker
executing rcu_nocb_rdp_offload() [1].

Introduce a local_lock to serialize an rdp's offload state while the rdp's
associated core kthread is executing rcu_core().

rcu_core() preemptability considerations
========================================

As pointed out by Paul [2], keeping rcu_check_quiescent_state() preemptible
(which is the case under CONFIG_PREEMPT_RT) requires some consideration.

note_gp_changes() itself runs with irqs off, and enters
__note_gp_changes() with rnp->lock held (raw_spinlock), thus is safe vs
preemption.

rdp->core_needs_qs *could* change after being read by the RCU core
kthread if it then gets preempted. Consider, with
CONFIG_RCU_STRICT_GRACE_PERIOD:

  rcuc/x                                   task_foo

    rcu_check_quiescent_state()
    `\
      rdp->core_needs_qs == true
			     <PREEMPT>
					   rcu_read_unlock()
					   `\
					     rcu_preempt_deferred_qs_irqrestore()
					     `\
					       rcu_report_qs_rdp()
					       `\
						 rdp->core_needs_qs := false;

This would let rcuc/x's rcu_check_quiescent_state() proceed further down to
rcu_report_qs_rdp(), but if task_foo's earlier rcu_report_qs_rdp()
invocation would have cleared the rdp grpmask from the rnp mask, so
rcuc/x's invocation would simply bail.

Since rcu_report_qs_rdp() can be safely invoked, even if rdp->core_needs_qs
changed, it appears safe to keep rcu_check_quiescent_state() preemptible.

[1]: http://lore.kernel.org/r/20210727230814.GC283787 at lothringen
[2]: http://lore.kernel.org/r/20210729010445.GO4397 at paulmck-ThinkPad-P17-Gen-1
Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
---
 kernel/rcu/tree.c        |  4 ++
 kernel/rcu/tree.h        |  4 ++
 kernel/rcu/tree_plugin.h | 82 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 51f24ecd94b2..caadfec994f3 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -87,6 +87,7 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_data, rcu_data) = {
 	.dynticks = ATOMIC_INIT(RCU_DYNTICK_CTRL_CTR),
 #ifdef CONFIG_RCU_NOCB_CPU
 	.cblist.flags = SEGCBLIST_SOFTIRQ_ONLY,
+	.nocb_local_lock =  INIT_LOCAL_LOCK(nocb_local_lock),
 #endif
 };
 static struct rcu_state rcu_state = {
@@ -2853,10 +2854,12 @@ static void rcu_cpu_kthread(unsigned int cpu)
 {
 	unsigned int *statusp = this_cpu_ptr(&rcu_data.rcu_cpu_kthread_status);
 	char work, *workp = this_cpu_ptr(&rcu_data.rcu_cpu_has_work);
+	struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
 	int spincnt;
 
 	trace_rcu_utilization(TPS("Start CPU kthread at rcu_run"));
 	for (spincnt = 0; spincnt < 10; spincnt++) {
+		rcu_nocb_local_lock(rdp);
 		local_bh_disable();
 		*statusp = RCU_KTHREAD_RUNNING;
 		local_irq_disable();
@@ -2866,6 +2869,7 @@ static void rcu_cpu_kthread(unsigned int cpu)
 		if (work)
 			rcu_core();
 		local_bh_enable();
+		rcu_nocb_local_unlock(rdp);
 		if (*workp == 0) {
 			trace_rcu_utilization(TPS("End CPU kthread at rcu_wait"));
 			*statusp = RCU_KTHREAD_WAITING;
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index 305cf6aeb408..aa6831255fec 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -210,6 +210,8 @@ struct rcu_data {
 	struct timer_list nocb_timer;	/* Enforce finite deferral. */
 	unsigned long nocb_gp_adv_time;	/* Last call_rcu() CB adv (jiffies). */
 
+	local_lock_t nocb_local_lock;
+
 	/* The following fields are used by call_rcu, hence own cacheline. */
 	raw_spinlock_t nocb_bypass_lock ____cacheline_internodealigned_in_smp;
 	struct rcu_cblist nocb_bypass;	/* Lock-contention-bypass CB list. */
@@ -445,6 +447,8 @@ static void rcu_nocb_unlock(struct rcu_data *rdp);
 static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
 				       unsigned long flags);
 static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp);
+static void rcu_nocb_local_lock(struct rcu_data *rdp);
+static void rcu_nocb_local_unlock(struct rcu_data *rdp);
 #ifdef CONFIG_RCU_NOCB_CPU
 static void __init rcu_organize_nocb_kthreads(void);
 #define rcu_nocb_lock_irqsave(rdp, flags)				\
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 0ff5e4fb933e..b1487cac9250 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -21,6 +21,17 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
 	return lockdep_is_held(&rdp->nocb_lock);
 }
 
+static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
+{
+	return lockdep_is_held(
+#ifdef CONFIG_PREEMPT_RT
+		&rdp->nocb_local_lock.lock
+#else
+		&rdp->nocb_local_lock
+#endif
+	);
+}
+
 static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
 {
 	/* Race on early boot between thread creation and assignment */
@@ -38,7 +49,10 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
 {
 	return 0;
 }
-
+static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
+{
+	return 0;
+}
 static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
 {
 	return false;
@@ -46,23 +60,44 @@ static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
 
 #endif /* #ifdef CONFIG_RCU_NOCB_CPU */
 
+/*
+ * Is a local read of the rdp's offloaded state safe and stable?
+ * See rcu_nocb_local_lock() & family.
+ */
+static inline bool rcu_local_offload_access_safe(struct rcu_data *rdp)
+{
+	if (!preemptible())
+		return true;
+
+	if (is_pcpu_safe()) {
+		if (!IS_ENABLED(CONFIG_RCU_NOCB))
+			return true;
+
+		return rcu_lockdep_is_held_nocb_local(rdp);
+	}
+
+	return false;
+}
+
 static bool rcu_rdp_is_offloaded(struct rcu_data *rdp)
 {
 	/*
-	 * In order to read the offloaded state of an rdp is a safe
-	 * and stable way and prevent from its value to be changed
-	 * under us, we must either hold the barrier mutex, the cpu
-	 * hotplug lock (read or write) or the nocb lock. Local
-	 * non-preemptible reads are also safe. NOCB kthreads and
-	 * timers have their own means of synchronization against the
-	 * offloaded state updaters.
+	 * In order to read the offloaded state of an rdp is a safe and stable
+	 * way and prevent from its value to be changed under us, we must either...
 	 */
 	RCU_LOCKDEP_WARN(
+		// ...hold the barrier mutex...
 		!(lockdep_is_held(&rcu_state.barrier_mutex) ||
+		  // ... the cpu hotplug lock (read or write)...
 		  (IS_ENABLED(CONFIG_HOTPLUG_CPU) && lockdep_is_cpus_held()) ||
+		  // ... or the NOCB lock.
 		  rcu_lockdep_is_held_nocb(rdp) ||
+		  // Local reads still require the local state to remain stable
+		  // (preemption disabled / local lock held)
 		  (rdp == this_cpu_ptr(&rcu_data) &&
-		   !(IS_ENABLED(CONFIG_PREEMPT_COUNT) && preemptible())) ||
+		   rcu_local_offload_access_safe(rdp)) ||
+		  // NOCB kthreads and timers have their own means of synchronization
+		  // against the offloaded state updaters.
 		  rcu_current_is_nocb_kthread(rdp)),
 		"Unsafe read of RCU_NOCB offloaded state"
 	);
@@ -1629,6 +1664,22 @@ static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
 	}
 }
 
+/*
+ * The invocation of rcu_core() within the RCU core kthreads remains preemptible
+ * under PREEMPT_RT, thus the offload state of a CPU could change while
+ * said kthreads are preempted. Prevent this from happening by protecting the
+ * offload state with a local_lock().
+ */
+static void rcu_nocb_local_lock(struct rcu_data *rdp)
+{
+	local_lock(&rcu_data.nocb_local_lock);
+}
+
+static void rcu_nocb_local_unlock(struct rcu_data *rdp)
+{
+	local_unlock(&rcu_data.nocb_local_lock);
+}
+
 /* Lockdep check that ->cblist may be safely accessed. */
 static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp)
 {
@@ -2396,6 +2447,7 @@ static int rdp_offload_toggle(struct rcu_data *rdp,
 	if (rdp->nocb_cb_sleep)
 		rdp->nocb_cb_sleep = false;
 	rcu_nocb_unlock_irqrestore(rdp, flags);
+	rcu_nocb_local_unlock(rdp);
 
 	/*
 	 * Ignore former value of nocb_cb_sleep and force wake up as it could
@@ -2427,6 +2479,7 @@ static long rcu_nocb_rdp_deoffload(void *arg)
 
 	pr_info("De-offloading %d\n", rdp->cpu);
 
+	rcu_nocb_local_lock(rdp);
 	rcu_nocb_lock_irqsave(rdp, flags);
 	/*
 	 * Flush once and for all now. This suffices because we are
@@ -2509,6 +2562,7 @@ static long rcu_nocb_rdp_offload(void *arg)
 	 * Can't use rcu_nocb_lock_irqsave() while we are in
 	 * SEGCBLIST_SOFTIRQ_ONLY mode.
 	 */
+	rcu_nocb_local_lock(rdp);
 	raw_spin_lock_irqsave(&rdp->nocb_lock, flags);
 
 	/*
@@ -2868,6 +2922,16 @@ static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
 	local_irq_restore(flags);
 }
 
+/* No ->nocb_local_lock to acquire. */
+static void rcu_nocb_local_lock(struct rcu_data *rdp)
+{
+}
+
+/* No ->nocb_local_lock to release. */
+static void rcu_nocb_local_unlock(struct rcu_data *rdp)
+{
+}
+
 /* Lockdep check that ->cblist may be safely accessed. */
 static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp)
 {
-- 
2.25.1



From efault at gmx.de  Fri Aug  6 18:42:28 2021
From: efault at gmx.de (Mike Galbraith)
Date: Sat, 07 Aug 2021 03:42:28 +0200
Subject: [PATCH v2 2/4] sched: Introduce is_pcpu_safe()
In-Reply-To: <20210807005807.1083943-3-valentin.schneider@arm.com>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
 <20210807005807.1083943-3-valentin.schneider@arm.com>
Message-ID: <800ff941e3ec86ea1397cddf8ecea3d4a17c55dc.camel@gmx.de>

On Sat, 2021-08-07 at 01:58 +0100, Valentin Schneider wrote:
>
> +static inline bool is_pcpu_safe(void)

Nit: seems odd to avoid spelling it out to save two characters, percpu
is word like, rolls off the ole tongue better than p-c-p-u.

	-Mike



From jeremy.linton at arm.com  Fri Aug  6 19:55:27 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri, 6 Aug 2021 21:55:27 -0500
Subject: [PATCH 2/3] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210806222151.GA1892781@bjorn-Precision-5520>
References: <20210806222151.GA1892781@bjorn-Precision-5520>
Message-ID: <51a11c89-d49b-7367-a75c-13016a2ea5d9@arm.com>

Hi,

On 8/6/21 5:21 PM, Bjorn Helgaas wrote:
> On Thu, Aug 05, 2021 at 04:11:59PM -0500, Jeremy Linton wrote:
>> The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
>> standard because its PCIe config space isn't ECAM compliant and is
>> split into two parts. One part for the root port registers and a
>> moveable window which points at a given device's 4K config space.
>> Thus it doesn't have a MCFG (and really any MCFG provided would be
>> nonsense anyway). As Linux doesn't support the PCIe SMCCC standard
>> we key off a Linux specific host bridge _DSD to add custom ECAM
>> ops and cfgres. The cfg op selects between those two regions, as
>> well as disallowing problematic accesses, particularly if the link
>> is down because there isn't an attached device.
> 
> I'm not sure SMCCC is *really* relevant here.  If it is, an expansion
> of the acronym and a link to a spec would be helpful.
> 
> But AFAICT the only important thing here is that it doesn't have
> standard ECAM, and we're going to work around that.

I will reword it a bit.

> 
> I don't see anything about _DSD in this series.

That is the "linux,pci-quirk" in the next patch.

> 
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>>   drivers/pci/controller/Makefile            |  1 +
>>   drivers/pci/controller/pcie-brcmstb-acpi.c | 77 ++++++++++++++++++++++
>>   include/linux/pci-ecam.h                   |  1 +
>>   3 files changed, 79 insertions(+)
>>   create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
>>
>> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
>> index aaf30b3dcc14..65aa6fd3ed89 100644
>> --- a/drivers/pci/controller/Makefile
>> +++ b/drivers/pci/controller/Makefile
>> @@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
>>   obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
>>   obj-$(CONFIG_ARM64) += pci-thunder-pem.o
>>   obj-$(CONFIG_ARM64) += pci-xgene.o
>> +obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
>>   endif
>>   endif
>> diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
>> new file mode 100644
>> index 000000000000..76944876155f
>> --- /dev/null
>> +++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
>> @@ -0,0 +1,77 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * ACPI quirks for Brcm2711 PCIe host controller
>> + * As used on the Raspberry Pi Compute Module 4
>> + *
>> + * Copyright (C) 2021 Arm Ltd.
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/pci.h>
>> +#include <linux/pci-acpi.h>
> 
> Do we use something from pci-acpi.h?

Good catch.

> 
>> +#include <linux/pci-ecam.h>
>> +#include "../pci.h"
>> +#include "pcie-brcmstb.h"
>> +
>> +static int brcm_acpi_init(struct pci_config_window *cfg)
>> +{
>> +	/*
>> +	 * This platform doesn't technically have anything that could be called
>> +	 * ECAM. Its config region has root port specific registers between
>> +	 * standard PCIe defined config registers. Thus the region setup by the
>> +	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
>> +	 * but the footprint isn't a nice power of 2 (40k). For purposes of
>> +	 * mapping the config region we are just going to squash the standard
>> +	 * and nonstandard registers together rather than mapping them
>> +	 * separately. This code simply honors the quirk provided base+size
>> +	 * instead.
>> +	 */
>> +	iounmap(cfg->win);
>> +	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
>> +	if (!cfg->win)
>> +		goto err_exit;
>> +
>> +	/* MSI is nonstandard as well */
>> +	pci_no_msi();
>> +
>> +	return 0;
>> +err_exit:
>> +	dev_err(cfg->parent, "PCI: Failed to remap config\n");
>> +	return -ENOMEM;
>> +}
>> +
>> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus, unsigned int devfn,
>> +					int where)
> 
> Rewrap to fit in 80 columns.  81 is just ... weird :)
Sure,
> 
>> +{
>> +	struct pci_config_window *cfg = bus->sysdata;
>> +	void __iomem *base = cfg->win;
>> +	int idx;
>> +	u32 up;
>> +
>> +	/* Accesses to the RC go right to the RC registers if slot==0 */
>> +	if (pci_is_root_bus(bus))
>> +		return PCI_SLOT(devfn) ? NULL : base + where;
>> +
>> +	/* Assure link up before sending request */
>> +	up = readl(base + PCIE_MISC_PCIE_STATUS);
>> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
>> +		return NULL;
>> +
>> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
>> +		return NULL;
> 
> What happens if the link goes down here?  Hopefully that's a
> recoverable error?

This check is intended to verify that something is plugged into the 
first bus/slot before attempting to probe it. If nothing is plugged in 
bad things (TM) happen without this check.

But, you sparked my curiosity. I've had some reasonable luck with error 
recovery with a number of those cheap pcie->pcie switches that passively 
route PCIe over USB3 cables when plugged into this thing. So, I tried 
hotpluging the first one to see what happens.

Game over!  :)

Linux was nice enough to tell me it couldn't change the power state back 
to active, but it looks like the link state actually recovered. OTOH, 
the downstream switch appeared to need reconfiguration even though it 
was on a separate power domain. Given, I booted the machine off a NVMe 
drive plugged into that switch, I got another nice screen full of blk_mq 
errors before it officially passed on.

So, the link appears to recover, but that doesn't appear to be enough to 
make the downstream devices recoverable.

Thanks,


> 
>> +	/* For devices, write to the config space index register */
>> +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
>> +	writel(idx, base + PCIE_EXT_CFG_INDEX);
>> +	return base + PCIE_EXT_CFG_DATA + where;
>> +}
>> +
>> +const struct pci_ecam_ops bcm2711_pcie_ops = {
>> +	.init		= brcm_acpi_init,
>> +	.bus_shift	= 1,
>> +	.pci_ops	= {
>> +		.map_bus	= brcm_pcie_map_conf2,
>> +		.read		= pci_generic_config_read,
>> +		.write		= pci_generic_config_write,
>> +	}
>> +};
>> diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
>> index adea5a4771cf..a5de0285bb7f 100644
>> --- a/include/linux/pci-ecam.h
>> +++ b/include/linux/pci-ecam.h
>> @@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
>>   extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
>>   extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
>>   extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
>> +extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
>>   #endif
>>   
>>   #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
>> -- 
>> 2.31.1
>>



From hsin-hsiung.wang at mediatek.com  Fri Aug  6 20:28:51 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-hsiung Wang)
Date: Sat, 7 Aug 2021 11:28:51 +0800
Subject: [PATCH v10 4/5] spmi: mediatek: Add support for MT8195
In-Reply-To: <162827215909.1975443.852277412377742323@swboyd.mtv.corp.google.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
 <1627972461-2627-5-git-send-email-hsin-hsiung.wang@mediatek.com>
 <162827215909.1975443.852277412377742323@swboyd.mtv.corp.google.com>
Message-ID: <1628306931.11590.0.camel@mtksdaap41>

Hi,

On Fri, 2021-08-06 at 10:49 -0700, Stephen Boyd wrote:
> Quoting Hsin-Hsiung Wang (2021-08-02 23:34:20)
> > From: Henry Chen <henryc.chen at mediatek.com>
> > 
> > Add spmi support for MT8195.
> > 
> > Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
> 
> Missing Signed-off-by from hsin-hsiung.wang here
> 

Sorry for the missing. I will add it in the next patch.

Thanks.

> > ---
> > changes since v9:
> > - No change.
> > ---
> >  drivers/spmi/spmi-mtk-pmif.c | 90 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 90 insertions(+)
> > 
> > diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
> > index 94c45d46ab0c..0c320801c9d5 100644
> > --- a/drivers/spmi/spmi-mtk-pmif.c
> > +++ b/drivers/spmi/spmi-mtk-pmif.c
> > @@ -348,6 +427,14 @@ static const struct pmif_data mt6873_pmif_arb = {
> >         .soc_chan = 2,
> >  };
> >  
> > +static const struct pmif_data mt8195_pmif_arb[] = {
> 
> This is an array of type pmif_data.
> 
> > +       {
> > +               .regs = mt8195_regs,
> > +               .spmimst_regs = mt8195_spmi_regs,
> > +               .soc_chan = 2,
> > +       },
> > +};
> > +
> >  static int mtk_spmi_probe(struct platform_device *pdev)
> >  {
> >         struct pmif *arb;
> > @@ -444,6 +531,9 @@ static const struct of_device_id mtk_spmi_match_table[] = {
> >         {
> >                 .compatible = "mediatek,mt6873-spmi",
> >                 .data = &mt6873_pmif_arb,
> 
> mt6873_pmif_arb is not an array, see the context header above.
> 
> How does this work? Has this been tested?
> 
> > +       }, {
> > +               .compatible = "mediatek,mt8195-spmi",
> > +               .data = &mt8195_pmif_arb,
> >         }, {
> >                 /* sentinel */
> >         },
> > -- 
> > 2.18.0
> >


From hsin-hsiung.wang at mediatek.com  Fri Aug  6 20:51:18 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-hsiung Wang)
Date: Sat, 7 Aug 2021 11:51:18 +0800
Subject: [PATCH v10 4/5] spmi: mediatek: Add support for MT8195
In-Reply-To: <162827215909.1975443.852277412377742323@swboyd.mtv.corp.google.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
 <1627972461-2627-5-git-send-email-hsin-hsiung.wang@mediatek.com>
 <162827215909.1975443.852277412377742323@swboyd.mtv.corp.google.com>
Message-ID: <1628308278.23588.3.camel@mtksdaap41>

Hi,
sorry for missing other comments, I will confirm it internally and
update it.

Thanks a lot.

On Fri, 2021-08-06 at 10:49 -0700, Stephen Boyd wrote:
> Quoting Hsin-Hsiung Wang (2021-08-02 23:34:20)
> > From: Henry Chen <henryc.chen at mediatek.com>
> > 
> > Add spmi support for MT8195.
> > 
> > Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
> 
> Missing Signed-off-by from hsin-hsiung.wang here
> 
> > ---
> > changes since v9:
> > - No change.
> > ---
> >  drivers/spmi/spmi-mtk-pmif.c | 90 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 90 insertions(+)
> > 
> > diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
> > index 94c45d46ab0c..0c320801c9d5 100644
> > --- a/drivers/spmi/spmi-mtk-pmif.c
> > +++ b/drivers/spmi/spmi-mtk-pmif.c
> > @@ -348,6 +427,14 @@ static const struct pmif_data mt6873_pmif_arb = {
> >         .soc_chan = 2,
> >  };
> >  
> > +static const struct pmif_data mt8195_pmif_arb[] = {
> 
> This is an array of type pmif_data.
> 
> > +       {
> > +               .regs = mt8195_regs,
> > +               .spmimst_regs = mt8195_spmi_regs,
> > +               .soc_chan = 2,
> > +       },
> > +};
> > +
> >  static int mtk_spmi_probe(struct platform_device *pdev)
> >  {
> >         struct pmif *arb;
> > @@ -444,6 +531,9 @@ static const struct of_device_id mtk_spmi_match_table[] = {
> >         {
> >                 .compatible = "mediatek,mt6873-spmi",
> >                 .data = &mt6873_pmif_arb,
> 
> mt6873_pmif_arb is not an array, see the context header above.
> 
> How does this work? Has this been tested?
> 
> > +       }, {
> > +               .compatible = "mediatek,mt8195-spmi",
> > +               .data = &mt8195_pmif_arb,
> >         }, {
> >                 /* sentinel */
> >         },
> > -- 
> > 2.18.0
> >


From tzimmermann at suse.de  Fri Aug  6 23:51:14 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Sat, 7 Aug 2021 08:51:14 +0200
Subject: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
In-Reply-To: <BY5PR11MB4182FBA1D240321F7D9BEC7D8CF29@BY5PR11MB4182.namprd11.prod.outlook.com>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <YQlbFjbrnyeWv7QP@ravnborg.org>
 <BY5PR11MB41822706053ADEE927E34E628CF09@BY5PR11MB4182.namprd11.prod.outlook.com>
 <4dbc29d7-5f88-e3ac-5dab-e2dc5c6a703e@suse.de>
 <BY5PR11MB4182FBA1D240321F7D9BEC7D8CF29@BY5PR11MB4182.namprd11.prod.outlook.com>
Message-ID: <8d10b841-8960-f782-4ed3-d15fa9761dce@suse.de>

Hi

Am 06.08.21 um 01:59 schrieb Chrisanthus, Anitha:
> Hi Thomas,
> 
>> -----Original Message-----
>> From: Thomas Zimmermann <tzimmermann at suse.de>
>> Sent: Wednesday, August 4, 2021 12:11 AM
>> To: Chrisanthus, Anitha <anitha.chrisanthus at intel.com>; Sam Ravnborg
>> <sam at ravnborg.org>
>> Cc: daniel at ffwll.ch; airlied at linux.ie; alexander.deucher at amd.com;
>> christian.koenig at amd.com; liviu.dudau at arm.com; brian.starkey at arm.com;
>> bbrezillon at kernel.org; nicolas.ferre at microchip.com;
>> maarten.lankhorst at linux.intel.com; mripard at kernel.org; stefan at agner.ch;
>> alison.wang at nxp.com; patrik.r.jakobsson at gmail.com; robdclark at gmail.com;
>> Dea, Edmund J <edmund.j.dea at intel.com>; sean at poorly.run;
>> shawnguo at kernel.org; s.hauer at pengutronix.de; kernel at pengutronix.de;
>> jyri.sarha at iki.fi; tomba at kernel.org; Dan.Sneddon at microchip.com;
>> tomi.valkeinen at ideasonboard.com; amd-gfx at lists.freedesktop.org; dri-
>> devel at lists.freedesktop.org; linux-arm-kernel at lists.infradead.org; linux-arm-
>> msm at vger.kernel.org; freedreno at lists.freedesktop.org
>> Subject: Re: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
>>
>> Hi
>>
>> Am 03.08.21 um 20:36 schrieb Chrisanthus, Anitha:
>>> Hi Thomas,
>>> Can you please hold off on applying the kmb patch, I am seeing some issues
>> while testing. Modetest works, but video playback only plays once, and it fails
>> the second time with this patch.
>>
>> Sounds a bit like the testing issue at [1]. For testing, you need the
>> latest drm-misc-next or drm-tip. Specifically, you need commit
>> 1e4cd78ed493 ("drm: Don't test for IRQ support in VBLANK ioctls").
> 
> 
> You are right, with the above patch video plays fine. It's all good now! Sorry about the confusion.

Thanks for trying. Can I add your Tested-by tag?

Best regards
Thomas

>>
>> Let me know whether this works for you.
>>
>> Best regards
>> Thomas
>>
>> [1] https://patchwork.freedesktop.org/patch/447057/?series=93078&rev=1
>>
>>>
>>> Thanks,
>>> Anitha
>>>
>>>
>>>> -----Original Message-----
>>>> From: Sam Ravnborg <sam at ravnborg.org>
>>>> Sent: Tuesday, August 3, 2021 8:05 AM
>>>> To: Thomas Zimmermann <tzimmermann at suse.de>
>>>> Cc: daniel at ffwll.ch; airlied at linux.ie; alexander.deucher at amd.com;
>>>> christian.koenig at amd.com; liviu.dudau at arm.com;
>> brian.starkey at arm.com;
>>>> bbrezillon at kernel.org; nicolas.ferre at microchip.com;
>>>> maarten.lankhorst at linux.intel.com; mripard at kernel.org;
>> stefan at agner.ch;
>>>> alison.wang at nxp.com; patrik.r.jakobsson at gmail.com; Chrisanthus, Anitha
>>>> <anitha.chrisanthus at intel.com>; robdclark at gmail.com; Dea, Edmund J
>>>> <edmund.j.dea at intel.com>; sean at poorly.run; shawnguo at kernel.org;
>>>> s.hauer at pengutronix.de; kernel at pengutronix.de; jyri.sarha at iki.fi;
>>>> tomba at kernel.org; Dan.Sneddon at microchip.com;
>>>> tomi.valkeinen at ideasonboard.com; amd-gfx at lists.freedesktop.org; dri-
>>>> devel at lists.freedesktop.org; linux-arm-kernel at lists.infradead.org; linux-
>> arm-
>>>> msm at vger.kernel.org; freedreno at lists.freedesktop.org
>>>> Subject: Re: [PATCH v2 00/14] drm: Make DRM's IRQ helpers legacy
>>>>
>>>> Hi Thomas,
>>>>
>>>> On Tue, Aug 03, 2021 at 11:06:50AM +0200, Thomas Zimmermann wrote:
>>>>> DRM's IRQ helpers are only helpful for old, non-KMS drivers. Move
>>>>> the code behind CONFIG_DRM_LEGACY. Convert KMS drivers to Linux
>>>>> IRQ interfaces.
>>>>>
>>>>> DRM provides IRQ helpers for setting up, receiving and removing IRQ
>>>>> handlers. It's an abstraction over plain Linux functions. The code
>>>>> is mid-layerish with several callbacks to hook into the rsp drivers.
>>>>> Old UMS driver have their interrupts enabled via ioctl, so these
>>>>> abstractions makes some sense. Modern KMS manage all their interrupts
>>>>> internally. Using the DRM helpers adds indirection without benefits.
>>>>>
>>>>> Most KMS drivers already use Linux IRQ functions instead of DRM's
>>>>> abstraction layer. Patches 1 to 12 convert the remaining ones.
>>>>> The patches also resolve a bug for devices without assigned interrupt
>>>>> number. DRM helpers don't test for IRQ_NOTCONNECTED, so drivers do
>>>>> not detect if the device has no interrupt assigned.
>>>>>
>>>>> Patch 13 removes an unused function.
>>>>>
>>>>> Patch 14 moves the DRM IRQ helpers behind CONFIG_DRM_LEGACY. Only
>>>>> the old non-KMS drivers still use the functionality.
>>>>>
>>>>> v2:
>>>>> 	* drop IRQ_NOTCONNECTED test from atmel-hlcdc (Sam)
>>>>> 	* use devm_request_irq() in atmel-hlcdc (Sam)
>>>>> 	* unify variable names in arm/hlcdc (Sam)
>>>>>
>>>>> Thomas Zimmermann (14):
>>>>
>>>> The following patches are all:
>>>> Acked-by: Sam Ravnborg <sam at ravnborg.org>
>>>>
>>>>>     drm/fsl-dcu: Convert to Linux IRQ interfaces
>>>>>     drm/gma500: Convert to Linux IRQ interfaces
>>>>>     drm/kmb: Convert to Linux IRQ interfaces
>>>>>     drm/msm: Convert to Linux IRQ interfaces
>>>>>     drm/mxsfb: Convert to Linux IRQ interfaces
>>>>>     drm/tidss: Convert to Linux IRQ interfaces
>>>>>     drm/vc4: Convert to Linux IRQ interfaces
>>>>>     drm: Remove unused devm_drm_irq_install()
>>>>
>>>> The remaining patches I either skipped or already had a feedback from
>>>> me or I asked a question.
>>>>
>>>> 	Sam
>>
>> --
>> Thomas Zimmermann
>> Graphics Driver Developer
>> SUSE Software Solutions Germany GmbH
>> Maxfeldstr. 5, 90409 N?rnberg, Germany
>> (HRB 36809, AG N?rnberg)
>> Gesch?ftsf?hrer: Felix Imend?rffer
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Felix Imend?rffer

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210807/8db3352f/attachment.sig>

From lkp at intel.com  Sat Aug  7 01:02:40 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 7 Aug 2021 16:02:40 +0800
Subject: [xlnx:xlnx_rebase_v5.10 724/1759] spi-zynqmp-gqspi.c:undefined
 reference to `update_stripe'
Message-ID: <202108071626.jSctbrae-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   ece61f55f53e04f92c815aead9564066efb19807
commit: 5d37ab2cf69a5d4367f49fca798d78e4be66a43b [724/1759] spi: Update ZynqMP and Versal QSPI controller driver
config: xtensa-randconfig-r005-20210804 (attached as .config)
compiler: xtensa-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/5d37ab2cf69a5d4367f49fca798d78e4be66a43b
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 5d37ab2cf69a5d4367f49fca798d78e4be66a43b
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=xtensa SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   xtensa-linux-ld: drivers/spi/spi-zynqmp-gqspi.o: in function `zynqmp_qspi_write_op.constprop.0':
>> spi-zynqmp-gqspi.c:(.text+0x13fc): undefined reference to `update_stripe'
   xtensa-linux-ld: drivers/spi/spi-zynqmp-gqspi.o: in function `zynqmp_qspi_exec_op':
   spi-zynqmp-gqspi.c:(.text+0x1680): undefined reference to `update_stripe'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 30757 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210807/7b691a4a/attachment-0001.gz>

From patchwork-bot+netdevbpf at kernel.org  Sat Aug  7 01:50:07 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Sat, 07 Aug 2021 08:50:07 +0000
Subject: [PATCH] net: ethernet: stmmac: Do not use unreachable() in
 ipq806x_gmac_probe()
In-Reply-To: <20210806191339.576318-1-nathan@kernel.org>
References: <20210806191339.576318-1-nathan@kernel.org>
Message-ID: <162832620705.3915.11584546852979312079.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (refs/heads/master):

On Fri,  6 Aug 2021 12:13:40 -0700 you wrote:
> When compiling with clang in certain configurations, an objtool warning
> appears:
> 
> drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.o: warning: objtool:
> ipq806x_gmac_probe() falls through to next function phy_modes()
> 
> This happens because the unreachable annotation in the third switch
> statement is not eliminated. The compiler should know that the first
> default case would prevent the second and third from being reached as
> the comment notes but sanitizer options can make it harder for the
> compiler to reason this out.
> 
> [...]

Here is the summary with links:
  - net: ethernet: stmmac: Do not use unreachable() in ipq806x_gmac_probe()
    https://git.kernel.org/netdev/net-next/c/4367355dd909

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From peng.fan at oss.nxp.com  Sat Aug  7 02:45:34 2021
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sat,  7 Aug 2021 17:45:34 +0800
Subject: [PATCH 0/3] arm64: dts: imx: pmu update 
Message-ID: <20210807094537.20290-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Update pmu compatible
Drop interrupt affinity

Peng Fan (3):
  arm64: dts: imx8mm: update pmu compatible
  arm64: dts: imx8qxp: update pmu compatible
  arm64: dts: imx8m: drop interrupt-affinity for pmu

 arch/arm64/boot/dts/freescale/imx8mm.dtsi  | 3 +--
 arch/arm64/boot/dts/freescale/imx8mn.dtsi  | 1 -
 arch/arm64/boot/dts/freescale/imx8mp.dtsi  | 1 -
 arch/arm64/boot/dts/freescale/imx8mq.dtsi  | 1 -
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 2 +-
 5 files changed, 2 insertions(+), 6 deletions(-)

-- 
2.30.0



From peng.fan at oss.nxp.com  Sat Aug  7 02:45:35 2021
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sat,  7 Aug 2021 17:45:35 +0800
Subject: [PATCH 1/3] arm64: dts: imx8mm: update pmu compatible
In-Reply-To: <20210807094537.20290-1-peng.fan@oss.nxp.com>
References: <20210807094537.20290-1-peng.fan@oss.nxp.com>
Message-ID: <20210807094537.20290-2-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX8MM features four Cortex-A53 cores, update the compatible
to use more accurate "arm,cortex-a53-pmu"

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 49c46bbf8d9c..e878eefd8f78 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -192,7 +192,7 @@ psci {
 	};
 
 	pmu {
-		compatible = "arm,armv8-pmuv3";
+		compatible = "arm,cortex-a53-pmu";
 		interrupts = <GIC_PPI 7
 			     (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>;
-- 
2.30.0



From peng.fan at oss.nxp.com  Sat Aug  7 02:45:36 2021
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sat,  7 Aug 2021 17:45:36 +0800
Subject: [PATCH 2/3] arm64: dts: imx8qxp: update pmu compatible
In-Reply-To: <20210807094537.20290-1-peng.fan@oss.nxp.com>
References: <20210807094537.20290-1-peng.fan@oss.nxp.com>
Message-ID: <20210807094537.20290-3-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX8QXP features four Cortex-A35 cores, use more accurate
compatible.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index a625fb6bdc62..617618edf77e 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -141,7 +141,7 @@ dsp_reserved: dsp at 92400000 {
 	};
 
 	pmu {
-		compatible = "arm,armv8-pmuv3";
+		compatible = "arm,cortex-a35-pmu";
 		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-- 
2.30.0



From peng.fan at oss.nxp.com  Sat Aug  7 02:45:37 2021
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sat,  7 Aug 2021 17:45:37 +0800
Subject: [PATCH 3/3] arm64: dts: imx8m: drop interrupt-affinity for pmu
In-Reply-To: <20210807094537.20290-1-peng.fan@oss.nxp.com>
References: <20210807094537.20290-1-peng.fan@oss.nxp.com>
Message-ID: <20210807094537.20290-4-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX8M use PPI for pmu, interrupt-affinity is not needed.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mm.dtsi | 1 -
 arch/arm64/boot/dts/freescale/imx8mn.dtsi | 1 -
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 1 -
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 1 -
 4 files changed, 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index e878eefd8f78..2f632e8ca388 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -195,7 +195,6 @@ pmu {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts = <GIC_PPI 7
 			     (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-		interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>;
 	};
 
 	timer {
diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index a5822d49c6ed..da6c942fb7f9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -190,7 +190,6 @@ pmu {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts = <GIC_PPI 7
 			     (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-		interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>;
 	};
 
 	psci {
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index f4eaab3ecf03..7360cb377293 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -139,7 +139,6 @@ pmu {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts = <GIC_PPI 7
 			     (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
-		interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>;
 	};
 
 	psci {
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 91df9c5350ae..5923d15a217b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -193,7 +193,6 @@ pmu {
 		compatible = "arm,cortex-a53-pmu";
 		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-parent = <&gic>;
-		interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>;
 	};
 
 	psci {
-- 
2.30.0



From peng.fan at oss.nxp.com  Sat Aug  7 03:45:17 2021
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Sat,  7 Aug 2021 18:45:17 +0800
Subject: [PATCH] arm64: dts: imx8qm: add smmu node
Message-ID: <20210807104517.24066-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

i.MX8QM has an iommu unit: SMMU-V2(mmu-500), add it.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qm.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
index aebbe2b84aa1..b8ffd5be6a3e 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
@@ -165,6 +165,22 @@ iomuxc: pinctrl {
 
 	};
 
+	smmu: iommu at 51400000 {
+		compatible = "arm,mmu-500";
+		reg = <0 0x51400000 0 0x40000>;
+		#iommu-cells = <2>;
+		#global-interrupts = <1>;
+		interrupts = <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
+			     <0 32 4>;
+	};
+
 	/* sorted in register address */
 	#include "imx8-ss-img.dtsi"
 	#include "imx8-ss-dma.dtsi"
-- 
2.30.0



From maz at kernel.org  Sat Aug  7 03:52:15 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 07 Aug 2021 11:52:15 +0100
Subject: [RESEND PATCH] clocksource/arm_arch_timer: Fix masking for high
 freq counters
In-Reply-To: <20210806182126.2842876-1-oupton@google.com>
References: <20210806182126.2842876-1-oupton@google.com>
Message-ID: <87pmup1q8w.wl-maz@kernel.org>

Hi Oliver,

On Fri, 06 Aug 2021 19:21:26 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Unfortunately, the architecture provides no means to determine the bit
> width of the system counter. However, we do know the following from the
> specification:
> 
>  - the system counter is at least 56 bits wide
>  - Roll-over time of not less than 40 years
> 
> To date, the arch timer driver has depended on the first property,
> assuming any system counter to be 56 bits wide and masking off the rest.
> However, combining a narrow clocksource mask with a high frequency
> counter could result in prematurely wrapping the system counter by a
> significant margin. For example, a 56 bit wide, 1GHz system counter
> would wrap in a mere 2.28 years!
> 
> This is a problem for two reasons: v8.6+ implementations are required to
> provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> implementers may select a counter frequency of their choosing.
> 
> Fix the issue by deriving a valid clock mask based on the second
> property from above. Set the floor at 56 bits, since we know no system
> counter is narrower than that.
> 
> Suggested-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
> This patch was tested with QEMU, tweaked to provide a 1GHz system
> counter frequency, as I could not easily figure out how to tweak the
> base FVP to provide a 1GHz counter.

<FVP>
"bp.refcounter.base_frequency" is the property you are looking for. In
general, passing --list-params to the model reveals a treasure trove
of weird and wonderful options that can be used to configure the model
to your liking.
</FVP>

> 
> Parent commit: 0c32706dac1b ("arm64: stacktrace: avoid tracing arch_stack_walk()")
> 
>  drivers/clocksource/arm_arch_timer.c | 28 ++++++++++++++++++++++++++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index be6d741d404c..8c41626a4c8a 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -52,6 +52,12 @@
>  #define CNTV_TVAL	0x38
>  #define CNTV_CTL	0x3c
>  
> +/*
> + * The minimum amount of time a generic timer is guaranteed to not roll over

nit: s/timer/counter/

> + * (40 years)

For later reference, could you add the section of the ARMv8 ARM where
this is mentioned? Something like 'ARM DDI 0487G.a D11.1.2 ("The
system counter")', either here or in the comment further down.

> + */
> +#define MIN_ROLLOVER_SECS	(40ULL * 365 * 24 * 3600)
> +
>  static unsigned arch_timers_present __initdata;
>  
>  static void __iomem *arch_counter_base __ro_after_init;
> @@ -1004,9 +1010,24 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
>  	return &arch_timer_kvm_info;
>  }
>  
> +/*
> + * Makes an educated guess at a valid counter width based on the Generic Timer
> + * specification. Of note:
> + *   1) the Generic Timer is at least 56 bits wide
> + *   2) a roll-over time of not less than 40 years
> + */
> +static int __init arch_counter_get_width(void)
> +{
> +	u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_get_cntfrq();

That's unfortunately wishful thinking. We have stupidly broken systems
out there that do not set CNTFRQ_EL0, and instead rely on DT
properties to describe the counter frequency. You're likely to end up
with a glorious zero as a result, with interesting consequences...

Use arch_timer_rate instead, which will be set as by the time you
register the counter.

> +
> +	/* guarantee the returned width is within the valid range */
> +	return max(56, min(64, ilog2(min_cycles)));

Maybe better written as "clamp_val(ilog2(min_cycles), 56, 64);".

> +}
> +
>  static void __init arch_counter_register(unsigned type)
>  {
>  	u64 start_count;
> +	int width;
>  
>  	/* Register the CP15 based counter if we have one */
>  	if (type & ARCH_TIMER_TYPE_CP15) {
> @@ -1031,6 +1052,10 @@ static void __init arch_counter_register(unsigned type)
>  		arch_timer_read_counter = arch_counter_get_cntvct_mem;
>  	}
>  
> +	width = arch_counter_get_width();
> +	clocksource_counter.mask = CLOCKSOURCE_MASK(width);
> +	cyclecounter.mask = CLOCKSOURCE_MASK(width);

Since you move this to be computed at runtime, how about dropping the
static initialisation of the mask fields?

> +
>  	if (!arch_counter_suspend_stop)
>  		clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
>  	start_count = arch_timer_read_counter();
> @@ -1040,8 +1065,7 @@ static void __init arch_counter_register(unsigned type)
>  	timecounter_init(&arch_timer_kvm_info.timecounter,
>  			 &cyclecounter, start_count);
>  
> -	/* 56 bits minimum, so we assume worst case rollover */
> -	sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
> +	sched_clock_register(arch_timer_read_counter, width, arch_timer_rate);
>  }
>  
>  static void arch_timer_stop(struct clock_event_device *clk)

Another thing that needs addressing for high frequency counter support
is to move away from TVAL programming and switch to CVAL, as the
maximum deadline we can currently program is 4.2s at 1GHz.

Fun fact: it has the interesting consequence of breaking XGene-1,
which implemented CVAL in terms of TVAL instead of the other way
around (what were these guys thinking?), though I don't think anyone
will notice in practice. I have a preliminary patch on a branch
somewhere that I'll try to dust up and post in the coming days.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From stefan.wahren at i2se.com  Sat Aug  7 04:06:34 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:34 +0200
Subject: [PATCH V2 03/10] dt-bindings: display: bcm2835: add optional property
 power-domains
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-4-git-send-email-stefan.wahren@i2se.com>

The Raspberry Pi boards with BCM283x needs control of the power domains
to get display components running. DT schema warns us that it's used, but not
documented as a optional property:

hdmi at 7e902000: 'power-domains' does not match any of the regexes: ...

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml | 3 +++
 Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml | 3 +++
 Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml  | 3 +++
 Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml  | 3 +++
 4 files changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml
index 3260857..c8b2459 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-dsi0.yaml
@@ -47,6 +47,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
 required:
   - "#clock-cells"
   - compatible
diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml
index 031e35e..48c8cad 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml
@@ -51,6 +51,9 @@ properties:
   dma-names:
     const: audio-rx
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml
index 8a73780..c55a821 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-v3d.yaml
@@ -24,6 +24,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml b/Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml
index 9b24081..5d921e3 100644
--- a/Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml
+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-vec.yaml
@@ -24,6 +24,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:35 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:35 +0200
Subject: [PATCH V2 04/10] mmc: sdhci-iproc: Cap min clock frequency on BCM2711
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-5-git-send-email-stefan.wahren@i2se.com>

From: Nicolas Saenz Julienne <nsaenz at kernel.org>

There is a known bug on BCM2711's SDHCI core integration where the
controller will hang when the difference between the core clock and the
bus clock is too great. Specifically this can be reproduced under the
following conditions:

- No SD card plugged in, polling thread is running, probing cards at
  100 kHz.
- BCM2711's core clock configured at 500MHz or more.

So set 200 kHz as the minimum clock frequency available for that board.

For more information on the issue see this:
https://lore.kernel.org/linux-mmc/20210322185816.27582-1-nsaenz at kernel.org/T/#m11f2783a09b581da6b8a15f302625b43a6ecdeca

Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 drivers/mmc/host/sdhci-iproc.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index cce390f..032bf85 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -173,6 +173,23 @@ static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host)
 		return pltfm_host->clock;
 }
 
+/*
+ * There is a known bug on BCM2711's SDHCI core integration where the
+ * controller will hang when the difference between the core clock and the bus
+ * clock is too great. Specifically this can be reproduced under the following
+ * conditions:
+ *
+ *  - No SD card plugged in, polling thread is running, probing cards at
+ *    100 kHz.
+ *  - BCM2711's core clock configured at 500MHz or more
+ *
+ * So we set 200kHz as the minimum clock frequency available for that SoC.
+ */
+static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
+{
+	return 200000;
+}
+
 static const struct sdhci_ops sdhci_iproc_ops = {
 	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_iproc_get_max_clock,
@@ -271,6 +288,7 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_power = sdhci_set_power_and_bus_voltage,
 	.get_max_clock = sdhci_iproc_get_max_clock,
+	.get_min_clock = sdhci_iproc_bcm2711_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 	.set_uhs_signaling = sdhci_set_uhs_signaling,
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:32 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:32 +0200
Subject: [PATCH V2 01/10] ARM: dts: bcm2711: fix MDIO #address- and #size-cells
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-2-git-send-email-stefan.wahren@i2se.com>

The values of #address-cells and #size-cells are swapped. Fix this
and avoid the following DT schema warnings for mdio at e14:

 #address-cells:0:0: 1 was expected
 #size-cells:0:0: 0 was expected

Fixes: be8af7a9e3cc ("ARM: dts: bcm2711-rpi-4: Enable GENET support")
Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
index b8a4096..a0db9b0 100644
--- a/arch/arm/boot/dts/bcm2711.dtsi
+++ b/arch/arm/boot/dts/bcm2711.dtsi
@@ -532,8 +532,8 @@
 				compatible = "brcm,genet-mdio-v5";
 				reg = <0xe14 0x8>;
 				reg-names = "mdio";
-				#address-cells = <0x0>;
-				#size-cells = <0x1>;
+				#address-cells = <0x1>;
+				#size-cells = <0x0>;
 			};
 		};
 	};
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:39 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:39 +0200
Subject: [PATCH V2 08/10] ARM: dts: Add Raspberry Pi Compute Module 4
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-9-git-send-email-stefan.wahren@i2se.com>

The Raspberry Pi Compute Module 4 (CM4) are SoMs which contain the
following:
  * BCM2711 quad core processor
  * up to 8 GB RAM
  * up to 32 GB eMMC
  * a GPIO expander
  * Gigabit PHY BCM54210PE
  * Wifi/BT module with internal and external antenna

The eMMC and the Wifi/BT module are optional.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi | 113 +++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi

diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi b/arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi
new file mode 100644
index 0000000..a2954d4
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2711.dtsi"
+#include "bcm2711-rpi.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
+
+/ {
+	compatible = "raspberrypi,4-compute-module", "brcm,bcm2711";
+
+	chosen {
+		/* 8250 auxiliary UART instead of pl011 */
+		stdout-path = "serial1:115200n8";
+	};
+
+	sd_io_1v8_reg: sd_io_1v8_reg {
+		compatible = "regulator-gpio";
+		regulator-name = "vdd-sd-io";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-settling-time-us = <5000>;
+		gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
+		states = <1800000 0x1>,
+			 <3300000 0x0>;
+		status = "okay";
+	};
+
+	sd_vcc_reg: sd_vcc_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc-sd";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		enable-active-high;
+		gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&bt {
+	shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
+};
+
+/* EMMC2 is used to drive the eMMC */
+&emmc2 {
+	bus-width = <8>;
+	vqmmc-supply = <&sd_io_1v8_reg>;
+	vmmc-supply = <&sd_vcc_reg>;
+	broken-cd;
+	/* Even the IP block is limited to 100 MHz
+	 * this provides a throughput gain
+	 */
+	mmc-hs200-1_8v;
+	status = "okay";
+};
+
+&expgpio {
+	gpio-line-names = "BT_ON",
+			  "WL_ON",
+			  "PWR_LED_OFF",
+			  "ANT1",
+			  "VDD_SD_IO_SEL",
+			  "CAM_GPIO",
+			  "SD_PWR_ON",
+			  "ANT2";
+
+	ant1: ant1-hog {
+		gpio-hog;
+		gpios = <3 GPIO_ACTIVE_HIGH>;
+		/* internal antenna enabled */
+		output-high;
+		line-name = "ant1";
+	};
+
+	ant2: ant2-hog {
+		gpio-hog;
+		gpios = <7 GPIO_ACTIVE_HIGH>;
+		/* external antenna disabled */
+		output-low;
+		line-name = "ant2";
+	};
+};
+
+&genet {
+	phy-handle = <&phy1>;
+	phy-mode = "rgmii-rxid";
+	status = "okay";
+};
+
+&genet_mdio {
+	phy1: ethernet-phy at 0 {
+		/* No PHY interrupt */
+		reg = <0x0>;
+	};
+};
+
+/* uart0 communicates with the BT module */
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
+	uart-has-rtscts;
+};
+
+/* uart1 is mapped to the pin header */
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_gpio14>;
+	status = "okay";
+};
+
+&wifi_pwrseq {
+	reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:38 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:38 +0200
Subject: [PATCH V2 07/10] dt-bindings: arm: bcm2835: Add Raspberry Pi Compute
 Module 4
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-8-git-send-email-stefan.wahren@i2se.com>

Add the Raspberry Pi Compute Module 4 to DT schema.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
index 230b80d..5dc4824 100644
--- a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
+++ b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
@@ -19,6 +19,7 @@ properties:
         items:
           - enum:
               - raspberrypi,400
+              - raspberrypi,4-compute-module
               - raspberrypi,4-model-b
           - const: brcm,bcm2711
 
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:31 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:31 +0200
Subject: [PATCH V2 00/10] ARM: dts: Add Raspberry Pi CM4 & CM4 IO Board support
Message-ID: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>

This series add support for the Raspberry Pi Compute Module 4 and its
IO board.

Changes in V2:
- drop emmc2bus patch as it affects userspace (thanks to Marc Zyngier)
- tested with CM4 and integrate sdhci patches from Nicolas (just include kHz fixups)
- add Rob's Acked-by
- add HS200 property to emmc2 node for a slight performance gain
- move antenna comment to the proper position

Nicolas Saenz Julienne (2):
  mmc: sdhci-iproc: Cap min clock frequency on BCM2711
  mmc: sdhci-iproc: Set SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711

Stefan Wahren (8):
  ARM: dts: bcm2711: fix MDIO #address- and #size-cells
  ARM: dts: bcm2711-rpi-4-b: fix sd_io_1v8_reg regulator states
  dt-bindings: display: bcm2835: add optional property power-domains
  ARM: dts: bcm283x-rpi: Move Wifi/BT into separate dtsi
  dt-bindings: arm: bcm2835: Add Raspberry Pi Compute Module 4
  ARM: dts: Add Raspberry Pi Compute Module 4
  ARM: dts: Add Raspberry Pi Compute Module 4 IO Board
  arm64: dts: broadcom: Add reference to RPi CM4 IO Board

 .../devicetree/bindings/arm/bcm/bcm2835.yaml       |   1 +
 .../bindings/display/brcm,bcm2835-dsi0.yaml        |   3 +
 .../bindings/display/brcm,bcm2835-hdmi.yaml        |   3 +
 .../bindings/display/brcm,bcm2835-v3d.yaml         |   3 +
 .../bindings/display/brcm,bcm2835-vec.yaml         |   3 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts              |  42 ++-----
 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts           | 138 +++++++++++++++++++++
 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi             | 113 +++++++++++++++++
 arch/arm/boot/dts/bcm2711.dtsi                     |   4 +-
 arch/arm/boot/dts/bcm2835-rpi-zero-w.dts           |  31 ++---
 arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts         |  36 ++----
 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts         |  36 ++----
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts              |  36 ++----
 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi         |  34 +++++
 arch/arm64/boot/dts/broadcom/Makefile              |   1 +
 .../arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts |   2 +
 drivers/mmc/host/sdhci-iproc.c                     |  21 +++-
 18 files changed, 366 insertions(+), 142 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
 create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi
 create mode 100644 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi
 create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts

-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:33 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:33 +0200
Subject: [PATCH V2 02/10] ARM: dts: bcm2711-rpi-4-b: fix sd_io_1v8_reg
 regulator states
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-3-git-send-email-stefan.wahren@i2se.com>

DT schema check complains at sd_io_1v8_reg about the following:

 [1800000, 1, 3300000, 0] is too long
 Additional items are not allowed (3300000, 0 were unexpected)

So fix the states definition.

Fixes: 7dbe8c62ceeb ("ARM: dts: Add minimal Raspberry Pi 4 support")
Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index f24bdd0..abf8298 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -40,8 +40,8 @@
 		regulator-always-on;
 		regulator-settling-time-us = <5000>;
 		gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
-		states = <1800000 0x1
-			  3300000 0x0>;
+		states = <1800000 0x1>,
+			 <3300000 0x0>;
 		status = "okay";
 	};
 
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:37 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:37 +0200
Subject: [PATCH V2 06/10] ARM: dts: bcm283x-rpi: Move Wifi/BT into separate
 dtsi
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-7-git-send-email-stefan.wahren@i2se.com>

A Wifi/BT chip is quite common for the Raspberry Pi boards. So move those
definitions into a separate dtsi in order to avoid copy & paste. This
change was inspired by a vendor tree patch from Phil Elwell.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts      | 38 +++++++-----------------------
 arch/arm/boot/dts/bcm2835-rpi-zero-w.dts   | 31 +++++++-----------------
 arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 36 ++++++----------------------
 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 36 +++++++---------------------
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts      | 36 +++++++---------------------
 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi | 34 ++++++++++++++++++++++++++
 6 files changed, 74 insertions(+), 137 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi

diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index abf8298..c54ba5cf 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -3,6 +3,7 @@
 #include "bcm2711.dtsi"
 #include "bcm2711-rpi.dtsi"
 #include "bcm283x-rpi-usb-peripheral.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
@@ -26,11 +27,6 @@
 		};
 	};
 
-	wifi_pwrseq: wifi-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
-	};
-
 	sd_io_1v8_reg: sd_io_1v8_reg {
 		compatible = "regulator-gpio";
 		regulator-name = "vdd-sd-io";
@@ -56,6 +52,10 @@
 	};
 };
 
+&bt {
+	shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
+};
+
 &ddc0 {
 	status = "okay";
 };
@@ -178,23 +178,6 @@
 	status = "okay";
 };
 
-/* SDHCI is used to control the SDIO for wireless */
-&sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_gpio34>;
-	bus-width = <4>;
-	non-removable;
-	mmc-pwrseq = <&wifi_pwrseq>;
-	status = "okay";
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
 /* EMMC2 is used to drive the SD card */
 &emmc2 {
 	vqmmc-supply = <&sd_io_1v8_reg>;
@@ -236,13 +219,6 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>;
 	uart-has-rtscts;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-		shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
-	};
 };
 
 /* uart1 is mapped to the pin header */
@@ -259,3 +235,7 @@
 &vec {
 	status = "disabled";
 };
+
+&wifi_pwrseq {
+	reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
index 33b2b77..243236b 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
@@ -7,6 +7,7 @@
 #include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
 #include "bcm283x-rpi-usb-otg.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
@@ -27,11 +28,10 @@
 			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
 		};
 	};
+};
 
-	wifi_pwrseq: wifi-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
-	};
+&bt {
+	shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
 };
 
 &gpio {
@@ -110,19 +110,7 @@
 };
 
 &sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>;
-	bus-width = <4>;
-	mmc-pwrseq = <&wifi_pwrseq>;
-	non-removable;
-	status = "okay";
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
 };
 
 &sdhost {
@@ -135,13 +123,6 @@
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-		shutdown-gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
-	};
 };
 
 &uart1 {
@@ -149,3 +130,7 @@
 	pinctrl-0 = <&uart1_gpio14>;
 	status = "okay";
 };
+
+&wifi_pwrseq {
+	reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
index 77099a7..d73daf5 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
@@ -3,6 +3,7 @@
 #include "bcm2837.dtsi"
 #include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,3-model-a-plus", "brcm,bcm2837";
@@ -130,28 +131,6 @@
 	status = "okay";
 };
 
-/*
- * SDHCI is used to control the SDIO for wireless
- *
- * WL_REG_ON and BT_REG_ON of the CYW43455 Wifi/BT module are driven
- * by a single GPIO. We can't give GPIO control to one of the drivers,
- * otherwise the other part would get unexpectedly disturbed.
- */
-&sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_gpio34>;
-	status = "okay";
-	bus-width = <4>;
-	non-removable;
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
 /* SDHOST is used to drive the SD card */
 &sdhost {
 	pinctrl-names = "default";
@@ -160,16 +139,15 @@
 	bus-width = <4>;
 };
 
-/* uart0 communicates with the BT module */
+/* uart0 communicates with the BT module
+ *
+ * WL_REG_ON and BT_REG_ON of the CYW43455 Wifi/BT module are driven
+ * by a single GPIO. We can't give GPIO control to one of the drivers,
+ * otherwise the other part would get unexpectedly disturbed.
+ */
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32 &gpclk2_gpio43>;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-	};
 };
 
 /* uart1 is mapped to the pin header */
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
index 6101026..e12938b 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
@@ -4,6 +4,7 @@
 #include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-lan7515.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837";
@@ -31,11 +32,10 @@
 			linux,default-trigger = "default-on";
 		};
 	};
+};
 
-	wifi_pwrseq: wifi-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
-	};
+&bt {
+	shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
 };
 
 &firmware {
@@ -137,23 +137,6 @@
 	status = "okay";
 };
 
-/* SDHCI is used to control the SDIO for wireless */
-&sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_gpio34>;
-	status = "okay";
-	bus-width = <4>;
-	non-removable;
-	mmc-pwrseq = <&wifi_pwrseq>;
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
 /* SDHOST is used to drive the SD card */
 &sdhost {
 	pinctrl-names = "default";
@@ -166,13 +149,6 @@
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32 &gpclk2_gpio43>;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-		shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
-	};
 };
 
 /* uart1 is mapped to the pin header */
@@ -181,3 +157,7 @@
 	pinctrl-0 = <&uart1_gpio14>;
 	status = "okay";
 };
+
+&wifi_pwrseq {
+	reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
index dd4a486..42b5383 100644
--- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
@@ -4,6 +4,7 @@
 #include "bcm2836-rpi.dtsi"
 #include "bcm283x-rpi-smsc9514.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
 
 / {
 	compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
@@ -24,11 +25,10 @@
 			gpios = <&expgpio 2 GPIO_ACTIVE_HIGH>;
 		};
 	};
+};
 
-	wifi_pwrseq: wifi-pwrseq {
-		compatible = "mmc-pwrseq-simple";
-		reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
-	};
+&bt {
+	shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
 };
 
 &firmware {
@@ -134,13 +134,6 @@
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_gpio32 &gpclk2_gpio43>;
-	status = "okay";
-
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		max-speed = <2000000>;
-		shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
-	};
 };
 
 /* uart1 is mapped to the pin header */
@@ -150,23 +143,6 @@
 	status = "okay";
 };
 
-/* SDHCI is used to control the SDIO for wireless */
-&sdhci {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_gpio34>;
-	status = "okay";
-	bus-width = <4>;
-	non-removable;
-	mmc-pwrseq = <&wifi_pwrseq>;
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
 /* SDHOST is used to drive the SD card */
 &sdhost {
 	pinctrl-names = "default";
@@ -174,3 +150,7 @@
 	status = "okay";
 	bus-width = <4>;
 };
+
+&wifi_pwrseq {
+	reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi b/arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi
new file mode 100644
index 0000000..0b64cc1
--- /dev/null
+++ b/arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	wifi_pwrseq: wifi-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+	};
+};
+
+/* SDHCI is used to control the SDIO for wireless */
+&sdhci {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_gpio34>;
+	bus-width = <4>;
+	non-removable;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	status = "okay";
+
+	brcmf: wifi at 1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+	};
+};
+
+/* uart0 communicates with the BT module */
+&uart0 {
+	status = "okay";
+
+	bt: bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		max-speed = <2000000>;
+	};
+};
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:41 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:41 +0200
Subject: [PATCH V2 10/10] arm64: dts: broadcom: Add reference to RPi CM4 IO
 Board
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-11-git-send-email-stefan.wahren@i2se.com>

This adds a reference to the dts of the Raspberry Pi Compute Module 4
IO Board, so we don't need to maintain the content in arm64.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm64/boot/dts/broadcom/Makefile               | 1 +
 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts | 2 ++
 2 files changed, 3 insertions(+)
 create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts

diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile
index 11eae3e..c688203 100644
--- a/arch/arm64/boot/dts/broadcom/Makefile
+++ b/arch/arm64/boot/dts/broadcom/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-400.dtb \
 			      bcm2711-rpi-4-b.dtb \
+			      bcm2711-rpi-cm4-io.dtb \
 			      bcm2837-rpi-3-a-plus.dtb \
 			      bcm2837-rpi-3-b.dtb \
 			      bcm2837-rpi-3-b-plus.dtb \
diff --git a/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
new file mode 100644
index 0000000..e36d395
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "arm/bcm2711-rpi-cm4-io.dts"
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:36 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:36 +0200
Subject: [PATCH V2 05/10] mmc: sdhci-iproc: Set
 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-6-git-send-email-stefan.wahren@i2se.com>

From: Nicolas Saenz Julienne <nsaenz at kernel.org>

The controller doesn't seem to pick-up on clock changes, so set the
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN flag to query the clock frequency
directly from the clock.

Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 drivers/mmc/host/sdhci-iproc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index 032bf85..e7565c6 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -295,7 +295,8 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
 };
 
 static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
-	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
+	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
+		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
 	.ops = &sdhci_iproc_bcm2711_ops,
 };
 
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Aug  7 04:06:40 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  7 Aug 2021 13:06:40 +0200
Subject: [PATCH V2 09/10] ARM: dts: Add Raspberry Pi Compute Module 4 IO Board
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1628334401-6577-10-git-send-email-stefan.wahren@i2se.com>

This adds the matching carrier for Raspberry Pi Compute Module 4.
Instead of xHCI USB host controller there is just a USB 2.0 interface
connected to the DWC2 controller from the BCM2711. As a result
there is a free PCIe Gen 2 socket. Also there are 2 full-size HDMI 2.0
connectors.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/Makefile               |   1 +
 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts | 138 +++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 863347b..d3f25b9 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -90,6 +90,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
 	bcm2837-rpi-cm3-io3.dtb \
 	bcm2711-rpi-400.dtb \
 	bcm2711-rpi-4-b.dtb \
+	bcm2711-rpi-cm4-io.dtb \
 	bcm2835-rpi-zero.dtb \
 	bcm2835-rpi-zero-w.dtb
 dtb-$(CONFIG_ARCH_BCM_5301X) += \
diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
new file mode 100644
index 0000000..19600b6
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+#include "bcm2711-rpi-cm4.dtsi"
+#include "bcm283x-rpi-usb-host.dtsi"
+
+/ {
+	model = "Raspberry Pi Compute Module 4 IO Board";
+
+	leds {
+		led-act {
+			gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
+		};
+
+		led-pwr {
+			label = "PWR";
+			gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+			linux,default-trigger = "default-on";
+		};
+	};
+};
+
+&ddc0 {
+	status = "okay";
+};
+
+&ddc1 {
+	status = "okay";
+};
+
+&gpio {
+	/*
+	 * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and
+	 * the official GPU firmware DT blob.
+	 *
+	 * Legend:
+	 * "FOO" = GPIO line named "FOO" on the schematic
+	 * "FOO_N" = GPIO line named "FOO" on schematic, active low
+	 */
+	gpio-line-names = "ID_SDA",
+			  "ID_SCL",
+			  "SDA1",
+			  "SCL1",
+			  "GPIO_GCLK",
+			  "GPIO5",
+			  "GPIO6",
+			  "SPI_CE1_N",
+			  "SPI_CE0_N",
+			  "SPI_MISO",
+			  "SPI_MOSI",
+			  "SPI_SCLK",
+			  "GPIO12",
+			  "GPIO13",
+			  /* Serial port */
+			  "TXD1",
+			  "RXD1",
+			  "GPIO16",
+			  "GPIO17",
+			  "GPIO18",
+			  "GPIO19",
+			  "GPIO20",
+			  "GPIO21",
+			  "GPIO22",
+			  "GPIO23",
+			  "GPIO24",
+			  "GPIO25",
+			  "GPIO26",
+			  "GPIO27",
+			  "RGMII_MDIO",
+			  "RGMIO_MDC",
+			  /* Used by BT module */
+			  "CTS0",
+			  "RTS0",
+			  "TXD0",
+			  "RXD0",
+			  /* Used by Wifi */
+			  "SD1_CLK",
+			  "SD1_CMD",
+			  "SD1_DATA0",
+			  "SD1_DATA1",
+			  "SD1_DATA2",
+			  "SD1_DATA3",
+			  /* Shared with SPI flash */
+			  "PWM0_MISO",
+			  "PWM1_MOSI",
+			  "STATUS_LED_G_CLK",
+			  "SPIFLASH_CE_N",
+			  "SDA0",
+			  "SCL0",
+			  "RGMII_RXCLK",
+			  "RGMII_RXCTL",
+			  "RGMII_RXD0",
+			  "RGMII_RXD1",
+			  "RGMII_RXD2",
+			  "RGMII_RXD3",
+			  "RGMII_TXCLK",
+			  "RGMII_TXCTL",
+			  "RGMII_TXD0",
+			  "RGMII_TXD1",
+			  "RGMII_TXD2",
+			  "RGMII_TXD3";
+};
+
+&hdmi0 {
+	status = "okay";
+};
+
+&hdmi1 {
+	status = "okay";
+};
+
+&genet {
+	status = "okay";
+};
+
+&pixelvalve0 {
+	status = "okay";
+};
+
+&pixelvalve1 {
+	status = "okay";
+};
+
+&pixelvalve2 {
+	status = "okay";
+};
+
+&pixelvalve4 {
+	status = "okay";
+};
+
+&vc4 {
+	status = "okay";
+};
+
+&vec {
+	status = "disabled";
+};
-- 
2.7.4



From pali at kernel.org  Sat Aug  7 04:35:36 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sat, 7 Aug 2021 13:35:36 +0200
Subject: [PATCH 2/2] arm64: dts: marvell: armada-37xx: Extend PCIe MEM
 space
In-Reply-To: <20210723164512.vo3scpzoodff2j33@pali>
References: <20210624215546.4015-1-pali@kernel.org>
 <20210624215546.4015-3-pali@kernel.org> <87pmv919bq.fsf@BL-laptop>
 <20210723141204.waiipazikhzzloj7@pali>
 <20210723155247.GB4103@lpieralisi>
 <20210723164512.vo3scpzoodff2j33@pali>
Message-ID: <20210807113536.24ik7m7uonebwox2@pali>

On Friday 23 July 2021 18:45:12 Pali Roh?r wrote:
> On Friday 23 July 2021 16:52:47 Lorenzo Pieralisi wrote:
> > On Fri, Jul 23, 2021 at 04:12:04PM +0200, Pali Roh?r wrote:
> > > On Friday 23 July 2021 14:52:25 Gregory CLEMENT wrote:
> > > > Hello Pali,
> > > > 
> > > > > Current PCIe MEM space of size 16 MB is not enough for some combination
> > > > > of PCIe cards (e.g. NVMe disk together with ath11k wifi card). ARM Trusted
> > > > > Firmware for Armada 3700 platform already assigns 128 MB for PCIe window,
> > > > > so extend PCIe MEM space to the end of 128 MB PCIe window which allows to
> > > > > allocate more PCIe BARs for more PCIe cards.
> > > > >
> > > > > Without this change some combination of PCIe cards cannot be used and
> > > > > kernel show error messages in dmesg during initialization:
> > > > >
> > > > >     pci 0000:00:00.0: BAR 8: no space for [mem size 0x01800000]
> > > > >     pci 0000:00:00.0: BAR 8: failed to assign [mem size 0x01800000]
> > > > >     pci 0000:00:00.0: BAR 6: assigned [mem 0xe8000000-0xe80007ff pref]
> > > > >     pci 0000:01:00.0: BAR 8: no space for [mem size 0x01800000]
> > > > >     pci 0000:01:00.0: BAR 8: failed to assign [mem size 0x01800000]
> > > > >     pci 0000:02:03.0: BAR 8: no space for [mem size 0x01000000]
> > > > >     pci 0000:02:03.0: BAR 8: failed to assign [mem size 0x01000000]
> > > > >     pci 0000:02:07.0: BAR 8: no space for [mem size 0x00100000]
> > > > >     pci 0000:02:07.0: BAR 8: failed to assign [mem size 0x00100000]
> > > > >     pci 0000:03:00.0: BAR 0: no space for [mem size 0x01000000 64bit]
> > > > >     pci 0000:03:00.0: BAR 0: failed to assign [mem size 0x01000000 64bit]
> > > > >
> > > > > Due to bugs in U-Boot port for Turris Mox, the second range in Turris Mox
> > > > > kernel DTS file for PCIe must start at 16 MB offset. Otherwise U-Boot
> > > > > crashes during loading of kernel DTB file. This bug is present only in
> > > > > U-Boot code for Turris Mox and therefore other Armada 3700 devices are not
> > > > > affected by this bug. Bug is fixed in U-Boot version 2021.07.
> > > > >
> > > > > To not break booting new kernels on existing versions of U-Boot on Turris
> > > > > Mox, use first 16 MB range for IO and second range with rest of PCIe window
> > > > > for MEM.
> > > > 
> > > > Is there any depencey with the firs patch of this series ?
> > > > 
> > > > What happend if this patch is applied without the other ?
> > > 
> > > First patch is fixing reading and setting ranges configuration from DTS.
> > > Without first patch memory windows stays as they were in bootloader or
> > > in its default configuration. Which is that all 128 MB are transparently
> > > mapped to PCIe MEM space.
> > > 
> > > Therefore this second DTS patch does not fixes issue with IO space
> > > (kernel still crashes when accessing it). But allows to use all PCIe MEM
> > > space (due to bootloader / default configuration) and therefore allows
> > > to use more PCIe cards (which needs more PCIe MEM space).
> > 
> > So, the two patches are decoupled then ? We are not taking dts changes
> > through the PCI tree.
> 
> Well, both patches are required to fix setup and use of PCIe ranges on
> A3720 platforms. But I would say they are independent and you can apply
> them in any order. So Gregory, feel free to take DTS change in your tree
> and Lorenzo can review other patch.

Lorenzo, so will you take driver change via PCI tree?

And Gregory, DTS change via DTS tree?

> I sent these two patches in one series as they are fixing one common
> issue. It is common that for fixing one common issue it is required to
> touch more subsystems / trees.
> 
> > Besides: these dts patches are a nightmare for backward compatibility,
> > hopefully Rob can shed some light on whether what you are doing here
> > is advisable and how to sync the changes with kernel changes.
> 
> As written in comment for armada-3720-turris-mox.dts file, there are
> specific requirements what needs to be put into ranges section. And
> version of this file without applying this patch and also version of
> this file with applied patch matches these requirements.
> 
> So I would say that this DTS change is backward and also forward
> compatible.
> 
> But I agree that DTS changes are lot of time nightmare...
> 
> > Lorenzo
> > 
> > > > Could you test it to see if any regression occure ?
> > > > 
> > > > Thanks,
> > > > 
> > > > Gr?gory
> > > > 
> > > > >
> > > > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > > > Fixes: 76f6386b25cc ("arm64: dts: marvell: Add Aardvark PCIe support for Armada 3700")
> > > > > ---
> > > > >  .../boot/dts/marvell/armada-3720-turris-mox.dts | 17 +++++++++++++++++
> > > > >  arch/arm64/boot/dts/marvell/armada-37xx.dtsi    | 11 +++++++++--
> > > > >  2 files changed, 26 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> > > > > index 53e817c5f6f3..86b3025f174b 100644
> > > > > --- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> > > > > +++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> > > > > @@ -134,6 +134,23 @@
> > > > >  	pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>;
> > > > >  	status = "okay";
> > > > >  	reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
> > > > > +	/*
> > > > > +	 * U-Boot port for Turris Mox has a bug which always expects that "ranges" DT property
> > > > > +	 * contains exactly 2 ranges with 3 (child) address cells, 2 (parent) address cells and
> > > > > +	 * 2 size cells and also expects that the second range starts at 16 MB offset. If these
> > > > > +	 * conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
> > > > > +	 * space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
> > > > > +	 * for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB.
> > > > > +	 * This bug is not present in U-Boot ports for other Armada 3700 devices and is fixed in
> > > > > +	 * U-Boot version 2021.07. See relevant U-Boot commits (the last one contains fix):
> > > > > +	 * https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
> > > > > +	 * https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf
> > > > > +	 * https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33
> > > > > +	 */
> > > > > +	#address-cells = <3>;
> > > > > +	#size-cells = <2>;
> > > > > +	ranges = <0x81000000 0 0xe8000000   0 0xe8000000   0 0x01000000   /* Port 0 IO */
> > > > > +		  0x82000000 0 0xe9000000   0 0xe9000000   0 0x07000000>; /* Port 0 MEM */
> > > > >  
> > > > >  	/* enabled by U-Boot if PCIe module is present */
> > > > >  	status = "disabled";
> > > > > diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> > > > > index 7a2df148c6a3..dac3007f2ac1 100644
> > > > > --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> > > > > +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> > > > > @@ -488,8 +488,15 @@
> > > > >  			#interrupt-cells = <1>;
> > > > >  			msi-parent = <&pcie0>;
> > > > >  			msi-controller;
> > > > > -			ranges = <0x82000000 0 0xe8000000   0 0xe8000000 0 0x1000000 /* Port 0 MEM */
> > > > > -				  0x81000000 0 0xe9000000   0 0xe9000000 0 0x10000>; /* Port 0 IO*/
> > > > > +			/*
> > > > > +			 * The 128 MiB address range [0xe8000000-0xf0000000] is
> > > > > +			 * dedicated for PCIe and can be assigned to 8 windows
> > > > > +			 * with size a power of two. Use one 64 KiB window for
> > > > > +			 * IO at the end and the remaining seven windows
> > > > > +			 * (totaling 127 MiB) for MEM.
> > > > > +			 */
> > > > > +			ranges = <0x82000000 0 0xe8000000   0 0xe8000000   0 0x07f00000   /* Port 0 MEM */
> > > > > +				  0x81000000 0 0xefff0000   0 0xefff0000   0 0x00010000>; /* Port 0 IO */
> > > > >  			interrupt-map-mask = <0 0 0 7>;
> > > > >  			interrupt-map = <0 0 0 1 &pcie_intc 0>,
> > > > >  					<0 0 0 2 &pcie_intc 1>,
> > > > > -- 
> > > > > 2.20.1
> > > > >
> > > > 
> > > > -- 
> > > > Gregory Clement, Bootlin
> > > > Embedded Linux and Kernel engineering
> > > > http://bootlin.com


From andrew at lunn.ch  Sat Aug  7 07:17:44 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Sat, 7 Aug 2021 16:17:44 +0200
Subject: [PATCH] ARM: kirkwood: add missing <linux/if_ether.h> for ETH_ALEN
In-Reply-To: <cde9de20efd3a75561080751766edbec@walle.cc>
References: <YQxk4jrbm31NM1US@makrotopia.org>
 <cde9de20efd3a75561080751766edbec@walle.cc>
Message-ID: <YQ6WCK0Sytb0nxj9@lunn.ch>

> What kernel is this? I've just tested with this exact commit as
> base and it compiles just fine.
> 
> I'm not saying including the file is wrong, but it seems it isn't
> needed in the upstream kernel and I don't know if it qualifies for
> the stable queue therefore.

I would like to see a reproducer for mainline. Do you have a kernel
config which generates the problem.

The change itself does seems reasonable, so if we can reproduce it, i
would be happy to merge it for stable.

      Andrew


From robdclark at gmail.com  Sat Aug  7 10:08:02 2021
From: robdclark at gmail.com (Rob Clark)
Date: Sat, 7 Aug 2021 10:08:02 -0700
Subject: [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces
In-Reply-To: <1f5f285a-b923-16ff-2ca1-6f92e22ffcab@linaro.org>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-8-tzimmermann@suse.de>
 <1f5f285a-b923-16ff-2ca1-6f92e22ffcab@linaro.org>
Message-ID: <CAF6AEGu-Vj_3ex1Auae_SQvFkwgaXVokqhL_nsFzXOKP0p06SQ@mail.gmail.com>

On Tue, Aug 3, 2021 at 2:37 AM Dmitry Baryshkov
<dmitry.baryshkov at linaro.org> wrote:
>
> On 03/08/2021 12:06, Thomas Zimmermann wrote:
> > Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> > IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> > don't benefit from using it.
> >
> > DRM IRQ callbacks are now being called directly or inlined.
> >
> > Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>
> Rob should probably also give his blessing on this patch though.
>

I've pushed this to msm-next-staging, but if Thomas would prefer to
merge the series together then I can drop it (in which case a-b for
this patch)

BR,
-R

> > ---
> >   drivers/gpu/drm/msm/msm_drv.c | 113 ++++++++++++++++++++--------------
> >   drivers/gpu/drm/msm/msm_kms.h |   2 +-
> >   2 files changed, 69 insertions(+), 46 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> > index 1594ae39d54f..a332b09a5a11 100644
> > --- a/drivers/gpu/drm/msm/msm_drv.c
> > +++ b/drivers/gpu/drm/msm/msm_drv.c
> > @@ -14,7 +14,6 @@
> >   #include <drm/drm_drv.h>
> >   #include <drm/drm_file.h>
> >   #include <drm/drm_ioctl.h>
> > -#include <drm/drm_irq.h>
> >   #include <drm/drm_prime.h>
> >   #include <drm/drm_of.h>
> >   #include <drm/drm_vblank.h>
> > @@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
> >       msm_writel(val | or, addr);
> >   }
> >
> > +static irqreturn_t msm_irq(int irq, void *arg)
> > +{
> > +     struct drm_device *dev = arg;
> > +     struct msm_drm_private *priv = dev->dev_private;
> > +     struct msm_kms *kms = priv->kms;
> > +
> > +     BUG_ON(!kms);
> > +
> > +     return kms->funcs->irq(kms);
> > +}
> > +
> > +static void msm_irq_preinstall(struct drm_device *dev)
> > +{
> > +     struct msm_drm_private *priv = dev->dev_private;
> > +     struct msm_kms *kms = priv->kms;
> > +
> > +     BUG_ON(!kms);
> > +
> > +     kms->funcs->irq_preinstall(kms);
> > +}
> > +
> > +static int msm_irq_postinstall(struct drm_device *dev)
> > +{
> > +     struct msm_drm_private *priv = dev->dev_private;
> > +     struct msm_kms *kms = priv->kms;
> > +
> > +     BUG_ON(!kms);
> > +
> > +     if (kms->funcs->irq_postinstall)
> > +             return kms->funcs->irq_postinstall(kms);
> > +
> > +     return 0;
> > +}
> > +
> > +static int msm_irq_install(struct drm_device *dev, unsigned int irq)
> > +{
> > +     int ret;
> > +
> > +     if (irq == IRQ_NOTCONNECTED)
> > +             return -ENOTCONN;
> > +
> > +     msm_irq_preinstall(dev);
> > +
> > +     ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = msm_irq_postinstall(dev);
> > +     if (ret) {
> > +             free_irq(irq, dev);
> > +             return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void msm_irq_uninstall(struct drm_device *dev)
> > +{
> > +     struct msm_drm_private *priv = dev->dev_private;
> > +     struct msm_kms *kms = priv->kms;
> > +
> > +     kms->funcs->irq_uninstall(kms);
> > +     free_irq(kms->irq, dev);
> > +}
> > +
> >   struct msm_vblank_work {
> >       struct work_struct work;
> >       int crtc_id;
> > @@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
> >       }
> >
> >       /* We must cancel and cleanup any pending vblank enable/disable
> > -      * work before drm_irq_uninstall() to avoid work re-enabling an
> > +      * work before msm_irq_uninstall() to avoid work re-enabling an
> >        * irq after uninstall has disabled it.
> >        */
> >
> > @@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
> >       drm_mode_config_cleanup(ddev);
> >
> >       pm_runtime_get_sync(dev);
> > -     drm_irq_uninstall(ddev);
> > +     msm_irq_uninstall(ddev);
> >       pm_runtime_put_sync(dev);
> >
> >       if (kms && kms->funcs)
> > @@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
> >
> >       if (kms) {
> >               pm_runtime_get_sync(dev);
> > -             ret = drm_irq_install(ddev, kms->irq);
> > +             ret = msm_irq_install(ddev, kms->irq);
> >               pm_runtime_put_sync(dev);
> >               if (ret < 0) {
> >                       DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
> > @@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
> >       context_close(ctx);
> >   }
> >
> > -static irqreturn_t msm_irq(int irq, void *arg)
> > -{
> > -     struct drm_device *dev = arg;
> > -     struct msm_drm_private *priv = dev->dev_private;
> > -     struct msm_kms *kms = priv->kms;
> > -     BUG_ON(!kms);
> > -     return kms->funcs->irq(kms);
> > -}
> > -
> > -static void msm_irq_preinstall(struct drm_device *dev)
> > -{
> > -     struct msm_drm_private *priv = dev->dev_private;
> > -     struct msm_kms *kms = priv->kms;
> > -     BUG_ON(!kms);
> > -     kms->funcs->irq_preinstall(kms);
> > -}
> > -
> > -static int msm_irq_postinstall(struct drm_device *dev)
> > -{
> > -     struct msm_drm_private *priv = dev->dev_private;
> > -     struct msm_kms *kms = priv->kms;
> > -     BUG_ON(!kms);
> > -
> > -     if (kms->funcs->irq_postinstall)
> > -             return kms->funcs->irq_postinstall(kms);
> > -
> > -     return 0;
> > -}
> > -
> > -static void msm_irq_uninstall(struct drm_device *dev)
> > -{
> > -     struct msm_drm_private *priv = dev->dev_private;
> > -     struct msm_kms *kms = priv->kms;
> > -     BUG_ON(!kms);
> > -     kms->funcs->irq_uninstall(kms);
> > -}
> > -
> >   int msm_crtc_enable_vblank(struct drm_crtc *crtc)
> >   {
> >       struct drm_device *dev = crtc->dev;
> > @@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
> >       .open               = msm_open,
> >       .postclose           = msm_postclose,
> >       .lastclose          = drm_fb_helper_lastclose,
> > -     .irq_handler        = msm_irq,
> > -     .irq_preinstall     = msm_irq_preinstall,
> > -     .irq_postinstall    = msm_irq_postinstall,
> > -     .irq_uninstall      = msm_irq_uninstall,
> >       .dumb_create        = msm_gem_dumb_create,
> >       .dumb_map_offset    = msm_gem_dumb_map_offset,
> >       .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
> > diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
> > index 086a2d59b8c8..9de7c42e1071 100644
> > --- a/drivers/gpu/drm/msm/msm_kms.h
> > +++ b/drivers/gpu/drm/msm/msm_kms.h
> > @@ -150,7 +150,7 @@ struct msm_kms {
> >       const struct msm_kms_funcs *funcs;
> >       struct drm_device *dev;
> >
> > -     /* irq number to be passed on to drm_irq_install */
> > +     /* irq number to be passed on to msm_irq_install */
> >       int irq;
> >
> >       /* mapper-id used to request GEM buffer mapped for scanout: */
> >
>
>
> --
> With best wishes
> Dmitry


From lkp at intel.com  Sat Aug  7 10:31:27 2021
From: lkp at intel.com (kernel test robot)
Date: Sun, 8 Aug 2021 01:31:27 +0800
Subject: [PATCH] firmware: arm_scmi: fix boolconv.cocci warnings
In-Reply-To: <202108080108.k5pHZ040-lkp@intel.com>
References: <202108080108.k5pHZ040-lkp@intel.com>
Message-ID: <20210807173127.GA43248@a24dbc127934>

From: kernel test robot <lkp at intel.com>

drivers/firmware/arm_scmi/virtio.c:225:40-45: WARNING: conversion to bool not needed here

 Remove unneeded conversion to bool

Semantic patch information:
 Relational and logical operators evaluate to bool,
 explicit conversion is overly verbose and unneeded.

Generated by: scripts/coccinelle/misc/boolconv.cocci

CC: Igor Skalkin <igor.skalkin at opensynergy.com>
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: kernel test robot <lkp at intel.com>
---

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git for-next/scmi
head:   1e7cbfaa66d39e78bd24df0c78b55df68176b59e
commit: 46abe13b5e3db187e52cd0de06c07bbce010726c [23/24] firmware: arm_scmi: Add virtio transport
:::::: branch date: 2 days ago
:::::: commit date: 2 days ago

 virtio.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/firmware/arm_scmi/virtio.c
+++ b/drivers/firmware/arm_scmi/virtio.c
@@ -222,7 +222,7 @@ static bool virtio_chan_available(struct
 		return false;
 	}
 
-	return vioch && !vioch->cinfo ? true : false;
+	return vioch && !vioch->cinfo;
 }
 
 static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,


From len.baker at gmx.com  Sat Aug  7 10:48:39 2021
From: len.baker at gmx.com (Len Baker)
Date: Sat, 7 Aug 2021 19:48:39 +0200
Subject: [PATCH v3] drivers/soc: Remove all strcpy() uses
In-Reply-To: <YQsTesvLfAwd8z5B@builder.lan>
References: <20210801131958.6144-1-len.baker@gmx.com>
 <YQsTesvLfAwd8z5B@builder.lan>
Message-ID: <20210807174839.GF2688@titan>

Hi,

On Wed, Aug 04, 2021 at 05:23:54PM -0500, Bjorn Andersson wrote:
> On Sun 01 Aug 08:19 CDT 2021, Len Baker wrote:
>
> > strcpy() performs no bounds checking on the destination buffer. This
> > could result in linear overflows beyond the end of the buffer, leading
> > to all kinds of misbehaviors. The safe replacement is strscpy().
> >
>
> While this is true, are any of these uses of strcpy affected by its
> shortcomings?

No, this patch is only an effort to clean up the proliferation of str*()
functions in the kernel.

> > Moreover, when the size of the destination buffer cannot be obtained
> > using "sizeof", use the memcpy function instead of strscpy.
> >
>
> This is not why you're using memcpy, you're using it because you _know_
> how many bytes should be copied - because you just did a strlen() and
> allocated that amount of space.

Understood, I will change the commit message.

>
> > [...]
> >  		/* Prepare req message */
> > -		strcpy(req.service_path, pds->service_path);
> > +		strscpy(req.service_path, pds->service_path,
> > +			sizeof(req.service_path));
>
> There's no need to break this line.

Ok, thanks.

Regards,
Len


From oupton at google.com  Sat Aug  7 11:35:21 2021
From: oupton at google.com (Oliver Upton)
Date: Sat, 7 Aug 2021 11:35:21 -0700
Subject: [RESEND PATCH] clocksource/arm_arch_timer: Fix masking for high
 freq counters
In-Reply-To: <87pmup1q8w.wl-maz@kernel.org>
References: <20210806182126.2842876-1-oupton@google.com>
 <87pmup1q8w.wl-maz@kernel.org>
Message-ID: <CAOQ_QsiZgpHsLGF8Fp7+oiKPZXuW-vGsjPdpwKhJ06XZAxDfVQ@mail.gmail.com>

Hi Marc,

On Sat, Aug 7, 2021 at 3:52 AM Marc Zyngier <maz at kernel.org> wrote:
>
> Hi Oliver,
>
> On Fri, 06 Aug 2021 19:21:26 +0100,
> Oliver Upton <oupton at google.com> wrote:
> >
> > Unfortunately, the architecture provides no means to determine the bit
> > width of the system counter. However, we do know the following from the
> > specification:
> >
> >  - the system counter is at least 56 bits wide
> >  - Roll-over time of not less than 40 years
> >
> > To date, the arch timer driver has depended on the first property,
> > assuming any system counter to be 56 bits wide and masking off the rest.
> > However, combining a narrow clocksource mask with a high frequency
> > counter could result in prematurely wrapping the system counter by a
> > significant margin. For example, a 56 bit wide, 1GHz system counter
> > would wrap in a mere 2.28 years!
> >
> > This is a problem for two reasons: v8.6+ implementations are required to
> > provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> > implementers may select a counter frequency of their choosing.
> >
> > Fix the issue by deriving a valid clock mask based on the second
> > property from above. Set the floor at 56 bits, since we know no system
> > counter is narrower than that.
> >
> > Suggested-by: Marc Zyngier <maz at kernel.org>
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > ---
> > This patch was tested with QEMU, tweaked to provide a 1GHz system
> > counter frequency, as I could not easily figure out how to tweak the
> > base FVP to provide a 1GHz counter.
>
> <FVP>
> "bp.refcounter.base_frequency" is the property you are looking for. In
> general, passing --list-params to the model reveals a treasure trove
> of weird and wonderful options that can be used to configure the model
> to your liking.
> </FVP>

Ah! Thanks for the tip. I didn't find the fast models documentation to
be too terribly helpful.
> >
> > +/*
> > + * The minimum amount of time a generic timer is guaranteed to not roll over
>
> nit: s/timer/counter/
>

Ack.

> > + * (40 years)
>
> For later reference, could you add the section of the ARMv8 ARM where
> this is mentioned? Something like 'ARM DDI 0487G.a D11.1.2 ("The
> system counter")', either here or in the comment further down.
>

Sure thing. I think I'll drop it on the function below since we depend
on two properties of the system counter there.

> > +static int __init arch_counter_get_width(void)
> > +{
> > +     u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_get_cntfrq();
>
> That's unfortunately wishful thinking. We have stupidly broken systems
> out there that do not set CNTFRQ_EL0, and instead rely on DT
> properties to describe the counter frequency. You're likely to end up
> with a glorious zero as a result, with interesting consequences...

Blech. I didn't read the DT hooks for the driver.  That's awful.

> Use arch_timer_rate instead, which will be set as by the time you
> register the counter.

Ack.

>
> > +
> > +     /* guarantee the returned width is within the valid range */
> > +     return max(56, min(64, ilog2(min_cycles)));
>
> Maybe better written as "clamp_val(ilog2(min_cycles), 56, 64);".
>

Agreed.

> > +     width = arch_counter_get_width();
> > +     clocksource_counter.mask = CLOCKSOURCE_MASK(width);
> > +     cyclecounter.mask = CLOCKSOURCE_MASK(width);
>
> Since you move this to be computed at runtime, how about dropping the
> static initialisation of the mask fields?
>

Yep, already made the change locally after mailing out :)

> > +
> >       if (!arch_counter_suspend_stop)
> >               clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
> >       start_count = arch_timer_read_counter();
> > @@ -1040,8 +1065,7 @@ static void __init arch_counter_register(unsigned type)
> >       timecounter_init(&arch_timer_kvm_info.timecounter,
> >                        &cyclecounter, start_count);
> >
> > -     /* 56 bits minimum, so we assume worst case rollover */
> > -     sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
> > +     sched_clock_register(arch_timer_read_counter, width, arch_timer_rate);
> >  }
> >
> >  static void arch_timer_stop(struct clock_event_device *clk)
>
> Another thing that needs addressing for high frequency counter support
> is to move away from TVAL programming and switch to CVAL, as the
> maximum deadline we can currently program is 4.2s at 1GHz.
>
> Fun fact: it has the interesting consequence of breaking XGene-1,
> which implemented CVAL in terms of TVAL instead of the other way
> around (what were these guys thinking?)

Yikes!

> , though I don't think anyone
> will notice in practice. I have a preliminary patch on a branch
> somewhere that I'll try to dust up and post in the coming days.

Sounds good, I'll clean this one up and send it out too.

--
Thanks,
Oliver


From tzimmermann at suse.de  Sat Aug  7 11:40:39 2021
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Sat, 7 Aug 2021 20:40:39 +0200
Subject: [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces
In-Reply-To: <CAF6AEGu-Vj_3ex1Auae_SQvFkwgaXVokqhL_nsFzXOKP0p06SQ@mail.gmail.com>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-8-tzimmermann@suse.de>
 <1f5f285a-b923-16ff-2ca1-6f92e22ffcab@linaro.org>
 <CAF6AEGu-Vj_3ex1Auae_SQvFkwgaXVokqhL_nsFzXOKP0p06SQ@mail.gmail.com>
Message-ID: <9c6471b2-cd6b-d5b9-0c93-1f3e498233ee@suse.de>

Hi

Am 07.08.21 um 19:08 schrieb Rob Clark:
> On Tue, Aug 3, 2021 at 2:37 AM Dmitry Baryshkov
> <dmitry.baryshkov at linaro.org> wrote:
>>
>> On 03/08/2021 12:06, Thomas Zimmermann wrote:
>>> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
>>> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
>>> don't benefit from using it.
>>>
>>> DRM IRQ callbacks are now being called directly or inlined.
>>>
>>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>>
>> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>
>> Rob should probably also give his blessing on this patch though.
>>
> 
> I've pushed this to msm-next-staging, but if Thomas would prefer to
> merge the series together then I can drop it (in which case a-b for
> this patch)

Yes, please. I'd prefer to merge the whole patchset at once through 
drm-misc-next.

Best regards
Thomas

> 
> BR,
> -R
> 
>>> ---
>>>    drivers/gpu/drm/msm/msm_drv.c | 113 ++++++++++++++++++++--------------
>>>    drivers/gpu/drm/msm/msm_kms.h |   2 +-
>>>    2 files changed, 69 insertions(+), 46 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
>>> index 1594ae39d54f..a332b09a5a11 100644
>>> --- a/drivers/gpu/drm/msm/msm_drv.c
>>> +++ b/drivers/gpu/drm/msm/msm_drv.c
>>> @@ -14,7 +14,6 @@
>>>    #include <drm/drm_drv.h>
>>>    #include <drm/drm_file.h>
>>>    #include <drm/drm_ioctl.h>
>>> -#include <drm/drm_irq.h>
>>>    #include <drm/drm_prime.h>
>>>    #include <drm/drm_of.h>
>>>    #include <drm/drm_vblank.h>
>>> @@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
>>>        msm_writel(val | or, addr);
>>>    }
>>>
>>> +static irqreturn_t msm_irq(int irq, void *arg)
>>> +{
>>> +     struct drm_device *dev = arg;
>>> +     struct msm_drm_private *priv = dev->dev_private;
>>> +     struct msm_kms *kms = priv->kms;
>>> +
>>> +     BUG_ON(!kms);
>>> +
>>> +     return kms->funcs->irq(kms);
>>> +}
>>> +
>>> +static void msm_irq_preinstall(struct drm_device *dev)
>>> +{
>>> +     struct msm_drm_private *priv = dev->dev_private;
>>> +     struct msm_kms *kms = priv->kms;
>>> +
>>> +     BUG_ON(!kms);
>>> +
>>> +     kms->funcs->irq_preinstall(kms);
>>> +}
>>> +
>>> +static int msm_irq_postinstall(struct drm_device *dev)
>>> +{
>>> +     struct msm_drm_private *priv = dev->dev_private;
>>> +     struct msm_kms *kms = priv->kms;
>>> +
>>> +     BUG_ON(!kms);
>>> +
>>> +     if (kms->funcs->irq_postinstall)
>>> +             return kms->funcs->irq_postinstall(kms);
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static int msm_irq_install(struct drm_device *dev, unsigned int irq)
>>> +{
>>> +     int ret;
>>> +
>>> +     if (irq == IRQ_NOTCONNECTED)
>>> +             return -ENOTCONN;
>>> +
>>> +     msm_irq_preinstall(dev);
>>> +
>>> +     ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     ret = msm_irq_postinstall(dev);
>>> +     if (ret) {
>>> +             free_irq(irq, dev);
>>> +             return ret;
>>> +     }
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static void msm_irq_uninstall(struct drm_device *dev)
>>> +{
>>> +     struct msm_drm_private *priv = dev->dev_private;
>>> +     struct msm_kms *kms = priv->kms;
>>> +
>>> +     kms->funcs->irq_uninstall(kms);
>>> +     free_irq(kms->irq, dev);
>>> +}
>>> +
>>>    struct msm_vblank_work {
>>>        struct work_struct work;
>>>        int crtc_id;
>>> @@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
>>>        }
>>>
>>>        /* We must cancel and cleanup any pending vblank enable/disable
>>> -      * work before drm_irq_uninstall() to avoid work re-enabling an
>>> +      * work before msm_irq_uninstall() to avoid work re-enabling an
>>>         * irq after uninstall has disabled it.
>>>         */
>>>
>>> @@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
>>>        drm_mode_config_cleanup(ddev);
>>>
>>>        pm_runtime_get_sync(dev);
>>> -     drm_irq_uninstall(ddev);
>>> +     msm_irq_uninstall(ddev);
>>>        pm_runtime_put_sync(dev);
>>>
>>>        if (kms && kms->funcs)
>>> @@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
>>>
>>>        if (kms) {
>>>                pm_runtime_get_sync(dev);
>>> -             ret = drm_irq_install(ddev, kms->irq);
>>> +             ret = msm_irq_install(ddev, kms->irq);
>>>                pm_runtime_put_sync(dev);
>>>                if (ret < 0) {
>>>                        DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
>>> @@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
>>>        context_close(ctx);
>>>    }
>>>
>>> -static irqreturn_t msm_irq(int irq, void *arg)
>>> -{
>>> -     struct drm_device *dev = arg;
>>> -     struct msm_drm_private *priv = dev->dev_private;
>>> -     struct msm_kms *kms = priv->kms;
>>> -     BUG_ON(!kms);
>>> -     return kms->funcs->irq(kms);
>>> -}
>>> -
>>> -static void msm_irq_preinstall(struct drm_device *dev)
>>> -{
>>> -     struct msm_drm_private *priv = dev->dev_private;
>>> -     struct msm_kms *kms = priv->kms;
>>> -     BUG_ON(!kms);
>>> -     kms->funcs->irq_preinstall(kms);
>>> -}
>>> -
>>> -static int msm_irq_postinstall(struct drm_device *dev)
>>> -{
>>> -     struct msm_drm_private *priv = dev->dev_private;
>>> -     struct msm_kms *kms = priv->kms;
>>> -     BUG_ON(!kms);
>>> -
>>> -     if (kms->funcs->irq_postinstall)
>>> -             return kms->funcs->irq_postinstall(kms);
>>> -
>>> -     return 0;
>>> -}
>>> -
>>> -static void msm_irq_uninstall(struct drm_device *dev)
>>> -{
>>> -     struct msm_drm_private *priv = dev->dev_private;
>>> -     struct msm_kms *kms = priv->kms;
>>> -     BUG_ON(!kms);
>>> -     kms->funcs->irq_uninstall(kms);
>>> -}
>>> -
>>>    int msm_crtc_enable_vblank(struct drm_crtc *crtc)
>>>    {
>>>        struct drm_device *dev = crtc->dev;
>>> @@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
>>>        .open               = msm_open,
>>>        .postclose           = msm_postclose,
>>>        .lastclose          = drm_fb_helper_lastclose,
>>> -     .irq_handler        = msm_irq,
>>> -     .irq_preinstall     = msm_irq_preinstall,
>>> -     .irq_postinstall    = msm_irq_postinstall,
>>> -     .irq_uninstall      = msm_irq_uninstall,
>>>        .dumb_create        = msm_gem_dumb_create,
>>>        .dumb_map_offset    = msm_gem_dumb_map_offset,
>>>        .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
>>> diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
>>> index 086a2d59b8c8..9de7c42e1071 100644
>>> --- a/drivers/gpu/drm/msm/msm_kms.h
>>> +++ b/drivers/gpu/drm/msm/msm_kms.h
>>> @@ -150,7 +150,7 @@ struct msm_kms {
>>>        const struct msm_kms_funcs *funcs;
>>>        struct drm_device *dev;
>>>
>>> -     /* irq number to be passed on to drm_irq_install */
>>> +     /* irq number to be passed on to msm_irq_install */
>>>        int irq;
>>>
>>>        /* mapper-id used to request GEM buffer mapped for scanout: */
>>>
>>
>>
>> --
>> With best wishes
>> Dmitry

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Felix Imend?rffer

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210807/34af74ac/attachment-0001.sig>

From robdclark at gmail.com  Sat Aug  7 11:50:22 2021
From: robdclark at gmail.com (Rob Clark)
Date: Sat, 7 Aug 2021 11:50:22 -0700
Subject: [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces
In-Reply-To: <9c6471b2-cd6b-d5b9-0c93-1f3e498233ee@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-8-tzimmermann@suse.de>
 <1f5f285a-b923-16ff-2ca1-6f92e22ffcab@linaro.org>
 <CAF6AEGu-Vj_3ex1Auae_SQvFkwgaXVokqhL_nsFzXOKP0p06SQ@mail.gmail.com>
 <9c6471b2-cd6b-d5b9-0c93-1f3e498233ee@suse.de>
Message-ID: <CAF6AEGs4wD725pqA-tVkyrbPkpumV5DuxWc41x=cPvqi1RACiw@mail.gmail.com>

On Sat, Aug 7, 2021 at 11:40 AM Thomas Zimmermann <tzimmermann at suse.de> wrote:
>
> Hi
>
> Am 07.08.21 um 19:08 schrieb Rob Clark:
> > On Tue, Aug 3, 2021 at 2:37 AM Dmitry Baryshkov
> > <dmitry.baryshkov at linaro.org> wrote:
> >>
> >> On 03/08/2021 12:06, Thomas Zimmermann wrote:
> >>> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> >>> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> >>> don't benefit from using it.
> >>>
> >>> DRM IRQ callbacks are now being called directly or inlined.
> >>>
> >>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> >>
> >> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> >>
> >> Rob should probably also give his blessing on this patch though.
> >>
> >
> > I've pushed this to msm-next-staging, but if Thomas would prefer to
> > merge the series together then I can drop it (in which case a-b for
> > this patch)
>
> Yes, please. I'd prefer to merge the whole patchset at once through
> drm-misc-next.

Ok, I've dropped from msm-next-staging..  for merging via drm-msm-next:

Acked-by: Rob Clark <robdclark at chromium.org>

>
> Best regards
> Thomas
>
> >
> > BR,
> > -R
> >
> >>> ---
> >>>    drivers/gpu/drm/msm/msm_drv.c | 113 ++++++++++++++++++++--------------
> >>>    drivers/gpu/drm/msm/msm_kms.h |   2 +-
> >>>    2 files changed, 69 insertions(+), 46 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> >>> index 1594ae39d54f..a332b09a5a11 100644
> >>> --- a/drivers/gpu/drm/msm/msm_drv.c
> >>> +++ b/drivers/gpu/drm/msm/msm_drv.c
> >>> @@ -14,7 +14,6 @@
> >>>    #include <drm/drm_drv.h>
> >>>    #include <drm/drm_file.h>
> >>>    #include <drm/drm_ioctl.h>
> >>> -#include <drm/drm_irq.h>
> >>>    #include <drm/drm_prime.h>
> >>>    #include <drm/drm_of.h>
> >>>    #include <drm/drm_vblank.h>
> >>> @@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
> >>>        msm_writel(val | or, addr);
> >>>    }
> >>>
> >>> +static irqreturn_t msm_irq(int irq, void *arg)
> >>> +{
> >>> +     struct drm_device *dev = arg;
> >>> +     struct msm_drm_private *priv = dev->dev_private;
> >>> +     struct msm_kms *kms = priv->kms;
> >>> +
> >>> +     BUG_ON(!kms);
> >>> +
> >>> +     return kms->funcs->irq(kms);
> >>> +}
> >>> +
> >>> +static void msm_irq_preinstall(struct drm_device *dev)
> >>> +{
> >>> +     struct msm_drm_private *priv = dev->dev_private;
> >>> +     struct msm_kms *kms = priv->kms;
> >>> +
> >>> +     BUG_ON(!kms);
> >>> +
> >>> +     kms->funcs->irq_preinstall(kms);
> >>> +}
> >>> +
> >>> +static int msm_irq_postinstall(struct drm_device *dev)
> >>> +{
> >>> +     struct msm_drm_private *priv = dev->dev_private;
> >>> +     struct msm_kms *kms = priv->kms;
> >>> +
> >>> +     BUG_ON(!kms);
> >>> +
> >>> +     if (kms->funcs->irq_postinstall)
> >>> +             return kms->funcs->irq_postinstall(kms);
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +static int msm_irq_install(struct drm_device *dev, unsigned int irq)
> >>> +{
> >>> +     int ret;
> >>> +
> >>> +     if (irq == IRQ_NOTCONNECTED)
> >>> +             return -ENOTCONN;
> >>> +
> >>> +     msm_irq_preinstall(dev);
> >>> +
> >>> +     ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
> >>> +     if (ret)
> >>> +             return ret;
> >>> +
> >>> +     ret = msm_irq_postinstall(dev);
> >>> +     if (ret) {
> >>> +             free_irq(irq, dev);
> >>> +             return ret;
> >>> +     }
> >>> +
> >>> +     return 0;
> >>> +}
> >>> +
> >>> +static void msm_irq_uninstall(struct drm_device *dev)
> >>> +{
> >>> +     struct msm_drm_private *priv = dev->dev_private;
> >>> +     struct msm_kms *kms = priv->kms;
> >>> +
> >>> +     kms->funcs->irq_uninstall(kms);
> >>> +     free_irq(kms->irq, dev);
> >>> +}
> >>> +
> >>>    struct msm_vblank_work {
> >>>        struct work_struct work;
> >>>        int crtc_id;
> >>> @@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
> >>>        }
> >>>
> >>>        /* We must cancel and cleanup any pending vblank enable/disable
> >>> -      * work before drm_irq_uninstall() to avoid work re-enabling an
> >>> +      * work before msm_irq_uninstall() to avoid work re-enabling an
> >>>         * irq after uninstall has disabled it.
> >>>         */
> >>>
> >>> @@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
> >>>        drm_mode_config_cleanup(ddev);
> >>>
> >>>        pm_runtime_get_sync(dev);
> >>> -     drm_irq_uninstall(ddev);
> >>> +     msm_irq_uninstall(ddev);
> >>>        pm_runtime_put_sync(dev);
> >>>
> >>>        if (kms && kms->funcs)
> >>> @@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
> >>>
> >>>        if (kms) {
> >>>                pm_runtime_get_sync(dev);
> >>> -             ret = drm_irq_install(ddev, kms->irq);
> >>> +             ret = msm_irq_install(ddev, kms->irq);
> >>>                pm_runtime_put_sync(dev);
> >>>                if (ret < 0) {
> >>>                        DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
> >>> @@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
> >>>        context_close(ctx);
> >>>    }
> >>>
> >>> -static irqreturn_t msm_irq(int irq, void *arg)
> >>> -{
> >>> -     struct drm_device *dev = arg;
> >>> -     struct msm_drm_private *priv = dev->dev_private;
> >>> -     struct msm_kms *kms = priv->kms;
> >>> -     BUG_ON(!kms);
> >>> -     return kms->funcs->irq(kms);
> >>> -}
> >>> -
> >>> -static void msm_irq_preinstall(struct drm_device *dev)
> >>> -{
> >>> -     struct msm_drm_private *priv = dev->dev_private;
> >>> -     struct msm_kms *kms = priv->kms;
> >>> -     BUG_ON(!kms);
> >>> -     kms->funcs->irq_preinstall(kms);
> >>> -}
> >>> -
> >>> -static int msm_irq_postinstall(struct drm_device *dev)
> >>> -{
> >>> -     struct msm_drm_private *priv = dev->dev_private;
> >>> -     struct msm_kms *kms = priv->kms;
> >>> -     BUG_ON(!kms);
> >>> -
> >>> -     if (kms->funcs->irq_postinstall)
> >>> -             return kms->funcs->irq_postinstall(kms);
> >>> -
> >>> -     return 0;
> >>> -}
> >>> -
> >>> -static void msm_irq_uninstall(struct drm_device *dev)
> >>> -{
> >>> -     struct msm_drm_private *priv = dev->dev_private;
> >>> -     struct msm_kms *kms = priv->kms;
> >>> -     BUG_ON(!kms);
> >>> -     kms->funcs->irq_uninstall(kms);
> >>> -}
> >>> -
> >>>    int msm_crtc_enable_vblank(struct drm_crtc *crtc)
> >>>    {
> >>>        struct drm_device *dev = crtc->dev;
> >>> @@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
> >>>        .open               = msm_open,
> >>>        .postclose           = msm_postclose,
> >>>        .lastclose          = drm_fb_helper_lastclose,
> >>> -     .irq_handler        = msm_irq,
> >>> -     .irq_preinstall     = msm_irq_preinstall,
> >>> -     .irq_postinstall    = msm_irq_postinstall,
> >>> -     .irq_uninstall      = msm_irq_uninstall,
> >>>        .dumb_create        = msm_gem_dumb_create,
> >>>        .dumb_map_offset    = msm_gem_dumb_map_offset,
> >>>        .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
> >>> diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
> >>> index 086a2d59b8c8..9de7c42e1071 100644
> >>> --- a/drivers/gpu/drm/msm/msm_kms.h
> >>> +++ b/drivers/gpu/drm/msm/msm_kms.h
> >>> @@ -150,7 +150,7 @@ struct msm_kms {
> >>>        const struct msm_kms_funcs *funcs;
> >>>        struct drm_device *dev;
> >>>
> >>> -     /* irq number to be passed on to drm_irq_install */
> >>> +     /* irq number to be passed on to msm_irq_install */
> >>>        int irq;
> >>>
> >>>        /* mapper-id used to request GEM buffer mapped for scanout: */
> >>>
> >>
> >>
> >> --
> >> With best wishes
> >> Dmitry
>
> --
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 N?rnberg, Germany
> (HRB 36809, AG N?rnberg)
> Gesch?ftsf?hrer: Felix Imend?rffer
>


From oupton at google.com  Sat Aug  7 12:14:28 2021
From: oupton at google.com (Oliver Upton)
Date: Sat,  7 Aug 2021 19:14:28 +0000
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
Message-ID: <20210807191428.3488948-1-oupton@google.com>

Unfortunately, the architecture provides no means to determine the bit
width of the system counter. However, we do know the following from the
specification:

 - the system counter is at least 56 bits wide
 - Roll-over time of not less than 40 years

To date, the arch timer driver has depended on the first property,
assuming any system counter to be 56 bits wide and masking off the rest.
However, combining a narrow clocksource mask with a high frequency
counter could result in prematurely wrapping the system counter by a
significant margin. For example, a 56 bit wide, 1GHz system counter
would wrap in a mere 2.28 years!

This is a problem for two reasons: v8.6+ implementations are required to
provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
implementers may select a counter frequency of their choosing.

Fix the issue by deriving a valid clock mask based on the second
property from above. Set the floor at 56 bits, since we know no system
counter is narrower than that.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Oliver Upton <oupton at google.com>
---
This patch was tested on QEMU, tweaked to provide a 1GHz system counter
frequency. The 'bp.refcounter.base_frequency' property does not seem to
have any affect on the 'ARMvA Base RevC AEM FVP', and instead provides a
100MHz counter.

Parent commit: 0c32706dac1b ("arm64: stacktrace: avoid tracing arch_stack_walk()")

 drivers/clocksource/arm_arch_timer.c | 32 ++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index be6d741d404c..f4816b22213c 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -52,6 +52,12 @@
 #define CNTV_TVAL	0x38
 #define CNTV_CTL	0x3c
 
+/*
+ * The minimum amount of time a generic counter is guaranteed to not roll over
+ * (40 years)
+ */
+#define MIN_ROLLOVER_SECS	(40ULL * 365 * 24 * 3600)
+
 static unsigned arch_timers_present __initdata;
 
 static void __iomem *arch_counter_base __ro_after_init;
@@ -205,13 +211,11 @@ static struct clocksource clocksource_counter = {
 	.id	= CSID_ARM_ARCH_COUNTER,
 	.rating	= 400,
 	.read	= arch_counter_read,
-	.mask	= CLOCKSOURCE_MASK(56),
 	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 static struct cyclecounter cyclecounter __ro_after_init = {
 	.read	= arch_counter_read_cc,
-	.mask	= CLOCKSOURCE_MASK(56),
 };
 
 struct ate_acpi_oem_info {
@@ -1004,9 +1008,26 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 	return &arch_timer_kvm_info;
 }
 
+/*
+ * Makes an educated guess at a valid counter width based on the Generic Timer
+ * specification. Of note:
+ *   1) the system counter is at least 56 bits wide
+ *   2) a roll-over time of not less than 40 years
+ *
+ * See 'ARM DDI 0487G.a D11.1.2 ("The system counter")' for more details.
+ */
+static int __init arch_counter_get_width(void)
+{
+	u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_rate;
+
+	/* guarantee the returned width is within the valid range */
+	return clamp_val(ilog2(min_cycles), 56, 64);
+}
+
 static void __init arch_counter_register(unsigned type)
 {
 	u64 start_count;
+	int width;
 
 	/* Register the CP15 based counter if we have one */
 	if (type & ARCH_TIMER_TYPE_CP15) {
@@ -1031,6 +1052,10 @@ static void __init arch_counter_register(unsigned type)
 		arch_timer_read_counter = arch_counter_get_cntvct_mem;
 	}
 
+	width = arch_counter_get_width();
+	clocksource_counter.mask = CLOCKSOURCE_MASK(width);
+	cyclecounter.mask = CLOCKSOURCE_MASK(width);
+
 	if (!arch_counter_suspend_stop)
 		clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 	start_count = arch_timer_read_counter();
@@ -1040,8 +1065,7 @@ static void __init arch_counter_register(unsigned type)
 	timecounter_init(&arch_timer_kvm_info.timecounter,
 			 &cyclecounter, start_count);
 
-	/* 56 bits minimum, so we assume worst case rollover */
-	sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
+	sched_clock_register(arch_timer_read_counter, width, arch_timer_rate);
 }
 
 static void arch_timer_stop(struct clock_event_device *clk)
-- 
2.32.0.605.g8dce9f2422-goog



From linus.walleij at linaro.org  Sat Aug  7 15:30:20 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 8 Aug 2021 00:30:20 +0200
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <20210807191428.3488948-1-oupton@google.com>
References: <20210807191428.3488948-1-oupton@google.com>
Message-ID: <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>

On Sat, Aug 7, 2021 at 9:14 PM Oliver Upton <oupton at google.com> wrote:

> Unfortunately, the architecture provides no means to determine the bit
> width of the system counter. However, we do know the following from the
> specification:
>
>  - the system counter is at least 56 bits wide
>  - Roll-over time of not less than 40 years
>
> To date, the arch timer driver has depended on the first property,
> assuming any system counter to be 56 bits wide and masking off the rest.
> However, combining a narrow clocksource mask with a high frequency
> counter could result in prematurely wrapping the system counter by a
> significant margin. For example, a 56 bit wide, 1GHz system counter
> would wrap in a mere 2.28 years!
>
> This is a problem for two reasons: v8.6+ implementations are required to
> provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> implementers may select a counter frequency of their choosing.
>
> Fix the issue by deriving a valid clock mask based on the second
> property from above. Set the floor at 56 bits, since we know no system
> counter is narrower than that.
>
> Suggested-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Oliver Upton <oupton at google.com>

This patch looks good to me:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Just a thought that crossed my mind: as this is real hardware we are
talking about mostly, how hard would it be for arch_counter_get_width()
to detect how wide it actually is if nbits > 56?

I would do something like this pseudocode:

nbits = 56;
while (nbits < 64)
    startval = GENMASK(nbits, 0);
    write_counter(startval);
    start_counter;
    nsleep(1);
    stop_counter;
    now = read_counter;
    if (now < startval)
         /* Ooops it wrapped */
         break;
    nbits++

pr_info("counter has %d bits\n", nbits);

Or did you folks already try this approach?

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Aug  7 15:55:18 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun,  8 Aug 2021 00:55:18 +0200
Subject: [PATCH] ARM: configs: Update the nhk8815_defconfig
Message-ID: <20210807225518.3607126-1-linus.walleij@linaro.org>

The platform lost the framebuffer due to a commit solving a
circular dependency in v5.14-rc1, so add it back in by explicitly
selecting the framebuffer.

Also fix up some Kconfig options that got dropped or moved around
while we're at it.

Fixes: f611b1e7624c ("drm: Avoid circular dependencies for CONFIG_FB")
Cc: Kees Cook <keescook at chromium.org>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
SoC maintainers: please apply this directly for fixes.
---
 arch/arm/configs/nhk8815_defconfig | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index 3f35761dc9ff..23595fc5a29a 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -15,8 +15,6 @@ CONFIG_SLAB=y
 CONFIG_ARCH_NOMADIK=y
 CONFIG_MACH_NOMADIK_8815NHK=y
 CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
@@ -52,9 +50,9 @@ CONFIG_MTD_BLOCK=y
 CONFIG_MTD_ONENAND=y
 CONFIG_MTD_ONENAND_VERIFY_WRITE=y
 CONFIG_MTD_ONENAND_GENERIC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_FSMC=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=y
 CONFIG_BLK_DEV_RAM=y
@@ -97,6 +95,7 @@ CONFIG_REGULATOR=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_TPO_TPG110=y
 CONFIG_DRM_PL111=y
+CONFIG_FB=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
@@ -136,9 +135,8 @@ CONFIG_NLS_ISO8859_15=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_DES=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_SCHED_DEBUG is not set
 # CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-- 
2.31.1



From linus.walleij at linaro.org  Sat Aug  7 16:00:16 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun,  8 Aug 2021 01:00:16 +0200
Subject: [PATCH] bus: ixp4xx: return on error in ixp4xx_exp_probe()
Message-ID: <20210807230016.3607666-1-linus.walleij@linaro.org>

From: Dan Carpenter <dan.carpenter at oracle.com>

This code was intended to return an error code if regmap_read() fails
but the return statement was missing.

Fixes: 1c953bda90ca ("bus: ixp4xx: Add a driver for IXP4xx expansion bus")
Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
SoC maintainers: please apply this to the same branch where the
bus changes in the pull request "ixp4xx-drivers-arm-soc-v5.15-1"
was pulled in.
---
 drivers/bus/intel-ixp4xx-eb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bus/intel-ixp4xx-eb.c b/drivers/bus/intel-ixp4xx-eb.c
index 9acd00da413c..a4388440aca7 100644
--- a/drivers/bus/intel-ixp4xx-eb.c
+++ b/drivers/bus/intel-ixp4xx-eb.c
@@ -369,7 +369,7 @@ static int ixp4xx_exp_probe(struct platform_device *pdev)
 	/* We check that the regmap work only on first read */
 	ret = regmap_read(eb->rmap, IXP4XX_EXP_CNFG0, &val);
 	if (ret)
-		dev_err_probe(dev, ret, "cannot read regmap\n");
+		return dev_err_probe(dev, ret, "cannot read regmap\n");
 	if (val & IXP4XX_EXP_CNFG0_MEM_MAP)
 		eb->bus_base = IXP4XX_EXP_BOOT_BASE;
 	else
-- 
2.31.1



From mick at ics.forth.gr  Sat Aug  7 16:05:34 2021
From: mick at ics.forth.gr (Nick Kossifidis)
Date: Sun, 08 Aug 2021 02:05:34 +0300
Subject: [PATCH v2] memblock: make memblock_find_in_range method private
In-Reply-To: <20210802063737.22733-1-rppt@kernel.org>
References: <20210802063737.22733-1-rppt@kernel.org>
Message-ID: <d0965f23c7ffb6b46a5b033fe242fc25@mailhost.ics.forth.gr>

???? 2021-08-02 09:37, Mike Rapoport ??????:
> From: Mike Rapoport <rppt at linux.ibm.com>
> 
> There are a lot of uses of memblock_find_in_range() along with
> memblock_reserve() from the times memblock allocation APIs did not 
> exist.
> 
> memblock_find_in_range() is the very core of memblock allocations, so 
> any
> future changes to its internal behaviour would mandate updates of all 
> the
> users outside memblock.
> 
> Replace the calls to memblock_find_in_range() with an equivalent calls 
> to
> memblock_phys_alloc() and memblock_phys_alloc_range() and make
> memblock_find_in_range() private method of memblock.
> 
> This simplifies the callers, ensures that (unlikely) errors in
> memblock_reserve() are handled and improves maintainability of
> memblock_find_in_range().
> 
> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
> ---
> v2: don't change error message in arm::reserve_crashkernel(), per 
> Russell
> v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org
> 
>  arch/arm/kernel/setup.c           | 18 +++++--------
>  arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
>  arch/arm64/mm/init.c              | 36 ++++++++-----------------
>  arch/mips/kernel/setup.c          | 14 +++++-----
>  arch/riscv/mm/init.c              | 44 ++++++++++---------------------
>  arch/s390/kernel/setup.c          | 10 ++++---
>  arch/x86/kernel/aperture_64.c     |  5 ++--
>  arch/x86/mm/init.c                | 21 +++++++++------
>  arch/x86/mm/numa.c                |  5 ++--
>  arch/x86/mm/numa_emulation.c      |  5 ++--
>  arch/x86/realmode/init.c          |  2 +-
>  drivers/acpi/tables.c             |  5 ++--
>  drivers/base/arch_numa.c          |  5 +---
>  drivers/of/of_reserved_mem.c      | 12 ++++++---
>  include/linux/memblock.h          |  2 --
>  mm/memblock.c                     |  2 +-
>  16 files changed, 78 insertions(+), 117 deletions(-)
> 
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index f97eb2371672..67f5421b2af7 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
>  		unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
>  		if (crash_max > lowmem_max)
>  			crash_max = lowmem_max;
> -		crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
> -						    crash_size, CRASH_ALIGN);
> +
> +		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> +						       CRASH_ALIGN, crash_max);
>  		if (!crash_base) {
>  			pr_err("crashkernel reservation failed - No suitable area 
> found.\n");
>  			return;
>  		}
>  	} else {
> +		unsigned long long crash_max = crash_base + crash_size;
>  		unsigned long long start;
> 
> -		start = memblock_find_in_range(crash_base,
> -					       crash_base + crash_size,
> -					       crash_size, SECTION_SIZE);
> +		start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
> +						  crash_base, crash_max);
>  		if (start != crash_base) {
>  			pr_err("crashkernel reservation failed - memory is in use.\n");
>  			return;
>  		}
>  	}
> 
> -	ret = memblock_reserve(crash_base, crash_size);
> -	if (ret < 0) {
> -		pr_warn("crashkernel reservation failed - memory is in use 
> (0x%lx)\n",
> -			(unsigned long)crash_base);
> -		return;
> -	}
> -
>  	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System
> RAM: %ldMB)\n",
>  		(unsigned long)(crash_size >> 20),
>  		(unsigned long)(crash_base >> 20),
> diff --git a/arch/arm64/kvm/hyp/reserved_mem.c
> b/arch/arm64/kvm/hyp/reserved_mem.c
> index d654921dd09b..578670e3f608 100644
> --- a/arch/arm64/kvm/hyp/reserved_mem.c
> +++ b/arch/arm64/kvm/hyp/reserved_mem.c
> @@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
>  	 * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
>  	 */
>  	hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
> -	hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> -					      ALIGN(hyp_mem_size, PMD_SIZE),
> -					      PMD_SIZE);
> +	hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
> +					   PMD_SIZE);
>  	if (!hyp_mem_base)
> -		hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> -						      hyp_mem_size, PAGE_SIZE);
> +		hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
>  	else
>  		hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
> 
> @@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
>  		kvm_err("Failed to reserve hyp memory\n");
>  		return;
>  	}
> -	memblock_reserve(hyp_mem_base, hyp_mem_size);
> 
>  	kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
>  		 hyp_mem_base);
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 8490ed2917ff..d566478a06dd 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>  static void __init reserve_crashkernel(void)
>  {
>  	unsigned long long crash_base, crash_size;
> +	unsigned long crash_max = arm64_dma_phys_limit;
>  	int ret;
> 
>  	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> @@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
> 
>  	crash_size = PAGE_ALIGN(crash_size);
> 
> -	if (crash_base == 0) {
> -		/* Current arm64 boot protocol requires 2MB alignment */
> -		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
> -				crash_size, SZ_2M);
> -		if (crash_base == 0) {
> -			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> -				crash_size);
> -			return;
> -		}
> -	} else {
> -		/* User specifies base address explicitly. */
> -		if (!memblock_is_region_memory(crash_base, crash_size)) {
> -			pr_warn("cannot reserve crashkernel: region is not memory\n");
> -			return;
> -		}
> +	/* User specifies base address explicitly. */
> +	if (crash_base)
> +		crash_max = crash_base + crash_size;
> 
> -		if (memblock_is_region_reserved(crash_base, crash_size)) {
> -			pr_warn("cannot reserve crashkernel: region overlaps reserved 
> memory\n");
> -			return;
> -		}
> -
> -		if (!IS_ALIGNED(crash_base, SZ_2M)) {
> -			pr_warn("cannot reserve crashkernel: base address is not 2MB 
> aligned\n");
> -			return;
> -		}
> +	/* Current arm64 boot protocol requires 2MB alignment */
> +	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> +					       crash_base, crash_max);
> +	if (!crash_base) {
> +		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> +			crash_size);
> +		return;
>  	}
> -	memblock_reserve(crash_base, crash_size);
> 
>  	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>  		crash_base, crash_base + crash_size, crash_size >> 20);
> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> index 23a140327a0b..f979adfd4fc2 100644
> --- a/arch/mips/kernel/setup.c
> +++ b/arch/mips/kernel/setup.c
> @@ -452,8 +452,9 @@ static void __init mips_parse_crashkernel(void)
>  		return;
> 
>  	if (crash_base <= 0) {
> -		crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX,
> -							crash_size, CRASH_ALIGN);
> +		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> +						       CRASH_ALIGN,
> +						       CRASH_ADDR_MAX);
>  		if (!crash_base) {
>  			pr_warn("crashkernel reservation failed - No suitable area 
> found.\n");
>  			return;
> @@ -461,8 +462,9 @@ static void __init mips_parse_crashkernel(void)
>  	} else {
>  		unsigned long long start;
> 
> -		start = memblock_find_in_range(crash_base, crash_base + crash_size,
> -						crash_size, 1);
> +		start = memblock_phys_alloc_range(crash_size, 1,
> +						  crash_base,
> +						  crash_base + crash_size);
>  		if (start != crash_base) {
>  			pr_warn("Invalid memory region reserved for crash kernel\n");
>  			return;
> @@ -656,10 +658,6 @@ static void __init arch_mem_init(char **cmdline_p)
>  	mips_reserve_vmcore();
> 
>  	mips_parse_crashkernel();
> -#ifdef CONFIG_KEXEC
> -	if (crashk_res.start != crashk_res.end)
> -		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
> -#endif
>  	device_tree_init();
> 
>  	/*
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index a14bf3910eec..88649337c568 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -812,38 +812,22 @@ static void __init reserve_crashkernel(void)
> 
>  	crash_size = PAGE_ALIGN(crash_size);
> 
> -	if (crash_base == 0) {
> -		/*
> -		 * Current riscv boot protocol requires 2MB alignment for
> -		 * RV64 and 4MB alignment for RV32 (hugepage size)
> -		 */
> -		crash_base = memblock_find_in_range(search_start, search_end,
> -						    crash_size, PMD_SIZE);
> -
> -		if (crash_base == 0) {
> -			pr_warn("crashkernel: couldn't allocate %lldKB\n",
> -				crash_size >> 10);
> -			return;
> -		}
> -	} else {
> -		/* User specifies base address explicitly. */
> -		if (!memblock_is_region_memory(crash_base, crash_size)) {
> -			pr_warn("crashkernel: requested region is not memory\n");
> -			return;
> -		}
> -
> -		if (memblock_is_region_reserved(crash_base, crash_size)) {
> -			pr_warn("crashkernel: requested region is reserved\n");
> -			return;
> -		}
> -
> +	if (crash_base) {
> +		search_start = crash_base;
> +		search_end = crash_base + crash_size;
> +	}
> 
> -		if (!IS_ALIGNED(crash_base, PMD_SIZE)) {
> -			pr_warn("crashkernel: requested region is misaligned\n");
> -			return;
> -		}
> +	/*
> +	 * Current riscv boot protocol requires 2MB alignment for
> +	 * RV64 and 4MB alignment for RV32 (hugepage size)
> +	 */
> +	crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
> +					       search_start, search_end);
> +	if (crash_base == 0) {
> +		pr_warn("crashkernel: couldn't allocate %lldKB\n",
> +			crash_size >> 10);
> +		return;
>  	}
> -	memblock_reserve(crash_base, crash_size);
> 
>  	pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n",
>  		crash_base, crash_base + crash_size, crash_size >> 20);

For the riscv part:

Acked-by: Nick Kossifidis <mick at ics.forth.gr>


From oupton at google.com  Sat Aug  7 18:14:35 2021
From: oupton at google.com (Oliver Upton)
Date: Sat, 7 Aug 2021 18:14:35 -0700
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>
References: <20210807191428.3488948-1-oupton@google.com>
 <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>
Message-ID: <CAOQ_QsiECN7iVDyiyos12tk__viGkFhH9b6ZfkZVAYjeKhB=pQ@mail.gmail.com>

Hi Linus,

On Sat, Aug 7, 2021 at 3:30 PM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Sat, Aug 7, 2021 at 9:14 PM Oliver Upton <oupton at google.com> wrote:
>
> > Unfortunately, the architecture provides no means to determine the bit
> > width of the system counter. However, we do know the following from the
> > specification:
> >
> >  - the system counter is at least 56 bits wide
> >  - Roll-over time of not less than 40 years
> >
> > To date, the arch timer driver has depended on the first property,
> > assuming any system counter to be 56 bits wide and masking off the rest.
> > However, combining a narrow clocksource mask with a high frequency
> > counter could result in prematurely wrapping the system counter by a
> > significant margin. For example, a 56 bit wide, 1GHz system counter
> > would wrap in a mere 2.28 years!
> >
> > This is a problem for two reasons: v8.6+ implementations are required to
> > provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> > implementers may select a counter frequency of their choosing.
> >
> > Fix the issue by deriving a valid clock mask based on the second
> > property from above. Set the floor at 56 bits, since we know no system
> > counter is narrower than that.
> >
> > Suggested-by: Marc Zyngier <maz at kernel.org>
> > Signed-off-by: Oliver Upton <oupton at google.com>
>
> This patch looks good to me:
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>

Thanks for the review!

> Just a thought that crossed my mind: as this is real hardware we are
> talking about mostly, how hard would it be for arch_counter_get_width()
> to detect how wide it actually is if nbits > 56?
>
> I would do something like this pseudocode:
>
> nbits = 56;
> while (nbits < 64)
>     startval = GENMASK(nbits, 0);
>     write_counter(startval);
>     start_counter;
>     nsleep(1);
>     stop_counter;
>     now = read_counter;
>     if (now < startval)
>          /* Ooops it wrapped */
>          break;
>     nbits++
>
> pr_info("counter has %d bits\n", nbits);
>
> Or did you folks already try this approach?

This would be a good idea, although I believe our only means of
offsetting the counter are available in EL2. I had thought we could
use a CVAL register instead, but this quote from the ARM ARM doesn't
imply the CVAL bit width matches that of the system counter:

<quote>
If the Generic counter is implemented at a size less than 64 bits,
then this field is permitted to be implemented at the same width as
the counter, and the upper bits are RES0.
</quote>

The only other sane idea that I could come up with is providing this
information to the kernel through DT, although that would leave ACPI
systems behind.

--
Thanks,
Oliver


From daniel at makrotopia.org  Sat Aug  7 20:27:49 2021
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 8 Aug 2021 04:27:49 +0100
Subject: [PATCH] ARM: kirkwood: add missing <linux/if_ether.h> for ETH_ALEN
In-Reply-To: <YQ6WCK0Sytb0nxj9@lunn.ch>
References: <YQxk4jrbm31NM1US@makrotopia.org>
 <cde9de20efd3a75561080751766edbec@walle.cc>
 <YQ6WCK0Sytb0nxj9@lunn.ch>
Message-ID: <YQ9PNeka8VhZqxGR@makrotopia.org>

Hi Andrew,

On Sat, Aug 07, 2021 at 04:17:44PM +0200, Andrew Lunn wrote:
> > What kernel is this? I've just tested with this exact commit as
> > base and it compiles just fine.
> > 
> > I'm not saying including the file is wrong, but it seems it isn't
> > needed in the upstream kernel and I don't know if it qualifies for
> > the stable queue therefore.
> 
> I would like to see a reproducer for mainline. Do you have a kernel
> config which generates the problem.

I encountered the problem when building the 'kirkwood' target in
OpenWrt. I have now tried building vanilla, and the problem indeed
doesn't exist. After tracing the header includes with the precompiler
for some time I concluded that <linux/of_net.h> included in kirkwood.c
includes <linux/phy.h> which includes <linux/ethtool.h> which includes
<uapi/linux/ethtool.h> which includes <uapi/linux/if_ether.h> which
includes <linux/if_ether.h> which defined ETH_ALEN.

When building OpenWrt kernel which includes a backport of
"of: net: pass the dst buffer to of_get_mac_address()", this is not the
same as <linux/of_net.h> doesn't include <linux/phy.h> yet. This is
because we miss commit 0c65b2b90d13c1 ("net: of_get_phy_mode: Change
API to solve int/unit warnings") which has been in mainline for a long
time.

> The change itself does seems reasonable, so if we can reproduce it, i
> would be happy to merge it for stable.

Sorry for the noise caused, I'm not sure what the policy is in this
case, but certainly this is *not* a regression which should make it to
stable asap. The long and confusing chain of includes which lead to the
ETH_ALEN macro being defined in arch/arm/mach-mvebu/kirkwood.c is
certainly not ideal, and in case you still consider this patch worth
merging, I will post v2 with re-written commit description.


From stefan.wahren at i2se.com  Sun Aug  8 00:45:28 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun, 8 Aug 2021 09:45:28 +0200
Subject: [PATCH v2 0/2] staging: vchiq: Fixups to Kconfig
In-Reply-To: <cover.1627925241.git.ojaswin98@gmail.com>
References: <cover.1627925241.git.ojaswin98@gmail.com>
Message-ID: <b2cba890-4838-7b43-c5c4-548f25e14f76@i2se.com>

Am 02.08.21 um 19:42 schrieb Ojaswin Mujoo:
> Hi everyone,
>
> This patchset performs some minor fixups to the config options defined in
> /staging/vc04_services/Kconfig. 
>
> Summary of the patches:
>
> Patch 1: Makes BCM2835_VCHIQ imply VCHIQ_CDEV to make the behavior more
>          compatible to how it was before VCHIQ_CDEV was introduced (in
>          [1]).
> Patch 2: Add some more details to the configs' help texts
>
>
> Changes since v1 [2]:
>
> *  As pre discussion with Greg and Stefan, used "imply" in BCM2835_VCHIQ
>    instead of "default y" in VCHIQ_CDEV.
> *  Added some more info in help texts of both the config options.
>
> In patch 2, although the resources on VideoCore and vchiq are really
> scattered around the internet, I've tried to keep the help text as
> accurate as possible, as per my knowledge.
> Please do let me know if anything is off in it and I'll fix it.

The whole series is:

Reviewed-by: Stefan Wahren <stefan.wahren at i2se.com>

Thanks



From rppt at kernel.org  Sun Aug  8 01:23:08 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Sun, 8 Aug 2021 11:23:08 +0300
Subject: [RFC PATCH 14/15] mm: introduce MIN_MAX_ORDER to replace
 MAX_ORDER as compile time constant.
In-Reply-To: <20210805190253.2795604-15-zi.yan@sent.com>
References: <20210805190253.2795604-1-zi.yan@sent.com>
 <20210805190253.2795604-15-zi.yan@sent.com>
Message-ID: <YQ+UbJtSWciIVqr4@kernel.org>

On Thu, Aug 05, 2021 at 03:02:52PM -0400, Zi Yan wrote:
> From: Zi Yan <ziy at nvidia.com>
> 
> For other MAX_ORDER uses (described below), there is no need or too much
> hassle to convert certain static array to dynamic ones. Add
> MIN_MAX_ORDER to serve as compile time constant in place of MAX_ORDER.
> 
> ARM64 hypervisor maintains its own free page list and does not import
> any core kernel symbols, so soon-to-be runtime variable MAX_ORDER is not
> accessible in ARM64 hypervisor code. Also there is no need to allocating
> very large pages.
> 
> In SLAB/SLOB/SLUB, 2-D array kmalloc_caches uses MAX_ORDER in its second
> dimension. It is too much hassle to allocate memory for kmalloc_caches
> before any proper memory allocator is set up.
> 
> Signed-off-by: Zi Yan <ziy at nvidia.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Christoph Lameter <cl at linux.com>
> Cc: Vlastimil Babka <vbabka at suse.cz>
> Cc: Quentin Perret <qperret at google.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-mm at kvack.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  arch/arm64/kvm/hyp/include/nvhe/gfp.h | 2 +-
>  arch/arm64/kvm/hyp/nvhe/page_alloc.c  | 3 ++-
>  include/linux/mmzone.h                | 3 +++
>  include/linux/slab.h                  | 8 ++++----
>  mm/slab.c                             | 2 +-
>  mm/slub.c                             | 7 ++++---
>  6 files changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> index fb0f523d1492..c774b4a98336 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
> @@ -16,7 +16,7 @@ struct hyp_pool {
>  	 * API at EL2.
>  	 */
>  	hyp_spinlock_t lock;
> -	struct list_head free_area[MAX_ORDER];
> +	struct list_head free_area[MIN_MAX_ORDER];
>  	phys_addr_t range_start;
>  	phys_addr_t range_end;
>  	unsigned short max_order;
> diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> index 41fc25bdfb34..a1cc1b648de0 100644
> --- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> +++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
> @@ -226,7 +226,8 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
>  	int i;
>  
>  	hyp_spin_lock_init(&pool->lock);
> -	pool->max_order = min(MAX_ORDER, get_order(nr_pages << PAGE_SHIFT));
> +
> +	pool->max_order = min(MIN_MAX_ORDER, get_order(nr_pages << PAGE_SHIFT));
>  	for (i = 0; i < pool->max_order; i++)
>  		INIT_LIST_HEAD(&pool->free_area[i]);
>  	pool->range_start = phys;
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index 09aafc05aef4..379dada82d4b 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -27,11 +27,14 @@
>  #ifndef CONFIG_ARCH_FORCE_MAX_ORDER
>  #ifdef CONFIG_SET_MAX_ORDER
>  #define MAX_ORDER CONFIG_SET_MAX_ORDER
> +#define MIN_MAX_ORDER CONFIG_SET_MAX_ORDER
>  #else
>  #define MAX_ORDER 11
> +#define MIN_MAX_ORDER MAX_ORDER
>  #endif /* CONFIG_SET_MAX_ORDER */
>  #else
>  #define MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
> +#define MIN_MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
>  #endif /* CONFIG_ARCH_FORCE_MAX_ORDER */
>  #define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))

The end result of this #ifdef explosion looks entirely unreadable:

/* Free memory management - zoned buddy allocator.  */
#ifndef CONFIG_ARCH_FORCE_MAX_ORDER
#ifdef CONFIG_SET_MAX_ORDER
/* Defined in mm/page_alloc.c */
extern int buddy_alloc_max_order;

#define MAX_ORDER buddy_alloc_max_order
#define MIN_MAX_ORDER CONFIG_SET_MAX_ORDER
#else
#define MAX_ORDER 11
#define MIN_MAX_ORDER MAX_ORDER
#endif /* CONFIG_SET_MAX_ORDER */
#else

#ifdef CONFIG_SPARSEMEM_VMEMMAP
/* Defined in mm/page_alloc.c */
extern int buddy_alloc_max_order;

#define MAX_ORDER buddy_alloc_max_order
#else
#define MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
#define MIN_MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
#endif /* CONFIG_ARCH_FORCE_MAX_ORDER */

> diff --git a/include/linux/slab.h b/include/linux/slab.h
> index 2c0d80cca6b8..d8747c158db6 100644
> --- a/include/linux/slab.h
> +++ b/include/linux/slab.h
> @@ -244,8 +244,8 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
>   * to do various tricks to work around compiler limitations in order to
>   * ensure proper constant folding.
>   */
> -#define KMALLOC_SHIFT_HIGH	((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
> -				(MAX_ORDER + PAGE_SHIFT - 1) : 25)
> +#define KMALLOC_SHIFT_HIGH	((MIN_MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
> +				(MIN_MAX_ORDER + PAGE_SHIFT - 1) : 25)
>  #define KMALLOC_SHIFT_MAX	KMALLOC_SHIFT_HIGH
>  #ifndef KMALLOC_SHIFT_LOW
>  #define KMALLOC_SHIFT_LOW	5
> @@ -258,7 +258,7 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
>   * (PAGE_SIZE*2).  Larger requests are passed to the page allocator.
>   */
>  #define KMALLOC_SHIFT_HIGH	(PAGE_SHIFT + 1)
> -#define KMALLOC_SHIFT_MAX	(MAX_ORDER + PAGE_SHIFT - 1)
> +#define KMALLOC_SHIFT_MAX	(MIN_MAX_ORDER + PAGE_SHIFT - 1)
>  #ifndef KMALLOC_SHIFT_LOW
>  #define KMALLOC_SHIFT_LOW	3
>  #endif
> @@ -271,7 +271,7 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
>   * be allocated from the same page.
>   */
>  #define KMALLOC_SHIFT_HIGH	PAGE_SHIFT
> -#define KMALLOC_SHIFT_MAX	(MAX_ORDER + PAGE_SHIFT - 1)
> +#define KMALLOC_SHIFT_MAX	(MIN_MAX_ORDER + PAGE_SHIFT - 1)
>  #ifndef KMALLOC_SHIFT_LOW
>  #define KMALLOC_SHIFT_LOW	3
>  #endif
> diff --git a/mm/slab.c b/mm/slab.c
> index d0f725637663..0041de8ec0e9 100644
> --- a/mm/slab.c
> +++ b/mm/slab.c
> @@ -466,7 +466,7 @@ static int __init slab_max_order_setup(char *str)
>  {
>  	get_option(&str, &slab_max_order);
>  	slab_max_order = slab_max_order < 0 ? 0 :
> -				min(slab_max_order, MAX_ORDER - 1);
> +				min(slab_max_order, MIN_MAX_ORDER - 1);
>  	slab_max_order_set = true;
>  
>  	return 1;
> diff --git a/mm/slub.c b/mm/slub.c
> index b6c5205252eb..228e4a77c678 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -3564,8 +3564,9 @@ static inline int calculate_order(unsigned int size)
>  	/*
>  	 * Doh this slab cannot be placed using slub_max_order.
>  	 */
> -	order = slab_order(size, 1, MAX_ORDER, 1);
> -	if (order < MAX_ORDER)
> +
> +	order = slab_order(size, 1, MIN_MAX_ORDER, 1);
> +	if (order < MIN_MAX_ORDER)
>  		return order;
>  	return -ENOSYS;
>  }
> @@ -4079,7 +4080,7 @@ __setup("slub_min_order=", setup_slub_min_order);
>  static int __init setup_slub_max_order(char *str)
>  {
>  	get_option(&str, (int *)&slub_max_order);
> -	slub_max_order = min(slub_max_order, (unsigned int)MAX_ORDER - 1);
> +	slub_max_order = min(slub_max_order, (unsigned int)MIN_MAX_ORDER - 1);
>  
>  	return 1;
>  }
> -- 
> 2.30.2
> 

-- 
Sincerely yours,
Mike.


From maz at kernel.org  Sun Aug  8 03:19:09 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 08 Aug 2021 11:19:09 +0100
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <MW4PR21MB2002ABD170CC9786CDF5D493C0F39@MW4PR21MB2002.namprd21.prod.outlook.com>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>
 <87r1f9wooc.wl-maz@kernel.org>
 <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87wnp0b86y.wl-maz@kernel.org>
 <MW4PR21MB2002ABD170CC9786CDF5D493C0F39@MW4PR21MB2002.namprd21.prod.outlook.com>
Message-ID: <87o8a81boi.wl-maz@kernel.org>

On Fri, 06 Aug 2021 20:14:13 +0100,
Sunil Muthuswamy <sunilmut at microsoft.com> wrote:
> 
> On Thursday, August 5, 2021 1:35 AM,
> Marc Zyngier <maz at kernel.org> wrote:
> [...]
> > > Hey Mark
> > 
> > I assume this is for me?
> > 
> Yes, sorry.
> 
> > > would you be willing to consider a scoped down implementation of GIC
> > > Direct LPI with just an IRQ chip implementation and no Direct LPI
> > > PCI-MSI IRQ chip.
> > 
> > Could you please clarify? If you are not implementing MSIs, how can a
> > device signal LPIs? At the end of the day, something has to write into
> > the RD, and it isn't going to happen by sheer magic.
> > 
> > > This will allow a MSI provider (such as Hyper-V vPCI) to provide a
> > > PCI-MSI IRQ chip on top of the Direct LPI IRQ chip and enable
> > > PCI-MSI scenarios, and avoid building in assumptions in other cases
> > > (like PCI) where firmware specification is not available.
> > 
> > I really don't get what you are suggesting. Could you please describe
> > what you have in mind?
> > 
> The suggestion was to *not* implement the PCI-MSI IRQ chip in the
> Direct LPI GIC implementation, but let the endpoint/specific
> implementation provide for the MSI IRQ chip.
> 
> For example, the Hyper-V vPCI module does implement a PCI-MSI IRQ
> chip (refer to 'hv_pcie_init_irq_domain'). Microsoft Hypervisor
> provides/virtualizes the MSI address to be used for Hyper-V vPCI. The
> Hypervisor might be using the ITS in the background, but it expects
> the device to be programmed with the MSI address that it provides.
> And, the Hypervisor takes care of routing the interrupt to the guest.
> This is done by the Hyper-V vPCI MSI IRQ chip (refer to
> hv_msi_irq_chip) compose MSI message.
> 
> Today, for X64, Hyper-V vPCI PCI-MSI irq chip parents itself to the
> architectural 'x86_vector_domain'. The suggestion here was to see
> if we can support a similar setup for ARM, where the Hyper-V vPCI
> PCI-MSI irq chip can parent itself to the 'Direct LPI arch IRQ chip'
> (to be implemented).
> 
> The arch Direct LPI arch IRQ chip is needed to enable LPIs, invalidate
> the LPI configuration (GICR_INVLPIR et. al. ) and allocate LPI IRQs from
> the LPI interrupt namespace (i.e. 8192-<num LPIS>).
> 
> Happy to expand on this further, if the above is not clear.

[+Lorenzo, as he deals with both PCI and ACPI]

I think it is clear enough, but I don't see what this buys us other
than turning DirectLPI into something that is essentially private to
Hyper-V, just for the sake of sidestepping a firmware description.
Furthermore, the Hyper-V "single MSI address" model doesn't match the
way DirectLPI works (after all, this is one of the many reasons why we
have the ITS).

The architecture already gives you everything you need to make things
work in Hyper-V. You can easily implement the DirectLPI support (you
definitely need most of it anyway), and the PCI-MSI layer is
*free*. All you need is a firmware description. Which I don't believe
is the end of the world, given that DT is freely hackable and that
IORT is an ARM-private extension to ACPI. I'm sure you know who to
reach out to in order to start a draft (and if you don't, I can give
you names offline).

I am not interested in expanding the GICv3 architecture support if it
cannot be generally used in a way that is *compliant with the
architecture*. If you think DirectLPIs can make the hypervisor
simpler, I'm fine with it. But let's fully embrace the concept instead
of hiding it behind a layer of PV muck. It will even have a chance of
working on bare metal (such as on the machine that is humming behind
me, or even the Fast Model).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Sun Aug  8 03:29:52 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 08 Aug 2021 11:29:52 +0100
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>
References: <20210807191428.3488948-1-oupton@google.com>
 <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>
Message-ID: <87mtps1b6n.wl-maz@kernel.org>

On Sat, 07 Aug 2021 23:30:20 +0100,
Linus Walleij <linus.walleij at linaro.org> wrote:
> 
> On Sat, Aug 7, 2021 at 9:14 PM Oliver Upton <oupton at google.com> wrote:
> 
> > Unfortunately, the architecture provides no means to determine the bit
> > width of the system counter. However, we do know the following from the
> > specification:
> >
> >  - the system counter is at least 56 bits wide
> >  - Roll-over time of not less than 40 years
> >
> > To date, the arch timer driver has depended on the first property,
> > assuming any system counter to be 56 bits wide and masking off the rest.
> > However, combining a narrow clocksource mask with a high frequency
> > counter could result in prematurely wrapping the system counter by a
> > significant margin. For example, a 56 bit wide, 1GHz system counter
> > would wrap in a mere 2.28 years!
> >
> > This is a problem for two reasons: v8.6+ implementations are required to
> > provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> > implementers may select a counter frequency of their choosing.
> >
> > Fix the issue by deriving a valid clock mask based on the second
> > property from above. Set the floor at 56 bits, since we know no system
> > counter is narrower than that.
> >
> > Suggested-by: Marc Zyngier <maz at kernel.org>
> > Signed-off-by: Oliver Upton <oupton at google.com>
> 
> This patch looks good to me:
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> 
> Just a thought that crossed my mind: as this is real hardware we are
> talking about mostly, how hard would it be for arch_counter_get_width()
> to detect how wide it actually is if nbits > 56?
> 
> I would do something like this pseudocode:
> 
> nbits = 56;
> while (nbits < 64)
>     startval = GENMASK(nbits, 0);
>     write_counter(startval);

That's where things stop. The counter is not writable, and for good
reasons (it is shared with all the CPUs in the system).

>     start_counter;
>     nsleep(1);
>     stop_counter;
>     now = read_counter;
>     if (now < startval)
>          /* Ooops it wrapped */
>          break;
>     nbits++
> 
> pr_info("counter has %d bits\n", nbits);
> 
> Or did you folks already try this approach?

The only way to emulate this behaviour is to use CNTVOFF_EL2 at EL2 to
offset a guest view of the counter, and to run minimal guest that will
do the start/stop/compare work. Given that it involves running a guest
at a point where we are unable to do so, and that it cannot work when
booted at EL1, we're left with guesswork.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Sun Aug  8 03:40:30 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 08 Aug 2021 11:40:30 +0100
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <CAOQ_QsiECN7iVDyiyos12tk__viGkFhH9b6ZfkZVAYjeKhB=pQ@mail.gmail.com>
References: <20210807191428.3488948-1-oupton@google.com>
 <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>
 <CAOQ_QsiECN7iVDyiyos12tk__viGkFhH9b6ZfkZVAYjeKhB=pQ@mail.gmail.com>
Message-ID: <87lf5c1aox.wl-maz@kernel.org>

On Sun, 08 Aug 2021 02:14:35 +0100,
Oliver Upton <oupton at google.com> wrote:

> The only other sane idea that I could come up with is providing this
> information to the kernel through DT, although that would leave ACPI
> systems behind.

It also has the disadvantage that a large number of DT timer nodes are
a mess of cargo-culted, copy-pasted idioms, and that adding another
property would only make it worse. I'm more confident with something
that can be either:

- checked from EL2 using CNTVOFF, which is complicated, doesn't work
  at EL1, and leaves us in a weird state if we have different counter
  width views in the system (BL is such a wonderful concept)

- or computed from first principle based on the requirements of the
  architecture.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From mans0n at gorani.run  Sun Aug  8 05:38:38 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Sun,  8 Aug 2021 21:38:38 +0900
Subject: [PATCH v2 0/2] Add MUSB for MT7623
In-Reply-To: <20210803151320.71531-1-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
Message-ID: <20210808123840.176738-1-mans0n@gorani.run>

These patches add support for the MUSB controller on Mediatek MT7623.
Tested on Mercury RUSH-318AC Wi-Fi router.

v2:
* dt-bindings
  * add reviewed by Matthias
* DTS
  * rename usb3 label to usb0
  * move usb0 & u2phy1 nodes to the right sorted place
  * disable u2phy1 by default
  * correct u2port2 node name to match its reg address

Sungbo Eo (2):
  dt-bindings: usb: mtk-musb: add MT7623 compatible
  arm: dts: mt7623: add musb device nodes

 .../bindings/usb/mediatek,musb.yaml           |  1 +
 arch/arm/boot/dts/mt7623.dtsi                 | 34 +++++++++++++++++++
 arch/arm/boot/dts/mt7623a.dtsi                |  4 +++
 3 files changed, 39 insertions(+)

-- 
2.32.0



From mans0n at gorani.run  Sun Aug  8 05:38:39 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Sun,  8 Aug 2021 21:38:39 +0900
Subject: [PATCH v2 1/2] dt-bindings: usb: mtk-musb: add MT7623 compatible
In-Reply-To: <20210808123840.176738-1-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <20210808123840.176738-1-mans0n@gorani.run>
Message-ID: <20210808123840.176738-2-mans0n@gorani.run>

Document MT7623 compatible for mtk-musb.

Signed-off-by: Sungbo Eo <mans0n at gorani.run>
Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
---
v2:
* add reviewed by Matthias
---
 Documentation/devicetree/bindings/usb/mediatek,musb.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,musb.yaml b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
index 84ddacfdbe9b..03d62d60ce5f 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,musb.yaml
@@ -19,6 +19,7 @@ properties:
       - enum:
           - mediatek,mt8516-musb
           - mediatek,mt2701-musb
+          - mediatek,mt7623-musb
       - const: mediatek,mtk-musb
 
   reg:
-- 
2.32.0



From mans0n at gorani.run  Sun Aug  8 05:38:40 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Sun,  8 Aug 2021 21:38:40 +0900
Subject: [PATCH v2 2/2] arm: dts: mt7623: add musb device nodes
In-Reply-To: <20210808123840.176738-1-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <20210808123840.176738-1-mans0n@gorani.run>
Message-ID: <20210808123840.176738-3-mans0n@gorani.run>

MT7623 has an musb controller that is compatible with the one from MT2701.

Signed-off-by: Sungbo Eo <mans0n at gorani.run>
---
v2:
* rename usb3 label to usb0
* move usb0 & u2phy1 nodes to the right sorted place
* disable u2phy1 by default
* correct u2port2 node name to match its reg address
---
 arch/arm/boot/dts/mt7623.dtsi  | 34 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
 2 files changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index 3c11f7cfcc40..790d74439cc6 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -585,6 +585,40 @@ spi2: spi at 11017000 {
 		status = "disabled";
 	};
 
+	usb0: usb at 11200000 {
+		compatible = "mediatek,mt7623-musb",
+			     "mediatek,mtk-musb";
+		reg = <0 0x11200000 0 0x1000>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "mc";
+		phys = <&u2port2 PHY_TYPE_USB2>;
+		dr_mode = "otg";
+		clocks = <&pericfg CLK_PERI_USB0>,
+			 <&pericfg CLK_PERI_USB0_MCU>,
+			 <&pericfg CLK_PERI_USB_SLV>;
+		clock-names = "main","mcu","univpll";
+		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
+		status = "disabled";
+	};
+
+	u2phy1: t-phy at 11210000 {
+		compatible = "mediatek,mt7623-tphy",
+			     "mediatek,generic-tphy-v1";
+		reg = <0 0x11210000 0 0x0800>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		u2port2: usb-phy at 11210800 {
+			reg = <0 0x11210800 0 0x0100>;
+			clocks = <&topckgen CLK_TOP_USB_PHY48M>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+	};
+
 	audsys: clock-controller at 11220000 {
 		compatible = "mediatek,mt7623-audsys",
 			     "mediatek,mt2701-audsys",
diff --git a/arch/arm/boot/dts/mt7623a.dtsi b/arch/arm/boot/dts/mt7623a.dtsi
index 0735a1fb8ad9..d304b62d24b5 100644
--- a/arch/arm/boot/dts/mt7623a.dtsi
+++ b/arch/arm/boot/dts/mt7623a.dtsi
@@ -35,6 +35,10 @@ &scpsys {
 	clock-names = "ethif";
 };
 
+&usb0 {
+	power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>;
+};
+
 &usb1 {
 	power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>;
 };
-- 
2.32.0



From len.baker at gmx.com  Sun Aug  8 05:50:09 2021
From: len.baker at gmx.com (Len Baker)
Date: Sun,  8 Aug 2021 14:50:09 +0200
Subject: [PATCH v4 0/3] drivers/soc: Remove all strcpy() uses
Message-ID: <20210808125012.4715-1-len.baker@gmx.com>

strcpy() performs no bounds checking on the destination buffer. This
could result in linear overflows beyond the end of the buffer, leading
to all kinds of misbehaviors. So use strscpy() or memcpy() as a safe
replacement.

This is a task of the KSPP [1].

Changelog v1 -> v2
- Change the "area_name_size" variable for a shorter name (Geert
  Uytterhoeven).
- Add the "Reviewed-by: Geert Uytterhoeven" tag.
- Use the memcpy function instead of strscpy function when the
  size of the destination buffer cannot be obtained with "sizeof"
  (David Laight, Robin Murphy).

Changelog v2 -> v3
- Remove the "Reviewed-by: Geert Uytterhoeven" tag since the code
  has changed after the v1 review (use of memcpy instead of
  strscpy).

Changelog v3 -> v4
- Split the changes in 3 commits (Bjorn Andersson).
- Don't break a long line (Bjorn Andersson).
- Reword the commit when used the memcpy function (Bjorn Andersson)

The previous version can be found here [2].

[1] https://github.com/KSPP/linux/issues/88
[2] https://lore.kernel.org/linux-hardening/20210801131958.6144-1-len.baker at gmx.com/

Len Baker (3):
  drivers/soc/qcom: Prefer strscpy over strcpy
  drivers/soc/renesas: Prefer memcpy over strcpy
  drivers/soc/ti: Prefer strscpy over strcpy

 drivers/soc/qcom/pdr_interface.c    | 12 ++++++------
 drivers/soc/renesas/r8a779a0-sysc.c |  6 ++++--
 drivers/soc/renesas/rcar-sysc.c     |  6 ++++--
 drivers/soc/ti/knav_dma.c           |  2 +-
 4 files changed, 15 insertions(+), 11 deletions(-)

--
2.25.1



From jitao.shi at mediatek.com  Sun Aug  8 06:24:30 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Sun, 8 Aug 2021 21:24:30 +0800
Subject: [PATCH v7 2/5] pwm: mtk_disp: fix force reg to working reg.
In-Reply-To: <20210808132433.66037-1-jitao.shi@mediatek.com>
References: <20210808132433.66037-1-jitao.shi@mediatek.com>
Message-ID: <20210808132433.66037-3-jitao.shi@mediatek.com>

The reg can't access when the clock is off.
Because the clocks "mm" and "main" prepare() and enabel() move to
mtk_disp_pwm_config() from probe(). So move the reg accress of
"reg double buffer" to mtk_disp_pwm_config() to.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 drivers/pwm/pwm-mtk-disp.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 3ade525adcc3..1070d78d4940 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -128,6 +128,17 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
 					 mdp->data->commit_mask,
 					 0x0);
+	} else {
+	/*
+	 * For MT2701, disable double buffer before writing register
+	 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
+	 */
+		mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
+					 mdp->data->bls_debug_mask,
+					 mdp->data->bls_debug_mask);
+		mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
+					 mdp->data->con0_sel,
+					 mdp->data->con0_sel);
 	}
 
 	clk_disable_unprepare(mdp->clk_mm);
@@ -213,19 +224,6 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mdp);
 
-	/*
-	 * For MT2701, disable double buffer before writing register
-	 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
-	 */
-	if (!mdp->data->has_commit) {
-		mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
-					 mdp->data->bls_debug_mask,
-					 mdp->data->bls_debug_mask);
-		mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
-					 mdp->data->con0_sel,
-					 mdp->data->con0_sel);
-	}
-
 	return 0;
 }
 
-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  8 06:24:28 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Sun, 8 Aug 2021 21:24:28 +0800
Subject: [PATCH v7 0/5] fix the clks on/off mismatch issue and switch
 pwm-mtk-disp to atomic APIs
Message-ID: <20210808132433.66037-1-jitao.shi@mediatek.com>

Changes since v6:
 - fix commit msg of "pwm: mtk_disp: fix force reg to working reg".
   Expain the reg access only when mm and main clock on.

Changes since v5:
 - fix overflow.
 - Seperate the reg shadow as a single patch.

Changes since v4:
 - Squash the commit "move the commit to clock enabled" to "adjust the clocks to avoid them mismatch".
 - Drop the useless comment about MT2701.
 - Reenable the clks "mm" and "main" in .enable().
 - Fix typo.
 - Seperate get_state() operation as single patch.

Changes since v3:
 - Seperate the clock sequence as single patch.
 - Fixup the reg commit when clocks sequence changed.
 - Merge the apply and get_state as single patch.

Changes since v2:
 - Change commit messages to remove the clock operations for atomic APIs.
 - Rebase to v5.13 rc1.

Changes since v1:
 - Seperate clock operation as single patch.
 - Seperate apply() as single patch.
 - Seperate get_state() operation as single patch.

Jitao Shi (5):
  pwm: mtk-disp: adjust the clocks to avoid them mismatch
  pwm: mtk_disp: fix force reg to working reg.
  pwm: mtk_disp: implement atomic API .apply()
  pwm: mtk_disp: fix overflow in period and duty calcalation
  pwm: mtk_disp: implement atomic API .get_state()

 drivers/pwm/pwm-mtk-disp.c | 172 ++++++++++++++++++++-----------------
 1 file changed, 92 insertions(+), 80 deletions(-)

-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  8 06:24:33 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Sun, 8 Aug 2021 21:24:33 +0800
Subject: [PATCH v7 5/5] pwm: mtk_disp: implement atomic API .get_state()
In-Reply-To: <20210808132433.66037-1-jitao.shi@mediatek.com>
References: <20210808132433.66037-1-jitao.shi@mediatek.com>
Message-ID: <20210808132433.66037-6-jitao.shi@mediatek.com>

Switch the driver to support the .get_state() method.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 drivers/pwm/pwm-mtk-disp.c | 41 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 4f6de6f24484..a1cd7c208743 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -167,8 +167,49 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	return 0;
 }
 
+static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
+				   struct pwm_device *pwm,
+				   struct pwm_state *state)
+{
+	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+	u32 clk_div, con0, con1;
+	u64 rate, period, high_width;
+	int err;
+
+	err = clk_prepare_enable(mdp->clk_main);
+	if (err < 0) {
+		dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
+		return;
+	}
+	err = clk_prepare_enable(mdp->clk_mm);
+	if (err < 0) {
+		dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+		clk_disable_unprepare(mdp->clk_main);
+		return;
+	}
+
+	rate = clk_get_rate(mdp->clk_main);
+	con0 = readl(mdp->base + mdp->data->con0);
+	con1 = readl(mdp->base + mdp->data->con1);
+	state->enabled = !!(con0 & BIT(0));
+	clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0);
+	period = FIELD_GET(PWM_PERIOD_MASK, con1);
+	/*
+	 * period has 12 bits, clk_div 11 and NSEC_PER_SEC has 30,
+	 * so period * (clk_div + 1) * NSEC_PER_SEC doesn't overflow.
+	 */
+	state->period = DIV64_U64_ROUND_UP(period * (clk_div + 1) * NSEC_PER_SEC, rate);
+	high_width = FIELD_GET(PWM_HIGH_WIDTH_MASK, con1);
+	state->duty_cycle = DIV64_U64_ROUND_UP(high_width * (clk_div + 1) * NSEC_PER_SEC,
+					       rate);
+	state->polarity = PWM_POLARITY_NORMAL;
+	clk_disable_unprepare(mdp->clk_mm);
+	clk_disable_unprepare(mdp->clk_main);
+}
+
 static const struct pwm_ops mtk_disp_pwm_ops = {
 	.apply = mtk_disp_pwm_apply,
+	.get_state = mtk_disp_pwm_get_state,
 	.owner = THIS_MODULE,
 };
 
-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  8 06:24:31 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Sun, 8 Aug 2021 21:24:31 +0800
Subject: [PATCH v7 3/5] pwm: mtk_disp: implement atomic API .apply()
In-Reply-To: <20210808132433.66037-1-jitao.shi@mediatek.com>
References: <20210808132433.66037-1-jitao.shi@mediatek.com>
Message-ID: <20210808132433.66037-4-jitao.shi@mediatek.com>

Switch the driver to support the .apply() method.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 drivers/pwm/pwm-mtk-disp.c | 93 ++++++++++++++++----------------------
 1 file changed, 38 insertions(+), 55 deletions(-)

diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 1070d78d4940..599d7dd8ecab 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -47,6 +47,7 @@ struct mtk_disp_pwm {
 	struct clk *clk_main;
 	struct clk *clk_mm;
 	void __iomem *base;
+	bool enabled;
 };
 
 static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip)
@@ -66,25 +67,42 @@ static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
 	writel(value, address);
 }
 
-static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-			       int duty_ns, int period_ns)
+static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			      const struct pwm_state *state)
 {
 	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
 	u32 clk_div, period, high_width, value;
 	u64 div, rate;
 	int err;
 
-	err = clk_prepare_enable(mdp->clk_main);
-	if (err < 0) {
-		dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
-		return err;
+	if (state->polarity != PWM_POLARITY_NORMAL)
+		return -EINVAL;
+
+	if (!state->enabled) {
+		mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
+					 0x0);
+		if (mdp->enabled) {
+			clk_disable_unprepare(mdp->clk_mm);
+			clk_disable_unprepare(mdp->clk_main);
+		}
+		mdp->enabled = false;
+		return 0;
 	}
 
-	err = clk_prepare_enable(mdp->clk_mm);
-	if (err < 0) {
-		dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
-		clk_disable_unprepare(mdp->clk_main);
-		return err;
+	if (!mdp->enabled) {
+		err = clk_prepare_enable(mdp->clk_main);
+		if (err < 0) {
+			dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n",
+				ERR_PTR(err));
+			return err;
+		}
+		err = clk_prepare_enable(mdp->clk_mm);
+		if (err < 0) {
+			dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n",
+				ERR_PTR(err));
+			clk_disable_unprepare(mdp->clk_main);
+			return err;
+		}
 	}
 
 	/*
@@ -98,20 +116,22 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
 	 */
 	rate = clk_get_rate(mdp->clk_main);
-	clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
+	clk_div = div_u64(rate * state->period, NSEC_PER_SEC) >>
 			  PWM_PERIOD_BIT_WIDTH;
 	if (clk_div > PWM_CLKDIV_MAX) {
-		clk_disable_unprepare(mdp->clk_mm);
-		clk_disable_unprepare(mdp->clk_main);
+		if (!mdp->enabled) {
+			clk_disable_unprepare(mdp->clk_mm);
+			clk_disable_unprepare(mdp->clk_main);
+		}
 		return -EINVAL;
 	}
 
 	div = NSEC_PER_SEC * (clk_div + 1);
-	period = div64_u64(rate * period_ns, div);
+	period = div64_u64(rate * state->period, div);
 	if (period > 0)
 		period--;
 
-	high_width = div64_u64(rate * duty_ns, div);
+	high_width = div64_u64(rate * state->duty_cycle, div);
 	value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
 
 	mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
@@ -140,52 +160,15 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 					 mdp->data->con0_sel,
 					 mdp->data->con0_sel);
 	}
-
-	clk_disable_unprepare(mdp->clk_mm);
-	clk_disable_unprepare(mdp->clk_main);
-
-	return 0;
-}
-
-static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
-	int err;
-
-	err = clk_prepare_enable(mdp->clk_main);
-	if (err < 0) {
-		dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
-		return err;
-	}
-
-	err = clk_prepare_enable(mdp->clk_mm);
-	if (err < 0) {
-		dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
-		clk_disable_unprepare(mdp->clk_main);
-		return err;
-	}
-
 	mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
 				 mdp->data->enable_mask);
+	mdp->enabled = true;
 
 	return 0;
 }
 
-static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
-
-	mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
-				 0x0);
-
-	clk_disable_unprepare(mdp->clk_mm);
-	clk_disable_unprepare(mdp->clk_main);
-}
-
 static const struct pwm_ops mtk_disp_pwm_ops = {
-	.config = mtk_disp_pwm_config,
-	.enable = mtk_disp_pwm_enable,
-	.disable = mtk_disp_pwm_disable,
+	.apply = mtk_disp_pwm_apply,
 	.owner = THIS_MODULE,
 };
 
-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  8 06:24:32 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Sun, 8 Aug 2021 21:24:32 +0800
Subject: [PATCH v7 4/5] pwm: mtk_disp: fix overflow in period and duty
 calcalation
In-Reply-To: <20210808132433.66037-1-jitao.shi@mediatek.com>
References: <20210808132433.66037-1-jitao.shi@mediatek.com>
Message-ID: <20210808132433.66037-5-jitao.shi@mediatek.com>

Current calculation for period and high_width may have
64-bit overflow. state->period and rate are u64.
rate * state->period will overflow.

clk_div = div_u64(rate * state->period, NSEC_PER_SEC)
period = div64_u64(rate * state->period, div);
high_width = div64_u64(rate * state->duty_cycle, div);

This patch is to resolve it by using mul_u64_u64_div_u64().

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 drivers/pwm/pwm-mtk-disp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 599d7dd8ecab..4f6de6f24484 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -116,7 +116,7 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
 	 */
 	rate = clk_get_rate(mdp->clk_main);
-	clk_div = div_u64(rate * state->period, NSEC_PER_SEC) >>
+	clk_div = mul_u64_u64_div_u64(state->period, rate, NSEC_PER_SEC) >>
 			  PWM_PERIOD_BIT_WIDTH;
 	if (clk_div > PWM_CLKDIV_MAX) {
 		if (!mdp->enabled) {
@@ -127,11 +127,11 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	div = NSEC_PER_SEC * (clk_div + 1);
-	period = div64_u64(rate * state->period, div);
+	period = mul_u64_u64_div_u64(state->period, rate, div);
 	if (period > 0)
 		period--;
 
-	high_width = div64_u64(rate * state->duty_cycle, div);
+	high_width = mul_u64_u64_div_u64(state->duty_cycle, rate, div);
 	value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
 
 	mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  8 06:24:29 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Sun, 8 Aug 2021 21:24:29 +0800
Subject: [PATCH v7 1/5] pwm: mtk-disp: adjust the clocks to avoid them mismatch
In-Reply-To: <20210808132433.66037-1-jitao.shi@mediatek.com>
References: <20210808132433.66037-1-jitao.shi@mediatek.com>
Message-ID: <20210808132433.66037-2-jitao.shi@mediatek.com>

The clks "main" and "mm" are prepared in .probe() (and
unprepared in .remove()). This results in the clocks being on
during suspend which results in unnecessarily increased power
consumption.

Remove the clock operations from .probe() and .remove().
Add the clk_prepare_enable() in .enable().
Add the clk_disable_unprepare() in .disable().

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 drivers/pwm/pwm-mtk-disp.c | 72 ++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 41 deletions(-)

diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index 9b3ba401a3db..3ade525adcc3 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -74,6 +74,19 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	u64 div, rate;
 	int err;
 
+	err = clk_prepare_enable(mdp->clk_main);
+	if (err < 0) {
+		dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
+		return err;
+	}
+
+	err = clk_prepare_enable(mdp->clk_mm);
+	if (err < 0) {
+		dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+		clk_disable_unprepare(mdp->clk_main);
+		return err;
+	}
+
 	/*
 	 * Find period, high_width and clk_div to suit duty_ns and period_ns.
 	 * Calculate proper div value to keep period value in the bound.
@@ -87,8 +100,11 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	rate = clk_get_rate(mdp->clk_main);
 	clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
 			  PWM_PERIOD_BIT_WIDTH;
-	if (clk_div > PWM_CLKDIV_MAX)
+	if (clk_div > PWM_CLKDIV_MAX) {
+		clk_disable_unprepare(mdp->clk_mm);
+		clk_disable_unprepare(mdp->clk_main);
 		return -EINVAL;
+	}
 
 	div = NSEC_PER_SEC * (clk_div + 1);
 	period = div64_u64(rate * period_ns, div);
@@ -98,16 +114,6 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	high_width = div64_u64(rate * duty_ns, div);
 	value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
 
-	err = clk_enable(mdp->clk_main);
-	if (err < 0)
-		return err;
-
-	err = clk_enable(mdp->clk_mm);
-	if (err < 0) {
-		clk_disable(mdp->clk_main);
-		return err;
-	}
-
 	mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
 				 PWM_CLKDIV_MASK,
 				 clk_div << PWM_CLKDIV_SHIFT);
@@ -124,8 +130,8 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 					 0x0);
 	}
 
-	clk_disable(mdp->clk_mm);
-	clk_disable(mdp->clk_main);
+	clk_disable_unprepare(mdp->clk_mm);
+	clk_disable_unprepare(mdp->clk_main);
 
 	return 0;
 }
@@ -135,13 +141,16 @@ static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
 	int err;
 
-	err = clk_enable(mdp->clk_main);
-	if (err < 0)
+	err = clk_prepare_enable(mdp->clk_main);
+	if (err < 0) {
+		dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
 		return err;
+	}
 
-	err = clk_enable(mdp->clk_mm);
+	err = clk_prepare_enable(mdp->clk_mm);
 	if (err < 0) {
-		clk_disable(mdp->clk_main);
+		dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+		clk_disable_unprepare(mdp->clk_main);
 		return err;
 	}
 
@@ -158,8 +167,8 @@ static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
 				 0x0);
 
-	clk_disable(mdp->clk_mm);
-	clk_disable(mdp->clk_main);
+	clk_disable_unprepare(mdp->clk_mm);
+	clk_disable_unprepare(mdp->clk_main);
 }
 
 static const struct pwm_ops mtk_disp_pwm_ops = {
@@ -192,22 +201,14 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
 	if (IS_ERR(mdp->clk_mm))
 		return PTR_ERR(mdp->clk_mm);
 
-	ret = clk_prepare(mdp->clk_main);
-	if (ret < 0)
-		return ret;
-
-	ret = clk_prepare(mdp->clk_mm);
-	if (ret < 0)
-		goto disable_clk_main;
-
 	mdp->chip.dev = &pdev->dev;
 	mdp->chip.ops = &mtk_disp_pwm_ops;
 	mdp->chip.npwm = 1;
 
 	ret = pwmchip_add(&mdp->chip);
 	if (ret < 0) {
-		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
-		goto disable_clk_mm;
+		dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, mdp);
@@ -226,24 +227,13 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
 	}
 
 	return 0;
-
-disable_clk_mm:
-	clk_unprepare(mdp->clk_mm);
-disable_clk_main:
-	clk_unprepare(mdp->clk_main);
-	return ret;
 }
 
 static int mtk_disp_pwm_remove(struct platform_device *pdev)
 {
 	struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = pwmchip_remove(&mdp->chip);
-	clk_unprepare(mdp->clk_mm);
-	clk_unprepare(mdp->clk_main);
 
-	return ret;
+	return pwmchip_remove(&mdp->chip);
 }
 
 static const struct mtk_pwm_data mt2701_pwm_data = {
-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  8 06:41:17 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Sun, 8 Aug 2021 21:41:17 +0800
Subject: [PATCH v6 1/1] drm/mediatek: force hsa hbp hfp packets multiple of
 lanenum to avoid screen shift
In-Reply-To: <20210808134117.66798-1-jitao.shi@mediatek.com>
References: <20210808134117.66798-1-jitao.shi@mediatek.com>
Message-ID: <20210808134117.66798-2-jitao.shi@mediatek.com>

The bridge chip ANX7625 requires the packets on lanes aligned at the end,
or ANX7625 will shift the screen.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ae403c67cbd9..033234d51e86 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -194,6 +194,8 @@ struct mtk_dsi {
 	struct clk *hs_clk;
 
 	u32 data_rate;
+	/* force dsi line end without dsi_null data */
+	bool force_dsi_end_without_null;
 
 	unsigned long mode_flags;
 	enum mipi_dsi_pixel_format format;
@@ -499,6 +501,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 		DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
 	}
 
+	if (dsi->force_dsi_end_without_null) {
+		horizontal_sync_active_byte = roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
+		horizontal_frontporch_byte = roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte = roundup(horizontal_backporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte -= (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
+	}
+
 	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
 	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
 	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
@@ -1095,6 +1104,10 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->bridge.of_node = dev->of_node;
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
+	if (dsi->next_bridge)
+		dsi->force_dsi_end_without_null = of_device_is_compatible(dsi->next_bridge->of_node,
+									  "analogix,anx7625");
+
 	drm_bridge_add(&dsi->bridge);
 
 	ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
-- 
2.25.1

From jitao.shi at mediatek.com  Sun Aug  8 06:41:16 2021
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Sun, 8 Aug 2021 21:41:16 +0800
Subject: [PATCH v6 0/1] force hsa hbp hfp packets multiple of lanenum to avoid
 screen shift
Message-ID: <20210808134117.66798-1-jitao.shi@mediatek.com>

Changes since v5:
 - Remvoe the anx7625 devicetree change. Use the compatible string intead.

Changes since v4:
 - Move "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null" before
   "drm/mediatek: force hsa hbp hfp packets multiple of lanenum to avoid".

 - Retitle "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null".

Jitao Shi (1):
  drm/mediatek: force hsa hbp hfp packets multiple of lanenum to avoid
    screen shift

 drivers/gpu/drm/mediatek/mtk_dsi.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

-- 
2.25.1

From len.baker at gmx.com  Sun Aug  8 05:50:10 2021
From: len.baker at gmx.com (Len Baker)
Date: Sun,  8 Aug 2021 14:50:10 +0200
Subject: [PATCH v4 1/3] drivers/soc/qcom: Prefer strscpy over strcpy
In-Reply-To: <20210808125012.4715-1-len.baker@gmx.com>
References: <20210808125012.4715-1-len.baker@gmx.com>
Message-ID: <20210808125012.4715-2-len.baker@gmx.com>

strcpy() performs no bounds checking on the destination buffer. This
could result in linear overflows beyond the end of the buffer, leading
to all kinds of misbehaviors. The safe replacement is strscpy().

This is a previous step in the path to remove the strcpy() function
entirely from the kernel.

Signed-off-by: Len Baker <len.baker at gmx.com>
---
 drivers/soc/qcom/pdr_interface.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c
index 915d5bc3d46e..fc580a3c4336 100644
--- a/drivers/soc/qcom/pdr_interface.c
+++ b/drivers/soc/qcom/pdr_interface.c
@@ -131,7 +131,7 @@ static int pdr_register_listener(struct pdr_handle *pdr,
 		return ret;

 	req.enable = enable;
-	strcpy(req.service_path, pds->service_path);
+	strscpy(req.service_path, pds->service_path, sizeof(req.service_path));

 	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
 			       &txn, SERVREG_REGISTER_LISTENER_REQ,
@@ -257,7 +257,7 @@ static int pdr_send_indack_msg(struct pdr_handle *pdr, struct pdr_service *pds,
 		return ret;

 	req.transaction_id = tid;
-	strcpy(req.service_path, pds->service_path);
+	strscpy(req.service_path, pds->service_path, sizeof(req.service_path));

 	ret = qmi_send_request(&pdr->notifier_hdl, &pds->addr,
 			       &txn, SERVREG_SET_ACK_REQ,
@@ -406,7 +406,7 @@ static int pdr_locate_service(struct pdr_handle *pdr, struct pdr_service *pds)
 		return -ENOMEM;

 	/* Prepare req message */
-	strcpy(req.service_name, pds->service_name);
+	strscpy(req.service_name, pds->service_name, sizeof(req.service_name));
 	req.domain_offset_valid = true;
 	req.domain_offset = 0;

@@ -531,8 +531,8 @@ struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr,
 		return ERR_PTR(-ENOMEM);

 	pds->service = SERVREG_NOTIFIER_SERVICE;
-	strcpy(pds->service_name, service_name);
-	strcpy(pds->service_path, service_path);
+	strscpy(pds->service_name, service_name, sizeof(pds->service_name));
+	strscpy(pds->service_path, service_path, sizeof(pds->service_path));
 	pds->need_locator_lookup = true;

 	mutex_lock(&pdr->list_lock);
@@ -587,7 +587,7 @@ int pdr_restart_pd(struct pdr_handle *pdr, struct pdr_service *pds)
 			break;

 		/* Prepare req message */
-		strcpy(req.service_path, pds->service_path);
+		strscpy(req.service_path, pds->service_path, sizeof(req.service_path));
 		addr = pds->addr;
 		break;
 	}
--
2.25.1



From jic23 at kernel.org  Sun Aug  8 06:54:31 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 8 Aug 2021 14:54:31 +0100
Subject: [PATCH v2] iio: adc: fsl-imx25-gcq: fix the right check and
 simplify code
In-Reply-To: <20210802120929.33760-1-tangbin@cmss.chinamobile.com>
References: <20210802120929.33760-1-tangbin@cmss.chinamobile.com>
Message-ID: <20210808145431.5164b2d8@jic23-huawei>

On Mon,  2 Aug 2021 20:09:29 +0800
Tang Bin <tangbin at cmss.chinamobile.com> wrote:

> For the function of platform_get_irq(), the example in platform.c is
>  *	int irq = platform_get_irq(pdev, 0);
>  *	if (irq < 0)
>  *		return irq;
> the return value of zero is unnecessary to check, so make the right
> check and simplify code.
> 
> Co-developed-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
> Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
> Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>

Applied.  I tweaked the message an title to make it clear this isn't
a fix, but rather a little clean up with no functional affect.

Thanks,

Jonathan

> ---
> Changes from v1
>  - change the code to the original place and make it simple.
>  - change the commit message.
> ---
>  drivers/iio/adc/fsl-imx25-gcq.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
> index 8cb51cf7a..2cdf45aa8 100644
> --- a/drivers/iio/adc/fsl-imx25-gcq.c
> +++ b/drivers/iio/adc/fsl-imx25-gcq.c
> @@ -336,14 +336,11 @@ static int mx25_gcq_probe(struct platform_device *pdev)
>  		goto err_vref_disable;
>  	}
>  
> -	priv->irq = platform_get_irq(pdev, 0);
> -	if (priv->irq <= 0) {
> -		ret = priv->irq;
> -		if (!ret)
> -			ret = -ENXIO;
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret < 0)
>  		goto err_clk_unprepare;
> -	}
>  
> +	priv->irq = ret;
>  	ret = request_irq(priv->irq, mx25_gcq_irq, 0, pdev->name, priv);
>  	if (ret) {
>  		dev_err(dev, "Failed requesting IRQ\n");



From len.baker at gmx.com  Sun Aug  8 05:50:11 2021
From: len.baker at gmx.com (Len Baker)
Date: Sun,  8 Aug 2021 14:50:11 +0200
Subject: [PATCH v4 2/3] drivers/soc/renesas: Prefer memcpy over strcpy
In-Reply-To: <20210808125012.4715-1-len.baker@gmx.com>
References: <20210808125012.4715-1-len.baker@gmx.com>
Message-ID: <20210808125012.4715-3-len.baker@gmx.com>

strcpy() performs no bounds checking on the destination buffer. This
could result in linear overflows beyond the end of the buffer, leading
to all kinds of misbehaviors. So, use memcpy() as a safe replacement.

This is a previous step in the path to remove the strcpy() function
entirely from the kernel.

Signed-off-by: Len Baker <len.baker at gmx.com>
---
 drivers/soc/renesas/r8a779a0-sysc.c | 6 ++++--
 drivers/soc/renesas/rcar-sysc.c     | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
index d464ffa1be33..7410b9fa9846 100644
--- a/drivers/soc/renesas/r8a779a0-sysc.c
+++ b/drivers/soc/renesas/r8a779a0-sysc.c
@@ -404,19 +404,21 @@ static int __init r8a779a0_sysc_pd_init(void)
 	for (i = 0; i < info->num_areas; i++) {
 		const struct r8a779a0_sysc_area *area = &info->areas[i];
 		struct r8a779a0_sysc_pd *pd;
+		size_t n;

 		if (!area->name) {
 			/* Skip NULLified area */
 			continue;
 		}

-		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
+		n = strlen(area->name) + 1;
+		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
 		if (!pd) {
 			error = -ENOMEM;
 			goto out_put;
 		}

-		strcpy(pd->name, area->name);
+		memcpy(pd->name, area->name, n);
 		pd->genpd.name = pd->name;
 		pd->pdr = area->pdr;
 		pd->flags = area->flags;
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index 53387a72ca00..b0a80de34c98 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -396,19 +396,21 @@ static int __init rcar_sysc_pd_init(void)
 	for (i = 0; i < info->num_areas; i++) {
 		const struct rcar_sysc_area *area = &info->areas[i];
 		struct rcar_sysc_pd *pd;
+		size_t n;

 		if (!area->name) {
 			/* Skip NULLified area */
 			continue;
 		}

-		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
+		n = strlen(area->name) + 1;
+		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
 		if (!pd) {
 			error = -ENOMEM;
 			goto out_put;
 		}

-		strcpy(pd->name, area->name);
+		memcpy(pd->name, area->name, n);
 		pd->genpd.name = pd->name;
 		pd->ch.chan_offs = area->chan_offs;
 		pd->ch.chan_bit = area->chan_bit;
--
2.25.1



From vidyas at nvidia.com  Sun Aug  8 08:01:01 2021
From: vidyas at nvidia.com (Vidya Sagar)
Date: Sun, 8 Aug 2021 20:31:01 +0530
Subject: [PATCH v2 39/40] PCI: dwc: Move N_FTS setup to common setup
In-Reply-To: <20200821035420.380495-40-robh@kernel.org>
References: <20200821035420.380495-1-robh@kernel.org>
 <20200821035420.380495-40-robh@kernel.org>
Message-ID: <d7146c20-6992-44a0-c390-f801d352cf15@nvidia.com>



On 8/21/2020 9:24 AM, Rob Herring wrote:
> The Designware controller has common registers to set number of fast
> training sequence ordered sets. The Artpec6, Intel, and Tegra driver
> initialize these register fields. Let's move the initialization to the
> common setup code and drivers just have to provide the value.
> 
> There's a slight change in that the common clock mode N_FTS field is
> now initialized. Previously only the Intel driver set this. It's not
> clear from the code if common clock mode is used in the Artpec6 or Tegra
> driver. It depends on the DWC configuration. Given the field is not
> initialized while the others are, it seems unlikely common clock mode
> is used.
> 
> Cc: Jesper Nilsson <jesper.nilsson at axis.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Cc: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Jingoo Han <jingoohan1 at gmail.com>
> Cc: Gustavo Pimentel <gustavo.pimentel at synopsys.com>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: Jonathan Hunter <jonathanh at nvidia.com>
> Cc: linux-tegra at vger.kernel.org
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>   drivers/pci/controller/dwc/pcie-artpec6.c    | 37 +++-----------------
>   drivers/pci/controller/dwc/pcie-designware.c | 28 +++++++++------
>   drivers/pci/controller/dwc/pcie-designware.h |  3 +-
>   drivers/pci/controller/dwc/pcie-intel-gw.c   | 27 +++++---------
>   drivers/pci/controller/dwc/pcie-tegra194.c   | 25 ++-----------
>   5 files changed, 35 insertions(+), 85 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
> index 86f4d66d8587..929448e9e0bc 100644
> --- a/drivers/pci/controller/dwc/pcie-artpec6.c
> +++ b/drivers/pci/controller/dwc/pcie-artpec6.c
> @@ -44,13 +44,6 @@ struct artpec_pcie_of_data {
>   
>   static const struct of_device_id artpec6_pcie_of_match[];
>   
> -/* PCIe Port Logic registers (memory-mapped) */
> -#define PL_OFFSET			0x700
> -
> -#define ACK_F_ASPM_CTRL_OFF		(PL_OFFSET + 0xc)
> -#define ACK_N_FTS_MASK			GENMASK(15, 8)
> -#define ACK_N_FTS(x)			(((x) << 8) & ACK_N_FTS_MASK)
> -
>   /* ARTPEC-6 specific registers */
>   #define PCIECFG				0x18
>   #define  PCIECFG_DBG_OEN		BIT(24)
> @@ -289,30 +282,6 @@ static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie)
>   	}
>   }
>   
> -static void artpec6_pcie_set_nfts(struct artpec6_pcie *artpec6_pcie)
> -{
> -	struct dw_pcie *pci = artpec6_pcie->pci;
> -	u32 val;
> -
> -	if (artpec6_pcie->variant != ARTPEC7)
> -		return;
> -
> -	/*
> -	 * Increase the N_FTS (Number of Fast Training Sequences)
> -	 * to be transmitted when transitioning from L0s to L0.
> -	 */
> -	val = dw_pcie_readl_dbi(pci, ACK_F_ASPM_CTRL_OFF);
> -	val &= ~ACK_N_FTS_MASK;
> -	val |= ACK_N_FTS(180);
> -	dw_pcie_writel_dbi(pci, ACK_F_ASPM_CTRL_OFF, val);
> -
> -	/*
> -	 * Set the Number of Fast Training Sequences that the core
> -	 * advertises as its N_FTS during Gen2 or Gen3 link training.
> -	 */
> -	dw_pcie_link_set_n_fts(pci, 180);
> -}
> -
>   static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
>   {
>   	u32 val;
> @@ -351,11 +320,14 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>   	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
>   
> +	if (artpec6_pcie->variant == ARTPEC7) {
> +		pci->n_fts[0] = 180;
> +		pci->n_fts[1] = 180;
> +	}
>   	artpec6_pcie_assert_core_reset(artpec6_pcie);
>   	artpec6_pcie_init_phy(artpec6_pcie);
>   	artpec6_pcie_deassert_core_reset(artpec6_pcie);
>   	artpec6_pcie_wait_for_phy(artpec6_pcie);
> -	artpec6_pcie_set_nfts(artpec6_pcie);
>   	dw_pcie_setup_rc(pp);
>   	artpec6_pcie_establish_link(pci);
>   	dw_pcie_wait_for_link(pci);
> @@ -403,7 +375,6 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
>   	artpec6_pcie_init_phy(artpec6_pcie);
>   	artpec6_pcie_deassert_core_reset(artpec6_pcie);
>   	artpec6_pcie_wait_for_phy(artpec6_pcie);
> -	artpec6_pcie_set_nfts(artpec6_pcie);
>   
>   	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
>   		dw_pcie_ep_reset_bar(pci, bar);
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index 61e1faba15bf..3cb21247619c 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -510,17 +510,6 @@ static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen)
>   }
>   EXPORT_SYMBOL_GPL(dw_pcie_link_set_max_speed);
>   
> -void dw_pcie_link_set_n_fts(struct dw_pcie *pci, u32 n_fts)
> -{
> -	u32 val;
> -
> -	val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
> -	val &= ~PORT_LOGIC_N_FTS_MASK;
> -	val |= n_fts & PORT_LOGIC_N_FTS_MASK;
> -	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
> -}
> -EXPORT_SYMBOL_GPL(dw_pcie_link_set_n_fts);
> -
>   static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci)
>   {
>   	u32 val;
> @@ -551,6 +540,23 @@ void dw_pcie_setup(struct dw_pcie *pci)
>   	if (pci->link_gen > 0)
>   		dw_pcie_link_set_max_speed(pci, pci->link_gen);
>   
> +	/* Configure Gen1 N_FTS */
> +	if (pci->n_fts[0]) {
> +		val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
> +		val &= ~(PORT_AFR_N_FTS_MASK | PORT_AFR_CC_N_FTS_MASK);
> +		val |= PORT_AFR_N_FTS(pci->n_fts[0]);
> +		val |= PORT_AFR_CC_N_FTS(pci->n_fts[0]);
> +		dw_pcie_writel_dbi(pci, PCIE_PORT_AFR, val);
> +	}
> +
> +	/* Configure Gen2+ N_FTS */
> +	if (pci->n_fts[1]) {
> +		val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
> +		val &= ~PORT_LOGIC_N_FTS_MASK;
> +		val |= pci->n_fts[pci->link_gen - 1];
Apologies for getting late to this change given that the change has 
already been merged.
I'm wondering why is it that link_gen has to be used in deriving the 
index instead of directly using '1' as the index?
Infact the for link speed greater than 2, accesses go beyond n_fts[] 
array boundaries.
Since the if() check is done based on a non-zero value of pci->n_fts[1], 
shouldn't the same be used for programming also?

- Vidya Sagar

> +		dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
> +	}
> +
>   	val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
>   	val &= ~PORT_LINK_FAST_LINK_MODE;
>   	val |= PORT_LINK_DLL_LINK_EN;
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index 0b48298362cd..d8771db247f4 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -34,6 +34,7 @@
>   #define PORT_AFR_N_FTS_MASK		GENMASK(15, 8)
>   #define PORT_AFR_N_FTS(n)		FIELD_PREP(PORT_AFR_N_FTS_MASK, n)
>   #define PORT_AFR_CC_N_FTS_MASK		GENMASK(23, 16)
> +#define PORT_AFR_CC_N_FTS(n)		FIELD_PREP(PORT_AFR_CC_N_FTS_MASK, n)
>   #define PORT_AFR_ENTER_ASPM		BIT(30)
>   #define PORT_AFR_L0S_ENTRANCE_LAT_SHIFT	24
>   #define PORT_AFR_L0S_ENTRANCE_LAT_MASK	GENMASK(26, 24)
> @@ -253,6 +254,7 @@ struct dw_pcie {
>   	unsigned int		version;
>   	int			num_lanes;
>   	int			link_gen;
> +	u8			n_fts[2];
>   };
>   
>   #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp)
> @@ -271,7 +273,6 @@ void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
>   void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
>   int dw_pcie_link_up(struct dw_pcie *pci);
>   void dw_pcie_upconfig_setup(struct dw_pcie *pci);
> -void dw_pcie_link_set_n_fts(struct dw_pcie *pci, u32 n_fts);
>   int dw_pcie_wait_for_link(struct dw_pcie *pci);
>   void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
>   			       int type, u64 cpu_addr, u64 pci_addr,
> diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c
> index 333f11561807..5650cb78acba 100644
> --- a/drivers/pci/controller/dwc/pcie-intel-gw.c
> +++ b/drivers/pci/controller/dwc/pcie-intel-gw.c
> @@ -67,7 +67,6 @@ struct intel_pcie_port {
>   	void __iomem		*app_base;
>   	struct gpio_desc	*reset_gpio;
>   	u32			rst_intrvl;
> -	u32			n_fts;
>   	struct clk		*core_clk;
>   	struct reset_control	*core_rst;
>   	struct phy		*phy;
> @@ -138,37 +137,29 @@ static void intel_pcie_link_setup(struct intel_pcie_port *lpp)
>   	pcie_rc_cfg_wr(lpp, offset + PCI_EXP_LNKCTL, val);
>   }
>   
> -static void intel_pcie_port_logic_setup(struct intel_pcie_port *lpp)
> +static void intel_pcie_init_n_fts(struct dw_pcie *pci)
>   {
> -	u32 val, mask;
> -	struct dw_pcie *pci = &lpp->pci;
> -
> -	switch (pcie_link_speed[pci->link_gen]) {
> -	case PCIE_SPEED_8_0GT:
> -		lpp->n_fts = PORT_AFR_N_FTS_GEN3;
> +	switch (pci->link_gen) {
> +	case 3:
> +		pci->n_fts[1] = PORT_AFR_N_FTS_GEN3;
>   		break;
> -	case PCIE_SPEED_16_0GT:
> -		lpp->n_fts = PORT_AFR_N_FTS_GEN4;
> +	case 4:
> +		pci->n_fts[1] = PORT_AFR_N_FTS_GEN4;
>   		break;
>   	default:
> -		lpp->n_fts = PORT_AFR_N_FTS_GEN12_DFT;
> +		pci->n_fts[1] = PORT_AFR_N_FTS_GEN12_DFT;
>   		break;
>   	}
> -
> -	mask = PORT_AFR_N_FTS_MASK | PORT_AFR_CC_N_FTS_MASK;
> -	val = FIELD_PREP(PORT_AFR_N_FTS_MASK, lpp->n_fts) |
> -	       FIELD_PREP(PORT_AFR_CC_N_FTS_MASK, lpp->n_fts);
> -	pcie_rc_cfg_wr_mask(lpp, PCIE_PORT_AFR, mask, val);
> +	pci->n_fts[0] = PORT_AFR_N_FTS_GEN12_DFT;
>   }
>   
>   static void intel_pcie_rc_setup(struct intel_pcie_port *lpp)
>   {
>   	intel_pcie_ltssm_disable(lpp);
>   	intel_pcie_link_setup(lpp);
> +	intel_pcie_init_n_fts(&lpp->pci);
>   	dw_pcie_setup_rc(&lpp->pci.pp);
>   	dw_pcie_upconfig_setup(&lpp->pci);
> -	intel_pcie_port_logic_setup(lpp);
> -	dw_pcie_link_set_n_fts(&lpp->pci, lpp->n_fts);
>   }
>   
>   static int intel_pcie_ep_rst_init(struct intel_pcie_port *lpp)
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 91ef4b3e860d..1560c449757d 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -881,17 +881,6 @@ static void tegra_pcie_prepare_host(struct pcie_port *pp)
>   
>   	dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0);
>   
> -	/* Configure FTS */
> -	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
> -	val &= ~PORT_AFR_N_FTS_MASK;
> -	val |= PORT_AFR_N_FTS(N_FTS_VAL);
> -	dw_pcie_writel_dbi(pci, PCIE_PORT_AFR, val);
> -
> -	val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
> -	val &= ~PORT_LOGIC_N_FTS_MASK;
> -	val |= FTS_VAL;
> -	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
> -
>   	/* Enable as 0xFFFF0001 response for CRS */
>   	val = dw_pcie_readl_dbi(pci, PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT);
>   	val &= ~(AMBA_ERROR_RESPONSE_CRS_MASK << AMBA_ERROR_RESPONSE_CRS_SHIFT);
> @@ -1794,17 +1783,6 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
>   	val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
>   	dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val);
>   
> -	/* Configure N_FTS & FTS */
> -	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
> -	val &= ~PORT_AFR_N_FTS_MASK;
> -	val |= PORT_AFR_N_FTS(FTS_VAL);
> -	dw_pcie_writel_dbi(pci, PCIE_PORT_AFR, val);
> -
> -	val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
> -	val &= ~PORT_LOGIC_N_FTS_MASK;
> -	val |= FTS_VAL;
> -	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
> -
>   	pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci,
>   						      PCI_CAP_ID_EXP);
>   	clk_set_rate(pcie->core_clk, GEN4_CORE_CLK_FREQ);
> @@ -2033,6 +2011,9 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
>   	pci = &pcie->pci;
>   	pci->dev = &pdev->dev;
>   	pci->ops = &tegra_dw_pcie_ops;
> +	pci->n_fts[0] = N_FTS_VAL;
> +	pci->n_fts[1] = FTS_VAL;
> +
>   	pp = &pci->pp;
>   	pcie->dev = &pdev->dev;
>   	pcie->mode = (enum dw_pcie_device_mode)data->mode;
> 


From cristian.marussi at arm.com  Sun Aug  8 08:07:41 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Sun, 8 Aug 2021 16:07:41 +0100
Subject: [PATCH] firmware: arm_scmi: fix boolconv.cocci warnings
In-Reply-To: <20210807173127.GA43248@a24dbc127934>
References: <202108080108.k5pHZ040-lkp@intel.com>
 <20210807173127.GA43248@a24dbc127934>
Message-ID: <20210808150741.GW6592@e120937-lin>

On Sun, Aug 08, 2021 at 01:31:27AM +0800, kernel test robot wrote:
> From: kernel test robot <lkp at intel.com>
> 
> drivers/firmware/arm_scmi/virtio.c:225:40-45: WARNING: conversion to bool not needed here
> 
>  Remove unneeded conversion to bool
> 
> Semantic patch information:
>  Relational and logical operators evaluate to bool,
>  explicit conversion is overly verbose and unneeded.
> 
> Generated by: scripts/coccinelle/misc/boolconv.cocci
> 
> CC: Igor Skalkin <igor.skalkin at opensynergy.com>
> Reported-by: kernel test robot <lkp at intel.com>
> Signed-off-by: kernel test robot <lkp at intel.com>
> ---
> 
> tree:   https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git for-next/scmi
> head:   1e7cbfaa66d39e78bd24df0c78b55df68176b59e
> commit: 46abe13b5e3db187e52cd0de06c07bbce010726c [23/24] firmware: arm_scmi: Add virtio transport
> :::::: branch date: 2 days ago
> :::::: commit date: 2 days ago
> 
>  virtio.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- a/drivers/firmware/arm_scmi/virtio.c
> +++ b/drivers/firmware/arm_scmi/virtio.c
> @@ -222,7 +222,7 @@ static bool virtio_chan_available(struct
>  		return false;
>  	}
>  
> -	return vioch && !vioch->cinfo ? true : false;
> +	return vioch && !vioch->cinfo;
>  }
>  
>  static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,o

Hi Sudeep,

this seems obviously right, would you pick it up as it is on top of
for-next/scmi when you have time ?

Thanks,
Cristian


From vidyas at nvidia.com  Sun Aug  8 08:13:43 2021
From: vidyas at nvidia.com (Vidya Sagar)
Date: Sun, 8 Aug 2021 20:43:43 +0530
Subject: [PATCH v2 03/40] PCI: dwc: Allow overriding bridge pci_ops
In-Reply-To: <20200821035420.380495-4-robh@kernel.org>
References: <20200821035420.380495-1-robh@kernel.org>
 <20200821035420.380495-4-robh@kernel.org>
Message-ID: <68e3adfb-a79d-3b70-87ed-2e5e1bf7fc93@nvidia.com>



On 8/21/2020 9:23 AM, Rob Herring wrote:
> In preparation to allow drivers to set their own root and child pci_ops
> instead of using the DWC specific config space ops, we need to make
> the pci_host_bridge pointer available and move setting the bridge->ops
> and bridge->child_ops pointer to before the .host_init() hook.
> 
> Cc: Jingoo Han <jingoohan1 at gmail.com>
> Cc: Gustavo Pimentel <gustavo.pimentel at synopsys.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Cc: Bjorn Helgaas <bhelgaas at google.com>
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>   drivers/pci/controller/dwc/pcie-designware-host.c | 15 ++++++++++-----
>   drivers/pci/controller/dwc/pcie-designware.h      |  1 +
>   2 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 1d98554db009..b626cc7cd43a 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -344,6 +344,8 @@ int dw_pcie_host_init(struct pcie_port *pp)
>   	if (!bridge)
>   		return -ENOMEM;
>   
> +	pp->bridge = bridge;
> +
>   	/* Get the I/O and memory ranges from DT */
>   	resource_list_for_each_entry(win, &bridge->windows) {
>   		switch (resource_type(win->res)) {
> @@ -445,6 +447,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
>   		}
>   	}
>   
> +	/* Set default bus ops */
> +	bridge->ops = &dw_pcie_ops;
> +	bridge->child_ops = &dw_pcie_ops;
> +
>   	if (pp->ops->host_init) {
>   		ret = pp->ops->host_init(pp);
>   		if (ret)
> @@ -452,7 +458,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
>   	}
>   
>   	bridge->sysdata = pp;
> -	bridge->ops = &dw_pcie_ops;
>   
>   	ret = pci_scan_root_bus_bridge(bridge);
>   	if (ret)
> @@ -654,11 +659,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
>   	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
>   
>   	/*
> -	 * If the platform provides ->rd_other_conf, it means the platform
> -	 * uses its own address translation component rather than ATU, so
> -	 * we should not program the ATU here.
> +	 * If the platform provides its own child bus config accesses, it means
> +	 * the platform uses its own address translation component rather than
> +	 * ATU, so we should not program the ATU here.
It is possible that a platform can have its own translation for 
configuration accesses and use DWC's ATU for memory/IO address 
translations. IMHO, ATU setup for memory/IO address translations 
shouldn't be skipped based on platform's '->rd_other_conf' 
implementation. Ex:- A platform can implement configuration space access 
through the ECAM mechanism yet choose to use ATU for memory/IO address 
translations.

Thanks,
Vidya Sagar
>   	 */
> -	if (!pp->ops->rd_other_conf) {
> +	if (pp->bridge->child_ops == &dw_pcie_ops && !pp->ops->rd_other_conf) {
>   		dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0,
>   					  PCIE_ATU_TYPE_MEM, pp->mem_base,
>   					  pp->mem_bus_addr, pp->mem_size);
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index f911760dcc69..8b8ea5f3e7af 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -200,6 +200,7 @@ struct pcie_port {
>   	u32			num_vectors;
>   	u32			irq_mask[MAX_MSI_CTRLS];
>   	struct pci_bus		*root_bus;
> +	struct pci_host_bridge  *bridge;
>   	raw_spinlock_t		lock;
>   	DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
>   };
> 


From andrew at lunn.ch  Sun Aug  8 08:18:00 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 8 Aug 2021 17:18:00 +0200
Subject: [PATCH] ARM: kirkwood: add missing <linux/if_ether.h> for ETH_ALEN
In-Reply-To: <YQ9PNeka8VhZqxGR@makrotopia.org>
References: <YQxk4jrbm31NM1US@makrotopia.org>
 <cde9de20efd3a75561080751766edbec@walle.cc>
 <YQ6WCK0Sytb0nxj9@lunn.ch> <YQ9PNeka8VhZqxGR@makrotopia.org>
Message-ID: <YQ/1qBum6BxRE6l6@lunn.ch>

> When building OpenWrt kernel which includes a backport of
> "of: net: pass the dst buffer to of_get_mac_address()", this is not the
> same as <linux/of_net.h> doesn't include <linux/phy.h> yet. This is
> because we miss commit 0c65b2b90d13c1 ("net: of_get_phy_mode: Change
> API to solve int/unit warnings") which has been in mainline for a long
> time.

That is quiet a big invasive patch, so i can understand it not being
backported. But on the flip side, it will make it harder getting
drivers upstream to mainline. And there are is one other big change,
how the MAC address is fetches from EEPROM, DT, etc.

> Sorry for the noise caused, I'm not sure what the policy is in this
> case

There is nothing in the coding style that all headers must be directly
included in the .c file. And it slows down the compiler having to pull
in a header file multiple times. You do see patches removing unused
includes. So i think OpenWRT should add yet another patch do deal with
its own breakage.

If you have more kirkwood, or Marvell boards in general in OpenWRT
which you want merged to mainline, i'm happy to review them.

      Andrew


From bernd at petrovitsch.priv.at  Sun Aug  8 08:35:54 2021
From: bernd at petrovitsch.priv.at (Bernd Petrovitsch)
Date: Sun, 8 Aug 2021 17:35:54 +0200
Subject: [PATCH v4 2/3] drivers/soc/renesas: Prefer memcpy over strcpy
In-Reply-To: <20210808125012.4715-3-len.baker@gmx.com>
References: <20210808125012.4715-1-len.baker@gmx.com>
 <20210808125012.4715-3-len.baker@gmx.com>
Message-ID: <39485c0e-511c-50a0-83be-f9ce6fc47e67@petrovitsch.priv.at>

Hi all!

On 08/08/2021 14:50, Len Baker wrote:
> strcpy() performs no bounds checking on the destination buffer. This
> could result in linear overflows beyond the end of the buffer, leading
> to all kinds of misbehaviors. So, use memcpy() as a safe replacement.
> 
> This is a previous step in the path to remove the strcpy() function
> entirely from the kernel.
> 
> Signed-off-by: Len Baker <len.baker at gmx.com>
> ---
>  drivers/soc/renesas/r8a779a0-sysc.c | 6 ++++--
>  drivers/soc/renesas/rcar-sysc.c     | 6 ++++--
>  2 files changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
> index d464ffa1be33..7410b9fa9846 100644
> --- a/drivers/soc/renesas/r8a779a0-sysc.c
> +++ b/drivers/soc/renesas/r8a779a0-sysc.c
> @@ -404,19 +404,21 @@ static int __init r8a779a0_sysc_pd_init(void)
>  	for (i = 0; i < info->num_areas; i++) {
>  		const struct r8a779a0_sysc_area *area = &info->areas[i];
>  		struct r8a779a0_sysc_pd *pd;
> +		size_t n;
> 
>  		if (!area->name) {
>  			/* Skip NULLified area */
>  			continue;
>  		}
> 
> -		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL)> +		n = strlen(area->name) + 1;
> +		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
Zeroing the allocated bytes is not needed since it's completly
overwritten with the strcpy()/memcpy().
>  		if (!pd) {
>  			error = -ENOMEM;
>  			goto out_put;
>  		}
> 
> -		strcpy(pd->name, area->name);
> +		memcpy(pd->name, area->name, n);
>  		pd->genpd.name = pd->name;
>  		pd->pdr = area->pdr;
>  		pd->flags = area->flags;

And similar for the second hunk.

MfG,
	Bernd
-- 
Bernd Petrovitsch                  Email : bernd at petrovitsch.priv.at
     There is NO CLOUD, just other people's computers. - FSFE
                     LUGA : http://www.luga.at


From len.baker at gmx.com  Sun Aug  8 05:50:12 2021
From: len.baker at gmx.com (Len Baker)
Date: Sun,  8 Aug 2021 14:50:12 +0200
Subject: [PATCH v4 3/3] drivers/soc/ti: Prefer strscpy over strcpy
In-Reply-To: <20210808125012.4715-1-len.baker@gmx.com>
References: <20210808125012.4715-1-len.baker@gmx.com>
Message-ID: <20210808125012.4715-4-len.baker@gmx.com>

strcpy() performs no bounds checking on the destination buffer. This
could result in linear overflows beyond the end of the buffer, leading
to all kinds of misbehaviors. The safe replacement is strscpy().

This is a previous step in the path to remove the strcpy() function
entirely from the kernel.

Signed-off-by: Len Baker <len.baker at gmx.com>
---
 drivers/soc/ti/knav_dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c
index 591d14ebcb11..5f9816d317a5 100644
--- a/drivers/soc/ti/knav_dma.c
+++ b/drivers/soc/ti/knav_dma.c
@@ -691,7 +691,7 @@ static int dma_init(struct device_node *cloud, struct device_node *dma_node)
 	dma->max_rx_flow = max_rx_flow;
 	dma->max_tx_chan = min(max_tx_chan, max_tx_sched);
 	atomic_set(&dma->ref_count, 0);
-	strcpy(dma->name, node->name);
+	strscpy(dma->name, node->name, sizeof(dma->name));
 	spin_lock_init(&dma->lock);

 	for (i = 0; i < dma->max_tx_chan; i++) {
--
2.25.1



From valentin.schneider at arm.com  Sun Aug  8 09:15:20 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sun, 08 Aug 2021 17:15:20 +0100
Subject: [PATCH v2 2/4] sched: Introduce is_pcpu_safe()
In-Reply-To: <800ff941e3ec86ea1397cddf8ecea3d4a17c55dc.camel@gmx.de>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
 <20210807005807.1083943-3-valentin.schneider@arm.com>
 <800ff941e3ec86ea1397cddf8ecea3d4a17c55dc.camel@gmx.de>
Message-ID: <87a6lrap5z.mognet@arm.com>

On 07/08/21 03:42, Mike Galbraith wrote:
> On Sat, 2021-08-07 at 01:58 +0100, Valentin Schneider wrote:
>>
>> +static inline bool is_pcpu_safe(void)
>
> Nit: seems odd to avoid spelling it out to save two characters, percpu
> is word like, rolls off the ole tongue better than p-c-p-u.
>
>       -Mike

True. A quick grep says both versions are used, though "percpu" wins by
about a factor of 2. I'll tweak that for a v3.


From dqfext at gmail.com  Sun Aug  8 10:00:24 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Mon,  9 Aug 2021 01:00:24 +0800
Subject: [PATCH] mt7530 fix mt7530_fdb_write vid missing ivl bit
In-Reply-To: <20210716152213.4213-1-ericwouds@gmail.com>
References: <20210716152213.4213-1-ericwouds@gmail.com>
Message-ID: <20210808170024.228363-1-dqfext@gmail.com>

On Fri, Jul 16, 2021 at 05:22:11PM +0200, ericwouds at gmail.com wrote:
> From: Eric Woudstra <37153012+ericwoud at users.noreply.github.com>
> 
> According to reference guides mt7530 (mt7620) and mt7531:
> 
> NOTE: When IVL is reset, MAC[47:0] and FID[2:0] will be used to 
> read/write the address table. When IVL is set, MAC[47:0] and CVID[11:0] 
> will be used to read/write the address table.
> 
> Since the function only fills in CVID and no FID, we need to set the
> IVL bit. The existing code does not set it.
> 
> This is a fix for the issue I dropped here earlier:
> 
> http://lists.infradead.org/pipermail/linux-mediatek/2021-June/025697.html
> 
> With this patch, it is now possible to delete the 'self' fdb entry
> manually. However, wifi roaming still has the same issue, the entry
> does not get deleted automatically. Wifi roaming also needs a fix
> somewhere else to function correctly in combination with vlan.

Sorry to bump this up, but I think I identified the issue:

Consider a VLAN-aware bridge br0, with two ports set to different PVIDs:

> bridge vlan
> port         vlan-id
> swp0         1 PVID Egress Untagged
> swp1         2 PVID Egress Untagged

When the bridge core sends a packet to swp1, the packet will be sent to
the CPU port of the switch as untagged because swp1 is set as "Egress
Untagged". However if the switch uses independent VLAN learning, the CPU
port PVID will be used to update the FDB. As we don't change its PVID
(not reasonable to change it anyway), hardware learning may not update
the correct FDB.

A possible solution is always send packets as tagged when serving a
VLAN-aware bridge.

mv88e6xxx has been using hardware learning on CPU port since commit
d82f8ab0d874 ("net: dsa: tag_dsa: offload the bridge forwarding process"),
does it have the same issue?


From jic23 at kernel.org  Sun Aug  8 10:06:08 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 8 Aug 2021 18:06:08 +0100
Subject: [PATCH v14 01/17] counter: 104-quad-8: Return error when
 invalid mode during ceiling_write
In-Reply-To: <a2147f022829b66839a1db5530a7fada47856847.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
 <a2147f022829b66839a1db5530a7fada47856847.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <20210808180608.2925961b@jic23-huawei>

On Tue,  3 Aug 2021 21:06:11 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> The 104-QUAD-8 only has two count modes where a ceiling value makes
> sense: Range Limit and Modulo-N. Outside of these two modes, setting a
> ceiling value is an invalid operation -- so let's report it as such by
> returning -EINVAL.
> 
> Fixes: fc069262261c ("counter: 104-quad-8: Add lock guards - generic interface")
> Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
Applied to the togreg branch of iio.git and pushed out as testing for 0-day to have
fun.

As an aside, I got the warning:
  CHECK   drivers/counter/104-quad-8.c
drivers/counter/104-quad-8.c:58: warning: Function parameter or member 'lock' not described in 'quad8'

Which might be nice to clean up, but has nothing much to do with this patch.

J

> ---
>  drivers/counter/104-quad-8.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
> index 09a9a77cce06..81f9642777fb 100644
> --- a/drivers/counter/104-quad-8.c
> +++ b/drivers/counter/104-quad-8.c
> @@ -715,12 +715,13 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
>  	case 1:
>  	case 3:
>  		quad8_preset_register_set(priv, count->id, ceiling);
> -		break;
> +		mutex_unlock(&priv->lock);
> +		return len;
>  	}
>  
>  	mutex_unlock(&priv->lock);
>  
> -	return len;
> +	return -EINVAL;
>  }
>  
>  static ssize_t quad8_count_preset_enable_read(struct counter_device *counter,



From jic23 at kernel.org  Sun Aug  8 10:07:11 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 8 Aug 2021 18:07:11 +0100
Subject: [PATCH v14 02/17] counter: Return error code on invalid modes
In-Reply-To: <7af82d4e39610da11edce0ee370285fe1cb1eac8.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
 <7af82d4e39610da11edce0ee370285fe1cb1eac8.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <20210808180711.0b359e79@jic23-huawei>

On Tue,  3 Aug 2021 21:06:12 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> Only a select set of modes (function, action, etc.) are valid for a
> given device configuration. This patch ensures that invalid modes result
> in a return -EINVAL. Such a situation should never occur in reality, but
> it's good to define a default switch case for the sake of making the
> intent of the code clear.
> 
> Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at st.com>
> Acked-by: David Lechner <david at lechnology.com>
> Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>

Applied,

Thanks,

> ---
>  drivers/counter/104-quad-8.c            | 20 ++++++++++++------
>  drivers/counter/microchip-tcb-capture.c |  6 ++++++
>  drivers/counter/stm32-lptimer-cnt.c     | 10 +++++----
>  drivers/counter/ti-eqep.c               | 27 +++++++++++++++----------
>  4 files changed, 42 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
> index 81f9642777fb..b358b2b2b883 100644
> --- a/drivers/counter/104-quad-8.c
> +++ b/drivers/counter/104-quad-8.c
> @@ -273,6 +273,10 @@ static int quad8_function_set(struct counter_device *counter,
>  			*scale = 2;
>  			mode_cfg |= QUAD8_CMR_QUADRATURE_X4;
>  			break;
> +		default:
> +			/* should never reach this path */
> +			mutex_unlock(&priv->lock);
> +			return -EINVAL;
>  		}
>  	}
>  
> @@ -349,7 +353,7 @@ static int quad8_action_get(struct counter_device *counter,
>  	case QUAD8_COUNT_FUNCTION_PULSE_DIRECTION:
>  		if (synapse->signal->id == signal_a_id)
>  			*action = QUAD8_SYNAPSE_ACTION_RISING_EDGE;
> -		break;
> +		return 0;
>  	case QUAD8_COUNT_FUNCTION_QUADRATURE_X1:
>  		if (synapse->signal->id == signal_a_id) {
>  			quad8_direction_get(counter, count, &direction);
> @@ -359,17 +363,18 @@ static int quad8_action_get(struct counter_device *counter,
>  			else
>  				*action = QUAD8_SYNAPSE_ACTION_FALLING_EDGE;
>  		}
> -		break;
> +		return 0;
>  	case QUAD8_COUNT_FUNCTION_QUADRATURE_X2:
>  		if (synapse->signal->id == signal_a_id)
>  			*action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES;
> -		break;
> +		return 0;
>  	case QUAD8_COUNT_FUNCTION_QUADRATURE_X4:
>  		*action = QUAD8_SYNAPSE_ACTION_BOTH_EDGES;
> -		break;
> +		return 0;
> +	default:
> +		/* should never reach this path */
> +		return -EINVAL;
>  	}
> -
> -	return 0;
>  }
>  
>  static const struct counter_ops quad8_ops = {
> @@ -529,6 +534,9 @@ static int quad8_count_mode_set(struct counter_device *counter,
>  	case COUNTER_COUNT_MODE_MODULO_N:
>  		cnt_mode = 3;
>  		break;
> +	default:
> +		/* should never reach this path */
> +		return -EINVAL;
>  	}
>  
>  	mutex_lock(&priv->lock);
> diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
> index 51b8af80f98b..0c9a61962911 100644
> --- a/drivers/counter/microchip-tcb-capture.c
> +++ b/drivers/counter/microchip-tcb-capture.c
> @@ -133,6 +133,9 @@ static int mchp_tc_count_function_set(struct counter_device *counter,
>  		bmr |= ATMEL_TC_QDEN | ATMEL_TC_POSEN;
>  		cmr |= ATMEL_TC_ETRGEDG_RISING | ATMEL_TC_ABETRG | ATMEL_TC_XC0;
>  		break;
> +	default:
> +		/* should never reach this path */
> +		return -EINVAL;
>  	}
>  
>  	regmap_write(priv->regmap, ATMEL_TC_BMR, bmr);
> @@ -226,6 +229,9 @@ static int mchp_tc_count_action_set(struct counter_device *counter,
>  	case MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE:
>  		edge = ATMEL_TC_ETRGEDG_BOTH;
>  		break;
> +	default:
> +		/* should never reach this path */
> +		return -EINVAL;
>  	}
>  
>  	return regmap_write_bits(priv->regmap,
> diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
> index c19d998df5ba..78f383b77bd2 100644
> --- a/drivers/counter/stm32-lptimer-cnt.c
> +++ b/drivers/counter/stm32-lptimer-cnt.c
> @@ -206,9 +206,10 @@ static int stm32_lptim_cnt_function_set(struct counter_device *counter,
>  		priv->quadrature_mode = 1;
>  		priv->polarity = STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES;
>  		return 0;
> +	default:
> +		/* should never reach this path */
> +		return -EINVAL;
>  	}
> -
> -	return -EINVAL;
>  }
>  
>  static ssize_t stm32_lptim_cnt_enable_read(struct counter_device *counter,
> @@ -326,9 +327,10 @@ static int stm32_lptim_cnt_action_get(struct counter_device *counter,
>  	case STM32_LPTIM_ENCODER_BOTH_EDGE:
>  		*action = priv->polarity;
>  		return 0;
> +	default:
> +		/* should never reach this path */
> +		return -EINVAL;
>  	}
> -
> -	return -EINVAL;
>  }
>  
>  static int stm32_lptim_cnt_action_set(struct counter_device *counter,
> diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
> index 65df9ef5b5bc..c303eb17c111 100644
> --- a/drivers/counter/ti-eqep.c
> +++ b/drivers/counter/ti-eqep.c
> @@ -157,7 +157,7 @@ static int ti_eqep_action_get(struct counter_device *counter,
>  		 * QEPA and QEPB trigger QCLK.
>  		 */
>  		*action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES;
> -		break;
> +		return 0;
>  	case TI_EQEP_COUNT_FUNC_DIR_COUNT:
>  		/* In direction-count mode only rising edge of QEPA is counted
>  		 * and QEPB gives direction.
> @@ -165,12 +165,14 @@ static int ti_eqep_action_get(struct counter_device *counter,
>  		switch (synapse->signal->id) {
>  		case TI_EQEP_SIGNAL_QEPA:
>  			*action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE;
> -			break;
> -		default:
> +			return 0;
> +		case TI_EQEP_SIGNAL_QEPB:
>  			*action = TI_EQEP_SYNAPSE_ACTION_NONE;
> -			break;
> +			return 0;
> +		default:
> +			/* should never reach this path */
> +			return -EINVAL;
>  		}
> -		break;
>  	case TI_EQEP_COUNT_FUNC_UP_COUNT:
>  	case TI_EQEP_COUNT_FUNC_DOWN_COUNT:
>  		/* In up/down-count modes only QEPA is counted and QEPB is not
> @@ -186,15 +188,18 @@ static int ti_eqep_action_get(struct counter_device *counter,
>  				*action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES;
>  			else
>  				*action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE;
> -			break;
> -		default:
> +			return 0;
> +		case TI_EQEP_SIGNAL_QEPB:
>  			*action = TI_EQEP_SYNAPSE_ACTION_NONE;
> -			break;
> +			return 0;
> +		default:
> +			/* should never reach this path */
> +			return -EINVAL;
>  		}
> -		break;
> +	default:
> +		/* should never reach this path */
> +		return -EINVAL;
>  	}
> -
> -	return 0;
>  }
>  
>  static const struct counter_ops ti_eqep_counter_ops = {



From jic23 at kernel.org  Sun Aug  8 10:08:55 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 8 Aug 2021 18:08:55 +0100
Subject: [PATCH v14 03/17] counter: Standardize to ERANGE for limit
 exceeded errors
In-Reply-To: <ae8d3b20b8b02c96b1c9898ffa2f9fa5d99edc81.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
 <ae8d3b20b8b02c96b1c9898ffa2f9fa5d99edc81.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <20210808180855.1251f06c@jic23-huawei>

On Tue,  3 Aug 2021 21:06:13 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> ERANGE is a semantically better error code to return when an argument
> value falls outside the supported limit range of a device.
> 
> Cc: Jarkko Nikula <jarkko.nikula at linux.intel.com>
> Cc: Oleksij Rempel <o.rempel at pengutronix.de>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at st.com>
> Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> Reviewed-by: David Lechner <david at lechnology.com>
> Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>

Just for the record, I'll note this is an ABI change.  However, I'm
fairly sure it's the category of no one will notice and so we are fine
to change it.

Applied,

Thanks,

Jonathan

> ---
>  drivers/counter/104-quad-8.c        | 6 +++---
>  drivers/counter/intel-qep.c         | 2 +-
>  drivers/counter/interrupt-cnt.c     | 3 +++
>  drivers/counter/stm32-lptimer-cnt.c | 2 +-
>  4 files changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
> index b358b2b2b883..d54efdb8d393 100644
> --- a/drivers/counter/104-quad-8.c
> +++ b/drivers/counter/104-quad-8.c
> @@ -154,7 +154,7 @@ static int quad8_count_write(struct counter_device *counter,
>  
>  	/* Only 24-bit values are supported */
>  	if (val > 0xFFFFFF)
> -		return -EINVAL;
> +		return -ERANGE;
>  
>  	mutex_lock(&priv->lock);
>  
> @@ -669,7 +669,7 @@ static ssize_t quad8_count_preset_write(struct counter_device *counter,
>  
>  	/* Only 24-bit values are supported */
>  	if (preset > 0xFFFFFF)
> -		return -EINVAL;
> +		return -ERANGE;
>  
>  	mutex_lock(&priv->lock);
>  
> @@ -714,7 +714,7 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
>  
>  	/* Only 24-bit values are supported */
>  	if (ceiling > 0xFFFFFF)
> -		return -EINVAL;
> +		return -ERANGE;
>  
>  	mutex_lock(&priv->lock);
>  
> diff --git a/drivers/counter/intel-qep.c b/drivers/counter/intel-qep.c
> index 1a9512e28519..204f94577666 100644
> --- a/drivers/counter/intel-qep.c
> +++ b/drivers/counter/intel-qep.c
> @@ -319,7 +319,7 @@ static ssize_t spike_filter_ns_write(struct counter_device *counter,
>  	}
>  
>  	if (length > INTEL_QEPFLT_MAX_COUNT(length))
> -		return -EINVAL;
> +		return -ERANGE;
>  
>  	mutex_lock(&qep->lock);
>  	if (qep->enabled) {
> diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
> index 5df7cd13d4c7..66cac4900327 100644
> --- a/drivers/counter/interrupt-cnt.c
> +++ b/drivers/counter/interrupt-cnt.c
> @@ -107,6 +107,9 @@ static int interrupt_cnt_write(struct counter_device *counter,
>  {
>  	struct interrupt_cnt_priv *priv = counter->priv;
>  
> +	if (val != (typeof(priv->count.counter))val)
> +		return -ERANGE;
> +
>  	atomic_set(&priv->count, val);
>  
>  	return 0;
> diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
> index 78f383b77bd2..49aeb9e393f3 100644
> --- a/drivers/counter/stm32-lptimer-cnt.c
> +++ b/drivers/counter/stm32-lptimer-cnt.c
> @@ -283,7 +283,7 @@ static ssize_t stm32_lptim_cnt_ceiling_write(struct counter_device *counter,
>  		return ret;
>  
>  	if (ceiling > STM32_LPTIM_MAX_ARR)
> -		return -EINVAL;
> +		return -ERANGE;
>  
>  	priv->ceiling = ceiling;
>  



From jic23 at kernel.org  Sun Aug  8 10:10:37 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 8 Aug 2021 18:10:37 +0100
Subject: [PATCH v14 04/17] counter: Rename counter_signal_value to
 counter_signal_level
In-Reply-To: <3f17010abe2415859cea9a5fddabd3c97f635ff5.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
 <3f17010abe2415859cea9a5fddabd3c97f635ff5.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <20210808181037.3016bb00@jic23-huawei>

On Tue,  3 Aug 2021 21:06:14 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> Signal values will always be levels so let's be explicit it about it to
> make the intent of the code clear.
> 
> Cc: Oleksij Rempel <o.rempel at pengutronix.de>
> Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
> Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> Reviewed-by: David Lechner <david at lechnology.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
Applied.
> ---
>  drivers/counter/104-quad-8.c            |  5 +++--
>  drivers/counter/counter.c               | 12 ++++++------
>  drivers/counter/interrupt-cnt.c         |  4 ++--
>  drivers/counter/microchip-tcb-capture.c |  4 ++--
>  include/linux/counter.h                 | 12 ++++++------
>  5 files changed, 19 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
> index d54efdb8d393..b4dd07cf51eb 100644
> --- a/drivers/counter/104-quad-8.c
> +++ b/drivers/counter/104-quad-8.c
> @@ -97,7 +97,8 @@ struct quad8 {
>  #define QUAD8_CMR_QUADRATURE_X4 0x18
>  
>  static int quad8_signal_read(struct counter_device *counter,
> -	struct counter_signal *signal, enum counter_signal_value *val)
> +			     struct counter_signal *signal,
> +			     enum counter_signal_level *level)
>  {
>  	const struct quad8 *const priv = counter->priv;
>  	unsigned int state;
> @@ -109,7 +110,7 @@ static int quad8_signal_read(struct counter_device *counter,
>  	state = inb(priv->base + QUAD8_REG_INDEX_INPUT_LEVELS)
>  		& BIT(signal->id - 16);
>  
> -	*val = (state) ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
> +	*level = (state) ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
>  
>  	return 0;
>  }
> diff --git a/drivers/counter/counter.c b/drivers/counter/counter.c
> index 6a683d086008..cb92673552b5 100644
> --- a/drivers/counter/counter.c
> +++ b/drivers/counter/counter.c
> @@ -289,9 +289,9 @@ struct counter_signal_unit {
>  	struct counter_signal *signal;
>  };
>  
> -static const char *const counter_signal_value_str[] = {
> -	[COUNTER_SIGNAL_LOW] = "low",
> -	[COUNTER_SIGNAL_HIGH] = "high"
> +static const char *const counter_signal_level_str[] = {
> +	[COUNTER_SIGNAL_LEVEL_LOW] = "low",
> +	[COUNTER_SIGNAL_LEVEL_HIGH] = "high"
>  };
>  
>  static ssize_t counter_signal_show(struct device *dev,
> @@ -302,13 +302,13 @@ static ssize_t counter_signal_show(struct device *dev,
>  	const struct counter_signal_unit *const component = devattr->component;
>  	struct counter_signal *const signal = component->signal;
>  	int err;
> -	enum counter_signal_value val;
> +	enum counter_signal_level level;
>  
> -	err = counter->ops->signal_read(counter, signal, &val);
> +	err = counter->ops->signal_read(counter, signal, &level);
>  	if (err)
>  		return err;
>  
> -	return sprintf(buf, "%s\n", counter_signal_value_str[val]);
> +	return sprintf(buf, "%s\n", counter_signal_level_str[level]);
>  }
>  
>  struct counter_name_unit {
> diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
> index 66cac4900327..d06367bef8f0 100644
> --- a/drivers/counter/interrupt-cnt.c
> +++ b/drivers/counter/interrupt-cnt.c
> @@ -130,7 +130,7 @@ static int interrupt_cnt_function_get(struct counter_device *counter,
>  
>  static int interrupt_cnt_signal_read(struct counter_device *counter,
>  				     struct counter_signal *signal,
> -				     enum counter_signal_value *val)
> +				     enum counter_signal_level *level)
>  {
>  	struct interrupt_cnt_priv *priv = counter->priv;
>  	int ret;
> @@ -142,7 +142,7 @@ static int interrupt_cnt_signal_read(struct counter_device *counter,
>  	if (ret < 0)
>  		return ret;
>  
> -	*val = ret ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
> +	*level = ret ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
>  
>  	return 0;
>  }
> diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
> index 0c9a61962911..6be3adf74114 100644
> --- a/drivers/counter/microchip-tcb-capture.c
> +++ b/drivers/counter/microchip-tcb-capture.c
> @@ -158,7 +158,7 @@ static int mchp_tc_count_function_set(struct counter_device *counter,
>  
>  static int mchp_tc_count_signal_read(struct counter_device *counter,
>  				     struct counter_signal *signal,
> -				     enum counter_signal_value *val)
> +				     enum counter_signal_level *lvl)
>  {
>  	struct mchp_tc_data *const priv = counter->priv;
>  	bool sigstatus;
> @@ -171,7 +171,7 @@ static int mchp_tc_count_signal_read(struct counter_device *counter,
>  	else
>  		sigstatus = (sr & ATMEL_TC_MTIOA);
>  
> -	*val = sigstatus ? COUNTER_SIGNAL_HIGH : COUNTER_SIGNAL_LOW;
> +	*lvl = sigstatus ? COUNTER_SIGNAL_LEVEL_HIGH : COUNTER_SIGNAL_LEVEL_LOW;
>  
>  	return 0;
>  }
> diff --git a/include/linux/counter.h b/include/linux/counter.h
> index 9dbd5df4cd34..79f5dcaf6ba0 100644
> --- a/include/linux/counter.h
> +++ b/include/linux/counter.h
> @@ -290,16 +290,16 @@ struct counter_device_state {
>  	const struct attribute_group **groups;
>  };
>  
> -enum counter_signal_value {
> -	COUNTER_SIGNAL_LOW = 0,
> -	COUNTER_SIGNAL_HIGH
> +enum counter_signal_level {
> +	COUNTER_SIGNAL_LEVEL_LOW,
> +	COUNTER_SIGNAL_LEVEL_HIGH,
>  };
>  
>  /**
>   * struct counter_ops - Callbacks from driver
>   * @signal_read:	optional read callback for Signal attribute. The read
> - *			value of the respective Signal should be passed back via
> - *			the val parameter.
> + *			level of the respective Signal should be passed back via
> + *			the level parameter.
>   * @count_read:		optional read callback for Count attribute. The read
>   *			value of the respective Count should be passed back via
>   *			the val parameter.
> @@ -324,7 +324,7 @@ enum counter_signal_value {
>  struct counter_ops {
>  	int (*signal_read)(struct counter_device *counter,
>  			   struct counter_signal *signal,
> -			   enum counter_signal_value *val);
> +			   enum counter_signal_level *level);
>  	int (*count_read)(struct counter_device *counter,
>  			  struct counter_count *count, unsigned long *val);
>  	int (*count_write)(struct counter_device *counter,



From jic23 at kernel.org  Sun Aug  8 10:15:38 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 8 Aug 2021 18:15:38 +0100
Subject: [PATCH v14 05/17] counter: Rename counter_count_function to
 counter_function
In-Reply-To: <8268c54d6f42075a19bb08151a37831e22652499.1627990337.git.vilhelm.gray@gmail.com>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
 <8268c54d6f42075a19bb08151a37831e22652499.1627990337.git.vilhelm.gray@gmail.com>
Message-ID: <20210808181130.2c855897@jic23-huawei>

On Tue,  3 Aug 2021 21:06:15 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> The phrase "Counter Count function" is verbose and unintentionally
> implies that function is a Count extension. This patch adjusts the
> Counter subsystem code to use the more direct "Counter function" phrase
> to make the intent of this code clearer.
> 
> Cc: Jarkko Nikula <jarkko.nikula at linux.intel.com>
> Cc: Patrick Havelange <patrick.havelange at essensium.com>
> Cc: Oleksij Rempel <o.rempel at pengutronix.de>
> Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at st.com>
> Cc: David Lechner <david at lechnology.com>
> Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>

this one doesn't build cleanly for me.

drivers/counter/microchip-tcb-capture.c:40:42: error: array type has incomplete element type ?enum counter_count_function?
   40 | static const enum counter_count_function mchp_tc_count_functions[] = {
      |                                          ^~~~~~~~~~~~~~~~~~~~~~~
In file included from ./include/linux/bits.h:22,
                 from ./include/linux/bitops.h:6,
                 from ./include/linux/kernel.h:12,
                 from ./include/linux/clk.h:13,
                 from drivers/counter/microchip-tcb-capture.c:7:
./include/linux/build_bug.h:16:51: error: bit-field ?<anonymous>? width not an integer constant
   16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
      |                                                   ^
./include/linux/compiler.h:256:33: note: in expansion of macro ?BUILD_BUG_ON_ZERO?
  256 | #define __must_be_array(a)      BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
      |                                 ^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:44:59: note: in expansion of macro ?__must_be_array?
   44 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
      |                                                           ^~~~~~~~~~~~~~~
drivers/counter/microchip-tcb-capture.c:260:34: note: in expansion of macro ?ARRAY_SIZE?
  260 |                 .num_functions = ARRAY_SIZE(mchp_tc_count_functions),
      |                                  ^~~~~~~~~~
drivers/counter/microchip-tcb-capture.c:40:42: warning: ?mchp_tc_count_functions? defined but not used [-Wunused-variable]
   40 | static const enum counter_count_function mchp_tc_count_functions[] = {
      |                                          ^~~~~~~~~~~~~~~~~~~~~~~
drivers/counter/104-quad-8.c:58: warning: Function parameter or member 'lock' not described in 'quad8'
make[2]: *** [scripts/Makefile.build:271: drivers/counter/microchip-tcb-capture.o] Error 1
make[2]: *** Waiting for unfinished jobs....
  CHECK   drivers/counter/counter.c
  CHECK   drivers/counter/intel-qep.c
make[1]: *** [scripts/Makefile.build:514: drivers/counter] Error 2
make: *** [Makefile:1841: drivers] Error 2

I fixed it by changing the type to counter_function to match the other cases and applied that.

Please take a quick look to make sure I didn't mess it up.

Jonathan




> ---
>  drivers/counter/104-quad-8.c            | 10 +++----
>  drivers/counter/counter.c               | 38 ++++++++++++-------------
>  drivers/counter/ftm-quaddec.c           |  5 ++--
>  drivers/counter/intel-qep.c             |  4 +--
>  drivers/counter/interrupt-cnt.c         |  4 +--
>  drivers/counter/microchip-tcb-capture.c |  4 +--
>  drivers/counter/stm32-lptimer-cnt.c     |  6 ++--
>  drivers/counter/stm32-timer-cnt.c       | 10 +++----
>  drivers/counter/ti-eqep.c               | 10 +++----
>  include/linux/counter.h                 | 20 ++++++-------
>  10 files changed, 55 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
> index b4dd07cf51eb..5283ff128c17 100644
> --- a/drivers/counter/104-quad-8.c
> +++ b/drivers/counter/104-quad-8.c
> @@ -194,11 +194,11 @@ enum quad8_count_function {
>  	QUAD8_COUNT_FUNCTION_QUADRATURE_X4
>  };
>  
> -static const enum counter_count_function quad8_count_functions_list[] = {
> -	[QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
> -	[QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A,
> -	[QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
> -	[QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4
> +static const enum counter_function quad8_count_functions_list[] = {
> +	[QUAD8_COUNT_FUNCTION_PULSE_DIRECTION] = COUNTER_FUNCTION_PULSE_DIRECTION,
> +	[QUAD8_COUNT_FUNCTION_QUADRATURE_X1] = COUNTER_FUNCTION_QUADRATURE_X1_A,
> +	[QUAD8_COUNT_FUNCTION_QUADRATURE_X2] = COUNTER_FUNCTION_QUADRATURE_X2_A,
> +	[QUAD8_COUNT_FUNCTION_QUADRATURE_X4] = COUNTER_FUNCTION_QUADRATURE_X4
>  };
>  
>  static int quad8_function_get(struct counter_device *counter,
> diff --git a/drivers/counter/counter.c b/drivers/counter/counter.c
> index cb92673552b5..de921e8a3f72 100644
> --- a/drivers/counter/counter.c
> +++ b/drivers/counter/counter.c
> @@ -744,15 +744,15 @@ static ssize_t counter_count_store(struct device *dev,
>  	return len;
>  }
>  
> -static const char *const counter_count_function_str[] = {
> -	[COUNTER_COUNT_FUNCTION_INCREASE] = "increase",
> -	[COUNTER_COUNT_FUNCTION_DECREASE] = "decrease",
> -	[COUNTER_COUNT_FUNCTION_PULSE_DIRECTION] = "pulse-direction",
> -	[COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a",
> -	[COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b",
> -	[COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a",
> -	[COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b",
> -	[COUNTER_COUNT_FUNCTION_QUADRATURE_X4] = "quadrature x4"
> +static const char *const counter_function_str[] = {
> +	[COUNTER_FUNCTION_INCREASE] = "increase",
> +	[COUNTER_FUNCTION_DECREASE] = "decrease",
> +	[COUNTER_FUNCTION_PULSE_DIRECTION] = "pulse-direction",
> +	[COUNTER_FUNCTION_QUADRATURE_X1_A] = "quadrature x1 a",
> +	[COUNTER_FUNCTION_QUADRATURE_X1_B] = "quadrature x1 b",
> +	[COUNTER_FUNCTION_QUADRATURE_X2_A] = "quadrature x2 a",
> +	[COUNTER_FUNCTION_QUADRATURE_X2_B] = "quadrature x2 b",
> +	[COUNTER_FUNCTION_QUADRATURE_X4] = "quadrature x4"
>  };
>  
>  static ssize_t counter_function_show(struct device *dev,
> @@ -764,7 +764,7 @@ static ssize_t counter_function_show(struct device *dev,
>  	const struct counter_count_unit *const component = devattr->component;
>  	struct counter_count *const count = component->count;
>  	size_t func_index;
> -	enum counter_count_function function;
> +	enum counter_function function;
>  
>  	err = counter->ops->function_get(counter, count, &func_index);
>  	if (err)
> @@ -773,7 +773,7 @@ static ssize_t counter_function_show(struct device *dev,
>  	count->function = func_index;
>  
>  	function = count->functions_list[func_index];
> -	return sprintf(buf, "%s\n", counter_count_function_str[function]);
> +	return sprintf(buf, "%s\n", counter_function_str[function]);
>  }
>  
>  static ssize_t counter_function_store(struct device *dev,
> @@ -785,14 +785,14 @@ static ssize_t counter_function_store(struct device *dev,
>  	struct counter_count *const count = component->count;
>  	const size_t num_functions = count->num_functions;
>  	size_t func_index;
> -	enum counter_count_function function;
> +	enum counter_function function;
>  	int err;
>  	struct counter_device *const counter = dev_get_drvdata(dev);
>  
>  	/* Find requested Count function mode */
>  	for (func_index = 0; func_index < num_functions; func_index++) {
>  		function = count->functions_list[func_index];
> -		if (sysfs_streq(buf, counter_count_function_str[function]))
> +		if (sysfs_streq(buf, counter_function_str[function]))
>  			break;
>  	}
>  	/* Return error if requested Count function mode not found */
> @@ -880,25 +880,25 @@ static int counter_count_ext_register(
>  }
>  
>  struct counter_func_avail_unit {
> -	const enum counter_count_function *functions_list;
> +	const enum counter_function *functions_list;
>  	size_t num_functions;
>  };
>  
> -static ssize_t counter_count_function_available_show(struct device *dev,
> +static ssize_t counter_function_available_show(struct device *dev,
>  	struct device_attribute *attr, char *buf)
>  {
>  	const struct counter_device_attr *const devattr = to_counter_attr(attr);
>  	const struct counter_func_avail_unit *const component = devattr->component;
> -	const enum counter_count_function *const func_list = component->functions_list;
> +	const enum counter_function *const func_list = component->functions_list;
>  	const size_t num_functions = component->num_functions;
>  	size_t i;
> -	enum counter_count_function function;
> +	enum counter_function function;
>  	ssize_t len = 0;
>  
>  	for (i = 0; i < num_functions; i++) {
>  		function = func_list[i];
>  		len += sprintf(buf + len, "%s\n",
> -			       counter_count_function_str[function]);
> +			       counter_function_str[function]);
>  	}
>  
>  	return len;
> @@ -968,7 +968,7 @@ static int counter_count_attributes_create(
>  	parm.group = group;
>  	parm.prefix = "";
>  	parm.name = "function_available";
> -	parm.show = counter_count_function_available_show;
> +	parm.show = counter_function_available_show;
>  	parm.store = NULL;
>  	parm.component = avail_comp;
>  	err = counter_attribute_create(&parm);
> diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c
> index 9371532406ca..53c15f84909b 100644
> --- a/drivers/counter/ftm-quaddec.c
> +++ b/drivers/counter/ftm-quaddec.c
> @@ -171,9 +171,8 @@ enum ftm_quaddec_count_function {
>  	FTM_QUADDEC_COUNT_ENCODER_MODE_1,
>  };
>  
> -static const enum counter_count_function ftm_quaddec_count_functions[] = {
> -	[FTM_QUADDEC_COUNT_ENCODER_MODE_1] =
> -	COUNTER_COUNT_FUNCTION_QUADRATURE_X4
> +static const enum counter_function ftm_quaddec_count_functions[] = {
> +	[FTM_QUADDEC_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X4
>  };
>  
>  static int ftm_quaddec_count_read(struct counter_device *counter,
> diff --git a/drivers/counter/intel-qep.c b/drivers/counter/intel-qep.c
> index 204f94577666..8a6847d5fb2b 100644
> --- a/drivers/counter/intel-qep.c
> +++ b/drivers/counter/intel-qep.c
> @@ -126,8 +126,8 @@ static int intel_qep_count_read(struct counter_device *counter,
>  	return 0;
>  }
>  
> -static const enum counter_count_function intel_qep_count_functions[] = {
> -	COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
> +static const enum counter_function intel_qep_count_functions[] = {
> +	COUNTER_FUNCTION_QUADRATURE_X4,
>  };
>  
>  static int intel_qep_function_get(struct counter_device *counter,
> diff --git a/drivers/counter/interrupt-cnt.c b/drivers/counter/interrupt-cnt.c
> index d06367bef8f0..1de4243db488 100644
> --- a/drivers/counter/interrupt-cnt.c
> +++ b/drivers/counter/interrupt-cnt.c
> @@ -115,8 +115,8 @@ static int interrupt_cnt_write(struct counter_device *counter,
>  	return 0;
>  }
>  
> -static const enum counter_count_function interrupt_cnt_functions[] = {
> -	COUNTER_COUNT_FUNCTION_INCREASE,
> +static const enum counter_function interrupt_cnt_functions[] = {
> +	COUNTER_FUNCTION_INCREASE,
>  };
>  
>  static int interrupt_cnt_function_get(struct counter_device *counter,
> diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
> index 6be3adf74114..4c57d43e7d66 100644
> --- a/drivers/counter/microchip-tcb-capture.c
> +++ b/drivers/counter/microchip-tcb-capture.c
> @@ -38,8 +38,8 @@ enum mchp_tc_count_function {
>  };
>  
>  static const enum counter_count_function mchp_tc_count_functions[] = {
> -	[MCHP_TC_FUNCTION_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE,
> -	[MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
> +	[MCHP_TC_FUNCTION_INCREASE] = COUNTER_FUNCTION_INCREASE,
> +	[MCHP_TC_FUNCTION_QUADRATURE] = COUNTER_FUNCTION_QUADRATURE_X4,
>  };
>  
>  enum mchp_tc_synapse_action {
> diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
> index 49aeb9e393f3..13656957c45f 100644
> --- a/drivers/counter/stm32-lptimer-cnt.c
> +++ b/drivers/counter/stm32-lptimer-cnt.c
> @@ -134,9 +134,9 @@ enum stm32_lptim_cnt_function {
>  	STM32_LPTIM_ENCODER_BOTH_EDGE,
>  };
>  
> -static const enum counter_count_function stm32_lptim_cnt_functions[] = {
> -	[STM32_LPTIM_COUNTER_INCREASE] = COUNTER_COUNT_FUNCTION_INCREASE,
> -	[STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
> +static const enum counter_function stm32_lptim_cnt_functions[] = {
> +	[STM32_LPTIM_COUNTER_INCREASE] = COUNTER_FUNCTION_INCREASE,
> +	[STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_FUNCTION_QUADRATURE_X4,
>  };
>  
>  enum stm32_lptim_synapse_action {
> diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
> index 603b30ada839..3fb0debd7425 100644
> --- a/drivers/counter/stm32-timer-cnt.c
> +++ b/drivers/counter/stm32-timer-cnt.c
> @@ -50,11 +50,11 @@ enum stm32_count_function {
>  	STM32_COUNT_ENCODER_MODE_3,
>  };
>  
> -static const enum counter_count_function stm32_count_functions[] = {
> -	[STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_COUNT_FUNCTION_INCREASE,
> -	[STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
> -	[STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B,
> -	[STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
> +static const enum counter_function stm32_count_functions[] = {
> +	[STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_FUNCTION_INCREASE,
> +	[STM32_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X2_A,
> +	[STM32_COUNT_ENCODER_MODE_2] = COUNTER_FUNCTION_QUADRATURE_X2_B,
> +	[STM32_COUNT_ENCODER_MODE_3] = COUNTER_FUNCTION_QUADRATURE_X4,
>  };
>  
>  static int stm32_count_read(struct counter_device *counter,
> diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
> index c303eb17c111..94fe58bb3eab 100644
> --- a/drivers/counter/ti-eqep.c
> +++ b/drivers/counter/ti-eqep.c
> @@ -294,11 +294,11 @@ static struct counter_signal ti_eqep_signals[] = {
>  	},
>  };
>  
> -static const enum counter_count_function ti_eqep_position_functions[] = {
> -	[TI_EQEP_COUNT_FUNC_QUAD_COUNT]	= COUNTER_COUNT_FUNCTION_QUADRATURE_X4,
> -	[TI_EQEP_COUNT_FUNC_DIR_COUNT]	= COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
> -	[TI_EQEP_COUNT_FUNC_UP_COUNT]	= COUNTER_COUNT_FUNCTION_INCREASE,
> -	[TI_EQEP_COUNT_FUNC_DOWN_COUNT]	= COUNTER_COUNT_FUNCTION_DECREASE,
> +static const enum counter_function ti_eqep_position_functions[] = {
> +	[TI_EQEP_COUNT_FUNC_QUAD_COUNT]	= COUNTER_FUNCTION_QUADRATURE_X4,
> +	[TI_EQEP_COUNT_FUNC_DIR_COUNT]	= COUNTER_FUNCTION_PULSE_DIRECTION,
> +	[TI_EQEP_COUNT_FUNC_UP_COUNT]	= COUNTER_FUNCTION_INCREASE,
> +	[TI_EQEP_COUNT_FUNC_DOWN_COUNT]	= COUNTER_FUNCTION_DECREASE,
>  };
>  
>  static const enum counter_synapse_action ti_eqep_position_synapse_actions[] = {
> diff --git a/include/linux/counter.h b/include/linux/counter.h
> index 79f5dcaf6ba0..d16ce2819b48 100644
> --- a/include/linux/counter.h
> +++ b/include/linux/counter.h
> @@ -162,15 +162,15 @@ struct counter_count_ext {
>  	void *priv;
>  };
>  
> -enum counter_count_function {
> -	COUNTER_COUNT_FUNCTION_INCREASE = 0,
> -	COUNTER_COUNT_FUNCTION_DECREASE,
> -	COUNTER_COUNT_FUNCTION_PULSE_DIRECTION,
> -	COUNTER_COUNT_FUNCTION_QUADRATURE_X1_A,
> -	COUNTER_COUNT_FUNCTION_QUADRATURE_X1_B,
> -	COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A,
> -	COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B,
> -	COUNTER_COUNT_FUNCTION_QUADRATURE_X4
> +enum counter_function {
> +	COUNTER_FUNCTION_INCREASE = 0,
> +	COUNTER_FUNCTION_DECREASE,
> +	COUNTER_FUNCTION_PULSE_DIRECTION,
> +	COUNTER_FUNCTION_QUADRATURE_X1_A,
> +	COUNTER_FUNCTION_QUADRATURE_X1_B,
> +	COUNTER_FUNCTION_QUADRATURE_X2_A,
> +	COUNTER_FUNCTION_QUADRATURE_X2_B,
> +	COUNTER_FUNCTION_QUADRATURE_X4
>  };
>  
>  /**
> @@ -192,7 +192,7 @@ struct counter_count {
>  	const char *name;
>  
>  	size_t function;
> -	const enum counter_count_function *functions_list;
> +	const enum counter_function *functions_list;
>  	size_t num_functions;
>  
>  	struct counter_synapse *synapses;



From christophe.jaillet at wanadoo.fr  Sun Aug  8 10:06:30 2021
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 8 Aug 2021 19:06:30 +0200
Subject: [PATCH v4 2/3] drivers/soc/renesas: Prefer memcpy over strcpy
In-Reply-To: <39485c0e-511c-50a0-83be-f9ce6fc47e67@petrovitsch.priv.at>
References: <20210808125012.4715-1-len.baker@gmx.com>
 <20210808125012.4715-3-len.baker@gmx.com>
 <39485c0e-511c-50a0-83be-f9ce6fc47e67@petrovitsch.priv.at>
Message-ID: <c33adb9e-9604-3d89-5a5b-152eb03e5b54@wanadoo.fr>

Hi,

Le 08/08/2021 ? 17:35, Bernd Petrovitsch a ?crit?:
> Hi all!
> 
> On 08/08/2021 14:50, Len Baker wrote:
>> strcpy() performs no bounds checking on the destination buffer. This
>> could result in linear overflows beyond the end of the buffer, leading
>> to all kinds of misbehaviors. So, use memcpy() as a safe replacement.
>>
>> This is a previous step in the path to remove the strcpy() function
>> entirely from the kernel.
>>
>> Signed-off-by: Len Baker <len.baker at gmx.com>
>> ---
>>   drivers/soc/renesas/r8a779a0-sysc.c | 6 ++++--
>>   drivers/soc/renesas/rcar-sysc.c     | 6 ++++--
>>   2 files changed, 8 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
>> index d464ffa1be33..7410b9fa9846 100644
>> --- a/drivers/soc/renesas/r8a779a0-sysc.c
>> +++ b/drivers/soc/renesas/r8a779a0-sysc.c
>> @@ -404,19 +404,21 @@ static int __init r8a779a0_sysc_pd_init(void)
>>   	for (i = 0; i < info->num_areas; i++) {
>>   		const struct r8a779a0_sysc_area *area = &info->areas[i];
>>   		struct r8a779a0_sysc_pd *pd;
>> +		size_t n;
>>
>>   		if (!area->name) {
>>   			/* Skip NULLified area */
>>   			continue;
>>   		}
>>
>> -		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
>> +		n = strlen(area->name) + 1;
>> +		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
> Zeroing the allocated bytes is not needed since it's completly
> overwritten with the strcpy()/memcpy().

The strcpy()/memcpy() only overwrites the pd->name field, not the whole 
pd structure.
I think that it is needed to keep the kzalloc.

Just my 2c,
CJ

>>   		if (!pd) {
>>   			error = -ENOMEM;
>>   			goto out_put;
>>   		}
>>
>> -		strcpy(pd->name, area->name);
>> +		memcpy(pd->name, area->name, n);
>>   		pd->genpd.name = pd->name;
>>   		pd->pdr = area->pdr;
>>   		pd->flags = area->flags;
> 
> And similar for the second hunk.
> 
> MfG,
> 	Bernd
> 



From jic23 at kernel.org  Sun Aug  8 10:32:43 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 8 Aug 2021 18:32:43 +0100
Subject: [PATCH] iio: adc: stm32-dfsdm: Fix the uninitialized use if
 regmap_read() fails
In-Reply-To: <20210724164840.7381053b@jic23-huawei>
References: <20210719195313.40341-1-yzhai003@ucr.edu>
 <20210724164840.7381053b@jic23-huawei>
Message-ID: <20210808183243.70619aa8@jic23-huawei>

On Sat, 24 Jul 2021 16:48:40 +0100
Jonathan Cameron <jic23 at kernel.org> wrote:

> On Mon, 19 Jul 2021 19:53:11 +0000
> Yizhuo <yzhai003 at ucr.edu> wrote:
> 
> > Inside function stm32_dfsdm_irq(), the variable "status", "int_en"
> > could be uninitialized if the regmap_read() fails and returns an error
> > code.  However, they are directly used in the later context to decide
> > the control flow, which is potentially unsafe.
> > 
> > Fixes: e2e6771c64625 ("IIO: ADC: add STM32 DFSDM sigma delta ADC support")
> > 
> > Signed-off-by: Yizhuo <yzhai003 at ucr.edu>  
> 
> Hi Yizhou
> 
> I want to get some review of this from people familiar with the
> hardware as there is a small possibility your reordering might have
> introduced a problem.

To stm32 people, can someone take a look at this?

Thanks,

Jonathan

> 
> > ---
> >  drivers/iio/adc/stm32-dfsdm-adc.c | 9 +++++++--
> >  1 file changed, 7 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
> > index 1cfefb3b5e56..d8b78aead942 100644
> > --- a/drivers/iio/adc/stm32-dfsdm-adc.c
> > +++ b/drivers/iio/adc/stm32-dfsdm-adc.c
> > @@ -1292,9 +1292,11 @@ static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)
> >  	struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> >  	struct regmap *regmap = adc->dfsdm->regmap;
> >  	unsigned int status, int_en;
> > +	int ret;
> >  
> > -	regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
> > -	regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en);  
> 
> Moving this later is only valid if there aren't any side effects.
> The current ordering is strange enough it makes me wonder if there might be!
> 
> Jonathan
> 
> > +	ret = regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
> > +	if (ret)
> > +		return IRQ_HANDLED;
> >  
> >  	if (status & DFSDM_ISR_REOCF_MASK) {
> >  		/* Read the data register clean the IRQ status */
> > @@ -1303,6 +1305,9 @@ static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)
> >  	}
> >  
> >  	if (status & DFSDM_ISR_ROVRF_MASK) {
> > +		ret = regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en);
> > +		if (ret)
> > +			return IRQ_HANDLED;
> >  		if (int_en & DFSDM_CR2_ROVRIE_MASK)
> >  			dev_warn(&indio_dev->dev, "Overrun detected\n");
> >  		regmap_update_bits(regmap, DFSDM_ICR(adc->fl_id),  
> 



From oupton at google.com  Sun Aug  8 12:01:10 2021
From: oupton at google.com (Oliver Upton)
Date: Sun, 8 Aug 2021 12:01:10 -0700
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <87lf5c1aox.wl-maz@kernel.org>
References: <20210807191428.3488948-1-oupton@google.com>
 <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>
 <CAOQ_QsiECN7iVDyiyos12tk__viGkFhH9b6ZfkZVAYjeKhB=pQ@mail.gmail.com>
 <87lf5c1aox.wl-maz@kernel.org>
Message-ID: <CAOQ_Qsi-r0=YubmaTezB7Cq-RhzU3njWm+P5w-RWZcUz4kMfDA@mail.gmail.com>

On Sun, Aug 8, 2021 at 3:40 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Sun, 08 Aug 2021 02:14:35 +0100,
> Oliver Upton <oupton at google.com> wrote:
>
> > The only other sane idea that I could come up with is providing this
> > information to the kernel through DT, although that would leave ACPI
> > systems behind.
>
> It also has the disadvantage that a large number of DT timer nodes are
> a mess of cargo-culted, copy-pasted idioms, and that adding another
> property would only make it worse.

Agreed, this does seem like the best solution, short of the
architecture actually providing something to determine the counter
width.

On that note, I wonder how (if ever) we will be able to move away from
unnecessarily masking a 64 bit counter, i.e. a v8.6 or above
implementation. With this patch, one such counter would wrap after
36.56 years, short of the 40 year guarantee we have from the
architecture for < v8.6 implementations. Getting it to 64 bits would
squarely make it someone else's problem ~585 years from now :)

--
Thanks,
Oliver


From pali at kernel.org  Sun Aug  8 12:30:26 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sun, 8 Aug 2021 21:30:26 +0200
Subject: [PATCH v2] cpufreq: armada-37xx: forbid cpufreq for 1.2 GHz
 variant
In-Reply-To: <20210715193321.z3vswz6x4rzvw2fd@pali>
References: <20210630135942.29730-1-kabel@kernel.org>
 <20210630225601.6372-1-kabel@kernel.org>
 <20210702163035.nmb5pniwpqtmaz4b@pali>
 <20210708143451.4htvdop4zvjufrq6@pali>
 <20210715193321.z3vswz6x4rzvw2fd@pali>
Message-ID: <20210808193026.xuyaufi5wqnrcakd@pali>

Gentle reminder. This is really serious issue. Could you please look at it?

Adding more MarvellEmbeddedProcessors people to the loop: Evan, Benjamin an Igal

On Thursday 15 July 2021 21:33:21 Pali Roh?r wrote:
> Ping! Gentle reminder for Marvell people.
> 
> On Thursday 08 July 2021 16:34:51 Pali Roh?r wrote:
> > Konstantin, Nadav, Ken, Victor, Jason: This issue is pretty serious,
> > CPU on 1.2GHz A3720 is crashing. Could you please look at it?
> > 
> > On Friday 02 July 2021 18:30:35 Pali Roh?r wrote:
> > > +Jason from GlobalScale as this issue affects GlobalScale Espressobin Ultra and V7 1.2 GHz boards.
> > > 
> > > On Thursday 01 July 2021 00:56:01 Marek Beh?n wrote:
> > > > The 1.2 GHz variant of the Armada 3720 SOC is unstable with DVFS: when
> > > > the SOC boots, the WTMI firmware sets clocks and AVS values that work
> > > > correctly with 1.2 GHz CPU frequency, but random crashes occur once
> > > > cpufreq driver starts scaling.
> > > > 
> > > > We do not know currently what is the reason:
> > > > - it may be that the voltage value for L0 for 1.2 GHz variant provided
> > > >   by the vendor in the OTP is simply incorrect when scaling is used,
> > > > - it may be that some delay is needed somewhere,
> > > > - it may be something else.
> > > > 
> > > > The most sane solution now seems to be to simply forbid the cpufreq
> > > > driver on 1.2 GHz variant.
> > > > 
> > > > Signed-off-by: Marek Beh?n <kabel at kernel.org>
> > > > Fixes: 92ce45fb875d ("cpufreq: Add DVFS support for Armada 37xx")
> > > > ---
> > > > If someone from Marvell could look into this, it would be great since
> > > > basically 1.2 GHz variant cannot scale, which is a feature that was
> > > > claimed to be supported by the SOC.
> > > > 
> > > > Ken Ma / Victor Gu, you have worked on commit
> > > > https://github.com/MarvellEmbeddedProcessors/linux-marvell/commit/d6719fdc2b3cac58064f41b531f86993c919aa9a
> > > > in linux-marvell.
> > > > Your patch takes away the 1202 mV constant for 1.2 GHz base CPU
> > > > frequency and instead adds code that computes the voltages from the
> > > > voltage found in L0 AVS register (which is filled in by WTMI firmware).
> > > > 
> > > > Do you know why the code does not work correctly for some 1.2 GHz
> > > > boards? Do we need to force the L0 voltage to 1202 mV if it is lower,
> > > > or something?
> > > > ---
> > > >  drivers/cpufreq/armada-37xx-cpufreq.c | 6 +++++-
> > > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
> > > > index 3fc98a3ffd91..c10fc33b29b1 100644
> > > > --- a/drivers/cpufreq/armada-37xx-cpufreq.c
> > > > +++ b/drivers/cpufreq/armada-37xx-cpufreq.c
> > > > @@ -104,7 +104,11 @@ struct armada_37xx_dvfs {
> > > >  };
> > > >  
> > > >  static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
> > > > -	{.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} },
> > > > +	/*
> > > > +	 * The cpufreq scaling for 1.2 GHz variant of the SOC is currently
> > > > +	 * unstable because we do not know how to configure it properly.
> > > > +	 */
> > > > +	/* {.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} }, */
> > > >  	{.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} },
> > > >  	{.cpu_freq_max = 800*1000*1000,  .divider = {1, 2, 3, 4} },
> > > >  	{.cpu_freq_max = 600*1000*1000,  .divider = {2, 4, 5, 6} },
> > > > -- 
> > > > 2.31.1
> > > > 


From Jason at zx2c4.com  Sun Aug  8 13:22:42 2021
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Sun, 8 Aug 2021 22:22:42 +0200
Subject: [PATCH 6/6 v2] wireguard: main: rename 'mod_init' & 'mod_exit'
 functions to be module-specific
In-Reply-To: <20210711223148.5250-7-rdunlap@infradead.org>
References: <20210711223148.5250-1-rdunlap@infradead.org>
 <20210711223148.5250-7-rdunlap@infradead.org>
Message-ID: <CAHmME9pqLEmNKu1gZDsvTbukzqv8O2kCp6ndQROTu9RzcPnrVA@mail.gmail.com>

Hi Randy,

Thanks, I've applied this to the wireguard stable tree, and it'll be
sent off to netdev during the next push there.

Regards,
Jason


From martin.blumenstingl at googlemail.com  Sun Aug  8 13:36:55 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 8 Aug 2021 22:36:55 +0200
Subject: [PATCH v3 2/2] remoteproc: meson-mx-ao-arc: Add a driver for the
 AO ARC remote procesor
In-Reply-To: <20210805161506.GA3205691@p14s>
References: <20210717234859.351911-1-martin.blumenstingl@googlemail.com>
 <20210717234859.351911-3-martin.blumenstingl@googlemail.com>
 <20210728175823.GA2766167@p14s>
 <CAFBinCB0-bAa7Y+YhscczarGrGuio37F8vRyfW6U2DiiDAvr-g@mail.gmail.com>
 <20210805161506.GA3205691@p14s>
Message-ID: <CAFBinCCkOgkzuxZPby-rJeH7ei-G_khiStkX9Zs3w1u1RAd7_Q@mail.gmail.com>

Hi Mathieu,

On Thu, Aug 5, 2021 at 6:15 PM Mathieu Poirier
<mathieu.poirier at linaro.org> wrote:
>
> On Wed, Aug 04, 2021 at 11:03:57PM +0200, Martin Blumenstingl wrote:
> > Hi Mathieu,
> >
> > thanks for taking the time to look into this!
> >
> > (I will address any of your comments that I am not mentioning in this
> > email anymore. Thanks a lot for the suggestions!)
> >
> > On Wed, Jul 28, 2021 at 7:58 PM Mathieu Poirier
> > <mathieu.poirier at linaro.org> wrote:
> > [...]
> > > > +     writel(FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
> > > > +                            priv->sram_pa >> 14),
> > > Indentation problem
> > The idea here is to align priv->sram_pa with AO_REMAP_REG0... which
> > are both arguments to FIELD_PREP
>
> Right, this is what I would have expected.  When I applied the patch on my side
> "priv->sram_pa ..." was aligned wiht the 'M' of "AO_REMAP_ ...".
>
> > Maybe using something like this will make that easier to read:
> >     tmp = FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
> >                                      priv->sram_pa >> 14);
> >     writel(tmp, priv->remap_base + AO_REMAP_REG0);
>
> I think the main problem is that
> AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU is simply too long.  I
> suggest making is shorter and add a comment to describe exactly what it does.
AO_CPU_CNTL_AHB_SRAM_BITS_31_20 is used below and when looking at it
now I think the alignment is also strange.
For the next version I'll go with the tmp variable as I think it
improves readability, even with the long(er) macro names.

[...]
> > > > +     priv->arc_reset = devm_reset_control_get_exclusive(dev, NULL);
> > > > +     if (IS_ERR(priv->arc_reset)) {
> > >
> > > Function __reset_control_get() in __devm_reset_control_get() can return NULL so
> > > this should be IS_ERR_OR_NULL().
> > The logic in there is: return optional ? NULL : ERR_PTR(-...);
>
> Ok, so you meant to do that.  And I just checked reset_control_reset() and it does
> account for a NULL parameter.  I'm good with this one but add a comment to
> make sure future readers don't think you've omitted to properly deal with the
> NULL return value.
>
> > I am requesting a mandatory reset line here, so reset core will never
> > return NULL
> > See also [0]
>
> Indeed, I've read that too.  Nonetheless __reset_control_get() can return NULL
> by way of __reset_control_get_from_lookup().
I could not find where __reset_control_get_from_lookup returns NULL in
case optional is false (which it is in this case because
devm_reset_control_get_exclusive requests a "mandatory" reset line).
Can you please point me to the problematic line(s) as I'd like to send
a patch (which fixes this) to the reset subsystem maintainers

$ git grep -A1 devm_reset_control_get_exclusive | grep IS_ERR_OR_NULL
drivers/remoteproc/ti_k3_r5_remoteproc.c-       if
(IS_ERR_OR_NULL(core->reset)) {
$

I suspect that this can be simplified then as well.


Best regards,
Martin


[0] https://elixir.bootlin.com/linux/v5.14-rc4/source/include/linux/reset.h#L227
[1] https://elixir.bootlin.com/linux/v5.14-rc4/source/drivers/reset/core.c#L932


From s.shtylyov at omp.ru  Sun Aug  8 13:37:38 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Sun, 8 Aug 2021 23:37:38 +0300
Subject: [PATCH 1/9] usb: dwc3: meson-g12a: add IRQ check
In-Reply-To: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
References: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
Message-ID: <f8eae1ec-91c7-e26e-665d-777930b001a9@omp.ru>

The driver neglects to check the result of platform_get_irq()'s call and
blithely passes the negative error codes to devm_request_threaded_irq()
(which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding
an original error code. Stop calling devm_request_threaded_irq() with the
invalid IRQ #s.

Fixes: f90db10779ad ("usb: dwc3: meson-g12a: Add support for IRQ based OTG switching")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

---
 drivers/usb/dwc3/dwc3-meson-g12a.c |    2 ++
 1 file changed, 2 insertions(+)

Index: usb/drivers/usb/dwc3/dwc3-meson-g12a.c
===================================================================
--- usb.orig/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ usb/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -598,6 +598,8 @@ static int dwc3_meson_g12a_otg_init(stru
 				   USB_R5_ID_DIG_IRQ, 0);
 
 		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return irq;
 		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 						dwc3_meson_g12a_irq_thread,
 						IRQF_ONESHOT, pdev->name, priv);


From s.shtylyov at omp.ru  Sun Aug  8 13:45:01 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Sun, 8 Aug 2021 23:45:01 +0300
Subject: [PATCH 3/9] usb: gadget: udc: at91: add IRQ check
In-Reply-To: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
References: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
Message-ID: <3ebcf6ee-4ca7-d7dc-6e04-62bc4f9e1ead@omp.ru>

The driver neglects to check the result of platform_get_irq()'s call and
blithely passes the negative error codes to devm_request_irq() (which takes
*unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
error code. Stop calling devm_request_irq() with the invalid IRQ #s.

Fixes: 8b2e76687b39 ("USB: AT91 UDC updates, mostly power management")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

---
 drivers/usb/gadget/udc/at91_udc.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: usb/drivers/usb/gadget/udc/at91_udc.c
===================================================================
--- usb.orig/drivers/usb/gadget/udc/at91_udc.c
+++ usb/drivers/usb/gadget/udc/at91_udc.c
@@ -1876,7 +1876,9 @@ static int at91udc_probe(struct platform
 	clk_disable(udc->iclk);
 
 	/* request UDC and maybe VBUS irqs */
-	udc->udp_irq = platform_get_irq(pdev, 0);
+	udc->udp_irq = retval = platform_get_irq(pdev, 0);
+	if (retval < 0)
+		goto err_unprepare_iclk;
 	retval = devm_request_irq(dev, udc->udp_irq, at91_udc_irq, 0,
 				  driver_name, udc);
 	if (retval) {


From martin.blumenstingl at googlemail.com  Sun Aug  8 13:50:10 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 8 Aug 2021 22:50:10 +0200
Subject: [PATCH 1/9] usb: dwc3: meson-g12a: add IRQ check
In-Reply-To: <f8eae1ec-91c7-e26e-665d-777930b001a9@omp.ru>
References: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
 <f8eae1ec-91c7-e26e-665d-777930b001a9@omp.ru>
Message-ID: <CAFBinCBKk_2Pk+8Uztx3yN8HSxiDcCW6VTF5duX3SuX+B8bzjw@mail.gmail.com>

Hi Sergey,

On Sun, Aug 8, 2021 at 10:37 PM Sergey Shtylyov <s.shtylyov at omp.ru> wrote:
>
> The driver neglects to check the result of platform_get_irq()'s call and
> blithely passes the negative error codes to devm_request_threaded_irq()
> (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding
> an original error code. Stop calling devm_request_threaded_irq() with the
> invalid IRQ #s.
>
> Fixes: f90db10779ad ("usb: dwc3: meson-g12a: Add support for IRQ based OTG switching")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>
Thanks for spotting and fixing this issue!
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From s.shtylyov at omp.ru  Sun Aug  8 13:57:29 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Sun, 8 Aug 2021 23:57:29 +0300
Subject: [PATCH 4/9] usb: gadget: udc: s3c2410: add IRQ check
In-Reply-To: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
References: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
Message-ID: <f704a632-a970-fe8d-35e7-f4d032c670c7@omp.ru>

The driver neglects to check the result of platform_get_irq()'s call and
blithely passes the negative error codes to devm_request_irq() (which takes
*unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
error code. Stop calling devm_request_irq() with the invalid IRQ #s.

Fixes: 8b2e76687b39 ("USB: AT91 UDC updates, mostly power management")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

---
 drivers/usb/gadget/udc/at91_udc.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: usb/drivers/usb/gadget/udc/at91_udc.c
===================================================================
--- usb.orig/drivers/usb/gadget/udc/at91_udc.c
+++ usb/drivers/usb/gadget/udc/at91_udc.c
@@ -1876,7 +1876,9 @@ static int at91udc_probe(struct platform
 	clk_disable(udc->iclk);
 
 	/* request UDC and maybe VBUS irqs */
-	udc->udp_irq = platform_get_irq(pdev, 0);
+	udc->udp_irq = retval = platform_get_irq(pdev, 0);
+	if (retval < 0)
+		goto err_unprepare_iclk;
 	retval = devm_request_irq(dev, udc->udp_irq, at91_udc_irq, 0,
 				  driver_name, udc);
 	if (retval) {


From s.shtylyov at omp.ru  Sun Aug  8 14:01:21 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Mon, 9 Aug 2021 00:01:21 +0300
Subject: [PATCH 4/9] usb: gadget: udc: s3c2410: add IRQ check
In-Reply-To: <f704a632-a970-fe8d-35e7-f4d032c670c7@omp.ru>
References: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
 <f704a632-a970-fe8d-35e7-f4d032c670c7@omp.ru>
Message-ID: <7ba95c65-416c-2b55-b004-bf87b91288d7@omp.ru>

Oops, duplicate patch. Scratch the series, I'm going to restart posting tomorrow... :-)


From sebastian.reichel at collabora.com  Sun Aug  8 16:47:38 2021
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 9 Aug 2021 01:47:38 +0200
Subject: [RFC v2 3/4] power: supply: Add charger driver for Rockchip RK817
In-Reply-To: <20210726190130.1973-4-macroalpha82@gmail.com>
References: <20210726190130.1973-1-macroalpha82@gmail.com>
 <20210726190130.1973-4-macroalpha82@gmail.com>
Message-ID: <20210808234738.s76kgcswcff6xe4l@earth.universe>

Hi,

On Mon, Jul 26, 2021 at 02:01:29PM -0500, Chris Morgan wrote:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Add support for the Rockchip rk817 battery charger integrated into the
> rk817 PMIC.
> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
> ---
>  drivers/power/supply/Kconfig         |   6 +
>  drivers/power/supply/Makefile        |   1 +
>  drivers/power/supply/rk817_charger.c | 932 +++++++++++++++++++++++++++
>  3 files changed, 939 insertions(+)
>  create mode 100644 drivers/power/supply/rk817_charger.c
> 
> diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> index 11f5368e810e..311130da36ff 100644
> --- a/drivers/power/supply/Kconfig
> +++ b/drivers/power/supply/Kconfig
> @@ -666,6 +666,12 @@ config CHARGER_BQ256XX
>  	  charge management and system power path management devices for single
>  	  cell Li-ion and Li-polymer batteries.
>  
> +config CHARGER_RK817
> +	tristate "Rockchip RK817 PMIC Battery Charger"
> +	depends on MFD_RK808
> +	help
> +	  Say Y to include support for Rockchip RK817 Battery Charger.
> +
>  config CHARGER_SMB347
>  	tristate "Summit Microelectronics SMB3XX Battery Charger"
>  	depends on I2C
> diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
> index 33059a91f60c..9497d2105712 100644
> --- a/drivers/power/supply/Makefile
> +++ b/drivers/power/supply/Makefile
> @@ -87,6 +87,7 @@ obj-$(CONFIG_CHARGER_BQ2515X)	+= bq2515x_charger.o
>  obj-$(CONFIG_CHARGER_BQ25890)	+= bq25890_charger.o
>  obj-$(CONFIG_CHARGER_BQ25980)	+= bq25980_charger.o
>  obj-$(CONFIG_CHARGER_BQ256XX)	+= bq256xx_charger.o
> +obj-$(CONFIG_CHARGER_RK817)	+= rk817_charger.o
>  obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
>  obj-$(CONFIG_CHARGER_TPS65090)	+= tps65090-charger.o
>  obj-$(CONFIG_CHARGER_TPS65217)	+= tps65217_charger.o
> diff --git a/drivers/power/supply/rk817_charger.c b/drivers/power/supply/rk817_charger.c
> new file mode 100644
> index 000000000000..0861bd428756
> --- /dev/null
> +++ b/drivers/power/supply/rk817_charger.c
> @@ -0,0 +1,932 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Charger Driver for Rockchip rk817
> + *
> + * Copyright (c) 2021
> + *
> + * Authors: Maya Matuszczyk <maccraft123mc at gmail.com>
> + *	    Chris Morgan <macromorgan at hotmail.com>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/extcon.h>
> +#include <linux/fb.h>
> +#include <linux/gpio.h>
> +#include <linux/iio/consumer.h>
> +#include <linux/iio/iio.h>
> +#include <linux/irq.h>
> +#include <linux/jiffies.h>
> +#include <linux/mfd/rk808.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_gpio.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/rtc.h>
> +#include <linux/timer.h>
> +#include <linux/workqueue.h>
> +#include <linux/power_supply.h>

how the heck did you come up with those includes? You are neither
using extcon, framebuffer, gpio, iio, rtc, workqueue, nor timers.

> +/* Charging statuses reported by hardware register */
> +enum rk817_charge_status {
> +	CHRG_OFF,
> +	DEAD_CHRG,
> +	TRICKLE_CHRG,
> +	CC_OR_CV_CHRG,
> +	CHARGE_FINISH,
> +	USB_OVER_VOL,
> +	BAT_TMP_ERR,
> +	BAT_TIM_ERR,
> +};
> +
> +/* Max charging current read to/written from hardware register.
> + * Note how highest value corresponding to 0x7 is the lowest
> + * current, this is per the datasheet.
> + */
> +enum rk817_chg_cur {
> +	CHG_1A,
> +	CHG_1_5A,
> +	CHG_2A,
> +	CHG_2_5A,
> +	CHG_2_75A,
> +	CHG_3A,
> +	CHG_3_5A,
> +	CHG_0_5A,
> +};
> +
> +struct rk817_charger {
> +	struct device *dev;
> +	struct rk808 *rk808;
> +
> +	struct power_supply *bat_ps;
> +	struct power_supply_battery_info bat_info;
> +
> +	struct power_supply *chg_ps;
> +	bool plugged_in;
> +
> +	uint32_t voltage_k;
> +	uint32_t voltage_b;

what's voltage_k and voltage_b?

> +
> +	/* dsoc seems to be difference between full charge and actual charge in
> +	 * BSP stored as a percentage, to the thousandth.
> +	 */
> +	int dsoc;
> +
> +	/* Implementation specific properties from device tree */
> +	int res_div;
> +	int sleep_enter_current;
> +	int sleep_filter_current;
> +};
> +
> +/* ADC coefficients extracted from BSP kernel */
> +#define ADC_TO_CURRENT(adc_value, res_div)	\
> +	(adc_value * 172 / res_div)
> +
> +#define CURRENT_TO_ADC(current, samp_res)	\
> +	(current * samp_res / 172)
> +
> +#define CHARGE_TO_ADC(capacity, res_div)	\
> +	(capacity * res_div * 3600 / 172 * 1000)
> +
> +#define ADC_TO_CHARGE_UAH(adc_value, res_div)	\
> +	(adc_value / 3600 * 172 / res_div)
> +
> +#define ADC_TO_CAPACITY(adc_value, res_div)	\
> +	(adc_value / 1000 * 172 / 3600 / res_div)
> +
> +static u8 rk817_chg_cur_to_reg(u32 chg_cur_ma)
> +{
> +	if (chg_cur_ma < 500)
> +		return -EINVAL;
> +	else if (chg_cur_ma < 1000)
> +		return CHG_0_5A;
> +	else if (chg_cur_ma < 1500)
> +		return CHG_1A;
> +	else if (chg_cur_ma < 2000)
> +		return CHG_1_5A;
> +	else if (chg_cur_ma < 2500)
> +		return CHG_2A;
> +	else if (chg_cur_ma < 2750)
> +		return CHG_2_5A;
> +	else if (chg_cur_ma < 3000)
> +		return CHG_2_75A;
> +	else if (chg_cur_ma < 3500)
> +		return CHG_3A;
> +	else
> +		return CHG_3_5A;
> +}

if you change the order this becomes more readable:

if (chg_cur_ma > 3500)
    return CHG_3_5A;
else if (chg_cur_ma > 3000)
    return CHG_3A;
...
else if (chg_cur_ma > 500)
    return CHG_0_5A;
else
    return -EINVAL;

> +static int rk817_chg_cur_from_reg(u8 reg)
> +{
> +	switch (reg) {
> +	case CHG_0_5A:
> +		return 500000;
> +	case CHG_1A:
> +		return 1000000;
> +	case CHG_1_5A:
> +		return 1500000;
> +	case CHG_2A:
> +		return 2000000;
> +	case CHG_2_5A:
> +		return 2500000;
> +	case CHG_2_75A:
> +		return 2750000;
> +	case CHG_3A:
> +		return 3000000;
> +	case CHG_3_5A:
> +		return 3500000;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int rk817_get_reg_hl(struct rk817_charger *charger, int regH, int regL)
> +{
> +	int tmp, ret;
> +	uint32_t out;
> +	struct rk808 *rk808 = charger->rk808;
> +
> +	ret = regmap_read(rk808->regmap, regL, &tmp);
> +	if (ret)
> +		return ret;
> +	out = tmp;
> +
> +	ret = regmap_read(rk808->regmap, regH, &tmp);
> +	if (ret)
> +		return ret;
> +	out |= tmp << 8;
> +
> +	return out;
> +}
> +
> +static void rk817_write_reg_hl(struct rk817_charger *charger, int regH,
> +			       int regL, int val)
> +{
> +	uint8_t tmp;
> +	struct rk808 *rk808 = charger->rk808;
> +
> +	tmp = val & 0xff;
> +	regmap_write(rk808->regmap, regL, tmp);
> +	tmp = (val >> 8) & 0xff;
> +	regmap_write(rk808->regmap, regH, tmp);
> +}
> +
> +static void rk817_bat_calib_vol(struct rk817_charger *charger)
> +{
> +	uint32_t vcalib0 = 0;
> +	uint32_t vcalib1 = 0;
> +
> +	/* calibrate voltage */
> +	vcalib0 = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_VCALIB0_H,
> +				   RK817_GAS_GAUGE_VCALIB0_L);
> +	vcalib1 = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_VCALIB1_H,
> +				   RK817_GAS_GAUGE_VCALIB1_L);
> +
> +	/* values were taken from BSP kernel */
> +	charger->voltage_k = (4025 - 2300) * 1000 /
> +			     ((vcalib1 - vcalib0) ? (vcalib1 - vcalib0) : 1);
> +	charger->voltage_b = 4025 - (charger->voltage_k * vcalib1) / 1000;
> +}
> +
> +static void rk817_bat_calib_cur(struct rk817_charger *charger)
> +{
> +	int ioffset = 0;
> +	/* calibrate current */
> +	ioffset = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_IOFFSET_H,
> +				   RK817_GAS_GAUGE_IOFFSET_L);
> +	rk817_write_reg_hl(charger, RK817_GAS_GAUGE_CAL_OFFSET_H,
> +			   RK817_GAS_GAUGE_CAL_OFFSET_L, ioffset);
> +}
> +
> +static int rk817_bat_calib_cap(struct rk817_charger *charger)
> +{
> +	struct rk808 *rk808 = charger->rk808;
> +	struct power_supply_battery_info *info = &charger->bat_info;
> +	int reg, tmp, charge_now, charge_now_adc, dsoc_value;
> +	u8 bulk_reg[4];
> +
> +	/* Calibrate the capacity on a fully charged battery */
> +
> +	regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
> +	tmp = (reg >> 4) & 0x07;
> +	if (tmp == CHARGE_FINISH) {
> +		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
> +				 bulk_reg, 4);
> +		charge_now_adc = (bulk_reg[0] << 24) | (bulk_reg[1] << 16) |
> +				 (bulk_reg[2] << 8) | bulk_reg[3];

charge_now_adc = get_unaligned_be32(bulk_reg);

> +		if (charge_now_adc < 0)
> +			charge_now_adc = 0;
> +		charge_now = ADC_TO_CHARGE_UAH(charge_now_adc, charger->res_div);
> +		dsoc_value = ((charge_now * 100) /
> +			      (info->charge_full_design_uah / 1000));
> +		if (dsoc_value > 100000)
> +			charger->dsoc = 100000;
> +		if (dsoc_value != charger->dsoc) {
> +			charger->dsoc = dsoc_value;
> +			bulk_reg[2] = (dsoc_value >> 16) & 0xff;
> +			bulk_reg[1] = (dsoc_value >> 8) & 0xff;
> +			bulk_reg[0] = dsoc_value & 0xff;

put_unaligned_le24(dsoc_value, bulk_reg);

> +			regmap_bulk_write(rk808->regmap,
> +					  RK817_GAS_GAUGE_BAT_R1, bulk_reg, 3);
> +		}
> +	}
> +
> +	return 0;
> +
> +}

extra newline at end of function.

> +
> +static int rk817_bat_get_prop(struct power_supply *ps,
> +		enum power_supply_property prop,
> +		union power_supply_propval *val)
> +{
> +	struct rk817_charger *charger = power_supply_get_drvdata(ps);
> +	uint32_t tmp = 0;
> +	/* Registers for current is a signed 16bit int */
> +	short int cur = 0;
> +	/* Registers for capacity-now is a signed 32bit int */
> +	int32_t charge_now = 0;
> +	int ret = 0;
> +	int reg = 0;
> +	u8 bulk_reg[4];
> +	struct rk808 *rk808 = charger->rk808;
> +
> +	/* Recalibrate voltage and current readings if we need to BSP does both
> +	 * on CUR_CALIB_UPD, ignoring VOL_CALIB_UPD. Curiously enough, both
> +	 * documentation and the BSP show that you perform an update if bit 7
> +	 * is 1, but you clear the status by writing a 1 to bit 7.
> +	 */
> +	regmap_read(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1, &reg);
> +	tmp = (reg >> 7) & 0x01;
> +	if (tmp) {
> +		rk817_bat_calib_cur(charger);
> +		rk817_bat_calib_vol(charger);
> +		regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1,
> +				   RK817_CUR_CALIB_UPD, (1 << 7));
> +	}
> +
> +	rk817_bat_calib_cap(charger);
> +
> +	switch (prop) {
> +	case POWER_SUPPLY_PROP_PRESENT:
> +		regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
> +		val->intval = (reg >> 7);
> +		break;
> +	case POWER_SUPPLY_PROP_STATUS:
> +		if (!charger->plugged_in) {
> +			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> +			break;
> +		}
> +		ret = regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
> +		if (ret)
> +			return ret;
> +		tmp = (reg >> 4) & 0x07;
> +		switch (tmp) {
> +		case CHRG_OFF:
> +			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
> +			break;
> +		/* Dead charge is documented, but not explained. I never
> +		 * observed it but assume it's a pre-charge for a dead
> +		 * battery.
> +		 */
> +		case DEAD_CHRG:
> +		case TRICKLE_CHRG:
> +		case CC_OR_CV_CHRG:
> +			val->intval = POWER_SUPPLY_STATUS_CHARGING;
> +			break;
> +		case CHARGE_FINISH:
> +			val->intval = POWER_SUPPLY_STATUS_FULL;
> +			break;
> +		default:
> +			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
> +			return -EINVAL;
> +
> +		}
> +		break;
> +	case POWER_SUPPLY_PROP_CHARGE_TYPE:
> +		ret = regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
> +		if (ret)
> +			return ret;
> +		tmp = (reg >> 4) & 0x07;
> +		switch (tmp) {
> +		case CHRG_OFF:
> +		case CHARGE_FINISH:
> +			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
> +			break;
> +		case TRICKLE_CHRG:
> +			val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
> +			break;
> +		case DEAD_CHRG:
> +		case CC_OR_CV_CHRG:
> +			val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
> +			break;
> +		default:
> +			val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
> +			break;
> +		}
> +		break;
> +	case POWER_SUPPLY_PROP_CHARGE_FULL:
> +		val->intval = ((charger->bat_info.charge_full_design_uah /
> +			       1000) * charger->dsoc) / 100;
> +		break;
> +	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
> +		val->intval = charger->bat_info.charge_full_design_uah;
> +		break;
> +	case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
> +		val->intval = 0;
> +		break;
> +	case POWER_SUPPLY_PROP_CHARGE_NOW:
> +		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
> +				 bulk_reg, 4);
> +		charge_now = (bulk_reg[0] << 24) | (bulk_reg[1] << 16) |
> +			     (bulk_reg[2] << 8) | bulk_reg[3];

charge_now = get_unaligned_be32(bulk_reg);

> +		if (charge_now < 0)
> +			charge_now = 0;
> +		val->intval = ADC_TO_CHARGE_UAH(charge_now, charger->res_div);
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> +		val->intval = charger->bat_info.voltage_min_design_uv;
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_BOOT:
> +		tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_PWRON_VOL_H,
> +				       RK817_GAS_GAUGE_PWRON_VOL_L);
> +		val->intval = (1000 * (((charger->voltage_k * tmp) / 1000) +
> +			       charger->voltage_b));

can be simplified to:

(charger->voltage_k * tmp) + 1000 * charger->voltage_b

> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
> +		tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_BAT_VOL_H,
> +				       RK817_GAS_GAUGE_BAT_VOL_L);
> +		val->intval = (1000 * (((charger->voltage_k * tmp) / 1000) +
> +			       charger->voltage_b));

same

> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_OCV:
> +		tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_OCV_VOL_H,
> +				       RK817_GAS_GAUGE_OCV_VOL_H);
> +		val->intval = (1000 * (((charger->voltage_k * tmp) / 1000) +
> +			       charger->voltage_b));

same

> +		break;
> +	case POWER_SUPPLY_PROP_CURRENT_BOOT:
> +		cur = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_PWRON_CUR_H,
> +				       RK817_GAS_GAUGE_PWRON_CUR_H);
> +		val->intval = ADC_TO_CURRENT(cur, charger->res_div);
> +		break;
> +	case POWER_SUPPLY_PROP_CURRENT_AVG:
> +		cur = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_BAT_CUR_H,
> +				       RK817_GAS_GAUGE_BAT_CUR_L);
> +		val->intval = ADC_TO_CURRENT(cur, charger->res_div);
> +		break;
> +	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
> +		regmap_read(rk808->regmap, RK817_PMIC_CHRG_OUT, &tmp);
> +		val->intval = rk817_chg_cur_from_reg(tmp & RK817_CHRG_CUR_SEL);
> +		break;
> +	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
> +		regmap_read(rk808->regmap, RK817_PMIC_CHRG_OUT, &tmp);
> +		val->intval = ((((tmp & RK817_CHRG_VOL_SEL) >> 4) * 50000) +
> +			       4100000);
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
> +		val->intval = charger->bat_info.voltage_max_design_uv;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	return 0;
> +}
> +
> +static int rk817_chg_get_prop(struct power_supply *ps,
> +			      enum power_supply_property prop,
> +			      union power_supply_propval *val)
> +{
> +	struct rk817_charger *charger = power_supply_get_drvdata(ps);
> +	int vol, tmp = 0;
> +
> +	switch (prop) {
> +	case POWER_SUPPLY_PROP_ONLINE:
> +		val->intval = charger->plugged_in;
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
> +		/* max voltage from datasheet at 5.5v (default 5.0v) */
> +		val->intval = 5500000;
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> +		/* min voltage from datasheet at 3.8v (default 5.0v) */
> +		val->intval = 3800000;
> +		break;
> +	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
> +		/* Note that on my example hardware (an Odroid Go Advance) the
> +		 * voltage of the power connector is measured on the register
> +		 * labelled USB in the datasheet; I don't know if this is how
> +		 * it is designed or just a quirk of the implementation. I
> +		 * believe this will also measure the voltage of the USB output
> +		 * when in OTG mode, if that is the case we may need to change
> +		 * this in the future to return 0 if the power supply status
> +		 * is offline.
> +		 */
> +		tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_USB_VOL_H,
> +				       RK817_GAS_GAUGE_USB_VOL_L);
> +		vol = ((charger->voltage_k * tmp / 1000 + charger->voltage_b) *
> +		       60 / 46);
> +		val->intval = vol * 1000;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +	return 0;
> +
> +}
> +
> +static irqreturn_t rk817_plug_in_isr(int irq, void *cg)
> +{
> +	struct rk817_charger *charger;
> +
> +	charger = (struct rk817_charger *)cg;
> +	charger->plugged_in = 1;
> +	power_supply_changed(charger->chg_ps);
> +	power_supply_changed(charger->bat_ps);
> +	dev_dbg(charger->dev, "Power Cord Inserted\n");
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t rk817_plug_out_isr(int irq, void *cg)
> +{
> +	struct rk817_charger *charger;
> +	struct rk808 *rk808;
> +
> +	charger = (struct rk817_charger *)cg;
> +	rk808 = charger->rk808;
> +	charger->plugged_in = 0;
> +	power_supply_changed(charger->bat_ps);
> +	power_supply_changed(charger->chg_ps);
> +
> +	/* For some reason the bits of RK817_PMIC_CHRG_IN reset whenever the
> +	 * power cord is unplugged. This was not documented in the BSP kernel
> +	 * or the datasheet and only discovered by trial and error. Set minimum
> +	 * USB input voltage to 4.5v and enable USB voltage input limit.
> +	 */
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
> +			  RK817_USB_VLIM_SEL, (0x05 << 4));
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN,
> +			  (0x01 << 7));
> +
> +	/* Set average USB input current limit to 1.5A and enable USB current
> +	 * input limit.
> +	 */
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
> +			  RK817_USB_ILIM_SEL, 0x03);
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN,
> +			  (0x01 << 3));
> +
> +	dev_dbg(charger->dev, "Power Cord Removed\n");
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static enum power_supply_property rk817_bat_props[] = {
> +	POWER_SUPPLY_PROP_PRESENT,
> +	POWER_SUPPLY_PROP_STATUS,
> +	POWER_SUPPLY_PROP_CHARGE_TYPE,
> +	POWER_SUPPLY_PROP_CHARGE_FULL,
> +	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
> +	POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
> +	POWER_SUPPLY_PROP_CHARGE_NOW,
> +	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
> +	POWER_SUPPLY_PROP_VOLTAGE_BOOT,
> +	POWER_SUPPLY_PROP_VOLTAGE_AVG,
> +	POWER_SUPPLY_PROP_VOLTAGE_OCV,
> +	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
> +	POWER_SUPPLY_PROP_CURRENT_BOOT,
> +	POWER_SUPPLY_PROP_CURRENT_AVG,
> +	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
> +	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
> +};
> +
> +static enum power_supply_property rk817_chg_props[] = {
> +	POWER_SUPPLY_PROP_ONLINE,
> +	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
> +	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
> +	POWER_SUPPLY_PROP_VOLTAGE_AVG,
> +};
> +
> +static const struct power_supply_desc rk817_bat_desc = {
> +	.name = "rk817-battery",
> +	.type = POWER_SUPPLY_TYPE_BATTERY,
> +	.properties = rk817_bat_props,
> +	.num_properties = ARRAY_SIZE(rk817_bat_props),
> +	.get_property = rk817_bat_get_prop,
> +};
> +
> +/* Note that all known existing implementations use a "USB" port that is either
> + * a power only port (no data lines) or use barrel plug to USB cable. Setting
> + * to POWER_SUPPLY_TYPE_USB_DCP.
> + */
> +static const struct power_supply_desc rk817_chg_desc = {
> +	.name = "rk817-charger",
> +	.type = POWER_SUPPLY_TYPE_USB_DCP,

Please don't use that, it only exists for historical purposes.
Set type to POWER_SUPPLY_TYPE_USB and report 
POWER_SUPPLY_USB_TYPE_DCP via the USB_TYPE property.

> +	.properties = rk817_chg_props,
> +	.num_properties = ARRAY_SIZE(rk817_chg_props),
> +	.get_property = rk817_chg_get_prop,
> +};
> +
> +static int rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger)
> +{
> +	struct rk808 *rk808 = charger->rk808;
> +	struct power_supply_battery_info *info = &charger->bat_info;
> +	u8 reg[4];
> +	u32 design_charge_mah = (info->charge_full_design_uah / 1000);
> +	u32 boot_voltage, boot_charge, tmp, full_charge_cap;
> +	int ret, boot_capacity;
> +
> +	/* Read DSOC value if pre-existing. If not, initialize at 100%.
> +	 * Note endianness, also register says it's for resistance,
> +	 * however BSP kernel treats this as an nvram field for the DSOC
> +	 * as best I can tell. Doing the same for backwards compatibility.
> +	 */
> +	ret = regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_BAT_R1, reg, 3);
> +	if (ret < 0)
> +		return ret;
> +
> +	charger->dsoc = (reg[2] << 16) | (reg[1] << 8) | (reg[0]);

charger->dsoc = get_unaligned_le24(reg);

> +	/* If we have an invalid DSOC, write 100 (100000) as default. */
> +	if (charger->dsoc < 1000 || charger->dsoc > 100000) {
> +		regmap_write(rk808->regmap, RK817_GAS_GAUGE_BAT_R1, 0xa0);
> +		regmap_write(rk808->regmap, RK817_GAS_GAUGE_BAT_R2, 0x86);
> +		regmap_write(rk808->regmap, RK817_GAS_GAUGE_BAT_R3, 0x01);
> +		charger->dsoc = 100000;
> +	}
> +
> +	/* Register appears to be nvram that stores capacity in mAH. Note
> +	 * endianness, keeping consistent with BSP kernel, however it looks
> +	 * like we can use any arbitrary method to store value if we don't care
> +	 * about compatibility. Additionally, it doesn't appear that this value
> +	 * is used for anything, so realistically getting it and setting it is
> +	 * to ensure backward compatibility with BSP and serves no purpose with
> +	 * this driver, and I'm not sure if the BSP driver does anything with
> +	 * this value either.
> +	 */
> +
> +	ret = regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_DATA3, reg, 3);
> +	if (ret < 0)
> +		return ret;
> +
> +	full_charge_cap = (reg[2] << 16) | (reg[1] << 8) | (reg[0]);

full_charge_cap = get_unaligned_le24(reg);

> +
> +	/* Sanity checking for values equal to zero or less than would be
> +	 * practical for this device (BSP Kernel assumes 500mAH or less) for
> +	 * practicality purposes.
> +	 */
> +	if (full_charge_cap < 500) {
> +		reg[2] = (design_charge_mah >> 16) & 0xff;
> +		reg[1] = (design_charge_mah >> 8) & 0xff;
> +		reg[0] = design_charge_mah & 0xff;
> +		ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_DATA3, reg, 3);
> +		if (ret < 0)
> +			return ret;
> +		dev_info(charger->dev,
> +			 "Invalid NVRAM Data for max charge, setting to design capacity %u uAH\n",
> +			 design_charge_mah*1000);
> +	}
> +
> +	/* Capture boot voltage and look up boot capacity from OCV tables. */
> +
> +	tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_PWRON_VOL_H,
> +			       RK817_GAS_GAUGE_PWRON_VOL_L);
> +	boot_voltage = (1000 * (((charger->voltage_k * tmp) / 1000) +
> +			charger->voltage_b));
> +	/* Since only implementation has no working thermistor, assume 20C for
> +	 * OCV lookup. If lookup fails, report error with OCV table.
> +	 */
> +	boot_capacity = power_supply_batinfo_ocv2cap(info, boot_voltage, 20);
> +	if (boot_capacity < 0) {
> +		dev_err(charger->dev,
> +			"Unable to read boot charge from OCV table: %i\n",
> +			boot_capacity);
> +		return boot_capacity;
> +	}
> +
> +	/* Write boot charge to registers, estimate boot charge based on
> +	 * capacity and max charge of battery.
> +	 */
> +	boot_charge = (boot_capacity * info->charge_full_design_uah) / 100;
> +	tmp = CHARGE_TO_ADC((boot_charge / 1000), charger->res_div);
> +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3,
> +		     (tmp >> 24) & 0xFF);
> +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H2,
> +		     (tmp >> 16) & 0xFF);
> +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_L1,
> +		     (tmp >> 8) & 0xFF);
> +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_L0,
> +		     tmp & 0xFF);

regmap_bulk_write?

> +
> +	/* Set QMAX value to max design capacity. */
> +	tmp = CHARGE_TO_ADC((info->charge_full_design_uah / 1000),
> +			    charger->res_div);
> +	reg[0] = (tmp >> 24) & 0xff;
> +	reg[1] = (tmp >> 16) & 0xff;
> +	reg[2] = (tmp >> 8) & 0xff;
> +	reg[3] = tmp & 0xff;

use put_unaligned_* API

> +	ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_MAX_H3,
> +				reg, 4);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +
> +}
> +
> +static int rk817_battery_init(struct rk817_charger *charger)
> +{
> +	struct rk808 *rk808 = charger->rk808;
> +	struct power_supply_battery_info *info = &charger->bat_info;
> +	u32 tmp, max_chg_vol_mv, max_chg_cur_ma;
> +	u8 max_chg_vol_reg, chg_term_i_reg, max_chg_cur_reg;
> +	int ret, chg_term_ma;
> +
> +	/* Get initial plug state */
> +	regmap_read(rk808->regmap, RK817_SYS_STS, &tmp);
> +	charger->plugged_in = (tmp & RK817_PLUG_IN_STS);
> +
> +	/* Turn on all ADC functions to measure battery, USB, and sys voltage,
> +	 * as well as batt temp. Note only tested implementation so far does
> +	 * not use a battery with a thermistor.
> +	 */
> +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG0, 0xfc);
> +
> +	/* Set relax mode voltage sampling interval and ADC offset calibration
> +	 * interval to 8 minutes to mirror BSP kernel. Set voltage and current
> +	 * modes to average to mirror BSP kernel.
> +	 */
> +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_GG_CON, 0x04);
> +
> +	/* Write relax threshold, derived from sleep enter current. */
> +	tmp = CURRENT_TO_ADC(charger->sleep_enter_current, charger->res_div);
> +	rk817_write_reg_hl(charger, RK817_GAS_GAUGE_RELAX_THRE_H,
> +			   RK817_GAS_GAUGE_RELAX_THRE_L, tmp);
> +
> +	/* Write sleep sample current, derived from sleep filter current. */
> +	tmp = CURRENT_TO_ADC(charger->sleep_filter_current, charger->res_div);
> +	rk817_write_reg_hl(charger, RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H,
> +			   RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_L, tmp);
> +
> +	/* Restart battery relax voltage */
> +	regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_GG_STS,
> +			  RK817_RELAX_VOL_UPD, (0x0 << 2));
> +
> +	/* Set OCV Threshold Voltage to 127.5mV. This was hard coded like this
> +	 * in the BSP.
> +	 */
> +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_OCV_THRE_VOL, 0xff);
> +
> +	/* Set maximum charging voltage to battery max voltage. Trying to be
> +	 * incredibly safe with these value, as setting them wrong could
> +	 * overcharge the battery, which would be very bad.
> +	 */
> +	max_chg_vol_mv = info->constant_charge_voltage_max_uv / 1000;
> +	max_chg_cur_ma = info->constant_charge_current_max_ua / 1000;
> +
> +	if (max_chg_vol_mv < 4100) {
> +		dev_emerg(charger->dev,
> +			  "Danger, invalid max charger voltage! Value %u unsupported\n",
> +			  max_chg_vol_mv * 1000);
> +		return -EINVAL;


return dev_err_probe(charger->dev, -EINVAL, "invalid max charger voltage ...",
                     max_chg_vol_mv * 1000);

> +	}
> +	if (max_chg_vol_mv > 4450) {
> +		dev_info(charger->dev,
> +			 "Setting max charge voltage to 4450000uv\n");
> +		max_chg_vol_mv = 4450;
> +	}
> +
> +	if (max_chg_cur_ma < 500) {
> +		dev_emerg(charger->dev,
> +			  "Danger, invalid max charger current! Value %u unsupported\n",
> +			  max_chg_cur_ma * 1000);

return dev_err_probe(...);

> +		return -EINVAL;
> +	}
> +	if (max_chg_cur_ma > 3500)
> +		dev_info(charger->dev,
> +			 "Setting max charge current to 3500000ua\n");
> +
> +	/* Now that the values are sanity checked, if we subtract 4100 from the
> +	 * max voltage and divide by 50, we conviently get the exact value for
> +	 * the registers, which are 4.1v, 4.15v, 4.2v, 4.25v, 4.3v, 4.35v,
> +	 * 4.4v, and 4.45v; these correspond to values 0x00 through 0x07.
> +	 */
> +	max_chg_vol_reg = (max_chg_vol_mv - 4100) / 50;
> +
> +	max_chg_cur_reg = rk817_chg_cur_to_reg(max_chg_cur_ma);
> +
> +	if (max_chg_vol_reg < 0 || max_chg_vol_reg > 7) {
> +		dev_emerg(charger->dev,
> +			  "Danger, invalid max charger voltage! Value %u unsupported\n",
> +			  max_chg_vol_mv * 1000);
> +		return -EINVAL;
> +	}

return dev_err_probe(...);

> +	if (max_chg_cur_reg < 0 || max_chg_cur_reg > 7) {
> +		dev_emerg(charger->dev,
> +			  "Danger, invalid max charger voltage! Value %u unsupported\n",
> +			  max_chg_cur_ma * 1000);
> +		return -EINVAL;
> +	}

return dev_err_probe(...);

> +
> +	/* Write the values to the registers, and deliver an emergency warning
> +	 * in the event they are not written correctly.
> +	 */
> +	ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT,
> +				RK817_CHRG_VOL_SEL, (max_chg_vol_reg << 4));
> +	if (ret) {
> +		dev_emerg(charger->dev,
> +			  "Danger, unable to set max charger voltage: %u\n",
> +			  ret);
> +	}
> +
> +	ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT,
> +				RK817_CHRG_CUR_SEL, max_chg_cur_reg);
> +	if (ret) {
> +		dev_emerg(charger->dev,
> +			  "Danger, unable to set max charger current: %u\n",
> +			  ret);
> +	}
> +
> +	/* Set charge finishing mode to analog */
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM,
> +			  RK817_CHRG_TERM_ANA_DIG, (0x0 << 2));
> +
> +	/* Set charge finish current, warn if value not in range and keep
> +	 * default.
> +	 */
> +	chg_term_ma = info->charge_term_current_ua / 1000;
> +	if (chg_term_ma < 150 || chg_term_ma > 400) {
> +		dev_warn(charger->dev,
> +			 "Invalid charge termination value %u, keeping default\n",
> +			 chg_term_ma * 1000);
> +		chg_term_ma = 200;
> +	}
> +
> +	/* Values of 150ma, 200ma, 300ma, and 400ma correspond to 00, 01, 10,
> +	 * and 11.
> +	 */
> +	chg_term_i_reg = (chg_term_ma - 100) / 100;
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM,
> +			  RK817_CHRG_TERM_ANA_SEL, chg_term_i_reg);
> +
> +	ret = rk817_read_or_set_full_charge_on_boot(charger);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Set minimum USB input voltage to 4.5v and enable USB voltage input
> +	 * limit.
> +	 */
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
> +			  RK817_USB_VLIM_SEL, (0x05 << 4));
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN,
> +			  (0x01 << 7));
> +
> +	/* Set average USB input current limit to 1.5A and enable USB current
> +	 * input limit.
> +	 */
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
> +			  RK817_USB_ILIM_SEL, 0x03);
> +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN,
> +			  (0x01 << 3));
> +
> +	return 0;
> +

another useless empty line

> +}
> +
> +static int rk817_charger_probe(struct platform_device *pdev)
> +{
> +	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
> +	struct rk817_charger *charger;
> +	struct device_node *node;
> +	struct power_supply_battery_info *info;
> +	struct device *dev = &pdev->dev;
> +	struct power_supply_config pscfg = {};
> +	int plugin_irq, plugout_irq;
> +	int of_value;
> +	int ret;
> +
> +	node = of_get_child_by_name(dev->parent->of_node, "battery");
> +	if (!node)
> +		return -ENODEV;
> +
> +	charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
> +	if (!charger)
> +		return -ENOMEM;
> +
> +	charger->rk808 = rk808;
> +
> +	charger->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, charger);
> +
> +	rk817_bat_calib_vol(charger);
> +
> +	pscfg.drv_data = charger;
> +	pscfg.of_node = node;
> +
> +	/* Get sample resistor value. Note only values of 10000 or 20000
> +	 * microohms are allowed. Schematic for my test implementation (an
> +	 * Odroid Go Advance) shows a 10 milliohm resistor for reference.
> +	 */
> +	ret = of_property_read_u32(node, "rockchip,resistor-sense", &of_value);

not using correct property unit:

https://github.com/devicetree-org/dt-schema/blob/master/schemas/property-units.yaml

> +	if (ret < 0) {
> +		dev_err(dev, "Error reading sample resistor value: %i\n", ret);
> +		return ret;

return dev_err_probe(...);

> +	}
> +	/* Store as a 1 or a 2, since all we really use the value for is as a
> +	 * divisor in some calculations.
> +	 */
> +	charger->res_div = (of_value == 20000) ? 2 : 1;
> +
> +	/* Get sleep enter current value. Not sure what this value is for
> +	 * other than to help calibrate the relax threshold.
> +	 */
> +	ret = of_property_read_u32(node, "rockchip,sleep-enter-current",
> +				   &of_value);

not using correct property unit:

https://github.com/devicetree-org/dt-schema/blob/master/schemas/property-units.yaml

> +	if (ret < 0) {
> +		dev_err(dev, "Error reading sleep enter current value: %i\n",
> +			ret);
> +		return ret;

return dev_err_probe(...);

> +	}
> +	charger->sleep_enter_current = of_value;
> +
> +	/* Get sleep filter current value */
> +	ret = of_property_read_u32(node, "rockchip,sleep-filter-current",
> +				   &of_value);

not using correct property unit:

https://github.com/devicetree-org/dt-schema/blob/master/schemas/property-units.yaml

> +	if (ret < 0) {
> +		dev_err(dev, "Error reading sleep filter current value: %i\n",
> +			ret);
> +		return ret;

return dev_err_probe(...);

> +	}
> +	charger->sleep_filter_current = of_value;
> +
> +	charger->bat_ps = devm_power_supply_register(&pdev->dev,
> +						     &rk817_bat_desc, &pscfg);
> +
> +	charger->chg_ps = devm_power_supply_register(&pdev->dev,
> +						     &rk817_chg_desc, &pscfg);
> +
> +	ret = power_supply_get_battery_info(charger->bat_ps,
> +					    &charger->bat_info);

You need to call power_supply_put_battery_info for the battery
info object once you no longer need it. I suppose in this case
it makes sense to do it via devm_add_action_or_reset().

> +	if (ret) {
> +		dev_err(dev, "Unable to get battery info: %d\n", ret);
> +		return ret;

return dev_err_probe(...);

> +	}
> +
> +	info = &charger->bat_info;
> +	if ((!info->charge_full_design_uah) ||
> +	    (!info->voltage_min_design_uv) ||
> +	    (!info->voltage_max_design_uv) ||
> +	    (!info->constant_charge_voltage_max_uv) ||
> +	    (!info->constant_charge_current_max_ua) ||
> +	    (!info->charge_term_current_ua)) {
> +		dev_err(dev, "Required battery information missing.\n");
> +		return -EINVAL;

return dev_err_probe(...);

> +	}
> +
> +	/* Has to run after power_supply_get_battery_info as it depends on some
> +	 * values discovered from that routine.
> +	 */
> +	ret = rk817_battery_init(charger);
> +	if (ret)
> +		return ret;
> +
> +	plugin_irq = platform_get_irq(pdev, 0);
> +	if (plugin_irq < 0)
> +		return plugin_irq;
> +
> +	plugout_irq = platform_get_irq(pdev, 1);
> +	if (plugout_irq < 0)
> +		return plugout_irq;
> +
> +	ret = devm_request_threaded_irq(charger->dev, plugin_irq, NULL,
> +					rk817_plug_in_isr,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +					"rk817_plug_in", charger);
> +	if (ret) {
> +		dev_err(&pdev->dev, "plug_in_irq request failed!\n");
> +		return ret;

return dev_err_probe(...);

> +	}
> +
> +	ret = devm_request_threaded_irq(charger->dev, plugout_irq, NULL,
> +					rk817_plug_out_isr,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +					"rk817_plug_out", charger);
> +	if (ret) {
> +		dev_err(&pdev->dev, "plug_out_irq request failed!\n");
> +		return ret;

return dev_err_probe(...);

> +	}
> +
> +	return 0;
> +}
> +
> +
> +static struct platform_driver rk817_charger_driver = {
> +	.probe    = rk817_charger_probe,
> +	.driver   = {
> +		.name  = "rk817-charger",
> +	},
> +};
> +module_platform_driver(rk817_charger_driver);
> +
> +MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC");
> +MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc at gmail.com>");
> +MODULE_LICENSE("GPL");

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210809/15a80fac/attachment-0001.sig>

From sebastian.reichel at collabora.com  Sun Aug  8 16:49:25 2021
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 9 Aug 2021 01:49:25 +0200
Subject: [RFC v2 1/4] dt-bindings: Add Rockchip rk817 battery charger
 support
In-Reply-To: <20210726190130.1973-2-macroalpha82@gmail.com>
References: <20210726190130.1973-1-macroalpha82@gmail.com>
 <20210726190130.1973-2-macroalpha82@gmail.com>
Message-ID: <20210808234925.rgd77x4nheom2bx3@earth.universe>

Hi,

On Mon, Jul 26, 2021 at 02:01:27PM -0500, Chris Morgan wrote:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Create dt-binding documentation to document rk817 battery and charger
> usage. New device-tree properties have been added.
> 
> - rockchip,resistor-sense: The value in microohms of the sample
>                            resistor.
> - rockchip,sleep-enter-current: The value in microamps of the sleep
>                                 enter current.
> - rockchip,sleep-filter-current: The value in microamps of the sleep
>                                  filter current.

please use common property units:

https://github.com/devicetree-org/dt-schema/blob/master/schemas/property-units.yaml

-- Sebastian

> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
> ---
>  .../devicetree/bindings/mfd/rk808.txt         | 35 +++++++++++++++++--
>  1 file changed, 33 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
> index 23a17a6663ec..fa42b6253d26 100644
> --- a/Documentation/devicetree/bindings/mfd/rk808.txt
> +++ b/Documentation/devicetree/bindings/mfd/rk808.txt
> @@ -70,13 +70,37 @@ Optional RK817 properties:
>  
>  - vcc8-supply:  The input supply for BOOST
>  - vcc9-supply:  The input supply for OTG_SWITCH
> +
>  - codec:	The child node for the codec to hold additional properties.
>  		If no additional properties are required for the codec, this
>  		node can be omitted.
> -
> -- rockchip,mic-in-differential: Telling if the microphone uses differential
> +- rockchip,mic-in-differential:	Telling if the microphone uses differential
>  				mode. Should be under the codec child node.
>  
> +- battery:	The child node for the charger to hold additional properties.
> +		If a battery is not in use, this node can be omitted. If a
> +		battery node is used, the following values are required:
> +		rockchip,resistor-sense, rockchip,sleep-enter-current,
> +		rockchip,sleep-filter-current, and a phandle to a
> +		monitored-battery node that contains a valid value for
> +		charge-full-design-microamp-hours,
> +		charge-term-current-microamp,
> +		constant-charge-current-max-microamp,
> +		constant-charge-voltage-max-microvolt,
> +		voltage-max-design-microvolt, voltage-min-design-microvolt,
> +		and a valid ocv-capacity table.
> +- rockchip,resistor-sense: Value in microohms of the battery sense resistor.
> +			   The PMIC only supports values of either 10000 or
> +			   20000. This value is used by the driver to set
> +			   the correct divisor value to translate ADC readings
> +			   into the proper units of measure.
> +- rockchip,sleep-enter-current: Value in microamps of the sleep enter current
> +				for the charger. Value is used by the driver
> +				to calibrate the relax threshold.
> +- rockchip,sleep-filter-current: Value in microamps of the sleep filter current
> +				 for the charger. Value is used by the driver
> +				 to derive the sleep sample current.
> +
>  Optional RK818 properties:
>  - vcc1-supply:  The input supply for DCDC_REG1
>  - vcc2-supply:  The input supply for DCDC_REG2
> @@ -459,6 +483,13 @@ Example:
>  			};
>  		};
>  
> +		rk817_battery: battery {
> +			monitored-battery = <&battery_cell>;
> +			rockchip,resistor-sense = <10000>;
> +			rockchip,sleep-enter-current = <300000>;
> +			rockchip,sleep-filter-current = <100000>;
> +		};
> +
>  		rk817_codec: codec {
>  			rockchip,mic-in-differential;
>  		};
> -- 
> 2.25.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210809/2fb41c60/attachment.sig>

From olteanv at gmail.com  Sun Aug  8 16:52:01 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 9 Aug 2021 02:52:01 +0300
Subject: [PATCH] mt7530 fix mt7530_fdb_write vid missing ivl bit
In-Reply-To: <20210808170024.228363-1-dqfext@gmail.com>
References: <20210716152213.4213-1-ericwouds@gmail.com>
 <20210808170024.228363-1-dqfext@gmail.com>
Message-ID: <20210808235201.wvw6mjzyvcpumxgk@skbuf>

On Mon, Aug 09, 2021 at 01:00:24AM +0800, DENG Qingfang wrote:
> On Fri, Jul 16, 2021 at 05:22:11PM +0200, ericwouds at gmail.com wrote:
> > From: Eric Woudstra <37153012+ericwoud at users.noreply.github.com>
> >
> > According to reference guides mt7530 (mt7620) and mt7531:
> >
> > NOTE: When IVL is reset, MAC[47:0] and FID[2:0] will be used to
> > read/write the address table. When IVL is set, MAC[47:0] and CVID[11:0]
> > will be used to read/write the address table.
> >
> > Since the function only fills in CVID and no FID, we need to set the
> > IVL bit. The existing code does not set it.
> >
> > This is a fix for the issue I dropped here earlier:
> >
> > http://lists.infradead.org/pipermail/linux-mediatek/2021-June/025697.html
> >
> > With this patch, it is now possible to delete the 'self' fdb entry
> > manually. However, wifi roaming still has the same issue, the entry
> > does not get deleted automatically. Wifi roaming also needs a fix
> > somewhere else to function correctly in combination with vlan.
>
> Sorry to bump this up, but I think I identified the issue:
>
> Consider a VLAN-aware bridge br0, with two ports set to different PVIDs:
>
> > bridge vlan
> > port         vlan-id
> > swp0         1 PVID Egress Untagged
> > swp1         2 PVID Egress Untagged
>
> When the bridge core sends a packet to swp1, the packet will be sent to
> the CPU port of the switch as untagged because swp1 is set as "Egress
> Untagged". However if the switch uses independent VLAN learning, the CPU
> port PVID will be used to update the FDB.

Sadly the Banana Pi MT7531 reference manual I have does not appear to
cover the DSA tagging header, so I am not actually clear what
MTK_HDR_XMIT_SA_DIS does when not set. Does it default to the CPU port's
value from the PSC register?

If it does, then I expect that your patch 0b69c54c74bc ("net: dsa:
mt7530: enable assisted learning on CPU port") fixes the issue Eric was
seeing, which in turn was caused by your other patch 5e5502e012b8 ("net:
dsa: mt7530: fix roaming from DSA user ports").

> As we don't change its PVID
> (not reasonable to change it anyway), hardware learning may not update
> the correct FDB.
>
> A possible solution is always send packets as tagged when serving a
> VLAN-aware bridge.

So as usual, VLANs put the "hard" in "hardware learning on the CPU port".
I would say "a possible solution is to not attempt to learn from
CPU-injected frames unless they are sent using the tx_fwd_offload
framework"....

>
> mv88e6xxx has been using hardware learning on CPU port since commit
> d82f8ab0d874 ("net: dsa: tag_dsa: offload the bridge forwarding process"),
> does it have the same issue?

...which ensures that bridge data plane packets are always sent to the
CPU port as VLAN-tagged:

br_handle_vlan:

	/* If the skb will be sent using forwarding offload, the assumption is
	 * that the switchdev will inject the packet into hardware together
	 * with the bridge VLAN, so that it can be forwarded according to that
	 * VLAN. The switchdev should deal with popping the VLAN header in
	 * hardware on each egress port as appropriate. So only strip the VLAN
	 * header if forwarding offload is not being used.
	 */
	if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED &&
	    !br_switchdev_frame_uses_tx_fwd_offload(skb))
		__vlan_hwaccel_clear_tag(skb);

Seriously, I expect that a packet injected through the CPU port will,
under normal circumstances, not default not look up the FDB, not update
the FDB, etc etc.

As long as you let the frame analyzer look in depth at the packet you do
need to ensure that it has a valid VLAN ID. Otherwise it is an actual
forwarding correctness issue and not just a "learn in wrong VLAN" issue:

https://patchwork.kernel.org/project/netdevbpf/patch/20210426170411.1789186-6-tobias at waldekranz.com/


From linus.walleij at linaro.org  Sun Aug  8 17:15:57 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 9 Aug 2021 02:15:57 +0200
Subject: [GIT PULL] IXP4xx DTS updates for v5.15
Message-ID: <CACRpkdY19AvWT--OcmEKbwFue_EcThVs7uZeHkzORten7xj-RA@mail.gmail.com>

Hi SoC folks,

this is the big DTS update for IXP4xx for kernel v5.15.

There is still some two device trees that need some more work
and some of these may need some additional hammering before
they are perfect(TM) but the basic functionality for all these systems
should be there and we can proceed to delete some boardfiles
as soon as we have successful boots on them all or we get tired of
waiting for someone to test them.

Please pull it in!

Yours,
Linus Walleij

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
tags/ixp4xx-dts-arm-soc-v5.15-1

for you to fetch changes up to f2841e3ab175da656e9124a9b032daf5a86c7ade:

  ARM: dts: ixp4xx: Add a devicetree for Freecom FSG-3 (2021-08-09
01:55:59 +0200)

----------------------------------------------------------------
IXP4xx DTS file updates for the v5.15 kernel cycle:

- Fix up some (non-urgent) IRQ flags for the PCI buses.

- Add the second UART to the generic ixp4xx.dtsi

- Make use of the new expansion bus driver in all device
  trees with e.g. flash memory on the expansion bus.

- Adds the CF card slot to the Gateworks GW2358.

- Add new device trees for:
  - Iomega NAS 100D
  - D-Link DSM-G600
  - Netgear WG302v2
  - Arcom Vulcan
  - Gateworks Avila GW2348
  - Intel IXPD425 and siblings
  - Coyote and IXDPG425
  - Linksys WRV54G

----------------------------------------------------------------
Linus Walleij (14):
      ARM: dts: ixp4xx: Fix up bad interrupt flags
      ARM: dts: ixp4xx: Add devicetree for Iomega NAS 100D
      ARM: dts: ixp4xx: Move EPBX100 flash to external bus node
      ARM: dts: ixp4xx: Add devicetree for D-Link DSM-G600 rev A
      ARM: dts: ixp4xx: Add second UART
      ARM: dts: ixp4xx: Use the expansion bus
      ARM: dts: ixp4xx: Add devicetree for Netgear WG302v2
      ARM: dts: ixp4xx: Add Arcom Vulcan device tree
      ARM: dts: ixp4xx: Add Gateworks Avila GW2348 device tree
      ARM: dts: ixp4xx: Add CF to GW2358
      ARM: dts: ixp4xx: Add Intel IXDP425 etc reference designs
      ARM: dts: ixp4xx: Add device trees for Coyote and IXDPG425
      ARM: dts: ixp4xx: Add devicetree for Linksys WRV54G
      ARM: dts: ixp4xx: Add a devicetree for Freecom FSG-3

 arch/arm/boot/dts/Makefile                         |  14 +-
 arch/arm/boot/dts/intel-ixp42x-adi-coyote.dts      | 110 +++++++++++++
 arch/arm/boot/dts/intel-ixp42x-arcom-vulcan.dts    | 167 ++++++++++++++++++++
 arch/arm/boot/dts/intel-ixp42x-dlink-dsm-g600.dts  | 145 +++++++++++++++++
 arch/arm/boot/dts/intel-ixp42x-freecom-fsg-3.dts   | 158 +++++++++++++++++++
 .../arm/boot/dts/intel-ixp42x-gateworks-gw2348.dts | 172 ++++++++++++++++++++
 arch/arm/boot/dts/intel-ixp42x-iomega-nas100d.dts  | 146 +++++++++++++++++
 arch/arm/boot/dts/intel-ixp42x-ixdp425.dts         |  72 +++++++++
 arch/arm/boot/dts/intel-ixp42x-ixdpg425.dts        | 125 +++++++++++++++
 arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts   |  30 ++--
 arch/arm/boot/dts/intel-ixp42x-linksys-wrv54g.dts  | 173 +++++++++++++++++++++
 arch/arm/boot/dts/intel-ixp42x-netgear-wg302v2.dts |  95 +++++++++++
 .../arm/boot/dts/intel-ixp42x-welltech-epbx100.dts |  84 +++++-----
 arch/arm/boot/dts/intel-ixp42x.dtsi                |   5 +
 .../arm/boot/dts/intel-ixp43x-gateworks-gw2358.dts |  81 ++++++----
 arch/arm/boot/dts/intel-ixp43x-kixrp435.dts        |  68 ++++++++
 arch/arm/boot/dts/intel-ixp43x.dtsi                |   6 +
 arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi         |  11 ++
 arch/arm/boot/dts/intel-ixp46x-ixdp465.dts         |  38 +++++
 .../boot/dts/intel-ixp4xx-reference-design.dtsi    | 132 ++++++++++++++++
 arch/arm/boot/dts/intel-ixp4xx.dtsi                |  44 +++++-
 21 files changed, 1784 insertions(+), 92 deletions(-)
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-adi-coyote.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-arcom-vulcan.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-dlink-dsm-g600.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-freecom-fsg-3.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-gateworks-gw2348.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-iomega-nas100d.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-ixdp425.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-ixdpg425.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-linksys-wrv54g.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-netgear-wg302v2.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp43x-kixrp435.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp46x-ixdp465.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp4xx-reference-design.dtsi


From laurent.pinchart at ideasonboard.com  Sun Aug  8 18:52:13 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 9 Aug 2021 04:52:13 +0300
Subject: [PATCH] arm64: zynqmp: Remove not documented is-dual property
In-Reply-To: <876c53b92f99623bae45d5c0c5ae79ee3e24f745.1628239345.git.michal.simek@xilinx.com>
References: <876c53b92f99623bae45d5c0c5ae79ee3e24f745.1628239345.git.michal.simek@xilinx.com>
Message-ID: <YRCKTfxmo60uPzp5@pendragon.ideasonboard.com>

Hi Michal,

Thank you for the patch.

On Fri, Aug 06, 2021 at 10:42:29AM +0200, Michal Simek wrote:
> Remove is-dual not documented property and also update comment about QSPI
> sizes to reflect dual configuration as 16MB + 16MB.
> Only single configuration is supported now.
> 
> Reported-by: Quanyang Wang <quanyang.wang at windriver.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
> 
>  arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts | 3 +--
>  arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts | 3 +--
>  arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts | 3 +--
>  3 files changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> index becfc23a5610..3d8d14ef1ede 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> @@ -937,9 +937,8 @@ &psgtr {
>  
>  &qspi {
>  	status = "okay";
> -	is-dual = <1>;
>  	flash at 0 {
> -		compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
> +		compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
>  		#address-cells = <1>;
>  		#size-cells = <1>;
>  		reg = <0x0>;
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> index d2219373580a..057c04352591 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> @@ -931,9 +931,8 @@ &psgtr {
>  
>  &qspi {
>  	status = "okay";
> -	is-dual = <1>;
>  	flash at 0 {
> -		compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
> +		compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
>  		#address-cells = <1>;
>  		#size-cells = <1>;
>  		reg = <0x0>;
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> index dac5ba67a160..e1fff62a4cd5 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> @@ -773,9 +773,8 @@ &psgtr {
>  
>  &qspi {
>  	status = "okay";
> -	is-dual = <1>;
>  	flash at 0 {
> -		compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
> +		compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
>  		#address-cells = <1>;
>  		#size-cells = <1>;
>  		reg = <0x0>;

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Sun Aug  8 18:57:03 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 9 Aug 2021 04:57:03 +0300
Subject: [PATCH] arm64: zynqmp: Fix serial compatible string
In-Reply-To: <89b36e0a6187cc6b05b27a035efdf79173bd4486.1628240307.git.michal.simek@xilinx.com>
References: <89b36e0a6187cc6b05b27a035efdf79173bd4486.1628240307.git.michal.simek@xilinx.com>
Message-ID: <YRCLb1grspPDh4vX@pendragon.ideasonboard.com>

Hi Michal,

Thank you for the patch.

On Fri, Aug 06, 2021 at 10:58:29AM +0200, Michal Simek wrote:
> Based on commit 65a2c14d4f00 ("dt-bindings: serial: convert Cadence UART
> bindings to YAML") compatible string should look like differently that's
> why fix it to be aligned with dt binding.
> 
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
> 
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 6f0fcec28ae2..b5fde9dddca5 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -786,7 +786,7 @@ ttc3: timer at ff140000 {
>  		};
>  
>  		uart0: serial at ff000000 {
> -			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
> +			compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12";
>  			status = "disabled";
>  			interrupt-parent = <&gic>;
>  			interrupts = <0 21 4>;
> @@ -796,7 +796,7 @@ uart0: serial at ff000000 {
>  		};
>  
>  		uart1: serial at ff010000 {
> -			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
> +			compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12";
>  			status = "disabled";
>  			interrupt-parent = <&gic>;
>  			interrupts = <0 22 4>;

-- 
Regards,

Laurent Pinchart


From sunilmut at microsoft.com  Sun Aug  8 19:35:05 2021
From: sunilmut at microsoft.com (Sunil Muthuswamy)
Date: Mon, 9 Aug 2021 02:35:05 +0000
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <87o8a81boi.wl-maz@kernel.org>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>	<87r1f9wooc.wl-maz@kernel.org>
 <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87wnp0b86y.wl-maz@kernel.org>
 <MW4PR21MB2002ABD170CC9786CDF5D493C0F39@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87o8a81boi.wl-maz@kernel.org>
Message-ID: <MW4PR21MB200286E2CF4DA229D7059598C0F69@MW4PR21MB2002.namprd21.prod.outlook.com>

Sunday, August 8, 2021 3:19 AM,
Marc Zyngier <maz at kernel.org> wrote:
> 
> [+Lorenzo, as he deals with both PCI and ACPI]
> 
> I think it is clear enough, but I don't see what this buys us other
> than turning DirectLPI into something that is essentially private to
> Hyper-V, just for the sake of sidestepping a firmware description.
> Furthermore, the Hyper-V "single MSI address" model doesn't match the
> way DirectLPI works (after all, this is one of the many reasons why we
> have the ITS).
> 
> The architecture already gives you everything you need to make things
> work in Hyper-V. You can easily implement the DirectLPI support (you
> definitely need most of it anyway), and the PCI-MSI layer is
> *free*. All you need is a firmware description. Which I don't believe
> is the end of the world, given that DT is freely hackable and that
> IORT is an ARM-private extension to ACPI. I'm sure you know who to
> reach out to in order to start a draft (and if you don't, I can give
> you names offline).
> 
That sounds reasonable. The DT extension here alone wont suffice for
Hyper-V and we would need the ACPI IORT extension here as well. Our
general experience with ACPI extension is that they can take time. But,
I am curious to hear from Lorenzo on his thoughts here and if just an
IORT extension means anything else in terms of timelines.

> I am not interested in expanding the GICv3 architecture support if it
> cannot be generally used in a way that is *compliant with the
> architecture*. If you think DirectLPIs can make the hypervisor
> simpler, I'm fine with it. But let's fully embrace the concept instead
> of hiding it behind a layer of PV muck. It will even have a chance of
> working on bare metal (such as on the machine that is humming behind
> me, or even the Fast Model).
> 
Appreciate your inputs. Since we are discussing options, there is one more
option to enable Hyper-V virtual PCI for ARM64 that I do would like to
discuss. That option is to implement the IRQ chip completely within the
Hyper-V module itself. That IRQ chip will take care of allocating LPI vectors,
enabling the interrupt (unmask, mask etc..). It won't be a Direct LPI based,
but based on custom Hyper-V methods. That chip will parent itself to the
GIC v3 IRQ domain. The only extra thing needed for this is for the Hyper-V
IRQ chip to be able to discover the GIC v3 IRQ domain, for which it
cannot use the 'irq_find_matching_fwnode' method as Hyper-V virtual
PCI bus/devices are not firmware enumerated. I am not sure if there is any
other way to discover the GIC (DOMAIN_BUS_WIRED) domain.

What are your thoughts/feedback on the above? This will allow us to
enable the scenario for the business timelines we are targeting for, while
we wait for firmware spec updates. Long term we also want to use
architectural methods here as that helps the Hypervisor as well, and I
would be glad to pursue the firmware spec updates in parallel.

Thanks,
Sunil





From yzhai003 at ucr.edu  Sun Aug  8 19:36:44 2021
From: yzhai003 at ucr.edu (Yizhuo Zhai)
Date: Sun, 8 Aug 2021 19:36:44 -0700
Subject: [PATCH] iio: adc: stm32-dfsdm: Fix the uninitialized use if
 regmap_read() fails
In-Reply-To: <20210808183243.70619aa8@jic23-huawei>
References: <20210719195313.40341-1-yzhai003@ucr.edu>
 <20210724164840.7381053b@jic23-huawei>
 <20210808183243.70619aa8@jic23-huawei>
Message-ID: <CABvMjLRHs61AAYqTeRWV0DHciLBoqHwJ5Djg7ZseYkjE=JhbQg@mail.gmail.com>

Hi Jonathan:
Thanks for your effort, and yes please take a look just in case.
FYI, I made the modifications align with Alexandru's help, this is the
original reply:

On Mon, Jul 19, 2021 at 12:47 AM Alexandru Ardelean
<ardeleanalex at gmail.com> wrote:
>
> On Mon, Jul 19, 2021 at 2:39 AM Yizhuo Zhai <yzhai003 at ucr.edu> wrote:
> >
> > Hi All:
> > Inside function stm32_dfsdm_irq(), the variable "status", "int_en"
> > could be uninitialized if the regmap_read() fails and returns an error
> > code.  However, they are directly used in the later context to decide
> > the control flow, which is potentially unsafe. However,
> > stm32_dfsdm_irq() returns the type irqreturn_t and I could not return
>
> Just curious: are you seeing any issues with these variables being
> uninitialized?
>
> > the error code directly. Could you please advise me here?
>
> The correct way to do it, would be:
>
> ret = regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
> if (ret)
>     return IRQ_HANDLED;
>
> IRQ handlers should return one of
> enum irqreturn {
>     IRQ_NONE        = (0 << 0),
>     IRQ_HANDLED     = (1 << 0),
>     IRQ_WAKE_THREAD     = (1 << 1),
> };
>
> If you want to fully optimize/correct this, then it may be something like:
>
>         ret = regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
>         if (ret)
>                 return IRQ_HANDLED;
>
>         if (status & DFSDM_ISR_REOCF_MASK) {
>                 /* Read the data register clean the IRQ status */
>                 regmap_read(regmap, DFSDM_RDATAR(adc->fl_id), adc->buffer);
>
> // in this point, we could check for regmap_read(), but it won't make
> sense; we should call the complete() handler, either way
>
>                 complete(&adc->completion);
>         }
>
>         if (status & DFSDM_ISR_ROVRF_MASK) {
>                 ret = regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en);
>                 if (ret)
>                         return IRQ_HANDLED;
>                 if (int_en & DFSDM_CR2_ROVRIE_MASK)
>                         dev_warn(&indio_dev->dev, "Overrun detected\n");
>                 regmap_update_bits(regmap, DFSDM_ICR(adc->fl_id),
>                                    DFSDM_ICR_CLRROVRF_MASK,
>                                    DFSDM_ICR_CLRROVRF_MASK);
>
> // in this point, we could also check the ret code; but we still need
> to call IRQ_HANDLED anyway;
>         }
>
>
> Quite often, when regmap_read() returns errors, then something is
> seriously wrong in the system.
> Something else would usually fail or crash worse than this interrupt handler.
> That being said, properly handling regmap_read() here is a good idea.
>
> >
> > The related code:
> >
> > static irqreturn_t stm32_dfsdm_irq(int irq, void *arg) {
> >     unsigned int status, int_en;
> >
> >     regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
> >     regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en);
> >
> >     if (status & DFSDM_ISR_REOCF_MASK) {}
> >     if (status & DFSDM_ISR_ROVRF_MASK) {}
> > }
> >
> >
> > --
> > Kind Regards,
> >
> > Yizhuo Zhai
> >
> > Computer Science, Graduate Student
> > University of California, Riverside


On Sun, Aug 8, 2021 at 10:29 AM Jonathan Cameron <jic23 at kernel.org> wrote:
>
> On Sat, 24 Jul 2021 16:48:40 +0100
> Jonathan Cameron <jic23 at kernel.org> wrote:
>
> > On Mon, 19 Jul 2021 19:53:11 +0000
> > Yizhuo <yzhai003 at ucr.edu> wrote:
> >
> > > Inside function stm32_dfsdm_irq(), the variable "status", "int_en"
> > > could be uninitialized if the regmap_read() fails and returns an error
> > > code.  However, they are directly used in the later context to decide
> > > the control flow, which is potentially unsafe.
> > >
> > > Fixes: e2e6771c64625 ("IIO: ADC: add STM32 DFSDM sigma delta ADC support")
> > >
> > > Signed-off-by: Yizhuo <yzhai003 at ucr.edu>
> >
> > Hi Yizhou
> >
> > I want to get some review of this from people familiar with the
> > hardware as there is a small possibility your reordering might have
> > introduced a problem.
>
> To stm32 people, can someone take a look at this?
>
> Thanks,
>
> Jonathan
>
> >
> > > ---
> > >  drivers/iio/adc/stm32-dfsdm-adc.c | 9 +++++++--
> > >  1 file changed, 7 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
> > > index 1cfefb3b5e56..d8b78aead942 100644
> > > --- a/drivers/iio/adc/stm32-dfsdm-adc.c
> > > +++ b/drivers/iio/adc/stm32-dfsdm-adc.c
> > > @@ -1292,9 +1292,11 @@ static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)
> > >     struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
> > >     struct regmap *regmap = adc->dfsdm->regmap;
> > >     unsigned int status, int_en;
> > > +   int ret;
> > >
> > > -   regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
> > > -   regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en);
> >
> > Moving this later is only valid if there aren't any side effects.
> > The current ordering is strange enough it makes me wonder if there might be!
> >
> > Jonathan
> >
> > > +   ret = regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status);
> > > +   if (ret)
> > > +           return IRQ_HANDLED;
> > >
> > >     if (status & DFSDM_ISR_REOCF_MASK) {
> > >             /* Read the data register clean the IRQ status */
> > > @@ -1303,6 +1305,9 @@ static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)
> > >     }
> > >
> > >     if (status & DFSDM_ISR_ROVRF_MASK) {
> > > +           ret = regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en);
> > > +           if (ret)
> > > +                   return IRQ_HANDLED;
> > >             if (int_en & DFSDM_CR2_ROVRIE_MASK)
> > >                     dev_warn(&indio_dev->dev, "Overrun detected\n");
> > >             regmap_update_bits(regmap, DFSDM_ICR(adc->fl_id),
> >
>


--
Kind Regards,

Yizhuo Zhai

Computer Science, Graduate Student
University of California, Riverside


From nina-cm.wu at mediatek.com  Sun Aug  8 20:08:15 2021
From: nina-cm.wu at mediatek.com (Nina Wu)
Date: Mon, 9 Aug 2021 11:08:15 +0800
Subject: [v4 3/7] soc: mediatek: devapc: add shared flag to IRQ
In-Reply-To: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
References: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
Message-ID: <1628478499-29460-3-git-send-email-nina-cm.wu@mediatek.com>

From: Nina Wu <Nina-CM.Wu at mediatek.com>

For new ICs, there are multiple devapc HWs for different subsys.
They all share the same IRQ number.

Signed-off-by: Nina Wu <Nina-CM.Wu at mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index 86bddb2..abc0962 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -282,7 +282,7 @@ static int mtk_devapc_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq,
-			       IRQF_TRIGGER_NONE, "devapc", ctx);
+			       IRQF_TRIGGER_NONE | IRQF_SHARED, "devapc", ctx);
 	if (ret) {
 		clk_disable_unprepare(ctx->infra_clk);
 		return ret;
-- 
2.6.4

From nina-cm.wu at mediatek.com  Sun Aug  8 20:08:19 2021
From: nina-cm.wu at mediatek.com (Nina Wu)
Date: Mon, 9 Aug 2021 11:08:19 +0800
Subject: [v4 7/7] arm64: dts: mt8192: Add devapc node
In-Reply-To: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
References: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
Message-ID: <1628478499-29460-7-git-send-email-nina-cm.wu@mediatek.com>

From: Nina Wu <Nina-CM.Wu at mediatek.com>

Add devapc nodes to mt8192.

Signed-off-by: Nina Wu <Nina-CM.Wu at mediatek.com>
---
This patch depends on "Add dt-bindings of MT8192 clocks" [1]
and "Add mt8192 clock controllers" [2]

[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/include/dt-bindings/clock/mt8192-clk.h?h=next-20210806&id=f35f1a23e0e12e3173e9e9dedbc150d139027189
[2] https://patchwork.kernel.org/project/linux-mediatek/patch/20210727023205.20319-2-chun-jie.chen at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 36 ++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 6b22441..accbd07 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -517,6 +517,33 @@
 			clock-names = "clk13m";
 		};
 
+		devapc_infra: devapc at 10207000 {
+			compatible = "mediatek,mt8192-devapc";
+			reg = <0 0x10207000 0 0x1000>;
+			vio-idx-num = <367>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_DEVICE_APC>;
+			clock-names = "devapc-infra-clock";
+		};
+
+		devapc_peri: devapc at 10274000 {
+			compatible = "mediatek,mt8192-devapc";
+			reg = <0 0x10274000 0 0x1000>;
+			vio-idx-num = <292>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_DEVICE_APC>;
+			clock-names = "devapc-infra-clock";
+		};
+
+		devapc_peri2: devapc at 10275000 {
+			compatible = "mediatek,mt8192-devapc";
+			reg = <0 0x10275000 0 0x1000>;
+			vio-idx-num = <242>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_DEVICE_APC>;
+			clock-names = "devapc-infra-clock";
+		};
+
 		scp_adsp: clock-controller at 10720000 {
 			compatible = "mediatek,mt8192-scp_adsp";
 			reg = <0 0x10720000 0 0x1000>;
@@ -661,6 +688,15 @@
 			status = "disabled";
 		};
 
+		devapc_peri_par: devapc at 11020000 {
+			compatible = "mediatek,mt8192-devapc";
+			reg = <0 0x11020000 0 0x1000>;
+			vio-idx-num = <58>;
+			interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_DEVICE_APC>;
+			clock-names = "devapc-infra-clock";
+		};
+
 		nor_flash: spi at 11234000 {
 			compatible = "mediatek,mt8192-nor";
 			reg = <0 0x11234000 0 0xe0>;
-- 
2.6.4

From nina-cm.wu at mediatek.com  Sun Aug  8 20:08:17 2021
From: nina-cm.wu at mediatek.com (Nina Wu)
Date: Mon, 9 Aug 2021 11:08:17 +0800
Subject: [v4 5/7] soc: mediatek: devapc: add debug register for new IC support
In-Reply-To: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
References: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
Message-ID: <1628478499-29460-5-git-send-email-nina-cm.wu@mediatek.com>

From: Nina Wu <Nina-CM.Wu at mediatek.com>

There are 3 debug info registers in new ICs while in legacy ones,
we have only 2. We add a 'version' field in compatible data to
decide how we extract the debug info.

Signed-off-by: Nina Wu <Nina-CM.Wu at mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 43 +++++++++++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index 8eb65dc0..42d3be5 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -26,12 +26,24 @@ struct mtk_devapc_vio_dbgs {
 			u32 addr_h:4;
 			u32 resv:4;
 		} dbg0_bits;
+
+		struct {
+			u32 dmnid:6;
+			u32 vio_w:1;
+			u32 vio_r:1;
+			u32 addr_h:4;
+			u32 resv:20;
+		} dbg0_bits_ver2;
 	};
 
 	u32 vio_dbg1;
+	u32 vio_dbg2;
 };
 
 struct mtk_devapc_data {
+	/* architecture version */
+	u32 version;
+
 	/* default numbers of violation index */
 	u32 vio_idx_num;
 
@@ -40,6 +52,7 @@ struct mtk_devapc_data {
 	u32 vio_sta_offset;
 	u32 vio_dbg0_offset;
 	u32 vio_dbg1_offset;
+	u32 vio_dbg2_offset;
 	u32 apc_con_offset;
 	u32 vio_shift_sta_offset;
 	u32 vio_shift_sel_offset;
@@ -163,22 +176,43 @@ static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx)
 	struct mtk_devapc_vio_dbgs vio_dbgs;
 	void __iomem *vio_dbg0_reg;
 	void __iomem *vio_dbg1_reg;
+	void __iomem *vio_dbg2_reg;
+	u32 vio_addr, bus_id, domain_id;
+	u32 vio_w, vio_r;
 
 	vio_dbg0_reg = ctx->base + ctx->data->vio_dbg0_offset;
 	vio_dbg1_reg = ctx->base + ctx->data->vio_dbg1_offset;
+	vio_dbg2_reg = ctx->base + ctx->data->vio_dbg2_offset;
 
 	vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg);
 	vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg);
+	if (ctx->data->version == 2U)
+		vio_dbgs.vio_dbg2 = readl(vio_dbg2_reg);
+
+	if (ctx->data->version == 1U) {
+		/* arch version 1 */
+		bus_id = vio_dbgs.dbg0_bits.mstid;
+		vio_addr = vio_dbgs.vio_dbg1;
+		domain_id = vio_dbgs.dbg0_bits.dmnid;
+		vio_w = vio_dbgs.dbg0_bits.vio_w;
+		vio_r = vio_dbgs.dbg0_bits.vio_r;
+	} else {
+		/* arch version 2 */
+		bus_id = vio_dbgs.vio_dbg1;
+		vio_addr = vio_dbgs.vio_dbg2;
+		domain_id = vio_dbgs.dbg0_bits_ver2.dmnid;
+		vio_w = vio_dbgs.dbg0_bits_ver2.vio_w;
+		vio_r = vio_dbgs.dbg0_bits_ver2.vio_r;
+	}
 
 	/* Print violation information */
-	if (vio_dbgs.dbg0_bits.vio_w)
+	if (vio_w)
 		dev_info(ctx->dev, "Write Violation\n");
-	else if (vio_dbgs.dbg0_bits.vio_r)
+	else if (vio_r)
 		dev_info(ctx->dev, "Read Violation\n");
 
 	dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%x\n",
-		 vio_dbgs.dbg0_bits.mstid, vio_dbgs.dbg0_bits.dmnid,
-		 vio_dbgs.vio_dbg1);
+		 bus_id, domain_id, vio_addr);
 }
 
 /*
@@ -219,6 +253,7 @@ static void stop_devapc(struct mtk_devapc_context *ctx)
 }
 
 static const struct mtk_devapc_data devapc_mt6779 = {
+	.version = 1,
 	.vio_idx_num = 511,
 	.vio_mask_offset = 0x0,
 	.vio_sta_offset = 0x400,
-- 
2.6.4

From nina-cm.wu at mediatek.com  Sun Aug  8 20:08:18 2021
From: nina-cm.wu at mediatek.com (Nina Wu)
Date: Mon, 9 Aug 2021 11:08:18 +0800
Subject: [v4 6/7] soc: mediatek: devapc: support mt8192
In-Reply-To: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
References: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
Message-ID: <1628478499-29460-6-git-send-email-nina-cm.wu@mediatek.com>

From: Nina Wu <Nina-CM.Wu at mediatek.com>

Add compatible to support mt8192.

Signed-off-by: Nina Wu <Nina-CM.Wu at mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index 42d3be5..c857678 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -265,11 +265,27 @@ static const struct mtk_devapc_data devapc_mt6779 = {
 	.vio_shift_con_offset = 0xF20,
 };
 
+static const struct mtk_devapc_data devapc_mt8192 = {
+	.version = 2,
+	.vio_mask_offset = 0x0,
+	.vio_sta_offset = 0x400,
+	.vio_dbg0_offset = 0x900,
+	.vio_dbg1_offset = 0x904,
+	.vio_dbg2_offset = 0x908,
+	.apc_con_offset = 0xF00,
+	.vio_shift_sta_offset = 0xF20,
+	.vio_shift_sel_offset = 0xF30,
+	.vio_shift_con_offset = 0xF10,
+};
+
 static const struct of_device_id mtk_devapc_dt_match[] = {
 	{
 		.compatible = "mediatek,mt6779-devapc",
 		.data = &devapc_mt6779,
 	}, {
+		.compatible = "mediatek,mt8192-devapc",
+		.data = &devapc_mt8192,
+	}, {
 	},
 };
 MODULE_DEVICE_TABLE(of, mtk_devapc_dt_match);
-- 
2.6.4

From nina-cm.wu at mediatek.com  Sun Aug  8 20:08:16 2021
From: nina-cm.wu at mediatek.com (Nina Wu)
Date: Mon, 9 Aug 2021 11:08:16 +0800
Subject: [v4 4/7] soc: mediatek: devapc: rename register variable infra_base
In-Reply-To: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
References: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
Message-ID: <1628478499-29460-4-git-send-email-nina-cm.wu@mediatek.com>

From: Nina Wu <Nina-CM.Wu at mediatek.com>

For new ICs, there are multiple devapc HWs for different subsys.
For example, there is devapc respectively for infra, peri, peri2, etc.
So we rename the variable 'infra_base' to 'base' for code readability.

Signed-off-by: Nina Wu <Nina-CM.Wu at mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index abc0962..8eb65dc0 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -48,7 +48,7 @@ struct mtk_devapc_data {
 
 struct mtk_devapc_context {
 	struct device *dev;
-	void __iomem *infra_base;
+	void __iomem *base;
 	struct clk *infra_clk;
 	const struct mtk_devapc_data *data;
 
@@ -61,7 +61,7 @@ static void clear_vio_status(struct mtk_devapc_context *ctx)
 	void __iomem *reg;
 	int i;
 
-	reg = ctx->infra_base + ctx->data->vio_sta_offset;
+	reg = ctx->base + ctx->data->vio_sta_offset;
 
 	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->vio_idx_num) - 1; i++)
 		writel(GENMASK(31, 0), reg + 4 * i);
@@ -76,7 +76,7 @@ static void mask_module_irq(struct mtk_devapc_context *ctx, bool mask)
 	u32 val;
 	int i;
 
-	reg = ctx->infra_base + ctx->data->vio_mask_offset;
+	reg = ctx->base + ctx->data->vio_mask_offset;
 
 	if (mask)
 		val = GENMASK(31, 0);
@@ -118,11 +118,11 @@ static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx)
 	int ret;
 	u32 val;
 
-	pd_vio_shift_sta_reg = ctx->infra_base +
+	pd_vio_shift_sta_reg = ctx->base +
 			       ctx->data->vio_shift_sta_offset;
-	pd_vio_shift_sel_reg = ctx->infra_base +
+	pd_vio_shift_sel_reg = ctx->base +
 			       ctx->data->vio_shift_sel_offset;
-	pd_vio_shift_con_reg = ctx->infra_base +
+	pd_vio_shift_con_reg = ctx->base +
 			       ctx->data->vio_shift_con_offset;
 
 	/* Find the minimum shift group which has violation */
@@ -164,8 +164,8 @@ static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx)
 	void __iomem *vio_dbg0_reg;
 	void __iomem *vio_dbg1_reg;
 
-	vio_dbg0_reg = ctx->infra_base + ctx->data->vio_dbg0_offset;
-	vio_dbg1_reg = ctx->infra_base + ctx->data->vio_dbg1_offset;
+	vio_dbg0_reg = ctx->base + ctx->data->vio_dbg0_offset;
+	vio_dbg1_reg = ctx->base + ctx->data->vio_dbg1_offset;
 
 	vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg);
 	vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg);
@@ -203,7 +203,7 @@ static irqreturn_t devapc_violation_irq(int irq_number, void *data)
  */
 static void start_devapc(struct mtk_devapc_context *ctx)
 {
-	writel(BIT(31), ctx->infra_base + ctx->data->apc_con_offset);
+	writel(BIT(31), ctx->base + ctx->data->apc_con_offset);
 
 	mask_module_irq(ctx, false);
 }
@@ -215,7 +215,7 @@ static void stop_devapc(struct mtk_devapc_context *ctx)
 {
 	mask_module_irq(ctx, true);
 
-	writel(BIT(2), ctx->infra_base + ctx->data->apc_con_offset);
+	writel(BIT(2), ctx->base + ctx->data->apc_con_offset);
 }
 
 static const struct mtk_devapc_data devapc_mt6779 = {
@@ -256,8 +256,8 @@ static int mtk_devapc_probe(struct platform_device *pdev)
 	ctx->data = of_device_get_match_data(&pdev->dev);
 	ctx->dev = &pdev->dev;
 
-	ctx->infra_base = of_iomap(node, 0);
-	if (!ctx->infra_base)
+	ctx->base = of_iomap(node, 0);
+	if (!ctx->base)
 		return -EINVAL;
 
 	/* Set vio_idx_num to default value.
-- 
2.6.4

From nina-cm.wu at mediatek.com  Sun Aug  8 20:08:14 2021
From: nina-cm.wu at mediatek.com (Nina Wu)
Date: Mon, 9 Aug 2021 11:08:14 +0800
Subject: [v4 2/7] soc: mediatek: devapc: get 'vio_idx_num' info from DT
In-Reply-To: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
References: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>
Message-ID: <1628478499-29460-2-git-send-email-nina-cm.wu@mediatek.com>

From: Nina Wu <Nina-CM.Wu at mediatek.com>

For new ICs, there are multiple devapc HWs for different subsys.
The number of devices controlled by each devapc (i.e. 'vio_idx_num')
will be set in DT for per devapc node.
On the other hand, for old ICs which have only one devapc HW, the
'vio_idx_num' info is set in compatible data.
To be backward compatible, the 'vio_idx_num' in compatible data is set
as the default value. Only when the default value is 0 will we get the
'vio_idx_num' from DT.

Signed-off-by: Nina Wu <Nina-CM.Wu at mediatek.com>
---
 drivers/soc/mediatek/mtk-devapc.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c
index 7c65ad3..86bddb2 100644
--- a/drivers/soc/mediatek/mtk-devapc.c
+++ b/drivers/soc/mediatek/mtk-devapc.c
@@ -32,7 +32,7 @@ struct mtk_devapc_vio_dbgs {
 };
 
 struct mtk_devapc_data {
-	/* numbers of violation index */
+	/* default numbers of violation index */
 	u32 vio_idx_num;
 
 	/* reg offset */
@@ -51,6 +51,9 @@ struct mtk_devapc_context {
 	void __iomem *infra_base;
 	struct clk *infra_clk;
 	const struct mtk_devapc_data *data;
+
+	/* numbers of violation index */
+	u32 vio_idx_num;
 };
 
 static void clear_vio_status(struct mtk_devapc_context *ctx)
@@ -60,10 +63,10 @@ static void clear_vio_status(struct mtk_devapc_context *ctx)
 
 	reg = ctx->infra_base + ctx->data->vio_sta_offset;
 
-	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++)
+	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->vio_idx_num) - 1; i++)
 		writel(GENMASK(31, 0), reg + 4 * i);
 
-	writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 0),
+	writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num) - 1, 0),
 	       reg + 4 * i);
 }
 
@@ -80,15 +83,15 @@ static void mask_module_irq(struct mtk_devapc_context *ctx, bool mask)
 	else
 		val = 0;
 
-	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++)
+	for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->vio_idx_num) - 1; i++)
 		writel(val, reg + 4 * i);
 
 	val = readl(reg + 4 * i);
 	if (mask)
-		val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1,
+		val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num) - 1,
 			       0);
 	else
-		val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1,
+		val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->vio_idx_num) - 1,
 				0);
 
 	writel(val, reg + 4 * i);
@@ -257,6 +260,16 @@ static int mtk_devapc_probe(struct platform_device *pdev)
 	if (!ctx->infra_base)
 		return -EINVAL;
 
+	/* Set vio_idx_num to default value.
+	 * If the value is 0, get the info from DT.
+	 */
+	ctx->vio_idx_num = ctx->data->vio_idx_num;
+	if (!ctx->vio_idx_num)
+		if (of_property_read_u32(node,
+					 "vio-idx-num",
+					 &ctx->vio_idx_num))
+			return -EINVAL;
+
 	devapc_irq = irq_of_parse_and_map(node, 0);
 	if (!devapc_irq)
 		return -EINVAL;
-- 
2.6.4

From nina-cm.wu at mediatek.com  Sun Aug  8 20:08:13 2021
From: nina-cm.wu at mediatek.com (Nina Wu)
Date: Mon, 9 Aug 2021 11:08:13 +0800
Subject: [v4 1/7] dt-bindings: devapc: Add 'vio-idx-num' field to support
 mt8192
Message-ID: <1628478499-29460-1-git-send-email-nina-cm.wu@mediatek.com>

From: Nina Wu <Nina-CM.Wu at mediatek.com>

For new ICs, there are multiple devapc HWs for different subsys.
We add a field 'vio-idx-num' in DT to indicate the number of
devices controlled by each devapc.
To be backward compatible with old ICs which have only one devapc
HW, this field is not required. The 'vio-idx-num' info will be set
in compatible data instead.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Nina Wu <Nina-CM.Wu at mediatek.com>
---
 Documentation/devicetree/bindings/soc/mediatek/devapc.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml b/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
index 31e4d3c..69abd03 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/devapc.yaml
@@ -20,11 +20,16 @@ properties:
   compatible:
     enum:
       - mediatek,mt6779-devapc
+      - mediatek,mt8192-devapc
 
   reg:
     description: The base address of devapc register bank
     maxItems: 1
 
+  mediatek,vio-idx-num:
+    description: The number of the devices controlled by devapc
+    $ref: /schemas/types.yaml#/definitions/uint32
+
   interrupts:
     description: A single interrupt specifier
     maxItems: 1
-- 
2.6.4

From eizan at google.com  Sun Aug  8 20:23:04 2021
From: eizan at google.com (Eizan Miyamoto)
Date: Mon, 9 Aug 2021 13:23:04 +1000
Subject: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on
In-Reply-To: <8fe5ac46-a9db-710e-a6d1-856805ab2773@collabora.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>
 <8fe5ac46-a9db-710e-a6d1-856805ab2773@collabora.com>
Message-ID: <CAOak1e_xw84Q+ikAn7TEqie00Sbv4Qpaax==jZ5MJVfPP1pf0Q@mail.gmail.com>

Hi Dafna, thank you very much for spending time to review the patch,
your time spent is very much appreciated.

On Thu, Aug 5, 2021 at 4:06 PM Dafna Hirschfeld
<dafna.hirschfeld at collabora.com> wrote:
> > +err_clk_prepare_enable:
> > +     for (--i; i >= 0; i--) {
> > +             if (IS_ERR(comp->clk[i]))
> > +                     continue;
> > +             clk_disable_unprepare(comp->clk[i]);
> >       }
> > +
> > +     return status;
>
> There is an API function clk_bulk_prepare_enable to prepare and enable an array of clks
> so you can just use it.

As per Enric's suggestion earlier in this email thread, are you OK
with me making this change in a follow-up patch, particularly since
the logic as it is was preserved from previous functionality?

> > -static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
> > +static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
> >   {
> > -     struct device *dev = &mdp->pdev->dev;
> >       struct mtk_mdp_comp *comp_node;
> > +     int status;
> > +     struct device *dev = &mdp->pdev->dev;
> > +     int err;
> >
> > -     list_for_each_entry(comp_node, &mdp->comp_list, node)
> > -             mtk_mdp_comp_clock_on(dev, comp_node);
> > +     list_for_each_entry(comp_node, &mdp->comp_list, node) {
> > +             err = mtk_mdp_comp_clock_on(dev, comp_node);
> > +             if (err) {
> > +                     status = err;
>
> You can get rid of the new var 'status' and just return ret in case of error

This seems like a nit (please let me know if you disagree), and it's
also cleaned up in a follow-on patch in the series ("don't
pm_run_time_get/put for master comp in clock_on"). Is making the
change you are suggesting here something that should require uploading
a new series version?

Eizan


From eizan at google.com  Sun Aug  8 20:23:37 2021
From: eizan at google.com (Eizan Miyamoto)
Date: Mon, 9 Aug 2021 13:23:37 +1000
Subject: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components
In-Reply-To: <0aff1abb-734f-c714-6ecc-c906862255c3@collabora.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
 <0aff1abb-734f-c714-6ecc-c906862255c3@collabora.com>
Message-ID: <CAOak1e8n6JpNKODfM57OTtbCNz8UBbj+wefwipVWP_Ep6SHmHA@mail.gmail.com>

Hi Dafna,

On Thu, Aug 5, 2021 at 4:40 PM Dafna Hirschfeld
<dafna.hirschfeld at collabora.com> wrote:
> > +int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
>
> This function can be static

If it's all the same to you, are you okay for me to make this change either:
- If upstream requests changes be made to this series, I will include
this suggestion
- If the series is accepted as-is, I will make a follow-up patch

This is to reduce workload on reviewers having to re-ack changes for
(what I hope you agree is) a nit.

If you don't agree, I will happily oblige and make the change and
upload a new version of the series.

> >       for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
> >               comp->clk[i] = of_clk_get(node, i);
>
> that iteration can be replaced with clk_bulk_get

As per Enric's suggestion in response to "propagate errors from
clock_on" in this series, are you okay for me to make the change in a
follow-up patch?

Thanks again for your review,

Eizan


From vilhelm.gray at gmail.com  Sun Aug  8 20:59:51 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon, 9 Aug 2021 12:59:51 +0900
Subject: [PATCH v14 06/17] counter: Internalize sysfs interface code
In-Reply-To: <20210808182325.2620de00@jic23-huawei>
References: <cover.1627990337.git.vilhelm.gray@gmail.com>
 <2df092636a9eea5a3ddae1e9a6429e32b51284f7.1627990337.git.vilhelm.gray@gmail.com>
 <20210808182325.2620de00@jic23-huawei>
Message-ID: <YRCoN5YZhytejzFh@shinobu>

On Sun, Aug 08, 2021 at 06:23:25PM +0100, Jonathan Cameron wrote:
> On Tue,  3 Aug 2021 21:06:16 +0900
> William Breathitt Gray <vilhelm.gray at gmail.com> wrote:
> 
> > This is a reimplementation of the Generic Counter driver interface.
> > There are no modifications to the Counter subsystem userspace interface,
> > so existing userspace applications should continue to run seamlessly.
> > 
> > The purpose of this patch is to internalize the sysfs interface code
> > among the various counter drivers into a shared module. Counter drivers
> > pass and take data natively (i.e. u8, u64, etc.) and the shared counter
> > module handles the translation between the sysfs interface and the
> > device drivers. This guarantees a standard userspace interface for all
> > counter drivers, and helps generalize the Generic Counter driver ABI in
> > order to support the Generic Counter chrdev interface (introduced in a
> > subsequent patch) without significant changes to the existing counter
> > drivers.
> > 
> > Note, Counter device registration is the same as before: drivers
> > populate a struct counter_device with components and callbacks, then
> > pass the structure to the devm_counter_register function. However,
> > what's different now is how the Counter subsystem code handles this
> > registration internally.
> > 
> > Whereas before callbacks would interact directly with sysfs data, this
> > interaction is now abstracted and instead callbacks interact with native
> > C data types. The counter_comp structure forms the basis for Counter
> > extensions.
> > 
> > The counter-sysfs.c file contains the code to parse through the
> > counter_device structure and register the requested components and
> > extensions. Attributes are created and populated based on type, with
> > respective translation functions to handle the mapping between sysfs and
> > the counter driver callbacks.
> > 
> > The translation performed for each attribute is straightforward: the
> > attribute type and data is parsed from the counter_attribute structure,
> > the respective counter driver read/write callback is called, and sysfs
> > I/O is handled before or after the driver read/write function is called.
> 
> Hi William,
> 
> There are some issues with this even after I've fixed the merge conflict
> because of the earlier change..
> 
>  DESCEND objtool
>   CALL    scripts/atomic/check-atomics.sh
>   CALL    scripts/checksyscalls.sh
>   CHK     include/generated/compile.h
>   CC [M]  drivers/counter/counter-core.o
>   CC [M]  drivers/counter/counter-sysfs.o
>   CC [M]  drivers/counter/104-quad-8.o
>   CC [M]  drivers/counter/interrupt-cnt.o
>   CC [M]  drivers/counter/stm32-timer-cnt.o
>   CC [M]  drivers/counter/stm32-lptimer-cnt.o
> drivers/counter/counter-core.c: In function ?counter_device_release?:
> drivers/counter/counter-core.c:23:9: error: implicit declaration of function ?counter_chrdev_remove? [-Werror=implicit-function-declaration]
>    23 |         counter_chrdev_remove(counter);
>       |         ^~~~~~~~~~~~~~~~~~~~~
> cc1: some warnings being treated as errors
> make[2]: *** [scripts/Makefile.build:271: drivers/counter/counter-core.o] Error 1
> make[2]: *** Waiting for unfinished jobs....
>   CHECK   drivers/counter/interrupt-cnt.c
>   CHECK   drivers/counter/104-quad-8.c
>   CHECK   drivers/counter/counter-sysfs.c
> drivers/counter/stm32-timer-cnt.c:55:9: warning: implicit conversion from ?enum stm32_count_function? to ?enum counter_function? [-Wenum-conversion]
>    55 |         STM32_COUNT_SLAVE_MODE_DISABLED,
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/counter/stm32-timer-cnt.c:56:9: warning: implicit conversion from ?enum stm32_count_function? to ?enum counter_function? [-Wenum-conversion]
>    56 |         STM32_COUNT_ENCODER_MODE_1,
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/counter/stm32-timer-cnt.c:57:9: warning: implicit conversion from ?enum stm32_count_function? to ?enum counter_function? [-Wenum-conversion]
>    57 |         STM32_COUNT_ENCODER_MODE_2,
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/counter/stm32-timer-cnt.c:58:9: warning: implicit conversion from ?enum stm32_count_function? to ?enum counter_function? [-Wenum-conversion]
>    58 |         STM32_COUNT_ENCODER_MODE_3,
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/counter/stm32-timer-cnt.c: In function ?stm32_count_function_read?:
> drivers/counter/stm32-timer-cnt.c:97:27: warning: implicit conversion from ?enum stm32_count_function? to ?enum counter_function? [-Wenum-conversion]
>    97 |                 *function = STM32_COUNT_SLAVE_MODE_DISABLED;
>       |                           ^
> drivers/counter/stm32-timer-cnt.c:100:27: warning: implicit conversion from ?enum stm32_count_function? to ?enum counter_function? [-Wenum-conversion]
>   100 |                 *function = STM32_COUNT_ENCODER_MODE_1;
>       |                           ^
> drivers/counter/stm32-timer-cnt.c:103:27: warning: implicit conversion from ?enum stm32_count_function? to ?enum counter_function? [-Wenum-conversion]
>   103 |                 *function = STM32_COUNT_ENCODER_MODE_2;
>       |                           ^
> drivers/counter/stm32-timer-cnt.c:106:27: warning: implicit conversion from ?enum stm32_count_function? to ?enum counter_function? [-Wenum-conversion]
>   106 |                 *function = STM32_COUNT_ENCODER_MODE_3;
>       |                           ^
> drivers/counter/stm32-lptimer-cnt.c:139:9: warning: implicit conversion from ?enum stm32_lptim_cnt_function? to ?enum counter_function? [-Wenum-conversion]
>   139 |         STM32_LPTIM_COUNTER_INCREASE,
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/counter/stm32-lptimer-cnt.c:140:9: warning: implicit conversion from ?enum stm32_lptim_cnt_function? to ?enum counter_function? [-Wenum-conversion]
>   140 |         STM32_LPTIM_ENCODER_BOTH_EDGE,
>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> drivers/counter/stm32-lptimer-cnt.c: In function ?stm32_lptim_cnt_function_read?:
> drivers/counter/stm32-lptimer-cnt.c:195:27: warning: implicit conversion from ?enum stm32_lptim_cnt_function? to ?enum counter_function? [-Wenum-conversion]
>   195 |                 *function = STM32_LPTIM_COUNTER_INCREASE;
>       |                           ^
> drivers/counter/stm32-lptimer-cnt.c:200:27: warning: implicit conversion from ?enum stm32_lptim_cnt_function? to ?enum counter_function? [-Wenum-conversion]
>   200 |                 *function = STM32_LPTIM_ENCODER_BOTH_EDGE;
>       |                           ^
> drivers/counter/104-quad-8.c:58: warning: Function parameter or member 'lock' not described in 'quad8'
>   CHECK   drivers/counter/stm32-timer-cnt.c
>   CHECK   drivers/counter/stm32-lptimer-cnt.c
> make[1]: *** [scripts/Makefile.build:514: drivers/counter] Error 2
> make: *** [Makefile:1841: drivers] Error 2
> 
> I could wait through these but it feels a little to likely I'll mess something up fixing things
> so please fix the errors and warnings this patch introduces
> with a W=1 C=1 build.
> 
> Also, do a patch by patch build of the rest of the set in case there are any other cases
> like this hiding.  It's very easy for these to build up when you have a lot of
> versions of a patch series.  I've been caught out a few times myself!
> 
> In the meantime, I'll keep the first 5 patches on my tree unless you shout otherwise.
> 
> Thanks,
> 
> Jonathan

Thanks,

I'll fix this up and submit a v15 to make sure these patches merge in
smoothly.

William Breathitt Gray
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210809/f1d4d409/attachment-0001.sig>

From viresh.kumar at linaro.org  Sun Aug  8 21:02:24 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 9 Aug 2021 09:32:24 +0530
Subject: [PATCH v2] cpufreq: armada-37xx: forbid cpufreq for 1.2 GHz
 variant
In-Reply-To: <20210808193026.xuyaufi5wqnrcakd@pali>
References: <20210630135942.29730-1-kabel@kernel.org>
 <20210630225601.6372-1-kabel@kernel.org>
 <20210702163035.nmb5pniwpqtmaz4b@pali>
 <20210708143451.4htvdop4zvjufrq6@pali>
 <20210715193321.z3vswz6x4rzvw2fd@pali>
 <20210808193026.xuyaufi5wqnrcakd@pali>
Message-ID: <20210809040224.j2rvopmmqda3utc5@vireshk-i7>

On 08-08-21, 21:30, Pali Roh?r wrote:
> Gentle reminder. This is really serious issue. Could you please look at it?
> 
> Adding more MarvellEmbeddedProcessors people to the loop: Evan, Benjamin an Igal

We can not hang forever for something that breaks stuff. Applied this for 5.14
now.

-- 
viresh


From amit.kachhap at arm.com  Sun Aug  8 21:15:32 2021
From: amit.kachhap at arm.com (Amit Kachhap)
Date: Mon, 9 Aug 2021 09:45:32 +0530
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210804060209.95817-1-liuqi115@huawei.com>
References: <20210804060209.95817-1-liuqi115@huawei.com>
Message-ID: <2fd3c78f-741a-4693-acae-4ea5465ad798@arm.com>

Hi Liu,

I am few minor comments.

On 8/4/21 11:32 AM, Qi Liu wrote:
> This patch introduce optprobe for ARM64. In optprobe, probed
> instruction is replaced by a branch instruction to detour
> buffer. Detour buffer contains trampoline code and a call to
> optimized_callback(). optimized_callback() calls opt_pre_handler()
> to execute kprobe handler.
> 
> Limitations:
> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
> guarantee the offset between probe point and kprobe pre_handler
> is not larger than 128MiB.
> 
> Performance of optprobe on Hip08 platform is test using kprobe
> example module[1] to analyze the latency of a kernel function,
> and here is the result:
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c

> +	 *
> +	 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
> +	 * According to ARM manual, branch instruction is:
> +	 *
> +	 *   31  30                  25              0
> +	 *  +----+---+---+---+---+---+---------------+
> +	 *  |cond| 0 | 0 | 1 | 0 | 1 |     imm26     |
> +	 *  +----+---+---+---+---+---+---------------+
> +	 *
> +	 * imm26 is a signed 26 bits integer. The real branch offset is computed
> +	 * by: imm64 = SignExtend(imm26:'00', 64);
> +	 *
> +	 * So the maximum forward branch should be:
> +	 *   (0x01ffffff << 2) = 1720x07fffffc =  0x07fffffc

7120x07fffffc ? Shouldn't it be just 0x07fffffc.

> +	 * The maximum backward branch should be:
> +	 *   (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
> +	 *
> +	 * We can simply check (rel & 0xf8000003):
> +	 *  if rel is positive, (rel & 0xf8000003) should be 0
> +	 *  if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
> +	 *  the last '3' is used for alignment checking.
> +	 */
> +	return (offset >= -0x08000000 && offset <= 0x07fffffc && !(offset & 0x3));
> +}
> +
> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
> +{
> +	kprobe_opcode_t *code;
> +	u32 insn;
> +	int ret, i;
> +	void *addrs[TMPL_END_IDX];
> +	void *addr;
> +
> +	code = get_optinsn_slot();
> +	if (!code)
> +		return -ENOMEM;
> +
> +	if (!is_offset_in_range((unsigned long)code,
> +				(unsigned long)orig->addr + 8))
> +		goto error;
> +
> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
> +				(unsigned long)optimized_callback))
> +		goto error;
> +
> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
> +				(unsigned long)op->kp.addr + 4))
> +		goto error;
> +
> +	/* Setup template */
> +	for (i = 0; i < TMPL_END_IDX; i++)
> +		addrs[i] = code + i;
> +
> +	ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
> +				      TMPL_END_IDX);

Here it copies nops for restore_orig_insn, restore_orig_insn and
again overwrites them with new values below.

> +	if (ret < 0)
> +		goto error;
> +
> +	/* Set probe information */
> +	addr = code + TMPL_VAL_IDX;
> +	insn =  (unsigned long long)op & 0xffffffff;
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	addr = addr + 4;
> +	insn = ((unsigned long long)op & GENMASK_ULL(63, 32)) >> 32;
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	addr = code + TMPL_CALL_BACK;
> +	insn =  aarch64_insn_gen_branch_imm((unsigned long)addr,
> +				(unsigned long)optimized_callback,
> +				AARCH64_INSN_BRANCH_LINK);
> +	aarch64_insn_patch_text(&addr, &insn, 1);
> +
> +	/* The original probed instruction */
> +	addr = code + TMPL_RESTORE_ORIGN_INSN;
> +	insn =  orig->opcode;
> +	aarch64_insn_patch_text(&addr, &insn, 1);

As commented above.

> +
> +	/* Jump back to next instruction */
> +	addr = code + TMPL_RESTORE_END;
> +	insn = aarch64_insn_gen_branch_imm(
> +				(unsigned long)(&code[TMPL_RESTORE_END]),
> +				(unsigned long)(op->kp.addr) + 4,
> +				AARCH64_INSN_BRANCH_NOLINK);
> +	aarch64_insn_patch_text(&addr, &insn, 1);

As commented above.

> +
> +	flush_icache_range((unsigned long)code,
> +			   (unsigned long)(&code[TMPL_END_IDX]));
> +	/* Set op->optinsn.insn means prepared. */
> +	op->optinsn.insn = code;
> +
> +	return 0;
> +
> +error:
> +	free_optinsn_slot(code, 0);
> +	return -ERANGE;
> +}
> +
> +void arch_optimize_kprobes(struct list_head *oplist)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		u32 insn;
> +
> +		WARN_ON(kprobe_disabled(&op->kp));
> +
> +		/*
> +		 * Backup instructions which will be replaced
> +		 * by jump address
> +		 */
> +		memcpy(op->optinsn.copied_insn, op->kp.addr,
> +			RELATIVEJUMP_SIZE);
> +		insn = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
> +				(unsigned long)op->optinsn.insn,
> +				AARCH64_INSN_BRANCH_NOLINK);
> +
> +		WARN_ON(insn == 0);
> +
> +		aarch64_insn_patch_text_nosync((void*)op->kp.addr, insn);
> +
> +		list_del_init(&op->list);
> +	}
> +}
> +
> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
> +{
> +	arch_arm_kprobe(&op->kp);
> +}
> +
> +/*
> + * Recover original instructions and breakpoints from relative jumps.
> + * Caller must call with locking kprobe_mutex.
> + */
> +void arch_unoptimize_kprobes(struct list_head *oplist,
> +			    struct list_head *done_list)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		arch_unoptimize_kprobe(op);
> +		list_move(&op->list, done_list);
> +	}
> +}
> +
> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
> +{
> +	if (op->optinsn.insn) {
> +		free_optinsn_slot(op->optinsn.insn, 1);
> +		op->optinsn.insn = NULL;
> +	}
> +}
> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
> new file mode 100644
> index 000000000000..13729cb279b8
> --- /dev/null
> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
> @@ -0,0 +1,80 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * trampoline entry and return code for optprobes.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/assembler.h>
> +
> +	.global optprobe_template_entry
> +optprobe_template_entry:
> +	sub sp, sp, #PT_REGS_SIZE
> +	stp x0, x1, [sp, #S_X0]
> +	stp x2, x3, [sp, #S_X2]
> +	stp x4, x5, [sp, #S_X4]
> +	stp x6, x7, [sp, #S_X6]
> +	stp x8, x9, [sp, #S_X8]
> +	stp x10, x11, [sp, #S_X10]
> +	stp x12, x13, [sp, #S_X12]
> +	stp x14, x15, [sp, #S_X14]
> +	stp x16, x17, [sp, #S_X16]
> +	stp x18, x19, [sp, #S_X18]
> +	stp x20, x21, [sp, #S_X20]
> +	stp x22, x23, [sp, #S_X22]
> +	stp x24, x25, [sp, #S_X24]
> +	stp x26, x27, [sp, #S_X26]
> +	stp x28, x29, [sp, #S_X28]
> +	add x0, sp, #PT_REGS_SIZE
> +	stp lr, x0, [sp, #S_LR]
> +	/*
> +	 * Construct a useful saved PSTATE
> +	 */
> +	mrs x0, nzcv
> +	mrs x1, daif
> +	orr x0, x0, x1
> +	mrs x1, CurrentEL
> +	orr x0, x0, x1
> +	mrs x1, SPSel
> +	orr x0, x0, x1
> +	stp xzr, x0, [sp, #S_PC]
> +	/* Get parameters to optimized_callback() */
> +	ldr	x0, 1f
> +	mov	x1, sp

Most of the codes here are same as save_all_base_regs macro in file
arch/arm64/kernel/probes/kprobes_trampoline.S. May be they
can be made common macros and kept in asm/assembler.h

> +	/* Branch to optimized_callback() */
> +	.global optprobe_template_call
> +optprobe_template_call:
> +	nop
> +        /* Restore registers */
> +	ldr x0, [sp, #S_PSTATE]
> +	and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
> +	msr nzcv, x0
> +	ldp x0, x1, [sp, #S_X0]
> +	ldp x2, x3, [sp, #S_X2]
> +	ldp x4, x5, [sp, #S_X4]
> +	ldp x6, x7, [sp, #S_X6]
> +	ldp x8, x9, [sp, #S_X8]
> +	ldp x10, x11, [sp, #S_X10]
> +	ldp x12, x13, [sp, #S_X12]
> +	ldp x14, x15, [sp, #S_X14]
> +	ldp x16, x17, [sp, #S_X16]
> +	ldp x18, x19, [sp, #S_X18]
> +	ldp x20, x21, [sp, #S_X20]
> +	ldp x22, x23, [sp, #S_X22]
> +	ldp x24, x25, [sp, #S_X24]
> +	ldp x26, x27, [sp, #S_X26]
> +	ldp x28, x29, [sp, #S_X28]
> +	ldr lr, [sp, #S_LR]
> +        add sp, sp, #PT_REGS_SIZE

Same as previous comment.

BR.
//Amit

> +	.global optprobe_template_restore_orig_insn
> +optprobe_template_restore_orig_insn:
> +	nop
> +	.global optprobe_template_restore_end
> +optprobe_template_restore_end:
> +	nop
> +	.global optprobe_template_end
> +optprobe_template_end:
> +	.global optprobe_template_val
> +optprobe_template_val:
> +	1:	.long 0
> +		.long 0
> 


From kishon at ti.com  Sun Aug  8 21:36:23 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Mon, 9 Aug 2021 10:06:23 +0530
Subject: [PATCH v2 5/6] misc: pci_endpoint_test: Do not request or
 allocate IRQs in probe
In-Reply-To: <20210805112639.GA20438@lpieralisi>
References: <20210803074932.19820-1-kishon@ti.com>
 <20210803074932.19820-6-kishon@ti.com> <20210803095839.GA11252@lpieralisi>
 <02c1ddb7-539e-20a0-1bef-e10e76922a0e@ti.com>
 <20210805112639.GA20438@lpieralisi>
Message-ID: <78b4c4df-0854-fe28-53bd-7629b0357637@ti.com>

Hi Lorenzo,

On 05/08/21 4:56 pm, Lorenzo Pieralisi wrote:
> On Wed, Aug 04, 2021 at 07:32:44PM +0530, Kishon Vijay Abraham I wrote:
>> Hi Lorenzo,
>>
>> On 03/08/21 3:28 pm, Lorenzo Pieralisi wrote:
>>> On Tue, Aug 03, 2021 at 01:19:31PM +0530, Kishon Vijay Abraham I wrote:
>>>> Allocation of IRQ vectors and requesting IRQ is done as part of
>>>> PCITEST_SET_IRQTYPE. Do not request or allocate IRQs in probe for
>>>> AM654 and J721E so that the user space test script has better control
>>>> of the devices for which the IRQs are configured. Since certain user
>>>> space scripts could rely on allocation of IRQ vectors during probe,
>>>> remove allocation of IRQs only for TI's K3 platform.
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>>>> ---
>>>>  drivers/misc/pci_endpoint_test.c | 19 +++++++++++++------
>>>>  1 file changed, 13 insertions(+), 6 deletions(-)
>>>
>>> I don't claim to understand the inner details of the endpoint test
>>> device but it looks like this approach should be redesigned.
>>>
>>> I don't believe using devices quirks is the best approach to
>>> expose/remove a feature to userspace, this can soon become
>>> unmaintenable.
>>>
>>> Maybe you can elaborate a bit more on what the real issue is please ?
>>
>> The actual reason for introducing this patch (affects only AM654 and
>> J721E) is due to Errata ID #i2101 GIC: ITS Misbehavior
>> (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf). So if more than 5
>> devices use GIC ITS simultaneously, GIC fails to raise interrupts.
>>
>> Though this patch is not an actual workaround for the issue (the
>> workaround is in GIC ITS driver provided in the errata document), it
>> helps to keep testing PCIe RC/EP using pci-endpoint-test even when
>> multiple pci-epf-test endpoint devices are connected (Normal test-setup
>> having J721E-J721E back to back connection can support 21 pci-epf-test
>> devices). So this patch lets user to individually enable interrupts for
>> each of the devices and could disable after the interrupt test.
>>
>> Since pci_endpoint_test is used only for testing PCIE RC/EP
>> communication and pci-endpoint-test has already implemented
>> PCITEST_SET_IRQTYPE for the userspace to enable interrupt, tried to not
>> enable the interrupts of all the devices by default in the probe (for
>> AM654 and J721E where this errata applies).
> 
> I understand - what I am asking is:
> 
> is it possible, instead of applying this patch, to make
> 
> pci_endpoint_test_alloc_irq_vectors() and pci_endpoint_test_request_irq()
> 
> fail in the target platforms instead of preventing to call them ?

hmm.. since both the platforms use GIC ITS it would need modifications
in the irq-gic-v3-its.c driver. I could add the workaround mentioned in
the errata document and send the patch for review to see what others think.

Thanks,
Kishon

> 
> My worry is that you may end up with more corner cases in the future
> and peppering code with is_() calls to work around them which does
> not look right.
> 
> Thanks,
> Lorenzo
> 
>> Thanks,
>> Kishon
>>
>>>
>>> Thanks,
>>> Lorenzo
>>>
>>>> diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
>>>> index c7ee34013485..9740f2a0e7cd 100644
>>>> --- a/drivers/misc/pci_endpoint_test.c
>>>> +++ b/drivers/misc/pci_endpoint_test.c
>>>> @@ -79,6 +79,9 @@
>>>>  #define PCI_DEVICE_ID_RENESAS_R8A774C0		0x002d
>>>>  #define PCI_DEVICE_ID_RENESAS_R8A774E1		0x0025
>>>>  
>>>> +#define is_j721e_pci_dev(pdev)         \
>>>> +		((pdev)->device == PCI_DEVICE_ID_TI_J721E)
>>>> +
>>>>  static DEFINE_IDA(pci_endpoint_test_ida);
>>>>  
>>>>  #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
>>>> @@ -810,9 +813,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
>>>>  
>>>>  	pci_set_master(pdev);
>>>>  
>>>> -	if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
>>>> -		err = -EINVAL;
>>>> -		goto err_disable_irq;
>>>> +	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
>>>> +		if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) {
>>>> +			err = -EINVAL;
>>>> +			goto err_disable_irq;
>>>> +		}
>>>>  	}
>>>>  
>>>>  	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
>>>> @@ -850,9 +855,11 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
>>>>  		goto err_ida_remove;
>>>>  	}
>>>>  
>>>> -	if (!pci_endpoint_test_request_irq(test)) {
>>>> -		err = -EINVAL;
>>>> -		goto err_kfree_test_name;
>>>> +	if (!(is_am654_pci_dev(pdev) || is_j721e_pci_dev(pdev))) {
>>>> +		if (!pci_endpoint_test_request_irq(test)) {
>>>> +			err = -EINVAL;
>>>> +			goto err_kfree_test_name;
>>>> +		}
>>>>  	}
>>>>  
>>>>  	misc_device = &test->miscdev;
>>>> -- 
>>>> 2.17.1
>>>>


From kishon at ti.com  Sun Aug  8 21:38:47 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Mon, 9 Aug 2021 10:08:47 +0530
Subject: [PATCH v2 1/3] dt-bindings: PCI: ti,j721e: Add bindings to
 specify legacy interrupts
In-Reply-To: <87im0lw8qy.wl-maz@kernel.org>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-2-kishon@ti.com> <87im0lw8qy.wl-maz@kernel.org>
Message-ID: <14717d53-1727-509c-9a62-02c1e8c5736e@ti.com>

Hi Marc,

On 04/08/21 8:35 pm, Marc Zyngier wrote:
> On Wed, 04 Aug 2021 14:29:10 +0100,
> Kishon Vijay Abraham I <kishon at ti.com> wrote:
>>
>> Add bindings to specify interrupt controller for legacy interrupts.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>> ---
>>  .../bindings/pci/ti,j721e-pci-host.yaml           | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> index cc900202df29..f461d7b4c0cc 100644
>> --- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> +++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> @@ -74,6 +74,11 @@ properties:
>>  
>>    msi-map: true
>>  
>> +patternProperties:
>> +  "interrupt-controller":
>> +    type: object
>> +    description: interrupt controller to handle legacy interrupts.
>> +
>>  required:
>>    - compatible
>>    - reg
>> @@ -97,6 +102,8 @@ unevaluatedProperties: false
>>  
>>  examples:
>>    - |
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/interrupt-controller/irq.h>
>>      #include <dt-bindings/soc/ti,sci_pm_domain.h>
>>      #include <dt-bindings/gpio/gpio.h>
>>  
>> @@ -131,5 +138,13 @@ examples:
>>              ranges = <0x01000000 0x0 0x10001000  0x00 0x10001000  0x0 0x0010000>,
>>                       <0x02000000 0x0 0x10011000  0x00 0x10011000  0x0 0x7fef000>;
>>              dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
>> +
>> +
>> +            pcie0_intc: interrupt-controller {
>> +                    interrupt-controller;
>> +                    #interrupt-cells = <1>;
>> +                    interrupt-parent = <&gic500>;
>> +                    interrupts = <GIC_SPI 312 IRQ_TYPE_EDGE_RISING>;
> 
> Are you sure about the edge signalling? How is the interrupt
> retriggered when the input is still high, which could well be the case
> for shared INTx?

There is a EOI register which is used for re-triggering the interrupt.
That functionality is broken in J721E but is fixed in J7200 (the
following two patches in the series deals with that).

Thanks,
Kishon


From kishon at ti.com  Sun Aug  8 21:50:10 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Mon, 9 Aug 2021 10:20:10 +0530
Subject: [PATCH v2 2/3] PCI: j721e: Add PCI legacy interrupt support for
 J721E
In-Reply-To: <87h7g5w8d8.wl-maz@kernel.org>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-3-kishon@ti.com> <87h7g5w8d8.wl-maz@kernel.org>
Message-ID: <c20be7ae-e4a7-c3ba-f1c9-e4ff2aae0a66@ti.com>

Hi Marc,

On 04/08/21 8:43 pm, Marc Zyngier wrote:
> On Wed, 04 Aug 2021 14:29:11 +0100,
> Kishon Vijay Abraham I <kishon at ti.com> wrote:
>>
>> Add PCI legacy interrupt support for J721E. J721E has a single HW
>> interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
>> The HW interrupt line connected to GIC is a pulse interrupt whereas
>> the legacy interrupts by definition is level interrupt. In order to
>> provide level interrupt functionality to edge interrupt line, PCIe
>> in J721E has provided IRQ_EOI register.
>>
>> However due to Errata ID #i2094 ([1]), EOI feature is not enabled in HW
>> and only a single pulse interrupt will be generated for every
>> ASSERT_INTx/DEASSERT_INTx.
> 
> So my earlier remark stands. If you get a single edge, how do you
> handle a level that is still high after having handled the interrupt
> on hardware that has this bug?

Right, this hardware (J721E) has a bug but was fixed in J7200 (Patch 3/3
handles that).
> 
>>
>> [1] -> J721E DRA829/TDA4VM Processors Silicon Revision 1.1/1.0 SPRZ455A ?
>>        DECEMBER 2020 ? REVISED AUGUST 2021
>>        (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf)
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>> ---
>>  drivers/pci/controller/cadence/pci-j721e.c | 85 ++++++++++++++++++++++
>>  1 file changed, 85 insertions(+)
>>
>> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
>> index 2ec037c43bd5..c2e7a78dc31f 100644
>> --- a/drivers/pci/controller/cadence/pci-j721e.c
>> +++ b/drivers/pci/controller/cadence/pci-j721e.c
>> @@ -29,6 +29,13 @@
>>  #define LINK_DOWN		BIT(1)
>>  #define J7200_LINK_DOWN		BIT(10)
>>  
>> +#define EOI_REG			0x10
>> +
>> +#define ENABLE_REG_SYS_0	0x100
>> +#define STATUS_REG_SYS_0	0x500
>> +#define STATUS_CLR_REG_SYS_0	0x700
>> +#define INTx_EN(num)		(1 << (num))
>> +
>>  #define J721E_PCIE_USER_CMD_STATUS	0x4
>>  #define LINK_TRAINING_ENABLE		BIT(0)
>>  
>> @@ -59,6 +66,7 @@ struct j721e_pcie {
>>  	void __iomem		*user_cfg_base;
>>  	void __iomem		*intd_cfg_base;
>>  	u32			linkdown_irq_regfield;
>> +	struct irq_domain	*legacy_irq_domain;
>>  };
>>  
>>  enum j721e_pcie_mode {
>> @@ -121,6 +129,79 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
>>  	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
>>  }
>>  
>> +static void j721e_pcie_v1_legacy_irq_handler(struct irq_desc *desc)
>> +{
>> +	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
>> +	struct irq_chip *chip = irq_desc_get_chip(desc);
>> +	int i, virq;
>> +	u32 reg;
>> +
>> +	chained_irq_enter(chip, desc);
>> +
>> +	for (i = 0; i < PCI_NUM_INTX; i++) {
>> +		reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_0);
>> +		if (!(reg & INTx_EN(i)))
>> +			continue;
> 
> Why do you need to perform multiple reads? Surely reg contains all the
> bits you need, doesn't it?

Right, will fix it up.
> 
>> +
>> +		virq = irq_find_mapping(pcie->legacy_irq_domain, 3 - i);
>> +		generic_handle_irq(virq);
> 
> Please combine both lines into a single generic_handle_domain_irq()
> call.

Okay.
> 
>> +		j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_0, INTx_EN(i));
> 
> What is the purpose of this write? It feels like this should be a
> irq_eoi callback.

It's an IRQ ACK, since in this platform the level to edge is not
implemented properly in HW.
> 
>> +	}
>> +
>> +	chained_irq_exit(chip, desc);
>> +}
>> +
>> +static int j721e_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq)
>> +{
>> +	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
> 
> An INTx interrupt is a level interrupt. Please use the corresponding flow.

Okay.
> 
>> +	irq_set_chip_data(irq, domain->host_data);
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct irq_domain_ops j721e_pcie_intx_domain_ops = {
>> +	.map = j721e_pcie_intx_map,
>> +};
>> +
>> +static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
>> +{
>> +	struct irq_domain *legacy_irq_domain;
>> +	struct device *dev = pcie->dev;
>> +	struct device_node *node = dev->of_node;
>> +	struct device_node *intc_node;
>> +	int irq, i;
>> +	u32 reg;
>> +
>> +	intc_node = of_get_child_by_name(node, "interrupt-controller");
>> +	if (!intc_node) {
>> +		dev_dbg(dev, "interrupt-controller node is absent. Legacy INTR not supported\n");
>> +		return 0;
>> +	}
>> +
>> +	irq = irq_of_parse_and_map(intc_node, 0);
>> +	if (!irq) {
>> +		dev_err(dev, "Failed to parse and map legacy irq\n");
>> +		return -EINVAL;
>> +	}
>> +	irq_set_chained_handler_and_data(irq, j721e_pcie_v1_legacy_irq_handler, pcie);
>> +
>> +	legacy_irq_domain = irq_domain_add_linear(intc_node, PCI_NUM_INTX,
>> +						  &j721e_pcie_intx_domain_ops, pcie);
>> +	if (!legacy_irq_domain) {
>> +		dev_err(dev, "Failed to add irq domain for legacy irqs\n");
>> +		return -EINVAL;
>> +	}
>> +	pcie->legacy_irq_domain = legacy_irq_domain;
>> +
>> +	for (i = 0; i < PCI_NUM_INTX; i++) {
>> +		reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_0);
>> +		reg |= INTx_EN(i);
>> +		j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_0, reg);
>> +	}
> 
> This should be moved to the irq_unmask() callback.

Should we also have a corresponding irq_mask()? Then would require us
implement reference counting since legacy interrupts are shared.

Thanks,
Kishon


From sudeep.holla at arm.com  Sun Aug  8 21:57:36 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon,  9 Aug 2021 05:57:36 +0100
Subject: [PATCH v7 00/15] Introduce SCMI transport based on VirtIO
In-Reply-To: <20210803131024.40280-1-cristian.marussi@arm.com>
References: <20210803131024.40280-1-cristian.marussi@arm.com>
Message-ID: <162848483974.232214.9506203742448269364.b4-ty@arm.com>

On Tue, 3 Aug 2021 14:10:09 +0100, Cristian Marussi wrote:
> While reworking this series starting from the work done up to V3 by
> OpenSynergy, I am keeping the original autorship and list distribution
> unchanged.
> 
> The main aim of this rework, as said, is to simplify where possible the
> SCMI VirtIO support added in V3 by adding at first some new general
> mechanisms in the SCMI Transport layer.
> 
> [...]

Applied to sudeep.holla/linux (for-next/scmi), thanks!

[01/15] firmware: arm_scmi: Add support for type handling in common functions
        https://git.kernel.org/sudeep.holla/c/63b282f172
[02/15] firmware: arm_scmi: Remove scmi_dump_header_dbg() helper
        https://git.kernel.org/sudeep.holla/c/3669032514
[03/15] firmware: arm_scmi: Add optional transport_init/exit support
        https://git.kernel.org/sudeep.holla/c/ceac257db0
[04/15] firmware: arm_scmi: Introduce monotonically increasing tokens
        https://git.kernel.org/sudeep.holla/c/9ca5a1838e
[05/15] firmware: arm_scmi: Handle concurrent and out-of-order messages
        https://git.kernel.org/sudeep.holla/c/ed7c04c1fe
[06/15] firmware: arm_scmi: Make .clear_channel optional
        https://git.kernel.org/sudeep.holla/c/e9b21c9618
[07/15] firmware: arm_scmi: Make polling mode optional
        https://git.kernel.org/sudeep.holla/c/2930abcffd
[08/15] firmware: arm_scmi: Make SCMI transports configurable
        https://git.kernel.org/sudeep.holla/c/e8419c24ba
[09/15] firmware: arm_scmi: Make shmem support optional for transports
        https://git.kernel.org/sudeep.holla/c/a7b1138b92
[10/15] firmware: arm_scmi: Add method to override max message number
        https://git.kernel.org/sudeep.holla/c/c92c3e382e
[11/15] firmware: arm_scmi: Add message passing abstractions for transports
        https://git.kernel.org/sudeep.holla/c/f301bba0ca
[12/15] firmware: arm_scmi: Add optional link_supplier() transport op
        https://git.kernel.org/sudeep.holla/c/7885281260
[13/15] dt-bindings: arm: Add virtio transport for SCMI
        https://git.kernel.org/sudeep.holla/c/60625667c4
[14/15] firmware: arm_scmi: Add priv parameter to scmi_rx_callback
        https://git.kernel.org/sudeep.holla/c/13fba878cc
[15/15] firmware: arm_scmi: Add virtio transport
        https://git.kernel.org/sudeep.holla/c/46abe13b5e

--

Regards,
Sudeep



From sudeep.holla at arm.com  Sun Aug  8 22:00:57 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon,  9 Aug 2021 06:00:57 +0100
Subject: [PATCH v3] firmware: arm_scmi: Free mailbox channels if probe
 fails
In-Reply-To: <1628111999-21595-1-git-send-email-rishabhb@codeaurora.org>
References: <1628111999-21595-1-git-send-email-rishabhb@codeaurora.org>
Message-ID: <162848516052.232525.343233021782950735.b4-ty@arm.com>

On Wed, 4 Aug 2021 14:19:59 -0700, Rishabh Bhatnagar wrote:
> Mailbox channels for the base protocol are setup during probe.
> There can be a scenario where probe fails to acquire the base
> protocol due to a timeout leading to cleaning up of all device
> managed memory including the scmi_mailbox structure setup during
> mailbox_chan_setup function.
> [   12.735104]arm-scmi soc:qcom,scmi: timed out in resp(caller: version_get+0x84/0x140)
> [   12.735224]arm-scmi soc:qcom,scmi: unable to communicate with SCMI
> [   12.735947]arm-scmi: probe of soc:qcom,scmi failed with error -110
> 
> [...]

Applied to sudeep.holla/linux (for-next/scmi), thanks!

[1/1] firmware: arm_scmi: Free mailbox channels if probe fails
      https://git.kernel.org/sudeep.holla/c/1e7cbfaa66

--
Regards,
Sudeep



From sudeep.holla at arm.com  Sun Aug  8 22:08:14 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon,  9 Aug 2021 06:08:14 +0100
Subject: [PATCH] firmware: arm_scmi: fix boolconv.cocci warnings
In-Reply-To: <20210807173127.GA43248@a24dbc127934>
References: <202108080108.k5pHZ040-lkp@intel.com>
 <20210807173127.GA43248@a24dbc127934>
Message-ID: <162848564301.232921.17556433266830316474.b4-ty@arm.com>

On Sun, 8 Aug 2021 01:31:27 +0800, kernel test robot wrote:
> drivers/firmware/arm_scmi/virtio.c:225:40-45: WARNING: conversion to bool not needed here
> 
>  Remove unneeded conversion to bool
> 
> Semantic patch information:
>  Relational and logical operators evaluate to bool,
>  explicit conversion is overly verbose and unneeded.
> 
> [...]

Applied to sudeep.holla/linux (for-next/scmi), thanks!

[1/1] firmware: arm_scmi: fix boolconv.cocci warnings
      https://git.kernel.org/sudeep.holla/c/d4fda7ec1d

--
Regards,
Sudeep



From qiangqing.zhang at nxp.com  Sun Aug  8 22:08:50 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Mon, 9 Aug 2021 05:08:50 +0000
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
Message-ID: <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>


Hi Florian,

> -----Original Message-----
> From: Florian Fainelli <f.fainelli at gmail.com>
> Sent: 2021?8?5? 17:18
> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
> netdev at vger.kernel.org; devicetree at vger.kernel.org;
> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
> wakeup-irq" property
> 
> 
> 
> On 8/5/2021 12:46 AM, Joakim Zhang wrote:
> > Add "fsl,wakeup-irq" property for FEC controller to select wakeup irq
> > source.
> >
> > Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
> > Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
> 
> Why are not you making use of the standard interrupts-extended property
> which allows different interrupt lines to be originating from different interrupt
> controllers, e.g.:
> 
> interrupts-extended = <&gic GIC_SPI 112 4>, <&wakeup_intc 0>;

Thanks.

AFAIK, interrupts-extended should be used instead of interrupts when a device is connected to multiple interrupt controllers
as it encodes a parent phandle with each interrupt specifier. However, for FEC controller, all interrupt lines are originating from
the same interrupt controllers.

1) FEC controller has up to 4 interrupt lines and all of these are routed to GIC interrupt controller.
2) FEC has a wakeup interrupt signal and always are mixed with other interrupt signals, and then output to one interrupt line.
3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but for i.MX8M serials, are mixed to int2 line.
4) Now driver treat int0 as the wakeup source by default, it is broken for i.MX8M.

Best Regards,
Joakim Zhang
> --
> Florian

From rashmi.a at intel.com  Sun Aug  8 22:16:09 2021
From: rashmi.a at intel.com (A, Rashmi)
Date: Mon, 9 Aug 2021 05:16:09 +0000
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
Message-ID: <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Ulf Hansson <ulf.hansson at linaro.org>
> Sent: Friday, August 6, 2021 6:36 PM
> To: A, Rashmi <rashmi.a at intel.com>
> Cc: linux-drivers-review-request at eclists.intel.com; Michal Simek
> <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
> kernel at vger.kernel.org>; Kishon <kishon at ti.com>; Vinod Koul
> <vkoul at kernel.org>; Andy Shevchenko
> <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org; Mark
> Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou, Furong
> <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> <adrian.hunter at intel.com>; Vaidya, Mahesh R
> <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> <kenchappa.demakkanavar at intel.com>
> Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
> support to the arasan eMMC driver
> 
> On Fri, 30 Jul 2021 at 08:33, <rashmi.a at intel.com> wrote:
> >
> > From: Rashmi A <rashmi.a at intel.com>
> >
> > Intel Thunder Bay SoC eMMC controller is based on Arasan eMMC 5.1 host
> > controller IP
> >
> > Signed-off-by: Rashmi A <rashmi.a at intel.com>
> > Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>
> 
> Rashmi, is it safe to apply this separately from the phy driver/dt changes?
> Then I can queue this via my mmc tree, if you like.
No, the phy driver/dt changes must go together with "mmc: sdhci-of-arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver" patch.

Regards
Rashmi
> 
> Kind regards
> Uffe
> 
> > ---
> >  drivers/mmc/host/sdhci-of-arasan.c | 29
> ++++++++++++++++++++++++++++-
> >  1 file changed, 28 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-of-arasan.c
> > b/drivers/mmc/host/sdhci-of-arasan.c
> > index 839965f7c717..6f202fb7a546 100644
> > --- a/drivers/mmc/host/sdhci-of-arasan.c
> > +++ b/drivers/mmc/host/sdhci-of-arasan.c
> > @@ -185,6 +185,13 @@ static const struct sdhci_arasan_soc_ctl_map
> intel_lgm_sdxc_soc_ctl_map = {
> >         .hiword_update = false,
> >  };
> >
> > +static const struct sdhci_arasan_soc_ctl_map thunderbay_soc_ctl_map = {
> > +       .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
> > +       .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
> > +       .support64b = { .reg = 0x4, .width = 1, .shift = 24 },
> > +       .hiword_update = false,
> > +};
> > +
> >  static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map
> = {
> >         .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
> >         .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 }, @@
> > -430,6 +437,15 @@ static const struct sdhci_pltfm_data
> sdhci_arasan_cqe_pdata = {
> >                         SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
> >  };
> >
> > +static const struct sdhci_pltfm_data sdhci_arasan_thunderbay_pdata = {
> > +       .ops = &sdhci_arasan_cqe_ops,
> > +       .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
> SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
> > +       .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
> > +               SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
> > +               SDHCI_QUIRK2_STOP_WITH_TC |
> > +               SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400,
> > +};
> > +
> >  #ifdef CONFIG_PM_SLEEP
> >  /**
> >   * sdhci_arasan_suspend - Suspend method for the driver @@ -1098,6
> > +1114,12 @@ static struct sdhci_arasan_of_data
> sdhci_arasan_generic_data = {
> >         .clk_ops = &arasan_clk_ops,
> >  };
> >
> > +static const struct sdhci_arasan_of_data sdhci_arasan_thunderbay_data =
> {
> > +       .soc_ctl_map = &thunderbay_soc_ctl_map,
> > +       .pdata = &sdhci_arasan_thunderbay_pdata,
> > +       .clk_ops = &arasan_clk_ops,
> > +};
> > +
> >  static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = {
> >         .ops = &sdhci_arasan_cqe_ops,
> >         .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | @@ -1231,6
> > +1253,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
> >                 .compatible = "intel,keembay-sdhci-5.1-sdio",
> >                 .data = &intel_keembay_sdio_data,
> >         },
> > +       {
> > +               .compatible = "intel,thunderbay-sdhci-5.1",
> > +               .data = &sdhci_arasan_thunderbay_data,
> > +       },
> >         /* Generic compatible below here */
> >         {
> >                 .compatible = "arasan,sdhci-8.9a", @@ -1582,7 +1608,8
> > @@ static int sdhci_arasan_probe(struct platform_device *pdev)
> >
> >         if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
> >             of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
> > -           of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {
> > +           of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio") ||
> > +           of_device_is_compatible(np, "intel,thunderbay-sdhci-5.1"))
> > + {
> >                 sdhci_arasan_update_clockmultiplier(host, 0x0);
> >                 sdhci_arasan_update_support64b(host, 0x0);
> >
> > --
> > 2.17.1
> >

From tinghan.shen at mediatek.com  Sun Aug  8 22:19:55 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Mon, 9 Aug 2021 13:19:55 +0800
Subject: [PATCH v6 2/6] dt-bindings: remoteproc: mediatek: Add binding for
 mt8192 scp
In-Reply-To: <20210809051959.31136-1-tinghan.shen@mediatek.com>
References: <20210809051959.31136-1-tinghan.shen@mediatek.com>
Message-ID: <20210809051959.31136-3-tinghan.shen@mediatek.com>

Add mt8192 compatible to binding document.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
index d64466eefbe3..88f37dee7bca 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
@@ -7,14 +7,17 @@ Mediatek SoCs.
 Required properties:
 - compatible		Should be one of:
 				"mediatek,mt8183-scp"
+				"mediatek,mt8192-scp"
 				"mediatek,mt8195-scp"
 - reg			Should contain the address ranges for memory regions:
 			SRAM, CFG, and L1TCM.
 - reg-names		Contains the corresponding names for the memory regions:
 			"sram", "cfg", and "l1tcm".
-- clocks		Required by mt8183. Clock for co-processor (See: ../clock/clock-bindings.txt)
-- clock-names		Required by mt8183. Contains the corresponding name for the clock. This
-			should be named "main".
+- clocks		Required by mt8183 and mt8192. Clock for co-processor
+			(See: ../clock/clock-bindings.txt)
+- clock-names		Required by mt8183 and mt8192. Contains the
+			corresponding name for the clock. This should be
+			named "main".
 
 Subnodes
 --------
-- 
2.18.0

From tinghan.shen at mediatek.com  Sun Aug  8 22:19:58 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Mon, 9 Aug 2021 13:19:58 +0800
Subject: [PATCH v6 5/6] rpmsg: change naming of mediatek rpmsg property
In-Reply-To: <20210809051959.31136-1-tinghan.shen@mediatek.com>
References: <20210809051959.31136-1-tinghan.shen@mediatek.com>
Message-ID: <20210809051959.31136-6-tinghan.shen@mediatek.com>

Change from "mtk,rpmsg-name" to "mediatek,rpmsg-name" to sync with the
vendor name defined in vendor-prefixes.yaml.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 drivers/rpmsg/mtk_rpmsg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c
index 96a17ec29140..5b4404b8be4c 100644
--- a/drivers/rpmsg/mtk_rpmsg.c
+++ b/drivers/rpmsg/mtk_rpmsg.c
@@ -183,7 +183,7 @@ mtk_rpmsg_match_device_subnode(struct device_node *node, const char *channel)
 	int ret;
 
 	for_each_available_child_of_node(node, child) {
-		ret = of_property_read_string(child, "mtk,rpmsg-name", &name);
+		ret = of_property_read_string(child, "mediatek,rpmsg-name", &name);
 		if (ret)
 			continue;
 
-- 
2.18.0

From tinghan.shen at mediatek.com  Sun Aug  8 22:19:54 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Mon, 9 Aug 2021 13:19:54 +0800
Subject: [PATCH v6 1/6] dt-bindings: remoteproc: mediatek: Add binding for
 mt8195 scp
In-Reply-To: <20210809051959.31136-1-tinghan.shen@mediatek.com>
References: <20210809051959.31136-1-tinghan.shen@mediatek.com>
Message-ID: <20210809051959.31136-2-tinghan.shen@mediatek.com>

Add mt8195 compatible to binding document. The description of required
properties are also modified to reflect the hardware change between
mt8183 and mt8195. The mt8195 doesn't have to control the scp clock on
kernel side.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
index 3f5f78764b60..d64466eefbe3 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
@@ -5,13 +5,15 @@ This binding provides support for ARM Cortex M4 Co-processor found on some
 Mediatek SoCs.
 
 Required properties:
-- compatible		Should be "mediatek,mt8183-scp"
+- compatible		Should be one of:
+				"mediatek,mt8183-scp"
+				"mediatek,mt8195-scp"
 - reg			Should contain the address ranges for memory regions:
 			SRAM, CFG, and L1TCM.
 - reg-names		Contains the corresponding names for the memory regions:
 			"sram", "cfg", and "l1tcm".
-- clocks		Clock for co-processor (See: ../clock/clock-bindings.txt)
-- clock-names		Contains the corresponding name for the clock. This
+- clocks		Required by mt8183. Clock for co-processor (See: ../clock/clock-bindings.txt)
+- clock-names		Required by mt8183. Contains the corresponding name for the clock. This
 			should be named "main".
 
 Subnodes
-- 
2.18.0

From tinghan.shen at mediatek.com  Sun Aug  8 22:19:57 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Mon, 9 Aug 2021 13:19:57 +0800
Subject: [PATCH v6 4/6] remoteproc: mediatek: Support mt8195 scp
In-Reply-To: <20210809051959.31136-1-tinghan.shen@mediatek.com>
References: <20210809051959.31136-1-tinghan.shen@mediatek.com>
Message-ID: <20210809051959.31136-5-tinghan.shen@mediatek.com>

The SCP clock design is changed on mt8195 that doesn't need to control
SCP clock on kernel side.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Reviewed-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 drivers/remoteproc/mtk_common.h |  1 +
 drivers/remoteproc/mtk_scp.c    | 48 +++++++++++++++++++++++++++++----
 2 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 61901f5efa05..5ff3867c72f3 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -72,6 +72,7 @@ struct scp_ipi_desc {
 struct mtk_scp;
 
 struct mtk_scp_of_data {
+	int (*scp_clk_get)(struct mtk_scp *scp);
 	int (*scp_before_load)(struct mtk_scp *scp);
 	void (*scp_irq_handler)(struct mtk_scp *scp);
 	void (*scp_reset_assert)(struct mtk_scp *scp);
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 9679cc26895e..36e48cf58ed6 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -312,6 +312,32 @@ static int scp_elf_read_ipi_buf_addr(struct mtk_scp *scp,
 	return -ENOENT;
 }
 
+static int mt8183_scp_clk_get(struct mtk_scp *scp)
+{
+	struct device *dev = scp->dev;
+	int ret = 0;
+
+	scp->clk = devm_clk_get(dev, "main");
+	if (IS_ERR(scp->clk)) {
+		dev_err(dev, "Failed to get clock\n");
+		ret = PTR_ERR(scp->clk);
+	}
+
+	return ret;
+}
+
+static int mt8192_scp_clk_get(struct mtk_scp *scp)
+{
+	return mt8183_scp_clk_get(scp);
+}
+
+static int mt8195_scp_clk_get(struct mtk_scp *scp)
+{
+	scp->clk = NULL;
+
+	return 0;
+}
+
 static int mt8183_scp_before_load(struct mtk_scp *scp)
 {
 	/* Clear SCP to host interrupt */
@@ -785,12 +811,9 @@ static int scp_probe(struct platform_device *pdev)
 	if (ret)
 		goto destroy_mutex;
 
-	scp->clk = devm_clk_get(dev, "main");
-	if (IS_ERR(scp->clk)) {
-		dev_err(dev, "Failed to get clock\n");
-		ret = PTR_ERR(scp->clk);
+	ret = scp->data->scp_clk_get(scp);
+	if (ret)
 		goto release_dev_mem;
-	}
 
 	/* register SCP initialization IPI */
 	ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp);
@@ -852,6 +875,7 @@ static int scp_remove(struct platform_device *pdev)
 }
 
 static const struct mtk_scp_of_data mt8183_of_data = {
+	.scp_clk_get = mt8183_scp_clk_get,
 	.scp_before_load = mt8183_scp_before_load,
 	.scp_irq_handler = mt8183_scp_irq_handler,
 	.scp_reset_assert = mt8183_scp_reset_assert,
@@ -864,6 +888,19 @@ static const struct mtk_scp_of_data mt8183_of_data = {
 };
 
 static const struct mtk_scp_of_data mt8192_of_data = {
+	.scp_clk_get = mt8192_scp_clk_get,
+	.scp_before_load = mt8192_scp_before_load,
+	.scp_irq_handler = mt8192_scp_irq_handler,
+	.scp_reset_assert = mt8192_scp_reset_assert,
+	.scp_reset_deassert = mt8192_scp_reset_deassert,
+	.scp_stop = mt8192_scp_stop,
+	.scp_da_to_va = mt8192_scp_da_to_va,
+	.host_to_scp_reg = MT8192_GIPC_IN_SET,
+	.host_to_scp_int_bit = MT8192_HOST_IPC_INT_BIT,
+};
+
+static const struct mtk_scp_of_data mt8195_of_data = {
+	.scp_clk_get = mt8195_scp_clk_get,
 	.scp_before_load = mt8192_scp_before_load,
 	.scp_irq_handler = mt8192_scp_irq_handler,
 	.scp_reset_assert = mt8192_scp_reset_assert,
@@ -877,6 +914,7 @@ static const struct mtk_scp_of_data mt8192_of_data = {
 static const struct of_device_id mtk_scp_of_match[] = {
 	{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
 	{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
+	{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
-- 
2.18.0

From tinghan.shen at mediatek.com  Sun Aug  8 22:19:53 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Mon, 9 Aug 2021 13:19:53 +0800
Subject: [PATCH v6 0/6] Mediatek MT8195 SCP support
Message-ID: <20210809051959.31136-1-tinghan.shen@mediatek.com>

Change since v5:
- Drop adding new vendor-prefix
- Rename rpmsg property from "mtk," to "mediatek," to use the name defined in 
  vendor-prefix.yaml for Mediatek Co.

Changes since v4:
- Move clock acquirement to mtk_scp_of_data
- Add new vendor-prefix for Mediatek SCP
- Refine mtk,scp.yaml
  - Remove '|' in 'description'
  - Add 'items' to replace 'description' in reg-names property
  - Add 'const' to replace 'description' in clock-names property
  - Add required property for mt8183 and mt8192
  - Rewrite 'patternProperties' by 'additionalProperties'
  - Rewrite example with 1 address and size-cell.
  - Drop dts label from example 

Changes since v3:
- Add missing patch version in mail subject
- No change to patches.

Changes since v2:
- Add compatible for mt8192
- Convert mtk,scp.txt to mtk,scp.yaml 
- Refine clock checking method

Changes since v1:
- Fix missing 'compatible' line in binding document

Tinghan Shen (6):
  dt-bindings: remoteproc: mediatek: Add binding for mt8195 scp
  dt-bindings: remoteproc: mediatek: Add binding for mt8192 scp
  dt-bindings: remoteproc: mediatek: Convert mtk,scp to json-schema
  remoteproc: mediatek: Support mt8195 scp
  rpmsg: change naming of mediatek rpmsg property
  arm64: dts: mt8183: change rpmsg property name

 .../bindings/remoteproc/mtk,scp.txt           | 36 --------
 .../bindings/remoteproc/mtk,scp.yaml          | 92 +++++++++++++++++++
 .../arm64/boot/dts/mediatek/mt8183-kukui.dtsi |  2 +-
 drivers/remoteproc/mtk_common.h               |  1 +
 drivers/remoteproc/mtk_scp.c                  | 48 +++++++++-
 drivers/rpmsg/mtk_rpmsg.c                     |  2 +-
 6 files changed, 138 insertions(+), 43 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
 create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml

-- 
2.18.0

From tinghan.shen at mediatek.com  Sun Aug  8 22:19:59 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Mon, 9 Aug 2021 13:19:59 +0800
Subject: [PATCH v6 6/6] arm64: dts: mt8183: change rpmsg property name
In-Reply-To: <20210809051959.31136-1-tinghan.shen@mediatek.com>
References: <20210809051959.31136-1-tinghan.shen@mediatek.com>
Message-ID: <20210809051959.31136-7-tinghan.shen@mediatek.com>

The rpmsg property name is changed to "mediatek," to sync with the
vendor name defined in vendor-prefixes.yaml.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index ae549d55a94f..30df2754be6d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -752,7 +752,7 @@
 
 	cros_ec {
 		compatible = "google,cros-ec-rpmsg";
-		mtk,rpmsg-name = "cros-ec-rpmsg";
+		mediatek,rpmsg-name = "cros-ec-rpmsg";
 	};
 };
 
-- 
2.18.0

From tinghan.shen at mediatek.com  Sun Aug  8 22:19:56 2021
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Mon, 9 Aug 2021 13:19:56 +0800
Subject: [PATCH v6 3/6] dt-bindings: remoteproc: mediatek: Convert mtk,
 scp to json-schema
In-Reply-To: <20210809051959.31136-1-tinghan.shen@mediatek.com>
References: <20210809051959.31136-1-tinghan.shen@mediatek.com>
Message-ID: <20210809051959.31136-4-tinghan.shen@mediatek.com>

Convert the mtk,scp binding to DT schema format using json-schema.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 .../bindings/remoteproc/mtk,scp.txt           | 41 ---------
 .../bindings/remoteproc/mtk,scp.yaml          | 92 +++++++++++++++++++
 2 files changed, 92 insertions(+), 41 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
 create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
deleted file mode 100644
index 88f37dee7bca..000000000000
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-Mediatek SCP Bindings
-----------------------------------------
-
-This binding provides support for ARM Cortex M4 Co-processor found on some
-Mediatek SoCs.
-
-Required properties:
-- compatible		Should be one of:
-				"mediatek,mt8183-scp"
-				"mediatek,mt8192-scp"
-				"mediatek,mt8195-scp"
-- reg			Should contain the address ranges for memory regions:
-			SRAM, CFG, and L1TCM.
-- reg-names		Contains the corresponding names for the memory regions:
-			"sram", "cfg", and "l1tcm".
-- clocks		Required by mt8183 and mt8192. Clock for co-processor
-			(See: ../clock/clock-bindings.txt)
-- clock-names		Required by mt8183 and mt8192. Contains the
-			corresponding name for the clock. This should be
-			named "main".
-
-Subnodes
---------
-
-Subnodes of the SCP represent rpmsg devices. The names of the devices are not
-important. The properties of these nodes are defined by the individual bindings
-for the rpmsg devices - but must contain the following property:
-
-- mtk,rpmsg-name	Contains the name for the rpmsg device. Used to match
-			the subnode to rpmsg device announced by SCP.
-
-Example:
-
-	scp: scp at 10500000 {
-		compatible = "mediatek,mt8183-scp";
-		reg = <0 0x10500000 0 0x80000>,
-		      <0 0x105c0000 0 0x5000>;
-		reg-names = "sram", "cfg";
-		clocks = <&infracfg CLK_INFRA_SCPSYS>;
-		clock-names = "main";
-	};
diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
new file mode 100644
index 000000000000..d21a25ee96e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/mtk,scp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek SCP Bindings
+
+maintainers:
+  - Tinghan Shen <tinghan.shen at mediatek.com>
+
+description:
+  This binding provides support for ARM Cortex M4 Co-processor found on some
+  Mediatek SoCs.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8183-scp
+      - mediatek,mt8192-scp
+      - mediatek,mt8195-scp
+
+  reg:
+    description:
+      Should contain the address ranges for memory regions SRAM, CFG, and
+      L1TCM.
+    maxItems: 3
+
+  reg-names:
+    items:
+      - const: sram
+      - const: cfg
+      - const: l1tcm
+
+  clocks:
+    description:
+      Clock for co-processor (see ../clock/clock-bindings.txt).
+      Required by mt8183 and mt8192.
+    maxItems: 1
+
+  clock-names:
+    const: main
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+if:
+  properties:
+    compatible:
+      enum:
+        - mediatek,mt8183-scp
+        - mediatek,mt8192-scp
+then:
+  required:
+    - clocks
+    - clock-names
+
+additionalProperties:
+  type: object
+  description:
+    Subnodes of the SCP represent rpmsg devices. The names of the devices
+    are not important. The properties of these nodes are defined by the
+    individual bindings for the rpmsg devices.
+  properties:
+    mediatek,rpmsg-name:
+      $ref: /schemas/types.yaml#/definitions/string-array
+      description:
+        Contains the name for the rpmsg device. Used to match
+        the subnode to rpmsg device announced by SCP.
+
+  required:
+    - mediatek,rpmsg-name
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+
+    scp at 10500000 {
+        compatible = "mediatek,mt8183-scp";
+        reg = <0x10500000 0x80000>,
+              <0x10700000 0x8000>,
+              <0x10720000 0xe0000>;
+        reg-names = "sram", "cfg", "l1tcm";
+        clocks = <&infracfg CLK_INFRA_SCPSYS>;
+        clock-names = "main";
+
+        cros_ec {
+            mediatek,rpmsg-name = "cros-ec-rpmsg";
+        };
+    };
-- 
2.18.0

From Mason.Zhang at mediatek.com  Sun Aug  8 22:59:12 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Mon, 9 Aug 2021 13:59:12 +0800
Subject: [PATCH 1/1] spi: mediatek: fix build warnning in set cs timing
Message-ID: <20210809055911.17538-1-Mason.Zhang@mediatek.com>

this patch fixed the build warnning in set cs timing.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index bb09592bc009..2f83599642fd 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -214,7 +214,7 @@ static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
 	struct spi_delay *cs_setup = &spi->cs_setup;
 	struct spi_delay *cs_hold = &spi->cs_hold;
 	struct spi_delay *cs_inactive = &spi->cs_inactive;
-	u16 setup, hold, inactive;
+	u32 setup, hold, inactive;
 	u32 reg_val;
 	int delay;
 
@@ -239,8 +239,8 @@ static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
 
 	reg_val = readl(mdata->base + SPI_CFG0_REG);
 	if (mdata->dev_comp->enhance_timing) {
-		hold = min(hold, 0xffff);
-		setup = min(setup, 0xffff);
+		hold = min_t(u32, hold, 0x10000);
+		setup = min_t(u32, setup, 0x10000);
 		reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
 		reg_val |= (((hold - 1) & 0xffff)
 			   << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
@@ -248,8 +248,8 @@ static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
 		reg_val |= (((setup - 1) & 0xffff)
 			   << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
 	} else {
-		hold = min(hold, 0xff);
-		setup = min(setup, 0xff);
+		hold = min_t(u32, hold, 0x100);
+		setup = min_t(u32, setup, 0x100);
 		reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
 		reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
 		reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
@@ -258,7 +258,7 @@ static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
 	}
 	writel(reg_val, mdata->base + SPI_CFG0_REG);
 
-	inactive = min(inactive, 0xff);
+	inactive = min_t(u32, inactive, 0x100);
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
 	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
 	reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
-- 
2.18.0

From liuqi115 at huawei.com  Sun Aug  8 23:33:12 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Mon, 9 Aug 2021 14:33:12 +0800
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210806014435.a1b6d7900e0e72599a8e325f@kernel.org>
References: <20210804060209.95817-1-liuqi115@huawei.com>
 <20210805105401.4acd3217c566b4e3933f355c@kernel.org>
 <d3e0c9ee-19b5-8042-d251-05348e8ac49e@huawei.com>
 <20210806014435.a1b6d7900e0e72599a8e325f@kernel.org>
Message-ID: <7aead513-7ce5-7761-70d0-d83fe127c486@huawei.com>



On 2021/8/6 0:44, Masami Hiramatsu wrote:
> On Thu, 5 Aug 2021 17:25:17 +0800
> "liuqi (BA)" <liuqi115 at huawei.com> wrote:
> 
>>
>> Hi Masami,
>>
>> On 2021/8/5 9:54, Masami Hiramatsu wrote:
>>> On Wed, 4 Aug 2021 14:02:09 +0800
>>> Qi Liu <liuqi115 at huawei.com> wrote:
>>>
>>>> This patch introduce optprobe for ARM64. In optprobe, probed
>>>> instruction is replaced by a branch instruction to detour
>>>> buffer. Detour buffer contains trampoline code and a call to
>>>> optimized_callback(). optimized_callback() calls opt_pre_handler()
>>>> to execute kprobe handler.
>>>>
>>>> Limitations:
>>>> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
>>>> guarantee the offset between probe point and kprobe pre_handler
>>>> is not larger than 128MiB.
>>>>
>>>> Performance of optprobe on Hip08 platform is test using kprobe
>>>> example module[1] to analyze the latency of a kernel function,
>>>> and here is the result:
>>>>
>>>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
>>>>
>>>> kprobe before optimized:
>>>> [280709.846380] do_empty returned 0 and took 1530 ns to execute
>>>> [280709.852057] do_empty returned 0 and took 550 ns to execute
>>>> [280709.857631] do_empty returned 0 and took 440 ns to execute
>>>> [280709.863215] do_empty returned 0 and took 380 ns to execute
>>>> [280709.868787] do_empty returned 0 and took 360 ns to execute
>>>> [280709.874362] do_empty returned 0 and took 340 ns to execute
>>>> [280709.879936] do_empty returned 0 and took 320 ns to execute
>>>> [280709.885505] do_empty returned 0 and took 300 ns to execute
>>>> [280709.891075] do_empty returned 0 and took 280 ns to execute
>>>> [280709.896646] do_empty returned 0 and took 290 ns to execute
>>>> [280709.902220] do_empty returned 0 and took 290 ns to execute
>>>> [280709.907807] do_empty returned 0 and took 290 ns to execute
>>>>
>>>> optprobe:
>>>> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
>>>> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
>>>> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
>>>> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
>>>> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
>>>> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
>>>> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
>>>> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
>>>> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
>>>> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
>>>> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
>>>> [ 2966.023779] do_empty returned 0 and took 70 ns to execute
>>>> [ 2966.029158] do_empty returned 0 and took 70 ns to execute
>>>>
>>>> Signed-off-by: Qi Liu <liuqi115 at huawei.com>
>>>>
>>>> ---
>>>>
>>>> Changes since V1:
>>>> - Address the comments from Masami, checks for all branch instructions, and
>>>> use aarch64_insn_patch_text_nosync() instead of aarch64_insn_patch_text()
>>>> in each probe.
>>>
>>> Is it safe for the multicore system? If it is safe because it modifies
>>> just one instruction (modifying 32bit in atomic), I understand it.
>>
>> Seems raw_spin_lock_irqsave is used in aarch64_insn_patch_text_nosync()
>> and spinlock could support a protection in multicore system.
> 
> No, that is not what I meant. stop_machine() will ensure that the all other
> cores parking in the safe area, so the target instruction will never be
> executed while modifying the code.
> Even if you use the spinlock, other cores don't stop unless it tries
> to lock the same spinlock. And they are possible to execute the instruction
> which you are modifying.
> 

got it, thanks, so I think aarch64_insn_patch_text_nosync() is not 
suitable for arch_optimize_kprobes, as stop_machine is indispensables here.
I also checked x86 opt.c, text_poke_bp() is used to modify the 
instruction, seems it calls do_sync_core and make sure other core will 
not execute the modifying instruction.

>>> BTW, anyway, you should use _nosync() variant in arch_prepare_optimized_kprobe()
>>> too, beacause the optprobe insn buffer is not touched until the probed instruction
>>> is optimized by br.
>>>
>> Yes, sounds resonable.
>>> [...]
>>>> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
>>>> +{
>>>> +	kprobe_opcode_t *code;
>>>> +	u32 insn;
>>>> +	int ret, i;
>>>> +	void *addrs[TMPL_END_IDX];
>>>> +	void *addr;
>>>> +
>>>> +	code = get_optinsn_slot();
>>>> +	if (!code)
>>>> +		return -ENOMEM;
>>>> +
>>>> +	if (!is_offset_in_range((unsigned long)code,
>>>> +				(unsigned long)orig->addr + 8))
>>>> +		goto error;
>>>> +
>>>> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
>>>> +				(unsigned long)optimized_callback))
>>>> +		goto error;
>>>> +
>>>> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
>>>> +				(unsigned long)op->kp.addr + 4))
>>>> +		goto error;
>>>> +
>>>> +	/* Setup template */
>>>> +	for (i = 0; i < TMPL_END_IDX; i++)
>>>> +		addrs[i] = code + i;
>>>> +
>>>> +	ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
>>>> +				      TMPL_END_IDX);
>>>
>>> You should use aarch64_insn_patch_text_nosync() here (and all the
>>> aarch64_insn_patch_text() in this function too), because the insn
>>> buffer must not executed until the probe point is optimized.
>>>
>> aarch64_insn_patch_text() could patch multi instructions to code[] each
>> time and aarch64_insn_patch_text_nosync() could only patch one
>> instruction each time,
> 
> Ah, right.
> 
>> so maybe aarch64_insn_patch_text() is better here.
>>
>> I'll replace other aarch64_insn_patch_text() in this function.
> 
> Could you see x86 optprobe code what it does?
> I prepare another writable buffer and build the trampoline code
> on it. Finally patch the code on the insn buffer at once.
> You can do the same thing here.
> 
> Thank you,
> 

Got it, I'll add this in next version.

Thanks,
Qi
>>
>> Thanks,
>> Qi
>>
>>>> +	if (ret < 0)
>>>> +		goto error;
>>>> +
>>>> +	/* Set probe information */
>>>> +	addr = code + TMPL_VAL_IDX;
>>>> +	insn =  (unsigned long long)op & 0xffffffff;
>>>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>>>> +
>>>> +	addr = addr + 4;
>>>> +	insn = ((unsigned long long)op & GENMASK_ULL(63, 32)) >> 32;
>>>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>>>> +
>>>> +	addr = code + TMPL_CALL_BACK;
>>>> +	insn =  aarch64_insn_gen_branch_imm((unsigned long)addr,
>>>> +				(unsigned long)optimized_callback,
>>>> +				AARCH64_INSN_BRANCH_LINK);
>>>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>>>> +
>>>> +	/* The original probed instruction */
>>>> +	addr = code + TMPL_RESTORE_ORIGN_INSN;
>>>> +	insn =  orig->opcode;
>>>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>>>> +
>>>> +	/* Jump back to next instruction */
>>>> +	addr = code + TMPL_RESTORE_END;
>>>> +	insn = aarch64_insn_gen_branch_imm(
>>>> +				(unsigned long)(&code[TMPL_RESTORE_END]),
>>>> +				(unsigned long)(op->kp.addr) + 4,
>>>> +				AARCH64_INSN_BRANCH_NOLINK);
>>>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>>>> +
>>>> +	flush_icache_range((unsigned long)code,
>>>> +			   (unsigned long)(&code[TMPL_END_IDX]));
>>>> +	/* Set op->optinsn.insn means prepared. */
>>>> +	op->optinsn.insn = code;
>>>> +
>>>> +	return 0;
>>>
>>> Thank you,
>>>
>>>
>>>
>>
> 
> 



From liuqi115 at huawei.com  Sun Aug  8 23:44:58 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Mon, 9 Aug 2021 14:44:58 +0800
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <e59357e126e34a6d97a55113483746f8@hisilicon.com>
References: <20210804060209.95817-1-liuqi115@huawei.com>
 <e59357e126e34a6d97a55113483746f8@hisilicon.com>
Message-ID: <925da4cb-f45f-fbaf-e0bd-4866690a2b26@huawei.com>


Hi Barry,
On 2021/8/5 16:55, Song Bao Hua (Barry Song) wrote:
> 
> 
>> -----Original Message-----
>> From: liuqi (BA)
>> Sent: Wednesday, August 4, 2021 6:02 PM
>> To: catalin.marinas at arm.com; will at kernel.org; naveen.n.rao at linux.ibm.com;
>> anil.s.keshavamurthy at intel.com; davem at davemloft.net; mhiramat at kernel.org;
>> linux-arm-kernel at lists.infradead.org
>> Cc: Song Bao Hua (Barry Song) <song.bao.hua at hisilicon.com>; Zengtao (B)
>> <prime.zeng at hisilicon.com>; robin.murphy at arm.com; Fangjian (Jay)
>> <f.fangjian at huawei.com>; liuqi (BA) <liuqi115 at huawei.com>; Linuxarm
>> <linuxarm at huawei.com>; linux-kernel at vger.kernel.org
>> Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
>>
>> This patch introduce optprobe for ARM64. In optprobe, probed
>> instruction is replaced by a branch instruction to detour
>> buffer. Detour buffer contains trampoline code and a call to
>> optimized_callback(). optimized_callback() calls opt_pre_handler()
>> to execute kprobe handler.
>>
>> Limitations:
>> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
>> guarantee the offset between probe point and kprobe pre_handler
>> is not larger than 128MiB.
>>
>> Performance of optprobe on Hip08 platform is test using kprobe
>> example module[1] to analyze the latency of a kernel function,
>> and here is the result:
>>
>> [1]
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sa
>> mples/kprobes/kretprobe_example.c
>>
>> kprobe before optimized:
>> [280709.846380] do_empty returned 0 and took 1530 ns to execute
>> [280709.852057] do_empty returned 0 and took 550 ns to execute
>> [280709.857631] do_empty returned 0 and took 440 ns to execute
>> [280709.863215] do_empty returned 0 and took 380 ns to execute
>> [280709.868787] do_empty returned 0 and took 360 ns to execute
>> [280709.874362] do_empty returned 0 and took 340 ns to execute
>> [280709.879936] do_empty returned 0 and took 320 ns to execute
>> [280709.885505] do_empty returned 0 and took 300 ns to execute
>> [280709.891075] do_empty returned 0 and took 280 ns to execute
>> [280709.896646] do_empty returned 0 and took 290 ns to execute
>> [280709.902220] do_empty returned 0 and took 290 ns to execute
>> [280709.907807] do_empty returned 0 and took 290 ns to execute
>>

[...]
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b5b13a932561..3532f0237c71 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -200,6 +200,7 @@ config ARM64
>>   	select HAVE_STACKPROTECTOR
>>   	select HAVE_SYSCALL_TRACEPOINTS
>>   	select HAVE_KPROBES
>> +	select HAVE_OPTPROBES if !RANDOMIZE_MODULE_REGION_FULL
> 
> Any negative side effect if we optprobe doesn't apply and we fall
> back to normal kprobe?
> 
> I mean, normal kprobe without this patch vs. fallback to kprobe
> from optprobe with this patch, any penalty in latency from
> optprobe?
> 

I test this situation on Hip08 platform, and here is the result:
</sys/bus/platform/devices/hello_driver/kprobe_test
[   29.713132] do_empty returned 0 and took 1800 ns to execute
[   29.713726] do_empty returned 0 and took 410 ns to execute
[   29.714296] do_empty returned 0 and took 320 ns to execute
[   29.714846] do_empty returned 0 and took 290 ns to execute
[   29.715388] do_empty returned 0 and took 280 ns to execute
[   29.715932] do_empty returned 0 and took 290 ns to execute
[   29.716472] do_empty returned 0 and took 280 ns to execute
[   29.717028] do_empty returned 0 and took 270 ns to execute
[   29.717578] do_empty returned 0 and took 270 ns to execute
[   29.718142] do_empty returned 0 and took 290 ns to execute
[   29.718700] do_empty returned 0 and took 250 ns to execute
[   29.719246] do_empty returned 0 and took 260 ns to execute
[   29.719797] do_empty returned 0 and took 250 ns to execute
[   29.720355] do_empty returned 0 and took 290 ns to execute
[   29.720915] do_empty returned 0 and took 270 ns to execute
[   29.721484] do_empty returned 0 and took 270 ns to execute
[   29.722032] do_empty returned 0 and took 270 ns to execute
[   29.722612] do_empty returned 0 and took 280 ns to execute
[   29.723161] do_empty returned 0 and took 260 ns to execute
[   29.723712] do_empty returned 0 and took 260 ns to execute
[   29.724266] do_empty returned 0 and took 260 ns to execute
[   29.724823] do_empty returned 0 and took 270 ns to execute
[   29.725423] do_empty returned 0 and took 340 ns to execute
[   29.725968] do_empty returned 0 and took 280 ns to execute

Seems no penalty here.

> If no penalty, I'd rather we remove the dependency of
> RANDOMIZE_MODULE_REGION_FULL since you mentioned
> nokaslr will always make optprobe work. I assume
> in those tests you enabled RANDOMIZE_MODULE_REGION_FULL?
> 

Yes, when I set nokaslr, I also set CONFIG_RANDOMIZE_MODULE_REGION_FULL=y.

ok, I'll remove this depending next version and metion it in commit log.

Thanks,
Qi

> We can mention those issues in commit log rather than statically
> depending on a kconfig option.
> 
>>   	select HAVE_KRETPROBES
>>   	select HAVE_GENERIC_VDSO
>>   	select IOMMU_DMA if IOMMU_SUPPORT
>> diff --git a/arch/arm64/include/asm/kprobes.h
>> b/arch/arm64/include/asm/kprobes.h
>> index 5d38ff4a4806..9e1c492a0c3d 100644
>> --- a/arch/arm64/include/asm/kprobes.h
>> +++ b/arch/arm64/include/asm/kprobes.h
>> @@ -39,6 +39,29 @@ void arch_remove_kprobe(struct kprobe *);
>>   int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
>>   int kprobe_exceptions_notify(struct notifier_block *self,
>>   			     unsigned long val, void *data);
>> +
>> +#define RELATIVEJUMP_SIZE (4)
>> +#define MAX_COPIED_INSN	DIV_ROUND_UP(RELATIVEJUMP_SIZE,
>> sizeof(kprobe_opcode_t))
>> +struct arch_optimized_insn {
>> +	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
>> +	/* detour code buffer */
>> +	kprobe_opcode_t *insn;
>> +};
>> +
>> +/* optinsn template addresses */
>> +extern __visible kprobe_opcode_t optprobe_template_entry[];
>> +extern __visible kprobe_opcode_t optprobe_template_val[];
>> +extern __visible kprobe_opcode_t optprobe_template_call[];
>> +extern __visible kprobe_opcode_t optprobe_template_end[];
>> +extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
>> +extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
>> +extern __visible kprobe_opcode_t optprobe_template_restore_end[];
>> +
>> +#define MAX_OPTIMIZED_LENGTH	4
>> +#define MAX_OPTINSN_SIZE				\
>> +	((unsigned long)optprobe_template_end -	\
>> +	 (unsigned long)optprobe_template_entry)
>> +
>>   void kretprobe_trampoline(void);
>>   void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
>>
>> diff --git a/arch/arm64/kernel/probes/Makefile
>> b/arch/arm64/kernel/probes/Makefile
>> index 8e4be92e25b1..52cf5d4ffe8a 100644
>> --- a/arch/arm64/kernel/probes/Makefile
>> +++ b/arch/arm64/kernel/probes/Makefile
>> @@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o decode-insn.o	\
>>   				   simulate-insn.o
>>   obj-$(CONFIG_UPROBES)		+= uprobes.o decode-insn.o	\
>>   				   simulate-insn.o
>> +obj-$(CONFIG_OPTPROBES)		+= opt-arm64.o			\
>> +				   optprobe_trampoline.o
>> diff --git a/arch/arm64/kernel/probes/kprobes.c
>> b/arch/arm64/kernel/probes/kprobes.c
>> index 6dbcc89f6662..83755ad62abe 100644
>> --- a/arch/arm64/kernel/probes/kprobes.c
>> +++ b/arch/arm64/kernel/probes/kprobes.c
>> @@ -11,6 +11,7 @@
>>   #include <linux/kasan.h>
>>   #include <linux/kernel.h>
>>   #include <linux/kprobes.h>
>> +#include <linux/moduleloader.h>
>>   #include <linux/sched/debug.h>
>>   #include <linux/set_memory.h>
>>   #include <linux/slab.h>
>> @@ -113,9 +114,21 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
>>
>>   void *alloc_insn_page(void)
>>   {
>> -	return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
>> -			GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
>> -			NUMA_NO_NODE, __builtin_return_address(0));
>> +	void *page;
>> +
>> +	page = module_alloc(PAGE_SIZE);
>> +	if (!page)
>> +		return NULL;
>> +
>> +	set_vm_flush_reset_perms(page);
>> +	/*
>> +	 * First make the page read-only, and only then make it executable to
>> +	 * prevent it from being W+X in between.
>> +	 */
>> +	set_memory_ro((unsigned long)page, 1);
>> +	set_memory_x((unsigned long)page, 1);
>> +
>> +	return page;
>>   }
>>
>>   /* arm kprobe: install breakpoint in text */
>> diff --git a/arch/arm64/kernel/probes/opt-arm64.c
>> b/arch/arm64/kernel/probes/opt-arm64.c
>> new file mode 100644
>> index 000000000000..a0302e3ad62d
>> --- /dev/null
>> +++ b/arch/arm64/kernel/probes/opt-arm64.c
>> @@ -0,0 +1,225 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Code for Kernel probes Jump optimization.
>> + *
>> + * Copyright (C) 2021 Hisilicon Limited
>> + */
>> +
>> +#include <linux/jump_label.h>
>> +#include <linux/kprobes.h>
>> +
>> +#include <asm/cacheflush.h>
>> +#include <asm/insn.h>
>> +#include <asm/kprobes.h>
>> +
>> +
>> +#define TMPL_VAL_IDX \
>> +	(optprobe_template_val - optprobe_template_entry)
>> +#define TMPL_CALL_BACK \
>> +	(optprobe_template_call - optprobe_template_entry)
>> +#define TMPL_END_IDX \
>> +	(optprobe_template_end - optprobe_template_entry)
>> +#define TMPL_RESTORE_ORIGN_INSN \
>> +	(optprobe_template_restore_orig_insn - optprobe_template_entry)
>> +#define TMPL_RESTORE_END \
>> +	(optprobe_template_restore_end - optprobe_template_entry)
>> +
>> +int arch_check_optimized_kprobe(struct optimized_kprobe *op)
>> +{
>> +	return 0;
>> +}
>> +
>> +int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
>> +{
>> +	return optinsn->insn != NULL;
>> +}
>> +
>> +int arch_within_optimized_kprobe(struct optimized_kprobe *op,
>> +				unsigned long addr)
>> +{
>> +	return ((unsigned long)op->kp.addr <= addr &&
>> +		(unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
>> +}
>> +
>> +static void
>> +optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
>> +{
>> +	/* This is possible if op is under delayed unoptimizing */
>> +	if (kprobe_disabled(&op->kp))
>> +		return;
>> +
>> +	preempt_disable();
>> +
>> +	if (kprobe_running()) {
>> +		kprobes_inc_nmissed_count(&op->kp);
>> +	} else {
>> +		__this_cpu_write(current_kprobe, &op->kp);
>> +		regs->pc = (unsigned long)op->kp.addr;
>> +		get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
>> +		opt_pre_handler(&op->kp, regs);
>> +		__this_cpu_write(current_kprobe, NULL);
>> +	}
>> +
>> +	preempt_enable_no_resched();
>> +}
>> +NOKPROBE_SYMBOL(optimized_callback)
>> +
>> +static bool is_offset_in_range(unsigned long start, unsigned long end)
>> +{
>> +	long offset = end - start;
>> +
>> +	/*
>> +	 * Verify if the address gap is in 128MiB range, because this uses
>> +	 * a relative jump.
>> +	 *
>> +	 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
>> +	 * According to ARM manual, branch instruction is:
>> +	 *
>> +	 *   31  30                  25              0
>> +	 *  +----+---+---+---+---+---+---------------+
>> +	 *  |cond| 0 | 0 | 1 | 0 | 1 |     imm26     |
>> +	 *  +----+---+---+---+---+---+---------------+
>> +	 *
>> +	 * imm26 is a signed 26 bits integer. The real branch offset is computed
>> +	 * by: imm64 = SignExtend(imm26:'00', 64);
>> +	 *
>> +	 * So the maximum forward branch should be:
>> +	 *   (0x01ffffff << 2) = 1720x07fffffc =  0x07fffffc
>> +	 * The maximum backward branch should be:
>> +	 *   (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
>> +	 *
>> +	 * We can simply check (rel & 0xf8000003):
>> +	 *  if rel is positive, (rel & 0xf8000003) should be 0
>> +	 *  if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
>> +	 *  the last '3' is used for alignment checking.
>> +	 */
>> +	return (offset >= -0x08000000 && offset <= 0x07fffffc && !(offset & 0x3));
>> +}
>> +
>> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe
>> *orig)
>> +{
>> +	kprobe_opcode_t *code;
>> +	u32 insn;
>> +	int ret, i;
>> +	void *addrs[TMPL_END_IDX];
>> +	void *addr;
>> +
>> +	code = get_optinsn_slot();
>> +	if (!code)
>> +		return -ENOMEM;
>> +
>> +	if (!is_offset_in_range((unsigned long)code,
>> +				(unsigned long)orig->addr + 8))
>> +		goto error;
>> +
>> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
>> +				(unsigned long)optimized_callback))
>> +		goto error;
>> +
>> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
>> +				(unsigned long)op->kp.addr + 4))
>> +		goto error;
>> +
>> +	/* Setup template */
>> +	for (i = 0; i < TMPL_END_IDX; i++)
>> +		addrs[i] = code + i;
>> +
>> +	ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
>> +				      TMPL_END_IDX);
>> +	if (ret < 0)
>> +		goto error;
>> +
>> +	/* Set probe information */
>> +	addr = code + TMPL_VAL_IDX;
>> +	insn =  (unsigned long long)op & 0xffffffff;
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	addr = addr + 4;
>> +	insn = ((unsigned long long)op & GENMASK_ULL(63, 32)) >> 32;
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	addr = code + TMPL_CALL_BACK;
>> +	insn =  aarch64_insn_gen_branch_imm((unsigned long)addr,
>> +				(unsigned long)optimized_callback,
>> +				AARCH64_INSN_BRANCH_LINK);
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	/* The original probed instruction */
>> +	addr = code + TMPL_RESTORE_ORIGN_INSN;
>> +	insn =  orig->opcode;
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	/* Jump back to next instruction */
>> +	addr = code + TMPL_RESTORE_END;
>> +	insn = aarch64_insn_gen_branch_imm(
>> +				(unsigned long)(&code[TMPL_RESTORE_END]),
>> +				(unsigned long)(op->kp.addr) + 4,
>> +				AARCH64_INSN_BRANCH_NOLINK);
>> +	aarch64_insn_patch_text(&addr, &insn, 1);
>> +
>> +	flush_icache_range((unsigned long)code,
>> +			   (unsigned long)(&code[TMPL_END_IDX]));
>> +	/* Set op->optinsn.insn means prepared. */
>> +	op->optinsn.insn = code;
>> +
>> +	return 0;
>> +
>> +error:
>> +	free_optinsn_slot(code, 0);
>> +	return -ERANGE;
>> +}
>> +
>> +void arch_optimize_kprobes(struct list_head *oplist)
>> +{
>> +	struct optimized_kprobe *op, *tmp;
>> +
>> +	list_for_each_entry_safe(op, tmp, oplist, list) {
>> +		u32 insn;
>> +
>> +		WARN_ON(kprobe_disabled(&op->kp));
>> +
>> +		/*
>> +		 * Backup instructions which will be replaced
>> +		 * by jump address
>> +		 */
>> +		memcpy(op->optinsn.copied_insn, op->kp.addr,
>> +			RELATIVEJUMP_SIZE);
>> +		insn = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
>> +				(unsigned long)op->optinsn.insn,
>> +				AARCH64_INSN_BRANCH_NOLINK);
>> +
>> +		WARN_ON(insn == 0);
>> +
>> +		aarch64_insn_patch_text_nosync((void*)op->kp.addr, insn);
>> +
>> +		list_del_init(&op->list);
>> +	}
>> +}
>> +
>> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
>> +{
>> +	arch_arm_kprobe(&op->kp);
>> +}
>> +
>> +/*
>> + * Recover original instructions and breakpoints from relative jumps.
>> + * Caller must call with locking kprobe_mutex.
>> + */
>> +void arch_unoptimize_kprobes(struct list_head *oplist,
>> +			    struct list_head *done_list)
>> +{
>> +	struct optimized_kprobe *op, *tmp;
>> +
>> +	list_for_each_entry_safe(op, tmp, oplist, list) {
>> +		arch_unoptimize_kprobe(op);
>> +		list_move(&op->list, done_list);
>> +	}
>> +}
>> +
>> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
>> +{
>> +	if (op->optinsn.insn) {
>> +		free_optinsn_slot(op->optinsn.insn, 1);
>> +		op->optinsn.insn = NULL;
>> +	}
>> +}
>> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S
>> b/arch/arm64/kernel/probes/optprobe_trampoline.S
>> new file mode 100644
>> index 000000000000..13729cb279b8
>> --- /dev/null
>> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
>> @@ -0,0 +1,80 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * trampoline entry and return code for optprobes.
>> + */
>> +
>> +#include <linux/linkage.h>
>> +#include <asm/asm-offsets.h>
>> +#include <asm/assembler.h>
>> +
>> +	.global optprobe_template_entry
>> +optprobe_template_entry:
>> +	sub sp, sp, #PT_REGS_SIZE
>> +	stp x0, x1, [sp, #S_X0]
>> +	stp x2, x3, [sp, #S_X2]
>> +	stp x4, x5, [sp, #S_X4]
>> +	stp x6, x7, [sp, #S_X6]
>> +	stp x8, x9, [sp, #S_X8]
>> +	stp x10, x11, [sp, #S_X10]
>> +	stp x12, x13, [sp, #S_X12]
>> +	stp x14, x15, [sp, #S_X14]
>> +	stp x16, x17, [sp, #S_X16]
>> +	stp x18, x19, [sp, #S_X18]
>> +	stp x20, x21, [sp, #S_X20]
>> +	stp x22, x23, [sp, #S_X22]
>> +	stp x24, x25, [sp, #S_X24]
>> +	stp x26, x27, [sp, #S_X26]
>> +	stp x28, x29, [sp, #S_X28]
>> +	add x0, sp, #PT_REGS_SIZE
>> +	stp lr, x0, [sp, #S_LR]
>> +	/*
>> +	 * Construct a useful saved PSTATE
>> +	 */
>> +	mrs x0, nzcv
>> +	mrs x1, daif
>> +	orr x0, x0, x1
>> +	mrs x1, CurrentEL
>> +	orr x0, x0, x1
>> +	mrs x1, SPSel
>> +	orr x0, x0, x1
>> +	stp xzr, x0, [sp, #S_PC]
>> +	/* Get parameters to optimized_callback() */
>> +	ldr	x0, 1f
>> +	mov	x1, sp
>> +	/* Branch to optimized_callback() */
>> +	.global optprobe_template_call
>> +optprobe_template_call:
>> +	nop
>> +        /* Restore registers */
>> +	ldr x0, [sp, #S_PSTATE]
>> +	and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
>> +	msr nzcv, x0
>> +	ldp x0, x1, [sp, #S_X0]
>> +	ldp x2, x3, [sp, #S_X2]
>> +	ldp x4, x5, [sp, #S_X4]
>> +	ldp x6, x7, [sp, #S_X6]
>> +	ldp x8, x9, [sp, #S_X8]
>> +	ldp x10, x11, [sp, #S_X10]
>> +	ldp x12, x13, [sp, #S_X12]
>> +	ldp x14, x15, [sp, #S_X14]
>> +	ldp x16, x17, [sp, #S_X16]
>> +	ldp x18, x19, [sp, #S_X18]
>> +	ldp x20, x21, [sp, #S_X20]
>> +	ldp x22, x23, [sp, #S_X22]
>> +	ldp x24, x25, [sp, #S_X24]
>> +	ldp x26, x27, [sp, #S_X26]
>> +	ldp x28, x29, [sp, #S_X28]
>> +	ldr lr, [sp, #S_LR]
>> +        add sp, sp, #PT_REGS_SIZE
>> +	.global optprobe_template_restore_orig_insn
>> +optprobe_template_restore_orig_insn:
>> +	nop
>> +	.global optprobe_template_restore_end
>> +optprobe_template_restore_end:
>> +	nop
>> +	.global optprobe_template_end
>> +optprobe_template_end:
>> +	.global optprobe_template_val
>> +optprobe_template_val:
>> +	1:	.long 0
>> +		.long 0
>> --
>> 2.17.1
> 
> 
> Thanks
> Barry
> 
> .
> 



From liuqi115 at huawei.com  Mon Aug  9 00:00:18 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Mon, 9 Aug 2021 15:00:18 +0800
Subject: [PATCH v2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <2fd3c78f-741a-4693-acae-4ea5465ad798@arm.com>
References: <20210804060209.95817-1-liuqi115@huawei.com>
 <2fd3c78f-741a-4693-acae-4ea5465ad798@arm.com>
Message-ID: <c2aa748e-14a9-1e5f-c4f2-5f6e1c140f5e@huawei.com>


Hi Amit,
On 2021/8/9 12:15, Amit Kachhap wrote:
> Hi Liu,
> 
> I am few minor comments.
> 
> On 8/4/21 11:32 AM, Qi Liu wrote:
>> This patch introduce optprobe for ARM64. In optprobe, probed
>> instruction is replaced by a branch instruction to detour
>> buffer. Detour buffer contains trampoline code and a call to
>> optimized_callback(). optimized_callback() calls opt_pre_handler()
>> to execute kprobe handler.
>>
>> Limitations:
>> - We only support !CONFIG_RANDOMIZE_MODULE_REGION_FULL case to
>> guarantee the offset between probe point and kprobe pre_handler
>> is not larger than 128MiB.
>>
>> Performance of optprobe on Hip08 platform is test using kprobe
>> example module[1] to analyze the latency of a kernel function,
>> and here is the result:
>>
>> [1] 
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c 
>>
> 
>> +???? *
>> +???? * kprobe opt use a 'b' instruction to branch to optinsn.insn.
>> +???? * According to ARM manual, branch instruction is:
>> +???? *
>> +???? *?? 31? 30????????????????? 25????????????? 0
>> +???? *? +----+---+---+---+---+---+---------------+
>> +???? *? |cond| 0 | 0 | 1 | 0 | 1 |???? imm26???? |
>> +???? *? +----+---+---+---+---+---+---------------+
>> +???? *
>> +???? * imm26 is a signed 26 bits integer. The real branch offset is 
>> computed
>> +???? * by: imm64 = SignExtend(imm26:'00', 64);
>> +???? *
>> +???? * So the maximum forward branch should be:
>> +???? *?? (0x01ffffff << 2) = 1720x07fffffc =? 0x07fffffc
> 
> 7120x07fffffc ? Shouldn't it be just 0x07fffffc.
> 

Emmm yes, 7120x07fffffc can be dropped, thanks.
>> +???? * The maximum backward branch should be:
>> +???? *?? (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
>> +???? *
>> +???? * We can simply check (rel & 0xf8000003):
>> +???? *? if rel is positive, (rel & 0xf8000003) should be 0
>> +???? *? if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
>> +???? *? the last '3' is used for alignment checking.
>> +???? */
>> +??? return (offset >= -0x08000000 && offset <= 0x07fffffc && !(offset 
>> & 0x3));
>> +}
>> +
>> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct 
>> kprobe *orig)
>> +{
>> +??? kprobe_opcode_t *code;
>> +??? u32 insn;
>> +??? int ret, i;
>> +??? void *addrs[TMPL_END_IDX];
>> +??? void *addr;
>> +
>> +??? code = get_optinsn_slot();
>> +??? if (!code)
>> +??????? return -ENOMEM;
>> +
>> +??? if (!is_offset_in_range((unsigned long)code,
>> +??????????????? (unsigned long)orig->addr + 8))
>> +??????? goto error;
>> +
>> +??? if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
>> +??????????????? (unsigned long)optimized_callback))
>> +??????? goto error;
>> +
>> +??? if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
>> +??????????????? (unsigned long)op->kp.addr + 4))
>> +??????? goto error;
>> +
>> +??? /* Setup template */
>> +??? for (i = 0; i < TMPL_END_IDX; i++)
>> +??????? addrs[i] = code + i;
>> +
>> +??? ret = aarch64_insn_patch_text(addrs, optprobe_template_entry,
>> +????????????????????? TMPL_END_IDX);
> 
> Here it copies nops for restore_orig_insn, restore_orig_insn and
> again overwrites them with new values below.
> 

Yes, as Masami said, I could prepare another writable buffer and build 
the trampoline code on it, like x86 optprobe. thanks.

>> +??? if (ret < 0)
>> +??????? goto error;
>> +
[...]
>> +??? mrs x1, CurrentEL
>> +??? orr x0, x0, x1
>> +??? mrs x1, SPSel
>> +??? orr x0, x0, x1
>> +??? stp xzr, x0, [sp, #S_PC]
>> +??? /* Get parameters to optimized_callback() */
>> +??? ldr??? x0, 1f
>> +??? mov??? x1, sp
> 
> Most of the codes here are same as save_all_base_regs macro in file
> arch/arm64/kernel/probes/kprobes_trampoline.S. May be they
> can be made common macros and kept in asm/assembler.h
> 
Sounds reasonable, will fix this next time.

Thanks,
Qi
>> +??? /* Branch to optimized_callback() */
>> +??? .global optprobe_template_call
>> +optprobe_template_call:
>> +??? nop
>> +??????? /* Restore registers */
>> +??? ldr x0, [sp, #S_PSTATE]
>> +??? and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
>> +??? msr nzcv, x0
>> +??? ldp x0, x1, [sp, #S_X0]
>> +??? ldp x2, x3, [sp, #S_X2]
>> +??? ldp x4, x5, [sp, #S_X4]
>> +??? ldp x6, x7, [sp, #S_X6]
>> +??? ldp x8, x9, [sp, #S_X8]
>> +??? ldp x10, x11, [sp, #S_X10]
>> +??? ldp x12, x13, [sp, #S_X12]
>> +??? ldp x14, x15, [sp, #S_X14]
>> +??? ldp x16, x17, [sp, #S_X16]
>> +??? ldp x18, x19, [sp, #S_X18]
>> +??? ldp x20, x21, [sp, #S_X20]
>> +??? ldp x22, x23, [sp, #S_X22]
>> +??? ldp x24, x25, [sp, #S_X24]
>> +??? ldp x26, x27, [sp, #S_X26]
>> +??? ldp x28, x29, [sp, #S_X28]
>> +??? ldr lr, [sp, #S_LR]
>> +??????? add sp, sp, #PT_REGS_SIZE
> 
> Same as previous comment.
> 
> BR.
> //Amit
> 
>> +??? .global optprobe_template_restore_orig_insn
>> +optprobe_template_restore_orig_insn:
>> +??? nop
>> +??? .global optprobe_template_restore_end
>> +optprobe_template_restore_end:
>> +??? nop
>> +??? .global optprobe_template_end
>> +optprobe_template_end:
>> +??? .global optprobe_template_val
>> +optprobe_template_val:
>> +??? 1:??? .long 0
>> +??????? .long 0
>>
> .



From shawnguo at kernel.org  Mon Aug  9 00:18:39 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:18:39 +0800
Subject: [GIT PULL] i.MX eCSPI errata handling for 5.15
Message-ID: <20210809071838.GF30984@dragon>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-ecspi-5.15

for you to fetch changes up to 4e2b10be1f4fe06c9deaaf2c03a05abcff191791:

  dmaengine: imx-sdma: add terminated list for freed descriptor in worker (2021-07-23 11:20:06 +0800)

----------------------------------------------------------------
i.MX eCSPI errata handling for 5.15:

It includes all required changes for handling i.MX6/7 eCSPI errata
ERR009165, which causes FIFO transfer to be sent twice in DMA mode.
Both SPI and DMA maintainers agree to merge it through arm-soc tree.

----------------------------------------------------------------
Robin Gong (12):
      Revert "ARM: dts: imx6q: Use correct SDMA script for SPI5 core"
      Revert "ARM: dts: imx6: Use correct SDMA script for SPI cores"
      Revert "dmaengine: imx-sdma: refine to load context only once"
      dmaengine: imx-sdma: remove duplicated sdma_load_context
      dmaengine: dma: imx-sdma: add fw_loaded and is_ram_script
      dmaengine: imx-sdma: add mcu_2_ecspi script
      spi: imx: fix ERR009165
      spi: imx: remove ERR009165 workaround on i.mx6ul
      dmaengine: imx-sdma: remove ERR009165 on i.mx6ul
      dma: imx-sdma: add i.mx6ul compatible name
      dmaengine: imx-sdma: add uart rom script
      dmaengine: imx-sdma: add terminated list for freed descriptor in worker

 .../devicetree/bindings/dma/fsl-imx-sdma.txt       |  1 +
 arch/arm/boot/dts/imx6q.dtsi                       |  2 +-
 arch/arm/boot/dts/imx6qdl.dtsi                     |  8 +-
 drivers/dma/imx-sdma.c                             | 93 ++++++++++++++++------
 drivers/spi/spi-imx.c                              | 41 ++++++++--
 5 files changed, 111 insertions(+), 34 deletions(-)


From shawnguo at kernel.org  Mon Aug  9 00:30:10 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:30:10 +0800
Subject: [PATCH V7 1/7] ARM: dts: imx6q-dhcom: Use 1G ethernet on the
 PDK2 board
In-Reply-To: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
Message-ID: <20210809073009.GG30984@dragon>

On Mon, Aug 02, 2021 at 04:10:32PM +0200, Christoph Niedermaier wrote:
> The PDK2 board is capable of running both 100M and 1G ethernet. However,
> the i.MX6 has only one ethernet MAC, so it is possible to configure
> either 100M or 1G Ethernet. In case of 100M option, the PHY is on the
> SoM and the signals are routed to a RJ45 port. For 1G the PHY is on
> the PDK2 board with another RJ45 port. 100M and 1G ethernet use
> different signal pins from the i.MX6, but share the MDIO bus.
> 
> This SoM board combination is used to demonstrate how to enable 1G
> ethernet configuration.
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Fabio Estevam <festevam at denx.de>
> Cc: Marek Vasut <marex at denx.de>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: kernel at dh-electronics.com
> To: linux-arm-kernel at lists.infradead.org

Applied, thanks.


From shawnguo at kernel.org  Mon Aug  9 00:31:08 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:31:08 +0800
Subject: [PATCH V7 2/7] ARM: dts: imx6q-dhcom: Rework of the DHCOM GPIO
 pinctrls
In-Reply-To: <20210802141038.59663-2-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
 <20210802141038.59663-2-cniedermaier@dh-electronics.com>
Message-ID: <20210809073107.GH30984@dragon>

On Mon, Aug 02, 2021 at 04:10:33PM +0200, Christoph Niedermaier wrote:
> The function of each SoM pins is defined in the DHCOM standard [1] and
> subset of them is defined as GPIOs (pins A-W). To ensure the interchange-
> ability of the DHCOM SoMs, the function of the pins are fixed and cannot
> be changed. On board level the DHCOM GPIOs can be used associated with
> different blocks e.g. for interrupt or reset, but the function is always
> GPIO. If not used, they can be freely used in the user space.
> 
> Therefore the whole configuration of SoM pins is made in the SoM DT.
> Defining the DHCOM GPIO pins as a separate pinctrl nodes makes moving a
> subset of them to an appropriate block pinctrl group easier on board level,
> since it is not necessary to have a large pinctrl hog group containing
> unrelated pinmux entries on board level. This also makes it easy to update
> the SoM DT without having to update all the board DTs too. If necessary it
> is also possible to change the electrical properties of the DHCOM GPIOs by
> overwriting the pinctrl on board level.
> 
> [1] https://wiki.dh-electronics.com/images/2/2e/DOC_DHCOM-Standard-Specification_R01_2016-11-17.pdf
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Fabio Estevam <festevam at denx.de>
> Cc: Marek Vasut <marex at denx.de>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: kernel at dh-electronics.com
> To: linux-arm-kernel at lists.infradead.org

Applied, thanks!


From ikjn at chromium.org  Mon Aug  9 00:32:31 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Mon, 9 Aug 2021 15:32:31 +0800
Subject: [PATCH 09/11] usb: xhci-mtk: check boundary before check tt
In-Reply-To: <1627635002-24521-9-git-send-email-chunfeng.yun@mediatek.com>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
 <1627635002-24521-9-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <CAATdQgA4qwKb=Uee1pUj-Fk8G31zA40OD7o49W1YLUhZh7BHWA@mail.gmail.com>

Hi Chunfeng,

On Fri, Jul 30, 2021 at 4:50 PM Chunfeng Yun <chunfeng.yun at mediatek.com> wrote:
>
> check_sch_tt() will access fs_bus_bw[] array, check boundary
> firstly to avoid out-of-bounds issue.
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  drivers/usb/host/xhci-mtk-sch.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
> index 10c0f0f6461f..c2f13d69c607 100644
> --- a/drivers/usb/host/xhci-mtk-sch.c
> +++ b/drivers/usb/host/xhci-mtk-sch.c
> @@ -600,13 +600,14 @@ static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
>          * and find a microframe where its worst bandwidth is minimum.
>          */
>         for (offset = 0; offset < sch_ep->esit; offset++) {
> -               ret = check_sch_tt(sch_ep, offset);
> -               if (ret)
> -                       continue;
>
>                 if ((offset + sch_ep->num_budget_microframes) > esit_boundary)
>                         break;

Instead of dropping it,
I'm wondering if it should be checked against (offset & 63) == 0 when it's 64?

>
> +               ret = check_sch_tt(sch_ep, offset);
> +               if (ret)
> +                       continue;
> +
>                 worst_bw = get_max_bw(sch_bw, sch_ep, offset);
>                 if (worst_bw > bw_boundary)
>                         continue;
> --
> 2.18.0
>


From shawnguo at kernel.org  Mon Aug  9 00:34:39 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:34:39 +0800
Subject: [PATCH V7 3/7] ARM: dts: imx6q-dhcom: Rearrange of iomux
In-Reply-To: <20210802141038.59663-3-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
 <20210802141038.59663-3-cniedermaier@dh-electronics.com>
Message-ID: <20210809073439.GI30984@dragon>

On Mon, Aug 02, 2021 at 04:10:34PM +0200, Christoph Niedermaier wrote:
> Move iomux to the end, no change in function.
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Reviewed-by: Marek Vasut <marex at denx.de>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Fabio Estevam <festevam at denx.de>
> Cc: Marek Vasut <marex at denx.de>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: kernel at dh-electronics.com
> To: linux-arm-kernel at lists.infradead.org

Applied, thanks!


From shawnguo at kernel.org  Mon Aug  9 00:35:31 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:35:31 +0800
Subject: [PATCH V7 4/7] ARM: dts: imx6q-dhcom: Cleanup of the devicetrees
In-Reply-To: <20210802141038.59663-4-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
 <20210802141038.59663-4-cniedermaier@dh-electronics.com>
Message-ID: <20210809073530.GJ30984@dragon>

On Mon, Aug 02, 2021 at 04:10:35PM +0200, Christoph Niedermaier wrote:
> Following cleanups of the devicetrees done, no change in function:
> - Remove parentheses from the license
> - Update copyright date
> - Alphabetical sorting
> - Add comments
> - Update pinctrl names
> - Hex values in lower case
> - Set 3rd values of fixed regulators gpio property to 0
> - Replace interrupt type with a define
> - Remove superfluous property max-speed from the fec node
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Reviewed-by: Marek Vasut <marex at denx.de>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Fabio Estevam <festevam at denx.de>
> Cc: Marek Vasut <marex at denx.de>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: kernel at dh-electronics.com
> To: linux-arm-kernel at lists.infradead.org

Applied, thanks!


From shawnguo at kernel.org  Mon Aug  9 00:36:25 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:36:25 +0800
Subject: [PATCH V7 5/7] ARM: dts: imx6qdl-dhcom: Split SoC-independent
 parts of DHCOM SOM and PDK2
In-Reply-To: <20210802141038.59663-5-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
 <20210802141038.59663-5-cniedermaier@dh-electronics.com>
Message-ID: <20210809073624.GK30984@dragon>

On Mon, Aug 02, 2021 at 04:10:36PM +0200, Christoph Niedermaier wrote:
> The DH electronics PDK2 can be populated with SoM with i.MX6S/DL/D/Q
> variants. Split the SoC-independent parts of the SoM and PDK2 into the
> imx6qdl-dhcom-*.dtsi and reduce imx6q-dhcom-pdk2.dts to example of
> adding i.MX6S/DL/D/Q variants of the SoM into a PDK2 carrier board.
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Fabio Estevam <festevam at denx.de>
> Cc: Marek Vasut <marex at denx.de>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: kernel at dh-electronics.com
> To: linux-arm-kernel at lists.infradead.org

Applied, thanks!


From shawnguo at kernel.org  Mon Aug  9 00:38:15 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:38:15 +0800
Subject: [PATCH V7 6/7] ARM: dts: imx6qdl-dhcom: Add DHCOM based PicoITX
 board
In-Reply-To: <20210802141038.59663-6-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
 <20210802141038.59663-6-cniedermaier@dh-electronics.com>
Message-ID: <20210809073807.GL30984@dragon>

On Mon, Aug 02, 2021 at 04:10:37PM +0200, Christoph Niedermaier wrote:
> Add DT for DH PicoITX unit, which is a bare-bones carrier board for
> the DHCOM. The board has ethernet port, USB, CAN, LEDs and a custom
> board-to-board expansion connector.
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Fabio Estevam <festevam at denx.de>
> Cc: Marek Vasut <marex at denx.de>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: kernel at dh-electronics.com
> To: linux-arm-kernel at lists.infradead.org

Applied, thanks!


From shawnguo at kernel.org  Mon Aug  9 00:40:27 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:40:27 +0800
Subject: [PATCH V7 7/7] ARM: dts: imx6qdl-dhcom: Add DHSOM based DRC02
 board
In-Reply-To: <20210802141038.59663-7-cniedermaier@dh-electronics.com>
References: <20210802141038.59663-1-cniedermaier@dh-electronics.com>
 <20210802141038.59663-7-cniedermaier@dh-electronics.com>
Message-ID: <20210809074011.GM30984@dragon>

On Mon, Aug 02, 2021 at 04:10:38PM +0200, Christoph Niedermaier wrote:
> Add DT for DH DRC02 unit, which is a universal controller device.
> The system has two ethernet ports, two CANs, RS485 and RS232, USB,
> capacitive buttons and an OLED display.
> 
> Signed-off-by: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Fabio Estevam <festevam at denx.de>
> Cc: Marek Vasut <marex at denx.de>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: kernel at dh-electronics.com
> To: linux-arm-kernel at lists.infradead.org

Applied, thanks!


From dafna.hirschfeld at collabora.com  Mon Aug  9 00:42:56 2021
From: dafna.hirschfeld at collabora.com (Dafna Hirschfeld)
Date: Mon, 9 Aug 2021 09:42:56 +0200
Subject: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on
In-Reply-To: <CAOak1e_xw84Q+ikAn7TEqie00Sbv4Qpaax==jZ5MJVfPP1pf0Q@mail.gmail.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>
 <8fe5ac46-a9db-710e-a6d1-856805ab2773@collabora.com>
 <CAOak1e_xw84Q+ikAn7TEqie00Sbv4Qpaax==jZ5MJVfPP1pf0Q@mail.gmail.com>
Message-ID: <171db357-0d8a-6676-32dd-7c506708375c@collabora.com>

Hi,

On 09.08.21 05:23, Eizan Miyamoto wrote:
> Hi Dafna, thank you very much for spending time to review the patch,
> your time spent is very much appreciated.
> 
> On Thu, Aug 5, 2021 at 4:06 PM Dafna Hirschfeld
> <dafna.hirschfeld at collabora.com> wrote:
>>> +err_clk_prepare_enable:
>>> +     for (--i; i >= 0; i--) {
>>> +             if (IS_ERR(comp->clk[i]))
>>> +                     continue;
>>> +             clk_disable_unprepare(comp->clk[i]);
>>>        }
>>> +
>>> +     return status;
>>
>> There is an API function clk_bulk_prepare_enable to prepare and enable an array of clks
>> so you can just use it.
> 
> As per Enric's suggestion earlier in this email thread, are you OK
> with me making this change in a follow-up patch, particularly since
> the logic as it is was preserved from previous functionality?

sure,
I just give suggestions.
A follow-up patch would be nice.

> 
>>> -static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
>>> +static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
>>>    {
>>> -     struct device *dev = &mdp->pdev->dev;
>>>        struct mtk_mdp_comp *comp_node;
>>> +     int status;
>>> +     struct device *dev = &mdp->pdev->dev;
>>> +     int err;
>>>
>>> -     list_for_each_entry(comp_node, &mdp->comp_list, node)
>>> -             mtk_mdp_comp_clock_on(dev, comp_node);
>>> +     list_for_each_entry(comp_node, &mdp->comp_list, node) {
>>> +             err = mtk_mdp_comp_clock_on(dev, comp_node);
>>> +             if (err) {
>>> +                     status = err;
>>
>> You can get rid of the new var 'status' and just return ret in case of error
> 
> This seems like a nit (please let me know if you disagree), and it's
> also cleaned up in a follow-on patch in the series ("don't
> pm_run_time_get/put for master comp in clock_on"). Is making the
> change you are suggesting here something that should require uploading
> a new series version?

Hi, no, I am fine with it. No need for new version.


Thanks,
Dafna

> 
> Eizan
> 


From shawnguo at kernel.org  Mon Aug  9 00:46:23 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 15:46:23 +0800
Subject: [PATCH v2 1/2] arm64: dts: ls1046a: fix eeprom entries
In-Reply-To: <1628105086-8172-2-git-send-email-raagjadav@gmail.com>
References: <1628105086-8172-1-git-send-email-raagjadav@gmail.com>
 <1628105086-8172-2-git-send-email-raagjadav@gmail.com>
Message-ID: <20210809074623.GN30984@dragon>

On Thu, Aug 05, 2021 at 12:54:45AM +0530, Raag Jadav wrote:
> ls1046afrwy and ls1046ardb boards have CAT24C04[1] and CAT24C05[2]
> eeproms respectively. Both are 4Kb (512 bytes) in size,
> and compatible with AT24C04[3].
> Remove multi-address entries, as both the boards have a single chip each.
> 
> [1] https://www.onsemi.com/pdf/datasheet/cat24c01-d.pdf
> [2] https://www.onsemi.com/pdf/datasheet/cat24c03-d.pdf
> [3] https://ww1.microchip.com/downloads/en/DeviceDoc/doc0180.pdf
> 
> Signed-off-by: Raag Jadav <raagjadav at gmail.com>

Applied, thanks!


From dafna.hirschfeld at collabora.com  Mon Aug  9 00:53:32 2021
From: dafna.hirschfeld at collabora.com (Dafna Hirschfeld)
Date: Mon, 9 Aug 2021 09:53:32 +0200
Subject: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components
In-Reply-To: <CAOak1e8n6JpNKODfM57OTtbCNz8UBbj+wefwipVWP_Ep6SHmHA@mail.gmail.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
 <0aff1abb-734f-c714-6ecc-c906862255c3@collabora.com>
 <CAOak1e8n6JpNKODfM57OTtbCNz8UBbj+wefwipVWP_Ep6SHmHA@mail.gmail.com>
Message-ID: <014b8075-8588-d741-e6f2-edc0567e8c8f@collabora.com>



On 09.08.21 05:23, Eizan Miyamoto wrote:
> Hi Dafna,
> 
> On Thu, Aug 5, 2021 at 4:40 PM Dafna Hirschfeld
> <dafna.hirschfeld at collabora.com> wrote:
>>> +int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
>>
>> This function can be static
> 
> If it's all the same to you, are you okay for me to make this change either:
> - If upstream requests changes be made to this series, I will include
> this suggestion
> - If the series is accepted as-is, I will make a follow-up patch
> 
> This is to reduce workload on reviewers having to re-ack changes for
> (what I hope you agree is) a nit.

I think you can keep the review-by tag of the reviewers since this is just a nit.
So sending a new version won't need a re-ack from the reviewers.

You can send it also as a separate patch. I don't care too much.

> 
> If you don't agree, I will happily oblige and make the change and
> upload a new version of the series.
> 
>>>        for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
>>>                comp->clk[i] = of_clk_get(node, i);
>>
>> that iteration can be replaced with clk_bulk_get
> 
> As per Enric's suggestion in response to "propagate errors from
> clock_on" in this series, are you okay for me to make the change in a
> follow-up patch?

yes,

Thanks,
Dafna

> 
> Thanks again for your review,
> 
> Eizan
> 


From Yong.Wu at mediatek.com  Mon Aug  9 01:00:34 2021
From: Yong.Wu at mediatek.com (=?utf-8?B?WW9uZyBXdSAo5ZC05YuHKQ==?=)
Date: Mon, 9 Aug 2021 08:00:34 +0000
Subject: [PATCH v7 04/12] iommu/mediatek: Add device_link between the
 consumer and the larb devices
In-Reply-To: <3f359c03-df44-2410-3172-2f17e620cada@collabora.com>
References: <20210730025238.22456-1-yong.wu@mediatek.com>
 <20210730025238.22456-5-yong.wu@mediatek.com>
 <3f359c03-df44-2410-3172-2f17e620cada@collabora.com>
Message-ID: <1bea58ed853eab23d4af8829538ab9aa22cbd340.camel@mediatek.com>

On Thu, 2021-08-05 at 15:22 +0200, Dafna Hirschfeld wrote:
> 
> On 30.07.21 04:52, Yong Wu wrote:
> > MediaTek IOMMU-SMI diagram is like below. all the consumer connect
> > with
> > smi-larb, then connect with smi-common.
> > 
> >          M4U
> >           |
> >      smi-common
> >           |
> >    -------------
> >    |         |    ...
> >    |         |
> > larb1     larb2
> >    |         |
> > vdec       venc
> > 
> > When the consumer works, it should enable the smi-larb's power
> > which
> > also need enable the smi-common's power firstly.
> > 
> > Thus, First of all, use the device link connect the consumer and
> > the
> > smi-larbs. then add device link between the smi-larb and smi-
> > common.
> > 
> > This patch adds device_link between the consumer and the larbs.
> > 
> > When device_link_add, I add the flag DL_FLAG_STATELESS to avoid
> > calling
> > pm_runtime_xx to keep the original status of clocks. It can avoid
> > two
> > issues:
> > 1) Display HW show fastlogo abnormally reported in [1]. At the
> > beggining,
> > all the clocks are enabled before entering kernel, but the clocks
> > for
> > display HW(always in larb0) will be gated after clk_enable and
> > clk_disable
> > called from device_link_add(->pm_runtime_resume) and rpm_idle. The
> > clock
> > operation happened before display driver probe. At that time, the
> > display
> > HW will be abnormal.
> > 
> > 2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip
> > pm_runtime_xx to avoid the deadlock.
> > 
> > Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then
> > device_link_removed should be added explicitly.
> > 
> > [1] 
> > https://lore.kernel.org/linux-mediatek/1564213888.22908.4.camel at mhfsdcap03/
> > [2] https://lore.kernel.org/patchwork/patch/1086569/
> > 
> > Suggested-by: Tomasz Figa <tfiga at chromium.org>
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > Tested-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com> # on
> > mt8173
> 
> Hi, unfortunately, I have to take back the Tested-by tag.

sorry for inconvenience you.

(and sorry for reply late, there is something wrong about my local mail
server.)

> I am now testing the mtk-vcodec with latest kernel + patches sent
> from the mailing list:
> 
https://gitlab.collabora.com/eballetbo/linux/-/commits/topic/chromeos/chromeos-5.14
> which includes this patchset.
> 
> On chromeos I open a video conference with googl-meet which cause the
> mtk-vcodec vp8 encoder to run.
> If I kill it with `killall -9 chrome` I get some page fault messages
> from the iommu:

Does the "git bisect" point to this patch?

If you don't kill it, Does it also have these error below?

I don't know what happen about "killall -9 chrome', Does it cause
freeing some buffer?

> 
> [  837.255952] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read

This means "larb0 port0" translation fault. 

If I am not wrong, you work at mt8173, from [0], this is DISP_OVL0.

May be "killall -9 chrome" free the buffer(iova:0xfcff0000) that
DISP_OVL is accessing, then iommu complain it is not a valid iova.

[0] 
https://elixir.bootlin.com/linux/v5.14-rc1/source/include/dt-bindings/memory/mt8173-larb-port.h#L19

> [  837.265696] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> [  837.282367] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> [  837.299028] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> [  837.315683] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> [  837.332345] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> [  837.349004] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> [  837.365665] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> [  837.382329] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> [  837.400002] mtk-iommu 10205000.iommu: fault type=0x5
> iova=0xfcff0001 pa=0x0 larb=0 port=0 layer=1 read
> 
> In addition, running the encoder tests from the shell:
> 
> sudo --user=#1000 /usr/local/libexec/chrome-binary-
> tests/video_encode_accelerator_tests --
> gtest_filter=VideoEncoderTest.FlushAtEndOfStream_Multiple*  
> --codec=vp8
> /usr/local/share/tast/data/chromiumos/tast/local/bundles/cros/video/d
> ata/tulip2-320x180.yuv --disable_validator
> 
> At some point it fails with the error
> 
> [ 5472.161821] [MTK_V4L2][ERROR] mtk_vcodec_wait_for_done_ctx:32:
> [290] ctx->type=1, cmd=1, wait_event_interruptible_timeout
> time=1000ms out 0 0!
> [ 5472.174678] [MTK_VCODEC][ERROR][290]: vp8_enc_encode_frame()
> irq_status=0 failed
> [ 5472.182687] [MTK_V4L2][ERROR] mtk_venc_worker:1239: venc_if_encode
> failed=-5

+our venc guy Irui.

This looks VENC HW don't start to work. Does this caused by this
patchset?  this patchset only change the flow of power.

I guess we should check if the power/clock for venc here is enable or
not?

> 
> 
> If you have any idea of what might be the problem or how to debug?
> 
> Thanks,
> Dafna
> 
> > --

From shawnguo at kernel.org  Mon Aug  9 01:03:47 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 16:03:47 +0800
Subject: [PATCH 8/8] MAINTAINERS: Add an entry for NXP S32G2 boards
In-Reply-To: <32310c2a-9800-8b04-b6ac-d8ada044c0f8@kernel.org>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-9-clin@suse.com>
 <32310c2a-9800-8b04-b6ac-d8ada044c0f8@kernel.org>
Message-ID: <20210809080346.GO30984@dragon>

On Thu, Aug 05, 2021 at 09:49:51AM +0200, Krzysztof Kozlowski wrote:
> On 05/08/2021 08:54, Chester Lin wrote:
> > Add a new entry for the maintenance of NXP S32G2 DT files.
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  MAINTAINERS | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 36aee8517ab0..3c6ba6cefd8f 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2281,6 +2281,12 @@ F:	arch/arm/boot/dts/nuvoton-wpcm450*
> >  F:	arch/arm/mach-npcm/wpcm450.c
> >  F:	drivers/*/*wpcm*
> >  
> > +ARM/NXP S32G2 ARCHITECTURE
> > +M:	Chester Lin <clin at suse.com>
> > +L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> > +S:	Maintained
> > +F:	arch/arm64/boot/dts/freescale/s32g2*
> 
> I support the idea of sub-sub-architecture maintainers but I think idea
> of in-file addresses was preferred:
> https://lore.kernel.org/lkml/20200830122922.3884-1-shawnguo at kernel.org/

Thanks for reminding that the patch didn't land.  I just resent it with
your Reviewed-by tag added.  Thanks!

Shawn


From shawnguo at kernel.org  Mon Aug  9 01:06:43 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 16:06:43 +0800
Subject: [PATCH 0/8] arm64: dts: initial NXP S32G2 support
In-Reply-To: <20210805065429.27485-1-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
Message-ID: <20210809080642.GP30984@dragon>

On Thu, Aug 05, 2021 at 02:54:21PM +0800, Chester Lin wrote:
> Hello,
> 
> Here I'd like to propose a patchset, which is initial upstream support for NXP
> S32G2. S32G is a processor family developed by NXP for automotive solutions,
> such as vehicle networking and automotive high-performance processing. This
> series focuses on S32G2, which is the latest generation we can find at the
> moment. As the first round to support S32G2, this patchset only enables basic
> components and interfaces the SoC must have while kernel booting, which aims
> to have minimum hardware enablement for these two boards, S32G-VNP-EVB and
> S32G-VNP-RDB2. The concepts of how these boards work are originated from the
> downstream kernel tree[1] developed by NXP, which provides lots of details
> about the SoC S32G274A and its integrated boards. This series has been
> verified with downstream ATF[2] & U-Boot[3] based on the ATF boot flow.
> 
> Thanks,
> Chester
> 
> [1] https://source.codeaurora.org/external/autobsps32/linux/
> [2] https://source.codeaurora.org/external/autobsps32/arm-trusted-firmware/
> [3] https://source.codeaurora.org/external/autobsps32/u-boot/
> 
> Chester Lin (8):
>   dt-bindings: arm: fsl: add NXP S32G2 boards
>   dt-bindings: serial: fsl-linflexuart: convert to json-schema format
>   dt-bindings: serial: fsl-linflexuart: Add compatible for S32G2
>   arm64: dts: add NXP S32G2 support
>   arm64: dts: s32g2: add serial/uart support
>   arm64: dts: s32g2: add VNP-EVB and VNP-RDB2 support
>   arm64: dts: s32g2: add memory nodes for evb and rdb2

The dts changes look good to me.  I will pick up the series once
bindings gets acked by Rob.

Shawn

>   MAINTAINERS: Add an entry for NXP S32G2 boards
> 
>  .../devicetree/bindings/arm/fsl.yaml          |   7 +
>  .../bindings/serial/fsl,s32-linflexuart.txt   |  22 ---
>  .../bindings/serial/fsl,s32-linflexuart.yaml  |  66 +++++++++
>  MAINTAINERS                                   |   6 +
>  arch/arm64/boot/dts/freescale/Makefile        |   2 +
>  arch/arm64/boot/dts/freescale/s32g2.dtsi      | 129 ++++++++++++++++++
>  .../arm64/boot/dts/freescale/s32g274a-evb.dts |  29 ++++
>  .../boot/dts/freescale/s32g274a-rdb2.dts      |  33 +++++
>  8 files changed, 272 insertions(+), 22 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
>  create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
>  create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> 
> -- 
> 2.30.0
> 


From shawnguo at kernel.org  Mon Aug  9 01:13:51 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 16:13:51 +0800
Subject: [PATCH 0/3] arm64: dts: imx: pmu update
In-Reply-To: <20210807094537.20290-1-peng.fan@oss.nxp.com>
References: <20210807094537.20290-1-peng.fan@oss.nxp.com>
Message-ID: <20210809081350.GS30984@dragon>

On Sat, Aug 07, 2021 at 05:45:34PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Update pmu compatible
> Drop interrupt affinity
> 
> Peng Fan (3):
>   arm64: dts: imx8mm: update pmu compatible
>   arm64: dts: imx8qxp: update pmu compatible
>   arm64: dts: imx8m: drop interrupt-affinity for pmu

Applied all, thanks!


From l.stach at pengutronix.de  Mon Aug  9 01:15:48 2021
From: l.stach at pengutronix.de (Lucas Stach)
Date: Mon, 09 Aug 2021 10:15:48 +0200
Subject: [PATCH V2 00/13] soc: imx: gpcv2: support i.MX8MM
In-Reply-To: <CAAEAJfDfjkHF164x2qRnZg3e5JRN0pHjxyAq+d5+-3JFYwEEOQ@mail.gmail.com>
References: <20210506010440.7016-1-peng.fan@oss.nxp.com>
 <CAAEAJfDfjkHF164x2qRnZg3e5JRN0pHjxyAq+d5+-3JFYwEEOQ@mail.gmail.com>
Message-ID: <d19d35e8a90ece7124d06855b9f2b226b73c8f6e.camel@pengutronix.de>

Hi Ezequiel,

Am Mittwoch, dem 04.08.2021 um 11:30 -0300 schrieb Ezequiel Garcia:
> Hi Peng, Lucas,
> 
> On Wed, 5 May 2021 at 21:32, Peng Fan (OSS) <peng.fan at oss.nxp.com> wrote:
> > 
> > From: Peng Fan <peng.fan at nxp.com>
> > 
> > 
> > V2:
> >  - Add R-b/A-b tag
> >  - Merge V1 patch 13 to V2 patch 6
> >  - Drop V1 patch 15
> >  - Merge V1 patch 16 to V2 patch 5 and add comments in patch 5 to explain
> >  details
> >  - Add explaination in patch 8 for "why the resets are not defined"
> > 
> > This patchset is a pick up Lucas's gpcv2 work for i.MX8MM and several
> > minor changes from me to make it could work with i.MX BLK-CTL driver.
> > 
> > Thanks for Lucas's work and suggestion, Frieder Schrempf for collecting
> > all the patches, Jacky Bai on help debug issues.
> > 
> > Lucas Stach (12):
> >   soc: imx: gpcv2: move to more ideomatic error handling in probe
> >   soc: imx: gpcv2: move domain mapping to domain driver probe
> >   soc: imx: gpcv2: switch to clk_bulk_* API
> >   soc: imx: gpcv2: split power up and power down sequence control
> >   soc: imx: gpcv2: wait for ADB400 handshake
> >   soc: imx: gpcv2: add runtime PM support for power-domains
> >   soc: imx: gpcv2: allow domains without power-sequence control
> >   dt-bindings: imx: gpcv2: add support for optional resets
> >   soc: imx: gpcv2: add support for optional resets
> >   dt-bindings: power: add defines for i.MX8MM power domains
> >   soc: imx: gpcv2: add support for i.MX8MM power domains
> >   soc: imx: gpcv2: Add support for missing i.MX8MM VPU/DISPMIX power
> >     domains
> > 
> 
> It's nice to see this finally moving forward!
> 
> As you know, Hantro G2 support for i.MX8MQ (and i.MX8MP, i.MX8MM) is currently
> blocked, as you have requested:
> 
> https://lore.kernel.org/driverdev-devel/5aa5700b862234895a7a6eb251ca3c80fdc1a6d3.camel at collabora.com/
> 
> So, I think we really need to include i.MX8MP and i.MX8MQ on this series.
> It's been quite a while and we really need to have that. To be honest,
> I fear that
> if we merge this series as-is, MX8MP and MX8MP support will fall in
> the oblivion,
> and Hantro G2 VPU will remain unusable.
> 
> We are planning to submit Hantro G2 VP9 support soon, and we've been testing
> on various platforms, but it will also be blocked by lack of power-domains.
> 
> In the future, please Cc the linux-media mailing list, as well as
> Benjamin, Andrzej and myself, so we can follow this.

Please take a look at [1], which is the current state of this work. I
intend to add both i.MX8MQ and i.MX8MP support to the series now, as it
seems that there have been no big objections to my approach over the
last 2 weeks, where I was on vacation. ;)

Regards,
Lucas

[1]
https://lore.kernel.org/linux-arm-kernel/20210716232916.3572966-14-l.stach at pengutronix.de/T/#m43cbf6b8615b2a37ff2abb0346e7e7f6594976d1




From shawnguo at kernel.org  Mon Aug  9 01:16:29 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 9 Aug 2021 16:16:29 +0800
Subject: [PATCH] arm64: dts: imx8qm: add smmu node
In-Reply-To: <20210807104517.24066-1-peng.fan@oss.nxp.com>
References: <20210807104517.24066-1-peng.fan@oss.nxp.com>
Message-ID: <20210809081628.GT30984@dragon>

On Sat, Aug 07, 2021 at 06:45:17PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> i.MX8QM has an iommu unit: SMMU-V2(mmu-500), add it.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8qm.dtsi | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> index aebbe2b84aa1..b8ffd5be6a3e 100644
> --- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> @@ -165,6 +165,22 @@ iomuxc: pinctrl {
>  
>  	};
>  
> +	smmu: iommu at 51400000 {
> +		compatible = "arm,mmu-500";
> +		reg = <0 0x51400000 0 0x40000>;
> +		#iommu-cells = <2>;
> +		#global-interrupts = <1>;
> +		interrupts = <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>;

Use macro to make it more readable.

Shawn

> +	};
> +
>  	/* sorted in register address */
>  	#include "imx8-ss-img.dtsi"
>  	#include "imx8-ss-dma.dtsi"
> -- 
> 2.30.0
> 


From Yong.Wu at mediatek.com  Mon Aug  9 01:30:03 2021
From: Yong.Wu at mediatek.com (=?utf-8?B?WW9uZyBXdSAo5ZC05YuHKQ==?=)
Date: Mon, 9 Aug 2021 08:30:03 +0000
Subject: [PATCH v7 00/12] Clean up "mediatek,larb"
In-Reply-To: <YQfALZNWyw8VKODp@8bytes.org>
References: <20210730025238.22456-1-yong.wu@mediatek.com>
 <YQfALZNWyw8VKODp@8bytes.org>
Message-ID: <ed099698f63bec6771561bcad7022dbff184ce7f.camel@mediatek.com>

On Mon, 2021-08-02 at 11:51 +0200, Joerg Roedel wrote:
> On Fri, Jul 30, 2021 at 10:52:26AM +0800, Yong Wu wrote:
> >  .../display/mediatek/mediatek,disp.txt        |  9 ----
> >  .../bindings/media/mediatek-jpeg-decoder.yaml |  9 ----
> >  .../bindings/media/mediatek-jpeg-encoder.yaml |  9 ----
> >  .../bindings/media/mediatek-mdp.txt           |  8 ----
> >  .../bindings/media/mediatek-vcodec.txt        |  4 --
> >  arch/arm/boot/dts/mt2701.dtsi                 |  2 -
> >  arch/arm/boot/dts/mt7623n.dtsi                |  5 --
> >  arch/arm64/boot/dts/mediatek/mt8173.dtsi      | 16 -------
> >  arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  6 ---
> >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c       |  9 +++-
> >  drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |  9 +++-
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 15 +++---
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   | 36 +--------------
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  1 -
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  5 +-
> >  drivers/iommu/mtk_iommu.c                     | 24 +++++++++-
> >  drivers/iommu/mtk_iommu_v1.c                  | 31 ++++++++++++-
> >  .../media/platform/mtk-jpeg/mtk_jpeg_core.c   | 45 +------------
> > -----
> >  .../media/platform/mtk-jpeg/mtk_jpeg_core.h   |  2 -
> >  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 46 +------------
> > ------
> >  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 -
> >  drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  1 -
> >  .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 37 ++-------------
> >  .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  3 --
> >  .../platform/mtk-vcodec/mtk_vcodec_enc.c      |  1 -
> >  .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 44 ++-------------
> > ---
> >  drivers/memory/mtk-smi.c                      | 14 ------
> >  include/soc/mediatek/smi.h                    | 20 --------
> >  28 files changed, 92 insertions(+), 321 deletions(-)
> 
> So this is likely not going through the IOMMU tree, given Matthias
> has
> reviewed the IOMMU changes you can add my Acked-by: Joerg Roedel <
> jroedel at suse.de>

Hi Joerg,

Thanks very much for your confirm. I will your Ack for iommu part in
the next version.


From vkoul at kernel.org  Mon Aug  9 01:41:38 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 9 Aug 2021 14:11:38 +0530
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
 <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
Message-ID: <YRDqQvKQ71/824Lu@matsya>

On 09-08-21, 05:16, A, Rashmi wrote:

> > 
> > Rashmi, is it safe to apply this separately from the phy driver/dt changes?
> > Then I can queue this via my mmc tree, if you like.
> No, the phy driver/dt changes must go together with "mmc: sdhci-of-arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver" patch.

Why is that?

What could happen, emmc driver will complain about phy not found and
bail right?

-- 
~Vinod


From ikjn at chromium.org  Mon Aug  9 01:59:29 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Mon,  9 Aug 2021 16:59:29 +0800
Subject: [RFC PATCH] usb: xhci-mtk: handle bandwidth table rollover
Message-ID: <20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid>

xhci-mtk has 64 slots for periodic bandwidth calculations and each
slot represents byte budgets on a microframe. When an endpoint's
allocation sits on the boundary of the table, byte budgets' slot
should be rolled over but the current implementation doesn't.

This patch applies a 6 bits mask to the microframe index to handle
its rollover 64 slots and prevent out-of-bounds array access.

Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
---

 drivers/usb/host/xhci-mtk-sch.c | 79 +++++++++------------------------
 drivers/usb/host/xhci-mtk.h     |  1 +
 2 files changed, 23 insertions(+), 57 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 46cbf5d54f4f..ef16cd124343 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -411,18 +411,13 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, u32 offset)
 {
-	u32 num_esit;
-	u32 max_bw = 0;
-	u32 bw;
-	int i;
-	int j;
-
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-	for (i = 0; i < num_esit; i++) {
-		u32 base = offset + i * sch_ep->esit;
+	u32 bw, max_bw = 0;
+	int i, j, idx;
 
+	for (i = 0; i < XHCI_MTK_MAX_ESIT; i += sch_ep->esit) {
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
-			bw = sch_bw->bus_bw[base + j] +
+			idx = XHCI_MTK_BW_IDX(i + offset + j);
+			bw = sch_bw->bus_bw[idx] +
 					sch_ep->bw_budget_table[j];
 			if (bw > max_bw)
 				max_bw = bw;
@@ -434,20 +429,16 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, bool used)
 {
-	u32 num_esit;
-	u32 base;
-	int i;
-	int j;
+	int i, j, idx;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-	for (i = 0; i < num_esit; i++) {
-		base = sch_ep->offset + i * sch_ep->esit;
+	for (i = 0; i < XHCI_MTK_MAX_ESIT; i += sch_ep->esit) {
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			idx = XHCI_MTK_BW_IDX(i + sch_ep->offset + j);
 			if (used)
-				sch_bw->bus_bw[base + j] +=
+				sch_bw->bus_bw[idx] +=
 					sch_ep->bw_budget_table[j];
 			else
-				sch_bw->bus_bw[base + j] -=
+				sch_bw->bus_bw[idx] -=
 					sch_ep->bw_budget_table[j];
 		}
 	}
@@ -456,22 +447,18 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
-	u32 num_esit, tmp;
-	int base;
-	int i, j;
+	u32 bw;
+	int i, j, idx;
 	u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-
 	if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
 		offset++;
 
-	for (i = 0; i < num_esit; i++) {
-		base = offset + i * sch_ep->esit;
-
+	for (i = 0; i < XHCI_MTK_MAX_ESIT; i += sch_ep->esit) {
 		for (j = 0; j < uframes; j++) {
-			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
-			if (tmp > FS_PAYLOAD_MAX)
+			idx = XHCI_MTK_BW_IDX(i + offset + j);
+			bw = tt->fs_bus_bw[idx] + sch_ep->bw_cost_per_microframe;
+			if (bw > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
 		}
 	}
@@ -544,14 +531,11 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
 static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
-	u32 base, num_esit;
 	int bw_updated;
-	int i, j;
+	int i, j, idx;
 	int offset = sch_ep->offset;
 	u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-
 	if (used)
 		bw_updated = sch_ep->bw_cost_per_microframe;
 	else
@@ -560,11 +544,11 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
 		offset++;
 
-	for (i = 0; i < num_esit; i++) {
-		base = offset + i * sch_ep->esit;
-
-		for (j = 0; j < uframes; j++)
-			tt->fs_bus_bw[base + j] += bw_updated;
+	for (i = 0; i < XHCI_MTK_MAX_ESIT; i += sch_ep->esit) {
+		for (j = 0; j < uframes; j++) {
+			idx = XHCI_MTK_BW_IDX(i + offset + j);
+			tt->fs_bus_bw[idx] += bw_updated;
+		}
 	}
 
 	if (used)
@@ -586,25 +570,9 @@ static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw,
 	return 0;
 }
 
-static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
-{
-	u32 boundary = sch_ep->esit;
-
-	if (sch_ep->sch_tt) { /* LS/FS with TT */
-		/* tune for CS */
-		if (sch_ep->ep_type != ISOC_OUT_EP)
-			boundary++;
-		else if (boundary > 1) /* normally esit >= 8 for FS/LS */
-			boundary--;
-	}
-
-	return boundary;
-}
-
 static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 {
 	struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info;
-	const u32 esit_boundary = get_esit_boundary(sch_ep);
 	const u32 bw_boundary = get_bw_boundary(sch_ep->speed);
 	u32 offset;
 	u32 worst_bw;
@@ -621,9 +589,6 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 		if (ret)
 			continue;
 
-		if ((offset + sch_ep->num_budget_microframes) > esit_boundary)
-			break;
-
 		worst_bw = get_max_bw(sch_bw, sch_ep, offset);
 		if (worst_bw > bw_boundary)
 			continue;
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index ddcf25524f67..f627941c4860 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -23,6 +23,7 @@
  * bandwidth to it.
  */
 #define XHCI_MTK_MAX_ESIT	64
+#define XHCI_MTK_BW_IDX(idx)	((idx) & 63)
 
 /**
  * @fs_bus_bw: array to keep track of bandwidth already used for FS
-- 
2.32.0.605.g8dce9f2422-goog



From hverkuil-cisco at xs4all.nl  Mon Aug  9 02:09:50 2021
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Mon, 9 Aug 2021 11:09:50 +0200
Subject: [PATCH v2 9/9] media: stm32-dma2d: STM32 DMA2D driver
In-Reply-To: <1626341068-20253-20-git-send-email-dillon.minfei@gmail.com>
References: <1626341068-20253-1-git-send-email-dillon.minfei@gmail.com>
 <1626341068-20253-20-git-send-email-dillon.minfei@gmail.com>
Message-ID: <cb22a3b2-5021-c246-d52b-dc6df78cd4c9@xs4all.nl>

On 15/07/2021 11:24, dillon.minfei at gmail.com wrote:
> From: Dillon Min <dillon.minfei at gmail.com>
> 
> This V4L2 subdev m2m driver enables Chrom-Art Accelerator unit
> of STMicroelectronics STM32 SoC series.
> 
> Currently support r2m, m2m, m2m_pfc functions.
> - r2m, Filling a part or the whole of a destination image with a specific
>   color.
> - m2m, Copying a part or the whole of a source image into a part or the
>   whole of a destination.
> - m2m_pfc, Copying a part or the whole of a source image into a part or the
>   whole of a destination image with a pixel format conversion.
> 
> Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
> ---
> v2: all the changes are based on Hans's review, thanks.
> - update Kconfig, replace ',' to 'and', add '.' at the description end,
>   add COMPILE_TEST.
> - fix a lots of warrnings from checkpatch.pl --strict.
> - add const to formats[] and def_frame.
> - chage line_ofs to line_offset.
> - replace ctx->fg to ctx->cap.
> - change implemention of get_frame().
> - move the ioctls definition from the code to stm32-media.h.
> - change "Set to r2m mode" to "Set R2M Mode".
> - add decription for r2m, m2m, m2m_pfc.
> 
>  drivers/media/platform/Kconfig                  |   9 +
>  drivers/media/platform/Makefile                 |   1 +
>  drivers/media/platform/stm32/Makefile           |   2 +
>  drivers/media/platform/stm32/dma2d/dma2d-hw.c   | 143 +++++
>  drivers/media/platform/stm32/dma2d/dma2d-regs.h | 113 ++++
>  drivers/media/platform/stm32/dma2d/dma2d.c      | 796 ++++++++++++++++++++++++
>  drivers/media/platform/stm32/dma2d/dma2d.h      | 136 ++++
>  7 files changed, 1200 insertions(+)
>  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d-hw.c
>  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d-regs.h
>  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d.c
>  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d.h
> 
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index 157c924686e4..4df18623e4ad 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -473,6 +473,15 @@ config VIDEO_STI_DELTA_DRIVER
>  
>  endif # VIDEO_STI_DELTA
>  
> +config VIDEO_STM32_DMA2D
> +	tristate "STM32 Chrom-Art Accelerator (DMA2D)"
> +	depends on (VIDEO_DEV && VIDEO_V4L2 && ARCH_STM32) || COMPILE_TEST
> +	select VIDEOBUF2_DMA_CONTIG
> +	select V4L2_MEM2MEM_DEV
> +	help
> +	  The STM32 DMA2D is a memory-to-memory engine for pixel conversion
> +	  and specialized DMA dedicated to image manipulation.
> +
>  config VIDEO_RENESAS_FDP1
>  	tristate "Renesas Fine Display Processor"
>  	depends on VIDEO_DEV && VIDEO_V4L2
> diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
> index 73ce083c2fc6..46f1c05bc576 100644
> --- a/drivers/media/platform/Makefile
> +++ b/drivers/media/platform/Makefile
> @@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_ATMEL_ISI)		+= atmel/
>  obj-$(CONFIG_VIDEO_ATMEL_XISC)		+= atmel/
>  
>  obj-$(CONFIG_VIDEO_STM32_DCMI)		+= stm32/
> +obj-$(CONFIG_VIDEO_STM32_DMA2D)		+= stm32/
>  
>  obj-$(CONFIG_VIDEO_MEDIATEK_VPU)	+= mtk-vpu/
>  
> diff --git a/drivers/media/platform/stm32/Makefile b/drivers/media/platform/stm32/Makefile
> index 48b36db2c2e2..896ef98a73ab 100644
> --- a/drivers/media/platform/stm32/Makefile
> +++ b/drivers/media/platform/stm32/Makefile
> @@ -1,2 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32-dcmi.o
> +stm32-dma2d-objs := dma2d/dma2d.o dma2d/dma2d-hw.o
> +obj-$(CONFIG_VIDEO_STM32_DMA2D) += stm32-dma2d.o
> diff --git a/drivers/media/platform/stm32/dma2d/dma2d-hw.c b/drivers/media/platform/stm32/dma2d/dma2d-hw.c
> new file mode 100644
> index 000000000000..8c1c664ab13b
> --- /dev/null
> +++ b/drivers/media/platform/stm32/dma2d/dma2d-hw.c
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * ST stm32 Chrom-Art - 2D Graphics Accelerator Driver
> + *
> + * Copyright (c) 2021 Dillon Min
> + * Dillon Min, <dillon.minfei at gmail.com>
> + *
> + * based on s5p-g2d
> + *
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + * Kamil Debski, <k.debski at samsung.com>
> + */
> +
> +#include <linux/io.h>
> +
> +#include "dma2d.h"
> +#include "dma2d-regs.h"
> +
> +static inline u32 reg_read(void __iomem *base, u32 reg)
> +{
> +	return readl_relaxed(base + reg);
> +}
> +
> +static inline void reg_write(void __iomem *base, u32 reg, u32 val)
> +{
> +	writel_relaxed(val, base + reg);
> +}
> +
> +static inline void reg_set(void __iomem *base, u32 reg, u32 mask)
> +{
> +	reg_write(base, reg, reg_read(base, reg) | mask);
> +}
> +
> +static inline void reg_clear(void __iomem *base, u32 reg, u32 mask)
> +{
> +	reg_write(base, reg, reg_read(base, reg) & ~mask);
> +}
> +
> +static inline void reg_update_bits(void __iomem *base, u32 reg, u32 mask,
> +				   u32 val)
> +{
> +	reg_write(base, reg, (reg_read(base, reg) & ~mask) | val);
> +}
> +
> +void dma2d_start(struct dma2d_dev *d)
> +{
> +	reg_update_bits(d->regs, DMA2D_CR_REG, CR_START, CR_START);
> +}
> +
> +u32 dma2d_get_int(struct dma2d_dev *d)
> +{
> +	return reg_read(d->regs, DMA2D_ISR_REG);
> +}
> +
> +void dma2d_clear_int(struct dma2d_dev *d)
> +{
> +	u32 isr_val = reg_read(d->regs, DMA2D_ISR_REG);
> +
> +	reg_write(d->regs, DMA2D_IFCR_REG, isr_val & 0x003f);
> +}
> +
> +void dma2d_config_common(struct dma2d_dev *d, enum dma2d_op_mode op_mode,
> +			 u16 width, u16 height)
> +{
> +	reg_update_bits(d->regs, DMA2D_CR_REG, CR_MODE_MASK,
> +			op_mode << CR_MODE_SHIFT);
> +
> +	reg_write(d->regs, DMA2D_NLR_REG, (width << 16) | height);
> +}
> +
> +void dma2d_config_out(struct dma2d_dev *d, struct dma2d_frame *frm,
> +		      dma_addr_t o_addr)
> +{
> +	reg_update_bits(d->regs, DMA2D_CR_REG, CR_CEIE, CR_CEIE);
> +	reg_update_bits(d->regs, DMA2D_CR_REG, CR_CTCIE, CR_CTCIE);
> +	reg_update_bits(d->regs, DMA2D_CR_REG, CR_CAEIE, CR_CAEIE);
> +	reg_update_bits(d->regs, DMA2D_CR_REG, CR_TCIE, CR_TCIE);
> +	reg_update_bits(d->regs, DMA2D_CR_REG, CR_TEIE, CR_TEIE);
> +
> +	if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
> +	    frm->fmt->cmode <= CM_MODE_ARGB4444)
> +		reg_update_bits(d->regs, DMA2D_OPFCCR_REG, OPFCCR_CM_MASK,
> +				frm->fmt->cmode);
> +
> +	reg_write(d->regs, DMA2D_OMAR_REG, o_addr);
> +
> +	reg_write(d->regs, DMA2D_OCOLR_REG,
> +		  (frm->a_rgb[3] << 24) |
> +		  (frm->a_rgb[2] << 16) |
> +		  (frm->a_rgb[1] << 8) |
> +		  frm->a_rgb[0]);
> +
> +	reg_update_bits(d->regs, DMA2D_OOR_REG, OOR_LO_MASK,
> +			frm->line_offset & 0x3fff);
> +}
> +
> +void dma2d_config_fg(struct dma2d_dev *d, struct dma2d_frame *frm,
> +		     dma_addr_t f_addr)
> +{
> +	reg_write(d->regs, DMA2D_FGMAR_REG, f_addr);
> +	reg_update_bits(d->regs, DMA2D_FGOR_REG, FGOR_LO_MASK,
> +			frm->line_offset);
> +
> +	if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
> +	    frm->fmt->cmode <= CM_MODE_A4)
> +		reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_CM_MASK,
> +				frm->fmt->cmode);
> +
> +	reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_AM_MASK,
> +			(frm->a_mode << 16) & 0x03);
> +
> +	reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_ALPHA_MASK,
> +			frm->a_rgb[3] << 24);
> +
> +	reg_write(d->regs, DMA2D_FGCOLR_REG,
> +		  (frm->a_rgb[2] << 16) |
> +		  (frm->a_rgb[1] << 8) |
> +		  frm->a_rgb[0]);
> +}
> +
> +void dma2d_config_bg(struct dma2d_dev *d, struct dma2d_frame *frm,
> +		     dma_addr_t b_addr)
> +{
> +	reg_write(d->regs, DMA2D_BGMAR_REG, b_addr);
> +	reg_update_bits(d->regs, DMA2D_BGOR_REG, BGOR_LO_MASK,
> +			frm->line_offset);
> +
> +	if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
> +	    frm->fmt->cmode <= CM_MODE_A4)
> +		reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_CM_MASK,
> +				frm->fmt->cmode);
> +
> +	reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_AM_MASK,
> +			(frm->a_mode << 16) & 0x03);
> +
> +	reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_ALPHA_MASK,
> +			frm->a_rgb[3] << 24);
> +
> +	reg_write(d->regs, DMA2D_BGCOLR_REG,
> +		  (frm->a_rgb[2] << 16) |
> +		  (frm->a_rgb[1] << 8) |
> +		  frm->a_rgb[0]);
> +}
> diff --git a/drivers/media/platform/stm32/dma2d/dma2d-regs.h b/drivers/media/platform/stm32/dma2d/dma2d-regs.h
> new file mode 100644
> index 000000000000..2128364406c8
> --- /dev/null
> +++ b/drivers/media/platform/stm32/dma2d/dma2d-regs.h
> @@ -0,0 +1,113 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * ST stm32 Chrom-Art - 2D Graphics Accelerator Driver
> + *
> + * Copyright (c) 2021 Dillon Min
> + * Dillon Min, <dillon.minfei at gmail.com>
> + *
> + * based on s5p-g2d
> + *
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + * Kamil Debski, <k.debski at samsung.com>
> + */
> +
> +#ifndef __DMA2D_REGS_H__
> +#define __DMA2D_REGS_H__
> +
> +#define DMA2D_CR_REG		0x0000
> +#define CR_MODE_MASK		GENMASK(17, 16)
> +#define CR_MODE_SHIFT		16
> +#define CR_M2M			0x0000
> +#define CR_M2M_PFC		BIT(16)
> +#define CR_M2M_BLEND		BIT(17)
> +#define CR_R2M			(BIT(17) | BIT(16))
> +#define CR_CEIE			BIT(13)
> +#define CR_CTCIE		BIT(12)
> +#define CR_CAEIE		BIT(11)
> +#define CR_TWIE			BIT(10)
> +#define CR_TCIE			BIT(9)
> +#define CR_TEIE			BIT(8)
> +#define CR_ABORT		BIT(2)
> +#define CR_SUSP			BIT(1)
> +#define CR_START		BIT(0)
> +
> +#define DMA2D_ISR_REG		0x0004
> +#define ISR_CEIF		BIT(5)
> +#define ISR_CTCIF		BIT(4)
> +#define ISR_CAEIF		BIT(3)
> +#define ISR_TWIF		BIT(2)
> +#define ISR_TCIF		BIT(1)
> +#define ISR_TEIF		BIT(0)
> +
> +#define DMA2D_IFCR_REG		0x0008
> +#define IFCR_CCEIF		BIT(5)
> +#define IFCR_CCTCIF		BIT(4)
> +#define IFCR_CAECIF		BIT(3)
> +#define IFCR_CTWIF		BIT(2)
> +#define IFCR_CTCIF		BIT(1)
> +#define IFCR_CTEIF		BIT(0)
> +
> +#define DMA2D_FGMAR_REG		0x000c
> +#define DMA2D_FGOR_REG		0x0010
> +#define FGOR_LO_MASK		GENMASK(13, 0)
> +
> +#define DMA2D_BGMAR_REG		0x0014
> +#define DMA2D_BGOR_REG		0x0018
> +#define BGOR_LO_MASK		GENMASK(13, 0)
> +
> +#define DMA2D_FGPFCCR_REG	0x001c
> +#define FGPFCCR_ALPHA_MASK	GENMASK(31, 24)
> +#define FGPFCCR_AM_MASK		GENMASK(17, 16)
> +#define FGPFCCR_CS_MASK		GENMASK(15, 8)
> +#define FGPFCCR_START		BIT(5)
> +#define FGPFCCR_CCM_RGB888	BIT(4)
> +#define FGPFCCR_CM_MASK		GENMASK(3, 0)
> +
> +#define DMA2D_FGCOLR_REG	0x0020
> +#define FGCOLR_REG_MASK		GENMASK(23, 16)
> +#define FGCOLR_GREEN_MASK	GENMASK(15, 8)
> +#define FGCOLR_BLUE_MASK	GENMASK(7, 0)
> +
> +#define DMA2D_BGPFCCR_REG	0x0024
> +#define BGPFCCR_ALPHA_MASK	GENMASK(31, 24)
> +#define BGPFCCR_AM_MASK		GENMASK(17, 16)
> +#define BGPFCCR_CS_MASK		GENMASK(15, 8)
> +#define BGPFCCR_START		BIT(5)
> +#define BGPFCCR_CCM_RGB888	BIT(4)
> +#define BGPFCCR_CM_MASK		GENMASK(3, 0)
> +
> +#define DMA2D_BGCOLR_REG	0x0028
> +#define BGCOLR_REG_MASK		GENMASK(23, 16)
> +#define BGCOLR_GREEN_MASK	GENMASK(15, 8)
> +#define BGCOLR_BLUE_MASK	GENMASK(7, 0)
> +
> +#define DMA2D_OPFCCR_REG	0x0034
> +#define OPFCCR_CM_MASK		GENMASK(2, 0)
> +
> +#define DMA2D_OCOLR_REG		0x0038
> +#define OCOLR_ALPHA_MASK	GENMASK(31, 24)
> +#define OCOLR_RED_MASK		GENMASK(23, 16)
> +#define OCOLR_GREEN_MASK	GENMASK(15, 8)
> +#define OCOLR_BLUE_MASK		GENMASK(7, 0)
> +
> +#define DMA2D_OMAR_REG		0x003c
> +
> +#define DMA2D_OOR_REG		0x0040
> +#define OOR_LO_MASK		GENMASK(13, 0)
> +
> +#define DMA2D_NLR_REG		0x0044
> +#define NLR_PL_MASK		GENMASK(29, 16)
> +#define NLR_NL_MASK		GENMASK(15, 0)
> +
> +/* Hardware limits */
> +#define MAX_WIDTH		0x3fff
> +#define MAX_HEIGHT		0xffff
> +
> +#define DEFAULT_WIDTH		240
> +#define DEFAULT_HEIGHT		320
> +#define DEFAULT_SIZE		307200
> +
> +#define CM_MODE_ARGB8888	0x00
> +#define CM_MODE_ARGB4444	0x04
> +#define CM_MODE_A4		0x0a
> +#endif /* __DMA2D_REGS_H__ */
> diff --git a/drivers/media/platform/stm32/dma2d/dma2d.c b/drivers/media/platform/stm32/dma2d/dma2d.c
> new file mode 100644
> index 000000000000..f41f94dfb7b7
> --- /dev/null
> +++ b/drivers/media/platform/stm32/dma2d/dma2d.c
> @@ -0,0 +1,796 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * STM32 DMA2D - 2D Graphics Accelerator Driver
> + *
> + * Copyright (c) 2021 Dillon Min
> + * Dillon Min, <dillon.minfei at gmail.com>
> + *
> + * based on s5p-g2d
> + *
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + * Kamil Debski, <k.debski at samsung.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/fs.h>
> +#include <linux/timer.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/clk.h>
> +#include <linux/interrupt.h>
> +#include <linux/of.h>
> +
> +#include <linux/platform_device.h>
> +#include <media/v4l2-mem2mem.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/v4l2-event.h>
> +#include <media/videobuf2-v4l2.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <uapi/linux/stm32-media.h>
> +
> +#include "dma2d.h"
> +#include "dma2d-regs.h"
> +
> +/*
> + * This V4L2 subdev m2m driver enables Chrom-Art Accelerator unit
> + * of STMicroelectronics STM32 SoC series.
> + *
> + * Currently support r2m, m2m, m2m_pfc.
> + *
> + * - r2m, Filling a part or the whole of a destination image with a specific
> + *   color.
> + * - m2m, Copying a part or the whole of a source image into a part or the
> + *   whole of a destination.
> + * - m2m_pfc, Copying a part or the whole of a source image into a part or the
> + *   whole of a destination image with a pixel format conversion.
> + */
> +
> +#define fh2ctx(__fh) container_of(__fh, struct dma2d_ctx, fh)
> +
> +static const struct dma2d_fmt formats[] = {
> +	{
> +		.fourcc	= V4L2_PIX_FMT_ARGB32,
> +		.cmode = DMA2D_CMODE_ARGB8888,
> +		.depth = 32,
> +	},
> +	{
> +		.fourcc	= V4L2_PIX_FMT_RGB24,
> +		.cmode = DMA2D_CMODE_RGB888,
> +		.depth = 24,
> +	},
> +	{
> +		.fourcc	= V4L2_PIX_FMT_RGB565,
> +		.cmode = DMA2D_CMODE_RGB565,
> +		.depth = 16,
> +	},
> +	{
> +		.fourcc	= V4L2_PIX_FMT_ARGB555,
> +		.cmode = DMA2D_CMODE_ARGB1555,
> +		.depth = 16,
> +	},
> +	{
> +		.fourcc	= V4L2_PIX_FMT_ARGB444,
> +		.cmode = DMA2D_CMODE_ARGB4444,
> +		.depth = 16,
> +	},
> +};
> +
> +#define NUM_FORMATS ARRAY_SIZE(formats)
> +
> +static const struct dma2d_frame def_frame = {
> +	.width		= DEFAULT_WIDTH,
> +	.height		= DEFAULT_HEIGHT,
> +	.line_offset	= 0,
> +	.a_rgb		= {0x00, 0x00, 0x00, 0xff},
> +	.a_mode		= DMA2D_ALPHA_MODE_NO_MODIF,
> +	.fmt		= (struct dma2d_fmt *)&formats[0],
> +	.size		= DEFAULT_SIZE,
> +};
> +
> +static struct dma2d_fmt *find_fmt(int pixelformat)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < NUM_FORMATS; i++) {
> +		if (formats[i].fourcc == pixelformat)
> +			return (struct dma2d_fmt *)&formats[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct dma2d_frame *get_frame(struct dma2d_ctx *ctx,
> +				     enum v4l2_buf_type type)
> +{
> +	return V4L2_TYPE_IS_OUTPUT(type) ? &ctx->cap : &ctx->out;
> +}
> +
> +static int dma2d_queue_setup(struct vb2_queue *vq,
> +			     unsigned int *nbuffers, unsigned int *nplanes,
> +			     unsigned int sizes[], struct device *alloc_devs[])
> +{
> +	struct dma2d_ctx *ctx = vb2_get_drv_priv(vq);
> +	struct dma2d_frame *f = get_frame(ctx, vq->type);
> +
> +	if (IS_ERR(f))
> +		return PTR_ERR(f);

Why this check? get_frame() doesn't return an error pointer, it always succeeds.
Just drop this.

> +
> +	if (*nplanes)
> +		return sizes[0] < f->size ? -EINVAL : 0;
> +
> +	sizes[0] = f->size;
> +	*nplanes = 1;
> +
> +	if (*nbuffers == 0)
> +		*nbuffers = 1;

*nbuffers can never be 0, so you can drop this check.

> +
> +	return 0;
> +}
> +
> +static int dma2d_buf_out_validate(struct vb2_buffer *vb)
> +{
> +	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> +
> +	if (vbuf->field == V4L2_FIELD_ANY)
> +		vbuf->field = V4L2_FIELD_NONE;
> +	if (vbuf->field != V4L2_FIELD_NONE)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int dma2d_buf_prepare(struct vb2_buffer *vb)
> +{
> +	struct dma2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
> +	struct dma2d_frame *f = get_frame(ctx, vb->vb2_queue->type);
> +
> +	if (IS_ERR(f))
> +		return PTR_ERR(f);

Drop this check.

> +
> +	if (vb2_plane_size(vb, 0) < f->size)
> +		return -EINVAL;
> +
> +	vb2_set_plane_payload(vb, 0, f->size);
> +
> +	return 0;
> +}
> +
> +static void dma2d_buf_queue(struct vb2_buffer *vb)
> +{
> +	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> +	struct dma2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
> +
> +	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
> +}
> +
> +static int dma2d_start_streaming(struct vb2_queue *q, unsigned int count)
> +{
> +	struct dma2d_ctx *ctx = vb2_get_drv_priv(q);
> +	struct dma2d_frame *f = get_frame(ctx, q->type);
> +
> +	if (IS_ERR(f))
> +		return -EINVAL;

Drop check.

> +
> +	f->sequence = 0;
> +	return 0;
> +}
> +
> +static void dma2d_stop_streaming(struct vb2_queue *q)
> +{
> +	struct dma2d_ctx *ctx = vb2_get_drv_priv(q);
> +	struct vb2_v4l2_buffer *vbuf;
> +
> +	for (;;) {
> +		if (V4L2_TYPE_IS_OUTPUT(q->type))
> +			vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
> +		else
> +			vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
> +		if (!vbuf)
> +			return;
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +	}
> +}
> +
> +static const struct vb2_ops dma2d_qops = {
> +	.queue_setup	= dma2d_queue_setup,
> +	.buf_out_validate	 = dma2d_buf_out_validate,
> +	.buf_prepare	= dma2d_buf_prepare,
> +	.buf_queue	= dma2d_buf_queue,
> +	.start_streaming = dma2d_start_streaming,
> +	.stop_streaming  = dma2d_stop_streaming,
> +	.wait_prepare	= vb2_ops_wait_prepare,
> +	.wait_finish	= vb2_ops_wait_finish,
> +};
> +
> +static int queue_init(void *priv, struct vb2_queue *src_vq,
> +		      struct vb2_queue *dst_vq)
> +{
> +	struct dma2d_ctx *ctx = priv;
> +	int ret;
> +
> +	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
> +	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
> +	src_vq->drv_priv = ctx;
> +	src_vq->ops = &dma2d_qops;
> +	src_vq->mem_ops = &vb2_dma_contig_memops;
> +	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
> +	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> +	src_vq->lock = &ctx->dev->mutex;
> +	src_vq->dev = ctx->dev->v4l2_dev.dev;
> +
> +	ret = vb2_queue_init(src_vq);
> +	if (ret)
> +		return ret;
> +
> +	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> +	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
> +	dst_vq->drv_priv = ctx;
> +	dst_vq->ops = &dma2d_qops;
> +	dst_vq->mem_ops = &vb2_dma_contig_memops;
> +	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
> +	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> +	dst_vq->lock = &ctx->dev->mutex;
> +	dst_vq->dev = ctx->dev->v4l2_dev.dev;
> +
> +	return vb2_queue_init(dst_vq);
> +}
> +
> +static int dma2d_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct dma2d_frame *frm;
> +	struct dma2d_ctx *ctx = container_of(ctrl->handler, struct dma2d_ctx,
> +								ctrl_handler);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&ctx->dev->ctrl_lock, flags);
> +	switch (ctrl->id) {
> +	case V4L2_CID_ALPHA_COMPONENT:
> +		/* set the background alpha value*/
> +		ctx->alpha_component = (u8)ctrl->val;

It's set here, but is never used?!

> +		break;
> +	case V4L2_CID_DMA2D_R2M_COLOR:
> +		frm = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +		frm->a_rgb[2] = (ctrl->val >> 16) & 0xff;
> +		frm->a_rgb[1] = (ctrl->val >>  8) & 0xff;
> +		frm->a_rgb[0] = ctrl->val & 0xff;

Hmm, the alpha value isn't copied, but that's documented in V4L2_CID_DMA2D_R2M_COLOR.
Either this code or the documentation is wrong.

> +		break;
> +	case V4L2_CID_DMA2D_R2M_MODE:
> +		if (ctrl->val)
> +			ctx->op_mode = DMA2D_MODE_R2M;
> +		break;
> +	default:
> +		v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
> +		spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
> +		return -EINVAL;
> +	}
> +	spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_ctrl_ops dma2d_ctrl_ops = {
> +	.s_ctrl	= dma2d_s_ctrl,
> +};
> +
> +static const struct v4l2_ctrl_config dma2d_r2m_control[] = {
> +	{
> +	.ops = &dma2d_ctrl_ops,
> +	.id = V4L2_CID_DMA2D_R2M_COLOR,
> +	.name = "R2M Alpha/Color Value",

This mentions alpha support as well. Very unclear how this relates to V4L2_CID_ALPHA_COMPONENT.

> +	.type = V4L2_CTRL_TYPE_INTEGER,
> +	.min = 0xffffffff80000000ULL,
> +	.max = 0x7fffffff,

I suggest using TYPE_BITMASK: it's more appropriate for a control like this.
(Yes, there are other color controls that are of type integer, but they predate
the introduction of type bitmask).

> +	.def = 0,
> +	.step = 1,
> +	},
> +	{
> +	.ops = &dma2d_ctrl_ops,
> +	.id = V4L2_CID_DMA2D_R2M_MODE,
> +	.name = "Set R2M Mode",
> +	.type = V4L2_CTRL_TYPE_BOOLEAN,
> +	.min = 0,
> +	.max = 1,
> +	.def = 0,
> +	.step = 1,
> +	}
> +};

It's not clear what R2M mode does. Is it just to enable filling the colors? Or will
there be other features in the future?

As it is now, this feature can instead be implemented by adding a new color effect
(see V4L2_CID_COLORFX): V4L2_COLORFX_SET_COLOR_ARGB.

And add a new bitmask control V4L2_CID_COLORFX_ARGB to set the ARGB value.

> +
> +static int dma2d_setup_ctrls(struct dma2d_ctx *ctx)
> +{
> +	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
> +
> +	v4l2_ctrl_new_std(&ctx->ctrl_handler, &dma2d_ctrl_ops,
> +			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
> +	v4l2_ctrl_new_custom(&ctx->ctrl_handler, &dma2d_r2m_control[0], NULL);
> +	v4l2_ctrl_new_custom(&ctx->ctrl_handler, &dma2d_r2m_control[1], NULL);
> +
> +	return 0;
> +}
> +
> +static int dma2d_open(struct file *file)
> +{
> +	struct dma2d_dev *dev = video_drvdata(file);
> +	struct dma2d_ctx *ctx = NULL;
> +	int ret = 0;
> +
> +	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
> +	if (!ctx)
> +		return -ENOMEM;
> +	ctx->dev = dev;
> +	/* Set default formats */
> +	ctx->cap		= def_frame;
> +	ctx->bg		= def_frame;
> +	ctx->out	= def_frame;
> +	ctx->op_mode	= DMA2D_MODE_M2M_FPC;
> +	ctx->colorspace = V4L2_COLORSPACE_REC709;
> +	ctx->alpha_component = 0x00;
> +	if (mutex_lock_interruptible(&dev->mutex)) {
> +		kfree(ctx);
> +		return -ERESTARTSYS;
> +	}
> +
> +	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
> +	if (IS_ERR(ctx->fh.m2m_ctx)) {
> +		ret = PTR_ERR(ctx->fh.m2m_ctx);
> +		mutex_unlock(&dev->mutex);
> +		kfree(ctx);
> +		return ret;
> +	}
> +
> +	v4l2_fh_init(&ctx->fh, video_devdata(file));
> +	file->private_data = &ctx->fh;
> +	v4l2_fh_add(&ctx->fh);
> +
> +	dma2d_setup_ctrls(ctx);
> +
> +	/* Write the default values to the ctx struct */
> +	v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
> +
> +	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
> +	mutex_unlock(&dev->mutex);
> +
> +	return 0;
> +}
> +
> +static int dma2d_release(struct file *file)
> +{
> +	struct dma2d_dev *dev = video_drvdata(file);
> +	struct dma2d_ctx *ctx = fh2ctx(file->private_data);
> +
> +	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
> +	v4l2_fh_del(&ctx->fh);
> +	v4l2_fh_exit(&ctx->fh);
> +	mutex_lock(&dev->mutex);
> +	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
> +	mutex_unlock(&dev->mutex);
> +	kfree(ctx);
> +
> +	return 0;
> +}
> +
> +static int vidioc_querycap(struct file *file, void *priv,
> +			   struct v4l2_capability *cap)
> +{
> +	strscpy(cap->driver, DMA2D_NAME, sizeof(cap->driver));
> +	strscpy(cap->card, DMA2D_NAME, sizeof(cap->card));
> +	strscpy(cap->bus_info, BUS_INFO, sizeof(cap->bus_info));
> +
> +	return 0;
> +}
> +
> +static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
> +{
> +	if (f->index >= NUM_FORMATS)
> +		return -EINVAL;
> +
> +	f->pixelformat = formats[f->index].fourcc;
> +	return 0;
> +}
> +
> +static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
> +{
> +	struct dma2d_ctx *ctx = prv;
> +	struct vb2_queue *vq;
> +	struct dma2d_frame *frm;
> +
> +	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
> +	if (!vq)
> +		return -EINVAL;
> +
> +	frm = get_frame(ctx, f->type);
> +	if (IS_ERR(frm))
> +		return PTR_ERR(frm);
> +
> +	f->fmt.pix.width		= frm->width;
> +	f->fmt.pix.height		= frm->height;
> +	f->fmt.pix.field		= V4L2_FIELD_NONE;
> +	f->fmt.pix.pixelformat		= frm->fmt->fourcc;
> +	f->fmt.pix.bytesperline		= (frm->width * frm->fmt->depth) >> 3;
> +	f->fmt.pix.sizeimage		= frm->size;
> +	f->fmt.pix.colorspace		= ctx->colorspace;
> +	f->fmt.pix.xfer_func		= ctx->xfer_func;
> +	f->fmt.pix.ycbcr_enc		= ctx->ycbcr_enc;
> +	f->fmt.pix.quantization		= ctx->quant;
> +
> +	return 0;
> +}
> +
> +static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
> +{
> +	struct dma2d_ctx *ctx = prv;
> +	struct dma2d_dev *dev = ctx->dev;
> +	struct dma2d_fmt *fmt;
> +	enum v4l2_field *field;
> +	u32 fourcc = f->fmt.pix.pixelformat;
> +
> +	fmt = find_fmt(fourcc);
> +	if (!fmt) {
> +		v4l2_warn(&dev->v4l2_dev,
> +			  "Format not supported: %c%c%c%c, use the default.\n",
> +			  (fourcc & 0xff),  (fourcc >>  8) & 0xff,
> +			  (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff);
> +		f->fmt.pix.pixelformat = formats[0].fourcc;
> +		fmt = find_fmt(f->fmt.pix.pixelformat);
> +	}
> +
> +	field = &f->fmt.pix.field;
> +	if (*field == V4L2_FIELD_ANY)
> +		*field = V4L2_FIELD_NONE;
> +	else if (*field != V4L2_FIELD_NONE)
> +		return -EINVAL;
> +
> +	if (f->fmt.pix.width > MAX_WIDTH)
> +		f->fmt.pix.width = MAX_WIDTH;
> +	if (f->fmt.pix.height > MAX_HEIGHT)
> +		f->fmt.pix.height = MAX_HEIGHT;
> +
> +	if (f->fmt.pix.width < 1)
> +		f->fmt.pix.width = 1;
> +	if (f->fmt.pix.height < 1)
> +		f->fmt.pix.height = 1;
> +
> +	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && !f->fmt.pix.colorspace) {
> +		f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
> +	} else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> +		f->fmt.pix.colorspace	= ctx->colorspace;
> +		f->fmt.pix.xfer_func = ctx->xfer_func;
> +		f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
> +		f->fmt.pix.quantization = ctx->quant;
> +	}
> +	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
> +	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
> +
> +	return 0;
> +}
> +
> +static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
> +{
> +	struct dma2d_ctx *ctx = prv;
> +	struct dma2d_dev *dev = ctx->dev;
> +	struct vb2_queue *vq;
> +	struct dma2d_frame *frm;
> +	struct dma2d_fmt *fmt;
> +	int ret = 0;
> +
> +	/* Adjust all values accordingly to the hardware capabilities
> +	 * and chosen format.
> +	 */
> +	ret = vidioc_try_fmt(file, prv, f);
> +	if (ret)
> +		return ret;
> +
> +	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
> +	if (vb2_is_busy(vq)) {
> +		v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type);
> +		return -EBUSY;
> +	}
> +
> +	frm = get_frame(ctx, f->type);
> +	if (IS_ERR(frm))
> +		return PTR_ERR(frm);
> +
> +	fmt = find_fmt(f->fmt.pix.pixelformat);
> +	if (!fmt)
> +		return -EINVAL;
> +
> +	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
> +		ctx->colorspace = f->fmt.pix.colorspace;
> +		ctx->xfer_func = f->fmt.pix.xfer_func;
> +		ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
> +		ctx->quant = f->fmt.pix.quantization;
> +	}
> +
> +	frm->width	= f->fmt.pix.width;
> +	frm->height	= f->fmt.pix.height;
> +	frm->size	= f->fmt.pix.sizeimage;
> +	/* Reset crop settings */
> +	frm->o_width	= 0;
> +	frm->o_height	= 0;
> +	frm->c_width	= frm->width;
> +	frm->c_height	= frm->height;

Why store crop values when cropping is not supported? Just crop this, this seems to be
copy-and-paste from the samsung driver.

> +	frm->right	= frm->width;
> +	frm->bottom	= frm->height;
> +	frm->fmt	= fmt;
> +	frm->line_offset	= 0;
> +	if (f->fmt.win.global_alpha != 0) {

Huh? There is no f->fmt.win, this v4l2_format struct uses f->fmt.pix.

> +		frm->a_rgb[3] = f->fmt.win.global_alpha;
> +		frm->a_mode = DMA2D_ALPHA_MODE_REPLACE;

Again perhaps old copy-and-paste code from the samsung driver?

> +	}
> +
> +	return 0;
> +}
> +
> +static void device_run(void *prv)
> +{
> +	struct dma2d_ctx *ctx = prv;
> +	struct dma2d_dev *dev = ctx->dev;
> +	struct dma2d_frame *frm_out, *frm_cap;
> +	struct vb2_v4l2_buffer *src, *dst;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dev->ctrl_lock, flags);
> +	dev->curr = ctx;
> +
> +	src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
> +	dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
> +	if (!dst || !src)
> +		goto end;
> +
> +	frm_cap = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	frm_out = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
> +	if (!frm_cap || !frm_out)
> +		goto end;
> +
> +	src->sequence = frm_out->sequence++;
> +	dst->sequence = frm_cap->sequence++;
> +	v4l2_m2m_buf_copy_metadata(src, dst, true);
> +
> +	clk_enable(dev->gate);
> +
> +	dma2d_config_fg(dev, frm_out,
> +			vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0));
> +
> +	/* TODO: add M2M_BLEND handler here */
> +
> +	if (ctx->op_mode != DMA2D_MODE_R2M) {
> +		if (frm_out->fmt->fourcc == frm_cap->fmt->fourcc)
> +			ctx->op_mode = DMA2D_MODE_M2M;
> +		else
> +			ctx->op_mode = DMA2D_MODE_M2M_FPC;
> +	}
> +
> +	dma2d_config_out(dev, frm_cap,
> +			 vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0));
> +	dma2d_config_common(dev, ctx->op_mode, frm_cap->width, frm_cap->height);
> +
> +	dma2d_start(dev);
> +end:
> +	spin_unlock_irqrestore(&dev->ctrl_lock, flags);
> +}
> +
> +static irqreturn_t dma2d_isr(int irq, void *prv)
> +{
> +	struct dma2d_dev *dev = prv;
> +	struct dma2d_ctx *ctx = dev->curr;
> +	struct vb2_v4l2_buffer *src, *dst;
> +	u32 s = dma2d_get_int(dev);
> +
> +	if (s & ISR_TCIF || s == 0) {
> +		dma2d_clear_int(dev);
> +		clk_disable(dev->gate);
> +
> +		WARN_ON(!ctx);
> +
> +		src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
> +		dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
> +
> +		WARN_ON(!dst);
> +		WARN_ON(!src);
> +
> +		v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
> +		v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
> +		v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
> +
> +		dev->curr = NULL;
> +	} else {
> +		dma2d_clear_int(dev);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static const struct v4l2_file_operations dma2d_fops = {
> +	.owner		= THIS_MODULE,
> +	.open		= dma2d_open,
> +	.release	= dma2d_release,
> +	.poll		= v4l2_m2m_fop_poll,
> +	.unlocked_ioctl	= video_ioctl2,
> +	.mmap		= v4l2_m2m_fop_mmap,
> +#ifndef CONFIG_MMU
> +	.get_unmapped_area = v4l2_m2m_get_unmapped_area,
> +#endif
> +};
> +
> +static const struct v4l2_ioctl_ops dma2d_ioctl_ops = {
> +	.vidioc_querycap	= vidioc_querycap,
> +
> +	.vidioc_enum_fmt_vid_cap	= vidioc_enum_fmt,
> +	.vidioc_g_fmt_vid_cap		= vidioc_g_fmt,
> +	.vidioc_try_fmt_vid_cap		= vidioc_try_fmt,
> +	.vidioc_s_fmt_vid_cap		= vidioc_s_fmt,
> +
> +	.vidioc_enum_fmt_vid_out	= vidioc_enum_fmt,
> +	.vidioc_g_fmt_vid_out		= vidioc_g_fmt,
> +	.vidioc_try_fmt_vid_out		= vidioc_try_fmt,
> +	.vidioc_s_fmt_vid_out		= vidioc_s_fmt,
> +
> +	.vidioc_reqbufs			= v4l2_m2m_ioctl_reqbufs,
> +	.vidioc_querybuf		= v4l2_m2m_ioctl_querybuf,
> +	.vidioc_qbuf			= v4l2_m2m_ioctl_qbuf,
> +	.vidioc_dqbuf			= v4l2_m2m_ioctl_dqbuf,
> +	.vidioc_prepare_buf		= v4l2_m2m_ioctl_prepare_buf,
> +	.vidioc_create_bufs		= v4l2_m2m_ioctl_create_bufs,
> +	.vidioc_expbuf			= v4l2_m2m_ioctl_expbuf,
> +
> +	.vidioc_streamon		= v4l2_m2m_ioctl_streamon,
> +	.vidioc_streamoff		= v4l2_m2m_ioctl_streamoff,
> +
> +	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
> +	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> +};
> +
> +static const struct video_device dma2d_videodev = {
> +	.name		= DMA2D_NAME,
> +	.fops		= &dma2d_fops,
> +	.ioctl_ops	= &dma2d_ioctl_ops,
> +	.minor		= -1,
> +	.release	= video_device_release,
> +	.vfl_dir	= VFL_DIR_M2M,
> +};
> +
> +static const struct v4l2_m2m_ops dma2d_m2m_ops = {
> +	.device_run	= device_run,
> +};
> +
> +static const struct of_device_id stm32_dma2d_match[];
> +
> +static int dma2d_probe(struct platform_device *pdev)
> +{
> +	struct dma2d_dev *dev;
> +	struct video_device *vfd;
> +	struct resource *res;
> +	int ret = 0;
> +
> +	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
> +	if (!dev)
> +		return -ENOMEM;
> +
> +	spin_lock_init(&dev->ctrl_lock);
> +	mutex_init(&dev->mutex);
> +	atomic_set(&dev->num_inst, 0);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> +	dev->regs = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(dev->regs))
> +		return PTR_ERR(dev->regs);
> +
> +	dev->gate = clk_get(&pdev->dev, "dma2d");
> +	if (IS_ERR(dev->gate)) {
> +		dev_err(&pdev->dev, "failed to get dma2d clock gate\n");
> +		ret = -ENXIO;
> +		return ret;
> +	}
> +
> +	ret = clk_prepare(dev->gate);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to prepare dma2d clock gate\n");
> +		goto put_clk_gate;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "failed to find IRQ\n");
> +		ret = -ENXIO;
> +		goto unprep_clk_gate;
> +	}
> +
> +	dev->irq = res->start;
> +
> +	ret = devm_request_irq(&pdev->dev, dev->irq, dma2d_isr,
> +			       0, pdev->name, dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to install IRQ\n");
> +		goto unprep_clk_gate;
> +	}
> +
> +	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
> +	if (ret)
> +		goto unprep_clk_gate;
> +
> +	vfd = video_device_alloc();
> +	if (!vfd) {
> +		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
> +		ret = -ENOMEM;
> +		goto unreg_v4l2_dev;
> +	}
> +
> +	*vfd = dma2d_videodev;
> +	set_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags);

Drop this quirk! Definitely copy-and-paste from the samsung driver, and not something
you want or need here.

> +	vfd->lock = &dev->mutex;
> +	vfd->v4l2_dev = &dev->v4l2_dev;
> +	vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
> +	ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);

This must be done last, so move it to the end of the probe().

> +	if (ret) {
> +		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
> +		goto rel_vdev;
> +	}
> +
> +	video_set_drvdata(vfd, dev);
> +	dev->vfd = vfd;
> +	v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
> +		  vfd->num);
> +	platform_set_drvdata(pdev, dev);
> +	dev->m2m_dev = v4l2_m2m_init(&dma2d_m2m_ops);
> +	if (IS_ERR(dev->m2m_dev)) {
> +		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
> +		ret = PTR_ERR(dev->m2m_dev);
> +		goto unreg_video_dev;
> +	}
> +
> +	v4l2_info(&dev->v4l2_dev, "stm32 dma2d initialized\n");
> +	return 0;
> +
> +unreg_video_dev:
> +	video_unregister_device(dev->vfd);
> +rel_vdev:
> +	video_device_release(vfd);
> +unreg_v4l2_dev:
> +	v4l2_device_unregister(&dev->v4l2_dev);
> +unprep_clk_gate:
> +	clk_unprepare(dev->gate);
> +put_clk_gate:
> +	clk_put(dev->gate);
> +
> +	return ret;
> +}
> +
> +static int dma2d_remove(struct platform_device *pdev)
> +{
> +	struct dma2d_dev *dev = platform_get_drvdata(pdev);
> +
> +	v4l2_info(&dev->v4l2_dev, "Removing " DMA2D_NAME);
> +	v4l2_m2m_release(dev->m2m_dev);
> +	video_unregister_device(dev->vfd);
> +	v4l2_device_unregister(&dev->v4l2_dev);
> +	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> +	clk_unprepare(dev->gate);
> +	clk_put(dev->gate);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id stm32_dma2d_match[] = {
> +	{
> +		.compatible = "st,stm32-dma2d",
> +		.data = NULL,
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, stm32_dma2d_match);
> +
> +static struct platform_driver dma2d_pdrv = {
> +	.probe		= dma2d_probe,
> +	.remove		= dma2d_remove,
> +	.driver		= {
> +		.name = DMA2D_NAME,
> +		.of_match_table = stm32_dma2d_match,
> +	},
> +};
> +
> +module_platform_driver(dma2d_pdrv);
> +
> +MODULE_AUTHOR("Dillon Min <dillon.minfei at gmail.com>");
> +MODULE_DESCRIPTION("STM32 Chrom-Art Accelerator DMA2D driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/media/platform/stm32/dma2d/dma2d.h b/drivers/media/platform/stm32/dma2d/dma2d.h
> new file mode 100644
> index 000000000000..f317cf1dd35a
> --- /dev/null
> +++ b/drivers/media/platform/stm32/dma2d/dma2d.h
> @@ -0,0 +1,136 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * ST stm32 DMA2D - 2D Graphics Accelerator Driver
> + *
> + * Copyright (c) 2021 Dillon Min
> + * Dillon Min, <dillon.minfei at gmail.com>
> + *
> + * based on s5p-g2d
> + *
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + * Kamil Debski, <k.debski at samsung.com>
> + */
> +
> +#ifndef __DMA2D_H__
> +#define __DMA2D_H__
> +
> +#include <linux/platform_device.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ctrls.h>
> +
> +#define DMA2D_NAME "stm-dma2d"
> +#define BUS_INFO "platform:stm-dma2d"
> +enum dma2d_op_mode {
> +	DMA2D_MODE_M2M,
> +	DMA2D_MODE_M2M_FPC,
> +	DMA2D_MODE_M2M_BLEND,
> +	DMA2D_MODE_R2M
> +};
> +
> +enum dma2d_cmode {
> +	/* output pfc cmode from ARGB888 to ARGB4444 */
> +	DMA2D_CMODE_ARGB8888,
> +	DMA2D_CMODE_RGB888,
> +	DMA2D_CMODE_RGB565,
> +	DMA2D_CMODE_ARGB1555,
> +	DMA2D_CMODE_ARGB4444,
> +	/* bg or fg pfc cmode from L8 to A4 */
> +	DMA2D_CMODE_L8,
> +	DMA2D_CMODE_AL44,
> +	DMA2D_CMODE_AL88,
> +	DMA2D_CMODE_L4,
> +	DMA2D_CMODE_A8,
> +	DMA2D_CMODE_A4
> +};
> +
> +enum dma2d_alpha_mode {
> +	DMA2D_ALPHA_MODE_NO_MODIF,
> +	DMA2D_ALPHA_MODE_REPLACE,
> +	DMA2D_ALPHA_MODE_COMBINE
> +};
> +
> +struct dma2d_fmt {
> +	u32	fourcc;
> +	int	depth;
> +	enum dma2d_cmode cmode;
> +};
> +
> +struct dma2d_frame {
> +	/* Original dimensions */
> +	u32	width;
> +	u32	height;
> +	/* Crop size */
> +	u32	c_width;
> +	u32	c_height;
> +	/* Offset */
> +	u32	o_width;
> +	u32	o_height;
> +	u32	bottom;
> +	u32	right;
> +	u16	line_offset;
> +	/* Image format */
> +	struct dma2d_fmt *fmt;
> +	/* [0]: blue
> +	 * [1]: green
> +	 * [2]: red
> +	 * [3]: alpha
> +	 */
> +	u8	a_rgb[4];
> +	/*
> +	 * AM[1:0] of DMA2D_FGPFCCR
> +	 */
> +	enum dma2d_alpha_mode a_mode;
> +	u32 size;
> +	unsigned int	sequence;
> +};
> +
> +struct dma2d_ctx {
> +	struct v4l2_fh fh;
> +	struct dma2d_dev	*dev;
> +	struct dma2d_frame	cap;
> +	struct dma2d_frame	out;
> +	struct dma2d_frame	bg;
> +	/* fb_buf always point to bg address */
> +	struct v4l2_framebuffer	fb_buf;
> +	/*
> +	 * MODE[17:16] of DMA2D_CR
> +	 */
> +	enum dma2d_op_mode	op_mode;
> +	u8			alpha_component;
> +	struct v4l2_ctrl_handler ctrl_handler;
> +	enum v4l2_colorspace	colorspace;
> +	enum v4l2_ycbcr_encoding ycbcr_enc;
> +	enum v4l2_xfer_func	xfer_func;
> +	enum v4l2_quantization	quant;
> +};
> +
> +struct dma2d_dev {
> +	struct v4l2_device	v4l2_dev;
> +	struct v4l2_m2m_dev	*m2m_dev;
> +	struct video_device	*vfd;
> +	/* for device open/close etc */
> +	struct mutex		mutex;
> +	/* to avoid the conflict with device running and user setting
> +	 * at the same time
> +	 */
> +	spinlock_t		ctrl_lock;
> +	atomic_t		num_inst;
> +	void __iomem		*regs;
> +	struct clk		*gate;
> +	struct dma2d_ctx	*curr;
> +	int irq;
> +};
> +
> +void dma2d_start(struct dma2d_dev *d);
> +u32 dma2d_get_int(struct dma2d_dev *d);
> +void dma2d_clear_int(struct dma2d_dev *d);
> +void dma2d_config_out(struct dma2d_dev *d, struct dma2d_frame *frm,
> +		      dma_addr_t o_addr);
> +void dma2d_config_fg(struct dma2d_dev *d, struct dma2d_frame *frm,
> +		     dma_addr_t f_addr);
> +void dma2d_config_bg(struct dma2d_dev *d, struct dma2d_frame *frm,
> +		     dma_addr_t b_addr);
> +void dma2d_config_common(struct dma2d_dev *d, enum dma2d_op_mode op_mode,
> +			 u16 width, u16 height);
> +
> +#endif /* __DMA2D_H__ */
> 

Regards,

	Hans


From gregkh at linuxfoundation.org  Mon Aug  9 02:11:42 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 9 Aug 2021 11:11:42 +0200
Subject: [RFC PATCH] usb: xhci-mtk: handle bandwidth table rollover
In-Reply-To: <20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid>
References: <20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid>
Message-ID: <YRDxTodNNqtnpPpn@kroah.com>

On Mon, Aug 09, 2021 at 04:59:29PM +0800, Ikjoon Jang wrote:
> xhci-mtk has 64 slots for periodic bandwidth calculations and each
> slot represents byte budgets on a microframe. When an endpoint's
> allocation sits on the boundary of the table, byte budgets' slot
> should be rolled over but the current implementation doesn't.
> 
> This patch applies a 6 bits mask to the microframe index to handle
> its rollover 64 slots and prevent out-of-bounds array access.
> 
> Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
> ---
> 
>  drivers/usb/host/xhci-mtk-sch.c | 79 +++++++++------------------------
>  drivers/usb/host/xhci-mtk.h     |  1 +
>  2 files changed, 23 insertions(+), 57 deletions(-)

Why is this "RFC"?  What needs to be addressed in this change before it
can be accepted?

thanks,

greg k-h


From joro at 8bytes.org  Mon Aug  9 02:11:42 2021
From: joro at 8bytes.org (joro at 8bytes.org)
Date: Mon, 9 Aug 2021 11:11:42 +0200
Subject: [PATCH v7 00/12] Clean up "mediatek,larb"
In-Reply-To: <ed099698f63bec6771561bcad7022dbff184ce7f.camel@mediatek.com>
References: <20210730025238.22456-1-yong.wu@mediatek.com>
 <YQfALZNWyw8VKODp@8bytes.org>
 <ed099698f63bec6771561bcad7022dbff184ce7f.camel@mediatek.com>
Message-ID: <YRDxTmvA9PcSRQUe@8bytes.org>

On Mon, Aug 09, 2021 at 08:30:03AM +0000, Yong Wu (??) wrote:
> Thanks very much for your confirm. I will your Ack for iommu part in
> the next version.

Note that my ack is conditional on the premise that Matthias has
reviewed the IOMMU parts.

Thanks,

	Joerg


From maz at kernel.org  Mon Aug  9 02:15:15 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Aug 2021 10:15:15 +0100
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <MW4PR21MB200286E2CF4DA229D7059598C0F69@MW4PR21MB2002.namprd21.prod.outlook.com>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>
 <87r1f9wooc.wl-maz@kernel.org>
 <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87wnp0b86y.wl-maz@kernel.org>
 <MW4PR21MB2002ABD170CC9786CDF5D493C0F39@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87o8a81boi.wl-maz@kernel.org>
 <MW4PR21MB200286E2CF4DA229D7059598C0F69@MW4PR21MB2002.namprd21.prod.outlook.com>
Message-ID: <87pmunasik.wl-maz@kernel.org>

On Mon, 09 Aug 2021 03:35:05 +0100,
Sunil Muthuswamy <sunilmut at microsoft.com> wrote:
> 
> Sunday, August 8, 2021 3:19 AM,
> Marc Zyngier <maz at kernel.org> wrote:
> > 
> > [+Lorenzo, as he deals with both PCI and ACPI]
> > 
> > I think it is clear enough, but I don't see what this buys us other
> > than turning DirectLPI into something that is essentially private to
> > Hyper-V, just for the sake of sidestepping a firmware description.
> > Furthermore, the Hyper-V "single MSI address" model doesn't match the
> > way DirectLPI works (after all, this is one of the many reasons why we
> > have the ITS).
> > 
> > The architecture already gives you everything you need to make things
> > work in Hyper-V. You can easily implement the DirectLPI support (you
> > definitely need most of it anyway), and the PCI-MSI layer is
> > *free*. All you need is a firmware description. Which I don't believe
> > is the end of the world, given that DT is freely hackable and that
> > IORT is an ARM-private extension to ACPI. I'm sure you know who to
> > reach out to in order to start a draft (and if you don't, I can give
> > you names offline).
> > 
> That sounds reasonable. The DT extension here alone wont suffice for
> Hyper-V and we would need the ACPI IORT extension here as well. Our
> general experience with ACPI extension is that they can take time. But,
> I am curious to hear from Lorenzo on his thoughts here and if just an
> IORT extension means anything else in terms of timelines.
> 
> > I am not interested in expanding the GICv3 architecture support if it
> > cannot be generally used in a way that is *compliant with the
> > architecture*. If you think DirectLPIs can make the hypervisor
> > simpler, I'm fine with it. But let's fully embrace the concept instead
> > of hiding it behind a layer of PV muck. It will even have a chance of
> > working on bare metal (such as on the machine that is humming behind
> > me, or even the Fast Model).
> > 
> Appreciate your inputs. Since we are discussing options, there is one more
> option to enable Hyper-V virtual PCI for ARM64 that I do would like to
> discuss. That option is to implement the IRQ chip completely within the
> Hyper-V module itself. That IRQ chip will take care of allocating LPI vectors,
> enabling the interrupt (unmask, mask etc..). It won't be a Direct LPI based,
> but based on custom Hyper-V methods. That chip will parent itself to the
> GIC v3 IRQ domain. The only extra thing needed for this is for the Hyper-V
> IRQ chip to be able to discover the GIC v3 IRQ domain, for which it
> cannot use the 'irq_find_matching_fwnode' method as Hyper-V virtual
> PCI bus/devices are not firmware enumerated. I am not sure if there is any
> other way to discover the GIC (DOMAIN_BUS_WIRED) domain.
>
> What are your thoughts/feedback on the above? This will allow us to
> enable the scenario for the business timelines we are targeting for, while
> we wait for firmware spec updates. Long term we also want to use
> architectural methods here as that helps the Hypervisor as well, and I
> would be glad to pursue the firmware spec updates in parallel.

This feels like yet another layer of PV ugliness that has the side
effect of fragmenting the architectural support.

If you plug directly into the GICv3 layer, I'd rather you inject SPIs,
just like any other non-architectural MSI controller. You can directly
interface with the ACPI GSI layer for that, without any need to mess
with the GICv3 internals. The SPI space isn't very large, but still
much larger than the equivalent x86 space (close to 1000).

If time is of the essence, I suggest you go the SPI way. For anything
involving LPIs, I really want to see a firmware spec that works for
everyone as opposed to a localised Hyper-V hack.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From hverkuil-cisco at xs4all.nl  Mon Aug  9 02:15:59 2021
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Mon, 9 Aug 2021 11:15:59 +0200
Subject: [PATCH v2 7/9] media: docs: add doc for the stm32 dma2d driver
In-Reply-To: <1626341068-20253-18-git-send-email-dillon.minfei@gmail.com>
References: <1626341068-20253-1-git-send-email-dillon.minfei@gmail.com>
 <1626341068-20253-18-git-send-email-dillon.minfei@gmail.com>
Message-ID: <7131ee03-fc81-cb9b-665f-80e4ce8435ab@xs4all.nl>

On 15/07/2021 11:24, dillon.minfei at gmail.com wrote:
> From: Dillon Min <dillon.minfei at gmail.com>
> 
> add stm32-uapi.rst for stm32's dma2d driver, explain the details of ioctl
> V4L2_CID_DMA2D_R2M_MODE, V4L2_CID_DMA2D_R2M_COLOR.
> 
> Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
> ---
> v2: introduce the stm32-uapi.rst to explain the detail of dma2d's ioctl.
> 
>  .../userspace-api/media/drivers/index.rst          |  1 +
>  .../userspace-api/media/drivers/stm32-uapi.rst     | 22 ++++++++++++++++++++++
>  2 files changed, 23 insertions(+)
>  create mode 100644 Documentation/userspace-api/media/drivers/stm32-uapi.rst
> 
> diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst
> index 12e3c512d718..ce42915d48f4 100644
> --- a/Documentation/userspace-api/media/drivers/index.rst
> +++ b/Documentation/userspace-api/media/drivers/index.rst
> @@ -38,4 +38,5 @@ For more details see the file COPYING in the source distribution of Linux.
>  	max2175
>  	meye-uapi
>  	omap3isp-uapi
> +	stm32-uapi
>  	uvcvideo
> diff --git a/Documentation/userspace-api/media/drivers/stm32-uapi.rst b/Documentation/userspace-api/media/drivers/stm32-uapi.rst
> new file mode 100644
> index 000000000000..d7a4f717387d
> --- /dev/null
> +++ b/Documentation/userspace-api/media/drivers/stm32-uapi.rst
> @@ -0,0 +1,22 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +STM32 Chrom-Art 2D Graphics Accelerator unit (DMA2D) driver
> +================================================
> +
> +The DMA2D driver implements the following driver-specific controls:
> +
> +``V4L2_CID_DMA2D_R2M_MODE``

Please mention the control type as well.

> +-------------------------
> +    Enable/Disable the Register-To-Memory mode, filling a part or the
> +    whole of a destination image with a specific color.
> +
> +    1 for enable, 0 for disable.
> +
> +``V4L2_CID_DMA2D_R2M_COLOR``

Ditto.

> +-------------------------------
> +    Set the color to fill a part or the whole of a destination image.
> +    only used under Register-To-Memory mode, to set the DMA2D_OCOLR register
> +    (RED, GREEN, BLUE) which is:

Here you mention RGB only,

> +
> +    31 .. 24    23 .. 16  15 .. 8     7 .. 0
> +    ALPHA[7:0]  RED[7:0]  GREEN[7:0]  BLUE[7:0]

but here you also mention Alpha. So which is it?

See also my review of patch 9/9.

> 

I'm getting some warnings building this doc:

Documentation/media/userspace-api/drivers/stm32-uapi.rst:4: WARNING: Title underline too short.

STM32 Chrom-Art 2D Graphics Accelerator unit (DMA2D) driver
================================================
Documentation/media/userspace-api/drivers/stm32-uapi.rst:9: WARNING: Title underline too short.

``V4L2_CID_DMA2D_R2M_MODE``
-------------------------

Regards,

	Hans


From cristian.marussi at arm.com  Mon Aug  9 02:22:45 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon,  9 Aug 2021 10:22:45 +0100
Subject: [PATCH] firmware: arm_scmi: Use WARN_ON() to check configured
 transports
Message-ID: <20210809092245.8730-1-cristian.marussi@arm.com>

Use a WARN_ON() when SCMI stack is loaded to check the consistency of
configured SCMI transports instead of the current compile-time check
BUILD_BUG_ON() to avoid breaking bot-builds on random bad configs.

Bail-out early and noisy during SCMI stack initialization if no transport
was enabled in configuration since SCMI cannot work without at least one
enabled transport and such constraint cannot be enforced in Kconfig due to
circular dependency issues.

Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index b28111ea7c8b..b406b3f78f46 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2067,9 +2067,11 @@ static int __init scmi_driver_init(void)
 {
 	int ret;
 
-	scmi_bus_init();
+	/* Bail out if no SCMI transport was configured */
+	if (WARN_ON(!IS_ENABLED(CONFIG_ARM_SCMI_HAVE_TRANSPORT)))
+		return -EINVAL;
 
-	BUILD_BUG_ON(!IS_ENABLED(CONFIG_ARM_SCMI_HAVE_TRANSPORT));
+	scmi_bus_init();
 
 	/* Initialize any compiled-in transport which provided an init/exit */
 	ret = scmi_transports_init();
-- 
2.17.1



From joro at 8bytes.org  Mon Aug  9 02:27:26 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Mon, 9 Aug 2021 11:27:26 +0200
Subject: [PATCH v5 0/3] Apple M1 DART IOMMU driver
In-Reply-To: <20210803121651.61594-1-sven@svenpeter.dev>
References: <20210803121651.61594-1-sven@svenpeter.dev>
Message-ID: <YRD0/qZek2iCwsJi@8bytes.org>

On Tue, Aug 03, 2021 at 02:16:48PM +0200, Sven Peter wrote:
> Sven Peter (3):
>   iommu/io-pgtable: Add DART pagetable format
>   dt-bindings: iommu: add DART iommu bindings
>   iommu/dart: Add DART iommu driver

Applied, thanks. This driver now lives in the apple/dart branch of the
IOMMU tree.



From wangkefeng.wang at huawei.com  Mon Aug  9 02:37:47 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 9 Aug 2021 17:37:47 +0800
Subject: [PATCH v3 0/3] arm64: support page mapping percpu first chunk
 allocator
Message-ID: <20210809093750.131091-1-wangkefeng.wang@huawei.com>

Percpu embedded first chunk allocator is the firstly option, but it
could fails on ARM64, eg,
  "percpu: max_distance=0x5fcfdc640000 too large for vmalloc space 0x781fefff0000"
  "percpu: max_distance=0x600000540000 too large for vmalloc space 0x7dffb7ff0000"
  "percpu: max_distance=0x5fff9adb0000 too large for vmalloc space 0x5dffb7ff0000"

then we could meet "WARNING: CPU: 15 PID: 461 at vmalloc.c:3087 pcpu_get_vm_areas+0x488/0x838",
even the system could not boot successfully.

Let's implement page mapping percpu first chunk allocator as a fallback
to the embedding allocator to increase the robustness of the system.

Also fix a crash when both NEED_PER_CPU_PAGE_FIRST_CHUNK and KASAN_VMALLOC enabled.

Tested on ARM64 qemu with cmdline "percpu_alloc=page" based on v5.14-rc5.

v3:
- search for a range that fits instead of always picking the end from
  vmalloc area suggested by Catalin.
- use NUMA_NO_NODE to avoid "virt_to_phys used for non-linear address:"
  issue in arm64 kasan_populate_early_vm_area_shadow().
- add Acked-by: Marco Elver <elver at google.com> to patch v3

V2:
- fix build error when CONFIG_KASAN disabled, found by lkp at intel.com
- drop wrong __weak comment from kasan_populate_early_vm_area_shadow(),
  found by Marco Elver <elver at google.com>

Kefeng Wang (3):
  vmalloc: Choose a better start address in vm_area_register_early()
  arm64: Support page mapping percpu first chunk allocator
  kasan: arm64: Fix pcpu_page_first_chunk crash with KASAN_VMALLOC

 arch/arm64/Kconfig         |  4 ++
 arch/arm64/mm/kasan_init.c | 16 ++++++++
 drivers/base/arch_numa.c   | 82 +++++++++++++++++++++++++++++++++-----
 include/linux/kasan.h      |  6 +++
 mm/kasan/init.c            |  5 +++
 mm/vmalloc.c               | 17 +++++---
 6 files changed, 115 insertions(+), 15 deletions(-)

-- 
2.26.2



From wangkefeng.wang at huawei.com  Mon Aug  9 02:37:48 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 9 Aug 2021 17:37:48 +0800
Subject: [PATCH v3 1/3] vmalloc: Choose a better start address in
 vm_area_register_early()
In-Reply-To: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
Message-ID: <20210809093750.131091-2-wangkefeng.wang@huawei.com>

There are some fixed locations in the vmalloc area be reserved
in ARM(see iotable_init()) and ARM64(see map_kernel()), but for
pcpu_page_first_chunk(), it calls vm_area_register_early() and
choose VMALLOC_START as the start address of vmap area which
could be conflicted with above address, then could trigger a
BUG_ON in vm_area_add_early().

Let's choose the end of existing address range in vmlist as the
start address instead of VMALLOC_START to avoid the BUG_ON.

Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 mm/vmalloc.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d5cd52805149..1e8fe08725b8 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2238,11 +2238,17 @@ void __init vm_area_add_early(struct vm_struct *vm)
  */
 void __init vm_area_register_early(struct vm_struct *vm, size_t align)
 {
-	static size_t vm_init_off __initdata;
-	unsigned long addr;
-
-	addr = ALIGN(VMALLOC_START + vm_init_off, align);
-	vm_init_off = PFN_ALIGN(addr + vm->size) - VMALLOC_START;
+	struct vm_struct *head = vmlist, *curr, *next;
+	unsigned long addr = ALIGN(VMALLOC_START, align);
+
+	while (head != NULL) {
+		next = head->next;
+		curr = head;
+		head = next;
+		addr = ALIGN((unsigned long)curr->addr + curr->size, align);
+		if (next && (unsigned long)next->addr - addr > vm->size)
+			break;
+	}
 
 	vm->addr = (void *)addr;
 
-- 
2.26.2



From wangkefeng.wang at huawei.com  Mon Aug  9 02:37:50 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 9 Aug 2021 17:37:50 +0800
Subject: [PATCH v3 3/3] kasan: arm64: Fix pcpu_page_first_chunk crash with
 KASAN_VMALLOC
In-Reply-To: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
Message-ID: <20210809093750.131091-4-wangkefeng.wang@huawei.com>

With KASAN_VMALLOC and NEED_PER_CPU_PAGE_FIRST_CHUNK, it crashs,

Unable to handle kernel paging request at virtual address ffff7000028f2000
...
swapper pgtable: 64k pages, 48-bit VAs, pgdp=0000000042440000
[ffff7000028f2000] pgd=000000063e7c0003, p4d=000000063e7c0003, pud=000000063e7c0003, pmd=000000063e7b0003, pte=0000000000000000
Internal error: Oops: 96000007 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.0-rc4-00003-gc6e6e28f3f30-dirty #62
Hardware name: linux,dummy-virt (DT)
pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO BTYPE=--)
pc : kasan_check_range+0x90/0x1a0
lr : memcpy+0x88/0xf4
sp : ffff80001378fe20
...
Call trace:
 kasan_check_range+0x90/0x1a0
 pcpu_page_first_chunk+0x3f0/0x568
 setup_per_cpu_areas+0xb8/0x184
 start_kernel+0x8c/0x328

The vm area used in vm_area_register_early() has no kasan shadow memory,
Let's add a new kasan_populate_early_vm_area_shadow() function to populate
the vm area shadow memory to fix the issue.

Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 arch/arm64/mm/kasan_init.c | 16 ++++++++++++++++
 include/linux/kasan.h      |  6 ++++++
 mm/kasan/init.c            |  5 +++++
 mm/vmalloc.c               |  1 +
 4 files changed, 28 insertions(+)

diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 61b52a92b8b6..5b996ca4d996 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -287,6 +287,22 @@ static void __init kasan_init_depth(void)
 	init_task.kasan_depth = 0;
 }
 
+#ifdef CONFIG_KASAN_VMALLOC
+void __init kasan_populate_early_vm_area_shadow(void *start, unsigned long size)
+{
+	unsigned long shadow_start, shadow_end;
+
+	if (!is_vmalloc_or_module_addr(start))
+		return;
+
+	shadow_start = (unsigned long)kasan_mem_to_shadow(start);
+	shadow_start = ALIGN_DOWN(shadow_start, PAGE_SIZE);
+	shadow_end = (unsigned long)kasan_mem_to_shadow(start + size);
+	shadow_end = ALIGN(shadow_end, PAGE_SIZE);
+	kasan_map_populate(shadow_start, shadow_end, NUMA_NO_NODE);
+}
+#endif
+
 void __init kasan_init(void)
 {
 	kasan_init_shadow();
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index dd874a1ee862..3f8c26d9ef82 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -133,6 +133,8 @@ struct kasan_cache {
 	bool is_kmalloc;
 };
 
+void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
+
 slab_flags_t __kasan_never_merge(void);
 static __always_inline slab_flags_t kasan_never_merge(void)
 {
@@ -303,6 +305,10 @@ void kasan_restore_multi_shot(bool enabled);
 
 #else /* CONFIG_KASAN */
 
+static inline void kasan_populate_early_vm_area_shadow(void *start,
+						       unsigned long size)
+{ }
+
 static inline slab_flags_t kasan_never_merge(void)
 {
 	return 0;
diff --git a/mm/kasan/init.c b/mm/kasan/init.c
index cc64ed6858c6..d39577d088a1 100644
--- a/mm/kasan/init.c
+++ b/mm/kasan/init.c
@@ -279,6 +279,11 @@ int __ref kasan_populate_early_shadow(const void *shadow_start,
 	return 0;
 }
 
+void __init __weak kasan_populate_early_vm_area_shadow(void *start,
+						       unsigned long size)
+{
+}
+
 static void kasan_free_pte(pte_t *pte_start, pmd_t *pmd)
 {
 	pte_t *pte;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1e8fe08725b8..66a7e1ea2561 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2253,6 +2253,7 @@ void __init vm_area_register_early(struct vm_struct *vm, size_t align)
 	vm->addr = (void *)addr;
 
 	vm_area_add_early(vm);
+	kasan_populate_early_vm_area_shadow(vm->addr, vm->size);
 }
 
 static void vmap_init_free_space(void)
-- 
2.26.2



From wangkefeng.wang at huawei.com  Mon Aug  9 02:37:49 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 9 Aug 2021 17:37:49 +0800
Subject: [PATCH v3 2/3] arm64: Support page mapping percpu first chunk
 allocator
In-Reply-To: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
Message-ID: <20210809093750.131091-3-wangkefeng.wang@huawei.com>

Percpu embedded first chunk allocator is the firstly option, but it
could fails on ARM64, eg,
  "percpu: max_distance=0x5fcfdc640000 too large for vmalloc space 0x781fefff0000"
  "percpu: max_distance=0x600000540000 too large for vmalloc space 0x7dffb7ff0000"
  "percpu: max_distance=0x5fff9adb0000 too large for vmalloc space 0x5dffb7ff0000"

then we could meet "WARNING: CPU: 15 PID: 461 at vmalloc.c:3087 pcpu_get_vm_areas+0x488/0x838",
even the system could not boot successfully.

Let's implement page mapping percpu first chunk allocator as a fallback
to the embedding allocator to increase the robustness of the system.

Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 arch/arm64/Kconfig       |  4 ++
 drivers/base/arch_numa.c | 82 +++++++++++++++++++++++++++++++++++-----
 2 files changed, 76 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index fdcd54d39c1e..39f27e268c38 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1045,6 +1045,10 @@ config NEED_PER_CPU_EMBED_FIRST_CHUNK
 	def_bool y
 	depends on NUMA
 
+config NEED_PER_CPU_PAGE_FIRST_CHUNK
+	def_bool y
+	depends on NUMA
+
 source "kernel/Kconfig.hz"
 
 config ARCH_SPARSEMEM_ENABLE
diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index 4cc4e117727d..563b2013b75a 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -14,6 +14,7 @@
 #include <linux/of.h>
 
 #include <asm/sections.h>
+#include <asm/pgalloc.h>
 
 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
 EXPORT_SYMBOL(node_data);
@@ -168,22 +169,83 @@ static void __init pcpu_fc_free(void *ptr, size_t size)
 	memblock_free_early(__pa(ptr), size);
 }
 
+#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
+static void __init pcpu_populate_pte(unsigned long addr)
+{
+	pgd_t *pgd = pgd_offset_k(addr);
+	p4d_t *p4d;
+	pud_t *pud;
+	pmd_t *pmd;
+
+	p4d = p4d_offset(pgd, addr);
+	if (p4d_none(*p4d)) {
+		pud_t *new;
+
+		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+		if (!new)
+			goto err_alloc;
+		p4d_populate(&init_mm, p4d, new);
+	}
+
+	pud = pud_offset(p4d, addr);
+	if (pud_none(*pud)) {
+		pmd_t *new;
+
+		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+		if (!new)
+			goto err_alloc;
+		pud_populate(&init_mm, pud, new);
+	}
+
+	pmd = pmd_offset(pud, addr);
+	if (!pmd_present(*pmd)) {
+		pte_t *new;
+
+		new = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+		if (!new)
+			goto err_alloc;
+		pmd_populate_kernel(&init_mm, pmd, new);
+	}
+
+	return;
+
+err_alloc:
+	panic("%s: Failed to allocate %lu bytes align=%lx from=%lx\n",
+	      __func__, PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+}
+#endif
+
 void __init setup_per_cpu_areas(void)
 {
 	unsigned long delta;
 	unsigned int cpu;
-	int rc;
+	int rc = -EINVAL;
+
+	if (pcpu_chosen_fc != PCPU_FC_PAGE) {
+		/*
+		 * Always reserve area for module percpu variables.  That's
+		 * what the legacy allocator did.
+		 */
+		rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
+					    PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
+					    pcpu_cpu_distance,
+					    pcpu_fc_alloc, pcpu_fc_free);
+#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
+		if (rc < 0)
+			pr_warn("PERCPU: %s allocator failed (%d), falling back to page size\n",
+				   pcpu_fc_names[pcpu_chosen_fc], rc);
+#endif
+	}
 
-	/*
-	 * Always reserve area for module percpu variables.  That's
-	 * what the legacy allocator did.
-	 */
-	rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
-				    PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
-				    pcpu_cpu_distance,
-				    pcpu_fc_alloc, pcpu_fc_free);
+#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
+	if (rc < 0)
+		rc = pcpu_page_first_chunk(PERCPU_MODULE_RESERVE,
+					   pcpu_fc_alloc,
+					   pcpu_fc_free,
+					   pcpu_populate_pte);
+#endif
 	if (rc < 0)
-		panic("Failed to initialize percpu areas.");
+		panic("Failed to initialize percpu areas (err=%d).", rc);
 
 	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
 	for_each_possible_cpu(cpu)
-- 
2.26.2



From maz at kernel.org  Mon Aug  9 02:39:03 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Aug 2021 10:39:03 +0100
Subject: [PATCH v2 2/3] PCI: j721e: Add PCI legacy interrupt support for
 J721E
In-Reply-To: <c20be7ae-e4a7-c3ba-f1c9-e4ff2aae0a66@ti.com>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-3-kishon@ti.com>
 <87h7g5w8d8.wl-maz@kernel.org>
 <c20be7ae-e4a7-c3ba-f1c9-e4ff2aae0a66@ti.com>
Message-ID: <87o8a7arew.wl-maz@kernel.org>

On Mon, 09 Aug 2021 05:50:10 +0100,
Kishon Vijay Abraham I <kishon at ti.com> wrote:
> 
> Hi Marc,
> 
> On 04/08/21 8:43 pm, Marc Zyngier wrote:
> > On Wed, 04 Aug 2021 14:29:11 +0100,
> > Kishon Vijay Abraham I <kishon at ti.com> wrote:
> >>
> >> Add PCI legacy interrupt support for J721E. J721E has a single HW
> >> interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
> >> The HW interrupt line connected to GIC is a pulse interrupt whereas
> >> the legacy interrupts by definition is level interrupt. In order to
> >> provide level interrupt functionality to edge interrupt line, PCIe
> >> in J721E has provided IRQ_EOI register.
> >>
> >> However due to Errata ID #i2094 ([1]), EOI feature is not enabled in HW
> >> and only a single pulse interrupt will be generated for every
> >> ASSERT_INTx/DEASSERT_INTx.
> > 
> > So my earlier remark stands. If you get a single edge, how do you
> > handle a level that is still high after having handled the interrupt
> > on hardware that has this bug?
> 
> Right, this hardware (J721E) has a bug but was fixed in J7200 (Patch 3/3
> handles that).

But how do you make it work with J721E? Is it even worth supporting if
(as I expect) it is unreliable?

> > 
> >>
> >> [1] -> J721E DRA829/TDA4VM Processors Silicon Revision 1.1/1.0 SPRZ455A ?
> >>        DECEMBER 2020 ? REVISED AUGUST 2021
> >>        (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf)
> >>
> >> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> >> ---
> >>  drivers/pci/controller/cadence/pci-j721e.c | 85 ++++++++++++++++++++++
> >>  1 file changed, 85 insertions(+)
> >>
> >> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
> >> index 2ec037c43bd5..c2e7a78dc31f 100644
> >> --- a/drivers/pci/controller/cadence/pci-j721e.c
> >> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> >> @@ -29,6 +29,13 @@
> >>  #define LINK_DOWN		BIT(1)
> >>  #define J7200_LINK_DOWN		BIT(10)
> >>  
> >> +#define EOI_REG			0x10
> >> +
> >> +#define ENABLE_REG_SYS_0	0x100
> >> +#define STATUS_REG_SYS_0	0x500
> >> +#define STATUS_CLR_REG_SYS_0	0x700
> >> +#define INTx_EN(num)		(1 << (num))
> >> +
> >>  #define J721E_PCIE_USER_CMD_STATUS	0x4
> >>  #define LINK_TRAINING_ENABLE		BIT(0)
> >>  
> >> @@ -59,6 +66,7 @@ struct j721e_pcie {
> >>  	void __iomem		*user_cfg_base;
> >>  	void __iomem		*intd_cfg_base;
> >>  	u32			linkdown_irq_regfield;
> >> +	struct irq_domain	*legacy_irq_domain;
> >>  };
> >>  
> >>  enum j721e_pcie_mode {
> >> @@ -121,6 +129,79 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
> >>  	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
> >>  }
> >>  
> >> +static void j721e_pcie_v1_legacy_irq_handler(struct irq_desc *desc)
> >> +{
> >> +	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
> >> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> >> +	int i, virq;
> >> +	u32 reg;
> >> +
> >> +	chained_irq_enter(chip, desc);
> >> +
> >> +	for (i = 0; i < PCI_NUM_INTX; i++) {
> >> +		reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_0);
> >> +		if (!(reg & INTx_EN(i)))
> >> +			continue;
> > 
> > Why do you need to perform multiple reads? Surely reg contains all the
> > bits you need, doesn't it?
> 
> Right, will fix it up.
> > 
> >> +
> >> +		virq = irq_find_mapping(pcie->legacy_irq_domain, 3 - i);
> >> +		generic_handle_irq(virq);
> > 
> > Please combine both lines into a single generic_handle_domain_irq()
> > call.
> 
> Okay.
> > 
> >> +		j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_0, INTx_EN(i));
> > 
> > What is the purpose of this write? It feels like this should be a
> > irq_eoi callback.
> 
> It's an IRQ ACK, since in this platform the level to edge is not
> implemented properly in HW.

An Ack for an edge interrupt would need to happen before you handle
the interrupt, or you'd wrongly acknowledge edges that fire between
the handling of the interrupt and the Ack, and that would never be
handled.

If it really is an Ack, it needs to be moved *before* the handling,
preferably in an irq_ack callback. Otherwise, it is an EOI, and it
belongs to irq_eoi.

> > 
> >> +	}
> >> +
> >> +	chained_irq_exit(chip, desc);
> >> +}
> >> +
> >> +static int j721e_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq)
> >> +{
> >> +	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
> > 
> > An INTx interrupt is a level interrupt. Please use the corresponding flow.
> 
> Okay.
> > 
> >> +	irq_set_chip_data(irq, domain->host_data);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static const struct irq_domain_ops j721e_pcie_intx_domain_ops = {
> >> +	.map = j721e_pcie_intx_map,
> >> +};
> >> +
> >> +static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
> >> +{
> >> +	struct irq_domain *legacy_irq_domain;
> >> +	struct device *dev = pcie->dev;
> >> +	struct device_node *node = dev->of_node;
> >> +	struct device_node *intc_node;
> >> +	int irq, i;
> >> +	u32 reg;
> >> +
> >> +	intc_node = of_get_child_by_name(node, "interrupt-controller");
> >> +	if (!intc_node) {
> >> +		dev_dbg(dev, "interrupt-controller node is absent. Legacy INTR not supported\n");
> >> +		return 0;
> >> +	}
> >> +
> >> +	irq = irq_of_parse_and_map(intc_node, 0);
> >> +	if (!irq) {
> >> +		dev_err(dev, "Failed to parse and map legacy irq\n");
> >> +		return -EINVAL;
> >> +	}
> >> +	irq_set_chained_handler_and_data(irq, j721e_pcie_v1_legacy_irq_handler, pcie);
> >> +
> >> +	legacy_irq_domain = irq_domain_add_linear(intc_node, PCI_NUM_INTX,
> >> +						  &j721e_pcie_intx_domain_ops, pcie);
> >> +	if (!legacy_irq_domain) {
> >> +		dev_err(dev, "Failed to add irq domain for legacy irqs\n");
> >> +		return -EINVAL;
> >> +	}
> >> +	pcie->legacy_irq_domain = legacy_irq_domain;
> >> +
> >> +	for (i = 0; i < PCI_NUM_INTX; i++) {
> >> +		reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_0);
> >> +		reg |= INTx_EN(i);
> >> +		j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_0, reg);
> >> +	}
> > 
> > This should be moved to the irq_unmask() callback.
> 
> Should we also have a corresponding irq_mask()? Then would require us
> implement reference counting since legacy interrupts are shared.

The core code should already deal with this, I expect. It isn't like
shared interrupts are something new. And yes, you should have both
mask and unmask.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From ikjn at chromium.org  Mon Aug  9 02:42:05 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Mon, 9 Aug 2021 17:42:05 +0800
Subject: [RFC PATCH] usb: xhci-mtk: handle bandwidth table rollover
In-Reply-To: <YRDxTodNNqtnpPpn@kroah.com>
References: <20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid>
 <YRDxTodNNqtnpPpn@kroah.com>
Message-ID: <CAATdQgDSCzZtiDSQk94CYHfSb9Mq28OH7-RdaTZNv3oPrW3nkQ@mail.gmail.com>

On Mon, Aug 9, 2021 at 5:11 PM Greg Kroah-Hartman
<gregkh at linuxfoundation.org> wrote:
>
> On Mon, Aug 09, 2021 at 04:59:29PM +0800, Ikjoon Jang wrote:
> > xhci-mtk has 64 slots for periodic bandwidth calculations and each
> > slot represents byte budgets on a microframe. When an endpoint's
> > allocation sits on the boundary of the table, byte budgets' slot
> > should be rolled over but the current implementation doesn't.
> >
> > This patch applies a 6 bits mask to the microframe index to handle
> > its rollover 64 slots and prevent out-of-bounds array access.
> >
> > Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
> > ---
> >
> >  drivers/usb/host/xhci-mtk-sch.c | 79 +++++++++------------------------
> >  drivers/usb/host/xhci-mtk.h     |  1 +
> >  2 files changed, 23 insertions(+), 57 deletions(-)
>
> Why is this "RFC"?  What needs to be addressed in this change before it
> can be accepted?

sorry, I had to mention why this is RFC:

I simply don't know about the details of the xhci-mtk internals.
It was okay from my tests with mt8173 and I think this will be harmless
as this is "better than before".

But when I removed get_esit_boundary(), I really have no idea why
it was there. I'm wondering if there was another reason of that function
other than just preventing out-of-bounds. Maybe chunfeng can answer this?

Thanks!

>
> thanks,
>
> greg k-h


From trevor.wu at mediatek.com  Mon Aug  9 02:48:47 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Mon, 9 Aug 2021 17:48:47 +0800
Subject: [PATCH v3 1/9] ASoC: mediatek: mt8195: update mediatek common driver
In-Reply-To: <20210809094855.7169-1-trevor.wu@mediatek.com>
References: <20210809094855.7169-1-trevor.wu@mediatek.com>
Message-ID: <20210809094855.7169-2-trevor.wu@mediatek.com>

Update mediatek common driver to support MT8195

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 sound/soc/mediatek/common/mtk-afe-fe-dai.c | 22 +++++++++++++++++++---
 sound/soc/mediatek/common/mtk-base-afe.h   | 10 ++++++++--
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
index 3cb2adf420bb..baaa5881b1d4 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -139,7 +139,7 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
 		substream->runtime->dma_area,
 		substream->runtime->dma_bytes);
 
-	memset_io(substream->runtime->dma_area, 0,
+	memset_io((void __force __iomem *)substream->runtime->dma_area, 0,
 		  substream->runtime->dma_bytes);
 
 	/* set addr */
@@ -433,11 +433,20 @@ int mtk_memif_set_addr(struct mtk_base_afe *afe, int id,
 				 phys_buf_addr_upper_32);
 	}
 
-	/* set MSB to 33-bit */
-	if (memif->data->msb_reg >= 0)
+	/*
+	 * set MSB to 33-bit, for memif address
+	 * only for memif base address, if msb_end_reg exists
+	 */
+	if (memif->data->msb_reg)
 		mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg,
 				       1, msb_at_bit33, memif->data->msb_shift);
 
+	/* set MSB to 33-bit, for memif end address */
+	if (memif->data->msb_end_reg)
+		mtk_regmap_update_bits(afe->regmap, memif->data->msb_end_reg,
+				       1, msb_at_bit33,
+				       memif->data->msb_end_shift);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_memif_set_addr);
@@ -464,6 +473,13 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe,
 	else
 		mono = (channel == 1) ? 1 : 0;
 
+	/* for specific configuration of memif mono mode */
+	if (memif->data->int_odd_flag_reg)
+		mtk_regmap_update_bits(afe->regmap,
+				       memif->data->int_odd_flag_reg,
+				       1, mono,
+				       memif->data->int_odd_flag_shift);
+
 	return mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg,
 				      1, mono, memif->data->mono_shift);
 }
diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h
index a6f68c68581c..ef83e78c22a8 100644
--- a/sound/soc/mediatek/common/mtk-base-afe.h
+++ b/sound/soc/mediatek/common/mtk-base-afe.h
@@ -29,6 +29,8 @@ struct mtk_base_memif_data {
 	int quad_ch_reg;
 	int quad_ch_mask;
 	int quad_ch_shift;
+	int int_odd_flag_reg;
+	int int_odd_flag_shift;
 	int enable_reg;
 	int enable_shift;
 	int hd_reg;
@@ -37,10 +39,13 @@ struct mtk_base_memif_data {
 	int hd_align_mshift;
 	int msb_reg;
 	int msb_shift;
-	int msb2_reg;
-	int msb2_shift;
+	int msb_end_reg;
+	int msb_end_shift;
 	int agent_disable_reg;
 	int agent_disable_shift;
+	int ch_num_reg;
+	int ch_num_shift;
+	int ch_num_maskbit;
 	/* playback memif only */
 	int pbuf_reg;
 	int pbuf_mask;
@@ -62,6 +67,7 @@ struct mtk_base_irq_data {
 	int irq_en_shift;
 	int irq_clr_reg;
 	int irq_clr_shift;
+	int irq_status_shift;
 };
 
 struct device;
-- 
2.18.0

From trevor.wu at mediatek.com  Mon Aug  9 02:48:51 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Mon, 9 Aug 2021 17:48:51 +0800
Subject: [PATCH v3 5/9] ASoC: mediatek: mt8195: support pcm in platform driver
In-Reply-To: <20210809094855.7169-1-trevor.wu@mediatek.com>
References: <20210809094855.7169-1-trevor.wu@mediatek.com>
Message-ID: <20210809094855.7169-6-trevor.wu@mediatek.com>

This patch adds mt8195 pcm dai driver.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c | 389 +++++++++++++++++++++
 1 file changed, 389 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c

diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
new file mode 100644
index 000000000000..5d10d2c4c991
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
@@ -0,0 +1,389 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI PCM I/F Control
+ *
+ * Copyright (c) 2020 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai at mediatek.com>
+ *         Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+enum {
+	MTK_DAI_PCM_FMT_I2S,
+	MTK_DAI_PCM_FMT_EIAJ,
+	MTK_DAI_PCM_FMT_MODEA,
+	MTK_DAI_PCM_FMT_MODEB,
+};
+
+enum {
+	MTK_DAI_PCM_CLK_A1SYS,
+	MTK_DAI_PCM_CLK_A2SYS,
+	MTK_DAI_PCM_CLK_26M_48K,
+	MTK_DAI_PCM_CLK_26M_441K,
+};
+
+struct mtk_dai_pcm_rate {
+	unsigned int rate;
+	unsigned int reg_value;
+};
+
+struct mtk_dai_pcmif_priv {
+	unsigned int slave_mode;
+	unsigned int lrck_inv;
+	unsigned int bck_inv;
+	unsigned int format;
+};
+
+static const struct mtk_dai_pcm_rate mtk_dai_pcm_rates[] = {
+	{ .rate = 8000, .reg_value = 0, },
+	{ .rate = 16000, .reg_value = 1, },
+	{ .rate = 32000, .reg_value = 2, },
+	{ .rate = 48000, .reg_value = 3, },
+	{ .rate = 11025, .reg_value = 1, },
+	{ .rate = 22050, .reg_value = 2, },
+	{ .rate = 44100, .reg_value = 3, },
+};
+
+static int mtk_dai_pcm_mode(unsigned int rate)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_dai_pcm_rates); i++)
+		if (mtk_dai_pcm_rates[i].rate == rate)
+			return mtk_dai_pcm_rates[i].reg_value;
+
+	return -EINVAL;
+}
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o000_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN0, 0, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN0_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o001_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN1, 1, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN1_2, 7, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
+	SND_SOC_DAPM_MIXER("I002", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I003", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("O000", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_pcm_o000_mix,
+			   ARRAY_SIZE(mtk_dai_pcm_o000_mix)),
+	SND_SOC_DAPM_MIXER("O001", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_pcm_o001_mix,
+			   ARRAY_SIZE(mtk_dai_pcm_o001_mix)),
+
+	SND_SOC_DAPM_INPUT("PCM1_INPUT"),
+	SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
+	{"I002", NULL, "PCM1 Capture"},
+	{"I003", NULL, "PCM1 Capture"},
+
+	{"O000", "I000 Switch", "I000"},
+	{"O001", "I001 Switch", "I001"},
+
+	{"O000", "I070 Switch", "I070"},
+	{"O001", "I071 Switch", "I071"},
+
+	{"PCM1 Playback", NULL, "O000"},
+	{"PCM1 Playback", NULL, "O001"},
+
+	{"PCM1_OUTPUT", NULL, "PCM1 Playback"},
+	{"PCM1 Capture", NULL, "PCM1_INPUT"},
+};
+
+static void mtk_dai_pcm_enable(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_PCM_EN, PCM_INTF_CON1_PCM_EN);
+}
+
+static void mtk_dai_pcm_disable(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_PCM_EN, 0x0);
+}
+
+static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_pcm_runtime * const runtime = substream->runtime;
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
+	unsigned int slave_mode = pcmif_priv->slave_mode;
+	unsigned int lrck_inv = pcmif_priv->lrck_inv;
+	unsigned int bck_inv = pcmif_priv->bck_inv;
+	unsigned int fmt = pcmif_priv->format;
+	unsigned int bit_width = dai->sample_bits;
+	unsigned int val = 0;
+	unsigned int mask = 0;
+	int fs = 0;
+	int mode = 0;
+
+	/* sync freq mode */
+	fs = mt8195_afe_fs_timing(runtime->rate);
+	if (fs < 0)
+		return -EINVAL;
+	val |= PCM_INTF_CON2_SYNC_FREQ_MODE(fs);
+	mask |= PCM_INTF_CON2_SYNC_FREQ_MODE_MASK;
+
+	/* clk domain sel */
+	if (runtime->rate % 8000)
+		val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_441K);
+	else
+		val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_48K);
+	mask |= PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK;
+
+	regmap_update_bits(afe->regmap, PCM_INTF_CON2, mask, val);
+
+	val = 0;
+	mask = 0;
+
+	/* pcm mode */
+	mode = mtk_dai_pcm_mode(runtime->rate);
+	if (mode < 0)
+		return -EINVAL;
+	val |= PCM_INTF_CON1_PCM_MODE(mode);
+	mask |= PCM_INTF_CON1_PCM_MODE_MASK;
+
+	/* pcm format */
+	val |= PCM_INTF_CON1_PCM_FMT(fmt);
+	mask |= PCM_INTF_CON1_PCM_FMT_MASK;
+
+	/* pcm sync length */
+	if (fmt == MTK_DAI_PCM_FMT_MODEA ||
+	    fmt == MTK_DAI_PCM_FMT_MODEB)
+		val |= PCM_INTF_CON1_SYNC_LENGTH(1);
+	else
+		val |= PCM_INTF_CON1_SYNC_LENGTH(bit_width);
+	mask |= PCM_INTF_CON1_SYNC_LENGTH_MASK;
+
+	/* pcm bits, word length */
+	if (bit_width > 16) {
+		val |= PCM_INTF_CON1_PCM_24BIT;
+		val |= PCM_INTF_CON1_PCM_WLEN_64BCK;
+	} else {
+		val |= PCM_INTF_CON1_PCM_16BIT;
+		val |= PCM_INTF_CON1_PCM_WLEN_32BCK;
+	}
+	mask |= PCM_INTF_CON1_PCM_BIT_MASK;
+	mask |= PCM_INTF_CON1_PCM_WLEN_MASK;
+
+	/* master/slave */
+	if (!slave_mode) {
+		val |= PCM_INTF_CON1_PCM_MASTER;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_OUT_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_OUT_INV;
+		mask |= PCM_INTF_CON1_CLK_OUT_INV_MASK;
+	} else {
+		val |= PCM_INTF_CON1_PCM_SLAVE;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_IN_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_IN_INV;
+		mask |= PCM_INTF_CON1_CLK_IN_INV_MASK;
+
+		/* TODO: add asrc setting for slave mode */
+	}
+	mask |= PCM_INTF_CON1_PCM_M_S_MASK;
+
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1, mask, val);
+
+	return 0;
+}
+
+/* dai ops */
+static int mtk_dai_pcm_startup(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+	if (dai->component->active)
+		return 0;
+
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]);
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]);
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]);
+
+	return 0;
+}
+
+static void mtk_dai_pcm_shutdown(struct snd_pcm_substream *substream,
+				 struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+	if (dai->component->active)
+		return;
+
+	mtk_dai_pcm_disable(afe);
+
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]);
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]);
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]);
+}
+
+static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	int ret = 0;
+
+	if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) &&
+	    snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE))
+		return 0;
+
+	ret = mtk_dai_pcm_configure(substream, dai);
+	if (ret)
+		return ret;
+
+	mtk_dai_pcm_enable(afe);
+
+	return 0;
+}
+
+static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
+
+	dev_dbg(dai->dev, "%s fmt 0x%x\n", __func__, fmt);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_I2S;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_MODEA;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_MODEB;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		pcmif_priv->bck_inv = 0;
+		pcmif_priv->lrck_inv = 0;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		pcmif_priv->bck_inv = 0;
+		pcmif_priv->lrck_inv = 1;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		pcmif_priv->bck_inv = 1;
+		pcmif_priv->lrck_inv = 0;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		pcmif_priv->bck_inv = 1;
+		pcmif_priv->lrck_inv = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		pcmif_priv->slave_mode = 1;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		pcmif_priv->slave_mode = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_pcm_ops = {
+	.startup	= mtk_dai_pcm_startup,
+	.shutdown	= mtk_dai_pcm_shutdown,
+	.prepare	= mtk_dai_pcm_prepare,
+	.set_fmt	= mtk_dai_pcm_set_fmt,
+};
+
+/* dai driver */
+#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000)
+
+#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+			 SNDRV_PCM_FMTBIT_S24_LE |\
+			 SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
+	{
+		.name = "PCM1",
+		.id = MT8195_AFE_IO_PCM,
+		.playback = {
+			.stream_name = "PCM1 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_PCM_RATES,
+			.formats = MTK_PCM_FORMATS,
+		},
+		.capture = {
+			.stream_name = "PCM1 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_PCM_RATES,
+			.formats = MTK_PCM_FORMATS,
+		},
+		.ops = &mtk_dai_pcm_ops,
+		.symmetric_rate = 1,
+		.symmetric_sample_bits = 1,
+	},
+};
+
+static int init_pcmif_priv_data(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv;
+
+	pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_pcmif_priv),
+				  GFP_KERNEL);
+	if (!pcmif_priv)
+		return -ENOMEM;
+
+	afe_priv->dai_priv[MT8195_AFE_IO_PCM] = pcmif_priv;
+	return 0;
+}
+
+int mt8195_dai_pcm_register(struct mtk_base_afe *afe)
+{
+	struct mtk_base_afe_dai *dai;
+
+	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+
+	list_add(&dai->list, &afe->sub_dais);
+
+	dai->dai_drivers = mtk_dai_pcm_driver;
+	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
+
+	dai->dapm_widgets = mtk_dai_pcm_widgets;
+	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
+	dai->dapm_routes = mtk_dai_pcm_routes;
+	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
+
+	return init_pcmif_priv_data(afe);
+}
-- 
2.18.0

From trevor.wu at mediatek.com  Mon Aug  9 02:48:53 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Mon, 9 Aug 2021 17:48:53 +0800
Subject: [PATCH v3 7/9] dt-bindings: mediatek: mt8195: add audio afe document
In-Reply-To: <20210809094855.7169-1-trevor.wu@mediatek.com>
References: <20210809094855.7169-1-trevor.wu@mediatek.com>
Message-ID: <20210809094855.7169-8-trevor.wu@mediatek.com>

This patch adds mt8195 audio afe document.

In order to support dynamic clock reparenting for ADDA and ETDM, PLL
and MUX clocks are requested even though they are not consumed by afe
directly.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
This patch depends on the following series that have not been accepted.

[1] Mediatek MT8195 clock support
https://patchwork.kernel.org/project/linux-mediatek/list/?series=501923
(dt-bindings/clock/mt8195-clk.h is included)

[2] Mediatek MT8195 power domain support
https://patchwork.kernel.org/project/linux-mediatek/list/?series=500709
(dt-bindings/power/mt8195-power.h is included)
---
---
 .../bindings/sound/mt8195-afe-pcm.yaml        | 184 ++++++++++++++++++
 1 file changed, 184 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml

diff --git a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
new file mode 100644
index 000000000000..53e9434a6d9d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt8195-afe-pcm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek AFE PCM controller for mt8195
+
+maintainers:
+  - Trevor Wu <trevor.wu at mediatek.com>
+
+properties:
+  compatible:
+    const: mediatek,mt8195-audio
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  mediatek,topckgen:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of the mediatek topckgen controller
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: 26M clock
+      - description: audio pll1 clock
+      - description: audio pll2 clock
+      - description: clock divider for i2si1_mck
+      - description: clock divider for i2si2_mck
+      - description: clock divider for i2so1_mck
+      - description: clock divider for i2so2_mck
+      - description: clock divider for dptx_mck
+      - description: a1sys hoping clock
+      - description: audio intbus clock
+      - description: audio hires clock
+      - description: audio local bus clock
+      - description: mux for dptx_mck
+      - description: mux for i2so1_mck
+      - description: mux for i2so2_mck
+      - description: mux for i2si1_mck
+      - description: mux for i2si2_mck
+      - description: audio infra 26M clock
+      - description: infra bus clock
+
+  clock-names:
+    items:
+      - const: clk26m
+      - const: apll1_ck
+      - const: apll2_ck
+      - const: apll12_div0
+      - const: apll12_div1
+      - const: apll12_div2
+      - const: apll12_div3
+      - const: apll12_div9
+      - const: a1sys_hp_sel
+      - const: aud_intbus_sel
+      - const: audio_h_sel
+      - const: audio_local_bus_sel
+      - const: dptx_m_sel
+      - const: i2so1_m_sel
+      - const: i2so2_m_sel
+      - const: i2si1_m_sel
+      - const: i2si2_m_sel
+      - const: infra_ao_audio_26m_b
+      - const: scp_adsp_audiodsp
+
+  mediatek,etdm-in1-chn-disabled:
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    maxItems: 24
+    description: Specify which input channel should be disabled.
+
+  mediatek,etdm-in2-chn-disabled:
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    maxItems: 16
+    description: Specify which input channel should be disabled.
+
+patternProperties:
+  "^mediatek,etdm-in[1-2]-mclk-always-on-rate-hz$":
+    description: Specify etdm in mclk output rate for always on case.
+
+  "^mediatek,etdm-out[1-3]-mclk-always-on-rate-hz$":
+    description: Specify etdm out mclk output rate for always on case.
+
+  "^mediatek,etdm-in[1-2]-multi-pin-mode$":
+    type: boolean
+    description: if present, the etdm data mode is I2S.
+
+  "^mediatek,etdm-out[1-3]-multi-pin-mode$":
+    type: boolean
+    description: if present, the etdm data mode is I2S.
+
+  "^mediatek,etdm-in[1-2]-cowork-source$":
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      etdm modules can share the same external clock pin. Specify
+      which etdm clock source is required by this etdm in moudule.
+    enum:
+      - 0 # etdm1_in
+      - 1 # etdm2_in
+      - 2 # etdm1_out
+      - 3 # etdm2_out
+
+  "^mediatek,etdm-out[1-2]-cowork-source$":
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      etdm modules can share the same external clock pin. Specify
+      which etdm clock source is required by this etdm out moudule.
+    enum:
+      - 0 # etdm1_in
+      - 1 # etdm2_in
+      - 2 # etdm1_out
+      - 3 # etdm2_out
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - mediatek,topckgen
+  - power-domains
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt8195-power.h>
+
+    afe: mt8195-afe-pcm at 10890000 {
+        compatible = "mediatek,mt8195-audio";
+        reg = <0x10890000 0x10000>;
+        interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
+        mediatek,topckgen = <&topckgen>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_AUDIO>;
+        clocks = <&clk26m>,
+                 <&topckgen CLK_TOP_APLL1>,
+                 <&topckgen CLK_TOP_APLL2>,
+                 <&topckgen CLK_TOP_APLL12_DIV0>,
+                 <&topckgen CLK_TOP_APLL12_DIV1>,
+                 <&topckgen CLK_TOP_APLL12_DIV2>,
+                 <&topckgen CLK_TOP_APLL12_DIV3>,
+                 <&topckgen CLK_TOP_APLL12_DIV9>,
+                 <&topckgen CLK_TOP_A1SYS_HP_SEL>,
+                 <&topckgen CLK_TOP_AUD_INTBUS_SEL>,
+                 <&topckgen CLK_TOP_AUDIO_H_SEL>,
+                 <&topckgen CLK_TOP_AUDIO_LOCAL_BUS_SEL>,
+                 <&topckgen CLK_TOP_DPTX_M_SEL>,
+                 <&topckgen CLK_TOP_I2SO1_M_SEL>,
+                 <&topckgen CLK_TOP_I2SO2_M_SEL>,
+                 <&topckgen CLK_TOP_I2SI1_M_SEL>,
+                 <&topckgen CLK_TOP_I2SI2_M_SEL>,
+                 <&infracfg_ao CLK_INFRA_AO_AUDIO_26M_B>,
+                 <&scp_adsp CLK_SCP_ADSP_AUDIODSP>;
+        clock-names = "clk26m",
+                      "apll1_ck",
+                      "apll2_ck",
+                      "apll12_div0",
+                      "apll12_div1",
+                      "apll12_div2",
+                      "apll12_div3",
+                      "apll12_div9",
+                      "a1sys_hp_sel",
+                      "aud_intbus_sel",
+                      "audio_h_sel",
+                      "audio_local_bus_sel",
+                      "dptx_m_sel",
+                      "i2so1_m_sel",
+                      "i2so2_m_sel",
+                      "i2si1_m_sel",
+                      "i2si2_m_sel",
+                      "infra_ao_audio_26m_b",
+                      "scp_adsp_audiodsp";
+    };
+
+...
-- 
2.18.0

From trevor.wu at mediatek.com  Mon Aug  9 02:48:46 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Mon, 9 Aug 2021 17:48:46 +0800
Subject: [PATCH v3 0/9] ASoC: mediatek: Add support for MT8195 SoC
Message-ID: <20210809094855.7169-1-trevor.wu@mediatek.com>

This series of patches adds support for Mediatek AFE of MT8195 SoC.
Patches are based on broonie tree "for-next" branch.

Changes since v2:
  - added audio clock gate control
  - added 'mediatek' prefix to private dts properties
  - added consumed clocks to dt-bindins and adopted suggestions from Rob
  - refined clock usage and remove unused clock and control code
  - fixed typos

Changes since v1:
  - fixed some problems related to dt-bindings
  - added some missing properties to dt-bindings
  - added depency declaration on dt-bindings
  - fixed some warnings found by kernel test robot

Trevor Wu (9):
  ASoC: mediatek: mt8195: update mediatek common driver
  ASoC: mediatek: mt8195: support audsys clock control
  ASoC: mediatek: mt8195: support etdm in platform driver
  ASoC: mediatek: mt8195: support adda in platform driver
  ASoC: mediatek: mt8195: support pcm in platform driver
  ASoC: mediatek: mt8195: add platform driver
  dt-bindings: mediatek: mt8195: add audio afe document
  ASoC: mediatek: mt8195: add machine driver with mt6359, rt1019 and
    rt5682
  dt-bindings: mediatek: mt8195: add mt8195-mt6359-rt1019-rt5682
    document

 .../bindings/sound/mt8195-afe-pcm.yaml        |  184 +
 .../sound/mt8195-mt6359-rt1019-rt5682.yaml    |   39 +
 sound/soc/mediatek/Kconfig                    |   23 +
 sound/soc/mediatek/Makefile                   |    1 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.c    |   22 +-
 sound/soc/mediatek/common/mtk-base-afe.h      |   10 +-
 sound/soc/mediatek/mt8195/Makefile            |   15 +
 sound/soc/mediatek/mt8195/mt8195-afe-clk.c    |  499 +++
 sound/soc/mediatek/mt8195/mt8195-afe-clk.h    |  113 +
 sound/soc/mediatek/mt8195/mt8195-afe-common.h |  158 +
 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c    | 3283 +++++++++++++++++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c |  217 ++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h |   15 +
 .../soc/mediatek/mt8195/mt8195-audsys-clkid.h |   93 +
 sound/soc/mediatek/mt8195/mt8195-dai-adda.c   |  830 +++++
 sound/soc/mediatek/mt8195/mt8195-dai-etdm.c   | 2652 +++++++++++++
 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c    |  389 ++
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      |  977 +++++
 sound/soc/mediatek/mt8195/mt8195-reg.h        | 2796 ++++++++++++++
 19 files changed, 12311 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
 create mode 100644 sound/soc/mediatek/mt8195/Makefile
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-common.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-adda.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-reg.h

-- 
2.18.0

From trevor.wu at mediatek.com  Mon Aug  9 02:48:48 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Mon, 9 Aug 2021 17:48:48 +0800
Subject: [PATCH v3 2/9] ASoC: mediatek: mt8195: support audsys clock control
In-Reply-To: <20210809094855.7169-1-trevor.wu@mediatek.com>
References: <20210809094855.7169-1-trevor.wu@mediatek.com>
Message-ID: <20210809094855.7169-3-trevor.wu@mediatek.com>

This patch adds mt8195 audio cg control.
Audio clock gates are registered to CCF for reference count and
clock parent management.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c | 217 ++++++++++++++++++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h |  15 ++
 .../soc/mediatek/mt8195/mt8195-audsys-clkid.h |  93 ++++++++
 3 files changed, 325 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h

diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
new file mode 100644
index 000000000000..40942239e240
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt8195-audsys-clk.h  --  Mediatek 8195 audsys clock control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include "mt8195-afe-common.h"
+#include "mt8195-audsys-clk.h"
+#include "mt8195-audsys-clkid.h"
+#include "mt8195-reg.h"
+
+struct afe_gate {
+	int id;
+	const char *name;
+	const char *parent_name;
+	int reg;
+	u8 bit;
+	const struct clk_ops *ops;
+	unsigned long flags;
+	u8 cg_flags;
+};
+
+#define GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, _flags, _cgflags) {\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.reg = _reg,					\
+		.bit = _bit,					\
+		.flags = _flags,				\
+		.cg_flags = _cgflags,				\
+	}
+
+#define GATE_AFE(_id, _name, _parent, _reg, _bit)		\
+	GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit,		\
+		       CLK_SET_RATE_PARENT, CLK_GATE_SET_TO_DISABLE)
+
+#define GATE_AUD0(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON0, _bit)
+
+#define GATE_AUD1(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON1, _bit)
+
+#define GATE_AUD3(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON3, _bit)
+
+#define GATE_AUD4(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON4, _bit)
+
+#define GATE_AUD5(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON5, _bit)
+
+#define GATE_AUD6(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON6, _bit)
+
+static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
+	/* AUD0 */
+	GATE_AUD0(CLK_AUD_AFE, "aud_afe", "a1sys_hp_sel", 2),
+	GATE_AUD0(CLK_AUD_LRCK_CNT, "aud_lrck_cnt", "a1sys_hp_sel", 4),
+	GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_APLL, "aud_spdifin_tuner_apll", "apll4_sel", 10),
+	GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_DBG, "aud_spdifin_tuner_dbg", "apll4_sel", 11),
+	GATE_AUD0(CLK_AUD_UL_TML, "aud_ul_tml", "a1sys_hp_sel", 18),
+	GATE_AUD0(CLK_AUD_APLL1_TUNER, "aud_apll1_tuner", "apll1_sel", 19),
+	GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "apll2_sel", 20),
+	GATE_AUD0(CLK_AUD_TOP0_SPDF, "aud_top0_spdf", "aud_iec_sel", 21),
+	GATE_AUD0(CLK_AUD_APLL, "aud_apll", "apll1_sel", 23),
+	GATE_AUD0(CLK_AUD_APLL2, "aud_apll2", "apll2_sel", 24),
+	GATE_AUD0(CLK_AUD_DAC, "aud_dac", "a1sys_hp_sel", 25),
+	GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "a1sys_hp_sel", 26),
+	GATE_AUD0(CLK_AUD_TML, "aud_tml", "a1sys_hp_sel", 27),
+	GATE_AUD0(CLK_AUD_ADC, "aud_adc", "a1sys_hp_sel", 28),
+	GATE_AUD0(CLK_AUD_DAC_HIRES, "aud_dac_hires", "audio_h_sel", 31),
+
+	/* AUD1 */
+	GATE_AUD1(CLK_AUD_A1SYS_HP, "aud_a1sys_hp", "a1sys_hp_sel", 2),
+	GATE_AUD1(CLK_AUD_AFE_DMIC1, "aud_afe_dmic1", "a1sys_hp_sel", 10),
+	GATE_AUD1(CLK_AUD_AFE_DMIC2, "aud_afe_dmic2", "a1sys_hp_sel", 11),
+	GATE_AUD1(CLK_AUD_AFE_DMIC3, "aud_afe_dmic3", "a1sys_hp_sel", 12),
+	GATE_AUD1(CLK_AUD_AFE_DMIC4, "aud_afe_dmic4", "a1sys_hp_sel", 13),
+	GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "a1sys_hp_sel", 14),
+	GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "audio_h_sel", 16),
+	GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "audio_h_sel", 17),
+	GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "a1sys_hp_sel", 18),
+	GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "audio_h_sel", 19),
+
+	/* AUD3 */
+	GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "apll5_sel", 5),
+	GATE_AUD3(CLK_AUD_EARC_TUNER, "aud_earc_tuner", "apll3_sel", 7),
+
+	/* AUD4 */
+	GATE_AUD4(CLK_AUD_I2SIN, "aud_i2sin", "a1sys_hp_sel", 0),
+	GATE_AUD4(CLK_AUD_TDM_IN, "aud_tdm_in", "a1sys_hp_sel", 1),
+	GATE_AUD4(CLK_AUD_I2S_OUT, "aud_i2s_out", "a1sys_hp_sel", 6),
+	GATE_AUD4(CLK_AUD_TDM_OUT, "aud_tdm_out", "a1sys_hp_sel", 7),
+	GATE_AUD4(CLK_AUD_HDMI_OUT, "aud_hdmi_out", "a1sys_hp_sel", 8),
+	GATE_AUD4(CLK_AUD_ASRC11, "aud_asrc11", "a1sys_hp_sel", 16),
+	GATE_AUD4(CLK_AUD_ASRC12, "aud_asrc12", "a1sys_hp_sel", 17),
+	GATE_AUD4(CLK_AUD_MULTI_IN, "aud_multi_in", "mphone_slave_b", 19),
+	GATE_AUD4(CLK_AUD_INTDIR, "aud_intdir", "intdir_sel", 20),
+	GATE_AUD4(CLK_AUD_A1SYS, "aud_a1sys", "a1sys_hp_sel", 21),
+	GATE_AUD4(CLK_AUD_A2SYS, "aud_a2sys", "a2sys_sel", 22),
+	GATE_AUD4(CLK_AUD_PCMIF, "aud_pcmif", "a1sys_hp_sel", 24),
+	GATE_AUD4(CLK_AUD_A3SYS, "aud_a3sys", "a3sys_sel", 30),
+	GATE_AUD4(CLK_AUD_A4SYS, "aud_a4sys", "a4sys_sel", 31),
+
+	/* AUD5 */
+	GATE_AUD5(CLK_AUD_MEMIF_UL1, "aud_memif_ul1", "a1sys_hp_sel", 0),
+	GATE_AUD5(CLK_AUD_MEMIF_UL2, "aud_memif_ul2", "a1sys_hp_sel", 1),
+	GATE_AUD5(CLK_AUD_MEMIF_UL3, "aud_memif_ul3", "a1sys_hp_sel", 2),
+	GATE_AUD5(CLK_AUD_MEMIF_UL4, "aud_memif_ul4", "a1sys_hp_sel", 3),
+	GATE_AUD5(CLK_AUD_MEMIF_UL5, "aud_memif_ul5", "a1sys_hp_sel", 4),
+	GATE_AUD5(CLK_AUD_MEMIF_UL6, "aud_memif_ul6", "a1sys_hp_sel", 5),
+	GATE_AUD5(CLK_AUD_MEMIF_UL8, "aud_memif_ul8", "a1sys_hp_sel", 7),
+	GATE_AUD5(CLK_AUD_MEMIF_UL9, "aud_memif_ul9", "a1sys_hp_sel", 8),
+	GATE_AUD5(CLK_AUD_MEMIF_UL10, "aud_memif_ul10", "a1sys_hp_sel", 9),
+	GATE_AUD5(CLK_AUD_MEMIF_DL2, "aud_memif_dl2", "a1sys_hp_sel", 18),
+	GATE_AUD5(CLK_AUD_MEMIF_DL3, "aud_memif_dl3", "a1sys_hp_sel", 19),
+	GATE_AUD5(CLK_AUD_MEMIF_DL6, "aud_memif_dl6", "a1sys_hp_sel", 22),
+	GATE_AUD5(CLK_AUD_MEMIF_DL7, "aud_memif_dl7", "a1sys_hp_sel", 23),
+	GATE_AUD5(CLK_AUD_MEMIF_DL8, "aud_memif_dl8", "a1sys_hp_sel", 24),
+	GATE_AUD5(CLK_AUD_MEMIF_DL10, "aud_memif_dl10", "a1sys_hp_sel", 26),
+	GATE_AUD5(CLK_AUD_MEMIF_DL11, "aud_memif_dl11", "a1sys_hp_sel", 27),
+
+	/* AUD6 */
+	GATE_AUD6(CLK_AUD_GASRC0, "aud_gasrc0", "asm_h_sel", 0),
+	GATE_AUD6(CLK_AUD_GASRC1, "aud_gasrc1", "asm_h_sel", 1),
+	GATE_AUD6(CLK_AUD_GASRC2, "aud_gasrc2", "asm_h_sel", 2),
+	GATE_AUD6(CLK_AUD_GASRC3, "aud_gasrc3", "asm_h_sel", 3),
+	GATE_AUD6(CLK_AUD_GASRC4, "aud_gasrc4", "asm_h_sel", 4),
+	GATE_AUD6(CLK_AUD_GASRC5, "aud_gasrc5", "asm_h_sel", 5),
+	GATE_AUD6(CLK_AUD_GASRC6, "aud_gasrc6", "asm_h_sel", 6),
+	GATE_AUD6(CLK_AUD_GASRC7, "aud_gasrc7", "asm_h_sel", 7),
+	GATE_AUD6(CLK_AUD_GASRC8, "aud_gasrc8", "asm_h_sel", 8),
+	GATE_AUD6(CLK_AUD_GASRC9, "aud_gasrc9", "asm_h_sel", 9),
+	GATE_AUD6(CLK_AUD_GASRC10, "aud_gasrc10", "asm_h_sel", 10),
+	GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "asm_h_sel", 11),
+	GATE_AUD6(CLK_AUD_GASRC12, "aud_gasrc12", "asm_h_sel", 12),
+	GATE_AUD6(CLK_AUD_GASRC13, "aud_gasrc13", "asm_h_sel", 13),
+	GATE_AUD6(CLK_AUD_GASRC14, "aud_gasrc14", "asm_h_sel", 14),
+	GATE_AUD6(CLK_AUD_GASRC15, "aud_gasrc15", "asm_h_sel", 15),
+	GATE_AUD6(CLK_AUD_GASRC16, "aud_gasrc16", "asm_h_sel", 16),
+	GATE_AUD6(CLK_AUD_GASRC17, "aud_gasrc17", "asm_h_sel", 17),
+	GATE_AUD6(CLK_AUD_GASRC18, "aud_gasrc18", "asm_h_sel", 18),
+	GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "asm_h_sel", 19),
+};
+
+int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk_onecell_data *clk_data;
+	struct clk *clk;
+	struct clk_lookup *cl;
+	int ret;
+	int i;
+
+	afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK,
+					sizeof(*afe_priv->lookup),
+					GFP_KERNEL);
+
+	if (!afe_priv->lookup)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
+		const struct afe_gate *gate = &aud_clks[i];
+
+		clk = clk_register_gate(afe->dev, gate->name, gate->parent_name,
+					gate->flags, afe->base_addr + gate->reg,
+					gate->bit, gate->cg_flags, NULL);
+
+		if (IS_ERR(clk)) {
+			dev_err(afe->dev, "Failed to register clk %s: %ld\n",
+				gate->name, PTR_ERR(clk));
+			continue;
+		}
+
+		/* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */
+		cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+		if (!cl)
+			return -ENOMEM;
+
+		cl->clk = clk;
+		cl->con_id = gate->name;
+		cl->dev_id = dev_name(afe->dev);
+		clkdev_add(cl);
+
+		afe_priv->lookup[i] = cl;
+	}
+
+	return 0;
+}
+
+void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk *clk;
+	struct clk_lookup *cl;
+	int i;
+
+	if (!afe_priv)
+		return;
+
+	for (i = 0; i < CLK_AUD_NR_CLK; i++) {
+		cl = afe_priv->lookup[i];
+		if (!cl)
+			continue;
+
+		clk = cl->clk;
+		clk_unregister_gate(clk);
+
+		clkdev_drop(cl);
+	}
+}
+
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
new file mode 100644
index 000000000000..239d31016ba7
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-audsys-clk.h  --  Mediatek 8195 audsys clock definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#ifndef _MT8195_AUDSYS_CLK_H_
+#define _MT8195_AUDSYS_CLK_H_
+
+int mt8195_audsys_clk_register(struct mtk_base_afe *afe);
+void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe);
+
+#endif
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
new file mode 100644
index 000000000000..4dd0a5c8b8fa
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-audsys-clkid.h  --  Mediatek 8195 audsys clock id definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#ifndef _MT8195_AUDSYS_CLKID_H_
+#define _MT8195_AUDSYS_CLKID_H_
+
+enum{
+	CLK_AUD_AFE,
+	CLK_AUD_LRCK_CNT,
+	CLK_AUD_SPDIFIN_TUNER_APLL,
+	CLK_AUD_SPDIFIN_TUNER_DBG,
+	CLK_AUD_UL_TML,
+	CLK_AUD_APLL1_TUNER,
+	CLK_AUD_APLL2_TUNER,
+	CLK_AUD_TOP0_SPDF,
+	CLK_AUD_APLL,
+	CLK_AUD_APLL2,
+	CLK_AUD_DAC,
+	CLK_AUD_DAC_PREDIS,
+	CLK_AUD_TML,
+	CLK_AUD_ADC,
+	CLK_AUD_DAC_HIRES,
+	CLK_AUD_A1SYS_HP,
+	CLK_AUD_AFE_DMIC1,
+	CLK_AUD_AFE_DMIC2,
+	CLK_AUD_AFE_DMIC3,
+	CLK_AUD_AFE_DMIC4,
+	CLK_AUD_AFE_26M_DMIC_TM,
+	CLK_AUD_UL_TML_HIRES,
+	CLK_AUD_ADC_HIRES,
+	CLK_AUD_ADDA6_ADC,
+	CLK_AUD_ADDA6_ADC_HIRES,
+	CLK_AUD_LINEIN_TUNER,
+	CLK_AUD_EARC_TUNER,
+	CLK_AUD_I2SIN,
+	CLK_AUD_TDM_IN,
+	CLK_AUD_I2S_OUT,
+	CLK_AUD_TDM_OUT,
+	CLK_AUD_HDMI_OUT,
+	CLK_AUD_ASRC11,
+	CLK_AUD_ASRC12,
+	CLK_AUD_MULTI_IN,
+	CLK_AUD_INTDIR,
+	CLK_AUD_A1SYS,
+	CLK_AUD_A2SYS,
+	CLK_AUD_PCMIF,
+	CLK_AUD_A3SYS,
+	CLK_AUD_A4SYS,
+	CLK_AUD_MEMIF_UL1,
+	CLK_AUD_MEMIF_UL2,
+	CLK_AUD_MEMIF_UL3,
+	CLK_AUD_MEMIF_UL4,
+	CLK_AUD_MEMIF_UL5,
+	CLK_AUD_MEMIF_UL6,
+	CLK_AUD_MEMIF_UL8,
+	CLK_AUD_MEMIF_UL9,
+	CLK_AUD_MEMIF_UL10,
+	CLK_AUD_MEMIF_DL2,
+	CLK_AUD_MEMIF_DL3,
+	CLK_AUD_MEMIF_DL6,
+	CLK_AUD_MEMIF_DL7,
+	CLK_AUD_MEMIF_DL8,
+	CLK_AUD_MEMIF_DL10,
+	CLK_AUD_MEMIF_DL11,
+	CLK_AUD_GASRC0,
+	CLK_AUD_GASRC1,
+	CLK_AUD_GASRC2,
+	CLK_AUD_GASRC3,
+	CLK_AUD_GASRC4,
+	CLK_AUD_GASRC5,
+	CLK_AUD_GASRC6,
+	CLK_AUD_GASRC7,
+	CLK_AUD_GASRC8,
+	CLK_AUD_GASRC9,
+	CLK_AUD_GASRC10,
+	CLK_AUD_GASRC11,
+	CLK_AUD_GASRC12,
+	CLK_AUD_GASRC13,
+	CLK_AUD_GASRC14,
+	CLK_AUD_GASRC15,
+	CLK_AUD_GASRC16,
+	CLK_AUD_GASRC17,
+	CLK_AUD_GASRC18,
+	CLK_AUD_GASRC19,
+	CLK_AUD_NR_CLK,
+};
+
+#endif
-- 
2.18.0

From trevor.wu at mediatek.com  Mon Aug  9 02:48:50 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Mon, 9 Aug 2021 17:48:50 +0800
Subject: [PATCH v3 4/9] ASoC: mediatek: mt8195: support adda in platform driver
In-Reply-To: <20210809094855.7169-1-trevor.wu@mediatek.com>
References: <20210809094855.7169-1-trevor.wu@mediatek.com>
Message-ID: <20210809094855.7169-5-trevor.wu@mediatek.com>

This patch adds mt8195 adda dai driver.

audio_h clock is used by ADSP bus and ADDA module.
When ADDA requires audio_h clock, it is switched to APLL1, otherwise
it is switched to Xtal_26m so that APLL1 can be turned off when audio
feature is not used.
ADSP bus only requires that the clock is on, so dynamic reparenting
is used for the purpose of lowering power consumption.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-dai-adda.c | 830 ++++++++++++++++++++
 1 file changed, 830 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-adda.c

diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-adda.c b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
new file mode 100644
index 000000000000..878dec0b69ed
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI ADDA Control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai at mediatek.com>
+ *         Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+#define ADDA_DL_GAIN_LOOPBACK 0x1800
+#define ADDA_HIRES_THRES 48000
+
+enum {
+	SUPPLY_SEQ_CLOCK_SEL,
+	SUPPLY_SEQ_CLOCK_ON,
+	SUPPLY_SEQ_ADDA_DL_ON,
+	SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+	SUPPLY_SEQ_ADDA_UL_ON,
+	SUPPLY_SEQ_ADDA_AFE_ON,
+};
+
+enum {
+	MTK_AFE_ADDA_DL_RATE_8K = 0,
+	MTK_AFE_ADDA_DL_RATE_11K = 1,
+	MTK_AFE_ADDA_DL_RATE_12K = 2,
+	MTK_AFE_ADDA_DL_RATE_16K = 3,
+	MTK_AFE_ADDA_DL_RATE_22K = 4,
+	MTK_AFE_ADDA_DL_RATE_24K = 5,
+	MTK_AFE_ADDA_DL_RATE_32K = 6,
+	MTK_AFE_ADDA_DL_RATE_44K = 7,
+	MTK_AFE_ADDA_DL_RATE_48K = 8,
+	MTK_AFE_ADDA_DL_RATE_96K = 9,
+	MTK_AFE_ADDA_DL_RATE_192K = 10,
+};
+
+enum {
+	MTK_AFE_ADDA_UL_RATE_8K = 0,
+	MTK_AFE_ADDA_UL_RATE_16K = 1,
+	MTK_AFE_ADDA_UL_RATE_32K = 2,
+	MTK_AFE_ADDA_UL_RATE_48K = 3,
+	MTK_AFE_ADDA_UL_RATE_96K = 4,
+	MTK_AFE_ADDA_UL_RATE_192K = 5,
+};
+
+enum {
+	DELAY_DATA_MISO1 = 0,
+	DELAY_DATA_MISO0 = 1,
+	DELAY_DATA_MISO2 = 1,
+};
+
+enum {
+	MTK_AFE_ADDA,
+	MTK_AFE_ADDA6,
+};
+
+struct mtk_dai_adda_priv {
+	bool hires_required;
+};
+
+static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
+					       unsigned int rate)
+{
+	switch (rate) {
+	case 8000:
+		return MTK_AFE_ADDA_DL_RATE_8K;
+	case 11025:
+		return MTK_AFE_ADDA_DL_RATE_11K;
+	case 12000:
+		return MTK_AFE_ADDA_DL_RATE_12K;
+	case 16000:
+		return MTK_AFE_ADDA_DL_RATE_16K;
+	case 22050:
+		return MTK_AFE_ADDA_DL_RATE_22K;
+	case 24000:
+		return MTK_AFE_ADDA_DL_RATE_24K;
+	case 32000:
+		return MTK_AFE_ADDA_DL_RATE_32K;
+	case 44100:
+		return MTK_AFE_ADDA_DL_RATE_44K;
+	case 48000:
+		return MTK_AFE_ADDA_DL_RATE_48K;
+	case 96000:
+		return MTK_AFE_ADDA_DL_RATE_96K;
+	case 192000:
+		return MTK_AFE_ADDA_DL_RATE_192K;
+	default:
+		dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+			 __func__, rate);
+		return MTK_AFE_ADDA_DL_RATE_48K;
+	}
+}
+
+static unsigned int afe_adda_ul_rate_transform(struct mtk_base_afe *afe,
+					       unsigned int rate)
+{
+	switch (rate) {
+	case 8000:
+		return MTK_AFE_ADDA_UL_RATE_8K;
+	case 16000:
+		return MTK_AFE_ADDA_UL_RATE_16K;
+	case 32000:
+		return MTK_AFE_ADDA_UL_RATE_32K;
+	case 48000:
+		return MTK_AFE_ADDA_UL_RATE_48K;
+	case 96000:
+		return MTK_AFE_ADDA_UL_RATE_96K;
+	case 192000:
+		return MTK_AFE_ADDA_UL_RATE_192K;
+	default:
+		dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+			 __func__, rate);
+		return MTK_AFE_ADDA_UL_RATE_48K;
+	}
+}
+
+static int mt8195_adda_mtkaif_init(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int delay_data;
+	int delay_cycle;
+	unsigned int mask = 0;
+	unsigned int val = 0;
+
+	/* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
+	mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+	val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+
+	regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask, val);
+	regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, mask, val);
+
+	mask = RG_RX_PROTOCOL2;
+	val = RG_RX_PROTOCOL2;
+	regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val);
+
+	if (!param->mtkaif_calibration_ok) {
+		dev_info(afe->dev, "%s(), calibration fail\n",  __func__);
+		return 0;
+	}
+
+	/* set delay for ch1, ch2 */
+	if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] >=
+	    param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {
+		delay_data = DELAY_DATA_MISO1;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];
+	} else {
+		delay_data = DELAY_DATA_MISO0;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0];
+	}
+
+	val = 0;
+	mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+	val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+	       MTKAIF_RXIF_DELAY_CYCLE_MASK;
+	val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+	regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
+
+	/* set delay between ch3 and ch2 */
+	if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] >=
+	    param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {
+		delay_data = DELAY_DATA_MISO1;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];
+	} else {
+		delay_data = DELAY_DATA_MISO2;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2];
+	}
+
+	val = 0;
+	mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+	val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+	       MTKAIF_RXIF_DELAY_CYCLE_MASK;
+	val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+	regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG2, mask, val);
+
+	return 0;
+}
+
+static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
+				     struct snd_kcontrol *kcontrol,
+				     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8195_adda_mtkaif_init(afe);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, int adda, bool dmic)
+{
+	unsigned int reg = 0;
+	unsigned int mask = 0;
+	unsigned int val = 0;
+
+	switch (adda) {
+	case MTK_AFE_ADDA:
+		reg = AFE_ADDA_UL_SRC_CON0;
+		break;
+	case MTK_AFE_ADDA6:
+		reg = AFE_ADDA6_UL_SRC_CON0;
+		break;
+	default:
+		dev_info(afe->dev, "%s(), wrong parameter\n",  __func__);
+		return;
+	}
+
+	mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
+		UL_MODE_3P25M_CH2_CTL);
+
+	/* turn on dmic, ch1, ch2 */
+	if (dmic)
+		val = mask;
+
+	regmap_update_bits(afe->regmap, reg, mask, val);
+}
+
+static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_adda_ul_mictype(afe, MTK_AFE_ADDA, param->mtkaif_dmic_on);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_adda6_ul_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol,
+			      int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	unsigned int val;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_adda_ul_mictype(afe, MTK_AFE_ADDA6, param->mtkaif_dmic_on);
+
+		val = (param->mtkaif_adda6_only ?
+			ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE : 0);
+
+		regmap_update_bits(afe->regmap,
+				   AFE_ADDA_MTKAIF_SYNCWORD_CFG,
+				   ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE,
+				   val);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk *clk = afe_priv->clk[MT8195_CLK_TOP_AUDIO_H_SEL];
+	struct clk *clk_parent;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		clk_parent = afe_priv->clk[MT8195_CLK_TOP_APLL1];
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		clk_parent = afe_priv->clk[MT8195_CLK_XTAL_26M];
+		break;
+	default:
+		return 0;
+	}
+	mt8195_afe_set_clk_parent(afe, clk, clk_parent);
+
+	return 0;
+}
+
+static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
+						       const char *name)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	int dai_id;
+
+	if (strstr(name, "aud_adc_hires"))
+		dai_id = MT8195_AFE_IO_UL_SRC1;
+	else if (strstr(name, "aud_adda6_adc_hires"))
+		dai_id = MT8195_AFE_IO_UL_SRC2;
+	else if (strstr(name, "aud_dac_hires"))
+		dai_id = MT8195_AFE_IO_DL_SRC;
+	else
+		return NULL;
+
+	return afe_priv->dai_priv[dai_id];
+}
+
+static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
+				      struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = source;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_adda_priv *adda_priv;
+
+	adda_priv = get_adda_priv_by_name(afe, w->name);
+
+	if (!adda_priv) {
+		dev_info(afe->dev, "adda_priv == NULL");
+		return 0;
+	}
+
+	return (adda_priv->hires_required) ? 1 : 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),
+};
+
+static const char * const adda_dlgain_mux_map[] = {
+	"Bypass", "Connect",
+};
+
+static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,
+			    SND_SOC_NOPM, 0,
+			    adda_dlgain_mux_map);
+
+static const struct snd_kcontrol_new adda_dlgain_mux_control =
+	SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);
+
+static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
+	SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I170", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I171", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_adda_o176_mix,
+			   ARRAY_SIZE(mtk_dai_adda_o176_mix)),
+	SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_adda_o177_mix,
+			   ARRAY_SIZE(mtk_dai_adda_o177_mix)),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
+			      AFE_ADDA_UL_DL_CON0,
+			      ADDA_AFE_ON_SHIFT, 0,
+			      NULL,
+			      0),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
+			      AFE_ADDA_DL_SRC2_CON0,
+			      DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,
+			      mtk_adda_dl_event,
+			      SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+			      AFE_ADDA_UL_SRC_CON0,
+			      UL_SRC_ON_TMP_CTL_SHIFT, 0,
+			      mtk_adda_ul_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA6 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+			      AFE_ADDA6_UL_SRC_CON0,
+			      UL_SRC_ON_TMP_CTL_SHIFT, 0,
+			      mtk_adda6_ul_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,
+			      SND_SOC_NOPM,
+			      0, 0,
+			      mtk_audio_hires_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+			      SND_SOC_NOPM,
+			      0, 0,
+			      mtk_adda_mtkaif_cfg_event,
+			      SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,
+			 &adda_dlgain_mux_control),
+
+	SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,
+			 DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),
+
+	SND_SOC_DAPM_INPUT("ADDA_INPUT"),
+	SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),
+
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc_hires"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
+	{"ADDA Capture", NULL, "ADDA Enable"},
+	{"ADDA Capture", NULL, "ADDA Capture Enable"},
+	{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
+	{"ADDA Capture", NULL, "aud_adc"},
+	{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
+	{"aud_adc_hires", NULL, "AUDIO_HIRES"},
+
+	{"ADDA6 Capture", NULL, "ADDA Enable"},
+	{"ADDA6 Capture", NULL, "ADDA6 Capture Enable"},
+	{"ADDA6 Capture", NULL, "ADDA_MTKAIF_CFG"},
+	{"ADDA6 Capture", NULL, "aud_adda6_adc"},
+	{"ADDA6 Capture", NULL, "aud_adda6_adc_hires",
+	mtk_afe_adda_hires_connect},
+	{"aud_adda6_adc_hires", NULL, "AUDIO_HIRES"},
+
+	{"I168", NULL, "ADDA Capture"},
+	{"I169", NULL, "ADDA Capture"},
+	{"I170", NULL, "ADDA6 Capture"},
+	{"I171", NULL, "ADDA6 Capture"},
+
+	{"ADDA Playback", NULL, "ADDA Enable"},
+	{"ADDA Playback", NULL, "ADDA Playback Enable"},
+	{"ADDA Playback", NULL, "aud_dac"},
+	{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
+	{"aud_dac_hires", NULL, "AUDIO_HIRES"},
+
+	{"DL_GAIN", NULL, "O176"},
+	{"DL_GAIN", NULL, "O177"},
+
+	{"DL_GAIN_MUX", "Bypass", "O176"},
+	{"DL_GAIN_MUX", "Bypass", "O177"},
+	{"DL_GAIN_MUX", "Connect", "DL_GAIN"},
+
+	{"ADDA Playback", NULL, "DL_GAIN_MUX"},
+
+	{"O176", "I000 Switch", "I000"},
+	{"O177", "I001 Switch", "I001"},
+
+	{"O176", "I002 Switch", "I002"},
+	{"O177", "I003 Switch", "I003"},
+
+	{"O176", "I020 Switch", "I020"},
+	{"O177", "I021 Switch", "I021"},
+
+	{"O176", "I022 Switch", "I022"},
+	{"O177", "I023 Switch", "I023"},
+
+	{"O176", "I070 Switch", "I070"},
+	{"O177", "I071 Switch", "I071"},
+
+	{"ADDA Capture", NULL, "ADDA_INPUT"},
+	{"ADDA6 Capture", NULL, "ADDA_INPUT"},
+	{"ADDA_OUTPUT", NULL, "ADDA Playback"},
+};
+
+static int mt8195_adda_dl_gain_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+	unsigned int reg = AFE_ADDA_DL_SRC2_CON1;
+	unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;
+	unsigned int value = (unsigned int)(ucontrol->value.integer.value[0]);
+
+	regmap_update_bits(afe->regmap, reg, mask, DL_2_GAIN_CTL_PRE(value));
+	return 0;
+}
+
+static int mt8195_adda_dl_gain_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+	unsigned int reg = AFE_ADDA_DL_SRC2_CON1;
+	unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;
+	unsigned int value = 0;
+
+	regmap_read(afe->regmap, reg, &value);
+
+	ucontrol->value.integer.value[0] = ((value & mask) >>
+					    DL_2_GAIN_CTL_PRE_SHIFT);
+	return 0;
+}
+
+static int mt8195_adda6_only_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	ucontrol->value.integer.value[0] = param->mtkaif_adda6_only;
+	return 0;
+}
+
+static int mt8195_adda6_only_set(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int mtkaif_adda6_only;
+
+	mtkaif_adda6_only = ucontrol->value.integer.value[0];
+
+	dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n",
+		 __func__, kcontrol->id.name, mtkaif_adda6_only);
+
+	param->mtkaif_adda6_only = mtkaif_adda6_only;
+
+	return 0;
+}
+
+static int mt8195_adda_dmic_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;
+	return 0;
+}
+
+static int mt8195_adda_dmic_set(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int dmic_on;
+
+	dmic_on = ucontrol->value.integer.value[0];
+
+	dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
+		__func__, kcontrol->id.name, dmic_on);
+
+	param->mtkaif_dmic_on = dmic_on;
+	return 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_controls[] = {
+	SOC_SINGLE_EXT("ADDA_DL_Gain", SND_SOC_NOPM, 0, 65535, 0,
+		       mt8195_adda_dl_gain_get, mt8195_adda_dl_gain_put),
+	SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC", 0,
+			    mt8195_adda_dmic_get, mt8195_adda_dmic_set),
+	SOC_SINGLE_BOOL_EXT("MTKAIF_ADDA6_ONLY", 0,
+			    mt8195_adda6_only_get,
+			    mt8195_adda6_only_set),
+};
+
+static int mtk_dai_da_configure(struct mtk_base_afe *afe,
+				unsigned int rate, int id)
+{
+	unsigned int val = 0;
+	unsigned int mask = 0;
+
+	/* set sampling rate */
+	mask |= DL_2_INPUT_MODE_CTL_MASK;
+	val |= DL_2_INPUT_MODE_CTL(afe_adda_dl_rate_transform(afe, rate));
+
+	/* turn off saturation */
+	mask |= DL_2_CH1_SATURATION_EN_CTL;
+	mask |= DL_2_CH2_SATURATION_EN_CTL;
+
+	/* turn off mute function */
+	mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+	mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+	val |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+	val |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+
+	/* set voice input data if input sample rate is 8k or 16k */
+	mask |= DL_2_VOICE_MODE_CTL_PRE;
+	if (rate == 8000 || rate == 16000)
+		val |= DL_2_VOICE_MODE_CTL_PRE;
+
+	regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);
+
+	mask = 0;
+	val = 0;
+
+	/* new 2nd sdm */
+	mask |= DL_USE_NEW_2ND_SDM;
+	val |= DL_USE_NEW_2ND_SDM;
+	regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, mask, val);
+
+	return 0;
+}
+
+static int mtk_dai_ad_configure(struct mtk_base_afe *afe,
+				unsigned int rate, int id)
+{
+	unsigned int val = 0;
+	unsigned int mask = 0;
+
+	mask |= UL_VOICE_MODE_CTL_MASK;
+	val |= UL_VOICE_MODE_CTL(afe_adda_ul_rate_transform(afe, rate));
+
+	switch (id) {
+	case MT8195_AFE_IO_UL_SRC1:
+		regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
+				   mask, val);
+		break;
+	case MT8195_AFE_IO_UL_SRC2:
+		regmap_update_bits(afe->regmap, AFE_ADDA6_UL_SRC_CON0,
+				   mask, val);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id];
+	unsigned int rate = params_rate(params);
+	int id = dai->id;
+	int ret = 0;
+
+	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
+		__func__, id, substream->stream, rate);
+
+	if (rate > ADDA_HIRES_THRES)
+		adda_priv->hires_required = 1;
+	else
+		adda_priv->hires_required = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ret = mtk_dai_da_configure(afe, rate, id);
+	else
+		ret = mtk_dai_ad_configure(afe, rate, id);
+
+	return ret;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
+	.hw_params = mtk_dai_adda_hw_params,
+};
+
+/* dai driver */
+#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
+				 SNDRV_PCM_RATE_96000 |\
+				 SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
+				SNDRV_PCM_RATE_16000 |\
+				SNDRV_PCM_RATE_32000 |\
+				SNDRV_PCM_RATE_48000 |\
+				SNDRV_PCM_RATE_96000 |\
+				SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+			  SNDRV_PCM_FMTBIT_S24_LE |\
+			  SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
+	{
+		.name = "DL_SRC",
+		.id = MT8195_AFE_IO_DL_SRC,
+		.playback = {
+			.stream_name = "ADDA Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_PLAYBACK_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+	{
+		.name = "UL_SRC1",
+		.id = MT8195_AFE_IO_UL_SRC1,
+		.capture = {
+			.stream_name = "ADDA Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_CAPTURE_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+	{
+		.name = "UL_SRC2",
+		.id = MT8195_AFE_IO_UL_SRC2,
+		.capture = {
+			.stream_name = "ADDA6 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_CAPTURE_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+};
+
+static int init_adda_priv_data(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_adda_priv *adda_priv;
+	int adda_dai_list[] = { MT8195_AFE_IO_DL_SRC,
+				MT8195_AFE_IO_UL_SRC1,
+				MT8195_AFE_IO_UL_SRC2};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
+		adda_priv = devm_kzalloc(afe->dev,
+					 sizeof(struct mtk_dai_adda_priv),
+					 GFP_KERNEL);
+		if (!adda_priv)
+			return -ENOMEM;
+
+		afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
+	}
+
+	return 0;
+}
+
+int mt8195_dai_adda_register(struct mtk_base_afe *afe)
+{
+	struct mtk_base_afe_dai *dai;
+
+	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+
+	list_add(&dai->list, &afe->sub_dais);
+
+	dai->dai_drivers = mtk_dai_adda_driver;
+	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
+
+	dai->dapm_widgets = mtk_dai_adda_widgets;
+	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
+	dai->dapm_routes = mtk_dai_adda_routes;
+	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
+	dai->controls = mtk_dai_adda_controls;
+	dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);
+
+	return init_adda_priv_data(afe);
+}
-- 
2.18.0

From trevor.wu at mediatek.com  Mon Aug  9 02:48:54 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Mon, 9 Aug 2021 17:48:54 +0800
Subject: [PATCH v3 8/9] ASoC: mediatek: mt8195: add machine driver with mt6359,
 rt1019 and rt5682
In-Reply-To: <20210809094855.7169-1-trevor.wu@mediatek.com>
References: <20210809094855.7169-1-trevor.wu@mediatek.com>
Message-ID: <20210809094855.7169-9-trevor.wu@mediatek.com>

This patch adds support for mt8195 board with mt6359, rt1019 and rt5682.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 sound/soc/mediatek/Kconfig                    |  14 +
 sound/soc/mediatek/mt8195/Makefile            |   3 +
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 977 ++++++++++++++++++
 3 files changed, 994 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 3389f382be06..bfee954d0c7c 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -193,3 +193,17 @@ config SND_SOC_MT8195
 	  that can be used with other codecs.
 	  Select Y if you have such device.
 	  If unsure select "N".
+
+config SND_SOC_MT8195_MT6359_RT1019_RT5682
+	tristate "ASoC Audio driver for MT8195 with MT6359 RT1019 RT5682 codec"
+	depends on I2C
+	depends on SND_SOC_MT8195
+	select SND_SOC_MT6359
+	select SND_SOC_RT1015P
+	select SND_SOC_RT5682_I2C
+	select SND_SOC_DMIC
+	help
+	  This adds ASoC driver for Mediatek MT8195 boards
+	  with the MT6359 RT1019 RT5682 audio codec.
+	  Select Y if you have such device.
+	  If unsure select "N".
diff --git a/sound/soc/mediatek/mt8195/Makefile b/sound/soc/mediatek/mt8195/Makefile
index 6529dd5beb2b..44775f400b40 100644
--- a/sound/soc/mediatek/mt8195/Makefile
+++ b/sound/soc/mediatek/mt8195/Makefile
@@ -10,3 +10,6 @@ snd-soc-mt8195-afe-objs := \
 	mt8195-dai-pcm.o
 
 obj-$(CONFIG_SND_SOC_MT8195) += snd-soc-mt8195-afe.o
+
+# machine driver
+obj-$(CONFIG_SND_SOC_MT8195_MT6359_RT1019_RT5682) += mt8195-mt6359-rt1019-rt5682.o
diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
new file mode 100644
index 000000000000..39b33aecc1e9
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
@@ -0,0 +1,977 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// mt8195-mt6359-rt1019-rt5682.c  --
+//	MT8195-MT6359-RT1019-RT6358 ALSA SoC machine driver
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Trevor Wu <trevor.wu at mediatek.com>
+//
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/rt5682.h>
+#include <sound/soc.h>
+#include "../../codecs/mt6359.h"
+#include "../../codecs/rt5682.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "mt8195-afe-common.h"
+
+#define RT1019_CODEC_DAI	"HiFi"
+#define RT1019_DEV0_NAME	"rt1019p"
+
+#define RT5682_CODEC_DAI	"rt5682-aif1"
+#define RT5682_DEV0_NAME	"rt5682.2-001a"
+
+struct mt8195_mt6359_rt1019_rt5682_priv {
+	struct snd_soc_jack headset_jack;
+};
+
+static const struct snd_soc_dapm_widget
+	mt8195_mt6359_rt1019_rt5682_widgets[] = {
+	SND_SOC_DAPM_SPK("Speakers", NULL),
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = {
+	/* speaker */
+	{ "Speakers", NULL, "Speaker" },
+	/* headset */
+	{ "Headphone Jack", NULL, "HPOL" },
+	{ "Headphone Jack", NULL, "HPOR" },
+	{ "IN1P", NULL, "Headset Mic" },
+};
+
+static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Speakers"),
+	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+	unsigned int rate = params_rate(params);
+	unsigned int mclk_fs_ratio = 128;
+	unsigned int mclk_fs = rate * mclk_fs_ratio;
+	int bitwidth;
+	int ret;
+
+	bitwidth = snd_pcm_format_width(params_format(params));
+	if (bitwidth < 0) {
+		dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
+		return bitwidth;
+	}
+
+	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
+	if (ret) {
+		dev_err(card->dev, "failed to set tdm slot\n");
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
+				  RT5682_PLL1_S_BCLK1,
+				  params_rate(params) * 64,
+				  params_rate(params) * 512);
+	if (ret) {
+		dev_err(card->dev, "failed to set pll\n");
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(codec_dai,
+				     RT5682_SCLK_S_PLL1,
+				     params_rate(params) * 512,
+				     SND_SOC_CLOCK_IN);
+	if (ret) {
+		dev_err(card->dev, "failed to set sysclk\n");
+		return ret;
+	}
+
+	return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
+}
+
+static const struct snd_soc_ops mt8195_rt5682_etdm_ops = {
+	.hw_params = mt8195_rt5682_etdm_hw_params,
+};
+
+#define CKSYS_AUD_TOP_CFG 0x032c
+#define CKSYS_AUD_TOP_MON 0x0330
+
+static int mt8195_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_afe =
+		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int phase;
+	unsigned int monitor;
+	int mtkaif_calibration_num_phase;
+	int test_done_1, test_done_2, test_done_3;
+	int cycle_1, cycle_2, cycle_3;
+	int prev_cycle_1, prev_cycle_2, prev_cycle_3;
+	int chosen_phase_1, chosen_phase_2, chosen_phase_3;
+	int counter;
+	bool mtkaif_calibration_ok;
+	int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM];
+	int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM];
+	int i;
+
+	dev_info(afe->dev, "%s(), start\n", __func__);
+
+	param->mtkaif_calibration_ok = false;
+	for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) {
+		param->mtkaif_chosen_phase[i] = -1;
+		param->mtkaif_phase_cycle[i] = 0;
+		mtkaif_chosen_phase[i] = -1;
+		mtkaif_phase_cycle[i] = 0;
+	}
+
+	if (IS_ERR(afe_priv->topckgen)) {
+		dev_info(afe->dev, "%s() Cannot find topckgen controller\n",
+			 __func__);
+		return 0;
+	}
+
+	pm_runtime_get_sync(afe->dev);
+	mt6359_mtkaif_calibration_enable(cmpnt_codec);
+
+	/* set test type to synchronizer pulse */
+	regmap_update_bits(afe_priv->topckgen,
+			   CKSYS_AUD_TOP_CFG, 0xffff, 0x4);
+	mtkaif_calibration_num_phase = 42;	/* mt6359: 0 ~ 42 */
+	mtkaif_calibration_ok = true;
+
+	for (phase = 0;
+	     phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok;
+	     phase++) {
+		mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+						    phase, phase, phase);
+
+		regmap_update_bits(afe_priv->topckgen,
+				   CKSYS_AUD_TOP_CFG, 0x1, 0x1);
+
+		test_done_1 = 0;
+		test_done_2 = 0;
+		test_done_3 = 0;
+		cycle_1 = -1;
+		cycle_2 = -1;
+		cycle_3 = -1;
+		counter = 0;
+		while (!(test_done_1 & test_done_2 & test_done_3)) {
+			regmap_read(afe_priv->topckgen,
+				    CKSYS_AUD_TOP_MON, &monitor);
+			test_done_1 = (monitor >> 28) & 0x1;
+			test_done_2 = (monitor >> 29) & 0x1;
+			test_done_3 = (monitor >> 30) & 0x1;
+			if (test_done_1 == 1)
+				cycle_1 = monitor & 0xf;
+
+			if (test_done_2 == 1)
+				cycle_2 = (monitor >> 4) & 0xf;
+
+			if (test_done_3 == 1)
+				cycle_3 = (monitor >> 8) & 0xf;
+
+			/* handle if never test done */
+			if (++counter > 10000) {
+				dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n",
+					 __func__,
+					 cycle_1, cycle_2, cycle_3, monitor);
+				mtkaif_calibration_ok = false;
+				break;
+			}
+		}
+
+		if (phase == 0) {
+			prev_cycle_1 = cycle_1;
+			prev_cycle_2 = cycle_2;
+			prev_cycle_3 = cycle_3;
+		}
+
+		if (cycle_1 != prev_cycle_1 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1;
+		}
+
+		if (cycle_2 != prev_cycle_2 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2;
+		}
+
+		if (cycle_3 != prev_cycle_3 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3;
+		}
+
+		regmap_update_bits(afe_priv->topckgen,
+				   CKSYS_AUD_TOP_CFG, 0x1, 0x0);
+
+		if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0)
+			break;
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_1 = 0;
+	} else {
+		chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0];
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_2 = 0;
+	} else {
+		chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1];
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_3 = 0;
+	} else {
+		chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2];
+	}
+
+	mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+					    chosen_phase_1,
+					    chosen_phase_2,
+					    chosen_phase_3);
+
+	mt6359_mtkaif_calibration_disable(cmpnt_codec);
+	pm_runtime_put(afe->dev);
+
+	param->mtkaif_calibration_ok = mtkaif_calibration_ok;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3;
+	for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++)
+		param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];
+
+	dev_info(afe->dev, "%s(), end, calibration ok %d\n",
+		 __func__, param->mtkaif_calibration_ok);
+
+	return 0;
+}
+
+static int mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+
+	/* set mtkaif protocol */
+	mt6359_set_mtkaif_protocol(cmpnt_codec,
+				   MT6359_MTKAIF_PROTOCOL_2_CLK_P2);
+
+	/* mtkaif calibration */
+	mt8195_mt6359_mtkaif_calibration(rtd);
+
+	return 0;
+}
+
+static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+		snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_jack *jack = &priv->headset_jack;
+	int ret;
+
+	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
+				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
+				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
+				    SND_JACK_BTN_3,
+				    jack, NULL, 0);
+	if (ret) {
+		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+		return ret;
+	}
+
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+	ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
+	if (ret) {
+		dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+};
+
+static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				       struct snd_pcm_hw_params *params)
+{
+	/* fix BE i2s format to 32bit, clean param mask first */
+	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
+
+	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+	return 0;
+}
+
+static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+	unsigned int rate = params_rate(params);
+	unsigned int mclk_fs_ratio = 256;
+	unsigned int mclk_fs = rate * mclk_fs_ratio;
+
+	return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs,
+				      SND_SOC_CLOCK_OUT);
+}
+
+static struct snd_soc_ops mt8195_dptx_ops = {
+	.hw_params = mt8195_dptx_hw_params,
+};
+
+static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				       struct snd_pcm_hw_params *params)
+{
+	/* fix BE i2s format to 32bit, clean param mask first */
+	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
+
+	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+	return 0;
+}
+
+static int mt8195_playback_startup(struct snd_pcm_substream *substream)
+{
+	static const unsigned int rates[] = {
+		48000
+	};
+	static const unsigned int channels[] = {
+		2
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list  = rates,
+		.mask = 0,
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list  = channels,
+		.mask = 0,
+	};
+
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_rates);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+		return ret;
+	}
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_CHANNELS,
+					 &constraints_channels);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops mt8195_playback_ops = {
+	.startup = mt8195_playback_startup,
+};
+
+static int mt8195_capture_startup(struct snd_pcm_substream *substream)
+{
+	static const unsigned int rates[] = {
+		48000
+	};
+	static const unsigned int channels[] = {
+		1, 2
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list  = rates,
+		.mask = 0,
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list  = channels,
+		.mask = 0,
+	};
+
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_rates);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+		return ret;
+	}
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_CHANNELS,
+					 &constraints_channels);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops mt8195_capture_ops = {
+	.startup = mt8195_capture_startup,
+};
+
+enum {
+	DAI_LINK_DL2_FE,
+	DAI_LINK_DL3_FE,
+	DAI_LINK_DL6_FE,
+	DAI_LINK_DL7_FE,
+	DAI_LINK_DL8_FE,
+	DAI_LINK_DL10_FE,
+	DAI_LINK_DL11_FE,
+	DAI_LINK_UL1_FE,
+	DAI_LINK_UL2_FE,
+	DAI_LINK_UL3_FE,
+	DAI_LINK_UL4_FE,
+	DAI_LINK_UL5_FE,
+	DAI_LINK_UL6_FE,
+	DAI_LINK_UL8_FE,
+	DAI_LINK_UL9_FE,
+	DAI_LINK_UL10_FE,
+	DAI_LINK_DL_SRC_BE,
+	DAI_LINK_DPTX_BE,
+	DAI_LINK_ETDM1_IN_BE,
+	DAI_LINK_ETDM2_IN_BE,
+	DAI_LINK_ETDM1_OUT_BE,
+	DAI_LINK_ETDM2_OUT_BE,
+	DAI_LINK_ETDM3_OUT_BE,
+	DAI_LINK_PCM1_BE,
+	DAI_LINK_UL_SRC1_BE,
+	DAI_LINK_UL_SRC2_BE,
+};
+
+/* FE */
+SND_SOC_DAILINK_DEFS(DL2_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL3_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL6_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL7_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL8_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL10_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL10")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL11_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL11")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL1_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL2_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL3_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL4_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL5_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL6_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL8_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL8")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL9_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL9")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL10_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL10")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+/* BE */
+SND_SOC_DAILINK_DEFS(DL_SRC_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif1")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DPTX_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM1_IN_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM2_IN_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME,
+						   RT5682_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME,
+						   RT5682_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME,
+						   RT1019_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(PCM1_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL_SRC1_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif1"),
+					COMP_CODEC("dmic-codec",
+						   "dmic-hifi")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL_SRC2_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif2")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
+	/* FE */
+	[DAI_LINK_DL2_FE] = {
+		.name = "DL2_FE",
+		.stream_name = "DL2 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL2_FE),
+	},
+	[DAI_LINK_DL3_FE] = {
+		.name = "DL3_FE",
+		.stream_name = "DL3 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL3_FE),
+	},
+	[DAI_LINK_DL6_FE] = {
+		.name = "DL6_FE",
+		.stream_name = "DL6 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL6_FE),
+	},
+	[DAI_LINK_DL7_FE] = {
+		.name = "DL7_FE",
+		.stream_name = "DL7 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL7_FE),
+	},
+	[DAI_LINK_DL8_FE] = {
+		.name = "DL8_FE",
+		.stream_name = "DL8 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL8_FE),
+	},
+	[DAI_LINK_DL10_FE] = {
+		.name = "DL10_FE",
+		.stream_name = "DL10 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL10_FE),
+	},
+	[DAI_LINK_DL11_FE] = {
+		.name = "DL11_FE",
+		.stream_name = "DL11 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL11_FE),
+	},
+	[DAI_LINK_UL1_FE] = {
+		.name = "UL1_FE",
+		.stream_name = "UL1 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL1_FE),
+	},
+	[DAI_LINK_UL2_FE] = {
+		.name = "UL2_FE",
+		.stream_name = "UL2 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL2_FE),
+	},
+	[DAI_LINK_UL3_FE] = {
+		.name = "UL3_FE",
+		.stream_name = "UL3 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL3_FE),
+	},
+	[DAI_LINK_UL4_FE] = {
+		.name = "UL4_FE",
+		.stream_name = "UL4 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL4_FE),
+	},
+	[DAI_LINK_UL5_FE] = {
+		.name = "UL5_FE",
+		.stream_name = "UL5 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL5_FE),
+	},
+	[DAI_LINK_UL6_FE] = {
+		.name = "UL6_FE",
+		.stream_name = "UL6 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL6_FE),
+	},
+	[DAI_LINK_UL8_FE] = {
+		.name = "UL8_FE",
+		.stream_name = "UL8 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL8_FE),
+	},
+	[DAI_LINK_UL9_FE] = {
+		.name = "UL9_FE",
+		.stream_name = "UL9 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL9_FE),
+	},
+	[DAI_LINK_UL10_FE] = {
+		.name = "UL10_FE",
+		.stream_name = "UL10 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL10_FE),
+	},
+	/* BE */
+	[DAI_LINK_DL_SRC_BE] = {
+		.name = "DL_SRC_BE",
+		.init = mt8195_mt6359_init,
+		.no_pcm = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL_SRC_BE),
+	},
+	[DAI_LINK_DPTX_BE] = {
+		.name = "DPTX_BE",
+		.no_pcm = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_dptx_ops,
+		.be_hw_params_fixup = mt8195_dptx_hw_params_fixup,
+		SND_SOC_DAILINK_REG(DPTX_BE),
+	},
+	[DAI_LINK_ETDM1_IN_BE] = {
+		.name = "ETDM1_IN_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(ETDM1_IN_BE),
+	},
+	[DAI_LINK_ETDM2_IN_BE] = {
+		.name = "ETDM2_IN_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		.init = mt8195_rt5682_init,
+		.ops = &mt8195_rt5682_etdm_ops,
+		.be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
+		SND_SOC_DAILINK_REG(ETDM2_IN_BE),
+	},
+	[DAI_LINK_ETDM1_OUT_BE] = {
+		.name = "ETDM1_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		.ops = &mt8195_rt5682_etdm_ops,
+		.be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
+		SND_SOC_DAILINK_REG(ETDM1_OUT_BE),
+	},
+	[DAI_LINK_ETDM2_OUT_BE] = {
+		.name = "ETDM2_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(ETDM2_OUT_BE),
+	},
+	[DAI_LINK_ETDM3_OUT_BE] = {
+		.name = "ETDM3_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(ETDM3_OUT_BE),
+	},
+	[DAI_LINK_PCM1_BE] = {
+		.name = "PCM1_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(PCM1_BE),
+	},
+	[DAI_LINK_UL_SRC1_BE] = {
+		.name = "UL_SRC1_BE",
+		.no_pcm = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL_SRC1_BE),
+	},
+	[DAI_LINK_UL_SRC2_BE] = {
+		.name = "UL_SRC2_BE",
+		.no_pcm = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL_SRC2_BE),
+	},
+};
+
+static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = {
+	.name = "mt8195_r1019_5682",
+	.owner = THIS_MODULE,
+	.dai_link = mt8195_mt6359_rt1019_rt5682_dai_links,
+	.num_links = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links),
+	.controls = mt8195_mt6359_rt1019_rt5682_controls,
+	.num_controls = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_controls),
+	.dapm_widgets = mt8195_mt6359_rt1019_rt5682_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets),
+	.dapm_routes = mt8195_mt6359_rt1019_rt5682_routes,
+	.num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes),
+};
+
+static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = &mt8195_mt6359_rt1019_rt5682_soc_card;
+	struct device_node *platform_node;
+	struct snd_soc_dai_link *dai_link;
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL;
+
+	int ret, i;
+
+	card->dev = &pdev->dev;
+
+	platform_node = of_parse_phandle(pdev->dev.of_node,
+					 "mediatek,platform", 0);
+	if (!platform_node) {
+		dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n");
+		return -EINVAL;
+	}
+
+	for_each_card_prelinks(card, i, dai_link) {
+		if (!dai_link->platforms->name)
+			dai_link->platforms->of_node = platform_node;
+	}
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	snd_soc_card_set_drvdata(card, priv);
+
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+	if (ret)
+		dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+			__func__, ret);
+	return ret;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id mt8195_mt6359_rt1019_rt5682_dt_match[] = {
+	{.compatible = "mediatek,mt8195_mt6359_rt1019_rt5682",},
+	{}
+};
+#endif
+
+static const struct dev_pm_ops mt8195_mt6359_rt1019_rt5682_pm_ops = {
+	.poweroff = snd_soc_poweroff,
+	.restore = snd_soc_resume,
+};
+
+static struct platform_driver mt8195_mt6359_rt1019_rt5682_driver = {
+	.driver = {
+		.name = "mt8195_mt6359_rt1019_rt5682",
+#ifdef CONFIG_OF
+		.of_match_table = mt8195_mt6359_rt1019_rt5682_dt_match,
+#endif
+		.pm = &mt8195_mt6359_rt1019_rt5682_pm_ops,
+	},
+	.probe = mt8195_mt6359_rt1019_rt5682_dev_probe,
+};
+
+module_platform_driver(mt8195_mt6359_rt1019_rt5682_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("MT8195-MT6359-RT1019-RT5682 ALSA SoC machine driver");
+MODULE_AUTHOR("Trevor Wu <trevor.wu at mediatek.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("mt8195_mt6359_rt1019_rt5682 soc card");
-- 
2.18.0

From trevor.wu at mediatek.com  Mon Aug  9 02:48:55 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Mon, 9 Aug 2021 17:48:55 +0800
Subject: [PATCH v3 9/9] dt-bindings: mediatek: mt8195: add
 mt8195-mt6359-rt1019-rt5682 document
In-Reply-To: <20210809094855.7169-1-trevor.wu@mediatek.com>
References: <20210809094855.7169-1-trevor.wu@mediatek.com>
Message-ID: <20210809094855.7169-10-trevor.wu@mediatek.com>

This patch adds document for mt8195 board with mt6359, rt1019 and rt5682

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 .../sound/mt8195-mt6359-rt1019-rt5682.yaml    | 39 +++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml

diff --git a/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
new file mode 100644
index 000000000000..246c0875e64e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1019-rt5682.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT8195 with MT6359, RT1019 and RT5682 ASoC sound card driver
+
+maintainers:
+  - Trevor Wu <trevor.wu at mediatek.com>
+
+description:
+  This binding describes the MT8195 sound card.
+
+properties:
+  compatible:
+    const: mediatek,mt8195_mt6359_rt1019_rt5682
+
+  mediatek,platform:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of MT8195 ASoC platform.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - mediatek,platform
+
+examples:
+  - |
+
+    sound: mt8195-sound {
+        compatible = "mediatek,mt8195_mt6359_rt1019_rt5682";
+        mediatek,platform = <&afe>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&aud_pins_default>;
+    };
+
+...
-- 
2.18.0

From sneeli at xilinx.com  Mon Aug  9 03:05:33 2021
From: sneeli at xilinx.com (Srinivas Neeli)
Date: Mon, 9 Aug 2021 10:05:33 +0000
Subject: [PATCH] rtc: zynqmp: Add calibration set and get support
In-Reply-To: <20210714080809.34289-1-srinivas.neeli@xilinx.com>
References: <20210714080809.34289-1-srinivas.neeli@xilinx.com>
Message-ID: <DM6PR02MB53863D113E167A4C789201EAAFF69@DM6PR02MB5386.namprd02.prod.outlook.com>

Hi,

Is this patch fine?

Thanks
Srinivas Neeli

> -----Original Message-----
> From: Srinivas Neeli <srinivas.neeli at xilinx.com>
> Sent: Wednesday, July 14, 2021 1:38 PM
> To: a.zummo at towertech.it; alexandre.belloni at bootlin.com; Michal Simek
> <michals at xilinx.com>; Srinivas Goud <sgoud at xilinx.com>; Shubhrajyoti
> Datta <shubhraj at xilinx.com>
> Cc: linux-rtc at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; git <git at xilinx.com>; Srinivas Neeli
> <sneeli at xilinx.com>
> Subject: [PATCH] rtc: zynqmp: Add calibration set and get support
> 
> Zynqmp RTC controller has a calibration feature to compensate time
> deviation due to input clock inaccuracy.
> Set and get calibration API's are used for setting and getting calibration value
> from the controller calibration register.
> 
> Signed-off-by: Srinivas Neeli <srinivas.neeli at xilinx.com>
> ---
>  drivers/rtc/rtc-zynqmp.c | 101 ++++++++++++++++++++++++++++++++----
> ---
>  1 file changed, 84 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index
> f440bb52be92..718f60d42760 100644
> --- a/drivers/rtc/rtc-zynqmp.c
> +++ b/drivers/rtc/rtc-zynqmp.c
> @@ -36,10 +36,16 @@
>  #define RTC_OSC_EN		BIT(24)
>  #define RTC_BATT_EN		BIT(31)
> 
> -#define RTC_CALIB_DEF		0x198233
> +#define RTC_CALIB_DEF		0x8000
>  #define RTC_CALIB_MASK		0x1FFFFF
>  #define RTC_ALRM_MASK          BIT(1)
>  #define RTC_MSEC               1000
> +#define RTC_FR_MASK		0xF0000
> +#define RTC_SEC_MAX_VAL		0xFFFFFFFF
> +#define RTC_FR_MAX_TICKS	16
> +#define RTC_OFFSET_MAX		150000
> +#define RTC_OFFSET_MIN		-150000
> +#define RTC_PPB			1000000000LL
> 
>  struct xlnx_rtc_dev {
>  	struct rtc_device	*rtc;
> @@ -61,13 +67,6 @@ static int xlnx_rtc_set_time(struct device *dev, struct
> rtc_time *tm)
>  	 */
>  	new_time = rtc_tm_to_time64(tm) + 1;
> 
> -	/*
> -	 * Writing into calibration register will clear the Tick Counter and
> -	 * force the next second to be signaled exactly in 1 second period
> -	 */
> -	xrtcdev->calibval &= RTC_CALIB_MASK;
> -	writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> -
>  	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
> 
>  	/*
> @@ -174,14 +173,76 @@ static void xlnx_init_rtc(struct xlnx_rtc_dev
> *xrtcdev)
>  	rtc_ctrl |= RTC_BATT_EN;
>  	writel(rtc_ctrl, xrtcdev->reg_base + RTC_CTRL);
> 
> -	/*
> -	 * Based on crystal freq of 33.330 KHz
> -	 * set the seconds counter and enable, set fractions counter
> -	 * to default value suggested as per design spec
> -	 * to correct RTC delay in frequency over period of time.
> +	/* Update calibvalue */
> +	xrtcdev->calibval = readl(xrtcdev->reg_base + RTC_CALIB_RD); }
> +
> +static int xlnx_rtc_read_offset(struct device *dev, long *offset) {
> +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +	long offset_val = 0;
> +	unsigned int tick_mult = RTC_PPB / (xrtcdev->calibval &
> +RTC_TICK_MASK);
> +
> +	/* Offset with seconds ticks */
> +	offset_val = xrtcdev->calibval & RTC_TICK_MASK;
> +	offset_val = offset_val - RTC_CALIB_DEF;
> +	offset_val = offset_val * tick_mult;
> +
> +	/* Offset with fractional ticks */
> +	if (xrtcdev->calibval & RTC_FR_EN)
> +		offset_val += ((xrtcdev->calibval & RTC_FR_MASK) >>
> RTC_FR_DATSHIFT)
> +			* (tick_mult / RTC_FR_MAX_TICKS);
> +	*offset = offset_val;
> +
> +	return 0;
> +}
> +
> +static int xlnx_rtc_set_offset(struct device *dev, long offset) {
> +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +	short int  max_tick;
> +	unsigned char fract_tick = 0;
> +	unsigned int calibval;
> +	int fract_offset;
> +	unsigned int tick_mult = RTC_PPB / (xrtcdev->calibval &
> +RTC_TICK_MASK);
> +
> +	/* Make sure offset value is within supported range */
> +	if (offset < RTC_OFFSET_MIN || offset > RTC_OFFSET_MAX)
> +		return -ERANGE;
> +
> +	/* Number ticks for given offset */
> +	max_tick = div_s64_rem(offset, tick_mult, &fract_offset);
> +
> +	/* Number fractional ticks for given offset */
> +	if (fract_offset) {
> +		if (fract_offset < 0) {
> +			fract_offset = fract_offset + tick_mult;
> +			max_tick--;
> +		}
> +		if (fract_offset > (tick_mult / RTC_FR_MAX_TICKS)) {
> +			for (fract_tick = 1; fract_tick < 16; fract_tick++) {
> +				if (fract_offset <=
> +				    (fract_tick *
> +				     (tick_mult / RTC_FR_MAX_TICKS)))
> +					break;
> +			}
> +		}
> +	}
> +
> +	/* Zynqmp RTC uses second and fractional tick
> +	 * counters for compensation
>  	 */
> -	xrtcdev->calibval &= RTC_CALIB_MASK;
> -	writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> +	calibval = max_tick + RTC_CALIB_DEF;
> +
> +	if (fract_tick)
> +		calibval |= RTC_FR_EN;
> +
> +	calibval |= (fract_tick << RTC_FR_DATSHIFT);
> +
> +	writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> +	xrtcdev->calibval = calibval;
> +
> +	return 0;
>  }
> 
>  static const struct rtc_class_ops xlnx_rtc_ops = { @@ -190,6 +251,8 @@
> static const struct rtc_class_ops xlnx_rtc_ops = {
>  	.read_alarm	  = xlnx_rtc_read_alarm,
>  	.set_alarm	  = xlnx_rtc_set_alarm,
>  	.alarm_irq_enable = xlnx_rtc_alarm_irq_enable,
> +	.read_offset	  = xlnx_rtc_read_offset,
> +	.set_offset	  = xlnx_rtc_set_offset,
>  };
> 
>  static irqreturn_t xlnx_rtc_interrupt(int irq, void *id) @@ -215,6 +278,7 @@
> static int xlnx_rtc_probe(struct platform_device *pdev)  {
>  	struct xlnx_rtc_dev *xrtcdev;
>  	int ret;
> +	unsigned int calibval;
> 
>  	xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev),
> GFP_KERNEL);
>  	if (!xrtcdev)
> @@ -256,9 +320,12 @@ static int xlnx_rtc_probe(struct platform_device
> *pdev)
>  	}
> 
>  	ret = of_property_read_u32(pdev->dev.of_node, "calibration",
> -				   &xrtcdev->calibval);
> +				   &calibval);
>  	if (ret)
> -		xrtcdev->calibval = RTC_CALIB_DEF;
> +		calibval = RTC_CALIB_DEF;
> +	ret = readl(xrtcdev->reg_base + RTC_CALIB_RD);
> +	if (!ret)
> +		writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> 
>  	xlnx_init_rtc(xrtcdev);
> 
> --
> 2.31.1



From balbi at kernel.org  Mon Aug  9 03:07:39 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Mon, 09 Aug 2021 13:07:39 +0300
Subject: [PATCH 3/9] usb: gadget: udc: at91: add IRQ check
In-Reply-To: <3ebcf6ee-4ca7-d7dc-6e04-62bc4f9e1ead@omp.ru>
References: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
 <3ebcf6ee-4ca7-d7dc-6e04-62bc4f9e1ead@omp.ru>
Message-ID: <8735rjkk16.fsf@kernel.org>


Sergey Shtylyov <s.shtylyov at omp.ru> writes:

> The driver neglects to check the result of platform_get_irq()'s call and
> blithely passes the negative error codes to devm_request_irq() (which takes
> *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
> error code. Stop calling devm_request_irq() with the invalid IRQ #s.
>
> Fixes: 8b2e76687b39 ("USB: AT91 UDC updates, mostly power management")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>
>
> ---
>  drivers/usb/gadget/udc/at91_udc.c |    4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> Index: usb/drivers/usb/gadget/udc/at91_udc.c
> ===================================================================
> --- usb.orig/drivers/usb/gadget/udc/at91_udc.c
> +++ usb/drivers/usb/gadget/udc/at91_udc.c
> @@ -1876,7 +1876,9 @@ static int at91udc_probe(struct platform
>  	clk_disable(udc->iclk);
>  
>  	/* request UDC and maybe VBUS irqs */
> -	udc->udp_irq = platform_get_irq(pdev, 0);
> +	udc->udp_irq = retval = platform_get_irq(pdev, 0);
> +	if (retval < 0)
> +		goto err_unprepare_iclk;

let's avoid multiple assignments in one line. How about:

	if (udc->udp_irq < 0) {
        	retval = udc->udp_irq;
                goto err_unprepare_iclk;
        }

-- 
balbi


From balbi at kernel.org  Mon Aug  9 03:08:43 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Mon, 09 Aug 2021 13:08:43 +0300
Subject: [PATCH 1/9] usb: dwc3: meson-g12a: add IRQ check
In-Reply-To: <f8eae1ec-91c7-e26e-665d-777930b001a9@omp.ru>
References: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
 <f8eae1ec-91c7-e26e-665d-777930b001a9@omp.ru>
Message-ID: <87zgtrj5fq.fsf@kernel.org>


Sergey Shtylyov <s.shtylyov at omp.ru> writes:

> The driver neglects to check the result of platform_get_irq()'s call and
> blithely passes the negative error codes to devm_request_threaded_irq()
> (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding
> an original error code. Stop calling devm_request_threaded_irq() with the
> invalid IRQ #s.
>
> Fixes: f90db10779ad ("usb: dwc3: meson-g12a: Add support for IRQ based OTG switching")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

Acked-by: Felipe Balbi <balbi at kernel.org>


-- 
balbi


From balbi at kernel.org  Mon Aug  9 03:09:07 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Mon, 09 Aug 2021 13:09:07 +0300
Subject: [PATCH 4/9] usb: gadget: udc: s3c2410: add IRQ check
In-Reply-To: <f704a632-a970-fe8d-35e7-f4d032c670c7@omp.ru>
References: <717ddd7c-22cd-d82c-e43d-80254718c801@omp.ru>
 <f704a632-a970-fe8d-35e7-f4d032c670c7@omp.ru>
Message-ID: <87wnovj5ey.fsf@kernel.org>


Sergey Shtylyov <s.shtylyov at omp.ru> writes:

> The driver neglects to check the result of platform_get_irq()'s call and
> blithely passes the negative error codes to devm_request_irq() (which takes
> *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
> error code. Stop calling devm_request_irq() with the invalid IRQ #s.
>
> Fixes: 8b2e76687b39 ("USB: AT91 UDC updates, mostly power management")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

Acked-by: Felipe Balbi <balbi at kernel.org>

-- 
balbi


From vee.khee.wong at linux.intel.com  Mon Aug  9 03:22:27 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Mon,  9 Aug 2021 18:22:27 +0800
Subject: [PATCH net-next 0/2] Intel AlderLake-S 2.5Gbps link speed support 
Message-ID: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>

This patch series add 2.5Gbps support for Intel AlderLake-S platform.

Beside register 2.5G callback function in the dwmac_intel driver, an
additional step to not perform xPCS soft reset on driver init is also
required.

Michael Sit Wei Hong (2):
  net: pcs: xpcs: enable skip xPCS soft reset
  stmmac: intel: Enable 2.5Gbps on Intel AlderLake-S

 drivers/net/dsa/sja1105/sja1105_mdio.c           |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c    |  4 ++++
 .../net/ethernet/stmicro/stmmac/stmmac_mdio.c    |  4 +++-
 drivers/net/pcs/pcs-xpcs.c                       | 16 ++++++++++++----
 include/linux/pcs/pcs-xpcs.h                     |  3 ++-
 include/linux/stmmac.h                           |  1 +
 6 files changed, 23 insertions(+), 7 deletions(-)

-- 
2.25.1



From vee.khee.wong at linux.intel.com  Mon Aug  9 03:22:28 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Mon,  9 Aug 2021 18:22:28 +0800
Subject: [PATCH net-next 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
Message-ID: <20210809102229.933748-2-vee.khee.wong@linux.intel.com>

From: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>

Unlike any other platforms, Intel AlderLake-S uses Synopsys SerDes where
all the SerDes PLL configurations are controlled by the xPCS at the BIOS
level. If the driver perform a xPCS soft reset on initialization, these
settings will be switched back to the power on reset values.

This changes the xpcs_create function to take in an additional argument
to check if the platform request to skip xPCS soft reset during device
initialization.

Cc: Vladimir Oltean <vladimir.oltean at nxp.com>
Signed-off-by: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>
Signed-off-by: Wong Vee Khee <vee.khee.wong at linux.intel.com>
---
 drivers/net/dsa/sja1105/sja1105_mdio.c           |  2 +-
 .../net/ethernet/stmicro/stmmac/stmmac_mdio.c    |  4 +++-
 drivers/net/pcs/pcs-xpcs.c                       | 16 ++++++++++++----
 include/linux/pcs/pcs-xpcs.h                     |  3 ++-
 include/linux/stmmac.h                           |  1 +
 5 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
index 19aea8fb76f6..73b43a5da68a 100644
--- a/drivers/net/dsa/sja1105/sja1105_mdio.c
+++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
@@ -437,7 +437,7 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
 			goto out_pcs_free;
 		}
 
-		xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
+		xpcs = xpcs_create(mdiodev, priv->phy_mode[port], false);
 		if (IS_ERR(xpcs)) {
 			rc = PTR_ERR(xpcs);
 			goto out_pcs_free;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index a5d150c5f3d8..803a4e61105b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -401,12 +401,14 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
 {
 	struct net_device *ndev = bus->priv;
 	struct mdio_device *mdiodev;
+	bool skip_xpcs_soft_reset;
 	struct stmmac_priv *priv;
 	struct dw_xpcs *xpcs;
 	int mode, addr;
 
 	priv = netdev_priv(ndev);
 	mode = priv->plat->phy_interface;
+	skip_xpcs_soft_reset = priv->plat->skip_xpcs_soft_reset;
 
 	/* Try to probe the XPCS by scanning all addresses. */
 	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
@@ -414,7 +416,7 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
 		if (IS_ERR(mdiodev))
 			continue;
 
-		xpcs = xpcs_create(mdiodev, mode);
+		xpcs = xpcs_create(mdiodev, mode, skip_xpcs_soft_reset);
 		if (IS_ERR_OR_NULL(xpcs)) {
 			mdio_device_free(mdiodev);
 			continue;
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 63fda3fc40aa..c7a3aa862079 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1081,7 +1081,8 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = {
 };
 
 struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-			    phy_interface_t interface)
+			    phy_interface_t interface,
+			    bool skip_reset)
 {
 	struct dw_xpcs *xpcs;
 	u32 xpcs_id;
@@ -1113,9 +1114,16 @@ struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
 		xpcs->pcs.ops = &xpcs_phylink_ops;
 		xpcs->pcs.poll = true;
 
-		ret = xpcs_soft_reset(xpcs, compat);
-		if (ret)
-			goto out;
+		if (!skip_reset) {
+			dev_info(&xpcs->mdiodev->dev, "%s: xPCS soft reset\n",
+				 __func__);
+			ret = xpcs_soft_reset(xpcs, compat);
+			if (ret)
+				goto out;
+		} else {
+			dev_info(&xpcs->mdiodev->dev,
+				 "%s: skip xpcs soft reset\n", __func__);
+		}
 
 		return xpcs;
 	}
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index add077a81b21..0c05a63f3446 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -36,7 +36,8 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
 struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-			    phy_interface_t interface);
+			    phy_interface_t interface,
+			    bool xpcs_reset);
 void xpcs_destroy(struct dw_xpcs *xpcs);
 
 #endif /* __LINUX_PCS_XPCS_H */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..0f901773c5e4 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -268,5 +268,6 @@ struct plat_stmmacenet_data {
 	int msi_rx_base_vec;
 	int msi_tx_base_vec;
 	bool use_phy_wol;
+	bool skip_xpcs_soft_reset;
 };
 #endif
-- 
2.25.1



From vee.khee.wong at linux.intel.com  Mon Aug  9 03:22:29 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Mon,  9 Aug 2021 18:22:29 +0800
Subject: [PATCH net-next 2/2] stmmac: intel: Enable 2.5Gbps on Intel
 AlderLake-S
In-Reply-To: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
Message-ID: <20210809102229.933748-3-vee.khee.wong@linux.intel.com>

From: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>

Intel AlderLake-S platform is capable of 2.5Gbps link speed.

This patch enables the 2.5Gbps link speed by adding the callback
function in the AlderLake-S PCI info struct.

Signed-off-by: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>
Signed-off-by: Wong Vee Khee <vee.khee.wong at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 8e8778cfbbad..c1db7e53e78f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -770,6 +770,8 @@ static int adls_sgmii_phy0_data(struct pci_dev *pdev,
 {
 	plat->bus_id = 1;
 	plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+	plat->speed_mode_2500 = intel_speed_mode_2500;
+	plat->skip_xpcs_soft_reset = 1;
 
 	/* SerDes power up and power down are done in BIOS for ADL */
 
@@ -785,6 +787,8 @@ static int adls_sgmii_phy1_data(struct pci_dev *pdev,
 {
 	plat->bus_id = 2;
 	plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+	plat->speed_mode_2500 = intel_speed_mode_2500;
+	plat->skip_xpcs_soft_reset = 1;
 
 	/* SerDes power up and power down are done in BIOS for ADL */
 
-- 
2.25.1



From krzysztof.kozlowski at canonical.com  Mon Aug  9 03:38:13 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 12:38:13 +0200
Subject: [PATCH] arm64: dts: exynos: correct GIC CPU interfaces address
 range on Exynos7
In-Reply-To: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
References: <20210805072110.4730-1-krzysztof.kozlowski@canonical.com>
Message-ID: <162850548977.33781.16424242900051733609.b4-ty@canonical.com>

On Thu, 5 Aug 2021 09:21:10 +0200, Krzysztof Kozlowski wrote:
> The GIC-400 CPU interfaces address range is defined as 0x2000-0x3FFF (by
> ARM).

Applied, thanks!

[1/1] arm64: dts: exynos: correct GIC CPU interfaces address range on Exynos7
      commit: 01c72cad790cb6cd3ccbe4c1402b6cb6c6bbffd0

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Mon Aug  9 03:43:34 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 9 Aug 2021 12:43:34 +0200
Subject: [PATCH v2 2/8] pinctrl: samsung: Add Exynos850 SoC specific data
In-Reply-To: <20210806152146.16107-3-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-3-semen.protsenko@linaro.org>
Message-ID: <407ee65f-6004-5173-9fcc-99023c85db4e@canonical.com>

On 06/08/2021 17:21, Sam Protsenko wrote:
> Add Samsung Exynos850 SoC specific data to enable pinctrl support for
> all platforms based on Exynos850.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v2:
>   - Removed .suspend/.resume callbacks, as retention registers are not
>     implemented yet for Exynos850
>   - Removed .eint_gpio_init for AUD domain, as there are no external
>     interrupts available for that domain
> 
>  .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 116 ++++++++++++++++++
>  drivers/pinctrl/samsung/pinctrl-exynos.h      |  29 +++++
>  drivers/pinctrl/samsung/pinctrl-samsung.c     |   2 +
>  drivers/pinctrl/samsung/pinctrl-samsung.h     |   1 +
>  4 files changed, 148 insertions(+)
> 
> diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> index b6e56422a700..3157bdf0233c 100644
> --- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> +++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> @@ -40,6 +40,24 @@ static const struct samsung_pin_bank_type exynos5433_bank_type_alive = {
>  	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
>  };
>  
> +/*
> + * Bank type for non-alive type. Bit fields:
> + * CON: 4, DAT: 1, PUD: 4, DRV: 4, CONPDN: 2, PUDPDN: 4
> + */
> +static struct samsung_pin_bank_type exynos850_bank_type_off  = {
> +	.fld_width = { 4, 1, 4, 4, 2, 4, },
> +	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
> +};
> +
> +/*
> + * Bank type for alive type. Bit fields:
> + * CON: 4, DAT: 1, PUD: 4, DRV: 4
> + */
> +static struct samsung_pin_bank_type exynos850_bank_type_alive = {

I missed that part last time - this and one before should be const.

> +	.fld_width = { 4, 1, 4, 4, },
> +	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
> +};
> +
>  /* Pad retention control code for accessing PMU regmap */
>  static atomic_t exynos_shared_retention_refcnt;
>  
> @@ -422,3 +440,101 @@ const struct samsung_pinctrl_of_match_data exynos7_of_data __initconst = {
>  	.ctrl		= exynos7_pin_ctrl,
>  	.num_ctrl	= ARRAY_SIZE(exynos7_pin_ctrl),
>  };
> +
> +/* pin banks of exynos850 pin-controller 0 (ALIVE) */
> +static struct samsung_pin_bank_data exynos850_pin_banks0[] = {

All these as well - initconst - unless they are somehow different than
rest of such structures?

> +	/* Must start with EINTG banks, ordered by EINT group number. */
> +	EXYNOS9_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
> +	EXYNOS9_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
> +	EXYNOS9_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
> +	EXYNOS9_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
> +	EXYNOS9_PIN_BANK_EINTW(4, 0x080, "gpa4", 0x10),
> +	EXYNOS9_PIN_BANK_EINTN(3, 0x0A0, "gpq0"),
> +};
> +
> +/* pin banks of exynos850 pin-controller 1 (CMGP) */
> +static struct samsung_pin_bank_data exynos850_pin_banks1[] = {
> +	/* Must start with EINTG banks, ordered by EINT group number. */
> +	EXYNOS9_PIN_BANK_EINTW(1, 0x000, "gpm0", 0x00),
> +	EXYNOS9_PIN_BANK_EINTW(1, 0x020, "gpm1", 0x04),
> +	EXYNOS9_PIN_BANK_EINTW(1, 0x040, "gpm2", 0x08),
> +	EXYNOS9_PIN_BANK_EINTW(1, 0x060, "gpm3", 0x0C),
> +	EXYNOS9_PIN_BANK_EINTW(1, 0x080, "gpm4", 0x10),
> +	EXYNOS9_PIN_BANK_EINTW(1, 0x0A0, "gpm5", 0x14),
> +	EXYNOS9_PIN_BANK_EINTW(1, 0x0C0, "gpm6", 0x18),
> +	EXYNOS9_PIN_BANK_EINTW(1, 0x0E0, "gpm7", 0x1C),
> +};
> +
> +/* pin banks of exynos850 pin-controller 2 (AUD) */
> +static struct samsung_pin_bank_data exynos850_pin_banks2[] = {
> +	/* Must start with EINTG banks, ordered by EINT group number. */
> +	EXYNOS9_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00),
> +	EXYNOS9_PIN_BANK_EINTG(5, 0x020, "gpb1", 0x04),
> +};
> +
> +/* pin banks of exynos850 pin-controller 3 (HSI) */
> +static struct samsung_pin_bank_data exynos850_pin_banks3[] = {
> +	/* Must start with EINTG banks, ordered by EINT group number. */
> +	EXYNOS9_PIN_BANK_EINTG(6, 0x000, "gpf2", 0x00),
> +};
> +
> +/* pin banks of exynos850 pin-controller 4 (CORE) */
> +static struct samsung_pin_bank_data exynos850_pin_banks4[] = {
> +	/* Must start with EINTG banks, ordered by EINT group number. */
> +	EXYNOS9_PIN_BANK_EINTG(4, 0x000, "gpf0", 0x00),
> +	EXYNOS9_PIN_BANK_EINTG(8, 0x020, "gpf1", 0x04),
> +};
> +
> +/* pin banks of exynos850 pin-controller 5 (PERI) */
> +static struct samsung_pin_bank_data exynos850_pin_banks5[] = {
> +	/* Must start with EINTG banks, ordered by EINT group number. */
> +	EXYNOS9_PIN_BANK_EINTG(2, 0x000, "gpg0", 0x00),
> +	EXYNOS9_PIN_BANK_EINTG(6, 0x020, "gpp0", 0x04),
> +	EXYNOS9_PIN_BANK_EINTG(4, 0x040, "gpp1", 0x08),
> +	EXYNOS9_PIN_BANK_EINTG(4, 0x060, "gpp2", 0x0C),
> +	EXYNOS9_PIN_BANK_EINTG(8, 0x080, "gpg1", 0x10),
> +	EXYNOS9_PIN_BANK_EINTG(8, 0x0A0, "gpg2", 0x14),
> +	EXYNOS9_PIN_BANK_EINTG(1, 0x0C0, "gpg3", 0x18),
> +	EXYNOS9_PIN_BANK_EINTG(3, 0x0E0, "gpc0", 0x1C),
> +	EXYNOS9_PIN_BANK_EINTG(6, 0x100, "gpc1", 0x20),
> +};
> +
> +static const struct samsung_pin_ctrl exynos850_pin_ctrl[] __initconst = {
> +	{
> +		/* pin-controller instance 0 ALIVE data */
> +		.pin_banks	= exynos850_pin_banks0,
> +		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks0),
> +		.eint_gpio_init = exynos_eint_gpio_init,
> +		.eint_wkup_init = exynos_eint_wkup_init,
> +	}, {
> +		/* pin-controller instance 1 CMGP data */
> +		.pin_banks	= exynos850_pin_banks1,
> +		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks1),
> +		.eint_gpio_init = exynos_eint_gpio_init,
> +		.eint_wkup_init = exynos_eint_wkup_init,
> +	}, {
> +		/* pin-controller instance 2 AUD data */
> +		.pin_banks	= exynos850_pin_banks2,
> +		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks2),
> +	}, {
> +		/* pin-controller instance 3 HSI data */
> +		.pin_banks	= exynos850_pin_banks3,
> +		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks3),
> +		.eint_gpio_init = exynos_eint_gpio_init,
> +	}, {
> +		/* pin-controller instance 4 CORE data */
> +		.pin_banks	= exynos850_pin_banks4,
> +		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks4),
> +		.eint_gpio_init = exynos_eint_gpio_init,
> +	}, {
> +		/* pin-controller instance 5 PERI data */
> +		.pin_banks	= exynos850_pin_banks5,
> +		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks5),
> +		.eint_gpio_init = exynos_eint_gpio_init,
> +	},
> +};
> +
> +const struct samsung_pinctrl_of_match_data exynos850_of_data __initconst = {
> +	.ctrl		= exynos850_pin_ctrl,
> +	.num_ctrl	= ARRAY_SIZE(exynos850_pin_ctrl),
> +};
> diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
> index da1ec13697e7..595086f2d5dd 100644
> --- a/drivers/pinctrl/samsung/pinctrl-exynos.h
> +++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
> @@ -108,6 +108,35 @@
>  		.pctl_res_idx   = pctl_idx,			\
>  	}							\
>  
> +#define EXYNOS9_PIN_BANK_EINTN(pins, reg, id)			\
> +	{							\
> +		.type		= &exynos850_bank_type_alive,	\

Having the prefix EXYNOS9 is actually confusing because:
1. There is no Exynos9 support,
2. The type is exynos850.

Let's keep it consistent, so 850 everywhere,

> +		.pctl_offset	= reg,				\
> +		.nr_pins	= pins,				\
> +		.eint_type	= EINT_TYPE_NONE,		\
> +		.name		= id				\
> +	}
> +
> +#define EXYNOS9_PIN_BANK_EINTG(pins, reg, id, offs)		\
> +	{							\
> +		.type		= &exynos850_bank_type_off,	\
> +		.pctl_offset	= reg,				\
> +		.nr_pins	= pins,				\
> +		.eint_type	= EINT_TYPE_GPIO,		\
> +		.eint_offset	= offs,				\
> +		.name		= id				\
> +	}
> +
> +#define EXYNOS9_PIN_BANK_EINTW(pins, reg, id, offs)		\
> +	{							\
> +		.type		= &exynos850_bank_type_alive,	\
> +		.pctl_offset	= reg,				\
> +		.nr_pins	= pins,				\
> +		.eint_type	= EINT_TYPE_WKUP,		\
> +		.eint_offset	= offs,				\
> +		.name		= id				\
> +	}
> +

Best regards,
Krzysztof


From uwe at kleine-koenig.org  Mon Aug  9 03:43:51 2021
From: uwe at kleine-koenig.org (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Mon,  9 Aug 2021 12:43:51 +0200
Subject: [PATCH] ARM: oxnas: Add basic support for Zyxel NSA210
Message-ID: <20210809104351.2050187-1-uwe@kleine-koenig.org>

This is a one bay NAS originally shipping Linux 2.6.24.4. It features

 - 128 MiB RAM
 - 2x eSATA (1x internal, 1x external)
 - 2x USB 2.0
 - 4 MiB NOR
 - battery powered RTC on i2c (PCF8563)
 - 1x GBit ethernet

For now only the low-hanging fruits are added to the device tree, eSATA,
USB, i2c and networking needs more work as there are no drivers
available.

Such a machine was offered to me by Richard Fr?hning. Thanks!

Signed-off-by: Uwe Kleine-K?nig <uwe at kleine-koenig.org>
---
 .../devicetree/bindings/arm/oxnas.txt         |   1 +
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/ox810se-zyxel-nsa210.dts    | 156 ++++++++++++++++++
 3 files changed, 158 insertions(+)
 create mode 100644 arch/arm/boot/dts/ox810se-zyxel-nsa210.dts

diff --git a/Documentation/devicetree/bindings/arm/oxnas.txt b/Documentation/devicetree/bindings/arm/oxnas.txt
index ac64e60f99f1..c1529d6c9666 100644
--- a/Documentation/devicetree/bindings/arm/oxnas.txt
+++ b/Documentation/devicetree/bindings/arm/oxnas.txt
@@ -11,4 +11,5 @@ Boards with the OX820 SoC shall have the following properties:
 
 Board compatible values:
   - "wd,mbwe" (OX810SE)
+  - "zyxel,nsa210" (OX810SE)
   - "cloudengines,pogoplugv3" (OX820)
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 863347b6b65e..720b7d7e342a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -913,6 +913,7 @@ dtb-$(CONFIG_ARCH_PXA) += \
 	pxa300-raumfeld-speaker-s.dtb
 dtb-$(CONFIG_ARCH_OXNAS) += \
 	ox810se-wd-mbwe.dtb \
+	ox810se-zyxel-nsa210.dtb \
 	ox820-cloudengines-pogoplug-series-3.dtb
 dtb-$(CONFIG_ARCH_QCOM) += \
 	qcom-apq8060-dragonboard.dtb \
diff --git a/arch/arm/boot/dts/ox810se-zyxel-nsa210.dts b/arch/arm/boot/dts/ox810se-zyxel-nsa210.dts
new file mode 100644
index 000000000000..88d0e065cf99
--- /dev/null
+++ b/arch/arm/boot/dts/ox810se-zyxel-nsa210.dts
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Device tree file for Zyxel NSA-210
+ */
+
+/dts-v1/;
+#include "ox810se.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	model = "Zyxel NSA-210";
+
+	compatible = "zyxel,nsa210", "oxsemi,ox810se";
+
+	chosen {
+		bootargs = "console=ttyS2,115200n8";
+	};
+
+	memory {
+		reg = <0x48000000 0x8000000>;
+	};
+
+	aliases {
+		serial2 = &uart2;
+	};
+
+	flash at 41000000 {
+		compatible = "cfi-flash";
+		reg = <0x41000000 0x00400000>;
+		bank-width = <1>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partitions at 0 {
+				label = "uboot";
+				reg = <0x00000000 0x00020000>;
+			};
+
+			partitions at 1 {
+				label = "kernel";
+				reg = <0x00020000 0x001c0000>;
+			};
+
+			partitions at 2 {
+				label = "initrd";
+				reg = <0x001e0000 0x001a0000>;
+			};
+
+			partitions at 3 {
+				label = "etc";
+				reg = <0x00380000 0x00070000>;
+			};
+
+			/* 448k gap */
+
+			partitions at 4 {
+				label = "env1";
+				reg = <0x003fc000 0x00002000>;
+			};
+
+			partitions at 5 {
+				label = "env2";
+				reg = <0x003fe000 0x00002000>;
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "Reset";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			label = "Power";
+			gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		sync {
+			label = "Copy/Sync";
+			gpio = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		/*
+		 * The vendor U-Boot enables a PWM to make this LED blink during boot.
+		 * This must be disabled to be able to drive the LED using the
+		 * GPIO as defined here by unsetting bit 9 in the
+		 * SYS_CTRL_GPIO_PWMSEL_CTRL_0 register.
+		 * E.g. do before starting Linux: mw 0x4500009c 0
+		 */
+		led1 {
+			label = "nsa210:green:sys";
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		led2 {
+			label = "nsa210:red:hdd";
+			gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
+		};
+
+		led3 {
+			label = "nsa210:green:hdd";
+			gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
+		};
+
+		led4 {
+			label = "nsa210:red:usb";
+			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		led5 {
+			label = "nsa210:green:usb";
+			gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+		};
+
+		led6 {
+			label = "nsa210:red:esata";
+			gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
+		};
+
+		led7 {
+			label = "nsa210:green:esata";
+			gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+		};
+
+		led8 {
+			label = "nsa210:red:copy";
+			gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+		};
+
+		led9 {
+			label = "nsa210:green:copy";
+			gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&uart2 {
+	/*
+	 * To make this device work as expected bit 2 of register
+	 * SYS_CTRL_UART_CTRL must be set. Otherwise the interrupt doesn't
+	 * trigger, so console messages make it through, but userspace cannot
+	 * make use of it.
+	 * E.g. do before starting Linux: mw 0x45000094 4
+	 */
+	status = "okay";
+};
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 03:45:16 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Aug 2021 11:45:16 +0100
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <CAOQ_Qsi-r0=YubmaTezB7Cq-RhzU3njWm+P5w-RWZcUz4kMfDA@mail.gmail.com>
References: <20210807191428.3488948-1-oupton@google.com>
 <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>
 <CAOQ_QsiECN7iVDyiyos12tk__viGkFhH9b6ZfkZVAYjeKhB=pQ@mail.gmail.com>
 <87lf5c1aox.wl-maz@kernel.org>
 <CAOQ_Qsi-r0=YubmaTezB7Cq-RhzU3njWm+P5w-RWZcUz4kMfDA@mail.gmail.com>
Message-ID: <87mtpqc2wz.wl-maz@kernel.org>

On Sun, 08 Aug 2021 20:01:10 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Sun, Aug 8, 2021 at 3:40 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Sun, 08 Aug 2021 02:14:35 +0100,
> > Oliver Upton <oupton at google.com> wrote:
> >
> > > The only other sane idea that I could come up with is providing this
> > > information to the kernel through DT, although that would leave ACPI
> > > systems behind.
> >
> > It also has the disadvantage that a large number of DT timer nodes are
> > a mess of cargo-culted, copy-pasted idioms, and that adding another
> > property would only make it worse.
> 
> Agreed, this does seem like the best solution, short of the
> architecture actually providing something to determine the counter
> width.
> 
> On that note, I wonder how (if ever) we will be able to move away from
> unnecessarily masking a 64 bit counter, i.e. a v8.6 or above
> implementation. With this patch, one such counter would wrap after
> 36.56 years, short of the 40 year guarantee we have from the
> architecture for < v8.6 implementations. Getting it to 64 bits would
> squarely make it someone else's problem ~585 years from now :)

Hmmm. If you end-up with something that falls short of 40 years, then
I suspect something is wrong in the way you compute the required
width.

40 years @1GHz (which we shall call FY1G from now on) fits comfortably
in 61 bits, and I fear that your use of ilog2() gives you one less bit
than what it should be:

log2(FY1G) ~= 60.13

What you are after is probably (ilog2(FY1G - 1) + 1), similar to the
way roundup_pow_of_two() works.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzysztof.kozlowski at canonical.com  Mon Aug  9 03:45:50 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 9 Aug 2021 12:45:50 +0200
Subject: [PATCH v2 4/8] tty: serial: samsung: Init USI to keep clocks
 running
In-Reply-To: <20210806152146.16107-5-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-5-semen.protsenko@linaro.org>
Message-ID: <85df3188-0227-f926-61bf-30db1a5ef41d@canonical.com>

On 06/08/2021 17:21, Sam Protsenko wrote:
> UART block is a part of USI (Universal Serial Interface) IP-core in
> Samsung SoCs since Exynos9810 (e.g. in Exynos850). USI allows one to
> enable one of three types of serial interface: UART, SPI or I2C. That's
> possible because USI shares almost all internal circuits within each
> protocol. USI also provides some additional registers so it's possible
> to configure it.
> 
> One USI register called USI_OPTION has reset value of 0x0. Because of
> this the clock gating behavior is controlled by hardware (HWACG =
> Hardware Auto Clock Gating), which simply means the serial won't work
> after reset as is. In order to make it work, USI_OPTION[2:1] bits must
> be set to 0b01, so that HWACG is controlled manually (by software).
> Bits meaning:
>   - CLKREQ_ON = 1: clock is continuously provided to IP
>   - CLKSTOP_ON = 0: drive IP_CLKREQ to High (needs to be set along with
>                     CLKREQ_ON = 1)
> 
> USI is not present on older chips, like s3c2410, s3c2412, s3c2440,
> s3c6400, s5pv210, exynos5433, exynos4210. So the new boolean field
> '.has_usi' was added to struct s3c24xx_uart_info. USI registers will be
> only actually accessed when '.has_usi' field is set to "1".
> 
> This feature is needed for further serial enablement on Exynos850, but
> some other new Exynos chips (like Exynos9810) may benefit from this
> feature as well.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v2:
>   - Non-intrusive modification of USI registers
>   - Improved comments
>   - Rearranged USI register definitions to conform with existing style
> 
>  drivers/tty/serial/samsung_tty.c | 32 +++++++++++++++++++++++++++++++-
>  include/linux/serial_s3c.h       |  9 +++++++++
>  2 files changed, 40 insertions(+), 1 deletion(-)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>



Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Mon Aug  9 03:46:19 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 9 Aug 2021 12:46:19 +0200
Subject: [PATCH v2 6/8] tty: serial: samsung: Add Exynos850 SoC data
In-Reply-To: <20210806152146.16107-7-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-7-semen.protsenko@linaro.org>
Message-ID: <6169e25b-2829-628a-f910-348ddd4b3030@canonical.com>

On 06/08/2021 17:21, Sam Protsenko wrote:
> Add serial driver data for Exynos850 SoC. This driver data is basically
> reusing EXYNOS_COMMON_SERIAL_DRV_DATA, which is common for all Exynos
> chips, but also enables USI init, which was added in previous commit:
> "tty: serial: samsung: Init USI to keep clocks running".
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v2:
>   - Fixed default fifo sizes
> 
>  drivers/tty/serial/samsung_tty.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From will at kernel.org  Mon Aug  9 03:52:38 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 11:52:38 +0100
Subject: [GIT PULL] arm64 fixes for -rc5
In-Reply-To: <CAHk-=whNiAtCUqeCAcq+GKjmOXFfLCYA84TpeeL2085c+BdmQQ@mail.gmail.com>
References: <20210806135331.GA2951@willie-the-truck>
 <CAHk-=whNiAtCUqeCAcq+GKjmOXFfLCYA84TpeeL2085c+BdmQQ@mail.gmail.com>
Message-ID: <20210809105238.GA5693@willie-the-truck>

Hi Linus,

[+Mark]

On Fri, Aug 06, 2021 at 11:40:33AM -0700, Linus Torvalds wrote:
> On Fri, Aug 6, 2021 at 6:53 AM Will Deacon <will at kernel.org> wrote:
> >
> > Please pull these arm64 fixes for -rc5. It's all pretty minor but the
> > main fix is sorting out how we deal with return values from 32-bit system
> > calls as audit expects error codes to be sign-extended to 64 bits
> 
> I've pulled this, but that change looks _really_ odd.

Cheers, and yes it does. We're stuck in the middle of the architecture,
the compat ABI and internal kernel expectations. More below.

> First you seem to intentionally *zero-extend* the error value when you
> actually set it in pt_regs, and then you sign-extend them when reading
> them.
> 
> So the rules seem entirely arbitrary: oen place says "upper 32 bits
> need to be clear" and another place says "upper 32 bits need to be
> sign-extended".
> 
> Why this insanity? Why not make the rule be that the upper 32 bits are
> always just sign-extended?

There are a few things which collide here:

The architecture doesn't guarantee that the upper 32-bits of a 64-bit
general purpose register are preserved across an exception return to a
32-bit task. They _might_ be left intact, but it's up to the CPU whether
you get the value you wrote or all zeroes if you read those bits after
taking an exception back to 64-bit state. Consequently, we can't
expose 64-bit registers for 32-bit tasks via ptrace() as the
resulting behaviour is going to vary based on how the hardware feels.
Maybe we could sign-extend everything on exception entry, but that would
necessitate many more syscall wrappers for compat tasks than we currently
have so we could truncate pointer arguments back down to 32 bits.

Instead, we currently handle this by (a) treating the registers of a 32-bit
task as 32 bits (hence the zero extension when writing the value in
syscall_set_return_value()) and (b) explicitly clearing the upper bits of
x0 on exception entry from a 32-bit task in case we previously leaked a
negative syscall return value in there.

The problem then is that some in-kernel users (e.g. audit and some parts of
ptrace which abstract the syscall return value away from the register state)
_do_ want to see sign-extended syscall return arguments in order to match
against error codes (see is_syscall_success()). So we end up in a situation
where we need to sign-extend the return value for those, whilst leaving the
zero-extended version in the actual pt_regs structure.

It's ugly and subtle because the sky doesn't tend to fall in if you get
it wrong. As you can see, we're still fixing it.

Will


From krzysztof.kozlowski at canonical.com  Mon Aug  9 03:55:27 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 9 Aug 2021 12:55:27 +0200
Subject: [PATCH v2 7/8] clk: samsung: Add Exynos850 clock driver stub
In-Reply-To: <20210806152146.16107-8-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-8-semen.protsenko@linaro.org>
Message-ID: <7110b1e2-1aee-6ddf-803f-ee392e494f2d@canonical.com>

On 06/08/2021 17:21, Sam Protsenko wrote:
> For now it's just a stub driver to make the serial driver work. Later it
> will be implemented properly. This driver doesn't really change clocks,
> only registers the UART clock as a fixed-rate clock. Without this clock
> driver the UART driver won't work, as it's trying to obtain "uart" clock
> and fails if it's not able to.

You know that as temporary solution you can add necessary clocks
directly in your DTS as fixed-rate-clocks? Effect would be quite similar
to the one here for UART driver but instead adding some temporary code
you would add temporary DTS nodes and references.

I am fine with this approach although the binding (if ever defined...)
would need to be marked as experimental.

> 
> In order to get a functional serial console we have to implement that
> minimal clock driver with "uart" clock. It's not necessary to actually
> configure clocks, as those are already configured in bootloader, so
> kernel can rely on that for now.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v2:
>   - Used hard coded clock indexes, as clock bindings were removed; will
>     add clock bindings back (reimplemented) once proper clock driver is
>     ready
>   - Removed .data = 0 for exynos850-oscclk, as it's in BSS section
>   - Removed comma for terminator {}
>   - Made exynos850_clk_init() static
>   - Removed checking np for NULL, as it's already done in of_iomap()
> 
>  drivers/clk/samsung/Makefile        |  1 +
>  drivers/clk/samsung/clk-exynos850.c | 64 +++++++++++++++++++++++++++++
>  2 files changed, 65 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-exynos850.c
> 
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index 028b2e27a37e..c46cf11e4d0b 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos5433.o
>  obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
>  obj-$(CONFIG_EXYNOS_CLKOUT)	+= clk-exynos-clkout.o
>  obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
> +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
>  obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
>  obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>  obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
> diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
> new file mode 100644
> index 000000000000..36c7c7fe7cf0
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-exynos850.c
> @@ -0,0 +1,64 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
> + * Copyright (C) 2021 Linaro Ltd.
> + *
> + * Common Clock Framework support for Exynos850 SoC.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include "clk.h"
> +
> +/* Will be extracted to bindings header once proper clk driver is implemented */
> +#define OSCCLK		1
> +#define DOUT_UART	2
> +#define CLK_NR_CLKS	3
> +
> +/* Fixed rate clocks generated outside the SoC */
> +static struct samsung_fixed_rate_clock exynos850_fixed_rate_ext_clks[] __initdata = {
> +	FRATE(OSCCLK, "fin_pll", NULL, 0, 26000000),
> +};
> +
> +/*
> + * Model the UART clock as a fixed-rate clock for now, to make serial driver
> + * work. This clock is already configured in the bootloader.
> + */
> +static const struct samsung_fixed_rate_clock exynos850_peri_clks[] __initconst = {
> +	FRATE(DOUT_UART, "DOUT_UART", NULL, 0, 200000000),
> +};
> +
> +static const struct of_device_id ext_clk_match[] __initconst = {
> +	{ .compatible = "samsung,exynos850-oscclk" },
> +	{}
> +};
> +
> +static void __init exynos850_clk_init(struct device_node *np)
> +{
> +	void __iomem *reg_base;
> +	struct samsung_clk_provider *ctx;
> +
> +	reg_base = of_iomap(np, 0);
> +	if (!reg_base)
> +		panic("%s: failed to map registers\n", __func__);
> +
> +	ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
> +	if (!ctx)
> +		panic("%s: unable to allocate ctx\n", __func__);

Not needed, the samsung_clk_init() panics or returns valid memory.

> +
> +	samsung_clk_of_register_fixed_ext(ctx,
> +			exynos850_fixed_rate_ext_clks,
> +			ARRAY_SIZE(exynos850_fixed_rate_ext_clks),
> +			ext_clk_match);
> +
> +	samsung_clk_register_fixed_rate(ctx, exynos850_peri_clks,
> +			ARRAY_SIZE(exynos850_peri_clks));
> +
> +	samsung_clk_of_add_provider(np, ctx);
> +}
> +
> +CLK_OF_DECLARE(exynos850_clk, "samsung,exynos850-clock", exynos850_clk_init);
> 

Best regards,
Krzysztof


From l.stach at pengutronix.de  Mon Aug  9 04:01:27 2021
From: l.stach at pengutronix.de (Lucas Stach)
Date: Mon, 09 Aug 2021 13:01:27 +0200
Subject: [PATCH v2 00/18] i.MX8MM GPC improvements and BLK_CTRL driver
In-Reply-To: <8de1cd0a-4d91-60e2-61e6-9f903bbf546b@kontron.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <818b52fe-8fa6-b47a-6dde-783ac378c603@kontron.de>
 <8de1cd0a-4d91-60e2-61e6-9f903bbf546b@kontron.de>
Message-ID: <8ea33d97fb3f7abb2d80b11db28cce8c01932a09.camel@pengutronix.de>

Hi Frieder,

Am Donnerstag, dem 05.08.2021 um 20:56 +0200 schrieb Frieder Schrempf:
> On 05.08.21 12:18, Frieder Schrempf wrote:
> > On 21.07.21 22:46, Lucas Stach wrote:
> > > Hi all,
> > > 
> > > second revision of the GPC improvements and BLK_CTRL driver to make use
> > > of all the power-domains on the i.MX8MM. I'm not going to repeat the full
> > > blurb from the v1 cover letter here, but if you are not familiar with
> > > i.MX8MM power domains, it may be worth a read.
> > > 
> > > This 2nd revision fixes the DT bindings to be valid yaml, some small
> > > failure path issues and most importantly the interaction with system
> > > suspend/resume. With the previous version some of the power domains
> > > would not come up correctly after a suspend/resume cycle.
> > > 
> > > Updated testing git trees here, disclaimer still applies:
> > > https://git.pengutronix.de/cgit/lst/linux/log/?h=imx8m-power-domains
> > > https://git.pengutronix.de/cgit/lst/linux/log/?h=imx8m-power-domains-testing
> > 
> > I finally did some tests on my side using USB, GPU and DSI (no PCIe, VPU, CSI so far) and the results are promising. Thanks for the effort!
> > 
> > I will try to run some more automated suspend/resume and reboot test cycles over the weekend and report the results here afterwards.
> > 
> 
> Unfortunately I got some results sooner than I had hoped. I set up a simple loop to suspend/resume every few seconds and on the first run it took around 2-3 hours for the device to lock up on resume. On the second run it took less than half an hour. I had glmark2-es2-drm running in the background, but it looks like it crashed at some point before the lockup occurred.
> 
> Of course this could also be unrelated and caused by some peripheral driver or something but the first suspicion is definitely the power domains.
> 
> If you have any suggestions for which debug options to enable or where to add some printks, please let me know. If I do another run I would like to make sure that the resulting logs are helpful for debugging.
> 
> And I would appreciate if someone else could try to reproduce this problem on his/her side. I use this simple script for testing:
> 
> #!/bin/sh
> 
> glmark2-es2-drm &
> 
> while true;
> do
>     echo +10 > /sys/class/rtc/rtc0/wakealarm
>     echo mem > /sys/power/state
>     sleep 5
> done;

Hm, that's unfortunate.

I'm back from a two week vacation, but it looks like I won't have much
time available to look into this issue soon. It would be very helpful
if you could try to pinpoint the hang a bit more.  If you can reproduce
the hang with no_console_suspend you might be able to extract a bit
more info in which stage the hang happens (suspend, resume, TF-A, etc.)
If the hang is in the kernel you might be able to add some prints to
the suspend/resume paths to be able to track down the exact point of
the hang.

I'm happy to look into the issue once it's better known where to look,
but I fear that I won't have time to do the above investigation myself
short term. Frieder, is this something you could help with over the
next few days?

Regards,
Lucas



From olteanv at gmail.com  Mon Aug  9 04:06:26 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 9 Aug 2021 14:06:26 +0300
Subject: [PATCH net-next 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
 <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
Message-ID: <20210809110626.4kfkegwixiualq2x@skbuf>

Hi VK,

On Mon, Aug 09, 2021 at 06:22:28PM +0800, Wong Vee Khee wrote:
> diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
> index 63fda3fc40aa..c7a3aa862079 100644
> --- a/drivers/net/pcs/pcs-xpcs.c
> +++ b/drivers/net/pcs/pcs-xpcs.c
> @@ -1081,7 +1081,8 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = {
>  };
>  
>  struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> -			    phy_interface_t interface)
> +			    phy_interface_t interface,
> +			    bool skip_reset)
>  {
>  	struct dw_xpcs *xpcs;
>  	u32 xpcs_id;
> @@ -1113,9 +1114,16 @@ struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
>  		xpcs->pcs.ops = &xpcs_phylink_ops;
>  		xpcs->pcs.poll = true;
>  
> -		ret = xpcs_soft_reset(xpcs, compat);
> -		if (ret)
> -			goto out;
> +		if (!skip_reset) {
> +			dev_info(&xpcs->mdiodev->dev, "%s: xPCS soft reset\n",
> +				 __func__);
> +			ret = xpcs_soft_reset(xpcs, compat);
> +			if (ret)
> +				goto out;
> +		} else {
> +			dev_info(&xpcs->mdiodev->dev,
> +				 "%s: skip xpcs soft reset\n", __func__);
> +		}

I don't feel like the prints are really necessary.

>  
>  		return xpcs;
>  	}
> diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
> index add077a81b21..0c05a63f3446 100644
> --- a/include/linux/pcs/pcs-xpcs.h
> +++ b/include/linux/pcs/pcs-xpcs.h
> @@ -36,7 +36,8 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
>  int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
>  		    int enable);
>  struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> -			    phy_interface_t interface);
> +			    phy_interface_t interface,
> +			    bool xpcs_reset);
>  void xpcs_destroy(struct dw_xpcs *xpcs);
>  

How about exporting the reset functionality as a separate function, and
the Intel Alder Lake stmmac shim just won't call it? Like this:

-----------------------------[ cut here ]-----------------------------
diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
index 19aea8fb76f6..5acf6742da4d 100644
--- a/drivers/net/dsa/sja1105/sja1105_mdio.c
+++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
@@ -437,13 +437,17 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
 			goto out_pcs_free;
 		}
 
-		xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
+		xpcs = xpcs_create(mdiodev);
 		if (IS_ERR(xpcs)) {
 			rc = PTR_ERR(xpcs);
 			goto out_pcs_free;
 		}
 
 		priv->xpcs[port] = xpcs;
+
+		rc = xpcs_reset(xpcs, priv->phy_mode[port]);
+		if (rc)
+			goto out_pcs_free;
 	}
 
 	priv->mdio_pcs = bus;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index a5d150c5f3d8..81a145009488 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -401,12 +401,15 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
 {
 	struct net_device *ndev = bus->priv;
 	struct mdio_device *mdiodev;
+	bool skip_xpcs_soft_reset;
 	struct stmmac_priv *priv;
 	struct dw_xpcs *xpcs;
 	int mode, addr;
+	int err;
 
 	priv = netdev_priv(ndev);
 	mode = priv->plat->phy_interface;
+	skip_xpcs_soft_reset = priv->plat->skip_xpcs_soft_reset;
 
 	/* Try to probe the XPCS by scanning all addresses. */
 	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
@@ -414,12 +417,21 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
 		if (IS_ERR(mdiodev))
 			continue;
 
-		xpcs = xpcs_create(mdiodev, mode);
+		xpcs = xpcs_create(mdiodev);
 		if (IS_ERR_OR_NULL(xpcs)) {
 			mdio_device_free(mdiodev);
 			continue;
 		}
 
+		if (!skip_xpcs_soft_reset) {
+			err = xpcs_reset(xpcs, mode);
+			if (err) {
+				xpcs_destroy(xpcs);
+				mdio_device_free(mdiodev);
+				continue;
+			}
+		}
+
 		priv->hw->xpcs = xpcs;
 		break;
 	}
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 63fda3fc40aa..2e721e57bee4 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -248,6 +248,18 @@ static int xpcs_soft_reset(struct dw_xpcs *xpcs,
 	return xpcs_poll_reset(xpcs, dev);
 }
 
+int xpcs_reset(struct dw_xpcs *xpcs, phy_interface_t interface)
+{
+	const struct xpcs_compat *compat;
+
+	compat = xpcs_find_compat(xpcs->id, interface);
+	if (!compat)
+		return -ENODEV;
+
+	return xpcs_soft_reset(xpcs, compat);
+}
+EXPORT_SYMBOL_GPL(xpcs_reset);
+
 #define xpcs_warn(__xpcs, __state, __args...) \
 ({ \
 	if ((__state)->link) \
@@ -1080,12 +1092,11 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = {
 	.pcs_link_up = xpcs_link_up,
 };
 
-struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-			    phy_interface_t interface)
+struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
 {
 	struct dw_xpcs *xpcs;
 	u32 xpcs_id;
-	int i, ret;
+	int i;
 
 	xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
 	if (!xpcs)
@@ -1097,35 +1108,18 @@ struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
 
 	for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
 		const struct xpcs_id *entry = &xpcs_id_list[i];
-		const struct xpcs_compat *compat;
 
 		if ((xpcs_id & entry->mask) != entry->id)
 			continue;
 
 		xpcs->id = entry;
-
-		compat = xpcs_find_compat(entry, interface);
-		if (!compat) {
-			ret = -ENODEV;
-			goto out;
-		}
-
 		xpcs->pcs.ops = &xpcs_phylink_ops;
 		xpcs->pcs.poll = true;
 
-		ret = xpcs_soft_reset(xpcs, compat);
-		if (ret)
-			goto out;
-
 		return xpcs;
 	}
 
-	ret = -ENODEV;
-
-out:
-	kfree(xpcs);
-
-	return ERR_PTR(ret);
+	return ERR_PTR(-ENODEV);
 }
 EXPORT_SYMBOL_GPL(xpcs_create);
 
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index add077a81b21..d841f55f12cc 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -35,8 +35,8 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
 		   struct phylink_link_state *state);
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
-struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-			    phy_interface_t interface);
+int xpcs_reset(struct dw_xpcs *xpcs, phy_interface_t interface);
+struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev);
 void xpcs_destroy(struct dw_xpcs *xpcs);
 
 #endif /* __LINUX_PCS_XPCS_H */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..0f901773c5e4 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -268,5 +268,6 @@ struct plat_stmmacenet_data {
 	int msi_rx_base_vec;
 	int msi_tx_base_vec;
 	bool use_phy_wol;
+	bool skip_xpcs_soft_reset;
 };
 #endif
-----------------------------[ cut here ]-----------------------------

I also gave this patch a run on sja1105 and it still works.


From maz at kernel.org  Mon Aug  9 04:07:52 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Aug 2021 12:07:52 +0100
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <20210807191428.3488948-1-oupton@google.com>
References: <20210807191428.3488948-1-oupton@google.com>
Message-ID: <87lf5ac1vb.wl-maz@kernel.org>

On Sat, 07 Aug 2021 20:14:28 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Unfortunately, the architecture provides no means to determine the bit
> width of the system counter. However, we do know the following from the
> specification:
> 
>  - the system counter is at least 56 bits wide
>  - Roll-over time of not less than 40 years
> 
> To date, the arch timer driver has depended on the first property,
> assuming any system counter to be 56 bits wide and masking off the rest.
> However, combining a narrow clocksource mask with a high frequency
> counter could result in prematurely wrapping the system counter by a
> significant margin. For example, a 56 bit wide, 1GHz system counter
> would wrap in a mere 2.28 years!
> 
> This is a problem for two reasons: v8.6+ implementations are required to
> provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> implementers may select a counter frequency of their choosing.
> 
> Fix the issue by deriving a valid clock mask based on the second
> property from above. Set the floor at 56 bits, since we know no system
> counter is narrower than that.
> 
> Suggested-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
> This patch was tested on QEMU, tweaked to provide a 1GHz system counter
> frequency. The 'bp.refcounter.base_frequency' property does not seem to
> have any affect on the 'ARMvA Base RevC AEM FVP', and instead provides a
> 100MHz counter.
> 
> Parent commit: 0c32706dac1b ("arm64: stacktrace: avoid tracing arch_stack_walk()")
> 
>  drivers/clocksource/arm_arch_timer.c | 32 ++++++++++++++++++++++++----
>  1 file changed, 28 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index be6d741d404c..f4816b22213c 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -52,6 +52,12 @@
>  #define CNTV_TVAL	0x38
>  #define CNTV_CTL	0x3c
>  
> +/*
> + * The minimum amount of time a generic counter is guaranteed to not roll over
> + * (40 years)
> + */
> +#define MIN_ROLLOVER_SECS	(40ULL * 365 * 24 * 3600)
> +
>  static unsigned arch_timers_present __initdata;
>  
>  static void __iomem *arch_counter_base __ro_after_init;
> @@ -205,13 +211,11 @@ static struct clocksource clocksource_counter = {
>  	.id	= CSID_ARM_ARCH_COUNTER,
>  	.rating	= 400,
>  	.read	= arch_counter_read,
> -	.mask	= CLOCKSOURCE_MASK(56),
>  	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
>  };
>  
>  static struct cyclecounter cyclecounter __ro_after_init = {
>  	.read	= arch_counter_read_cc,
> -	.mask	= CLOCKSOURCE_MASK(56),
>  };
>  
>  struct ate_acpi_oem_info {
> @@ -1004,9 +1008,26 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
>  	return &arch_timer_kvm_info;
>  }
>  
> +/*
> + * Makes an educated guess at a valid counter width based on the Generic Timer
> + * specification. Of note:
> + *   1) the system counter is at least 56 bits wide
> + *   2) a roll-over time of not less than 40 years
> + *
> + * See 'ARM DDI 0487G.a D11.1.2 ("The system counter")' for more details.
> + */
> +static int __init arch_counter_get_width(void)
> +{
> +	u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_rate;
> +
> +	/* guarantee the returned width is within the valid range */
> +	return clamp_val(ilog2(min_cycles), 56, 64);

See my comment somewhere else in the thread about the potential wasted
bit.

> +}
> +
>  static void __init arch_counter_register(unsigned type)
>  {
>  	u64 start_count;
> +	int width;
>  
>  	/* Register the CP15 based counter if we have one */
>  	if (type & ARCH_TIMER_TYPE_CP15) {
> @@ -1031,6 +1052,10 @@ static void __init arch_counter_register(unsigned type)
>  		arch_timer_read_counter = arch_counter_get_cntvct_mem;
>  	}
>  
> +	width = arch_counter_get_width();
> +	clocksource_counter.mask = CLOCKSOURCE_MASK(width);
> +	cyclecounter.mask = CLOCKSOURCE_MASK(width);
> +
>  	if (!arch_counter_suspend_stop)
>  		clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
>  	start_count = arch_timer_read_counter();
> @@ -1040,8 +1065,7 @@ static void __init arch_counter_register(unsigned type)
>  	timecounter_init(&arch_timer_kvm_info.timecounter,
>  			 &cyclecounter, start_count);
>  
> -	/* 56 bits minimum, so we assume worst case rollover */
> -	sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
> +	sched_clock_register(arch_timer_read_counter, width, arch_timer_rate);

For the record, there is one spot where the clockevent gets registered
and configured that also needs addressing (there is a mask harcoded to
31 bits there, which is pretty odd). It cannot be fixed directly in
this patch though. I'll probably take this patch on top of my series
and adjust the relevant bits.

	M.

-- 
Without deviation from the norm, progress is not possible.


From wangkefeng.wang at huawei.com  Mon Aug  9 04:10:09 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 9 Aug 2021 19:10:09 +0800
Subject: [PATCH v3 3/3] kasan: arm64: Fix pcpu_page_first_chunk crash with
 KASAN_VMALLOC
In-Reply-To: <20210809093750.131091-4-wangkefeng.wang@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <20210809093750.131091-4-wangkefeng.wang@huawei.com>
Message-ID: <ae15c02e-d825-dbef-1419-5b5220f826c1@huawei.com>


On 2021/8/9 17:37, Kefeng Wang wrote:
> With KASAN_VMALLOC and NEED_PER_CPU_PAGE_FIRST_CHUNK, it crashs,
>
> Unable to handle kernel paging request at virtual address ffff7000028f2000
> ...
> swapper pgtable: 64k pages, 48-bit VAs, pgdp=0000000042440000
> [ffff7000028f2000] pgd=000000063e7c0003, p4d=000000063e7c0003, pud=000000063e7c0003, pmd=000000063e7b0003, pte=0000000000000000
> Internal error: Oops: 96000007 [#1] PREEMPT SMP
> Modules linked in:
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.0-rc4-00003-gc6e6e28f3f30-dirty #62
> Hardware name: linux,dummy-virt (DT)
> pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO BTYPE=--)
> pc : kasan_check_range+0x90/0x1a0
> lr : memcpy+0x88/0xf4
> sp : ffff80001378fe20
> ...
> Call trace:
>   kasan_check_range+0x90/0x1a0
>   pcpu_page_first_chunk+0x3f0/0x568
>   setup_per_cpu_areas+0xb8/0x184
>   start_kernel+0x8c/0x328
>
> The vm area used in vm_area_register_early() has no kasan shadow memory,
> Let's add a new kasan_populate_early_vm_area_shadow() function to populate
> the vm area shadow memory to fix the issue.

Should add Acked-by: Marco Elver <elver at google.com> [for KASAN parts] ,

missed here :(

> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>   arch/arm64/mm/kasan_init.c | 16 ++++++++++++++++
>   include/linux/kasan.h      |  6 ++++++
>   mm/kasan/init.c            |  5 +++++
>   mm/vmalloc.c               |  1 +
>   4 files changed, 28 insertions(+)
>
> diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
> index 61b52a92b8b6..5b996ca4d996 100644
> --- a/arch/arm64/mm/kasan_init.c
> +++ b/arch/arm64/mm/kasan_init.c
> @@ -287,6 +287,22 @@ static void __init kasan_init_depth(void)
>   	init_task.kasan_depth = 0;
>   }
>   
> +#ifdef CONFIG_KASAN_VMALLOC
> +void __init kasan_populate_early_vm_area_shadow(void *start, unsigned long size)
> +{
> +	unsigned long shadow_start, shadow_end;
> +
> +	if (!is_vmalloc_or_module_addr(start))
> +		return;
> +
> +	shadow_start = (unsigned long)kasan_mem_to_shadow(start);
> +	shadow_start = ALIGN_DOWN(shadow_start, PAGE_SIZE);
> +	shadow_end = (unsigned long)kasan_mem_to_shadow(start + size);
> +	shadow_end = ALIGN(shadow_end, PAGE_SIZE);
> +	kasan_map_populate(shadow_start, shadow_end, NUMA_NO_NODE);
> +}
> +#endif
> +
>   void __init kasan_init(void)
>   {
>   	kasan_init_shadow();
> diff --git a/include/linux/kasan.h b/include/linux/kasan.h
> index dd874a1ee862..3f8c26d9ef82 100644
> --- a/include/linux/kasan.h
> +++ b/include/linux/kasan.h
> @@ -133,6 +133,8 @@ struct kasan_cache {
>   	bool is_kmalloc;
>   };
>   
> +void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
> +
>   slab_flags_t __kasan_never_merge(void);
>   static __always_inline slab_flags_t kasan_never_merge(void)
>   {
> @@ -303,6 +305,10 @@ void kasan_restore_multi_shot(bool enabled);
>   
>   #else /* CONFIG_KASAN */
>   
> +static inline void kasan_populate_early_vm_area_shadow(void *start,
> +						       unsigned long size)
> +{ }
> +
>   static inline slab_flags_t kasan_never_merge(void)
>   {
>   	return 0;
> diff --git a/mm/kasan/init.c b/mm/kasan/init.c
> index cc64ed6858c6..d39577d088a1 100644
> --- a/mm/kasan/init.c
> +++ b/mm/kasan/init.c
> @@ -279,6 +279,11 @@ int __ref kasan_populate_early_shadow(const void *shadow_start,
>   	return 0;
>   }
>   
> +void __init __weak kasan_populate_early_vm_area_shadow(void *start,
> +						       unsigned long size)
> +{
> +}
> +
>   static void kasan_free_pte(pte_t *pte_start, pmd_t *pmd)
>   {
>   	pte_t *pte;
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 1e8fe08725b8..66a7e1ea2561 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -2253,6 +2253,7 @@ void __init vm_area_register_early(struct vm_struct *vm, size_t align)
>   	vm->addr = (void *)addr;
>   
>   	vm_area_add_early(vm);
> +	kasan_populate_early_vm_area_shadow(vm->addr, vm->size);
>   }
>   
>   static void vmap_init_free_space(void)


From rashmi.a at intel.com  Mon Aug  9 04:16:56 2021
From: rashmi.a at intel.com (A, Rashmi)
Date: Mon, 9 Aug 2021 11:16:56 +0000
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <YRDqQvKQ71/824Lu@matsya>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
 <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
 <YRDqQvKQ71/824Lu@matsya>
Message-ID: <MWHPR11MB1789D2B707B39CB42322C73A8CF69@MWHPR11MB1789.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Vinod Koul <vkoul at kernel.org>
> Sent: Monday, August 9, 2021 2:12 PM
> To: A, Rashmi <rashmi.a at intel.com>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>; Michal Simek
> <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
> kernel at vger.kernel.org>; Kishon <kishon at ti.com>; Andy Shevchenko
> <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org; Mark
> Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou, Furong
> <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> <adrian.hunter at intel.com>; Vaidya, Mahesh R
> <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> <kenchappa.demakkanavar at intel.com>
> Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
> support to the arasan eMMC driver
> 
> On 09-08-21, 05:16, A, Rashmi wrote:
> 
> > >
> > > Rashmi, is it safe to apply this separately from the phy driver/dt changes?
> > > Then I can queue this via my mmc tree, if you like.
> > No, the phy driver/dt changes must go together with "mmc: sdhci-of-
> arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver"
> patch.
> 
> Why is that?
> 
> What could happen, emmc driver will complain about phy not found and bail
> right?
This is right, but ideally both mmc:phy and mmc: sdhci-of-arasan driver code changes should go together
> 
> --
> ~Vinod


From elver at google.com  Mon Aug  9 04:21:44 2021
From: elver at google.com (Marco Elver)
Date: Mon, 9 Aug 2021 13:21:44 +0200
Subject: [PATCH v3 3/3] kasan: arm64: Fix pcpu_page_first_chunk crash with
 KASAN_VMALLOC
In-Reply-To: <ae15c02e-d825-dbef-1419-5b5220f826c1@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <20210809093750.131091-4-wangkefeng.wang@huawei.com>
 <ae15c02e-d825-dbef-1419-5b5220f826c1@huawei.com>
Message-ID: <CANpmjNOM-fzk2_q9LNLgM1wSReHWj42MxHBeDBLg8Ga5vv8HhQ@mail.gmail.com>

On Mon, 9 Aug 2021 at 13:10, Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
>
> On 2021/8/9 17:37, Kefeng Wang wrote:
> > With KASAN_VMALLOC and NEED_PER_CPU_PAGE_FIRST_CHUNK, it crashs,
> >
> > Unable to handle kernel paging request at virtual address ffff7000028f2000
> > ...
> > swapper pgtable: 64k pages, 48-bit VAs, pgdp=0000000042440000
> > [ffff7000028f2000] pgd=000000063e7c0003, p4d=000000063e7c0003, pud=000000063e7c0003, pmd=000000063e7b0003, pte=0000000000000000
> > Internal error: Oops: 96000007 [#1] PREEMPT SMP
> > Modules linked in:
> > CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.0-rc4-00003-gc6e6e28f3f30-dirty #62
> > Hardware name: linux,dummy-virt (DT)
> > pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO BTYPE=--)
> > pc : kasan_check_range+0x90/0x1a0
> > lr : memcpy+0x88/0xf4
> > sp : ffff80001378fe20
> > ...
> > Call trace:
> >   kasan_check_range+0x90/0x1a0
> >   pcpu_page_first_chunk+0x3f0/0x568
> >   setup_per_cpu_areas+0xb8/0x184
> >   start_kernel+0x8c/0x328
> >
> > The vm area used in vm_area_register_early() has no kasan shadow memory,
> > Let's add a new kasan_populate_early_vm_area_shadow() function to populate
> > the vm area shadow memory to fix the issue.
>
> Should add Acked-by: Marco Elver <elver at google.com> [for KASAN parts] ,

My Ack is still valid, thanks for noting.

> > Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> > ---
> >   arch/arm64/mm/kasan_init.c | 16 ++++++++++++++++
> >   include/linux/kasan.h      |  6 ++++++
> >   mm/kasan/init.c            |  5 +++++
> >   mm/vmalloc.c               |  1 +
> >   4 files changed, 28 insertions(+)
> >
> > diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
> > index 61b52a92b8b6..5b996ca4d996 100644
> > --- a/arch/arm64/mm/kasan_init.c
> > +++ b/arch/arm64/mm/kasan_init.c
> > @@ -287,6 +287,22 @@ static void __init kasan_init_depth(void)
> >       init_task.kasan_depth = 0;
> >   }
> >
> > +#ifdef CONFIG_KASAN_VMALLOC
> > +void __init kasan_populate_early_vm_area_shadow(void *start, unsigned long size)
> > +{
> > +     unsigned long shadow_start, shadow_end;
> > +
> > +     if (!is_vmalloc_or_module_addr(start))
> > +             return;
> > +
> > +     shadow_start = (unsigned long)kasan_mem_to_shadow(start);
> > +     shadow_start = ALIGN_DOWN(shadow_start, PAGE_SIZE);
> > +     shadow_end = (unsigned long)kasan_mem_to_shadow(start + size);
> > +     shadow_end = ALIGN(shadow_end, PAGE_SIZE);
> > +     kasan_map_populate(shadow_start, shadow_end, NUMA_NO_NODE);
> > +}
> > +#endif
> > +
> >   void __init kasan_init(void)
> >   {
> >       kasan_init_shadow();
> > diff --git a/include/linux/kasan.h b/include/linux/kasan.h
> > index dd874a1ee862..3f8c26d9ef82 100644
> > --- a/include/linux/kasan.h
> > +++ b/include/linux/kasan.h
> > @@ -133,6 +133,8 @@ struct kasan_cache {
> >       bool is_kmalloc;
> >   };
> >
> > +void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
> > +
> >   slab_flags_t __kasan_never_merge(void);
> >   static __always_inline slab_flags_t kasan_never_merge(void)
> >   {
> > @@ -303,6 +305,10 @@ void kasan_restore_multi_shot(bool enabled);
> >
> >   #else /* CONFIG_KASAN */
> >
> > +static inline void kasan_populate_early_vm_area_shadow(void *start,
> > +                                                    unsigned long size)
> > +{ }
> > +
> >   static inline slab_flags_t kasan_never_merge(void)
> >   {
> >       return 0;
> > diff --git a/mm/kasan/init.c b/mm/kasan/init.c
> > index cc64ed6858c6..d39577d088a1 100644
> > --- a/mm/kasan/init.c
> > +++ b/mm/kasan/init.c
> > @@ -279,6 +279,11 @@ int __ref kasan_populate_early_shadow(const void *shadow_start,
> >       return 0;
> >   }
> >
> > +void __init __weak kasan_populate_early_vm_area_shadow(void *start,
> > +                                                    unsigned long size)
> > +{
> > +}
> > +
> >   static void kasan_free_pte(pte_t *pte_start, pmd_t *pmd)
> >   {
> >       pte_t *pte;
> > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > index 1e8fe08725b8..66a7e1ea2561 100644
> > --- a/mm/vmalloc.c
> > +++ b/mm/vmalloc.c
> > @@ -2253,6 +2253,7 @@ void __init vm_area_register_early(struct vm_struct *vm, size_t align)
> >       vm->addr = (void *)addr;
> >
> >       vm_area_add_early(vm);
> > +     kasan_populate_early_vm_area_shadow(vm->addr, vm->size);
> >   }
> >
> >   static void vmap_init_free_space(void)


From krzysztof.kozlowski at canonical.com  Mon Aug  9 04:22:56 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 9 Aug 2021 13:22:56 +0200
Subject: [PATCH v2 7/8] clk: samsung: Add Exynos850 clock driver stub
In-Reply-To: <20210806152146.16107-8-semen.protsenko@linaro.org>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-8-semen.protsenko@linaro.org>
Message-ID: <3add6f87-7293-e1ae-8f9e-c69e9de18cf5@canonical.com>

On 06/08/2021 17:21, Sam Protsenko wrote:
> For now it's just a stub driver to make the serial driver work. Later it
> will be implemented properly. This driver doesn't really change clocks,
> only registers the UART clock as a fixed-rate clock. Without this clock
> driver the UART driver won't work, as it's trying to obtain "uart" clock
> and fails if it's not able to.
> 
> In order to get a functional serial console we have to implement that
> minimal clock driver with "uart" clock. It's not necessary to actually
> configure clocks, as those are already configured in bootloader, so
> kernel can rely on that for now.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v2:
>   - Used hard coded clock indexes, as clock bindings were removed; will
>     add clock bindings back (reimplemented) once proper clock driver is
>     ready
>   - Removed .data = 0 for exynos850-oscclk, as it's in BSS section
>   - Removed comma for terminator {}
>   - Made exynos850_clk_init() static
>   - Removed checking np for NULL, as it's already done in of_iomap()
> 
>  drivers/clk/samsung/Makefile        |  1 +
>  drivers/clk/samsung/clk-exynos850.c | 64 +++++++++++++++++++++++++++++
>  2 files changed, 65 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-exynos850.c
> 
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index 028b2e27a37e..c46cf11e4d0b 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -17,6 +17,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos5433.o
>  obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
>  obj-$(CONFIG_EXYNOS_CLKOUT)	+= clk-exynos-clkout.o
>  obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
> +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
>  obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
>  obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>  obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
> diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
> new file mode 100644
> index 000000000000..36c7c7fe7cf0
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-exynos850.c
> @@ -0,0 +1,64 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
> + * Copyright (C) 2021 Linaro Ltd.
> + *
> + * Common Clock Framework support for Exynos850 SoC.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include "clk.h"
> +
> +/* Will be extracted to bindings header once proper clk driver is implemented */
> +#define OSCCLK		1
> +#define DOUT_UART	2
> +#define CLK_NR_CLKS	3
> +
> +/* Fixed rate clocks generated outside the SoC */
> +static struct samsung_fixed_rate_clock exynos850_fixed_rate_ext_clks[] __initdata = {
> +	FRATE(OSCCLK, "fin_pll", NULL, 0, 26000000),
> +};
> +
> +/*
> + * Model the UART clock as a fixed-rate clock for now, to make serial driver
> + * work. This clock is already configured in the bootloader.
> + */
> +static const struct samsung_fixed_rate_clock exynos850_peri_clks[] __initconst = {
> +	FRATE(DOUT_UART, "DOUT_UART", NULL, 0, 200000000),
> +};
> +
> +static const struct of_device_id ext_clk_match[] __initconst = {
> +	{ .compatible = "samsung,exynos850-oscclk" },

One more thing - I am not sure anymore if this is correct. AFAIR, we
wanted to drop compatibles for external clocks.

Chanwoo, Sylwester, Tomasz,
Do you remember the recommended approach? Shall it be like Exynos542x
(samsung,exynos5420-oscclk) or Exynos5433?


BTW, I am now converting some of existing clock controller bindings to
dtschema.

Best regards,
Krzysztof


From leo.yan at linaro.org  Mon Aug  9 04:27:24 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  9 Aug 2021 19:27:24 +0800
Subject: [PATCH v1 0/3] perf: Support compat mode for AUX ring buffer
Message-ID: <20210809112727.596876-1-leo.yan@linaro.org>

For better organising and easier review, this patch series is extracted
from the patch set "perf: Refine barriers for AUX ring buffer" .  When
applying this patch series, it needs to be applied on the top of the
patch series [1].

To support the compat mode in perf tool, the patch 01 adds an new item
in "perf_env" to track if kernel is running in 64-bit mode.  This patch
is a preparation for later changes.

Patch 02 introduces compat variant functions for accessing AUX trace's
head and tail, these two functions are defined with weak attribute, so
they can be called when any architectures cannot provide 64-bit value
atomic accessing when perf is in compat mode.

Patch 03 supports compat_auxtrace_mmap__{read_head|write_tail} on Arm
platform.  For Arm platform with compat mode, the kernel runs in 64-bit
kernel mode and user space tool runs in 32-bit mode, it uses the
instructions "ldrd" and "strd" for 64-bit value atomicity.

This patch set have been tested on Arm64 Juno platform for the perf tool
is built with compiler arm-linux-gnueabihf-gcc.

[1] https://lore.kernel.org/patchwork/cover/1473916/


Leo Yan (3):
  perf env: Track kernel 64-bit mode in environment
  perf auxtrace: Add compat_auxtrace_mmap__{read_head|write_tail}
  perf auxtrace arm: Support
    compat_auxtrace_mmap__{read_head|write_tail}

 tools/perf/arch/arm/util/auxtrace.c | 32 +++++++++++
 tools/perf/util/auxtrace.c          | 88 +++++++++++++++++++++++++++--
 tools/perf/util/auxtrace.h          | 22 +++++++-
 tools/perf/util/env.c               | 24 +++++++-
 tools/perf/util/env.h               |  3 +
 5 files changed, 161 insertions(+), 8 deletions(-)

-- 
2.25.1



From leo.yan at linaro.org  Mon Aug  9 04:27:25 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  9 Aug 2021 19:27:25 +0800
Subject: [PATCH v1 1/3] perf env: Track kernel 64-bit mode in environment
In-Reply-To: <20210809112727.596876-1-leo.yan@linaro.org>
References: <20210809112727.596876-1-leo.yan@linaro.org>
Message-ID: <20210809112727.596876-2-leo.yan@linaro.org>

It's useful to know that the kernel is running in 32-bit or 64-bit
mode.  E.g. We can decide if perf tool is running in compat mode
based on the info.

This patch adds an item "kernel_is_64_bit" into session's environment
structure perf_env, its value is initialized based on the architecture
string.

Suggested-by: Arnaldo Carvalho de Melo <acme at redhat.com>
Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 tools/perf/util/env.c | 24 +++++++++++++++++++++++-
 tools/perf/util/env.h |  3 +++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index ab341050be46..8f7ff0035c41 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -219,13 +219,35 @@ void perf_env__exit(struct perf_env *env)
 	zfree(&env->hybrid_cpc_nodes);
 }
 
-void perf_env__init(struct perf_env *env __maybe_unused)
+void perf_env__init(struct perf_env *env)
 {
 #ifdef HAVE_LIBBPF_SUPPORT
 	env->bpf_progs.infos = RB_ROOT;
 	env->bpf_progs.btfs = RB_ROOT;
 	init_rwsem(&env->bpf_progs.lock);
 #endif
+	env->kernel_is_64_bit = -1;
+}
+
+static void perf_env__init_kernel_mode(struct perf_env *env)
+{
+	const char *arch = perf_env__raw_arch(env);
+
+	if (!strncmp(arch, "x86_64", 6) || !strncmp(arch, "aarch64", 7) ||
+	    !strncmp(arch, "arm64", 5) || !strncmp(arch, "mips64", 6) ||
+	    !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) ||
+	    !strncmp(arch, "s390x", 5) || !strncmp(arch, "sparc64", 7))
+		env->kernel_is_64_bit = 1;
+	else
+		env->kernel_is_64_bit = 0;
+}
+
+int perf_env__kernel_is_64_bit(struct perf_env *env)
+{
+	if (env->kernel_is_64_bit == -1)
+		perf_env__init_kernel_mode(env);
+
+	return env->kernel_is_64_bit;
 }
 
 int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 6824a7423a2d..1f5175820a05 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -61,6 +61,7 @@ struct perf_env {
 	unsigned long long	total_mem;
 	unsigned int		msr_pmu_type;
 	unsigned int		max_branches;
+	int			kernel_is_64_bit;
 
 	int			nr_cmdline;
 	int			nr_sibling_cores;
@@ -143,6 +144,8 @@ extern struct perf_env perf_env;
 
 void perf_env__exit(struct perf_env *env);
 
+int perf_env__kernel_is_64_bit(struct perf_env *env);
+
 int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]);
 
 int perf_env__read_cpuid(struct perf_env *env);
-- 
2.25.1



From leo.yan at linaro.org  Mon Aug  9 04:27:26 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  9 Aug 2021 19:27:26 +0800
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210809112727.596876-1-leo.yan@linaro.org>
References: <20210809112727.596876-1-leo.yan@linaro.org>
Message-ID: <20210809112727.596876-3-leo.yan@linaro.org>

When perf runs in compat mode (kernel in 64-bit mode and the perf is in
32-bit mode), the 64-bit value atomicity in the user space cannot be
assured, E.g. on some architectures, the 64-bit value accessing is split
into two instructions, one is for the low 32-bit word accessing and
another is for the high 32-bit word.

This patch introduces weak functions compat_auxtrace_mmap__read_head()
and compat_auxtrace_mmap__write_tail(), as their naming indicates, when
perf tool works in compat mode, it uses these two functions to access
the AUX head and tail.  These two functions can allow the perf tool to
work properly in certain conditions, e.g. when perf tool works in
snapshot mode with only using AUX head pointer, or perf tool uses the
AUX buffer and the incremented tail is not bigger than 4GB.

When perf tool cannot handle the case when the AUX tail is bigger than
4GB, the function compat_auxtrace_mmap__write_tail() returns -1 and
tells the caller to bail out for the error.

These two functions are declared as weak attribute, this allows to
implement arch specific functions if any arch can support the 64-bit
value atomicity in compat mode.

Suggested-by: Adrian Hunter <adrian.hunter at intel.com>
Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 tools/perf/util/auxtrace.c | 88 ++++++++++++++++++++++++++++++++++++--
 tools/perf/util/auxtrace.h | 22 ++++++++--
 2 files changed, 103 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index f33f09b8b535..60975df05d54 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -1669,6 +1669,82 @@ int perf_event__process_auxtrace_error(struct perf_session *session,
 	return 0;
 }
 
+/*
+ * In the compat mode kernel runs in 64-bit and perf tool runs in 32-bit mode,
+ * 32-bit perf tool cannot access 64-bit value atomically, which might lead to
+ * the issues caused by the below sequence on multiple CPUs: when perf tool
+ * accesses either the load operation or the store operation for 64-bit value,
+ * on some architectures the operation is divided into two instructions, one
+ * is for accessing the low 32-bit value and another is for the high 32-bit;
+ * thus these two user operations can give the kernel chances to access the
+ * 64-bit value, and thus leads to the unexpected load values.
+ *
+ *   kernel (64-bit)                        user (32-bit)
+ *
+ *   if (LOAD ->aux_tail) { --,             LOAD ->aux_head_lo
+ *       STORE $aux_data      |       ,--->
+ *       FLUSH $aux_data      |       |     LOAD ->aux_head_hi
+ *       STORE ->aux_head   --|-------`     smp_rmb()
+ *   }                        |             LOAD $data
+ *                            |             smp_mb()
+ *                            |             STORE ->aux_tail_lo
+ *                            `----------->
+ *                                          STORE ->aux_tail_hi
+ *
+ * For this reason, it's impossible for the perf tool to work correctly when
+ * the AUX head or tail is bigger than 4GB (more than 32 bits length); and we
+ * can not simply limit the AUX ring buffer to less than 4GB, the reason is
+ * the pointers can be increased monotonically, whatever the buffer size it is,
+ * at the end the head and tail can be bigger than 4GB and carry out to the
+ * high 32-bit.
+ *
+ * To mitigate the issues and improve the user experience, we can allow the
+ * perf tool working in certain conditions and bail out with error if detect
+ * any overflow cannot be handled.
+ *
+ * For reading the AUX head, it reads out the values for three times, and
+ * compares the high 4 bytes of the values between the first time and the last
+ * time, if there has no change for high 4 bytes injected by the kernel during
+ * the user reading sequence, it's safe for use the second value.
+ *
+ * When update the AUX tail and detects any carrying in the high 32 bits, it
+ * means there have two store operations in user space and it cannot promise
+ * the atomicity for 64-bit write, so return '-1' in this case to tell the
+ * caller an overflow error has happened.
+ */
+u64 __weak compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+	u64 first, second, last;
+	u64 mask = (u64)(UINT32_MAX) << 32;
+
+	do {
+		first = READ_ONCE(pc->aux_head);
+		/* Ensure all reads are done after we read the head */
+		smp_rmb();
+		second = READ_ONCE(pc->aux_head);
+		/* Ensure all reads are done after we read the head */
+		smp_rmb();
+		last = READ_ONCE(pc->aux_head);
+	} while ((first & mask) != (last & mask));
+
+	return second;
+}
+
+int __weak compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+	u64 mask = (u64)(UINT32_MAX) << 32;
+
+	if (tail & mask)
+		return -1;
+
+	/* Ensure all reads are done before we write the tail out */
+	smp_mb();
+	WRITE_ONCE(pc->aux_tail, tail);
+	return 0;
+}
+
 static int __auxtrace_mmap__read(struct mmap *map,
 				 struct auxtrace_record *itr,
 				 struct perf_tool *tool, process_auxtrace_t fn,
@@ -1680,8 +1756,9 @@ static int __auxtrace_mmap__read(struct mmap *map,
 	size_t size, head_off, old_off, len1, len2, padding;
 	union perf_event ev;
 	void *data1, *data2;
+	int kernel_is_64_bit = perf_env__kernel_is_64_bit(evsel__env(NULL));
 
-	head = auxtrace_mmap__read_head(mm);
+	head = auxtrace_mmap__read_head(mm, kernel_is_64_bit);
 
 	if (snapshot &&
 	    auxtrace_record__find_snapshot(itr, mm->idx, mm, data, &head, &old))
@@ -1764,10 +1841,13 @@ static int __auxtrace_mmap__read(struct mmap *map,
 	mm->prev = head;
 
 	if (!snapshot) {
-		auxtrace_mmap__write_tail(mm, head);
-		if (itr->read_finish) {
-			int err;
+		int err;
+
+		err = auxtrace_mmap__write_tail(mm, head, kernel_is_64_bit);
+		if (err < 0)
+			return err;
 
+		if (itr->read_finish) {
 			err = itr->read_finish(itr, mm->idx);
 			if (err < 0)
 				return err;
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index d68a5e80b217..5f383908ca6e 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -440,23 +440,39 @@ struct auxtrace_cache;
 
 #ifdef HAVE_AUXTRACE_SUPPORT
 
-static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
+u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm);
+int compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail);
+
+static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm,
+					   int kernel_is_64_bit __maybe_unused)
 {
 	struct perf_event_mmap_page *pc = mm->userpg;
-	u64 head = READ_ONCE(pc->aux_head);
+	u64 head;
+
+#if BITS_PER_LONG == 32
+	if (kernel_is_64_bit)
+		return compat_auxtrace_mmap__read_head(mm);
+#endif
+	head = READ_ONCE(pc->aux_head);
 
 	/* Ensure all reads are done after we read the head */
 	smp_rmb();
 	return head;
 }
 
-static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
+static inline int auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail,
+					    int kernel_is_64_bit __maybe_unused)
 {
 	struct perf_event_mmap_page *pc = mm->userpg;
 
+#if BITS_PER_LONG == 32
+	if (kernel_is_64_bit)
+		return compat_auxtrace_mmap__write_tail(mm, tail);
+#endif
 	/* Ensure all reads are done before we write the tail out */
 	smp_mb();
 	WRITE_ONCE(pc->aux_tail, tail);
+	return 0;
 }
 
 int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
-- 
2.25.1



From leo.yan at linaro.org  Mon Aug  9 04:27:27 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  9 Aug 2021 19:27:27 +0800
Subject: [PATCH v1 3/3] perf auxtrace arm: Support
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210809112727.596876-1-leo.yan@linaro.org>
References: <20210809112727.596876-1-leo.yan@linaro.org>
Message-ID: <20210809112727.596876-4-leo.yan@linaro.org>

When the tool runs with compat mode on Arm platform, the kernel is in
64-bit mode and user space is in 32-bit mode; the user space can use
instructions "ldrd" and "strd" for 64-bit value atomicity.

This patch adds compat_auxtrace_mmap__{read_head|write_tail} for arm
building, it uses "ldrd" and "strd" instructions to ensure accessing
atomicity for aux head and tail.  The file arch/arm/util/auxtrace.c is
built for arm and arm64 building, these two functions are not needed for
arm64, so check the compiler macro "__arm__" to only include them for
arm building.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 tools/perf/arch/arm/util/auxtrace.c | 32 +++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c
index b187bddbd01a..c7c7ec0812d5 100644
--- a/tools/perf/arch/arm/util/auxtrace.c
+++ b/tools/perf/arch/arm/util/auxtrace.c
@@ -107,3 +107,35 @@ struct auxtrace_record
 	*err = 0;
 	return NULL;
 }
+
+#if defined(__arm__)
+u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+	u64 result;
+
+	__asm__ __volatile__(
+"	ldrd    %0, %H0, [%1]"
+	: "=&r" (result)
+	: "r" (&pc->aux_head), "Qo" (pc->aux_head)
+	);
+
+	return result;
+}
+
+int compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+
+	/* Ensure all reads are done before we write the tail out */
+	smp_mb();
+
+	__asm__ __volatile__(
+"	strd    %2, %H2, [%1]"
+	: "=Qo" (pc->aux_tail)
+	: "r" (&pc->aux_tail), "r" (tail)
+	);
+
+	return 0;
+}
+#endif
-- 
2.25.1



From lkp at intel.com  Mon Aug  9 04:34:01 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 9 Aug 2021 19:34:01 +0800
Subject: [PATCH v3 6/9] ASoC: mediatek: mt8195: add platform driver
In-Reply-To: <20210809094855.7169-7-trevor.wu@mediatek.com>
References: <20210809094855.7169-7-trevor.wu@mediatek.com>
Message-ID: <202108091939.bRYCdwJz-lkp@intel.com>

Hi Trevor,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on asoc/for-next]
[also build test WARNING on spi/for-next sound/for-next v5.14-rc5 next-20210806]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Trevor-Wu/ASoC-mediatek-Add-support-for-MT8195-SoC/20210809-175133
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
config: mips-allyesconfig (attached as .config)
compiler: mips-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/67c1e85ec1f88b1e5554b402e54ad6224a1398f7
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Trevor-Wu/ASoC-mediatek-Add-support-for-MT8195-SoC/20210809-175133
        git checkout 67c1e85ec1f88b1e5554b402e54ad6224a1398f7
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> sound/soc/mediatek/mt8195/mt8195-afe-clk.c:437:5: warning: no previous prototype for 'mt8195_afe_enable_timing_sys' [-Wmissing-prototypes]
     437 | int mt8195_afe_enable_timing_sys(struct mtk_base_afe *afe)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> sound/soc/mediatek/mt8195/mt8195-afe-clk.c:460:5: warning: no previous prototype for 'mt8195_afe_disable_timing_sys' [-Wmissing-prototypes]
     460 | int mt8195_afe_disable_timing_sys(struct mtk_base_afe *afe)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/mt8195_afe_enable_timing_sys +437 sound/soc/mediatek/mt8195/mt8195-afe-clk.c

   436	
 > 437	int mt8195_afe_enable_timing_sys(struct mtk_base_afe *afe)
   438	{
   439		struct mt8195_afe_private *afe_priv = afe->platform_priv;
   440		int i;
   441		unsigned int clk_array[] = {
   442			MT8195_CLK_AUD_A1SYS,
   443			MT8195_CLK_AUD_A2SYS,
   444		};
   445		unsigned int cg_array[] = {
   446			MT8195_TOP_CG_A1SYS_TIMING,
   447			MT8195_TOP_CG_A2SYS_TIMING,
   448			MT8195_TOP_CG_26M_TIMING,
   449		};
   450	
   451		for (i = 0; i < ARRAY_SIZE(clk_array); i++)
   452			mt8195_afe_enable_clk(afe, afe_priv->clk[clk_array[i]]);
   453	
   454		for (i = 0; i < ARRAY_SIZE(cg_array); i++)
   455			mt8195_afe_enable_top_cg(afe, cg_array[i]);
   456	
   457		return 0;
   458	}
   459	
 > 460	int mt8195_afe_disable_timing_sys(struct mtk_base_afe *afe)
   461	{
   462		struct mt8195_afe_private *afe_priv = afe->platform_priv;
   463		int i;
   464		unsigned int clk_array[] = {
   465			MT8195_CLK_AUD_A2SYS,
   466			MT8195_CLK_AUD_A1SYS,
   467		};
   468		unsigned int cg_array[] = {
   469			MT8195_TOP_CG_26M_TIMING,
   470			MT8195_TOP_CG_A2SYS_TIMING,
   471			MT8195_TOP_CG_A1SYS_TIMING,
   472		};
   473	
   474		for (i = 0; i < ARRAY_SIZE(cg_array); i++)
   475			mt8195_afe_disable_top_cg(afe, cg_array[i]);
   476	
   477		for (i = 0; i < ARRAY_SIZE(clk_array); i++)
   478			mt8195_afe_disable_clk(afe, afe_priv->clk[clk_array[i]]);
   479	
   480		return 0;
   481	}
   482	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 70955 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210809/853b2e71/attachment-0001.gz>

From lkp at intel.com  Mon Aug  9 04:44:20 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 09 Aug 2021 19:44:20 +0800
Subject: [keystone:next] BUILD SUCCESS a7a6278a5674f6d2f807f75558a280433886d5d9
Message-ID: <61111514.PnT1YjqxyXUjwDIu%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git next
branch HEAD: a7a6278a5674f6d2f807f75558a280433886d5d9  Merge branch 'for_5.14/drivers-soc' into next

elapsed time: 721m

configs tested: 170
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
mips                           ip27_defconfig
arm                      tct_hammer_defconfig
powerpc                         wii_defconfig
openrisc                    or1ksim_defconfig
arm                         nhk8815_defconfig
powerpc                 mpc8272_ads_defconfig
powerpc                      obs600_defconfig
arm                       aspeed_g5_defconfig
m68k                         amcore_defconfig
powerpc                      ppc64e_defconfig
powerpc                   microwatt_defconfig
h8300                     edosk2674_defconfig
sh                          r7785rp_defconfig
powerpc                     ksi8560_defconfig
sh                        edosk7705_defconfig
xtensa                           allyesconfig
arm                       mainstone_defconfig
m68k                       m5475evb_defconfig
arm                         lpc18xx_defconfig
powerpc                     taishan_defconfig
arm                        keystone_defconfig
x86_64                            allnoconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
sh                         apsh4a3a_defconfig
sh                          sdk7786_defconfig
arm                          lpd270_defconfig
arc                          axs103_defconfig
riscv                            alldefconfig
mips                        jmr3927_defconfig
m68k                       bvme6000_defconfig
arc                              allyesconfig
powerpc                    klondike_defconfig
i386                                defconfig
sh                           se7343_defconfig
m68k                          atari_defconfig
riscv                             allnoconfig
powerpc                     tqm8541_defconfig
mips                       capcella_defconfig
arm                      pxa255-idp_defconfig
sh                          rsk7201_defconfig
sh                          polaris_defconfig
powerpc                     ep8248e_defconfig
powerpc                 mpc832x_mds_defconfig
powerpc                      ppc44x_defconfig
h8300                            allyesconfig
sh                      rts7751r2d1_defconfig
powerpc                 xes_mpc85xx_defconfig
arm                          badge4_defconfig
powerpc                        cell_defconfig
mips                        vocore2_defconfig
arm                       aspeed_g4_defconfig
arm                       imx_v4_v5_defconfig
arm                          moxart_defconfig
sh                             sh03_defconfig
powerpc                     rainier_defconfig
arm                        realview_defconfig
mips                         tb0287_defconfig
powerpc                      ep88xc_defconfig
powerpc64                           defconfig
m68k                        stmark2_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                    sam440ep_defconfig
m68k                            q40_defconfig
arc                      axs103_smp_defconfig
mips                      pistachio_defconfig
powerpc                 mpc837x_rdb_defconfig
mips                     loongson1b_defconfig
powerpc                     tqm8555_defconfig
powerpc                 mpc834x_mds_defconfig
arm                           sunxi_defconfig
sh                          urquell_defconfig
mips                     loongson1c_defconfig
powerpc                       holly_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
x86_64               randconfig-a002-20210809
x86_64               randconfig-a004-20210809
x86_64               randconfig-a006-20210809
x86_64               randconfig-a003-20210809
x86_64               randconfig-a001-20210809
x86_64               randconfig-a005-20210809
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210809
x86_64               randconfig-c001-20210808
x86_64               randconfig-a002-20210808
x86_64               randconfig-a004-20210808
x86_64               randconfig-a006-20210808
x86_64               randconfig-a003-20210808
x86_64               randconfig-a001-20210808
x86_64               randconfig-a005-20210808
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Mon Aug  9 04:44:22 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 09 Aug 2021 19:44:22 +0800
Subject: [keystone:for_5.14/drivers-soc] BUILD SUCCESS
 195645d02ff5595744fc9f31d2a872e240da86bd
Message-ID: <61111516.EwM+vdV8OA50kzU2%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git for_5.14/drivers-soc
branch HEAD: 195645d02ff5595744fc9f31d2a872e240da86bd  soc: ti: Remove pm_runtime_irq_safe() usage for smartreflex

elapsed time: 721m

configs tested: 170
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
mips                           ip27_defconfig
arm                      tct_hammer_defconfig
powerpc                         wii_defconfig
openrisc                    or1ksim_defconfig
arm                         nhk8815_defconfig
powerpc                 mpc8272_ads_defconfig
powerpc                      obs600_defconfig
arm                       aspeed_g5_defconfig
m68k                         amcore_defconfig
powerpc                      ppc64e_defconfig
powerpc                   microwatt_defconfig
h8300                     edosk2674_defconfig
sh                          r7785rp_defconfig
powerpc                     ksi8560_defconfig
sh                        edosk7705_defconfig
xtensa                           allyesconfig
arm                       mainstone_defconfig
m68k                       m5475evb_defconfig
arm                         lpc18xx_defconfig
powerpc                     taishan_defconfig
arm                        keystone_defconfig
x86_64                            allnoconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
m68k                            q40_defconfig
sh                         apsh4a3a_defconfig
sh                          sdk7786_defconfig
arm                          lpd270_defconfig
arc                          axs103_defconfig
riscv                            alldefconfig
mips                        jmr3927_defconfig
m68k                       bvme6000_defconfig
arc                              allyesconfig
powerpc                    klondike_defconfig
i386                                defconfig
sh                           se7343_defconfig
m68k                          atari_defconfig
riscv                             allnoconfig
powerpc                     tqm8541_defconfig
mips                       capcella_defconfig
arm                      pxa255-idp_defconfig
sh                          rsk7201_defconfig
sh                          polaris_defconfig
powerpc                     ep8248e_defconfig
powerpc                 mpc832x_mds_defconfig
powerpc                      ppc44x_defconfig
h8300                            allyesconfig
sh                      rts7751r2d1_defconfig
powerpc                 xes_mpc85xx_defconfig
arm                          badge4_defconfig
powerpc                        cell_defconfig
mips                        vocore2_defconfig
arm                       aspeed_g4_defconfig
arm                       imx_v4_v5_defconfig
arm                          moxart_defconfig
sh                             sh03_defconfig
powerpc                     rainier_defconfig
arm                        realview_defconfig
mips                         tb0287_defconfig
powerpc                      ep88xc_defconfig
powerpc64                           defconfig
m68k                        stmark2_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                    sam440ep_defconfig
arc                      axs103_smp_defconfig
mips                      pistachio_defconfig
powerpc                 mpc837x_rdb_defconfig
mips                     loongson1b_defconfig
powerpc                     tqm8555_defconfig
powerpc                 mpc834x_mds_defconfig
arm                           sunxi_defconfig
sh                          urquell_defconfig
mips                     loongson1c_defconfig
powerpc                       holly_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
x86_64               randconfig-a002-20210809
x86_64               randconfig-a004-20210809
x86_64               randconfig-a006-20210809
x86_64               randconfig-a003-20210809
x86_64               randconfig-a001-20210809
x86_64               randconfig-a005-20210809
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210809
x86_64               randconfig-c001-20210808
x86_64               randconfig-a002-20210808
x86_64               randconfig-a004-20210808
x86_64               randconfig-a006-20210808
x86_64               randconfig-a003-20210808
x86_64               randconfig-a001-20210808
x86_64               randconfig-a005-20210808
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From robin.murphy at arm.com  Mon Aug  9 04:44:32 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 9 Aug 2021 12:44:32 +0100
Subject: [PATCH] arm64: dts: imx8qm: add smmu node
In-Reply-To: <20210807104517.24066-1-peng.fan@oss.nxp.com>
References: <20210807104517.24066-1-peng.fan@oss.nxp.com>
Message-ID: <57fc0247-808d-1c83-2ec9-840a48af025a@arm.com>

On 2021-08-07 11:45, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> i.MX8QM has an iommu unit: SMMU-V2(mmu-500), add it.

Given CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT, you may want to add 
this in a disabled state until you've filled in all the "iommus" 
properties for the client devices. Otherwise, be prepared to hear from 
people reporting issues bisected to this patch ;)

Robin.

> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>   arch/arm64/boot/dts/freescale/imx8qm.dtsi | 16 ++++++++++++++++
>   1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> index aebbe2b84aa1..b8ffd5be6a3e 100644
> --- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> @@ -165,6 +165,22 @@ iomuxc: pinctrl {
>   
>   	};
>   
> +	smmu: iommu at 51400000 {
> +		compatible = "arm,mmu-500";
> +		reg = <0 0x51400000 0 0x40000>;
> +		#iommu-cells = <2>;
> +		#global-interrupts = <1>;
> +		interrupts = <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>, <0 32 4>, <0 32 4>, <0 32 4>,
> +			     <0 32 4>;
> +	};
> +
>   	/* sorted in register address */
>   	#include "imx8-ss-img.dtsi"
>   	#include "imx8-ss-dma.dtsi"
> 


From frieder.schrempf at kontron.de  Mon Aug  9 04:50:44 2021
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Mon, 9 Aug 2021 13:50:44 +0200
Subject: [PATCH v2 00/18] i.MX8MM GPC improvements and BLK_CTRL driver
In-Reply-To: <8ea33d97fb3f7abb2d80b11db28cce8c01932a09.camel@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <818b52fe-8fa6-b47a-6dde-783ac378c603@kontron.de>
 <8de1cd0a-4d91-60e2-61e6-9f903bbf546b@kontron.de>
 <8ea33d97fb3f7abb2d80b11db28cce8c01932a09.camel@pengutronix.de>
Message-ID: <befbf918-c14a-e97c-a8d5-f5fe874dfa94@kontron.de>

On 09.08.21 13:01, Lucas Stach wrote:
> Hi Frieder,
> 
> Am Donnerstag, dem 05.08.2021 um 20:56 +0200 schrieb Frieder Schrempf:
>> On 05.08.21 12:18, Frieder Schrempf wrote:
>>> On 21.07.21 22:46, Lucas Stach wrote:
>>>> Hi all,
>>>>
>>>> second revision of the GPC improvements and BLK_CTRL driver to make use
>>>> of all the power-domains on the i.MX8MM. I'm not going to repeat the full
>>>> blurb from the v1 cover letter here, but if you are not familiar with
>>>> i.MX8MM power domains, it may be worth a read.
>>>>
>>>> This 2nd revision fixes the DT bindings to be valid yaml, some small
>>>> failure path issues and most importantly the interaction with system
>>>> suspend/resume. With the previous version some of the power domains
>>>> would not come up correctly after a suspend/resume cycle.
>>>>
>>>> Updated testing git trees here, disclaimer still applies:
>>>> https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.pengutronix.de%2Fcgit%2Flst%2Flinux%2Flog%2F%3Fh%3Dimx8m-power-domains&amp;data=04%7C01%7Cfrieder.schrempf%40kontron.de%7C189884f9332e40cd566a08d95b250a82%7C8c9d3c973fd941c8a2b1646f3942daf1%7C0%7C0%7C637641036912506485%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=OlymcyF9VOt6nsb2E%2BpFLTBnmlpOIOxwzdBbggPu%2FHo%3D&amp;reserved=0
>>>> https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.pengutronix.de%2Fcgit%2Flst%2Flinux%2Flog%2F%3Fh%3Dimx8m-power-domains-testing&amp;data=04%7C01%7Cfrieder.schrempf%40kontron.de%7C189884f9332e40cd566a08d95b250a82%7C8c9d3c973fd941c8a2b1646f3942daf1%7C0%7C0%7C637641036912506485%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=XSHl3JDKPFX%2FifXK5fcMQFOXbQXuHOJaNnJ3%2BtrMErk%3D&amp;reserved=0
>>>
>>> I finally did some tests on my side using USB, GPU and DSI (no PCIe, VPU, CSI so far) and the results are promising. Thanks for the effort!
>>>
>>> I will try to run some more automated suspend/resume and reboot test cycles over the weekend and report the results here afterwards.
>>>
>>
>> Unfortunately I got some results sooner than I had hoped. I set up a simple loop to suspend/resume every few seconds and on the first run it took around 2-3 hours for the device to lock up on resume. On the second run it took less than half an hour. I had glmark2-es2-drm running in the background, but it looks like it crashed at some point before the lockup occurred.
>>
>> Of course this could also be unrelated and caused by some peripheral driver or something but the first suspicion is definitely the power domains.
>>
>> If you have any suggestions for which debug options to enable or where to add some printks, please let me know. If I do another run I would like to make sure that the resulting logs are helpful for debugging.
>>
>> And I would appreciate if someone else could try to reproduce this problem on his/her side. I use this simple script for testing:
>>
>> #!/bin/sh
>>
>> glmark2-es2-drm &
>>
>> while true;
>> do
>>     echo +10 > /sys/class/rtc/rtc0/wakealarm
>>     echo mem > /sys/power/state
>>     sleep 5
>> done;
> 
> Hm, that's unfortunate.
> 
> I'm back from a two week vacation, but it looks like I won't have much
> time available to look into this issue soon. It would be very helpful
> if you could try to pinpoint the hang a bit more.  If you can reproduce
> the hang with no_console_suspend you might be able to extract a bit
> more info in which stage the hang happens (suspend, resume, TF-A, etc.)
> If the hang is in the kernel you might be able to add some prints to
> the suspend/resume paths to be able to track down the exact point of
> the hang.
> 
> I'm happy to look into the issue once it's better known where to look,
> but I fear that I won't have time to do the above investigation myself
> short term. Frieder, is this something you could help with over the
> next few days?

I will see if I can find some time to track down the issue at least a little bit more. But I imagine it could get quite tedious if it takes up to several hours to reproduce the issue and I don't have much time to spare.

@Peng, @Adam and everyone else: Any chance you could setup a similar test and try to reproduce this?

On the other hand reboot cycle testing didn't show any lockup problems over more than 24 hours, so it seems like the issue is limited to resume.


From linus.walleij at linaro.org  Mon Aug  9 04:52:33 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon,  9 Aug 2021 13:52:33 +0200
Subject: [PATCH v3] ARM: Fix Keystone 2 kernel mapping regression
Message-ID: <20210809115233.1009708-1-linus.walleij@linaro.org>

This fixes a Keystone 2 regression discovered as a side effect of
defining an passing the physical start/end sections of the kernel
to the MMU remapping code.

As the Keystone applies an offset to all physical addresses,
including those identified and patches by phys2virt, we fail to
account for this offset in the kernel_sec_start and kernel_sec_end
variables.

Further these offsets can extend into the 64bit range on LPAE
systems such as the Keystone 2.

Fix it like this:
- Extend kernel_sec_start and kernel_sec_end to be 64bit
- Add the offset also to kernel_sec_start and kernel_sec_end

As passing kernel_sec_start and kernel_sec_end as 64bit invariably
incurs BE8 endianness issues I have attempted to dry-code around
these.

Tested on the Vexpress QEMU model both with and without LPAE
enabled.

Fixes: 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel separately")
Reported-by: Nishanth Menon <nmenon at kernel.org>
Suggested-by: Russell King <linux at armlinux.org.uk>
Tested-by: Grygorii Strashko <grygorii.strashko at ti.com>
Tested-by: Nishanth Menon <nmenon at kernel.org>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
ChangeLog v2->v3:
- Fixa BE8 bug, where I was using r8 instead of r3.
ChangeLog v1->v2:
- Better assembly, pass the #4 addition along in the str instruction
  str r8, [r5, #4]
- Collect Tested-by tags from successful boot tests on Keystone 2.
- I will put this into Russell's patch tracker immediately.
---
 arch/arm/include/asm/memory.h |  7 ++++---
 arch/arm/kernel/head.S        | 17 ++++++++++++++---
 arch/arm/mm/mmu.c             |  9 ++++++++-
 arch/arm/mm/pv-fixup-asm.S    |  2 +-
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index cfc9dfd70aad..f673e13e0f94 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -160,10 +160,11 @@ extern unsigned long vectors_base;
 
 /*
  * Physical start and end address of the kernel sections. These addresses are
- * 2MB-aligned to match the section mappings placed over the kernel.
+ * 2MB-aligned to match the section mappings placed over the kernel. We use
+ * u64 so that LPAE mappings beyond the 32bit limit will work out as well.
  */
-extern u32 kernel_sec_start;
-extern u32 kernel_sec_end;
+extern u64 kernel_sec_start;
+extern u64 kernel_sec_end;
 
 /*
  * Physical vs virtual RAM address space conversion.  These are
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 9eb0b4dbcc12..29070eb8df7d 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -49,7 +49,8 @@
 
 	/*
 	 * This needs to be assigned at runtime when the linker symbols are
-	 * resolved.
+	 * resolved. These are unsigned 64bit really, but in this assembly code
+	 * We store them as 32bit.
 	 */
 	.pushsection .data
 	.align	2
@@ -57,7 +58,9 @@
 	.globl	kernel_sec_end
 kernel_sec_start:
 	.long	0
+	.long	0
 kernel_sec_end:
+	.long	0
 	.long	0
 	.popsection
 
@@ -250,7 +253,11 @@ __create_page_tables:
 	add	r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ORDER)
 	ldr	r6, =(_end - 1)
 	adr_l	r5, kernel_sec_start		@ _pa(kernel_sec_start)
-	str	r8, [r5]			@ Save physical start of kernel
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	str	r8, [r5, #4]			@ Save physical start of kernel (BE)
+#else
+	str	r8, [r5]			@ Save physical start of kernel (LE)
+#endif
 	orr	r3, r8, r7			@ Add the MMU flags
 	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
 1:	str	r3, [r0], #1 << PMD_ORDER
@@ -259,7 +266,11 @@ __create_page_tables:
 	bls	1b
 	eor	r3, r3, r7			@ Remove the MMU flags
 	adr_l	r5, kernel_sec_end		@ _pa(kernel_sec_end)
-	str	r3, [r5]			@ Save physical end of kernel
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	str	r3, [r5, #4]			@ Save physical end of kernel (BE)
+#else
+	str	r3, [r5]			@ Save physical end of kernel (LE)
+#endif
 
 #ifdef CONFIG_XIP_KERNEL
 	/*
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 7583bda5ea7d..a4e006005107 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1608,6 +1608,13 @@ static void __init early_paging_init(const struct machine_desc *mdesc)
 	if (offset == 0)
 		return;
 
+	/*
+	 * Offset the kernel section physical offsets so that the kernel
+	 * mapping will work out later on.
+	 */
+	kernel_sec_start += offset;
+	kernel_sec_end += offset;
+
 	/*
 	 * Get the address of the remap function in the 1:1 identity
 	 * mapping setup by the early page table assembly code.  We
@@ -1716,7 +1723,7 @@ void __init paging_init(const struct machine_desc *mdesc)
 {
 	void *zero_page;
 
-	pr_debug("physical kernel sections: 0x%08x-0x%08x\n",
+	pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
 		 kernel_sec_start, kernel_sec_end);
 
 	prepare_page_table();
diff --git a/arch/arm/mm/pv-fixup-asm.S b/arch/arm/mm/pv-fixup-asm.S
index 5c5e1952000a..f8e11f7c7880 100644
--- a/arch/arm/mm/pv-fixup-asm.S
+++ b/arch/arm/mm/pv-fixup-asm.S
@@ -29,7 +29,7 @@ ENTRY(lpae_pgtables_remap_asm)
 	ldr	r6, =(_end - 1)
 	add	r7, r2, #0x1000
 	add	r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
-	add	r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER)
+	add	r7, r7, #KERNEL_OFFSET >> (SECTION_SHIFT - L2_ORDER)
 1:	ldrd	r4, r5, [r7]
 	adds	r4, r4, r0
 	adc	r5, r5, r1
-- 
2.31.1



From krzysztof.kozlowski at canonical.com  Mon Aug  9 05:05:44 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 14:05:44 +0200
Subject: [PATCH 3/3] dt-bindings: clock: samsung: convert Exynos542x to
 dtschema
In-Reply-To: <20210809120544.56596-1-krzysztof.kozlowski@canonical.com>
References: <20210809120544.56596-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210809120544.56596-3-krzysztof.kozlowski@canonical.com>

Merge Exynos542x clock controller bindings to existing DT schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos5420-clock.txt       | 42 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  | 11 ++++-
 2 files changed, 10 insertions(+), 43 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
deleted file mode 100644
index 717a7b1531c7..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-* Samsung Exynos5420 Clock Controller
-
-The Exynos5420 clock controller generates and supplies clock to various
-controllers within the Exynos5420 SoC and for the Exynos5800 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
-  - "samsung,exynos5800-clock" - controller compatible with Exynos5800 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5420.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10010000 {
-		compatible = "samsung,exynos5420-clock";
-		reg = <0x10010000 0x30000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index cd6567bd8cc7..b0f58a1cf6cb 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -18,7 +18,16 @@ description: |
 
 properties:
   compatible:
-    const: samsung,exynos5250-clock
+    oneOf:
+      - enum:
+          - samsung,exynos5250-clock
+          - samsung,exynos5420-clock
+          - samsung,exynos5800-clock
+      - items:
+          - enum:
+              - samsung,exynos5420-clock
+              - samsung,exynos5800-clock
+          - const: syscon
 
   assigned-clocks: true
   assigned-clock-parents: true
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Aug  9 05:05:43 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 14:05:43 +0200
Subject: [PATCH 2/3] dt-bindings: clock: samsung: add bindings for Exynos
 external clock
In-Reply-To: <20210809120544.56596-1-krzysztof.kozlowski@canonical.com>
References: <20210809120544.56596-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210809120544.56596-2-krzysztof.kozlowski@canonical.com>

Document the bindings for Samsung Exynos external to SoC
(oscclk/XXTI/XusbXTI) clock provided on boards.  The bindings are
already implemented in most of the Exynos clock drivers and DTS files.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../clock/samsung,exynos-ext-clock.yaml       | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
new file mode 100644
index 000000000000..64d027dbe3b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-ext-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung SoC external/osc/XXTI/XusbXTI clock
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Samsung SoCs require an external clock supplied through XXTI or XusbXTI pins.
+
+properties:
+  compatible:
+    enum:
+      - samsung,clock-xxti
+      - samsung,clock-xusbxti
+      - samsung,exynos5420-oscclk
+
+  "#clock-cells":
+    const: 0
+
+  clock-frequency: true
+
+  clock-output-names:
+    maxItems: 1
+
+required:
+  - compatible
+  - clock-frequency
+
+additionalProperties: false
+
+examples:
+  - |
+    fixed-rate-clocks {
+        clock {
+            compatible = "samsung,clock-xxti";
+            clock-frequency = <24000000>;
+        };
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Aug  9 05:05:42 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 14:05:42 +0200
Subject: [PATCH 1/3] dt-bindings: clock: samsung: convert Exynos5250 to
 dtschema
Message-ID: <20210809120544.56596-1-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos5250 clock controller bindings to DT schema format
using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos5250-clock.txt       | 41 ----------------
 .../bindings/clock/samsung,exynos-clock.yaml  | 48 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 3 files changed, 49 insertions(+), 41 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
deleted file mode 100644
index aff266a12eeb..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-* Samsung Exynos5250 Clock Controller
-
-The Exynos5250 clock controller generates and supplies clock to various
-controllers within the Exynos5250 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5250.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10010000 {
-		compatible = "samsung,exynos5250-clock";
-		reg = <0x10010000 0x30000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
new file mode 100644
index 000000000000..cd6567bd8cc7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  dt-bindings/clock/ headers.
+
+properties:
+  compatible:
+    const: samsung,exynos5250-clock
+
+  assigned-clocks: true
+  assigned-clock-parents: true
+  assigned-clock-rates: true
+  clocks: true
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5250.h>
+    clock: clock-controller at 10010000 {
+        compatible = "samsung,exynos5250-clock";
+        reg = <0x10010000 0x30000>;
+        #clock-cells = <1>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 36aee8517ab0..2dbacacac3f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16491,6 +16491,7 @@ L:	linux-samsung-soc at vger.kernel.org
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
 F:	Documentation/devicetree/bindings/clock/exynos*.txt
+F:	Documentation/devicetree/bindings/clock/samsung,*.yaml
 F:	Documentation/devicetree/bindings/clock/samsung,s3c*
 F:	Documentation/devicetree/bindings/clock/samsung,s5p*
 F:	drivers/clk/samsung/
-- 
2.30.2



From lkp at intel.com  Mon Aug  9 05:11:29 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 09 Aug 2021 20:11:29 +0800
Subject: [nomadik:ux500-codina-v5.14-rc1] BUILD SUCCESS
 fec8a598bb9304ac82cb470fbf49c2378a1e1efe
Message-ID: <61111b71.NlDeNQIYb94c8C0p%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-codina-v5.14-rc1
branch HEAD: fec8a598bb9304ac82cb470fbf49c2378a1e1efe  brcmfmac: firmware: Fix firmware loading

elapsed time: 725m

configs tested: 165
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
arm                                 defconfig
mips                      fuloong2e_defconfig
mips                      malta_kvm_defconfig
powerpc                 canyonlands_defconfig
arm                       spear13xx_defconfig
ia64                             alldefconfig
mips                           ip27_defconfig
arm                      tct_hammer_defconfig
powerpc                         wii_defconfig
openrisc                    or1ksim_defconfig
arm                         nhk8815_defconfig
powerpc                 mpc8272_ads_defconfig
powerpc                      obs600_defconfig
arm                       aspeed_g5_defconfig
m68k                         amcore_defconfig
powerpc                      ppc64e_defconfig
powerpc                   microwatt_defconfig
xtensa                           allyesconfig
h8300                     edosk2674_defconfig
sh                          r7785rp_defconfig
powerpc                     ksi8560_defconfig
sh                        edosk7705_defconfig
arm                       mainstone_defconfig
m68k                       m5475evb_defconfig
arm                    vt8500_v6_v7_defconfig
sh                         apsh4a3a_defconfig
sh                          sdk7786_defconfig
arm                          lpd270_defconfig
arc                          axs103_defconfig
riscv                            alldefconfig
mips                        jmr3927_defconfig
m68k                       bvme6000_defconfig
powerpc                    klondike_defconfig
sh                           se7343_defconfig
m68k                          atari_defconfig
riscv                             allnoconfig
powerpc                     tqm8541_defconfig
mips                       capcella_defconfig
arm                      pxa255-idp_defconfig
sh                          rsk7201_defconfig
h8300                            allyesconfig
sh                          polaris_defconfig
powerpc                     ep8248e_defconfig
powerpc                 mpc832x_mds_defconfig
powerpc                      ppc44x_defconfig
sh                      rts7751r2d1_defconfig
powerpc                 xes_mpc85xx_defconfig
arm                          badge4_defconfig
powerpc                        cell_defconfig
mips                        vocore2_defconfig
arm                       aspeed_g4_defconfig
arm                       imx_v4_v5_defconfig
arm                          moxart_defconfig
sh                             sh03_defconfig
powerpc                     rainier_defconfig
arm                        realview_defconfig
mips                         tb0287_defconfig
powerpc                      ep88xc_defconfig
powerpc64                           defconfig
m68k                        stmark2_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                    sam440ep_defconfig
m68k                            q40_defconfig
arc                      axs103_smp_defconfig
mips                      pistachio_defconfig
powerpc                 mpc837x_rdb_defconfig
mips                     loongson1b_defconfig
powerpc                     tqm8555_defconfig
powerpc                 mpc834x_mds_defconfig
arm                           sunxi_defconfig
sh                          urquell_defconfig
mips                     loongson1c_defconfig
powerpc                       holly_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
x86_64               randconfig-a002-20210809
x86_64               randconfig-a004-20210809
x86_64               randconfig-a006-20210809
x86_64               randconfig-a003-20210809
x86_64               randconfig-a001-20210809
x86_64               randconfig-a005-20210809
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210809
x86_64               randconfig-c001-20210808
x86_64               randconfig-a002-20210808
x86_64               randconfig-a004-20210808
x86_64               randconfig-a006-20210808
x86_64               randconfig-a003-20210808
x86_64               randconfig-a001-20210808
x86_64               randconfig-a005-20210808

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Mon Aug  9 05:11:13 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 09 Aug 2021 20:11:13 +0800
Subject: [nomadik:ixp4xx-dts-arm-soc-v5.15] BUILD SUCCESS
 f2841e3ab175da656e9124a9b032daf5a86c7ade
Message-ID: <61111b61.tsWg1RnmEAzo6jU3%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-dts-arm-soc-v5.15
branch HEAD: f2841e3ab175da656e9124a9b032daf5a86c7ade  ARM: dts: ixp4xx: Add a devicetree for Freecom FSG-3

elapsed time: 725m

configs tested: 168
configs skipped: 86

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
mips                           ip27_defconfig
arm                      tct_hammer_defconfig
powerpc                         wii_defconfig
openrisc                    or1ksim_defconfig
arm                         nhk8815_defconfig
powerpc                 mpc8272_ads_defconfig
powerpc                      obs600_defconfig
arm                       aspeed_g5_defconfig
m68k                         amcore_defconfig
powerpc                      ppc64e_defconfig
powerpc                   microwatt_defconfig
arm                       mainstone_defconfig
m68k                       m5475evb_defconfig
powerpc                      ppc44x_defconfig
arm                         lpc18xx_defconfig
powerpc                     taishan_defconfig
arm                        keystone_defconfig
x86_64                            allnoconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
m68k                            q40_defconfig
sh                         apsh4a3a_defconfig
sh                          sdk7786_defconfig
arm                          lpd270_defconfig
arc                          axs103_defconfig
powerpc                      tqm8xx_defconfig
arm                        clps711x_defconfig
mips                      malta_kvm_defconfig
powerpc                     skiroot_defconfig
powerpc                     kmeter1_defconfig
h8300                     edosk2674_defconfig
riscv                            alldefconfig
mips                        jmr3927_defconfig
m68k                       bvme6000_defconfig
m68k                          atari_defconfig
sh                           se7343_defconfig
riscv                             allnoconfig
powerpc                     tqm8541_defconfig
mips                       capcella_defconfig
arm                      pxa255-idp_defconfig
sh                          rsk7201_defconfig
sh                      rts7751r2d1_defconfig
powerpc                 xes_mpc85xx_defconfig
arm                          badge4_defconfig
powerpc                        cell_defconfig
mips                        vocore2_defconfig
arm                       aspeed_g4_defconfig
arm                       imx_v4_v5_defconfig
arm                          moxart_defconfig
sh                             sh03_defconfig
powerpc                     rainier_defconfig
arm                        realview_defconfig
mips                         tb0287_defconfig
powerpc                      ep88xc_defconfig
powerpc64                           defconfig
m68k                        stmark2_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                    sam440ep_defconfig
arc                      axs103_smp_defconfig
mips                      pistachio_defconfig
powerpc                 mpc837x_rdb_defconfig
mips                     loongson1b_defconfig
powerpc                     tqm8555_defconfig
powerpc                 mpc834x_mds_defconfig
arm                           sunxi_defconfig
sh                          urquell_defconfig
mips                     loongson1c_defconfig
powerpc                       holly_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
x86_64               randconfig-a002-20210809
x86_64               randconfig-a004-20210809
x86_64               randconfig-a006-20210809
x86_64               randconfig-a003-20210809
x86_64               randconfig-a001-20210809
x86_64               randconfig-a005-20210809
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210809
x86_64               randconfig-c001-20210808
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809
x86_64               randconfig-a002-20210808
x86_64               randconfig-a004-20210808
x86_64               randconfig-a006-20210808
x86_64               randconfig-a003-20210808
x86_64               randconfig-a001-20210808
x86_64               randconfig-a005-20210808

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Mon Aug  9 05:11:21 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 09 Aug 2021 20:11:21 +0800
Subject: [nomadik:ux500-cleanups] BUILD SUCCESS
 4152dae62240c77ff56dbd239afd9b45f6dbf6a1
Message-ID: <61111b69.SQz9RnIkdP01baxZ%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-cleanups
branch HEAD: 4152dae62240c77ff56dbd239afd9b45f6dbf6a1  watchdog: db8500_wdt: Rename symbols

elapsed time: 725m

configs tested: 175
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
mips                           ip27_defconfig
arm                      tct_hammer_defconfig
powerpc                         wii_defconfig
openrisc                    or1ksim_defconfig
arm                         nhk8815_defconfig
powerpc                 mpc8272_ads_defconfig
powerpc                      obs600_defconfig
arm                       aspeed_g5_defconfig
m68k                         amcore_defconfig
powerpc                      ppc64e_defconfig
powerpc                   microwatt_defconfig
xtensa                           allyesconfig
h8300                     edosk2674_defconfig
sh                          r7785rp_defconfig
powerpc                     ksi8560_defconfig
sh                        edosk7705_defconfig
arm                       mainstone_defconfig
m68k                       m5475evb_defconfig
arm                         lpc18xx_defconfig
powerpc                     taishan_defconfig
arm                        keystone_defconfig
x86_64                            allnoconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
sh                         apsh4a3a_defconfig
sh                          sdk7786_defconfig
arm                          lpd270_defconfig
arc                          axs103_defconfig
riscv                            alldefconfig
mips                        jmr3927_defconfig
m68k                       bvme6000_defconfig
powerpc                    klondike_defconfig
sh                           se7343_defconfig
m68k                          atari_defconfig
riscv                             allnoconfig
powerpc                     tqm8541_defconfig
mips                       capcella_defconfig
arm                      pxa255-idp_defconfig
sh                          rsk7201_defconfig
h8300                            allyesconfig
sh                          polaris_defconfig
powerpc                     ep8248e_defconfig
powerpc                 mpc832x_mds_defconfig
powerpc                      ppc44x_defconfig
sh                      rts7751r2d1_defconfig
powerpc                 xes_mpc85xx_defconfig
arm                          badge4_defconfig
powerpc                        cell_defconfig
mips                        vocore2_defconfig
mips                     cu1830-neo_defconfig
sh                          sdk7780_defconfig
mips                       bmips_be_defconfig
mips                  decstation_64_defconfig
powerpc                     stx_gp3_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                       aspeed_g4_defconfig
arm                       imx_v4_v5_defconfig
arm                          moxart_defconfig
sh                             sh03_defconfig
powerpc                     rainier_defconfig
arm                        realview_defconfig
mips                         tb0287_defconfig
powerpc                      ep88xc_defconfig
powerpc64                           defconfig
m68k                        stmark2_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                    sam440ep_defconfig
m68k                            q40_defconfig
arc                      axs103_smp_defconfig
mips                      pistachio_defconfig
mips                     loongson1b_defconfig
powerpc                     tqm8555_defconfig
powerpc                 mpc834x_mds_defconfig
arm                           sunxi_defconfig
sh                          urquell_defconfig
mips                     loongson1c_defconfig
powerpc                       holly_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
x86_64               randconfig-a002-20210809
x86_64               randconfig-a004-20210809
x86_64               randconfig-a006-20210809
x86_64               randconfig-a003-20210809
x86_64               randconfig-a001-20210809
x86_64               randconfig-a005-20210809
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210809
x86_64               randconfig-c001-20210808
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809
x86_64               randconfig-a002-20210808
x86_64               randconfig-a004-20210808
x86_64               randconfig-a006-20210808
x86_64               randconfig-a003-20210808
x86_64               randconfig-a001-20210808
x86_64               randconfig-a005-20210808

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Mon Aug  9 05:11:17 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 09 Aug 2021 20:11:17 +0800
Subject: [nomadik:ux500-href-charging-v5.14-rc1] BUILD SUCCESS
 98c04e935ab81896ea0cdade87d92531782d0d54
Message-ID: <61111b65.wGlRX3aejC5crgI+%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-href-charging-v5.14-rc1
branch HEAD: 98c04e935ab81896ea0cdade87d92531782d0d54  dt-bindings: power: Bindings for Samsung batteries

elapsed time: 725m

configs tested: 172
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
mips                           ip27_defconfig
arm                      tct_hammer_defconfig
powerpc                         wii_defconfig
openrisc                    or1ksim_defconfig
arm                         nhk8815_defconfig
powerpc                 mpc8272_ads_defconfig
powerpc                      obs600_defconfig
arm                       aspeed_g5_defconfig
m68k                         amcore_defconfig
powerpc                      ppc64e_defconfig
powerpc                   microwatt_defconfig
xtensa                           allyesconfig
h8300                     edosk2674_defconfig
sh                          r7785rp_defconfig
powerpc                     ksi8560_defconfig
sh                        edosk7705_defconfig
arm                       mainstone_defconfig
m68k                       m5475evb_defconfig
arm                         lpc18xx_defconfig
powerpc                     taishan_defconfig
arm                        keystone_defconfig
x86_64                            allnoconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
sh                         apsh4a3a_defconfig
sh                          sdk7786_defconfig
arm                          lpd270_defconfig
arc                          axs103_defconfig
powerpc                      tqm8xx_defconfig
arm                        clps711x_defconfig
powerpc                          allyesconfig
mips                      malta_kvm_defconfig
powerpc                     skiroot_defconfig
powerpc                     kmeter1_defconfig
riscv                            alldefconfig
mips                        jmr3927_defconfig
m68k                       bvme6000_defconfig
powerpc                    klondike_defconfig
sh                           se7343_defconfig
m68k                          atari_defconfig
riscv                             allnoconfig
powerpc                     tqm8541_defconfig
mips                       capcella_defconfig
arm                      pxa255-idp_defconfig
sh                          rsk7201_defconfig
h8300                            allyesconfig
sh                          polaris_defconfig
powerpc                     ep8248e_defconfig
powerpc                 mpc832x_mds_defconfig
powerpc                      ppc44x_defconfig
sh                      rts7751r2d1_defconfig
powerpc                 xes_mpc85xx_defconfig
arm                          badge4_defconfig
powerpc                        cell_defconfig
mips                        vocore2_defconfig
arm                       aspeed_g4_defconfig
arm                       imx_v4_v5_defconfig
arm                          moxart_defconfig
sh                             sh03_defconfig
powerpc                     rainier_defconfig
arm                        realview_defconfig
mips                         tb0287_defconfig
powerpc                      ep88xc_defconfig
powerpc64                           defconfig
m68k                        stmark2_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                    sam440ep_defconfig
m68k                            q40_defconfig
arc                      axs103_smp_defconfig
mips                      pistachio_defconfig
powerpc                 mpc837x_rdb_defconfig
sh                          urquell_defconfig
mips                     loongson1b_defconfig
mips                     loongson1c_defconfig
powerpc                       holly_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
x86_64               randconfig-a002-20210809
x86_64               randconfig-a004-20210809
x86_64               randconfig-a006-20210809
x86_64               randconfig-a003-20210809
x86_64               randconfig-a001-20210809
x86_64               randconfig-a005-20210809
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210809
x86_64               randconfig-c001-20210808
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809
x86_64               randconfig-a002-20210808
x86_64               randconfig-a004-20210808
x86_64               randconfig-a006-20210808
x86_64               randconfig-a003-20210808
x86_64               randconfig-a001-20210808
x86_64               randconfig-a005-20210808

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Mon Aug  9 05:11:19 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 09 Aug 2021 20:11:19 +0800
Subject: [nomadik:ixp4xx-drivers-arm-soc-v5.15] BUILD SUCCESS
 3ec768bf8ef418ba07ffed3b9de57f630405ae92
Message-ID: <61111b67.0ZlwILYou1+WC1X4%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-drivers-arm-soc-v5.15
branch HEAD: 3ec768bf8ef418ba07ffed3b9de57f630405ae92  bus: ixp4xx: return on error in ixp4xx_exp_probe()

elapsed time: 725m

configs tested: 175
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
mips                           ip27_defconfig
arm                      tct_hammer_defconfig
powerpc                         wii_defconfig
openrisc                    or1ksim_defconfig
arm                         nhk8815_defconfig
powerpc                 mpc8272_ads_defconfig
powerpc                      obs600_defconfig
arm                       aspeed_g5_defconfig
m68k                         amcore_defconfig
powerpc                      ppc64e_defconfig
powerpc                   microwatt_defconfig
xtensa                           allyesconfig
h8300                     edosk2674_defconfig
sh                          r7785rp_defconfig
powerpc                     ksi8560_defconfig
sh                        edosk7705_defconfig
arm                       mainstone_defconfig
m68k                       m5475evb_defconfig
arm                         lpc18xx_defconfig
powerpc                     taishan_defconfig
arm                        keystone_defconfig
x86_64                            allnoconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
m68k                            q40_defconfig
sh                         apsh4a3a_defconfig
sh                          sdk7786_defconfig
arm                          lpd270_defconfig
arc                          axs103_defconfig
riscv                            alldefconfig
mips                        jmr3927_defconfig
m68k                       bvme6000_defconfig
powerpc                    klondike_defconfig
sh                           se7343_defconfig
m68k                          atari_defconfig
riscv                             allnoconfig
powerpc                     tqm8541_defconfig
mips                       capcella_defconfig
arm                      pxa255-idp_defconfig
sh                          rsk7201_defconfig
sh                          polaris_defconfig
powerpc                     ep8248e_defconfig
powerpc                 mpc832x_mds_defconfig
powerpc                      ppc44x_defconfig
h8300                            allyesconfig
sh                      rts7751r2d1_defconfig
powerpc                 xes_mpc85xx_defconfig
arm                          badge4_defconfig
powerpc                        cell_defconfig
mips                        vocore2_defconfig
powerpc                       maple_defconfig
mips                     cu1000-neo_defconfig
powerpc                     asp8347_defconfig
arc                        nsim_700_defconfig
s390                             alldefconfig
arm                       aspeed_g4_defconfig
arm                       imx_v4_v5_defconfig
arm                          moxart_defconfig
sh                             sh03_defconfig
powerpc                     rainier_defconfig
arm                        realview_defconfig
mips                         tb0287_defconfig
powerpc                      ep88xc_defconfig
powerpc64                           defconfig
m68k                        stmark2_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                    sam440ep_defconfig
arc                      axs103_smp_defconfig
mips                      pistachio_defconfig
powerpc                 mpc837x_rdb_defconfig
mips                     loongson1b_defconfig
powerpc                     tqm8555_defconfig
powerpc                 mpc834x_mds_defconfig
arm                           sunxi_defconfig
sh                          urquell_defconfig
mips                     loongson1c_defconfig
powerpc                       holly_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
x86_64               randconfig-a002-20210809
x86_64               randconfig-a004-20210809
x86_64               randconfig-a006-20210809
x86_64               randconfig-a003-20210809
x86_64               randconfig-a001-20210809
x86_64               randconfig-a005-20210809
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210809
x86_64               randconfig-c001-20210808
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809
x86_64               randconfig-a002-20210808
x86_64               randconfig-a004-20210808
x86_64               randconfig-a006-20210808
x86_64               randconfig-a003-20210808
x86_64               randconfig-a001-20210808
x86_64               randconfig-a005-20210808

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From marex at denx.de  Mon Aug  9 05:13:24 2021
From: marex at denx.de (Marek Vasut)
Date: Mon,  9 Aug 2021 14:13:24 +0200
Subject: [PATCH] ARM: dts: stm32: Reduce DHCOR SPI NOR frequency to 50 MHz
Message-ID: <20210809121324.155219-1-marex@denx.de>

The SPI NOR is a bit further away from the SoC on DHCOR than on DHCOM,
which causes additional signal delay. At 108 MHz, this delay triggers
a sporadic issue where the first bit of RX data is not received by the
QSPI controller.

There are two options of addressing this problem, either by using the
DLYB block to compensate the extra delay, or by reducing the QSPI bus
clock frequency. The former requires calibration and that is overly
complex, so opt for the second option.

Fixes: 76045bc457104 ("ARM: dts: stm32: Add QSPI NOR on AV96")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
index 2b0ac605549d7..44ecc47085871 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
@@ -202,7 +202,7 @@ flash0: flash at 0 {
 		compatible = "jedec,spi-nor";
 		reg = <0>;
 		spi-rx-bus-width = <4>;
-		spi-max-frequency = <108000000>;
+		spi-max-frequency = <50000000>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 	};
-- 
2.30.2



From ulf.hansson at linaro.org  Mon Aug  9 05:13:18 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 9 Aug 2021 14:13:18 +0200
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <MWHPR11MB1789D2B707B39CB42322C73A8CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
 <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
 <YRDqQvKQ71/824Lu@matsya>
 <MWHPR11MB1789D2B707B39CB42322C73A8CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
Message-ID: <CAPDyKFp5HcCfsoLgBc=D9RKOrVY2SuV3FKsFCVT2=WaxZBsNiA@mail.gmail.com>

On Mon, 9 Aug 2021 at 13:17, A, Rashmi <rashmi.a at intel.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Vinod Koul <vkoul at kernel.org>
> > Sent: Monday, August 9, 2021 2:12 PM
> > To: A, Rashmi <rashmi.a at intel.com>
> > Cc: Ulf Hansson <ulf.hansson at linaro.org>; Michal Simek
> > <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>; Linux
> > ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
> > kernel at vger.kernel.org>; Kishon <kishon at ti.com>; Andy Shevchenko
> > <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org; Mark
> > Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou, Furong
> > <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> > <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> > <adrian.hunter at intel.com>; Vaidya, Mahesh R
> > <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> > <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> > <kenchappa.demakkanavar at intel.com>
> > Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
> > support to the arasan eMMC driver
> >
> > On 09-08-21, 05:16, A, Rashmi wrote:
> >
> > > >
> > > > Rashmi, is it safe to apply this separately from the phy driver/dt changes?
> > > > Then I can queue this via my mmc tree, if you like.
> > > No, the phy driver/dt changes must go together with "mmc: sdhci-of-
> > arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver"
> > patch.
> >
> > Why is that?
> >
> > What could happen, emmc driver will complain about phy not found and bail
> > right?
> This is right, but ideally both mmc:phy and mmc: sdhci-of-arasan driver code changes should go together

If patches are well written and can be standalone, we (maintainers)
ideally prefer to queue things on a per subsystem basis, because it's
just easier.

That said, I also noticed that a new compatible string was added,
"intel,thunderbay-sdhci-5.1". This needs to be documented in
Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml, in a separate
patch, preceding $subject patch.

Kind regards
Uffe


From matthias.bgg at gmail.com  Mon Aug  9 05:19:57 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Mon, 9 Aug 2021 14:19:57 +0200
Subject: [GIT PULL] drivers: soc: mediatek: updates for v5.15
Message-ID: <49fc7bef-20db-b98c-9437-dd9e4d00e870@gmail.com>

Hi Olof,
Hi Arnd,

Please have a look for the updates of the SoC drivers for Mediatek. If you
wonder why there is no binding patch for the MT8365 mmsys: The binding was
converted to YAML. This got taken by Rob. To minimize merge conflicts I left it
to him to take other mmsys binding patches. Unfortunately there is one mmsys
binding patch taken by Stephen through the clock tree. So there will be a
trivial merge conflict (although not in your tree). A bit of a mess this time,
I'll try to make sure that the bindings for drivers/soc will go through my tree
in the future (which will make my life easier as well...).

Regards,
Matthias

---
The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/
tags/v5.14-next-soc

for you to fetch changes up to 25423731956b3d72bc35d336227c88ada49148e8:

  soc: mediatek: mmsys: Fix missing UFOE component in mt8173 table routing
(2021-08-06 16:43:23 +0200)

----------------------------------------------------------------
pm-domains:
- correct mask define if used for update on TOPAXI bus
- mt8173: enable regulator befor turning on MFG_ASYNC

mmsys:
- add a mask property to the routing information
- add support for MT8365
- add UFOE routing for MT8173

----------------------------------------------------------------
Bilal Wasim (2):
      soc: mediatek: pm-domains: Use correct mask for bus_prot_clr
      soc: mediatek: pm-domains: Add domain_supply cap for mfg_async PD

CK Hu (1):
      soc: mmsys: mediatek: add mask to mmsys routes

Enric Balletbo i Serra (1):
      soc: mediatek: mmsys: Fix missing UFOE component in mt8173 table routing

Fabien Parent (1):
      soc: mediatek: mmsys: add MT8365 support

 drivers/soc/mediatek/mt8173-pm-domains.h |   1 +
 drivers/soc/mediatek/mt8183-mmsys.h      |  21 +++--
 drivers/soc/mediatek/mt8365-mmsys.h      |  60 ++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c         |  18 +++-
 drivers/soc/mediatek/mtk-mmsys.h         | 137 ++++++++++++++++++++++---------
 drivers/soc/mediatek/mtk-pm-domains.h    |   2 +-
 6 files changed, 189 insertions(+), 50 deletions(-)
 create mode 100644 drivers/soc/mediatek/mt8365-mmsys.h


From matthias.bgg at gmail.com  Mon Aug  9 05:20:03 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Mon, 9 Aug 2021 14:20:03 +0200
Subject: [GIT PULL] ARM: dts32 updates for v5.15
Message-ID: <289ded1c-dae7-54ef-6b56-9433bfcaf9de@gmail.com>

Hi Olof and Arnd,

Please have a look on the single patch in this pull request for arm32 MediaTek.

Thanks,
Matthias

---
The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/
tags/v5.14-next-dts32

for you to fetch changes up to 293cb6b0ea19e628388959da4baa9558e891afc0:

  arm: dts: mt7623: increase passive cooling trip (2021-08-04 19:14:26 +0200)

----------------------------------------------------------------
Increase trip point on MT7623

----------------------------------------------------------------
Frank Wunderlich (1):
      arm: dts: mt7623: increase passive cooling trip

 arch/arm/boot/dts/mt7623.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


From matthias.bgg at gmail.com  Mon Aug  9 05:20:11 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Mon, 9 Aug 2021 14:20:11 +0200
Subject: [GIT PULL] arm64: dts updates for v5.15
Message-ID: <26c4026a-9f26-d5a3-c30f-439120a4eaa0@gmail.com>

Hi Arnd and Olof,

Please have a look for the arm64 DTS updates. This time we only have smaller
changes for existing boards, but no new HW. But don't worry, probably for v5.16
we will see some new SoCs.

Regards,
Matthias

---
The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/
tags/v5.14-next-dts64

for you to fetch changes up to ce5db043d2e8811f30de3ebb5d9e6bd8a33596c4:

  dt-bindings: mediatek: Add optional mediatek,gce-events property (2021-08-05
17:37:54 +0200)

----------------------------------------------------------------
MT8173:
- Add regulator for MFG_ASYNC power domain
- Use alias for MMC to get fixed numbers

MT8183:
- Use alia for MMC to get fixed numbers
- Add optional event number for Global Comman Engine

----------------------------------------------------------------
Bilal Wasim (1):
      arm64: dts: mediatek: mt8173: Add domain supply for mfg_async

Hsin-Yi Wang (4):
      arm64: dts: mt8183: kukui: Use aliases to mmc nodes
      arm64: dts: mt8173: elm: Use aliases to mmc nodes
      arm64: dts: mt8183: add mediatek,gce-events in mutex
      dt-bindings: mediatek: Add optional mediatek,gce-events property

 Documentation/devicetree/bindings/mailbox/mtk-gce.txt | 15 +++++++++++++++
 arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi          | 10 ++++++++++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts           |  4 ++++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi              |  2 +-
 arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi        |  2 ++
 arch/arm64/boot/dts/mediatek/mt8183.dtsi              |  2 ++
 6 files changed, 34 insertions(+), 1 deletion(-)


From narmstrong at baylibre.com  Mon Aug  9 05:22:21 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 9 Aug 2021 14:22:21 +0200
Subject: [PATCH] ARM: oxnas: Add basic support for Zyxel NSA210
In-Reply-To: <20210809104351.2050187-1-uwe@kleine-koenig.org>
References: <20210809104351.2050187-1-uwe@kleine-koenig.org>
Message-ID: <a082058f-365a-8990-7bb1-cf34fa58b166@baylibre.com>

Hi,

On 09/08/2021 12:43, Uwe Kleine-K?nig wrote:
> This is a one bay NAS originally shipping Linux 2.6.24.4. It features
> 
>  - 128 MiB RAM
>  - 2x eSATA (1x internal, 1x external)
>  - 2x USB 2.0
>  - 4 MiB NOR
>  - battery powered RTC on i2c (PCF8563)
>  - 1x GBit ethernet
> 
> For now only the low-hanging fruits are added to the device tree, eSATA,
> USB, i2c and networking needs more work as there are no drivers
> available.
> 
> Such a machine was offered to me by Richard Fr?hning. Thanks!

Thanks for posting this !

> 
> Signed-off-by: Uwe Kleine-K?nig <uwe at kleine-koenig.org>
> ---
>  .../devicetree/bindings/arm/oxnas.txt         |   1 +
>  arch/arm/boot/dts/Makefile                    |   1 +
>  arch/arm/boot/dts/ox810se-zyxel-nsa210.dts    | 156 ++++++++++++++++++
>  3 files changed, 158 insertions(+)
>  create mode 100644 arch/arm/boot/dts/ox810se-zyxel-nsa210.dts
> 
> diff --git a/Documentation/devicetree/bindings/arm/oxnas.txt b/Documentation/devicetree/bindings/arm/oxnas.txt
> index ac64e60f99f1..c1529d6c9666 100644
> --- a/Documentation/devicetree/bindings/arm/oxnas.txt
> +++ b/Documentation/devicetree/bindings/arm/oxnas.txt
> @@ -11,4 +11,5 @@ Boards with the OX820 SoC shall have the following properties:
>  
>  Board compatible values:
>    - "wd,mbwe" (OX810SE)
> +  - "zyxel,nsa210" (OX810SE)
>    - "cloudengines,pogoplugv3" (OX820)
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 863347b6b65e..720b7d7e342a 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -913,6 +913,7 @@ dtb-$(CONFIG_ARCH_PXA) += \
>  	pxa300-raumfeld-speaker-s.dtb
>  dtb-$(CONFIG_ARCH_OXNAS) += \
>  	ox810se-wd-mbwe.dtb \
> +	ox810se-zyxel-nsa210.dtb \
>  	ox820-cloudengines-pogoplug-series-3.dtb
>  dtb-$(CONFIG_ARCH_QCOM) += \
>  	qcom-apq8060-dragonboard.dtb \
> diff --git a/arch/arm/boot/dts/ox810se-zyxel-nsa210.dts b/arch/arm/boot/dts/ox810se-zyxel-nsa210.dts
> new file mode 100644
> index 000000000000..88d0e065cf99
> --- /dev/null
> +++ b/arch/arm/boot/dts/ox810se-zyxel-nsa210.dts
> @@ -0,0 +1,156 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Device tree file for Zyxel NSA-210
> + */
> +
> +/dts-v1/;
> +#include "ox810se.dtsi"
> +#include <dt-bindings/gpio/gpio.h>
> +
> +/ {
> +	model = "Zyxel NSA-210";
> +
> +	compatible = "zyxel,nsa210", "oxsemi,ox810se";
> +
> +	chosen {
> +		bootargs = "console=ttyS2,115200n8";
> +	};
> +
> +	memory {
> +		reg = <0x48000000 0x8000000>;
> +	};
> +
> +	aliases {
> +		serial2 = &uart2;
> +	};
> +
> +	flash at 41000000 {
> +		compatible = "cfi-flash";
> +		reg = <0x41000000 0x00400000>;
> +		bank-width = <1>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			partitions at 0 {
> +				label = "uboot";
> +				reg = <0x00000000 0x00020000>;
> +			};
> +
> +			partitions at 1 {
> +				label = "kernel";
> +				reg = <0x00020000 0x001c0000>;
> +			};
> +
> +			partitions at 2 {
> +				label = "initrd";
> +				reg = <0x001e0000 0x001a0000>;
> +			};
> +
> +			partitions at 3 {
> +				label = "etc";
> +				reg = <0x00380000 0x00070000>;
> +			};
> +
> +			/* 448k gap */
> +
> +			partitions at 4 {
> +				label = "env1";
> +				reg = <0x003fc000 0x00002000>;
> +			};
> +
> +			partitions at 5 {
> +				label = "env2";
> +				reg = <0x003fe000 0x00002000>;
> +			};
> +		};
> +	};
> +
> +	keys {
> +		compatible = "gpio-keys";
> +
> +		reset {
> +			label = "Reset";
> +			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		power {
> +			label = "Power";
> +			gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		sync {
> +			label = "Copy/Sync";
> +			gpio = <&gpio0 10 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		/*
> +		 * The vendor U-Boot enables a PWM to make this LED blink during boot.
> +		 * This must be disabled to be able to drive the LED using the
> +		 * GPIO as defined here by unsetting bit 9 in the
> +		 * SYS_CTRL_GPIO_PWMSEL_CTRL_0 register.
> +		 * E.g. do before starting Linux: mw 0x4500009c 0
> +		 */
> +		led1 {
> +			label = "nsa210:green:sys";
> +			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
> +		};

In order to support this usecase, the oxnas pinctrl driver could be augmented to handle this PWMSEL mux.

> +
> +		led2 {
> +			label = "nsa210:red:hdd";
> +			gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led3 {
> +			label = "nsa210:green:hdd";
> +			gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led4 {
> +			label = "nsa210:red:usb";
> +			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led5 {
> +			label = "nsa210:green:usb";
> +			gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led6 {
> +			label = "nsa210:red:esata";
> +			gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led7 {
> +			label = "nsa210:green:esata";
> +			gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led8 {
> +			label = "nsa210:red:copy";
> +			gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led9 {
> +			label = "nsa210:green:copy";
> +			gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +};
> +
> +&uart2 {
> +	/*
> +	 * To make this device work as expected bit 2 of register
> +	 * SYS_CTRL_UART_CTRL must be set. Otherwise the interrupt doesn't
> +	 * trigger, so console messages make it through, but userspace cannot
> +	 * make use of it.
> +	 * E.g. do before starting Linux: mw 0x45000094 4
> +	 */
> +	status = "okay";
> +};
> 

This one should be handled by adding an oxnas ns16550a variant with access to the &sys syscon to setup
the UART.

Neil


From hverkuil-cisco at xs4all.nl  Mon Aug  9 05:31:00 2021
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Mon, 9 Aug 2021 14:31:00 +0200
Subject: [PATCH v7 00/14] media: mtk-vcodec: support for MT8183 decoder
In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com>
References: <20210806041530.4170869-1-tzungbi@google.com>
Message-ID: <104309d4-0973-cf1f-d61f-731b0642c1cf@xs4all.nl>

Hi Tzung-Bi,

I made a PR for this series, but I would like a follow-up patch that fixes this
sparse warning:

SPARSE:mtk-vcodec/mtk_vcodec_dec_stateful.c:615:35: warning: symbol 'mtk_vdec_8173_pdata' was not declared. Should it be static?
SPARSE:mtk-vcodec/mtk_vcodec_dec_stateless.c:346:35: warning: symbol 'mtk_vdec_8183_pdata' was not declared. Should it be static?

mtk_vcodec_dec.h is probably a good header to put the extern declaration.

Regards,

	Hans

On 06/08/2021 06:15, Tzung-Bi Shih wrote:
> This series adds support for the stateless API into mtk-vcodec, by first
> separating the stateful ops into their own source file, and introducing
> a new set of ops suitable for stateless decoding. As such, support for
> stateful decoders should remain completely unaffected.
> 
> This series has been tested with both MT8183 and MT8173. Decoding was
> working for both chips, and in the case of MT8173 no regression has been
> spotted.
> 
> Patches 1-5 fix a few compliance issues with the decoder and encoder, most
> notably by adding support for the START and STOP command for the latter. These
> patches were last up until v4 but have been moved to the beginning so they can
> be applied sooner.
> 
> Patches 6-9 separates the "stateful" part of the driver into its own file and
> add support for the new firmware and pixel format used by MT8183.
> 
> Patches 10-14 add support for H.264 stateless decoding and MT8183.
> 
> Note that a few checkpatch issues have been left unadressed on purpose:
> * Conversion from e.g. uint32_t to u32 can't be done without breaking
>   consistency. This should be done by a driver-wide patch.
> * Some macro warning suggesting parentheses for parameters expanded as struct
>   members, which is obviously not applicable here.
> * Warnings about adding new files without an update the MAINTAINERS, which is
>   irrelevant as the new files are already covered by the existing wildcards.
> 
> Changes since v6:
> (https://patchwork.linuxtv.org/project/linux-media/cover/20210705053258.1614177-1-acourbot at chromium.org/)
> * Fix errors from 'checkpatch.pl --strict'.
> * Fix missing kerneldoc issue.
> * Fix wrong device minor number reference.
> 
> Changes since v5:
> * Rebased against latest media tree.
> * Applied most suggestions of `checkpatch.pl --strict`. Some proposed fixes were
>   not applied because they would require a larger refactoring (i.e. large-scale
>   type changes) of the code.
> * Applied Reviewed-by and fix suggestions from Tzung-bi.
> * Check for ABORT state in vidioc_encoder_cmd.
> 
> Changes since v4:
> * Reorganized fixup patches first.
> * Select MEDIA_CONTROLLER_REQUEST_API.
> * Properly capitalize MM21's format description string.
> * Reorganize stateless code as suggested by Hans.
> * Fix compilation errors when DEBUG is defined.
> * Merge double-free fixup patch into the patch that introduced the issue.
> 
> Changes since v3:
> * Stop checking that controls are set for every request.
> * Add V4L2_CID_STATELESS_H264_START_CODE control.
> * Stop mapping OUTPUT buffers and getting the NAL type from them, use the
>   nal_ref_idc field instead.
> * Make V4L2_CID_MIN_BUFFERS_FOR_CAPTURE control stateful-only.
> * Set vb2_buffer's field to V4L2_FIELD_NONE in buffer validation hook.
> 
> Changes since v2:
> * Add follow-up patches fixing support for START/STOP commands for the
>   encoder, and stateful decoder.
> 
> Alexandre Courbot (8):
>   media: mtk-vcodec: vdec: use helpers in VIDIOC_(TRY_)DECODER_CMD
>   media: mtk-vcodec: vdec: clamp OUTPUT resolution to hardware limits
>   media: mtk-vcodec: make flush buffer reusable by encoder
>   media: mtk-vcodec: venc: support START and STOP commands
>   media: mtk-vcodec: vdec: handle firmware version field
>   media: mtk-vcodec: support version 2 of decoder firmware ABI
>   media: add Mediatek's MM21 format
>   dt-bindings: media: document mediatek,mt8183-vcodec-dec
> 
> Hirokazu Honda (1):
>   media: mtk-vcodec: vdec: Support H264 profile control
> 
> Yunfei Dong (5):
>   media: mtk-vcodec: vdec: move stateful ops into their own file
>   media: mtk-vcodec: vdec: support stateless API
>   media: mtk-vcodec: vdec: support stateless H.264 decoding
>   media: mtk-vcodec: vdec: add media device if using stateless api
>   media: mtk-vcodec: enable MT8183 decoder
> 
>  .../bindings/media/mediatek-vcodec.txt        |   1 +
>  .../media/v4l/pixfmt-reserved.rst             |   7 +
>  drivers/media/platform/Kconfig                |   3 +
>  drivers/media/platform/mtk-vcodec/Makefile    |   3 +
>  .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 820 +++---------------
>  .../platform/mtk-vcodec/mtk_vcodec_dec.h      |  25 +-
>  .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  68 +-
>  .../mtk-vcodec/mtk_vcodec_dec_stateful.c      | 628 ++++++++++++++
>  .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 360 ++++++++
>  .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  58 +-
>  .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 140 ++-
>  .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |   6 +-
>  .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 774 +++++++++++++++++
>  .../media/platform/mtk-vcodec/vdec_drv_if.c   |   3 +
>  .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
>  .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  23 +-
>  .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  43 +-
>  .../media/platform/mtk-vcodec/vdec_vpu_if.h   |   5 +
>  drivers/media/v4l2-core/v4l2-ioctl.c          |   1 +
>  include/uapi/linux/videodev2.h                |   1 +
>  20 files changed, 2241 insertions(+), 729 deletions(-)
>  create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
>  create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
>  create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> 



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:25 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:25 +0900
Subject: [PATCH v15 00/13] Introduce the Counter character device interface
Message-ID: <cover.1628511445.git.vilhelm.gray@gmail.com>

Changes in v15:
 - Move the description for the member 'lock' in the 'quad8' structure
   as a separate patch
 - Reorganize the "counter: Internalize sysfs interface code" patch to
   not call chrdev code; respective code moved to the "counter: Add
   character device interface" patch with the other chrdev code
 - Custom enums removed from the ftm-quaddec.c, stm32-lptimer-cnt.c, and
   stm32-timer-cnt.c files; respective drivers refactored to use the
   COUNTER_FUNCTION_* and COUNTER_SYNAPSE_* enum constants instead

For convenience, this patchset is also available on my personal git
repo: https://gitlab.com/vilhelmgray/iio/-/tree/counter_chrdev_v15

The patches preceding "counter: Internalize sysfs interface code" are
primarily cleanup and fixes that can be picked up and applied now to the
IIO tree if so desired. The "counter: Internalize sysfs interface code"
patch as well may be considered for pickup because it is relatively safe
and makes no changes to the userspace interface.

To summarize the main points of this patchset: there are no changes to
the existing Counter sysfs userspace interface; a Counter character
device interface is introduced that allows Counter events and associated
data to be read() by userspace; the events_configure() and
watch_validate() driver callbacks are introduced to support Counter
events; and IRQ support is added to the 104-QUAD-8 driver, serving as an
example of how to support the new Counter events functionality.

William Breathitt Gray (13):
  counter: 104-quad-8: Describe member 'lock' in 'quad8'
  counter: Internalize sysfs interface code
  counter: Update counter.h comments to reflect sysfs internalization
  docs: counter: Update to reflect sysfs internalization
  counter: Move counter enums to uapi header
  counter: Add character device interface
  docs: counter: Document character device interface
  tools/counter: Create Counter tools
  counter: Implement signalZ_action_component_id sysfs attribute
  counter: Implement *_component_id sysfs attributes
  counter: Implement events_queue_size sysfs attribute
  counter: 104-quad-8: Replace mutex with spinlock
  counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8

 Documentation/ABI/testing/sysfs-bus-counter   |   38 +-
 Documentation/driver-api/generic-counter.rst  |  358 +++-
 .../userspace-api/ioctl/ioctl-number.rst      |    1 +
 MAINTAINERS                                   |    3 +-
 drivers/counter/104-quad-8.c                  |  700 ++++----
 drivers/counter/Kconfig                       |    6 +-
 drivers/counter/Makefile                      |    1 +
 drivers/counter/counter-chrdev.c              |  553 ++++++
 drivers/counter/counter-chrdev.h              |   14 +
 drivers/counter/counter-core.c                |  191 +++
 drivers/counter/counter-sysfs.c               |  962 +++++++++++
 drivers/counter/counter-sysfs.h               |   13 +
 drivers/counter/counter.c                     | 1496 -----------------
 drivers/counter/ftm-quaddec.c                 |   60 +-
 drivers/counter/intel-qep.c                   |  144 +-
 drivers/counter/interrupt-cnt.c               |   62 +-
 drivers/counter/microchip-tcb-capture.c       |   91 +-
 drivers/counter/stm32-lptimer-cnt.c           |  226 +--
 drivers/counter/stm32-timer-cnt.c             |  179 +-
 drivers/counter/ti-eqep.c                     |  180 +-
 include/linux/counter.h                       |  715 ++++----
 include/linux/counter_enum.h                  |   45 -
 include/uapi/linux/counter.h                  |  154 ++
 tools/Makefile                                |   13 +-
 tools/counter/Build                           |    1 +
 tools/counter/Makefile                        |   53 +
 tools/counter/counter_example.c               |   93 +
 27 files changed, 3568 insertions(+), 2784 deletions(-)
 create mode 100644 drivers/counter/counter-chrdev.c
 create mode 100644 drivers/counter/counter-chrdev.h
 create mode 100644 drivers/counter/counter-core.c
 create mode 100644 drivers/counter/counter-sysfs.c
 create mode 100644 drivers/counter/counter-sysfs.h
 delete mode 100644 drivers/counter/counter.c
 delete mode 100644 include/linux/counter_enum.h
 create mode 100644 include/uapi/linux/counter.h
 create mode 100644 tools/counter/Build
 create mode 100644 tools/counter/Makefile
 create mode 100644 tools/counter/counter_example.c


base-commit: c886885336b0b5f1a08ce580f7201a2ca30ab041
prerequisite-patch-id: 8ca55ffcdd5d060dd5fa2b4dd50bf01dc1026da6
prerequisite-patch-id: 46ef2668ca6bdc0d08dd488fe1d2b886189a5652
prerequisite-patch-id: 2df1946c917d6408148306db30a071e67b00ad73
prerequisite-patch-id: f81579f50552e6041a95403cc743c5f36962b111
prerequisite-patch-id: 8a6860e75cdec162812c56dc39c5d7fc6fc5154e
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:26 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:26 +0900
Subject: [PATCH v15 01/13] counter: 104-quad-8: Describe member 'lock' in
 'quad8'
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <43b4acab9e238638c7067dd4a363a42f94c94ccb.1628511445.git.vilhelm.gray@gmail.com>

This adds a kernel-doc comment line describing the 'lock' member of the
'quad8' structure.

Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index 5283ff128c17..0caa60537b14 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -28,6 +28,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
 
 /**
  * struct quad8 - device private data structure
+ * @lock:		lock to prevent clobbering device states during R/W ops
  * @counter:		instance of the counter_device
  * @fck_prescaler:	array of filter clock prescaler configurations
  * @preset:		array of preset values
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:28 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:28 +0900
Subject: [PATCH v15 03/13] counter: Update counter.h comments to reflect sysfs
 internalization
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <83d75aa8d88d7ca1b5cc9fbb0249fed61f10ba13.1628511445.git.vilhelm.gray@gmail.com>

The Counter subsystem architecture and driver implementations have
changed in order to handle Counter sysfs interactions in a more
consistent way. This patch updates the Generic Counter interface
header file comments to reflect the changes.

Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/counter-core.c |  3 ++
 include/linux/counter.h        | 62 ++++++++++++++++------------------
 2 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
index c533a6ff12cf..3cda2c47bacb 100644
--- a/drivers/counter/counter-core.c
+++ b/drivers/counter/counter-core.c
@@ -38,6 +38,9 @@ static struct bus_type counter_bus_type = {
  * This function registers a Counter to the system. A sysfs "counter" directory
  * will be created and populated with sysfs attributes correlating with the
  * Counter Signals, Synapses, and Counts respectively.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
  */
 int counter_register(struct counter_device *const counter)
 {
diff --git a/include/linux/counter.h b/include/linux/counter.h
index b69277f5c4c5..445f22d8bfe2 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -188,11 +188,10 @@ struct counter_comp {
 
 /**
  * struct counter_signal - Counter Signal node
- * @id:		unique ID used to identify signal
- * @name:	device-specific Signal name; ideally, this should match the name
- *		as it appears in the datasheet documentation
- * @ext:	optional array of Counter Signal extensions
- * @num_ext:	number of Counter Signal extensions specified in @ext
+ * @id:		unique ID used to identify the Signal
+ * @name:	device-specific Signal name
+ * @ext:	optional array of Signal extensions
+ * @num_ext:	number of Signal extensions specified in @ext
  */
 struct counter_signal {
 	int id;
@@ -206,7 +205,7 @@ struct counter_signal {
  * struct counter_synapse - Counter Synapse node
  * @actions_list:	array of available action modes
  * @num_actions:	number of action modes specified in @actions_list
- * @signal:		pointer to associated signal
+ * @signal:		pointer to the associated Signal
  */
 struct counter_synapse {
 	const enum counter_synapse_action *actions_list;
@@ -217,15 +216,14 @@ struct counter_synapse {
 
 /**
  * struct counter_count - Counter Count node
- * @id:			unique ID used to identify Count
- * @name:		device-specific Count name; ideally, this should match
- *			the name as it appears in the datasheet documentation
- * @functions_list:	array available function modes
+ * @id:			unique ID used to identify the Count
+ * @name:		device-specific Count name
+ * @functions_list:	array of available function modes
  * @num_functions:	number of function modes specified in @functions_list
- * @synapses:		array of synapses for initialization
- * @num_synapses:	number of synapses specified in @synapses
- * @ext:		optional array of Counter Count extensions
- * @num_ext:		number of Counter Count extensions specified in @ext
+ * @synapses:		array of Synapses for initialization
+ * @num_synapses:	number of Synapses specified in @synapses
+ * @ext:		optional array of Count extensions
+ * @num_ext:		number of Count extensions specified in @ext
  */
 struct counter_count {
 	int id;
@@ -243,27 +241,27 @@ struct counter_count {
 
 /**
  * struct counter_ops - Callbacks from driver
- * @signal_read:	optional read callback for Signal attribute. The read
- *			level of the respective Signal should be passed back via
- *			the level parameter.
- * @count_read:		optional read callback for Count attribute. The read
- *			value of the respective Count should be passed back via
- *			the val parameter.
- * @count_write:	optional write callback for Count attribute. The write
- *			value for the respective Count is passed in via the val
+ * @signal_read:	optional read callback for Signals. The read level of
+ *			the respective Signal should be passed back via the
+ *			level parameter.
+ * @count_read:		read callback for Counts. The read value of the
+ *			respective Count should be passed back via the value
+ *			parameter.
+ * @count_write:	optional write callback for Counts. The write value for
+ *			the respective Count is passed in via the value
  *			parameter.
  * @function_read:	read callback the Count function modes. The read
  *			function mode of the respective Count should be passed
  *			back via the function parameter.
- * @function_write:	write callback for Count function modes. The function
- *			mode to write for the respective Count is passed in via
- *			the function parameter.
- * @action_read:	read callback the Synapse action modes. The read action
- *			mode of the respective Synapse should be passed back via
- *			the action parameter.
- * @action_write:	write callback for Synapse action modes. The action mode
- *			to write for the respective Synapse is passed in via the
- *			action parameter.
+ * @function_write:	optional write callback for Count function modes. The
+ *			function mode to write for the respective Count is
+ *			passed in via the function parameter.
+ * @action_read:	optional read callback the Synapse action modes. The
+ *			read action mode of the respective Synapse should be
+ *			passed back via the action parameter.
+ * @action_write:	optional write callback for Synapse action modes. The
+ *			action mode to write for the respective Synapse is
+ *			passed in via the action parameter.
  */
 struct counter_ops {
 	int (*signal_read)(struct counter_device *counter,
@@ -291,7 +289,7 @@ struct counter_ops {
 
 /**
  * struct counter_device - Counter data structure
- * @name:		name of the device as it appears in the datasheet
+ * @name:		name of the device
  * @parent:		optional parent device providing the counters
  * @ops:		callbacks from driver
  * @signals:		array of Signals
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:29 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:29 +0900
Subject: [PATCH v15 04/13] docs: counter: Update to reflect sysfs
 internalization
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <412b52740764644ccc2294173d5a822d4243b536.1628511445.git.vilhelm.gray@gmail.com>

The Counter subsystem architecture and driver implementations have
changed in order to handle Counter sysfs interactions in a more
consistent way. This patch updates the Generic Counter interface
documentation to reflect the changes.

Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter  |   9 +-
 Documentation/driver-api/generic-counter.rst | 243 ++++++++++++++-----
 2 files changed, 185 insertions(+), 67 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index 20fe5afd4f9e..dee79b606847 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -286,7 +286,14 @@ What:		/sys/bus/counter/devices/counterX/signalY/signal
 KernelVersion:	5.2
 Contact:	linux-iio at vger.kernel.org
 Description:
-		Signal data of Signal Y represented as a string.
+		Signal level state of Signal Y. The following signal level
+		states are available:
+
+		low:
+			Low level state.
+
+		high:
+			High level state.
 
 What:		/sys/bus/counter/devices/counterX/signalY/synchronous_mode
 KernelVersion:	5.2
diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
index 64fe7db080e5..f6397218aa4c 100644
--- a/Documentation/driver-api/generic-counter.rst
+++ b/Documentation/driver-api/generic-counter.rst
@@ -250,8 +250,8 @@ for defining a counter device.
 .. kernel-doc:: drivers/counter/counter.c
    :export:
 
-Implementation
-==============
+Driver Implementation
+=====================
 
 To support a counter device, a driver must first allocate the available
 Counter Signals via counter_signal structures. These Signals should
@@ -267,25 +267,61 @@ respective counter_count structure. These counter_count structures are
 set to the counts array member of an allocated counter_device structure
 before the Counter is registered to the system.
 
-Driver callbacks should be provided to the counter_device structure via
-a constant counter_ops structure in order to communicate with the
-device: to read and write various Signals and Counts, and to set and get
-the "action mode" and "function mode" for various Synapses and Counts
-respectively.
+Driver callbacks must be provided to the counter_device structure in
+order to communicate with the device: to read and write various Signals
+and Counts, and to set and get the "action mode" and "function mode" for
+various Synapses and Counts respectively.
 
 A defined counter_device structure may be registered to the system by
 passing it to the counter_register function, and unregistered by passing
 it to the counter_unregister function. Similarly, the
-devm_counter_register and devm_counter_unregister functions may be used
-if device memory-managed registration is desired.
-
-Extension sysfs attributes can be created for auxiliary functionality
-and data by passing in defined counter_device_ext, counter_count_ext,
-and counter_signal_ext structures. In these cases, the
-counter_device_ext structure is used for global/miscellaneous exposure
-and configuration of the respective Counter device, while the
-counter_count_ext and counter_signal_ext structures allow for auxiliary
-exposure and configuration of a specific Count or Signal respectively.
+devm_counter_register function may be used if device memory-managed
+registration is desired.
+
+The struct counter_comp structure is used to define counter extensions
+for Signals, Synapses, and Counts.
+
+The "type" member specifies the type of high-level data (e.g. BOOL,
+COUNT_DIRECTION, etc.) handled by this extension. The "``*_read``" and
+"``*_write``" members can then be set by the counter device driver with
+callbacks to handle that data using native C data types (i.e. u8, u64,
+etc.).
+
+Convenience macros such as ``COUNTER_COMP_COUNT_U64`` are provided for
+use by driver authors. In particular, driver authors are expected to use
+the provided macros for standard Counter subsystem attributes in order
+to maintain a consistent interface for userspace. For example, a counter
+device driver may define several standard attributes like so::
+
+        struct counter_comp count_ext[] = {
+                COUNTER_COMP_DIRECTION(count_direction_read),
+                COUNTER_COMP_ENABLE(count_enable_read, count_enable_write),
+                COUNTER_COMP_CEILING(count_ceiling_read, count_ceiling_write),
+        };
+
+This makes it simple to see, add, and modify the attributes that are
+supported by this driver ("direction", "enable", and "ceiling") and to
+maintain this code without getting lost in a web of struct braces.
+
+Callbacks must match the function type expected for the respective
+component or extension. These function types are defined in the struct
+counter_comp structure as the "``*_read``" and "``*_write``" union
+members.
+
+The corresponding callback prototypes for the extensions mentioned in
+the previous example above would be::
+
+        int count_direction_read(struct counter_device *counter,
+                                 struct counter_count *count,
+                                 enum counter_count_direction *direction);
+        int count_enable_read(struct counter_device *counter,
+                              struct counter_count *count, u8 *enable);
+        int count_enable_write(struct counter_device *counter,
+                               struct counter_count *count, u8 enable);
+        int count_ceiling_read(struct counter_device *counter,
+                               struct counter_count *count, u64 *ceiling);
+        int count_ceiling_write(struct counter_device *counter,
+                                struct counter_count *count, u64 ceiling);
 
 Determining the type of extension to create is a matter of scope.
 
@@ -313,52 +349,127 @@ Determining the type of extension to create is a matter of scope.
   chip overheated via a device extension called "error_overtemp":
   /sys/bus/counter/devices/counterX/error_overtemp
 
-Architecture
-============
-
-When the Generic Counter interface counter module is loaded, the
-counter_init function is called which registers a bus_type named
-"counter" to the system. Subsequently, when the module is unloaded, the
-counter_exit function is called which unregisters the bus_type named
-"counter" from the system.
-
-Counter devices are registered to the system via the counter_register
-function, and later removed via the counter_unregister function. The
-counter_register function establishes a unique ID for the Counter
-device and creates a respective sysfs directory, where X is the
-mentioned unique ID:
-
-    /sys/bus/counter/devices/counterX
-
-Sysfs attributes are created within the counterX directory to expose
-functionality, configurations, and data relating to the Counts, Signals,
-and Synapses of the Counter device, as well as options and information
-for the Counter device itself.
-
-Each Signal has a directory created to house its relevant sysfs
-attributes, where Y is the unique ID of the respective Signal:
-
-    /sys/bus/counter/devices/counterX/signalY
-
-Similarly, each Count has a directory created to house its relevant
-sysfs attributes, where Y is the unique ID of the respective Count:
-
-    /sys/bus/counter/devices/counterX/countY
-
-For a more detailed breakdown of the available Generic Counter interface
-sysfs attributes, please refer to the
-Documentation/ABI/testing/sysfs-bus-counter file.
-
-The Signals and Counts associated with the Counter device are registered
-to the system as well by the counter_register function. The
-signal_read/signal_write driver callbacks are associated with their
-respective Signal attributes, while the count_read/count_write and
-function_get/function_set driver callbacks are associated with their
-respective Count attributes; similarly, the same is true for the
-action_get/action_set driver callbacks and their respective Synapse
-attributes. If a driver callback is left undefined, then the respective
-read/write permission is left disabled for the relevant attributes.
-
-Similarly, extension sysfs attributes are created for the defined
-counter_device_ext, counter_count_ext, and counter_signal_ext
-structures that are passed in.
+Subsystem Architecture
+======================
+
+Counter drivers pass and take data natively (i.e. ``u8``, ``u64``, etc.)
+and the shared counter module handles the translation between the sysfs
+interface. This guarantees a standard userspace interface for all
+counter drivers, and enables a Generic Counter chrdev interface via a
+generalized device driver ABI.
+
+A high-level view of how a count value is passed down from a counter
+driver is exemplified by the following. The driver callbacks are first
+registered to the Counter core component for use by the Counter
+userspace interface components::
+
+        Driver callbacks registration:
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        +----------------------------+
+                        | Counter device driver      |
+                        +----------------------------+
+                        | Processes data from device |
+                        +----------------------------+
+                                |
+                         -------------------
+                        / driver callbacks /
+                        -------------------
+                                |
+                                V
+                        +----------------------+
+                        | Counter core         |
+                        +----------------------+
+                        | Routes device driver |
+                        | callbacks to the     |
+                        | userspace interfaces |
+                        +----------------------+
+                                |
+                         -------------------
+                        / driver callbacks /
+                        -------------------
+                                |
+                +---------------+
+                |
+                V
+        +--------------------+
+        | Counter sysfs      |
+        +--------------------+
+        | Translates to the  |
+        | standard Counter   |
+        | sysfs output       |
+        +--------------------+
+
+Thereafter, data can be transferred directly between the Counter device
+driver and Counter userspace interface::
+
+        Count data request:
+        ~~~~~~~~~~~~~~~~~~~
+                         ----------------------
+                        / Counter device       \
+                        +----------------------+
+                        | Count register: 0x28 |
+                        +----------------------+
+                                |
+                         -----------------
+                        / raw count data /
+                        -----------------
+                                |
+                                V
+                        +----------------------------+
+                        | Counter device driver      |
+                        +----------------------------+
+                        | Processes data from device |
+                        |----------------------------|
+                        | Type: u64                  |
+                        | Value: 42                  |
+                        +----------------------------+
+                                |
+                         ----------
+                        / u64     /
+                        ----------
+                                |
+                +---------------+
+                |
+                V
+        +--------------------+
+        | Counter sysfs      |
+        +--------------------+
+        | Translates to the  |
+        | standard Counter   |
+        | sysfs output       |
+        |--------------------|
+        | Type: const char * |
+        | Value: "42"        |
+        +--------------------+
+                |
+         ---------------
+        / const char * /
+        ---------------
+                |
+                V
+        +--------------------------------------------------+
+        | `/sys/bus/counter/devices/counterX/countY/count` |
+        +--------------------------------------------------+
+        \ Count: "42"                                      /
+         --------------------------------------------------
+
+There are three primary components involved:
+
+Counter device driver
+---------------------
+Communicates with the hardware device to read/write data; e.g. counter
+drivers for quadrature encoders, timers, etc.
+
+Counter core
+------------
+Registers the counter device driver to the system so that the respective
+callbacks are called during userspace interaction.
+
+Counter sysfs
+-------------
+Translates counter data to the standard Counter sysfs interface format
+and vice versa.
+
+Please refer to the ``Documentation/ABI/testing/sysfs-bus-counter`` file
+for a detailed breakdown of the available Generic Counter interface
+sysfs attributes.
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:30 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:30 +0900
Subject: [PATCH v15 05/13] counter: Move counter enums to uapi header
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <4dfa52b09cd7b8034b679d2b4af7c9f7fd0d027c.1628511445.git.vilhelm.gray@gmail.com>

This is in preparation for a subsequent patch implementing a character
device interface for the Counter subsystem.

Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 MAINTAINERS                  |  1 +
 include/linux/counter.h      | 42 +--------------------------
 include/uapi/linux/counter.h | 56 ++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 41 deletions(-)
 create mode 100644 include/uapi/linux/counter.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5d3f7e05a588..cef0f840e142 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4764,6 +4764,7 @@ F:	Documentation/ABI/testing/sysfs-bus-counter
 F:	Documentation/driver-api/generic-counter.rst
 F:	drivers/counter/
 F:	include/linux/counter.h
+F:	include/uapi/linux/counter.h
 
 CP2615 I2C DRIVER
 M:	Bence Cs?k?s <bence98 at sch.bme.hu>
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 445f22d8bfe2..7c9f7e23953a 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -9,6 +9,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <uapi/linux/counter.h>
 
 struct counter_device;
 struct counter_count;
@@ -27,47 +28,6 @@ enum counter_comp_type {
 	COUNTER_COMP_COUNT_MODE,
 };
 
-enum counter_scope {
-	COUNTER_SCOPE_DEVICE,
-	COUNTER_SCOPE_SIGNAL,
-	COUNTER_SCOPE_COUNT,
-};
-
-enum counter_count_direction {
-	COUNTER_COUNT_DIRECTION_FORWARD,
-	COUNTER_COUNT_DIRECTION_BACKWARD,
-};
-
-enum counter_count_mode {
-	COUNTER_COUNT_MODE_NORMAL,
-	COUNTER_COUNT_MODE_RANGE_LIMIT,
-	COUNTER_COUNT_MODE_NON_RECYCLE,
-	COUNTER_COUNT_MODE_MODULO_N,
-};
-
-enum counter_function {
-	COUNTER_FUNCTION_INCREASE,
-	COUNTER_FUNCTION_DECREASE,
-	COUNTER_FUNCTION_PULSE_DIRECTION,
-	COUNTER_FUNCTION_QUADRATURE_X1_A,
-	COUNTER_FUNCTION_QUADRATURE_X1_B,
-	COUNTER_FUNCTION_QUADRATURE_X2_A,
-	COUNTER_FUNCTION_QUADRATURE_X2_B,
-	COUNTER_FUNCTION_QUADRATURE_X4,
-};
-
-enum counter_signal_level {
-	COUNTER_SIGNAL_LEVEL_LOW,
-	COUNTER_SIGNAL_LEVEL_HIGH,
-};
-
-enum counter_synapse_action {
-	COUNTER_SYNAPSE_ACTION_NONE,
-	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
-	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
-	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
-};
-
 /**
  * struct counter_comp - Counter component node
  * @type:		Counter component data type
diff --git a/include/uapi/linux/counter.h b/include/uapi/linux/counter.h
new file mode 100644
index 000000000000..6113938a6044
--- /dev/null
+++ b/include/uapi/linux/counter.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Userspace ABI for Counter character devices
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#ifndef _UAPI_COUNTER_H_
+#define _UAPI_COUNTER_H_
+
+/* Component scope definitions */
+enum counter_scope {
+	COUNTER_SCOPE_DEVICE,
+	COUNTER_SCOPE_SIGNAL,
+	COUNTER_SCOPE_COUNT,
+};
+
+/* Count direction values */
+enum counter_count_direction {
+	COUNTER_COUNT_DIRECTION_FORWARD,
+	COUNTER_COUNT_DIRECTION_BACKWARD,
+};
+
+/* Count mode values */
+enum counter_count_mode {
+	COUNTER_COUNT_MODE_NORMAL,
+	COUNTER_COUNT_MODE_RANGE_LIMIT,
+	COUNTER_COUNT_MODE_NON_RECYCLE,
+	COUNTER_COUNT_MODE_MODULO_N,
+};
+
+/* Count function values */
+enum counter_function {
+	COUNTER_FUNCTION_INCREASE,
+	COUNTER_FUNCTION_DECREASE,
+	COUNTER_FUNCTION_PULSE_DIRECTION,
+	COUNTER_FUNCTION_QUADRATURE_X1_A,
+	COUNTER_FUNCTION_QUADRATURE_X1_B,
+	COUNTER_FUNCTION_QUADRATURE_X2_A,
+	COUNTER_FUNCTION_QUADRATURE_X2_B,
+	COUNTER_FUNCTION_QUADRATURE_X4,
+};
+
+/* Signal values */
+enum counter_signal_level {
+	COUNTER_SIGNAL_LEVEL_LOW,
+	COUNTER_SIGNAL_LEVEL_HIGH,
+};
+
+/* Action mode values */
+enum counter_synapse_action {
+	COUNTER_SYNAPSE_ACTION_NONE,
+	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
+	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
+};
+
+#endif /* _UAPI_COUNTER_H_ */
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:31 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:31 +0900
Subject: [PATCH v15 06/13] counter: Add character device interface
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <140d2e86b9aab72531f7861c312c2c532c06d59a.1628511445.git.vilhelm.gray@gmail.com>

This patch introduces a character device interface for the Counter
subsystem. Device data is exposed through standard character device read
operations. Device data is gathered when a Counter event is pushed by
the respective Counter device driver. Configuration is handled via ioctl
operations on the respective Counter character device node.

Cc: David Lechner <david at lechnology.com>
Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/Makefile         |   2 +-
 drivers/counter/counter-chrdev.c | 553 +++++++++++++++++++++++++++++++
 drivers/counter/counter-chrdev.h |  14 +
 drivers/counter/counter-core.c   |  60 +++-
 include/linux/counter.h          |  51 +++
 include/uapi/linux/counter.h     |  98 ++++++
 6 files changed, 770 insertions(+), 8 deletions(-)
 create mode 100644 drivers/counter/counter-chrdev.c
 create mode 100644 drivers/counter/counter-chrdev.h

diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
index 1ab7e087fdc2..8fde6c100ebc 100644
--- a/drivers/counter/Makefile
+++ b/drivers/counter/Makefile
@@ -4,7 +4,7 @@
 #
 
 obj-$(CONFIG_COUNTER) += counter.o
-counter-y := counter-core.o counter-sysfs.o
+counter-y := counter-core.o counter-sysfs.o counter-chrdev.o
 
 obj-$(CONFIG_104_QUAD_8)	+= 104-quad-8.o
 obj-$(CONFIG_INTERRUPT_CNT)		+= interrupt-cnt.o
diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c
new file mode 100644
index 000000000000..30659b67d8f3
--- /dev/null
+++ b/drivers/counter/counter-chrdev.c
@@ -0,0 +1,553 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Generic Counter character device interface
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#include <linux/bitops.h>
+#include <linux/cdev.h>
+#include <linux/counter.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/kfifo.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/nospec.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/timekeeping.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+
+#include "counter-chrdev.h"
+
+struct counter_comp_node {
+	struct list_head l;
+	struct counter_component component;
+	struct counter_comp comp;
+	void *parent;
+};
+
+static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
+				   size_t len, loff_t *f_ps)
+{
+	struct counter_device *const counter = filp->private_data;
+	int err;
+	unsigned int copied;
+
+	if (!counter->ops)
+		return -ENODEV;
+
+	if (len < sizeof(struct counter_event))
+		return -EINVAL;
+
+	do {
+		if (kfifo_is_empty(&counter->events)) {
+			if (filp->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+
+			err = wait_event_interruptible(counter->events_wait,
+					!kfifo_is_empty(&counter->events) ||
+					!counter->ops);
+			if (err < 0)
+				return err;
+			if (!counter->ops)
+				return -ENODEV;
+		}
+
+		if (mutex_lock_interruptible(&counter->events_lock))
+			return -ERESTARTSYS;
+		err = kfifo_to_user(&counter->events, buf, len, &copied);
+		mutex_unlock(&counter->events_lock);
+		if (err < 0)
+			return err;
+	} while (!copied);
+
+	return copied;
+}
+
+static __poll_t counter_chrdev_poll(struct file *filp,
+				    struct poll_table_struct *pollt)
+{
+	struct counter_device *const counter = filp->private_data;
+	__poll_t events = 0;
+
+	if (!counter->ops)
+		return events;
+
+	poll_wait(filp, &counter->events_wait, pollt);
+
+	if (!kfifo_is_empty(&counter->events))
+		events = EPOLLIN | EPOLLRDNORM;
+
+	return events;
+}
+
+static void counter_events_list_free(struct list_head *const events_list)
+{
+	struct counter_event_node *p, *n;
+	struct counter_comp_node *q, *o;
+
+	list_for_each_entry_safe(p, n, events_list, l) {
+		/* Free associated component nodes */
+		list_for_each_entry_safe(q, o, &p->comp_list, l) {
+			list_del(&q->l);
+			kfree(q);
+		}
+
+		/* Free event node */
+		list_del(&p->l);
+		kfree(p);
+	}
+}
+
+static int counter_set_event_node(struct counter_device *const counter,
+				  struct counter_watch *const watch,
+				  const struct counter_comp_node *const cfg)
+{
+	struct counter_event_node *event_node;
+	int err = 0;
+	struct counter_comp_node *comp_node;
+
+	/* Search for event in the list */
+	list_for_each_entry(event_node, &counter->next_events_list, l)
+		if (event_node->event == watch->event &&
+		    event_node->channel == watch->channel)
+			break;
+
+	/* If event is not already in the list */
+	if (&event_node->l == &counter->next_events_list) {
+		/* Allocate new event node */
+		event_node = kmalloc(sizeof(*event_node), GFP_KERNEL);
+		if (!event_node)
+			return -ENOMEM;
+
+		/* Configure event node and add to the list */
+		event_node->event = watch->event;
+		event_node->channel = watch->channel;
+		INIT_LIST_HEAD(&event_node->comp_list);
+		list_add(&event_node->l, &counter->next_events_list);
+	}
+
+	/* Check if component watch has already been set before */
+	list_for_each_entry(comp_node, &event_node->comp_list, l)
+		if (comp_node->parent == cfg->parent &&
+		    comp_node->comp.count_u8_read == cfg->comp.count_u8_read) {
+			err = -EINVAL;
+			goto exit_free_event_node;
+		}
+
+	/* Allocate component node */
+	comp_node = kmalloc(sizeof(*comp_node), GFP_KERNEL);
+	if (!comp_node) {
+		err = -ENOMEM;
+		goto exit_free_event_node;
+	}
+	*comp_node = *cfg;
+
+	/* Add component node to event node */
+	list_add_tail(&comp_node->l, &event_node->comp_list);
+
+exit_free_event_node:
+	/* Free event node if no one else is watching */
+	if (list_empty(&event_node->comp_list)) {
+		list_del(&event_node->l);
+		kfree(event_node);
+	}
+
+	return err;
+}
+
+static int counter_enable_events(struct counter_device *const counter)
+{
+	unsigned long flags;
+	int err = 0;
+
+	mutex_lock(&counter->n_events_list_lock);
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	counter_events_list_free(&counter->events_list);
+	list_replace_init(&counter->next_events_list,
+			  &counter->events_list);
+
+	if (counter->ops->events_configure)
+		err = counter->ops->events_configure(counter);
+
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static int counter_disable_events(struct counter_device *const counter)
+{
+	unsigned long flags;
+	int err = 0;
+
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	counter_events_list_free(&counter->events_list);
+
+	if (counter->ops->events_configure)
+		err = counter->ops->events_configure(counter);
+
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+
+	mutex_lock(&counter->n_events_list_lock);
+
+	counter_events_list_free(&counter->next_events_list);
+
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static int counter_add_watch(struct counter_device *const counter,
+			     const unsigned long arg)
+{
+	void __user *const uwatch = (void __user *)arg;
+	struct counter_watch watch;
+	struct counter_comp_node comp_node = {};
+	size_t parent, id;
+	struct counter_comp *ext;
+	size_t num_ext;
+	int err = 0;
+
+	if (copy_from_user(&watch, uwatch, sizeof(watch)))
+		return -EFAULT;
+
+	if (watch.component.type == COUNTER_COMPONENT_NONE)
+		goto no_component;
+
+	parent = watch.component.parent;
+
+	/* Configure parent component info for comp node */
+	switch (watch.component.scope) {
+	case COUNTER_SCOPE_DEVICE:
+		ext = counter->ext;
+		num_ext = counter->num_ext;
+		break;
+	case COUNTER_SCOPE_SIGNAL:
+		if (parent >= counter->num_signals)
+			return -EINVAL;
+		parent = array_index_nospec(parent, counter->num_signals);
+
+		comp_node.parent = counter->signals + parent;
+
+		ext = counter->signals[parent].ext;
+		num_ext = counter->signals[parent].num_ext;
+		break;
+	case COUNTER_SCOPE_COUNT:
+		if (parent >= counter->num_counts)
+			return -EINVAL;
+		parent = array_index_nospec(parent, counter->num_counts);
+
+		comp_node.parent = counter->counts + parent;
+
+		ext = counter->counts[parent].ext;
+		num_ext = counter->counts[parent].num_ext;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	id = watch.component.id;
+
+	/* Configure component info for comp node */
+	switch (watch.component.type) {
+	case COUNTER_COMPONENT_SIGNAL:
+		if (watch.component.scope != COUNTER_SCOPE_SIGNAL)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_SIGNAL_LEVEL;
+		comp_node.comp.signal_u32_read = counter->ops->signal_read;
+		break;
+	case COUNTER_COMPONENT_COUNT:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_U64;
+		comp_node.comp.count_u64_read = counter->ops->count_read;
+		break;
+	case COUNTER_COMPONENT_FUNCTION:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_FUNCTION;
+		comp_node.comp.count_u32_read = counter->ops->function_read;
+		break;
+	case COUNTER_COMPONENT_SYNAPSE_ACTION:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+		if (id >= counter->counts[parent].num_synapses)
+			return -EINVAL;
+		id = array_index_nospec(id, counter->counts[parent].num_synapses);
+
+		comp_node.comp.type = COUNTER_COMP_SYNAPSE_ACTION;
+		comp_node.comp.action_read = counter->ops->action_read;
+		comp_node.comp.priv = counter->counts[parent].synapses + id;
+		break;
+	case COUNTER_COMPONENT_EXTENSION:
+		if (id >= num_ext)
+			return -EINVAL;
+		id = array_index_nospec(id, num_ext);
+
+		comp_node.comp = ext[id];
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* Check if any read callback is set; this is part of a union */
+	if (!comp_node.comp.count_u8_read)
+		return -EOPNOTSUPP;
+
+no_component:
+	mutex_lock(&counter->n_events_list_lock);
+
+	if (counter->ops->watch_validate) {
+		err = counter->ops->watch_validate(counter, &watch);
+		if (err < 0)
+			goto err_exit;
+	}
+
+	comp_node.component = watch.component;
+
+	err = counter_set_event_node(counter, &watch, &comp_node);
+
+err_exit:
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static long counter_chrdev_ioctl(struct file *filp, unsigned int cmd,
+				 unsigned long arg)
+{
+	struct counter_device *const counter = filp->private_data;
+	int ret = -ENODEV;
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	if (!counter->ops)
+		goto out_unlock;
+
+	switch (cmd) {
+	case COUNTER_ADD_WATCH_IOCTL:
+		ret = counter_add_watch(counter, arg);
+		break;
+	case COUNTER_ENABLE_EVENTS_IOCTL:
+		ret = counter_enable_events(counter);
+		break;
+	case COUNTER_DISABLE_EVENTS_IOCTL:
+		ret = counter_disable_events(counter);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+out_unlock:
+	mutex_unlock(&counter->ops_exist_lock);
+
+	return ret;
+}
+
+static int counter_chrdev_open(struct inode *inode, struct file *filp)
+{
+	struct counter_device *const counter = container_of(inode->i_cdev,
+							    typeof(*counter),
+							    chrdev);
+
+	if (test_and_set_bit_lock(0, counter->chrdev_lock))
+		return -EBUSY;
+
+	get_device(&counter->dev);
+	filp->private_data = counter;
+
+	return nonseekable_open(inode, filp);
+}
+
+static int counter_chrdev_release(struct inode *inode, struct file *filp)
+{
+	struct counter_device *const counter = filp->private_data;
+	int ret = 0;
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	if (!counter->ops) {
+		counter_events_list_free(&counter->events_list);
+		counter_events_list_free(&counter->next_events_list);
+		ret = -ENODEV;
+		goto out_unlock;
+	}
+
+	ret = counter_disable_events(counter);
+	if (ret < 0) {
+		mutex_unlock(&counter->ops_exist_lock);
+		return ret;
+	}
+
+out_unlock:
+	mutex_unlock(&counter->ops_exist_lock);
+
+	put_device(&counter->dev);
+	clear_bit_unlock(0, counter->chrdev_lock);
+
+	return ret;
+}
+
+static const struct file_operations counter_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.read = counter_chrdev_read,
+	.poll = counter_chrdev_poll,
+	.unlocked_ioctl = counter_chrdev_ioctl,
+	.open = counter_chrdev_open,
+	.release = counter_chrdev_release,
+};
+
+int counter_chrdev_add(struct counter_device *const counter)
+{
+	/* Initialize Counter events lists */
+	INIT_LIST_HEAD(&counter->events_list);
+	INIT_LIST_HEAD(&counter->next_events_list);
+	spin_lock_init(&counter->events_list_lock);
+	mutex_init(&counter->n_events_list_lock);
+	init_waitqueue_head(&counter->events_wait);
+	mutex_init(&counter->events_lock);
+
+	/* Initialize character device */
+	clear_bit(0, counter->chrdev_lock);
+	cdev_init(&counter->chrdev, &counter_fops);
+
+	/* Allocate Counter events queue */
+	return kfifo_alloc(&counter->events, 64, GFP_KERNEL);
+}
+
+void counter_chrdev_remove(struct counter_device *const counter)
+{
+	kfifo_free(&counter->events);
+}
+
+static int counter_get_data(struct counter_device *const counter,
+			    const struct counter_comp_node *const comp_node,
+			    u64 *const value)
+{
+	const struct counter_comp *const comp = &comp_node->comp;
+	void *const parent = comp_node->parent;
+	u8 value_u8 = 0;
+	u32 value_u32 = 0;
+	int ret;
+
+	if (comp_node->component.type == COUNTER_COMPONENT_NONE)
+		return 0;
+
+	switch (comp->type) {
+	case COUNTER_COMP_U8:
+	case COUNTER_COMP_BOOL:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			ret = comp->device_u8_read(counter, &value_u8);
+			break;
+		case COUNTER_SCOPE_SIGNAL:
+			ret = comp->signal_u8_read(counter, parent, &value_u8);
+			break;
+		case COUNTER_SCOPE_COUNT:
+			ret = comp->count_u8_read(counter, parent, &value_u8);
+			break;
+		}
+		*value = value_u8;
+		return ret;
+	case COUNTER_COMP_SIGNAL_LEVEL:
+	case COUNTER_COMP_FUNCTION:
+	case COUNTER_COMP_ENUM:
+	case COUNTER_COMP_COUNT_DIRECTION:
+	case COUNTER_COMP_COUNT_MODE:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			ret = comp->device_u32_read(counter, &value_u32);
+			break;
+		case COUNTER_SCOPE_SIGNAL:
+			ret = comp->signal_u32_read(counter, parent,
+						    &value_u32);
+			break;
+		case COUNTER_SCOPE_COUNT:
+			ret = comp->count_u32_read(counter, parent, &value_u32);
+			break;
+		}
+		*value = value_u32;
+		return ret;
+	case COUNTER_COMP_U64:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			return comp->device_u64_read(counter, value);
+		case COUNTER_SCOPE_SIGNAL:
+			return comp->signal_u64_read(counter, parent, value);
+		case COUNTER_SCOPE_COUNT:
+			return comp->count_u64_read(counter, parent, value);
+		default:
+			return -EINVAL;
+		}
+	case COUNTER_COMP_SYNAPSE_ACTION:
+		ret = comp->action_read(counter, parent, comp->priv,
+					&value_u32);
+		*value = value_u32;
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ * counter_push_event - queue event for userspace reading
+ * @counter:	pointer to Counter structure
+ * @event:	triggered event
+ * @channel:	event channel
+ *
+ * Note: If no one is watching for the respective event, it is silently
+ * discarded.
+ */
+void counter_push_event(struct counter_device *const counter, const u8 event,
+			const u8 channel)
+{
+	struct counter_event ev;
+	unsigned int copied = 0;
+	unsigned long flags;
+	struct counter_event_node *event_node;
+	struct counter_comp_node *comp_node;
+
+	ev.timestamp = ktime_get_ns();
+	ev.watch.event = event;
+	ev.watch.channel = channel;
+
+	/* Could be in an interrupt context, so use a spin lock */
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	/* Search for event in the list */
+	list_for_each_entry(event_node, &counter->events_list, l)
+		if (event_node->event == event &&
+		    event_node->channel == channel)
+			break;
+
+	/* If event is not in the list */
+	if (&event_node->l == &counter->events_list)
+		goto exit_early;
+
+	/* Read and queue relevant comp for userspace */
+	list_for_each_entry(comp_node, &event_node->comp_list, l) {
+		ev.watch.component = comp_node->component;
+		ev.status = -counter_get_data(counter, comp_node, &ev.value);
+
+		copied += kfifo_in(&counter->events, &ev, 1);
+	}
+
+exit_early:
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+
+	if (copied)
+		wake_up_poll(&counter->events_wait, EPOLLIN);
+}
+EXPORT_SYMBOL_GPL(counter_push_event);
diff --git a/drivers/counter/counter-chrdev.h b/drivers/counter/counter-chrdev.h
new file mode 100644
index 000000000000..5529d16703c4
--- /dev/null
+++ b/drivers/counter/counter-chrdev.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Counter character device interface
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#ifndef _COUNTER_CHRDEV_H_
+#define _COUNTER_CHRDEV_H_
+
+#include <linux/counter.h>
+
+int counter_chrdev_add(struct counter_device *const counter);
+void counter_chrdev_remove(struct counter_device *const counter);
+
+#endif /* _COUNTER_CHRDEV_H_ */
diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
index 3cda2c47bacb..28dc1ff63c94 100644
--- a/drivers/counter/counter-core.c
+++ b/drivers/counter/counter-core.c
@@ -3,14 +3,22 @@
  * Generic Counter interface
  * Copyright (C) 2020 William Breathitt Gray
  */
+#include <linux/cdev.h>
 #include <linux/counter.h>
 #include <linux/device.h>
+#include <linux/device/bus.h>
 #include <linux/export.h>
+#include <linux/fs.h>
 #include <linux/gfp.h>
 #include <linux/idr.h>
 #include <linux/init.h>
+#include <linux/kdev_t.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/wait.h>
 
+#include "counter-chrdev.h"
 #include "counter-sysfs.h"
 
 /* Provides a unique ID for each counter device */
@@ -18,6 +26,9 @@ static DEFINE_IDA(counter_ida);
 
 static void counter_device_release(struct device *dev)
 {
+	struct counter_device *const counter = dev_get_drvdata(dev);
+
+	counter_chrdev_remove(counter);
 	ida_free(&counter_ida, dev->id);
 }
 
@@ -31,6 +42,8 @@ static struct bus_type counter_bus_type = {
 	.dev_name = "counter",
 };
 
+static dev_t counter_devt;
+
 /**
  * counter_register - register Counter to the system
  * @counter:	pointer to Counter to register
@@ -53,10 +66,13 @@ int counter_register(struct counter_device *const counter)
 	if (id < 0)
 		return id;
 
+	mutex_init(&counter->ops_exist_lock);
+
 	/* Configure device structure for Counter */
 	dev->id = id;
 	dev->type = &counter_device_type;
 	dev->bus = &counter_bus_type;
+	dev->devt = MKDEV(MAJOR(counter_devt), id);
 	if (counter->parent) {
 		dev->parent = counter->parent;
 		dev->of_node = counter->parent->of_node;
@@ -64,18 +80,22 @@ int counter_register(struct counter_device *const counter)
 	device_initialize(dev);
 	dev_set_drvdata(dev, counter);
 
-	/* Add Counter sysfs attributes */
-	err = counter_sysfs_add(counter);
+	err = counter_chrdev_add(counter);
 	if (err < 0)
 		goto err_free_id;
 
-	/* Add device to system */
-	err = device_add(dev);
+	err = counter_sysfs_add(counter);
 	if (err < 0)
-		goto err_free_id;
+		goto err_remove_chrdev;
+
+	err = cdev_device_add(&counter->chrdev, dev);
+	if (err < 0)
+		goto err_remove_chrdev;
 
 	return 0;
 
+err_remove_chrdev:
+	counter_chrdev_remove(counter);
 err_free_id:
 	put_device(dev);
 	return err;
@@ -93,7 +113,16 @@ void counter_unregister(struct counter_device *const counter)
 	if (!counter)
 		return;
 
-	device_unregister(&counter->dev);
+	cdev_device_del(&counter->chrdev, &counter->dev);
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	counter->ops = NULL;
+	wake_up(&counter->events_wait);
+
+	mutex_unlock(&counter->ops_exist_lock);
+
+	put_device(&counter->dev);
 }
 EXPORT_SYMBOL_GPL(counter_unregister);
 
@@ -127,13 +156,30 @@ int devm_counter_register(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_counter_register);
 
+#define COUNTER_DEV_MAX 256
+
 static int __init counter_init(void)
 {
-	return bus_register(&counter_bus_type);
+	int err;
+
+	err = bus_register(&counter_bus_type);
+	if (err < 0)
+		return err;
+
+	err = alloc_chrdev_region(&counter_devt, 0, COUNTER_DEV_MAX, "counter");
+	if (err < 0)
+		goto err_unregister_bus;
+
+	return 0;
+
+err_unregister_bus:
+	bus_unregister(&counter_bus_type);
+	return err;
 }
 
 static void __exit counter_exit(void)
 {
+	unregister_chrdev_region(counter_devt, COUNTER_DEV_MAX);
 	bus_unregister(&counter_bus_type);
 }
 
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 7c9f7e23953a..9c9984655f8c 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -6,9 +6,14 @@
 #ifndef _COUNTER_H_
 #define _COUNTER_H_
 
+#include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/kfifo.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
 #include <linux/types.h>
+#include <linux/wait.h>
 #include <uapi/linux/counter.h>
 
 struct counter_device;
@@ -199,6 +204,20 @@ struct counter_count {
 	size_t num_ext;
 };
 
+/**
+ * struct counter_event_node - Counter Event node
+ * @l:		list of current watching Counter events
+ * @event:	event that triggers
+ * @channel:	event channel
+ * @comp_list:	list of components to watch when event triggers
+ */
+struct counter_event_node {
+	struct list_head l;
+	u8 event;
+	u8 channel;
+	struct list_head comp_list;
+};
+
 /**
  * struct counter_ops - Callbacks from driver
  * @signal_read:	optional read callback for Signals. The read level of
@@ -222,6 +241,13 @@ struct counter_count {
  * @action_write:	optional write callback for Synapse action modes. The
  *			action mode to write for the respective Synapse is
  *			passed in via the action parameter.
+ * @events_configure:	optional write callback to configure events. The list of
+ *			struct counter_event_node may be accessed via the
+ *			events_list member of the counter parameter.
+ * @watch_validate:	optional callback to validate a watch. The Counter
+ *			component watch configuration is passed in via the watch
+ *			parameter. A return value of 0 indicates a valid Counter
+ *			component watch configuration.
  */
 struct counter_ops {
 	int (*signal_read)(struct counter_device *counter,
@@ -245,6 +271,9 @@ struct counter_ops {
 			    struct counter_count *count,
 			    struct counter_synapse *synapse,
 			    enum counter_synapse_action action);
+	int (*events_configure)(struct counter_device *counter);
+	int (*watch_validate)(struct counter_device *counter,
+			      const struct counter_watch *watch);
 };
 
 /**
@@ -260,6 +289,16 @@ struct counter_ops {
  * @num_ext:		number of Counter device extensions specified in @ext
  * @priv:		optional private data supplied by driver
  * @dev:		internal device structure
+ * @chrdev:		internal character device structure
+ * @events_list:	list of current watching Counter events
+ * @events_list_lock:	lock to protect Counter events list operations
+ * @next_events_list:	list of next watching Counter events
+ * @n_events_list_lock:	lock to protect Counter next events list operations
+ * @events:		queue of detected Counter events
+ * @events_wait:	wait queue to allow blocking reads of Counter events
+ * @events_lock:	lock to protect Counter events queue read operations
+ * @chrdev_lock:	lock to limit chrdev to a single open at a time
+ * @ops_exist_lock:	lock to prevent use during removal
  */
 struct counter_device {
 	const char *name;
@@ -278,12 +317,24 @@ struct counter_device {
 	void *priv;
 
 	struct device dev;
+	struct cdev chrdev;
+	struct list_head events_list;
+	spinlock_t events_list_lock;
+	struct list_head next_events_list;
+	struct mutex n_events_list_lock;
+	DECLARE_KFIFO_PTR(events, struct counter_event);
+	wait_queue_head_t events_wait;
+	struct mutex events_lock;
+	DECLARE_BITMAP(chrdev_lock, 1);
+	struct mutex ops_exist_lock;
 };
 
 int counter_register(struct counter_device *const counter);
 void counter_unregister(struct counter_device *const counter);
 int devm_counter_register(struct device *dev,
 			  struct counter_device *const counter);
+void counter_push_event(struct counter_device *const counter, const u8 event,
+			const u8 channel);
 
 #define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \
 { \
diff --git a/include/uapi/linux/counter.h b/include/uapi/linux/counter.h
index 6113938a6044..d0aa95aeff7b 100644
--- a/include/uapi/linux/counter.h
+++ b/include/uapi/linux/counter.h
@@ -6,6 +6,19 @@
 #ifndef _UAPI_COUNTER_H_
 #define _UAPI_COUNTER_H_
 
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/* Component type definitions */
+enum counter_component_type {
+	COUNTER_COMPONENT_NONE,
+	COUNTER_COMPONENT_SIGNAL,
+	COUNTER_COMPONENT_COUNT,
+	COUNTER_COMPONENT_FUNCTION,
+	COUNTER_COMPONENT_SYNAPSE_ACTION,
+	COUNTER_COMPONENT_EXTENSION,
+};
+
 /* Component scope definitions */
 enum counter_scope {
 	COUNTER_SCOPE_DEVICE,
@@ -13,6 +26,91 @@ enum counter_scope {
 	COUNTER_SCOPE_COUNT,
 };
 
+/**
+ * struct counter_component - Counter component identification
+ * @type: component type (one of enum counter_component_type)
+ * @scope: component scope (one of enum counter_scope)
+ * @parent: parent ID (matching the ID suffix of the respective parent sysfs
+ *          path as described by the ABI documentation file
+ *          Documentation/ABI/testing/sysfs-bus-counter)
+ * @id: component ID (matching the ID provided by the respective *_component_id
+ *      sysfs attribute of the desired component)
+ *
+ * For example, if the Count 2 ceiling extension of Counter device 4 is desired,
+ * set type equal to COUNTER_COMPONENT_EXTENSION, scope equal to
+ * COUNTER_COUNT_SCOPE, parent equal to 2, and id equal to the value provided by
+ * the respective /sys/bus/counter/devices/counter4/count2/ceiling_component_id
+ * sysfs attribute.
+ */
+struct counter_component {
+	__u8 type;
+	__u8 scope;
+	__u8 parent;
+	__u8 id;
+};
+
+/* Event type definitions */
+enum counter_event_type {
+	/* Count value increased past ceiling */
+	COUNTER_EVENT_OVERFLOW,
+	/* Count value decreased past floor */
+	COUNTER_EVENT_UNDERFLOW,
+	/* Count value increased past ceiling, or decreased past floor */
+	COUNTER_EVENT_OVERFLOW_UNDERFLOW,
+	/* Count value reached threshold */
+	COUNTER_EVENT_THRESHOLD,
+	/* Index signal detected */
+	COUNTER_EVENT_INDEX,
+};
+
+/**
+ * struct counter_watch - Counter component watch configuration
+ * @component: component to watch when event triggers
+ * @event: event that triggers (one of enum counter_event_type)
+ * @channel: event channel (typically 0 unless the device supports concurrent
+ *	     events of the same type)
+ */
+struct counter_watch {
+	struct counter_component component;
+	__u8 event;
+	__u8 channel;
+};
+
+/*
+ * Queues a Counter watch for the specified event.
+ *
+ * The queued watches will not be applied until COUNTER_ENABLE_EVENTS_IOCTL is
+ * called.
+ */
+#define COUNTER_ADD_WATCH_IOCTL _IOW(0x3E, 0x00, struct counter_watch)
+/*
+ * Enables monitoring the events specified by the Counter watches that were
+ * queued by COUNTER_ADD_WATCH_IOCTL.
+ *
+ * If events are already enabled, the new set of watches replaces the old one.
+ * Calling this ioctl also has the effect of clearing the queue of watches added
+ * by COUNTER_ADD_WATCH_IOCTL.
+ */
+#define COUNTER_ENABLE_EVENTS_IOCTL _IO(0x3E, 0x01)
+/*
+ * Stops monitoring the previously enabled events.
+ */
+#define COUNTER_DISABLE_EVENTS_IOCTL _IO(0x3E, 0x02)
+
+/**
+ * struct counter_event - Counter event data
+ * @timestamp: best estimate of time of event occurrence, in nanoseconds
+ * @value: component value
+ * @watch: component watch configuration
+ * @status: return status (system error number)
+ */
+struct counter_event {
+	__aligned_u64 timestamp;
+	__aligned_u64 value;
+	struct counter_watch watch;
+	__u8 status;
+};
+
 /* Count direction values */
 enum counter_count_direction {
 	COUNTER_COUNT_DIRECTION_FORWARD,
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:32 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:32 +0900
Subject: [PATCH v15 07/13] docs: counter: Document character device interface
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <a6f7be32b8ff7cc1e8e416599820a30fa9aab9f5.1628511445.git.vilhelm.gray@gmail.com>

This patch adds high-level documentation about the Counter subsystem
character device interface.

Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/driver-api/generic-counter.rst  | 177 ++++++++++++++----
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 2 files changed, 137 insertions(+), 41 deletions(-)

diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
index f6397218aa4c..e9cb95c1c828 100644
--- a/Documentation/driver-api/generic-counter.rst
+++ b/Documentation/driver-api/generic-counter.rst
@@ -223,19 +223,6 @@ whether an input line is differential or single-ended) and instead focus
 on the core idea of what the data and process represent (e.g. position
 as interpreted from quadrature encoding data).
 
-Userspace Interface
-===================
-
-Several sysfs attributes are generated by the Generic Counter interface,
-and reside under the /sys/bus/counter/devices/counterX directory, where
-counterX refers to the respective counter device. Please see
-Documentation/ABI/testing/sysfs-bus-counter for detailed
-information on each Generic Counter interface sysfs attribute.
-
-Through these sysfs attributes, programs and scripts may interact with
-the Generic Counter paradigm Counts, Signals, and Synapses of respective
-counter devices.
-
 Driver API
 ==========
 
@@ -388,16 +375,16 @@ userspace interface components::
                         / driver callbacks /
                         -------------------
                                 |
-                +---------------+
-                |
-                V
-        +--------------------+
-        | Counter sysfs      |
-        +--------------------+
-        | Translates to the  |
-        | standard Counter   |
-        | sysfs output       |
-        +--------------------+
+                +---------------+---------------+
+                |                               |
+                V                               V
+        +--------------------+          +---------------------+
+        | Counter sysfs      |          | Counter chrdev      |
+        +--------------------+          +---------------------+
+        | Translates to the  |          | Translates to the   |
+        | standard Counter   |          | standard Counter    |
+        | sysfs output       |          | character device    |
+        +--------------------+          +---------------------+
 
 Thereafter, data can be transferred directly between the Counter device
 driver and Counter userspace interface::
@@ -428,23 +415,30 @@ driver and Counter userspace interface::
                         / u64     /
                         ----------
                                 |
-                +---------------+
-                |
-                V
-        +--------------------+
-        | Counter sysfs      |
-        +--------------------+
-        | Translates to the  |
-        | standard Counter   |
-        | sysfs output       |
-        |--------------------|
-        | Type: const char * |
-        | Value: "42"        |
-        +--------------------+
-                |
-         ---------------
-        / const char * /
-        ---------------
+                +---------------+---------------+
+                |                               |
+                V                               V
+        +--------------------+          +---------------------+
+        | Counter sysfs      |          | Counter chrdev      |
+        +--------------------+          +---------------------+
+        | Translates to the  |          | Translates to the   |
+        | standard Counter   |          | standard Counter    |
+        | sysfs output       |          | character device    |
+        |--------------------|          |---------------------|
+        | Type: const char * |          | Type: u64           |
+        | Value: "42"        |          | Value: 42           |
+        +--------------------+          +---------------------+
+                |                               |
+         ---------------                 -----------------------
+        / const char * /                / struct counter_event /
+        ---------------                 -----------------------
+                |                               |
+                |                               V
+                |                       +-----------+
+                |                       | read      |
+                |                       +-----------+
+                |                       \ Count: 42 /
+                |                        -----------
                 |
                 V
         +--------------------------------------------------+
@@ -453,7 +447,7 @@ driver and Counter userspace interface::
         \ Count: "42"                                      /
          --------------------------------------------------
 
-There are three primary components involved:
+There are four primary components involved:
 
 Counter device driver
 ---------------------
@@ -473,3 +467,104 @@ and vice versa.
 Please refer to the ``Documentation/ABI/testing/sysfs-bus-counter`` file
 for a detailed breakdown of the available Generic Counter interface
 sysfs attributes.
+
+Counter chrdev
+--------------
+Translates counter data to the standard Counter character device; data
+is transferred via standard character device read calls, while Counter
+events are configured via ioctl calls.
+
+Sysfs Interface
+===============
+
+Several sysfs attributes are generated by the Generic Counter interface,
+and reside under the ``/sys/bus/counter/devices/counterX`` directory,
+where ``X`` is to the respective counter device id. Please see
+``Documentation/ABI/testing/sysfs-bus-counter`` for detailed information
+on each Generic Counter interface sysfs attribute.
+
+Through these sysfs attributes, programs and scripts may interact with
+the Generic Counter paradigm Counts, Signals, and Synapses of respective
+counter devices.
+
+Counter Character Device
+========================
+
+Counter character device nodes are created under the ``/dev`` directory
+as ``counterX``, where ``X`` is the respective counter device id.
+Defines for the standard Counter data types are exposed via the
+userspace ``include/uapi/linux/counter.h`` file.
+
+Counter events
+--------------
+Counter device drivers can support Counter events by utilizing the
+``counter_push_event`` function::
+
+        void counter_push_event(struct counter_device *const counter, const u8 event,
+                                const u8 channel);
+
+The event id is specified by the ``event`` parameter; the event channel
+id is specified by the ``channel`` parameter. When this function is
+called, the Counter data associated with the respective event is
+gathered, and a ``struct counter_event`` is generated for each datum and
+pushed to userspace.
+
+Counter events can be configured by users to report various Counter
+data of interest. This can be conceptualized as a list of Counter
+component read calls to perform. For example:
+
+        +-------------------------------------------------+
+        | COUNTER_EVENT_OVERFLOW | COUNTER_EVENT_INDEX    |
+        +========================+========================+
+        | Channel 0              | Channel 0              |
+        +------------------------+------------------------+
+        | * Count 0              | * Signal 0             |
+        | * Count 1              | * Signal 0 Extension 0 |
+        | * Signal 3             | * Extension 4          |
+        | * Count 4 Extension 2  +------------------------+
+        | * Signal 5 Extension 0 | Channel 1              |
+        |                        +------------------------+
+        |                        | * Signal 4             |
+        |                        | * Signal 4 Extension 0 |
+        |                        | * Count 7              |
+        +------------------------+------------------------+
+
+When ``counter_push_event(counter, COUNTER_EVENT_INDEX, 1)`` is called
+for example, it will go down the list for the ``COUNTER_EVENT_INDEX``
+event channel 1 and execute the read callbacks for Signal 4, Signal 4
+Extension 0, and Count 4 -- the data returned for each is pushed to a
+kfifo as a ``struct counter_event``, which userspace can retrieve via a
+standard read operation on the respective character device node.
+
+Userspace
+---------
+Userspace applications can configure Counter events via ioctl operations
+on the Counter character device node. There following ioctl codes are
+supported and provided by the ``linux/counter.h`` userspace header file:
+
+* :c:macro:`COUNTER_ADD_WATCH_IOCTL`
+
+* :c:macro:`COUNTER_ENABLE_EVENTS_IOCTL`
+
+* :c:macro:`COUNTER_DISABLE_EVENTS_IOCTL`
+
+To configure events to gather Counter data, users first populate a
+``struct counter_watch`` with the relevant event id, event channel id,
+and the information for the desired Counter component from which to
+read, and then pass it via the ``COUNTER_ADD_WATCH_IOCTL`` ioctl
+command.
+
+Note that an event can be watched without gathering Counter data by
+setting the ``component.type`` member equal to
+``COUNTER_COMPONENT_NONE``. With this configuration the Counter
+character device will simply populate the event timestamps for those
+respective ``struct counter_event`` elements and ignore the component
+value.
+
+The ``COUNTER_ADD_WATCH_IOCTL`` command will buffer these Counter
+watches. When ready, the ``COUNTER_ENABLE_EVENTS_IOCTL`` ioctl command
+may be used to activate these Counter watches.
+
+Userspace applications can then execute a ``read`` operation (optionally
+calling ``poll`` first) on the Counter character device node to retrieve
+``struct counter_event`` elements with the desired data.
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 1409e40e6345..fc4ccc79b1b8 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -88,6 +88,7 @@ Code  Seq#    Include File                                           Comments
                                                                      <http://infiniband.sourceforge.net/>
 0x20  all    drivers/cdrom/cm206.h
 0x22  all    scsi/sg.h
+0x3E  00-0F  linux/counter.h                                         <mailto:linux-iio at vger.kernel.org>
 '!'   00-1F  uapi/linux/seccomp.h
 '#'   00-3F                                                          IEEE 1394 Subsystem
                                                                      Block for the entire subsystem
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:33 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:33 +0900
Subject: [PATCH v15 08/13] tools/counter: Create Counter tools
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <060c8c58a5b4250a5dcc7fa3bc7b0b4945ffd49e.1628511445.git.vilhelm.gray@gmail.com>

This creates an example Counter program under tools/counter/*
to exemplify the Counter character device interface.

Cc: Pavel Machek <pavel at ucw.cz>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 MAINTAINERS                     |  1 +
 tools/Makefile                  | 13 ++---
 tools/counter/Build             |  1 +
 tools/counter/Makefile          | 53 +++++++++++++++++++
 tools/counter/counter_example.c | 93 +++++++++++++++++++++++++++++++++
 5 files changed, 155 insertions(+), 6 deletions(-)
 create mode 100644 tools/counter/Build
 create mode 100644 tools/counter/Makefile
 create mode 100644 tools/counter/counter_example.c

diff --git a/MAINTAINERS b/MAINTAINERS
index cef0f840e142..45488c9b8e94 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4765,6 +4765,7 @@ F:	Documentation/driver-api/generic-counter.rst
 F:	drivers/counter/
 F:	include/linux/counter.h
 F:	include/uapi/linux/counter.h
+F:	tools/counter/
 
 CP2615 I2C DRIVER
 M:	Bence Cs?k?s <bence98 at sch.bme.hu>
diff --git a/tools/Makefile b/tools/Makefile
index 7e9d34ddd74c..5da1fde03a9a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -12,6 +12,7 @@ help:
 	@echo '  acpi                   - ACPI tools'
 	@echo '  bpf                    - misc BPF tools'
 	@echo '  cgroup                 - cgroup tools'
+	@echo '  counter                - counter tools'
 	@echo '  cpupower               - a tool for all things x86 CPU power'
 	@echo '  debugging              - tools for debugging'
 	@echo '  firewire               - the userspace part of nosy, an IEEE-1394 traffic sniffer'
@@ -65,7 +66,7 @@ acpi: FORCE
 cpupower: FORCE
 	$(call descend,power/$@)
 
-cgroup firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
+cgroup counter firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
 	$(call descend,$@)
 
 bpf/%: FORCE
@@ -100,7 +101,7 @@ freefall: FORCE
 kvm_stat: FORCE
 	$(call descend,kvm/$@)
 
-all: acpi cgroup cpupower gpio hv firewire liblockdep \
+all: acpi cgroup counter cpupower gpio hv firewire liblockdep \
 		perf selftests bootconfig spi turbostat usb \
 		virtio vm bpf x86_energy_perf_policy \
 		tmon freefall iio objtool kvm_stat wmi \
@@ -112,7 +113,7 @@ acpi_install:
 cpupower_install:
 	$(call descend,power/$(@:_install=),install)
 
-cgroup_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
+cgroup_install counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
 	$(call descend,$(@:_install=),install)
 
 liblockdep_install:
@@ -133,7 +134,7 @@ freefall_install:
 kvm_stat_install:
 	$(call descend,kvm/$(@:_install=),install)
 
-install: acpi_install cgroup_install cpupower_install gpio_install \
+install: acpi_install cgroup_install counter_install cpupower_install gpio_install \
 		hv_install firewire_install iio_install liblockdep_install \
 		perf_install selftests_install turbostat_install usb_install \
 		virtio_install vm_install bpf_install x86_energy_perf_policy_install \
@@ -147,7 +148,7 @@ acpi_clean:
 cpupower_clean:
 	$(call descend,power/cpupower,clean)
 
-cgroup_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
+cgroup_clean counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
 	$(call descend,$(@:_clean=),clean)
 
 liblockdep_clean:
@@ -181,7 +182,7 @@ freefall_clean:
 build_clean:
 	$(call descend,build,clean)
 
-clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
+clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_clean \
 		perf_clean selftests_clean turbostat_clean bootconfig_clean spi_clean usb_clean virtio_clean \
 		vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
 		freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \
diff --git a/tools/counter/Build b/tools/counter/Build
new file mode 100644
index 000000000000..33f4a51d715e
--- /dev/null
+++ b/tools/counter/Build
@@ -0,0 +1 @@
+counter_example-y += counter_example.o
diff --git a/tools/counter/Makefile b/tools/counter/Makefile
new file mode 100644
index 000000000000..5ebc195fd9c0
--- /dev/null
+++ b/tools/counter/Makefile
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: GPL-2.0
+include ../scripts/Makefile.include
+
+bindir ?= /usr/bin
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+endif
+
+# Do not use make's built-in rules
+# (this improves performance and avoids hard-to-debug behaviour);
+MAKEFLAGS += -r
+
+override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
+
+ALL_TARGETS := counter_example
+ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
+
+all: $(ALL_PROGRAMS)
+
+export srctree OUTPUT CC LD CFLAGS
+include $(srctree)/tools/build/Makefile.include
+
+#
+# We need the following to be outside of kernel tree
+#
+$(OUTPUT)include/linux/counter.h: ../../include/uapi/linux/counter.h
+	mkdir -p $(OUTPUT)include/linux 2>&1 || true
+	ln -sf $(CURDIR)/../../include/uapi/linux/counter.h $@
+
+prepare: $(OUTPUT)include/linux/counter.h
+
+COUNTER_EXAMPLE := $(OUTPUT)counter_example.o
+$(COUNTER_EXAMPLE): prepare FORCE
+	$(Q)$(MAKE) $(build)=counter_example
+$(OUTPUT)counter_example: $(COUNTER_EXAMPLE)
+	$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+
+clean:
+	rm -f $(ALL_PROGRAMS)
+	rm -rf $(OUTPUT)include/linux/counter.h
+	find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
+
+install: $(ALL_PROGRAMS)
+	install -d -m 755 $(DESTDIR)$(bindir);		\
+	for program in $(ALL_PROGRAMS); do		\
+		install $$program $(DESTDIR)$(bindir);	\
+	done
+
+FORCE:
+
+.PHONY: all install clean FORCE prepare
diff --git a/tools/counter/counter_example.c b/tools/counter/counter_example.c
new file mode 100644
index 000000000000..90d69fb9463b
--- /dev/null
+++ b/tools/counter/counter_example.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Counter - example userspace application
+ *
+ * The userspace application opens /dev/counter0, configures the
+ * COUNTER_EVENT_INDEX event channel 0 to gather Count 0 count and Count
+ * 1 count, and prints out the data as it becomes available on the
+ * character device node.
+ *
+ * Copyright (C) 2021 William Breathitt Gray
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/counter.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+static struct counter_watch watches[2] = {
+	{
+		/* Component data: Count 0 count */
+		.component.type = COUNTER_COMPONENT_COUNT,
+		.component.scope = COUNTER_SCOPE_COUNT,
+		.component.parent = 0,
+		/* Event type: Index */
+		.event = COUNTER_EVENT_INDEX,
+		/* Device event channel 0 */
+		.channel = 0,
+	},
+	{
+		/* Component data: Count 1 count */
+		.component.type = COUNTER_COMPONENT_COUNT,
+		.component.scope = COUNTER_SCOPE_COUNT,
+		.component.parent = 1,
+		/* Event type: Index */
+		.event = COUNTER_EVENT_INDEX,
+		/* Device event channel 0 */
+		.channel = 0,
+	},
+};
+
+int main(void)
+{
+	int fd;
+	int ret;
+	struct counter_event event_data[2];
+
+	fd = open("/dev/counter0", O_RDWR);
+	if (fd == -1) {
+		perror("Unable to open /dev/counter0");
+		return -errno;
+	}
+
+	ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches);
+	if (ret == -1) {
+		perror("Error adding watches[0]");
+		return -errno;
+	}
+	ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + 1);
+	if (ret == -1) {
+		perror("Error adding watches[1]");
+		return -errno;
+	}
+	ret = ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
+	if (ret == -1) {
+		perror("Error enabling events");
+		return -errno;
+	}
+
+	for (;;) {
+		ret = read(fd, event_data, sizeof(event_data));
+		if (ret == -1) {
+			perror("Failed to read event data");
+			return 1;
+		}
+
+		if (ret != sizeof(event_data)) {
+			fprintf(stderr, "Failed to read event data\n");
+			return -EIO;
+		}
+
+		printf("Timestamp 0: %llu\tCount 0: %llu\n"
+		       "Error Message 0: %s\n"
+		       "Timestamp 1: %llu\tCount 1: %llu\n"
+		       "Error Message 1: %s\n",
+		       event_data[0].timestamp, event_data[0].value,
+		       strerror(event_data[0].status),
+		       event_data[1].timestamp, event_data[1].value,
+		       strerror(event_data[1].status));
+	}
+
+	return 0;
+}
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:34 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:34 +0900
Subject: [PATCH v15 09/13] counter: Implement signalZ_action_component_id
 sysfs attribute
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <d72159ab7ebfe607d86c0ab472979e8eca6f16a0.1628511445.git.vilhelm.gray@gmail.com>

The Generic Counter chrdev interface expects users to supply component
IDs in order to select Synapses for requests. In order for users to know
what component ID belongs to which Synapse this information must be
exposed. The signalZ_action_component_id attribute provides a way for
users to discover what component ID belongs to the respective Synapse.

Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter |  7 ++++
 drivers/counter/counter-sysfs.c             | 46 ++++++++++++++++++++-
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index dee79b606847..9809d8a47431 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -203,6 +203,13 @@ Description:
 		both edges:
 			Any state transition.
 
+What:		/sys/bus/counter/devices/counterX/countY/signalZ_action_component_id
+KernelVersion:	5.15
+Contact:	linux-iio at vger.kernel.org
+Description:
+		Read-only attribute that indicates the component ID of the
+		respective Synapse of Count Y for Signal Z.
+
 What:		/sys/bus/counter/devices/counterX/countY/spike_filter_ns
 KernelVersion:	5.14
 Contact:	linux-iio at vger.kernel.org
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index dbb507c9da11..11bef9f8190f 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -393,7 +393,6 @@ static int counter_avail_attr_create(struct device *const dev,
 	struct counter_attribute *counter_attr;
 	struct device_attribute *dev_attr;
 
-	/* Allocate Counter attribute */
 	counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL);
 	if (!counter_attr)
 		return -ENOMEM;
@@ -535,6 +534,46 @@ static int counter_name_attr_create(struct device *const dev,
 	return 0;
 }
 
+static ssize_t counter_comp_id_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	const size_t id = (size_t)to_counter_attribute(attr)->comp.priv;
+
+	return sprintf(buf, "%zu\n", id);
+}
+
+static int counter_comp_id_attr_create(struct device *const dev,
+				       struct counter_attribute_group *const group,
+				       const char *name, const size_t id)
+{
+	struct counter_attribute *counter_attr;
+
+	/* Allocate Counter attribute */
+	counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL);
+	if (!counter_attr)
+		return -ENOMEM;
+
+	/* Generate component ID name */
+	name = devm_kasprintf(dev, GFP_KERNEL, "%s_component_id", name);
+	if (!name)
+		return -ENOMEM;
+
+	/* Configure Counter attribute */
+	counter_attr->comp.priv = (void *)id;
+
+	/* Configure device attribute */
+	sysfs_attr_init(&counter_attr->dev_attr.attr);
+	counter_attr->dev_attr.attr.name = name;
+	counter_attr->dev_attr.attr.mode = 0444;
+	counter_attr->dev_attr.show = counter_comp_id_show;
+
+	/* Store list node */
+	list_add(&counter_attr->l, &group->attr_list);
+	group->num_attr++;
+
+	return 0;
+}
+
 static struct counter_comp counter_signal_comp = {
 	.type = COUNTER_COMP_SIGNAL_LEVEL,
 	.name = "signal",
@@ -629,6 +668,11 @@ static int counter_sysfs_synapses_add(struct counter_device *const counter,
 					  COUNTER_SCOPE_COUNT, count);
 		if (err < 0)
 			return err;
+
+		/* Create Synapse component ID attribute */
+		err = counter_comp_id_attr_create(dev, group, comp.name, i);
+		if (err < 0)
+			return err;
 	}
 
 	return 0;
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:35 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:35 +0900
Subject: [PATCH v15 10/13] counter: Implement *_component_id sysfs attributes
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <2ecfebc5652f9595c79be87c0e7e64d9276d2032.1628511445.git.vilhelm.gray@gmail.com>

The Generic Counter chrdev interface expects users to supply component
IDs in order to select extensions for requests. In order for users to
know what component ID belongs to which extension this information must
be exposed. The *_component_id attribute provides a way for users to
discover what component ID belongs to which respective extension.

Cc: David Lechner <david at lechnology.com>
Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter | 16 +++++++++-
 drivers/counter/counter-sysfs.c             | 33 +++++++++++++++++----
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index 9809d8a47431..e0e99adb0ecc 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -203,12 +203,26 @@ Description:
 		both edges:
 			Any state transition.
 
+What:		/sys/bus/counter/devices/counterX/countY/ceiling_component_id
+What:		/sys/bus/counter/devices/counterX/countY/floor_component_id
+What:		/sys/bus/counter/devices/counterX/countY/count_mode_component_id
+What:		/sys/bus/counter/devices/counterX/countY/direction_component_id
+What:		/sys/bus/counter/devices/counterX/countY/enable_component_id
+What:		/sys/bus/counter/devices/counterX/countY/error_noise_component_id
+What:		/sys/bus/counter/devices/counterX/countY/prescaler_component_id
+What:		/sys/bus/counter/devices/counterX/countY/preset_component_id
+What:		/sys/bus/counter/devices/counterX/countY/preset_enable_component_id
 What:		/sys/bus/counter/devices/counterX/countY/signalZ_action_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/cable_fault_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/cable_fault_enable_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/filter_clock_prescaler_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/index_polarity_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/synchronous_mode_component_id
 KernelVersion:	5.15
 Contact:	linux-iio at vger.kernel.org
 Description:
 		Read-only attribute that indicates the component ID of the
-		respective Synapse of Count Y for Signal Z.
+		respective extension or Synapse.
 
 What:		/sys/bus/counter/devices/counterX/countY/spike_filter_ns
 KernelVersion:	5.14
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index 11bef9f8190f..df1d75e0d7b8 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -588,6 +588,7 @@ static int counter_signal_attrs_create(struct counter_device *const counter,
 	int err;
 	struct counter_comp comp;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Create main Signal attribute */
 	comp = counter_signal_comp;
@@ -603,8 +604,14 @@ static int counter_signal_attrs_create(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < signal->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, signal->ext + i,
-					  scope, signal);
+		ext = &signal->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, signal);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
@@ -695,6 +702,7 @@ static int counter_count_attrs_create(struct counter_device *const counter,
 	int err;
 	struct counter_comp comp;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Create main Count attribute */
 	comp = counter_count_comp;
@@ -719,8 +727,14 @@ static int counter_count_attrs_create(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < count->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, count->ext + i,
-					  scope, count);
+		ext = &count->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, count);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
@@ -784,6 +798,7 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 	struct device *const dev = &counter->dev;
 	int err;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Add Signals sysfs attributes */
 	err = counter_sysfs_signals_add(counter, cattr_group);
@@ -816,8 +831,14 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < counter->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, counter->ext + i,
-					  scope, NULL);
+		ext = &counter->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, NULL);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:36 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:36 +0900
Subject: [PATCH v15 11/13] counter: Implement events_queue_size sysfs attribute
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <ca9595cfd824a2a21399b21906aacad18b5f9328.1628511445.git.vilhelm.gray@gmail.com>

The events_queue_size sysfs attribute provides a way for users to
dynamically configure the Counter events queue size for the Counter
character device interface. The size is in number of struct
counter_event data structures. The number of elements will be rounded-up
to a power of 2 due to a requirement of the kfifo_alloc function called
during reallocation of the queue.

Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter |  8 ++++
 drivers/counter/counter-sysfs.c             | 45 +++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index e0e99adb0ecc..84ebb1ed28ed 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -233,6 +233,14 @@ Description:
 		shorter or equal to configured value are ignored. Value 0 means
 		filter is disabled.
 
+What:		/sys/bus/counter/devices/counterX/events_queue_size
+KernelVersion:	5.15
+Contact:	linux-iio at vger.kernel.org
+Description:
+		Size of the Counter events queue in number of struct
+		counter_event data structures. The number of elements will be
+		rounded-up to a power of 2.
+
 What:		/sys/bus/counter/devices/counterX/name
 KernelVersion:	5.2
 Contact:	linux-iio at vger.kernel.org
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index df1d75e0d7b8..d2d6495f73c5 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -3,11 +3,13 @@
  * Generic Counter sysfs interface
  * Copyright (C) 2020 William Breathitt Gray
  */
+#include <linux/bitops.h>
 #include <linux/counter.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/gfp.h>
 #include <linux/kernel.h>
+#include <linux/kfifo.h>
 #include <linux/kstrtox.h>
 #include <linux/list.h>
 #include <linux/string.h>
@@ -785,12 +787,49 @@ static int counter_num_counts_read(struct counter_device *counter, u8 *val)
 	return 0;
 }
 
+static int counter_events_queue_size_read(struct counter_device *counter,
+					  u64 *val)
+{
+	*val = kfifo_size(&counter->events);
+	return 0;
+}
+
+static int counter_events_queue_size_write(struct counter_device *counter,
+					   u64 val)
+{
+	DECLARE_KFIFO_PTR(events, struct counter_event);
+	int err = 0;
+
+	/* Verify chrdev is not currently being used */
+	if (test_and_set_bit_lock(0, counter->chrdev_lock))
+		return -EBUSY;
+
+	/* Allocate new events queue */
+	err = kfifo_alloc(&events, val, GFP_KERNEL);
+	if (err)
+		goto exit_early;
+
+	/* Swap in new events queue */
+	kfifo_free(&counter->events);
+	counter->events.kfifo = events.kfifo;
+
+exit_early:
+	clear_bit_unlock(0, counter->chrdev_lock);
+
+	return err;
+}
+
 static struct counter_comp counter_num_signals_comp =
 	COUNTER_COMP_DEVICE_U8("num_signals", counter_num_signals_read, NULL);
 
 static struct counter_comp counter_num_counts_comp =
 	COUNTER_COMP_DEVICE_U8("num_counts", counter_num_counts_read, NULL);
 
+static struct counter_comp counter_events_queue_size_comp =
+	COUNTER_COMP_DEVICE_U64("events_queue_size",
+				counter_events_queue_size_read,
+				counter_events_queue_size_write);
+
 static int counter_sysfs_attr_add(struct counter_device *const counter,
 				  struct counter_attribute_group *cattr_group)
 {
@@ -829,6 +868,12 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 	if (err < 0)
 		return err;
 
+	/* Create events_queue_size attribute */
+	err = counter_attr_create(dev, cattr_group,
+				  &counter_events_queue_size_comp, scope, NULL);
+	if (err < 0)
+		return err;
+
 	/* Create an attribute for each extension */
 	for (i = 0; i < counter->num_ext; i++) {
 		ext = &counter->ext[i];
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:37 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:37 +0900
Subject: [PATCH v15 12/13] counter: 104-quad-8: Replace mutex with spinlock
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <25d7b0c6a64bcc856e875630dbd65a3da831f269.1628511445.git.vilhelm.gray@gmail.com>

This patch replaces the mutex I/O lock with a spinlock. This is in
preparation for a subsequent patch adding IRQ support for 104-QUAD-8
devices; we can't sleep in an interrupt context, so we'll need to use a
spinlock instead.

Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c | 89 +++++++++++++++++++++---------------
 1 file changed, 52 insertions(+), 37 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index c587f295d720..a56751bf1e9b 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/types.h>
+#include <linux/spinlock.h>
 
 #define QUAD8_EXTENT 32
 
@@ -43,7 +44,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
  * @base:		base port address of the device
  */
 struct quad8 {
-	struct mutex lock;
+	spinlock_t lock;
 	struct counter_device counter;
 	unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
 	unsigned int preset[QUAD8_NUM_COUNTERS];
@@ -124,6 +125,7 @@ static int quad8_count_read(struct counter_device *counter,
 	unsigned int flags;
 	unsigned int borrow;
 	unsigned int carry;
+	unsigned long irqflags;
 	int i;
 
 	flags = inb(base_offset + 1);
@@ -133,7 +135,7 @@ static int quad8_count_read(struct counter_device *counter,
 	/* Borrow XOR Carry effectively doubles count range */
 	*val = (unsigned long)(borrow ^ carry) << 24;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Reset Byte Pointer; transfer Counter to Output Latch */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
@@ -142,7 +144,7 @@ static int quad8_count_read(struct counter_device *counter,
 	for (i = 0; i < 3; i++)
 		*val |= (unsigned long)inb(base_offset) << (8 * i);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -152,13 +154,14 @@ static int quad8_count_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
+	unsigned long irqflags;
 	int i;
 
 	/* Only 24-bit values are supported */
 	if (val > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Reset Byte Pointer */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
@@ -183,7 +186,7 @@ static int quad8_count_write(struct counter_device *counter,
 	/* Reset Error flag */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -201,8 +204,9 @@ static int quad8_function_read(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int id = count->id;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	if (priv->quadrature_mode[id])
 		switch (priv->quadrature_scale[id]) {
@@ -219,7 +223,7 @@ static int quad8_function_read(struct counter_device *counter,
 	else
 		*function = COUNTER_FUNCTION_PULSE_DIRECTION;
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -234,10 +238,11 @@ static int quad8_function_write(struct counter_device *counter,
 	unsigned int *const scale = priv->quadrature_scale + id;
 	unsigned int *const synchronous_mode = priv->synchronous_mode + id;
 	const int base_offset = priv->base + 2 * id + 1;
+	unsigned long irqflags;
 	unsigned int mode_cfg;
 	unsigned int idr_cfg;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	mode_cfg = priv->count_mode[id] << 1;
 	idr_cfg = priv->index_polarity[id] << 1;
@@ -272,7 +277,7 @@ static int quad8_function_write(struct counter_device *counter,
 			break;
 		default:
 			/* should never reach this path */
-			mutex_unlock(&priv->lock);
+			spin_unlock_irqrestore(&priv->lock, irqflags);
 			return -EINVAL;
 		}
 	}
@@ -280,7 +285,7 @@ static int quad8_function_write(struct counter_device *counter,
 	/* Load mode configuration to Counter Mode Register */
 	outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -406,9 +411,10 @@ static int quad8_index_polarity_set(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 	const int base_offset = priv->base + 2 * channel_id + 1;
+	unsigned long irqflags;
 	unsigned int idr_cfg = index_polarity << 1;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	idr_cfg |= priv->synchronous_mode[channel_id];
 
@@ -417,7 +423,7 @@ static int quad8_index_polarity_set(struct counter_device *counter,
 	/* Load Index Control configuration to Index Control Register */
 	outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -446,15 +452,16 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 	const int base_offset = priv->base + 2 * channel_id + 1;
+	unsigned long irqflags;
 	unsigned int idr_cfg = synchronous_mode;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	idr_cfg |= priv->index_polarity[channel_id] << 1;
 
 	/* Index function must be non-synchronous in non-quadrature mode */
 	if (synchronous_mode && !priv->quadrature_mode[channel_id]) {
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return -EINVAL;
 	}
 
@@ -463,7 +470,7 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
 	/* Load Index Control configuration to Index Control Register */
 	outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -510,6 +517,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 	unsigned int count_mode;
 	unsigned int mode_cfg;
 	const int base_offset = priv->base + 2 * count->id + 1;
+	unsigned long irqflags;
 
 	/* Map Generic Counter count mode to 104-QUAD-8 count mode */
 	switch (cnt_mode) {
@@ -530,7 +538,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 		return -EINVAL;
 	}
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->count_mode[count->id] = count_mode;
 
@@ -544,7 +552,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 	/* Load mode configuration to Counter Mode Register */
 	outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -564,9 +572,10 @@ static int quad8_count_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
+	unsigned long irqflags;
 	unsigned int ior_cfg;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->ab_enable[count->id] = enable;
 
@@ -575,7 +584,7 @@ static int quad8_count_enable_write(struct counter_device *counter,
 	/* Load I/O control configuration */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -626,16 +635,17 @@ static int quad8_count_preset_write(struct counter_device *counter,
 				    struct counter_count *count, u64 preset)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
 	/* Only 24-bit values are supported */
 	if (preset > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	quad8_preset_register_set(priv, count->id, preset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -644,8 +654,9 @@ static int quad8_count_ceiling_read(struct counter_device *counter,
 				    struct counter_count *count, u64 *ceiling)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Range Limit and Modulo-N count modes use preset value as ceiling */
 	switch (priv->count_mode[count->id]) {
@@ -659,7 +670,7 @@ static int quad8_count_ceiling_read(struct counter_device *counter,
 		break;
 	}
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -668,23 +679,24 @@ static int quad8_count_ceiling_write(struct counter_device *counter,
 				     struct counter_count *count, u64 ceiling)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
 	/* Only 24-bit values are supported */
 	if (ceiling > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Range Limit and Modulo-N count modes use preset value as ceiling */
 	switch (priv->count_mode[count->id]) {
 	case 1:
 	case 3:
 		quad8_preset_register_set(priv, count->id, ceiling);
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return 0;
 	}
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return -EINVAL;
 }
@@ -706,12 +718,13 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id + 1;
+	unsigned long irqflags;
 	unsigned int ior_cfg;
 
 	/* Preset enable is active low in Input/Output Control register */
 	preset_enable = !preset_enable;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->preset_enable[count->id] = preset_enable;
 
@@ -720,7 +733,7 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 	/* Load I/O control configuration to Input / Output Control Register */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -731,22 +744,23 @@ static int quad8_signal_cable_fault_read(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
+	unsigned long irqflags;
 	bool disabled;
 	unsigned int status;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	disabled = !(priv->cable_fault_enable & BIT(channel_id));
 
 	if (disabled) {
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return -EINVAL;
 	}
 
 	/* Logic 0 = cable fault */
 	status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	/* Mask respective channel and invert logic */
 	*cable_fault = !(status & BIT(channel_id));
@@ -772,9 +786,10 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
+	unsigned long irqflags;
 	unsigned int cable_fault_enable;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	if (enable)
 		priv->cable_fault_enable |= BIT(channel_id);
@@ -786,7 +801,7 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
 
 	outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -809,8 +824,9 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
 	const int base_offset = priv->base + 2 * channel_id;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->fck_prescaler[channel_id] = prescaler;
 
@@ -822,7 +838,7 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
 	     base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -991,8 +1007,7 @@ static int quad8_probe(struct device *dev, unsigned int id)
 	priv->counter.priv = priv;
 	priv->base = base[id];
 
-	/* Initialize mutex */
-	mutex_init(&priv->lock);
+	spin_lock_init(&priv->lock);
 
 	/* Reset all counters and disable interrupt function */
 	outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
-- 
2.32.0



From vilhelm.gray at gmail.com  Mon Aug  9 05:37:38 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Mon,  9 Aug 2021 21:37:38 +0900
Subject: [PATCH v15 13/13] counter: 104-quad-8: Add IRQ support for the ACCES
 104-QUAD-8
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <aaab68f0b90adcbf4b5934f1383f8c8ee4af3976.1628511445.git.vilhelm.gray@gmail.com>

The LSI/CSI LS7266R1 chip provides programmable output via the FLG pins.
When interrupts are enabled on the ACCES 104-QUAD-8, they occur whenever
FLG1 is active. Four functions are available for the FLG1 signal: Carry,
Compare, Carry-Borrow, and Index.

	Carry:
		Interrupt generated on active low Carry signal. Carry
		signal toggles every time the respective channel's
		counter overflows.

	Compare:
		Interrupt generated on active low Compare signal.
		Compare signal toggles every time respective channel's
		preset register is equal to the respective channel's
		counter.

	Carry-Borrow:
		Interrupt generated on active low Carry signal and
		active low Borrow signal. Carry signal toggles every
		time the respective channel's counter overflows. Borrow
		signal toggles every time the respective channel's
		counter underflows.

	Index:
		Interrupt generated on active high Index signal.

These four functions correspond respectivefly to the following four
Counter event types: COUNTER_EVENT_OVERFLOW, COUNTER_EVENT_THRESHOLD,
COUNTER_EVENT_OVERFLOW_UNDERFLOW, and COUNTER_EVENT_INDEX. Interrupts
push Counter events to event channel X, where 'X' is the respective
channel whose FLG1 activated.

This patch adds IRQ support for the ACCES 104-QUAD-8. The interrupt line
numbers for the devices may be configured via the irq array module
parameter.

Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c | 167 +++++++++++++++++++++++++++++++++--
 drivers/counter/Kconfig      |   6 +-
 2 files changed, 164 insertions(+), 9 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index a56751bf1e9b..1cbd60aaed69 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
+#include <linux/interrupt.h>
 #include <linux/isa.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -25,6 +26,10 @@ static unsigned int num_quad8;
 module_param_hw_array(base, uint, ioport, &num_quad8, 0);
 MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
 
+static unsigned int irq[max_num_isa_dev(QUAD8_EXTENT)];
+module_param_hw_array(irq, uint, irq, NULL, 0);
+MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
+
 #define QUAD8_NUM_COUNTERS 8
 
 /**
@@ -38,6 +43,8 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
  * @quadrature_scale:	array of quadrature mode scale configurations
  * @ab_enable:		array of A and B inputs enable configurations
  * @preset_enable:	array of set_to_preset_on_index attribute configurations
+ * @irq_trigger:	array of current IRQ trigger function configurations
+ * @next_irq_trigger:	array of next IRQ trigger function configurations
  * @synchronous_mode:	array of index function synchronous mode configurations
  * @index_polarity:	array of index function polarity configurations
  * @cable_fault_enable:	differential encoder cable status enable configurations
@@ -53,13 +60,17 @@ struct quad8 {
 	unsigned int quadrature_scale[QUAD8_NUM_COUNTERS];
 	unsigned int ab_enable[QUAD8_NUM_COUNTERS];
 	unsigned int preset_enable[QUAD8_NUM_COUNTERS];
+	unsigned int irq_trigger[QUAD8_NUM_COUNTERS];
+	unsigned int next_irq_trigger[QUAD8_NUM_COUNTERS];
 	unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
 	unsigned int index_polarity[QUAD8_NUM_COUNTERS];
 	unsigned int cable_fault_enable;
 	unsigned int base;
 };
 
+#define QUAD8_REG_INTERRUPT_STATUS 0x10
 #define QUAD8_REG_CHAN_OP 0x11
+#define QUAD8_REG_INDEX_INTERRUPT 0x12
 #define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
 #define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17
 /* Borrow Toggle flip-flop */
@@ -92,8 +103,8 @@ struct quad8 {
 #define QUAD8_RLD_CNTR_OUT 0x10
 /* Transfer Preset Register LSB to FCK Prescaler */
 #define QUAD8_RLD_PRESET_PSC 0x18
-#define QUAD8_CHAN_OP_ENABLE_COUNTERS 0x00
 #define QUAD8_CHAN_OP_RESET_COUNTERS 0x01
+#define QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC 0x04
 #define QUAD8_CMR_QUADRATURE_X1 0x08
 #define QUAD8_CMR_QUADRATURE_X2 0x10
 #define QUAD8_CMR_QUADRATURE_X4 0x18
@@ -378,13 +389,103 @@ static int quad8_action_read(struct counter_device *counter,
 	}
 }
 
+enum {
+	QUAD8_EVENT_NONE = -1,
+	QUAD8_EVENT_CARRY = 0,
+	QUAD8_EVENT_COMPARE = 1,
+	QUAD8_EVENT_CARRY_BORROW = 2,
+	QUAD8_EVENT_INDEX = 3,
+};
+
+static int quad8_events_configure(struct counter_device *counter)
+{
+	struct quad8 *const priv = counter->priv;
+	unsigned long irq_enabled = 0;
+	unsigned long irqflags;
+	size_t channel;
+	unsigned long ior_cfg;
+	unsigned long base_offset;
+
+	spin_lock_irqsave(&priv->lock, irqflags);
+
+	/* Enable interrupts for the requested channels, disable for the rest */
+	for (channel = 0; channel < QUAD8_NUM_COUNTERS; channel++) {
+		if (priv->next_irq_trigger[channel] == QUAD8_EVENT_NONE)
+			continue;
+
+		if (priv->irq_trigger[channel] != priv->next_irq_trigger[channel]) {
+			/* Save new IRQ function configuration */
+			priv->irq_trigger[channel] = priv->next_irq_trigger[channel];
+
+			/* Load configuration to I/O Control Register */
+			ior_cfg = priv->ab_enable[channel] |
+				  priv->preset_enable[channel] << 1 |
+				  priv->irq_trigger[channel] << 3;
+			base_offset = priv->base + 2 * channel + 1;
+			outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
+		}
+
+		/* Reset next IRQ trigger function configuration */
+		priv->next_irq_trigger[channel] = QUAD8_EVENT_NONE;
+
+		/* Enable IRQ line */
+		irq_enabled |= BIT(channel);
+	}
+
+	outb(irq_enabled, priv->base + QUAD8_REG_INDEX_INTERRUPT);
+
+	spin_unlock_irqrestore(&priv->lock, irqflags);
+
+	return 0;
+}
+
+static int quad8_watch_validate(struct counter_device *counter,
+				const struct counter_watch *watch)
+{
+	struct quad8 *const priv = counter->priv;
+
+	if (watch->channel > QUAD8_NUM_COUNTERS - 1)
+		return -EINVAL;
+
+	switch (watch->event) {
+	case COUNTER_EVENT_OVERFLOW:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_CARRY;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_CARRY)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_THRESHOLD:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_COMPARE;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_COMPARE)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_CARRY_BORROW;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_CARRY_BORROW)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_INDEX:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_INDEX;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_INDEX)
+			return -EINVAL;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 static const struct counter_ops quad8_ops = {
 	.signal_read = quad8_signal_read,
 	.count_read = quad8_count_read,
 	.count_write = quad8_count_write,
 	.function_read = quad8_function_read,
 	.function_write = quad8_function_write,
-	.action_read = quad8_action_read
+	.action_read = quad8_action_read,
+	.events_configure = quad8_events_configure,
+	.watch_validate = quad8_watch_validate,
 };
 
 static const char *const quad8_index_polarity_modes[] = {
@@ -579,7 +680,8 @@ static int quad8_count_enable_write(struct counter_device *counter,
 
 	priv->ab_enable[count->id] = enable;
 
-	ior_cfg = enable | priv->preset_enable[count->id] << 1;
+	ior_cfg = enable | priv->preset_enable[count->id] << 1 |
+		  priv->irq_trigger[count->id] << 3;
 
 	/* Load I/O control configuration */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
@@ -728,7 +830,8 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 
 	priv->preset_enable[count->id] = preset_enable;
 
-	ior_cfg = priv->ab_enable[count->id] | preset_enable << 1;
+	ior_cfg = priv->ab_enable[count->id] | preset_enable << 1 |
+		  priv->irq_trigger[count->id] << 3;
 
 	/* Load I/O control configuration to Input / Output Control Register */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
@@ -980,11 +1083,54 @@ static struct counter_count quad8_counts[] = {
 	QUAD8_COUNT(7, "Channel 8 Count")
 };
 
+static irqreturn_t quad8_irq_handler(int irq, void *private)
+{
+	struct quad8 *const priv = private;
+	const unsigned long base = priv->base;
+	unsigned long irq_status;
+	unsigned long channel;
+	u8 event;
+
+	irq_status = inb(base + QUAD8_REG_INTERRUPT_STATUS);
+	if (!irq_status)
+		return IRQ_NONE;
+
+	for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) {
+		switch (priv->irq_trigger[channel]) {
+		case QUAD8_EVENT_CARRY:
+			event = COUNTER_EVENT_OVERFLOW;
+				break;
+		case QUAD8_EVENT_COMPARE:
+			event = COUNTER_EVENT_THRESHOLD;
+				break;
+		case QUAD8_EVENT_CARRY_BORROW:
+			event = COUNTER_EVENT_OVERFLOW_UNDERFLOW;
+				break;
+		case QUAD8_EVENT_INDEX:
+			event = COUNTER_EVENT_INDEX;
+				break;
+		default:
+			/* should never reach this path */
+			WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
+				  priv->irq_trigger[channel], channel);
+			continue;
+		}
+
+		counter_push_event(&priv->counter, event, channel);
+	}
+
+	/* Clear pending interrupts on device */
+	outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
+
+	return IRQ_HANDLED;
+}
+
 static int quad8_probe(struct device *dev, unsigned int id)
 {
 	struct quad8 *priv;
 	int i, j;
 	unsigned int base_offset;
+	int err;
 
 	if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
@@ -1009,6 +1155,8 @@ static int quad8_probe(struct device *dev, unsigned int id)
 
 	spin_lock_init(&priv->lock);
 
+	/* Reset Index/Interrupt Register */
+	outb(0x00, base[id] + QUAD8_REG_INDEX_INTERRUPT);
 	/* Reset all counters and disable interrupt function */
 	outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
 	/* Set initial configuration for all counters */
@@ -1035,11 +1183,18 @@ static int quad8_probe(struct device *dev, unsigned int id)
 		outb(QUAD8_CTR_IOR, base_offset + 1);
 		/* Disable index function; negative index polarity */
 		outb(QUAD8_CTR_IDR, base_offset + 1);
+		/* Initialize next IRQ trigger function configuration */
+		priv->next_irq_trigger[i] = QUAD8_EVENT_NONE;
 	}
 	/* Disable Differential Encoder Cable Status for all channels */
 	outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS);
-	/* Enable all counters */
-	outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
+	/* Enable all counters and enable interrupt function */
+	outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base[id] + QUAD8_REG_CHAN_OP);
+
+	err = devm_request_irq(dev, irq[id], quad8_irq_handler, IRQF_SHARED,
+			       priv->counter.name, priv);
+	if (err)
+		return err;
 
 	return devm_counter_register(dev, &priv->counter);
 }
diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index d5d2540b30c2..3dcdb681c4e4 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -23,11 +23,11 @@ config 104_QUAD_8
 	  A counter's respective error flag may be cleared by performing a write
 	  operation on the respective count value attribute. Although the
 	  104-QUAD-8 counters have a 25-bit range, only the lower 24 bits may be
-	  set, either directly or via the counter's preset attribute. Interrupts
-	  are not supported by this driver.
+	  set, either directly or via the counter's preset attribute.
 
 	  The base port addresses for the devices may be configured via the base
-	  array module parameter.
+	  array module parameter. The interrupt line numbers for the devices may
+	  be configured via the irq array module parameter.
 
 config INTERRUPT_CNT
 	tristate "Interrupt counter driver"
-- 
2.32.0



From geert at linux-m68k.org  Mon Aug  9 05:46:02 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 9 Aug 2021 14:46:02 +0200
Subject: [PATCH 4/5] ARM: Add basic support for EcoNet EN7523 SoC
In-Reply-To: <1e3070fe-b5da-0acc-f50b-b0986a1045cd@biot.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-5-bert@biot.com>
 <CAK8P3a3OuJ3pMSdEA4Rt3aWvvuX2+_Bg5x7-kZ1++fvvJvgGxA@mail.gmail.com>
 <1e3070fe-b5da-0acc-f50b-b0986a1045cd@biot.com>
Message-ID: <CAMuHMdWni=2ggV7dQiy-nfF1nOmKferbZOCkLp0kDsvMNfwF2Q@mail.gmail.com>

Hoi Bert,

On Wed, Aug 4, 2021 at 6:43 PM Bert Vermeulen <bert at biot.com> wrote:
> On 7/30/21 4:48 PM, Arnd Bergmann wrote:
> > On Fri, Jul 30, 2021 at 3:45 PM Bert Vermeulen <bert at biot.com> wrote:
> >> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> >> index 173da685a52e..1bff0aa29c07 100644
> >> --- a/arch/arm/Makefile
> >> +++ b/arch/arm/Makefile
> >> @@ -152,6 +152,7 @@ textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
> >>  textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
> >>  textofs-$(CONFIG_ARCH_MESON) := 0x00208000
> >>  textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
> >> +textofs-$(CONFIG_ARCH_ECONET) := 0x00088000
> >
> > Why is this needed?
> >
> > Note also the comment directly above it exlaining
> > # Text offset. This list is sorted numerically by address in order to
> > # provide a means to avoid/resolve conflicts in multi-arch kernels.
>
> I didn't make that patch, but it turns out it's needed to get PSCI working;
> detection hangs without it. That makes no sense to me, but I'll examine further.

Probably PSCI relies on the memory contents at the start of RAM not
being overwritten?
Does it help if you remove the first 512 KiB from the /memory node
(which should be declared in en7523-evb.dts instead of en7523.dtsi
BTW)?

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From will at kernel.org  Mon Aug  9 05:49:32 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 13:49:32 +0100
Subject: [PATCH v3 25/25] iommu: Allow enabling non-strict mode dynamically
In-Reply-To: <22b044263f69e2bfe404c4379a435005ea58b3e2.1628094601.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <22b044263f69e2bfe404c4379a435005ea58b3e2.1628094601.git.robin.murphy@arm.com>
Message-ID: <20210809124931.GA1097@willie-the-truck>

On Wed, Aug 04, 2021 at 06:15:53PM +0100, Robin Murphy wrote:
> Allocating and enabling a flush queue is in fact something we can
> reasonably do while a DMA domain is active, without having to rebuild it
> from scratch. Thus we can allow a strict -> non-strict transition from
> sysfs without requiring to unbind the device's driver, which is of
> particular interest to users who want to make selective relaxations to
> critical devices like the one serving their root filesystem.
> 
> Disabling and draining a queue also seems technically possible to
> achieve without rebuilding the whole domain, but would certainly be more
> involved. Furthermore there's not such a clear use-case for tightening
> up security *after* the device may already have done whatever it is that
> you don't trust it not to do, so we only consider the relaxation case.
> 
> CC: Sai Praneeth Prakhya <sai.praneeth.prakhya at intel.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> 
> ---
> 
> v3: Actually think about concurrency, rework most of the fq data
>     accesses to be (hopefully) safe and comment it all
> ---
>  drivers/iommu/dma-iommu.c | 25 ++++++++++++++++++-------
>  drivers/iommu/iommu.c     | 16 ++++++++++++----
>  drivers/iommu/iova.c      |  9 ++++++---
>  3 files changed, 36 insertions(+), 14 deletions(-)

I failed to break this, so hopefully you've caught everything now.

Only thing I wasn't sure of is why we still need the smp_wmb() in
init_iova_flush_queue(). Can we remove it now that we have one before
assigning into the cookie?

Will


From ardb at kernel.org  Mon Aug  9 05:49:28 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 9 Aug 2021 14:49:28 +0200
Subject: [PATCH 4/5] ARM: Add basic support for EcoNet EN7523 SoC
In-Reply-To: <CAMuHMdWni=2ggV7dQiy-nfF1nOmKferbZOCkLp0kDsvMNfwF2Q@mail.gmail.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-5-bert@biot.com>
 <CAK8P3a3OuJ3pMSdEA4Rt3aWvvuX2+_Bg5x7-kZ1++fvvJvgGxA@mail.gmail.com>
 <1e3070fe-b5da-0acc-f50b-b0986a1045cd@biot.com>
 <CAMuHMdWni=2ggV7dQiy-nfF1nOmKferbZOCkLp0kDsvMNfwF2Q@mail.gmail.com>
Message-ID: <CAMj1kXFUpb6JYndtX9LPpr-dOFQ2-m7n0z70+7Bh-JHhnfoMpw@mail.gmail.com>

On Mon, 9 Aug 2021 at 14:46, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hoi Bert,
>
> On Wed, Aug 4, 2021 at 6:43 PM Bert Vermeulen <bert at biot.com> wrote:
> > On 7/30/21 4:48 PM, Arnd Bergmann wrote:
> > > On Fri, Jul 30, 2021 at 3:45 PM Bert Vermeulen <bert at biot.com> wrote:
> > >> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > >> index 173da685a52e..1bff0aa29c07 100644
> > >> --- a/arch/arm/Makefile
> > >> +++ b/arch/arm/Makefile
> > >> @@ -152,6 +152,7 @@ textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
> > >>  textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
> > >>  textofs-$(CONFIG_ARCH_MESON) := 0x00208000
> > >>  textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
> > >> +textofs-$(CONFIG_ARCH_ECONET) := 0x00088000
> > >
> > > Why is this needed?
> > >
> > > Note also the comment directly above it exlaining
> > > # Text offset. This list is sorted numerically by address in order to
> > > # provide a means to avoid/resolve conflicts in multi-arch kernels.
> >
> > I didn't make that patch, but it turns out it's needed to get PSCI working;
> > detection hangs without it. That makes no sense to me, but I'll examine further.
>
> Probably PSCI relies on the memory contents at the start of RAM not
> being overwritten?
> Does it help if you remove the first 512 KiB from the /memory node

I /think/ we rely on the first memblock being mappable using section
mappings, so it might be better to remove the first 1 MB (or 2 MB in
case the platform is LPAE capable). Note that this memory is discarded
in any case, so this change is not as costly as it may seem.


> (which should be declared in en7523-evb.dts instead of en7523.dtsi
> BTW)?
>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds


From will at kernel.org  Mon Aug  9 05:52:39 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 13:52:39 +0100
Subject: [PATCH v3 24/25] iommu/dma: Factor out flush queue init
In-Reply-To: <3b5284ee394f267ba966839173f874fc9a996bb2.1628094601.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <3b5284ee394f267ba966839173f874fc9a996bb2.1628094601.git.robin.murphy@arm.com>
Message-ID: <20210809125238.GB1097@willie-the-truck>

On Wed, Aug 04, 2021 at 06:15:52PM +0100, Robin Murphy wrote:
> Factor out flush queue setup from the initial domain init so that we
> can potentially trigger it from sysfs later on in a domain's lifetime.
> 
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Reviewed-by: John Garry <john.garry at huawei.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  drivers/iommu/dma-iommu.c | 30 ++++++++++++++++++++----------
>  include/linux/dma-iommu.h |  9 ++++++---
>  2 files changed, 26 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index 2e19505dddf9..f51b8dc99ac6 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -310,6 +310,25 @@ static bool dev_is_untrusted(struct device *dev)
>  	return dev_is_pci(dev) && to_pci_dev(dev)->untrusted;
>  }
>  
> +int iommu_dma_init_fq(struct iommu_domain *domain)
> +{
> +	struct iommu_dma_cookie *cookie = domain->iova_cookie;
> +
> +	if (domain->type != IOMMU_DOMAIN_DMA_FQ)
> +		return -EINVAL;
> +	if (cookie->fq_domain)
> +		return 0;
> +
> +	if (init_iova_flush_queue(&cookie->iovad, iommu_dma_flush_iotlb_all,
> +				  iommu_dma_entry_dtor)) {
> +		pr_warn("iova flush queue initialization failed\n");
> +		domain->type = IOMMU_DOMAIN_DMA;
> +		return -ENODEV;

I do find this a bit odd: we assert that the caller has set domain->type
to IOMMU_DOMAIN_DMA_FQ but then on failure we reset it to IOMMU_DOMAIN_DMA
here. I think it would be less error-prone if the setting of domain->type
was handled in the same function.

Will


From max.chou at realtek.com  Mon Aug  9 06:01:52 2021
From: max.chou at realtek.com (max.chou at realtek.com)
Date: Mon, 9 Aug 2021 21:01:52 +0800
Subject: [PATCH] Bluetooth: btusb: Remove WAKEUP_DISABLE and add
 WAKEUP_AUTOSUSPEND for Realtek devices
Message-ID: <20210809130152.12528-1-max.chou@realtek.com>

From: Max Chou <max.chou at realtek.com>

For the commit of 9e45524a011107a73bc2cdde8370c61e82e93a4d, wakeup is
always disabled for Realtek devices. However, there's the capability
for Realtek devices to apply USB wake-up.

In this commit, remove WAKEUP_DISABLE feature for Realtek devices.
If users would switch wake-up, they should access
"/sys/bus/usb/.../power/wakeup"

In this commit, it also adds the feature as WAKEUP_AUTOSUSPEND
for Realtek devices because it should set do_remote_wakeup on autosuspend.

Signed-off-by: Max Chou <max.chou at realtek.com>
Tested-by: Hilda Wu <hildawu at realtek.com>
Reviewed-by: Archie Pusaka <apusaka at chromium.org>
Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit at chromium.org>
---
 drivers/bluetooth/btusb.c | 25 +++++++++----------------
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 488f110e17e2..73a835bf37f7 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -527,7 +527,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
 #define BTUSB_OOB_WAKE_ENABLED	11
 #define BTUSB_HW_RESET_ACTIVE	12
 #define BTUSB_TX_WAIT_VND_EVT	13
-#define BTUSB_WAKEUP_DISABLE	14
+#define BTUSB_WAKEUP_AUTOSUSPEND	14
 
 struct btusb_data {
 	struct hci_dev       *hdev;
@@ -1349,13 +1349,6 @@ static int btusb_open(struct hci_dev *hdev)
 
 	data->intf->needs_remote_wakeup = 1;
 
-	/* Disable device remote wakeup when host is suspended
-	 * For Realtek chips, global suspend without
-	 * SET_FEATURE (DEVICE_REMOTE_WAKEUP) can save more power in device.
-	 */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
-		device_wakeup_disable(&data->udev->dev);
-
 	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
 		goto done;
 
@@ -1422,7 +1415,7 @@ static int btusb_close(struct hci_dev *hdev)
 	data->intf->needs_remote_wakeup = 0;
 
 	/* Enable remote wake up for auto-suspend */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
+	if (test_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags))
 		data->intf->needs_remote_wakeup = 1;
 
 	usb_autopm_put_interface(data->intf);
@@ -3877,11 +3870,8 @@ static int btusb_probe(struct usb_interface *intf,
 		hdev->shutdown = btrtl_shutdown_realtek;
 		hdev->cmd_timeout = btusb_rtl_cmd_timeout;
 
-		/* Realtek devices lose their updated firmware over global
-		 * suspend that means host doesn't send SET_FEATURE
-		 * (DEVICE_REMOTE_WAKEUP)
-		 */
-		set_bit(BTUSB_WAKEUP_DISABLE, &data->flags);
+		/* Realtek devices need to set remote wakeup on auto-suspend */
+		set_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags);
 	}
 
 	if (!reset)
@@ -4056,12 +4046,15 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
 	 * Actually, it depends on whether the usb host sends
 	 * set feature (enable wakeup) or not.
 	 */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags)) {
+	if (test_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags)) {
 		if (PMSG_IS_AUTO(message) &&
 		    device_can_wakeup(&data->udev->dev))
 			data->udev->do_remote_wakeup = 1;
-		else if (!PMSG_IS_AUTO(message))
+		else if (!PMSG_IS_AUTO(message) &&
+			 !device_may_wakeup(&data->udev->dev)) {
+			data->udev->do_remote_wakeup = 0;
 			data->udev->reset_resume = 1;
+		}
 	}
 
 	return 0;
-- 
2.17.1



From bert at biot.com  Mon Aug  9 06:00:12 2021
From: bert at biot.com (Bert Vermeulen)
Date: Mon, 9 Aug 2021 15:00:12 +0200
Subject: [PATCH 4/5] ARM: Add basic support for EcoNet EN7523 SoC
In-Reply-To: <CAMuHMdWni=2ggV7dQiy-nfF1nOmKferbZOCkLp0kDsvMNfwF2Q@mail.gmail.com>
References: <20210730134552.853350-1-bert@biot.com>
 <20210730134552.853350-5-bert@biot.com>
 <CAK8P3a3OuJ3pMSdEA4Rt3aWvvuX2+_Bg5x7-kZ1++fvvJvgGxA@mail.gmail.com>
 <1e3070fe-b5da-0acc-f50b-b0986a1045cd@biot.com>
 <CAMuHMdWni=2ggV7dQiy-nfF1nOmKferbZOCkLp0kDsvMNfwF2Q@mail.gmail.com>
Message-ID: <c9ec706f-4a55-a716-ed2e-5c04a6f6bffd@biot.com>

On 8/9/21 2:46 PM, Geert Uytterhoeven wrote:
>> I didn't make that patch, but it turns out it's needed to get PSCI working;
>> detection hangs without it. That makes no sense to me, but I'll examine further.
> 
> Probably PSCI relies on the memory contents at the start of RAM not
> being overwritten?

It turns out to hang at the first SMC call, for PSCI_0_2_FN_PSCI_VERSION. I 
assume the receiver of that call, ATF, got dropped in that region by the 
vendor's U-Boot.

> Does it help if you remove the first 512 KiB from the /memory node
> (which should be declared in en7523-evb.dts instead of en7523.dtsi
> BTW)?
No it doesn't, was just trying to work out why not, in your 
fdt_check_mem_start().

Anyway that was Arnd's first suggestion, but I think his second suggestion 
(teach fdt_check_mem_start() about /memreserve/) is the cleaner approach to 
this. Opinions?


-- 
Bert Vermeulen
bert at biot.com


From nm at ti.com  Mon Aug  9 06:06:31 2021
From: nm at ti.com (Nishanth Menon)
Date: Mon, 9 Aug 2021 08:06:31 -0500
Subject: arm64: dts: TI K3 updates for v5.15
Message-ID: <20210809130631.pfvntcichsyeekbo@festive>

Hi Arnd and Olof,

Here is the DT updates for 5.15. Just minor additions this time around.

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/nmenon/linux.git tags/ti-k3-dt-for-v5.15

for you to fetch changes up to c1fa5ac6c2f475b5140e6323801ed93c24e7e5cf:

  arm64: dts: ti: k3-am642-sk: Add pwm nodes (2021-07-30 10:44:42 -0500)

----------------------------------------------------------------
Devicetree changes for TI K3 platforms for v5.15 merge window:

* New features:
  - AM64 adds pwm and ecap capability

----------------------------------------------------------------
Lokesh Vutla (4):
      arm64: dts: ti: k3-am64-main: Add epwm nodes
      arm64: dts: ti: k3-am64-main: Add ecap pwm nodes
      arm64: dts: ti: k3-am642-evm: Add pwm nodes
      arm64: dts: ti: k3-am642-sk: Add pwm nodes

 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 114 +++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am642-evm.dts  |  56 +++++++++++++++
 arch/arm64/boot/dts/ti/k3-am642-sk.dts   |  64 +++++++++++++++++
 3 files changed, 234 insertions(+)

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210809/913a494d/attachment.sig>

From will at kernel.org  Mon Aug  9 06:09:17 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 14:09:17 +0100
Subject: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU schedule out
In-Reply-To: <b2146ea5db47485f8410a4c1ab0c15fe@huawei.com>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
 <20210803114034.GB30853@willie-the-truck>
 <ee2863107d614ef8a36006b5aa912eca@huawei.com>
 <20210803153036.GA31125@willie-the-truck>
 <b2146ea5db47485f8410a4c1ab0c15fe@huawei.com>
Message-ID: <20210809130917.GA1207@willie-the-truck>

On Fri, Aug 06, 2021 at 12:24:36PM +0000, Shameerali Kolothum Thodi wrote:
> These are some test numbers with and without this patch, run on two
> different test setups.
> 
> 
> a)Test Setup -1
> -----------------------
> 
> Platform: HiSilicon D06 with 128 CPUs, VMID bits = 16
> Run 128 VMs concurrently each with 2 vCPUs. Each Guest will execute hackbench
> 5 times before exiting.
> 
> Measurements taken avg. of 10 Runs.
> 
> Image : 5.14-rc3
> ---------------------------
>   Time(s)       44.43813888
>   No. of exits    145,348,264
> 
> Image: 5.14-rc3 + vmid-v3
> ----------------------------------------
>   Time(s)        46.59789034
>   No. of exits     133,587,307
> 
> %diff against 5.14-rc3
>   Time: 4.8% more
>   Exits: 8% less 
> 
> Image: 5.14-rc3 + vmid-v3 + Without active_asid clear
> ---------------------------------------------------------------------------
>   Time(s)         44.5031782
>   No. of exits      144,443,188
> 
> %diff against 5.14-rc3
>   Time: 0.15% more
>   Exits: 2.42% less
> 
> b)Test Setup -2
> -----------------------
> 
> Platform: HiSilicon D06 + Kernel with maxcpus set to 8 and VMID bits set to 4.
> Run 40 VMs concurrently each with 2 vCPUs. Each Guest will execute hackbench
> 5 times before exiting.
> 
> Measurements taken avg. of 10 Runs.
> 
> Image : 5.14-rc3-vmid4bit
> ------------------------------------
>   Time(s)        46.19963266
>   No. of exits     23,699,546
> 
> Image: 5.14-rc3-vmid4bit + vmid-v3
> ---------------------------------------------------
>   Time(s)          45.83307736
>   No. of exits      23,260,203
> 
> %diff against 5.14-rc3-vmid4bit
>   Time: 0.8% less
>   Exits: 1.85% less 
> 
> Image: 5.14-rc3-vmid4bit + vmid-v3 + Without active_asid clear
> -----------------------------------------------------------------------------------------
>   Time(s)           44.5031782
>   No. of exits        144,443,188

Really? The *exact* same numbers as the "Image: 5.14-rc3 + vmid-v3 + Without
active_asid clear" configuration? Guessing a copy-paste error here.

> %diff against 5.14-rc3-vmid4bit
>   Time: 1.05% less
>   Exits: 2.06% less
> 
> As expected, the active_asid clear on schedule out is not helping.
> But without this patch, the numbers seems to be better than the
> vanilla kernel when we force the setup(cpus=8, vmd=4bits)
> to perform rollover.

I'm struggling a bit to understand these numbers. Are you saying that
clearing the active_asid helps in the 16-bit VMID case but not in the
4-bit case?

Why would the active_asid clear have any impact on the number of exits?

The problem I see with not having the active_asid clear is that we will
roll over more frequently as the number of reserved VMIDs increases.

Will


From christianshewitt at gmail.com  Mon Aug  9 06:10:45 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  9 Aug 2021 13:10:45 +0000
Subject: [PATCH 0/2] arm64: dts: amlogic: add support for Radxa Zero
Message-ID: <20210809131047.28047-1-christianshewitt@gmail.com>

This adds support for the Radxa Zero SBC. The device-tree is loosely
based upon existing support for SEI510 and U200 (also G12A boards)
and has been developed with the 4/32 board configuration.

Christian Hewitt (2):
  dt-bindings: arm: amlogic: add support for Radxa Zero
  arm64: dts: amlogic: add support for Radxa Zero

 .../devicetree/bindings/arm/amlogic.yaml      |   1 +
 arch/arm64/boot/dts/amlogic/Makefile          |   1 +
 .../dts/amlogic/meson-g12a-radxa-zero.dts     | 418 ++++++++++++++++++
 3 files changed, 420 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts

-- 
2.17.1



From christianshewitt at gmail.com  Mon Aug  9 06:10:46 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  9 Aug 2021 13:10:46 +0000
Subject: [PATCH 1/2] dt-bindings: arm: amlogic: add support for Radxa Zero
In-Reply-To: <20210809131047.28047-1-christianshewitt@gmail.com>
References: <20210809131047.28047-1-christianshewitt@gmail.com>
Message-ID: <20210809131047.28047-2-christianshewitt@gmail.com>

Radxa Zero is a small form-factor SBC with an Amlogic S905Y2 chip.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 6423377710ee..67dccdd9a5a4 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -141,6 +141,7 @@ properties:
           - enum:
               - amediatech,x96-max
               - amlogic,u200
+              - radxa,zero
               - seirobotics,sei510
           - const: amlogic,g12a
 
-- 
2.17.1



From christianshewitt at gmail.com  Mon Aug  9 06:10:47 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  9 Aug 2021 13:10:47 +0000
Subject: [PATCH 2/2] arm64: dts: amlogic: add support for Radxa Zero
In-Reply-To: <20210809131047.28047-1-christianshewitt@gmail.com>
References: <20210809131047.28047-1-christianshewitt@gmail.com>
Message-ID: <20210809131047.28047-3-christianshewitt@gmail.com>

Radxa Zero is a small form factor SBC based on the Amlogic S905Y2
chipset that ships in a number of RAM/eMMC configurations:

Boards with 512MB/1GB LPDDR4 RAM have no eMMC storage and BCM43436
wireless (2.4GHz b/g/n) while 2GB/4GB boards have 8/16/32/64/128GB
eMMC storage and BCM4345 wireless (2.4/5GHz a/b/g/n/ac).

- Amlogic S905Y2 quad-core Cortex-A53
- Mali G31-MP2 GPU
- HDMI 2.1 output (micro)
- 1x USB 2.0 port - Type C (OTG)
- 1x USB 3.0 port - Type C (Host)
- 1x micro SD Card slot
- 40 Pin GPIO header

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   1 +
 .../dts/amlogic/meson-g12a-radxa-zero.dts     | 418 ++++++++++++++++++
 2 files changed, 419 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index faa0a79a34f5..be308361e2f1 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12a-radxa-zero.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
new file mode 100644
index 000000000000..d44d3881d9b9
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
@@ -0,0 +1,418 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 BayLibre SAS. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-g12a.dtsi"
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "radxa,zero", "amlogic,g12a";
+	model = "Radxa Zero";
+
+	aliases {
+		serial0 = &uart_AO;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	cvbs-connector {
+		status = "disabled";
+		compatible = "composite-video-connector";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	flash_1v8: regulator-flash_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "FLASH_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_3v3>;
+		regulator-always-on;
+	};
+
+	dc_in: regulator-dc_in {
+		compatible = "regulator-fixed";
+		regulator-name = "DC_IN";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	vcc_1v8: regulator-vcc_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_3v3>;
+		regulator-always-on;
+	};
+
+	vcc_3v3: regulator-vcc_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vcc_5v: regulator-vcc_5v {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_in>;
+
+		gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
+		enable-active-low;
+	};
+
+	vddao_1v8: regulator-vddao_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	vddcpu: regulator-vddcpu {
+		compatible = "pwm-regulator";
+
+		regulator-name = "VDDCPU";
+		regulator-min-microvolt = <721000>;
+		regulator-max-microvolt = <1022000>;
+
+		vin-supply = <&dc_in>;
+
+		pwms = <&pwm_AO_cd 1 1250 0>;
+		pwm-dutycycle-range = <100 0>;
+
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "RADXA-ZERO";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&cec_AO {
+	pinctrl-0 = <&cec_ao_a_h_pins>;
+	pinctrl-names = "default";
+	status = "disabled";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+	pinctrl-0 = <&cec_ao_b_h_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu1 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu2 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu3 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+	pinctrl-names = "default";
+	hdmi-supply = <&vcc_5v>;
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&ir {
+	status = "disabled";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&pwm_AO_cd {
+	pinctrl-0 = <&pwm_ao_d_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin1";
+	status = "okay";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddao_1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+	max-frequency = <100000000>;
+
+	non-removable;
+	disable-wp;
+
+	/* WiFi firmware requires power to be kept while in suspend */
+	keep-power-in-suspend;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddao_1v8>;
+
+	brcmf: wifi at 1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+		interrupts = <&gpio GPIOX_7 GPIO_ACTIVE_HIGH>;
+		interrupt-names = "host-wake";
+	};
+};
+
+/* SD card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_c_pins>;
+	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
+	pinctrl-1 = <&emmc_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	max-frequency = <200000000>;
+	disable-wp;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&flash_1v8>;
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
+
+&uart_A {
+	status = "okay";
+	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+		max-speed = <2000000>;
+		clocks = <&wifi32k>;
+		clock-names = "lpo";
+	};
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&usb {
+	status = "okay";
+	dr_mode = "host";
+};
-- 
2.17.1



From krzysztof.kozlowski at canonical.com  Mon Aug  9 06:09:34 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 15:09:34 +0200
Subject: [PATCH 1/2] dt-bindings: clock: samsung: convert Exynos3250 to
 dtschema
In-Reply-To: <20210809130935.80565-1-krzysztof.kozlowski@canonical.com>
References: <20210809130935.80565-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210809130935.80565-2-krzysztof.kozlowski@canonical.com>

Merge Exynos3250 clock controller bindings to existing DT schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos3250-clock.txt       | 57 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  |  3 +
 2 files changed, 3 insertions(+), 57 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos3250-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/exynos3250-clock.txt b/Documentation/devicetree/bindings/clock/exynos3250-clock.txt
deleted file mode 100644
index 7441ed519f02..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos3250-clock.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-* Samsung Exynos3250 Clock Controller
-
-The Exynos3250 clock controller generates and supplies clock to various
-controllers within the Exynos3250 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos3250-cmu" - controller compatible with Exynos3250 SoC.
-  - "samsung,exynos3250-cmu-dmc" - controller compatible with
-    Exynos3250 SoC for Dynamic Memory Controller domain.
-  - "samsung,exynos3250-cmu-isp" - ISP block clock controller compatible
-     with Exynos3250 SOC
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos3250.h header and can be used in device
-tree sources.
-
-Example 1: Examples of clock controller nodes are listed below.
-
-	cmu: clock-controller at 10030000 {
-		compatible = "samsung,exynos3250-cmu";
-		reg = <0x10030000 0x20000>;
-		#clock-cells = <1>;
-	};
-
-	cmu_dmc: clock-controller at 105c0000 {
-		compatible = "samsung,exynos3250-cmu-dmc";
-		reg = <0x105C0000 0x2000>;
-		#clock-cells = <1>;
-	};
-
-	cmu_isp: clock-controller at 10048000 {
-		compatible = "samsung,exynos3250-cmu-isp";
-		reg = <0x10048000 0x1000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13800000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13800000 0x100>;
-		interrupts = <0 109 0>;
-		clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index b0f58a1cf6cb..c7b07fcd3fa1 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -20,6 +20,9 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - samsung,exynos3250-cmu
+          - samsung,exynos3250-cmu-dmc
+          - samsung,exynos3250-cmu-isp
           - samsung,exynos5250-clock
           - samsung,exynos5420-clock
           - samsung,exynos5800-clock
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Aug  9 06:09:33 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 15:09:33 +0200
Subject: [PATCH 0/2] dt-bindings: clock: samsung: more conversions
Message-ID: <20210809130935.80565-1-krzysztof.kozlowski@canonical.com>

Hi,

Conversion of Exynos4 and Exynos3250 seems straightforward.

This depends on:
https://lore.kernel.org/linux-samsung-soc/20210809120544.56596-1-krzysztof.kozlowski at canonical.com/

Best regards,
Krzysztof


Krzysztof Kozlowski (2):
  dt-bindings: clock: samsung: convert Exynos3250 to dtschema
  dt-bindings: clock: samsung: convert Exynos4 to dtschema

 .../bindings/clock/exynos3250-clock.txt       | 57 ------------
 .../bindings/clock/exynos4-clock.txt          | 86 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  | 32 ++++++-
 3 files changed, 31 insertions(+), 144 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos3250-clock.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt

-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Aug  9 06:09:35 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 15:09:35 +0200
Subject: [PATCH 2/2] dt-bindings: clock: samsung: convert Exynos4 to dtschema
In-Reply-To: <20210809130935.80565-1-krzysztof.kozlowski@canonical.com>
References: <20210809130935.80565-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210809130935.80565-3-krzysztof.kozlowski@canonical.com>

Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos4-clock.txt          | 86 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  | 29 ++++++-
 2 files changed, 28 insertions(+), 87 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
deleted file mode 100644
index 17bb11365354..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-* Samsung Exynos4 Clock Controller
-
-The Exynos4 clock controller generates and supplies clock to various controllers
-within the Exynos4 SoC. The clock binding described here is applicable to all
-SoC's in the Exynos4 family.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
-  - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos4.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10030000 {
-		compatible = "samsung,exynos4210-clock";
-		reg = <0x10030000 0x20000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
-
-Exynos4412 SoC contains some additional clocks for FIMC-ISP (Camera ISP)
-subsystem. Registers for those clocks are located in the ISP power domain.
-Because those registers are also located in a different memory region than
-the main clock controller, a separate clock controller has to be defined for
-handling them.
-
-Required Properties:
-
-- compatible: should be "samsung,exynos4412-isp-clock".
-
-- reg: physical base address of the ISP clock controller and length of memory
-  mapped region.
-
-- #clock-cells: should be 1.
-
-- clocks: list of the clock controller input clock identifiers,
-  from common clock bindings, should point to CLK_ACLK200 and
-  CLK_ACLK400_MCUISP clocks from the main clock controller.
-
-- clock-names: list of the clock controller input clock names,
-  as described in clock-bindings.txt, should be "aclk200" and
-  "aclk400_mcuisp".
-
-- power-domains: a phandle to ISP power domain node as described by
-  generic PM domain bindings.
-
-Example 3: The clock controllers bindings for Exynos4412 SoCs.
-
-	clock: clock-controller at 10030000 {
-		compatible = "samsung,exynos4412-clock";
-		reg = <0x10030000 0x18000>;
-		#clock-cells = <1>;
-	};
-
-	isp_clock: clock-controller at 10048000 {
-		compatible = "samsung,exynos4412-isp-clock";
-		reg = <0x10048000 0x1000>;
-		#clock-cells = <1>;
-		power-domains = <&pd_isp>;
-		clocks = <&clock CLK_ACLK200>, <&clock CLK_ACLK400_MCUISP>;
-		clock-names = "aclk200", "aclk400_mcuisp";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index c7b07fcd3fa1..ea73201f259b 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -23,6 +23,9 @@ properties:
           - samsung,exynos3250-cmu
           - samsung,exynos3250-cmu-dmc
           - samsung,exynos3250-cmu-isp
+          - samsung,exynos4210-clock
+          - samsung,exynos4412-clock
+          - samsung,exynos4412-isp-clock
           - samsung,exynos5250-clock
           - samsung,exynos5420-clock
           - samsung,exynos5800-clock
@@ -35,11 +38,18 @@ properties:
   assigned-clocks: true
   assigned-clock-parents: true
   assigned-clock-rates: true
-  clocks: true
+  clocks:
+    description: |
+      For samsung,exynos4412-isp-clock, the input clocks should be CLK_ACLK200
+      and CLK_ACLK400_MCUISP from the main clock controller.
+
+  clock-names: true
 
   "#clock-cells":
     const: 1
 
+  power-domains: true
+
   reg:
     maxItems: 1
 
@@ -50,6 +60,23 @@ required:
 
 additionalProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos4412-isp-clock
+    then:
+      properties:
+        clock-names:
+          items:
+            - const: aclk200
+            - const: aclk400_mcuisp
+      required:
+        - clocks
+        - clock-names
+        - power-domains
+
 examples:
   - |
     #include <dt-bindings/clock/exynos5250.h>
-- 
2.30.2



From vladimir.oltean at nxp.com  Mon Aug  9 06:11:52 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Mon,  9 Aug 2021 16:11:52 +0300
Subject: [PATCH net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
Message-ID: <20210809131152.509092-1-vladimir.oltean@nxp.com>

The blamed commit a new field to struct switchdev_notifier_fdb_info, but
did not make sure that all call paths set it to something valid. For
example, a switchdev driver may emit a SWITCHDEV_FDB_ADD_TO_BRIDGE
notifier, and since the 'is_local' flag is not set, it contains junk
from the stack, so the bridge might interpret those notifications as
being for local FDB entries when that was not intended.

To avoid that now and in the future, zero-initialize all
switchdev_notifier_fdb_info structures created by drivers such that all
newly added fields to not need to touch drivers again.

Fixes: 2c4eca3ef716 ("net: bridge: switchdev: include local flag in FDB notifications")
Reported-by: Ido Schimmel <idosch at idosch.org>
Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 drivers/net/ethernet/marvell/prestera/prestera_switchdev.c | 2 ++
 drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c       | 1 +
 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c      | 2 ++
 drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 1 +
 drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c    | 1 +
 drivers/net/ethernet/rocker/rocker_main.c                  | 1 +
 drivers/net/ethernet/rocker/rocker_ofdpa.c                 | 1 +
 drivers/net/ethernet/ti/am65-cpsw-switchdev.c              | 1 +
 drivers/net/ethernet/ti/cpsw_switchdev.c                   | 1 +
 drivers/s390/net/qeth_l2_main.c                            | 2 ++
 net/dsa/slave.c                                            | 1 +
 11 files changed, 14 insertions(+)

diff --git a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
index 0b3e8f2db294..cf60e80dd3ba 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
@@ -750,6 +750,7 @@ prestera_fdb_offload_notify(struct prestera_port *port,
 {
 	struct switchdev_notifier_fdb_info send_info;
 
+	memset(&send_info, 0, sizeof(send_info));
 	send_info.addr = info->addr;
 	send_info.vid = info->vid;
 	send_info.offloaded = true;
@@ -1146,6 +1147,7 @@ static void prestera_fdb_event(struct prestera_switch *sw,
 	if (!dev)
 		return;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = evt->fdb_evt.data.mac;
 	info.vid = evt->fdb_evt.vid;
 	info.offloaded = true;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
index a6e1d4f78268..77e09397a062 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
@@ -71,6 +71,7 @@ mlx5_esw_bridge_fdb_offload_notify(struct net_device *dev, const unsigned char *
 {
 	struct switchdev_notifier_fdb_info send_info;
 
+	memset(&send_info, 0, sizeof(send_info));
 	send_info.addr = addr;
 	send_info.vid = vid;
 	send_info.offloaded = true;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 7e221ef01437..8a7660f2d048 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -9086,6 +9086,7 @@ static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
 	if (!dev)
 		return;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = mac;
 	info.vid = 0;
 	call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info,
@@ -9137,6 +9138,7 @@ static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
 	if (!dev)
 		return;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = mac;
 	info.vid = vid;
 	call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index c5ef9aa64efe..f016d909bead 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -2510,6 +2510,7 @@ mlxsw_sp_fdb_call_notifiers(enum switchdev_notifier_type type,
 {
 	struct switchdev_notifier_fdb_info info;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = mac;
 	info.vid = vid;
 	info.offloaded = offloaded;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
index 0443f66b5550..fbc3f5e65882 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
@@ -279,6 +279,7 @@ static void sparx5_fdb_call_notifiers(enum switchdev_notifier_type type,
 {
 	struct switchdev_notifier_fdb_info info;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = mac;
 	info.vid = vid;
 	info.offloaded = offloaded;
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index a46633606cae..49d548be9fe4 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2717,6 +2717,7 @@ rocker_fdb_offload_notify(struct rocker_port *rocker_port,
 {
 	struct switchdev_notifier_fdb_info info;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = recv_info->addr;
 	info.vid = recv_info->vid;
 	info.offloaded = true;
diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c
index 967a634ee9ac..7d954fd24134 100644
--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
+++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
@@ -1824,6 +1824,7 @@ static void ofdpa_port_fdb_learn_work(struct work_struct *work)
 	bool learned = (lw->flags & OFDPA_OP_FLAG_LEARNED);
 	struct switchdev_notifier_fdb_info info;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = lw->addr;
 	info.vid = lw->vid;
 
diff --git a/drivers/net/ethernet/ti/am65-cpsw-switchdev.c b/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
index 9c29b363e9ae..81d2b1765a66 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
@@ -360,6 +360,7 @@ static void am65_cpsw_fdb_offload_notify(struct net_device *ndev,
 {
 	struct switchdev_notifier_fdb_info info;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = rcv->addr;
 	info.vid = rcv->vid;
 	info.offloaded = true;
diff --git a/drivers/net/ethernet/ti/cpsw_switchdev.c b/drivers/net/ethernet/ti/cpsw_switchdev.c
index f7fb6e17dadd..446bdab06bdd 100644
--- a/drivers/net/ethernet/ti/cpsw_switchdev.c
+++ b/drivers/net/ethernet/ti/cpsw_switchdev.c
@@ -370,6 +370,7 @@ static void cpsw_fdb_offload_notify(struct net_device *ndev,
 {
 	struct switchdev_notifier_fdb_info info;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = rcv->addr;
 	info.vid = rcv->vid;
 	info.offloaded = true;
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 2abf86c104d5..843dd4f4d8d7 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -283,6 +283,7 @@ static void qeth_l2_dev2br_fdb_flush(struct qeth_card *card)
 
 	QETH_CARD_TEXT(card, 2, "fdbflush");
 
+	memset(&info, 0, sizeof(info));
 	info.addr = NULL;
 	/* flush all VLANs: */
 	info.vid = 0;
@@ -693,6 +694,7 @@ static void qeth_l2_dev2br_fdb_notify(struct qeth_card *card, u8 code,
 	if (qeth_is_my_net_if_token(card, token))
 		return;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = ntfy_mac;
 	/* don't report VLAN IDs */
 	info.vid = 0;
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 532085da8d8f..1cb7f7e56784 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2298,6 +2298,7 @@ dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work)
 	if (!dsa_is_user_port(ds, switchdev_work->port))
 		return;
 
+	memset(&info, 0, sizeof(info));
 	info.addr = switchdev_work->addr;
 	info.vid = switchdev_work->vid;
 	info.offloaded = true;
-- 
2.25.1



From tzungbi at google.com  Mon Aug  9 06:19:40 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Mon,  9 Aug 2021 21:19:40 +0800
Subject: [PATCH] media: mtk-vcodec: fix warnings: symbol XXX was not declared
Message-ID: <20210809131940.2890108-1-tzungbi@google.com>

Fixes sparse warnings:
- warning: symbol 'mtk_vdec_8173_pdata' was not declared. Should it be
static?
- warning: symbol 'mtk_vdec_8183_pdata' was not declared. Should it be
static?

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
---
The patch applies after series [1] to fix the follow up sparse warnings.

[1]: https://patchwork.linuxtv.org/project/linux-media/cover/20210806041530.4170869-1-tzungbi at google.com/

 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h     | 2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 3 ---
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 9fbd24186c1a..46783516b84a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -65,6 +65,8 @@ struct mtk_video_dec_buf {
 extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops;
 extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
 extern const struct media_device_ops mtk_vcodec_media_ops;
+extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata;
+extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata;
 
 
 /*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 36ae3e6017f0..e6e6a8203eeb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -372,9 +372,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	return ret;
 }
 
-extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata;
-extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata;
-
 static const struct of_device_id mtk_vcodec_match[] = {
 	{
 		.compatible = "mediatek,mt8173-vcodec-dec",
-- 
2.32.0.605.g8dce9f2422-goog



From tzungbi at google.com  Mon Aug  9 06:22:49 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Mon, 9 Aug 2021 21:22:49 +0800
Subject: [PATCH v7 00/14] media: mtk-vcodec: support for MT8183 decoder
In-Reply-To: <104309d4-0973-cf1f-d61f-731b0642c1cf@xs4all.nl>
References: <20210806041530.4170869-1-tzungbi@google.com>
 <104309d4-0973-cf1f-d61f-731b0642c1cf@xs4all.nl>
Message-ID: <CA+Px+wU16dp+g7-kmkT8VcJJ3x8hZv8DxuZiXgt2zzkUMSm_dw@mail.gmail.com>

On Mon, Aug 9, 2021 at 8:31 PM Hans Verkuil <hverkuil-cisco at xs4all.nl> wrote:
> I made a PR for this series, but I would like a follow-up patch that fixes this
> sparse warning:
>
> SPARSE:mtk-vcodec/mtk_vcodec_dec_stateful.c:615:35: warning: symbol 'mtk_vdec_8173_pdata' was not declared. Should it be static?
> SPARSE:mtk-vcodec/mtk_vcodec_dec_stateless.c:346:35: warning: symbol 'mtk_vdec_8183_pdata' was not declared. Should it be static?
>
> mtk_vcodec_dec.h is probably a good header to put the extern declaration.
The follow up fix:
https://patchwork.linuxtv.org/project/linux-media/list/?series=6066


From olteanv at gmail.com  Mon Aug  9 06:27:51 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Mon, 9 Aug 2021 16:27:51 +0300
Subject: info@cestasdeplastico.com spam
Message-ID: <20210809132751.kwmgd2movxgoc4v6@skbuf>

Every time I send an email to a few mailing lists, like
linux-kernel at vger.kernel.org, and (I believe)
linux-arm-kernel at lists.infradead.org, I get an auto-reply from said
email address which says:

	Hemos recibido correctamente su consulta, en breve le contestaremos. Gracias.

It is really annoying. Can we make it stop?


From chunkuang.hu at kernel.org  Mon Aug  9 06:28:14 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Mon, 9 Aug 2021 21:28:14 +0800
Subject: [PATCH] drm/mediatek: Implement mmap as GEM object function
In-Reply-To: <20210624090126.8167-1-tzimmermann@suse.de>
References: <20210624090126.8167-1-tzimmermann@suse.de>
Message-ID: <CAAOTY_-GekVvWFQVt693_7KLkFWprzybcD1=JzQZU--2mSL6oA@mail.gmail.com>

Hi, Thomas:

Thomas Zimmermann <tzimmermann at suse.de> ? 2021?6?24? ?? ??5:01???
>
> Moving the driver-specific mmap code into a GEM object function allows
> for using DRM helpers for various mmap callbacks.
>
> The respective mediatek functions are being removed. The file_operations
> structure fops is now being created by the helper macro
> DEFINE_DRM_GEM_FOPS().

Applied to mediatek-drm-next [1], thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next

Regards,
Chun-Kuang.

>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c | 13 ++------
>  drivers/gpu/drm/mediatek/mtk_drm_gem.c | 44 +++++++-------------------
>  drivers/gpu/drm/mediatek/mtk_drm_gem.h |  3 --
>  3 files changed, 14 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index b46bdb8985da..bbfefb29c211 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -300,16 +300,7 @@ static void mtk_drm_kms_deinit(struct drm_device *drm)
>         component_unbind_all(drm->dev, drm);
>  }
>
> -static const struct file_operations mtk_drm_fops = {
> -       .owner = THIS_MODULE,
> -       .open = drm_open,
> -       .release = drm_release,
> -       .unlocked_ioctl = drm_ioctl,
> -       .mmap = mtk_drm_gem_mmap,
> -       .poll = drm_poll,
> -       .read = drm_read,
> -       .compat_ioctl = drm_compat_ioctl,
> -};
> +DEFINE_DRM_GEM_FOPS(mtk_drm_fops);
>
>  /*
>   * We need to override this because the device used to import the memory is
> @@ -332,7 +323,7 @@ static const struct drm_driver mtk_drm_driver = {
>         .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
>         .gem_prime_import = mtk_drm_gem_prime_import,
>         .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
> -       .gem_prime_mmap = mtk_drm_gem_mmap_buf,
> +       .gem_prime_mmap = drm_gem_prime_mmap,
>         .fops = &mtk_drm_fops,
>
>         .name = DRIVER_NAME,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> index 280ea0d5e840..d0544962cfc1 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
> @@ -14,11 +14,14 @@
>  #include "mtk_drm_drv.h"
>  #include "mtk_drm_gem.h"
>
> +static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
> +
>  static const struct drm_gem_object_funcs mtk_drm_gem_object_funcs = {
>         .free = mtk_drm_gem_free_object,
>         .get_sg_table = mtk_gem_prime_get_sg_table,
>         .vmap = mtk_drm_gem_prime_vmap,
>         .vunmap = mtk_drm_gem_prime_vunmap,
> +       .mmap = mtk_drm_gem_object_mmap,
>         .vm_ops = &drm_gem_cma_vm_ops,
>  };
>
> @@ -145,11 +148,19 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
>         struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj);
>         struct mtk_drm_private *priv = obj->dev->dev_private;
>
> +       /*
> +        * Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the
> +        * whole buffer from the start.
> +        */
> +       vma->vm_pgoff = 0;
> +
>         /*
>          * dma_alloc_attrs() allocated a struct page table for mtk_gem, so clear
>          * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap().
>          */
> -       vma->vm_flags &= ~VM_PFNMAP;
> +       vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
> +       vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
> +       vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
>
>         ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie,
>                              mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs);
> @@ -159,37 +170,6 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
>         return ret;
>  }
>
> -int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj, struct vm_area_struct *vma)
> -{
> -       int ret;
> -
> -       ret = drm_gem_mmap_obj(obj, obj->size, vma);
> -       if (ret)
> -               return ret;
> -
> -       return mtk_drm_gem_object_mmap(obj, vma);
> -}
> -
> -int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
> -{
> -       struct drm_gem_object *obj;
> -       int ret;
> -
> -       ret = drm_gem_mmap(filp, vma);
> -       if (ret)
> -               return ret;
> -
> -       obj = vma->vm_private_data;
> -
> -       /*
> -        * Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the
> -        * whole buffer from the start.
> -        */
> -       vma->vm_pgoff = 0;
> -
> -       return mtk_drm_gem_object_mmap(obj, vma);
> -}
> -
>  /*
>   * Allocate a sg_table for this GEM object.
>   * Note: Both the table's contents, and the sg_table itself must be freed by
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
> index 6da5ccb4b933..9a359a06cb73 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h
> @@ -39,9 +39,6 @@ struct mtk_drm_gem_obj *mtk_drm_gem_create(struct drm_device *dev, size_t size,
>                                            bool alloc_kmap);
>  int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
>                             struct drm_mode_create_dumb *args);
> -int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
> -int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj,
> -                        struct vm_area_struct *vma);
>  struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj);
>  struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev,
>                         struct dma_buf_attachment *attach, struct sg_table *sg);
> --
> 2.32.0
>


From wangkefeng.wang at huawei.com  Mon Aug  9 06:34:57 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 9 Aug 2021 21:34:57 +0800
Subject: [PATCH v3 3/3] kasan: arm64: Fix pcpu_page_first_chunk crash with
 KASAN_VMALLOC
In-Reply-To: <CANpmjNOM-fzk2_q9LNLgM1wSReHWj42MxHBeDBLg8Ga5vv8HhQ@mail.gmail.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <20210809093750.131091-4-wangkefeng.wang@huawei.com>
 <ae15c02e-d825-dbef-1419-5b5220f826c1@huawei.com>
 <CANpmjNOM-fzk2_q9LNLgM1wSReHWj42MxHBeDBLg8Ga5vv8HhQ@mail.gmail.com>
Message-ID: <03828e22-9869-7c57-3ad0-f266a435e427@huawei.com>


On 2021/8/9 19:21, Marco Elver wrote:
> On Mon, 9 Aug 2021 at 13:10, Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>
>> On 2021/8/9 17:37, Kefeng Wang wrote:
>>> With KASAN_VMALLOC and NEED_PER_CPU_PAGE_FIRST_CHUNK, it crashs,
>>>
>>> Unable to handle kernel paging request at virtual address ffff7000028f2000
>>> ...
>>> swapper pgtable: 64k pages, 48-bit VAs, pgdp=0000000042440000
>>> [ffff7000028f2000] pgd=000000063e7c0003, p4d=000000063e7c0003, pud=000000063e7c0003, pmd=000000063e7b0003, pte=0000000000000000
>>> Internal error: Oops: 96000007 [#1] PREEMPT SMP
>>> Modules linked in:
>>> CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.0-rc4-00003-gc6e6e28f3f30-dirty #62
>>> Hardware name: linux,dummy-virt (DT)
>>> pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO BTYPE=--)
>>> pc : kasan_check_range+0x90/0x1a0
>>> lr : memcpy+0x88/0xf4
>>> sp : ffff80001378fe20
>>> ...
>>> Call trace:
>>>    kasan_check_range+0x90/0x1a0
>>>    pcpu_page_first_chunk+0x3f0/0x568
>>>    setup_per_cpu_areas+0xb8/0x184
>>>    start_kernel+0x8c/0x328
>>>
>>> The vm area used in vm_area_register_early() has no kasan shadow memory,
>>> Let's add a new kasan_populate_early_vm_area_shadow() function to populate
>>> the vm area shadow memory to fix the issue.
>> Should add Acked-by: Marco Elver <elver at google.com> [for KASAN parts] ,
> My Ack is still valid, thanks for noting.
Thanks,? Marco ;)


From andrew at lunn.ch  Mon Aug  9 06:35:09 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 9 Aug 2021 15:35:09 +0200
Subject: [PATCH net-next 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
 <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
Message-ID: <YREvDRkiuScyN8Ws@lunn.ch>

On Mon, Aug 09, 2021 at 06:22:28PM +0800, Wong Vee Khee wrote:
> From: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>
> 
> Unlike any other platforms, Intel AlderLake-S uses Synopsys SerDes where
> all the SerDes PLL configurations are controlled by the xPCS at the BIOS
> level. If the driver perform a xPCS soft reset on initialization, these
> settings will be switched back to the power on reset values.
> 
> This changes the xpcs_create function to take in an additional argument
> to check if the platform request to skip xPCS soft reset during device
> initialization.

Why not just call into the BIOS and ask it to configure the SERDES?
Isn't that what ACPI is all about, hiding the details from the OS? Or
did the BIOS writers not add a control method to do this?

    Andrew


From robin.murphy at arm.com  Mon Aug  9 06:40:07 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 9 Aug 2021 14:40:07 +0100
Subject: [PATCH v3 25/25] iommu: Allow enabling non-strict mode dynamically
In-Reply-To: <20210809124931.GA1097@willie-the-truck>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <22b044263f69e2bfe404c4379a435005ea58b3e2.1628094601.git.robin.murphy@arm.com>
 <20210809124931.GA1097@willie-the-truck>
Message-ID: <283ba58e-0257-8785-d0e6-eb96ab169e35@arm.com>

On 2021-08-09 13:49, Will Deacon wrote:
> On Wed, Aug 04, 2021 at 06:15:53PM +0100, Robin Murphy wrote:
>> Allocating and enabling a flush queue is in fact something we can
>> reasonably do while a DMA domain is active, without having to rebuild it
>> from scratch. Thus we can allow a strict -> non-strict transition from
>> sysfs without requiring to unbind the device's driver, which is of
>> particular interest to users who want to make selective relaxations to
>> critical devices like the one serving their root filesystem.
>>
>> Disabling and draining a queue also seems technically possible to
>> achieve without rebuilding the whole domain, but would certainly be more
>> involved. Furthermore there's not such a clear use-case for tightening
>> up security *after* the device may already have done whatever it is that
>> you don't trust it not to do, so we only consider the relaxation case.
>>
>> CC: Sai Praneeth Prakhya <sai.praneeth.prakhya at intel.com>
>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
>>
>> ---
>>
>> v3: Actually think about concurrency, rework most of the fq data
>>      accesses to be (hopefully) safe and comment it all
>> ---
>>   drivers/iommu/dma-iommu.c | 25 ++++++++++++++++++-------
>>   drivers/iommu/iommu.c     | 16 ++++++++++++----
>>   drivers/iommu/iova.c      |  9 ++++++---
>>   3 files changed, 36 insertions(+), 14 deletions(-)
> 
> I failed to break this, so hopefully you've caught everything now.
> 
> Only thing I wasn't sure of is why we still need the smp_wmb() in
> init_iova_flush_queue(). Can we remove it now that we have one before
> assigning into the cookie?

Mostly because I failed to spot it, I think :)

Indeed now that we don't have any callers other than iommu_dma_init_fq() 
to worry about, I don't think that one matters any more. It would if 
were testing cookie->iovad->fq directly as our indicator instead of 
cookie->fq_domain, but then we'd still need the new barrier to ensure 
iommu_dma_flush_iotlb_all() properly observes the latter, so we may as 
well rely on that everywhere and let it fully replace the old one.

Thanks,
Robin.


From nicolas.ferre at microchip.com  Mon Aug  9 06:41:32 2021
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Mon, 9 Aug 2021 15:41:32 +0200
Subject: [GIT PULL] ARM: at91: defconfig for 5.15
In-Reply-To: <CAK8P3a1Ru-qawBWtbmfJm-jiPpJTRJ9zSufXHNCZvxt1RCMFBA@mail.gmail.com>
References: <20210804084631.12934-1-nicolas.ferre@microchip.com>
 <CAK8P3a1Ru-qawBWtbmfJm-jiPpJTRJ9zSufXHNCZvxt1RCMFBA@mail.gmail.com>
Message-ID: <5f5e8843-1a07-760a-db1a-aee084f00405@microchip.com>

On 04/08/2021 at 16:02, Arnd Bergmann wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Wed, Aug 4, 2021 at 10:46 AM <nicolas.ferre at microchip.com> wrote:
>> AT91 defconfig for 5.15:
>>
>> - add defconfig entries for new SoC: SAMA7G5
>>    - dedicated sama7_defconfig to match the needed peripherals and
>>      dependencies
> 
> I feel this needs  better description in the changelog: Why do you need another
> defconfig file in addition to the existing sama5_defconfig? Are they so
> different that a single config is not a good fit for both?

Hi Arnd,

I'm pushing another tag for this with better description. I hope it's 
convincing ;-)

Best regards,
   Nicolas

-- 
Nicolas Ferre


From nicolas.ferre at microchip.com  Mon Aug  9 06:45:21 2021
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Mon, 9 Aug 2021 15:45:21 +0200
Subject: [GIT PULL v2] ARM: at91: defconfig for 5.15
In-Reply-To: <CAK8P3a1Ru-qawBWtbmfJm-jiPpJTRJ9zSufXHNCZvxt1RCMFBA@mail.gmail.com>
References: <CAK8P3a1Ru-qawBWtbmfJm-jiPpJTRJ9zSufXHNCZvxt1RCMFBA@mail.gmail.com>
Message-ID: <20210809134521.10155-1-nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

Arnd, Olof,

Here is the second attept about defconfig changes for 5.15 which contains
addition for SAMA7G5.

v1 --> v2:
- add more information to the tag message for explaining why we prefer
  a new sama7_defconfig file.

Thanks, best regards,
  Nicolas

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git tags/at91-defconfig-5.15

for you to fetch changes up to b62869dcd4bcf341d3750a2bcad9a80c6d5562a8:

  ARM: multi_v7_defconfig: add sama7g5 SoC (2021-07-19 15:25:42 +0200)

----------------------------------------------------------------
AT91 defconfig for 5.15:

- add defconfig entries for new SoC: SAMA7G5
  - dedicated sama7_defconfig which avoids having to carry older drivers
    and dependencies from the sama5 family:
    CACHE_L2X0, CAN_AT91, TOUCHSCREEN_ADC, AT91SAM9X_WATCHDOG,
    VIDEO_ATMEL_ISI, SND_ATMEL_SOC_I2S, MMC_ATMELMCI, AT_HDMAC, AT91_ADC,
    REGULATOR_ACT*
    Addition of new drivers that are not part of any sama5 SoC:
    SND_MCHP_SOC_I2S_MCC, SND_MCHP_SOC_SPDIFTX|RX, MICROCHIP_PIT64B
    plus upcoming MIPI pipeline, audio sample rate converter, ...
    It also maintains both sama5 and sama7 defconfig tailored for their
    respective families and easy to identify.
  - addition to the generic multi_v7_defconfig

----------------------------------------------------------------
Eugen Hristev (2):
      ARM: configs: at91: add defconfig for sama7 family of SoCs
      ARM: multi_v7_defconfig: add sama7g5 SoC

 arch/arm/configs/multi_v7_defconfig |   2 +
 arch/arm/configs/sama7_defconfig    | 209 +++++++++++++++++++++++++++++++++++
 2 files changed, 211 insertions(+)
 create mode 100644 arch/arm/configs/sama7_defconfig

-- 
Nicolas Ferre


From nm at ti.com  Mon Aug  9 06:47:28 2021
From: nm at ti.com (Nishanth Menon)
Date: Mon, 9 Aug 2021 08:47:28 -0500
Subject: [PATCH v3] ARM: Fix Keystone 2 kernel mapping regression
In-Reply-To: <20210809115233.1009708-1-linus.walleij@linaro.org>
References: <20210809115233.1009708-1-linus.walleij@linaro.org>
Message-ID: <20210809134728.3fy3gczobmdxvxtb@reword>

On 13:52-20210809, Linus Walleij wrote:
> This fixes a Keystone 2 regression discovered as a side effect of
> defining an passing the physical start/end sections of the kernel
> to the MMU remapping code.
> 
> As the Keystone applies an offset to all physical addresses,
> including those identified and patches by phys2virt, we fail to
> account for this offset in the kernel_sec_start and kernel_sec_end
> variables.
> 
> Further these offsets can extend into the 64bit range on LPAE
> systems such as the Keystone 2.
> 
> Fix it like this:
> - Extend kernel_sec_start and kernel_sec_end to be 64bit
> - Add the offset also to kernel_sec_start and kernel_sec_end
> 
> As passing kernel_sec_start and kernel_sec_end as 64bit invariably
> incurs BE8 endianness issues I have attempted to dry-code around
> these.
> 
> Tested on the Vexpress QEMU model both with and without LPAE
> enabled.
> 
> Fixes: 6e121df14ccd ("ARM: 9090/1: Map the lowmem and kernel separately")
> Reported-by: Nishanth Menon <nmenon at kernel.org>
> Suggested-by: Russell King <linux at armlinux.org.uk>
> Tested-by: Grygorii Strashko <grygorii.strashko at ti.com>
> Tested-by: Nishanth Menon <nmenon at kernel.org>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> Signed-off-by: Nishanth Menon <nm at ti.com>
> Link: https://lore.kernel.org/r/20210809115233.1009708-1-linus.walleij at linaro.org
> ---

V3 looks good as well. Thanks.

Test log for v3:
https://pastebin.ubuntu.com/p/RfhFwJf349/ (k2g-evm)
https://pastebin.ubuntu.com/p/QmXsDPwyh9/ (k2hk evm)

Tag used: next-20210809


-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From shameerali.kolothum.thodi at huawei.com  Mon Aug  9 06:48:37 2021
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Mon, 9 Aug 2021 13:48:37 +0000
Subject: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU schedule out
In-Reply-To: <20210809130917.GA1207@willie-the-truck>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
 <20210803114034.GB30853@willie-the-truck>
 <ee2863107d614ef8a36006b5aa912eca@huawei.com>
 <20210803153036.GA31125@willie-the-truck>
 <b2146ea5db47485f8410a4c1ab0c15fe@huawei.com>
 <20210809130917.GA1207@willie-the-truck>
Message-ID: <85b1c1a7861a4cb2a92fc87af800bf4c@huawei.com>



> -----Original Message-----
> From: Will Deacon [mailto:will at kernel.org]
> Sent: 09 August 2021 14:09
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org; maz at kernel.org; catalin.marinas at arm.com;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Linuxarm
> <linuxarm at huawei.com>
> Subject: Re: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU
> schedule out
> 
> On Fri, Aug 06, 2021 at 12:24:36PM +0000, Shameerali Kolothum Thodi
> wrote:
> > These are some test numbers with and without this patch, run on two
> > different test setups.
> >
> >
> > a)Test Setup -1
> > -----------------------
> >
> > Platform: HiSilicon D06 with 128 CPUs, VMID bits = 16
> > Run 128 VMs concurrently each with 2 vCPUs. Each Guest will execute
> hackbench
> > 5 times before exiting.
> >
> > Measurements taken avg. of 10 Runs.
> >
> > Image : 5.14-rc3
> > ---------------------------
> >   Time(s)       44.43813888
> >   No. of exits    145,348,264
> >
> > Image: 5.14-rc3 + vmid-v3
> > ----------------------------------------
> >   Time(s)        46.59789034
> >   No. of exits     133,587,307
> >
> > %diff against 5.14-rc3
> >   Time: 4.8% more
> >   Exits: 8% less
> >
> > Image: 5.14-rc3 + vmid-v3 + Without active_asid clear
> > ---------------------------------------------------------------------------
> >   Time(s)         44.5031782
> >   No. of exits      144,443,188
> >
> > %diff against 5.14-rc3
> >   Time: 0.15% more
> >   Exits: 2.42% less
> >
> > b)Test Setup -2
> > -----------------------
> >
> > Platform: HiSilicon D06 + Kernel with maxcpus set to 8 and VMID bits set to
> 4.
> > Run 40 VMs concurrently each with 2 vCPUs. Each Guest will execute
> hackbench
> > 5 times before exiting.
> >
> > Measurements taken avg. of 10 Runs.
> >
> > Image : 5.14-rc3-vmid4bit
> > ------------------------------------
> >   Time(s)        46.19963266
> >   No. of exits     23,699,546
> >
> > Image: 5.14-rc3-vmid4bit + vmid-v3
> > ---------------------------------------------------
> >   Time(s)          45.83307736
> >   No. of exits      23,260,203
> >
> > %diff against 5.14-rc3-vmid4bit
> >   Time: 0.8% less
> >   Exits: 1.85% less
> >
> > Image: 5.14-rc3-vmid4bit + vmid-v3 + Without active_asid clear
> > -----------------------------------------------------------------------------------------
> >   Time(s)           44.5031782
> >   No. of exits        144,443,188
> 
> Really? The *exact* same numbers as the "Image: 5.14-rc3 + vmid-v3 +
> Without
> active_asid clear" configuration? Guessing a copy-paste error here.
> 
> > %diff against 5.14-rc3-vmid4bit
> >   Time: 1.05% less
> >   Exits: 2.06% less
> >
> > As expected, the active_asid clear on schedule out is not helping.
> > But without this patch, the numbers seems to be better than the
> > vanilla kernel when we force the setup(cpus=8, vmd=4bits)
> > to perform rollover.
> 
> I'm struggling a bit to understand these numbers. Are you saying that
> clearing the active_asid helps in the 16-bit VMID case but not in the
> 4-bit case?

Nope, the other way around.. The point I was trying to make is that
clearing the active_vmids definitely have an impact in 16-bit vmid
case, where rollover is not happening, as it ends up taking the slow
path more frequently.

Test setup-1, case 2(with active_vmids clear): Around 4.8% more time
to finish the test compared to vanilla kernel.

Test setup-1, case 3(Without clear): 0.15% more time compared to
vanilla kernel.

For the 4-bit vmid case, the impact of clearing vmids is not that obvious
probably because we have more rollovers.

Test setup-2, case 2(with active_vmids clear):0.8% less time compared to vanilla.
Test setup-2, case 3(Without clear): 1.05% less time compared to vanilla kernel.
 
So between the two(with and without clearing the active_vmids), the "without" 
one has better numbers for both Test setups.

> Why would the active_asid clear have any impact on the number of exits?

In 16 bit vmid case, it looks like the no. of exits is considerably lower if we clear
active_vmids. . Not sure it is because of the frequent slow path or not. But anyway,
the time to finish the test is higher.
 
> The problem I see with not having the active_asid clear is that we will
> roll over more frequently as the number of reserved VMIDs increases.

Ok. The idea of running the 4-bit test setup was to capture that. It doesn't
look like it has a major impact when compared to the original kernel. May be
I should take an average of more test runs. Please let me know if there is a 
better way to measure that impact.

Hope, I am clear.

Thanks,
Shameer


From will at kernel.org  Mon Aug  9 06:50:41 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 14:50:41 +0100
Subject: [EXT] Re: The problem about arm64: io: Relax implicit barriers
 in default I/O accessors
In-Reply-To: <AS8PR04MB850048A35E12270B42448B4C88E49@AS8PR04MB8500.eurprd04.prod.outlook.com>
References: <20210621162641.GA29595@willie-the-truck>
 <20210621165941.GB29595@willie-the-truck>
 <AS8PR04MB85000A5E88F7CDDAB9105821880A9@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210621181326.GD29713@willie-the-truck>
 <AS8PR04MB85006677E34CD6CC2C132FA2880A9@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210622091140.GA30677@willie-the-truck>
 <AS8PR04MB85002F0B0C99E7B4F1D27D3D88089@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210706171106.GE20750@willie-the-truck>
 <AS8PR04MB8500635E829B332A61AC85C988129@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <AS8PR04MB850048A35E12270B42448B4C88E49@AS8PR04MB8500.eurprd04.prod.outlook.com>
Message-ID: <20210809135041.GC1207@willie-the-truck>

On Thu, Jul 22, 2021 at 07:14:19PM +0000, Frank Li wrote:
> > > On Wed, Jun 23, 2021 at 03:48:10PM +0000, Frank Li wrote:
> > > > > I think you had a support case open with Arm [1] which I'm not able
> > to
> > > > > access -- please can you ask them about the two examples above?
> > > >
> > > > Still not get feedback from ARM.
> > >
> > > Just wondering if you were able to solve this without the need to change
> > > Linux?
> > 
> > Sorry for late reply
> > 
> > For CCI-500 and 550, ARM removed support for barrier transactions but CCI-
> > 400 supports barrier transactions. With CCI-400 it is a valid configuration
> > to have SYSBARDISABLE LOW in Cortex-A processors. This change in Linux
> > kernel is assuming that the SYSBARDISABLE is set to HIGH hence its not
> > correct change for all products having various versions of ARM CCI IP.
> > 
> > Frank Li
> 
> Deacon:
> 
>       Did you plan fix this problem by changing dma_wmb()?

No. As far as I understand this problem, you're driving SYSBARDISABLE
'low' yet you have your own bus fabric downstream of the CCI which doesn't
respect barrier transactions. Even if we bodge dma_wmb(), store-release to
non-cacheable memory cannot be made to work on your system as you're
effectively putting some of your non-coherent DMA devices into a separate
outer-shareable domain from the CPUs.

So you have two options:

  1. Drive SYSBARDISABLE 'high' so that the CPU handles ordering for you

- or -

  2. Quirk Linux so that we patch dma_wmb() when we detect your system at
     runtime (so we can extend this in future if we need to emit a different
     sequence for store release)

(1) is definitely the easiest option if it's possible.

Will


From krzysztof.kozlowski at canonical.com  Mon Aug  9 06:59:39 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 15:59:39 +0200
Subject: [PATCH 0/3] dt-bindings: clock: samsung: convert AudSS to dtschema
Message-ID: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>

Hi,

Rebased on on previous series:
https://lore.kernel.org/linux-samsung-soc/20210809120544.56596-1-krzysztof.kozlowski at canonical.com/T/#t
It affects only the maintainers file change (context-dependency).

Best regards,
Krzysztof


Krzysztof Kozlowski (3):
  dt-bindings: clock: samsung: convert Exynos AudSS to dtschema
  dt-bindings: clock: samsung: convert S5Pv210 AudSS to dtschema
  MAINTAINERS: clock: include S3C and S5P in Samsung SoC clock entry

 .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
 .../bindings/clock/clk-s5pv210-audss.txt      |  53 ---------
 .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
 .../clock/samsung,s5pv210-audss-clock.yaml    |  75 +++++++++++++
 MAINTAINERS                                   |   3 +
 5 files changed, 157 insertions(+), 156 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml

-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Aug  9 06:59:40 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 15:59:40 +0200
Subject: [PATCH 1/3] dt-bindings: clock: samsung: convert Exynos AudSS to
 dtschema
In-Reply-To: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>
References: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210809135942.100744-2-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
 .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
 2 files changed, 79 insertions(+), 103 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
deleted file mode 100644
index 6030afb10b5c..000000000000
--- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-* Samsung Audio Subsystem Clock Controller
-
-The Samsung Audio Subsystem clock controller generates and supplies clocks
-to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
-binding described here is applicable to all SoCs in Exynos family.
-
-Required Properties:
-
-- compatible: should be one of the following:
-  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
-  - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
-    SoCs.
-  - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
-    SoCs.
-  - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
-    SoCs.
-- reg: physical base address and length of the controller's register set.
-
-- #clock-cells: should be 1.
-
-- clocks:
-  - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
-    is used if not specified.
-  - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
-    is used if not specified.
-  - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
-    specified.
-  - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
-    not specified.
-  - sclk_pcm_in: PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not
-    specified.
-
-- clock-names: Aliases for the above clocks. They should be "pll_ref",
-  "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
-
-Optional Properties:
-
-  - power-domains: a phandle to respective power domain node as described by
-    generic PM domain bindings (see power/power_domain.txt for more
-    information).
-
-The following is the list of clocks generated by the controller. Each clock is
-assigned an identifier and client nodes use this identifier to specify the
-clock which they consume. Some of the clocks are available only on a particular
-Exynos4 SoC and this is specified where applicable.
-
-Provided clocks:
-
-Clock           ID      SoC (if specific)
------------------------------------------------
-
-mout_audss      0
-mout_i2s        1
-dout_srp        2
-dout_aud_bus    3
-dout_i2s        4
-srp_clk         5
-i2s_bus         6
-sclk_i2s        7
-pcm_bus         8
-sclk_pcm        9
-adma            10      Exynos5420
-
-Example 1: An example of a clock controller node using the default input
-	   clock names is listed below.
-
-clock_audss: audss-clock-controller at 3810000 {
-	compatible = "samsung,exynos5250-audss-clock";
-	reg = <0x03810000 0x0C>;
-	#clock-cells = <1>;
-};
-
-Example 2: An example of a clock controller node with the input clocks
-           specified.
-
-clock_audss: audss-clock-controller at 3810000 {
-	compatible = "samsung,exynos5250-audss-clock";
-	reg = <0x03810000 0x0C>;
-	#clock-cells = <1>;
-	clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
-		<&ext_i2s_clk>;
-	clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
-};
-
-Example 3: I2S controller node that consumes the clock generated by the clock
-           controller. Refer to the standard clock bindings for information
-           about 'clocks' and 'clock-names' property.
-
-i2s0: i2s at 3830000 {
-	compatible = "samsung,i2s-v5";
-	reg = <0x03830000 0x100>;
-	dmas = <&pdma0 10
-		&pdma0 9
-		&pdma0 8>;
-	dma-names = "tx", "rx", "tx-sec";
-	clocks = <&clock_audss EXYNOS_I2S_BUS>,
-		<&clock_audss EXYNOS_I2S_BUS>,
-		<&clock_audss EXYNOS_SCLK_I2S>,
-		<&clock_audss EXYNOS_MOUT_AUDSS>,
-		<&clock_audss EXYNOS_MOUT_I2S>;
-	clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
-		      "mout_audss", "mout_i2s";
-};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
new file mode 100644
index 000000000000..d60b29fa22e7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-audss-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC Audio SubSystem clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/exynos-audss-clk.h header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos4210-audss-clock
+      - samsung,exynos5250-audss-clock
+      - samsung,exynos5410-audss-clock
+      - samsung,exynos5420-audss-clock
+
+  clocks:
+    minItems: 2
+    items:
+      - description:
+          Fixed rate PLL reference clock, parent of mout_audss. "fin_pll" is
+          used if not specified.
+      - description:
+          Input PLL to the AudioSS block, parent of mout_audss. "fout_epll" is
+          used if not specified.
+      - description:
+          Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if not
+          specified.
+      - description:
+          PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not specified.
+      - description:
+          External i2s clock, parent of mout_i2s. "cdclk0" is used if not
+          specified.
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: pll_ref
+      - const: pll_in
+      - const: sclk_audio
+      - const: sclk_pcm_in
+      - const: cdclk
+
+  "#clock-cells":
+    const: 1
+
+  power-domains: true
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 3810000 {
+        compatible = "samsung,exynos5250-audss-clock";
+        reg = <0x03810000 0x0c>;
+        #clock-cells = <1>;
+        clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>, <&ext_i2s_clk>;
+        clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Aug  9 06:59:41 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 15:59:41 +0200
Subject: [PATCH 2/3] dt-bindings: clock: samsung: convert S5Pv210 AudSS to
 dtschema
In-Reply-To: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>
References: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210809135942.100744-3-krzysztof.kozlowski@canonical.com>

Convert Samsung S5Pv210 Audio SubSystem clock controller bindings to DT
schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/clk-s5pv210-audss.txt      | 53 -------------
 .../clock/samsung,s5pv210-audss-clock.yaml    | 75 +++++++++++++++++++
 2 files changed, 75 insertions(+), 53 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt b/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
deleted file mode 100644
index f6272dcd96f4..000000000000
--- a/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-* Samsung Audio Subsystem Clock Controller
-
-The Samsung Audio Subsystem clock controller generates and supplies clocks
-to Audio Subsystem block available in the S5PV210 and compatible SoCs.
-
-Required Properties:
-
-- compatible: should be "samsung,s5pv210-audss-clock".
-- reg: physical base address and length of the controller's register set.
-
-- #clock-cells: should be 1.
-
-- clocks:
-  - hclk: AHB bus clock of the Audio Subsystem.
-  - xxti: Optional fixed rate PLL reference clock, parent of mout_audss. If
-    not specified (i.e. xusbxti is used for PLL reference), it is fixed to
-    a clock named "xxti".
-  - fout_epll: Input PLL to the AudioSS block, parent of mout_audss.
-  - iiscdclk0: Optional external i2s clock, parent of mout_i2s. If not
-    specified, it is fixed to a clock named "iiscdclk0".
-  - sclk_audio0: Audio bus clock, parent of mout_i2s.
-
-- clock-names: Aliases for the above clocks. They should be "hclk",
-  "xxti", "fout_epll", "iiscdclk0", and "sclk_audio0" respectively.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/s5pv210-audss-clk.h header and can be used in device
-tree sources.
-
-Example: Clock controller node.
-
-	clk_audss: clock-controller at c0900000 {
-		compatible = "samsung,s5pv210-audss-clock";
-		reg = <0xc0900000 0x1000>;
-		#clock-cells = <1>;
-		clock-names = "hclk", "xxti",
-				"fout_epll", "sclk_audio0";
-		clocks = <&clocks DOUT_HCLKP>, <&xxti>,
-				<&clocks FOUT_EPLL>, <&clocks SCLK_AUDIO0>;
-	};
-
-Example: I2S controller node that consumes the clock generated by the clock
-	 controller. Refer to the standard clock bindings for information
-         about 'clocks' and 'clock-names' property.
-
-	i2s0: i2s at 3830000 {
-		/* ... */
-		clock-names = "iis", "i2s_opclk0",
-				"i2s_opclk1";
-		clocks = <&clk_audss CLK_I2S>, <&clk_audss CLK_I2S>,
-				<&clk_audss CLK_DOUT_AUD_BUS>;
-		/* ... */
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
new file mode 100644
index 000000000000..e56be98c025e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,s5pv210-audss-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S5Pv210 SoC Audio SubSystem clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/s5pv210-audss.h header.
+
+properties:
+  compatible:
+    const: samsung,s5pv210-audss-clock
+
+  clocks:
+    minItems: 4
+    items:
+      - description:
+          AHB bus clock of the Audio Subsystem.
+      - description:
+          Optional fixed rate PLL reference clock, parent of mout_audss. If not
+          specified (i.e. xusbxti is used for PLL reference), it is fixed to a
+          clock named "xxti".
+      - description:
+          Input PLL to the AudioSS block, parent of mout_audss.
+      - description:
+          Audio bus clock, parent of mout_i2s.
+      - description:
+          Optional external i2s clock, parent of mout_i2s. If not specified, it
+          is fixed to a clock named "iiscdclk0".
+
+  clock-names:
+    minItems: 4
+    items:
+      - const: hclk
+      - const: xxti
+      - const: fout_epll
+      - const: sclk_audio0
+      - const: iiscdclk0
+
+  "#clock-cells":
+    const: 1
+
+  power-domains: true
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at c0900000 {
+        compatible = "samsung,s5pv210-audss-clock";
+        reg = <0xc0900000 0x1000>;
+        #clock-cells = <1>;
+        clock-names = "hclk", "xxti", "fout_epll", "sclk_audio0";
+        clocks = <&clocks DOUT_HCLKP>, <&xxti>, <&clocks FOUT_EPLL>,
+                 <&clocks SCLK_AUDIO0>;
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Aug  9 06:59:42 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon,  9 Aug 2021 15:59:42 +0200
Subject: [PATCH 3/3] MAINTAINERS: clock: include S3C and S5P in Samsung SoC
 clock entry
In-Reply-To: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>
References: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210809135942.100744-4-krzysztof.kozlowski@canonical.com>

Cover the S3C and S5Pv210 clock controller binding headers by Samsung
SoC clock controller drivers maintainer entry.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2dbacacac3f5..7846ce554b07 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16496,6 +16496,9 @@ F:	Documentation/devicetree/bindings/clock/samsung,s3c*
 F:	Documentation/devicetree/bindings/clock/samsung,s5p*
 F:	drivers/clk/samsung/
 F:	include/dt-bindings/clock/exynos*.h
+F:	include/dt-bindings/clock/s3c*.h
+F:	include/dt-bindings/clock/s5p*.h
+F:	include/dt-bindings/clock/samsung,*.h
 F:	include/linux/clk/samsung.h
 F:	include/linux/platform_data/clk-s3c2410.h
 
-- 
2.30.2



From rocco.yue at mediatek.com  Mon Aug  9 07:01:09 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Mon, 9 Aug 2021 22:01:09 +0800
Subject: [PATCH net-next v3] ipv6: add IFLA_INET6_RA_MTU to expose mtu value
 in the RA message
Message-ID: <20210809140109.32595-1-rocco.yue@mediatek.com>

The kernel provides a "/proc/sys/net/ipv6/conf/<iface>/mtu"
file, which can temporarily record the mtu value of the last
received RA message when the RA mtu value is lower than the
interface mtu, but this proc has following limitations:

(1) when the interface mtu (/sys/class/net/<iface>/mtu) is
updeated, mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) will
be updated to the value of interface mtu;
(2) mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) only affect
ipv6 connection, and not affect ipv4.

Therefore, when the mtu option is carried in the RA message,
there will be a problem that the user sometimes cannot obtain
RA mtu value correctly by reading mtu6.

After this patch set, if a RA message carries the mtu option,
you can send a netlink msg which nlmsg_type is RTM_GETLINK,
and then by parsing the attribute of IFLA_INET6_RA_MTU to
get the mtu value carried in the RA message received on the
inet6 device. In addition, you can also get a link notification
when ra_mtu is updated so it doesn't have to poll.

In this way, if the MTU values that the device receives from
the network in the PCO IPv4 and the RA IPv6 procedures are
different, the user space process can read ra_mtu to get
the mtu value carried in the RA message without worrying
about the issue of ipv4 being stuck due to the late arrival
of RA message. After comparing the value of ra_mtu and ipv4
mtu, then the device can use the lower MTU value for both
IPv4 and IPv6.

Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
---
 include/net/if_inet6.h             |  2 +
 include/net/ndisc.h                |  1 +
 include/uapi/linux/if_link.h       |  1 +
 net/ipv6/addrconf.c                | 67 ++++++++++++++++++++++++++++++
 net/ipv6/ndisc.c                   |  6 +++
 tools/include/uapi/linux/if_link.h |  1 +
 6 files changed, 78 insertions(+)

diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 42235c178b06..653e7d0f65cb 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -210,6 +210,8 @@ struct inet6_dev {
 
 	unsigned long		tstamp; /* ipv6InterfaceTable update timestamp */
 	struct rcu_head		rcu;
+
+	unsigned int		ra_mtu;
 };
 
 static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf)
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 38e4094960ce..c7b7f1b002fd 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -501,5 +501,6 @@ int ndisc_ifinfo_sysctl_strategy(struct ctl_table *ctl,
 #endif
 
 void inet6_ifinfo_notify(int event, struct inet6_dev *idev);
+void inet6_iframtu_notify(struct inet6_dev *idev);
 
 #endif
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 5310003523ce..6dfdae1bb860 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -417,6 +417,7 @@ enum {
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
 	IFLA_INET6_TOKEN,	/* device token			*/
 	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	IFLA_INET6_RA_MTU,	/* mtu carried in the RA message  */
 	__IFLA_INET6_MAX
 };
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8381288a0d6e..3e3cdd49c295 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5543,6 +5543,7 @@ static inline size_t inet6_ifla6_size(void)
 	     + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
 	     + nla_total_size(sizeof(struct in6_addr)) /* IFLA_INET6_TOKEN */
 	     + nla_total_size(1) /* IFLA_INET6_ADDR_GEN_MODE */
+	     + nla_total_size(4) /* IFLA_INET6_RA_MTU */
 	     + 0;
 }
 
@@ -5651,6 +5652,9 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
 	if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
 		goto nla_put_failure;
 
+	if (nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))
+		goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
@@ -5767,6 +5771,9 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token,
 static const struct nla_policy inet6_af_policy[IFLA_INET6_MAX + 1] = {
 	[IFLA_INET6_ADDR_GEN_MODE]	= { .type = NLA_U8 },
 	[IFLA_INET6_TOKEN]		= { .len = sizeof(struct in6_addr) },
+	[IFLA_INET6_RA_MTU]		= { .type = NLA_REJECT,
+					    .reject_message =
+					    "IFLA_INET6_RA_MTU can not be set" },
 };
 
 static int check_addr_gen_mode(int mode)
@@ -6129,6 +6136,66 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
 		__ipv6_ifa_notify(event, ifp);
 }
 
+static inline size_t inet6_iframtu_msgsize(void)
+{
+	return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+	     + nla_total_size(IFNAMSIZ)	/* IFLA_IFNAME */
+	     + nla_total_size(4);	/* IFLA_INET6_RA_MTU */
+}
+
+static int inet6_fill_iframtu(struct sk_buff *skb, struct inet6_dev *idev)
+{
+	struct net_device *dev = idev->dev;
+	struct ifinfomsg *hdr;
+	struct nlmsghdr *nlh;
+
+	nlh = nlmsg_put(skb, 0, 0, RTM_NEWLINK, sizeof(*hdr), 0);
+	if (!nlh)
+		return -EMSGSIZE;
+
+	hdr = nlmsg_data(nlh);
+	hdr->ifi_family = AF_INET6;
+	hdr->__ifi_pad = 0;
+	hdr->ifi_index = dev->ifindex;
+	hdr->ifi_flags = dev_get_flags(dev);
+	hdr->ifi_change = 0;
+
+	if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
+	    nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))
+		goto nla_put_failure;
+
+	nlmsg_end(skb, nlh);
+	return 0;
+
+nla_put_failure:
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
+}
+
+void inet6_iframtu_notify(struct inet6_dev *idev)
+{
+	struct sk_buff *skb;
+	struct net *net = dev_net(idev->dev);
+	int err = -ENOBUFS;
+
+	skb = nlmsg_new(inet6_iframtu_msgsize(), GFP_ATOMIC);
+	if (!skb)
+		goto errout;
+
+	err = inet6_fill_iframtu(skb, idev);
+	if (err < 0) {
+		/* -EMSGSIZE implies BUG in inet6_iframtu_msgsize() */
+		WARN_ON(err == -EMSGSIZE);
+		kfree_skb(skb);
+		goto errout;
+	}
+	rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
+	return;
+errout:
+	if (err < 0)
+		rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
+}
+
 #ifdef CONFIG_SYSCTL
 
 static int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c467c6419893..a04164cbd77f 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1496,6 +1496,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
 		mtu = ntohl(n);
 
+		if (in6_dev->ra_mtu != mtu) {
+			in6_dev->ra_mtu = mtu;
+			inet6_iframtu_notify(in6_dev);
+			ND_PRINTK(2, info, "update ra_mtu to %d\n", in6_dev->ra_mtu);
+		}
+
 		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
 			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
 		} else if (in6_dev->cnf.mtu6 != mtu) {
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index eb15f319aa57..36a8ae4793f1 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -230,6 +230,7 @@ enum {
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
 	IFLA_INET6_TOKEN,	/* device token			*/
 	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	IFLA_INET6_RA_MTU,	/* mtu carried in the RA message  */
 	__IFLA_INET6_MAX
 };
 
-- 
2.18.0

From chunkuang.hu at kernel.org  Mon Aug  9 07:05:28 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Mon, 9 Aug 2021 22:05:28 +0800
Subject: [PATCH v2 5/5] drm/mediatek: Add support for main DDP path on
 MT8167
In-Reply-To: <20201023133130.194140-6-fparent@baylibre.com>
References: <20201023133130.194140-1-fparent@baylibre.com>
 <20201023133130.194140-6-fparent@baylibre.com>
Message-ID: <CAAOTY_-9zscXmC83oDkk-JZvnooZbiqtei+R2+c=VhBJ7xW84A@mail.gmail.com>

Hi, Fabien:

Fabien Parent <fparent at baylibre.com> ? 2020?10?23? ?? ??9:31???
>
> Add the main (DSI) drm display path for MT8167.
>

Applied to mediatek-drm-next [1], thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next

Regards,
Chun-Kuang.

> Signed-off-by: Fabien Parent <fparent at baylibre.com>
> ---
>
> Changelog:
>
> V2: No change
>
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c | 38 ++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 59c85c63b7cc..3952435093fe 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -112,6 +112,17 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = {
>         DDP_COMPONENT_PWM2,
>  };
>
> +static enum mtk_ddp_comp_id mt8167_mtk_ddp_main[] = {
> +       DDP_COMPONENT_OVL0,
> +       DDP_COMPONENT_COLOR0,
> +       DDP_COMPONENT_CCORR,
> +       DDP_COMPONENT_AAL0,
> +       DDP_COMPONENT_GAMMA,
> +       DDP_COMPONENT_DITHER,
> +       DDP_COMPONENT_RDMA0,
> +       DDP_COMPONENT_DSI0,
> +};
> +
>  static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
>         DDP_COMPONENT_OVL0,
>         DDP_COMPONENT_COLOR0,
> @@ -163,6 +174,11 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
>         .ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
>  };
>
> +static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
> +       .main_path = mt8167_mtk_ddp_main,
> +       .main_len = ARRAY_SIZE(mt8167_mtk_ddp_main),
> +};
> +
>  static int mtk_drm_kms_init(struct drm_device *drm)
>  {
>         struct mtk_drm_private *private = drm->dev_private;
> @@ -401,26 +417,42 @@ static const struct component_master_ops mtk_drm_ops = {
>  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>         { .compatible = "mediatek,mt2701-disp-ovl",
>           .data = (void *)MTK_DISP_OVL },
> +       { .compatible = "mediatek,mt8167-disp-ovl",
> +         .data = (void *)MTK_DISP_OVL },
>         { .compatible = "mediatek,mt8173-disp-ovl",
>           .data = (void *)MTK_DISP_OVL },
>         { .compatible = "mediatek,mt2701-disp-rdma",
>           .data = (void *)MTK_DISP_RDMA },
> +       { .compatible = "mediatek,mt8167-disp-rdma",
> +         .data = (void *)MTK_DISP_RDMA },
>         { .compatible = "mediatek,mt8173-disp-rdma",
>           .data = (void *)MTK_DISP_RDMA },
>         { .compatible = "mediatek,mt8173-disp-wdma",
>           .data = (void *)MTK_DISP_WDMA },
> +       { .compatible = "mediatek,mt8167-disp-ccorr",
> +         .data = (void *)MTK_DISP_CCORR },
>         { .compatible = "mediatek,mt2701-disp-color",
>           .data = (void *)MTK_DISP_COLOR },
> +       { .compatible = "mediatek,mt8167-disp-color",
> +         .data = (void *)MTK_DISP_COLOR },
>         { .compatible = "mediatek,mt8173-disp-color",
>           .data = (void *)MTK_DISP_COLOR },
> +       { .compatible = "mediatek,mt8167-disp-aal",
> +         .data = (void *)MTK_DISP_AAL},
>         { .compatible = "mediatek,mt8173-disp-aal",
>           .data = (void *)MTK_DISP_AAL},
> +       { .compatible = "mediatek,mt8167-disp-gamma",
> +         .data = (void *)MTK_DISP_GAMMA, },
>         { .compatible = "mediatek,mt8173-disp-gamma",
>           .data = (void *)MTK_DISP_GAMMA, },
> +       { .compatible = "mediatek,mt8167-disp-dither",
> +         .data = (void *)MTK_DISP_DITHER },
>         { .compatible = "mediatek,mt8173-disp-ufoe",
>           .data = (void *)MTK_DISP_UFOE },
>         { .compatible = "mediatek,mt2701-dsi",
>           .data = (void *)MTK_DSI },
> +       { .compatible = "mediatek,mt8167-dsi",
> +         .data = (void *)MTK_DSI },
>         { .compatible = "mediatek,mt8173-dsi",
>           .data = (void *)MTK_DSI },
>         { .compatible = "mediatek,mt2701-dpi",
> @@ -431,10 +463,14 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt2712-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
> +       { .compatible = "mediatek,mt8167-disp-mutex",
> +         .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt8173-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt2701-disp-pwm",
>           .data = (void *)MTK_DISP_BLS },
> +       { .compatible = "mediatek,mt8167-disp-pwm",
> +         .data = (void *)MTK_DISP_PWM },
>         { .compatible = "mediatek,mt8173-disp-pwm",
>           .data = (void *)MTK_DISP_PWM },
>         { .compatible = "mediatek,mt8173-disp-od",
> @@ -449,6 +485,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
>           .data = &mt7623_mmsys_driver_data},
>         { .compatible = "mediatek,mt2712-mmsys",
>           .data = &mt2712_mmsys_driver_data},
> +       { .compatible = "mediatek,mt8167-mmsys",
> +         .data = &mt8167_mmsys_driver_data},
>         { .compatible = "mediatek,mt8173-mmsys",
>           .data = &mt8173_mmsys_driver_data},
>         { }
> --
> 2.28.0
>


From chunkuang.hu at kernel.org  Mon Aug  9 07:06:01 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Mon, 9 Aug 2021 22:06:01 +0800
Subject: [PATCH v2 2/5] dt-bindings: display: mediatek: dsi: add
 documentation for MT8167 SoC
In-Reply-To: <20201023133130.194140-3-fparent@baylibre.com>
References: <20201023133130.194140-1-fparent@baylibre.com>
 <20201023133130.194140-3-fparent@baylibre.com>
Message-ID: <CAAOTY__-E19JJiw=0X=Kdm9afWSTCeoYFKJAVJObrikfhV=BVA@mail.gmail.com>

Hi, Fabien:

Fabien Parent <fparent at baylibre.com> ? 2020?10?23? ?? ??9:31???
>
> Add binding documentation for the MT8167 SoC.

Applied to mediatek-drm-next [1], thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next

Regards,
Chun-Kuang.

>
> Signed-off-by: Fabien Parent <fparent at baylibre.com>
> ---
>
> Changelog:
>
> V2: removed part that added a new clock
>
>  .../devicetree/bindings/display/mediatek/mediatek,dsi.txt     | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> index f06f24d405a5..6a10de812158 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> @@ -7,7 +7,7 @@ channel output.
>
>  Required properties:
>  - compatible: "mediatek,<chip>-dsi"
> -- the supported chips are mt2701, mt7623, mt8173 and mt8183.
> +- the supported chips are mt2701, mt7623, mt8167, mt8173 and mt8183.
>  - reg: Physical base address and length of the controller's registers
>  - interrupts: The interrupt signal from the function block.
>  - clocks: device clocks
> @@ -26,7 +26,7 @@ The MIPI TX configuration module controls the MIPI D-PHY.
>
>  Required properties:
>  - compatible: "mediatek,<chip>-mipi-tx"
> -- the supported chips are mt2701, 7623, mt8173 and mt8183.
> +- the supported chips are mt2701, 7623, mt8167, mt8173 and mt8183.
>  - reg: Physical base address and length of the controller's registers
>  - clocks: PLL reference clock
>  - clock-output-names: name of the output clock line to the DSI encoder
> --
> 2.28.0
>


From jc at kynesim.co.uk  Mon Aug  9 07:29:29 2021
From: jc at kynesim.co.uk (John Cox)
Date: Mon, 09 Aug 2021 15:29:29 +0100
Subject: [PATCH v13 2/9] media: hevc: Add decode params control
In-Reply-To: <20210603115004.915294-3-benjamin.gaignard@collabora.com>
References: <20210603115004.915294-1-benjamin.gaignard@collabora.com>
 <20210603115004.915294-3-benjamin.gaignard@collabora.com>
Message-ID: <h8e2hgh73r8lqgr8lgmuobubj2jcdg6mv5@4ax.com>

Hi

>Add decode params control and the associated structure to group
>all the information that are needed to decode a reference frame as
>is described in ITU-T Rec. H.265 section "8.3.2 Decoding process
>for reference picture set".

I'm sorry I'm commenting late but I've only just got round to
implementing code based on this.

>Adapt Cedrus driver to these changes.
>
>Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
>Reviewed-by: Ezequiel Garcia <ezequiel at collabora.com>
>---
>version 11:
> - Split what was done in v4l2-ctrls.c in v4l2-ctrls-core.c and v4l2-ctrls-defs.c
>
> .../media/v4l/ext-ctrls-codec.rst             | 94 +++++++++++++++----
> .../media/v4l/vidioc-queryctrl.rst            |  6 ++
> drivers/media/v4l2-core/v4l2-ctrls-core.c     | 21 +++--
> drivers/media/v4l2-core/v4l2-ctrls-defs.c     |  4 +
> drivers/staging/media/sunxi/cedrus/cedrus.c   |  6 ++
> drivers/staging/media/sunxi/cedrus/cedrus.h   |  1 +
> .../staging/media/sunxi/cedrus/cedrus_dec.c   |  2 +
> .../staging/media/sunxi/cedrus/cedrus_h265.c  | 12 ++-
> include/media/hevc-ctrls.h                    | 29 ++++--
> 9 files changed, 136 insertions(+), 39 deletions(-)
>
>diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>index 9cfb471fc6be..9120c5bcaf90 100644
>--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>@@ -2997,9 +2997,6 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>     * - __u8
>       - ``pic_struct``
>       -
>-    * - __u8
>-      - ``num_active_dpb_entries``
>-      - The number of entries in ``dpb``.
>     * - __u8
>       - ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>       - The list of L0 reference elements as indices in the DPB.
>@@ -3007,22 +3004,8 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>       - ``ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>       - The list of L1 reference elements as indices in the DPB.
>     * - __u8
>-      - ``num_rps_poc_st_curr_before``
>-      - The number of reference pictures in the short-term set that come before
>-        the current frame.
>-    * - __u8
>-      - ``num_rps_poc_st_curr_after``
>-      - The number of reference pictures in the short-term set that come after
>-        the current frame.
>-    * - __u8
>-      - ``num_rps_poc_lt_curr``
>-      - The number of reference pictures in the long-term set.
>-    * - __u8
>-      - ``padding[7]``
>+      - ``padding``
>       - Applications and drivers must set this to zero.
>-    * - struct :c:type:`v4l2_hevc_dpb_entry`
>-      - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>-      - The decoded picture buffer, for meta-data about reference frames.
>     * - struct :c:type:`v4l2_hevc_pred_weight_table`
>       - ``pred_weight_table``
>       - The prediction weight coefficients for inter-picture prediction.
>@@ -3278,3 +3261,78 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>     encoding the next frame queued after setting this control.
>     This provides a bitmask which consists of bits [0, LTR_COUNT-1].
>     This is applicable to the H264 and HEVC encoders.
>+
>+``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (struct)``
>+    Specifies various decode parameters, especially the references picture order
>+    count (POC) for all the lists (short, long, before, current, after) and the
>+    number of entries for each of them.
>+    These parameters are defined according to :ref:`hevc`.
>+    They are described in section 8.3 "Slice decoding process" of the
>+    specification.
>+
>+.. c:type:: v4l2_ctrl_hevc_decode_params
>+
>+.. cssclass:: longtable
>+
>+.. flat-table:: struct v4l2_ctrl_hevc_decode_params
>+    :header-rows:  0
>+    :stub-columns: 0
>+    :widths:       1 1 2
>+
>+    * - __s32
>+      - ``pic_order_cnt_val``
>+      - PicOrderCntVal as described in section 8.3.1 "Decoding process
>+        for picture order count" of the specification.
>+    * - __u8
>+      - ``num_active_dpb_entries``
>+      - The number of entries in ``dpb``.
>+    * - struct :c:type:`v4l2_hevc_dpb_entry`
>+      - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>+      - The decoded picture buffer, for meta-data about reference frames.
>+    * - __u8
>+      - ``num_poc_st_curr_before``
>+      - The number of reference pictures in the short-term set that come before
>+        the current frame.
>+    * - __u8
>+      - ``num_poc_st_curr_after``
>+      - The number of reference pictures in the short-term set that come after
>+        the current frame.
>+    * - __u8
>+      - ``num_poc_lt_curr``
>+      - The number of reference pictures in the long-term set.
>+    * - __u8
>+      - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>+      - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
>+        picture set.
>+    * - __u8
>+      - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>+      - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
>+        picture set.
>+    * - __u8
>+      - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>+      - PocLtCurr as described in section 8.3.2 "Decoding process for reference
>+        picture set.

Two things here

1) By my understanding poc_st_curr_before/after & poc_lt_curr attempt to
hold a POC (as per 8.3.2). That is a 32bit signed value not U8.  You can
get away with U16 if you mask & sign extend your comparisions but U8 I'm
pretty sure is too small.

2) I think you can calculate these list from the info in the DPB
structure. Certainly v4l2_hevc_dpb_entry.rps contains which list every
entry is in.

Regards

John Cox


>+    * - __u64
>+      - ``flags``
>+      - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
>+
>+.. _hevc_decode_params_flags:
>+
>+``Decode Parameters Flags``
>+
>+.. cssclass:: longtable
>+
>+.. flat-table::
>+    :header-rows:  0
>+    :stub-columns: 0
>+    :widths:       1 1 2
>+
>+    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC``
>+      - 0x00000001
>+      -
>+    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC``
>+      - 0x00000002
>+      -
>+    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR``
>+      - 0x00000004
>+      -
>diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
>index 07e54029e1e9..f9ecf6276129 100644
>--- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
>+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
>@@ -501,6 +501,12 @@ See also the examples in :ref:`control`.
>       - n/a
>       - A struct :c:type:`v4l2_ctrl_vp8_frame`, containing VP8
> 	frame parameters for stateless video decoders.
>+    * - ``V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS``
>+      - n/a
>+      - n/a
>+      - n/a
>+      - A struct :c:type:`v4l2_ctrl_hevc_decode_params`, containing HEVC
>+	decoding parameters for stateless video decoders.
> 
> .. raw:: latex
> 
>diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
>index 081439224357..c4b5082849b6 100644
>--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
>+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
>@@ -337,6 +337,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
> 	struct v4l2_ctrl_hevc_pps *p_hevc_pps;
> 	struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
> 	struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
>+	struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params;
> 	struct v4l2_area *area;
> 	void *p = ptr.p + idx * ctrl->elem_size;
> 	unsigned int i;
>@@ -616,23 +617,26 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
> 		zero_padding(*p_hevc_pps);
> 		break;
> 
>-	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
>-		p_hevc_slice_params = p;
>+	case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
>+		p_hevc_decode_params = p;
> 
>-		if (p_hevc_slice_params->num_active_dpb_entries >
>+		if (p_hevc_decode_params->num_active_dpb_entries >
> 		    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
> 			return -EINVAL;
> 
>-		zero_padding(p_hevc_slice_params->pred_weight_table);
>-
>-		for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries;
>+		for (i = 0; i < p_hevc_decode_params->num_active_dpb_entries;
> 		     i++) {
> 			struct v4l2_hevc_dpb_entry *dpb_entry =
>-				&p_hevc_slice_params->dpb[i];
>+				&p_hevc_decode_params->dpb[i];
> 
> 			zero_padding(*dpb_entry);
> 		}
>+		break;
> 
>+	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
>+		p_hevc_slice_params = p;
>+
>+		zero_padding(p_hevc_slice_params->pred_weight_table);
> 		zero_padding(*p_hevc_slice_params);
> 		break;
> 
>@@ -1236,6 +1240,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
> 	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> 		elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
> 		break;
>+	case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
>+		elem_size = sizeof(struct v4l2_ctrl_hevc_decode_params);
>+		break;
> 	case V4L2_CTRL_TYPE_HDR10_CLL_INFO:
> 		elem_size = sizeof(struct v4l2_ctrl_hdr10_cll_info);
> 		break;
>diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>index 7963c7b43450..b6344bbf1e00 100644
>--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>@@ -996,6 +996,7 @@ const char *v4l2_ctrl_get_name(u32 id)
> 	case V4L2_CID_MPEG_VIDEO_HEVC_SPS:			return "HEVC Sequence Parameter Set";
> 	case V4L2_CID_MPEG_VIDEO_HEVC_PPS:			return "HEVC Picture Parameter Set";
> 	case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:		return "HEVC Slice Parameters";
>+	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:		return "HEVC Decode Parameters";
> 	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:		return "HEVC Decode Mode";
> 	case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:		return "HEVC Start Code";
> 
>@@ -1487,6 +1488,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
> 	case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
> 		*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
> 		break;
>+	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:
>+		*type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS;
>+		break;
> 	case V4L2_CID_UNIT_CELL_SIZE:
> 		*type = V4L2_CTRL_TYPE_AREA;
> 		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
>diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
>index fa348c09f844..c0d005dafc6c 100644
>--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
>+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
>@@ -157,6 +157,12 @@ static const struct cedrus_control cedrus_controls[] = {
> 		},
> 		.codec		= CEDRUS_CODEC_VP8,
> 	},
>+	{
>+		.cfg = {
>+			.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS,
>+		},
>+		.codec		= CEDRUS_CODEC_H265,
>+	},
> };
> 
> #define CEDRUS_CONTROLS_COUNT	ARRAY_SIZE(cedrus_controls)
>diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
>index bbcdcd0787cf..88afba17b78b 100644
>--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
>+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
>@@ -77,6 +77,7 @@ struct cedrus_h265_run {
> 	const struct v4l2_ctrl_hevc_sps			*sps;
> 	const struct v4l2_ctrl_hevc_pps			*pps;
> 	const struct v4l2_ctrl_hevc_slice_params	*slice_params;
>+	const struct v4l2_ctrl_hevc_decode_params	*decode_params;
> };
> 
> struct cedrus_vp8_run {
>diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
>index 97e410d92506..40e8c4123f76 100644
>--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
>+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
>@@ -70,6 +70,8 @@ void cedrus_device_run(void *priv)
> 			V4L2_CID_MPEG_VIDEO_HEVC_PPS);
> 		run.h265.slice_params = cedrus_find_control_data(ctx,
> 			V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
>+		run.h265.decode_params = cedrus_find_control_data(ctx,
>+			V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS);
> 		break;
> 
> 	case V4L2_PIX_FMT_VP8_FRAME:
>diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>index 10744fab7cea..6821e3d05d34 100644
>--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>@@ -245,6 +245,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> 	const struct v4l2_ctrl_hevc_sps *sps;
> 	const struct v4l2_ctrl_hevc_pps *pps;
> 	const struct v4l2_ctrl_hevc_slice_params *slice_params;
>+	const struct v4l2_ctrl_hevc_decode_params *decode_params;
> 	const struct v4l2_hevc_pred_weight_table *pred_weight_table;
> 	dma_addr_t src_buf_addr;
> 	dma_addr_t src_buf_end_addr;
>@@ -256,6 +257,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> 	sps = run->h265.sps;
> 	pps = run->h265.pps;
> 	slice_params = run->h265.slice_params;
>+	decode_params = run->h265.decode_params;
> 	pred_weight_table = &slice_params->pred_weight_table;
> 
> 	/* MV column buffer size and allocation. */
>@@ -487,7 +489,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> 
> 	reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) |
> 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) |
>-	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(slice_params->num_rps_poc_st_curr_after == 0) |
>+	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(decode_params->num_poc_st_curr_after == 0) |
> 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) |
> 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) |
> 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta);
>@@ -527,8 +529,8 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> 	cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg);
> 
> 	/* Write decoded picture buffer in pic list. */
>-	cedrus_h265_frame_info_write_dpb(ctx, slice_params->dpb,
>-					 slice_params->num_active_dpb_entries);
>+	cedrus_h265_frame_info_write_dpb(ctx, decode_params->dpb,
>+					 decode_params->num_active_dpb_entries);
> 
> 	/* Output frame. */
> 
>@@ -545,7 +547,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> 
> 	/* Reference picture list 0 (for P/B frames). */
> 	if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) {
>-		cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
>+		cedrus_h265_ref_pic_list_write(dev, decode_params->dpb,
> 					       slice_params->ref_idx_l0,
> 					       slice_params->num_ref_idx_l0_active_minus1 + 1,
> 					       VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
>@@ -564,7 +566,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> 
> 	/* Reference picture list 1 (for B frames). */
> 	if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) {
>-		cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
>+		cedrus_h265_ref_pic_list_write(dev, decode_params->dpb,
> 					       slice_params->ref_idx_l1,
> 					       slice_params->num_ref_idx_l1_active_minus1 + 1,
> 					       VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
>diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
>index 245052c15864..e53666a1127f 100644
>--- a/include/media/hevc-ctrls.h
>+++ b/include/media/hevc-ctrls.h
>@@ -19,6 +19,7 @@
> #define V4L2_CID_MPEG_VIDEO_HEVC_SPS		(V4L2_CID_CODEC_BASE + 1008)
> #define V4L2_CID_MPEG_VIDEO_HEVC_PPS		(V4L2_CID_CODEC_BASE + 1009)
> #define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS	(V4L2_CID_CODEC_BASE + 1010)
>+#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS	(V4L2_CID_CODEC_BASE + 1012)
> #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE	(V4L2_CID_CODEC_BASE + 1015)
> #define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE	(V4L2_CID_CODEC_BASE + 1016)
> 
>@@ -26,6 +27,7 @@
> #define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
> #define V4L2_CTRL_TYPE_HEVC_PPS 0x0121
> #define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122
>+#define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124
> 
> enum v4l2_mpeg_video_hevc_decode_mode {
> 	V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
>@@ -195,18 +197,10 @@ struct v4l2_ctrl_hevc_slice_params {
> 	__u8	pic_struct;
> 
> 	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
>-	__u8	num_active_dpb_entries;
> 	__u8	ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> 	__u8	ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> 
>-	__u8	num_rps_poc_st_curr_before;
>-	__u8	num_rps_poc_st_curr_after;
>-	__u8	num_rps_poc_lt_curr;
>-
>-	__u8	padding;
>-
>-	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
>-	struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>+	__u8	padding[5];
> 
> 	/* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
> 	struct v4l2_hevc_pred_weight_table pred_weight_table;
>@@ -214,4 +208,21 @@ struct v4l2_ctrl_hevc_slice_params {
> 	__u64	flags;
> };
> 
>+#define V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC		0x1
>+#define V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC		0x2
>+#define V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR  0x4
>+
>+struct v4l2_ctrl_hevc_decode_params {
>+	__s32	pic_order_cnt_val;
>+	__u8	num_active_dpb_entries;
>+	struct	v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>+	__u8	num_poc_st_curr_before;
>+	__u8	num_poc_st_curr_after;
>+	__u8	num_poc_lt_curr;
>+	__u8	poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>+	__u8	poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>+	__u8	poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>+	__u64	flags;
>+};
>+
> #endif


From chunkuang.hu at kernel.org  Mon Aug  9 07:34:53 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Mon, 9 Aug 2021 22:34:53 +0800
Subject: [PATCH v6 4/7] drm/mediatek: adjust to the alphabetic order for
 mediatek-drm
In-Reply-To: <20210805205226.24880-5-jason-jh.lin@mediatek.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-5-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_9EajkTgyjV2F3K+S-Y=yZUbRg2maE34e73=FOnJsgjRg@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?6? ?? ??4:52???
>
> 1. Adjust to the alphabetic order for the define, function, struct
>    and array in mediatek-drm driver
> 2. Remove the unsed define in mtk_drm_ddp_comp.c

Separate the 2nd part to another patch.

>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 180 +++++++++-----------
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  22 +--
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  76 ++++-----
>  3 files changed, 133 insertions(+), 145 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 75bc00e17fc4..328ee19f931e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -20,50 +20,36 @@
>  #include "mtk_drm_ddp_comp.h"
>  #include "mtk_drm_crtc.h"
>
> -#define DISP_OD_EN                             0x0000
> -#define DISP_OD_INTEN                          0x0008
> -#define DISP_OD_INTSTA                         0x000c
> -#define DISP_OD_CFG                            0x0020
> -#define DISP_OD_SIZE                           0x0030
> -#define DISP_DITHER_5                          0x0114
> -#define DISP_DITHER_7                          0x011c
> -#define DISP_DITHER_15                         0x013c
> -#define DISP_DITHER_16                         0x0140
> -
> -#define DISP_REG_UFO_START                     0x0000
> -
> -#define DISP_AAL_EN                            0x0000
> -#define DISP_AAL_SIZE                          0x0030
> +#define DISP_REG_AAL_EN                                0x0000
> +#define AAL_EN                                 BIT(0)
> +#define DISP_REG_AAL_SIZE                      0x0030
>
> -#define DISP_DITHER_EN                         0x0000
> +#define DISP_REG_DITHER_EN                     0x0000

I think we should not change the register name just for alphabetic
order. We list the register in the order of its address.
If you have another reason to change register name, add another patch
to do this.

Regards,
Chun-Kuang.

>  #define DITHER_EN                              BIT(0)
> -#define DISP_DITHER_CFG                                0x0020
> +#define DISP_REG_DITHER_CFG                    0x0020
>  #define DITHER_RELAY_MODE                      BIT(0)
>  #define DITHER_ENGINE_EN                       BIT(1)
> -#define DISP_DITHER_SIZE                       0x0030
> -
> -#define LUT_10BIT_MASK                         0x03ff
> -
> -#define OD_RELAYMODE                           BIT(0)
> -
> -#define UFO_BYPASS                             BIT(2)
> -
> -#define AAL_EN                                 BIT(0)
> -
>  #define DISP_DITHERING                         BIT(2)
> +#define DISP_REG_DITHER_SIZE                   0x0030
> +#define DISP_REG_DITHER_5                      0x0114
> +#define DISP_REG_DITHER_7                      0x011c
> +#define DISP_REG_DITHER_15                     0x013c
>  #define DITHER_LSB_ERR_SHIFT_R(x)              (((x) & 0x7) << 28)
> -#define DITHER_OVFLW_BIT_R(x)                  (((x) & 0x7) << 24)
>  #define DITHER_ADD_LSHIFT_R(x)                 (((x) & 0x7) << 20)
> -#define DITHER_ADD_RSHIFT_R(x)                 (((x) & 0x7) << 16)
>  #define DITHER_NEW_BIT_MODE                    BIT(0)
> +#define DISP_REG_DITHER_16                     0x0140
>  #define DITHER_LSB_ERR_SHIFT_B(x)              (((x) & 0x7) << 28)
> -#define DITHER_OVFLW_BIT_B(x)                  (((x) & 0x7) << 24)
>  #define DITHER_ADD_LSHIFT_B(x)                 (((x) & 0x7) << 20)
> -#define DITHER_ADD_RSHIFT_B(x)                 (((x) & 0x7) << 16)
>  #define DITHER_LSB_ERR_SHIFT_G(x)              (((x) & 0x7) << 12)
> -#define DITHER_OVFLW_BIT_G(x)                  (((x) & 0x7) << 8)
>  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
> -#define DITHER_ADD_RSHIFT_G(x)                 (((x) & 0x7) << 0)
> +
> +#define DISP_REG_OD_EN                         0x0000
> +#define DISP_REG_OD_CFG                                0x0020
> +#define OD_RELAYMODE                           BIT(0)
> +#define DISP_REG_OD_SIZE                       0x0030
> +
> +#define DISP_REG_UFO_START                     0x0000
> +#define UFO_BYPASS                             BIT(2)
>
>  struct mtk_ddp_comp_dev {
>         struct clk *clk;
> @@ -116,20 +102,6 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
>  #endif
>  }
>
> -static int mtk_ddp_clk_enable(struct device *dev)
> -{
> -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> -
> -       return clk_prepare_enable(priv->clk);
> -}
> -
> -static void mtk_ddp_clk_disable(struct device *dev)
> -{
> -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> -
> -       clk_disable_unprepare(priv->clk);
> -}
> -
>  void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
>                            unsigned int bpc, unsigned int cfg,
>                            unsigned int dither_en, struct cmdq_pkt *cmdq_pkt)
> @@ -139,55 +111,35 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
>                 return;
>
>         if (bpc >= MTK_MIN_BPC) {
> -               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
> -               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
> +               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_5);
> +               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_7);
>                 mtk_ddp_write(cmdq_pkt,
>                               DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
>                               DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
>                               DITHER_NEW_BIT_MODE,
> -                             cmdq_reg, regs, DISP_DITHER_15);
> +                             cmdq_reg, regs, DISP_REG_DITHER_15);
>                 mtk_ddp_write(cmdq_pkt,
>                               DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
>                               DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
>                               DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
>                               DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
> -                             cmdq_reg, regs, DISP_DITHER_16);
> +                             cmdq_reg, regs, DISP_REG_DITHER_16);
>                 mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg);
>         }
>  }
>
> -static void mtk_dither_set(struct device *dev, unsigned int bpc,
> -                   unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
> -{
> -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> -
> -       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
> -                             DISP_DITHERING, cmdq_pkt);
> -}
> -
> -static void mtk_od_config(struct device *dev, unsigned int w,
> -                         unsigned int h, unsigned int vrefresh,
> -                         unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> -{
> -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> -
> -       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE);
> -       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG);
> -       mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
> -}
> -
> -static void mtk_od_start(struct device *dev)
> +static int mtk_ddp_clk_enable(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(1, priv->regs + DISP_OD_EN);
> +       return clk_prepare_enable(priv->clk);
>  }
>
> -static void mtk_ufoe_start(struct device *dev)
> +static void mtk_ddp_clk_disable(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
> +       clk_disable_unprepare(priv->clk);
>  }
>
>  static void mtk_aal_config(struct device *dev, unsigned int w,
> @@ -196,7 +148,7 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
> +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_AAL_SIZE);
>  }
>
>  static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
> @@ -210,14 +162,14 @@ static void mtk_aal_start(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(AAL_EN, priv->regs + DISP_AAL_EN);
> +       writel(AAL_EN, priv->regs + DISP_REG_AAL_EN);
>  }
>
>  static void mtk_aal_stop(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel_relaxed(0x0, priv->regs + DISP_AAL_EN);
> +       writel_relaxed(0x0, priv->regs + DISP_REG_AAL_EN);
>  }
>
>  static void mtk_dither_config(struct device *dev, unsigned int w,
> @@ -226,9 +178,11 @@ static void mtk_dither_config(struct device *dev, unsigned int w,
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_DITHER_SIZE);
> -       mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, DISP_DITHER_CFG);
> -       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_DITHER_CFG,
> +       mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
> +                     DISP_REG_DITHER_SIZE);
> +       mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
> +                     DISP_REG_DITHER_CFG);
> +       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
>                               DITHER_ENGINE_EN, cmdq_pkt);
>  }
>
> @@ -236,14 +190,48 @@ static void mtk_dither_start(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
> +       writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
>  }
>
>  static void mtk_dither_stop(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
> +       writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
> +}
> +
> +static void mtk_dither_set(struct device *dev, unsigned int bpc,
> +                          unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
> +                             DISP_DITHERING, cmdq_pkt);
> +}
> +
> +static void mtk_od_config(struct device *dev, unsigned int w,
> +                         unsigned int h, unsigned int vrefresh,
> +                         unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
> +       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
> +       mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
> +}
> +
> +static void mtk_od_start(struct device *dev)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       writel(1, priv->regs + DISP_REG_OD_EN);
> +}
> +
> +static void mtk_ufoe_start(struct device *dev)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
>  }
>
>  static const struct mtk_ddp_comp_funcs ddp_aal = {
> @@ -340,22 +328,22 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
>  };
>
>  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> +       [MTK_DISP_AAL] = "aal",
> +       [MTK_DISP_BLS] = "bls",
> +       [MTK_DISP_CCORR] = "ccorr",
> +       [MTK_DISP_COLOR] = "color",
> +       [MTK_DISP_DITHER] = "dither",
> +       [MTK_DISP_GAMMA] = "gamma",
> +       [MTK_DISP_MUTEX] = "mutex",
> +       [MTK_DISP_OD] = "od",
>         [MTK_DISP_OVL] = "ovl",
>         [MTK_DISP_OVL_2L] = "ovl-2l",
> +       [MTK_DISP_PWM] = "pwm",
>         [MTK_DISP_RDMA] = "rdma",
> -       [MTK_DISP_WDMA] = "wdma",
> -       [MTK_DISP_COLOR] = "color",
> -       [MTK_DISP_CCORR] = "ccorr",
> -       [MTK_DISP_AAL] = "aal",
> -       [MTK_DISP_GAMMA] = "gamma",
> -       [MTK_DISP_DITHER] = "dither",
>         [MTK_DISP_UFOE] = "ufoe",
> -       [MTK_DSI] = "dsi",
> +       [MTK_DISP_WDMA] = "wdma",
>         [MTK_DPI] = "dpi",
> -       [MTK_DISP_PWM] = "pwm",
> -       [MTK_DISP_MUTEX] = "mutex",
> -       [MTK_DISP_OD] = "od",
> -       [MTK_DISP_BLS] = "bls",
> +       [MTK_DSI] = "dsi",
>  };
>
>  struct mtk_ddp_comp_match {
> @@ -509,12 +497,12 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>             type == MTK_DISP_CCORR ||
>             type == MTK_DISP_COLOR ||
>             type == MTK_DISP_GAMMA ||
> -           type == MTK_DPI ||
> -           type == MTK_DSI ||
>             type == MTK_DISP_OVL ||
>             type == MTK_DISP_OVL_2L ||
>             type == MTK_DISP_PWM ||
> -           type == MTK_DISP_RDMA)
> +           type == MTK_DISP_RDMA ||
> +           type == MTK_DPI ||
> +           type == MTK_DSI)
>                 return 0;
>
>         priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index bb914d976cf5..d317b944df66 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -18,22 +18,22 @@ struct mtk_plane_state;
>  struct drm_crtc_state;
>
>  enum mtk_ddp_comp_type {
> -       MTK_DISP_OVL,
> -       MTK_DISP_OVL_2L,
> -       MTK_DISP_RDMA,
> -       MTK_DISP_WDMA,
> -       MTK_DISP_COLOR,
> +       MTK_DISP_AAL,
> +       MTK_DISP_BLS,
>         MTK_DISP_CCORR,
> +       MTK_DISP_COLOR,
>         MTK_DISP_DITHER,
> -       MTK_DISP_AAL,
>         MTK_DISP_GAMMA,
> -       MTK_DISP_UFOE,
> -       MTK_DSI,
> -       MTK_DPI,
> -       MTK_DISP_PWM,
>         MTK_DISP_MUTEX,
>         MTK_DISP_OD,
> -       MTK_DISP_BLS,
> +       MTK_DISP_OVL,
> +       MTK_DISP_OVL_2L,
> +       MTK_DISP_PWM,
> +       MTK_DISP_RDMA,
> +       MTK_DISP_UFOE,
> +       MTK_DISP_WDMA,
> +       MTK_DPI,
> +       MTK_DSI,
>         MTK_DDP_COMP_TYPE_MAX,
>  };
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index b46bdb8985da..a95dc1006b82 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -396,50 +396,20 @@ static const struct component_master_ops mtk_drm_ops = {
>  };
>
>  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
> -       { .compatible = "mediatek,mt2701-disp-ovl",
> -         .data = (void *)MTK_DISP_OVL },
> -       { .compatible = "mediatek,mt8173-disp-ovl",
> -         .data = (void *)MTK_DISP_OVL },
> -       { .compatible = "mediatek,mt8183-disp-ovl",
> -         .data = (void *)MTK_DISP_OVL },
> -       { .compatible = "mediatek,mt8183-disp-ovl-2l",
> -         .data = (void *)MTK_DISP_OVL_2L },
> -       { .compatible = "mediatek,mt2701-disp-rdma",
> -         .data = (void *)MTK_DISP_RDMA },
> -       { .compatible = "mediatek,mt8173-disp-rdma",
> -         .data = (void *)MTK_DISP_RDMA },
> -       { .compatible = "mediatek,mt8183-disp-rdma",
> -         .data = (void *)MTK_DISP_RDMA },
> -       { .compatible = "mediatek,mt8173-disp-wdma",
> -         .data = (void *)MTK_DISP_WDMA },
> +       { .compatible = "mediatek,mt8173-disp-aal",
> +         .data = (void *)MTK_DISP_AAL},
>         { .compatible = "mediatek,mt8183-disp-ccorr",
>           .data = (void *)MTK_DISP_CCORR },
>         { .compatible = "mediatek,mt2701-disp-color",
>           .data = (void *)MTK_DISP_COLOR },
>         { .compatible = "mediatek,mt8173-disp-color",
>           .data = (void *)MTK_DISP_COLOR },
> -       { .compatible = "mediatek,mt8173-disp-aal",
> -         .data = (void *)MTK_DISP_AAL},
> +       { .compatible = "mediatek,mt8183-disp-dither",
> +         .data = (void *)MTK_DISP_DITHER },
>         { .compatible = "mediatek,mt8173-disp-gamma",
>           .data = (void *)MTK_DISP_GAMMA, },
>         { .compatible = "mediatek,mt8183-disp-gamma",
>           .data = (void *)MTK_DISP_GAMMA, },
> -       { .compatible = "mediatek,mt8183-disp-dither",
> -         .data = (void *)MTK_DISP_DITHER },
> -       { .compatible = "mediatek,mt8173-disp-ufoe",
> -         .data = (void *)MTK_DISP_UFOE },
> -       { .compatible = "mediatek,mt2701-dsi",
> -         .data = (void *)MTK_DSI },
> -       { .compatible = "mediatek,mt8173-dsi",
> -         .data = (void *)MTK_DSI },
> -       { .compatible = "mediatek,mt8183-dsi",
> -         .data = (void *)MTK_DSI },
> -       { .compatible = "mediatek,mt2701-dpi",
> -         .data = (void *)MTK_DPI },
> -       { .compatible = "mediatek,mt8173-dpi",
> -         .data = (void *)MTK_DPI },
> -       { .compatible = "mediatek,mt8183-dpi",
> -         .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt2701-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt2712-disp-mutex",
> @@ -448,12 +418,42 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt8183-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
> +       { .compatible = "mediatek,mt8173-disp-od",
> +         .data = (void *)MTK_DISP_OD },
> +       { .compatible = "mediatek,mt2701-disp-ovl",
> +         .data = (void *)MTK_DISP_OVL },
> +       { .compatible = "mediatek,mt8173-disp-ovl",
> +         .data = (void *)MTK_DISP_OVL },
> +       { .compatible = "mediatek,mt8183-disp-ovl",
> +         .data = (void *)MTK_DISP_OVL },
> +       { .compatible = "mediatek,mt8183-disp-ovl-2l",
> +         .data = (void *)MTK_DISP_OVL_2L },
>         { .compatible = "mediatek,mt2701-disp-pwm",
>           .data = (void *)MTK_DISP_BLS },
>         { .compatible = "mediatek,mt8173-disp-pwm",
>           .data = (void *)MTK_DISP_PWM },
> -       { .compatible = "mediatek,mt8173-disp-od",
> -         .data = (void *)MTK_DISP_OD },
> +       { .compatible = "mediatek,mt2701-disp-rdma",
> +         .data = (void *)MTK_DISP_RDMA },
> +       { .compatible = "mediatek,mt8173-disp-rdma",
> +         .data = (void *)MTK_DISP_RDMA },
> +       { .compatible = "mediatek,mt8183-disp-rdma",
> +         .data = (void *)MTK_DISP_RDMA },
> +       { .compatible = "mediatek,mt8173-disp-ufoe",
> +         .data = (void *)MTK_DISP_UFOE },
> +       { .compatible = "mediatek,mt8173-disp-wdma",
> +         .data = (void *)MTK_DISP_WDMA },
> +       { .compatible = "mediatek,mt2701-dpi",
> +         .data = (void *)MTK_DPI },
> +       { .compatible = "mediatek,mt8173-dpi",
> +         .data = (void *)MTK_DPI },
> +       { .compatible = "mediatek,mt8183-dpi",
> +         .data = (void *)MTK_DPI },
> +       { .compatible = "mediatek,mt2701-dsi",
> +         .data = (void *)MTK_DSI },
> +       { .compatible = "mediatek,mt8173-dsi",
> +         .data = (void *)MTK_DSI },
> +       { .compatible = "mediatek,mt8183-dsi",
> +         .data = (void *)MTK_DSI },
>         { }
>  };
>
> @@ -542,8 +542,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
>                     comp_type == MTK_DISP_OVL ||
>                     comp_type == MTK_DISP_OVL_2L ||
>                     comp_type == MTK_DISP_RDMA ||
> -                   comp_type == MTK_DSI ||
> -                   comp_type == MTK_DPI) {
> +                   comp_type == MTK_DPI ||
> +                   comp_type == MTK_DSI) {
>                         dev_info(dev, "Adding component match for %pOF\n",
>                                  node);
>                         drm_of_component_match_add(dev, &match, compare_of,
> --
> 2.18.0
>


From boqun.feng at gmail.com  Mon Aug  9 07:38:48 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Mon, 9 Aug 2021 22:38:48 +0800
Subject: [PATCH v6 8/8] PCI: hv: Turn on the host bridge probing on ARM64
In-Reply-To: <20210803171451.GA15466@lpieralisi>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-9-boqun.feng@gmail.com>
 <20210803171451.GA15466@lpieralisi>
Message-ID: <YRE9+LaAjAW3SUvc@boqun-archlinux>

On Tue, Aug 03, 2021 at 06:14:51PM +0100, Lorenzo Pieralisi wrote:
> On Tue, Jul 27, 2021 at 02:06:57AM +0800, Boqun Feng wrote:
> > Now we have everything we need, just provide a proper sysdata type for
> > the bus to use on ARM64 and everything else works.
> > 
> > Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
> > ---
> >  drivers/pci/controller/pci-hyperv.c | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> > index e6276aaa4659..62dbe98d1fe1 100644
> > --- a/drivers/pci/controller/pci-hyperv.c
> > +++ b/drivers/pci/controller/pci-hyperv.c
> > @@ -40,6 +40,7 @@
> >  #include <linux/kernel.h>
> >  #include <linux/module.h>
> >  #include <linux/pci.h>
> > +#include <linux/pci-ecam.h>
> >  #include <linux/delay.h>
> >  #include <linux/semaphore.h>
> >  #include <linux/irqdomain.h>
> > @@ -448,7 +449,11 @@ enum hv_pcibus_state {
> >  };
> >  
> >  struct hv_pcibus_device {
> > +#ifdef CONFIG_X86
> >  	struct pci_sysdata sysdata;
> > +#elif defined(CONFIG_ARM64)
> > +	struct pci_config_window sysdata;
> 
> This is ugly. HV does not need pci_config_window at all right
> (other than arm64 pcibios_root_bridge_prepare()) ?
> 

Right.

> The issue is that in HV you have to have *some* sysdata != NULL, it is
> just some data to retrieve the hv_pcibus_device.
> 
> Mmaybe we can rework ARM64 ACPI code to store the acpi_device in struct
> pci_host_bridge->private instead of retrieving it from pci_config_window
> so that we decouple HV from the ARM64 back-end.
> 
> HV would just set struct pci_host_bridge->private == NULL.
> 

Works for me, but please note that pci_sysdata is an x86-specific
structure, so we still need to define a fake pci_sysdata inside
pci-hyperv.c, like:

	#ifndef CONFIG_X86
	struct pci_sysdata { };
	#end

> I need to think about this a bit, I don't think it should block
> this series though but it would be nicer.

After a quick look into the code, seems that what we need to do is to
add an additional parameter for acpi_pci_root_create() and introduce a
slightly different version of pci_create_root_bus(). A question is:
should we only do this for ARM64, or should we also do this for
other acpi_pci_root_create() users (x86 and ia64)? Another question
comes to my mind is, while we are at it, is there anything else that we
want to move from sysdata to ->private? These questions are out of scope
of this patchset, I think. Maybe it's better that we address them in the
future, and I can send out separate RFC patches to start the discussion.
Does that sound like a plan to you?

Regards,
Boqun

> 
> Lorenzo
> 
> > +#endif
> >  	struct pci_host_bridge *bridge;
> >  	struct fwnode_handle *fwnode;
> >  	/* Protocol version negotiated with the host */
> > @@ -3075,7 +3080,9 @@ static int hv_pci_probe(struct hv_device *hdev,
> >  			 dom_req, dom);
> >  
> >  	hbus->bridge->domain_nr = dom;
> > +#ifdef CONFIG_X86
> >  	hbus->sysdata.domain = dom;
> > +#endif
> >  
> >  	hbus->hdev = hdev;
> >  	INIT_LIST_HEAD(&hbus->children);
> > -- 
> > 2.32.0
> > 


From chunkuang.hu at kernel.org  Mon Aug  9 07:44:52 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Mon, 9 Aug 2021 22:44:52 +0800
Subject: [PATCH v6 1/1] drm/mediatek: force hsa hbp hfp packets multiple
 of lanenum to avoid screen shift
In-Reply-To: <20210808134117.66798-2-jitao.shi@mediatek.com>
References: <20210808134117.66798-1-jitao.shi@mediatek.com>
 <20210808134117.66798-2-jitao.shi@mediatek.com>
Message-ID: <CAAOTY_90UteUjOgJ5w7vKW6amXCfps7=SennwYYk2=TUrr6aYA@mail.gmail.com>

Hi, Jitao:

Jitao Shi <jitao.shi at mediatek.com> ? 2021?8?8? ?? ??9:41???
>
> The bridge chip ANX7625 requires the packets on lanes aligned at the end,
> or ANX7625 will shift the screen.

In anx7625_attach_dsi(), it call mipi_dsi_attach(), and it call into
mtk_dsi_host_attach().
I would like to pass this information from anx7623 driver to mtk_dsi
driver when attach.

Regards,
Chun-Kuang.

>
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index ae403c67cbd9..033234d51e86 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -194,6 +194,8 @@ struct mtk_dsi {
>         struct clk *hs_clk;
>
>         u32 data_rate;
> +       /* force dsi line end without dsi_null data */
> +       bool force_dsi_end_without_null;
>
>         unsigned long mode_flags;
>         enum mipi_dsi_pixel_format format;
> @@ -499,6 +501,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>                 DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
>         }
>
> +       if (dsi->force_dsi_end_without_null) {
> +               horizontal_sync_active_byte = roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
> +               horizontal_frontporch_byte = roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
> +               horizontal_backporch_byte = roundup(horizontal_backporch_byte, dsi->lanes) - 2;
> +               horizontal_backporch_byte -= (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
> +       }
> +
>         writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
>         writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>         writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
> @@ -1095,6 +1104,10 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>         dsi->bridge.of_node = dev->of_node;
>         dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>
> +       if (dsi->next_bridge)
> +               dsi->force_dsi_end_without_null = of_device_is_compatible(dsi->next_bridge->of_node,
> +                                                                         "analogix,anx7625");
> +
>         drm_bridge_add(&dsi->bridge);
>
>         ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
> --
> 2.25.1


From macromorgan at hotmail.com  Mon Aug  9 07:45:02 2021
From: macromorgan at hotmail.com (Chris Morgan)
Date: Mon, 9 Aug 2021 09:45:02 -0500
Subject: [RFC v2 3/4] power: supply: Add charger driver for Rockchip RK817
In-Reply-To: <20210808234738.s76kgcswcff6xe4l@earth.universe>
References: <20210726190130.1973-1-macroalpha82@gmail.com>
 <20210726190130.1973-4-macroalpha82@gmail.com>
 <20210808234738.s76kgcswcff6xe4l@earth.universe>
Message-ID: <SN6PR06MB534257D38CA4858B776BD346A5F69@SN6PR06MB5342.namprd06.prod.outlook.com>

On Mon, Aug 09, 2021 at 01:47:38AM +0200, Sebastian Reichel wrote:
> Hi,
> 
> On Mon, Jul 26, 2021 at 02:01:29PM -0500, Chris Morgan wrote:
> > From: Chris Morgan <macromorgan at hotmail.com>
> > 
> > Add support for the Rockchip rk817 battery charger integrated into the
> > rk817 PMIC.
> > 
> > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> > Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
> > ---
> >  drivers/power/supply/Kconfig         |   6 +
> >  drivers/power/supply/Makefile        |   1 +
> >  drivers/power/supply/rk817_charger.c | 932 +++++++++++++++++++++++++++
> >  3 files changed, 939 insertions(+)
> >  create mode 100644 drivers/power/supply/rk817_charger.c
> > 
> > diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
> > index 11f5368e810e..311130da36ff 100644
> > --- a/drivers/power/supply/Kconfig
> > +++ b/drivers/power/supply/Kconfig
> > @@ -666,6 +666,12 @@ config CHARGER_BQ256XX
> >  	  charge management and system power path management devices for single
> >  	  cell Li-ion and Li-polymer batteries.
> >  
> > +config CHARGER_RK817
> > +	tristate "Rockchip RK817 PMIC Battery Charger"
> > +	depends on MFD_RK808
> > +	help
> > +	  Say Y to include support for Rockchip RK817 Battery Charger.
> > +
> >  config CHARGER_SMB347
> >  	tristate "Summit Microelectronics SMB3XX Battery Charger"
> >  	depends on I2C
> > diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
> > index 33059a91f60c..9497d2105712 100644
> > --- a/drivers/power/supply/Makefile
> > +++ b/drivers/power/supply/Makefile
> > @@ -87,6 +87,7 @@ obj-$(CONFIG_CHARGER_BQ2515X)	+= bq2515x_charger.o
> >  obj-$(CONFIG_CHARGER_BQ25890)	+= bq25890_charger.o
> >  obj-$(CONFIG_CHARGER_BQ25980)	+= bq25980_charger.o
> >  obj-$(CONFIG_CHARGER_BQ256XX)	+= bq256xx_charger.o
> > +obj-$(CONFIG_CHARGER_RK817)	+= rk817_charger.o
> >  obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
> >  obj-$(CONFIG_CHARGER_TPS65090)	+= tps65090-charger.o
> >  obj-$(CONFIG_CHARGER_TPS65217)	+= tps65217_charger.o
> > diff --git a/drivers/power/supply/rk817_charger.c b/drivers/power/supply/rk817_charger.c
> > new file mode 100644
> > index 000000000000..0861bd428756
> > --- /dev/null
> > +++ b/drivers/power/supply/rk817_charger.c
> > @@ -0,0 +1,932 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Charger Driver for Rockchip rk817
> > + *
> > + * Copyright (c) 2021
> > + *
> > + * Authors: Maya Matuszczyk <maccraft123mc at gmail.com>
> > + *	    Chris Morgan <macromorgan at hotmail.com>
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/extcon.h>
> > +#include <linux/fb.h>
> > +#include <linux/gpio.h>
> > +#include <linux/iio/consumer.h>
> > +#include <linux/iio/iio.h>
> > +#include <linux/irq.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/mfd/rk808.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_gpio.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/rtc.h>
> > +#include <linux/timer.h>
> > +#include <linux/workqueue.h>
> > +#include <linux/power_supply.h>
> 
> how the heck did you come up with those includes? You are neither
> using extcon, framebuffer, gpio, iio, rtc, workqueue, nor timers.

I think I forgot to purge them from an earlier version of the driver.
I'll clean them up to ensure we only include what is needed going
forward.

> 
> > +/* Charging statuses reported by hardware register */
> > +enum rk817_charge_status {
> > +	CHRG_OFF,
> > +	DEAD_CHRG,
> > +	TRICKLE_CHRG,
> > +	CC_OR_CV_CHRG,
> > +	CHARGE_FINISH,
> > +	USB_OVER_VOL,
> > +	BAT_TMP_ERR,
> > +	BAT_TIM_ERR,
> > +};
> > +
> > +/* Max charging current read to/written from hardware register.
> > + * Note how highest value corresponding to 0x7 is the lowest
> > + * current, this is per the datasheet.
> > + */
> > +enum rk817_chg_cur {
> > +	CHG_1A,
> > +	CHG_1_5A,
> > +	CHG_2A,
> > +	CHG_2_5A,
> > +	CHG_2_75A,
> > +	CHG_3A,
> > +	CHG_3_5A,
> > +	CHG_0_5A,
> > +};
> > +
> > +struct rk817_charger {
> > +	struct device *dev;
> > +	struct rk808 *rk808;
> > +
> > +	struct power_supply *bat_ps;
> > +	struct power_supply_battery_info bat_info;
> > +
> > +	struct power_supply *chg_ps;
> > +	bool plugged_in;
> > +
> > +	uint32_t voltage_k;
> > +	uint32_t voltage_b;
> 
> what's voltage_k and voltage_b?
> 

To be brutally honest I don't know. It appears to be some coefficents
used for calibrating the voltage output as read by the ADC. In the
datasheet and BSP driver that's what it's called, but aside from that
I don't see an explicit explanation of it anywhere else.

> > +
> > +	/* dsoc seems to be difference between full charge and actual charge in
> > +	 * BSP stored as a percentage, to the thousandth.
> > +	 */
> > +	int dsoc;
> > +
> > +	/* Implementation specific properties from device tree */
> > +	int res_div;
> > +	int sleep_enter_current;
> > +	int sleep_filter_current;
> > +};
> > +
> > +/* ADC coefficients extracted from BSP kernel */
> > +#define ADC_TO_CURRENT(adc_value, res_div)	\
> > +	(adc_value * 172 / res_div)
> > +
> > +#define CURRENT_TO_ADC(current, samp_res)	\
> > +	(current * samp_res / 172)
> > +
> > +#define CHARGE_TO_ADC(capacity, res_div)	\
> > +	(capacity * res_div * 3600 / 172 * 1000)
> > +
> > +#define ADC_TO_CHARGE_UAH(adc_value, res_div)	\
> > +	(adc_value / 3600 * 172 / res_div)
> > +
> > +#define ADC_TO_CAPACITY(adc_value, res_div)	\
> > +	(adc_value / 1000 * 172 / 3600 / res_div)
> > +
> > +static u8 rk817_chg_cur_to_reg(u32 chg_cur_ma)
> > +{
> > +	if (chg_cur_ma < 500)
> > +		return -EINVAL;
> > +	else if (chg_cur_ma < 1000)
> > +		return CHG_0_5A;
> > +	else if (chg_cur_ma < 1500)
> > +		return CHG_1A;
> > +	else if (chg_cur_ma < 2000)
> > +		return CHG_1_5A;
> > +	else if (chg_cur_ma < 2500)
> > +		return CHG_2A;
> > +	else if (chg_cur_ma < 2750)
> > +		return CHG_2_5A;
> > +	else if (chg_cur_ma < 3000)
> > +		return CHG_2_75A;
> > +	else if (chg_cur_ma < 3500)
> > +		return CHG_3A;
> > +	else
> > +		return CHG_3_5A;
> > +}
> 
> if you change the order this becomes more readable:
> 
> if (chg_cur_ma > 3500)
>     return CHG_3_5A;
> else if (chg_cur_ma > 3000)
>     return CHG_3A;
> ...
> else if (chg_cur_ma > 500)
>     return CHG_0_5A;
> else
>     return -EINVAL;

Acknowledged, will change.

> 
> > +static int rk817_chg_cur_from_reg(u8 reg)
> > +{
> > +	switch (reg) {
> > +	case CHG_0_5A:
> > +		return 500000;
> > +	case CHG_1A:
> > +		return 1000000;
> > +	case CHG_1_5A:
> > +		return 1500000;
> > +	case CHG_2A:
> > +		return 2000000;
> > +	case CHG_2_5A:
> > +		return 2500000;
> > +	case CHG_2_75A:
> > +		return 2750000;
> > +	case CHG_3A:
> > +		return 3000000;
> > +	case CHG_3_5A:
> > +		return 3500000;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +}
> > +
> > +static int rk817_get_reg_hl(struct rk817_charger *charger, int regH, int regL)
> > +{
> > +	int tmp, ret;
> > +	uint32_t out;
> > +	struct rk808 *rk808 = charger->rk808;
> > +
> > +	ret = regmap_read(rk808->regmap, regL, &tmp);
> > +	if (ret)
> > +		return ret;
> > +	out = tmp;
> > +
> > +	ret = regmap_read(rk808->regmap, regH, &tmp);
> > +	if (ret)
> > +		return ret;
> > +	out |= tmp << 8;
> > +
> > +	return out;
> > +}
> > +
> > +static void rk817_write_reg_hl(struct rk817_charger *charger, int regH,
> > +			       int regL, int val)
> > +{
> > +	uint8_t tmp;
> > +	struct rk808 *rk808 = charger->rk808;
> > +
> > +	tmp = val & 0xff;
> > +	regmap_write(rk808->regmap, regL, tmp);
> > +	tmp = (val >> 8) & 0xff;
> > +	regmap_write(rk808->regmap, regH, tmp);
> > +}
> > +
> > +static void rk817_bat_calib_vol(struct rk817_charger *charger)
> > +{
> > +	uint32_t vcalib0 = 0;
> > +	uint32_t vcalib1 = 0;
> > +
> > +	/* calibrate voltage */
> > +	vcalib0 = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_VCALIB0_H,
> > +				   RK817_GAS_GAUGE_VCALIB0_L);
> > +	vcalib1 = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_VCALIB1_H,
> > +				   RK817_GAS_GAUGE_VCALIB1_L);
> > +
> > +	/* values were taken from BSP kernel */
> > +	charger->voltage_k = (4025 - 2300) * 1000 /
> > +			     ((vcalib1 - vcalib0) ? (vcalib1 - vcalib0) : 1);
> > +	charger->voltage_b = 4025 - (charger->voltage_k * vcalib1) / 1000;
> > +}
> > +
> > +static void rk817_bat_calib_cur(struct rk817_charger *charger)
> > +{
> > +	int ioffset = 0;
> > +	/* calibrate current */
> > +	ioffset = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_IOFFSET_H,
> > +				   RK817_GAS_GAUGE_IOFFSET_L);
> > +	rk817_write_reg_hl(charger, RK817_GAS_GAUGE_CAL_OFFSET_H,
> > +			   RK817_GAS_GAUGE_CAL_OFFSET_L, ioffset);
> > +}
> > +
> > +static int rk817_bat_calib_cap(struct rk817_charger *charger)
> > +{
> > +	struct rk808 *rk808 = charger->rk808;
> > +	struct power_supply_battery_info *info = &charger->bat_info;
> > +	int reg, tmp, charge_now, charge_now_adc, dsoc_value;
> > +	u8 bulk_reg[4];
> > +
> > +	/* Calibrate the capacity on a fully charged battery */
> > +
> > +	regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
> > +	tmp = (reg >> 4) & 0x07;
> > +	if (tmp == CHARGE_FINISH) {
> > +		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
> > +				 bulk_reg, 4);
> > +		charge_now_adc = (bulk_reg[0] << 24) | (bulk_reg[1] << 16) |
> > +				 (bulk_reg[2] << 8) | bulk_reg[3];
> 
> charge_now_adc = get_unaligned_be32(bulk_reg);

Thank you, I was unfamiliar with that macro.

> 
> > +		if (charge_now_adc < 0)
> > +			charge_now_adc = 0;
> > +		charge_now = ADC_TO_CHARGE_UAH(charge_now_adc, charger->res_div);
> > +		dsoc_value = ((charge_now * 100) /
> > +			      (info->charge_full_design_uah / 1000));
> > +		if (dsoc_value > 100000)
> > +			charger->dsoc = 100000;
> > +		if (dsoc_value != charger->dsoc) {
> > +			charger->dsoc = dsoc_value;
> > +			bulk_reg[2] = (dsoc_value >> 16) & 0xff;
> > +			bulk_reg[1] = (dsoc_value >> 8) & 0xff;
> > +			bulk_reg[0] = dsoc_value & 0xff;
> 
> put_unaligned_le24(dsoc_value, bulk_reg);
> 

Ditto for this macro, thank you.

> > +			regmap_bulk_write(rk808->regmap,
> > +					  RK817_GAS_GAUGE_BAT_R1, bulk_reg, 3);
> > +		}
> > +	}
> > +
> > +	return 0;
> > +
> > +}
> 
> extra newline at end of function.
> 

Acknowledged.

> > +
> > +static int rk817_bat_get_prop(struct power_supply *ps,
> > +		enum power_supply_property prop,
> > +		union power_supply_propval *val)
> > +{
> > +	struct rk817_charger *charger = power_supply_get_drvdata(ps);
> > +	uint32_t tmp = 0;
> > +	/* Registers for current is a signed 16bit int */
> > +	short int cur = 0;
> > +	/* Registers for capacity-now is a signed 32bit int */
> > +	int32_t charge_now = 0;
> > +	int ret = 0;
> > +	int reg = 0;
> > +	u8 bulk_reg[4];
> > +	struct rk808 *rk808 = charger->rk808;
> > +
> > +	/* Recalibrate voltage and current readings if we need to BSP does both
> > +	 * on CUR_CALIB_UPD, ignoring VOL_CALIB_UPD. Curiously enough, both
> > +	 * documentation and the BSP show that you perform an update if bit 7
> > +	 * is 1, but you clear the status by writing a 1 to bit 7.
> > +	 */
> > +	regmap_read(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1, &reg);
> > +	tmp = (reg >> 7) & 0x01;
> > +	if (tmp) {
> > +		rk817_bat_calib_cur(charger);
> > +		rk817_bat_calib_vol(charger);
> > +		regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1,
> > +				   RK817_CUR_CALIB_UPD, (1 << 7));
> > +	}
> > +
> > +	rk817_bat_calib_cap(charger);
> > +
> > +	switch (prop) {
> > +	case POWER_SUPPLY_PROP_PRESENT:
> > +		regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
> > +		val->intval = (reg >> 7);
> > +		break;
> > +	case POWER_SUPPLY_PROP_STATUS:
> > +		if (!charger->plugged_in) {
> > +			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
> > +			break;
> > +		}
> > +		ret = regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
> > +		if (ret)
> > +			return ret;
> > +		tmp = (reg >> 4) & 0x07;
> > +		switch (tmp) {
> > +		case CHRG_OFF:
> > +			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
> > +			break;
> > +		/* Dead charge is documented, but not explained. I never
> > +		 * observed it but assume it's a pre-charge for a dead
> > +		 * battery.
> > +		 */
> > +		case DEAD_CHRG:
> > +		case TRICKLE_CHRG:
> > +		case CC_OR_CV_CHRG:
> > +			val->intval = POWER_SUPPLY_STATUS_CHARGING;
> > +			break;
> > +		case CHARGE_FINISH:
> > +			val->intval = POWER_SUPPLY_STATUS_FULL;
> > +			break;
> > +		default:
> > +			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
> > +			return -EINVAL;
> > +
> > +		}
> > +		break;
> > +	case POWER_SUPPLY_PROP_CHARGE_TYPE:
> > +		ret = regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
> > +		if (ret)
> > +			return ret;
> > +		tmp = (reg >> 4) & 0x07;
> > +		switch (tmp) {
> > +		case CHRG_OFF:
> > +		case CHARGE_FINISH:
> > +			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
> > +			break;
> > +		case TRICKLE_CHRG:
> > +			val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
> > +			break;
> > +		case DEAD_CHRG:
> > +		case CC_OR_CV_CHRG:
> > +			val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
> > +			break;
> > +		default:
> > +			val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
> > +			break;
> > +		}
> > +		break;
> > +	case POWER_SUPPLY_PROP_CHARGE_FULL:
> > +		val->intval = ((charger->bat_info.charge_full_design_uah /
> > +			       1000) * charger->dsoc) / 100;
> > +		break;
> > +	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
> > +		val->intval = charger->bat_info.charge_full_design_uah;
> > +		break;
> > +	case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
> > +		val->intval = 0;
> > +		break;
> > +	case POWER_SUPPLY_PROP_CHARGE_NOW:
> > +		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
> > +				 bulk_reg, 4);
> > +		charge_now = (bulk_reg[0] << 24) | (bulk_reg[1] << 16) |
> > +			     (bulk_reg[2] << 8) | bulk_reg[3];
> 
> charge_now = get_unaligned_be32(bulk_reg);
> 

Acknowledged.

> > +		if (charge_now < 0)
> > +			charge_now = 0;
> > +		val->intval = ADC_TO_CHARGE_UAH(charge_now, charger->res_div);
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> > +		val->intval = charger->bat_info.voltage_min_design_uv;
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_BOOT:
> > +		tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_PWRON_VOL_H,
> > +				       RK817_GAS_GAUGE_PWRON_VOL_L);
> > +		val->intval = (1000 * (((charger->voltage_k * tmp) / 1000) +
> > +			       charger->voltage_b));
> 
> can be simplified to:
> 
> (charger->voltage_k * tmp) + 1000 * charger->voltage_b
> 

Acknowledged, thank you.

> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
> > +		tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_BAT_VOL_H,
> > +				       RK817_GAS_GAUGE_BAT_VOL_L);
> > +		val->intval = (1000 * (((charger->voltage_k * tmp) / 1000) +
> > +			       charger->voltage_b));
> 
> same
> 

Ack

> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_OCV:
> > +		tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_OCV_VOL_H,
> > +				       RK817_GAS_GAUGE_OCV_VOL_H);
> > +		val->intval = (1000 * (((charger->voltage_k * tmp) / 1000) +
> > +			       charger->voltage_b));
> 
> same
> 

Ack

> > +		break;
> > +	case POWER_SUPPLY_PROP_CURRENT_BOOT:
> > +		cur = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_PWRON_CUR_H,
> > +				       RK817_GAS_GAUGE_PWRON_CUR_H);
> > +		val->intval = ADC_TO_CURRENT(cur, charger->res_div);
> > +		break;
> > +	case POWER_SUPPLY_PROP_CURRENT_AVG:
> > +		cur = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_BAT_CUR_H,
> > +				       RK817_GAS_GAUGE_BAT_CUR_L);
> > +		val->intval = ADC_TO_CURRENT(cur, charger->res_div);
> > +		break;
> > +	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
> > +		regmap_read(rk808->regmap, RK817_PMIC_CHRG_OUT, &tmp);
> > +		val->intval = rk817_chg_cur_from_reg(tmp & RK817_CHRG_CUR_SEL);
> > +		break;
> > +	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
> > +		regmap_read(rk808->regmap, RK817_PMIC_CHRG_OUT, &tmp);
> > +		val->intval = ((((tmp & RK817_CHRG_VOL_SEL) >> 4) * 50000) +
> > +			       4100000);
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
> > +		val->intval = charger->bat_info.voltage_max_design_uv;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int rk817_chg_get_prop(struct power_supply *ps,
> > +			      enum power_supply_property prop,
> > +			      union power_supply_propval *val)
> > +{
> > +	struct rk817_charger *charger = power_supply_get_drvdata(ps);
> > +	int vol, tmp = 0;
> > +
> > +	switch (prop) {
> > +	case POWER_SUPPLY_PROP_ONLINE:
> > +		val->intval = charger->plugged_in;
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
> > +		/* max voltage from datasheet at 5.5v (default 5.0v) */
> > +		val->intval = 5500000;
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
> > +		/* min voltage from datasheet at 3.8v (default 5.0v) */
> > +		val->intval = 3800000;
> > +		break;
> > +	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
> > +		/* Note that on my example hardware (an Odroid Go Advance) the
> > +		 * voltage of the power connector is measured on the register
> > +		 * labelled USB in the datasheet; I don't know if this is how
> > +		 * it is designed or just a quirk of the implementation. I
> > +		 * believe this will also measure the voltage of the USB output
> > +		 * when in OTG mode, if that is the case we may need to change
> > +		 * this in the future to return 0 if the power supply status
> > +		 * is offline.
> > +		 */
> > +		tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_USB_VOL_H,
> > +				       RK817_GAS_GAUGE_USB_VOL_L);
> > +		vol = ((charger->voltage_k * tmp / 1000 + charger->voltage_b) *
> > +		       60 / 46);
> > +		val->intval = vol * 1000;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +	return 0;
> > +
> > +}
> > +
> > +static irqreturn_t rk817_plug_in_isr(int irq, void *cg)
> > +{
> > +	struct rk817_charger *charger;
> > +
> > +	charger = (struct rk817_charger *)cg;
> > +	charger->plugged_in = 1;
> > +	power_supply_changed(charger->chg_ps);
> > +	power_supply_changed(charger->bat_ps);
> > +	dev_dbg(charger->dev, "Power Cord Inserted\n");
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static irqreturn_t rk817_plug_out_isr(int irq, void *cg)
> > +{
> > +	struct rk817_charger *charger;
> > +	struct rk808 *rk808;
> > +
> > +	charger = (struct rk817_charger *)cg;
> > +	rk808 = charger->rk808;
> > +	charger->plugged_in = 0;
> > +	power_supply_changed(charger->bat_ps);
> > +	power_supply_changed(charger->chg_ps);
> > +
> > +	/* For some reason the bits of RK817_PMIC_CHRG_IN reset whenever the
> > +	 * power cord is unplugged. This was not documented in the BSP kernel
> > +	 * or the datasheet and only discovered by trial and error. Set minimum
> > +	 * USB input voltage to 4.5v and enable USB voltage input limit.
> > +	 */
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
> > +			  RK817_USB_VLIM_SEL, (0x05 << 4));
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN,
> > +			  (0x01 << 7));
> > +
> > +	/* Set average USB input current limit to 1.5A and enable USB current
> > +	 * input limit.
> > +	 */
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
> > +			  RK817_USB_ILIM_SEL, 0x03);
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN,
> > +			  (0x01 << 3));
> > +
> > +	dev_dbg(charger->dev, "Power Cord Removed\n");
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static enum power_supply_property rk817_bat_props[] = {
> > +	POWER_SUPPLY_PROP_PRESENT,
> > +	POWER_SUPPLY_PROP_STATUS,
> > +	POWER_SUPPLY_PROP_CHARGE_TYPE,
> > +	POWER_SUPPLY_PROP_CHARGE_FULL,
> > +	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
> > +	POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
> > +	POWER_SUPPLY_PROP_CHARGE_NOW,
> > +	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
> > +	POWER_SUPPLY_PROP_VOLTAGE_BOOT,
> > +	POWER_SUPPLY_PROP_VOLTAGE_AVG,
> > +	POWER_SUPPLY_PROP_VOLTAGE_OCV,
> > +	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
> > +	POWER_SUPPLY_PROP_CURRENT_BOOT,
> > +	POWER_SUPPLY_PROP_CURRENT_AVG,
> > +	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
> > +	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
> > +};
> > +
> > +static enum power_supply_property rk817_chg_props[] = {
> > +	POWER_SUPPLY_PROP_ONLINE,
> > +	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
> > +	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
> > +	POWER_SUPPLY_PROP_VOLTAGE_AVG,
> > +};
> > +
> > +static const struct power_supply_desc rk817_bat_desc = {
> > +	.name = "rk817-battery",
> > +	.type = POWER_SUPPLY_TYPE_BATTERY,
> > +	.properties = rk817_bat_props,
> > +	.num_properties = ARRAY_SIZE(rk817_bat_props),
> > +	.get_property = rk817_bat_get_prop,
> > +};
> > +
> > +/* Note that all known existing implementations use a "USB" port that is either
> > + * a power only port (no data lines) or use barrel plug to USB cable. Setting
> > + * to POWER_SUPPLY_TYPE_USB_DCP.
> > + */
> > +static const struct power_supply_desc rk817_chg_desc = {
> > +	.name = "rk817-charger",
> > +	.type = POWER_SUPPLY_TYPE_USB_DCP,
> 
> Please don't use that, it only exists for historical purposes.
> Set type to POWER_SUPPLY_TYPE_USB and report 
> POWER_SUPPLY_USB_TYPE_DCP via the USB_TYPE property.
> 

Understood, will make the change as requested.

> > +	.properties = rk817_chg_props,
> > +	.num_properties = ARRAY_SIZE(rk817_chg_props),
> > +	.get_property = rk817_chg_get_prop,
> > +};
> > +
> > +static int rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger)
> > +{
> > +	struct rk808 *rk808 = charger->rk808;
> > +	struct power_supply_battery_info *info = &charger->bat_info;
> > +	u8 reg[4];
> > +	u32 design_charge_mah = (info->charge_full_design_uah / 1000);
> > +	u32 boot_voltage, boot_charge, tmp, full_charge_cap;
> > +	int ret, boot_capacity;
> > +
> > +	/* Read DSOC value if pre-existing. If not, initialize at 100%.
> > +	 * Note endianness, also register says it's for resistance,
> > +	 * however BSP kernel treats this as an nvram field for the DSOC
> > +	 * as best I can tell. Doing the same for backwards compatibility.
> > +	 */
> > +	ret = regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_BAT_R1, reg, 3);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	charger->dsoc = (reg[2] << 16) | (reg[1] << 8) | (reg[0]);
> 
> charger->dsoc = get_unaligned_le24(reg);
> 

Ack

> > +	/* If we have an invalid DSOC, write 100 (100000) as default. */
> > +	if (charger->dsoc < 1000 || charger->dsoc > 100000) {
> > +		regmap_write(rk808->regmap, RK817_GAS_GAUGE_BAT_R1, 0xa0);
> > +		regmap_write(rk808->regmap, RK817_GAS_GAUGE_BAT_R2, 0x86);
> > +		regmap_write(rk808->regmap, RK817_GAS_GAUGE_BAT_R3, 0x01);
> > +		charger->dsoc = 100000;
> > +	}
> > +
> > +	/* Register appears to be nvram that stores capacity in mAH. Note
> > +	 * endianness, keeping consistent with BSP kernel, however it looks
> > +	 * like we can use any arbitrary method to store value if we don't care
> > +	 * about compatibility. Additionally, it doesn't appear that this value
> > +	 * is used for anything, so realistically getting it and setting it is
> > +	 * to ensure backward compatibility with BSP and serves no purpose with
> > +	 * this driver, and I'm not sure if the BSP driver does anything with
> > +	 * this value either.
> > +	 */
> > +
> > +	ret = regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_DATA3, reg, 3);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	full_charge_cap = (reg[2] << 16) | (reg[1] << 8) | (reg[0]);
> 
> full_charge_cap = get_unaligned_le24(reg);
> 

Ack

> > +
> > +	/* Sanity checking for values equal to zero or less than would be
> > +	 * practical for this device (BSP Kernel assumes 500mAH or less) for
> > +	 * practicality purposes.
> > +	 */
> > +	if (full_charge_cap < 500) {
> > +		reg[2] = (design_charge_mah >> 16) & 0xff;
> > +		reg[1] = (design_charge_mah >> 8) & 0xff;
> > +		reg[0] = design_charge_mah & 0xff;
> > +		ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_DATA3, reg, 3);
> > +		if (ret < 0)
> > +			return ret;
> > +		dev_info(charger->dev,
> > +			 "Invalid NVRAM Data for max charge, setting to design capacity %u uAH\n",
> > +			 design_charge_mah*1000);
> > +	}
> > +
> > +	/* Capture boot voltage and look up boot capacity from OCV tables. */
> > +
> > +	tmp = rk817_get_reg_hl(charger, RK817_GAS_GAUGE_PWRON_VOL_H,
> > +			       RK817_GAS_GAUGE_PWRON_VOL_L);
> > +	boot_voltage = (1000 * (((charger->voltage_k * tmp) / 1000) +
> > +			charger->voltage_b));
> > +	/* Since only implementation has no working thermistor, assume 20C for
> > +	 * OCV lookup. If lookup fails, report error with OCV table.
> > +	 */
> > +	boot_capacity = power_supply_batinfo_ocv2cap(info, boot_voltage, 20);
> > +	if (boot_capacity < 0) {
> > +		dev_err(charger->dev,
> > +			"Unable to read boot charge from OCV table: %i\n",
> > +			boot_capacity);
> > +		return boot_capacity;
> > +	}
> > +
> > +	/* Write boot charge to registers, estimate boot charge based on
> > +	 * capacity and max charge of battery.
> > +	 */
> > +	boot_charge = (boot_capacity * info->charge_full_design_uah) / 100;
> > +	tmp = CHARGE_TO_ADC((boot_charge / 1000), charger->res_div);
> > +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3,
> > +		     (tmp >> 24) & 0xFF);
> > +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H2,
> > +		     (tmp >> 16) & 0xFF);
> > +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_L1,
> > +		     (tmp >> 8) & 0xFF);
> > +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_L0,
> > +		     tmp & 0xFF);
> 
> regmap_bulk_write?
> 

Probably, will change.

> > +
> > +	/* Set QMAX value to max design capacity. */
> > +	tmp = CHARGE_TO_ADC((info->charge_full_design_uah / 1000),
> > +			    charger->res_div);
> > +	reg[0] = (tmp >> 24) & 0xff;
> > +	reg[1] = (tmp >> 16) & 0xff;
> > +	reg[2] = (tmp >> 8) & 0xff;
> > +	reg[3] = tmp & 0xff;
> 
> use put_unaligned_* API
> 

Ack.

> > +	ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_MAX_H3,
> > +				reg, 4);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	return 0;
> > +
> > +}
> > +
> > +static int rk817_battery_init(struct rk817_charger *charger)
> > +{
> > +	struct rk808 *rk808 = charger->rk808;
> > +	struct power_supply_battery_info *info = &charger->bat_info;
> > +	u32 tmp, max_chg_vol_mv, max_chg_cur_ma;
> > +	u8 max_chg_vol_reg, chg_term_i_reg, max_chg_cur_reg;
> > +	int ret, chg_term_ma;
> > +
> > +	/* Get initial plug state */
> > +	regmap_read(rk808->regmap, RK817_SYS_STS, &tmp);
> > +	charger->plugged_in = (tmp & RK817_PLUG_IN_STS);
> > +
> > +	/* Turn on all ADC functions to measure battery, USB, and sys voltage,
> > +	 * as well as batt temp. Note only tested implementation so far does
> > +	 * not use a battery with a thermistor.
> > +	 */
> > +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG0, 0xfc);
> > +
> > +	/* Set relax mode voltage sampling interval and ADC offset calibration
> > +	 * interval to 8 minutes to mirror BSP kernel. Set voltage and current
> > +	 * modes to average to mirror BSP kernel.
> > +	 */
> > +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_GG_CON, 0x04);
> > +
> > +	/* Write relax threshold, derived from sleep enter current. */
> > +	tmp = CURRENT_TO_ADC(charger->sleep_enter_current, charger->res_div);
> > +	rk817_write_reg_hl(charger, RK817_GAS_GAUGE_RELAX_THRE_H,
> > +			   RK817_GAS_GAUGE_RELAX_THRE_L, tmp);
> > +
> > +	/* Write sleep sample current, derived from sleep filter current. */
> > +	tmp = CURRENT_TO_ADC(charger->sleep_filter_current, charger->res_div);
> > +	rk817_write_reg_hl(charger, RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H,
> > +			   RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_L, tmp);
> > +
> > +	/* Restart battery relax voltage */
> > +	regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_GG_STS,
> > +			  RK817_RELAX_VOL_UPD, (0x0 << 2));
> > +
> > +	/* Set OCV Threshold Voltage to 127.5mV. This was hard coded like this
> > +	 * in the BSP.
> > +	 */
> > +	regmap_write(rk808->regmap, RK817_GAS_GAUGE_OCV_THRE_VOL, 0xff);
> > +
> > +	/* Set maximum charging voltage to battery max voltage. Trying to be
> > +	 * incredibly safe with these value, as setting them wrong could
> > +	 * overcharge the battery, which would be very bad.
> > +	 */
> > +	max_chg_vol_mv = info->constant_charge_voltage_max_uv / 1000;
> > +	max_chg_cur_ma = info->constant_charge_current_max_ua / 1000;
> > +
> > +	if (max_chg_vol_mv < 4100) {
> > +		dev_emerg(charger->dev,
> > +			  "Danger, invalid max charger voltage! Value %u unsupported\n",
> > +			  max_chg_vol_mv * 1000);
> > +		return -EINVAL;
> 
> 
> return dev_err_probe(charger->dev, -EINVAL, "invalid max charger voltage ...",
>                      max_chg_vol_mv * 1000);
> 

Ack.

> > +	}
> > +	if (max_chg_vol_mv > 4450) {
> > +		dev_info(charger->dev,
> > +			 "Setting max charge voltage to 4450000uv\n");
> > +		max_chg_vol_mv = 4450;
> > +	}
> > +
> > +	if (max_chg_cur_ma < 500) {
> > +		dev_emerg(charger->dev,
> > +			  "Danger, invalid max charger current! Value %u unsupported\n",
> > +			  max_chg_cur_ma * 1000);
> 
> return dev_err_probe(...);
> 

Ack.

> > +		return -EINVAL;
> > +	}
> > +	if (max_chg_cur_ma > 3500)
> > +		dev_info(charger->dev,
> > +			 "Setting max charge current to 3500000ua\n");
> > +
> > +	/* Now that the values are sanity checked, if we subtract 4100 from the
> > +	 * max voltage and divide by 50, we conviently get the exact value for
> > +	 * the registers, which are 4.1v, 4.15v, 4.2v, 4.25v, 4.3v, 4.35v,
> > +	 * 4.4v, and 4.45v; these correspond to values 0x00 through 0x07.
> > +	 */
> > +	max_chg_vol_reg = (max_chg_vol_mv - 4100) / 50;
> > +
> > +	max_chg_cur_reg = rk817_chg_cur_to_reg(max_chg_cur_ma);
> > +
> > +	if (max_chg_vol_reg < 0 || max_chg_vol_reg > 7) {
> > +		dev_emerg(charger->dev,
> > +			  "Danger, invalid max charger voltage! Value %u unsupported\n",
> > +			  max_chg_vol_mv * 1000);
> > +		return -EINVAL;
> > +	}
> 
> return dev_err_probe(...);
> 

Ack.

> > +	if (max_chg_cur_reg < 0 || max_chg_cur_reg > 7) {
> > +		dev_emerg(charger->dev,
> > +			  "Danger, invalid max charger voltage! Value %u unsupported\n",
> > +			  max_chg_cur_ma * 1000);
> > +		return -EINVAL;
> > +	}
> 
> return dev_err_probe(...);
> 

Ack.

> > +
> > +	/* Write the values to the registers, and deliver an emergency warning
> > +	 * in the event they are not written correctly.
> > +	 */
> > +	ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT,
> > +				RK817_CHRG_VOL_SEL, (max_chg_vol_reg << 4));
> > +	if (ret) {
> > +		dev_emerg(charger->dev,
> > +			  "Danger, unable to set max charger voltage: %u\n",
> > +			  ret);
> > +	}
> > +
> > +	ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT,
> > +				RK817_CHRG_CUR_SEL, max_chg_cur_reg);
> > +	if (ret) {
> > +		dev_emerg(charger->dev,
> > +			  "Danger, unable to set max charger current: %u\n",
> > +			  ret);
> > +	}
> > +
> > +	/* Set charge finishing mode to analog */
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM,
> > +			  RK817_CHRG_TERM_ANA_DIG, (0x0 << 2));
> > +
> > +	/* Set charge finish current, warn if value not in range and keep
> > +	 * default.
> > +	 */
> > +	chg_term_ma = info->charge_term_current_ua / 1000;
> > +	if (chg_term_ma < 150 || chg_term_ma > 400) {
> > +		dev_warn(charger->dev,
> > +			 "Invalid charge termination value %u, keeping default\n",
> > +			 chg_term_ma * 1000);
> > +		chg_term_ma = 200;
> > +	}
> > +
> > +	/* Values of 150ma, 200ma, 300ma, and 400ma correspond to 00, 01, 10,
> > +	 * and 11.
> > +	 */
> > +	chg_term_i_reg = (chg_term_ma - 100) / 100;
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM,
> > +			  RK817_CHRG_TERM_ANA_SEL, chg_term_i_reg);
> > +
> > +	ret = rk817_read_or_set_full_charge_on_boot(charger);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	/* Set minimum USB input voltage to 4.5v and enable USB voltage input
> > +	 * limit.
> > +	 */
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
> > +			  RK817_USB_VLIM_SEL, (0x05 << 4));
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN,
> > +			  (0x01 << 7));
> > +
> > +	/* Set average USB input current limit to 1.5A and enable USB current
> > +	 * input limit.
> > +	 */
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
> > +			  RK817_USB_ILIM_SEL, 0x03);
> > +	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN,
> > +			  (0x01 << 3));
> > +
> > +	return 0;
> > +
> 
> another useless empty line
> 

Sorry, will remove.

> > +}
> > +
> > +static int rk817_charger_probe(struct platform_device *pdev)
> > +{
> > +	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
> > +	struct rk817_charger *charger;
> > +	struct device_node *node;
> > +	struct power_supply_battery_info *info;
> > +	struct device *dev = &pdev->dev;
> > +	struct power_supply_config pscfg = {};
> > +	int plugin_irq, plugout_irq;
> > +	int of_value;
> > +	int ret;
> > +
> > +	node = of_get_child_by_name(dev->parent->of_node, "battery");
> > +	if (!node)
> > +		return -ENODEV;
> > +
> > +	charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
> > +	if (!charger)
> > +		return -ENOMEM;
> > +
> > +	charger->rk808 = rk808;
> > +
> > +	charger->dev = &pdev->dev;
> > +	platform_set_drvdata(pdev, charger);
> > +
> > +	rk817_bat_calib_vol(charger);
> > +
> > +	pscfg.drv_data = charger;
> > +	pscfg.of_node = node;
> > +
> > +	/* Get sample resistor value. Note only values of 10000 or 20000
> > +	 * microohms are allowed. Schematic for my test implementation (an
> > +	 * Odroid Go Advance) shows a 10 milliohm resistor for reference.
> > +	 */
> > +	ret = of_property_read_u32(node, "rockchip,resistor-sense", &of_value);
> 
> not using correct property unit:
> 
> https://github.com/devicetree-org/dt-schema/blob/master/schemas/property-units.yaml
> 

Understood, will add property units. I was under the impression that
micro units were always implied, but there's no harm in being explicit.

> > +	if (ret < 0) {
> > +		dev_err(dev, "Error reading sample resistor value: %i\n", ret);
> > +		return ret;
> 
> return dev_err_probe(...);

Ack.

> 
> > +	}
> > +	/* Store as a 1 or a 2, since all we really use the value for is as a
> > +	 * divisor in some calculations.
> > +	 */
> > +	charger->res_div = (of_value == 20000) ? 2 : 1;
> > +
> > +	/* Get sleep enter current value. Not sure what this value is for
> > +	 * other than to help calibrate the relax threshold.
> > +	 */
> > +	ret = of_property_read_u32(node, "rockchip,sleep-enter-current",
> > +				   &of_value);
> 
> not using correct property unit:
> 
> https://github.com/devicetree-org/dt-schema/blob/master/schemas/property-units.yaml
> 

Ack.

> > +	if (ret < 0) {
> > +		dev_err(dev, "Error reading sleep enter current value: %i\n",
> > +			ret);
> > +		return ret;
> 
> return dev_err_probe(...);
> 

Ack.

> > +	}
> > +	charger->sleep_enter_current = of_value;
> > +
> > +	/* Get sleep filter current value */
> > +	ret = of_property_read_u32(node, "rockchip,sleep-filter-current",
> > +				   &of_value);
> 
> not using correct property unit:
> 
> https://github.com/devicetree-org/dt-schema/blob/master/schemas/property-units.yaml
> 

Ack.

> > +	if (ret < 0) {
> > +		dev_err(dev, "Error reading sleep filter current value: %i\n",
> > +			ret);
> > +		return ret;
> 
> return dev_err_probe(...);
> 

Ack.

> > +	}
> > +	charger->sleep_filter_current = of_value;
> > +
> > +	charger->bat_ps = devm_power_supply_register(&pdev->dev,
> > +						     &rk817_bat_desc, &pscfg);
> > +
> > +	charger->chg_ps = devm_power_supply_register(&pdev->dev,
> > +						     &rk817_chg_desc, &pscfg);
> > +
> > +	ret = power_supply_get_battery_info(charger->bat_ps,
> > +					    &charger->bat_info);
> 
> You need to call power_supply_put_battery_info for the battery
> info object once you no longer need it. I suppose in this case
> it makes sense to do it via devm_add_action_or_reset().
> 

When would I no longer need it, when I unregister the device?

> > +	if (ret) {
> > +		dev_err(dev, "Unable to get battery info: %d\n", ret);
> > +		return ret;
> 
> return dev_err_probe(...);

Ack.

> 
> > +	}
> > +
> > +	info = &charger->bat_info;
> > +	if ((!info->charge_full_design_uah) ||
> > +	    (!info->voltage_min_design_uv) ||
> > +	    (!info->voltage_max_design_uv) ||
> > +	    (!info->constant_charge_voltage_max_uv) ||
> > +	    (!info->constant_charge_current_max_ua) ||
> > +	    (!info->charge_term_current_ua)) {
> > +		dev_err(dev, "Required battery information missing.\n");
> > +		return -EINVAL;
> 
> return dev_err_probe(...);
> 

Ack.

> > +	}
> > +
> > +	/* Has to run after power_supply_get_battery_info as it depends on some
> > +	 * values discovered from that routine.
> > +	 */
> > +	ret = rk817_battery_init(charger);
> > +	if (ret)
> > +		return ret;
> > +
> > +	plugin_irq = platform_get_irq(pdev, 0);
> > +	if (plugin_irq < 0)
> > +		return plugin_irq;
> > +
> > +	plugout_irq = platform_get_irq(pdev, 1);
> > +	if (plugout_irq < 0)
> > +		return plugout_irq;
> > +
> > +	ret = devm_request_threaded_irq(charger->dev, plugin_irq, NULL,
> > +					rk817_plug_in_isr,
> > +					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> > +					"rk817_plug_in", charger);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "plug_in_irq request failed!\n");
> > +		return ret;
> 
> return dev_err_probe(...);
> 

Ack.

> > +	}
> > +
> > +	ret = devm_request_threaded_irq(charger->dev, plugout_irq, NULL,
> > +					rk817_plug_out_isr,
> > +					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> > +					"rk817_plug_out", charger);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "plug_out_irq request failed!\n");
> > +		return ret;
> 
> return dev_err_probe(...);
> 

Ack.

> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +
> > +static struct platform_driver rk817_charger_driver = {
> > +	.probe    = rk817_charger_probe,
> > +	.driver   = {
> > +		.name  = "rk817-charger",
> > +	},
> > +};
> > +module_platform_driver(rk817_charger_driver);
> > +
> > +MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC");
> > +MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc at gmail.com>");
> > +MODULE_LICENSE("GPL");
> 
> -- Sebastian

Thank you for your feedback, I will make the requested changes and
resubmit upstream. Do you have any other thoughts, pointers, or advice
in regards to this driver? It's my first battery driver and I want to
make sure it works well for all users. The main concern I still have
is I noticed the columb counter seems to drift upwards over time if
the device stays plugged in and powered on for a very long time. Over
the course of one week I noticed my device is sitting at a 103% charge
according to the counter (if I go off the voltage it's still at roughly
100%). Should I always check if the columb counter exceeds the max
capacity and re-init it at max capacity if it exceeds the value?

Again, I appreciate the feedback, it's very helpful.

- Chris & Maya


From frank.li at nxp.com  Mon Aug  9 07:46:55 2021
From: frank.li at nxp.com (Frank Li)
Date: Mon, 9 Aug 2021 14:46:55 +0000
Subject: [EXT] Re: The problem about arm64: io: Relax implicit barriers in
 default I/O accessors
In-Reply-To: <20210809135041.GC1207@willie-the-truck>
References: <20210621162641.GA29595@willie-the-truck>
 <20210621165941.GB29595@willie-the-truck>
 <AS8PR04MB85000A5E88F7CDDAB9105821880A9@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210621181326.GD29713@willie-the-truck>
 <AS8PR04MB85006677E34CD6CC2C132FA2880A9@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210622091140.GA30677@willie-the-truck>
 <AS8PR04MB85002F0B0C99E7B4F1D27D3D88089@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210706171106.GE20750@willie-the-truck>
 <AS8PR04MB8500635E829B332A61AC85C988129@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <AS8PR04MB850048A35E12270B42448B4C88E49@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210809135041.GC1207@willie-the-truck>
Message-ID: <AS8PR04MB85001637B4DAE19BB51FA54588F69@AS8PR04MB8500.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Will Deacon <will at kernel.org>
> Sent: Monday, August 9, 2021 8:51 AM
> To: Frank Li <frank.li at nxp.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>; Zhi Li <lznuaa at gmail.com>;
> Shenwei Wang <shenwei.wang at nxp.com>; Han Xu <han.xu at nxp.com>; Nitin Garg
> <nitin.garg at nxp.com>; Jason Liu <jason.hui.liu at nxp.com>; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [EXT] Re: The problem about arm64: io: Relax implicit barriers
> in default I/O accessors
> 
> Caution: EXT Email
> 
> On Thu, Jul 22, 2021 at 07:14:19PM +0000, Frank Li wrote:
> > > > On Wed, Jun 23, 2021 at 03:48:10PM +0000, Frank Li wrote:
> > > > > > I think you had a support case open with Arm [1] which I'm not
> able
> > > to
> > > > > > access -- please can you ask them about the two examples above?
> > > > >
> > > > > Still not get feedback from ARM.
> > > >
> > > > Just wondering if you were able to solve this without the need to
> change
> > > > Linux?
> > >
> > > Sorry for late reply
> > >
> > > For CCI-500 and 550, ARM removed support for barrier transactions but
> CCI-
> > > 400 supports barrier transactions. With CCI-400 it is a valid
> configuration
> > > to have SYSBARDISABLE LOW in Cortex-A processors. This change in Linux
> > > kernel is assuming that the SYSBARDISABLE is set to HIGH hence its not
> > > correct change for all products having various versions of ARM CCI IP.
> > >
> > > Frank Li
> >
> > Deacon:
> >
> >       Did you plan fix this problem by changing dma_wmb()?
> 
> No. As far as I understand this problem, you're driving SYSBARDISABLE
> 'low' yet you have your own bus fabric downstream of the CCI which doesn't
> respect barrier transactions. Even if we bodge dma_wmb(), store-release to
> non-cacheable memory cannot be made to work on your system as you're
> effectively putting some of your non-coherent DMA devices into a separate
> outer-shareable domain from the CPUs.

Does it means the Linux expect all DMA devices in outer-shareable domain instead
of system shared domain?  

Frank

> 
> So you have two options:
> 
>   1. Drive SYSBARDISABLE 'high' so that the CPU handles ordering for you
> 
> - or -
> 
>   2. Quirk Linux so that we patch dma_wmb() when we detect your system at
>      runtime (so we can extend this in future if we need to emit a
> different
>      sequence for store release)
> 
> (1) is definitely the easiest option if it's possible.
> 
> Will


From robin.murphy at arm.com  Mon Aug  9 07:47:32 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 9 Aug 2021 15:47:32 +0100
Subject: [PATCH v3 24/25] iommu/dma: Factor out flush queue init
In-Reply-To: <20210809125238.GB1097@willie-the-truck>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <3b5284ee394f267ba966839173f874fc9a996bb2.1628094601.git.robin.murphy@arm.com>
 <20210809125238.GB1097@willie-the-truck>
Message-ID: <4c6ecfb1-cf64-fa35-9fa7-f6fa39e2c066@arm.com>

On 2021-08-09 13:52, Will Deacon wrote:
> On Wed, Aug 04, 2021 at 06:15:52PM +0100, Robin Murphy wrote:
>> Factor out flush queue setup from the initial domain init so that we
>> can potentially trigger it from sysfs later on in a domain's lifetime.
>>
>> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
>> Reviewed-by: John Garry <john.garry at huawei.com>
>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
>> ---
>>   drivers/iommu/dma-iommu.c | 30 ++++++++++++++++++++----------
>>   include/linux/dma-iommu.h |  9 ++++++---
>>   2 files changed, 26 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
>> index 2e19505dddf9..f51b8dc99ac6 100644
>> --- a/drivers/iommu/dma-iommu.c
>> +++ b/drivers/iommu/dma-iommu.c
>> @@ -310,6 +310,25 @@ static bool dev_is_untrusted(struct device *dev)
>>   	return dev_is_pci(dev) && to_pci_dev(dev)->untrusted;
>>   }
>>   
>> +int iommu_dma_init_fq(struct iommu_domain *domain)
>> +{
>> +	struct iommu_dma_cookie *cookie = domain->iova_cookie;
>> +
>> +	if (domain->type != IOMMU_DOMAIN_DMA_FQ)
>> +		return -EINVAL;
>> +	if (cookie->fq_domain)
>> +		return 0;
>> +
>> +	if (init_iova_flush_queue(&cookie->iovad, iommu_dma_flush_iotlb_all,
>> +				  iommu_dma_entry_dtor)) {
>> +		pr_warn("iova flush queue initialization failed\n");
>> +		domain->type = IOMMU_DOMAIN_DMA;
>> +		return -ENODEV;
> 
> I do find this a bit odd: we assert that the caller has set domain->type
> to IOMMU_DOMAIN_DMA_FQ but then on failure we reset it to IOMMU_DOMAIN_DMA
> here. I think it would be less error-prone if the setting of domain->type
> was handled in the same function.

On reflection I think I agree. For some reason I settled on the idea of 
doing this to make the callers simpler, but it turns out that unpicking 
it to flow logically is in fact a +4/-5 diff essentially just moving all 
the same statements to different places, and that's before I update 
comments since that theoretical race between the sysfs and DMA ops paths 
only exists because of sysfs having to dance around the type check here...

I'll send v4 later today or possibly tomorrow, but not in such a hurry 
that I skimp on the build-testing this time!

Cheers,
Robin.


From sean.anderson at seco.com  Mon Aug  9 07:48:40 2021
From: sean.anderson at seco.com (Sean Anderson)
Date: Mon, 9 Aug 2021 10:48:40 -0400
Subject: [PATCH v5 3/3] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <20210719221322.3723009-3-sean.anderson@seco.com>
References: <20210719221322.3723009-1-sean.anderson@seco.com>
 <20210719221322.3723009-3-sean.anderson@seco.com>
Message-ID: <cf3cfa4c-a519-1413-1e7b-649b07de844a@seco.com>

ping?

On 7/19/21 6:13 PM, Sean Anderson wrote:
> This adds PWM support for Xilinx LogiCORE IP AXI soft timers commonly
> found on Xilinx FPGAs. At the moment clock control is very basic: we
> just enable the clock during probe and pin the frequency. In the future,
> someone could add support for disabling the clock when not in use.
> 
> This driver was written with reference to Xilinx DS764 for v1.03.a [1].
> 
> [1] https://www.xilinx.com/support/documentation/ip_documentation/axi_timer/v1_03_a/axi_timer_ds764.pdf
> 
> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
> ---
> Uwe, I know we haven't finished our discussion on the previous series
> wrt what checks/rounding apply_state should do, but I want to get some
> feedback on the other changes I've made to this series in the meantime.
> 
> Changes in v5:
> - Elaborate on limitation section
> - Rework duty-cycle and period calculations with feedback from Uwe
> - Use more verbose error messages
> - Allow non-zero #pwm-cells
> - Remove xlnx,axi-timer-2.0 compatible string
> - Correctly set duty_cycle in get_state when TLR0=TLR1
> - Perform some additional checks/rounding in apply_state
> - Switch to regmap to abstract endianness issues
> 
> Changes in v4:
> - Remove references to properties which are not good enough for Linux.
> - Don't use volatile in read/write replacements. Some arches have it and
>    some don't.
> - Put common timer properties into their own struct to better reuse
>    code.
> 
> Changes in v3:
> - Add clockevent and clocksource support
> - Rewrite probe to only use a device_node, since timers may need to be
>    initialized before we have proper devices. This does bloat the code a bit
>    since we can no longer rely on helpers such as dev_err_probe. We also
>    cannot rely on device resources being free'd on failure, so we must free
>    them manually.
> - We now access registers through xilinx_timer_(read|write). This allows us
>    to deal with endianness issues, as originally seen in the microblaze
>    driver. CAVEAT EMPTOR: I have not tested this on big-endian!
> - Remove old microblaze driver
> 
> Changes in v2:
> - Don't compile this module by default for arm64
> - Add dependencies on COMMON_CLK and HAS_IOMEM
> - Add comment explaining why we depend on !MICROBLAZE
> - Add comment describing device
> - Rename TCSR_(SET|CLEAR) to TCSR_RUN_(SET|CLEAR)
> - Use NSEC_TO_SEC instead of defining our own
> - Use TCSR_RUN_MASK to check if the PWM is enabled, as suggested by Uwe
> - Cast dividends to u64 to avoid overflow
> - Check for over- and underflow when calculating TLR
> - Set xilinx_pwm_ops.owner
> - Don't set pwmchip.base to -1
> - Check range of xlnx,count-width
> - Ensure the clock is always running when the pwm is registered
> - Remove debugfs file :l
> - Report errors with dev_error_probe
> 
>   MAINTAINERS                  |   1 +
>   drivers/clocksource/Makefile |   5 +-
>   drivers/pwm/Kconfig          |  13 ++
>   drivers/pwm/Makefile         |   1 +
>   drivers/pwm/pwm-xilinx.c     | 268 +++++++++++++++++++++++++++++++++++
>   5 files changed, 287 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/pwm/pwm-xilinx.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 252d71addd18..6adafd3e7a09 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20050,6 +20050,7 @@ XILINX TIMER/PWM DRIVER
>   M:	Sean Anderson <sean.anderson at seco.com>
>   S:	Maintained
>   F:	drivers/clocksource/timer-xilinx*
> +F:	drivers/pwm/pwm-xilinx.c
>   F:	include/clocksource/timer-xilinx.h
>   
>   XILINX UARTLITE SERIAL DRIVER
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index a7cba6ef5782..dcf434fdb726 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -88,4 +88,7 @@ obj-$(CONFIG_CSKY_MP_TIMER)		+= timer-mp-csky.o
>   obj-$(CONFIG_GX6605S_TIMER)		+= timer-gx6605s.o
>   obj-$(CONFIG_HYPERV_TIMER)		+= hyperv_timer.o
>   obj-$(CONFIG_MICROCHIP_PIT64B)		+= timer-microchip-pit64b.o
> -obj-$(CONFIG_XILINX_TIMER)		+= timer-xilinx.o timer-xilinx-common.o
> +obj-$(CONFIG_XILINX_TIMER)		+= timer-xilinx.o
> +ifneq ($(CONFIG_XILINX_TIMER$)(CONFIG_PWM_XILINX),)
> +obj-y					+= timer-xilinx-common.o
> +endif
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index c76adedd58c9..974774b7c987 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -637,4 +637,17 @@ config PWM_VT8500
>   	  To compile this driver as a module, choose M here: the module
>   	  will be called pwm-vt8500.
>   
> +config PWM_XILINX
> +	tristate "Xilinx AXI Timer PWM support"
> +	depends on COMMON_CLK
> +	select REGMAP_MMIO
> +	help
> +	  PWM driver for Xilinx LogiCORE IP AXI timers. This timer is
> +	  typically a soft core which may be present in Xilinx FPGAs.
> +	  This device may also be present in Microblaze soft processors.
> +	  If you don't have this IP in your design, choose N.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-xilinx.
> +
>   endif
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 708840b7fba8..ea785480359b 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -60,3 +60,4 @@ obj-$(CONFIG_PWM_TWL)		+= pwm-twl.o
>   obj-$(CONFIG_PWM_TWL_LED)	+= pwm-twl-led.o
>   obj-$(CONFIG_PWM_VISCONTI)	+= pwm-visconti.o
>   obj-$(CONFIG_PWM_VT8500)	+= pwm-vt8500.o
> +obj-$(CONFIG_PWM_XILINX)	+= pwm-xilinx.o
> diff --git a/drivers/pwm/pwm-xilinx.c b/drivers/pwm/pwm-xilinx.c
> new file mode 100644
> index 000000000000..291577be992f
> --- /dev/null
> +++ b/drivers/pwm/pwm-xilinx.c
> @@ -0,0 +1,268 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021 Sean Anderson <sean.anderson at seco.com>
> + *
> + * Limitations:
> + * - When changing both duty cycle and period, we may end up with one cycle
> + *   with the old duty cycle and the new period. This is because the counters
> + *   may only be reloaded by first stopping them, or by letting them be
> + *   automatically reloaded at the end of a cycle. If this automatic reload
> + *   happens after we set TLR0 but before we set TLR1 then we will will have a
> + *   bad cycle. This could probably be fixed by reading TCR0 just before
> + *   reprogramming, but I think it would add complexity for little gain.
> + * - Cannot produce 100% duty cycle by configuring the TLRs. This might be
> + *   possible by stopping the counters at an appropriate point in the cycle,
> + *   but this is not (yet) implemented.
> + * - Only produces "normal" output.
> + * - Always produces low output if disabled.
> + */
> +
> +#include <clocksource/timer-xilinx.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/regmap.h>
> +
> +/*
> + * The idea here is to capture whether the PWM is actually running (e.g.
> + * because we or the bootloader set it up) and we need to be careful to ensure
> + * we don't cause a glitch. According to the data sheet, to enable the PWM we
> + * need to
> + *
> + * - Set both timers to generate mode (MDT=1)
> + * - Set both timers to PWM mode (PWMA=1)
> + * - Enable the generate out signals (GENT=1)
> + *
> + * In addition,
> + *
> + * - The timer must be running (ENT=1)
> + * - The timer must auto-reload TLR into TCR (ARHT=1)
> + * - We must not be in the process of loading TLR into TCR (LOAD=0)
> + * - Cascade mode must be disabled (CASC=0)
> + *
> + * If any of these differ from usual, then the PWM is either disabled, or is
> + * running in a mode that this driver does not support.
> + */
> +#define TCSR_PWM_SET (TCSR_GENT | TCSR_ARHT | TCSR_ENT | TCSR_PWMA)
> +#define TCSR_PWM_CLEAR (TCSR_MDT | TCSR_LOAD)
> +#define TCSR_PWM_MASK (TCSR_PWM_SET | TCSR_PWM_CLEAR)
> +
> +struct xilinx_pwm_device {
> +	struct pwm_chip chip;
> +	struct xilinx_timer_priv priv;
> +};
> +
> +static inline struct xilinx_timer_priv
> +*xilinx_pwm_chip_to_priv(struct pwm_chip *chip)
> +{
> +	return &container_of(chip, struct xilinx_pwm_device, chip)->priv;
> +}
> +
> +static bool xilinx_timer_pwm_enabled(u32 tcsr0, u32 tcsr1)
> +{
> +	return ((TCSR_PWM_MASK | TCSR_CASC) & tcsr0) == TCSR_PWM_SET &&
> +		(TCSR_PWM_MASK & tcsr1) == TCSR_PWM_SET;
> +}
> +
> +static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
> +			    const struct pwm_state *state)
> +{
> +	bool enabled;
> +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
> +	u32 tlr0, tlr1, tcsr0, tcsr1;
> +	u64 period_cycles, duty_cycles;
> +	unsigned long rate;
> +
> +	if (state->polarity != PWM_POLARITY_NORMAL)
> +		return -EINVAL;
> +
> +	/*
> +	 * To be representable by TLR, cycles must be between 2 and
> +	 * priv->max + 2. To enforce this we can reduce the duty
> +	 * cycle, but we may not increase it.
> +	 */
> +	rate = clk_get_rate(priv->clk);
> +	period_cycles = mul_u64_u32_div(state->period, rate, NSEC_PER_SEC);
> +	if (period_cycles - 2 > priv->max || period_cycles < 2)
> +		return -ERANGE;
> +	duty_cycles = mul_u64_u32_div(state->duty_cycle, rate, NSEC_PER_SEC);
> +
> +	/*
> +	 * If we specify 100% duty cycle, we will get 0% instead, so decrease
> +	 * the duty cycle count by one.
> +	 */
> +	if (period_cycles == duty_cycles)
> +		duty_cycles--;
> +
> +	/* Round down to 0% duty cycle for unrepresentable duty cycles */
> +	if (duty_cycles < 2)
> +		duty_cycles = period_cycles;
> +
> +	regmap_read(priv->map, TCSR0, &tcsr0);
> +	regmap_read(priv->map, TCSR1, &tcsr1);
> +	tlr0 = xilinx_timer_tlr_cycles(priv, tcsr0, period_cycles);
> +	tlr1 = xilinx_timer_tlr_cycles(priv, tcsr1, duty_cycles);
> +	regmap_write(priv->map, TLR0, tlr0);
> +	regmap_write(priv->map, TLR1, tlr1);
> +
> +	enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1);
> +	if (state->enabled) {
> +		/*
> +		 * If the PWM is already running, then the counters will be
> +		 * reloaded at the end of the current cycle.
> +		 */
> +		if (!enabled) {
> +			/* Load TLR into TCR */
> +			regmap_write(priv->map, TCSR0, tcsr0 | TCSR_LOAD);
> +			regmap_write(priv->map, TCSR1, tcsr1 | TCSR_LOAD);
> +			/* Enable timers all at once with ENALL */
> +			tcsr0 = (TCSR_PWM_SET & ~TCSR_ENT) | (tcsr0 & TCSR_UDT);
> +			tcsr1 = TCSR_PWM_SET | TCSR_ENALL | (tcsr1 & TCSR_UDT);
> +			regmap_write(priv->map, TCSR0, tcsr0);
> +			regmap_write(priv->map, TCSR1, tcsr1);
> +		}
> +	} else {
> +		regmap_write(priv->map, TCSR0, 0);
> +		regmap_write(priv->map, TCSR1, 0);
> +	}
> +
> +	return 0;
> +}
> +
> +static void xilinx_pwm_get_state(struct pwm_chip *chip,
> +				 struct pwm_device *unused,
> +				 struct pwm_state *state)
> +{
> +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
> +	u32 tlr0, tlr1, tcsr0, tcsr1;
> +
> +	regmap_read(priv->map, TLR0, &tlr0);
> +	regmap_read(priv->map, TLR1, &tlr1);
> +	regmap_read(priv->map, TCSR0, &tcsr0);
> +	regmap_read(priv->map, TCSR1, &tcsr1);
> +	state->period = xilinx_timer_get_period(priv, tlr0, tcsr0);
> +	state->duty_cycle = xilinx_timer_get_period(priv, tlr1, tcsr1);
> +	state->enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1);
> +	state->polarity = PWM_POLARITY_NORMAL;
> +
> +	/* 100% duty cycle results in constant low output */
> +	if (state->period == state->duty_cycle)
> +		state->duty_cycle = 0;
> +}
> +
> +static const struct pwm_ops xilinx_pwm_ops = {
> +	.apply = xilinx_pwm_apply,
> +	.get_state = xilinx_pwm_get_state,
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct regmap_config xilinx_pwm_regmap_config = {
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.val_bits = 32,
> +	.val_format_endian = REGMAP_ENDIAN_LITTLE,
> +	.max_register = TCR1,
> +	.disable_locking = true, /* The PWM subsystem handles locking */
> +};
> +
> +static int xilinx_timer_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct xilinx_timer_priv *priv;
> +	struct xilinx_pwm_device *pwm;
> +	u32 pwm_cells, one_timer;
> +	void __iomem *regs;
> +
> +	ret = of_property_read_u32(np, "#pwm-cells", &pwm_cells);
> +	if (ret == -EINVAL)
> +		return -ENODEV;
> +	else if (ret)
> +		return dev_err_probe(dev, ret, "could not read #pwm-cells\n");
> +
> +	pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
> +	if (!pwm)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, pwm);
> +	priv = &pwm->priv;
> +
> +	regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> +
> +	priv->map = devm_regmap_init_mmio(dev, regs,
> +					  &xilinx_pwm_regmap_config);
> +	if (IS_ERR(priv->map))
> +		return dev_err_probe(dev, PTR_ERR(priv->map),
> +				     "could not create regmap\n");
> +
> +	ret = xilinx_timer_common_init(np, priv, &one_timer);
> +	if (ret)
> +		return ret;
> +
> +	if (one_timer)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "two timers required for PWM mode\n");
> +
> +	/*
> +	 * The polarity of the generate outputs must be active high for PWM
> +	 * mode to work. We could determine this from the device tree, but
> +	 * alas, such properties are not allowed to be used.
> +	 */
> +
> +	priv->clk = devm_clk_get(dev, "s_axi_aclk");
> +	if (IS_ERR(priv->clk))
> +		return dev_err_probe(dev, PTR_ERR(priv->clk),
> +				     "could not get clock\n");
> +
> +	ret = clk_prepare_enable(priv->clk);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "clock enable failed\n");
> +	clk_rate_exclusive_get(priv->clk);
> +
> +	pwm->chip.dev = dev;
> +	pwm->chip.ops = &xilinx_pwm_ops;
> +	pwm->chip.npwm = 1;
> +	ret = pwmchip_add(&pwm->chip);
> +	if (ret) {
> +		clk_rate_exclusive_put(priv->clk);
> +		clk_disable_unprepare(priv->clk);
> +		return dev_err_probe(dev, ret, "could not register pwm chip\n");
> +	}
> +
> +	return 0;
> +}
> +
> +static int xilinx_timer_remove(struct platform_device *pdev)
> +{
> +	struct xilinx_pwm_device *pwm = platform_get_drvdata(pdev);
> +
> +	pwmchip_remove(&pwm->chip);
> +	clk_rate_exclusive_put(pwm->priv.clk);
> +	clk_disable_unprepare(pwm->priv.clk);
> +	return 0;
> +}
> +
> +static const struct of_device_id xilinx_timer_of_match[] = {
> +	{ .compatible = "xlnx,xps-timer-1.00.a", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, xilinx_timer_of_match);
> +
> +static struct platform_driver xilinx_timer_driver = {
> +	.probe = xilinx_timer_probe,
> +	.remove = xilinx_timer_remove,
> +	.driver = {
> +		.name = "xilinx-timer",
> +		.of_match_table = of_match_ptr(xilinx_timer_of_match),
> +	},
> +};
> +module_platform_driver(xilinx_timer_driver);
> +
> +MODULE_ALIAS("platform:xilinx-timer");
> +MODULE_DESCRIPTION("Xilinx LogiCORE IP AXI Timer driver");
> +MODULE_LICENSE("GPL v2");
> 


From robh at kernel.org  Mon Aug  9 07:52:37 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 9 Aug 2021 08:52:37 -0600
Subject: [PATCH v2 03/40] PCI: dwc: Allow overriding bridge pci_ops
In-Reply-To: <68e3adfb-a79d-3b70-87ed-2e5e1bf7fc93@nvidia.com>
References: <20200821035420.380495-1-robh@kernel.org>
 <20200821035420.380495-4-robh@kernel.org>
 <68e3adfb-a79d-3b70-87ed-2e5e1bf7fc93@nvidia.com>
Message-ID: <CAL_JsqJZ-BzxnEPeqirrd=yZFSWejP4PBYDgLNEn-kubFzvXCA@mail.gmail.com>

On Sun, Aug 8, 2021 at 9:13 AM Vidya Sagar <vidyas at nvidia.com> wrote:
>
>
>
> On 8/21/2020 9:23 AM, Rob Herring wrote:
> > In preparation to allow drivers to set their own root and child pci_ops
> > instead of using the DWC specific config space ops, we need to make
> > the pci_host_bridge pointer available and move setting the bridge->ops
> > and bridge->child_ops pointer to before the .host_init() hook.
> >
> > Cc: Jingoo Han <jingoohan1 at gmail.com>
> > Cc: Gustavo Pimentel <gustavo.pimentel at synopsys.com>
> > Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Cc: Bjorn Helgaas <bhelgaas at google.com>
> > Signed-off-by: Rob Herring <robh at kernel.org>
> > ---
> >   drivers/pci/controller/dwc/pcie-designware-host.c | 15 ++++++++++-----
> >   drivers/pci/controller/dwc/pcie-designware.h      |  1 +
> >   2 files changed, 11 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 1d98554db009..b626cc7cd43a 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -344,6 +344,8 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >       if (!bridge)
> >               return -ENOMEM;
> >
> > +     pp->bridge = bridge;
> > +
> >       /* Get the I/O and memory ranges from DT */
> >       resource_list_for_each_entry(win, &bridge->windows) {
> >               switch (resource_type(win->res)) {
> > @@ -445,6 +447,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >               }
> >       }
> >
> > +     /* Set default bus ops */
> > +     bridge->ops = &dw_pcie_ops;
> > +     bridge->child_ops = &dw_pcie_ops;
> > +
> >       if (pp->ops->host_init) {
> >               ret = pp->ops->host_init(pp);
> >               if (ret)
> > @@ -452,7 +458,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >       }
> >
> >       bridge->sysdata = pp;
> > -     bridge->ops = &dw_pcie_ops;
> >
> >       ret = pci_scan_root_bus_bridge(bridge);
> >       if (ret)
> > @@ -654,11 +659,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
> >       dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> >
> >       /*
> > -      * If the platform provides ->rd_other_conf, it means the platform
> > -      * uses its own address translation component rather than ATU, so
> > -      * we should not program the ATU here.
> > +      * If the platform provides its own child bus config accesses, it means
> > +      * the platform uses its own address translation component rather than
> > +      * ATU, so we should not program the ATU here.
> It is possible that a platform can have its own translation for
> configuration accesses and use DWC's ATU for memory/IO address
> translations. IMHO, ATU setup for memory/IO address translations
> shouldn't be skipped based on platform's '->rd_other_conf'
> implementation. Ex:- A platform can implement configuration space access
> through the ECAM mechanism yet choose to use ATU for memory/IO address
> translations.

A platform could, but none of them upstream do that. I'm all for doing
ECAM setup (in the kernel) if possible. That could be in the DWC core
with a feature flag the platform can set or something to enable it if
we do that. It could be based on the config space size as well. I'm
not sure what else determines whether ECAM can work besides having
enough address space and at least 3 outbound iATU windows.

Rob


From will at kernel.org  Mon Aug  9 07:54:20 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 15:54:20 +0100
Subject: [Patch V2 0/2] iommu/arm-smmu: Fix races in iommu domain/group
 creation
In-Reply-To: <9c38c53c-c145-097a-4c7e-40f1c06a1f01@arm.com>
References: <1623961837-12540-1-git-send-email-amhetre@nvidia.com>
 <20210802151607.GF28735@willie-the-truck>
 <9c38c53c-c145-097a-4c7e-40f1c06a1f01@arm.com>
Message-ID: <20210809145420.GB1458@willie-the-truck>

On Mon, Aug 02, 2021 at 04:46:37PM +0100, Robin Murphy wrote:
> On 2021-08-02 16:16, Will Deacon wrote:
> > On Fri, Jun 18, 2021 at 02:00:35AM +0530, Ashish Mhetre wrote:
> > > Multiple iommu domains and iommu groups are getting created for the devices
> > > sharing same SID. It is expected for devices sharing same SID to be in same
> > > iommu group and same iommu domain.
> > > This is leading to context faults when one device is accessing IOVA from
> > > other device which shouldn't be the case for devices sharing same SID.
> > > Fix this by protecting iommu domain and iommu group creation with mutexes.
> > 
> > Robin -- any chance you could take a look at these, please? You had some
> > comments on the first version which convinced me that they are needed,
> > but I couldn't tell whether you wanted to solve this a different way or not.
> 
> Sorry, I was lamenting that this came to light due to the
> of_iommu_configure() flow being yucky, but that wasn't meant to imply that
> there aren't - or couldn't be in future - better reasons for
> iommu_probe_device() to be robust against concurrency anyway. I do think
> these are legitimate fixes to make in their own right, even if the current
> need might get swept back under the rug in future.
> 
> I would say, however, that the commit messages seem to focus too much on the
> wrong details and aren't overly useful, and patch #2 is missing Ashish's
> sign-off.

Ashish -- please can you send a v3 fixing these issues?

Will


From pali at kernel.org  Mon Aug  9 07:53:24 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  9 Aug 2021 16:53:24 +0200
Subject: [PATCH v5 1/6] math64: New DIV_U64_ROUND_CLOSEST helper
In-Reply-To: <20210809145329.24177-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210809145329.24177-1-pali@kernel.org>
Message-ID: <20210809145329.24177-2-pali@kernel.org>

Provide DIV_U64_ROUND_CLOSEST helper which uses div_u64 to perform
division rounded to the closest integer using unsigned 64bit
dividend and unsigned 32bit divisor.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 include/linux/math64.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/linux/math64.h b/include/linux/math64.h
index 66deb1fdc2ef..1cc61d748e1f 100644
--- a/include/linux/math64.h
+++ b/include/linux/math64.h
@@ -281,6 +281,19 @@ u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div);
 #define DIV64_U64_ROUND_CLOSEST(dividend, divisor)	\
 	({ u64 _tmp = (divisor); div64_u64((dividend) + _tmp / 2, _tmp); })
 
+/*
+ * DIV_U64_ROUND_CLOSEST - unsigned 64bit divide with 32bit divisor rounded to nearest integer
+ * @dividend: unsigned 64bit dividend
+ * @divisor: unsigned 32bit divisor
+ *
+ * Divide unsigned 64bit dividend by unsigned 32bit divisor
+ * and round to closest integer.
+ *
+ * Return: dividend / divisor rounded to nearest integer
+ */
+#define DIV_U64_ROUND_CLOSEST(dividend, divisor)	\
+	({ u32 _tmp = (divisor); div_u64((u64)(dividend) + _tmp / 2, _tmp); })
+
 /*
  * DIV_S64_ROUND_CLOSEST - signed 64bit divide with 32bit divisor rounded to nearest integer
  * @dividend: signed 64bit dividend
-- 
2.20.1



From pali at kernel.org  Mon Aug  9 07:53:23 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  9 Aug 2021 16:53:23 +0200
Subject: [PATCH v5 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <20210624224909.6350-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
Message-ID: <20210809145329.24177-1-pali@kernel.org>

This patch series add support for baudrates higher than 230400 on
Marvell Armada 37xx boards.

Please review these patches as they touch both Device Tree bindings and
mvebu-uart.c driver.

Changes in v5:
* fixed yaml binding file

Changes in v4:
* converted armada3700-uart-clock documentation to YAML
* split documentation changes into two commits:
  - first which adds clock documentation
  - second which updates UART documentation

Changes in v3:
v3 is rebased on top of Linus master branch and all already applied patches
were dropped. There are no changes in patches itself since v2.

Pali Roh?r (6):
  math64: New DIV_U64_ROUND_CLOSEST helper
  serial: mvebu-uart: implement UART clock driver for configuring UART
    base clock
  dt-bindings: mvebu-uart: document DT bindings for
    marvell,armada-3700-uart-clock
  dt-bindings: mvebu-uart: update information about UART clock
  arm64: dts: marvell: armada-37xx: add device node for UART clock and
    use it
  serial: mvebu-uart: implement support for baudrates higher than 230400

 .../bindings/clock/armada3700-uart-clock.yaml |  57 ++
 .../devicetree/bindings/serial/mvebu-uart.txt |   9 +-
 .../arm64/boot/dts/marvell/armada-3720-db.dts |   4 +
 .../dts/marvell/armada-3720-espressobin.dtsi  |   4 +
 .../dts/marvell/armada-3720-turris-mox.dts    |   4 +
 .../boot/dts/marvell/armada-3720-uDPU.dts     |   4 +
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi  |  15 +-
 drivers/tty/serial/Kconfig                    |   1 +
 drivers/tty/serial/mvebu-uart.c               | 592 +++++++++++++++++-
 include/linux/math64.h                        |  13 +
 10 files changed, 682 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml

-- 
2.20.1



From pali at kernel.org  Mon Aug  9 07:53:28 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  9 Aug 2021 16:53:28 +0200
Subject: [PATCH v5 5/6] arm64: dts: marvell: armada-37xx: add device node for
 UART clock and use it
In-Reply-To: <20210809145329.24177-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210809145329.24177-1-pali@kernel.org>
Message-ID: <20210809145329.24177-6-pali@kernel.org>

This change defines DT node for UART clock "marvell,armada-3700-uart-clock"
and use this UART clock as a base clock for all UART devices.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 arch/arm64/boot/dts/marvell/armada-3720-db.dts    |  4 ++++
 .../boot/dts/marvell/armada-3720-espressobin.dtsi |  4 ++++
 .../boot/dts/marvell/armada-3720-turris-mox.dts   |  4 ++++
 arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts  |  4 ++++
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi      | 15 +++++++++++++--
 5 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
index 3e5789f37206..accf014a6a1e 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts
@@ -191,6 +191,10 @@
 	};
 };
 
+&uartclk {
+	status = "okay";
+};
+
 /*
  * Exported on the micro USB connector CON30(V2.0)/CON32(V1.4) through
  * an FTDI (also on CON24(V2.0)/CON26(V1.4)).
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
index 5fc613d24151..d03c7cdfbfb3 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
@@ -117,6 +117,10 @@
 	};
 };
 
+&uartclk {
+	status = "okay";
+};
+
 /* Exported on the micro USB connector J5 through an FTDI */
 &uart0 {
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
index cacf2a05fb22..972c6d400f8b 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
@@ -167,6 +167,10 @@
 	status = "disabled";
 };
 
+&uartclk {
+	status = "okay";
+};
+
 &uart0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
index 95d46e8d081c..c8217440b8dd 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
@@ -183,6 +183,10 @@
 	phy-names = "usb2-utmi-otg-phy";
 };
 
+&uartclk {
+	status = "okay";
+};
+
 &uart0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 20dd9d9e9d58..d9bdd374cf45 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -132,10 +132,21 @@
 				reg = <0x11500 0x40>;
 			};
 
+			uartclk: uartclk at 12000 {
+				compatible = "marvell,armada-3700-uart-clock";
+				reg = <0x12010 0x4>, <0x12210 0x4>;
+				clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>,
+					<&tbg 3>, <&xtalclk>;
+				clock-names = "TBG-A-P", "TBG-B-P", "TBG-A-S",
+					"TBG-B-S", "xtal";
+				#clock-cells = <1>;
+				status = "disabled";
+			};
+
 			uart0: serial at 12000 {
 				compatible = "marvell,armada-3700-uart";
 				reg = <0x12000 0x18>;
-				clocks = <&xtalclk>;
+				clocks = <&uartclk 0>;
 				interrupts =
 				<GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
 				<GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
@@ -147,7 +158,7 @@
 			uart1: serial at 12200 {
 				compatible = "marvell,armada-3700-uart-ext";
 				reg = <0x12200 0x30>;
-				clocks = <&xtalclk>;
+				clocks = <&uartclk 1>;
 				interrupts =
 				<GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
 				<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>;
-- 
2.20.1



From pali at kernel.org  Mon Aug  9 07:53:26 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  9 Aug 2021 16:53:26 +0200
Subject: [PATCH v5 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <20210809145329.24177-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210809145329.24177-1-pali@kernel.org>
Message-ID: <20210809145329.24177-4-pali@kernel.org>

This change adds DT bindings documentation for device nodes with compatible
string "marvell,armada-3700-uart-clock".

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 .../bindings/clock/armada3700-uart-clock.yaml | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
new file mode 100644
index 000000000000..5bdb23e0ba3e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/marvell,armada-3700-uart-clock#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+title: Marvell Armada 3720 UART clocks
+
+properties:
+  compatible:
+    const: marvell,armada-3700-uart-clock
+
+  reg:
+    items:
+      - description: UART Clock Control Register
+      - description: UART 2 Baud Rate Divisor Register
+
+  clocks:
+    description: |
+      List of parent clocks suitable for UART from following set:
+        "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal"
+      UART clock can use one from this set and when more are provided
+      then kernel would choose and configure the most suitable one.
+      It is suggest to specify at least one TBG clock to achieve
+      baudrates above 230400 and also to specify clock which bootloader
+      used for UART (most probably xtal) for smooth boot log on UART.
+
+  clock-names:
+    items:
+      - const: TBG-A-P
+      - const: TBG-B-P
+      - const: TBG-A-S
+      - const: TBG-B-S
+      - const: xtal
+    minItems: 1
+    maxItems: 5
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    uartclk: uartclk at 12000 {
+      compatible = "marvell,armada-3700-uart-clock";
+      reg = <0x12010 0x4>, <0x12210 0x4>;
+      clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>, <&xtalclk>;
+      clock-names = "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal";
+      #clock-cells = <1>;
+    };
-- 
2.20.1



From pali at kernel.org  Mon Aug  9 07:53:25 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  9 Aug 2021 16:53:25 +0200
Subject: [PATCH v5 2/6] serial: mvebu-uart: implement UART clock driver for
 configuring UART base clock
In-Reply-To: <20210809145329.24177-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210809145329.24177-1-pali@kernel.org>
Message-ID: <20210809145329.24177-3-pali@kernel.org>

This patch implements a new device driver for controlling UART clocks on
Marvell Armada 3700 SoC. This device driver is loaded for devices which
match compatible string "marvell,armada-3700-uart-clock".

There are more pitfalls related to UART clocks. Both UARTs use same base
clock source. Also divisors for TBG base clock are shared between both
UARTs and are configured only from UART1 address space. Clocks can be
enabled / disabled separately for UART1 and UART2, but they are controlled
only from UART1 address space. Moreover Marvell Armada 3700 Functional
Specifications has swapped bits for enabling/disabling UART1 and UART2
clocks.

So driver for controlling UART2 needs to have access to UART1 address space
as UART1 address space contains some bits exclusively used by UART2 and
also bits which are shared for both UART1 and UART2.

For changing UART base clock (which controls both UARTs) during boot when
UART driver is not ready and only early console is active, is not simple
operation as it is required to also recalculate divisors to not change UART
baudrate used by early console. So for this operation UART1 clock driver
needs to access also into address space of UART2 where are registers for
UART2 divisors.

For these reasons, this new device driver for UART clocks does not use
ioremap_resource(), but only ioremap() to prevent resource conflicts
between UART clock driver and UART driver.

Shared between drivers are only two 4-bytes registers: UART Clock Control
and UART 2 Baud Rate Divisor. Access to these two registers are protected
by one spinlock to prevent any conflicts. Access is required only during
probe time, changing baudrate and during suspend/resume.

Hardware can be configured to use one of following clocks as UART base
clock: TBG-A-P, TBG-B-P, TBG-A-S, TBG-B-S, xtal. Not every clock is usable
for higher buadrates. In DT node can be specified any subset and kernel
choose the best one, which still supports required baudrate 9600. For
smooth boot log output it is needed to specify clock used by early console
otherwise garbage would be put on UART during probing for UART clock driver
and transitioning from early console to normal console.

This change is required to enable and configure TBG clock as a base clock
for UART. TBG clock is required to achieve higher baudrates than 230400.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/tty/serial/Kconfig      |   1 +
 drivers/tty/serial/mvebu-uart.c | 519 +++++++++++++++++++++++++++++++-
 2 files changed, 518 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 0c4cd4a348f4..b3726797a0f5 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1441,6 +1441,7 @@ config SERIAL_STM32_CONSOLE
 config SERIAL_MVEBU_UART
 	bool "Marvell EBU serial port support"
 	depends on ARCH_MVEBU || COMPILE_TEST
+	depends on COMMON_CLK
 	select SERIAL_CORE
 	help
 	  This driver is for Marvell EBU SoC's UART. If you have a machine
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index 414e92064ac6..a31235add99f 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -8,12 +8,14 @@
 */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/math64.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -68,8 +70,31 @@
 #define  STAT_BRK_ERR		(STAT_BRK_DET | STAT_FRM_ERR \
 				 | STAT_PAR_ERR | STAT_OVR_ERR)
 
+/*
+ * Marvell Armada 3700 Functional Specifications describes that bit 21 of UART
+ * Clock Control register controls UART1 and bit 20 controls UART2. But in
+ * reality bit 21 controls UART2 and bit 20 controls UART1. This seems to be a
+ * bug in Marvell documentation. Hence following CLK_DIS macros are swapped.
+ */
+
 #define UART_BRDV		0x10
+/* These bits are located in UART1 address space and control UART2 */
+#define  UART2_CLK_DIS		BIT(21)
+/* These bits are located in UART1 address space and control UART1 */
+#define  UART1_CLK_DIS		BIT(20)
+/* These bits are located in UART1 address space and control both UARTs */
+#define  CLK_NO_XTAL		BIT(19)
+#define  CLK_TBG_DIV1_SHIFT	15
+#define  CLK_TBG_DIV1_MASK	0x7
+#define  CLK_TBG_DIV1_MAX	6
+#define  CLK_TBG_DIV2_SHIFT	12
+#define  CLK_TBG_DIV2_MASK	0x7
+#define  CLK_TBG_DIV2_MAX	6
+#define  CLK_TBG_SEL_SHIFT	10
+#define  CLK_TBG_SEL_MASK	0x3
+/* These bits are located in both UARTs address space */
 #define  BRDV_BAUD_MASK         0x3FF
+#define  BRDV_BAUD_MAX		BRDV_BAUD_MASK
 
 #define UART_OSAMP		0x14
 #define  OSAMP_DEFAULT_DIVISOR	16
@@ -153,6 +178,8 @@ static struct mvebu_uart *to_mvuart(struct uart_port *port)
 
 static struct uart_port mvebu_uart_ports[MVEBU_NR_UARTS];
 
+static DEFINE_SPINLOCK(mvebu_uart_lock);
+
 /* Core UART Driver Operations */
 static unsigned int mvebu_uart_tx_empty(struct uart_port *port)
 {
@@ -445,6 +472,7 @@ static void mvebu_uart_shutdown(struct uart_port *port)
 static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 {
 	unsigned int d_divisor, m_divisor;
+	unsigned long flags;
 	u32 brdv, osamp;
 
 	if (!port->uartclk)
@@ -463,10 +491,12 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 	m_divisor = OSAMP_DEFAULT_DIVISOR;
 	d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
 
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
 	brdv = readl(port->membase + UART_BRDV);
 	brdv &= ~BRDV_BAUD_MASK;
 	brdv |= d_divisor;
 	writel(brdv, port->membase + UART_BRDV);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
 
 	osamp = readl(port->membase + UART_OSAMP);
 	osamp &= ~OSAMP_DIVISORS_MASK;
@@ -762,6 +792,7 @@ static int mvebu_uart_suspend(struct device *dev)
 {
 	struct mvebu_uart *mvuart = dev_get_drvdata(dev);
 	struct uart_port *port = mvuart->port;
+	unsigned long flags;
 
 	uart_suspend_port(&mvebu_uart_driver, port);
 
@@ -770,7 +801,9 @@ static int mvebu_uart_suspend(struct device *dev)
 	mvuart->pm_regs.ctrl = readl(port->membase + UART_CTRL(port));
 	mvuart->pm_regs.intr = readl(port->membase + UART_INTR(port));
 	mvuart->pm_regs.stat = readl(port->membase + UART_STAT);
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
 	mvuart->pm_regs.brdv = readl(port->membase + UART_BRDV);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
 	mvuart->pm_regs.osamp = readl(port->membase + UART_OSAMP);
 
 	device_set_wakeup_enable(dev, true);
@@ -782,13 +815,16 @@ static int mvebu_uart_resume(struct device *dev)
 {
 	struct mvebu_uart *mvuart = dev_get_drvdata(dev);
 	struct uart_port *port = mvuart->port;
+	unsigned long flags;
 
 	writel(mvuart->pm_regs.rbr, port->membase + UART_RBR(port));
 	writel(mvuart->pm_regs.tsh, port->membase + UART_TSH(port));
 	writel(mvuart->pm_regs.ctrl, port->membase + UART_CTRL(port));
 	writel(mvuart->pm_regs.intr, port->membase + UART_INTR(port));
 	writel(mvuart->pm_regs.stat, port->membase + UART_STAT);
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
 	writel(mvuart->pm_regs.brdv, port->membase + UART_BRDV);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
 	writel(mvuart->pm_regs.osamp, port->membase + UART_OSAMP);
 
 	uart_resume_port(&mvebu_uart_driver, port);
@@ -975,6 +1011,476 @@ static struct platform_driver mvebu_uart_platform_driver = {
 	},
 };
 
+/* This code is based on clk-fixed-factor.c driver and modified. */
+
+struct mvebu_uart_clock {
+	struct clk_hw clk_hw;
+	int clock_idx;
+	u32 pm_context_reg1;
+	u32 pm_context_reg2;
+};
+
+struct mvebu_uart_clock_base {
+	struct mvebu_uart_clock clocks[2];
+	unsigned int parent_rates[5];
+	int parent_idx;
+	unsigned int div;
+	void __iomem *reg1;
+	void __iomem *reg2;
+	bool configured;
+};
+
+#define PARENT_CLOCK_XTAL 4
+
+#define to_uart_clock(hw) container_of(hw, struct mvebu_uart_clock, clk_hw)
+#define to_uart_clock_base(uart_clock) container_of(uart_clock, \
+	struct mvebu_uart_clock_base, clocks[uart_clock->clock_idx])
+
+static int mvebu_uart_clock_prepare(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned int prev_clock_idx, prev_clock_rate, prev_d1d2;
+	unsigned int parent_clock_idx, parent_clock_rate;
+	unsigned long flags;
+	unsigned int d1, d2;
+	u64 divisor;
+	u32 val;
+
+	/*
+	 * This function just reconfigures UART Clock Control register (located
+	 * in UART1 address space which controls both UART1 and UART2) to
+	 * selected UART base clock and recalculate current UART1/UART2 divisors
+	 * in their address spaces, so final baudrate will not be changed by
+	 * switching UART base clock. This is required otherwise kernel boot log
+	 * stops working. It is needed to ensure that UART baudrate does not
+	 * change during this setup. It is one time operation, so based on
+	 * "configured" member this function is skipped on second call. Because
+	 * this UART Clock Control register (UART_BRDV) is shared between UART1
+	 * baudrate function, UART1 clock selector and UART2 clock selector,
+	 * every access to UART_BRDV (reg1) needs to be protected by lock.
+	 */
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+
+	if (uart_clock_base->configured) {
+		spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+		return 0;
+	}
+
+	parent_clock_idx = uart_clock_base->parent_idx;
+	parent_clock_rate = uart_clock_base->parent_rates[parent_clock_idx];
+
+	val = readl(uart_clock_base->reg1);
+
+	if (uart_clock_base->div > CLK_TBG_DIV1_MAX) {
+		d1 = CLK_TBG_DIV1_MAX;
+		d2 = uart_clock_base->div / CLK_TBG_DIV1_MAX;
+	} else {
+		d1 = uart_clock_base->div;
+		d2 = 1;
+	}
+
+	if (val & CLK_NO_XTAL) {
+		prev_clock_idx = (val >> CLK_TBG_SEL_SHIFT) & CLK_TBG_SEL_MASK;
+		prev_d1d2 = ((val >> CLK_TBG_DIV1_SHIFT) & CLK_TBG_DIV1_MASK)
+			  * ((val >> CLK_TBG_DIV2_SHIFT) & CLK_TBG_DIV2_MASK);
+	} else {
+		prev_clock_idx = PARENT_CLOCK_XTAL;
+		prev_d1d2 = 1;
+	}
+
+	/* Note that uart_clock_base->parent_rates[i] may not be available */
+	prev_clock_rate = uart_clock_base->parent_rates[prev_clock_idx];
+
+	/* Recalculate UART1 divisor so UART1 baudrate does not change */
+	if (prev_clock_rate) {
+		divisor = DIV_U64_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) *
+						parent_clock_rate * prev_d1d2,
+						prev_clock_rate * d1 * d2);
+		if (divisor < 1)
+			divisor = 1;
+		else if (divisor > BRDV_BAUD_MAX)
+			divisor = BRDV_BAUD_MAX;
+		val = (val & ~BRDV_BAUD_MASK) | divisor;
+	}
+
+	if (parent_clock_idx != PARENT_CLOCK_XTAL) {
+		/* Do not use XTAL, select TBG clock and TBG d1 * d2 divisors */
+		val |= CLK_NO_XTAL;
+		val &= ~(CLK_TBG_DIV1_MASK << CLK_TBG_DIV1_SHIFT);
+		val |= d1 << CLK_TBG_DIV1_SHIFT;
+		val &= ~(CLK_TBG_DIV2_MASK << CLK_TBG_DIV2_SHIFT);
+		val |= d2 << CLK_TBG_DIV2_SHIFT;
+		val &= ~(CLK_TBG_SEL_MASK << CLK_TBG_SEL_SHIFT);
+		val |= parent_clock_idx << CLK_TBG_SEL_SHIFT;
+	} else {
+		/* Use XTAL, TBG bits are then ignored */
+		val &= ~CLK_NO_XTAL;
+	}
+
+	writel(val, uart_clock_base->reg1);
+
+	/* Recalculate UART2 divisor so UART2 baudrate does not change */
+	if (prev_clock_rate) {
+		val = readl(uart_clock_base->reg2);
+		divisor = DIV_U64_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) *
+						parent_clock_rate * prev_d1d2,
+						prev_clock_rate * d1 * d2);
+		if (divisor < 1)
+			divisor = 1;
+		else if (divisor > BRDV_BAUD_MAX)
+			divisor = BRDV_BAUD_MAX;
+		val = (val & ~BRDV_BAUD_MASK) | divisor;
+		writel(val, uart_clock_base->reg2);
+	}
+
+	uart_clock_base->configured = true;
+
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+
+	return 0;
+}
+
+static int mvebu_uart_clock_enable(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+
+	val = readl(uart_clock_base->reg1);
+
+	if (uart_clock->clock_idx == 0)
+		val &= ~UART1_CLK_DIS;
+	else
+		val &= ~UART2_CLK_DIS;
+
+	writel(val, uart_clock_base->reg1);
+
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+
+	return 0;
+}
+
+static void mvebu_uart_clock_disable(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+
+	val = readl(uart_clock_base->reg1);
+
+	if (uart_clock->clock_idx == 0)
+		val |= UART1_CLK_DIS;
+	else
+		val |= UART2_CLK_DIS;
+
+	writel(val, uart_clock_base->reg1);
+
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+}
+
+static int mvebu_uart_clock_is_enabled(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	u32 val;
+
+	val = readl(uart_clock_base->reg1);
+
+	if (uart_clock->clock_idx == 0)
+		return !(val & UART1_CLK_DIS);
+	else
+		return !(val & UART2_CLK_DIS);
+}
+
+static int mvebu_uart_clock_save_context(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+	uart_clock->pm_context_reg1 = readl(uart_clock_base->reg1);
+	uart_clock->pm_context_reg2 = readl(uart_clock_base->reg2);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+
+	return 0;
+}
+
+static void mvebu_uart_clock_restore_context(struct clk_hw *hw)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&mvebu_uart_lock, flags);
+	writel(uart_clock->pm_context_reg1, uart_clock_base->reg1);
+	writel(uart_clock->pm_context_reg2, uart_clock_base->reg2);
+	spin_unlock_irqrestore(&mvebu_uart_lock, flags);
+}
+
+static unsigned long mvebu_uart_clock_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+
+	return parent_rate / uart_clock_base->div;
+}
+
+static long mvebu_uart_clock_round_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long *parent_rate)
+{
+	struct mvebu_uart_clock *uart_clock = to_uart_clock(hw);
+	struct mvebu_uart_clock_base *uart_clock_base =
+						to_uart_clock_base(uart_clock);
+
+	return *parent_rate / uart_clock_base->div;
+}
+
+static int mvebu_uart_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long parent_rate)
+{
+	/*
+	 * We must report success but we can do so unconditionally because
+	 * mvebu_uart_clock_round_rate returns values that ensure this call is a
+	 * nop.
+	 */
+
+	return 0;
+}
+
+static const struct clk_ops mvebu_uart_clock_ops = {
+	.prepare = mvebu_uart_clock_prepare,
+	.enable = mvebu_uart_clock_enable,
+	.disable = mvebu_uart_clock_disable,
+	.is_enabled = mvebu_uart_clock_is_enabled,
+	.save_context = mvebu_uart_clock_save_context,
+	.restore_context = mvebu_uart_clock_restore_context,
+	.round_rate = mvebu_uart_clock_round_rate,
+	.set_rate = mvebu_uart_clock_set_rate,
+	.recalc_rate = mvebu_uart_clock_recalc_rate,
+};
+
+static int mvebu_uart_clock_register(struct device *dev,
+				     struct mvebu_uart_clock *uart_clock,
+				     const char *name,
+				     const char *parent_name)
+{
+	struct clk_init_data init = { };
+
+	uart_clock->clk_hw.init = &init;
+
+	init.name = name;
+	init.ops = &mvebu_uart_clock_ops;
+	init.flags = 0;
+	init.num_parents = 1;
+	init.parent_names = &parent_name;
+
+	return devm_clk_hw_register(dev, &uart_clock->clk_hw);
+}
+
+static int mvebu_uart_clock_probe(struct platform_device *pdev)
+{
+	static const char *const uart_clk_names[] = { "uart_1", "uart_2" };
+	static const char *const parent_clk_names[] = { "TBG-A-P", "TBG-B-P",
+							"TBG-A-S", "TBG-B-S",
+							"xtal" };
+	struct clk *parent_clks[ARRAY_SIZE(parent_clk_names)];
+	struct mvebu_uart_clock_base *uart_clock_base;
+	struct clk_hw_onecell_data *hw_clk_data;
+	struct device *dev = &pdev->dev;
+	int i, parent_clk_idx, ret;
+	unsigned long div, rate;
+	struct resource *res;
+	unsigned int d1, d2;
+
+	BUILD_BUG_ON(ARRAY_SIZE(uart_clk_names) !=
+		     ARRAY_SIZE(uart_clock_base->clocks));
+	BUILD_BUG_ON(ARRAY_SIZE(parent_clk_names) !=
+		     ARRAY_SIZE(uart_clock_base->parent_rates));
+
+	uart_clock_base = devm_kzalloc(dev,
+				       sizeof(*uart_clock_base),
+				       GFP_KERNEL);
+	if (!uart_clock_base)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "Couldn't get first register\n");
+		return -ENOENT;
+	}
+
+	/*
+	 * UART Clock Control register (reg1 / UART_BRDV) is in address range
+	 * of UART1 (standard UART variant), controls clock source and dividers
+	 * for both UART1 and UART2 and is supplied via DT as first resource.
+	 * Therefore use ioremap() function rather than ioremap_resource() to
+	 * avoid conflicts with UART1 driver. Access to UART_BRDV is protected
+	 * by lock shared between clock and UART driver.
+	 */
+	uart_clock_base->reg1 = devm_ioremap(dev, res->start,
+					     resource_size(res));
+	if (IS_ERR(uart_clock_base->reg1))
+		return PTR_ERR(uart_clock_base->reg1);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_err(dev, "Couldn't get second register\n");
+		return -ENOENT;
+	}
+
+	/*
+	 * UART 2 Baud Rate Divisor register (reg2 / UART_BRDV) is in address
+	 * range of UART2 (extended UART variant), controls only one UART2
+	 * specific divider and is supplied via DT as second resource.
+	 * Therefore use ioremap() function rather than ioremap_resource() to
+	 * avoid conflicts with UART2 driver. Access to UART_BRDV is protected
+	 * by lock shared between clock and UART driver.
+	 */
+	uart_clock_base->reg2 = devm_ioremap(dev, res->start,
+					     resource_size(res));
+	if (IS_ERR(uart_clock_base->reg2))
+		return PTR_ERR(uart_clock_base->reg2);
+
+	hw_clk_data = devm_kzalloc(dev,
+				   struct_size(hw_clk_data, hws,
+					       ARRAY_SIZE(uart_clk_names)),
+				   GFP_KERNEL);
+	if (!hw_clk_data)
+		return -ENOMEM;
+
+	hw_clk_data->num = ARRAY_SIZE(uart_clk_names);
+	for (i = 0; i < ARRAY_SIZE(uart_clk_names); i++) {
+		hw_clk_data->hws[i] = &uart_clock_base->clocks[i].clk_hw;
+		uart_clock_base->clocks[i].clock_idx = i;
+	}
+
+	parent_clk_idx = -1;
+
+	for (i = 0; i < ARRAY_SIZE(parent_clk_names); i++) {
+		parent_clks[i] = devm_clk_get(dev, parent_clk_names[i]);
+		if (IS_ERR(parent_clks[i])) {
+			if (PTR_ERR(parent_clks[i]) == -EPROBE_DEFER)
+				return -EPROBE_DEFER;
+			dev_warn(dev, "Couldn't get the parent clock %s: %ld\n",
+				parent_clk_names[i], PTR_ERR(parent_clks[i]));
+			continue;
+		}
+
+		ret = clk_prepare_enable(parent_clks[i]);
+		if (ret) {
+			dev_warn(dev, "Couldn't enable parent clock %s: %d\n",
+				parent_clk_names[i], ret);
+			continue;
+		}
+		rate = clk_get_rate(parent_clks[i]);
+		uart_clock_base->parent_rates[i] = rate;
+
+		if (i != PARENT_CLOCK_XTAL) {
+			/*
+			 * Calculate the smallest TBG d1 and d2 divisors that
+			 * still can provide 9600 baudrate.
+			 */
+			d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+						BRDV_BAUD_MAX);
+			if (d1 < 1)
+				d1 = 1;
+			else if (d1 > CLK_TBG_DIV1_MAX)
+				d1 = CLK_TBG_DIV1_MAX;
+
+			d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+						BRDV_BAUD_MAX * d1);
+			if (d2 < 1)
+				d2 = 1;
+			else if (d2 > CLK_TBG_DIV2_MAX)
+				d2 = CLK_TBG_DIV2_MAX;
+		} else {
+			/*
+			 * When UART clock uses XTAL clock as a source then it
+			 * is not possible to use d1 and d2 divisors.
+			 */
+			d1 = d2 = 1;
+		}
+
+		/* Skip clock source which cannot provide 9600 baudrate */
+		if (rate > 9600 * OSAMP_DEFAULT_DIVISOR * BRDV_BAUD_MAX * d1 * d2)
+			continue;
+
+		/*
+		 * Choose TBG clock source with the smallest divisors. Use XTAL
+		 * clock source only in case TBG is not available as XTAL cannot
+		 * be used for baudrates higher than 230400.
+		 */
+		if (parent_clk_idx == -1 ||
+		    (i != PARENT_CLOCK_XTAL && div > d1 * d2)) {
+			parent_clk_idx = i;
+			div = d1 * d2;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(parent_clk_names); i++) {
+		if (i == parent_clk_idx || IS_ERR(parent_clks[i]))
+			continue;
+		clk_disable_unprepare(parent_clks[i]);
+		devm_clk_put(dev, parent_clks[i]);
+	}
+
+	if (parent_clk_idx == -1) {
+		dev_err(dev, "No usable parent clock\n");
+		return -ENOENT;
+	}
+
+	uart_clock_base->parent_idx = parent_clk_idx;
+	uart_clock_base->div = div;
+
+	dev_notice(dev, "Using parent clock %s as base UART clock\n",
+		   __clk_get_name(parent_clks[parent_clk_idx]));
+
+	for (i = 0; i < ARRAY_SIZE(uart_clk_names); i++) {
+		ret = mvebu_uart_clock_register(dev,
+				&uart_clock_base->clocks[i],
+				uart_clk_names[i],
+				__clk_get_name(parent_clks[parent_clk_idx]));
+		if (ret) {
+			dev_err(dev, "Can't register UART clock %d: %d\n",
+				i, ret);
+			return ret;
+		}
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   hw_clk_data);
+}
+
+static const struct of_device_id mvebu_uart_clock_of_match[] = {
+	{ .compatible = "marvell,armada-3700-uart-clock", },
+	{ }
+};
+
+static struct platform_driver mvebu_uart_clock_platform_driver = {
+	.probe = mvebu_uart_clock_probe,
+	.driver		= {
+		.name	= "mvebu-uart-clock",
+		.of_match_table = mvebu_uart_clock_of_match,
+	},
+};
+
 static int __init mvebu_uart_init(void)
 {
 	int ret;
@@ -983,10 +1489,19 @@ static int __init mvebu_uart_init(void)
 	if (ret)
 		return ret;
 
+	ret = platform_driver_register(&mvebu_uart_clock_platform_driver);
+	if (ret) {
+		uart_unregister_driver(&mvebu_uart_driver);
+		return ret;
+	}
+
 	ret = platform_driver_register(&mvebu_uart_platform_driver);
-	if (ret)
+	if (ret) {
+		platform_driver_unregister(&mvebu_uart_clock_platform_driver);
 		uart_unregister_driver(&mvebu_uart_driver);
+		return ret;
+	}
 
-	return ret;
+	return 0;
 }
 arch_initcall(mvebu_uart_init);
-- 
2.20.1



From pali at kernel.org  Mon Aug  9 07:53:27 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  9 Aug 2021 16:53:27 +0200
Subject: [PATCH v5 4/6] dt-bindings: mvebu-uart: update information about UART
 clock
In-Reply-To: <20210809145329.24177-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210809145329.24177-1-pali@kernel.org>
Message-ID: <20210809145329.24177-5-pali@kernel.org>

Device "marvell,armada-3700-uart" should use
"marvell,armada-3700-uart-clock" compatible clock.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 Documentation/devicetree/bindings/serial/mvebu-uart.txt | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/mvebu-uart.txt b/Documentation/devicetree/bindings/serial/mvebu-uart.txt
index 2d0dbdf32d1d..a062bbca532c 100644
--- a/Documentation/devicetree/bindings/serial/mvebu-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mvebu-uart.txt
@@ -14,7 +14,10 @@ Required properties:
       is provided (possible only with the "marvell,armada-3700-uart"
       compatible string for backward compatibility), it will only work
       if the baudrate was initialized by the bootloader and no baudrate
-      change will then be possible.
+      change will then be possible. When provided it should be UART1-clk
+      for standard variant of UART and UART2-clk for extended variant
+      of UART. TBG clock (with UART TBG divisors d1=d2=1) or xtal clock
+      should not be used and are supported only for backward compatibility.
 - interrupts:
     - Must contain three elements for the standard variant of the IP
       (marvell,armada-3700-uart): "uart-sum", "uart-tx" and "uart-rx",
@@ -34,7 +37,7 @@ Example:
 	uart0: serial at 12000 {
 		compatible = "marvell,armada-3700-uart";
 		reg = <0x12000 0x18>;
-		clocks = <&xtalclk>;
+		clocks = <&uartclk 0>;
 		interrupts =
 		<GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
 		<GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
@@ -45,7 +48,7 @@ Example:
 	uart1: serial at 12200 {
 		compatible = "marvell,armada-3700-uart-ext";
 		reg = <0x12200 0x30>;
-		clocks = <&xtalclk>;
+		clocks = <&uartclk 1>;
 		interrupts =
 		<GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
 		<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>;
-- 
2.20.1



From pali at kernel.org  Mon Aug  9 07:53:29 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon,  9 Aug 2021 16:53:29 +0200
Subject: [PATCH v5 6/6] serial: mvebu-uart: implement support for baudrates
 higher than 230400
In-Reply-To: <20210809145329.24177-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210809145329.24177-1-pali@kernel.org>
Message-ID: <20210809145329.24177-7-pali@kernel.org>

This change implements simple usage of fractional divisor. When main
divisor D is too large to represent requested baudrate then use divisor M
from fractional divisor feature. All the M prescalers are set to same and
maximal value 63, so fractional part is not used at all.

Tests showed that UART at 1500000 baudrate via this configuration is stable
and usable. So there is no need to implement complicated calculation of
fractional coefficients yet.

To use this feature with higher baudrates, it is required to use UART clock
provided by UART clock driver. Default boot xtal clock is not capable of
higher baudrates and this change also contains code for determining upper
limit of possible baudrate.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/tty/serial/mvebu-uart.c | 79 ++++++++++++++++++++++++++-------
 1 file changed, 62 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
index a31235add99f..0fe251b8627b 100644
--- a/drivers/tty/serial/mvebu-uart.c
+++ b/drivers/tty/serial/mvebu-uart.c
@@ -99,6 +99,7 @@
 #define UART_OSAMP		0x14
 #define  OSAMP_DEFAULT_DIVISOR	16
 #define  OSAMP_DIVISORS_MASK	0x3F3F3F3F
+#define  OSAMP_MAX_DIVISOR	63
 
 #define MVEBU_NR_UARTS		2
 
@@ -479,18 +480,59 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 		return -EOPNOTSUPP;
 
 	/*
-	 * The baudrate is derived from the UART clock thanks to two divisors:
-	 *   > D ("baud generator"): can divide the clock from 2 to 2^10 - 1.
-	 *   > M ("fractional divisor"): allows a better accuracy for
-	 *     baudrates higher than 230400.
+	 * The baudrate is derived from the UART clock thanks to divisors:
+	 *   > d1 * d2 ("TBG divisors"): can divide only TBG clock from 1 to 6
+	 *   > D ("baud generator"): can divide the clock from 1 to 1023
+	 *   > M ("fractional divisor"): allows a better accuracy (from 1 to 63)
 	 *
-	 * As the derivation of M is rather complicated, the code sticks to its
-	 * default value (x16) when all the prescalers are zeroed, and only
-	 * makes use of D to configure the desired baudrate.
+	 * Exact formulas for calculating baudrate:
+	 *
+	 * with default x16 scheme:
+	 *   baudrate = xtal / (d * 16)
+	 *   baudrate = tbg / (d1 * d2 * d * 16)
+	 *
+	 * with fractional divisor:
+	 *   baudrate = 10 * xtal / (d * (3 * (m1 + m2) + 2 * (m3 + m4)))
+	 *   baudrate = 10 * tbg / (d1*d2 * d * (3 * (m1 + m2) + 2 * (m3 + m4)))
+	 *
+	 * Oversampling value:
+	 *   osamp = (m1 << 0) | (m2 << 8) | (m3 << 16) | (m4 << 24);
+	 *
+	 * Where m1 controls number of clock cycles per bit for bits 1,2,3;
+	 * m2 for bits 4,5,6; m3 for bits 7,8 and m4 for bits 9,10.
+	 *
+	 * To simplify baudrate setup set all the M prescalers to same value.
+	 * For 9600 baudrate and higher it is enough to use just default (x16)
+	 * divisor or fractional divisor with M = 63, so there is no need to
+	 * use real fractional support (when the M prescalers are not equal).
+	 *
+	 * When all the M prescalers are zeroed then default (x16) divisor is
+	 * used. Default x16 scheme is more stable than M (fractional divisor),
+	 * so use M only when D divisor is not enough to derivate baudrate.
+	 *
+	 * Member port->uartclk is either xtal clock rate or TBG clock rate
+	 * divided by (d1 * d2). So UART clock driver already sets d1 and d2
+	 * divisors and UART driver cannot change them. Moreover they are
+	 * shared with both UARTs.
 	 */
+
 	m_divisor = OSAMP_DEFAULT_DIVISOR;
 	d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
 
+	if (d_divisor > BRDV_BAUD_MAX) {
+		/*
+		 * Experiments showed that small M divisors are unstable.
+		 * So use maximal possible M = 63 and calculate D divisor.
+		 */
+		m_divisor = OSAMP_MAX_DIVISOR;
+		d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
+	}
+
+	if (d_divisor < 1)
+		d_divisor = 1;
+	else if (d_divisor > BRDV_BAUD_MAX)
+		d_divisor = BRDV_BAUD_MAX;
+
 	spin_lock_irqsave(&mvebu_uart_lock, flags);
 	brdv = readl(port->membase + UART_BRDV);
 	brdv &= ~BRDV_BAUD_MASK;
@@ -500,6 +542,9 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
 
 	osamp = readl(port->membase + UART_OSAMP);
 	osamp &= ~OSAMP_DIVISORS_MASK;
+	if (m_divisor != OSAMP_DEFAULT_DIVISOR)
+		osamp |= (m_divisor << 0) | (m_divisor << 8) |
+			(m_divisor << 16) | (m_divisor << 24);
 	writel(osamp, port->membase + UART_OSAMP);
 
 	return 0;
@@ -529,14 +574,14 @@ static void mvebu_uart_set_termios(struct uart_port *port,
 		port->ignore_status_mask |= STAT_RX_RDY(port) | STAT_BRK_ERR;
 
 	/*
-	 * Maximal divisor is 1023 * 16 when using default (x16) scheme.
-	 * Maximum achievable frequency with simple baudrate divisor is 230400.
-	 * Since the error per bit frame would be of more than 15%, achieving
-	 * higher frequencies would require to implement the fractional divisor
-	 * feature.
+	 * Maximal divisor is 1023 and maximal fractional divisor is 63. And
+	 * experiments showed that baudrates above 1/80 of base clock are not
+	 * stable and usable. So disallow baudrate above 1/80 of the base clock.
+	 * When port->uartclk is not available then mvebu_uart_baud_rate_set()
+	 * fails so values min_baud and max_baud in this case does not matter.
 	 */
-	min_baud = DIV_ROUND_UP(port->uartclk, 1023 * 16);
-	max_baud = 230400;
+	min_baud = DIV_ROUND_UP(port->uartclk, BRDV_BAUD_MAX*OSAMP_MAX_DIVISOR);
+	max_baud = port->uartclk / 80;
 
 	baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud);
 	if (mvebu_uart_baud_rate_set(port, baud)) {
@@ -1397,14 +1442,14 @@ static int mvebu_uart_clock_probe(struct platform_device *pdev)
 			 * Calculate the smallest TBG d1 and d2 divisors that
 			 * still can provide 9600 baudrate.
 			 */
-			d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+			d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_MAX_DIVISOR *
 						BRDV_BAUD_MAX);
 			if (d1 < 1)
 				d1 = 1;
 			else if (d1 > CLK_TBG_DIV1_MAX)
 				d1 = CLK_TBG_DIV1_MAX;
 
-			d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR *
+			d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_MAX_DIVISOR *
 						BRDV_BAUD_MAX * d1);
 			if (d2 < 1)
 				d2 = 1;
@@ -1419,7 +1464,7 @@ static int mvebu_uart_clock_probe(struct platform_device *pdev)
 		}
 
 		/* Skip clock source which cannot provide 9600 baudrate */
-		if (rate > 9600 * OSAMP_DEFAULT_DIVISOR * BRDV_BAUD_MAX * d1 * d2)
+		if (rate > 9600 * OSAMP_MAX_DIVISOR * BRDV_BAUD_MAX * d1 * d2)
 			continue;
 
 		/*
-- 
2.20.1



From will at kernel.org  Mon Aug  9 07:56:51 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 15:56:51 +0100
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent
 masters to use system cache
In-Reply-To: <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
References: <cover.1610372717.git.saiprakash.ranjan@codeaurora.org>
 <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
 <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
Message-ID: <20210809145651.GC1458@willie-the-truck>

On Mon, Aug 02, 2021 at 06:36:04PM -0700, Rob Clark wrote:
> On Mon, Aug 2, 2021 at 8:14 AM Will Deacon <will at kernel.org> wrote:
> >
> > On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> > > On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> > > >
> > > > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> > > > > On 2021-07-28 19:30, Georgi Djakov wrote:
> > > > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > > > > > the memory type setting required for the non-coherent masters to use
> > > > > > > system cache. Now that system cache support for GPU is added, we will
> > > > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > > > > > Without this, the system cache lines are not allocated for GPU.
> > > > > > >
> > > > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > > > > > and makes GPU the user of this protection flag.
> > > > > >
> > > > > > Thank you for the patchset! Are you planning to refresh it, as it does
> > > > > > not apply anymore?
> > > > > >
> > > > >
> > > > > I was waiting on Will's reply [1]. If there are no changes needed, then
> > > > > I can repost the patch.
> > > >
> > > > I still think you need to handle the mismatched alias, no? You're adding
> > > > a new memory type to the SMMU which doesn't exist on the CPU side. That
> > > > can't be right.
> > > >
> > >
> > > Just curious, and maybe this is a dumb question, but what is your
> > > concern about mismatched aliases?  I mean the cache hierarchy on the
> > > GPU device side (anything beyond the LLC) is pretty different and
> > > doesn't really care about the smmu pgtable attributes..
> >
> > If the CPU accesses a shared buffer with different attributes to those which
> > the device is using then you fall into the "mismatched memory attributes"
> > part of the Arm architecture. It's reasonably unforgiving (you should go and
> > read it) and in some cases can apply to speculative accesses as well, but
> > the end result is typically loss of coherency.
> 
> Ok, I might have a few other sections to read first to decipher the
> terminology..
> 
> But my understanding of LLC is that it looks just like system memory
> to the CPU and GPU (I think that would make it "the point of
> coherence" between the GPU and CPU?)  If that is true, shouldn't it be
> invisible from the point of view of different CPU mapping options?

You could certainly build a system where mismatched attributes don't cause
loss of coherence, but as it's not guaranteed by the architecture and the
changes proposed here affect APIs which are exposed across SoCs, then I
don't think it helps much.

Will


From kishon at ti.com  Mon Aug  9 07:58:38 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Mon, 9 Aug 2021 20:28:38 +0530
Subject: [PATCH v2 2/3] PCI: j721e: Add PCI legacy interrupt support for
 J721E
In-Reply-To: <87o8a7arew.wl-maz@kernel.org>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-3-kishon@ti.com> <87h7g5w8d8.wl-maz@kernel.org>
 <c20be7ae-e4a7-c3ba-f1c9-e4ff2aae0a66@ti.com> <87o8a7arew.wl-maz@kernel.org>
Message-ID: <7646c75e-29de-1edc-225c-57feeaa80118@ti.com>

Hi Marc,

On 09/08/21 3:09 pm, Marc Zyngier wrote:
> On Mon, 09 Aug 2021 05:50:10 +0100,
> Kishon Vijay Abraham I <kishon at ti.com> wrote:
>>
>> Hi Marc,
>>
>> On 04/08/21 8:43 pm, Marc Zyngier wrote:
>>> On Wed, 04 Aug 2021 14:29:11 +0100,
>>> Kishon Vijay Abraham I <kishon at ti.com> wrote:
>>>>
>>>> Add PCI legacy interrupt support for J721E. J721E has a single HW
>>>> interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
>>>> The HW interrupt line connected to GIC is a pulse interrupt whereas
>>>> the legacy interrupts by definition is level interrupt. In order to
>>>> provide level interrupt functionality to edge interrupt line, PCIe
>>>> in J721E has provided IRQ_EOI register.
>>>>
>>>> However due to Errata ID #i2094 ([1]), EOI feature is not enabled in HW
>>>> and only a single pulse interrupt will be generated for every
>>>> ASSERT_INTx/DEASSERT_INTx.
>>>
>>> So my earlier remark stands. If you get a single edge, how do you
>>> handle a level that is still high after having handled the interrupt
>>> on hardware that has this bug?
>>
>> Right, this hardware (J721E) has a bug but was fixed in J7200 (Patch 3/3
>> handles that).
> 
> But how do you make it work with J721E? Is it even worth supporting if
> (as I expect) it is unreliable?

I've seen at-least the NVMe devices triggers the interrupts again and
the data transfer completes. But I agree, this is unreliable.
> 
>>>
>>>>
>>>> [1] -> J721E DRA829/TDA4VM Processors Silicon Revision 1.1/1.0 SPRZ455A ?
>>>>        DECEMBER 2020 ? REVISED AUGUST 2021
>>>>        (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf)
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>>>> ---
>>>>  drivers/pci/controller/cadence/pci-j721e.c | 85 ++++++++++++++++++++++
>>>>  1 file changed, 85 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
>>>> index 2ec037c43bd5..c2e7a78dc31f 100644
>>>> --- a/drivers/pci/controller/cadence/pci-j721e.c
>>>> +++ b/drivers/pci/controller/cadence/pci-j721e.c
>>>> @@ -29,6 +29,13 @@
>>>>  #define LINK_DOWN		BIT(1)
>>>>  #define J7200_LINK_DOWN		BIT(10)
>>>>  
>>>> +#define EOI_REG			0x10
>>>> +
>>>> +#define ENABLE_REG_SYS_0	0x100
>>>> +#define STATUS_REG_SYS_0	0x500
>>>> +#define STATUS_CLR_REG_SYS_0	0x700
>>>> +#define INTx_EN(num)		(1 << (num))
>>>> +
>>>>  #define J721E_PCIE_USER_CMD_STATUS	0x4
>>>>  #define LINK_TRAINING_ENABLE		BIT(0)
>>>>  
>>>> @@ -59,6 +66,7 @@ struct j721e_pcie {
>>>>  	void __iomem		*user_cfg_base;
>>>>  	void __iomem		*intd_cfg_base;
>>>>  	u32			linkdown_irq_regfield;
>>>> +	struct irq_domain	*legacy_irq_domain;
>>>>  };
>>>>  
>>>>  enum j721e_pcie_mode {
>>>> @@ -121,6 +129,79 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
>>>>  	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
>>>>  }
>>>>  
>>>> +static void j721e_pcie_v1_legacy_irq_handler(struct irq_desc *desc)
>>>> +{
>>>> +	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
>>>> +	struct irq_chip *chip = irq_desc_get_chip(desc);
>>>> +	int i, virq;
>>>> +	u32 reg;
>>>> +
>>>> +	chained_irq_enter(chip, desc);
>>>> +
>>>> +	for (i = 0; i < PCI_NUM_INTX; i++) {
>>>> +		reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_0);
>>>> +		if (!(reg & INTx_EN(i)))
>>>> +			continue;
>>>
>>> Why do you need to perform multiple reads? Surely reg contains all the
>>> bits you need, doesn't it?
>>
>> Right, will fix it up.
>>>
>>>> +
>>>> +		virq = irq_find_mapping(pcie->legacy_irq_domain, 3 - i);
>>>> +		generic_handle_irq(virq);
>>>
>>> Please combine both lines into a single generic_handle_domain_irq()
>>> call.
>>
>> Okay.
>>>
>>>> +		j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_0, INTx_EN(i));
>>>
>>> What is the purpose of this write? It feels like this should be a
>>> irq_eoi callback.
>>
>> It's an IRQ ACK, since in this platform the level to edge is not
>> implemented properly in HW.
> 
> An Ack for an edge interrupt would need to happen before you handle
> the interrupt, or you'd wrongly acknowledge edges that fire between
> the handling of the interrupt and the Ack, and that would never be
> handled.
> 
> If it really is an Ack, it needs to be moved *before* the handling,
> preferably in an irq_ack callback. Otherwise, it is an EOI, and it
> belongs to irq_eoi.
> 
>>>
>>>> +	}
>>>> +
>>>> +	chained_irq_exit(chip, desc);
>>>> +}
>>>> +
>>>> +static int j721e_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq)
>>>> +{
>>>> +	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
>>>
>>> An INTx interrupt is a level interrupt. Please use the corresponding flow.
>>
>> Okay.
>>>
>>>> +	irq_set_chip_data(irq, domain->host_data);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static const struct irq_domain_ops j721e_pcie_intx_domain_ops = {
>>>> +	.map = j721e_pcie_intx_map,
>>>> +};
>>>> +
>>>> +static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
>>>> +{
>>>> +	struct irq_domain *legacy_irq_domain;
>>>> +	struct device *dev = pcie->dev;
>>>> +	struct device_node *node = dev->of_node;
>>>> +	struct device_node *intc_node;
>>>> +	int irq, i;
>>>> +	u32 reg;
>>>> +
>>>> +	intc_node = of_get_child_by_name(node, "interrupt-controller");
>>>> +	if (!intc_node) {
>>>> +		dev_dbg(dev, "interrupt-controller node is absent. Legacy INTR not supported\n");
>>>> +		return 0;
>>>> +	}
>>>> +
>>>> +	irq = irq_of_parse_and_map(intc_node, 0);
>>>> +	if (!irq) {
>>>> +		dev_err(dev, "Failed to parse and map legacy irq\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +	irq_set_chained_handler_and_data(irq, j721e_pcie_v1_legacy_irq_handler, pcie);
>>>> +
>>>> +	legacy_irq_domain = irq_domain_add_linear(intc_node, PCI_NUM_INTX,
>>>> +						  &j721e_pcie_intx_domain_ops, pcie);
>>>> +	if (!legacy_irq_domain) {
>>>> +		dev_err(dev, "Failed to add irq domain for legacy irqs\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +	pcie->legacy_irq_domain = legacy_irq_domain;
>>>> +
>>>> +	for (i = 0; i < PCI_NUM_INTX; i++) {
>>>> +		reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_0);
>>>> +		reg |= INTx_EN(i);
>>>> +		j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_0, reg);
>>>> +	}
>>>
>>> This should be moved to the irq_unmask() callback.
>>
>> Should we also have a corresponding irq_mask()? Then would require us
>> implement reference counting since legacy interrupts are shared.
> 
> The core code should already deal with this, I expect. It isn't like
> shared interrupts are something new. And yes, you should have both
> mask and unmask.

Thanks for clarifying.

Best Regards,
Kishon


From robh at kernel.org  Mon Aug  9 08:02:25 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 9 Aug 2021 09:02:25 -0600
Subject: [PATCH v2 39/40] PCI: dwc: Move N_FTS setup to common setup
In-Reply-To: <d7146c20-6992-44a0-c390-f801d352cf15@nvidia.com>
References: <20200821035420.380495-1-robh@kernel.org>
 <20200821035420.380495-40-robh@kernel.org>
 <d7146c20-6992-44a0-c390-f801d352cf15@nvidia.com>
Message-ID: <CAL_Jsq+=AyqU-GPvt_cfDPpe0Grs2ez9BH7HvqyiPNgB6QTkYw@mail.gmail.com>

On Sun, Aug 8, 2021 at 9:01 AM Vidya Sagar <vidyas at nvidia.com> wrote:
>
>
>
> On 8/21/2020 9:24 AM, Rob Herring wrote:
> > The Designware controller has common registers to set number of fast
> > training sequence ordered sets. The Artpec6, Intel, and Tegra driver
> > initialize these register fields. Let's move the initialization to the
> > common setup code and drivers just have to provide the value.
> >
> > There's a slight change in that the common clock mode N_FTS field is
> > now initialized. Previously only the Intel driver set this. It's not
> > clear from the code if common clock mode is used in the Artpec6 or Tegra
> > driver. It depends on the DWC configuration. Given the field is not
> > initialized while the others are, it seems unlikely common clock mode
> > is used.
> >
> > Cc: Jesper Nilsson <jesper.nilsson at axis.com>
> > Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Cc: Bjorn Helgaas <bhelgaas at google.com>
> > Cc: Jingoo Han <jingoohan1 at gmail.com>
> > Cc: Gustavo Pimentel <gustavo.pimentel at synopsys.com>
> > Cc: Thierry Reding <thierry.reding at gmail.com>
> > Cc: Jonathan Hunter <jonathanh at nvidia.com>
> > Cc: linux-tegra at vger.kernel.org
> > Signed-off-by: Rob Herring <robh at kernel.org>
> > ---
> >   drivers/pci/controller/dwc/pcie-artpec6.c    | 37 +++-----------------
> >   drivers/pci/controller/dwc/pcie-designware.c | 28 +++++++++------
> >   drivers/pci/controller/dwc/pcie-designware.h |  3 +-
> >   drivers/pci/controller/dwc/pcie-intel-gw.c   | 27 +++++---------
> >   drivers/pci/controller/dwc/pcie-tegra194.c   | 25 ++-----------
> >   5 files changed, 35 insertions(+), 85 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
> > index 86f4d66d8587..929448e9e0bc 100644
> > --- a/drivers/pci/controller/dwc/pcie-artpec6.c
> > +++ b/drivers/pci/controller/dwc/pcie-artpec6.c
> > @@ -44,13 +44,6 @@ struct artpec_pcie_of_data {
> >
> >   static const struct of_device_id artpec6_pcie_of_match[];
> >
> > -/* PCIe Port Logic registers (memory-mapped) */
> > -#define PL_OFFSET                    0x700
> > -
> > -#define ACK_F_ASPM_CTRL_OFF          (PL_OFFSET + 0xc)
> > -#define ACK_N_FTS_MASK                       GENMASK(15, 8)
> > -#define ACK_N_FTS(x)                 (((x) << 8) & ACK_N_FTS_MASK)
> > -
> >   /* ARTPEC-6 specific registers */
> >   #define PCIECFG                             0x18
> >   #define  PCIECFG_DBG_OEN            BIT(24)
> > @@ -289,30 +282,6 @@ static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie)
> >       }
> >   }
> >
> > -static void artpec6_pcie_set_nfts(struct artpec6_pcie *artpec6_pcie)
> > -{
> > -     struct dw_pcie *pci = artpec6_pcie->pci;
> > -     u32 val;
> > -
> > -     if (artpec6_pcie->variant != ARTPEC7)
> > -             return;
> > -
> > -     /*
> > -      * Increase the N_FTS (Number of Fast Training Sequences)
> > -      * to be transmitted when transitioning from L0s to L0.
> > -      */
> > -     val = dw_pcie_readl_dbi(pci, ACK_F_ASPM_CTRL_OFF);
> > -     val &= ~ACK_N_FTS_MASK;
> > -     val |= ACK_N_FTS(180);
> > -     dw_pcie_writel_dbi(pci, ACK_F_ASPM_CTRL_OFF, val);
> > -
> > -     /*
> > -      * Set the Number of Fast Training Sequences that the core
> > -      * advertises as its N_FTS during Gen2 or Gen3 link training.
> > -      */
> > -     dw_pcie_link_set_n_fts(pci, 180);
> > -}
> > -
> >   static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
> >   {
> >       u32 val;
> > @@ -351,11 +320,14 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
> >       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> >       struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
> >
> > +     if (artpec6_pcie->variant == ARTPEC7) {
> > +             pci->n_fts[0] = 180;
> > +             pci->n_fts[1] = 180;
> > +     }
> >       artpec6_pcie_assert_core_reset(artpec6_pcie);
> >       artpec6_pcie_init_phy(artpec6_pcie);
> >       artpec6_pcie_deassert_core_reset(artpec6_pcie);
> >       artpec6_pcie_wait_for_phy(artpec6_pcie);
> > -     artpec6_pcie_set_nfts(artpec6_pcie);
> >       dw_pcie_setup_rc(pp);
> >       artpec6_pcie_establish_link(pci);
> >       dw_pcie_wait_for_link(pci);
> > @@ -403,7 +375,6 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
> >       artpec6_pcie_init_phy(artpec6_pcie);
> >       artpec6_pcie_deassert_core_reset(artpec6_pcie);
> >       artpec6_pcie_wait_for_phy(artpec6_pcie);
> > -     artpec6_pcie_set_nfts(artpec6_pcie);
> >
> >       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
> >               dw_pcie_ep_reset_bar(pci, bar);
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > index 61e1faba15bf..3cb21247619c 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -510,17 +510,6 @@ static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen)
> >   }
> >   EXPORT_SYMBOL_GPL(dw_pcie_link_set_max_speed);
> >
> > -void dw_pcie_link_set_n_fts(struct dw_pcie *pci, u32 n_fts)
> > -{
> > -     u32 val;
> > -
> > -     val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
> > -     val &= ~PORT_LOGIC_N_FTS_MASK;
> > -     val |= n_fts & PORT_LOGIC_N_FTS_MASK;
> > -     dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
> > -}
> > -EXPORT_SYMBOL_GPL(dw_pcie_link_set_n_fts);
> > -
> >   static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci)
> >   {
> >       u32 val;
> > @@ -551,6 +540,23 @@ void dw_pcie_setup(struct dw_pcie *pci)
> >       if (pci->link_gen > 0)
> >               dw_pcie_link_set_max_speed(pci, pci->link_gen);
> >
> > +     /* Configure Gen1 N_FTS */
> > +     if (pci->n_fts[0]) {
> > +             val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
> > +             val &= ~(PORT_AFR_N_FTS_MASK | PORT_AFR_CC_N_FTS_MASK);
> > +             val |= PORT_AFR_N_FTS(pci->n_fts[0]);
> > +             val |= PORT_AFR_CC_N_FTS(pci->n_fts[0]);
> > +             dw_pcie_writel_dbi(pci, PCIE_PORT_AFR, val);
> > +     }
> > +
> > +     /* Configure Gen2+ N_FTS */
> > +     if (pci->n_fts[1]) {
> > +             val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
> > +             val &= ~PORT_LOGIC_N_FTS_MASK;
> > +             val |= pci->n_fts[pci->link_gen - 1];
> Apologies for getting late to this change given that the change has
> already been merged.
> I'm wondering why is it that link_gen has to be used in deriving the
> index instead of directly using '1' as the index?
> Infact the for link speed greater than 2, accesses go beyond n_fts[]
> array boundaries.
> Since the if() check is done based on a non-zero value of pci->n_fts[1],
> shouldn't the same be used for programming also?

Yes, I think you are right.

Rob


From broonie at kernel.org  Mon Aug  9 08:02:54 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon,  9 Aug 2021 16:02:54 +0100
Subject: [PATCH 1/1] spi: mediatek: fix build warnning in set cs timing
In-Reply-To: <20210809055911.17538-1-Mason.Zhang@mediatek.com>
References: <20210809055911.17538-1-Mason.Zhang@mediatek.com>
Message-ID: <162852121764.46095.11307268331804449714.b4-ty@kernel.org>

On Mon, 9 Aug 2021 13:59:12 +0800, Mason Zhang wrote:
> this patch fixed the build warnning in set cs timing.
> 
> 
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: mediatek: fix build warnning in set cs timing
      commit: 5c842e51ac63130a1344650b0a95bdc398666947

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From geert at linux-m68k.org  Mon Aug  9 08:07:11 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 9 Aug 2021 17:07:11 +0200
Subject: [PATCH v4.1] include: linux: Reorganize timekeeping and ktime
 headers
In-Reply-To: <3bdd5b29-b6a1-54a8-ac99-adb59e8e91a7@vt.edu>
References: <202108010312.8uIaWK0u-lkp@intel.com>
 <3bdd5b29-b6a1-54a8-ac99-adb59e8e91a7@vt.edu>
Message-ID: <CAMuHMdXueYTAYFgt-gP79e1NaFzmPmsE1if+DsiZaB5VmNqCXA@mail.gmail.com>

On Sun, Aug 1, 2021 at 10:13 PM Carlos Bilbao <bilbao at vt.edu> wrote:
> Reorganize and separate the headers by making ktime.h take care of the
> ktime_get() family of functions, and reserve timekeeping.h for the actual
> timekeeping. This also helps to avoid implicit function errors and strengthens
> the header dependencies, since timekeeping.h was using ktime_to_ns(), a static
> function defined in a header it does no include, ktime.h. Include the header
> timekeeping.h wherever it is necessary for a successful compilation after the
> header code reorganization.
>
> Signed-off-by: Carlos Bilbao <bilbao at vt.edu>
> Reported-by: kernel test robot <lkp at intel.com>

>  arch/m68k/atari/time.c         |   1 +
>  arch/m68k/hp300/time.c         |   2 +
>  arch/m68k/mac/via.c            |   1 +
>  arch/m68k/mvme16x/config.c     |   1 +
>  arch/m68k/sun3/sun3ints.c      |   1 +

Acked-by: Geert Uytterhoeven <geert at linux-m68k.org>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From oupton at google.com  Mon Aug  9 08:08:19 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 08:08:19 -0700
Subject: [PATCH v2] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <87mtpqc2wz.wl-maz@kernel.org>
References: <20210807191428.3488948-1-oupton@google.com>
 <CACRpkdYPEGygxAtU8jrCtnJsQr_JoYkBCRGpRFpvxGiOzUmxgg@mail.gmail.com>
 <CAOQ_QsiECN7iVDyiyos12tk__viGkFhH9b6ZfkZVAYjeKhB=pQ@mail.gmail.com>
 <87lf5c1aox.wl-maz@kernel.org>
 <CAOQ_Qsi-r0=YubmaTezB7Cq-RhzU3njWm+P5w-RWZcUz4kMfDA@mail.gmail.com>
 <87mtpqc2wz.wl-maz@kernel.org>
Message-ID: <CAOQ_QsiKttAwrGKuXKHmuXac4ANaJd79KNQAFwuD6h_VztJu+A@mail.gmail.com>

On Mon, Aug 9, 2021 at 3:45 AM Marc Zyngier <maz at kernel.org> wrote:
> > On that note, I wonder how (if ever) we will be able to move away from
> > unnecessarily masking a 64 bit counter, i.e. a v8.6 or above
> > implementation. With this patch, one such counter would wrap after
> > 36.56 years, short of the 40 year guarantee we have from the
> > architecture for < v8.6 implementations. Getting it to 64 bits would
> > squarely make it someone else's problem ~585 years from now :)
>
> Hmmm. If you end-up with something that falls short of 40 years, then
> I suspect something is wrong in the way you compute the required
> width.
>
> 40 years @1GHz (which we shall call FY1G from now on) fits comfortably
> in 61 bits, and I fear that your use of ilog2() gives you one less bit
> than what it should be:
>
> log2(FY1G) ~= 60.13

Right, this is round-down behavior was deliberate. Reading the ARM ARM
D11.1.2 'The system counter', I did not find any language that
suggested the counter saturates the register width before rolling
over. So, it may be paranoid, but I presumed it to be safer to wrap
within the guaranteed interval rather than assume the sanity of the
system counter implementation. That being said, fine with rounding up
instead, so long as we don't believe there's any chance of hardware
doing something crazy.

--
Thanks,
Oliver
> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


From david at ixit.cz  Mon Aug  9 08:10:21 2021
From: david at ixit.cz (David Heidelberg)
Date: Mon,  9 Aug 2021 17:10:21 +0200
Subject: [PATCH] ARM: atags_to_fdt: don't warn about stack size
Message-ID: <20210809151021.5137-1-david@ixit.cz>

The merge_fdt_bootargs() function by definition consumes more than 1024
bytes of stack because it has a 1024 byte command line on the stack,
meaning that we always get a warning when building this file:

arch/arm/boot/compressed/atags_to_fdt.c: In function 'merge_fdt_bootargs':
arch/arm/boot/compressed/atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 1024 bytes [-Wframe-larger-than=]

However, as this is the decompressor and we know that it has a very shallow
call chain, and we do not actually risk overflowing the kernel stack
at runtime here.

This just shuts up the warning by disabling the warning flag for this
file.

Tested on Nexus 7 2012 builds.

Original Author: Arnd Bergmann <arnd at arndb.de>
Reference: https://lore.kernel.org/lkml/8232115.18ykgQ6J5T at wuerfel/

Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Nicolas Pitre <nico at linaro.org>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org

Signed-off-by: David Heidelberg <david at ixit.cz>
---
 arch/arm/boot/compressed/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 9d91ae1091b0..91265e7ff672 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -85,6 +85,8 @@ compress-$(CONFIG_KERNEL_LZ4)  = lz4
 libfdt_objs := fdt_rw.o fdt_ro.o fdt_wip.o fdt.o
 
 ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
+CFLAGS_REMOVE_atags_to_fdt.o += -Wframe-larger-than=${CONFIG_FRAME_WARN}
+CFLAGS_atags_to_fdt.o += -Wframe-larger-than=1280
 OBJS	+= $(libfdt_objs) atags_to_fdt.o
 endif
 ifeq ($(CONFIG_USE_OF),y)
-- 
2.30.2



From geert at linux-m68k.org  Mon Aug  9 08:15:17 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 9 Aug 2021 17:15:17 +0200
Subject: [PATCH 1/3] arch: Export machine_restart() instances so they can
 be called from modules
In-Reply-To: <20210803155452.435812-2-lee.jones@linaro.org>
References: <20210803155452.435812-1-lee.jones@linaro.org>
 <20210803155452.435812-2-lee.jones@linaro.org>
Message-ID: <CAMuHMdXpYV+pbiOwiCjZ+aZYR-xPDGkeANfLt0fwhg4zevAKgg@mail.gmail.com>

On Tue, Aug 3, 2021 at 5:56 PM Lee Jones <lee.jones at linaro.org> wrote:
> A recent attempt to convert the Power Reset Restart driver to tristate
> failed because of the following compile error (reported once merged by
> Stephen Rothwell via Linux Next):
>
>   ERROR: "machine_restart" [drivers/power/reset/restart-poweroff.ko] undefined!
>
> This error occurs since some of the machine_restart() instances are
> not currently exported for use in modules.  This patch aims to rectify
> that.
>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>

> NB: If it's safe to omit some of these, let me know and I'll revise the patch.

How do you plan to handle that? Isn't this an all-or-nothing export?

>  arch/m68k/kernel/process.c         | 1 +

Acked-by: Geert Uytterhoeven <geert at linux-m68k.org>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From hch at lst.de  Mon Aug  9 08:16:22 2021
From: hch at lst.de (Christoph Hellwig)
Date: Mon, 9 Aug 2021 17:16:22 +0200
Subject: [PATCH v3 00/21] .map_sg() error cleanup
In-Reply-To: <20210729201539.5602-1-logang@deltatee.com>
References: <20210729201539.5602-1-logang@deltatee.com>
Message-ID: <20210809151622.GB22445@lst.de>

Thanks,

I've applied this to the dma-mapping tree with a few minor cosmetic
tweaks.


From idosch at idosch.org  Mon Aug  9 08:16:23 2021
From: idosch at idosch.org (Ido Schimmel)
Date: Mon, 9 Aug 2021 18:16:23 +0300
Subject: [PATCH net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <20210809131152.509092-1-vladimir.oltean@nxp.com>
References: <20210809131152.509092-1-vladimir.oltean@nxp.com>
Message-ID: <YRFGxxkNyJDxoGWu@shredder>

On Mon, Aug 09, 2021 at 04:11:52PM +0300, Vladimir Oltean wrote:
> The blamed commit a new field to struct switchdev_notifier_fdb_info, but
> did not make sure that all call paths set it to something valid. For
> example, a switchdev driver may emit a SWITCHDEV_FDB_ADD_TO_BRIDGE
> notifier, and since the 'is_local' flag is not set, it contains junk
> from the stack, so the bridge might interpret those notifications as
> being for local FDB entries when that was not intended.
> 
> To avoid that now and in the future, zero-initialize all
> switchdev_notifier_fdb_info structures created by drivers such that all
> newly added fields to not need to touch drivers again.
> 
> Fixes: 2c4eca3ef716 ("net: bridge: switchdev: include local flag in FDB notifications")
> Reported-by: Ido Schimmel <idosch at idosch.org>
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>

Reviewed-by: Ido Schimmel <idosch at nvidia.com>
Tested-by: Ido Schimmel <idosch at nvidia.com>

Thanks


From qperret at google.com  Mon Aug  9 08:24:27 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:27 +0100
Subject: [PATCH v4 00/21] Track shared pages at EL2 in protected mode
Message-ID: <20210809152448.1810400-1-qperret@google.com>

Hi all,

This is v4 of the patch series previously posted here:

https://lore.kernel.org/lkml/20210729132818.4091769-1-qperret at google.com/

This series aims to improve how the nVHE hypervisor tracks ownership of
memory pages when running in protected mode ("kvm-arm.mode=protected" on
the kernel command line).

The main issue with the existing ownership tracking code is that it is
completely binary: a page is either owned by an entity (e.g. the host)
or not. However, we'll need something smarter to track shared pages, as
is needed for virtio, or even just host/hypervisor communications.

This series introduces a few changes to the kvm page-table library to
allow annotating shared pages in ignored bits (a.k.a. software bits) of
leaf entries, and makes use of that infrastructure to track all pages
that are shared between the host and the hypervisor. We will obviously
want to apply the same treatment to guest stage-2 page-tables, but that
is not really possible to do until EL2 manages them directly, so I'll
keep that for another series.

The series is based on the 5.14-rc5, and has been tested on
AML-S905X-CC (Le Potato) and using various Qemu configurations.

Changes since v3
 - Fixed typos in comments / commit messages;
 - Various small cleanups and refactoring;
 - Rebased on 5.14-rc5.

Marc Zyngier (1):
  KVM: arm64: Introduce helper to retrieve a PTE and its level

Quentin Perret (19):
  KVM: arm64: Introduce hyp_assert_lock_held()
  KVM: arm64: Provide the host_stage2_try() helper macro
  KVM: arm64: Expose page-table helpers
  KVM: arm64: Optimize host memory aborts
  KVM: arm64: Rename KVM_PTE_LEAF_ATTR_S2_IGNORED
  KVM: arm64: Don't overwrite software bits with owner id
  KVM: arm64: Tolerate re-creating hyp mappings to set software bits
  KVM: arm64: Enable forcing page-level stage-2 mappings
  KVM: arm64: Allow populating software bits
  KVM: arm64: Add helpers to tag shared pages in SW bits
  KVM: arm64: Expose host stage-2 manipulation helpers
  KVM: arm64: Expose pkvm_hyp_id
  KVM: arm64: Introduce addr_is_memory()
  KVM: arm64: Enable retrieving protections attributes of PTEs
  KVM: arm64: Mark host bss and rodata section as shared
  KVM: arm64: Remove __pkvm_mark_hyp
  KVM: arm64: Refactor protected nVHE stage-1 locking
  KVM: arm64: Restrict EL2 stage-1 changes in protected mode
  KVM: arm64: Make __pkvm_create_mappings static

Will Deacon (1):
  KVM: arm64: Add hyp_spin_is_locked() for basic locking assertions at
    EL2

 arch/arm64/include/asm/kvm_asm.h              |   5 +-
 arch/arm64/include/asm/kvm_pgtable.h          | 167 ++++++++----
 arch/arm64/kvm/Kconfig                        |   9 +
 arch/arm64/kvm/arm.c                          |  46 ----
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  33 ++-
 arch/arm64/kvm/hyp/include/nvhe/mm.h          |   3 +-
 arch/arm64/kvm/hyp/include/nvhe/spinlock.h    |  25 ++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  20 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 225 +++++++++++++---
 arch/arm64/kvm/hyp/nvhe/mm.c                  |  22 +-
 arch/arm64/kvm/hyp/nvhe/setup.c               |  82 +++++-
 arch/arm64/kvm/hyp/pgtable.c                  | 247 +++++++++---------
 arch/arm64/kvm/mmu.c                          |  28 +-
 13 files changed, 628 insertions(+), 284 deletions(-)

-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:28 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:28 +0100
Subject: [PATCH v4 01/21] KVM: arm64: Add hyp_spin_is_locked() for basic
 locking assertions at EL2
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-2-qperret@google.com>

From: Will Deacon <will at kernel.org>

Introduce hyp_spin_is_locked() so that functions can easily assert that
a given lock is held (albeit possibly by another CPU!) without having to
drag full lockdep support up to EL2.

Signed-off-by: Will Deacon <will at kernel.org>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/spinlock.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/spinlock.h b/arch/arm64/kvm/hyp/include/nvhe/spinlock.h
index 76b537f8d1c6..04f65b655fcf 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/spinlock.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/spinlock.h
@@ -15,6 +15,7 @@
 
 #include <asm/alternative.h>
 #include <asm/lse.h>
+#include <asm/rwonce.h>
 
 typedef union hyp_spinlock {
 	u32	__val;
@@ -89,4 +90,11 @@ static inline void hyp_spin_unlock(hyp_spinlock_t *lock)
 	: "memory");
 }
 
+static inline bool hyp_spin_is_locked(hyp_spinlock_t *lock)
+{
+	hyp_spinlock_t lockval = READ_ONCE(*lock);
+
+	return lockval.owner != lockval.next;
+}
+
 #endif /* __ARM64_KVM_NVHE_SPINLOCK_H__ */
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:29 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:29 +0100
Subject: [PATCH v4 02/21] KVM: arm64: Introduce hyp_assert_lock_held()
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-3-qperret@google.com>

Introduce a poor man's lockdep implementation at EL2 which allows to
BUG() whenever a hyp spinlock is not held when it should. Hide this
feature behind a new Kconfig option that targets the EL2 object
specifically, instead of piggy backing on the existing CONFIG_LOCKDEP.
EL2 cannot WARN() cleanly to report locking issues, hence BUG() is the
only option and it is not clear whether we want this widely enabled.
This is most likely going to be useful for local testing until the EL2
WARN() situation has improved.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/Kconfig                     |  9 +++++++++
 arch/arm64/kvm/hyp/include/nvhe/spinlock.h | 17 +++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index a4eba0908bfa..9b9721895e5c 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -46,6 +46,15 @@ if KVM
 
 source "virt/kvm/Kconfig"
 
+config NVHE_EL2_DEBUG
+	bool "Debug mode for non-VHE EL2 object"
+	help
+	  Say Y here to enable the debug mode for the non-VHE KVM EL2 object.
+	  Failure reports will BUG() in the hypervisor. This is intended for
+	  local EL2 hypervisor development.
+
+	  If unsure, say N.
+
 endif # KVM
 
 endif # VIRTUALIZATION
diff --git a/arch/arm64/kvm/hyp/include/nvhe/spinlock.h b/arch/arm64/kvm/hyp/include/nvhe/spinlock.h
index 04f65b655fcf..4652fd04bdbe 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/spinlock.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/spinlock.h
@@ -97,4 +97,21 @@ static inline bool hyp_spin_is_locked(hyp_spinlock_t *lock)
 	return lockval.owner != lockval.next;
 }
 
+#ifdef CONFIG_NVHE_EL2_DEBUG
+static inline void hyp_assert_lock_held(hyp_spinlock_t *lock)
+{
+	/*
+	 * The __pkvm_init() path accesses protected data-structures without
+	 * holding locks as the other CPUs are guaranteed to not enter EL2
+	 * concurrently at this point in time. The point by which EL2 is
+	 * initialized on all CPUs is reflected in the pkvm static key, so
+	 * wait until it is set before checking the lock state.
+	 */
+	if (static_branch_likely(&kvm_protected_mode_initialized))
+		BUG_ON(!hyp_spin_is_locked(lock));
+}
+#else
+static inline void hyp_assert_lock_held(hyp_spinlock_t *lock) { }
+#endif
+
 #endif /* __ARM64_KVM_NVHE_SPINLOCK_H__ */
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:30 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:30 +0100
Subject: [PATCH v4 03/21] KVM: arm64: Provide the host_stage2_try() helper
 macro
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-4-qperret@google.com>

We currently unmap all MMIO mappings from the host stage-2 to recycle
the pages whenever we run out. In order to make this pattern easy to
re-use from other places, factor the logic out into a dedicated macro.
While at it, apply the macro for the kvm_pgtable_stage2_set_owner()
calls. They're currently only called early on and are guaranteed to
succeed, but making them robust to the -ENOMEM case doesn't hurt and
will avoid painful debugging sessions later on.

Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/nvhe/mem_protect.c | 40 +++++++++++++++------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index d938ce95d3bd..74280a753efb 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -208,6 +208,25 @@ static inline int __host_stage2_idmap(u64 start, u64 end,
 				      prot, &host_s2_pool);
 }
 
+/*
+ * The pool has been provided with enough pages to cover all of memory with
+ * page granularity, but it is difficult to know how much of the MMIO range
+ * we will need to cover upfront, so we may need to 'recycle' the pages if we
+ * run out.
+ */
+#define host_stage2_try(fn, ...)					\
+	({								\
+		int __ret;						\
+		hyp_assert_lock_held(&host_kvm.lock);			\
+		__ret = fn(__VA_ARGS__);				\
+		if (__ret == -ENOMEM) {					\
+			__ret = host_stage2_unmap_dev_all();		\
+			if (!__ret)					\
+				__ret = fn(__VA_ARGS__);		\
+		}							\
+		__ret;							\
+	 })
+
 static int host_stage2_idmap(u64 addr)
 {
 	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
@@ -223,22 +242,7 @@ static int host_stage2_idmap(u64 addr)
 	if (ret)
 		goto unlock;
 
-	ret = __host_stage2_idmap(range.start, range.end, prot);
-	if (ret != -ENOMEM)
-		goto unlock;
-
-	/*
-	 * The pool has been provided with enough pages to cover all of memory
-	 * with page granularity, but it is difficult to know how much of the
-	 * MMIO range we will need to cover upfront, so we may need to 'recycle'
-	 * the pages if we run out.
-	 */
-	ret = host_stage2_unmap_dev_all();
-	if (ret)
-		goto unlock;
-
-	ret = __host_stage2_idmap(range.start, range.end, prot);
-
+	ret = host_stage2_try(__host_stage2_idmap, range.start, range.end, prot);
 unlock:
 	hyp_spin_unlock(&host_kvm.lock);
 
@@ -257,8 +261,8 @@ int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
 		return -EINVAL;
 
 	hyp_spin_lock(&host_kvm.lock);
-	ret = kvm_pgtable_stage2_set_owner(&host_kvm.pgt, start, end - start,
-					   &host_s2_pool, pkvm_hyp_id);
+	ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
+			      start, end - start, &host_s2_pool, pkvm_hyp_id);
 	hyp_spin_unlock(&host_kvm.lock);
 
 	return ret != -EAGAIN ? ret : 0;
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:31 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:31 +0100
Subject: [PATCH v4 04/21] KVM: arm64: Introduce helper to retrieve a PTE and
 its level
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-5-qperret@google.com>

From: Marc Zyngier <maz at kernel.org>

It is becoming a common need to fetch the PTE for a given address
together with its level. Add such a helper.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 19 ++++++++++++++
 arch/arm64/kvm/hyp/pgtable.c         | 39 ++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index f004c0115d89..082b9d65f40b 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -432,6 +432,25 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
 int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
 		     struct kvm_pgtable_walker *walker);
 
+/**
+ * kvm_pgtable_get_leaf() - Walk a page-table and retrieve the leaf entry
+ *			    with its level.
+ * @pgt:	Page-table structure initialised by kvm_pgtable_*_init().
+ * @addr:	Input address for the start of the walk.
+ * @ptep:	Pointer to storage for the retrieved PTE.
+ * @level:	Pointer to storage for the level of the retrieved PTE.
+ *
+ * The offset of @addr within a page is ignored.
+ *
+ * The walker will walk the page-table entries corresponding to the input
+ * address specified, retrieving the leaf corresponding to this address.
+ * Invalid entries are treated as leaf entries.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
+			 kvm_pte_t *ptep, u32 *level);
+
 /**
  * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical
  *				     Addresses with compatible permission
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 05321f4165e3..78f36bd5df6c 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -326,6 +326,45 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
 	return _kvm_pgtable_walk(&walk_data);
 }
 
+struct leaf_walk_data {
+	kvm_pte_t	pte;
+	u32		level;
+};
+
+static int leaf_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
+		       enum kvm_pgtable_walk_flags flag, void * const arg)
+{
+	struct leaf_walk_data *data = arg;
+
+	data->pte   = *ptep;
+	data->level = level;
+
+	return 0;
+}
+
+int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
+			 kvm_pte_t *ptep, u32 *level)
+{
+	struct leaf_walk_data data;
+	struct kvm_pgtable_walker walker = {
+		.cb	= leaf_walker,
+		.flags	= KVM_PGTABLE_WALK_LEAF,
+		.arg	= &data,
+	};
+	int ret;
+
+	ret = kvm_pgtable_walk(pgt, ALIGN_DOWN(addr, PAGE_SIZE),
+			       PAGE_SIZE, &walker);
+	if (!ret) {
+		if (ptep)
+			*ptep  = data.pte;
+		if (level)
+			*level = data.level;
+	}
+
+	return ret;
+}
+
 struct hyp_map_data {
 	u64				phys;
 	kvm_pte_t			attr;
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:32 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:32 +0100
Subject: [PATCH v4 05/21] KVM: arm64: Expose page-table helpers
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-6-qperret@google.com>

The KVM pgtable API exposes the kvm_pgtable_walk() function to allow
the definition of walkers outside of pgtable.c. However, it is not easy
to implement any of those walkers without some of the low-level helpers.
Move some of them to the header file to allow re-use from other places.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 40 ++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/pgtable.c         | 39 ---------------------------
 2 files changed, 40 insertions(+), 39 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 082b9d65f40b..6938eac72c1f 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -25,6 +25,46 @@ static inline u64 kvm_get_parange(u64 mmfr0)
 
 typedef u64 kvm_pte_t;
 
+#define KVM_PTE_VALID			BIT(0)
+
+#define KVM_PTE_ADDR_MASK		GENMASK(47, PAGE_SHIFT)
+#define KVM_PTE_ADDR_51_48		GENMASK(15, 12)
+
+static inline bool kvm_pte_valid(kvm_pte_t pte)
+{
+	return pte & KVM_PTE_VALID;
+}
+
+static inline u64 kvm_pte_to_phys(kvm_pte_t pte)
+{
+	u64 pa = pte & KVM_PTE_ADDR_MASK;
+
+	if (PAGE_SHIFT == 16)
+		pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
+
+	return pa;
+}
+
+static inline u64 kvm_granule_shift(u32 level)
+{
+	/* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */
+	return ARM64_HW_PGTABLE_LEVEL_SHIFT(level);
+}
+
+static inline u64 kvm_granule_size(u32 level)
+{
+	return BIT(kvm_granule_shift(level));
+}
+
+static inline bool kvm_level_supports_block_mapping(u32 level)
+{
+	/*
+	 * Reject invalid block mappings and don't bother with 4TB mappings for
+	 * 52-bit PAs.
+	 */
+	return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
+}
+
 /**
  * struct kvm_pgtable_mm_ops - Memory management callbacks.
  * @zalloc_page:		Allocate a single zeroed memory page.
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 78f36bd5df6c..49d768b92997 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -11,16 +11,12 @@
 #include <asm/kvm_pgtable.h>
 #include <asm/stage2_pgtable.h>
 
-#define KVM_PTE_VALID			BIT(0)
 
 #define KVM_PTE_TYPE			BIT(1)
 #define KVM_PTE_TYPE_BLOCK		0
 #define KVM_PTE_TYPE_PAGE		1
 #define KVM_PTE_TYPE_TABLE		1
 
-#define KVM_PTE_ADDR_MASK		GENMASK(47, PAGE_SHIFT)
-#define KVM_PTE_ADDR_51_48		GENMASK(15, 12)
-
 #define KVM_PTE_LEAF_ATTR_LO		GENMASK(11, 2)
 
 #define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX	GENMASK(4, 2)
@@ -61,17 +57,6 @@ struct kvm_pgtable_walk_data {
 	u64				end;
 };
 
-static u64 kvm_granule_shift(u32 level)
-{
-	/* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */
-	return ARM64_HW_PGTABLE_LEVEL_SHIFT(level);
-}
-
-static u64 kvm_granule_size(u32 level)
-{
-	return BIT(kvm_granule_shift(level));
-}
-
 #define KVM_PHYS_INVALID (-1ULL)
 
 static bool kvm_phys_is_valid(u64 phys)
@@ -79,15 +64,6 @@ static bool kvm_phys_is_valid(u64 phys)
 	return phys < BIT(id_aa64mmfr0_parange_to_phys_shift(ID_AA64MMFR0_PARANGE_MAX));
 }
 
-static bool kvm_level_supports_block_mapping(u32 level)
-{
-	/*
-	 * Reject invalid block mappings and don't bother with 4TB mappings for
-	 * 52-bit PAs.
-	 */
-	return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
-}
-
 static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level)
 {
 	u64 granule = kvm_granule_size(level);
@@ -135,11 +111,6 @@ static u32 kvm_pgd_pages(u32 ia_bits, u32 start_level)
 	return __kvm_pgd_page_idx(&pgt, -1ULL) + 1;
 }
 
-static bool kvm_pte_valid(kvm_pte_t pte)
-{
-	return pte & KVM_PTE_VALID;
-}
-
 static bool kvm_pte_table(kvm_pte_t pte, u32 level)
 {
 	if (level == KVM_PGTABLE_MAX_LEVELS - 1)
@@ -151,16 +122,6 @@ static bool kvm_pte_table(kvm_pte_t pte, u32 level)
 	return FIELD_GET(KVM_PTE_TYPE, pte) == KVM_PTE_TYPE_TABLE;
 }
 
-static u64 kvm_pte_to_phys(kvm_pte_t pte)
-{
-	u64 pa = pte & KVM_PTE_ADDR_MASK;
-
-	if (PAGE_SHIFT == 16)
-		pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
-
-	return pa;
-}
-
 static kvm_pte_t kvm_phys_to_pte(u64 pa)
 {
 	kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK;
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:33 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:33 +0100
Subject: [PATCH v4 06/21] KVM: arm64: Optimize host memory aborts
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-7-qperret@google.com>

The kvm_pgtable_stage2_find_range() function is used in the host memory
abort path to try and look for the largest block mapping that can be
used to map the faulting address. In order to do so, the function
currently walks the stage-2 page-table and looks for existing
incompatible mappings within the range of the largest possible block.
If incompatible mappings are found, it tries the same procedure again,
but using a smaller block range, and repeats until a matching range is
found (potentially up to page granularity). While this approach has
benefits (mostly in the fact that it proactively coalesces host stage-2
mappings), it can be slow if the ranges are fragmented, and it isn't
optimized to deal with CPUs faulting on the same IPA as all of them will
do all the work every time.

To avoid these issues, remove kvm_pgtable_stage2_find_range(), and walk
the page-table only once in the host_mem_abort() path to find the
closest leaf to the input address. With this, use the corresponding
range if it is invalid and not owned by another entity. If a valid leaf
is found, return -EAGAIN similar to what is done in the
kvm_pgtable_stage2_map() path to optimize concurrent faults.

Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h  | 30 -----------
 arch/arm64/kvm/hyp/nvhe/mem_protect.c | 45 +++++++++++++++-
 arch/arm64/kvm/hyp/pgtable.c          | 74 ---------------------------
 3 files changed, 44 insertions(+), 105 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 6938eac72c1f..83c5c97d9eac 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -154,16 +154,6 @@ enum kvm_pgtable_prot {
 #define PAGE_HYP_RO		(KVM_PGTABLE_PROT_R)
 #define PAGE_HYP_DEVICE		(PAGE_HYP | KVM_PGTABLE_PROT_DEVICE)
 
-/**
- * struct kvm_mem_range - Range of Intermediate Physical Addresses
- * @start:	Start of the range.
- * @end:	End of the range.
- */
-struct kvm_mem_range {
-	u64 start;
-	u64 end;
-};
-
 /**
  * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk.
  * @KVM_PGTABLE_WALK_LEAF:		Visit leaf entries, including invalid
@@ -490,24 +480,4 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
  */
 int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
 			 kvm_pte_t *ptep, u32 *level);
-
-/**
- * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical
- *				     Addresses with compatible permission
- *				     attributes.
- * @pgt:	Page-table structure initialised by kvm_pgtable_stage2_init*().
- * @addr:	Address that must be covered by the range.
- * @prot:	Protection attributes that the range must be compatible with.
- * @range:	Range structure used to limit the search space at call time and
- *		that will hold the result.
- *
- * The offset of @addr within a page is ignored. An IPA is compatible with @prot
- * iff its corresponding stage-2 page-table entry has default ownership and, if
- * valid, is mapped with protection attributes identical to @prot.
- *
- * Return: 0 on success, negative error code on failure.
- */
-int kvm_pgtable_stage2_find_range(struct kvm_pgtable *pgt, u64 addr,
-				  enum kvm_pgtable_prot prot,
-				  struct kvm_mem_range *range);
 #endif	/* __ARM64_KVM_PGTABLE_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 74280a753efb..2148d3968aa5 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -159,6 +159,11 @@ static int host_stage2_unmap_dev_all(void)
 	return kvm_pgtable_stage2_unmap(pgt, addr, BIT(pgt->ia_bits) - addr);
 }
 
+struct kvm_mem_range {
+	u64 start;
+	u64 end;
+};
+
 static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range)
 {
 	int cur, left = 0, right = hyp_memblock_nr;
@@ -227,6 +232,44 @@ static inline int __host_stage2_idmap(u64 start, u64 end,
 		__ret;							\
 	 })
 
+static inline bool range_included(struct kvm_mem_range *child,
+				  struct kvm_mem_range *parent)
+{
+	return parent->start <= child->start && child->end <= parent->end;
+}
+
+static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
+{
+	struct kvm_mem_range cur;
+	kvm_pte_t pte;
+	u32 level;
+	int ret;
+
+	hyp_assert_lock_held(&host_kvm.lock);
+	ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, &level);
+	if (ret)
+		return ret;
+
+	if (kvm_pte_valid(pte))
+		return -EAGAIN;
+
+	if (pte)
+		return -EPERM;
+
+	do {
+		u64 granule = kvm_granule_size(level);
+		cur.start = ALIGN_DOWN(addr, granule);
+		cur.end = cur.start + granule;
+		level++;
+	} while ((level < KVM_PGTABLE_MAX_LEVELS) &&
+			!(kvm_level_supports_block_mapping(level) &&
+			  range_included(&cur, range)));
+
+	*range = cur;
+
+	return 0;
+}
+
 static int host_stage2_idmap(u64 addr)
 {
 	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
@@ -238,7 +281,7 @@ static int host_stage2_idmap(u64 addr)
 		prot |= KVM_PGTABLE_PROT_X;
 
 	hyp_spin_lock(&host_kvm.lock);
-	ret = kvm_pgtable_stage2_find_range(&host_kvm.pgt, addr, prot, &range);
+	ret = host_stage2_adjust_range(addr, &range);
 	if (ret)
 		goto unlock;
 
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 49d768b92997..4dff2ad39ee4 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -1102,77 +1102,3 @@ void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
 	pgt->mm_ops->free_pages_exact(pgt->pgd, pgd_sz);
 	pgt->pgd = NULL;
 }
-
-#define KVM_PTE_LEAF_S2_COMPAT_MASK	(KVM_PTE_LEAF_ATTR_S2_PERMS | \
-					 KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR | \
-					 KVM_PTE_LEAF_ATTR_S2_IGNORED)
-
-static int stage2_check_permission_walker(u64 addr, u64 end, u32 level,
-					  kvm_pte_t *ptep,
-					  enum kvm_pgtable_walk_flags flag,
-					  void * const arg)
-{
-	kvm_pte_t old_attr, pte = *ptep, *new_attr = arg;
-
-	/*
-	 * Compatible mappings are either invalid and owned by the page-table
-	 * owner (whose id is 0), or valid with matching permission attributes.
-	 */
-	if (kvm_pte_valid(pte)) {
-		old_attr = pte & KVM_PTE_LEAF_S2_COMPAT_MASK;
-		if (old_attr != *new_attr)
-			return -EEXIST;
-	} else if (pte) {
-		return -EEXIST;
-	}
-
-	return 0;
-}
-
-int kvm_pgtable_stage2_find_range(struct kvm_pgtable *pgt, u64 addr,
-				  enum kvm_pgtable_prot prot,
-				  struct kvm_mem_range *range)
-{
-	kvm_pte_t attr;
-	struct kvm_pgtable_walker check_perm_walker = {
-		.cb		= stage2_check_permission_walker,
-		.flags		= KVM_PGTABLE_WALK_LEAF,
-		.arg		= &attr,
-	};
-	u64 granule, start, end;
-	u32 level;
-	int ret;
-
-	ret = stage2_set_prot_attr(pgt, prot, &attr);
-	if (ret)
-		return ret;
-	attr &= KVM_PTE_LEAF_S2_COMPAT_MASK;
-
-	for (level = pgt->start_level; level < KVM_PGTABLE_MAX_LEVELS; level++) {
-		granule = kvm_granule_size(level);
-		start = ALIGN_DOWN(addr, granule);
-		end = start + granule;
-
-		if (!kvm_level_supports_block_mapping(level))
-			continue;
-
-		if (start < range->start || range->end < end)
-			continue;
-
-		/*
-		 * Check the presence of existing mappings with incompatible
-		 * permissions within the current block range, and try one level
-		 * deeper if one is found.
-		 */
-		ret = kvm_pgtable_walk(pgt, start, granule, &check_perm_walker);
-		if (ret != -EEXIST)
-			break;
-	}
-
-	if (!ret) {
-		range->start = start;
-		range->end = end;
-	}
-
-	return ret;
-}
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:34 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:34 +0100
Subject: [PATCH v4 07/21] KVM: arm64: Rename KVM_PTE_LEAF_ATTR_S2_IGNORED
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-8-qperret@google.com>

The ignored bits for both stage-1 and stage-2 page and block
descriptors are in [55:58], so rename KVM_PTE_LEAF_ATTR_S2_IGNORED to
make it applicable to both. And while at it, since these bits are more
commonly known as 'software' bits, rename accordingly.

Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/pgtable.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 4dff2ad39ee4..59a394d82de3 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -36,6 +36,8 @@
 
 #define KVM_PTE_LEAF_ATTR_HI		GENMASK(63, 51)
 
+#define KVM_PTE_LEAF_ATTR_HI_SW		GENMASK(58, 55)
+
 #define KVM_PTE_LEAF_ATTR_HI_S1_XN	BIT(54)
 
 #define KVM_PTE_LEAF_ATTR_HI_S2_XN	BIT(54)
@@ -44,8 +46,6 @@
 					 KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
 					 KVM_PTE_LEAF_ATTR_HI_S2_XN)
 
-#define KVM_PTE_LEAF_ATTR_S2_IGNORED	GENMASK(58, 55)
-
 #define KVM_INVALID_PTE_OWNER_MASK	GENMASK(63, 56)
 #define KVM_MAX_OWNER_ID		1
 
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:35 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:35 +0100
Subject: [PATCH v4 08/21] KVM: arm64: Don't overwrite software bits with owner
 id
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-9-qperret@google.com>

We will soon start annotating page-tables with new flags to track shared
pages and such, and we will do so in valid mappings using software bits
in the PTEs, as provided by the architecture. However, it is possible
that we will need to use those flags to annotate invalid mappings as
well in the future, similar to what we do to track page ownership in the
host stage-2.

In order to facilitate the annotation of invalid mappings with such
flags, it would be preferable to re-use the same bits as for valid
mappings (bits [58-55]), but these are currently used for ownership
encoding. Since we have plenty of bits left to use in invalid
mappings, move the ownership bits further down the PTE to avoid the
conflict.

Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/pgtable.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 59a394d82de3..1ee1168ac32d 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -46,7 +46,7 @@
 					 KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
 					 KVM_PTE_LEAF_ATTR_HI_S2_XN)
 
-#define KVM_INVALID_PTE_OWNER_MASK	GENMASK(63, 56)
+#define KVM_INVALID_PTE_OWNER_MASK	GENMASK(9, 2)
 #define KVM_MAX_OWNER_ID		1
 
 struct kvm_pgtable_walk_data {
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:36 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:36 +0100
Subject: [PATCH v4 09/21] KVM: arm64: Tolerate re-creating hyp mappings to set
 software bits
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-10-qperret@google.com>

The current hypervisor stage-1 mapping code doesn't allow changing an
existing valid mapping. Relax this condition by allowing changes that
only target software bits, as that will soon be needed to annotate shared
pages.

Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/pgtable.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 1ee1168ac32d..2689fcb7901d 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -362,6 +362,21 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
 	return 0;
 }
 
+static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new)
+{
+	/*
+	 * Tolerate KVM recreating the exact same mapping, or changing software
+	 * bits if the existing mapping was valid.
+	 */
+	if (old == new)
+		return false;
+
+	if (!kvm_pte_valid(old))
+		return true;
+
+	return !WARN_ON((old ^ new) & ~KVM_PTE_LEAF_ATTR_HI_SW);
+}
+
 static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level,
 				    kvm_pte_t *ptep, struct hyp_map_data *data)
 {
@@ -371,9 +386,8 @@ static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level,
 	if (!kvm_block_mapping_supported(addr, end, phys, level))
 		return false;
 
-	/* Tolerate KVM recreating the exact same mapping */
 	new = kvm_init_valid_leaf_pte(phys, data->attr, level);
-	if (old != new && !WARN_ON(kvm_pte_valid(old)))
+	if (hyp_pte_needs_update(old, new))
 		smp_store_release(ptep, new);
 
 	data->phys += granule;
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:37 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:37 +0100
Subject: [PATCH v4 10/21] KVM: arm64: Enable forcing page-level stage-2
 mappings
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-11-qperret@google.com>

Much of the stage-2 manipulation logic relies on being able to destroy
block mappings if e.g. installing a smaller mapping in the range. The
rationale for this behaviour is that stage-2 mappings can always be
re-created lazily. However, this gets more complicated when the stage-2
page-table is used to store metadata about the underlying pages. In such
cases, destroying a block mapping may lead to losing part of the state,
and confuse the user of those metadata (such as the hypervisor in nVHE
protected mode).

To avoid this, introduce a callback function in the pgtable struct which
is called during all map operations to determine whether the mappings
can use blocks, or should be forced to page granularity. This is used by
the hypervisor when creating the host stage-2 to force page-level
mappings when using non-default protection attributes.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h  | 66 +++++++++++++++++----------
 arch/arm64/kvm/hyp/nvhe/mem_protect.c | 34 ++++++++++++--
 arch/arm64/kvm/hyp/pgtable.c          | 29 ++++++++++--
 3 files changed, 94 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 83c5c97d9eac..2c090b0eee77 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -115,25 +115,6 @@ enum kvm_pgtable_stage2_flags {
 	KVM_PGTABLE_S2_IDMAP			= BIT(1),
 };
 
-/**
- * struct kvm_pgtable - KVM page-table.
- * @ia_bits:		Maximum input address size, in bits.
- * @start_level:	Level at which the page-table walk starts.
- * @pgd:		Pointer to the first top-level entry of the page-table.
- * @mm_ops:		Memory management callbacks.
- * @mmu:		Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
- */
-struct kvm_pgtable {
-	u32					ia_bits;
-	u32					start_level;
-	kvm_pte_t				*pgd;
-	struct kvm_pgtable_mm_ops		*mm_ops;
-
-	/* Stage-2 only */
-	struct kvm_s2_mmu			*mmu;
-	enum kvm_pgtable_stage2_flags		flags;
-};
-
 /**
  * enum kvm_pgtable_prot - Page-table permissions and attributes.
  * @KVM_PGTABLE_PROT_X:		Execute permission.
@@ -149,11 +130,43 @@ enum kvm_pgtable_prot {
 	KVM_PGTABLE_PROT_DEVICE			= BIT(3),
 };
 
-#define PAGE_HYP		(KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
+#define KVM_PGTABLE_PROT_RW	(KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
+#define KVM_PGTABLE_PROT_RWX	(KVM_PGTABLE_PROT_RW | KVM_PGTABLE_PROT_X)
+
+#define PKVM_HOST_MEM_PROT	KVM_PGTABLE_PROT_RWX
+#define PKVM_HOST_MMIO_PROT	KVM_PGTABLE_PROT_RW
+
+#define PAGE_HYP		KVM_PGTABLE_PROT_RW
 #define PAGE_HYP_EXEC		(KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X)
 #define PAGE_HYP_RO		(KVM_PGTABLE_PROT_R)
 #define PAGE_HYP_DEVICE		(PAGE_HYP | KVM_PGTABLE_PROT_DEVICE)
 
+typedef bool (*kvm_pgtable_force_pte_cb_t)(u64 addr, u64 end,
+					   enum kvm_pgtable_prot prot);
+
+/**
+ * struct kvm_pgtable - KVM page-table.
+ * @ia_bits:		Maximum input address size, in bits.
+ * @start_level:	Level at which the page-table walk starts.
+ * @pgd:		Pointer to the first top-level entry of the page-table.
+ * @mm_ops:		Memory management callbacks.
+ * @mmu:		Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
+ * @flags:		Stage-2 page-table flags.
+ * @force_pte_cb:	Function that returns true if page level mappings must
+ *			be used instead of block mappings.
+ */
+struct kvm_pgtable {
+	u32					ia_bits;
+	u32					start_level;
+	kvm_pte_t				*pgd;
+	struct kvm_pgtable_mm_ops		*mm_ops;
+
+	/* Stage-2 only */
+	struct kvm_s2_mmu			*mmu;
+	enum kvm_pgtable_stage2_flags		flags;
+	kvm_pgtable_force_pte_cb_t		force_pte_cb;
+};
+
 /**
  * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk.
  * @KVM_PGTABLE_WALK_LEAF:		Visit leaf entries, including invalid
@@ -246,21 +259,24 @@ int kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
 u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift);
 
 /**
- * kvm_pgtable_stage2_init_flags() - Initialise a guest stage-2 page-table.
+ * __kvm_pgtable_stage2_init() - Initialise a guest stage-2 page-table.
  * @pgt:	Uninitialised page-table structure to initialise.
  * @arch:	Arch-specific KVM structure representing the guest virtual
  *		machine.
  * @mm_ops:	Memory management callbacks.
  * @flags:	Stage-2 configuration flags.
+ * @force_pte_cb: Function that returns true if page level mappings must
+ *		be used instead of block mappings.
  *
  * Return: 0 on success, negative error code on failure.
  */
-int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch,
-				  struct kvm_pgtable_mm_ops *mm_ops,
-				  enum kvm_pgtable_stage2_flags flags);
+int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
+			      struct kvm_pgtable_mm_ops *mm_ops,
+			      enum kvm_pgtable_stage2_flags flags,
+			      kvm_pgtable_force_pte_cb_t force_pte_cb);
 
 #define kvm_pgtable_stage2_init(pgt, arch, mm_ops) \
-	kvm_pgtable_stage2_init_flags(pgt, arch, mm_ops, 0)
+	__kvm_pgtable_stage2_init(pgt, arch, mm_ops, 0, NULL)
 
 /**
  * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 2148d3968aa5..6fed6772c673 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -89,6 +89,8 @@ static void prepare_host_vtcr(void)
 					  id_aa64mmfr1_el1_sys_val, phys_shift);
 }
 
+static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot);
+
 int kvm_host_prepare_stage2(void *pgt_pool_base)
 {
 	struct kvm_s2_mmu *mmu = &host_kvm.arch.mmu;
@@ -101,8 +103,9 @@ int kvm_host_prepare_stage2(void *pgt_pool_base)
 	if (ret)
 		return ret;
 
-	ret = kvm_pgtable_stage2_init_flags(&host_kvm.pgt, &host_kvm.arch,
-					    &host_kvm.mm_ops, KVM_HOST_S2_FLAGS);
+	ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, &host_kvm.arch,
+					&host_kvm.mm_ops, KVM_HOST_S2_FLAGS,
+					host_stage2_force_pte_cb);
 	if (ret)
 		return ret;
 
@@ -270,15 +273,36 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
 	return 0;
 }
 
+static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
+{
+	/*
+	 * Block mappings must be used with care in the host stage-2 as a
+	 * kvm_pgtable_stage2_map() operation targeting a page in the range of
+	 * an existing block will delete the block under the assumption that
+	 * mappings in the rest of the block range can always be rebuilt lazily.
+	 * That assumption is correct for the host stage-2 with RWX mappings
+	 * targeting memory or RW mappings targeting MMIO ranges (see
+	 * host_stage2_idmap() below which implements some of the host memory
+	 * abort logic). However, this is not safe for any other mappings where
+	 * the host stage-2 page-table is in fact the only place where this
+	 * state is stored. In all those cases, it is safer to use page-level
+	 * mappings, hence avoiding to lose the state because of side-effects in
+	 * kvm_pgtable_stage2_map().
+	 */
+	if (range_is_memory(addr, end))
+		return prot != PKVM_HOST_MEM_PROT;
+	else
+		return prot != PKVM_HOST_MMIO_PROT;
+}
+
 static int host_stage2_idmap(u64 addr)
 {
-	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
 	struct kvm_mem_range range;
 	bool is_memory = find_mem_range(addr, &range);
+	enum kvm_pgtable_prot prot;
 	int ret;
 
-	if (is_memory)
-		prot |= KVM_PGTABLE_PROT_X;
+	prot = is_memory ? PKVM_HOST_MEM_PROT : PKVM_HOST_MMIO_PROT;
 
 	hyp_spin_lock(&host_kvm.lock);
 	ret = host_stage2_adjust_range(addr, &range);
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 2689fcb7901d..e25d829587b9 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -452,6 +452,8 @@ int kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits,
 	pgt->start_level	= KVM_PGTABLE_MAX_LEVELS - levels;
 	pgt->mm_ops		= mm_ops;
 	pgt->mmu		= NULL;
+	pgt->force_pte_cb	= NULL;
+
 	return 0;
 }
 
@@ -489,6 +491,9 @@ struct stage2_map_data {
 	void				*memcache;
 
 	struct kvm_pgtable_mm_ops	*mm_ops;
+
+	/* Force mappings to page granularity */
+	bool				force_pte;
 };
 
 u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
@@ -602,6 +607,15 @@ static bool stage2_pte_executable(kvm_pte_t pte)
 	return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN);
 }
 
+static bool stage2_leaf_mapping_allowed(u64 addr, u64 end, u32 level,
+					struct stage2_map_data *data)
+{
+	if (data->force_pte && (level < (KVM_PGTABLE_MAX_LEVELS - 1)))
+		return false;
+
+	return kvm_block_mapping_supported(addr, end, data->phys, level);
+}
+
 static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level,
 				      kvm_pte_t *ptep,
 				      struct stage2_map_data *data)
@@ -611,7 +625,7 @@ static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level,
 	struct kvm_pgtable *pgt = data->mmu->pgt;
 	struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops;
 
-	if (!kvm_block_mapping_supported(addr, end, phys, level))
+	if (!stage2_leaf_mapping_allowed(addr, end, level, data))
 		return -E2BIG;
 
 	if (kvm_phys_is_valid(phys))
@@ -655,7 +669,7 @@ static int stage2_map_walk_table_pre(u64 addr, u64 end, u32 level,
 	if (data->anchor)
 		return 0;
 
-	if (!kvm_block_mapping_supported(addr, end, data->phys, level))
+	if (!stage2_leaf_mapping_allowed(addr, end, level, data))
 		return 0;
 
 	data->childp = kvm_pte_follow(*ptep, data->mm_ops);
@@ -785,6 +799,7 @@ int kvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
 		.mmu		= pgt->mmu,
 		.memcache	= mc,
 		.mm_ops		= pgt->mm_ops,
+		.force_pte	= pgt->force_pte_cb && pgt->force_pte_cb(addr, addr + size, prot),
 	};
 	struct kvm_pgtable_walker walker = {
 		.cb		= stage2_map_walker,
@@ -816,6 +831,7 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size,
 		.memcache	= mc,
 		.mm_ops		= pgt->mm_ops,
 		.owner_id	= owner_id,
+		.force_pte	= true,
 	};
 	struct kvm_pgtable_walker walker = {
 		.cb		= stage2_map_walker,
@@ -1057,9 +1073,11 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
 	return kvm_pgtable_walk(pgt, addr, size, &walker);
 }
 
-int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch,
-				  struct kvm_pgtable_mm_ops *mm_ops,
-				  enum kvm_pgtable_stage2_flags flags)
+
+int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
+			      struct kvm_pgtable_mm_ops *mm_ops,
+			      enum kvm_pgtable_stage2_flags flags,
+			      kvm_pgtable_force_pte_cb_t force_pte_cb)
 {
 	size_t pgd_sz;
 	u64 vtcr = arch->vtcr;
@@ -1077,6 +1095,7 @@ int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch
 	pgt->mm_ops		= mm_ops;
 	pgt->mmu		= &arch->mmu;
 	pgt->flags		= flags;
+	pgt->force_pte_cb	= force_pte_cb;
 
 	/* Ensure zeroed PGD pages are visible to the hardware walker */
 	dsb(ishst);
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:38 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:38 +0100
Subject: [PATCH v4 11/21] KVM: arm64: Allow populating software bits
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-12-qperret@google.com>

Introduce infrastructure allowing to manipulate software bits in stage-1
and stage-2 page-tables using additional entries in the kvm_pgtable_prot
enum.

This is heavily inspired by Marc's implementation of a similar feature
in the NV patch series, but adapted to allow stage-1 changes as well:

  https://lore.kernel.org/kvmarm/20210510165920.1913477-56-maz at kernel.org/

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 12 +++++++++++-
 arch/arm64/kvm/hyp/pgtable.c         |  5 +++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index 2c090b0eee77..ff9d52f8073a 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -121,6 +121,10 @@ enum kvm_pgtable_stage2_flags {
  * @KVM_PGTABLE_PROT_W:		Write permission.
  * @KVM_PGTABLE_PROT_R:		Read permission.
  * @KVM_PGTABLE_PROT_DEVICE:	Device attributes.
+ * @KVM_PGTABLE_PROT_SW0:	Software bit 0.
+ * @KVM_PGTABLE_PROT_SW1:	Software bit 1.
+ * @KVM_PGTABLE_PROT_SW2:	Software bit 2.
+ * @KVM_PGTABLE_PROT_SW3:	Software bit 3.
  */
 enum kvm_pgtable_prot {
 	KVM_PGTABLE_PROT_X			= BIT(0),
@@ -128,6 +132,11 @@ enum kvm_pgtable_prot {
 	KVM_PGTABLE_PROT_R			= BIT(2),
 
 	KVM_PGTABLE_PROT_DEVICE			= BIT(3),
+
+	KVM_PGTABLE_PROT_SW0			= BIT(55),
+	KVM_PGTABLE_PROT_SW1			= BIT(56),
+	KVM_PGTABLE_PROT_SW2			= BIT(57),
+	KVM_PGTABLE_PROT_SW3			= BIT(58),
 };
 
 #define KVM_PGTABLE_PROT_RW	(KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
@@ -420,7 +429,8 @@ kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr);
  * If there is a valid, leaf page-table entry used to translate @addr, then
  * relax the permissions in that entry according to the read, write and
  * execute permissions specified by @prot. No permissions are removed, and
- * TLB invalidation is performed after updating the entry.
+ * TLB invalidation is performed after updating the entry. Software bits cannot
+ * be set or cleared using kvm_pgtable_stage2_relax_perms().
  *
  * Return: 0 on success, negative error code on failure.
  */
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index e25d829587b9..cff744136044 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -357,6 +357,7 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
 	attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_AP, ap);
 	attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_SH, sh);
 	attr |= KVM_PTE_LEAF_ATTR_LO_S1_AF;
+	attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW;
 	*ptep = attr;
 
 	return 0;
@@ -558,6 +559,7 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p
 
 	attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S2_SH, sh);
 	attr |= KVM_PTE_LEAF_ATTR_LO_S2_AF;
+	attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW;
 	*ptep = attr;
 
 	return 0;
@@ -1025,6 +1027,9 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
 	u32 level;
 	kvm_pte_t set = 0, clr = 0;
 
+	if (prot & KVM_PTE_LEAF_ATTR_HI_SW)
+		return -EINVAL;
+
 	if (prot & KVM_PGTABLE_PROT_R)
 		set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
 
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:39 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:39 +0100
Subject: [PATCH v4 12/21] KVM: arm64: Add helpers to tag shared pages in SW
 bits
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-13-qperret@google.com>

We will soon start annotating shared pages in page-tables in nVHE
protected mode. Define all the states in which a page can be (owned,
shared and owned, shared and borrowed), and provide helpers allowing to
convert this into SW bits annotations using the matching prot
attributes.

Reviewed-by: Fuad Tabba <tabba at google.com>
Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 9c227d87c36d..87b1690c439f 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -12,6 +12,32 @@
 #include <asm/virt.h>
 #include <nvhe/spinlock.h>
 
+/*
+ * SW bits 0-1 are reserved to track the memory ownership state of each page:
+ *   00: The page is owned exclusively by the page-table owner.
+ *   01: The page is owned by the page-table owner, but is shared
+ *       with another entity.
+ *   10: The page is shared with, but not owned by the page-table owner.
+ *   11: Reserved for future use (lending).
+ */
+enum pkvm_page_state {
+	PKVM_PAGE_OWNED			= 0ULL,
+	PKVM_PAGE_SHARED_OWNED		= KVM_PGTABLE_PROT_SW0,
+	PKVM_PAGE_SHARED_BORROWED	= KVM_PGTABLE_PROT_SW1,
+};
+
+#define PKVM_PAGE_STATE_PROT_MASK	(KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1)
+static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot,
+						 enum pkvm_page_state state)
+{
+	return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state;
+}
+
+static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot)
+{
+	return prot & PKVM_PAGE_STATE_PROT_MASK;
+}
+
 struct host_kvm {
 	struct kvm_arch arch;
 	struct kvm_pgtable pgt;
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:40 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:40 +0100
Subject: [PATCH v4 13/21] KVM: arm64: Expose host stage-2 manipulation helpers
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-14-qperret@google.com>

We will need to manipulate the host stage-2 page-table from outside
mem_protect.c soon. Introduce two functions allowing this, and make
them usable to users of mem_protect.h.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 ++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 18 +++++++++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 87b1690c439f..0849ee8fa260 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -49,6 +49,8 @@ extern struct host_kvm host_kvm;
 int __pkvm_prot_finalize(void);
 int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
 
+int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
+int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id);
 int kvm_host_prepare_stage2(void *pgt_pool_base);
 void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
 
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 6fed6772c673..f95a5a4aa09c 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -273,6 +273,22 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
 	return 0;
 }
 
+int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
+			     enum kvm_pgtable_prot prot)
+{
+	hyp_assert_lock_held(&host_kvm.lock);
+
+	return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
+}
+
+int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
+{
+	hyp_assert_lock_held(&host_kvm.lock);
+
+	return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
+			       addr, size, &host_s2_pool, owner_id);
+}
+
 static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
 {
 	/*
@@ -309,7 +325,7 @@ static int host_stage2_idmap(u64 addr)
 	if (ret)
 		goto unlock;
 
-	ret = host_stage2_try(__host_stage2_idmap, range.start, range.end, prot);
+	ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot);
 unlock:
 	hyp_spin_unlock(&host_kvm.lock);
 
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:41 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:41 +0100
Subject: [PATCH v4 14/21] KVM: arm64: Expose pkvm_hyp_id
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-15-qperret@google.com>

Allow references to the hypervisor's owner id from outside
mem_protect.c.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 2 ++
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 0849ee8fa260..23316a021880 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -46,6 +46,8 @@ struct host_kvm {
 };
 extern struct host_kvm host_kvm;
 
+extern const u8 pkvm_hyp_id;
+
 int __pkvm_prot_finalize(void);
 int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
 
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index f95a5a4aa09c..ee255171945c 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -31,7 +31,7 @@ static struct hyp_pool host_s2_pool;
 u64 id_aa64mmfr0_el1_sys_val;
 u64 id_aa64mmfr1_el1_sys_val;
 
-static const u8 pkvm_hyp_id = 1;
+const u8 pkvm_hyp_id = 1;
 
 static void *host_s2_zalloc_pages_exact(size_t size)
 {
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:42 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:42 +0100
Subject: [PATCH v4 15/21] KVM: arm64: Introduce addr_is_memory()
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-16-qperret@google.com>

Introduce a helper usable in nVHE protected mode to check whether a
physical address is in a RAM region or not.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 +
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 23316a021880..49db0ec5a606 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -51,6 +51,7 @@ extern const u8 pkvm_hyp_id;
 int __pkvm_prot_finalize(void);
 int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
 
+bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
 int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id);
 int kvm_host_prepare_stage2(void *pgt_pool_base);
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index ee255171945c..cb023d31666e 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -197,6 +197,13 @@ static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range)
 	return false;
 }
 
+bool addr_is_memory(phys_addr_t phys)
+{
+	struct kvm_mem_range range;
+
+	return find_mem_range(phys, &range);
+}
+
 static bool range_is_memory(u64 start, u64 end)
 {
 	struct kvm_mem_range r1, r2;
-- 
2.32.0.605.g8dce9f2422-goog



From nico at fluxnic.net  Mon Aug  9 08:25:24 2021
From: nico at fluxnic.net (Nicolas Pitre)
Date: Mon, 9 Aug 2021 11:25:24 -0400 (EDT)
Subject: [PATCH] ARM: atags_to_fdt: don't warn about stack size
In-Reply-To: <20210809151021.5137-1-david@ixit.cz>
References: <20210809151021.5137-1-david@ixit.cz>
Message-ID: <5qs88614-n75s-1rn5-353r-o1p96s5qp59n@syhkavp.arg>

On Mon, 9 Aug 2021, David Heidelberg wrote:

> The merge_fdt_bootargs() function by definition consumes more than 1024
> bytes of stack because it has a 1024 byte command line on the stack,
> meaning that we always get a warning when building this file:
> 
> arch/arm/boot/compressed/atags_to_fdt.c: In function 'merge_fdt_bootargs':
> arch/arm/boot/compressed/atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 1024 bytes [-Wframe-larger-than=]
> 
> However, as this is the decompressor and we know that it has a very shallow
> call chain, and we do not actually risk overflowing the kernel stack
> at runtime here.
> 
> This just shuts up the warning by disabling the warning flag for this
> file.
> 
> Tested on Nexus 7 2012 builds.
> 
> Original Author: Arnd Bergmann <arnd at arndb.de>
> Reference: https://lore.kernel.org/lkml/8232115.18ykgQ6J5T at wuerfel/
> 
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Nicolas Pitre <nico at linaro.org>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> Cc: Marc Zyngier <marc.zyngier at arm.com>
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> 
> Signed-off-by: David Heidelberg <david at ixit.cz>

Acked-by: Nicolas Pitre <nico at fluxnic.net>

> ---
>  arch/arm/boot/compressed/Makefile | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
> index 9d91ae1091b0..91265e7ff672 100644
> --- a/arch/arm/boot/compressed/Makefile
> +++ b/arch/arm/boot/compressed/Makefile
> @@ -85,6 +85,8 @@ compress-$(CONFIG_KERNEL_LZ4)  = lz4
>  libfdt_objs := fdt_rw.o fdt_ro.o fdt_wip.o fdt.o
>  
>  ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
> +CFLAGS_REMOVE_atags_to_fdt.o += -Wframe-larger-than=${CONFIG_FRAME_WARN}
> +CFLAGS_atags_to_fdt.o += -Wframe-larger-than=1280
>  OBJS	+= $(libfdt_objs) atags_to_fdt.o
>  endif
>  ifeq ($(CONFIG_USE_OF),y)
> -- 
> 2.30.2
> 
> 


From qperret at google.com  Mon Aug  9 08:24:43 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:43 +0100
Subject: [PATCH v4 16/21] KVM: arm64: Enable retrieving protections attributes
 of PTEs
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-17-qperret@google.com>

Introduce helper functions in the KVM stage-2 and stage-1 page-table
manipulation library allowing to retrieve the enum kvm_pgtable_prot of a
PTE. This will be useful to implement custom walkers outside of
pgtable.c.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_pgtable.h | 20 +++++++++++++++
 arch/arm64/kvm/hyp/pgtable.c         | 37 ++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index ff9d52f8073a..f1651e0153ad 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -506,4 +506,24 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
  */
 int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
 			 kvm_pte_t *ptep, u32 *level);
+
+/**
+ * kvm_pgtable_stage2_pte_prot() - Retrieve the protection attributes of a
+ *				   stage-2 Page-Table Entry.
+ * @pte:	Page-table entry
+ *
+ * Return: protection attributes of the page-table entry in the enum
+ *	   kvm_pgtable_prot format.
+ */
+enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte);
+
+/**
+ * kvm_pgtable_hyp_pte_prot() - Retrieve the protection attributes of a stage-1
+ *				Page-Table Entry.
+ * @pte:	Page-table entry
+ *
+ * Return: protection attributes of the page-table entry in the enum
+ *	   kvm_pgtable_prot format.
+ */
+enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte);
 #endif	/* __ARM64_KVM_PGTABLE_H__ */
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index cff744136044..f8ceebe4982e 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -363,6 +363,26 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
 	return 0;
 }
 
+enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte)
+{
+	enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW;
+	u32 ap;
+
+	if (!kvm_pte_valid(pte))
+		return prot;
+
+	if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN))
+		prot |= KVM_PGTABLE_PROT_X;
+
+	ap = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_AP, pte);
+	if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RO)
+		prot |= KVM_PGTABLE_PROT_R;
+	else if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RW)
+		prot |= KVM_PGTABLE_PROT_RW;
+
+	return prot;
+}
+
 static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new)
 {
 	/*
@@ -565,6 +585,23 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p
 	return 0;
 }
 
+enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte)
+{
+	enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW;
+
+	if (!kvm_pte_valid(pte))
+		return prot;
+
+	if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R)
+		prot |= KVM_PGTABLE_PROT_R;
+	if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W)
+		prot |= KVM_PGTABLE_PROT_W;
+	if (!(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN))
+		prot |= KVM_PGTABLE_PROT_X;
+
+	return prot;
+}
+
 static bool stage2_pte_needs_update(kvm_pte_t old, kvm_pte_t new)
 {
 	if (!kvm_pte_valid(old) || !kvm_pte_valid(new))
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:44 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:44 +0100
Subject: [PATCH v4 17/21] KVM: arm64: Mark host bss and rodata section as
 shared
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-18-qperret@google.com>

As the hypervisor maps the host's .bss and .rodata sections in its
stage-1, make sure to tag them as shared in hyp and host page-tables.

But since the hypervisor relies on the presence of these mappings, we
cannot let the host in complete control of the memory regions -- it
must not unshare or donate them to another entity for example. To
prevent this, let's transfer the ownership of those ranges to the
hypervisor itself, and share the pages back with the host.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/nvhe/setup.c | 82 +++++++++++++++++++++++++++++----
 1 file changed, 74 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index 0b574d106519..57c27846320f 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -58,6 +58,7 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 {
 	void *start, *end, *virt = hyp_phys_to_virt(phys);
 	unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT;
+	enum kvm_pgtable_prot prot;
 	int ret, i;
 
 	/* Recreate the hyp page-table using the early page allocator */
@@ -83,10 +84,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 	if (ret)
 		return ret;
 
-	ret = pkvm_create_mappings(__start_rodata, __end_rodata, PAGE_HYP_RO);
-	if (ret)
-		return ret;
-
 	ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO);
 	if (ret)
 		return ret;
@@ -95,10 +92,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 	if (ret)
 		return ret;
 
-	ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, PAGE_HYP_RO);
-	if (ret)
-		return ret;
-
 	ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP);
 	if (ret)
 		return ret;
@@ -117,6 +110,24 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 			return ret;
 	}
 
+	/*
+	 * Map the host's .bss and .rodata sections RO in the hypervisor, but
+	 * transfer the ownership from the host to the hypervisor itself to
+	 * make sure it can't be donated or shared with another entity.
+	 *
+	 * The ownership transition requires matching changes in the host
+	 * stage-2. This will be done later (see finalize_host_mappings()) once
+	 * the hyp_vmemmap is addressable.
+	 */
+	prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
+	ret = pkvm_create_mappings(__start_rodata, __end_rodata, prot);
+	if (ret)
+		return ret;
+
+	ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, prot);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
@@ -148,6 +159,57 @@ static void hpool_put_page(void *addr)
 	hyp_put_page(&hpool, addr);
 }
 
+static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
+					 kvm_pte_t *ptep,
+					 enum kvm_pgtable_walk_flags flag,
+					 void * const arg)
+{
+	enum kvm_pgtable_prot prot;
+	enum pkvm_page_state state;
+	kvm_pte_t pte = *ptep;
+	phys_addr_t phys;
+
+	if (!kvm_pte_valid(pte))
+		return 0;
+
+	if (level != (KVM_PGTABLE_MAX_LEVELS - 1))
+		return -EINVAL;
+
+	phys = kvm_pte_to_phys(pte);
+	if (!addr_is_memory(phys))
+		return 0;
+
+	/*
+	 * Adjust the host stage-2 mappings to match the ownership attributes
+	 * configured in the hypervisor stage-1.
+	 */
+	state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte));
+	switch (state) {
+	case PKVM_PAGE_OWNED:
+		return host_stage2_set_owner_locked(phys, PAGE_SIZE, pkvm_hyp_id);
+	case PKVM_PAGE_SHARED_OWNED:
+		prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
+		break;
+	case PKVM_PAGE_SHARED_BORROWED:
+		prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
+}
+
+static int finalize_host_mappings(void)
+{
+	struct kvm_pgtable_walker walker = {
+		.cb	= finalize_host_mappings_walker,
+		.flags	= KVM_PGTABLE_WALK_LEAF,
+	};
+
+	return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker);
+}
+
 void __noreturn __pkvm_init_finalise(void)
 {
 	struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data);
@@ -167,6 +229,10 @@ void __noreturn __pkvm_init_finalise(void)
 	if (ret)
 		goto out;
 
+	ret = finalize_host_mappings();
+	if (ret)
+		goto out;
+
 	pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) {
 		.zalloc_page = hyp_zalloc_hyp_page,
 		.phys_to_virt = hyp_phys_to_virt,
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:45 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:45 +0100
Subject: [PATCH v4 18/21] KVM: arm64: Remove __pkvm_mark_hyp
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-19-qperret@google.com>

Now that we mark memory owned by the hypervisor in the host stage-2
during __pkvm_init(), we no longer need to rely on the host to
explicitly mark the hyp sections later on.

Remove the __pkvm_mark_hyp() hypercall altogether.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  3 +-
 arch/arm64/kvm/arm.c                          | 46 -------------------
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 -
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  9 ----
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 --------
 5 files changed, 1 insertion(+), 77 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 9f0bf2109be7..432a9ea1f02e 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -63,8 +63,7 @@
 #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping	17
 #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector		18
 #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize		19
-#define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp			20
-#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc			21
+#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc			20
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..2f378482471b 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1954,57 +1954,11 @@ static void _kvm_host_prot_finalize(void *discard)
 	WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize));
 }
 
-static inline int pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
-{
-	return kvm_call_hyp_nvhe(__pkvm_mark_hyp, start, end);
-}
-
-#define pkvm_mark_hyp_section(__section)		\
-	pkvm_mark_hyp(__pa_symbol(__section##_start),	\
-			__pa_symbol(__section##_end))
-
 static int finalize_hyp_mode(void)
 {
-	int cpu, ret;
-
 	if (!is_protected_kvm_enabled())
 		return 0;
 
-	ret = pkvm_mark_hyp_section(__hyp_idmap_text);
-	if (ret)
-		return ret;
-
-	ret = pkvm_mark_hyp_section(__hyp_text);
-	if (ret)
-		return ret;
-
-	ret = pkvm_mark_hyp_section(__hyp_rodata);
-	if (ret)
-		return ret;
-
-	ret = pkvm_mark_hyp_section(__hyp_bss);
-	if (ret)
-		return ret;
-
-	ret = pkvm_mark_hyp(hyp_mem_base, hyp_mem_base + hyp_mem_size);
-	if (ret)
-		return ret;
-
-	for_each_possible_cpu(cpu) {
-		phys_addr_t start = virt_to_phys((void *)kvm_arm_hyp_percpu_base[cpu]);
-		phys_addr_t end = start + (PAGE_SIZE << nvhe_percpu_order());
-
-		ret = pkvm_mark_hyp(start, end);
-		if (ret)
-			return ret;
-
-		start = virt_to_phys((void *)per_cpu(kvm_arm_hyp_stack_page, cpu));
-		end = start + PAGE_SIZE;
-		ret = pkvm_mark_hyp(start, end);
-		if (ret)
-			return ret;
-	}
-
 	/*
 	 * Flip the static key upfront as that may no longer be possible
 	 * once the host stage 2 is installed.
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 49db0ec5a606..0118527b07b0 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -49,7 +49,6 @@ extern struct host_kvm host_kvm;
 extern const u8 pkvm_hyp_id;
 
 int __pkvm_prot_finalize(void);
-int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 1632f001f4ed..7900d5b66ba3 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -163,14 +163,6 @@ static void handle___pkvm_prot_finalize(struct kvm_cpu_context *host_ctxt)
 {
 	cpu_reg(host_ctxt, 1) = __pkvm_prot_finalize();
 }
-
-static void handle___pkvm_mark_hyp(struct kvm_cpu_context *host_ctxt)
-{
-	DECLARE_REG(phys_addr_t, start, host_ctxt, 1);
-	DECLARE_REG(phys_addr_t, end, host_ctxt, 2);
-
-	cpu_reg(host_ctxt, 1) = __pkvm_mark_hyp(start, end);
-}
 typedef void (*hcall_t)(struct kvm_cpu_context *);
 
 #define HANDLE_FUNC(x)	[__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x
@@ -196,7 +188,6 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_create_mappings),
 	HANDLE_FUNC(__pkvm_create_private_mapping),
 	HANDLE_FUNC(__pkvm_prot_finalize),
-	HANDLE_FUNC(__pkvm_mark_hyp),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index cb023d31666e..2991dc6996b9 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -339,25 +339,6 @@ static int host_stage2_idmap(u64 addr)
 	return ret;
 }
 
-int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
-{
-	int ret;
-
-	/*
-	 * host_stage2_unmap_dev_all() currently relies on MMIO mappings being
-	 * non-persistent, so don't allow changing page ownership in MMIO range.
-	 */
-	if (!range_is_memory(start, end))
-		return -EINVAL;
-
-	hyp_spin_lock(&host_kvm.lock);
-	ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
-			      start, end - start, &host_s2_pool, pkvm_hyp_id);
-	hyp_spin_unlock(&host_kvm.lock);
-
-	return ret != -EAGAIN ? ret : 0;
-}
-
 void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
 {
 	struct kvm_vcpu_fault_info fault;
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:46 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:46 +0100
Subject: [PATCH v4 19/21] KVM: arm64: Refactor protected nVHE stage-1 locking
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-20-qperret@google.com>

Refactor the hypervisor stage-1 locking in nVHE protected mode to expose
a new pkvm_create_mappings_locked() function. This will be used in later
patches to allow walking and changing the hypervisor stage-1 without
releasing the lock.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mm.h |  1 +
 arch/arm64/kvm/hyp/nvhe/mm.c         | 18 ++++++++++++++++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
index 8ec3a5a7744b..c76d7136ed9b 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
@@ -23,6 +23,7 @@ int hyp_map_vectors(void);
 int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
 int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
 int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
+int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
 int __pkvm_create_mappings(unsigned long start, unsigned long size,
 			   unsigned long phys, enum kvm_pgtable_prot prot);
 unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
index a8efdf0f9003..6fbe8e8030f6 100644
--- a/arch/arm64/kvm/hyp/nvhe/mm.c
+++ b/arch/arm64/kvm/hyp/nvhe/mm.c
@@ -67,13 +67,15 @@ unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
 	return addr;
 }
 
-int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
+int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot)
 {
 	unsigned long start = (unsigned long)from;
 	unsigned long end = (unsigned long)to;
 	unsigned long virt_addr;
 	phys_addr_t phys;
 
+	hyp_assert_lock_held(&pkvm_pgd_lock);
+
 	start = start & PAGE_MASK;
 	end = PAGE_ALIGN(end);
 
@@ -81,7 +83,8 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
 		int err;
 
 		phys = hyp_virt_to_phys((void *)virt_addr);
-		err = __pkvm_create_mappings(virt_addr, PAGE_SIZE, phys, prot);
+		err = kvm_pgtable_hyp_map(&pkvm_pgtable, virt_addr, PAGE_SIZE,
+					  phys, prot);
 		if (err)
 			return err;
 	}
@@ -89,6 +92,17 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
 	return 0;
 }
 
+int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
+{
+	int ret;
+
+	hyp_spin_lock(&pkvm_pgd_lock);
+	ret = pkvm_create_mappings_locked(from, to, prot);
+	hyp_spin_unlock(&pkvm_pgd_lock);
+
+	return ret;
+}
+
 int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back)
 {
 	unsigned long start, end;
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:47 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:47 +0100
Subject: [PATCH v4 20/21] KVM: arm64: Restrict EL2 stage-1 changes in
 protected mode
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-21-qperret@google.com>

The host kernel is currently able to change EL2 stage-1 mappings without
restrictions thanks to the __pkvm_create_mappings() hypercall. But in a
world where the host is no longer part of the TCB, this clearly poses a
problem.

To fix this, introduce a new hypercall to allow the host to share a
physical memory page with the hypervisor, and remove the
__pkvm_create_mappings() variant. The new hypercall implements
ownership and permission checks before allowing the sharing operation,
and it annotates the shared page in the hypervisor stage-1 and host
stage-2 page-tables.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/include/asm/kvm_asm.h              |  2 +-
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 11 +--
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 88 +++++++++++++++++++
 arch/arm64/kvm/mmu.c                          | 28 +++++-
 5 files changed, 118 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 432a9ea1f02e..aed2aa61766a 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -59,7 +59,7 @@
 #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs		13
 #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs		14
 #define __KVM_HOST_SMCCC_FUNC___pkvm_init			15
-#define __KVM_HOST_SMCCC_FUNC___pkvm_create_mappings		16
+#define __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp		16
 #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping	17
 #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector		18
 #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize		19
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
index 0118527b07b0..03e604f842e2 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
@@ -49,6 +49,7 @@ extern struct host_kvm host_kvm;
 extern const u8 pkvm_hyp_id;
 
 int __pkvm_prot_finalize(void);
+int __pkvm_host_share_hyp(u64 pfn);
 
 bool addr_is_memory(phys_addr_t phys);
 int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 7900d5b66ba3..2da6aa8da868 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -140,14 +140,11 @@ static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) = pkvm_cpu_set_vector(slot);
 }
 
-static void handle___pkvm_create_mappings(struct kvm_cpu_context *host_ctxt)
+static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt)
 {
-	DECLARE_REG(unsigned long, start, host_ctxt, 1);
-	DECLARE_REG(unsigned long, size, host_ctxt, 2);
-	DECLARE_REG(unsigned long, phys, host_ctxt, 3);
-	DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4);
+	DECLARE_REG(u64, pfn, host_ctxt, 1);
 
-	cpu_reg(host_ctxt, 1) = __pkvm_create_mappings(start, size, phys, prot);
+	cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(pfn);
 }
 
 static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt)
@@ -185,7 +182,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__vgic_v3_restore_aprs),
 	HANDLE_FUNC(__pkvm_init),
 	HANDLE_FUNC(__pkvm_cpu_set_vector),
-	HANDLE_FUNC(__pkvm_create_mappings),
+	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_create_private_mapping),
 	HANDLE_FUNC(__pkvm_prot_finalize),
 };
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 2991dc6996b9..8165390d3ec9 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -339,6 +339,94 @@ static int host_stage2_idmap(u64 addr)
 	return ret;
 }
 
+static inline bool check_prot(enum kvm_pgtable_prot prot,
+			      enum kvm_pgtable_prot required,
+			      enum kvm_pgtable_prot denied)
+{
+	return (prot & (required | denied)) == required;
+}
+
+int __pkvm_host_share_hyp(u64 pfn)
+{
+	phys_addr_t addr = hyp_pfn_to_phys(pfn);
+	enum kvm_pgtable_prot prot, cur;
+	void *virt = __hyp_va(addr);
+	enum pkvm_page_state state;
+	kvm_pte_t pte;
+	int ret;
+
+	if (!addr_is_memory(addr))
+		return -EINVAL;
+
+	hyp_spin_lock(&host_kvm.lock);
+	hyp_spin_lock(&pkvm_pgd_lock);
+
+	ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, NULL);
+	if (ret)
+		goto unlock;
+	if (!pte)
+		goto map_shared;
+
+	/*
+	 * Check attributes in the host stage-2 PTE. We need the page to be:
+	 *  - mapped RWX as we're sharing memory;
+	 *  - not borrowed, as that implies absence of ownership.
+	 * Otherwise, we can't let it got through
+	 */
+	cur = kvm_pgtable_stage2_pte_prot(pte);
+	prot = pkvm_mkstate(0, PKVM_PAGE_SHARED_BORROWED);
+	if (!check_prot(cur, PKVM_HOST_MEM_PROT, prot)) {
+		ret = -EPERM;
+		goto unlock;
+	}
+
+	state = pkvm_getstate(cur);
+	if (state == PKVM_PAGE_OWNED)
+		goto map_shared;
+
+	/*
+	 * Tolerate double-sharing the same page, but this requires
+	 * cross-checking the hypervisor stage-1.
+	 */
+	if (state != PKVM_PAGE_SHARED_OWNED) {
+		ret = -EPERM;
+		goto unlock;
+	}
+
+	ret = kvm_pgtable_get_leaf(&pkvm_pgtable, (u64)virt, &pte, NULL);
+	if (ret)
+		goto unlock;
+
+	/*
+	 * If the page has been shared with the hypervisor, it must be
+	 * already mapped as SHARED_BORROWED in its stage-1.
+	 */
+	cur = kvm_pgtable_hyp_pte_prot(pte);
+	prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
+	if (!check_prot(cur, prot, ~prot))
+		ret = EPERM;
+	goto unlock;
+
+map_shared:
+	/*
+	 * If the page is not yet shared, adjust mappings in both page-tables
+	 * while both locks are held.
+	 */
+	prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
+	ret = pkvm_create_mappings_locked(virt, virt + PAGE_SIZE, prot);
+	BUG_ON(ret);
+
+	prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
+	ret = host_stage2_idmap_locked(addr, PAGE_SIZE, prot);
+	BUG_ON(ret);
+
+unlock:
+	hyp_spin_unlock(&pkvm_pgd_lock);
+	hyp_spin_unlock(&host_kvm.lock);
+
+	return ret;
+}
+
 void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
 {
 	struct kvm_vcpu_fault_info fault;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 0625bf2353c2..cbab146cda6a 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -259,10 +259,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size,
 {
 	int err;
 
-	if (!kvm_host_owns_hyp_mappings()) {
-		return kvm_call_hyp_nvhe(__pkvm_create_mappings,
-					 start, size, phys, prot);
-	}
+	if (WARN_ON(!kvm_host_owns_hyp_mappings()))
+		return -EINVAL;
 
 	mutex_lock(&kvm_hyp_pgd_mutex);
 	err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot);
@@ -282,6 +280,21 @@ static phys_addr_t kvm_kaddr_to_phys(void *kaddr)
 	}
 }
 
+static int pkvm_share_hyp(phys_addr_t start, phys_addr_t end)
+{
+	phys_addr_t addr;
+	int ret;
+
+	for (addr = ALIGN_DOWN(start, PAGE_SIZE); addr < end; addr += PAGE_SIZE) {
+		ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp,
+					__phys_to_pfn(addr));
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 /**
  * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode
  * @from:	The virtual kernel start address of the range
@@ -302,6 +315,13 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
 	if (is_kernel_in_hyp_mode())
 		return 0;
 
+	if (!kvm_host_owns_hyp_mappings()) {
+		if (WARN_ON(prot != PAGE_HYP))
+			return -EPERM;
+		return pkvm_share_hyp(kvm_kaddr_to_phys(from),
+				      kvm_kaddr_to_phys(to));
+	}
+
 	start = start & PAGE_MASK;
 	end = PAGE_ALIGN(end);
 
-- 
2.32.0.605.g8dce9f2422-goog



From qperret at google.com  Mon Aug  9 08:24:48 2021
From: qperret at google.com (Quentin Perret)
Date: Mon,  9 Aug 2021 16:24:48 +0100
Subject: [PATCH v4 21/21] KVM: arm64: Make __pkvm_create_mappings static
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <20210809152448.1810400-22-qperret@google.com>

The __pkvm_create_mappings() function is no longer used outside of
nvhe/mm.c, make it static.

Signed-off-by: Quentin Perret <qperret at google.com>
---
 arch/arm64/kvm/hyp/include/nvhe/mm.h | 2 --
 arch/arm64/kvm/hyp/nvhe/mm.c         | 4 ++--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
index c76d7136ed9b..c9a8f535212e 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
@@ -24,8 +24,6 @@ int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
 int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
 int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
 int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
-int __pkvm_create_mappings(unsigned long start, unsigned long size,
-			   unsigned long phys, enum kvm_pgtable_prot prot);
 unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
 					    enum kvm_pgtable_prot prot);
 
diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
index 6fbe8e8030f6..2fabeceb889a 100644
--- a/arch/arm64/kvm/hyp/nvhe/mm.c
+++ b/arch/arm64/kvm/hyp/nvhe/mm.c
@@ -23,8 +23,8 @@ u64 __io_map_base;
 struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS];
 unsigned int hyp_memblock_nr;
 
-int __pkvm_create_mappings(unsigned long start, unsigned long size,
-			  unsigned long phys, enum kvm_pgtable_prot prot)
+static int __pkvm_create_mappings(unsigned long start, unsigned long size,
+				  unsigned long phys, enum kvm_pgtable_prot prot)
 {
 	int err;
 
-- 
2.32.0.605.g8dce9f2422-goog



From linux at armlinux.org.uk  Mon Aug  9 08:24:21 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 9 Aug 2021 16:24:21 +0100
Subject: [PATCH] ARM: atags_to_fdt: don't warn about stack size
In-Reply-To: <20210809151021.5137-1-david@ixit.cz>
References: <20210809151021.5137-1-david@ixit.cz>
Message-ID: <20210809152421.GU22278@shell.armlinux.org.uk>

On Mon, Aug 09, 2021 at 05:10:21PM +0200, David Heidelberg wrote:
> The merge_fdt_bootargs() function by definition consumes more than 1024
> bytes of stack because it has a 1024 byte command line on the stack,
> meaning that we always get a warning when building this file:
> 
> arch/arm/boot/compressed/atags_to_fdt.c: In function 'merge_fdt_bootargs':
> arch/arm/boot/compressed/atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 1024 bytes [-Wframe-larger-than=]
> 
> However, as this is the decompressor and we know that it has a very shallow
> call chain, and we do not actually risk overflowing the kernel stack
> at runtime here.
> 
> This just shuts up the warning by disabling the warning flag for this
> file.
> 
> Tested on Nexus 7 2012 builds.
> 
> Original Author: Arnd Bergmann <arnd at arndb.de>
> Reference: https://lore.kernel.org/lkml/8232115.18ykgQ6J5T at wuerfel/
> 
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Nicolas Pitre <nico at linaro.org>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> Cc: Marc Zyngier <marc.zyngier at arm.com>
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> 
> Signed-off-by: David Heidelberg <david at ixit.cz>

I assume Arnd never sent his v3 from what I see in the thread you link
to above.

This needs to go to the patch system to be applied. Details in my
signature below. Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From will at kernel.org  Mon Aug  9 08:26:34 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 16:26:34 +0100
Subject: [EXT] Re: The problem about arm64: io: Relax implicit barriers
 in default I/O accessors
In-Reply-To: <AS8PR04MB85001637B4DAE19BB51FA54588F69@AS8PR04MB8500.eurprd04.prod.outlook.com>
References: <AS8PR04MB85000A5E88F7CDDAB9105821880A9@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210621181326.GD29713@willie-the-truck>
 <AS8PR04MB85006677E34CD6CC2C132FA2880A9@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210622091140.GA30677@willie-the-truck>
 <AS8PR04MB85002F0B0C99E7B4F1D27D3D88089@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210706171106.GE20750@willie-the-truck>
 <AS8PR04MB8500635E829B332A61AC85C988129@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <AS8PR04MB850048A35E12270B42448B4C88E49@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210809135041.GC1207@willie-the-truck>
 <AS8PR04MB85001637B4DAE19BB51FA54588F69@AS8PR04MB8500.eurprd04.prod.outlook.com>
Message-ID: <20210809152634.GA1589@willie-the-truck>

On Mon, Aug 09, 2021 at 02:46:55PM +0000, Frank Li wrote:
> 
> 
> > -----Original Message-----
> > From: Will Deacon <will at kernel.org>
> > Sent: Monday, August 9, 2021 8:51 AM
> > To: Frank Li <frank.li at nxp.com>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>; Zhi Li <lznuaa at gmail.com>;
> > Shenwei Wang <shenwei.wang at nxp.com>; Han Xu <han.xu at nxp.com>; Nitin Garg
> > <nitin.garg at nxp.com>; Jason Liu <jason.hui.liu at nxp.com>; linux-arm-
> > kernel at lists.infradead.org
> > Subject: Re: [EXT] Re: The problem about arm64: io: Relax implicit barriers
> > in default I/O accessors
> > 
> > Caution: EXT Email
> > 
> > On Thu, Jul 22, 2021 at 07:14:19PM +0000, Frank Li wrote:
> > > > > On Wed, Jun 23, 2021 at 03:48:10PM +0000, Frank Li wrote:
> > > > > > > I think you had a support case open with Arm [1] which I'm not
> > able
> > > > to
> > > > > > > access -- please can you ask them about the two examples above?
> > > > > >
> > > > > > Still not get feedback from ARM.
> > > > >
> > > > > Just wondering if you were able to solve this without the need to
> > change
> > > > > Linux?
> > > >
> > > > Sorry for late reply
> > > >
> > > > For CCI-500 and 550, ARM removed support for barrier transactions but
> > CCI-
> > > > 400 supports barrier transactions. With CCI-400 it is a valid
> > configuration
> > > > to have SYSBARDISABLE LOW in Cortex-A processors. This change in Linux
> > > > kernel is assuming that the SYSBARDISABLE is set to HIGH hence its not
> > > > correct change for all products having various versions of ARM CCI IP.
> > > >
> > > > Frank Li
> > >
> > > Deacon:
> > >
> > >       Did you plan fix this problem by changing dma_wmb()?
> > 
> > No. As far as I understand this problem, you're driving SYSBARDISABLE
> > 'low' yet you have your own bus fabric downstream of the CCI which doesn't
> > respect barrier transactions. Even if we bodge dma_wmb(), store-release to
> > non-cacheable memory cannot be made to work on your system as you're
> > effectively putting some of your non-coherent DMA devices into a separate
> > outer-shareable domain from the CPUs.
> 
> Does it means the Linux expect all DMA devices in outer-shareable domain instead
> of system shared domain?  

I don't think we've ever documented that and, to be honest, the
outer-shareable domain stuff in the architecture is pretty academic.

However, I think it's fair to say that we do want the acquire/release
instructions to work for non-cacheable buffers when communicating with
non-coherent devices. I _think_ that implies that such devices need to
be in the same outer-shareable domain as the CPUs, although the
architecture isn't really clear here. I can try to find out.

Will


From maz at kernel.org  Mon Aug  9 08:26:42 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:42 +0100
Subject: [PATCH 04/13] clocksource/arm_arch_timer: Move drop _tval from
 erratum function names
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-5-maz@kernel.org>

The '_tval' name in the erratum handling function names doesn't
make much sense anymore (and they were using CVAL the first place).

Drop the _tval tag.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/clocksource/arm_arch_timer.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 898a07dc01cd..160464f75017 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -371,7 +371,7 @@ EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
 
 static atomic_t timer_unstable_counter_workaround_in_use = ATOMIC_INIT(0);
 
-static void erratum_set_next_event_tval_generic(const int access, unsigned long evt,
+static void erratum_set_next_event_generic(const int access, unsigned long evt,
 						struct clock_event_device *clk)
 {
 	unsigned long ctrl;
@@ -392,17 +392,17 @@ static void erratum_set_next_event_tval_generic(const int access, unsigned long
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
-static __maybe_unused int erratum_set_next_event_tval_virt(unsigned long evt,
+static __maybe_unused int erratum_set_next_event_virt(unsigned long evt,
 					    struct clock_event_device *clk)
 {
-	erratum_set_next_event_tval_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
+	erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
 	return 0;
 }
 
-static __maybe_unused int erratum_set_next_event_tval_phys(unsigned long evt,
+static __maybe_unused int erratum_set_next_event_phys(unsigned long evt,
 					    struct clock_event_device *clk)
 {
-	erratum_set_next_event_tval_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
+	erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
 	return 0;
 }
 
@@ -414,8 +414,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.desc = "Freescale erratum a005858",
 		.read_cntpct_el0 = fsl_a008585_read_cntpct_el0,
 		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
-		.set_next_event_phys = erratum_set_next_event_tval_phys,
-		.set_next_event_virt = erratum_set_next_event_tval_virt,
+		.set_next_event_phys = erratum_set_next_event_phys,
+		.set_next_event_virt = erratum_set_next_event_virt,
 	},
 #endif
 #ifdef CONFIG_HISILICON_ERRATUM_161010101
@@ -425,8 +425,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.desc = "HiSilicon erratum 161010101",
 		.read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
 		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
-		.set_next_event_phys = erratum_set_next_event_tval_phys,
-		.set_next_event_virt = erratum_set_next_event_tval_virt,
+		.set_next_event_phys = erratum_set_next_event_phys,
+		.set_next_event_virt = erratum_set_next_event_virt,
 	},
 	{
 		.match_type = ate_match_acpi_oem_info,
@@ -434,8 +434,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.desc = "HiSilicon erratum 161010101",
 		.read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
 		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
-		.set_next_event_phys = erratum_set_next_event_tval_phys,
-		.set_next_event_virt = erratum_set_next_event_tval_virt,
+		.set_next_event_phys = erratum_set_next_event_phys,
+		.set_next_event_virt = erratum_set_next_event_virt,
 	},
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_858921
@@ -454,8 +454,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.desc = "Allwinner erratum UNKNOWN1",
 		.read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
 		.read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
-		.set_next_event_phys = erratum_set_next_event_tval_phys,
-		.set_next_event_virt = erratum_set_next_event_tval_virt,
+		.set_next_event_phys = erratum_set_next_event_phys,
+		.set_next_event_virt = erratum_set_next_event_virt,
 	},
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_1418040
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:38 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:38 +0100
Subject: [PATCH 00/13] clocksource/arm_arch_timer: Add basic ARMv8.6 support
Message-ID: <20210809152651.2297337-1-maz@kernel.org>

This small series has been prompted by a discussion with Oliver around
the fact that an ARMv8.6 implementation must have a 1GHz counter,
which leads to a number of things to break in the timer code:

- the counter rollover can come pretty quickly as we only advertise a
  56bit counter,
- the maximum timer delta can be remarkably small, as we use the
  countdown interface which is limited to 32bit...

Thankfully, there is a way out: we can compute the minimal width of
the counter based on the guarantees that the architecture gives us,
and we can use the 64bit comparator interface instead of the countdown
to program the timer.

Finally, we start making use of the ARMv8.6 ECV features by switching
accesses to the counters to a self-synchronising register, removing
the need for an ISB. Hopefully, implementations will *not* just stick
an invisible ISB there...

A side effect of the switch to CVAL is that XGene-1 breaks. I have
added a workaround to keep it alive.

I have added Oliver's original patch[0] to the series and tweaked a
couple of things. Blame me if I broke anything.

The whole things has been tested on Juno (sysreg + MMIO timers),
XGene-1 (broken sysreg timers), FVP (FEAT_ECV, CNT*CTSS_EL0).

[0] https://lore.kernel.org/r/20210807191428.3488948-1-oupton at google.com

Marc Zyngier (12):
  clocksource/arm_arch_timer: Drop CNT*_TVAL read accessors
  clocksource/arm_arch_timer: Extend write side of timer register
    accessors to u64
  clocksource/arm_arch_timer: Move system register timer programming
    over to CVAL
  clocksource/arm_arch_timer: Move drop _tval from erratum function
    names
  clocksource/arm_arch_timer: Fix MMIO base address vs callback ordering
    issue
  clocksource/arm_arch_timer: Move MMIO timer programming over to CVAL
  clocksource/arm_arch_timer: Advertise 56bit timer to the core code
  clocksource/arm_arch_timer: Work around broken CVAL implementations
  clocksource/arm_arch_timer: Remove any trace of the TVAL programming
    interface
  clocksource/arm_arch_timer: Drop unnecessary ISB on CVAL programming
  arm64: Add a capability for FEAT_EVC
  arm64: Add CNT{P,V}CTSS_EL0 alternatives to cnt{p,v}ct_el0

Oliver Upton (1):
  clocksource/arm_arch_timer: Fix masking for high freq counters

 arch/arm/include/asm/arch_timer.h    |  29 ++--
 arch/arm64/include/asm/arch_timer.h  |  65 +++----
 arch/arm64/include/asm/esr.h         |   6 +
 arch/arm64/include/asm/sysreg.h      |   3 +
 arch/arm64/kernel/cpufeature.c       |  10 ++
 arch/arm64/kernel/traps.c            |  11 ++
 arch/arm64/tools/cpucaps             |   1 +
 drivers/clocksource/arm_arch_timer.c | 249 ++++++++++++++++-----------
 include/clocksource/arm_arch_timer.h |   2 +-
 9 files changed, 234 insertions(+), 142 deletions(-)

-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:40 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:40 +0100
Subject: [PATCH 02/13] clocksource/arm_arch_timer: Extend write side of timer
 register accessors to u64
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-3-maz@kernel.org>

The various accessors for the timer sysreg and MMIO registers are
currently hardwired to 32bit. However, we are about to introduce
the use of the CVAL registers, which require a 64bit access.

Upgrade the write side of the accessors to take a 64bit value
(the read side is left untouched as we don't plan to ever read
back any of these registers).

No functional change expected.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm/include/asm/arch_timer.h    | 10 +++++-----
 arch/arm64/include/asm/arch_timer.h  |  2 +-
 drivers/clocksource/arm_arch_timer.c | 10 +++++-----
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 0c09afaa590d..88075c7f4bfd 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -24,24 +24,24 @@ int arch_timer_arch_init(void);
  * the code. At least it does so with a recent GCC (4.6.3).
  */
 static __always_inline
-void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
+void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 {
 	if (access == ARCH_TIMER_PHYS_ACCESS) {
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
-			asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
+			asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
 			break;
 		case ARCH_TIMER_REG_TVAL:
-			asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
+			asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val));
 			break;
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
-			asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
+			asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
 			break;
 		case ARCH_TIMER_REG_TVAL:
-			asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
+			asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val));
 			break;
 		}
 	}
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 8e3b2ac60c30..107afb721749 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -89,7 +89,7 @@ static inline notrace u64 arch_timer_read_cntvct_el0(void)
  * the code.
  */
 static __always_inline
-void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
+void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 {
 	if (access == ARCH_TIMER_PHYS_ACCESS) {
 		switch (reg) {
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 9db5c16e31e7..0b2bac3ef7ce 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -100,27 +100,27 @@ early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
  */
 
 static __always_inline
-void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
+void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
 			  struct clock_event_device *clk)
 {
 	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
 		struct arch_timer *timer = to_arch_timer(clk);
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
-			writel_relaxed(val, timer->base + CNTP_CTL);
+			writel_relaxed((u32)val, timer->base + CNTP_CTL);
 			break;
 		case ARCH_TIMER_REG_TVAL:
-			writel_relaxed(val, timer->base + CNTP_TVAL);
+			writel_relaxed((u32)val, timer->base + CNTP_TVAL);
 			break;
 		}
 	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
 		struct arch_timer *timer = to_arch_timer(clk);
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
-			writel_relaxed(val, timer->base + CNTV_CTL);
+			writel_relaxed((u32)val, timer->base + CNTV_CTL);
 			break;
 		case ARCH_TIMER_REG_TVAL:
-			writel_relaxed(val, timer->base + CNTV_TVAL);
+			writel_relaxed((u32)val, timer->base + CNTV_TVAL);
 			break;
 		}
 	} else {
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:39 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:39 +0100
Subject: [PATCH 01/13] clocksource/arm_arch_timer: Drop CNT*_TVAL read
 accessors
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-2-maz@kernel.org>

The arch timer driver never reads the various TVAL registers, only
writes to them. It is thus pointless to provide accessors
for them and to implement errata workarounds.

Drop these read-side accessors, and add a couple of BUG() statements
for the time being. These statements will be removed further down
the line.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm/include/asm/arch_timer.h    |  6 ++--
 arch/arm64/include/asm/arch_timer.h  | 17 ++---------
 drivers/clocksource/arm_arch_timer.c | 44 ++--------------------------
 3 files changed, 6 insertions(+), 61 deletions(-)

diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 99175812d903..0c09afaa590d 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -60,8 +60,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 			asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
 			break;
 		case ARCH_TIMER_REG_TVAL:
-			asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
-			break;
+			BUG();
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
 		switch (reg) {
@@ -69,8 +68,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 			asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
 			break;
 		case ARCH_TIMER_REG_TVAL:
-			asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
-			break;
+			BUG();
 		}
 	}
 
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 88d20f04c64a..8e3b2ac60c30 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -52,8 +52,6 @@ struct arch_timer_erratum_workaround {
 	enum arch_timer_erratum_match_type match_type;
 	const void *id;
 	const char *desc;
-	u32 (*read_cntp_tval_el0)(void);
-	u32 (*read_cntv_tval_el0)(void);
 	u64 (*read_cntpct_el0)(void);
 	u64 (*read_cntvct_el0)(void);
 	int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
@@ -64,17 +62,6 @@ struct arch_timer_erratum_workaround {
 DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
 		timer_unstable_counter_workaround);
 
-/* inline sysreg accessors that make erratum_handler() work */
-static inline notrace u32 arch_timer_read_cntp_tval_el0(void)
-{
-	return read_sysreg(cntp_tval_el0);
-}
-
-static inline notrace u32 arch_timer_read_cntv_tval_el0(void)
-{
-	return read_sysreg(cntv_tval_el0);
-}
-
 static inline notrace u64 arch_timer_read_cntpct_el0(void)
 {
 	return read_sysreg(cntpct_el0);
@@ -135,14 +122,14 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 		case ARCH_TIMER_REG_CTRL:
 			return read_sysreg(cntp_ctl_el0);
 		case ARCH_TIMER_REG_TVAL:
-			return arch_timer_reg_read_stable(cntp_tval_el0);
+			break;
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			return read_sysreg(cntv_ctl_el0);
 		case ARCH_TIMER_REG_TVAL:
-			return arch_timer_reg_read_stable(cntv_tval_el0);
+			break;
 		}
 	}
 
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index be6d741d404c..9db5c16e31e7 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -141,8 +141,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
 			val = readl_relaxed(timer->base + CNTP_CTL);
 			break;
 		case ARCH_TIMER_REG_TVAL:
-			val = readl_relaxed(timer->base + CNTP_TVAL);
-			break;
+			BUG();
 		}
 	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
 		struct arch_timer *timer = to_arch_timer(clk);
@@ -151,8 +150,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
 			val = readl_relaxed(timer->base + CNTV_CTL);
 			break;
 		case ARCH_TIMER_REG_TVAL:
-			val = readl_relaxed(timer->base + CNTV_TVAL);
-			break;
+			BUG();
 		}
 	} else {
 		val = arch_timer_reg_read_cp15(access, reg);
@@ -239,16 +237,6 @@ struct ate_acpi_oem_info {
 	_new;						\
 })
 
-static u32 notrace fsl_a008585_read_cntp_tval_el0(void)
-{
-	return __fsl_a008585_read_reg(cntp_tval_el0);
-}
-
-static u32 notrace fsl_a008585_read_cntv_tval_el0(void)
-{
-	return __fsl_a008585_read_reg(cntv_tval_el0);
-}
-
 static u64 notrace fsl_a008585_read_cntpct_el0(void)
 {
 	return __fsl_a008585_read_reg(cntpct_el0);
@@ -285,16 +273,6 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void)
 	_new;							\
 })
 
-static u32 notrace hisi_161010101_read_cntp_tval_el0(void)
-{
-	return __hisi_161010101_read_reg(cntp_tval_el0);
-}
-
-static u32 notrace hisi_161010101_read_cntv_tval_el0(void)
-{
-	return __hisi_161010101_read_reg(cntv_tval_el0);
-}
-
 static u64 notrace hisi_161010101_read_cntpct_el0(void)
 {
 	return __hisi_161010101_read_reg(cntpct_el0);
@@ -379,16 +357,6 @@ static u64 notrace sun50i_a64_read_cntvct_el0(void)
 {
 	return __sun50i_a64_read_reg(cntvct_el0);
 }
-
-static u32 notrace sun50i_a64_read_cntp_tval_el0(void)
-{
-	return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0();
-}
-
-static u32 notrace sun50i_a64_read_cntv_tval_el0(void)
-{
-	return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0();
-}
 #endif
 
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
@@ -438,8 +406,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.match_type = ate_match_dt,
 		.id = "fsl,erratum-a008585",
 		.desc = "Freescale erratum a005858",
-		.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
-		.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
 		.read_cntpct_el0 = fsl_a008585_read_cntpct_el0,
 		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
 		.set_next_event_phys = erratum_set_next_event_tval_phys,
@@ -451,8 +417,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.match_type = ate_match_dt,
 		.id = "hisilicon,erratum-161010101",
 		.desc = "HiSilicon erratum 161010101",
-		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
-		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
 		.read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
 		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
 		.set_next_event_phys = erratum_set_next_event_tval_phys,
@@ -462,8 +426,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.match_type = ate_match_acpi_oem_info,
 		.id = hisi_161010101_oem_info,
 		.desc = "HiSilicon erratum 161010101",
-		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
-		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
 		.read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
 		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
 		.set_next_event_phys = erratum_set_next_event_tval_phys,
@@ -484,8 +446,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.match_type = ate_match_dt,
 		.id = "allwinner,erratum-unknown1",
 		.desc = "Allwinner erratum UNKNOWN1",
-		.read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0,
-		.read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0,
 		.read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
 		.read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
 		.set_next_event_phys = erratum_set_next_event_tval_phys,
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:41 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:41 +0100
Subject: [PATCH 03/13] clocksource/arm_arch_timer: Move system register timer
 programming over to CVAL
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-4-maz@kernel.org>

In order to cope better with high frequency counters, move the
programming of the timers from the countdown timer (TVAL) over
to the comparator (CVAL).

The programming model is slightly different, as we now need to
read the current counter value to have an absolute deadline
instead of a relative one.

There is a small overhead to this change, which we will address
in the following patches.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm/include/asm/arch_timer.h    | 14 ++++++++----
 arch/arm64/include/asm/arch_timer.h  | 16 +++++++++-----
 drivers/clocksource/arm_arch_timer.c | 32 +++++++++++++++++++++++++---
 include/clocksource/arm_arch_timer.h |  1 +
 4 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 88075c7f4bfd..b48de9d26f27 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -31,18 +31,22 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		case ARCH_TIMER_REG_CTRL:
 			asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val));
+		case ARCH_TIMER_REG_CVAL:
+			asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
 			break;
+		case ARCH_TIMER_REG_TVAL:
+			BUG();
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val));
+		case ARCH_TIMER_REG_CVAL:
+			asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
 			break;
+		case ARCH_TIMER_REG_TVAL:
+			BUG();
 		}
 	}
 
@@ -60,6 +64,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 			asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
 			break;
 		case ARCH_TIMER_REG_TVAL:
+		case ARCH_TIMER_REG_CVAL:
 			BUG();
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
@@ -68,6 +73,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 			asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
 			break;
 		case ARCH_TIMER_REG_TVAL:
+		case ARCH_TIMER_REG_CVAL:
 			BUG();
 		}
 	}
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 107afb721749..6ceb050ae7b9 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -96,18 +96,22 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		case ARCH_TIMER_REG_CTRL:
 			write_sysreg(val, cntp_ctl_el0);
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			write_sysreg(val, cntp_tval_el0);
+		case ARCH_TIMER_REG_CVAL:
+			write_sysreg(val, cntp_cval_el0);
 			break;
+		case ARCH_TIMER_REG_TVAL:
+			BUG();
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			write_sysreg(val, cntv_ctl_el0);
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			write_sysreg(val, cntv_tval_el0);
+		case ARCH_TIMER_REG_CVAL:
+			write_sysreg(val, cntv_cval_el0);
 			break;
+		case ARCH_TIMER_REG_TVAL:
+			BUG();
 		}
 	}
 
@@ -115,13 +119,14 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 }
 
 static __always_inline
-u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
+u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 {
 	if (access == ARCH_TIMER_PHYS_ACCESS) {
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			return read_sysreg(cntp_ctl_el0);
 		case ARCH_TIMER_REG_TVAL:
+		case ARCH_TIMER_REG_CVAL:
 			break;
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
@@ -129,6 +134,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 		case ARCH_TIMER_REG_CTRL:
 			return read_sysreg(cntv_ctl_el0);
 		case ARCH_TIMER_REG_TVAL:
+		case ARCH_TIMER_REG_CVAL:
 			break;
 		}
 	}
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 0b2bac3ef7ce..898a07dc01cd 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -112,6 +112,8 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
 		case ARCH_TIMER_REG_TVAL:
 			writel_relaxed((u32)val, timer->base + CNTP_TVAL);
 			break;
+		case ARCH_TIMER_REG_CVAL:
+			BUG();
 		}
 	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
 		struct arch_timer *timer = to_arch_timer(clk);
@@ -122,6 +124,8 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
 		case ARCH_TIMER_REG_TVAL:
 			writel_relaxed((u32)val, timer->base + CNTV_TVAL);
 			break;
+		case ARCH_TIMER_REG_CVAL:
+			BUG();
 		}
 	} else {
 		arch_timer_reg_write_cp15(access, reg, val);
@@ -141,6 +145,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
 			val = readl_relaxed(timer->base + CNTP_CTL);
 			break;
 		case ARCH_TIMER_REG_TVAL:
+		case ARCH_TIMER_REG_CVAL:
 			BUG();
 		}
 	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
@@ -150,6 +155,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
 			val = readl_relaxed(timer->base + CNTV_CTL);
 			break;
 		case ARCH_TIMER_REG_TVAL:
+		case ARCH_TIMER_REG_CVAL:
 			BUG();
 		}
 	} else {
@@ -687,10 +693,18 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
 					   struct clock_event_device *clk)
 {
 	unsigned long ctrl;
+	u64 cnt;
+
 	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
 	ctrl |= ARCH_TIMER_CTRL_ENABLE;
 	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
-	arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
+
+	if (access == ARCH_TIMER_PHYS_ACCESS)
+		cnt = __arch_counter_get_cntpct();
+	else
+		cnt = __arch_counter_get_cntvct();
+
+	arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk);
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
@@ -708,17 +722,29 @@ static int arch_timer_set_next_event_phys(unsigned long evt,
 	return 0;
 }
 
+static __always_inline void set_next_event_mem(const int access, unsigned long evt,
+					   struct clock_event_device *clk)
+{
+	unsigned long ctrl;
+	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
+	ctrl |= ARCH_TIMER_CTRL_ENABLE;
+	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
+
+	arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
+	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
+}
+
 static int arch_timer_set_next_event_virt_mem(unsigned long evt,
 					      struct clock_event_device *clk)
 {
-	set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
+	set_next_event_mem(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
 	return 0;
 }
 
 static int arch_timer_set_next_event_phys_mem(unsigned long evt,
 					      struct clock_event_device *clk)
 {
-	set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
+	set_next_event_mem(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
 	return 0;
 }
 
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 73c7139c866f..d59537afb29d 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -25,6 +25,7 @@
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
 	ARCH_TIMER_REG_TVAL,
+	ARCH_TIMER_REG_CVAL,
 };
 
 enum arch_timer_ppi_nr {
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:45 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:45 +0100
Subject: [PATCH 07/13] clocksource/arm_arch_timer: Advertise 56bit timer to
 the core code
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-8-maz@kernel.org>

Proudly tell the code code that we have a timer able to handle
56 bits deltas.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/clocksource/arm_arch_timer.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 29544b16edf3..895844c33351 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -832,7 +832,7 @@ static void __arch_timer_setup(unsigned type,
 
 	clk->set_state_shutdown(clk);
 
-	clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
+	clockevents_config_and_register(clk, arch_timer_rate, 0xf, CLOCKSOURCE_MASK(56));
 }
 
 static void arch_timer_evtstrm_enable(int divider)
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:43 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:43 +0100
Subject: [PATCH 05/13] clocksource/arm_arch_timer: Fix MMIO base address vs
 callback ordering issue
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-6-maz@kernel.org>

The MMIO timer base address gets published after we have registered
the callbacks and the interrupt handler, which is... a bit dangerous.

Fix this by moving the base address publication to the point where
we register the timer, and expose a pointer to the timer structure
itself rather than a naked value.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/clocksource/arm_arch_timer.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 160464f75017..ca7761d8459a 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -54,13 +54,13 @@
 
 static unsigned arch_timers_present __initdata;
 
-static void __iomem *arch_counter_base __ro_after_init;
-
 struct arch_timer {
 	void __iomem *base;
 	struct clock_event_device evt;
 };
 
+static struct arch_timer *arch_timer_mem __ro_after_init;
+
 #define to_arch_timer(e) container_of(e, struct arch_timer, evt)
 
 static u32 arch_timer_rate __ro_after_init;
@@ -975,9 +975,9 @@ static u64 arch_counter_get_cntvct_mem(void)
 	u32 vct_lo, vct_hi, tmp_hi;
 
 	do {
-		vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI);
-		vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO);
-		tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI);
+		vct_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI);
+		vct_lo = readl_relaxed(arch_timer_mem->base + CNTVCT_LO);
+		tmp_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI);
 	} while (vct_hi != tmp_hi);
 
 	return ((u64) vct_hi << 32) | vct_lo;
@@ -1168,25 +1168,25 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq)
 {
 	int ret;
 	irq_handler_t func;
-	struct arch_timer *t;
 
-	t = kzalloc(sizeof(*t), GFP_KERNEL);
-	if (!t)
+	arch_timer_mem = kzalloc(sizeof(*arch_timer_mem), GFP_KERNEL);
+	if (!arch_timer_mem)
 		return -ENOMEM;
 
-	t->base = base;
-	t->evt.irq = irq;
-	__arch_timer_setup(ARCH_TIMER_TYPE_MEM, &t->evt);
+	arch_timer_mem->base = base;
+	arch_timer_mem->evt.irq = irq;
+	__arch_timer_setup(ARCH_TIMER_TYPE_MEM, &arch_timer_mem->evt);
 
 	if (arch_timer_mem_use_virtual)
 		func = arch_timer_handler_virt_mem;
 	else
 		func = arch_timer_handler_phys_mem;
 
-	ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &t->evt);
+	ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &arch_timer_mem->evt);
 	if (ret) {
 		pr_err("Failed to request mem timer irq\n");
-		kfree(t);
+		kfree(arch_timer_mem);
+		arch_timer_mem = NULL;
 	}
 
 	return ret;
@@ -1444,7 +1444,6 @@ arch_timer_mem_frame_register(struct arch_timer_mem_frame *frame)
 		return ret;
 	}
 
-	arch_counter_base = base;
 	arch_timers_present |= ARCH_TIMER_TYPE_MEM;
 
 	return 0;
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:44 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:44 +0100
Subject: [PATCH 06/13] clocksource/arm_arch_timer: Move MMIO timer programming
 over to CVAL
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-7-maz@kernel.org>

Similarily to the sysreg-based timer, move the MMIO over to using
the CVAL registers instead of TVAL. Note that there is no warranty
that the 64bit MMIO access will be atomic, but the timer is always
disabled at the point where we program CVAL.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm/include/asm/arch_timer.h    |  1 +
 drivers/clocksource/arm_arch_timer.c | 50 ++++++++++++++++++++--------
 2 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index b48de9d26f27..d21a7f788d7b 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -7,6 +7,7 @@
 #include <asm/hwcap.h>
 #include <linux/clocksource.h>
 #include <linux/init.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include <linux/types.h>
 
 #include <clocksource/arm_arch_timer.h>
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index ca7761d8459a..29544b16edf3 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -44,11 +44,13 @@
 #define CNTACR_RWVT	BIT(4)
 #define CNTACR_RWPT	BIT(5)
 
-#define CNTVCT_LO	0x08
-#define CNTVCT_HI	0x0c
+#define CNTVCT_LO	0x00
+#define CNTPCT_LO	0x08
 #define CNTFRQ		0x10
+#define CNTP_CVAL_LO	0x20
 #define CNTP_TVAL	0x28
 #define CNTP_CTL	0x2c
+#define CNTV_CVAL_LO	0x30
 #define CNTV_TVAL	0x38
 #define CNTV_CTL	0x3c
 
@@ -113,7 +115,12 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
 			writel_relaxed((u32)val, timer->base + CNTP_TVAL);
 			break;
 		case ARCH_TIMER_REG_CVAL:
-			BUG();
+			/*
+			 * Not guaranteed to be atomic, so the timer
+			 * must be disabled at this point.
+			 */
+			writeq_relaxed(val, timer->base + CNTP_CVAL_LO);
+			break;
 		}
 	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
 		struct arch_timer *timer = to_arch_timer(clk);
@@ -125,7 +132,9 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
 			writel_relaxed((u32)val, timer->base + CNTV_TVAL);
 			break;
 		case ARCH_TIMER_REG_CVAL:
-			BUG();
+			/* Same restriction as above */
+			writeq_relaxed(val, timer->base + CNTV_CVAL_LO);
+			break;
 		}
 	} else {
 		arch_timer_reg_write_cp15(access, reg, val);
@@ -722,15 +731,36 @@ static int arch_timer_set_next_event_phys(unsigned long evt,
 	return 0;
 }
 
+static u64 arch_counter_get_cnt_mem(struct arch_timer *t, int offset_lo)
+{
+	u32 cnt_lo, cnt_hi, tmp_hi;
+
+	do {
+		cnt_hi = readl_relaxed(t->base + offset_lo + 4);
+		cnt_lo = readl_relaxed(t->base + offset_lo);
+		tmp_hi = readl_relaxed(t->base + offset_lo + 4);
+	} while (cnt_hi != tmp_hi);
+
+	return ((u64) cnt_hi << 32) | cnt_lo;
+}
+
 static __always_inline void set_next_event_mem(const int access, unsigned long evt,
 					   struct clock_event_device *clk)
 {
+	struct arch_timer *timer = to_arch_timer(clk);
 	unsigned long ctrl;
+	u64 cnt;
+
 	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
 	ctrl |= ARCH_TIMER_CTRL_ENABLE;
 	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
 
-	arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
+	if (access ==  ARCH_TIMER_MEM_VIRT_ACCESS)
+		cnt = arch_counter_get_cnt_mem(timer, CNTVCT_LO);
+	else
+		cnt = arch_counter_get_cnt_mem(timer, CNTPCT_LO);
+
+	arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk);
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
@@ -972,15 +1002,7 @@ bool arch_timer_evtstrm_available(void)
 
 static u64 arch_counter_get_cntvct_mem(void)
 {
-	u32 vct_lo, vct_hi, tmp_hi;
-
-	do {
-		vct_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI);
-		vct_lo = readl_relaxed(arch_timer_mem->base + CNTVCT_LO);
-		tmp_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI);
-	} while (vct_hi != tmp_hi);
-
-	return ((u64) vct_hi << 32) | vct_lo;
+	return arch_counter_get_cnt_mem(arch_timer_mem, CNTVCT_LO);
 }
 
 static struct arch_timer_kvm_info arch_timer_kvm_info;
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:46 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:46 +0100
Subject: [PATCH 08/13] clocksource/arm_arch_timer: Work around broken CVAL
 implementations
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-9-maz@kernel.org>

The Applied Micro XGene-1 SoC has a busted implementation of the
CVAL register: it looks like it is based on TVAL instead of the
other way around. The net effect of this implementation blunder
is that the maximum deadline you can program in the timer is
32bit wide.

Detect the problematic case and limit the timer to 32bit deltas.
Note that we don't tie this bug to XGene specifically, as it may
also catch similar defects on other high-quality implementations.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/clocksource/arm_arch_timer.c | 38 +++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 895844c33351..1c596cd3cc5c 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -778,9 +778,42 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
 	return 0;
 }
 
+static u64 __arch_timer_check_delta(void)
+{
+#ifdef CONFIG_ARM64
+	u64 tmp;
+
+	/*
+	 * XGene-1 implements CVAL in terms of TVAL, meaning that the
+	 * maximum timer range is 32bit. Shame on them. Detect the
+	 * issue by setting a timer to now+(1<<32), which will
+	 * immediately fire on the duff CPU.
+	 */
+	write_sysreg(0, cntv_ctl_el0);
+	isb();
+	tmp = read_sysreg(cntvct_el0) | BIT(32);
+	write_sysreg(tmp, cntv_cval_el0);
+	write_sysreg(ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK,
+		     cntv_ctl_el0);
+	isb();
+
+	tmp = read_sysreg(cntv_ctl_el0);
+	write_sysreg(0, cntv_ctl_el0);
+	isb();
+
+	if (tmp & ARCH_TIMER_CTRL_IT_STAT) {
+		pr_warn_once("Detected broken implementation, limiting width to 32bits");
+		return CLOCKSOURCE_MASK(32);
+	}
+#endif
+	return CLOCKSOURCE_MASK(56);
+}
+
 static void __arch_timer_setup(unsigned type,
 			       struct clock_event_device *clk)
 {
+	u64 max_delta;
+
 	clk->features = CLOCK_EVT_FEAT_ONESHOT;
 
 	if (type == ARCH_TIMER_TYPE_CP15) {
@@ -812,6 +845,7 @@ static void __arch_timer_setup(unsigned type,
 		}
 
 		clk->set_next_event = sne;
+		max_delta = __arch_timer_check_delta();
 	} else {
 		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
 		clk->name = "arch_mem_timer";
@@ -828,11 +862,13 @@ static void __arch_timer_setup(unsigned type,
 			clk->set_next_event =
 				arch_timer_set_next_event_phys_mem;
 		}
+
+		max_delta = CLOCKSOURCE_MASK(56);
 	}
 
 	clk->set_state_shutdown(clk);
 
-	clockevents_config_and_register(clk, arch_timer_rate, 0xf, CLOCKSOURCE_MASK(56));
+	clockevents_config_and_register(clk, arch_timer_rate, 0xf, max_delta);
 }
 
 static void arch_timer_evtstrm_enable(int divider)
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:47 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:47 +0100
Subject: [PATCH 09/13] clocksource/arm_arch_timer: Remove any trace of the
 TVAL programming interface
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-10-maz@kernel.org>

TVAL usage is now long gone, get rid of the leftovers.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm/include/asm/arch_timer.h    |  6 ------
 arch/arm64/include/asm/arch_timer.h  |  6 ------
 drivers/clocksource/arm_arch_timer.c | 10 ----------
 include/clocksource/arm_arch_timer.h |  1 -
 4 files changed, 23 deletions(-)

diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index d21a7f788d7b..f014630259cb 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -35,8 +35,6 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		case ARCH_TIMER_REG_CVAL:
 			asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			BUG();
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
 		switch (reg) {
@@ -46,8 +44,6 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		case ARCH_TIMER_REG_CVAL:
 			asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			BUG();
 		}
 	}
 
@@ -64,7 +60,6 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 		case ARCH_TIMER_REG_CTRL:
 			asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
 			break;
-		case ARCH_TIMER_REG_TVAL:
 		case ARCH_TIMER_REG_CVAL:
 			BUG();
 		}
@@ -73,7 +68,6 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 		case ARCH_TIMER_REG_CTRL:
 			asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
 			break;
-		case ARCH_TIMER_REG_TVAL:
 		case ARCH_TIMER_REG_CVAL:
 			BUG();
 		}
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 6ceb050ae7b9..861cafc4aca5 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -99,8 +99,6 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		case ARCH_TIMER_REG_CVAL:
 			write_sysreg(val, cntp_cval_el0);
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			BUG();
 		}
 	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
 		switch (reg) {
@@ -110,8 +108,6 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		case ARCH_TIMER_REG_CVAL:
 			write_sysreg(val, cntv_cval_el0);
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			BUG();
 		}
 	}
 
@@ -125,7 +121,6 @@ u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			return read_sysreg(cntp_ctl_el0);
-		case ARCH_TIMER_REG_TVAL:
 		case ARCH_TIMER_REG_CVAL:
 			break;
 		}
@@ -133,7 +128,6 @@ u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			return read_sysreg(cntv_ctl_el0);
-		case ARCH_TIMER_REG_TVAL:
 		case ARCH_TIMER_REG_CVAL:
 			break;
 		}
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 1c596cd3cc5c..fa09952b94bf 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -48,10 +48,8 @@
 #define CNTPCT_LO	0x08
 #define CNTFRQ		0x10
 #define CNTP_CVAL_LO	0x20
-#define CNTP_TVAL	0x28
 #define CNTP_CTL	0x2c
 #define CNTV_CVAL_LO	0x30
-#define CNTV_TVAL	0x38
 #define CNTV_CTL	0x3c
 
 static unsigned arch_timers_present __initdata;
@@ -111,9 +109,6 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
 		case ARCH_TIMER_REG_CTRL:
 			writel_relaxed((u32)val, timer->base + CNTP_CTL);
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			writel_relaxed((u32)val, timer->base + CNTP_TVAL);
-			break;
 		case ARCH_TIMER_REG_CVAL:
 			/*
 			 * Not guaranteed to be atomic, so the timer
@@ -128,9 +123,6 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
 		case ARCH_TIMER_REG_CTRL:
 			writel_relaxed((u32)val, timer->base + CNTV_CTL);
 			break;
-		case ARCH_TIMER_REG_TVAL:
-			writel_relaxed((u32)val, timer->base + CNTV_TVAL);
-			break;
 		case ARCH_TIMER_REG_CVAL:
 			/* Same restriction as above */
 			writeq_relaxed(val, timer->base + CNTV_CVAL_LO);
@@ -153,7 +145,6 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
 		case ARCH_TIMER_REG_CTRL:
 			val = readl_relaxed(timer->base + CNTP_CTL);
 			break;
-		case ARCH_TIMER_REG_TVAL:
 		case ARCH_TIMER_REG_CVAL:
 			BUG();
 		}
@@ -163,7 +154,6 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
 		case ARCH_TIMER_REG_CTRL:
 			val = readl_relaxed(timer->base + CNTV_CTL);
 			break;
-		case ARCH_TIMER_REG_TVAL:
 		case ARCH_TIMER_REG_CVAL:
 			BUG();
 		}
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index d59537afb29d..e715bdb720d5 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -24,7 +24,6 @@
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-	ARCH_TIMER_REG_TVAL,
 	ARCH_TIMER_REG_CVAL,
 };
 
-- 
2.30.2



From robh at kernel.org  Mon Aug  9 08:27:01 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 9 Aug 2021 09:27:01 -0600
Subject: [PATCH 3/3] PCI/ACPI: Add new quirk detection, enable bcm2711
In-Reply-To: <5f4f484b-9eef-2722-405d-a7ff6259aa0f@arm.com>
References: <20210806221256.GA1891371@bjorn-Precision-5520>
 <5f4f484b-9eef-2722-405d-a7ff6259aa0f@arm.com>
Message-ID: <CAL_JsqL=ipGBOsMUaCDvAETX5DQ2tCunNSAtFs6VZybOW7Xrdg@mail.gmail.com>

On Fri, Aug 6, 2021 at 6:35 PM Jeremy Linton <jeremy.linton at arm.com> wrote:
>
> Hi,
>
> Thanks for looking at this.
>
> On 8/6/21 5:12 PM, Bjorn Helgaas wrote:
> > In subject, this or similar would match history:
> >
> >    PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
> >
> > On Thu, Aug 05, 2021 at 04:12:00PM -0500, Jeremy Linton wrote:
> >> Now that we have a bcm2711 quirk, we need to be able to
> >> detect it when the MCFG is missing. Use a namespace
> >> property as an alternative to the MCFG OEM.
> >
> > Rewrap to use ~75 columns.
> >
> > Mention the DT namespace property here.
> >
> >> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> >> ---
> >>   drivers/acpi/pci_mcfg.c | 14 ++++++++++++++
> >>   1 file changed, 14 insertions(+)
> >>
> >> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
> >> index 53cab975f612..7d77fc72c2a4 100644
> >> --- a/drivers/acpi/pci_mcfg.c
> >> +++ b/drivers/acpi/pci_mcfg.c
> >> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
> >>      ALTRA_ECAM_QUIRK(1, 13),
> >>      ALTRA_ECAM_QUIRK(1, 14),
> >>      ALTRA_ECAM_QUIRK(1, 15),
> >> +
> >> +    { "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
> >> +      DEFINE_RES_MEM(0xFD500000, 0xA000) },
> >>   };
> >>
> >>   static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
> >> @@ -198,8 +201,19 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
> >>      u16 segment = root->segment;
> >>      struct resource *bus_range = &root->secondary;
> >>      struct mcfg_fixup *f;
> >> +    const char *soc;
> >>      int i;
> >>
> >> +    /*
> >> +     * This could be a machine with a PCI/SMC conduit,
> >> +     * which means it doens't have MCFG. Get the machineid from
> >> +     * the namespace definition instead.
> >
> > s/SMC/SMCCC/ ?  Cover letter uses SMCCC (not sure it's relevant anyway)
> > s/doens't/doesn't/
> >
> > Rewrap comment to use ~80 columns.
> >
> > Seems pretty reasonable that a platform without standard ECAM might
> > not have MCFG, since MCFG basically implies ECAM.
>
>
> Sure, on all the above comments.
>
> >
> > Is "linux,pcie-quirk" the right property to look for?  It doesn't
> > sound very generic, and it doesn't sound like anything related to
> > ECAM.  Is it new?  I don't see it in the tree yet.  Should it be in
> > Documentation/devicetree/bindings/pci/pci.txt so we don't get a
> > different property name for every new platform?

No, it should not be in pci.txt. Nothing to do with DT and I don't
review ACPI bindings (someone should) if I can help it.

> Yes, I made it up. Someone else commented about the "linux," partially
> because it should be "linux-" to conform with
> https://github.com/UEFI/DSD-Guide. But also in the same context of it
> being linux specific.  I think that guide is where it should end up,
> rather than the devicetree bindings.
>
> I guess we can request addition to the uefi- but that seems like a
> mistake this is really (hopefully?) a Linux specific properly as other
> OS's will simply use the SMC. I think we could request another prefix if
> we come up with a good one and think it belongs in that guide.

It's only Linux specific until it's not.

What happens when there's a second PCIe quirk here? Say what the quirk
is (and not in terms of Linux policy).

Don't you know the device here and can imply all this (like implying
off of 'compatible' in DT)? Adding properties to address issues
creates compatibility issues. Maybe not an issue in this case if the
firmware is not stable, but not a good practice to be in.

Rob


From ziy at nvidia.com  Mon Aug  9 08:35:39 2021
From: ziy at nvidia.com (Zi Yan)
Date: Mon, 09 Aug 2021 11:35:39 -0400
Subject: [RFC PATCH 14/15] mm: introduce MIN_MAX_ORDER to replace
 MAX_ORDER as compile time constant.
In-Reply-To: <YQ+UbJtSWciIVqr4@kernel.org>
References: <20210805190253.2795604-1-zi.yan@sent.com>
 <20210805190253.2795604-15-zi.yan@sent.com> <YQ+UbJtSWciIVqr4@kernel.org>
Message-ID: <D69C9107-F7ED-4E18-86D8-77877992F08F@nvidia.com>

On 8 Aug 2021, at 4:23, Mike Rapoport wrote:

> On Thu, Aug 05, 2021 at 03:02:52PM -0400, Zi Yan wrote:
>> From: Zi Yan <ziy at nvidia.com>
>>
>> For other MAX_ORDER uses (described below), there is no need or too much
>> hassle to convert certain static array to dynamic ones. Add
>> MIN_MAX_ORDER to serve as compile time constant in place of MAX_ORDER.
>>
>> ARM64 hypervisor maintains its own free page list and does not import
>> any core kernel symbols, so soon-to-be runtime variable MAX_ORDER is not
>> accessible in ARM64 hypervisor code. Also there is no need to allocating
>> very large pages.
>>
>> In SLAB/SLOB/SLUB, 2-D array kmalloc_caches uses MAX_ORDER in its second
>> dimension. It is too much hassle to allocate memory for kmalloc_caches
>> before any proper memory allocator is set up.
>>
>> Signed-off-by: Zi Yan <ziy at nvidia.com>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Christoph Lameter <cl at linux.com>
>> Cc: Vlastimil Babka <vbabka at suse.cz>
>> Cc: Quentin Perret <qperret at google.com>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: kvmarm at lists.cs.columbia.edu
>> Cc: linux-mm at kvack.org
>> Cc: linux-kernel at vger.kernel.org
>> ---
>>  arch/arm64/kvm/hyp/include/nvhe/gfp.h | 2 +-
>>  arch/arm64/kvm/hyp/nvhe/page_alloc.c  | 3 ++-
>>  include/linux/mmzone.h                | 3 +++
>>  include/linux/slab.h                  | 8 ++++----
>>  mm/slab.c                             | 2 +-
>>  mm/slub.c                             | 7 ++++---
>>  6 files changed, 15 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
>> index fb0f523d1492..c774b4a98336 100644
>> --- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h
>> +++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h
>> @@ -16,7 +16,7 @@ struct hyp_pool {
>>  	 * API at EL2.
>>  	 */
>>  	hyp_spinlock_t lock;
>> -	struct list_head free_area[MAX_ORDER];
>> +	struct list_head free_area[MIN_MAX_ORDER];
>>  	phys_addr_t range_start;
>>  	phys_addr_t range_end;
>>  	unsigned short max_order;
>> diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
>> index 41fc25bdfb34..a1cc1b648de0 100644
>> --- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
>> +++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
>> @@ -226,7 +226,8 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
>>  	int i;
>>
>>  	hyp_spin_lock_init(&pool->lock);
>> -	pool->max_order = min(MAX_ORDER, get_order(nr_pages << PAGE_SHIFT));
>> +
>> +	pool->max_order = min(MIN_MAX_ORDER, get_order(nr_pages << PAGE_SHIFT));
>>  	for (i = 0; i < pool->max_order; i++)
>>  		INIT_LIST_HEAD(&pool->free_area[i]);
>>  	pool->range_start = phys;
>> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
>> index 09aafc05aef4..379dada82d4b 100644
>> --- a/include/linux/mmzone.h
>> +++ b/include/linux/mmzone.h
>> @@ -27,11 +27,14 @@
>>  #ifndef CONFIG_ARCH_FORCE_MAX_ORDER
>>  #ifdef CONFIG_SET_MAX_ORDER
>>  #define MAX_ORDER CONFIG_SET_MAX_ORDER
>> +#define MIN_MAX_ORDER CONFIG_SET_MAX_ORDER
>>  #else
>>  #define MAX_ORDER 11
>> +#define MIN_MAX_ORDER MAX_ORDER
>>  #endif /* CONFIG_SET_MAX_ORDER */
>>  #else
>>  #define MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
>> +#define MIN_MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
>>  #endif /* CONFIG_ARCH_FORCE_MAX_ORDER */
>>  #define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))
>
> The end result of this #ifdef explosion looks entirely unreadable:

Just to clarify the use of #ifdef:

MAX_ORDER is changed to a boot time variable and it cannot be used
for static array declaration, so I added MIN_MAX_ORDER.

At the moment, there are three cases of setting MAX_ORDER and
MIN_MAX_ORDER:

1. CONFIG_ARCH_FORCE_MAX_ORDER tells the MAX_ORDER certain arch
needs at compilation time.
2. CONFIG_SET_MAX_ORDER allows to change MAX_ORDER when an arch
does not set its MAX_ORER and SPARSEMEM_VMEMMAP is set.
3. !SPARSEMEM_VMEMMAP and no CONFIG_ARCH_FORCE_MAX_ORDER, then
MAX_ORDER is set to 11 by default.

I agree the code is hard to read, I will clean this up.


>
> /* Free memory management - zoned buddy allocator.  */
> #ifndef CONFIG_ARCH_FORCE_MAX_ORDER
> #ifdef CONFIG_SET_MAX_ORDER
> /* Defined in mm/page_alloc.c */
> extern int buddy_alloc_max_order;
>
> #define MAX_ORDER buddy_alloc_max_order
> #define MIN_MAX_ORDER CONFIG_SET_MAX_ORDER
> #else
> #define MAX_ORDER 11
> #define MIN_MAX_ORDER MAX_ORDER
> #endif /* CONFIG_SET_MAX_ORDER */
> #else
>
> #ifdef CONFIG_SPARSEMEM_VMEMMAP
> /* Defined in mm/page_alloc.c */
> extern int buddy_alloc_max_order;
>
> #define MAX_ORDER buddy_alloc_max_order
> #else
> #define MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
> #endif /* CONFIG_SPARSEMEM_VMEMMAP */
> #define MIN_MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
> #endif /* CONFIG_ARCH_FORCE_MAX_ORDER */
>
>> diff --git a/include/linux/slab.h b/include/linux/slab.h
>> index 2c0d80cca6b8..d8747c158db6 100644
>> --- a/include/linux/slab.h
>> +++ b/include/linux/slab.h
>> @@ -244,8 +244,8 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
>>   * to do various tricks to work around compiler limitations in order to
>>   * ensure proper constant folding.
>>   */
>> -#define KMALLOC_SHIFT_HIGH	((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
>> -				(MAX_ORDER + PAGE_SHIFT - 1) : 25)
>> +#define KMALLOC_SHIFT_HIGH	((MIN_MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
>> +				(MIN_MAX_ORDER + PAGE_SHIFT - 1) : 25)
>>  #define KMALLOC_SHIFT_MAX	KMALLOC_SHIFT_HIGH
>>  #ifndef KMALLOC_SHIFT_LOW
>>  #define KMALLOC_SHIFT_LOW	5
>> @@ -258,7 +258,7 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
>>   * (PAGE_SIZE*2).  Larger requests are passed to the page allocator.
>>   */
>>  #define KMALLOC_SHIFT_HIGH	(PAGE_SHIFT + 1)
>> -#define KMALLOC_SHIFT_MAX	(MAX_ORDER + PAGE_SHIFT - 1)
>> +#define KMALLOC_SHIFT_MAX	(MIN_MAX_ORDER + PAGE_SHIFT - 1)
>>  #ifndef KMALLOC_SHIFT_LOW
>>  #define KMALLOC_SHIFT_LOW	3
>>  #endif
>> @@ -271,7 +271,7 @@ static inline void __check_heap_object(const void *ptr, unsigned long n,
>>   * be allocated from the same page.
>>   */
>>  #define KMALLOC_SHIFT_HIGH	PAGE_SHIFT
>> -#define KMALLOC_SHIFT_MAX	(MAX_ORDER + PAGE_SHIFT - 1)
>> +#define KMALLOC_SHIFT_MAX	(MIN_MAX_ORDER + PAGE_SHIFT - 1)
>>  #ifndef KMALLOC_SHIFT_LOW
>>  #define KMALLOC_SHIFT_LOW	3
>>  #endif
>> diff --git a/mm/slab.c b/mm/slab.c
>> index d0f725637663..0041de8ec0e9 100644
>> --- a/mm/slab.c
>> +++ b/mm/slab.c
>> @@ -466,7 +466,7 @@ static int __init slab_max_order_setup(char *str)
>>  {
>>  	get_option(&str, &slab_max_order);
>>  	slab_max_order = slab_max_order < 0 ? 0 :
>> -				min(slab_max_order, MAX_ORDER - 1);
>> +				min(slab_max_order, MIN_MAX_ORDER - 1);
>>  	slab_max_order_set = true;
>>
>>  	return 1;
>> diff --git a/mm/slub.c b/mm/slub.c
>> index b6c5205252eb..228e4a77c678 100644
>> --- a/mm/slub.c
>> +++ b/mm/slub.c
>> @@ -3564,8 +3564,9 @@ static inline int calculate_order(unsigned int size)
>>  	/*
>>  	 * Doh this slab cannot be placed using slub_max_order.
>>  	 */
>> -	order = slab_order(size, 1, MAX_ORDER, 1);
>> -	if (order < MAX_ORDER)
>> +
>> +	order = slab_order(size, 1, MIN_MAX_ORDER, 1);
>> +	if (order < MIN_MAX_ORDER)
>>  		return order;
>>  	return -ENOSYS;
>>  }
>> @@ -4079,7 +4080,7 @@ __setup("slub_min_order=", setup_slub_min_order);
>>  static int __init setup_slub_max_order(char *str)
>>  {
>>  	get_option(&str, (int *)&slub_max_order);
>> -	slub_max_order = min(slub_max_order, (unsigned int)MAX_ORDER - 1);
>> +	slub_max_order = min(slub_max_order, (unsigned int)MIN_MAX_ORDER - 1);
>>
>>  	return 1;
>>  }
>> -- 
>> 2.30.2
>>
>
> -- 
> Sincerely yours,
> Mike.


?
Best Regards,
Yan, Zi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 854 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210809/295e1548/attachment.sig>

From robh at kernel.org  Mon Aug  9 08:40:08 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 09 Aug 2021 09:40:08 -0600
Subject: [PATCH 2/3] dt-bindings: clock: samsung: convert S5Pv210 AudSS to
 dtschema
In-Reply-To: <20210809135942.100744-3-krzysztof.kozlowski@canonical.com>
References: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>
 <20210809135942.100744-3-krzysztof.kozlowski@canonical.com>
Message-ID: <1628523608.157762.3895394.nullmailer@robh.at.kernel.org>

On Mon, 09 Aug 2021 15:59:41 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung S5Pv210 Audio SubSystem clock controller bindings to DT
> schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/clk-s5pv210-audss.txt      | 53 -------------
>  .../clock/samsung,s5pv210-audss-clock.yaml    | 75 +++++++++++++++++++
>  2 files changed, 75 insertions(+), 53 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.example.dts:24.31-32 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1515121

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From maz at kernel.org  Mon Aug  9 08:26:50 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:50 +0100
Subject: [PATCH 12/13] arm64: Add a capability for FEAT_EVC
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-13-maz@kernel.org>

Add a new capability to detect the Enhanced Counter Virtualization
feature (FEAT_EVC).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 10 ++++++++++
 arch/arm64/tools/cpucaps       |  1 +
 2 files changed, 11 insertions(+)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0ead8bfedf20..9c2ce5408811 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1899,6 +1899,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
+	{
+		.desc = "Enhanced counter virtualization",
+		.capability = ARM64_HAS_ECV,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_cpuid_feature,
+		.sys_reg = SYS_ID_AA64MMFR0_EL1,
+		.field_pos = ID_AA64MMFR0_ECV_SHIFT,
+		.sign = FTR_UNSIGNED,
+		.min_field_value = 1,
+	},
 #ifdef CONFIG_ARM64_PAN
 	{
 		.desc = "Privileged Access Never",
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 49305c2e6dfd..7a7c58acd8f0 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -18,6 +18,7 @@ HAS_CRC32
 HAS_DCPODP
 HAS_DCPOP
 HAS_E0PD
+HAS_ECV
 HAS_EPAN
 HAS_GENERIC_AUTH
 HAS_GENERIC_AUTH_ARCH
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:48 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:48 +0100
Subject: [PATCH 10/13] clocksource/arm_arch_timer: Drop unnecessary ISB on
 CVAL programming
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-11-maz@kernel.org>

Switching from TVAL to CVAL has a small drawback: we need an ISB
before reading the counter. We cannot get rid of it, but we can
instead remove the one that comes just after writing to CVAL.

This reduces the number of ISBs from 3 to 2 when programming
the timer.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm/include/asm/arch_timer.h   | 4 ++--
 arch/arm64/include/asm/arch_timer.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index f014630259cb..787a98ed0716 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -31,6 +31,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
+			isb();
 			break;
 		case ARCH_TIMER_REG_CVAL:
 			asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
@@ -40,14 +41,13 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
+			isb();
 			break;
 		case ARCH_TIMER_REG_CVAL:
 			asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
 			break;
 		}
 	}
-
-	isb();
 }
 
 static __always_inline
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 861cafc4aca5..b2f056db1225 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -95,6 +95,7 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			write_sysreg(val, cntp_ctl_el0);
+			isb();
 			break;
 		case ARCH_TIMER_REG_CVAL:
 			write_sysreg(val, cntp_cval_el0);
@@ -104,14 +105,13 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
 		switch (reg) {
 		case ARCH_TIMER_REG_CTRL:
 			write_sysreg(val, cntv_ctl_el0);
+			isb();
 			break;
 		case ARCH_TIMER_REG_CVAL:
 			write_sysreg(val, cntv_cval_el0);
 			break;
 		}
 	}
-
-	isb();
 }
 
 static __always_inline
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:51 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:51 +0100
Subject: [PATCH 13/13] arm64: Add CNT{P, V}CTSS_EL0 alternatives to cnt{p,
 v}ct_el0
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-14-maz@kernel.org>

CNTPCTSS_EL0 and CNTVCTSS_EL0 are alternatives to the usual
CNTPCT_EL0 and CNTVCT_EL0 that do not require a previous ISB
to be synchronised (SS stands for Self-Synchronising).

Use the ARM64_HAS_ECV capability to control alternative sequences
that switch to these low(er)-cost primitives. Note that the
counter access in the VDSO is for now left alone until we decide
whether we want to allow this.

For a good measure, wire the cntvct hooks to also handle CNTVCTSS.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/arch_timer.h | 30 +++++++++++++++++++++++------
 arch/arm64/include/asm/esr.h        |  6 ++++++
 arch/arm64/include/asm/sysreg.h     |  3 +++
 arch/arm64/kernel/traps.c           | 11 +++++++++++
 4 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index b2f056db1225..785411a48512 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -64,12 +64,26 @@ DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
 
 static inline notrace u64 arch_timer_read_cntpct_el0(void)
 {
-	return read_sysreg(cntpct_el0);
+	u64 cnt;
+
+	asm volatile(ALTERNATIVE("isb\n mrs %x0, cntpct_el0",
+				 "nop\n" __mrs_s("%x0", SYS_CNTPCTSS_EL0),
+				 ARM64_HAS_ECV)
+		     : "=r" (cnt));
+
+	return cnt;
 }
 
 static inline notrace u64 arch_timer_read_cntvct_el0(void)
 {
-	return read_sysreg(cntvct_el0);
+	u64 cnt;
+
+	asm volatile(ALTERNATIVE("isb\n mrs %x0, cntvct_el0",
+				 "nop\n" __mrs_s("%x0", SYS_CNTVCTSS_EL0),
+				 ARM64_HAS_ECV)
+		     : "=r" (cnt));
+
+	return cnt;
 }
 
 #define arch_timer_reg_read_stable(reg)					\
@@ -166,8 +180,10 @@ static __always_inline u64 __arch_counter_get_cntpct(void)
 {
 	u64 cnt;
 
-	isb();
-	cnt = read_sysreg(cntpct_el0);
+	asm volatile(ALTERNATIVE("isb\n mrs %x0, cntpct_el0",
+				 "nop\n" __mrs_s("%x0", SYS_CNTPCTSS_EL0),
+				 ARM64_HAS_ECV)
+		     : "=r" (cnt));
 	arch_counter_enforce_ordering(cnt);
 	return cnt;
 }
@@ -186,8 +202,10 @@ static __always_inline u64 __arch_counter_get_cntvct(void)
 {
 	u64 cnt;
 
-	isb();
-	cnt = read_sysreg(cntvct_el0);
+	asm volatile(ALTERNATIVE("isb\n mrs %x0, cntvct_el0",
+				 "nop\n" __mrs_s("%x0", SYS_CNTVCTSS_EL0),
+				 ARM64_HAS_ECV)
+		     : "=r" (cnt));
 	arch_counter_enforce_ordering(cnt);
 	return cnt;
 }
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 29f97eb3dad4..a305ce256090 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -227,6 +227,9 @@
 #define ESR_ELx_SYS64_ISS_SYS_CNTVCT	(ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
 					 ESR_ELx_SYS64_ISS_DIR_READ)
 
+#define ESR_ELx_SYS64_ISS_SYS_CNTVCTSS	(ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 6, 14, 0) | \
+					 ESR_ELx_SYS64_ISS_DIR_READ)
+
 #define ESR_ELx_SYS64_ISS_SYS_CNTFRQ	(ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 0, 14, 0) | \
 					 ESR_ELx_SYS64_ISS_DIR_READ)
 
@@ -317,6 +320,9 @@
 #define ESR_ELx_CP15_64_ISS_SYS_CNTVCT	(ESR_ELx_CP15_64_ISS_SYS_VAL(1, 14) | \
 					 ESR_ELx_CP15_64_ISS_DIR_READ)
 
+#define ESR_ELx_CP15_64_ISS_SYS_CNTVCTSS (ESR_ELx_CP15_64_ISS_SYS_VAL(9, 14) | \
+					 ESR_ELx_CP15_64_ISS_DIR_READ)
+
 #define ESR_ELx_CP15_32_ISS_SYS_CNTFRQ	(ESR_ELx_CP15_32_ISS_SYS_VAL(0, 0, 14, 0) |\
 					 ESR_ELx_CP15_32_ISS_DIR_READ)
 
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7b9c3acba684..897f9c882895 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -506,6 +506,9 @@
 
 #define SYS_CNTFRQ_EL0			sys_reg(3, 3, 14, 0, 0)
 
+#define SYS_CNTPCTSS_EL0		sys_reg(3, 3, 14, 0, 5)
+#define SYS_CNTVCTSS_EL0		sys_reg(3, 3, 14, 0, 6)
+
 #define SYS_CNTP_TVAL_EL0		sys_reg(3, 3, 14, 2, 0)
 #define SYS_CNTP_CTL_EL0		sys_reg(3, 3, 14, 2, 1)
 #define SYS_CNTP_CVAL_EL0		sys_reg(3, 3, 14, 2, 2)
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index b03e383d944a..16710ca55fbb 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -653,6 +653,12 @@ static const struct sys64_hook sys64_hooks[] = {
 		.esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCT,
 		.handler = cntvct_read_handler,
 	},
+	{
+		/* Trap read access to CNTVCTSS_EL0 */
+		.esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
+		.esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCTSS,
+		.handler = cntvct_read_handler,
+	},
 	{
 		/* Trap read access to CNTFRQ_EL0 */
 		.esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
@@ -729,6 +735,11 @@ static const struct sys64_hook cp15_64_hooks[] = {
 		.esr_val = ESR_ELx_CP15_64_ISS_SYS_CNTVCT,
 		.handler = compat_cntvct_read_handler,
 	},
+	{
+		.esr_mask = ESR_ELx_CP15_64_ISS_SYS_MASK,
+		.esr_val = ESR_ELx_CP15_64_ISS_SYS_CNTVCTSS,
+		.handler = compat_cntvct_read_handler,
+	},
 	{},
 };
 
-- 
2.30.2



From maz at kernel.org  Mon Aug  9 08:26:49 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon,  9 Aug 2021 16:26:49 +0100
Subject: [PATCH 11/13] clocksource/arm_arch_timer: Fix masking for high freq
 counters
In-Reply-To: <20210809152651.2297337-1-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
Message-ID: <20210809152651.2297337-12-maz@kernel.org>

From: Oliver Upton <oupton at google.com>

Unfortunately, the architecture provides no means to determine the bit
width of the system counter. However, we do know the following from the
specification:

 - the system counter is at least 56 bits wide
 - Roll-over time of not less than 40 years

To date, the arch timer driver has depended on the first property,
assuming any system counter to be 56 bits wide and masking off the rest.
However, combining a narrow clocksource mask with a high frequency
counter could result in prematurely wrapping the system counter by a
significant margin. For example, a 56 bit wide, 1GHz system counter
would wrap in a mere 2.28 years!

This is a problem for two reasons: v8.6+ implementations are required to
provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
implementers may select a counter frequency of their choosing.

Fix the issue by deriving a valid clock mask based on the second
property from above. Set the floor at 56 bits, since we know no system
counter is narrower than that.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
[maz: fixed width computation not to lose the last bit, added
      max delta generation for the timer]
Signed-off-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/r/20210807191428.3488948-1-oupton at google.com
---
 drivers/clocksource/arm_arch_timer.c | 34 ++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index fa09952b94bf..74eca831d0d9 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -52,6 +52,12 @@
 #define CNTV_CVAL_LO	0x30
 #define CNTV_CTL	0x3c
 
+/*
+ * The minimum amount of time a generic counter is guaranteed to not roll over
+ * (40 years)
+ */
+#define MIN_ROLLOVER_SECS	(40ULL * 365 * 24 * 3600)
+
 static unsigned arch_timers_present __initdata;
 
 struct arch_timer {
@@ -95,6 +101,22 @@ static int __init early_evtstrm_cfg(char *buf)
 }
 early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
 
+/*
+ * Makes an educated guess at a valid counter width based on the Generic Timer
+ * specification. Of note:
+ *   1) the system counter is at least 56 bits wide
+ *   2) a roll-over time of not less than 40 years
+ *
+ * See 'ARM DDI 0487G.a D11.1.2 ("The system counter")' for more details.
+ */
+static int arch_counter_get_width(void)
+{
+	u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_rate;
+
+	/* guarantee the returned width is within the valid range */
+	return clamp_val(ilog2(min_cycles - 1) + 1, 56, 64);
+}
+
 /*
  * Architected system timer support.
  */
@@ -208,13 +230,11 @@ static struct clocksource clocksource_counter = {
 	.id	= CSID_ARM_ARCH_COUNTER,
 	.rating	= 400,
 	.read	= arch_counter_read,
-	.mask	= CLOCKSOURCE_MASK(56),
 	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 static struct cyclecounter cyclecounter __ro_after_init = {
 	.read	= arch_counter_read_cc,
-	.mask	= CLOCKSOURCE_MASK(56),
 };
 
 struct ate_acpi_oem_info {
@@ -796,7 +816,7 @@ static u64 __arch_timer_check_delta(void)
 		return CLOCKSOURCE_MASK(32);
 	}
 #endif
-	return CLOCKSOURCE_MASK(56);
+	return CLOCKSOURCE_MASK(arch_counter_get_width());
 }
 
 static void __arch_timer_setup(unsigned type,
@@ -1041,6 +1061,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 static void __init arch_counter_register(unsigned type)
 {
 	u64 start_count;
+	int width;
 
 	/* Register the CP15 based counter if we have one */
 	if (type & ARCH_TIMER_TYPE_CP15) {
@@ -1065,6 +1086,10 @@ static void __init arch_counter_register(unsigned type)
 		arch_timer_read_counter = arch_counter_get_cntvct_mem;
 	}
 
+	width = arch_counter_get_width();
+	clocksource_counter.mask = CLOCKSOURCE_MASK(width);
+	cyclecounter.mask = CLOCKSOURCE_MASK(width);
+
 	if (!arch_counter_suspend_stop)
 		clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 	start_count = arch_timer_read_counter();
@@ -1074,8 +1099,7 @@ static void __init arch_counter_register(unsigned type)
 	timecounter_init(&arch_timer_kvm_info.timecounter,
 			 &cyclecounter, start_count);
 
-	/* 56 bits minimum, so we assume worst case rollover */
-	sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
+	sched_clock_register(arch_timer_read_counter, width, arch_timer_rate);
 }
 
 static void arch_timer_stop(struct clock_event_device *clk)
-- 
2.30.2



From mka at chromium.org  Mon Aug  9 08:49:50 2021
From: mka at chromium.org (Matthias Kaehlcke)
Date: Mon, 9 Aug 2021 08:49:50 -0700
Subject: [PATCH v15 0/6] usb: misc: Add onboard_usb_hub driver
In-Reply-To: <20210727004118.2583774-1-mka@chromium.org>
References: <20210727004118.2583774-1-mka@chromium.org>
Message-ID: <YRFOnhJkB2vi/zwD@google.com>

Hi Greg,

Just wanted to check if this series is still on your radar. Is
there anything that blocks it from landing (further ACKs, ...)?

Thanks

Matthias

On Mon, Jul 26, 2021 at 05:41:12PM -0700, Matthias Kaehlcke wrote:
> This series adds:
> - the onboard_usb_hub_driver
> - glue in the xhci-plat driver to create and destroy the
>   onboard_usb_hub platform devices if needed
> - a device tree binding for the Realtek RTS5411 USB hub controller
> - device tree changes that add RTS5411 entries for the QCA SC7180
>   based boards trogdor and lazor
> - a couple of stubs for platform device functions to avoid
>   unresolved symbols with certain kernel configs
> 
> The main issue the driver addresses is that a USB hub needs to be
> powered before it can be discovered. For discrete onboard hubs (an
> example for such a hub is the Realtek RTS5411) this is often solved
> by supplying the hub with an 'always-on' regulator, which is kind
> of a hack. Some onboard hubs may require further initialization
> steps, like changing the state of a GPIO or enabling a clock, which
> requires even more hacks. This driver creates a platform device
> representing the hub which performs the necessary initialization.
> Currently it only supports switching on a single regulator, support
> for multiple regulators or other actions can be added as needed.
> Different initialization sequences can be supported based on the
> compatible string.
> 
> Besides performing the initialization the driver can be configured
> to power the hub off during system suspend. This can help to extend
> battery life on battery powered devices which have no requirements
> to keep the hub powered during suspend. The driver can also be
> configured to leave the hub powered when a wakeup capable USB device
> is connected when suspending, and power it off otherwise.
> 
> Changes in v15:
> - adjusted dependencies of USB_DWC3_CORE to make sure it can only
>   be enabled when at least one of USB_DWC3_HOST, USB_DWC3_GADGET
>   or USB_DWC3_DUAL_ROLE is selectable
> 
> Changes in v14:
> - rebased on top of v5.14-rc1
> - dropped DT binding patch which landed in v5.13
> 
> Changes in v13:
> - added patch "usb: Specify dependency on USB_XHCI_PLATFORM with
>   'depends on'" to the series to avoid Kconfig conflicts
> - added patch "arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM"
>   to the series to keep effective defconfig unchanged
> 
> Changes in v12:
> - onboard_hub driver: use IS_ENABLED(CONFIG_USB_ONBOARD_HUB_MODULE)
>   in onboard_hub.h to also check for the driver built as module
> - onboard_hub_driver: include onboard_hub.h again to make sure there
>   are prototype declarations for the public functions
> 
> Changes in v11:
> - support multiple onboard hubs connected to the same parent
> - don't include ?onboard_hub.h? from the onboard hub driver
> 
> Changes in v10:
> - always use of_is_onboard_usb_hub() stub unless ONBOARD_USB_HUB=y/m
> - keep 'regulator-boot-on' property for pp3300_hub
> 
> Changes in v9:
> - added dependency on ONBOARD_USB_HUB (or !!ONBOARD_USB_HUB) to
>   USB_PLATFORM_XHCI
> 
> Changes in v7:
> - updated DT binding
> - series rebased on qcom/arm64-for-5.13
> 
> Changes in v6:
> - updated summary
> 
> Changes in v5:
> - cover letter added
> 
> Matthias Kaehlcke (6):
>   usb: misc: Add onboard_usb_hub driver
>   of/platform: Add stubs for of_platform_device_create/destroy()
>   arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM
>   usb: Specify dependencies on USB_XHCI_PLATFORM with 'depends on'
>   usb: host: xhci-plat: Create platform device for onboard hubs in
>     probe()
>   arm64: dts: qcom: sc7180-trogdor: Add nodes for onboard USB hub
> 
>  .../sysfs-bus-platform-onboard-usb-hub        |   8 +
>  MAINTAINERS                                   |   7 +
>  .../boot/dts/qcom/sc7180-trogdor-lazor-r0.dts |  19 +-
>  .../boot/dts/qcom/sc7180-trogdor-lazor-r1.dts |  12 +-
>  .../arm64/boot/dts/qcom/sc7180-trogdor-r1.dts |  19 +-
>  arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |  19 +-
>  arch/arm64/configs/defconfig                  |   1 +
>  drivers/usb/cdns3/Kconfig                     |   2 +-
>  drivers/usb/dwc3/Kconfig                      |   5 +-
>  drivers/usb/host/Kconfig                      |   5 +-
>  drivers/usb/host/xhci-plat.c                  |   6 +
>  drivers/usb/host/xhci.h                       |   2 +
>  drivers/usb/misc/Kconfig                      |  17 +
>  drivers/usb/misc/Makefile                     |   1 +
>  drivers/usb/misc/onboard_usb_hub.c            | 497 ++++++++++++++++++
>  include/linux/of_platform.h                   |  22 +-
>  include/linux/usb/onboard_hub.h               |  18 +
>  17 files changed, 621 insertions(+), 39 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-platform-onboard-usb-hub
>  create mode 100644 drivers/usb/misc/onboard_usb_hub.c
>  create mode 100644 include/linux/usb/onboard_hub.h
> 
> -- 
> 2.32.0.432.gabb21c7263-goog
> 


From lorenzo.pieralisi at arm.com  Mon Aug  9 08:53:43 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 9 Aug 2021 16:53:43 +0100
Subject: [PATCH v6 8/8] PCI: hv: Turn on the host bridge probing on ARM64
In-Reply-To: <YRE9+LaAjAW3SUvc@boqun-archlinux>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-9-boqun.feng@gmail.com>
 <20210803171451.GA15466@lpieralisi>
 <YRE9+LaAjAW3SUvc@boqun-archlinux>
Message-ID: <20210809155343.GA31511@lpieralisi>

On Mon, Aug 09, 2021 at 10:38:48PM +0800, Boqun Feng wrote:
> On Tue, Aug 03, 2021 at 06:14:51PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Jul 27, 2021 at 02:06:57AM +0800, Boqun Feng wrote:
> > > Now we have everything we need, just provide a proper sysdata type for
> > > the bus to use on ARM64 and everything else works.
> > > 
> > > Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
> > > ---
> > >  drivers/pci/controller/pci-hyperv.c | 7 +++++++
> > >  1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> > > index e6276aaa4659..62dbe98d1fe1 100644
> > > --- a/drivers/pci/controller/pci-hyperv.c
> > > +++ b/drivers/pci/controller/pci-hyperv.c
> > > @@ -40,6 +40,7 @@
> > >  #include <linux/kernel.h>
> > >  #include <linux/module.h>
> > >  #include <linux/pci.h>
> > > +#include <linux/pci-ecam.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/semaphore.h>
> > >  #include <linux/irqdomain.h>
> > > @@ -448,7 +449,11 @@ enum hv_pcibus_state {
> > >  };
> > >  
> > >  struct hv_pcibus_device {
> > > +#ifdef CONFIG_X86
> > >  	struct pci_sysdata sysdata;
> > > +#elif defined(CONFIG_ARM64)
> > > +	struct pci_config_window sysdata;
> > 
> > This is ugly. HV does not need pci_config_window at all right
> > (other than arm64 pcibios_root_bridge_prepare()) ?
> > 
> 
> Right.
> 
> > The issue is that in HV you have to have *some* sysdata != NULL, it is
> > just some data to retrieve the hv_pcibus_device.
> > 
> > Mmaybe we can rework ARM64 ACPI code to store the acpi_device in struct
> > pci_host_bridge->private instead of retrieving it from pci_config_window
> > so that we decouple HV from the ARM64 back-end.
> > 
> > HV would just set struct pci_host_bridge->private == NULL.
> > 
> 
> Works for me, but please note that pci_sysdata is an x86-specific
> structure, so we still need to define a fake pci_sysdata inside
> pci-hyperv.c, like:
> 
> 	#ifndef CONFIG_X86
> 	struct pci_sysdata { };
> 	#end
> 
> > I need to think about this a bit, I don't think it should block
> > this series though but it would be nicer.
> 
> After a quick look into the code, seems that what we need to do is to
> add an additional parameter for acpi_pci_root_create() and introduce a
> slightly different version of pci_create_root_bus(). A question is:
> should we only do this for ARM64, or should we also do this for
> other acpi_pci_root_create() users (x86 and ia64)? Another question
> comes to my mind is, while we are at it, is there anything else that we
> want to move from sysdata to ->private? These questions are out of scope
> of this patchset, I think. Maybe it's better that we address them in the
> future, and I can send out separate RFC patches to start the discussion.
> Does that sound like a plan to you?

Yes it does and we can start from ARM64 - what I really don't like
is the arch/arm64 dependency with the HV controller driver as I
described, being forced to have a struct pci_config_window in the
driver is not really nice or clean IMO.

Not that I expect any other PCI host bridge driver with ACPI coming
anytime soon but even if it is not within set (that we can merge) I'd
like to see the decoupling rework done asap, let me put it this way.

Thanks,
Lorenzo

> Regards,
> Boqun
> 
> > 
> > Lorenzo
> > 
> > > +#endif
> > >  	struct pci_host_bridge *bridge;
> > >  	struct fwnode_handle *fwnode;
> > >  	/* Protocol version negotiated with the host */
> > > @@ -3075,7 +3080,9 @@ static int hv_pci_probe(struct hv_device *hdev,
> > >  			 dom_req, dom);
> > >  
> > >  	hbus->bridge->domain_nr = dom;
> > > +#ifdef CONFIG_X86
> > >  	hbus->sysdata.domain = dom;
> > > +#endif
> > >  
> > >  	hbus->hdev = hdev;
> > >  	INIT_LIST_HEAD(&hbus->children);
> > > -- 
> > > 2.32.0
> > > 


From arnd at arndb.de  Mon Aug  9 09:02:36 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 9 Aug 2021 18:02:36 +0200
Subject: [PATCH] ARM: atags_to_fdt: don't warn about stack size
In-Reply-To: <20210809152421.GU22278@shell.armlinux.org.uk>
References: <20210809151021.5137-1-david@ixit.cz>
 <20210809152421.GU22278@shell.armlinux.org.uk>
Message-ID: <CAK8P3a0qB3Nj8-wKPiAJvPrnH9LZjeXdkQA1MfS998RYk5foRA@mail.gmail.com>

On Mon, Aug 9, 2021 at 5:24 PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:
> On Mon, Aug 09, 2021 at 05:10:21PM +0200, David Heidelberg wrote:
> > Signed-off-by: David Heidelberg <david at ixit.cz>

Acked-by: Arnd Bergmann <arnd at arndb.de>

(or keep my original Signed-off-by if you like)

> I assume Arnd never sent his v3 from what I see in the thread you link
> to above.

Yes, it's in my ever-growing backlog of things I plan to eventually resubmit.

In this case, I actually have a different patch in my tree, but that in turn
depends on other stuff I have to submit first (reorganizing the way that
warning options get handled based on compiler version etc), and the
version here is what works on current mainline kernels.

     Arnd


From krzysztof.kozlowski at canonical.com  Mon Aug  9 09:08:14 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 9 Aug 2021 18:08:14 +0200
Subject: [PATCH 2/3] dt-bindings: clock: samsung: convert S5Pv210 AudSS to
 dtschema
In-Reply-To: <1628523608.157762.3895394.nullmailer@robh.at.kernel.org>
References: <20210809135942.100744-1-krzysztof.kozlowski@canonical.com>
 <20210809135942.100744-3-krzysztof.kozlowski@canonical.com>
 <1628523608.157762.3895394.nullmailer@robh.at.kernel.org>
Message-ID: <3ba3aeee-7ee2-2b38-397a-71ea1543163e@canonical.com>

On 09/08/2021 17:40, Rob Herring wrote:
> On Mon, 09 Aug 2021 15:59:41 +0200, Krzysztof Kozlowski wrote:
>> Convert Samsung S5Pv210 Audio SubSystem clock controller bindings to DT
>> schema format using json-schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/clock/clk-s5pv210-audss.txt      | 53 -------------
>>  .../clock/samsung,s5pv210-audss-clock.yaml    | 75 +++++++++++++++++++
>>  2 files changed, 75 insertions(+), 53 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
>>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
>>
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Error: Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.example.dts:24.31-32 syntax error
> FATAL ERROR: Unable to parse input tree
> make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.example.dt.yaml] Error 1
> make[1]: *** Waiting for unfinished jobs....
> make: *** [Makefile:1419: dt_binding_check] Error 2

Thanks, I'll fix it in v2.


Best regards,
Krzysztof


From oupton at google.com  Mon Aug  9 09:12:52 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 09:12:52 -0700
Subject: [PATCH 02/13] clocksource/arm_arch_timer: Extend write side of
 timer register accessors to u64
In-Reply-To: <20210809152651.2297337-3-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-3-maz@kernel.org>
Message-ID: <CAOQ_QshJmjSUGVVLOqGJFicDpGfvf159W8utDWMpuT6i4fCBQQ@mail.gmail.com>

On Mon, Aug 9, 2021 at 8:27 AM Marc Zyngier <maz at kernel.org> wrote:
>
> The various accessors for the timer sysreg and MMIO registers are
> currently hardwired to 32bit. However, we are about to introduce
> the use of the CVAL registers, which require a 64bit access.
>
> Upgrade the write side of the accessors to take a 64bit value
> (the read side is left untouched as we don't plan to ever read
> back any of these registers).
>
> No functional change expected.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Oliver Upton <oupton at google.com>

> ---
>  arch/arm/include/asm/arch_timer.h    | 10 +++++-----
>  arch/arm64/include/asm/arch_timer.h  |  2 +-
>  drivers/clocksource/arm_arch_timer.c | 10 +++++-----
>  3 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
> index 0c09afaa590d..88075c7f4bfd 100644
> --- a/arch/arm/include/asm/arch_timer.h
> +++ b/arch/arm/include/asm/arch_timer.h
> @@ -24,24 +24,24 @@ int arch_timer_arch_init(void);
>   * the code. At least it does so with a recent GCC (4.6.3).
>   */
>  static __always_inline
> -void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
> +void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>  {
>         if (access == ARCH_TIMER_PHYS_ACCESS) {
>                 switch (reg) {
>                 case ARCH_TIMER_REG_CTRL:
> -                       asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
> +                       asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> -                       asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
> +                       asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val));
>                         break;
>                 }
>         } else if (access == ARCH_TIMER_VIRT_ACCESS) {
>                 switch (reg) {
>                 case ARCH_TIMER_REG_CTRL:
> -                       asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
> +                       asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> -                       asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
> +                       asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val));
>                         break;
>                 }
>         }
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index 8e3b2ac60c30..107afb721749 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -89,7 +89,7 @@ static inline notrace u64 arch_timer_read_cntvct_el0(void)
>   * the code.
>   */
>  static __always_inline
> -void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
> +void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>  {
>         if (access == ARCH_TIMER_PHYS_ACCESS) {
>                 switch (reg) {
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 9db5c16e31e7..0b2bac3ef7ce 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -100,27 +100,27 @@ early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
>   */
>
>  static __always_inline
> -void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
> +void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
>                           struct clock_event_device *clk)
>  {
>         if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
>                 struct arch_timer *timer = to_arch_timer(clk);
>                 switch (reg) {
>                 case ARCH_TIMER_REG_CTRL:
> -                       writel_relaxed(val, timer->base + CNTP_CTL);
> +                       writel_relaxed((u32)val, timer->base + CNTP_CTL);
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> -                       writel_relaxed(val, timer->base + CNTP_TVAL);
> +                       writel_relaxed((u32)val, timer->base + CNTP_TVAL);
>                         break;
>                 }
>         } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
>                 struct arch_timer *timer = to_arch_timer(clk);
>                 switch (reg) {
>                 case ARCH_TIMER_REG_CTRL:
> -                       writel_relaxed(val, timer->base + CNTV_CTL);
> +                       writel_relaxed((u32)val, timer->base + CNTV_CTL);
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> -                       writel_relaxed(val, timer->base + CNTV_TVAL);
> +                       writel_relaxed((u32)val, timer->base + CNTV_TVAL);
>                         break;
>                 }
>         } else {
> --
> 2.30.2
>


From oupton at google.com  Mon Aug  9 09:16:38 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 09:16:38 -0700
Subject: [PATCH 04/13] clocksource/arm_arch_timer: Move drop _tval from
 erratum function names
In-Reply-To: <20210809152651.2297337-5-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-5-maz@kernel.org>
Message-ID: <CAOQ_QshxJgSP1y0R3uCgGepTKTqQkU4ELv3BTmQNPY0-B4rTsA@mail.gmail.com>

On Mon, Aug 9, 2021 at 8:27 AM Marc Zyngier <maz at kernel.org> wrote:
>
> The '_tval' name in the erratum handling function names doesn't
> make much sense anymore (and they were using CVAL the first place).
>
> Drop the _tval tag.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Oliver Upton <oupton at google.com>

> ---
>  drivers/clocksource/arm_arch_timer.c | 26 +++++++++++++-------------
>  1 file changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 898a07dc01cd..160464f75017 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -371,7 +371,7 @@ EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
>
>  static atomic_t timer_unstable_counter_workaround_in_use = ATOMIC_INIT(0);
>
> -static void erratum_set_next_event_tval_generic(const int access, unsigned long evt,
> +static void erratum_set_next_event_generic(const int access, unsigned long evt,
>                                                 struct clock_event_device *clk)
>  {
>         unsigned long ctrl;
> @@ -392,17 +392,17 @@ static void erratum_set_next_event_tval_generic(const int access, unsigned long
>         arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
>  }
>
> -static __maybe_unused int erratum_set_next_event_tval_virt(unsigned long evt,
> +static __maybe_unused int erratum_set_next_event_virt(unsigned long evt,
>                                             struct clock_event_device *clk)
>  {
> -       erratum_set_next_event_tval_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
> +       erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
>         return 0;
>  }
>
> -static __maybe_unused int erratum_set_next_event_tval_phys(unsigned long evt,
> +static __maybe_unused int erratum_set_next_event_phys(unsigned long evt,
>                                             struct clock_event_device *clk)
>  {
> -       erratum_set_next_event_tval_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
> +       erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
>         return 0;
>  }
>
> @@ -414,8 +414,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>                 .desc = "Freescale erratum a005858",
>                 .read_cntpct_el0 = fsl_a008585_read_cntpct_el0,
>                 .read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
> -               .set_next_event_phys = erratum_set_next_event_tval_phys,
> -               .set_next_event_virt = erratum_set_next_event_tval_virt,
> +               .set_next_event_phys = erratum_set_next_event_phys,
> +               .set_next_event_virt = erratum_set_next_event_virt,
>         },
>  #endif
>  #ifdef CONFIG_HISILICON_ERRATUM_161010101
> @@ -425,8 +425,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>                 .desc = "HiSilicon erratum 161010101",
>                 .read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
>                 .read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
> -               .set_next_event_phys = erratum_set_next_event_tval_phys,
> -               .set_next_event_virt = erratum_set_next_event_tval_virt,
> +               .set_next_event_phys = erratum_set_next_event_phys,
> +               .set_next_event_virt = erratum_set_next_event_virt,
>         },
>         {
>                 .match_type = ate_match_acpi_oem_info,
> @@ -434,8 +434,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>                 .desc = "HiSilicon erratum 161010101",
>                 .read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
>                 .read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
> -               .set_next_event_phys = erratum_set_next_event_tval_phys,
> -               .set_next_event_virt = erratum_set_next_event_tval_virt,
> +               .set_next_event_phys = erratum_set_next_event_phys,
> +               .set_next_event_virt = erratum_set_next_event_virt,
>         },
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_858921
> @@ -454,8 +454,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>                 .desc = "Allwinner erratum UNKNOWN1",
>                 .read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
>                 .read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
> -               .set_next_event_phys = erratum_set_next_event_tval_phys,
> -               .set_next_event_virt = erratum_set_next_event_tval_virt,
> +               .set_next_event_phys = erratum_set_next_event_phys,
> +               .set_next_event_virt = erratum_set_next_event_virt,
>         },
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_1418040
> --
> 2.30.2
>


From jeremy.linton at arm.com  Mon Aug  9 09:24:46 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Mon, 9 Aug 2021 11:24:46 -0500
Subject: [PATCH 3/3] PCI/ACPI: Add new quirk detection, enable bcm2711
In-Reply-To: <CAL_JsqL=ipGBOsMUaCDvAETX5DQ2tCunNSAtFs6VZybOW7Xrdg@mail.gmail.com>
References: <20210806221256.GA1891371@bjorn-Precision-5520>
 <5f4f484b-9eef-2722-405d-a7ff6259aa0f@arm.com>
 <CAL_JsqL=ipGBOsMUaCDvAETX5DQ2tCunNSAtFs6VZybOW7Xrdg@mail.gmail.com>
Message-ID: <ba0409df-dbd7-b765-48d4-a2db846de689@arm.com>

Hi,

Thanks for looking at this.

On 8/9/21 10:27 AM, Rob Herring wrote:
> On Fri, Aug 6, 2021 at 6:35 PM Jeremy Linton <jeremy.linton at arm.com> wrote:
>>
>> Hi,
>>
>> Thanks for looking at this.
>>
>> On 8/6/21 5:12 PM, Bjorn Helgaas wrote:
>>> In subject, this or similar would match history:
>>>
>>>     PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
>>>
>>> On Thu, Aug 05, 2021 at 04:12:00PM -0500, Jeremy Linton wrote:
>>>> Now that we have a bcm2711 quirk, we need to be able to
>>>> detect it when the MCFG is missing. Use a namespace
>>>> property as an alternative to the MCFG OEM.
>>>
>>> Rewrap to use ~75 columns.
>>>
>>> Mention the DT namespace property here.
>>>
>>>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>>>> ---
>>>>    drivers/acpi/pci_mcfg.c | 14 ++++++++++++++
>>>>    1 file changed, 14 insertions(+)
>>>>
>>>> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
>>>> index 53cab975f612..7d77fc72c2a4 100644
>>>> --- a/drivers/acpi/pci_mcfg.c
>>>> +++ b/drivers/acpi/pci_mcfg.c
>>>> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>>>>       ALTRA_ECAM_QUIRK(1, 13),
>>>>       ALTRA_ECAM_QUIRK(1, 14),
>>>>       ALTRA_ECAM_QUIRK(1, 15),
>>>> +
>>>> +    { "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
>>>> +      DEFINE_RES_MEM(0xFD500000, 0xA000) },
>>>>    };
>>>>
>>>>    static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
>>>> @@ -198,8 +201,19 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
>>>>       u16 segment = root->segment;
>>>>       struct resource *bus_range = &root->secondary;
>>>>       struct mcfg_fixup *f;
>>>> +    const char *soc;
>>>>       int i;
>>>>
>>>> +    /*
>>>> +     * This could be a machine with a PCI/SMC conduit,
>>>> +     * which means it doens't have MCFG. Get the machineid from
>>>> +     * the namespace definition instead.
>>>
>>> s/SMC/SMCCC/ ?  Cover letter uses SMCCC (not sure it's relevant anyway)
>>> s/doens't/doesn't/
>>>
>>> Rewrap comment to use ~80 columns.
>>>
>>> Seems pretty reasonable that a platform without standard ECAM might
>>> not have MCFG, since MCFG basically implies ECAM.
>>
>>
>> Sure, on all the above comments.
>>
>>>
>>> Is "linux,pcie-quirk" the right property to look for?  It doesn't
>>> sound very generic, and it doesn't sound like anything related to
>>> ECAM.  Is it new?  I don't see it in the tree yet.  Should it be in
>>> Documentation/devicetree/bindings/pci/pci.txt so we don't get a
>>> different property name for every new platform?
> 
> No, it should not be in pci.txt. Nothing to do with DT and I don't
> review ACPI bindings (someone should) if I can help it.

That is the intention of the uefi properties registry I referred to 
earlier. It has a code first model too, which allows us to review it 
here and then update the document with the property and the intended 
behavior.

> 
>> Yes, I made it up. Someone else commented about the "linux," partially
>> because it should be "linux-" to conform with
>> https://github.com/UEFI/DSD-Guide. But also in the same context of it
>> being linux specific.  I think that guide is where it should end up,
>> rather than the devicetree bindings.
>>
>> I guess we can request addition to the uefi- but that seems like a
>> mistake this is really (hopefully?) a Linux specific properly as other
>> OS's will simply use the SMC. I think we could request another prefix if
>> we come up with a good one and think it belongs in that guide.
> 
> It's only Linux specific until it's not.
> 
> What happens when there's a second PCIe quirk here? Say what the quirk
> is (and not in terms of Linux policy).

This is really just a stand in for the existing MCFG oem id, its an 
identifier to key off, nothing else.  Maybe a better name is 
"linux-ecam-quirk-id" or something to that effect?

> 
> Don't you know the device here and can imply all this (like implying
> off of 'compatible' in DT)? Adding properties to address issues
> creates compatibility issues. Maybe not an issue in this case if the
> firmware is not stable, but not a good practice to be in.

Yes, and no, I think there was some discussion a few years back about 
using non standard HID's for these nonstandard implementations, but that 
was discouraged at the time in favor of using the standard identifiers 
and and keying off a Soc/platform specific ID to enable a "quirk". Given 
we are a bit far down that path and the decision was made to continue 
down it (rather than solving much of it with a new firmware interface) 
this seems like the straightforward solution. The vast majority of these 
are SoC specific, and just minor tweaks for alignment/etc. Given its an 
ACPI/UEFI machine we are already hiding a lot of the platform specific 
behavior for configuring the bridge/etc that might require DT like 
properties in the firmware.


Thanks again.



From oupton at google.com  Mon Aug  9 09:30:45 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 09:30:45 -0700
Subject: [PATCH 12/13] arm64: Add a capability for FEAT_EVC
In-Reply-To: <20210809152651.2297337-13-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-13-maz@kernel.org>
Message-ID: <CAOQ_QsjT8DUoXQsxWGgGiZkwNe2itRswGomtq6-p+7_oU01orQ@mail.gmail.com>

Hi Marc,

On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
>
> Add a new capability to detect the Enhanced Counter Virtualization
> feature (FEAT_EVC).
>

s/FEAT_EVC/FEAT_ECV/g

> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kernel/cpufeature.c | 10 ++++++++++
>  arch/arm64/tools/cpucaps       |  1 +
>  2 files changed, 11 insertions(+)
>
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 0ead8bfedf20..9c2ce5408811 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1899,6 +1899,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>                 .sign = FTR_UNSIGNED,
>                 .min_field_value = 1,
>         },
> +       {
> +               .desc = "Enhanced counter virtualization",
> +               .capability = ARM64_HAS_ECV,
> +               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +               .matches = has_cpuid_feature,
> +               .sys_reg = SYS_ID_AA64MMFR0_EL1,
> +               .field_pos = ID_AA64MMFR0_ECV_SHIFT,
> +               .sign = FTR_UNSIGNED,
> +               .min_field_value = 1,
> +       },

Per one of your other patches in the series, it sounds like userspace
access to the self-synchronized registers hasn't been settled yet.
However, if/when available to userspace, should this cpufeature map to
an ELF HWCAP?

Also, w.r.t. my series I have out for ECV in KVM. All the controls
used in EL2 depend on ECV=0x2. I agree that ECV=0x1 needs a cpufeature
bit, but what about EL2's use case?

Besides the typo:

Reviewed-by: Oliver Upton <oupton at google.com>

--
Thanks,
Oliver

>  #ifdef CONFIG_ARM64_PAN
>         {
>                 .desc = "Privileged Access Never",
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 49305c2e6dfd..7a7c58acd8f0 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -18,6 +18,7 @@ HAS_CRC32
>  HAS_DCPODP
>  HAS_DCPOP
>  HAS_E0PD
> +HAS_ECV
>  HAS_EPAN
>  HAS_GENERIC_AUTH
>  HAS_GENERIC_AUTH_ARCH
> --
> 2.30.2
>


From oupton at google.com  Mon Aug  9 09:34:26 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 09:34:26 -0700
Subject: [PATCH 12/13] arm64: Add a capability for FEAT_EVC
In-Reply-To: <CAOQ_QsjT8DUoXQsxWGgGiZkwNe2itRswGomtq6-p+7_oU01orQ@mail.gmail.com>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-13-maz@kernel.org>
 <CAOQ_QsjT8DUoXQsxWGgGiZkwNe2itRswGomtq6-p+7_oU01orQ@mail.gmail.com>
Message-ID: <CAOQ_QshvUVB-Ey3P0MJbj9OxU46kis6=Lo4soz_g_WebgRuvyg@mail.gmail.com>

On Mon, Aug 9, 2021 at 9:30 AM Oliver Upton <oupton at google.com> wrote:
>
> Hi Marc,
>
> On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > Add a new capability to detect the Enhanced Counter Virtualization
> > feature (FEAT_EVC).
> >
>
> s/FEAT_EVC/FEAT_ECV/g
>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kernel/cpufeature.c | 10 ++++++++++
> >  arch/arm64/tools/cpucaps       |  1 +
> >  2 files changed, 11 insertions(+)
> >
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 0ead8bfedf20..9c2ce5408811 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -1899,6 +1899,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
> >                 .sign = FTR_UNSIGNED,
> >                 .min_field_value = 1,
> >         },
> > +       {
> > +               .desc = "Enhanced counter virtualization",
> > +               .capability = ARM64_HAS_ECV,
> > +               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
> > +               .matches = has_cpuid_feature,
> > +               .sys_reg = SYS_ID_AA64MMFR0_EL1,
> > +               .field_pos = ID_AA64MMFR0_ECV_SHIFT,
> > +               .sign = FTR_UNSIGNED,
> > +               .min_field_value = 1,
> > +       },
>
> Per one of your other patches in the series, it sounds like userspace
> access to the self-synchronized registers hasn't been settled yet.
> However, if/when available to userspace, should this cpufeature map to
> an ELF HWCAP?
>
> Also, w.r.t. my series I have out for ECV in KVM. All the controls
> used in EL2 depend on ECV=0x2. I agree that ECV=0x1 needs a cpufeature
> bit, but what about EL2's use case?

Forgot to link the series:

http://lore.kernel.org/r/20210804085819.846610-1-oupton at google.com

>
> Besides the typo:
>
> Reviewed-by: Oliver Upton <oupton at google.com>
>
> --
> Thanks,
> Oliver
>
> >  #ifdef CONFIG_ARM64_PAN
> >         {
> >                 .desc = "Privileged Access Never",
> > diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> > index 49305c2e6dfd..7a7c58acd8f0 100644
> > --- a/arch/arm64/tools/cpucaps
> > +++ b/arch/arm64/tools/cpucaps
> > @@ -18,6 +18,7 @@ HAS_CRC32
> >  HAS_DCPODP
> >  HAS_DCPOP
> >  HAS_E0PD
> > +HAS_ECV
> >  HAS_EPAN
> >  HAS_GENERIC_AUTH
> >  HAS_GENERIC_AUTH_ARCH
> > --
> > 2.30.2
> >


From bilbao at vt.edu  Mon Aug  9 09:39:42 2021
From: bilbao at vt.edu (Carlos Bilbao)
Date: Mon, 9 Aug 2021 12:39:42 -0400
Subject: [PATCH v4.1] include: linux: Reorganize timekeeping and ktime headers
In-Reply-To: <CAMuHMdXueYTAYFgt-gP79e1NaFzmPmsE1if+DsiZaB5VmNqCXA@mail.gmail.com>
References: <202108010312.8uIaWK0u-lkp@intel.com>
 <3bdd5b29-b6a1-54a8-ac99-adb59e8e91a7@vt.edu>
 <CAMuHMdXueYTAYFgt-gP79e1NaFzmPmsE1if+DsiZaB5VmNqCXA@mail.gmail.com>
Message-ID: <b5d4536f-a096-b259-1385-3c1d32754dbf@vt.edu>

Reorganize and separate the headers by making ktime.h take care of the 
ktime_get() family of functions, and reserve timekeeping.h for the actual 
timekeeping. This also helps to avoid implicit function errors and strengthens
the header dependencies, since timekeeping.h was using ktime_to_ns(), a static 
function defined in a header it does no include, ktime.h. Include the header 
timekeeping.h wherever it is necessary for a successful compilation after the 
header code reorganization.

Signed-off-by: Carlos Bilbao <bilbao at vt.edu>
Acked-by: Geert Uytterhoeven <geert at linux-m68k.org>
Reported-by: kernel test robot <lkp at intel.com>
---
Changelog:
- v2: Add three more files that also needed a header update for x86: 
  pps_kernel.h, posix-timers.c and hda_controller.c
- v3: Cover build tests for other architectures than x86. To compile arm64, 
  update arch/arm64/kvm/hypercalls.c, include/linux/stmmac.h, and 
  drivers/rtc/class.c. No other arch/ seems to need fixes but to be on the safe
  side compiled arm, mips, powerpc, sparc, s390, riscv and i386.
- v4: 4.0 Fix kernel test robot warnings for ia64 and x86.
      4.1 Fix kernel test robot warnings for m68k and powerpc.
---
 arch/arm64/kvm/hypercalls.c    |   1 +
 arch/ia64/kernel/time.c        |   1 +
 arch/m68k/atari/time.c         |   1 +
 arch/m68k/hp300/time.c         |   2 +
 arch/m68k/mac/via.c            |   1 +
 arch/m68k/mvme16x/config.c     |   1 +
 arch/m68k/sun3/sun3ints.c      |   1 +
 arch/powerpc/kernel/time.c     |   1 +
 arch/x86/kernel/rtc.c          |   1 +
 arch/x86/kernel/tsc.c          |   1 +
 drivers/rtc/class.c            |   1 +
 include/linux/ktime.h          | 196 +++++++++++++++++++++++++++++++-
 include/linux/pps_kernel.h     |   1 +
 include/linux/sched_clock.h    |   2 +
 include/linux/stmmac.h         |   1 +
 include/linux/timekeeping.h    | 197 +--------------------------------
 init/main.c                    |   1 +
 kernel/time/ntp.c              |   1 +
 kernel/time/posix-timers.c     |   1 +
 kernel/time/tick-legacy.c      |   1 +
 kernel/time/time.c             |   1 +
 kernel/time/timekeeping.c      |   1 +
 sound/pci/hda/hda_controller.c |   1 +
 23 files changed, 218 insertions(+), 198 deletions(-)

diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 30da78f72b3b..41499c1d7379 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -3,6 +3,7 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/kvm_host.h>
+#include <linux/timekeeping.h>
 
 #include <asm/kvm_emulate.h>
 
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index fa9c0ab8c6fc..85e79ff3c98e 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/efi.h>
 #include <linux/timex.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/platform_device.h>
 #include <linux/sched/cputime.h>
 
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 7e44d0e9d0f8..b09d3ff40b36 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -19,6 +19,7 @@
 #include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/timekeeping.h>
 
 #include <asm/atariints.h>
 #include <asm/machdep.h>
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index 1d1b7b3b5dd4..56c575096bcb 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -14,6 +14,8 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
+
 #include <asm/machdep.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 3d11d6219cdd..6dd8f85288e4 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/irq.h>
+#include <linux/timekeeping.h>
 
 #include <asm/macintosh.h>
 #include <asm/macints.h>
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index b59593c7cfb9..bb2ae926bb17 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -28,6 +28,7 @@
 #include <linux/rtc.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/timekeeping.h>
 
 #include <asm/bootinfo.h>
 #include <asm/bootinfo-vme.h>
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 41ae422119d3..3834a172be47 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
 #include <asm/segment.h>
 #include <asm/intersil.h>
 #include <asm/oplib.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index e45ce427bffb..4b6952165a0a 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -55,6 +55,7 @@
 #include <linux/sched/cputime.h>
 #include <linux/sched/clock.h>
 #include <linux/processor.h>
+#include <linux/timekeeping.h>
 #include <asm/trace.h>
 
 #include <asm/interrupt.h>
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 586f718b8e95..98ea05cc6aeb 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -9,6 +9,7 @@
 #include <linux/export.h>
 #include <linux/pnp.h>
 #include <linux/of.h>
+#include <linux/timekeeping.h>
 
 #include <asm/vsyscall.h>
 #include <asm/x86_init.h>
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 2e076a459a0c..b730cb20f5fd 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -15,6 +15,7 @@
 #include <linux/timex.h>
 #include <linux/static_key.h>
 #include <linux/static_call.h>
+#include <linux/timekeeping.h>
 
 #include <asm/hpet.h>
 #include <asm/timer.h>
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index f77bc089eb6b..1bdf1f790beb 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 #include <linux/workqueue.h>
 
 #include "rtc-core.h"
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 73f20deb497d..37955d6664dd 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -229,6 +229,198 @@ static inline ktime_t ms_to_ktime(u64 ms)
 	return ms * NSEC_PER_MSEC;
 }
 
-# include <linux/timekeeping.h>
+/*
+ * ktime_get() family: read the current time in a multitude of ways,
+ *
+ * The default time reference is CLOCK_MONOTONIC, starting at
+ * boot time but not counting the time spent in suspend.
+ * For other references, use the functions with "real", "clocktai",
+ * "boottime" and "raw" suffixes.
+ *
+ * To get the time in a different format, use the ones wit
+ * "ns", "ts64" and "seconds" suffix.
+ *
+ * See Documentation/core-api/timekeeping.rst for more details.
+ */
 
-#endif
+
+/*
+ * timespec64 based interfaces
+ */
+extern void ktime_get_raw_ts64(struct timespec64 *ts);
+extern void ktime_get_ts64(struct timespec64 *ts);
+extern void ktime_get_real_ts64(struct timespec64 *tv);
+extern void ktime_get_coarse_ts64(struct timespec64 *ts);
+extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
+
+void getboottime64(struct timespec64 *ts);
+
+/*
+ * time64_t base interfaces
+ */
+extern time64_t ktime_get_seconds(void);
+extern time64_t __ktime_get_real_seconds(void);
+extern time64_t ktime_get_real_seconds(void);
+
+/*
+ * ktime_t based interfaces
+ */
+
+enum tk_offsets {
+       TK_OFFS_REAL,
+       TK_OFFS_BOOT,
+       TK_OFFS_TAI,
+       TK_OFFS_MAX,
+};
+
+extern ktime_t ktime_get(void);
+extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
+extern ktime_t ktime_get_raw(void);
+extern u32 ktime_get_resolution_ns(void);
+
+/**
+ * ktime_get_real - get the real (wall-) time in ktime_t format
+ */
+static inline ktime_t ktime_get_real(void)
+{
+       return ktime_get_with_offset(TK_OFFS_REAL);
+}
+
+static inline ktime_t ktime_get_coarse_real(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_REAL);
+}
+
+/**
+ * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
+ *
+ * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
+ * time spent in suspend.
+ */
+static inline ktime_t ktime_get_boottime(void)
+{
+       return ktime_get_with_offset(TK_OFFS_BOOT);
+}
+
+static inline ktime_t ktime_get_coarse_boottime(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
+}
+
+/**
+ * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
+ */
+static inline ktime_t ktime_get_clocktai(void)
+{
+       return ktime_get_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse_clocktai(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse(void)
+{
+       struct timespec64 ts;
+
+       ktime_get_coarse_ts64(&ts);
+       return timespec64_to_ktime(ts);
+}
+
+static inline u64 ktime_get_coarse_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse());
+}
+
+static inline u64 ktime_get_coarse_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_real());
+}
+
+static inline u64 ktime_get_coarse_boottime_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_boottime());
+}
+
+static inline u64 ktime_get_coarse_clocktai_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_clocktai());
+}
+
+/**
+ * ktime_mono_to_real - Convert monotonic time to clock realtime
+ */
+static inline ktime_t ktime_mono_to_real(ktime_t mono)
+{
+       return ktime_mono_to_any(mono, TK_OFFS_REAL);
+}
+
+static inline u64 ktime_get_ns(void)
+{
+       return ktime_to_ns(ktime_get());
+}
+
+static inline u64 ktime_get_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_real());
+}
+
+static inline u64 ktime_get_boottime_ns(void)
+{
+       return ktime_to_ns(ktime_get_boottime());
+}
+
+static inline u64 ktime_get_clocktai_ns(void)
+{
+       return ktime_to_ns(ktime_get_clocktai());
+}
+
+static inline u64 ktime_get_raw_ns(void)
+{
+       return ktime_to_ns(ktime_get_raw());
+}
+
+extern u64 ktime_get_mono_fast_ns(void);
+extern u64 ktime_get_raw_fast_ns(void);
+extern u64 ktime_get_boot_fast_ns(void);
+extern u64 ktime_get_real_fast_ns(void);
+
+/*
+ * timespec64/time64_t interfaces utilizing the ktime based ones
+ * for API completeness, these could be implemented more efficiently
+ * if needed.
+ */
+static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_boottime());
+}
+
+static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_coarse_boottime());
+}
+
+static inline time64_t ktime_get_boottime_seconds(void)
+{
+       return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
+}
+
+static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_clocktai());
+}
+
+static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
+}
+
+static inline time64_t ktime_get_clocktai_seconds(void)
+{
+       return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
+}
+
+#endif /* _LINUX_KTIME_H */
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h
index 78c8ac4951b5..24970c202ac6 100644
--- a/include/linux/pps_kernel.h
+++ b/include/linux/pps_kernel.h
@@ -12,6 +12,7 @@
 #include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 
 /*
  * Global defines
diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h
index 835ee87ed792..f0fa287710da 100644
--- a/include/linux/sched_clock.h
+++ b/include/linux/sched_clock.h
@@ -5,6 +5,8 @@
 #ifndef LINUX_SCHED_CLOCK
 #define LINUX_SCHED_CLOCK
 
+#include <linux/timekeeping.h>
+
 #ifdef CONFIG_GENERIC_SCHED_CLOCK
 /**
  * struct clock_read_data - data required to read from sched_clock()
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..bf235ff101d5 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -14,6 +14,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/timekeeping.h>
 
 #define MTL_MAX_RX_QUEUES	8
 #define MTL_MAX_TX_QUEUES	8
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 78a98bdff76d..b1c54f5ff91e 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -19,201 +19,6 @@ extern void legacy_timer_tick(unsigned long ticks);
 extern int do_settimeofday64(const struct timespec64 *ts);
 extern int do_sys_settimeofday64(const struct timespec64 *tv,
 				 const struct timezone *tz);
-
-/*
- * ktime_get() family: read the current time in a multitude of ways,
- *
- * The default time reference is CLOCK_MONOTONIC, starting at
- * boot time but not counting the time spent in suspend.
- * For other references, use the functions with "real", "clocktai",
- * "boottime" and "raw" suffixes.
- *
- * To get the time in a different format, use the ones wit
- * "ns", "ts64" and "seconds" suffix.
- *
- * See Documentation/core-api/timekeeping.rst for more details.
- */
-
-
-/*
- * timespec64 based interfaces
- */
-extern void ktime_get_raw_ts64(struct timespec64 *ts);
-extern void ktime_get_ts64(struct timespec64 *ts);
-extern void ktime_get_real_ts64(struct timespec64 *tv);
-extern void ktime_get_coarse_ts64(struct timespec64 *ts);
-extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
-
-void getboottime64(struct timespec64 *ts);
-
-/*
- * time64_t base interfaces
- */
-extern time64_t ktime_get_seconds(void);
-extern time64_t __ktime_get_real_seconds(void);
-extern time64_t ktime_get_real_seconds(void);
-
-/*
- * ktime_t based interfaces
- */
-
-enum tk_offsets {
-	TK_OFFS_REAL,
-	TK_OFFS_BOOT,
-	TK_OFFS_TAI,
-	TK_OFFS_MAX,
-};
-
-extern ktime_t ktime_get(void);
-extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
-extern ktime_t ktime_get_raw(void);
-extern u32 ktime_get_resolution_ns(void);
-
-/**
- * ktime_get_real - get the real (wall-) time in ktime_t format
- */
-static inline ktime_t ktime_get_real(void)
-{
-	return ktime_get_with_offset(TK_OFFS_REAL);
-}
-
-static inline ktime_t ktime_get_coarse_real(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_REAL);
-}
-
-/**
- * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
- *
- * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
- * time spent in suspend.
- */
-static inline ktime_t ktime_get_boottime(void)
-{
-	return ktime_get_with_offset(TK_OFFS_BOOT);
-}
-
-static inline ktime_t ktime_get_coarse_boottime(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
-}
-
-/**
- * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
- */
-static inline ktime_t ktime_get_clocktai(void)
-{
-	return ktime_get_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse_clocktai(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse(void)
-{
-	struct timespec64 ts;
-
-	ktime_get_coarse_ts64(&ts);
-	return timespec64_to_ktime(ts);
-}
-
-static inline u64 ktime_get_coarse_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse());
-}
-
-static inline u64 ktime_get_coarse_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_real());
-}
-
-static inline u64 ktime_get_coarse_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_boottime());
-}
-
-static inline u64 ktime_get_coarse_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_clocktai());
-}
-
-/**
- * ktime_mono_to_real - Convert monotonic time to clock realtime
- */
-static inline ktime_t ktime_mono_to_real(ktime_t mono)
-{
-	return ktime_mono_to_any(mono, TK_OFFS_REAL);
-}
-
-static inline u64 ktime_get_ns(void)
-{
-	return ktime_to_ns(ktime_get());
-}
-
-static inline u64 ktime_get_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_real());
-}
-
-static inline u64 ktime_get_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_boottime());
-}
-
-static inline u64 ktime_get_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_clocktai());
-}
-
-static inline u64 ktime_get_raw_ns(void)
-{
-	return ktime_to_ns(ktime_get_raw());
-}
-
-extern u64 ktime_get_mono_fast_ns(void);
-extern u64 ktime_get_raw_fast_ns(void);
-extern u64 ktime_get_boot_fast_ns(void);
-extern u64 ktime_get_real_fast_ns(void);
-
-/*
- * timespec64/time64_t interfaces utilizing the ktime based ones
- * for API completeness, these could be implemented more efficiently
- * if needed.
- */
-static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_boottime());
-}
-
-static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_boottime());
-}
-
-static inline time64_t ktime_get_boottime_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
-}
-
-static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_clocktai());
-}
-
-static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
-}
-
-static inline time64_t ktime_get_clocktai_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
-}
-
 /*
  * RTC specific
  */
@@ -308,4 +113,4 @@ void read_persistent_wall_and_boot_offset(struct timespec64 *wall_clock,
 extern int update_persistent_clock64(struct timespec64 now);
 #endif
 
-#endif
+#endif /* _LINUX_TIMEKEEPING_H */
diff --git a/init/main.c b/init/main.c
index f5b8246e8aa1..a8db3a136d6a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -100,6 +100,7 @@
 #include <linux/kcsan.h>
 #include <linux/init_syscalls.h>
 #include <linux/stackdepot.h>
+#include <linux/timekeeping.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 406dccb79c2b..804f06801737 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "ntp_internal.h"
 #include "timekeeping_internal.h"
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index dd5697d7347b..14f82cd95d10 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 #include <linux/mutex.h>
 #include <linux/sched/task.h>
 
diff --git a/kernel/time/tick-legacy.c b/kernel/time/tick-legacy.c
index af225b32f5b3..9a534f716462 100644
--- a/kernel/time/tick-legacy.c
+++ b/kernel/time/tick-legacy.c
@@ -7,6 +7,7 @@
 #include <linux/irq.h>
 #include <linux/profile.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 29923b20e0e4..7292ed074742 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -29,6 +29,7 @@
 #include <linux/timex.h>
 #include <linux/capability.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/errno.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8a364aa9881a..4dfee925adc8 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -22,6 +22,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index ca2f2ecd1488..efbbe624d81d 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 
 #ifdef CONFIG_X86
 /* for art-tsc conversion */
-- 
2.25.1



From oupton at google.com  Mon Aug  9 09:42:00 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 09:42:00 -0700
Subject: [PATCH 13/13] arm64: Add CNT{P, V}CTSS_EL0 alternatives to cnt{p,
 v}ct_el0
In-Reply-To: <20210809152651.2297337-14-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-14-maz@kernel.org>
Message-ID: <CAOQ_QshjRWh=onT-j3dWgmVfnAXsMFJoz0i7OEezQxkW4O9KZA@mail.gmail.com>

On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
>
> CNTPCTSS_EL0 and CNTVCTSS_EL0 are alternatives to the usual
> CNTPCT_EL0 and CNTVCT_EL0 that do not require a previous ISB
> to be synchronised (SS stands for Self-Synchronising).
>
> Use the ARM64_HAS_ECV capability to control alternative sequences
> that switch to these low(er)-cost primitives. Note that the
> counter access in the VDSO is for now left alone until we decide
> whether we want to allow this.

What remains to be figured out before we add this to the vDSO (and
presumably advertise to userspace through some standard convention)?
It would be nice to skip the trap handler altogether, unless there's a
can of worms lurking that I'm not aware of.

--
Thanks,
Oliver

> For a good measure, wire the cntvct hooks to also handle CNTVCTSS.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/arch_timer.h | 30 +++++++++++++++++++++++------
>  arch/arm64/include/asm/esr.h        |  6 ++++++
>  arch/arm64/include/asm/sysreg.h     |  3 +++
>  arch/arm64/kernel/traps.c           | 11 +++++++++++
>  4 files changed, 44 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index b2f056db1225..785411a48512 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -64,12 +64,26 @@ DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
>
>  static inline notrace u64 arch_timer_read_cntpct_el0(void)
>  {
> -       return read_sysreg(cntpct_el0);
> +       u64 cnt;
> +
> +       asm volatile(ALTERNATIVE("isb\n mrs %x0, cntpct_el0",
> +                                "nop\n" __mrs_s("%x0", SYS_CNTPCTSS_EL0),
> +                                ARM64_HAS_ECV)
> +                    : "=r" (cnt));
> +
> +       return cnt;
>  }
>
>  static inline notrace u64 arch_timer_read_cntvct_el0(void)
>  {
> -       return read_sysreg(cntvct_el0);
> +       u64 cnt;
> +
> +       asm volatile(ALTERNATIVE("isb\n mrs %x0, cntvct_el0",
> +                                "nop\n" __mrs_s("%x0", SYS_CNTVCTSS_EL0),
> +                                ARM64_HAS_ECV)
> +                    : "=r" (cnt));
> +
> +       return cnt;
>  }
>
>  #define arch_timer_reg_read_stable(reg)                                        \
> @@ -166,8 +180,10 @@ static __always_inline u64 __arch_counter_get_cntpct(void)
>  {
>         u64 cnt;
>
> -       isb();
> -       cnt = read_sysreg(cntpct_el0);
> +       asm volatile(ALTERNATIVE("isb\n mrs %x0, cntpct_el0",
> +                                "nop\n" __mrs_s("%x0", SYS_CNTPCTSS_EL0),
> +                                ARM64_HAS_ECV)
> +                    : "=r" (cnt));
>         arch_counter_enforce_ordering(cnt);
>         return cnt;
>  }
> @@ -186,8 +202,10 @@ static __always_inline u64 __arch_counter_get_cntvct(void)
>  {
>         u64 cnt;
>
> -       isb();
> -       cnt = read_sysreg(cntvct_el0);
> +       asm volatile(ALTERNATIVE("isb\n mrs %x0, cntvct_el0",
> +                                "nop\n" __mrs_s("%x0", SYS_CNTVCTSS_EL0),
> +                                ARM64_HAS_ECV)
> +                    : "=r" (cnt));
>         arch_counter_enforce_ordering(cnt);
>         return cnt;
>  }
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index 29f97eb3dad4..a305ce256090 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -227,6 +227,9 @@
>  #define ESR_ELx_SYS64_ISS_SYS_CNTVCT   (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
>                                          ESR_ELx_SYS64_ISS_DIR_READ)
>
> +#define ESR_ELx_SYS64_ISS_SYS_CNTVCTSS (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 6, 14, 0) | \
> +                                        ESR_ELx_SYS64_ISS_DIR_READ)
> +
>  #define ESR_ELx_SYS64_ISS_SYS_CNTFRQ   (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 0, 14, 0) | \
>                                          ESR_ELx_SYS64_ISS_DIR_READ)
>
> @@ -317,6 +320,9 @@
>  #define ESR_ELx_CP15_64_ISS_SYS_CNTVCT (ESR_ELx_CP15_64_ISS_SYS_VAL(1, 14) | \
>                                          ESR_ELx_CP15_64_ISS_DIR_READ)
>
> +#define ESR_ELx_CP15_64_ISS_SYS_CNTVCTSS (ESR_ELx_CP15_64_ISS_SYS_VAL(9, 14) | \
> +                                        ESR_ELx_CP15_64_ISS_DIR_READ)
> +
>  #define ESR_ELx_CP15_32_ISS_SYS_CNTFRQ (ESR_ELx_CP15_32_ISS_SYS_VAL(0, 0, 14, 0) |\
>                                          ESR_ELx_CP15_32_ISS_DIR_READ)
>
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 7b9c3acba684..897f9c882895 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -506,6 +506,9 @@
>
>  #define SYS_CNTFRQ_EL0                 sys_reg(3, 3, 14, 0, 0)
>
> +#define SYS_CNTPCTSS_EL0               sys_reg(3, 3, 14, 0, 5)
> +#define SYS_CNTVCTSS_EL0               sys_reg(3, 3, 14, 0, 6)
> +
>  #define SYS_CNTP_TVAL_EL0              sys_reg(3, 3, 14, 2, 0)
>  #define SYS_CNTP_CTL_EL0               sys_reg(3, 3, 14, 2, 1)
>  #define SYS_CNTP_CVAL_EL0              sys_reg(3, 3, 14, 2, 2)
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index b03e383d944a..16710ca55fbb 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -653,6 +653,12 @@ static const struct sys64_hook sys64_hooks[] = {
>                 .esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCT,
>                 .handler = cntvct_read_handler,
>         },
> +       {
> +               /* Trap read access to CNTVCTSS_EL0 */
> +               .esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
> +               .esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCTSS,
> +               .handler = cntvct_read_handler,
> +       },
>         {
>                 /* Trap read access to CNTFRQ_EL0 */
>                 .esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
> @@ -729,6 +735,11 @@ static const struct sys64_hook cp15_64_hooks[] = {
>                 .esr_val = ESR_ELx_CP15_64_ISS_SYS_CNTVCT,
>                 .handler = compat_cntvct_read_handler,
>         },
> +       {
> +               .esr_mask = ESR_ELx_CP15_64_ISS_SYS_MASK,
> +               .esr_val = ESR_ELx_CP15_64_ISS_SYS_CNTVCTSS,
> +               .handler = compat_cntvct_read_handler,
> +       },
>         {},
>  };
>
> --
> 2.30.2
>


From david at ixit.cz  Mon Aug  9 09:44:57 2021
From: david at ixit.cz (David Heidelberg)
Date: Mon, 09 Aug 2021 16:44:57 +0000
Subject: [PATCH] ARM: atags_to_fdt: don't warn about stack size
In-Reply-To: <CAK8P3a0qB3Nj8-wKPiAJvPrnH9LZjeXdkQA1MfS998RYk5foRA@mail.gmail.com>
References: <20210809151021.5137-1-david@ixit.cz>
 <20210809152421.GU22278@shell.armlinux.org.uk>
 <CAK8P3a0qB3Nj8-wKPiAJvPrnH9LZjeXdkQA1MfS998RYk5foRA@mail.gmail.com>
Message-ID: <21CA0122-5D3C-4375-93DB-564126F1E352@ixit.cz>

Thank you, in next iteration I'll keep you as author and keep your S-off-by


-------- P?vodn? zpr?va --------
Odes?latel: Arnd Bergmann <arnd at arndb.de>
Odesl?no: 9. srpna 2021 16:02:36 UTC
Komu: "Russell King (Oracle)" <linux at armlinux.org.uk>
Kopie: David Heidelberg <david at ixit.cz>, Arnd Bergmann <arnd at arndb.de>, Jon Medhurst <tixy at linaro.org>, Ard Biesheuvel <ard.biesheuvel at linaro.org>, Marc Zyngier <marc.zyngier at arm.com>, Nicolas Pitre <nico at linaro.org>, Linux Kernel Mailing List <linux-kernel at vger.kernel.org>, Linux ARM <linux-arm-kernel at lists.infradead.org>
P?edm?t: Re: [PATCH] ARM: atags_to_fdt: don't warn about stack size

On Mon, Aug 9, 2021 at 5:24 PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:
> On Mon, Aug 09, 2021 at 05:10:21PM +0200, David Heidelberg wrote:
> > Signed-off-by: David Heidelberg <david at ixit.cz>

Acked-by: Arnd Bergmann <arnd at arndb.de>

(or keep my original Signed-off-by if you like)

> I assume Arnd never sent his v3 from what I see in the thread you link
> to above.

Yes, it's in my ever-growing backlog of things I plan to eventually resubmit.

In this case, I actually have a different patch in my tree, but that in turn
depends on other stuff I have to submit first (reorganizing the way that
warning options get handled based on compiler version etc), and the
version here is what works on current mainline kernels.

     Arnd

S pozdravem a p??n?m kr?sn?ho dne
David Heidelberg


From oupton at google.com  Mon Aug  9 09:45:28 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 09:45:28 -0700
Subject: [PATCH 11/13] clocksource/arm_arch_timer: Fix masking for high
 freq counters
In-Reply-To: <20210809152651.2297337-12-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-12-maz@kernel.org>
Message-ID: <CAOQ_Qshfi=RN8fExhXQh1i640LAZaZjQSJApyvdU2Gva9KtFaQ@mail.gmail.com>

On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
>
> From: Oliver Upton <oupton at google.com>
>
> Unfortunately, the architecture provides no means to determine the bit
> width of the system counter. However, we do know the following from the
> specification:
>
>  - the system counter is at least 56 bits wide
>  - Roll-over time of not less than 40 years
>
> To date, the arch timer driver has depended on the first property,
> assuming any system counter to be 56 bits wide and masking off the rest.
> However, combining a narrow clocksource mask with a high frequency
> counter could result in prematurely wrapping the system counter by a
> significant margin. For example, a 56 bit wide, 1GHz system counter
> would wrap in a mere 2.28 years!
>
> This is a problem for two reasons: v8.6+ implementations are required to
> provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> implementers may select a counter frequency of their choosing.
>
> Fix the issue by deriving a valid clock mask based on the second
> property from above. Set the floor at 56 bits, since we know no system
> counter is narrower than that.
>
> Suggested-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Oliver Upton <oupton at google.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> [maz: fixed width computation not to lose the last bit, added
>       max delta generation for the timer]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Link: https://lore.kernel.org/r/20210807191428.3488948-1-oupton at google.com
> ---
>  drivers/clocksource/arm_arch_timer.c | 34 ++++++++++++++++++++++++----
>  1 file changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index fa09952b94bf..74eca831d0d9 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -52,6 +52,12 @@
>  #define CNTV_CVAL_LO   0x30
>  #define CNTV_CTL       0x3c
>
> +/*
> + * The minimum amount of time a generic counter is guaranteed to not roll over
> + * (40 years)
> + */
> +#define MIN_ROLLOVER_SECS      (40ULL * 365 * 24 * 3600)
> +
>  static unsigned arch_timers_present __initdata;
>
>  struct arch_timer {
> @@ -95,6 +101,22 @@ static int __init early_evtstrm_cfg(char *buf)
>  }
>  early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
>
> +/*
> + * Makes an educated guess at a valid counter width based on the Generic Timer
> + * specification. Of note:
> + *   1) the system counter is at least 56 bits wide
> + *   2) a roll-over time of not less than 40 years
> + *
> + * See 'ARM DDI 0487G.a D11.1.2 ("The system counter")' for more details.
> + */
> +static int arch_counter_get_width(void)
> +{
> +       u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_rate;
> +
> +       /* guarantee the returned width is within the valid range */
> +       return clamp_val(ilog2(min_cycles - 1) + 1, 56, 64);
> +}

Reposting thoughts from the original patch:

Reading the ARM ARM
D11.1.2 'The system counter', I did not find any language that
suggested the counter saturates the register width before rolling
over. So, it may be paranoid, but I presumed it to be safer to wrap
within the guaranteed interval rather (40 years) than assume the
sanity of the system counter implementation.

--
Thanks,
Oliver

> +
>  /*
>   * Architected system timer support.
>   */
> @@ -208,13 +230,11 @@ static struct clocksource clocksource_counter = {
>         .id     = CSID_ARM_ARCH_COUNTER,
>         .rating = 400,
>         .read   = arch_counter_read,
> -       .mask   = CLOCKSOURCE_MASK(56),
>         .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
>  };
>
>  static struct cyclecounter cyclecounter __ro_after_init = {
>         .read   = arch_counter_read_cc,
> -       .mask   = CLOCKSOURCE_MASK(56),
>  };
>
>  struct ate_acpi_oem_info {
> @@ -796,7 +816,7 @@ static u64 __arch_timer_check_delta(void)
>                 return CLOCKSOURCE_MASK(32);
>         }
>  #endif
> -       return CLOCKSOURCE_MASK(56);
> +       return CLOCKSOURCE_MASK(arch_counter_get_width());
>  }
>
>  static void __arch_timer_setup(unsigned type,
> @@ -1041,6 +1061,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
>  static void __init arch_counter_register(unsigned type)
>  {
>         u64 start_count;
> +       int width;
>
>         /* Register the CP15 based counter if we have one */
>         if (type & ARCH_TIMER_TYPE_CP15) {
> @@ -1065,6 +1086,10 @@ static void __init arch_counter_register(unsigned type)
>                 arch_timer_read_counter = arch_counter_get_cntvct_mem;
>         }
>
> +       width = arch_counter_get_width();
> +       clocksource_counter.mask = CLOCKSOURCE_MASK(width);
> +       cyclecounter.mask = CLOCKSOURCE_MASK(width);
> +
>         if (!arch_counter_suspend_stop)
>                 clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
>         start_count = arch_timer_read_counter();
> @@ -1074,8 +1099,7 @@ static void __init arch_counter_register(unsigned type)
>         timecounter_init(&arch_timer_kvm_info.timecounter,
>                          &cyclecounter, start_count);
>
> -       /* 56 bits minimum, so we assume worst case rollover */
> -       sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
> +       sched_clock_register(arch_timer_read_counter, width, arch_timer_rate);
>  }
>
>  static void arch_timer_stop(struct clock_event_device *clk)
> --
> 2.30.2
>


From oupton at google.com  Mon Aug  9 09:52:00 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 09:52:00 -0700
Subject: [PATCH 05/13] clocksource/arm_arch_timer: Fix MMIO base address
 vs callback ordering issue
In-Reply-To: <20210809152651.2297337-6-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-6-maz@kernel.org>
Message-ID: <CAOQ_QsjATdRRFdiG5kR+Ni7X-_kMaF+V_XQx3uuxivk0t4xt_w@mail.gmail.com>

On Mon, Aug 9, 2021 at 8:27 AM Marc Zyngier <maz at kernel.org> wrote:
>
> The MMIO timer base address gets published after we have registered
> the callbacks and the interrupt handler, which is... a bit dangerous.
>
> Fix this by moving the base address publication to the point where
> we register the timer, and expose a pointer to the timer structure
> itself rather than a naked value.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Is this patch stable-worthy? I take it there haven't been any reports
of issues, though this seems rather perilous.

Reviewed-by: Oliver Upton <oupton at google.com>

> ---
>  drivers/clocksource/arm_arch_timer.c | 27 +++++++++++++--------------
>  1 file changed, 13 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 160464f75017..ca7761d8459a 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -54,13 +54,13 @@
>
>  static unsigned arch_timers_present __initdata;
>
> -static void __iomem *arch_counter_base __ro_after_init;
> -
>  struct arch_timer {
>         void __iomem *base;
>         struct clock_event_device evt;
>  };
>
> +static struct arch_timer *arch_timer_mem __ro_after_init;
> +
>  #define to_arch_timer(e) container_of(e, struct arch_timer, evt)
>
>  static u32 arch_timer_rate __ro_after_init;
> @@ -975,9 +975,9 @@ static u64 arch_counter_get_cntvct_mem(void)
>         u32 vct_lo, vct_hi, tmp_hi;
>
>         do {
> -               vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI);
> -               vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO);
> -               tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI);
> +               vct_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI);
> +               vct_lo = readl_relaxed(arch_timer_mem->base + CNTVCT_LO);
> +               tmp_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI);
>         } while (vct_hi != tmp_hi);
>
>         return ((u64) vct_hi << 32) | vct_lo;
> @@ -1168,25 +1168,25 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq)
>  {
>         int ret;
>         irq_handler_t func;
> -       struct arch_timer *t;
>
> -       t = kzalloc(sizeof(*t), GFP_KERNEL);
> -       if (!t)
> +       arch_timer_mem = kzalloc(sizeof(*arch_timer_mem), GFP_KERNEL);
> +       if (!arch_timer_mem)
>                 return -ENOMEM;
>
> -       t->base = base;
> -       t->evt.irq = irq;
> -       __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &t->evt);
> +       arch_timer_mem->base = base;
> +       arch_timer_mem->evt.irq = irq;
> +       __arch_timer_setup(ARCH_TIMER_TYPE_MEM, &arch_timer_mem->evt);
>
>         if (arch_timer_mem_use_virtual)
>                 func = arch_timer_handler_virt_mem;
>         else
>                 func = arch_timer_handler_phys_mem;
>
> -       ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &t->evt);
> +       ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &arch_timer_mem->evt);
>         if (ret) {
>                 pr_err("Failed to request mem timer irq\n");
> -               kfree(t);
> +               kfree(arch_timer_mem);
> +               arch_timer_mem = NULL;
>         }
>
>         return ret;
> @@ -1444,7 +1444,6 @@ arch_timer_mem_frame_register(struct arch_timer_mem_frame *frame)
>                 return ret;
>         }
>
> -       arch_counter_base = base;
>         arch_timers_present |= ARCH_TIMER_TYPE_MEM;
>
>         return 0;
> --
> 2.30.2
>


From robdclark at gmail.com  Mon Aug  9 09:57:08 2021
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 9 Aug 2021 09:57:08 -0700
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent masters
 to use system cache
In-Reply-To: <20210809145651.GC1458@willie-the-truck>
References: <cover.1610372717.git.saiprakash.ranjan@codeaurora.org>
 <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
 <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
 <20210809145651.GC1458@willie-the-truck>
Message-ID: <CAF6AEGsSUojA=V0n2iRWTCn++buqN=Eoxo0r3=+=PBu1O=H-AQ@mail.gmail.com>

On Mon, Aug 9, 2021 at 7:56 AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Aug 02, 2021 at 06:36:04PM -0700, Rob Clark wrote:
> > On Mon, Aug 2, 2021 at 8:14 AM Will Deacon <will at kernel.org> wrote:
> > >
> > > On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> > > > On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> > > > >
> > > > > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> > > > > > On 2021-07-28 19:30, Georgi Djakov wrote:
> > > > > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > > > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > > > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > > > > > > the memory type setting required for the non-coherent masters to use
> > > > > > > > system cache. Now that system cache support for GPU is added, we will
> > > > > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > > > > > > Without this, the system cache lines are not allocated for GPU.
> > > > > > > >
> > > > > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > > > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > > > > > > and makes GPU the user of this protection flag.
> > > > > > >
> > > > > > > Thank you for the patchset! Are you planning to refresh it, as it does
> > > > > > > not apply anymore?
> > > > > > >
> > > > > >
> > > > > > I was waiting on Will's reply [1]. If there are no changes needed, then
> > > > > > I can repost the patch.
> > > > >
> > > > > I still think you need to handle the mismatched alias, no? You're adding
> > > > > a new memory type to the SMMU which doesn't exist on the CPU side. That
> > > > > can't be right.
> > > > >
> > > >
> > > > Just curious, and maybe this is a dumb question, but what is your
> > > > concern about mismatched aliases?  I mean the cache hierarchy on the
> > > > GPU device side (anything beyond the LLC) is pretty different and
> > > > doesn't really care about the smmu pgtable attributes..
> > >
> > > If the CPU accesses a shared buffer with different attributes to those which
> > > the device is using then you fall into the "mismatched memory attributes"
> > > part of the Arm architecture. It's reasonably unforgiving (you should go and
> > > read it) and in some cases can apply to speculative accesses as well, but
> > > the end result is typically loss of coherency.
> >
> > Ok, I might have a few other sections to read first to decipher the
> > terminology..
> >
> > But my understanding of LLC is that it looks just like system memory
> > to the CPU and GPU (I think that would make it "the point of
> > coherence" between the GPU and CPU?)  If that is true, shouldn't it be
> > invisible from the point of view of different CPU mapping options?
>
> You could certainly build a system where mismatched attributes don't cause
> loss of coherence, but as it's not guaranteed by the architecture and the
> changes proposed here affect APIs which are exposed across SoCs, then I
> don't think it helps much.
>

Hmm, the description of the new mapping flag is that it applies only
to transparent outer level cache:

+/*
+ * Non-coherent masters can use this page protection flag to set cacheable
+ * memory attributes for only a transparent outer level of cache, also known as
+ * the last-level or system cache.
+ */
+#define IOMMU_LLC      (1 << 6)

But I suppose we could call it instead IOMMU_QCOM_LLC or something
like that to make it more clear that it is not necessarily something
that would work with a different outer level cache implementation?

BR,
-R


From arnaud.pouliquen at foss.st.com  Mon Aug  9 10:00:26 2021
From: arnaud.pouliquen at foss.st.com (Arnaud POULIQUEN)
Date: Mon, 9 Aug 2021 19:00:26 +0200
Subject: [PATCH v2 1/5] remoteproc: Add support for detach-only during
 shutdown
In-Reply-To: <7e264184-60ea-a035-7bd3-1fc2c76a160d@ti.com>
References: <20210723220248.6554-1-s-anna@ti.com>
 <20210723220248.6554-2-s-anna@ti.com> <20210802184431.GC3051951@p14s>
 <cd399fef-6db7-72eb-933f-7454a043ed14@ti.com> <20210803162311.GB3091608@p14s>
 <7e264184-60ea-a035-7bd3-1fc2c76a160d@ti.com>
Message-ID: <1c526c7c-40cd-90b5-c5b3-0e130f54bc1e@foss.st.com>

Hi Suman, Mathieu,


On 8/4/21 9:17 PM, Suman Anna wrote:
> Hi Mathieu,
> 
> On 8/3/21 11:23 AM, Mathieu Poirier wrote:
>> Good morning,
>>
>> On Mon, Aug 02, 2021 at 06:21:38PM -0500, Suman Anna wrote:
>>> Hi Mathieu,
>>>
>>> On 8/2/21 1:44 PM, Mathieu Poirier wrote:
>>>> On Fri, Jul 23, 2021 at 05:02:44PM -0500, Suman Anna wrote:
>>>>> The remoteproc core has support for both stopping and detaching a
>>>>> remote processor that was attached to previously, through both the
>>>>> remoteproc sysfs and cdev interfaces. The rproc_shutdown() though
>>>>> unconditionally only uses the stop functionality at present. This
>>>>> may not be the default desired functionality for all the remoteproc
>>>>> platform drivers.
>>>>>
>>>>> Enhance the remoteproc core logic to key off the presence of the
>>>>> .stop() ops and allow the individual remoteproc drivers to continue
>>>>> to use the standard rproc_add() and rproc_del() API. This allows
>>>>> the remoteproc drivers to only do detach if supported when the driver
>>>>> is uninstalled, and the remote processor continues to run undisturbed
>>>>> even after the driver removal.
>>>>>
>>>>> Signed-off-by: Suman Anna <s-anna at ti.com>
>>>>> ---
>>>>> v2: Addressed various review comments from v1
>>>>>  - Reworked the logic to not use remoteproc detach_on_shutdown and
>>>>>    rely only on rproc callback ops
>>>>>  - Updated the last para of the patch description
>>>>> v1: https://patchwork.kernel.org/project/linux-remoteproc/patch/20210522000309.26134-3-s-anna at ti.com/
>>>>>
>>>>>  drivers/remoteproc/remoteproc_cdev.c  | 7 +++++++
>>>>>  drivers/remoteproc/remoteproc_core.c  | 5 ++++-
>>>>>  drivers/remoteproc/remoteproc_sysfs.c | 6 ++++++
>>>>>  3 files changed, 17 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c
>>>>> index 4ad98b0b8caa..16c932beed88 100644
>>>>> --- a/drivers/remoteproc/remoteproc_cdev.c
>>>>> +++ b/drivers/remoteproc/remoteproc_cdev.c
>>>>> @@ -42,6 +42,13 @@ static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_
>>>>>  		    rproc->state != RPROC_ATTACHED)
>>>>>  			return -EINVAL;
>>>>>  
>>>>> +		if (rproc->state == RPROC_ATTACHED &&
>>>>
>>>> This is already checked just above.
>>>>
>>>>> +		    !rproc->ops->stop) {
>>>
>>> Well, this is checking for both conditions, and not just the stop ops
>>> independently. We expect to have .stop() defined normally for both regular
>>> remoteproc mode and attached mode where you want to stop (and not detach), but
>>> as you can see, I am supporting only detach and so will not have .stop() defined
>>>  with RPROC_ATTACHED.
>>>
>>>>
>>>> This is checked in rproc_stop() where -EINVAL is returned if ops::stop has not
>>>> been provided.
>>>
>>> rproc_shutdown() actually doesn't return any status, so all its internal
>>> checking gets ignored and a success is returned today.
>>>
>>
>> That is correct, and I have suggested to add a return value in my previous
>> review.
> 
> Yeah ok. I can add a separate patch fixing that, and couple of these checks then
> become redundant.
> 
>>
>>>>
>>>>> +			dev_err(&rproc->dev,
>>>>> +				"stop not supported for this rproc, use detach\n");
>>>>
>>>> The standard error message from the shell should be enough here, the same way it
>>>> is enough when the "start" and "stop" scenarios fail.
>>>
>>> Thought this was a bit more informative, but sure this trace can be dropped.
>>>
>>>>
>>>>> +			return -EINVAL;
>>>>> +		}
>>>>> +
>>>>>  		rproc_shutdown(rproc);
>>>>>  	} else if (!strncmp(cmd, "detach", len)) {
>>>>>  		if (rproc->state != RPROC_ATTACHED)
>>>>> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
>>>>> index 7de5905d276a..ab9e52180b04 100644
>>>>> --- a/drivers/remoteproc/remoteproc_core.c
>>>>> +++ b/drivers/remoteproc/remoteproc_core.c
>>>>> @@ -2075,7 +2075,10 @@ void rproc_shutdown(struct rproc *rproc)
>>>>>  	if (!atomic_dec_and_test(&rproc->power))
>>>>>  		goto out;
>>>>>  
>>>>> -	ret = rproc_stop(rproc, false);
>>>>> +	if (rproc->state == RPROC_ATTACHED && !rproc->ops->stop)
>>>>> +		ret = __rproc_detach(rproc);
>>>>> +	else
>>>>> +		ret = rproc_stop(rproc, false);
>>>>
>>>> As I indicated in my last review I think rproc_shutdown() and rproc_del() should
>>>> be decoupled and the right call made in the platform drivers based on the state
>>>> of the remote processor.  

Agree With Mathieu. More than that it looks to me that the stop ops is not
optional and mandatory to implement the remoteproc shutdown. It should be the
role of the platform driver to decide if a stop is a detachment.

This behavior may also depend on the project for multi purpose platforms. In
this case DT property might be more appropriate than a null stop ops to
determine the behavior.

>>>
>>> We have various remoteproc API provided in pairs - rproc_alloc()/rproc_free(),
>>> rproc_add()/rproc_del(), rproc_boot()/rproc_shutdown() and
>>> rproc_attach()/rproc_detach(). The drivers are configuring conditions for
>>> auto-boot and RPROC_DETACHED. The reason they are coupled is primarily because
>>> of the auto-boot done during rproc_add(). And we handle the RPROC_DETACHED case
>>> just as well in rproc_boot().
>>>
>>
>> The difference with rproc_boot() is that we are checking only the state of the
>> remoteproc, everything else related to the remote processor operations is
>> seamlessly handles by the state machine.  It is also tied to the
>> rproc_trigger_auto_boot() mechanic - decoupling that would be messy without
>> bringing any advantages other than keeping with a semantic symmetry.
> 
> Most of this is actually tied to auto_boot if you think about it, not just the
> rproc state. If we have auto_boot set to false, then rproc_add() would not do
> anything, and the decision to start or attach can either be done through the
> sysfs/cdev or a kernel remoteproc or some consumer driver. And the state machine
> is getting influenced by this flag. auto-boot is a very useful feature.
> 
> You are asking is to do things differently between the regular start/stop case
> and attach/detach case ignoring the auto-boot. The semantic symmetry actually
> makes it easier to follow the state machine given that there are some internal
> reference counts as well.
> 
> Note that we also have the devres API, and rproc_alloc()/rproc_free() and
> rproc_add()/rproc_del() form the main remoteproc subsystem API. The drivers
> would end up using matching calls if we don't have auto_boot.
> 
>>
>>> While what you have suggested works, but I am not quite convinced on this
>>> asymmetric usage, and why this state-machine logic should be split between the
>>> core and remoteproc drivers differently between attach and detach. To me,
>>> calling rproc_detach() in remoteproc drivers would have made sense only if they
>>> are also calling rproc_attach().

In current implementation to be able to detach a remote processor we need to be
in RPROC_ATTACHED state. If I well remember the reason is the backup of the
resource table to reinitialize it on detach.should we improve this?

We could also consider the attach and detach as 2 separate features:
- attach is used for a pre loaded firmware (e.g early action use case waiting
Linux boot)
   => can be stopped as a loaded firmware.

- boot a remote firmware loaded from sysfs but detach it on Linux shutdown to
allow it to property stop it own activities (e.g Linux independent reboot).

>>
>> As pointed out above I see rproc_boot() as a special case but if that really
>> concerns you I'm open to consider patches that will take rproc_attach() out of
>> rproc_boot(). 
>>
> 
> We are talking about a bigger behavioral change to remoteproc core here. So I
> would definitely want to hear from others as well on this before we spend any
> time reworking code.

I'm not sure to understand what would be behind this rework. What is exactly the
issue on the rproc_boot? having a semantic symmetry? In this case do you expect
that the user application determines the current state of the remote processor
and "start" it or "attach" it, depending on state? Or does it be implemented in
rproc_sysfs and rpcroc_cdev (and few platform drivers).

Look to me that take rproc_attach() out of rproc_boot() could break or
complexify some legacy APIs.

Regards,
Arnaud

> 
> Meanwhile, how do I take this series forward? One option I can probably do is
> turn off auto-boot for early-boot case in my drivers and do the matching
> attach/detach.
> 
> regards
> Suman
> 
>>>
>>>
>>> Conditions such as the above make the core code
>>>> brittle, difficult to understand and tedious to maintain.
>>>
>>> The logic I have added actually makes rproc_shutdown behavior to be on par with
>>> the rproc_boot().
>>>
>>> regards
>>> Suman
>>>
>>>>
>>>> Thanks,
>>>> Mathieu
>>>>
>>>>>  	if (ret) {
>>>>>  		atomic_inc(&rproc->power);
>>>>>  		goto out;
>>>>> diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c
>>>>> index ea8b89f97d7b..133e766f38d4 100644
>>>>> --- a/drivers/remoteproc/remoteproc_sysfs.c
>>>>> +++ b/drivers/remoteproc/remoteproc_sysfs.c
>>>>> @@ -206,6 +206,12 @@ static ssize_t state_store(struct device *dev,
>>>>>  		    rproc->state != RPROC_ATTACHED)
>>>>>  			return -EINVAL;
>>>>>  
>>>>> +		if (rproc->state == RPROC_ATTACHED &&
>>>>> +		    !rproc->ops->stop) {
>>>>> +			dev_err(&rproc->dev, "stop not supported for this rproc, use detach\n");
>>>>> +			return -EINVAL;
>>>>> +		}
>>>>> +
>>>>>  		rproc_shutdown(rproc);
>>>>>  	} else if (sysfs_streq(buf, "detach")) {
>>>>>  		if (rproc->state != RPROC_ATTACHED)
>>>>> -- 
>>>>> 2.32.0
>>>>>
>>>
> 


From will at kernel.org  Mon Aug  9 10:05:08 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 18:05:08 +0100
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent
 masters to use system cache
In-Reply-To: <CAF6AEGsSUojA=V0n2iRWTCn++buqN=Eoxo0r3=+=PBu1O=H-AQ@mail.gmail.com>
References: <cover.1610372717.git.saiprakash.ranjan@codeaurora.org>
 <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
 <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
 <20210809145651.GC1458@willie-the-truck>
 <CAF6AEGsSUojA=V0n2iRWTCn++buqN=Eoxo0r3=+=PBu1O=H-AQ@mail.gmail.com>
Message-ID: <20210809170508.GB1589@willie-the-truck>

On Mon, Aug 09, 2021 at 09:57:08AM -0700, Rob Clark wrote:
> On Mon, Aug 9, 2021 at 7:56 AM Will Deacon <will at kernel.org> wrote:
> > On Mon, Aug 02, 2021 at 06:36:04PM -0700, Rob Clark wrote:
> > > On Mon, Aug 2, 2021 at 8:14 AM Will Deacon <will at kernel.org> wrote:
> > > > On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> > > > > On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> > > > > > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> > > > > > > On 2021-07-28 19:30, Georgi Djakov wrote:
> > > > > > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > > > > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > > > > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > > > > > > > the memory type setting required for the non-coherent masters to use
> > > > > > > > > system cache. Now that system cache support for GPU is added, we will
> > > > > > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > > > > > > > Without this, the system cache lines are not allocated for GPU.
> > > > > > > > >
> > > > > > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > > > > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > > > > > > > and makes GPU the user of this protection flag.
> > > > > > > >
> > > > > > > > Thank you for the patchset! Are you planning to refresh it, as it does
> > > > > > > > not apply anymore?
> > > > > > > >
> > > > > > >
> > > > > > > I was waiting on Will's reply [1]. If there are no changes needed, then
> > > > > > > I can repost the patch.
> > > > > >
> > > > > > I still think you need to handle the mismatched alias, no? You're adding
> > > > > > a new memory type to the SMMU which doesn't exist on the CPU side. That
> > > > > > can't be right.
> > > > > >
> > > > >
> > > > > Just curious, and maybe this is a dumb question, but what is your
> > > > > concern about mismatched aliases?  I mean the cache hierarchy on the
> > > > > GPU device side (anything beyond the LLC) is pretty different and
> > > > > doesn't really care about the smmu pgtable attributes..
> > > >
> > > > If the CPU accesses a shared buffer with different attributes to those which
> > > > the device is using then you fall into the "mismatched memory attributes"
> > > > part of the Arm architecture. It's reasonably unforgiving (you should go and
> > > > read it) and in some cases can apply to speculative accesses as well, but
> > > > the end result is typically loss of coherency.
> > >
> > > Ok, I might have a few other sections to read first to decipher the
> > > terminology..
> > >
> > > But my understanding of LLC is that it looks just like system memory
> > > to the CPU and GPU (I think that would make it "the point of
> > > coherence" between the GPU and CPU?)  If that is true, shouldn't it be
> > > invisible from the point of view of different CPU mapping options?
> >
> > You could certainly build a system where mismatched attributes don't cause
> > loss of coherence, but as it's not guaranteed by the architecture and the
> > changes proposed here affect APIs which are exposed across SoCs, then I
> > don't think it helps much.
> >
> 
> Hmm, the description of the new mapping flag is that it applies only
> to transparent outer level cache:
> 
> +/*
> + * Non-coherent masters can use this page protection flag to set cacheable
> + * memory attributes for only a transparent outer level of cache, also known as
> + * the last-level or system cache.
> + */
> +#define IOMMU_LLC      (1 << 6)
> 
> But I suppose we could call it instead IOMMU_QCOM_LLC or something
> like that to make it more clear that it is not necessarily something
> that would work with a different outer level cache implementation?

... or we could just deal with the problem so that other people can reuse
the code. I haven't really understood the reluctance to solve this properly.

Am I missing some reason this isn't solvable?

Will


From jernej.skrabec at gmail.com  Mon Aug  9 10:07:35 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 09 Aug 2021 19:07:35 +0200
Subject: [PATCH v3 09/10] media: hantro: Support VP9 on the G2 core
In-Reply-To: <20210805144246.11998-10-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
 <20210805144246.11998-10-andrzej.p@collabora.com>
Message-ID: <1771240.sZXMzDhkfG@kista>

Hi Andrzej!

Dne ?etrtek, 05. avgust 2021 ob 16:42:45 CEST je Andrzej Pietrasiewicz 
napisal(a):
> VeriSilicon Hantro G2 core supports VP9 codec.
> 
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
> ---
>  drivers/staging/media/hantro/Kconfig          |   1 +
>  drivers/staging/media/hantro/Makefile         |   6 +-
>  drivers/staging/media/hantro/hantro.h         |  26 +
>  drivers/staging/media/hantro/hantro_drv.c     |  18 +-
>  drivers/staging/media/hantro/hantro_g2_regs.h |  97 ++
>  .../staging/media/hantro/hantro_g2_vp9_dec.c  | 978 ++++++++++++++++++
>  drivers/staging/media/hantro/hantro_hw.h      |  67 ++
>  drivers/staging/media/hantro/hantro_v4l2.c    |   6 +
>  drivers/staging/media/hantro/hantro_vp9.c     | 240 +++++
>  drivers/staging/media/hantro/hantro_vp9.h     | 103 ++
>  drivers/staging/media/hantro/imx8m_vpu_hw.c   |  22 +-
>  11 files changed, 1560 insertions(+), 4 deletions(-)
>  create mode 100644 drivers/staging/media/hantro/hantro_g2_vp9_dec.c
>  create mode 100644 drivers/staging/media/hantro/hantro_vp9.c
>  create mode 100644 drivers/staging/media/hantro/hantro_vp9.h

<snip>

> diff --git a/drivers/staging/media/hantro/hantro_g2_vp9_dec.c b/drivers/
staging/media/hantro/hantro_g2_vp9_dec.c
> new file mode 100644
> index 000000000000..45a7be4a43fa
> --- /dev/null
> +++ b/drivers/staging/media/hantro/hantro_g2_vp9_dec.c
> @@ -0,0 +1,978 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Hantro VP9 codec driver
> + *
> + * Copyright (C) 2021 Collabora Ltd.
> + */
> +#include "media/videobuf2-core.h"
> +#include "media/videobuf2-dma-contig.h"
> +#include "media/videobuf2-v4l2.h"
> +#include <linux/kernel.h>
> +#include <linux/vmalloc.h>
> +#include <media/v4l2-mem2mem.h>
> +#include <media/v4l2-vp9.h>
> +
> +#include "hantro.h"
> +#include "hantro_vp9.h"
> +#include "hantro_g2_regs.h"
> +
> +#define G2_ALIGN 16
> +
> +enum hantro_ref_frames {
> +	INTRA_FRAME = 0,
> +	LAST_FRAME = 1,
> +	GOLDEN_FRAME = 2,
> +	ALTREF_FRAME = 3,
> +	MAX_REF_FRAMES = 4
> +};
> +
> +static int start_prepare_run(struct hantro_ctx *ctx, const struct 
v4l2_ctrl_vp9_frame **dec_params)
> +{
> +	const struct v4l2_ctrl_vp9_compressed_hdr_probs *prob_updates;
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	struct v4l2_ctrl *ctrl;
> +	unsigned int fctx_idx;
> +
> +	/* v4l2-specific stuff */
> +	hantro_start_prepare_run(ctx);
> +
> +	ctrl = v4l2_ctrl_find(&ctx->ctrl_handler, 
V4L2_CID_STATELESS_VP9_FRAME);
> +	if (WARN_ON(!ctrl))
> +		return -EINVAL;
> +	*dec_params = ctrl->p_cur.p;
> +
> +	ctrl = v4l2_ctrl_find(&ctx->ctrl_handler, 
V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS);
> +	if (WARN_ON(!ctrl))
> +		return -EINVAL;
> +	prob_updates = ctrl->p_cur.p;
> +
> +	/*
> +	 * vp9 stuff
> +	 *
> +	 * by this point the userspace has done all parts of 6.2 
uncompressed_header()
> +	 * except this fragment:
> +	 * if ( FrameIsIntra || error_resilient_mode ) {
> +	 *	setup_past_independence ( )
> +	 *	if ( frame_type == KEY_FRAME || error_resilient_mode == 
1 ||
> +	 *	     reset_frame_context == 3 ) {
> +	 *		for ( i = 0; i < 4; i ++ ) {
> +	 *			save_probs( i )
> +	 *		}
> +	 *	} else if ( reset_frame_context == 2 ) {
> +	 *		save_probs( frame_context_idx )
> +	 *	}
> +	 *	frame_context_idx = 0
> +	 * }
> +	 */
> +	fctx_idx = v4l2_vp9_reset_frame_ctx(*dec_params, vp9_ctx-
>frame_context);
> +	vp9_ctx->cur.frame_context_idx = fctx_idx;
> +
> +	/* 6.1 frame(sz): load_probs() and load_probs2() */
> +	vp9_ctx->probability_tables = vp9_ctx->frame_context[fctx_idx];
> +
> +	/*
> +	 * The userspace has also performed 6.3 compressed_header(), but 
handling the
> +	 * probs in a special way. All probs which need updating, except 
MV-related,
> +	 * have been read from the bitstream and translated through 
inv_map_table[],
> +	 * but no 6.3.6 inv_recenter_nonneg(v, m) has been performed. The 
values passed
> +	 * by userspace are either translated values (there are no 0 values 
in
> +	 * inv_map_table[]), or zero to indicate no update. All MV-related 
probs which need
> +	 * updating have been read from the bitstream and (mv_prob << 1) | 
1 has been
> +	 * performed. The values passed by userspace are either new values
> +	 * to replace old ones (the above mentioned shift and bitwise or 
never result in
> +	 * a zero) or zero to indicate no update.
> +	 * fw_update_probs() performs actual probs updates or leaves probs 
as-is
> +	 * for values for which a zero was passed from userspace.
> +	 */
> +	v4l2_vp9_fw_update_probs(&vp9_ctx->probability_tables, 
prob_updates, *dec_params);
> +
> +	return 0;
> +}
> +
> +static size_t chroma_offset(const struct hantro_ctx *ctx,
> +			    const struct v4l2_ctrl_vp9_frame 
*dec_params)
> +{
> +	int bytes_per_pixel = dec_params->bit_depth == 8 ? 1 : 2;
> +
> +	return ctx->src_fmt.width * ctx->src_fmt.height * bytes_per_pixel;
> +}
> +
> +static size_t mv_offset(const struct hantro_ctx *ctx,
> +			const struct v4l2_ctrl_vp9_frame *dec_params)
> +{
> +	size_t cr_offset = chroma_offset(ctx, dec_params);
> +
> +	return ALIGN((cr_offset * 3) / 2, G2_ALIGN);
> +}
> +
> +static struct hantro_decoded_buffer *
> +get_ref_buf(struct hantro_ctx *ctx, struct vb2_v4l2_buffer *dst, u64 
timestamp)
> +{
> +	struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
> +	struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
> +	int buf_idx;
> +
> +	/*
> +	 * If a ref is unused or invalid, address of current destination
> +	 * buffer is returned.
> +	 */
> +	buf_idx = vb2_find_timestamp(cap_q, timestamp, 0);
> +	if (buf_idx < 0)
> +		return vb2_to_hantro_decoded_buf(&dst->vb2_buf);
> +
> +	return vb2_to_hantro_decoded_buf(vb2_get_buffer(cap_q, buf_idx));
> +}
> +
> +static void update_dec_buf_info(struct hantro_decoded_buffer *buf,
> +				const struct v4l2_ctrl_vp9_frame 
*dec_params)
> +{
> +	buf->vp9.width = dec_params->frame_width_minus_1 + 1;
> +	buf->vp9.height = dec_params->frame_height_minus_1 + 1;
> +	buf->vp9.bit_depth = dec_params->bit_depth;
> +}
> +
> +static void update_ctx_cur_info(struct hantro_vp9_dec_hw_ctx *vp9_ctx,
> +				struct hantro_decoded_buffer *buf,
> +				const struct v4l2_ctrl_vp9_frame 
*dec_params)
> +{
> +	vp9_ctx->cur.valid = true;
> +	vp9_ctx->cur.reference_mode = dec_params->reference_mode;
> +	vp9_ctx->cur.tx_mode = dec_params->tx_mode;
> +	vp9_ctx->cur.interpolation_filter = dec_params->interpolation_filter;
> +	vp9_ctx->cur.flags = dec_params->flags;
> +	vp9_ctx->cur.timestamp = buf->base.vb.vb2_buf.timestamp;
> +}
> +
> +static void config_output(struct hantro_ctx *ctx,
> +			  struct hantro_decoded_buffer *dst,
> +			  const struct v4l2_ctrl_vp9_frame 
*dec_params)
> +{
> +	dma_addr_t luma_addr, chroma_addr, mv_addr;
> +
> +	hantro_reg_write(ctx->dev, &g2_out_dis, 0);
> +	hantro_reg_write(ctx->dev, &g2_output_format, 0);
> +
> +	luma_addr = vb2_dma_contig_plane_dma_addr(&dst->base.vb.vb2_buf, 
0);
> +	hantro_write_addr(ctx->dev, G2_ADDR_DST, luma_addr);
> +
> +	chroma_addr = luma_addr + chroma_offset(ctx, dec_params);
> +	hantro_write_addr(ctx->dev, G2_ADDR_DST_CHR, chroma_addr);
> +
> +	mv_addr = luma_addr + mv_offset(ctx, dec_params);
> +	hantro_write_addr(ctx->dev, G2_ADDR_DST_MV, mv_addr);
> +}
> +
> +struct hantro_vp9_ref_reg {
> +	const struct hantro_reg width;
> +	const struct hantro_reg height;
> +	const struct hantro_reg hor_scale;
> +	const struct hantro_reg ver_scale;
> +	u32 y_base;
> +	u32 c_base;
> +};
> +
> +static void config_ref(struct hantro_ctx *ctx,
> +		       struct hantro_decoded_buffer *dst,
> +		       const struct hantro_vp9_ref_reg *ref_reg,
> +		       const struct v4l2_ctrl_vp9_frame *dec_params,
> +		       u64 ref_ts)
> +{
> +	struct hantro_decoded_buffer *buf;
> +	dma_addr_t luma_addr, chroma_addr;
> +	u32 refw, refh;
> +
> +	buf = get_ref_buf(ctx, &dst->base.vb, ref_ts);
> +	refw = buf->vp9.width;
> +	refh = buf->vp9.height;
> +
> +	hantro_reg_write(ctx->dev, &ref_reg->width, refw);
> +	hantro_reg_write(ctx->dev, &ref_reg->height, refh);
> +
> +	hantro_reg_write(ctx->dev, &ref_reg->hor_scale, (refw << 14) / dst-
>vp9.width);
> +	hantro_reg_write(ctx->dev, &ref_reg->ver_scale, (refh << 14) / dst-
>vp9.height);
> +
> +	luma_addr = vb2_dma_contig_plane_dma_addr(&buf->base.vb.vb2_buf, 
0);
> +	hantro_write_addr(ctx->dev, ref_reg->y_base, luma_addr);
> +
> +	chroma_addr = luma_addr + chroma_offset(ctx, dec_params);
> +	hantro_write_addr(ctx->dev, ref_reg->c_base, chroma_addr);
> +}
> +
> +static void config_ref_registers(struct hantro_ctx *ctx,
> +				 const struct v4l2_ctrl_vp9_frame 
*dec_params,
> +				 struct hantro_decoded_buffer *dst,
> +				 struct hantro_decoded_buffer 
*mv_ref)
> +{
> +	static const struct hantro_vp9_ref_reg ref_regs[] = {
> +		{
> +			/* Last */
> +			.width = vp9_lref_width,
> +			.height = vp9_lref_height,
> +			.hor_scale = vp9_lref_hor_scale,
> +			.ver_scale = vp9_lref_ver_scale,
> +			.y_base = G2_REG_ADDR_REF(0),
> +			.c_base = G2_REG_CHR_REF(0),
> +		}, {
> +			/* Golden */
> +			.width = vp9_gref_width,
> +			.height = vp9_gref_height,
> +			.hor_scale = vp9_gref_hor_scale,
> +			.ver_scale = vp9_gref_ver_scale,
> +			.y_base = G2_REG_ADDR_REF(4),
> +			.c_base = G2_REG_CHR_REF(4),
> +		}, {
> +			/* Altref */
> +			.width = vp9_aref_width,
> +			.height = vp9_aref_height,
> +			.hor_scale = vp9_aref_hor_scale,
> +			.ver_scale = vp9_aref_ver_scale,
> +			.y_base = G2_REG_ADDR_REF(5),
> +			.c_base = G2_REG_CHR_REF(5),
> +		},
> +	};
> +	dma_addr_t mv_addr;
> +
> +	config_ref(ctx, dst, &ref_regs[0], dec_params, dec_params-
>last_frame_ts);
> +	config_ref(ctx, dst, &ref_regs[1], dec_params, dec_params-
>golden_frame_ts);
> +	config_ref(ctx, dst, &ref_regs[2], dec_params, dec_params-
>alt_frame_ts);
> +
> +	mv_addr = vb2_dma_contig_plane_dma_addr(&mv_ref->base.vb.vb2_buf, 
0) +
> +		  mv_offset(ctx, dec_params);
> +	hantro_write_addr(ctx->dev, G2_REG_DMV_REF(0), mv_addr);
> +
> +	hantro_reg_write(ctx->dev, &vp9_last_sign_bias,
> +			 dec_params->ref_frame_sign_bias & 
V4L2_VP9_SIGN_BIAS_LAST ? 1 : 0);
> +
> +	hantro_reg_write(ctx->dev, &vp9_gref_sign_bias,
> +			 dec_params->ref_frame_sign_bias & 
V4L2_VP9_SIGN_BIAS_GOLDEN ? 1 : 0);
> +
> +	hantro_reg_write(ctx->dev, &vp9_aref_sign_bias,
> +			 dec_params->ref_frame_sign_bias & 
V4L2_VP9_SIGN_BIAS_ALT ? 1 : 0);

Not sure if I'm missing something, but V4L2_VP9_SIGN_BIAS_LAST, 
V4L2_VP9_SIGN_BIAS_GOLDEN and V4L2_VP9_SIGN_BIAS_ALT are defined in ordinary 
enum in patch 5, without any value, so they would have values 0, 1 and 2.

I guess you actually want (1 << 0), (1 << 1) and (1 << 2) in patch 5. Second 
and third flag still work by chance and first flag is always applied.

Best regards,
Jernej


> +}
> +
> +static void recompute_tile_info(unsigned short *tile_info, unsigned int 
tiles, unsigned int sbs)
> +{
> +	int i;
> +	unsigned int accumulated = 0;
> +	unsigned int next_accumulated;
> +
> +	for (i = 1; i <= tiles; ++i) {
> +		next_accumulated = i * sbs / tiles;
> +		*tile_info++ = next_accumulated - accumulated;
> +		accumulated = next_accumulated;
> +	}
> +}
> +
> +static void
> +recompute_tile_rc_info(struct hantro_ctx *ctx,
> +		       unsigned int tile_r, unsigned int tile_c,
> +		       unsigned int sbs_r, unsigned int sbs_c)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +
> +	recompute_tile_info(vp9_ctx->tile_r_info, tile_r, sbs_r);
> +	recompute_tile_info(vp9_ctx->tile_c_info, tile_c, sbs_c);
> +
> +	vp9_ctx->last_tile_r = tile_r;
> +	vp9_ctx->last_tile_c = tile_c;
> +	vp9_ctx->last_sbs_r = sbs_r;
> +	vp9_ctx->last_sbs_c = sbs_c;
> +}
> +
> +static inline unsigned int first_tile_row(unsigned int tile_r, unsigned int 
sbs_r)
> +{
> +	if (tile_r == sbs_r + 1)
> +		return 1;
> +
> +	if (tile_r == sbs_r + 2)
> +		return 2;
> +
> +	return 0;
> +}
> +
> +static void
> +fill_tile_info(struct hantro_ctx *ctx,
> +	       unsigned int tile_r, unsigned int tile_c,
> +	       unsigned int sbs_r, unsigned int sbs_c,
> +	       unsigned short *tile_mem)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	unsigned int i, j;
> +	bool first = true;
> +
> +	for (i = first_tile_row(tile_r, sbs_r); i < tile_r; ++i) {
> +		unsigned short r_info = vp9_ctx->tile_r_info[i];
> +
> +		if (first) {
> +			if (i > 0)
> +				r_info += vp9_ctx->tile_r_info[0];
> +			if (i == 2)
> +				r_info += vp9_ctx->tile_r_info[1];
> +			first = false;
> +		}
> +		for (j = 0; j < tile_c; ++j) {
> +			*tile_mem++ = vp9_ctx->tile_c_info[j];
> +			*tile_mem++ = r_info;
> +		}
> +	}
> +}
> +
> +static void
> +config_tiles(struct hantro_ctx *ctx,
> +	     const struct v4l2_ctrl_vp9_frame *dec_params,
> +	     struct hantro_decoded_buffer *dst)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	struct hantro_aux_buf *misc = &vp9_ctx->misc;
> +	struct hantro_aux_buf *tile_edge = &vp9_ctx->tile_edge;
> +	dma_addr_t addr;
> +	unsigned short *tile_mem;
> +
> +	addr = misc->dma + vp9_ctx->tile_info_offset;
> +	hantro_write_addr(ctx->dev, G2_ADDR_TILE_SIZE, addr);
> +
> +	tile_mem = misc->cpu + vp9_ctx->tile_info_offset;
> +	if (dec_params->tile_cols_log2 || dec_params->tile_rows_log2) {
> +		unsigned int tile_r = (1 << dec_params->tile_rows_log2);
> +		unsigned int tile_c = (1 << dec_params->tile_cols_log2);
> +		unsigned int sbs_r = hantro_vp9_num_sbs(dst-
>vp9.height);
> +		unsigned int sbs_c = hantro_vp9_num_sbs(dst->vp9.width);
> +
> +		if (tile_r != vp9_ctx->last_tile_r || tile_c != vp9_ctx-
>last_tile_c ||
> +		    sbs_r != vp9_ctx->last_sbs_r || sbs_c != vp9_ctx-
>last_sbs_c)
> +			recompute_tile_rc_info(ctx, tile_r, tile_c, 
sbs_r, sbs_c);
> +
> +		fill_tile_info(ctx, tile_r, tile_c, sbs_r, sbs_c, 
tile_mem);
> +
> +		hantro_reg_write(ctx->dev, &g2_tile_e, 1);
> +		hantro_reg_write(ctx->dev, &g2_num_tile_cols, tile_c);
> +		hantro_reg_write(ctx->dev, &g2_num_tile_rows, tile_r);
> +
> +		addr = tile_edge->dma;
> +		hantro_write_addr(ctx->dev, G2_TILE_FILTER, addr);
> +
> +		addr = tile_edge->dma + vp9_ctx->bsd_ctrl_offset;
> +		hantro_write_addr(ctx->dev, G2_TILE_BSD, addr);
> +	} else {
> +		tile_mem[0] = hantro_vp9_num_sbs(dst->vp9.width);
> +		tile_mem[1] = hantro_vp9_num_sbs(dst->vp9.height);
> +
> +		hantro_reg_write(ctx->dev, &g2_tile_e, 0);
> +		hantro_reg_write(ctx->dev, &g2_num_tile_cols, 1);
> +		hantro_reg_write(ctx->dev, &g2_num_tile_rows, 1);
> +	}
> +}
> +
> +static void
> +update_feat_and_flag(struct hantro_vp9_dec_hw_ctx *vp9_ctx,
> +		     const struct v4l2_vp9_segmentation *seg,
> +		     enum v4l2_vp9_segment_feature feature,
> +		     unsigned int segid)
> +{
> +	u8 mask = V4L2_VP9_SEGMENT_FEATURE_ENABLED(feature);
> +
> +	vp9_ctx->feature_data[segid][feature] = seg->feature_data[segid]
[feature];
> +	vp9_ctx->feature_enabled[segid] &= ~mask;
> +	vp9_ctx->feature_enabled[segid] |= (seg->feature_enabled[segid] & 
mask);
> +}
> +
> +static inline s16 clip3(s16 x, s16 y, s16 z)
> +{
> +	return (z < x) ? x : (z > y) ? y : z;
> +}
> +
> +static s16 feat_val_clip3(s16 feat_val, s16 feature_data, bool absolute, u8 
clip)
> +{
> +	if (absolute)
> +		return feature_data;
> +
> +	return clip3(0, 255, feat_val + feature_data);
> +}
> +
> +static void config_segment(struct hantro_ctx *ctx, const struct 
v4l2_ctrl_vp9_frame *dec_params)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	const struct v4l2_vp9_segmentation *seg;
> +	s16 feat_val;
> +	unsigned char feat_id;
> +	unsigned int segid;
> +	bool segment_enabled, absolute, update_data;
> +
> +	static const struct hantro_reg seg_regs[8][V4L2_VP9_SEG_LVL_MAX] = 
{
> +		{ vp9_quant_seg0, vp9_filt_level_seg0, vp9_refpic_seg0, 
vp9_skip_seg0 },
> +		{ vp9_quant_seg1, vp9_filt_level_seg1, vp9_refpic_seg1, 
vp9_skip_seg1 },
> +		{ vp9_quant_seg2, vp9_filt_level_seg2, vp9_refpic_seg2, 
vp9_skip_seg2 },
> +		{ vp9_quant_seg3, vp9_filt_level_seg3, vp9_refpic_seg3, 
vp9_skip_seg3 },
> +		{ vp9_quant_seg4, vp9_filt_level_seg4, vp9_refpic_seg4, 
vp9_skip_seg4 },
> +		{ vp9_quant_seg5, vp9_filt_level_seg5, vp9_refpic_seg5, 
vp9_skip_seg5 },
> +		{ vp9_quant_seg6, vp9_filt_level_seg6, vp9_refpic_seg6, 
vp9_skip_seg6 },
> +		{ vp9_quant_seg7, vp9_filt_level_seg7, vp9_refpic_seg7, 
vp9_skip_seg7 },
> +	};
> +
> +	segment_enabled = !!(dec_params->seg.flags & 
V4L2_VP9_SEGMENTATION_FLAG_ENABLED);
> +	hantro_reg_write(ctx->dev, &vp9_segment_e, segment_enabled);
> +	hantro_reg_write(ctx->dev, &vp9_segment_upd_e,
> +			 !!(dec_params->seg.flags & 
V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP));
> +	hantro_reg_write(ctx->dev, &vp9_segment_temp_upd_e,
> +			 !!(dec_params->seg.flags & 
V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE));
> +
> +	seg = &dec_params->seg;
> +	absolute = !!(seg->flags & 
V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE);
> +	update_data = !!(seg->flags & 
V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA);
> +
> +	for (segid = 0; segid < 8; ++segid) {
> +		/* Quantizer segment feature */
> +		feat_id = V4L2_VP9_SEG_LVL_ALT_Q;
> +		feat_val = dec_params->quant.base_q_idx;
> +		if (segment_enabled) {
> +			if (update_data)
> +				update_feat_and_flag(vp9_ctx, seg, 
feat_id, segid);
> +			if (v4l2_vp9_seg_feat_enabled(vp9_ctx-
>feature_enabled, feat_id, segid))
> +				feat_val = 
feat_val_clip3(feat_val,
> +							  
vp9_ctx->feature_data[segid][feat_id],
> +							  
absolute, 255);
> +		}
> +		hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], 
feat_val);
> +
> +		/* Loop filter segment feature */
> +		feat_id = V4L2_VP9_SEG_LVL_ALT_L;
> +		feat_val = dec_params->lf.level;
> +		if (segment_enabled) {
> +			if (update_data)
> +				update_feat_and_flag(vp9_ctx, seg, 
feat_id, segid);
> +			if (v4l2_vp9_seg_feat_enabled(vp9_ctx-
>feature_enabled, feat_id, segid))
> +				feat_val = 
feat_val_clip3(feat_val,
> +							  
vp9_ctx->feature_data[segid][feat_id],
> +							  
absolute, 63);
> +		}
> +		hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], 
feat_val);
> +
> +		/* Reference frame segment feature */
> +		feat_id = V4L2_VP9_SEG_LVL_REF_FRAME;
> +		feat_val = 0;
> +		if (segment_enabled) {
> +			if (update_data)
> +				update_feat_and_flag(vp9_ctx, seg, 
feat_id, segid);
> +			if (!(dec_params->flags & 
V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
> +			    v4l2_vp9_seg_feat_enabled(vp9_ctx-
>feature_enabled, feat_id, segid))
> +				feat_val = vp9_ctx-
>feature_data[segid][feat_id] + 1;
> +		}
> +		hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], 
feat_val);
> +
> +		/* Skip segment feature */
> +		feat_id = V4L2_VP9_SEG_LVL_SKIP;
> +		feat_val = 0;
> +		if (segment_enabled) {
> +			if (update_data)
> +				update_feat_and_flag(vp9_ctx, seg, 
feat_id, segid);
> +			feat_val = v4l2_vp9_seg_feat_enabled(vp9_ctx-
>feature_enabled,
> +							     
feat_id, segid) ? 1 : 0;
> +		}
> +		hantro_reg_write(ctx->dev, &seg_regs[segid][feat_id], 
feat_val);
> +	}
> +}
> +
> +static void config_loop_filter(struct hantro_ctx *ctx, const struct 
v4l2_ctrl_vp9_frame *dec_params)
> +{
> +	bool d = dec_params->lf.flags & 
V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED;
> +
> +	hantro_reg_write(ctx->dev, &vp9_filt_level, dec_params->lf.level);
> +	hantro_reg_write(ctx->dev, &g2_out_filtering_dis, dec_params-
>lf.level == 0);
> +	hantro_reg_write(ctx->dev, &vp9_filt_sharpness, dec_params-
>lf.sharpness);
> +
> +	hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_0, d ? dec_params-
>lf.ref_deltas[0] : 0);
> +	hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_1, d ? dec_params-
>lf.ref_deltas[1] : 0);
> +	hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_2, d ? dec_params-
>lf.ref_deltas[2] : 0);
> +	hantro_reg_write(ctx->dev, &vp9_filt_ref_adj_3, d ? dec_params-
>lf.ref_deltas[3] : 0);
> +	hantro_reg_write(ctx->dev, &vp9_filt_mb_adj_0, d ? dec_params-
>lf.mode_deltas[0] : 0);
> +	hantro_reg_write(ctx->dev, &vp9_filt_mb_adj_1, d ? dec_params-
>lf.mode_deltas[1] : 0);
> +}
> +
> +static void config_picture_dimensions(struct hantro_ctx *ctx, struct 
hantro_decoded_buffer *dst)
> +{
> +	u32 pic_w_4x4, pic_h_4x4;
> +
> +	hantro_reg_write(ctx->dev, &g2_pic_width_in_cbs, (dst->vp9.width + 
7) / 8);
> +	hantro_reg_write(ctx->dev, &g2_pic_height_in_cbs, (dst->vp9.height 
+ 7) / 8);
> +	pic_w_4x4 = roundup(dst->vp9.width, 8) >> 2;
> +	pic_h_4x4 = roundup(dst->vp9.height, 8) >> 2;
> +	hantro_reg_write(ctx->dev, &g2_pic_width_4x4, pic_w_4x4);
> +	hantro_reg_write(ctx->dev, &g2_pic_height_4x4, pic_h_4x4);
> +}
> +
> +static void
> +config_bit_depth(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame 
*dec_params)
> +{
> +	hantro_reg_write(ctx->dev, &g2_bit_depth_y_minus8, dec_params-
>bit_depth - 8);
> +	hantro_reg_write(ctx->dev, &g2_bit_depth_c_minus8, dec_params-
>bit_depth - 8);
> +}
> +
> +static inline bool is_lossless(const struct v4l2_vp9_quantization *quant)
> +{
> +	return quant->base_q_idx == 0 && quant->delta_q_uv_ac == 0 &&
> +	       quant->delta_q_uv_dc == 0 && quant->delta_q_y_dc == 0;
> +}
> +
> +static void
> +config_quant(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame 
*dec_params)
> +{
> +	hantro_reg_write(ctx->dev, &vp9_qp_delta_y_dc, dec_params-
>quant.delta_q_y_dc);
> +	hantro_reg_write(ctx->dev, &vp9_qp_delta_ch_dc, dec_params-
>quant.delta_q_uv_dc);
> +	hantro_reg_write(ctx->dev, &vp9_qp_delta_ch_ac, dec_params-
>quant.delta_q_uv_ac);
> +	hantro_reg_write(ctx->dev, &vp9_lossless_e, 
is_lossless(&dec_params->quant));
> +}
> +
> +static u32
> +hantro_interp_filter_from_v4l2(enum v4l2_vp9_interpolation_filter 
interpolation_filter)
> +{
> +	switch (interpolation_filter) {
> +	case V4L2_VP9_INTERP_FILTER_EIGHTTAP:
> +		return 0x1;
> +	case V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH:
> +		return 0;
> +	case V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP:
> +		return 0x2;
> +	case V4L2_VP9_INTERP_FILTER_BILINEAR:
> +		return 0x3;
> +	case V4L2_VP9_INTERP_FILTER_SWITCHABLE:
> +		return 0x4;
> +	}
> +
> +	return 0;
> +}
> +
> +static void
> +config_others(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame 
*dec_params,
> +	      bool intra_only, bool resolution_change)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +
> +	hantro_reg_write(ctx->dev, &g2_idr_pic_e, intra_only);
> +
> +	hantro_reg_write(ctx->dev, &vp9_transform_mode, dec_params-
>tx_mode);
> +
> +	hantro_reg_write(ctx->dev, &vp9_mcomp_filt_type, intra_only ?
> +		0 : hantro_interp_filter_from_v4l2(dec_params-
>interpolation_filter));
> +
> +	hantro_reg_write(ctx->dev, &vp9_high_prec_mv_e,
> +			 !!(dec_params->flags & 
V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV));
> +
> +	hantro_reg_write(ctx->dev, &vp9_comp_pred_mode, dec_params-
>reference_mode);
> +
> +	hantro_reg_write(ctx->dev, &g2_tempor_mvp_e,
> +			 !(dec_params->flags & 
V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
> +			 !(dec_params->flags & 
V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
> +			 !(vp9_ctx->last.flags & 
V4L2_VP9_FRAME_FLAG_KEY_FRAME) &&
> +			 !(dec_params->flags & 
V4L2_VP9_FRAME_FLAG_INTRA_ONLY) &&
> +			 !resolution_change &&
> +			 vp9_ctx->last.flags & 
V4L2_VP9_FRAME_FLAG_SHOW_FRAME
> +	);
> +
> +	hantro_reg_write(ctx->dev, &g2_write_mvs_e,
> +			 !(dec_params->flags & 
V4L2_VP9_FRAME_FLAG_KEY_FRAME));
> +}
> +
> +static void
> +config_compound_reference(struct hantro_ctx *ctx,
> +			  const struct v4l2_ctrl_vp9_frame 
*dec_params)
> +{
> +	u32 comp_fixed_ref, comp_var_ref[2];
> +	bool last_ref_frame_sign_bias;
> +	bool golden_ref_frame_sign_bias;
> +	bool alt_ref_frame_sign_bias;
> +	bool comp_ref_allowed = 0;
> +
> +	comp_fixed_ref = 0;
> +	comp_var_ref[0] = 0;
> +	comp_var_ref[1] = 0;
> +
> +	last_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & 
V4L2_VP9_SIGN_BIAS_LAST;
> +	golden_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & 
V4L2_VP9_SIGN_BIAS_GOLDEN;
> +	alt_ref_frame_sign_bias = dec_params->ref_frame_sign_bias & 
V4L2_VP9_SIGN_BIAS_ALT;
> +
> +	/* 6.3.12 Frame reference mode syntax */
> +	comp_ref_allowed |= golden_ref_frame_sign_bias != 
last_ref_frame_sign_bias;
> +	comp_ref_allowed |= alt_ref_frame_sign_bias != 
last_ref_frame_sign_bias;
> +
> +	if (comp_ref_allowed) {
> +		if (last_ref_frame_sign_bias ==
> +		    golden_ref_frame_sign_bias) {
> +			comp_fixed_ref = ALTREF_FRAME;
> +			comp_var_ref[0] = LAST_FRAME;
> +			comp_var_ref[1] = GOLDEN_FRAME;
> +		} else if (last_ref_frame_sign_bias ==
> +			   alt_ref_frame_sign_bias) {
> +			comp_fixed_ref = GOLDEN_FRAME;
> +			comp_var_ref[0] = LAST_FRAME;
> +			comp_var_ref[1] = ALTREF_FRAME;
> +		} else {
> +			comp_fixed_ref = LAST_FRAME;
> +			comp_var_ref[0] = GOLDEN_FRAME;
> +			comp_var_ref[1] = ALTREF_FRAME;
> +		}
> +	}
> +
> +	hantro_reg_write(ctx->dev, &vp9_comp_pred_fixed_ref, comp_fixed_ref);
> +	hantro_reg_write(ctx->dev, &vp9_comp_pred_var_ref0, 
comp_var_ref[0]);
> +	hantro_reg_write(ctx->dev, &vp9_comp_pred_var_ref1, 
comp_var_ref[1]);
> +}
> +
> +#define INNER_LOOP \
> +do {								
	\
> +	for (m = 0; m < ARRAY_SIZE(adaptive->coef[0][0][0][0]); ++m) {	\
> +		memcpy(adaptive->coef[i][j][k][l][m],			
\
> +		       probs->coef[i][j][k][l][m],			
\
> +		       sizeof(probs->coef[i][j][k][l][m]));		
\
> +								
	\
> +		adaptive->coef[i][j][k][l][m][3] = 0;			
\
> +	}							
	\
> +} while (0)
> +
> +static void config_probs(struct hantro_ctx *ctx, const struct 
v4l2_ctrl_vp9_frame *dec_params)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	struct hantro_aux_buf *misc = &vp9_ctx->misc;
> +	struct hantro_g2_all_probs *all_probs = misc->cpu;
> +	struct hantro_g2_probs *adaptive;
> +	struct hantro_g2_mv_probs *mv;
> +	const struct v4l2_vp9_segmentation *seg = &dec_params->seg;
> +	const struct v4l2_vp9_frame_context *probs = &vp9_ctx-
>probability_tables;
> +	int i, j, k, l, m;
> +
> +	for (i = 0; i < ARRAY_SIZE(all_probs->kf_y_mode_prob); ++i)
> +		for (j = 0; j < ARRAY_SIZE(all_probs-
>kf_y_mode_prob[0]); ++j) {
> +			memcpy(all_probs->kf_y_mode_prob[i][j],
> +			       v4l2_vp9_kf_y_mode_prob[i][j],
> +			       ARRAY_SIZE(all_probs-
>kf_y_mode_prob[i][j]));
> +
> +			all_probs->kf_y_mode_prob_tail[i][j][0] =
> +				v4l2_vp9_kf_y_mode_prob[i][j][8];
> +		}
> +
> +	memcpy(all_probs->mb_segment_tree_probs, seg->tree_probs,
> +	       sizeof(all_probs->mb_segment_tree_probs));
> +
> +	memcpy(all_probs->segment_pred_probs, seg->pred_probs,
> +	       sizeof(all_probs->segment_pred_probs));
> +
> +	for (i = 0; i < ARRAY_SIZE(all_probs->kf_uv_mode_prob); ++i) {
> +		memcpy(all_probs->kf_uv_mode_prob[i], 
v4l2_vp9_kf_uv_mode_prob[i],
> +		       ARRAY_SIZE(all_probs->kf_uv_mode_prob[i]));
> +
> +		all_probs->kf_uv_mode_prob_tail[i][0] = 
v4l2_vp9_kf_uv_mode_prob[i][8];
> +	}
> +
> +	adaptive = &all_probs->probs;
> +
> +	for (i = 0; i < ARRAY_SIZE(adaptive->inter_mode); ++i) {
> +		memcpy(adaptive->inter_mode[i], probs->inter_mode[i],
> +		       sizeof(probs->inter_mode));
> +
> +		adaptive->inter_mode[i][3] = 0;
> +	}
> +
> +	memcpy(adaptive->is_inter, probs->is_inter, sizeof(adaptive-
>is_inter));
> +
> +	for (i = 0; i < ARRAY_SIZE(adaptive->uv_mode); ++i) {
> +		memcpy(adaptive->uv_mode[i], probs->uv_mode[i],
> +		       sizeof(adaptive->uv_mode[i]));
> +		adaptive->uv_mode_tail[i][0] = probs->uv_mode[i][8];
> +	}
> +
> +	memcpy(adaptive->tx8, probs->tx8, sizeof(adaptive->tx8));
> +	memcpy(adaptive->tx16, probs->tx16, sizeof(adaptive->tx16));
> +	memcpy(adaptive->tx32, probs->tx32, sizeof(adaptive->tx32));
> +
> +	for (i = 0; i < ARRAY_SIZE(adaptive->y_mode); ++i) {
> +		memcpy(adaptive->y_mode[i], probs->y_mode[i],
> +		       ARRAY_SIZE(adaptive->y_mode[i]));
> +
> +		adaptive->y_mode_tail[i][0] = probs->y_mode[i][8];
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(adaptive->partition[0]); ++i) {
> +		memcpy(adaptive->partition[0][i], 
v4l2_vp9_kf_partition_probs[i],
> +		       sizeof(v4l2_vp9_kf_partition_probs[i]));
> +
> +		adaptive->partition[0][i][3] = 0;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(adaptive->partition[1]); ++i) {
> +		memcpy(adaptive->partition[1][i], probs->partition[i],
> +		       sizeof(probs->partition[i]));
> +
> +		adaptive->partition[1][i][3] = 0;
> +	}
> +
> +	memcpy(adaptive->interp_filter, probs->interp_filter,
> +	       sizeof(adaptive->interp_filter));
> +
> +	memcpy(adaptive->comp_mode, probs->comp_mode, sizeof(adaptive-
>comp_mode));
> +
> +	memcpy(adaptive->skip, probs->skip, sizeof(adaptive->skip));
> +
> +	mv = &adaptive->mv;
> +
> +	memcpy(mv->joint, probs->mv.joint, sizeof(mv->joint));
> +	memcpy(mv->sign, probs->mv.sign, sizeof(mv->sign));
> +	memcpy(mv->class0_bit, probs->mv.class0_bit, sizeof(mv-
>class0_bit));
> +	memcpy(mv->fr, probs->mv.fr, sizeof(mv->fr));
> +	memcpy(mv->class0_hp, probs->mv.class0_hp, sizeof(mv->class0_hp));
> +	memcpy(mv->hp, probs->mv.hp, sizeof(mv->hp));
> +	memcpy(mv->classes, probs->mv.classes, sizeof(mv->classes));
> +	memcpy(mv->class0_fr, probs->mv.class0_fr, sizeof(mv->class0_fr));
> +	memcpy(mv->bits, probs->mv.bits, sizeof(mv->bits));
> +
> +	memcpy(adaptive->single_ref, probs->single_ref, sizeof(adaptive-
>single_ref));
> +
> +	memcpy(adaptive->comp_ref, probs->comp_ref, sizeof(adaptive-
>comp_ref));
> +
> +	for (i = 0; i < ARRAY_SIZE(adaptive->coef); ++i)
> +		for (j = 0; j < ARRAY_SIZE(adaptive->coef[0]); ++j)
> +			for (k = 0; k < ARRAY_SIZE(adaptive->coef[0]
[0]); ++k)
> +				for (l = 0; l < 
ARRAY_SIZE(adaptive->coef[0][0][0]); ++l)
> +					INNER_LOOP;
> +
> +	hantro_write_addr(ctx->dev, VP9_ADDR_PROBS, misc->dma);
> +}
> +
> +static void config_counts(struct hantro_ctx *ctx)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
> +	struct hantro_aux_buf *misc = &vp9_dec->misc;
> +	dma_addr_t addr = misc->dma + vp9_dec->ctx_counters_offset;
> +
> +	hantro_write_addr(ctx->dev, VP9_ADDR_CTR, addr);
> +}
> +
> +static void config_seg_map(struct hantro_ctx *ctx,
> +			   const struct v4l2_ctrl_vp9_frame 
*dec_params,
> +			   bool intra_only, bool update_map)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	struct hantro_aux_buf *segment_map = &vp9_ctx->segment_map;
> +	dma_addr_t addr;
> +
> +	if (intra_only ||
> +	    (dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT)) {
> +		memset(segment_map->cpu, 0, segment_map->size);
> +		memset(vp9_ctx->feature_data, 0, sizeof(vp9_ctx-
>feature_data));
> +		memset(vp9_ctx->feature_enabled, 0, sizeof(vp9_ctx-
>feature_enabled));
> +	}
> +
> +	addr = segment_map->dma + vp9_ctx->active_segment * vp9_ctx-
>segment_map_size;
> +	hantro_write_addr(ctx->dev, VP9_ADDR_SEGMENT_READ, addr);
> +
> +	addr = segment_map->dma + (1 - vp9_ctx->active_segment) * vp9_ctx-
>segment_map_size;
> +	hantro_write_addr(ctx->dev, VP9_ADDR_SEGMENT_WRITE, addr);
> +
> +	if (update_map)
> +		vp9_ctx->active_segment = 1 - vp9_ctx->active_segment;
> +}
> +
> +static void
> +config_source(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame 
*dec_params,
> +	      struct vb2_v4l2_buffer *vb2_src)
> +{
> +	dma_addr_t stream_base, tmp_addr;
> +	unsigned int headres_size;
> +	u32 src_len, start_bit, src_buf_len;
> +
> +	headres_size = dec_params->uncompressed_header_size
> +		     + dec_params->compressed_header_size;
> +
> +	stream_base = vb2_dma_contig_plane_dma_addr(&vb2_src->vb2_buf, 0);
> +	hantro_write_addr(ctx->dev, G2_ADDR_STR, stream_base);
> +
> +	tmp_addr = stream_base + headres_size;
> +	start_bit = (tmp_addr & 0xf) * 8;
> +	hantro_reg_write(ctx->dev, &g2_start_bit, start_bit);
> +
> +	src_len = vb2_get_plane_payload(&vb2_src->vb2_buf, 0);
> +	src_len += start_bit / 8 - headres_size;
> +	hantro_reg_write(ctx->dev, &g2_stream_len, src_len);
> +
> +	tmp_addr &= ~0xf;
> +	hantro_reg_write(ctx->dev, &g2_strm_start_offset, tmp_addr - 
stream_base);
> +	src_buf_len = vb2_plane_size(&vb2_src->vb2_buf, 0);
> +	hantro_reg_write(ctx->dev, &g2_strm_buffer_len, src_buf_len);
> +}
> +
> +static void
> +config_registers(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame 
*dec_params,
> +		 struct vb2_v4l2_buffer *vb2_src, struct vb2_v4l2_buffer 
*vb2_dst)
> +{
> +	struct hantro_decoded_buffer *dst, *last, *mv_ref;
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	const struct v4l2_vp9_segmentation *seg;
> +	bool intra_only, resolution_change;
> +
> +	/* vp9 stuff */
> +	dst = vb2_to_hantro_decoded_buf(&vb2_dst->vb2_buf);
> +
> +	if (vp9_ctx->last.valid)
> +		last = get_ref_buf(ctx, &dst->base.vb, vp9_ctx-
>last.timestamp);
> +	else
> +		last = dst;
> +
> +	update_dec_buf_info(dst, dec_params);
> +	update_ctx_cur_info(vp9_ctx, dst, dec_params);
> +	seg = &dec_params->seg;
> +
> +	intra_only = !!(dec_params->flags &
> +			(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
> +			V4L2_VP9_FRAME_FLAG_INTRA_ONLY));
> +
> +	if (!intra_only &&
> +	    !(dec_params->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT) &&
> +	    vp9_ctx->last.valid)
> +		mv_ref = last;
> +	else
> +		mv_ref = dst;
> +
> +	resolution_change = dst->vp9.width != last->vp9.width ||
> +			    dst->vp9.height != last->vp9.height;
> +
> +	/* configure basic registers */
> +	hantro_reg_write(ctx->dev, &g2_mode, VP9_DEC_MODE);
> +	hantro_reg_write(ctx->dev, &g2_strm_swap, 0xf);
> +	hantro_reg_write(ctx->dev, &g2_dirmv_swap, 0xf);
> +	hantro_reg_write(ctx->dev, &g2_compress_swap, 0xf);
> +	hantro_reg_write(ctx->dev, &g2_buswidth, BUS_WIDTH_128);
> +	hantro_reg_write(ctx->dev, &g2_max_burst, 16);
> +	hantro_reg_write(ctx->dev, &g2_apf_threshold, 8);
> +	hantro_reg_write(ctx->dev, &g2_ref_compress_bypass, 1);
> +	hantro_reg_write(ctx->dev, &g2_clk_gate_e, 1);
> +	hantro_reg_write(ctx->dev, &g2_max_cb_size, 6);
> +	hantro_reg_write(ctx->dev, &g2_min_cb_size, 3);
> +
> +	config_output(ctx, dst, dec_params);
> +
> +	if (!intra_only)
> +		config_ref_registers(ctx, dec_params, dst, mv_ref);
> +
> +	config_tiles(ctx, dec_params, dst);
> +	config_segment(ctx, dec_params);
> +	config_loop_filter(ctx, dec_params);
> +	config_picture_dimensions(ctx, dst);
> +	config_bit_depth(ctx, dec_params);
> +	config_quant(ctx, dec_params);
> +	config_others(ctx, dec_params, intra_only, resolution_change);
> +	config_compound_reference(ctx, dec_params);
> +	config_probs(ctx, dec_params);
> +	config_counts(ctx);
> +	config_seg_map(ctx, dec_params, intra_only,
> +		       seg->flags & 
V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP);
> +	config_source(ctx, dec_params, vb2_src);
> +}
> +
> +int hantro_g2_vp9_dec_run(struct hantro_ctx *ctx)
> +{
> +	const struct v4l2_ctrl_vp9_frame *decode_params;
> +	struct vb2_v4l2_buffer *src;
> +	struct vb2_v4l2_buffer *dst;
> +	int ret;
> +
> +	hantro_g2_check_idle(ctx->dev);
> +
> +	ret = start_prepare_run(ctx, &decode_params);
> +	if (ret) {
> +		hantro_end_prepare_run(ctx);
> +		return ret;
> +	}
> +
> +	src = hantro_get_src_buf(ctx);
> +	dst = hantro_get_dst_buf(ctx);
> +
> +	config_registers(ctx, decode_params, src, dst);
> +
> +	hantro_end_prepare_run(ctx);
> +
> +	vdpu_write(ctx->dev, G2_REG_INTERRUPT_DEC_E, G2_REG_INTERRUPT);
> +
> +	return 0;
> +}
> +
> +#define copy_tx_and_skip(p1, p2)				\
> +do {								
\
> +	memcpy((p1)->tx8, (p2)->tx8, sizeof((p1)->tx8));	\
> +	memcpy((p1)->tx16, (p2)->tx16, sizeof((p1)->tx16));	\
> +	memcpy((p1)->tx32, (p2)->tx32, sizeof((p1)->tx32));	\
> +	memcpy((p1)->skip, (p2)->skip, sizeof((p1)->skip));	\
> +} while (0)
> +
> +void hantro_g2_vp9_dec_done(struct hantro_ctx *ctx)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	unsigned int fctx_idx;
> +
> +	if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX))
> +		goto out_update_last;
> +
> +	fctx_idx = vp9_ctx->cur.frame_context_idx;
> +
> +	if (!(vp9_ctx->cur.flags & V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE)) {
> +		/* error_resilient_mode == 0 && 
frame_parallel_decoding_mode == 0 */
> +		struct v4l2_vp9_frame_context *probs = &vp9_ctx-
>probability_tables;
> +		bool frame_is_intra = vp9_ctx->cur.flags &
> +		    (V4L2_VP9_FRAME_FLAG_KEY_FRAME | 
V4L2_VP9_FRAME_FLAG_INTRA_ONLY);
> +		struct tx_and_skip {
> +			u8 tx8[2][1];
> +			u8 tx16[2][2];
> +			u8 tx32[2][3];
> +			u8 skip[3];
> +		} _tx_skip, *tx_skip = &_tx_skip;
> +		struct v4l2_vp9_frame_symbol_counts *counts;
> +		struct symbol_counts *hantro_cnts;
> +		u32 tx16p[2][4];
> +		int i;
> +
> +		/* buffer the forward-updated TX and skip probs */
> +		if (frame_is_intra)
> +			copy_tx_and_skip(tx_skip, probs);
> +
> +		/* 6.1.2 refresh_probs(): load_probs() and load_probs2() 
*/
> +		*probs = vp9_ctx->frame_context[fctx_idx];
> +
> +		/* if FrameIsIntra then undo the effect of load_probs2() 
*/
> +		if (frame_is_intra)
> +			copy_tx_and_skip(probs, tx_skip);
> +
> +		counts = &vp9_ctx->cnts;
> +		hantro_cnts = vp9_ctx->misc.cpu + vp9_ctx-
>ctx_counters_offset;
> +		for (i = 0; i < ARRAY_SIZE(tx16p); ++i) {
> +			memcpy(tx16p[i],
> +			       hantro_cnts->tx16x16_count[i],
> +			       sizeof(hantro_cnts-
>tx16x16_count[0]));
> +			tx16p[i][3] = 0;
> +		}
> +		counts->tx16p = &tx16p;
> +
> +		v4l2_vp9_adapt_coef_probs(probs, counts,
> +					  !vp9_ctx->last.valid 
||
> +					  vp9_ctx->last.flags & 
V4L2_VP9_FRAME_FLAG_KEY_FRAME,
> +					  frame_is_intra);
> +
> +		if (!frame_is_intra) {
> +			/* load_probs2() already done */
> +			u32 mv_mode[7][4];
> +
> +			for (i = 0; i < ARRAY_SIZE(mv_mode); ++i) {
> +				mv_mode[i][0] = hantro_cnts-
>inter_mode_counts[i][1][0];
> +				mv_mode[i][1] = hantro_cnts-
>inter_mode_counts[i][2][0];
> +				mv_mode[i][2] = hantro_cnts-
>inter_mode_counts[i][0][0];
> +				mv_mode[i][3] = hantro_cnts-
>inter_mode_counts[i][2][1];
> +			}
> +			counts->mv_mode = &mv_mode;
> +			v4l2_vp9_adapt_noncoef_probs(&vp9_ctx-
>probability_tables, counts,
> +						     
vp9_ctx->cur.reference_mode,
> +						     
vp9_ctx->cur.interpolation_filter,
> +						     
vp9_ctx->cur.tx_mode, vp9_ctx->cur.flags);
> +		}
> +	}
> +
> +	vp9_ctx->frame_context[fctx_idx] = vp9_ctx->probability_tables;
> +
> +out_update_last:
> +	vp9_ctx->last = vp9_ctx->cur;
> +}
> diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/
media/hantro/hantro_hw.h
> index 42b3f3961f75..2961d399fd60 100644
> --- a/drivers/staging/media/hantro/hantro_hw.h
> +++ b/drivers/staging/media/hantro/hantro_hw.h
> @@ -12,6 +12,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/v4l2-controls.h>
>  #include <media/v4l2-ctrls.h>
> +#include <media/v4l2-vp9.h>
>  #include <media/videobuf2-core.h>
>  
>  #define DEC_8190_ALIGN_MASK	0x07U
> @@ -161,6 +162,50 @@ struct hantro_vp8_dec_hw_ctx {
>  	struct hantro_aux_buf prob_tbl;
>  };
>  
> +struct hantro_vp9_frame_info {
> +	u32 valid : 1;
> +	u32 frame_context_idx : 2;
> +	u32 reference_mode : 2;
> +	u32 tx_mode : 3;
> +	u32 interpolation_filter : 3;
> +	u32 flags;
> +	u64 timestamp;
> +};
> +
> +#define MAX_SB_COLS	64
> +#define MAX_SB_ROWS	34
> +
> +/**
> + * struct hantro_vp9_dec_hw_ctx
> + *
> + */
> +struct hantro_vp9_dec_hw_ctx {
> +	struct hantro_aux_buf tile_edge;
> +	struct hantro_aux_buf segment_map;
> +	struct hantro_aux_buf misc;
> +	struct v4l2_vp9_frame_symbol_counts cnts;
> +	struct v4l2_vp9_frame_context probability_tables;
> +	struct v4l2_vp9_frame_context frame_context[4];
> +	struct hantro_vp9_frame_info cur;
> +	struct hantro_vp9_frame_info last;
> +
> +	unsigned int bsd_ctrl_offset;
> +	unsigned int segment_map_size;
> +	unsigned int ctx_counters_offset;
> +	unsigned int tile_info_offset;
> +
> +	unsigned short tile_r_info[MAX_SB_ROWS];
> +	unsigned short tile_c_info[MAX_SB_COLS];
> +	unsigned int last_tile_r;
> +	unsigned int last_tile_c;
> +	unsigned int last_sbs_r;
> +	unsigned int last_sbs_c;
> +
> +	unsigned int active_segment;
> +	u8 feature_enabled[8];
> +	s16 feature_data[8][4];
> +};
> +
>  /**
>   * struct hantro_postproc_ctx
>   *
> @@ -267,6 +312,24 @@ void hantro_hevc_ref_remove_unused(struct hantro_ctx 
*ctx);
>  size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps);
>  size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps 
*sps);
>  
> +static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
> +{
> +	return (dimension + 63) / 64;
> +}
> +
> +static inline size_t
> +hantro_vp9_mv_size(unsigned int width, unsigned int height)
> +{
> +	int num_ctbs;
> +
> +	/*
> +	 * There can be up to (CTBs x 64) number of blocks,
> +	 * and the motion vector for each block needs 16 bytes.
> +	 */
> +	num_ctbs = hantro_vp9_num_sbs(width) * hantro_vp9_num_sbs(height);
> +	return (num_ctbs * 64) * 16;
> +}
> +
>  static inline size_t
>  hantro_h264_mv_size(unsigned int width, unsigned int height)
>  {
> @@ -308,6 +371,10 @@ void hantro_vp8_dec_exit(struct hantro_ctx *ctx);
>  void hantro_vp8_prob_update(struct hantro_ctx *ctx,
>  			    const struct v4l2_ctrl_vp8_frame *hdr);
>  
> +int hantro_g2_vp9_dec_run(struct hantro_ctx *ctx);
> +void hantro_g2_vp9_dec_done(struct hantro_ctx *ctx);
> +int hantro_vp9_dec_init(struct hantro_ctx *ctx);
> +void hantro_vp9_dec_exit(struct hantro_ctx *ctx);
>  void hantro_g2_check_idle(struct hantro_dev *vpu);
>  
>  #endif /* HANTRO_HW_H_ */
> diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/
media/hantro/hantro_v4l2.c
> index d1f060c55fed..e4b0645ba6fc 100644
> --- a/drivers/staging/media/hantro/hantro_v4l2.c
> +++ b/drivers/staging/media/hantro/hantro_v4l2.c
> @@ -299,6 +299,11 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
>  			pix_mp->plane_fmt[0].sizeimage +=
>  				hantro_h264_mv_size(pix_mp-
>width,
>  						    pix_mp-
>height);
> +		else if (ctx->vpu_src_fmt->fourcc == 
V4L2_PIX_FMT_VP9_FRAME &&
> +			 !hantro_needs_postproc(ctx, fmt))
> +			pix_mp->plane_fmt[0].sizeimage +=
> +				hantro_vp9_mv_size(pix_mp->width,
> +						   pix_mp-
>height);
>  	} else if (!pix_mp->plane_fmt[0].sizeimage) {
>  		/*
>  		 * For coded formats the application can specify
> @@ -407,6 +412,7 @@ hantro_update_requires_request(struct hantro_ctx *ctx, 
u32 fourcc)
>  	case V4L2_PIX_FMT_VP8_FRAME:
>  	case V4L2_PIX_FMT_H264_SLICE:
>  	case V4L2_PIX_FMT_HEVC_SLICE:
> +	case V4L2_PIX_FMT_VP9_FRAME:
>  		ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true;
>  		break;
>  	default:
> diff --git a/drivers/staging/media/hantro/hantro_vp9.c b/drivers/staging/
media/hantro/hantro_vp9.c
> new file mode 100644
> index 000000000000..566cd376c097
> --- /dev/null
> +++ b/drivers/staging/media/hantro/hantro_vp9.c
> @@ -0,0 +1,240 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Hantro VP9 codec driver
> + *
> + * Copyright (C) 2021 Collabora Ltd.
> + */
> +
> +#include <linux/types.h>
> +#include <media/v4l2-mem2mem.h>
> +
> +#include "hantro.h"
> +#include "hantro_hw.h"
> +#include "hantro_vp9.h"
> +
> +#define POW2(x) (1 << (x))
> +
> +#define MAX_LOG2_TILE_COLUMNS 6
> +#define MAX_NUM_TILE_COLS POW2(MAX_LOG2_TILE_COLUMNS)
> +#define MAX_TILE_COLS 20
> +#define MAX_TILE_ROWS 22
> +
> +static size_t hantro_vp9_tile_filter_size(unsigned int height)
> +{
> +	u32 h, height32, size;
> +
> +	h = roundup(height, 8);
> +
> +	height32 = roundup(h, 64);
> +	size = 24 * height32 * (MAX_NUM_TILE_COLS - 1); /* luma: 8, chroma: 
8 + 8 */
> +
> +	return size;
> +}
> +
> +static size_t hantro_vp9_bsd_control_size(unsigned int height)
> +{
> +	u32 h, height32;
> +
> +	h = roundup(height, 8);
> +	height32 = roundup(h, 64);
> +
> +	return 16 * (height32 / 4) * (MAX_NUM_TILE_COLS - 1);
> +}
> +
> +static size_t hantro_vp9_segment_map_size(unsigned int width, unsigned int 
height)
> +{
> +	u32 w, h;
> +	int num_ctbs;
> +
> +	w = roundup(width, 8);
> +	h = roundup(height, 8);
> +	num_ctbs = ((w + 63) / 64) * ((h + 63) / 64);
> +
> +	return num_ctbs * 32;
> +}
> +
> +static inline size_t hantro_vp9_prob_tab_size(void)
> +{
> +	return roundup(sizeof(struct hantro_g2_all_probs), 16);
> +}
> +
> +static inline size_t hantro_vp9_count_tab_size(void)
> +{
> +	return roundup(sizeof(struct symbol_counts), 16);
> +}
> +
> +static inline size_t hantro_vp9_tile_info_size(void)
> +{
> +	return roundup((MAX_TILE_COLS * MAX_TILE_ROWS * 4 * sizeof(u16) + 
15 + 16) & ~0xf, 16);
> +}
> +
> +static void *get_coeffs_arr(struct symbol_counts *cnts, int i, int j, int k, 
int l, int m)
> +{
> +	if (i == 0)
> +		return &cnts->count_coeffs[j][k][l][m];
> +
> +	if (i == 1)
> +		return &cnts->count_coeffs8x8[j][k][l][m];
> +
> +	if (i == 2)
> +		return &cnts->count_coeffs16x16[j][k][l][m];
> +
> +	if (i == 3)
> +		return &cnts->count_coeffs32x32[j][k][l][m];
> +
> +	return NULL;
> +}
> +
> +static void *get_eobs1(struct symbol_counts *cnts, int i, int j, int k, int 
l, int m)
> +{
> +	if (i == 0)
> +		return &cnts->count_coeffs[j][k][l][m][3];
> +
> +	if (i == 1)
> +		return &cnts->count_coeffs8x8[j][k][l][m][3];
> +
> +	if (i == 2)
> +		return &cnts->count_coeffs16x16[j][k][l][m][3];
> +
> +	if (i == 3)
> +		return &cnts->count_coeffs32x32[j][k][l][m][3];
> +
> +	return NULL;
> +}
> +
> +#define INNER_LOOP \
> +	do {							
			\
> +		for (m = 0; m < ARRAY_SIZE(vp9_ctx->cnts.coeff[i][0][0]
[0]); ++m) {	\
> +			vp9_ctx->cnts.coeff[i][j][k][l][m] =		
		\
> +				get_coeffs_arr(cnts, i, j, k, l, 
m);			\
> +			vp9_ctx->cnts.eob[i][j][k][l][m][0] =		
		\
> +				&cnts->count_eobs[i][j][k][l][m];	
		\
> +			vp9_ctx->cnts.eob[i][j][k][l][m][1] =		
		\
> +				get_eobs1(cnts, i, j, k, l, m);	
			\
> +		}						
			\
> +	} while (0)
> +
> +static void init_v4l2_vp9_count_tbl(struct hantro_ctx *ctx)
> +{
> +	struct hantro_vp9_dec_hw_ctx *vp9_ctx = &ctx->vp9_dec;
> +	struct symbol_counts *cnts = vp9_ctx->misc.cpu + vp9_ctx-
>ctx_counters_offset;
> +	int i, j, k, l, m;
> +
> +	vp9_ctx->cnts.partition = &cnts->partition_counts;
> +	vp9_ctx->cnts.skip = &cnts->mbskip_count;
> +	vp9_ctx->cnts.intra_inter = &cnts->intra_inter_count;
> +	vp9_ctx->cnts.tx32p = &cnts->tx32x32_count;
> +	/*
> +	 * g2 hardware uses tx16x16_count[2][3], while the api
> +	 * expects tx16p[2][4], so this must be explicitly copied
> +	 * into vp9_ctx->cnts.tx16p when passing the data to the
> +	 * vp9 library function
> +	 */
> +	vp9_ctx->cnts.tx8p = &cnts->tx8x8_count;
> +
> +	vp9_ctx->cnts.y_mode = &cnts->sb_ymode_counts;
> +	vp9_ctx->cnts.uv_mode = &cnts->uv_mode_counts;
> +	vp9_ctx->cnts.comp = &cnts->comp_inter_count;
> +	vp9_ctx->cnts.comp_ref = &cnts->comp_ref_count;
> +	vp9_ctx->cnts.single_ref = &cnts->single_ref_count;
> +	vp9_ctx->cnts.filter = &cnts->switchable_interp_counts;
> +	vp9_ctx->cnts.mv_joint = &cnts->mv_counts.joints;
> +	vp9_ctx->cnts.sign = &cnts->mv_counts.sign;
> +	vp9_ctx->cnts.classes = &cnts->mv_counts.classes;
> +	vp9_ctx->cnts.class0 = &cnts->mv_counts.class0;
> +	vp9_ctx->cnts.bits = &cnts->mv_counts.bits;
> +	vp9_ctx->cnts.class0_fp = &cnts->mv_counts.class0_fp;
> +	vp9_ctx->cnts.fp = &cnts->mv_counts.fp;
> +	vp9_ctx->cnts.class0_hp = &cnts->mv_counts.class0_hp;
> +	vp9_ctx->cnts.hp = &cnts->mv_counts.hp;
> +
> +	for (i = 0; i < ARRAY_SIZE(vp9_ctx->cnts.coeff); ++i)
> +		for (j = 0; j < ARRAY_SIZE(vp9_ctx->cnts.coeff[i]); ++j)
> +			for (k = 0; k < ARRAY_SIZE(vp9_ctx-
>cnts.coeff[i][0]); ++k)
> +				for (l = 0; l < 
ARRAY_SIZE(vp9_ctx->cnts.coeff[i][0][0]); ++l)
> +					INNER_LOOP;
> +}
> +
> +int hantro_vp9_dec_init(struct hantro_ctx *ctx)
> +{
> +	struct hantro_dev *vpu = ctx->dev;
> +	const struct hantro_variant *variant = vpu->variant;
> +	struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
> +	struct hantro_aux_buf *tile_edge = &vp9_dec->tile_edge;
> +	struct hantro_aux_buf *segment_map = &vp9_dec->segment_map;
> +	struct hantro_aux_buf *misc = &vp9_dec->misc;
> +	u32 i, max_width, max_height, size;
> +
> +	if (variant->num_dec_fmts < 1)
> +		return -EINVAL;
> +
> +	for (i = 0; i < variant->num_dec_fmts; ++i)
> +		if (variant->dec_fmts[i].fourcc == 
V4L2_PIX_FMT_VP9_FRAME)
> +			break;
> +
> +	if (i == variant->num_dec_fmts)
> +		return -EINVAL;
> +
> +	max_width = vpu->variant->dec_fmts[i].frmsize.max_width;
> +	max_height = vpu->variant->dec_fmts[i].frmsize.max_height;
> +
> +	size = hantro_vp9_tile_filter_size(max_height);
> +	vp9_dec->bsd_ctrl_offset = size;
> +	size += hantro_vp9_bsd_control_size(max_height);
> +
> +	tile_edge->cpu = dma_alloc_coherent(vpu->dev, size, &tile_edge-
>dma, GFP_KERNEL);
> +	if (!tile_edge->cpu)
> +		return -ENOMEM;
> +
> +	tile_edge->size = size;
> +	memset(tile_edge->cpu, 0, size);
> +
> +	size = hantro_vp9_segment_map_size(max_width, max_height);
> +	vp9_dec->segment_map_size = size;
> +	size *= 2; /* we need two areas of this size, used alternately */
> +
> +	segment_map->cpu = dma_alloc_coherent(vpu->dev, size, &segment_map-
>dma, GFP_KERNEL);
> +	if (!segment_map->cpu)
> +		goto err_segment_map;
> +
> +	segment_map->size = size;
> +	memset(segment_map->cpu, 0, size);
> +
> +	size = hantro_vp9_prob_tab_size();
> +	vp9_dec->ctx_counters_offset = size;
> +	size += hantro_vp9_count_tab_size();
> +	vp9_dec->tile_info_offset = size;
> +	size += hantro_vp9_tile_info_size();
> +
> +	misc->cpu = dma_alloc_coherent(vpu->dev, size, &misc->dma, 
GFP_KERNEL);
> +	if (!misc->cpu)
> +		goto err_misc;
> +
> +	misc->size = size;
> +	memset(misc->cpu, 0, size);
> +
> +	init_v4l2_vp9_count_tbl(ctx);
> +
> +	return 0;
> +
> +err_misc:
> +	dma_free_coherent(vpu->dev, segment_map->size, segment_map->cpu, 
segment_map->dma);
> +
> +err_segment_map:
> +	dma_free_coherent(vpu->dev, tile_edge->size, tile_edge->cpu, 
tile_edge->dma);
> +
> +	return -ENOMEM;
> +}
> +
> +void hantro_vp9_dec_exit(struct hantro_ctx *ctx)
> +{
> +	struct hantro_dev *vpu = ctx->dev;
> +	struct hantro_vp9_dec_hw_ctx *vp9_dec = &ctx->vp9_dec;
> +	struct hantro_aux_buf *tile_edge = &vp9_dec->tile_edge;
> +	struct hantro_aux_buf *segment_map = &vp9_dec->segment_map;
> +	struct hantro_aux_buf *misc = &vp9_dec->misc;
> +
> +	dma_free_coherent(vpu->dev, misc->size, misc->cpu, misc->dma);
> +	dma_free_coherent(vpu->dev, segment_map->size, segment_map->cpu, 
segment_map->dma);
> +	dma_free_coherent(vpu->dev, tile_edge->size, tile_edge->cpu, 
tile_edge->dma);
> +}
> diff --git a/drivers/staging/media/hantro/hantro_vp9.h b/drivers/staging/
media/hantro/hantro_vp9.h
> new file mode 100644
> index 000000000000..c7f4bd3ff8dd
> --- /dev/null
> +++ b/drivers/staging/media/hantro/hantro_vp9.h
> @@ -0,0 +1,103 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Hantro VP9 codec driver
> + *
> + * Copyright (C) 2021 Collabora Ltd.
> + */
> +
> +struct hantro_g2_mv_probs {
> +	u8 joint[3];
> +	u8 sign[2];
> +	u8 class0_bit[2][1];
> +	u8 fr[2][3];
> +	u8 class0_hp[2];
> +	u8 hp[2];
> +	u8 classes[2][10];
> +	u8 class0_fr[2][2][3];
> +	u8 bits[2][10];
> +};
> +
> +struct hantro_g2_probs {
> +	u8 inter_mode[7][4];
> +	u8 is_inter[4];
> +	u8 uv_mode[10][8];
> +	u8 tx8[2][1];
> +	u8 tx16[2][2];
> +	u8 tx32[2][3];
> +	u8 y_mode_tail[4][1];
> +	u8 y_mode[4][8];
> +	u8 partition[2][16][4]; /* [keyframe][][], [inter][][] */
> +	u8 uv_mode_tail[10][1];
> +	u8 interp_filter[4][2];
> +	u8 comp_mode[5];
> +	u8 skip[3];
> +
> +	u8 pad1[1];
> +
> +	struct hantro_g2_mv_probs mv;
> +
> +	u8 single_ref[5][2];
> +	u8 comp_ref[5];
> +
> +	u8 pad2[17];
> +
> +	u8 coef[4][2][2][6][6][4];
> +};
> +
> +struct hantro_g2_all_probs {
> +	u8 kf_y_mode_prob[10][10][8];
> +
> +	u8 kf_y_mode_prob_tail[10][10][1];
> +	u8 ref_pred_probs[3];
> +	u8 mb_segment_tree_probs[7];
> +	u8 segment_pred_probs[3];
> +	u8 ref_scores[4];
> +	u8 prob_comppred[2];
> +
> +	u8 pad1[9];
> +
> +	u8 kf_uv_mode_prob[10][8];
> +	u8 kf_uv_mode_prob_tail[10][1];
> +
> +	u8 pad2[6];
> +
> +	struct hantro_g2_probs probs;
> +};
> +
> +struct mv_counts {
> +	u32 joints[4];
> +	u32 sign[2][2];
> +	u32 classes[2][11];
> +	u32 class0[2][2];
> +	u32 bits[2][10][2];
> +	u32 class0_fp[2][2][4];
> +	u32 fp[2][4];
> +	u32 class0_hp[2][2];
> +	u32 hp[2][2];
> +};
> +
> +struct symbol_counts {
> +	u32 inter_mode_counts[7][3][2];
> +	u32 sb_ymode_counts[4][10];
> +	u32 uv_mode_counts[10][10];
> +	u32 partition_counts[16][4];
> +	u32 switchable_interp_counts[4][3];
> +	u32 intra_inter_count[4][2];
> +	u32 comp_inter_count[5][2];
> +	u32 single_ref_count[5][2][2];
> +	u32 comp_ref_count[5][2];
> +	u32 tx32x32_count[2][4];
> +	u32 tx16x16_count[2][3];
> +	u32 tx8x8_count[2][2];
> +	u32 mbskip_count[3][2];
> +
> +	struct mv_counts mv_counts;
> +
> +	u32 count_coeffs[2][2][6][6][4];
> +	u32 count_coeffs8x8[2][2][6][6][4];
> +	u32 count_coeffs16x16[2][2][6][6][4];
> +	u32 count_coeffs32x32[2][2][6][6][4];
> +
> +	u32 count_eobs[4][2][2][6][6];
> +};
> +
> diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/
media/hantro/imx8m_vpu_hw.c
> index a40b161e5956..455a107ffb02 100644
> --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
> +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
> @@ -150,6 +150,19 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] 
= {
>  			.step_height = MB_DIM,
>  		},
>  	},
> +	{
> +		.fourcc = V4L2_PIX_FMT_VP9_FRAME,
> +		.codec_mode = HANTRO_MODE_VP9_DEC,
> +		.max_depth = 2,
> +		.frmsize = {
> +			.min_width = 48,
> +			.max_width = 3840,
> +			.step_width = MB_DIM,
> +			.min_height = 48,
> +			.max_height = 2160,
> +			.step_height = MB_DIM,
> +		},
> +	},
>  };
>  
>  static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)
> @@ -241,6 +254,13 @@ static const struct hantro_codec_ops 
imx8mq_vpu_g2_codec_ops[] = {
>  		.init = hantro_hevc_dec_init,
>  		.exit = hantro_hevc_dec_exit,
>  	},
> +	[HANTRO_MODE_VP9_DEC] = {
> +		.run = hantro_g2_vp9_dec_run,
> +		.done = hantro_g2_vp9_dec_done,
> +		.reset = imx8m_vpu_g2_reset,
> +		.init = hantro_vp9_dec_init,
> +		.exit = hantro_vp9_dec_exit,
> +	},
>  };
>  
>  /*
> @@ -281,7 +301,7 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
>  	.dec_offset = 0x0,
>  	.dec_fmts = imx8m_vpu_g2_dec_fmts,
>  	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts),
> -	.codec = HANTRO_HEVC_DECODER,
> +	.codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,
>  	.codec_ops = imx8mq_vpu_g2_codec_ops,
>  	.init = imx8mq_vpu_hw_init,
>  	.runtime_resume = imx8mq_runtime_resume,
> -- 
> 2.17.1
> 
> 




From robdclark at gmail.com  Mon Aug  9 10:18:21 2021
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 9 Aug 2021 10:18:21 -0700
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent masters
 to use system cache
In-Reply-To: <20210809170508.GB1589@willie-the-truck>
References: <cover.1610372717.git.saiprakash.ranjan@codeaurora.org>
 <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
 <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
 <20210809145651.GC1458@willie-the-truck>
 <CAF6AEGsSUojA=V0n2iRWTCn++buqN=Eoxo0r3=+=PBu1O=H-AQ@mail.gmail.com>
 <20210809170508.GB1589@willie-the-truck>
Message-ID: <CAF6AEGtmZ3LzAJdtnKDQDbEN-a6_JgdN-fZ96pkU3dZqkiW91g@mail.gmail.com>

On Mon, Aug 9, 2021 at 10:05 AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Aug 09, 2021 at 09:57:08AM -0700, Rob Clark wrote:
> > On Mon, Aug 9, 2021 at 7:56 AM Will Deacon <will at kernel.org> wrote:
> > > On Mon, Aug 02, 2021 at 06:36:04PM -0700, Rob Clark wrote:
> > > > On Mon, Aug 2, 2021 at 8:14 AM Will Deacon <will at kernel.org> wrote:
> > > > > On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> > > > > > On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> > > > > > > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> > > > > > > > On 2021-07-28 19:30, Georgi Djakov wrote:
> > > > > > > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > > > > > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > > > > > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > > > > > > > > the memory type setting required for the non-coherent masters to use
> > > > > > > > > > system cache. Now that system cache support for GPU is added, we will
> > > > > > > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > > > > > > > > Without this, the system cache lines are not allocated for GPU.
> > > > > > > > > >
> > > > > > > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > > > > > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > > > > > > > > and makes GPU the user of this protection flag.
> > > > > > > > >
> > > > > > > > > Thank you for the patchset! Are you planning to refresh it, as it does
> > > > > > > > > not apply anymore?
> > > > > > > > >
> > > > > > > >
> > > > > > > > I was waiting on Will's reply [1]. If there are no changes needed, then
> > > > > > > > I can repost the patch.
> > > > > > >
> > > > > > > I still think you need to handle the mismatched alias, no? You're adding
> > > > > > > a new memory type to the SMMU which doesn't exist on the CPU side. That
> > > > > > > can't be right.
> > > > > > >
> > > > > >
> > > > > > Just curious, and maybe this is a dumb question, but what is your
> > > > > > concern about mismatched aliases?  I mean the cache hierarchy on the
> > > > > > GPU device side (anything beyond the LLC) is pretty different and
> > > > > > doesn't really care about the smmu pgtable attributes..
> > > > >
> > > > > If the CPU accesses a shared buffer with different attributes to those which
> > > > > the device is using then you fall into the "mismatched memory attributes"
> > > > > part of the Arm architecture. It's reasonably unforgiving (you should go and
> > > > > read it) and in some cases can apply to speculative accesses as well, but
> > > > > the end result is typically loss of coherency.
> > > >
> > > > Ok, I might have a few other sections to read first to decipher the
> > > > terminology..
> > > >
> > > > But my understanding of LLC is that it looks just like system memory
> > > > to the CPU and GPU (I think that would make it "the point of
> > > > coherence" between the GPU and CPU?)  If that is true, shouldn't it be
> > > > invisible from the point of view of different CPU mapping options?
> > >
> > > You could certainly build a system where mismatched attributes don't cause
> > > loss of coherence, but as it's not guaranteed by the architecture and the
> > > changes proposed here affect APIs which are exposed across SoCs, then I
> > > don't think it helps much.
> > >
> >
> > Hmm, the description of the new mapping flag is that it applies only
> > to transparent outer level cache:
> >
> > +/*
> > + * Non-coherent masters can use this page protection flag to set cacheable
> > + * memory attributes for only a transparent outer level of cache, also known as
> > + * the last-level or system cache.
> > + */
> > +#define IOMMU_LLC      (1 << 6)
> >
> > But I suppose we could call it instead IOMMU_QCOM_LLC or something
> > like that to make it more clear that it is not necessarily something
> > that would work with a different outer level cache implementation?
>
> ... or we could just deal with the problem so that other people can reuse
> the code. I haven't really understood the reluctance to solve this properly.
>
> Am I missing some reason this isn't solvable?
>

Oh, was there another way to solve it (other than foregoing setting
INC_OCACHE in the pgtables)?  Maybe I misunderstood, is there a
corresponding setting on the MMU pgtables side of things?

BR,
-R


From will at kernel.org  Mon Aug  9 10:40:23 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 9 Aug 2021 18:40:23 +0100
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent
 masters to use system cache
In-Reply-To: <CAF6AEGtmZ3LzAJdtnKDQDbEN-a6_JgdN-fZ96pkU3dZqkiW91g@mail.gmail.com>
References: <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
 <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
 <20210809145651.GC1458@willie-the-truck>
 <CAF6AEGsSUojA=V0n2iRWTCn++buqN=Eoxo0r3=+=PBu1O=H-AQ@mail.gmail.com>
 <20210809170508.GB1589@willie-the-truck>
 <CAF6AEGtmZ3LzAJdtnKDQDbEN-a6_JgdN-fZ96pkU3dZqkiW91g@mail.gmail.com>
Message-ID: <20210809174022.GA1840@willie-the-truck>

On Mon, Aug 09, 2021 at 10:18:21AM -0700, Rob Clark wrote:
> On Mon, Aug 9, 2021 at 10:05 AM Will Deacon <will at kernel.org> wrote:
> >
> > On Mon, Aug 09, 2021 at 09:57:08AM -0700, Rob Clark wrote:
> > > On Mon, Aug 9, 2021 at 7:56 AM Will Deacon <will at kernel.org> wrote:
> > > > On Mon, Aug 02, 2021 at 06:36:04PM -0700, Rob Clark wrote:
> > > > > On Mon, Aug 2, 2021 at 8:14 AM Will Deacon <will at kernel.org> wrote:
> > > > > > On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> > > > > > > On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> > > > > > > > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> > > > > > > > > On 2021-07-28 19:30, Georgi Djakov wrote:
> > > > > > > > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> > > > > > > > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> > > > > > > > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> > > > > > > > > > > the memory type setting required for the non-coherent masters to use
> > > > > > > > > > > system cache. Now that system cache support for GPU is added, we will
> > > > > > > > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> > > > > > > > > > > Without this, the system cache lines are not allocated for GPU.
> > > > > > > > > > >
> > > > > > > > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> > > > > > > > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> > > > > > > > > > > and makes GPU the user of this protection flag.
> > > > > > > > > >
> > > > > > > > > > Thank you for the patchset! Are you planning to refresh it, as it does
> > > > > > > > > > not apply anymore?
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > I was waiting on Will's reply [1]. If there are no changes needed, then
> > > > > > > > > I can repost the patch.
> > > > > > > >
> > > > > > > > I still think you need to handle the mismatched alias, no? You're adding
> > > > > > > > a new memory type to the SMMU which doesn't exist on the CPU side. That
> > > > > > > > can't be right.
> > > > > > > >
> > > > > > >
> > > > > > > Just curious, and maybe this is a dumb question, but what is your
> > > > > > > concern about mismatched aliases?  I mean the cache hierarchy on the
> > > > > > > GPU device side (anything beyond the LLC) is pretty different and
> > > > > > > doesn't really care about the smmu pgtable attributes..
> > > > > >
> > > > > > If the CPU accesses a shared buffer with different attributes to those which
> > > > > > the device is using then you fall into the "mismatched memory attributes"
> > > > > > part of the Arm architecture. It's reasonably unforgiving (you should go and
> > > > > > read it) and in some cases can apply to speculative accesses as well, but
> > > > > > the end result is typically loss of coherency.
> > > > >
> > > > > Ok, I might have a few other sections to read first to decipher the
> > > > > terminology..
> > > > >
> > > > > But my understanding of LLC is that it looks just like system memory
> > > > > to the CPU and GPU (I think that would make it "the point of
> > > > > coherence" between the GPU and CPU?)  If that is true, shouldn't it be
> > > > > invisible from the point of view of different CPU mapping options?
> > > >
> > > > You could certainly build a system where mismatched attributes don't cause
> > > > loss of coherence, but as it's not guaranteed by the architecture and the
> > > > changes proposed here affect APIs which are exposed across SoCs, then I
> > > > don't think it helps much.
> > > >
> > >
> > > Hmm, the description of the new mapping flag is that it applies only
> > > to transparent outer level cache:
> > >
> > > +/*
> > > + * Non-coherent masters can use this page protection flag to set cacheable
> > > + * memory attributes for only a transparent outer level of cache, also known as
> > > + * the last-level or system cache.
> > > + */
> > > +#define IOMMU_LLC      (1 << 6)
> > >
> > > But I suppose we could call it instead IOMMU_QCOM_LLC or something
> > > like that to make it more clear that it is not necessarily something
> > > that would work with a different outer level cache implementation?
> >
> > ... or we could just deal with the problem so that other people can reuse
> > the code. I haven't really understood the reluctance to solve this properly.
> >
> > Am I missing some reason this isn't solvable?
> 
> Oh, was there another way to solve it (other than foregoing setting
> INC_OCACHE in the pgtables)?  Maybe I misunderstood, is there a
> corresponding setting on the MMU pgtables side of things?

Right -- we just need to program the CPU's MMU with the matching memory
attributes! It's a bit more fiddly if you're just using ioremap_wc()
though, as it's usually the DMA API which handles the attributes under the
hood.

Anyway, sorry, I should've said that explicitly earlier on. We've done this
sort of thing in the Android tree so I assumed Sai knew what needed to be
done and then I didn't think to explain to you :(

Will


From helgaas at kernel.org  Mon Aug  9 10:42:44 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 9 Aug 2021 12:42:44 -0500
Subject: [PATCH 2/3] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <51a11c89-d49b-7367-a75c-13016a2ea5d9@arm.com>
Message-ID: <20210809174244.GA2167737@bjorn-Precision-5520>

On Fri, Aug 06, 2021 at 09:55:27PM -0500, Jeremy Linton wrote:
> Hi,
> 
> On 8/6/21 5:21 PM, Bjorn Helgaas wrote:
> > On Thu, Aug 05, 2021 at 04:11:59PM -0500, Jeremy Linton wrote:
> > > The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
> > > standard because its PCIe config space isn't ECAM compliant and is
> > > split into two parts. One part for the root port registers and a
> > > moveable window which points at a given device's 4K config space.
> > > Thus it doesn't have a MCFG (and really any MCFG provided would be
> > > nonsense anyway). As Linux doesn't support the PCIe SMCCC standard
> > > we key off a Linux specific host bridge _DSD to add custom ECAM
> > > ops and cfgres. The cfg op selects between those two regions, as
> > > well as disallowing problematic accesses, particularly if the link
> > > is down because there isn't an attached device.
> > 
> > I'm not sure SMCCC is *really* relevant here.  If it is, an expansion
> > of the acronym and a link to a spec would be helpful.
> > 
> > But AFAICT the only important thing here is that it doesn't have
> > standard ECAM, and we're going to work around that.
> 
> I will reword it a bit.
> 
> > I don't see anything about _DSD in this series.
> 
> That is the "linux,pci-quirk" in the next patch.

The next patch doesn't mention _DSD either.  Is it obfuscated by
being inside fwnode_property_read_string()?  If so, it's well and
truly hidden; I gave up trying to connect that with ACPI.

Bjorn


From sboyd at kernel.org  Mon Aug  9 10:55:09 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 09 Aug 2021 10:55:09 -0700
Subject: [PATCH v10 3/5] spmi: mediatek: Add support for MT6873/8192
In-Reply-To: <1627972461-2627-4-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
 <1627972461-2627-4-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <162853170949.1975443.12492156194100139076@swboyd.mtv.corp.google.com>

Quoting Hsin-Hsiung Wang (2021-08-02 23:34:19)
> diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
> new file mode 100644
> index 000000000000..94c45d46ab0c
> --- /dev/null
> +++ b/drivers/spmi/spmi-mtk-pmif.c
> @@ -0,0 +1,465 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Copyright (c) 2021 MediaTek Inc.
> +
> +#include <linux/clk.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>

include platform_device.h for the platform device driver that this is.

> +#include <linux/spmi.h>
> +
> +#define SWINF_IDLE     0x00
> +#define SWINF_WFVLDCLR 0x06
> +
> +#define GET_SWINF(x)   (((x) >> 1) & 0x7)
> +
> +#define PMIF_CMD_REG_0         0
> +#define PMIF_CMD_REG           1
> +#define PMIF_CMD_EXT_REG       2
> +#define PMIF_CMD_EXT_REG_LONG  3
> +
> +#define PMIF_DELAY_US   10
> +#define PMIF_TIMEOUT_US (10 * 1000)
> +
> +#define PMIF_CHAN_OFFSET 0x5
> +
> +#define PMIF_MAX_CLKS  3
> +
> +#define SPMI_OP_ST_BUSY 1
> +
> +struct ch_reg {
> +       u32 ch_sta;
> +       u32 wdata;
> +       u32 rdata;
> +       u32 ch_send;
> +       u32 ch_rdy;
> +};
> +
> +struct pmif_data {
> +       const u32       *regs;
> +       const u32       *spmimst_regs;
> +       u32     soc_chan;
> +};
> +
> +struct pmif {
> +       void __iomem    *base;
> +       void __iomem    *spmimst_base;
> +       struct ch_reg   chan;
> +       struct clk_bulk_data clks[PMIF_MAX_CLKS];
> +       u32 nclks;

size_t? Surely 32-bits isn't important.

> +       const struct pmif_data *data;
> +};
> +
> +static const char * const pmif_clock_names[] = {
> +       "pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux",
> +};
[...]
> +
> +static bool pmif_is_fsm_vldclr(struct pmif *arb)
> +{
> +       u32 reg_rdata;
> +
> +       reg_rdata = pmif_readl(arb, arb->chan.ch_sta);

Newline here please.

> +       return GET_SWINF(reg_rdata) == SWINF_WFVLDCLR;
> +}
> +
> +static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
> +{
> +       struct pmif *arb = spmi_controller_get_drvdata(ctrl);
> +       u32 rdata, cmd;
> +       int ret;
> +
> +       /* Check the opcode */
> +       if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
> +               return -EINVAL;
> +
> +       cmd = opc - SPMI_CMD_RESET;
> +
> +       mtk_spmi_writel(arb, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL);
> +       ret = readl_poll_timeout_atomic(arb->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA],
> +                                       rdata, (rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY,
> +                                       PMIF_DELAY_US, PMIF_TIMEOUT_US);
> +       if (ret < 0)
> +               dev_err(&ctrl->dev, "timeout, err = %d\n", ret);
> +
> +       return ret;
> +}
> +
> +static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
> +                             u16 addr, u8 *buf, size_t len)
> +{
> +       struct pmif *arb = spmi_controller_get_drvdata(ctrl);
> +       struct ch_reg *inf_reg;
> +       int ret;
> +       u32 data, cmd;
> +
> +       /* Check for argument validation. */
> +       if (sid & ~0xf) {
> +               dev_err(&ctrl->dev, "exceed the max slv id\n");
> +               return -EINVAL;
> +       }
> +
> +       if (len > 4) {
> +               dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);

Missing newline

> +               return -EINVAL;
> +       }
> +
> +       if (opc >= 0x60 && opc <= 0x7f)
> +               opc = PMIF_CMD_REG;
> +       else if ((opc >= 0x20 && opc <= 0x2f) || (opc >= 0x38 && opc <= 0x3f))
> +               opc = PMIF_CMD_EXT_REG_LONG;
> +       else
> +               return -EINVAL;
> +
> +       /* Wait for Software Interface FSM state to be IDLE. */
> +       inf_reg = &arb->chan;
> +       ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
> +                                       data, GET_SWINF(data) == SWINF_IDLE,
> +                                       PMIF_DELAY_US, PMIF_TIMEOUT_US);
> +       if (ret < 0) {
> +               /* set channel ready if the data has transferred */
> +               if (pmif_is_fsm_vldclr(arb))
> +                       pmif_writel(arb, 1, inf_reg->ch_rdy);
> +               dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
> +               goto out;
> +       }
> +
> +       /* Send the command. */
> +       cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr;
> +       pmif_writel(arb, cmd, inf_reg->ch_send);
> +
> +       /*
> +        * Wait for Software Interface FSM state to be WFVLDCLR,
> +        * read the data and clear the valid flag.
> +        */
> +       ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
> +                                       data, GET_SWINF(data) == SWINF_WFVLDCLR,
> +                                       PMIF_DELAY_US, PMIF_TIMEOUT_US);
> +       if (ret < 0) {
> +               dev_err(&ctrl->dev, "failed to wait for SWINF_WFVLDCLR\n");
> +               goto out;
> +       }
> +
> +       data = pmif_readl(arb, inf_reg->rdata);
> +       memcpy(buf, &data, len);
> +       pmif_writel(arb, 1, inf_reg->ch_rdy);
> +
> +out:
> +       if (ret < 0)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
> +                              u16 addr, const u8 *buf, size_t len)
> +{
> +       struct pmif *arb = spmi_controller_get_drvdata(ctrl);
> +       struct ch_reg *inf_reg;
> +       int ret;
> +       u32 data, cmd;
> +
> +       if (len > 4) {
> +               dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);

Missing newline

> +               return -EINVAL;
> +       }
> +
> +       /* Check the opcode */
> +       if (opc >= 0x40 && opc <= 0x5F)
> +               opc = PMIF_CMD_REG;
> +       else if ((opc <= 0xF) || (opc >= 0x30 && opc <= 0x37))
> +               opc = PMIF_CMD_EXT_REG_LONG;
> +       else if (opc >= 0x80)
> +               opc = PMIF_CMD_REG_0;
> +       else
> +               return -EINVAL;
> +
> +       /* Wait for Software Interface FSM state to be IDLE. */
> +       inf_reg = &arb->chan;
> +       ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
> +                                       data, GET_SWINF(data) == SWINF_IDLE,
> +                                       PMIF_DELAY_US, PMIF_TIMEOUT_US);
> +       if (ret < 0) {
> +               /* set channel ready if the data has transferred */
> +               if (pmif_is_fsm_vldclr(arb))
> +                       pmif_writel(arb, 1, inf_reg->ch_rdy);
> +               dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
> +               goto out;
> +       }
> +
> +       /* Set the write data. */
> +       memcpy(&data, buf, len);
> +       pmif_writel(arb, data, inf_reg->wdata);
> +
> +       /* Send the command. */
> +       cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr;
> +       pmif_writel(arb, cmd, inf_reg->ch_send);
> +
> +out:
> +       if (ret < 0)
> +               return ret;
> +
> +       return 0;

Simplify to 

	out:
		return ret;

> +}
> +
> +static const struct pmif_data mt6873_pmif_arb = {
> +       .regs = mt6873_regs,
> +       .spmimst_regs = mt6873_spmi_regs,
> +       .soc_chan = 2,
> +};
> +
> +static int mtk_spmi_probe(struct platform_device *pdev)
> +{
> +       struct pmif *arb;
> +       struct spmi_controller *ctrl;
> +       int err, i;
> +       u32 chan_offset;
> +
> +       ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*arb));
> +       if (!ctrl)
> +               return -ENOMEM;
> +
> +       arb = spmi_controller_get_drvdata(ctrl);
> +       arb->data = of_device_get_match_data(&pdev->dev);

Use device_get_match_data() instead please.

> +       if (!arb->data) {
> +               err = -EINVAL;
> +               dev_err(&pdev->dev, "Cannot get drv_data\n");
> +               goto err_put_ctrl;
> +       }
> +
> +       arb->base = devm_platform_ioremap_resource_byname(pdev, "pmif");
> +       if (IS_ERR(arb->base)) {
> +               err = PTR_ERR(arb->base);
> +               dev_err(&pdev->dev, "pmif failed to get the remappped memory\n");

Please drop print as the API already prints errors for every problem.

> +               goto err_put_ctrl;
> +       }
> +
> +       arb->spmimst_base = devm_platform_ioremap_resource_byname(pdev, "spmimst");
> +       if (IS_ERR(arb->spmimst_base)) {
> +               err = PTR_ERR(arb->spmimst_base);
> +               dev_err(&pdev->dev, "spmimst failed to get the remappped memory\n");

Please drop print as the API already prints errors for every problem.

> +               goto err_put_ctrl;
> +       }
> +
> +       arb->nclks = ARRAY_SIZE(pmif_clock_names);
> +       if (arb->nclks > PMIF_MAX_CLKS) {
> +               err = -EINVAL;
> +               dev_err(&pdev->dev, "exceed the max clock numbers\n");

Do we really care? The dt schema should be checking this instead of the
driver.

> +               goto err_put_ctrl;
> +       }
> +
> +       for (i = 0; i < arb->nclks; i++)
> +               arb->clks[i].id = pmif_clock_names[i];
> +


From maz at kernel.org  Mon Aug  9 11:02:33 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Aug 2021 19:02:33 +0100
Subject: [PATCH 12/13] arm64: Add a capability for FEAT_EVC
In-Reply-To: <CAOQ_QsjT8DUoXQsxWGgGiZkwNe2itRswGomtq6-p+7_oU01orQ@mail.gmail.com>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-13-maz@kernel.org>
 <CAOQ_QsjT8DUoXQsxWGgGiZkwNe2itRswGomtq6-p+7_oU01orQ@mail.gmail.com>
Message-ID: <87k0kubio6.wl-maz@kernel.org>

Hi Oliver,

Thanks for having a look.

On Mon, 09 Aug 2021 17:30:45 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Hi Marc,
> 
> On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > Add a new capability to detect the Enhanced Counter Virtualization
> > feature (FEAT_EVC).
> >
> 
> s/FEAT_EVC/FEAT_ECV/g

I'm the knig fo tpyoes :).

> 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kernel/cpufeature.c | 10 ++++++++++
> >  arch/arm64/tools/cpucaps       |  1 +
> >  2 files changed, 11 insertions(+)
> >
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 0ead8bfedf20..9c2ce5408811 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -1899,6 +1899,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
> >                 .sign = FTR_UNSIGNED,
> >                 .min_field_value = 1,
> >         },
> > +       {
> > +               .desc = "Enhanced counter virtualization",
> > +               .capability = ARM64_HAS_ECV,
> > +               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
> > +               .matches = has_cpuid_feature,
> > +               .sys_reg = SYS_ID_AA64MMFR0_EL1,
> > +               .field_pos = ID_AA64MMFR0_ECV_SHIFT,
> > +               .sign = FTR_UNSIGNED,
> > +               .min_field_value = 1,
> > +       },
> 
> Per one of your other patches in the series, it sounds like userspace
> access to the self-synchronized registers hasn't been settled yet.
> However, if/when available to userspace, should this cpufeature map to
> an ELF HWCAP?

We can't prevent the access to userspace, unless we also trap
cntvct_el0 and cntfreq_el0. Which we try not to do. But you are indeed
correct, we probably have a HWCAP if we decide to advertise it to
userspace.

> Also, w.r.t. my series I have out for ECV in KVM. All the controls
> used in EL2 depend on ECV=0x2. I agree that ECV=0x1 needs a cpufeature
> bit, but what about EL2's use case?

My idea was to have a ARM64_HAS_ECV2 to capture the EL2 extensions
with min_field_value=2.

> Besides the typo:
> 
> Reviewed-by: Oliver Upton <oupton at google.com>

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From robdclark at gmail.com  Mon Aug  9 11:07:22 2021
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 9 Aug 2021 11:07:22 -0700
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent masters
 to use system cache
In-Reply-To: <76bfd0b4248148dfbf9d174ddcb4c2a2@codeaurora.org>
References: <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
 <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
 <20210809145651.GC1458@willie-the-truck>
 <CAF6AEGsSUojA=V0n2iRWTCn++buqN=Eoxo0r3=+=PBu1O=H-AQ@mail.gmail.com>
 <20210809170508.GB1589@willie-the-truck>
 <CAF6AEGtmZ3LzAJdtnKDQDbEN-a6_JgdN-fZ96pkU3dZqkiW91g@mail.gmail.com>
 <20210809174022.GA1840@willie-the-truck>
 <76bfd0b4248148dfbf9d174ddcb4c2a2@codeaurora.org>
Message-ID: <CAF6AEGtiVgHc7rcfzOpBmtVGQBvGPCBmtKJ3AJx887NSMj0EzQ@mail.gmail.com>

On Mon, Aug 9, 2021 at 10:47 AM Sai Prakash Ranjan
<saiprakash.ranjan at codeaurora.org> wrote:
>
> On 2021-08-09 23:10, Will Deacon wrote:
> > On Mon, Aug 09, 2021 at 10:18:21AM -0700, Rob Clark wrote:
> >> On Mon, Aug 9, 2021 at 10:05 AM Will Deacon <will at kernel.org> wrote:
> >> >
> >> > On Mon, Aug 09, 2021 at 09:57:08AM -0700, Rob Clark wrote:
> >> > > On Mon, Aug 9, 2021 at 7:56 AM Will Deacon <will at kernel.org> wrote:
> >> > > > On Mon, Aug 02, 2021 at 06:36:04PM -0700, Rob Clark wrote:
> >> > > > > On Mon, Aug 2, 2021 at 8:14 AM Will Deacon <will at kernel.org> wrote:
> >> > > > > > On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> >> > > > > > > On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> >> > > > > > > > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> >> > > > > > > > > On 2021-07-28 19:30, Georgi Djakov wrote:
> >> > > > > > > > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> >> > > > > > > > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> >> > > > > > > > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> >> > > > > > > > > > > the memory type setting required for the non-coherent masters to use
> >> > > > > > > > > > > system cache. Now that system cache support for GPU is added, we will
> >> > > > > > > > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> >> > > > > > > > > > > Without this, the system cache lines are not allocated for GPU.
> >> > > > > > > > > > >
> >> > > > > > > > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> >> > > > > > > > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> >> > > > > > > > > > > and makes GPU the user of this protection flag.
> >> > > > > > > > > >
> >> > > > > > > > > > Thank you for the patchset! Are you planning to refresh it, as it does
> >> > > > > > > > > > not apply anymore?
> >> > > > > > > > > >
> >> > > > > > > > >
> >> > > > > > > > > I was waiting on Will's reply [1]. If there are no changes needed, then
> >> > > > > > > > > I can repost the patch.
> >> > > > > > > >
> >> > > > > > > > I still think you need to handle the mismatched alias, no? You're adding
> >> > > > > > > > a new memory type to the SMMU which doesn't exist on the CPU side. That
> >> > > > > > > > can't be right.
> >> > > > > > > >
> >> > > > > > >
> >> > > > > > > Just curious, and maybe this is a dumb question, but what is your
> >> > > > > > > concern about mismatched aliases?  I mean the cache hierarchy on the
> >> > > > > > > GPU device side (anything beyond the LLC) is pretty different and
> >> > > > > > > doesn't really care about the smmu pgtable attributes..
> >> > > > > >
> >> > > > > > If the CPU accesses a shared buffer with different attributes to those which
> >> > > > > > the device is using then you fall into the "mismatched memory attributes"
> >> > > > > > part of the Arm architecture. It's reasonably unforgiving (you should go and
> >> > > > > > read it) and in some cases can apply to speculative accesses as well, but
> >> > > > > > the end result is typically loss of coherency.
> >> > > > >
> >> > > > > Ok, I might have a few other sections to read first to decipher the
> >> > > > > terminology..
> >> > > > >
> >> > > > > But my understanding of LLC is that it looks just like system memory
> >> > > > > to the CPU and GPU (I think that would make it "the point of
> >> > > > > coherence" between the GPU and CPU?)  If that is true, shouldn't it be
> >> > > > > invisible from the point of view of different CPU mapping options?
> >> > > >
> >> > > > You could certainly build a system where mismatched attributes don't cause
> >> > > > loss of coherence, but as it's not guaranteed by the architecture and the
> >> > > > changes proposed here affect APIs which are exposed across SoCs, then I
> >> > > > don't think it helps much.
> >> > > >
> >> > >
> >> > > Hmm, the description of the new mapping flag is that it applies only
> >> > > to transparent outer level cache:
> >> > >
> >> > > +/*
> >> > > + * Non-coherent masters can use this page protection flag to set cacheable
> >> > > + * memory attributes for only a transparent outer level of cache, also known as
> >> > > + * the last-level or system cache.
> >> > > + */
> >> > > +#define IOMMU_LLC      (1 << 6)
> >> > >
> >> > > But I suppose we could call it instead IOMMU_QCOM_LLC or something
> >> > > like that to make it more clear that it is not necessarily something
> >> > > that would work with a different outer level cache implementation?
> >> >
> >> > ... or we could just deal with the problem so that other people can reuse
> >> > the code. I haven't really understood the reluctance to solve this properly.
> >> >
> >> > Am I missing some reason this isn't solvable?
> >>
> >> Oh, was there another way to solve it (other than foregoing setting
> >> INC_OCACHE in the pgtables)?  Maybe I misunderstood, is there a
> >> corresponding setting on the MMU pgtables side of things?
> >
> > Right -- we just need to program the CPU's MMU with the matching memory
> > attributes! It's a bit more fiddly if you're just using ioremap_wc()
> > though, as it's usually the DMA API which handles the attributes under
> > the
> > hood.
> >
> > Anyway, sorry, I should've said that explicitly earlier on. We've done
> > this
> > sort of thing in the Android tree so I assumed Sai knew what needed to
> > be
> > done and then I didn't think to explain to you :(
> >
>
> Right I was aware of that but even in the android tree there is no user
> :)
> I think we can't have a new memory type without any user right in
> upstream
> like android tree?
>
> @Rob, I think you  already tried adding a new MT and used
> pgprot_syscached()
> in GPU driver but it was crashing?

Correct, but IIRC there were some differences in the code for memory
types compared to the android tree.. I couldn't figure out the
necessary patches to cherry-pick to get the android patch to apply
cleanly, so I tried re-implementing it without having much of a clue
about how that code works (which was probably the issue) ;-)

BR,
-R


From jernej.skrabec at gmail.com  Mon Aug  9 11:04:09 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 09 Aug 2021 20:04:09 +0200
Subject: [PATCH v3 05/10] media: uapi: Add VP9 stateless decoder controls
In-Reply-To: <20210805144246.11998-6-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
 <20210805144246.11998-6-andrzej.p@collabora.com>
Message-ID: <5154683.x8GX3iSW2O@kista>

Hi Andrzej!

Dne ?etrtek, 05. avgust 2021 ob 16:42:41 CEST je Andrzej Pietrasiewicz 
napisal(a):
> Add the VP9 stateless decoder controls plus the documentation that goes
> with it.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
> Co-developed-by: Ezequiel Garcia <ezequiel at collabora.com>
> Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
> Signed-off-by: Adrian Ratiu <adrian.ratiu at collabora.com>
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
> Co-developed-by: Daniel Almeida <daniel.almeida at collabora.com>
> Signed-off-by: Daniel Almeida <daniel.almeida at collabora.com>
> ---
>  .../userspace-api/media/v4l/biblio.rst        |  10 +
>  .../media/v4l/ext-ctrls-codec-stateless.rst   | 545 ++++++++++++++++++
>  .../media/v4l/pixfmt-compressed.rst           |  15 +
>  .../media/v4l/vidioc-g-ext-ctrls.rst          |   8 +
>  .../media/v4l/vidioc-queryctrl.rst            |  12 +
>  .../media/videodev2.h.rst.exceptions          |   2 +
>  drivers/media/v4l2-core/v4l2-ctrls-core.c     | 174 ++++++
>  drivers/media/v4l2-core/v4l2-ctrls-defs.c     |   8 +
>  drivers/media/v4l2-core/v4l2-ioctl.c          |   1 +
>  include/media/v4l2-ctrls.h                    |   4 +
>  include/uapi/linux/v4l2-controls.h            | 433 ++++++++++++++
>  include/uapi/linux/videodev2.h                |   6 +
>  12 files changed, 1218 insertions(+)
> 

<snip>

> diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-
controls.h
> index 5532b5f68493..8f8c3c1ad885 100644
> --- a/include/uapi/linux/v4l2-controls.h
> +++ b/include/uapi/linux/v4l2-controls.h
> @@ -2010,6 +2010,439 @@ struct v4l2_ctrl_hdr10_mastering_display {
>  	__u32 min_display_mastering_luminance;
>  };
>  
> +/* Stateless VP9 controls */
> +
> +/**
> + * enum v4l2_vp9_loop_filter_flags - VP9 loop filter flags
> + *
> + * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED: the filter level depends on
> + *	the mode and reference frame used to predict a block
> + * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE: the bitstream contains 
additional
> + *	syntax elements that specify which mode and reference frame deltas 
are to be updated
> + *
> + * Those are the flags that may be passed to &v4l2_vp9_loop_filter.flags. See
> + * section '7.2.8 Loop filter semantics' of the VP9 specification for more
> + * details.
> + */
> +enum v4l2_vp9_loop_filter_flags {
> +	V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED = 1 << 0,
> +	V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE = 1 << 1,
> +};
> +
> +/**
> + * struct v4l2_vp9_loop_filter - VP9 loop filter parameters
> + *
> + * @ref_deltas: contains the adjustment needed for the filter level based on 
the chosen
> + *	reference frame. If this syntax element is not present in the 
bitstream, users
> + *	should pass its last value.
> + * @mode_deltas: contains the adjustment needed for the filter level based 
on the chosen mode.
> + *	If this syntax element is not present in the bitstream, users
> + *	should pass its last value.
> + * @level: indicates the loop filter strength
> + * @sharpness: indicates the sharpness level
> + * @flags: combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags
> + * @reserved: padding field. Should be zeroed by applications.
> + *
> + * This structure contains all loop filter related parameters. See sections
> + * '7.2.8 Loop filter semantics' of the VP9 specification for more details.
> + */
> +struct v4l2_vp9_loop_filter {
> +	__s8 ref_deltas[4];
> +	__s8 mode_deltas[2];
> +	__u8 level;
> +	__u8 sharpness;
> +	__u8 flags;
> +	__u8 reserved[7];
> +};
> +
> +/**
> + * struct v4l2_vp9_quantization - VP9 quantization parameters
> + *
> + * @base_q_idx: indicates the base frame qindex
> + * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx
> + * @delta_q_uv_dc: indicates the UV DC quantizer relative to base_q_idx
> + * @delta_q_uv_ac: indicates the UV AC quantizer relative to base_q_idx
> + * @reserved: padding field. Should be zeroed by applications.
> + *
> + * Encodes the quantization parameters. See section '7.2.9 Quantization 
params
> + * syntax' of the VP9 specification for more details.
> + */
> +struct v4l2_vp9_quantization {
> +	__u8 base_q_idx;
> +	__s8 delta_q_y_dc;
> +	__s8 delta_q_uv_dc;
> +	__s8 delta_q_uv_ac;
> +	__u8 reserved[4];
> +};
> +
> +/**
> + * enum v4l2_vp9_segmentation_flags - VP9 segmentation flags
> + *
> + * @V4L2_VP9_SEGMENTATION_FLAG_ENABLED: indicates that this frame makes use 
of
> + *	the segmentation tool
> + * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP: indicates that the segmentation 
map
> + *	should be updated during the decoding of this frame
> + * @V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE: indicates that the updates 
to
> + *	the segmentation map are coded relative to the existing 
segmentation map
> + * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA: indicates that new parameters 
are
> + *	about to be specified for each segment
> + * @V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE: indicates that the
> + *	segmentation parameters represent the actual values to be used
> + *
> + * Those are the flags that may be passed to &v4l2_vp9_segmentation.flags. 
See
> + * section '7.2.10 Segmentation params syntax' of the VP9 specification for
> + * more details.
> + */
> +enum v4l2_vp9_segmentation_flags {
> +	V4L2_VP9_SEGMENTATION_FLAG_ENABLED = 1 << 0,
> +	V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP = 1 << 1,
> +	V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE = 1 << 2,
> +	V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA = 1 << 3,
> +	V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE = 1 << 4,
> +};
> +
> +#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id)	(1 << (id))
> +#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK	0xf
> +
> +/**
> + * enum v4l2_vp9_segment_feature - VP9 segment feature IDs
> + *
> + * @V4L2_VP9_SEG_LVL_ALT_Q: quantizer segment feature
> + * @V4L2_VP9_SEG_LVL_ALT_L: loop filter segment feature
> + * @V4L2_VP9_SEG_LVL_REF_FRAME reference frame segment feature
> + * @V4L2_VP9_SEG_LVL_SKIP: skip segment feature
> + * @V4L2_VP9_SEG_LVV_MAX: number of segment features
> + *
> + * Segment feature IDs. See section '7.2.10 Segmentation params syntax' of 
the
> + * VP9 specification for more details.
> + */
> +enum v4l2_vp9_segment_feature {
> +	V4L2_VP9_SEG_LVL_ALT_Q,
> +	V4L2_VP9_SEG_LVL_ALT_L,
> +	V4L2_VP9_SEG_LVL_REF_FRAME,
> +	V4L2_VP9_SEG_LVL_SKIP,
> +	V4L2_VP9_SEG_LVL_MAX,
> +};

What is the reason not to assign values like 1 << 0, 1 << 1, etc. and instead 
provide separate macro V4L2_VP9_SEGMENT_FEATURE_ENABLED()? This is a departure 
from current practice.

> +
> +/**
> + * struct v4l2_vp9_segmentation - VP9 segmentation parameters
> + *
> + * @feature_data: data attached to each feature. Data entry is only valid 
if the feature is enabled
> + * @feature_enabled: bitmask defining which features are enabled in each 
segment
> + * @tree_probs: specifies the probability values to be used when
> + *	decoding a Segment-ID. See '5.15. Segmentation map' section of the 
VP9 specification
> + *	for more details.
> + * @pred_probs: specifies the probability values to be used when decoding a
> + *	Predicted-Segment-ID. See '6.4.14. Get segment id syntax' section 
of :ref:`vp9`
> + *	for more details.
> + * @flags: combination of V4L2_VP9_SEGMENTATION_FLAG_* flags
> + * @reserved: padding field. Should be zeroed by applications.
> + *
> + * Encodes the quantization parameters. See section '7.2.10 Segmentation 
params syntax' of
> + * the VP9 specification for more details.
> + */
> +struct v4l2_vp9_segmentation {
> +	__s16 feature_data[8][4];
> +	__u8 feature_enabled[8];
> +	__u8 tree_probs[7];
> +	__u8 pred_probs[3];
> +	__u8 flags;
> +	__u8 reserved[5];
> +};
> +
> +/**
> + * enum v4l2_vp9_intra_prediction_mode - VP9 Intra prediction modes
> + *
> + * @V4L2_VP9_INTRA_PRED_MODE_DC_PRED: DC intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_V_PRED: vertical intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_H_PRED: horizontal intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D45_PRED: D45 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D135_PRED: D135 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D117_PRED: D117 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D153_PRED: D153 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D207_PRED: D207 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D63_PRED: D63 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_TM_PRED: True Motion intra prediction
> + *
> + * See section '7.4.5 Intra frame mode info semantics' for more details.
> + */
> +enum v4l2_vp9_intra_prediction_mode {
> +	V4L2_VP9_INTRA_PRED_MODE_DC_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_V_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_H_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D45_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D135_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D117_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D153_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D207_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D63_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_TM_PRED,
> +};

I dislike using enums without assigning values. I see that historically (at 
the beginning of this file), values were always assigned. However, if 
maintainers agree with you, that's fine by me.

> +
> +/**
> + * enum v4l2_vp9_reset_frame_context - Valid values for
> + *			&v4l2_ctrl_vp9_frame->reset_frame_context
> + *
> + * @V4L2_VP9_RESET_FRAME_CTX_NONE: don't reset any frame context
> + * @V4L2_VP9_RESET_FRAME_CTX_SPEC: reset the frame context pointed by
> + *	&v4l2_ctrl_vp9_frame.frame_context_idx
> + * @V4L2_VP9_RESET_FRAME_CTX_ALL: reset all frame contexts
> + *
> + * See section '7.2 Uncompressed header semantics' of the VP9 specification 
for more details.
> + */
> +enum v4l2_vp9_reset_frame_context {
> +	V4L2_VP9_RESET_FRAME_CTX_NONE,
> +	V4L2_VP9_RESET_FRAME_CTX_SPEC,
> +	V4L2_VP9_RESET_FRAME_CTX_ALL,
> +};
> +
> +/**
> + * enum v4l2_vp9_interpolation_filter - VP9 interpolation filter types
> + *
> + * @V4L2_VP9_INTERP_FILTER_EIGHTTAP: eight tap filter
> + * @V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH: eight tap smooth filter
> + * @V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP: eight tap sharp filter
> + * @V4L2_VP9_INTERP_FILTER_BILINEAR: bilinear filter
> + * @V4L2_VP9_INTERP_FILTER_SWITCHABLE: filter selection is signaled at the 
block level
> + *
> + * See section '7.2.7 Interpolation filter semantics' of the VP9 
specification
> + * for more details.
> + */
> +enum v4l2_vp9_interpolation_filter {
> +	V4L2_VP9_INTERP_FILTER_EIGHTTAP,
> +	V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH,
> +	V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP,
> +	V4L2_VP9_INTERP_FILTER_BILINEAR,
> +	V4L2_VP9_INTERP_FILTER_SWITCHABLE,
> +};
> +
> +/**
> + * enum v4l2_vp9_reference_mode - VP9 reference modes
> + *
> + * @V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE: indicates that all the inter 
blocks use only a
> + *	single reference frame to generate motion compensated prediction
> + * @V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE: requires all the inter 
blocks to use compound mode.
> + *	Single reference frame prediction is not allowed
> + * @V4L2_VP9_REFERENCE_MODE_SELECT: allows each individual inter block to 
select between single
> + *	and compound prediction modes
> + *
> + * See section '7.3.6 Frame reference mode semantics' of the VP9 
specification
> + * for more details.
> + */
> +enum v4l2_vp9_reference_mode {
> +	V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE,
> +	V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE,
> +	V4L2_VP9_REFERENCE_MODE_SELECT,
> +};
> +
> +/**
> + * enum v4l2_vp9_tx_mode - VP9 TX modes
> + *
> + * @V4L2_VP9_TX_MODE_ONLY_4X4: transform size is 4x4
> + * @V4L2_VP9_TX_MODE_ALLOW_8X8: transform size can be up to 8x8
> + * @V4L2_VP9_TX_MODE_ALLOW_16X16: transform size can be up to 16x16
> + * @V4L2_VP9_TX_MODE_ALLOW_32X32: transform size can be up to 32x32
> + * @V4L2_VP9_TX_MODE_SELECT: bitstream contains the transform size for each 
block
> + *
> + * See section '7.3.1 Tx mode semantics' of the VP9 specification for more 
details.
> + */
> +enum v4l2_vp9_tx_mode {
> +	V4L2_VP9_TX_MODE_ONLY_4X4,
> +	V4L2_VP9_TX_MODE_ALLOW_8X8,
> +	V4L2_VP9_TX_MODE_ALLOW_16X16,
> +	V4L2_VP9_TX_MODE_ALLOW_32X32,
> +	V4L2_VP9_TX_MODE_SELECT,
> +};
> +
> +/**
> + * enum v4l2_vp9_frame_flags - VP9 frame flags
> + * @V4L2_VP9_FRAME_FLAG_KEY_FRAME: the frame is a key frame
> + * @V4L2_VP9_FRAME_FLAG_SHOW_FRAME: the frame should be displayed
> + * @V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT: the decoding should be error 
resilient
> + * @V4L2_VP9_FRAME_FLAG_INTRA_ONLY: the frame does not reference other 
frames
> + * @V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV: the frame can use high 
precision motion vectors
> + * @V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX: frame context should be updated 
after decoding
> + * @V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE: parallel decoding is used
> + * @V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING: vertical subsampling is enabled
> + * @V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING: horizontal subsampling is enabled
> + * @V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING: full UV range is used
> + *
> + * Check the VP9 specification for more details.
> + */
> +enum v4l2_vp9_frame_flags {
> +	V4L2_VP9_FRAME_FLAG_KEY_FRAME = 1 << 0,
> +	V4L2_VP9_FRAME_FLAG_SHOW_FRAME = 1 << 1,
> +	V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT = 1 << 2,
> +	V4L2_VP9_FRAME_FLAG_INTRA_ONLY = 1 << 3,
> +	V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV = 1 << 4,
> +	V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX = 1 << 5,
> +	V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE = 1 << 6,
> +	V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING = 1 << 7,
> +	V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING = 1 << 8,
> +	V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING = 1 << 9,
> +};
> +
> +/**
> + * enum v4l2_vp9_ref_frame_sign_bias - Whether ref_frame_sign_bias is 1 for 
a given reference frame
> + * @V4L2_VP9_SIGN_BIAS_LAST: ref_frame_sign_bias is 1 for the "last" 
reference frame
> + * @V4L2_VP9_SIGN_BIAS_GOLDEN: ref_frame_sign_bias is 1 for the "golden" 
reference frame
> + * @V4L2_VP9_SIGN_BIAS_ALT: ref_frame_sign_bias is 1 for the "alt" 
reference frame
> + */
> +
> +enum v4l2_vp9_ref_frame_sign_bias {
> +	V4L2_VP9_SIGN_BIAS_LAST,
> +	V4L2_VP9_SIGN_BIAS_GOLDEN,
> +	V4L2_VP9_SIGN_BIAS_ALT,
> +};

As I mentioned before, you probably want to assign values here, since values 
are used as bitmap.

> +
> +#define V4L2_VP9_PROFILE_MAX		3
> +
> +#define V4L2_CID_STATELESS_VP9_FRAME	(V4L2_CID_CODEC_STATELESS_BASE + 
300)
> +/**
> + * struct v4l2_ctrl_vp9_frame - VP9 frame decoding control
> + *
> + * @lf: loop filter parameters. See &v4l2_vp9_loop_filter for more details
> + * @quant: quantization parameters. See &v4l2_vp9_quantization for more 
details
> + * @seg: segmentation parameters. See &v4l2_vp9_segmentation for more 
details
> + * @flags: combination of V4L2_VP9_FRAME_FLAG_* flags
> + * @compressed_header_size: compressed header size in bytes
> + * @uncompressed_header_size: uncompressed header size in bytes
> + * @frame_width_minus_1: add 1 to it and you'll get the frame width 
expressed in pixels
> + * @frame_height_minus_1: add 1 to it and you'll get the frame height 
expressed in pixels
> + * @render_width_minus_1: add 1 to it and you'll get the expected render 
width expressed in
> + *	pixels. This is not used during the decoding process but might be 
used by HW scalers
> + *	to prepare a frame that's ready for scanout
> + * @render_height_minus_1: add 1 to it and you'll get the expected render 
height expressed in
> + *	pixels. This is not used during the decoding process but might be 
used by HW scalers
> + *	to prepare a frame that's ready for scanout
> + * @last_frame_ts: "last" reference buffer timestamp.
> + * The timestamp refers to the timestamp field in struct v4l2_buffer.
> + * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
> + * @golden_frame_ts: "golden" reference buffer timestamp.
> + * The timestamp refers to the timestamp field in struct v4l2_buffer.
> + * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
> + * @alt_frame_ts: "alt" reference buffer timestamp.
> + * The timestamp refers to the timestamp field in struct v4l2_buffer.
> + * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
> + * @ref_frame_sign_bias: a bitfield specifying whether the sign bias is set 
for a given
> + *	reference frame. See &v4l2_vp9_ref_frame_sign_bias for more 
details.
> + * @reset_frame_context: specifies whether the frame context should be reset 
to default values.
> + *	See &v4l2_vp9_reset_frame_context for more details
> + * @frame_context_idx: frame context that should be used/updated
> + * @profile: VP9 profile. Can be 0, 1, 2 or 3
> + * @bit_depth: bits per components. Can be 8, 10 or 12. Note that not all 
profiles support
> + *	10 and/or 12 bits depths
> + * @interpolation_filter: specifies the filter selection used for performing 
inter prediction.
> + *	See &v4l2_vp9_interpolation_filter for more details
> + * @tile_cols_log2: specifies the base 2 logarithm of the width of each tile 
(where the width
> + *	is measured in units of 8x8 blocks). Shall be less than or equal 
to 6
> + * @tile_rows_log2: specifies the base 2 logarithm of the height of each 
tile (where the height
> + *	is measured in units of 8x8 blocks)
> + * @tx_mode: specifies the TX mode. See &v4l2_vp9_tx_mode for more details
> + * @reference_mode: specifies the type of inter prediction to be used. See
> + *	&v4l2_vp9_reference_mode for more details
> + * @reserved: padding field. Should be zeroed by applications.
> + */
> +struct v4l2_ctrl_vp9_frame {
> +	struct v4l2_vp9_loop_filter lf;
> +	struct v4l2_vp9_quantization quant;
> +	struct v4l2_vp9_segmentation seg;
> +	__u32 flags;
> +	__u16 compressed_header_size;
> +	__u16 uncompressed_header_size;
> +	__u16 frame_width_minus_1;
> +	__u16 frame_height_minus_1;
> +	__u16 render_width_minus_1;
> +	__u16 render_height_minus_1;
> +	__u64 last_frame_ts;
> +	__u64 golden_frame_ts;
> +	__u64 alt_frame_ts;
> +	__u8 ref_frame_sign_bias;
> +	__u8 reset_frame_context;
> +	__u8 frame_context_idx;
> +	__u8 profile;
> +	__u8 bit_depth;
> +	__u8 interpolation_filter;
> +	__u8 tile_cols_log2;
> +	__u8 tile_rows_log2;
> +	__u8 tx_mode;

AFAICS, TX mode is part of compressed header in chapter 6.3.1. Any reason it's 
here and not in  v4l2_ctrl_vp9_compressed_hdr_probs?

> +	__u8 reference_mode;
> +	__u8 reserved[6];
> +};
> +
> +#define V4L2_VP9_NUM_FRAME_CTX	4
> +
> +/**
> + * struct v4l2_vp9_mv_compressed_hdr_probs - VP9 Motion vector probability 
updates
> + * @joint: motion vector joint probability updates
> + * @sign: motion vector sign probability updates
> + * @classes: motion vector class probability updates
> + * @class0_bit: motion vector class0 bit probability updates
> + * @bits: motion vector bits probability updates
> + * @class0_fr: motion vector class0 fractional bit probability updates
> + * @fr: motion vector fractional bit probability updates
> + * @class0_hp: motion vector class0 high precision fractional bit 
probability updates
> + * @hp: motion vector high precision fractional bit probability updates
> + *
> + * This structure contains new values of motion vector probabilities.
> + * A value of zero in an array element means there is no update of the 
relevant probability.
> + * See `struct v4l2_vp9_prob_updates` for details.
> + */
> +struct v4l2_vp9_mv_compressed_hdr_probs {
> +	__u8 joint[3];
> +	__u8 sign[2];
> +	__u8 classes[2][10];
> +	__u8 class0_bit[2];
> +	__u8 bits[2][10];
> +	__u8 class0_fr[2][2][3];
> +	__u8 fr[2][3];
> +	__u8 class0_hp[2];
> +	__u8 hp[2];
> +};
> +
> +#define V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS	
(V4L2_CID_CODEC_STATELESS_BASE + 301)
> +/**
> + * struct v4l2_ctrl_vp9_compressed_hdr_probs - VP9 probability updates 
control
> + * @tx8: TX 8x8 probability updates
> + * @tx16: TX 16x16 probability updates
> + * @tx32: TX 32x32 probability updates
> + * @coef: coefficient probability updates
> + * @skip: skip probability updates
> + * @inter_mode: inter mode probability updates
> + * @interp_filter: interpolation filter probability updates
> + * @is_inter: is inter-block probability updates
> + * @comp_mode: compound prediction mode probability updates
> + * @single_ref: single ref probability updates
> + * @comp_ref: compound ref probability updates
> + * @y_mode: Y prediction mode probability updates
> + * @uv_mode: UV prediction mode probability updates
> + * @partition: partition probability updates
> + * @mv: motion vector probability updates
> + *
> + * This structure holds the probabilities update as parsed in the 
compressed
> + * header (Spec 6.3). These values represent the value of probability 
update after
> + * being translated with inv_map_table[] (see 6.3.5). A value of zero in an 
array element
> + * means that there is no update of the relevant probability.
> + */
> +struct v4l2_ctrl_vp9_compressed_hdr_probs {
> +	__u8 tx8[2][1];
> +	__u8 tx16[2][2];
> +	__u8 tx32[2][3];
> +	__u8 coef[4][2][2][6][6][3];
> +	__u8 skip[3];
> +	__u8 inter_mode[7][3];
> +	__u8 interp_filter[4][2];
> +	__u8 is_inter[4];
> +	__u8 comp_mode[5];
> +	__u8 single_ref[5][2];
> +	__u8 comp_ref[5];
> +	__u8 y_mode[4][9];
> +	__u8 uv_mode[10][9];
> +	__u8 partition[16][3];
> +
> +	struct v4l2_vp9_mv_compressed_hdr_probs mv;

v4l2_ctrl_vp9_compressed_hdr_probs and v4l2_vp9_mv_compressed_hdr_probs are so 
confusingly similar, it's easy to mess up quickly. Can we find more distinct 
names?

Note, I just skimmed this patch, maybe I'll have some more questions later. 
Great work!

Best regards,
Jernej

> +};
> +
>  /* MPEG-compression definitions kept for backwards compatibility */
>  #ifndef __KERNEL__
>  #define V4L2_CTRL_CLASS_MPEG            V4L2_CTRL_CLASS_CODEC
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 58392dcd3bf5..4abe4362519e 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -703,6 +703,7 @@ struct v4l2_pix_format {
>  #define V4L2_PIX_FMT_VP8      v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
>  #define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') /* VP8 parsed 
frame */
>  #define V4L2_PIX_FMT_VP9      v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
> +#define V4L2_PIX_FMT_VP9_FRAME v4l2_fourcc('V', 'P', '9', 'F') /* VP9 parsed 
frame */
>  #define V4L2_PIX_FMT_HEVC     v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.
265 */
>  #define V4L2_PIX_FMT_FWHT     v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh 
Hadamard Transform (vicodec) */
>  #define V4L2_PIX_FMT_FWHT_STATELESS     v4l2_fourcc('S', 'F', 'W', 'H') /* 
Stateless FWHT (vicodec) */
> @@ -1755,6 +1756,8 @@ struct v4l2_ext_control {
>  		struct v4l2_ctrl_mpeg2_sequence __user 
*p_mpeg2_sequence;
>  		struct v4l2_ctrl_mpeg2_picture __user *p_mpeg2_picture;
>  		struct v4l2_ctrl_mpeg2_quantisation __user 
*p_mpeg2_quantisation;
> +		struct v4l2_ctrl_vp9_compressed_hdr_probs __user 
*p_vp9_compressed_hdr_probs;
> +		struct v4l2_ctrl_vp9_frame __user *p_vp9_frame;
>  		void __user *ptr;
>  	};
>  } __attribute__ ((packed));
> @@ -1819,6 +1822,9 @@ enum v4l2_ctrl_type {
>  	V4L2_CTRL_TYPE_MPEG2_QUANTISATION   = 0x0250,
>  	V4L2_CTRL_TYPE_MPEG2_SEQUENCE       = 0x0251,
>  	V4L2_CTRL_TYPE_MPEG2_PICTURE        = 0x0252,
> +
> +	V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS	= 0x0260,
> +	V4L2_CTRL_TYPE_VP9_FRAME		= 0x0261,
>  };
>  
>  /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
> -- 
> 2.17.1
> 
> 





From maz at kernel.org  Mon Aug  9 11:11:17 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 09 Aug 2021 19:11:17 +0100
Subject: [PATCH 13/13] arm64: Add CNT{P, V}CTSS_EL0 alternatives to cnt{p,
 v}ct_el0
In-Reply-To: <CAOQ_QshjRWh=onT-j3dWgmVfnAXsMFJoz0i7OEezQxkW4O9KZA@mail.gmail.com>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-14-maz@kernel.org>
 <CAOQ_QshjRWh=onT-j3dWgmVfnAXsMFJoz0i7OEezQxkW4O9KZA@mail.gmail.com>
Message-ID: <87im0ebi9m.wl-maz@kernel.org>

On Mon, 09 Aug 2021 17:42:00 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > CNTPCTSS_EL0 and CNTVCTSS_EL0 are alternatives to the usual
> > CNTPCT_EL0 and CNTVCT_EL0 that do not require a previous ISB
> > to be synchronised (SS stands for Self-Synchronising).
> >
> > Use the ARM64_HAS_ECV capability to control alternative sequences
> > that switch to these low(er)-cost primitives. Note that the
> > counter access in the VDSO is for now left alone until we decide
> > whether we want to allow this.
> 
> What remains to be figured out before we add this to the vDSO (and
> presumably advertise to userspace through some standard convention)?

We need to understand what breaks if we runtime-patch the VDSO just
like we do with the rest of the kernel. To start with, the debug
version of the shared object is not the same as the object presented
to the process. Maybe that's not a problem, but I would tend to err on
the side of caution.

An alternative suggested by Ard was to have a separate function
altogether for the counter access and an ifunc mapping to pick the
right one.

> It would be nice to skip the trap handler altogether, unless there's a
> can of worms lurking that I'm not aware of.

The trap handlers are only there to work around errata. If you look at
the arch timer code, you will notice that there is a bunch of SoCs and
CPUs that do not have a reliable counter, and for which we have to
trap the virtual counter accesses from userspace (as well as the
VDSO).

On sane platforms, userspace is free to use the virtual counter
without any trap.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From oupton at google.com  Mon Aug  9 11:17:38 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 11:17:38 -0700
Subject: [PATCH 13/13] arm64: Add CNT{P, V}CTSS_EL0 alternatives to cnt{p,
 v}ct_el0
In-Reply-To: <87im0ebi9m.wl-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-14-maz@kernel.org>
 <CAOQ_QshjRWh=onT-j3dWgmVfnAXsMFJoz0i7OEezQxkW4O9KZA@mail.gmail.com>
 <87im0ebi9m.wl-maz@kernel.org>
Message-ID: <CAOQ_Qsh6h_afu_-WjJ2JTP=gYBYW4hbC92qmxzyJ8dgRCCgLKw@mail.gmail.com>

On Mon, Aug 9, 2021 at 11:11 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 09 Aug 2021 17:42:00 +0100,
> Oliver Upton <oupton at google.com> wrote:
> >
> > On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > CNTPCTSS_EL0 and CNTVCTSS_EL0 are alternatives to the usual
> > > CNTPCT_EL0 and CNTVCT_EL0 that do not require a previous ISB
> > > to be synchronised (SS stands for Self-Synchronising).
> > >
> > > Use the ARM64_HAS_ECV capability to control alternative sequences
> > > that switch to these low(er)-cost primitives. Note that the
> > > counter access in the VDSO is for now left alone until we decide
> > > whether we want to allow this.
> >
> > What remains to be figured out before we add this to the vDSO (and
> > presumably advertise to userspace through some standard convention)?
>
> We need to understand what breaks if we runtime-patch the VDSO just
> like we do with the rest of the kernel. To start with, the debug
> version of the shared object is not the same as the object presented
> to the process. Maybe that's not a problem, but I would tend to err on
> the side of caution.

I would too, but there sadly are instances of Linux patching *user*
memory already (go look at how KVM/x86 handles the VMCALL/VMMCALL
instruction). But yes, I would much prefer the debug vDSO correspond
to the actual instructions.

> An alternative suggested by Ard was to have a separate function
> altogether for the counter access and an ifunc mapping to pick the
> right one.
>

Hmm, this does sound promising.

> > It would be nice to skip the trap handler altogether, unless there's a
> > can of worms lurking that I'm not aware of.
>
> The trap handlers are only there to work around errata. If you look at
> the arch timer code, you will notice that there is a bunch of SoCs and
> CPUs that do not have a reliable counter, and for which we have to
> trap the virtual counter accesses from userspace (as well as the
> VDSO).
>
> On sane platforms, userspace is free to use the virtual counter
> without any trap.

/facepalm I was about 2 cups of coffee short when writing this :) Thanks!

--
Oliver


From semen.protsenko at linaro.org  Mon Aug  9 11:18:29 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 9 Aug 2021 21:18:29 +0300
Subject: [PATCH v2 2/8] pinctrl: samsung: Add Exynos850 SoC specific data
In-Reply-To: <407ee65f-6004-5173-9fcc-99023c85db4e@canonical.com>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-3-semen.protsenko@linaro.org>
 <407ee65f-6004-5173-9fcc-99023c85db4e@canonical.com>
Message-ID: <CAPLW+4mfTMWWssW8+nTt8Yp3dN5=WJpji=o_rRYYr6+kx_dctA@mail.gmail.com>

On Mon, 9 Aug 2021 at 13:43, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 06/08/2021 17:21, Sam Protsenko wrote:
> > Add Samsung Exynos850 SoC specific data to enable pinctrl support for
> > all platforms based on Exynos850.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> > Changes in v2:
> >   - Removed .suspend/.resume callbacks, as retention registers are not
> >     implemented yet for Exynos850
> >   - Removed .eint_gpio_init for AUD domain, as there are no external
> >     interrupts available for that domain
> >
> >  .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 116 ++++++++++++++++++
> >  drivers/pinctrl/samsung/pinctrl-exynos.h      |  29 +++++
> >  drivers/pinctrl/samsung/pinctrl-samsung.c     |   2 +
> >  drivers/pinctrl/samsung/pinctrl-samsung.h     |   1 +
> >  4 files changed, 148 insertions(+)
> >
> > diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> > index b6e56422a700..3157bdf0233c 100644
> > --- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> > +++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> > @@ -40,6 +40,24 @@ static const struct samsung_pin_bank_type exynos5433_bank_type_alive = {
> >       .reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
> >  };
> >
> > +/*
> > + * Bank type for non-alive type. Bit fields:
> > + * CON: 4, DAT: 1, PUD: 4, DRV: 4, CONPDN: 2, PUDPDN: 4
> > + */
> > +static struct samsung_pin_bank_type exynos850_bank_type_off  = {
> > +     .fld_width = { 4, 1, 4, 4, 2, 4, },
> > +     .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
> > +};
> > +
> > +/*
> > + * Bank type for alive type. Bit fields:
> > + * CON: 4, DAT: 1, PUD: 4, DRV: 4
> > + */
> > +static struct samsung_pin_bank_type exynos850_bank_type_alive = {
>
> I missed that part last time - this and one before should be const.
>
> > +     .fld_width = { 4, 1, 4, 4, },
> > +     .reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
> > +};
> > +
> >  /* Pad retention control code for accessing PMU regmap */
> >  static atomic_t exynos_shared_retention_refcnt;
> >
> > @@ -422,3 +440,101 @@ const struct samsung_pinctrl_of_match_data exynos7_of_data __initconst = {
> >       .ctrl           = exynos7_pin_ctrl,
> >       .num_ctrl       = ARRAY_SIZE(exynos7_pin_ctrl),
> >  };
> > +
> > +/* pin banks of exynos850 pin-controller 0 (ALIVE) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks0[] = {
>
> All these as well - initconst - unless they are somehow different than
> rest of such structures?
>
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
> > +     EXYNOS9_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
> > +     EXYNOS9_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
> > +     EXYNOS9_PIN_BANK_EINTW(4, 0x080, "gpa4", 0x10),
> > +     EXYNOS9_PIN_BANK_EINTN(3, 0x0A0, "gpq0"),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 1 (CMGP) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks1[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x000, "gpm0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x020, "gpm1", 0x04),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x040, "gpm2", 0x08),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x060, "gpm3", 0x0C),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x080, "gpm4", 0x10),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x0A0, "gpm5", 0x14),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x0C0, "gpm6", 0x18),
> > +     EXYNOS9_PIN_BANK_EINTW(1, 0x0E0, "gpm7", 0x1C),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 2 (AUD) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks2[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTG(5, 0x020, "gpb1", 0x04),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 3 (HSI) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks3[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTG(6, 0x000, "gpf2", 0x00),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 4 (CORE) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks4[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTG(4, 0x000, "gpf0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTG(8, 0x020, "gpf1", 0x04),
> > +};
> > +
> > +/* pin banks of exynos850 pin-controller 5 (PERI) */
> > +static struct samsung_pin_bank_data exynos850_pin_banks5[] = {
> > +     /* Must start with EINTG banks, ordered by EINT group number. */
> > +     EXYNOS9_PIN_BANK_EINTG(2, 0x000, "gpg0", 0x00),
> > +     EXYNOS9_PIN_BANK_EINTG(6, 0x020, "gpp0", 0x04),
> > +     EXYNOS9_PIN_BANK_EINTG(4, 0x040, "gpp1", 0x08),
> > +     EXYNOS9_PIN_BANK_EINTG(4, 0x060, "gpp2", 0x0C),
> > +     EXYNOS9_PIN_BANK_EINTG(8, 0x080, "gpg1", 0x10),
> > +     EXYNOS9_PIN_BANK_EINTG(8, 0x0A0, "gpg2", 0x14),
> > +     EXYNOS9_PIN_BANK_EINTG(1, 0x0C0, "gpg3", 0x18),
> > +     EXYNOS9_PIN_BANK_EINTG(3, 0x0E0, "gpc0", 0x1C),
> > +     EXYNOS9_PIN_BANK_EINTG(6, 0x100, "gpc1", 0x20),
> > +};
> > +
> > +static const struct samsung_pin_ctrl exynos850_pin_ctrl[] __initconst = {
> > +     {
> > +             /* pin-controller instance 0 ALIVE data */
> > +             .pin_banks      = exynos850_pin_banks0,
> > +             .nr_banks       = ARRAY_SIZE(exynos850_pin_banks0),
> > +             .eint_gpio_init = exynos_eint_gpio_init,
> > +             .eint_wkup_init = exynos_eint_wkup_init,
> > +     }, {
> > +             /* pin-controller instance 1 CMGP data */
> > +             .pin_banks      = exynos850_pin_banks1,
> > +             .nr_banks       = ARRAY_SIZE(exynos850_pin_banks1),
> > +             .eint_gpio_init = exynos_eint_gpio_init,
> > +             .eint_wkup_init = exynos_eint_wkup_init,
> > +     }, {
> > +             /* pin-controller instance 2 AUD data */
> > +             .pin_banks      = exynos850_pin_banks2,
> > +             .nr_banks       = ARRAY_SIZE(exynos850_pin_banks2),
> > +     }, {
> > +             /* pin-controller instance 3 HSI data */
> > +             .pin_banks      = exynos850_pin_banks3,
> > +             .nr_banks       = ARRAY_SIZE(exynos850_pin_banks3),
> > +             .eint_gpio_init = exynos_eint_gpio_init,
> > +     }, {
> > +             /* pin-controller instance 4 CORE data */
> > +             .pin_banks      = exynos850_pin_banks4,
> > +             .nr_banks       = ARRAY_SIZE(exynos850_pin_banks4),
> > +             .eint_gpio_init = exynos_eint_gpio_init,
> > +     }, {
> > +             /* pin-controller instance 5 PERI data */
> > +             .pin_banks      = exynos850_pin_banks5,
> > +             .nr_banks       = ARRAY_SIZE(exynos850_pin_banks5),
> > +             .eint_gpio_init = exynos_eint_gpio_init,
> > +     },
> > +};
> > +
> > +const struct samsung_pinctrl_of_match_data exynos850_of_data __initconst = {
> > +     .ctrl           = exynos850_pin_ctrl,
> > +     .num_ctrl       = ARRAY_SIZE(exynos850_pin_ctrl),
> > +};
> > diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
> > index da1ec13697e7..595086f2d5dd 100644
> > --- a/drivers/pinctrl/samsung/pinctrl-exynos.h
> > +++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
> > @@ -108,6 +108,35 @@
> >               .pctl_res_idx   = pctl_idx,                     \
> >       }                                                       \
> >
> > +#define EXYNOS9_PIN_BANK_EINTN(pins, reg, id)                        \
> > +     {                                                       \
> > +             .type           = &exynos850_bank_type_alive,   \
>
> Having the prefix EXYNOS9 is actually confusing because:
> 1. There is no Exynos9 support,
> 2. The type is exynos850.
>
> Let's keep it consistent, so 850 everywhere,
>

Sure. Will send v3 shortly with fixes for everything you mentioned.

> > +             .pctl_offset    = reg,                          \
> > +             .nr_pins        = pins,                         \
> > +             .eint_type      = EINT_TYPE_NONE,               \
> > +             .name           = id                            \
> > +     }
> > +
> > +#define EXYNOS9_PIN_BANK_EINTG(pins, reg, id, offs)          \
> > +     {                                                       \
> > +             .type           = &exynos850_bank_type_off,     \
> > +             .pctl_offset    = reg,                          \
> > +             .nr_pins        = pins,                         \
> > +             .eint_type      = EINT_TYPE_GPIO,               \
> > +             .eint_offset    = offs,                         \
> > +             .name           = id                            \
> > +     }
> > +
> > +#define EXYNOS9_PIN_BANK_EINTW(pins, reg, id, offs)          \
> > +     {                                                       \
> > +             .type           = &exynos850_bank_type_alive,   \
> > +             .pctl_offset    = reg,                          \
> > +             .nr_pins        = pins,                         \
> > +             .eint_type      = EINT_TYPE_WKUP,               \
> > +             .eint_offset    = offs,                         \
> > +             .name           = id                            \
> > +     }
> > +
>
> Best regards,
> Krzysztof


From oupton at google.com  Mon Aug  9 11:21:22 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 11:21:22 -0700
Subject: [PATCH 12/13] arm64: Add a capability for FEAT_EVC
In-Reply-To: <87k0kubio6.wl-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-13-maz@kernel.org>
 <CAOQ_QsjT8DUoXQsxWGgGiZkwNe2itRswGomtq6-p+7_oU01orQ@mail.gmail.com>
 <87k0kubio6.wl-maz@kernel.org>
Message-ID: <CAOQ_Qsi6gL9R4Hc2-Ljc0E2uN4qu5upsxaEHTz0fY9CWuF1rVQ@mail.gmail.com>

On Mon, Aug 9, 2021 at 11:02 AM Marc Zyngier <maz at kernel.org> wrote:
>
> Hi Oliver,
>
> Thanks for having a look.
>
> On Mon, 09 Aug 2021 17:30:45 +0100,
> Oliver Upton <oupton at google.com> wrote:
> >
> > Hi Marc,
> >
> > On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > Add a new capability to detect the Enhanced Counter Virtualization
> > > feature (FEAT_EVC).
> > >
> >
> > s/FEAT_EVC/FEAT_ECV/g
>
> I'm the knig fo tpyoes :).
>
> >
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > ---
> > >  arch/arm64/kernel/cpufeature.c | 10 ++++++++++
> > >  arch/arm64/tools/cpucaps       |  1 +
> > >  2 files changed, 11 insertions(+)
> > >
> > > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > > index 0ead8bfedf20..9c2ce5408811 100644
> > > --- a/arch/arm64/kernel/cpufeature.c
> > > +++ b/arch/arm64/kernel/cpufeature.c
> > > @@ -1899,6 +1899,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
> > >                 .sign = FTR_UNSIGNED,
> > >                 .min_field_value = 1,
> > >         },
> > > +       {
> > > +               .desc = "Enhanced counter virtualization",
> > > +               .capability = ARM64_HAS_ECV,
> > > +               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
> > > +               .matches = has_cpuid_feature,
> > > +               .sys_reg = SYS_ID_AA64MMFR0_EL1,
> > > +               .field_pos = ID_AA64MMFR0_ECV_SHIFT,
> > > +               .sign = FTR_UNSIGNED,
> > > +               .min_field_value = 1,
> > > +       },
> >
> > Per one of your other patches in the series, it sounds like userspace
> > access to the self-synchronized registers hasn't been settled yet.
> > However, if/when available to userspace, should this cpufeature map to
> > an ELF HWCAP?
>
> We can't prevent the access to userspace, unless we also trap
> cntvct_el0 and cntfreq_el0. Which we try not to do. But you are indeed
> correct, we probably have a HWCAP if we decide to advertise it to
> userspace.
>
> > Also, w.r.t. my series I have out for ECV in KVM. All the controls
> > used in EL2 depend on ECV=0x2. I agree that ECV=0x1 needs a cpufeature
> > bit, but what about EL2's use case?
>
> My idea was to have a ARM64_HAS_ECV2 to capture the EL2 extensions
> with min_field_value=2.

This SGTM. I imagine with your HWCAP patch you will be passing through
ID_AA64MMFR0_EL1.ECV to userspace too. Dunno if we should clamp to 1
or let userspace see ECV=2 when we enumerate the second cpufeature.
Definitely not worthy of a HWCAP, though.

--
Thanks,
Oliver


> > Besides the typo:
> >
> > Reviewed-by: Oliver Upton <oupton at google.com>
>
> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


From andreyknvl at gmail.com  Mon Aug  9 11:21:46 2021
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Mon, 9 Aug 2021 20:21:46 +0200
Subject: [PATCH v3 3/3] kasan: arm64: Fix pcpu_page_first_chunk crash with
 KASAN_VMALLOC
In-Reply-To: <20210809093750.131091-4-wangkefeng.wang@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <20210809093750.131091-4-wangkefeng.wang@huawei.com>
Message-ID: <CA+fCnZcL7tv=HsXJjXMayjASeAriy6N0HJwCoH7iPZZ6hqZGQw@mail.gmail.com>

On Mon, Aug 9, 2021 at 11:32 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
> With KASAN_VMALLOC and NEED_PER_CPU_PAGE_FIRST_CHUNK, it crashs,
>
> Unable to handle kernel paging request at virtual address ffff7000028f2000
> ...
> swapper pgtable: 64k pages, 48-bit VAs, pgdp=0000000042440000
> [ffff7000028f2000] pgd=000000063e7c0003, p4d=000000063e7c0003, pud=000000063e7c0003, pmd=000000063e7b0003, pte=0000000000000000
> Internal error: Oops: 96000007 [#1] PREEMPT SMP
> Modules linked in:
> CPU: 0 PID: 0 Comm: swapper Not tainted 5.13.0-rc4-00003-gc6e6e28f3f30-dirty #62
> Hardware name: linux,dummy-virt (DT)
> pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO BTYPE=--)
> pc : kasan_check_range+0x90/0x1a0
> lr : memcpy+0x88/0xf4
> sp : ffff80001378fe20
> ...
> Call trace:
>  kasan_check_range+0x90/0x1a0
>  pcpu_page_first_chunk+0x3f0/0x568
>  setup_per_cpu_areas+0xb8/0x184
>  start_kernel+0x8c/0x328
>
> The vm area used in vm_area_register_early() has no kasan shadow memory,
> Let's add a new kasan_populate_early_vm_area_shadow() function to populate
> the vm area shadow memory to fix the issue.
>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  arch/arm64/mm/kasan_init.c | 16 ++++++++++++++++
>  include/linux/kasan.h      |  6 ++++++
>  mm/kasan/init.c            |  5 +++++
>  mm/vmalloc.c               |  1 +
>  4 files changed, 28 insertions(+)
>
> diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
> index 61b52a92b8b6..5b996ca4d996 100644
> --- a/arch/arm64/mm/kasan_init.c
> +++ b/arch/arm64/mm/kasan_init.c
> @@ -287,6 +287,22 @@ static void __init kasan_init_depth(void)
>         init_task.kasan_depth = 0;
>  }
>
> +#ifdef CONFIG_KASAN_VMALLOC
> +void __init kasan_populate_early_vm_area_shadow(void *start, unsigned long size)
> +{
> +       unsigned long shadow_start, shadow_end;
> +
> +       if (!is_vmalloc_or_module_addr(start))
> +               return;
> +
> +       shadow_start = (unsigned long)kasan_mem_to_shadow(start);
> +       shadow_start = ALIGN_DOWN(shadow_start, PAGE_SIZE);
> +       shadow_end = (unsigned long)kasan_mem_to_shadow(start + size);
> +       shadow_end = ALIGN(shadow_end, PAGE_SIZE);
> +       kasan_map_populate(shadow_start, shadow_end, NUMA_NO_NODE);
> +}
> +#endif
> +
>  void __init kasan_init(void)
>  {
>         kasan_init_shadow();
> diff --git a/include/linux/kasan.h b/include/linux/kasan.h
> index dd874a1ee862..3f8c26d9ef82 100644
> --- a/include/linux/kasan.h
> +++ b/include/linux/kasan.h
> @@ -133,6 +133,8 @@ struct kasan_cache {
>         bool is_kmalloc;
>  };
>
> +void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
> +
>  slab_flags_t __kasan_never_merge(void);
>  static __always_inline slab_flags_t kasan_never_merge(void)
>  {
> @@ -303,6 +305,10 @@ void kasan_restore_multi_shot(bool enabled);
>
>  #else /* CONFIG_KASAN */
>
> +static inline void kasan_populate_early_vm_area_shadow(void *start,
> +                                                      unsigned long size)
> +{ }
> +
>  static inline slab_flags_t kasan_never_merge(void)
>  {
>         return 0;
> diff --git a/mm/kasan/init.c b/mm/kasan/init.c
> index cc64ed6858c6..d39577d088a1 100644
> --- a/mm/kasan/init.c
> +++ b/mm/kasan/init.c
> @@ -279,6 +279,11 @@ int __ref kasan_populate_early_shadow(const void *shadow_start,
>         return 0;
>  }
>
> +void __init __weak kasan_populate_early_vm_area_shadow(void *start,
> +                                                      unsigned long size)
> +{
> +}
> +
>  static void kasan_free_pte(pte_t *pte_start, pmd_t *pmd)
>  {
>         pte_t *pte;
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 1e8fe08725b8..66a7e1ea2561 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -2253,6 +2253,7 @@ void __init vm_area_register_early(struct vm_struct *vm, size_t align)
>         vm->addr = (void *)addr;
>
>         vm_area_add_early(vm);
> +       kasan_populate_early_vm_area_shadow(vm->addr, vm->size);
>  }
>
>  static void vmap_init_free_space(void)
> --
> 2.26.2
>

Acked-by: Andrey Konovalov <andreyknvl at gmail.com>

for KASAN parts.

Thanks!


From oupton at google.com  Mon Aug  9 11:23:32 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 11:23:32 -0700
Subject: [PATCH 12/13] arm64: Add a capability for FEAT_EVC
In-Reply-To: <CAOQ_Qsi6gL9R4Hc2-Ljc0E2uN4qu5upsxaEHTz0fY9CWuF1rVQ@mail.gmail.com>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-13-maz@kernel.org>
 <CAOQ_QsjT8DUoXQsxWGgGiZkwNe2itRswGomtq6-p+7_oU01orQ@mail.gmail.com>
 <87k0kubio6.wl-maz@kernel.org>
 <CAOQ_Qsi6gL9R4Hc2-Ljc0E2uN4qu5upsxaEHTz0fY9CWuF1rVQ@mail.gmail.com>
Message-ID: <CAOQ_QsgQhBcnOxbanhmWoNQsKUQJUkLJZCOOBDtOC29guugKrA@mail.gmail.com>

Oh, one more thing,

On Mon, Aug 9, 2021 at 11:21 AM Oliver Upton <oupton at google.com> wrote:
>
> On Mon, Aug 9, 2021 at 11:02 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > Hi Oliver,
> >
> > Thanks for having a look.
> >
> > On Mon, 09 Aug 2021 17:30:45 +0100,
> > Oliver Upton <oupton at google.com> wrote:
> > >
> > > Hi Marc,
> > >
> > > On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > Add a new capability to detect the Enhanced Counter Virtualization
> > > > feature (FEAT_EVC).
> > > >
> > >
> > > s/FEAT_EVC/FEAT_ECV/g
> >
> > I'm the knig fo tpyoes :).
> >
> > >
> > > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > > ---
> > > >  arch/arm64/kernel/cpufeature.c | 10 ++++++++++
> > > >  arch/arm64/tools/cpucaps       |  1 +
> > > >  2 files changed, 11 insertions(+)
> > > >
> > > > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > > > index 0ead8bfedf20..9c2ce5408811 100644
> > > > --- a/arch/arm64/kernel/cpufeature.c
> > > > +++ b/arch/arm64/kernel/cpufeature.c
> > > > @@ -1899,6 +1899,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
> > > >                 .sign = FTR_UNSIGNED,
> > > >                 .min_field_value = 1,
> > > >         },
> > > > +       {
> > > > +               .desc = "Enhanced counter virtualization",

Pesky nit: "Enhanced Counter Virtualization"

> > > > +               .capability = ARM64_HAS_ECV,
> > > > +               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
> > > > +               .matches = has_cpuid_feature,
> > > > +               .sys_reg = SYS_ID_AA64MMFR0_EL1,
> > > > +               .field_pos = ID_AA64MMFR0_ECV_SHIFT,
> > > > +               .sign = FTR_UNSIGNED,
> > > > +               .min_field_value = 1,
> > > > +       },
> > >
> > > Per one of your other patches in the series, it sounds like userspace
> > > access to the self-synchronized registers hasn't been settled yet.
> > > However, if/when available to userspace, should this cpufeature map to
> > > an ELF HWCAP?
> >
> > We can't prevent the access to userspace, unless we also trap
> > cntvct_el0 and cntfreq_el0. Which we try not to do. But you are indeed
> > correct, we probably have a HWCAP if we decide to advertise it to
> > userspace.
> >
> > > Also, w.r.t. my series I have out for ECV in KVM. All the controls
> > > used in EL2 depend on ECV=0x2. I agree that ECV=0x1 needs a cpufeature
> > > bit, but what about EL2's use case?
> >
> > My idea was to have a ARM64_HAS_ECV2 to capture the EL2 extensions
> > with min_field_value=2.
>
> This SGTM. I imagine with your HWCAP patch you will be passing through
> ID_AA64MMFR0_EL1.ECV to userspace too. Dunno if we should clamp to 1
> or let userspace see ECV=2 when we enumerate the second cpufeature.
> Definitely not worthy of a HWCAP, though.
>
> --
> Thanks,
> Oliver
>
>
> > > Besides the typo:
> > >
> > > Reviewed-by: Oliver Upton <oupton at google.com>
> >
> > Thanks,
> >
> >         M.
> >
> > --
> > Without deviation from the norm, progress is not possible.


From robdclark at gmail.com  Mon Aug  9 11:30:45 2021
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 9 Aug 2021 11:30:45 -0700
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent masters
 to use system cache
In-Reply-To: <8e5edd6886a0c3a5f6c8cb4dff517224@codeaurora.org>
References: <20210728140052.GB22887@mms-0441>
 <8b2742c8891abe4fec3664730717a089@codeaurora.org>
 <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
 <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
 <20210809145651.GC1458@willie-the-truck>
 <CAF6AEGsSUojA=V0n2iRWTCn++buqN=Eoxo0r3=+=PBu1O=H-AQ@mail.gmail.com>
 <20210809170508.GB1589@willie-the-truck>
 <CAF6AEGtmZ3LzAJdtnKDQDbEN-a6_JgdN-fZ96pkU3dZqkiW91g@mail.gmail.com>
 <20210809174022.GA1840@willie-the-truck>
 <76bfd0b4248148dfbf9d174ddcb4c2a2@codeaurora.org>
 <CAF6AEGtiVgHc7rcfzOpBmtVGQBvGPCBmtKJ3AJx887NSMj0EzQ@mail.gmail.com>
 <8e5edd6886a0c3a5f6c8cb4dff517224@codeaurora.org>
Message-ID: <CAF6AEGut0LFFLmR7WV66HkDee4dg5xusTmFC23zsUGqjZuoNpw@mail.gmail.com>

On Mon, Aug 9, 2021 at 11:11 AM Sai Prakash Ranjan
<saiprakash.ranjan at codeaurora.org> wrote:
>
> On 2021-08-09 23:37, Rob Clark wrote:
> > On Mon, Aug 9, 2021 at 10:47 AM Sai Prakash Ranjan
> > <saiprakash.ranjan at codeaurora.org> wrote:
> >>
> >> On 2021-08-09 23:10, Will Deacon wrote:
> >> > On Mon, Aug 09, 2021 at 10:18:21AM -0700, Rob Clark wrote:
> >> >> On Mon, Aug 9, 2021 at 10:05 AM Will Deacon <will at kernel.org> wrote:
> >> >> >
> >> >> > On Mon, Aug 09, 2021 at 09:57:08AM -0700, Rob Clark wrote:
> >> >> > > On Mon, Aug 9, 2021 at 7:56 AM Will Deacon <will at kernel.org> wrote:
> >> >> > > > On Mon, Aug 02, 2021 at 06:36:04PM -0700, Rob Clark wrote:
> >> >> > > > > On Mon, Aug 2, 2021 at 8:14 AM Will Deacon <will at kernel.org> wrote:
> >> >> > > > > > On Mon, Aug 02, 2021 at 08:08:07AM -0700, Rob Clark wrote:
> >> >> > > > > > > On Mon, Aug 2, 2021 at 3:55 AM Will Deacon <will at kernel.org> wrote:
> >> >> > > > > > > > On Thu, Jul 29, 2021 at 10:08:22AM +0530, Sai Prakash Ranjan wrote:
> >> >> > > > > > > > > On 2021-07-28 19:30, Georgi Djakov wrote:
> >> >> > > > > > > > > > On Mon, Jan 11, 2021 at 07:45:02PM +0530, Sai Prakash Ranjan wrote:
> >> >> > > > > > > > > > > commit ecd7274fb4cd ("iommu: Remove unused IOMMU_SYS_CACHE_ONLY flag")
> >> >> > > > > > > > > > > removed unused IOMMU_SYS_CACHE_ONLY prot flag and along with it went
> >> >> > > > > > > > > > > the memory type setting required for the non-coherent masters to use
> >> >> > > > > > > > > > > system cache. Now that system cache support for GPU is added, we will
> >> >> > > > > > > > > > > need to set the right PTE attribute for GPU buffers to be sys cached.
> >> >> > > > > > > > > > > Without this, the system cache lines are not allocated for GPU.
> >> >> > > > > > > > > > >
> >> >> > > > > > > > > > > So the patches in this series introduces a new prot flag IOMMU_LLC,
> >> >> > > > > > > > > > > renames IO_PGTABLE_QUIRK_ARM_OUTER_WBWA to IO_PGTABLE_QUIRK_PTW_LLC
> >> >> > > > > > > > > > > and makes GPU the user of this protection flag.
> >> >> > > > > > > > > >
> >> >> > > > > > > > > > Thank you for the patchset! Are you planning to refresh it, as it does
> >> >> > > > > > > > > > not apply anymore?
> >> >> > > > > > > > > >
> >> >> > > > > > > > >
> >> >> > > > > > > > > I was waiting on Will's reply [1]. If there are no changes needed, then
> >> >> > > > > > > > > I can repost the patch.
> >> >> > > > > > > >
> >> >> > > > > > > > I still think you need to handle the mismatched alias, no? You're adding
> >> >> > > > > > > > a new memory type to the SMMU which doesn't exist on the CPU side. That
> >> >> > > > > > > > can't be right.
> >> >> > > > > > > >
> >> >> > > > > > >
> >> >> > > > > > > Just curious, and maybe this is a dumb question, but what is your
> >> >> > > > > > > concern about mismatched aliases?  I mean the cache hierarchy on the
> >> >> > > > > > > GPU device side (anything beyond the LLC) is pretty different and
> >> >> > > > > > > doesn't really care about the smmu pgtable attributes..
> >> >> > > > > >
> >> >> > > > > > If the CPU accesses a shared buffer with different attributes to those which
> >> >> > > > > > the device is using then you fall into the "mismatched memory attributes"
> >> >> > > > > > part of the Arm architecture. It's reasonably unforgiving (you should go and
> >> >> > > > > > read it) and in some cases can apply to speculative accesses as well, but
> >> >> > > > > > the end result is typically loss of coherency.
> >> >> > > > >
> >> >> > > > > Ok, I might have a few other sections to read first to decipher the
> >> >> > > > > terminology..
> >> >> > > > >
> >> >> > > > > But my understanding of LLC is that it looks just like system memory
> >> >> > > > > to the CPU and GPU (I think that would make it "the point of
> >> >> > > > > coherence" between the GPU and CPU?)  If that is true, shouldn't it be
> >> >> > > > > invisible from the point of view of different CPU mapping options?
> >> >> > > >
> >> >> > > > You could certainly build a system where mismatched attributes don't cause
> >> >> > > > loss of coherence, but as it's not guaranteed by the architecture and the
> >> >> > > > changes proposed here affect APIs which are exposed across SoCs, then I
> >> >> > > > don't think it helps much.
> >> >> > > >
> >> >> > >
> >> >> > > Hmm, the description of the new mapping flag is that it applies only
> >> >> > > to transparent outer level cache:
> >> >> > >
> >> >> > > +/*
> >> >> > > + * Non-coherent masters can use this page protection flag to set cacheable
> >> >> > > + * memory attributes for only a transparent outer level of cache, also known as
> >> >> > > + * the last-level or system cache.
> >> >> > > + */
> >> >> > > +#define IOMMU_LLC      (1 << 6)
> >> >> > >
> >> >> > > But I suppose we could call it instead IOMMU_QCOM_LLC or something
> >> >> > > like that to make it more clear that it is not necessarily something
> >> >> > > that would work with a different outer level cache implementation?
> >> >> >
> >> >> > ... or we could just deal with the problem so that other people can reuse
> >> >> > the code. I haven't really understood the reluctance to solve this properly.
> >> >> >
> >> >> > Am I missing some reason this isn't solvable?
> >> >>
> >> >> Oh, was there another way to solve it (other than foregoing setting
> >> >> INC_OCACHE in the pgtables)?  Maybe I misunderstood, is there a
> >> >> corresponding setting on the MMU pgtables side of things?
> >> >
> >> > Right -- we just need to program the CPU's MMU with the matching memory
> >> > attributes! It's a bit more fiddly if you're just using ioremap_wc()
> >> > though, as it's usually the DMA API which handles the attributes under
> >> > the
> >> > hood.
> >> >
> >> > Anyway, sorry, I should've said that explicitly earlier on. We've done
> >> > this
> >> > sort of thing in the Android tree so I assumed Sai knew what needed to
> >> > be
> >> > done and then I didn't think to explain to you :(
> >> >
> >>
> >> Right I was aware of that but even in the android tree there is no
> >> user
> >> :)
> >> I think we can't have a new memory type without any user right in
> >> upstream
> >> like android tree?
> >>
> >> @Rob, I think you  already tried adding a new MT and used
> >> pgprot_syscached()
> >> in GPU driver but it was crashing?
> >
> > Correct, but IIRC there were some differences in the code for memory
> > types compared to the android tree.. I couldn't figure out the
> > necessary patches to cherry-pick to get the android patch to apply
> > cleanly, so I tried re-implementing it without having much of a clue
> > about how that code works (which was probably the issue) ;-)
> >
>
> Hehe no, even I get the same crash after porting/modifying the required
> patches from android ;) and I think crashes would be seen in android as
> well, its just that they don't have any user exercising that code.
>
> Thing is I can't make head and tail of the GPU crash logs, maybe you
> know
> how to decode those errors, if not I can start a thread with QC GPU team
> and ask them to decode?
>

If you have a gpu devcore dump, I can take a look at it with
crashdec.. otherwise I can try to find the branch where I had that
patch backported.

I'm more familiar with using crashdec to figure out mesa bugs, but
maybe I could spot something where what the GPU is seeing disagrees
with what the CPU expects it to be seeing.

BR,
-R


From lkp at intel.com  Mon Aug  9 11:26:20 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 10 Aug 2021 02:26:20 +0800
Subject: [PATCH] Bluetooth: btusb: Remove WAKEUP_DISABLE and add
 WAKEUP_AUTOSUSPEND  for Realtek devices
In-Reply-To: <20210809130152.12528-1-max.chou@realtek.com>
References: <20210809130152.12528-1-max.chou@realtek.com>
Message-ID: <202108100252.2RrOR5hK-lkp@intel.com>

Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on bluetooth/master]
[also build test ERROR on bluetooth-next/master v5.14-rc5 next-20210809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/max-chou-realtek-com/Bluetooth-btusb-Remove-WAKEUP_DISABLE-and-add-WAKEUP_AUTOSUSPEND-for-Realtek-devices/20210809-210601
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master
config: h8300-buildonly-randconfig-r001-20210809 (attached as .config)
compiler: h8300-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/a791e68679a17d6560048ebc7b8ca1ed4491a5b5
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review max-chou-realtek-com/Bluetooth-btusb-Remove-WAKEUP_DISABLE-and-add-WAKEUP_AUTOSUSPEND-for-Realtek-devices/20210809-210601
        git checkout a791e68679a17d6560048ebc7b8ca1ed4491a5b5
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=h8300 SHELL=/bin/bash drivers/bluetooth/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/bluetooth/btusb.c: In function 'btusb_prevent_wake':
>> drivers/bluetooth/btusb.c:4402:15: error: 'BTUSB_WAKEUP_DISABLE' undeclared (first use in this function)
    4402 |  if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
         |               ^~~~~~~~~~~~~~~~~~~~
   drivers/bluetooth/btusb.c:4402:15: note: each undeclared identifier is reported only once for each function it appears in


vim +/BTUSB_WAKEUP_DISABLE +4402 drivers/bluetooth/btusb.c

fc54910280eb38 Hans de Goede          2018-04-27  4397  
b7d0bf11a7ad0e Abhishek Pandit-Subedi 2020-05-12  4398  static bool btusb_prevent_wake(struct hci_dev *hdev)
b7d0bf11a7ad0e Abhishek Pandit-Subedi 2020-05-12  4399  {
b7d0bf11a7ad0e Abhishek Pandit-Subedi 2020-05-12  4400  	struct btusb_data *data = hci_get_drvdata(hdev);
b7d0bf11a7ad0e Abhishek Pandit-Subedi 2020-05-12  4401  
34a68655a1414a Abhishek Pandit-Subedi 2020-06-24 @4402  	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
34a68655a1414a Abhishek Pandit-Subedi 2020-06-24  4403  		return true;
34a68655a1414a Abhishek Pandit-Subedi 2020-06-24  4404  
b7d0bf11a7ad0e Abhishek Pandit-Subedi 2020-05-12  4405  	return !device_may_wakeup(&data->udev->dev);
b7d0bf11a7ad0e Abhishek Pandit-Subedi 2020-05-12  4406  }
b7d0bf11a7ad0e Abhishek Pandit-Subedi 2020-05-12  4407  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 39503 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210810/6c105b41/attachment-0001.gz>

From ezequiel.garcia at collabora.com  Mon Aug  9 11:36:30 2021
From: ezequiel.garcia at collabora.com (Ezequiel Garcia)
Date: Mon, 09 Aug 2021 19:36:30 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 05/10]
 =?utf-8?q?media=3A?==?utf-8?q?_uapi=3A?= 
 Add VP9 stateless decoder controls
In-Reply-To: <5154683.x8GX3iSW2O@kista>
Message-ID: <3ce7-61117580-f1-4ae96900@79504131>

Hi Jernej,

On Monday, August 09, 2021 15:04 -03, Jernej ?krabec <jernej.skrabec at gmail.com> wrote: 
 
> Hi Andrzej!
> 
> Dne ?etrtek, 05. avgust 2021 ob 16:42:41 CEST je Andrzej Pietrasiewicz 
> napisal(a):
> > Add the VP9 stateless decoder controls plus the documentation that goes
> > with it.
> > 
> > Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
> > Co-developed-by: Ezequiel Garcia <ezequiel at collabora.com>
> > Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
> > Signed-off-by: Adrian Ratiu <adrian.ratiu at collabora.com>
> > Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
> > Co-developed-by: Daniel Almeida <daniel.almeida at collabora.com>
> > Signed-off-by: Daniel Almeida <daniel.almeida at collabora.com>
> > ---
> >  .../userspace-api/media/v4l/biblio.rst        |  10 +
> >  .../media/v4l/ext-ctrls-codec-stateless.rst   | 545 ++++++++++++++++++
> >  .../media/v4l/pixfmt-compressed.rst           |  15 +
> >  .../media/v4l/vidioc-g-ext-ctrls.rst          |   8 +
> >  .../media/v4l/vidioc-queryctrl.rst            |  12 +
> >  .../media/videodev2.h.rst.exceptions          |   2 +
> >  drivers/media/v4l2-core/v4l2-ctrls-core.c     | 174 ++++++
> >  drivers/media/v4l2-core/v4l2-ctrls-defs.c     |   8 +
> >  drivers/media/v4l2-core/v4l2-ioctl.c          |   1 +
> >  include/media/v4l2-ctrls.h                    |   4 +
> >  include/uapi/linux/v4l2-controls.h            | 433 ++++++++++++++
> >  include/uapi/linux/videodev2.h                |   6 +
> >  12 files changed, 1218 insertions(+)
> > 
> 
> <snip>
> 
> > diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-
> controls.h
> > index 5532b5f68493..8f8c3c1ad885 100644
> > --- a/include/uapi/linux/v4l2-controls.h
> > +++ b/include/uapi/linux/v4l2-controls.h
> > @@ -2010,6 +2010,439 @@ struct v4l2_ctrl_hdr10_mastering_display {
> >  	__u32 min_display_mastering_luminance;
> >  };
> >  
> > +/* Stateless VP9 controls */
> > +
> > +/**
> > + * enum v4l2_vp9_loop_filter_flags - VP9 loop filter flags
> > + *
> > + * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED: the filter level depends on
> > + *	the mode and reference frame used to predict a block
> > + * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE: the bitstream contains 
> additional
> > + *	syntax elements that specify which mode and reference frame deltas 
> are to be updated
> > + *
> > + * Those are the flags that may be passed to &v4l2_vp9_loop_filter.flags. See
> > + * section '7.2.8 Loop filter semantics' of the VP9 specification for more
> > + * details.
> > + */
> > +enum v4l2_vp9_loop_filter_flags {
> > +	V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED = 1 << 0,
> > +	V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE = 1 << 1,
> > +};
> > +
> > +/**
> > + * struct v4l2_vp9_loop_filter - VP9 loop filter parameters
> > + *
> > + * @ref_deltas: contains the adjustment needed for the filter level based on 
> the chosen
> > + *	reference frame. If this syntax element is not present in the 
> bitstream, users
> > + *	should pass its last value.
> > + * @mode_deltas: contains the adjustment needed for the filter level based 
> on the chosen mode.
> > + *	If this syntax element is not present in the bitstream, users
> > + *	should pass its last value.
> > + * @level: indicates the loop filter strength
> > + * @sharpness: indicates the sharpness level
> > + * @flags: combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags
> > + * @reserved: padding field. Should be zeroed by applications.
> > + *
> > + * This structure contains all loop filter related parameters. See sections
> > + * '7.2.8 Loop filter semantics' of the VP9 specification for more details.
> > + */
> > +struct v4l2_vp9_loop_filter {
> > +	__s8 ref_deltas[4];
> > +	__s8 mode_deltas[2];
> > +	__u8 level;
> > +	__u8 sharpness;
> > +	__u8 flags;
> > +	__u8 reserved[7];
> > +};
> > +
> > +/**
> > + * struct v4l2_vp9_quantization - VP9 quantization parameters
> > + *
> > + * @base_q_idx: indicates the base frame qindex
> > + * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx
> > + * @delta_q_uv_dc: indicates the UV DC quantizer relative to base_q_idx
> > + * @delta_q_uv_ac: indicates the UV AC quantizer relative to base_q_idx
> > + * @reserved: padding field. Should be zeroed by applications.
> > + *
> > + * Encodes the quantization parameters. See section '7.2.9 Quantization 
> params
> > + * syntax' of the VP9 specification for more details.
> > + */
> > +struct v4l2_vp9_quantization {
> > +	__u8 base_q_idx;
> > +	__s8 delta_q_y_dc;
> > +	__s8 delta_q_uv_dc;
> > +	__s8 delta_q_uv_ac;
> > +	__u8 reserved[4];
> > +};
> > +
> > +/**
> > + * enum v4l2_vp9_segmentation_flags - VP9 segmentation flags
> > + *
> > + * @V4L2_VP9_SEGMENTATION_FLAG_ENABLED: indicates that this frame makes use 
> of
> > + *	the segmentation tool
> > + * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP: indicates that the segmentation 
> map
> > + *	should be updated during the decoding of this frame
> > + * @V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE: indicates that the updates 
> to
> > + *	the segmentation map are coded relative to the existing 
> segmentation map
> > + * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA: indicates that new parameters 
> are
> > + *	about to be specified for each segment
> > + * @V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE: indicates that the
> > + *	segmentation parameters represent the actual values to be used
> > + *
> > + * Those are the flags that may be passed to &v4l2_vp9_segmentation.flags. 
> See
> > + * section '7.2.10 Segmentation params syntax' of the VP9 specification for
> > + * more details.
> > + */
> > +enum v4l2_vp9_segmentation_flags {
> > +	V4L2_VP9_SEGMENTATION_FLAG_ENABLED = 1 << 0,
> > +	V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP = 1 << 1,
> > +	V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE = 1 << 2,
> > +	V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA = 1 << 3,
> > +	V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE = 1 << 4,
> > +};
> > +
> > +#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id)	(1 << (id))
> > +#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK	0xf
> > +
> > +/**
> > + * enum v4l2_vp9_segment_feature - VP9 segment feature IDs
> > + *
> > + * @V4L2_VP9_SEG_LVL_ALT_Q: quantizer segment feature
> > + * @V4L2_VP9_SEG_LVL_ALT_L: loop filter segment feature
> > + * @V4L2_VP9_SEG_LVL_REF_FRAME reference frame segment feature
> > + * @V4L2_VP9_SEG_LVL_SKIP: skip segment feature
> > + * @V4L2_VP9_SEG_LVV_MAX: number of segment features
> > + *
> > + * Segment feature IDs. See section '7.2.10 Segmentation params syntax' of 
> the
> > + * VP9 specification for more details.
> > + */
> > +enum v4l2_vp9_segment_feature {
> > +	V4L2_VP9_SEG_LVL_ALT_Q,
> > +	V4L2_VP9_SEG_LVL_ALT_L,
> > +	V4L2_VP9_SEG_LVL_REF_FRAME,
> > +	V4L2_VP9_SEG_LVL_SKIP,
> > +	V4L2_VP9_SEG_LVL_MAX,
> > +};
> 
> What is the reason not to assign values like 1 << 0, 1 << 1, etc. and instead 
> provide separate macro V4L2_VP9_SEGMENT_FEATURE_ENABLED()? This is a departure 
> from current practice.
> 

Fully agreed.

Thanks,
Ezequiel



From f.fainelli at gmail.com  Mon Aug  9 11:39:40 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 9 Aug 2021 11:39:40 -0700
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
Message-ID: <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>



On 8/8/2021 10:08 PM, Joakim Zhang wrote:
> 
> Hi Florian,
> 
>> -----Original Message-----
>> From: Florian Fainelli <f.fainelli at gmail.com>
>> Sent: 2021?8?5? 17:18
>> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
>> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
>> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
>> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
>> netdev at vger.kernel.org; devicetree at vger.kernel.org;
>> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
>> wakeup-irq" property
>>
>>
>>
>> On 8/5/2021 12:46 AM, Joakim Zhang wrote:
>>> Add "fsl,wakeup-irq" property for FEC controller to select wakeup irq
>>> source.
>>>
>>> Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
>>> Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
>>
>> Why are not you making use of the standard interrupts-extended property
>> which allows different interrupt lines to be originating from different interrupt
>> controllers, e.g.:
>>
>> interrupts-extended = <&gic GIC_SPI 112 4>, <&wakeup_intc 0>;
> 
> Thanks.
> 
> AFAIK, interrupts-extended should be used instead of interrupts when a device is connected to multiple interrupt controllers
> as it encodes a parent phandle with each interrupt specifier. However, for FEC controller, all interrupt lines are originating from
> the same interrupt controllers.

OK, so why this custom property then?

> 
> 1) FEC controller has up to 4 interrupt lines and all of these are routed to GIC interrupt controller.
> 2) FEC has a wakeup interrupt signal and always are mixed with other interrupt signals, and then output to one interrupt line.
> 3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but for i.MX8M serials, are mixed to int2 line.
> 4) Now driver treat int0 as the wakeup source by default, it is broken for i.MX8M.

I don't really know what to make of your response, it seems to me that 
you are carrying some legacy Device Tree properties that were invented 
when interrupts-extended did not exist and we did not know any better.
-- 
Florian


From semen.protsenko at linaro.org  Mon Aug  9 11:51:48 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 9 Aug 2021 21:51:48 +0300
Subject: [PATCH v2 7/8] clk: samsung: Add Exynos850 clock driver stub
In-Reply-To: <7110b1e2-1aee-6ddf-803f-ee392e494f2d@canonical.com>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-8-semen.protsenko@linaro.org>
 <7110b1e2-1aee-6ddf-803f-ee392e494f2d@canonical.com>
Message-ID: <CAPLW+4=yK-dfWjKjLEOKL2o2sG1eyqSNqgVCnQNYvbUHo+Om4w@mail.gmail.com>

On Mon, 9 Aug 2021 at 13:55, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 06/08/2021 17:21, Sam Protsenko wrote:
> > For now it's just a stub driver to make the serial driver work. Later it
> > will be implemented properly. This driver doesn't really change clocks,
> > only registers the UART clock as a fixed-rate clock. Without this clock
> > driver the UART driver won't work, as it's trying to obtain "uart" clock
> > and fails if it's not able to.
>
> You know that as temporary solution you can add necessary clocks
> directly in your DTS as fixed-rate-clocks? Effect would be quite similar
> to the one here for UART driver but instead adding some temporary code
> you would add temporary DTS nodes and references.
>
> I am fine with this approach although the binding (if ever defined...)
> would need to be marked as experimental.
>

Let's keep this driver then. My next step would be implementing the
proper clk driver, so this review would be a good starting point for
me. I will, of course, address your other comments.

> >
> > In order to get a functional serial console we have to implement that
> > minimal clock driver with "uart" clock. It's not necessary to actually
> > configure clocks, as those are already configured in bootloader, so
> > kernel can rely on that for now.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> > Changes in v2:
> >   - Used hard coded clock indexes, as clock bindings were removed; will
> >     add clock bindings back (reimplemented) once proper clock driver is
> >     ready
> >   - Removed .data = 0 for exynos850-oscclk, as it's in BSS section
> >   - Removed comma for terminator {}
> >   - Made exynos850_clk_init() static
> >   - Removed checking np for NULL, as it's already done in of_iomap()
> >
> >  drivers/clk/samsung/Makefile        |  1 +
> >  drivers/clk/samsung/clk-exynos850.c | 64 +++++++++++++++++++++++++++++
> >  2 files changed, 65 insertions(+)
> >  create mode 100644 drivers/clk/samsung/clk-exynos850.c
> >
> > diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> > index 028b2e27a37e..c46cf11e4d0b 100644
> > --- a/drivers/clk/samsung/Makefile
> > +++ b/drivers/clk/samsung/Makefile
> > @@ -17,6 +17,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)       += clk-exynos5433.o
> >  obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
> >  obj-$(CONFIG_EXYNOS_CLKOUT)  += clk-exynos-clkout.o
> >  obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)        += clk-exynos7.o
> > +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)        += clk-exynos850.o
> >  obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
> >  obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
> >  obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
> > diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
> > new file mode 100644
> > index 000000000000..36c7c7fe7cf0
> > --- /dev/null
> > +++ b/drivers/clk/samsung/clk-exynos850.c
> > @@ -0,0 +1,64 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
> > + * Copyright (C) 2021 Linaro Ltd.
> > + *
> > + * Common Clock Framework support for Exynos850 SoC.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clkdev.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +
> > +#include "clk.h"
> > +
> > +/* Will be extracted to bindings header once proper clk driver is implemented */
> > +#define OSCCLK               1
> > +#define DOUT_UART    2
> > +#define CLK_NR_CLKS  3
> > +
> > +/* Fixed rate clocks generated outside the SoC */
> > +static struct samsung_fixed_rate_clock exynos850_fixed_rate_ext_clks[] __initdata = {
> > +     FRATE(OSCCLK, "fin_pll", NULL, 0, 26000000),
> > +};
> > +
> > +/*
> > + * Model the UART clock as a fixed-rate clock for now, to make serial driver
> > + * work. This clock is already configured in the bootloader.
> > + */
> > +static const struct samsung_fixed_rate_clock exynos850_peri_clks[] __initconst = {
> > +     FRATE(DOUT_UART, "DOUT_UART", NULL, 0, 200000000),
> > +};
> > +
> > +static const struct of_device_id ext_clk_match[] __initconst = {
> > +     { .compatible = "samsung,exynos850-oscclk" },
> > +     {}
> > +};
> > +
> > +static void __init exynos850_clk_init(struct device_node *np)
> > +{
> > +     void __iomem *reg_base;
> > +     struct samsung_clk_provider *ctx;
> > +
> > +     reg_base = of_iomap(np, 0);
> > +     if (!reg_base)
> > +             panic("%s: failed to map registers\n", __func__);
> > +
> > +     ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
> > +     if (!ctx)
> > +             panic("%s: unable to allocate ctx\n", __func__);
>
> Not needed, the samsung_clk_init() panics or returns valid memory.
>

Done. Btw, I noticed that similar check is present in clk-exynos5433.c.

> > +
> > +     samsung_clk_of_register_fixed_ext(ctx,
> > +                     exynos850_fixed_rate_ext_clks,
> > +                     ARRAY_SIZE(exynos850_fixed_rate_ext_clks),
> > +                     ext_clk_match);
> > +
> > +     samsung_clk_register_fixed_rate(ctx, exynos850_peri_clks,
> > +                     ARRAY_SIZE(exynos850_peri_clks));
> > +
> > +     samsung_clk_of_add_provider(np, ctx);
> > +}
> > +
> > +CLK_OF_DECLARE(exynos850_clk, "samsung,exynos850-clock", exynos850_clk_init);
> >
>
> Best regards,
> Krzysztof


From aford173 at gmail.com  Mon Aug  9 11:51:55 2021
From: aford173 at gmail.com (Adam Ford)
Date: Mon, 9 Aug 2021 13:51:55 -0500
Subject: [PATCH v2 00/18] i.MX8MM GPC improvements and BLK_CTRL driver
In-Reply-To: <befbf918-c14a-e97c-a8d5-f5fe874dfa94@kontron.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <818b52fe-8fa6-b47a-6dde-783ac378c603@kontron.de>
 <8de1cd0a-4d91-60e2-61e6-9f903bbf546b@kontron.de>
 <8ea33d97fb3f7abb2d80b11db28cce8c01932a09.camel@pengutronix.de>
 <befbf918-c14a-e97c-a8d5-f5fe874dfa94@kontron.de>
Message-ID: <CAHCN7xKkgNbVJNX57192z0X1DqiGje-CEAV9LA+EAPROtO2P3A@mail.gmail.com>

On Mon, Aug 9, 2021 at 6:50 AM Frieder Schrempf
<frieder.schrempf at kontron.de> wrote:
>
> On 09.08.21 13:01, Lucas Stach wrote:
> > Hi Frieder,
> >
> > Am Donnerstag, dem 05.08.2021 um 20:56 +0200 schrieb Frieder Schrempf:
> >> On 05.08.21 12:18, Frieder Schrempf wrote:
> >>> On 21.07.21 22:46, Lucas Stach wrote:
> >>>> Hi all,
> >>>>
> >>>> second revision of the GPC improvements and BLK_CTRL driver to make use
> >>>> of all the power-domains on the i.MX8MM. I'm not going to repeat the full
> >>>> blurb from the v1 cover letter here, but if you are not familiar with
> >>>> i.MX8MM power domains, it may be worth a read.
> >>>>
> >>>> This 2nd revision fixes the DT bindings to be valid yaml, some small
> >>>> failure path issues and most importantly the interaction with system
> >>>> suspend/resume. With the previous version some of the power domains
> >>>> would not come up correctly after a suspend/resume cycle.
> >>>>
> >>>> Updated testing git trees here, disclaimer still applies:
> >>>> https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.pengutronix.de%2Fcgit%2Flst%2Flinux%2Flog%2F%3Fh%3Dimx8m-power-domains&amp;data=04%7C01%7Cfrieder.schrempf%40kontron.de%7C189884f9332e40cd566a08d95b250a82%7C8c9d3c973fd941c8a2b1646f3942daf1%7C0%7C0%7C637641036912506485%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=OlymcyF9VOt6nsb2E%2BpFLTBnmlpOIOxwzdBbggPu%2FHo%3D&amp;reserved=0
> >>>> https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.pengutronix.de%2Fcgit%2Flst%2Flinux%2Flog%2F%3Fh%3Dimx8m-power-domains-testing&amp;data=04%7C01%7Cfrieder.schrempf%40kontron.de%7C189884f9332e40cd566a08d95b250a82%7C8c9d3c973fd941c8a2b1646f3942daf1%7C0%7C0%7C637641036912506485%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=XSHl3JDKPFX%2FifXK5fcMQFOXbQXuHOJaNnJ3%2BtrMErk%3D&amp;reserved=0
> >>>
> >>> I finally did some tests on my side using USB, GPU and DSI (no PCIe, VPU, CSI so far) and the results are promising. Thanks for the effort!
> >>>
> >>> I will try to run some more automated suspend/resume and reboot test cycles over the weekend and report the results here afterwards.
> >>>
> >>
> >> Unfortunately I got some results sooner than I had hoped. I set up a simple loop to suspend/resume every few seconds and on the first run it took around 2-3 hours for the device to lock up on resume. On the second run it took less than half an hour. I had glmark2-es2-drm running in the background, but it looks like it crashed at some point before the lockup occurred.
> >>
> >> Of course this could also be unrelated and caused by some peripheral driver or something but the first suspicion is definitely the power domains.
> >>
> >> If you have any suggestions for which debug options to enable or where to add some printks, please let me know. If I do another run I would like to make sure that the resulting logs are helpful for debugging.
> >>
> >> And I would appreciate if someone else could try to reproduce this problem on his/her side. I use this simple script for testing:
> >>
> >> #!/bin/sh
> >>
> >> glmark2-es2-drm &
> >>
> >> while true;
> >> do
> >>     echo +10 > /sys/class/rtc/rtc0/wakealarm
> >>     echo mem > /sys/power/state
> >>     sleep 5
> >> done;
> >
> > Hm, that's unfortunate.
> >
> > I'm back from a two week vacation, but it looks like I won't have much
> > time available to look into this issue soon. It would be very helpful
> > if you could try to pinpoint the hang a bit more.  If you can reproduce
> > the hang with no_console_suspend you might be able to extract a bit
> > more info in which stage the hang happens (suspend, resume, TF-A, etc.)
> > If the hang is in the kernel you might be able to add some prints to
> > the suspend/resume paths to be able to track down the exact point of
> > the hang.
> >
> > I'm happy to look into the issue once it's better known where to look,
> > but I fear that I won't have time to do the above investigation myself
> > short term. Frieder, is this something you could help with over the
> > next few days?
>
> I will see if I can find some time to track down the issue at least a little bit more. But I imagine it could get quite tedious if it takes up to several hours to reproduce the issue and I don't have much time to spare.
>
> @Peng, @Adam and everyone else: Any chance you could setup a similar test and try to reproduce this?

right now i am on medical leave due to a broken wrist, and i wont be
able to help until it heals.

sorry

adam
>
> On the other hand reboot cycle testing didn't show any lockup problems over more than 24 hours, so it seems like the issue is limited to resume.


From rajatja at google.com  Mon Aug  9 12:05:23 2021
From: rajatja at google.com (Rajat Jain)
Date: Mon, 9 Aug 2021 12:05:23 -0700
Subject: [PATCH v3 24/25] iommu/dma: Factor out flush queue init
In-Reply-To: <3b5284ee394f267ba966839173f874fc9a996bb2.1628094601.git.robin.murphy@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <3b5284ee394f267ba966839173f874fc9a996bb2.1628094601.git.robin.murphy@arm.com>
Message-ID: <CACK8Z6HSM678q=BZ3FY7spN2S3ZkhdJ3ecnMCbKWrqB5dNWaMA@mail.gmail.com>

On Wed, Aug 4, 2021 at 10:16 AM Robin Murphy <robin.murphy at arm.com> wrote:
>
> Factor out flush queue setup from the initial domain init so that we
> can potentially trigger it from sysfs later on in a domain's lifetime.
>
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Reviewed-by: John Garry <john.garry at huawei.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  drivers/iommu/dma-iommu.c | 30 ++++++++++++++++++++----------
>  include/linux/dma-iommu.h |  9 ++++++---
>  2 files changed, 26 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index 2e19505dddf9..f51b8dc99ac6 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -310,6 +310,25 @@ static bool dev_is_untrusted(struct device *dev)
>         return dev_is_pci(dev) && to_pci_dev(dev)->untrusted;
>  }
>
> +int iommu_dma_init_fq(struct iommu_domain *domain)
> +{
> +       struct iommu_dma_cookie *cookie = domain->iova_cookie;
> +
> +       if (domain->type != IOMMU_DOMAIN_DMA_FQ)
> +               return -EINVAL;
> +       if (cookie->fq_domain)
> +               return 0;
> +
> +       if (init_iova_flush_queue(&cookie->iovad, iommu_dma_flush_iotlb_all,
> +                                 iommu_dma_entry_dtor)) {
> +               pr_warn("iova flush queue initialization failed\n");
> +               domain->type = IOMMU_DOMAIN_DMA;
> +               return -ENODEV;
> +       }
> +       cookie->fq_domain = domain;
> +       return 0;
> +}
> +
>  /**
>   * iommu_dma_init_domain - Initialise a DMA mapping domain
>   * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()
> @@ -362,16 +381,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
>         }
>
>         init_iova_domain(iovad, 1UL << order, base_pfn);
> -
> -       if (domain->type == IOMMU_DOMAIN_DMA_FQ && !cookie->fq_domain) {
> -               if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
> -                                         iommu_dma_entry_dtor)) {
> -                       pr_warn("iova flush queue initialization failed\n");
> -                       domain->type = IOMMU_DOMAIN_DMA;
> -               } else {
> -                       cookie->fq_domain = domain;
> -               }
> -       }
> +       iommu_dma_init_fq(domain);
>
>         return iova_reserve_iommu_regions(dev, domain);
>  }
> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
> index 758ca4694257..81ab647f1618 100644
> --- a/include/linux/dma-iommu.h
> +++ b/include/linux/dma-iommu.h
> @@ -20,6 +20,7 @@ void iommu_put_dma_cookie(struct iommu_domain *domain);
>
>  /* Setup call for arch DMA mapping code */
>  void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit);
> +int iommu_dma_init_fq(struct iommu_domain *domain);
>
>  /* The DMA API isn't _quite_ the whole story, though... */
>  /*
> @@ -37,9 +38,6 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc,
>
>  void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
>
> -void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
> -               struct iommu_domain *domain);
> -

This looks like an unrelated code cleanup. Should this be a separate patch?

Thanks,

Rajat


>  extern bool iommu_dma_forcedac;
>
>  #else /* CONFIG_IOMMU_DMA */
> @@ -54,6 +52,11 @@ static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base,
>  {
>  }
>
> +static inline int iommu_dma_init_fq(struct iommu_domain *domain)
> +{
> +       return -EINVAL;
> +}
> +
>  static inline int iommu_get_dma_cookie(struct iommu_domain *domain)
>  {
>         return -ENODEV;
> --
> 2.25.1
>


From linux at roeck-us.net  Mon Aug  9 12:06:41 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 9 Aug 2021 12:06:41 -0700
Subject: [PATCH v3] memblock: make memblock_find_in_range method private
In-Reply-To: <20210803064218.6611-1-rppt@kernel.org>
References: <20210803064218.6611-1-rppt@kernel.org>
Message-ID: <20210809190641.GA1176508@roeck-us.net>

On Tue, Aug 03, 2021 at 09:42:18AM +0300, Mike Rapoport wrote:
> From: Mike Rapoport <rppt at linux.ibm.com>
> 
> There are a lot of uses of memblock_find_in_range() along with
> memblock_reserve() from the times memblock allocation APIs did not exist.
> 
> memblock_find_in_range() is the very core of memblock allocations, so any
> future changes to its internal behaviour would mandate updates of all the
> users outside memblock.
> 
> Replace the calls to memblock_find_in_range() with an equivalent calls to
> memblock_phys_alloc() and memblock_phys_alloc_range() and make
> memblock_find_in_range() private method of memblock.
> 
> This simplifies the callers, ensures that (unlikely) errors in
> memblock_reserve() are handled and improves maintainability of
> memblock_find_in_range().
> 
> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>

I see a number of crashes in next-20210806 when booting x86 images from efi.

[    0.000000] efi: EFI v2.70 by EDK II
[    0.000000] efi: SMBIOS=0x1fbcc000 ACPI=0x1fbfa000 ACPI 2.0=0x1fbfa014 MEMATTR=0x1f25f018
[    0.000000] SMBIOS 2.8 present.
[    0.000000] DMI: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
[    0.000000] last_pfn = 0x1ff50 max_arch_pfn = 0x400000000
[    0.000000] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT
[    0.000000] Kernel panic - not syncing: alloc_low_pages: can not alloc memory
[    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.14.0-rc4-next-20210806 #1
[    0.000000] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
[    0.000000] Call Trace:
[    0.000000]  ? dump_stack_lvl+0x57/0x7d
[    0.000000]  ? panic+0xfc/0x2c6
[    0.000000]  ? alloc_low_pages+0x117/0x156
[    0.000000]  ? phys_pmd_init+0x234/0x342
[    0.000000]  ? phys_pud_init+0x171/0x337
[    0.000000]  ? __kernel_physical_mapping_init+0xec/0x276
[    0.000000]  ? init_memory_mapping+0x1ea/0x2aa
[    0.000000]  ? init_range_memory_mapping+0xdf/0x12e
[    0.000000]  ? init_mem_mapping+0x1e9/0x26f
[    0.000000]  ? setup_arch+0x5ff/0xb6d
[    0.000000]  ? start_kernel+0x71/0x6b4
[    0.000000]  ? secondary_startup_64_no_verify+0xc2/0xcb

Bisect points to this patch. Reverting it fixes the problem. Key seems to
be the amount of memory configured in qemu; the problem is not seen if
there is 1G or more of memory, but it is seen with all test boots with
512M or 256M of memory. It is also seen with almost all 32-bit efi boots.

The problem is not seen when booting without efi.

Guenter

---
Bisect log:

# bad: [da454ebf578f6c542ba9f5b3ddb98db3ede109c1] Add linux-next specific files for 20210809
# good: [36a21d51725af2ce0700c6ebcb6b9594aac658a6] Linux 5.14-rc5
git bisect start 'HEAD' 'v5.14-rc5'
# good: [d22fda64bea5f33000e31e5b7e4ba876bca37436] Merge remote-tracking branch 'crypto/master'
git bisect good d22fda64bea5f33000e31e5b7e4ba876bca37436
# good: [b084da3a98fad27a39ed5ca64106b86df0417851] Merge remote-tracking branch 'irqchip/irq/irqchip-next'
git bisect good b084da3a98fad27a39ed5ca64106b86df0417851
# good: [a5383d1f57190a33c6afc25c62b9907d84ba2bc6] Merge remote-tracking branch 'staging/staging-next'
git bisect good a5383d1f57190a33c6afc25c62b9907d84ba2bc6
# good: [a439da3e6abeb054f4e6b0d37814e762b7340196] Merge remote-tracking branch 'seccomp/for-next/seccomp'
git bisect good a439da3e6abeb054f4e6b0d37814e762b7340196
# bad: [9801f3c0890c7b992b45a5c2afcb16c5cdc8388e] mm/idle_page_tracking: Make PG_idle reusable
git bisect bad 9801f3c0890c7b992b45a5c2afcb16c5cdc8388e
# good: [b4f7f4a9b542836683308d48ffdd18471c6f3e76] lazy-tlb-allow-lazy-tlb-mm-refcounting-to-be-configurable-fix
git bisect good b4f7f4a9b542836683308d48ffdd18471c6f3e76
# good: [e30842a48c36f094271eea0984bb861b49c49c87] mm/vmscan: add 'else' to remove check_pending label
git bisect good e30842a48c36f094271eea0984bb861b49c49c87
# bad: [65300b20a21214fb2043419d4e5da1d9947c6e15] mm/madvise: add MADV_WILLNEED to process_madvise()
git bisect bad 65300b20a21214fb2043419d4e5da1d9947c6e15
# bad: [7348da7a8c244d1a755bc5838b04cb9b1b6ee06c] memblock: make memblock_find_in_range method private
git bisect bad 7348da7a8c244d1a755bc5838b04cb9b1b6ee06c
# good: [98f8c467fe2ba8e553b450b2a3294d69f1f2027f] mm-mempolicy-convert-from-atomic_t-to-refcount_t-on-mempolicy-refcnt-fix
git bisect good 98f8c467fe2ba8e553b450b2a3294d69f1f2027f
# good: [760ded422ebe4f8899905b752d8378c44f2a78f3] mm/memplicy: add page allocation function for MPOL_PREFERRED_MANY policy
git bisect good 760ded422ebe4f8899905b752d8378c44f2a78f3
# good: [fbfa0492d9639b67119d3d94b7a6a3f85e064260] mm/mempolicy: advertise new MPOL_PREFERRED_MANY
git bisect good fbfa0492d9639b67119d3d94b7a6a3f85e064260
# good: [ff6d5759a871883aeea38309fb16d91666179328] mm/mempolicy: unify the create() func for bind/interleave/prefer-many policies
git bisect good ff6d5759a871883aeea38309fb16d91666179328
# first bad commit: [7348da7a8c244d1a755bc5838b04cb9b1b6ee06c] memblock: make memblock_find_in_range method private


From adelg at google.com  Mon Aug  9 12:14:14 2021
From: adelg at google.com (Andrew Delgadillo)
Date: Mon,  9 Aug 2021 19:14:14 +0000
Subject: [PATCH] arm64: clean vdso files
Message-ID: <20210809191414.3572827-1-adelg@google.com>

commit a5b8ca97fbf8 ("arm64: do not descend to vdso directories twice")
changes the cleaning behavior of arm64's vdso files, in that vdso.lds,
vdso.so, and vdso.so.dbg are not removed upon a 'make clean/mrproper':

$ make defconfig ARCH=arm64
$ make ARCH=arm64
$ make mrproper ARCH=arm64
$ git clean -nxdf
Would remove arch/arm64/kernel/vdso/vdso.lds
Would remove arch/arm64/kernel/vdso/vdso.so
Would remove arch/arm64/kernel/vdso/vdso.so.dbg

To remedy this, manually descend into arch/arm64/kernel/vdso upon
cleaning.

After this commit:
$ make defconfig ARCH=arm64
$ make ARCH=arm64
$ make mrproper ARCH=arm64
$ git clean -nxdf
<empty>

Signed-off-by: Andrew Delgadillo <adelg at google.com>
---
 arch/arm64/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index b52481f0605d..ef6598cb5a9b 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -181,6 +181,7 @@ archprepare:
 # We use MRPROPER_FILES and CLEAN_FILES now
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
+	$(Q)$(MAKE) $(clean)=arch/arm64/kernel/vdso
 
 ifeq ($(KBUILD_EXTMOD),)
 # We need to generate vdso-offsets.h before compiling certain files in kernel/.
-- 
2.32.0.605.g8dce9f2422-goog



From jic23 at kernel.org  Mon Aug  9 12:26:37 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 9 Aug 2021 20:26:37 +0100
Subject: [PATCH v15 01/13] counter: 104-quad-8: Describe member 'lock'
 in 'quad8'
In-Reply-To: <43b4acab9e238638c7067dd4a363a42f94c94ccb.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
 <43b4acab9e238638c7067dd4a363a42f94c94ccb.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <20210809202637.4aac5c81@jic23-huawei>

On Mon,  9 Aug 2021 21:37:26 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> This adds a kernel-doc comment line describing the 'lock' member of the
> 'quad8' structure.
> 
> Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
Initially I was confused as to when Syed had acked a new patch, but
then realised you have pulled it out of the later spinlock conversion
patch which Syed had indeed acked, so fair enough.

Applied to the togreg branch of iio.git and (unlike yesterday)
pushed out as testing for 0-day to poke at it.
> ---
>  drivers/counter/104-quad-8.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
> index 5283ff128c17..0caa60537b14 100644
> --- a/drivers/counter/104-quad-8.c
> +++ b/drivers/counter/104-quad-8.c
> @@ -28,6 +28,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
>  
>  /**
>   * struct quad8 - device private data structure
> + * @lock:		lock to prevent clobbering device states during R/W ops
>   * @counter:		instance of the counter_device
>   * @fck_prescaler:	array of filter clock prescaler configurations
>   * @preset:		array of preset values



From jic23 at kernel.org  Mon Aug  9 12:34:55 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 9 Aug 2021 20:34:55 +0100
Subject: [PATCH v15 00/13] Introduce the Counter character device interface
In-Reply-To: <cover.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <20210809203455.59ad5a61@jic23-huawei>

On Mon,  9 Aug 2021 21:37:25 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> Changes in v15:
>  - Move the description for the member 'lock' in the 'quad8' structure
>    as a separate patch
>  - Reorganize the "counter: Internalize sysfs interface code" patch to
>    not call chrdev code; respective code moved to the "counter: Add
>    character device interface" patch with the other chrdev code
>  - Custom enums removed from the ftm-quaddec.c, stm32-lptimer-cnt.c, and
>    stm32-timer-cnt.c files; respective drivers refactored to use the
>    COUNTER_FUNCTION_* and COUNTER_SYNAPSE_* enum constants instead
Given this last one isn't trivial, I'll let patch 2 onwards sit
on the list for a little while just to see if anyone wants to take
a look at those changes.  Then I'll take up to patch 5. Whilst some
are precursors to the later patches, they don't do any harm and
will reduce the amount we are asking people to review going forwards.

As for the chrdev part.   My gut feeling is that needs more eyes
yet despite being fairly stable in form for a while now.
I'll try and take another look, and would definitely encourage
others to look at it as well.

New ABI is hard to get right so needs a bit more time than many other
forms of patch set.

Jonathan

> 
> For convenience, this patchset is also available on my personal git
> repo: https://gitlab.com/vilhelmgray/iio/-/tree/counter_chrdev_v15
> 
> The patches preceding "counter: Internalize sysfs interface code" are
> primarily cleanup and fixes that can be picked up and applied now to the
> IIO tree if so desired. The "counter: Internalize sysfs interface code"
> patch as well may be considered for pickup because it is relatively safe
> and makes no changes to the userspace interface.
> 
> To summarize the main points of this patchset: there are no changes to
> the existing Counter sysfs userspace interface; a Counter character
> device interface is introduced that allows Counter events and associated
> data to be read() by userspace; the events_configure() and
> watch_validate() driver callbacks are introduced to support Counter
> events; and IRQ support is added to the 104-QUAD-8 driver, serving as an
> example of how to support the new Counter events functionality.
> 
> William Breathitt Gray (13):
>   counter: 104-quad-8: Describe member 'lock' in 'quad8'
>   counter: Internalize sysfs interface code
>   counter: Update counter.h comments to reflect sysfs internalization
>   docs: counter: Update to reflect sysfs internalization
>   counter: Move counter enums to uapi header
>   counter: Add character device interface
>   docs: counter: Document character device interface
>   tools/counter: Create Counter tools
>   counter: Implement signalZ_action_component_id sysfs attribute
>   counter: Implement *_component_id sysfs attributes
>   counter: Implement events_queue_size sysfs attribute
>   counter: 104-quad-8: Replace mutex with spinlock
>   counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8
> 
>  Documentation/ABI/testing/sysfs-bus-counter   |   38 +-
>  Documentation/driver-api/generic-counter.rst  |  358 +++-
>  .../userspace-api/ioctl/ioctl-number.rst      |    1 +
>  MAINTAINERS                                   |    3 +-
>  drivers/counter/104-quad-8.c                  |  700 ++++----
>  drivers/counter/Kconfig                       |    6 +-
>  drivers/counter/Makefile                      |    1 +
>  drivers/counter/counter-chrdev.c              |  553 ++++++
>  drivers/counter/counter-chrdev.h              |   14 +
>  drivers/counter/counter-core.c                |  191 +++
>  drivers/counter/counter-sysfs.c               |  962 +++++++++++
>  drivers/counter/counter-sysfs.h               |   13 +
>  drivers/counter/counter.c                     | 1496 -----------------
>  drivers/counter/ftm-quaddec.c                 |   60 +-
>  drivers/counter/intel-qep.c                   |  144 +-
>  drivers/counter/interrupt-cnt.c               |   62 +-
>  drivers/counter/microchip-tcb-capture.c       |   91 +-
>  drivers/counter/stm32-lptimer-cnt.c           |  226 +--
>  drivers/counter/stm32-timer-cnt.c             |  179 +-
>  drivers/counter/ti-eqep.c                     |  180 +-
>  include/linux/counter.h                       |  715 ++++----
>  include/linux/counter_enum.h                  |   45 -
>  include/uapi/linux/counter.h                  |  154 ++
>  tools/Makefile                                |   13 +-
>  tools/counter/Build                           |    1 +
>  tools/counter/Makefile                        |   53 +
>  tools/counter/counter_example.c               |   93 +
>  27 files changed, 3568 insertions(+), 2784 deletions(-)
>  create mode 100644 drivers/counter/counter-chrdev.c
>  create mode 100644 drivers/counter/counter-chrdev.h
>  create mode 100644 drivers/counter/counter-core.c
>  create mode 100644 drivers/counter/counter-sysfs.c
>  create mode 100644 drivers/counter/counter-sysfs.h
>  delete mode 100644 drivers/counter/counter.c
>  delete mode 100644 include/linux/counter_enum.h
>  create mode 100644 include/uapi/linux/counter.h
>  create mode 100644 tools/counter/Build
>  create mode 100644 tools/counter/Makefile
>  create mode 100644 tools/counter/counter_example.c
> 
> 
> base-commit: c886885336b0b5f1a08ce580f7201a2ca30ab041
> prerequisite-patch-id: 8ca55ffcdd5d060dd5fa2b4dd50bf01dc1026da6
> prerequisite-patch-id: 46ef2668ca6bdc0d08dd488fe1d2b886189a5652
> prerequisite-patch-id: 2df1946c917d6408148306db30a071e67b00ad73
> prerequisite-patch-id: f81579f50552e6041a95403cc743c5f36962b111
> prerequisite-patch-id: 8a6860e75cdec162812c56dc39c5d7fc6fc5154e



From jeremy.linton at arm.com  Mon Aug  9 12:48:17 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Mon, 9 Aug 2021 14:48:17 -0500
Subject: [PATCH 2/3] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210809174244.GA2167737@bjorn-Precision-5520>
References: <20210809174244.GA2167737@bjorn-Precision-5520>
Message-ID: <4d4732b9-e8df-3803-2db7-c6eef1196269@arm.com>

Hi,

On 8/9/21 12:42 PM, Bjorn Helgaas wrote:
> On Fri, Aug 06, 2021 at 09:55:27PM -0500, Jeremy Linton wrote:
>> Hi,
>>
>> On 8/6/21 5:21 PM, Bjorn Helgaas wrote:
>>> On Thu, Aug 05, 2021 at 04:11:59PM -0500, Jeremy Linton wrote:
>>>> The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
>>>> standard because its PCIe config space isn't ECAM compliant and is
>>>> split into two parts. One part for the root port registers and a
>>>> moveable window which points at a given device's 4K config space.
>>>> Thus it doesn't have a MCFG (and really any MCFG provided would be
>>>> nonsense anyway). As Linux doesn't support the PCIe SMCCC standard
>>>> we key off a Linux specific host bridge _DSD to add custom ECAM
>>>> ops and cfgres. The cfg op selects between those two regions, as
>>>> well as disallowing problematic accesses, particularly if the link
>>>> is down because there isn't an attached device.
>>>
>>> I'm not sure SMCCC is *really* relevant here.  If it is, an expansion
>>> of the acronym and a link to a spec would be helpful.
>>>
>>> But AFAICT the only important thing here is that it doesn't have
>>> standard ECAM, and we're going to work around that.
>>
>> I will reword it a bit.
>>
>>> I don't see anything about _DSD in this series.
>>
>> That is the "linux,pci-quirk" in the next patch.
> 
> The next patch doesn't mention _DSD either.  Is it obfuscated by
> being inside fwnode_property_read_string()?  If so, it's well and
> truly hidden; I gave up trying to connect that with ACPI.

Right, the fwnode stuff works as a DT/ACPI abstraction for reading 
values from firmware tables. In this case the ACPI definition looks 
something like:

Device(PCI0) {
...
   Name (_DSD, Package () {
   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
     Package () {
     Package () { "linux-pcie-quirk", "bcm2711" },
   }
   })

...
}

Which explains a bit of why the underlying code is a bit uh... complicated.


From semen.protsenko at linaro.org  Mon Aug  9 12:48:59 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 9 Aug 2021 22:48:59 +0300
Subject: [PATCH v2 7/8] clk: samsung: Add Exynos850 clock driver stub
In-Reply-To: <3add6f87-7293-e1ae-8f9e-c69e9de18cf5@canonical.com>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-8-semen.protsenko@linaro.org>
 <3add6f87-7293-e1ae-8f9e-c69e9de18cf5@canonical.com>
Message-ID: <CAPLW+4=-uUcoLCjjBAC2K5NLswnXGXW1qrsTJrb_uZDgOQ5Ehw@mail.gmail.com>

On Mon, 9 Aug 2021 at 14:23, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 06/08/2021 17:21, Sam Protsenko wrote:
> > For now it's just a stub driver to make the serial driver work. Later it
> > will be implemented properly. This driver doesn't really change clocks,
> > only registers the UART clock as a fixed-rate clock. Without this clock
> > driver the UART driver won't work, as it's trying to obtain "uart" clock
> > and fails if it's not able to.
> >
> > In order to get a functional serial console we have to implement that
> > minimal clock driver with "uart" clock. It's not necessary to actually
> > configure clocks, as those are already configured in bootloader, so
> > kernel can rely on that for now.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> > Changes in v2:
> >   - Used hard coded clock indexes, as clock bindings were removed; will
> >     add clock bindings back (reimplemented) once proper clock driver is
> >     ready
> >   - Removed .data = 0 for exynos850-oscclk, as it's in BSS section
> >   - Removed comma for terminator {}
> >   - Made exynos850_clk_init() static
> >   - Removed checking np for NULL, as it's already done in of_iomap()
> >
> >  drivers/clk/samsung/Makefile        |  1 +
> >  drivers/clk/samsung/clk-exynos850.c | 64 +++++++++++++++++++++++++++++
> >  2 files changed, 65 insertions(+)
> >  create mode 100644 drivers/clk/samsung/clk-exynos850.c
> >
> > diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> > index 028b2e27a37e..c46cf11e4d0b 100644
> > --- a/drivers/clk/samsung/Makefile
> > +++ b/drivers/clk/samsung/Makefile
> > @@ -17,6 +17,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)       += clk-exynos5433.o
> >  obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
> >  obj-$(CONFIG_EXYNOS_CLKOUT)  += clk-exynos-clkout.o
> >  obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)        += clk-exynos7.o
> > +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)        += clk-exynos850.o
> >  obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
> >  obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
> >  obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
> > diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
> > new file mode 100644
> > index 000000000000..36c7c7fe7cf0
> > --- /dev/null
> > +++ b/drivers/clk/samsung/clk-exynos850.c
> > @@ -0,0 +1,64 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (C) 2019 Samsung Electronics Co., Ltd.
> > + * Copyright (C) 2021 Linaro Ltd.
> > + *
> > + * Common Clock Framework support for Exynos850 SoC.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clkdev.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +
> > +#include "clk.h"
> > +
> > +/* Will be extracted to bindings header once proper clk driver is implemented */
> > +#define OSCCLK               1
> > +#define DOUT_UART    2
> > +#define CLK_NR_CLKS  3
> > +
> > +/* Fixed rate clocks generated outside the SoC */
> > +static struct samsung_fixed_rate_clock exynos850_fixed_rate_ext_clks[] __initdata = {
> > +     FRATE(OSCCLK, "fin_pll", NULL, 0, 26000000),
> > +};
> > +
> > +/*
> > + * Model the UART clock as a fixed-rate clock for now, to make serial driver
> > + * work. This clock is already configured in the bootloader.
> > + */
> > +static const struct samsung_fixed_rate_clock exynos850_peri_clks[] __initconst = {
> > +     FRATE(DOUT_UART, "DOUT_UART", NULL, 0, 200000000),
> > +};
> > +
> > +static const struct of_device_id ext_clk_match[] __initconst = {
> > +     { .compatible = "samsung,exynos850-oscclk" },
>
> One more thing - I am not sure anymore if this is correct. AFAIR, we
> wanted to drop compatibles for external clocks.
>

I'll remove oscclk from the clock driver and device tree. It's not
needed right now anyway, as that driver is just a stub.

But I'd still like to know the proper way to define external clocks. I
can see that in exynos7.dtsi and exynos5433.dtsi there is just regular
fixed clock defined for "oscclk" (or "fin_pll"), and then that clock
is referenced in corresponding clock driver by its
'clock-output-names' property. I guess that approach is the
recommended one?

> Chanwoo, Sylwester, Tomasz,
> Do you remember the recommended approach? Shall it be like Exynos542x
> (samsung,exynos5420-oscclk) or Exynos5433?
>
>
> BTW, I am now converting some of existing clock controller bindings to
> dtschema.
>

I'll try to review those in a day, that might also be helpful when I
get to clk implementation. Btw, thank you for reviewing my patches in
such a quick pace!

> Best regards,
> Krzysztof


From robin.murphy at arm.com  Mon Aug  9 12:59:35 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 9 Aug 2021 20:59:35 +0100
Subject: [PATCH v3 24/25] iommu/dma: Factor out flush queue init
In-Reply-To: <CACK8Z6HSM678q=BZ3FY7spN2S3ZkhdJ3ecnMCbKWrqB5dNWaMA@mail.gmail.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <3b5284ee394f267ba966839173f874fc9a996bb2.1628094601.git.robin.murphy@arm.com>
 <CACK8Z6HSM678q=BZ3FY7spN2S3ZkhdJ3ecnMCbKWrqB5dNWaMA@mail.gmail.com>
Message-ID: <00baf83a-5eb3-4d72-309c-5adfd3242c07@arm.com>

On 2021-08-09 20:05, Rajat Jain wrote:
> On Wed, Aug 4, 2021 at 10:16 AM Robin Murphy <robin.murphy at arm.com> wrote:
>>
>> Factor out flush queue setup from the initial domain init so that we
>> can potentially trigger it from sysfs later on in a domain's lifetime.
>>
>> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
>> Reviewed-by: John Garry <john.garry at huawei.com>
>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
>> ---
>>   drivers/iommu/dma-iommu.c | 30 ++++++++++++++++++++----------
>>   include/linux/dma-iommu.h |  9 ++++++---
>>   2 files changed, 26 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
>> index 2e19505dddf9..f51b8dc99ac6 100644
>> --- a/drivers/iommu/dma-iommu.c
>> +++ b/drivers/iommu/dma-iommu.c
>> @@ -310,6 +310,25 @@ static bool dev_is_untrusted(struct device *dev)
>>          return dev_is_pci(dev) && to_pci_dev(dev)->untrusted;
>>   }
>>
>> +int iommu_dma_init_fq(struct iommu_domain *domain)
>> +{
>> +       struct iommu_dma_cookie *cookie = domain->iova_cookie;
>> +
>> +       if (domain->type != IOMMU_DOMAIN_DMA_FQ)
>> +               return -EINVAL;
>> +       if (cookie->fq_domain)
>> +               return 0;
>> +
>> +       if (init_iova_flush_queue(&cookie->iovad, iommu_dma_flush_iotlb_all,
>> +                                 iommu_dma_entry_dtor)) {
>> +               pr_warn("iova flush queue initialization failed\n");
>> +               domain->type = IOMMU_DOMAIN_DMA;
>> +               return -ENODEV;
>> +       }
>> +       cookie->fq_domain = domain;
>> +       return 0;
>> +}
>> +
>>   /**
>>    * iommu_dma_init_domain - Initialise a DMA mapping domain
>>    * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()
>> @@ -362,16 +381,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
>>          }
>>
>>          init_iova_domain(iovad, 1UL << order, base_pfn);
>> -
>> -       if (domain->type == IOMMU_DOMAIN_DMA_FQ && !cookie->fq_domain) {
>> -               if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
>> -                                         iommu_dma_entry_dtor)) {
>> -                       pr_warn("iova flush queue initialization failed\n");
>> -                       domain->type = IOMMU_DOMAIN_DMA;
>> -               } else {
>> -                       cookie->fq_domain = domain;
>> -               }
>> -       }
>> +       iommu_dma_init_fq(domain);
>>
>>          return iova_reserve_iommu_regions(dev, domain);
>>   }
>> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
>> index 758ca4694257..81ab647f1618 100644
>> --- a/include/linux/dma-iommu.h
>> +++ b/include/linux/dma-iommu.h
>> @@ -20,6 +20,7 @@ void iommu_put_dma_cookie(struct iommu_domain *domain);
>>
>>   /* Setup call for arch DMA mapping code */
>>   void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit);
>> +int iommu_dma_init_fq(struct iommu_domain *domain);
>>
>>   /* The DMA API isn't _quite_ the whole story, though... */
>>   /*
>> @@ -37,9 +38,6 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc,
>>
>>   void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
>>
>> -void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
>> -               struct iommu_domain *domain);
>> -
> 
> This looks like an unrelated code cleanup. Should this be a separate patch?

Ha, busted! Much of this was done in the "stream of consciousness" style 
where I made a big sprawling mess then split it up into patches and 
branches afterwards. TBH it was already feeling pretty tenuous having a 
separate patch just to move this one function, and it only gets more so 
with the simplification Will pointed out earlier. I think I'll squash 
iommu_dma_init_fq() into the next patch then do a thorough header sweep, 
since I've now spotted some things in iova.h which could probably go as 
well.

Thanks for the poke!

Robin.

> 
> Thanks,
> 
> Rajat
> 
> 
>>   extern bool iommu_dma_forcedac;
>>
>>   #else /* CONFIG_IOMMU_DMA */
>> @@ -54,6 +52,11 @@ static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base,
>>   {
>>   }
>>
>> +static inline int iommu_dma_init_fq(struct iommu_domain *domain)
>> +{
>> +       return -EINVAL;
>> +}
>> +
>>   static inline int iommu_get_dma_cookie(struct iommu_domain *domain)
>>   {
>>          return -ENODEV;
>> --
>> 2.25.1
>>


From acme at kernel.org  Mon Aug  9 13:11:44 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 9 Aug 2021 17:11:44 -0300
Subject: [PATCH v1 1/3] perf env: Track kernel 64-bit mode in environment
In-Reply-To: <20210809112727.596876-2-leo.yan@linaro.org>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-2-leo.yan@linaro.org>
Message-ID: <YRGMAHj3MUndBEUq@kernel.org>

Em Mon, Aug 09, 2021 at 07:27:25PM +0800, Leo Yan escreveu:
> It's useful to know that the kernel is running in 32-bit or 64-bit
> mode.  E.g. We can decide if perf tool is running in compat mode
> based on the info.
> 
> This patch adds an item "kernel_is_64_bit" into session's environment
> structure perf_env, its value is initialized based on the architecture
> string.

Thanks, applied.

- Arnaldo

 
> Suggested-by: Arnaldo Carvalho de Melo <acme at redhat.com>
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>  tools/perf/util/env.c | 24 +++++++++++++++++++++++-
>  tools/perf/util/env.h |  3 +++
>  2 files changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
> index ab341050be46..8f7ff0035c41 100644
> --- a/tools/perf/util/env.c
> +++ b/tools/perf/util/env.c
> @@ -219,13 +219,35 @@ void perf_env__exit(struct perf_env *env)
>  	zfree(&env->hybrid_cpc_nodes);
>  }
>  
> -void perf_env__init(struct perf_env *env __maybe_unused)
> +void perf_env__init(struct perf_env *env)
>  {
>  #ifdef HAVE_LIBBPF_SUPPORT
>  	env->bpf_progs.infos = RB_ROOT;
>  	env->bpf_progs.btfs = RB_ROOT;
>  	init_rwsem(&env->bpf_progs.lock);
>  #endif
> +	env->kernel_is_64_bit = -1;
> +}
> +
> +static void perf_env__init_kernel_mode(struct perf_env *env)
> +{
> +	const char *arch = perf_env__raw_arch(env);
> +
> +	if (!strncmp(arch, "x86_64", 6) || !strncmp(arch, "aarch64", 7) ||
> +	    !strncmp(arch, "arm64", 5) || !strncmp(arch, "mips64", 6) ||
> +	    !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) ||
> +	    !strncmp(arch, "s390x", 5) || !strncmp(arch, "sparc64", 7))
> +		env->kernel_is_64_bit = 1;
> +	else
> +		env->kernel_is_64_bit = 0;
> +}
> +
> +int perf_env__kernel_is_64_bit(struct perf_env *env)
> +{
> +	if (env->kernel_is_64_bit == -1)
> +		perf_env__init_kernel_mode(env);
> +
> +	return env->kernel_is_64_bit;
>  }
>  
>  int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index 6824a7423a2d..1f5175820a05 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -61,6 +61,7 @@ struct perf_env {
>  	unsigned long long	total_mem;
>  	unsigned int		msr_pmu_type;
>  	unsigned int		max_branches;
> +	int			kernel_is_64_bit;
>  
>  	int			nr_cmdline;
>  	int			nr_sibling_cores;
> @@ -143,6 +144,8 @@ extern struct perf_env perf_env;
>  
>  void perf_env__exit(struct perf_env *env);
>  
> +int perf_env__kernel_is_64_bit(struct perf_env *env);
> +
>  int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]);
>  
>  int perf_env__read_cpuid(struct perf_env *env);
> -- 
> 2.25.1
> 

-- 

- Arnaldo


From acme at kernel.org  Mon Aug  9 13:12:30 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 9 Aug 2021 17:12:30 -0300
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210809112727.596876-3-leo.yan@linaro.org>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-3-leo.yan@linaro.org>
Message-ID: <YRGMLsEnWI+opAqB@kernel.org>

Em Mon, Aug 09, 2021 at 07:27:26PM +0800, Leo Yan escreveu:
> When perf runs in compat mode (kernel in 64-bit mode and the perf is in
> 32-bit mode), the 64-bit value atomicity in the user space cannot be
> assured, E.g. on some architectures, the 64-bit value accessing is split
> into two instructions, one is for the low 32-bit word accessing and
> another is for the high 32-bit word.
> 
> This patch introduces weak functions compat_auxtrace_mmap__read_head()
> and compat_auxtrace_mmap__write_tail(), as their naming indicates, when
> perf tool works in compat mode, it uses these two functions to access
> the AUX head and tail.  These two functions can allow the perf tool to
> work properly in certain conditions, e.g. when perf tool works in
> snapshot mode with only using AUX head pointer, or perf tool uses the
> AUX buffer and the incremented tail is not bigger than 4GB.
> 
> When perf tool cannot handle the case when the AUX tail is bigger than
> 4GB, the function compat_auxtrace_mmap__write_tail() returns -1 and
> tells the caller to bail out for the error.
> 
> These two functions are declared as weak attribute, this allows to
> implement arch specific functions if any arch can support the 64-bit
> value atomicity in compat mode.

Adrian, ARM guys, can you please review this?

Thanks,

- Arnaldo
 
> Suggested-by: Adrian Hunter <adrian.hunter at intel.com>
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>  tools/perf/util/auxtrace.c | 88 ++++++++++++++++++++++++++++++++++++--
>  tools/perf/util/auxtrace.h | 22 ++++++++--
>  2 files changed, 103 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
> index f33f09b8b535..60975df05d54 100644
> --- a/tools/perf/util/auxtrace.c
> +++ b/tools/perf/util/auxtrace.c
> @@ -1669,6 +1669,82 @@ int perf_event__process_auxtrace_error(struct perf_session *session,
>  	return 0;
>  }
>  
> +/*
> + * In the compat mode kernel runs in 64-bit and perf tool runs in 32-bit mode,
> + * 32-bit perf tool cannot access 64-bit value atomically, which might lead to
> + * the issues caused by the below sequence on multiple CPUs: when perf tool
> + * accesses either the load operation or the store operation for 64-bit value,
> + * on some architectures the operation is divided into two instructions, one
> + * is for accessing the low 32-bit value and another is for the high 32-bit;
> + * thus these two user operations can give the kernel chances to access the
> + * 64-bit value, and thus leads to the unexpected load values.
> + *
> + *   kernel (64-bit)                        user (32-bit)
> + *
> + *   if (LOAD ->aux_tail) { --,             LOAD ->aux_head_lo
> + *       STORE $aux_data      |       ,--->
> + *       FLUSH $aux_data      |       |     LOAD ->aux_head_hi
> + *       STORE ->aux_head   --|-------`     smp_rmb()
> + *   }                        |             LOAD $data
> + *                            |             smp_mb()
> + *                            |             STORE ->aux_tail_lo
> + *                            `----------->
> + *                                          STORE ->aux_tail_hi
> + *
> + * For this reason, it's impossible for the perf tool to work correctly when
> + * the AUX head or tail is bigger than 4GB (more than 32 bits length); and we
> + * can not simply limit the AUX ring buffer to less than 4GB, the reason is
> + * the pointers can be increased monotonically, whatever the buffer size it is,
> + * at the end the head and tail can be bigger than 4GB and carry out to the
> + * high 32-bit.
> + *
> + * To mitigate the issues and improve the user experience, we can allow the
> + * perf tool working in certain conditions and bail out with error if detect
> + * any overflow cannot be handled.
> + *
> + * For reading the AUX head, it reads out the values for three times, and
> + * compares the high 4 bytes of the values between the first time and the last
> + * time, if there has no change for high 4 bytes injected by the kernel during
> + * the user reading sequence, it's safe for use the second value.
> + *
> + * When update the AUX tail and detects any carrying in the high 32 bits, it
> + * means there have two store operations in user space and it cannot promise
> + * the atomicity for 64-bit write, so return '-1' in this case to tell the
> + * caller an overflow error has happened.
> + */
> +u64 __weak compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> +{
> +	struct perf_event_mmap_page *pc = mm->userpg;
> +	u64 first, second, last;
> +	u64 mask = (u64)(UINT32_MAX) << 32;
> +
> +	do {
> +		first = READ_ONCE(pc->aux_head);
> +		/* Ensure all reads are done after we read the head */
> +		smp_rmb();
> +		second = READ_ONCE(pc->aux_head);
> +		/* Ensure all reads are done after we read the head */
> +		smp_rmb();
> +		last = READ_ONCE(pc->aux_head);
> +	} while ((first & mask) != (last & mask));
> +
> +	return second;
> +}
> +
> +int __weak compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
> +{
> +	struct perf_event_mmap_page *pc = mm->userpg;
> +	u64 mask = (u64)(UINT32_MAX) << 32;
> +
> +	if (tail & mask)
> +		return -1;
> +
> +	/* Ensure all reads are done before we write the tail out */
> +	smp_mb();
> +	WRITE_ONCE(pc->aux_tail, tail);
> +	return 0;
> +}
> +
>  static int __auxtrace_mmap__read(struct mmap *map,
>  				 struct auxtrace_record *itr,
>  				 struct perf_tool *tool, process_auxtrace_t fn,
> @@ -1680,8 +1756,9 @@ static int __auxtrace_mmap__read(struct mmap *map,
>  	size_t size, head_off, old_off, len1, len2, padding;
>  	union perf_event ev;
>  	void *data1, *data2;
> +	int kernel_is_64_bit = perf_env__kernel_is_64_bit(evsel__env(NULL));
>  
> -	head = auxtrace_mmap__read_head(mm);
> +	head = auxtrace_mmap__read_head(mm, kernel_is_64_bit);
>  
>  	if (snapshot &&
>  	    auxtrace_record__find_snapshot(itr, mm->idx, mm, data, &head, &old))
> @@ -1764,10 +1841,13 @@ static int __auxtrace_mmap__read(struct mmap *map,
>  	mm->prev = head;
>  
>  	if (!snapshot) {
> -		auxtrace_mmap__write_tail(mm, head);
> -		if (itr->read_finish) {
> -			int err;
> +		int err;
> +
> +		err = auxtrace_mmap__write_tail(mm, head, kernel_is_64_bit);
> +		if (err < 0)
> +			return err;
>  
> +		if (itr->read_finish) {
>  			err = itr->read_finish(itr, mm->idx);
>  			if (err < 0)
>  				return err;
> diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
> index d68a5e80b217..5f383908ca6e 100644
> --- a/tools/perf/util/auxtrace.h
> +++ b/tools/perf/util/auxtrace.h
> @@ -440,23 +440,39 @@ struct auxtrace_cache;
>  
>  #ifdef HAVE_AUXTRACE_SUPPORT
>  
> -static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> +u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm);
> +int compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail);
> +
> +static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm,
> +					   int kernel_is_64_bit __maybe_unused)
>  {
>  	struct perf_event_mmap_page *pc = mm->userpg;
> -	u64 head = READ_ONCE(pc->aux_head);
> +	u64 head;
> +
> +#if BITS_PER_LONG == 32
> +	if (kernel_is_64_bit)
> +		return compat_auxtrace_mmap__read_head(mm);
> +#endif
> +	head = READ_ONCE(pc->aux_head);
>  
>  	/* Ensure all reads are done after we read the head */
>  	smp_rmb();
>  	return head;
>  }
>  
> -static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
> +static inline int auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail,
> +					    int kernel_is_64_bit __maybe_unused)
>  {
>  	struct perf_event_mmap_page *pc = mm->userpg;
>  
> +#if BITS_PER_LONG == 32
> +	if (kernel_is_64_bit)
> +		return compat_auxtrace_mmap__write_tail(mm, tail);
> +#endif
>  	/* Ensure all reads are done before we write the tail out */
>  	smp_mb();
>  	WRITE_ONCE(pc->aux_tail, tail);
> +	return 0;
>  }
>  
>  int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
> -- 
> 2.25.1
> 

-- 

- Arnaldo


From rajatja at google.com  Mon Aug  9 13:15:46 2021
From: rajatja at google.com (Rajat Jain)
Date: Mon, 9 Aug 2021 13:15:46 -0700
Subject: [PATCH v3 24/25] iommu/dma: Factor out flush queue init
In-Reply-To: <00baf83a-5eb3-4d72-309c-5adfd3242c07@arm.com>
References: <cover.1628094600.git.robin.murphy@arm.com>
 <3b5284ee394f267ba966839173f874fc9a996bb2.1628094601.git.robin.murphy@arm.com>
 <CACK8Z6HSM678q=BZ3FY7spN2S3ZkhdJ3ecnMCbKWrqB5dNWaMA@mail.gmail.com>
 <00baf83a-5eb3-4d72-309c-5adfd3242c07@arm.com>
Message-ID: <CACK8Z6Gb1O8Ok1GEy80nQJ4ZQeFJ3TOgFHRYfH3Yb=8CNT=ysw@mail.gmail.com>

On Mon, Aug 9, 2021 at 12:59 PM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2021-08-09 20:05, Rajat Jain wrote:
> > On Wed, Aug 4, 2021 at 10:16 AM Robin Murphy <robin.murphy at arm.com> wrote:
> >>
> >> Factor out flush queue setup from the initial domain init so that we
> >> can potentially trigger it from sysfs later on in a domain's lifetime.
> >>
> >> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> >> Reviewed-by: John Garry <john.garry at huawei.com>
> >> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> >> ---
> >>   drivers/iommu/dma-iommu.c | 30 ++++++++++++++++++++----------
> >>   include/linux/dma-iommu.h |  9 ++++++---
> >>   2 files changed, 26 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> >> index 2e19505dddf9..f51b8dc99ac6 100644
> >> --- a/drivers/iommu/dma-iommu.c
> >> +++ b/drivers/iommu/dma-iommu.c
> >> @@ -310,6 +310,25 @@ static bool dev_is_untrusted(struct device *dev)
> >>          return dev_is_pci(dev) && to_pci_dev(dev)->untrusted;
> >>   }
> >>
> >> +int iommu_dma_init_fq(struct iommu_domain *domain)
> >> +{
> >> +       struct iommu_dma_cookie *cookie = domain->iova_cookie;
> >> +
> >> +       if (domain->type != IOMMU_DOMAIN_DMA_FQ)
> >> +               return -EINVAL;
> >> +       if (cookie->fq_domain)
> >> +               return 0;
> >> +
> >> +       if (init_iova_flush_queue(&cookie->iovad, iommu_dma_flush_iotlb_all,
> >> +                                 iommu_dma_entry_dtor)) {
> >> +               pr_warn("iova flush queue initialization failed\n");
> >> +               domain->type = IOMMU_DOMAIN_DMA;
> >> +               return -ENODEV;
> >> +       }
> >> +       cookie->fq_domain = domain;
> >> +       return 0;
> >> +}
> >> +
> >>   /**
> >>    * iommu_dma_init_domain - Initialise a DMA mapping domain
> >>    * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()
> >> @@ -362,16 +381,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
> >>          }
> >>
> >>          init_iova_domain(iovad, 1UL << order, base_pfn);
> >> -
> >> -       if (domain->type == IOMMU_DOMAIN_DMA_FQ && !cookie->fq_domain) {
> >> -               if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
> >> -                                         iommu_dma_entry_dtor)) {
> >> -                       pr_warn("iova flush queue initialization failed\n");
> >> -                       domain->type = IOMMU_DOMAIN_DMA;
> >> -               } else {
> >> -                       cookie->fq_domain = domain;
> >> -               }
> >> -       }
> >> +       iommu_dma_init_fq(domain);
> >>
> >>          return iova_reserve_iommu_regions(dev, domain);
> >>   }
> >> diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
> >> index 758ca4694257..81ab647f1618 100644
> >> --- a/include/linux/dma-iommu.h
> >> +++ b/include/linux/dma-iommu.h
> >> @@ -20,6 +20,7 @@ void iommu_put_dma_cookie(struct iommu_domain *domain);
> >>
> >>   /* Setup call for arch DMA mapping code */
> >>   void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit);
> >> +int iommu_dma_init_fq(struct iommu_domain *domain);
> >>
> >>   /* The DMA API isn't _quite_ the whole story, though... */
> >>   /*
> >> @@ -37,9 +38,6 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc,
> >>
> >>   void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
> >>
> >> -void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
> >> -               struct iommu_domain *domain);
> >> -
> >
> > This looks like an unrelated code cleanup. Should this be a separate patch?
>
> Ha, busted! Much of this was done in the "stream of consciousness" style
> where I made a big sprawling mess then split it up into patches and
> branches afterwards. TBH it was already feeling pretty tenuous having a
> separate patch just to move this one function, and it only gets more so
> with the simplification Will pointed out earlier. I think I'll squash
> iommu_dma_init_fq() into the next patch then do a thorough header sweep,
> since I've now spotted some things in iova.h which could probably go as
> well.

Thank you. I chanced upon this only because I've backported your
patchset (and some other changes that it depends on) to 5.10 which is
the kernel we currently use for our Intel platforms, and this cleanup
hunk was creating a problem (since 5.10 still uses the symbol you
removed). I'll be giving your v3 patchset a spin in my setup and
update you in case I see any issue.

Thanks,

Rajat


>
> Thanks for the poke!
>
> Robin.
>
> >
> > Thanks,
> >
> > Rajat
> >
> >
> >>   extern bool iommu_dma_forcedac;
> >>
> >>   #else /* CONFIG_IOMMU_DMA */
> >> @@ -54,6 +52,11 @@ static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base,
> >>   {
> >>   }
> >>
> >> +static inline int iommu_dma_init_fq(struct iommu_domain *domain)
> >> +{
> >> +       return -EINVAL;
> >> +}
> >> +
> >>   static inline int iommu_get_dma_cookie(struct iommu_domain *domain)
> >>   {
> >>          return -ENODEV;
> >> --
> >> 2.25.1
> >>


From s.shtylyov at omp.ru  Mon Aug  9 13:21:14 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Mon, 9 Aug 2021 23:21:14 +0300
Subject: [PATCH v2 1/9] usb: dwc3: meson-g12a: add IRQ check
In-Reply-To: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
References: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
Message-ID: <96106462-5538-0b2f-f2ab-ee56e4853912@omp.ru>

The driver neglects to check the result of platform_get_irq()'s call and
blithely passes the negative error codes to devm_request_threaded_irq()
(which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding
an original error code. Stop calling devm_request_threaded_irq() with the
invalid IRQ #s.

Fixes: f90db10779ad ("usb: dwc3: meson-g12a: Add support for IRQ based OTG switching")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Acked-by: Felipe Balbi <balbi at kernel.org>

---
Changes in version 2:
- added Martin's and Felipe's tags.

drivers/usb/dwc3/dwc3-meson-g12a.c |    2 ++
 1 file changed, 2 insertions(+)

Index: usb/drivers/usb/dwc3/dwc3-meson-g12a.c
===================================================================
--- usb.orig/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ usb/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -598,6 +598,8 @@ static int dwc3_meson_g12a_otg_init(stru
 				   USB_R5_ID_DIG_IRQ, 0);
 
 		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return irq;
 		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 						dwc3_meson_g12a_irq_thread,
 						IRQF_ONESHOT, pdev->name, priv);


From s.shtylyov at omp.ru  Mon Aug  9 13:27:28 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Mon, 9 Aug 2021 23:27:28 +0300
Subject: [PATCH v2 3/6] usb: gadget: udc: at91: add IRQ check
In-Reply-To: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
References: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
Message-ID: <6654a224-739a-1a80-12f0-76d920f87b6c@omp.ru>

The driver neglects to check the result of platform_get_irq()'s call and
blithely passes the negative error codes to devm_request_irq() (which takes
*unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
error code. Stop calling devm_request_irq() with the invalid IRQ #s.

Fixes: 8b2e76687b39 ("USB: AT91 UDC updates, mostly power management")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

Acked-by: Felipe Balbi <balbi at kernel.org>

---
Changes in version 2:
- added Felipe's ACK.

drivers/usb/gadget/udc/at91_udc.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: usb/drivers/usb/gadget/udc/at91_udc.c
===================================================================
--- usb.orig/drivers/usb/gadget/udc/at91_udc.c
+++ usb/drivers/usb/gadget/udc/at91_udc.c
@@ -1876,7 +1876,9 @@ static int at91udc_probe(struct platform
 	clk_disable(udc->iclk);
 
 	/* request UDC and maybe VBUS irqs */
-	udc->udp_irq = platform_get_irq(pdev, 0);
+	udc->udp_irq = retval = platform_get_irq(pdev, 0);
+	if (retval < 0)
+		goto err_unprepare_iclk;
 	retval = devm_request_irq(dev, udc->udp_irq, at91_udc_irq, 0,
 				  driver_name, udc);
 	if (retval) {


From helgaas at kernel.org  Mon Aug  9 13:33:23 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 9 Aug 2021 15:33:23 -0500
Subject: [PATCH 2/3] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <4d4732b9-e8df-3803-2db7-c6eef1196269@arm.com>
Message-ID: <20210809203323.GA2184624@bjorn-Precision-5520>

On Mon, Aug 09, 2021 at 02:48:17PM -0500, Jeremy Linton wrote:
> Hi,
> 
> On 8/9/21 12:42 PM, Bjorn Helgaas wrote:
> > On Fri, Aug 06, 2021 at 09:55:27PM -0500, Jeremy Linton wrote:
> > > Hi,
> > > 
> > > On 8/6/21 5:21 PM, Bjorn Helgaas wrote:
> > > > On Thu, Aug 05, 2021 at 04:11:59PM -0500, Jeremy Linton wrote:
> > > > > The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
> > > > > standard because its PCIe config space isn't ECAM compliant and is
> > > > > split into two parts. One part for the root port registers and a
> > > > > moveable window which points at a given device's 4K config space.
> > > > > Thus it doesn't have a MCFG (and really any MCFG provided would be
> > > > > nonsense anyway). As Linux doesn't support the PCIe SMCCC standard
> > > > > we key off a Linux specific host bridge _DSD to add custom ECAM
> > > > > ops and cfgres. The cfg op selects between those two regions, as
> > > > > well as disallowing problematic accesses, particularly if the link
> > > > > is down because there isn't an attached device.
> > > > 
> > > > I'm not sure SMCCC is *really* relevant here.  If it is, an expansion
> > > > of the acronym and a link to a spec would be helpful.
> > > > 
> > > > But AFAICT the only important thing here is that it doesn't have
> > > > standard ECAM, and we're going to work around that.
> > > 
> > > I will reword it a bit.
> > > 
> > > > I don't see anything about _DSD in this series.
> > > 
> > > That is the "linux,pci-quirk" in the next patch.
> > 
> > The next patch doesn't mention _DSD either.  Is it obfuscated by
> > being inside fwnode_property_read_string()?  If so, it's well and
> > truly hidden; I gave up trying to connect that with ACPI.
> 
> Right, the fwnode stuff works as a DT/ACPI abstraction for reading values
> from firmware tables. In this case the ACPI definition looks something like:
> 
> Device(PCI0) {
> ...
>   Name (_DSD, Package () {
>   ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>     Package () {
>     Package () { "linux-pcie-quirk", "bcm2711" },
>   }
>   })
> 
> ...
> }
> 
> Which explains a bit of why the underlying code is a bit uh... complicated.

Wow, that's ... special.

I think I would include "ecam" or something in the name.  There might
be a variety of quirks, e.g., "P2PDMA allowed between root ports",
that could reasonably fit under "linux-pcie-quirk".


From s.shtylyov at omp.ru  Mon Aug  9 13:35:11 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Mon, 9 Aug 2021 23:35:11 +0300
Subject: [PATCH v2 4/9] usb: gadget: udc: s3c2410: add IRQ check
In-Reply-To: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
References: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
Message-ID: <bd69b22c-b484-5a1f-c798-78d4b78405f2@omp.ru>

The driver neglects to check the result of platform_get_irq()'s call and
blithely passes the negative error codes to request_irq() (which takes
*unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
error code. Stop calling request_irq() with the invalid IRQ #s.

Fixes: 188db4435ac6 ("usb: gadget: s3c: use platform resources")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

---
 drivers/usb/gadget/udc/s3c2410_udc.c |    4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

Index: usb/drivers/usb/gadget/udc/s3c2410_udc.c
===================================================================
--- usb.orig/drivers/usb/gadget/udc/s3c2410_udc.c
+++ usb/drivers/usb/gadget/udc/s3c2410_udc.c
@@ -1784,6 +1784,10 @@ static int s3c2410_udc_probe(struct plat
 	s3c2410_udc_reinit(udc);
 
 	irq_usbd = platform_get_irq(pdev, 0);
+	if (irq_usbd < 0) {
+		retval = irq_usbd;
+		goto err_udc_clk;
+	}
 
 	/* irq setup after old hardware state is cleaned up */
 	retval = request_irq(irq_usbd, s3c2410_udc_irq,


From s.shtylyov at omp.ru  Mon Aug  9 13:45:15 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Mon, 9 Aug 2021 23:45:15 +0300
Subject: [PATCH v2 6/9] usb: misc: brcmstb-usb-pinmap: add IRQ check
In-Reply-To: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
References: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
Message-ID: <806d0b1a-365b-93d9-3fc1-922105ca5e61@omp.ru>

The driver neglects to check the result of platform_get_irq()'s call and
blithely passes the negative error codes to devm_request_irq() (which takes
*unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
error code.  Stop calling devm_request_irq() with the invalid IRQ #s.

Fixes: 517c4c44b323 ("usb: Add driver to allow any GPIO to be used for 7211 USB signals")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

---
 drivers/usb/misc/brcmstb-usb-pinmap.c |    2 ++
 1 file changed, 2 insertions(+)

Index: usb/drivers/usb/misc/brcmstb-usb-pinmap.c
===================================================================
--- usb.orig/drivers/usb/misc/brcmstb-usb-pinmap.c
+++ usb/drivers/usb/misc/brcmstb-usb-pinmap.c
@@ -293,6 +293,8 @@ static int __init brcmstb_usb_pinmap_pro
 
 		/* Enable interrupt for out pins */
 		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return irq;
 		err = devm_request_irq(&pdev->dev, irq,
 				       brcmstb_usb_pinmap_ovr_isr,
 				       IRQF_TRIGGER_RISING,


From kuba at kernel.org  Mon Aug  9 13:53:34 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 9 Aug 2021 13:53:34 -0700
Subject: [PATCH net-next v3] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <20210809140109.32595-1-rocco.yue@mediatek.com>
References: <20210809140109.32595-1-rocco.yue@mediatek.com>
Message-ID: <20210809135334.79f000e2@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Mon, 9 Aug 2021 22:01:09 +0800 Rocco Yue wrote:
> +static inline size_t inet6_iframtu_msgsize(void)
> +{
> +	return NLMSG_ALIGN(sizeof(struct ifinfomsg))
> +	     + nla_total_size(IFNAMSIZ)	/* IFLA_IFNAME */
> +	     + nla_total_size(4);	/* IFLA_INET6_RA_MTU */
> +}

Please don't use 'static inline' in C sources, static is enough


From jeremy.linton at arm.com  Mon Aug  9 14:21:21 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Mon, 9 Aug 2021 16:21:21 -0500
Subject: [PATCH 2/3] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210809203323.GA2184624@bjorn-Precision-5520>
References: <20210809203323.GA2184624@bjorn-Precision-5520>
Message-ID: <e3d3394d-c241-77f7-e40a-b14726cc0063@arm.com>

Hi,

On 8/9/21 3:33 PM, Bjorn Helgaas wrote:
> On Mon, Aug 09, 2021 at 02:48:17PM -0500, Jeremy Linton wrote:
>> Hi,
>>
>> On 8/9/21 12:42 PM, Bjorn Helgaas wrote:
>>> On Fri, Aug 06, 2021 at 09:55:27PM -0500, Jeremy Linton wrote:
>>>> Hi,
>>>>
>>>> On 8/6/21 5:21 PM, Bjorn Helgaas wrote:
>>>>> On Thu, Aug 05, 2021 at 04:11:59PM -0500, Jeremy Linton wrote:
>>>>>> The PFTF CM4 is an ACPI platform that is following the PCIe SMCCC
>>>>>> standard because its PCIe config space isn't ECAM compliant and is
>>>>>> split into two parts. One part for the root port registers and a
>>>>>> moveable window which points at a given device's 4K config space.
>>>>>> Thus it doesn't have a MCFG (and really any MCFG provided would be
>>>>>> nonsense anyway). As Linux doesn't support the PCIe SMCCC standard
>>>>>> we key off a Linux specific host bridge _DSD to add custom ECAM
>>>>>> ops and cfgres. The cfg op selects between those two regions, as
>>>>>> well as disallowing problematic accesses, particularly if the link
>>>>>> is down because there isn't an attached device.
>>>>>
>>>>> I'm not sure SMCCC is *really* relevant here.  If it is, an expansion
>>>>> of the acronym and a link to a spec would be helpful.
>>>>>
>>>>> But AFAICT the only important thing here is that it doesn't have
>>>>> standard ECAM, and we're going to work around that.
>>>>
>>>> I will reword it a bit.
>>>>
>>>>> I don't see anything about _DSD in this series.
>>>>
>>>> That is the "linux,pci-quirk" in the next patch.
>>>
>>> The next patch doesn't mention _DSD either.  Is it obfuscated by
>>> being inside fwnode_property_read_string()?  If so, it's well and
>>> truly hidden; I gave up trying to connect that with ACPI.
>>
>> Right, the fwnode stuff works as a DT/ACPI abstraction for reading values
>> from firmware tables. In this case the ACPI definition looks something like:
>>
>> Device(PCI0) {
>> ...
>>    Name (_DSD, Package () {
>>    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>>      Package () {
>>      Package () { "linux-pcie-quirk", "bcm2711" },
>>    }
>>    })
>>
>> ...
>> }
>>
>> Which explains a bit of why the underlying code is a bit uh... complicated.
> 
> Wow, that's ... special.
> 
> I think I would include "ecam" or something in the name.  There might
> be a variety of quirks, e.g., "P2PDMA allowed between root ports",
> that could reasonably fit under "linux-pcie-quirk".
> 

I think I mentioned "linux-ecam-quirk-id" in the bit with Rob. How is that?

I think the description would be something roughly: MCFG oem id override 
string which selects a platform specific ECAM accessor quirk.

Thanks,


From Thinh.Nguyen at synopsys.com  Mon Aug  9 15:13:13 2021
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Mon, 9 Aug 2021 22:13:13 +0000
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <87im0l5lj1.fsf@kernel.org>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org> <87v94lxpb0.fsf@tarshish>
 <87im0l5lj1.fsf@kernel.org>
Message-ID: <33aaae91-3833-d88c-361f-ac9d62e26ccc@synopsys.com>

Felipe Balbi wrote:
> 
> Hi,
> 
> Baruch Siach <baruch at tkos.co.il> writes:
>> Hi Felipe,
>>
>> On Wed, Aug 04 2021, Felipe Balbi wrote:
>>> Baruch Siach <baruch at tkos.co.il> writes:
>>>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>>>  				    &dwc->hsphy_interface);
>>>>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>>>>  				 &dwc->fladj);
>>>> +	device_property_read_u32(dev, "snps,ref-clock-period",
>>>> +				 &dwc->ref_clk_per);
>>>
>>> I wonder if it would make more sense to pass an actual clock reference
>>> here. If valid, then reconfigure the period to the value returned by
>>> clk_get_rate(). It would avoid yet another DT binding. If we make the
>>> clock optional, then we won't affect any other platforms. The clock
>>> itself could be a regular fixed clock node.
>>
>> Thinh Nguyen asked to add a dedicated DT property. He explained that
>> clk_get_rate() does not work for PCI hosted dwc3. This is the most
>> complete summary of the discussion:
> 
> Hence the "optional" :-)
> 
> Or, perhaps, Thinh wants to use this for internal FPGA-based validation?
> 
> In that case, I'm okay with the property.
> 

We do use it for internal FPGA validation, but it should help for other
dwc3 PCI devices also.

BR,
Thinh

From dsahern at gmail.com  Mon Aug  9 15:43:58 2021
From: dsahern at gmail.com (David Ahern)
Date: Mon, 9 Aug 2021 16:43:58 -0600
Subject: [PATCH net-next v3] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <20210809140109.32595-1-rocco.yue@mediatek.com>
References: <20210809140109.32595-1-rocco.yue@mediatek.com>
Message-ID: <c0a6f817-0225-c863-722c-19c798daaa4b@gmail.com>

On 8/9/21 8:01 AM, Rocco Yue wrote:
> @@ -6129,6 +6136,66 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
>  		__ipv6_ifa_notify(event, ifp);
>  }
>  
> +static inline size_t inet6_iframtu_msgsize(void)
> +{
> +	return NLMSG_ALIGN(sizeof(struct ifinfomsg))
> +	     + nla_total_size(IFNAMSIZ)	/* IFLA_IFNAME */
> +	     + nla_total_size(4);	/* IFLA_INET6_RA_MTU */
> +}
> +
> +static int inet6_fill_iframtu(struct sk_buff *skb, struct inet6_dev *idev)
> +{
> +	struct net_device *dev = idev->dev;
> +	struct ifinfomsg *hdr;
> +	struct nlmsghdr *nlh;
> +
> +	nlh = nlmsg_put(skb, 0, 0, RTM_NEWLINK, sizeof(*hdr), 0);
> +	if (!nlh)
> +		return -EMSGSIZE;
> +
> +	hdr = nlmsg_data(nlh);
> +	hdr->ifi_family = AF_INET6;
> +	hdr->__ifi_pad = 0;
> +	hdr->ifi_index = dev->ifindex;
> +	hdr->ifi_flags = dev_get_flags(dev);
> +	hdr->ifi_change = 0;
> +
> +	if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
> +	    nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))
> +		goto nla_put_failure;
> +
> +	nlmsg_end(skb, nlh);
> +	return 0;
> +
> +nla_put_failure:
> +	nlmsg_cancel(skb, nlh);
> +	return -EMSGSIZE;
> +}
> +
> +void inet6_iframtu_notify(struct inet6_dev *idev)
> +{
> +	struct sk_buff *skb;
> +	struct net *net = dev_net(idev->dev);
> +	int err = -ENOBUFS;
> +
> +	skb = nlmsg_new(inet6_iframtu_msgsize(), GFP_ATOMIC);
> +	if (!skb)
> +		goto errout;
> +
> +	err = inet6_fill_iframtu(skb, idev);
> +	if (err < 0) {
> +		/* -EMSGSIZE implies BUG in inet6_iframtu_msgsize() */
> +		WARN_ON(err == -EMSGSIZE);
> +		kfree_skb(skb);
> +		goto errout;
> +	}
> +	rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
> +	return;
> +errout:
> +	if (err < 0)
> +		rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
> +}

pretty sure you don't need to build a new notify function.

> +
>  #ifdef CONFIG_SYSCTL
>  
>  static int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
> index c467c6419893..a04164cbd77f 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -1496,6 +1496,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
>  		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
>  		mtu = ntohl(n);
>  
> +		if (in6_dev->ra_mtu != mtu) {
> +			in6_dev->ra_mtu = mtu;
> +			inet6_iframtu_notify(in6_dev);
> +			ND_PRINTK(2, info, "update ra_mtu to %d\n", in6_dev->ra_mtu);
> +		}
> +
>  		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
>  			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
>  		} else if (in6_dev->cnf.mtu6 != mtu) {

Since this MTU is getting reported via af_info infrastructure,
rtmsg_ifinfo should be sufficient.

>From there use 'ip monitor' to make sure you are not generating multiple
notifications; you may only need this on the error path.


From leoyang.li at nxp.com  Mon Aug  9 15:52:04 2021
From: leoyang.li at nxp.com (Leo Li)
Date: Mon, 9 Aug 2021 22:52:04 +0000
Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
 LX2160A UART
In-Reply-To: <20210615131605.616-2-thunder.leizhen@huawei.com>
References: <20210615131605.616-1-thunder.leizhen@huawei.com>
 <20210615131605.616-2-thunder.leizhen@huawei.com>
Message-ID: <AS8PR04MB8946D0EB15D631346F4D13198FF69@AS8PR04MB8946.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Zhen Lei <thunder.leizhen at huawei.com>
> Sent: Tuesday, June 15, 2021 8:16 AM
> To: Shawn Guo <shawnguo at kernel.org>; Leo Li <leoyang.li at nxp.com>; Rob
> Herring <robh+dt at kernel.org>; Mark Kettenis <mark.kettenis at xs4all.nl>;
> devicetree <devicetree at vger.kernel.org>; linux-arm-kernel <linux-arm-
> kernel at lists.infradead.org>; linux-kernel <linux-kernel at vger.kernel.org>
> Cc: Zhen Lei <thunder.leizhen at huawei.com>
> Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
> LX2160A UART
> 
> Mark Kettenis told us that:
> According to the NXP documentation, the LX2160A has a real PL011 UART.
> 
> Therefore, rewrite it to the compatible string of pl011. The property "current-
> speed" specific to "arm,sbsa-uart" is also deleted.

Sorry that I missed the discussion on the v1.  But looks like this change breaks the LX2160 boot.  The AMBA matching doesn't seem to work.  And the console is not registered correctly.

[    0.639055] OF: amba_device_add() failed (-2) for /soc/serial at 21c0000
[    0.645612] OF: amba_device_add() failed (-2) for /soc/serial at 21d0000

> 
> Suggested-by: Shawn Guo <shawnguo at kernel.org>
> Suggested-by: Mark Kettenis <mark.kettenis at xs4all.nl>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> ---
>  arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 12 ++++--------
>  1 file changed, 4 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> index c4b1a59ba424..d2e6f7285674 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> @@ -920,34 +920,30 @@ QORIQ_CLK_PLL_DIV(8)>,
>  		};
> 
>  		uart0: serial at 21c0000 {
> -			compatible = "arm,sbsa-uart","arm,pl011";
> +			compatible = "arm,pl011", "arm,primecell";
>  			reg = <0x0 0x21c0000 0x0 0x1000>;
>  			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> -			current-speed = <115200>;
>  			status = "disabled";
>  		};
> 
>  		uart1: serial at 21d0000 {
> -			compatible = "arm,sbsa-uart","arm,pl011";
> +			compatible = "arm,pl011", "arm,primecell";
>  			reg = <0x0 0x21d0000 0x0 0x1000>;
>  			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
> -			current-speed = <115200>;
>  			status = "disabled";
>  		};
> 
>  		uart2: serial at 21e0000 {
> -			compatible = "arm,sbsa-uart","arm,pl011";
> +			compatible = "arm,pl011", "arm,primecell";
>  			reg = <0x0 0x21e0000 0x0 0x1000>;
>  			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
> -			current-speed = <115200>;
>  			status = "disabled";
>  		};
> 
>  		uart3: serial at 21f0000 {
> -			compatible = "arm,sbsa-uart","arm,pl011";
> +			compatible = "arm,pl011", "arm,primecell";
>  			reg = <0x0 0x21f0000 0x0 0x1000>;
>  			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> -			current-speed = <115200>;
>  			status = "disabled";
>  		};
> 
> --
> 2.25.1
> 



From oupton at google.com  Mon Aug  9 17:04:38 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 9 Aug 2021 17:04:38 -0700
Subject: [PATCH v6 00/21] KVM: Add idempotent controls for migrating
 system counter state
In-Reply-To: <CAOQ_Qsh9wzP301xdfbwBcFXHBoYkf9PCY-+mrfmfwVWL4UexGw@mail.gmail.com>
References: <20210804085819.846610-1-oupton@google.com>
 <CAOQ_QsiVNS==c-ahnKN6Jja_+FfkWEmDnQPoP9sdNWBc1m2gsg@mail.gmail.com>
 <CAOQ_Qsh9wzP301xdfbwBcFXHBoYkf9PCY-+mrfmfwVWL4UexGw@mail.gmail.com>
Message-ID: <CAOQ_QsgkB32rgfr7=X8XNyXe2Vw3arFjo6umvgDfTLQgjU4i2A@mail.gmail.com>

On Wed, Aug 4, 2021 at 3:03 PM Oliver Upton <oupton at google.com> wrote:
>
> On Wed, Aug 4, 2021 at 4:05 AM Oliver Upton <oupton at google.com> wrote:
> >
> > On Wed, Aug 4, 2021 at 1:58 AM Oliver Upton <oupton at google.com> wrote:
> > >
> > > KVM's current means of saving/restoring system counters is plagued with
> > > temporal issues. At least on ARM64 and x86, we migrate the guest's
> > > system counter by-value through the respective guest system register
> > > values (cntvct_el0, ia32_tsc). Restoring system counters by-value is
> > > brittle as the state is not idempotent: the host system counter is still
> > > oscillating between the attempted save and restore. Furthermore, VMMs
> > > may wish to transparently live migrate guest VMs, meaning that they
> > > include the elapsed time due to live migration blackout in the guest
> > > system counter view. The VMM thread could be preempted for any number of
> > > reasons (scheduler, L0 hypervisor under nested) between the time that
> > > it calculates the desired guest counter value and when KVM actually sets
> > > this counter state.
> > >
> > > Despite the value-based interface that we present to userspace, KVM
> > > actually has idempotent guest controls by way of system counter offsets.
> > > We can avoid all of the issues associated with a value-based interface
> > > by abstracting these offset controls in new ioctls. This series
> > > introduces new vCPU device attributes to provide userspace access to the
> > > vCPU's system counter offset.
> > >
> > > Patch 1 addresses a possible race in KVM_GET_CLOCK where
> > > use_master_clock is read outside of the pvclock_gtod_sync_lock.
> > >
> > > Patch 2 adopts Paolo's suggestion, augmenting the KVM_{GET,SET}_CLOCK
> > > ioctls to provide userspace with a (host_tsc, realtime) instant. This is
> > > essential for a VMM to perform precise migration of the guest's system
> > > counters.
> > >
> > > Patches 3-4 are some preparatory changes for exposing the TSC offset to
> > > userspace. Patch 5 provides a vCPU attribute to provide userspace access
> > > to the TSC offset.
> > >
> > > Patches 6-7 implement a test for the new additions to
> > > KVM_{GET,SET}_CLOCK.
> > >
> > > Patch 8 fixes some assertions in the kvm device attribute helpers.
> > >
> > > Patches 9-10 implement at test for the tsc offset attribute introduced in
> > > patch 5.

Paolo,

Is there anything else you're waiting to see for the x86 portion of
this series after addressing Sean's comments? There's some work
remaining on the arm64 side, though I believe the two architectures
are now disjoint for this series.

--
Thanks,
Oliver

> > > Patches 11-12 lay the groundwork for patch 13, which exposes CNTVOFF_EL2
> > > through the ONE_REG interface.
> > >
> > > Patches 14-15 add test cases for userspace manipulation of the virtual
> > > counter-timer.
> > >
> > > Patches 16-17 add a vCPU attribute to adjust the host-guest offset of an
> > > ARM vCPU, but only implements support for ECV hosts. Patches 18-19 add
> > > support for non-ECV hosts by emulating physical counter offsetting.
> > >
> > > Patch 20 adds test cases for adjusting the host-guest offset, and
> > > finally patch 21 adds a test to measure the emulation overhead of
> > > CNTPCT_EL2.
> > >
> > > This series was tested on both an Ampere Mt. Jade and Haswell systems.
> > > Unfortunately, the ECV portions of this series are untested, as there is
> > > no ECV-capable hardware and the ARM fast models only partially implement
> > > ECV.
> >
> > Small correction: I was only using the foundation model. Apparently
> > the AEM FVP provides full ECV support.
>
> Ok. I've now tested this series on the FVP Base RevC fast model at v8.6 +
> ECV=2. Passes on VHE, fails on nVHE.
>
> I'll respin this series with the fix for nVHE+ECV soon.
>
> --
> Thanks,
> Oliver
>
> >
> > >
> > > Physical counter benchmark
> > > --------------------------
> > >
> > > The following data was collected by running 10000 iterations of the
> > > benchmark test from Patch 21 on an Ampere Mt. Jade reference server, A 2S
> > > machine with 2 80-core Ampere Altra SoCs. Measurements were collected
> > > for both VHE and nVHE operation using the `kvm-arm.mode=` command-line
> > > parameter.
> > >
> > > nVHE
> > > ----
> > >
> > > +--------------------+--------+---------+
> > > |       Metric       | Native | Trapped |
> > > +--------------------+--------+---------+
> > > | Average            | 54ns   | 148ns   |
> > > | Standard Deviation | 124ns  | 122ns   |
> > > | 95th Percentile    | 258ns  | 348ns   |
> > > +--------------------+--------+---------+
> > >
> > > VHE
> > > ---
> > >
> > > +--------------------+--------+---------+
> > > |       Metric       | Native | Trapped |
> > > +--------------------+--------+---------+
> > > | Average            | 53ns   | 152ns   |
> > > | Standard Deviation | 92ns   | 94ns    |
> > > | 95th Percentile    | 204ns  | 307ns   |
> > > +--------------------+--------+---------+
> > >
> > > This series applies cleanly to kvm/queue at the following commit:
> > >
> > > 6cd974485e25 ("KVM: selftests: Add a test of an unbacked nested PI descriptor")
> > >
> > > v1 -> v2:
> > >   - Reimplemented as vCPU device attributes instead of a distinct ioctl.
> > >   - Added the (realtime, host_tsc) instant support to KVM_{GET,SET}_CLOCK
> > >   - Changed the arm64 implementation to broadcast counter
> > >     offset values to all vCPUs in a guest. This upholds the
> > >     architectural expectations of a consistent counter-timer across CPUs.
> > >   - Fixed a bug with traps in VHE mode. We now configure traps on every
> > >     transition into a guest to handle differing VMs (trapped, emulated).
> > >
> > > v2 -> v3:
> > >   - Added documentation for additions to KVM_{GET,SET}_CLOCK
> > >   - Added documentation for all new vCPU attributes
> > >   - Added documentation for suggested algorithm to migrate a guest's
> > >     TSC(s)
> > >   - Bug fixes throughout series
> > >   - Rename KVM_CLOCK_REAL_TIME -> KVM_CLOCK_REALTIME
> > >
> > > v3 -> v4:
> > >   - Added patch to address incorrect device helper assertions (Drew)
> > >   - Carried Drew's r-b tags where appropriate
> > >   - x86 selftest cleanup
> > >   - Removed stale kvm_timer_init_vhe() function
> > >   - Removed unnecessary GUEST_DONE() from selftests
> > >
> > > v4 -> v5:
> > >   - Fix typo in TSC migration algorithm
> > >   - Carry more of Drew's r-b tags
> > >   - clean up run loop logic in counter emulation benchmark (missed from
> > >     Drew's comments on v3)
> > >
> > > v5 -> v6:
> > >   - Add fix for race in KVM_GET_CLOCK (Sean)
> > >   - Fix 32-bit build issues in series + use of uninitialized host tsc
> > >     value (Sean)
> > >   - General style cleanups
> > >   - Rework ARM virtual counter offsetting to match guest behavior. Use
> > >     the ONE_REG interface instead of a VM attribute (Marc)
> > >   - Maintain a single host-guest counter offset, which applies to both
> > >     physical and virtual counters
> > >   - Dropped some of Drew's r-b tags due to nontrivial patch changes
> > >     (sorry for the churn!)
> > >
> > > v1: https://lore.kernel.org/kvm/20210608214742.1897483-1-oupton at google.com/
> > > v2: https://lore.kernel.org/r/20210716212629.2232756-1-oupton at google.com
> > > v3: https://lore.kernel.org/r/20210719184949.1385910-1-oupton at google.com
> > > v4: https://lore.kernel.org/r/20210729001012.70394-1-oupton at google.com
> > > v5: https://lore.kernel.org/r/20210729173300.181775-1-oupton at google.com
> > >
> > > Oliver Upton (21):
> > >   KVM: x86: Fix potential race in KVM_GET_CLOCK
> > >   KVM: x86: Report host tsc and realtime values in KVM_GET_CLOCK
> > >   KVM: x86: Take the pvclock sync lock behind the tsc_write_lock
> > >   KVM: x86: Refactor tsc synchronization code
> > >   KVM: x86: Expose TSC offset controls to userspace
> > >   tools: arch: x86: pull in pvclock headers
> > >   selftests: KVM: Add test for KVM_{GET,SET}_CLOCK
> > >   selftests: KVM: Fix kvm device helper ioctl assertions
> > >   selftests: KVM: Add helpers for vCPU device attributes
> > >   selftests: KVM: Introduce system counter offset test
> > >   KVM: arm64: Refactor update_vtimer_cntvoff()
> > >   KVM: arm64: Separate guest/host counter offset values
> > >   KVM: arm64: Allow userspace to configure a vCPU's virtual offset
> > >   selftests: KVM: Add helper to check for register presence
> > >   selftests: KVM: Add support for aarch64 to system_counter_offset_test
> > >   arm64: cpufeature: Enumerate support for Enhanced Counter
> > >     Virtualization
> > >   KVM: arm64: Allow userspace to configure a guest's counter-timer
> > >     offset
> > >   KVM: arm64: Configure timer traps in vcpu_load() for VHE
> > >   KVM: arm64: Emulate physical counter offsetting on non-ECV systems
> > >   selftests: KVM: Test physical counter offsetting
> > >   selftests: KVM: Add counter emulation benchmark
> > >
> > >  Documentation/virt/kvm/api.rst                |  52 ++-
> > >  Documentation/virt/kvm/devices/vcpu.rst       |  85 ++++
> > >  Documentation/virt/kvm/locking.rst            |  11 +
> > >  arch/arm64/include/asm/kvm_asm.h              |   2 +
> > >  arch/arm64/include/asm/sysreg.h               |   5 +
> > >  arch/arm64/include/uapi/asm/kvm.h             |   2 +
> > >  arch/arm64/kernel/cpufeature.c                |  10 +
> > >  arch/arm64/kvm/arch_timer.c                   | 224 ++++++++++-
> > >  arch/arm64/kvm/arm.c                          |   4 +-
> > >  arch/arm64/kvm/guest.c                        |   6 +-
> > >  arch/arm64/kvm/hyp/include/hyp/switch.h       |  29 ++
> > >  arch/arm64/kvm/hyp/nvhe/hyp-main.c            |   6 +
> > >  arch/arm64/kvm/hyp/nvhe/timer-sr.c            |  16 +-
> > >  arch/arm64/kvm/hyp/vhe/timer-sr.c             |   5 +
> > >  arch/arm64/tools/cpucaps                      |   1 +
> > >  arch/x86/include/asm/kvm_host.h               |   4 +
> > >  arch/x86/include/uapi/asm/kvm.h               |   4 +
> > >  arch/x86/kvm/x86.c                            | 364 +++++++++++++-----
> > >  include/clocksource/arm_arch_timer.h          |   1 +
> > >  include/kvm/arm_arch_timer.h                  |   6 +-
> > >  include/uapi/linux/kvm.h                      |   7 +-
> > >  tools/arch/x86/include/asm/pvclock-abi.h      |  48 +++
> > >  tools/arch/x86/include/asm/pvclock.h          | 103 +++++
> > >  tools/testing/selftests/kvm/.gitignore        |   3 +
> > >  tools/testing/selftests/kvm/Makefile          |   4 +
> > >  .../kvm/aarch64/counter_emulation_benchmark.c | 207 ++++++++++
> > >  .../selftests/kvm/include/aarch64/processor.h |  24 ++
> > >  .../testing/selftests/kvm/include/kvm_util.h  |  13 +
> > >  tools/testing/selftests/kvm/lib/kvm_util.c    |  63 ++-
> > >  .../kvm/system_counter_offset_test.c          | 211 ++++++++++
> > >  .../selftests/kvm/x86_64/kvm_clock_test.c     | 204 ++++++++++
> > >  31 files changed, 1581 insertions(+), 143 deletions(-)
> > >  create mode 100644 tools/arch/x86/include/asm/pvclock-abi.h
> > >  create mode 100644 tools/arch/x86/include/asm/pvclock.h
> > >  create mode 100644 tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
> > >  create mode 100644 tools/testing/selftests/kvm/system_counter_offset_test.c
> > >  create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
> > >
> > > --
> > > 2.32.0.605.g8dce9f2422-goog
> > >


From rdunlap at infradead.org  Mon Aug  9 17:54:31 2021
From: rdunlap at infradead.org (Randy Dunlap)
Date: Mon,  9 Aug 2021 17:54:31 -0700
Subject: [PATCH] clk/at91: remove kernel-doc warnings in sama7g5.c
Message-ID: <20210810005431.22007-1-rdunlap@infradead.org>

Fix multiple kernel-doc warnings in sama7g5.c. There are several
enums and structs that were not identified as such.
There are also several anonymous structs (that scripts/kernel-doc
has problems with), so add struct names to them.

Fixes the following warnings:

drivers/clk/at91/sama7g5.c:39: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * PLL clocks identifiers
drivers/clk/at91/sama7g5.c:60: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * PLL type identifiers
drivers/clk/at91/sama7g5.c:122: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * PLL clocks description
drivers/clk/at91/sama7g5.c:289: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Master clock (MCK[1..4]) description
drivers/clk/at91/sama7g5.c:341: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * System clock description
drivers/clk/at91/sama7g5.c:365: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Peripheral clock description
drivers/clk/at91/sama7g5.c:453: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
 * Generic clock description
drivers/clk/at91/sama7g5.c:339: warning: Function parameter or member 'ep_chg_id' not described in 'master_clock'

Some kernel-doc warnings are still printed, but they are all due to
problems in the kernel-doc script (if anyone is interested in playing
with some Perl :). These warnings are:

sama7g5.c:287: warning: Function parameter or member '{' not described in 'sama7g5_plls'
sama7g5.c:287: warning: Function parameter or member '' not described in 'sama7g5_plls'
sama7g5.c:287: warning: Function parameter or member '}' not described in 'sama7g5_plls'
sama7g5.c:339: warning: Function parameter or member 'sama7g5_mckx' not described in 'master_clock'
sama7g5.c:339: warning: Function parameter or member '}' not described in 'master_clock'
sama7g5.c:360: warning: Function parameter or member 'sama7g5_systemck' not described in 'system_clock'
sama7g5.c:451: warning: Function parameter or member 'sama7g5_periphck' not described in 'periph_clock'
sama7g5.c:451: warning: Function parameter or member '' not described in 'periph_clock'
sama7g5.c:451: warning: Function parameter or member '}' not described in 'periph_clock'
sama7g5.c:841: warning: Function parameter or member 'sama7g5_gck' not described in 'generic_clock'
sama7g5.c:841: warning: Function parameter or member '}' not described in 'generic_clock'

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Reported-by: kernel test robot <lkp at intel.com>
Cc: Claudiu Beznea <claudiu.beznea at microchip.com>
Cc: Michael Turquette <mturquette at baylibre.com>
Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Eugen Hristev <eugen.hristev at microchip.com>
Cc: linux-clk at vger.kernel.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: Jonathan Corbet <corbet at lwn.net>
---
 drivers/clk/at91/sama7g5.c |   27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

--- linux-next-20210809.orig/drivers/clk/at91/sama7g5.c
+++ linux-next-20210809/drivers/clk/at91/sama7g5.c
@@ -36,7 +36,7 @@ static DEFINE_SPINLOCK(pmc_mck0_lock);
 static DEFINE_SPINLOCK(pmc_mckX_lock);
 
 /**
- * PLL clocks identifiers
+ * enum pll_ids - PLL clocks identifiers
  * @PLL_ID_CPU:		CPU PLL identifier
  * @PLL_ID_SYS:		System PLL identifier
  * @PLL_ID_DDR:		DDR PLL identifier
@@ -44,6 +44,7 @@ static DEFINE_SPINLOCK(pmc_mckX_lock);
  * @PLL_ID_BAUD:	Baud PLL identifier
  * @PLL_ID_AUDIO:	Audio PLL identifier
  * @PLL_ID_ETH:		Ethernet PLL identifier
+ * @PLL_ID_MAX:		Number of PLL_ID values (1 more than the last valid PLL_ID)
  */
 enum pll_ids {
 	PLL_ID_CPU,
@@ -57,7 +58,7 @@ enum pll_ids {
 };
 
 /**
- * PLL type identifiers
+ * enum pll_type - PLL type identifiers
  * @PLL_TYPE_FRAC:	fractional PLL identifier
  * @PLL_TYPE_DIV:	divider PLL identifier
  */
@@ -119,7 +120,7 @@ static const struct clk_pll_characterist
 };
 
 /**
- * PLL clocks description
+ * struct sama7g5_plls - PLL clocks description
  * @n:		clock name
  * @p:		clock parent
  * @l:		clock layout
@@ -128,7 +129,7 @@ static const struct clk_pll_characterist
  * @f:		clock flags
  * @eid:	export index in sama7g5->chws[] array
  */
-static const struct {
+static const struct sama7g5_plls {
 	const char *n;
 	const char *p;
 	const struct clk_pll_layout *l;
@@ -286,17 +287,17 @@ static const struct {
 };
 
 /**
- * Master clock (MCK[1..4]) description
+ * struct master_clock - Master clock (MCK[1..4]) description
  * @n:			clock name
  * @ep:			extra parents names array
- * @ep_chg_chg_id:	index in parents array that specifies the changeable
+ * @ep_chg_id:		index in parents array that specifies the changeable
  *			parent
  * @ep_count:		extra parents count
  * @ep_mux_table:	mux table for extra parents
  * @id:			clock id
  * @c:			true if clock is critical and cannot be disabled
  */
-static const struct {
+static const struct master_clock {
 	const char *n;
 	const char *ep[4];
 	int ep_chg_id;
@@ -338,12 +339,12 @@ static const struct {
 };
 
 /**
- * System clock description
+ * struct system_clock - System clock description
  * @n:	clock name
  * @p:	clock parent name
  * @id: clock id
  */
-static const struct {
+static const struct system_clock {
 	const char *n;
 	const char *p;
 	u8 id;
@@ -362,14 +363,14 @@ static const struct {
 static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, };
 
 /**
- * Peripheral clock description
+ * struct periph_clock - Peripheral clock description
  * @n:		clock name
  * @p:		clock parent name
  * @r:		clock range values
  * @id:		clock id
  * @chgp:	index in parent array of the changeable parent
  */
-static const struct {
+static const struct periph_clock {
 	const char *n;
 	const char *p;
 	struct clk_range r;
@@ -450,7 +451,7 @@ static const struct {
 };
 
 /**
- * Generic clock description
+ * struct generic_clock - Generic clock description
  * @n:			clock name
  * @pp:			PLL parents
  * @pp_mux_table:	PLL parents mux table
@@ -459,7 +460,7 @@ static const struct {
  * @pp_count:		PLL parents count
  * @id:			clock id
  */
-static const struct {
+static const struct generic_clock {
 	const char *n;
 	const char *pp[8];
 	const char pp_mux_table[8];


From sunilmut at microsoft.com  Mon Aug  9 18:10:40 2021
From: sunilmut at microsoft.com (Sunil Muthuswamy)
Date: Tue, 10 Aug 2021 01:10:40 +0000
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <87pmunasik.wl-maz@kernel.org>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>	<87r1f9wooc.wl-maz@kernel.org>
 <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87wnp0b86y.wl-maz@kernel.org>
 <MW4PR21MB2002ABD170CC9786CDF5D493C0F39@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87o8a81boi.wl-maz@kernel.org>
 <MW4PR21MB200286E2CF4DA229D7059598C0F69@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87pmunasik.wl-maz@kernel.org>
Message-ID: <MW4PR21MB20022D4903CDD8F989C30C50C0F79@MW4PR21MB2002.namprd21.prod.outlook.com>

On Monday, August 9, 2021 2:15 AM,
Marc Zyngier <maz at kernel.org> wrote:
[...]
> If you plug directly into the GICv3 layer, I'd rather you inject SPIs,
> just like any other non-architectural MSI controller. You can directly
> interface with the ACPI GSI layer for that, without any need to mess
> with the GICv3 internals. The SPI space isn't very large, but still
> much larger than the equivalent x86 space (close to 1000).
> 
> If time is of the essence, I suggest you go the SPI way. For anything
> involving LPIs, I really want to see a firmware spec that works for
> everyone as opposed to a localised Hyper-V hack.
> 
Ok, thanks. Before we commit to anything, I would like to make sure
that I am on the same page in terms of your description. With that in
mind, I have few questions. Hopefully, these should settle the matter.
1. If we go with the SPI route, then the way I envision it is that the 
    Hyper-V vPCI driver will implement an IRQ chip, which will take
    care of allocating & managing the SPI interrupt for Hyper-V vPCI.
    This IRQ chip will parent itself to the architectural GIC IRQ chip for
    general interrupt management. Does that match with your
    understanding/suggestion as well?

2. In the above, how will Hyper-V vPCI module discover the
    architectural GIC IRQ domain generically for virtual devices that
    are not firmware enumerated? Today, the GIC v3 IRQ domain is
    not exported and the general 'irq_find_xyz' APIs only work for
    firmware enumerated devices (i.e. something that has a fwnode
    handle).

3. Longer term, if we implement LPIs (with an ITS or Direct LPI), to
    be able to support all scenarios such as Live Migration, the
    Hyper-V virtual PCI driver would like to be able to control the
    MSI address & data that gets programmed on the device
   (i.e. .irq_compose_msi_msg). We can use the architectural
   methods for everything else. Does that fit into the realm of
   what would be acceptable upstream?

Thanks,
Sunil


From thunder.leizhen at huawei.com  Mon Aug  9 18:28:05 2021
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Tue, 10 Aug 2021 09:28:05 +0800
Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
 LX2160A UART
In-Reply-To: <AS8PR04MB8946D0EB15D631346F4D13198FF69@AS8PR04MB8946.eurprd04.prod.outlook.com>
References: <20210615131605.616-1-thunder.leizhen@huawei.com>
 <20210615131605.616-2-thunder.leizhen@huawei.com>
 <AS8PR04MB8946D0EB15D631346F4D13198FF69@AS8PR04MB8946.eurprd04.prod.outlook.com>
Message-ID: <03d7c7be-2f19-9fdf-2a4e-f49a62bb82f6@huawei.com>



On 2021/8/10 6:52, Leo Li wrote:
> 
> 
>> -----Original Message-----
>> From: Zhen Lei <thunder.leizhen at huawei.com>
>> Sent: Tuesday, June 15, 2021 8:16 AM
>> To: Shawn Guo <shawnguo at kernel.org>; Leo Li <leoyang.li at nxp.com>; Rob
>> Herring <robh+dt at kernel.org>; Mark Kettenis <mark.kettenis at xs4all.nl>;
>> devicetree <devicetree at vger.kernel.org>; linux-arm-kernel <linux-arm-
>> kernel at lists.infradead.org>; linux-kernel <linux-kernel at vger.kernel.org>
>> Cc: Zhen Lei <thunder.leizhen at huawei.com>
>> Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
>> LX2160A UART
>>
>> Mark Kettenis told us that:
>> According to the NXP documentation, the LX2160A has a real PL011 UART.
>>
>> Therefore, rewrite it to the compatible string of pl011. The property "current-
>> speed" specific to "arm,sbsa-uart" is also deleted.
> 
> Sorry that I missed the discussion on the v1.  But looks like this change breaks the LX2160 boot.  The AMBA matching doesn't seem to work.  And the console is not registered correctly.

https://lore.kernel.org/linux-arm-kernel/cba3a29f-92b5-072a-9a27-60240f072dad at huawei.com/

Maybe we should fall back to v1.

> 
> [    0.639055] OF: amba_device_add() failed (-2) for /soc/serial at 21c0000
> [    0.645612] OF: amba_device_add() failed (-2) for /soc/serial at 21d0000
> 
>>
>> Suggested-by: Shawn Guo <shawnguo at kernel.org>
>> Suggested-by: Mark Kettenis <mark.kettenis at xs4all.nl>
>> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
>> ---
>>  arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 12 ++++--------
>>  1 file changed, 4 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
>> b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
>> index c4b1a59ba424..d2e6f7285674 100644
>> --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
>> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
>> @@ -920,34 +920,30 @@ QORIQ_CLK_PLL_DIV(8)>,
>>  		};
>>
>>  		uart0: serial at 21c0000 {
>> -			compatible = "arm,sbsa-uart","arm,pl011";
>> +			compatible = "arm,pl011", "arm,primecell";
>>  			reg = <0x0 0x21c0000 0x0 0x1000>;
>>  			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>> -			current-speed = <115200>;
>>  			status = "disabled";
>>  		};
>>
>>  		uart1: serial at 21d0000 {
>> -			compatible = "arm,sbsa-uart","arm,pl011";
>> +			compatible = "arm,pl011", "arm,primecell";
>>  			reg = <0x0 0x21d0000 0x0 0x1000>;
>>  			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
>> -			current-speed = <115200>;
>>  			status = "disabled";
>>  		};
>>
>>  		uart2: serial at 21e0000 {
>> -			compatible = "arm,sbsa-uart","arm,pl011";
>> +			compatible = "arm,pl011", "arm,primecell";
>>  			reg = <0x0 0x21e0000 0x0 0x1000>;
>>  			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
>> -			current-speed = <115200>;
>>  			status = "disabled";
>>  		};
>>
>>  		uart3: serial at 21f0000 {
>> -			compatible = "arm,sbsa-uart","arm,pl011";
>> +			compatible = "arm,pl011", "arm,primecell";
>>  			reg = <0x0 0x21f0000 0x0 0x1000>;
>>  			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
>> -			current-speed = <115200>;
>>  			status = "disabled";
>>  		};
>>
>> --
>> 2.25.1
>>
> 
> .
> 


From ck.hu at mediatek.com  Mon Aug  9 18:52:58 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Tue, 10 Aug 2021 09:52:58 +0800
Subject: [PATCH v1] drm/mediatek: add AAL output size configuration
In-Reply-To: <20210709055635.22296-1-jason-jh.lin@mediatek.com>
References: <20210709055635.22296-1-jason-jh.lin@mediatek.com>
Message-ID: <1628560378.15645.1.camel@mtksdaap41>

Hi, Jason:

On Fri, 2021-07-09 at 13:56 +0800, jason-jh.lin wrote:
> To avoid the output height is incorrect, AAL_OUTPUT_SIZE
> configuration should be set.
> 
> Fixes: 0664d1392c26 ("drm/mediatek: Add AAL engine basic function")
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 75bc00e17fc4..fc608d05f040 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -34,6 +34,7 @@
>  
>  #define DISP_AAL_EN				0x0000
>  #define DISP_AAL_SIZE				0x0030
> +#define DISP_AAL_OUTPUT_SIZE			0x04d8
>  
>  #define DISP_DITHER_EN				0x0000
>  #define DITHER_EN				BIT(0)
> @@ -196,7 +197,12 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
>  {
>  	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>  
> -	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
> +	mtk_ddp_write(cmdq_pkt, w << 16 | h,
> +		      &priv->cmdq_reg, priv->regs,
> +				DISP_AAL_SIZE);

This modification break one line into multiple line. This is not related
to this patch.

> +	mtk_ddp_write(cmdq_pkt, w << 16 | h,
> +		      &priv->cmdq_reg, priv->regs,
> +				DISP_AAL_OUTPUT_SIZE);

One line.

Regards,
CK

>  }
>  
>  static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)


From ck.hu at mediatek.com  Mon Aug  9 18:58:40 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Tue, 10 Aug 2021 09:58:40 +0800
Subject: [PATCH v1] drm/mediatek: Add component_del in OVL remove function
In-Reply-To: <20210709034308.21713-1-jason-jh.lin@mediatek.com>
References: <20210709034308.21713-1-jason-jh.lin@mediatek.com>
Message-ID: <1628560720.15645.4.camel@mtksdaap41>

Hi, Jason:

On Fri, 2021-07-09 at 11:43 +0800, jason-jh.lin wrote:
> Add component_del in OVL remove function to make it symmetrical
> to component_add in probe function.
> 
> Fixes: ff1395609e20 ("drm/mediatek: Move mtk_ddp_comp_init() from sub driver to DRM driver")
> 

In patch [1], both OVL and COLOR has the same problem. I would like you
to fix both bug. It could be in one patch.


[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.14-rc5&id=ff1395609e20c1cd98b3ec65d16dc18f0471dca3


Regards,
CK

> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 961f87f8d4d1..081c96aa7f72 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -158,7 +158,6 @@ void mtk_ovl_stop(struct device *dev)
>  		reg = reg & ~OVL_LAYER_SMI_ID_EN;
>  		writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
>  	}
> -
>  }
>  
>  void mtk_ovl_config(struct device *dev, unsigned int w,
> @@ -424,6 +423,8 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
>  
>  static int mtk_disp_ovl_remove(struct platform_device *pdev)
>  {
> +	component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
> +
>  	return 0;
>  }
>  


From max.chou at realtek.com  Mon Aug  9 19:01:47 2021
From: max.chou at realtek.com (max.chou at realtek.com)
Date: Tue, 10 Aug 2021 10:01:47 +0800
Subject: [PATCH v2] Bluetooth: btusb: Remove WAKEUP_DISABLE and add
 WAKEUP_AUTOSUSPEND for Realtek devices
Message-ID: <20210810020147.14276-1-max.chou@realtek.com>

From: Max Chou <max.chou at realtek.com>

For the commit of 9e45524a011107a73bc2cdde8370c61e82e93a4d, wakeup is
always disabled for Realtek devices. However, there's the capability
for Realtek devices to apply USB wake-up.

In this commit, remove WAKEUP_DISABLE feature for Realtek devices.
If users would switch wake-up, they should access
"/sys/bus/usb/.../power/wakeup"

In this commit, it also adds the feature as WAKEUP_AUTOSUSPEND
for Realtek devices because it should set do_remote_wakeup on autosuspend.

Signed-off-by: Max Chou <max.chou at realtek.com>
Tested-by: Hilda Wu <hildawu at realtek.com>
Reviewed-by: Archie Pusaka <apusaka at chromium.org>
Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit at chromium.org>
---
Changes in v2:
-fix the compiling error due to the incorrect patch file submited
---
 drivers/bluetooth/btusb.c | 28 +++++++++-------------------
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 1876a960b3dc..92919f379331 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -537,7 +537,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
 #define BTUSB_OOB_WAKE_ENABLED	11
 #define BTUSB_HW_RESET_ACTIVE	12
 #define BTUSB_TX_WAIT_VND_EVT	13
-#define BTUSB_WAKEUP_DISABLE	14
+#define BTUSB_WAKEUP_AUTOSUSPEND	14
 
 struct btusb_data {
 	struct hci_dev       *hdev;
@@ -1358,13 +1358,6 @@ static int btusb_open(struct hci_dev *hdev)
 
 	data->intf->needs_remote_wakeup = 1;
 
-	/* Disable device remote wakeup when host is suspended
-	 * For Realtek chips, global suspend without
-	 * SET_FEATURE (DEVICE_REMOTE_WAKEUP) can save more power in device.
-	 */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
-		device_wakeup_disable(&data->udev->dev);
-
 	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
 		goto done;
 
@@ -1431,7 +1424,7 @@ static int btusb_close(struct hci_dev *hdev)
 	data->intf->needs_remote_wakeup = 0;
 
 	/* Enable remote wake up for auto-suspend */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
+	if (test_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags))
 		data->intf->needs_remote_wakeup = 1;
 
 	usb_autopm_put_interface(data->intf);
@@ -4452,9 +4445,6 @@ static bool btusb_prevent_wake(struct hci_dev *hdev)
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
 
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
-		return true;
-
 	return !device_may_wakeup(&data->udev->dev);
 }
 
@@ -4752,11 +4742,8 @@ static int btusb_probe(struct usb_interface *intf,
 		hdev->shutdown = btrtl_shutdown_realtek;
 		hdev->cmd_timeout = btusb_rtl_cmd_timeout;
 
-		/* Realtek devices lose their updated firmware over global
-		 * suspend that means host doesn't send SET_FEATURE
-		 * (DEVICE_REMOTE_WAKEUP)
-		 */
-		set_bit(BTUSB_WAKEUP_DISABLE, &data->flags);
+		/* Realtek devices need to set remote wakeup on auto-suspend */
+		set_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags);
 	}
 
 	if (!reset)
@@ -4931,12 +4918,15 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
 	 * Actually, it depends on whether the usb host sends
 	 * set feature (enable wakeup) or not.
 	 */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags)) {
+	if (test_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags)) {
 		if (PMSG_IS_AUTO(message) &&
 		    device_can_wakeup(&data->udev->dev))
 			data->udev->do_remote_wakeup = 1;
-		else if (!PMSG_IS_AUTO(message))
+		else if (!PMSG_IS_AUTO(message) &&
+			 !device_may_wakeup(&data->udev->dev)) {
+			data->udev->do_remote_wakeup = 0;
 			data->udev->reset_resume = 1;
+		}
 	}
 
 	return 0;
-- 
2.17.1



From guangming.cao at mediatek.com  Mon Aug  9 19:02:54 2021
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Tue, 10 Aug 2021 10:02:54 +0800
Subject: [PATCH] dma_heap: enable map_attrs when (un)map_attachment
In-Reply-To: <20210721094314.117413-1-guangming.cao@mediatek.com>
References: <20210721094314.117413-1-guangming.cao@mediatek.com>
Message-ID: <20210810020254.103134-1-guangming.cao@mediatek.com>

From: Guangming Cao <Guangming.Cao at mediatek.com>

For dma-heap users, they can't bypass cache sync when (un)map
iova with dma heap. But they can do it by adding
DMA_ATTR_SKIP_CPU_SYNC into dma_alloc_attrs.

To Keep alignment, add map_attrs support for dma_heap when
(un)map_attachment.

Signed-off-by: Guangming Cao <Guangming.Cao at mediatek.com>
---
 drivers/dma-buf/heaps/cma_heap.c    | 6 ++++--
 drivers/dma-buf/heaps/system_heap.c | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index 0c05b79870f9..2c9feb3bfc3e 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -99,9 +99,10 @@ static struct sg_table *cma_heap_map_dma_buf(struct dma_buf_attachment *attachme
 {
 	struct dma_heap_attachment *a = attachment->priv;
 	struct sg_table *table = &a->table;
+	int attrs = attachment->dma_map_attrs;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
 	if (ret)
 		return ERR_PTR(-ENOMEM);
 	a->mapped = true;
@@ -113,9 +114,10 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   enum dma_data_direction direction)
 {
 	struct dma_heap_attachment *a = attachment->priv;
+	int attrs = attachment->dma_map_attrs;
 
 	a->mapped = false;
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(attachment->dev, table, direction, attrs);
 }
 
 static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 23a7e74ef966..fc7b1e02988e 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -130,9 +130,10 @@ static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attac
 {
 	struct dma_heap_attachment *a = attachment->priv;
 	struct sg_table *table = a->table;
+	int attrs = attachment->dma_map_attrs;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
 	if (ret)
 		return ERR_PTR(ret);
 
@@ -145,9 +146,10 @@ static void system_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				      enum dma_data_direction direction)
 {
 	struct dma_heap_attachment *a = attachment->priv;
+	int attrs = attachment->dma_map_attrs;
 
 	a->mapped = false;
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(attachment->dev, table, direction, attrs);
 }
 
 static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
-- 
2.17.1

From qiangqing.zhang at nxp.com  Mon Aug  9 19:21:55 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Tue, 10 Aug 2021 02:21:55 +0000
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
Message-ID: <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>


Hi Florian,

> -----Original Message-----
> From: Florian Fainelli <f.fainelli at gmail.com>
> Sent: 2021?8?10? 2:40
> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
> netdev at vger.kernel.org; devicetree at vger.kernel.org;
> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
> wakeup-irq" property
> 
> 
> 
> On 8/8/2021 10:08 PM, Joakim Zhang wrote:
> >
> > Hi Florian,
> >
> >> -----Original Message-----
> >> From: Florian Fainelli <f.fainelli at gmail.com>
> >> Sent: 2021?8?5? 17:18
> >> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
> >> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> >> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
> >> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
> >> netdev at vger.kernel.org; devicetree at vger.kernel.org;
> >> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> >> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add
> >> "fsl, wakeup-irq" property
> >>
> >>
> >>
> >> On 8/5/2021 12:46 AM, Joakim Zhang wrote:
> >>> Add "fsl,wakeup-irq" property for FEC controller to select wakeup
> >>> irq source.
> >>>
> >>> Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
> >>> Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
> >>
> >> Why are not you making use of the standard interrupts-extended
> >> property which allows different interrupt lines to be originating
> >> from different interrupt controllers, e.g.:
> >>
> >> interrupts-extended = <&gic GIC_SPI 112 4>, <&wakeup_intc 0>;
> >
> > Thanks.
> >
> > AFAIK, interrupts-extended should be used instead of interrupts when a
> > device is connected to multiple interrupt controllers as it encodes a
> > parent phandle with each interrupt specifier. However, for FEC controller, all
> interrupt lines are originating from the same interrupt controllers.
> 
> OK, so why this custom property then?
> 
> >
> > 1) FEC controller has up to 4 interrupt lines and all of these are routed to GIC
> interrupt controller.
> > 2) FEC has a wakeup interrupt signal and always are mixed with other
> interrupt signals, and then output to one interrupt line.
> > 3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but for i.MX8M
> serials, are mixed to int2 line.
> > 4) Now driver treat int0 as the wakeup source by default, it is broken for
> i.MX8M.
> 
> I don't really know what to make of your response, it seems to me that you are
> carrying some legacy Device Tree properties that were invented when
> interrupts-extended did not exist and we did not know any better.

As I described in former mail, it is not related to interrupts-extended property.

Let's take a look, e.g.

1) arch/arm/boot/dts/imx7d.dtsi
interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
		<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
		<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
		<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "int0", "int1", "int2", "pps";

For these 4 interrupts are originating from GIC interrupt controller, "int0" for queue 0 and other interrupt signals, containing wakeup;
"int1" for queue 1; "int2" for queue 2.

2) arch/arm64/boot/dts/freescale/imx8mq.dtsi
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
	<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
	<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
	<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "int0", "int1", "int2", "pps";

For these 4 interrupts are also originating from GIC interrupt controller, "int0" for queue 0; "int1" for queue 1; "int2" for queue 2 and other
interrupt signals, containing wakeup.

If we want to use WoL feature, we need invoke enable_irq_wake() to let this specific interrupt line be a wakeup source. For FEC driver now,
it treats "int0" as wakeup interrupt by default. Obviously it's not fine for i.MX8M serials, since SoC mix wakeup interrupt signal into "int2",
so I add this "fsl,wakeup-irq" custom property to indicate which interrupt line contains wakeup signal.

Not sure if I have explained it clearly enough, from my point of view, I think interrupts-extended property can't fix this issue, right?

If there is any common properties can be used for it, please let me know. Or any other better solutions also be appreciated. Thanks.
 
Best Regards,
Joakim Zhang
> --
> Florian

From boqun.feng at gmail.com  Mon Aug  9 19:42:21 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Tue, 10 Aug 2021 10:42:21 +0800
Subject: [PATCH v2 2/4] sched: Introduce is_pcpu_safe()
In-Reply-To: <20210807005807.1083943-3-valentin.schneider@arm.com>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
 <20210807005807.1083943-3-valentin.schneider@arm.com>
Message-ID: <YRHnjQqf28/uFq+Z@boqun-archlinux>

Hi,

On Sat, Aug 07, 2021 at 01:58:05AM +0100, Valentin Schneider wrote:
> Some areas use preempt_disable() + preempt_enable() to safely access
> per-CPU data. The PREEMPT_RT folks have shown this can also be done by
> keeping preemption enabled and instead disabling migration (and acquiring a
> sleepable lock, if relevant).
> 
> Introduce a helper which checks whether the current task can safely access
> per-CPU data, IOW if the task's context guarantees the accesses will target
> a single CPU. This accounts for preemption, CPU affinity, and migrate
> disable - note that the CPU affinity check also mandates the presence of
> PF_NO_SETAFFINITY, as otherwise userspace could concurrently render the
> upcoming per-CPU access(es) unsafe.
> 
> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
> ---
>  include/linux/sched.h | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index debc960f41e3..b77d65f677f6 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
>  #endif
>  }
>  
> +/* Is the current task guaranteed not to be migrated elsewhere? */
> +static inline bool is_pcpu_safe(void)
> +{
> +#ifdef CONFIG_SMP
> +	return !preemptible() || is_percpu_thread() || current->migration_disabled;
> +#else
> +	return true;
> +#endif
> +}

I wonder whether the following can happen, say thread A is a worker
thread for CPU 1, so it has the flag PF_NO_SETAFFINITY set.

	{ percpu variable X on CPU 2 is initially 0 }

	thread A
	========

	<preemption enabled>
	if (is_pcpu_safe()) { // nr_cpus_allowed == 1, so return true.
		<preempted>
		<hot unplug CPU 1>
			unbinder_workers(1); // A->cpus_mask becomes cpu_possible_mask
		<back to run on CPU 2>
		__this_cpu_inc(X);
		  tmp = X; // tmp == 0
		  <preempted>
		  <in thread B>
		  this_cpu_inc(X); // X becomes 1
		  <back to run A on CPU 2>
		  X = tmp + 1; // race!
	}

if so, then is_percpu_thread() doesn't indicate is_pcpu_safe()?

Regards,
Boqun

> +
>  /* Per-process atomic flags. */
>  #define PFA_NO_NEW_PRIVS		0	/* May not gain new privileges. */
>  #define PFA_SPREAD_PAGE			1	/* Spread page cache over cpuset */
> -- 
> 2.25.1
> 


From jason-jh.lin at mediatek.com  Mon Aug  9 19:55:03 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Tue, 10 Aug 2021 10:55:03 +0800
Subject: [PATCH v2] drm/mediatek: add AAL output size configuration
Message-ID: <20210810025503.16353-1-jason-jh.lin@mediatek.com>

To avoid the output width and height is incorrect,
AAL_OUTPUT_SIZE configuration should be set.

Fixes: 0664d1392c26 ("drm/mediatek: Add AAL engine basic function")
Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
Change in v2:
- fix to one line
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 75bc00e17fc4..50d20562e612 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -34,6 +34,7 @@
 
 #define DISP_AAL_EN				0x0000
 #define DISP_AAL_SIZE				0x0030
+#define DISP_AAL_OUTPUT_SIZE			0x04d8
 
 #define DISP_DITHER_EN				0x0000
 #define DITHER_EN				BIT(0)
@@ -197,6 +198,7 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
 	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_OUTPUT_SIZE);
 }
 
 static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
-- 
2.18.0

From leoyang.li at nxp.com  Mon Aug  9 20:38:26 2021
From: leoyang.li at nxp.com (Leo Li)
Date: Tue, 10 Aug 2021 03:38:26 +0000
Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
 LX2160A UART
In-Reply-To: <03d7c7be-2f19-9fdf-2a4e-f49a62bb82f6@huawei.com>
References: <20210615131605.616-1-thunder.leizhen@huawei.com>
 <20210615131605.616-2-thunder.leizhen@huawei.com>
 <AS8PR04MB8946D0EB15D631346F4D13198FF69@AS8PR04MB8946.eurprd04.prod.outlook.com>
 <03d7c7be-2f19-9fdf-2a4e-f49a62bb82f6@huawei.com>
Message-ID: <AS8PR04MB8946913A8B97C18240ADBAEA8FF79@AS8PR04MB8946.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Leizhen (ThunderTown) <thunder.leizhen at huawei.com>
> Sent: Monday, August 9, 2021 8:28 PM
> To: Leo Li <leoyang.li at nxp.com>; Shawn Guo <shawnguo at kernel.org>; Rob
> Herring <robh+dt at kernel.org>; Mark Kettenis <mark.kettenis at xs4all.nl>;
> devicetree <devicetree at vger.kernel.org>; linux-arm-kernel <linux-arm-
> kernel at lists.infradead.org>; linux-kernel <linux-kernel at vger.kernel.org>
> Subject: Re: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
> LX2160A UART
> 
> 
> 
> On 2021/8/10 6:52, Leo Li wrote:
> >
> >
> >> -----Original Message-----
> >> From: Zhen Lei <thunder.leizhen at huawei.com>
> >> Sent: Tuesday, June 15, 2021 8:16 AM
> >> To: Shawn Guo <shawnguo at kernel.org>; Leo Li <leoyang.li at nxp.com>;
> Rob
> >> Herring <robh+dt at kernel.org>; Mark Kettenis
> >> <mark.kettenis at xs4all.nl>; devicetree <devicetree at vger.kernel.org>;
> >> linux-arm-kernel <linux-arm- kernel at lists.infradead.org>;
> >> linux-kernel <linux-kernel at vger.kernel.org>
> >> Cc: Zhen Lei <thunder.leizhen at huawei.com>
> >> Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible
> >> string of LX2160A UART
> >>
> >> Mark Kettenis told us that:
> >> According to the NXP documentation, the LX2160A has a real PL011 UART.
> >>
> >> Therefore, rewrite it to the compatible string of pl011. The property
> >> "current- speed" specific to "arm,sbsa-uart" is also deleted.
> >
> > Sorry that I missed the discussion on the v1.  But looks like this change
> breaks the LX2160 boot.  The AMBA matching doesn't seem to work.  And
> the console is not registered correctly.
> 
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.k
> ernel.org%2Flinux-arm-kernel%2Fcba3a29f-92b5-072a-9a27-
> 60240f072dad%40huawei.com%2F&amp;data=04%7C01%7Cleoyang.li%40nx
> p.com%7C9986b52f71724d7f6ae108d95b9e1d9b%7C686ea1d3bc2b4c6fa92cd
> 99c5c301635%7C0%7C0%7C637641556923909225%7CUnknown%7CTWFpbGZ
> sb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6M
> n0%3D%7C1000&amp;sdata=wReesSfMj1hV2iPTN0%2F%2B%2Fb%2BKJH8xF
> LLcDgOMfjx731I%3D&amp;reserved=0
> 
> Maybe we should fall back to v1.

I didn't look into the problem in detail.  Probably it is because of lacking the clock properties needed by the AMBA bus?

> 
> >
> > [    0.639055] OF: amba_device_add() failed (-2) for /soc/serial at 21c0000
> > [    0.645612] OF: amba_device_add() failed (-2) for /soc/serial at 21d0000
> >
> >>
> >> Suggested-by: Shawn Guo <shawnguo at kernel.org>
> >> Suggested-by: Mark Kettenis <mark.kettenis at xs4all.nl>
> >> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> >> ---
> >>  arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 12 ++++--------
> >>  1 file changed, 4 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> >> b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> >> index c4b1a59ba424..d2e6f7285674 100644
> >> --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> >> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> >> @@ -920,34 +920,30 @@ QORIQ_CLK_PLL_DIV(8)>,
> >>  		};
> >>
> >>  		uart0: serial at 21c0000 {
> >> -			compatible = "arm,sbsa-uart","arm,pl011";
> >> +			compatible = "arm,pl011", "arm,primecell";
> >>  			reg = <0x0 0x21c0000 0x0 0x1000>;
> >>  			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> >> -			current-speed = <115200>;
> >>  			status = "disabled";
> >>  		};
> >>
> >>  		uart1: serial at 21d0000 {
> >> -			compatible = "arm,sbsa-uart","arm,pl011";
> >> +			compatible = "arm,pl011", "arm,primecell";
> >>  			reg = <0x0 0x21d0000 0x0 0x1000>;
> >>  			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
> >> -			current-speed = <115200>;
> >>  			status = "disabled";
> >>  		};
> >>
> >>  		uart2: serial at 21e0000 {
> >> -			compatible = "arm,sbsa-uart","arm,pl011";
> >> +			compatible = "arm,pl011", "arm,primecell";
> >>  			reg = <0x0 0x21e0000 0x0 0x1000>;
> >>  			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
> >> -			current-speed = <115200>;
> >>  			status = "disabled";
> >>  		};
> >>
> >>  		uart3: serial at 21f0000 {
> >> -			compatible = "arm,sbsa-uart","arm,pl011";
> >> +			compatible = "arm,pl011", "arm,primecell";
> >>  			reg = <0x0 0x21f0000 0x0 0x1000>;
> >>  			interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> >> -			current-speed = <115200>;
> >>  			status = "disabled";
> >>  		};
> >>
> >> --
> >> 2.25.1
> >>
> >
> > .
> >


From jason-jh.lin at mediatek.com  Mon Aug  9 21:01:48 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Tue, 10 Aug 2021 12:01:48 +0800
Subject: [PATCH v2] drm/mediatek: Add component_del in OVL and COLOR remove
 function
Message-ID: <20210810040148.17157-1-jason-jh.lin@mediatek.com>

Add component_del in OVL and COLOR remove function.

Fixes: ff1395609e20 ("drm/mediatek: Move mtk_ddp_comp_init() from sub driver to DRM driver")
Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
Change in v2:
- add component_del function in COLOR remove function
---
 drivers/gpu/drm/mediatek/mtk_disp_color.c | 2 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c   | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index 6f4c80bbc0eb..473f5bb5cbad 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -133,6 +133,8 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
 
 static int mtk_disp_color_remove(struct platform_device *pdev)
 {
+	component_del(&pdev->dev, &mtk_disp_color_component_ops);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index fa9d79963cd3..5326989d5206 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -423,6 +423,8 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 
 static int mtk_disp_ovl_remove(struct platform_device *pdev)
 {
+	component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
+
 	return 0;
 }
 
-- 
2.18.0

From email2tema at gmail.com  Mon Aug  9 21:16:29 2021
From: email2tema at gmail.com (Artem Lapkin)
Date: Tue, 10 Aug 2021 12:16:29 +0800
Subject: [PATCH 1/2] arm64: dts: meson: add spdif out to khadas-vim
Message-ID: <20210810041630.3673406-1-art@khadas.com>

Add spdif output audio support to khadas-vim

Signed-off-by: Artem Lapkin <art at khadas.com>
---
 .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts  | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
index 60feac0179c0..01f13822a616 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
@@ -64,6 +64,13 @@ hdmi_connector_in: endpoint {
 		};
 	};
 
+	spdif_dit: audio-codec-0 {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+		status = "okay";
+		sound-name-prefix = "DIT";
+	};
+
 	sound {
 		compatible = "amlogic,gx-sound-card";
 		model = "KHADAS-VIM";
@@ -97,11 +104,21 @@ codec-0 {
 				sound-dai = <&hdmi_tx>;
 			};
 		};
+
+		dai-link-3 {
+			sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
+
+			codec-0 {
+				sound-dai = <&spdif_dit>;
+			};
+		};
 	};
 };
 
 &aiu {
 	status = "okay";
+	pinctrl-0 = <&spdif_out_h_pins>;
+	pinctrl-names = "default";
 };
 
 &cec_AO {
-- 
2.25.1



From email2tema at gmail.com  Mon Aug  9 21:16:30 2021
From: email2tema at gmail.com (Artem Lapkin)
Date: Tue, 10 Aug 2021 12:16:30 +0800
Subject: [PATCH 2/2] arm64: dts: meson: add spdif out to khadas-vim2
In-Reply-To: <20210810041630.3673406-1-art@khadas.com>
References: <20210810041630.3673406-1-art@khadas.com>
Message-ID: <20210810041630.3673406-2-art@khadas.com>

Add spdif output audio support to khadas-vim2

Signed-off-by: Artem Lapkin <art at khadas.com>
---
 .../boot/dts/amlogic/meson-gxm-khadas-vim2.dts  | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
index 18a4b7a6c5df..a129a827f6ee 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
@@ -146,6 +146,13 @@ wifi32k: wifi32k {
 		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
 	};
 
+	spdif_dit: audio-codec-0 {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+		status = "okay";
+		sound-name-prefix = "DIT";
+	};
+
 	sound {
 		compatible = "amlogic,gx-sound-card";
 		model = "KHADAS-VIM2";
@@ -179,11 +186,21 @@ codec-0 {
 				sound-dai = <&hdmi_tx>;
 			};
 		};
+
+		dai-link-3 {
+			sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
+
+			codec-0 {
+			sound-dai = <&spdif_dit>;
+			};
+		};
 	};
 };
 
 &aiu {
 	status = "okay";
+	pinctrl-0 = <&spdif_out_h_pins>;
+	pinctrl-names = "default";
 };
 
 &cec_AO {
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Aug  9 21:29:42 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 09:59:42 +0530
Subject: [PATCH] arm64/mm: Define ID_AA64MMFR0_TGRAN_2_SHIFT
Message-ID: <1628569782-30213-1-git-send-email-anshuman.khandual@arm.com>

Streamline the Stage-2 TGRAN value extraction from ID_AA64MMFR0 register by
adding a page size agnostic ID_AA64MMFR0_TGRAN_2_SHIFT. This is similar to
the existing Stage-1 TGRAN shift i.e ID_AA64MMFR0_TGRAN_SHIFT.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.14-rc5.

 arch/arm64/include/asm/sysreg.h |  3 +++
 arch/arm64/kvm/reset.c          | 17 ++---------------
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7b9c3acba684..943d31d92b5b 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1028,14 +1028,17 @@
 
 #if defined(CONFIG_ARM64_4K_PAGES)
 #define ID_AA64MMFR0_TGRAN_SHIFT		ID_AA64MMFR0_TGRAN4_SHIFT
+#define ID_AA64MMFR0_TGRAN_2_SHIFT		ID_AA64MMFR0_TGRAN4_2_SHIFT
 #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_TGRAN4_SUPPORTED
 #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX	0x7
 #elif defined(CONFIG_ARM64_16K_PAGES)
 #define ID_AA64MMFR0_TGRAN_SHIFT		ID_AA64MMFR0_TGRAN16_SHIFT
+#define ID_AA64MMFR0_TGRAN_2_SHIFT		ID_AA64MMFR0_TGRAN16_2_SHIFT
 #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_TGRAN16_SUPPORTED
 #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX	0xF
 #elif defined(CONFIG_ARM64_64K_PAGES)
 #define ID_AA64MMFR0_TGRAN_SHIFT		ID_AA64MMFR0_TGRAN64_SHIFT
+#define ID_AA64MMFR0_TGRAN_2_SHIFT		ID_AA64MMFR0_TGRAN64_2_SHIFT
 #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN	ID_AA64MMFR0_TGRAN64_SUPPORTED
 #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX	0x7
 #endif
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index cba7872d69a8..20588220fe66 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -311,7 +311,7 @@ u32 get_kvm_ipa_limit(void)
 
 int kvm_set_ipa_limit(void)
 {
-	unsigned int parange, tgran_2;
+	unsigned int parange;
 	u64 mmfr0;
 
 	mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
@@ -322,20 +322,7 @@ int kvm_set_ipa_limit(void)
 	 * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at
 	 * Stage-2. If not, things will stop very quickly.
 	 */
-	switch (PAGE_SIZE) {
-	default:
-	case SZ_4K:
-		tgran_2 = ID_AA64MMFR0_TGRAN4_2_SHIFT;
-		break;
-	case SZ_16K:
-		tgran_2 = ID_AA64MMFR0_TGRAN16_2_SHIFT;
-		break;
-	case SZ_64K:
-		tgran_2 = ID_AA64MMFR0_TGRAN64_2_SHIFT;
-		break;
-	}
-
-	switch (cpuid_feature_extract_unsigned_field(mmfr0, tgran_2)) {
+	switch (cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_TGRAN_2_SHIFT)) {
 	case ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE:
 		kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n");
 		return -EINVAL;
-- 
2.20.1



From tabba at google.com  Mon Aug  9 21:33:07 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:33:07 +0200
Subject: [PATCH v4 10/21] KVM: arm64: Enable forcing page-level stage-2
 mappings
In-Reply-To: <20210809152448.1810400-11-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-11-qperret@google.com>
Message-ID: <CA+EHjTyiMjPxQTTxWJ2Nd46bkCnh=6Yj01EGpx9QYEp=J7Bp4w@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> Much of the stage-2 manipulation logic relies on being able to destroy
> block mappings if e.g. installing a smaller mapping in the range. The
> rationale for this behaviour is that stage-2 mappings can always be
> re-created lazily. However, this gets more complicated when the stage-2
> page-table is used to store metadata about the underlying pages. In such
> cases, destroying a block mapping may lead to losing part of the state,
> and confuse the user of those metadata (such as the hypervisor in nVHE
> protected mode).
>
> To avoid this, introduce a callback function in the pgtable struct which
> is called during all map operations to determine whether the mappings
> can use blocks, or should be forced to page granularity. This is used by
> the hypervisor when creating the host stage-2 to force page-level
> mappings when using non-default protection attributes.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad


> ---
>  arch/arm64/include/asm/kvm_pgtable.h  | 66 +++++++++++++++++----------
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 34 ++++++++++++--
>  arch/arm64/kvm/hyp/pgtable.c          | 29 ++++++++++--
>  3 files changed, 94 insertions(+), 35 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 83c5c97d9eac..2c090b0eee77 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -115,25 +115,6 @@ enum kvm_pgtable_stage2_flags {
>         KVM_PGTABLE_S2_IDMAP                    = BIT(1),
>  };
>
> -/**
> - * struct kvm_pgtable - KVM page-table.
> - * @ia_bits:           Maximum input address size, in bits.
> - * @start_level:       Level at which the page-table walk starts.
> - * @pgd:               Pointer to the first top-level entry of the page-table.
> - * @mm_ops:            Memory management callbacks.
> - * @mmu:               Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
> - */
> -struct kvm_pgtable {
> -       u32                                     ia_bits;
> -       u32                                     start_level;
> -       kvm_pte_t                               *pgd;
> -       struct kvm_pgtable_mm_ops               *mm_ops;
> -
> -       /* Stage-2 only */
> -       struct kvm_s2_mmu                       *mmu;
> -       enum kvm_pgtable_stage2_flags           flags;
> -};
> -
>  /**
>   * enum kvm_pgtable_prot - Page-table permissions and attributes.
>   * @KVM_PGTABLE_PROT_X:                Execute permission.
> @@ -149,11 +130,43 @@ enum kvm_pgtable_prot {
>         KVM_PGTABLE_PROT_DEVICE                 = BIT(3),
>  };
>
> -#define PAGE_HYP               (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
> +#define KVM_PGTABLE_PROT_RW    (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
> +#define KVM_PGTABLE_PROT_RWX   (KVM_PGTABLE_PROT_RW | KVM_PGTABLE_PROT_X)
> +
> +#define PKVM_HOST_MEM_PROT     KVM_PGTABLE_PROT_RWX
> +#define PKVM_HOST_MMIO_PROT    KVM_PGTABLE_PROT_RW
> +
> +#define PAGE_HYP               KVM_PGTABLE_PROT_RW
>  #define PAGE_HYP_EXEC          (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X)
>  #define PAGE_HYP_RO            (KVM_PGTABLE_PROT_R)
>  #define PAGE_HYP_DEVICE                (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE)
>
> +typedef bool (*kvm_pgtable_force_pte_cb_t)(u64 addr, u64 end,
> +                                          enum kvm_pgtable_prot prot);
> +
> +/**
> + * struct kvm_pgtable - KVM page-table.
> + * @ia_bits:           Maximum input address size, in bits.
> + * @start_level:       Level at which the page-table walk starts.
> + * @pgd:               Pointer to the first top-level entry of the page-table.
> + * @mm_ops:            Memory management callbacks.
> + * @mmu:               Stage-2 KVM MMU struct. Unused for stage-1 page-tables.
> + * @flags:             Stage-2 page-table flags.
> + * @force_pte_cb:      Function that returns true if page level mappings must
> + *                     be used instead of block mappings.
> + */
> +struct kvm_pgtable {
> +       u32                                     ia_bits;
> +       u32                                     start_level;
> +       kvm_pte_t                               *pgd;
> +       struct kvm_pgtable_mm_ops               *mm_ops;
> +
> +       /* Stage-2 only */
> +       struct kvm_s2_mmu                       *mmu;
> +       enum kvm_pgtable_stage2_flags           flags;
> +       kvm_pgtable_force_pte_cb_t              force_pte_cb;
> +};
> +
>  /**
>   * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk.
>   * @KVM_PGTABLE_WALK_LEAF:             Visit leaf entries, including invalid
> @@ -246,21 +259,24 @@ int kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
>  u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift);
>
>  /**
> - * kvm_pgtable_stage2_init_flags() - Initialise a guest stage-2 page-table.
> + * __kvm_pgtable_stage2_init() - Initialise a guest stage-2 page-table.
>   * @pgt:       Uninitialised page-table structure to initialise.
>   * @arch:      Arch-specific KVM structure representing the guest virtual
>   *             machine.
>   * @mm_ops:    Memory management callbacks.
>   * @flags:     Stage-2 configuration flags.
> + * @force_pte_cb: Function that returns true if page level mappings must
> + *             be used instead of block mappings.
>   *
>   * Return: 0 on success, negative error code on failure.
>   */
> -int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> -                                 struct kvm_pgtable_mm_ops *mm_ops,
> -                                 enum kvm_pgtable_stage2_flags flags);
> +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> +                             struct kvm_pgtable_mm_ops *mm_ops,
> +                             enum kvm_pgtable_stage2_flags flags,
> +                             kvm_pgtable_force_pte_cb_t force_pte_cb);
>
>  #define kvm_pgtable_stage2_init(pgt, arch, mm_ops) \
> -       kvm_pgtable_stage2_init_flags(pgt, arch, mm_ops, 0)
> +       __kvm_pgtable_stage2_init(pgt, arch, mm_ops, 0, NULL)
>
>  /**
>   * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table.
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 2148d3968aa5..6fed6772c673 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -89,6 +89,8 @@ static void prepare_host_vtcr(void)
>                                           id_aa64mmfr1_el1_sys_val, phys_shift);
>  }
>
> +static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot);
> +
>  int kvm_host_prepare_stage2(void *pgt_pool_base)
>  {
>         struct kvm_s2_mmu *mmu = &host_kvm.arch.mmu;
> @@ -101,8 +103,9 @@ int kvm_host_prepare_stage2(void *pgt_pool_base)
>         if (ret)
>                 return ret;
>
> -       ret = kvm_pgtable_stage2_init_flags(&host_kvm.pgt, &host_kvm.arch,
> -                                           &host_kvm.mm_ops, KVM_HOST_S2_FLAGS);
> +       ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, &host_kvm.arch,
> +                                       &host_kvm.mm_ops, KVM_HOST_S2_FLAGS,
> +                                       host_stage2_force_pte_cb);
>         if (ret)
>                 return ret;
>
> @@ -270,15 +273,36 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
>         return 0;
>  }
>
> +static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
> +{
> +       /*
> +        * Block mappings must be used with care in the host stage-2 as a
> +        * kvm_pgtable_stage2_map() operation targeting a page in the range of
> +        * an existing block will delete the block under the assumption that
> +        * mappings in the rest of the block range can always be rebuilt lazily.
> +        * That assumption is correct for the host stage-2 with RWX mappings
> +        * targeting memory or RW mappings targeting MMIO ranges (see
> +        * host_stage2_idmap() below which implements some of the host memory
> +        * abort logic). However, this is not safe for any other mappings where
> +        * the host stage-2 page-table is in fact the only place where this
> +        * state is stored. In all those cases, it is safer to use page-level
> +        * mappings, hence avoiding to lose the state because of side-effects in
> +        * kvm_pgtable_stage2_map().
> +        */
> +       if (range_is_memory(addr, end))
> +               return prot != PKVM_HOST_MEM_PROT;
> +       else
> +               return prot != PKVM_HOST_MMIO_PROT;
> +}
> +
>  static int host_stage2_idmap(u64 addr)
>  {
> -       enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
>         struct kvm_mem_range range;
>         bool is_memory = find_mem_range(addr, &range);
> +       enum kvm_pgtable_prot prot;
>         int ret;
>
> -       if (is_memory)
> -               prot |= KVM_PGTABLE_PROT_X;
> +       prot = is_memory ? PKVM_HOST_MEM_PROT : PKVM_HOST_MMIO_PROT;
>
>         hyp_spin_lock(&host_kvm.lock);
>         ret = host_stage2_adjust_range(addr, &range);
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 2689fcb7901d..e25d829587b9 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -452,6 +452,8 @@ int kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits,
>         pgt->start_level        = KVM_PGTABLE_MAX_LEVELS - levels;
>         pgt->mm_ops             = mm_ops;
>         pgt->mmu                = NULL;
> +       pgt->force_pte_cb       = NULL;
> +
>         return 0;
>  }
>
> @@ -489,6 +491,9 @@ struct stage2_map_data {
>         void                            *memcache;
>
>         struct kvm_pgtable_mm_ops       *mm_ops;
> +
> +       /* Force mappings to page granularity */
> +       bool                            force_pte;
>  };
>
>  u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift)
> @@ -602,6 +607,15 @@ static bool stage2_pte_executable(kvm_pte_t pte)
>         return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN);
>  }
>
> +static bool stage2_leaf_mapping_allowed(u64 addr, u64 end, u32 level,
> +                                       struct stage2_map_data *data)
> +{
> +       if (data->force_pte && (level < (KVM_PGTABLE_MAX_LEVELS - 1)))
> +               return false;
> +
> +       return kvm_block_mapping_supported(addr, end, data->phys, level);
> +}
> +
>  static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level,
>                                       kvm_pte_t *ptep,
>                                       struct stage2_map_data *data)
> @@ -611,7 +625,7 @@ static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level,
>         struct kvm_pgtable *pgt = data->mmu->pgt;
>         struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops;
>
> -       if (!kvm_block_mapping_supported(addr, end, phys, level))
> +       if (!stage2_leaf_mapping_allowed(addr, end, level, data))
>                 return -E2BIG;
>
>         if (kvm_phys_is_valid(phys))
> @@ -655,7 +669,7 @@ static int stage2_map_walk_table_pre(u64 addr, u64 end, u32 level,
>         if (data->anchor)
>                 return 0;
>
> -       if (!kvm_block_mapping_supported(addr, end, data->phys, level))
> +       if (!stage2_leaf_mapping_allowed(addr, end, level, data))
>                 return 0;
>
>         data->childp = kvm_pte_follow(*ptep, data->mm_ops);
> @@ -785,6 +799,7 @@ int kvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
>                 .mmu            = pgt->mmu,
>                 .memcache       = mc,
>                 .mm_ops         = pgt->mm_ops,
> +               .force_pte      = pgt->force_pte_cb && pgt->force_pte_cb(addr, addr + size, prot),
>         };
>         struct kvm_pgtable_walker walker = {
>                 .cb             = stage2_map_walker,
> @@ -816,6 +831,7 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size,
>                 .memcache       = mc,
>                 .mm_ops         = pgt->mm_ops,
>                 .owner_id       = owner_id,
> +               .force_pte      = true,
>         };
>         struct kvm_pgtable_walker walker = {
>                 .cb             = stage2_map_walker,
> @@ -1057,9 +1073,11 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size)
>         return kvm_pgtable_walk(pgt, addr, size, &walker);
>  }
>
> -int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> -                                 struct kvm_pgtable_mm_ops *mm_ops,
> -                                 enum kvm_pgtable_stage2_flags flags)
> +
> +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch,
> +                             struct kvm_pgtable_mm_ops *mm_ops,
> +                             enum kvm_pgtable_stage2_flags flags,
> +                             kvm_pgtable_force_pte_cb_t force_pte_cb)
>  {
>         size_t pgd_sz;
>         u64 vtcr = arch->vtcr;
> @@ -1077,6 +1095,7 @@ int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch
>         pgt->mm_ops             = mm_ops;
>         pgt->mmu                = &arch->mmu;
>         pgt->flags              = flags;
> +       pgt->force_pte_cb       = force_pte_cb;
>
>         /* Ensure zeroed PGD pages are visible to the hardware walker */
>         dsb(ishst);
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:36:27 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:36:27 +0200
Subject: [PATCH v4 13/21] KVM: arm64: Expose host stage-2 manipulation
 helpers
In-Reply-To: <20210809152448.1810400-14-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-14-qperret@google.com>
Message-ID: <CA+EHjTyb2Ge1QBXyRaTmXfjB=2uy2y-EDxag-Oyy03paAt4tvg@mail.gmail.com>

Hi Quentin,


On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> We will need to manipulate the host stage-2 page-table from outside
> mem_protect.c soon. Introduce two functions allowing this, and make
> them usable to users of mem_protect.h.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

> ---
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 ++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 18 +++++++++++++++++-
>  2 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 87b1690c439f..0849ee8fa260 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -49,6 +49,8 @@ extern struct host_kvm host_kvm;
>  int __pkvm_prot_finalize(void);
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
>
> +int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> +int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id);
>  int kvm_host_prepare_stage2(void *pgt_pool_base);
>  void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 6fed6772c673..f95a5a4aa09c 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -273,6 +273,22 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range)
>         return 0;
>  }
>
> +int host_stage2_idmap_locked(phys_addr_t addr, u64 size,
> +                            enum kvm_pgtable_prot prot)
> +{
> +       hyp_assert_lock_held(&host_kvm.lock);
> +
> +       return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot);
> +}
> +
> +int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id)
> +{
> +       hyp_assert_lock_held(&host_kvm.lock);
> +
> +       return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
> +                              addr, size, &host_s2_pool, owner_id);
> +}
> +
>  static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot)
>  {
>         /*
> @@ -309,7 +325,7 @@ static int host_stage2_idmap(u64 addr)
>         if (ret)
>                 goto unlock;
>
> -       ret = host_stage2_try(__host_stage2_idmap, range.start, range.end, prot);
> +       ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot);
>  unlock:
>         hyp_spin_unlock(&host_kvm.lock);
>
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:37:43 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:37:43 +0200
Subject: [PATCH v4 15/21] KVM: arm64: Introduce addr_is_memory()
In-Reply-To: <20210809152448.1810400-16-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-16-qperret@google.com>
Message-ID: <CA+EHjTxTMQ1n2F_6i6Ep9JgJauRs1ez2OyT-3y26dkGS5p58Zw@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> Introduce a helper usable in nVHE protected mode to check whether a
> physical address is in a RAM region or not.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 +
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 7 +++++++
>  2 files changed, 8 insertions(+)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 23316a021880..49db0ec5a606 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -51,6 +51,7 @@ extern const u8 pkvm_hyp_id;
>  int __pkvm_prot_finalize(void);
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
>
> +bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
>  int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id);
>  int kvm_host_prepare_stage2(void *pgt_pool_base);
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index ee255171945c..cb023d31666e 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -197,6 +197,13 @@ static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range)
>         return false;
>  }
>
> +bool addr_is_memory(phys_addr_t phys)
> +{
> +       struct kvm_mem_range range;
> +
> +       return find_mem_range(phys, &range);
> +}
> +
>  static bool range_is_memory(u64 start, u64 end)
>  {
>         struct kvm_mem_range r1, r2;
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:38:32 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:38:32 +0200
Subject: [PATCH v4 16/21] KVM: arm64: Enable retrieving protections
 attributes of PTEs
In-Reply-To: <20210809152448.1810400-17-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-17-qperret@google.com>
Message-ID: <CA+EHjTyRKnAhE3joW_VNOL51qJToaR=20KhkKXm98bpvymBX6g@mail.gmail.com>

Hi Quentin,


On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> Introduce helper functions in the KVM stage-2 and stage-1 page-table
> manipulation library allowing to retrieve the enum kvm_pgtable_prot of a
> PTE. This will be useful to implement custom walkers outside of
> pgtable.c.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>  arch/arm64/include/asm/kvm_pgtable.h | 20 +++++++++++++++
>  arch/arm64/kvm/hyp/pgtable.c         | 37 ++++++++++++++++++++++++++++
>  2 files changed, 57 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index ff9d52f8073a..f1651e0153ad 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -506,4 +506,24 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
>   */
>  int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
>                          kvm_pte_t *ptep, u32 *level);
> +
> +/**
> + * kvm_pgtable_stage2_pte_prot() - Retrieve the protection attributes of a
> + *                                stage-2 Page-Table Entry.
> + * @pte:       Page-table entry
> + *
> + * Return: protection attributes of the page-table entry in the enum
> + *        kvm_pgtable_prot format.
> + */
> +enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte);
> +
> +/**
> + * kvm_pgtable_hyp_pte_prot() - Retrieve the protection attributes of a stage-1
> + *                             Page-Table Entry.
> + * @pte:       Page-table entry
> + *
> + * Return: protection attributes of the page-table entry in the enum
> + *        kvm_pgtable_prot format.
> + */
> +enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte);
>  #endif /* __ARM64_KVM_PGTABLE_H__ */
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index cff744136044..f8ceebe4982e 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -363,6 +363,26 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
>         return 0;
>  }
>
> +enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte)
> +{
> +       enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW;
> +       u32 ap;
> +
> +       if (!kvm_pte_valid(pte))
> +               return prot;
> +
> +       if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN))
> +               prot |= KVM_PGTABLE_PROT_X;
> +
> +       ap = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_AP, pte);
> +       if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RO)
> +               prot |= KVM_PGTABLE_PROT_R;
> +       else if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RW)
> +               prot |= KVM_PGTABLE_PROT_RW;
> +
> +       return prot;
> +}
> +
>  static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new)
>  {
>         /*
> @@ -565,6 +585,23 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p
>         return 0;
>  }
>
> +enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte)
> +{
> +       enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW;
> +
> +       if (!kvm_pte_valid(pte))
> +               return prot;
> +
> +       if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R)
> +               prot |= KVM_PGTABLE_PROT_R;
> +       if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W)
> +               prot |= KVM_PGTABLE_PROT_W;
> +       if (!(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN))
> +               prot |= KVM_PGTABLE_PROT_X;
> +
> +       return prot;
> +}
> +
>  static bool stage2_pte_needs_update(kvm_pte_t old, kvm_pte_t new)
>  {
>         if (!kvm_pte_valid(old) || !kvm_pte_valid(new))
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:40:55 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:40:55 +0200
Subject: [PATCH v4 17/21] KVM: arm64: Mark host bss and rodata section as
 shared
In-Reply-To: <20210809152448.1810400-18-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-18-qperret@google.com>
Message-ID: <CA+EHjTxM1QA30k4ZzajmQftZWtSR7QPVaSfVOMgpJH7GPHT+Fw@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> As the hypervisor maps the host's .bss and .rodata sections in its
> stage-1, make sure to tag them as shared in hyp and host page-tables.
>
> But since the hypervisor relies on the presence of these mappings, we
> cannot let the host in complete control of the memory regions -- it
> must not unshare or donate them to another entity for example. To
> prevent this, let's transfer the ownership of those ranges to the
> hypervisor itself, and share the pages back with the host.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad


>  arch/arm64/kvm/hyp/nvhe/setup.c | 82 +++++++++++++++++++++++++++++----
>  1 file changed, 74 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
> index 0b574d106519..57c27846320f 100644
> --- a/arch/arm64/kvm/hyp/nvhe/setup.c
> +++ b/arch/arm64/kvm/hyp/nvhe/setup.c
> @@ -58,6 +58,7 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>  {
>         void *start, *end, *virt = hyp_phys_to_virt(phys);
>         unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT;
> +       enum kvm_pgtable_prot prot;
>         int ret, i;
>
>         /* Recreate the hyp page-table using the early page allocator */
> @@ -83,10 +84,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>         if (ret)
>                 return ret;
>
> -       ret = pkvm_create_mappings(__start_rodata, __end_rodata, PAGE_HYP_RO);
> -       if (ret)
> -               return ret;
> -
>         ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO);
>         if (ret)
>                 return ret;
> @@ -95,10 +92,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>         if (ret)
>                 return ret;
>
> -       ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, PAGE_HYP_RO);
> -       if (ret)
> -               return ret;
> -
>         ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP);
>         if (ret)
>                 return ret;
> @@ -117,6 +110,24 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
>                         return ret;
>         }
>
> +       /*
> +        * Map the host's .bss and .rodata sections RO in the hypervisor, but
> +        * transfer the ownership from the host to the hypervisor itself to
> +        * make sure it can't be donated or shared with another entity.
> +        *
> +        * The ownership transition requires matching changes in the host
> +        * stage-2. This will be done later (see finalize_host_mappings()) once
> +        * the hyp_vmemmap is addressable.
> +        */
> +       prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
> +       ret = pkvm_create_mappings(__start_rodata, __end_rodata, prot);
> +       if (ret)
> +               return ret;
> +
> +       ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, prot);
> +       if (ret)
> +               return ret;
> +
>         return 0;
>  }
>
> @@ -148,6 +159,57 @@ static void hpool_put_page(void *addr)
>         hyp_put_page(&hpool, addr);
>  }
>
> +static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
> +                                        kvm_pte_t *ptep,
> +                                        enum kvm_pgtable_walk_flags flag,
> +                                        void * const arg)
> +{
> +       enum kvm_pgtable_prot prot;
> +       enum pkvm_page_state state;
> +       kvm_pte_t pte = *ptep;
> +       phys_addr_t phys;
> +
> +       if (!kvm_pte_valid(pte))
> +               return 0;
> +
> +       if (level != (KVM_PGTABLE_MAX_LEVELS - 1))
> +               return -EINVAL;
> +
> +       phys = kvm_pte_to_phys(pte);
> +       if (!addr_is_memory(phys))
> +               return 0;
> +
> +       /*
> +        * Adjust the host stage-2 mappings to match the ownership attributes
> +        * configured in the hypervisor stage-1.
> +        */
> +       state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte));
> +       switch (state) {
> +       case PKVM_PAGE_OWNED:
> +               return host_stage2_set_owner_locked(phys, PAGE_SIZE, pkvm_hyp_id);
> +       case PKVM_PAGE_SHARED_OWNED:
> +               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED);
> +               break;
> +       case PKVM_PAGE_SHARED_BORROWED:
> +               prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return host_stage2_idmap_locked(phys, PAGE_SIZE, prot);
> +}
> +
> +static int finalize_host_mappings(void)
> +{
> +       struct kvm_pgtable_walker walker = {
> +               .cb     = finalize_host_mappings_walker,
> +               .flags  = KVM_PGTABLE_WALK_LEAF,
> +       };
> +
> +       return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker);
> +}
> +
>  void __noreturn __pkvm_init_finalise(void)
>  {
>         struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data);
> @@ -167,6 +229,10 @@ void __noreturn __pkvm_init_finalise(void)
>         if (ret)
>                 goto out;
>
> +       ret = finalize_host_mappings();
> +       if (ret)
> +               goto out;
> +
>         pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) {
>                 .zalloc_page = hyp_zalloc_hyp_page,
>                 .phys_to_virt = hyp_phys_to_virt,
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:41:52 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:41:52 +0200
Subject: [PATCH v4 19/21] KVM: arm64: Refactor protected nVHE stage-1
 locking
In-Reply-To: <20210809152448.1810400-20-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-20-qperret@google.com>
Message-ID: <CA+EHjTxfnNFwOk=V+w5BUMTCREX+FUpVnzKAhCoCMnyL3BPZBw@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> Refactor the hypervisor stage-1 locking in nVHE protected mode to expose
> a new pkvm_create_mappings_locked() function. This will be used in later
> patches to allow walking and changing the hypervisor stage-1 without
> releasing the lock.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

> ---
>  arch/arm64/kvm/hyp/include/nvhe/mm.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/mm.c         | 18 ++++++++++++++++--
>  2 files changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> index 8ec3a5a7744b..c76d7136ed9b 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> @@ -23,6 +23,7 @@ int hyp_map_vectors(void);
>  int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
>  int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
>  int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
> +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
>  int __pkvm_create_mappings(unsigned long start, unsigned long size,
>                            unsigned long phys, enum kvm_pgtable_prot prot);
>  unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
> diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
> index a8efdf0f9003..6fbe8e8030f6 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mm.c
> @@ -67,13 +67,15 @@ unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
>         return addr;
>  }
>
> -int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot)
>  {
>         unsigned long start = (unsigned long)from;
>         unsigned long end = (unsigned long)to;
>         unsigned long virt_addr;
>         phys_addr_t phys;
>
> +       hyp_assert_lock_held(&pkvm_pgd_lock);
> +
>         start = start & PAGE_MASK;
>         end = PAGE_ALIGN(end);
>
> @@ -81,7 +83,8 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>                 int err;
>
>                 phys = hyp_virt_to_phys((void *)virt_addr);
> -               err = __pkvm_create_mappings(virt_addr, PAGE_SIZE, phys, prot);
> +               err = kvm_pgtable_hyp_map(&pkvm_pgtable, virt_addr, PAGE_SIZE,
> +                                         phys, prot);
>                 if (err)
>                         return err;
>         }
> @@ -89,6 +92,17 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>         return 0;
>  }
>
> +int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
> +{
> +       int ret;
> +
> +       hyp_spin_lock(&pkvm_pgd_lock);
> +       ret = pkvm_create_mappings_locked(from, to, prot);
> +       hyp_spin_unlock(&pkvm_pgd_lock);
> +
> +       return ret;
> +}
> +
>  int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back)
>  {
>         unsigned long start, end;
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:43:20 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:43:20 +0200
Subject: [PATCH v4 20/21] KVM: arm64: Restrict EL2 stage-1 changes in
 protected mode
In-Reply-To: <20210809152448.1810400-21-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-21-qperret@google.com>
Message-ID: <CA+EHjTwZX2m1LwUyrh9vxnhh5GYRJOcQnmKQHXg9B+uNTdYp1Q@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> The host kernel is currently able to change EL2 stage-1 mappings without
> restrictions thanks to the __pkvm_create_mappings() hypercall. But in a
> world where the host is no longer part of the TCB, this clearly poses a
> problem.
>
> To fix this, introduce a new hypercall to allow the host to share a
> physical memory page with the hypervisor, and remove the
> __pkvm_create_mappings() variant. The new hypercall implements
> ownership and permission checks before allowing the sharing operation,
> and it annotates the shared page in the hypervisor stage-1 and host
> stage-2 page-tables.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>  arch/arm64/include/asm/kvm_asm.h              |  2 +-
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            | 11 +--
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 88 +++++++++++++++++++
>  arch/arm64/kvm/mmu.c                          | 28 +++++-
>  5 files changed, 118 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 432a9ea1f02e..aed2aa61766a 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -59,7 +59,7 @@
>  #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs              13
>  #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs           14
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_init                      15
> -#define __KVM_HOST_SMCCC_FUNC___pkvm_create_mappings           16
> +#define __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp            16
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping    17
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector            18
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize             19
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 0118527b07b0..03e604f842e2 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -49,6 +49,7 @@ extern struct host_kvm host_kvm;
>  extern const u8 pkvm_hyp_id;
>
>  int __pkvm_prot_finalize(void);
> +int __pkvm_host_share_hyp(u64 pfn);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 7900d5b66ba3..2da6aa8da868 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -140,14 +140,11 @@ static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) = pkvm_cpu_set_vector(slot);
>  }
>
> -static void handle___pkvm_create_mappings(struct kvm_cpu_context *host_ctxt)
> +static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt)
>  {
> -       DECLARE_REG(unsigned long, start, host_ctxt, 1);
> -       DECLARE_REG(unsigned long, size, host_ctxt, 2);
> -       DECLARE_REG(unsigned long, phys, host_ctxt, 3);
> -       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4);
> +       DECLARE_REG(u64, pfn, host_ctxt, 1);
>
> -       cpu_reg(host_ctxt, 1) = __pkvm_create_mappings(start, size, phys, prot);
> +       cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(pfn);
>  }
>
>  static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt)
> @@ -185,7 +182,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__vgic_v3_restore_aprs),
>         HANDLE_FUNC(__pkvm_init),
>         HANDLE_FUNC(__pkvm_cpu_set_vector),
> -       HANDLE_FUNC(__pkvm_create_mappings),
> +       HANDLE_FUNC(__pkvm_host_share_hyp),
>         HANDLE_FUNC(__pkvm_create_private_mapping),
>         HANDLE_FUNC(__pkvm_prot_finalize),
>  };
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 2991dc6996b9..8165390d3ec9 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -339,6 +339,94 @@ static int host_stage2_idmap(u64 addr)
>         return ret;
>  }
>
> +static inline bool check_prot(enum kvm_pgtable_prot prot,
> +                             enum kvm_pgtable_prot required,
> +                             enum kvm_pgtable_prot denied)
> +{
> +       return (prot & (required | denied)) == required;
> +}
> +
> +int __pkvm_host_share_hyp(u64 pfn)
> +{
> +       phys_addr_t addr = hyp_pfn_to_phys(pfn);
> +       enum kvm_pgtable_prot prot, cur;
> +       void *virt = __hyp_va(addr);
> +       enum pkvm_page_state state;
> +       kvm_pte_t pte;
> +       int ret;
> +
> +       if (!addr_is_memory(addr))
> +               return -EINVAL;
> +
> +       hyp_spin_lock(&host_kvm.lock);
> +       hyp_spin_lock(&pkvm_pgd_lock);
> +
> +       ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, NULL);
> +       if (ret)
> +               goto unlock;
> +       if (!pte)
> +               goto map_shared;
> +
> +       /*
> +        * Check attributes in the host stage-2 PTE. We need the page to be:
> +        *  - mapped RWX as we're sharing memory;
> +        *  - not borrowed, as that implies absence of ownership.
> +        * Otherwise, we can't let it got through
> +        */
> +       cur = kvm_pgtable_stage2_pte_prot(pte);
> +       prot = pkvm_mkstate(0, PKVM_PAGE_SHARED_BORROWED);
> +       if (!check_prot(cur, PKVM_HOST_MEM_PROT, prot)) {
> +               ret = -EPERM;
> +               goto unlock;
> +       }
> +
> +       state = pkvm_getstate(cur);
> +       if (state == PKVM_PAGE_OWNED)
> +               goto map_shared;
> +
> +       /*
> +        * Tolerate double-sharing the same page, but this requires
> +        * cross-checking the hypervisor stage-1.
> +        */
> +       if (state != PKVM_PAGE_SHARED_OWNED) {
> +               ret = -EPERM;
> +               goto unlock;
> +       }
> +
> +       ret = kvm_pgtable_get_leaf(&pkvm_pgtable, (u64)virt, &pte, NULL);
> +       if (ret)
> +               goto unlock;
> +
> +       /*
> +        * If the page has been shared with the hypervisor, it must be
> +        * already mapped as SHARED_BORROWED in its stage-1.
> +        */
> +       cur = kvm_pgtable_hyp_pte_prot(pte);
> +       prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
> +       if (!check_prot(cur, prot, ~prot))
> +               ret = EPERM;
> +       goto unlock;
> +
> +map_shared:
> +       /*
> +        * If the page is not yet shared, adjust mappings in both page-tables
> +        * while both locks are held.
> +        */
> +       prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
> +       ret = pkvm_create_mappings_locked(virt, virt + PAGE_SIZE, prot);
> +       BUG_ON(ret);
> +
> +       prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED);
> +       ret = host_stage2_idmap_locked(addr, PAGE_SIZE, prot);
> +       BUG_ON(ret);
> +
> +unlock:
> +       hyp_spin_unlock(&pkvm_pgd_lock);
> +       hyp_spin_unlock(&host_kvm.lock);
> +
> +       return ret;
> +}
> +
>  void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
>  {
>         struct kvm_vcpu_fault_info fault;
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 0625bf2353c2..cbab146cda6a 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -259,10 +259,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size,
>  {
>         int err;
>
> -       if (!kvm_host_owns_hyp_mappings()) {
> -               return kvm_call_hyp_nvhe(__pkvm_create_mappings,
> -                                        start, size, phys, prot);
> -       }
> +       if (WARN_ON(!kvm_host_owns_hyp_mappings()))
> +               return -EINVAL;
>
>         mutex_lock(&kvm_hyp_pgd_mutex);
>         err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot);
> @@ -282,6 +280,21 @@ static phys_addr_t kvm_kaddr_to_phys(void *kaddr)
>         }
>  }
>
> +static int pkvm_share_hyp(phys_addr_t start, phys_addr_t end)
> +{
> +       phys_addr_t addr;
> +       int ret;
> +
> +       for (addr = ALIGN_DOWN(start, PAGE_SIZE); addr < end; addr += PAGE_SIZE) {
> +               ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp,
> +                                       __phys_to_pfn(addr));
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       return 0;
> +}
> +
>  /**
>   * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode
>   * @from:      The virtual kernel start address of the range
> @@ -302,6 +315,13 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>         if (is_kernel_in_hyp_mode())
>                 return 0;
>
> +       if (!kvm_host_owns_hyp_mappings()) {
> +               if (WARN_ON(prot != PAGE_HYP))
> +                       return -EPERM;
> +               return pkvm_share_hyp(kvm_kaddr_to_phys(from),
> +                                     kvm_kaddr_to_phys(to));
> +       }
> +
>         start = start & PAGE_MASK;
>         end = PAGE_ALIGN(end);
>
> --
> 2.32.0.605.g8dce9f2422-goog
>


From amhetre at nvidia.com  Mon Aug  9 21:43:59 2021
From: amhetre at nvidia.com (Ashish Mhetre)
Date: Tue, 10 Aug 2021 10:13:59 +0530
Subject: [Patch V3 0/2] iommu/arm-smmu: Fix races in iommu domain/group
 creation
Message-ID: <1628570641-9127-1-git-send-email-amhetre@nvidia.com>

When two devices with same SID are getting probed concurrently through
iommu_probe_device(), the iommu_group and iommu_domain are allocated more
than once because they are not protected for concurrency. This is leading
to context faults when one device is accessing IOVA from other device.
Fix this by protecting iommu_domain and iommu_group creation with mutexes.

Changes in v3:
* Updated commit messages.
* Added Signed-off-by in patch 2.

Ashish Mhetre (1):
  iommu: Fix race condition during default domain allocation

Krishna Reddy (1):
  iommu/arm-smmu: Fix race condition during iommu_group creation

 drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 +++++-
 drivers/iommu/iommu.c                 | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

-- 
2.7.4



From amhetre at nvidia.com  Mon Aug  9 21:44:00 2021
From: amhetre at nvidia.com (Ashish Mhetre)
Date: Tue, 10 Aug 2021 10:14:00 +0530
Subject: [Patch V3 1/2] iommu: Fix race condition during default domain
 allocation
In-Reply-To: <1628570641-9127-1-git-send-email-amhetre@nvidia.com>
References: <1628570641-9127-1-git-send-email-amhetre@nvidia.com>
Message-ID: <1628570641-9127-2-git-send-email-amhetre@nvidia.com>

When two devices with same SID are getting probed concurrently through
iommu_probe_device(), the iommu_domain sometimes is getting allocated more
than once as call to iommu_alloc_default_domain() is not protected for
concurrency. Furthermore, it leads to each device holding a different
iommu_domain pointer, separate IOVA space and only one of the devices'
domain is used for translations from IOMMU. This causes accesses from other
device to fault or see incorrect translations.
Fix this by protecting iommu_alloc_default_domain() call with group->mutex
and let all devices with same SID share same iommu_domain.

Signed-off-by: Ashish Mhetre <amhetre at nvidia.com>
---
 drivers/iommu/iommu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 5419c4b..80c5a1c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -273,7 +273,9 @@ int iommu_probe_device(struct device *dev)
 	 * support default domains, so the return value is not yet
 	 * checked.
 	 */
+	mutex_lock(&group->mutex);
 	iommu_alloc_default_domain(group, dev);
+	mutex_unlock(&group->mutex);
 
 	if (group->default_domain) {
 		ret = __iommu_attach_device(group->default_domain, dev);
-- 
2.7.4



From amhetre at nvidia.com  Mon Aug  9 21:44:01 2021
From: amhetre at nvidia.com (Ashish Mhetre)
Date: Tue, 10 Aug 2021 10:14:01 +0530
Subject: [Patch V3 2/2] iommu/arm-smmu: Fix race condition during iommu_group
 creation
In-Reply-To: <1628570641-9127-1-git-send-email-amhetre@nvidia.com>
References: <1628570641-9127-1-git-send-email-amhetre@nvidia.com>
Message-ID: <1628570641-9127-3-git-send-email-amhetre@nvidia.com>

From: Krishna Reddy <vdumpa at nvidia.com>

When two devices with same SID are getting probed concurrently through
iommu_probe_device(), the iommu_group sometimes is getting allocated more
than once as call to arm_smmu_device_group() is not protected for
concurrency. Furthermore, it leads to each device holding a different
iommu_group and domain pointer, separate IOVA space and only one of the
devices' domain is used for translations from IOMMU. This causes accesses
from other device to fault or see incorrect translations.
Fix this by protecting iommu_group allocation from concurrency in
arm_smmu_device_group().

Signed-off-by: Krishna Reddy <vdumpa at nvidia.com>
Signed-off-by: Ashish Mhetre <amhetre at nvidia.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index dba15f3..f9c6648 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1457,6 +1457,7 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
 	struct iommu_group *group = NULL;
 	int i, idx;
 
+	mutex_lock(&smmu->stream_map_mutex);
 	for_each_cfg_sme(cfg, fwspec, i, idx) {
 		if (group && smmu->s2crs[idx].group &&
 		    group != smmu->s2crs[idx].group)
@@ -1465,8 +1466,10 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
 		group = smmu->s2crs[idx].group;
 	}
 
-	if (group)
+	if (group) {
+		mutex_unlock(&smmu->stream_map_mutex);
 		return iommu_group_ref_get(group);
+	}
 
 	if (dev_is_pci(dev))
 		group = pci_device_group(dev);
@@ -1480,6 +1483,7 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
 		for_each_cfg_sme(cfg, fwspec, i, idx)
 			smmu->s2crs[idx].group = group;
 
+	mutex_unlock(&smmu->stream_map_mutex);
 	return group;
 }
 
-- 
2.7.4



From tabba at google.com  Mon Aug  9 21:55:00 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:55:00 +0200
Subject: [PATCH v4 21/21] KVM: arm64: Make __pkvm_create_mappings static
In-Reply-To: <20210809152448.1810400-22-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-22-qperret@google.com>
Message-ID: <CA+EHjTz4fYdAj50KXkeccb4SMxiwWeZBz1ORhs99kY76ZF=9OA@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> The __pkvm_create_mappings() function is no longer used outside of
> nvhe/mm.c, make it static.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>  arch/arm64/kvm/hyp/include/nvhe/mm.h | 2 --
>  arch/arm64/kvm/hyp/nvhe/mm.c         | 4 ++--
>  2 files changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> index c76d7136ed9b..c9a8f535212e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> @@ -24,8 +24,6 @@ int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
>  int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
>  int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
>  int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
> -int __pkvm_create_mappings(unsigned long start, unsigned long size,
> -                          unsigned long phys, enum kvm_pgtable_prot prot);
>  unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
>                                             enum kvm_pgtable_prot prot);
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
> index 6fbe8e8030f6..2fabeceb889a 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mm.c
> @@ -23,8 +23,8 @@ u64 __io_map_base;
>  struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS];
>  unsigned int hyp_memblock_nr;
>
> -int __pkvm_create_mappings(unsigned long start, unsigned long size,
> -                         unsigned long phys, enum kvm_pgtable_prot prot)
> +static int __pkvm_create_mappings(unsigned long start, unsigned long size,
> +                                 unsigned long phys, enum kvm_pgtable_prot prot)
>  {
>         int err;
>
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:55:17 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:55:17 +0200
Subject: [PATCH v4 18/21] KVM: arm64: Remove __pkvm_mark_hyp
In-Reply-To: <20210809152448.1810400-19-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-19-qperret@google.com>
Message-ID: <CA+EHjTx=jb2vzo9U2=RxHYH79u7jRmncLGzR6PNC0ZiRN+km+A@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> Now that we mark memory owned by the hypervisor in the host stage-2
> during __pkvm_init(), we no longer need to rely on the host to
> explicitly mark the hyp sections later on.
>
> Remove the __pkvm_mark_hyp() hypercall altogether.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>  arch/arm64/include/asm/kvm_asm.h              |  3 +-
>  arch/arm64/kvm/arm.c                          | 46 -------------------
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 -
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  9 ----
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 19 --------
>  5 files changed, 1 insertion(+), 77 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 9f0bf2109be7..432a9ea1f02e 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -63,8 +63,7 @@
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping    17
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector            18
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize             19
> -#define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp                  20
> -#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc                  21
> +#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc                  20
>
>  #ifndef __ASSEMBLY__
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e9a2b8f27792..2f378482471b 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -1954,57 +1954,11 @@ static void _kvm_host_prot_finalize(void *discard)
>         WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize));
>  }
>
> -static inline int pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
> -{
> -       return kvm_call_hyp_nvhe(__pkvm_mark_hyp, start, end);
> -}
> -
> -#define pkvm_mark_hyp_section(__section)               \
> -       pkvm_mark_hyp(__pa_symbol(__section##_start),   \
> -                       __pa_symbol(__section##_end))
> -
>  static int finalize_hyp_mode(void)
>  {
> -       int cpu, ret;
> -
>         if (!is_protected_kvm_enabled())
>                 return 0;
>
> -       ret = pkvm_mark_hyp_section(__hyp_idmap_text);
> -       if (ret)
> -               return ret;
> -
> -       ret = pkvm_mark_hyp_section(__hyp_text);
> -       if (ret)
> -               return ret;
> -
> -       ret = pkvm_mark_hyp_section(__hyp_rodata);
> -       if (ret)
> -               return ret;
> -
> -       ret = pkvm_mark_hyp_section(__hyp_bss);
> -       if (ret)
> -               return ret;
> -
> -       ret = pkvm_mark_hyp(hyp_mem_base, hyp_mem_base + hyp_mem_size);
> -       if (ret)
> -               return ret;
> -
> -       for_each_possible_cpu(cpu) {
> -               phys_addr_t start = virt_to_phys((void *)kvm_arm_hyp_percpu_base[cpu]);
> -               phys_addr_t end = start + (PAGE_SIZE << nvhe_percpu_order());
> -
> -               ret = pkvm_mark_hyp(start, end);
> -               if (ret)
> -                       return ret;
> -
> -               start = virt_to_phys((void *)per_cpu(kvm_arm_hyp_stack_page, cpu));
> -               end = start + PAGE_SIZE;
> -               ret = pkvm_mark_hyp(start, end);
> -               if (ret)
> -                       return ret;
> -       }
> -
>         /*
>          * Flip the static key upfront as that may no longer be possible
>          * once the host stage 2 is installed.
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 49db0ec5a606..0118527b07b0 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -49,7 +49,6 @@ extern struct host_kvm host_kvm;
>  extern const u8 pkvm_hyp_id;
>
>  int __pkvm_prot_finalize(void);
> -int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
>
>  bool addr_is_memory(phys_addr_t phys);
>  int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot);
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 1632f001f4ed..7900d5b66ba3 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -163,14 +163,6 @@ static void handle___pkvm_prot_finalize(struct kvm_cpu_context *host_ctxt)
>  {
>         cpu_reg(host_ctxt, 1) = __pkvm_prot_finalize();
>  }
> -
> -static void handle___pkvm_mark_hyp(struct kvm_cpu_context *host_ctxt)
> -{
> -       DECLARE_REG(phys_addr_t, start, host_ctxt, 1);
> -       DECLARE_REG(phys_addr_t, end, host_ctxt, 2);
> -
> -       cpu_reg(host_ctxt, 1) = __pkvm_mark_hyp(start, end);
> -}
>  typedef void (*hcall_t)(struct kvm_cpu_context *);
>
>  #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x
> @@ -196,7 +188,6 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__pkvm_create_mappings),
>         HANDLE_FUNC(__pkvm_create_private_mapping),
>         HANDLE_FUNC(__pkvm_prot_finalize),
> -       HANDLE_FUNC(__pkvm_mark_hyp),
>  };
>
>  static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index cb023d31666e..2991dc6996b9 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -339,25 +339,6 @@ static int host_stage2_idmap(u64 addr)
>         return ret;
>  }
>
> -int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
> -{
> -       int ret;
> -
> -       /*
> -        * host_stage2_unmap_dev_all() currently relies on MMIO mappings being
> -        * non-persistent, so don't allow changing page ownership in MMIO range.
> -        */
> -       if (!range_is_memory(start, end))
> -               return -EINVAL;
> -
> -       hyp_spin_lock(&host_kvm.lock);
> -       ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt,
> -                             start, end - start, &host_s2_pool, pkvm_hyp_id);
> -       hyp_spin_unlock(&host_kvm.lock);
> -
> -       return ret != -EAGAIN ? ret : 0;
> -}
> -
>  void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt)
>  {
>         struct kvm_vcpu_fault_info fault;
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:56:12 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:56:12 +0200
Subject: [PATCH v4 05/21] KVM: arm64: Expose page-table helpers
In-Reply-To: <20210809152448.1810400-6-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-6-qperret@google.com>
Message-ID: <CA+EHjTzu=_-ZBZYUWiz7T328UYsNsHEfAqxnSRvO5s52t-g2Bw@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> The KVM pgtable API exposes the kvm_pgtable_walk() function to allow
> the definition of walkers outside of pgtable.c. However, it is not easy
> to implement any of those walkers without some of the low-level helpers.
> Move some of them to the header file to allow re-use from other places.
>
> Signed-off-by: Quentin Perret <qperret at google.com>

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

> ---
>  arch/arm64/include/asm/kvm_pgtable.h | 40 ++++++++++++++++++++++++++++
>  arch/arm64/kvm/hyp/pgtable.c         | 39 ---------------------------
>  2 files changed, 40 insertions(+), 39 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 082b9d65f40b..6938eac72c1f 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -25,6 +25,46 @@ static inline u64 kvm_get_parange(u64 mmfr0)
>
>  typedef u64 kvm_pte_t;
>
> +#define KVM_PTE_VALID                  BIT(0)
> +
> +#define KVM_PTE_ADDR_MASK              GENMASK(47, PAGE_SHIFT)
> +#define KVM_PTE_ADDR_51_48             GENMASK(15, 12)
> +
> +static inline bool kvm_pte_valid(kvm_pte_t pte)
> +{
> +       return pte & KVM_PTE_VALID;
> +}
> +
> +static inline u64 kvm_pte_to_phys(kvm_pte_t pte)
> +{
> +       u64 pa = pte & KVM_PTE_ADDR_MASK;
> +
> +       if (PAGE_SHIFT == 16)
> +               pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
> +
> +       return pa;
> +}
> +
> +static inline u64 kvm_granule_shift(u32 level)
> +{
> +       /* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */
> +       return ARM64_HW_PGTABLE_LEVEL_SHIFT(level);
> +}
> +
> +static inline u64 kvm_granule_size(u32 level)
> +{
> +       return BIT(kvm_granule_shift(level));
> +}
> +
> +static inline bool kvm_level_supports_block_mapping(u32 level)
> +{
> +       /*
> +        * Reject invalid block mappings and don't bother with 4TB mappings for
> +        * 52-bit PAs.
> +        */
> +       return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
> +}
> +
>  /**
>   * struct kvm_pgtable_mm_ops - Memory management callbacks.
>   * @zalloc_page:               Allocate a single zeroed memory page.
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 78f36bd5df6c..49d768b92997 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -11,16 +11,12 @@
>  #include <asm/kvm_pgtable.h>
>  #include <asm/stage2_pgtable.h>
>
> -#define KVM_PTE_VALID                  BIT(0)
>
>  #define KVM_PTE_TYPE                   BIT(1)
>  #define KVM_PTE_TYPE_BLOCK             0
>  #define KVM_PTE_TYPE_PAGE              1
>  #define KVM_PTE_TYPE_TABLE             1
>
> -#define KVM_PTE_ADDR_MASK              GENMASK(47, PAGE_SHIFT)
> -#define KVM_PTE_ADDR_51_48             GENMASK(15, 12)
> -
>  #define KVM_PTE_LEAF_ATTR_LO           GENMASK(11, 2)
>
>  #define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX        GENMASK(4, 2)
> @@ -61,17 +57,6 @@ struct kvm_pgtable_walk_data {
>         u64                             end;
>  };
>
> -static u64 kvm_granule_shift(u32 level)
> -{
> -       /* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */
> -       return ARM64_HW_PGTABLE_LEVEL_SHIFT(level);
> -}
> -
> -static u64 kvm_granule_size(u32 level)
> -{
> -       return BIT(kvm_granule_shift(level));
> -}
> -
>  #define KVM_PHYS_INVALID (-1ULL)
>
>  static bool kvm_phys_is_valid(u64 phys)
> @@ -79,15 +64,6 @@ static bool kvm_phys_is_valid(u64 phys)
>         return phys < BIT(id_aa64mmfr0_parange_to_phys_shift(ID_AA64MMFR0_PARANGE_MAX));
>  }
>
> -static bool kvm_level_supports_block_mapping(u32 level)
> -{
> -       /*
> -        * Reject invalid block mappings and don't bother with 4TB mappings for
> -        * 52-bit PAs.
> -        */
> -       return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
> -}
> -
>  static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level)
>  {
>         u64 granule = kvm_granule_size(level);
> @@ -135,11 +111,6 @@ static u32 kvm_pgd_pages(u32 ia_bits, u32 start_level)
>         return __kvm_pgd_page_idx(&pgt, -1ULL) + 1;
>  }
>
> -static bool kvm_pte_valid(kvm_pte_t pte)
> -{
> -       return pte & KVM_PTE_VALID;
> -}
> -
>  static bool kvm_pte_table(kvm_pte_t pte, u32 level)
>  {
>         if (level == KVM_PGTABLE_MAX_LEVELS - 1)
> @@ -151,16 +122,6 @@ static bool kvm_pte_table(kvm_pte_t pte, u32 level)
>         return FIELD_GET(KVM_PTE_TYPE, pte) == KVM_PTE_TYPE_TABLE;
>  }
>
> -static u64 kvm_pte_to_phys(kvm_pte_t pte)
> -{
> -       u64 pa = pte & KVM_PTE_ADDR_MASK;
> -
> -       if (PAGE_SHIFT == 16)
> -               pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
> -
> -       return pa;
> -}
> -
>  static kvm_pte_t kvm_phys_to_pte(u64 pa)
>  {
>         kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK;
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:56:51 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:56:51 +0200
Subject: [PATCH v4 11/21] KVM: arm64: Allow populating software bits
In-Reply-To: <20210809152448.1810400-12-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-12-qperret@google.com>
Message-ID: <CA+EHjTxu57SbJdp45k7Rnp14pSaakg7L9eYOtCr1ohXnj19JGw@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> Introduce infrastructure allowing to manipulate software bits in stage-1
> and stage-2 page-tables using additional entries in the kvm_pgtable_prot
> enum.
>
> This is heavily inspired by Marc's implementation of a similar feature
> in the NV patch series, but adapted to allow stage-1 changes as well:
>
>   https://lore.kernel.org/kvmarm/20210510165920.1913477-56-maz at kernel.org/
>
> Suggested-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>  arch/arm64/include/asm/kvm_pgtable.h | 12 +++++++++++-
>  arch/arm64/kvm/hyp/pgtable.c         |  5 +++++
>  2 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index 2c090b0eee77..ff9d52f8073a 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -121,6 +121,10 @@ enum kvm_pgtable_stage2_flags {
>   * @KVM_PGTABLE_PROT_W:                Write permission.
>   * @KVM_PGTABLE_PROT_R:                Read permission.
>   * @KVM_PGTABLE_PROT_DEVICE:   Device attributes.
> + * @KVM_PGTABLE_PROT_SW0:      Software bit 0.
> + * @KVM_PGTABLE_PROT_SW1:      Software bit 1.
> + * @KVM_PGTABLE_PROT_SW2:      Software bit 2.
> + * @KVM_PGTABLE_PROT_SW3:      Software bit 3.
>   */
>  enum kvm_pgtable_prot {
>         KVM_PGTABLE_PROT_X                      = BIT(0),
> @@ -128,6 +132,11 @@ enum kvm_pgtable_prot {
>         KVM_PGTABLE_PROT_R                      = BIT(2),
>
>         KVM_PGTABLE_PROT_DEVICE                 = BIT(3),
> +
> +       KVM_PGTABLE_PROT_SW0                    = BIT(55),
> +       KVM_PGTABLE_PROT_SW1                    = BIT(56),
> +       KVM_PGTABLE_PROT_SW2                    = BIT(57),
> +       KVM_PGTABLE_PROT_SW3                    = BIT(58),
>  };
>
>  #define KVM_PGTABLE_PROT_RW    (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W)
> @@ -420,7 +429,8 @@ kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr);
>   * If there is a valid, leaf page-table entry used to translate @addr, then
>   * relax the permissions in that entry according to the read, write and
>   * execute permissions specified by @prot. No permissions are removed, and
> - * TLB invalidation is performed after updating the entry.
> + * TLB invalidation is performed after updating the entry. Software bits cannot
> + * be set or cleared using kvm_pgtable_stage2_relax_perms().
>   *
>   * Return: 0 on success, negative error code on failure.
>   */
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index e25d829587b9..cff744136044 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -357,6 +357,7 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep)
>         attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_AP, ap);
>         attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_SH, sh);
>         attr |= KVM_PTE_LEAF_ATTR_LO_S1_AF;
> +       attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW;
>         *ptep = attr;
>
>         return 0;
> @@ -558,6 +559,7 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p
>
>         attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S2_SH, sh);
>         attr |= KVM_PTE_LEAF_ATTR_LO_S2_AF;
> +       attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW;
>         *ptep = attr;
>
>         return 0;
> @@ -1025,6 +1027,9 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
>         u32 level;
>         kvm_pte_t set = 0, clr = 0;
>
> +       if (prot & KVM_PTE_LEAF_ATTR_HI_SW)
> +               return -EINVAL;
> +
>         if (prot & KVM_PGTABLE_PROT_R)
>                 set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
>
> --
> 2.32.0.605.g8dce9f2422-goog
>


From tabba at google.com  Mon Aug  9 21:57:13 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 10 Aug 2021 06:57:13 +0200
Subject: [PATCH v4 14/21] KVM: arm64: Expose pkvm_hyp_id
In-Reply-To: <20210809152448.1810400-15-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-15-qperret@google.com>
Message-ID: <CA+EHjTyxW_X-xjn7opfrLFWXupfjMzCZFVBYZjgpaqLbxbjDVQ@mail.gmail.com>

Hi Quentin,

On Mon, Aug 9, 2021 at 5:25 PM Quentin Perret <qperret at google.com> wrote:
>
> Allow references to the hypervisor's owner id from outside
> mem_protect.c.
>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---

Reviewed-by: Fuad Tabba <tabba at google.com>

Thanks,
/fuad

>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 2 ++
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 2 +-
>  2 files changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index 0849ee8fa260..23316a021880 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -46,6 +46,8 @@ struct host_kvm {
>  };
>  extern struct host_kvm host_kvm;
>
> +extern const u8 pkvm_hyp_id;
> +
>  int __pkvm_prot_finalize(void);
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index f95a5a4aa09c..ee255171945c 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -31,7 +31,7 @@ static struct hyp_pool host_s2_pool;
>  u64 id_aa64mmfr0_el1_sys_val;
>  u64 id_aa64mmfr1_el1_sys_val;
>
> -static const u8 pkvm_hyp_id = 1;
> +const u8 pkvm_hyp_id = 1;
>
>  static void *host_s2_zalloc_pages_exact(size_t size)
>  {
> --
> 2.32.0.605.g8dce9f2422-goog
>


From anshuman.khandual at arm.com  Mon Aug  9 22:06:38 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 10:36:38 +0530
Subject: [PATCH] arm64/perf: Replace '0xf' instances with
 ID_AA64DFR0_PMUVER_IMP_DEF
Message-ID: <1628571998-13634-1-git-send-email-anshuman.khandual@arm.com>

ID_AA64DFR0_PMUVER_IMP_DEF which indicate implementation defined PMU, never
actually gets used although there are '0xf' instances scattered all around.
Just do the macro replacement to improve readability.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: linux-perf-users at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.14-rc5

 arch/arm64/include/asm/cpufeature.h | 2 +-
 arch/arm64/kernel/perf_event.c      | 2 +-
 arch/arm64/kvm/perf.c               | 2 +-
 arch/arm64/kvm/pmu-emul.c           | 6 +++---
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 9bb9d11750d7..54474e76ad86 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -552,7 +552,7 @@ cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap)
 	u64 mask = GENMASK_ULL(field + 3, field);
 
 	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
-	if (val == 0xf)
+	if (val == ID_AA64DFR0_PMUVER_IMP_DEF)
 		val = 0;
 
 	if (val > cap) {
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index d07788dad388..b4044469527e 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1055,7 +1055,7 @@ static void __armv8pmu_probe_pmu(void *info)
 	dfr0 = read_sysreg(id_aa64dfr0_el1);
 	pmuver = cpuid_feature_extract_unsigned_field(dfr0,
 			ID_AA64DFR0_PMUVER_SHIFT);
-	if (pmuver == 0xf || pmuver == 0)
+	if (pmuver == ID_AA64DFR0_PMUVER_IMP_DEF || pmuver == 0)
 		return;
 
 	cpu_pmu->pmuver = pmuver;
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 151c31fb9860..f9bb3b14130e 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -50,7 +50,7 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
 
 int kvm_perf_init(void)
 {
-	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
+	if (kvm_pmu_probe_pmuver() != ID_AA64DFR0_PMUVER_IMP_DEF && !is_protected_kvm_enabled())
 		static_branch_enable(&kvm_arm_pmu_available);
 
 	return perf_register_guest_info_callbacks(&kvm_guest_cbs);
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index f33825c995cb..60f89bdbeebb 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -745,7 +745,7 @@ int kvm_pmu_probe_pmuver(void)
 	struct perf_event_attr attr = { };
 	struct perf_event *event;
 	struct arm_pmu *pmu;
-	int pmuver = 0xf;
+	int pmuver = ID_AA64DFR0_PMUVER_IMP_DEF;
 
 	/*
 	 * Create a dummy event that only counts user cycles. As we'll never
@@ -770,7 +770,7 @@ int kvm_pmu_probe_pmuver(void)
 	if (IS_ERR(event)) {
 		pr_err_once("kvm: pmu event creation failed %ld\n",
 			    PTR_ERR(event));
-		return 0xf;
+		return ID_AA64DFR0_PMUVER_IMP_DEF;
 	}
 
 	if (event->pmu) {
@@ -923,7 +923,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	if (!vcpu->kvm->arch.pmuver)
 		vcpu->kvm->arch.pmuver = kvm_pmu_probe_pmuver();
 
-	if (vcpu->kvm->arch.pmuver == 0xf)
+	if (vcpu->kvm->arch.pmuver == ID_AA64DFR0_PMUVER_IMP_DEF)
 		return -ENODEV;
 
 	switch (attr->attr) {
-- 
2.20.1



From marex at denx.de  Mon Aug  9 22:36:24 2021
From: marex at denx.de (Marek Vasut)
Date: Tue, 10 Aug 2021 07:36:24 +0200
Subject: [PATCH] ARM: imx_v6_v7_defconfig: enable driver of the LTC3676
 PMIC
In-Reply-To: <20210805135035.124938-1-pzimmermann@dh-electronics.com>
References: <20210805135035.124938-1-pzimmermann@dh-electronics.com>
Message-ID: <54505ae8-075c-bc54-e039-0badc261fa27@denx.de>

On 8/5/21 3:50 PM, Pascal Zimmermann wrote:
> The LTC3676 is a PMIC which is used on some i.MX6 based boards (like the
> DHCOM i.MX6 Quad SoM), it was first used on the GW Ventana board, enable
> LTC3676 driver in imx_v6_v7_defconfig.
> 
> Fixes: e3946fe805053 ("ARM: dts: add Gateworks Ventana support")
> Signed-off-by: Pascal Zimmermann <pzimmermann at dh-electronics.com>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
> Cc: Fabio Estevam <festevam at denx.de>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Marek Vasut <marex at denx.de>
> Cc: kernel at dh-electronics.com
> To: linux-arm-kernel at lists.infradead.org
> ---
>   arch/arm/configs/imx_v6_v7_defconfig | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
> index 079fcd8d1d11..f94e3d11c3e9 100644
> --- a/arch/arm/configs/imx_v6_v7_defconfig
> +++ b/arch/arm/configs/imx_v6_v7_defconfig
> @@ -252,6 +252,7 @@ CONFIG_REGULATOR_DA9052=y
>   CONFIG_REGULATOR_DA9062=y
>   CONFIG_REGULATOR_DA9063=y
>   CONFIG_REGULATOR_GPIO=y
> +CONFIG_REGULATOR_LTC3676=y
>   CONFIG_REGULATOR_MC13783=y
>   CONFIG_REGULATOR_MC13892=y
>   CONFIG_REGULATOR_PFUZE100=y

Reviewed-by: Marek Vasut <marex at denx.de>
Tested-by: Marek Vasut <marex at denx.de> # On DH iMX6Q DHCOM PDK2

Neither board can work well without a PMIC driver.


From matt at traverse.com.au  Mon Aug  9 22:38:23 2021
From: matt at traverse.com.au (Mathew McBride)
Date: Tue, 10 Aug 2021 05:38:23 +0000
Subject: [PATCH v3 0/5] Add Traverse Technologies Ten64 board DTS
In-Reply-To: <20210722042450.11862-1-matt@traverse.com.au>
References: <20210722042450.11862-1-matt@traverse.com.au>
Message-ID: <20210810053828.4240-1-matt@traverse.com.au>

The Traverse Technologies Ten64 board is a networking-oriented
Mini-ITX form factor appliance using the NXP LS1088A SoC.

This patch series adds a basic device tree (fsl-ls1088a-ten64.dts)
for the board. At the moment only hardware features supported
(or soon to be supported) by mainline kernels are described.

In the course of verifying the DTS on recent kernels, it
was found that some LS1088A features were not described
in fsl-ls1088a.dtsi. The first two patches add them.

The device tree includes a reference to the Epson RX-8035
RTC which depends on this patch series:
"rtc: Implement support for EPSON RX-8035", reviewed but
not yet in the Linus tree.
https://lore.kernel.org/linux-rtc/20210709044518.28769-1-matt at traverse.com.au/T/#t

Changes since v2:
 - Move flash (NOR and NAND) partitions under a partitions node
 - Fix minor spelling error in fsl.yaml (s/bassed/based/g)

Changes since v1:
 - Pick up Reviewed-By tags for PCS and MAC/PHY related parts
 - Use constants for describing interrupts for the PMU
 - Use the Cortex-A53 specific PMU compatible instead of the armv8-pmu3 generic
 - Fix formatting issues for the board DTS (ordering, newlines, node names)

Mathew McBride (5):
  arm64: dts: ls1088a: add internal PCS for DPMAC1 node
  arm64: dts: ls1088a: add missing PMU node
  dt-bindings: vendor-prefixes: add Traverse Technologies
  dt-bindings: arm: fsl: Add Traverse Ten64 (LS1088A) board
  arm64: dts: add device tree for Traverse Ten64 (LS1088A)

 .../devicetree/bindings/arm/fsl.yaml          |   6 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm64/boot/dts/freescale/Makefile        |   1 +
 .../boot/dts/freescale/fsl-ls1088a-ten64.dts  | 389 ++++++++++++++++++
 .../arm64/boot/dts/freescale/fsl-ls1088a.dtsi |  18 +
 5 files changed, 416 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts

-- 
2.30.1



From matt at traverse.com.au  Mon Aug  9 22:38:24 2021
From: matt at traverse.com.au (Mathew McBride)
Date: Tue, 10 Aug 2021 05:38:24 +0000
Subject: [PATCH v3 1/5] arm64: dts: ls1088a: add internal PCS for DPMAC1 node
In-Reply-To: <20210810053828.4240-1-matt@traverse.com.au>
References: <20210722042450.11862-1-matt@traverse.com.au>
 <20210810053828.4240-1-matt@traverse.com.au>
Message-ID: <20210810053828.4240-2-matt@traverse.com.au>

A previous patch added the PCS for DPMAC2 only, as
used for the AQR PHY on the LS1088ARDB.

DPMAC1 PCS access is required for PHYLINK SFP support
on the Traverse Ten64 board.

Signed-off-by: Mathew McBride <matt at traverse.com.au>
Reviewed-by: Ioana Ciornei <ioana.ciornei at nxp.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 2fa6cfbef01f..79ceadc9dc4a 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -765,6 +765,19 @@ emdio2: mdio at 8b97000 {
 			status = "disabled";
 		};
 
+		pcs_mdio1: mdio at 8c07000 {
+			compatible = "fsl,fman-memac-mdio";
+			reg = <0x0 0x8c07000 0x0 0x1000>;
+			little-endian;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+
+			pcs1: ethernet-phy at 0 {
+				reg = <0>;
+			};
+		};
+
 		pcs_mdio2: mdio at 8c0b000 {
 			compatible = "fsl,fman-memac-mdio";
 			reg = <0x0 0x8c0b000 0x0 0x1000>;
-- 
2.30.1



From matt at traverse.com.au  Mon Aug  9 22:38:25 2021
From: matt at traverse.com.au (Mathew McBride)
Date: Tue, 10 Aug 2021 05:38:25 +0000
Subject: [PATCH v3 2/5] arm64: dts: ls1088a: add missing PMU node
In-Reply-To: <20210810053828.4240-1-matt@traverse.com.au>
References: <20210722042450.11862-1-matt@traverse.com.au>
 <20210810053828.4240-1-matt@traverse.com.au>
Message-ID: <20210810053828.4240-3-matt@traverse.com.au>

The Performance Manager Unit was not described in the DTS
which meant performance event monitoring was not possible.

This was exposed by a change to the PMU handling in KVM
in 5.11-rc3 which now prevents a PMU being exposed to a
guest when the host does not provide one:
"KVM: arm64: Don't access PMCR_EL0 when no PMU is available"

Signed-off-by: Mathew McBride <matt at traverse.com.au>
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 79ceadc9dc4a..f85e437f80b7 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -189,6 +189,11 @@ timer {
 			     <1 10 IRQ_TYPE_LEVEL_LOW>;/* Hypervisor PPI */
 	};
 
+	pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+	};
+
 	psci {
 		compatible = "arm,psci-0.2";
 		method = "smc";
-- 
2.30.1



From matt at traverse.com.au  Mon Aug  9 22:38:26 2021
From: matt at traverse.com.au (Mathew McBride)
Date: Tue, 10 Aug 2021 05:38:26 +0000
Subject: [PATCH v3 3/5] dt-bindings: vendor-prefixes: add Traverse Technologies
In-Reply-To: <20210810053828.4240-1-matt@traverse.com.au>
References: <20210722042450.11862-1-matt@traverse.com.au>
 <20210810053828.4240-1-matt@traverse.com.au>
Message-ID: <20210810053828.4240-4-matt@traverse.com.au>

Traverse Technologies is a designer and manufacturer
of networking appliances.

Signed-off-by: Mathew McBride <matt at traverse.com.au>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 07fb0d25fc15..eba2029d3ba7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1184,6 +1184,8 @@ patternProperties:
     description: TPO
   "^tq,.*":
     description: TQ-Systems GmbH
+  "^traverse,.*":
+    description: Traverse Technologies Australia Pty Ltd
   "^tronfy,.*":
     description: Tronfy
   "^tronsmart,.*":
-- 
2.30.1



From matt at traverse.com.au  Mon Aug  9 22:38:27 2021
From: matt at traverse.com.au (Mathew McBride)
Date: Tue, 10 Aug 2021 05:38:27 +0000
Subject: [PATCH v3 4/5] dt-bindings: arm: fsl: Add Traverse Ten64 (LS1088A)
 board
In-Reply-To: <20210810053828.4240-1-matt@traverse.com.au>
References: <20210722042450.11862-1-matt@traverse.com.au>
 <20210810053828.4240-1-matt@traverse.com.au>
Message-ID: <20210810053828.4240-5-matt@traverse.com.au>

Document the compatible for the Ten64 board which will
be included as freescale/fsl-ls1088a-ten64.dtb in arm64.

Signed-off-by: Mathew McBride <matt at traverse.com.au>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 1c827c1954dc..20537be8e803 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -973,6 +973,12 @@ properties:
               - fsl,s32v234-evb           # S32V234-EVB2 Customer Evaluation Board
           - const: fsl,s32v234
 
+      - description: Traverse LS1088A based Boards
+        items:
+          - enum:
+              - traverse,ten64            # Ten64 Networking Appliance / Board
+          - const: fsl,ls1088a
+
 additionalProperties: true
 
 ...
-- 
2.30.1



From matt at traverse.com.au  Mon Aug  9 22:38:28 2021
From: matt at traverse.com.au (Mathew McBride)
Date: Tue, 10 Aug 2021 05:38:28 +0000
Subject: [PATCH v3 5/5] arm64: dts: add device tree for Traverse Ten64
 (LS1088A)
In-Reply-To: <20210810053828.4240-1-matt@traverse.com.au>
References: <20210722042450.11862-1-matt@traverse.com.au>
 <20210810053828.4240-1-matt@traverse.com.au>
Message-ID: <20210810053828.4240-6-matt@traverse.com.au>

The Traverse Technologies Ten64 is a Mini-ITX form factor
networking board using the NXP LS1088A SoC.

This device tree only describes features which the mainline
kernel currently has support for, such as some I2C-connected
devices that are not described at present.

System documentation may be found at ten64doc.traverse.com.au

Signed-off-by: Mathew McBride <matt at traverse.com.au>
Reviewed-by: Ioana Ciornei <ioana.ciornei at nxp.com> # for the MAC/PHY
---
 arch/arm64/boot/dts/freescale/Makefile        |   1 +
 .../boot/dts/freescale/fsl-ls1088a-ten64.dts  | 389 ++++++++++++++++++
 2 files changed, 390 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 25806c4924cb..2b3ee42e4a2a 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -19,6 +19,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-ten64.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts
new file mode 100644
index 000000000000..3063851c2fb9
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts
@@ -0,0 +1,389 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Travese Ten64 (LS1088) board
+ * Based on fsl-ls1088a-rdb.dts
+ * Copyright 2017-2020 NXP
+ * Copyright 2019-2021 Traverse Technologies
+ *
+ * Author: Mathew McBride <matt at traverse.com.au>
+ */
+
+/dts-v1/;
+
+#include "fsl-ls1088a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Traverse Ten64";
+	compatible = "traverse,ten64", "fsl,ls1088a";
+
+	aliases {
+		serial0 = &duart0;
+		serial1 = &duart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	buttons {
+		compatible = "gpio-keys";
+
+		/* Fired by system controller when
+		 * external power off (e.g ATX Power Button)
+		 * asserted
+		 */
+		powerdn {
+			label = "External Power Down";
+			gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
+			interrupts = <&gpio1 17 IRQ_TYPE_EDGE_FALLING>;
+			linux,code = <KEY_POWER>;
+		};
+
+		/* Rear Panel 'ADMIN' button (GPIO_H) */
+		admin {
+			label = "ADMIN button";
+			gpios = <&gpio3 8 GPIO_ACTIVE_HIGH>;
+			interrupts = <&gpio3 8 IRQ_TYPE_EDGE_RISING>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		sfp1down {
+			label = "ten64:green:sfp1:down";
+			gpios = <&gpio3 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		sfp2up {
+			label = "ten64:green:sfp2:up";
+			gpios = <&gpio3 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		admin {
+			label = "ten64:admin";
+			gpios = <&sfpgpio 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	sfp_xg0: dpmac2-sfp {
+		compatible = "sff,sfp";
+		i2c-bus = <&sfplower_i2c>;
+		tx-fault-gpios = <&sfpgpio 0 GPIO_ACTIVE_HIGH>;
+		tx-disable-gpios = <&sfpgpio 1 GPIO_ACTIVE_HIGH>;
+		mod-def0-gpios = <&sfpgpio 2 GPIO_ACTIVE_LOW>;
+		los-gpios = <&sfpgpio 3 GPIO_ACTIVE_HIGH>;
+		maximum-power-milliwatt = <2000>;
+	};
+
+	sfp_xg1: dpmac1-sfp {
+		compatible = "sff,sfp";
+		i2c-bus = <&sfpupper_i2c>;
+		tx-fault-gpios = <&sfpgpio 4 GPIO_ACTIVE_HIGH>;
+		tx-disable-gpios = <&sfpgpio 5 GPIO_ACTIVE_HIGH>;
+		mod-def0-gpios = <&sfpgpio 6 GPIO_ACTIVE_LOW>;
+		los-gpios = <&sfpgpio 7 GPIO_ACTIVE_HIGH>;
+		maximum-power-milliwatt = <2000>;
+	};
+};
+
+/* XG1 - Upper SFP */
+&dpmac1 {
+	sfp = <&sfp_xg1>;
+	pcs-handle = <&pcs1>;
+	phy-connection-type = "10gbase-r";
+	managed = "in-band-status";
+};
+
+/* XG0 - Lower SFP */
+&dpmac2 {
+	sfp = <&sfp_xg0>;
+	pcs-handle = <&pcs2>;
+	phy-connection-type = "10gbase-r";
+	managed = "in-band-status";
+};
+
+/* DPMAC3..6 is GE4 to GE8 */
+&dpmac3 {
+	phy-handle = <&mdio1_phy5>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	pcs-handle = <&pcs3_0>;
+};
+
+&dpmac4 {
+	phy-handle = <&mdio1_phy6>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	pcs-handle = <&pcs3_1>;
+};
+
+&dpmac5 {
+	phy-handle = <&mdio1_phy7>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	pcs-handle = <&pcs3_2>;
+};
+
+&dpmac6 {
+	phy-handle = <&mdio1_phy8>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	pcs-handle = <&pcs3_3>;
+};
+
+/* DPMAC7..10 is GE0 to GE3 */
+&dpmac7 {
+	phy-handle = <&mdio1_phy1>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	pcs-handle = <&pcs7_0>;
+};
+
+&dpmac8 {
+	phy-handle = <&mdio1_phy2>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	pcs-handle = <&pcs7_1>;
+};
+
+&dpmac9 {
+	phy-handle = <&mdio1_phy3>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	pcs-handle = <&pcs7_2>;
+};
+
+&dpmac10 {
+	phy-handle = <&mdio1_phy4>;
+	phy-connection-type = "qsgmii";
+	managed = "in-band-status";
+	pcs-handle = <&pcs7_3>;
+};
+
+&duart0 {
+	status = "okay";
+};
+
+&duart1 {
+	status = "okay";
+};
+
+&emdio1 {
+	status = "okay";
+
+	mdio1_phy5: ethernet-phy at c {
+		reg = <0xc>;
+	};
+
+	mdio1_phy6: ethernet-phy at d {
+		reg = <0xd>;
+	};
+
+	mdio1_phy7: ethernet-phy at e {
+		reg = <0xe>;
+	};
+
+	mdio1_phy8: ethernet-phy at f {
+		reg = <0xf>;
+	};
+
+	mdio1_phy1: ethernet-phy at 1c {
+		reg = <0x1c>;
+	};
+
+	mdio1_phy2: ethernet-phy at 1d {
+		reg = <0x1d>;
+	};
+
+	mdio1_phy3: ethernet-phy at 1e {
+		reg = <0x1e>;
+	};
+
+	mdio1_phy4: ethernet-phy at 1f {
+		reg = <0x1f>;
+	};
+};
+
+&esdhc {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	sfpgpio: gpio at 76 {
+		compatible = "ti,tca9539";
+		reg = <0x76>;
+		#gpio-cells = <2>;
+		gpio-controller;
+
+		admin_led_lower {
+			gpio-hog;
+			gpios = <13 GPIO_ACTIVE_HIGH>;
+			output-low;
+		};
+	};
+
+	at97sc: tpm at 29 {
+		compatible = "atmel,at97sc3204t";
+		reg = <0x29>;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	rx8035: rtc at 32 {
+		compatible = "epson,rx8035";
+		reg = <0x32>;
+	};
+};
+
+&i2c3 {
+	status = "okay";
+
+	i2c-switch at 70 {
+		compatible = "nxp,pca9540";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		sfpupper_i2c: i2c at 0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		sfplower_i2c: i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+	};
+};
+
+&pcs_mdio1 {
+	status = "okay";
+};
+
+&pcs_mdio2 {
+	status = "okay";
+};
+
+&pcs_mdio3 {
+	status = "okay";
+};
+
+&pcs_mdio7 {
+	status = "okay";
+};
+
+&qspi {
+	status = "okay";
+
+	en25s64: flash at 0 {
+		compatible = "jedec,spi-nor";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition at 0 {
+				label = "bl2";
+				reg = <0 0x100000>;
+			};
+
+			partition at 100000 {
+				label = "bl3";
+				reg = <0x100000 0x200000>;
+			};
+
+			partition at 300000 {
+				label = "mcfirmware";
+				reg = <0x300000 0x200000>;
+			};
+
+			partition at 500000 {
+				label = "ubootenv";
+				reg = <0x500000 0x80000>;
+			};
+
+			partition at 580000 {
+				label = "dpl";
+				reg = <0x580000 0x40000>;
+			};
+
+			partition at 5C0000 {
+				label = "dpc";
+				reg = <0x5C0000 0x40000>;
+			};
+
+			partition at 600000 {
+				label = "devicetree";
+				reg = <0x600000 0x40000>;
+			};
+		};
+	};
+
+	nand: flash at 1 {
+		compatible = "spi-nand";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <1>;
+		spi-max-frequency = <20000000>;
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			/* reserved for future boot direct from NAND flash
+			 * (this would use the same layout as the 8MiB NOR flash)
+			 */
+			partition at 0 {
+				label = "nand-boot-reserved";
+				reg = <0 0x800000>;
+			};
+
+			/* recovery / install environment */
+			partition at 800000 {
+				label = "recovery";
+				reg = <0x800000 0x2000000>;
+			};
+
+			/* ubia (first OpenWrt) - a/b names to prevent confusion with ubi0/1/etc. */
+			partition at 2800000 {
+				label = "ubia";
+				reg = <0x2800000 0x6C00000>;
+			};
+
+			/* ubib (second OpenWrt) */
+			partition at 9400000 {
+				label = "ubib";
+				reg = <0x9400000 0x6C00000>;
+			};
+		};
+	};
+};
+
+&usb0 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
-- 
2.30.1



From gregkh at linuxfoundation.org  Mon Aug  9 22:57:26 2021
From: gregkh at linuxfoundation.org (Greg KH)
Date: Tue, 10 Aug 2021 07:57:26 +0200
Subject: [PATCH] arm64: clean vdso files
In-Reply-To: <20210809191414.3572827-1-adelg@google.com>
References: <20210809191414.3572827-1-adelg@google.com>
Message-ID: <YRIVRgxhvGJxfXYs@kroah.com>

On Mon, Aug 09, 2021 at 07:14:14PM +0000, Andrew Delgadillo wrote:
> commit a5b8ca97fbf8 ("arm64: do not descend to vdso directories twice")
> changes the cleaning behavior of arm64's vdso files, in that vdso.lds,
> vdso.so, and vdso.so.dbg are not removed upon a 'make clean/mrproper':
> 
> $ make defconfig ARCH=arm64
> $ make ARCH=arm64
> $ make mrproper ARCH=arm64
> $ git clean -nxdf
> Would remove arch/arm64/kernel/vdso/vdso.lds
> Would remove arch/arm64/kernel/vdso/vdso.so
> Would remove arch/arm64/kernel/vdso/vdso.so.dbg
> 
> To remedy this, manually descend into arch/arm64/kernel/vdso upon
> cleaning.
> 
> After this commit:
> $ make defconfig ARCH=arm64
> $ make ARCH=arm64
> $ make mrproper ARCH=arm64
> $ git clean -nxdf
> <empty>
> 
> Signed-off-by: Andrew Delgadillo <adelg at google.com>
> ---
>  arch/arm64/Makefile | 1 +
>  1 file changed, 1 insertion(+)
> 

<formletter>

This is not the correct way to submit patches for inclusion in the
stable kernel tree.  Please read:
    https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.

</formletter>


From juerg.haefliger at canonical.com  Mon Aug  9 23:13:50 2021
From: juerg.haefliger at canonical.com (Juerg Haefliger)
Date: Tue, 10 Aug 2021 08:13:50 +0200
Subject: [PATCH] ARM: Fix instruction set selection for GCC 11
Message-ID: <20210810061350.754134-1-juergh@canonical.com>

GCC 11 on ARM now complains like the following when trying to determine if
an arch is supported. Presumably because it enforces the default option
'--with-float=hard' which GCC 10 didn't do?

  $ arm-linux-gnueabihf-gcc-11 -march=armv7-a -c -x c /dev/null
  cc1: error: ?-mfloat-abi=hard?: selected architecture lacks an FPU

Due to that, the kernel build system selects the wrong compiler options
which throws errros like this during the build:

  /tmp/ccrHfZPj.s: Assembler messages:
  /tmp/ccrHfZPj.s:116: Error: selected processor does not support `dmb ish' in ARM mode
  /tmp/ccrHfZPj.s:150: Error: selected processor does not support `isb ' in ARM mode
  /tmp/ccrHfZPj.s:160: Error: selected processor does not support `mrrc p15,1,r4,r5,c14' in ARM mode
  /tmp/ccrHfZPj.s:245: Error: selected processor does not support `dmb ish' in ARM mode
  /tmp/ccrHfZPj.s:503: Error: selected processor does not support `dmb ish' in ARM mode
  /tmp/ccrHfZPj.s:527: Error: selected processor does not support `dmb ish' in ARM mode
  /tmp/ccrHfZPj.s:698: Error: selected processor does not support `dmb ish' in ARM mode
  /tmp/ccrHfZPj.s:731: Error: selected processor does not support `isb ' in ARM mode

Fix that by adding '-msoft-float' to KBUILD_CFLAGS before the definition of
the 'arch-$(CONFIG_CPU_<foo>)' instruction selection macros.

Signed-off-by: Juerg Haefliger <juergh at canonical.com>
---
 arch/arm/Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 173da685a52e..d21198833997 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -56,6 +56,9 @@ endif
 #
 KBUILD_CFLAGS	+= $(call cc-option,-fno-ipa-sra)
 
+# Need -msoft-float for gcc 11 for the below instruction set selection
+KBUILD_CFLAGS	+= -msoft-float
+
 # This selects which instruction set is used.
 # Note that GCC does not numerically define an architecture version
 # macro, but instead defines a whole series of macros which makes
@@ -125,7 +128,7 @@ AFLAGS_ISA	:=$(CFLAGS_ISA)
 endif
 
 # Need -Uarm for gcc < 3.x
-KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -Uarm
 KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
 
 CHECKFLAGS	+= -D__arm__
-- 
2.30.2



From a-govindraju at ti.com  Mon Aug  9 23:44:20 2021
From: a-govindraju at ti.com (Aswath Govindraju)
Date: Tue, 10 Aug 2021 12:14:20 +0530
Subject: [PATCH] ARM: dts: vf610-zii-dev-rev-b: Remove #address-cells and
 #size-cells property from at93c46d dt node
Message-ID: <20210810064420.9489-1-a-govindraju@ti.com>

Remove #address-cells and #size-cells property from at93c46d device tree
node as it does not have child nodes.

Fixes: 1556063fde42 ("ARM: dts: vf610-zii-dev: Add ZII development board.")
Signed-off-by: Aswath Govindraju <a-govindraju at ti.com>
---
 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
index 6f1e0f0d4f0a..043ddd70372f 100644
--- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@ -311,8 +311,6 @@
 			compatible = "atmel,at93c46d";
 			pinctrl-0 = <&pinctrl_gpio_e6185_eeprom_sel>;
 			pinctrl-names = "default";
-			#address-cells = <0>;
-			#size-cells = <0>;
 			reg = <1>;
 			spi-max-frequency = <500000>;
 			spi-cs-high;
-- 
2.17.1



From leon at kernel.org  Mon Aug  9 23:50:41 2021
From: leon at kernel.org (Leon Romanovsky)
Date: Tue, 10 Aug 2021 09:50:41 +0300
Subject: [PATCH net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <20210809131152.509092-1-vladimir.oltean@nxp.com>
References: <20210809131152.509092-1-vladimir.oltean@nxp.com>
Message-ID: <YRIhwQ3ji8eqPQOQ@unreal>

On Mon, Aug 09, 2021 at 04:11:52PM +0300, Vladimir Oltean wrote:
> The blamed commit a new field to struct switchdev_notifier_fdb_info, but
> did not make sure that all call paths set it to something valid. For
> example, a switchdev driver may emit a SWITCHDEV_FDB_ADD_TO_BRIDGE
> notifier, and since the 'is_local' flag is not set, it contains junk
> from the stack, so the bridge might interpret those notifications as
> being for local FDB entries when that was not intended.
> 
> To avoid that now and in the future, zero-initialize all
> switchdev_notifier_fdb_info structures created by drivers such that all
> newly added fields to not need to touch drivers again.
> 
> Fixes: 2c4eca3ef716 ("net: bridge: switchdev: include local flag in FDB notifications")
> Reported-by: Ido Schimmel <idosch at idosch.org>
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> ---
>  drivers/net/ethernet/marvell/prestera/prestera_switchdev.c | 2 ++
>  drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c       | 1 +
>  drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c      | 2 ++
>  drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 1 +
>  drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c    | 1 +
>  drivers/net/ethernet/rocker/rocker_main.c                  | 1 +
>  drivers/net/ethernet/rocker/rocker_ofdpa.c                 | 1 +
>  drivers/net/ethernet/ti/am65-cpsw-switchdev.c              | 1 +
>  drivers/net/ethernet/ti/cpsw_switchdev.c                   | 1 +
>  drivers/s390/net/qeth_l2_main.c                            | 2 ++
>  net/dsa/slave.c                                            | 1 +
>  11 files changed, 14 insertions(+)
> 
> diff --git a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
> index 0b3e8f2db294..cf60e80dd3ba 100644
> --- a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
> +++ b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
> @@ -750,6 +750,7 @@ prestera_fdb_offload_notify(struct prestera_port *port,
>  {
>  	struct switchdev_notifier_fdb_info send_info;
>  
> +	memset(&send_info, 0, sizeof(send_info));

This can be written simpler.
struct switchdev_notifier_fdb_info send_info = {};

In all places.

Thanks

>  	send_info.addr = info->addr;
>  	send_info.vid = info->vid;
>  	send_info.offloaded = true;
> @@ -1146,6 +1147,7 @@ static void prestera_fdb_event(struct prestera_switch *sw,
>  	if (!dev)
>  		return;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = evt->fdb_evt.data.mac;
>  	info.vid = evt->fdb_evt.vid;
>  	info.offloaded = true;
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
> index a6e1d4f78268..77e09397a062 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
> @@ -71,6 +71,7 @@ mlx5_esw_bridge_fdb_offload_notify(struct net_device *dev, const unsigned char *
>  {
>  	struct switchdev_notifier_fdb_info send_info;
>  
> +	memset(&send_info, 0, sizeof(send_info));
>  	send_info.addr = addr;
>  	send_info.vid = vid;
>  	send_info.offloaded = true;
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
> index 7e221ef01437..8a7660f2d048 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
> @@ -9086,6 +9086,7 @@ static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
>  	if (!dev)
>  		return;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = mac;
>  	info.vid = 0;
>  	call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info,
> @@ -9137,6 +9138,7 @@ static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
>  	if (!dev)
>  		return;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = mac;
>  	info.vid = vid;
>  	call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info,
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> index c5ef9aa64efe..f016d909bead 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> @@ -2510,6 +2510,7 @@ mlxsw_sp_fdb_call_notifiers(enum switchdev_notifier_type type,
>  {
>  	struct switchdev_notifier_fdb_info info;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = mac;
>  	info.vid = vid;
>  	info.offloaded = offloaded;
> diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
> index 0443f66b5550..fbc3f5e65882 100644
> --- a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
> +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
> @@ -279,6 +279,7 @@ static void sparx5_fdb_call_notifiers(enum switchdev_notifier_type type,
>  {
>  	struct switchdev_notifier_fdb_info info;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = mac;
>  	info.vid = vid;
>  	info.offloaded = offloaded;
> diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
> index a46633606cae..49d548be9fe4 100644
> --- a/drivers/net/ethernet/rocker/rocker_main.c
> +++ b/drivers/net/ethernet/rocker/rocker_main.c
> @@ -2717,6 +2717,7 @@ rocker_fdb_offload_notify(struct rocker_port *rocker_port,
>  {
>  	struct switchdev_notifier_fdb_info info;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = recv_info->addr;
>  	info.vid = recv_info->vid;
>  	info.offloaded = true;
> diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c
> index 967a634ee9ac..7d954fd24134 100644
> --- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
> +++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
> @@ -1824,6 +1824,7 @@ static void ofdpa_port_fdb_learn_work(struct work_struct *work)
>  	bool learned = (lw->flags & OFDPA_OP_FLAG_LEARNED);
>  	struct switchdev_notifier_fdb_info info;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = lw->addr;
>  	info.vid = lw->vid;
>  
> diff --git a/drivers/net/ethernet/ti/am65-cpsw-switchdev.c b/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
> index 9c29b363e9ae..81d2b1765a66 100644
> --- a/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
> +++ b/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
> @@ -360,6 +360,7 @@ static void am65_cpsw_fdb_offload_notify(struct net_device *ndev,
>  {
>  	struct switchdev_notifier_fdb_info info;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = rcv->addr;
>  	info.vid = rcv->vid;
>  	info.offloaded = true;
> diff --git a/drivers/net/ethernet/ti/cpsw_switchdev.c b/drivers/net/ethernet/ti/cpsw_switchdev.c
> index f7fb6e17dadd..446bdab06bdd 100644
> --- a/drivers/net/ethernet/ti/cpsw_switchdev.c
> +++ b/drivers/net/ethernet/ti/cpsw_switchdev.c
> @@ -370,6 +370,7 @@ static void cpsw_fdb_offload_notify(struct net_device *ndev,
>  {
>  	struct switchdev_notifier_fdb_info info;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = rcv->addr;
>  	info.vid = rcv->vid;
>  	info.offloaded = true;
> diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
> index 2abf86c104d5..843dd4f4d8d7 100644
> --- a/drivers/s390/net/qeth_l2_main.c
> +++ b/drivers/s390/net/qeth_l2_main.c
> @@ -283,6 +283,7 @@ static void qeth_l2_dev2br_fdb_flush(struct qeth_card *card)
>  
>  	QETH_CARD_TEXT(card, 2, "fdbflush");
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = NULL;
>  	/* flush all VLANs: */
>  	info.vid = 0;
> @@ -693,6 +694,7 @@ static void qeth_l2_dev2br_fdb_notify(struct qeth_card *card, u8 code,
>  	if (qeth_is_my_net_if_token(card, token))
>  		return;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = ntfy_mac;
>  	/* don't report VLAN IDs */
>  	info.vid = 0;
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index 532085da8d8f..1cb7f7e56784 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -2298,6 +2298,7 @@ dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work)
>  	if (!dsa_is_user_port(ds, switchdev_work->port))
>  		return;
>  
> +	memset(&info, 0, sizeof(info));
>  	info.addr = switchdev_work->addr;
>  	info.vid = switchdev_work->vid;
>  	info.offloaded = true;
> -- 
> 2.25.1
> 


From krzysztof.kozlowski at canonical.com  Mon Aug  9 23:53:52 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 08:53:52 +0200
Subject: [PATCH v2 4/9] usb: gadget: udc: s3c2410: add IRQ check
In-Reply-To: <bd69b22c-b484-5a1f-c798-78d4b78405f2@omp.ru>
References: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
 <bd69b22c-b484-5a1f-c798-78d4b78405f2@omp.ru>
Message-ID: <9db78434-6eb0-0094-3ed6-9b355eb923dc@canonical.com>

On 09/08/2021 22:35, Sergey Shtylyov wrote:
> The driver neglects to check the result of platform_get_irq()'s call and
> blithely passes the negative error codes to request_irq() (which takes
> *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
> error code. Stop calling request_irq() with the invalid IRQ #s.
> 
> Fixes: 188db4435ac6 ("usb: gadget: s3c: use platform resources")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>
> 
> ---
>  drivers/usb/gadget/udc/s3c2410_udc.c |    4 ++++
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From tony at atomide.com  Mon Aug  9 23:59:42 2021
From: tony at atomide.com (Tony Lindgren)
Date: Tue, 10 Aug 2021 09:59:42 +0300
Subject: [PATCH 1/2] ARM: dts: am335x-sancloud-bbe: Fix missing pinctrl
 refs
In-Reply-To: <20210806085907.14615-1-paul.barker@sancloud.com>
References: <20210806085907.14615-1-paul.barker@sancloud.com>
Message-ID: <YRIj3qaCuiMRZ4m7@atomide.com>

* Paul Barker <paul.barker at sancloud.com> [210806 11:59]:
> pinctrl settings for the USB hub, barometer & accelerometer need to be
> referenced from the relevant nodes to work.

Thanks applying both into omap-for-v5.15/dt.

Tony


From anshuman.khandual at arm.com  Tue Aug 10 00:02:36 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 12:32:36 +0530
Subject: [PATCH 0/5] KVM: arm64: General cleanups
Message-ID: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>

This series contains mostly unrelated general cleanups. This series applies
on v5.14-rc5 and has been boot tested with different page sized guests.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (5):
  KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as page size
  KVM: arm64: Drop init_common_resources()
  KVM: arm64: Drop check_kvm_target_cpu() based percpu probe
  KVM: arm64: Drop unused REQUIRES_VIRT
  KVM: arm64: Define KVM_PHYS_SHIFT_MIN

 arch/arm64/include/asm/kvm_mmu.h |  3 ++-
 arch/arm64/kvm/arm.c             | 25 +------------------------
 arch/arm64/kvm/hyp/pgtable.c     |  6 +++---
 arch/arm64/kvm/reset.c           |  2 +-
 arch/arm64/mm/mmu.c              |  2 +-
 5 files changed, 8 insertions(+), 30 deletions(-)

-- 
2.20.1



From anshuman.khandual at arm.com  Tue Aug 10 00:02:37 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 12:32:37 +0530
Subject: [PATCH 1/5] KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as page
 size
In-Reply-To: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>

All instances here could just directly test against CONFIG_ARM64_XXK_PAGES
instead of evaluating via PAGE_SHIFT or PAGE_SIZE. With this change, there
will be no such usage left.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kvm/hyp/pgtable.c | 6 +++---
 arch/arm64/mm/mmu.c          | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 05321f4165e3..a6112b6d6ef6 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -85,7 +85,7 @@ static bool kvm_level_supports_block_mapping(u32 level)
 	 * Reject invalid block mappings and don't bother with 4TB mappings for
 	 * 52-bit PAs.
 	 */
-	return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
+	return !(level == 0 || (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) && level == 1));
 }
 
 static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level)
@@ -155,7 +155,7 @@ static u64 kvm_pte_to_phys(kvm_pte_t pte)
 {
 	u64 pa = pte & KVM_PTE_ADDR_MASK;
 
-	if (PAGE_SHIFT == 16)
+	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
 		pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
 
 	return pa;
@@ -165,7 +165,7 @@ static kvm_pte_t kvm_phys_to_pte(u64 pa)
 {
 	kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK;
 
-	if (PAGE_SHIFT == 16)
+	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
 		pte |= FIELD_PREP(KVM_PTE_ADDR_51_48, pa >> 48);
 
 	return pte;
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 9ff0de1b2b93..8fdfca179815 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -296,7 +296,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
 static inline bool use_1G_block(unsigned long addr, unsigned long next,
 			unsigned long phys)
 {
-	if (PAGE_SHIFT != 12)
+	if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
 		return false;
 
 	if (((addr | next | phys) & ~PUD_MASK) != 0)
-- 
2.20.1



From anshuman.khandual at arm.com  Tue Aug 10 00:02:38 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 12:32:38 +0530
Subject: [PATCH 2/5] KVM: arm64: Drop init_common_resources()
In-Reply-To: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628578961-29097-3-git-send-email-anshuman.khandual@arm.com>

Could do without this additional indirection via init_common_resources() by
just calling kvm_set_ipa_limit() directly instead. This change saves memory
and cycles.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kvm/arm.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..19560e457c11 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1696,11 +1696,6 @@ static bool init_psci_relay(void)
 	return true;
 }
 
-static int init_common_resources(void)
-{
-	return kvm_set_ipa_limit();
-}
-
 static int init_subsystems(void)
 {
 	int err = 0;
@@ -2102,7 +2097,7 @@ int kvm_arch_init(void *opaque)
 		}
 	}
 
-	err = init_common_resources();
+	err = kvm_set_ipa_limit();
 	if (err)
 		return err;
 
-- 
2.20.1



From anshuman.khandual at arm.com  Tue Aug 10 00:02:39 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 12:32:39 +0530
Subject: [PATCH 3/5] KVM: arm64: Drop check_kvm_target_cpu() based percpu probe
In-Reply-To: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628578961-29097-4-git-send-email-anshuman.khandual@arm.com>

kvm_target_cpu() never returns a negative error code, so check_kvm_target()
would never have 'ret' filled with a negative error code. Hence the percpu
probe via check_kvm_target_cpu() does not make sense as its never going to
find an unsupported CPU, forcing kvm_arch_init() to exit early. Hence lets
just drop this percpu probe (and also check_kvm_target_cpu()) altogether.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kvm/arm.c | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 19560e457c11..16f93678c17e 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -2010,11 +2010,6 @@ static int finalize_hyp_mode(void)
 	return 0;
 }
 
-static void check_kvm_target_cpu(void *ret)
-{
-	*(int *)ret = kvm_target_cpu();
-}
-
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
 {
 	struct kvm_vcpu *vcpu;
@@ -2074,7 +2069,6 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons)
 int kvm_arch_init(void *opaque)
 {
 	int err;
-	int ret, cpu;
 	bool in_hyp_mode;
 
 	if (!is_hyp_mode_available()) {
@@ -2089,14 +2083,6 @@ int kvm_arch_init(void *opaque)
 		kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \
 			 "Only trusted guests should be used on this system.\n");
 
-	for_each_online_cpu(cpu) {
-		smp_call_function_single(cpu, check_kvm_target_cpu, &ret, 1);
-		if (ret < 0) {
-			kvm_err("Error, CPU %d not supported!\n", cpu);
-			return -ENODEV;
-		}
-	}
-
 	err = kvm_set_ipa_limit();
 	if (err)
 		return err;
-- 
2.20.1



From anshuman.khandual at arm.com  Tue Aug 10 00:02:40 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 12:32:40 +0530
Subject: [PATCH 4/5] KVM: arm64: Drop unused REQUIRES_VIRT
In-Reply-To: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628578961-29097-5-git-send-email-anshuman.khandual@arm.com>

This seems like a residue from the past. REQUIRES_VIRT is no more available
. Hence it can just be dropped along with the related code section.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kvm/arm.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 16f93678c17e..bae22d2bdca9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -42,10 +42,6 @@
 #include <kvm/arm_pmu.h>
 #include <kvm/arm_psci.h>
 
-#ifdef REQUIRES_VIRT
-__asm__(".arch_extension	virt");
-#endif
-
 static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT;
 DEFINE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);
 
-- 
2.20.1



From anshuman.khandual at arm.com  Tue Aug 10 00:02:41 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 12:32:41 +0530
Subject: [PATCH 5/5] KVM: arm64: Define KVM_PHYS_SHIFT_MIN
In-Reply-To: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628578961-29097-6-git-send-email-anshuman.khandual@arm.com>

Drop the hard coded value for the minimum IPA range i.e 32 bit. Instead
define a macro KVM_PHYS_SHIFT_MIN which improves the code readability.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/kvm_mmu.h | 3 ++-
 arch/arm64/kvm/reset.c           | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index b52c5c4b9a3d..716f999818d9 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -141,7 +141,8 @@ static __always_inline unsigned long __kern_hyp_va(unsigned long v)
  * We currently support using a VM-specified IPA size. For backward
  * compatibility, the default IPA size is fixed to 40bits.
  */
-#define KVM_PHYS_SHIFT	(40)
+#define KVM_PHYS_SHIFT		(40)
+#define KVM_PHYS_SHIFT_MIN	(32)
 
 #define kvm_phys_shift(kvm)		VTCR_EL2_IPA(kvm->arch.vtcr)
 #define kvm_phys_size(kvm)		(_AC(1, ULL) << kvm_phys_shift(kvm))
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index cba7872d69a8..8dc8b4b9de37 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -369,7 +369,7 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type)
 	phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
 	if (phys_shift) {
 		if (phys_shift > kvm_ipa_limit ||
-		    phys_shift < 32)
+		    phys_shift < KVM_PHYS_SHIFT_MIN)
 			return -EINVAL;
 	} else {
 		phys_shift = KVM_PHYS_SHIFT;
-- 
2.20.1



From rashmi.a at intel.com  Tue Aug 10 00:32:55 2021
From: rashmi.a at intel.com (A, Rashmi)
Date: Tue, 10 Aug 2021 07:32:55 +0000
Subject: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <CAPDyKFp5HcCfsoLgBc=D9RKOrVY2SuV3FKsFCVT2=WaxZBsNiA@mail.gmail.com>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-3-rashmi.a@intel.com>
 <CAPDyKFqZ-H3+OnYyyY7y611YrRAAMFq+W65DMfM4wSNvY_fzjA@mail.gmail.com>
 <MWHPR11MB17891909766F5295AF34B0578CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
 <YRDqQvKQ71/824Lu@matsya>
 <MWHPR11MB1789D2B707B39CB42322C73A8CF69@MWHPR11MB1789.namprd11.prod.outlook.com>
 <CAPDyKFp5HcCfsoLgBc=D9RKOrVY2SuV3FKsFCVT2=WaxZBsNiA@mail.gmail.com>
Message-ID: <MWHPR11MB17898D0E3A0A4DD993AD7E948CF79@MWHPR11MB1789.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Ulf Hansson <ulf.hansson at linaro.org>
> Sent: Monday, August 9, 2021 5:43 PM
> To: A, Rashmi <rashmi.a at intel.com>
> Cc: Vinod Koul <vkoul at kernel.org>; Michal Simek
> <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
> kernel at vger.kernel.org>; Kishon <kishon at ti.com>; Andy Shevchenko
> <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org; Mark
> Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou, Furong
> <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> <adrian.hunter at intel.com>; Vaidya, Mahesh R
> <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> <kenchappa.demakkanavar at intel.com>
> Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
> support to the arasan eMMC driver
> 
> On Mon, 9 Aug 2021 at 13:17, A, Rashmi <rashmi.a at intel.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Vinod Koul <vkoul at kernel.org>
> > > Sent: Monday, August 9, 2021 2:12 PM
> > > To: A, Rashmi <rashmi.a at intel.com>
> > > Cc: Ulf Hansson <ulf.hansson at linaro.org>; Michal Simek
> > > <michal.simek at xilinx.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> > > Linux ARM <linux-arm-kernel at lists.infradead.org>; Linux Kernel
> > > Mailing List <linux- kernel at vger.kernel.org>; Kishon
> > > <kishon at ti.com>; Andy Shevchenko
> > > <andriy.shevchenko at linux.intel.com>; linux-phy at lists.infradead.org;
> > > Mark Gross <mgross at linux.intel.com>; kris.pan at linux.intel.com; Zhou,
> > > Furong <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> > > <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> > > <adrian.hunter at intel.com>; Vaidya, Mahesh R
> > > <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> > > <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> > > <kenchappa.demakkanavar at intel.com>
> > > Subject: Re: [PATCH 2/3] mmc: sdhci-of-arasan: Add intel Thunder Bay
> > > SOC support to the arasan eMMC driver
> > >
> > > On 09-08-21, 05:16, A, Rashmi wrote:
> > >
> > > > >
> > > > > Rashmi, is it safe to apply this separately from the phy driver/dt
> changes?
> > > > > Then I can queue this via my mmc tree, if you like.
> > > > No, the phy driver/dt changes must go together with "mmc:
> > > > sdhci-of-
> > > arasan: Add intel Thunder Bay SOC support to the arasan eMMC driver"
> > > patch.
> > >
> > > Why is that?
> > >
> > > What could happen, emmc driver will complain about phy not found and
> > > bail right?
> > This is right, but ideally both mmc:phy and mmc: sdhci-of-arasan
> > driver code changes should go together
> 
> If patches are well written and can be standalone, we (maintainers) ideally
> prefer to queue things on a per subsystem basis, because it's just easier.
> 
> That said, I also noticed that a new compatible string was added,
> "intel,thunderbay-sdhci-5.1". This needs to be documented in
> Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml, in a separate
> patch, preceding $subject patch.
> 
I acknowledge your comments. I will submit a separate patch to document device tree bindings. After that mmc: sdhci-of-arasan driver patch could be queued.

Regards
Rashmi

From viresh.kumar at linaro.org  Tue Aug 10 00:36:47 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 10 Aug 2021 13:06:47 +0530
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
Message-ID: <cover.1628579170.git.viresh.kumar@linaro.org>

Provide a cpufreq driver flag so drivers can ask the cpufreq core to register
with the EM core on their behalf. This allows us to get rid of duplicated code
in the drivers and fix the unregistration part as well, which none of the
drivers have done until now.

This would also make the registration with EM core to happen only after policy
is fully initialized, and the EM core can do other stuff from in there, like
marking frequencies as inefficient (WIP). Though this patchset is useful without
that work being done and should be merged nevertheless.

This doesn't update scmi cpufreq driver for now as it is a special case and need
to be handled differently. Though we can make it work with this if required.

This is build/boot tested by the bot for a couple of boards.

https://gitlab.com/vireshk/pmko/-/pipelines/350674298

--
Viresh

Viresh Kumar (8):
  cpufreq: Auto-register with energy model if asked
  cpufreq: dt: Use auto-registration for energy model
  cpufreq: imx6q: Use auto-registration for energy model
  cpufreq: mediatek: Use auto-registration for energy model
  cpufreq: omap: Use auto-registration for energy model
  cpufreq: qcom-cpufreq-hw: Use auto-registration for energy model
  cpufreq: scpi: Use auto-registration for energy model
  cpufreq: vexpress: Use auto-registration for energy model

 drivers/cpufreq/cpufreq-dt.c           | 5 ++---
 drivers/cpufreq/cpufreq.c              | 9 +++++++++
 drivers/cpufreq/imx6q-cpufreq.c        | 4 ++--
 drivers/cpufreq/mediatek-cpufreq.c     | 5 ++---
 drivers/cpufreq/omap-cpufreq.c         | 4 ++--
 drivers/cpufreq/qcom-cpufreq-hw.c      | 5 ++---
 drivers/cpufreq/scpi-cpufreq.c         | 5 ++---
 drivers/cpufreq/vexpress-spc-cpufreq.c | 5 ++---
 include/linux/cpufreq.h                | 6 ++++++
 9 files changed, 29 insertions(+), 19 deletions(-)

-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Tue Aug 10 00:36:50 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 10 Aug 2021 13:06:50 +0530
Subject: [PATCH 3/8] cpufreq: imx6q: Use auto-registration for energy model
In-Reply-To: <cover.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <ba662b10e043e7734eb9d9e9bbc4c75afab9c2a4.1628579170.git.viresh.kumar@linaro.org>

Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
automatically register with the energy model.

This allows removal of boiler plate code from the driver and fixes the
unregistration part as well.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/imx6q-cpufreq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 5bf5fc759881..aa8df5b468d7 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -192,14 +192,14 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
 	policy->clk = clks[ARM].clk;
 	cpufreq_generic_init(policy, freq_table, transition_latency);
 	policy->suspend_freq = max_freq;
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
 
 	return 0;
 }
 
 static struct cpufreq_driver imx6q_cpufreq_driver = {
 	.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
-		 CPUFREQ_IS_COOLING_DEV,
+		 CPUFREQ_IS_COOLING_DEV |
+		 CPUFREQ_REGISTER_WITH_EM,
 	.verify = cpufreq_generic_frequency_table_verify,
 	.target_index = imx6q_set_target,
 	.get = cpufreq_generic_get,
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Tue Aug 10 00:36:51 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 10 Aug 2021 13:06:51 +0530
Subject: [PATCH 4/8] cpufreq: mediatek: Use auto-registration for energy model
In-Reply-To: <cover.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <fe10f291210bfd16620f4be766e6647c8e577995.1628579170.git.viresh.kumar@linaro.org>

Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
automatically register with the energy model.

This allows removal of boiler plate code from the driver and fixes the
unregistration part as well.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/mediatek-cpufreq.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
index 87019d5a9547..4743f2e58b97 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -448,8 +448,6 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy)
 	policy->driver_data = info;
 	policy->clk = info->cpu_clk;
 
-	dev_pm_opp_of_register_em(info->cpu_dev, policy->cpus);
-
 	return 0;
 }
 
@@ -465,7 +463,8 @@ static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
 static struct cpufreq_driver mtk_cpufreq_driver = {
 	.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
 		 CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
-		 CPUFREQ_IS_COOLING_DEV,
+		 CPUFREQ_IS_COOLING_DEV |
+		 CPUFREQ_REGISTER_WITH_EM,
 	.verify = cpufreq_generic_frequency_table_verify,
 	.target_index = mtk_cpufreq_set_target,
 	.get = cpufreq_generic_get,
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Tue Aug 10 00:36:54 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 10 Aug 2021 13:06:54 +0530
Subject: [PATCH 7/8] cpufreq: scpi: Use auto-registration for energy model
In-Reply-To: <cover.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <7809d747fecbaad46699a178f26288a015055b20.1628579170.git.viresh.kumar@linaro.org>

Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
automatically register with the energy model.

This allows removal of boiler plate code from the driver and fixes the
unregistration part as well.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/scpi-cpufreq.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
index d6a698a1b5d1..bc8c62b1beb5 100644
--- a/drivers/cpufreq/scpi-cpufreq.c
+++ b/drivers/cpufreq/scpi-cpufreq.c
@@ -163,8 +163,6 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
 
 	policy->fast_switch_possible = false;
 
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
-
 	return 0;
 
 out_free_cpufreq_table:
@@ -193,7 +191,8 @@ static struct cpufreq_driver scpi_cpufreq_driver = {
 	.name	= "scpi-cpufreq",
 	.flags	= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
 		  CPUFREQ_NEED_INITIAL_FREQ_CHECK |
-		  CPUFREQ_IS_COOLING_DEV,
+		  CPUFREQ_IS_COOLING_DEV |
+		  CPUFREQ_REGISTER_WITH_EM,
 	.verify	= cpufreq_generic_frequency_table_verify,
 	.attr	= cpufreq_generic_attr,
 	.get	= scpi_cpufreq_get_rate,
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Tue Aug 10 00:36:55 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 10 Aug 2021 13:06:55 +0530
Subject: [PATCH 8/8] cpufreq: vexpress: Use auto-registration for energy model
In-Reply-To: <cover.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>

Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
automatically register with the energy model.

This allows removal of boiler plate code from the driver and fixes the
unregistration part as well.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/vexpress-spc-cpufreq.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c
index 51dfa9ae6cf5..28c4c3254337 100644
--- a/drivers/cpufreq/vexpress-spc-cpufreq.c
+++ b/drivers/cpufreq/vexpress-spc-cpufreq.c
@@ -442,8 +442,6 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy)
 	policy->freq_table = freq_table[cur_cluster];
 	policy->cpuinfo.transition_latency = 1000000; /* 1 ms */
 
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
-
 	if (is_bL_switching_enabled())
 		per_cpu(cpu_last_req_freq, policy->cpu) =
 						clk_get_cpu_rate(policy->cpu);
@@ -487,7 +485,8 @@ static void ve_spc_cpufreq_ready(struct cpufreq_policy *policy)
 static struct cpufreq_driver ve_spc_cpufreq_driver = {
 	.name			= "vexpress-spc",
 	.flags			= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
-					CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+				  CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+				  CPUFREQ_REGISTER_WITH_EM,
 	.verify			= cpufreq_generic_frequency_table_verify,
 	.target_index		= ve_spc_cpufreq_set_target,
 	.get			= ve_spc_cpufreq_get_rate,
-- 
2.31.1.272.g89b43f80a514



From narmstrong at baylibre.com  Tue Aug 10 00:44:35 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:44:35 +0200
Subject: [GIT PULL] arm64: dts: amlogic updates for v5.15
Message-ID: <032895d9-62b6-6c9e-b04b-9c3d316f27ec@baylibre.com>

Hi,

Here's the ARM64 DT changes for v5.15:
- nanoki-k2: enable bluetooth
- khadas vim & vim2: improve wifi

Neil

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git tags/amlogic-arm64-dt-for-v5.15

for you to fetch changes up to 4b5260032ec691b11a9185f7f38f5761e67fab48:

  arm64: dts: meson: improve gxm-khadas-vim2 wifi (2021-07-26 10:08:16 +0200)

----------------------------------------------------------------
Amlogic ARM64 DT changes for v5.15:
- nanoki-k2: enable bluetooth
- khadas vim & vim2: improve wifi

----------------------------------------------------------------
Artem Lapkin (2):
      arm64: dts: meson: improve gxl-s905x-khadas-vim wifi
      arm64: dts: meson: improve gxm-khadas-vim2 wifi

Chen-Yu Tsai (1):
      arm64: dts: meson-gxbb: nanopi-k2: Enable Bluetooth

 arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts       | 13 ++++++++++++-
 arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts |  2 ++
 arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts      |  3 ++-
 3 files changed, 16 insertions(+), 2 deletions(-)


From narmstrong at baylibre.com  Tue Aug 10 00:45:21 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:45:21 +0200
Subject: [GIT PULL] arm: dts: amlogic updates for v5.15
Message-ID: <87519792-c9e7-76a6-5db5-0e955286b564@baylibre.com>

Hi,

Here's Amlogic ARM DT changes for v5.15:
- meson8: use a default higher default GPU clock to solve probe failure
- meson: add AIU audio controller and codec for ec100
- meson8b: fix pwm regulator supply property name

Neil

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git tags/amlogic-arm-dt-for-v5.15

for you to fetch changes up to 72ccc373b064ae3ac0c5b5f2306069b60ca118df:

  ARM: dts: meson8b: ec100: Fix the pwm regulator supply properties (2021-07-26 10:05:36 +0200)

----------------------------------------------------------------
Amlogic ARM DT changes for v5.15:
- meson8: use a default higher default GPU clock to solve probe failure
- meson: add AIU audio controller and codec for ec100
- meson8b: fix pwm regulator supply property name

----------------------------------------------------------------
Anand Moon (3):
      ARM: dts: meson8b: odroidc1: Fix the pwm regulator supply properties
      ARM: dts: meson8b: mxq: Fix the pwm regulator supply properties
      ARM: dts: meson8b: ec100: Fix the pwm regulator supply properties

Martin Blumenstingl (3):
      ARM: dts: meson8: Use a higher default GPU clock frequency
      ARM: dts: meson: Add the AIU audio controller
      ARM: dts: meson8b: ec100: wire up the RT5640 audio codec

 arch/arm/boot/dts/meson.dtsi           | 12 ++++++
 arch/arm/boot/dts/meson8.dtsi          | 68 ++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/meson8b-ec100.dts    | 48 +++++++++++++++++++++++-
 arch/arm/boot/dts/meson8b-mxq.dts      |  4 +-
 arch/arm/boot/dts/meson8b-odroidc1.dts |  4 +-
 arch/arm/boot/dts/meson8b.dtsi         | 63 +++++++++++++++++++++++++++++++
 6 files changed, 194 insertions(+), 5 deletions(-)


From narmstrong at baylibre.com  Tue Aug 10 00:46:59 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:46:59 +0200
Subject: [GIT PULL] ARM: multi_v7_defconfig: amlogic updates for v5.15
Message-ID: <8e2b5139-86e6-0da3-75c4-d8df66448d51@baylibre.com>

Hi,

Here's a single multi_v7_defconfig change for v5.15 to enable CONFIG_MMC_MESON_MX_SDHC controller used on meson8/8b

Neil

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git tags/amlogic-arm-configs-for-v5.15

for you to fetch changes up to c8cec81305463d042d51af946b6b273d8367626e:

  ARM: multi_v7_defconfig: Enable CONFIG_MMC_MESON_MX_SDHC (2021-07-26 09:59:09 +0200)

----------------------------------------------------------------
Amlogic ARM configs change for v5.15:
- Enable CONFIG_MMC_MESON_MX_SDHC controller used on meson8/8b

----------------------------------------------------------------
Anand Moon (1):
      ARM: multi_v7_defconfig: Enable CONFIG_MMC_MESON_MX_SDHC

 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)


From narmstrong at baylibre.com  Tue Aug 10 00:48:34 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:48:34 +0200
Subject: [PATCH] arm64: dts: meson: add audio playback to nexbox-a1
In-Reply-To: <20210804140029.4445-1-christianshewitt@gmail.com>
References: <20210804140029.4445-1-christianshewitt@gmail.com>
Message-ID: <7f060ba5-139a-3656-53ac-0ecef37ac496@baylibre.com>

On 04/08/2021 16:00, Christian Hewitt wrote:
> Add initial support limited to HDMI i2s and SPDIF (LPCM).
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  .../boot/dts/amlogic/meson-gxm-nexbox-a1.dts  | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
> index dfa7a37a1281..236c0a144142 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
> @@ -10,6 +10,7 @@
>  /dts-v1/;
>  
>  #include "meson-gxm.dtsi"
> +#include <dt-bindings/sound/meson-aiu.h>
>  
>  / {
>  	compatible = "nexbox,a1", "amlogic,s912", "amlogic,meson-gxm";
> @@ -24,6 +25,13 @@
>  		stdout-path = "serial0:115200n8";
>  	};
>  
> +	spdif_dit: audio-codec-0 {
> +		#sound-dai-cells = <0>;
> +		compatible = "linux,spdif-dit";
> +		status = "okay";
> +		sound-name-prefix = "DIT";
> +	};
> +
>  	memory at 0 {
>  		device_type = "memory";
>  		reg = <0x0 0x0 0x0 0x80000000>;
> @@ -75,6 +83,59 @@
>  			};
>  		};
>  	};
> +
> +	sound {
> +		compatible = "amlogic,gx-sound-card";
> +		model = "NEXBOX-A1";
> +		assigned-clocks = <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>,
> +				  <&clkc CLKID_MPLL2>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
> +			dai-format = "i2s";
> +			mclk-fs = <256>;
> +
> +			codec-0 {
> +				sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
> +			};
> +		};
> +
> +		dai-link-3 {
> +			sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
> +
> +			codec-0 {
> +				sound-dai = <&spdif_dit>;
> +			};
> +		};
> +
> +		dai-link-4 {
> +			sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
> +
> +			codec-0 {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&aiu {
> +	status = "okay";
> +	pinctrl-0 = <&spdif_out_h_pins>;
> +	pinctrl-names = "default";
>  };
>  
>  &cec_AO {
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Tue Aug 10 00:48:41 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:48:41 +0200
Subject: [PATCH] arm64: dts: meson: add audio playback to vega-s95 dtsi
In-Reply-To: <20210804140258.4666-1-christianshewitt@gmail.com>
References: <20210804140258.4666-1-christianshewitt@gmail.com>
Message-ID: <fb7e150d-cbb4-8631-9ae8-aced75c6aa09@baylibre.com>

On 04/08/2021 16:02, Christian Hewitt wrote:
> Add initial support limited to HDMI i2s and SPDIF (LPCM).
> 
> Tested-by: Oleg Ivanov <150balbes at yandex.ru>
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
> index 9b0b81f191f1..66daf3af34c3 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
> @@ -4,6 +4,7 @@
>   */
>  
>  #include "meson-gxbb.dtsi"
> +#include <dt-bindings/sound/meson-aiu.h>
>  
>  / {
>  	compatible = "tronsmart,vega-s95", "amlogic,meson-gxbb";
> @@ -17,6 +18,13 @@
>  		stdout-path = "serial0:115200n8";
>  	};
>  
> +	spdif_dit: audio-codec-0 {
> +		#sound-dai-cells = <0>;
> +		compatible = "linux,spdif-dit";
> +		status = "okay";
> +		sound-name-prefix = "DIT";
> +	};
> +
>  	leds {
>  		compatible = "gpio-leds";
>  
> @@ -97,6 +105,59 @@
>  		clocks = <&wifi32k>;
>  		clock-names = "ext_clock";
>  	};
> +
> +	sound {
> +		compatible = "amlogic,gx-sound-card";
> +		model = "VEGA-S95";
> +		assigned-clocks = <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>,
> +				  <&clkc CLKID_MPLL2>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&aiu AIU_CPU CPU_SPDIF_FIFO>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
> +			dai-format = "i2s";
> +			mclk-fs = <256>;
> +
> +			codec-0 {
> +				sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
> +			};
> +		};
> +
> +		dai-link-3 {
> +			sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
> +
> +			codec-0 {
> +				sound-dai = <&spdif_dit>;
> +			};
> +		};
> +
> +		dai-link-4 {
> +			sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
> +
> +			codec-0 {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&aiu {
> +	status = "okay";
> +	pinctrl-0 = <&spdif_out_y_pins>;
> +	pinctrl-names = "default";
>  };
>  
>  &cec_AO {
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Tue Aug 10 00:55:19 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:55:19 +0200
Subject: [PATCH 1/2] arm64: dts: meson: add spdif out to khadas-vim
In-Reply-To: <20210810041630.3673406-1-art@khadas.com>
References: <20210810041630.3673406-1-art@khadas.com>
Message-ID: <7dbba936-e8ab-4d47-1af8-0d3d1adb8c30@baylibre.com>

Hi,

On 10/08/2021 06:16, Artem Lapkin wrote:
> Add spdif output audio support to khadas-vim
> 
> Signed-off-by: Artem Lapkin <art at khadas.com>
> ---
>  .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts  | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> index 60feac0179c0..01f13822a616 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> @@ -64,6 +64,13 @@ hdmi_connector_in: endpoint {
>  		};
>  	};
>  
> +	spdif_dit: audio-codec-0 {
> +		#sound-dai-cells = <0>;
> +		compatible = "linux,spdif-dit";
> +		status = "okay";
> +		sound-name-prefix = "DIT";
> +	};
> +
>  	sound {
>  		compatible = "amlogic,gx-sound-card";
>  		model = "KHADAS-VIM";
> @@ -97,11 +104,21 @@ codec-0 {
>  				sound-dai = <&hdmi_tx>;
>  			};
>  		};
> +
> +		dai-link-3 {
> +			sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
> +
> +			codec-0 {
> +				sound-dai = <&spdif_dit>;
> +			};
> +		};
>  	};
>  };
>  
>  &aiu {
>  	status = "okay";
> +	pinctrl-0 = <&spdif_out_h_pins>;
> +	pinctrl-names = "default";
>  };
>  
>  &cec_AO {
> 

AFAIK the board doesn't have a physical SPDIF output, but one of the 40pin header can output SPDIF, right ?

In this case, following the other boards mainline definitions, we do not enable any function by default
for pins on the 40pin (or other programmable) headers.

There is still ongoing discussions on how to handle that on a more generic level, but you should write a bunch
of DT overlays for the VIM boards to enable optional functions like SPDIF and store then in a public git
tree for everybody to use (like armbian or LibreELEC for example) from the U-Boot stage.

Neil


From s.nawrocki at samsung.com  Tue Aug 10 00:55:37 2021
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Tue, 10 Aug 2021 09:55:37 +0200
Subject: [PATCH v2 7/8] clk: samsung: Add Exynos850 clock driver stub
In-Reply-To: <CAPLW+4=-uUcoLCjjBAC2K5NLswnXGXW1qrsTJrb_uZDgOQ5Ehw@mail.gmail.com>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-8-semen.protsenko@linaro.org>
 <3add6f87-7293-e1ae-8f9e-c69e9de18cf5@canonical.com>
 <CGME20210809194915eucas1p19999295aef3127f95ffe4c75a8acc63f@eucas1p1.samsung.com>
 <CAPLW+4=-uUcoLCjjBAC2K5NLswnXGXW1qrsTJrb_uZDgOQ5Ehw@mail.gmail.com>
Message-ID: <bb69e79d-55a8-2090-e51c-fdfea755cf99@samsung.com>

On 09.08.2021 21:48, Sam Protsenko wrote:
>>> +/* Will be extracted to bindings header once proper clk driver is implemented */
>>> +#define OSCCLK               1
>>> +#define DOUT_UART    2
>>> +#define CLK_NR_CLKS  3
>>> +
>>> +/* Fixed rate clocks generated outside the SoC */
>>> +static struct samsung_fixed_rate_clock exynos850_fixed_rate_ext_clks[] __initdata = {
>>> +     FRATE(OSCCLK, "fin_pll", NULL, 0, 26000000),
>>> +};
>>> +
>>> +/*
>>> + * Model the UART clock as a fixed-rate clock for now, to make serial driver
>>> + * work. This clock is already configured in the bootloader.
>>> + */
>>> +static const struct samsung_fixed_rate_clock exynos850_peri_clks[] __initconst = {
>>> +     FRATE(DOUT_UART, "DOUT_UART", NULL, 0, 200000000),
>>> +};
>>> +
>>> +static const struct of_device_id ext_clk_match[] __initconst = {
>>> +     { .compatible = "samsung,exynos850-oscclk" },
>>
>> One more thing - I am not sure anymore if this is correct. AFAIR, we
>> wanted to drop compatibles for external clocks.
>>
> I'll remove oscclk from the clock driver and device tree. It's not
> needed right now anyway, as that driver is just a stub.
> 
> But I'd still like to know the proper way to define external clocks. I
> can see that in exynos7.dtsi and exynos5433.dtsi there is just regular
> fixed clock defined for "oscclk" (or "fin_pll"), and then that clock
> is referenced in corresponding clock driver by its
> 'clock-output-names' property. I guess that approach is the
> recommended one?

Yes, we should use generic "fixed-clock" in DT to model the external
root clock. Registering the external clock from within the CMU driver
is a legacy method that predates generic "fixed-clock" and should be
avoided.  

That said I think this temporary stub driver is not needed at all, 
you could well define a fixed clock in DT and reference it in the UART 
node, as Krzysztof suggested.

--
Regards, 
Sylwester


From narmstrong at baylibre.com  Tue Aug 10 00:56:26 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:56:26 +0200
Subject: [PATCH] drm/meson: fix colour distortion from HDR set during
 vendor u-boot
In-Reply-To: <20210806094005.7136-1-christianshewitt@gmail.com>
References: <20210806094005.7136-1-christianshewitt@gmail.com>
Message-ID: <75c870f1-af7c-88ac-9884-43cc62b22411@baylibre.com>

Hi Christian,

On 06/08/2021 11:40, Christian Hewitt wrote:
> Add support for the OSD1 HDR registers so meson DRM can handle the HDR
> properties set by Amlogic u-boot on G12A and newer devices which result
> in blue/green/pink colour distortion to display output.
> 
> This takes the original patch submissions from Mathias [0] and [1] with
> corrections for formatting and the missing description and attribution
> needed for merge.
> 
> [0] https://lore.kernel.org/linux-amlogic/59dfd7e6-fc91-3d61-04c4-94e078a3188c at baylibre.com/T/
> [1] https://lore.kernel.org/linux-amlogic/CAOKfEHBx_fboUqkENEMd-OC-NSrf46nto+vDLgvgttzPe99kXg at mail.gmail.com/T/#u
> 
> Fixes: 728883948b0d ("drm/meson: Add G12A Support for VIU setup")
> Suggested-by: Mathias Steiger <mathias.steiger at googlemail.com>
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> Tested-by: Neil Armstrong<narmstrong at baylibre.com>
> Tested-by: Philip Milev <milev.philip at gmail.com>
> ---
>  drivers/gpu/drm/meson/meson_registers.h | 5 +++++
>  drivers/gpu/drm/meson/meson_viu.c       | 7 ++++++-
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
> index 446e7961da48..0f3cafab8860 100644
> --- a/drivers/gpu/drm/meson/meson_registers.h
> +++ b/drivers/gpu/drm/meson/meson_registers.h
> @@ -634,6 +634,11 @@
>  #define VPP_WRAP_OSD3_MATRIX_PRE_OFFSET2 0x3dbc
>  #define VPP_WRAP_OSD3_MATRIX_EN_CTRL 0x3dbd
>  
> +/* osd1 HDR */
> +#define OSD1_HDR2_CTRL 0x38a0
> +#define OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN       BIT(13)
> +#define OSD1_HDR2_CTRL_REG_ONLY_MAT            BIT(16)
> +
>  /* osd2 scaler */
>  #define OSD2_VSC_PHASE_STEP 0x3d00
>  #define OSD2_VSC_INI_PHASE 0x3d01
> diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
> index aede0c67a57f..259f3e6bec90 100644
> --- a/drivers/gpu/drm/meson/meson_viu.c
> +++ b/drivers/gpu/drm/meson/meson_viu.c
> @@ -425,9 +425,14 @@ void meson_viu_init(struct meson_drm *priv)
>  	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
>  	    meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
>  		meson_viu_load_matrix(priv);
> -	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
> +	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
>  		meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff,
>  					       true);
> +		/* fix green/pink color distortion from vendor u-boot */
> +		writel_bits_relaxed(OSD1_HDR2_CTRL_REG_ONLY_MAT |
> +				OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN, 0,
> +				priv->io_base + _REG(OSD1_HDR2_CTRL));
> +	}
>  
>  	/* Initialize OSD1 fifo control register */
>  	reg = VIU_OSD_DDR_PRIORITY_URGENT |
> 

Thanks for taking time to re-submit this patch,
Applying to drm-misc-fixes

Neil


From lee.jones at linaro.org  Tue Aug 10 00:58:14 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 10 Aug 2021 08:58:14 +0100
Subject: [PATCH 1/3] arch: Export machine_restart() instances so they can
 be called from modules
In-Reply-To: <CAMuHMdXpYV+pbiOwiCjZ+aZYR-xPDGkeANfLt0fwhg4zevAKgg@mail.gmail.com>
References: <20210803155452.435812-1-lee.jones@linaro.org>
 <20210803155452.435812-2-lee.jones@linaro.org>
 <CAMuHMdXpYV+pbiOwiCjZ+aZYR-xPDGkeANfLt0fwhg4zevAKgg@mail.gmail.com>
Message-ID: <YRIxluiYdZo9OOAn@google.com>

On Mon, 09 Aug 2021, Geert Uytterhoeven wrote:

> On Tue, Aug 3, 2021 at 5:56 PM Lee Jones <lee.jones at linaro.org> wrote:
> > A recent attempt to convert the Power Reset Restart driver to tristate
> > failed because of the following compile error (reported once merged by
> > Stephen Rothwell via Linux Next):
> >
> >   ERROR: "machine_restart" [drivers/power/reset/restart-poweroff.ko] undefined!
> >
> > This error occurs since some of the machine_restart() instances are
> > not currently exported for use in modules.  This patch aims to rectify
> > that.
> >
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> 
> > NB: If it's safe to omit some of these, let me know and I'll revise the patch.
> 
> How do you plan to handle that? Isn't this an all-or-nothing export?

That's the way I see it, but I don't have an in-depth knowledge of all
of the architectures.  There may be a method there that isn't part of
the core API.  If that's the case, I can drop the export.

> >  arch/m68k/kernel/process.c         | 1 +
> 
> Acked-by: Geert Uytterhoeven <geert at linux-m68k.org>

Thanks Geert.

I'll pick this up when I do the re-spin shortly.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From hsinyi at chromium.org  Tue Aug 10 00:57:57 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Tue, 10 Aug 2021 15:57:57 +0800
Subject: [PATCH v3 0/2] arm64: dts: mt8183: Add kukui platform audio node
 to the device tree
In-Reply-To: <20210706100136.1205047-1-kansho@chromium.org>
References: <20210706100136.1205047-1-kansho@chromium.org>
Message-ID: <CAJMQK-jDNcDYcMY8tTxyVhbEP0g8z5E+cWc3Cu_gqr4fQaUmoQ@mail.gmail.com>

On Tue, Jul 6, 2021 at 6:01 PM Kansho Nishida <kansho at chromium.org> wrote:
>
>
> Hi Matthias,
>
> This patchset is the v3 patch!
>
> Regards,
> Kansho
>

Tested-by: Hsin-Yi Wang <hsinyi at chromium.org>

Tested on several mt8183 models

>
> Changes in v3:
> - Use audio-controller as the audio node instead.
>
> Changes in v2:
> - Changed to the dual license GPL + MIT.
>
> Kansho Nishida (2):
>   arm64: dts: mt8183: add audio node
>   arm64: dts: mt8183: add kukui platform audio node
>
>  arch/arm64/boot/dts/mediatek/mt6358.dtsi      |  1 +
>  .../mt8183-kukui-audio-da7219-max98357a.dtsi  | 13 +++
>  .../mt8183-kukui-audio-da7219-rt1015p.dtsi    | 13 +++
>  .../mediatek/mt8183-kukui-audio-da7219.dtsi   | 54 +++++++++++
>  .../mt8183-kukui-audio-max98357a.dtsi         | 13 +++
>  .../mediatek/mt8183-kukui-audio-rt1015p.dtsi  | 13 +++
>  ...mt8183-kukui-audio-ts3a227e-max98357a.dtsi | 13 +++
>  .../mt8183-kukui-audio-ts3a227e-rt1015p.dtsi  | 13 +++
>  .../mediatek/mt8183-kukui-audio-ts3a227e.dtsi | 32 +++++++
>  .../mediatek/mt8183-kukui-jacuzzi-burnet.dts  |  1 +
>  .../mediatek/mt8183-kukui-jacuzzi-damu.dts    |  1 +
>  .../mediatek/mt8183-kukui-jacuzzi-fennel.dtsi |  1 +
>  .../mt8183-kukui-jacuzzi-juniper-sku16.dts    |  1 +
>  .../mediatek/mt8183-kukui-jacuzzi-kappa.dts   |  1 +
>  .../mediatek/mt8183-kukui-jacuzzi-kenzo.dts   |  1 +
>  .../mt8183-kukui-jacuzzi-willow-sku0.dts      |  1 +
>  .../mt8183-kukui-jacuzzi-willow-sku1.dts      |  1 +
>  .../boot/dts/mediatek/mt8183-kukui-kakadu.dts |  1 +
>  .../dts/mediatek/mt8183-kukui-kodama.dtsi     |  1 +
>  .../boot/dts/mediatek/mt8183-kukui-krane.dtsi |  5 +
>  .../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 67 ++++++++++++-
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi      | 94 ++++++++++++++++++-
>  22 files changed, 336 insertions(+), 5 deletions(-)
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-max98357a.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-rt1015p.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-max98357a.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-rt1015p.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-max98357a.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-rt1015p.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e.dtsi
>
> --
> 2.32.0.93.g670b81a890-goog
>
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From narmstrong at baylibre.com  Tue Aug 10 00:58:34 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:58:34 +0200
Subject: [PATCH] arm64: dts: meson: add audio playback to nexbox-a1
In-Reply-To: <20210804140029.4445-1-christianshewitt@gmail.com>
References: <20210804140029.4445-1-christianshewitt@gmail.com>
Message-ID: <162858223387.1486110.3448385617438726477.b4-ty@baylibre.com>

Hi,

On Wed, 4 Aug 2021 14:00:29 +0000, Christian Hewitt wrote:
> Add initial support limited to HDMI i2s and SPDIF (LPCM).

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.15/dt64)

[1/1] arm64: dts: meson: add audio playback to nexbox-a1
      https://git.kernel.org/amlogic/c/c7f5675b345224f212a0006c73a643182e953a5f

-- 
Neil


From narmstrong at baylibre.com  Tue Aug 10 00:58:35 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 09:58:35 +0200
Subject: [PATCH] arm64: dts: meson: add audio playback to vega-s95 dtsi
In-Reply-To: <20210804140258.4666-1-christianshewitt@gmail.com>
References: <20210804140258.4666-1-christianshewitt@gmail.com>
Message-ID: <162858223387.1486110.6330831652699678995.b4-ty@baylibre.com>

Hi,

On Wed, 4 Aug 2021 14:02:58 +0000, Christian Hewitt wrote:
> Add initial support limited to HDMI i2s and SPDIF (LPCM).

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.15/dt64)

[1/1] arm64: dts: meson: add audio playback to vega-s95 dtsi
      https://git.kernel.org/amlogic/c/c6cf488e3bfdf92427686317d99e0342516753de

-- 
Neil


From maz at kernel.org  Tue Aug 10 00:59:03 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 08:59:03 +0100
Subject: [PATCH 13/13] arm64: Add CNT{P, V}CTSS_EL0 alternatives to cnt{p,
 v}ct_el0
In-Reply-To: <CAOQ_Qsh6h_afu_-WjJ2JTP=gYBYW4hbC92qmxzyJ8dgRCCgLKw@mail.gmail.com>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-14-maz@kernel.org>
 <CAOQ_QshjRWh=onT-j3dWgmVfnAXsMFJoz0i7OEezQxkW4O9KZA@mail.gmail.com>
 <87im0ebi9m.wl-maz@kernel.org>
 <CAOQ_Qsh6h_afu_-WjJ2JTP=gYBYW4hbC92qmxzyJ8dgRCCgLKw@mail.gmail.com>
Message-ID: <87h7fxbuig.wl-maz@kernel.org>

On Mon, 09 Aug 2021 19:17:38 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Mon, Aug 9, 2021 at 11:11 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Mon, 09 Aug 2021 17:42:00 +0100,
> > Oliver Upton <oupton at google.com> wrote:
> > >
> > > On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > CNTPCTSS_EL0 and CNTVCTSS_EL0 are alternatives to the usual
> > > > CNTPCT_EL0 and CNTVCT_EL0 that do not require a previous ISB
> > > > to be synchronised (SS stands for Self-Synchronising).
> > > >
> > > > Use the ARM64_HAS_ECV capability to control alternative sequences
> > > > that switch to these low(er)-cost primitives. Note that the
> > > > counter access in the VDSO is for now left alone until we decide
> > > > whether we want to allow this.
> > >
> > > What remains to be figured out before we add this to the vDSO (and
> > > presumably advertise to userspace through some standard convention)?
> >
> > We need to understand what breaks if we runtime-patch the VDSO just
> > like we do with the rest of the kernel. To start with, the debug
> > version of the shared object is not the same as the object presented
> > to the process. Maybe that's not a problem, but I would tend to err on
> > the side of caution.
> 
> I would too, but there sadly are instances of Linux patching *user*
> memory already (go look at how KVM/x86 handles the VMCALL/VMMCALL
> instruction). But yes, I would much prefer the debug vDSO correspond
> to the actual instructions.

Urghhh... This reminds me of

https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?h=arm/netwinder&id=72797818a31d37a7ec28db659afcab0a56d47968

which I never tried to get merged for this exact reason. I'd rather
not replicate this sort of braindamage^Wthing if I can avoid it.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From yong.wu at mediatek.com  Tue Aug 10 01:08:47 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:47 +0800
Subject: [PATCH v3 01/13] dt-bindings: memory: mediatek: Add mt8195 smi binding
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-2-yong.wu@mediatek.com>

Add mt8195 smi supporting in the bindings.

In mt8195, there are two smi-common HW, one is for vdo(video output),
the other is for vpp(video processing pipe). They connect with different
smi-larbs, then some setting(bus_sel) is different. Differentiate them
with the compatible string.

Something like this:

    IOMMU(VDO)          IOMMU(VPP)
       |                   |
 SMI_COMMON_VDO      SMI_COMMON_VPP
 ----------------     ----------------
  |      |   ...      |      |     ...
larb0 larb2  ...    larb1 larb3    ...

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 .../bindings/memory-controllers/mediatek,smi-common.yaml    | 6 +++++-
 .../bindings/memory-controllers/mediatek,smi-larb.yaml      | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
index e87e4382807c..602592b6c3f5 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
@@ -16,7 +16,7 @@ description: |
   MediaTek SMI have two generations of HW architecture, here is the list
   which generation the SoCs use:
   generation 1: mt2701 and mt7623.
-  generation 2: mt2712, mt6779, mt8167, mt8173, mt8183 and mt8192.
+  generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8192 and mt8195.
 
   There's slight differences between the two SMI, for generation 2, the
   register which control the iommu port is at each larb's register base. But
@@ -36,6 +36,8 @@ properties:
           - mediatek,mt8173-smi-common
           - mediatek,mt8183-smi-common
           - mediatek,mt8192-smi-common
+          - mediatek,mt8195-smi-common-vdo
+          - mediatek,mt8195-smi-common-vpp
 
       - description: for mt7623
         items:
@@ -98,6 +100,8 @@ allOf:
             - mediatek,mt6779-smi-common
             - mediatek,mt8183-smi-common
             - mediatek,mt8192-smi-common
+            - mediatek,mt8195-smi-common-vdo
+            - mediatek,mt8195-smi-common-vpp
 
     then:
       properties:
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index 2353f6cf3c80..eaeff1ada7f8 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -24,6 +24,7 @@ properties:
           - mediatek,mt8173-smi-larb
           - mediatek,mt8183-smi-larb
           - mediatek,mt8192-smi-larb
+          - mediatek,mt8195-smi-larb
 
       - description: for mt7623
         items:
@@ -74,6 +75,7 @@ allOf:
         compatible:
           enum:
             - mediatek,mt8183-smi-larb
+            - mediatek,mt8195-smi-larb
 
     then:
       properties:
@@ -108,6 +110,7 @@ allOf:
               - mediatek,mt6779-smi-larb
               - mediatek,mt8167-smi-larb
               - mediatek,mt8192-smi-larb
+              - mediatek,mt8195-smi-larb
 
     then:
       required:
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:49 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:49 +0800
Subject: [PATCH v3 03/13] memory: mtk-smi: Use clk_bulk clock ops
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-4-yong.wu@mediatek.com>

Use clk_bulk interface instead of the orginal one to simplify the code.

For SMI larbs: Require apb/smi clocks while gals is optional.
For SMI common: Require apb/smi/gals0/gal1 in has_gals case. Otherwise,
                also only require apb/smi, No optional clk here.

About the "has_gals" flag, for smi larbs, the gals clock also may be
optional even this platform support it. thus it always use
*_bulk_get_optional, then the flag has_gals is unnecessary. Remove it.
The smi_common's has_gals still keep it.

Also remove clk fail logs since bulk interface already output fail log.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
change note:
still keep smi-common's has_glas flag. it is more strict.
But it did change many code, thus I didn't keep Ikjoon's R-b.
---
 drivers/memory/mtk-smi.c | 143 +++++++++++++++------------------------
 1 file changed, 55 insertions(+), 88 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index c5fb51f73b34..f91eaf5c3ab0 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -60,6 +60,20 @@ enum mtk_smi_gen {
 	MTK_SMI_GEN2
 };
 
+#define MTK_SMI_CLK_NR_MAX			4
+
+/* larbs: Require apb/smi clocks while gals is optional. */
+static const char * const mtk_smi_larb_clks[] = {"apb", "smi", "gals"};
+#define MTK_SMI_LARB_REQ_CLK_NR		2
+#define MTK_SMI_LARB_OPT_CLK_NR		1
+
+/*
+ * common: Require these four clocks in has_gals case. Otherwise, only apb/smi are required.
+ */
+static const char * const mtk_smi_common_clks[] = {"apb", "smi", "gals0", "gals1"};
+#define MTK_SMI_COM_REQ_CLK_NR		2
+#define MTK_SMI_COM_GALS_REQ_CLK_NR	MTK_SMI_CLK_NR_MAX
+
 struct mtk_smi_common_plat {
 	enum mtk_smi_gen gen;
 	bool             has_gals;
@@ -70,13 +84,12 @@ struct mtk_smi_larb_gen {
 	int port_in_larb[MTK_LARB_NR_MAX + 1];
 	void (*config_port)(struct device *dev);
 	unsigned int			larb_direct_to_common_mask;
-	bool				has_gals;
 };
 
 struct mtk_smi {
 	struct device			*dev;
-	struct clk			*clk_apb, *clk_smi;
-	struct clk			*clk_gals0, *clk_gals1;
+	unsigned int			clk_num;
+	struct clk_bulk_data		clks[MTK_SMI_CLK_NR_MAX];
 	struct clk			*clk_async; /*only needed by mt2701*/
 	union {
 		void __iomem		*smi_ao_base; /* only for gen1 */
@@ -95,45 +108,6 @@ struct mtk_smi_larb { /* larb: local arbiter */
 	unsigned char			*bank;
 };
 
-static int mtk_smi_clk_enable(const struct mtk_smi *smi)
-{
-	int ret;
-
-	ret = clk_prepare_enable(smi->clk_apb);
-	if (ret)
-		return ret;
-
-	ret = clk_prepare_enable(smi->clk_smi);
-	if (ret)
-		goto err_disable_apb;
-
-	ret = clk_prepare_enable(smi->clk_gals0);
-	if (ret)
-		goto err_disable_smi;
-
-	ret = clk_prepare_enable(smi->clk_gals1);
-	if (ret)
-		goto err_disable_gals0;
-
-	return 0;
-
-err_disable_gals0:
-	clk_disable_unprepare(smi->clk_gals0);
-err_disable_smi:
-	clk_disable_unprepare(smi->clk_smi);
-err_disable_apb:
-	clk_disable_unprepare(smi->clk_apb);
-	return ret;
-}
-
-static void mtk_smi_clk_disable(const struct mtk_smi *smi)
-{
-	clk_disable_unprepare(smi->clk_gals1);
-	clk_disable_unprepare(smi->clk_gals0);
-	clk_disable_unprepare(smi->clk_smi);
-	clk_disable_unprepare(smi->clk_apb);
-}
-
 int mtk_smi_larb_get(struct device *larbdev)
 {
 	int ret = pm_runtime_resume_and_get(larbdev);
@@ -270,7 +244,6 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt6779 = {
 };
 
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
-	.has_gals                   = true,
 	.config_port                = mtk_smi_larb_config_port_gen2_general,
 	.larb_direct_to_common_mask = BIT(2) | BIT(3) | BIT(7),
 				      /* IPU0 | IPU1 | CCU */
@@ -312,6 +285,27 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
 	{}
 };
 
+static int mtk_smi_dts_clk_init(struct device *dev, struct mtk_smi *smi,
+				const char * const clks[],
+				unsigned int clk_nr_required,
+				unsigned int clk_nr_optional)
+{
+	int i, ret;
+
+	for (i = 0; i < clk_nr_required; i++)
+		smi->clks[i].id = clks[i];
+	ret = devm_clk_bulk_get(dev, clk_nr_required, smi->clks);
+	if (ret)
+		return ret;
+
+	for (i = clk_nr_required; i < clk_nr_required + clk_nr_optional; i++)
+		smi->clks[i].id = clks[i];
+	ret = devm_clk_bulk_get_optional(dev, clk_nr_optional,
+					 smi->clks + clk_nr_required);
+	smi->clk_num = clk_nr_required + clk_nr_optional;
+	return ret;
+}
+
 static int mtk_smi_larb_probe(struct platform_device *pdev)
 {
 	struct mtk_smi_larb *larb;
@@ -320,6 +314,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
 	struct device_node *smi_node;
 	struct platform_device *smi_pdev;
 	struct device_link *link;
+	int ret;
 
 	larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
 	if (!larb)
@@ -331,24 +326,12 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
 	if (IS_ERR(larb->base))
 		return PTR_ERR(larb->base);
 
-	larb->smi.clk_apb = devm_clk_get(dev, "apb");
-	if (IS_ERR(larb->smi.clk_apb))
-		return PTR_ERR(larb->smi.clk_apb);
-
-	larb->smi.clk_smi = devm_clk_get(dev, "smi");
-	if (IS_ERR(larb->smi.clk_smi))
-		return PTR_ERR(larb->smi.clk_smi);
-
-	if (larb->larb_gen->has_gals) {
-		/* The larbs may still haven't gals even if the SoC support.*/
-		larb->smi.clk_gals0 = devm_clk_get(dev, "gals");
-		if (PTR_ERR(larb->smi.clk_gals0) == -ENOENT)
-			larb->smi.clk_gals0 = NULL;
-		else if (IS_ERR(larb->smi.clk_gals0))
-			return PTR_ERR(larb->smi.clk_gals0);
-	}
-	larb->smi.dev = dev;
+	ret = mtk_smi_dts_clk_init(dev, &larb->smi, mtk_smi_larb_clks,
+				   MTK_SMI_LARB_REQ_CLK_NR, MTK_SMI_LARB_OPT_CLK_NR);
+	if (ret)
+		return ret;
 
+	larb->smi.dev = dev;
 	smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
 	if (!smi_node)
 		return -EINVAL;
@@ -391,11 +374,9 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
 	const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
 	int ret;
 
-	ret = mtk_smi_clk_enable(&larb->smi);
-	if (ret < 0) {
-		dev_err(dev, "Failed to enable clock(%d).\n", ret);
+	ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
+	if (ret < 0)
 		return ret;
-	}
 
 	/* Configure the basic setting for this larb */
 	larb_gen->config_port(dev);
@@ -407,7 +388,7 @@ static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
 {
 	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
 
-	mtk_smi_clk_disable(&larb->smi);
+	clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);
 	return 0;
 }
 
@@ -493,7 +474,7 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct mtk_smi *common;
 	struct resource *res;
-	int ret;
+	int ret, clk_required = MTK_SMI_COM_REQ_CLK_NR;
 
 	common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
 	if (!common)
@@ -501,23 +482,11 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 	common->dev = dev;
 	common->plat = of_device_get_match_data(dev);
 
-	common->clk_apb = devm_clk_get(dev, "apb");
-	if (IS_ERR(common->clk_apb))
-		return PTR_ERR(common->clk_apb);
-
-	common->clk_smi = devm_clk_get(dev, "smi");
-	if (IS_ERR(common->clk_smi))
-		return PTR_ERR(common->clk_smi);
-
-	if (common->plat->has_gals) {
-		common->clk_gals0 = devm_clk_get(dev, "gals0");
-		if (IS_ERR(common->clk_gals0))
-			return PTR_ERR(common->clk_gals0);
-
-		common->clk_gals1 = devm_clk_get(dev, "gals1");
-		if (IS_ERR(common->clk_gals1))
-			return PTR_ERR(common->clk_gals1);
-	}
+	if (common->plat->has_gals)
+		clk_required = MTK_SMI_COM_GALS_REQ_CLK_NR;
+	ret = mtk_smi_dts_clk_init(dev, common, mtk_smi_common_clks, clk_required, 0);
+	if (ret)
+		return ret;
 
 	/*
 	 * for mtk smi gen 1, we need to get the ao(always on) base to config
@@ -561,11 +530,9 @@ static int __maybe_unused mtk_smi_common_resume(struct device *dev)
 	u32 bus_sel = common->plat->bus_sel;
 	int ret;
 
-	ret = mtk_smi_clk_enable(common);
-	if (ret) {
-		dev_err(common->dev, "Failed to enable clock(%d).\n", ret);
+	ret = clk_bulk_prepare_enable(common->clk_num, common->clks);
+	if (ret)
 		return ret;
-	}
 
 	if (common->plat->gen == MTK_SMI_GEN2 && bus_sel)
 		writel(bus_sel, common->base + SMI_BUS_SEL);
@@ -576,7 +543,7 @@ static int __maybe_unused mtk_smi_common_suspend(struct device *dev)
 {
 	struct mtk_smi *common = dev_get_drvdata(dev);
 
-	mtk_smi_clk_disable(common);
+	clk_bulk_disable_unprepare(common->clk_num, common->clks);
 	return 0;
 }
 
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:51 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:51 +0800
Subject: [PATCH v3 05/13] memory: mtk-smi: Adjust some code position
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-6-yong.wu@mediatek.com>

No functional change. Only move the code position to make the code more
readable.
1. Put the register smi-common above smi-larb. Prepare to add some others
   register setting.
2. Put mtk_smi_larb_unbind around larb_bind.
3. Sort the SoC data alphabetically. and put them in one line as the
   current kernel allow it.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Ikjoon Jang <ikjn at chromium.org>
---
 drivers/memory/mtk-smi.c | 188 ++++++++++++++++-----------------------
 1 file changed, 75 insertions(+), 113 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 02a584dfb9b1..33b6c5efe102 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -17,13 +17,16 @@
 #include <dt-bindings/memory/mt2701-larb-port.h>
 #include <dt-bindings/memory/mtk-memory-port.h>
 
-/* mt8173 */
-#define SMI_LARB_MMU_EN		0xf00
+/* SMI COMMON */
+#define SMI_BUS_SEL			0x220
+#define SMI_BUS_LARB_SHIFT(larbid)	((larbid) << 1)
+/* All are MMU0 defaultly. Only specialize mmu1 here. */
+#define F_MMU1_LARB(larbid)		(0x1 << SMI_BUS_LARB_SHIFT(larbid))
 
-/* mt8167 */
-#define MT8167_SMI_LARB_MMU_EN	0xfc0
+/* SMI LARB */
 
-/* mt2701 */
+/* Below are about mmu enable registers, they are different in SoCs */
+/* gen1: mt2701 */
 #define REG_SMI_SECUR_CON_BASE		0x5c0
 
 /* every register control 8 port, register offset 0x4 */
@@ -41,20 +44,21 @@
 /* mt2701 domain should be set to 3 */
 #define SMI_SECUR_CON_VAL_DOMAIN(id)	(0x3 << ((((id) & 0x7) << 2) + 1))
 
-/* mt2712 */
-#define SMI_LARB_NONSEC_CON(id)	(0x380 + ((id) * 4))
-#define F_MMU_EN		BIT(0)
-#define BANK_SEL(id)		({			\
+/* gen2: */
+/* mt8167 */
+#define MT8167_SMI_LARB_MMU_EN		0xfc0
+
+/* mt8173 */
+#define MT8173_SMI_LARB_MMU_EN		0xf00
+
+/* general */
+#define SMI_LARB_NONSEC_CON(id)		(0x380 + ((id) * 4))
+#define F_MMU_EN			BIT(0)
+#define BANK_SEL(id)			({		\
 	u32 _id = (id) & 0x3;				\
 	(_id << 8 | _id << 10 | _id << 12 | _id << 14);	\
 })
 
-/* SMI COMMON */
-#define SMI_BUS_SEL			0x220
-#define SMI_BUS_LARB_SHIFT(larbid)	((larbid) << 1)
-/* All are MMU0 defaultly. Only specialize mmu1 here. */
-#define F_MMU1_LARB(larbid)		(0x1 << SMI_BUS_LARB_SHIFT(larbid))
-
 enum mtk_smi_type {
 	MTK_SMI_GEN1,
 	MTK_SMI_GEN2
@@ -140,36 +144,16 @@ mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
 	return -ENODEV;
 }
 
-static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
-{
-	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
-	u32 reg;
-	int i;
-
-	if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
-		return;
-
-	for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
-		reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
-		reg |= F_MMU_EN;
-		reg |= BANK_SEL(larb->bank[i]);
-		writel(reg, larb->base + SMI_LARB_NONSEC_CON(i));
-	}
-}
-
-static void mtk_smi_larb_config_port_mt8173(struct device *dev)
+static void
+mtk_smi_larb_unbind(struct device *dev, struct device *master, void *data)
 {
-	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
-
-	writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
+	/* Do nothing as the iommu is always enabled. */
 }
 
-static void mtk_smi_larb_config_port_mt8167(struct device *dev)
-{
-	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
-
-	writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN);
-}
+static const struct component_ops mtk_smi_larb_component_ops = {
+	.bind = mtk_smi_larb_bind,
+	.unbind = mtk_smi_larb_unbind,
+};
 
 static void mtk_smi_larb_config_port_gen1(struct device *dev)
 {
@@ -202,26 +186,36 @@ static void mtk_smi_larb_config_port_gen1(struct device *dev)
 	}
 }
 
-static void
-mtk_smi_larb_unbind(struct device *dev, struct device *master, void *data)
+static void mtk_smi_larb_config_port_mt8167(struct device *dev)
 {
-	/* Do nothing as the iommu is always enabled. */
+	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+
+	writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN);
 }
 
-static const struct component_ops mtk_smi_larb_component_ops = {
-	.bind = mtk_smi_larb_bind,
-	.unbind = mtk_smi_larb_unbind,
-};
+static void mtk_smi_larb_config_port_mt8173(struct device *dev)
+{
+	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
 
-static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = {
-	/* mt8173 do not need the port in larb */
-	.config_port = mtk_smi_larb_config_port_mt8173,
-};
+	writel(*larb->mmu, larb->base + MT8173_SMI_LARB_MMU_EN);
+}
 
-static const struct mtk_smi_larb_gen mtk_smi_larb_mt8167 = {
-	/* mt8167 do not need the port in larb */
-	.config_port = mtk_smi_larb_config_port_mt8167,
-};
+static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
+{
+	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+	u32 reg;
+	int i;
+
+	if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
+		return;
+
+	for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
+		reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
+		reg |= F_MMU_EN;
+		reg |= BANK_SEL(larb->bank[i]);
+		writel(reg, larb->base + SMI_LARB_NONSEC_CON(i));
+	}
+}
 
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
 	.port_in_larb = {
@@ -243,6 +237,16 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt6779 = {
 		/* DUMMY | IPU0 | IPU1 | CCU | MDLA */
 };
 
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8167 = {
+	/* mt8167 do not need the port in larb */
+	.config_port = mtk_smi_larb_config_port_mt8167,
+};
+
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = {
+	/* mt8173 do not need the port in larb */
+	.config_port = mtk_smi_larb_config_port_mt8173,
+};
+
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
 	.config_port                = mtk_smi_larb_config_port_gen2_general,
 	.larb_direct_to_common_mask = BIT(2) | BIT(3) | BIT(7),
@@ -254,34 +258,13 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
 };
 
 static const struct of_device_id mtk_smi_larb_of_ids[] = {
-	{
-		.compatible = "mediatek,mt8167-smi-larb",
-		.data = &mtk_smi_larb_mt8167
-	},
-	{
-		.compatible = "mediatek,mt8173-smi-larb",
-		.data = &mtk_smi_larb_mt8173
-	},
-	{
-		.compatible = "mediatek,mt2701-smi-larb",
-		.data = &mtk_smi_larb_mt2701
-	},
-	{
-		.compatible = "mediatek,mt2712-smi-larb",
-		.data = &mtk_smi_larb_mt2712
-	},
-	{
-		.compatible = "mediatek,mt6779-smi-larb",
-		.data = &mtk_smi_larb_mt6779
-	},
-	{
-		.compatible = "mediatek,mt8183-smi-larb",
-		.data = &mtk_smi_larb_mt8183
-	},
-	{
-		.compatible = "mediatek,mt8192-smi-larb",
-		.data = &mtk_smi_larb_mt8192
-	},
+	{.compatible = "mediatek,mt2701-smi-larb", .data = &mtk_smi_larb_mt2701},
+	{.compatible = "mediatek,mt2712-smi-larb", .data = &mtk_smi_larb_mt2712},
+	{.compatible = "mediatek,mt6779-smi-larb", .data = &mtk_smi_larb_mt6779},
+	{.compatible = "mediatek,mt8167-smi-larb", .data = &mtk_smi_larb_mt8167},
+	{.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},
+	{.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
+	{.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
 	{}
 };
 
@@ -438,34 +421,13 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
 };
 
 static const struct of_device_id mtk_smi_common_of_ids[] = {
-	{
-		.compatible = "mediatek,mt8173-smi-common",
-		.data = &mtk_smi_common_gen2,
-	},
-	{
-		.compatible = "mediatek,mt8167-smi-common",
-		.data = &mtk_smi_common_gen2,
-	},
-	{
-		.compatible = "mediatek,mt2701-smi-common",
-		.data = &mtk_smi_common_gen1,
-	},
-	{
-		.compatible = "mediatek,mt2712-smi-common",
-		.data = &mtk_smi_common_gen2,
-	},
-	{
-		.compatible = "mediatek,mt6779-smi-common",
-		.data = &mtk_smi_common_mt6779,
-	},
-	{
-		.compatible = "mediatek,mt8183-smi-common",
-		.data = &mtk_smi_common_mt8183,
-	},
-	{
-		.compatible = "mediatek,mt8192-smi-common",
-		.data = &mtk_smi_common_mt8192,
-	},
+	{.compatible = "mediatek,mt2701-smi-common", .data = &mtk_smi_common_gen1},
+	{.compatible = "mediatek,mt2712-smi-common", .data = &mtk_smi_common_gen2},
+	{.compatible = "mediatek,mt6779-smi-common", .data = &mtk_smi_common_mt6779},
+	{.compatible = "mediatek,mt8167-smi-common", .data = &mtk_smi_common_gen2},
+	{.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},
+	{.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
+	{.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
 	{}
 };
 
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:52 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:52 +0800
Subject: [PATCH v3 06/13] memory: mtk-smi: Add error handle for smi_probe
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-7-yong.wu@mediatek.com>

Add error handle while component_add fail.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Ikjoon Jang <ikjn at chromium.org>
---
 drivers/memory/mtk-smi.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 33b6c5efe102..b362d528944e 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -338,7 +338,15 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(dev);
 	platform_set_drvdata(pdev, larb);
-	return component_add(dev, &mtk_smi_larb_component_ops);
+	ret = component_add(dev, &mtk_smi_larb_component_ops);
+	if (ret)
+		goto err_pm_disable;
+	return 0;
+
+err_pm_disable:
+	pm_runtime_disable(dev);
+	device_link_remove(dev, larb->smi_common_dev);
+	return ret;
 }
 
 static int mtk_smi_larb_remove(struct platform_device *pdev)
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:53 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:53 +0800
Subject: [PATCH v3 07/13] memory: mtk-smi: Add device link for smi-sub-common
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-8-yong.wu@mediatek.com>

In mt8195, there are some larbs connect with the smi-sub-common, then
connect with smi-common.

Before we create device link between smi-larb with smi-common. If we have
sub-common, we should use device link the smi-larb and smi-sub-common,
then use device link between the smi-sub-common with smi-common. This is
for enabling clock/power automatically.

Move the device link code to a new interface for reusing.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Ikjoon Jang <ikjn at chromium.org>
---
 drivers/memory/mtk-smi.c | 75 +++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 24 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index b362d528944e..5c2bd5795cfd 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -61,7 +61,8 @@
 
 enum mtk_smi_type {
 	MTK_SMI_GEN1,
-	MTK_SMI_GEN2
+	MTK_SMI_GEN2,		/* gen2 smi common */
+	MTK_SMI_GEN2_SUB_COMM,	/* gen2 smi sub common */
 };
 
 #define MTK_SMI_CLK_NR_MAX			4
@@ -99,13 +100,14 @@ struct mtk_smi {
 		void __iomem		*smi_ao_base; /* only for gen1 */
 		void __iomem		*base;	      /* only for gen2 */
 	};
+	struct device			*smi_common_dev; /* for sub common */
 	const struct mtk_smi_common_plat *plat;
 };
 
 struct mtk_smi_larb { /* larb: local arbiter */
 	struct mtk_smi			smi;
 	void __iomem			*base;
-	struct device			*smi_common_dev;
+	struct device			*smi_common_dev; /* common or sub-common dev */
 	const struct mtk_smi_larb_gen	*larb_gen;
 	int				larbid;
 	u32				*mmu;
@@ -268,6 +270,38 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
 	{}
 };
 
+static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev)
+{
+	struct platform_device *smi_com_pdev;
+	struct device_node *smi_com_node;
+	struct device *smi_com_dev;
+	struct device_link *link;
+
+	smi_com_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
+	if (!smi_com_node)
+		return -EINVAL;
+
+	smi_com_pdev = of_find_device_by_node(smi_com_node);
+	of_node_put(smi_com_node);
+	if (smi_com_pdev) {
+		/* smi common is the supplier, Make sure it is ready before */
+		if (!platform_get_drvdata(smi_com_pdev))
+			return -EPROBE_DEFER;
+		smi_com_dev = &smi_com_pdev->dev;
+		link = device_link_add(dev, smi_com_dev,
+				       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+		if (!link) {
+			dev_err(dev, "Unable to link smi-common dev\n");
+			return -ENODEV;
+		}
+		*com_dev = smi_com_dev;
+	} else {
+		dev_err(dev, "Failed to get the smi_common device\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int mtk_smi_dts_clk_init(struct device *dev, struct mtk_smi *smi,
 				const char * const clks[],
 				unsigned int clk_nr_required,
@@ -294,9 +328,6 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
 	struct mtk_smi_larb *larb;
 	struct resource *res;
 	struct device *dev = &pdev->dev;
-	struct device_node *smi_node;
-	struct platform_device *smi_pdev;
-	struct device_link *link;
 	int ret;
 
 	larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
@@ -315,26 +346,10 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
 		return ret;
 
 	larb->smi.dev = dev;
-	smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
-	if (!smi_node)
-		return -EINVAL;
 
-	smi_pdev = of_find_device_by_node(smi_node);
-	of_node_put(smi_node);
-	if (smi_pdev) {
-		if (!platform_get_drvdata(smi_pdev))
-			return -EPROBE_DEFER;
-		larb->smi_common_dev = &smi_pdev->dev;
-		link = device_link_add(dev, larb->smi_common_dev,
-				       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
-		if (!link) {
-			dev_err(dev, "Unable to link smi-common dev\n");
-			return -ENODEV;
-		}
-	} else {
-		dev_err(dev, "Failed to get the smi_common device\n");
-		return -EINVAL;
-	}
+	ret = mtk_smi_device_link_common(dev, &larb->smi_common_dev);
+	if (ret < 0)
+		return ret;
 
 	pm_runtime_enable(dev);
 	platform_set_drvdata(pdev, larb);
@@ -483,6 +498,14 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 		if (IS_ERR(common->base))
 			return PTR_ERR(common->base);
 	}
+
+	/* link its smi-common if this is smi-sub-common */
+	if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) {
+		ret = mtk_smi_device_link_common(dev, &common->smi_common_dev);
+		if (ret < 0)
+			return ret;
+	}
+
 	pm_runtime_enable(dev);
 	platform_set_drvdata(pdev, common);
 	return 0;
@@ -490,6 +513,10 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 
 static int mtk_smi_common_remove(struct platform_device *pdev)
 {
+	struct mtk_smi *common = dev_get_drvdata(&pdev->dev);
+
+	if (common->plat->type == MTK_SMI_GEN2_SUB_COMM)
+		device_link_remove(&pdev->dev, common->smi_common_dev);
 	pm_runtime_disable(&pdev->dev);
 	return 0;
 }
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:54 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:54 +0800
Subject: [PATCH v3 08/13] memory: mtk-smi: Add clocks for smi-sub-common
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-9-yong.wu@mediatek.com>

SMI sub common only have one output port. thus it has only one gals
clocks(gals0). then, smi-sub-common require the three clocks(apb/smi/gals0)
in has_gals case.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/memory/mtk-smi.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 5c2bd5795cfd..58d9f7667490 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -74,10 +74,12 @@ static const char * const mtk_smi_larb_clks[] = {"apb", "smi", "gals"};
 
 /*
  * common: Require these four clocks in has_gals case. Otherwise, only apb/smi are required.
+ * sub common: Require apb/smi/gals0 clocks in has_gals case. Otherwise, only apb/smi are required.
  */
 static const char * const mtk_smi_common_clks[] = {"apb", "smi", "gals0", "gals1"};
 #define MTK_SMI_COM_REQ_CLK_NR		2
 #define MTK_SMI_COM_GALS_REQ_CLK_NR	MTK_SMI_CLK_NR_MAX
+#define MTK_SMI_SUB_COM_GALS_REQ_CLK_NR 3
 
 struct mtk_smi_common_plat {
 	enum mtk_smi_type	type;
@@ -467,8 +469,12 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 	common->dev = dev;
 	common->plat = of_device_get_match_data(dev);
 
-	if (common->plat->has_gals)
-		clk_required = MTK_SMI_COM_GALS_REQ_CLK_NR;
+	if (common->plat->has_gals) {
+		if (common->plat->type == MTK_SMI_GEN2)
+			clk_required = MTK_SMI_COM_GALS_REQ_CLK_NR;
+		else if (common->plat->type == MTK_SMI_GEN2_SUB_COMM)
+			clk_required = MTK_SMI_SUB_COM_GALS_REQ_CLK_NR;
+	}
 	ret = mtk_smi_dts_clk_init(dev, common, mtk_smi_common_clks, clk_required, 0);
 	if (ret)
 		return ret;
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:55 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:55 +0800
Subject: [PATCH v3 09/13] memory: mtk-smi: Use devm_platform_ioremap_resource
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-10-yong.wu@mediatek.com>

No functional change. Simplify probing code.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Ikjoon Jang <ikjn at chromium.org>
---
 drivers/memory/mtk-smi.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 58d9f7667490..a001e41f5074 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -328,7 +328,6 @@ static int mtk_smi_dts_clk_init(struct device *dev, struct mtk_smi *smi,
 static int mtk_smi_larb_probe(struct platform_device *pdev)
 {
 	struct mtk_smi_larb *larb;
-	struct resource *res;
 	struct device *dev = &pdev->dev;
 	int ret;
 
@@ -337,8 +336,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	larb->larb_gen = of_device_get_match_data(dev);
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	larb->base = devm_ioremap_resource(dev, res);
+	larb->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(larb->base))
 		return PTR_ERR(larb->base);
 
@@ -460,7 +458,6 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_smi *common;
-	struct resource *res;
 	int ret, clk_required = MTK_SMI_COM_REQ_CLK_NR;
 
 	common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
@@ -486,8 +483,7 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 	 * base.
 	 */
 	if (common->plat->type == MTK_SMI_GEN1) {
-		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-		common->smi_ao_base = devm_ioremap_resource(dev, res);
+		common->smi_ao_base = devm_platform_ioremap_resource(pdev, 0);
 		if (IS_ERR(common->smi_ao_base))
 			return PTR_ERR(common->smi_ao_base);
 
@@ -499,8 +495,7 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 		if (ret)
 			return ret;
 	} else {
-		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-		common->base = devm_ioremap_resource(dev, res);
+		common->base = devm_platform_ioremap_resource(pdev, 0);
 		if (IS_ERR(common->base))
 			return PTR_ERR(common->base);
 	}
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:56 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:56 +0800
Subject: [PATCH v3 10/13] memory: mtk-smi: mt8195: Add smi support
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-11-yong.wu@mediatek.com>

MT8195 has two smi-common, their IP are the same. Only the larbs that
connect with the smi-common are different. thus the bus_sel are different
for the two smi-common.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Ikjoon Jang <ikjn at chromium.org>
---
 drivers/memory/mtk-smi.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index a001e41f5074..35853ba980c9 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -261,6 +261,10 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
 	.config_port                = mtk_smi_larb_config_port_gen2_general,
 };
 
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = {
+	.config_port                = mtk_smi_larb_config_port_gen2_general,
+};
+
 static const struct of_device_id mtk_smi_larb_of_ids[] = {
 	{.compatible = "mediatek,mt2701-smi-larb", .data = &mtk_smi_larb_mt2701},
 	{.compatible = "mediatek,mt2712-smi-larb", .data = &mtk_smi_larb_mt2712},
@@ -269,6 +273,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
 	{.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},
 	{.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
 	{.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
+	{.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
 	{}
 };
 
@@ -443,6 +448,24 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
 		    F_MMU1_LARB(6),
 };
 
+static const struct mtk_smi_common_plat mtk_smi_common_mt8195_vdo = {
+	.type     = MTK_SMI_GEN2,
+	.has_gals = true,
+	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(3) | F_MMU1_LARB(5) |
+		    F_MMU1_LARB(7),
+};
+
+static const struct mtk_smi_common_plat mtk_smi_common_mt8195_vpp = {
+	.type     = MTK_SMI_GEN2,
+	.has_gals = true,
+	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(7),
+};
+
+static const struct mtk_smi_common_plat mtk_smi_sub_common_mt8195 = {
+	.type     = MTK_SMI_GEN2_SUB_COMM,
+	.has_gals = true,
+};
+
 static const struct of_device_id mtk_smi_common_of_ids[] = {
 	{.compatible = "mediatek,mt2701-smi-common", .data = &mtk_smi_common_gen1},
 	{.compatible = "mediatek,mt2712-smi-common", .data = &mtk_smi_common_gen2},
@@ -451,6 +474,9 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
 	{.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},
 	{.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
 	{.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
+	{.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
+	{.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},
+	{.compatible = "mediatek,mt8195-smi-sub-common", .data = &mtk_smi_sub_common_mt8195},
 	{}
 };
 
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:48 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:48 +0800
Subject: [PATCH v3 02/13] dt-bindings: memory: mediatek: Add mt8195 smi sub
 common
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-3-yong.wu@mediatek.com>

Add the binding for smi-sub-common. The SMI block diagram like this:

        IOMMU
         |  |
      smi-common
  ------------------
  |      ....      |
 larb0           larb7   <-max is 8

The smi-common connects with smi-larb and IOMMU. The maximum larbs number
that connects with a smi-common is 8. If the engines number is over 8,
sometimes we use a smi-sub-common which is nearly same with smi-common.
It supports up to 8 input and 1 output(smi-common has 2 output)

Something like:

        IOMMU
         |  |
      smi-common
  ---------------------
  |      |          ...
larb0  sub-common   ...   <-max is 8
      -----------
       |    |    ...   <-max is 8 too.
     larb2 larb5

We don't need extra SW setting for smi-sub-common, only the sub-common has
special clocks need to enable when the engines access dram.

If it is sub-common, it should have a "mediatek,smi" phandle to point to
its smi-common. meanwhile the sub-common only has one gals clock.

Additionally, add a new property "mediatek,smi_sub_common" for this
sub-common, this is needed in the IOMMU driver in which we create a device
link between smi-common and the IOMMU device. If we add the smi-sub-common
here, the IOMMU driver still need to find the smi-common device. thus,
add this bool property to indicate if it is sub-common.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
change note:
a. change mediatek, smi type from phandle-array to phandle from Rob.
b. Add a new bool property (mediatek,smi_sub_common) to indicate this is
   smi-sub-common. the reason is as above.
---
 .../mediatek,smi-common.yaml                  | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
index 602592b6c3f5..26bb9903864b 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
@@ -38,6 +38,7 @@ properties:
           - mediatek,mt8192-smi-common
           - mediatek,mt8195-smi-common-vdo
           - mediatek,mt8195-smi-common-vpp
+          - mediatek,mt8195-smi-sub-common
 
       - description: for mt7623
         items:
@@ -67,6 +68,14 @@ properties:
     minItems: 2
     maxItems: 4
 
+  mediatek,smi:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: a phandle to the smi-common node above. Only for sub-common.
+
+  mediatek,smi_sub_common:
+    type: boolean
+    description: Indicate if this is smi-sub-common.
+
 required:
   - compatible
   - reg
@@ -93,6 +102,27 @@ allOf:
             - const: smi
             - const: async
 
+  - if:  # only for sub common
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8195-smi-sub-common
+    then:
+      required:
+        - mediatek,smi
+        - mediatek,smi_sub_common
+      properties:
+        clock:
+          items:
+            minItems: 3
+            maxItems: 3
+        clock-names:
+          items:
+            - const: apb
+            - const: smi
+            - const: gals0
+
   - if:  # for gen2 HW that have gals
       properties:
         compatible:
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:58 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:58 +0800
Subject: [PATCH v3 12/13] memory: mtk-smi: mt8195: Add initial setting for
 smi-larb
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-13-yong.wu@mediatek.com>

To improve the performance, We add some initial setting for smi larbs.
there are two part:
1), Each port has the special ostd(outstanding) value in each larb.
2), Two general settings for each larb.
   a. THRT_UPDATE: the value in bits[7:4] of 0x24 is not so good.
   The HW default is 4, and we expect it is 5, thus, add a flag to update
   it. This is only a DE recommendatory value, not a actual issue.
   The register name(THRT_CON) means: throttling control, and the field
   RD_NU_LMT means: Read Non-ultra commands limit.
   This change means update the Read non-ultra command from 4 to 5 here.

   b. SW_FLAG: Set 1 to the FLAG register. this is only for helping
   debug. We could confirm if the larb is reset from this value is 1 or 0.

In some SoC, this setting maybe changed dynamically for some special case
like 4K, and this initial setting is enough in mt8195.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/memory/mtk-smi.c | 79 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 78 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 689a45b39a65..b883dcc0bbfa 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -32,6 +32,15 @@
 #define SMI_DUMMY			0x444
 
 /* SMI LARB */
+#define SMI_LARB_CMD_THRT_CON		0x24
+#define SMI_LARB_THRT_RD_NU_LMT_MSK	GENMASK(7, 4)
+#define SMI_LARB_THRT_RD_NU_LMT		(5 << 4)
+
+#define SMI_LARB_SW_FLAG		0x40
+#define SMI_LARB_SW_FLAG_1		0x1
+
+#define SMI_LARB_OSTDL_PORT		0x200
+#define SMI_LARB_OSTDL_PORTx(id)	(SMI_LARB_OSTDL_PORT + (((id) & 0x1f) << 2))
 
 /* Below are about mmu enable registers, they are different in SoCs */
 /* gen1: mt2701 */
@@ -68,6 +77,11 @@
 })
 
 #define SMI_COMMON_INIT_REGS_NR		6
+#define SMI_LARB_PORT_NR_MAX		32
+
+#define MTK_SMI_FLAG_THRT_UPDATE	BIT(0)
+#define MTK_SMI_FLAG_SW_FLAG		BIT(1)
+#define MTK_SMI_CAPS(flags, _x)		(!!((flags) & (_x)))
 
 struct mtk_smi_reg_pair {
 	unsigned int		offset;
@@ -108,6 +122,8 @@ struct mtk_smi_larb_gen {
 	int port_in_larb[MTK_LARB_NR_MAX + 1];
 	void (*config_port)(struct device *dev);
 	unsigned int			larb_direct_to_common_mask;
+	unsigned int			flags_general;
+	const u8			(*ostd)[SMI_LARB_PORT_NR_MAX];
 };
 
 struct mtk_smi {
@@ -224,12 +240,26 @@ static void mtk_smi_larb_config_port_mt8173(struct device *dev)
 static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
 {
 	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
-	u32 reg;
+	u32 reg, flags_general = larb->larb_gen->flags_general;
+	const u8 *larbostd = larb->larb_gen->ostd[larb->larbid];
 	int i;
 
 	if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
 		return;
 
+	if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_THRT_UPDATE)) {
+		reg = readl_relaxed(larb->base + SMI_LARB_CMD_THRT_CON);
+		reg &= ~SMI_LARB_THRT_RD_NU_LMT_MSK;
+		reg |= SMI_LARB_THRT_RD_NU_LMT;
+		writel_relaxed(reg, larb->base + SMI_LARB_CMD_THRT_CON);
+	}
+
+	if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_SW_FLAG))
+		writel_relaxed(SMI_LARB_SW_FLAG_1, larb->base + SMI_LARB_SW_FLAG);
+
+	for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++)
+		writel_relaxed(larbostd[i], larb->base + SMI_LARB_OSTDL_PORTx(i));
+
 	for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
 		reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
 		reg |= F_MMU_EN;
@@ -238,6 +268,51 @@ static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
 	}
 }
 
+static const u8 mtk_smi_larb_mt8195_ostd[][SMI_LARB_PORT_NR_MAX] = {
+	[0] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb0 */
+	[1] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb1 */
+	[2] = {0x12, 0x12, 0x12, 0x12, 0x0a,},      /* ... */
+	[3] = {0x12, 0x12, 0x12, 0x12, 0x28, 0x28, 0x0a,},
+	[4] = {0x06, 0x01, 0x17, 0x06, 0x0a,},
+	[5] = {0x06, 0x01, 0x17, 0x06, 0x06, 0x01, 0x06, 0x0a,},
+	[6] = {0x06, 0x01, 0x06, 0x0a,},
+	[7] = {0x0c, 0x0c, 0x12,},
+	[8] = {0x0c, 0x0c, 0x12,},
+	[9] = {0x0a, 0x08, 0x04, 0x06, 0x01, 0x01, 0x10, 0x18, 0x11, 0x0a,
+		0x08, 0x04, 0x11, 0x06, 0x02, 0x06, 0x01, 0x11, 0x11, 0x06,},
+	[10] = {0x18, 0x08, 0x01, 0x01, 0x20, 0x12, 0x18, 0x06, 0x05, 0x10,
+		0x08, 0x08, 0x10, 0x08, 0x08, 0x18, 0x0c, 0x09, 0x0b, 0x0d,
+		0x0d, 0x06, 0x10, 0x10,},
+	[11] = {0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x01, 0x01, 0x01, 0x01,},
+	[12] = {0x09, 0x09, 0x05, 0x05, 0x0c, 0x18, 0x02, 0x02, 0x04, 0x02,},
+	[13] = {0x02, 0x02, 0x12, 0x12, 0x02, 0x02, 0x02, 0x02, 0x08, 0x01,},
+	[14] = {0x12, 0x12, 0x02, 0x02, 0x02, 0x02, 0x16, 0x01, 0x16, 0x01,
+		0x01, 0x02, 0x02, 0x08, 0x02,},
+	[15] = {},
+	[16] = {0x28, 0x02, 0x02, 0x12, 0x02, 0x12, 0x10, 0x02, 0x02, 0x0a,
+		0x12, 0x02, 0x0a, 0x16, 0x02, 0x04,},
+	[17] = {0x1a, 0x0e, 0x0a, 0x0a, 0x0c, 0x0e, 0x10,},
+	[18] = {0x12, 0x06, 0x12, 0x06,},
+	[19] = {0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x01,
+		0x01, 0x01, 0x04, 0x0a, 0x06, 0x01, 0x01, 0x01, 0x0a, 0x06,
+		0x01, 0x01, 0x05, 0x03, 0x03, 0x04, 0x01,},
+	[20] = {0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x01,
+		0x01, 0x01, 0x04, 0x0a, 0x06, 0x01, 0x01, 0x01, 0x0a, 0x06,
+		0x01, 0x01, 0x05, 0x03, 0x03, 0x04, 0x01,},
+	[21] = {0x28, 0x19, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04,},
+	[22] = {0x28, 0x19, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04,},
+	[23] = {0x18, 0x01,},
+	[24] = {0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01,
+		0x01, 0x01,},
+	[25] = {0x02, 0x02, 0x02, 0x28, 0x16, 0x02, 0x02, 0x02, 0x12, 0x16,
+		0x02, 0x01,},
+	[26] = {0x02, 0x02, 0x02, 0x28, 0x16, 0x02, 0x02, 0x02, 0x12, 0x16,
+		0x02, 0x01,},
+	[27] = {0x02, 0x02, 0x02, 0x28, 0x16, 0x02, 0x02, 0x02, 0x12, 0x16,
+		0x02, 0x01,},
+	[28] = {0x1a, 0x0e, 0x0a, 0x0a, 0x0c, 0x0e, 0x10,},
+};
+
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
 	.port_in_larb = {
 		LARB0_PORT_OFFSET, LARB1_PORT_OFFSET,
@@ -280,6 +355,8 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
 
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = {
 	.config_port                = mtk_smi_larb_config_port_gen2_general,
+	.flags_general	            = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG,
+	.ostd		            = mtk_smi_larb_mt8195_ostd,
 };
 
 static const struct of_device_id mtk_smi_larb_of_ids[] = {
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:46 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:46 +0800
Subject: [PATCH v3 00/13] MT8195 SMI support
Message-ID: <20210810080859.29511-1-yong.wu@mediatek.com>

This patchset mainly adds SMI support for mt8195.

Comparing with the previous version, add two new functions:
a) add smi sub common
b) add initial setting for smi-common and smi-larb.

Change note:
v3:1) In the dt-binding:
       a. Change mediatek,smi type from phandle-array to phandle from Rob.
       b. Add a new bool property (mediatek,smi_sub_common)
          to indicate if this is smi-sub-common.
   2) Change the clock using bulk parting.
      keep the smi-common's has_gals flag. more strict.
   3) More comment about larb initial setting.
   4) Add a maintain patch
       
v2: https://lore.kernel.org/linux-mediatek/20210715121209.31024-1-yong.wu at mediatek.com/
    rebase on v5.14-rc1
    1) Adjust clk_bulk flow: use devm_clk_bulk_get for necessary clocks.
    2) Add two new little patches:
       a) use devm_platform_ioremap_resource
       b) Add error handle for smi_probe

v1: https://lore.kernel.org/linux-mediatek/20210616114346.18812-1-yong.wu at mediatek.com/

Yong Wu (13):
  dt-bindings: memory: mediatek: Add mt8195 smi binding
  dt-bindings: memory: mediatek: Add mt8195 smi sub common
  memory: mtk-smi: Use clk_bulk clock ops
  memory: mtk-smi: Rename smi_gen to smi_type
  memory: mtk-smi: Adjust some code position
  memory: mtk-smi: Add error handle for smi_probe
  memory: mtk-smi: Add device link for smi-sub-common
  memory: mtk-smi: Add clocks for smi-sub-common
  memory: mtk-smi: Use devm_platform_ioremap_resource
  memory: mtk-smi: mt8195: Add smi support
  memory: mtk-smi: mt8195: Add initial setting for smi-common
  memory: mtk-smi: mt8195: Add initial setting for smi-larb
  MAINTAINERS: Add entry for MediaTek SMI

 .../mediatek,smi-common.yaml                  |  36 +-
 .../memory-controllers/mediatek,smi-larb.yaml |   3 +
 MAINTAINERS                                   |   8 +
 drivers/memory/mtk-smi.c                      | 596 ++++++++++--------
 4 files changed, 395 insertions(+), 248 deletions(-)

-- 
2.18.0


From yong.wu at mediatek.com  Tue Aug 10 01:08:50 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:50 +0800
Subject: [PATCH v3 04/13] memory: mtk-smi: Rename smi_gen to smi_type
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-5-yong.wu@mediatek.com>

Prepare for adding smi sub common. Only rename from smi_gen to smi_type.
No functional change.

About the current "smi_gen", we have gen1/gen2 that stand for the
generation number for HW. I plan to add a new type(sub_common), then the
name "gen" is not proper.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Ikjoon Jang <ikjn at chromium.org>
---
 drivers/memory/mtk-smi.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index f91eaf5c3ab0..02a584dfb9b1 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -55,7 +55,7 @@
 /* All are MMU0 defaultly. Only specialize mmu1 here. */
 #define F_MMU1_LARB(larbid)		(0x1 << SMI_BUS_LARB_SHIFT(larbid))
 
-enum mtk_smi_gen {
+enum mtk_smi_type {
 	MTK_SMI_GEN1,
 	MTK_SMI_GEN2
 };
@@ -75,9 +75,9 @@ static const char * const mtk_smi_common_clks[] = {"apb", "smi", "gals0", "gals1
 #define MTK_SMI_COM_GALS_REQ_CLK_NR	MTK_SMI_CLK_NR_MAX
 
 struct mtk_smi_common_plat {
-	enum mtk_smi_gen gen;
-	bool             has_gals;
-	u32              bus_sel; /* Balance some larbs to enter mmu0 or mmu1 */
+	enum mtk_smi_type	type;
+	bool			has_gals;
+	u32			bus_sel; /* Balance some larbs to enter mmu0 or mmu1 */
 };
 
 struct mtk_smi_larb_gen {
@@ -409,29 +409,29 @@ static struct platform_driver mtk_smi_larb_driver = {
 };
 
 static const struct mtk_smi_common_plat mtk_smi_common_gen1 = {
-	.gen = MTK_SMI_GEN1,
+	.type     = MTK_SMI_GEN1,
 };
 
 static const struct mtk_smi_common_plat mtk_smi_common_gen2 = {
-	.gen = MTK_SMI_GEN2,
+	.type	  = MTK_SMI_GEN2,
 };
 
 static const struct mtk_smi_common_plat mtk_smi_common_mt6779 = {
-	.gen		= MTK_SMI_GEN2,
-	.has_gals	= true,
-	.bus_sel	= F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(4) |
-			  F_MMU1_LARB(5) | F_MMU1_LARB(6) | F_MMU1_LARB(7),
+	.type	  = MTK_SMI_GEN2,
+	.has_gals = true,
+	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(4) |
+		    F_MMU1_LARB(5) | F_MMU1_LARB(6) | F_MMU1_LARB(7),
 };
 
 static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
-	.gen      = MTK_SMI_GEN2,
+	.type     = MTK_SMI_GEN2,
 	.has_gals = true,
 	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
 		    F_MMU1_LARB(7),
 };
 
 static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
-	.gen      = MTK_SMI_GEN2,
+	.type     = MTK_SMI_GEN2,
 	.has_gals = true,
 	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
 		    F_MMU1_LARB(6),
@@ -494,7 +494,7 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
 	 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
 	 * base.
 	 */
-	if (common->plat->gen == MTK_SMI_GEN1) {
+	if (common->plat->type == MTK_SMI_GEN1) {
 		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 		common->smi_ao_base = devm_ioremap_resource(dev, res);
 		if (IS_ERR(common->smi_ao_base))
@@ -534,7 +534,7 @@ static int __maybe_unused mtk_smi_common_resume(struct device *dev)
 	if (ret)
 		return ret;
 
-	if (common->plat->gen == MTK_SMI_GEN2 && bus_sel)
+	if (common->plat->type == MTK_SMI_GEN2 && bus_sel)
 		writel(bus_sel, common->base + SMI_BUS_SEL);
 	return 0;
 }
-- 
2.18.0

From vladimir.oltean at nxp.com  Tue Aug 10 01:16:17 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Tue, 10 Aug 2021 08:16:17 +0000
Subject: [PATCH net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <YRIhwQ3ji8eqPQOQ@unreal>
References: <20210809131152.509092-1-vladimir.oltean@nxp.com>
 <YRIhwQ3ji8eqPQOQ@unreal>
Message-ID: <20210810081616.wjx6jnlh3qxqsfm2@skbuf>

Hi Leon,

On Tue, Aug 10, 2021 at 09:50:41AM +0300, Leon Romanovsky wrote:
> > +	memset(&send_info, 0, sizeof(send_info));
> 
> This can be written simpler.
> struct switchdev_notifier_fdb_info send_info = {};
> 
> In all places.

Because the structure contains a sub-structure, I believe that a
compound literal initializer would require additional braces for the
initialization of its sub-objects too. At least I know that expressions
like that have attracted the attention of clang people in the past:
https://patchwork.ozlabs.org/project/netdev/patch/20190506202447.30907-1-natechancellor at gmail.com/
So I went for the 'unambiguous' path.

From yong.wu at mediatek.com  Tue Aug 10 01:08:57 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:57 +0800
Subject: [PATCH v3 11/13] memory: mtk-smi: mt8195: Add initial setting for
 smi-common
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-12-yong.wu@mediatek.com>

To improve the performance, add initial setting for smi-common.
some register use some fix setting(suggested from DE).

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/memory/mtk-smi.c | 42 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 35853ba980c9..689a45b39a65 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -18,11 +18,19 @@
 #include <dt-bindings/memory/mtk-memory-port.h>
 
 /* SMI COMMON */
+#define SMI_L1LEN			0x100
+
 #define SMI_BUS_SEL			0x220
 #define SMI_BUS_LARB_SHIFT(larbid)	((larbid) << 1)
 /* All are MMU0 defaultly. Only specialize mmu1 here. */
 #define F_MMU1_LARB(larbid)		(0x1 << SMI_BUS_LARB_SHIFT(larbid))
 
+#define SMI_M4U_TH			0x234
+#define SMI_FIFO_TH1			0x238
+#define SMI_FIFO_TH2			0x23c
+#define SMI_DCM				0x300
+#define SMI_DUMMY			0x444
+
 /* SMI LARB */
 
 /* Below are about mmu enable registers, they are different in SoCs */
@@ -59,6 +67,13 @@
 	(_id << 8 | _id << 10 | _id << 12 | _id << 14);	\
 })
 
+#define SMI_COMMON_INIT_REGS_NR		6
+
+struct mtk_smi_reg_pair {
+	unsigned int		offset;
+	u32			value;
+};
+
 enum mtk_smi_type {
 	MTK_SMI_GEN1,
 	MTK_SMI_GEN2,		/* gen2 smi common */
@@ -85,6 +100,8 @@ struct mtk_smi_common_plat {
 	enum mtk_smi_type	type;
 	bool			has_gals;
 	u32			bus_sel; /* Balance some larbs to enter mmu0 or mmu1 */
+
+	const struct mtk_smi_reg_pair	*init;
 };
 
 struct mtk_smi_larb_gen {
@@ -419,6 +436,15 @@ static struct platform_driver mtk_smi_larb_driver = {
 	}
 };
 
+static const struct mtk_smi_reg_pair mtk_smi_common_mt8195_init[SMI_COMMON_INIT_REGS_NR] = {
+	{SMI_L1LEN, 0xb},
+	{SMI_M4U_TH, 0xe100e10},
+	{SMI_FIFO_TH1, 0x506090a},
+	{SMI_FIFO_TH2, 0x506090a},
+	{SMI_DCM, 0x4f1},
+	{SMI_DUMMY, 0x1},
+};
+
 static const struct mtk_smi_common_plat mtk_smi_common_gen1 = {
 	.type     = MTK_SMI_GEN1,
 };
@@ -453,12 +479,14 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8195_vdo = {
 	.has_gals = true,
 	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(3) | F_MMU1_LARB(5) |
 		    F_MMU1_LARB(7),
+	.init     = mtk_smi_common_mt8195_init,
 };
 
 static const struct mtk_smi_common_plat mtk_smi_common_mt8195_vpp = {
 	.type     = MTK_SMI_GEN2,
 	.has_gals = true,
 	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(7),
+	.init     = mtk_smi_common_mt8195_init,
 };
 
 static const struct mtk_smi_common_plat mtk_smi_sub_common_mt8195 = {
@@ -551,15 +579,21 @@ static int mtk_smi_common_remove(struct platform_device *pdev)
 static int __maybe_unused mtk_smi_common_resume(struct device *dev)
 {
 	struct mtk_smi *common = dev_get_drvdata(dev);
-	u32 bus_sel = common->plat->bus_sel;
-	int ret;
+	const struct mtk_smi_reg_pair *init = common->plat->init;
+	u32 bus_sel = common->plat->bus_sel; /* default is 0 */
+	int ret, i;
 
 	ret = clk_bulk_prepare_enable(common->clk_num, common->clks);
 	if (ret)
 		return ret;
 
-	if (common->plat->type == MTK_SMI_GEN2 && bus_sel)
-		writel(bus_sel, common->base + SMI_BUS_SEL);
+	if (common->plat->type != MTK_SMI_GEN2)
+		return 0;
+
+	for (i = 0; i < SMI_COMMON_INIT_REGS_NR && init && init[i].offset; i++)
+		writel_relaxed(init[i].value, common->base + init[i].offset);
+
+	writel(bus_sel, common->base + SMI_BUS_SEL);
 	return 0;
 }
 
-- 
2.18.0

From yong.wu at mediatek.com  Tue Aug 10 01:08:59 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 10 Aug 2021 16:08:59 +0800
Subject: [PATCH v3 13/13] MAINTAINERS: Add entry for MediaTek SMI
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <20210810080859.29511-14-yong.wu@mediatek.com>

I am the author of MediaTek SMI driver, and will to maintain
and develop it further.
Add myself to cover these items.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a61f4f3b78a9..91af55b45e80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11754,6 +11754,14 @@ M:	Sean Wang <sean.wang at mediatek.com>
 S:	Maintained
 F:	drivers/char/hw_random/mtk-rng.c
 
+MEDIATEK SMI DRIVER
+M:	Yong Wu <yong.wu at mediatek.com>
+L:	linux-mediatek at lists.infradead.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/memory-controllers/mediatek,smi*
+F:	drivers/memory/mtk-smi.c
+F:	include/soc/mediatek/smi.h
+
 MEDIATEK SWITCH DRIVER
 M:	Sean Wang <sean.wang at mediatek.com>
 M:	Landen Chao <Landen.Chao at mediatek.com>
-- 
2.18.0

From maz at kernel.org  Tue Aug 10 01:27:32 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 09:27:32 +0100
Subject: [PATCH 05/13] clocksource/arm_arch_timer: Fix MMIO base address
 vs callback ordering issue
In-Reply-To: <CAOQ_QsjATdRRFdiG5kR+Ni7X-_kMaF+V_XQx3uuxivk0t4xt_w@mail.gmail.com>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-6-maz@kernel.org>
 <CAOQ_QsjATdRRFdiG5kR+Ni7X-_kMaF+V_XQx3uuxivk0t4xt_w@mail.gmail.com>
Message-ID: <87fsvhbt6z.wl-maz@kernel.org>

On Mon, 09 Aug 2021 17:52:00 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Mon, Aug 9, 2021 at 8:27 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > The MMIO timer base address gets published after we have registered
> > the callbacks and the interrupt handler, which is... a bit dangerous.
> >
> > Fix this by moving the base address publication to the point where
> > we register the timer, and expose a pointer to the timer structure
> > itself rather than a naked value.
> >
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> 
> Is this patch stable-worthy? I take it there haven't been any reports
> of issues, though this seems rather perilous.

It *could* deserve a Cc stable, although I suspect it doesn't easily
fall over with the current code:

- When programming a timer, the driver uses the base contained in
  struct arch_timer, and derived from the clock_event_device.
- As long as you don't need to read the counter, you are good (the
  whole point of using TVAL is that you avoid reading the counter).

It is only if someone called into the standalone counter accessor that
there would be a firework, and that's rather unlikely.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From yunfei.dong at mediatek.com  Tue Aug 10 01:30:36 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:36 +0800
Subject: [PATCH v4,
 04/15] media: mtk-vcodec: Use component framework to manage each
 hardware information
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-5-yunfei.dong@mediatek.com>

Uses component framework to manage each hardware information which
includes irq/power/clk. The hardware includes LAT0, LAT1 and CORE.

Change-Id: I90b4da74a1ea482551bf8c3e7c07917a7bae2e7a
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: Fix many coments
  > Looking up "mediatek,mtk-vcodec-core" to determine if it uses component framwork sounds like...
  Add prameter in pdata, for all platform will use compoent after mt8183

  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  > + Has asked the same question in [1].  Why it removes the
  > +platform_set_drvdata() above?  mtk_vcodec_init_master() also calls platform_set_drvdata().
  Must call component_master_add_with_match after platform_set_drvdata for component architecture.
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 198 ++++++++++++++----
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 184 ++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  49 +++++
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  19 ++
 8 files changed, 419 insertions(+), 35 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index ca8e9e7a9c4e..edeb3b66e9e9 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -15,6 +15,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_stateless.o \
 		mtk_vcodec_dec_pm.o \
+		mtk_vcodec_dec_hw.o \
 
 mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		venc/venc_h264_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 9fbd24186c1a..c509224cbff4 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -66,6 +66,7 @@ extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops;
 extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
 extern const struct media_device_ops mtk_vcodec_media_ops;
 
+extern struct platform_driver mtk_vdec_comp_driver;
 
 /*
  * mtk_vdec_lock/mtk_vdec_unlock are for ctx instance to
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index dd749d41c75a..d93ea5c63e1e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -5,6 +5,7 @@
  *         Tiffany Lin <tiffany.lin at mediatek.com>
  */
 
+#include <linux/component.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -18,19 +19,90 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
 #include "mtk_vcodec_fw.h"
 
-#define VDEC_HW_ACTIVE	0x10
-#define VDEC_IRQ_CFG	0x11
-#define VDEC_IRQ_CLR	0x10
-#define VDEC_IRQ_CFG_REG	0xa4
-
 module_param(mtk_v4l2_dbg_level, int, 0644);
 module_param(mtk_vcodec_dbg, bool, 0644);
 
+static struct of_device_id mtk_vdec_drv_ids[] = {
+	{
+		.compatible = "mediatek,mtk-vcodec-lat",
+		.data = (void *)MTK_VDEC_LAT0,
+	},
+	{
+		.compatible = "mediatek,mtk-vcodec-core",
+		.data = (void *)MTK_VDEC_CORE,
+	},
+	{},
+};
+
+static inline int mtk_vdec_compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static inline void mtk_vdec_release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
+static inline int mtk_vdec_bind(struct device *dev)
+{
+	struct mtk_vcodec_dev *data = dev_get_drvdata(dev);
+
+	return component_bind_all(dev, data);
+}
+
+static inline void mtk_vdec_unbind(struct device *dev)
+{
+	struct mtk_vcodec_dev *data = dev_get_drvdata(dev);
+
+	component_unbind_all(dev, data);
+}
+
+static const struct component_master_ops mtk_vdec_ops = {
+   .bind = mtk_vdec_bind,
+   .unbind = mtk_vdec_unbind,
+};
+
+static struct component_match *mtk_vcodec_match_add(
+	struct mtk_vcodec_dev *vdec_dev)
+ {
+	struct platform_device *pdev = vdec_dev->plat_dev;
+	struct component_match *match = NULL;
+	struct device_node *comp_node;
+	enum mtk_vdec_hw_id comp_idx;
+	const struct of_device_id *of_id;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_vdec_drv_ids); i++) {
+		of_id = &mtk_vdec_drv_ids[i];
+		comp_node = of_find_compatible_node(NULL, NULL,
+			of_id->compatible);
+		if (!comp_node)
+			continue;
+
+		if (!of_device_is_available(comp_node)) {
+			of_node_put(comp_node);
+			dev_err(&pdev->dev, "Fail to get MMSYS node\n");
+			continue;
+		}
+
+		comp_idx = (enum mtk_vdec_hw_id)of_id->data;
+		mtk_v4l2_debug(4, "Get component:hw_id(%d),vdec_dev(0x%p),comp_node(0x%p)\n",
+			comp_idx, vdec_dev, comp_node);
+		vdec_dev->component_node[comp_idx] = comp_node;
+
+		component_match_add_release(&pdev->dev, &match, mtk_vdec_release_of,
+			mtk_vdec_compare_of, comp_node);
+	}
+
+	return match;
+}
+
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -95,6 +167,59 @@ static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
 	return 0;
 }
 
+static int mtk_vcodec_init_master(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	struct component_match *match;
+	int ret;
+
+	match = mtk_vcodec_match_add(dev);
+	if (IS_ERR_OR_NULL(match))
+		return -EINVAL;
+
+	platform_set_drvdata(pdev, dev);
+	ret = component_master_add_with_match(&pdev->dev, &mtk_vdec_ops, match);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int mtk_vcodec_init_dec_params(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		return ret;
+
+	if (!dev->vdec_pdata->is_comp_supported) {
+		dev->dec_irq = platform_get_irq(pdev, 0);
+		if (dev->dec_irq < 0) {
+			dev_err(&pdev->dev, "failed to get irq number");
+			return dev->dec_irq;
+		}
+
+		irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+		ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)",
+				dev->dec_irq, ret);
+			return ret;
+		}
+
+		ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "failed to get mt vcodec clock source");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -220,7 +345,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 {
 	struct mtk_vcodec_dev *dev;
 	struct video_device *vfd_dec;
-	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
 	int ret;
@@ -249,32 +373,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
-		goto err_dec_pm;
-	}
-
-	ret = mtk_vcodec_get_reg_bases(dev);
-	if (ret)
-		goto err_res;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
-		goto err_res;
-	}
-
-	dev->dec_irq = platform_get_irq(pdev, 0);
-	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
-			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+	ret = mtk_vcodec_init_dec_params(dev);
 	if (ret) {
-		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
-			dev->dec_irq,
-			ret);
-		goto err_res;
+		dev_err(&pdev->dev, "Failed to init pm and registers");
+		goto err_dec_pm;
 	}
 
 	mutex_init(&dev->dec_mutex);
@@ -311,7 +413,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		MTK_VCODEC_DEC_NAME);
 	video_set_drvdata(vfd_dec, dev);
 	dev->vfd_dec = vfd_dec;
-	platform_set_drvdata(pdev, dev);
 
 	dev->m2m_dev_dec = v4l2_m2m_init(&mtk_vdec_m2m_ops);
 	if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
@@ -362,8 +463,16 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	mtk_v4l2_debug(0, "decoder registered as /dev/video%d",
 		vfd_dec->num);
 
-	return 0;
+	if (dev->vdec_pdata->is_comp_supported) {
+		ret = mtk_vcodec_init_master(dev);
+		if (ret < 0)
+			goto err_component_match;
+	} else {
+		platform_set_drvdata(pdev, dev);
+	}
 
+	return 0;
+err_component_match:
 err_dec_reg:
 	if (dev->vdec_pdata->uses_stateless_api)
 		media_device_unregister(&dev->mdev_dec);
@@ -382,6 +491,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
+
 	return ret;
 }
 
@@ -436,7 +546,25 @@ static struct platform_driver mtk_vcodec_dec_driver = {
 	},
 };
 
-module_platform_driver(mtk_vcodec_dec_driver);
+static struct platform_driver * const mtk_vdec_drivers[] = {
+	&mtk_vdec_comp_driver,
+	&mtk_vcodec_dec_driver,
+};
+
+static int __init mtk_vdec_init(void)
+{
+	return platform_register_drivers(mtk_vdec_drivers,
+					 ARRAY_SIZE(mtk_vdec_drivers));
+}
+
+static void __exit mtk_vdec_exit(void)
+{
+	platform_unregister_drivers(mtk_vdec_drivers,
+				    ARRAY_SIZE(mtk_vdec_drivers));
+}
+
+module_init(mtk_vdec_init);
+module_exit(mtk_vdec_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
new file mode 100644
index 000000000000..5e1b7670ba5b
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/component.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_intr.h"
+#include "mtk_vcodec_util.h"
+
+static int mtk_vdec_comp_bind(struct device *dev, struct device *master,
+	void *data)
+{
+	struct mtk_vdec_comp_dev *comp_dev = dev_get_drvdata(dev);
+	struct mtk_vcodec_dev *master_dev = data;
+	int i;
+
+	for (i = 0; i < MTK_VDEC_HW_MAX; i++) {
+		if (dev->of_node != master_dev->component_node[i])
+			continue;
+
+		master_dev->comp_dev[i] = comp_dev;
+		comp_dev->comp_idx = i;
+		comp_dev->master_dev = master_dev;
+		break;
+	}
+
+	if (i == MTK_VDEC_HW_MAX) {
+		dev_err(dev, "Failed to get component node\n");
+		return -EINVAL;
+	}
+
+	comp_dev->reg_base[VDEC_COMP_SYS] =
+		master_dev->reg_base[VDEC_COMP_SYS];
+	return 0;
+}
+
+static void mtk_vdec_comp_unbind(struct device *dev, struct device *master,
+	void *data)
+{
+	struct mtk_vdec_comp_dev *comp_dev = dev_get_drvdata(dev);
+
+	comp_dev->reg_base[VDEC_COMP_SYS] = NULL;
+}
+
+static const struct component_ops mtk_vdec_hw_component_ops = {
+	.bind = mtk_vdec_comp_bind,
+	.unbind = mtk_vdec_comp_unbind,
+};
+
+static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
+{
+	struct mtk_vdec_comp_dev *dev = priv;
+	struct mtk_vcodec_ctx *ctx;
+	u32 cg_status;
+	unsigned int dec_done_status;
+	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
+					VDEC_IRQ_CFG_REG;
+
+	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
+
+	/* check if HW active or not */
+	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
+	if ((cg_status & VDEC_HW_ACTIVE) != 0) {
+		mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",
+			cg_status);
+		return IRQ_HANDLED;
+	}
+
+	dec_done_status = readl(vdec_misc_addr);
+	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
+		MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
+		return IRQ_HANDLED;
+
+	/* clear interrupt */
+	writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
+	writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
+
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+
+	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
+		ctx->id, dec_done_status);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_vdec_comp_init_irq(struct mtk_vdec_comp_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	dev->dec_irq = platform_get_irq(pdev, 0);
+	if (dev->dec_irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource");
+		return dev->dec_irq;
+	}
+
+	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+				mtk_vdec_comp_irq_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
+			dev->dec_irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mtk_vdec_comp_probe(struct platform_device *pdev)
+{
+	struct mtk_vdec_comp_dev *dev;
+	int ret;
+
+	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->plat_dev = pdev;
+	ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
+		return ret;
+	}
+
+	dev->reg_base[VDEC_COMP_MISC] =
+		devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR((__force void *)dev->reg_base[VDEC_COMP_MISC])) {
+		ret = PTR_ERR((__force void *)dev->reg_base[VDEC_COMP_MISC]);
+		goto err;
+	}
+
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+
+	ret = mtk_vdec_comp_init_irq(dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register irq handler.\n");
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, dev);
+
+	ret = component_add(&pdev->dev, &mtk_vdec_hw_component_ops);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add component: %d\n", ret);
+		goto err;
+	}
+
+	return 0;
+err:
+	mtk_vcodec_release_dec_pm(&dev->pm);
+	return ret;
+}
+
+static const struct of_device_id mtk_vdec_comp_ids[] = {
+	{
+		.compatible = "mediatek,mtk-vcodec-lat",
+	},
+	{
+		.compatible = "mediatek,mtk-vcodec-core",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_vdec_comp_ids);
+
+struct platform_driver mtk_vdec_comp_driver = {
+	.probe	= mtk_vdec_comp_probe,
+	.driver	= {
+		.name	= "mtk-vdec-comp",
+		.of_match_table = mtk_vdec_comp_ids,
+	},
+};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
new file mode 100644
index 000000000000..8d6e818a3474
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _MTK_VCODEC_DEC_HW_H_
+#define _MTK_VCODEC_DEC_HW_H_
+
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "mtk_vcodec_drv.h"
+
+#define VDEC_HW_ACTIVE	0x10
+#define VDEC_IRQ_CFG	0x11
+#define VDEC_IRQ_CLR	0x10
+#define VDEC_IRQ_CFG_REG	0xa4
+
+/**
+ * enum mtk_comp_hw_reg_idx - component register base index
+ */
+enum mtk_comp_hw_reg_idx {
+	VDEC_COMP_SYS,
+	VDEC_COMP_MISC,
+	VDEC_COMP_MAX
+};
+
+/**
+ * struct mtk_vdec_comp_dev - component framwork driver data
+ * @plat_dev: platform device
+ * @master_dev: master device
+ * @reg_base: Mapped address of MTK Vcodec registers.
+ *
+ * @dec_irq: decoder irq resource
+ * @pm: power management control
+ * @comp_idx: component index
+ */
+struct mtk_vdec_comp_dev {
+	struct platform_device *plat_dev;
+	struct mtk_vcodec_dev *master_dev;
+	void __iomem *reg_base[VDEC_COMP_MAX];
+
+	int dec_irq;
+	struct mtk_vcodec_pm pm;
+	int comp_idx;
+};
+
+#endif /* _MTK_VCODEC_DEC_HW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 59c24b22ab6d..4f9a80ce15d8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -623,4 +623,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_comp_supported = false,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 8f4a1f0a0769..762633572b49 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -357,4 +357,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_comp_supported = false,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 973b0b3649c6..e530757a9b5a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -93,6 +93,17 @@ enum mtk_fmt_type {
 	MTK_FMT_FRAME = 2,
 };
 
+/**
+ * struct mtk_vdec_hw_id - Hardware index used to separate
+ *                         different hardware
+ */
+enum mtk_vdec_hw_id {
+	MTK_VDEC_CORE,
+	MTK_VDEC_LAT0,
+	MTK_VDEC_LAT1,
+	MTK_VDEC_HW_MAX,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -331,6 +342,7 @@ enum mtk_chip {
  *
  * @chip: chip this decoder is compatible with
  *
+ * @is_comp_supported: true: using compoent framework, false: not support
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
  */
 
@@ -352,6 +364,7 @@ struct mtk_vcodec_dec_pdata {
 
 	enum mtk_chip chip;
 
+	bool is_comp_supported;
 	bool uses_stateless_api;
 };
 
@@ -422,6 +435,9 @@ struct mtk_vcodec_enc_pdata {
  * @pm: power management control
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
+ *
+ * @comp_dev: component hardware device
+ * @component_node: component node
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -459,6 +475,9 @@ struct mtk_vcodec_dev {
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
 	unsigned int enc_capability;
+
+	void *comp_dev[MTK_VDEC_HW_MAX];
+	struct device_node *component_node[MTK_VDEC_HW_MAX];
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:38 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:38 +0800
Subject: [PATCH v4, 06/15] media: mtk-vcodec: Use pure single core for MT8183
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-7-yunfei.dong@mediatek.com>

Separates different architecture for hardware: pure_sin_core
and lat_sin_core. MT8183 is pure single core. Uses .hw_arch to
distinguish.

Change-Id: Ie771c7f7233ff9caa8c7aac0c787bdff757f7b0e
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c      |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c     |  1 +
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 10 ++++++++++
 3 files changed, 12 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 4f9a80ce15d8..138f6fcb36bb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -624,4 +624,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_comp_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 762633572b49..12c243d6dff3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -358,4 +358,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_comp_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index e530757a9b5a..1d0798fd9adf 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -323,6 +323,14 @@ enum mtk_chip {
 	MTK_MT8192,
 };
 
+/**
+ * struct mtk_vdec_hw_arch - Used to separate different hardware architecture
+ */
+enum mtk_vdec_hw_arch {
+	MTK_VDEC_PURE_SINGLE_CORE,
+	MTK_VDEC_LAT_SINGLE_CORE,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -341,6 +349,7 @@ enum mtk_chip {
  * @num_framesizes: count of video decoder frame sizes
  *
  * @chip: chip this decoder is compatible with
+ * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_comp_supported: true: using compoent framework, false: not support
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
@@ -363,6 +372,7 @@ struct mtk_vcodec_dec_pdata {
 	const int num_framesizes;
 
 	enum mtk_chip chip;
+	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_comp_supported;
 	bool uses_stateless_api;
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:37 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:37 +0800
Subject: [PATCH v4,
 05/15] dt-bindings: media: mtk-vcodec: Separate video encoder and
 decoder dt-bindings
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-6-yunfei.dong@mediatek.com>

Decoder will use component framework to manage hardware, it is big
difference with encoder.

Change-Id: I8c919c7c133beafff2bb94c266286b3ac5f93905
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: fix yaml file check fail
---
 .../media/mediatek,vcodec-decoder.yaml        | 175 +++++++++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 185 ++++++++++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 130 ------------
 3 files changed, 360 insertions(+), 130 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
new file mode 100644
index 000000000000..b6b97110024d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -0,0 +1,175 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-dec
+      - mediatek,mt8183-vcodec-dec
+
+  reg:
+    maxItems: 12
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 8
+
+  clock-names:
+    items:
+      - const: vcodecpll
+      - const: univpll_d2
+      - const: clk_cci400_sel
+      - const: vdec_sel
+      - const: vdecpll
+      - const: vencpll
+      - const: venc_lt_sel
+      - const: vdec_bus_clk_src
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  assigned-clock-rates: true
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-dec
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-dec
+
+    then:
+      required:
+        - mediatek,vpu
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt8173-power.h>
+
+    vcodec_dec: vcodec at 16000000 {
+      compatible = "mediatek,mt8173-vcodec-dec";
+      reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
+          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
+          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
+          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
+          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
+          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
+          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
+          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
+          <0 0x16026800 0 0x800>,   /*VP8_VD*/
+          <0 0x16027000 0 0x800>,   /*VP6_VD*/
+          <0 0x16027800 0 0x800>,   /*VP8_VL*/
+          <0 0x16028400 0 0x400>;   /*VP9_VD*/
+      interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
+      mediatek,larb = <&larb1>;
+      iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
+      mediatek,vpu = <&vpu>;
+      power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+      clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
+             <&topckgen CLK_TOP_UNIVPLL_D2>,
+             <&topckgen CLK_TOP_CCI400_SEL>,
+             <&topckgen CLK_TOP_VDEC_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL>,
+             <&apmixedsys CLK_APMIXED_VENCPLL>,
+             <&topckgen CLK_TOP_VENC_LT_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL_370P5>;
+      clock-names = "vcodecpll",
+                  "univpll_d2",
+                  "clk_cci400_sel",
+                  "vdec_sel",
+                  "vdecpll",
+                  "vencpll",
+                  "venc_lt_sel",
+                  "vdec_bus_clk_src";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
+                      <&topckgen CLK_TOP_CCI400_SEL>,
+                      <&topckgen CLK_TOP_VDEC_SEL>,
+                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
+                      <&apmixedsys CLK_APMIXED_VENCPLL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
+                             <&topckgen CLK_TOP_UNIVPLL_D2>,
+                             <&topckgen CLK_TOP_VCODECPLL>;
+      assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
new file mode 100644
index 000000000000..ee93ac07e2fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -0,0 +1,185 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Encode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Encode is the video encode hardware present in Mediatek
+  SoCs which supports high resolution encoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-enc-vp8
+      - mediatek,mt8173-vcodec-enc
+      - mediatek,mt8183-vcodec-enc
+      - mediatek,mt8192-vcodec-enc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-enc
+              - mediatek,mt8192-vcodec-enc
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-enc-vp8
+              - mediatek,mt8173-vcodec-enc
+
+    then:
+      required:
+        - mediatek,vpu
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - mediatek,mt8173-vcodec-enc
+            - mediatek,mt8192-vcodec-enc
+            - mediatek,mt8173-vcodec-enc
+
+    then:
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+           - const: venc_sel
+    else:  # for vp8 hw decoder
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_lt_sel
+ 
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    vcodec_enc_avc: vcodec at 18002000 {
+      compatible = "mediatek,mt8173-vcodec-enc";
+      reg = <0 0x18002000 0 0x1000>;
+      interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU>,
+             <&iommu M4U_PORT_VENC_REC>,
+             <&iommu M4U_PORT_VENC_BSDMA>,
+             <&iommu M4U_PORT_VENC_SV_COMV>,
+             <&iommu M4U_PORT_VENC_RD_COMV>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
+             <&iommu M4U_PORT_VENC_REF_LUMA>,
+             <&iommu M4U_PORT_VENC_REF_CHROMA>,
+             <&iommu M4U_PORT_VENC_NBM_RDMA>,
+             <&iommu M4U_PORT_VENC_NBM_WDMA>;
+      mediatek,larb = <&larb3>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      clock-names = "venc_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
+    };
+
+    vcodec_enc_vp8: vcodec at 19002000 {
+      compatible = "mediatek,mt8173-vcodec-enc-vp8";
+      reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
+      interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
+             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
+             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
+             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
+             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
+      mediatek,larb = <&larb5>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      clock-names = "venc_lt_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
deleted file mode 100644
index c44a6e6943af..000000000000
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ /dev/null
@@ -1,130 +0,0 @@
-Mediatek Video Codec
-
-Mediatek Video Codec is the video codec hw present in Mediatek SoCs which
-supports high resolution encoding and decoding functionalities.
-
-Required properties:
-- compatible : must be one of the following string:
-  "mediatek,mt8173-vcodec-enc-vp8" for mt8173 vp8 encoder.
-  "mediatek,mt8173-vcodec-enc" for mt8173 avc encoder.
-  "mediatek,mt8183-vcodec-enc" for MT8183 encoder.
-  "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
-  "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
-  "mediatek,mt8183-vcodec-dec" for MT8183 decoder.
-- reg : Physical base address of the video codec registers and length of
-  memory mapped region.
-- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
-- clocks : list of clock specifiers, corresponding to entries in
-  the clock-names property.
-- clock-names: avc encoder must contain "venc_sel", vp8 encoder must
-  contain "venc_lt_sel", decoder must contain "vcodecpll", "univpll_d2",
-  "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", "venc_lt_sel",
-  "vdec_bus_clk_src".
-- iommus : should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-- dma-ranges : describes the dma address range space that the codec hw access.
-One of the two following nodes:
-- mediatek,vpu : the node of the video processor unit, if using VPU.
-- mediatek,scp : the node of the SCP unit, if using SCP.
-
-
-Example:
-
-vcodec_dec: vcodec at 16000000 {
-    compatible = "mediatek,mt8173-vcodec-dec";
-    reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
-          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
-          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
-          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
-          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
-          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
-          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
-          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
-          <0 0x16026800 0 0x800>,   /*VP8_VD*/
-          <0 0x16027000 0 0x800>,   /*VP6_VD*/
-          <0 0x16027800 0 0x800>,   /*VP8_VL*/
-          <0 0x16028400 0 0x400>;   /*VP9_VD*/
-    interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
-    mediatek,larb = <&larb1>;
-    iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
-    mediatek,vpu = <&vpu>;
-    power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
-    clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
-             <&topckgen CLK_TOP_UNIVPLL_D2>,
-             <&topckgen CLK_TOP_CCI400_SEL>,
-             <&topckgen CLK_TOP_VDEC_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL>,
-             <&apmixedsys CLK_APMIXED_VENCPLL>,
-             <&topckgen CLK_TOP_VENC_LT_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL_370P5>;
-    clock-names = "vcodecpll",
-                  "univpll_d2",
-                  "clk_cci400_sel",
-                  "vdec_sel",
-                  "vdecpll",
-                  "vencpll",
-                  "venc_lt_sel",
-                  "vdec_bus_clk_src";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
-                      <&topckgen CLK_TOP_CCI400_SEL>,
-                      <&topckgen CLK_TOP_VDEC_SEL>,
-                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
-                      <&apmixedsys CLK_APMIXED_VENCPLL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
-                             <&topckgen CLK_TOP_UNIVPLL_D2>,
-                             <&topckgen CLK_TOP_VCODECPLL>;
-    assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
-  };
-
-vcodec_enc_avc: vcodec at 18002000 {
-    compatible = "mediatek,mt8173-vcodec-enc";
-    reg = <0 0x18002000 0 0x1000>;
-    interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU>,
-             <&iommu M4U_PORT_VENC_REC>,
-             <&iommu M4U_PORT_VENC_BSDMA>,
-             <&iommu M4U_PORT_VENC_SV_COMV>,
-             <&iommu M4U_PORT_VENC_RD_COMV>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
-             <&iommu M4U_PORT_VENC_REF_LUMA>,
-             <&iommu M4U_PORT_VENC_REF_CHROMA>,
-             <&iommu M4U_PORT_VENC_NBM_RDMA>,
-             <&iommu M4U_PORT_VENC_NBM_WDMA>;
-    mediatek,larb = <&larb3>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    clock-names = "venc_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
-  };
-
-vcodec_enc_vp8: vcodec at 19002000 {
-    compatible = "mediatek,mt8173-vcodec-enc-vp8";
-    reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
-    interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
-             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
-             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
-             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
-             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
-    mediatek,larb = <&larb5>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    clock-names = "venc_lt_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
-  };
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:42 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:42 +0800
Subject: [PATCH v4,
 10/15] media: mtk-vcodec: Add new interface to lock different hardware
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-11-yunfei.dong@mediatek.com>

For add new hardware, not only need to lock lat hardware, also
need to lock core hardware in case of different instance start
to decoder at the same time.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c     | 4 ++--
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 6 +++---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 2b334a8a81c6..130ecef2e766 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -105,12 +105,12 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
 
 void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_unlock(&ctx->dev->dec_mutex);
+	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_lock(&ctx->dev->dec_mutex);
+	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 2c62543a5328..37ecb8252955 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -374,7 +374,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct video_device *vfd_dec;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret;
+	int i, ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -406,8 +406,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	mutex_init(&dev->dec_mutex);
-	mutex_init(&dev->dev_mutex);
+	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
+		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
 
 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index a8242389ad24..f1e63acaec76 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -496,7 +496,7 @@ struct mtk_vcodec_dev {
 	int dec_irq;
 	int enc_irq;
 
-	struct mutex dec_mutex;
+	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
 	struct mutex enc_mutex;
 
 	struct mtk_vcodec_pm pm;
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:41 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:41 +0800
Subject: [PATCH v4, 09/15] media: mtk-vcodec: Generalize power and clock on/off
 interfaces
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-10-yunfei.dong@mediatek.com>

Generalizes power and clock on/off interfaces to support different hardware.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  4 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 76 ++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  8 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  2 +
 .../platform/mtk-vcodec/mtk_vcodec_util.c     | 87 ++++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |  8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   | 21 ++---
 9 files changed, 174 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index d52e975292dc..2c62543a5328 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -126,7 +126,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[0]);
@@ -287,7 +287,7 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(&dev->pm);
+		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
 		if (ret < 0)
 			goto err_load_fw;
 		/*
@@ -348,7 +348,7 @@ static int fops_vcodec_release(struct file *file)
 	mtk_vcodec_dec_release(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(&dev->pm);
+		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 7a31afd294ba..714df68ffb19 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -68,7 +68,7 @@ static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev, dev->comp_idx);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
index 8d6e818a3474..0a4c2e6f5df2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -32,6 +32,8 @@ enum mtk_comp_hw_reg_idx {
  * @master_dev: master device
  * @reg_base: Mapped address of MTK Vcodec registers.
  *
+ * @curr_ctx: The context that is waiting for codec hardware
+ *
  * @dec_irq: decoder irq resource
  * @pm: power management control
  * @comp_idx: component index
@@ -41,6 +43,8 @@ struct mtk_vdec_comp_dev {
 	struct mtk_vcodec_dev *master_dev;
 	void __iomem *reg_base[VDEC_COMP_MAX];
 
+	struct mtk_vcodec_ctx *curr_ctx;
+
 	int dec_irq;
 	struct mtk_vcodec_pm pm;
 	int comp_idx;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 20bd157a855c..c2de88bb8092 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -5,11 +5,13 @@
  */
 
 #include <linux/clk.h>
+#include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
@@ -84,10 +86,23 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 	put_device(pm->larbvdec);
 }
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return -EINVAL;
+		}
+		pm = &comp_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
@@ -95,20 +110,49 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 	return ret;
 }
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int ret, i = 0;
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int ret, i;
+
+	if (vdec_dev->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+		enable_irq(comp_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		enable_irq(vdec_dev->dec_irq);
+	}
 
+	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
 		if (ret) {
@@ -130,11 +174,27 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int i = 0;
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int i;
 
+	if (vdec_dev->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+		disable_irq(comp_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		disable_irq(vdec_dev->dec_irq);
+	}
+
+	dec_clk = &pm->vdec_clk;
 	mtk_smi_larb_put(pm->larbvdec);
 	for (i = dec_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index a3df6aef6cb9..698750572b57 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -13,9 +13,9 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
 	struct mtk_vcodec_pm *pm);
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm);
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 4ad0566e715d..a8242389ad24 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -284,6 +284,7 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ * @hw_id: hardware index used to identify different hardware.
  *
  * @msg_queue: msg queue used to store lat buffer information.
  */
@@ -328,6 +329,7 @@ struct mtk_vcodec_ctx {
 
 	int decoded_frame_cnt;
 	struct mutex lock;
+	int hw_id;
 
 	struct vdec_msg_queue msg_queue;
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index ac5973b6735f..bee0f22db36e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -6,7 +6,10 @@
 */
 
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
 
@@ -81,25 +84,87 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 }
 EXPORT_SYMBOL(mtk_vcodec_mem_free);
 
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx)
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int comp_idx)
 {
-	unsigned long flags;
+	struct platform_device *hw_pdev;
+	struct device_node *node;
+	struct mtk_vdec_comp_dev *master_dev;
+
+	if (comp_idx >= MTK_VDEC_HW_MAX || comp_idx < 0) {
+		mtk_v4l2_err("Comp idx is out of range:%d", comp_idx);
+		return NULL;
+	}
+
+	if (dev->comp_dev[comp_idx])
+		return dev->comp_dev[comp_idx];
+
+	node = dev->component_node[comp_idx];
+	if (!node) {
+		mtk_v4l2_err("Get lat node fail:%d", comp_idx);
+		return NULL;
+	}
+
+	hw_pdev = of_find_device_by_node(node);
+	of_node_put(node);
+
+	if (WARN_ON(!hw_pdev)) {
+		mtk_v4l2_err("Get hw id(%d) node fail", comp_idx);
+		return NULL;
+	}
+
+	master_dev = platform_get_drvdata(hw_pdev);
+	if (!master_dev) {
+		mtk_v4l2_err("Get hw id(%d) pdev fail", comp_idx);
+		return NULL;
+	}
 
-	spin_lock_irqsave(&dev->irqlock, flags);
-	dev->curr_ctx = ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+	dev->comp_dev[master_dev->comp_idx] = master_dev;
+	return master_dev;
+}
+EXPORT_SYMBOL(mtk_vcodec_get_hw_dev);
+
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	struct mtk_vcodec_ctx *ctx, int comp_idx)
+{
+	unsigned long flags;
+	struct mtk_vdec_comp_dev *comp_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return;
+		}
+		comp_dev->curr_ctx = ctx;
+	} else {
+		vdec_dev->curr_ctx = ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 }
 EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx);
 
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	unsigned int comp_idx)
 {
 	unsigned long flags;
 	struct mtk_vcodec_ctx *ctx;
-
-	spin_lock_irqsave(&dev->irqlock, flags);
-	ctx = dev->curr_ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+	struct mtk_vdec_comp_dev *comp_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return NULL;
+		}
+		ctx = comp_dev->curr_ctx;
+	} else {
+		ctx = vdec_dev->curr_ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 	return ctx;
 }
 EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index b999d7b84ed1..4cb0fc60c94f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -79,8 +79,10 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
 void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx);
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev);
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+				struct mtk_vcodec_ctx *ctx, int comp_idx);
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	unsigned int comp_idx);
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int comp_idx);
 
 #endif /* _MTK_VCODEC_UTIL_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 42008243ceac..05a5b240e906 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -24,21 +24,24 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP8:
 		ctx->dec_if = &vdec_vp8_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP9:
 		ctx->dec_if = &vdec_vp9_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	default:
 		return -EINVAL;
 	}
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	return ret;
@@ -69,13 +72,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 
 	mtk_vdec_lock(ctx);
 
-	mtk_vcodec_set_curr_ctx(ctx->dev, ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
-	enable_irq(ctx->dev->dec_irq);
+	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	disable_irq(ctx->dev->dec_irq);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
-	mtk_vcodec_set_curr_ctx(ctx->dev, NULL);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
+	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
 
 	mtk_vdec_unlock(ctx);
 
@@ -103,9 +104,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 		return;
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	ctx->drv_handle = NULL;
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:43 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:43 +0800
Subject: [PATCH v4, 11/15] media: mtk-vcodec: Add core thread
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-12-yunfei.dong@mediatek.com>

Core thread:
1. Gets lat_buf from core msg queue.
2. Proceeds core decode.
3. Puts the lat_buf back to lat msg queue.

Both H264 and VP9 rely on the core thread.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 12 +++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  7 ++++
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 32 +++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      |  6 ++++
 4 files changed, 57 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 37ecb8252955..05601d911fb4 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -406,6 +406,18 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
+	if (VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
+		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx,
+			MTK_VDEC_CORE);
+		dev->kthread_core = kthread_run(vdec_msg_queue_core_thead, dev,
+			"mtk-%s", "core");
+		if (IS_ERR(dev->kthread_core)) {
+			dev_err(&pdev->dev, "Failed to create core thread");
+			ret = PTR_ERR(dev->kthread_core);
+			goto err_res;
+		}
+	}
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index f1e63acaec76..b6f030a6e55f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -27,6 +27,7 @@
 #define MTK_VCODEC_MAX_PLANES	3
 #define MTK_V4L2_BENCHMARK	0
 #define WAIT_INTR_TIMEOUT_MS	1000
+#define VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
 
 /*
  * enum mtk_hw_reg_idx - MTK hw register base index
@@ -465,6 +466,9 @@ struct mtk_vcodec_enc_pdata {
  *
  * @comp_dev: component hardware device
  * @component_node: component node
+ *
+ * @kthread_core: thread used for core hardware decode
+ * @msg_queue_core_ctx: msg queue context used for core thread
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -505,6 +509,9 @@ struct mtk_vcodec_dev {
 
 	void *comp_dev[MTK_VDEC_HW_MAX];
 	struct device_node *component_node[MTK_VDEC_HW_MAX];
+
+	struct task_struct *kthread_core;
+	struct vdec_msg_queue_ctx msg_queue_core_ctx;
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index d66ed98c79a9..665f571eab4b 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -256,3 +256,35 @@ void vdec_msg_queue_deinit(
 			kfree(lat_buf->private_data);
 	}
 }
+
+int vdec_msg_queue_core_thead(void *data)
+{
+	struct mtk_vcodec_dev *dev = data;
+	struct vdec_lat_buf *lat_buf;
+	struct mtk_vcodec_ctx *ctx;
+
+	set_freezable();
+	for (;;) {
+		try_to_freeze();
+		if (kthread_should_stop())
+			break;
+
+		lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
+		if (!lat_buf)
+			continue;
+
+		ctx = lat_buf->ctx;
+		mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
+
+		if (!lat_buf->core_decode)
+			mtk_v4l2_err("Core decode callback func is NULL");
+		else
+			lat_buf->core_decode(lat_buf);
+
+		mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+		vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
+	}
+
+	mtk_v4l2_debug(3, "Video Capture Thread End");
+	return 0;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
index 1905ce713592..b5745b144140 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -148,4 +148,10 @@ void vdec_msg_queue_deinit(
 	struct vdec_msg_queue *msg_queue,
 	struct mtk_vcodec_ctx *ctx);
 
+/**
+ * vdec_msg_queue_core_thead - used for core decoder.
+ * @data: private data used for each codec
+ */
+int vdec_msg_queue_core_thead(void *data);
+
 #endif
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:40 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:40 +0800
Subject: [PATCH v4,
 08/15] media: mtk-vcodec: Add msg queue feature for lat and core
 architecture
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-9-yunfei.dong@mediatek.com>

For lat and core architecture, lat thread will send message to core
thread when lat decode done. Core hardware will use the message
from lat to decode, then free message to lat thread when decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 258 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 151 ++++++++++
 4 files changed, 415 insertions(+)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index edeb3b66e9e9..5000e59da576 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -11,6 +11,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
+		vdec_msg_queue.o \
 		mtk_vcodec_dec.o \
 		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_stateless.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 08fd43106fc7..4ad0566e715d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -15,7 +15,9 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
+
 #include "mtk_vcodec_util.h"
+#include "vdec_msg_queue.h"
 
 #define MTK_VCODEC_DRV_NAME	"mtk_vcodec_drv"
 #define MTK_VCODEC_DEC_NAME	"mtk-vcodec-dec"
@@ -282,6 +284,8 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ *
+ * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -325,6 +329,7 @@ struct mtk_vcodec_ctx {
 	int decoded_frame_cnt;
 	struct mutex lock;
 
+	struct vdec_msg_queue msg_queue;
 };
 
 enum mtk_chip {
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
new file mode 100644
index 000000000000..d66ed98c79a9
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/freezer.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_drv.h"
+#include "vdec_msg_queue.h"
+
+#define VDEC_LAT_SLICE_HEADER_SZ    (640 * 1024)
+#define VDEC_ERR_MAP_SZ_AVC         ((8192 / 16) * (4352 / 16) / 8)
+
+/* lat write decoded hardware information to trans buffer,
+ * and core will read the trans buffer to decode again. The
+ * trans buffer size of FHD and 4K bitstreams are different.
+ */
+static int vde_msg_queue_get_trans_size(int width, int height)
+{
+	if (width > 1920 || height > 1088)
+		return (30 * 1024 * 1024);
+	else
+		return 6 * 1024 * 1024;
+}
+
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
+	int hardware_index)
+{
+	init_waitqueue_head(&ctx->ready_to_use);
+	INIT_LIST_HEAD(&ctx->ready_queue);
+	spin_lock_init(&ctx->ready_lock);
+	ctx->ready_num = 0;
+	ctx->hardware_index = hardware_index;
+}
+
+int vdec_msg_queue_init(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx,
+	core_decode_cb_t core_decode,
+	int private_size)
+{
+	struct vdec_lat_buf *lat_buf;
+	int i, err;
+
+	/* already init msg queue */
+	if (msg_queue->wdma_addr.size)
+		return 0;
+
+	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+	msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(
+		ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+
+	err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
+	if (err) {
+		mtk_v4l2_err("failed to allocate wdma_addr buf");
+		return -ENOMEM;
+	}
+	msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
+	msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
+
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->wdma_err_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_err_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->slice_bc_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
+		if (!lat_buf->private_data) {
+			mtk_v4l2_err("failed to allocate private_data[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->ctx = ctx;
+		lat_buf->core_decode = core_decode;
+		vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
+	}
+	return 0;
+
+mem_alloc_err:
+	vdec_msg_queue_deinit(msg_queue, ctx);
+	return -ENOMEM;
+}
+
+static struct list_head *vdec_get_buf_list(int hardware_index,
+	struct vdec_lat_buf *buf)
+{
+	switch (hardware_index) {
+	case MTK_VDEC_CORE:
+		return &buf->core_list;
+	case MTK_VDEC_LAT0:
+		return &buf->lat_list;
+	default:
+		return NULL;
+	}
+}
+
+void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
+	struct vdec_lat_buf *buf)
+{
+	struct list_head *head;
+
+	head = vdec_get_buf_list(ctx->hardware_index, buf);
+	if (!head) {
+		mtk_v4l2_err("fail to qbuf: %d",ctx->hardware_index);
+		return;
+	}
+
+	spin_lock(&ctx->ready_lock);
+	list_add_tail(head, &ctx->ready_queue);
+	ctx->ready_num++;
+
+	wake_up_all(&ctx->ready_to_use);
+
+	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
+		ctx->hardware_index, buf, ctx->ready_num);
+	spin_unlock(&ctx->ready_lock);
+}
+
+static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx *ctx)
+{
+	long timeout_jiff;
+	int ret;
+
+	if (ctx->hardware_index == MTK_VDEC_CORE) {
+		ret = wait_event_freezable(ctx->ready_to_use,
+			!list_empty(&ctx->ready_queue));
+		if (ret)
+			return false;
+	} else {
+		timeout_jiff = msecs_to_jiffies(1500);
+		ret = wait_event_timeout(ctx->ready_to_use,
+			!list_empty(&ctx->ready_queue), timeout_jiff);
+		if (!ret)
+			return false;
+	}
+
+	return true;
+}
+
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx)
+{
+	struct vdec_lat_buf *buf;
+	struct list_head *head;
+	int ret;
+
+	spin_lock(&ctx->ready_lock);
+	if (list_empty(&ctx->ready_queue)) {
+		mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d",
+			ctx->hardware_index, ctx->ready_num);
+		spin_unlock(&ctx->ready_lock);
+		ret = vdec_msg_queue_wait_event(ctx);
+		if (!ret)
+			return NULL;
+		spin_lock(&ctx->ready_lock);
+	}
+
+	if (ctx->hardware_index == MTK_VDEC_CORE)
+		buf = list_first_entry(&ctx->ready_queue,
+			struct vdec_lat_buf, core_list);
+	else
+		buf = list_first_entry(&ctx->ready_queue,
+			struct vdec_lat_buf, lat_list);
+
+	head = vdec_get_buf_list(ctx->hardware_index, buf);
+	if (!head) {
+		mtk_v4l2_err("fail to dqbuf: %d",ctx->hardware_index);
+		return NULL;
+	}
+	list_del(head);
+
+	ctx->ready_num--;
+	mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
+		ctx->hardware_index, buf, ctx->ready_num);
+	spin_unlock(&ctx->ready_lock);
+
+	return buf;
+}
+
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_rptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_rptr_addr = ube_rptr;
+	mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_wptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_wptr_addr = ube_wptr;
+	mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx",
+		msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr, ube_wptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
+{
+	long timeout_jiff;
+	int ret;
+
+	timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
+
+	ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
+		msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
+		timeout_jiff);
+	if (ret) {
+		mtk_v4l2_debug(3, "success to get lat buf: %d",
+			msg_queue->lat_ctx.ready_num);
+		return true;
+	}
+	mtk_v4l2_err("failed with lat buf isn't full: %d",
+		msg_queue->lat_ctx.ready_num);
+	return false;
+}
+
+void vdec_msg_queue_deinit(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_lat_buf *lat_buf;
+	struct mtk_vcodec_mem *mem;
+	int i;
+
+	mem = &msg_queue->wdma_addr;
+	if (mem->va)
+		mtk_vcodec_mem_free(ctx, mem);
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		mem = &lat_buf->wdma_err_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		mem = &lat_buf->slice_bc_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		if (lat_buf->private_data)
+			kfree(lat_buf->private_data);
+	}
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
new file mode 100644
index 000000000000..1905ce713592
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _VDEC_MSG_QUEUE_H_
+#define _VDEC_MSG_QUEUE_H_
+
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "mtk_vcodec_util.h"
+
+#define NUM_BUFFER_COUNT 3
+
+struct vdec_lat_buf;
+struct mtk_vcodec_ctx;
+struct mtk_vcodec_dev;
+typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
+
+/**
+ * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be
+ *	                           processed
+ * @ready_used: ready used queue used to signalize when get a job queue
+ * @ready_queue: list of ready lat buffer queues
+ * @ready_lock: spin lock to protect the lat buffer usage
+ * @ready_num: number of buffers ready to be processed
+ * @hardware_index: hardware id that this queue is used for
+ */
+struct vdec_msg_queue_ctx {
+	wait_queue_head_t ready_to_use;
+	struct list_head ready_queue;
+	spinlock_t ready_lock;
+	int ready_num;
+	int hardware_index;
+};
+
+/**
+ * struct vdec_lat_buf - lat buffer message used to store lat
+ *                       info for core decode
+ * @wdma_err_addr: wdma error address used for lat hardware
+ * @slice_bc_addr: slice bc address used for lat hardware
+ * @ts_info: need to set timestamp from output to capture
+ *
+ * @private_data: shared information used to lat and core hardware
+ * @ctx: mtk vcodec context information
+ * @core_decode: different codec use different decode callback function
+ * @lat_list: add lat buffer to lat head list
+ * @core_list: add lat buffer to core head list
+ */
+struct vdec_lat_buf {
+	struct mtk_vcodec_mem wdma_err_addr;
+	struct mtk_vcodec_mem slice_bc_addr;
+	struct vb2_v4l2_buffer ts_info;
+
+	void *private_data;
+	struct mtk_vcodec_ctx *ctx;
+	core_decode_cb_t core_decode;
+	struct list_head lat_list;
+	struct list_head core_list;
+};
+
+/**
+ * struct vdec_msg_queue - used to store lat buffer message
+ * @lat_buf: lat buffer used to store lat buffer information
+ * @wdma_addr: wdma address used for ube
+ * @wdma_rptr_addr: ube read point
+ * @wdma_wptr_addr: ube write point
+ * @lat_ctx: used to store lat buffer list
+ */
+struct vdec_msg_queue {
+	struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
+
+	struct mtk_vcodec_mem wdma_addr;
+	uint64_t wdma_rptr_addr;
+	uint64_t wdma_wptr_addr;
+
+	struct vdec_msg_queue_ctx lat_ctx;
+};
+
+/**
+ * vdec_msg_queue_init - init lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ * @core_decode: core decode callback for each codec
+ * @private_size: the private data size used to share with core
+ */
+int vdec_msg_queue_init(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx,
+	core_decode_cb_t core_decode,
+	int private_size);
+
+/**
+ * vdec_msg_queue_init_ctx - used to init msg queue context information.
+ * @ctx: message queue context
+ * @hardware_index: hardware index
+ */
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
+	int hardware_index);
+
+/**
+ * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
+ * @ctx: message queue context
+ * @buf: current lat buffer
+ */
+void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
+	struct vdec_lat_buf *buf);
+
+/**
+ * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
+ * @ctx: message queue context
+ */
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx);
+
+/**
+ * vdec_msg_queue_update_ube_rptr - used to updata the ube read point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_rptr: current ube read point
+ */
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_rptr);
+
+/**
+ * vdec_msg_queue_update_ube_wptr - used to updata the ube write point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_wptr: current ube write point
+ */
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_wptr);
+
+/**
+ * vdec_msg_queue_wait_lat_buf_full - used to check whether all lat buffer
+ *                                    in lat list.
+ * @msg_queue: used to store the lat buffer information
+ */
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue);
+
+/**
+ * vdec_msg_queue_deinit - deinit lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ */
+void vdec_msg_queue_deinit(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx);
+
+#endif
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:46 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:46 +0800
Subject: [PATCH v4, 14/15] media: mtk-vcodec: Add core dec and dec end ipi msg
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-15-yunfei.dong@mediatek.com>

Add core dec and dec end ipi msg: AP_IPIMSG_DEC_CORE/AP_IPIMSG_DEC_CORE_END.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h   |  4 ++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c    | 12 ++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h    | 18 ++++++++++++++++++
 3 files changed, 34 insertions(+)
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 5f45a537beb4..9d8079c4f976 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -18,12 +18,16 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_END = 0xA002,
 	AP_IPIMSG_DEC_DEINIT = 0xA003,
 	AP_IPIMSG_DEC_RESET = 0xA004,
+	AP_IPIMSG_DEC_CORE = 0xA005,
+	AP_IPIMSG_DEC_CORE_END = 0xA006,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
 	VPU_IPIMSG_DEC_END_ACK = 0xB002,
 	VPU_IPIMSG_DEC_DEINIT_ACK = 0xB003,
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
+	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
+	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 5dffc459a33d..bfd8e87dceff 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -85,6 +85,8 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_END_ACK:
 		case VPU_IPIMSG_DEC_DEINIT_ACK:
 		case VPU_IPIMSG_DEC_RESET_ACK:
+		case VPU_IPIMSG_DEC_CORE_ACK:
+		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
 		default:
@@ -191,11 +193,21 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_core(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
+}
+
 int vpu_dec_end(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_END);
 }
 
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE_END);
+}
+
 int vpu_dec_deinit(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_DEINIT);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index c2ed5b6cab8b..ae24b75d1649 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -82,4 +82,22 @@ int vpu_dec_deinit(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_reset(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_core - core start decoding, basically the function will be invoked once
+ *                 every frame.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core(struct vdec_vpu_inst *vpu);
+
+/**
+ * vpu_dec_core_end - core end decoding, basically the function will be invoked once
+ *               when core HW decoding done and receive interrupt successfully. The
+ *               decoder in VPU will updata hardware information and deinit hardware
+ *               and check if there is a new decoded frame available to display.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
+
 #endif
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:35 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:35 +0800
Subject: [PATCH v4, 03/15] media: mtk-vcodec: Refactor vcodec pm interface
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-4-yunfei.dong@mediatek.com>

Using the needed param for pm init/release function and remove unused
param mtkdev in 'struct mtk_vcodec_pm'.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4, no change
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 22 ++++++++-----------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  5 +++--
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
 5 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 8db9cdc66043..dd749d41c75a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -249,7 +249,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev);
+	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
 		goto err_dec_pm;
@@ -379,7 +379,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -422,7 +422,7 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_dec);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 6038db96f71c..20bd157a855c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -13,18 +13,15 @@
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+	struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
-	struct platform_device *pdev;
-	struct mtk_vcodec_pm *pm;
+	struct platform_device *larb_pdev;
 	struct mtk_vcodec_clk *dec_clk;
 	struct mtk_vcodec_clk_info *clk_info;
 	int i = 0, ret = 0;
 
-	pdev = mtkdev->plat_dev;
-	pm = &mtkdev->pm;
-	pm->mtkdev = mtkdev;
 	dec_clk = &pm->vdec_clk;
 	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
 	if (!node) {
@@ -32,13 +29,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 		return -1;
 	}
 
-	pdev = of_find_device_by_node(node);
+	larb_pdev = of_find_device_by_node(node);
 	of_node_put(node);
-	if (WARN_ON(!pdev)) {
+	if (WARN_ON(!larb_pdev)) {
 		return -1;
 	}
-	pm->larbvdec = &pdev->dev;
-	pdev = mtkdev->plat_dev;
+	pm->larbvdec = &larb_pdev->dev;
 	pm->dev = &pdev->dev;
 
 	dec_clk->clk_num =
@@ -82,10 +78,10 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 	return ret;
 }
 
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 {
-	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvdec);
+	pm_runtime_disable(pm->dev);
+	put_device(pm->larbvdec);
 }
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 280aeaefdb65..a3df6aef6cb9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -9,8 +9,9 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+	struct mtk_vcodec_pm *pm);
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 3b1e5e3a450e..973b0b3649c6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -195,7 +195,6 @@ struct mtk_vcodec_pm {
 	struct mtk_vcodec_clk	venc_clk;
 	struct device	*larbvenc;
 	struct device	*dev;
-	struct mtk_vcodec_dev	*mtkdev;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 1b2e4930ed27..0c8c8f86788c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -26,7 +26,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
 	pdev = mtkdev->plat_dev;
 	pm = &mtkdev->pm;
 	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
-	pm->mtkdev = mtkdev;
 	pm->dev = &pdev->dev;
 	dev = &pdev->dev;
 	enc_clk = &pm->venc_clk;
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:33 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:33 +0800
Subject: [PATCH v4,
 01/15] media: mtk-vcodec: Get numbers of register bases from DT
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-2-yunfei.dong@mediatek.com>

Different platform may has different numbers of register bases. Gets the
numbers of register bases from DT (sizeof(u32) * 4 bytes for each).

Change-Id: I7af216c85ee72d55760eae79c20cc212c3b537c1
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: fix comments
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 37 ++++++++++++++-----
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 55ae198dbcf9..983e0f2831af 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -78,6 +78,30 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	return IRQ_HANDLED;
 }
 
+static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int reg_num, i;
+
+	/* Sizeof(u32) * 4 bytes for each register base. */
+	reg_num = of_property_count_elems_of_size(pdev->dev.of_node, "reg",
+		sizeof(u32) * 4);
+	if (reg_num <= 0 || reg_num > NUM_MAX_VDEC_REG_BASE) {
+		dev_err(&pdev->dev, "Invalid register property size: %d\n", reg_num);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < reg_num; i++) {
+		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
+		if (IS_ERR(dev->reg_base[i]))
+			return PTR_ERR(dev->reg_base[i]);
+
+		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -206,7 +230,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int i, ret;
+	int ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -238,14 +262,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) {
-		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
-		if (IS_ERR((__force void *)dev->reg_base[i])) {
-			ret = PTR_ERR((__force void *)dev->reg_base[i]);
-			goto err_res;
-		}
-		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
-	}
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		goto err_res;
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (res == NULL) {
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:32 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:32 +0800
Subject: [PATCH v4,
 00/15] Using component framework to support multi hardware decode
Message-ID: <20210810083047.16693-1-yunfei.dong@mediatek.com>

This series adds support for multi hardware decode into mtk-vcodec, by first
adding component framework to manage each hardware information: interrupt,
clock, register bases and power. Secondly add core thread to deal with core
hardware message, at the same time, add msg queue for different hardware
share messages. Lastly, the architecture of different specs are not the same,
using specs type to separate them.

This series has been tested with both MT8183 and MT8173. Decoding was working
for both chips.

Patches 1~3 rewrite get register bases and power on/off interface.

Patch 4 add component framework to support multi hardware.

Patch 5 separate video encoder and decoder document

Patches 6-15 add interfaces to support core hardware.
----
This patch dependents on "media: mtk-vcodec: support for MT8183 decoder"[1].

Multi hardware decode is based on stateless decoder, MT8183 is the first time
to add stateless decoder. Otherwise it will cause conflict. Please also accept
this patch together with [1].

[1]https://lore.kernel.org/patchwork/project/lkml/list/?series=507084
----
Changes compared with v3:
- Fix return value for patch 1/15
- Fix comments for patch 4/15
  > Looking up "mediatek,mtk-vcodec-core" to determine if it uses component framwork sounds like...
  Add prameter in pdata, for all platform will use compoent after mt8183

  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  > + Has asked the same question in [1].  Why it removes the
  > +platform_set_drvdata() above?  mtk_vcodec_init_master() also calls platform_set_drvdata().
  Must call component_master_add_with_match after platform_set_drvdata for component architecture.
- Fix yaml files check fail for patch 5/15
- Fix yaml file check fail for patch 14/15

Changes compared with v1:
- Fix many comments for patch 3/14
- Remove unnecessary code for patch 4/14
- Using enum mtk_vdec_hw_count instead of magic numbers for patch 6/14
- Reconstructed get/put lat buffer for lat and core hardware for patch 7/14
- Using yaml format to instead of txt file for patch 12/14

Yunfei Dong (15):
  media: mtk-vcodec: Get numbers of register bases from DT
  media: mtk-vcodec: Align vcodec wake up interrupt interface
  media: mtk-vcodec: Refactor vcodec pm interface
  media: mtk-vcodec: Use component framework to manage each hardware
    information
  dt-bindings: media: mtk-vcodec: Separate video encoder and decoder
    dt-bindings
  media: mtk-vcodec: Use pure single core for MT8183
  media: mtk-vcodec: Add irq interface for multi hardware
  media: mtk-vcodec: Add msg queue feature for lat and core architecture
  media: mtk-vcodec: Generalize power and clock on/off interfaces
  media: mtk-vcodec: Add new interface to lock different hardware
  media: mtk-vcodec: Add core thread
  media: mtk-vcodec: Support 34bits dma address for vdec
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192
  media: mtk-vcodec: Add core dec and dec end ipi msg
  media: mtk-vcodec: Use codec type to separate different hardware

 .../media/mediatek,vcodec-comp-decoder.yaml   | 172 +++++++++++
 .../media/mediatek,vcodec-decoder.yaml        | 175 +++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 185 +++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 130 --------
 drivers/media/platform/mtk-vcodec/Makefile    |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 280 ++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 184 +++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  53 ++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   |  98 ++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  13 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   2 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  71 ++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  12 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |   1 -
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     |  27 +-
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  87 +++++-
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   8 +-
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |   2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |   2 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  21 +-
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  16 +-
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 290 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 157 ++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  46 ++-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  22 ++
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |   2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |   2 +-
 33 files changed, 1795 insertions(+), 280 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:47 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:47 +0800
Subject: [PATCH v4,
 15/15] media: mtk-vcodec: Use codec type to separate different
 hardware
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-16-yunfei.dong@mediatek.com>

There are just one core thread, in order to separeate different
hardware, using codec type to separeate it in scp driver.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 12 ++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 34 ++++++++++++++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  4 +++
 3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 9d8079c4f976..c488f0c40190 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -35,6 +35,8 @@ enum vdec_ipi_msgid {
  * @msg_id	: vdec_ipi_msgid
  * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
  * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @codec_type	: Codec fourcc
+ * @reserved	: reserved param
  */
 struct vdec_ap_ipi_cmd {
 	uint32_t msg_id;
@@ -42,6 +44,8 @@ struct vdec_ap_ipi_cmd {
 		uint32_t vpu_inst_addr;
 		uint32_t inst_id;
 	};
+	uint32_t codec_type;
+	uint32_t reserved;
 };
 
 /**
@@ -59,12 +63,12 @@ struct vdec_vpu_ipi_ack {
 /**
  * struct vdec_ap_ipi_init - for AP_IPIMSG_DEC_INIT
  * @msg_id	: AP_IPIMSG_DEC_INIT
- * @reserved	: Reserved field
+ * @codec_type	: Codec fourcc
  * @ap_inst_addr	: AP video decoder instance address
  */
 struct vdec_ap_ipi_init {
 	uint32_t msg_id;
-	uint32_t reserved;
+	uint32_t codec_type;
 	uint64_t ap_inst_addr;
 };
 
@@ -77,7 +81,7 @@ struct vdec_ap_ipi_init {
  *	H264 decoder [0]:buf_sz [1]:nal_start
  *	VP8 decoder  [0]:width/height
  *	VP9 decoder  [0]:profile, [1][2] width/height
- * @reserved	: Reserved field
+ * @codec_type	: Codec fourcc
  */
 struct vdec_ap_ipi_dec_start {
 	uint32_t msg_id;
@@ -86,7 +90,7 @@ struct vdec_ap_ipi_dec_start {
 		uint32_t inst_id;
 	};
 	uint32_t data[3];
-	uint32_t reserved;
+	uint32_t codec_type;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index bfd8e87dceff..c84fac52fe26 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -100,18 +100,29 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 
 static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
 {
-	int err;
+	int err, id, msgid;
 
-	mtk_vcodec_debug(vpu, "id=%X", *(uint32_t *)msg);
+	msgid = *(uint32_t *)msg;
+	mtk_vcodec_debug(vpu, "id=%X", msgid);
 
 	vpu->failure = 0;
 	vpu->signaled = 0;
 
-	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, vpu->id, msg,
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		if (msgid == AP_IPIMSG_DEC_CORE ||
+			msgid == AP_IPIMSG_DEC_CORE_END)
+			id = vpu->core_id;
+		else
+			id = vpu->id;
+	} else {
+		id = vpu->id;
+	}
+
+	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg,
 				     len, 2000);
 	if (err) {
 		mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d",
-			       vpu->id, *(uint32_t *)msg, err);
+			       id, msgid, err);
 		return err;
 	}
 
@@ -131,6 +142,7 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id)
 		msg.vpu_inst_addr = vpu->inst_addr;
 	else
 		msg.inst_id = vpu->inst_id;
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err);
@@ -149,14 +161,25 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu)
 
 	err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id,
 					 vpu->handler, "vdec", NULL);
-	if (err != 0) {
+	if (err) {
 		mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err);
 		return err;
 	}
 
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler,
+					 vpu->core_id, vpu->handler,
+					 "vdec", NULL);
+		if (err) {
+			mtk_vcodec_err(vpu, "vpu_ipi_register core fail status=%d", err);
+			return err;
+		}
+	}
+
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_id = AP_IPIMSG_DEC_INIT;
 	msg.ap_inst_addr = (unsigned long)vpu;
+	msg.codec_type = vpu->codec_type;
 
 	mtk_vcodec_debug(vpu, "vdec_inst=%p", vpu);
 
@@ -187,6 +210,7 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 
 	for (i = 0; i < len; i++)
 		msg.data[i] = data[i];
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- ret=%d", err);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index ae24b75d1649..802660770a87 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -14,6 +14,7 @@ struct mtk_vcodec_ctx;
 /**
  * struct vdec_vpu_inst - VPU instance for video codec
  * @id          : ipi msg id for each decoder
+ * @core_id     : core id used to separate different hardware
  * @vsi         : driver structure allocated by VPU side and shared to AP side
  *                for control and info share
  * @failure     : VPU execution result status, 0: success, others: fail
@@ -26,9 +27,11 @@ struct mtk_vcodec_ctx;
  * @dev		: platform device of VPU
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
+ * @codec_type     : used codec type to separate different codecs
  */
 struct vdec_vpu_inst {
 	int id;
+	int core_id;
 	void *vsi;
 	int32_t failure;
 	uint32_t inst_addr;
@@ -38,6 +41,7 @@ struct vdec_vpu_inst {
 	struct mtk_vcodec_ctx *ctx;
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
+	unsigned int codec_type;
 };
 
 /**
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:44 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:44 +0800
Subject: [PATCH v4,
 12/15] media: mtk-vcodec: Support 34bits dma address for vdec
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-13-yunfei.dong@mediatek.com>

Use the dma_set_mask_and_coherent helper to set vdec
DMA bit mask to support 34bits iova space(16GB) that
the mt8192 iommu HW support.

Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G,
regarding which iova range VDEC actually locate, it
depends on the dma-ranges property of vdec dtsi node.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 05601d911fb4..6c3268778fb3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -418,6 +418,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:45 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:45 +0800
Subject: [PATCH v4,
 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8192
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-14-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for mt8192.

Change-Id: I2c482fa6c0a91b5fc4f1950dd563cbc4d6c35da1
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: fix yaml file check fail
---
 .../media/mediatek,vcodec-comp-decoder.yaml   | 172 ++++++++++++++++++
 1 file changed, 172 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
new file mode 100644
index 000000000000..083c89933917
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities. Required
+  master and component node.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - mediatek,mt8192-vcodec-dec  # for lat hardware
+          - mediatek,mtk-vcodec-lat     # for core hardware
+          - mediatek,mtk-vcodec-core
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 5
+
+  clock-names:
+    items:
+      - const: vdec-sel
+      - const: vdec-soc-vdec
+      - const: vdec-soc-lat
+      - const: vdec-vdec
+      - const: vdec-top
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+      - compatible
+      - reg
+      - iommus
+      - dma-ranges
+
+allOf:
+  - if: #master node
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8192-vcodec-dec  # for lat hardware
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if: #component node
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mtk-vcodec-lat     # for core hardware
+              - mediatek,mtk-vcodec-core
+
+    then:
+      required:
+        - interrupts
+        - clocks
+        - clock-names
+        - assigned-clocks
+        - assigned-clock-parents
+        - power-domains
+
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/memory/mt8192-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mt8192-clk.h>
+    #include <dt-bindings/power/mt8192-power.h>
+
+    vcodec_dec: vcodec_dec at 16000000 {
+        compatible = "mediatek,mt8192-vcodec-dec";
+        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
+        mediatek,scp = <&scp>;
+        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+    };
+
+    vcodec_lat: vcodec_lat at 0x16010000 {
+        compatible = "mediatek,mtk-vcodec-lat";
+        reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
+        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
+        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
+             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
+             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
+             <&topckgen CLK_TOP_MAINPLL_D4>;
+        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
+              "vdec-vdec", "vdec-top";
+        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
+    };
+
+    vcodec_core: vcodec_core at 0x16025000 {
+        compatible = "mediatek,mtk-vcodec-core";
+        reg = <0 0x16025000 0 0x1000>;		/* VDEC_CORE_MISC */
+        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
+        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+             <&vdecsys CLK_VDEC_VDEC>,
+             <&vdecsys CLK_VDEC_LAT>,
+             <&vdecsys CLK_VDEC_LARB1>,
+             <&topckgen CLK_TOP_MAINPLL_D4>;
+        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
+              "vdec-vdec", "vdec-top";
+        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
+    };
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:39 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:39 +0800
Subject: [PATCH v4,
 07/15] media: mtk-vcodec: Add irq interface for multi hardware
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-8-yunfei.dong@mediatek.com>

Adds irq interface for multi hardware.

Change-Id: I9ed8f9538c83d9376a70bc125f77686ac85cedb9
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 33 +++++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 25 ++++++++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  4 +--
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     | 27 +++++++--------
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |  4 +--
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |  2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |  2 +-
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |  2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  2 +-
 12 files changed, 71 insertions(+), 36 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index d93ea5c63e1e..d52e975292dc 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -68,6 +68,20 @@ static const struct component_master_ops mtk_vdec_ops = {
    .unbind = mtk_vdec_unbind,
 };
 
+static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev)
+{
+	switch (dev->vdec_pdata->hw_arch) {
+	case MTK_VDEC_PURE_SINGLE_CORE:
+		return MTK_VDEC_ONE_CORE;
+	case MTK_VDEC_LAT_SINGLE_CORE:
+		return MTK_VDEC_ONE_LAT_ONE_CORE;
+	default:
+		mtk_v4l2_err("not support hw arch:%d",
+			dev->vdec_pdata->hw_arch);
+		return MTK_VDEC_NO_HW;
+	}
+}
+
 static struct component_match *mtk_vcodec_match_add(
 	struct mtk_vcodec_dev *vdec_dev)
  {
@@ -134,7 +148,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
 		dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
@@ -224,7 +238,7 @@ static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
 	struct mtk_vcodec_ctx *ctx = NULL;
-	int ret = 0;
+	int ret = 0, i, hw_count;
 	struct vb2_queue *src_vq;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -238,7 +252,19 @@ static int fops_vcodec_open(struct file *file)
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
-	init_waitqueue_head(&ctx->queue);
+
+	if (ctx->dev->vdec_pdata->is_comp_supported) {
+		hw_count = mtk_vcodec_get_hw_count(dev);
+		if (!hw_count) {
+			ret = -EINVAL;
+			goto err_init_queue;
+		}
+		for (i = 0; i < hw_count; i++)
+			init_waitqueue_head(&ctx->queue[i]);
+	} else {
+		init_waitqueue_head(&ctx->queue[0]);
+	}
+
 	mutex_init(&ctx->lock);
 
 	ctx->type = MTK_INST_DECODER;
@@ -295,6 +321,7 @@ static int fops_vcodec_open(struct file *file)
 err_m2m_ctx_init:
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 err_ctrls_setup:
+err_init_queue:
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	kfree(ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 5e1b7670ba5b..7a31afd294ba 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -87,7 +87,7 @@ static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
 	writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
 	writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->comp_idx);
 
 	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
 		ctx->id, dec_done_status);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 1d0798fd9adf..08fd43106fc7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -104,6 +104,16 @@ enum mtk_vdec_hw_id {
 	MTK_VDEC_HW_MAX,
 };
 
+/**
+ * struct mtk_vdec_hw_count - Supported hardware count
+ */
+enum mtk_vdec_hw_count {
+	MTK_VDEC_NO_HW = 0,
+	MTK_VDEC_ONE_CORE,
+	MTK_VDEC_ONE_LAT_ONE_CORE,
+	MTK_VDEC_MAX_HW_COUNT,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -293,9 +303,9 @@ struct mtk_vcodec_ctx {
 	struct vdec_pic_info picinfo;
 	int dpb_size;
 
-	int int_cond;
-	int int_type;
-	wait_queue_head_t queue;
+	int int_cond[MTK_VDEC_HW_MAX];
+	int int_type[MTK_VDEC_HW_MAX];
+	wait_queue_head_t queue[MTK_VDEC_HW_MAX];
 	unsigned int irq_status;
 
 	struct v4l2_ctrl_handler ctrl_hdl;
@@ -501,11 +511,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 }
 
 /* Wake up context wait_queue */
-static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason,
+	unsigned int hw_id)
 {
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
+	ctx->int_cond[hw_id] = 1;
+	ctx->int_type[hw_id] = reason;
+	wake_up_interruptible(&ctx->queue[hw_id]);
 }
 
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 2828df77020c..c7540c0cdcea 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -114,7 +114,7 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
 
 	clean_irq_status(ctx->irq_status, addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
 	return IRQ_HANDLED;
 }
 
@@ -140,7 +140,7 @@ static int fops_vcodec_open(struct file *file)
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
-	init_waitqueue_head(&ctx->queue);
+	init_waitqueue_head(&ctx->queue[0]);
 
 	ctx->type = MTK_INST_ENCODER;
 	ret = mtk_vcodec_enc_ctrls_setup(ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
index 70580c2525ba..8147533da98b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
@@ -11,34 +11,31 @@
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx  *ctx, int command,
-				 unsigned int timeout_ms)
+int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
+	int command, unsigned int timeout_ms, unsigned hw_id)
 {
-	wait_queue_head_t *waitqueue;
 	long timeout_jiff, ret;
 	int status = 0;
 
-	waitqueue = (wait_queue_head_t *)&ctx->queue;
 	timeout_jiff = msecs_to_jiffies(timeout_ms);
-
-	ret = wait_event_interruptible_timeout(*waitqueue,
-				ctx->int_cond,
+	ret = wait_event_interruptible_timeout(ctx->queue[hw_id],
+				ctx->int_cond[hw_id],
 				timeout_jiff);
 
 	if (!ret) {
 		status = -1;	/* timeout */
-		mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout time=%ums out %d %d!",
-			     ctx->id, ctx->type, command, timeout_ms,
-			     ctx->int_cond, ctx->int_type);
+		mtk_v4l2_err("[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)",
+				ctx->id, command, ctx->type, timeout_ms,
+				ctx->int_cond[hw_id], ctx->int_type[hw_id]);
 	} else if (-ERESTARTSYS == ret) {
-		mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout interrupted by a signal %d %d",
-			     ctx->id, ctx->type, command, ctx->int_cond,
-			     ctx->int_type);
 		status = -1;
+		mtk_v4l2_err("[%d] cmd=%d, type=%d, dec inter fail (%d %d)",
+				ctx->id, command, ctx->type,
+				ctx->int_cond[hw_id], ctx->int_type[hw_id]);
 	}
 
-	ctx->int_cond = 0;
-	ctx->int_type = 0;
+	ctx->int_cond[hw_id] = 0;
+	ctx->int_type[hw_id] = 0;
 
 	return status;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
index 638cd1f3526a..2bf4cabfaa43 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
@@ -12,7 +12,7 @@
 struct mtk_vcodec_ctx;
 
 /* timeout is ms */
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *data, int command,
-				unsigned int timeout_ms);
+int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
+				int command, unsigned int timeout_ms, unsigned int hw_id);
 
 #endif /* _MTK_VCODEC_INTR_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
index 40d6e6c5ac7a..481655bb6016 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
@@ -413,7 +413,7 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 		/* wait decoder done interrupt */
 		err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
 						   MTK_INST_IRQ_RECEIVED,
-						   WAIT_INTR_TIMEOUT_MS);
+						   WAIT_INTR_TIMEOUT_MS, 0);
 		if (err)
 			goto err_free_fb_out;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 4dde9ee786b4..d23baa364246 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -724,7 +724,7 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 	/* wait decoder done interrupt */
 	err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
 					   MTK_INST_IRQ_RECEIVED,
-					   WAIT_INTR_TIMEOUT_MS);
+					   WAIT_INTR_TIMEOUT_MS, 0);
 	if (err)
 		goto err_free_fb_out;
 	vpu_dec_end(vpu);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
index e5393f841080..88c046731754 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
@@ -488,7 +488,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	/* wait decoder done interrupt */
 	mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
-				     WAIT_INTR_TIMEOUT_MS);
+				     WAIT_INTR_TIMEOUT_MS, 0);
 
 	if (inst->vsi->load_data)
 		load_dec_table(inst);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
index 71cdc3ddafcb..70b8383f7c8e 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
@@ -539,7 +539,7 @@ static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst)
 
 	mtk_vcodec_wait_for_done_ctx(inst->ctx,
 			MTK_INST_IRQ_RECEIVED,
-			WAIT_INTR_TIMEOUT_MS);
+			WAIT_INTR_TIMEOUT_MS, 0);
 
 	if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
 		return true;
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index b6a4f2074fa5..9ae1bd8dbc32 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -335,7 +335,7 @@ static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
 	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 
 	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
-					  WAIT_INTR_TIMEOUT_MS)) {
+					  WAIT_INTR_TIMEOUT_MS, 0)) {
 		irq_status = ctx->irq_status;
 		mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
 	}
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index 8267a9c4fd25..f96564277577 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -222,7 +222,7 @@ static unsigned int vp8_enc_wait_venc_done(struct venc_vp8_inst *inst)
 	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 
 	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
-					  WAIT_INTR_TIMEOUT_MS)) {
+					  WAIT_INTR_TIMEOUT_MS, 0)) {
 		irq_status = ctx->irq_status;
 		mtk_vcodec_debug(inst, "isr return %x", irq_status);
 	}
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 01:30:34 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 10 Aug 2021 16:30:34 +0800
Subject: [PATCH v4,
 02/15] media: mtk-vcodec: Align vcodec wake up interrupt interface
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <20210810083047.16693-3-yunfei.dong@mediatek.com>

Vdec and venc can use the same function to wake up interrupt event.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v4: no change
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 9 +--------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 8 ++++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 8 --------
 3 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 983e0f2831af..8db9cdc66043 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -31,13 +31,6 @@
 module_param(mtk_v4l2_dbg_level, int, 0644);
 module_param(mtk_vcodec_dbg, bool, 0644);
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx)
-{
-	ctx->int_cond = 1;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -69,7 +62,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
 		dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
 
-	wake_up_ctx(ctx);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index d4f840a7bbcb..3b1e5e3a450e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -472,4 +472,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 	return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl);
 }
 
+/* Wake up context wait_queue */
+static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+{
+	ctx->int_cond = 1;
+	ctx->int_type = reason;
+	wake_up_interruptible(&ctx->queue);
+}
+
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 4167e865b23f..2828df77020c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -73,14 +73,6 @@ static const struct mtk_video_fmt mtk_video_formats_capture_mt8183[] =  {
 	},
 };
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
-{
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
 {
 	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
-- 
2.25.1

From matthias.bgg at gmail.com  Tue Aug 10 01:35:18 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 10 Aug 2021 10:35:18 +0200
Subject: [PATCH v2 5/5] drm/mediatek: Add support for main DDP path on
 MT8167
In-Reply-To: <CAOwMV_wzp67zeiSvXP59OLMwd_8srfSTSqV9BwXagq5gFu6B3g@mail.gmail.com>
References: <20201023133130.194140-1-fparent@baylibre.com>
 <20201023133130.194140-6-fparent@baylibre.com>
 <CAAOTY_8ZgoQJFnEDDZ=JCy-3zLwn7yjk1EHVYgeSG2ufLxK04g@mail.gmail.com>
 <CAOwMV_wzp67zeiSvXP59OLMwd_8srfSTSqV9BwXagq5gFu6B3g@mail.gmail.com>
Message-ID: <43fb2cda-5fed-f770-35d7-ed59db7dbae5@gmail.com>



On 27/10/2020 17:08, Fabien Parent wrote:
> Hi Chun-Kuang,
> 
> On Fri, Oct 23, 2020 at 5:52 PM Chun-Kuang Hu <chunkuang.hu at kernel.org> wrote:
>>
>> Hi, Fabien:
>>
>> Fabien Parent <fparent at baylibre.com> ? 2020?10?23? ?? ??9:31???
>>>
>>> Add the main (DSI) drm display path for MT8167.
>>>
>>> Signed-off-by: Fabien Parent <fparent at baylibre.com>
>>> ---
>>>
>>> Changelog:
>>>
>>> V2: No change
>>>
>>>  drivers/gpu/drm/mediatek/mtk_drm_drv.c | 38 ++++++++++++++++++++++++++
>>>  1 file changed, 38 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
>>> index 59c85c63b7cc..3952435093fe 100644
>>> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
>>> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
>>> @@ -112,6 +112,17 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = {
>>>         DDP_COMPONENT_PWM2,
>>>  };
>>>
>>> +static enum mtk_ddp_comp_id mt8167_mtk_ddp_main[] = {
>>> +       DDP_COMPONENT_OVL0,
>>> +       DDP_COMPONENT_COLOR0,
>>> +       DDP_COMPONENT_CCORR,
>>> +       DDP_COMPONENT_AAL0,
>>> +       DDP_COMPONENT_GAMMA,
>>> +       DDP_COMPONENT_DITHER,
>>> +       DDP_COMPONENT_RDMA0,
>>> +       DDP_COMPONENT_DSI0,
>>> +};
>>> +
>>>  static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
>>>         DDP_COMPONENT_OVL0,
>>>         DDP_COMPONENT_COLOR0,
>>> @@ -163,6 +174,11 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
>>>         .ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
>>>  };
>>>
>>> +static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
>>> +       .main_path = mt8167_mtk_ddp_main,
>>> +       .main_len = ARRAY_SIZE(mt8167_mtk_ddp_main),
>>> +};
>>> +
>>>  static int mtk_drm_kms_init(struct drm_device *drm)
>>>  {
>>>         struct mtk_drm_private *private = drm->dev_private;
>>> @@ -401,26 +417,42 @@ static const struct component_master_ops mtk_drm_ops = {
>>>  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>>>         { .compatible = "mediatek,mt2701-disp-ovl",
>>>           .data = (void *)MTK_DISP_OVL },
>>> +       { .compatible = "mediatek,mt8167-disp-ovl",
>>> +         .data = (void *)MTK_DISP_OVL },
>>>         { .compatible = "mediatek,mt8173-disp-ovl",
>>>           .data = (void *)MTK_DISP_OVL },
>>>         { .compatible = "mediatek,mt2701-disp-rdma",
>>>           .data = (void *)MTK_DISP_RDMA },
>>> +       { .compatible = "mediatek,mt8167-disp-rdma",
>>> +         .data = (void *)MTK_DISP_RDMA },
>>>         { .compatible = "mediatek,mt8173-disp-rdma",
>>>           .data = (void *)MTK_DISP_RDMA },
>>>         { .compatible = "mediatek,mt8173-disp-wdma",
>>>           .data = (void *)MTK_DISP_WDMA },
>>> +       { .compatible = "mediatek,mt8167-disp-ccorr",
>>> +         .data = (void *)MTK_DISP_CCORR },
>>>         { .compatible = "mediatek,mt2701-disp-color",
>>>           .data = (void *)MTK_DISP_COLOR },
>>> +       { .compatible = "mediatek,mt8167-disp-color",
>>> +         .data = (void *)MTK_DISP_COLOR },
>>>         { .compatible = "mediatek,mt8173-disp-color",
>>>           .data = (void *)MTK_DISP_COLOR },
>>> +       { .compatible = "mediatek,mt8167-disp-aal",
>>> +         .data = (void *)MTK_DISP_AAL},
>>>         { .compatible = "mediatek,mt8173-disp-aal",
>>>           .data = (void *)MTK_DISP_AAL},
>>> +       { .compatible = "mediatek,mt8167-disp-gamma",
>>> +         .data = (void *)MTK_DISP_GAMMA, },
>>>         { .compatible = "mediatek,mt8173-disp-gamma",
>>>           .data = (void *)MTK_DISP_GAMMA, },
>>> +       { .compatible = "mediatek,mt8167-disp-dither",
>>> +         .data = (void *)MTK_DISP_DITHER },
>>>         { .compatible = "mediatek,mt8173-disp-ufoe",
>>>           .data = (void *)MTK_DISP_UFOE },
>>>         { .compatible = "mediatek,mt2701-dsi",
>>>           .data = (void *)MTK_DSI },
>>> +       { .compatible = "mediatek,mt8167-dsi",
>>> +         .data = (void *)MTK_DSI },
>>>         { .compatible = "mediatek,mt8173-dsi",
>>>           .data = (void *)MTK_DSI },
>>>         { .compatible = "mediatek,mt2701-dpi",
>>> @@ -431,10 +463,14 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>>>           .data = (void *)MTK_DISP_MUTEX },
>>>         { .compatible = "mediatek,mt2712-disp-mutex",
>>>           .data = (void *)MTK_DISP_MUTEX },
>>> +       { .compatible = "mediatek,mt8167-disp-mutex",
>>> +         .data = (void *)MTK_DISP_MUTEX },
>>>         { .compatible = "mediatek,mt8173-disp-mutex",
>>>           .data = (void *)MTK_DISP_MUTEX },
>>>         { .compatible = "mediatek,mt2701-disp-pwm",
>>>           .data = (void *)MTK_DISP_BLS },
>>> +       { .compatible = "mediatek,mt8167-disp-pwm",
>>> +         .data = (void *)MTK_DISP_PWM },
>>>         { .compatible = "mediatek,mt8173-disp-pwm",
>>>           .data = (void *)MTK_DISP_PWM },
>>>         { .compatible = "mediatek,mt8173-disp-od",
>>> @@ -449,6 +485,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
>>>           .data = &mt7623_mmsys_driver_data},
>>>         { .compatible = "mediatek,mt2712-mmsys",
>>>           .data = &mt2712_mmsys_driver_data},
>>> +       { .compatible = "mediatek,mt8167-mmsys",
>>
>> This patch looks good to me, but it depend on another patch which
>> define the compatible "mediatek,mt8167-mmsys". Where is that patch?
> 
> You can find the patch there:
> https://patchwork.kernel.org/project/linux-mediatek/patch/20201027160631.608503-2-fparent at baylibre.com/
> 

Driver is upstream since v5.13 with:
e7be7853ab1b ("dt-bindings: mediatek: mmsys: add mt8167 binding")

060f7875bd23 ("soc: mediatek: mmsys: Add support for MT8167 SoC")


Regards,
Matthias

>>
>> Regards,
>> Chun-Kuang.
>>
>>> +         .data = &mt8167_mmsys_driver_data},
>>>         { .compatible = "mediatek,mt8173-mmsys",
>>>           .data = &mt8173_mmsys_driver_data},
>>>         { }
>>> --
>>> 2.28.0
>>>


From narmstrong at baylibre.com  Tue Aug 10 01:40:02 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 10 Aug 2021 10:40:02 +0200
Subject: [PATCH 2/2] arm64: dts: amlogic: add support for Radxa Zero
In-Reply-To: <20210809131047.28047-3-christianshewitt@gmail.com>
References: <20210809131047.28047-1-christianshewitt@gmail.com>
 <20210809131047.28047-3-christianshewitt@gmail.com>
Message-ID: <add888eb-769f-fbd3-e3d3-d8986eeaec80@baylibre.com>

On 09/08/2021 15:10, Christian Hewitt wrote:
> Radxa Zero is a small form factor SBC based on the Amlogic S905Y2
> chipset that ships in a number of RAM/eMMC configurations:
> 
> Boards with 512MB/1GB LPDDR4 RAM have no eMMC storage and BCM43436
> wireless (2.4GHz b/g/n) while 2GB/4GB boards have 8/16/32/64/128GB
> eMMC storage and BCM4345 wireless (2.4/5GHz a/b/g/n/ac).
> 
> - Amlogic S905Y2 quad-core Cortex-A53
> - Mali G31-MP2 GPU
> - HDMI 2.1 output (micro)
> - 1x USB 2.0 port - Type C (OTG)
> - 1x USB 3.0 port - Type C (Host)
> - 1x micro SD Card slot
> - 40 Pin GPIO header
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/Makefile          |   1 +
>  .../dts/amlogic/meson-g12a-radxa-zero.dts     | 418 ++++++++++++++++++
>  2 files changed, 419 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
> 
> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
> index faa0a79a34f5..be308361e2f1 100644
> --- a/arch/arm64/boot/dts/amlogic/Makefile
> +++ b/arch/arm64/boot/dts/amlogic/Makefile
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-g12a-radxa-zero.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
> new file mode 100644
> index 000000000000..d44d3881d9b9
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
> @@ -0,0 +1,418 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2018 BayLibre SAS. All rights reserved.
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-g12a.dtsi"
> +#include <dt-bindings/gpio/meson-g12a-gpio.h>
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "radxa,zero", "amlogic,g12a";
> +	model = "Radxa Zero";
> +
> +	aliases {
> +		serial0 = &uart_AO;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	memory at 0 {
> +		device_type = "memory";
> +		reg = <0x0 0x0 0x0 0x40000000>;
> +	};
> +
> +	cvbs-connector {
> +		status = "disabled";
> +		compatible = "composite-video-connector";
> +
> +		port {
> +			cvbs_connector_in: endpoint {
> +				remote-endpoint = <&cvbs_vdac_out>;
> +			};
> +		};
> +	};
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_connector_in: endpoint {
> +				remote-endpoint = <&hdmi_tx_tmds_out>;
> +			};
> +		};
> +	};
> +
> +	emmc_pwrseq: emmc-pwrseq {
> +		compatible = "mmc-pwrseq-emmc";
> +		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
> +	};
> +
> +	sdio_pwrseq: sdio-pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
> +		clocks = <&wifi32k>;
> +		clock-names = "ext_clock";
> +	};
> +
> +	flash_1v8: regulator-flash_1v8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "FLASH_1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		vin-supply = <&vcc_3v3>;
> +		regulator-always-on;
> +	};

Drop this one and directly use vcc_1v8 regulator

> +
> +	dc_in: regulator-dc_in {
> +		compatible = "regulator-fixed";
> +		regulator-name = "DC_IN";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	}
The name is AO_5V on the Schematics

> +
> +	vcc_1v8: regulator-vcc_1v8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VCC_1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		vin-supply = <&vcc_3v3>;
> +		regulator-always-on;
> +	};
> +
> +	vcc_3v3: regulator-vcc_3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VCC_3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vddao_3v3>;
> +		regulator-always-on;
> +	};
> +
> +	vcc_5v: regulator-vcc_5v {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VCC_5V";

The name is "HDMI_PW" on the Schematics

> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&dc_in>;
> +
> +		gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
> +		enable-active-low;

As the Schematics, the HDMI 5v is always on, no need for a GPIO control here,
please replace with regulator-always-on;

> +	};
> +
> +	vddao_1v8: regulator-vddao_1v8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VDDAO_1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		vin-supply = <&vddao_3v3>;
> +		regulator-always-on;
> +	};
> +
> +	vddao_3v3: regulator-vddao_3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VDDAO_3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&dc_in>;
> +		regulator-always-on;
> +	};
> +
> +	vddcpu: regulator-vddcpu {
> +		compatible = "pwm-regulator";
> +
> +		regulator-name = "VDDCPU";
> +		regulator-min-microvolt = <721000>;
> +		regulator-max-microvolt = <1022000>;
> +
> +		vin-supply = <&dc_in>;
> +
> +		pwms = <&pwm_AO_cd 1 1250 0>;
> +		pwm-dutycycle-range = <100 0>;
> +
> +		regulator-boot-on;
> +		regulator-always-on;
> +	};
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "RADXA-ZERO";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +
> +	wifi32k: wifi32k {
> +		compatible = "pwm-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <32768>;
> +		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&cec_AO {
> +	pinctrl-0 = <&cec_ao_a_h_pins>;
> +	pinctrl-names = "default";
> +	status = "disabled";
> +	hdmi-phandle = <&hdmi_tx>;
> +};
> +
> +&cecb_AO {
> +	pinctrl-0 = <&cec_ao_b_h_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +	hdmi-phandle = <&hdmi_tx>;
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu1 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu2 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu3 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cvbs_vdac_port {
> +	cvbs_vdac_out: endpoint {
> +		remote-endpoint = <&cvbs_connector_in>;
> +	};
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&hdmi_tx {
> +	status = "okay";
> +	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
> +	pinctrl-names = "default";
> +	hdmi-supply = <&vcc_5v>;
> +};
> +
> +&hdmi_tx_tmds_port {
> +	hdmi_tx_tmds_out: endpoint {
> +		remote-endpoint = <&hdmi_connector_in>;
> +	};
> +};
> +
> +&ir {
> +	status = "disabled";
> +	pinctrl-0 = <&remote_input_ao_pins>;
> +	pinctrl-names = "default";
> +};
> +
> +&pwm_AO_cd {
> +	pinctrl-0 = <&pwm_ao_d_e_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&xtal>;
> +	clock-names = "clkin1";
> +	status = "okay";
> +};
> +
> +&pwm_ef {
> +	status = "okay";
> +	pinctrl-0 = <&pwm_e_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&xtal>;
> +	clock-names = "clkin0";
> +};
> +
> +&saradc {
> +	status = "okay";
> +	vref-supply = <&vddao_1v8>;
> +};
> +
> +/* SDIO */
> +&sd_emmc_a {
> +	status = "okay";
> +	pinctrl-0 = <&sdio_pins>;
> +	pinctrl-1 = <&sdio_clk_gate_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	sd-uhs-sdr50;
> +	max-frequency = <100000000>;
> +
> +	non-removable;
> +	disable-wp;
> +
> +	/* WiFi firmware requires power to be kept while in suspend */
> +	keep-power-in-suspend;
> +
> +	mmc-pwrseq = <&sdio_pwrseq>;
> +
> +	vmmc-supply = <&vddao_3v3>;
> +	vqmmc-supply = <&vddao_1v8>;
> +
> +	brcmf: wifi at 1 {
> +		reg = <1>;
> +		compatible = "brcm,bcm4329-fmac";
> +		interrupts = <&gpio GPIOX_7 GPIO_ACTIVE_HIGH>;
> +		interrupt-names = "host-wake";
> +	};
> +};
> +
> +/* SD card */
> +&sd_emmc_b {
> +	status = "okay";
> +	pinctrl-0 = <&sdcard_c_pins>;
> +	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	max-frequency = <100000000>;
> +	disable-wp;
> +
> +	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
> +	vmmc-supply = <&vddao_3v3>;
> +	vqmmc-supply = <&vddao_3v3>;
> +};
> +
> +/* eMMC */
> +&sd_emmc_c {
> +	status = "okay";
> +	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
> +	pinctrl-1 = <&emmc_clk_gate_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +
> +	bus-width = <8>;
> +	cap-mmc-highspeed;
> +	mmc-ddr-1_8v;
> +	mmc-hs200-1_8v;
> +	max-frequency = <200000000>;
> +	disable-wp;
> +
> +	mmc-pwrseq = <&emmc_pwrseq>;
> +	vmmc-supply = <&vcc_3v3>;
> +	vqmmc-supply = <&flash_1v8>;
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> +
> +&uart_A {
> +	status = "okay";
> +	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
> +	pinctrl-names = "default";
> +	uart-has-rtscts;
> +
> +	bluetooth {
> +		compatible = "brcm,bcm43438-bt";
> +		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
> +		max-speed = <2000000>;
> +		clocks = <&wifi32k>;
> +		clock-names = "lpo";
> +	};
> +};
> +
> +&uart_AO {
> +	status = "okay";
> +	pinctrl-0 = <&uart_ao_a_pins>;
> +	pinctrl-names = "default";
> +};
> +
> +&usb {
> +	status = "okay";
> +	dr_mode = "host";
> +};
> 

Type-C controller is missing, something like was done on libretech-pc:

	typec2_vbus: regulator-typec2_vbus {
		typec2_vbus: regulator-typec2_vbus {
		compatible = "regulator-fixed";
		regulator-name = "TYPEC2_VBUS";
		regulator-min-microvolt = <5000000>;
		regulator-max-microvolt = <5000000>;
		vin-supply = <&vcc5v>;

		gpio = <&gpio_ao GPIOAO_7 GPIO_ACTIVE_HIGH>;
		enable-active-high;
	};


&ao_pinctrl {
	/*
	 * Make sure the irq pin of the TYPE C controller is not driven
	 * by the SoC.
	 */
	fusb302_irq_pins: fusb302_irq {
		mux {
			groups = "GPIOAO_5";
			function = "gpio_aobus";
			bias-pull-up;
			output-disable;
		};
	};
};

&i2c3 {
	status = "okay";
	pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
	pinctrl-names = "default";

	fusb302 at 22 {
		compatible = "fcs,fusb302";
		reg = <0x22>;

		pinctrl-0 = <&fusb302_irq_pins>;
		pinctrl-names = "default";
		interrupt-parent = <&gpio_intc>;
		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;

		vbus-supply = <&typec2_vbus>;

		status = "okay";
	};
};

&usb2_phy0 {
	phy-supply = <&typec2_vbus>;
};

&usb3_pcie_phy {
	phy-supply = <&typec2_vbus>;
};

But, seems polarity swapping via GPIO is not implemented in drivers/usb/typec/tcpm/fusb302.c so no idea how to handle GPIOAO_6 for USB3 polarity control...
 717 static int tcpm_set_polarity(struct tcpc_dev *dev,
 718                              enum typec_cc_polarity polarity)
 719 {
 720         return 0;
 721 }

Repost with regulator changes, TypeC stuff is not mandatory for v1.

Thanks,
Neil


From maz at kernel.org  Tue Aug 10 01:40:37 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 09:40:37 +0100
Subject: [PATCH 11/13] clocksource/arm_arch_timer: Fix masking for high
 freq counters
In-Reply-To: <CAOQ_Qshfi=RN8fExhXQh1i640LAZaZjQSJApyvdU2Gva9KtFaQ@mail.gmail.com>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-12-maz@kernel.org>
 <CAOQ_Qshfi=RN8fExhXQh1i640LAZaZjQSJApyvdU2Gva9KtFaQ@mail.gmail.com>
Message-ID: <87eeb1bsl6.wl-maz@kernel.org>

On Mon, 09 Aug 2021 17:45:28 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > From: Oliver Upton <oupton at google.com>
> >
> > Unfortunately, the architecture provides no means to determine the bit
> > width of the system counter. However, we do know the following from the
> > specification:
> >
> >  - the system counter is at least 56 bits wide
> >  - Roll-over time of not less than 40 years
> >
> > To date, the arch timer driver has depended on the first property,
> > assuming any system counter to be 56 bits wide and masking off the rest.
> > However, combining a narrow clocksource mask with a high frequency
> > counter could result in prematurely wrapping the system counter by a
> > significant margin. For example, a 56 bit wide, 1GHz system counter
> > would wrap in a mere 2.28 years!
> >
> > This is a problem for two reasons: v8.6+ implementations are required to
> > provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> > implementers may select a counter frequency of their choosing.
> >
> > Fix the issue by deriving a valid clock mask based on the second
> > property from above. Set the floor at 56 bits, since we know no system
> > counter is narrower than that.
> >
> > Suggested-by: Marc Zyngier <maz at kernel.org>
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> > [maz: fixed width computation not to lose the last bit, added
> >       max delta generation for the timer]
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > Link: https://lore.kernel.org/r/20210807191428.3488948-1-oupton at google.com
> > ---
> >  drivers/clocksource/arm_arch_timer.c | 34 ++++++++++++++++++++++++----
> >  1 file changed, 29 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> > index fa09952b94bf..74eca831d0d9 100644
> > --- a/drivers/clocksource/arm_arch_timer.c
> > +++ b/drivers/clocksource/arm_arch_timer.c
> > @@ -52,6 +52,12 @@
> >  #define CNTV_CVAL_LO   0x30
> >  #define CNTV_CTL       0x3c
> >
> > +/*
> > + * The minimum amount of time a generic counter is guaranteed to not roll over
> > + * (40 years)
> > + */
> > +#define MIN_ROLLOVER_SECS      (40ULL * 365 * 24 * 3600)
> > +
> >  static unsigned arch_timers_present __initdata;
> >
> >  struct arch_timer {
> > @@ -95,6 +101,22 @@ static int __init early_evtstrm_cfg(char *buf)
> >  }
> >  early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
> >
> > +/*
> > + * Makes an educated guess at a valid counter width based on the Generic Timer
> > + * specification. Of note:
> > + *   1) the system counter is at least 56 bits wide
> > + *   2) a roll-over time of not less than 40 years
> > + *
> > + * See 'ARM DDI 0487G.a D11.1.2 ("The system counter")' for more details.
> > + */
> > +static int arch_counter_get_width(void)
> > +{
> > +       u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_rate;
> > +
> > +       /* guarantee the returned width is within the valid range */
> > +       return clamp_val(ilog2(min_cycles - 1) + 1, 56, 64);
> > +}
> 
> Reposting thoughts from the original patch:
> 
> Reading the ARM ARM
> D11.1.2 'The system counter', I did not find any language that
> suggested the counter saturates the register width before rolling
> over. So, it may be paranoid, but I presumed it to be safer to wrap
> within the guaranteed interval rather (40 years) than assume the
> sanity of the system counter implementation.

I really don't think that would be a likely implementation. The fact
that the ARM ARM only talks about the width of the counter makes it a
strong case that there is no 'ceiling' other than the natural
saturation of the counter, IMO. If a rollover was allowed to occur
before, it would definitely be mentioned.

Think about it: you'd need to implement an extra comparator to drive
the reset of the counter. It would also make the implementation of
CVAL stupidly complicated: how do you handle the set of values that
fit in the counter width, but are out of the counter range?

Even though the architecture is not the clearest thing, I'm expecting
the CPU designers to try and save gates, rather than trying to
implement a GOTCHA, expensive counter... ;-)

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From matthias.bgg at gmail.com  Tue Aug 10 01:46:19 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 10 Aug 2021 10:46:19 +0200
Subject: [PATCH v8, 0/2] soc: mediatek: mmsys: add mt8192 mmsys support
In-Reply-To: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <e4afa712-9936-15fc-ad43-576948758f6c@gmail.com>



On 02/08/2021 10:59, Yongqiang Niu wrote:
> base v5.14-rc1
> 
> Yongqiang Niu (2):
>   soc: mediatek: mmsys: add comp OVL_2L2/POSTMASK/RDMA4
>   soc: mediatek: mmsys: Add mt8192 mmsys routing table
> 

Series queued in v5.15-tmp/soc

Thanks

>  drivers/soc/mediatek/mt8192-mmsys.h    | 67 ++++++++++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c       | 11 ++++++
>  include/linux/soc/mediatek/mtk-mmsys.h |  3 ++
>  3 files changed, 81 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mt8192-mmsys.h
> 


From dillon.minfei at gmail.com  Tue Aug 10 01:51:03 2021
From: dillon.minfei at gmail.com (Dillon Min)
Date: Tue, 10 Aug 2021 16:51:03 +0800
Subject: [PATCH v2 9/9] media: stm32-dma2d: STM32 DMA2D driver
In-Reply-To: <cb22a3b2-5021-c246-d52b-dc6df78cd4c9@xs4all.nl>
References: <1626341068-20253-1-git-send-email-dillon.minfei@gmail.com>
 <1626341068-20253-20-git-send-email-dillon.minfei@gmail.com>
 <cb22a3b2-5021-c246-d52b-dc6df78cd4c9@xs4all.nl>
Message-ID: <CAL9mu0JnZmQRQfN2rgpfzjBqz1tTuWMvWqjHAjqeSVO-bcrk6w@mail.gmail.com>

Hi Hans

Thanks for the detailed review.
All the suggestions will be addressed at v3.

On Mon, 9 Aug 2021 at 17:09, Hans Verkuil <hverkuil-cisco at xs4all.nl> wrote:
>
> On 15/07/2021 11:24, dillon.minfei at gmail.com wrote:
> > From: Dillon Min <dillon.minfei at gmail.com>
> >
> > This V4L2 subdev m2m driver enables Chrom-Art Accelerator unit
> > of STMicroelectronics STM32 SoC series.
> >
> > Currently support r2m, m2m, m2m_pfc functions.
> > - r2m, Filling a part or the whole of a destination image with a specific
> >   color.
> > - m2m, Copying a part or the whole of a source image into a part or the
> >   whole of a destination.
> > - m2m_pfc, Copying a part or the whole of a source image into a part or the
> >   whole of a destination image with a pixel format conversion.
> >
> > Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
> > ---
> > v2: all the changes are based on Hans's review, thanks.
> > - update Kconfig, replace ',' to 'and', add '.' at the description end,
> >   add COMPILE_TEST.
> > - fix a lots of warrnings from checkpatch.pl --strict.
> > - add const to formats[] and def_frame.
> > - chage line_ofs to line_offset.
> > - replace ctx->fg to ctx->cap.
> > - change implemention of get_frame().
> > - move the ioctls definition from the code to stm32-media.h.
> > - change "Set to r2m mode" to "Set R2M Mode".
> > - add decription for r2m, m2m, m2m_pfc.
> >
> >  drivers/media/platform/Kconfig                  |   9 +
> >  drivers/media/platform/Makefile                 |   1 +
> >  drivers/media/platform/stm32/Makefile           |   2 +
> >  drivers/media/platform/stm32/dma2d/dma2d-hw.c   | 143 +++++
> >  drivers/media/platform/stm32/dma2d/dma2d-regs.h | 113 ++++
> >  drivers/media/platform/stm32/dma2d/dma2d.c      | 796 ++++++++++++++++++++++++
> >  drivers/media/platform/stm32/dma2d/dma2d.h      | 136 ++++
> >  7 files changed, 1200 insertions(+)
> >  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d-hw.c
> >  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d-regs.h
> >  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d.c
> >  create mode 100644 drivers/media/platform/stm32/dma2d/dma2d.h
> >
> > diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> > index 157c924686e4..4df18623e4ad 100644
> > --- a/drivers/media/platform/Kconfig
> > +++ b/drivers/media/platform/Kconfig
> > @@ -473,6 +473,15 @@ config VIDEO_STI_DELTA_DRIVER
> >
> >  endif # VIDEO_STI_DELTA
> >
> > +config VIDEO_STM32_DMA2D
> > +     tristate "STM32 Chrom-Art Accelerator (DMA2D)"
> > +     depends on (VIDEO_DEV && VIDEO_V4L2 && ARCH_STM32) || COMPILE_TEST
> > +     select VIDEOBUF2_DMA_CONTIG
> > +     select V4L2_MEM2MEM_DEV
> > +     help
> > +       The STM32 DMA2D is a memory-to-memory engine for pixel conversion
> > +       and specialized DMA dedicated to image manipulation.
> > +
> >  config VIDEO_RENESAS_FDP1
> >       tristate "Renesas Fine Display Processor"
> >       depends on VIDEO_DEV && VIDEO_V4L2
> > diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
> > index 73ce083c2fc6..46f1c05bc576 100644
> > --- a/drivers/media/platform/Makefile
> > +++ b/drivers/media/platform/Makefile
> > @@ -70,6 +70,7 @@ obj-$(CONFIG_VIDEO_ATMEL_ISI)               += atmel/
> >  obj-$(CONFIG_VIDEO_ATMEL_XISC)               += atmel/
> >
> >  obj-$(CONFIG_VIDEO_STM32_DCMI)               += stm32/
> > +obj-$(CONFIG_VIDEO_STM32_DMA2D)              += stm32/
> >
> >  obj-$(CONFIG_VIDEO_MEDIATEK_VPU)     += mtk-vpu/
> >
> > diff --git a/drivers/media/platform/stm32/Makefile b/drivers/media/platform/stm32/Makefile
> > index 48b36db2c2e2..896ef98a73ab 100644
> > --- a/drivers/media/platform/stm32/Makefile
> > +++ b/drivers/media/platform/stm32/Makefile
> > @@ -1,2 +1,4 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >  obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32-dcmi.o
> > +stm32-dma2d-objs := dma2d/dma2d.o dma2d/dma2d-hw.o
> > +obj-$(CONFIG_VIDEO_STM32_DMA2D) += stm32-dma2d.o
> > diff --git a/drivers/media/platform/stm32/dma2d/dma2d-hw.c b/drivers/media/platform/stm32/dma2d/dma2d-hw.c
> > new file mode 100644
> > index 000000000000..8c1c664ab13b
> > --- /dev/null
> > +++ b/drivers/media/platform/stm32/dma2d/dma2d-hw.c
> > @@ -0,0 +1,143 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * ST stm32 Chrom-Art - 2D Graphics Accelerator Driver
> > + *
> > + * Copyright (c) 2021 Dillon Min
> > + * Dillon Min, <dillon.minfei at gmail.com>
> > + *
> > + * based on s5p-g2d
> > + *
> > + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> > + * Kamil Debski, <k.debski at samsung.com>
> > + */
> > +
> > +#include <linux/io.h>
> > +
> > +#include "dma2d.h"
> > +#include "dma2d-regs.h"
> > +
> > +static inline u32 reg_read(void __iomem *base, u32 reg)
> > +{
> > +     return readl_relaxed(base + reg);
> > +}
> > +
> > +static inline void reg_write(void __iomem *base, u32 reg, u32 val)
> > +{
> > +     writel_relaxed(val, base + reg);
> > +}
> > +
> > +static inline void reg_set(void __iomem *base, u32 reg, u32 mask)
> > +{
> > +     reg_write(base, reg, reg_read(base, reg) | mask);
> > +}
> > +
> > +static inline void reg_clear(void __iomem *base, u32 reg, u32 mask)
> > +{
> > +     reg_write(base, reg, reg_read(base, reg) & ~mask);
> > +}
> > +
> > +static inline void reg_update_bits(void __iomem *base, u32 reg, u32 mask,
> > +                                u32 val)
> > +{
> > +     reg_write(base, reg, (reg_read(base, reg) & ~mask) | val);
> > +}
> > +
> > +void dma2d_start(struct dma2d_dev *d)
> > +{
> > +     reg_update_bits(d->regs, DMA2D_CR_REG, CR_START, CR_START);
> > +}
> > +
> > +u32 dma2d_get_int(struct dma2d_dev *d)
> > +{
> > +     return reg_read(d->regs, DMA2D_ISR_REG);
> > +}
> > +
> > +void dma2d_clear_int(struct dma2d_dev *d)
> > +{
> > +     u32 isr_val = reg_read(d->regs, DMA2D_ISR_REG);
> > +
> > +     reg_write(d->regs, DMA2D_IFCR_REG, isr_val & 0x003f);
> > +}
> > +
> > +void dma2d_config_common(struct dma2d_dev *d, enum dma2d_op_mode op_mode,
> > +                      u16 width, u16 height)
> > +{
> > +     reg_update_bits(d->regs, DMA2D_CR_REG, CR_MODE_MASK,
> > +                     op_mode << CR_MODE_SHIFT);
> > +
> > +     reg_write(d->regs, DMA2D_NLR_REG, (width << 16) | height);
> > +}
> > +
> > +void dma2d_config_out(struct dma2d_dev *d, struct dma2d_frame *frm,
> > +                   dma_addr_t o_addr)
> > +{
> > +     reg_update_bits(d->regs, DMA2D_CR_REG, CR_CEIE, CR_CEIE);
> > +     reg_update_bits(d->regs, DMA2D_CR_REG, CR_CTCIE, CR_CTCIE);
> > +     reg_update_bits(d->regs, DMA2D_CR_REG, CR_CAEIE, CR_CAEIE);
> > +     reg_update_bits(d->regs, DMA2D_CR_REG, CR_TCIE, CR_TCIE);
> > +     reg_update_bits(d->regs, DMA2D_CR_REG, CR_TEIE, CR_TEIE);
> > +
> > +     if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
> > +         frm->fmt->cmode <= CM_MODE_ARGB4444)
> > +             reg_update_bits(d->regs, DMA2D_OPFCCR_REG, OPFCCR_CM_MASK,
> > +                             frm->fmt->cmode);
> > +
> > +     reg_write(d->regs, DMA2D_OMAR_REG, o_addr);
> > +
> > +     reg_write(d->regs, DMA2D_OCOLR_REG,
> > +               (frm->a_rgb[3] << 24) |
> > +               (frm->a_rgb[2] << 16) |
> > +               (frm->a_rgb[1] << 8) |
> > +               frm->a_rgb[0]);
> > +
> > +     reg_update_bits(d->regs, DMA2D_OOR_REG, OOR_LO_MASK,
> > +                     frm->line_offset & 0x3fff);
> > +}
> > +
> > +void dma2d_config_fg(struct dma2d_dev *d, struct dma2d_frame *frm,
> > +                  dma_addr_t f_addr)
> > +{
> > +     reg_write(d->regs, DMA2D_FGMAR_REG, f_addr);
> > +     reg_update_bits(d->regs, DMA2D_FGOR_REG, FGOR_LO_MASK,
> > +                     frm->line_offset);
> > +
> > +     if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
> > +         frm->fmt->cmode <= CM_MODE_A4)
> > +             reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_CM_MASK,
> > +                             frm->fmt->cmode);
> > +
> > +     reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_AM_MASK,
> > +                     (frm->a_mode << 16) & 0x03);
> > +
> > +     reg_update_bits(d->regs, DMA2D_FGPFCCR_REG, FGPFCCR_ALPHA_MASK,
> > +                     frm->a_rgb[3] << 24);
> > +
> > +     reg_write(d->regs, DMA2D_FGCOLR_REG,
> > +               (frm->a_rgb[2] << 16) |
> > +               (frm->a_rgb[1] << 8) |
> > +               frm->a_rgb[0]);
> > +}
> > +
> > +void dma2d_config_bg(struct dma2d_dev *d, struct dma2d_frame *frm,
> > +                  dma_addr_t b_addr)
> > +{
> > +     reg_write(d->regs, DMA2D_BGMAR_REG, b_addr);
> > +     reg_update_bits(d->regs, DMA2D_BGOR_REG, BGOR_LO_MASK,
> > +                     frm->line_offset);
> > +
> > +     if (frm->fmt->cmode >= CM_MODE_ARGB8888 &&
> > +         frm->fmt->cmode <= CM_MODE_A4)
> > +             reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_CM_MASK,
> > +                             frm->fmt->cmode);
> > +
> > +     reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_AM_MASK,
> > +                     (frm->a_mode << 16) & 0x03);
> > +
> > +     reg_update_bits(d->regs, DMA2D_BGPFCCR_REG, BGPFCCR_ALPHA_MASK,
> > +                     frm->a_rgb[3] << 24);
> > +
> > +     reg_write(d->regs, DMA2D_BGCOLR_REG,
> > +               (frm->a_rgb[2] << 16) |
> > +               (frm->a_rgb[1] << 8) |
> > +               frm->a_rgb[0]);
> > +}
> > diff --git a/drivers/media/platform/stm32/dma2d/dma2d-regs.h b/drivers/media/platform/stm32/dma2d/dma2d-regs.h
> > new file mode 100644
> > index 000000000000..2128364406c8
> > --- /dev/null
> > +++ b/drivers/media/platform/stm32/dma2d/dma2d-regs.h
> > @@ -0,0 +1,113 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * ST stm32 Chrom-Art - 2D Graphics Accelerator Driver
> > + *
> > + * Copyright (c) 2021 Dillon Min
> > + * Dillon Min, <dillon.minfei at gmail.com>
> > + *
> > + * based on s5p-g2d
> > + *
> > + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> > + * Kamil Debski, <k.debski at samsung.com>
> > + */
> > +
> > +#ifndef __DMA2D_REGS_H__
> > +#define __DMA2D_REGS_H__
> > +
> > +#define DMA2D_CR_REG         0x0000
> > +#define CR_MODE_MASK         GENMASK(17, 16)
> > +#define CR_MODE_SHIFT                16
> > +#define CR_M2M                       0x0000
> > +#define CR_M2M_PFC           BIT(16)
> > +#define CR_M2M_BLEND         BIT(17)
> > +#define CR_R2M                       (BIT(17) | BIT(16))
> > +#define CR_CEIE                      BIT(13)
> > +#define CR_CTCIE             BIT(12)
> > +#define CR_CAEIE             BIT(11)
> > +#define CR_TWIE                      BIT(10)
> > +#define CR_TCIE                      BIT(9)
> > +#define CR_TEIE                      BIT(8)
> > +#define CR_ABORT             BIT(2)
> > +#define CR_SUSP                      BIT(1)
> > +#define CR_START             BIT(0)
> > +
> > +#define DMA2D_ISR_REG                0x0004
> > +#define ISR_CEIF             BIT(5)
> > +#define ISR_CTCIF            BIT(4)
> > +#define ISR_CAEIF            BIT(3)
> > +#define ISR_TWIF             BIT(2)
> > +#define ISR_TCIF             BIT(1)
> > +#define ISR_TEIF             BIT(0)
> > +
> > +#define DMA2D_IFCR_REG               0x0008
> > +#define IFCR_CCEIF           BIT(5)
> > +#define IFCR_CCTCIF          BIT(4)
> > +#define IFCR_CAECIF          BIT(3)
> > +#define IFCR_CTWIF           BIT(2)
> > +#define IFCR_CTCIF           BIT(1)
> > +#define IFCR_CTEIF           BIT(0)
> > +
> > +#define DMA2D_FGMAR_REG              0x000c
> > +#define DMA2D_FGOR_REG               0x0010
> > +#define FGOR_LO_MASK         GENMASK(13, 0)
> > +
> > +#define DMA2D_BGMAR_REG              0x0014
> > +#define DMA2D_BGOR_REG               0x0018
> > +#define BGOR_LO_MASK         GENMASK(13, 0)
> > +
> > +#define DMA2D_FGPFCCR_REG    0x001c
> > +#define FGPFCCR_ALPHA_MASK   GENMASK(31, 24)
> > +#define FGPFCCR_AM_MASK              GENMASK(17, 16)
> > +#define FGPFCCR_CS_MASK              GENMASK(15, 8)
> > +#define FGPFCCR_START                BIT(5)
> > +#define FGPFCCR_CCM_RGB888   BIT(4)
> > +#define FGPFCCR_CM_MASK              GENMASK(3, 0)
> > +
> > +#define DMA2D_FGCOLR_REG     0x0020
> > +#define FGCOLR_REG_MASK              GENMASK(23, 16)
> > +#define FGCOLR_GREEN_MASK    GENMASK(15, 8)
> > +#define FGCOLR_BLUE_MASK     GENMASK(7, 0)
> > +
> > +#define DMA2D_BGPFCCR_REG    0x0024
> > +#define BGPFCCR_ALPHA_MASK   GENMASK(31, 24)
> > +#define BGPFCCR_AM_MASK              GENMASK(17, 16)
> > +#define BGPFCCR_CS_MASK              GENMASK(15, 8)
> > +#define BGPFCCR_START                BIT(5)
> > +#define BGPFCCR_CCM_RGB888   BIT(4)
> > +#define BGPFCCR_CM_MASK              GENMASK(3, 0)
> > +
> > +#define DMA2D_BGCOLR_REG     0x0028
> > +#define BGCOLR_REG_MASK              GENMASK(23, 16)
> > +#define BGCOLR_GREEN_MASK    GENMASK(15, 8)
> > +#define BGCOLR_BLUE_MASK     GENMASK(7, 0)
> > +
> > +#define DMA2D_OPFCCR_REG     0x0034
> > +#define OPFCCR_CM_MASK               GENMASK(2, 0)
> > +
> > +#define DMA2D_OCOLR_REG              0x0038
> > +#define OCOLR_ALPHA_MASK     GENMASK(31, 24)
> > +#define OCOLR_RED_MASK               GENMASK(23, 16)
> > +#define OCOLR_GREEN_MASK     GENMASK(15, 8)
> > +#define OCOLR_BLUE_MASK              GENMASK(7, 0)
> > +
> > +#define DMA2D_OMAR_REG               0x003c
> > +
> > +#define DMA2D_OOR_REG                0x0040
> > +#define OOR_LO_MASK          GENMASK(13, 0)
> > +
> > +#define DMA2D_NLR_REG                0x0044
> > +#define NLR_PL_MASK          GENMASK(29, 16)
> > +#define NLR_NL_MASK          GENMASK(15, 0)
> > +
> > +/* Hardware limits */
> > +#define MAX_WIDTH            0x3fff
> > +#define MAX_HEIGHT           0xffff
> > +
> > +#define DEFAULT_WIDTH                240
> > +#define DEFAULT_HEIGHT               320
> > +#define DEFAULT_SIZE         307200
> > +
> > +#define CM_MODE_ARGB8888     0x00
> > +#define CM_MODE_ARGB4444     0x04
> > +#define CM_MODE_A4           0x0a
> > +#endif /* __DMA2D_REGS_H__ */
> > diff --git a/drivers/media/platform/stm32/dma2d/dma2d.c b/drivers/media/platform/stm32/dma2d/dma2d.c
> > new file mode 100644
> > index 000000000000..f41f94dfb7b7
> > --- /dev/null
> > +++ b/drivers/media/platform/stm32/dma2d/dma2d.c
> > @@ -0,0 +1,796 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * STM32 DMA2D - 2D Graphics Accelerator Driver
> > + *
> > + * Copyright (c) 2021 Dillon Min
> > + * Dillon Min, <dillon.minfei at gmail.com>
> > + *
> > + * based on s5p-g2d
> > + *
> > + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> > + * Kamil Debski, <k.debski at samsung.com>
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/fs.h>
> > +#include <linux/timer.h>
> > +#include <linux/sched.h>
> > +#include <linux/slab.h>
> > +#include <linux/clk.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/of.h>
> > +
> > +#include <linux/platform_device.h>
> > +#include <media/v4l2-mem2mem.h>
> > +#include <media/v4l2-device.h>
> > +#include <media/v4l2-ioctl.h>
> > +#include <media/v4l2-event.h>
> > +#include <media/videobuf2-v4l2.h>
> > +#include <media/videobuf2-dma-contig.h>
> > +#include <uapi/linux/stm32-media.h>
> > +
> > +#include "dma2d.h"
> > +#include "dma2d-regs.h"
> > +
> > +/*
> > + * This V4L2 subdev m2m driver enables Chrom-Art Accelerator unit
> > + * of STMicroelectronics STM32 SoC series.
> > + *
> > + * Currently support r2m, m2m, m2m_pfc.
> > + *
> > + * - r2m, Filling a part or the whole of a destination image with a specific
> > + *   color.
> > + * - m2m, Copying a part or the whole of a source image into a part or the
> > + *   whole of a destination.
> > + * - m2m_pfc, Copying a part or the whole of a source image into a part or the
> > + *   whole of a destination image with a pixel format conversion.
> > + */
> > +
> > +#define fh2ctx(__fh) container_of(__fh, struct dma2d_ctx, fh)
> > +
> > +static const struct dma2d_fmt formats[] = {
> > +     {
> > +             .fourcc = V4L2_PIX_FMT_ARGB32,
> > +             .cmode = DMA2D_CMODE_ARGB8888,
> > +             .depth = 32,
> > +     },
> > +     {
> > +             .fourcc = V4L2_PIX_FMT_RGB24,
> > +             .cmode = DMA2D_CMODE_RGB888,
> > +             .depth = 24,
> > +     },
> > +     {
> > +             .fourcc = V4L2_PIX_FMT_RGB565,
> > +             .cmode = DMA2D_CMODE_RGB565,
> > +             .depth = 16,
> > +     },
> > +     {
> > +             .fourcc = V4L2_PIX_FMT_ARGB555,
> > +             .cmode = DMA2D_CMODE_ARGB1555,
> > +             .depth = 16,
> > +     },
> > +     {
> > +             .fourcc = V4L2_PIX_FMT_ARGB444,
> > +             .cmode = DMA2D_CMODE_ARGB4444,
> > +             .depth = 16,
> > +     },
> > +};
> > +
> > +#define NUM_FORMATS ARRAY_SIZE(formats)
> > +
> > +static const struct dma2d_frame def_frame = {
> > +     .width          = DEFAULT_WIDTH,
> > +     .height         = DEFAULT_HEIGHT,
> > +     .line_offset    = 0,
> > +     .a_rgb          = {0x00, 0x00, 0x00, 0xff},
> > +     .a_mode         = DMA2D_ALPHA_MODE_NO_MODIF,
> > +     .fmt            = (struct dma2d_fmt *)&formats[0],
> > +     .size           = DEFAULT_SIZE,
> > +};
> > +
> > +static struct dma2d_fmt *find_fmt(int pixelformat)
> > +{
> > +     unsigned int i;
> > +
> > +     for (i = 0; i < NUM_FORMATS; i++) {
> > +             if (formats[i].fourcc == pixelformat)
> > +                     return (struct dma2d_fmt *)&formats[i];
> > +     }
> > +
> > +     return NULL;
> > +}
> > +
> > +static struct dma2d_frame *get_frame(struct dma2d_ctx *ctx,
> > +                                  enum v4l2_buf_type type)
> > +{
> > +     return V4L2_TYPE_IS_OUTPUT(type) ? &ctx->cap : &ctx->out;
> > +}
> > +
> > +static int dma2d_queue_setup(struct vb2_queue *vq,
> > +                          unsigned int *nbuffers, unsigned int *nplanes,
> > +                          unsigned int sizes[], struct device *alloc_devs[])
> > +{
> > +     struct dma2d_ctx *ctx = vb2_get_drv_priv(vq);
> > +     struct dma2d_frame *f = get_frame(ctx, vq->type);
> > +
> > +     if (IS_ERR(f))
> > +             return PTR_ERR(f);
>
> Why this check? get_frame() doesn't return an error pointer, it always succeeds.
> Just drop this.

OK, will remove all the checks on get_frame() from this driver.

>
> > +
> > +     if (*nplanes)
> > +             return sizes[0] < f->size ? -EINVAL : 0;
> > +
> > +     sizes[0] = f->size;
> > +     *nplanes = 1;
> > +
> > +     if (*nbuffers == 0)
> > +             *nbuffers = 1;
>
> *nbuffers can never be 0, so you can drop this check.

OK

>
> > +
> > +     return 0;
> > +}
> > +
> > +static int dma2d_buf_out_validate(struct vb2_buffer *vb)
> > +{
> > +     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> > +
> > +     if (vbuf->field == V4L2_FIELD_ANY)
> > +             vbuf->field = V4L2_FIELD_NONE;
> > +     if (vbuf->field != V4L2_FIELD_NONE)
> > +             return -EINVAL;
> > +
> > +     return 0;
> > +}
> > +
> > +static int dma2d_buf_prepare(struct vb2_buffer *vb)
> > +{
> > +     struct dma2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
> > +     struct dma2d_frame *f = get_frame(ctx, vb->vb2_queue->type);
> > +
> > +     if (IS_ERR(f))
> > +             return PTR_ERR(f);
>
> Drop this check.

OK

>
> > +
> > +     if (vb2_plane_size(vb, 0) < f->size)
> > +             return -EINVAL;
> > +
> > +     vb2_set_plane_payload(vb, 0, f->size);
> > +
> > +     return 0;
> > +}
> > +
> > +static void dma2d_buf_queue(struct vb2_buffer *vb)
> > +{
> > +     struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> > +     struct dma2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
> > +
> > +     v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
> > +}
> > +
> > +static int dma2d_start_streaming(struct vb2_queue *q, unsigned int count)
> > +{
> > +     struct dma2d_ctx *ctx = vb2_get_drv_priv(q);
> > +     struct dma2d_frame *f = get_frame(ctx, q->type);
> > +
> > +     if (IS_ERR(f))
> > +             return -EINVAL;
>
> Drop check.

OK

>
> > +
> > +     f->sequence = 0;
> > +     return 0;
> > +}
> > +
> > +static void dma2d_stop_streaming(struct vb2_queue *q)
> > +{
> > +     struct dma2d_ctx *ctx = vb2_get_drv_priv(q);
> > +     struct vb2_v4l2_buffer *vbuf;
> > +
> > +     for (;;) {
> > +             if (V4L2_TYPE_IS_OUTPUT(q->type))
> > +                     vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
> > +             else
> > +                     vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
> > +             if (!vbuf)
> > +                     return;
> > +             v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> > +     }
> > +}
> > +
> > +static const struct vb2_ops dma2d_qops = {
> > +     .queue_setup    = dma2d_queue_setup,
> > +     .buf_out_validate        = dma2d_buf_out_validate,
> > +     .buf_prepare    = dma2d_buf_prepare,
> > +     .buf_queue      = dma2d_buf_queue,
> > +     .start_streaming = dma2d_start_streaming,
> > +     .stop_streaming  = dma2d_stop_streaming,
> > +     .wait_prepare   = vb2_ops_wait_prepare,
> > +     .wait_finish    = vb2_ops_wait_finish,
> > +};
> > +
> > +static int queue_init(void *priv, struct vb2_queue *src_vq,
> > +                   struct vb2_queue *dst_vq)
> > +{
> > +     struct dma2d_ctx *ctx = priv;
> > +     int ret;
> > +
> > +     src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
> > +     src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
> > +     src_vq->drv_priv = ctx;
> > +     src_vq->ops = &dma2d_qops;
> > +     src_vq->mem_ops = &vb2_dma_contig_memops;
> > +     src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
> > +     src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> > +     src_vq->lock = &ctx->dev->mutex;
> > +     src_vq->dev = ctx->dev->v4l2_dev.dev;
> > +
> > +     ret = vb2_queue_init(src_vq);
> > +     if (ret)
> > +             return ret;
> > +
> > +     dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> > +     dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
> > +     dst_vq->drv_priv = ctx;
> > +     dst_vq->ops = &dma2d_qops;
> > +     dst_vq->mem_ops = &vb2_dma_contig_memops;
> > +     dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
> > +     dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> > +     dst_vq->lock = &ctx->dev->mutex;
> > +     dst_vq->dev = ctx->dev->v4l2_dev.dev;
> > +
> > +     return vb2_queue_init(dst_vq);
> > +}
> > +
> > +static int dma2d_s_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > +     struct dma2d_frame *frm;
> > +     struct dma2d_ctx *ctx = container_of(ctrl->handler, struct dma2d_ctx,
> > +                                                             ctrl_handler);
> > +     unsigned long flags;
> > +
> > +     spin_lock_irqsave(&ctx->dev->ctrl_lock, flags);
> > +     switch (ctrl->id) {
> > +     case V4L2_CID_ALPHA_COMPONENT:
> > +             /* set the background alpha value*/
> > +             ctx->alpha_component = (u8)ctrl->val;
>
> It's set here, but is never used?!

It's used in mem2mem-pfc-blend mode, as the blending part is not ready
now, so this can be simply removed at this stage.

I'll remove it at v3, add it back in case the m2m-pfc-blend function is ready.

>
> > +             break;
> > +     case V4L2_CID_DMA2D_R2M_COLOR:
> > +             frm = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> > +             frm->a_rgb[2] = (ctrl->val >> 16) & 0xff;
> > +             frm->a_rgb[1] = (ctrl->val >>  8) & 0xff;
> > +             frm->a_rgb[0] = ctrl->val & 0xff;
>
> Hmm, the alpha value isn't copied, but that's documented in V4L2_CID_DMA2D_R2M_COLOR.
> Either this code or the documentation is wrong.

Yes, the description is confusing. The first time I write this code, I
plan to use the heigh 31..24 bits for the dma2d alpha channel of
output color register (DMA2D_OCLOR), which will be used for
mem2mem-pfc-blend mode.

DMA2D output color register (DMA2D_OCOLR)
Bits 31:24 ALPHA[7: 0]: Alpha Channel Value
These bits define the alpha channel of the output color. These bits
can only be written
when data transfers are disabled. Once the transfer has started, they
are read-only.

Since you give a more common way for it, I will drop
V4L2_CID_DMA2D_R2M_COLOR in v3.
turn to use V4L2_CID_COLORFX and V4L2_CID_COLORFX_ARGB.

>
> > +             break;
> > +     case V4L2_CID_DMA2D_R2M_MODE:
> > +             if (ctrl->val)
> > +                     ctx->op_mode = DMA2D_MODE_R2M;
> > +             break;
> > +     default:
> > +             v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
> > +             spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
> > +             return -EINVAL;
> > +     }
> > +     spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct v4l2_ctrl_ops dma2d_ctrl_ops = {
> > +     .s_ctrl = dma2d_s_ctrl,
> > +};
> > +
> > +static const struct v4l2_ctrl_config dma2d_r2m_control[] = {
> > +     {
> > +     .ops = &dma2d_ctrl_ops,
> > +     .id = V4L2_CID_DMA2D_R2M_COLOR,
> > +     .name = "R2M Alpha/Color Value",
>
> This mentions alpha support as well. Very unclear how this relates to V4L2_CID_ALPHA_COMPONENT.

This V4L2_CID_DMA2D_R2M_COLOR will be removed in v3.
DMA2D controller has three place related to alpha component for
blending function, which is

DMA2D foreground PFC control register (DMA2D_FGPFCCR)
DMA2D background PFC control register (DMA2D_BGPFCCR)
DMA2D output color register (DMA2D_OCOLR)

for FGPFCCR, BGPFCCR, they can use alpha value setting from user-space
to replace the original background/foreground image alpha channel
value.
for OCOLR, it's used to define the output pfc result alpha channel.

So, I plan to use
V4L2_CID_ALPHA_COMPONENT for BGPFCCR.
fmt.win.global_alpha for FGPFCCR
V4L2_CID_DMA2D_R2M_COLOR high 8 bits for OCOLR.

I'm still not clear about how to add the overlay function to a mem2mem
device driver.  so all the code related to the alpha/blend part will
be removed at v3.

>
> > +     .type = V4L2_CTRL_TYPE_INTEGER,
> > +     .min = 0xffffffff80000000ULL,
> > +     .max = 0x7fffffff,
>
> I suggest using TYPE_BITMASK: it's more appropriate for a control like this.
> (Yes, there are other color controls that are of type integer, but they predate
> the introduction of type bitmask).

OK, I will use TYPE_BITMASK in v3, thanks for the suggestion.

>
> > +     .def = 0,
> > +     .step = 1,
> > +     },
> > +     {
> > +     .ops = &dma2d_ctrl_ops,
> > +     .id = V4L2_CID_DMA2D_R2M_MODE,
> > +     .name = "Set R2M Mode",
> > +     .type = V4L2_CTRL_TYPE_BOOLEAN,
> > +     .min = 0,
> > +     .max = 1,
> > +     .def = 0,
> > +     .step = 1,
> > +     }
> > +};
>
> It's not clear what R2M mode does. Is it just to enable filling the colors? Or will
> there be other features in the future?

Yes, R2M means register to memory, fill the colors at the assigned
address of memory.
this ctrl just lets the driver know which mode to activate.

drivers can decide to activate below modes at device_run():
- register2mem, this is active by user-space ioctl setting before stream on.
- mem2mem, capture has all the same property with output, just address
different.
  Actually, this is something like normal dma.
- mem2mem-pfc, capture has the different fourcc property with output.
- mem2mem-pfc-blend, not ready now.

>
> As it is now, this feature can instead be implemented by adding a new color effect
> (see V4L2_CID_COLORFX): V4L2_COLORFX_SET_COLOR_ARGB.
>
> And add a new bitmask control V4L2_CID_COLORFX_ARGB to set the ARGB value.

Good idea, will follow your suggestion at v3. thanks.

>
> > +
> > +static int dma2d_setup_ctrls(struct dma2d_ctx *ctx)
> > +{
> > +     v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
> > +
> > +     v4l2_ctrl_new_std(&ctx->ctrl_handler, &dma2d_ctrl_ops,
> > +                       V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
> > +     v4l2_ctrl_new_custom(&ctx->ctrl_handler, &dma2d_r2m_control[0], NULL);
> > +     v4l2_ctrl_new_custom(&ctx->ctrl_handler, &dma2d_r2m_control[1], NULL);
> > +
> > +     return 0;
> > +}
> > +
> > +static int dma2d_open(struct file *file)
> > +{
> > +     struct dma2d_dev *dev = video_drvdata(file);
> > +     struct dma2d_ctx *ctx = NULL;
> > +     int ret = 0;
> > +
> > +     ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
> > +     if (!ctx)
> > +             return -ENOMEM;
> > +     ctx->dev = dev;
> > +     /* Set default formats */
> > +     ctx->cap                = def_frame;
> > +     ctx->bg         = def_frame;
> > +     ctx->out        = def_frame;
> > +     ctx->op_mode    = DMA2D_MODE_M2M_FPC;
> > +     ctx->colorspace = V4L2_COLORSPACE_REC709;
> > +     ctx->alpha_component = 0x00;
> > +     if (mutex_lock_interruptible(&dev->mutex)) {
> > +             kfree(ctx);
> > +             return -ERESTARTSYS;
> > +     }
> > +
> > +     ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
> > +     if (IS_ERR(ctx->fh.m2m_ctx)) {
> > +             ret = PTR_ERR(ctx->fh.m2m_ctx);
> > +             mutex_unlock(&dev->mutex);
> > +             kfree(ctx);
> > +             return ret;
> > +     }
> > +
> > +     v4l2_fh_init(&ctx->fh, video_devdata(file));
> > +     file->private_data = &ctx->fh;
> > +     v4l2_fh_add(&ctx->fh);
> > +
> > +     dma2d_setup_ctrls(ctx);
> > +
> > +     /* Write the default values to the ctx struct */
> > +     v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
> > +
> > +     ctx->fh.ctrl_handler = &ctx->ctrl_handler;
> > +     mutex_unlock(&dev->mutex);
> > +
> > +     return 0;
> > +}
> > +
> > +static int dma2d_release(struct file *file)
> > +{
> > +     struct dma2d_dev *dev = video_drvdata(file);
> > +     struct dma2d_ctx *ctx = fh2ctx(file->private_data);
> > +
> > +     v4l2_ctrl_handler_free(&ctx->ctrl_handler);
> > +     v4l2_fh_del(&ctx->fh);
> > +     v4l2_fh_exit(&ctx->fh);
> > +     mutex_lock(&dev->mutex);
> > +     v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
> > +     mutex_unlock(&dev->mutex);
> > +     kfree(ctx);
> > +
> > +     return 0;
> > +}
> > +
> > +static int vidioc_querycap(struct file *file, void *priv,
> > +                        struct v4l2_capability *cap)
> > +{
> > +     strscpy(cap->driver, DMA2D_NAME, sizeof(cap->driver));
> > +     strscpy(cap->card, DMA2D_NAME, sizeof(cap->card));
> > +     strscpy(cap->bus_info, BUS_INFO, sizeof(cap->bus_info));
> > +
> > +     return 0;
> > +}
> > +
> > +static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
> > +{
> > +     if (f->index >= NUM_FORMATS)
> > +             return -EINVAL;
> > +
> > +     f->pixelformat = formats[f->index].fourcc;
> > +     return 0;
> > +}
> > +
> > +static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
> > +{
> > +     struct dma2d_ctx *ctx = prv;
> > +     struct vb2_queue *vq;
> > +     struct dma2d_frame *frm;
> > +
> > +     vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
> > +     if (!vq)
> > +             return -EINVAL;
> > +
> > +     frm = get_frame(ctx, f->type);
> > +     if (IS_ERR(frm))
> > +             return PTR_ERR(frm);
> > +
> > +     f->fmt.pix.width                = frm->width;
> > +     f->fmt.pix.height               = frm->height;
> > +     f->fmt.pix.field                = V4L2_FIELD_NONE;
> > +     f->fmt.pix.pixelformat          = frm->fmt->fourcc;
> > +     f->fmt.pix.bytesperline         = (frm->width * frm->fmt->depth) >> 3;
> > +     f->fmt.pix.sizeimage            = frm->size;
> > +     f->fmt.pix.colorspace           = ctx->colorspace;
> > +     f->fmt.pix.xfer_func            = ctx->xfer_func;
> > +     f->fmt.pix.ycbcr_enc            = ctx->ycbcr_enc;
> > +     f->fmt.pix.quantization         = ctx->quant;
> > +
> > +     return 0;
> > +}
> > +
> > +static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
> > +{
> > +     struct dma2d_ctx *ctx = prv;
> > +     struct dma2d_dev *dev = ctx->dev;
> > +     struct dma2d_fmt *fmt;
> > +     enum v4l2_field *field;
> > +     u32 fourcc = f->fmt.pix.pixelformat;
> > +
> > +     fmt = find_fmt(fourcc);
> > +     if (!fmt) {
> > +             v4l2_warn(&dev->v4l2_dev,
> > +                       "Format not supported: %c%c%c%c, use the default.\n",
> > +                       (fourcc & 0xff),  (fourcc >>  8) & 0xff,
> > +                       (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff);
> > +             f->fmt.pix.pixelformat = formats[0].fourcc;
> > +             fmt = find_fmt(f->fmt.pix.pixelformat);
> > +     }
> > +
> > +     field = &f->fmt.pix.field;
> > +     if (*field == V4L2_FIELD_ANY)
> > +             *field = V4L2_FIELD_NONE;
> > +     else if (*field != V4L2_FIELD_NONE)
> > +             return -EINVAL;
> > +
> > +     if (f->fmt.pix.width > MAX_WIDTH)
> > +             f->fmt.pix.width = MAX_WIDTH;
> > +     if (f->fmt.pix.height > MAX_HEIGHT)
> > +             f->fmt.pix.height = MAX_HEIGHT;
> > +
> > +     if (f->fmt.pix.width < 1)
> > +             f->fmt.pix.width = 1;
> > +     if (f->fmt.pix.height < 1)
> > +             f->fmt.pix.height = 1;
> > +
> > +     if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && !f->fmt.pix.colorspace) {
> > +             f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
> > +     } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> > +             f->fmt.pix.colorspace   = ctx->colorspace;
> > +             f->fmt.pix.xfer_func = ctx->xfer_func;
> > +             f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
> > +             f->fmt.pix.quantization = ctx->quant;
> > +     }
> > +     f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
> > +     f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
> > +
> > +     return 0;
> > +}
> > +
> > +static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
> > +{
> > +     struct dma2d_ctx *ctx = prv;
> > +     struct dma2d_dev *dev = ctx->dev;
> > +     struct vb2_queue *vq;
> > +     struct dma2d_frame *frm;
> > +     struct dma2d_fmt *fmt;
> > +     int ret = 0;
> > +
> > +     /* Adjust all values accordingly to the hardware capabilities
> > +      * and chosen format.
> > +      */
> > +     ret = vidioc_try_fmt(file, prv, f);
> > +     if (ret)
> > +             return ret;
> > +
> > +     vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
> > +     if (vb2_is_busy(vq)) {
> > +             v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type);
> > +             return -EBUSY;
> > +     }
> > +
> > +     frm = get_frame(ctx, f->type);
> > +     if (IS_ERR(frm))
> > +             return PTR_ERR(frm);
> > +
> > +     fmt = find_fmt(f->fmt.pix.pixelformat);
> > +     if (!fmt)
> > +             return -EINVAL;
> > +
> > +     if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
> > +             ctx->colorspace = f->fmt.pix.colorspace;
> > +             ctx->xfer_func = f->fmt.pix.xfer_func;
> > +             ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
> > +             ctx->quant = f->fmt.pix.quantization;
> > +     }
> > +
> > +     frm->width      = f->fmt.pix.width;
> > +     frm->height     = f->fmt.pix.height;
> > +     frm->size       = f->fmt.pix.sizeimage;
> > +     /* Reset crop settings */
> > +     frm->o_width    = 0;
> > +     frm->o_height   = 0;
> > +     frm->c_width    = frm->width;
> > +     frm->c_height   = frm->height;
>
> Why store crop values when cropping is not supported? Just crop this, this seems to be
> copy-and-paste from the samsung driver.

dma2d controller supports cropping by OOR, FGOR, BGOR.
output/foreground/background offset register. but this part is working
now, i'll remove c_width, c_height at v3.

>
> > +     frm->right      = frm->width;
> > +     frm->bottom     = frm->height;
> > +     frm->fmt        = fmt;
> > +     frm->line_offset        = 0;
> > +     if (f->fmt.win.global_alpha != 0) {
>
> Huh? There is no f->fmt.win, this v4l2_format struct uses f->fmt.pix.

Thanks, I'll try to find another way for FGPFCCR.

>
> > +             frm->a_rgb[3] = f->fmt.win.global_alpha;
> > +             frm->a_mode = DMA2D_ALPHA_MODE_REPLACE;
>
> Again perhaps old copy-and-paste code from the samsung driver?

This driver is based on s5p-g2d, but the alpha part does not refer to s5p-g2d.
I'm still trying to find a reference about the overly on m2m driver,
but no luck.
imx-pxp does support the overlay feature, but their driver didn't
include that part.

m2m support capture/output, but for dma2d, it's need a third layer, which means
foreground + background => output, i can use m2m-output for dma2d-foreground,
m2m-capture for dma2d-output, but can't a layer for dma2d-background.

maybe v4l2_framebuffer is an option for it? Thanks
since the blend part is not ready, I will remove a_mode in v3.

>
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void device_run(void *prv)
> > +{
> > +     struct dma2d_ctx *ctx = prv;
> > +     struct dma2d_dev *dev = ctx->dev;
> > +     struct dma2d_frame *frm_out, *frm_cap;
> > +     struct vb2_v4l2_buffer *src, *dst;
> > +     unsigned long flags;
> > +
> > +     spin_lock_irqsave(&dev->ctrl_lock, flags);
> > +     dev->curr = ctx;
> > +
> > +     src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
> > +     dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
> > +     if (!dst || !src)
> > +             goto end;
> > +
> > +     frm_cap = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> > +     frm_out = get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
> > +     if (!frm_cap || !frm_out)
> > +             goto end;
> > +
> > +     src->sequence = frm_out->sequence++;
> > +     dst->sequence = frm_cap->sequence++;
> > +     v4l2_m2m_buf_copy_metadata(src, dst, true);
> > +
> > +     clk_enable(dev->gate);
> > +
> > +     dma2d_config_fg(dev, frm_out,
> > +                     vb2_dma_contig_plane_dma_addr(&src->vb2_buf, 0));
> > +
> > +     /* TODO: add M2M_BLEND handler here */
> > +
> > +     if (ctx->op_mode != DMA2D_MODE_R2M) {
> > +             if (frm_out->fmt->fourcc == frm_cap->fmt->fourcc)
> > +                     ctx->op_mode = DMA2D_MODE_M2M;
> > +             else
> > +                     ctx->op_mode = DMA2D_MODE_M2M_FPC;
> > +     }
> > +
> > +     dma2d_config_out(dev, frm_cap,
> > +                      vb2_dma_contig_plane_dma_addr(&dst->vb2_buf, 0));
> > +     dma2d_config_common(dev, ctx->op_mode, frm_cap->width, frm_cap->height);
> > +
> > +     dma2d_start(dev);
> > +end:
> > +     spin_unlock_irqrestore(&dev->ctrl_lock, flags);
> > +}
> > +
> > +static irqreturn_t dma2d_isr(int irq, void *prv)
> > +{
> > +     struct dma2d_dev *dev = prv;
> > +     struct dma2d_ctx *ctx = dev->curr;
> > +     struct vb2_v4l2_buffer *src, *dst;
> > +     u32 s = dma2d_get_int(dev);
> > +
> > +     if (s & ISR_TCIF || s == 0) {
> > +             dma2d_clear_int(dev);
> > +             clk_disable(dev->gate);
> > +
> > +             WARN_ON(!ctx);
> > +
> > +             src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
> > +             dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
> > +
> > +             WARN_ON(!dst);
> > +             WARN_ON(!src);
> > +
> > +             v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
> > +             v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
> > +             v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
> > +
> > +             dev->curr = NULL;
> > +     } else {
> > +             dma2d_clear_int(dev);
> > +     }
> > +
> > +     return IRQ_HANDLED;
> > +}
> > +
> > +static const struct v4l2_file_operations dma2d_fops = {
> > +     .owner          = THIS_MODULE,
> > +     .open           = dma2d_open,
> > +     .release        = dma2d_release,
> > +     .poll           = v4l2_m2m_fop_poll,
> > +     .unlocked_ioctl = video_ioctl2,
> > +     .mmap           = v4l2_m2m_fop_mmap,
> > +#ifndef CONFIG_MMU
> > +     .get_unmapped_area = v4l2_m2m_get_unmapped_area,
> > +#endif
> > +};
> > +
> > +static const struct v4l2_ioctl_ops dma2d_ioctl_ops = {
> > +     .vidioc_querycap        = vidioc_querycap,
> > +
> > +     .vidioc_enum_fmt_vid_cap        = vidioc_enum_fmt,
> > +     .vidioc_g_fmt_vid_cap           = vidioc_g_fmt,
> > +     .vidioc_try_fmt_vid_cap         = vidioc_try_fmt,
> > +     .vidioc_s_fmt_vid_cap           = vidioc_s_fmt,
> > +
> > +     .vidioc_enum_fmt_vid_out        = vidioc_enum_fmt,
> > +     .vidioc_g_fmt_vid_out           = vidioc_g_fmt,
> > +     .vidioc_try_fmt_vid_out         = vidioc_try_fmt,
> > +     .vidioc_s_fmt_vid_out           = vidioc_s_fmt,
> > +
> > +     .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
> > +     .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
> > +     .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
> > +     .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
> > +     .vidioc_prepare_buf             = v4l2_m2m_ioctl_prepare_buf,
> > +     .vidioc_create_bufs             = v4l2_m2m_ioctl_create_bufs,
> > +     .vidioc_expbuf                  = v4l2_m2m_ioctl_expbuf,
> > +
> > +     .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
> > +     .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
> > +
> > +     .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
> > +     .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> > +};
> > +
> > +static const struct video_device dma2d_videodev = {
> > +     .name           = DMA2D_NAME,
> > +     .fops           = &dma2d_fops,
> > +     .ioctl_ops      = &dma2d_ioctl_ops,
> > +     .minor          = -1,
> > +     .release        = video_device_release,
> > +     .vfl_dir        = VFL_DIR_M2M,
> > +};
> > +
> > +static const struct v4l2_m2m_ops dma2d_m2m_ops = {
> > +     .device_run     = device_run,
> > +};
> > +
> > +static const struct of_device_id stm32_dma2d_match[];
> > +
> > +static int dma2d_probe(struct platform_device *pdev)
> > +{
> > +     struct dma2d_dev *dev;
> > +     struct video_device *vfd;
> > +     struct resource *res;
> > +     int ret = 0;
> > +
> > +     dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
> > +     if (!dev)
> > +             return -ENOMEM;
> > +
> > +     spin_lock_init(&dev->ctrl_lock);
> > +     mutex_init(&dev->mutex);
> > +     atomic_set(&dev->num_inst, 0);
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +
> > +     dev->regs = devm_ioremap_resource(&pdev->dev, res);
> > +     if (IS_ERR(dev->regs))
> > +             return PTR_ERR(dev->regs);
> > +
> > +     dev->gate = clk_get(&pdev->dev, "dma2d");
> > +     if (IS_ERR(dev->gate)) {
> > +             dev_err(&pdev->dev, "failed to get dma2d clock gate\n");
> > +             ret = -ENXIO;
> > +             return ret;
> > +     }
> > +
> > +     ret = clk_prepare(dev->gate);
> > +     if (ret) {
> > +             dev_err(&pdev->dev, "failed to prepare dma2d clock gate\n");
> > +             goto put_clk_gate;
> > +     }
> > +
> > +     res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> > +     if (!res) {
> > +             dev_err(&pdev->dev, "failed to find IRQ\n");
> > +             ret = -ENXIO;
> > +             goto unprep_clk_gate;
> > +     }
> > +
> > +     dev->irq = res->start;
> > +
> > +     ret = devm_request_irq(&pdev->dev, dev->irq, dma2d_isr,
> > +                            0, pdev->name, dev);
> > +     if (ret) {
> > +             dev_err(&pdev->dev, "failed to install IRQ\n");
> > +             goto unprep_clk_gate;
> > +     }
> > +
> > +     ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
> > +     if (ret)
> > +             goto unprep_clk_gate;
> > +
> > +     vfd = video_device_alloc();
> > +     if (!vfd) {
> > +             v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
> > +             ret = -ENOMEM;
> > +             goto unreg_v4l2_dev;
> > +     }
> > +
> > +     *vfd = dma2d_videodev;
> > +     set_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags);
>
> Drop this quirk! Definitely copy-and-paste from the samsung driver, and not something
> you want or need here.

OK, I'll add crop feature in the future.

>
> > +     vfd->lock = &dev->mutex;
> > +     vfd->v4l2_dev = &dev->v4l2_dev;
> > +     vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
> > +     ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
>
> This must be done last, so move it to the end of the probe().

OK

>
> > +     if (ret) {
> > +             v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
> > +             goto rel_vdev;
> > +     }
> > +
> > +     video_set_drvdata(vfd, dev);
> > +     dev->vfd = vfd;
> > +     v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
> > +               vfd->num);
> > +     platform_set_drvdata(pdev, dev);
> > +     dev->m2m_dev = v4l2_m2m_init(&dma2d_m2m_ops);
> > +     if (IS_ERR(dev->m2m_dev)) {
> > +             v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
> > +             ret = PTR_ERR(dev->m2m_dev);
> > +             goto unreg_video_dev;
> > +     }
> > +
> > +     v4l2_info(&dev->v4l2_dev, "stm32 dma2d initialized\n");
> > +     return 0;
> > +
> > +unreg_video_dev:
> > +     video_unregister_device(dev->vfd);
> > +rel_vdev:
> > +     video_device_release(vfd);
> > +unreg_v4l2_dev:
> > +     v4l2_device_unregister(&dev->v4l2_dev);
> > +unprep_clk_gate:
> > +     clk_unprepare(dev->gate);
> > +put_clk_gate:
> > +     clk_put(dev->gate);
> > +
> > +     return ret;
> > +}
> > +
> > +static int dma2d_remove(struct platform_device *pdev)
> > +{
> > +     struct dma2d_dev *dev = platform_get_drvdata(pdev);
> > +
> > +     v4l2_info(&dev->v4l2_dev, "Removing " DMA2D_NAME);
> > +     v4l2_m2m_release(dev->m2m_dev);
> > +     video_unregister_device(dev->vfd);
> > +     v4l2_device_unregister(&dev->v4l2_dev);
> > +     vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> > +     clk_unprepare(dev->gate);
> > +     clk_put(dev->gate);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct of_device_id stm32_dma2d_match[] = {
> > +     {
> > +             .compatible = "st,stm32-dma2d",
> > +             .data = NULL,
> > +     },
> > +     {},
> > +};
> > +MODULE_DEVICE_TABLE(of, stm32_dma2d_match);
> > +
> > +static struct platform_driver dma2d_pdrv = {
> > +     .probe          = dma2d_probe,
> > +     .remove         = dma2d_remove,
> > +     .driver         = {
> > +             .name = DMA2D_NAME,
> > +             .of_match_table = stm32_dma2d_match,
> > +     },
> > +};
> > +
> > +module_platform_driver(dma2d_pdrv);
> > +
> > +MODULE_AUTHOR("Dillon Min <dillon.minfei at gmail.com>");
> > +MODULE_DESCRIPTION("STM32 Chrom-Art Accelerator DMA2D driver");
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/media/platform/stm32/dma2d/dma2d.h b/drivers/media/platform/stm32/dma2d/dma2d.h
> > new file mode 100644
> > index 000000000000..f317cf1dd35a
> > --- /dev/null
> > +++ b/drivers/media/platform/stm32/dma2d/dma2d.h
> > @@ -0,0 +1,136 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * ST stm32 DMA2D - 2D Graphics Accelerator Driver
> > + *
> > + * Copyright (c) 2021 Dillon Min
> > + * Dillon Min, <dillon.minfei at gmail.com>
> > + *
> > + * based on s5p-g2d
> > + *
> > + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> > + * Kamil Debski, <k.debski at samsung.com>
> > + */
> > +
> > +#ifndef __DMA2D_H__
> > +#define __DMA2D_H__
> > +
> > +#include <linux/platform_device.h>
> > +#include <media/v4l2-device.h>
> > +#include <media/v4l2-ctrls.h>
> > +
> > +#define DMA2D_NAME "stm-dma2d"
> > +#define BUS_INFO "platform:stm-dma2d"
> > +enum dma2d_op_mode {
> > +     DMA2D_MODE_M2M,
> > +     DMA2D_MODE_M2M_FPC,
> > +     DMA2D_MODE_M2M_BLEND,
> > +     DMA2D_MODE_R2M
> > +};
> > +
> > +enum dma2d_cmode {
> > +     /* output pfc cmode from ARGB888 to ARGB4444 */
> > +     DMA2D_CMODE_ARGB8888,
> > +     DMA2D_CMODE_RGB888,
> > +     DMA2D_CMODE_RGB565,
> > +     DMA2D_CMODE_ARGB1555,
> > +     DMA2D_CMODE_ARGB4444,
> > +     /* bg or fg pfc cmode from L8 to A4 */
> > +     DMA2D_CMODE_L8,
> > +     DMA2D_CMODE_AL44,
> > +     DMA2D_CMODE_AL88,
> > +     DMA2D_CMODE_L4,
> > +     DMA2D_CMODE_A8,
> > +     DMA2D_CMODE_A4
> > +};
> > +
> > +enum dma2d_alpha_mode {
> > +     DMA2D_ALPHA_MODE_NO_MODIF,
> > +     DMA2D_ALPHA_MODE_REPLACE,
> > +     DMA2D_ALPHA_MODE_COMBINE
> > +};
> > +
> > +struct dma2d_fmt {
> > +     u32     fourcc;
> > +     int     depth;
> > +     enum dma2d_cmode cmode;
> > +};
> > +
> > +struct dma2d_frame {
> > +     /* Original dimensions */
> > +     u32     width;
> > +     u32     height;
> > +     /* Crop size */
> > +     u32     c_width;
> > +     u32     c_height;
> > +     /* Offset */
> > +     u32     o_width;
> > +     u32     o_height;
> > +     u32     bottom;
> > +     u32     right;
> > +     u16     line_offset;
> > +     /* Image format */
> > +     struct dma2d_fmt *fmt;
> > +     /* [0]: blue
> > +      * [1]: green
> > +      * [2]: red
> > +      * [3]: alpha
> > +      */
> > +     u8      a_rgb[4];
> > +     /*
> > +      * AM[1:0] of DMA2D_FGPFCCR
> > +      */
> > +     enum dma2d_alpha_mode a_mode;
> > +     u32 size;
> > +     unsigned int    sequence;
> > +};
> > +
> > +struct dma2d_ctx {
> > +     struct v4l2_fh fh;
> > +     struct dma2d_dev        *dev;
> > +     struct dma2d_frame      cap;
> > +     struct dma2d_frame      out;
> > +     struct dma2d_frame      bg;
> > +     /* fb_buf always point to bg address */
> > +     struct v4l2_framebuffer fb_buf;
> > +     /*
> > +      * MODE[17:16] of DMA2D_CR
> > +      */
> > +     enum dma2d_op_mode      op_mode;
> > +     u8                      alpha_component;
> > +     struct v4l2_ctrl_handler ctrl_handler;
> > +     enum v4l2_colorspace    colorspace;
> > +     enum v4l2_ycbcr_encoding ycbcr_enc;
> > +     enum v4l2_xfer_func     xfer_func;
> > +     enum v4l2_quantization  quant;
> > +};
> > +
> > +struct dma2d_dev {
> > +     struct v4l2_device      v4l2_dev;
> > +     struct v4l2_m2m_dev     *m2m_dev;
> > +     struct video_device     *vfd;
> > +     /* for device open/close etc */
> > +     struct mutex            mutex;
> > +     /* to avoid the conflict with device running and user setting
> > +      * at the same time
> > +      */
> > +     spinlock_t              ctrl_lock;
> > +     atomic_t                num_inst;
> > +     void __iomem            *regs;
> > +     struct clk              *gate;
> > +     struct dma2d_ctx        *curr;
> > +     int irq;
> > +};
> > +
> > +void dma2d_start(struct dma2d_dev *d);
> > +u32 dma2d_get_int(struct dma2d_dev *d);
> > +void dma2d_clear_int(struct dma2d_dev *d);
> > +void dma2d_config_out(struct dma2d_dev *d, struct dma2d_frame *frm,
> > +                   dma_addr_t o_addr);
> > +void dma2d_config_fg(struct dma2d_dev *d, struct dma2d_frame *frm,
> > +                  dma_addr_t f_addr);
> > +void dma2d_config_bg(struct dma2d_dev *d, struct dma2d_frame *frm,
> > +                  dma_addr_t b_addr);
> > +void dma2d_config_common(struct dma2d_dev *d, enum dma2d_op_mode op_mode,
> > +                      u16 width, u16 height);
> > +
> > +#endif /* __DMA2D_H__ */
> >
>
> Regards,
>
>         Hans

Thanks and Best Regards.
Dillon


From rashmi.a at intel.com  Tue Aug 10 01:51:40 2021
From: rashmi.a at intel.com (A, Rashmi)
Date: Tue, 10 Aug 2021 08:51:40 +0000
Subject: [PATCH 3/3] phy: intel: Add Thunder Bay eMMC PHY support
In-Reply-To: <YQ0td9y5+RNFxWZs@matsya>
References: <20210730063309.8194-1-rashmi.a@intel.com>
 <20210730063309.8194-4-rashmi.a@intel.com> <YQ0td9y5+RNFxWZs@matsya>
Message-ID: <MWHPR11MB1789393D5B868B0DBF6FC0A28CF79@MWHPR11MB1789.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Vinod Koul <vkoul at kernel.org>
> Sent: Friday, August 6, 2021 6:09 PM
> To: A, Rashmi <rashmi.a at intel.com>
> Cc: linux-drivers-review-request at eclists.intel.com; michal.simek at xilinx.com;
> ulf.hansson at linaro.org; linux-mmc at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org; kishon at ti.com;
> andriy.shevchenko at linux.intel.com; linux-phy at lists.infradead.org;
> mgross at linux.intel.com; kris.pan at linux.intel.com; Zhou, Furong
> <furong.zhou at intel.com>; Sangannavar, Mallikarjunappa
> <mallikarjunappa.sangannavar at intel.com>; Hunter, Adrian
> <adrian.hunter at intel.com>; Vaidya, Mahesh R
> <mahesh.r.vaidya at intel.com>; Srikandan, Nandhini
> <nandhini.srikandan at intel.com>; Demakkanavar, Kenchappa
> <kenchappa.demakkanavar at intel.com>
> Subject: Re: [PATCH 3/3] phy: intel: Add Thunder Bay eMMC PHY support
> 
> On 30-07-21, 12:03, rashmi.a at intel.com wrote:
> 
> > diff --git a/drivers/phy/intel/Kconfig b/drivers/phy/intel/Kconfig
> > index ac42bb2fb394..18a3cc5b98c0 100644
> > --- a/drivers/phy/intel/Kconfig
> > +++ b/drivers/phy/intel/Kconfig
> > @@ -46,3 +46,13 @@ config PHY_INTEL_LGM_EMMC
> >  	select GENERIC_PHY
> >  	help
> >  	  Enable this to support the Intel EMMC PHY
> > +
> > +config PHY_INTEL_THUNDERBAY_EMMC
> 
> Alphabetical sort please
> 
> > +        tristate "Intel Thunder Bay eMMC PHY driver"
> > +        depends on OF && (ARCH_THUNDERBAY || COMPILE_TEST)
> > +        select GENERIC_PHY
> > +        help
> > +	  This option enables support for Intel Thunder Bay SoC eMMC PHY.
> > +
> > +	  To compile this driver as a module, choose M here: the module
> > +	  will be called phy-intel-thunderbay-emmc.ko.
> > diff --git a/drivers/phy/intel/Makefile b/drivers/phy/intel/Makefile
> > index 14550981a707..6a4db3ee7393 100644
> > --- a/drivers/phy/intel/Makefile
> > +++ b/drivers/phy/intel/Makefile
> > @@ -1,5 +1,6 @@
> >  # SPDX-License-Identifier: GPL-2.0
> >  obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC)	+= phy-intel-
> keembay-emmc.o
> > +obj-$(CONFIG_PHY_INTEL_THUNDERBAY_EMMC)	+= phy-intel-
> thunderbay-emmc.o
> 
> here as well
I will reorder the entry in Makefile. The Kconfig entries are in alphabetical order. Let me know if I am missing something.

-Rashmi
> 
> > +static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on)
> > +{
> > +	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
> > +	unsigned int freqsel = FREQSEL_200M_170M;
> > +	unsigned long rate;
> > +	static int lock;
> > +	u32 val;
> > +	int ret;
> > +
> > +	/* Disable DLL */
> > +	rate = clk_get_rate(tbh_phy->emmcclk);
> > +	switch (rate) {
> > +	case 200000000:
> > +	/* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0
> */
> > +		update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK,
> DLL_EN_SHIFT, 0x0);
> 
> pls keep the same indent for comment and code!
Acknowledged

-Rashmi
> 
> > +		break;
> > +	/* dll lock not required for other frequencies */
> > +	case 50000000 ... 52000000:
> > +	case 400000:
> > +	default:
> > +		break;
> > +	}
> > +
> > +	if (!power_on)
> > +		return 0;
> 
> should this not be the first thing you check...
During phy power on/off condition, dll should be disabled first. So power_on check is made after disabling dll.

-Rashmi
> 
> > +
> > +	rate = clk_get_rate(tbh_phy->emmcclk);
> > +	switch (rate) {
> > +	case 170000001 ... 200000000:
> > +		freqsel = FREQSEL_200M_170M;
> > +		break;
> > +	case 140000001 ... 170000000:
> > +		freqsel = FREQSEL_170M_140M;
> > +		break;
> > +	case 110000001 ... 140000000:
> > +		freqsel = FREQSEL_140M_110M;
> > +		break;
> > +	case 80000001 ... 110000000:
> > +		freqsel = FREQSEL_110M_80M;
> > +		break;
> > +	case 50000000 ... 80000000:
> > +		freqsel = FREQSEL_80M_50M;
> > +		break;
> > +	case 250000001 ... 275000000:
> > +		freqsel = FREQSEL_275M_250M;
> > +		break;
> > +	case 225000001 ... 250000000:
> > +		freqsel = FREQSEL_250M_225M;
> > +		break;
> > +	case 200000001 ... 225000000:
> > +		freqsel = FREQSEL_225M_200M;
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	if (rate > 200000000)
> > +	/* only the upper limit is considered as the clock rate may fall low
> during init */
> > +		dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
> 
> here as well! (checkpatch --strict should have told you so)
I will follow the proper alignment, though check-patch script didn't show any warnings.

-Rashmi
> 
> > +static int thunderbay_emmc_phy_power_on(struct phy *phy) {
> > +	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
> > +	unsigned long rate;
> > +
> > +	/* Overwrite capability bits configurable in bootloader */
> > +	update_reg(tbh_phy, CTRL_CFG_0,
> > +		   SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_0,
> > +		   SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1);
> > +	update_reg(tbh_phy, CTRL_CFG_1,
> > +		   SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1);
> > +
> > +	if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) {
> > +	/* Indicates initialization, so settings to be done for init , same as
> 400KHZ setting */
> > +		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
> > +SEL_DLY_TXCLK_SHIFT, 0x1);
> 
> inconsistent indent here too!
> 
> > +		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
> SEL_DLY_RXCLK_SHIFT, 0x1);
> > +		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
> ITAP_DLY_ENA_SHIFT, 0x0);
> > +		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
> ITAP_DLY_SEL_SHIFT, 0x0);
> > +		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
> OTAP_DLY_ENA_SHIFT, 0x0);
> > +		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
> OTAP_DLY_SEL_SHIFT, 0);
> > +		update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
> DLL_TRIM_ICP_SHIFT, 0);
> > +		update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
> DR_TY_SHIFT, 0x1);
> > +
> > +	} else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) {
> > +		/* Indicates actual clock setting */
> > +		rate = clk_get_rate(tbh_phy->emmcclk);
> > +		switch (rate) {
> > +		case 200000000:
> > +			update_reg(tbh_phy, PHY_CFG_0,
> SEL_DLY_TXCLK_MASK,
> > +				   SEL_DLY_TXCLK_SHIFT, 0x0);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> SEL_DLY_RXCLK_MASK,
> > +				   SEL_DLY_RXCLK_SHIFT, 0x0);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> ITAP_DLY_ENA_MASK,
> > +				   ITAP_DLY_ENA_SHIFT, 0x0);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> ITAP_DLY_SEL_MASK,
> > +				   ITAP_DLY_SEL_SHIFT, 0x0);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> OTAP_DLY_ENA_MASK,
> > +				   OTAP_DLY_ENA_SHIFT, 0x1);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> OTAP_DLY_SEL_MASK,
> > +				   OTAP_DLY_SEL_SHIFT, 2);
> > +			update_reg(tbh_phy, PHY_CFG_0,
> DLL_TRIM_ICP_MASK,
> > +				   DLL_TRIM_ICP_SHIFT, 0x8);
> > +			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
> > +				   DR_TY_SHIFT, 0x1);
> > +			/* For HS400 only */
> > +			update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK,
> > +				   SEL_STRB_SHIFT, STRB);
> > +			break;
> 
> pls give a empty line after break, helps to read the code
Acknowledged

-Rashmi


From dillon.minfei at gmail.com  Tue Aug 10 01:52:04 2021
From: dillon.minfei at gmail.com (Dillon Min)
Date: Tue, 10 Aug 2021 16:52:04 +0800
Subject: [PATCH v2 7/9] media: docs: add doc for the stm32 dma2d driver
In-Reply-To: <7131ee03-fc81-cb9b-665f-80e4ce8435ab@xs4all.nl>
References: <1626341068-20253-1-git-send-email-dillon.minfei@gmail.com>
 <1626341068-20253-18-git-send-email-dillon.minfei@gmail.com>
 <7131ee03-fc81-cb9b-665f-80e4ce8435ab@xs4all.nl>
Message-ID: <CAL9mu0+QF==63hzkLo1x=dVeXdnu7wyugmfQCRLsTE+=AJZWxw@mail.gmail.com>

Hi Hans

Thanks for the detailed review.

On Mon, 9 Aug 2021 at 17:16, Hans Verkuil <hverkuil-cisco at xs4all.nl> wrote:
>
> On 15/07/2021 11:24, dillon.minfei at gmail.com wrote:
> > From: Dillon Min <dillon.minfei at gmail.com>
> >
> > add stm32-uapi.rst for stm32's dma2d driver, explain the details of ioctl
> > V4L2_CID_DMA2D_R2M_MODE, V4L2_CID_DMA2D_R2M_COLOR.
> >
> > Signed-off-by: Dillon Min <dillon.minfei at gmail.com>
> > ---
> > v2: introduce the stm32-uapi.rst to explain the detail of dma2d's ioctl.
> >
> >  .../userspace-api/media/drivers/index.rst          |  1 +
> >  .../userspace-api/media/drivers/stm32-uapi.rst     | 22 ++++++++++++++++++++++
> >  2 files changed, 23 insertions(+)
> >  create mode 100644 Documentation/userspace-api/media/drivers/stm32-uapi.rst
> >
> > diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst
> > index 12e3c512d718..ce42915d48f4 100644
> > --- a/Documentation/userspace-api/media/drivers/index.rst
> > +++ b/Documentation/userspace-api/media/drivers/index.rst
> > @@ -38,4 +38,5 @@ For more details see the file COPYING in the source distribution of Linux.
> >       max2175
> >       meye-uapi
> >       omap3isp-uapi
> > +     stm32-uapi
> >       uvcvideo
> > diff --git a/Documentation/userspace-api/media/drivers/stm32-uapi.rst b/Documentation/userspace-api/media/drivers/stm32-uapi.rst
> > new file mode 100644
> > index 000000000000..d7a4f717387d
> > --- /dev/null
> > +++ b/Documentation/userspace-api/media/drivers/stm32-uapi.rst
> > @@ -0,0 +1,22 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +STM32 Chrom-Art 2D Graphics Accelerator unit (DMA2D) driver
> > +================================================
> > +
> > +The DMA2D driver implements the following driver-specific controls:
> > +
> > +``V4L2_CID_DMA2D_R2M_MODE``
>
> Please mention the control type as well.

OK, how about change to
``V4L2_CID_DMA2D_R2M_MODE (boolean)``

>
> > +-------------------------
> > +    Enable/Disable the Register-To-Memory mode, filling a part or the
> > +    whole of a destination image with a specific color.
> > +
> > +    1 for enable, 0 for disable.
> > +
> > +``V4L2_CID_DMA2D_R2M_COLOR``
>
> Ditto.

I will remove this item in v3, turn to use your suggestion (add
V4L2_COLORFX_SET_COLOR_ARGB to V4L2_CID_COLORFX)

>
> > +-------------------------------
> > +    Set the color to fill a part or the whole of a destination image.
> > +    only used under Register-To-Memory mode, to set the DMA2D_OCOLR register
> > +    (RED, GREEN, BLUE) which is:
>
> Here you mention RGB only,
>
> > +
> > +    31 .. 24    23 .. 16  15 .. 8     7 .. 0
> > +    ALPHA[7:0]  RED[7:0]  GREEN[7:0]  BLUE[7:0]
>
> but here you also mention Alpha. So which is it?

Anyway this will be removed in v3, give a short explanation about it,
The DMA2D_OCOLR register contains alpha value for m2m-pfc-blend mode,
which defines the alpha channel of the output color. it's not used for R2M.

sorry for confusion.

>
> See also my review of patch 9/9.
>
> >
>
> I'm getting some warnings building this doc:
>
> Documentation/media/userspace-api/drivers/stm32-uapi.rst:4: WARNING: Title underline too short.
>
> STM32 Chrom-Art 2D Graphics Accelerator unit (DMA2D) driver
> ================================================
> Documentation/media/userspace-api/drivers/stm32-uapi.rst:9: WARNING: Title underline too short.
>
> ``V4L2_CID_DMA2D_R2M_MODE``
> -------------------------

OK, will be fixed in v3.

>
> Regards,
>
>         Hans


Thanks and Best Regards
Dillon


From matthias.bgg at gmail.com  Tue Aug 10 01:52:40 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 10 Aug 2021 10:52:40 +0200
Subject: [v6 1/2] arm64: dts: mediatek: Add mt8192 clock controllers
In-Reply-To: <20210727023205.20319-2-chun-jie.chen@mediatek.com>
References: <20210727023205.20319-1-chun-jie.chen@mediatek.com>
 <20210727023205.20319-2-chun-jie.chen@mediatek.com>
Message-ID: <4517664b-7dd5-c338-69a9-86d0b6828f14@gmail.com>



On 27/07/2021 04:32, Chun-Jie Chen wrote:
> Add clock controller nodes for SoC mt8192
> 
> Signed-off-by: Weiyi Lu <weiyi.lu at mediatek.com>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Applied to v5.15-tmp/dst64

Please help making patch 2/2 better, adding clocks to all nodes.

Thanks a lot!
Matthias

> ---
>  arch/arm64/boot/dts/mediatek/mt8192.dtsi | 163 +++++++++++++++++++++++
>  1 file changed, 163 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> index 9757138a8bbd..c7c7d4e017ae 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> @@ -5,6 +5,7 @@
>   */
>  
>  /dts-v1/;
> +#include <dt-bindings/clock/mt8192-clk.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  #include <dt-bindings/interrupt-controller/irq.h>
>  #include <dt-bindings/pinctrl/mt8192-pinfunc.h>
> @@ -257,6 +258,24 @@
>  			};
>  		};
>  
> +		topckgen: syscon at 10000000 {
> +			compatible = "mediatek,mt8192-topckgen", "syscon";
> +			reg = <0 0x10000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		infracfg: syscon at 10001000 {
> +			compatible = "mediatek,mt8192-infracfg", "syscon";
> +			reg = <0 0x10001000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		pericfg: syscon at 10003000 {
> +			compatible = "mediatek,mt8192-pericfg", "syscon";
> +			reg = <0 0x10003000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		pio: pinctrl at 10005000 {
>  			compatible = "mediatek,mt8192-pinctrl";
>  			reg = <0 0x10005000 0 0x1000>,
> @@ -282,6 +301,12 @@
>  			#interrupt-cells = <2>;
>  		};
>  
> +		apmixedsys: syscon at 1000c000 {
> +			compatible = "mediatek,mt8192-apmixedsys", "syscon";
> +			reg = <0 0x1000c000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		systimer: timer at 10017000 {
>  			compatible = "mediatek,mt8192-timer",
>  				     "mediatek,mt6765-timer";
> @@ -291,6 +316,12 @@
>  			clock-names = "clk13m";
>  		};
>  
> +		scp_adsp: clock-controller at 10720000 {
> +			compatible = "mediatek,mt8192-scp_adsp";
> +			reg = <0 0x10720000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		uart0: serial at 11002000 {
>  			compatible = "mediatek,mt8192-uart",
>  				     "mediatek,mt6577-uart";
> @@ -311,6 +342,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_c: clock-controller at 11007000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_c";
> +			reg = <0 0x11007000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		spi0: spi at 1100a000 {
>  			compatible = "mediatek,mt8192-spi",
>  				     "mediatek,mt6765-spi";
> @@ -436,6 +473,12 @@
>  			status = "disable";
>  		};
>  
> +		audsys: clock-controller at 11210000 {
> +			compatible = "mediatek,mt8192-audsys", "syscon";
> +			reg = <0 0x11210000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c3: i2c3 at 11cb0000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11cb0000 0 0x1000>,
> @@ -449,6 +492,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_e: clock-controller at 11cb1000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_e";
> +			reg = <0 0x11cb1000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c7: i2c7 at 11d00000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11d00000 0 0x1000>,
> @@ -488,6 +537,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_s: clock-controller at 11d03000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_s";
> +			reg = <0 0x11d03000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c1: i2c1 at 11d20000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11d20000 0 0x1000>,
> @@ -527,6 +582,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_ws: clock-controller at 11d23000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_ws";
> +			reg = <0 0x11d23000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c5: i2c5 at 11e00000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11e00000 0 0x1000>,
> @@ -540,6 +601,12 @@
>  			status = "disabled";
>  		};
>  
> +		imp_iic_wrap_w: clock-controller at 11e01000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_w";
> +			reg = <0 0x11e01000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
>  		i2c0: i2c0 at 11f00000 {
>  			compatible = "mediatek,mt8192-i2c";
>  			reg = <0 0x11f00000 0 0x1000>,
> @@ -565,5 +632,101 @@
>  			#size-cells = <0>;
>  			status = "disabled";
>  		};
> +
> +		imp_iic_wrap_n: clock-controller at 11f02000 {
> +			compatible = "mediatek,mt8192-imp_iic_wrap_n";
> +			reg = <0 0x11f02000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		msdc_top: clock-controller at 11f10000 {
> +			compatible = "mediatek,mt8192-msdc_top";
> +			reg = <0 0x11f10000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		msdc: clock-controller at 11f60000 {
> +			compatible = "mediatek,mt8192-msdc";
> +			reg = <0 0x11f60000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		mfgcfg: clock-controller at 13fbf000 {
> +			compatible = "mediatek,mt8192-mfgcfg";
> +			reg = <0 0x13fbf000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		mmsys: syscon at 14000000 {
> +			compatible = "mediatek,mt8192-mmsys", "syscon";
> +			reg = <0 0x14000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		imgsys: clock-controller at 15020000 {
> +			compatible = "mediatek,mt8192-imgsys";
> +			reg = <0 0x15020000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		imgsys2: clock-controller at 15820000 {
> +			compatible = "mediatek,mt8192-imgsys2";
> +			reg = <0 0x15820000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		vdecsys_soc: clock-controller at 1600f000 {
> +			compatible = "mediatek,mt8192-vdecsys_soc";
> +			reg = <0 0x1600f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		vdecsys: clock-controller at 1602f000 {
> +			compatible = "mediatek,mt8192-vdecsys";
> +			reg = <0 0x1602f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		vencsys: clock-controller at 17000000 {
> +			compatible = "mediatek,mt8192-vencsys";
> +			reg = <0 0x17000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		camsys: clock-controller at 1a000000 {
> +			compatible = "mediatek,mt8192-camsys";
> +			reg = <0 0x1a000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		camsys_rawa: clock-controller at 1a04f000 {
> +			compatible = "mediatek,mt8192-camsys_rawa";
> +			reg = <0 0x1a04f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		camsys_rawb: clock-controller at 1a06f000 {
> +			compatible = "mediatek,mt8192-camsys_rawb";
> +			reg = <0 0x1a06f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		camsys_rawc: clock-controller at 1a08f000 {
> +			compatible = "mediatek,mt8192-camsys_rawc";
> +			reg = <0 0x1a08f000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		ipesys: clock-controller at 1b000000 {
> +			compatible = "mediatek,mt8192-ipesys";
> +			reg = <0 0x1b000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
> +
> +		mdpsys: clock-controller at 1f000000 {
> +			compatible = "mediatek,mt8192-mdpsys";
> +			reg = <0 0x1f000000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
>  	};
>  };
> 


From matthias.bgg at gmail.com  Tue Aug 10 01:58:52 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 10 Aug 2021 10:58:52 +0200
Subject: Aw: [PATCH v8, 2/2] soc: mediatek: mmsys: Add mt8192 mmsys
 routing table
In-Reply-To: <trinity-a5eeacb8-1625-4111-b613-19ee1609b902-1628062221917@3c-app-gmx-bap67>
References: <1627894773-23872-1-git-send-email-yongqiang.niu@mediatek.com>
 <1627894773-23872-3-git-send-email-yongqiang.niu@mediatek.com>
 <trinity-a5eeacb8-1625-4111-b613-19ee1609b902-1628062221917@3c-app-gmx-bap67>
Message-ID: <a09da534-274d-3eaf-6c4d-eb2a4817626b@gmail.com>



On 04/08/2021 09:30, Frank Wunderlich wrote:
> Hi
> 
> can you please test if your device still work after applying this
> 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20210729070549.5514-1-linux at fw-web.de/
> 
> and
> 
> duplicate value constants in your routes?
> 
> e.g. changing
> 
> +		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
> +		MT8192_DISP_OVL0_2L_MOUT_EN, MT8192_OVL0_MOUT_EN_DISP_RDMA0,
> 
> to
> 
> +		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA0,
> +		MT8192_DISP_OVL0_2L_MOUT_EN, MT8192_OVL0_MOUT_EN_DISP_RDMA0,
> +		MT8192_OVL0_MOUT_EN_DISP_RDMA0
> 
> regards Frank
> 

I did a fixup for that in v5.15-tmp/soc

Yongqiang, please test if this is working on the SoC.

Regards,
Matthias


From oupton at google.com  Tue Aug 10 02:09:46 2021
From: oupton at google.com (Oliver Upton)
Date: Tue, 10 Aug 2021 02:09:46 -0700
Subject: [PATCH 11/13] clocksource/arm_arch_timer: Fix masking for high
 freq counters
In-Reply-To: <87eeb1bsl6.wl-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-12-maz@kernel.org>
 <CAOQ_Qshfi=RN8fExhXQh1i640LAZaZjQSJApyvdU2Gva9KtFaQ@mail.gmail.com>
 <87eeb1bsl6.wl-maz@kernel.org>
Message-ID: <CAOQ_QsjWH5EL-ajadf4PT3R_0TqrucaN4c5m0YvOj6Foh00sQg@mail.gmail.com>

On Tue, Aug 10, 2021 at 1:40 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Mon, 09 Aug 2021 17:45:28 +0100,
> Oliver Upton <oupton at google.com> wrote:
> >
> > On Mon, Aug 9, 2021 at 8:48 AM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > From: Oliver Upton <oupton at google.com>
> > >
> > > Unfortunately, the architecture provides no means to determine the bit
> > > width of the system counter. However, we do know the following from the
> > > specification:
> > >
> > >  - the system counter is at least 56 bits wide
> > >  - Roll-over time of not less than 40 years
> > >
> > > To date, the arch timer driver has depended on the first property,
> > > assuming any system counter to be 56 bits wide and masking off the rest.
> > > However, combining a narrow clocksource mask with a high frequency
> > > counter could result in prematurely wrapping the system counter by a
> > > significant margin. For example, a 56 bit wide, 1GHz system counter
> > > would wrap in a mere 2.28 years!
> > >
> > > This is a problem for two reasons: v8.6+ implementations are required to
> > > provide a 64 bit, 1GHz system counter. Furthermore, before v8.6,
> > > implementers may select a counter frequency of their choosing.
> > >
> > > Fix the issue by deriving a valid clock mask based on the second
> > > property from above. Set the floor at 56 bits, since we know no system
> > > counter is narrower than that.
> > >
> > > Suggested-by: Marc Zyngier <maz at kernel.org>
> > > Signed-off-by: Oliver Upton <oupton at google.com>
> > > Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> > > [maz: fixed width computation not to lose the last bit, added
> > >       max delta generation for the timer]
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > Link: https://lore.kernel.org/r/20210807191428.3488948-1-oupton at google.com
> > > ---
> > >  drivers/clocksource/arm_arch_timer.c | 34 ++++++++++++++++++++++++----
> > >  1 file changed, 29 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> > > index fa09952b94bf..74eca831d0d9 100644
> > > --- a/drivers/clocksource/arm_arch_timer.c
> > > +++ b/drivers/clocksource/arm_arch_timer.c
> > > @@ -52,6 +52,12 @@
> > >  #define CNTV_CVAL_LO   0x30
> > >  #define CNTV_CTL       0x3c
> > >
> > > +/*
> > > + * The minimum amount of time a generic counter is guaranteed to not roll over
> > > + * (40 years)
> > > + */
> > > +#define MIN_ROLLOVER_SECS      (40ULL * 365 * 24 * 3600)
> > > +
> > >  static unsigned arch_timers_present __initdata;
> > >
> > >  struct arch_timer {
> > > @@ -95,6 +101,22 @@ static int __init early_evtstrm_cfg(char *buf)
> > >  }
> > >  early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
> > >
> > > +/*
> > > + * Makes an educated guess at a valid counter width based on the Generic Timer
> > > + * specification. Of note:
> > > + *   1) the system counter is at least 56 bits wide
> > > + *   2) a roll-over time of not less than 40 years
> > > + *
> > > + * See 'ARM DDI 0487G.a D11.1.2 ("The system counter")' for more details.
> > > + */
> > > +static int arch_counter_get_width(void)
> > > +{
> > > +       u64 min_cycles = MIN_ROLLOVER_SECS * arch_timer_rate;
> > > +
> > > +       /* guarantee the returned width is within the valid range */
> > > +       return clamp_val(ilog2(min_cycles - 1) + 1, 56, 64);
> > > +}
> >
> > Reposting thoughts from the original patch:
> >
> > Reading the ARM ARM
> > D11.1.2 'The system counter', I did not find any language that
> > suggested the counter saturates the register width before rolling
> > over. So, it may be paranoid, but I presumed it to be safer to wrap
> > within the guaranteed interval rather (40 years) than assume the
> > sanity of the system counter implementation.
>
> I really don't think that would be a likely implementation. The fact
> that the ARM ARM only talks about the width of the counter makes it a
> strong case that there is no 'ceiling' other than the natural
> saturation of the counter, IMO. If a rollover was allowed to occur
> before, it would definitely be mentioned.
>
> Think about it: you'd need to implement an extra comparator to drive
> the reset of the counter. It would also make the implementation of
> CVAL stupidly complicated: how do you handle the set of values that
> fit in the counter width, but are out of the counter range?
>
> Even though the architecture is not the clearest thing, I'm expecting
> the CPU designers to try and save gates, rather than trying to
> implement a GOTCHA, expensive counter... ;-)

Fair, I'll put the tinfoil away then :) Just wanted to avoid reading
between the lines, but it would be rather stunning to encounter
hardware in the wild that does this. Your additions to the patch LGTM.

--
Thanks,
Oliver


From linux at armlinux.org.uk  Tue Aug 10 02:12:38 2021
From: linux at armlinux.org.uk (Russell King - ARM Linux admin)
Date: Tue, 10 Aug 2021 10:12:38 +0100
Subject: [PATCH net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <20210810081616.wjx6jnlh3qxqsfm2@skbuf>
References: <20210809131152.509092-1-vladimir.oltean@nxp.com>
 <YRIhwQ3ji8eqPQOQ@unreal> <20210810081616.wjx6jnlh3qxqsfm2@skbuf>
Message-ID: <20210810091238.GB1343@shell.armlinux.org.uk>

On Tue, Aug 10, 2021 at 08:16:17AM +0000, Vladimir Oltean wrote:
> Hi Leon,
> 
> On Tue, Aug 10, 2021 at 09:50:41AM +0300, Leon Romanovsky wrote:
> > > +	memset(&send_info, 0, sizeof(send_info));
> > 
> > This can be written simpler.
> > struct switchdev_notifier_fdb_info send_info = {};
> > 
> > In all places.
> 
> Because the structure contains a sub-structure, I believe that a
> compound literal initializer would require additional braces for the
> initialization of its sub-objects too. At least I know that expressions
> like that have attracted the attention of clang people in the past:
> https://patchwork.ozlabs.org/project/netdev/patch/20190506202447.30907-1-natechancellor at gmail.com/
> So I went for the 'unambiguous' path.

There's a difference between:

	struct foo bar = { 0 };

and

	struct foo bar = { };

The former tells the compiler that you wish to set the first member of
struct foo, which will be an integer type, to zero. The latter is an
empty initialiser where all members and sub-members of the structure
default to a zero value.

You should have no problem with the latter. You will encounter problems
with the former if the first member of struct foo is not an integer
type.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From will at kernel.org  Tue Aug 10 02:16:19 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 10:16:19 +0100
Subject: [Freedreno] [PATCH 0/3] iommu/drm/msm: Allow non-coherent
 masters to use system cache
In-Reply-To: <76bfd0b4248148dfbf9d174ddcb4c2a2@codeaurora.org>
References: <20210802105544.GA27657@willie-the-truck>
 <CAF6AEGvtpFu8st=ZFNoKjP9YsAenciLxL1zMFi_iqMCvdby73w@mail.gmail.com>
 <20210802151409.GE28735@willie-the-truck>
 <CAF6AEGtzvyEUm0Fc8QT5t9KNK7i0FbFyi7zDM2_PMCzZBp7qbw@mail.gmail.com>
 <20210809145651.GC1458@willie-the-truck>
 <CAF6AEGsSUojA=V0n2iRWTCn++buqN=Eoxo0r3=+=PBu1O=H-AQ@mail.gmail.com>
 <20210809170508.GB1589@willie-the-truck>
 <CAF6AEGtmZ3LzAJdtnKDQDbEN-a6_JgdN-fZ96pkU3dZqkiW91g@mail.gmail.com>
 <20210809174022.GA1840@willie-the-truck>
 <76bfd0b4248148dfbf9d174ddcb4c2a2@codeaurora.org>
Message-ID: <20210810091619.GA2494@willie-the-truck>

On Mon, Aug 09, 2021 at 11:17:40PM +0530, Sai Prakash Ranjan wrote:
> On 2021-08-09 23:10, Will Deacon wrote:
> > On Mon, Aug 09, 2021 at 10:18:21AM -0700, Rob Clark wrote:
> > > On Mon, Aug 9, 2021 at 10:05 AM Will Deacon <will at kernel.org> wrote:
> > > > On Mon, Aug 09, 2021 at 09:57:08AM -0700, Rob Clark wrote:
> > > > > But I suppose we could call it instead IOMMU_QCOM_LLC or something
> > > > > like that to make it more clear that it is not necessarily something
> > > > > that would work with a different outer level cache implementation?
> > > >
> > > > ... or we could just deal with the problem so that other people can reuse
> > > > the code. I haven't really understood the reluctance to solve this properly.
> > > >
> > > > Am I missing some reason this isn't solvable?
> > > 
> > > Oh, was there another way to solve it (other than foregoing setting
> > > INC_OCACHE in the pgtables)?  Maybe I misunderstood, is there a
> > > corresponding setting on the MMU pgtables side of things?
> > 
> > Right -- we just need to program the CPU's MMU with the matching memory
> > attributes! It's a bit more fiddly if you're just using ioremap_wc()
> > though, as it's usually the DMA API which handles the attributes under
> > the
> > hood.
> > 
> > Anyway, sorry, I should've said that explicitly earlier on. We've done
> > this
> > sort of thing in the Android tree so I assumed Sai knew what needed to
> > be
> > done and then I didn't think to explain to you :(
> > 
> 
> Right I was aware of that but even in the android tree there is no user :)

I'm assuming there are vendor modules using it there, otherwise we wouldn't
have been asked to put it in. Since you work at Qualcomm, maybe you could
talk to your colleagues (Isaac and Patrick) directly?

> I think we can't have a new memory type without any user right in upstream
> like android tree?

Correct. But I don't think we should be adding IOMMU_* anything upstream
if we don't have a user.

Will


From liuqi115 at huawei.com  Mon Aug  9 22:53:28 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Tue, 10 Aug 2021 13:53:28 +0800
Subject: [PATCH v3 0/2] arm64: Enable OPTPROBE for arm64
Message-ID: <20210810055330.18924-1-liuqi115@huawei.com>

This patch introduce optprobe for ARM64, using a branch instruction
to replace probed instruction.

The test result on Hip08 platform is shown here, and optprobe could
reduce the latency to 1/4 of normal kprobe

kprobe before optimized:
[280709.846380] do_empty returned 0 and took 1530 ns to execute
[280709.852057] do_empty returned 0 and took 550 ns to execute
[280709.857631] do_empty returned 0 and took 440 ns to execute
[280709.863215] do_empty returned 0 and took 380 ns to execute
[280709.868787] do_empty returned 0 and took 360 ns to execute
[280709.874362] do_empty returned 0 and took 340 ns to execute
[280709.879936] do_empty returned 0 and took 320 ns to execute
[280709.885505] do_empty returned 0 and took 300 ns to execute
[280709.891075] do_empty returned 0 and took 280 ns to execute
[280709.896646] do_empty returned 0 and took 290 ns to execute
[280709.902220] do_empty returned 0 and took 290 ns to execute
[280709.907807] do_empty returned 0 and took 290 ns to execute

optprobe:
[ 2965.964572] do_empty returned 0 and took 90 ns to execute
[ 2965.969952] do_empty returned 0 and took 80 ns to execute
[ 2965.975332] do_empty returned 0 and took 70 ns to execute
[ 2965.980714] do_empty returned 0 and took 60 ns to execute
[ 2965.986128] do_empty returned 0 and took 80 ns to execute
[ 2965.991507] do_empty returned 0 and took 70 ns to execute
[ 2965.996884] do_empty returned 0 and took 70 ns to execute
[ 2966.002262] do_empty returned 0 and took 80 ns to execute
[ 2966.007642] do_empty returned 0 and took 70 ns to execute
[ 2966.013020] do_empty returned 0 and took 70 ns to execute
[ 2966.018400] do_empty returned 0 and took 70 ns to execute
[ 2966.023779] do_empty returned 0 and took 70 ns to execute
[ 2966.029158] do_empty returned 0 and took 70 ns to execute

Changes since V2:
- Address the comments from Masami, prepare another writable buffer in
arch_prepare_optimized_kprobe()and build the trampoline code on it.
- Address the comments from Amit, move save_all_base_regs and
restore_all_base_regs to <asm/assembler.h>, as these two macros are reused
in optprobe.
- Link: https://lore.kernel.org/lkml/20210804060209.95817-1-liuqi115 at huawei.com/

Changes since V1:
- Address the comments from Masami, checks for all branch instructions, and
use aarch64_insn_patch_text_nosync() instead of aarch64_insn_patch_text()
in each probe.
- Link: https://lore.kernel.org/lkml/20210719122417.10355-1-liuqi115 at huawei.com/

Qi Liu (2):
  arm64: assembler: Make save_all_base_regs and restore_all_base_regs common macros
  arm64: kprobe: Enable OPTPROBE for arm64

 arch/arm64/Kconfig                            |   1 +
 arch/arm64/include/asm/assembler.h            |  52 ++++
 arch/arm64/include/asm/kprobes.h              |  24 ++
 arch/arm64/kernel/probes/Makefile             |   2 +
 arch/arm64/kernel/probes/kprobes.c            |  19 +-
 arch/arm64/kernel/probes/kprobes_trampoline.S |  52 ----
 arch/arm64/kernel/probes/opt_arm64.c          | 239 ++++++++++++++++++
 .../arm64/kernel/probes/optprobe_trampoline.S |  37 +++
 8 files changed, 371 insertions(+), 55 deletions(-)
 create mode 100644 arch/arm64/kernel/probes/opt_arm64.c
 create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S

-- 
2.17.1



From liuqi115 at huawei.com  Mon Aug  9 22:53:30 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Tue, 10 Aug 2021 13:53:30 +0800
Subject: [PATCH v3 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210810055330.18924-1-liuqi115@huawei.com>
References: <20210810055330.18924-1-liuqi115@huawei.com>
Message-ID: <20210810055330.18924-3-liuqi115@huawei.com>

This patch introduce optprobe for ARM64. In optprobe, probed
instruction is replaced by a branch instruction to detour
buffer. Detour buffer contains trampoline code and a call to
optimized_callback(). optimized_callback() calls opt_pre_handler()
to execute kprobe handler.

Performance of optprobe on Hip08 platform is test using kprobe
example module[1] to analyze the latency of a kernel function,
and here is the result:

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c

kprobe before optimized:
[280709.846380] do_empty returned 0 and took 1530 ns to execute
[280709.852057] do_empty returned 0 and took 550 ns to execute
[280709.857631] do_empty returned 0 and took 440 ns to execute
[280709.863215] do_empty returned 0 and took 380 ns to execute
[280709.868787] do_empty returned 0 and took 360 ns to execute
[280709.874362] do_empty returned 0 and took 340 ns to execute
[280709.879936] do_empty returned 0 and took 320 ns to execute
[280709.885505] do_empty returned 0 and took 300 ns to execute
[280709.891075] do_empty returned 0 and took 280 ns to execute
[280709.896646] do_empty returned 0 and took 290 ns to execute
[280709.902220] do_empty returned 0 and took 290 ns to execute
[280709.907807] do_empty returned 0 and took 290 ns to execute

optprobe:
[ 2965.964572] do_empty returned 0 and took 90 ns to execute
[ 2965.969952] do_empty returned 0 and took 80 ns to execute
[ 2965.975332] do_empty returned 0 and took 70 ns to execute
[ 2965.980714] do_empty returned 0 and took 60 ns to execute
[ 2965.986128] do_empty returned 0 and took 80 ns to execute
[ 2965.991507] do_empty returned 0 and took 70 ns to execute
[ 2965.996884] do_empty returned 0 and took 70 ns to execute
[ 2966.002262] do_empty returned 0 and took 80 ns to execute
[ 2966.007642] do_empty returned 0 and took 70 ns to execute
[ 2966.013020] do_empty returned 0 and took 70 ns to execute
[ 2966.018400] do_empty returned 0 and took 70 ns to execute
[ 2966.023779] do_empty returned 0 and took 70 ns to execute
[ 2966.029158] do_empty returned 0 and took 70 ns to execute

Note:
To guarantee the offset between probe point and kprobe pre_handler
is smaller than 128MiB, users should set
CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
optprobe will not work and fall back to normal kprobe.

Signed-off-by: Qi Liu <liuqi115 at huawei.com>
---
 arch/arm64/Kconfig                            |   1 +
 arch/arm64/include/asm/kprobes.h              |  24 ++
 arch/arm64/kernel/probes/Makefile             |   2 +
 arch/arm64/kernel/probes/kprobes.c            |  19 +-
 arch/arm64/kernel/probes/opt_arm64.c          | 239 ++++++++++++++++++
 .../arm64/kernel/probes/optprobe_trampoline.S |  37 +++
 6 files changed, 319 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/kernel/probes/opt_arm64.c
 create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5b13a932561..b05d1d275d87 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -200,6 +200,7 @@ config ARM64
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_KPROBES
+	select HAVE_OPTPROBES
 	select HAVE_KRETPROBES
 	select HAVE_GENERIC_VDSO
 	select IOMMU_DMA if IOMMU_SUPPORT
diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
index 5d38ff4a4806..6b2fdd2ad7d8 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -39,6 +39,30 @@ void arch_remove_kprobe(struct kprobe *);
 int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
 int kprobe_exceptions_notify(struct notifier_block *self,
 			     unsigned long val, void *data);
+
+#define RELATIVEJUMP_SIZE (4)
+#define MAX_COPIED_INSN	DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
+struct arch_optimized_insn {
+	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
+	/* detour code buffer */
+	kprobe_opcode_t *insn;
+};
+
+/* optinsn template addresses */
+extern __visible kprobe_opcode_t optprobe_template_entry[];
+extern __visible kprobe_opcode_t optprobe_template_val[];
+extern __visible kprobe_opcode_t optprobe_template_call[];
+extern __visible kprobe_opcode_t optprobe_template_end[];
+extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
+extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
+extern __visible kprobe_opcode_t optprobe_template_restore_end[];
+extern __visible kprobe_opcode_t optprobe_template_max_length[];
+
+#define MAX_OPTIMIZED_LENGTH	4
+#define MAX_OPTINSN_SIZE				\
+	((unsigned long)optprobe_template_end -	\
+	 (unsigned long)optprobe_template_entry)
+
 void kretprobe_trampoline(void);
 void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
 
diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
index 8e4be92e25b1..07105fd3261d 100644
--- a/arch/arm64/kernel/probes/Makefile
+++ b/arch/arm64/kernel/probes/Makefile
@@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o decode-insn.o	\
 				   simulate-insn.o
 obj-$(CONFIG_UPROBES)		+= uprobes.o decode-insn.o	\
 				   simulate-insn.o
+obj-$(CONFIG_OPTPROBES)		+= opt_arm64.o			\
+				   optprobe_trampoline.o
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index 6dbcc89f6662..83755ad62abe 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -11,6 +11,7 @@
 #include <linux/kasan.h>
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
+#include <linux/moduleloader.h>
 #include <linux/sched/debug.h>
 #include <linux/set_memory.h>
 #include <linux/slab.h>
@@ -113,9 +114,21 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 
 void *alloc_insn_page(void)
 {
-	return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
-			GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
-			NUMA_NO_NODE, __builtin_return_address(0));
+	void *page;
+
+	page = module_alloc(PAGE_SIZE);
+	if (!page)
+		return NULL;
+
+	set_vm_flush_reset_perms(page);
+	/*
+	 * First make the page read-only, and only then make it executable to
+	 * prevent it from being W+X in between.
+	 */
+	set_memory_ro((unsigned long)page, 1);
+	set_memory_x((unsigned long)page, 1);
+
+	return page;
 }
 
 /* arm kprobe: install breakpoint in text */
diff --git a/arch/arm64/kernel/probes/opt_arm64.c b/arch/arm64/kernel/probes/opt_arm64.c
new file mode 100644
index 000000000000..d59b6a31a005
--- /dev/null
+++ b/arch/arm64/kernel/probes/opt_arm64.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Code for Kernel probes Jump optimization.
+ *
+ * Copyright (C) 2021 Hisilicon Limited
+ */
+
+#include <linux/jump_label.h>
+#include <linux/kprobes.h>
+
+#include <asm/cacheflush.h>
+#include <asm/insn.h>
+#include <asm/kprobes.h>
+#include <asm/patching.h>
+
+#define TMPL_VAL_IDX \
+	(optprobe_template_val - optprobe_template_entry)
+#define TMPL_CALL_BACK \
+	(optprobe_template_call - optprobe_template_entry)
+#define TMPL_END_IDX \
+	(optprobe_template_end - optprobe_template_entry)
+#define TMPL_RESTORE_ORIGN_INSN \
+	(optprobe_template_restore_orig_insn - optprobe_template_entry)
+#define TMPL_RESTORE_END \
+	(optprobe_template_restore_end - optprobe_template_entry)
+#define TMPL_MAX_LENGTH \
+	(optprobe_template_max_length - optprobe_template_entry)
+
+int arch_check_optimized_kprobe(struct optimized_kprobe *op)
+{
+	return 0;
+}
+
+int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
+{
+	return optinsn->insn != NULL;
+}
+
+int arch_within_optimized_kprobe(struct optimized_kprobe *op,
+				unsigned long addr)
+{
+	return ((unsigned long)op->kp.addr <= addr &&
+		(unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
+}
+
+static void
+optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
+{
+	/* This is possible if op is under delayed unoptimizing */
+	if (kprobe_disabled(&op->kp))
+		return;
+
+	preempt_disable();
+
+	if (kprobe_running()) {
+		kprobes_inc_nmissed_count(&op->kp);
+	} else {
+		__this_cpu_write(current_kprobe, &op->kp);
+		regs->pc = (unsigned long)op->kp.addr;
+		get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+		opt_pre_handler(&op->kp, regs);
+		__this_cpu_write(current_kprobe, NULL);
+	}
+
+	preempt_enable_no_resched();
+}
+NOKPROBE_SYMBOL(optimized_callback)
+
+static bool is_offset_in_range(unsigned long start, unsigned long end)
+{
+	long offset = end - start;
+
+	/*
+	 * Verify if the address gap is in 128MiB range, because this uses
+	 * a relative jump.
+	 *
+	 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
+	 * According to ARM manual, branch instruction is:
+	 *
+	 *   31  30                  25              0
+	 *  +----+---+---+---+---+---+---------------+
+	 *  |cond| 0 | 0 | 1 | 0 | 1 |     imm26     |
+	 *  +----+---+---+---+---+---+---------------+
+	 *
+	 * imm26 is a signed 26 bits integer. The real branch offset is computed
+	 * by: imm64 = SignExtend(imm26:'00', 64);
+	 *
+	 * So the maximum forward branch should be:
+	 *   (0x01ffffff << 2) = 0x07fffffc
+	 * The maximum backward branch should be:
+	 *   (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
+	 *
+	 * We can simply check (rel & 0xf8000003):
+	 *  if rel is positive, (rel & 0xf8000003) should be 0
+	 *  if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
+	 *  the last '3' is used for alignment checking.
+	 */
+	return (offset >= -0x8000000 && offset <= 0x7fffffc && !(offset & 0x3));
+}
+
+int arch_prepare_optimized_kprobe(struct optimized_kprobe *op,
+				  struct kprobe *orig)
+{
+	kprobe_opcode_t *code, *buf;
+	void **addrs;
+	u32 insn;
+	int ret, i;
+
+	addrs = kcalloc(TMPL_MAX_LENGTH, sizeof(void *), GFP_KERNEL);
+	if (!addrs)
+		return -ENOMEM;
+
+	buf = kcalloc(TMPL_MAX_LENGTH, sizeof(kprobe_opcode_t), GFP_KERNEL);
+	if (!buf) {
+		kfree(addrs);
+		return -ENOMEM;
+	}
+
+	code = get_optinsn_slot();
+	if (!code) {
+		kfree(addrs);
+		kfree(buf);
+		return -ENOMEM;
+	}
+
+	if (!is_offset_in_range((unsigned long)code,
+				(unsigned long)orig->addr + 8)) {
+		ret = -ERANGE;
+		goto error;
+	}
+
+	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
+				(unsigned long)optimized_callback)) {
+		ret = -ERANGE;
+		goto error;
+	}
+
+	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
+				(unsigned long)op->kp.addr + 4)) {
+		ret = -ERANGE;
+		goto error;
+	}
+
+	memcpy(buf, optprobe_template_entry,
+	       TMPL_END_IDX * sizeof(kprobe_opcode_t));
+
+	buf[TMPL_VAL_IDX] = FIELD_GET(GENMASK(31, 0), (unsigned long long)op);
+	buf[TMPL_VAL_IDX + 1] =
+		FIELD_GET(GENMASK(63, 32), (unsigned long long)op);
+	buf[TMPL_RESTORE_ORIGN_INSN] = orig->opcode;
+
+	insn = aarch64_insn_gen_branch_imm(
+		(unsigned long)(&code[TMPL_CALL_BACK]),
+		(unsigned long)optimized_callback, AARCH64_INSN_BRANCH_LINK);
+	buf[TMPL_CALL_BACK] = insn;
+
+	insn = aarch64_insn_gen_branch_imm(
+		(unsigned long)(&code[TMPL_RESTORE_END]),
+		(unsigned long)(op->kp.addr) + 4, AARCH64_INSN_BRANCH_NOLINK);
+	buf[TMPL_RESTORE_END] = insn;
+
+	/* Setup template */
+	for (i = 0; i < TMPL_MAX_LENGTH; i++)
+		addrs[i] = code + i;
+
+	ret = aarch64_insn_patch_text(addrs, buf, TMPL_MAX_LENGTH);
+	if (ret < 0)
+		goto error;
+
+	flush_icache_range((unsigned long)code,
+			   (unsigned long)(&code[TMPL_END_IDX]));
+
+	/* Set op->optinsn.insn means prepared. */
+	op->optinsn.insn = code;
+
+out:
+	kfree(addrs);
+	kfree(buf);
+	return ret;
+
+error:
+	free_optinsn_slot(code, 0);
+	goto out;
+}
+
+void arch_optimize_kprobes(struct list_head *oplist)
+{
+	struct optimized_kprobe *op, *tmp;
+
+	list_for_each_entry_safe(op, tmp, oplist, list) {
+		u32 insn;
+
+		WARN_ON(kprobe_disabled(&op->kp));
+
+		/*
+		 * Backup instructions which will be replaced
+		 * by jump address
+		 */
+		memcpy(op->optinsn.copied_insn, op->kp.addr,
+			RELATIVEJUMP_SIZE);
+		insn = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
+				(unsigned long)op->optinsn.insn,
+				AARCH64_INSN_BRANCH_NOLINK);
+
+		WARN_ON(insn == 0);
+
+		aarch64_insn_patch_text((void *)&(op->kp.addr), &insn, 1);
+
+		list_del_init(&op->list);
+	}
+}
+
+void arch_unoptimize_kprobe(struct optimized_kprobe *op)
+{
+	arch_arm_kprobe(&op->kp);
+}
+
+/*
+ * Recover original instructions and breakpoints from relative jumps.
+ * Caller must call with locking kprobe_mutex.
+ */
+void arch_unoptimize_kprobes(struct list_head *oplist,
+			    struct list_head *done_list)
+{
+	struct optimized_kprobe *op, *tmp;
+
+	list_for_each_entry_safe(op, tmp, oplist, list) {
+		arch_unoptimize_kprobe(op);
+		list_move(&op->list, done_list);
+	}
+}
+
+void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
+{
+	if (op->optinsn.insn) {
+		free_optinsn_slot(op->optinsn.insn, 1);
+		op->optinsn.insn = NULL;
+	}
+}
diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
new file mode 100644
index 000000000000..24d713d400cd
--- /dev/null
+++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * trampoline entry and return code for optprobes.
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+
+	.global optprobe_template_entry
+optprobe_template_entry:
+	sub sp, sp, #PT_REGS_SIZE
+	save_all_base_regs
+	/* Get parameters to optimized_callback() */
+	ldr	x0, 1f
+	mov	x1, sp
+	/* Branch to optimized_callback() */
+	.global optprobe_template_call
+optprobe_template_call:
+	nop
+	restore_all_base_regs
+	ldr lr, [sp, #S_LR]
+        add sp, sp, #PT_REGS_SIZE
+	.global optprobe_template_restore_orig_insn
+optprobe_template_restore_orig_insn:
+	nop
+	.global optprobe_template_restore_end
+optprobe_template_restore_end:
+	nop
+	.global optprobe_template_end
+optprobe_template_end:
+	.global optprobe_template_val
+optprobe_template_val:
+	1:	.long 0
+		.long 0
+	.global optprobe_template_max_length
+optprobe_template_max_length:
-- 
2.17.1



From liuqi115 at huawei.com  Mon Aug  9 22:53:29 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Tue, 10 Aug 2021 13:53:29 +0800
Subject: [PATCH v3 1/2] arm64: assembler: Make save_all_base_regs and
 restore_all_base_regs common macros
In-Reply-To: <20210810055330.18924-1-liuqi115@huawei.com>
References: <20210810055330.18924-1-liuqi115@huawei.com>
Message-ID: <20210810055330.18924-2-liuqi115@huawei.com>

Move save_all_base_regs and restore_all_base_regs to <asm/assembler.h>,
as these two macros can be reused in optprobe.

Signed-off-by: Qi Liu <liuqi115 at huawei.com>
---
 arch/arm64/include/asm/assembler.h            | 52 +++++++++++++++++++
 arch/arm64/kernel/probes/kprobes_trampoline.S | 52 -------------------
 2 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 89faca0e740d..cd912810fc80 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -515,6 +515,58 @@ alternative_endif
 	.pushsection "_kprobe_blacklist", "aw";	\
 	.quad	x;				\
 	.popsection;
+
+	.macro	save_all_base_regs
+	stp x0, x1, [sp, #S_X0]
+	stp x2, x3, [sp, #S_X2]
+	stp x4, x5, [sp, #S_X4]
+	stp x6, x7, [sp, #S_X6]
+	stp x8, x9, [sp, #S_X8]
+	stp x10, x11, [sp, #S_X10]
+	stp x12, x13, [sp, #S_X12]
+	stp x14, x15, [sp, #S_X14]
+	stp x16, x17, [sp, #S_X16]
+	stp x18, x19, [sp, #S_X18]
+	stp x20, x21, [sp, #S_X20]
+	stp x22, x23, [sp, #S_X22]
+	stp x24, x25, [sp, #S_X24]
+	stp x26, x27, [sp, #S_X26]
+	stp x28, x29, [sp, #S_X28]
+	add x0, sp, #PT_REGS_SIZE
+	stp lr, x0, [sp, #S_LR]
+	/*
+	 * Construct a useful saved PSTATE
+	 */
+	mrs x0, nzcv
+	mrs x1, daif
+	orr x0, x0, x1
+	mrs x1, CurrentEL
+	orr x0, x0, x1
+	mrs x1, SPSel
+	orr x0, x0, x1
+	stp xzr, x0, [sp, #S_PC]
+	.endm
+
+	.macro	restore_all_base_regs
+	ldr x0, [sp, #S_PSTATE]
+	and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
+	msr nzcv, x0
+	ldp x0, x1, [sp, #S_X0]
+	ldp x2, x3, [sp, #S_X2]
+	ldp x4, x5, [sp, #S_X4]
+	ldp x6, x7, [sp, #S_X6]
+	ldp x8, x9, [sp, #S_X8]
+	ldp x10, x11, [sp, #S_X10]
+	ldp x12, x13, [sp, #S_X12]
+	ldp x14, x15, [sp, #S_X14]
+	ldp x16, x17, [sp, #S_X16]
+	ldp x18, x19, [sp, #S_X18]
+	ldp x20, x21, [sp, #S_X20]
+	ldp x22, x23, [sp, #S_X22]
+	ldp x24, x25, [sp, #S_X24]
+	ldp x26, x27, [sp, #S_X26]
+	ldp x28, x29, [sp, #S_X28]
+	.endm
 #else
 #define NOKPROBE(x)
 #endif
diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S
index 288a84e253cc..2463d5d0e004 100644
--- a/arch/arm64/kernel/probes/kprobes_trampoline.S
+++ b/arch/arm64/kernel/probes/kprobes_trampoline.S
@@ -9,58 +9,6 @@
 
 	.text
 
-	.macro	save_all_base_regs
-	stp x0, x1, [sp, #S_X0]
-	stp x2, x3, [sp, #S_X2]
-	stp x4, x5, [sp, #S_X4]
-	stp x6, x7, [sp, #S_X6]
-	stp x8, x9, [sp, #S_X8]
-	stp x10, x11, [sp, #S_X10]
-	stp x12, x13, [sp, #S_X12]
-	stp x14, x15, [sp, #S_X14]
-	stp x16, x17, [sp, #S_X16]
-	stp x18, x19, [sp, #S_X18]
-	stp x20, x21, [sp, #S_X20]
-	stp x22, x23, [sp, #S_X22]
-	stp x24, x25, [sp, #S_X24]
-	stp x26, x27, [sp, #S_X26]
-	stp x28, x29, [sp, #S_X28]
-	add x0, sp, #PT_REGS_SIZE
-	stp lr, x0, [sp, #S_LR]
-	/*
-	 * Construct a useful saved PSTATE
-	 */
-	mrs x0, nzcv
-	mrs x1, daif
-	orr x0, x0, x1
-	mrs x1, CurrentEL
-	orr x0, x0, x1
-	mrs x1, SPSel
-	orr x0, x0, x1
-	stp xzr, x0, [sp, #S_PC]
-	.endm
-
-	.macro	restore_all_base_regs
-	ldr x0, [sp, #S_PSTATE]
-	and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
-	msr nzcv, x0
-	ldp x0, x1, [sp, #S_X0]
-	ldp x2, x3, [sp, #S_X2]
-	ldp x4, x5, [sp, #S_X4]
-	ldp x6, x7, [sp, #S_X6]
-	ldp x8, x9, [sp, #S_X8]
-	ldp x10, x11, [sp, #S_X10]
-	ldp x12, x13, [sp, #S_X12]
-	ldp x14, x15, [sp, #S_X14]
-	ldp x16, x17, [sp, #S_X16]
-	ldp x18, x19, [sp, #S_X18]
-	ldp x20, x21, [sp, #S_X20]
-	ldp x22, x23, [sp, #S_X22]
-	ldp x24, x25, [sp, #S_X24]
-	ldp x26, x27, [sp, #S_X26]
-	ldp x28, x29, [sp, #S_X28]
-	.endm
-
 SYM_CODE_START(kretprobe_trampoline)
 	sub sp, sp, #PT_REGS_SIZE
 
-- 
2.17.1



From lukasz.luba at arm.com  Tue Aug 10 02:17:58 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 10:17:58 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <cover.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <6449a61f-a5fc-0b81-65b2-7bf77b8a71aa@arm.com>

Hi Viresh,

I like the idea, only small comments here in the cover letter.

On 8/10/21 8:36 AM, Viresh Kumar wrote:
> Provide a cpufreq driver flag so drivers can ask the cpufreq core to register
> with the EM core on their behalf. This allows us to get rid of duplicated code
> in the drivers and fix the unregistration part as well, which none of the
> drivers have done until now.

The EM is never freed for CPUs by design. The unregister function was
introduced for devfreq devices.

> 
> This would also make the registration with EM core to happen only after policy
> is fully initialized, and the EM core can do other stuff from in there, like
> marking frequencies as inefficient (WIP). Though this patchset is useful without
> that work being done and should be merged nevertheless.
> 
> This doesn't update scmi cpufreq driver for now as it is a special case and need
> to be handled differently. Though we can make it work with this if required.

The scmi cpufreq driver uses direct EM API, which provides flexibility
and should stay as is.

Let me review the patches.

Regards,
Lukasz


From valentin.schneider at arm.com  Tue Aug 10 02:26:15 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Tue, 10 Aug 2021 10:26:15 +0100
Subject: [PATCH v2 2/4] sched: Introduce is_pcpu_safe()
In-Reply-To: <YRHnjQqf28/uFq+Z@boqun-archlinux>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
 <20210807005807.1083943-3-valentin.schneider@arm.com>
 <YRHnjQqf28/uFq+Z@boqun-archlinux>
Message-ID: <871r71abwo.mognet@arm.com>

Hi,

On 10/08/21 10:42, Boqun Feng wrote:
> Hi,
>
> On Sat, Aug 07, 2021 at 01:58:05AM +0100, Valentin Schneider wrote:
>> Some areas use preempt_disable() + preempt_enable() to safely access
>> per-CPU data. The PREEMPT_RT folks have shown this can also be done by
>> keeping preemption enabled and instead disabling migration (and acquiring a
>> sleepable lock, if relevant).
>> 
>> Introduce a helper which checks whether the current task can safely access
>> per-CPU data, IOW if the task's context guarantees the accesses will target
>> a single CPU. This accounts for preemption, CPU affinity, and migrate
>> disable - note that the CPU affinity check also mandates the presence of
>> PF_NO_SETAFFINITY, as otherwise userspace could concurrently render the
>> upcoming per-CPU access(es) unsafe.
>> 
>> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
>> ---
>>  include/linux/sched.h | 10 ++++++++++
>>  1 file changed, 10 insertions(+)
>> 
>> diff --git a/include/linux/sched.h b/include/linux/sched.h
>> index debc960f41e3..b77d65f677f6 100644
>> --- a/include/linux/sched.h
>> +++ b/include/linux/sched.h
>> @@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
>>  #endif
>>  }
>>  
>> +/* Is the current task guaranteed not to be migrated elsewhere? */
>> +static inline bool is_pcpu_safe(void)
>> +{
>> +#ifdef CONFIG_SMP
>> +	return !preemptible() || is_percpu_thread() || current->migration_disabled;
>> +#else
>> +	return true;
>> +#endif
>> +}
>
> I wonder whether the following can happen, say thread A is a worker
> thread for CPU 1, so it has the flag PF_NO_SETAFFINITY set.
>
> 	{ percpu variable X on CPU 2 is initially 0 }
>
> 	thread A
> 	========
>
> 	<preemption enabled>
> 	if (is_pcpu_safe()) { // nr_cpus_allowed == 1, so return true.
> 		<preempted>
> 		<hot unplug CPU 1>
> 			unbinder_workers(1); // A->cpus_mask becomes cpu_possible_mask
> 		<back to run on CPU 2>
> 		__this_cpu_inc(X);
> 		  tmp = X; // tmp == 0
> 		  <preempted>
> 		  <in thread B>
> 		  this_cpu_inc(X); // X becomes 1
> 		  <back to run A on CPU 2>
> 		  X = tmp + 1; // race!
> 	}
>
> if so, then is_percpu_thread() doesn't indicate is_pcpu_safe()?
>

You're absolutely right.

migrate_disable() protects the thread against being migrated due to
hotplug, but pure CPU affinity doesn't at all. kthread_is_per_cpu() doesn't
work either, because parking is not the only approach to hotplug for those
(e.g. per-CPU workqueue threads unbind themselves on hotplug, as in your
example).

One could hold cpus_read_lock(), but I don't see much point here. So that
has to be 

  return !preemptible() || current->migration_disabled;

Thanks!


From viresh.kumar at linaro.org  Tue Aug 10 02:27:05 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 10 Aug 2021 14:57:05 +0530
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <6449a61f-a5fc-0b81-65b2-7bf77b8a71aa@arm.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <6449a61f-a5fc-0b81-65b2-7bf77b8a71aa@arm.com>
Message-ID: <20210810092705.ctf43hwhzdepmcrv@vireshk-i7>

On 10-08-21, 10:17, Lukasz Luba wrote:
> Hi Viresh,
> 
> I like the idea, only small comments here in the cover letter.
> 
> On 8/10/21 8:36 AM, Viresh Kumar wrote:
> > Provide a cpufreq driver flag so drivers can ask the cpufreq core to register
> > with the EM core on their behalf. This allows us to get rid of duplicated code
> > in the drivers and fix the unregistration part as well, which none of the
> > drivers have done until now.
> 
> The EM is never freed for CPUs by design. The unregister function was
> introduced for devfreq devices.

I see. So if a cpufreq driver unregisters and registers again, it will
be required to use the entries created by the registration itself,
right ? Technically speaking, it is better to unregister and free any
related resources and parse everything again.

Lets say, just for fun, I want to test two copies of a cpufreq driver
(providing different set of freq-tables). I build both of them as
modules, insert the first version, remove it, insert the second one.
Ideally, this should just work as expected. But I don't think it will
in this case as you never parse the EM stuff again.

Again, since the routine is there already, I think it is better/fine
to just use it.

> > This would also make the registration with EM core to happen only after policy
> > is fully initialized, and the EM core can do other stuff from in there, like
> > marking frequencies as inefficient (WIP). Though this patchset is useful without
> > that work being done and should be merged nevertheless.
> > 
> > This doesn't update scmi cpufreq driver for now as it is a special case and need
> > to be handled differently. Though we can make it work with this if required.
> 
> The scmi cpufreq driver uses direct EM API, which provides flexibility
> and should stay as is.

Right, so I left it as is for now.

-- 
viresh


From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:39 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:39 +0200
Subject: [PATCH v2 2/8] dt-bindings: clock: samsung: add bindings for Exynos
 external clock
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210810093145.26153-3-krzysztof.kozlowski@canonical.com>

Document the bindings for Samsung Exynos external to SoC
(oscclk/XXTI/XusbXTI) clock provided on boards.  The bindings are
already implemented in most of the Exynos clock drivers and DTS files.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../clock/samsung,exynos-ext-clock.yaml       | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
new file mode 100644
index 000000000000..64d027dbe3b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-ext-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung SoC external/osc/XXTI/XusbXTI clock
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Samsung SoCs require an external clock supplied through XXTI or XusbXTI pins.
+
+properties:
+  compatible:
+    enum:
+      - samsung,clock-xxti
+      - samsung,clock-xusbxti
+      - samsung,exynos5420-oscclk
+
+  "#clock-cells":
+    const: 0
+
+  clock-frequency: true
+
+  clock-output-names:
+    maxItems: 1
+
+required:
+  - compatible
+  - clock-frequency
+
+additionalProperties: false
+
+examples:
+  - |
+    fixed-rate-clocks {
+        clock {
+            compatible = "samsung,clock-xxti";
+            clock-frequency = <24000000>;
+        };
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:40 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:40 +0200
Subject: [PATCH v2 3/8] dt-bindings: clock: samsung: convert Exynos542x to
 dtschema
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210810093145.26153-4-krzysztof.kozlowski@canonical.com>

Merge Exynos542x clock controller bindings to existing DT schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos5420-clock.txt       | 42 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  | 11 ++++-
 2 files changed, 10 insertions(+), 43 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
deleted file mode 100644
index 717a7b1531c7..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-* Samsung Exynos5420 Clock Controller
-
-The Exynos5420 clock controller generates and supplies clock to various
-controllers within the Exynos5420 SoC and for the Exynos5800 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
-  - "samsung,exynos5800-clock" - controller compatible with Exynos5800 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5420.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10010000 {
-		compatible = "samsung,exynos5420-clock";
-		reg = <0x10010000 0x30000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index cd6567bd8cc7..b0f58a1cf6cb 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -18,7 +18,16 @@ description: |
 
 properties:
   compatible:
-    const: samsung,exynos5250-clock
+    oneOf:
+      - enum:
+          - samsung,exynos5250-clock
+          - samsung,exynos5420-clock
+          - samsung,exynos5800-clock
+      - items:
+          - enum:
+              - samsung,exynos5420-clock
+              - samsung,exynos5800-clock
+          - const: syscon
 
   assigned-clocks: true
   assigned-clock-parents: true
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:41 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:41 +0200
Subject: [PATCH v2 4/8] dt-bindings: clock: samsung: convert Exynos3250 to
 dtschema
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210810093145.26153-5-krzysztof.kozlowski@canonical.com>

Merge Exynos3250 clock controller bindings to existing DT schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos3250-clock.txt       | 57 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  |  3 +
 2 files changed, 3 insertions(+), 57 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos3250-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/exynos3250-clock.txt b/Documentation/devicetree/bindings/clock/exynos3250-clock.txt
deleted file mode 100644
index 7441ed519f02..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos3250-clock.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-* Samsung Exynos3250 Clock Controller
-
-The Exynos3250 clock controller generates and supplies clock to various
-controllers within the Exynos3250 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos3250-cmu" - controller compatible with Exynos3250 SoC.
-  - "samsung,exynos3250-cmu-dmc" - controller compatible with
-    Exynos3250 SoC for Dynamic Memory Controller domain.
-  - "samsung,exynos3250-cmu-isp" - ISP block clock controller compatible
-     with Exynos3250 SOC
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos3250.h header and can be used in device
-tree sources.
-
-Example 1: Examples of clock controller nodes are listed below.
-
-	cmu: clock-controller at 10030000 {
-		compatible = "samsung,exynos3250-cmu";
-		reg = <0x10030000 0x20000>;
-		#clock-cells = <1>;
-	};
-
-	cmu_dmc: clock-controller at 105c0000 {
-		compatible = "samsung,exynos3250-cmu-dmc";
-		reg = <0x105C0000 0x2000>;
-		#clock-cells = <1>;
-	};
-
-	cmu_isp: clock-controller at 10048000 {
-		compatible = "samsung,exynos3250-cmu-isp";
-		reg = <0x10048000 0x1000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13800000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13800000 0x100>;
-		interrupts = <0 109 0>;
-		clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index b0f58a1cf6cb..c7b07fcd3fa1 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -20,6 +20,9 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - samsung,exynos3250-cmu
+          - samsung,exynos3250-cmu-dmc
+          - samsung,exynos3250-cmu-isp
           - samsung,exynos5250-clock
           - samsung,exynos5420-clock
           - samsung,exynos5800-clock
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:42 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:42 +0200
Subject: [PATCH v2 5/8] dt-bindings: clock: samsung: convert Exynos4 to
 dtschema
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210810093145.26153-6-krzysztof.kozlowski@canonical.com>

Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos4-clock.txt          | 86 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  | 29 ++++++-
 2 files changed, 28 insertions(+), 87 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
deleted file mode 100644
index 17bb11365354..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-* Samsung Exynos4 Clock Controller
-
-The Exynos4 clock controller generates and supplies clock to various controllers
-within the Exynos4 SoC. The clock binding described here is applicable to all
-SoC's in the Exynos4 family.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
-  - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos4.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10030000 {
-		compatible = "samsung,exynos4210-clock";
-		reg = <0x10030000 0x20000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
-
-Exynos4412 SoC contains some additional clocks for FIMC-ISP (Camera ISP)
-subsystem. Registers for those clocks are located in the ISP power domain.
-Because those registers are also located in a different memory region than
-the main clock controller, a separate clock controller has to be defined for
-handling them.
-
-Required Properties:
-
-- compatible: should be "samsung,exynos4412-isp-clock".
-
-- reg: physical base address of the ISP clock controller and length of memory
-  mapped region.
-
-- #clock-cells: should be 1.
-
-- clocks: list of the clock controller input clock identifiers,
-  from common clock bindings, should point to CLK_ACLK200 and
-  CLK_ACLK400_MCUISP clocks from the main clock controller.
-
-- clock-names: list of the clock controller input clock names,
-  as described in clock-bindings.txt, should be "aclk200" and
-  "aclk400_mcuisp".
-
-- power-domains: a phandle to ISP power domain node as described by
-  generic PM domain bindings.
-
-Example 3: The clock controllers bindings for Exynos4412 SoCs.
-
-	clock: clock-controller at 10030000 {
-		compatible = "samsung,exynos4412-clock";
-		reg = <0x10030000 0x18000>;
-		#clock-cells = <1>;
-	};
-
-	isp_clock: clock-controller at 10048000 {
-		compatible = "samsung,exynos4412-isp-clock";
-		reg = <0x10048000 0x1000>;
-		#clock-cells = <1>;
-		power-domains = <&pd_isp>;
-		clocks = <&clock CLK_ACLK200>, <&clock CLK_ACLK400_MCUISP>;
-		clock-names = "aclk200", "aclk400_mcuisp";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index c7b07fcd3fa1..ea73201f259b 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -23,6 +23,9 @@ properties:
           - samsung,exynos3250-cmu
           - samsung,exynos3250-cmu-dmc
           - samsung,exynos3250-cmu-isp
+          - samsung,exynos4210-clock
+          - samsung,exynos4412-clock
+          - samsung,exynos4412-isp-clock
           - samsung,exynos5250-clock
           - samsung,exynos5420-clock
           - samsung,exynos5800-clock
@@ -35,11 +38,18 @@ properties:
   assigned-clocks: true
   assigned-clock-parents: true
   assigned-clock-rates: true
-  clocks: true
+  clocks:
+    description: |
+      For samsung,exynos4412-isp-clock, the input clocks should be CLK_ACLK200
+      and CLK_ACLK400_MCUISP from the main clock controller.
+
+  clock-names: true
 
   "#clock-cells":
     const: 1
 
+  power-domains: true
+
   reg:
     maxItems: 1
 
@@ -50,6 +60,23 @@ required:
 
 additionalProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos4412-isp-clock
+    then:
+      properties:
+        clock-names:
+          items:
+            - const: aclk200
+            - const: aclk400_mcuisp
+      required:
+        - clocks
+        - clock-names
+        - power-domains
+
 examples:
   - |
     #include <dt-bindings/clock/exynos5250.h>
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:37 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:37 +0200
Subject: [PATCH v2 0/8] dt-bindings: clock: samsung: convert to dtschema
Message-ID: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>

Hi,

Combined patchset of separate v1 sets:

https://lore.kernel.org/linux-samsung-soc/20210809120544.56596-1-krzysztof.kozlowski at canonical.com/T/#t
https://lore.kernel.org/linux-samsung-soc/20210809130935.80565-1-krzysztof.kozlowski at canonical.com/T/#t
https://lore.kernel.org/linux-samsung-soc/20210809135942.100744-1-krzysztof.kozlowski at canonical.com/T/#t

Changes since v1:
1. Patch 7/8: include header to fix clock IDs error in example.

Best regards,
Krzysztof


Krzysztof Kozlowski (8):
  dt-bindings: clock: samsung: convert Exynos5250 to dtschema
  dt-bindings: clock: samsung: add bindings for Exynos external clock
  dt-bindings: clock: samsung: convert Exynos542x to dtschema
  dt-bindings: clock: samsung: convert Exynos3250 to dtschema
  dt-bindings: clock: samsung: convert Exynos4 to dtschema
  dt-bindings: clock: samsung: convert Exynos AudSS to dtschema
  dt-bindings: clock: samsung: convert S5Pv210 AudSS to dtschema
  MAINTAINERS: clock: include S3C and S5P in Samsung SoC clock entry

 .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
 .../bindings/clock/clk-s5pv210-audss.txt      |  53 ---------
 .../bindings/clock/exynos3250-clock.txt       |  57 ----------
 .../bindings/clock/exynos4-clock.txt          |  86 ---------------
 .../bindings/clock/exynos5250-clock.txt       |  41 -------
 .../bindings/clock/exynos5420-clock.txt       |  42 -------
 .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
 .../bindings/clock/samsung,exynos-clock.yaml  |  87 +++++++++++++++
 .../clock/samsung,exynos-ext-clock.yaml       |  46 ++++++++
 .../clock/samsung,s5pv210-audss-clock.yaml    |  77 +++++++++++++
 MAINTAINERS                                   |   4 +
 11 files changed, 293 insertions(+), 382 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos3250-clock.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml

-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:38 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:38 +0200
Subject: [PATCH v2 1/8] dt-bindings: clock: samsung: convert Exynos5250 to
 dtschema
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210810093145.26153-2-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos5250 clock controller bindings to DT schema format
using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos5250-clock.txt       | 41 ----------------
 .../bindings/clock/samsung,exynos-clock.yaml  | 48 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 3 files changed, 49 insertions(+), 41 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
deleted file mode 100644
index aff266a12eeb..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-* Samsung Exynos5250 Clock Controller
-
-The Exynos5250 clock controller generates and supplies clock to various
-controllers within the Exynos5250 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5250.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10010000 {
-		compatible = "samsung,exynos5250-clock";
-		reg = <0x10010000 0x30000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
new file mode 100644
index 000000000000..cd6567bd8cc7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  dt-bindings/clock/ headers.
+
+properties:
+  compatible:
+    const: samsung,exynos5250-clock
+
+  assigned-clocks: true
+  assigned-clock-parents: true
+  assigned-clock-rates: true
+  clocks: true
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5250.h>
+    clock: clock-controller at 10010000 {
+        compatible = "samsung,exynos5250-clock";
+        reg = <0x10010000 0x30000>;
+        #clock-cells = <1>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 36aee8517ab0..2dbacacac3f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16491,6 +16491,7 @@ L:	linux-samsung-soc at vger.kernel.org
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
 F:	Documentation/devicetree/bindings/clock/exynos*.txt
+F:	Documentation/devicetree/bindings/clock/samsung,*.yaml
 F:	Documentation/devicetree/bindings/clock/samsung,s3c*
 F:	Documentation/devicetree/bindings/clock/samsung,s5p*
 F:	drivers/clk/samsung/
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:43 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:43 +0200
Subject: [PATCH v2 6/8] dt-bindings: clock: samsung: convert Exynos AudSS to
 dtschema
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210810093145.26153-7-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
 .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
 2 files changed, 79 insertions(+), 103 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
deleted file mode 100644
index 6030afb10b5c..000000000000
--- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-* Samsung Audio Subsystem Clock Controller
-
-The Samsung Audio Subsystem clock controller generates and supplies clocks
-to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
-binding described here is applicable to all SoCs in Exynos family.
-
-Required Properties:
-
-- compatible: should be one of the following:
-  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
-  - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
-    SoCs.
-  - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
-    SoCs.
-  - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
-    SoCs.
-- reg: physical base address and length of the controller's register set.
-
-- #clock-cells: should be 1.
-
-- clocks:
-  - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
-    is used if not specified.
-  - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
-    is used if not specified.
-  - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
-    specified.
-  - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
-    not specified.
-  - sclk_pcm_in: PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not
-    specified.
-
-- clock-names: Aliases for the above clocks. They should be "pll_ref",
-  "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
-
-Optional Properties:
-
-  - power-domains: a phandle to respective power domain node as described by
-    generic PM domain bindings (see power/power_domain.txt for more
-    information).
-
-The following is the list of clocks generated by the controller. Each clock is
-assigned an identifier and client nodes use this identifier to specify the
-clock which they consume. Some of the clocks are available only on a particular
-Exynos4 SoC and this is specified where applicable.
-
-Provided clocks:
-
-Clock           ID      SoC (if specific)
------------------------------------------------
-
-mout_audss      0
-mout_i2s        1
-dout_srp        2
-dout_aud_bus    3
-dout_i2s        4
-srp_clk         5
-i2s_bus         6
-sclk_i2s        7
-pcm_bus         8
-sclk_pcm        9
-adma            10      Exynos5420
-
-Example 1: An example of a clock controller node using the default input
-	   clock names is listed below.
-
-clock_audss: audss-clock-controller at 3810000 {
-	compatible = "samsung,exynos5250-audss-clock";
-	reg = <0x03810000 0x0C>;
-	#clock-cells = <1>;
-};
-
-Example 2: An example of a clock controller node with the input clocks
-           specified.
-
-clock_audss: audss-clock-controller at 3810000 {
-	compatible = "samsung,exynos5250-audss-clock";
-	reg = <0x03810000 0x0C>;
-	#clock-cells = <1>;
-	clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
-		<&ext_i2s_clk>;
-	clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
-};
-
-Example 3: I2S controller node that consumes the clock generated by the clock
-           controller. Refer to the standard clock bindings for information
-           about 'clocks' and 'clock-names' property.
-
-i2s0: i2s at 3830000 {
-	compatible = "samsung,i2s-v5";
-	reg = <0x03830000 0x100>;
-	dmas = <&pdma0 10
-		&pdma0 9
-		&pdma0 8>;
-	dma-names = "tx", "rx", "tx-sec";
-	clocks = <&clock_audss EXYNOS_I2S_BUS>,
-		<&clock_audss EXYNOS_I2S_BUS>,
-		<&clock_audss EXYNOS_SCLK_I2S>,
-		<&clock_audss EXYNOS_MOUT_AUDSS>,
-		<&clock_audss EXYNOS_MOUT_I2S>;
-	clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
-		      "mout_audss", "mout_i2s";
-};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
new file mode 100644
index 000000000000..d60b29fa22e7
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-audss-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC Audio SubSystem clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/exynos-audss-clk.h header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos4210-audss-clock
+      - samsung,exynos5250-audss-clock
+      - samsung,exynos5410-audss-clock
+      - samsung,exynos5420-audss-clock
+
+  clocks:
+    minItems: 2
+    items:
+      - description:
+          Fixed rate PLL reference clock, parent of mout_audss. "fin_pll" is
+          used if not specified.
+      - description:
+          Input PLL to the AudioSS block, parent of mout_audss. "fout_epll" is
+          used if not specified.
+      - description:
+          Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if not
+          specified.
+      - description:
+          PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not specified.
+      - description:
+          External i2s clock, parent of mout_i2s. "cdclk0" is used if not
+          specified.
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: pll_ref
+      - const: pll_in
+      - const: sclk_audio
+      - const: sclk_pcm_in
+      - const: cdclk
+
+  "#clock-cells":
+    const: 1
+
+  power-domains: true
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 3810000 {
+        compatible = "samsung,exynos5250-audss-clock";
+        reg = <0x03810000 0x0c>;
+        #clock-cells = <1>;
+        clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>, <&ext_i2s_clk>;
+        clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:44 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:44 +0200
Subject: [PATCH v2 7/8] dt-bindings: clock: samsung: convert S5Pv210 AudSS to
 dtschema
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210810093145.26153-8-krzysztof.kozlowski@canonical.com>

Convert Samsung S5Pv210 Audio SubSystem clock controller bindings to DT
schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes since v1:
1. Include header to fix clock IDs error in example.
---
 .../bindings/clock/clk-s5pv210-audss.txt      | 53 -------------
 .../clock/samsung,s5pv210-audss-clock.yaml    | 77 +++++++++++++++++++
 2 files changed, 77 insertions(+), 53 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt b/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
deleted file mode 100644
index f6272dcd96f4..000000000000
--- a/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-* Samsung Audio Subsystem Clock Controller
-
-The Samsung Audio Subsystem clock controller generates and supplies clocks
-to Audio Subsystem block available in the S5PV210 and compatible SoCs.
-
-Required Properties:
-
-- compatible: should be "samsung,s5pv210-audss-clock".
-- reg: physical base address and length of the controller's register set.
-
-- #clock-cells: should be 1.
-
-- clocks:
-  - hclk: AHB bus clock of the Audio Subsystem.
-  - xxti: Optional fixed rate PLL reference clock, parent of mout_audss. If
-    not specified (i.e. xusbxti is used for PLL reference), it is fixed to
-    a clock named "xxti".
-  - fout_epll: Input PLL to the AudioSS block, parent of mout_audss.
-  - iiscdclk0: Optional external i2s clock, parent of mout_i2s. If not
-    specified, it is fixed to a clock named "iiscdclk0".
-  - sclk_audio0: Audio bus clock, parent of mout_i2s.
-
-- clock-names: Aliases for the above clocks. They should be "hclk",
-  "xxti", "fout_epll", "iiscdclk0", and "sclk_audio0" respectively.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/s5pv210-audss-clk.h header and can be used in device
-tree sources.
-
-Example: Clock controller node.
-
-	clk_audss: clock-controller at c0900000 {
-		compatible = "samsung,s5pv210-audss-clock";
-		reg = <0xc0900000 0x1000>;
-		#clock-cells = <1>;
-		clock-names = "hclk", "xxti",
-				"fout_epll", "sclk_audio0";
-		clocks = <&clocks DOUT_HCLKP>, <&xxti>,
-				<&clocks FOUT_EPLL>, <&clocks SCLK_AUDIO0>;
-	};
-
-Example: I2S controller node that consumes the clock generated by the clock
-	 controller. Refer to the standard clock bindings for information
-         about 'clocks' and 'clock-names' property.
-
-	i2s0: i2s at 3830000 {
-		/* ... */
-		clock-names = "iis", "i2s_opclk0",
-				"i2s_opclk1";
-		clocks = <&clk_audss CLK_I2S>, <&clk_audss CLK_I2S>,
-				<&clk_audss CLK_DOUT_AUD_BUS>;
-		/* ... */
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
new file mode 100644
index 000000000000..ef313df4afa4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,s5pv210-audss-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S5Pv210 SoC Audio SubSystem clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/s5pv210-audss.h header.
+
+properties:
+  compatible:
+    const: samsung,s5pv210-audss-clock
+
+  clocks:
+    minItems: 4
+    items:
+      - description:
+          AHB bus clock of the Audio Subsystem.
+      - description:
+          Optional fixed rate PLL reference clock, parent of mout_audss. If not
+          specified (i.e. xusbxti is used for PLL reference), it is fixed to a
+          clock named "xxti".
+      - description:
+          Input PLL to the AudioSS block, parent of mout_audss.
+      - description:
+          Audio bus clock, parent of mout_i2s.
+      - description:
+          Optional external i2s clock, parent of mout_i2s. If not specified, it
+          is fixed to a clock named "iiscdclk0".
+
+  clock-names:
+    minItems: 4
+    items:
+      - const: hclk
+      - const: xxti
+      - const: fout_epll
+      - const: sclk_audio0
+      - const: iiscdclk0
+
+  "#clock-cells":
+    const: 1
+
+  power-domains: true
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/s5pv210.h>
+
+    clock-controller at c0900000 {
+        compatible = "samsung,s5pv210-audss-clock";
+        reg = <0xc0900000 0x1000>;
+        #clock-cells = <1>;
+        clock-names = "hclk", "xxti", "fout_epll", "sclk_audio0";
+        clocks = <&clocks DOUT_HCLKP>, <&xxti>, <&clocks FOUT_EPLL>,
+                 <&clocks SCLK_AUDIO0>;
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Tue Aug 10 02:31:45 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 10 Aug 2021 11:31:45 +0200
Subject: [PATCH v2 8/8] MAINTAINERS: clock: include S3C and S5P in Samsung SoC
 clock entry
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210810093145.26153-9-krzysztof.kozlowski@canonical.com>

Cover the S3C and S5Pv210 clock controller binding headers by Samsung
SoC clock controller drivers maintainer entry.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2dbacacac3f5..4477215ef649 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16496,6 +16496,9 @@ F:	Documentation/devicetree/bindings/clock/samsung,s3c*
 F:	Documentation/devicetree/bindings/clock/samsung,s5p*
 F:	drivers/clk/samsung/
 F:	include/dt-bindings/clock/exynos*.h
+F:	include/dt-bindings/clock/s3c*.h
+F:	include/dt-bindings/clock/s5p*.h
+F:	include/dt-bindings/clock/samsung,*.h
 F:	include/linux/clk/samsung.h
 F:	include/linux/platform_data/clk-s3c2410.h
 
-- 
2.30.2



From vladimir.oltean at nxp.com  Tue Aug 10 02:34:57 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Tue, 10 Aug 2021 09:34:57 +0000
Subject: [PATCH net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <20210810091238.GB1343@shell.armlinux.org.uk>
References: <20210809131152.509092-1-vladimir.oltean@nxp.com>
 <YRIhwQ3ji8eqPQOQ@unreal> <20210810081616.wjx6jnlh3qxqsfm2@skbuf>
 <20210810091238.GB1343@shell.armlinux.org.uk>
Message-ID: <20210810093456.3ojqgvhe6ivo7sdr@skbuf>

On Tue, Aug 10, 2021 at 10:12:38AM +0100, Russell King - ARM Linux admin wrote:
> There's a difference between:
> 
> 	struct foo bar = { 0 };
> 
> and
> 
> 	struct foo bar = { };
> 
> The former tells the compiler that you wish to set the first member of
> struct foo, which will be an integer type, to zero. The latter is an
> empty initialiser where all members and sub-members of the structure
> default to a zero value.
> 
> You should have no problem with the latter. You will encounter problems
> with the former if the first member of struct foo is not an integer
> type.

Ok, that's good to know. Seeing that this patch has not been applied yet
I'll go for a v2.

From lukasz.luba at arm.com  Tue Aug 10 02:35:21 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 10:35:21 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <20210810092705.ctf43hwhzdepmcrv@vireshk-i7>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <6449a61f-a5fc-0b81-65b2-7bf77b8a71aa@arm.com>
 <20210810092705.ctf43hwhzdepmcrv@vireshk-i7>
Message-ID: <765a5fd5-1109-1af1-b339-624561070890@arm.com>



On 8/10/21 10:27 AM, Viresh Kumar wrote:
> On 10-08-21, 10:17, Lukasz Luba wrote:
>> Hi Viresh,
>>
>> I like the idea, only small comments here in the cover letter.
>>
>> On 8/10/21 8:36 AM, Viresh Kumar wrote:
>>> Provide a cpufreq driver flag so drivers can ask the cpufreq core to register
>>> with the EM core on their behalf. This allows us to get rid of duplicated code
>>> in the drivers and fix the unregistration part as well, which none of the
>>> drivers have done until now.
>>
>> The EM is never freed for CPUs by design. The unregister function was
>> introduced for devfreq devices.
> 
> I see. So if a cpufreq driver unregisters and registers again, it will
> be required to use the entries created by the registration itself,
> right ? Technically speaking, it is better to unregister and free any
> related resources and parse everything again.
> 
> Lets say, just for fun, I want to test two copies of a cpufreq driver

It's good that it's just for fun ;)

> (providing different set of freq-tables). I build both of them as
> modules, insert the first version, remove it, insert the second one.
> Ideally, this should just work as expected. But I don't think it will
> in this case as you never parse the EM stuff again.

The EM is directly used by scheduler in the hot-path, there are no
checks even if the EM if for CPUs. We are sure it's is for CPUs and
is always there for all CPUs.

I'm currently working on a EM v2 which would have stronger mechanisms
and do better job in this field. The patches are under internal review
and hopefully ready to post by the end of month.

> 
> Again, since the routine is there already, I think it is better/fine
> to just use it.

True, it doesn't harm, so I commented it in the patch 1/8 that it
could stay.

> 
>>> This would also make the registration with EM core to happen only after policy
>>> is fully initialized, and the EM core can do other stuff from in there, like
>>> marking frequencies as inefficient (WIP). Though this patchset is useful without
>>> that work being done and should be merged nevertheless.
>>>
>>> This doesn't update scmi cpufreq driver for now as it is a special case and need
>>> to be handled differently. Though we can make it work with this if required.
>>
>> The scmi cpufreq driver uses direct EM API, which provides flexibility
>> and should stay as is.
> 
> Right, so I left it as is for now.
> 


From maz at kernel.org  Tue Aug 10 02:35:50 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 10:35:50 +0100
Subject: [PATCH v6 13/21] KVM: arm64: Allow userspace to configure a
 vCPU's virtual offset
In-Reply-To: <20210804085819.846610-14-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-14-oupton@google.com>
Message-ID: <87czqlbq15.wl-maz@kernel.org>

On Wed, 04 Aug 2021 09:58:11 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Allow userspace to access the guest's virtual counter-timer offset
> through the ONE_REG interface. The value read or written is defined to
> be an offset from the guest's physical counter-timer. Add some
> documentation to clarify how a VMM should use this and the existing
> CNTVCT_EL0.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  Documentation/virt/kvm/api.rst    | 10 ++++++++++
>  arch/arm64/include/uapi/asm/kvm.h |  1 +
>  arch/arm64/kvm/arch_timer.c       | 11 +++++++++++
>  arch/arm64/kvm/guest.c            |  6 +++++-
>  include/kvm/arm_arch_timer.h      |  1 +
>  5 files changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index 8d4a3471ad9e..28a65dc89985 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -2487,6 +2487,16 @@ arm64 system registers have the following id bit patterns::
>       derived from the register encoding for CNTV_CVAL_EL0.  As this is
>       API, it must remain this way.
>  
> +.. warning::
> +
> +     The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from
> +     the guest's view of the physical counter-timer.
> +
> +     Userspace should use either KVM_REG_ARM_TIMER_OFFSET or
> +     KVM_REG_ARM_TIMER_CVAL to pause and resume a guest's virtual

You probably mean KVM_REG_ARM_TIMER_CNT here, despite the broken
encoding.

> +     counter-timer. Mixed use of these registers could result in an
> +     unpredictable guest counter value.
> +
>  arm64 firmware pseudo-registers have the following bit pattern::
>  
>    0x6030 0000 0014 <regno:16>
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index b3edde68bc3e..949a31bc10f0 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags {
>  #define KVM_REG_ARM_TIMER_CTL		ARM64_SYS_REG(3, 3, 14, 3, 1)
>  #define KVM_REG_ARM_TIMER_CVAL		ARM64_SYS_REG(3, 3, 14, 0, 2)
>  #define KVM_REG_ARM_TIMER_CNT		ARM64_SYS_REG(3, 3, 14, 3, 2)
> +#define KVM_REG_ARM_TIMER_OFFSET	ARM64_SYS_REG(3, 4, 14, 0, 3)

I don't think we can use the encoding for CNTPOFF_EL2 here, as it will
eventually clash with a NV guest using the same feature for its own
purpose. We don't want this offset to overlap with any of the existing
features.

I actually liked your previous proposal of controlling the physical
offset via a device property, as it clearly indicated that you were
dealing with non-architectural state.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From john.garry at huawei.com  Tue Aug 10 02:36:47 2021
From: john.garry at huawei.com (John Garry)
Date: Tue, 10 Aug 2021 10:36:47 +0100
Subject: [bug report] iommu_dma_unmap_sg() is very slow then running IO
 from remote numa node
In-Reply-To: <YQF1AKS6Y14dLU/A@T590>
References: <YPklDMng1hL3bQ+v@T590>
 <9c929985-4fcb-e65d-0265-34c820b770ea@huawei.com> <YPlGOOMSdm6Bcyy/@T590>
 <fc552129-e89d-74ad-9e57-30e3ffe4cf5d@huawei.com> <YPmUoBk9u+tU2rbS@T590>
 <0adbe03b-ce26-e4d3-3425-d967bc436ef5@arm.com> <YPqYDY9/VAhfHNfU@T590>
 <6ceab844-465f-3bf3-1809-5df1f1dbbc5c@huawei.com>
 <CAFj5m9J+9vO=CK3uPP+va5EoWffZj9ruSRe2fDDLXn+AE971CQ@mail.gmail.com>
 <ead87bf2-ddfa-eb67-db44-9619c6cdb714@huawei.com> <YQF1AKS6Y14dLU/A@T590>
Message-ID: <dfdd16e8-278f-3bc9-da97-a91264aec909@huawei.com>

On 28/07/2021 16:17, Ming Lei wrote:
>>>> Have you tried turning off the IOMMU to ensure that this is really just
>>>> an IOMMU problem?
>>>>
>>>> You can try setting CONFIG_ARM_SMMU_V3=n in the defconfig or passing
>>>> cmdline param iommu.passthrough=1 to bypass the the SMMU (equivalent to
>>>> disabling for kernel drivers).
>>> Bypassing SMMU via iommu.passthrough=1 basically doesn't make a difference
>>> on this issue.
>> A ~90% throughput drop still seems to me to be too high to be a software
>> issue. More so since I don't see similar on my system. And that throughput
>> drop does not lead to a total CPU usage drop, from the fio log.
>>
>> Do you know if anyone has run memory benchmark tests on this board to find
>> out NUMA effect? I think lmbench or stream could be used for this.
> https://lore.kernel.org/lkml/YOhbc5C47IzC893B at T590/

Hi Ming,

Out of curiosity, did you investigate this topic any further?

And you also asked about my results earlier:

On 22/07/2021 16:54, Ming Lei wrote:
 >> [   52.035895] nvme 0000:81:00.0: Adding to iommu group 5
 >> [   52.047732] nvme nvme0: pci function 0000:81:00.0
 >> [   52.067216] nvme nvme0: 22/0/2 default/read/poll queues
 >> [   52.087318]  nvme0n1: p1
 >>
 >> So I get these results:
 >> cpu0 335K
 >> cpu32 346K
 >> cpu64 300K
 >> cpu96 300K
 >>
 >> So still not massive changes.
 > In your last email, the results are the following with irq mode io_uring:
 >
 >   cpu0  497K
 >   cpu4  307K
 >   cpu32 566K
 >   cpu64 488K
 >   cpu96 508K
 >
 > So looks you get much worse result with real io_polling?
 >

Would the expectation be that at least I get the same performance with 
io_polling here? Anything else to try which you can suggest to 
investigate this lower performance?

Thanks,
John


From maz at kernel.org  Tue Aug 10 02:38:10 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 10:38:10 +0100
Subject: [PATCH v6 16/21] arm64: cpufeature: Enumerate support for
 Enhanced Counter Virtualization
In-Reply-To: <20210804085819.846610-17-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-17-oupton@google.com>
Message-ID: <87bl65bpx9.wl-maz@kernel.org>

On Wed, 04 Aug 2021 09:58:14 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Introduce a new cpucap to indicate if the system supports full enhanced
> counter virtualization (i.e. ID_AA64MMFR0_EL1.ECV==0x2).
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  arch/arm64/include/asm/sysreg.h |  2 ++
>  arch/arm64/kernel/cpufeature.c  | 10 ++++++++++
>  arch/arm64/tools/cpucaps        |  1 +
>  3 files changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 7b9c3acba684..4dfc44066dfb 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -847,6 +847,8 @@
>  #define ID_AA64MMFR0_ASID_SHIFT		4
>  #define ID_AA64MMFR0_PARANGE_SHIFT	0
>  
> +#define ID_AA64MMFR0_ECV_VIRT		0x1
> +#define ID_AA64MMFR0_ECV_PHYS		0x2
>  #define ID_AA64MMFR0_TGRAN4_NI		0xf
>  #define ID_AA64MMFR0_TGRAN4_SUPPORTED	0x0
>  #define ID_AA64MMFR0_TGRAN64_NI		0xf
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 0ead8bfedf20..94c349e179d3 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2301,6 +2301,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.matches = has_cpuid_feature,
>  		.min_field_value = 1,
>  	},
> +	{
> +		.desc = "Enhanced Counter Virtualization (Physical)",
> +		.capability = ARM64_ECV,
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.sys_reg = SYS_ID_AA64MMFR0_EL1,
> +		.sign = FTR_UNSIGNED,
> +		.field_pos = ID_AA64MMFR0_ECV_SHIFT,
> +		.matches = has_cpuid_feature,
> +		.min_field_value = ID_AA64MMFR0_ECV_PHYS,
> +	},
>  	{},
>  };
>  
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 49305c2e6dfd..d819ea614da5 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -3,6 +3,7 @@
>  # Internal CPU capabilities constants, keep this list sorted
>  
>  BTI
> +ECV
>  # Unreliable: use system_supports_32bit_el0() instead.
>  HAS_32BIT_EL0_DO_NOT_USE
>  HAS_32BIT_EL1

As discussed in another context, we probably want both ECV and ECV2 to
distinguish the two feature sets that ECV has so far.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From bbhushan2 at marvell.com  Tue Aug 10 02:43:03 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Tue, 10 Aug 2021 15:13:03 +0530
Subject: [PATCH v2 0/4] cn10k DDR Performance monitor support
Message-ID: <20210810094307.29595-1-bbhushan2@marvell.com>

This patch series adds DDR performance monitor support
on Marvell cn10k series of processor.

First patch adds device tree binding changes.
Second patch add basic support (without overflow and event
ownership). Third and fourth patch adds overflow and event
ownership respectively.

Seems like 4th patch can be merged in second patch,
For easy review it is currently separate
 
v1->v2:
 - DT binding changed to new DT Schema
 - writeq/readq changed to respective relaxed
 - Using PMU_EVENT_ATTR_ID

Bharat Bhushan (4):
  dt-bindings: perf: marvell: cn10k ddr performance monitor
  perf/marvell: CN10k DDR performance monitor support
  perf/marvell: cn10k DDR perfmon event overflow handling
  perf/marvell: cn10k DDR perf event core ownership

 .../bindings/perf/marvell-cn10k-ddr.yaml      |  37 +
 drivers/perf/Kconfig                          |   7 +
 drivers/perf/Makefile                         |   1 +
 drivers/perf/marvell_cn10k_ddr_pmu.c          | 763 ++++++++++++++++++
 include/linux/cpuhotplug.h                    |   1 +
 5 files changed, 809 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
 create mode 100644 drivers/perf/marvell_cn10k_ddr_pmu.c

-- 
2.17.1



From bbhushan2 at marvell.com  Tue Aug 10 02:43:04 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Tue, 10 Aug 2021 15:13:04 +0530
Subject: [PATCH v2 1/4] dt-bindings: perf: marvell: cn10k ddr performance
 monitor
In-Reply-To: <20210810094307.29595-1-bbhushan2@marvell.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
Message-ID: <20210810094307.29595-2-bbhushan2@marvell.com>

Add binding documentation for the Marvell CN10k DDR
performance monitor unit.

Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
---
v1->v2:
 - DT binding changed to new DT Schema

 .../bindings/perf/marvell-cn10k-ddr.yaml      | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml

diff --git a/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
new file mode 100644
index 000000000000..2a335444cf53
--- /dev/null
+++ b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/perf/marvell-cn10k-ddr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell CN10K DDR performance monitor
+
+maintainers:
+  - Bharat Bhushan <bbhushan2 at marvell.com>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - marvell,cn10k-ddr-pmu
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        ddrcpmu at 1 {
+            compatible = "marvell,cn10k-ddr-pmu";
+            reg = <0x87e1 0xc0000000 0x0 0x10000>;
+        };
+    };
-- 
2.17.1



From bbhushan2 at marvell.com  Tue Aug 10 02:43:05 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Tue, 10 Aug 2021 15:13:05 +0530
Subject: [PATCH v2 2/4] perf/marvell: CN10k DDR performance monitor support
In-Reply-To: <20210810094307.29595-1-bbhushan2@marvell.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
Message-ID: <20210810094307.29595-3-bbhushan2@marvell.com>

Marvell CN10k DRAM Subsystem (DSS) supports eight
event counters for monitoring performance and software
can program each counter to monitor any of the defined
performance event. Performance events are for interface
between the DDR controller and the PHY, interface between
the DDR Controller and the CHI interconnect, or within
the DDR Controller. Additionally DSS also supports two
fixed performance event counters, one for number of
ddr reads and other for ddr writes.

This patch add basic support for these performance
monitoring events on CN10k.

Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
---
v1->v2:
 - writeq/readq changed to respective relaxed version
 - Using PMU_EVENT_ATTR_ID

 drivers/perf/Kconfig                 |   7 +
 drivers/perf/Makefile                |   1 +
 drivers/perf/marvell_cn10k_ddr_pmu.c | 606 +++++++++++++++++++++++++++
 3 files changed, 614 insertions(+)
 create mode 100644 drivers/perf/marvell_cn10k_ddr_pmu.c

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 77522e5efe11..41a80a4b8d29 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -139,4 +139,11 @@ config ARM_DMC620_PMU
 
 source "drivers/perf/hisilicon/Kconfig"
 
+config MARVELL_CN10K_DDR_PMU
+	tristate "Enable MARVELL CN10K DRAM Subsystem(DSS) PMU Support"
+	depends on ARM64
+	help
+	  Enable perf support for Marvell DDR Performance monitoring
+	  event on CN10K platform.
+
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 5260b116c7da..ee1126219d8d 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
+obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
new file mode 100644
index 000000000000..8f9e3d1fcd8d
--- /dev/null
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -0,0 +1,606 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell CN10K DRAM Subsystem (DSS) Performance Monitor Driver
+ *
+ * Copyright (C) 2021 Marvell.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/perf_event.h>
+
+/* Performance Counters Operating Mode Control Registers */
+#define DDRC_PERF_CNT_OP_MODE_CTRL	0x8020
+#define OP_MODE_CTRL_VAL_MANNUAL	0x1
+
+/* Performance Counters Start Operation Control Registers */
+#define DDRC_PERF_CNT_START_OP_CTRL	0x8028
+#define START_OP_CTRL_VAL_START		0x1ULL
+#define START_OP_CTRL_VAL_ACTIVE	0x2
+
+/* Performance Counters End Operation Control Registers */
+#define DDRC_PERF_CNT_END_OP_CTRL	0x8030
+#define END_OP_CTRL_VAL_END		0x1ULL
+
+/* Performance Counters End Status Registers */
+#define DDRC_PERF_CNT_END_STATUS		0x8038
+#define END_STATUS_VAL_END_TIMER_MODE_END	0x1
+
+/* Performance Counters Configuration Registers */
+#define DDRC_PERF_CFG_BASE		0x8040
+
+/* 8 Generic event counter + 2 fixed event counters */
+#define DDRC_PERF_NUM_GEN_COUNTERS	8
+#define DDRC_PERF_NUM_FIX_COUNTERS	2
+#define DDRC_PERF_READ_COUNTER_IDX	DDRC_PERF_NUM_GEN_COUNTERS
+#define DDRC_PERF_WRITE_COUNTER_IDX	(DDRC_PERF_NUM_GEN_COUNTERS + 1)
+#define DDRC_PERF_NUM_COUNTERS		(DDRC_PERF_NUM_GEN_COUNTERS + \
+					 DDRC_PERF_NUM_FIX_COUNTERS)
+
+/* Generic event counter registers */
+#define DDRC_PERF_CFG(n)		(DDRC_PERF_CFG_BASE + 8 * (n))
+#define EVENT_ENABLE			BIT_ULL(63)
+
+/* Two dedicated event counters for DDR reads and writes */
+#define EVENT_DDR_READS			101
+#define EVENT_DDR_WRITES		100
+
+/*
+ * programmable events IDs in programmable event counters.
+ * DO NOT change these event-id numbers, they are used to
+ * program event bitmap in h/w.
+ */
+#define EVENT_OP_IS_ZQLATCH			55
+#define EVENT_OP_IS_ZQSTART			54
+#define EVENT_OP_IS_TCR_MRR			53
+#define EVENT_OP_IS_DQSOSC_MRR			52
+#define EVENT_OP_IS_DQSOSC_MPC			51
+#define EVENT_VISIBLE_WIN_LIMIT_REACHED_WR	50
+#define EVENT_VISIBLE_WIN_LIMIT_REACHED_RD	49
+#define EVENT_BSM_STARVATION			48
+#define EVENT_BSM_ALLOC				47
+#define EVENT_LPR_REQ_WITH_NOCREDIT		46
+#define EVENT_HPR_REQ_WITH_NOCREDIT		45
+#define EVENT_OP_IS_ZQCS			44
+#define EVENT_OP_IS_ZQCL			43
+#define EVENT_OP_IS_LOAD_MODE			42
+#define EVENT_OP_IS_SPEC_REF			41
+#define EVENT_OP_IS_CRIT_REF			40
+#define EVENT_OP_IS_REFRESH			39
+#define EVENT_OP_IS_ENTER_MPSM			35
+#define EVENT_OP_IS_ENTER_POWERDOWN		31
+#define EVENT_OP_IS_ENTER_SELFREF		27
+#define EVENT_WAW_HAZARD			26
+#define EVENT_RAW_HAZARD			25
+#define EVENT_WAR_HAZARD			24
+#define EVENT_WRITE_COMBINE			23
+#define EVENT_RDWR_TRANSITIONS			22
+#define EVENT_PRECHARGE_FOR_OTHER		21
+#define EVENT_PRECHARGE_FOR_RDWR		20
+#define EVENT_OP_IS_PRECHARGE			19
+#define EVENT_OP_IS_MWR				18
+#define EVENT_OP_IS_WR				17
+#define EVENT_OP_IS_RD				16
+#define EVENT_OP_IS_RD_ACTIVATE			15
+#define EVENT_OP_IS_RD_OR_WR			14
+#define EVENT_OP_IS_ACTIVATE			13
+#define EVENT_WR_XACT_WHEN_CRITICAL		12
+#define EVENT_LPR_XACT_WHEN_CRITICAL		11
+#define EVENT_HPR_XACT_WHEN_CRITICAL		10
+#define EVENT_DFI_RD_DATA_CYCLES		9
+#define EVENT_DFI_WR_DATA_CYCLES		8
+#define EVENT_ACT_BYPASS			7
+#define EVENT_READ_BYPASS			6
+#define EVENT_HIF_HI_PRI_RD			5
+#define EVENT_HIF_RMW				4
+#define EVENT_HIF_RD				3
+#define EVENT_HIF_WR				2
+#define EVENT_HIF_RD_OR_WR			1
+
+/* Event counter value registers */
+#define DDRC_PERF_CNT_VALUE_BASE		0x8080
+#define DDRC_PERF_CNT_VALUE(n)	(DDRC_PERF_CNT_VALUE_BASE + 8 * (n))
+
+/* Fixed event counter enable/disable register */
+#define DDRC_PERF_CNT_FREERUN_EN	0x80C0
+#define DDRC_PERF_FREERUN_WRITE_EN	0x1
+#define DDRC_PERF_FREERUN_READ_EN	0x2
+
+/* Fixed event counter control register */
+#define DDRC_PERF_CNT_FREERUN_CTRL	0x80C8
+#define DDRC_FREERUN_WRITE_CNT_CLR	0x1
+#define DDRC_FREERUN_READ_CNT_CLR	0x2
+
+/* Fixed event counter value register */
+#define DDRC_PERF_CNT_VALUE_WR_OP	0x80D0
+#define DDRC_PERF_CNT_VALUE_RD_OP	0x80D8
+#define DDRC_PERF_CNT_VALUE_OVERFLOW	BIT_ULL(48)
+#define DDRC_PERF_CNT_MAX_VALUE		GENMASK_ULL(48, 0)
+
+struct cn10k_ddr_pmu {
+	struct pmu pmu;
+	int id;
+	void __iomem *base;
+	unsigned int cpu;
+	struct	device *dev;
+	int active_events;
+	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
+};
+
+#define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu, pmu)
+
+static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
+					struct device_attribute *attr,
+					char *page)
+{
+	struct perf_pmu_events_attr *pmu_attr;
+
+	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
+	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+}
+
+#define CN10K_DDR_PMU_EVENT_ATTR(_name, _id)				     \
+	PMU_EVENT_ATTR_ID(_name, cn10k_ddr_pmu_event_show, _id)
+
+static struct attribute *cn10k_ddr_perf_events_attrs[] = {
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access, EVENT_HIF_RD_OR_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access, EVENT_HIF_RMW),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess, EVENT_HIF_HI_PRI_RD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access, EVENT_READ_BYPASS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access, EVENT_ACT_BYPASS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_wr_data_access, EVENT_DFI_WR_DATA_CYCLES),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_rd_data_access, EVENT_DFI_RD_DATA_CYCLES),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
+					EVENT_HPR_XACT_WHEN_CRITICAL),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
+					EVENT_LPR_XACT_WHEN_CRITICAL),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
+					EVENT_WR_XACT_WHEN_CRITICAL),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access, EVENT_OP_IS_ACTIVATE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access, EVENT_OP_IS_RD_OR_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access, EVENT_OP_IS_RD_ACTIVATE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge, EVENT_OP_IS_PRECHARGE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr, EVENT_PRECHARGE_FOR_RDWR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
+					EVENT_PRECHARGE_FOR_OTHER),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions, EVENT_RDWR_TRANSITIONS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine, EVENT_WRITE_COMBINE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard, EVENT_WAR_HAZARD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard, EVENT_RAW_HAZARD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard, EVENT_WAW_HAZARD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref, EVENT_OP_IS_ENTER_SELFREF),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown, EVENT_OP_IS_ENTER_POWERDOWN),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_mpsm, EVENT_OP_IS_ENTER_MPSM),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode, EVENT_OP_IS_LOAD_MODE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqcl, EVENT_OP_IS_ZQCL),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_wr_access, EVENT_OP_IS_ZQCS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpr_req_with_nocredit,
+					EVENT_HPR_REQ_WITH_NOCREDIT),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpr_req_with_nocredit,
+					EVENT_LPR_REQ_WITH_NOCREDIT),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_alloc, EVENT_BSM_ALLOC),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_starvation, EVENT_BSM_STARVATION),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
+					EVENT_VISIBLE_WIN_LIMIT_REACHED_RD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
+					EVENT_VISIBLE_WIN_LIMIT_REACHED_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc, EVENT_OP_IS_DQSOSC_MPC),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr, EVENT_OP_IS_DQSOSC_MRR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_OP_IS_TCR_MRR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_OP_IS_ZQSTART),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_OP_IS_ZQLATCH),
+	/* Free run event counters */
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
+	NULL,
+};
+
+static struct attribute_group cn10k_ddr_perf_events_attr_group = {
+	.name = "events",
+	.attrs = cn10k_ddr_perf_events_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-8");
+
+static struct attribute *cn10k_ddr_perf_format_attrs[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group cn10k_ddr_perf_format_attr_group = {
+	.name = "format",
+	.attrs = cn10k_ddr_perf_format_attrs,
+};
+
+static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
+
+	return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
+}
+
+static struct device_attribute cn10k_ddr_perf_cpumask_attr =
+	__ATTR(cpumask, 0444, cn10k_ddr_perf_cpumask_show, NULL);
+
+static struct attribute *cn10k_ddr_perf_cpumask_attrs[] = {
+	&cn10k_ddr_perf_cpumask_attr.attr,
+	NULL,
+};
+
+static struct attribute_group cn10k_ddr_perf_cpumask_attr_group = {
+	.attrs = cn10k_ddr_perf_cpumask_attrs,
+};
+
+static const struct attribute_group *cn10k_attr_groups[] = {
+	&cn10k_ddr_perf_events_attr_group,
+	&cn10k_ddr_perf_format_attr_group,
+	&cn10k_ddr_perf_cpumask_attr_group,
+	NULL,
+};
+
+static uint64_t ddr_perf_get_event_bitmap(int eventid)
+{
+	uint64_t event_bitmap = 0;
+
+	switch (eventid) {
+	case EVENT_HIF_RD_OR_WR ... EVENT_WAW_HAZARD:
+	case EVENT_OP_IS_REFRESH ... EVENT_OP_IS_ZQLATCH:
+		event_bitmap = (1ULL << (eventid - 1));
+		break;
+
+	case EVENT_OP_IS_ENTER_SELFREF:
+	case EVENT_OP_IS_ENTER_POWERDOWN:
+	case EVENT_OP_IS_ENTER_MPSM:
+		event_bitmap = (0xFULL << (eventid - 1));
+		break;
+	default:
+		pr_err("%s Invalid eventid %d\n", __func__, eventid);
+		break;
+	}
+
+	return event_bitmap;
+}
+
+static int cn10k_ddr_perf_alloc_counter(struct cn10k_ddr_pmu *pmu,
+					struct perf_event *event)
+{
+	uint8_t config = event->attr.config;
+	int i;
+
+	/* DDR read free-run counter index */
+	if (config == EVENT_DDR_READS) {
+		pmu->events[DDRC_PERF_READ_COUNTER_IDX] = event;
+		return DDRC_PERF_READ_COUNTER_IDX;
+	}
+
+	/* DDR write free-run counter index */
+	if (config == EVENT_DDR_WRITES) {
+		pmu->events[DDRC_PERF_WRITE_COUNTER_IDX] = event;
+		return DDRC_PERF_WRITE_COUNTER_IDX;
+	}
+
+	/* Allocate DDR generic counters */
+	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+		if (pmu->events[i] == NULL) {
+			pmu->events[i] = event;
+			return i;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static void cn10k_ddr_perf_free_counter(struct cn10k_ddr_pmu *pmu, int counter)
+{
+	pmu->events[counter] = NULL;
+}
+
+static int cn10k_ddr_perf_event_init(struct perf_event *event)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	if (is_sampling_event(event)) {
+		dev_info(pmu->dev, "Sampling not supported!\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (event->cpu < 0) {
+		dev_warn(pmu->dev, "Can't provide per-task data!\n");
+		return -EOPNOTSUPP;
+	}
+
+	/*  We must NOT create groups containing mixed PMUs */
+	if (event->group_leader->pmu != event->pmu &&
+			!is_software_event(event->group_leader))
+		return -EINVAL;
+
+	/* Set ownership of event to one CPU, same event can not be observed
+	 * on multiple cpus at same time.
+	 */
+	event->cpu = pmu->cpu;
+	hwc->idx = -1;
+	return 0;
+}
+
+static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
+					  int counter, bool enable)
+{
+	uint32_t reg;
+	uint64_t val;
+
+	if (counter > DDRC_PERF_NUM_COUNTERS) {
+		pr_err("Error: unsupported counter %d\n", counter);
+		return;
+	}
+
+	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
+		reg = DDRC_PERF_CFG(counter);
+		val = readq_relaxed(pmu->base + reg);
+
+		if (enable)
+			val |= EVENT_ENABLE;
+		else
+			val &= ~EVENT_ENABLE;
+
+		writeq_relaxed(val, pmu->base + reg);
+	} else {
+		val = readq_relaxed(pmu->base + DDRC_PERF_CNT_FREERUN_EN);
+		if (enable) {
+			if (counter == DDRC_PERF_READ_COUNTER_IDX)
+				val |= DDRC_PERF_FREERUN_READ_EN;
+			else
+				val |= DDRC_PERF_FREERUN_WRITE_EN;
+		} else {
+			if (counter == DDRC_PERF_READ_COUNTER_IDX)
+				val &= ~DDRC_PERF_FREERUN_READ_EN;
+			else
+				val &= ~DDRC_PERF_FREERUN_WRITE_EN;
+		}
+		writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_EN);
+	}
+}
+
+static uint64_t cn10k_ddr_perf_read_counter(struct cn10k_ddr_pmu *pmu,
+					    int counter)
+{
+	uint64_t val;
+
+	if (counter == DDRC_PERF_READ_COUNTER_IDX)
+		return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_RD_OP);
+
+	if (counter == DDRC_PERF_WRITE_COUNTER_IDX)
+		return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_WR_OP);
+
+	val = readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE(counter));
+	return val;
+}
+
+static void cn10k_ddr_perf_event_update(struct perf_event *event)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	uint64_t prev_count, new_count, mask;
+
+	do {
+		prev_count = local64_read(&hwc->prev_count);
+		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+	} while (local64_xchg(&hwc->prev_count, new_count) != prev_count);
+
+	mask = DDRC_PERF_CNT_MAX_VALUE;
+
+	local64_add((new_count - prev_count) & mask, &event->count);
+}
+
+static void cn10k_ddr_perf_event_start(struct perf_event *event, int flags)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int counter = hwc->idx;
+
+	local64_set(&hwc->prev_count, 0);
+
+	cn10k_ddr_perf_counter_enable(pmu, counter, true);
+
+	hwc->state = 0;
+}
+
+static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	uint8_t config = event->attr.config;
+	uint32_t reg_offset;
+	uint64_t val;
+	int counter;
+
+	counter = cn10k_ddr_perf_alloc_counter(pmu, event);
+	if (counter < 0) {
+		dev_dbg(pmu->dev, "There are not enough counters\n");
+		return -EOPNOTSUPP;
+	}
+
+	pmu->active_events++;
+	hwc->idx = counter;
+
+	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
+		/* Generic counters, configure event id */
+		reg_offset = DDRC_PERF_CFG(counter);
+		val = ddr_perf_get_event_bitmap(config);
+		writeq_relaxed(val, pmu->base + reg_offset);
+	} else {
+		/* fixed event counter, clear counter value */
+		if (counter == DDRC_PERF_READ_COUNTER_IDX)
+			val = DDRC_FREERUN_READ_CNT_CLR;
+		else
+			val = DDRC_FREERUN_WRITE_CNT_CLR;
+
+		writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_CTRL);
+	}
+
+	hwc->state |= PERF_HES_STOPPED;
+
+	if (flags & PERF_EF_START)
+		cn10k_ddr_perf_event_start(event, flags);
+
+	return 0;
+}
+
+static void cn10k_ddr_perf_event_stop(struct perf_event *event, int flags)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int counter = hwc->idx;
+
+	cn10k_ddr_perf_counter_enable(pmu, counter, false);
+
+	if (flags & PERF_EF_UPDATE)
+		cn10k_ddr_perf_event_update(event);
+
+	hwc->state |= PERF_HES_STOPPED;
+}
+
+static void cn10k_ddr_perf_event_del(struct perf_event *event, int flags)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int counter = hwc->idx;
+
+	cn10k_ddr_perf_event_stop(event, PERF_EF_UPDATE);
+
+	cn10k_ddr_perf_free_counter(pmu, counter);
+	pmu->active_events--;
+	hwc->idx = -1;
+}
+
+static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu)
+{
+	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
+
+	writeq_relaxed(START_OP_CTRL_VAL_START, ddr_pmu->base +
+		       DDRC_PERF_CNT_START_OP_CTRL);
+}
+
+static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu)
+{
+	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
+
+	writeq_relaxed(END_OP_CTRL_VAL_END, ddr_pmu->base +
+		       DDRC_PERF_CNT_END_OP_CTRL);
+}
+
+static int cn10k_ddr_perf_probe(struct platform_device *pdev)
+{
+	struct cn10k_ddr_pmu *ddr_pmu;
+	struct resource *res;
+	void __iomem *base;
+	static int index;
+	char *name;
+	int ret;
+
+	ddr_pmu = devm_kzalloc(&pdev->dev, sizeof(*ddr_pmu), GFP_KERNEL);
+	if (!ddr_pmu)
+		return -ENOMEM;
+
+	ddr_pmu->dev = &pdev->dev;
+	platform_set_drvdata(pdev, ddr_pmu);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	ddr_pmu->base = base;
+
+	/* Setup the PMU counter to work in mannual mode */
+	writeq_relaxed(OP_MODE_CTRL_VAL_MANNUAL, ddr_pmu->base +
+		       DDRC_PERF_CNT_OP_MODE_CTRL);
+
+	ddr_pmu->pmu = (struct pmu) {
+		.module	      = THIS_MODULE,
+		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+		.task_ctx_nr = perf_invalid_context,
+		.attr_groups = cn10k_attr_groups,
+		.event_init  = cn10k_ddr_perf_event_init,
+		.add	     = cn10k_ddr_perf_event_add,
+		.del	     = cn10k_ddr_perf_event_del,
+		.start	     = cn10k_ddr_perf_event_start,
+		.stop	     = cn10k_ddr_perf_event_stop,
+		.read	     = cn10k_ddr_perf_event_update,
+		.pmu_enable  = cn10k_ddr_perf_pmu_enable,
+		.pmu_disable = cn10k_ddr_perf_pmu_disable,
+	};
+
+	/* Choose this cpu to collect perf data */
+	ddr_pmu->cpu = raw_smp_processor_id();
+
+	name = devm_kasprintf(ddr_pmu->dev, GFP_KERNEL, "mrvl_ddr_pmu@%llx",
+			      res->start);
+	if (!name)
+		return -ENOMEM;
+
+	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
+	if (ret)
+		return ret;
+
+	ddr_pmu->id = index++;
+	pr_info("CN10K DDR PMU Driver for ddrc@%llx - id-%d\n",
+		res->start, ddr_pmu->id);
+	return 0;
+}
+
+static int cn10k_ddr_perf_remove(struct platform_device *pdev)
+{
+	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
+
+	perf_pmu_unregister(&ddr_pmu->pmu);
+	return 0;
+}
+
+static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
+	{ .compatible = "marvell,cn10k-ddr-pmu", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
+
+static struct platform_driver cn10k_ddr_pmu_driver = {
+	.driver	= {
+		.name   = "cn10k-ddr-pmu",
+		.of_match_table = cn10k_ddr_pmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe		= cn10k_ddr_perf_probe,
+	.remove		= cn10k_ddr_perf_remove,
+};
+
+static int __init cn10k_ddr_pmu_init(void)
+{
+	return platform_driver_register(&cn10k_ddr_pmu_driver);
+}
+
+static void __exit cn10k_ddr_pmu_exit(void)
+{
+	platform_driver_unregister(&cn10k_ddr_pmu_driver);
+}
+
+module_init(cn10k_ddr_pmu_init);
+module_exit(cn10k_ddr_pmu_exit);
+
+MODULE_AUTHOR("Bharat Bhushan <bbhushan2 at marvell.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1



From bbhushan2 at marvell.com  Tue Aug 10 02:43:06 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Tue, 10 Aug 2021 15:13:06 +0530
Subject: [PATCH v2 3/4] perf/marvell: cn10k DDR perfmon event overflow handling
In-Reply-To: <20210810094307.29595-1-bbhushan2@marvell.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
Message-ID: <20210810094307.29595-4-bbhushan2@marvell.com>

CN10k DSS h/w perfmon does not support event overflow
interrupt, so periodic timer is being used. Each
event counter is 48bit, which in worst case scenario
can increment at maximum 5.6 GT/s. At this rate it may
take many hours to overflow these counters. Therefore
polling period for overflow is set to 100 sec, which
can be changed using sysfs parameter.

Two fixed event counters starts counting from zero on
overflow, so overflow condition is when new count less
than previous count. While eight programmable event
counters freezes at maximum value. Also individual
counter cannot be restarted, so need to restart all
eight counters.

Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
---
v1->v2:
 - No change

 drivers/perf/marvell_cn10k_ddr_pmu.c | 111 +++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index 8f9e3d1fcd8d..80f1441961d0 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -11,6 +11,7 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/perf_event.h>
+#include <linux/hrtimer.h>
 
 /* Performance Counters Operating Mode Control Registers */
 #define DDRC_PERF_CNT_OP_MODE_CTRL	0x8020
@@ -128,6 +129,7 @@ struct cn10k_ddr_pmu {
 	struct	device *dev;
 	int active_events;
 	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
+	struct hrtimer hrtimer;
 };
 
 #define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu, pmu)
@@ -251,6 +253,18 @@ static const struct attribute_group *cn10k_attr_groups[] = {
 	NULL,
 };
 
+/* Default poll timeout is 100 sec, which is very sufficient for
+ * 48 bit counter incremented max at 5.6 GT/s, which may take many
+ * hours to overflow.
+ */
+static unsigned long cn10k_ddr_pmu_poll_period_sec = 100;
+module_param_named(poll_period_sec, cn10k_ddr_pmu_poll_period_sec, ulong, 0644);
+
+static ktime_t cn10k_ddr_pmu_timer_period(void)
+{
+	return ms_to_ktime((u64)cn10k_ddr_pmu_poll_period_sec * USEC_PER_SEC);
+}
+
 static uint64_t ddr_perf_get_event_bitmap(int eventid)
 {
 	uint64_t event_bitmap = 0;
@@ -439,6 +453,10 @@ static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
 	pmu->active_events++;
 	hwc->idx = counter;
 
+	if (pmu->active_events == 1)
+		hrtimer_start(&pmu->hrtimer, cn10k_ddr_pmu_timer_period(),
+			      HRTIMER_MODE_REL_PINNED);
+
 	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
 		/* Generic counters, configure event id */
 		reg_offset = DDRC_PERF_CFG(counter);
@@ -487,6 +505,10 @@ static void cn10k_ddr_perf_event_del(struct perf_event *event, int flags)
 	cn10k_ddr_perf_free_counter(pmu, counter);
 	pmu->active_events--;
 	hwc->idx = -1;
+
+	/* Cancel timer when no events to capture */
+	if (pmu->active_events == 0)
+		hrtimer_cancel(&pmu->hrtimer);
 }
 
 static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu)
@@ -505,6 +527,92 @@ static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu)
 		       DDRC_PERF_CNT_END_OP_CTRL);
 }
 
+static void cn10k_ddr_perf_event_update_all(struct cn10k_ddr_pmu *pmu)
+{
+	struct hw_perf_event *hwc;
+	int i;
+
+	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+		if (pmu->events[i] == NULL)
+			continue;
+
+		cn10k_ddr_perf_event_update(pmu->events[i]);
+	}
+
+	/* Reset previous count as h/w counter are reset */
+	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+		if (pmu->events[i] == NULL)
+			continue;
+
+		hwc = &pmu->events[i]->hw;
+		local64_set(&hwc->prev_count, 0);
+	}
+}
+
+static irqreturn_t cn10k_ddr_pmu_overflow_handler(struct cn10k_ddr_pmu *pmu)
+{
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	uint64_t prev_count, new_count;
+	uint64_t value;
+	int i;
+
+	event = pmu->events[DDRC_PERF_READ_COUNTER_IDX];
+	if (event) {
+		hwc = &event->hw;
+		prev_count = local64_read(&hwc->prev_count);
+		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+
+		/* Overflow condition is when new count less than
+		 * previous count
+		 */
+		if (new_count < prev_count)
+			cn10k_ddr_perf_event_update(event);
+	}
+
+	event = pmu->events[DDRC_PERF_WRITE_COUNTER_IDX];
+	if (event) {
+		hwc = &event->hw;
+		prev_count = local64_read(&hwc->prev_count);
+		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+
+		/* Overflow condition is when new count less than
+		 * previous count
+		 */
+		if (new_count < prev_count)
+			cn10k_ddr_perf_event_update(event);
+	}
+
+	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+		if (pmu->events[i] == NULL)
+			continue;
+
+		value = cn10k_ddr_perf_read_counter(pmu, i);
+		if (value == DDRC_PERF_CNT_MAX_VALUE) {
+			pr_info("Counter-(%d) reached max value\n", i);
+			cn10k_ddr_perf_event_update_all(pmu);
+			cn10k_ddr_perf_pmu_disable(&pmu->pmu);
+			cn10k_ddr_perf_pmu_enable(&pmu->pmu);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static enum hrtimer_restart cn10k_ddr_pmu_timer_handler(struct hrtimer *hrtimer)
+{
+	struct cn10k_ddr_pmu *pmu = container_of(hrtimer, struct cn10k_ddr_pmu,
+						 hrtimer);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	cn10k_ddr_pmu_overflow_handler(pmu);
+	local_irq_restore(flags);
+
+	hrtimer_forward_now(hrtimer, cn10k_ddr_pmu_timer_period());
+	return HRTIMER_RESTART;
+}
+
 static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 {
 	struct cn10k_ddr_pmu *ddr_pmu;
@@ -555,6 +663,9 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 	if (!name)
 		return -ENOMEM;
 
+	hrtimer_init(&ddr_pmu->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	ddr_pmu->hrtimer.function = cn10k_ddr_pmu_timer_handler;
+
 	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
 	if (ret)
 		return ret;
-- 
2.17.1



From bbhushan2 at marvell.com  Tue Aug 10 02:43:07 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Tue, 10 Aug 2021 15:13:07 +0530
Subject: [PATCH v2 4/4] perf/marvell: cn10k DDR perf event core ownership
In-Reply-To: <20210810094307.29595-1-bbhushan2@marvell.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
Message-ID: <20210810094307.29595-5-bbhushan2@marvell.com>

As DDR perf event counters are not per core, so they
should be accessed only by one core at a time.
Select new core when previously owning core is going
offline.

Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
---
v1->v2:
 - No change

 drivers/perf/marvell_cn10k_ddr_pmu.c | 50 ++++++++++++++++++++++++++--
 include/linux/cpuhotplug.h           |  1 +
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index 80f1441961d0..3bf810fe0cf5 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -130,6 +130,7 @@ struct cn10k_ddr_pmu {
 	int active_events;
 	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
 	struct hrtimer hrtimer;
+	struct hlist_node node;
 };
 
 #define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu, pmu)
@@ -613,6 +614,24 @@ static enum hrtimer_restart cn10k_ddr_pmu_timer_handler(struct hrtimer *hrtimer)
 	return HRTIMER_RESTART;
 }
 
+static int cn10k_ddr_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct cn10k_ddr_pmu *pmu = hlist_entry_safe(node, struct cn10k_ddr_pmu,
+						     node);
+	unsigned int target;
+
+	if (cpu != pmu->cpu)
+		return 0;
+
+	target = cpumask_any_but(cpu_online_mask, cpu);
+	if (target >= nr_cpu_ids)
+		return 0;
+
+	perf_pmu_migrate_context(&pmu->pmu, cpu, target);
+	pmu->cpu = target;
+	return 0;
+}
+
 static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 {
 	struct cn10k_ddr_pmu *ddr_pmu;
@@ -666,20 +685,33 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 	hrtimer_init(&ddr_pmu->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	ddr_pmu->hrtimer.function = cn10k_ddr_pmu_timer_handler;
 
+	cpuhp_state_add_instance_nocalls(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+				&ddr_pmu->node);
+
 	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
 	if (ret)
-		return ret;
+		goto error;
 
 	ddr_pmu->id = index++;
 	pr_info("CN10K DDR PMU Driver for ddrc@%llx - id-%d\n",
 		res->start, ddr_pmu->id);
 	return 0;
+error:
+	cpuhp_state_remove_instance_nocalls(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+				&ddr_pmu->node);
+	return ret;
 }
 
 static int cn10k_ddr_perf_remove(struct platform_device *pdev)
 {
 	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
 
+	cpuhp_state_remove_instance_nocalls(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+				&ddr_pmu->node);
+
 	perf_pmu_unregister(&ddr_pmu->pmu);
 	return 0;
 }
@@ -702,12 +734,26 @@ static struct platform_driver cn10k_ddr_pmu_driver = {
 
 static int __init cn10k_ddr_pmu_init(void)
 {
-	return platform_driver_register(&cn10k_ddr_pmu_driver);
+	int ret;
+
+	ret = cpuhp_setup_state_multi(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+				"perf/marvell/cn10k/ddr:online", NULL,
+				cn10k_ddr_pmu_offline_cpu);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&cn10k_ddr_pmu_driver);
+	if (ret)
+		cpuhp_remove_multi_state(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE);
+	return ret;
 }
 
 static void __exit cn10k_ddr_pmu_exit(void)
 {
 	platform_driver_unregister(&cn10k_ddr_pmu_driver);
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE);
 }
 
 module_init(cn10k_ddr_pmu_init);
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 47e13582d9fc..ce7f2740d7db 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -185,6 +185,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
 	CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE,
 	CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE,
+	CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
 	CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
 	CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
 	CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,
-- 
2.17.1



From oupton at google.com  Tue Aug 10 02:44:01 2021
From: oupton at google.com (Oliver Upton)
Date: Tue, 10 Aug 2021 02:44:01 -0700
Subject: [PATCH v6 13/21] KVM: arm64: Allow userspace to configure a
 vCPU's virtual offset
In-Reply-To: <87czqlbq15.wl-maz@kernel.org>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-14-oupton@google.com>
 <87czqlbq15.wl-maz@kernel.org>
Message-ID: <CAOQ_Qsjiyp_HQLhgFfF-o7T=Qpe+djL9KCFjAU2xmj8OXhAf4w@mail.gmail.com>

On Tue, Aug 10, 2021 at 2:35 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Wed, 04 Aug 2021 09:58:11 +0100,
> Oliver Upton <oupton at google.com> wrote:
> >
> > Allow userspace to access the guest's virtual counter-timer offset
> > through the ONE_REG interface. The value read or written is defined to
> > be an offset from the guest's physical counter-timer. Add some
> > documentation to clarify how a VMM should use this and the existing
> > CNTVCT_EL0.
> >
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > ---
> >  Documentation/virt/kvm/api.rst    | 10 ++++++++++
> >  arch/arm64/include/uapi/asm/kvm.h |  1 +
> >  arch/arm64/kvm/arch_timer.c       | 11 +++++++++++
> >  arch/arm64/kvm/guest.c            |  6 +++++-
> >  include/kvm/arm_arch_timer.h      |  1 +
> >  5 files changed, 28 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> > index 8d4a3471ad9e..28a65dc89985 100644
> > --- a/Documentation/virt/kvm/api.rst
> > +++ b/Documentation/virt/kvm/api.rst
> > @@ -2487,6 +2487,16 @@ arm64 system registers have the following id bit patterns::
> >       derived from the register encoding for CNTV_CVAL_EL0.  As this is
> >       API, it must remain this way.
> >
> > +.. warning::
> > +
> > +     The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from
> > +     the guest's view of the physical counter-timer.
> > +
> > +     Userspace should use either KVM_REG_ARM_TIMER_OFFSET or
> > +     KVM_REG_ARM_TIMER_CVAL to pause and resume a guest's virtual
>
> You probably mean KVM_REG_ARM_TIMER_CNT here, despite the broken
> encoding.

Indeed I do!

>
> > +     counter-timer. Mixed use of these registers could result in an
> > +     unpredictable guest counter value.
> > +
> >  arm64 firmware pseudo-registers have the following bit pattern::
> >
> >    0x6030 0000 0014 <regno:16>
> > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> > index b3edde68bc3e..949a31bc10f0 100644
> > --- a/arch/arm64/include/uapi/asm/kvm.h
> > +++ b/arch/arm64/include/uapi/asm/kvm.h
> > @@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags {
> >  #define KVM_REG_ARM_TIMER_CTL                ARM64_SYS_REG(3, 3, 14, 3, 1)
> >  #define KVM_REG_ARM_TIMER_CVAL               ARM64_SYS_REG(3, 3, 14, 0, 2)
> >  #define KVM_REG_ARM_TIMER_CNT                ARM64_SYS_REG(3, 3, 14, 3, 2)
> > +#define KVM_REG_ARM_TIMER_OFFSET     ARM64_SYS_REG(3, 4, 14, 0, 3)
>
> I don't think we can use the encoding for CNTPOFF_EL2 here, as it will
> eventually clash with a NV guest using the same feature for its own
> purpose. We don't want this offset to overlap with any of the existing
> features.
>
> I actually liked your previous proposal of controlling the physical
> offset via a device property, as it clearly indicated that you were
> dealing with non-architectural state.

That's actually exactly what I did here :) That said, the macro name
is horribly obfuscated from CNTVOFF_EL2. I did this for the sake of
symmetry with other virtual counter-timer registers above, though this
may warrant special casing given the fact that we have a similarly
named device attribute to handle the physical offset.

--
Thanks,
Oliver


From f.fainelli at gmail.com  Tue Aug 10 02:51:02 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 10 Aug 2021 02:51:02 -0700
Subject: [PATCH v2 6/9] usb: misc: brcmstb-usb-pinmap: add IRQ check
In-Reply-To: <806d0b1a-365b-93d9-3fc1-922105ca5e61@omp.ru>
References: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
 <806d0b1a-365b-93d9-3fc1-922105ca5e61@omp.ru>
Message-ID: <56cc78f2-c082-0c92-cba6-175500d6b0cf@gmail.com>



On 8/9/2021 1:45 PM, Sergey Shtylyov wrote:
> The driver neglects to check the result of platform_get_irq()'s call and
> blithely passes the negative error codes to devm_request_irq() (which takes
> *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
> error code.  Stop calling devm_request_irq() with the invalid IRQ #s.
> 
> Fixes: 517c4c44b323 ("usb: Add driver to allow any GPIO to be used for 7211 USB signals")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
--
Florian


From lukasz.luba at arm.com  Tue Aug 10 03:05:00 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 11:05:00 +0100
Subject: [PATCH 8/8] cpufreq: vexpress: Use auto-registration for energy
 model
In-Reply-To: <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <d3629cc7-d9db-0e54-94e9-278e308b7e8e@arm.com>



On 8/10/21 8:36 AM, Viresh Kumar wrote:
> Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
> automatically register with the energy model.
> 
> This allows removal of boiler plate code from the driver and fixes the
> unregistration part as well.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>   drivers/cpufreq/vexpress-spc-cpufreq.c | 5 ++---
>   1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c
> index 51dfa9ae6cf5..28c4c3254337 100644
> --- a/drivers/cpufreq/vexpress-spc-cpufreq.c
> +++ b/drivers/cpufreq/vexpress-spc-cpufreq.c
> @@ -442,8 +442,6 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy)
>   	policy->freq_table = freq_table[cur_cluster];
>   	policy->cpuinfo.transition_latency = 1000000; /* 1 ms */
>   
> -	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
> -
>   	if (is_bL_switching_enabled())
>   		per_cpu(cpu_last_req_freq, policy->cpu) =
>   						clk_get_cpu_rate(policy->cpu);
> @@ -487,7 +485,8 @@ static void ve_spc_cpufreq_ready(struct cpufreq_policy *policy)
>   static struct cpufreq_driver ve_spc_cpufreq_driver = {
>   	.name			= "vexpress-spc",
>   	.flags			= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
> -					CPUFREQ_NEED_INITIAL_FREQ_CHECK,
> +				  CPUFREQ_NEED_INITIAL_FREQ_CHECK |
> +				  CPUFREQ_REGISTER_WITH_EM,
>   	.verify			= cpufreq_generic_frequency_table_verify,
>   	.target_index		= ve_spc_cpufreq_set_target,
>   	.get			= ve_spc_cpufreq_get_rate,
> 

I can see that this driver calls explicitly the
of_cpufreq_cooling_register()
It does this in the cpufreq_driver->ready() callback
implementation: ve_spc_cpufreq_ready()

With that in mind, the new code in the patch 1/8, which
registers the EM, should be called even earlier, above:
---------------------8<---------------------------------
/* Callback for handling stuff after policy is ready */
	if (cpufreq_driver->ready)
		cpufreq_driver->ready(policy);
------------------->8----------------------------------

This also triggered a question:
If this new flag can be set in the cpufreq driver which hasn't set
CPUFREQ_IS_COOLING_DEV
?
I can only see one driver (this one in the patch) which has such
configuration.



From viresh.kumar at linaro.org  Tue Aug 10 03:06:52 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 10 Aug 2021 15:36:52 +0530
Subject: [PATCH 8/8] cpufreq: vexpress: Use auto-registration for energy
 model
In-Reply-To: <d3629cc7-d9db-0e54-94e9-278e308b7e8e@arm.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
 <d3629cc7-d9db-0e54-94e9-278e308b7e8e@arm.com>
Message-ID: <20210810100652.h473q6hgtc5czfyk@vireshk-i7>

On 10-08-21, 11:05, Lukasz Luba wrote:
> I can see that this driver calls explicitly the
> of_cpufreq_cooling_register()
> It does this in the cpufreq_driver->ready() callback
> implementation: ve_spc_cpufreq_ready()
> 
> With that in mind, the new code in the patch 1/8, which
> registers the EM, should be called even earlier, above:
> ---------------------8<---------------------------------
> /* Callback for handling stuff after policy is ready */
> 	if (cpufreq_driver->ready)
> 		cpufreq_driver->ready(policy);
> ------------------->8----------------------------------

Thanks. I will look at this sequencing issue again.

> This also triggered a question:
> If this new flag can be set in the cpufreq driver which hasn't set
> CPUFREQ_IS_COOLING_DEV
> ?

Why not ?

> I can only see one driver (this one in the patch) which has such
> configuration.

-- 
viresh


From f.fainelli at gmail.com  Tue Aug 10 03:07:13 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 10 Aug 2021 03:07:13 -0700
Subject: [PATCH 1/3] PCI: brcmstb: Break register definitions into
 separate header
In-Reply-To: <20210805211200.491275-2-jeremy.linton@arm.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
 <20210805211200.491275-2-jeremy.linton@arm.com>
Message-ID: <f82761b1-fb7e-08b2-8bc3-c84d258e26d3@gmail.com>



On 8/5/2021 2:11 PM, Jeremy Linton wrote:
> We are about to create a standalone ACPI quirk module for the
> bcmstb controller. Lets move the register definitions into a separate
> file so they can be shared between the APCI quirk and the normal
> host bridge driver.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>   drivers/pci/controller/pcie-brcmstb.c | 179 +------------------------
>   drivers/pci/controller/pcie-brcmstb.h | 182 ++++++++++++++++++++++++++
>   2 files changed, 183 insertions(+), 178 deletions(-)
>   create mode 100644 drivers/pci/controller/pcie-brcmstb.h

You moved more than just register definitions into pcie-brcmstb.h you 
also moved internal structure definitions, enumerations, etc. which are 
not required since pcie-brcmstb-acpi.c does not access the brcm_pcie 
structure but open codes accesses to the MISC_STATUS register instead.

There are no include guards added to this file (it is debatable whether 
we should add them), and it is also not covered by the existing BROADCOM 
BCM2711/BCM2835 ARM ARCHITECTURE MAINTAINERS file entry.

Given that there can be new platforms supported by this PCIe controller 
in the future possibly with the same limitations as the 2711, but with a 
seemingly different MISC_STATUS layout, you will have to think about a 
solution that scales, maybe we cross that bridge when we get there.
-- 
Florian


From lukasz.luba at arm.com  Tue Aug 10 03:11:31 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 11:11:31 +0100
Subject: [PATCH 8/8] cpufreq: vexpress: Use auto-registration for energy
 model
In-Reply-To: <20210810100652.h473q6hgtc5czfyk@vireshk-i7>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
 <d3629cc7-d9db-0e54-94e9-278e308b7e8e@arm.com>
 <20210810100652.h473q6hgtc5czfyk@vireshk-i7>
Message-ID: <2210acb9-2666-7aa9-d36c-346480541f3c@arm.com>



On 8/10/21 11:06 AM, Viresh Kumar wrote:
> On 10-08-21, 11:05, Lukasz Luba wrote:
>> I can see that this driver calls explicitly the
>> of_cpufreq_cooling_register()
>> It does this in the cpufreq_driver->ready() callback
>> implementation: ve_spc_cpufreq_ready()
>>
>> With that in mind, the new code in the patch 1/8, which
>> registers the EM, should be called even earlier, above:
>> ---------------------8<---------------------------------
>> /* Callback for handling stuff after policy is ready */
>> 	if (cpufreq_driver->ready)
>> 		cpufreq_driver->ready(policy);
>> ------------------->8----------------------------------
> 
> Thanks. I will look at this sequencing issue again.
> 
>> This also triggered a question:
>> If this new flag can be set in the cpufreq driver which hasn't set
>> CPUFREQ_IS_COOLING_DEV
>> ?
> 
> Why not ?

I thought someone could try to call cpufreq_cooling_register()
from the cpufreq driver init function, but it's not possible. I have
just checked that, so should be good with these two flags being
independent and working fine.

> 
>> I can only see one driver (this one in the patch) which has such
>> configuration.
> 


From viresh.kumar at linaro.org  Tue Aug 10 03:12:25 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 10 Aug 2021 15:42:25 +0530
Subject: [PATCH 8/8] cpufreq: vexpress: Use auto-registration for energy
 model
In-Reply-To: <2210acb9-2666-7aa9-d36c-346480541f3c@arm.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
 <d3629cc7-d9db-0e54-94e9-278e308b7e8e@arm.com>
 <20210810100652.h473q6hgtc5czfyk@vireshk-i7>
 <2210acb9-2666-7aa9-d36c-346480541f3c@arm.com>
Message-ID: <20210810101225.hw6co5ymuqpuntnt@vireshk-i7>

On 10-08-21, 11:11, Lukasz Luba wrote:
> 
> 
> On 8/10/21 11:06 AM, Viresh Kumar wrote:
> > On 10-08-21, 11:05, Lukasz Luba wrote:
> > > I can see that this driver calls explicitly the
> > > of_cpufreq_cooling_register()
> > > It does this in the cpufreq_driver->ready() callback
> > > implementation: ve_spc_cpufreq_ready()
> > > 
> > > With that in mind, the new code in the patch 1/8, which
> > > registers the EM, should be called even earlier, above:
> > > ---------------------8<---------------------------------
> > > /* Callback for handling stuff after policy is ready */
> > > 	if (cpufreq_driver->ready)
> > > 		cpufreq_driver->ready(policy);
> > > ------------------->8----------------------------------
> > 
> > Thanks. I will look at this sequencing issue again.
> > 
> > > This also triggered a question:
> > > If this new flag can be set in the cpufreq driver which hasn't set
> > > CPUFREQ_IS_COOLING_DEV
> > > ?
> > 
> > Why not ?
> 
> I thought someone could try to call cpufreq_cooling_register()
> from the cpufreq driver init function, but it's not possible. I have
> just checked that, so should be good with these two flags being
> independent and working fine.

Ahh, I see. Great.

-- 
viresh


From lukasz.luba at arm.com  Tue Aug 10 03:20:16 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 11:20:16 +0100
Subject: [PATCH 3/8] cpufreq: imx6q: Use auto-registration for energy model
In-Reply-To: <ba662b10e043e7734eb9d9e9bbc4c75afab9c2a4.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <ba662b10e043e7734eb9d9e9bbc4c75afab9c2a4.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <ff0a6452-22b0-8d03-5fc5-4a48e460eb3d@arm.com>



On 8/10/21 8:36 AM, Viresh Kumar wrote:
> Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
> automatically register with the energy model.
> 
> This allows removal of boiler plate code from the driver and fixes the
> unregistration part as well.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>   drivers/cpufreq/imx6q-cpufreq.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
> index 5bf5fc759881..aa8df5b468d7 100644
> --- a/drivers/cpufreq/imx6q-cpufreq.c
> +++ b/drivers/cpufreq/imx6q-cpufreq.c
> @@ -192,14 +192,14 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
>   	policy->clk = clks[ARM].clk;
>   	cpufreq_generic_init(policy, freq_table, transition_latency);
>   	policy->suspend_freq = max_freq;
> -	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
>   
>   	return 0;
>   }
>   
>   static struct cpufreq_driver imx6q_cpufreq_driver = {
>   	.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
> -		 CPUFREQ_IS_COOLING_DEV,
> +		 CPUFREQ_IS_COOLING_DEV |
> +		 CPUFREQ_REGISTER_WITH_EM,
>   	.verify = cpufreq_generic_frequency_table_verify,
>   	.target_index = imx6q_set_target,
>   	.get = cpufreq_generic_get,
> 

Reviewed-by: Lukasz Luba <lukasz.luba at arm.com>


From lukasz.luba at arm.com  Tue Aug 10 03:20:53 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 11:20:53 +0100
Subject: [PATCH 4/8] cpufreq: mediatek: Use auto-registration for energy
 model
In-Reply-To: <fe10f291210bfd16620f4be766e6647c8e577995.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <fe10f291210bfd16620f4be766e6647c8e577995.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <12fc1e9d-bb74-63c2-7905-c0917df1cf5b@arm.com>



On 8/10/21 8:36 AM, Viresh Kumar wrote:
> Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
> automatically register with the energy model.
> 
> This allows removal of boiler plate code from the driver and fixes the
> unregistration part as well.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>   drivers/cpufreq/mediatek-cpufreq.c | 5 ++---
>   1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
> index 87019d5a9547..4743f2e58b97 100644
> --- a/drivers/cpufreq/mediatek-cpufreq.c
> +++ b/drivers/cpufreq/mediatek-cpufreq.c
> @@ -448,8 +448,6 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy)
>   	policy->driver_data = info;
>   	policy->clk = info->cpu_clk;
>   
> -	dev_pm_opp_of_register_em(info->cpu_dev, policy->cpus);
> -
>   	return 0;
>   }
>   
> @@ -465,7 +463,8 @@ static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
>   static struct cpufreq_driver mtk_cpufreq_driver = {
>   	.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
>   		 CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
> -		 CPUFREQ_IS_COOLING_DEV,
> +		 CPUFREQ_IS_COOLING_DEV |
> +		 CPUFREQ_REGISTER_WITH_EM,
>   	.verify = cpufreq_generic_frequency_table_verify,
>   	.target_index = mtk_cpufreq_set_target,
>   	.get = cpufreq_generic_get,
> 

Reviewed-by: Lukasz Luba <lukasz.luba at arm.com>


From christianshewitt at gmail.com  Tue Aug 10 03:26:11 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Tue, 10 Aug 2021 10:26:11 +0000
Subject: [PATCH v2 0/2] arm64: dts: amlogic: add support for Radxa Zero
Message-ID: <20210810102613.25149-1-christianshewitt@gmail.com>

This adds support for the Radxa Zero SBC. The device-tree is loosely
based upon existing support for SEI510 and U200 (also G12A boards)
and has been developed with the 4/32 board configuration.

Changes since v1:
- Drop flash_1v8 and use vcc_1v8
- Rename dc_in to ao_5v
- Rename vcc_5v to hdmi_pw and drop GPIO control

Christian Hewitt (2):
  dt-bindings: arm: amlogic: add support for Radxa Zero
  arm64: dts: amlogic: add support for Radxa Zero

 .../devicetree/bindings/arm/amlogic.yaml      |   1 +
 arch/arm64/boot/dts/amlogic/Makefile          |   1 +
 .../dts/amlogic/meson-g12a-radxa-zero.dts     | 407 ++++++++++++++++++
 3 files changed, 409 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts

-- 
2.17.1



From christianshewitt at gmail.com  Tue Aug 10 03:26:12 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Tue, 10 Aug 2021 10:26:12 +0000
Subject: [PATCH v2 1/2] dt-bindings: arm: amlogic: add support for Radxa Zero
In-Reply-To: <20210810102613.25149-1-christianshewitt@gmail.com>
References: <20210810102613.25149-1-christianshewitt@gmail.com>
Message-ID: <20210810102613.25149-2-christianshewitt@gmail.com>

Radxa Zero is a small form-factor SBC with an Amlogic S905Y2 chip.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 6423377710ee..67dccdd9a5a4 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -141,6 +141,7 @@ properties:
           - enum:
               - amediatech,x96-max
               - amlogic,u200
+              - radxa,zero
               - seirobotics,sei510
           - const: amlogic,g12a
 
-- 
2.17.1



From christianshewitt at gmail.com  Tue Aug 10 03:26:13 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Tue, 10 Aug 2021 10:26:13 +0000
Subject: [PATCH v2 2/2] arm64: dts: amlogic: add support for Radxa Zero
In-Reply-To: <20210810102613.25149-1-christianshewitt@gmail.com>
References: <20210810102613.25149-1-christianshewitt@gmail.com>
Message-ID: <20210810102613.25149-3-christianshewitt@gmail.com>

Radxa Zero is a small form factor SBC based on the Amlogic S905Y2
chipset that ships in a number of RAM/eMMC configurations:

Boards with 512MB/1GB LPDDR4 RAM have no eMMC storage and BCM43436
wireless (2.4GHz b/g/n) while 2GB/4GB boards have 8/16/32/64/128GB
eMMC storage and BCM4345 wireless (2.4/5GHz a/b/g/n/ac).

- Amlogic S905Y2 quad-core Cortex-A53
- Mali G31-MP2 GPU
- HDMI 2.1 output (micro)
- 1x USB 2.0 port - Type C (OTG)
- 1x USB 3.0 port - Type C (Host)
- 1x micro SD Card slot
- 40 Pin GPIO header

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   1 +
 .../dts/amlogic/meson-g12a-radxa-zero.dts     | 407 ++++++++++++++++++
 2 files changed, 408 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index faa0a79a34f5..be308361e2f1 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12a-radxa-zero.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
new file mode 100644
index 000000000000..c7bf2ee41134
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
@@ -0,0 +1,407 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 BayLibre SAS. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-g12a.dtsi"
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "radxa,zero", "amlogic,g12a";
+	model = "Radxa Zero";
+
+	aliases {
+		serial0 = &uart_AO;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	cvbs-connector {
+		status = "disabled";
+		compatible = "composite-video-connector";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	ao_5v: regulator-ao_5v {
+		compatible = "regulator-fixed";
+		regulator-name = "AO_5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	vcc_1v8: regulator-vcc_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc_3v3>;
+		regulator-always-on;
+	};
+
+	vcc_3v3: regulator-vcc_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VCC_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	hdmi_pw: regulator-hdmi_pw {
+		compatible = "regulator-fixed";
+		regulator-name = "HDMI_PW";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&ao_5v>;
+		regulator-always-on;
+	};
+
+	vddao_1v8: regulator-vddao_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&ao_5v>;
+		regulator-always-on;
+	};
+
+	vddcpu: regulator-vddcpu {
+		compatible = "pwm-regulator";
+
+		regulator-name = "VDDCPU";
+		regulator-min-microvolt = <721000>;
+		regulator-max-microvolt = <1022000>;
+
+		vin-supply = <&ao_5v>;
+
+		pwms = <&pwm_AO_cd 1 1250 0>;
+		pwm-dutycycle-range = <100 0>;
+
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "RADXA-ZERO";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&cec_AO {
+	pinctrl-0 = <&cec_ao_a_h_pins>;
+	pinctrl-names = "default";
+	status = "disabled";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+	pinctrl-0 = <&cec_ao_b_h_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu1 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu2 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu3 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+	pinctrl-names = "default";
+	hdmi-supply = <&hdmi_pw>;
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&ir {
+	status = "disabled";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&pwm_AO_cd {
+	pinctrl-0 = <&pwm_ao_d_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin1";
+	status = "okay";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddao_1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+	max-frequency = <100000000>;
+
+	non-removable;
+	disable-wp;
+
+	/* WiFi firmware requires power to be kept while in suspend */
+	keep-power-in-suspend;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddao_1v8>;
+
+	brcmf: wifi at 1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+		interrupts = <&gpio GPIOX_7 GPIO_ACTIVE_HIGH>;
+		interrupt-names = "host-wake";
+	};
+};
+
+/* SD card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_c_pins>;
+	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	max-frequency = <100000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
+	pinctrl-1 = <&emmc_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	max-frequency = <200000000>;
+	disable-wp;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vcc_1v8>;
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
+
+&uart_A {
+	status = "okay";
+	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+		max-speed = <2000000>;
+		clocks = <&wifi32k>;
+		clock-names = "lpo";
+	};
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&usb {
+	status = "okay";
+	dr_mode = "host";
+};
-- 
2.17.1



From lukasz.luba at arm.com  Tue Aug 10 03:27:38 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 11:27:38 +0100
Subject: [PATCH 7/8] cpufreq: scpi: Use auto-registration for energy model
In-Reply-To: <7809d747fecbaad46699a178f26288a015055b20.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <7809d747fecbaad46699a178f26288a015055b20.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <4db552cd-a362-13ab-194e-5117addd636f@arm.com>



On 8/10/21 8:36 AM, Viresh Kumar wrote:
> Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
> automatically register with the energy model.
> 
> This allows removal of boiler plate code from the driver and fixes the
> unregistration part as well.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>   drivers/cpufreq/scpi-cpufreq.c | 5 ++---
>   1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
> index d6a698a1b5d1..bc8c62b1beb5 100644
> --- a/drivers/cpufreq/scpi-cpufreq.c
> +++ b/drivers/cpufreq/scpi-cpufreq.c
> @@ -163,8 +163,6 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
>   
>   	policy->fast_switch_possible = false;
>   
> -	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
> -
>   	return 0;
>   
>   out_free_cpufreq_table:
> @@ -193,7 +191,8 @@ static struct cpufreq_driver scpi_cpufreq_driver = {
>   	.name	= "scpi-cpufreq",
>   	.flags	= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
>   		  CPUFREQ_NEED_INITIAL_FREQ_CHECK |
> -		  CPUFREQ_IS_COOLING_DEV,
> +		  CPUFREQ_IS_COOLING_DEV |
> +		  CPUFREQ_REGISTER_WITH_EM,
>   	.verify	= cpufreq_generic_frequency_table_verify,
>   	.attr	= cpufreq_generic_attr,
>   	.get	= scpi_cpufreq_get_rate,
> 

Reviewed-by: Lukasz Luba <lukasz.luba at arm.com>


From lukasz.luba at arm.com  Tue Aug 10 03:30:07 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 11:30:07 +0100
Subject: [PATCH 8/8] cpufreq: vexpress: Use auto-registration for energy
 model
In-Reply-To: <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <b48f04c1-9025-ccae-fe6d-da1d64dba4ed@arm.com>



On 8/10/21 8:36 AM, Viresh Kumar wrote:
> Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
> automatically register with the energy model.
> 
> This allows removal of boiler plate code from the driver and fixes the
> unregistration part as well.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>   drivers/cpufreq/vexpress-spc-cpufreq.c | 5 ++---
>   1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c
> index 51dfa9ae6cf5..28c4c3254337 100644
> --- a/drivers/cpufreq/vexpress-spc-cpufreq.c
> +++ b/drivers/cpufreq/vexpress-spc-cpufreq.c
> @@ -442,8 +442,6 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy)
>   	policy->freq_table = freq_table[cur_cluster];
>   	policy->cpuinfo.transition_latency = 1000000; /* 1 ms */
>   
> -	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
> -
>   	if (is_bL_switching_enabled())
>   		per_cpu(cpu_last_req_freq, policy->cpu) =
>   						clk_get_cpu_rate(policy->cpu);
> @@ -487,7 +485,8 @@ static void ve_spc_cpufreq_ready(struct cpufreq_policy *policy)
>   static struct cpufreq_driver ve_spc_cpufreq_driver = {
>   	.name			= "vexpress-spc",
>   	.flags			= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
> -					CPUFREQ_NEED_INITIAL_FREQ_CHECK,
> +				  CPUFREQ_NEED_INITIAL_FREQ_CHECK |
> +				  CPUFREQ_REGISTER_WITH_EM,
>   	.verify			= cpufreq_generic_frequency_table_verify,
>   	.target_index		= ve_spc_cpufreq_set_target,
>   	.get			= ve_spc_cpufreq_get_rate,
> 

With the change for patch 1/8 the we discussed below this patch 8/8,
it LGTM

Reviewed-by: Lukasz Luba <lukasz.luba at arm.com>


From ming.lei at redhat.com  Tue Aug 10 03:35:45 2021
From: ming.lei at redhat.com (Ming Lei)
Date: Tue, 10 Aug 2021 18:35:45 +0800
Subject: [bug report] iommu_dma_unmap_sg() is very slow then running IO
 from remote numa node
In-Reply-To: <dfdd16e8-278f-3bc9-da97-a91264aec909@huawei.com>
References: <YPlGOOMSdm6Bcyy/@T590>
 <fc552129-e89d-74ad-9e57-30e3ffe4cf5d@huawei.com>
 <YPmUoBk9u+tU2rbS@T590>
 <0adbe03b-ce26-e4d3-3425-d967bc436ef5@arm.com>
 <YPqYDY9/VAhfHNfU@T590>
 <6ceab844-465f-3bf3-1809-5df1f1dbbc5c@huawei.com>
 <CAFj5m9J+9vO=CK3uPP+va5EoWffZj9ruSRe2fDDLXn+AE971CQ@mail.gmail.com>
 <ead87bf2-ddfa-eb67-db44-9619c6cdb714@huawei.com>
 <YQF1AKS6Y14dLU/A@T590>
 <dfdd16e8-278f-3bc9-da97-a91264aec909@huawei.com>
Message-ID: <YRJWgU5VhzBe1JP4@T590>

On Tue, Aug 10, 2021 at 10:36:47AM +0100, John Garry wrote:
> On 28/07/2021 16:17, Ming Lei wrote:
> > > > > Have you tried turning off the IOMMU to ensure that this is really just
> > > > > an IOMMU problem?
> > > > > 
> > > > > You can try setting CONFIG_ARM_SMMU_V3=n in the defconfig or passing
> > > > > cmdline param iommu.passthrough=1 to bypass the the SMMU (equivalent to
> > > > > disabling for kernel drivers).
> > > > Bypassing SMMU via iommu.passthrough=1 basically doesn't make a difference
> > > > on this issue.
> > > A ~90% throughput drop still seems to me to be too high to be a software
> > > issue. More so since I don't see similar on my system. And that throughput
> > > drop does not lead to a total CPU usage drop, from the fio log.
> > > 
> > > Do you know if anyone has run memory benchmark tests on this board to find
> > > out NUMA effect? I think lmbench or stream could be used for this.
> > https://lore.kernel.org/lkml/YOhbc5C47IzC893B at T590/
> 
> Hi Ming,
> 
> Out of curiosity, did you investigate this topic any further?

IMO, the issue is probably in device/system side, since completion latency is
increased a lot, meantime submission latency isn't changed.

Either the submission isn't committed to hardware in time, or the
completion status isn't updated to HW in time from viewpoint of CPU.

We have tried to update to new FW, but not see difference made.

> 
> And you also asked about my results earlier:
> 
> On 22/07/2021 16:54, Ming Lei wrote:
> >> [   52.035895] nvme 0000:81:00.0: Adding to iommu group 5
> >> [   52.047732] nvme nvme0: pci function 0000:81:00.0
> >> [   52.067216] nvme nvme0: 22/0/2 default/read/poll queues
> >> [   52.087318]  nvme0n1: p1
> >>
> >> So I get these results:
> >> cpu0 335K
> >> cpu32 346K
> >> cpu64 300K
> >> cpu96 300K
> >>
> >> So still not massive changes.
> > In your last email, the results are the following with irq mode io_uring:
> >
> >   cpu0  497K
> >   cpu4  307K
> >   cpu32 566K
> >   cpu64 488K
> >   cpu96 508K
> >
> > So looks you get much worse result with real io_polling?
> >
> 
> Would the expectation be that at least I get the same performance with
> io_polling here?

io_polling is supposed to improve IO latency a lot compared with irq
mode, and the perf data shows that clearly on x86_64.

> Anything else to try which you can suggest to investigate
> this lower performance?

You may try to compare irq mode and polling and narrow down the possible
reasons, no exact suggestion on how to investigate it, :-(


Thanks,
Ming



From maz at kernel.org  Tue Aug 10 03:56:08 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 11:56:08 +0100
Subject: [PATCH v6 17/21] KVM: arm64: Allow userspace to configure a
 guest's counter-timer offset
In-Reply-To: <20210804085819.846610-18-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-18-oupton@google.com>
Message-ID: <87a6lpbmbb.wl-maz@kernel.org>

On Wed, 04 Aug 2021 09:58:15 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Presently, KVM provides no facilities for correctly migrating a guest
> that depends on the physical counter-timer. Whie most guests (barring

nit: While

> NV, of course) should not depend on the physical counter-timer, an
> operator may wish to provide a consistent view of the physical
> counter-timer across migrations.
> 
> Provide userspace with a new vCPU attribute to modify the guest
> counter-timer offset. Unlike KVM_REG_ARM_TIMER_OFFSET, this attribute is
> hidden from the guest's architectural state. The value offsets *both*
> the virtual and physical counter-timer views for the guest. Only support
> this attribute on ECV systems as ECV is required for hardware offsetting
> of the physical counter-timer.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  Documentation/virt/kvm/devices/vcpu.rst |  28 ++++++
>  arch/arm64/include/asm/kvm_asm.h        |   2 +
>  arch/arm64/include/asm/sysreg.h         |   2 +
>  arch/arm64/include/uapi/asm/kvm.h       |   1 +
>  arch/arm64/kvm/arch_timer.c             | 122 +++++++++++++++++++++++-
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |   6 ++
>  arch/arm64/kvm/hyp/nvhe/timer-sr.c      |   5 +
>  arch/arm64/kvm/hyp/vhe/timer-sr.c       |   5 +
>  include/clocksource/arm_arch_timer.h    |   1 +
>  9 files changed, 169 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
> index 3b399d727c11..3ba35b9d9d03 100644
> --- a/Documentation/virt/kvm/devices/vcpu.rst
> +++ b/Documentation/virt/kvm/devices/vcpu.rst
> @@ -139,6 +139,34 @@ configured values on other VCPUs.  Userspace should configure the interrupt
>  numbers on at least one VCPU after creating all VCPUs and before running any
>  VCPUs.
>  
> +2.2. ATTRIBUTE: KVM_ARM_VCPU_TIMER_OFFSET
> +-----------------------------------------
> +
> +:Parameters: in kvm_device_attr.addr the address for the timer offset is a
> +             pointer to a __u64
> +
> +Returns:
> +
> +	 ======= ==================================
> +	 -EFAULT Error reading/writing the provided
> +		 parameter address
> +	 -ENXIO  Timer offsetting not implemented
> +	 ======= ==================================
> +
> +Specifies the guest's counter-timer offset from the host's virtual counter.
> +The guest's physical counter value is then derived by the following
> +equation:
> +
> +  guest_cntpct = host_cntvct - KVM_ARM_VCPU_TIMER_OFFSET
> +
> +The guest's virtual counter value is derived by the following equation:
> +
> +  guest_cntvct = host_cntvct - KVM_REG_ARM_TIMER_OFFSET
> +			- KVM_ARM_VCPU_TIMER_OFFSET
> +
> +KVM does not allow the use of varying offset values for different vCPUs;
> +the last written offset value will be broadcasted to all vCPUs in a VM.
> +
>  3. GROUP: KVM_ARM_VCPU_PVTIME_CTRL
>  ==================================
>  
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 9f0bf2109be7..ab1c8fdb0177 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -65,6 +65,7 @@
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize		19
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp			20
>  #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc			21
> +#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntpoff		22
>  
>  #ifndef __ASSEMBLY__
>  
> @@ -200,6 +201,7 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
>  extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
>  
>  extern void __kvm_timer_set_cntvoff(u64 cntvoff);
> +extern void __kvm_timer_set_cntpoff(u64 cntpoff);
>  
>  extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
>  
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 4dfc44066dfb..c34672aa65b9 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -586,6 +586,8 @@
>  #define SYS_ICH_LR14_EL2		__SYS__LR8_EL2(6)
>  #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
>  
> +#define SYS_CNTPOFF_EL2			sys_reg(3, 4, 14, 0, 6)
> +
>  /* VHE encodings for architectural EL0/1 system registers */
>  #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
>  #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index 949a31bc10f0..15150f8224a1 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -366,6 +366,7 @@ struct kvm_arm_copy_mte_tags {
>  #define KVM_ARM_VCPU_TIMER_CTRL		1
>  #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
>  #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
> +#define   KVM_ARM_VCPU_TIMER_OFFSET		2
>  #define KVM_ARM_VCPU_PVTIME_CTRL	2
>  #define   KVM_ARM_VCPU_PVTIME_IPA	0
>  
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index a8815b09da3e..f15058612994 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -85,11 +85,15 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
>  static u64 timer_get_offset(struct arch_timer_context *ctxt)
>  {
>  	struct kvm_vcpu *vcpu = ctxt->vcpu;
> +	struct arch_timer_cpu *timer = vcpu_timer(vcpu);

Unused variable?

>  
>  	switch(arch_timer_ctx_index(ctxt)) {
>  	case TIMER_VTIMER:
> +	case TIMER_PTIMER:
>  		return ctxt->host_offset;
>  	default:
> +		WARN_ONCE(1, "unrecognized timer %ld\n",
> +			  arch_timer_ctx_index(ctxt));
>  		return 0;
>  	}
>  }
> @@ -144,6 +148,7 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
>  
>  	switch(arch_timer_ctx_index(ctxt)) {
>  	case TIMER_VTIMER:
> +	case TIMER_PTIMER:
>  		ctxt->host_offset = offset;
>  		break;
>  	default:
> @@ -572,6 +577,11 @@ static void set_cntvoff(u64 cntvoff)
>  	kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff);
>  }
>  
> +static void set_cntpoff(u64 cntpoff)
> +{
> +	kvm_call_hyp(__kvm_timer_set_cntpoff, cntpoff);
> +}
> +
>  static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active)
>  {
>  	int r;
> @@ -647,6 +657,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
>  	}
>  
>  	set_cntvoff(timer_get_offset(map.direct_vtimer));
> +	if (cpus_have_const_cap(ARM64_ECV))

This really should be a final cap instead (same for all the other use
cases).

> +		set_cntpoff(timer_get_offset(vcpu_ptimer(vcpu)));

However, tripping to EL2 for each offset on nVHE may prove to be an
unnecessary overhead. Not a problem for now anyway.

>
>  	kvm_timer_unblocking(vcpu);
>  
> @@ -814,6 +826,22 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
>  	mutex_unlock(&kvm->lock);
>  }
>  
> +static void update_ptimer_cntpoff(struct kvm_vcpu *vcpu, u64 cntpoff)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 cntvoff;
> +
> +	mutex_lock(&kvm->lock);
> +
> +	/* adjustments to the physical offset also affect vtimer */
> +	cntvoff = timer_get_offset(vcpu_vtimer(vcpu));
> +	cntvoff += cntpoff - timer_get_offset(vcpu_ptimer(vcpu));
> +
> +	update_timer_offset(vcpu, TIMER_PTIMER, cntpoff, false);
> +	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, false);
> +	mutex_unlock(&kvm->lock);
> +}
> +
>  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
>  {
>  	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
> @@ -932,6 +960,29 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
>  	return (u64)-1;
>  }
>  
> +/**
> + * kvm_arm_timer_read_offset - returns the guest value of CNTVOFF_EL2.
> + * @vcpu: the vcpu pointer
> + *
> + * Computes the guest value of CNTVOFF_EL2 by subtracting the physical
> + * counter offset. Note that KVM defines CNTVOFF_EL2 as the offset from the
> + * guest's physical counter-timer, not the host's.
> + *
> + * Returns: the guest value for CNTVOFF_EL2
> + */
> +static u64 kvm_arm_timer_read_offset(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 offset;
> +
> +	mutex_lock(&kvm->lock);
> +	offset = timer_get_offset(vcpu_vtimer(vcpu)) -
> +			timer_get_offset(vcpu_ptimer(vcpu));

nit: please keep this on a single line.

> +	mutex_unlock(&kvm->lock);
> +
> +	return offset;
> +}
> +
>  static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
>  			      struct arch_timer_context *timer,
>  			      enum kvm_arch_timer_regs treg)
> @@ -957,7 +1008,7 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
>  		break;
>  
>  	case TIMER_REG_OFFSET:
> -		val = timer_get_offset(timer);
> +		val = kvm_arm_timer_read_offset(vcpu);
>  		break;
>  
>  	default:
> @@ -1350,6 +1401,9 @@ void kvm_timer_init_vhe(void)
>  	val = read_sysreg(cnthctl_el2);
>  	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
>  	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
> +
> +	if (cpus_have_const_cap(ARM64_ECV))
> +		val |= CNTHCTL_ECV;

I cannot immediately see where you are doing the equivalent enablement
of ECV on the nVHE path. Obviously, it has to be done eagerly from
EL2, together with the rest of the EL1 timer setup. Something like:

diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index 9072e71693ba..999931fe55d2 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -26,6 +26,8 @@ void __timer_disable_traps(struct kvm_vcpu *vcpu)
 	/* Allow physical timer/counter access for the host */
 	val = read_sysreg(cnthctl_el2);
 	val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
+	if (cpus_have_final_cap(ARM64_ECV))
+		val |= CNTHCTL_ECV;
 	write_sysreg(val, cnthctl_el2);
 }
 
@@ -42,6 +44,8 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
 	 * Physical counter access is allowed
 	 */
 	val = read_sysreg(cnthctl_el2);
+	if (cpus_have_final_cap(ARM64_ECV))
+		val &= ~CNTHCTL_ECV;
 	val &= ~CNTHCTL_EL1PCEN;
 	val |= CNTHCTL_EL1PCTEN;
 	write_sysreg(val, cnthctl_el2);

This will ensure that only the guest sees the physical offset.

>  	write_sysreg(val, cnthctl_el2);
>  }
>  
> @@ -1364,7 +1418,8 @@ static void set_timer_irqs(struct kvm *kvm, int vtimer_irq, int ptimer_irq)
>  	}
>  }
>  
> -int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +static int kvm_arm_timer_set_attr_irq(struct kvm_vcpu *vcpu,
> +				      struct kvm_device_attr *attr)
>  {
>  	int __user *uaddr = (int __user *)(long)attr->addr;
>  	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
> @@ -1397,7 +1452,37 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  	return 0;
>  }
>  
> -int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
> +					 struct kvm_device_attr *attr)
> +{
> +	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +	u64 offset;
> +
> +	if (!cpus_have_const_cap(ARM64_ECV))
> +		return -ENXIO;
> +
> +	if (get_user(offset, uaddr))
> +		return -EFAULT;
> +
> +	update_ptimer_cntpoff(vcpu, offset);
> +	return 0;
> +}
> +
> +int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +{
> +	switch (attr->attr) {
> +	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> +	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> +		return kvm_arm_timer_set_attr_irq(vcpu, attr);
> +	case KVM_ARM_VCPU_TIMER_OFFSET:
> +		return kvm_arm_timer_set_attr_offset(vcpu, attr);
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
> +static int kvm_arm_timer_get_attr_irq(struct kvm_vcpu *vcpu,
> +				      struct kvm_device_attr *attr)
>  {
>  	int __user *uaddr = (int __user *)(long)attr->addr;
>  	struct arch_timer_context *timer;
> @@ -1418,12 +1503,43 @@ int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  	return put_user(irq, uaddr);
>  }
>  
> +static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
> +					 struct kvm_device_attr *attr)
> +{
> +	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +	u64 offset;
> +
> +	if (!cpus_have_const_cap(ARM64_ECV))
> +		return -ENXIO;
> +
> +	offset = timer_get_offset(vcpu_ptimer(vcpu));
> +	return put_user(offset, uaddr);
> +}
> +
> +int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu,
> +			   struct kvm_device_attr *attr)
> +{
> +	switch (attr->attr) {
> +	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> +	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> +		return kvm_arm_timer_get_attr_irq(vcpu, attr);
> +	case KVM_ARM_VCPU_TIMER_OFFSET:
> +		return kvm_arm_timer_get_attr_offset(vcpu, attr);
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
>  int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  {
>  	switch (attr->attr) {
>  	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
>  	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
>  		return 0;
> +	case KVM_ARM_VCPU_TIMER_OFFSET:
> +		if (cpus_have_const_cap(ARM64_ECV))
> +			return 0;
> +		break;
>  	}
>  
>  	return -ENXIO;
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 1632f001f4ed..cfa923df3af6 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -68,6 +68,11 @@ static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt)
>  	__kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1));
>  }
>  
> +static void handle___kvm_timer_set_cntpoff(struct kvm_cpu_context *host_ctxt)
> +{
> +	__kvm_timer_set_cntpoff(cpu_reg(host_ctxt, 1));
> +}
> +
>  static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt)
>  {
>  	u64 tmp;
> @@ -197,6 +202,7 @@ static const hcall_t host_hcall[] = {
>  	HANDLE_FUNC(__pkvm_create_private_mapping),
>  	HANDLE_FUNC(__pkvm_prot_finalize),
>  	HANDLE_FUNC(__pkvm_mark_hyp),
> +	HANDLE_FUNC(__kvm_timer_set_cntpoff),
>  };
>  
>  static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> index 9072e71693ba..5b8b4cd02506 100644
> --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> @@ -15,6 +15,11 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
>  	write_sysreg(cntvoff, cntvoff_el2);
>  }
>  
> +void __kvm_timer_set_cntpoff(u64 cntpoff)
> +{
> +	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
> +}
> +
>  /*
>   * Should only be called on non-VHE systems.
>   * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe().
> diff --git a/arch/arm64/kvm/hyp/vhe/timer-sr.c b/arch/arm64/kvm/hyp/vhe/timer-sr.c
> index 4cda674a8be6..231e16a071a5 100644
> --- a/arch/arm64/kvm/hyp/vhe/timer-sr.c
> +++ b/arch/arm64/kvm/hyp/vhe/timer-sr.c
> @@ -10,3 +10,8 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
>  {
>  	write_sysreg(cntvoff, cntvoff_el2);
>  }
> +
> +void __kvm_timer_set_cntpoff(u64 cntpoff)
> +{
> +	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
> +}
> diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
> index 73c7139c866f..7252ffa3d675 100644
> --- a/include/clocksource/arm_arch_timer.h
> +++ b/include/clocksource/arm_arch_timer.h
> @@ -21,6 +21,7 @@
>  #define CNTHCTL_EVNTEN			(1 << 2)
>  #define CNTHCTL_EVNTDIR			(1 << 3)
>  #define CNTHCTL_EVNTI			(0xF << 4)
> +#define CNTHCTL_ECV			(1 << 12)
>  
>  enum arch_timer_reg {
>  	ARCH_TIMER_REG_CTRL,

You also want to document that SCR_EL3.ECVEn has to be set to 1 for
this to work (see Documentation/arm64/booting.txt). And if it isn't,
the firmware better handle the CNTPOFF_EL2 traps correctly...

What firmware did you use for this? I think we need to update the boot
wrapper, but that's something that can be done in parallel.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From ulf.hansson at linaro.org  Tue Aug 10 04:04:08 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 10 Aug 2021 13:04:08 +0200
Subject: [PATCH 00/17] Basical Allwinner R329 support
In-Reply-To: <20210802062212.73220-1-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
Message-ID: <CAPDyKFrOcoFi4iTYSkbTAyZaXkfPb4RV=zMPm9j1dmK88=mgpA@mail.gmail.com>

On Mon, 2 Aug 2021 at 08:24, Icenowy Zheng <icenowy at sipeed.com> wrote:
>
> This patchset tries to add basical support for Allwinner R329 SoC to the
> Linux kernel, including clock/pintrl driver and MMC support.
>
> Three patches from the H616 patchset, which are used to support the RTC
> with linear day, are attached into this patchset. Other RTC-related
> patches of that patchset is not included, because the binding of the
> clock part there is still under discussion.
>
> Then I added RTC binding and support (which is now only a struct
> addition). I added RTC into this patchset, with the same reason that
> H616 patchset contains RTC, which is to make the clock tree correct at
> the first inclusion.
>
> After RTC, main basical SoC-specific part, pinctrl and CCU, come. The
> R329 CCU is something special because PLLs are in R-CCU, no main CCU.
>
> MMC support is added here because it's also a simple struct addition
> work, no main driver code change needed.

It sounds like the MMC updates can be posted separately to linux-mmc.
Please do so I can pick them up.

[...]

Kind regards
Uffe


From tzungbi at google.com  Tue Aug 10 04:13:23 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Tue, 10 Aug 2021 19:13:23 +0800
Subject: [PATCH v4, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <20210810083047.16693-1-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
Message-ID: <CA+Px+wWsYUCAzwbJjFQqhtOiW1zkn6ZTbr3NymUs1TZQWwdQxQ@mail.gmail.com>

On Tue, Aug 10, 2021 at 04:30:32PM +0800, Yunfei Dong wrote:
> This patch dependents on "media: mtk-vcodec: support for MT8183 decoder"[1].
>
> Multi hardware decode is based on stateless decoder, MT8183 is the first time
> to add stateless decoder. Otherwise it will cause conflict. Please also accept
> this patch together with [1].
>
> [1]https://lore.kernel.org/patchwork/project/lkml/list/?series=507084
Didn't see anything from the link but I guess you mean the series
https://patchwork.linuxtv.org/project/linux-media/list/?series=6057


Some obvious issues from the series:
- Please remove all unneeded "Change-Id" tags.
- Please include Reviewed-by tags if no significant changes.
  - E.g. https://patchwork.linuxtv.org/project/linux-media/patch/20210727101051.24418-3-yunfei.dong at mediatek.com/
  - E.g. https://patchwork.linuxtv.org/project/linux-media/patch/20210727101051.24418-4-yunfei.dong at mediatek.com/


From tzungbi at google.com  Tue Aug 10 04:13:42 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Tue, 10 Aug 2021 19:13:42 +0800
Subject: [PATCH v4, 04/15] media: mtk-vcodec: Use component framework to
 manage each hardware information
In-Reply-To: <20210810083047.16693-5-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
 <20210810083047.16693-5-yunfei.dong@mediatek.com>
Message-ID: <CA+Px+wUbDU8ZD_TOoWRGT2qXh1KS-jh_P6NUDdUA-GuO8CiFiw@mail.gmail.com>

On Tue, Aug 10, 2021 at 04:30:36PM +0800, Yunfei Dong wrote:
>   > Looking up "mediatek,mtk-vcodec-core" to determine if it uses component framwork sounds like...
>   Add prameter in pdata, for all platform will use compoent after mt8183
>
>   >> +     if (dev->is_comp_supported) {
>   >> +             ret = mtk_vcodec_init_master(dev);
>   >> +             if (ret < 0)
>   >> +                     goto err_component_match;
>   >> +     } else {
>   >> +             platform_set_drvdata(pdev, dev);
>   >> +     }
>   > + Has asked the same question in [1].  Why it removes the
>   > +platform_set_drvdata() above?  mtk_vcodec_init_master() also calls platform_set_drvdata().
>   Must call component_master_add_with_match after platform_set_drvdata for component architecture.
I am confused.  The condition "call component_master_add_with_match
after platform_set_drvdata" is already true even if without the
change.  See below.

> +static int mtk_vcodec_init_master(struct mtk_vcodec_dev *dev)
> +{
> +     struct platform_device *pdev = dev->plat_dev;
> +     struct component_match *match;
> +     int ret;
> +
> +     match = mtk_vcodec_match_add(dev);
> +     if (IS_ERR_OR_NULL(match))
> +             return -EINVAL;
> +
> +     platform_set_drvdata(pdev, dev);
> +     ret = component_master_add_with_match(&pdev->dev, &mtk_vdec_ops, match);
Point [1].

> @@ -311,7 +413,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>               MTK_VCODEC_DEC_NAME);
>       video_set_drvdata(vfd_dec, dev);
>       dev->vfd_dec = vfd_dec;
> -     platform_set_drvdata(pdev, dev);
Point [2].

> @@ -362,8 +463,16 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>       mtk_v4l2_debug(0, "decoder registered as /dev/video%d",
>               vfd_dec->num);
>
> -     return 0;
> +     if (dev->vdec_pdata->is_comp_supported) {
> +             ret = mtk_vcodec_init_master(dev);
Point [3].


The calling sequence is: [2] -> component_master_add_with_match() -> [1] -> [3].

Don't understand why it removes the platform_set_drvdata() at point [2].


From maz at kernel.org  Tue Aug 10 04:27:48 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 12:27:48 +0100
Subject: [PATCH v6 19/21] KVM: arm64: Emulate physical counter offsetting
 on non-ECV systems
In-Reply-To: <20210804085819.846610-20-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-20-oupton@google.com>
Message-ID: <878s19bkuj.wl-maz@kernel.org>

On Wed, 04 Aug 2021 09:58:17 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Unfortunately, ECV hasn't yet arrived in any tangible hardware. At the
> same time, controlling the guest view of the physical counter-timer is
> useful. Support guest counter-timer offsetting on non-ECV systems by
> trapping guest accesses to the physical counter-timer. Emulate reads of
> the physical counter in the fast exit path.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>  arch/arm64/include/asm/sysreg.h         |  1 +
>  arch/arm64/kvm/arch_timer.c             | 53 +++++++++++++++----------
>  arch/arm64/kvm/hyp/include/hyp/switch.h | 29 ++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/timer-sr.c      | 11 ++++-
>  4 files changed, 70 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index c34672aa65b9..e49790ae5da4 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -505,6 +505,7 @@
>  #define SYS_AMEVCNTR0_MEM_STALL		SYS_AMEVCNTR0_EL0(3)
>  
>  #define SYS_CNTFRQ_EL0			sys_reg(3, 3, 14, 0, 0)
> +#define SYS_CNTPCT_EL0			sys_reg(3, 3, 14, 0, 1)
>  
>  #define SYS_CNTP_TVAL_EL0		sys_reg(3, 3, 14, 2, 0)
>  #define SYS_CNTP_CTL_EL0		sys_reg(3, 3, 14, 2, 1)
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 9ead94aa867d..b7cb63acf2a0 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -51,7 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
>  static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
>  			      struct arch_timer_context *timer,
>  			      enum kvm_arch_timer_regs treg);
> -static void kvm_timer_enable_traps_vhe(void);
> +static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu);
>  
>  u32 timer_get_ctl(struct arch_timer_context *ctxt)
>  {
> @@ -175,6 +175,12 @@ static void timer_set_guest_offset(struct arch_timer_context *ctxt, u64 offset)
>  	}
>  }
>  
> +static bool ptimer_emulation_required(struct kvm_vcpu *vcpu)
> +{
> +	return timer_get_offset(vcpu_ptimer(vcpu)) &&
> +			!cpus_have_const_cap(ARM64_ECV);

What Andrew said! :-)

> +}
> +
>  u64 kvm_phys_timer_read(void)
>  {
>  	return timecounter->cc->read(timecounter->cc);
> @@ -184,8 +190,13 @@ static void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
>  {
>  	if (has_vhe()) {
>  		map->direct_vtimer = vcpu_vtimer(vcpu);
> -		map->direct_ptimer = vcpu_ptimer(vcpu);
> -		map->emul_ptimer = NULL;
> +		if (!ptimer_emulation_required(vcpu)) {
> +			map->direct_ptimer = vcpu_ptimer(vcpu);
> +			map->emul_ptimer = NULL;
> +		} else {
> +			map->direct_ptimer = NULL;
> +			map->emul_ptimer = vcpu_ptimer(vcpu);
> +		}
>  	} else {
>  		map->direct_vtimer = vcpu_vtimer(vcpu);
>  		map->direct_ptimer = NULL;
> @@ -671,7 +682,7 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
>  		timer_emulate(map.emul_ptimer);
>  
>  	if (has_vhe())
> -		kvm_timer_enable_traps_vhe();
> +		kvm_timer_enable_traps_vhe(vcpu);
>  }
>  
>  bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
> @@ -1392,22 +1403,29 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>   * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
>   * and this makes those bits have no effect for the host kernel execution.
>   */
> -static void kvm_timer_enable_traps_vhe(void)
> +static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu)
>  {
>  	/* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
>  	u32 cnthctl_shift = 10;
> -	u64 val;
> +	u64 val, mask;
> +
> +	mask = CNTHCTL_EL1PCEN << cnthctl_shift;
> +	mask |= CNTHCTL_EL1PCTEN << cnthctl_shift;
>  
> -	/*
> -	 * VHE systems allow the guest direct access to the EL1 physical
> -	 * timer/counter.
> -	 */
>  	val = read_sysreg(cnthctl_el2);
> -	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
> -	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
>  
>  	if (cpus_have_const_cap(ARM64_ECV))
>  		val |= CNTHCTL_ECV;
> +
> +	/*
> +	 * VHE systems allow the guest direct access to the EL1 physical
> +	 * timer/counter if offsetting isn't requested on a non-ECV system.
> +	 */
> +	if (ptimer_emulation_required(vcpu))
> +		val &= ~mask;
> +	else
> +		val |= mask;
> +
>  	write_sysreg(val, cnthctl_el2);
>  }
>  
> @@ -1462,9 +1480,6 @@ static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
>  	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
>  	u64 offset;
>  
> -	if (!cpus_have_const_cap(ARM64_ECV))
> -		return -ENXIO;
> -
>  	if (get_user(offset, uaddr))
>  		return -EFAULT;
>  
> @@ -1513,9 +1528,6 @@ static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
>  	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
>  	u64 offset;
>  
> -	if (!cpus_have_const_cap(ARM64_ECV))
> -		return -ENXIO;
> -
>  	offset = timer_get_offset(vcpu_ptimer(vcpu));
>  	return put_user(offset, uaddr);
>  }
> @@ -1539,11 +1551,8 @@ int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  	switch (attr->attr) {
>  	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
>  	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> -		return 0;
>  	case KVM_ARM_VCPU_TIMER_OFFSET:
> -		if (cpus_have_const_cap(ARM64_ECV))
> -			return 0;
> -		break;
> +		return 0;
>  	}
>  
>  	return -ENXIO;
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index e4a2f295a394..abd3813a709e 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -15,6 +15,7 @@
>  #include <linux/jump_label.h>
>  #include <uapi/linux/psci.h>
>  
> +#include <kvm/arm_arch_timer.h>
>  #include <kvm/arm_psci.h>
>  
>  #include <asm/barrier.h>
> @@ -405,6 +406,31 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
>  	return true;
>  }
>  
> +static inline u64 __timer_read_cntpct(struct kvm_vcpu *vcpu)
> +{
> +	return __arch_counter_get_cntpct() - vcpu_ptimer(vcpu)->host_offset;
> +}
> +
> +static inline bool __hyp_handle_counter(struct kvm_vcpu *vcpu)
> +{
> +	u32 sysreg;
> +	int rt;
> +	u64 rv;

You could start with a

	if (cpus_have_final_cap(ARM64_ECV))
		return false;

which will speed-up the exit on ECV-capable systems.

> +
> +	if (kvm_vcpu_trap_get_class(vcpu) != ESR_ELx_EC_SYS64)
> +		return false;
> +
> +	sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
> +	if (sysreg != SYS_CNTPCT_EL0)
> +		return false;

You also want to check for CNTPCTSS_EL0 which will also be caught by
this trap.

> +
> +	rt = kvm_vcpu_sys_get_rt(vcpu);
> +	rv = __timer_read_cntpct(vcpu);
> +	vcpu_set_reg(vcpu, rt, rv);
> +	__kvm_skip_instr(vcpu);
> +	return true;
> +}
> +
>  /*
>   * Return true when we were able to fixup the guest exit and should return to
>   * the guest, false when we should restore the host state and return to the
> @@ -439,6 +465,9 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  	if (*exit_code != ARM_EXCEPTION_TRAP)
>  		goto exit;
>  
> +	if (__hyp_handle_counter(vcpu))
> +		goto guest;
> +
>  	if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) &&
>  	    kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 &&
>  	    handle_tx2_tvm(vcpu))
> diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> index 5b8b4cd02506..67236c2e0ba7 100644
> --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> @@ -44,10 +44,17 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
>  
>  	/*
>  	 * Disallow physical timer access for the guest
> -	 * Physical counter access is allowed
>  	 */
>  	val = read_sysreg(cnthctl_el2);
>  	val &= ~CNTHCTL_EL1PCEN;
> -	val |= CNTHCTL_EL1PCTEN;
> +
> +	/*
> +	 * Disallow physical counter access for the guest if offsetting is
> +	 * requested on a non-ECV system.
> +	 */
> +	if (vcpu_ptimer(vcpu)->host_offset && !cpus_have_const_cap(ARM64_ECV))
> +		val &= ~CNTHCTL_EL1PCTEN;
> +	else
> +		val |= CNTHCTL_EL1PCTEN;
>  	write_sysreg(val, cnthctl_el2);
>  }

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From allen.chen at ite.com.tw  Tue Aug 10 04:11:06 2021
From: allen.chen at ite.com.tw (allen)
Date: Tue, 10 Aug 2021 19:11:06 +0800
Subject: [PATCH v8] drm/bridge: add it6505 driver
Message-ID: <20210810111124.247838-1-allen.chen@ite.com.tw>

This adds support for the iTE IT6505.
This device can convert DPI signal to DP output.

From: Allen Chen <allen.chen at ite.com.tw>
Tested-by: Hsin-yi Wang <hsinyi at chromium.org>
Signed-off-by: Hermes Wu <hermes.wu at ite.com.tw>
Signed-off-by: Allen Chen <allen.chen at ite.com.tw>

v7->v8:
fixed "checkpatch --strict" error
remove unused variable *edid
remove mode_set() callback
Documenting the individual bits of the interrupt mask values
change it6505_dpcd_write parameter from unsigned long to u8

This patch depends on https://patchwork.kernel.org/project/linux-mediatek/patch/20210722062246.2512666-4-sam at ravnborg.org/
---
 drivers/gpu/drm/bridge/Kconfig      |    8 +
 drivers/gpu/drm/bridge/Makefile     |    1 +
 drivers/gpu/drm/bridge/ite-it6505.c | 3333 +++++++++++++++++++++++++++
 3 files changed, 3342 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/ite-it6505.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 431b6e12a81fe..e1afe171075f5 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -74,6 +74,14 @@ config DRM_DISPLAY_CONNECTOR
 	  on ARM-based platforms. Saying Y here when this driver is not needed
 	  will not cause any issue.
 
+config DRM_ITE_IT6505
+        tristate "ITE IT6505 DisplayPort bridge"
+        depends on OF
+        select DRM_KMS_HELPER
+        select EXTCON
+        help
+          ITE IT6505 DisplayPort bridge chip driver.
+
 config DRM_LONTIUM_LT8912B
 	tristate "Lontium LT8912B DSI/HDMI bridge"
 	depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index f2c73683cfcb7..425844c304953 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
 obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
 obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
 obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o
+obj-$(CONFIG_DRM_ITE_IT6505) += ite-it6505.o
 obj-$(CONFIG_DRM_LONTIUM_LT8912B) += lontium-lt8912b.o
 obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
 obj-$(CONFIG_DRM_LONTIUM_LT9611UXC) += lontium-lt9611uxc.o
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
new file mode 100644
index 0000000000000..27586c3fd5f28
--- /dev/null
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -0,0 +1,3333 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+#include <linux/bits.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/extcon.h>
+#include <linux/fs.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+
+#include <crypto/hash.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_hdcp.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
+#include <sound/hdmi-codec.h>
+
+#define REG_IC_VER 0x04
+
+#define REG_RESET_CTRL 0x05
+#define VIDEO_RESET BIT(0)
+#define AUDIO_RESET BIT(1)
+#define ALL_LOGIC_RESET BIT(2)
+#define AUX_RESET BIT(3)
+#define HDCP_RESET BIT(4)
+
+#define INT_STATUS_01 0x06
+#define INT_MASK_01 0x09
+#define INT_HPD_CHANGE 0
+#define INT_RECEIVE_HPD_IRQ 1
+#define INT_SCDT_CHANGE 2
+#define INT_HDCP_FAIL 3
+#define INT_HDCP_DONE 4
+#define BIT_OFFSET(x) (((x) - INT_STATUS_01) * BITS_PER_BYTE)
+#define BIT_INT_HPD INT_HPD_CHANGE
+#define BIT_INT_HPD_IRQ INT_RECEIVE_HPD_IRQ
+#define BIT_INT_SCDT INT_SCDT_CHANGE
+#define BIT_INT_HDCP_FAIL INT_HDCP_FAIL
+#define BIT_INT_HDCP_DONE INT_HDCP_DONE
+
+#define INT_STATUS_02 0x07
+#define INT_MASK_02 0x0A
+#define INT_AUX_CMD_FAIL 0
+#define INT_HDCP_KSV_CHECK 1
+#define INT_AUDIO_FIFO_ERROR 2
+#define BIT_INT_AUX_CMD_FAIL (BIT_OFFSET(0x07) + INT_AUX_CMD_FAIL)
+#define BIT_INT_HDCP_KSV_CHECK (BIT_OFFSET(0x07) + INT_HDCP_KSV_CHECK)
+#define BIT_INT_AUDIO_FIFO_ERROR (BIT_OFFSET(0x07) + INT_AUDIO_FIFO_ERROR)
+
+#define INT_STATUS_03 0x08
+#define INT_MASK_03 0x0B
+#define INT_LINK_TRAIN_FAIL 4
+#define INT_VID_FIFO_ERROR 5
+#define INT_IO_LATCH_FIFO_OVERFLOW 7
+#define BIT_INT_LINK_TRAIN_FAIL (BIT_OFFSET(0x08) + INT_LINK_TRAIN_FAIL)
+#define BIT_INT_VID_FIFO_ERROR (BIT_OFFSET(0x08) + INT_VID_FIFO_ERROR)
+#define BIT_INT_IO_FIFO_OVERFLOW (BIT_OFFSET(0x08) + INT_IO_LATCH_FIFO_OVERFLOW)
+
+#define REG_SYSTEM_STS 0x0D
+#define INT_STS BIT(0)
+#define HPD_STS BIT(1)
+#define VIDEO_STB BIT(2)
+
+#define REG_LINK_TRAIN_STS 0x0E
+#define LINK_STATE_CR BIT(2)
+#define LINK_STATE_EQ BIT(3)
+#define LINK_STATE_NORP BIT(4)
+
+#define REG_BANK_SEL 0x0F
+#define REG_CLK_CTRL0 0x10
+#define M_PCLK_DELAY 0x03
+
+#define REG_AUX_OPT 0x11
+#define AUX_AUTO_RST BIT(0)
+#define AUX_FIX_FREQ BIT(3)
+
+#define REG_DATA_CTRL0 0x12
+#define VIDEO_LATCH_EDGE BIT(4)
+#define ENABLE_PCLK_COUNTER BIT(7)
+
+#define REG_PCLK_COUNTER_VALUE 0x13
+
+#define REG_501_FIFO_CTRL 0x15
+#define RST_501_FIFO BIT(1)
+
+#define REG_TRAIN_CTRL0 0x16
+#define FORCE_LBR BIT(0)
+#define LANE_COUNT_MASK 0x06
+#define LANE_SWAP BIT(3)
+#define SPREAD_AMP_5 BIT(4)
+#define FORCE_CR_DONE BIT(5)
+#define FORCE_EQ_DONE BIT(6)
+
+#define REG_TRAIN_CTRL1 0x17
+#define AUTO_TRAIN BIT(0)
+#define MANUAL_TRAIN BIT(1)
+#define FORCE_RETRAIN BIT(2)
+
+#define REG_AUX_CTRL 0x23
+#define CLR_EDID_FIFO BIT(0)
+#define AUX_USER_MODE BIT(1)
+#define AUX_NO_SEGMENT_WR BIT(6)
+#define AUX_EN_FIFO_READ BIT(7)
+
+#define REG_AUX_ADR_0_7 0x24
+#define REG_AUX_ADR_8_15 0x25
+#define REG_AUX_ADR_16_19 0x26
+#define REG_AUX_OUT_DATA0 0x27
+
+#define REG_AUX_CMD_REQ 0x2B
+#define AUX_BUSY BIT(5)
+
+#define REG_AUX_DATA_0_7 0x2C
+#define REG_AUX_DATA_8_15 0x2D
+#define REG_AUX_DATA_16_23 0x2E
+#define REG_AUX_DATA_24_31 0x2F
+
+#define REG_AUX_DATA_FIFO 0x2F
+
+#define REG_AUX_ERROR_STS 0x9F
+#define M_AUX_REQ_FAIL 0x03
+
+#define REG_HDCP_CTRL1 0x38
+#define HDCP_CP_ENABLE BIT(0)
+
+#define REG_HDCP_TRIGGER 0x39
+#define HDCP_TRIGGER_START  BIT(0)
+#define HDCP_TRIGGER_CPIRQ  BIT(1)
+#define HDCP_TRIGGER_KSV_DONE  BIT(4)
+#define HDCP_TRIGGER_KSV_FAIL BIT(5)
+
+#define REG_HDCP_CTRL2 0x3A
+#define HDCP_AN_SEL BIT(0)
+#define HDCP_AN_GEN BIT(1)
+#define HDCP_HW_HPDIRQ_ACT BIT(2)
+#define HDCP_EN_M0_READ BIT(5)
+
+#define REG_M0_0_7 0x4C
+#define REG_AN_0_7 0x4C
+#define REG_SP_CTRL0 0x58
+#define REG_IP_CTRL1 0x59
+#define REG_IP_CTRL2 0x5A
+
+#define REG_LINK_DRV 0x5C
+#define DRV_HS BIT(1)
+
+#define REG_DRV_LN_DATA_SEL 0x5D
+
+#define REG_AUX 0x5E
+
+#define REG_VID_BUS_CTRL0 0x60
+#define IN_DDR BIT(2)
+#define DDR_CD (0x01 << 6)
+
+#define REG_VID_BUS_CTRL1 0x61
+#define TX_FIFO_RESET BIT(1)
+
+#define REG_INPUT_CTRL 0xA0
+#define INPUT_HSYNC_POL BIT(0)
+#define INPUT_VSYNC_POL BIT(2)
+#define INPUT_INTERLACED BIT(4)
+
+#define REG_INPUT_HTOTAL 0xA1
+#define REG_INPUT_HACTIVE_START 0xA3
+#define REG_INPUT_HACTIVE_WIDTH 0xA5
+#define REG_INPUT_HFRONT_PORCH 0xA7
+#define REG_INPUT_HSYNC_WIDTH 0xA9
+#define REG_INPUT_VTOTAL 0xAB
+#define REG_INPUT_VACTIVE_START 0xAD
+#define REG_INPUT_VACTIVE_WIDTH 0xAF
+#define REG_INPUT_VFRONT_PORCH 0xB1
+#define REG_INPUT_VSYNC_WIDTH 0xB3
+
+#define REG_AUDIO_SRC_CTRL 0xB8
+#define M_AUDIO_I2S_EN 0x0F
+#define EN_I2S0 BIT(0)
+#define EN_I2S1 BIT(1)
+#define EN_I2S2 BIT(2)
+#define EN_I2S3 BIT(3)
+#define AUDIO_FIFO_RESET BIT(7)
+
+#define REG_AUDIO_FMT 0xB9
+#define REG_AUDIO_FIFO_SEL 0xBA
+
+#define REG_AUDIO_CTRL0 0xBB
+#define AUDIO_FULL_PKT BIT(4)
+#define AUDIO_16B_BOUND BIT(5)
+
+#define REG_AUDIO_CTRL1 0xBC
+#define REG_AUDIO_INPUT_FREQ 0xBE
+
+#define REG_IEC958_STS0 0xBF
+#define REG_IEC958_STS1 0xC0
+#define REG_IEC958_STS2 0xC1
+#define REG_IEC958_STS3 0xC2
+#define REG_IEC958_STS4 0xC3
+
+#define REG_HPD_IRQ_TIME 0xC9
+#define REG_AUX_DEBUG_MODE 0xCA
+#define REG_AUX_OPT2 0xCB
+#define REG_HDCP_OPT 0xCE
+#define REG_USER_DRV_PRE 0xCF
+
+#define REG_DATA_MUTE_CTRL 0xD3
+#define ENABLE_ENHANCED_FRAME BIT(0)
+#define ENABLE_AUTO_VIDEO_FIFO_RESET BIT(1)
+#define EN_VID_MUTE BIT(4)
+#define EN_AUD_MUTE BIT(5)
+
+#define REG_TIME_STMP_CTRL 0xD4
+#define EN_ENHANCE_VID_STMP BIT(0)
+#define EN_ENHANCE_AUD_STMP BIT(2)
+#define M_STAMP_STEP 0x30
+#define EN_SSC_GAT BIT(6)
+
+#define REG_INFOFRAME_CTRL 0xE8
+#define EN_AVI_PKT BIT(0)
+#define EN_AUD_PKT BIT(1)
+#define EN_MPG_PKT BIT(2)
+#define EN_GEN_PKT BIT(3)
+#define EN_VID_TIME_STMP BIT(4)
+#define EN_AUD_TIME_STMP BIT(5)
+#define EN_VID_CTRL_PKT (EN_AVI_PKT | EN_VID_TIME_STMP)
+#define EN_AUD_CTRL_PKT (EN_AUD_PKT | EN_AUD_TIME_STMP)
+
+#define REG_AUDIO_N_0_7 0xDE
+#define REG_AUDIO_N_8_15 0xDF
+#define REG_AUDIO_N_16_23 0xE0
+
+#define REG_AVI_INFO_DB1 0xE9
+#define REG_AVI_INFO_DB2 0xEA
+#define REG_AVI_INFO_DB3 0xEB
+#define REG_AVI_INFO_DB4 0xEC
+#define REG_AVI_INFO_DB5 0xED
+#define REG_AVI_INFO_SUM 0xF6
+
+#define REG_AUD_INFOFRAM_DB1 0xF7
+#define REG_AUD_INFOFRAM_DB2 0xF8
+#define REG_AUD_INFOFRAM_DB3 0xF9
+#define REG_AUD_INFOFRAM_DB4 0xFA
+#define REG_AUD_INFOFRAM_SUM 0xFB
+
+/* the following six registers are in bank1 */
+#define REG_DRV_0_DB_800_MV 0x7E
+#define REG_PRE_0_DB_800_MV 0x7F
+#define REG_PRE_3P5_DB_800_MV 0x81
+#define REG_SSC_CTRL0 0x88
+#define REG_SSC_CTRL1 0x89
+#define REG_SSC_CTRL2 0x8A
+
+#define RBR DP_LINK_BW_1_62
+#define HBR DP_LINK_BW_2_7
+#define HBR2 DP_LINK_BW_5_4
+#define HBR3 DP_LINK_BW_8_1
+
+#define DPCD_V_1_1 0x11
+#define MISC_VERB 0xF0
+#define MISC_VERC 0x70
+#define I2S_INPUT_FORMAT_STANDARD 0
+#define I2S_INPUT_FORMAT_32BIT 1
+#define I2S_INPUT_LEFT_JUSTIFIED 0
+#define I2S_INPUT_RIGHT_JUSTIFIED 1
+#define I2S_DATA_1T_DELAY 0
+#define I2S_DATA_NO_DELAY 1
+#define I2S_WS_LEFT_CHANNEL 0
+#define I2S_WS_RIGHT_CHANNEL 1
+#define I2S_DATA_MSB_FIRST 0
+#define I2S_DATA_LSB_FIRST 1
+#define WORD_LENGTH_16BIT 0
+#define WORD_LENGTH_18BIT 1
+#define WORD_LENGTH_20BIT 2
+#define WORD_LENGTH_24BIT 3
+#define DEBUGFS_DIR_NAME "it6505-debugfs"
+#define READ_BUFFER_SIZE 200
+
+/* Vendor option */
+#define HDCP_DESIRED 1
+#define MAX_LANE_COUNT 4
+#define MAX_LINK_RATE HBR
+#define AUTO_TRAIN_RETRY 3
+#define MAX_HDCP_DOWN_STREAM_COUNT 10
+#define MAX_CR_LEVEL 0x03
+#define MAX_EQ_LEVEL 0x03
+#define AUX_WAIT_TIMEOUT_MS 15
+#define AUX_FIFO_MAX_SIZE 32
+#define PIXEL_CLK_DELAY 1
+#define PIXEL_CLK_INVERSE 0
+#define ADJUST_PHASE_THRESHOLD 80000
+#define DPI_PIXEL_CLK_MAX 95000
+#define HDCP_SHA1_FIFO_LEN (MAX_HDCP_DOWN_STREAM_COUNT * 5 + 10)
+#define DEFAULT_PWR_ON 0
+#define DEFAULT_DRV_HOLD 0
+
+#define AUDIO_SELECT I2S
+#define AUDIO_TYPE LPCM
+#define AUDIO_SAMPLE_RATE SAMPLE_RATE_48K
+#define AUDIO_CHANNEL_COUNT 2
+#define I2S_INPUT_FORMAT I2S_INPUT_FORMAT_32BIT
+#define I2S_JUSTIFIED I2S_INPUT_LEFT_JUSTIFIED
+#define I2S_DATA_DELAY I2S_DATA_1T_DELAY
+#define I2S_WS_CHANNEL I2S_WS_LEFT_CHANNEL
+#define I2S_DATA_SEQUENCE I2S_DATA_MSB_FIRST
+#define AUDIO_WORD_LENGTH WORD_LENGTH_24BIT
+
+enum aux_cmd_type {
+	CMD_AUX_NATIVE_READ = 0x0,
+	CMD_AUX_NATIVE_WRITE = 0x5,
+	CMD_AUX_I2C_EDID_READ = 0xB,
+};
+
+enum aux_cmd_reply {
+	REPLY_ACK,
+	REPLY_NACK,
+	REPLY_DEFER,
+};
+
+enum link_train_status {
+	LINK_IDLE,
+	LINK_BUSY,
+	LINK_OK,
+};
+
+enum hdcp_state {
+	HDCP_AUTH_IDLE,
+	HDCP_AUTH_GOING,
+	HDCP_AUTH_DONE,
+};
+
+struct it6505_platform_data {
+	struct regulator *pwr18;
+	struct regulator *ovdd;
+	struct gpio_desc *gpiod_reset;
+};
+
+enum it6505_audio_select {
+	I2S = 0,
+	SPDIF,
+};
+
+enum it6505_audio_sample_rate {
+	SAMPLE_RATE_24K = 0x6,
+	SAMPLE_RATE_32K = 0x3,
+	SAMPLE_RATE_48K = 0x2,
+	SAMPLE_RATE_96K = 0xA,
+	SAMPLE_RATE_192K = 0xE,
+	SAMPLE_RATE_44_1K = 0x0,
+	SAMPLE_RATE_88_2K = 0x8,
+	SAMPLE_RATE_176_4K = 0xC,
+};
+
+enum it6505_audio_type {
+	LPCM = 0,
+	NLPCM,
+	DSS,
+};
+
+struct it6505_audio_data {
+	enum it6505_audio_select select;
+	enum it6505_audio_sample_rate sample_rate;
+	enum it6505_audio_type type;
+	u8 word_length;
+	u8 channel_count;
+	u8 i2s_input_format;
+	u8 i2s_justified;
+	u8 i2s_data_delay;
+	u8 i2s_ws_channel;
+	u8 i2s_data_sequence;
+};
+
+struct it6505_audio_sample_rate_map {
+	enum it6505_audio_sample_rate rate;
+	int sample_rate_value;
+};
+
+struct it6505_drm_dp_link {
+	unsigned char revision;
+	unsigned int rate;
+	unsigned int num_lanes;
+	unsigned long capabilities;
+};
+
+struct debugfs_entries {
+	char *name;
+	const struct file_operations *fops;
+};
+
+struct it6505 {
+	struct drm_dp_aux aux;
+	struct drm_bridge bridge;
+	struct i2c_client *client;
+	struct it6505_drm_dp_link link;
+	struct it6505_platform_data pdata;
+	/*
+	 * Mutex protects extcon and interrupt functions from interfering
+	 * each other.
+	 */
+	struct mutex extcon_lock;
+	struct mutex mode_lock; /* used to bridge_detect */
+	struct mutex aux_lock; /* used to aux data transfers */
+	struct regmap *regmap;
+	struct drm_display_mode source_output_mode;
+	struct drm_display_mode video_info;
+	struct notifier_block event_nb;
+	struct extcon_dev *extcon;
+	struct work_struct extcon_wq;
+	enum drm_connector_status connector_status;
+	enum link_train_status link_state;
+	struct work_struct link_works;
+	u8 dpcd[DP_RECEIVER_CAP_SIZE];
+	u8 lane_count;
+	u8 link_rate_bw_code;
+	u8 sink_count;
+	bool step_train;
+	bool branch_device;
+	bool enable_ssc;
+	bool lane_swap_disabled;
+	bool lane_swap;
+	bool powered;
+	bool hpd_state;
+	u32 afe_setting;
+	enum hdcp_state hdcp_status;
+	struct delayed_work hdcp_work;
+	struct work_struct hdcp_wait_ksv_list;
+	struct completion wait_edid_complete;
+	u8 auto_train_retry;
+	bool hdcp_desired;
+	bool is_repeater;
+	u8 hdcp_down_stream_count;
+	u8 bksvs[DRM_HDCP_KSV_LEN];
+	u8 sha1_input[HDCP_SHA1_FIFO_LEN];
+	bool enable_enhanced_frame;
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
+	struct delayed_work delayed_audio;
+	struct it6505_audio_data audio;
+	struct dentry *debugfs;
+
+	/* it6505 driver hold option */
+	bool enable_drv_hold;
+};
+
+struct it6505_step_train_para {
+	u8 voltage_swing[MAX_LANE_COUNT];
+	u8 pre_emphasis[MAX_LANE_COUNT];
+};
+
+/*
+ * Vendor option afe settings for different platforms
+ * 0: without FPC cable
+ * 1: with FPC cable
+ */
+
+static const u8 afe_setting_table[][3] = {
+	{0x82, 0x00, 0x45},
+	{0x93, 0x2A, 0x85}
+};
+
+static const struct it6505_audio_sample_rate_map audio_sample_rate_map[] = {
+	{SAMPLE_RATE_24K, 24000},
+	{SAMPLE_RATE_32K, 32000},
+	{SAMPLE_RATE_48K, 48000},
+	{SAMPLE_RATE_96K, 96000},
+	{SAMPLE_RATE_192K, 192000},
+	{SAMPLE_RATE_44_1K, 44100},
+	{SAMPLE_RATE_88_2K, 88200},
+	{SAMPLE_RATE_176_4K, 176400},
+};
+
+static const struct regmap_range it6505_bridge_volatile_ranges[] = {
+	{ .range_min = 0, .range_max = 0xFF },
+};
+
+static const struct regmap_access_table it6505_bridge_volatile_table = {
+	.yes_ranges = it6505_bridge_volatile_ranges,
+	.n_yes_ranges = ARRAY_SIZE(it6505_bridge_volatile_ranges),
+};
+
+static const struct regmap_config it6505_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_table = &it6505_bridge_volatile_table,
+	.cache_type = REGCACHE_NONE,
+};
+
+static int it6505_read(struct it6505 *it6505, unsigned int reg_addr)
+{
+	unsigned int value;
+	int err;
+	struct device *dev = &it6505->client->dev;
+
+	err = regmap_read(it6505->regmap, reg_addr, &value);
+	if (err < 0) {
+		dev_err(dev, "read failed reg[0x%x] err: %d", reg_addr, err);
+		return err;
+	}
+
+	return value;
+}
+
+static int it6505_write(struct it6505 *it6505, unsigned int reg_addr,
+			unsigned int reg_val)
+{
+	int err;
+	struct device *dev = &it6505->client->dev;
+
+	err = regmap_write(it6505->regmap, reg_addr, reg_val);
+
+	if (err < 0) {
+		dev_err(dev, "write failed reg[0x%x] = 0x%x err = %d",
+			reg_addr, reg_val, err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int it6505_set_bits(struct it6505 *it6505, unsigned int reg,
+			   unsigned int mask, unsigned int value)
+{
+	int err;
+	struct device *dev = &it6505->client->dev;
+
+	err = regmap_update_bits(it6505->regmap, reg, mask, value);
+	if (err < 0) {
+		dev_err(dev, "write reg[0x%x] = 0x%x mask = 0x%x failed err %d",
+			reg, value, mask, err);
+		return err;
+	}
+
+	return 0;
+}
+
+static void it6505_debug_print(struct it6505 *it6505, unsigned int reg,
+			       const char *prefix)
+{
+	struct device *dev = &it6505->client->dev;
+	int val;
+
+	if (likely(!(__drm_debug & DRM_UT_DRIVER)))
+		return;
+
+	val = it6505_read(it6505, reg);
+	if (val < 0)
+		DRM_DEV_DEBUG_DRIVER(dev, "%s reg[%02x] read error (%d)",
+				     prefix, reg, val);
+	else
+		DRM_DEV_DEBUG_DRIVER(dev, "%s reg[%02x] = 0x%02x", prefix, reg,
+				     val);
+}
+
+static int it6505_dpcd_read(struct it6505 *it6505, unsigned long offset)
+{
+	u8 value;
+	int ret;
+	struct device *dev = &it6505->client->dev;
+
+	ret = drm_dp_dpcd_readb(&it6505->aux, offset, &value);
+	if (ret < 0) {
+		dev_err(dev, "DPCD read failed [0x%lx] ret: %d", offset, ret);
+		return ret;
+	}
+	return value;
+}
+
+static int it6505_dpcd_write(struct it6505 *it6505, unsigned long offset,
+			     u8 datain)
+{
+	int ret;
+	struct device *dev = &it6505->client->dev;
+
+	ret = drm_dp_dpcd_writeb(&it6505->aux, offset, datain);
+	if (ret < 0) {
+		dev_err(dev, "DPCD write failed [0x%lx] ret: %d", offset, ret);
+		return ret;
+	}
+	return 0;
+}
+
+static int it6505_get_dpcd(struct it6505 *it6505, int offset, u8 *dpcd, int num)
+{
+	int ret;
+	struct device *dev = &it6505->client->dev;
+
+	ret = drm_dp_dpcd_read(&it6505->aux, offset, dpcd, num);
+
+	if (ret < 0)
+		return ret;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "ret = %d DPCD[0x%x] = 0x%*ph", ret, offset,
+			     num, dpcd);
+
+	return 0;
+}
+
+static void it6505_dump(struct it6505 *it6505)
+{
+	unsigned int i, j;
+	u8 regs[16];
+	struct device *dev = &it6505->client->dev;
+
+	for (i = 0; i <= 0xff; i += 16) {
+		for (j = 0; j < 16; j++)
+			regs[j] = it6505_read(it6505, i + j);
+
+		DRM_DEV_DEBUG_DRIVER(dev, "[0x%02x] = %16ph", i, regs);
+	}
+}
+
+static bool it6505_get_sink_hpd_status(struct it6505 *it6505)
+{
+	int reg_0d;
+
+	reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+
+	if (reg_0d < 0)
+		return false;
+
+	return reg_0d & HPD_STS;
+}
+
+static int it6505_read_word(struct it6505 *it6505, unsigned int reg)
+{
+	int val0, val1;
+
+	val0 = it6505_read(it6505, reg);
+	if (val0 < 0)
+		return val0;
+
+	val1 = it6505_read(it6505, reg + 1);
+	if (val1 < 0)
+		return val1;
+
+	return (val1 << 8) | val0;
+}
+
+static void it6505_calc_video_info(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	int hsync_pol, vsync_pol, interlaced;
+	int htotal, hdes, hdew, hfph, hsyncw;
+	int vtotal, vdes, vdew, vfph, vsyncw;
+	int rddata, i, pclk, sum = 0;
+
+	usleep_range(10000, 15000);
+	rddata = it6505_read(it6505, REG_INPUT_CTRL);
+	hsync_pol = rddata & INPUT_HSYNC_POL;
+	vsync_pol = (rddata & INPUT_VSYNC_POL) >> 2;
+	interlaced = (rddata & INPUT_INTERLACED) >> 4;
+
+	htotal = it6505_read_word(it6505, REG_INPUT_HTOTAL) & 0x1FFF;
+	hdes = it6505_read_word(it6505, REG_INPUT_HACTIVE_START) & 0x1FFF;
+	hdew = it6505_read_word(it6505, REG_INPUT_HACTIVE_WIDTH) & 0x1FFF;
+	hfph = it6505_read_word(it6505, REG_INPUT_HFRONT_PORCH) & 0x1FFF;
+	hsyncw = it6505_read_word(it6505, REG_INPUT_HSYNC_WIDTH) & 0x1FFF;
+
+	vtotal = it6505_read_word(it6505, REG_INPUT_VTOTAL) & 0xFFF;
+	vdes = it6505_read_word(it6505, REG_INPUT_VACTIVE_START) & 0xFFF;
+	vdew = it6505_read_word(it6505, REG_INPUT_VACTIVE_WIDTH) & 0xFFF;
+	vfph = it6505_read_word(it6505, REG_INPUT_VFRONT_PORCH) & 0xFFF;
+	vsyncw = it6505_read_word(it6505, REG_INPUT_VSYNC_WIDTH) & 0xFFF;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "hsync_pol:%d, vsync_pol:%d, interlaced:%d",
+			     hsync_pol, vsync_pol, interlaced);
+	DRM_DEV_DEBUG_DRIVER(dev, "hactive_start:%d, vactive_start:%d",
+			     hdes, vdes);
+
+	for (i = 0; i < 10; i++) {
+		it6505_set_bits(it6505, REG_DATA_CTRL0, ENABLE_PCLK_COUNTER,
+				ENABLE_PCLK_COUNTER);
+		usleep_range(10000, 15000);
+		it6505_set_bits(it6505, REG_DATA_CTRL0, ENABLE_PCLK_COUNTER,
+				0x00);
+		rddata = it6505_read_word(it6505, REG_PCLK_COUNTER_VALUE) &
+			 0xFFF;
+
+		sum += rddata;
+	}
+
+	if (sum == 0) {
+		DRM_DEV_DEBUG_DRIVER(dev, "calc video timing error");
+		return;
+	}
+
+	sum /= 10;
+	pclk = 13500 * 2048 / sum;
+	it6505->video_info.clock = pclk;
+	it6505->video_info.hdisplay = hdew;
+	it6505->video_info.hsync_start = hdew + hfph;
+	it6505->video_info.hsync_end = hdew + hfph + hsyncw;
+	it6505->video_info.htotal = htotal;
+	it6505->video_info.vdisplay = vdew;
+	it6505->video_info.vsync_start = vdew + vfph;
+	it6505->video_info.vsync_end = vdew + vfph + vsyncw;
+	it6505->video_info.vtotal = vtotal;
+
+	DRM_DEV_DEBUG_DRIVER(dev, DRM_MODE_FMT,
+			     DRM_MODE_ARG(&it6505->video_info));
+}
+
+static int it6505_drm_dp_link_probe(struct drm_dp_aux *aux,
+				    struct it6505_drm_dp_link *link)
+{
+	u8 values[3];
+	int err;
+
+	memset(link, 0, sizeof(*link));
+
+	err = drm_dp_dpcd_read(aux, DP_DPCD_REV, values, sizeof(values));
+	if (err < 0)
+		return err;
+
+	link->revision = values[0];
+	link->rate = drm_dp_bw_code_to_link_rate(values[1]);
+	link->num_lanes = values[2] & DP_MAX_LANE_COUNT_MASK;
+
+	if (values[2] & DP_ENHANCED_FRAME_CAP)
+		link->capabilities = DP_ENHANCED_FRAME_CAP;
+
+	return 0;
+}
+
+static int it6505_drm_dp_link_power_up(struct drm_dp_aux *aux,
+				       struct it6505_drm_dp_link *link)
+{
+	u8 value;
+	int err;
+
+	/* DP_SET_POWER register is only available on DPCD v1.1 and later */
+	if (link->revision < DPCD_V_1_1)
+		return 0;
+
+	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
+	if (err < 0)
+		return err;
+
+	value &= ~DP_SET_POWER_MASK;
+	value |= DP_SET_POWER_D0;
+
+	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
+	if (err < 0)
+		return err;
+
+	/*
+	 * According to the DP 1.1 specification, a "Sink Device must exit the
+	 * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
+	 * Control Field" (register 0x600).
+	 */
+	usleep_range(1000, 2000);
+
+	return 0;
+}
+
+static void it6505_clear_int(struct it6505 *it6505)
+{
+	it6505_write(it6505, INT_STATUS_01, 0xFF);
+	it6505_write(it6505, INT_STATUS_02, 0xFF);
+	it6505_write(it6505, INT_STATUS_03, 0xFF);
+}
+
+static void it6505_int_mask_enable(struct it6505 *it6505)
+{
+	it6505_write(it6505, INT_MASK_01, BIT(INT_HPD_CHANGE) |
+		     BIT(INT_RECEIVE_HPD_IRQ) | BIT(INT_SCDT_CHANGE) |
+		     BIT(INT_HDCP_FAIL) | BIT(INT_HDCP_DONE));
+
+	it6505_write(it6505, INT_MASK_02, BIT(INT_AUX_CMD_FAIL) |
+		     BIT(INT_HDCP_KSV_CHECK) | BIT(INT_AUDIO_FIFO_ERROR));
+
+	it6505_write(it6505, INT_MASK_03, BIT(INT_LINK_TRAIN_FAIL) |
+		     BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW));
+}
+
+static void it6505_int_mask_disable(struct it6505 *it6505)
+{
+	it6505_write(it6505, INT_MASK_01, 0x00);
+	it6505_write(it6505, INT_MASK_02, 0x00);
+	it6505_write(it6505, INT_MASK_03, 0x00);
+}
+
+static void it6505_lane_termination_on(struct it6505 *it6505)
+{
+	int regcf;
+
+	regcf = it6505_read(it6505, REG_USER_DRV_PRE);
+
+	if (regcf == MISC_VERB)
+		it6505_set_bits(it6505, REG_DRV_LN_DATA_SEL, 0x80, 0x00);
+
+	if (regcf == MISC_VERC) {
+		if (it6505->lane_swap) {
+			switch (it6505->lane_count) {
+			case 1:
+			case 2:
+				it6505_set_bits(it6505, REG_DRV_LN_DATA_SEL,
+						0x0C, 0x08);
+				break;
+			default:
+				it6505_set_bits(it6505, REG_DRV_LN_DATA_SEL,
+						0x0C, 0x0C);
+				break;
+			}
+		} else {
+			switch (it6505->lane_count) {
+			case 1:
+			case 2:
+				it6505_set_bits(it6505, REG_DRV_LN_DATA_SEL,
+						0x0C, 0x04);
+				break;
+			default:
+				it6505_set_bits(it6505, REG_DRV_LN_DATA_SEL,
+						0x0C, 0x0C);
+				break;
+			}
+		}
+	}
+}
+
+static void it6505_lane_termination_off(struct it6505 *it6505)
+{
+	int regcf;
+
+	regcf = it6505_read(it6505, REG_USER_DRV_PRE);
+
+	if (regcf == MISC_VERB)
+		it6505_set_bits(it6505, REG_DRV_LN_DATA_SEL, 0x80, 0x80);
+
+	if (regcf == MISC_VERC)
+		it6505_set_bits(it6505, REG_DRV_LN_DATA_SEL, 0x0C, 0x00);
+}
+
+static void it6505_lane_power_on(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_LINK_DRV, 0xF1,
+			(it6505->lane_swap ?
+				 GENMASK(7, 8 - it6505->lane_count) :
+				 GENMASK(3 + it6505->lane_count, 4)) |
+				0x01);
+}
+
+static void it6505_lane_power_off(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_LINK_DRV, 0xF0, 0x00);
+}
+
+static void it6505_lane_off(struct it6505 *it6505)
+{
+	it6505_lane_power_off(it6505);
+	it6505_lane_termination_off(it6505);
+}
+
+static void it6505_aux_termination_on(struct it6505 *it6505)
+{
+	int regcf;
+
+	regcf = it6505_read(it6505, REG_USER_DRV_PRE);
+
+	if (regcf == MISC_VERB)
+		it6505_lane_termination_on(it6505);
+
+	if (regcf == MISC_VERC)
+		it6505_set_bits(it6505, REG_DRV_LN_DATA_SEL, 0x80, 0x80);
+}
+
+static void it6505_aux_power_on(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_AUX, 0x02, 0x02);
+}
+
+static void it6505_aux_on(struct it6505 *it6505)
+{
+	it6505_aux_power_on(it6505);
+	it6505_aux_termination_on(it6505);
+}
+
+static void it6505_aux_reset(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_RESET_CTRL, AUX_RESET, AUX_RESET);
+	it6505_set_bits(it6505, REG_RESET_CTRL, AUX_RESET, 0x00);
+}
+
+static void it6505_reset_logic(struct it6505 *it6505)
+{
+	regmap_write(it6505->regmap, REG_RESET_CTRL, ALL_LOGIC_RESET);
+	usleep_range(1000, 1500);
+}
+
+static bool it6505_aux_op_finished(struct it6505 *it6505)
+{
+	int reg2b = it6505_read(it6505, REG_AUX_CMD_REQ);
+
+	if (reg2b < 0)
+		return false;
+
+	return (reg2b & AUX_BUSY) == 0;
+}
+
+static int it6505_aux_wait(struct it6505 *it6505)
+{
+	int status;
+	unsigned long timeout;
+	struct device *dev = &it6505->client->dev;
+
+	timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1;
+
+	while (!it6505_aux_op_finished(it6505)) {
+		if (time_after(jiffies, timeout)) {
+			dev_err(dev, "Timed out waiting AUX to finish");
+			return -ETIMEDOUT;
+		}
+		usleep_range(1000, 2000);
+	}
+
+	status = it6505_read(it6505, REG_AUX_ERROR_STS);
+	if (status < 0) {
+		dev_err(dev, "Failed to read AUX channel: %d", status);
+		return status;
+	}
+
+	return 0;
+}
+
+static ssize_t it6505_aux_operation(struct it6505 *it6505,
+				    enum aux_cmd_type cmd,
+				    unsigned int address, u8 *buffer,
+				    size_t size, enum aux_cmd_reply *reply)
+{
+	int i, ret;
+	bool aux_write_check = false;
+
+	if (!it6505_get_sink_hpd_status(it6505))
+		return -EIO;
+
+	/* set AUX user mode */
+	it6505_set_bits(it6505, REG_AUX_CTRL, AUX_USER_MODE, AUX_USER_MODE);
+
+aux_op_start:
+	if (cmd == CMD_AUX_I2C_EDID_READ) {
+		/* AUX EDID FIFO has max length of AUX_FIFO_MAX_SIZE bytes. */
+		size = min_t(size_t, size, AUX_FIFO_MAX_SIZE);
+		/* Enable AUX FIFO read back and clear FIFO */
+		it6505_set_bits(it6505, REG_AUX_CTRL,
+				AUX_EN_FIFO_READ | CLR_EDID_FIFO,
+				AUX_EN_FIFO_READ | CLR_EDID_FIFO);
+
+		it6505_set_bits(it6505, REG_AUX_CTRL,
+				AUX_EN_FIFO_READ | CLR_EDID_FIFO,
+				AUX_EN_FIFO_READ);
+	} else {
+		/* The DP AUX transmit buffer has 4 bytes. */
+		size = min_t(size_t, size, 4);
+		it6505_set_bits(it6505, REG_AUX_CTRL, AUX_NO_SEGMENT_WR,
+				AUX_NO_SEGMENT_WR);
+	}
+
+	/* Start Address[7:0] */
+	it6505_write(it6505, REG_AUX_ADR_0_7, (address >> 0) & 0xFF);
+	/* Start Address[15:8] */
+	it6505_write(it6505, REG_AUX_ADR_8_15, (address >> 8) & 0xFF);
+	/* WriteNum[3:0]+StartAdr[19:16] */
+	it6505_write(it6505, REG_AUX_ADR_16_19,
+		     ((address >> 16) & 0x0F) | ((size - 1) << 4));
+
+	if (cmd == CMD_AUX_NATIVE_WRITE)
+		regmap_bulk_write(it6505->regmap, REG_AUX_OUT_DATA0, buffer,
+				  size);
+
+	/* Aux Fire */
+	it6505_write(it6505, REG_AUX_CMD_REQ, cmd);
+
+	ret = it6505_aux_wait(it6505);
+	if (ret < 0)
+		goto aux_op_err;
+
+	ret = it6505_read(it6505, REG_AUX_ERROR_STS);
+	if (ret < 0)
+		goto aux_op_err;
+
+	switch ((ret >> 6) & 0x3) {
+	case 0:
+		*reply = REPLY_ACK;
+		break;
+	case 1:
+		*reply = REPLY_DEFER;
+		ret = -EAGAIN;
+		goto aux_op_err;
+	case 2:
+		*reply = REPLY_NACK;
+		ret = -EIO;
+		goto aux_op_err;
+	case 3:
+		ret = -ETIMEDOUT;
+		goto aux_op_err;
+	}
+
+	/* Read back Native Write data */
+	if (cmd == CMD_AUX_NATIVE_WRITE) {
+		aux_write_check = true;
+		cmd = CMD_AUX_NATIVE_READ;
+		goto aux_op_start;
+	}
+
+	if (cmd == CMD_AUX_I2C_EDID_READ) {
+		for (i = 0; i < size; i++) {
+			ret = it6505_read(it6505, REG_AUX_DATA_FIFO);
+			if (ret < 0)
+				goto aux_op_err;
+			buffer[i] = ret;
+		}
+	} else {
+		for (i = 0; i < size; i++) {
+			ret = it6505_read(it6505, REG_AUX_DATA_0_7 + i);
+			if (ret < 0)
+				goto aux_op_err;
+
+			if (aux_write_check && buffer[size - 1 - i] != ret) {
+				ret = -EINVAL;
+				goto aux_op_err;
+			}
+
+			buffer[size - 1 - i] = ret;
+		}
+	}
+
+	ret = i;
+
+aux_op_err:
+	if (cmd == CMD_AUX_I2C_EDID_READ) {
+		/* clear AUX FIFO */
+		it6505_set_bits(it6505, REG_AUX_CTRL,
+				AUX_EN_FIFO_READ | CLR_EDID_FIFO,
+				AUX_EN_FIFO_READ | CLR_EDID_FIFO);
+		it6505_set_bits(it6505, REG_AUX_CTRL,
+				AUX_EN_FIFO_READ | CLR_EDID_FIFO, 0x00);
+	}
+
+	/* Leave AUX user mode */
+	it6505_set_bits(it6505, REG_AUX_CTRL, AUX_USER_MODE, 0);
+
+	return ret;
+}
+
+static ssize_t it6505_aux_do_transfer(struct it6505 *it6505,
+				      enum aux_cmd_type cmd,
+				      unsigned int address, u8 *buffer,
+				      size_t size, enum aux_cmd_reply *reply)
+{
+	int i, ret_size, ret = 0, request_size;
+
+	mutex_lock(&it6505->aux_lock);
+	for (i = 0; i < size; i += 4) {
+		request_size = min((int)size - i, 4);
+		ret_size = it6505_aux_operation(it6505, cmd, address + i,
+						buffer + i, request_size,
+						reply);
+		if (ret_size < 0) {
+			ret = ret_size;
+			goto aux_op_err;
+		}
+
+		ret += ret_size;
+	}
+
+aux_op_err:
+	mutex_unlock(&it6505->aux_lock);
+	return ret;
+}
+
+static ssize_t it6505_aux_transfer(struct drm_dp_aux *aux,
+				   struct drm_dp_aux_msg *msg)
+{
+	struct it6505 *it6505 = container_of(aux, struct it6505, aux);
+	u8 cmd;
+	bool is_i2c = !(msg->request & DP_AUX_NATIVE_WRITE);
+	int ret;
+	enum aux_cmd_reply reply;
+
+	/* IT6505 doesn't support arbitrary I2C read / write. */
+	if (is_i2c)
+		return -EINVAL;
+
+	switch (msg->request) {
+	case DP_AUX_NATIVE_READ:
+		cmd = CMD_AUX_NATIVE_READ;
+		break;
+	case DP_AUX_NATIVE_WRITE:
+		cmd = CMD_AUX_NATIVE_WRITE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = it6505_aux_do_transfer(it6505, cmd, msg->address, msg->buffer,
+				     msg->size, &reply);
+	if (ret < 0)
+		return ret;
+
+	switch (reply) {
+	case REPLY_ACK:
+		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+		break;
+	case REPLY_NACK:
+		msg->reply = DP_AUX_NATIVE_REPLY_NACK;
+		break;
+	case REPLY_DEFER:
+		msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
+		break;
+	}
+
+	return ret;
+}
+
+static int it6505_get_edid_block(void *data, u8 *buf, unsigned int block,
+				 size_t len)
+{
+	struct it6505 *it6505 = data;
+	struct device *dev = &it6505->client->dev;
+	enum aux_cmd_reply reply;
+	int offset, ret, aux_retry = 100;
+
+	it6505_aux_reset(it6505);
+	DRM_DEV_DEBUG_DRIVER(dev, "block number = %d", block);
+
+	for (offset = 0; offset < EDID_LENGTH;) {
+		ret = it6505_aux_do_transfer(it6505, CMD_AUX_I2C_EDID_READ,
+					     block * EDID_LENGTH + offset,
+					     buf + offset, 8, &reply);
+
+		if (ret < 0 && ret != -EAGAIN)
+			return ret;
+
+		switch (reply) {
+		case REPLY_ACK:
+			DRM_DEV_DEBUG_DRIVER(dev, "[0x%02x]: %8ph", offset,
+					     buf + offset);
+			offset += 8;
+			aux_retry = 100;
+			break;
+		case REPLY_NACK:
+			return -EIO;
+		case REPLY_DEFER:
+			msleep(20);
+			if (!(--aux_retry))
+				return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static void it6505_variable_config(struct it6505 *it6505)
+{
+	it6505->link_rate_bw_code = HBR;
+	it6505->lane_count = MAX_LANE_COUNT;
+	it6505->link_state = LINK_IDLE;
+	it6505->hdcp_desired = HDCP_DESIRED;
+	it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+	it6505->audio.select = AUDIO_SELECT;
+	it6505->audio.sample_rate = AUDIO_SAMPLE_RATE;
+	it6505->audio.channel_count = AUDIO_CHANNEL_COUNT;
+	it6505->audio.type = AUDIO_TYPE;
+	it6505->audio.i2s_input_format = I2S_INPUT_FORMAT;
+	it6505->audio.i2s_justified = I2S_JUSTIFIED;
+	it6505->audio.i2s_data_delay = I2S_DATA_DELAY;
+	it6505->audio.i2s_ws_channel = I2S_WS_CHANNEL;
+	it6505->audio.i2s_data_sequence = I2S_DATA_SEQUENCE;
+	it6505->audio.word_length = AUDIO_WORD_LENGTH;
+	memset(it6505->sha1_input, 0, sizeof(it6505->sha1_input));
+	memset(it6505->bksvs, 0, sizeof(it6505->bksvs));
+}
+
+static int it6505_send_video_infoframe(struct it6505 *it6505,
+				       struct hdmi_avi_infoframe *frame)
+{
+	u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
+	int err;
+	struct device *dev = &it6505->client->dev;
+
+	err = hdmi_avi_infoframe_pack(frame, buffer, sizeof(buffer));
+	if (err < 0) {
+		dev_err(dev, "Failed to pack AVI infoframe: %d", err);
+		return err;
+	}
+
+	err = it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_AVI_PKT, 0x00);
+	if (err)
+		return err;
+
+	err = regmap_bulk_write(it6505->regmap, REG_AVI_INFO_DB1,
+				buffer + HDMI_INFOFRAME_HEADER_SIZE,
+				frame->length);
+	if (err)
+		return err;
+
+	err = it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_AVI_PKT,
+			      EN_AVI_PKT);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static void it6505_get_extcon_property(struct it6505 *it6505)
+{
+	int err;
+	union extcon_property_value property;
+	struct device *dev = &it6505->client->dev;
+
+	if (it6505->extcon && !it6505->lane_swap_disabled) {
+		err = extcon_get_property(it6505->extcon, EXTCON_DISP_DP,
+					  EXTCON_PROP_USB_TYPEC_POLARITY,
+					  &property);
+		if (err) {
+			dev_err(dev, "get property fail!");
+			return;
+		}
+		it6505->lane_swap = property.intval;
+	}
+}
+
+static void it6505_clk_phase_adjustment(struct it6505 *it6505,
+					const struct drm_display_mode *mode)
+{
+	int clock = mode->clock;
+
+	it6505_set_bits(it6505, REG_CLK_CTRL0, M_PCLK_DELAY,
+			clock < ADJUST_PHASE_THRESHOLD ? PIXEL_CLK_DELAY : 0);
+	it6505_set_bits(it6505, REG_DATA_CTRL0, VIDEO_LATCH_EDGE,
+			PIXEL_CLK_INVERSE << 4);
+}
+
+static void it6505_link_reset_step_train(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_TRAIN_CTRL0,
+			FORCE_CR_DONE | FORCE_EQ_DONE, 0x00);
+	it6505_dpcd_write(it6505, DP_TRAINING_PATTERN_SET,
+			  DP_TRAINING_PATTERN_DISABLE);
+}
+
+static void it6505_init(struct it6505 *it6505)
+{
+	it6505_write(it6505, REG_AUX_OPT, AUX_AUTO_RST | AUX_FIX_FREQ);
+	it6505_write(it6505, REG_AUX_CTRL, AUX_NO_SEGMENT_WR);
+	it6505_write(it6505, REG_HDCP_CTRL2, HDCP_AN_SEL | HDCP_HW_HPDIRQ_ACT);
+	it6505_write(it6505, REG_VID_BUS_CTRL0, IN_DDR | DDR_CD);
+	it6505_write(it6505, REG_VID_BUS_CTRL1, 0x01);
+	it6505_write(it6505, REG_AUDIO_CTRL0, AUDIO_16B_BOUND);
+
+	/* chip internal setting, don't modify */
+	it6505_write(it6505, REG_HPD_IRQ_TIME, 0xF5);
+	it6505_write(it6505, REG_AUX_DEBUG_MODE, 0x4D);
+	it6505_write(it6505, REG_AUX_OPT2, 0x17);
+	it6505_write(it6505, REG_HDCP_OPT, 0x60);
+	it6505_write(it6505, REG_DATA_MUTE_CTRL,
+		     EN_VID_MUTE | EN_AUD_MUTE | ENABLE_AUTO_VIDEO_FIFO_RESET);
+	it6505_write(it6505, REG_TIME_STMP_CTRL,
+		     EN_SSC_GAT | EN_ENHANCE_VID_STMP | EN_ENHANCE_AUD_STMP);
+	it6505_write(it6505, REG_INFOFRAME_CTRL, 0x00);
+	it6505_write(it6505, REG_BANK_SEL, 0x01);
+	it6505_write(it6505, REG_DRV_0_DB_800_MV,
+		     afe_setting_table[it6505->afe_setting][0]);
+	it6505_write(it6505, REG_PRE_0_DB_800_MV,
+		     afe_setting_table[it6505->afe_setting][1]);
+	it6505_write(it6505, REG_PRE_3P5_DB_800_MV,
+		     afe_setting_table[it6505->afe_setting][2]);
+	it6505_write(it6505, REG_SSC_CTRL0, 0x9E);
+	it6505_write(it6505, REG_SSC_CTRL1, 0x1C);
+	it6505_write(it6505, REG_SSC_CTRL2, 0x42);
+	it6505_write(it6505, REG_BANK_SEL, 0x00);
+}
+
+static void it6505_video_disable(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, EN_VID_MUTE);
+	it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_VID_CTRL_PKT, 0x00);
+	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET);
+}
+
+static void it6505_video_reset(struct it6505 *it6505)
+{
+	it6505_link_reset_step_train(it6505);
+	it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, EN_VID_MUTE);
+	it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_VID_CTRL_PKT, 0x00);
+	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET);
+	it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, RST_501_FIFO);
+	it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, 0x00);
+	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, 0x00);
+}
+
+static void it6505_update_video_parameter(struct it6505 *it6505,
+					  const struct drm_display_mode *mode)
+{
+	it6505_clk_phase_adjustment(it6505, mode);
+	it6505_video_disable(it6505);
+}
+
+static bool it6505_audio_input(struct it6505 *it6505)
+{
+	int reg05, regbe;
+
+	reg05 = it6505_read(it6505, REG_RESET_CTRL);
+	it6505_set_bits(it6505, REG_RESET_CTRL, AUDIO_RESET, 0x00);
+	usleep_range(3000, 4000);
+	regbe = it6505_read(it6505, REG_AUDIO_INPUT_FREQ);
+	it6505_write(it6505, REG_RESET_CTRL, reg05);
+
+	return regbe != 0xFF;
+}
+
+static void it6505_setup_audio_channel_status(struct it6505 *it6505)
+{
+	enum it6505_audio_sample_rate sample_rate = it6505->audio.sample_rate;
+	u8 audio_word_length_map[] = { 0x02, 0x04, 0x03, 0x0B };
+
+	/* Channel Status */
+	it6505_write(it6505, REG_IEC958_STS0, it6505->audio.type << 1);
+	it6505_write(it6505, REG_IEC958_STS1, 0x00);
+	it6505_write(it6505, REG_IEC958_STS2, 0x00);
+	it6505_write(it6505, REG_IEC958_STS3, sample_rate);
+	it6505_write(it6505, REG_IEC958_STS4, (~sample_rate << 4) |
+		     audio_word_length_map[it6505->audio.word_length]);
+}
+
+static void it6505_setup_audio_format(struct it6505 *it6505)
+{
+	/* I2S MODE */
+	it6505_write(it6505, REG_AUDIO_FMT,
+		     (it6505->audio.word_length << 5) |
+		     (it6505->audio.i2s_data_sequence << 4) |
+		     (it6505->audio.i2s_ws_channel << 3) |
+		     (it6505->audio.i2s_data_delay << 2) |
+		     (it6505->audio.i2s_justified << 1) |
+		     it6505->audio.i2s_input_format);
+	if (it6505->audio.select == SPDIF) {
+		it6505_write(it6505, REG_AUDIO_FIFO_SEL, 0x00);
+		/* 0x30 = 128*FS */
+		it6505_set_bits(it6505, REG_AUX_OPT, 0xF0, 0x30);
+	} else {
+		it6505_write(it6505, REG_AUDIO_FIFO_SEL, 0xE4);
+	}
+
+	it6505_write(it6505, REG_AUDIO_CTRL0, 0x20);
+	it6505_write(it6505, REG_AUDIO_CTRL1, 0x00);
+}
+
+static void it6505_enable_audio_source(struct it6505 *it6505)
+{
+	unsigned int audio_source_count;
+
+	audio_source_count = BIT(DIV_ROUND_UP(it6505->audio.channel_count, 2))
+				 - 1;
+
+	audio_source_count |= it6505->audio.select << 4;
+
+	it6505_write(it6505, REG_AUDIO_SRC_CTRL, audio_source_count);
+}
+
+static void it6505_enable_audio_infoframe(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	u8 audio_info_ca[] = { 0x00, 0x00, 0x01, 0x03, 0x07, 0x0B, 0x0F, 0x1F };
+
+	DRM_DEV_DEBUG_DRIVER(dev, "infoframe channel_allocation:0x%02x",
+			     audio_info_ca[it6505->audio.channel_count - 1]);
+
+	it6505_write(it6505, REG_AUD_INFOFRAM_DB1, it6505->audio.channel_count
+		     - 1);
+	it6505_write(it6505, REG_AUD_INFOFRAM_DB2, 0x00);
+	it6505_write(it6505, REG_AUD_INFOFRAM_DB3,
+		     audio_info_ca[it6505->audio.channel_count - 1]);
+	it6505_write(it6505, REG_AUD_INFOFRAM_DB4, 0x00);
+	it6505_write(it6505, REG_AUD_INFOFRAM_SUM, 0x00);
+
+	/* Enable Audio InfoFrame */
+	it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_AUD_CTRL_PKT,
+			EN_AUD_CTRL_PKT);
+}
+
+static void it6505_disable_audio(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_AUD_MUTE, EN_AUD_MUTE);
+	it6505_set_bits(it6505, REG_AUDIO_SRC_CTRL, M_AUDIO_I2S_EN, 0x00);
+	it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_AUD_CTRL_PKT, 0x00);
+	it6505_set_bits(it6505, REG_RESET_CTRL, AUDIO_RESET, AUDIO_RESET);
+}
+
+static void it6505_enable_audio(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	int regbe;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "start");
+	it6505_disable_audio(it6505);
+
+	it6505_setup_audio_channel_status(it6505);
+	it6505_setup_audio_format(it6505);
+	it6505_enable_audio_source(it6505);
+	it6505_enable_audio_infoframe(it6505);
+
+	it6505_write(it6505, REG_AUDIO_N_0_7, 0x00);
+	it6505_write(it6505, REG_AUDIO_N_8_15, 0x80);
+	it6505_write(it6505, REG_AUDIO_N_16_23, 0x00);
+
+	it6505_set_bits(it6505, REG_AUDIO_SRC_CTRL, AUDIO_FIFO_RESET,
+			AUDIO_FIFO_RESET);
+	it6505_set_bits(it6505, REG_AUDIO_SRC_CTRL, AUDIO_FIFO_RESET, 0x00);
+	it6505_set_bits(it6505, REG_RESET_CTRL, AUDIO_RESET, 0x00);
+	regbe = it6505_read(it6505, REG_AUDIO_INPUT_FREQ);
+	DRM_DEV_DEBUG_DRIVER(dev, "regbe:0x%02x audio input fs: %d.%d kHz",
+			     regbe, 6750 / regbe, (6750 % regbe) * 10 / regbe);
+	it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_AUD_MUTE, 0x00);
+}
+
+static bool it6505_use_step_train_check(struct it6505 *it6505)
+{
+	if (it6505->link.revision >= 0x12)
+		return it6505->dpcd[DP_TRAINING_AUX_RD_INTERVAL] >= 0x01;
+
+	return true;
+}
+
+static void it6505_parse_link_capabilities(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	struct it6505_drm_dp_link *link = &it6505->link;
+	int bcaps;
+
+	if (it6505->dpcd[0] == 0) {
+		it6505_aux_on(it6505);
+		it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd,
+				ARRAY_SIZE(it6505->dpcd));
+	}
+
+	DRM_DEV_DEBUG_DRIVER(dev, "DPCD Rev.: %d.%d",
+			     link->revision >> 4, link->revision & 0x0F);
+
+	DRM_DEV_DEBUG_DRIVER(dev, "Sink max link rate: %d.%02d Gbps per lane",
+			     link->rate / 100000, link->rate / 1000 % 100);
+
+	it6505->link_rate_bw_code = drm_dp_link_rate_to_bw_code(link->rate);
+	DRM_DEV_DEBUG_DRIVER(dev, "link rate bw code:0x%02x",
+			     it6505->link_rate_bw_code);
+	it6505->link_rate_bw_code = min_t(int, it6505->link_rate_bw_code,
+					  MAX_LINK_RATE);
+
+	it6505->lane_count = link->num_lanes;
+	DRM_DEV_DEBUG_DRIVER(dev, "Sink support %d lanes training",
+			     it6505->lane_count);
+	it6505->lane_count = min_t(int, it6505->lane_count, MAX_LANE_COUNT);
+
+	it6505->branch_device = drm_dp_is_branch(it6505->dpcd);
+	DRM_DEV_DEBUG_DRIVER(dev, "Sink %sbranch device",
+			     it6505->branch_device ? "" : "Not ");
+
+	it6505->enable_enhanced_frame = link->capabilities;
+	DRM_DEV_DEBUG_DRIVER(dev, "Sink %sSupport Enhanced Framing",
+			     it6505->enable_enhanced_frame ? "" : "Not ");
+
+	it6505->enable_ssc = (it6505->dpcd[DP_MAX_DOWNSPREAD] &
+				DP_MAX_DOWNSPREAD_0_5);
+	DRM_DEV_DEBUG_DRIVER(dev, "Maximum Down-Spread: %s, %ssupport SSC!",
+			     it6505->enable_ssc ? "0.5" : "0",
+			     it6505->enable_ssc ? "" : "Not ");
+
+	it6505->step_train = it6505_use_step_train_check(it6505);
+	if (it6505->step_train)
+		DRM_DEV_DEBUG_DRIVER(dev, "auto train fail, will step train");
+
+	bcaps = it6505_dpcd_read(it6505, DP_AUX_HDCP_BCAPS);
+	DRM_DEV_DEBUG_DRIVER(dev, "bcaps:0x%02x", bcaps);
+	if (bcaps & DP_BCAPS_HDCP_CAPABLE) {
+		it6505->is_repeater = (bcaps & DP_BCAPS_REPEATER_PRESENT);
+		DRM_DEV_DEBUG_DRIVER(dev, "Support HDCP! Downstream is %s!",
+				     it6505->is_repeater ? "repeater" :
+				     "receiver");
+	} else {
+		DRM_DEV_DEBUG_DRIVER(dev, "Sink not support HDCP!");
+		it6505->hdcp_desired = false;
+	}
+	DRM_DEV_DEBUG_DRIVER(dev, "HDCP %s",
+			     it6505->hdcp_desired ? "desired" : "undesired");
+}
+
+static void it6505_setup_ssc(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_TRAIN_CTRL0, SPREAD_AMP_5,
+			it6505->enable_ssc ? SPREAD_AMP_5 : 0x00);
+	if (it6505->enable_ssc) {
+		it6505_write(it6505, REG_BANK_SEL, 0x01);
+		it6505_write(it6505, REG_SSC_CTRL0, 0x9E);
+		it6505_write(it6505, REG_SSC_CTRL1, 0x1C);
+		it6505_write(it6505, REG_SSC_CTRL2, 0x42);
+		it6505_write(it6505, REG_BANK_SEL, 0x00);
+		it6505_write(it6505, REG_SP_CTRL0, 0x07);
+		it6505_write(it6505, REG_IP_CTRL1, 0x29);
+		it6505_write(it6505, REG_IP_CTRL2, 0x03);
+		/* Stamp Interrupt Step */
+		it6505_set_bits(it6505, REG_TIME_STMP_CTRL, M_STAMP_STEP,
+				0x10);
+		it6505_dpcd_write(it6505, DP_DOWNSPREAD_CTRL,
+				  DP_SPREAD_AMP_0_5);
+	} else {
+		it6505_dpcd_write(it6505, DP_DOWNSPREAD_CTRL, 0x00);
+		it6505_set_bits(it6505, REG_TIME_STMP_CTRL, M_STAMP_STEP,
+				0x00);
+	}
+}
+
+static inline void it6505_link_rate_setup(struct it6505 *it6505)
+{
+	it6505_set_bits(it6505, REG_TRAIN_CTRL0, FORCE_LBR,
+			(it6505->link_rate_bw_code == RBR) ? FORCE_LBR : 0x00);
+	it6505_set_bits(it6505, REG_LINK_DRV, DRV_HS,
+			(it6505->link_rate_bw_code == RBR) ? 0x00 : DRV_HS);
+}
+
+static void it6505_lane_count_setup(struct it6505 *it6505)
+{
+	it6505_get_extcon_property(it6505);
+	it6505_set_bits(it6505, REG_TRAIN_CTRL0, LANE_SWAP,
+			it6505->lane_swap ? LANE_SWAP : 0x00);
+	it6505_set_bits(it6505, REG_TRAIN_CTRL0, LANE_COUNT_MASK,
+			(it6505->lane_count - 1) << 1);
+}
+
+static void it6505_link_training_setup(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	if (it6505->enable_enhanced_frame)
+		it6505_set_bits(it6505, REG_DATA_MUTE_CTRL,
+				ENABLE_ENHANCED_FRAME, ENABLE_ENHANCED_FRAME);
+
+	it6505_link_rate_setup(it6505);
+	it6505_lane_count_setup(it6505);
+	it6505_setup_ssc(it6505);
+	DRM_DEV_DEBUG_DRIVER(dev,
+			     "%s, %d lanes, %sable ssc, %sable enhanced frame",
+			     it6505->link_rate_bw_code != RBR ? "HBR" : "RBR",
+			     it6505->lane_count,
+			     it6505->enable_ssc ? "en" : "dis",
+			     it6505->enable_enhanced_frame ? "en" : "dis");
+}
+
+static bool it6505_link_start_auto_train(struct it6505 *it6505)
+{
+	int timeout = 500, link_training_state;
+	bool state = false;
+
+	mutex_lock(&it6505->aux_lock);
+	it6505_set_bits(it6505, REG_TRAIN_CTRL0,
+			FORCE_CR_DONE | FORCE_EQ_DONE, 0x00);
+	it6505_write(it6505, REG_TRAIN_CTRL1, FORCE_RETRAIN);
+	it6505_write(it6505, REG_TRAIN_CTRL1, AUTO_TRAIN);
+
+	while (timeout > 0) {
+		usleep_range(1000, 2000);
+		link_training_state = it6505_read(it6505, REG_LINK_TRAIN_STS);
+
+		if (link_training_state > 0 &&
+		    (link_training_state & LINK_STATE_NORP)) {
+			state = true;
+			goto unlock;
+		}
+
+		timeout--;
+	}
+unlock:
+	mutex_unlock(&it6505->aux_lock);
+
+	return state;
+}
+
+static int it6505_drm_dp_link_configure(struct it6505 *it6505)
+{
+	u8 values[2];
+	int err;
+	struct drm_dp_aux *aux = &it6505->aux;
+
+	values[0] = it6505->link_rate_bw_code;
+	values[1] = it6505->lane_count;
+
+	if (it6505->enable_enhanced_frame)
+		values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+
+	err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, values, sizeof(values));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static bool it6505_check_voltage_swing_max(u8 lane_voltage_swing_pre_emphasis)
+{
+	return ((lane_voltage_swing_pre_emphasis & 0x03) == MAX_CR_LEVEL);
+}
+
+static bool it6505_check_pre_emphasis_max(u8 lane_voltage_swing_pre_emphasis)
+{
+	return ((lane_voltage_swing_pre_emphasis & 0x03) == MAX_EQ_LEVEL);
+}
+
+static bool it6505_check_max_voltage_swing_reached(u8 *lane_voltage_swing,
+						   u8 lane_count)
+{
+	u8 i;
+
+	for (i = 0; i < lane_count; i++) {
+		if (lane_voltage_swing[i] & DP_TRAIN_MAX_SWING_REACHED)
+			return true;
+	}
+
+	return false;
+}
+
+static bool
+step_train_lane_voltage_para_set(struct it6505 *it6505,
+				 struct it6505_step_train_para
+				 *lane_voltage_pre_emphasis,
+				 u8 *lane_voltage_pre_emphasis_set)
+{
+	u8 *voltage_swing = lane_voltage_pre_emphasis->voltage_swing;
+	u8 *pre_emphasis = lane_voltage_pre_emphasis->pre_emphasis;
+	u8 i;
+
+	for (i = 0; i < it6505->lane_count; i++) {
+		voltage_swing[i] &= 0x03;
+		lane_voltage_pre_emphasis_set[i] = voltage_swing[i];
+		if (it6505_check_voltage_swing_max(voltage_swing[i]))
+			lane_voltage_pre_emphasis_set[i] |=
+				DP_TRAIN_MAX_SWING_REACHED;
+
+		pre_emphasis[i] &= 0x03;
+		lane_voltage_pre_emphasis_set[i] |= pre_emphasis[i]
+			<< DP_TRAIN_PRE_EMPHASIS_SHIFT;
+		if (it6505_check_pre_emphasis_max(pre_emphasis[i]))
+			lane_voltage_pre_emphasis_set[i] |=
+				DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+		it6505_dpcd_write(it6505, DP_TRAINING_LANE0_SET + i,
+				  lane_voltage_pre_emphasis_set[i]);
+
+		if (lane_voltage_pre_emphasis_set[i] !=
+		    it6505_dpcd_read(it6505, DP_TRAINING_LANE0_SET + i))
+			return false;
+	}
+
+	return true;
+}
+
+static bool
+it6505_step_cr_train(struct it6505 *it6505,
+		     struct it6505_step_train_para *lane_voltage_pre_emphasis)
+{
+	u8 loop_count = 0, i = 0, j;
+	u8 link_status[DP_LINK_STATUS_SIZE] = { 0 };
+	u8 lane_level_config[MAX_LANE_COUNT] = { 0 };
+	int pre_emphasis_adjust = -1, voltage_swing_adjust = -1;
+	const struct drm_dp_aux *aux = &it6505->aux;
+
+	it6505_dpcd_write(it6505, DP_DOWNSPREAD_CTRL,
+			  it6505->enable_ssc ? DP_SPREAD_AMP_0_5 : 0x00);
+	it6505_dpcd_write(it6505, DP_TRAINING_PATTERN_SET,
+			  DP_TRAINING_PATTERN_1);
+
+	while (loop_count < 5 && i < 10) {
+		i++;
+		if (!step_train_lane_voltage_para_set(it6505,
+						      lane_voltage_pre_emphasis,
+						      lane_level_config))
+			continue;
+		drm_dp_link_train_clock_recovery_delay(aux, it6505->dpcd);
+		drm_dp_dpcd_read_link_status(&it6505->aux, link_status);
+
+		if (drm_dp_clock_recovery_ok(link_status, it6505->lane_count)) {
+			it6505_set_bits(it6505, REG_TRAIN_CTRL0, FORCE_CR_DONE,
+					FORCE_CR_DONE);
+			return true;
+		}
+		DRM_DEV_DEBUG_DRIVER(&it6505->client->dev, "cr not done");
+
+		if (it6505_check_max_voltage_swing_reached(lane_level_config,
+							   it6505->lane_count))
+			goto cr_train_fail;
+
+		for (j = 0; j < it6505->lane_count; j++) {
+			lane_voltage_pre_emphasis->voltage_swing[j] =
+				drm_dp_get_adjust_request_voltage(link_status,
+								  j) >>
+				DP_TRAIN_VOLTAGE_SWING_SHIFT;
+			lane_voltage_pre_emphasis->pre_emphasis[j] =
+			drm_dp_get_adjust_request_pre_emphasis(link_status,
+							       j) >>
+					DP_TRAIN_PRE_EMPHASIS_SHIFT;
+			if (voltage_swing_adjust ==
+			     lane_voltage_pre_emphasis->voltage_swing[j] &&
+			    pre_emphasis_adjust ==
+			     lane_voltage_pre_emphasis->pre_emphasis[j]) {
+				loop_count++;
+				continue;
+			}
+
+			voltage_swing_adjust =
+				lane_voltage_pre_emphasis->voltage_swing[j];
+			pre_emphasis_adjust =
+				lane_voltage_pre_emphasis->pre_emphasis[j];
+			loop_count = 0;
+
+			if (voltage_swing_adjust + pre_emphasis_adjust >
+			    MAX_EQ_LEVEL)
+				lane_voltage_pre_emphasis->voltage_swing[j] =
+					MAX_EQ_LEVEL -
+					lane_voltage_pre_emphasis
+						->pre_emphasis[j];
+		}
+	}
+
+cr_train_fail:
+	it6505_dpcd_write(it6505, DP_TRAINING_PATTERN_SET,
+			  DP_TRAINING_PATTERN_DISABLE);
+
+	return false;
+}
+
+static bool
+it6505_step_eq_train(struct it6505 *it6505,
+		     struct it6505_step_train_para *lane_voltage_pre_emphasis)
+{
+	u8 loop_count = 0, i, link_status[DP_LINK_STATUS_SIZE] = { 0 };
+	u8 lane_level_config[MAX_LANE_COUNT] = { 0 };
+	const struct drm_dp_aux *aux = &it6505->aux;
+
+	it6505_dpcd_write(it6505, DP_TRAINING_PATTERN_SET,
+			  DP_TRAINING_PATTERN_2);
+
+	while (loop_count < 6) {
+		loop_count++;
+
+		if (!step_train_lane_voltage_para_set(it6505,
+						      lane_voltage_pre_emphasis,
+						      lane_level_config))
+			continue;
+
+		drm_dp_link_train_channel_eq_delay(aux, it6505->dpcd);
+		drm_dp_dpcd_read_link_status(&it6505->aux, link_status);
+
+		if (!drm_dp_clock_recovery_ok(link_status, it6505->lane_count))
+			goto eq_train_fail;
+
+		if (drm_dp_channel_eq_ok(link_status, it6505->lane_count)) {
+			it6505_dpcd_write(it6505, DP_TRAINING_PATTERN_SET,
+					  DP_TRAINING_PATTERN_DISABLE);
+			it6505_set_bits(it6505, REG_TRAIN_CTRL0, FORCE_EQ_DONE,
+					FORCE_EQ_DONE);
+			return true;
+		}
+		DRM_DEV_DEBUG_DRIVER(&it6505->client->dev, "eq not done");
+
+		for (i = 0; i < it6505->lane_count; i++) {
+			lane_voltage_pre_emphasis->voltage_swing[i] =
+				drm_dp_get_adjust_request_voltage(link_status,
+								  i) >>
+				DP_TRAIN_VOLTAGE_SWING_SHIFT;
+			lane_voltage_pre_emphasis->pre_emphasis[i] =
+			drm_dp_get_adjust_request_pre_emphasis(link_status,
+							       i) >>
+					DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+			if (lane_voltage_pre_emphasis->voltage_swing[i] +
+				    lane_voltage_pre_emphasis->pre_emphasis[i] >
+			    MAX_EQ_LEVEL)
+				lane_voltage_pre_emphasis->voltage_swing[i] =
+					0x03 - lane_voltage_pre_emphasis
+						       ->pre_emphasis[i];
+		}
+	}
+
+eq_train_fail:
+	it6505_dpcd_write(it6505, DP_TRAINING_PATTERN_SET,
+			  DP_TRAINING_PATTERN_DISABLE);
+	return false;
+}
+
+static bool it6505_link_start_step_train(struct it6505 *it6505)
+{
+	int err;
+	struct it6505_step_train_para lane_voltage_pre_emphasis = {
+		.voltage_swing = { 0 },
+		.pre_emphasis = { 0 },
+	};
+
+	DRM_DEV_DEBUG_DRIVER(&it6505->client->dev, "start");
+	err = it6505_drm_dp_link_configure(it6505);
+
+	if (err < 0)
+		return false;
+	if (!it6505_step_cr_train(it6505, &lane_voltage_pre_emphasis))
+		return false;
+	if (!it6505_step_eq_train(it6505, &lane_voltage_pre_emphasis))
+		return false;
+	return true;
+}
+
+static bool it6505_get_video_status(struct it6505 *it6505)
+{
+	int reg_0d;
+
+	reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+
+	if (reg_0d < 0)
+		return false;
+
+	return reg_0d & VIDEO_STB;
+}
+
+static void it6505_reset_hdcp(struct it6505 *it6505)
+{
+	it6505->hdcp_status = HDCP_AUTH_IDLE;
+	/* Disable CP_Desired */
+	it6505_set_bits(it6505, REG_HDCP_CTRL1, HDCP_CP_ENABLE, 0x00);
+	it6505_set_bits(it6505, REG_RESET_CTRL, HDCP_RESET, HDCP_RESET);
+}
+
+static void it6505_start_hdcp(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "start");
+	it6505_reset_hdcp(it6505);
+	queue_delayed_work(system_wq, &it6505->hdcp_work,
+			   msecs_to_jiffies(2400));
+}
+
+static void it6505_stop_hdcp(struct it6505 *it6505)
+{
+	it6505_reset_hdcp(it6505);
+	cancel_delayed_work(&it6505->hdcp_work);
+}
+
+static bool it6505_hdcp_is_ksv_valid(u8 *ksv)
+{
+	int i, ones = 0;
+
+	/* KSV has 20 1's and 20 0's */
+	for (i = 0; i < DRM_HDCP_KSV_LEN; i++)
+		ones += hweight8(ksv[i]);
+	if (ones != 20)
+		return false;
+	return true;
+}
+
+static void it6505_hdcp_part1_auth(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	u8 hdcp_bcaps;
+
+	it6505_set_bits(it6505, REG_RESET_CTRL, HDCP_RESET, 0x00);
+	/* Disable CP_Desired */
+	it6505_set_bits(it6505, REG_HDCP_CTRL1, HDCP_CP_ENABLE, 0x00);
+
+	usleep_range(1000, 1500);
+	hdcp_bcaps = it6505_dpcd_read(it6505, DP_AUX_HDCP_BCAPS);
+	DRM_DEV_DEBUG_DRIVER(dev, "DPCD[0x68028]: 0x%02x",
+			     hdcp_bcaps);
+
+	if (!hdcp_bcaps)
+		return;
+
+	/* clear the repeater List Chk Done and fail bit */
+	it6505_set_bits(it6505, REG_HDCP_TRIGGER,
+			HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL,
+			0x00);
+
+	/* Enable An Generator */
+	it6505_set_bits(it6505, REG_HDCP_CTRL2, HDCP_AN_GEN, HDCP_AN_GEN);
+	/* delay1ms(10);*/
+	usleep_range(10000, 15000);
+	/* Stop An Generator */
+	it6505_set_bits(it6505, REG_HDCP_CTRL2, HDCP_AN_GEN, 0x00);
+
+	it6505_set_bits(it6505, REG_HDCP_CTRL1, HDCP_CP_ENABLE, HDCP_CP_ENABLE);
+
+	it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_START,
+			HDCP_TRIGGER_START);
+
+	it6505->hdcp_status = HDCP_AUTH_GOING;
+}
+
+static int it6505_sha1_digest(struct it6505 *it6505, u8 *sha1_input,
+			      unsigned int size, u8 *output_av)
+{
+	struct shash_desc *desc;
+	struct crypto_shash *tfm;
+	int err;
+	struct device *dev = &it6505->client->dev;
+
+	tfm = crypto_alloc_shash("sha1", 0, 0);
+	if (IS_ERR(tfm)) {
+		dev_err(dev, "crypto_alloc_shash sha1 failed");
+		return PTR_ERR(tfm);
+	}
+	desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
+	if (!desc) {
+		crypto_free_shash(tfm);
+		return -ENOMEM;
+	}
+
+	desc->tfm = tfm;
+	err = crypto_shash_digest(desc, sha1_input, size, output_av);
+	if (err)
+		dev_err(dev, "crypto_shash_digest sha1 failed");
+
+	crypto_free_shash(tfm);
+	kfree(desc);
+	return err;
+}
+
+static int it6505_setup_sha1_input(struct it6505 *it6505, u8 *sha1_input)
+{
+	struct device *dev = &it6505->client->dev;
+	u8 binfo[2];
+	int down_stream_count, i, err, msg_count = 0;
+
+	err = it6505_get_dpcd(it6505, DP_AUX_HDCP_BINFO, binfo,
+			      ARRAY_SIZE(binfo));
+
+	if (err < 0) {
+		dev_err(dev, "Read binfo value Fail");
+		return err;
+	}
+
+	down_stream_count = binfo[0] & 0x7F;
+	DRM_DEV_DEBUG_DRIVER(dev, "binfo:0x%*ph", (int)ARRAY_SIZE(binfo),
+			     binfo);
+
+	if ((binfo[0] & BIT(7)) || (binfo[1] & BIT(3))) {
+		dev_err(dev, "HDCP max cascade device exceed");
+		return 0;
+	}
+
+	if (!down_stream_count ||
+	    down_stream_count > MAX_HDCP_DOWN_STREAM_COUNT) {
+		dev_err(dev, "HDCP down stream count Error %d",
+			down_stream_count);
+		return 0;
+	}
+
+	for (i = 0; i < down_stream_count; i++) {
+		err = it6505_get_dpcd(it6505, DP_AUX_HDCP_KSV_FIFO +
+				      (i % 3) * DRM_HDCP_KSV_LEN,
+				      sha1_input + msg_count,
+				      DRM_HDCP_KSV_LEN);
+
+		if (err < 0)
+			return err;
+
+		msg_count += 5;
+	}
+
+	it6505->hdcp_down_stream_count = down_stream_count;
+	sha1_input[msg_count++] = binfo[0];
+	sha1_input[msg_count++] = binfo[1];
+
+	it6505_set_bits(it6505, REG_HDCP_CTRL2, HDCP_EN_M0_READ,
+			HDCP_EN_M0_READ);
+
+	err = regmap_bulk_read(it6505->regmap, REG_M0_0_7,
+			       sha1_input + msg_count, 8);
+
+	it6505_set_bits(it6505, REG_HDCP_CTRL2, HDCP_EN_M0_READ, 0x00);
+
+	if (err < 0) {
+		dev_err(dev, " Warning, Read M value Fail");
+		return err;
+	}
+
+	msg_count += 8;
+
+	return msg_count;
+}
+
+static bool it6505_hdcp_part2_ksvlist_check(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	u8 av[5][4], bv[5][4];
+	int i, err;
+
+	i = it6505_setup_sha1_input(it6505, it6505->sha1_input);
+	if (i <= 0) {
+		dev_err(dev, "SHA-1 Input length error %d", i);
+		return false;
+	}
+
+	it6505_sha1_digest(it6505, it6505->sha1_input, i, (u8 *)av);
+
+	err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv,
+			      sizeof(bv));
+
+	if (err < 0) {
+		dev_err(dev, "Read V' value Fail");
+		return false;
+	}
+
+	for (i = 0; i < 5; i++)
+		if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] ||
+		    bv[i][1] != av[i][2] || bv[i][0] != av[i][3])
+			return false;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "V' all match!!");
+	return true;
+}
+
+static void it6505_hdcp_wait_ksv_list(struct work_struct *work)
+{
+	struct it6505 *it6505 = container_of(work, struct it6505,
+					     hdcp_wait_ksv_list);
+	struct device *dev = &it6505->client->dev;
+	unsigned int timeout = 5000;
+	u8 bstatus = 0;
+	bool ksv_list_check;
+
+	timeout /= 20;
+	while (timeout > 0) {
+		if (!it6505_get_sink_hpd_status(it6505))
+			return;
+
+		bstatus = it6505_dpcd_read(it6505, DP_AUX_HDCP_BSTATUS);
+
+		if (bstatus & DP_BSTATUS_READY)
+			break;
+
+		msleep(20);
+		timeout--;
+	}
+
+	if (timeout == 0) {
+		DRM_DEV_DEBUG_DRIVER(dev, "timeout and ksv list wait failed");
+		goto timeout;
+	}
+
+	ksv_list_check = it6505_hdcp_part2_ksvlist_check(it6505);
+	DRM_DEV_DEBUG_DRIVER(dev, "ksv list ready, ksv list check %s",
+			     ksv_list_check ? "pass" : "fail");
+	if (ksv_list_check) {
+		it6505_set_bits(it6505, REG_HDCP_TRIGGER,
+				HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE);
+		return;
+	}
+timeout:
+	it6505_set_bits(it6505, REG_HDCP_TRIGGER,
+			HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL,
+			HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL);
+}
+
+static void it6505_hdcp_work(struct work_struct *work)
+{
+	struct it6505 *it6505 = container_of(work, struct it6505,
+					     hdcp_work.work);
+	struct device *dev = &it6505->client->dev;
+	int ret;
+	u8 link_status[DP_LINK_STATUS_SIZE] = { 0 };
+
+	DRM_DEV_DEBUG_DRIVER(dev, "start");
+
+	if (!it6505_get_sink_hpd_status(it6505))
+		return;
+
+	ret = drm_dp_dpcd_read_link_status(&it6505->aux, link_status);
+	DRM_DEV_DEBUG_DRIVER(dev, "ret: %d link_status: %*ph", ret,
+			     (int)sizeof(link_status), link_status);
+
+	if (ret < 0 || !drm_dp_channel_eq_ok(link_status, it6505->lane_count) ||
+	    !it6505_get_video_status(it6505)) {
+		DRM_DEV_DEBUG_DRIVER(dev, "link train not done or no video");
+		return;
+	}
+
+	ret = it6505_get_dpcd(it6505, DP_AUX_HDCP_BKSV, it6505->bksvs,
+			      ARRAY_SIZE(it6505->bksvs));
+	if (ret < 0) {
+		dev_err(dev, "fail to get bksv  ret: %d", ret);
+		it6505_set_bits(it6505, REG_HDCP_TRIGGER,
+				HDCP_TRIGGER_KSV_FAIL, HDCP_TRIGGER_KSV_FAIL);
+	}
+
+	DRM_DEV_DEBUG_DRIVER(dev, "bksv = 0x%*ph",
+			     (int)ARRAY_SIZE(it6505->bksvs), it6505->bksvs);
+
+	if (!it6505_hdcp_is_ksv_valid(it6505->bksvs)) {
+		dev_err(dev, "Display Port bksv not valid");
+		it6505_set_bits(it6505, REG_HDCP_TRIGGER,
+				HDCP_TRIGGER_KSV_FAIL, HDCP_TRIGGER_KSV_FAIL);
+	}
+
+	it6505_hdcp_part1_auth(it6505);
+}
+
+static void it6505_show_hdcp_info(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	int i;
+	u8 *sha1 = it6505->sha1_input;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "hdcp_status: %d is_repeater: %d",
+			     it6505->hdcp_status, it6505->is_repeater);
+	DRM_DEV_DEBUG_DRIVER(dev, "bksv = 0x%*ph",
+			     (int)ARRAY_SIZE(it6505->bksvs), it6505->bksvs);
+
+	if (it6505->is_repeater) {
+		DRM_DEV_DEBUG_DRIVER(dev, "hdcp_down_stream_count: %d",
+				     it6505->hdcp_down_stream_count);
+		DRM_DEV_DEBUG_DRIVER(dev, "sha1_input: 0x%*ph",
+				     (int)ARRAY_SIZE(it6505->sha1_input),
+				     it6505->sha1_input);
+		for (i = 0; i < it6505->hdcp_down_stream_count; i++) {
+			DRM_DEV_DEBUG_DRIVER(dev, "KSV_%d = 0x%*ph", i,
+					     DRM_HDCP_KSV_LEN, sha1);
+			sha1 += DRM_HDCP_KSV_LEN;
+		}
+		DRM_DEV_DEBUG_DRIVER(dev, "binfo: 0x%2ph M0: 0x%8ph",
+				     sha1, sha1 + 2);
+	}
+}
+
+static void it6505_stop_link_train(struct it6505 *it6505)
+{
+	it6505->link_state = LINK_IDLE;
+	cancel_work_sync(&it6505->link_works);
+	it6505_write(it6505, REG_TRAIN_CTRL1, FORCE_RETRAIN);
+}
+
+static void it6505_link_train_ok(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	it6505->link_state = LINK_OK;
+	/* disalbe mute enable avi info frame */
+	it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, 0x00);
+	it6505_set_bits(it6505, REG_INFOFRAME_CTRL,
+			EN_VID_CTRL_PKT, EN_VID_CTRL_PKT);
+
+	if (it6505_audio_input(it6505)) {
+		DRM_DEV_DEBUG_DRIVER(dev, "Enable audio!");
+		it6505_enable_audio(it6505);
+	}
+
+	if (it6505->hdcp_desired)
+		it6505_start_hdcp(it6505);
+}
+
+static void it6505_link_step_train_process(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	int ret, i, step_retry = 3;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "Start step train");
+
+	if (it6505->sink_count == 0) {
+		DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count:%d, force eq",
+				     it6505->sink_count);
+		it6505_set_bits(it6505,	REG_TRAIN_CTRL0, FORCE_EQ_DONE,
+				FORCE_EQ_DONE);
+		return;
+	}
+
+	if (!it6505->step_train) {
+		DRM_DEV_DEBUG_DRIVER(dev, "not support step train");
+		return;
+	}
+
+	/* step training start here */
+	for (i = 0; i < step_retry; i++) {
+		it6505_link_reset_step_train(it6505);
+		ret = it6505_link_start_step_train(it6505);
+		DRM_DEV_DEBUG_DRIVER(dev, "step train %s, retry:%d times",
+				     ret ? "pass" : "failed", i + 1);
+		if (ret) {
+			it6505_link_train_ok(it6505);
+			return;
+		}
+	}
+
+	DRM_DEV_DEBUG_DRIVER(dev, "training fail");
+	it6505->link_state = LINK_IDLE;
+	it6505_video_reset(it6505);
+}
+
+static void it6505_link_training_work(struct work_struct *work)
+{
+	struct it6505 *it6505 = container_of(work, struct it6505, link_works);
+	struct device *dev = &it6505->client->dev;
+	int ret;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d",
+			     it6505->sink_count);
+
+	if (!it6505_get_sink_hpd_status(it6505))
+		return;
+
+	it6505_link_training_setup(it6505);
+	it6505_reset_hdcp(it6505);
+	it6505_aux_reset(it6505);
+
+	if (it6505->auto_train_retry < 1) {
+		it6505_link_step_train_process(it6505);
+		return;
+	}
+
+	ret = it6505_link_start_auto_train(it6505);
+	DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d",
+			     ret ? "pass" : "failed", it6505->auto_train_retry);
+	it6505->auto_train_retry--;
+
+	if (ret) {
+		it6505_link_train_ok(it6505);
+		return;
+	}
+
+	it6505_dump(it6505);
+}
+
+static void it6505_plugged_status_to_codec(struct it6505 *it6505)
+{
+	enum drm_connector_status status = it6505->connector_status;
+
+	if (it6505->plugged_cb && it6505->codec_dev)
+		it6505->plugged_cb(it6505->codec_dev,
+				   status == connector_status_connected);
+}
+
+static int it6505_process_hpd_irq(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	int ret, dpcd_sink_count, dp_irq_vector, bstatus;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+
+	if (!it6505_get_sink_hpd_status(it6505)) {
+		DRM_DEV_DEBUG_DRIVER(dev, "HPD_IRQ HPD low");
+		it6505->sink_count = 0;
+		return 0;
+	}
+
+	ret = it6505_dpcd_read(it6505, DP_SINK_COUNT);
+	if (ret < 0)
+		return ret;
+
+	dpcd_sink_count = DP_GET_SINK_COUNT(ret);
+	DRM_DEV_DEBUG_DRIVER(dev, "dpcd_sink_count: %d it6505->sink_count:%d",
+			     dpcd_sink_count, it6505->sink_count);
+
+	if (it6505->branch_device && dpcd_sink_count != it6505->sink_count) {
+		memset(it6505->dpcd, 0, sizeof(it6505->dpcd));
+		it6505->sink_count = dpcd_sink_count;
+		it6505_reset_logic(it6505);
+		it6505_int_mask_enable(it6505);
+		it6505_init(it6505);
+		return 0;
+	}
+
+	dp_irq_vector = it6505_dpcd_read(it6505, DP_DEVICE_SERVICE_IRQ_VECTOR);
+	if (dp_irq_vector < 0)
+		return dp_irq_vector;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "dp_irq_vector = 0x%02x", dp_irq_vector);
+
+	if (dp_irq_vector & DP_CP_IRQ) {
+		it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ,
+				HDCP_TRIGGER_CPIRQ);
+
+		bstatus = it6505_dpcd_read(it6505, DP_AUX_HDCP_BSTATUS);
+		if (bstatus < 0)
+			return bstatus;
+
+		DRM_DEV_DEBUG_DRIVER(dev, "Bstatus = 0x%02x", bstatus);
+	}
+
+	ret = drm_dp_dpcd_read_link_status(&it6505->aux, link_status);
+	if (ret < 0) {
+		dev_err(dev, "Fail to read link status ret: %d", ret);
+		return ret;
+	}
+
+	DRM_DEV_DEBUG_DRIVER(dev, "link status = 0x%*ph",
+			     (int)ARRAY_SIZE(link_status), link_status);
+
+	if (!drm_dp_channel_eq_ok(link_status, it6505->lane_count)) {
+		it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+		it6505_video_reset(it6505);
+	}
+
+	return 0;
+}
+
+static void it6505_irq_hpd(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	it6505->hpd_state = it6505_get_sink_hpd_status(it6505);
+	DRM_DEV_DEBUG_DRIVER(dev, "hpd change interrupt, change to %s",
+			     it6505->hpd_state ? "high" : "low");
+
+	if (it6505->bridge.dev)
+		drm_helper_hpd_irq_event(it6505->bridge.dev);
+	DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d",
+			     it6505->sink_count);
+
+	if (it6505->hpd_state) {
+		wait_for_completion_timeout(&it6505->wait_edid_complete,
+					    msecs_to_jiffies(6000));
+		it6505_lane_termination_on(it6505);
+		it6505_lane_power_on(it6505);
+
+		/*
+		 * for some dongle which issue HPD_irq
+		 * when sink count change from  0->1
+		 * it6505 not able to receive HPD_IRQ
+		 * if HW never go into trainig done
+		 */
+
+		if (it6505->branch_device && it6505->sink_count == 0)
+			schedule_work(&it6505->link_works);
+
+		if (!it6505_get_video_status(it6505))
+			it6505_video_reset(it6505);
+
+		it6505_calc_video_info(it6505);
+	} else {
+		memset(it6505->dpcd, 0, sizeof(it6505->dpcd));
+
+		if (it6505->hdcp_desired)
+			it6505_stop_hdcp(it6505);
+
+		it6505_video_disable(it6505);
+		it6505_disable_audio(it6505);
+		it6505_stop_link_train(it6505);
+		it6505_lane_off(it6505);
+		it6505_link_reset_step_train(it6505);
+	}
+}
+
+static void it6505_irq_hpd_irq(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "hpd_irq interrupt");
+
+	if (it6505_process_hpd_irq(it6505) < 0)
+		DRM_DEV_DEBUG_DRIVER(dev, "process hpd_irq fail!");
+}
+
+static void it6505_irq_scdt(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	bool data;
+
+	data = it6505_get_video_status(it6505);
+	DRM_DEV_DEBUG_DRIVER(dev, "video stable change interrupt, %s",
+			     data ? "stable" : "unstable");
+	it6505_calc_video_info(it6505);
+	it6505_link_reset_step_train(it6505);
+
+	if (data)
+		schedule_work(&it6505->link_works);
+}
+
+static void it6505_irq_hdcp_done(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "hdcp done interrupt");
+	it6505->hdcp_status = HDCP_AUTH_DONE;
+	it6505_show_hdcp_info(it6505);
+}
+
+static void it6505_irq_hdcp_fail(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "hdcp fail interrupt");
+	it6505->hdcp_status = HDCP_AUTH_IDLE;
+	it6505_show_hdcp_info(it6505);
+	it6505_start_hdcp(it6505);
+}
+
+static void it6505_irq_aux_cmd_fail(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "AUX PC Request Fail Interrupt");
+}
+
+static void it6505_irq_hdcp_ksv_check(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "HDCP event Interrupt");
+	schedule_work(&it6505->hdcp_wait_ksv_list);
+}
+
+static void it6505_irq_audio_fifo_error(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "audio fifo error Interrupt");
+
+	if (it6505_audio_input(it6505))
+		it6505_enable_audio(it6505);
+}
+
+static void it6505_irq_link_train_fail(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "link training fail interrupt");
+	schedule_work(&it6505->link_works);
+}
+
+static void it6505_irq_video_fifo_error(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "video fifo overflow interrupt");
+	it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+	flush_work(&it6505->link_works);
+	it6505_stop_hdcp(it6505);
+	it6505_video_reset(it6505);
+}
+
+static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "IO latch fifo overflow interrupt");
+	it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+	flush_work(&it6505->link_works);
+	it6505_stop_hdcp(it6505);
+	it6505_video_reset(it6505);
+}
+
+static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
+{
+	return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
+}
+
+static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
+{
+	struct it6505 *it6505 = data;
+	struct device *dev = &it6505->client->dev;
+	static const struct {
+		int bit;
+		void (*handler)(struct it6505 *it6505);
+	} irq_vec[] = {
+		{ BIT_INT_HPD, it6505_irq_hpd },
+		{ BIT_INT_HPD_IRQ, it6505_irq_hpd_irq },
+		{ BIT_INT_SCDT, it6505_irq_scdt },
+		{ BIT_INT_HDCP_FAIL, it6505_irq_hdcp_fail },
+		{ BIT_INT_HDCP_DONE, it6505_irq_hdcp_done },
+		{ BIT_INT_AUX_CMD_FAIL, it6505_irq_aux_cmd_fail },
+		{ BIT_INT_HDCP_KSV_CHECK, it6505_irq_hdcp_ksv_check },
+		{ BIT_INT_AUDIO_FIFO_ERROR, it6505_irq_audio_fifo_error },
+		{ BIT_INT_LINK_TRAIN_FAIL, it6505_irq_link_train_fail },
+		{ BIT_INT_VID_FIFO_ERROR, it6505_irq_video_fifo_error },
+		{ BIT_INT_IO_FIFO_OVERFLOW, it6505_irq_io_latch_fifo_overflow },
+	};
+	int int_status[3], i;
+
+	msleep(100);
+	mutex_lock(&it6505->extcon_lock);
+
+	if (it6505->enable_drv_hold || !it6505->powered)
+		goto unlock;
+
+	int_status[0] = it6505_read(it6505, INT_STATUS_01);
+	int_status[1] = it6505_read(it6505, INT_STATUS_02);
+	int_status[2] = it6505_read(it6505, INT_STATUS_03);
+
+	it6505_write(it6505, INT_STATUS_01, int_status[0]);
+	it6505_write(it6505, INT_STATUS_02, int_status[1]);
+	it6505_write(it6505, INT_STATUS_03, int_status[2]);
+
+	DRM_DEV_DEBUG_DRIVER(dev, "reg06 = 0x%02x", int_status[0]);
+	DRM_DEV_DEBUG_DRIVER(dev, "reg07 = 0x%02x", int_status[1]);
+	DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", int_status[2]);
+	it6505_debug_print(it6505, REG_SYSTEM_STS, "");
+
+	if (it6505_test_bit(irq_vec[0].bit, (unsigned int *)int_status))
+		irq_vec[0].handler(it6505);
+
+	if (!it6505->hpd_state)
+		goto unlock;
+
+	for (i = 1; i < ARRAY_SIZE(irq_vec); i++) {
+		if (it6505_test_bit(irq_vec[i].bit, (unsigned int *)int_status))
+			irq_vec[i].handler(it6505);
+	}
+
+unlock:
+	mutex_unlock(&it6505->extcon_lock);
+
+	return IRQ_HANDLED;
+}
+
+static int it6505_poweron(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	struct it6505_platform_data *pdata = &it6505->pdata;
+	int err;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "it6505 start powered on");
+
+	if (it6505->powered) {
+		DRM_DEV_DEBUG_DRIVER(dev, "it6505 already powered on");
+		return 0;
+	}
+
+	if (pdata->pwr18) {
+		err = regulator_enable(pdata->pwr18);
+		if (err) {
+			DRM_DEV_DEBUG_DRIVER(dev, "Failed to enable VDD18: %d",
+					     err);
+			return err;
+		}
+	}
+
+	if (pdata->ovdd) {
+		/* time interval between IVDD and OVDD at least be 1ms */
+		usleep_range(1000, 2000);
+		err = regulator_enable(pdata->ovdd);
+		if (err) {
+			regulator_disable(pdata->pwr18);
+			return err;
+		}
+	}
+	/* time interval between OVDD and SYSRSTN at least be 10ms */
+	if (pdata->gpiod_reset) {
+		usleep_range(10000, 20000);
+		gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
+		usleep_range(1000, 2000);
+		gpiod_set_value_cansleep(pdata->gpiod_reset, 1);
+		usleep_range(10000, 20000);
+	}
+
+	it6505_reset_logic(it6505);
+	it6505_int_mask_enable(it6505);
+	it6505_init(it6505);
+	it6505_lane_off(it6505);
+
+	it6505->powered = true;
+
+	return 0;
+}
+
+static int it6505_poweroff(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	struct it6505_platform_data *pdata = &it6505->pdata;
+	int err;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "it6505 start power off");
+
+	if (!it6505->powered) {
+		DRM_DEV_DEBUG_DRIVER(dev, "power had been already off");
+		return 0;
+	}
+
+	if (pdata->gpiod_reset)
+		gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
+
+	if (pdata->pwr18) {
+		err = regulator_disable(pdata->pwr18);
+		if (err)
+			return err;
+	}
+
+	if (pdata->ovdd) {
+		err = regulator_disable(pdata->ovdd);
+		if (err)
+			return err;
+	}
+
+	it6505->powered = false;
+	it6505->sink_count = 0;
+
+	return 0;
+}
+
+static enum drm_connector_status it6505_detect(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	enum drm_connector_status status = connector_status_disconnected;
+	int dp_sink_count;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count:%d powered:%d",
+			     it6505->sink_count, it6505->powered);
+
+	mutex_lock(&it6505->mode_lock);
+
+	if (!it6505->powered)
+		goto unlock;
+
+	if (it6505->enable_drv_hold) {
+		status = it6505_get_sink_hpd_status(it6505) ?
+					connector_status_connected :
+					connector_status_disconnected;
+		goto unlock;
+	}
+
+	if (it6505_get_sink_hpd_status(it6505)) {
+		it6505_aux_on(it6505);
+		it6505_drm_dp_link_probe(&it6505->aux, &it6505->link);
+		it6505_drm_dp_link_power_up(&it6505->aux, &it6505->link);
+		it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+
+		if (it6505->dpcd[0] == 0) {
+			it6505_get_dpcd(it6505, DP_DPCD_REV, it6505->dpcd,
+					ARRAY_SIZE(it6505->dpcd));
+			it6505_variable_config(it6505);
+			it6505_parse_link_capabilities(it6505);
+		}
+
+		dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT);
+		it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count);
+		DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count:%d branch:%d",
+				     it6505->sink_count, it6505->branch_device);
+
+		if (it6505->branch_device) {
+			status = (it6505->sink_count != 0) ?
+				 connector_status_connected :
+				 connector_status_disconnected;
+		} else {
+			status = connector_status_connected;
+		}
+	} else {
+		it6505->sink_count = 0;
+		memset(it6505->dpcd, 0, sizeof(it6505->dpcd));
+	}
+
+unlock:
+	if (it6505->connector_status != status) {
+		it6505->connector_status = status;
+		it6505_plugged_status_to_codec(it6505);
+	}
+
+	mutex_unlock(&it6505->mode_lock);
+
+	return status;
+}
+
+static int it6505_extcon_notifier(struct notifier_block *self,
+				  unsigned long event, void *ptr)
+{
+	struct it6505 *it6505 = container_of(self, struct it6505, event_nb);
+
+	schedule_work(&it6505->extcon_wq);
+	return NOTIFY_DONE;
+}
+
+static void it6505_extcon_work(struct work_struct *work)
+{
+	struct it6505 *it6505 = container_of(work, struct it6505, extcon_wq);
+	struct device *dev = &it6505->client->dev;
+	int state = extcon_get_state(it6505->extcon, EXTCON_DISP_DP);
+	unsigned int pwroffretry = 0;
+
+	if (it6505->enable_drv_hold)
+		return;
+
+	mutex_lock(&it6505->extcon_lock);
+
+	DRM_DEV_DEBUG_DRIVER(dev, "EXTCON_DISP_DP = 0x%02x", state);
+	if (state > 0) {
+		DRM_DEV_DEBUG_DRIVER(dev, "start to power on");
+		msleep(100);
+		it6505_poweron(it6505);
+	} else {
+		DRM_DEV_DEBUG_DRIVER(dev, "start to power off");
+		while (it6505_poweroff(it6505) && pwroffretry++ < 5) {
+			DRM_DEV_DEBUG_DRIVER(dev, "power off fail %d times",
+					     pwroffretry);
+		}
+
+		drm_helper_hpd_irq_event(it6505->bridge.dev);
+		memset(it6505->dpcd, 0, sizeof(it6505->dpcd));
+		DRM_DEV_DEBUG_DRIVER(dev, "power off it6505 success!");
+	}
+
+	mutex_unlock(&it6505->extcon_lock);
+}
+
+static int it6505_use_notifier_module(struct it6505 *it6505)
+{
+	int ret;
+	struct device *dev = &it6505->client->dev;
+
+	it6505->event_nb.notifier_call = it6505_extcon_notifier;
+	INIT_WORK(&it6505->extcon_wq, it6505_extcon_work);
+	ret = devm_extcon_register_notifier(&it6505->client->dev,
+					    it6505->extcon, EXTCON_DISP_DP,
+					    &it6505->event_nb);
+	if (ret) {
+		dev_err(dev, "failed to register notifier for DP");
+		return ret;
+	}
+
+	schedule_work(&it6505->extcon_wq);
+
+	return 0;
+}
+
+static void it6505_remove_notifier_module(struct it6505 *it6505)
+{
+	if (it6505->extcon) {
+		devm_extcon_unregister_notifier(&it6505->client->dev,
+						it6505->extcon,	EXTCON_DISP_DP,
+						&it6505->event_nb);
+
+		flush_work(&it6505->extcon_wq);
+	}
+}
+
+static void __maybe_unused it6505_delayed_audio(struct work_struct *work)
+{
+	struct it6505 *it6505 = container_of(work, struct it6505,
+					     delayed_audio.work);
+
+	DRM_DEV_DEBUG_DRIVER(&it6505->client->dev, "start");
+
+	if (!it6505->powered)
+		return;
+
+	if (!it6505->enable_drv_hold)
+		it6505_enable_audio(it6505);
+}
+
+static int __maybe_unused it6505_audio_setup_hw_params(struct it6505 *it6505,
+						       struct hdmi_codec_params
+						       *params)
+{
+	struct device *dev = &it6505->client->dev;
+	int i = 0;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "%s %d Hz, %d bit, %d channels\n", __func__,
+			     params->sample_rate, params->sample_width,
+			     params->cea.channels);
+
+	if (!it6505->bridge.encoder)
+		return -ENODEV;
+
+	if (params->cea.channels <= 1 || params->cea.channels > 8) {
+		DRM_DEV_DEBUG_DRIVER(dev, "channel number: %d not support",
+				     it6505->audio.channel_count);
+		return -EINVAL;
+	}
+
+	it6505->audio.channel_count = params->cea.channels;
+
+	while (i < ARRAY_SIZE(audio_sample_rate_map) &&
+	       params->sample_rate !=
+		       audio_sample_rate_map[i].sample_rate_value) {
+		i++;
+	}
+	if (i == ARRAY_SIZE(audio_sample_rate_map)) {
+		DRM_DEV_DEBUG_DRIVER(dev, "sample rate: %d Hz not support",
+				     params->sample_rate);
+		return -EINVAL;
+	}
+	it6505->audio.sample_rate = audio_sample_rate_map[i].rate;
+
+	switch (params->sample_width) {
+	case 16:
+		it6505->audio.word_length = WORD_LENGTH_16BIT;
+		break;
+	case 18:
+		it6505->audio.word_length = WORD_LENGTH_18BIT;
+		break;
+	case 20:
+		it6505->audio.word_length = WORD_LENGTH_20BIT;
+		break;
+	case 24:
+	case 32:
+		it6505->audio.word_length = WORD_LENGTH_24BIT;
+		break;
+	default:
+		DRM_DEV_DEBUG_DRIVER(dev, "wordlength: %d bit not support",
+				     params->sample_width);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void __maybe_unused it6505_audio_shutdown(struct device *dev, void *data)
+{
+	struct it6505 *it6505 = dev_get_drvdata(dev);
+
+	if (it6505->powered)
+		it6505_disable_audio(it6505);
+}
+
+static int __maybe_unused it6505_audio_hook_plugged_cb(struct device *dev,
+						       void *data,
+						       hdmi_codec_plugged_cb fn,
+						       struct device *codec_dev)
+{
+	struct it6505 *it6505 = data;
+
+	it6505->plugged_cb = fn;
+	it6505->codec_dev = codec_dev;
+	it6505_plugged_status_to_codec(it6505);
+
+	return 0;
+}
+
+static inline struct it6505 *bridge_to_it6505(struct drm_bridge *bridge)
+{
+	return container_of(bridge, struct it6505, bridge);
+}
+
+static int it6505_bridge_attach(struct drm_bridge *bridge,
+				enum drm_bridge_attach_flags flags)
+{
+	struct it6505 *it6505 = bridge_to_it6505(bridge);
+	struct device *dev = &it6505->client->dev;
+	int ret;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		DRM_ERROR("DRM_BRIDGE_ATTACH_NO_CONNECTOR must be supplied");
+		return -EINVAL;
+	}
+
+	if (!bridge->encoder) {
+		dev_err(dev, "Parent encoder object not found");
+		return -ENODEV;
+	}
+
+	if (it6505->extcon) {
+		ret = it6505_use_notifier_module(it6505);
+		if (ret < 0) {
+			dev_err(dev, "use notifier module failed");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void it6505_bridge_detach(struct drm_bridge *bridge)
+{
+	struct it6505 *it6505 = bridge_to_it6505(bridge);
+
+	flush_work(&it6505->link_works);
+	it6505_remove_notifier_module(it6505);
+}
+
+static enum drm_mode_status
+it6505_bridge_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode)
+{
+	struct it6505 *it6505 = bridge_to_it6505(bridge);
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_NO_INTERLACE;
+
+	if (mode->clock > DPI_PIXEL_CLK_MAX)
+		return MODE_CLOCK_HIGH;
+
+	it6505->video_info.clock = mode->clock;
+
+	return MODE_OK;
+}
+
+static void it6505_bridge_atomic_enable(struct drm_bridge *bridge,
+					struct drm_bridge_state *old_state)
+{
+	struct it6505 *it6505 = bridge_to_it6505(bridge);
+	struct device *dev = &it6505->client->dev;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct hdmi_avi_infoframe frame;
+	const struct drm_crtc_state *crtc_state;
+	const struct drm_display_mode *mode;
+	struct drm_connector *connector;
+	int ret;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "start");
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     bridge->encoder);
+
+	crtc_state = drm_bridge_new_crtc_state(bridge, old_state);
+	mode = &crtc_state->mode;
+	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
+						       connector,
+						       mode);
+	if (ret)
+		dev_err(dev, "Failed to setup AVI infoframe: %d", ret);
+
+	it6505_update_video_parameter(it6505, mode);
+
+	ret = it6505_send_video_infoframe(it6505, &frame);
+
+	if (ret)
+		dev_err(dev, "Failed to send AVI infoframe: %d", ret);
+
+	it6505_int_mask_enable(it6505);
+	it6505_video_reset(it6505);
+}
+
+static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
+					 struct drm_bridge_state *old_state)
+{
+	struct it6505 *it6505 = bridge_to_it6505(bridge);
+	struct device *dev = &it6505->client->dev;
+
+	DRM_DEV_DEBUG_DRIVER(dev, "start");
+
+	if (it6505->powered)
+		it6505_video_disable(it6505);
+}
+
+static enum drm_connector_status
+it6505_bridge_detect(struct drm_bridge *bridge)
+{
+	struct it6505 *it6505 = bridge_to_it6505(bridge);
+
+	return it6505_detect(it6505);
+}
+
+static struct edid *it6505_bridge_get_edid(struct drm_bridge *bridge,
+					   struct drm_connector *connector)
+{
+	struct it6505 *it6505 = bridge_to_it6505(bridge);
+	struct device *dev = &it6505->client->dev;
+	struct edid *edid;
+
+	edid = drm_do_get_edid(connector, it6505_get_edid_block, it6505);
+
+	if (!edid) {
+		DRM_DEV_DEBUG_DRIVER(dev, "failed to get edid!");
+		return NULL;
+	}
+
+	return edid;
+}
+
+static const struct drm_bridge_funcs it6505_bridge_funcs = {
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.attach = it6505_bridge_attach,
+	.detach = it6505_bridge_detach,
+	.mode_valid = it6505_bridge_mode_valid,
+	.atomic_enable = it6505_bridge_atomic_enable,
+	.atomic_disable = it6505_bridge_atomic_disable,
+	.detect = it6505_bridge_detect,
+	.get_edid = it6505_bridge_get_edid,
+};
+
+static __maybe_unused int it6505_bridge_resume(struct device *dev)
+{
+	struct it6505 *it6505 = dev_get_drvdata(dev);
+
+	return it6505_poweron(it6505);
+}
+
+static __maybe_unused int it6505_bridge_suspend(struct device *dev)
+{
+	struct it6505 *it6505 = dev_get_drvdata(dev);
+
+	return it6505_poweroff(it6505);
+}
+
+static SIMPLE_DEV_PM_OPS(it6505_bridge_pm_ops, it6505_bridge_suspend,
+			 it6505_bridge_resume);
+
+static int it6505_init_pdata(struct it6505 *it6505)
+{
+	struct it6505_platform_data *pdata = &it6505->pdata;
+	struct device *dev = &it6505->client->dev;
+
+	/* 1.0V digital core power regulator  */
+	pdata->pwr18 = devm_regulator_get(dev, "pwr18");
+	if (IS_ERR(pdata->pwr18)) {
+		dev_err(dev, "pwr18 regulator not found");
+		return PTR_ERR(pdata->pwr18);
+	}
+
+	pdata->ovdd = devm_regulator_get(dev, "ovdd");
+	if (IS_ERR(pdata->ovdd)) {
+		dev_err(dev, "ovdd regulator not found");
+		return PTR_ERR(pdata->ovdd);
+	}
+
+	pdata->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(pdata->gpiod_reset)) {
+		dev_err(dev, "gpiod_reset gpio not found");
+		return PTR_ERR(pdata->gpiod_reset);
+	}
+
+	return 0;
+}
+
+static void it6505_parse_dt(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+	u32 *afe_setting = &it6505->afe_setting;
+
+	it6505->lane_swap_disabled =
+		device_property_read_bool(dev, "no-laneswap");
+
+	if (it6505->lane_swap_disabled)
+		it6505->lane_swap = false;
+
+	if (device_property_read_u32(dev, "afe-setting", afe_setting) == 0) {
+		if (*afe_setting >= ARRAY_SIZE(afe_setting_table)) {
+			dev_err(dev, "afe setting error, use default");
+			*afe_setting = 0;
+		}
+	} else {
+		*afe_setting = 0;
+	}
+	DRM_DEV_DEBUG_DRIVER(dev, "using afe_setting: %d", *afe_setting);
+}
+
+static ssize_t receive_timing_debugfs_show(struct file *file, char __user *buf,
+					   size_t len, loff_t *ppos)
+{
+	struct it6505 *it6505 = file->private_data;
+	struct drm_display_mode *vid = &it6505->video_info;
+	u8 read_buf[READ_BUFFER_SIZE];
+	u8 *str = read_buf, *end = read_buf + PAGE_SIZE;
+	ssize_t ret, count;
+
+	if (!it6505)
+		return -ENODEV;
+
+	it6505_calc_video_info(it6505);
+	str += scnprintf(str, end - str, "---video timing---\n");
+	str += scnprintf(str, end - str, "PCLK:%d.%03dMHz\n",
+			 vid->clock / 1000, vid->clock % 1000);
+	str += scnprintf(str, end - str, "HTotal:%d\n", vid->htotal);
+	str += scnprintf(str, end - str, "HActive:%d\n", vid->hdisplay);
+	str += scnprintf(str, end - str, "HFrontPorch:%d\n",
+			 vid->hsync_start - vid->hdisplay);
+	str += scnprintf(str, end - str, "HSyncWidth:%d\n",
+			 vid->hsync_end - vid->hsync_start);
+	str += scnprintf(str, end - str, "HBackPorch:%d\n",
+			 vid->htotal - vid->hsync_end);
+	str += scnprintf(str, end - str, "VTotal:%d\n", vid->vtotal);
+	str += scnprintf(str, end - str, "VActive:%d\n", vid->vdisplay);
+	str += scnprintf(str, end - str, "VFrontPorch:%d\n",
+			 vid->vsync_start - vid->vdisplay);
+	str += scnprintf(str, end - str, "VSyncWidth:%d\n",
+			 vid->vsync_end - vid->vsync_start);
+	str += scnprintf(str, end - str, "VBackPorch:%d\n",
+			 vid->vtotal - vid->vsync_end);
+
+	count = str - read_buf;
+	ret = simple_read_from_buffer(buf, len, ppos, read_buf, count);
+
+	return ret;
+}
+
+static int force_power_on_off_debugfs_write(void *data, u64 value)
+{
+	struct it6505 *it6505 = data;
+
+	if (!it6505)
+		return -ENODEV;
+
+	if (value)
+		it6505_poweron(it6505);
+	else
+		it6505_poweroff(it6505);
+
+	return 0;
+}
+
+static int enable_drv_hold_debugfs_show(void *data, u64 *buf)
+{
+	struct it6505 *it6505 = data;
+
+	if (!it6505)
+		return -ENODEV;
+
+	*buf = it6505->enable_drv_hold;
+
+	return 0;
+}
+
+static int enable_drv_hold_debugfs_write(void *data, u64 drv_hold)
+{
+	struct it6505 *it6505 = data;
+
+	if (!it6505)
+		return -ENODEV;
+
+	it6505->enable_drv_hold = drv_hold;
+
+	if (it6505->enable_drv_hold) {
+		it6505_int_mask_disable(it6505);
+	} else {
+		it6505_clear_int(it6505);
+		it6505_int_mask_enable(it6505);
+
+		if (it6505->powered) {
+			it6505->connector_status =
+					it6505_get_sink_hpd_status(it6505) ?
+					connector_status_connected :
+					connector_status_disconnected;
+		} else {
+			it6505->connector_status =
+					connector_status_disconnected;
+		}
+	}
+
+	return 0;
+}
+
+static const struct file_operations receive_timing_fops = {
+	.owner = THIS_MODULE,
+	.open = simple_open,
+	.read = receive_timing_debugfs_show,
+	.llseek = default_llseek,
+};
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_force_power, NULL,
+			 force_power_on_off_debugfs_write, "%llu\n");
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_enable_drv_hold, enable_drv_hold_debugfs_show,
+			 enable_drv_hold_debugfs_write, "%llu\n");
+
+static const struct debugfs_entries debugfs_entry[] = {
+	{ "receive_timing", &receive_timing_fops },
+	{ "force_power_on_off", &fops_force_power },
+	{ "enable_drv_hold", &fops_enable_drv_hold },
+	{ NULL, NULL },
+};
+
+static void debugfs_create_files(struct it6505 *it6505)
+{
+	int i = 0;
+
+	while (debugfs_entry[i].name && debugfs_entry[i].fops) {
+		debugfs_create_file(debugfs_entry[i].name, 0644,
+				    it6505->debugfs, it6505,
+				    debugfs_entry[i].fops);
+		i++;
+	}
+}
+
+static void debugfs_init(struct it6505 *it6505)
+{
+	struct device *dev = &it6505->client->dev;
+
+	it6505->debugfs = debugfs_create_dir(DEBUGFS_DIR_NAME, NULL);
+
+	if (IS_ERR(it6505->debugfs)) {
+		dev_err(dev, "failed to create debugfs root");
+		return;
+	}
+
+	debugfs_create_files(it6505);
+}
+
+static void it6505_debugfs_remove(struct it6505 *it6505)
+{
+	debugfs_remove_recursive(it6505->debugfs);
+}
+
+static void it6505_shutdown(struct i2c_client *client)
+{
+	struct it6505 *it6505 = dev_get_drvdata(&client->dev);
+
+	if (it6505->powered)
+		it6505_lane_off(it6505);
+}
+
+static int it6505_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct it6505 *it6505;
+	struct device *dev = &client->dev;
+	struct extcon_dev *extcon;
+	int err, intp_irq;
+
+	it6505 = devm_kzalloc(&client->dev, sizeof(*it6505), GFP_KERNEL);
+	if (!it6505)
+		return -ENOMEM;
+
+	mutex_init(&it6505->extcon_lock);
+	mutex_init(&it6505->mode_lock);
+	mutex_init(&it6505->aux_lock);
+
+	it6505->bridge.of_node = client->dev.of_node;
+	it6505->connector_status = connector_status_disconnected;
+	it6505->client = client;
+	i2c_set_clientdata(client, it6505);
+
+	/* get extcon device from DTS */
+	extcon = extcon_get_edev_by_phandle(dev, 0);
+	if (PTR_ERR(extcon) == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+	if (IS_ERR(extcon)) {
+		dev_err(dev, "can not get extcon device!");
+		return PTR_ERR(extcon);
+	}
+
+	it6505->extcon = extcon;
+
+	it6505->regmap = devm_regmap_init_i2c(client, &it6505_regmap_config);
+	if (IS_ERR(it6505->regmap)) {
+		dev_err(dev, "regmap i2c init failed");
+		err = PTR_ERR(it6505->regmap);
+		return err;
+	}
+
+	err = it6505_init_pdata(it6505);
+	if (err) {
+		dev_err(dev, "Failed to initialize pdata: %d", err);
+		return err;
+	}
+
+	it6505_parse_dt(it6505);
+
+	intp_irq = client->irq;
+
+	if (!intp_irq) {
+		dev_err(dev, "Failed to get INTP IRQ");
+		err = -ENODEV;
+		return err;
+	}
+
+	err = devm_request_threaded_irq(&client->dev, intp_irq, NULL,
+					it6505_int_threaded_handler,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					"it6505-intp", it6505);
+	if (err) {
+		dev_err(dev, "Failed to request INTP threaded IRQ: %d", err);
+		return err;
+	}
+
+	/* Register aux channel */
+	it6505->aux.name = "DP-AUX";
+	it6505->aux.dev = dev;
+	it6505->aux.transfer = it6505_aux_transfer;
+
+	err = drm_dp_aux_register(&it6505->aux);
+	if (err < 0) {
+		dev_err(dev, "Failed to register aux: %d", err);
+		return err;
+	}
+
+	INIT_WORK(&it6505->link_works, it6505_link_training_work);
+	INIT_WORK(&it6505->hdcp_wait_ksv_list, it6505_hdcp_wait_ksv_list);
+	INIT_DELAYED_WORK(&it6505->hdcp_work, it6505_hdcp_work);
+	init_completion(&it6505->wait_edid_complete);
+	memset(it6505->dpcd, 0, sizeof(it6505->dpcd));
+	it6505->powered = false;
+	it6505->enable_drv_hold = DEFAULT_DRV_HOLD;
+
+	if (DEFAULT_PWR_ON)
+		it6505_poweron(it6505);
+
+	DRM_DEV_DEBUG_DRIVER(dev, "it6505 device name: %s", dev_name(dev));
+	debugfs_init(it6505);
+
+	it6505->bridge.funcs = &it6505_bridge_funcs;
+	it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
+	it6505->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+			     DRM_BRIDGE_OP_HPD;
+	drm_bridge_add(&it6505->bridge);
+
+	return 0;
+}
+
+static int it6505_i2c_remove(struct i2c_client *client)
+{
+	struct it6505 *it6505 = i2c_get_clientdata(client);
+
+	drm_bridge_remove(&it6505->bridge);
+	drm_dp_aux_unregister(&it6505->aux);
+	it6505_debugfs_remove(it6505);
+	it6505_poweroff(it6505);
+
+	return 0;
+}
+
+static const struct i2c_device_id it6505_id[] = {
+	{ "it6505", 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, it6505_id);
+
+static const struct of_device_id it6505_of_match[] = {
+	{ .compatible = "ite,it6505" },
+	{ }
+};
+
+static struct i2c_driver it6505_i2c_driver = {
+	.driver = {
+		.name = "it6505",
+		.of_match_table = it6505_of_match,
+		.pm = &it6505_bridge_pm_ops,
+	},
+	.probe = it6505_i2c_probe,
+	.remove = it6505_i2c_remove,
+	.shutdown = it6505_shutdown,
+	.id_table = it6505_id,
+};
+
+module_i2c_driver(it6505_i2c_driver);
+
+MODULE_AUTHOR("Allen Chen <allen.chen at ite.com.tw>");
+MODULE_DESCRIPTION("IT6505 DisplayPort Transmitter driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From hsinyi at chromium.org  Tue Aug 10 04:38:30 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Tue, 10 Aug 2021 19:38:30 +0800
Subject: [PATCH v8] drm/bridge: add it6505 driver
In-Reply-To: <20210810111124.247838-1-allen.chen@ite.com.tw>
References: <20210810111124.247838-1-allen.chen@ite.com.tw>
Message-ID: <CAJMQK-g9=7o750t4ZAyND7nqrRvx=tMqUs+-=1--M1CqGXvAdw@mail.gmail.com>

On Tue, Aug 10, 2021 at 7:31 PM allen <allen.chen at ite.com.tw> wrote:
>
> This adds support for the iTE IT6505.
> This device can convert DPI signal to DP output.
>
> From: Allen Chen <allen.chen at ite.com.tw>
> Tested-by: Hsin-yi Wang <hsinyi at chromium.org>
> Signed-off-by: Hermes Wu <hermes.wu at ite.com.tw>
> Signed-off-by: Allen Chen <allen.chen at ite.com.tw>
>
---  <-- Add this line next time.
Add the change logs below this line so that they're not mixed with
commit messages.

> v7->v8:
> fixed "checkpatch --strict" error
> remove unused variable *edid
> remove mode_set() callback
> Documenting the individual bits of the interrupt mask values
> change it6505_dpcd_write parameter from unsigned long to u8
>
> This patch depends on https://patchwork.kernel.org/project/linux-mediatek/patch/20210722062246.2512666-4-sam at ravnborg.org/
> ---
>  drivers/gpu/drm/bridge/Kconfig      |    8 +
>  drivers/gpu/drm/bridge/Makefile     |    1 +
>  drivers/gpu/drm/bridge/ite-it6505.c | 3333 +++++++++++++++++++++++++++
>  3 files changed, 3342 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/ite-it6505.c
>
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index 431b6e12a81fe..e1afe171075f5 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -74,6 +74,14 @@ config DRM_DISPLAY_CONNECTOR
>           on ARM-based platforms. Saying Y here when this driver is not needed
>           will not cause any issue.
>
<snip>

> +
> +       /* Register aux channel */
> +       it6505->aux.name = "DP-AUX";
> +       it6505->aux.dev = dev;
> +       it6505->aux.transfer = it6505_aux_transfer;
> +
> +       err = drm_dp_aux_register(&it6505->aux);

drm_dp_aux_register() checks if aux->drm_dev is null. Assign this
otherwise you'll see warnings.

> +       if (err < 0) {
> +               dev_err(dev, "Failed to register aux: %d", err);
> +               return err;
> +       }
<snip>


From vladimir.oltean at nxp.com  Tue Aug 10 04:50:24 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Tue, 10 Aug 2021 14:50:24 +0300
Subject: [PATCH v2 net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
Message-ID: <20210810115024.1629983-1-vladimir.oltean@nxp.com>

The blamed commit a new field to struct switchdev_notifier_fdb_info, but
did not make sure that all call paths set it to something valid. For
example, a switchdev driver may emit a SWITCHDEV_FDB_ADD_TO_BRIDGE
notifier, and since the 'is_local' flag is not set, it contains junk
from the stack, so the bridge might interpret those notifications as
being for local FDB entries when that was not intended.

To avoid that now and in the future, zero-initialize all
switchdev_notifier_fdb_info structures created by drivers such that all
newly added fields to not need to touch drivers again.

Fixes: 2c4eca3ef716 ("net: bridge: switchdev: include local flag in FDB notifications")
Reported-by: Ido Schimmel <idosch at idosch.org>
Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Reviewed-by: Ido Schimmel <idosch at nvidia.com>
Tested-by: Ido Schimmel <idosch at nvidia.com>
---
v1->v2: use an empty struct initializer as opposed to memset, as
        suggested by Leon Romanovsky

 drivers/net/ethernet/marvell/prestera/prestera_switchdev.c | 4 ++--
 drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c       | 2 +-
 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c      | 4 ++--
 drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 2 +-
 drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c    | 2 +-
 drivers/net/ethernet/rocker/rocker_main.c                  | 2 +-
 drivers/net/ethernet/rocker/rocker_ofdpa.c                 | 2 +-
 drivers/net/ethernet/ti/am65-cpsw-switchdev.c              | 2 +-
 drivers/net/ethernet/ti/cpsw_switchdev.c                   | 2 +-
 drivers/s390/net/qeth_l2_main.c                            | 4 ++--
 net/dsa/slave.c                                            | 2 +-
 11 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
index 0b3e8f2db294..9a309169dbae 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c
@@ -748,7 +748,7 @@ static void
 prestera_fdb_offload_notify(struct prestera_port *port,
 			    struct switchdev_notifier_fdb_info *info)
 {
-	struct switchdev_notifier_fdb_info send_info;
+	struct switchdev_notifier_fdb_info send_info = {};
 
 	send_info.addr = info->addr;
 	send_info.vid = info->vid;
@@ -1123,7 +1123,7 @@ static int prestera_switchdev_blk_event(struct notifier_block *unused,
 static void prestera_fdb_event(struct prestera_switch *sw,
 			       struct prestera_event *evt, void *arg)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 	struct net_device *dev = NULL;
 	struct prestera_port *port;
 	struct prestera_lag *lag;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
index f3f56f32e435..69a3630818d7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
@@ -69,7 +69,7 @@ static void
 mlx5_esw_bridge_fdb_offload_notify(struct net_device *dev, const unsigned char *addr, u16 vid,
 				   unsigned long val)
 {
-	struct switchdev_notifier_fdb_info send_info;
+	struct switchdev_notifier_fdb_info send_info = {};
 
 	send_info.addr = addr;
 	send_info.vid = vid;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 7e221ef01437..f69cbb3852d5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -9079,7 +9079,7 @@ mlxsw_sp_rif_fid_fid_get(struct mlxsw_sp_rif *rif,
 
 static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 	struct net_device *dev;
 
 	dev = br_fdb_find_port(rif->dev, mac, 0);
@@ -9127,8 +9127,8 @@ mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif,
 
 static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
 {
+	struct switchdev_notifier_fdb_info info = {};
 	u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid);
-	struct switchdev_notifier_fdb_info info;
 	struct net_device *br_dev;
 	struct net_device *dev;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index c5ef9aa64efe..8f90cd323d5f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -2508,7 +2508,7 @@ mlxsw_sp_fdb_call_notifiers(enum switchdev_notifier_type type,
 			    const char *mac, u16 vid,
 			    struct net_device *dev, bool offloaded)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 
 	info.addr = mac;
 	info.vid = vid;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
index 0443f66b5550..9a8e4f201eb1 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
@@ -277,7 +277,7 @@ static void sparx5_fdb_call_notifiers(enum switchdev_notifier_type type,
 				      const char *mac, u16 vid,
 				      struct net_device *dev, bool offloaded)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 
 	info.addr = mac;
 	info.vid = vid;
diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c
index a46633606cae..1f06b92ee5bb 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2715,7 +2715,7 @@ static void
 rocker_fdb_offload_notify(struct rocker_port *rocker_port,
 			  struct switchdev_notifier_fdb_info *recv_info)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 
 	info.addr = recv_info->addr;
 	info.vid = recv_info->vid;
diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c
index 967a634ee9ac..e33a9d283a4e 100644
--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
+++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
@@ -1822,7 +1822,7 @@ static void ofdpa_port_fdb_learn_work(struct work_struct *work)
 		container_of(work, struct ofdpa_fdb_learn_work, work);
 	bool removing = (lw->flags & OFDPA_OP_FLAG_REMOVE);
 	bool learned = (lw->flags & OFDPA_OP_FLAG_LEARNED);
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 
 	info.addr = lw->addr;
 	info.vid = lw->vid;
diff --git a/drivers/net/ethernet/ti/am65-cpsw-switchdev.c b/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
index 9c29b363e9ae..599708a3e81d 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-switchdev.c
@@ -358,7 +358,7 @@ static int am65_cpsw_port_obj_del(struct net_device *ndev, const void *ctx,
 static void am65_cpsw_fdb_offload_notify(struct net_device *ndev,
 					 struct switchdev_notifier_fdb_info *rcv)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 
 	info.addr = rcv->addr;
 	info.vid = rcv->vid;
diff --git a/drivers/net/ethernet/ti/cpsw_switchdev.c b/drivers/net/ethernet/ti/cpsw_switchdev.c
index f7fb6e17dadd..a7d97d429e06 100644
--- a/drivers/net/ethernet/ti/cpsw_switchdev.c
+++ b/drivers/net/ethernet/ti/cpsw_switchdev.c
@@ -368,7 +368,7 @@ static int cpsw_port_obj_del(struct net_device *ndev, const void *ctx,
 static void cpsw_fdb_offload_notify(struct net_device *ndev,
 				    struct switchdev_notifier_fdb_info *rcv)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 
 	info.addr = rcv->addr;
 	info.vid = rcv->vid;
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 2abf86c104d5..d7cdd9cfe485 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -279,7 +279,7 @@ static void qeth_l2_set_pnso_mode(struct qeth_card *card,
 
 static void qeth_l2_dev2br_fdb_flush(struct qeth_card *card)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 
 	QETH_CARD_TEXT(card, 2, "fdbflush");
 
@@ -679,7 +679,7 @@ static void qeth_l2_dev2br_fdb_notify(struct qeth_card *card, u8 code,
 				      struct net_if_token *token,
 				      struct mac_addr_lnid *addr_lnid)
 {
-	struct switchdev_notifier_fdb_info info;
+	struct switchdev_notifier_fdb_info info = {};
 	u8 ntfy_mac[ETH_ALEN];
 
 	ether_addr_copy(ntfy_mac, addr_lnid->mac);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 532085da8d8f..23be8e01026b 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2291,8 +2291,8 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb,
 static void
 dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work)
 {
+	struct switchdev_notifier_fdb_info info = {};
 	struct dsa_switch *ds = switchdev_work->ds;
-	struct switchdev_notifier_fdb_info info;
 	struct dsa_port *dp;
 
 	if (!dsa_is_user_port(ds, switchdev_work->port))
-- 
2.25.1



From maz at kernel.org  Tue Aug 10 05:30:51 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 13:30:51 +0100
Subject: [PATCH v6 00/21] KVM: Add idempotent controls for migrating
 system counter state
In-Reply-To: <CAOQ_QsgkB32rgfr7=X8XNyXe2Vw3arFjo6umvgDfTLQgjU4i2A@mail.gmail.com>
References: <20210804085819.846610-1-oupton@google.com>
 <CAOQ_QsiVNS==c-ahnKN6Jja_+FfkWEmDnQPoP9sdNWBc1m2gsg@mail.gmail.com>
 <CAOQ_Qsh9wzP301xdfbwBcFXHBoYkf9PCY-+mrfmfwVWL4UexGw@mail.gmail.com>
 <CAOQ_QsgkB32rgfr7=X8XNyXe2Vw3arFjo6umvgDfTLQgjU4i2A@mail.gmail.com>
Message-ID: <877dgtbhxg.wl-maz@kernel.org>

On Tue, 10 Aug 2021 01:04:38 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Wed, Aug 4, 2021 at 3:03 PM Oliver Upton <oupton at google.com> wrote:
> >
> > On Wed, Aug 4, 2021 at 4:05 AM Oliver Upton <oupton at google.com> wrote:
> > >
> > > On Wed, Aug 4, 2021 at 1:58 AM Oliver Upton <oupton at google.com> wrote:
> > > >
> > > > KVM's current means of saving/restoring system counters is plagued with
> > > > temporal issues. At least on ARM64 and x86, we migrate the guest's
> > > > system counter by-value through the respective guest system register
> > > > values (cntvct_el0, ia32_tsc). Restoring system counters by-value is
> > > > brittle as the state is not idempotent: the host system counter is still
> > > > oscillating between the attempted save and restore. Furthermore, VMMs
> > > > may wish to transparently live migrate guest VMs, meaning that they
> > > > include the elapsed time due to live migration blackout in the guest
> > > > system counter view. The VMM thread could be preempted for any number of
> > > > reasons (scheduler, L0 hypervisor under nested) between the time that
> > > > it calculates the desired guest counter value and when KVM actually sets
> > > > this counter state.
> > > >
> > > > Despite the value-based interface that we present to userspace, KVM
> > > > actually has idempotent guest controls by way of system counter offsets.
> > > > We can avoid all of the issues associated with a value-based interface
> > > > by abstracting these offset controls in new ioctls. This series
> > > > introduces new vCPU device attributes to provide userspace access to the
> > > > vCPU's system counter offset.
> > > >
> > > > Patch 1 addresses a possible race in KVM_GET_CLOCK where
> > > > use_master_clock is read outside of the pvclock_gtod_sync_lock.
> > > >
> > > > Patch 2 adopts Paolo's suggestion, augmenting the KVM_{GET,SET}_CLOCK
> > > > ioctls to provide userspace with a (host_tsc, realtime) instant. This is
> > > > essential for a VMM to perform precise migration of the guest's system
> > > > counters.
> > > >
> > > > Patches 3-4 are some preparatory changes for exposing the TSC offset to
> > > > userspace. Patch 5 provides a vCPU attribute to provide userspace access
> > > > to the TSC offset.
> > > >
> > > > Patches 6-7 implement a test for the new additions to
> > > > KVM_{GET,SET}_CLOCK.
> > > >
> > > > Patch 8 fixes some assertions in the kvm device attribute helpers.
> > > >
> > > > Patches 9-10 implement at test for the tsc offset attribute introduced in
> > > > patch 5.
> 
> Paolo,
> 
> Is there anything else you're waiting to see for the x86 portion of
> this series after addressing Sean's comments? There's some work
> remaining on the arm64 side, though I believe the two architectures
> are now disjoint for this series.

I think at this stage it would make sense to split the series in two
and drive them independently.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Tue Aug 10 05:33:21 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 13:33:21 +0100
Subject: [PATCH v2 2/3] PCI: j721e: Add PCI legacy interrupt support for
 J721E
In-Reply-To: <7646c75e-29de-1edc-225c-57feeaa80118@ti.com>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-3-kishon@ti.com>
 <87h7g5w8d8.wl-maz@kernel.org>
 <c20be7ae-e4a7-c3ba-f1c9-e4ff2aae0a66@ti.com>
 <87o8a7arew.wl-maz@kernel.org>
 <7646c75e-29de-1edc-225c-57feeaa80118@ti.com>
Message-ID: <875ywdbhta.wl-maz@kernel.org>

On Mon, 09 Aug 2021 15:58:38 +0100,
Kishon Vijay Abraham I <kishon at ti.com> wrote:
> 
> Hi Marc,
> 
> On 09/08/21 3:09 pm, Marc Zyngier wrote:
> > On Mon, 09 Aug 2021 05:50:10 +0100,
> > Kishon Vijay Abraham I <kishon at ti.com> wrote:
> >>
> >> Hi Marc,
> >>
> >> On 04/08/21 8:43 pm, Marc Zyngier wrote:
> >>> On Wed, 04 Aug 2021 14:29:11 +0100,
> >>> Kishon Vijay Abraham I <kishon at ti.com> wrote:
> >>>>
> >>>> Add PCI legacy interrupt support for J721E. J721E has a single HW
> >>>> interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
> >>>> The HW interrupt line connected to GIC is a pulse interrupt whereas
> >>>> the legacy interrupts by definition is level interrupt. In order to
> >>>> provide level interrupt functionality to edge interrupt line, PCIe
> >>>> in J721E has provided IRQ_EOI register.
> >>>>
> >>>> However due to Errata ID #i2094 ([1]), EOI feature is not enabled in HW
> >>>> and only a single pulse interrupt will be generated for every
> >>>> ASSERT_INTx/DEASSERT_INTx.
> >>>
> >>> So my earlier remark stands. If you get a single edge, how do you
> >>> handle a level that is still high after having handled the interrupt
> >>> on hardware that has this bug?
> >>
> >> Right, this hardware (J721E) has a bug but was fixed in J7200 (Patch 3/3
> >> handles that).
> > 
> > But how do you make it work with J721E? Is it even worth supporting if
> > (as I expect) it is unreliable?
> 
> I've seen at-least the NVMe devices triggers the interrupts again and
> the data transfer completes. But I agree, this is unreliable.

Then I don't think you should add INTx support for this system. It is
bound to be a support burden, and will reflect badly on the whole
platform. Focusing on J7200 is probably the best thing to do.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From mark.rutland at arm.com  Tue Aug 10 05:34:07 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Aug 2021 13:34:07 +0100
Subject: [PATCH 08/13] clocksource/arm_arch_timer: Work around broken
 CVAL implementations
In-Reply-To: <20210809152651.2297337-9-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-9-maz@kernel.org>
Message-ID: <20210810123407.GB52842@C02TD0UTHF1T.local>

On Mon, Aug 09, 2021 at 04:26:46PM +0100, Marc Zyngier wrote:
> The Applied Micro XGene-1 SoC has a busted implementation of the
> CVAL register: it looks like it is based on TVAL instead of the
> other way around. The net effect of this implementation blunder
> is that the maximum deadline you can program in the timer is
> 32bit wide.
> 
> Detect the problematic case and limit the timer to 32bit deltas.
> Note that we don't tie this bug to XGene specifically, as it may
> also catch similar defects on other high-quality implementations.

Do we know of any other implementations that have a similar bug?

> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  drivers/clocksource/arm_arch_timer.c | 38 +++++++++++++++++++++++++++-
>  1 file changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 895844c33351..1c596cd3cc5c 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -778,9 +778,42 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
>  	return 0;
>  }
>  
> +static u64 __arch_timer_check_delta(void)
> +{
> +#ifdef CONFIG_ARM64
> +	u64 tmp;
> +
> +	/*
> +	 * XGene-1 implements CVAL in terms of TVAL, meaning that the
> +	 * maximum timer range is 32bit. Shame on them. Detect the
> +	 * issue by setting a timer to now+(1<<32), which will
> +	 * immediately fire on the duff CPU.
> +	 */
> +	write_sysreg(0, cntv_ctl_el0);
> +	isb();
> +	tmp = read_sysreg(cntvct_el0) | BIT(32);
> +	write_sysreg(tmp, cntv_cval_el0);

This will fire on legitimate implementations fairly often. Consider if
we enter this function at a time where CNTCVT_EL0[32] == 1, where:

* At 100MHz, bit 32 flips every ~42.95
* At 200MHz, bit 32 flips every ~21.47
* At 1GHz, bit 32 flips every ~4.29s

... and ThunderX2 has a 200MHz frequency today, with SBSA recommending
100MHz.

What does XGene-1 return upon a read of CVAL? If it always returns 0 for
the high bits, we could do a timing-insensitive check for truncation of
CVAL, e.g.

| 	/* CVAL must be at least 56 bits wide, as with CNT */
| 	u64 mask = GENMASK(55, 0);
| 	u64 val;
| 
| 	write_sysreg(mask, cntv_cval_el0);
| 	val = read_sysread(cnt_cval_el0);
| 
| 	if (val != mask) {
| 		/* What a great CPU */
| 	}

Thanks,
Mark.

> +	write_sysreg(ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK,
> +		     cntv_ctl_el0);
> +	isb();
> +
> +	tmp = read_sysreg(cntv_ctl_el0);
> +	write_sysreg(0, cntv_ctl_el0);
> +	isb();
> +
> +	if (tmp & ARCH_TIMER_CTRL_IT_STAT) {
> +		pr_warn_once("Detected broken implementation, limiting width to 32bits");
> +		return CLOCKSOURCE_MASK(32);
> +	}
> +#endif
> +	return CLOCKSOURCE_MASK(56);
> +}
> +
>  static void __arch_timer_setup(unsigned type,
>  			       struct clock_event_device *clk)
>  {
> +	u64 max_delta;
> +
>  	clk->features = CLOCK_EVT_FEAT_ONESHOT;
>  
>  	if (type == ARCH_TIMER_TYPE_CP15) {
> @@ -812,6 +845,7 @@ static void __arch_timer_setup(unsigned type,
>  		}
>  
>  		clk->set_next_event = sne;
> +		max_delta = __arch_timer_check_delta();
>  	} else {
>  		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
>  		clk->name = "arch_mem_timer";
> @@ -828,11 +862,13 @@ static void __arch_timer_setup(unsigned type,
>  			clk->set_next_event =
>  				arch_timer_set_next_event_phys_mem;
>  		}
> +
> +		max_delta = CLOCKSOURCE_MASK(56);
>  	}
>  
>  	clk->set_state_shutdown(clk);
>  
> -	clockevents_config_and_register(clk, arch_timer_rate, 0xf, CLOCKSOURCE_MASK(56));
> +	clockevents_config_and_register(clk, arch_timer_rate, 0xf, max_delta);
>  }
>  
>  static void arch_timer_evtstrm_enable(int divider)
> -- 
> 2.30.2
> 


From qperret at google.com  Tue Aug 10 05:35:39 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Aug 2021 13:35:39 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <cover.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <YRJym+Vn4bbwQzzs@google.com>

On Tuesday 10 Aug 2021 at 13:06:47 (+0530), Viresh Kumar wrote:
> Provide a cpufreq driver flag so drivers can ask the cpufreq core to register
> with the EM core on their behalf.

Hmm, that's not quite what this does. This asks the cpufreq core to
use *PM_OPP* to register an EM, which I think is kinda wrong to do from
there IMO. The decision to use PM_OPP or another mechanism to register
an EM belongs to platform specific code (drivers), so it is odd for the
PM_OPP registration to have its own cpufreq flag but not the other ways.

As mentioned in another thread, the very reason to have PM_EM is to not
depend on PM_OPP, so I'm worried about the direction of travel with this
series TBH.

> This allows us to get rid of duplicated code
> in the drivers and fix the unregistration part as well, which none of the
> drivers have done until now.

This series adds more code than it removes, and the unregistration is
not a fix as we don't ever remove the EM tables by design, so not sure
either of these points are valid arguments.

> This would also make the registration with EM core to happen only after policy
> is fully initialized, and the EM core can do other stuff from in there, like
> marking frequencies as inefficient (WIP). Though this patchset is useful without
> that work being done and should be merged nevertheless.
> 
> This doesn't update scmi cpufreq driver for now as it is a special case and need
> to be handled differently. Though we can make it work with this if required.

Note that we'll have more 'special cases' if other architectures start
using PM_EM, which is what we have been trying to allow since the
beginning, so that's worth keeping in mind.

Thanks,
Quentin


From leon at kernel.org  Tue Aug 10 05:36:44 2021
From: leon at kernel.org (Leon Romanovsky)
Date: Tue, 10 Aug 2021 15:36:44 +0300
Subject: [PATCH v2 net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <20210810115024.1629983-1-vladimir.oltean@nxp.com>
References: <20210810115024.1629983-1-vladimir.oltean@nxp.com>
Message-ID: <YRJy3F6lXuKNQIpl@unreal>

On Tue, Aug 10, 2021 at 02:50:24PM +0300, Vladimir Oltean wrote:
> The blamed commit a new field to struct switchdev_notifier_fdb_info, but
> did not make sure that all call paths set it to something valid. For
> example, a switchdev driver may emit a SWITCHDEV_FDB_ADD_TO_BRIDGE
> notifier, and since the 'is_local' flag is not set, it contains junk
> from the stack, so the bridge might interpret those notifications as
> being for local FDB entries when that was not intended.
> 
> To avoid that now and in the future, zero-initialize all
> switchdev_notifier_fdb_info structures created by drivers such that all
> newly added fields to not need to touch drivers again.
> 
> Fixes: 2c4eca3ef716 ("net: bridge: switchdev: include local flag in FDB notifications")
> Reported-by: Ido Schimmel <idosch at idosch.org>
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> Reviewed-by: Ido Schimmel <idosch at nvidia.com>
> Tested-by: Ido Schimmel <idosch at nvidia.com>
> ---
> v1->v2: use an empty struct initializer as opposed to memset, as
>         suggested by Leon Romanovsky
> 
>  drivers/net/ethernet/marvell/prestera/prestera_switchdev.c | 4 ++--
>  drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c       | 2 +-
>  drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c      | 4 ++--
>  drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 2 +-
>  drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c    | 2 +-
>  drivers/net/ethernet/rocker/rocker_main.c                  | 2 +-
>  drivers/net/ethernet/rocker/rocker_ofdpa.c                 | 2 +-
>  drivers/net/ethernet/ti/am65-cpsw-switchdev.c              | 2 +-
>  drivers/net/ethernet/ti/cpsw_switchdev.c                   | 2 +-
>  drivers/s390/net/qeth_l2_main.c                            | 4 ++--
>  net/dsa/slave.c                                            | 2 +-
>  11 files changed, 14 insertions(+), 14 deletions(-)
> 

Thanks,
Reviewed-by: Leon Romanovsky <leonro at nvidia.com>


From pavel at denx.de  Tue Aug 10 05:40:07 2021
From: pavel at denx.de (Pavel Machek)
Date: Tue, 10 Aug 2021 14:40:07 +0200
Subject: [PATCH] bus: ti-sysc: Fix gpt12 system timer issue with reserved
 status
In-Reply-To: <20210611060224.36769-1-tony@atomide.com>
References: <20210611060224.36769-1-tony@atomide.com>
Message-ID: <20210810124006.GA25121@amd>

Hi!

I noticed the issue while reviewing stable kernels, as this is being
backported.

> Jarkko Nikula <jarkko.nikula at bitmer.com> reported that Beagleboard
> revision c2 stopped booting. Jarkko bisected the issue down to
> commit 6cfcd5563b4f ("clocksource/drivers/timer-ti-dm: Fix suspend
> and resume for am3 and am4").
> 
> Let's fix the issue by tagging system timers as reserved rather than
> ignoring them. And let's not probe any interconnect target module child
> devices for reserved modules.

+++ b/drivers/bus/ti-sysc.c
> @@ -3093,8 +3095,8 @@ static int sysc_probe(struct platform_device *pdev)
>  		return error;
>  
>  	error = sysc_check_active_timer(ddata);
> -	if (error)
> -		return error;
> +	if (error == -EBUSY)
> +		ddata->reserved = true;
>  
>  	error = sysc_get_clocks(ddata);
>  	if (error)

What is going on here? First, we silently ignore errors other than
EBUSY. Second, sysc_check_active_timer() can't return -EBUSY: it
returns either 0 or -ENXIO. (I checked 5.10-stable, mainline and
-next-20210806).

Best regards,
								Pavel
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210810/c427f791/attachment-0001.sig>

From kgraul at linux.ibm.com  Tue Aug 10 05:41:48 2021
From: kgraul at linux.ibm.com (Karsten Graul)
Date: Tue, 10 Aug 2021 14:41:48 +0200
Subject: [PATCH v2 net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <20210810115024.1629983-1-vladimir.oltean@nxp.com>
References: <20210810115024.1629983-1-vladimir.oltean@nxp.com>
Message-ID: <dfa98bf7-cab4-4076-ef5f-880a8baa89ee@linux.ibm.com>

On 10/08/2021 13:50, Vladimir Oltean wrote:
> The blamed commit a new field to struct switchdev_notifier_fdb_info, but
                  ^^^ added?

> did not make sure that all call paths set it to something valid. For
> example, a switchdev driver may emit a SWITCHDEV_FDB_ADD_TO_BRIDGE
> notifier, and since the 'is_local' flag is not set, it contains junk
> from the stack, so the bridge might interpret those notifications as
> being for local FDB entries when that was not intended.
> 
> To avoid that now and in the future, zero-initialize all
> switchdev_notifier_fdb_info structures created by drivers such that all
> newly added fields to not need to touch drivers again.
> 
> Fixes: 2c4eca3ef716 ("net: bridge: switchdev: include local flag in FDB notifications")
> Reported-by: Ido Schimmel <idosch at idosch.org>
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> Reviewed-by: Ido Schimmel <idosch at nvidia.com>
> Tested-by: Ido Schimmel <idosch at nvidia.com>
> ---
> v1->v2: use an empty struct initializer as opposed to memset, as
>         suggested by Leon Romanovsky

For drivers/s390/net/qeth_l2_main.c :

Reviewed-by: Karsten Graul <kgraul at linux.ibm.com>

Thanks


From rocco.yue at mediatek.com  Tue Aug 10 05:33:27 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Tue, 10 Aug 2021 20:33:27 +0800
Subject: [PATCH net-next v3] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <c0a6f817-0225-c863-722c-19c798daaa4b@gmail.com>
References: <c0a6f817-0225-c863-722c-19c798daaa4b@gmail.com>
Message-ID: <20210810123327.15998-1-rocco.yue@mediatek.com>

On Mon, 2021-08-09 at 16:43 -0600, David Ahern wrote:
> On 8/9/21 8:01 AM, Rocco Yue wrote:

> +
>>  #ifdef CONFIG_SYSCTL
>>  
>>  static int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
>> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
>> index c467c6419893..a04164cbd77f 100644
>> --- a/net/ipv6/ndisc.c
>> +++ b/net/ipv6/ndisc.c
>> @@ -1496,6 +1496,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
>>  		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
>>  		mtu = ntohl(n);
>>  
>> +		if (in6_dev->ra_mtu != mtu) {
>> +			in6_dev->ra_mtu = mtu;
>> +			inet6_iframtu_notify(in6_dev);
>> +			ND_PRINTK(2, info, "update ra_mtu to %d\n", in6_dev->ra_mtu);
>> +		}
>> +
>>  		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
>>  			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
>>  		} else if (in6_dev->cnf.mtu6 != mtu) {
> 
> Since this MTU is getting reported via af_info infrastructure,
> rtmsg_ifinfo should be sufficient.
> 
> From there use 'ip monitor' to make sure you are not generating multiple
> notifications; you may only need this on the error path.

Hi David,

To avoid generating multiple notifications, I added a separate ramtu notify
function in this patch, and I added RTNLGRP_IPV6_IFINFO nl_mgrp to the ipmonitor.c
to verify this patch was as expected.

I look at the rtmsg_ifinfo code, it should be appropriate and I will use it and
verify it.

But there's one thing, I'm sorry I didn't fully understand the meaning of this
sentence "you may only need this on the error path". Honestly, I'm not sure what
the error patch refers to, do you mean "if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu)" ?

Thanks
Rocco

From linus.walleij at linaro.org  Tue Aug 10 05:43:33 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 14:43:33 +0200
Subject: [PATCH v2 0/2] pinctrl: single: Move test PCS_HAS_PINCONF in
 pcs_parse_bits_in_pinctrl_entry() to the beginning and fix its return value
In-Reply-To: <20210722033930.4034-1-thunder.leizhen@huawei.com>
References: <20210722033930.4034-1-thunder.leizhen@huawei.com>
Message-ID: <CACRpkdaHDZpHayo+ytHJik6CAkx2NhYrmxoObxQiu3ELRxCBQw@mail.gmail.com>

On Thu, Jul 22, 2021 at 5:40 AM Zhen Lei <thunder.leizhen at huawei.com> wrote:

> v1 --> v2:
> Split bugfix and cleanup into two patches.

Patches applied! Thanks for fixing this Zhen, sorry for the delay.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Tue Aug 10 05:45:12 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 14:45:12 +0200
Subject: [PATCH 1/7] dt-bindings: pinctrl: stm32: add new compatible for
 STM32MP135 SoC
In-Reply-To: <20210723132810.25728-2-alexandre.torgue@foss.st.com>
References: <20210723132810.25728-1-alexandre.torgue@foss.st.com>
 <20210723132810.25728-2-alexandre.torgue@foss.st.com>
Message-ID: <CACRpkdZKU7zA-SiV8n=wtaD1iqYMUocncvQB6NdAmYSn4xN7LA@mail.gmail.com>

On Fri, Jul 23, 2021 at 3:28 PM Alexandre Torgue
<alexandre.torgue at foss.st.com> wrote:

> New compatible to manage ball out and pin muxing of STM32MP135 SoC.
>
> Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>

Patch applied!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Tue Aug 10 05:45:52 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 14:45:52 +0200
Subject: [PATCH 2/7] pinctrl: stm32: Add STM32MP135 SoC support
In-Reply-To: <20210723132810.25728-3-alexandre.torgue@foss.st.com>
References: <20210723132810.25728-1-alexandre.torgue@foss.st.com>
 <20210723132810.25728-3-alexandre.torgue@foss.st.com>
Message-ID: <CACRpkdb2Wvr510Oc-cbN4GHaNBoMvnobB6dUJiCMg=vo3SeTMA@mail.gmail.com>

On Fri, Jul 23, 2021 at 3:28 PM Alexandre Torgue
<alexandre.torgue at foss.st.com> wrote:

> STM32MP135 SoC embeds 9 GPIO banks of 16 gpios each. Those GPIO
> banks contain same features as STM32MP157 GPIO banks except that
> each GPIO line of the STM32MP135 can be secured.
>
> Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>

Patch applied!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Tue Aug 10 05:48:26 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 14:48:26 +0200
Subject: [PATCH] pinctrl: stmfx: Fix hazardous u8[] to unsigned long cast
In-Reply-To: <20210725180830.250218-1-maz@kernel.org>
References: <20210725180830.250218-1-maz@kernel.org>
Message-ID: <CACRpkdbAnvk2AyT=Gom=AHZacm7sDJONR=6EnHLZ+cEySqQ4KQ@mail.gmail.com>

On Sun, Jul 25, 2021 at 8:08 PM Marc Zyngier <maz at kernel.org> wrote:

> Casting a small array of u8 to an unsigned long is *never* OK:
>
> - it does funny thing when the array size is less than that of a long,
>   as it accesses random places in the stack
> - it makes everything even more fun with a BE kernel
>
> Fix this by building the unsigned long used as a bitmap byte by byte,
> in a way that works across endianess and has no undefined behaviours.
>
> An extra BUILD_BUG_ON() catches the unlikely case where the array
> would be larger than a single unsigned long.
>
> Fixes: 1490d9f841b1 ("pinctrl: Add STMFX GPIO expander Pinctrl/GPIO driver")
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Cc: stable at vger.kernel.org
> Cc: Amelie Delaunay <amelie.delaunay at foss.st.com>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>

Patch applied!

Yours,
Linus Walleij


From boqun.feng at gmail.com  Tue Aug 10 05:49:14 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Tue, 10 Aug 2021 20:49:14 +0800
Subject: [PATCH v2 2/4] sched: Introduce is_pcpu_safe()
In-Reply-To: <87a6lrap5z.mognet@arm.com>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
 <20210807005807.1083943-3-valentin.schneider@arm.com>
 <800ff941e3ec86ea1397cddf8ecea3d4a17c55dc.camel@gmx.de>
 <87a6lrap5z.mognet@arm.com>
Message-ID: <YRJ1yvfRjDJpXZWf@boqun-archlinux>

On Sun, Aug 08, 2021 at 05:15:20PM +0100, Valentin Schneider wrote:
> On 07/08/21 03:42, Mike Galbraith wrote:
> > On Sat, 2021-08-07 at 01:58 +0100, Valentin Schneider wrote:
> >>
> >> +static inline bool is_pcpu_safe(void)
> >
> > Nit: seems odd to avoid spelling it out to save two characters, percpu
> > is word like, rolls off the ole tongue better than p-c-p-u.
> >
> >       -Mike
> 
> True. A quick grep says both versions are used, though "percpu" wins by
> about a factor of 2. I'll tweak that for a v3.

I wonder why is_percpu_safe() is the correct name. The safety of
accesses to percpu variables means two things to me:

a)	The thread cannot migrate to other CPU in the middle of
	accessing a percpu variable, in other words, the following
	cannot happen:

	{ percpu variable X is 0 on CPU 0 and 2 on CPU 1
	CPU 0				CPU 1
	========			=========
	<in thread A>
	__this_cpu_inc(X);
	  tmp = X; // tmp is 0
	  <preempted>
	  <migrate to CPU 1>
	  				// continue __this_cpu_inc(X);
					X = tmp + 1; // CPU 0 miss this
						     // increment (this
						     // may be OK), and
						     // CPU 1's X got
						     // corrupted.

b)	The accesses to a percpu variable are exclusive, i.e. no
	interrupt or preemption can happen in the middle of accessing,
	in other words, the following cannot happen:

	{ percpu variable X is 0 on CPU 0 }
	CPU 0
	========
	<in thread A>
	__this_cpu_inc(X);
	  tmp = X; // tmp is 0
	  <preempted>
	  <in other thread>
	  this_cpu_inc(X); // X is 1 afterwards.
	  <back to thread A>
	  X = tmp + 1; // X is 1, and we have a race condition.

And the is_p{er}cpu_safe() only detects the first, and it doesn't mean
totally safe for percpu accesses.

Maybe we can implement a migratable()? Although not sure it's a English
word.

Regards,
Boqun



From tony at atomide.com  Tue Aug 10 05:52:15 2021
From: tony at atomide.com (Tony Lindgren)
Date: Tue, 10 Aug 2021 15:52:15 +0300
Subject: [PATCH] bus: ti-sysc: Fix gpt12 system timer issue with reserved
 status
In-Reply-To: <20210810124006.GA25121@amd>
References: <20210611060224.36769-1-tony@atomide.com>
 <20210810124006.GA25121@amd>
Message-ID: <YRJ2fyS6z1i/2W2e@atomide.com>

* Pavel Machek <pavel at denx.de> [210810 12:40]:
> Hi!
> 
> I noticed the issue while reviewing stable kernels, as this is being
> backported.
> 
> > Jarkko Nikula <jarkko.nikula at bitmer.com> reported that Beagleboard
> > revision c2 stopped booting. Jarkko bisected the issue down to
> > commit 6cfcd5563b4f ("clocksource/drivers/timer-ti-dm: Fix suspend
> > and resume for am3 and am4").
> > 
> > Let's fix the issue by tagging system timers as reserved rather than
> > ignoring them. And let's not probe any interconnect target module child
> > devices for reserved modules.
> 
> +++ b/drivers/bus/ti-sysc.c
> > @@ -3093,8 +3095,8 @@ static int sysc_probe(struct platform_device *pdev)
> >  		return error;
> >  
> >  	error = sysc_check_active_timer(ddata);
> > -	if (error)
> > -		return error;
> > +	if (error == -EBUSY)
> > +		ddata->reserved = true;
> >  
> >  	error = sysc_get_clocks(ddata);
> >  	if (error)
> 
> What is going on here? First, we silently ignore errors other than
> EBUSY. Second, sysc_check_active_timer() can't return -EBUSY: it
> returns either 0 or -ENXIO. (I checked 5.10-stable, mainline and
> -next-20210806).

Thanks for spotting it, looks like there's now a conflict with commit
65fb73676112 ("bus: ti-sysc: suppress err msg for timers used as
clockevent/source"). It seems we should also check for -ENXIO here
too. And yeah it makes sens to return on other errors for sure.

Regards,

Tony


From linus.walleij at linaro.org  Tue Aug 10 05:55:58 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 14:55:58 +0200
Subject: [PATCH] pinctrl: sunxi: Don't underestimate number of functions
In-Reply-To: <20210722132548.22121-1-andre.przywara@arm.com>
References: <20210722132548.22121-1-andre.przywara@arm.com>
Message-ID: <CACRpkdYKk4An56a0rmoXgmcpAmGTLeyhM6qfTK+y1yopHB4NXA@mail.gmail.com>

On Thu, Jul 22, 2021 at 3:26 PM Andre Przywara <andre.przywara at arm.com> wrote:

> When we are building all the various pinctrl structures for the
> Allwinner pinctrl devices, we do some estimation about the maximum
> number of distinct function (names) that we will need.
>
> So far we take the number of pins as an upper bound, even though we
> can actually have up to four special functions per pin. This wasn't a
> problem until now, since we indeed have typically far more pins than
> functions, and most pins share common functions.
>
> However the H616 "-r" pin controller has only two pins, but four
> functions, so we run over the end of the array when we are looking for
> a matching function name in sunxi_pinctrl_add_function - there is no
> NULL sentinel left that would terminate the loop:
>
> [    8.200648] Unable to handle kernel paging request at virtual address fffdff7efbefaff5
> [    8.209179] Mem abort info:
> ....
> [    8.368456] Call trace:
> [    8.370925]  __pi_strcmp+0x90/0xf0
> [    8.374559]  sun50i_h616_r_pinctrl_probe+0x1c/0x28
> [    8.379557]  platform_probe+0x68/0xd8
>
> Do an actual worst case allocation (4 functions per pin, three common
> functions and the sentinel) for the initial array allocation. This is
> now heavily overestimating the number of functions in the common case,
> but we will reallocate this array later with the actual number of
> functions, so it's only temporarily.
>
> Fixes: 561c1cf17c46 ("pinctrl: sunxi: Add support for the Allwinner H616-R pin controller")
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Patch applied for fixes!
Thanks for finding this.

Yours,
Linus Walleij


From valentin.schneider at arm.com  Tue Aug 10 06:04:16 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Tue, 10 Aug 2021 14:04:16 +0100
Subject: [PATCH v2 2/4] sched: Introduce is_pcpu_safe()
In-Reply-To: <YRJ1yvfRjDJpXZWf@boqun-archlinux>
References: <20210807005807.1083943-1-valentin.schneider@arm.com>
 <20210807005807.1083943-3-valentin.schneider@arm.com>
 <800ff941e3ec86ea1397cddf8ecea3d4a17c55dc.camel@gmx.de>
 <87a6lrap5z.mognet@arm.com> <YRJ1yvfRjDJpXZWf@boqun-archlinux>
Message-ID: <87wnot8n8v.mognet@arm.com>

On 10/08/21 20:49, Boqun Feng wrote:
> On Sun, Aug 08, 2021 at 05:15:20PM +0100, Valentin Schneider wrote:
>> On 07/08/21 03:42, Mike Galbraith wrote:
>> > On Sat, 2021-08-07 at 01:58 +0100, Valentin Schneider wrote:
>> >>
>> >> +static inline bool is_pcpu_safe(void)
>> >
>> > Nit: seems odd to avoid spelling it out to save two characters, percpu
>> > is word like, rolls off the ole tongue better than p-c-p-u.
>> >
>> >       -Mike
>> 
>> True. A quick grep says both versions are used, though "percpu" wins by
>> about a factor of 2. I'll tweak that for a v3.
>
> I wonder why is_percpu_safe() is the correct name. The safety of
> accesses to percpu variables means two things to me:
>
> a)	The thread cannot migrate to other CPU in the middle of
> 	accessing a percpu variable, in other words, the following
> 	cannot happen:
>
> 	{ percpu variable X is 0 on CPU 0 and 2 on CPU 1
> 	CPU 0				CPU 1
> 	========			=========
> 	<in thread A>
> 	__this_cpu_inc(X);
> 	  tmp = X; // tmp is 0
> 	  <preempted>
> 	  <migrate to CPU 1>
> 	  				// continue __this_cpu_inc(X);
> 					X = tmp + 1; // CPU 0 miss this
> 						     // increment (this
> 						     // may be OK), and
> 						     // CPU 1's X got
> 						     // corrupted.
>
> b)	The accesses to a percpu variable are exclusive, i.e. no
> 	interrupt or preemption can happen in the middle of accessing,
> 	in other words, the following cannot happen:
>
> 	{ percpu variable X is 0 on CPU 0 }
> 	CPU 0
> 	========
> 	<in thread A>
> 	__this_cpu_inc(X);
> 	  tmp = X; // tmp is 0
> 	  <preempted>
> 	  <in other thread>
> 	  this_cpu_inc(X); // X is 1 afterwards.
> 	  <back to thread A>
> 	  X = tmp + 1; // X is 1, and we have a race condition.
>
> And the is_p{er}cpu_safe() only detects the first, and it doesn't mean
> totally safe for percpu accesses.
>

Right. I do briefly point this out in the changelog (the bit about
"acquiring a sleepable lock if relevant"), but that doesn't do much to
clarify the helper name itself.

> Maybe we can implement a migratable()? Although not sure it's a English
> word.
>

Funnily enough that is exactly how I named the thing in my initial draft,
but then I somehow convinced myself that tailoring the name to per-CPU
accesses would make its intent clearer.

I think you're right that "migratable()" is less confusing at the end of
the day. Oh well, so much for overthinking the naming problem :-)

> Regards,
> Boqun


From olteanv at gmail.com  Tue Aug 10 06:08:21 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 10 Aug 2021 16:08:21 +0300
Subject: [PATCH v2 net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <dfa98bf7-cab4-4076-ef5f-880a8baa89ee@linux.ibm.com>
References: <20210810115024.1629983-1-vladimir.oltean@nxp.com>
 <dfa98bf7-cab4-4076-ef5f-880a8baa89ee@linux.ibm.com>
Message-ID: <20210810130821.7gdngordzzxkpws3@skbuf>

On Tue, Aug 10, 2021 at 02:41:48PM +0200, Karsten Graul wrote:
> On 10/08/2021 13:50, Vladimir Oltean wrote:
> > The blamed commit a new field to struct switchdev_notifier_fdb_info, but
>                   ^^^ added?

yes. but I won't send a v3 just for that. thanks for noticing.


From maz at kernel.org  Tue Aug 10 06:15:02 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 14:15:02 +0100
Subject: [PATCH 08/13] clocksource/arm_arch_timer: Work around broken CVAL
 implementations
In-Reply-To: <20210810123407.GB52842@C02TD0UTHF1T.local>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-9-maz@kernel.org>
 <20210810123407.GB52842@C02TD0UTHF1T.local>
Message-ID: <874kbxbfvt.wl-maz@kernel.org>

On Tue, 10 Aug 2021 13:34:07 +0100,
Mark Rutland <mark.rutland at arm.com> wrote:
> 
> On Mon, Aug 09, 2021 at 04:26:46PM +0100, Marc Zyngier wrote:
> > The Applied Micro XGene-1 SoC has a busted implementation of the
> > CVAL register: it looks like it is based on TVAL instead of the
> > other way around. The net effect of this implementation blunder
> > is that the maximum deadline you can program in the timer is
> > 32bit wide.
> > 
> > Detect the problematic case and limit the timer to 32bit deltas.
> > Note that we don't tie this bug to XGene specifically, as it may
> > also catch similar defects on other high-quality implementations.
> 
> Do we know of any other implementations that have a similar bug?
> 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  drivers/clocksource/arm_arch_timer.c | 38 +++++++++++++++++++++++++++-
> >  1 file changed, 37 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> > index 895844c33351..1c596cd3cc5c 100644
> > --- a/drivers/clocksource/arm_arch_timer.c
> > +++ b/drivers/clocksource/arm_arch_timer.c
> > @@ -778,9 +778,42 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
> >  	return 0;
> >  }
> >  
> > +static u64 __arch_timer_check_delta(void)
> > +{
> > +#ifdef CONFIG_ARM64
> > +	u64 tmp;
> > +
> > +	/*
> > +	 * XGene-1 implements CVAL in terms of TVAL, meaning that the
> > +	 * maximum timer range is 32bit. Shame on them. Detect the
> > +	 * issue by setting a timer to now+(1<<32), which will
> > +	 * immediately fire on the duff CPU.
> > +	 */
> > +	write_sysreg(0, cntv_ctl_el0);
> > +	isb();
> > +	tmp = read_sysreg(cntvct_el0) | BIT(32);
> > +	write_sysreg(tmp, cntv_cval_el0);
> 
> This will fire on legitimate implementations fairly often. Consider if
> we enter this function at a time where CNTCVT_EL0[32] == 1, where:
> 
> * At 100MHz, bit 32 flips every ~42.95
> * At 200MHz, bit 32 flips every ~21.47
> * At 1GHz, bit 32 flips every ~4.29s
> 
> ... and ThunderX2 has a 200MHz frequency today, with SBSA recommending
> 100MHz.

Yup, you're right, this is silly. Orr-ing the bit is a bad enough bug
(it really should be a +), but also preemption in a guest will add
another set of false positives.

> What does XGene-1 return upon a read of CVAL? If it always returns 0 for
> the high bits, we could do a timing-insensitive check for truncation of
> CVAL, e.g.
> 
> | 	/* CVAL must be at least 56 bits wide, as with CNT */
> | 	u64 mask = GENMASK(55, 0);
> | 	u64 val;
> | 
> | 	write_sysreg(mask, cntv_cval_el0);
> | 	val = read_sysread(cnt_cval_el0);
> | 
> | 	if (val != mask) {
> | 		/* What a great CPU */
> | 	}

No, the register itself returns what has been written. But only the
low 32bits of the delta trickle into TVAL on write, which is then used
as a countdown. I guess I could play the same trick as above with a
higher bit, but it still is pretty unreliable, as it could then wrap
through 0.

Maybe I'll just check the MIDR in the end...

	M.

-- 
Without deviation from the norm, progress is not possible.


From will at kernel.org  Tue Aug 10 06:20:15 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 14:20:15 +0100
Subject: [PATCH 1/5] KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as
 page size
In-Reply-To: <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210810132015.GA2946@willie-the-truck>

On Tue, Aug 10, 2021 at 12:32:37PM +0530, Anshuman Khandual wrote:
> All instances here could just directly test against CONFIG_ARM64_XXK_PAGES
> instead of evaluating via PAGE_SHIFT or PAGE_SIZE. With this change, there
> will be no such usage left.
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>
> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/kvm/hyp/pgtable.c | 6 +++---
>  arch/arm64/mm/mmu.c          | 2 +-
>  2 files changed, 4 insertions(+), 4 deletions(-)

Why is this better?

WIll


From will at kernel.org  Tue Aug 10 06:21:24 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 14:21:24 +0100
Subject: [PATCH 2/5] KVM: arm64: Drop init_common_resources()
In-Reply-To: <1628578961-29097-3-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-3-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210810132123.GB2946@willie-the-truck>

On Tue, Aug 10, 2021 at 12:32:38PM +0530, Anshuman Khandual wrote:
> Could do without this additional indirection via init_common_resources() by
> just calling kvm_set_ipa_limit() directly instead. This change saves memory
> and cycles.

Does it? Really?

Will

> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e9a2b8f27792..19560e457c11 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -1696,11 +1696,6 @@ static bool init_psci_relay(void)
>  	return true;
>  }
>  
> -static int init_common_resources(void)
> -{
> -	return kvm_set_ipa_limit();
> -}
> -
>  static int init_subsystems(void)
>  {
>  	int err = 0;
> @@ -2102,7 +2097,7 @@ int kvm_arch_init(void *opaque)
>  		}
>  	}
>  
> -	err = init_common_resources();
> +	err = kvm_set_ipa_limit();
>  	if (err)
>  		return err;
>  
> -- 
> 2.20.1
> 


From lukasz.luba at arm.com  Tue Aug 10 06:25:15 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 10 Aug 2021 14:25:15 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <YRJym+Vn4bbwQzzs@google.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
Message-ID: <af06b333-3d8a-807c-9ccb-d491d6a54930@arm.com>



On 8/10/21 1:35 PM, Quentin Perret wrote:
> On Tuesday 10 Aug 2021 at 13:06:47 (+0530), Viresh Kumar wrote:
>> Provide a cpufreq driver flag so drivers can ask the cpufreq core to register
>> with the EM core on their behalf.
> 
> Hmm, that's not quite what this does. This asks the cpufreq core to
> use *PM_OPP* to register an EM, which I think is kinda wrong to do from
> there IMO. The decision to use PM_OPP or another mechanism to register
> an EM belongs to platform specific code (drivers), so it is odd for the
> PM_OPP registration to have its own cpufreq flag but not the other ways.
> 
> As mentioned in another thread, the very reason to have PM_EM is to not
> depend on PM_OPP, so I'm worried about the direction of travel with this
> series TBH.
> 
>> This allows us to get rid of duplicated code
>> in the drivers and fix the unregistration part as well, which none of the
>> drivers have done until now.
> 
> This series adds more code than it removes, and the unregistration is
> not a fix as we don't ever remove the EM tables by design, so not sure
> either of these points are valid arguments.
> 
>> This would also make the registration with EM core to happen only after policy
>> is fully initialized, and the EM core can do other stuff from in there, like
>> marking frequencies as inefficient (WIP). Though this patchset is useful without
>> that work being done and should be merged nevertheless.
>>
>> This doesn't update scmi cpufreq driver for now as it is a special case and need
>> to be handled differently. Though we can make it work with this if required.
> 
> Note that we'll have more 'special cases' if other architectures start
> using PM_EM, which is what we have been trying to allow since the
> beginning, so that's worth keeping in mind.
> 

The way I see this is that the flag in cpufreq avoids
mistakes potentially made by driver developer. It will automaticaly
register the *simple* EM model via dev_pm_opp_of_register_em() on behalf
of drivers (which is already done manually by drivers). The developer
would just set the flag similarly to CPUFREQ_IS_COOLING_DEV and be sure
it will register at the right time. Well tested flag approach should be
safer, easier to understand, maintain.

If there is a need for *advanced* EM model, driver developer would
have to care about all these things (order, setup-ready-structures,
fw channels, freeing, etc) while developing custom registration.
The developer won't set this flag in such case, so the core won't
try to auto register the EM for that driver.

I don't see the dependency of PM_EM on PM_OPP in this series.


From will at kernel.org  Tue Aug 10 06:28:22 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 14:28:22 +0100
Subject: [PATCH 3/5] KVM: arm64: Drop check_kvm_target_cpu() based percpu
 probe
In-Reply-To: <1628578961-29097-4-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-4-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210810132822.GC2946@willie-the-truck>

On Tue, Aug 10, 2021 at 12:32:39PM +0530, Anshuman Khandual wrote:
> kvm_target_cpu() never returns a negative error code, so check_kvm_target()
> would never have 'ret' filled with a negative error code. Hence the percpu
> probe via check_kvm_target_cpu() does not make sense as its never going to
> find an unsupported CPU, forcing kvm_arch_init() to exit early. Hence lets
> just drop this percpu probe (and also check_kvm_target_cpu()) altogether.
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>
> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/kvm/arm.c | 14 --------------
>  1 file changed, 14 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 19560e457c11..16f93678c17e 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -2010,11 +2010,6 @@ static int finalize_hyp_mode(void)
>  	return 0;
>  }
>  
> -static void check_kvm_target_cpu(void *ret)
> -{
> -	*(int *)ret = kvm_target_cpu();
> -}
> -
>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
>  {
>  	struct kvm_vcpu *vcpu;
> @@ -2074,7 +2069,6 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons)
>  int kvm_arch_init(void *opaque)
>  {
>  	int err;
> -	int ret, cpu;
>  	bool in_hyp_mode;
>  
>  	if (!is_hyp_mode_available()) {
> @@ -2089,14 +2083,6 @@ int kvm_arch_init(void *opaque)
>  		kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \
>  			 "Only trusted guests should be used on this system.\n");
>  
> -	for_each_online_cpu(cpu) {
> -		smp_call_function_single(cpu, check_kvm_target_cpu, &ret, 1);
> -		if (ret < 0) {
> -			kvm_err("Error, CPU %d not supported!\n", cpu);
> -			return -ENODEV;
> -		}
> -	}

Looks like kvm_target_cpu() *could* return an error at one time of day (at
least on 32-bit), but agreed that this checking is no longer needed:

Acked-by: Will Deacon <will at kernel.org>

Perhaps it's worth making the return type of kvm_target_cpu() a u32 to
make it a bit more explicit that you shouldn't be returning an error code
there?

Will


From maz at kernel.org  Tue Aug 10 06:29:14 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 14:29:14 +0100
Subject: [PATCH 5/5] KVM: arm64: Define KVM_PHYS_SHIFT_MIN
In-Reply-To: <1628578961-29097-6-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-6-git-send-email-anshuman.khandual@arm.com>
Message-ID: <2dbeb2c329cfeb1ee9a7331683cdbc97@kernel.org>

On 2021-08-10 08:02, Anshuman Khandual wrote:
> Drop the hard coded value for the minimum IPA range i.e 32 bit. Instead
> define a macro KVM_PHYS_SHIFT_MIN which improves the code readability.
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>
> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/include/asm/kvm_mmu.h | 3 ++-
>  arch/arm64/kvm/reset.c           | 2 +-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_mmu.h 
> b/arch/arm64/include/asm/kvm_mmu.h
> index b52c5c4b9a3d..716f999818d9 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -141,7 +141,8 @@ static __always_inline unsigned long
> __kern_hyp_va(unsigned long v)
>   * We currently support using a VM-specified IPA size. For backward
>   * compatibility, the default IPA size is fixed to 40bits.
>   */
> -#define KVM_PHYS_SHIFT	(40)
> +#define KVM_PHYS_SHIFT		(40)
> +#define KVM_PHYS_SHIFT_MIN	(32)
> 
>  #define kvm_phys_shift(kvm)		VTCR_EL2_IPA(kvm->arch.vtcr)
>  #define kvm_phys_size(kvm)		(_AC(1, ULL) << kvm_phys_shift(kvm))
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index cba7872d69a8..8dc8b4b9de37 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -369,7 +369,7 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned
> long type)
>  	phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
>  	if (phys_shift) {
>  		if (phys_shift > kvm_ipa_limit ||
> -		    phys_shift < 32)
> +		    phys_shift < KVM_PHYS_SHIFT_MIN)
>  			return -EINVAL;
>  	} else {
>  		phys_shift = KVM_PHYS_SHIFT;

This is not a KVM property, but an architectural one. If you
want to replace it with something more readable, please
make it global to the whole of arm64 (ARM64_MIN_PARANGE?).

Thanks,

       M.
-- 
Jazz is not dead. It just smells funny...


From will at kernel.org  Tue Aug 10 06:31:01 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 14:31:01 +0100
Subject: [PATCH] arm64/perf: Replace '0xf' instances with
 ID_AA64DFR0_PMUVER_IMP_DEF
In-Reply-To: <1628571998-13634-1-git-send-email-anshuman.khandual@arm.com>
References: <1628571998-13634-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210810133101.GD2946@willie-the-truck>

On Tue, Aug 10, 2021 at 10:36:38AM +0530, Anshuman Khandual wrote:
> ID_AA64DFR0_PMUVER_IMP_DEF which indicate implementation defined PMU, never
> actually gets used although there are '0xf' instances scattered all around.
> Just do the macro replacement to improve readability.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
> This applies on v5.14-rc5
> 
>  arch/arm64/include/asm/cpufeature.h | 2 +-
>  arch/arm64/kernel/perf_event.c      | 2 +-
>  arch/arm64/kvm/perf.c               | 2 +-
>  arch/arm64/kvm/pmu-emul.c           | 6 +++---
>  4 files changed, 6 insertions(+), 6 deletions(-)

Please can you split this with the KVM parts in their own patch?

Thanks,

Will


From wangborong at cdjrlc.com  Tue Aug 10 06:29:54 2021
From: wangborong at cdjrlc.com (Jason Wang)
Date: Tue, 10 Aug 2021 21:29:54 +0800
Subject: [PATCH] ARM: sunxi: Add a missing SPDX license header
Message-ID: <20210810132954.107518-1-wangborong@cdjrlc.com>

Add the missing SPDX license header to arch/arm/mach-sunxi/sunxi.c.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
---
 arch/arm/mach-sunxi/sunxi.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 19635721013d..e1b7945aac99 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Device Tree support for Allwinner A1X SoCs
  *
@@ -5,9 +6,6 @@
  *
  * Maxime Ripard <maxime.ripard at free-electrons.com>
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/clocksource.h>
-- 
2.32.0



From wangborong at cdjrlc.com  Tue Aug 10 06:31:38 2021
From: wangborong at cdjrlc.com (Jason Wang)
Date: Tue, 10 Aug 2021 21:31:38 +0800
Subject: [PATCH] ARM: sunxi: Add a missing SPDX license header
Message-ID: <20210810133138.109309-1-wangborong@cdjrlc.com>

Add the missing SPDX license header to arch/arm/mach-sunxi/platsmp.c.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
---
 arch/arm/mach-sunxi/platsmp.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
index bdde9ef3aaa9..052097e78e6e 100644
--- a/arch/arm/mach-sunxi/platsmp.c
+++ b/arch/arm/mach-sunxi/platsmp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * SMP support for Allwinner SoCs
  *
@@ -8,9 +9,6 @@
  * Based on code
  *  Copyright (C) 2012-2013 Allwinner Ltd.
  *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/delay.h>
-- 
2.32.0



From maz at kernel.org  Tue Aug 10 06:33:17 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 14:33:17 +0100
Subject: [PATCH 1/5] KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as
 page size
In-Reply-To: <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
Message-ID: <25ee7799069492f2501003faec7f9732@kernel.org>

On 2021-08-10 08:02, Anshuman Khandual wrote:
> All instances here could just directly test against 
> CONFIG_ARM64_XXK_PAGES
> instead of evaluating via PAGE_SHIFT or PAGE_SIZE. With this change, 
> there
> will be no such usage left.
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>
> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/kvm/hyp/pgtable.c | 6 +++---
>  arch/arm64/mm/mmu.c          | 2 +-
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/pgtable.c 
> b/arch/arm64/kvm/hyp/pgtable.c
> index 05321f4165e3..a6112b6d6ef6 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -85,7 +85,7 @@ static bool kvm_level_supports_block_mapping(u32 
> level)
>  	 * Reject invalid block mappings and don't bother with 4TB mappings 
> for
>  	 * 52-bit PAs.
>  	 */
> -	return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
> +	return !(level == 0 || (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) && level 
> == 1));
>  }
> 
>  static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, 
> u32 level)
> @@ -155,7 +155,7 @@ static u64 kvm_pte_to_phys(kvm_pte_t pte)
>  {
>  	u64 pa = pte & KVM_PTE_ADDR_MASK;
> 
> -	if (PAGE_SHIFT == 16)
> +	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
>  		pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
> 
>  	return pa;
> @@ -165,7 +165,7 @@ static kvm_pte_t kvm_phys_to_pte(u64 pa)
>  {
>  	kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK;
> 
> -	if (PAGE_SHIFT == 16)
> +	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
>  		pte |= FIELD_PREP(KVM_PTE_ADDR_51_48, pa >> 48);
> 
>  	return pte;
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 9ff0de1b2b93..8fdfca179815 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -296,7 +296,7 @@ static void alloc_init_cont_pmd(pud_t *pudp,
> unsigned long addr,
>  static inline bool use_1G_block(unsigned long addr, unsigned long 
> next,
>  			unsigned long phys)
>  {
> -	if (PAGE_SHIFT != 12)
> +	if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
>  		return false;
> 
>  	if (((addr | next | phys) & ~PUD_MASK) != 0)

I personally find it a lot less readable.

Also, there is no evaluation whatsoever. All the code guarded
by a PAGE_SIZE/PAGE_SHIFT that doesn't match the configuration
is dropped at compile time.

Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...


From linus.walleij at linaro.org  Tue Aug 10 06:34:39 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 15:34:39 +0200
Subject: [RFC PATCH 1/6] pinctrl: Add pinctrl_gpio_as_pin()
In-Reply-To: <20210723075858.376378-2-andrew@aj.id.au>
References: <20210723075858.376378-1-andrew@aj.id.au>
 <20210723075858.376378-2-andrew@aj.id.au>
Message-ID: <CACRpkdZ4A3Lw2U+_jXfbuXJFhpesi3SzNN1Codqxi4sLNu5zPw@mail.gmail.com>

On Fri, Jul 23, 2021 at 9:59 AM Andrew Jeffery <andrew at aj.id.au> wrote:

> Allow gpiochips to map the GPIO numberspace onto a pin numberspace when
> the register layout for GPIO control is implemented in terms of the
> pin numberspace.
>
> This requirement sounds kind of strange, but the patch is driven by
> trying to resolve a bug in the leds-pca955x driver where this mapping is
> not correctly performed.
>
> Signed-off-by: Andrew Jeffery <andrew at aj.id.au>

(...)

Hm  this looks a bit strange...

> +int pinctrl_gpio_as_pin(struct pinctrl_dev *pctldev, unsigned int gpio)

This is not a good name for this function. Try to come up with
a name that says exactly what the function does.

E.g. "apple pear as apple slice" isn't very helpful, the use case for
this is really hard to understand.

> +EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);

This looks completely wrong.

Yours,
Linus Walleij


From mathieu.poirier at linaro.org  Tue Aug 10 06:36:01 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 10 Aug 2021 07:36:01 -0600
Subject: [PATCH v3 2/2] remoteproc: meson-mx-ao-arc: Add a driver for the
 AO ARC remote procesor
In-Reply-To: <CAFBinCCkOgkzuxZPby-rJeH7ei-G_khiStkX9Zs3w1u1RAd7_Q@mail.gmail.com>
References: <20210717234859.351911-1-martin.blumenstingl@googlemail.com>
 <20210717234859.351911-3-martin.blumenstingl@googlemail.com>
 <20210728175823.GA2766167@p14s>
 <CAFBinCB0-bAa7Y+YhscczarGrGuio37F8vRyfW6U2DiiDAvr-g@mail.gmail.com>
 <20210805161506.GA3205691@p14s>
 <CAFBinCCkOgkzuxZPby-rJeH7ei-G_khiStkX9Zs3w1u1RAd7_Q@mail.gmail.com>
Message-ID: <CANLsYkyz5h9Qb+ZLFAtegDHYeQoOYeF_6GF7jYo8kxhF-pt66Q@mail.gmail.com>

On Sun, 8 Aug 2021 at 14:37, Martin Blumenstingl
<martin.blumenstingl at googlemail.com> wrote:
>
> Hi Mathieu,
>
> On Thu, Aug 5, 2021 at 6:15 PM Mathieu Poirier
> <mathieu.poirier at linaro.org> wrote:
> >
> > On Wed, Aug 04, 2021 at 11:03:57PM +0200, Martin Blumenstingl wrote:
> > > Hi Mathieu,
> > >
> > > thanks for taking the time to look into this!
> > >
> > > (I will address any of your comments that I am not mentioning in this
> > > email anymore. Thanks a lot for the suggestions!)
> > >
> > > On Wed, Jul 28, 2021 at 7:58 PM Mathieu Poirier
> > > <mathieu.poirier at linaro.org> wrote:
> > > [...]
> > > > > +     writel(FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
> > > > > +                            priv->sram_pa >> 14),
> > > > Indentation problem
> > > The idea here is to align priv->sram_pa with AO_REMAP_REG0... which
> > > are both arguments to FIELD_PREP
> >
> > Right, this is what I would have expected.  When I applied the patch on my side
> > "priv->sram_pa ..." was aligned wiht the 'M' of "AO_REMAP_ ...".
> >
> > > Maybe using something like this will make that easier to read:
> > >     tmp = FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
> > >                                      priv->sram_pa >> 14);
> > >     writel(tmp, priv->remap_base + AO_REMAP_REG0);
> >
> > I think the main problem is that
> > AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU is simply too long.  I
> > suggest making is shorter and add a comment to describe exactly what it does.
> AO_CPU_CNTL_AHB_SRAM_BITS_31_20 is used below and when looking at it
> now I think the alignment is also strange.
> For the next version I'll go with the tmp variable as I think it
> improves readability, even with the long(er) macro names.
>
> [...]
> > > > > +     priv->arc_reset = devm_reset_control_get_exclusive(dev, NULL);
> > > > > +     if (IS_ERR(priv->arc_reset)) {
> > > >
> > > > Function __reset_control_get() in __devm_reset_control_get() can return NULL so
> > > > this should be IS_ERR_OR_NULL().
> > > The logic in there is: return optional ? NULL : ERR_PTR(-...);
> >
> > Ok, so you meant to do that.  And I just checked reset_control_reset() and it does
> > account for a NULL parameter.  I'm good with this one but add a comment to
> > make sure future readers don't think you've omitted to properly deal with the
> > NULL return value.
> >
> > > I am requesting a mandatory reset line here, so reset core will never
> > > return NULL
> > > See also [0]
> >
> > Indeed, I've read that too.  Nonetheless __reset_control_get() can return NULL
> > by way of __reset_control_get_from_lookup().
> I could not find where __reset_control_get_from_lookup returns NULL in
> case optional is false (which it is in this case because
> devm_reset_control_get_exclusive requests a "mandatory" reset line).
> Can you please point me to the problematic line(s) as I'd like to send
> a patch (which fixes this) to the reset subsystem maintainers
>

I am currently traveling - I will get back to you in a week or so.

> $ git grep -A1 devm_reset_control_get_exclusive | grep IS_ERR_OR_NULL
> drivers/remoteproc/ti_k3_r5_remoteproc.c-       if
> (IS_ERR_OR_NULL(core->reset)) {
> $
>
> I suspect that this can be simplified then as well.
>
>
> Best regards,
> Martin
>
>
> [0] https://elixir.bootlin.com/linux/v5.14-rc4/source/include/linux/reset.h#L227
> [1] https://elixir.bootlin.com/linux/v5.14-rc4/source/drivers/reset/core.c#L932


From geert+renesas at glider.be  Tue Aug 10 06:47:19 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue, 10 Aug 2021 15:47:19 +0200
Subject: [PATCH] iommu: APPLE_DART should depend on ARCH_APPLE
Message-ID: <44fcf525273b32c9afcd7e99acbd346d47f0e047.1628603162.git.geert+renesas@glider.be>

The Apple DART (Device Address Resolution Table) IOMMU is only present
on Apple ARM SoCs like the M1.  Hence add a dependency on ARCH_APPLE, to
prevent asking the user about this driver when configuring a kernel
without support for the Apple Silicon SoC family.

Fixes: 05ce9d20d699b093 ("iommu/dart: Add DART iommu driver")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 drivers/iommu/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index dfe81da483e9e073..e908b8222e4ed679 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -292,7 +292,7 @@ config SPAPR_TCE_IOMMU
 
 config APPLE_DART
 	tristate "Apple DART IOMMU Support"
-	depends on ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64)
+	depends on ARCH_APPLE || (COMPILE_TEST && !GENERIC_ATOMIC64)
 	select IOMMU_API
 	select IOMMU_IO_PGTABLE_LPAE
 	default ARCH_APPLE
-- 
2.25.1



From will at kernel.org  Tue Aug 10 06:52:36 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 14:52:36 +0100
Subject: [PATCH] arm64: clean vdso files
In-Reply-To: <20210809191414.3572827-1-adelg@google.com>
References: <20210809191414.3572827-1-adelg@google.com>
Message-ID: <20210810135236.GA3101@willie-the-truck>

[+Masahiro]

On Mon, Aug 09, 2021 at 07:14:14PM +0000, Andrew Delgadillo wrote:
> commit a5b8ca97fbf8 ("arm64: do not descend to vdso directories twice")
> changes the cleaning behavior of arm64's vdso files, in that vdso.lds,
> vdso.so, and vdso.so.dbg are not removed upon a 'make clean/mrproper':
> 
> $ make defconfig ARCH=arm64
> $ make ARCH=arm64
> $ make mrproper ARCH=arm64
> $ git clean -nxdf
> Would remove arch/arm64/kernel/vdso/vdso.lds
> Would remove arch/arm64/kernel/vdso/vdso.so
> Would remove arch/arm64/kernel/vdso/vdso.so.dbg
> 
> To remedy this, manually descend into arch/arm64/kernel/vdso upon
> cleaning.
> 
> After this commit:
> $ make defconfig ARCH=arm64
> $ make ARCH=arm64
> $ make mrproper ARCH=arm64
> $ git clean -nxdf
> <empty>

Well spotted!

> Signed-off-by: Andrew Delgadillo <adelg at google.com>
> ---
>  arch/arm64/Makefile | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> index b52481f0605d..ef6598cb5a9b 100644
> --- a/arch/arm64/Makefile
> +++ b/arch/arm64/Makefile
> @@ -181,6 +181,7 @@ archprepare:
>  # We use MRPROPER_FILES and CLEAN_FILES now
>  archclean:
>  	$(Q)$(MAKE) $(clean)=$(boot)
> +	$(Q)$(MAKE) $(clean)=arch/arm64/kernel/vdso

I think we also need to clean the vdso32 directory here. Please can you
send a v2 with that added?

Cheers,

Will


From robh at kernel.org  Tue Aug 10 06:52:51 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 10 Aug 2021 07:52:51 -0600
Subject: [PATCH v4,
 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8192
In-Reply-To: <20210810083047.16693-14-yunfei.dong@mediatek.com>
References: <20210810083047.16693-1-yunfei.dong@mediatek.com>
 <20210810083047.16693-14-yunfei.dong@mediatek.com>
Message-ID: <1628603571.555258.1500789.nullmailer@robh.at.kernel.org>

On Tue, 10 Aug 2021 16:30:45 +0800, Yunfei Dong wrote:
> Adds decoder dt-bindings for mt8192.
> 
> Change-Id: I2c482fa6c0a91b5fc4f1950dd563cbc4d6c35da1
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
> v4: fix yaml file check fail
> ---
>  .../media/mediatek,vcodec-comp-decoder.yaml   | 172 ++++++++++++++++++
>  1 file changed, 172 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
./Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml: $id: relative path/filename doesn't match actual path or filename
	expected: http://devicetree.org/schemas/media/mediatek,vcodec-comp-decoder.yaml#
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dts:22:18: fatal error: dt-bindings/clock/mt8192-clk.h: No such file or directory
   22 |         #include <dt-bindings/clock/mt8192-clk.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1515305

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From qperret at google.com  Tue Aug 10 06:53:18 2021
From: qperret at google.com (Quentin Perret)
Date: Tue, 10 Aug 2021 14:53:18 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <af06b333-3d8a-807c-9ccb-d491d6a54930@arm.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <af06b333-3d8a-807c-9ccb-d491d6a54930@arm.com>
Message-ID: <YRKEztjdIFU1J5/9@google.com>

On Tuesday 10 Aug 2021 at 14:25:15 (+0100), Lukasz Luba wrote:
> The way I see this is that the flag in cpufreq avoids
> mistakes potentially made by driver developer. It will automaticaly
> register the *simple* EM model via dev_pm_opp_of_register_em() on behalf
> of drivers (which is already done manually by drivers). The developer
> would just set the flag similarly to CPUFREQ_IS_COOLING_DEV and be sure
> it will register at the right time. Well tested flag approach should be
> safer, easier to understand, maintain.

I would agree with all that if calling dev_pm_opp_of_register_em() was
complicated, but that is not really the case. I don't think we ever call
PM_OPP directly from cpufreq core ATM, which makes a lot of sense if you
consider PM_OPP arch-specific. I could understand that we might accept a
little 'violation' of the abstraction with this series if there were
real benefits, but I just don't see them.


From linus.walleij at linaro.org  Tue Aug 10 06:54:11 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 10 Aug 2021 15:54:11 +0200
Subject: [RFC PATCH 4/6] leds: pca955x: Use pinctrl to map GPIOs to pins
In-Reply-To: <20210723075858.376378-5-andrew@aj.id.au>
References: <20210723075858.376378-1-andrew@aj.id.au>
 <20210723075858.376378-5-andrew@aj.id.au>
Message-ID: <CACRpkdZm9C23aHTWs8DNX1RChSB4A-X0PoyW5wnH2XyQQeviag@mail.gmail.com>

On Fri, Jul 23, 2021 at 9:59 AM Andrew Jeffery <andrew at aj.id.au> wrote:

> The leds-pca955x driver currently assumes that the GPIO numberspace and
> the pin numberspace are the same. This quickly falls apart with a
> devicetree binding such as the following:
(...)

Honestly I do not understand this patch. It seems to implement a pin
controller and using it in nonstandard ways.

If something implements the pin controller driver API it should be
used as such IMO, externally. This seems to be using it do relay
calls to itself which seems complicated, just invent something
locally in the driver in that case? No need to use pin control?

Can you explain why this LED driver needs to implement a pin
controller?

Yours,
Linus Walleij


From maz at kernel.org  Tue Aug 10 06:57:06 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 14:57:06 +0100
Subject: [EXTERNAL] Re: [RFC 1/1] irqchip/gic-v3-its: Add irq domain and
 chip for Direct LPI without ITS
In-Reply-To: <MW4PR21MB20022D4903CDD8F989C30C50C0F79@MW4PR21MB2002.namprd21.prod.outlook.com>
References: <MW4PR21MB2002BA20FA4A8DAA1C27F4C6C0199@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87a6mt2jke.wl-maz@kernel.org>
 <MW4PR21MB2002E51429F7E13B61A34FFEC0E89@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87tuka24kj.wl-maz@kernel.org>
 <MW4PR21MB20027EAC23E8053210364E2BC0F09@MW4PR21MB2002.namprd21.prod.outlook.com>
 <b2dea108-9166-dc9d-abd0-d22491f78568@arm.com>
 <87r1f9wooc.wl-maz@kernel.org>
 <MW4PR21MB2002860BAED850B2B52D6E2BC0F19@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87wnp0b86y.wl-maz@kernel.org>
 <MW4PR21MB2002ABD170CC9786CDF5D493C0F39@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87o8a81boi.wl-maz@kernel.org>
 <MW4PR21MB200286E2CF4DA229D7059598C0F69@MW4PR21MB2002.namprd21.prod.outlook.com>
 <87pmunasik.wl-maz@kernel.org>
 <MW4PR21MB20022D4903CDD8F989C30C50C0F79@MW4PR21MB2002.namprd21.prod.outlook.com>
Message-ID: <8735rhbdxp.wl-maz@kernel.org>

On Tue, 10 Aug 2021 02:10:40 +0100,
Sunil Muthuswamy <sunilmut at microsoft.com> wrote:
> 
> On Monday, August 9, 2021 2:15 AM,
> Marc Zyngier <maz at kernel.org> wrote:
> [...]
> > If you plug directly into the GICv3 layer, I'd rather you inject SPIs,
> > just like any other non-architectural MSI controller. You can directly
> > interface with the ACPI GSI layer for that, without any need to mess
> > with the GICv3 internals. The SPI space isn't very large, but still
> > much larger than the equivalent x86 space (close to 1000).
> > 
> > If time is of the essence, I suggest you go the SPI way. For anything
> > involving LPIs, I really want to see a firmware spec that works for
> > everyone as opposed to a localised Hyper-V hack.
> > 
> Ok, thanks. Before we commit to anything, I would like to make sure
> that I am on the same page in terms of your description. With that in
> mind, I have few questions. Hopefully, these should settle the matter.
> 1. If we go with the SPI route, then the way I envision it is that the 
>     Hyper-V vPCI driver will implement an IRQ chip, which will take
>     care of allocating & managing the SPI interrupt for Hyper-V vPCI.
>     This IRQ chip will parent itself to the architectural GIC IRQ chip for
>     general interrupt management. Does that match with your
>     understanding/suggestion as well?

Yes.

> 
> 2. In the above, how will Hyper-V vPCI module discover the
>     architectural GIC IRQ domain generically for virtual devices that
>     are not firmware enumerated? Today, the GIC v3 IRQ domain is
>     not exported and the general 'irq_find_xyz' APIs only work for
>     firmware enumerated devices (i.e. something that has a fwnode
>     handle).

You don't need to discover it with ACPI. You simply instantiate your
own irqdomain using acpi_irq_create_hierarchy(), which will do the
right thing. Your PCI driver will have to create its own fwnode out of
thin air (there is an API for that), and call into this function to
plumb everything.

> 
> 3. Longer term, if we implement LPIs (with an ITS or Direct LPI), to
>     be able to support all scenarios such as Live Migration, the
>     Hyper-V virtual PCI driver would like to be able to control the
>     MSI address & data that gets programmed on the device
>    (i.e. .irq_compose_msi_msg). We can use the architectural
>    methods for everything else. Does that fit into the realm of
>    what would be acceptable upstream?

I cannot see how this works. The address has to match that of the
virtual HW you target (whether this is a redistributor or an ITS), and
the data is only meaningful in that context. And it really shouldn't
matter at all, as I expect you don't let the guest directly write to
the PCI MSI-X table.

If you let the guest have access direct to that table (which seems to
contradict your "live migration" argument), then your best bet is to
use provide a skeletal IOMMU implementation, and get
iommu_dma_compose_msi_msg() to do the remapping. But frankly, that's
horrible and I fully expect the IOMMU people to push back (and that
still doesn't give you any control over the data, only the address).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From sashal at kernel.org  Tue Aug 10 07:14:42 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:14:42 -0400
Subject: [PATCH AUTOSEL 5.13 01/24] dmaengine: xilinx_dma: Fix read-after-free
 bug when terminating transfers
Message-ID: <20210810141505.3117318-1-sashal@kernel.org>

From: Adrian Larumbe <adrian.martinezlarumbe at imgtec.com>

[ Upstream commit 7dd2dd4ff9f3abda601f22b9d01441a0869d20d7 ]

When user calls dmaengine_terminate_sync, the driver will clean up any
remaining descriptors for all the pending or active transfers that had
previously been submitted. However, this might happen whilst the tasklet is
invoking the DMA callback for the last finished transfer, so by the time it
returns and takes over the channel's spinlock, the list of completed
descriptors it was traversing is no longer valid. This leads to a
read-after-free situation.

Fix it by signalling whether a user-triggered termination has happened by
means of a boolean variable.

Signed-off-by: Adrian Larumbe <adrian.martinezlarumbe at imgtec.com>
Link: https://lore.kernel.org/r/20210706234338.7696-3-adrian.martinezlarumbe at imgtec.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/dma/xilinx/xilinx_dma.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 75c0b8e904e5..4b9530a7bf65 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -394,6 +394,7 @@ struct xilinx_dma_tx_descriptor {
  * @genlock: Support genlock mode
  * @err: Channel has errors
  * @idle: Check for channel idle
+ * @terminating: Check for channel being synchronized by user
  * @tasklet: Cleanup work after irq
  * @config: Device configuration info
  * @flush_on_fsync: Flush on Frame sync
@@ -431,6 +432,7 @@ struct xilinx_dma_chan {
 	bool genlock;
 	bool err;
 	bool idle;
+	bool terminating;
 	struct tasklet_struct tasklet;
 	struct xilinx_vdma_config config;
 	bool flush_on_fsync;
@@ -1049,6 +1051,13 @@ static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
 		/* Run any dependencies, then free the descriptor */
 		dma_run_dependencies(&desc->async_tx);
 		xilinx_dma_free_tx_descriptor(chan, desc);
+
+		/*
+		 * While we ran a callback the user called a terminate function,
+		 * which takes care of cleaning up any remaining descriptors
+		 */
+		if (chan->terminating)
+			break;
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
@@ -1965,6 +1974,8 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	if (desc->cyclic)
 		chan->cyclic = true;
 
+	chan->terminating = false;
+
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	return cookie;
@@ -2436,6 +2447,7 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan)
 
 	xilinx_dma_chan_reset(chan);
 	/* Remove and free all of the descriptors in the lists */
+	chan->terminating = true;
 	xilinx_dma_free_descriptors(chan);
 	chan->idle = true;
 
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:14:55 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:14:55 -0400
Subject: [PATCH AUTOSEL 5.13 14/24] ARM: dts: nomadik: Fix up interrupt
 controller node names
In-Reply-To: <20210810141505.3117318-1-sashal@kernel.org>
References: <20210810141505.3117318-1-sashal@kernel.org>
Message-ID: <20210810141505.3117318-14-sashal@kernel.org>

From: Sudeep Holla <sudeep.holla at arm.com>

[ Upstream commit 47091f473b364c98207c4def197a0ae386fc9af1 ]

Once the new schema interrupt-controller/arm,vic.yaml is added, we get
the below warnings:

	arch/arm/boot/dts/ste-nomadik-nhk15.dt.yaml:
	intc at 10140000: $nodename:0: 'intc at 10140000' does not match
	'^interrupt-controller(@[0-9a-f,]+)*$'

Fix the node names for the interrupt controller to conform
to the standard node name interrupt-controller at ..

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20210617210825.3064367-2-sudeep.holla at arm.com
Link: https://lore.kernel.org/r/20210626000103.830184-1-linus.walleij at linaro.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index c9b906432341..1815361fe73c 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -755,14 +755,14 @@ clcd at 10120000 {
 			status = "disabled";
 		};
 
-		vica: intc at 10140000 {
+		vica: interrupt-controller at 10140000 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			reg = <0x10140000 0x20>;
 		};
 
-		vicb: intc at 10140020 {
+		vicb: interrupt-controller at 10140020 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:14:56 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:14:56 -0400
Subject: [PATCH AUTOSEL 5.13 15/24] ARM: ixp4xx: goramo_mlr depends on old PCI
 driver
In-Reply-To: <20210810141505.3117318-1-sashal@kernel.org>
References: <20210810141505.3117318-1-sashal@kernel.org>
Message-ID: <20210810141505.3117318-15-sashal@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

[ Upstream commit 796a8c85b1216618258e08b463d3bef0d7123760 ]

When this driver is disabled, the board file fails to build,
so add a dependency:

arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_preinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:472:9: error: implicit declaration of function 'ixp4xx_pci_preinit'; did you mean 'iop3xx_pci_preinit'? [-Werror=implicit-function-declaration]
  472 |         ixp4xx_pci_preinit();
      |         ^~~~~~~~~~~~~~~~~~
      |         iop3xx_pci_preinit
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_postinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:481:22: error: implicit declaration of function 'ixp4xx_pci_read' [-Werror=implicit-function-declaration]
  481 |                 if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
      |                      ^~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c:231:35: error: 'IXP4XX_UART1_BASE_PHYS' undeclared here (not in a function)
  231 |                 .start          = IXP4XX_UART1_BASE_PHYS,
      |                                   ^~~~~~~~~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_init':
arch/arm/mach-ixp4xx/goramo_mlr.c:376:9: error: implicit declaration of function 'ixp4xx_sys_init' [-Werror=implicit-function-declaration]
  376 |         ixp4xx_sys_init();
      |         ^~~~~~~~~~~~~~~

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: soc at kernel.org
Link: https://lore.kernel.org/r/20210721151620.2373500-1-arnd at kernel.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-ixp4xx/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 165c184801e1..57e61e797189 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -89,6 +89,7 @@ config MACH_IXDP465
 
 config MACH_GORAMO_MLR
 	bool "GORAMO Multi Link Router"
+	depends on IXP4XX_PCI_LEGACY
 	help
 	  Say 'Y' here if you want your kernel to support GORAMO
 	  MultiLink router.
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:15:19 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:15:19 -0400
Subject: [PATCH AUTOSEL 5.10 01/20] dmaengine: xilinx_dma: Fix read-after-free
 bug when terminating transfers
Message-ID: <20210810141538.3117707-1-sashal@kernel.org>

From: Adrian Larumbe <adrian.martinezlarumbe at imgtec.com>

[ Upstream commit 7dd2dd4ff9f3abda601f22b9d01441a0869d20d7 ]

When user calls dmaengine_terminate_sync, the driver will clean up any
remaining descriptors for all the pending or active transfers that had
previously been submitted. However, this might happen whilst the tasklet is
invoking the DMA callback for the last finished transfer, so by the time it
returns and takes over the channel's spinlock, the list of completed
descriptors it was traversing is no longer valid. This leads to a
read-after-free situation.

Fix it by signalling whether a user-triggered termination has happened by
means of a boolean variable.

Signed-off-by: Adrian Larumbe <adrian.martinezlarumbe at imgtec.com>
Link: https://lore.kernel.org/r/20210706234338.7696-3-adrian.martinezlarumbe at imgtec.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/dma/xilinx/xilinx_dma.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 79777550a6ff..9ffdbeec436b 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -394,6 +394,7 @@ struct xilinx_dma_tx_descriptor {
  * @genlock: Support genlock mode
  * @err: Channel has errors
  * @idle: Check for channel idle
+ * @terminating: Check for channel being synchronized by user
  * @tasklet: Cleanup work after irq
  * @config: Device configuration info
  * @flush_on_fsync: Flush on Frame sync
@@ -431,6 +432,7 @@ struct xilinx_dma_chan {
 	bool genlock;
 	bool err;
 	bool idle;
+	bool terminating;
 	struct tasklet_struct tasklet;
 	struct xilinx_vdma_config config;
 	bool flush_on_fsync;
@@ -1049,6 +1051,13 @@ static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
 		/* Run any dependencies, then free the descriptor */
 		dma_run_dependencies(&desc->async_tx);
 		xilinx_dma_free_tx_descriptor(chan, desc);
+
+		/*
+		 * While we ran a callback the user called a terminate function,
+		 * which takes care of cleaning up any remaining descriptors
+		 */
+		if (chan->terminating)
+			break;
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
@@ -1965,6 +1974,8 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	if (desc->cyclic)
 		chan->cyclic = true;
 
+	chan->terminating = false;
+
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	return cookie;
@@ -2436,6 +2447,7 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan)
 
 	xilinx_dma_chan_reset(chan);
 	/* Remove and free all of the descriptors in the lists */
+	chan->terminating = true;
 	xilinx_dma_free_descriptors(chan);
 	chan->idle = true;
 
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:15:32 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:15:32 -0400
Subject: [PATCH AUTOSEL 5.10 14/20] ARM: dts: nomadik: Fix up interrupt
 controller node names
In-Reply-To: <20210810141538.3117707-1-sashal@kernel.org>
References: <20210810141538.3117707-1-sashal@kernel.org>
Message-ID: <20210810141538.3117707-14-sashal@kernel.org>

From: Sudeep Holla <sudeep.holla at arm.com>

[ Upstream commit 47091f473b364c98207c4def197a0ae386fc9af1 ]

Once the new schema interrupt-controller/arm,vic.yaml is added, we get
the below warnings:

	arch/arm/boot/dts/ste-nomadik-nhk15.dt.yaml:
	intc at 10140000: $nodename:0: 'intc at 10140000' does not match
	'^interrupt-controller(@[0-9a-f,]+)*$'

Fix the node names for the interrupt controller to conform
to the standard node name interrupt-controller at ..

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20210617210825.3064367-2-sudeep.holla at arm.com
Link: https://lore.kernel.org/r/20210626000103.830184-1-linus.walleij at linaro.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index 4f38aeecadb3..42abea3ea92c 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -755,14 +755,14 @@ clcd at 10120000 {
 			status = "disabled";
 		};
 
-		vica: intc at 10140000 {
+		vica: interrupt-controller at 10140000 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			reg = <0x10140000 0x20>;
 		};
 
-		vicb: intc at 10140020 {
+		vicb: interrupt-controller at 10140020 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:15:33 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:15:33 -0400
Subject: [PATCH AUTOSEL 5.10 15/20] ARM: ixp4xx: goramo_mlr depends on old PCI
 driver
In-Reply-To: <20210810141538.3117707-1-sashal@kernel.org>
References: <20210810141538.3117707-1-sashal@kernel.org>
Message-ID: <20210810141538.3117707-15-sashal@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

[ Upstream commit 796a8c85b1216618258e08b463d3bef0d7123760 ]

When this driver is disabled, the board file fails to build,
so add a dependency:

arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_preinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:472:9: error: implicit declaration of function 'ixp4xx_pci_preinit'; did you mean 'iop3xx_pci_preinit'? [-Werror=implicit-function-declaration]
  472 |         ixp4xx_pci_preinit();
      |         ^~~~~~~~~~~~~~~~~~
      |         iop3xx_pci_preinit
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_postinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:481:22: error: implicit declaration of function 'ixp4xx_pci_read' [-Werror=implicit-function-declaration]
  481 |                 if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
      |                      ^~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c:231:35: error: 'IXP4XX_UART1_BASE_PHYS' undeclared here (not in a function)
  231 |                 .start          = IXP4XX_UART1_BASE_PHYS,
      |                                   ^~~~~~~~~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_init':
arch/arm/mach-ixp4xx/goramo_mlr.c:376:9: error: implicit declaration of function 'ixp4xx_sys_init' [-Werror=implicit-function-declaration]
  376 |         ixp4xx_sys_init();
      |         ^~~~~~~~~~~~~~~

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: soc at kernel.org
Link: https://lore.kernel.org/r/20210721151620.2373500-1-arnd at kernel.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-ixp4xx/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 165c184801e1..57e61e797189 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -89,6 +89,7 @@ config MACH_IXDP465
 
 config MACH_GORAMO_MLR
 	bool "GORAMO Multi Link Router"
+	depends on IXP4XX_PCI_LEGACY
 	help
 	  Say 'Y' here if you want your kernel to support GORAMO
 	  MultiLink router.
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:15:53 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:15:53 -0400
Subject: [PATCH AUTOSEL 5.4 01/13] dmaengine: xilinx_dma: Fix read-after-free
 bug when terminating transfers
Message-ID: <20210810141606.3117932-1-sashal@kernel.org>

From: Adrian Larumbe <adrian.martinezlarumbe at imgtec.com>

[ Upstream commit 7dd2dd4ff9f3abda601f22b9d01441a0869d20d7 ]

When user calls dmaengine_terminate_sync, the driver will clean up any
remaining descriptors for all the pending or active transfers that had
previously been submitted. However, this might happen whilst the tasklet is
invoking the DMA callback for the last finished transfer, so by the time it
returns and takes over the channel's spinlock, the list of completed
descriptors it was traversing is no longer valid. This leads to a
read-after-free situation.

Fix it by signalling whether a user-triggered termination has happened by
means of a boolean variable.

Signed-off-by: Adrian Larumbe <adrian.martinezlarumbe at imgtec.com>
Link: https://lore.kernel.org/r/20210706234338.7696-3-adrian.martinezlarumbe at imgtec.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/dma/xilinx/xilinx_dma.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 1b5f3e9f43d7..ce18bca45ff2 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -333,6 +333,7 @@ struct xilinx_dma_tx_descriptor {
  * @genlock: Support genlock mode
  * @err: Channel has errors
  * @idle: Check for channel idle
+ * @terminating: Check for channel being synchronized by user
  * @tasklet: Cleanup work after irq
  * @config: Device configuration info
  * @flush_on_fsync: Flush on Frame sync
@@ -370,6 +371,7 @@ struct xilinx_dma_chan {
 	bool genlock;
 	bool err;
 	bool idle;
+	bool terminating;
 	struct tasklet_struct tasklet;
 	struct xilinx_vdma_config config;
 	bool flush_on_fsync;
@@ -844,6 +846,13 @@ static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
 		/* Run any dependencies, then free the descriptor */
 		dma_run_dependencies(&desc->async_tx);
 		xilinx_dma_free_tx_descriptor(chan, desc);
+
+		/*
+		 * While we ran a callback the user called a terminate function,
+		 * which takes care of cleaning up any remaining descriptors
+		 */
+		if (chan->terminating)
+			break;
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
@@ -1618,6 +1627,8 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	if (desc->cyclic)
 		chan->cyclic = true;
 
+	chan->terminating = false;
+
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	return cookie;
@@ -2074,6 +2085,7 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan)
 	}
 
 	/* Remove and free all of the descriptors in the lists */
+	chan->terminating = true;
 	xilinx_dma_free_descriptors(chan);
 	chan->idle = true;
 
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:01 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:01 -0400
Subject: [PATCH AUTOSEL 5.4 09/13] ARM: dts: nomadik: Fix up interrupt
 controller node names
In-Reply-To: <20210810141606.3117932-1-sashal@kernel.org>
References: <20210810141606.3117932-1-sashal@kernel.org>
Message-ID: <20210810141606.3117932-9-sashal@kernel.org>

From: Sudeep Holla <sudeep.holla at arm.com>

[ Upstream commit 47091f473b364c98207c4def197a0ae386fc9af1 ]

Once the new schema interrupt-controller/arm,vic.yaml is added, we get
the below warnings:

	arch/arm/boot/dts/ste-nomadik-nhk15.dt.yaml:
	intc at 10140000: $nodename:0: 'intc at 10140000' does not match
	'^interrupt-controller(@[0-9a-f,]+)*$'

Fix the node names for the interrupt controller to conform
to the standard node name interrupt-controller at ..

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20210617210825.3064367-2-sudeep.holla at arm.com
Link: https://lore.kernel.org/r/20210626000103.830184-1-linus.walleij at linaro.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index f78b4eabd68c..e7178a6db6be 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -755,14 +755,14 @@ clcd at 10120000 {
 			status = "disabled";
 		};
 
-		vica: intc at 10140000 {
+		vica: interrupt-controller at 10140000 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			reg = <0x10140000 0x20>;
 		};
 
-		vicb: intc at 10140020 {
+		vicb: interrupt-controller at 10140020 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:02 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:02 -0400
Subject: [PATCH AUTOSEL 5.4 10/13] ARM: ixp4xx: goramo_mlr depends on old PCI
 driver
In-Reply-To: <20210810141606.3117932-1-sashal@kernel.org>
References: <20210810141606.3117932-1-sashal@kernel.org>
Message-ID: <20210810141606.3117932-10-sashal@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

[ Upstream commit 796a8c85b1216618258e08b463d3bef0d7123760 ]

When this driver is disabled, the board file fails to build,
so add a dependency:

arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_preinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:472:9: error: implicit declaration of function 'ixp4xx_pci_preinit'; did you mean 'iop3xx_pci_preinit'? [-Werror=implicit-function-declaration]
  472 |         ixp4xx_pci_preinit();
      |         ^~~~~~~~~~~~~~~~~~
      |         iop3xx_pci_preinit
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_postinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:481:22: error: implicit declaration of function 'ixp4xx_pci_read' [-Werror=implicit-function-declaration]
  481 |                 if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
      |                      ^~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c:231:35: error: 'IXP4XX_UART1_BASE_PHYS' undeclared here (not in a function)
  231 |                 .start          = IXP4XX_UART1_BASE_PHYS,
      |                                   ^~~~~~~~~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_init':
arch/arm/mach-ixp4xx/goramo_mlr.c:376:9: error: implicit declaration of function 'ixp4xx_sys_init' [-Werror=implicit-function-declaration]
  376 |         ixp4xx_sys_init();
      |         ^~~~~~~~~~~~~~~

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: soc at kernel.org
Link: https://lore.kernel.org/r/20210721151620.2373500-1-arnd at kernel.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-ixp4xx/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 165c184801e1..57e61e797189 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -89,6 +89,7 @@ config MACH_IXDP465
 
 config MACH_GORAMO_MLR
 	bool "GORAMO Multi Link Router"
+	depends on IXP4XX_PCI_LEGACY
 	help
 	  Say 'Y' here if you want your kernel to support GORAMO
 	  MultiLink router.
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:14 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:14 -0400
Subject: [PATCH AUTOSEL 4.19 01/11] dmaengine: xilinx_dma: Fix read-after-free
 bug when terminating transfers
Message-ID: <20210810141625.3118097-1-sashal@kernel.org>

From: Adrian Larumbe <adrian.martinezlarumbe at imgtec.com>

[ Upstream commit 7dd2dd4ff9f3abda601f22b9d01441a0869d20d7 ]

When user calls dmaengine_terminate_sync, the driver will clean up any
remaining descriptors for all the pending or active transfers that had
previously been submitted. However, this might happen whilst the tasklet is
invoking the DMA callback for the last finished transfer, so by the time it
returns and takes over the channel's spinlock, the list of completed
descriptors it was traversing is no longer valid. This leads to a
read-after-free situation.

Fix it by signalling whether a user-triggered termination has happened by
means of a boolean variable.

Signed-off-by: Adrian Larumbe <adrian.martinezlarumbe at imgtec.com>
Link: https://lore.kernel.org/r/20210706234338.7696-3-adrian.martinezlarumbe at imgtec.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/dma/xilinx/xilinx_dma.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 0c5668e897fe..d891ec05bc48 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -332,6 +332,7 @@ struct xilinx_dma_tx_descriptor {
  * @genlock: Support genlock mode
  * @err: Channel has errors
  * @idle: Check for channel idle
+ * @terminating: Check for channel being synchronized by user
  * @tasklet: Cleanup work after irq
  * @config: Device configuration info
  * @flush_on_fsync: Flush on Frame sync
@@ -369,6 +370,7 @@ struct xilinx_dma_chan {
 	bool genlock;
 	bool err;
 	bool idle;
+	bool terminating;
 	struct tasklet_struct tasklet;
 	struct xilinx_vdma_config config;
 	bool flush_on_fsync;
@@ -843,6 +845,13 @@ static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
 		/* Run any dependencies, then free the descriptor */
 		dma_run_dependencies(&desc->async_tx);
 		xilinx_dma_free_tx_descriptor(chan, desc);
+
+		/*
+		 * While we ran a callback the user called a terminate function,
+		 * which takes care of cleaning up any remaining descriptors
+		 */
+		if (chan->terminating)
+			break;
 	}
 
 	spin_unlock_irqrestore(&chan->lock, flags);
@@ -1612,6 +1621,8 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
 	if (desc->cyclic)
 		chan->cyclic = true;
 
+	chan->terminating = false;
+
 	spin_unlock_irqrestore(&chan->lock, flags);
 
 	return cookie;
@@ -2068,6 +2079,7 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan)
 	}
 
 	/* Remove and free all of the descriptors in the lists */
+	chan->terminating = true;
 	xilinx_dma_free_descriptors(chan);
 	chan->idle = true;
 
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:21 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:21 -0400
Subject: [PATCH AUTOSEL 4.19 08/11] ARM: dts: nomadik: Fix up interrupt
 controller node names
In-Reply-To: <20210810141625.3118097-1-sashal@kernel.org>
References: <20210810141625.3118097-1-sashal@kernel.org>
Message-ID: <20210810141625.3118097-8-sashal@kernel.org>

From: Sudeep Holla <sudeep.holla at arm.com>

[ Upstream commit 47091f473b364c98207c4def197a0ae386fc9af1 ]

Once the new schema interrupt-controller/arm,vic.yaml is added, we get
the below warnings:

	arch/arm/boot/dts/ste-nomadik-nhk15.dt.yaml:
	intc at 10140000: $nodename:0: 'intc at 10140000' does not match
	'^interrupt-controller(@[0-9a-f,]+)*$'

Fix the node names for the interrupt controller to conform
to the standard node name interrupt-controller at ..

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20210617210825.3064367-2-sudeep.holla at arm.com
Link: https://lore.kernel.org/r/20210626000103.830184-1-linus.walleij at linaro.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index fca76a696d9d..9ba4d1630ca3 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -755,14 +755,14 @@ clcd at 10120000 {
 			status = "disabled";
 		};
 
-		vica: intc at 10140000 {
+		vica: interrupt-controller at 10140000 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			reg = <0x10140000 0x20>;
 		};
 
-		vicb: intc at 10140020 {
+		vicb: interrupt-controller at 10140020 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:22 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:22 -0400
Subject: [PATCH AUTOSEL 4.19 09/11] ARM: ixp4xx: goramo_mlr depends on old PCI
 driver
In-Reply-To: <20210810141625.3118097-1-sashal@kernel.org>
References: <20210810141625.3118097-1-sashal@kernel.org>
Message-ID: <20210810141625.3118097-9-sashal@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

[ Upstream commit 796a8c85b1216618258e08b463d3bef0d7123760 ]

When this driver is disabled, the board file fails to build,
so add a dependency:

arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_preinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:472:9: error: implicit declaration of function 'ixp4xx_pci_preinit'; did you mean 'iop3xx_pci_preinit'? [-Werror=implicit-function-declaration]
  472 |         ixp4xx_pci_preinit();
      |         ^~~~~~~~~~~~~~~~~~
      |         iop3xx_pci_preinit
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_postinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:481:22: error: implicit declaration of function 'ixp4xx_pci_read' [-Werror=implicit-function-declaration]
  481 |                 if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
      |                      ^~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c:231:35: error: 'IXP4XX_UART1_BASE_PHYS' undeclared here (not in a function)
  231 |                 .start          = IXP4XX_UART1_BASE_PHYS,
      |                                   ^~~~~~~~~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_init':
arch/arm/mach-ixp4xx/goramo_mlr.c:376:9: error: implicit declaration of function 'ixp4xx_sys_init' [-Werror=implicit-function-declaration]
  376 |         ixp4xx_sys_init();
      |         ^~~~~~~~~~~~~~~

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: soc at kernel.org
Link: https://lore.kernel.org/r/20210721151620.2373500-1-arnd at kernel.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-ixp4xx/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index c342dc4e8a45..2489b6151ace 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -76,6 +76,7 @@ config MACH_IXDP465
 
 config MACH_GORAMO_MLR
 	bool "GORAMO Multi Link Router"
+	depends on IXP4XX_PCI_LEGACY
 	help
 	  Say 'Y' here if you want your kernel to support GORAMO
 	  MultiLink router.
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:38 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:38 -0400
Subject: [PATCH AUTOSEL 4.14 07/10] ARM: dts: nomadik: Fix up interrupt
 controller node names
In-Reply-To: <20210810141641.3118360-1-sashal@kernel.org>
References: <20210810141641.3118360-1-sashal@kernel.org>
Message-ID: <20210810141641.3118360-7-sashal@kernel.org>

From: Sudeep Holla <sudeep.holla at arm.com>

[ Upstream commit 47091f473b364c98207c4def197a0ae386fc9af1 ]

Once the new schema interrupt-controller/arm,vic.yaml is added, we get
the below warnings:

	arch/arm/boot/dts/ste-nomadik-nhk15.dt.yaml:
	intc at 10140000: $nodename:0: 'intc at 10140000' does not match
	'^interrupt-controller(@[0-9a-f,]+)*$'

Fix the node names for the interrupt controller to conform
to the standard node name interrupt-controller at ..

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20210617210825.3064367-2-sudeep.holla at arm.com
Link: https://lore.kernel.org/r/20210626000103.830184-1-linus.walleij at linaro.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index 733678b75b88..ad3cdf2ca7fb 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -756,14 +756,14 @@ clcd at 10120000 {
 			status = "disabled";
 		};
 
-		vica: intc at 10140000 {
+		vica: interrupt-controller at 10140000 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			reg = <0x10140000 0x20>;
 		};
 
-		vicb: intc at 10140020 {
+		vicb: interrupt-controller at 10140020 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:39 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:39 -0400
Subject: [PATCH AUTOSEL 4.14 08/10] ARM: ixp4xx: goramo_mlr depends on old PCI
 driver
In-Reply-To: <20210810141641.3118360-1-sashal@kernel.org>
References: <20210810141641.3118360-1-sashal@kernel.org>
Message-ID: <20210810141641.3118360-8-sashal@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

[ Upstream commit 796a8c85b1216618258e08b463d3bef0d7123760 ]

When this driver is disabled, the board file fails to build,
so add a dependency:

arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_preinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:472:9: error: implicit declaration of function 'ixp4xx_pci_preinit'; did you mean 'iop3xx_pci_preinit'? [-Werror=implicit-function-declaration]
  472 |         ixp4xx_pci_preinit();
      |         ^~~~~~~~~~~~~~~~~~
      |         iop3xx_pci_preinit
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_postinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:481:22: error: implicit declaration of function 'ixp4xx_pci_read' [-Werror=implicit-function-declaration]
  481 |                 if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
      |                      ^~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c:231:35: error: 'IXP4XX_UART1_BASE_PHYS' undeclared here (not in a function)
  231 |                 .start          = IXP4XX_UART1_BASE_PHYS,
      |                                   ^~~~~~~~~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_init':
arch/arm/mach-ixp4xx/goramo_mlr.c:376:9: error: implicit declaration of function 'ixp4xx_sys_init' [-Werror=implicit-function-declaration]
  376 |         ixp4xx_sys_init();
      |         ^~~~~~~~~~~~~~~

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: soc at kernel.org
Link: https://lore.kernel.org/r/20210721151620.2373500-1-arnd at kernel.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-ixp4xx/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index c342dc4e8a45..2489b6151ace 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -76,6 +76,7 @@ config MACH_IXDP465
 
 config MACH_GORAMO_MLR
 	bool "GORAMO Multi Link Router"
+	depends on IXP4XX_PCI_LEGACY
 	help
 	  Say 'Y' here if you want your kernel to support GORAMO
 	  MultiLink router.
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:54 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:54 -0400
Subject: [PATCH AUTOSEL 4.9 7/8] ARM: dts: nomadik: Fix up interrupt
 controller node names
In-Reply-To: <20210810141655.3118498-1-sashal@kernel.org>
References: <20210810141655.3118498-1-sashal@kernel.org>
Message-ID: <20210810141655.3118498-7-sashal@kernel.org>

From: Sudeep Holla <sudeep.holla at arm.com>

[ Upstream commit 47091f473b364c98207c4def197a0ae386fc9af1 ]

Once the new schema interrupt-controller/arm,vic.yaml is added, we get
the below warnings:

	arch/arm/boot/dts/ste-nomadik-nhk15.dt.yaml:
	intc at 10140000: $nodename:0: 'intc at 10140000' does not match
	'^interrupt-controller(@[0-9a-f,]+)*$'

Fix the node names for the interrupt controller to conform
to the standard node name interrupt-controller at ..

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20210617210825.3064367-2-sudeep.holla at arm.com
Link: https://lore.kernel.org/r/20210626000103.830184-1-linus.walleij at linaro.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index 1077ceebb2d6..87494773f409 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -755,14 +755,14 @@ clcd at 10120000 {
 			status = "disabled";
 		};
 
-		vica: intc at 10140000 {
+		vica: interrupt-controller at 10140000 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
 			reg = <0x10140000 0x20>;
 		};
 
-		vicb: intc at 10140020 {
+		vicb: interrupt-controller at 10140020 {
 			compatible = "arm,versatile-vic";
 			interrupt-controller;
 			#interrupt-cells = <1>;
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:16:55 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:16:55 -0400
Subject: [PATCH AUTOSEL 4.9 8/8] ARM: ixp4xx: goramo_mlr depends on old PCI
 driver
In-Reply-To: <20210810141655.3118498-1-sashal@kernel.org>
References: <20210810141655.3118498-1-sashal@kernel.org>
Message-ID: <20210810141655.3118498-8-sashal@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

[ Upstream commit 796a8c85b1216618258e08b463d3bef0d7123760 ]

When this driver is disabled, the board file fails to build,
so add a dependency:

arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_preinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:472:9: error: implicit declaration of function 'ixp4xx_pci_preinit'; did you mean 'iop3xx_pci_preinit'? [-Werror=implicit-function-declaration]
  472 |         ixp4xx_pci_preinit();
      |         ^~~~~~~~~~~~~~~~~~
      |         iop3xx_pci_preinit
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_postinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:481:22: error: implicit declaration of function 'ixp4xx_pci_read' [-Werror=implicit-function-declaration]
  481 |                 if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
      |                      ^~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c:231:35: error: 'IXP4XX_UART1_BASE_PHYS' undeclared here (not in a function)
  231 |                 .start          = IXP4XX_UART1_BASE_PHYS,
      |                                   ^~~~~~~~~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_init':
arch/arm/mach-ixp4xx/goramo_mlr.c:376:9: error: implicit declaration of function 'ixp4xx_sys_init' [-Werror=implicit-function-declaration]
  376 |         ixp4xx_sys_init();
      |         ^~~~~~~~~~~~~~~

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: soc at kernel.org
Link: https://lore.kernel.org/r/20210721151620.2373500-1-arnd at kernel.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-ixp4xx/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index c342dc4e8a45..2489b6151ace 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -76,6 +76,7 @@ config MACH_IXDP465
 
 config MACH_GORAMO_MLR
 	bool "GORAMO Multi Link Router"
+	depends on IXP4XX_PCI_LEGACY
 	help
 	  Say 'Y' here if you want your kernel to support GORAMO
 	  MultiLink router.
-- 
2.30.2



From sashal at kernel.org  Tue Aug 10 07:17:07 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 10 Aug 2021 10:17:07 -0400
Subject: [PATCH AUTOSEL 4.4 6/6] ARM: ixp4xx: goramo_mlr depends on old PCI
 driver
In-Reply-To: <20210810141707.3118714-1-sashal@kernel.org>
References: <20210810141707.3118714-1-sashal@kernel.org>
Message-ID: <20210810141707.3118714-6-sashal@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

[ Upstream commit 796a8c85b1216618258e08b463d3bef0d7123760 ]

When this driver is disabled, the board file fails to build,
so add a dependency:

arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_preinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:472:9: error: implicit declaration of function 'ixp4xx_pci_preinit'; did you mean 'iop3xx_pci_preinit'? [-Werror=implicit-function-declaration]
  472 |         ixp4xx_pci_preinit();
      |         ^~~~~~~~~~~~~~~~~~
      |         iop3xx_pci_preinit
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_pci_postinit':
arch/arm/mach-ixp4xx/goramo_mlr.c:481:22: error: implicit declaration of function 'ixp4xx_pci_read' [-Werror=implicit-function-declaration]
  481 |                 if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
      |                      ^~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c:231:35: error: 'IXP4XX_UART1_BASE_PHYS' undeclared here (not in a function)
  231 |                 .start          = IXP4XX_UART1_BASE_PHYS,
      |                                   ^~~~~~~~~~~~~~~~~~~~~~
arch/arm/mach-ixp4xx/goramo_mlr.c: In function 'gmlr_init':
arch/arm/mach-ixp4xx/goramo_mlr.c:376:9: error: implicit declaration of function 'ixp4xx_sys_init' [-Werror=implicit-function-declaration]
  376 |         ixp4xx_sys_init();
      |         ^~~~~~~~~~~~~~~

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: soc at kernel.org
Link: https://lore.kernel.org/r/20210721151620.2373500-1-arnd at kernel.org'
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-ixp4xx/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index c342dc4e8a45..2489b6151ace 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -76,6 +76,7 @@ config MACH_IXDP465
 
 config MACH_GORAMO_MLR
 	bool "GORAMO Multi Link Router"
+	depends on IXP4XX_PCI_LEGACY
 	help
 	  Say 'Y' here if you want your kernel to support GORAMO
 	  MultiLink router.
-- 
2.30.2



From tglx at linutronix.de  Tue Aug 10 07:21:01 2021
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 10 Aug 2021 16:21:01 +0200
Subject: [PATCH 1/1] genirq/cpuhotplug: Bump debugging information print
 down to KERN_DEBUG
In-Reply-To: <20210617073136.315723-1-lee.jones@linaro.org>
Message-ID: <8735rhs7n6.ffs@tglx>

On Thu, Jun 17 2021 at 08:31, Lee Jones wrote:
> This sort of information is only generally useful when debugging.
>
> No need to have these sprinkled through the kernel log otherwise.

Yes and no. 

> Cc: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---
>  kernel/irq/cpuhotplug.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c
> index 02236b13b3599..cf8d4f75632e8 100644
> --- a/kernel/irq/cpuhotplug.c
> +++ b/kernel/irq/cpuhotplug.c
> @@ -42,7 +42,7 @@ static inline bool irq_needs_fixup(struct irq_data *d)
>  		 * If this happens then there was a missed IRQ fixup at some
>  		 * point. Warn about it and enforce fixup.
>  		 */
> -		pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",

This one is clearly a warning as this should not happen. See the
comments around that.

> +		pr_debug("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",
>  			cpumask_pr_args(m), d->irq, cpu);
>  		return true;
>  	}
> @@ -166,7 +166,7 @@ void irq_migrate_all_off_this_cpu(void)
>  		raw_spin_unlock(&desc->lock);
>  
>  		if (affinity_broken) {
> -			pr_warn_ratelimited("IRQ %u: no longer affine to CPU%u\n",
> +			pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n",
>  					    irq, smp_processor_id());

Maybe, but distro people might have opinions on that.

Thanks,

        tglx


From sdonthineni at nvidia.com  Tue Aug 10 07:31:30 2021
From: sdonthineni at nvidia.com (Shanker R Donthineni)
Date: Tue, 10 Aug 2021 09:31:30 -0500
Subject: [PATCH 3/3] PCI/ACPI: Add new quirk detection, enable bcm2711
In-Reply-To: <20210805211200.491275-4-jeremy.linton@arm.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
 <20210805211200.491275-4-jeremy.linton@arm.com>
Message-ID: <b574f9bb-72f3-72cd-9a6a-f1f4d998afda@nvidia.com>

Hi Jeremy,

On 8/5/21 4:12 PM, Jeremy Linton wrote:
> Now that we have a bcm2711 quirk, we need to be able to
> detect it when the MCFG is missing. Use a namespace
> property as an alternative to the MCFG OEM.
>
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  drivers/acpi/pci_mcfg.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
> index 53cab975f612..7d77fc72c2a4 100644
> --- a/drivers/acpi/pci_mcfg.c
> +++ b/drivers/acpi/pci_mcfg.c
> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>         ALTRA_ECAM_QUIRK(1, 13),
>         ALTRA_ECAM_QUIRK(1, 14),
>         ALTRA_ECAM_QUIRK(1, 15),
> +
> +       { "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
> +         DEFINE_RES_MEM(0xFD500000, 0xA000) },
>  };
>
>  static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
> @@ -198,8 +201,19 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
>         u16 segment = root->segment;
>         struct resource *bus_range = &root->secondary;
>         struct mcfg_fixup *f;
> +       const char *soc;
>         int i;
>
> +       /*
> +        * This could be a machine with a PCI/SMC conduit,
> +        * which means it doens't have MCFG. Get the machineid from
> +        * the namespace definition instead.
> +        */
> +       if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
> +                                        "linux,pcie-quirk", &soc)) {
> +               memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
> +       }
> +

Is there any specific reason for not using the firmware agnostic API to get properties?
?

 if (!device_property_read_string(root->device, "linux,pcie-quirk", &soc)) {
     memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
 }




From andrew at lunn.ch  Tue Aug 10 07:32:57 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 10 Aug 2021 16:32:57 +0200
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
 <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
Message-ID: <YRKOGYwx1uVdsKoF@lunn.ch>

> > > 1) FEC controller has up to 4 interrupt lines and all of these are routed to GIC
> > interrupt controller.
> > > 2) FEC has a wakeup interrupt signal and always are mixed with other
> > interrupt signals, and then output to one interrupt line.
> > > 3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but for i.MX8M
> > serials, are mixed to int2 line.

So you need to know which of the interrupts listed is the wake up
interrupt.

I can see a few ways to do this:

The FEC driver already has quirks. Add a quirk to fec_imx8mq_info and
fec_imx8qm_info to indicate these should use int2.

or

Documentation/devicetree/bindings/interrupt-controller/interrupts.txt 

  b) two cells
  ------------
  The #interrupt-cells property is set to 2 and the first cell defines the
  index of the interrupt within the controller, while the second cell is used
  to specify any of the following flags:
    - bits[3:0] trigger type and level flags
        1 = low-to-high edge triggered
        2 = high-to-low edge triggered
        4 = active high level-sensitive
        8 = active low level-sensitive

You could add

       18 = wakeup source

and extend to core to either do all the work for you, or tell you this
interrupt is flagged as being a wakeup source. This solution has the
advantage of it should be usable in other drivers.

	  Andrew


From jeremy.linton at arm.com  Tue Aug 10 07:47:12 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Tue, 10 Aug 2021 09:47:12 -0500
Subject: [PATCH 3/3] PCI/ACPI: Add new quirk detection, enable bcm2711
In-Reply-To: <b574f9bb-72f3-72cd-9a6a-f1f4d998afda@nvidia.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
 <20210805211200.491275-4-jeremy.linton@arm.com>
 <b574f9bb-72f3-72cd-9a6a-f1f4d998afda@nvidia.com>
Message-ID: <1ed33f6e-fbfb-e8a0-741e-6961f9a7072b@arm.com>

Hi,

Thanks for looking at this!

On 8/10/21 9:31 AM, Shanker R Donthineni wrote:
> Hi Jeremy,
> 
> On 8/5/21 4:12 PM, Jeremy Linton wrote:
>> Now that we have a bcm2711 quirk, we need to be able to
>> detect it when the MCFG is missing. Use a namespace
>> property as an alternative to the MCFG OEM.
>>
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>>   drivers/acpi/pci_mcfg.c | 14 ++++++++++++++
>>   1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
>> index 53cab975f612..7d77fc72c2a4 100644
>> --- a/drivers/acpi/pci_mcfg.c
>> +++ b/drivers/acpi/pci_mcfg.c
>> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>>          ALTRA_ECAM_QUIRK(1, 13),
>>          ALTRA_ECAM_QUIRK(1, 14),
>>          ALTRA_ECAM_QUIRK(1, 15),
>> +
>> +       { "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
>> +         DEFINE_RES_MEM(0xFD500000, 0xA000) },
>>   };
>>
>>   static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
>> @@ -198,8 +201,19 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
>>          u16 segment = root->segment;
>>          struct resource *bus_range = &root->secondary;
>>          struct mcfg_fixup *f;
>> +       const char *soc;
>>          int i;
>>
>> +       /*
>> +        * This could be a machine with a PCI/SMC conduit,
>> +        * which means it doens't have MCFG. Get the machineid from
>> +        * the namespace definition instead.
>> +        */
>> +       if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
>> +                                        "linux,pcie-quirk", &soc)) {
>> +               memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
>> +       }
>> +
> 
> Is there any specific reason for not using the firmware agnostic API to get properties?
>   
> 
>   if (!device_property_read_string(root->device, "linux,pcie-quirk", &soc)) {
>       memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
>   }
> 
> 

IIRC it was because the "device" here isn't a struct device, rather a 
struct acpi_device. I think this is the normal way in this situation 
since we are directly picking up the fwnode rather than finding a 
generic node and then backtracking to get the fwnode.



From matthias.bgg at gmail.com  Tue Aug 10 07:49:28 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 10 Aug 2021 16:49:28 +0200
Subject: [PATCH v3 1/2] arm64: dts: mt8183: add audio node
In-Reply-To: <20210706190111.v3.1.I88a52644e47e88b15f5db9841cb084dc53c5875c@changeid>
References: <20210706100136.1205047-1-kansho@chromium.org>
 <20210706190111.v3.1.I88a52644e47e88b15f5db9841cb084dc53c5875c@changeid>
Message-ID: <3db268d2-b662-8fd4-d6dd-0679fa010b71@gmail.com>



On 06/07/2021 12:01, Kansho Nishida wrote:
> Add afe (audio front end) device node to the MT8183 dtsi.
> 
> Signed-off-by: Kansho Nishida <kansho at chromium.org>

Now queued in v5.15-tmp/dts64

Please submit a patch to update the binding description. Maybe we should think
of merging the two binding descriptions into one (clock and audio part).

Regards,
Matthias

> ---
> 
> Changes in v3:
> - Use audio-controller as the audio node instead.
> 
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi | 94 +++++++++++++++++++++++-
>  1 file changed, 93 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> index f90df6439c08..af895921700c 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> @@ -1115,10 +1115,102 @@ usb_host: usb at 11200000 {
>  			};
>  		};
>  
> -		audiosys: syscon at 11220000 {
> +		audiosys: audio-controller at 11220000 {
>  			compatible = "mediatek,mt8183-audiosys", "syscon";
>  			reg = <0 0x11220000 0 0x1000>;
>  			#clock-cells = <1>;
> +			afe: mt8183-afe-pcm {
> +				compatible = "mediatek,mt8183-audio";
> +				interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_LOW>;
> +				resets = <&watchdog MT8183_TOPRGU_AUDIO_SW_RST>;
> +				reset-names = "audiosys";
> +				power-domains =
> +					<&spm MT8183_POWER_DOMAIN_AUDIO>;
> +				clocks = <&audiosys CLK_AUDIO_AFE>,
> +					 <&audiosys CLK_AUDIO_DAC>,
> +					 <&audiosys CLK_AUDIO_DAC_PREDIS>,
> +					 <&audiosys CLK_AUDIO_ADC>,
> +					 <&audiosys CLK_AUDIO_PDN_ADDA6_ADC>,
> +					 <&audiosys CLK_AUDIO_22M>,
> +					 <&audiosys CLK_AUDIO_24M>,
> +					 <&audiosys CLK_AUDIO_APLL_TUNER>,
> +					 <&audiosys CLK_AUDIO_APLL2_TUNER>,
> +					 <&audiosys CLK_AUDIO_I2S1>,
> +					 <&audiosys CLK_AUDIO_I2S2>,
> +					 <&audiosys CLK_AUDIO_I2S3>,
> +					 <&audiosys CLK_AUDIO_I2S4>,
> +					 <&audiosys CLK_AUDIO_TDM>,
> +					 <&audiosys CLK_AUDIO_TML>,
> +					 <&infracfg CLK_INFRA_AUDIO>,
> +					 <&infracfg CLK_INFRA_AUDIO_26M_BCLK>,
> +					 <&topckgen CLK_TOP_MUX_AUDIO>,
> +					 <&topckgen CLK_TOP_MUX_AUD_INTBUS>,
> +					 <&topckgen CLK_TOP_SYSPLL_D2_D4>,
> +					 <&topckgen CLK_TOP_MUX_AUD_1>,
> +					 <&topckgen CLK_TOP_APLL1_CK>,
> +					 <&topckgen CLK_TOP_MUX_AUD_2>,
> +					 <&topckgen CLK_TOP_APLL2_CK>,
> +					 <&topckgen CLK_TOP_MUX_AUD_ENG1>,
> +					 <&topckgen CLK_TOP_APLL1_D8>,
> +					 <&topckgen CLK_TOP_MUX_AUD_ENG2>,
> +					 <&topckgen CLK_TOP_APLL2_D8>,
> +					 <&topckgen CLK_TOP_MUX_APLL_I2S0>,
> +					 <&topckgen CLK_TOP_MUX_APLL_I2S1>,
> +					 <&topckgen CLK_TOP_MUX_APLL_I2S2>,
> +					 <&topckgen CLK_TOP_MUX_APLL_I2S3>,
> +					 <&topckgen CLK_TOP_MUX_APLL_I2S4>,
> +					 <&topckgen CLK_TOP_MUX_APLL_I2S5>,
> +					 <&topckgen CLK_TOP_APLL12_DIV0>,
> +					 <&topckgen CLK_TOP_APLL12_DIV1>,
> +					 <&topckgen CLK_TOP_APLL12_DIV2>,
> +					 <&topckgen CLK_TOP_APLL12_DIV3>,
> +					 <&topckgen CLK_TOP_APLL12_DIV4>,
> +					 <&topckgen CLK_TOP_APLL12_DIVB>,
> +					 /*<&topckgen CLK_TOP_APLL12_DIV5>,*/
> +					 <&clk26m>;
> +				clock-names = "aud_afe_clk",
> +						  "aud_dac_clk",
> +						  "aud_dac_predis_clk",
> +						  "aud_adc_clk",
> +						  "aud_adc_adda6_clk",
> +						  "aud_apll22m_clk",
> +						  "aud_apll24m_clk",
> +						  "aud_apll1_tuner_clk",
> +						  "aud_apll2_tuner_clk",
> +						  "aud_i2s1_bclk_sw",
> +						  "aud_i2s2_bclk_sw",
> +						  "aud_i2s3_bclk_sw",
> +						  "aud_i2s4_bclk_sw",
> +						  "aud_tdm_clk",
> +						  "aud_tml_clk",
> +						  "aud_infra_clk",
> +						  "mtkaif_26m_clk",
> +						  "top_mux_audio",
> +						  "top_mux_aud_intbus",
> +						  "top_syspll_d2_d4",
> +						  "top_mux_aud_1",
> +						  "top_apll1_ck",
> +						  "top_mux_aud_2",
> +						  "top_apll2_ck",
> +						  "top_mux_aud_eng1",
> +						  "top_apll1_d8",
> +						  "top_mux_aud_eng2",
> +						  "top_apll2_d8",
> +						  "top_i2s0_m_sel",
> +						  "top_i2s1_m_sel",
> +						  "top_i2s2_m_sel",
> +						  "top_i2s3_m_sel",
> +						  "top_i2s4_m_sel",
> +						  "top_i2s5_m_sel",
> +						  "top_apll12_div0",
> +						  "top_apll12_div1",
> +						  "top_apll12_div2",
> +						  "top_apll12_div3",
> +						  "top_apll12_div4",
> +						  "top_apll12_divb",
> +						  /*"top_apll12_div5",*/
> +						  "top_clk26m_clk";
> +			};
>  		};
>  
>  		mmc0: mmc at 11230000 {
> 


From matthias.bgg at gmail.com  Tue Aug 10 07:49:55 2021
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 10 Aug 2021 16:49:55 +0200
Subject: [PATCH v3 2/2] arm64: dts: mt8183: add kukui platform audio node
In-Reply-To: <20210706190111.v3.2.I6e9ce0f2a489f9a52299656cd966b38ae75e7552@changeid>
References: <20210706100136.1205047-1-kansho@chromium.org>
 <20210706190111.v3.2.I6e9ce0f2a489f9a52299656cd966b38ae75e7552@changeid>
Message-ID: <8923429b-bf81-e185-86e1-6a5bc78f0f60@gmail.com>



On 06/07/2021 12:01, Kansho Nishida wrote:
> Set pin control for the SoC sound node.
> The compatibles are set by each model dts.
> 
> The codecs that each models use are:
> burnet       ts3a227_max98357
> damu         da7219_max98357
> fennel       da7219_rt1015p
> fennel14     da7219_rt1015p
> juniper      ts3a227_max98357
> kakadu       da7219_rt1015p
> kappa        ts3a227_max98357
> kenzo        ts3a227_max98357
> kodama       ts3a227_max98357
> krane        ts3a227_max98357
> willow-sku0  da7219_max98357
> willow-sku1  ts3a227_max98357
> 
> Signed-off-by: Kansho Nishida <kansho at chromium.org>

Queued in v5.15-tmp/dts64

Thanks!

> ---
> 
> (no changes since v2)
> 
> Changes in v2:
> - Changed to the dual license GPL + MIT.
> 
>  arch/arm64/boot/dts/mediatek/mt6358.dtsi      |  1 +
>  .../mt8183-kukui-audio-da7219-max98357a.dtsi  | 13 ++++
>  .../mt8183-kukui-audio-da7219-rt1015p.dtsi    | 13 ++++
>  .../mediatek/mt8183-kukui-audio-da7219.dtsi   | 54 +++++++++++++++
>  .../mt8183-kukui-audio-max98357a.dtsi         | 13 ++++
>  .../mediatek/mt8183-kukui-audio-rt1015p.dtsi  | 13 ++++
>  ...mt8183-kukui-audio-ts3a227e-max98357a.dtsi | 13 ++++
>  .../mt8183-kukui-audio-ts3a227e-rt1015p.dtsi  | 13 ++++
>  .../mediatek/mt8183-kukui-audio-ts3a227e.dtsi | 32 +++++++++
>  .../mediatek/mt8183-kukui-jacuzzi-burnet.dts  |  1 +
>  .../mediatek/mt8183-kukui-jacuzzi-damu.dts    |  1 +
>  .../mediatek/mt8183-kukui-jacuzzi-fennel.dtsi |  1 +
>  .../mt8183-kukui-jacuzzi-juniper-sku16.dts    |  1 +
>  .../mediatek/mt8183-kukui-jacuzzi-kappa.dts   |  1 +
>  .../mediatek/mt8183-kukui-jacuzzi-kenzo.dts   |  1 +
>  .../mt8183-kukui-jacuzzi-willow-sku0.dts      |  1 +
>  .../mt8183-kukui-jacuzzi-willow-sku1.dts      |  1 +
>  .../boot/dts/mediatek/mt8183-kukui-kakadu.dts |  1 +
>  .../dts/mediatek/mt8183-kukui-kodama.dtsi     |  1 +
>  .../boot/dts/mediatek/mt8183-kukui-krane.dtsi |  5 ++
>  .../arm64/boot/dts/mediatek/mt8183-kukui.dtsi | 67 +++++++++++++++++--
>  21 files changed, 243 insertions(+), 4 deletions(-)
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-max98357a.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-rt1015p.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-max98357a.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-rt1015p.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-max98357a.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-rt1015p.dtsi
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e.dtsi
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
> index fa159b20379e..95145076b7e6 100644
> --- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
> @@ -13,6 +13,7 @@ pmic: mt6358 {
>  
>  		mt6358codec: mt6358codec {
>  			compatible = "mediatek,mt6358-sound";
> +			mediatek,dmic-mode = <0>; /* two-wires */
>  		};
>  
>  		mt6358regulator: mt6358regulator {
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-max98357a.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-max98357a.dtsi
> new file mode 100644
> index 000000000000..e4aeea4599f5
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-max98357a.dtsi
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Google Kukui (and derivatives) da7219-max98357a sound card.
> + *
> + * Copyright 2019 Google LLC.
> + */
> +
> +#include "mt8183-kukui-audio-da7219.dtsi"
> +#include "mt8183-kukui-audio-max98357a.dtsi"
> +
> +&sound {
> +	compatible = "mediatek,mt8183_da7219_max98357";
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-rt1015p.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-rt1015p.dtsi
> new file mode 100644
> index 000000000000..16ce5a3612ee
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219-rt1015p.dtsi
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Google Kukui (and derivatives) da7219-rt1015p sound card.
> + *
> + * Copyright 2020 Google LLC.
> + */
> +
> +#include "mt8183-kukui-audio-da7219.dtsi"
> +#include "mt8183-kukui-audio-rt1015p.dtsi"
> +
> +&sound {
> +	compatible = "mediatek,mt8183_da7219_rt1015p";
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
> new file mode 100644
> index 000000000000..2c69e7658dba
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
> @@ -0,0 +1,54 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Google Kukui (and derivatives) audio fragment for da7219.
> + *
> + * Copyright 2020 Google LLC.
> + */
> +
> +&i2c5 {
> +	da7219: da7219 at 1a {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&da7219_pins>;
> +		compatible = "dlg,da7219";
> +		reg = <0x1a>;
> +		interrupt-parent = <&pio>;
> +		interrupts = <165 IRQ_TYPE_LEVEL_LOW 165 0>;
> +
> +		dlg,micbias-lvl = <2600>;
> +		dlg,mic-amp-in-sel = "diff";
> +		VDD-supply = <&pp1800_alw>;
> +		VDDMIC-supply = <&pp3300_alw>;
> +		VDDIO-supply = <&pp1800_alw>;
> +
> +		status = "okay";
> +
> +		da7219_aad {
> +			dlg,adc-1bit-rpt = <1>;
> +			dlg,btn-avg = <4>;
> +			dlg,btn-cfg = <50>;
> +			dlg,mic-det-thr = <500>;
> +			dlg,jack-ins-deb = <20>;
> +			dlg,jack-det-rate = "32ms_64ms";
> +			dlg,jack-rem-deb = <1>;
> +
> +			dlg,a-d-btn-thr = <0xa>;
> +			dlg,d-b-btn-thr = <0x16>;
> +			dlg,b-c-btn-thr = <0x21>;
> +			dlg,c-mic-btn-thr = <0x3E>;
> +		};
> +	};
> +};
> +
> +&pio {
> +	da7219_pins: da7219_pins {
> +		pins1 {
> +			pinmux = <PINMUX_GPIO165__FUNC_GPIO165>;
> +			input-enable;
> +			bias-pull-up;
> +		};
> +	};
> +};
> +
> +&sound {
> +	mediatek,headset-codec = <&da7219>;
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-max98357a.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-max98357a.dtsi
> new file mode 100644
> index 000000000000..2b60967c0c1c
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-max98357a.dtsi
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Google Kukui (and derivatives) audio fragment for max98357a.
> + *
> + * Copyright 2020 Google LLC.
> + */
> +
> +/ {
> +	max98357a: max98357a {
> +		compatible = "maxim,max98357a";
> +		sdmode-gpios = <&pio 175 0>;
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-rt1015p.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-rt1015p.dtsi
> new file mode 100644
> index 000000000000..658a764fe9ee
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-rt1015p.dtsi
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Google Kukui (and derivatives) audio fragment for rt1015p.
> + *
> + * Copyright 2020 Google LLC.
> + */
> +
> +/ {
> +	rt1015p: rt1015p {
> +		compatible = "realtek,rt1015p";
> +		sdb-gpios = <&pio 175 0>;
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-max98357a.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-max98357a.dtsi
> new file mode 100644
> index 000000000000..260a5f561495
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-max98357a.dtsi
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Google Kukui (and derivatives) ts3a227e-max98357a sound card.
> + *
> + * Copyright 2020 Google LLC.
> + */
> +
> +#include "mt8183-kukui-audio-max98357a.dtsi"
> +#include "mt8183-kukui-audio-ts3a227e.dtsi"
> +
> +&sound {
> +	compatible = "mediatek,mt8183_mt6358_ts3a227_max98357";
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-rt1015p.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-rt1015p.dtsi
> new file mode 100644
> index 000000000000..2f7d1fa1c90f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e-rt1015p.dtsi
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Google Kukui (and derivatives) mt6358-ts3a227-rt1015p sound card.
> + *
> + * Copyright 2021 Google LLC.
> + */
> +
> +#include "mt8183-kukui-audio-ts3a227e.dtsi"
> +#include "mt8183-kukui-audio-rt1015p.dtsi"
> +
> +&sound {
> +	compatible = "mediatek,mt8183_mt6358_ts3a227_rt1015p";
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e.dtsi
> new file mode 100644
> index 000000000000..0799c48ade19
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-ts3a227e.dtsi
> @@ -0,0 +1,32 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Google Kukui (and derivatives) audio fragment for ts3a227e.
> + *
> + * Copyright 2019 Google LLC.
> + */
> +
> +&i2c5 {
> +	ts3a227e: ts3a227e at 3b {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&ts3a227e_pins>;
> +		compatible = "ti,ts3a227e";
> +		reg = <0x3b>;
> +		interrupt-parent = <&pio>;
> +		interrupts = <157 IRQ_TYPE_LEVEL_LOW>;
> +		status = "okay";
> +	};
> +};
> +
> +&pio {
> +	ts3a227e_pins: ts3a227e_pins {
> +		pins1 {
> +			pinmux = <PINMUX_GPIO157__FUNC_GPIO157>;
> +			input-enable;
> +			bias-pull-up;
> +		};
> +	};
> +};
> +
> +&sound {
> +	mediatek,headset-codec = <&ts3a227e>;
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
> index a8d6f32ade8d..1a2ec0787d3c 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-jacuzzi.dtsi"
> +#include "mt8183-kukui-audio-ts3a227e-max98357a.dtsi"
>  
>  / {
>  	model = "Google burnet board";
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
> index 42ba9c00866c..0eca3ff8672a 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-jacuzzi.dtsi"
> +#include "mt8183-kukui-audio-da7219-max98357a.dtsi"
>  
>  / {
>  	model = "Google damu board";
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi
> index bbe6c338f465..577519a775c0 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-jacuzzi.dtsi"
> +#include "mt8183-kukui-audio-da7219-rt1015p.dtsi"
>  
>  &mt6358codec {
>  	mediatek,dmic-mode = <1>; /* one-wire */
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts
> index 36d2c3b3cadf..bc2c57f0a827 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-juniper-sku16.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-jacuzzi-juniper.dtsi"
> +#include "mt8183-kukui-audio-ts3a227e-max98357a.dtsi"
>  
>  / {
>  	model = "Google juniper sku16 board";
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts
> index b3f46c16e5d7..e5bd9191e426 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kappa.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-jacuzzi.dtsi"
> +#include "mt8183-kukui-audio-ts3a227e-max98357a.dtsi"
>  
>  / {
>  	model = "Google kappa board";
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
> index 6f1aa692753a..8fa89db03e63 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-jacuzzi-juniper.dtsi"
> +#include "mt8183-kukui-audio-ts3a227e-max98357a.dtsi"
>  
>  / {
>  	model = "Google kenzo sku17 board";
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts
> index 281265f082db..89208b843b27 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku0.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-jacuzzi-willow.dtsi"
> +#include "mt8183-kukui-audio-da7219-max98357a.dtsi"
>  
>  / {
>  	model = "Google willow board sku0";
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts
> index 22e56bdc1ee3..c7b20441d053 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow-sku1.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-jacuzzi-willow.dtsi"
> +#include "mt8183-kukui-audio-ts3a227e-max98357a.dtsi"
>  
>  / {
>  	model = "Google willow board sku1";
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts
> index 20eb0dc68f09..89a139a0ee44 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui-kakadu.dtsi"
> +#include "mt8183-kukui-audio-da7219-rt1015p.dtsi"
>  
>  / {
>  	model = "MediaTek kakadu board";
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
> index 3aa79403c0c2..06f8c80bf553 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  #include "mt8183-kukui.dtsi"
> +#include "mt8183-kukui-audio-ts3a227e-max98357a.dtsi"
>  
>  / {
>  	ppvarn_lcd: ppvarn-lcd {
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
> index 30c183c96a54..a7b0cb3ff7b0 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
> @@ -4,6 +4,7 @@
>   */
>  
>  #include "mt8183-kukui.dtsi"
> +#include "mt8183-kukui-audio-max98357a.dtsi"
>  
>  / {
>  	ppvarn_lcd: ppvarn-lcd {
> @@ -345,3 +346,7 @@ rst_pin {
>  &qca_wifi {
>  	qcom,ath10k-calibration-variant = "LE_Krane";
>  };
> +
> +&sound {
> +	compatible = "mediatek,mt8183_mt6358_ts3a227_max98357";
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
> index ae549d55a94f..b709859b0a03 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
> @@ -113,12 +113,18 @@ scp_mem_reserved: scp_mem_region {
>  		};
>  	};
>  
> -	max98357a: codec0 {
> -		compatible = "maxim,max98357a";
> -		sdmode-gpios = <&pio 175 0>;
> +	sound: mt8183-sound {
> +		mediatek,platform = <&afe>;
> +		pinctrl-names = "default",
> +				"aud_tdm_out_on",
> +				"aud_tdm_out_off";
> +		pinctrl-0 = <&aud_pins_default>;
> +		pinctrl-1 = <&aud_pins_tdm_out_on>;
> +		pinctrl-2 = <&aud_pins_tdm_out_off>;
> +		status = "okay";
>  	};
>  
> -	btsco: codec1 {
> +	btsco: bt-sco {
>  		compatible = "linux,bt-sco";
>  	};
>  
> @@ -213,6 +219,11 @@ tboard_thermistor2: thermal-sensor2 {
>  	};
>  };
>  
> +&afe {
> +	i2s3-share = "I2S2";
> +	i2s0-share = "I2S5";
> +};
> +
>  &auxadc {
>  	status = "okay";
>  };
> @@ -400,6 +411,54 @@ &mt6358_vsim2_reg {
>  };
>  
>  &pio {
> +	aud_pins_default: audiopins {
> +		pins_bus {
> +			pinmux = <PINMUX_GPIO97__FUNC_I2S2_MCK>,
> +				<PINMUX_GPIO98__FUNC_I2S2_BCK>,
> +				<PINMUX_GPIO101__FUNC_I2S2_LRCK>,
> +				<PINMUX_GPIO102__FUNC_I2S2_DI>,
> +				<PINMUX_GPIO3__FUNC_I2S3_DO>, /*i2s to da7219/max98357*/
> +				<PINMUX_GPIO89__FUNC_I2S5_BCK>,
> +				<PINMUX_GPIO90__FUNC_I2S5_LRCK>,
> +				<PINMUX_GPIO91__FUNC_I2S5_DO>,
> +				<PINMUX_GPIO174__FUNC_I2S0_DI>, /*i2s to wifi/bt*/
> +				<PINMUX_GPIO136__FUNC_AUD_CLK_MOSI>,
> +				<PINMUX_GPIO137__FUNC_AUD_SYNC_MOSI>,
> +				<PINMUX_GPIO138__FUNC_AUD_DAT_MOSI0>,
> +				<PINMUX_GPIO139__FUNC_AUD_DAT_MOSI1>,
> +				<PINMUX_GPIO140__FUNC_AUD_CLK_MISO>,
> +				<PINMUX_GPIO141__FUNC_AUD_SYNC_MISO>,
> +				<PINMUX_GPIO142__FUNC_AUD_DAT_MISO0>,
> +				<PINMUX_GPIO143__FUNC_AUD_DAT_MISO1>; /*mtkaif3.0*/
> +		};
> +	};
> +
> +	aud_pins_tdm_out_on: audiotdmouton {
> +		pins_bus {
> +			pinmux = <PINMUX_GPIO169__FUNC_TDM_BCK_2ND>,
> +				<PINMUX_GPIO170__FUNC_TDM_LRCK_2ND>,
> +				<PINMUX_GPIO171__FUNC_TDM_DATA0_2ND>,
> +				<PINMUX_GPIO172__FUNC_TDM_DATA1_2ND>,
> +				<PINMUX_GPIO173__FUNC_TDM_DATA2_2ND>,
> +				<PINMUX_GPIO10__FUNC_TDM_DATA3>; /*8ch-i2s to it6505*/
> +			drive-strength = <MTK_DRIVE_6mA>;
> +		};
> +	};
> +
> +	aud_pins_tdm_out_off: audiotdmoutoff {
> +		pins_bus {
> +			pinmux = <PINMUX_GPIO169__FUNC_GPIO169>,
> +				<PINMUX_GPIO170__FUNC_GPIO170>,
> +				<PINMUX_GPIO171__FUNC_GPIO171>,
> +				<PINMUX_GPIO172__FUNC_GPIO172>,
> +				<PINMUX_GPIO173__FUNC_GPIO173>,
> +				<PINMUX_GPIO10__FUNC_GPIO10>;
> +			input-enable;
> +			bias-pull-down;
> +			drive-strength = <MTK_DRIVE_2mA>;
> +		};
> +	};
> +
>  	bt_pins: bt-pins {
>  		pins_bt_en {
>  			pinmux = <PINMUX_GPIO120__FUNC_GPIO120>;
> 


From anshuman.khandual at arm.com  Tue Aug 10 08:01:05 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 20:31:05 +0530
Subject: [PATCH] arm64/perf: Replace '0xf' instances with
 ID_AA64DFR0_PMUVER_IMP_DEF
In-Reply-To: <20210810133101.GD2946@willie-the-truck>
References: <1628571998-13634-1-git-send-email-anshuman.khandual@arm.com>
 <20210810133101.GD2946@willie-the-truck>
Message-ID: <995fce58-d1fa-9f0f-b8bd-05e689330482@arm.com>



On 8/10/21 7:01 PM, Will Deacon wrote:
> On Tue, Aug 10, 2021 at 10:36:38AM +0530, Anshuman Khandual wrote:
>> ID_AA64DFR0_PMUVER_IMP_DEF which indicate implementation defined PMU, never
>> actually gets used although there are '0xf' instances scattered all around.
>> Just do the macro replacement to improve readability.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Peter Zijlstra <peterz at infradead.org>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: linux-perf-users at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: kvmarm at lists.cs.columbia.edu
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> This applies on v5.14-rc5
>>
>>  arch/arm64/include/asm/cpufeature.h | 2 +-
>>  arch/arm64/kernel/perf_event.c      | 2 +-
>>  arch/arm64/kvm/perf.c               | 2 +-
>>  arch/arm64/kvm/pmu-emul.c           | 6 +++---
>>  4 files changed, 6 insertions(+), 6 deletions(-)
> 
> Please can you split this with the KVM parts in their own patch?

Sure, will do.


From sdonthineni at nvidia.com  Tue Aug 10 08:09:35 2021
From: sdonthineni at nvidia.com (Shanker R Donthineni)
Date: Tue, 10 Aug 2021 10:09:35 -0500
Subject: [PATCH 3/3] PCI/ACPI: Add new quirk detection, enable bcm2711
In-Reply-To: <1ed33f6e-fbfb-e8a0-741e-6961f9a7072b@arm.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
 <20210805211200.491275-4-jeremy.linton@arm.com>
 <b574f9bb-72f3-72cd-9a6a-f1f4d998afda@nvidia.com>
 <1ed33f6e-fbfb-e8a0-741e-6961f9a7072b@arm.com>
Message-ID: <4dbb779a-4cf2-6cb8-81b5-871a12b1f883@nvidia.com>



On 8/10/21 9:47 AM, Jeremy Linton wrote:
>>> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
>>> index 53cab975f612..7d77fc72c2a4 100644
>>> --- a/drivers/acpi/pci_mcfg.c
>>> +++ b/drivers/acpi/pci_mcfg.c
>>> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>>> ???????? ALTRA_ECAM_QUIRK(1, 13),
>>> ???????? ALTRA_ECAM_QUIRK(1, 14),
>>> ???????? ALTRA_ECAM_QUIRK(1, 15),
>>> +
>>> +?????? { "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
>>> +???????? DEFINE_RES_MEM(0xFD500000, 0xA000) },
>>> ? };
>>>
>>> ? static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
>>> @@ -198,8 +201,19 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
>>> ???????? u16 segment = root->segment;
>>> ???????? struct resource *bus_range = &root->secondary;
>>> ???????? struct mcfg_fixup *f;
>>> +?????? const char *soc;
>>> ???????? int i;
>>>
>>> +?????? /*
>>> +??????? * This could be a machine with a PCI/SMC conduit,
>>> +??????? * which means it doens't have MCFG. Get the machineid from
>>> +??????? * the namespace definition instead.
>>> +??????? */
>>> +?????? if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
>>> +??????????????????????????????????????? "linux,pcie-quirk", &soc)) {
>>> +?????????????? memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
>>> +?????? }
>>> +
>>
>> Is there any specific reason for not using the firmware agnostic API to get properties?
>>
>>
>> ? if (!device_property_read_string(root->device, "linux,pcie-quirk", &soc)) {
>> ????? memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
>> ? }
>>
>>
>
> IIRC it was because the "device" here isn't a struct device, rather a
> struct acpi_device. I think this is the normal way in this situation
> since we are directly picking up the fwnode rather than finding a
> generic node and then backtracking to get the fwnode. 

Yes, you are right.


From anshuman.khandual at arm.com  Tue Aug 10 08:11:16 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 20:41:16 +0530
Subject: [PATCH 2/5] KVM: arm64: Drop init_common_resources()
In-Reply-To: <20210810132123.GB2946@willie-the-truck>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-3-git-send-email-anshuman.khandual@arm.com>
 <20210810132123.GB2946@willie-the-truck>
Message-ID: <0480869b-bb08-747a-f4f1-3f77ba4bbed9@arm.com>



On 8/10/21 6:51 PM, Will Deacon wrote:
> On Tue, Aug 10, 2021 at 12:32:38PM +0530, Anshuman Khandual wrote:
>> Could do without this additional indirection via init_common_resources() by
>> just calling kvm_set_ipa_limit() directly instead. This change saves memory
>> and cycles.
> 
> Does it? Really?

TBH, I did not really measure them to be sure. It was more like an intuitive
assumption. But do you suspect that the compiler might be already optimizing
this out, hence giving memory and CPU cycle benefits ? Regardless this still
drops an unnecessary function.

> 
> Will
> 
>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>> index e9a2b8f27792..19560e457c11 100644
>> --- a/arch/arm64/kvm/arm.c
>> +++ b/arch/arm64/kvm/arm.c
>> @@ -1696,11 +1696,6 @@ static bool init_psci_relay(void)
>>  	return true;
>>  }
>>  
>> -static int init_common_resources(void)
>> -{
>> -	return kvm_set_ipa_limit();
>> -}
>> -
>>  static int init_subsystems(void)
>>  {
>>  	int err = 0;
>> @@ -2102,7 +2097,7 @@ int kvm_arch_init(void *opaque)
>>  		}
>>  	}
>>  
>> -	err = init_common_resources();
>> +	err = kvm_set_ipa_limit();
>>  	if (err)
>>  		return err;
>>  
>> -- 
>> 2.20.1
>>


From jeremy.linton at arm.com  Tue Aug 10 08:10:30 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Tue, 10 Aug 2021 10:10:30 -0500
Subject: [PATCH 1/3] PCI: brcmstb: Break register definitions into
 separate header
In-Reply-To: <f82761b1-fb7e-08b2-8bc3-c84d258e26d3@gmail.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
 <20210805211200.491275-2-jeremy.linton@arm.com>
 <f82761b1-fb7e-08b2-8bc3-c84d258e26d3@gmail.com>
Message-ID: <ab2aa9e3-cdc7-1bc7-d493-8f3c991c3285@arm.com>

Hi,

Thanks for taking a look at this!


On 8/10/21 5:07 AM, Florian Fainelli wrote:
> 
> 
> On 8/5/2021 2:11 PM, Jeremy Linton wrote:
>> We are about to create a standalone ACPI quirk module for the
>> bcmstb controller. Lets move the register definitions into a separate
>> file so they can be shared between the APCI quirk and the normal
>> host bridge driver.
>>
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>> ? drivers/pci/controller/pcie-brcmstb.c | 179 +------------------------
>> ? drivers/pci/controller/pcie-brcmstb.h | 182 ++++++++++++++++++++++++++
>> ? 2 files changed, 183 insertions(+), 178 deletions(-)
>> ? create mode 100644 drivers/pci/controller/pcie-brcmstb.h
> 
> You moved more than just register definitions into pcie-brcmstb.h you 
> also moved internal structure definitions, enumerations, etc. which are 
> not required since pcie-brcmstb-acpi.c does not access the brcm_pcie 
> structure but open codes accesses to the MISC_STATUS register instead.
> 
> There are no include guards added to this file (it is debatable whether 
> we should add them), and it is also not covered by the existing BROADCOM 
> BCM2711/BCM2835 ARM ARCHITECTURE MAINTAINERS file entry.

Sure, I will reduce the .h to just the register definitions, guard it, 
and tweak maintainers to cover pcie-brcmstb*.


> 
> Given that there can be new platforms supported by this PCIe controller 
> in the future possibly with the same limitations as the 2711, but with a 
> seemingly different MISC_STATUS layout, you will have to think about a 
> solution that scales, maybe we cross that bridge when we get there.

Yes, given I don't know what those changes are I can't predict how they 
would have to be handled, or even if the platform would be a target of 
the community maintaining the UEFI/ACPI port on the RPi. So punting on 
that topic seems a reasonable solution at the moment. Better yet, more 
of the linux community will see the advantage of the firmware interface 
and this platform can utilize that method.


From a.fatoum at pengutronix.de  Tue Aug 10 08:14:33 2021
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Tue, 10 Aug 2021 17:14:33 +0200
Subject: [PATCH] clk: imx8m: fix clock tree update of TF-A managed clocks
Message-ID: <20210810151432.9228-1-a.fatoum@pengutronix.de>

On the i.MX8M*, the TF-A exposes a SiP (Silicon Provider) service
for DDR frequency scaling. The imx8m-ddrc-devfreq driver calls the
SiP and then does clk_set_parent on the DDR muxes to synchronize
the clock tree.

Since 936c383673b9 ("clk: imx: fix composite peripheral flags"),
these TF-A managed muxes have SET_PARENT_GATE set, which results
in imx8m-ddrc-devfreq's clk_set_parent after SiP failing with -EBUSY:

	echo 25000000 > userspace/set_freq
	imx8m-ddrc-devfreq 3d400000.memory-controller: failed to set
		dram_apb parent: -16

Fix this by adding a new i.MX composite flag for firmware managed
clocks, which clears SET_PARENT_GATE.

This is safe to do, because updating the Linux clock tree to reflect
reality will always be glitch-free.

Fixes: 936c383673b9 ("clk: imx: fix composite peripheral flags")
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
To: Abel Vesa <abel.vesa at nxp.com>
To: Michael Turquette <mturquette at baylibre.com>
To: Stephen Boyd <sboyd at kernel.org>
To: Shawn Guo <shawnguo at kernel.org>
To: Sascha Hauer <s.hauer at pengutronix.de>
To: Pengutronix Kernel Team <kernel at pengutronix.de>
To: Fabio Estevam <festevam at gmail.com>
To: NXP Linux Team <linux-imx at nxp.com>
To: Peng Fan <peng.fan at nxp.com>
To: Leonard Crestez <leonard.crestez at nxp.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-clk at vger.kernel.org
---
 drivers/clk/imx/clk-composite-8m.c |  3 ++-
 drivers/clk/imx/clk-imx8mm.c       |  7 ++++---
 drivers/clk/imx/clk-imx8mn.c       |  7 ++++---
 drivers/clk/imx/clk-imx8mq.c       |  7 ++++---
 drivers/clk/imx/clk.h              | 16 ++++++++++++++--
 5 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
index 2c309e3dc8e3..04e728538cef 100644
--- a/drivers/clk/imx/clk-composite-8m.c
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -216,7 +216,8 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
 		div->width = PCG_PREDIV_WIDTH;
 		divider_ops = &imx8m_clk_composite_divider_ops;
 		mux_ops = &clk_mux_ops;
-		flags |= CLK_SET_PARENT_GATE;
+		if (!(composite_flags & IMX_COMPOSITE_FW_MANAGED))
+			flags |= CLK_SET_PARENT_GATE;
 	}
 
 	div->lock = &imx_ccm_lock;
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index f1919fafb124..73cc9805ec59 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -470,10 +470,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 
 	/*
 	 * DRAM clocks are manipulated from TF-A outside clock framework.
-	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
+	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
+	 * as div value should always be read from hardware
 	 */
-	hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
-	hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+	hws[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
+	hws[IMX8MM_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
 
 	/* IP */
 	hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 88f6630cd472..0a76f969b28b 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -453,10 +453,11 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 
 	/*
 	 * DRAM clocks are manipulated from TF-A outside clock framework.
-	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
+	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
+	 * as div value should always be read from hardware
 	 */
-	hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
-	hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+	hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
+	hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
 
 	hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
 	hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index c491bc9c61ce..83cc2b1c3294 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -449,11 +449,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
 
 	/*
 	 * DRAM clocks are manipulated from TF-A outside clock framework.
-	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
+	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
+	 * as div value should always be read from hardware
 	 */
 	hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
-	hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
-	hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+	hws[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
+	hws[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
 
 	/* IP */
 	hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 7571603bee23..e144f983fd8c 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -530,8 +530,9 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
 		struct clk *div, struct clk *mux, struct clk *pll,
 		struct clk *step);
 
-#define IMX_COMPOSITE_CORE	BIT(0)
-#define IMX_COMPOSITE_BUS	BIT(1)
+#define IMX_COMPOSITE_CORE		BIT(0)
+#define IMX_COMPOSITE_BUS		BIT(1)
+#define IMX_COMPOSITE_FW_MANAGED	BIT(2)
 
 struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
 					    const char * const *parent_names,
@@ -567,6 +568,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
 		ARRAY_SIZE(parent_names), reg, 0, \
 		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
 
+#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \
+	imx8m_clk_hw_composite_flags(name, parent_names, \
+		ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \
+		flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
+
+#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
+	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0)
+
+#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
+	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL)
+
 #define __imx8m_clk_composite(name, parent_names, reg, flags) \
 	to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
 
-- 
2.30.2



From anshuman.khandual at arm.com  Tue Aug 10 08:19:38 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 10 Aug 2021 20:49:38 +0530
Subject: [PATCH 5/5] KVM: arm64: Define KVM_PHYS_SHIFT_MIN
In-Reply-To: <2dbeb2c329cfeb1ee9a7331683cdbc97@kernel.org>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-6-git-send-email-anshuman.khandual@arm.com>
 <2dbeb2c329cfeb1ee9a7331683cdbc97@kernel.org>
Message-ID: <43c5ffa3-b3c5-9154-72b5-811eeb9ece8f@arm.com>



On 8/10/21 6:59 PM, Marc Zyngier wrote:
> On 2021-08-10 08:02, Anshuman Khandual wrote:
>> Drop the hard coded value for the minimum IPA range i.e 32 bit. Instead
>> define a macro KVM_PHYS_SHIFT_MIN which improves the code readability.
>>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: James Morse <james.morse at arm.com>
>> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: kvmarm at lists.cs.columbia.edu
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> ?arch/arm64/include/asm/kvm_mmu.h | 3 ++-
>> ?arch/arm64/kvm/reset.c?????????? | 2 +-
>> ?2 files changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
>> index b52c5c4b9a3d..716f999818d9 100644
>> --- a/arch/arm64/include/asm/kvm_mmu.h
>> +++ b/arch/arm64/include/asm/kvm_mmu.h
>> @@ -141,7 +141,8 @@ static __always_inline unsigned long
>> __kern_hyp_va(unsigned long v)
>> ? * We currently support using a VM-specified IPA size. For backward
>> ? * compatibility, the default IPA size is fixed to 40bits.
>> ? */
>> -#define KVM_PHYS_SHIFT??? (40)
>> +#define KVM_PHYS_SHIFT??????? (40)
>> +#define KVM_PHYS_SHIFT_MIN??? (32)
>>
>> ?#define kvm_phys_shift(kvm)??????? VTCR_EL2_IPA(kvm->arch.vtcr)
>> ?#define kvm_phys_size(kvm)??????? (_AC(1, ULL) << kvm_phys_shift(kvm))
>> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
>> index cba7872d69a8..8dc8b4b9de37 100644
>> --- a/arch/arm64/kvm/reset.c
>> +++ b/arch/arm64/kvm/reset.c
>> @@ -369,7 +369,7 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned
>> long type)
>> ???? phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
>> ???? if (phys_shift) {
>> ???????? if (phys_shift > kvm_ipa_limit ||
>> -??????????? phys_shift < 32)
>> +??????????? phys_shift < KVM_PHYS_SHIFT_MIN)
>> ???????????? return -EINVAL;
>> ???? } else {
>> ???????? phys_shift = KVM_PHYS_SHIFT;
> 
> This is not a KVM property, but an architectural one. If you

Architectural property which suggest the minimum physical address shift
supported on a platform, as indicated via ID_AA64MMFR0.PARANGE = 0x0 ?

> want to replace it with something more readable, please
> make it global to the whole of arm64 (ARM64_MIN_PARANGE?).

Sure, will do.


From mark.rutland at arm.com  Tue Aug 10 08:27:56 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Aug 2021 16:27:56 +0100
Subject: [PATCH] arm64: head: avoid over-mapping in map_memory
Message-ID: <20210810152756.23903-1-mark.rutland@arm.com>

The `compute_indices` and `populate_entries` macros operate on inclusive
bounds, and thus the `map_memory` macro which uses them also operates
on inclusive bounds.

We pass `_end` and `_idmap_text_end` to `map_memory`, but these are
exclusive bounds, and if one of these is sufficiently aligned (as a
result of kernel configuration, physical placement, and KASLR), then:

* In `compute_indices`, the computed `iend` will be in the page/block *after*
  the final byte of the intended mapping.

* In `populate_entries`, an unnecessary entry will be created at the end
  of each level of table. At the leaf level, this entry will map up to
  SWAPPER_BLOCK_SIZE bytes of physical addresses that we did not intend
  to map.

As we may map up to SWAPPER_BLOCK_SIZE bytes more than intended, we may
violate the boot protocol and map physical address past the 2MiB-aligned
end address we are permitted to map. As we map these with Normal memory
attributes, this may result in further problems depending on what these
physical addresses correspond to.

Fix this by subtracting one from the end address in both cases, such
that we always use inclusive bounds. For clarity, comments are updated
to more clearly document that the macros expect inclusive bounds.

Fixes: 0370b31e48454d8c ("arm64: Extend early page table code to allow for larger kernel")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Anshuman Khandual <anshuman.khandual at arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Steve Capper <steve.capper at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/head.S | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

I spotted this while working on some rework of the early page table code.
While the rest isn't ready yet, I thought I'd send this out on its own as it's
a fix.

Mark.

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c5c994a73a64..f0826be4c104 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -176,8 +176,8 @@ SYM_CODE_END(preserve_boot_args)
  * were needed in the previous page table level then the next page table level is assumed
  * to be composed of multiple pages. (This effectively scales the end index).
  *
- *	vstart:	virtual address of start of range
- *	vend:	virtual address of end of range
+ *	vstart:	virtual address of start of range (inclusive)
+ *	vend:	virtual address of end of range (inclusive)
  *	shift:	shift used to transform virtual address into index
  *	ptrs:	number of entries in page table
  *	istart:	index in table corresponding to vstart
@@ -214,8 +214,8 @@ SYM_CODE_END(preserve_boot_args)
  *
  *	tbl:	location of page table
  *	rtbl:	address to be used for first level page table entry (typically tbl + PAGE_SIZE)
- *	vstart:	start address to map
- *	vend:	end address to map - we map [vstart, vend]
+ *	vstart:	virtual address of start of mapping (inclusive)
+ *	vend:	virtual address of end of mapping (inclusive)
  *	flags:	flags to use to map last level entries
  *	phys:	physical address corresponding to vstart - physical memory is contiguous
  *	pgds:	the number of pgd entries
@@ -355,6 +355,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
 1:
 	ldr_l	x4, idmap_ptrs_per_pgd
 	adr_l	x6, __idmap_text_end		// __pa(__idmap_text_end)
+	sub	x6, x6, #1
 
 	map_memory x0, x1, x3, x6, x7, x3, x4, x10, x11, x12, x13, x14
 
@@ -366,6 +367,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
 	add	x5, x5, x23			// add KASLR displacement
 	mov	x4, PTRS_PER_PGD
 	adrp	x6, _end			// runtime __pa(_end)
+	sub	x6, x6, #1
 	adrp	x3, _text			// runtime __pa(_text)
 	sub	x6, x6, x3			// _end - _text
 	add	x6, x6, x5			// runtime __va(_end)
-- 
2.11.0



From maz at kernel.org  Tue Aug 10 08:32:00 2021
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 10 Aug 2021 16:32:00 +0100
Subject: [PATCH 5/5] KVM: arm64: Define KVM_PHYS_SHIFT_MIN
In-Reply-To: <43c5ffa3-b3c5-9154-72b5-811eeb9ece8f@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-6-git-send-email-anshuman.khandual@arm.com>
 <2dbeb2c329cfeb1ee9a7331683cdbc97@kernel.org>
 <43c5ffa3-b3c5-9154-72b5-811eeb9ece8f@arm.com>
Message-ID: <f6293361a98a6a9413643adeeb352f60@kernel.org>

On 2021-08-10 16:19, Anshuman Khandual wrote:
> On 8/10/21 6:59 PM, Marc Zyngier wrote:
>> On 2021-08-10 08:02, Anshuman Khandual wrote:
>>> Drop the hard coded value for the minimum IPA range i.e 32 bit. 
>>> Instead
>>> define a macro KVM_PHYS_SHIFT_MIN which improves the code 
>>> readability.
>>> 
>>> Cc: Marc Zyngier <maz at kernel.org>
>>> Cc: James Morse <james.morse at arm.com>
>>> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
>>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>> Cc: Will Deacon <will at kernel.org>
>>> Cc: linux-arm-kernel at lists.infradead.org
>>> Cc: kvmarm at lists.cs.columbia.edu
>>> Cc: linux-kernel at vger.kernel.org
>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>>> ---
>>> ?arch/arm64/include/asm/kvm_mmu.h | 3 ++-
>>> ?arch/arm64/kvm/reset.c?????????? | 2 +-
>>> ?2 files changed, 3 insertions(+), 2 deletions(-)
>>> 
>>> diff --git a/arch/arm64/include/asm/kvm_mmu.h 
>>> b/arch/arm64/include/asm/kvm_mmu.h
>>> index b52c5c4b9a3d..716f999818d9 100644
>>> --- a/arch/arm64/include/asm/kvm_mmu.h
>>> +++ b/arch/arm64/include/asm/kvm_mmu.h
>>> @@ -141,7 +141,8 @@ static __always_inline unsigned long
>>> __kern_hyp_va(unsigned long v)
>>> ? * We currently support using a VM-specified IPA size. For backward
>>> ? * compatibility, the default IPA size is fixed to 40bits.
>>> ? */
>>> -#define KVM_PHYS_SHIFT??? (40)
>>> +#define KVM_PHYS_SHIFT??????? (40)
>>> +#define KVM_PHYS_SHIFT_MIN??? (32)
>>> 
>>> ?#define kvm_phys_shift(kvm)??????? VTCR_EL2_IPA(kvm->arch.vtcr)
>>> ?#define kvm_phys_size(kvm)??????? (_AC(1, ULL) << 
>>> kvm_phys_shift(kvm))
>>> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
>>> index cba7872d69a8..8dc8b4b9de37 100644
>>> --- a/arch/arm64/kvm/reset.c
>>> +++ b/arch/arm64/kvm/reset.c
>>> @@ -369,7 +369,7 @@ int kvm_arm_setup_stage2(struct kvm *kvm, 
>>> unsigned
>>> long type)
>>> ???? phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
>>> ???? if (phys_shift) {
>>> ???????? if (phys_shift > kvm_ipa_limit ||
>>> -??????????? phys_shift < 32)
>>> +??????????? phys_shift < KVM_PHYS_SHIFT_MIN)
>>> ???????????? return -EINVAL;
>>> ???? } else {
>>> ???????? phys_shift = KVM_PHYS_SHIFT;
>> 
>> This is not a KVM property, but an architectural one. If you
> 
> Architectural property which suggest the minimum physical address shift
> supported on a platform, as indicated via ID_AA64MMFR0.PARANGE = 0x0 ?

That's the one.

         M.
-- 
Jazz is not dead. It just smells funny...


From len.baker at gmx.com  Tue Aug 10 08:59:53 2021
From: len.baker at gmx.com (Len Baker)
Date: Tue, 10 Aug 2021 17:59:53 +0200
Subject: [PATCH v4 2/3] drivers/soc/renesas: Prefer memcpy over strcpy
In-Reply-To: <c33adb9e-9604-3d89-5a5b-152eb03e5b54@wanadoo.fr>
References: <20210808125012.4715-1-len.baker@gmx.com>
 <20210808125012.4715-3-len.baker@gmx.com>
 <39485c0e-511c-50a0-83be-f9ce6fc47e67@petrovitsch.priv.at>
 <c33adb9e-9604-3d89-5a5b-152eb03e5b54@wanadoo.fr>
Message-ID: <20210810155953.GB2508@titan>

Hi,

On Sun, Aug 08, 2021 at 07:06:30PM +0200, Christophe JAILLET wrote:
> Hi,
>
> Le 08/08/2021 ? 17:35, Bernd Petrovitsch a ?crit?:
> > Hi all!
> >
> > On 08/08/2021 14:50, Len Baker wrote:
> > > strcpy() performs no bounds checking on the destination buffer. This
> > > could result in linear overflows beyond the end of the buffer, leading
> > > to all kinds of misbehaviors. So, use memcpy() as a safe replacement.
> > >
> > > This is a previous step in the path to remove the strcpy() function
> > > entirely from the kernel.
> > >
> > > Signed-off-by: Len Baker <len.baker at gmx.com>
> > > ---
> > >   drivers/soc/renesas/r8a779a0-sysc.c | 6 ++++--
> > >   drivers/soc/renesas/rcar-sysc.c     | 6 ++++--
> > >   2 files changed, 8 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/soc/renesas/r8a779a0-sysc.c b/drivers/soc/renesas/r8a779a0-sysc.c
> > > index d464ffa1be33..7410b9fa9846 100644
> > > --- a/drivers/soc/renesas/r8a779a0-sysc.c
> > > +++ b/drivers/soc/renesas/r8a779a0-sysc.c
> > > @@ -404,19 +404,21 @@ static int __init r8a779a0_sysc_pd_init(void)
> > >   	for (i = 0; i < info->num_areas; i++) {
> > >   		const struct r8a779a0_sysc_area *area = &info->areas[i];
> > >   		struct r8a779a0_sysc_pd *pd;
> > > +		size_t n;
> > >
> > >   		if (!area->name) {
> > >   			/* Skip NULLified area */
> > >   			continue;
> > >   		}
> > >
> > > -		pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL);
> > > +		n = strlen(area->name) + 1;
> > > +		pd = kzalloc(sizeof(*pd) + n, GFP_KERNEL);
> > Zeroing the allocated bytes is not needed since it's completly
> > overwritten with the strcpy()/memcpy().
>
> The strcpy()/memcpy() only overwrites the pd->name field, not the whole pd
> structure.

You are right.

> I think that it is needed to keep the kzalloc.

Yes, I think so. The kzalloc is needed to guarantee that the whole struct is
initialize (all the members are initialized with zeros).

Regards,
Len

>
> Just my 2c,
> CJ
>
> > >   		if (!pd) {
> > >   			error = -ENOMEM;
> > >   			goto out_put;
> > >   		}
> > >
> > > -		strcpy(pd->name, area->name);
> > > +		memcpy(pd->name, area->name, n);
> > >   		pd->genpd.name = pd->name;
> > >   		pd->pdr = area->pdr;
> > >   		pd->flags = area->flags;
> >
> > And similar for the second hunk.
> >
> > MfG,
> > 	Bernd
> >
>


From ardb at kernel.org  Tue Aug 10 09:12:44 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 10 Aug 2021 18:12:44 +0200
Subject: [RFC PATCH] arm64: mm: limit linear region to 51 bits for KVM in nVHE
 mode
Message-ID: <20210810161244.84231-1-ardb@kernel.org>

KVM in nVHE mode divides up its VA space into two equal halves, and
picks the half that does not conflict with the HYP ID map to map its
linear region. This worked fine when the kernel's linear map itself was
guaranteed to cover precisely as many bits of VA space, but this was
changed by commit f4693c2716b35d08 ("arm64: mm: extend linear region for
52-bit VA configurations").

The result is that, depending on the placement of the ID map, kernel-VA
to hyp-VA translations may produce addresses that either conflict with
other HYP mappings (including the ID map itself) or generate addresses
outside of the 52-bit addressable range, neither of which is likely to
lead to anything useful.

Given that 52-bit capable cores are guaranteed to implement VHE, this
only affects configurations such as pKVM where we opt into non-VHE mode
even if the hardware is VHE capable. So just for these configurations,
let's limit the kernel linear map to 51 bits and work around the
problem.

Fixes:f4693c2716b35d08 ("arm64: mm: extend linear region for 52-bit VA configurations")
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
NOTE: build tested only

 arch/arm64/mm/init.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2917ff..542dad13e2fc 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -282,7 +282,21 @@ static void __init fdt_enforce_memory_region(void)
 
 void __init arm64_memblock_init(void)
 {
-	const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
+	s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
+
+	/*
+	 * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
+	 * be limited in their ability to support a linear map that exceeds 51
+	 * bits of VA space, depending on the placement of the ID map. Given
+	 * that the placement of the ID map may be randomized, let's simply
+	 * limit the kernel's linear map to 51 bits as well if we detect this
+	 * configuration.
+	 */
+	if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 &&
+	    !is_kernel_in_hyp_mode()) {
+		pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n");
+		linear_region_size = BIT(51);
+	}
 
 	/* Handle linux,usable-memory-range property */
 	fdt_enforce_memory_region();
-- 
2.20.1



From ardb at kernel.org  Tue Aug 10 09:16:49 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 10 Aug 2021 18:16:49 +0200
Subject: [PATCH] arm64: head: avoid over-mapping in map_memory
In-Reply-To: <20210810152756.23903-1-mark.rutland@arm.com>
References: <20210810152756.23903-1-mark.rutland@arm.com>
Message-ID: <CAMj1kXG8+7MHON0MePA8+2Vji1P_9JCTTY_0f3iP0LWi1pEqcA@mail.gmail.com>

On Tue, 10 Aug 2021 at 17:29, Mark Rutland <mark.rutland at arm.com> wrote:
>
> The `compute_indices` and `populate_entries` macros operate on inclusive
> bounds, and thus the `map_memory` macro which uses them also operates
> on inclusive bounds.
>
> We pass `_end` and `_idmap_text_end` to `map_memory`, but these are
> exclusive bounds, and if one of these is sufficiently aligned (as a
> result of kernel configuration, physical placement, and KASLR), then:
>
> * In `compute_indices`, the computed `iend` will be in the page/block *after*
>   the final byte of the intended mapping.
>
> * In `populate_entries`, an unnecessary entry will be created at the end
>   of each level of table. At the leaf level, this entry will map up to
>   SWAPPER_BLOCK_SIZE bytes of physical addresses that we did not intend
>   to map.
>
> As we may map up to SWAPPER_BLOCK_SIZE bytes more than intended, we may
> violate the boot protocol and map physical address past the 2MiB-aligned
> end address we are permitted to map. As we map these with Normal memory
> attributes, this may result in further problems depending on what these
> physical addresses correspond to.
>
> Fix this by subtracting one from the end address in both cases, such
> that we always use inclusive bounds. For clarity, comments are updated
> to more clearly document that the macros expect inclusive bounds.
>
> Fixes: 0370b31e48454d8c ("arm64: Extend early page table code to allow for larger kernel")
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Steve Capper <steve.capper at arm.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/kernel/head.S | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
>
> I spotted this while working on some rework of the early page table code.
> While the rest isn't ready yet, I thought I'd send this out on its own as it's
> a fix.
>
> Mark.
>
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index c5c994a73a64..f0826be4c104 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -176,8 +176,8 @@ SYM_CODE_END(preserve_boot_args)
>   * were needed in the previous page table level then the next page table level is assumed
>   * to be composed of multiple pages. (This effectively scales the end index).
>   *
> - *     vstart: virtual address of start of range
> - *     vend:   virtual address of end of range
> + *     vstart: virtual address of start of range (inclusive)
> + *     vend:   virtual address of end of range (inclusive)
>   *     shift:  shift used to transform virtual address into index
>   *     ptrs:   number of entries in page table
>   *     istart: index in table corresponding to vstart
> @@ -214,8 +214,8 @@ SYM_CODE_END(preserve_boot_args)
>   *
>   *     tbl:    location of page table
>   *     rtbl:   address to be used for first level page table entry (typically tbl + PAGE_SIZE)
> - *     vstart: start address to map
> - *     vend:   end address to map - we map [vstart, vend]
> + *     vstart: virtual address of start of mapping (inclusive)
> + *     vend:   virtual address of end of mapping (inclusive)
>   *     flags:  flags to use to map last level entries
>   *     phys:   physical address corresponding to vstart - physical memory is contiguous
>   *     pgds:   the number of pgd entries
> @@ -355,6 +355,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
>  1:
>         ldr_l   x4, idmap_ptrs_per_pgd
>         adr_l   x6, __idmap_text_end            // __pa(__idmap_text_end)
> +       sub     x6, x6, #1
>

__idmap_text_end-1 should do the trick as well, no?

>         map_memory x0, x1, x3, x6, x7, x3, x4, x10, x11, x12, x13, x14
>
> @@ -366,6 +367,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
>         add     x5, x5, x23                     // add KASLR displacement
>         mov     x4, PTRS_PER_PGD
>         adrp    x6, _end                        // runtime __pa(_end)
> +       sub     x6, x6, #1
>         adrp    x3, _text                       // runtime __pa(_text)
>         sub     x6, x6, x3                      // _end - _text
>         add     x6, x6, x5                      // runtime __va(_end)
> --
> 2.11.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From mark.rutland at arm.com  Tue Aug 10 09:28:29 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 10 Aug 2021 17:28:29 +0100
Subject: [PATCH] arm64: head: avoid over-mapping in map_memory
In-Reply-To: <CAMj1kXG8+7MHON0MePA8+2Vji1P_9JCTTY_0f3iP0LWi1pEqcA@mail.gmail.com>
References: <20210810152756.23903-1-mark.rutland@arm.com>
 <CAMj1kXG8+7MHON0MePA8+2Vji1P_9JCTTY_0f3iP0LWi1pEqcA@mail.gmail.com>
Message-ID: <20210810162829.GC52842@C02TD0UTHF1T.local>

On Tue, Aug 10, 2021 at 06:16:49PM +0200, Ard Biesheuvel wrote:
> On Tue, 10 Aug 2021 at 17:29, Mark Rutland <mark.rutland at arm.com> wrote:
> >
> > The `compute_indices` and `populate_entries` macros operate on inclusive
> > bounds, and thus the `map_memory` macro which uses them also operates
> > on inclusive bounds.
> >
> > We pass `_end` and `_idmap_text_end` to `map_memory`, but these are
> > exclusive bounds, and if one of these is sufficiently aligned (as a
> > result of kernel configuration, physical placement, and KASLR), then:
> >
> > * In `compute_indices`, the computed `iend` will be in the page/block *after*
> >   the final byte of the intended mapping.
> >
> > * In `populate_entries`, an unnecessary entry will be created at the end
> >   of each level of table. At the leaf level, this entry will map up to
> >   SWAPPER_BLOCK_SIZE bytes of physical addresses that we did not intend
> >   to map.
> >
> > As we may map up to SWAPPER_BLOCK_SIZE bytes more than intended, we may
> > violate the boot protocol and map physical address past the 2MiB-aligned
> > end address we are permitted to map. As we map these with Normal memory
> > attributes, this may result in further problems depending on what these
> > physical addresses correspond to.
> >
> > Fix this by subtracting one from the end address in both cases, such
> > that we always use inclusive bounds. For clarity, comments are updated
> > to more clearly document that the macros expect inclusive bounds.
> >
> > Fixes: 0370b31e48454d8c ("arm64: Extend early page table code to allow for larger kernel")
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> > Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: Steve Capper <steve.capper at arm.com>
> > Cc: Will Deacon <will at kernel.org>
> > ---
> >  arch/arm64/kernel/head.S | 10 ++++++----
> >  1 file changed, 6 insertions(+), 4 deletions(-)
> >
> > I spotted this while working on some rework of the early page table code.
> > While the rest isn't ready yet, I thought I'd send this out on its own as it's
> > a fix.
> >
> > Mark.
> >
> > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> > index c5c994a73a64..f0826be4c104 100644
> > --- a/arch/arm64/kernel/head.S
> > +++ b/arch/arm64/kernel/head.S
> > @@ -176,8 +176,8 @@ SYM_CODE_END(preserve_boot_args)
> >   * were needed in the previous page table level then the next page table level is assumed
> >   * to be composed of multiple pages. (This effectively scales the end index).
> >   *
> > - *     vstart: virtual address of start of range
> > - *     vend:   virtual address of end of range
> > + *     vstart: virtual address of start of range (inclusive)
> > + *     vend:   virtual address of end of range (inclusive)
> >   *     shift:  shift used to transform virtual address into index
> >   *     ptrs:   number of entries in page table
> >   *     istart: index in table corresponding to vstart
> > @@ -214,8 +214,8 @@ SYM_CODE_END(preserve_boot_args)
> >   *
> >   *     tbl:    location of page table
> >   *     rtbl:   address to be used for first level page table entry (typically tbl + PAGE_SIZE)
> > - *     vstart: start address to map
> > - *     vend:   end address to map - we map [vstart, vend]
> > + *     vstart: virtual address of start of mapping (inclusive)
> > + *     vend:   virtual address of end of mapping (inclusive)
> >   *     flags:  flags to use to map last level entries
> >   *     phys:   physical address corresponding to vstart - physical memory is contiguous
> >   *     pgds:   the number of pgd entries
> > @@ -355,6 +355,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
> >  1:
> >         ldr_l   x4, idmap_ptrs_per_pgd
> >         adr_l   x6, __idmap_text_end            // __pa(__idmap_text_end)
> > +       sub     x6, x6, #1
> >
> 
> __idmap_text_end-1 should do the trick as well, no?

Yup. If you want, I can make that:

	adr_l   x6, __idmap_text_end - 1	// __pa(__idmap_text_end - 1)

> > @@ -366,6 +367,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables)
> >         add     x5, x5, x23                     // add KASLR displacement
> >         mov     x4, PTRS_PER_PGD
> >         adrp    x6, _end                        // runtime __pa(_end)
> > +       sub     x6, x6, #1

... and likewise here:

	adr_l x6, _end - 1			// runtime __pa(_end  - 1)

Thanks,
Mark.

> >         adrp    x3, _text                       // runtime __pa(_text)
> >         sub     x6, x6, x3                      // _end - _text
> >         add     x6, x6, x5                      // runtime __va(_end)
> > --
> > 2.11.0
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From hch at infradead.org  Tue Aug 10 09:45:04 2021
From: hch at infradead.org (Christoph Hellwig)
Date: Tue, 10 Aug 2021 17:45:04 +0100
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
Message-ID: <YRKtEDycefrZLB3X@infradead.org>

On Mon, Aug 02, 2021 at 04:23:57PM +0100, Lorenzo Pieralisi wrote:
> Add a __force attribute to the void* cast in acpi_os_map_iomem()
> to prevent sparse warnings.

Err, no.  These annotation are there for a reason and need to
be propagated instead.  And independent of that a __force cast
without a comment explaining it is a complete no-go.


From gregkh at linuxfoundation.org  Tue Aug 10 10:29:21 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 10 Aug 2021 19:29:21 +0200
Subject: [PATCH 5.10 027/135] ARM: dts: stm32: Disable LAN8710 EDPD on DHCOM
In-Reply-To: <20210810172955.660225700@linuxfoundation.org>
References: <20210810172955.660225700@linuxfoundation.org>
Message-ID: <20210810172956.599446244@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

[ Upstream commit 36862c1ebc92a7e6fcc55002965c44b8ad17d4ca ]

The LAN8710 Energy Detect Power Down (EDPD) functionality might cause
unreliable cable detection. There are multiple accounts of this in the
SMSC PHY driver patches which attempted to make EDPD reliable, however
it seems there is always some sort of corner case left. Unfortunatelly,
there is no errata documented which would confirm this to be a silicon
bug on the LAN87xx series of PHYs (LAN8700, LAN8710, LAN8720 at least).

Disable EDPD on the DHCOM SoM, just like multiple other boards already
do as well, to make the cable detection reliable.

Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
index 8221bf69fefe..000af7177701 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
@@ -133,6 +133,7 @@
 			reset-gpios = <&gpioh 3 GPIO_ACTIVE_LOW>;
 			reset-assert-us = <500>;
 			reset-deassert-us = <500>;
+			smsc,disable-energy-detect;
 			interrupt-parent = <&gpioi>;
 			interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
 		};
-- 
2.30.2





From gregkh at linuxfoundation.org  Tue Aug 10 10:29:22 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 10 Aug 2021 19:29:22 +0200
Subject: [PATCH 5.10 028/135] ARM: dts: stm32: Fix touchscreen IRQ line
 assignment on DHCOM
In-Reply-To: <20210810172955.660225700@linuxfoundation.org>
References: <20210810172955.660225700@linuxfoundation.org>
Message-ID: <20210810172956.630090823@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

[ Upstream commit 15f68f027ebd961b99a1c420f96ff3838c5e4450 ]

While 7e5f3155dcbb4 ("ARM: dts: stm32: Fix LED5 on STM32MP1 DHCOM PDK2")
fixed the LED0 assignment on the PDK2 board, the same commit did not
update the touchscreen IRQ line assignment, which is the same GPIO line,
shared between the LED0 output and touchscreen IRQ input. To make this
more convoluted, the same EXTI input (not the same GPIO line) is shared
between Button B which is Active-Low IRQ, and touchscreen IRQ which is
Edge-Falling IRQ, which cannot be used at the same time. In case the LCD
board with touchscreen is in use, which is the case here, LED0 must be
disabled, Button B must be polled, so the touchscreen interrupt works as
it should.

Update the touchscreen IRQ line assignment, disable LED0 and use polled
GPIO button driver for Button B, since the DT here describes baseboard
with LCD board.

Fixes: 7e5f3155dcbb4 ("ARM: dts: stm32: Fix LED5 on STM32MP1 DHCOM PDK2")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 24 +++++++++++--------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
index 59b3239bcd76..633079245601 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
@@ -37,7 +37,7 @@
 		poll-interval = <20>;
 
 		/*
-		 * The EXTi IRQ line 3 is shared with touchscreen and ethernet,
+		 * The EXTi IRQ line 3 is shared with ethernet,
 		 * so mark this as polled GPIO key.
 		 */
 		button-0 {
@@ -46,6 +46,16 @@
 			gpios = <&gpiof 3 GPIO_ACTIVE_LOW>;
 		};
 
+		/*
+		 * The EXTi IRQ line 6 is shared with touchscreen,
+		 * so mark this as polled GPIO key.
+		 */
+		button-1 {
+			label = "TA2-GPIO-B";
+			linux,code = <KEY_B>;
+			gpios = <&gpiod 6 GPIO_ACTIVE_LOW>;
+		};
+
 		/*
 		 * The EXTi IRQ line 0 is shared with PMIC,
 		 * so mark this as polled GPIO key.
@@ -60,13 +70,6 @@
 	gpio-keys {
 		compatible = "gpio-keys";
 
-		button-1 {
-			label = "TA2-GPIO-B";
-			linux,code = <KEY_B>;
-			gpios = <&gpiod 6 GPIO_ACTIVE_LOW>;
-			wakeup-source;
-		};
-
 		button-3 {
 			label = "TA4-GPIO-D";
 			linux,code = <KEY_D>;
@@ -82,6 +85,7 @@
 			label = "green:led5";
 			gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
+			status = "disabled";
 		};
 
 		led-1 {
@@ -185,8 +189,8 @@
 	touchscreen at 38 {
 		compatible = "edt,edt-ft5406";
 		reg = <0x38>;
-		interrupt-parent = <&gpiog>;
-		interrupts = <2 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */
+		interrupt-parent = <&gpioc>;
+		interrupts = <6 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */
 	};
 };
 
-- 
2.30.2





From gregkh at linuxfoundation.org  Tue Aug 10 10:29:04 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 10 Aug 2021 19:29:04 +0200
Subject: [PATCH 5.13 036/175] ARM: dts: stm32: Prefer HW RTC on DHCOM SoM
In-Reply-To: <20210810173000.928681411@linuxfoundation.org>
References: <20210810173000.928681411@linuxfoundation.org>
Message-ID: <20210810173002.144730926@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

[ Upstream commit 3a0670824979a986a2314c921aa092e60730eeae ]

The DHCOM SoM has two RTC, one is the STM32 RTC built into the SoC
and another is Microcrystal RV RTC. By default, only the later has
battery backup, the former does not. The order in which the RTCs
are probed on boot is random, which means the kernel might pick up
system time from the STM32 RTC which has no battery backup. This
then leads to incorrect initial system time setup, even though the
HW RTC has correct time configured in it.

Add DT alias entries, so that the RTCs get assigned fixed IDs and
the HW RTC is always picked by the kernel as the default RTC, thus
resulting in correct system time in early userspace.

Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
index 2af0a6752674..8349c9099e30 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
@@ -12,6 +12,8 @@
 	aliases {
 		ethernet0 = &ethernet0;
 		ethernet1 = &ksz8851;
+		rtc0 = &hwrtc;
+		rtc1 = &rtc;
 	};
 
 	memory at c0000000 {
@@ -248,7 +250,7 @@
 	/delete-property/dmas;
 	/delete-property/dma-names;
 
-	rtc at 32 {
+	hwrtc: rtc at 32 {
 		compatible = "microcrystal,rv8803";
 		reg = <0x32>;
 	};
-- 
2.30.2





From gregkh at linuxfoundation.org  Tue Aug 10 10:29:05 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 10 Aug 2021 19:29:05 +0200
Subject: [PATCH 5.13 037/175] ARM: dts: stm32: Disable LAN8710 EDPD on DHCOM
In-Reply-To: <20210810173000.928681411@linuxfoundation.org>
References: <20210810173000.928681411@linuxfoundation.org>
Message-ID: <20210810173002.177092701@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

[ Upstream commit 36862c1ebc92a7e6fcc55002965c44b8ad17d4ca ]

The LAN8710 Energy Detect Power Down (EDPD) functionality might cause
unreliable cable detection. There are multiple accounts of this in the
SMSC PHY driver patches which attempted to make EDPD reliable, however
it seems there is always some sort of corner case left. Unfortunatelly,
there is no errata documented which would confirm this to be a silicon
bug on the LAN87xx series of PHYs (LAN8700, LAN8710, LAN8720 at least).

Disable EDPD on the DHCOM SoM, just like multiple other boards already
do as well, to make the cable detection reliable.

Fixes: 34e0c7847dcf ("ARM: dts: stm32: Add DH Electronics DHCOM STM32MP1 SoM and PDK2 board")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
index 8349c9099e30..8c41f819f776 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
@@ -140,6 +140,7 @@
 			reset-gpios = <&gpioh 3 GPIO_ACTIVE_LOW>;
 			reset-assert-us = <500>;
 			reset-deassert-us = <500>;
+			smsc,disable-energy-detect;
 			interrupt-parent = <&gpioi>;
 			interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
 		};
-- 
2.30.2





From gregkh at linuxfoundation.org  Tue Aug 10 10:29:06 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 10 Aug 2021 19:29:06 +0200
Subject: [PATCH 5.13 038/175] ARM: dts: stm32: Fix touchscreen IRQ line
 assignment on DHCOM
In-Reply-To: <20210810173000.928681411@linuxfoundation.org>
References: <20210810173000.928681411@linuxfoundation.org>
Message-ID: <20210810173002.209740494@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

[ Upstream commit 15f68f027ebd961b99a1c420f96ff3838c5e4450 ]

While 7e5f3155dcbb4 ("ARM: dts: stm32: Fix LED5 on STM32MP1 DHCOM PDK2")
fixed the LED0 assignment on the PDK2 board, the same commit did not
update the touchscreen IRQ line assignment, which is the same GPIO line,
shared between the LED0 output and touchscreen IRQ input. To make this
more convoluted, the same EXTI input (not the same GPIO line) is shared
between Button B which is Active-Low IRQ, and touchscreen IRQ which is
Edge-Falling IRQ, which cannot be used at the same time. In case the LCD
board with touchscreen is in use, which is the case here, LED0 must be
disabled, Button B must be polled, so the touchscreen interrupt works as
it should.

Update the touchscreen IRQ line assignment, disable LED0 and use polled
GPIO button driver for Button B, since the DT here describes baseboard
with LCD board.

Fixes: 7e5f3155dcbb4 ("ARM: dts: stm32: Fix LED5 on STM32MP1 DHCOM PDK2")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi | 24 +++++++++++--------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
index c5ea08fec535..6cf1c8b4c6e2 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi
@@ -37,7 +37,7 @@
 		poll-interval = <20>;
 
 		/*
-		 * The EXTi IRQ line 3 is shared with touchscreen and ethernet,
+		 * The EXTi IRQ line 3 is shared with ethernet,
 		 * so mark this as polled GPIO key.
 		 */
 		button-0 {
@@ -46,6 +46,16 @@
 			gpios = <&gpiof 3 GPIO_ACTIVE_LOW>;
 		};
 
+		/*
+		 * The EXTi IRQ line 6 is shared with touchscreen,
+		 * so mark this as polled GPIO key.
+		 */
+		button-1 {
+			label = "TA2-GPIO-B";
+			linux,code = <KEY_B>;
+			gpios = <&gpiod 6 GPIO_ACTIVE_LOW>;
+		};
+
 		/*
 		 * The EXTi IRQ line 0 is shared with PMIC,
 		 * so mark this as polled GPIO key.
@@ -60,13 +70,6 @@
 	gpio-keys {
 		compatible = "gpio-keys";
 
-		button-1 {
-			label = "TA2-GPIO-B";
-			linux,code = <KEY_B>;
-			gpios = <&gpiod 6 GPIO_ACTIVE_LOW>;
-			wakeup-source;
-		};
-
 		button-3 {
 			label = "TA4-GPIO-D";
 			linux,code = <KEY_D>;
@@ -82,6 +85,7 @@
 			label = "green:led5";
 			gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>;
 			default-state = "off";
+			status = "disabled";
 		};
 
 		led-1 {
@@ -185,8 +189,8 @@
 	touchscreen at 38 {
 		compatible = "edt,edt-ft5406";
 		reg = <0x38>;
-		interrupt-parent = <&gpiog>;
-		interrupts = <2 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */
+		interrupt-parent = <&gpioc>;
+		interrupts = <6 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */
 	};
 };
 
-- 
2.30.2





From f.fainelli at gmail.com  Tue Aug 10 10:45:16 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 10 Aug 2021 10:45:16 -0700
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
 <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
Message-ID: <90af8051-512d-1230-72a7-8bbcee984939@gmail.com>



On 8/9/2021 7:21 PM, Joakim Zhang wrote:
> 
> Hi Florian,
> 
>> -----Original Message-----
>> From: Florian Fainelli <f.fainelli at gmail.com>
>> Sent: 2021?8?10? 2:40
>> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
>> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
>> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
>> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
>> netdev at vger.kernel.org; devicetree at vger.kernel.org;
>> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
>> wakeup-irq" property
>>
>>
>>
>> On 8/8/2021 10:08 PM, Joakim Zhang wrote:
>>>
>>> Hi Florian,
>>>
>>>> -----Original Message-----
>>>> From: Florian Fainelli <f.fainelli at gmail.com>
>>>> Sent: 2021?8?5? 17:18
>>>> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
>>>> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
>>>> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
>>>> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
>>>> netdev at vger.kernel.org; devicetree at vger.kernel.org;
>>>> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
>>>> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add
>>>> "fsl, wakeup-irq" property
>>>>
>>>>
>>>>
>>>> On 8/5/2021 12:46 AM, Joakim Zhang wrote:
>>>>> Add "fsl,wakeup-irq" property for FEC controller to select wakeup
>>>>> irq source.
>>>>>
>>>>> Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
>>>>> Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
>>>>
>>>> Why are not you making use of the standard interrupts-extended
>>>> property which allows different interrupt lines to be originating
>>>> from different interrupt controllers, e.g.:
>>>>
>>>> interrupts-extended = <&gic GIC_SPI 112 4>, <&wakeup_intc 0>;
>>>
>>> Thanks.
>>>
>>> AFAIK, interrupts-extended should be used instead of interrupts when a
>>> device is connected to multiple interrupt controllers as it encodes a
>>> parent phandle with each interrupt specifier. However, for FEC controller, all
>> interrupt lines are originating from the same interrupt controllers.
>>
>> OK, so why this custom property then?
>>
>>>
>>> 1) FEC controller has up to 4 interrupt lines and all of these are routed to GIC
>> interrupt controller.
>>> 2) FEC has a wakeup interrupt signal and always are mixed with other
>> interrupt signals, and then output to one interrupt line.
>>> 3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but for i.MX8M
>> serials, are mixed to int2 line.
>>> 4) Now driver treat int0 as the wakeup source by default, it is broken for
>> i.MX8M.
>>
>> I don't really know what to make of your response, it seems to me that you are
>> carrying some legacy Device Tree properties that were invented when
>> interrupts-extended did not exist and we did not know any better.
> 
> As I described in former mail, it is not related to interrupts-extended property.
> 
> Let's take a look, e.g.
> 
> 1) arch/arm/boot/dts/imx7d.dtsi
> interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
> 		<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
> 		<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
> 		<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> interrupt-names = "int0", "int1", "int2", "pps";
> 
> For these 4 interrupts are originating from GIC interrupt controller, "int0" for queue 0 and other interrupt signals, containing wakeup;
> "int1" for queue 1; "int2" for queue 2.
> 
> 2) arch/arm64/boot/dts/freescale/imx8mq.dtsi
> interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
> 	<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
> 	<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
> 	<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
> interrupt-names = "int0", "int1", "int2", "pps";
> 
> For these 4 interrupts are also originating from GIC interrupt controller, "int0" for queue 0; "int1" for queue 1; "int2" for queue 2 and other
> interrupt signals, containing wakeup.
> 
> If we want to use WoL feature, we need invoke enable_irq_wake() to let this specific interrupt line be a wakeup source. For FEC driver now,
> it treats "int0" as wakeup interrupt by default. Obviously it's not fine for i.MX8M serials, since SoC mix wakeup interrupt signal into "int2",
> so I add this "fsl,wakeup-irq" custom property to indicate which interrupt line contains wakeup signal.
> 
> Not sure if I have explained it clearly enough, from my point of view, I think interrupts-extended property can't fix this issue, right?

This is clearer, and indeed interrupts-extended won't fix that, however 
it seems to me that this is a problem that ought to be fixed at the 
interrupt controller/irq_chip level which should know and be told which 
interrupt lines can be made wake-up interrupts or not. From there on, 
the driver can test with enable_irq_wake() whether this has a chance of 
working or not.

It seems to me that the 'fsl,wakeup-irq' property ought to be within the 
interrupt controller Device Tree node (where it would be easier to 
validate that the specific interrupt line is correct) as opposed to 
within the consumer (FEC) Device Tree node.

> 
> If there is any common properties can be used for it, please let me know. Or any other better solutions also be appreciated. Thanks.

There is a standard 'wakeup-source' boolean property that can be added 
to any Device Tree node to indicate it can be a wake-up source, but what 
you need here is a bitmask, so introducing a custom property may be 
appropriate here.
-- 
Florian


From semen.protsenko at linaro.org  Tue Aug 10 10:46:24 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 10 Aug 2021 20:46:24 +0300
Subject: [PATCH v2 6/8] dt-bindings: clock: samsung: convert Exynos AudSS
 to dtschema
In-Reply-To: <20210810093145.26153-7-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-7-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4=tOpaNGs6vxwyVy7xaeX+w_jhtY2P2U8sZGvm6mdqh1Q@mail.gmail.com>

On Tue, 10 Aug 2021 at 12:32, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
> schema format using json-schema.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
>  .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
>  2 files changed, 79 insertions(+), 103 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
>
> diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
> deleted file mode 100644
> index 6030afb10b5c..000000000000
> --- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
> +++ /dev/null
> @@ -1,103 +0,0 @@
> -* Samsung Audio Subsystem Clock Controller
> -
> -The Samsung Audio Subsystem clock controller generates and supplies clocks
> -to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
> -binding described here is applicable to all SoCs in Exynos family.
> -
> -Required Properties:
> -
> -- compatible: should be one of the following:
> -  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
> -  - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
> -    SoCs.
> -  - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
> -    SoCs.
> -  - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
> -    SoCs.
> -- reg: physical base address and length of the controller's register set.
> -
> -- #clock-cells: should be 1.
> -
> -- clocks:
> -  - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
> -    is used if not specified.
> -  - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
> -    is used if not specified.
> -  - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
> -    specified.
> -  - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
> -    not specified.
> -  - sclk_pcm_in: PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not
> -    specified.
> -
> -- clock-names: Aliases for the above clocks. They should be "pll_ref",
> -  "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
> -
> -Optional Properties:
> -
> -  - power-domains: a phandle to respective power domain node as described by
> -    generic PM domain bindings (see power/power_domain.txt for more
> -    information).
> -
> -The following is the list of clocks generated by the controller. Each clock is
> -assigned an identifier and client nodes use this identifier to specify the
> -clock which they consume. Some of the clocks are available only on a particular
> -Exynos4 SoC and this is specified where applicable.
> -
> -Provided clocks:
> -
> -Clock           ID      SoC (if specific)
> ------------------------------------------------
> -
> -mout_audss      0
> -mout_i2s        1
> -dout_srp        2
> -dout_aud_bus    3
> -dout_i2s        4
> -srp_clk         5
> -i2s_bus         6
> -sclk_i2s        7
> -pcm_bus         8
> -sclk_pcm        9
> -adma            10      Exynos5420
> -
> -Example 1: An example of a clock controller node using the default input
> -          clock names is listed below.
> -
> -clock_audss: audss-clock-controller at 3810000 {
> -       compatible = "samsung,exynos5250-audss-clock";
> -       reg = <0x03810000 0x0C>;
> -       #clock-cells = <1>;
> -};
> -
> -Example 2: An example of a clock controller node with the input clocks
> -           specified.
> -
> -clock_audss: audss-clock-controller at 3810000 {
> -       compatible = "samsung,exynos5250-audss-clock";
> -       reg = <0x03810000 0x0C>;
> -       #clock-cells = <1>;
> -       clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
> -               <&ext_i2s_clk>;
> -       clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
> -};
> -
> -Example 3: I2S controller node that consumes the clock generated by the clock
> -           controller. Refer to the standard clock bindings for information
> -           about 'clocks' and 'clock-names' property.
> -
> -i2s0: i2s at 3830000 {
> -       compatible = "samsung,i2s-v5";
> -       reg = <0x03830000 0x100>;
> -       dmas = <&pdma0 10
> -               &pdma0 9
> -               &pdma0 8>;
> -       dma-names = "tx", "rx", "tx-sec";
> -       clocks = <&clock_audss EXYNOS_I2S_BUS>,
> -               <&clock_audss EXYNOS_I2S_BUS>,
> -               <&clock_audss EXYNOS_SCLK_I2S>,
> -               <&clock_audss EXYNOS_MOUT_AUDSS>,
> -               <&clock_audss EXYNOS_MOUT_I2S>;
> -       clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
> -                     "mout_audss", "mout_i2s";
> -};

Seems like some examples and "Provided clocks" table were dropped in
in yaml binding. Also there is no description for example present in
yaml file. Is that some redundant info and was dropped intentionally?
I'm just worrying about losing some useful info during the conversion.

> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
> new file mode 100644
> index 000000000000..d60b29fa22e7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
> @@ -0,0 +1,79 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/samsung,exynos-audss-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung Exynos SoC Audio SubSystem clock controller
> +
> +maintainers:
> +  - Chanwoo Choi <cw00.choi at samsung.com>
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  All available clocks are defined as preprocessor macros in
> +  include/dt-bindings/clock/exynos-audss-clk.h header.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - samsung,exynos4210-audss-clock
> +      - samsung,exynos5250-audss-clock
> +      - samsung,exynos5410-audss-clock
> +      - samsung,exynos5420-audss-clock
> +
> +  clocks:
> +    minItems: 2
> +    items:
> +      - description:
> +          Fixed rate PLL reference clock, parent of mout_audss. "fin_pll" is
> +          used if not specified.
> +      - description:
> +          Input PLL to the AudioSS block, parent of mout_audss. "fout_epll" is
> +          used if not specified.
> +      - description:
> +          Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if not
> +          specified.
> +      - description:
> +          PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not specified.
> +      - description:
> +          External i2s clock, parent of mout_i2s. "cdclk0" is used if not
> +          specified.
> +
> +  clock-names:
> +    minItems: 2
> +    items:
> +      - const: pll_ref
> +      - const: pll_in
> +      - const: sclk_audio
> +      - const: sclk_pcm_in
> +      - const: cdclk
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  power-domains: true
> +
> +  reg:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - "#clock-cells"
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    clock-controller at 3810000 {
> +        compatible = "samsung,exynos5250-audss-clock";
> +        reg = <0x03810000 0x0c>;
> +        #clock-cells = <1>;
> +        clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>, <&ext_i2s_clk>;
> +        clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
> +    };
> --
> 2.30.2
>


From semen.protsenko at linaro.org  Tue Aug 10 10:49:52 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 10 Aug 2021 20:49:52 +0300
Subject: [PATCH v2 2/8] dt-bindings: clock: samsung: add bindings for
 Exynos external clock
In-Reply-To: <20210810093145.26153-3-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-3-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4mKv0Azi4w2S=Ono1gpghmBtfy4QpaRBjtHkgrUGZVW_Q@mail.gmail.com>

On Tue, 10 Aug 2021 at 12:32, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Document the bindings for Samsung Exynos external to SoC
> (oscclk/XXTI/XusbXTI) clock provided on boards.  The bindings are
> already implemented in most of the Exynos clock drivers and DTS files.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Just want to mention that remaining users of such fixed clocks can be
converted to regular fixed-rate-clock, and then this binding can be
removed along with samsung_clk_of_register_fixed_ext() API? Just a
thought.

>  .../clock/samsung,exynos-ext-clock.yaml       | 46 +++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
>
> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
> new file mode 100644
> index 000000000000..64d027dbe3b2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
> @@ -0,0 +1,46 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/samsung,exynos-ext-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung SoC external/osc/XXTI/XusbXTI clock
> +
> +maintainers:
> +  - Chanwoo Choi <cw00.choi at samsung.com>
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  Samsung SoCs require an external clock supplied through XXTI or XusbXTI pins.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - samsung,clock-xxti
> +      - samsung,clock-xusbxti
> +      - samsung,exynos5420-oscclk
> +
> +  "#clock-cells":
> +    const: 0
> +
> +  clock-frequency: true
> +
> +  clock-output-names:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - clock-frequency
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    fixed-rate-clocks {
> +        clock {
> +            compatible = "samsung,clock-xxti";
> +            clock-frequency = <24000000>;
> +        };
> +    };
> --
> 2.30.2
>


From semen.protsenko at linaro.org  Tue Aug 10 10:51:35 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 10 Aug 2021 20:51:35 +0300
Subject: [PATCH v2 1/8] dt-bindings: clock: samsung: convert Exynos5250 to
 dtschema
In-Reply-To: <20210810093145.26153-2-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-2-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4njX-R2e66qcCz=OT_bYKTRLHTH4nFv==EEovJyjN8qAg@mail.gmail.com>

On Tue, 10 Aug 2021 at 12:32, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Convert Samsung Exynos5250 clock controller bindings to DT schema format
> using json-schema.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos5250-clock.txt       | 41 ----------------
>  .../bindings/clock/samsung,exynos-clock.yaml  | 48 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  3 files changed, 49 insertions(+), 41 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>
> diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
> deleted file mode 100644
> index aff266a12eeb..000000000000
> --- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
> +++ /dev/null
> @@ -1,41 +0,0 @@
> -* Samsung Exynos5250 Clock Controller
> -
> -The Exynos5250 clock controller generates and supplies clock to various
> -controllers within the Exynos5250 SoC.
> -
> -Required Properties:
> -
> -- compatible: should be one of the following.
> -  - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
> -
> -- reg: physical base address of the controller and length of memory mapped
> -  region.
> -
> -- #clock-cells: should be 1.
> -
> -Each clock is assigned an identifier and client nodes can use this identifier
> -to specify the clock which they consume.
> -
> -All available clocks are defined as preprocessor macros in
> -dt-bindings/clock/exynos5250.h header and can be used in device
> -tree sources.
> -
> -Example 1: An example of a clock controller node is listed below.
> -
> -       clock: clock-controller at 10010000 {
> -               compatible = "samsung,exynos5250-clock";
> -               reg = <0x10010000 0x30000>;
> -               #clock-cells = <1>;
> -       };
> -
> -Example 2: UART controller node that consumes the clock generated by the clock
> -          controller. Refer to the standard clock bindings for information
> -          about 'clocks' and 'clock-names' property.
> -
> -       serial at 13820000 {
> -               compatible = "samsung,exynos4210-uart";
> -               reg = <0x13820000 0x100>;
> -               interrupts = <0 54 0>;
> -               clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
> -               clock-names = "uart", "clk_uart_baud0";
> -       };
> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> new file mode 100644
> index 000000000000..cd6567bd8cc7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> @@ -0,0 +1,48 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/samsung,exynos-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung Exynos SoC clock controller
> +
> +maintainers:
> +  - Chanwoo Choi <cw00.choi at samsung.com>
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  All available clocks are defined as preprocessor macros in
> +  dt-bindings/clock/ headers.
> +
> +properties:
> +  compatible:
> +    const: samsung,exynos5250-clock
> +
> +  assigned-clocks: true
> +  assigned-clock-parents: true
> +  assigned-clock-rates: true
> +  clocks: true
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  reg:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - "#clock-cells"
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/exynos5250.h>
> +    clock: clock-controller at 10010000 {
> +        compatible = "samsung,exynos5250-clock";
> +        reg = <0x10010000 0x30000>;
> +        #clock-cells = <1>;
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 36aee8517ab0..2dbacacac3f5 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16491,6 +16491,7 @@ L:      linux-samsung-soc at vger.kernel.org
>  S:     Supported
>  T:     git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
>  F:     Documentation/devicetree/bindings/clock/exynos*.txt

Are there any exynos*.txt bindings actually left after this series? If
no, maybe it's worth to remove this line while at it.

> +F:     Documentation/devicetree/bindings/clock/samsung,*.yaml
>  F:     Documentation/devicetree/bindings/clock/samsung,s3c*
>  F:     Documentation/devicetree/bindings/clock/samsung,s5p*
>  F:     drivers/clk/samsung/
> --
> 2.30.2
>


From semen.protsenko at linaro.org  Tue Aug 10 10:52:30 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Tue, 10 Aug 2021 20:52:30 +0300
Subject: [PATCH v2 0/8] dt-bindings: clock: samsung: convert to dtschema
In-Reply-To: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4nx68hsz_+W5MtB3CfE0GsFwMLMRYh-ksq2CHZ84eCLcg@mail.gmail.com>

Hi Krzysztof,

On Tue, 10 Aug 2021 at 12:32, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Hi,
>
> Combined patchset of separate v1 sets:
>
> https://lore.kernel.org/linux-samsung-soc/20210809120544.56596-1-krzysztof.kozlowski at canonical.com/T/#t
> https://lore.kernel.org/linux-samsung-soc/20210809130935.80565-1-krzysztof.kozlowski at canonical.com/T/#t
> https://lore.kernel.org/linux-samsung-soc/20210809135942.100744-1-krzysztof.kozlowski at canonical.com/T/#t
>
> Changes since v1:
> 1. Patch 7/8: include header to fix clock IDs error in example.
>
> Best regards,
> Krzysztof
>
>
> Krzysztof Kozlowski (8):
>   dt-bindings: clock: samsung: convert Exynos5250 to dtschema
>   dt-bindings: clock: samsung: add bindings for Exynos external clock
>   dt-bindings: clock: samsung: convert Exynos542x to dtschema
>   dt-bindings: clock: samsung: convert Exynos3250 to dtschema
>   dt-bindings: clock: samsung: convert Exynos4 to dtschema
>   dt-bindings: clock: samsung: convert Exynos AudSS to dtschema
>   dt-bindings: clock: samsung: convert S5Pv210 AudSS to dtschema
>   MAINTAINERS: clock: include S3C and S5P in Samsung SoC clock entry
>
>  .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
>  .../bindings/clock/clk-s5pv210-audss.txt      |  53 ---------
>  .../bindings/clock/exynos3250-clock.txt       |  57 ----------
>  .../bindings/clock/exynos4-clock.txt          |  86 ---------------
>  .../bindings/clock/exynos5250-clock.txt       |  41 -------
>  .../bindings/clock/exynos5420-clock.txt       |  42 -------
>  .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
>  .../bindings/clock/samsung,exynos-clock.yaml  |  87 +++++++++++++++
>  .../clock/samsung,exynos-ext-clock.yaml       |  46 ++++++++
>  .../clock/samsung,s5pv210-audss-clock.yaml    |  77 +++++++++++++
>  MAINTAINERS                                   |   4 +
>  11 files changed, 293 insertions(+), 382 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos3250-clock.txt
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
>
> --

For the whole series:

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

Thanks!

> 2.30.2
>


From oupton at google.com  Tue Aug 10 10:55:12 2021
From: oupton at google.com (Oliver Upton)
Date: Tue, 10 Aug 2021 10:55:12 -0700
Subject: [PATCH v6 17/21] KVM: arm64: Allow userspace to configure a
 guest's counter-timer offset
In-Reply-To: <87a6lpbmbb.wl-maz@kernel.org>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-18-oupton@google.com>
 <87a6lpbmbb.wl-maz@kernel.org>
Message-ID: <CAOQ_Qsjn4UK81qBj-uPzoejNc4GAnZXPi=mvcoVi15N0_kayAw@mail.gmail.com>

On Tue, Aug 10, 2021 at 3:56 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Wed, 04 Aug 2021 09:58:15 +0100,
> Oliver Upton <oupton at google.com> wrote:
> >
> > Presently, KVM provides no facilities for correctly migrating a guest
> > that depends on the physical counter-timer. Whie most guests (barring
>
> nit: While

Ack.

>
> > NV, of course) should not depend on the physical counter-timer, an
> > operator may wish to provide a consistent view of the physical
> > counter-timer across migrations.
> >
> > Provide userspace with a new vCPU attribute to modify the guest
> > counter-timer offset. Unlike KVM_REG_ARM_TIMER_OFFSET, this attribute is
> > hidden from the guest's architectural state. The value offsets *both*
> > the virtual and physical counter-timer views for the guest. Only support
> > this attribute on ECV systems as ECV is required for hardware offsetting
> > of the physical counter-timer.
> >
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > ---
> >  Documentation/virt/kvm/devices/vcpu.rst |  28 ++++++
> >  arch/arm64/include/asm/kvm_asm.h        |   2 +
> >  arch/arm64/include/asm/sysreg.h         |   2 +
> >  arch/arm64/include/uapi/asm/kvm.h       |   1 +
> >  arch/arm64/kvm/arch_timer.c             | 122 +++++++++++++++++++++++-
> >  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |   6 ++
> >  arch/arm64/kvm/hyp/nvhe/timer-sr.c      |   5 +
> >  arch/arm64/kvm/hyp/vhe/timer-sr.c       |   5 +
> >  include/clocksource/arm_arch_timer.h    |   1 +
> >  9 files changed, 169 insertions(+), 3 deletions(-)
> >
> > diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
> > index 3b399d727c11..3ba35b9d9d03 100644
> > --- a/Documentation/virt/kvm/devices/vcpu.rst
> > +++ b/Documentation/virt/kvm/devices/vcpu.rst
> > @@ -139,6 +139,34 @@ configured values on other VCPUs.  Userspace should configure the interrupt
> >  numbers on at least one VCPU after creating all VCPUs and before running any
> >  VCPUs.
> >
> > +2.2. ATTRIBUTE: KVM_ARM_VCPU_TIMER_OFFSET
> > +-----------------------------------------
> > +
> > +:Parameters: in kvm_device_attr.addr the address for the timer offset is a
> > +             pointer to a __u64
> > +
> > +Returns:
> > +
> > +      ======= ==================================
> > +      -EFAULT Error reading/writing the provided
> > +              parameter address
> > +      -ENXIO  Timer offsetting not implemented
> > +      ======= ==================================
> > +
> > +Specifies the guest's counter-timer offset from the host's virtual counter.
> > +The guest's physical counter value is then derived by the following
> > +equation:
> > +
> > +  guest_cntpct = host_cntvct - KVM_ARM_VCPU_TIMER_OFFSET
> > +
> > +The guest's virtual counter value is derived by the following equation:
> > +
> > +  guest_cntvct = host_cntvct - KVM_REG_ARM_TIMER_OFFSET
> > +                     - KVM_ARM_VCPU_TIMER_OFFSET
> > +
> > +KVM does not allow the use of varying offset values for different vCPUs;
> > +the last written offset value will be broadcasted to all vCPUs in a VM.
> > +
> >  3. GROUP: KVM_ARM_VCPU_PVTIME_CTRL
> >  ==================================
> >
> > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> > index 9f0bf2109be7..ab1c8fdb0177 100644
> > --- a/arch/arm64/include/asm/kvm_asm.h
> > +++ b/arch/arm64/include/asm/kvm_asm.h
> > @@ -65,6 +65,7 @@
> >  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize           19
> >  #define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp                        20
> >  #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc                        21
> > +#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntpoff                22
> >
> >  #ifndef __ASSEMBLY__
> >
> > @@ -200,6 +201,7 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
> >  extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
> >
> >  extern void __kvm_timer_set_cntvoff(u64 cntvoff);
> > +extern void __kvm_timer_set_cntpoff(u64 cntpoff);
> >
> >  extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
> >
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 4dfc44066dfb..c34672aa65b9 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -586,6 +586,8 @@
> >  #define SYS_ICH_LR14_EL2             __SYS__LR8_EL2(6)
> >  #define SYS_ICH_LR15_EL2             __SYS__LR8_EL2(7)
> >
> > +#define SYS_CNTPOFF_EL2                      sys_reg(3, 4, 14, 0, 6)
> > +
> >  /* VHE encodings for architectural EL0/1 system registers */
> >  #define SYS_SCTLR_EL12                       sys_reg(3, 5, 1, 0, 0)
> >  #define SYS_CPACR_EL12                       sys_reg(3, 5, 1, 0, 2)
> > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> > index 949a31bc10f0..15150f8224a1 100644
> > --- a/arch/arm64/include/uapi/asm/kvm.h
> > +++ b/arch/arm64/include/uapi/asm/kvm.h
> > @@ -366,6 +366,7 @@ struct kvm_arm_copy_mte_tags {
> >  #define KVM_ARM_VCPU_TIMER_CTRL              1
> >  #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER              0
> >  #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER              1
> > +#define   KVM_ARM_VCPU_TIMER_OFFSET          2
> >  #define KVM_ARM_VCPU_PVTIME_CTRL     2
> >  #define   KVM_ARM_VCPU_PVTIME_IPA    0
> >
> > diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> > index a8815b09da3e..f15058612994 100644
> > --- a/arch/arm64/kvm/arch_timer.c
> > +++ b/arch/arm64/kvm/arch_timer.c
> > @@ -85,11 +85,15 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
> >  static u64 timer_get_offset(struct arch_timer_context *ctxt)
> >  {
> >       struct kvm_vcpu *vcpu = ctxt->vcpu;
> > +     struct arch_timer_cpu *timer = vcpu_timer(vcpu);
>
> Unused variable?

Yep!

> >
> >       switch(arch_timer_ctx_index(ctxt)) {
> >       case TIMER_VTIMER:
> > +     case TIMER_PTIMER:
> >               return ctxt->host_offset;
> >       default:
> > +             WARN_ONCE(1, "unrecognized timer %ld\n",
> > +                       arch_timer_ctx_index(ctxt));
> >               return 0;
> >       }
> >  }
> > @@ -144,6 +148,7 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
> >
> >       switch(arch_timer_ctx_index(ctxt)) {
> >       case TIMER_VTIMER:
> > +     case TIMER_PTIMER:
> >               ctxt->host_offset = offset;
> >               break;
> >       default:
> > @@ -572,6 +577,11 @@ static void set_cntvoff(u64 cntvoff)
> >       kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff);
> >  }
> >
> > +static void set_cntpoff(u64 cntpoff)
> > +{
> > +     kvm_call_hyp(__kvm_timer_set_cntpoff, cntpoff);
> > +}
> > +
> >  static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active)
> >  {
> >       int r;
> > @@ -647,6 +657,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
> >       }
> >
> >       set_cntvoff(timer_get_offset(map.direct_vtimer));
> > +     if (cpus_have_const_cap(ARM64_ECV))
>
> This really should be a final cap instead (same for all the other use
> cases).

Ack.

> > +             set_cntpoff(timer_get_offset(vcpu_ptimer(vcpu)));
>
> However, tripping to EL2 for each offset on nVHE may prove to be an
> unnecessary overhead. Not a problem for now anyway.
>
> >
> >       kvm_timer_unblocking(vcpu);
> >
> > @@ -814,6 +826,22 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
> >       mutex_unlock(&kvm->lock);
> >  }
> >
> > +static void update_ptimer_cntpoff(struct kvm_vcpu *vcpu, u64 cntpoff)
> > +{
> > +     struct kvm *kvm = vcpu->kvm;
> > +     u64 cntvoff;
> > +
> > +     mutex_lock(&kvm->lock);
> > +
> > +     /* adjustments to the physical offset also affect vtimer */
> > +     cntvoff = timer_get_offset(vcpu_vtimer(vcpu));
> > +     cntvoff += cntpoff - timer_get_offset(vcpu_ptimer(vcpu));
> > +
> > +     update_timer_offset(vcpu, TIMER_PTIMER, cntpoff, false);
> > +     update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, false);
> > +     mutex_unlock(&kvm->lock);
> > +}
> > +
> >  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
> >  {
> >       struct arch_timer_cpu *timer = vcpu_timer(vcpu);
> > @@ -932,6 +960,29 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
> >       return (u64)-1;
> >  }
> >
> > +/**
> > + * kvm_arm_timer_read_offset - returns the guest value of CNTVOFF_EL2.
> > + * @vcpu: the vcpu pointer
> > + *
> > + * Computes the guest value of CNTVOFF_EL2 by subtracting the physical
> > + * counter offset. Note that KVM defines CNTVOFF_EL2 as the offset from the
> > + * guest's physical counter-timer, not the host's.
> > + *
> > + * Returns: the guest value for CNTVOFF_EL2
> > + */
> > +static u64 kvm_arm_timer_read_offset(struct kvm_vcpu *vcpu)
> > +{
> > +     struct kvm *kvm = vcpu->kvm;
> > +     u64 offset;
> > +
> > +     mutex_lock(&kvm->lock);
> > +     offset = timer_get_offset(vcpu_vtimer(vcpu)) -
> > +                     timer_get_offset(vcpu_ptimer(vcpu));
>
> nit: please keep this on a single line.
>
> > +     mutex_unlock(&kvm->lock);
> > +
> > +     return offset;
> > +}
> > +
> >  static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
> >                             struct arch_timer_context *timer,
> >                             enum kvm_arch_timer_regs treg)
> > @@ -957,7 +1008,7 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
> >               break;
> >
> >       case TIMER_REG_OFFSET:
> > -             val = timer_get_offset(timer);
> > +             val = kvm_arm_timer_read_offset(vcpu);
> >               break;
> >
> >       default:
> > @@ -1350,6 +1401,9 @@ void kvm_timer_init_vhe(void)
> >       val = read_sysreg(cnthctl_el2);
> >       val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
> >       val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
> > +
> > +     if (cpus_have_const_cap(ARM64_ECV))
> > +             val |= CNTHCTL_ECV;
>
> I cannot immediately see where you are doing the equivalent enablement
> of ECV on the nVHE path. Obviously, it has to be done eagerly from
> EL2, together with the rest of the EL1 timer setup. Something like:

Yep, I had caught this when I was actually able to run the Base FVP. I
have a fix (same as yours, basically) but held back until you reviewed
to avoid storming your inbox :)

> diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> index 9072e71693ba..999931fe55d2 100644
> --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> @@ -26,6 +26,8 @@ void __timer_disable_traps(struct kvm_vcpu *vcpu)
>         /* Allow physical timer/counter access for the host */
>         val = read_sysreg(cnthctl_el2);
>         val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
> +       if (cpus_have_final_cap(ARM64_ECV))
> +               val |= CNTHCTL_ECV;
>         write_sysreg(val, cnthctl_el2);
>  }
>
> @@ -42,6 +44,8 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
>          * Physical counter access is allowed
>          */
>         val = read_sysreg(cnthctl_el2);
> +       if (cpus_have_final_cap(ARM64_ECV))
> +               val &= ~CNTHCTL_ECV;
>         val &= ~CNTHCTL_EL1PCEN;
>         val |= CNTHCTL_EL1PCTEN;
>         write_sysreg(val, cnthctl_el2);
>
> This will ensure that only the guest sees the physical offset.
>
> >       write_sysreg(val, cnthctl_el2);
> >  }
> >
> > @@ -1364,7 +1418,8 @@ static void set_timer_irqs(struct kvm *kvm, int vtimer_irq, int ptimer_irq)
> >       }
> >  }
> >
> > -int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> > +static int kvm_arm_timer_set_attr_irq(struct kvm_vcpu *vcpu,
> > +                                   struct kvm_device_attr *attr)
> >  {
> >       int __user *uaddr = (int __user *)(long)attr->addr;
> >       struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
> > @@ -1397,7 +1452,37 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> >       return 0;
> >  }
> >
> > -int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> > +static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
> > +                                      struct kvm_device_attr *attr)
> > +{
> > +     u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> > +     u64 offset;
> > +
> > +     if (!cpus_have_const_cap(ARM64_ECV))
> > +             return -ENXIO;
> > +
> > +     if (get_user(offset, uaddr))
> > +             return -EFAULT;
> > +
> > +     update_ptimer_cntpoff(vcpu, offset);
> > +     return 0;
> > +}
> > +
> > +int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> > +{
> > +     switch (attr->attr) {
> > +     case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> > +     case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> > +             return kvm_arm_timer_set_attr_irq(vcpu, attr);
> > +     case KVM_ARM_VCPU_TIMER_OFFSET:
> > +             return kvm_arm_timer_set_attr_offset(vcpu, attr);
> > +     default:
> > +             return -ENXIO;
> > +     }
> > +}
> > +
> > +static int kvm_arm_timer_get_attr_irq(struct kvm_vcpu *vcpu,
> > +                                   struct kvm_device_attr *attr)
> >  {
> >       int __user *uaddr = (int __user *)(long)attr->addr;
> >       struct arch_timer_context *timer;
> > @@ -1418,12 +1503,43 @@ int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> >       return put_user(irq, uaddr);
> >  }
> >
> > +static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
> > +                                      struct kvm_device_attr *attr)
> > +{
> > +     u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> > +     u64 offset;
> > +
> > +     if (!cpus_have_const_cap(ARM64_ECV))
> > +             return -ENXIO;
> > +
> > +     offset = timer_get_offset(vcpu_ptimer(vcpu));
> > +     return put_user(offset, uaddr);
> > +}
> > +
> > +int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu,
> > +                        struct kvm_device_attr *attr)
> > +{
> > +     switch (attr->attr) {
> > +     case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> > +     case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> > +             return kvm_arm_timer_get_attr_irq(vcpu, attr);
> > +     case KVM_ARM_VCPU_TIMER_OFFSET:
> > +             return kvm_arm_timer_get_attr_offset(vcpu, attr);
> > +     default:
> > +             return -ENXIO;
> > +     }
> > +}
> > +
> >  int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> >  {
> >       switch (attr->attr) {
> >       case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> >       case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> >               return 0;
> > +     case KVM_ARM_VCPU_TIMER_OFFSET:
> > +             if (cpus_have_const_cap(ARM64_ECV))
> > +                     return 0;
> > +             break;
> >       }
> >
> >       return -ENXIO;
> > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > index 1632f001f4ed..cfa923df3af6 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> > @@ -68,6 +68,11 @@ static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt)
> >       __kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1));
> >  }
> >
> > +static void handle___kvm_timer_set_cntpoff(struct kvm_cpu_context *host_ctxt)
> > +{
> > +     __kvm_timer_set_cntpoff(cpu_reg(host_ctxt, 1));
> > +}
> > +
> >  static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt)
> >  {
> >       u64 tmp;
> > @@ -197,6 +202,7 @@ static const hcall_t host_hcall[] = {
> >       HANDLE_FUNC(__pkvm_create_private_mapping),
> >       HANDLE_FUNC(__pkvm_prot_finalize),
> >       HANDLE_FUNC(__pkvm_mark_hyp),
> > +     HANDLE_FUNC(__kvm_timer_set_cntpoff),
> >  };
> >
> >  static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> > diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> > index 9072e71693ba..5b8b4cd02506 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> > @@ -15,6 +15,11 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
> >       write_sysreg(cntvoff, cntvoff_el2);
> >  }
> >
> > +void __kvm_timer_set_cntpoff(u64 cntpoff)
> > +{
> > +     write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
> > +}
> > +
> >  /*
> >   * Should only be called on non-VHE systems.
> >   * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe().
> > diff --git a/arch/arm64/kvm/hyp/vhe/timer-sr.c b/arch/arm64/kvm/hyp/vhe/timer-sr.c
> > index 4cda674a8be6..231e16a071a5 100644
> > --- a/arch/arm64/kvm/hyp/vhe/timer-sr.c
> > +++ b/arch/arm64/kvm/hyp/vhe/timer-sr.c
> > @@ -10,3 +10,8 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
> >  {
> >       write_sysreg(cntvoff, cntvoff_el2);
> >  }
> > +
> > +void __kvm_timer_set_cntpoff(u64 cntpoff)
> > +{
> > +     write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
> > +}
> > diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
> > index 73c7139c866f..7252ffa3d675 100644
> > --- a/include/clocksource/arm_arch_timer.h
> > +++ b/include/clocksource/arm_arch_timer.h
> > @@ -21,6 +21,7 @@
> >  #define CNTHCTL_EVNTEN                       (1 << 2)
> >  #define CNTHCTL_EVNTDIR                      (1 << 3)
> >  #define CNTHCTL_EVNTI                        (0xF << 4)
> > +#define CNTHCTL_ECV                  (1 << 12)
> >
> >  enum arch_timer_reg {
> >       ARCH_TIMER_REG_CTRL,
>
> You also want to document that SCR_EL3.ECVEn has to be set to 1 for
> this to work (see Documentation/arm64/booting.txt). And if it isn't,
> the firmware better handle the CNTPOFF_EL2 traps correctly...

I'll grab the popcorn now ;-) Adding docs for this, good idea.

> What firmware did you use for this? I think we need to update the boot
> wrapper, but that's something that can be done in parallel.

I had actually just done a direct boot from ARM-TF -> Linux, nothing
else in between.

--
Thanks,
Oliver


From will at kernel.org  Tue Aug 10 11:08:28 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 19:08:28 +0100
Subject: [PATCHv3] iommu/arm-smmu: Optimize ->tlb_flush_walk() for qcom
 implementation
In-Reply-To: <584e31653ee0e01d249e414dbbc816ea@codeaurora.org>
References: <20210623134201.16140-1-saiprakash.ranjan@codeaurora.org>
 <20210802154308.GG28735@willie-the-truck>
 <584e31653ee0e01d249e414dbbc816ea@codeaurora.org>
Message-ID: <20210810180827.GA3296@willie-the-truck>

On Tue, Aug 03, 2021 at 11:09:17AM +0530, Sai Prakash Ranjan wrote:
> On 2021-08-02 21:13, Will Deacon wrote:
> > On Wed, Jun 23, 2021 at 07:12:01PM +0530, Sai Prakash Ranjan wrote:
> > > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > > b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > > index d3c6f54110a5..f3845e822565 100644
> > > --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> > > @@ -341,6 +341,12 @@ static void arm_smmu_tlb_add_page_s1(struct
> > > iommu_iotlb_gather *gather,
> > >  				  ARM_SMMU_CB_S1_TLBIVAL);
> > >  }
> > > 
> > > +static void arm_smmu_tlb_inv_walk_impl_s1(unsigned long iova,
> > > size_t size,
> > > +				     size_t granule, void *cookie)
> > > +{
> > > +	arm_smmu_tlb_inv_context_s1(cookie);
> > > +}
> > > +
> > >  static void arm_smmu_tlb_inv_walk_s2(unsigned long iova, size_t size,
> > >  				     size_t granule, void *cookie)
> > >  {
> > > @@ -388,6 +394,12 @@ static const struct iommu_flush_ops
> > > arm_smmu_s1_tlb_ops = {
> > >  	.tlb_add_page	= arm_smmu_tlb_add_page_s1,
> > >  };
> > > 
> > > +const struct iommu_flush_ops arm_smmu_s1_tlb_impl_ops = {
> > > +	.tlb_flush_all	= arm_smmu_tlb_inv_context_s1,
> > > +	.tlb_flush_walk	= arm_smmu_tlb_inv_walk_impl_s1,
> > > +	.tlb_add_page	= arm_smmu_tlb_add_page_s1,
> > > +};
> > 
> > Hmm, dunno about this. Wouldn't it be a lot cleaner if the
> > tlb_flush_walk
> > callbacks just did the right thing based on the smmu_domain (maybe in
> > the
> > arm_smmu_cfg?) rather than having an entirely new set of ops just
> > because
> > they're const and you can't overide the bit you want?
> > 
> > I don't think there's really an awful lot qcom-specific about the
> > principle
> > here -- there's a trade-off between over-invalidation and invalidation
> > latency. That happens on the CPU as well.
> > 
> 
> Sorry didn't understand, based on smmu_domain what? How do we make
> this implementation specific? Do you mean something like a quirk?
> The reason we didn't make this common was because nvidia folks weren't
> so happy with that, you can find the discussion in this thread [1].
> 
> [1] https://lore.kernel.org/lkml/20210609145315.25750-1-saiprakash.ranjan at codeaurora.org/

The ->tlb_flush_walk() callbacks take a 'void *cookie' which, for this
driver, is a 'struct arm_smmu_domain *'. From that, you can get to the
'struct arm_smmu_cfg' which could have something as coarse as:

	bool	flush_walk_prefer_tlbiasid;

which you can set when you initialise the domain (maybe in the
->init_context callback?). It shouldn't affect anybody else.

Will


From will at kernel.org  Tue Aug 10 11:24:54 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 19:24:54 +0100
Subject: [PATCH RFC 2/8] iommu/arm-smmu-v3: Add and use static helper
 function arm_smmu_cmdq_issue_cmd_with_sync()
In-Reply-To: <20210626110130.2416-3-thunder.leizhen@huawei.com>
References: <20210626110130.2416-1-thunder.leizhen@huawei.com>
 <20210626110130.2416-3-thunder.leizhen@huawei.com>
Message-ID: <20210810182454.GB3296@willie-the-truck>

On Sat, Jun 26, 2021 at 07:01:24PM +0800, Zhen Lei wrote:
> The obvious key to the performance optimization of commit 587e6c10a7ce
> ("iommu/arm-smmu-v3: Reduce contention during command-queue insertion") is
> to allow multiple cores to insert commands in parallel after a brief mutex
> contention.
> 
> Obviously, inserting as many commands at a time as possible can reduce the
> number of times the mutex contention participates, thereby improving the
> overall performance. At least it reduces the number of calls to function
> arm_smmu_cmdq_issue_cmdlist().
> 
> Therefore, function arm_smmu_cmdq_issue_cmd_with_sync() is added to insert
> the 'cmd+sync' commands at a time.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 33 +++++++++++++--------
>  1 file changed, 21 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 2433d3c29b49ff2..a5361153ca1d6a4 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -858,11 +858,25 @@ static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
>  	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
>  }
>  
> -static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
> +static int __maybe_unused arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
>  {
>  	return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
>  }
>  
> +static int arm_smmu_cmdq_issue_cmd_with_sync(struct arm_smmu_device *smmu,
> +					     struct arm_smmu_cmdq_ent *ent)
> +{
> +	u64 cmd[CMDQ_ENT_DWORDS];
> +
> +	if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
> +		dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
> +			 ent->opcode);
> +		return -EINVAL;
> +	}
> +
> +	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, true);
> +}

This function is almost identical to arm_smmu_cmdq_issue_cmd(). How about
moving the guts out into a helper:

	static int __arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
					     struct arm_smmu_cmdq_ent *ent,
					     bool sync);

and then having arm_smmu_cmdq_issue_cmd_with_sync() and
arm_smmu_cmdq_issue_cmd() wrap that?

Will


From will at kernel.org  Tue Aug 10 11:35:30 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 19:35:30 +0100
Subject: [PATCH RFC 0/8] iommu/arm-smmu-v3: add support for ECMDQ
 register mode
In-Reply-To: <20210626110130.2416-1-thunder.leizhen@huawei.com>
References: <20210626110130.2416-1-thunder.leizhen@huawei.com>
Message-ID: <20210810183529.GC3296@willie-the-truck>

On Sat, Jun 26, 2021 at 07:01:22PM +0800, Zhen Lei wrote:
> SMMU v3.3 added a new feature, which is Enhanced Command queue interface
> for reducing contention when submitting Commands to the SMMU, in this
> patch set, ECMDQ is the abbreviation of Enhanced Command Queue.
> 
> When the hardware supports ECMDQ and each core can exclusively use one ECMDQ,
> each core does not need to compete with other cores when using its own ECMDQ.
> This means that each core can insert commands in parallel. If each ECMDQ can
> execute commands in parallel, the overall performance may be better. However,
> our hardware currently does not support multiple ECMDQ execute commands in
> parallel.
> 
> In order to reuse existing code, I originally still call arm_smmu_cmdq_issue_cmdlist()
> to insert commands. Even so, however, there was a performance improvement of nearly 12%
> in strict mode.
> 
> The test environment is the EMU, which simulates the connection of the 200 Gbit/s NIC.
> Number of queues:    passthrough   lazy   strict(ECMDQ)  strict(CMDQ)
>       6                  188        180       162           145        --> 11.7% improvement
>       8                  188        188       184           183        --> 0.55% improvement

Sorry, I don't quite follow the numbers here. Why does the number of queues
affect the classic "CMDQ" mode? We only have one queue there, right?

> In recent days, I implemented a new function without competition with other
> cores to replace arm_smmu_cmdq_issue_cmdlist() when a core can have an ECMDQ.
> I'm guessing it might get better performance results. Because the EMU is too
> slow, it will take a while before the relevant data is available.

I'd certainly prefer to wait until we have something we know is
representative. However, I can take the first four prep patches now if you
respin the second one. At least that's then less for you to carry.

I'd also like review from the Arm side on this (and thank you for adopting
the architecture unlike others seem to have done judging by the patches
floating around).

Will


From frank.li at nxp.com  Tue Aug 10 11:50:18 2021
From: frank.li at nxp.com (Frank Li)
Date: Tue, 10 Aug 2021 18:50:18 +0000
Subject: [EXT] Re: The problem about arm64: io: Relax implicit barriers in
 default I/O accessors
In-Reply-To: <20210809152634.GA1589@willie-the-truck>
References: <AS8PR04MB85000A5E88F7CDDAB9105821880A9@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210621181326.GD29713@willie-the-truck>
 <AS8PR04MB85006677E34CD6CC2C132FA2880A9@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210622091140.GA30677@willie-the-truck>
 <AS8PR04MB85002F0B0C99E7B4F1D27D3D88089@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210706171106.GE20750@willie-the-truck>
 <AS8PR04MB8500635E829B332A61AC85C988129@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <AS8PR04MB850048A35E12270B42448B4C88E49@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210809135041.GC1207@willie-the-truck>
 <AS8PR04MB85001637B4DAE19BB51FA54588F69@AS8PR04MB8500.eurprd04.prod.outlook.com>
 <20210809152634.GA1589@willie-the-truck>
Message-ID: <AS8PR04MB8500F081C02159DA86D5935B88F79@AS8PR04MB8500.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Will Deacon <will at kernel.org>
> Sent: Monday, August 9, 2021 10:27 AM
> To: Frank Li <frank.li at nxp.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>; Zhi Li <lznuaa at gmail.com>;
> Shenwei Wang <shenwei.wang at nxp.com>; Han Xu <han.xu at nxp.com>; Nitin Garg
> <nitin.garg at nxp.com>; Jason Liu <jason.hui.liu at nxp.com>; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [EXT] Re: The problem about arm64: io: Relax implicit barriers
> in default I/O accessors
> 
> Caution: EXT Email
> 
> On Mon, Aug 09, 2021 at 02:46:55PM +0000, Frank Li wrote:
> >
> >
> > > -----Original Message-----
> > > From: Will Deacon <will at kernel.org>
> > > Sent: Monday, August 9, 2021 8:51 AM
> > > To: Frank Li <frank.li at nxp.com>
> > > Cc: Catalin Marinas <catalin.marinas at arm.com>; Zhi Li
> <lznuaa at gmail.com>;
> > > Shenwei Wang <shenwei.wang at nxp.com>; Han Xu <han.xu at nxp.com>; Nitin
> Garg
> > > <nitin.garg at nxp.com>; Jason Liu <jason.hui.liu at nxp.com>; linux-arm-
> > > kernel at lists.infradead.org
> > > Subject: Re: [EXT] Re: The problem about arm64: io: Relax implicit
> barriers
> > > in default I/O accessors
> > >
> > > Caution: EXT Email
> > >
> > > On Thu, Jul 22, 2021 at 07:14:19PM +0000, Frank Li wrote:
> > > > > > On Wed, Jun 23, 2021 at 03:48:10PM +0000, Frank Li wrote:
> > > > > > > > I think you had a support case open with Arm [1] which I'm
> not
> > > able
> > > > > to
> > > > > > > > access -- please can you ask them about the two examples
> above?
> > > > > > >
> > > > > > > Still not get feedback from ARM.
> > > > > >
> > > > > > Just wondering if you were able to solve this without the need to
> > > change
> > > > > > Linux?
> > > > >
> > > > > Sorry for late reply
> > > > >
> > > > > For CCI-500 and 550, ARM removed support for barrier transactions
> but
> > > CCI-
> > > > > 400 supports barrier transactions. With CCI-400 it is a valid
> > > configuration
> > > > > to have SYSBARDISABLE LOW in Cortex-A processors. This change in
> Linux
> > > > > kernel is assuming that the SYSBARDISABLE is set to HIGH hence its
> not
> > > > > correct change for all products having various versions of ARM CCI
> IP.
> > > > >
> > > > > Frank Li
> > > >
> > > > Deacon:
> > > >
> > > >       Did you plan fix this problem by changing dma_wmb()?
> > >
> > > No. As far as I understand this problem, you're driving SYSBARDISABLE
> > > 'low' yet you have your own bus fabric downstream of the CCI which
> doesn't
> > > respect barrier transactions. Even if we bodge dma_wmb(), store-release
> to
> > > non-cacheable memory cannot be made to work on your system as you're
> > > effectively putting some of your non-coherent DMA devices into a
> separate
> > > outer-shareable domain from the CPUs.
> >
> > Does it means the Linux expect all DMA devices in outer-shareable domain
> instead
> > of system shared domain?
> 
> I don't think we've ever documented that and, to be honest, the
> outer-shareable domain stuff in the architecture is pretty academic.
> 
> However, I think it's fair to say that we do want the acquire/release
> instructions to work for non-cacheable buffers when communicating with
> non-coherent devices. I _think_ that implies that such devices need to
> be in the same outer-shareable domain as the CPUs, although the
> architecture isn't really clear here. I can try to find out.

Thanks, if you find anything, let me know.

Frank
 

> 
> Will


From rppt at kernel.org  Tue Aug 10 11:55:32 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 10 Aug 2021 21:55:32 +0300
Subject: [PATCH v3] memblock: make memblock_find_in_range method private
In-Reply-To: <20210809190641.GA1176508@roeck-us.net>
References: <20210803064218.6611-1-rppt@kernel.org>
 <20210809190641.GA1176508@roeck-us.net>
Message-ID: <YRLLpImNhZaLzs3z@kernel.org>

On Mon, Aug 09, 2021 at 12:06:41PM -0700, Guenter Roeck wrote:
> On Tue, Aug 03, 2021 at 09:42:18AM +0300, Mike Rapoport wrote:
> > From: Mike Rapoport <rppt at linux.ibm.com>
> > 
> > There are a lot of uses of memblock_find_in_range() along with
> > memblock_reserve() from the times memblock allocation APIs did not exist.
> > 
> > memblock_find_in_range() is the very core of memblock allocations, so any
> > future changes to its internal behaviour would mandate updates of all the
> > users outside memblock.
> > 
> > Replace the calls to memblock_find_in_range() with an equivalent calls to
> > memblock_phys_alloc() and memblock_phys_alloc_range() and make
> > memblock_find_in_range() private method of memblock.
> > 
> > This simplifies the callers, ensures that (unlikely) errors in
> > memblock_reserve() are handled and improves maintainability of
> > memblock_find_in_range().
> > 
> > Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
> 
> I see a number of crashes in next-20210806 when booting x86 images from efi.
> 
> [    0.000000] efi: EFI v2.70 by EDK II
> [    0.000000] efi: SMBIOS=0x1fbcc000 ACPI=0x1fbfa000 ACPI 2.0=0x1fbfa014 MEMATTR=0x1f25f018
> [    0.000000] SMBIOS 2.8 present.
> [    0.000000] DMI: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
> [    0.000000] last_pfn = 0x1ff50 max_arch_pfn = 0x400000000
> [    0.000000] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT
> [    0.000000] Kernel panic - not syncing: alloc_low_pages: can not alloc memory
> [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.14.0-rc4-next-20210806 #1
> [    0.000000] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
> [    0.000000] Call Trace:
> [    0.000000]  ? dump_stack_lvl+0x57/0x7d
> [    0.000000]  ? panic+0xfc/0x2c6
> [    0.000000]  ? alloc_low_pages+0x117/0x156
> [    0.000000]  ? phys_pmd_init+0x234/0x342
> [    0.000000]  ? phys_pud_init+0x171/0x337
> [    0.000000]  ? __kernel_physical_mapping_init+0xec/0x276
> [    0.000000]  ? init_memory_mapping+0x1ea/0x2aa
> [    0.000000]  ? init_range_memory_mapping+0xdf/0x12e
> [    0.000000]  ? init_mem_mapping+0x1e9/0x26f
> [    0.000000]  ? setup_arch+0x5ff/0xb6d
> [    0.000000]  ? start_kernel+0x71/0x6b4
> [    0.000000]  ? secondary_startup_64_no_verify+0xc2/0xcb
> 
> Bisect points to this patch. Reverting it fixes the problem. Key seems to
> be the amount of memory configured in qemu; the problem is not seen if
> there is 1G or more of memory, but it is seen with all test boots with
> 512M or 256M of memory. It is also seen with almost all 32-bit efi boots.
> 
> The problem is not seen when booting without efi.

It looks like this change uncovered a problem in
x86::memory_map_top_down(). 

The allocation in alloc_low_pages() is limited by min_pfn_mapped and
max_pfn_mapped. The min_pfn_mapped is updated at every iteration of the
loop in memory_map_top_down, but there is another loop in
init_range_memory_mapping() that maps several regions below the current
min_pfn_mapped without updating this variable.

The memory layout in qemu with 256M of RAM and EFI enabled, causes
exhaustion of the memory limited by min_pfn_mapped and max_pfn_mapped
before min_pfn_mapped is updated.

Before this commit there was unconditional "reservation" of 2M in the end
of the memory that moved the initial min_pfn_mapped below the memory
reserved by EFI. The addition of check for xen_domain() removed this
reservation for !XEN and made alloc_low_pages() use the range already busy
with EFI data.

The patch below moves the update of min_pfn_mapped near the update of
max_pfn_mapped so that every time a new range is mapped both limits will be
updated accordingly.

diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 1152a29ce109..be279f6e5a0a 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -1,3 +1,4 @@
+#define DEBUG
 #include <linux/gfp.h>
 #include <linux/initrd.h>
 #include <linux/ioport.h>
@@ -485,6 +486,7 @@ static void add_pfn_range_mapped(unsigned long start_pfn, unsigned long end_pfn)
 	nr_pfn_mapped = clean_sort_range(pfn_mapped, E820_MAX_ENTRIES);
 
 	max_pfn_mapped = max(max_pfn_mapped, end_pfn);
+	min_pfn_mapped = min(min_pfn_mapped, start_pfn);
 
 	if (start_pfn < (1UL<<(32-PAGE_SHIFT)))
 		max_low_pfn_mapped = max(max_low_pfn_mapped,
@@ -643,7 +645,6 @@ static void __init memory_map_top_down(unsigned long map_start,
 		mapped_ram_size += init_range_memory_mapping(start,
 							last_start);
 		last_start = start;
-		min_pfn_mapped = last_start >> PAGE_SHIFT;
 		if (mapped_ram_size >= step_size)
 			step_size = get_new_step_size(step_size);
 	}
 

> Guenter
> 
> ---
> Bisect log:
> 
> # bad: [da454ebf578f6c542ba9f5b3ddb98db3ede109c1] Add linux-next specific files for 20210809
> # good: [36a21d51725af2ce0700c6ebcb6b9594aac658a6] Linux 5.14-rc5
> git bisect start 'HEAD' 'v5.14-rc5'
> # good: [d22fda64bea5f33000e31e5b7e4ba876bca37436] Merge remote-tracking branch 'crypto/master'
> git bisect good d22fda64bea5f33000e31e5b7e4ba876bca37436
> # good: [b084da3a98fad27a39ed5ca64106b86df0417851] Merge remote-tracking branch 'irqchip/irq/irqchip-next'
> git bisect good b084da3a98fad27a39ed5ca64106b86df0417851
> # good: [a5383d1f57190a33c6afc25c62b9907d84ba2bc6] Merge remote-tracking branch 'staging/staging-next'
> git bisect good a5383d1f57190a33c6afc25c62b9907d84ba2bc6
> # good: [a439da3e6abeb054f4e6b0d37814e762b7340196] Merge remote-tracking branch 'seccomp/for-next/seccomp'
> git bisect good a439da3e6abeb054f4e6b0d37814e762b7340196
> # bad: [9801f3c0890c7b992b45a5c2afcb16c5cdc8388e] mm/idle_page_tracking: Make PG_idle reusable
> git bisect bad 9801f3c0890c7b992b45a5c2afcb16c5cdc8388e
> # good: [b4f7f4a9b542836683308d48ffdd18471c6f3e76] lazy-tlb-allow-lazy-tlb-mm-refcounting-to-be-configurable-fix
> git bisect good b4f7f4a9b542836683308d48ffdd18471c6f3e76
> # good: [e30842a48c36f094271eea0984bb861b49c49c87] mm/vmscan: add 'else' to remove check_pending label
> git bisect good e30842a48c36f094271eea0984bb861b49c49c87
> # bad: [65300b20a21214fb2043419d4e5da1d9947c6e15] mm/madvise: add MADV_WILLNEED to process_madvise()
> git bisect bad 65300b20a21214fb2043419d4e5da1d9947c6e15
> # bad: [7348da7a8c244d1a755bc5838b04cb9b1b6ee06c] memblock: make memblock_find_in_range method private
> git bisect bad 7348da7a8c244d1a755bc5838b04cb9b1b6ee06c
> # good: [98f8c467fe2ba8e553b450b2a3294d69f1f2027f] mm-mempolicy-convert-from-atomic_t-to-refcount_t-on-mempolicy-refcnt-fix
> git bisect good 98f8c467fe2ba8e553b450b2a3294d69f1f2027f
> # good: [760ded422ebe4f8899905b752d8378c44f2a78f3] mm/memplicy: add page allocation function for MPOL_PREFERRED_MANY policy
> git bisect good 760ded422ebe4f8899905b752d8378c44f2a78f3
> # good: [fbfa0492d9639b67119d3d94b7a6a3f85e064260] mm/mempolicy: advertise new MPOL_PREFERRED_MANY
> git bisect good fbfa0492d9639b67119d3d94b7a6a3f85e064260
> # good: [ff6d5759a871883aeea38309fb16d91666179328] mm/mempolicy: unify the create() func for bind/interleave/prefer-many policies
> git bisect good ff6d5759a871883aeea38309fb16d91666179328
> # first bad commit: [7348da7a8c244d1a755bc5838b04cb9b1b6ee06c] memblock: make memblock_find_in_range method private

-- 
Sincerely yours,
Mike.


From lukas.bulwahn at gmail.com  Tue Aug 10 12:17:24 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Tue, 10 Aug 2021 21:17:24 +0200
Subject: [PATCH] MAINTAINERS: adjust ARM/NOMADIK/Ux500 ARCHITECTURES to file
 renaming
Message-ID: <20210810191724.24452-1-lukas.bulwahn@gmail.com>

Commit 8f00b3c41ae7 ("mfd: db8500-prcmu: Rename register header") renames
dbx500-prcmu-regs.h to db8500-prcmu-regs.h in ./drivers/mfd/, but misses
to adjust the ARM/NOMADIK/Ux500 ARCHITECTURES section in MAINTAINERS.

Hence, ./scripts/get_maintainer.pl --self-test=patterns complains:

  warning: no file matches    F:    drivers/mfd/dbx500*

Remove the obsolete file entry after this file renaming.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
applies cleanly on next-20210810

Linus, Lee, please pick this patch on your -next tree on top of the patch
mentioned above.

 MAINTAINERS | 1 -
 1 file changed, 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index efac6221afe1..706e9a556747 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2258,7 +2258,6 @@ F:	drivers/iio/adc/ab8500-gpadc.c
 F:	drivers/mfd/ab8500*
 F:	drivers/mfd/abx500*
 F:	drivers/mfd/db8500*
-F:	drivers/mfd/dbx500*
 F:	drivers/pinctrl/nomadik/
 F:	drivers/rtc/rtc-ab8500.c
 F:	drivers/rtc/rtc-pl031.c
-- 
2.17.1



From linux at roeck-us.net  Tue Aug 10 12:21:46 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Tue, 10 Aug 2021 12:21:46 -0700
Subject: [PATCH v3] memblock: make memblock_find_in_range method private
In-Reply-To: <YRLLpImNhZaLzs3z@kernel.org>
References: <20210803064218.6611-1-rppt@kernel.org>
 <20210809190641.GA1176508@roeck-us.net> <YRLLpImNhZaLzs3z@kernel.org>
Message-ID: <7db20940-cbd9-e900-db28-774c5782601c@roeck-us.net>

On 8/10/21 11:55 AM, Mike Rapoport wrote:
> On Mon, Aug 09, 2021 at 12:06:41PM -0700, Guenter Roeck wrote:
>> On Tue, Aug 03, 2021 at 09:42:18AM +0300, Mike Rapoport wrote:
>>> From: Mike Rapoport <rppt at linux.ibm.com>
>>>
>>> There are a lot of uses of memblock_find_in_range() along with
>>> memblock_reserve() from the times memblock allocation APIs did not exist.
>>>
>>> memblock_find_in_range() is the very core of memblock allocations, so any
>>> future changes to its internal behaviour would mandate updates of all the
>>> users outside memblock.
>>>
>>> Replace the calls to memblock_find_in_range() with an equivalent calls to
>>> memblock_phys_alloc() and memblock_phys_alloc_range() and make
>>> memblock_find_in_range() private method of memblock.
>>>
>>> This simplifies the callers, ensures that (unlikely) errors in
>>> memblock_reserve() are handled and improves maintainability of
>>> memblock_find_in_range().
>>>
>>> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
>>
>> I see a number of crashes in next-20210806 when booting x86 images from efi.
>>
>> [    0.000000] efi: EFI v2.70 by EDK II
>> [    0.000000] efi: SMBIOS=0x1fbcc000 ACPI=0x1fbfa000 ACPI 2.0=0x1fbfa014 MEMATTR=0x1f25f018
>> [    0.000000] SMBIOS 2.8 present.
>> [    0.000000] DMI: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
>> [    0.000000] last_pfn = 0x1ff50 max_arch_pfn = 0x400000000
>> [    0.000000] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT
>> [    0.000000] Kernel panic - not syncing: alloc_low_pages: can not alloc memory
>> [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.14.0-rc4-next-20210806 #1
>> [    0.000000] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
>> [    0.000000] Call Trace:
>> [    0.000000]  ? dump_stack_lvl+0x57/0x7d
>> [    0.000000]  ? panic+0xfc/0x2c6
>> [    0.000000]  ? alloc_low_pages+0x117/0x156
>> [    0.000000]  ? phys_pmd_init+0x234/0x342
>> [    0.000000]  ? phys_pud_init+0x171/0x337
>> [    0.000000]  ? __kernel_physical_mapping_init+0xec/0x276
>> [    0.000000]  ? init_memory_mapping+0x1ea/0x2aa
>> [    0.000000]  ? init_range_memory_mapping+0xdf/0x12e
>> [    0.000000]  ? init_mem_mapping+0x1e9/0x26f
>> [    0.000000]  ? setup_arch+0x5ff/0xb6d
>> [    0.000000]  ? start_kernel+0x71/0x6b4
>> [    0.000000]  ? secondary_startup_64_no_verify+0xc2/0xcb
>>
>> Bisect points to this patch. Reverting it fixes the problem. Key seems to
>> be the amount of memory configured in qemu; the problem is not seen if
>> there is 1G or more of memory, but it is seen with all test boots with
>> 512M or 256M of memory. It is also seen with almost all 32-bit efi boots.
>>
>> The problem is not seen when booting without efi.
> 
> It looks like this change uncovered a problem in
> x86::memory_map_top_down().
> 
> The allocation in alloc_low_pages() is limited by min_pfn_mapped and
> max_pfn_mapped. The min_pfn_mapped is updated at every iteration of the
> loop in memory_map_top_down, but there is another loop in
> init_range_memory_mapping() that maps several regions below the current
> min_pfn_mapped without updating this variable.
> 
> The memory layout in qemu with 256M of RAM and EFI enabled, causes
> exhaustion of the memory limited by min_pfn_mapped and max_pfn_mapped
> before min_pfn_mapped is updated.
> 
> Before this commit there was unconditional "reservation" of 2M in the end
> of the memory that moved the initial min_pfn_mapped below the memory
> reserved by EFI. The addition of check for xen_domain() removed this
> reservation for !XEN and made alloc_low_pages() use the range already busy
> with EFI data.
> 
> The patch below moves the update of min_pfn_mapped near the update of
> max_pfn_mapped so that every time a new range is mapped both limits will be
> updated accordingly.
> 
> diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
> index 1152a29ce109..be279f6e5a0a 100644
> --- a/arch/x86/mm/init.c
> +++ b/arch/x86/mm/init.c
> @@ -1,3 +1,4 @@
> +#define DEBUG
>   #include <linux/gfp.h>
>   #include <linux/initrd.h>
>   #include <linux/ioport.h>
> @@ -485,6 +486,7 @@ static void add_pfn_range_mapped(unsigned long start_pfn, unsigned long end_pfn)
>   	nr_pfn_mapped = clean_sort_range(pfn_mapped, E820_MAX_ENTRIES);
>   
>   	max_pfn_mapped = max(max_pfn_mapped, end_pfn);
> +	min_pfn_mapped = min(min_pfn_mapped, start_pfn);
>   
>   	if (start_pfn < (1UL<<(32-PAGE_SHIFT)))
>   		max_low_pfn_mapped = max(max_low_pfn_mapped,
> @@ -643,7 +645,6 @@ static void __init memory_map_top_down(unsigned long map_start,
>   		mapped_ram_size += init_range_memory_mapping(start,
>   							last_start);
>   		last_start = start;
> -		min_pfn_mapped = last_start >> PAGE_SHIFT;
>   		if (mapped_ram_size >= step_size)
>   			step_size = get_new_step_size(step_size);
>   	}
>   

The offending patch was removed from next-20210810, but I applied the above change
to next-20210809 and it does indeed fix the problem. If it is added as separate patch,
please feel free to add

Tested-by: Guenter Roeck <linux at roeck-us.net>

Thanks,
Guenter


From helgaas at kernel.org  Tue Aug 10 12:42:50 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 10 Aug 2021 14:42:50 -0500
Subject: [PATCH v11 2/4] PCI: mediatek: Add new method to get shared
 pcie-cfg base address and parse node
In-Reply-To: <20210719073456.28666-3-chuanjia.liu@mediatek.com>
Message-ID: <20210810194250.GA2276275@bjorn-Precision-5520>

On Mon, Jul 19, 2021 at 03:34:54PM +0800, Chuanjia Liu wrote:
> For the new dts format, add a new method to get
> shared pcie-cfg base address and parse node.

This commit log doesn't seem to really cover what's going on here.  It
looks like:

  - You added a check for "mediatek,generic-pciecfg" (I guess this is
    the "shared pcie-cfg base address" part).  Probably could have
    been its own patch.

  - You added checks for "interrupt-names" and "pcie_irq".  Not
    explained in commit log; probably could have been its own patch,
    too.

  - You now look for "linux,pci-domain" (via of_get_pci_domain_nr()).
    If present, you parse only one port instead of looking for all the
    children of the node.

    That's sort of weird behavior -- why should the presence of
    "linux,pci-domain" determine whether the node can have children?
    Is that really what you intend?

    Should be explained in the commit log and could have been its own
    patch, too.

> Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> ---
>  drivers/pci/controller/pcie-mediatek.c | 52 +++++++++++++++++++-------
>  1 file changed, 39 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> index 25bee693834f..928e0983a900 100644
> --- a/drivers/pci/controller/pcie-mediatek.c
> +++ b/drivers/pci/controller/pcie-mediatek.c
> @@ -14,6 +14,7 @@
>  #include <linux/irqchip/chained_irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/msi.h>
>  #include <linux/module.h>
>  #include <linux/of_address.h>
> @@ -23,6 +24,7 @@
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
>  #include <linux/reset.h>
>  
>  #include "../pci.h"
> @@ -207,6 +209,7 @@ struct mtk_pcie_port {
>   * struct mtk_pcie - PCIe host information
>   * @dev: pointer to PCIe device
>   * @base: IO mapped register base
> + * @cfg: IO mapped register map for PCIe config
>   * @free_ck: free-run reference clock
>   * @mem: non-prefetchable memory resource
>   * @ports: pointer to PCIe port information
> @@ -215,6 +218,7 @@ struct mtk_pcie_port {
>  struct mtk_pcie {
>  	struct device *dev;
>  	void __iomem *base;
> +	struct regmap *cfg;
>  	struct clk *free_ck;
>  
>  	struct list_head ports;
> @@ -650,7 +654,11 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
>  		return err;
>  	}
>  
> -	port->irq = platform_get_irq(pdev, port->slot);
> +	if (of_find_property(dev->of_node, "interrupt-names", NULL))
> +		port->irq = platform_get_irq_byname(pdev, "pcie_irq");
> +	else
> +		port->irq = platform_get_irq(pdev, port->slot);
> +
>  	if (port->irq < 0)
>  		return port->irq;
>  
> @@ -682,6 +690,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
>  		val |= PCIE_CSR_LTSSM_EN(port->slot) |
>  		       PCIE_CSR_ASPM_L1_EN(port->slot);
>  		writel(val, pcie->base + PCIE_SYS_CFG_V2);
> +	} else if (pcie->cfg) {
> +		val = PCIE_CSR_LTSSM_EN(port->slot) |
> +		      PCIE_CSR_ASPM_L1_EN(port->slot);
> +		regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
>  	}
>  
>  	/* Assert all reset signals */
> @@ -985,6 +997,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct resource *regs;
> +	struct device_node *cfg_node;
>  	int err;
>  
>  	/* get shared registers, which are optional */
> @@ -995,6 +1008,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
>  			return PTR_ERR(pcie->base);
>  	}
>  
> +	cfg_node = of_find_compatible_node(NULL, NULL,
> +					   "mediatek,generic-pciecfg");
> +	if (cfg_node) {
> +		pcie->cfg = syscon_node_to_regmap(cfg_node);
> +		if (IS_ERR(pcie->cfg))
> +			return PTR_ERR(pcie->cfg);
> +	}
> +
>  	pcie->free_ck = devm_clk_get(dev, "free_ck");
>  	if (IS_ERR(pcie->free_ck)) {
>  		if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
> @@ -1027,22 +1048,27 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct device_node *node = dev->of_node, *child;
>  	struct mtk_pcie_port *port, *tmp;
> -	int err;
> +	int err, slot;
> +
> +	slot = of_get_pci_domain_nr(dev->of_node);
> +	if (slot < 0) {
> +		for_each_available_child_of_node(node, child) {
> +			err = of_pci_get_devfn(child);
> +			if (err < 0) {
> +				dev_err(dev, "failed to get devfn: %d\n", err);
> +				goto error_put_node;
> +			}
>  
> -	for_each_available_child_of_node(node, child) {
> -		int slot;
> +			slot = PCI_SLOT(err);
>  
> -		err = of_pci_get_devfn(child);
> -		if (err < 0) {
> -			dev_err(dev, "failed to parse devfn: %d\n", err);
> -			goto error_put_node;
> +			err = mtk_pcie_parse_port(pcie, child, slot);
> +			if (err)
> +				goto error_put_node;
>  		}
> -
> -		slot = PCI_SLOT(err);
> -
> -		err = mtk_pcie_parse_port(pcie, child, slot);
> +	} else {
> +		err = mtk_pcie_parse_port(pcie, node, slot);
>  		if (err)
> -			goto error_put_node;
> +			return err;
>  	}
>  
>  	err = mtk_pcie_subsys_powerup(pcie);
> -- 
> 2.18.0
> 


From will at kernel.org  Tue Aug 10 13:25:54 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 21:25:54 +0100
Subject: [Patch V3 0/2] iommu/arm-smmu: Fix races in iommu domain/group
 creation
In-Reply-To: <1628570641-9127-1-git-send-email-amhetre@nvidia.com>
References: <1628570641-9127-1-git-send-email-amhetre@nvidia.com>
Message-ID: <162861955924.3590382.10228157894867875931.b4-ty@kernel.org>

On Tue, 10 Aug 2021 10:13:59 +0530, Ashish Mhetre wrote:
> When two devices with same SID are getting probed concurrently through
> iommu_probe_device(), the iommu_group and iommu_domain are allocated more
> than once because they are not protected for concurrency. This is leading
> to context faults when one device is accessing IOVA from other device.
> Fix this by protecting iommu_domain and iommu_group creation with mutexes.
> 
> Changes in v3:
> * Updated commit messages.
> * Added Signed-off-by in patch 2.
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/2] iommu: Fix race condition during default domain allocation
      https://git.kernel.org/will/c/211ff31b3d33
[2/2] iommu/arm-smmu: Fix race condition during iommu_group creation
      https://git.kernel.org/will/c/b1a1347912a7

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Tue Aug 10 13:25:55 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 10 Aug 2021 21:25:55 +0100
Subject: [PATCHv2] iommu/arm-smmu: Add clk_bulk_{prepare/unprepare} to
 system pm callbacks
In-Reply-To: <20210810064808.32486-1-saiprakash.ranjan@codeaurora.org>
References: <20210810064808.32486-1-saiprakash.ranjan@codeaurora.org>
Message-ID: <162860133458.2066705.4766353866731374871.b4-ty@kernel.org>

On Tue, 10 Aug 2021 12:18:08 +0530, Sai Prakash Ranjan wrote:
> Some clocks for SMMU can have parent as XO such as gpu_cc_hub_cx_int_clk
> of GPU SMMU in QTI SC7280 SoC and in order to enter deep sleep states in
> such cases, we would need to drop the XO clock vote in unprepare call and
> this unprepare callback for XO is in RPMh (Resource Power Manager-Hardened)
> clock driver which controls RPMh managed clock resources for new QTI SoCs.
> 
> Given we cannot have a sleeping calls such as clk_bulk_prepare() and
> clk_bulk_unprepare() in arm-smmu runtime pm callbacks since the iommu
> operations like map and unmap can be in atomic context and are in fast
> path, add this prepare and unprepare call to drop the XO vote only for
> system pm callbacks since it is not a fast path and we expect the system
> to enter deep sleep states with system pm as opposed to runtime pm.
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/1] iommu/arm-smmu: Add clk_bulk_{prepare/unprepare} to system pm callbacks
      https://git.kernel.org/will/c/afefe67e0893

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From patchwork-bot+netdevbpf at kernel.org  Tue Aug 10 13:30:05 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Tue, 10 Aug 2021 20:30:05 +0000
Subject: [PATCH v2 net] net: switchdev: zero-initialize struct
 switchdev_notifier_fdb_info emitted by drivers towards the bridge
In-Reply-To: <20210810115024.1629983-1-vladimir.oltean@nxp.com>
References: <20210810115024.1629983-1-vladimir.oltean@nxp.com>
Message-ID: <162862740581.16281.10031076649352815360.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (refs/heads/master):

On Tue, 10 Aug 2021 14:50:24 +0300 you wrote:
> The blamed commit a new field to struct switchdev_notifier_fdb_info, but
> did not make sure that all call paths set it to something valid. For
> example, a switchdev driver may emit a SWITCHDEV_FDB_ADD_TO_BRIDGE
> notifier, and since the 'is_local' flag is not set, it contains junk
> from the stack, so the bridge might interpret those notifications as
> being for local FDB entries when that was not intended.
> 
> [...]

Here is the summary with links:
  - [v2,net] net: switchdev: zero-initialize struct switchdev_notifier_fdb_info emitted by drivers towards the bridge
    https://git.kernel.org/netdev/net/c/c35b57ceff90

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From wsa at kernel.org  Tue Aug 10 14:09:08 2021
From: wsa at kernel.org (Wolfram Sang)
Date: Tue, 10 Aug 2021 23:09:08 +0200
Subject: [PATCH] i2c: at91: remove #define CONFIG_PM
In-Reply-To: <20210705121516.622326-1-claudiu.beznea@microchip.com>
References: <20210705121516.622326-1-claudiu.beznea@microchip.com>
Message-ID: <YRLq9ClCMZlApNqr@kunai>

On Mon, Jul 05, 2021 at 03:15:16PM +0300, Claudiu Beznea wrote:
> Remove #define CONFIG_PM and use __maybe_unused for PM functions and
> pm_ptr() for PM ops.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210810/935ecdd1/attachment.sig>

From lkp at intel.com  Tue Aug 10 14:20:24 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 11 Aug 2021 05:20:24 +0800
Subject: [nomadik:nomadik] BUILD SUCCESS
 c7698331119f58f92217aeee98cf77a82b6a4dfd
Message-ID: <6112ed98.GflbIFx1nVSgBRJr%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git nomadik
branch HEAD: c7698331119f58f92217aeee98cf77a82b6a4dfd  ARM: configs: Update the nhk8815_defconfig

elapsed time: 4198m

configs tested: 286
configs skipped: 33

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
arm                         cm_x300_defconfig
arm                         axm55xx_defconfig
arm                       cns3420vb_defconfig
powerpc                       ppc64_defconfig
powerpc                          allmodconfig
m68k                        m5272c3_defconfig
nios2                         10m50_defconfig
powerpc                      walnut_defconfig
arm                            xcep_defconfig
mips                        nlm_xlp_defconfig
sh                           se7721_defconfig
sh                           se7750_defconfig
powerpc                       ebony_defconfig
m68k                        m5407c3_defconfig
powerpc                 mpc832x_rdb_defconfig
nios2                            allyesconfig
arc                 nsimosci_hs_smp_defconfig
powerpc                     ep8248e_defconfig
mips                        qi_lb60_defconfig
arm                          exynos_defconfig
mips                           ip27_defconfig
arm                      tct_hammer_defconfig
powerpc                         wii_defconfig
openrisc                    or1ksim_defconfig
arm                         nhk8815_defconfig
arm                         at91_dt_defconfig
arm                          iop32x_defconfig
sh                               allmodconfig
mips                malta_qemu_32r6_defconfig
sparc                            alldefconfig
riscv                             allnoconfig
powerpc                 mpc8272_ads_defconfig
powerpc                      obs600_defconfig
m68k                         amcore_defconfig
powerpc                      ppc64e_defconfig
powerpc                   microwatt_defconfig
arm                       aspeed_g5_defconfig
arc                    vdk_hs38_smp_defconfig
arc                        nsim_700_defconfig
arm                          imote2_defconfig
h8300                     edosk2674_defconfig
sh                          r7785rp_defconfig
powerpc                     ksi8560_defconfig
sh                        edosk7705_defconfig
xtensa                           allyesconfig
arm                         socfpga_defconfig
s390                             allyesconfig
arc                           tb10x_defconfig
powerpc                     kmeter1_defconfig
sh                         ecovec24_defconfig
arm                      jornada720_defconfig
powerpc64                           defconfig
xtensa                    smp_lx200_defconfig
arm                       mainstone_defconfig
m68k                       m5475evb_defconfig
powerpc                      ppc44x_defconfig
arm                         lpc18xx_defconfig
powerpc                     taishan_defconfig
arm                        keystone_defconfig
x86_64                            allnoconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
arc                                 defconfig
arm                           corgi_defconfig
mips                           rs90_defconfig
powerpc                      acadia_defconfig
mips                            gpr_defconfig
sh                          rsk7264_defconfig
sh                   rts7751r2dplus_defconfig
sh                         apsh4a3a_defconfig
sh                          sdk7786_defconfig
arm                          lpd270_defconfig
arc                          axs103_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
arm                         lpc32xx_defconfig
sh                              ul2_defconfig
mips                      maltasmvp_defconfig
powerpc                      tqm8xx_defconfig
arm                        clps711x_defconfig
mips                      malta_kvm_defconfig
powerpc                     skiroot_defconfig
riscv                            alldefconfig
mips                        jmr3927_defconfig
m68k                       bvme6000_defconfig
sh                          polaris_defconfig
alpha                            alldefconfig
parisc                generic-32bit_defconfig
arm                       imx_v6_v7_defconfig
ia64                        generic_defconfig
mips                        bcm47xx_defconfig
sh                            migor_defconfig
powerpc                    klondike_defconfig
i386                                defconfig
sh                           se7343_defconfig
arc                              allyesconfig
sh                        sh7785lcr_defconfig
xtensa                  nommu_kc705_defconfig
sh                 kfr2r09-romimage_defconfig
arm                           h3600_defconfig
arm                           omap1_defconfig
arm                       multi_v4t_defconfig
arm                          pxa168_defconfig
m68k                          atari_defconfig
mips                           ip28_defconfig
powerpc                     tqm8541_defconfig
i386                             alldefconfig
powerpc                      bamboo_defconfig
arm                          pxa910_defconfig
mips                         tb0287_defconfig
arm                       aspeed_g4_defconfig
arm64                            alldefconfig
arc                            hsdk_defconfig
sh                          landisk_defconfig
openrisc                         alldefconfig
arm                           stm32_defconfig
mips                       capcella_defconfig
arm                      pxa255-idp_defconfig
sh                          rsk7201_defconfig
xtensa                         virt_defconfig
arm                         bcm2835_defconfig
sparc64                             defconfig
powerpc                      ppc40x_defconfig
mips                         tb0219_defconfig
arm                        neponset_defconfig
powerpc                    sam440ep_defconfig
powerpc                     tqm8555_defconfig
powerpc                 mpc832x_mds_defconfig
h8300                            allyesconfig
arm                       omap2plus_defconfig
powerpc                      mgcoge_defconfig
mips                         cobalt_defconfig
powerpc                 mpc85xx_cds_defconfig
sh                      rts7751r2d1_defconfig
powerpc                 xes_mpc85xx_defconfig
arm                          badge4_defconfig
powerpc                        cell_defconfig
mips                        vocore2_defconfig
sh                          rsk7203_defconfig
xtensa                       common_defconfig
powerpc                 mpc8560_ads_defconfig
mips                     loongson2k_defconfig
mips                      fuloong2e_defconfig
powerpc                           allnoconfig
powerpc                       maple_defconfig
mips                     cu1000-neo_defconfig
powerpc                     asp8347_defconfig
s390                             alldefconfig
arm                       imx_v4_v5_defconfig
arm                          moxart_defconfig
sh                             sh03_defconfig
powerpc                     rainier_defconfig
arm                        realview_defconfig
arm                         s3c6400_defconfig
riscv                    nommu_virt_defconfig
powerpc                 canyonlands_defconfig
powerpc                      ep88xc_defconfig
m68k                        stmark2_defconfig
sh                           se7724_defconfig
m68k                                defconfig
m68k                            q40_defconfig
arc                      axs103_smp_defconfig
mips                      pistachio_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                 linkstation_defconfig
mips                             allyesconfig
um                                  defconfig
sh                     magicpanelr2_defconfig
powerpc                     tqm5200_defconfig
sh                            titan_defconfig
arm                            hisi_defconfig
sh                          urquell_defconfig
mips                     loongson1b_defconfig
mips                     loongson1c_defconfig
powerpc                       holly_defconfig
powerpc                 mpc8540_ads_defconfig
powerpc                   lite5200b_defconfig
csky                                defconfig
mips                          ath25_defconfig
sh                           sh2007_defconfig
arm                           viper_defconfig
ia64                             allmodconfig
ia64                             allyesconfig
ia64                                defconfig
m68k                             allmodconfig
m68k                             allyesconfig
nios2                               defconfig
nds32                             allnoconfig
nds32                               defconfig
alpha                               defconfig
alpha                            allyesconfig
parisc                              defconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
mips                             allmodconfig
powerpc                          allyesconfig
x86_64               randconfig-a004-20210810
x86_64               randconfig-a006-20210810
x86_64               randconfig-a003-20210810
x86_64               randconfig-a005-20210810
x86_64               randconfig-a002-20210810
x86_64               randconfig-a001-20210810
x86_64               randconfig-a002-20210809
x86_64               randconfig-a004-20210809
x86_64               randconfig-a006-20210809
x86_64               randconfig-a003-20210809
x86_64               randconfig-a001-20210809
x86_64               randconfig-a005-20210809
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
i386                 randconfig-a011-20210810
i386                 randconfig-a015-20210810
i386                 randconfig-a013-20210810
i386                 randconfig-a014-20210810
i386                 randconfig-a016-20210810
i386                 randconfig-a012-20210810
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210808
x86_64               randconfig-c001-20210809
x86_64               randconfig-c001-20210810
x86_64               randconfig-a002-20210808
x86_64               randconfig-a004-20210808
x86_64               randconfig-a006-20210808
x86_64               randconfig-a003-20210808
x86_64               randconfig-a001-20210808
x86_64               randconfig-a005-20210808
x86_64               randconfig-a013-20210810
x86_64               randconfig-a011-20210810
x86_64               randconfig-a012-20210810
x86_64               randconfig-a016-20210810
x86_64               randconfig-a014-20210810
x86_64               randconfig-a015-20210810
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From pgwipeout at gmail.com  Tue Aug 10 15:31:24 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Aug 2021 18:31:24 -0400
Subject: [BUG] dw-mipi-dsi-rockchip display corruption with dsi panel
Message-ID: <20210810223123.2174596-1-pgwipeout@gmail.com>

Good Evening,

I've been attempting to light off the feiyang fy07024di26a30d panel on
the rockpro64. This is the official panel from the Pine64 store.
I've confirmed it works with the downstream kernel on both the rk3399
and rk3566, but on the mainline driver the display is partially
corrupted (see attached photo: [1]).

As you can see, the left half of the display is fine, but the right half
of the display is corrupted with the pixels smearing horizontally.

I saw when the panel was added, some additional code was added to
handle burst mode in the sun6_mipi_dsi driver [2].
I've seen that the dw-mipi-dsi driver appears to already support burst
mode and I can't find anything out of place there.
I also haven't had much success finding anything obviously different in
the downstream driver vs the upstream driver that would explain this.

Attached below is the in-progress dts changes for an example of how the
panel is plugged in.

I admit, I have little understanding of the mipi-dsi internal workings,
so I'm reaching out to the experts on how to correct this.

Thank you for your time,
Peter Geis

[1] https://photos.app.goo.gl/LBA9M2WcweGaEb4cA
[2] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20181116163916.29621-1-jagan at amarulasolutions.com/

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
index 687a5afa5d2c..af55a30297ae 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
@@ -20,6 +20,13 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm0 0 1000000 0>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <128>;
+	};
+
 	clkin_gmac: external-gmac-clock {
 		compatible = "fixed-clock";
 		clock-frequency = <125000000>;
@@ -69,7 +76,7 @@ diy_led: led-1 {
 
 	fan: pwm-fan {
 		compatible = "pwm-fan";
-		cooling-levels = <0 150 200 255>;
+		cooling-levels = <0 100 150 255>;
 		#cooling-cells = <2>;
 		fan-supply = <&vcc12v_dcin>;
 		pwms = <&pwm1 0 50000 0>;
@@ -220,6 +227,16 @@ vdd_log: vdd-log {
 		regulator-max-microvolt = <1700000>;
 		vin-supply = <&vcc5v0_sys>;
 	};
+
+	avdd: avdd {
+		compatible = "regulator-fixed";
+		regulator-name = "avdd";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <11000000>;
+		regulator-max-microvolt = <11000000>;
+		vin-supply = <&vcc3v3_s0>;
+	};
 };
 
 &cpu_l0 {
@@ -428,8 +445,8 @@ regulator-state-mem {
 
 			vcc3v0_touch: LDO_REG2 {
 				regulator-name = "vcc3v0_touch";
-				regulator-always-on;
-				regulator-boot-on;
+//				regulator-always-on;
+//				regulator-boot-on;
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3000000>;
 				regulator-state-mem {
@@ -518,8 +535,8 @@ regulator-state-mem {
 
 			vcc3v3_s0: SWITCH_REG2 {
 				regulator-name = "vcc3v3_s0";
-				regulator-always-on;
-				regulator-boot-on;
+//				regulator-always-on;
+//				regulator-boot-on;
 				regulator-state-mem {
 					regulator-off-in-suspend;
 				};
@@ -593,6 +610,19 @@ fusb0: typec-portc at 22 {
 		vbus-supply = <&vcc5v0_typec>;
 		status = "okay";
 	};
+
+	touch: touchscreen at 5d {
+		compatible = "goodix,gt911";
+		reg = <0x5d>;
+		AVDD28-supply = <&vcc3v0_touch>;
+		VDDIO-supply = <&vcc3v0_touch>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <RK_PD5 IRQ_TYPE_EDGE_FALLING>;
+		irq-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
+//		touchscreen-inverted-x;
+//		touchscreen-inverted-y;
+	};
 };
 
 &i2s0 {
@@ -628,6 +658,88 @@ &io_domains {
 	gpio1830-supply = <&vcc_3v0>;
 };
 
+&mipi_dsi {
+	status = "okay";
+	clock-master;
+
+	ports {
+		mipi_out: port at 1 {
+			reg = <1>;
+
+			mipi_out_panel: endpoint {
+				remote-endpoint = <&mipi_in_panel>;
+			};
+		};
+	};
+
+	mipi_panel: panel at 0 {
+		compatible = "feiyang,fy07024di26a30d";
+		reg = <0>;
+		backlight = <&backlight>;
+		reset-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
+//		enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
+		width-mm = <154>;
+		height-mm = <86>;
+		rotation = <0>;
+		avdd-supply = <&avdd>;
+		dvdd-supply = <&vcc3v3_s0>;
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: timing0 {
+				clock-frequency = <50000000>;
+				hactive = <1024>;
+				vactive = <600>;
+				hfront-porch = <160>;
+				hback-porch = <160>;
+				hsync-len = <10>;
+				vback-porch = <23>;
+				vfront-porch = <12>;
+				vsync-len = <1>;
+				hsync-active = <0>;
+				vsync-active = <0>;
+				pixelclk-active = <0>;
+				de-active = <0>;
+			};
+		};
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				mipi_in_panel: endpoint {
+					remote-endpoint = <&mipi_out_panel>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+
+				mipi1_in_panel: endpoint at 1 {
+					remote-endpoint = <&mipi1_out_panel>;
+				};
+			};
+		};
+	};
+};
+
+&mipi_dsi1 {
+	status = "okay";
+
+	ports {
+		mipi1_out: port at 1 {
+			reg = <1>;
+
+			mipi1_out_panel: endpoint {
+				remote-endpoint = <&mipi1_in_panel>;
+			};
+		};
+	};
+};
+
 &pcie0 {
 	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
 	num-lanes = <4>;


From heiko at sntech.de  Tue Aug 10 16:11:29 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 11 Aug 2021 01:11:29 +0200
Subject: [BUG] dw-mipi-dsi-rockchip display corruption with dsi panel
In-Reply-To: <20210810223123.2174596-1-pgwipeout@gmail.com>
References: <20210810223123.2174596-1-pgwipeout@gmail.com>
Message-ID: <3455830.ypAZr3mf50@diego>

Hi Peter,

Am Mittwoch, 11. August 2021, 00:31:24 CEST schrieb Peter Geis:
> Good Evening,
> 
> I've been attempting to light off the feiyang fy07024di26a30d panel on
> the rockpro64. This is the official panel from the Pine64 store.
> I've confirmed it works with the downstream kernel on both the rk3399
> and rk3566, but on the mainline driver the display is partially
> corrupted (see attached photo: [1]).
> 
> As you can see, the left half of the display is fine, but the right half
> of the display is corrupted with the pixels smearing horizontally.
> 
> I saw when the panel was added, some additional code was added to
> handle burst mode in the sun6_mipi_dsi driver [2].
> I've seen that the dw-mipi-dsi driver appears to already support burst
> mode and I can't find anything out of place there.
> I also haven't had much success finding anything obviously different in
> the downstream driver vs the upstream driver that would explain this.
> 
> Attached below is the in-progress dts changes for an example of how the
> panel is plugged in.

is that really a dual-dsi panel needing two dsi controllers to drive it?

With that tiny resultion of 1024x600 I definitly wouldn't expect this,
in contrast to say the 2048x1536 dual-dsi displays used in the
Gru-Scarlet ChromeOS tablets.

So maybe just drop the 2nd dsi controller connection in a first step?
Because I really don't think that is the case on the hardware.

The dual-dsi setup means that you have one vop supplying half of its
display data to each of the 2 involved dsi controllers. And you're missing
in fact half of your display data.


Heiko



> I admit, I have little understanding of the mipi-dsi internal workings,
> so I'm reaching out to the experts on how to correct this.
> 
> Thank you for your time,
> Peter Geis
> 
> [1] https://photos.app.goo.gl/LBA9M2WcweGaEb4cA
> [2] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20181116163916.29621-1-jagan at amarulasolutions.com/
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> index 687a5afa5d2c..af55a30297ae 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> @@ -20,6 +20,13 @@ chosen {
>  		stdout-path = "serial2:1500000n8";
>  	};
>  
> +	backlight: backlight {
> +		compatible = "pwm-backlight";
> +		pwms = <&pwm0 0 1000000 0>;
> +		brightness-levels = <0 4 8 16 32 64 128 255>;
> +		default-brightness-level = <128>;
> +	};
> +
>  	clkin_gmac: external-gmac-clock {
>  		compatible = "fixed-clock";
>  		clock-frequency = <125000000>;
> @@ -69,7 +76,7 @@ diy_led: led-1 {
>  
>  	fan: pwm-fan {
>  		compatible = "pwm-fan";
> -		cooling-levels = <0 150 200 255>;
> +		cooling-levels = <0 100 150 255>;
>  		#cooling-cells = <2>;
>  		fan-supply = <&vcc12v_dcin>;
>  		pwms = <&pwm1 0 50000 0>;
> @@ -220,6 +227,16 @@ vdd_log: vdd-log {
>  		regulator-max-microvolt = <1700000>;
>  		vin-supply = <&vcc5v0_sys>;
>  	};
> +
> +	avdd: avdd {
> +		compatible = "regulator-fixed";
> +		regulator-name = "avdd";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <11000000>;
> +		regulator-max-microvolt = <11000000>;
> +		vin-supply = <&vcc3v3_s0>;
> +	};
>  };
>  
>  &cpu_l0 {
> @@ -428,8 +445,8 @@ regulator-state-mem {
>  
>  			vcc3v0_touch: LDO_REG2 {
>  				regulator-name = "vcc3v0_touch";
> -				regulator-always-on;
> -				regulator-boot-on;
> +//				regulator-always-on;
> +//				regulator-boot-on;
>  				regulator-min-microvolt = <3000000>;
>  				regulator-max-microvolt = <3000000>;
>  				regulator-state-mem {
> @@ -518,8 +535,8 @@ regulator-state-mem {
>  
>  			vcc3v3_s0: SWITCH_REG2 {
>  				regulator-name = "vcc3v3_s0";
> -				regulator-always-on;
> -				regulator-boot-on;
> +//				regulator-always-on;
> +//				regulator-boot-on;
>  				regulator-state-mem {
>  					regulator-off-in-suspend;
>  				};
> @@ -593,6 +610,19 @@ fusb0: typec-portc at 22 {
>  		vbus-supply = <&vcc5v0_typec>;
>  		status = "okay";
>  	};
> +
> +	touch: touchscreen at 5d {
> +		compatible = "goodix,gt911";
> +		reg = <0x5d>;
> +		AVDD28-supply = <&vcc3v0_touch>;
> +		VDDIO-supply = <&vcc3v0_touch>;
> +		interrupt-parent = <&gpio4>;
> +		interrupts = <RK_PD5 IRQ_TYPE_EDGE_FALLING>;
> +		irq-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
> +		reset-gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
> +//		touchscreen-inverted-x;
> +//		touchscreen-inverted-y;
> +	};
>  };
>  
>  &i2s0 {
> @@ -628,6 +658,88 @@ &io_domains {
>  	gpio1830-supply = <&vcc_3v0>;
>  };
>  
> +&mipi_dsi {
> +	status = "okay";
> +	clock-master;
> +
> +	ports {
> +		mipi_out: port at 1 {
> +			reg = <1>;
> +
> +			mipi_out_panel: endpoint {
> +				remote-endpoint = <&mipi_in_panel>;
> +			};
> +		};
> +	};
> +
> +	mipi_panel: panel at 0 {
> +		compatible = "feiyang,fy07024di26a30d";
> +		reg = <0>;
> +		backlight = <&backlight>;
> +		reset-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
> +//		enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
> +		width-mm = <154>;
> +		height-mm = <86>;
> +		rotation = <0>;
> +		avdd-supply = <&avdd>;
> +		dvdd-supply = <&vcc3v3_s0>;
> +
> +		display-timings {
> +			native-mode = <&timing0>;
> +			timing0: timing0 {
> +				clock-frequency = <50000000>;
> +				hactive = <1024>;
> +				vactive = <600>;
> +				hfront-porch = <160>;
> +				hback-porch = <160>;
> +				hsync-len = <10>;
> +				vback-porch = <23>;
> +				vfront-porch = <12>;
> +				vsync-len = <1>;
> +				hsync-active = <0>;
> +				vsync-active = <0>;
> +				pixelclk-active = <0>;
> +				de-active = <0>;
> +			};
> +		};
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port at 0 {
> +				reg = <0>;
> +
> +				mipi_in_panel: endpoint {
> +					remote-endpoint = <&mipi_out_panel>;
> +				};
> +			};
> +
> +			port at 1 {
> +				reg = <1>;
> +
> +				mipi1_in_panel: endpoint at 1 {
> +					remote-endpoint = <&mipi1_out_panel>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&mipi_dsi1 {
> +	status = "okay";
> +
> +	ports {
> +		mipi1_out: port at 1 {
> +			reg = <1>;
> +
> +			mipi1_out_panel: endpoint {
> +				remote-endpoint = <&mipi1_in_panel>;
> +			};
> +		};
> +	};
> +};
> +
>  &pcie0 {
>  	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
>  	num-lanes = <4>;
> 






From adelg at google.com  Tue Aug 10 16:17:55 2021
From: adelg at google.com (Andrew Delgadillo)
Date: Tue, 10 Aug 2021 23:17:55 +0000
Subject: [PATCH v2] arm64: clean vdso & vdso32 files
Message-ID: <20210810231755.1743524-1-adelg@google.com>

commit a5b8ca97fbf8 ("arm64: do not descend to vdso directories twice")
changes the cleaning behavior of arm64's vdso files, in that vdso.lds,
vdso.so, and vdso.so.dbg are not removed upon a 'make clean/mrproper':

$ make defconfig ARCH=arm64
$ make ARCH=arm64
$ make mrproper ARCH=arm64
$ git clean -nxdf
Would remove arch/arm64/kernel/vdso/vdso.lds
Would remove arch/arm64/kernel/vdso/vdso.so
Would remove arch/arm64/kernel/vdso/vdso.so.dbg

To remedy this, manually descend into arch/arm64/kernel/vdso upon
cleaning.

After this commit:
$ make defconfig ARCH=arm64
$ make ARCH=arm64
$ make mrproper ARCH=arm64
$ git clean -nxdf
<empty>

Similar results are obtained for the vdso32 equivalent.

Signed-off-by: Andrew Delgadillo <adelg at google.com>
Cc: stable at vger.kernel.org
---
Changelog since v1:
- Also descend into vdso32 upon archclean
- Add stable to cc in signoff area

 arch/arm64/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index b52481f0605d..02997b253dee 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -181,6 +181,8 @@ archprepare:
 # We use MRPROPER_FILES and CLEAN_FILES now
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
+	$(Q)$(MAKE) $(clean)=arch/arm64/kernel/vdso
+	$(Q)$(MAKE) $(clean)=arch/arm64/kernel/vdso32
 
 ifeq ($(KBUILD_EXTMOD),)
 # We need to generate vdso-offsets.h before compiling certain files in kernel/.
-- 
2.32.0.605.g8dce9f2422-goog



From email2tema at gmail.com  Tue Aug 10 16:21:08 2021
From: email2tema at gmail.com (Art Nikpal)
Date: Wed, 11 Aug 2021 07:21:08 +0800
Subject: [PATCH 1/2] arm64: dts: meson: add spdif out to khadas-vim
In-Reply-To: <7dbba936-e8ab-4d47-1af8-0d3d1adb8c30@baylibre.com>
References: <20210810041630.3673406-1-art@khadas.com>
 <7dbba936-e8ab-4d47-1af8-0d3d1adb8c30@baylibre.com>
Message-ID: <CAKaHn9LWCHpAiO8siGmcOxA-FyurwE6x0T5_D7hwpVH72wScNw@mail.gmail.com>

> AFAIK the board doesn't have a physical SPDIF output, but one of the 40pin header can output SPDIF, right ?
Yes it's right

>In this case, following the other boards mainline definitions, we do not enable any function by default
For pins on the 40pin (or other programmable) headers.

ok ! now  i'm understand reason

But maybe it is possible to add this area as commented /* */
and users will have possibilities to uncomment  it.

> DT overlays
Yes but I still don't understand how-to apply dt overlays for EFI+grub
may be somebody can clarify this problem?

On Tue, Aug 10, 2021 at 3:55 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi,
>
> On 10/08/2021 06:16, Artem Lapkin wrote:
> > Add spdif output audio support to khadas-vim
> >
> > Signed-off-by: Artem Lapkin <art at khadas.com>
> > ---
> >  .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts  | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> > index 60feac0179c0..01f13822a616 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> > +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> > @@ -64,6 +64,13 @@ hdmi_connector_in: endpoint {
> >               };
> >       };
> >
> > +     spdif_dit: audio-codec-0 {
> > +             #sound-dai-cells = <0>;
> > +             compatible = "linux,spdif-dit";
> > +             status = "okay";
> > +             sound-name-prefix = "DIT";
> > +     };
> > +
> >       sound {
> >               compatible = "amlogic,gx-sound-card";
> >               model = "KHADAS-VIM";
> > @@ -97,11 +104,21 @@ codec-0 {
> >                               sound-dai = <&hdmi_tx>;
> >                       };
> >               };
> > +
> > +             dai-link-3 {
> > +                     sound-dai = <&aiu AIU_CPU CPU_SPDIF_ENCODER>;
> > +
> > +                     codec-0 {
> > +                             sound-dai = <&spdif_dit>;
> > +                     };
> > +             };
> >       };
> >  };
> >
> >  &aiu {
> >       status = "okay";
> > +     pinctrl-0 = <&spdif_out_h_pins>;
> > +     pinctrl-names = "default";
> >  };
> >
> >  &cec_AO {
> >
>
> AFAIK the board doesn't have a physical SPDIF output, but one of the 40pin header can output SPDIF, right ?
>
> In this case, following the other boards mainline definitions, we do not enable any function by default
> for pins on the 40pin (or other programmable) headers.
>
> There is still ongoing discussions on how to handle that on a more generic level, but you should write a bunch
> of DT overlays for the VIM boards to enable optional functions like SPDIF and store then in a public git
> tree for everybody to use (like armbian or LibreELEC for example) from the U-Boot stage.
>
> Neil


From santosh.shilimkar at oracle.com  Tue Aug 10 16:38:07 2021
From: santosh.shilimkar at oracle.com (Santosh Shilimkar)
Date: Tue, 10 Aug 2021 23:38:07 +0000
Subject: [GIT PULL] soc: Keystone driver update for v5.15
Message-ID: <0A637A41-2353-4900-962C-DBE50BBDE75A@oracle.com>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/drivers_soc_for_5.15

for you to fetch changes up to 62e8ce8506f5a998796dbdd93363fbed3342d379:

  dt-bindings: soc: ti: pruss: Add dma-coherent property (2021-08-10 15:51:22 -0700)

----------------------------------------------------------------
soc: Keystone SOC drivers for v5.15

The pull request contains:
 - ICSSG subsystem support for Keystone3 AM64x SOCs
 - Removes smartrefelx PM dependency for deeper low power states

----------------------------------------------------------------
Suman Anna (3):
      dt-bindings: soc: ti: pruss: Update bindings for K3 AM64x SoCs
      soc: ti: pruss: Enable support for ICSSG subsystems on K3 AM64x SoCs
      dt-bindings: soc: ti: pruss: Add dma-coherent property

Tony Lindgren (1):
      soc: ti: Remove pm_runtime_irq_safe() usage for smartreflex

 .../devicetree/bindings/soc/ti/ti,pruss.yaml       | 41 +++++++++++------
 drivers/bus/ti-sysc.c                              |  6 +--
 drivers/soc/ti/pruss.c                             |  1 +
 drivers/soc/ti/smartreflex.c                       | 52 +++++++++-------------
 include/linux/power/smartreflex.h                  |  2 +
 5 files changed, 55 insertions(+), 47 deletions(-)


From pgwipeout at gmail.com  Tue Aug 10 16:46:50 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 10 Aug 2021 19:46:50 -0400
Subject: [BUG] dw-mipi-dsi-rockchip display corruption with dsi panel
In-Reply-To: <3455830.ypAZr3mf50@diego>
References: <20210810223123.2174596-1-pgwipeout@gmail.com>
 <3455830.ypAZr3mf50@diego>
Message-ID: <CAMdYzYp7FvkOt3u+UJfTep1qb5Vs_ynv4tLVyWbzmXtD+Bvo5w@mail.gmail.com>

On Tue, Aug 10, 2021 at 7:11 PM Heiko St?bner <heiko at sntech.de> wrote:
>
> Hi Peter,
>
> Am Mittwoch, 11. August 2021, 00:31:24 CEST schrieb Peter Geis:
> > Good Evening,
> >
> > I've been attempting to light off the feiyang fy07024di26a30d panel on
> > the rockpro64. This is the official panel from the Pine64 store.
> > I've confirmed it works with the downstream kernel on both the rk3399
> > and rk3566, but on the mainline driver the display is partially
> > corrupted (see attached photo: [1]).
> >
> > As you can see, the left half of the display is fine, but the right half
> > of the display is corrupted with the pixels smearing horizontally.
> >
> > I saw when the panel was added, some additional code was added to
> > handle burst mode in the sun6_mipi_dsi driver [2].
> > I've seen that the dw-mipi-dsi driver appears to already support burst
> > mode and I can't find anything out of place there.
> > I also haven't had much success finding anything obviously different in
> > the downstream driver vs the upstream driver that would explain this.
> >
> > Attached below is the in-progress dts changes for an example of how the
> > panel is plugged in.
>
> is that really a dual-dsi panel needing two dsi controllers to drive it?
>
> With that tiny resultion of 1024x600 I definitly wouldn't expect this,
> in contrast to say the 2048x1536 dual-dsi displays used in the
> Gru-Scarlet ChromeOS tablets.
>
> So maybe just drop the 2nd dsi controller connection in a first step?
> Because I really don't think that is the case on the hardware.
>
> The dual-dsi setup means that you have one vop supplying half of its
> display data to each of the 2 involved dsi controllers. And you're missing
> in fact half of your display data.

Thanks, that was it.
I had tried removing the link previously, but I had to also disable
that controller altogether or the vop fails to probe silently.

That is a common issue I ran into when getting this all set up,
anything failed to probe for the dsi panel the vop just silently dies
in the background and graphics fail everywhere.

>
>
> Heiko
>
>
>
> > I admit, I have little understanding of the mipi-dsi internal workings,
> > so I'm reaching out to the experts on how to correct this.
> >
> > Thank you for your time,
> > Peter Geis
> >
> > [1] https://photos.app.goo.gl/LBA9M2WcweGaEb4cA
> > [2] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20181116163916.29621-1-jagan at amarulasolutions.com/
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > index 687a5afa5d2c..af55a30297ae 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > @@ -20,6 +20,13 @@ chosen {
> >               stdout-path = "serial2:1500000n8";
> >       };
> >
> > +     backlight: backlight {
> > +             compatible = "pwm-backlight";
> > +             pwms = <&pwm0 0 1000000 0>;
> > +             brightness-levels = <0 4 8 16 32 64 128 255>;
> > +             default-brightness-level = <128>;
> > +     };
> > +
> >       clkin_gmac: external-gmac-clock {
> >               compatible = "fixed-clock";
> >               clock-frequency = <125000000>;
> > @@ -69,7 +76,7 @@ diy_led: led-1 {
> >
> >       fan: pwm-fan {
> >               compatible = "pwm-fan";
> > -             cooling-levels = <0 150 200 255>;
> > +             cooling-levels = <0 100 150 255>;
> >               #cooling-cells = <2>;
> >               fan-supply = <&vcc12v_dcin>;
> >               pwms = <&pwm1 0 50000 0>;
> > @@ -220,6 +227,16 @@ vdd_log: vdd-log {
> >               regulator-max-microvolt = <1700000>;
> >               vin-supply = <&vcc5v0_sys>;
> >       };
> > +
> > +     avdd: avdd {
> > +             compatible = "regulator-fixed";
> > +             regulator-name = "avdd";
> > +             regulator-always-on;
> > +             regulator-boot-on;
> > +             regulator-min-microvolt = <11000000>;
> > +             regulator-max-microvolt = <11000000>;
> > +             vin-supply = <&vcc3v3_s0>;
> > +     };
> >  };
> >
> >  &cpu_l0 {
> > @@ -428,8 +445,8 @@ regulator-state-mem {
> >
> >                       vcc3v0_touch: LDO_REG2 {
> >                               regulator-name = "vcc3v0_touch";
> > -                             regulator-always-on;
> > -                             regulator-boot-on;
> > +//                           regulator-always-on;
> > +//                           regulator-boot-on;
> >                               regulator-min-microvolt = <3000000>;
> >                               regulator-max-microvolt = <3000000>;
> >                               regulator-state-mem {
> > @@ -518,8 +535,8 @@ regulator-state-mem {
> >
> >                       vcc3v3_s0: SWITCH_REG2 {
> >                               regulator-name = "vcc3v3_s0";
> > -                             regulator-always-on;
> > -                             regulator-boot-on;
> > +//                           regulator-always-on;
> > +//                           regulator-boot-on;
> >                               regulator-state-mem {
> >                                       regulator-off-in-suspend;
> >                               };
> > @@ -593,6 +610,19 @@ fusb0: typec-portc at 22 {
> >               vbus-supply = <&vcc5v0_typec>;
> >               status = "okay";
> >       };
> > +
> > +     touch: touchscreen at 5d {
> > +             compatible = "goodix,gt911";
> > +             reg = <0x5d>;
> > +             AVDD28-supply = <&vcc3v0_touch>;
> > +             VDDIO-supply = <&vcc3v0_touch>;
> > +             interrupt-parent = <&gpio4>;
> > +             interrupts = <RK_PD5 IRQ_TYPE_EDGE_FALLING>;
> > +             irq-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
> > +             reset-gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
> > +//           touchscreen-inverted-x;
> > +//           touchscreen-inverted-y;
> > +     };
> >  };
> >
> >  &i2s0 {
> > @@ -628,6 +658,88 @@ &io_domains {
> >       gpio1830-supply = <&vcc_3v0>;
> >  };
> >
> > +&mipi_dsi {
> > +     status = "okay";
> > +     clock-master;
> > +
> > +     ports {
> > +             mipi_out: port at 1 {
> > +                     reg = <1>;
> > +
> > +                     mipi_out_panel: endpoint {
> > +                             remote-endpoint = <&mipi_in_panel>;
> > +                     };
> > +             };
> > +     };
> > +
> > +     mipi_panel: panel at 0 {
> > +             compatible = "feiyang,fy07024di26a30d";
> > +             reg = <0>;
> > +             backlight = <&backlight>;
> > +             reset-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
> > +//           enable-gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
> > +             width-mm = <154>;
> > +             height-mm = <86>;
> > +             rotation = <0>;
> > +             avdd-supply = <&avdd>;
> > +             dvdd-supply = <&vcc3v3_s0>;
> > +
> > +             display-timings {
> > +                     native-mode = <&timing0>;
> > +                     timing0: timing0 {
> > +                             clock-frequency = <50000000>;
> > +                             hactive = <1024>;
> > +                             vactive = <600>;
> > +                             hfront-porch = <160>;
> > +                             hback-porch = <160>;
> > +                             hsync-len = <10>;
> > +                             vback-porch = <23>;
> > +                             vfront-porch = <12>;
> > +                             vsync-len = <1>;
> > +                             hsync-active = <0>;
> > +                             vsync-active = <0>;
> > +                             pixelclk-active = <0>;
> > +                             de-active = <0>;
> > +                     };
> > +             };
> > +
> > +             ports {
> > +                     #address-cells = <1>;
> > +                     #size-cells = <0>;
> > +
> > +                     port at 0 {
> > +                             reg = <0>;
> > +
> > +                             mipi_in_panel: endpoint {
> > +                                     remote-endpoint = <&mipi_out_panel>;
> > +                             };
> > +                     };
> > +
> > +                     port at 1 {
> > +                             reg = <1>;
> > +
> > +                             mipi1_in_panel: endpoint at 1 {
> > +                                     remote-endpoint = <&mipi1_out_panel>;
> > +                             };
> > +                     };
> > +             };
> > +     };
> > +};
> > +
> > +&mipi_dsi1 {
> > +     status = "okay";
> > +
> > +     ports {
> > +             mipi1_out: port at 1 {
> > +                     reg = <1>;
> > +
> > +                     mipi1_out_panel: endpoint {
> > +                             remote-endpoint = <&mipi1_in_panel>;
> > +                     };
> > +             };
> > +     };
> > +};
> > +
> >  &pcie0 {
> >       ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
> >       num-lanes = <4>;
> >
>
>
>
>


From vee.khee.wong at linux.intel.com  Tue Aug 10 16:50:41 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Wed, 11 Aug 2021 07:50:41 +0800
Subject: [PATCH net-next 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <20210809110626.4kfkegwixiualq2x@skbuf>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
 <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
 <20210809110626.4kfkegwixiualq2x@skbuf>
Message-ID: <20210810235041.GA30818@linux.intel.com>

On Mon, Aug 09, 2021 at 02:06:26PM +0300, Vladimir Oltean wrote:
> Hi VK,
> 
> On Mon, Aug 09, 2021 at 06:22:28PM +0800, Wong Vee Khee wrote:
> > diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
> > index 63fda3fc40aa..c7a3aa862079 100644
> > --- a/drivers/net/pcs/pcs-xpcs.c
> > +++ b/drivers/net/pcs/pcs-xpcs.c
> > @@ -1081,7 +1081,8 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = {
> >  };
> >  
> >  struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> > -			    phy_interface_t interface)
> > +			    phy_interface_t interface,
> > +			    bool skip_reset)
> >  {
> >  	struct dw_xpcs *xpcs;
> >  	u32 xpcs_id;
> > @@ -1113,9 +1114,16 @@ struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> >  		xpcs->pcs.ops = &xpcs_phylink_ops;
> >  		xpcs->pcs.poll = true;
> >  
> > -		ret = xpcs_soft_reset(xpcs, compat);
> > -		if (ret)
> > -			goto out;
> > +		if (!skip_reset) {
> > +			dev_info(&xpcs->mdiodev->dev, "%s: xPCS soft reset\n",
> > +				 __func__);
> > +			ret = xpcs_soft_reset(xpcs, compat);
> > +			if (ret)
> > +				goto out;
> > +		} else {
> > +			dev_info(&xpcs->mdiodev->dev,
> > +				 "%s: skip xpcs soft reset\n", __func__);
> > +		}
> 
> I don't feel like the prints are really necessary.

Sounds good to me. I'll remove these.

> 
> >  
> >  		return xpcs;
> >  	}
> > diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
> > index add077a81b21..0c05a63f3446 100644
> > --- a/include/linux/pcs/pcs-xpcs.h
> > +++ b/include/linux/pcs/pcs-xpcs.h
> > @@ -36,7 +36,8 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
> >  int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
> >  		    int enable);
> >  struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> > -			    phy_interface_t interface);
> > +			    phy_interface_t interface,
> > +			    bool xpcs_reset);
> >  void xpcs_destroy(struct dw_xpcs *xpcs);
> >  
> 
> How about exporting the reset functionality as a separate function, and
> the Intel Alder Lake stmmac shim just won't call it? Like this:
> 
> -----------------------------[ cut here ]-----------------------------
> diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
> index 19aea8fb76f6..5acf6742da4d 100644
> --- a/drivers/net/dsa/sja1105/sja1105_mdio.c
> +++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
> @@ -437,13 +437,17 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
>  			goto out_pcs_free;
>  		}
>  
> -		xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
> +		xpcs = xpcs_create(mdiodev);
>  		if (IS_ERR(xpcs)) {
>  			rc = PTR_ERR(xpcs);
>  			goto out_pcs_free;
>  		}
>  
>  		priv->xpcs[port] = xpcs;
> +
> +		rc = xpcs_reset(xpcs, priv->phy_mode[port]);
> +		if (rc)
> +			goto out_pcs_free;
>  	}
>  
>  	priv->mdio_pcs = bus;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> index a5d150c5f3d8..81a145009488 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
> @@ -401,12 +401,15 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
>  {
>  	struct net_device *ndev = bus->priv;
>  	struct mdio_device *mdiodev;
> +	bool skip_xpcs_soft_reset;
>  	struct stmmac_priv *priv;
>  	struct dw_xpcs *xpcs;
>  	int mode, addr;
> +	int err;
>  
>  	priv = netdev_priv(ndev);
>  	mode = priv->plat->phy_interface;
> +	skip_xpcs_soft_reset = priv->plat->skip_xpcs_soft_reset;
>  
>  	/* Try to probe the XPCS by scanning all addresses. */
>  	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
> @@ -414,12 +417,21 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
>  		if (IS_ERR(mdiodev))
>  			continue;
>  
> -		xpcs = xpcs_create(mdiodev, mode);
> +		xpcs = xpcs_create(mdiodev);
>  		if (IS_ERR_OR_NULL(xpcs)) {
>  			mdio_device_free(mdiodev);
>  			continue;
>  		}
>  
> +		if (!skip_xpcs_soft_reset) {
> +			err = xpcs_reset(xpcs, mode);
> +			if (err) {
> +				xpcs_destroy(xpcs);
> +				mdio_device_free(mdiodev);
> +				continue;
> +			}
> +		}
> +
>  		priv->hw->xpcs = xpcs;
>  		break;
>  	}
> diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
> index 63fda3fc40aa..2e721e57bee4 100644
> --- a/drivers/net/pcs/pcs-xpcs.c
> +++ b/drivers/net/pcs/pcs-xpcs.c
> @@ -248,6 +248,18 @@ static int xpcs_soft_reset(struct dw_xpcs *xpcs,
>  	return xpcs_poll_reset(xpcs, dev);
>  }
>  
> +int xpcs_reset(struct dw_xpcs *xpcs, phy_interface_t interface)
> +{
> +	const struct xpcs_compat *compat;
> +
> +	compat = xpcs_find_compat(xpcs->id, interface);
> +	if (!compat)
> +		return -ENODEV;
> +
> +	return xpcs_soft_reset(xpcs, compat);
> +}
> +EXPORT_SYMBOL_GPL(xpcs_reset);
> +
>  #define xpcs_warn(__xpcs, __state, __args...) \
>  ({ \
>  	if ((__state)->link) \
> @@ -1080,12 +1092,11 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = {
>  	.pcs_link_up = xpcs_link_up,
>  };
>  
> -struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> -			    phy_interface_t interface)
> +struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
>  {
>  	struct dw_xpcs *xpcs;
>  	u32 xpcs_id;
> -	int i, ret;
> +	int i;
>  
>  	xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
>  	if (!xpcs)
> @@ -1097,35 +1108,18 @@ struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
>  
>  	for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
>  		const struct xpcs_id *entry = &xpcs_id_list[i];
> -		const struct xpcs_compat *compat;
>  
>  		if ((xpcs_id & entry->mask) != entry->id)
>  			continue;
>  
>  		xpcs->id = entry;
> -
> -		compat = xpcs_find_compat(entry, interface);
> -		if (!compat) {
> -			ret = -ENODEV;
> -			goto out;
> -		}
> -
>  		xpcs->pcs.ops = &xpcs_phylink_ops;
>  		xpcs->pcs.poll = true;
>  
> -		ret = xpcs_soft_reset(xpcs, compat);
> -		if (ret)
> -			goto out;
> -
>  		return xpcs;
>  	}
>  
> -	ret = -ENODEV;
> -
> -out:
> -	kfree(xpcs);
> -
> -	return ERR_PTR(ret);
> +	return ERR_PTR(-ENODEV);
>  }
>  EXPORT_SYMBOL_GPL(xpcs_create);
>  
> diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
> index add077a81b21..d841f55f12cc 100644
> --- a/include/linux/pcs/pcs-xpcs.h
> +++ b/include/linux/pcs/pcs-xpcs.h
> @@ -35,8 +35,8 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
>  		   struct phylink_link_state *state);
>  int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
>  		    int enable);
> -struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
> -			    phy_interface_t interface);
> +int xpcs_reset(struct dw_xpcs *xpcs, phy_interface_t interface);
> +struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev);
>  void xpcs_destroy(struct dw_xpcs *xpcs);
>  
>  #endif /* __LINUX_PCS_XPCS_H */
> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
> index a6f03b36fc4f..0f901773c5e4 100644
> --- a/include/linux/stmmac.h
> +++ b/include/linux/stmmac.h
> @@ -268,5 +268,6 @@ struct plat_stmmacenet_data {
>  	int msi_rx_base_vec;
>  	int msi_tx_base_vec;
>  	bool use_phy_wol;
> +	bool skip_xpcs_soft_reset;
>  };
>  #endif
> -----------------------------[ cut here ]-----------------------------
> 
> I also gave this patch a run on sja1105 and it still works.

Thanks for the suggestion. I tested it out on stmmac and it works.
I will use this as it looks neater. :)

Regards,
 VK



From vee.khee.wong at linux.intel.com  Tue Aug 10 16:55:29 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Wed, 11 Aug 2021 07:55:29 +0800
Subject: [PATCH net-next 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <YREvDRkiuScyN8Ws@lunn.ch>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
 <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
 <YREvDRkiuScyN8Ws@lunn.ch>
Message-ID: <20210810235529.GB30818@linux.intel.com>

Hi Andrew,
On Mon, Aug 09, 2021 at 03:35:09PM +0200, Andrew Lunn wrote:
> On Mon, Aug 09, 2021 at 06:22:28PM +0800, Wong Vee Khee wrote:
> > From: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>
> > 
> > Unlike any other platforms, Intel AlderLake-S uses Synopsys SerDes where
> > all the SerDes PLL configurations are controlled by the xPCS at the BIOS
> > level. If the driver perform a xPCS soft reset on initialization, these
> > settings will be switched back to the power on reset values.
> > 
> > This changes the xpcs_create function to take in an additional argument
> > to check if the platform request to skip xPCS soft reset during device
> > initialization.
> 
> Why not just call into the BIOS and ask it to configure the SERDES?
> Isn't that what ACPI is all about, hiding the details from the OS? Or
> did the BIOS writers not add a control method to do this?
> 
>     Andrew

BIOS does configured the SerDes. The problem here is that all the
configurations done by BIOS are being reset at xpcs_create().

We would want user of the pcs-xpcs module (stmmac, sja1105) to have
control whether or not we need to perform to the soft reset in the
xpcs_create() call.

Hope that explained.

Regards,
 VK


From andrew at aj.id.au  Tue Aug 10 17:19:05 2021
From: andrew at aj.id.au (Andrew Jeffery)
Date: Wed, 11 Aug 2021 09:49:05 +0930
Subject: [RFC PATCH 4/6] leds: pca955x: Use pinctrl to map GPIOs to pins
In-Reply-To: <CACRpkdZm9C23aHTWs8DNX1RChSB4A-X0PoyW5wnH2XyQQeviag@mail.gmail.com>
References: <20210723075858.376378-1-andrew@aj.id.au>
 <20210723075858.376378-5-andrew@aj.id.au>
 <CACRpkdZm9C23aHTWs8DNX1RChSB4A-X0PoyW5wnH2XyQQeviag@mail.gmail.com>
Message-ID: <96e52916-f113-4a91-b83f-e0de144611ca@www.fastmail.com>



On Tue, 10 Aug 2021, at 23:24, Linus Walleij wrote:
> On Fri, Jul 23, 2021 at 9:59 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> 
> > The leds-pca955x driver currently assumes that the GPIO numberspace and
> > the pin numberspace are the same. This quickly falls apart with a
> > devicetree binding such as the following:
> (...)
> 
> Honestly I do not understand this patch. It seems to implement a pin
> controller and using it in nonstandard ways.

Yeah, it's a bit abusive, hence RFC :)

> 
> If something implements the pin controller driver API it should be
> used as such IMO, externally. This seems to be using it do relay
> calls to itself which seems complicated, just invent something
> locally in the driver in that case? No need to use pin control?

Right. After discussions with Andy I'm going to rework the approach to 
GPIOs which will remove a lot of complexity.

The thought was to try to maintain the intent of the devicetree binding 
and use existing APIs, but all-in-all it's ended up twisting things up 
in knots a fair bit. We discard a lot of it by making the gpiochip 
always cover all pins and track use directly in the driver.

> 
> Can you explain why this LED driver needs to implement a pin
> controller?

The short answer is it doesn't as it has none of the associated 
hardware.

I'll cook up something simpler with the aim to avoid non-standard (or 
any) pinctrl.

Andrew


From andrew at aj.id.au  Tue Aug 10 17:24:53 2021
From: andrew at aj.id.au (Andrew Jeffery)
Date: Wed, 11 Aug 2021 09:54:53 +0930
Subject: [RFC PATCH 1/6] pinctrl: Add pinctrl_gpio_as_pin()
In-Reply-To: <CACRpkdZ4A3Lw2U+_jXfbuXJFhpesi3SzNN1Codqxi4sLNu5zPw@mail.gmail.com>
References: <20210723075858.376378-1-andrew@aj.id.au>
 <20210723075858.376378-2-andrew@aj.id.au>
 <CACRpkdZ4A3Lw2U+_jXfbuXJFhpesi3SzNN1Codqxi4sLNu5zPw@mail.gmail.com>
Message-ID: <53199b3e-a711-4071-96a3-7836d3323906@www.fastmail.com>



On Tue, 10 Aug 2021, at 23:04, Linus Walleij wrote:
> On Fri, Jul 23, 2021 at 9:59 AM Andrew Jeffery <andrew at aj.id.au> wrote:
> 
> > Allow gpiochips to map the GPIO numberspace onto a pin numberspace when
> > the register layout for GPIO control is implemented in terms of the
> > pin numberspace.
> >
> > This requirement sounds kind of strange, but the patch is driven by
> > trying to resolve a bug in the leds-pca955x driver where this mapping is
> > not correctly performed.
> >
> > Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
> 
> (...)
> 
> Hm  this looks a bit strange...
> 
> > +int pinctrl_gpio_as_pin(struct pinctrl_dev *pctldev, unsigned int gpio)
> 
> This is not a good name for this function. Try to come up with
> a name that says exactly what the function does.
> 
> E.g. "apple pear as apple slice" isn't very helpful, the use case for
> this is really hard to understand.

That's probably because I shouldn't be trying to do what I'm doing :)

I'll stop doing that (i.e. rework patch 4/6) and this will go away entirely.

> 
> > +EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin);
> 
> This looks completely wrong.

Yeah, whoops. That was an oversight while iterating on the patch.

Andrew


From masahiroy at kernel.org  Tue Aug 10 18:15:24 2021
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Wed, 11 Aug 2021 10:15:24 +0900
Subject: [PATCH] arm64: clean vdso files
In-Reply-To: <20210810135236.GA3101@willie-the-truck>
References: <20210809191414.3572827-1-adelg@google.com>
 <20210810135236.GA3101@willie-the-truck>
Message-ID: <CAK7LNAR2Wxvujh5USqWsrTMfupKeKhb0zzbP+SDOY6McR3O25A@mail.gmail.com>

On Tue, Aug 10, 2021 at 10:52 PM Will Deacon <will at kernel.org> wrote:
>
> [+Masahiro]
>
> On Mon, Aug 09, 2021 at 07:14:14PM +0000, Andrew Delgadillo wrote:
> > commit a5b8ca97fbf8 ("arm64: do not descend to vdso directories twice")
> > changes the cleaning behavior of arm64's vdso files, in that vdso.lds,
> > vdso.so, and vdso.so.dbg are not removed upon a 'make clean/mrproper':
> >
> > $ make defconfig ARCH=arm64
> > $ make ARCH=arm64
> > $ make mrproper ARCH=arm64
> > $ git clean -nxdf
> > Would remove arch/arm64/kernel/vdso/vdso.lds
> > Would remove arch/arm64/kernel/vdso/vdso.so
> > Would remove arch/arm64/kernel/vdso/vdso.so.dbg
> >
> > To remedy this, manually descend into arch/arm64/kernel/vdso upon
> > cleaning.
> >
> > After this commit:
> > $ make defconfig ARCH=arm64
> > $ make ARCH=arm64
> > $ make mrproper ARCH=arm64
> > $ git clean -nxdf
> > <empty>
>
> Well spotted!



Ah, I missed this. Sorry.

Yes, please do this for vdso,
and vdso32 as well.





> > Signed-off-by: Andrew Delgadillo <adelg at google.com>
> > ---
> >  arch/arm64/Makefile | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
> > index b52481f0605d..ef6598cb5a9b 100644
> > --- a/arch/arm64/Makefile
> > +++ b/arch/arm64/Makefile
> > @@ -181,6 +181,7 @@ archprepare:
> >  # We use MRPROPER_FILES and CLEAN_FILES now
> >  archclean:
> >       $(Q)$(MAKE) $(clean)=$(boot)
> > +     $(Q)$(MAKE) $(clean)=arch/arm64/kernel/vdso
>
> I think we also need to clean the vdso32 directory here. Please can you
> send a v2 with that added?
>
> Cheers,
>
> Will



-- 
Best Regards
Masahiro Yamada


From yongqiang.niu at mediatek.com  Tue Aug 10 18:47:47 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Wed, 11 Aug 2021 09:47:47 +0800
Subject: [PATCH v4] drm/mediatek: clear pending flag when cmdq packet is done
Message-ID: <1628646468-29775-1-git-send-email-yongqiang.niu@mediatek.com>

Change since v3:
- remove useless condition check


Yongqiang Niu (1):
  drm/mediatek: clear pending flag when cmdq packet is done.

 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 47 +++++++++++++++++++++++++++++----
 1 file changed, 42 insertions(+), 5 deletions(-)

-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Tue Aug 10 18:47:48 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Wed, 11 Aug 2021 09:47:48 +0800
Subject: [PATCH v4] drm/mediatek: clear pending flag when cmdq packet is done.
In-Reply-To: <1628646468-29775-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1628646468-29775-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1628646468-29775-2-git-send-email-yongqiang.niu@mediatek.com>

In cmdq mode, packet may be flushed before it is executed, so
the pending flag should be cleared after cmdq packet is done.

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 47 +++++++++++++++++++++++++++++----
 1 file changed, 42 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 4c25e33..89f093d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -267,6 +267,36 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 {
 	struct mtk_drm_crtc *mtk_crtc = container_of(cl, struct mtk_drm_crtc, cmdq_cl);
 	struct cmdq_cb_data *data = mssg;
+	struct mtk_crtc_state *state;
+	unsigned int i;
+
+	state = to_mtk_crtc_state(mtk_crtc->base.state);
+
+	state->pending_config = false;
+
+	if (mtk_crtc->pending_planes) {
+		for (i = 0; i < mtk_crtc->layer_nr; i++) {
+			struct drm_plane *plane = &mtk_crtc->planes[i];
+			struct mtk_plane_state *plane_state;
+
+			plane_state = to_mtk_plane_state(plane->state);
+
+			plane_state->pending.config = false;
+		}
+		mtk_crtc->pending_planes = false;
+	}
+
+	if (mtk_crtc->pending_async_planes) {
+		for (i = 0; i < mtk_crtc->layer_nr; i++) {
+			struct drm_plane *plane = &mtk_crtc->planes[i];
+			struct mtk_plane_state *plane_state;
+
+			plane_state = to_mtk_plane_state(plane->state);
+
+			plane_state->pending.async_config = false;
+		}
+		mtk_crtc->pending_async_planes = false;
+	}
 
 	mtk_crtc->cmdq_vblank_cnt = 0;
 	mtk_drm_cmdq_pkt_destroy(mtk_crtc->cmdq_chan, data->pkt);
@@ -423,7 +453,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 				    state->pending_vrefresh, 0,
 				    cmdq_handle);
 
-		state->pending_config = false;
+		if (!cmdq_handle)
+			state->pending_config = false;
 	}
 
 	if (mtk_crtc->pending_planes) {
@@ -443,9 +474,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 				mtk_ddp_comp_layer_config(comp, local_layer,
 							  plane_state,
 							  cmdq_handle);
-			plane_state->pending.config = false;
+			if (!cmdq_handle)
+				plane_state->pending.config = false;
 		}
-		mtk_crtc->pending_planes = false;
+
+		if (!cmdq_handle)
+			mtk_crtc->pending_planes = false;
 	}
 
 	if (mtk_crtc->pending_async_planes) {
@@ -465,9 +499,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
 				mtk_ddp_comp_layer_config(comp, local_layer,
 							  plane_state,
 							  cmdq_handle);
-			plane_state->pending.async_config = false;
+			if (!cmdq_handle)
+				plane_state->pending.async_config = false;
 		}
-		mtk_crtc->pending_async_planes = false;
+
+		if (!cmdq_handle)
+			mtk_crtc->pending_async_planes = false;
 	}
 }
 
-- 
1.8.1.1.dirty

From thunder.leizhen at huawei.com  Tue Aug 10 19:07:27 2021
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Wed, 11 Aug 2021 10:07:27 +0800
Subject: [PATCH RFC 0/8] iommu/arm-smmu-v3: add support for ECMDQ register
 mode
In-Reply-To: <20210810183529.GC3296@willie-the-truck>
References: <20210626110130.2416-1-thunder.leizhen@huawei.com>
 <20210810183529.GC3296@willie-the-truck>
Message-ID: <af0c3116-c110-095d-d250-0b6d56614a0b@huawei.com>



On 2021/8/11 2:35, Will Deacon wrote:
> On Sat, Jun 26, 2021 at 07:01:22PM +0800, Zhen Lei wrote:
>> SMMU v3.3 added a new feature, which is Enhanced Command queue interface
>> for reducing contention when submitting Commands to the SMMU, in this
>> patch set, ECMDQ is the abbreviation of Enhanced Command Queue.
>>
>> When the hardware supports ECMDQ and each core can exclusively use one ECMDQ,
>> each core does not need to compete with other cores when using its own ECMDQ.
>> This means that each core can insert commands in parallel. If each ECMDQ can
>> execute commands in parallel, the overall performance may be better. However,
>> our hardware currently does not support multiple ECMDQ execute commands in
>> parallel.
>>
>> In order to reuse existing code, I originally still call arm_smmu_cmdq_issue_cmdlist()
>> to insert commands. Even so, however, there was a performance improvement of nearly 12%
>> in strict mode.
>>
>> The test environment is the EMU, which simulates the connection of the 200 Gbit/s NIC.
>> Number of queues:    passthrough   lazy   strict(ECMDQ)  strict(CMDQ)
>>       6                  188        180       162           145        --> 11.7% improvement
>>       8                  188        188       184           183        --> 0.55% improvement
> 
> Sorry, I don't quite follow the numbers here. Why does the number of queues
> affect the classic "CMDQ" mode? We only have one queue there, right?

These queues indicates the network concurrency, maybe I should use channels or threads.
6 means six threads are deployed on different cores using their own channels to send
and receive network packets.

> 
>> In recent days, I implemented a new function without competition with other
>> cores to replace arm_smmu_cmdq_issue_cmdlist() when a core can have an ECMDQ.
>> I'm guessing it might get better performance results. Because the EMU is too
>> slow, it will take a while before the relevant data is available.
> 
> I'd certainly prefer to wait until we have something we know is
> representative. 

Yes, it would be better to have an actual set of performance data. Now the EMU is
used to analyze hardware problems. This test has not been numbered yet.

> However, I can take the first four prep patches now if you
> respin the second one. At least that's then less for you to carry.

Great. Thank you. I will respin the second one.

> 
> I'd also like review from the Arm side on this (and thank you for adopting
> the architecture unlike others seem to have done judging by the patches
> floating around).
> 
> Will
> .
> 


From yongqiang.niu at mediatek.com  Tue Aug 10 19:09:57 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Wed, 11 Aug 2021 10:09:57 +0800
Subject: [PATCH v9, 0/5] drm/mediatek: add support for mediatek SOC MT8192
Message-ID: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>

Change since v8:
rebase Linux v5.14-rc1

Yongqiang Niu (5):
  drm/mediatek: add component OVL_2L2
  drm/mediatek: add component POSTMASK
  drm/mediatek: add component RDMA4
  soc: mediatek: add mtk mutex support for MT8192
  drm/mediatek: add support for mediatek SOC MT8192

 drivers/gpu/drm/mediatek/mtk_disp_ccorr.c   |   6 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     |  20 ++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c    |   6 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 102 ++++++++++++++++++++--------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  42 ++++++++++++
 drivers/soc/mediatek/mtk-mutex.c            |  35 ++++++++++
 7 files changed, 183 insertions(+), 29 deletions(-)

-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Tue Aug 10 19:10:01 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Wed, 11 Aug 2021 10:10:01 +0800
Subject: [PATCH v9, 4/5] soc: mediatek: add mtk mutex support for MT8192
In-Reply-To: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1628647802-5127-5-git-send-email-yongqiang.niu@mediatek.com>

Add mtk mutex support for MT8192 SoC.

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2e4bcc3..2ca55bb 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -39,6 +39,18 @@
 #define MT8167_MUTEX_MOD_DISP_DITHER		15
 #define MT8167_MUTEX_MOD_DISP_UFOE		16
 
+#define MT8192_MUTEX_MOD_DISP_OVL0		0
+#define MT8192_MUTEX_MOD_DISP_OVL0_2L		1
+#define MT8192_MUTEX_MOD_DISP_RDMA0		2
+#define MT8192_MUTEX_MOD_DISP_COLOR0		4
+#define MT8192_MUTEX_MOD_DISP_CCORR0		5
+#define MT8192_MUTEX_MOD_DISP_AAL0		6
+#define MT8192_MUTEX_MOD_DISP_GAMMA0		7
+#define MT8192_MUTEX_MOD_DISP_POSTMASK0		8
+#define MT8192_MUTEX_MOD_DISP_DITHER0		9
+#define MT8192_MUTEX_MOD_DISP_OVL2_2L		16
+#define MT8192_MUTEX_MOD_DISP_RDMA4		17
+
 #define MT8183_MUTEX_MOD_DISP_RDMA0		0
 #define MT8183_MUTEX_MOD_DISP_RDMA1		1
 #define MT8183_MUTEX_MOD_DISP_OVL0		9
@@ -214,6 +226,20 @@ struct mtk_mutex_ctx {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
+static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+	[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
+	[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
+	[DDP_COMPONENT_COLOR0] = MT8192_MUTEX_MOD_DISP_COLOR0,
+	[DDP_COMPONENT_DITHER] = MT8192_MUTEX_MOD_DISP_DITHER0,
+	[DDP_COMPONENT_GAMMA] = MT8192_MUTEX_MOD_DISP_GAMMA0,
+	[DDP_COMPONENT_POSTMASK0] = MT8192_MUTEX_MOD_DISP_POSTMASK0,
+	[DDP_COMPONENT_OVL0] = MT8192_MUTEX_MOD_DISP_OVL0,
+	[DDP_COMPONENT_OVL_2L0] = MT8192_MUTEX_MOD_DISP_OVL0_2L,
+	[DDP_COMPONENT_OVL_2L2] = MT8192_MUTEX_MOD_DISP_OVL2_2L,
+	[DDP_COMPONENT_RDMA0] = MT8192_MUTEX_MOD_DISP_RDMA0,
+	[DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4,
+};
+
 static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
@@ -275,6 +301,13 @@ struct mtk_mutex_ctx {
 	.no_clk = true,
 };
 
+static const struct mtk_mutex_data mt8192_mutex_driver_data = {
+	.mutex_mod = mt8192_mutex_mod,
+	.mutex_sof = mt8183_mutex_sof,
+	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
+};
+
 struct mtk_mutex *mtk_mutex_get(struct device *dev)
 {
 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
@@ -507,6 +540,8 @@ static int mtk_mutex_remove(struct platform_device *pdev)
 	  .data = &mt8173_mutex_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = &mt8183_mutex_driver_data},
+	{ .compatible = "mediatek,mt8192-disp-mutex",
+	  .data = &mt8192_mutex_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Tue Aug 10 19:09:59 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Wed, 11 Aug 2021 10:09:59 +0800
Subject: [PATCH v9, 2/5] drm/mediatek: add component POSTMASK
In-Reply-To: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1628647802-5127-3-git-send-email-yongqiang.niu@mediatek.com>

This patch add component POSTMASK.

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 102 ++++++++++++++++++++--------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 2 files changed, 73 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index b564513..17309ce 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -50,6 +50,12 @@
 
 #define AAL_EN					BIT(0)
 
+#define DISP_POSTMASK_EN			0x0000
+#define POSTMASK_EN				BIT(0)
+#define DISP_POSTMASK_CFG			0x0020
+#define POSTMASK_RELAY_MODE			BIT(0)
+#define DISP_POSTMASK_SIZE			0x0030
+
 #define DISP_DITHERING				BIT(2)
 #define DITHER_LSB_ERR_SHIFT_R(x)		(((x) & 0x7) << 28)
 #define DITHER_OVFLW_BIT_R(x)			(((x) & 0x7) << 24)
@@ -190,6 +196,32 @@ static void mtk_ufoe_start(struct device *dev)
 	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
 }
 
+static void mtk_postmask_config(struct device *dev, unsigned int w,
+			unsigned int h, unsigned int vrefresh,
+			unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs,
+		      DISP_POSTMASK_SIZE);
+	mtk_ddp_write(cmdq_pkt, POSTMASK_RELAY_MODE, &priv->cmdq_reg,
+		      priv->regs, DISP_POSTMASK_CFG);
+}
+
+static void mtk_postmask_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel(POSTMASK_EN, priv->regs + DISP_POSTMASK_EN);
+}
+
+static void mtk_postmask_stop(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(0x0, priv->regs + DISP_POSTMASK_EN);
+}
+
 static void mtk_aal_config(struct device *dev, unsigned int w,
 			   unsigned int h, unsigned int vrefresh,
 			   unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -321,6 +353,14 @@ static void mtk_dither_stop(struct device *dev)
 	.bgclr_in_off = mtk_ovl_bgclr_in_off,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_postmask = {
+	.clk_enable = mtk_ddp_clk_enable,
+	.clk_disable = mtk_ddp_clk_disable,
+	.config = mtk_postmask_config,
+	.start = mtk_postmask_start,
+	.stop = mtk_postmask_stop,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_rdma = {
 	.clk_enable = mtk_rdma_clk_enable,
 	.clk_disable = mtk_rdma_clk_disable,
@@ -356,6 +396,7 @@ static void mtk_dither_stop(struct device *dev)
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_BLS] = "bls",
+	[MTK_DISP_POSTMASK] = "postmask",
 };
 
 struct mtk_ddp_comp_match {
@@ -365,36 +406,37 @@ struct mtk_ddp_comp_match {
 };
 
 static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
-	[DDP_COMPONENT_AAL0]	= { MTK_DISP_AAL,	0, &ddp_aal },
-	[DDP_COMPONENT_AAL1]	= { MTK_DISP_AAL,	1, &ddp_aal },
-	[DDP_COMPONENT_BLS]	= { MTK_DISP_BLS,	0, NULL },
-	[DDP_COMPONENT_CCORR]	= { MTK_DISP_CCORR,	0, &ddp_ccorr },
-	[DDP_COMPONENT_COLOR0]	= { MTK_DISP_COLOR,	0, &ddp_color },
-	[DDP_COMPONENT_COLOR1]	= { MTK_DISP_COLOR,	1, &ddp_color },
-	[DDP_COMPONENT_DITHER]	= { MTK_DISP_DITHER,	0, &ddp_dither },
-	[DDP_COMPONENT_DPI0]	= { MTK_DPI,		0, &ddp_dpi },
-	[DDP_COMPONENT_DPI1]	= { MTK_DPI,		1, &ddp_dpi },
-	[DDP_COMPONENT_DSI0]	= { MTK_DSI,		0, &ddp_dsi },
-	[DDP_COMPONENT_DSI1]	= { MTK_DSI,		1, &ddp_dsi },
-	[DDP_COMPONENT_DSI2]	= { MTK_DSI,		2, &ddp_dsi },
-	[DDP_COMPONENT_DSI3]	= { MTK_DSI,		3, &ddp_dsi },
-	[DDP_COMPONENT_GAMMA]	= { MTK_DISP_GAMMA,	0, &ddp_gamma },
-	[DDP_COMPONENT_OD0]	= { MTK_DISP_OD,	0, &ddp_od },
-	[DDP_COMPONENT_OD1]	= { MTK_DISP_OD,	1, &ddp_od },
-	[DDP_COMPONENT_OVL0]	= { MTK_DISP_OVL,	0, &ddp_ovl },
-	[DDP_COMPONENT_OVL1]	= { MTK_DISP_OVL,	1, &ddp_ovl },
-	[DDP_COMPONENT_OVL_2L0]	= { MTK_DISP_OVL_2L,	0, &ddp_ovl },
-	[DDP_COMPONENT_OVL_2L1]	= { MTK_DISP_OVL_2L,	1, &ddp_ovl },
-	[DDP_COMPONENT_OVL_2L2] = { MTK_DISP_OVL_2L,    2, &ddp_ovl },
-	[DDP_COMPONENT_PWM0]	= { MTK_DISP_PWM,	0, NULL },
-	[DDP_COMPONENT_PWM1]	= { MTK_DISP_PWM,	1, NULL },
-	[DDP_COMPONENT_PWM2]	= { MTK_DISP_PWM,	2, NULL },
-	[DDP_COMPONENT_RDMA0]	= { MTK_DISP_RDMA,	0, &ddp_rdma },
-	[DDP_COMPONENT_RDMA1]	= { MTK_DISP_RDMA,	1, &ddp_rdma },
-	[DDP_COMPONENT_RDMA2]	= { MTK_DISP_RDMA,	2, &ddp_rdma },
-	[DDP_COMPONENT_UFOE]	= { MTK_DISP_UFOE,	0, &ddp_ufoe },
-	[DDP_COMPONENT_WDMA0]	= { MTK_DISP_WDMA,	0, NULL },
-	[DDP_COMPONENT_WDMA1]	= { MTK_DISP_WDMA,	1, NULL },
+	[DDP_COMPONENT_AAL0]		= { MTK_DISP_AAL,	0, &ddp_aal },
+	[DDP_COMPONENT_AAL1]		= { MTK_DISP_AAL,	1, &ddp_aal },
+	[DDP_COMPONENT_BLS]		= { MTK_DISP_BLS,	0, NULL },
+	[DDP_COMPONENT_CCORR]		= { MTK_DISP_CCORR,	0, &ddp_ccorr },
+	[DDP_COMPONENT_COLOR0]		= { MTK_DISP_COLOR,	0, &ddp_color },
+	[DDP_COMPONENT_COLOR1]		= { MTK_DISP_COLOR,	1, &ddp_color },
+	[DDP_COMPONENT_DITHER]		= { MTK_DISP_DITHER,	0, &ddp_dither },
+	[DDP_COMPONENT_DPI0]		= { MTK_DPI,		0, &ddp_dpi },
+	[DDP_COMPONENT_DPI1]		= { MTK_DPI,		1, &ddp_dpi },
+	[DDP_COMPONENT_DSI0]		= { MTK_DSI,		0, &ddp_dsi },
+	[DDP_COMPONENT_DSI1]		= { MTK_DSI,		1, &ddp_dsi },
+	[DDP_COMPONENT_DSI2]		= { MTK_DSI,		2, &ddp_dsi },
+	[DDP_COMPONENT_DSI3]		= { MTK_DSI,		3, &ddp_dsi },
+	[DDP_COMPONENT_GAMMA]		= { MTK_DISP_GAMMA,	0, &ddp_gamma },
+	[DDP_COMPONENT_OD0]		= { MTK_DISP_OD,	0, &ddp_od },
+	[DDP_COMPONENT_OD1]		= { MTK_DISP_OD,	1, &ddp_od },
+	[DDP_COMPONENT_OVL0]		= { MTK_DISP_OVL,	0, &ddp_ovl },
+	[DDP_COMPONENT_OVL1]		= { MTK_DISP_OVL,	1, &ddp_ovl },
+	[DDP_COMPONENT_OVL_2L0]		= { MTK_DISP_OVL_2L,	0, &ddp_ovl },
+	[DDP_COMPONENT_OVL_2L1]		= { MTK_DISP_OVL_2L,	1, &ddp_ovl },
+	[DDP_COMPONENT_OVL_2L2]		= { MTK_DISP_OVL_2L,    2, &ddp_ovl },
+	[DDP_COMPONENT_POSTMASK0]	= { MTK_DISP_POSTMASK,	0, &ddp_postmask },
+	[DDP_COMPONENT_PWM0]		= { MTK_DISP_PWM,	0, NULL },
+	[DDP_COMPONENT_PWM1]		= { MTK_DISP_PWM,	1, NULL },
+	[DDP_COMPONENT_PWM2]		= { MTK_DISP_PWM,	2, NULL },
+	[DDP_COMPONENT_RDMA0]		= { MTK_DISP_RDMA,	0, &ddp_rdma },
+	[DDP_COMPONENT_RDMA1]		= { MTK_DISP_RDMA,	1, &ddp_rdma },
+	[DDP_COMPONENT_RDMA2]		= { MTK_DISP_RDMA,	2, &ddp_rdma },
+	[DDP_COMPONENT_UFOE]		= { MTK_DISP_UFOE,	0, &ddp_ufoe },
+	[DDP_COMPONENT_WDMA0]		= { MTK_DISP_WDMA,	0, NULL },
+	[DDP_COMPONENT_WDMA1]		= { MTK_DISP_WDMA,	1, NULL },
 };
 
 static bool mtk_drm_find_comp_in_ddp(struct device *dev,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index bb914d9..cd1dec6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -30,6 +30,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_UFOE,
 	MTK_DSI,
 	MTK_DPI,
+	MTK_DISP_POSTMASK,
 	MTK_DISP_PWM,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Tue Aug 10 19:09:58 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Wed, 11 Aug 2021 10:09:58 +0800
Subject: [PATCH v9, 1/5] drm/mediatek: add component OVL_2L2
In-Reply-To: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1628647802-5127-2-git-send-email-yongqiang.niu@mediatek.com>

This patch add component OVL_2L2

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 75bc00e..b564513 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -385,6 +385,7 @@ struct mtk_ddp_comp_match {
 	[DDP_COMPONENT_OVL1]	= { MTK_DISP_OVL,	1, &ddp_ovl },
 	[DDP_COMPONENT_OVL_2L0]	= { MTK_DISP_OVL_2L,	0, &ddp_ovl },
 	[DDP_COMPONENT_OVL_2L1]	= { MTK_DISP_OVL_2L,	1, &ddp_ovl },
+	[DDP_COMPONENT_OVL_2L2] = { MTK_DISP_OVL_2L,    2, &ddp_ovl },
 	[DDP_COMPONENT_PWM0]	= { MTK_DISP_PWM,	0, NULL },
 	[DDP_COMPONENT_PWM1]	= { MTK_DISP_PWM,	1, NULL },
 	[DDP_COMPONENT_PWM2]	= { MTK_DISP_PWM,	2, NULL },
-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Tue Aug 10 19:10:02 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Wed, 11 Aug 2021 10:10:02 +0800
Subject: [PATCH v9, 5/5] drm/mediatek: add support for mediatek SOC MT8192
In-Reply-To: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1628647802-5127-6-git-send-email-yongqiang.niu@mediatek.com>

add support for mediatek SOC MT8192

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ccorr.c |  6 +++++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c   | 20 +++++++++++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c  |  6 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c    | 42 +++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
index 141cb36..3a53ebc 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
@@ -205,9 +205,15 @@ static int mtk_disp_ccorr_remove(struct platform_device *pdev)
 	.matrix_bits = 10,
 };
 
+static const struct mtk_disp_ccorr_data mt8192_ccorr_driver_data = {
+	.matrix_bits = 11,
+};
+
 static const struct of_device_id mtk_disp_ccorr_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt8183-disp-ccorr",
 	  .data = &mt8183_ccorr_driver_data},
+	{ .compatible = "mediatek,mt8192-disp-ccorr",
+	  .data = &mt8192_ccorr_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index fa9d799..ba4d157 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -454,6 +454,22 @@ static int mtk_disp_ovl_remove(struct platform_device *pdev)
 	.fmt_rgb565_is_0 = true,
 };
 
+static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
+	.addr = DISP_REG_OVL_ADDR_MT8173,
+	.gmc_bits = 10,
+	.layer_nr = 4,
+	.fmt_rgb565_is_0 = true,
+	.smi_id_en = true,
+};
+
+static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
+	.addr = DISP_REG_OVL_ADDR_MT8173,
+	.gmc_bits = 10,
+	.layer_nr = 2,
+	.fmt_rgb565_is_0 = true,
+	.smi_id_en = true,
+};
+
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt2701-disp-ovl",
 	  .data = &mt2701_ovl_driver_data},
@@ -463,6 +479,10 @@ static int mtk_disp_ovl_remove(struct platform_device *pdev)
 	  .data = &mt8183_ovl_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = &mt8183_ovl_2l_driver_data},
+	{ .compatible = "mediatek,mt8192-disp-ovl",
+	  .data = &mt8192_ovl_driver_data},
+	{ .compatible = "mediatek,mt8192-disp-ovl-2l",
+	  .data = &mt8192_ovl_2l_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 705f28c..a2386aa 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -353,6 +353,10 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
 	.fifo_size = 5 * SZ_1K,
 };
 
+static const struct mtk_disp_rdma_data mt8192_rdma_driver_data = {
+	.fifo_size = 5 * SZ_1K,
+};
+
 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt2701-disp-rdma",
 	  .data = &mt2701_rdma_driver_data},
@@ -360,6 +364,8 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
 	  .data = &mt8173_rdma_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = &mt8183_rdma_driver_data},
+	{ .compatible = "mediatek,mt8192-disp-rdma",
+	  .data = &mt8192_rdma_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b46bdb8..8465da1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -147,6 +147,25 @@
 	DDP_COMPONENT_DPI0,
 };
 
+static const enum mtk_ddp_comp_id mt8192_mtk_ddp_main[] = {
+	DDP_COMPONENT_OVL0,
+	DDP_COMPONENT_OVL_2L0,
+	DDP_COMPONENT_RDMA0,
+	DDP_COMPONENT_COLOR0,
+	DDP_COMPONENT_CCORR,
+	DDP_COMPONENT_AAL0,
+	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_POSTMASK0,
+	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DSI0,
+};
+
+static const enum mtk_ddp_comp_id mt8192_mtk_ddp_ext[] = {
+	DDP_COMPONENT_OVL_2L2,
+	DDP_COMPONENT_RDMA4,
+	DDP_COMPONENT_DPI0,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -186,6 +205,13 @@
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
 };
 
+static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
+	.main_path = mt8192_mtk_ddp_main,
+	.main_len = ARRAY_SIZE(mt8192_mtk_ddp_main),
+	.ext_path = mt8192_mtk_ddp_ext,
+	.ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
+};
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
@@ -404,22 +430,32 @@ static void mtk_drm_unbind(struct device *dev)
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
+	{ .compatible = "mediatek,mt8192-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8192-disp-ovl-2l",
+	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt2701-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8173-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8192-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8173-disp-wdma",
 	  .data = (void *)MTK_DISP_WDMA },
 	{ .compatible = "mediatek,mt8183-disp-ccorr",
 	  .data = (void *)MTK_DISP_CCORR },
+	{ .compatible = "mediatek,mt8192-disp-ccorr",
+	  .data = (void *)MTK_DISP_CCORR },
 	{ .compatible = "mediatek,mt2701-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8173-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8173-disp-aal",
 	  .data = (void *)MTK_DISP_AAL},
+	{ .compatible = "mediatek,mt8192-disp-aal",
+	  .data = (void *)MTK_DISP_AAL},
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
@@ -448,12 +484,16 @@ static void mtk_drm_unbind(struct device *dev)
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8192-disp-mutex",
+	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2701-disp-pwm",
 	  .data = (void *)MTK_DISP_BLS },
 	{ .compatible = "mediatek,mt8173-disp-pwm",
 	  .data = (void *)MTK_DISP_PWM },
 	{ .compatible = "mediatek,mt8173-disp-od",
 	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt8192-disp-postmask",
+	  .data = (void *)MTK_DISP_POSTMASK },
 	{ }
 };
 
@@ -468,6 +508,8 @@ static void mtk_drm_unbind(struct device *dev)
 	  .data = &mt8173_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8183-mmsys",
 	  .data = &mt8183_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8192-mmsys",
+	  .data = &mt8192_mmsys_driver_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
1.8.1.1.dirty

From yongqiang.niu at mediatek.com  Tue Aug 10 19:10:00 2021
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Wed, 11 Aug 2021 10:10:00 +0800
Subject: [PATCH v9, 3/5] drm/mediatek: add component RDMA4
In-Reply-To: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1628647802-5127-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <1628647802-5127-4-git-send-email-yongqiang.niu@mediatek.com>

This patch add component RDMA4

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 17309ce..ebe8eec 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -434,6 +434,7 @@ struct mtk_ddp_comp_match {
 	[DDP_COMPONENT_RDMA0]		= { MTK_DISP_RDMA,	0, &ddp_rdma },
 	[DDP_COMPONENT_RDMA1]		= { MTK_DISP_RDMA,	1, &ddp_rdma },
 	[DDP_COMPONENT_RDMA2]		= { MTK_DISP_RDMA,	2, &ddp_rdma },
+	[DDP_COMPONENT_RDMA4]		= { MTK_DISP_RDMA,      4, &ddp_rdma },
 	[DDP_COMPONENT_UFOE]		= { MTK_DISP_UFOE,	0, &ddp_ufoe },
 	[DDP_COMPONENT_WDMA0]		= { MTK_DISP_WDMA,	0, NULL },
 	[DDP_COMPONENT_WDMA1]		= { MTK_DISP_WDMA,	1, NULL },
-- 
1.8.1.1.dirty

From thunder.leizhen at huawei.com  Tue Aug 10 19:16:39 2021
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Wed, 11 Aug 2021 10:16:39 +0800
Subject: [PATCH RFC 2/8] iommu/arm-smmu-v3: Add and use static helper
 function arm_smmu_cmdq_issue_cmd_with_sync()
In-Reply-To: <20210810182454.GB3296@willie-the-truck>
References: <20210626110130.2416-1-thunder.leizhen@huawei.com>
 <20210626110130.2416-3-thunder.leizhen@huawei.com>
 <20210810182454.GB3296@willie-the-truck>
Message-ID: <b9fa05b5-d3ee-5c79-c8b8-b908e533646a@huawei.com>



On 2021/8/11 2:24, Will Deacon wrote:
> On Sat, Jun 26, 2021 at 07:01:24PM +0800, Zhen Lei wrote:
>> The obvious key to the performance optimization of commit 587e6c10a7ce
>> ("iommu/arm-smmu-v3: Reduce contention during command-queue insertion") is
>> to allow multiple cores to insert commands in parallel after a brief mutex
>> contention.
>>
>> Obviously, inserting as many commands at a time as possible can reduce the
>> number of times the mutex contention participates, thereby improving the
>> overall performance. At least it reduces the number of calls to function
>> arm_smmu_cmdq_issue_cmdlist().
>>
>> Therefore, function arm_smmu_cmdq_issue_cmd_with_sync() is added to insert
>> the 'cmd+sync' commands at a time.
>>
>> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
>> ---
>>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 33 +++++++++++++--------
>>  1 file changed, 21 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index 2433d3c29b49ff2..a5361153ca1d6a4 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -858,11 +858,25 @@ static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
>>  	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
>>  }
>>  
>> -static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
>> +static int __maybe_unused arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
>>  {
>>  	return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
>>  }
>>  
>> +static int arm_smmu_cmdq_issue_cmd_with_sync(struct arm_smmu_device *smmu,
>> +					     struct arm_smmu_cmdq_ent *ent)
>> +{
>> +	u64 cmd[CMDQ_ENT_DWORDS];
>> +
>> +	if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
>> +		dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
>> +			 ent->opcode);
>> +		return -EINVAL;
>> +	}
>> +
>> +	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, true);
>> +}
> 
> This function is almost identical to arm_smmu_cmdq_issue_cmd(). How about
> moving the guts out into a helper:
> 
> 	static int __arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
> 					     struct arm_smmu_cmdq_ent *ent,
> 					     bool sync);
> 
> and then having arm_smmu_cmdq_issue_cmd_with_sync() and
> arm_smmu_cmdq_issue_cmd() wrap that?

OK, I will do it.

How about remove arm_smmu_cmdq_issue_sync()? It's unused now.

> 
> Will
> .
> 


From sudeep.holla at arm.com  Tue Aug 10 19:40:01 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 11 Aug 2021 03:40:01 +0100
Subject: [PATCH 8/8] cpufreq: vexpress: Use auto-registration for energy
 model
In-Reply-To: <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <87fecd84e3f6ff6f153be14b0d53de93c0b04ae6.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <20210811024001.arrak7lk7eyuwcld@bogus>

On Tue, Aug 10, 2021 at 01:06:55PM +0530, Viresh Kumar wrote:
> Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
> automatically register with the energy model.
> 
> This allows removal of boiler plate code from the driver and fixes the
> unregistration part as well.
> 

Acked-by: Sudeep Holla <sudeep.holla at arm.com>

-- 
Regards,
Sudeep


From sudeep.holla at arm.com  Tue Aug 10 19:40:47 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 11 Aug 2021 03:40:47 +0100
Subject: [PATCH 7/8] cpufreq: scpi: Use auto-registration for energy model
In-Reply-To: <7809d747fecbaad46699a178f26288a015055b20.1628579170.git.viresh.kumar@linaro.org>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <7809d747fecbaad46699a178f26288a015055b20.1628579170.git.viresh.kumar@linaro.org>
Message-ID: <20210811024047.4vq2da52dpegaho5@bogus>

On Tue, Aug 10, 2021 at 01:06:54PM +0530, Viresh Kumar wrote:
> Use the CPUFREQ_REGISTER_WITH_EM flag to allow cpufreq core to
> automatically register with the energy model.
> 
> This allows removal of boiler plate code from the driver and fixes the
> unregistration part as well.
> 

Acked-by: Sudeep Holla <sudeep.holla at arm.com>

-- 
Regards,
Sudeep


From yunfei.dong at mediatek.com  Tue Aug 10 19:58:00 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:58:00 +0800
Subject: [PATCH v5, 14/15] media: mtk-vcodec: Add core dec and dec end ipi msg
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-15-yunfei.dong@mediatek.com>

Add core dec and dec end ipi msg: AP_IPIMSG_DEC_CORE/AP_IPIMSG_DEC_CORE_END.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h   |  4 ++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c    | 12 ++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h    | 18 ++++++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 5f45a537beb4..9d8079c4f976 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -18,12 +18,16 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_END = 0xA002,
 	AP_IPIMSG_DEC_DEINIT = 0xA003,
 	AP_IPIMSG_DEC_RESET = 0xA004,
+	AP_IPIMSG_DEC_CORE = 0xA005,
+	AP_IPIMSG_DEC_CORE_END = 0xA006,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
 	VPU_IPIMSG_DEC_END_ACK = 0xB002,
 	VPU_IPIMSG_DEC_DEINIT_ACK = 0xB003,
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
+	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
+	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 5dffc459a33d..bfd8e87dceff 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -85,6 +85,8 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_END_ACK:
 		case VPU_IPIMSG_DEC_DEINIT_ACK:
 		case VPU_IPIMSG_DEC_RESET_ACK:
+		case VPU_IPIMSG_DEC_CORE_ACK:
+		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
 		default:
@@ -191,11 +193,21 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_core(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
+}
+
 int vpu_dec_end(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_END);
 }
 
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE_END);
+}
+
 int vpu_dec_deinit(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_DEINIT);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index c2ed5b6cab8b..ae24b75d1649 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -82,4 +82,22 @@ int vpu_dec_deinit(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_reset(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_core - core start decoding, basically the function will be invoked once
+ *                 every frame.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core(struct vdec_vpu_inst *vpu);
+
+/**
+ * vpu_dec_core_end - core end decoding, basically the function will be invoked once
+ *               when core HW decoding done and receive interrupt successfully. The
+ *               decoder in VPU will updata hardware information and deinit hardware
+ *               and check if there is a new decoded frame available to display.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
+
 #endif
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:50 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:50 +0800
Subject: [PATCH v5,
 04/15] media: mtk-vcodec: Use component framework to manage each
 hardware information
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-5-yunfei.dong@mediatek.com>

Uses component framework to manage each hardware information which
includes irq/power/clk. The hardware includes LAT0, LAT1 and CORE.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: Fix platform_set_drvdata in error place.
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 194 +++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 184 +++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  49 +++++
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  19 ++
 8 files changed, 416 insertions(+), 34 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index ca8e9e7a9c4e..edeb3b66e9e9 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -15,6 +15,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_stateless.o \
 		mtk_vcodec_dec_pm.o \
+		mtk_vcodec_dec_hw.o \
 
 mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		venc/venc_h264_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 9fbd24186c1a..c509224cbff4 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -66,6 +66,7 @@ extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops;
 extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
 extern const struct media_device_ops mtk_vcodec_media_ops;
 
+extern struct platform_driver mtk_vdec_comp_driver;
 
 /*
  * mtk_vdec_lock/mtk_vdec_unlock are for ctx instance to
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index dd749d41c75a..4c6f4d7612fa 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -5,6 +5,7 @@
  *         Tiffany Lin <tiffany.lin at mediatek.com>
  */
 
+#include <linux/component.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -18,19 +19,90 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
 #include "mtk_vcodec_fw.h"
 
-#define VDEC_HW_ACTIVE	0x10
-#define VDEC_IRQ_CFG	0x11
-#define VDEC_IRQ_CLR	0x10
-#define VDEC_IRQ_CFG_REG	0xa4
-
 module_param(mtk_v4l2_dbg_level, int, 0644);
 module_param(mtk_vcodec_dbg, bool, 0644);
 
+static struct of_device_id mtk_vdec_drv_ids[] = {
+	{
+		.compatible = "mediatek,mtk-vcodec-lat",
+		.data = (void *)MTK_VDEC_LAT0,
+	},
+	{
+		.compatible = "mediatek,mtk-vcodec-core",
+		.data = (void *)MTK_VDEC_CORE,
+	},
+	{},
+};
+
+static inline int mtk_vdec_compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static inline void mtk_vdec_release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
+static inline int mtk_vdec_bind(struct device *dev)
+{
+	struct mtk_vcodec_dev *data = dev_get_drvdata(dev);
+
+	return component_bind_all(dev, data);
+}
+
+static inline void mtk_vdec_unbind(struct device *dev)
+{
+	struct mtk_vcodec_dev *data = dev_get_drvdata(dev);
+
+	component_unbind_all(dev, data);
+}
+
+static const struct component_master_ops mtk_vdec_ops = {
+   .bind = mtk_vdec_bind,
+   .unbind = mtk_vdec_unbind,
+};
+
+static struct component_match *mtk_vcodec_match_add(
+	struct mtk_vcodec_dev *vdec_dev)
+ {
+	struct platform_device *pdev = vdec_dev->plat_dev;
+	struct component_match *match = NULL;
+	struct device_node *comp_node;
+	enum mtk_vdec_hw_id comp_idx;
+	const struct of_device_id *of_id;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_vdec_drv_ids); i++) {
+		of_id = &mtk_vdec_drv_ids[i];
+		comp_node = of_find_compatible_node(NULL, NULL,
+			of_id->compatible);
+		if (!comp_node)
+			continue;
+
+		if (!of_device_is_available(comp_node)) {
+			of_node_put(comp_node);
+			dev_err(&pdev->dev, "Fail to get MMSYS node\n");
+			continue;
+		}
+
+		comp_idx = (enum mtk_vdec_hw_id)of_id->data;
+		mtk_v4l2_debug(4, "Get component:hw_id(%d),vdec_dev(0x%p),comp_node(0x%p)\n",
+			comp_idx, vdec_dev, comp_node);
+		vdec_dev->component_node[comp_idx] = comp_node;
+
+		component_match_add_release(&pdev->dev, &match, mtk_vdec_release_of,
+			mtk_vdec_compare_of, comp_node);
+	}
+
+	return match;
+}
+
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -95,6 +167,58 @@ static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
 	return 0;
 }
 
+static int mtk_vcodec_init_master(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	struct component_match *match;
+	int ret;
+
+	match = mtk_vcodec_match_add(dev);
+	if (IS_ERR_OR_NULL(match))
+		return -EINVAL;
+
+	ret = component_master_add_with_match(&pdev->dev, &mtk_vdec_ops, match);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int mtk_vcodec_init_dec_params(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		return ret;
+
+	if (!dev->vdec_pdata->is_comp_supported) {
+		dev->dec_irq = platform_get_irq(pdev, 0);
+		if (dev->dec_irq < 0) {
+			dev_err(&pdev->dev, "failed to get irq number");
+			return dev->dec_irq;
+		}
+
+		irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+		ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)",
+				dev->dec_irq, ret);
+			return ret;
+		}
+
+		ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "failed to get mt vcodec clock source");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -220,7 +344,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 {
 	struct mtk_vcodec_dev *dev;
 	struct video_device *vfd_dec;
-	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
 	int ret;
@@ -249,32 +372,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
-		goto err_dec_pm;
-	}
-
-	ret = mtk_vcodec_get_reg_bases(dev);
-	if (ret)
-		goto err_res;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
-		goto err_res;
-	}
-
-	dev->dec_irq = platform_get_irq(pdev, 0);
-	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
-			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+	ret = mtk_vcodec_init_dec_params(dev);
 	if (ret) {
-		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
-			dev->dec_irq,
-			ret);
-		goto err_res;
+		dev_err(&pdev->dev, "Failed to init pm and registers");
+		goto err_dec_pm;
 	}
 
 	mutex_init(&dev->dec_mutex);
@@ -362,8 +463,14 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	mtk_v4l2_debug(0, "decoder registered as /dev/video%d",
 		vfd_dec->num);
 
-	return 0;
+	if (dev->vdec_pdata->is_comp_supported) {
+		ret = mtk_vcodec_init_master(dev);
+		if (ret < 0)
+			goto err_component_match;
+	}
 
+	return 0;
+err_component_match:
 err_dec_reg:
 	if (dev->vdec_pdata->uses_stateless_api)
 		media_device_unregister(&dev->mdev_dec);
@@ -382,6 +489,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
+
 	return ret;
 }
 
@@ -436,7 +544,25 @@ static struct platform_driver mtk_vcodec_dec_driver = {
 	},
 };
 
-module_platform_driver(mtk_vcodec_dec_driver);
+static struct platform_driver * const mtk_vdec_drivers[] = {
+	&mtk_vdec_comp_driver,
+	&mtk_vcodec_dec_driver,
+};
+
+static int __init mtk_vdec_init(void)
+{
+	return platform_register_drivers(mtk_vdec_drivers,
+					 ARRAY_SIZE(mtk_vdec_drivers));
+}
+
+static void __exit mtk_vdec_exit(void)
+{
+	platform_unregister_drivers(mtk_vdec_drivers,
+				    ARRAY_SIZE(mtk_vdec_drivers));
+}
+
+module_init(mtk_vdec_init);
+module_exit(mtk_vdec_exit);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
new file mode 100644
index 000000000000..5e1b7670ba5b
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/component.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_intr.h"
+#include "mtk_vcodec_util.h"
+
+static int mtk_vdec_comp_bind(struct device *dev, struct device *master,
+	void *data)
+{
+	struct mtk_vdec_comp_dev *comp_dev = dev_get_drvdata(dev);
+	struct mtk_vcodec_dev *master_dev = data;
+	int i;
+
+	for (i = 0; i < MTK_VDEC_HW_MAX; i++) {
+		if (dev->of_node != master_dev->component_node[i])
+			continue;
+
+		master_dev->comp_dev[i] = comp_dev;
+		comp_dev->comp_idx = i;
+		comp_dev->master_dev = master_dev;
+		break;
+	}
+
+	if (i == MTK_VDEC_HW_MAX) {
+		dev_err(dev, "Failed to get component node\n");
+		return -EINVAL;
+	}
+
+	comp_dev->reg_base[VDEC_COMP_SYS] =
+		master_dev->reg_base[VDEC_COMP_SYS];
+	return 0;
+}
+
+static void mtk_vdec_comp_unbind(struct device *dev, struct device *master,
+	void *data)
+{
+	struct mtk_vdec_comp_dev *comp_dev = dev_get_drvdata(dev);
+
+	comp_dev->reg_base[VDEC_COMP_SYS] = NULL;
+}
+
+static const struct component_ops mtk_vdec_hw_component_ops = {
+	.bind = mtk_vdec_comp_bind,
+	.unbind = mtk_vdec_comp_unbind,
+};
+
+static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
+{
+	struct mtk_vdec_comp_dev *dev = priv;
+	struct mtk_vcodec_ctx *ctx;
+	u32 cg_status;
+	unsigned int dec_done_status;
+	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
+					VDEC_IRQ_CFG_REG;
+
+	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
+
+	/* check if HW active or not */
+	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
+	if ((cg_status & VDEC_HW_ACTIVE) != 0) {
+		mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",
+			cg_status);
+		return IRQ_HANDLED;
+	}
+
+	dec_done_status = readl(vdec_misc_addr);
+	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
+		MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
+		return IRQ_HANDLED;
+
+	/* clear interrupt */
+	writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
+	writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
+
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+
+	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
+		ctx->id, dec_done_status);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_vdec_comp_init_irq(struct mtk_vdec_comp_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	dev->dec_irq = platform_get_irq(pdev, 0);
+	if (dev->dec_irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource");
+		return dev->dec_irq;
+	}
+
+	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+				mtk_vdec_comp_irq_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
+			dev->dec_irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mtk_vdec_comp_probe(struct platform_device *pdev)
+{
+	struct mtk_vdec_comp_dev *dev;
+	int ret;
+
+	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->plat_dev = pdev;
+	ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
+		return ret;
+	}
+
+	dev->reg_base[VDEC_COMP_MISC] =
+		devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR((__force void *)dev->reg_base[VDEC_COMP_MISC])) {
+		ret = PTR_ERR((__force void *)dev->reg_base[VDEC_COMP_MISC]);
+		goto err;
+	}
+
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+
+	ret = mtk_vdec_comp_init_irq(dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register irq handler.\n");
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, dev);
+
+	ret = component_add(&pdev->dev, &mtk_vdec_hw_component_ops);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add component: %d\n", ret);
+		goto err;
+	}
+
+	return 0;
+err:
+	mtk_vcodec_release_dec_pm(&dev->pm);
+	return ret;
+}
+
+static const struct of_device_id mtk_vdec_comp_ids[] = {
+	{
+		.compatible = "mediatek,mtk-vcodec-lat",
+	},
+	{
+		.compatible = "mediatek,mtk-vcodec-core",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_vdec_comp_ids);
+
+struct platform_driver mtk_vdec_comp_driver = {
+	.probe	= mtk_vdec_comp_probe,
+	.driver	= {
+		.name	= "mtk-vdec-comp",
+		.of_match_table = mtk_vdec_comp_ids,
+	},
+};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
new file mode 100644
index 000000000000..8d6e818a3474
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _MTK_VCODEC_DEC_HW_H_
+#define _MTK_VCODEC_DEC_HW_H_
+
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "mtk_vcodec_drv.h"
+
+#define VDEC_HW_ACTIVE	0x10
+#define VDEC_IRQ_CFG	0x11
+#define VDEC_IRQ_CLR	0x10
+#define VDEC_IRQ_CFG_REG	0xa4
+
+/**
+ * enum mtk_comp_hw_reg_idx - component register base index
+ */
+enum mtk_comp_hw_reg_idx {
+	VDEC_COMP_SYS,
+	VDEC_COMP_MISC,
+	VDEC_COMP_MAX
+};
+
+/**
+ * struct mtk_vdec_comp_dev - component framwork driver data
+ * @plat_dev: platform device
+ * @master_dev: master device
+ * @reg_base: Mapped address of MTK Vcodec registers.
+ *
+ * @dec_irq: decoder irq resource
+ * @pm: power management control
+ * @comp_idx: component index
+ */
+struct mtk_vdec_comp_dev {
+	struct platform_device *plat_dev;
+	struct mtk_vcodec_dev *master_dev;
+	void __iomem *reg_base[VDEC_COMP_MAX];
+
+	int dec_irq;
+	struct mtk_vcodec_pm pm;
+	int comp_idx;
+};
+
+#endif /* _MTK_VCODEC_DEC_HW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 59c24b22ab6d..4f9a80ce15d8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -623,4 +623,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_comp_supported = false,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 8f4a1f0a0769..762633572b49 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -357,4 +357,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_comp_supported = false,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 973b0b3649c6..e530757a9b5a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -93,6 +93,17 @@ enum mtk_fmt_type {
 	MTK_FMT_FRAME = 2,
 };
 
+/**
+ * struct mtk_vdec_hw_id - Hardware index used to separate
+ *                         different hardware
+ */
+enum mtk_vdec_hw_id {
+	MTK_VDEC_CORE,
+	MTK_VDEC_LAT0,
+	MTK_VDEC_LAT1,
+	MTK_VDEC_HW_MAX,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -331,6 +342,7 @@ enum mtk_chip {
  *
  * @chip: chip this decoder is compatible with
  *
+ * @is_comp_supported: true: using compoent framework, false: not support
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
  */
 
@@ -352,6 +364,7 @@ struct mtk_vcodec_dec_pdata {
 
 	enum mtk_chip chip;
 
+	bool is_comp_supported;
 	bool uses_stateless_api;
 };
 
@@ -422,6 +435,9 @@ struct mtk_vcodec_enc_pdata {
  * @pm: power management control
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
+ *
+ * @comp_dev: component hardware device
+ * @component_node: component node
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -459,6 +475,9 @@ struct mtk_vcodec_dev {
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
 	unsigned int enc_capability;
+
+	void *comp_dev[MTK_VDEC_HW_MAX];
+	struct device_node *component_node[MTK_VDEC_HW_MAX];
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:57 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:57 +0800
Subject: [PATCH v5, 11/15] media: mtk-vcodec: Add core thread
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-12-yunfei.dong@mediatek.com>

Core thread:
1. Gets lat_buf from core msg queue.
2. Proceeds core decode.
3. Puts the lat_buf back to lat msg queue.

Both H264 and VP9 rely on the core thread.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 12 +++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  7 ++++
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 32 +++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      |  6 ++++
 4 files changed, 57 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index e448cb238c7f..002352fcf8de 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -405,6 +405,18 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
+	if (VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
+		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx,
+			MTK_VDEC_CORE);
+		dev->kthread_core = kthread_run(vdec_msg_queue_core_thead, dev,
+			"mtk-%s", "core");
+		if (IS_ERR(dev->kthread_core)) {
+			dev_err(&pdev->dev, "Failed to create core thread");
+			ret = PTR_ERR(dev->kthread_core);
+			goto err_res;
+		}
+	}
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index f1e63acaec76..b6f030a6e55f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -27,6 +27,7 @@
 #define MTK_VCODEC_MAX_PLANES	3
 #define MTK_V4L2_BENCHMARK	0
 #define WAIT_INTR_TIMEOUT_MS	1000
+#define VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
 
 /*
  * enum mtk_hw_reg_idx - MTK hw register base index
@@ -465,6 +466,9 @@ struct mtk_vcodec_enc_pdata {
  *
  * @comp_dev: component hardware device
  * @component_node: component node
+ *
+ * @kthread_core: thread used for core hardware decode
+ * @msg_queue_core_ctx: msg queue context used for core thread
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -505,6 +509,9 @@ struct mtk_vcodec_dev {
 
 	void *comp_dev[MTK_VDEC_HW_MAX];
 	struct device_node *component_node[MTK_VDEC_HW_MAX];
+
+	struct task_struct *kthread_core;
+	struct vdec_msg_queue_ctx msg_queue_core_ctx;
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index d66ed98c79a9..665f571eab4b 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -256,3 +256,35 @@ void vdec_msg_queue_deinit(
 			kfree(lat_buf->private_data);
 	}
 }
+
+int vdec_msg_queue_core_thead(void *data)
+{
+	struct mtk_vcodec_dev *dev = data;
+	struct vdec_lat_buf *lat_buf;
+	struct mtk_vcodec_ctx *ctx;
+
+	set_freezable();
+	for (;;) {
+		try_to_freeze();
+		if (kthread_should_stop())
+			break;
+
+		lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
+		if (!lat_buf)
+			continue;
+
+		ctx = lat_buf->ctx;
+		mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
+
+		if (!lat_buf->core_decode)
+			mtk_v4l2_err("Core decode callback func is NULL");
+		else
+			lat_buf->core_decode(lat_buf);
+
+		mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+		vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
+	}
+
+	mtk_v4l2_debug(3, "Video Capture Thread End");
+	return 0;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
index 1905ce713592..b5745b144140 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -148,4 +148,10 @@ void vdec_msg_queue_deinit(
 	struct vdec_msg_queue *msg_queue,
 	struct mtk_vcodec_ctx *ctx);
 
+/**
+ * vdec_msg_queue_core_thead - used for core decoder.
+ * @data: private data used for each codec
+ */
+int vdec_msg_queue_core_thead(void *data);
+
 #endif
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:51 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:51 +0800
Subject: [PATCH v5,
 05/15] dt-bindings: media: mtk-vcodec: Separate video encoder and
 decoder dt-bindings
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-6-yunfei.dong@mediatek.com>

Decoder will use component framework to manage hardware, it is big
difference with encoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 .../media/mediatek,vcodec-decoder.yaml        | 175 +++++++++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 185 ++++++++++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 130 ------------
 3 files changed, 360 insertions(+), 130 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
new file mode 100644
index 000000000000..b6b97110024d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -0,0 +1,175 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-dec
+      - mediatek,mt8183-vcodec-dec
+
+  reg:
+    maxItems: 12
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 8
+
+  clock-names:
+    items:
+      - const: vcodecpll
+      - const: univpll_d2
+      - const: clk_cci400_sel
+      - const: vdec_sel
+      - const: vdecpll
+      - const: vencpll
+      - const: venc_lt_sel
+      - const: vdec_bus_clk_src
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  assigned-clock-rates: true
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-dec
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-dec
+
+    then:
+      required:
+        - mediatek,vpu
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt8173-power.h>
+
+    vcodec_dec: vcodec at 16000000 {
+      compatible = "mediatek,mt8173-vcodec-dec";
+      reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
+          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
+          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
+          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
+          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
+          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
+          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
+          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
+          <0 0x16026800 0 0x800>,   /*VP8_VD*/
+          <0 0x16027000 0 0x800>,   /*VP6_VD*/
+          <0 0x16027800 0 0x800>,   /*VP8_VL*/
+          <0 0x16028400 0 0x400>;   /*VP9_VD*/
+      interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
+      mediatek,larb = <&larb1>;
+      iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
+      mediatek,vpu = <&vpu>;
+      power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+      clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
+             <&topckgen CLK_TOP_UNIVPLL_D2>,
+             <&topckgen CLK_TOP_CCI400_SEL>,
+             <&topckgen CLK_TOP_VDEC_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL>,
+             <&apmixedsys CLK_APMIXED_VENCPLL>,
+             <&topckgen CLK_TOP_VENC_LT_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL_370P5>;
+      clock-names = "vcodecpll",
+                  "univpll_d2",
+                  "clk_cci400_sel",
+                  "vdec_sel",
+                  "vdecpll",
+                  "vencpll",
+                  "venc_lt_sel",
+                  "vdec_bus_clk_src";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
+                      <&topckgen CLK_TOP_CCI400_SEL>,
+                      <&topckgen CLK_TOP_VDEC_SEL>,
+                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
+                      <&apmixedsys CLK_APMIXED_VENCPLL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
+                             <&topckgen CLK_TOP_UNIVPLL_D2>,
+                             <&topckgen CLK_TOP_VCODECPLL>;
+      assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
new file mode 100644
index 000000000000..6f28394e8ce3
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -0,0 +1,185 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Encode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Encode is the video encode hardware present in Mediatek
+  SoCs which supports high resolution encoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-enc-vp8
+      - mediatek,mt8173-vcodec-enc
+      - mediatek,mt8183-vcodec-enc
+      - mediatek,mt8192-vcodec-enc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-enc
+              - mediatek,mt8192-vcodec-enc
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-enc-vp8
+              - mediatek,mt8173-vcodec-enc
+
+    then:
+      required:
+        - mediatek,vpu
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - mediatek,mt8173-vcodec-enc
+            - mediatek,mt8192-vcodec-enc
+            - mediatek,mt8173-vcodec-enc
+
+    then:
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_sel
+    else:  # for vp8 hw decoder
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_lt_sel
+ 
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    vcodec_enc_avc: vcodec at 18002000 {
+      compatible = "mediatek,mt8173-vcodec-enc";
+      reg = <0 0x18002000 0 0x1000>;
+      interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU>,
+             <&iommu M4U_PORT_VENC_REC>,
+             <&iommu M4U_PORT_VENC_BSDMA>,
+             <&iommu M4U_PORT_VENC_SV_COMV>,
+             <&iommu M4U_PORT_VENC_RD_COMV>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
+             <&iommu M4U_PORT_VENC_REF_LUMA>,
+             <&iommu M4U_PORT_VENC_REF_CHROMA>,
+             <&iommu M4U_PORT_VENC_NBM_RDMA>,
+             <&iommu M4U_PORT_VENC_NBM_WDMA>;
+      mediatek,larb = <&larb3>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      clock-names = "venc_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
+    };
+
+    vcodec_enc_vp8: vcodec at 19002000 {
+      compatible = "mediatek,mt8173-vcodec-enc-vp8";
+      reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
+      interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
+             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
+             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
+             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
+             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
+      mediatek,larb = <&larb5>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      clock-names = "venc_lt_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
deleted file mode 100644
index c44a6e6943af..000000000000
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ /dev/null
@@ -1,130 +0,0 @@
-Mediatek Video Codec
-
-Mediatek Video Codec is the video codec hw present in Mediatek SoCs which
-supports high resolution encoding and decoding functionalities.
-
-Required properties:
-- compatible : must be one of the following string:
-  "mediatek,mt8173-vcodec-enc-vp8" for mt8173 vp8 encoder.
-  "mediatek,mt8173-vcodec-enc" for mt8173 avc encoder.
-  "mediatek,mt8183-vcodec-enc" for MT8183 encoder.
-  "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
-  "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
-  "mediatek,mt8183-vcodec-dec" for MT8183 decoder.
-- reg : Physical base address of the video codec registers and length of
-  memory mapped region.
-- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
-- clocks : list of clock specifiers, corresponding to entries in
-  the clock-names property.
-- clock-names: avc encoder must contain "venc_sel", vp8 encoder must
-  contain "venc_lt_sel", decoder must contain "vcodecpll", "univpll_d2",
-  "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", "venc_lt_sel",
-  "vdec_bus_clk_src".
-- iommus : should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-- dma-ranges : describes the dma address range space that the codec hw access.
-One of the two following nodes:
-- mediatek,vpu : the node of the video processor unit, if using VPU.
-- mediatek,scp : the node of the SCP unit, if using SCP.
-
-
-Example:
-
-vcodec_dec: vcodec at 16000000 {
-    compatible = "mediatek,mt8173-vcodec-dec";
-    reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
-          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
-          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
-          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
-          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
-          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
-          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
-          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
-          <0 0x16026800 0 0x800>,   /*VP8_VD*/
-          <0 0x16027000 0 0x800>,   /*VP6_VD*/
-          <0 0x16027800 0 0x800>,   /*VP8_VL*/
-          <0 0x16028400 0 0x400>;   /*VP9_VD*/
-    interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
-    mediatek,larb = <&larb1>;
-    iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
-    mediatek,vpu = <&vpu>;
-    power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
-    clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
-             <&topckgen CLK_TOP_UNIVPLL_D2>,
-             <&topckgen CLK_TOP_CCI400_SEL>,
-             <&topckgen CLK_TOP_VDEC_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL>,
-             <&apmixedsys CLK_APMIXED_VENCPLL>,
-             <&topckgen CLK_TOP_VENC_LT_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL_370P5>;
-    clock-names = "vcodecpll",
-                  "univpll_d2",
-                  "clk_cci400_sel",
-                  "vdec_sel",
-                  "vdecpll",
-                  "vencpll",
-                  "venc_lt_sel",
-                  "vdec_bus_clk_src";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
-                      <&topckgen CLK_TOP_CCI400_SEL>,
-                      <&topckgen CLK_TOP_VDEC_SEL>,
-                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
-                      <&apmixedsys CLK_APMIXED_VENCPLL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
-                             <&topckgen CLK_TOP_UNIVPLL_D2>,
-                             <&topckgen CLK_TOP_VCODECPLL>;
-    assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
-  };
-
-vcodec_enc_avc: vcodec at 18002000 {
-    compatible = "mediatek,mt8173-vcodec-enc";
-    reg = <0 0x18002000 0 0x1000>;
-    interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU>,
-             <&iommu M4U_PORT_VENC_REC>,
-             <&iommu M4U_PORT_VENC_BSDMA>,
-             <&iommu M4U_PORT_VENC_SV_COMV>,
-             <&iommu M4U_PORT_VENC_RD_COMV>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
-             <&iommu M4U_PORT_VENC_REF_LUMA>,
-             <&iommu M4U_PORT_VENC_REF_CHROMA>,
-             <&iommu M4U_PORT_VENC_NBM_RDMA>,
-             <&iommu M4U_PORT_VENC_NBM_WDMA>;
-    mediatek,larb = <&larb3>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    clock-names = "venc_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
-  };
-
-vcodec_enc_vp8: vcodec at 19002000 {
-    compatible = "mediatek,mt8173-vcodec-enc-vp8";
-    reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
-    interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
-             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
-             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
-             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
-             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
-    mediatek,larb = <&larb5>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    clock-names = "venc_lt_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
-  };
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:52 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:52 +0800
Subject: [PATCH v5, 06/15] media: mtk-vcodec: Use pure single core for MT8183
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-7-yunfei.dong@mediatek.com>

Separates different architecture for hardware: pure_sin_core
and lat_sin_core. MT8183 is pure single core. Uses .hw_arch to
distinguish.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c      |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c     |  1 +
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 10 ++++++++++
 3 files changed, 12 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 4f9a80ce15d8..138f6fcb36bb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -624,4 +624,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_comp_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 762633572b49..12c243d6dff3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -358,4 +358,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_comp_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index e530757a9b5a..1d0798fd9adf 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -323,6 +323,14 @@ enum mtk_chip {
 	MTK_MT8192,
 };
 
+/**
+ * struct mtk_vdec_hw_arch - Used to separate different hardware architecture
+ */
+enum mtk_vdec_hw_arch {
+	MTK_VDEC_PURE_SINGLE_CORE,
+	MTK_VDEC_LAT_SINGLE_CORE,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -341,6 +349,7 @@ enum mtk_chip {
  * @num_framesizes: count of video decoder frame sizes
  *
  * @chip: chip this decoder is compatible with
+ * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_comp_supported: true: using compoent framework, false: not support
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
@@ -363,6 +372,7 @@ struct mtk_vcodec_dec_pdata {
 	const int num_framesizes;
 
 	enum mtk_chip chip;
+	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_comp_supported;
 	bool uses_stateless_api;
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:53 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:53 +0800
Subject: [PATCH v5,
 07/15] media: mtk-vcodec: Add irq interface for multi hardware
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-8-yunfei.dong@mediatek.com>

Adds irq interface for multi hardware.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 33 +++++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 25 ++++++++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  4 +--
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     | 27 +++++++--------
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |  4 +--
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |  2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |  2 +-
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |  2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  2 +-
 12 files changed, 71 insertions(+), 36 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 4c6f4d7612fa..f096ad1c01ac 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -68,6 +68,20 @@ static const struct component_master_ops mtk_vdec_ops = {
    .unbind = mtk_vdec_unbind,
 };
 
+static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev)
+{
+	switch (dev->vdec_pdata->hw_arch) {
+	case MTK_VDEC_PURE_SINGLE_CORE:
+		return MTK_VDEC_ONE_CORE;
+	case MTK_VDEC_LAT_SINGLE_CORE:
+		return MTK_VDEC_ONE_LAT_ONE_CORE;
+	default:
+		mtk_v4l2_err("not support hw arch:%d",
+			dev->vdec_pdata->hw_arch);
+		return MTK_VDEC_NO_HW;
+	}
+}
+
 static struct component_match *mtk_vcodec_match_add(
 	struct mtk_vcodec_dev *vdec_dev)
  {
@@ -134,7 +148,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
 		dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
@@ -223,7 +237,7 @@ static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
 	struct mtk_vcodec_ctx *ctx = NULL;
-	int ret = 0;
+	int ret = 0, i, hw_count;
 	struct vb2_queue *src_vq;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -237,7 +251,19 @@ static int fops_vcodec_open(struct file *file)
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
-	init_waitqueue_head(&ctx->queue);
+
+	if (ctx->dev->vdec_pdata->is_comp_supported) {
+		hw_count = mtk_vcodec_get_hw_count(dev);
+		if (!hw_count) {
+			ret = -EINVAL;
+			goto err_init_queue;
+		}
+		for (i = 0; i < hw_count; i++)
+			init_waitqueue_head(&ctx->queue[i]);
+	} else {
+		init_waitqueue_head(&ctx->queue[0]);
+	}
+
 	mutex_init(&ctx->lock);
 
 	ctx->type = MTK_INST_DECODER;
@@ -294,6 +320,7 @@ static int fops_vcodec_open(struct file *file)
 err_m2m_ctx_init:
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 err_ctrls_setup:
+err_init_queue:
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	kfree(ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 5e1b7670ba5b..7a31afd294ba 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -87,7 +87,7 @@ static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
 	writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
 	writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->comp_idx);
 
 	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
 		ctx->id, dec_done_status);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 1d0798fd9adf..08fd43106fc7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -104,6 +104,16 @@ enum mtk_vdec_hw_id {
 	MTK_VDEC_HW_MAX,
 };
 
+/**
+ * struct mtk_vdec_hw_count - Supported hardware count
+ */
+enum mtk_vdec_hw_count {
+	MTK_VDEC_NO_HW = 0,
+	MTK_VDEC_ONE_CORE,
+	MTK_VDEC_ONE_LAT_ONE_CORE,
+	MTK_VDEC_MAX_HW_COUNT,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -293,9 +303,9 @@ struct mtk_vcodec_ctx {
 	struct vdec_pic_info picinfo;
 	int dpb_size;
 
-	int int_cond;
-	int int_type;
-	wait_queue_head_t queue;
+	int int_cond[MTK_VDEC_HW_MAX];
+	int int_type[MTK_VDEC_HW_MAX];
+	wait_queue_head_t queue[MTK_VDEC_HW_MAX];
 	unsigned int irq_status;
 
 	struct v4l2_ctrl_handler ctrl_hdl;
@@ -501,11 +511,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 }
 
 /* Wake up context wait_queue */
-static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason,
+	unsigned int hw_id)
 {
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
+	ctx->int_cond[hw_id] = 1;
+	ctx->int_type[hw_id] = reason;
+	wake_up_interruptible(&ctx->queue[hw_id]);
 }
 
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 2828df77020c..c7540c0cdcea 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -114,7 +114,7 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
 
 	clean_irq_status(ctx->irq_status, addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
 	return IRQ_HANDLED;
 }
 
@@ -140,7 +140,7 @@ static int fops_vcodec_open(struct file *file)
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
-	init_waitqueue_head(&ctx->queue);
+	init_waitqueue_head(&ctx->queue[0]);
 
 	ctx->type = MTK_INST_ENCODER;
 	ret = mtk_vcodec_enc_ctrls_setup(ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
index 70580c2525ba..8147533da98b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
@@ -11,34 +11,31 @@
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx  *ctx, int command,
-				 unsigned int timeout_ms)
+int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
+	int command, unsigned int timeout_ms, unsigned hw_id)
 {
-	wait_queue_head_t *waitqueue;
 	long timeout_jiff, ret;
 	int status = 0;
 
-	waitqueue = (wait_queue_head_t *)&ctx->queue;
 	timeout_jiff = msecs_to_jiffies(timeout_ms);
-
-	ret = wait_event_interruptible_timeout(*waitqueue,
-				ctx->int_cond,
+	ret = wait_event_interruptible_timeout(ctx->queue[hw_id],
+				ctx->int_cond[hw_id],
 				timeout_jiff);
 
 	if (!ret) {
 		status = -1;	/* timeout */
-		mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout time=%ums out %d %d!",
-			     ctx->id, ctx->type, command, timeout_ms,
-			     ctx->int_cond, ctx->int_type);
+		mtk_v4l2_err("[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)",
+				ctx->id, command, ctx->type, timeout_ms,
+				ctx->int_cond[hw_id], ctx->int_type[hw_id]);
 	} else if (-ERESTARTSYS == ret) {
-		mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout interrupted by a signal %d %d",
-			     ctx->id, ctx->type, command, ctx->int_cond,
-			     ctx->int_type);
 		status = -1;
+		mtk_v4l2_err("[%d] cmd=%d, type=%d, dec inter fail (%d %d)",
+				ctx->id, command, ctx->type,
+				ctx->int_cond[hw_id], ctx->int_type[hw_id]);
 	}
 
-	ctx->int_cond = 0;
-	ctx->int_type = 0;
+	ctx->int_cond[hw_id] = 0;
+	ctx->int_type[hw_id] = 0;
 
 	return status;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
index 638cd1f3526a..2bf4cabfaa43 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
@@ -12,7 +12,7 @@
 struct mtk_vcodec_ctx;
 
 /* timeout is ms */
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *data, int command,
-				unsigned int timeout_ms);
+int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
+				int command, unsigned int timeout_ms, unsigned int hw_id);
 
 #endif /* _MTK_VCODEC_INTR_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
index 40d6e6c5ac7a..481655bb6016 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
@@ -413,7 +413,7 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 		/* wait decoder done interrupt */
 		err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
 						   MTK_INST_IRQ_RECEIVED,
-						   WAIT_INTR_TIMEOUT_MS);
+						   WAIT_INTR_TIMEOUT_MS, 0);
 		if (err)
 			goto err_free_fb_out;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 4dde9ee786b4..d23baa364246 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -724,7 +724,7 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 	/* wait decoder done interrupt */
 	err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
 					   MTK_INST_IRQ_RECEIVED,
-					   WAIT_INTR_TIMEOUT_MS);
+					   WAIT_INTR_TIMEOUT_MS, 0);
 	if (err)
 		goto err_free_fb_out;
 	vpu_dec_end(vpu);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
index e5393f841080..88c046731754 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
@@ -488,7 +488,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	/* wait decoder done interrupt */
 	mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
-				     WAIT_INTR_TIMEOUT_MS);
+				     WAIT_INTR_TIMEOUT_MS, 0);
 
 	if (inst->vsi->load_data)
 		load_dec_table(inst);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
index 71cdc3ddafcb..70b8383f7c8e 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
@@ -539,7 +539,7 @@ static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst)
 
 	mtk_vcodec_wait_for_done_ctx(inst->ctx,
 			MTK_INST_IRQ_RECEIVED,
-			WAIT_INTR_TIMEOUT_MS);
+			WAIT_INTR_TIMEOUT_MS, 0);
 
 	if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
 		return true;
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index b6a4f2074fa5..9ae1bd8dbc32 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -335,7 +335,7 @@ static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
 	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 
 	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
-					  WAIT_INTR_TIMEOUT_MS)) {
+					  WAIT_INTR_TIMEOUT_MS, 0)) {
 		irq_status = ctx->irq_status;
 		mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
 	}
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index 8267a9c4fd25..f96564277577 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -222,7 +222,7 @@ static unsigned int vp8_enc_wait_venc_done(struct venc_vp8_inst *inst)
 	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 
 	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
-					  WAIT_INTR_TIMEOUT_MS)) {
+					  WAIT_INTR_TIMEOUT_MS, 0)) {
 		irq_status = ctx->irq_status;
 		mtk_vcodec_debug(inst, "isr return %x", irq_status);
 	}
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:56 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:56 +0800
Subject: [PATCH v5,
 10/15] media: mtk-vcodec: Add new interface to lock different hardware
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-11-yunfei.dong@mediatek.com>

For add new hardware, not only need to lock lat hardware, also
need to lock core hardware in case of different instance start
to decoder at the same time.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c     | 4 ++--
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 6 +++---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 2b334a8a81c6..130ecef2e766 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -105,12 +105,12 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
 
 void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_unlock(&ctx->dev->dec_mutex);
+	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_lock(&ctx->dev->dec_mutex);
+	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 109f7de126a1..e448cb238c7f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -373,7 +373,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct video_device *vfd_dec;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret;
+	int i, ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -405,8 +405,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	mutex_init(&dev->dec_mutex);
-	mutex_init(&dev->dev_mutex);
+	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
+		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
 
 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index a8242389ad24..f1e63acaec76 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -496,7 +496,7 @@ struct mtk_vcodec_dev {
 	int dec_irq;
 	int enc_irq;
 
-	struct mutex dec_mutex;
+	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
 	struct mutex enc_mutex;
 
 	struct mtk_vcodec_pm pm;
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:58:01 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:58:01 +0800
Subject: [PATCH v5,
 15/15] media: mtk-vcodec: Use codec type to separate different
 hardware
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-16-yunfei.dong@mediatek.com>

There are just one core thread, in order to separeate different
hardware, using codec type to separeate it in scp driver.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 12 ++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 34 ++++++++++++++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  4 +++
 3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 9d8079c4f976..c488f0c40190 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -35,6 +35,8 @@ enum vdec_ipi_msgid {
  * @msg_id	: vdec_ipi_msgid
  * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
  * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @codec_type	: Codec fourcc
+ * @reserved	: reserved param
  */
 struct vdec_ap_ipi_cmd {
 	uint32_t msg_id;
@@ -42,6 +44,8 @@ struct vdec_ap_ipi_cmd {
 		uint32_t vpu_inst_addr;
 		uint32_t inst_id;
 	};
+	uint32_t codec_type;
+	uint32_t reserved;
 };
 
 /**
@@ -59,12 +63,12 @@ struct vdec_vpu_ipi_ack {
 /**
  * struct vdec_ap_ipi_init - for AP_IPIMSG_DEC_INIT
  * @msg_id	: AP_IPIMSG_DEC_INIT
- * @reserved	: Reserved field
+ * @codec_type	: Codec fourcc
  * @ap_inst_addr	: AP video decoder instance address
  */
 struct vdec_ap_ipi_init {
 	uint32_t msg_id;
-	uint32_t reserved;
+	uint32_t codec_type;
 	uint64_t ap_inst_addr;
 };
 
@@ -77,7 +81,7 @@ struct vdec_ap_ipi_init {
  *	H264 decoder [0]:buf_sz [1]:nal_start
  *	VP8 decoder  [0]:width/height
  *	VP9 decoder  [0]:profile, [1][2] width/height
- * @reserved	: Reserved field
+ * @codec_type	: Codec fourcc
  */
 struct vdec_ap_ipi_dec_start {
 	uint32_t msg_id;
@@ -86,7 +90,7 @@ struct vdec_ap_ipi_dec_start {
 		uint32_t inst_id;
 	};
 	uint32_t data[3];
-	uint32_t reserved;
+	uint32_t codec_type;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index bfd8e87dceff..c84fac52fe26 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -100,18 +100,29 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 
 static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
 {
-	int err;
+	int err, id, msgid;
 
-	mtk_vcodec_debug(vpu, "id=%X", *(uint32_t *)msg);
+	msgid = *(uint32_t *)msg;
+	mtk_vcodec_debug(vpu, "id=%X", msgid);
 
 	vpu->failure = 0;
 	vpu->signaled = 0;
 
-	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, vpu->id, msg,
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		if (msgid == AP_IPIMSG_DEC_CORE ||
+			msgid == AP_IPIMSG_DEC_CORE_END)
+			id = vpu->core_id;
+		else
+			id = vpu->id;
+	} else {
+		id = vpu->id;
+	}
+
+	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg,
 				     len, 2000);
 	if (err) {
 		mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d",
-			       vpu->id, *(uint32_t *)msg, err);
+			       id, msgid, err);
 		return err;
 	}
 
@@ -131,6 +142,7 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id)
 		msg.vpu_inst_addr = vpu->inst_addr;
 	else
 		msg.inst_id = vpu->inst_id;
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err);
@@ -149,14 +161,25 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu)
 
 	err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id,
 					 vpu->handler, "vdec", NULL);
-	if (err != 0) {
+	if (err) {
 		mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err);
 		return err;
 	}
 
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler,
+					 vpu->core_id, vpu->handler,
+					 "vdec", NULL);
+		if (err) {
+			mtk_vcodec_err(vpu, "vpu_ipi_register core fail status=%d", err);
+			return err;
+		}
+	}
+
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_id = AP_IPIMSG_DEC_INIT;
 	msg.ap_inst_addr = (unsigned long)vpu;
+	msg.codec_type = vpu->codec_type;
 
 	mtk_vcodec_debug(vpu, "vdec_inst=%p", vpu);
 
@@ -187,6 +210,7 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 
 	for (i = 0; i < len; i++)
 		msg.data[i] = data[i];
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- ret=%d", err);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index ae24b75d1649..802660770a87 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -14,6 +14,7 @@ struct mtk_vcodec_ctx;
 /**
  * struct vdec_vpu_inst - VPU instance for video codec
  * @id          : ipi msg id for each decoder
+ * @core_id     : core id used to separate different hardware
  * @vsi         : driver structure allocated by VPU side and shared to AP side
  *                for control and info share
  * @failure     : VPU execution result status, 0: success, others: fail
@@ -26,9 +27,11 @@ struct mtk_vcodec_ctx;
  * @dev		: platform device of VPU
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
+ * @codec_type     : used codec type to separate different codecs
  */
 struct vdec_vpu_inst {
 	int id;
+	int core_id;
 	void *vsi;
 	int32_t failure;
 	uint32_t inst_addr;
@@ -38,6 +41,7 @@ struct vdec_vpu_inst {
 	struct mtk_vcodec_ctx *ctx;
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
+	unsigned int codec_type;
 };
 
 /**
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:54 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:54 +0800
Subject: [PATCH v5,
 08/15] media: mtk-vcodec: Add msg queue feature for lat and core
 architecture
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-9-yunfei.dong@mediatek.com>

For lat and core architecture, lat thread will send message to core
thread when lat decode done. Core hardware will use the message
from lat to decode, then free message to lat thread when decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 258 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 151 ++++++++++
 4 files changed, 415 insertions(+)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index edeb3b66e9e9..5000e59da576 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -11,6 +11,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
+		vdec_msg_queue.o \
 		mtk_vcodec_dec.o \
 		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_stateless.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 08fd43106fc7..4ad0566e715d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -15,7 +15,9 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
+
 #include "mtk_vcodec_util.h"
+#include "vdec_msg_queue.h"
 
 #define MTK_VCODEC_DRV_NAME	"mtk_vcodec_drv"
 #define MTK_VCODEC_DEC_NAME	"mtk-vcodec-dec"
@@ -282,6 +284,8 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ *
+ * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -325,6 +329,7 @@ struct mtk_vcodec_ctx {
 	int decoded_frame_cnt;
 	struct mutex lock;
 
+	struct vdec_msg_queue msg_queue;
 };
 
 enum mtk_chip {
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
new file mode 100644
index 000000000000..d66ed98c79a9
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/freezer.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_drv.h"
+#include "vdec_msg_queue.h"
+
+#define VDEC_LAT_SLICE_HEADER_SZ    (640 * 1024)
+#define VDEC_ERR_MAP_SZ_AVC         ((8192 / 16) * (4352 / 16) / 8)
+
+/* lat write decoded hardware information to trans buffer,
+ * and core will read the trans buffer to decode again. The
+ * trans buffer size of FHD and 4K bitstreams are different.
+ */
+static int vde_msg_queue_get_trans_size(int width, int height)
+{
+	if (width > 1920 || height > 1088)
+		return (30 * 1024 * 1024);
+	else
+		return 6 * 1024 * 1024;
+}
+
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
+	int hardware_index)
+{
+	init_waitqueue_head(&ctx->ready_to_use);
+	INIT_LIST_HEAD(&ctx->ready_queue);
+	spin_lock_init(&ctx->ready_lock);
+	ctx->ready_num = 0;
+	ctx->hardware_index = hardware_index;
+}
+
+int vdec_msg_queue_init(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx,
+	core_decode_cb_t core_decode,
+	int private_size)
+{
+	struct vdec_lat_buf *lat_buf;
+	int i, err;
+
+	/* already init msg queue */
+	if (msg_queue->wdma_addr.size)
+		return 0;
+
+	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+	msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(
+		ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+
+	err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
+	if (err) {
+		mtk_v4l2_err("failed to allocate wdma_addr buf");
+		return -ENOMEM;
+	}
+	msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
+	msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
+
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->wdma_err_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_err_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->slice_bc_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
+		if (!lat_buf->private_data) {
+			mtk_v4l2_err("failed to allocate private_data[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->ctx = ctx;
+		lat_buf->core_decode = core_decode;
+		vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
+	}
+	return 0;
+
+mem_alloc_err:
+	vdec_msg_queue_deinit(msg_queue, ctx);
+	return -ENOMEM;
+}
+
+static struct list_head *vdec_get_buf_list(int hardware_index,
+	struct vdec_lat_buf *buf)
+{
+	switch (hardware_index) {
+	case MTK_VDEC_CORE:
+		return &buf->core_list;
+	case MTK_VDEC_LAT0:
+		return &buf->lat_list;
+	default:
+		return NULL;
+	}
+}
+
+void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
+	struct vdec_lat_buf *buf)
+{
+	struct list_head *head;
+
+	head = vdec_get_buf_list(ctx->hardware_index, buf);
+	if (!head) {
+		mtk_v4l2_err("fail to qbuf: %d",ctx->hardware_index);
+		return;
+	}
+
+	spin_lock(&ctx->ready_lock);
+	list_add_tail(head, &ctx->ready_queue);
+	ctx->ready_num++;
+
+	wake_up_all(&ctx->ready_to_use);
+
+	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
+		ctx->hardware_index, buf, ctx->ready_num);
+	spin_unlock(&ctx->ready_lock);
+}
+
+static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx *ctx)
+{
+	long timeout_jiff;
+	int ret;
+
+	if (ctx->hardware_index == MTK_VDEC_CORE) {
+		ret = wait_event_freezable(ctx->ready_to_use,
+			!list_empty(&ctx->ready_queue));
+		if (ret)
+			return false;
+	} else {
+		timeout_jiff = msecs_to_jiffies(1500);
+		ret = wait_event_timeout(ctx->ready_to_use,
+			!list_empty(&ctx->ready_queue), timeout_jiff);
+		if (!ret)
+			return false;
+	}
+
+	return true;
+}
+
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx)
+{
+	struct vdec_lat_buf *buf;
+	struct list_head *head;
+	int ret;
+
+	spin_lock(&ctx->ready_lock);
+	if (list_empty(&ctx->ready_queue)) {
+		mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d",
+			ctx->hardware_index, ctx->ready_num);
+		spin_unlock(&ctx->ready_lock);
+		ret = vdec_msg_queue_wait_event(ctx);
+		if (!ret)
+			return NULL;
+		spin_lock(&ctx->ready_lock);
+	}
+
+	if (ctx->hardware_index == MTK_VDEC_CORE)
+		buf = list_first_entry(&ctx->ready_queue,
+			struct vdec_lat_buf, core_list);
+	else
+		buf = list_first_entry(&ctx->ready_queue,
+			struct vdec_lat_buf, lat_list);
+
+	head = vdec_get_buf_list(ctx->hardware_index, buf);
+	if (!head) {
+		mtk_v4l2_err("fail to dqbuf: %d",ctx->hardware_index);
+		return NULL;
+	}
+	list_del(head);
+
+	ctx->ready_num--;
+	mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
+		ctx->hardware_index, buf, ctx->ready_num);
+	spin_unlock(&ctx->ready_lock);
+
+	return buf;
+}
+
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_rptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_rptr_addr = ube_rptr;
+	mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_wptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_wptr_addr = ube_wptr;
+	mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx",
+		msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr, ube_wptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
+{
+	long timeout_jiff;
+	int ret;
+
+	timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
+
+	ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
+		msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
+		timeout_jiff);
+	if (ret) {
+		mtk_v4l2_debug(3, "success to get lat buf: %d",
+			msg_queue->lat_ctx.ready_num);
+		return true;
+	}
+	mtk_v4l2_err("failed with lat buf isn't full: %d",
+		msg_queue->lat_ctx.ready_num);
+	return false;
+}
+
+void vdec_msg_queue_deinit(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_lat_buf *lat_buf;
+	struct mtk_vcodec_mem *mem;
+	int i;
+
+	mem = &msg_queue->wdma_addr;
+	if (mem->va)
+		mtk_vcodec_mem_free(ctx, mem);
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		mem = &lat_buf->wdma_err_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		mem = &lat_buf->slice_bc_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		if (lat_buf->private_data)
+			kfree(lat_buf->private_data);
+	}
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
new file mode 100644
index 000000000000..1905ce713592
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _VDEC_MSG_QUEUE_H_
+#define _VDEC_MSG_QUEUE_H_
+
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "mtk_vcodec_util.h"
+
+#define NUM_BUFFER_COUNT 3
+
+struct vdec_lat_buf;
+struct mtk_vcodec_ctx;
+struct mtk_vcodec_dev;
+typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
+
+/**
+ * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be
+ *	                           processed
+ * @ready_used: ready used queue used to signalize when get a job queue
+ * @ready_queue: list of ready lat buffer queues
+ * @ready_lock: spin lock to protect the lat buffer usage
+ * @ready_num: number of buffers ready to be processed
+ * @hardware_index: hardware id that this queue is used for
+ */
+struct vdec_msg_queue_ctx {
+	wait_queue_head_t ready_to_use;
+	struct list_head ready_queue;
+	spinlock_t ready_lock;
+	int ready_num;
+	int hardware_index;
+};
+
+/**
+ * struct vdec_lat_buf - lat buffer message used to store lat
+ *                       info for core decode
+ * @wdma_err_addr: wdma error address used for lat hardware
+ * @slice_bc_addr: slice bc address used for lat hardware
+ * @ts_info: need to set timestamp from output to capture
+ *
+ * @private_data: shared information used to lat and core hardware
+ * @ctx: mtk vcodec context information
+ * @core_decode: different codec use different decode callback function
+ * @lat_list: add lat buffer to lat head list
+ * @core_list: add lat buffer to core head list
+ */
+struct vdec_lat_buf {
+	struct mtk_vcodec_mem wdma_err_addr;
+	struct mtk_vcodec_mem slice_bc_addr;
+	struct vb2_v4l2_buffer ts_info;
+
+	void *private_data;
+	struct mtk_vcodec_ctx *ctx;
+	core_decode_cb_t core_decode;
+	struct list_head lat_list;
+	struct list_head core_list;
+};
+
+/**
+ * struct vdec_msg_queue - used to store lat buffer message
+ * @lat_buf: lat buffer used to store lat buffer information
+ * @wdma_addr: wdma address used for ube
+ * @wdma_rptr_addr: ube read point
+ * @wdma_wptr_addr: ube write point
+ * @lat_ctx: used to store lat buffer list
+ */
+struct vdec_msg_queue {
+	struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
+
+	struct mtk_vcodec_mem wdma_addr;
+	uint64_t wdma_rptr_addr;
+	uint64_t wdma_wptr_addr;
+
+	struct vdec_msg_queue_ctx lat_ctx;
+};
+
+/**
+ * vdec_msg_queue_init - init lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ * @core_decode: core decode callback for each codec
+ * @private_size: the private data size used to share with core
+ */
+int vdec_msg_queue_init(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx,
+	core_decode_cb_t core_decode,
+	int private_size);
+
+/**
+ * vdec_msg_queue_init_ctx - used to init msg queue context information.
+ * @ctx: message queue context
+ * @hardware_index: hardware index
+ */
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx,
+	int hardware_index);
+
+/**
+ * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
+ * @ctx: message queue context
+ * @buf: current lat buffer
+ */
+void vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx,
+	struct vdec_lat_buf *buf);
+
+/**
+ * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
+ * @ctx: message queue context
+ */
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx);
+
+/**
+ * vdec_msg_queue_update_ube_rptr - used to updata the ube read point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_rptr: current ube read point
+ */
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_rptr);
+
+/**
+ * vdec_msg_queue_update_ube_wptr - used to updata the ube write point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_wptr: current ube write point
+ */
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue,
+	uint64_t ube_wptr);
+
+/**
+ * vdec_msg_queue_wait_lat_buf_full - used to check whether all lat buffer
+ *                                    in lat list.
+ * @msg_queue: used to store the lat buffer information
+ */
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue);
+
+/**
+ * vdec_msg_queue_deinit - deinit lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ */
+void vdec_msg_queue_deinit(
+	struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx);
+
+#endif
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:55 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:55 +0800
Subject: [PATCH v5, 09/15] media: mtk-vcodec: Generalize power and clock on/off
 interfaces
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-10-yunfei.dong@mediatek.com>

Generalizes power and clock on/off interfaces to support different hardware.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: Fix build error.
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  4 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 76 ++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  8 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  2 +
 .../platform/mtk-vcodec/mtk_vcodec_util.c     | 87 ++++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |  8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   | 21 ++---
 9 files changed, 174 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index f096ad1c01ac..109f7de126a1 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -126,7 +126,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[0]);
@@ -286,7 +286,7 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(&dev->pm);
+		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
 		if (ret < 0)
 			goto err_load_fw;
 		/*
@@ -347,7 +347,7 @@ static int fops_vcodec_release(struct file *file)
 	mtk_vcodec_dec_release(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(&dev->pm);
+		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 7a31afd294ba..714df68ffb19 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -68,7 +68,7 @@ static irqreturn_t mtk_vdec_comp_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_COMP_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev->master_dev, dev->comp_idx);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[VDEC_COMP_SYS]);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
index 8d6e818a3474..0a4c2e6f5df2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -32,6 +32,8 @@ enum mtk_comp_hw_reg_idx {
  * @master_dev: master device
  * @reg_base: Mapped address of MTK Vcodec registers.
  *
+ * @curr_ctx: The context that is waiting for codec hardware
+ *
  * @dec_irq: decoder irq resource
  * @pm: power management control
  * @comp_idx: component index
@@ -41,6 +43,8 @@ struct mtk_vdec_comp_dev {
 	struct mtk_vcodec_dev *master_dev;
 	void __iomem *reg_base[VDEC_COMP_MAX];
 
+	struct mtk_vcodec_ctx *curr_ctx;
+
 	int dec_irq;
 	struct mtk_vcodec_pm pm;
 	int comp_idx;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 20bd157a855c..183d4c4e36f0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -5,11 +5,13 @@
  */
 
 #include <linux/clk.h>
+#include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
@@ -84,10 +86,23 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 	put_device(pm->larbvdec);
 }
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return -EINVAL;
+		}
+		pm = &comp_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
@@ -95,20 +110,49 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 	return ret;
 }
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int ret, i = 0;
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int ret, i;
+
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+		enable_irq(comp_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		enable_irq(vdec_dev->dec_irq);
+	}
 
+	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
 		if (ret) {
@@ -130,11 +174,27 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int i = 0;
+	struct mtk_vdec_comp_dev *comp_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int i;
 
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &comp_dev->pm;
+		disable_irq(comp_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		disable_irq(vdec_dev->dec_irq);
+	}
+
+	dec_clk = &pm->vdec_clk;
 	mtk_smi_larb_put(pm->larbvdec);
 	for (i = dec_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index a3df6aef6cb9..698750572b57 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -13,9 +13,9 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
 	struct mtk_vcodec_pm *pm);
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm);
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int comp_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 4ad0566e715d..a8242389ad24 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -284,6 +284,7 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ * @hw_id: hardware index used to identify different hardware.
  *
  * @msg_queue: msg queue used to store lat buffer information.
  */
@@ -328,6 +329,7 @@ struct mtk_vcodec_ctx {
 
 	int decoded_frame_cnt;
 	struct mutex lock;
+	int hw_id;
 
 	struct vdec_msg_queue msg_queue;
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index ac5973b6735f..511b75e49fe7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -6,7 +6,10 @@
 */
 
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
 
@@ -81,25 +84,87 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 }
 EXPORT_SYMBOL(mtk_vcodec_mem_free);
 
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx)
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int comp_idx)
 {
-	unsigned long flags;
+	struct platform_device *hw_pdev;
+	struct device_node *node;
+	struct mtk_vdec_comp_dev *master_dev;
+
+	if (comp_idx >= MTK_VDEC_HW_MAX || comp_idx < 0) {
+		mtk_v4l2_err("Comp idx is out of range:%d", comp_idx);
+		return NULL;
+	}
+
+	if (dev->comp_dev[comp_idx])
+		return dev->comp_dev[comp_idx];
+
+	node = dev->component_node[comp_idx];
+	if (!node) {
+		mtk_v4l2_err("Get lat node fail:%d", comp_idx);
+		return NULL;
+	}
+
+	hw_pdev = of_find_device_by_node(node);
+	of_node_put(node);
+
+	if (WARN_ON(!hw_pdev)) {
+		mtk_v4l2_err("Get hw id(%d) node fail", comp_idx);
+		return NULL;
+	}
+
+	master_dev = platform_get_drvdata(hw_pdev);
+	if (!master_dev) {
+		mtk_v4l2_err("Get hw id(%d) pdev fail", comp_idx);
+		return NULL;
+	}
 
-	spin_lock_irqsave(&dev->irqlock, flags);
-	dev->curr_ctx = ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+	dev->comp_dev[master_dev->comp_idx] = master_dev;
+	return master_dev;
+}
+EXPORT_SYMBOL(mtk_vcodec_get_hw_dev);
+
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	struct mtk_vcodec_ctx *ctx, int comp_idx)
+{
+	unsigned long flags;
+	struct mtk_vdec_comp_dev *comp_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return;
+		}
+		comp_dev->curr_ctx = ctx;
+	} else {
+		vdec_dev->curr_ctx = ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 }
 EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx);
 
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	unsigned int comp_idx)
 {
 	unsigned long flags;
 	struct mtk_vcodec_ctx *ctx;
-
-	spin_lock_irqsave(&dev->irqlock, flags);
-	ctx = dev->curr_ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+	struct mtk_vdec_comp_dev *comp_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->vdec_pdata->is_comp_supported) {
+		comp_dev = mtk_vcodec_get_hw_dev(vdec_dev, comp_idx);
+		if (!comp_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return NULL;
+		}
+		ctx = comp_dev->curr_ctx;
+	} else {
+		ctx = vdec_dev->curr_ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 	return ctx;
 }
 EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index b999d7b84ed1..4cb0fc60c94f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -79,8 +79,10 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
 void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx);
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev);
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+				struct mtk_vcodec_ctx *ctx, int comp_idx);
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	unsigned int comp_idx);
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int comp_idx);
 
 #endif /* _MTK_VCODEC_UTIL_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 42008243ceac..05a5b240e906 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -24,21 +24,24 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP8:
 		ctx->dec_if = &vdec_vp8_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP9:
 		ctx->dec_if = &vdec_vp9_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	default:
 		return -EINVAL;
 	}
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	return ret;
@@ -69,13 +72,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 
 	mtk_vdec_lock(ctx);
 
-	mtk_vcodec_set_curr_ctx(ctx->dev, ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
-	enable_irq(ctx->dev->dec_irq);
+	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	disable_irq(ctx->dev->dec_irq);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
-	mtk_vcodec_set_curr_ctx(ctx->dev, NULL);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
+	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
 
 	mtk_vdec_unlock(ctx);
 
@@ -103,9 +104,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 		return;
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	ctx->drv_handle = NULL;
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:47 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:47 +0800
Subject: [PATCH v5,
 01/15] media: mtk-vcodec: Get numbers of register bases from DT
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-2-yunfei.dong@mediatek.com>

Different platform may has different numbers of register bases. Gets the
numbers of register bases from DT (sizeof(u32) * 4 bytes for each).

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 37 ++++++++++++++-----
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 55ae198dbcf9..983e0f2831af 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -78,6 +78,30 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	return IRQ_HANDLED;
 }
 
+static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int reg_num, i;
+
+	/* Sizeof(u32) * 4 bytes for each register base. */
+	reg_num = of_property_count_elems_of_size(pdev->dev.of_node, "reg",
+		sizeof(u32) * 4);
+	if (reg_num <= 0 || reg_num > NUM_MAX_VDEC_REG_BASE) {
+		dev_err(&pdev->dev, "Invalid register property size: %d\n", reg_num);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < reg_num; i++) {
+		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
+		if (IS_ERR(dev->reg_base[i]))
+			return PTR_ERR(dev->reg_base[i]);
+
+		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -206,7 +230,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int i, ret;
+	int ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -238,14 +262,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) {
-		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
-		if (IS_ERR((__force void *)dev->reg_base[i])) {
-			ret = PTR_ERR((__force void *)dev->reg_base[i]);
-			goto err_res;
-		}
-		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
-	}
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		goto err_res;
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (res == NULL) {
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:48 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:48 +0800
Subject: [PATCH v5,
 02/15] media: mtk-vcodec: Align vcodec wake up interrupt interface
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-3-yunfei.dong@mediatek.com>

Vdec and venc can use the same function to wake up interrupt event.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
---
v5: no changes
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 9 +--------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 8 ++++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 8 --------
 3 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 983e0f2831af..8db9cdc66043 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -31,13 +31,6 @@
 module_param(mtk_v4l2_dbg_level, int, 0644);
 module_param(mtk_vcodec_dbg, bool, 0644);
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx)
-{
-	ctx->int_cond = 1;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -69,7 +62,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
 		dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
 
-	wake_up_ctx(ctx);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index d4f840a7bbcb..3b1e5e3a450e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -472,4 +472,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 	return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl);
 }
 
+/* Wake up context wait_queue */
+static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+{
+	ctx->int_cond = 1;
+	ctx->int_type = reason;
+	wake_up_interruptible(&ctx->queue);
+}
+
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 4167e865b23f..2828df77020c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -73,14 +73,6 @@ static const struct mtk_video_fmt mtk_video_formats_capture_mt8183[] =  {
 	},
 };
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
-{
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
 {
 	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:46 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:46 +0800
Subject: [PATCH v5,
 00/15] Using component framework to support multi hardware decode
Message-ID: <20210811025801.21597-1-yunfei.dong@mediatek.com>

This series adds support for multi hardware decode into mtk-vcodec, by first
adding component framework to manage each hardware information: interrupt,
clock, register bases and power. Secondly add core thread to deal with core
hardware message, at the same time, add msg queue for different hardware
share messages. Lastly, the architecture of different specs are not the same,
using specs type to separate them.

This series has been tested with both MT8183 and MT8173. Decoding was working
for both chips.

Patches 1~3 rewrite get register bases and power on/off interface.

Patch 4 add component framework to support multi hardware.

Patch 5 separate video encoder and decoder document

Patches 6-15 add interfaces to support core hardware.
----
This patch dependents on : "media: mtk-vcodec: support for MT8183 decoder"[1] and
"Mediatek MT8192 clock support"[2].

1: Multi hardware decode is based on stateless decoder, MT8183 is the first time
to add stateless decoder. Otherwise it will cause conflict. Please also accept
this patch together with [1].

2: The definition of decoder clocks are in mt8192-clk.h, need to include them in
case of build fail [2].

[1]https://patchwork.linuxtv.org/project/linux-media/list/?series=6057
[2]https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
----
Changes compared with v4:
- Fix comments for patch 4/15
  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  Fix platform_set_drvdata.
- Fix build error for patch 9/15
- Add depend patch in case of error header file for patch 13/15

Changes compared with v3:
- Fix return value for patch 1/15
- Fix comments for patch 4/15
  > Looking up "mediatek,mtk-vcodec-core" to determine if it uses component framwork sounds like...
  Add prameter in pdata, for all platform will use compoent after mt8183

  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  > + Has asked the same question in [1].  Why it removes the
  > +platform_set_drvdata() above?  mtk_vcodec_init_master() also calls platform_set_drvdata().
  Must call component_master_add_with_match after platform_set_drvdata for component architecture.
- Fix yaml files check fail for patch 5/15
- Fix yaml file check fail for patch 14/15

Changes compared with v1:
- Fix many comments for patch 3/14
- Remove unnecessary code for patch 4/14
- Using enum mtk_vdec_hw_count instead of magic numbers for patch 6/14
- Reconstructed get/put lat buffer for lat and core hardware for patch 7/14
- Using yaml format to instead of txt file for patch 12/14

Yunfei Dong (15):
  media: mtk-vcodec: Get numbers of register bases from DT
  media: mtk-vcodec: Align vcodec wake up interrupt interface
  media: mtk-vcodec: Refactor vcodec pm interface
  media: mtk-vcodec: Use component framework to manage each hardware
    information
  dt-bindings: media: mtk-vcodec: Separate video encoder and decoder
    dt-bindings
  media: mtk-vcodec: Use pure single core for MT8183
  media: mtk-vcodec: Add irq interface for multi hardware
  media: mtk-vcodec: Add msg queue feature for lat and core architecture
  media: mtk-vcodec: Generalize power and clock on/off interfaces
  media: mtk-vcodec: Add new interface to lock different hardware
  media: mtk-vcodec: Add core thread
  media: mtk-vcodec: Support 34bits dma address for vdec
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192
  media: mtk-vcodec: Add core dec and dec end ipi msg
  media: mtk-vcodec: Use codec type to separate different hardware

 .../media/mediatek,vcodec-comp-decoder.yaml   | 172 +++++++++++
 .../media/mediatek,vcodec-decoder.yaml        | 175 +++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 185 +++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 130 --------
 drivers/media/platform/mtk-vcodec/Makefile    |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 276 ++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 184 +++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  53 ++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   |  98 ++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  13 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   2 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  71 ++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  12 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |   1 -
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     |  27 +-
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  87 +++++-
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   8 +-
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |   2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |   2 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  21 +-
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  16 +-
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 290 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 157 ++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  46 ++-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  22 ++
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |   2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |   2 +-
 33 files changed, 1792 insertions(+), 279 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:59 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:59 +0800
Subject: [PATCH v5,
 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8192
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-14-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for mt8192.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes

This patch depends on "Mediatek MT8192 clock support"[1].

The definition of decoder clocks are in mt8192-clk.h, need to include them in case of build fail [1].

[1]https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
---
 .../media/mediatek,vcodec-comp-decoder.yaml   | 172 ++++++++++++++++++
 1 file changed, 172 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
new file mode 100644
index 000000000000..083c89933917
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator With Component
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities. Required
+  master and component node.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - mediatek,mt8192-vcodec-dec  # for lat hardware
+          - mediatek,mtk-vcodec-lat     # for core hardware
+          - mediatek,mtk-vcodec-core
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 5
+
+  clock-names:
+    items:
+      - const: vdec-sel
+      - const: vdec-soc-vdec
+      - const: vdec-soc-lat
+      - const: vdec-vdec
+      - const: vdec-top
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+      - compatible
+      - reg
+      - iommus
+      - dma-ranges
+
+allOf:
+  - if: #master node
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8192-vcodec-dec  # for lat hardware
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if: #component node
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mtk-vcodec-lat     # for core hardware
+              - mediatek,mtk-vcodec-core
+
+    then:
+      required:
+        - interrupts
+        - clocks
+        - clock-names
+        - assigned-clocks
+        - assigned-clock-parents
+        - power-domains
+
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/memory/mt8192-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mt8192-clk.h>
+    #include <dt-bindings/power/mt8192-power.h>
+
+    vcodec_dec: vcodec_dec at 16000000 {
+        compatible = "mediatek,mt8192-vcodec-dec";
+        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
+        mediatek,scp = <&scp>;
+        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+    };
+
+    vcodec_lat: vcodec_lat at 0x16010000 {
+        compatible = "mediatek,mtk-vcodec-lat";
+        reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
+        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
+        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
+             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
+             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
+             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
+             <&topckgen CLK_TOP_MAINPLL_D4>;
+        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
+              "vdec-vdec", "vdec-top";
+        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
+    };
+
+    vcodec_core: vcodec_core at 0x16025000 {
+        compatible = "mediatek,mtk-vcodec-core";
+        reg = <0 0x16025000 0 0x1000>;		/* VDEC_CORE_MISC */
+        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
+        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
+             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+             <&vdecsys CLK_VDEC_VDEC>,
+             <&vdecsys CLK_VDEC_LAT>,
+             <&vdecsys CLK_VDEC_LARB1>,
+             <&topckgen CLK_TOP_MAINPLL_D4>;
+        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
+              "vdec-vdec", "vdec-top";
+        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
+    };
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:58 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:58 +0800
Subject: [PATCH v5,
 12/15] media: mtk-vcodec: Support 34bits dma address for vdec
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-13-yunfei.dong@mediatek.com>

Use the dma_set_mask_and_coherent helper to set vdec
DMA bit mask to support 34bits iova space(16GB) that
the mt8192 iommu HW support.

Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G,
regarding which iova range VDEC actually locate, it
depends on the dma-ranges property of vdec dtsi node.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
v5: no changes
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 002352fcf8de..1a8d9308327d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -417,6 +417,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	spin_lock_init(&dev->irqlock);
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 10 19:57:49 2021
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 11 Aug 2021 10:57:49 +0800
Subject: [PATCH v5, 03/15] media: mtk-vcodec: Refactor vcodec pm interface
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <20210811025801.21597-4-yunfei.dong@mediatek.com>

Using the needed param for pm init/release function and remove unused
param mtkdev in 'struct mtk_vcodec_pm'.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
---
v5: no changes
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 22 ++++++++-----------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  5 +++--
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
 5 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 8db9cdc66043..dd749d41c75a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -249,7 +249,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev);
+	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
 		goto err_dec_pm;
@@ -379,7 +379,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -422,7 +422,7 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_dec);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 6038db96f71c..20bd157a855c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -13,18 +13,15 @@
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+	struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
-	struct platform_device *pdev;
-	struct mtk_vcodec_pm *pm;
+	struct platform_device *larb_pdev;
 	struct mtk_vcodec_clk *dec_clk;
 	struct mtk_vcodec_clk_info *clk_info;
 	int i = 0, ret = 0;
 
-	pdev = mtkdev->plat_dev;
-	pm = &mtkdev->pm;
-	pm->mtkdev = mtkdev;
 	dec_clk = &pm->vdec_clk;
 	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
 	if (!node) {
@@ -32,13 +29,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 		return -1;
 	}
 
-	pdev = of_find_device_by_node(node);
+	larb_pdev = of_find_device_by_node(node);
 	of_node_put(node);
-	if (WARN_ON(!pdev)) {
+	if (WARN_ON(!larb_pdev)) {
 		return -1;
 	}
-	pm->larbvdec = &pdev->dev;
-	pdev = mtkdev->plat_dev;
+	pm->larbvdec = &larb_pdev->dev;
 	pm->dev = &pdev->dev;
 
 	dec_clk->clk_num =
@@ -82,10 +78,10 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 	return ret;
 }
 
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 {
-	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvdec);
+	pm_runtime_disable(pm->dev);
+	put_device(pm->larbvdec);
 }
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 280aeaefdb65..a3df6aef6cb9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -9,8 +9,9 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+	struct mtk_vcodec_pm *pm);
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 3b1e5e3a450e..973b0b3649c6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -195,7 +195,6 @@ struct mtk_vcodec_pm {
 	struct mtk_vcodec_clk	venc_clk;
 	struct device	*larbvenc;
 	struct device	*dev;
-	struct mtk_vcodec_dev	*mtkdev;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 1b2e4930ed27..0c8c8f86788c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -26,7 +26,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
 	pdev = mtkdev->plat_dev;
 	pm = &mtkdev->pm;
 	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
-	pm->mtkdev = mtkdev;
 	pm->dev = &pdev->dev;
 	dev = &pdev->dev;
 	enc_clk = &pm->venc_clk;
-- 
2.25.1

From chunfeng.yun at mediatek.com  Tue Aug 10 20:04:28 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 11:04:28 +0800
Subject: [PATCH v3 1/2] PM / wakeirq: support enabling wake-up irq after
 runtime_suspend called
Message-ID: <1628651069-22162-1-git-send-email-chunfeng.yun@mediatek.com>

When the dedicated wake-irq is level trigger, and it uses the
consumer's sleep status as the wakeup source, that means if the
consumer is not in sleep state, the wake-irq will be triggered
when enable it; For this case, need enable the wake-irq after
invoking the consumer's runtime_suspend() which make the consumer
enter sleep state.

e.g.
Assume the wake-irq is a low level trigger type, and the wakeup
signal comes from the sleep status of consumer.
The wakeup signal is low level at running time (0), and becomes
high level when the consumer enters sleep state (runtime_suspend
(1) is called), a wakeup event at (2) make the consumer exit sleep
state, then the wakeup signal also becomes low level.

                ------------------
               |           ^     ^|
----------------           |     | --------------
 |<---(0)--->|<--(1)--|   (3)   (2)    (4)

if enable the wake-irq before calling runtime_suspend during (0),
an interrupt will arise, it causes resume immediately;
it works if enable wake-irq ( e.g. at (3) or (4)) after calling
runtime_suspend.

This patch introduces a new status WAKE_IRQ_DEDICATED_LATE_ENABLED
to optionally support enabling wake-irq after calling runtime_suspend().

Suggested-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: add new status suggested by Rafael

v2: add more commit message

  Use the falling edge trigger interrupt suggested by Ikjoon [1], it
works well at firstly when only use this related wakeup source, but
encounter issues if use other wakeup sources to wakeup platform as
below steps:
1. use another wakeup source to wake up the suspended system;
2. the consumer's resume() will be called, and exits sleep state;
3. the consumer's wakeup signal will fall into low level, due to
   currently the wakeup irq is disabled, the wake-irq is pending;
4. the consumer tries to enter runtime suspend, but there is a
   pending wakeup irq, so will resume again, this will repeat
   endlessly.

  Send out the patch again for further discussion.

[1]: https://patchwork.kernel.org/patch/12190407

---
 drivers/base/power/power.h   |  7 ++++--
 drivers/base/power/runtime.c |  6 +++--
 drivers/base/power/wakeirq.c | 49 +++++++++++++++++++++++++++++++++---
 include/linux/pm_wakeirq.h   |  5 ++++
 4 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 54292cdd7808..2d5dfc886f0b 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -25,8 +25,10 @@ extern u64 pm_runtime_active_time(struct device *dev);
 
 #define WAKE_IRQ_DEDICATED_ALLOCATED	BIT(0)
 #define WAKE_IRQ_DEDICATED_MANAGED	BIT(1)
+#define WAKE_IRQ_DEDICATED_LATE_ENABLED	BIT(2)
 #define WAKE_IRQ_DEDICATED_MASK		(WAKE_IRQ_DEDICATED_ALLOCATED | \
-					 WAKE_IRQ_DEDICATED_MANAGED)
+					 WAKE_IRQ_DEDICATED_MANAGED | \
+					 WAKE_IRQ_DEDICATED_LATE_ENABLED)
 
 struct wake_irq {
 	struct device *dev;
@@ -39,7 +41,8 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq);
 extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq);
 extern void dev_pm_enable_wake_irq_check(struct device *dev,
 					 bool can_change_status);
-extern void dev_pm_disable_wake_irq_check(struct device *dev);
+extern void dev_pm_disable_wake_irq_check(struct device *dev, bool skip_enable_late);
+extern void dev_pm_enable_wake_irq_complete(struct device *dev);
 
 #ifdef CONFIG_PM_SLEEP
 
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 8a66eaf731e4..97646aa11376 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -645,6 +645,8 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 	if (retval)
 		goto fail;
 
+	dev_pm_enable_wake_irq_complete(dev);
+
  no_callback:
 	__update_runtime_status(dev, RPM_SUSPENDED);
 	pm_runtime_deactivate_timer(dev);
@@ -690,7 +692,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 	return retval;
 
  fail:
-	dev_pm_disable_wake_irq_check(dev);
+	dev_pm_disable_wake_irq_check(dev, false);
 	__update_runtime_status(dev, RPM_ACTIVE);
 	dev->power.deferred_resume = false;
 	wake_up_all(&dev->power.wait_queue);
@@ -873,7 +875,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
 
 	callback = RPM_GET_CALLBACK(dev, runtime_resume);
 
-	dev_pm_disable_wake_irq_check(dev);
+	dev_pm_disable_wake_irq_check(dev, true);
 	retval = rpm_callback(callback, dev);
 	if (retval) {
 		__update_runtime_status(dev, RPM_SUSPENDED);
diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c
index 3bad3266a2ad..a612f5c26c6c 100644
--- a/drivers/base/power/wakeirq.c
+++ b/drivers/base/power/wakeirq.c
@@ -215,6 +215,24 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
 }
 EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
 
+/**
+ * dev_pm_wake_irq_set_late_enabled_status - set status WAKE_IRQ_DEDICATED_LATE_ENABLED
+ * @dev: Device
+ *
+ * Set the status of WAKE_IRQ_DEDICATED_LATE_ENABLED to tell rpm_suspend()
+ * to enable dedicated wake-up interrupt after invoking the runtime_suspend(),
+ *
+ * Should be called after setting dedicated wake-up interrupt.
+ */
+void dev_pm_wake_irq_set_late_enabled_status(struct device *dev)
+{
+	struct wake_irq *wirq = dev->power.wakeirq;
+
+	if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED))
+		wirq->status |= WAKE_IRQ_DEDICATED_LATE_ENABLED;
+}
+EXPORT_SYMBOL_GPL(dev_pm_wake_irq_set_late_enabled_status);
+
 /**
  * dev_pm_enable_wake_irq - Enable device wake-up interrupt
  * @dev: Device
@@ -285,27 +303,52 @@ void dev_pm_enable_wake_irq_check(struct device *dev,
 	return;
 
 enable:
-	enable_irq(wirq->irq);
+	if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_LATE_ENABLED))
+		enable_irq(wirq->irq);
 }
 
 /**
  * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
  * @dev: Device
+ * @skip_late_enabled_status: skip checking WAKE_IRQ_DEDICATED_LATE_ENABLED
  *
  * Disables wake-up interrupt conditionally based on status.
  * Should be only called from rpm_suspend() and rpm_resume() path.
  */
-void dev_pm_disable_wake_irq_check(struct device *dev)
+void dev_pm_disable_wake_irq_check(struct device *dev, bool skip_late_enabled_status)
 {
 	struct wake_irq *wirq = dev->power.wakeirq;
 
 	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
 		return;
 
-	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
+	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
+	    (skip_late_enabled_status ||
+	     !(wirq->status & WAKE_IRQ_DEDICATED_LATE_ENABLED)))
 		disable_irq_nosync(wirq->irq);
 }
 
+/**
+ * dev_pm_enable_wake_irq_complete - enable wake irq based on status
+ * @dev: Device
+ *
+ * Enable wake-up interrupt conditionally based on status, mainly for
+ * enabling wake-up interrupt after runtime_suspend() is called.
+ *
+ * Should be only called from rpm_suspend() path.
+ */
+void dev_pm_enable_wake_irq_complete(struct device *dev)
+{
+	struct wake_irq *wirq = dev->power.wakeirq;
+
+	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
+		return;
+
+	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
+	    wirq->status & WAKE_IRQ_DEDICATED_LATE_ENABLED)
+		enable_irq(wirq->irq);
+}
+
 /**
  * dev_pm_arm_wake_irq - Arm device wake-up
  * @wirq: Device wake-up interrupt
diff --git a/include/linux/pm_wakeirq.h b/include/linux/pm_wakeirq.h
index cd5b62db9084..92f814d583f8 100644
--- a/include/linux/pm_wakeirq.h
+++ b/include/linux/pm_wakeirq.h
@@ -22,6 +22,7 @@ extern int dev_pm_set_dedicated_wake_irq(struct device *dev,
 extern void dev_pm_clear_wake_irq(struct device *dev);
 extern void dev_pm_enable_wake_irq(struct device *dev);
 extern void dev_pm_disable_wake_irq(struct device *dev);
+extern void dev_pm_wake_irq_set_late_enabled_status(struct device *dev);
 
 #else	/* !CONFIG_PM */
 
@@ -47,5 +48,9 @@ static inline void dev_pm_disable_wake_irq(struct device *dev)
 {
 }
 
+static inline void dev_pm_wake_irq_set_late_enabled_status(struct device *dev)
+{
+}
+
 #endif	/* CONFIG_PM */
 #endif	/* _LINUX_PM_WAKEIRQ_H */
-- 
2.25.1

From chunfeng.yun at mediatek.com  Tue Aug 10 20:04:29 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 11:04:29 +0800
Subject: [PATCH v3 2/2] usb: xhci-mtk: enable wake-up interrupt after
 runtime_suspend called
In-Reply-To: <1628651069-22162-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628651069-22162-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628651069-22162-2-git-send-email-chunfeng.yun@mediatek.com>

Use new function dev_pm_wake_irq_set_late_enabled_status() to enable
dedicated wake-up interrupt after xhci_mtk_runtime_suspend() is called.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: new patch
---
 drivers/usb/host/xhci-mtk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 7ff0cd707ba1..6fb6f6853129 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -611,6 +611,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
 			dev_err(dev, "set wakeup irq %d failed\n", wakeup_irq);
 			goto dealloc_usb3_hcd;
 		}
+		dev_pm_wake_irq_set_late_enabled_status(dev);
 		dev_info(dev, "wakeup irq %d\n", wakeup_irq);
 	}
 
-- 
2.25.1

From anshuman.khandual at arm.com  Tue Aug 10 20:27:07 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 08:57:07 +0530
Subject: [PATCH V2] arm64/perf: Replace '0xf' instances with
 ID_AA64DFR0_PMUVER_IMP_DEF
In-Reply-To: <1628652427-24695-1-git-send-email-anshuman.khandual@arm.com>
References: <1628652427-24695-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628652427-24695-2-git-send-email-anshuman.khandual@arm.com>

ID_AA64DFR0_PMUVER_IMP_DEF which indicate implementation defined PMU, never
actually gets used although there are '0xf' instances scattered all around.
Just do the macro replacement to improve readability.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: linux-perf-users at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.14-rc5

Changes in V2:

- Split out the arm64 part

Changes in V1:

https://lore.kernel.org/linux-perf-users/1628571998-13634-1-git-send-email-anshuman.khandual at arm.com/

 arch/arm64/include/asm/cpufeature.h | 2 +-
 arch/arm64/kernel/perf_event.c      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 9bb9d11750d7..54474e76ad86 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -552,7 +552,7 @@ cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap)
 	u64 mask = GENMASK_ULL(field + 3, field);
 
 	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
-	if (val == 0xf)
+	if (val == ID_AA64DFR0_PMUVER_IMP_DEF)
 		val = 0;
 
 	if (val > cap) {
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index d07788dad388..b4044469527e 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1055,7 +1055,7 @@ static void __armv8pmu_probe_pmu(void *info)
 	dfr0 = read_sysreg(id_aa64dfr0_el1);
 	pmuver = cpuid_feature_extract_unsigned_field(dfr0,
 			ID_AA64DFR0_PMUVER_SHIFT);
-	if (pmuver == 0xf || pmuver == 0)
+	if (pmuver == ID_AA64DFR0_PMUVER_IMP_DEF || pmuver == 0)
 		return;
 
 	cpu_pmu->pmuver = pmuver;
-- 
2.20.1



From anshuman.khandual at arm.com  Tue Aug 10 20:27:06 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 08:57:06 +0530
Subject: [PATCH V2] KVM: arm64: perf: Replace '0xf' instances with
 ID_AA64DFR0_PMUVER_IMP_DEF
Message-ID: <1628652427-24695-1-git-send-email-anshuman.khandual@arm.com>

ID_AA64DFR0_PMUVER_IMP_DEF which indicate implementation defined PMU, never
actually gets used although there are '0xf' instances scattered all around.
Just do the macro replacement to improve readability.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: linux-perf-users at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.14-rc5

Changes in V2:

- Split out the KVM part

Changes in V1:

https://lore.kernel.org/linux-perf-users/1628571998-13634-1-git-send-email-anshuman.khandual at arm.com/

 arch/arm64/kvm/perf.c     | 2 +-
 arch/arm64/kvm/pmu-emul.c | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 151c31fb9860..f9bb3b14130e 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -50,7 +50,7 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
 
 int kvm_perf_init(void)
 {
-	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
+	if (kvm_pmu_probe_pmuver() != ID_AA64DFR0_PMUVER_IMP_DEF && !is_protected_kvm_enabled())
 		static_branch_enable(&kvm_arm_pmu_available);
 
 	return perf_register_guest_info_callbacks(&kvm_guest_cbs);
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index f33825c995cb..60f89bdbeebb 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -745,7 +745,7 @@ int kvm_pmu_probe_pmuver(void)
 	struct perf_event_attr attr = { };
 	struct perf_event *event;
 	struct arm_pmu *pmu;
-	int pmuver = 0xf;
+	int pmuver = ID_AA64DFR0_PMUVER_IMP_DEF;
 
 	/*
 	 * Create a dummy event that only counts user cycles. As we'll never
@@ -770,7 +770,7 @@ int kvm_pmu_probe_pmuver(void)
 	if (IS_ERR(event)) {
 		pr_err_once("kvm: pmu event creation failed %ld\n",
 			    PTR_ERR(event));
-		return 0xf;
+		return ID_AA64DFR0_PMUVER_IMP_DEF;
 	}
 
 	if (event->pmu) {
@@ -923,7 +923,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	if (!vcpu->kvm->arch.pmuver)
 		vcpu->kvm->arch.pmuver = kvm_pmu_probe_pmuver();
 
-	if (vcpu->kvm->arch.pmuver == 0xf)
+	if (vcpu->kvm->arch.pmuver == ID_AA64DFR0_PMUVER_IMP_DEF)
 		return -ENODEV;
 
 	switch (attr->attr) {
-- 
2.20.1



From yt.lee at mediatek.com  Tue Aug 10 20:37:47 2021
From: yt.lee at mediatek.com (YT Lee)
Date: Wed, 11 Aug 2021 11:37:47 +0800
Subject: [PATCH v2 0/2] soc: mediatek: SVS: add mt8195 SVS GPU driver
Message-ID: <20210811033749.30490-1-yt.lee@mediatek.com>

this patch series is based on Linux kernel 5.14-rc1,
it adds SVS GPU support on mt8195 and depends on
"soc: mediatek: SVS: introduce MTK SVS"[1].

[1]http://lists.infradead.org/pipermail/linux-mediatek/2021-July/027128.html

changes since v1:
- Rebase to kernel 5.14-rc1.
- Based on latest svs driver (v20).

YT Lee (2):
  dt-bindings: soc: mediatek: add mt8195 svs dt-bindings
  soc: mediatek: SVS: add mt8195 SVS GPU driver

 .../bindings/soc/mediatek/mtk-svs.yaml        |   1 +
 drivers/soc/mediatek/mtk-svs.c                | 207 ++++++++++++++++++
 2 files changed, 208 insertions(+)

-- 
2.18.0

From yt.lee at mediatek.com  Tue Aug 10 20:37:48 2021
From: yt.lee at mediatek.com (YT Lee)
Date: Wed, 11 Aug 2021 11:37:48 +0800
Subject: [PATCH v2 1/2] dt-bindings: soc: mediatek: add mt8195 svs dt-bindings
In-Reply-To: <20210811033749.30490-1-yt.lee@mediatek.com>
References: <20210811033749.30490-1-yt.lee@mediatek.com>
Message-ID: <20210811033749.30490-2-yt.lee@mediatek.com>

Add new binding documentation of the mt8195 svs.

Signed-off-by: YT Lee <yt.lee at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
index 59342e627b67..fdd656448454 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
@@ -23,6 +23,7 @@ properties:
     enum:
       - mediatek,mt8183-svs
       - mediatek,mt8192-svs
+      - mediatek,mt8195-svs
 
   reg:
     maxItems: 1
-- 
2.18.0

From yt.lee at mediatek.com  Tue Aug 10 20:37:49 2021
From: yt.lee at mediatek.com (YT Lee)
Date: Wed, 11 Aug 2021 11:37:49 +0800
Subject: [PATCH v2 2/2] soc: mediatek: SVS: add mt8195 SVS GPU driver
In-Reply-To: <20210811033749.30490-1-yt.lee@mediatek.com>
References: <20210811033749.30490-1-yt.lee@mediatek.com>
Message-ID: <20210811033749.30490-3-yt.lee@mediatek.com>

To support SVS GPU on mt8195, add corresponding
bank information, platform data and parsing function.

Signed-off-by: YT Lee <yt.lee at mediatek.com>
---
 drivers/soc/mediatek/mtk-svs.c | 207 +++++++++++++++++++++++++++++++++
 1 file changed, 207 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 363f189e6054..732e8d7b4ab7 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -1443,6 +1443,88 @@ static int svs_resource_setup(struct svs_platform *svsp)
 	return 0;
 }
 
+static bool svs_mt8195_efuse_parsing(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct nvmem_cell *cell;
+	u32 idx, i, ft_pgm, vmin, golden_temp;
+
+	for (i = 0; i < svsp->efuse_num; i++)
+		if (svsp->efuse[i])
+			dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
+				 i, svsp->efuse[i]);
+
+	/* Svs efuse parsing */
+	ft_pgm = svsp->efuse[0] & GENMASK(7, 0);
+	vmin = (svsp->efuse[19] >> 4) & GENMASK(1, 0);
+
+	for (idx = 0; idx < svsp->bank_num; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (svsb->sw_id != SVSB_GPU)
+			return false;
+
+		if (vmin == 0x1)
+			svsb->vmin = 0x1e;
+
+		if (ft_pgm == 0)
+			svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
+
+		if (svsb->type == SVSB_LOW) {
+			svsb->mtdes = svsp->efuse[10] & GENMASK(7, 0);
+			svsb->bdes = (svsp->efuse[10] >> 16) & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[10] >> 24) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[8]) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[8] >> 8) & GENMASK(7, 0);
+			svsb->vmax += svsb->dvt_fixed;
+		} else if (svsb->type == SVSB_HIGH) {
+			svsb->mtdes = svsp->efuse[9] & GENMASK(7, 0);
+			svsb->bdes = (svsp->efuse[9] >> 16) & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[9] >> 24) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[8]) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[8] >> 8) & GENMASK(7, 0);
+			svsb->vmax += svsb->dvt_fixed;
+		}
+	}
+
+	/* Thermal efuse parsing */
+	cell = nvmem_cell_get(svsp->dev, "t-calibration-data");
+	if (IS_ERR_OR_NULL(cell)) {
+		dev_err(svsp->dev, "no thermal cell, no mon mode\n");
+		for (idx = 0; idx < svsp->bank_num; idx++) {
+			svsb = &svsp->banks[idx];
+			svsb->mode_support &= ~SVSB_MODE_MON;
+		}
+
+		return true;
+	}
+
+	svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_num);
+	svsp->tefuse_num /= sizeof(u32);
+	nvmem_cell_put(cell);
+
+	for (i = 0; i < svsp->tefuse_num; i++)
+		if (svsp->tefuse[i] != 0)
+			break;
+
+	if (i == svsp->tefuse_num)
+		golden_temp = 50; /* All thermal efuse data are 0 */
+	else
+		golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
+
+	for (idx = 0; idx < svsp->bank_num; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (svsb->sw_id != SVSB_GPU)
+			return false;
+
+		svsb->mts = 500;
+		svsb->bts = (((500 * golden_temp + 250460) / 1000) - 25) * 4;
+	}
+
+	return true;
+}
+
 static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb;
@@ -2080,6 +2162,88 @@ static int svs_create_svs_debug_cmds(struct svs_platform *svsp)
 	return 0;
 }
 
+static struct svs_bank svs_mt8195_banks[] = {
+	{
+		.sw_id			= SVSB_GPU,
+		.set_freqs_pct		= svs_set_freqs_pct_v3,
+		.get_vops		= svs_get_vops_v3,
+		.hw_id			= 0,
+		.tzone_name		= "gpu1",
+		.buck_name		= "mali",
+		.volt_flags		= SVSB_INIT02_RM_DVTFIXED,
+		.mode_support		= SVSB_MODE_INIT02,
+		.opp_count		= 16,
+		.freq_base		= 640000000,
+		.turn_freq_base		= 640000000,
+		.vboot			= 0x38,
+		.volt_step		= 6250,
+		.volt_base		= 400000,
+		.volt_offset		= 0,
+		.vmax			= 0x38,
+		.vmin			= 0x14,
+		.dthi			= 0x1,
+		.dtlo			= 0xfe,
+		.det_window		= 0xa28,
+		.det_max		= 0xffff,
+		.age_config		= 0x555555,
+		.agem			= 0,
+		.dc_config		= 0x1,
+		.dvt_fixed		= 0x1,
+		.vco			= 0x18,
+		.chk_shift		= 0x87,
+		.temp_upper_bound	= 0x64,
+		.temp_lower_bound	= 0xb2,
+		.tzone_high_temp	= 85000,
+		.tzone_high_temp_offset	= 0,
+		.tzone_low_temp		= 25000,
+		.tzone_low_temp_offset	= 7,
+		.core_sel		= 0x0fff0100,
+		.int_st			= BIT(0),
+		.ctl0			= 0x00540003,
+		.type			= SVSB_LOW,
+	},
+	{
+		.sw_id			= SVSB_GPU,
+		.set_freqs_pct		= svs_set_freqs_pct_v3,
+		.get_vops		= svs_get_vops_v3,
+		.hw_id			= 1,
+		.tzone_name		= "gpu1",
+		.buck_name		= "mali",
+		.volt_flags		= SVSB_INIT02_RM_DVTFIXED |
+					  SVSB_MON_VOLT_IGNORE,
+		.mode_support		= SVSB_MODE_INIT02 | SVSB_MODE_MON,
+		.opp_count		= 16,
+		.freq_base		= 880000000,
+		.turn_freq_base		= 640000000,
+		.vboot			= 0x38,
+		.volt_step		= 6250,
+		.volt_base		= 400000,
+		.volt_offset		= 0,
+		.vmax			= 0x38,
+		.vmin			= 0x14,
+		.dthi			= 0x1,
+		.dtlo			= 0xfe,
+		.det_window		= 0xa28,
+		.det_max		= 0xffff,
+		.age_config		= 0x555555,
+		.agem			= 0,
+		.dc_config		= 0x1,
+		.dvt_fixed		= 0x6,
+		.vco			= 0x18,
+		.chk_shift		= 0x87,
+		.temp_upper_bound	= 0x64,
+		.temp_lower_bound	= 0xb2,
+		.tzone_high_temp	= 85000,
+		.tzone_high_temp_offset	= 0,
+		.tzone_low_temp		= 25000,
+		.tzone_low_temp_offset	= 7,
+		.core_sel		= 0x0fff0101,
+		.int_st			= BIT(1),
+		.ctl0			= 0x00540003,
+		.type			= SVSB_HIGH,
+	},
+};
+
 static struct svs_bank svs_mt8192_banks[] = {
 	{
 		.sw_id			= SVSB_GPU,
@@ -2316,6 +2480,46 @@ static struct svs_bank svs_mt8183_banks[] = {
 	},
 };
 
+static int svs_get_svs_mt8195_platform_data(struct svs_platform *svsp)
+{
+	struct device *dev;
+	struct svs_bank *svsb;
+	u32 idx;
+
+	svsp->name = "mt8195-svs";
+	svsp->banks = svs_mt8195_banks;
+	svsp->efuse_parsing = svs_mt8195_efuse_parsing;
+	svsp->regs = svs_regs_v2;
+	svsp->irqflags = IRQF_TRIGGER_HIGH;
+	svsp->bank_num = ARRAY_SIZE(svs_mt8195_banks);
+	svsp->efuse_check = 10;
+
+	svsp->rst = devm_reset_control_get_optional(svsp->dev, "svs_rst");
+	if (IS_ERR(svsp->rst)) {
+		dev_err_probe(svsp->dev, PTR_ERR(svsp->rst),
+			      "cannot get svs reset control\n");
+		return PTR_ERR(svsp->rst);
+	}
+
+	dev = svs_add_device_link(svsp, "lvts");
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	for (idx = 0; idx < svsp->bank_num; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (svsb->type == SVSB_HIGH)
+			svsb->opp_dev = svs_add_device_link(svsp, "mali");
+		else if (svsb->type == SVSB_LOW)
+			svsb->opp_dev = svs_get_subsys_device(svsp, "mali");
+
+		if (IS_ERR(svsb->opp_dev))
+			return PTR_ERR(svsb->opp_dev);
+	}
+
+	return 0;
+}
+
 static int svs_get_svs_mt8192_platform_data(struct svs_platform *svsp)
 {
 	struct device *dev;
@@ -2412,6 +2616,9 @@ static const struct of_device_id mtk_svs_of_match[] = {
 	}, {
 		.compatible = "mediatek,mt8192-svs",
 		.data = &svs_get_svs_mt8192_platform_data,
+	}, {
+		.compatible = "mediatek,mt8195-svs",
+		.data = &svs_get_svs_mt8195_platform_data,
 	}, {
 		/* Sentinel */
 	},
-- 
2.18.0

From chun-jie.chen at mediatek.com  Tue Aug 10 21:31:26 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 11 Aug 2021 12:31:26 +0800
Subject: [PATCH 04/22] clk: mediatek: Add MT8195 basic clocks support
In-Reply-To: <CAGXv+5ETdg+SfLDtbjmSwvjxdAr3+0eWmyPR9+ev=05XdoU7wQ@mail.gmail.com>
References: <20210616224743.5109-1-chun-jie.chen@mediatek.com>
 <20210616224743.5109-5-chun-jie.chen@mediatek.com>
 <CAGXv+5ELvHXE-r-5Y1mugL=y85_oBGXvO4hXG0K9zgaPt_JDZg@mail.gmail.com>
 <1626913060.1546.4.camel@mtksdaap41>
 <CAGXv+5ETdg+SfLDtbjmSwvjxdAr3+0eWmyPR9+ev=05XdoU7wQ@mail.gmail.com>
Message-ID: <d09283c94fa031579002dcf83e97bea34bf0725e.camel@mediatek.com>

On Thu, 2021-07-22 at 15:44 +0800, Chen-Yu Tsai wrote:
> Hi,
> 
> It seems your reply included HTML, which means that it never reached
> the mailing lists. Please always use plaintext only.
> 
> On Thu, Jul 22, 2021 at 08:17:40AM +0800, Chun-Jie Chen wrote:
> > On Fri, 2021-07-02 at 19:44 +0800, Chen-Yu Tsai wrote:
> > > > On Thu, Jun 17, 2021 at 7:05 AM Chun-Jie Chen
> > > > <chun-jie.chen at mediatek.com> wrote:
> > > > > > 
> > > > > > Add MT8195 basic clock providers, include topckgen,
> > > > > > apmixedsys,
> > > > > > infracfg_ao and pericfg_ao.
> > > > > > 
> > > > > > Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > > > > > ---
> > > > > >  drivers/clk/mediatek/Kconfig      |    8 +
> > > > > >  drivers/clk/mediatek/Makefile     |    1 +
> > > > > >  drivers/clk/mediatek/clk-mt8195.c | 1958
> > > > > > +++++++++++++++++++++++++++++
> > > > > >  3 files changed, 1967 insertions(+)
> > > > > >  create mode 100644 drivers/clk/mediatek/clk-mt8195.c
> > > > > > 
> > > > > > diff --git a/drivers/clk/mediatek/Kconfig
> > > > > > b/drivers/clk/mediatek/Kconfig
> > > > > > index 576babd86f98..6707aba3d500 100644
> > > > > > --- a/drivers/clk/mediatek/Kconfig
> > > > > > +++ b/drivers/clk/mediatek/Kconfig
> > > > > > @@ -580,6 +580,14 @@ config COMMON_CLK_MT8192_VENCSYS
> > > > > >         help
> > > > > >           This driver supports MediaTek MT8192 vencsys
> > > > > > clocks.
> > > > > > 
> > > > > > +config COMMON_CLK_MT8195
> > > > > > +       bool "Clock driver for MediaTek MT8195"
> > > > > > +       depends on ARM64 || COMPILE_TEST
> > > > > > +       select COMMON_CLK_MEDIATEK
> > > > > > +       default ARM64
> > > > > > +       help
> > > > > > +         This driver supports MediaTek MT8195 basic
> > > > > > clocks.
> > > > > > +
> > > > > >  config COMMON_CLK_MT8516
> > > > > >         bool "Clock driver for MediaTek MT8516"
> > > > > >         depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > > > diff --git a/drivers/clk/mediatek/Makefile
> > > > > > b/drivers/clk/mediatek/Makefile
> > > > > > index 15bc045f0b71..f8002d8966e1 100644
> > > > > > --- a/drivers/clk/mediatek/Makefile
> > > > > > +++ b/drivers/clk/mediatek/Makefile
> > > > > > @@ -80,5 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) +=
> > > > > > clk-
> > > > > > mt8192-msdc.o
> > > > > >  obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) +=
> > > > 
> > > > clk-mt8192-scp_adsp.o
> > > > > >  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-
> > > > > > vdec.o
> > > > > >  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-
> > > > > > venc.o
> > > > > > +obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195.o
> > > > > >  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
> > > > > >  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> > > > > > diff --git a/drivers/clk/mediatek/clk-mt8195.c
> > > > > > b/drivers/clk/mediatek/clk-mt8195.c
> > > > > > new file mode 100644
> > > > > > index 000000000000..aea9ebe4c051
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/clk/mediatek/clk-mt8195.c
> > > > > > @@ -0,0 +1,1958 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > > +//
> > > > > > +// Copyright (c) 2021 MediaTek Inc.
> > > > > > +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > > > > > +
> > > > > > +#include <linux/clk.h>
> > > > > > +#include <linux/delay.h>
> > > > > > +#include <linux/mfd/syscon.h>
> > > > > > +#include <linux/of.h>
> > > > > > +#include <linux/of_address.h>
> > > > > > +#include <linux/of_device.h>
> > > > > > +#include <linux/platform_device.h>
> > > > > > +#include <linux/slab.h>
> > > > > > +
> > > > > > +#include "clk-mtk.h"
> > > > > > +#include "clk-mux.h"
> > > > > > +#include "clk-gate.h"
> > > > > > +
> > > > > > +#include <dt-bindings/clock/mt8195-clk.h>
> > > > > > +
> > > > > > +static DEFINE_SPINLOCK(mt8195_clk_lock);
> > > > > > +
> > > > > > +static const struct mtk_fixed_clk top_fixed_clks[] = {
> > > > > > +       FIXED_CLK(CLK_TOP_IN_DGI, "in_dgi", NULL,
> > > > > > 165000000),
> > > > > > +       FIXED_CLK(CLK_TOP_ULPOSC, "ulposc", NULL,
> > > > > > 248000000),
> > > > > > +       FIXED_CLK(CLK_TOP_ULPOSC2, "ulposc2", NULL,
> > > > > > 326000000),
> > > > > > +       FIXED_CLK(CLK_TOP_MEM_466M, "mem_466m", NULL,
> > > > 
> > > > 533000000),
> > > > > > +       FIXED_CLK(CLK_TOP_MPHONE_SLAVE_B, "mphone_slave_b",
> > > > 
> > > > NULL,
> > > > > > 49152000),
> > > > > > +       FIXED_CLK(CLK_TOP_PEXTP_PIPE, "pextp_pipe", NULL,
> > > > > > 250000000),
> > > > > > +       FIXED_CLK(CLK_TOP_UFS_RX_SYMBOL, "ufs_rx_symbol",
> > > > > > NULL,
> > > > > > 166000000),
> > > > > > +       FIXED_CLK(CLK_TOP_UFS_TX_SYMBOL, "ufs_tx_symbol",
> > > > > > NULL,
> > > > > > 166000000),
> > > > > > +       FIXED_CLK(CLK_TOP_SSUSB_U3PHY_P1_P_P0,
> > > > > > "ssusb_u3phy_p1_p_p0", NULL, 131000000),
> > > > > > +       FIXED_CLK(CLK_TOP_UFS_RX_SYMBOL1, "ufs_rx_symbol1",
> > > > 
> > > > NULL,
> > > > > > 166000000),
> > > > > > +       FIXED_CLK(CLK_TOP_FPC, "fpc", NULL, 50000000),
> > > > > > +       FIXED_CLK(CLK_TOP_HDMIRX_P, "hdmirx_p", NULL,
> > > > 
> > > > 594000000),
> > > > 
> > > > I assume these are fixed PLLs? They should have inputs
> > > > (parents).
> > > > 
> > > > Moreover, at least ULPOSC and ULPOSC2 look like they are in
> > > > APMIXEDSYS
> > > > 
> > 
> > The clock in top_fixed_clks is special clock that generated from
> > the
> > specific hardware block, not PLLs in APMIXEDSYS. ULPOSC and ULPOSC2
> > has
> > configuration register in APMIXEDSYS, but their clock source are
> > not
> > "clk26m" (other plls in APMIXEDSYS in is generated from "clk26m")
> 
> I see. Surely they have some input though. It would be nice to be
> able
> to have them described.
> 
> > > > > > +};T
> > > > > > +
> > > > > > +static const struct mtk_fixed_factor top_early_divs[] = {
> > > > > > +       FACTOR(CLK_TOP_CLK26M_D2, "clk26m_d2", "clk26m", 1,
> > > > > > 2),
> > > > > > +};
> > > > > > +
> > > > > > +static const struct mtk_fixed_factor top_divs[] = {
> > > > > > +       FACTOR(CLK_TOP_CLK26M_D52, "clk26m_d52", "clk26m",
> > > > > > 1,
> > > > 
> > > > 52),
> > > > > > +       FACTOR(CLK_TOP_IN_DGI_D2, "in_dgi_d2", "in_dgi", 1,
> > > > > > 2),
> > > > > > +       FACTOR(CLK_TOP_IN_DGI_D4, "in_dgi_d4", "in_dgi", 1,
> > > > > > 4),
> > > > > > +       FACTOR(CLK_TOP_IN_DGI_D6, "in_dgi_d6", "in_dgi", 1,
> > > > > > 6),
> > > > > > +       FACTOR(CLK_TOP_IN_DGI_D8, "in_dgi_d8", "in_dgi", 1,
> > > > > > 8),
> > > > > > +       FACTOR(CLK_TOP_MFGPLL_OPP, "mfgpll_opp", "mfgpll",
> > > > > > 1,
> > > > 
> > > > 1),
> > > > > > +       FACTOR(CLK_TOP_MAINPLL, "mainpll_ck", "mainpll", 1,
> > > > > > 1),
> > > > 
> > > > Why are this and other 1:1 factor clks needed? They look like
> > > > placeholders.
> > > > Please remove them.
> > 
> > 
> > 
> > These 1:1 factors make more readable between dividers. For example,
> > CLK_APMIXED_MAINPLL and CLK_TOP_MAINPLL_D3 is not easy to see the
> > relation, but CLK_TOP_MAINPLL and CLK_TOP_MAINPLL_D3 is more clear
> > to
> > see the relation.
> 
> If the clocks are named appropriately, it should be clear that
> "mainpll_dX"
> is derived from "mainpll". We really don't need an extra "mainpll_ck"
> in
> between.
> 
> The only thing gained here is having the parent clock in the same
> driver.
> But that is only a problem because we are directly using global clock
> names
> for parent names. This isn't the preferred way for clock parenting.
> 
> For proper parenting, the driver should be using `struct
> clk_parent_data`
> if possible, or using of_clk_get_parent_name() or of_clk_get_hw()
> manually
> to get the parent's global name or a reference to it. This is
> something
> the clk drivers should slowly be converted to doing.
> 
> I'm not saying we should do everything now, but we can start by
> getting
> rid of some of the excess baggage.
> 
> [...]

Ok, I will remove the 1-to-1 divider in next version.
Thanks for your comment.

> 
> > > > > > +static const char * const dsp7_parents[] = {
> > > > > > +       "clk26m",
> > > > > > +       "univpll_d6_d2",
> > > > > > +       "univpll_d4_d2",
> > > > > > +       "univpll_d5",
> > > > > > +       "univpll_d4",
> > > > > > +       "mmpll_d4",
> > > > > > +       "mainpll_d3",
> > > > > > +       "univpll_d3"
> > > > > > +};
> > > > 
> > > > If dsp~dsp7_parents are all the same, please merge them and
> > > > share
> > > 
> > > one
> > > > instance. And since they are located a bit far from the clock
> > > > definitions
> > > > in this file, please add comments describing which clocks share
> > > > the
> > > > same
> > > > set of parents.
> > > > 
> > 
> > I will merge it if they can share the same parent source data
> > (include
> > you mention below), thanks for your comment.
> 
> Great!
> 
> [...]
> 
> Tip: You can trim out portions of the original email from your reply,
> like
> what I did here, so that the emails are shorter. Keeping just the
> bits that
> are relevant to the discussion is better for the reader. In cases
> here a
> lot of it are related cases, you could keep just the one nearest to
> your
> reply.
> 
> > > > > > +static const char * const spinor_parents[] = {
> > > > > > +       "clk26m",
> > > > 
> > > > Datasheet says first parent is "univpll_d5_d8". Please check
> > > > with
> > > > hardware
> > > > engineers. If the datasheet is wrong please add a comment
> > > > saying so.
> > > > 
> > > 
> > > 
> > > > > > +       "clk26m_d2",
> > > > > > +       "mainpll_d7_d8",
> > > > > > +       "univpll_d6_d8"
> > > > > > +};
> > > > > > +
> > 
> > The parent source here is correct, but not update to the latest in
> > datasheet.
> 
> For future reference, could you leave a comment stating that the
> datasheet
> has not been updated then? Please include the version of the
> datasheet.
> 

The parent source here was updated at v25 internal version.

> > > > > > +static const char * const dvio_dgi_ref_parents[] = {
> > > > > > +       "clk26m",
> > > > > > +       "in_dgi",
> > > > > > +       "in_dgi_d2",
> > > > > > +       "in_dgi_d4",
> > > > > > +       "in_dgi_d6",
> > > > > > +       "in_dgi_d8",
> > > > > > +       "mmpll_d4_d4"
> > > > > > +};
> > > > > > +
> > > > > > +static const char * const srck_parents[] = {
> > > > > > +       "ulposc_d10",
> > > > > > +       "clk26m"
> > > > > > +};
> > > > > > +
> > > > > > +static const char * const rsvd1_parents[] = {
> > > > > > +       "clk26m",
> > > > > > +       "mainpll_d4_d4",
> > > > > > +       "mainpll_d5_d4",
> > > > > > +       "mainpll_d6_d4",
> > > > > > +       "mainpll_d7_d4",
> > > > > > +       "univpll_d6_d4",
> > > > 
> > > > These are completely different from the datasheet. Please
> > > > check.
> > > > 
> > > 
> > > 
> > > > > > +       "ulposc",
> > > > > > +       "ulposc2"
> > > > > > +};
> > > > > > +
> > 
> > The parent source here is correct, but not update to the latest in
> > datasheet.
> 
> Same for this one.
> 

The parent source here was updated at v25 internal version.

> > > > > > +static const char * const mfg_fast_parents[] = {
> > > > > > +       "mfg_sel",
> > > > > > +       "mfgpll_opp"
> > > > > > +};
> > > > > > +
> > > > > > +static const struct mtk_mux top_mtk_muxes[] = {
> > > > > > +       /* CLK_CFG_0 */
> > > > > > +       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_SEL,
> > > > > > "axi_sel",
> > > > 
> > > > Please drop the "_sel" suffix from the clock names. It would
> > > > have
> > > > made
> > > > sense if this were purely a mux, and there was another clock
> > > > gate.
> > > > But
> > > > since the driver combines the two components into one
> > > 
> > > representation,
> > > > please just drop the suffix that implies just a mux. This goes
> > > > for
> > > > all
> > > > clocks in the series and also the macro bindings.
> > 
> > 
> > 
> > If we move the "_sel" suffix from clock names, it's hard to
> > represent
> > this mux with gate control. Do you think revise it to
> > "XXX_sel_gate" in
> > CCF name but keep the binding name because change the binding name
> > need
> > all CCF consumer changes.
> 
> Please elaborate. Does the "type" of the clock matter? All that is
> really needed is that the name is unique, matches the datasheet more
> or
> less, and describes the usage or purpose of the clock.
> 
> For example, on Allwinner sunxi platforms, we don't include the type
> of the clock in the clock names. Only the base clock name is used.
> That is because the clocks are modeled as composite-ish clocks, so
> only one clock is needed to describe a full mux+divider+gate.
> 
> On other platforms, the clock driver deliberately uses base clock
> types,
> mux, div, and gate, to build up a representation of the full clock
> unit.
> In these cases, we end up with "XXX_mux", "XXX_div", and "XXX_gate".
> 
> Since the Mediatek clock driver is more like the first case, I would
> prefer to see clock names with just the base name, and none of the
> typing.
> 
> And regarding binding names, please change them as well. Right now
> the
> only place that needs to be changed are the header files. This is the
> time to get them right.
> 

Ok, I will remove suffix "_SEL" in binding name and change
clock name from "xxx_sel" to "top_xxx".
Thanks for your comment.

> > > > > > +               axi_parents, 0x020, 0x024, 0x028, 0, 3, 7,
> > > > > > 0x04,
> > > > 
> > > > 0,
> > > > > > CLK_IS_CRITICAL),
> > > > > > +       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM_SEL,
> > > > > > "spm_sel",
> > > > > > +               spm_parents, 0x020, 0x024, 0x028, 8, 2, 15,
> > > > 
> > > > 0x04,
> > > > > > 1, CLK_IS_CRITICAL),
> > > > 
> > > > Where is the SCP clock?
> > 
> > 
> > 
> > Because SCP is always on and no other clock gates need to reference
> > it,
> > so move it.
> 
> Please add a comment as a placeholder then. The comment could simply
> state "clock is always on and should not be handled by Linux".
> 
> [...]
> 

Ok, I will leave some comment to describe why skip or why make is
critical in next version.

> > > > > > +       /* CLK_CFG_11 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_SEL, "usb_sel",
> > > > 
> > > > The datasheet lists these as "usb_top" and "usb_top_Xp". Please
> > > > keep
> > > > the name
> > > > the same as the datasheet so it is easy to search for. Also
> > > > note the
> > > > discrepency
> > > > between the macro name and the clock name. Same goes for the
> > > > three
> > > > other USB
> > > > clocks.
> > 
> > 
> > 
> > Do you think revise the name the same as datasheet in CCF name but
> > keep
> > binding name?
> 
> Please have them match each other. The whole point of keeping names
> consistent is to be able to search for them easily.
> 

Ok, I will revise the clock name which can match in datasheet.

> > > > 
> > > 
> > > 
> > > > > > +               usb_parents, 0x0A4, 0x0A8, 0x0AC, 0, 2, 7,
> > > > > > 0x08,
> > > > > > 12),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_SEL,
> > > > > > "ssusb_xhci_sel",
> > > > > > +               ssusb_xhci_parents, 0x0A4, 0x0A8, 0x0AC, 8,
> > > > > > 2,
> > > > 
> > > > 15,
> > > > > > 0x08, 13),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_1P_SEL,
> > > > > > "usb_1p_sel",
> > > > > > +               usb_1p_parents, 0x0A4, 0x0A8, 0x0AC, 16, 2,
> > > > > > 23,
> > > > > > 0x08, 14),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_1P_SEL,
> > > > > > "ssusb_xhci_1p_sel",
> > > > > > +               ssusb_xhci_1p_parents, 0x0A4, 0x0A8, 0x0AC,
> > > > > > 24,
> > > > 
> > > > 2,
> > > > > > 31, 0x08, 15),
> > > > > > +       /* CLK_CFG_12 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_2P_SEL,
> > > > > > "usb_2p_sel",
> > > > > > +               usb_2p_parents, 0x0B0, 0x0B4, 0x0B8, 0, 2,
> > > > > > 7,
> > > > 
> > > > 0x08,
> > > > > > 16),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_2P_SEL,
> > > > > > "ssusb_xhci_2p_sel",
> > > > > > +               ssusb_xhci_2p_parents, 0x0B0, 0x0B4, 0x0B8,
> > > > > > 8,
> > > > 
> > > > 2,
> > > > > > 15, 0x08, 17),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_3P_SEL,
> > > > > > "usb_3p_sel",
> > > > > > +               usb_3p_parents, 0x0B0, 0x0B4, 0x0B8, 16, 2,
> > > > > > 23,
> > > > > > 0x08, 18),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_3P_SEL,
> > > > > > "ssusb_xhci_3p_sel",
> > > > > > +               ssusb_xhci_3p_parents, 0x0B0, 0x0B4, 0x0B8,
> > > > > > 24,
> > > > 
> > > > 2,
> > > > > > 31, 0x08, 19),
> > > > > > +       /* CLK_CFG_13 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel",
> > > > > > +               i2c_parents, 0x0BC, 0x0C0, 0x0C4, 0, 2, 7,
> > > > > > 0x08,
> > > > > > 20),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF_SEL,
> > > > > > "seninf_sel",
> > > > > > +               seninf_parents, 0x0BC, 0x0C0, 0x0C4, 8, 3,
> > > > > > 15,
> > > > > > 0x08, 21),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1_SEL,
> > > > 
> > > > "seninf1_sel",
> > > > > > +               seninf1_parents, 0x0BC, 0x0C0, 0x0C4, 16,
> > > > > > 3, 23,
> > > > > > 0x08, 22),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2_SEL,
> > > > 
> > > > "seninf2_sel",
> > > > > > +               seninf2_parents, 0x0BC, 0x0C0, 0x0C4, 24,
> > > > > > 3, 31,
> > > > > > 0x08, 23),
> > > > > > +       /* CLK_CFG_14 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF3_SEL,
> > > > 
> > > > "seninf3_sel",
> > > > > > +               seninf3_parents, 0x0C8, 0x0CC, 0x0D0, 0, 3,
> > > > > > 7,
> > > > > > 0x08, 24),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_GCPU_SEL, "gcpu_sel",
> > > > > > +               gcpu_parents, 0x0C8, 0x0CC, 0x0D0, 8, 3,
> > > > > > 15,
> > > > 
> > > > 0x08,
> > > > > > 25),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC_SEL, "dxcc_sel",
> > > > > > +               dxcc_parents, 0x0C8, 0x0CC, 0x0D0, 16, 2,
> > > > > > 23,
> > > > 
> > > > 0x08,
> > > > > > 26),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPMAIF_SEL,
> > > > > > "dpmaif_sel",
> > > > > > +               dpmaif_parents, 0x0C8, 0x0CC, 0x0D0, 24, 3,
> > > > > > 31,
> > > > > > 0x08, 27),
> > > > > > +       /* CLK_CFG_15 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_UFSFDE_SEL,
> > > > > > "aes_ufsfde_sel",
> > > > > > +               aes_ufsfde_parents, 0x0D4, 0x0D8, 0x0DC, 0,
> > > > > > 3,
> > > > 
> > > > 7,
> > > > > > 0x08, 28),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS_SEL, "ufs_sel",
> > > > > > +               ufs_parents, 0x0D4, 0x0D8, 0x0DC, 8, 3, 15,
> > > > 
> > > > 0x08,
> > > > > > 29),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS_TICK1US_SEL,
> > > > > > "ufs_tick1us_sel",
> > > > > > +               ufs_tick1us_parents, 0x0D4, 0x0D8, 0x0DC,
> > > > > > 16, 1,
> > > > > > 23, 0x08, 30),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS_MP_SAP_SEL,
> > > > > > "ufs_mp_sap_sel",
> > > > > > +               ufs_mp_sap_parents, 0x0D4, 0x0D8, 0x0DC,
> > > > > > 24, 1,
> > > > 
> > > > 31,
> > > > > > 0x08, 31),
> > > > > > +       /* CLK_CFG_16 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_VENC_SEL, "venc_sel",
> > > > > > +               venc_parents, 0x0E0, 0x0E4, 0x0E8, 0, 4, 7,
> > > > 
> > > > 0x0C,
> > > > > > 0),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC_SEL, "vdec_sel",
> > > > > > +               vdec_parents, 0x0E0, 0x0E4, 0x0E8, 8, 4,
> > > > > > 15,
> > > > 
> > > > 0x0C,
> > > > > > 1),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel",
> > > > > > +               pwm_parents, 0x0E0, 0x0E4, 0x0E8, 16, 1,
> > > > > > 23,
> > > > 
> > > > 0x0C,
> > > > > > 2),
> > > > 
> > > > MCU clock? Not sure what it's supposed to be called since the
> > > > naming
> > > > has a
> > > > slightly different format.
> > > > 
> > > > If you are skipping clocks, please leave a comment in the list
> > > > explaining
> > > > why.
> > > > 
> > > 
> > > "mcupm" is another micro-processor and is always on, and no
> > > others
> > > clock gates need to reference it, so remove it.
> 
> Please add a comment, just like in the SCP clock case.
> 
> > > > > > +       /* CLK_CFG_17 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_P_MST_SEL,
> > > > > > "spmi_p_mst_sel",
> > > > > > +               spmi_p_mst_parents, 0x0EC, 0x0F0, 0x0F4, 0,
> > > > > > 4,
> > > > 
> > > > 7,
> > > > > > 0x0C, 4),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_M_MST_SEL,
> > > > > > "spmi_m_mst_sel",
> > > > > > +               spmi_m_mst_parents, 0x0EC, 0x0F0, 0x0F4, 8,
> > > > > > 4,
> > > > 
> > > > 15,
> > > > > > 0x0C, 5),
> > > > 
> > > > DVFSRC clock?
> > > > 
> > > 
> > > "DVFSRC" IP block is always on  and no others clock gates need to
> > > reference it, so remove it.
> 
> This one as well.
> 
> [...]
> 
> > > > > > +       /* CLK_CFG_24 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_APLL5_SEL,
> > > > > > "apll5_sel",
> > > > > > +               apll5_parents, 0x0140, 0x0144, 0x0148, 0,
> > > > > > 1, 7,
> > > > > > 0x010, 0),
> > > > 
> > > > For the APLLs, you will need to differentiate them from the
> > > > actual
> > > > PLLs in
> > > > the APMIXEDSYS block.
> > > > 
> > > 
> > > APLLX providers more precise clock so it has more configuration
> > > register, but it still has same control flow like other PLLs in
> > > APMIXEDSYS.
> 
> I think what I meant was, because I asked to remove the "_sel"
> suffix,
> the global clock names here now collide with the ones in APMIXEDSYS.
> So what I was asking was the names here need to be changed, maybe to
> something like "top_apllX".
> 
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2SO1_M_SEL,
> > > > 
> > > > "i2so1_m_sel",
> > > > > > +               i2so1_m_parents, 0x0140, 0x0144, 0x0148, 8,
> > > > > > 3,
> > > > 
> > > > 15,
> > > > > > 0x010, 1),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2SO2_M_SEL,
> > > > 
> > > > "i2so2_m_sel",
> > > > > > +               i2so2_m_parents, 0x0140, 0x0144, 0x0148,
> > > > > > 16, 3,
> > > > 
> > > > 23,
> > > > > > 0x010, 2),
> > > > 
> > > > I2SO4_M?
> > > > 
> > > 
> > > 
> > > > > > +       /* CLK_CFG_25 */
> > > > 
> > > > I2SO5_M?
> > > > 
> > > 
> > > 
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2SI1_M_SEL,
> > > > 
> > > > "i2si1_m_sel",
> > > > > > +               i2si1_m_parents, 0x014C, 0x0150, 0x0154, 8,
> > > > > > 3,
> > > > 
> > > > 15,
> > > > > > 0x010, 5),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2SI2_M_SEL,
> > > > 
> > > > "i2si2_m_sel",
> > > > > > +               i2si2_m_parents, 0x014C, 0x0150, 0x0154,
> > > > > > 16, 3,
> > > > 
> > > > 23,
> > > > > > 0x010, 6),
> > > > 
> > > > I2SI4_M?
> > > > 
> > > 
> > > 
> > > > > > +       /* CLK_CFG_26 */
> > > > 
> > > > I2SI5_M?
> > > > 
> > > 
> > > I2SO4/I2SO5/I2SI4_M/I2SI5_M is not used in MT8195, so remove it
> > > here.
> 
> Please add comments as placeholders for them. The comment could state
> that the clock is unused in the hardware design, so it was skipped.
> 
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPTX_M_SEL,
> > > > > > "dptx_m_sel",
> > > > > > +               dptx_m_parents, 0x0158, 0x015C, 0x0160, 8,
> > > > > > 3,
> > > > 
> > > > 15,
> > > > > > 0x010, 9),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_IEC_SEL,
> > > > 
> > > > "aud_iec_sel",
> > > > > > +               aud_iec_parents, 0x0158, 0x015C, 0x0160,
> > > > > > 16, 3,
> > > > 
> > > > 23,
> > > > > > 0x010, 10),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_HP_SEL,
> > > > 
> > > > "a1sys_hp_sel",
> > > > > > +               a1sys_hp_parents, 0x0158, 0x015C, 0x0160,
> > > > > > 24, 1,
> > > > > > 31, 0x010, 11),
> > > > > > +       /* CLK_CFG_27 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_A2SYS_SEL,
> > > > > > "a2sys_sel",
> > > > > > +               a2sys_parents, 0x0164, 0x0168, 0x016C, 0,
> > > > > > 1, 7,
> > > > > > 0x010, 12),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_A3SYS_SEL,
> > > > > > "a3sys_sel",
> > > > > > +               a3sys_parents, 0x0164, 0x0168, 0x016C, 8,
> > > > > > 3, 15,
> > > > > > 0x010, 13),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_A4SYS_SEL,
> > > > > > "a4sys_sel",
> > > > > > +               a4sys_parents, 0x0164, 0x0168, 0x016C, 16,
> > > > > > 3,
> > > > 
> > > > 23,
> > > > > > 0x010, 14),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_B_SEL,
> > > > 
> > > > "spinfi_b_sel",
> > > > > > +               spinfi_b_parents, 0x0164, 0x0168, 0x016C,
> > > > > > 24, 3,
> > > > > > 31, 0x010, 15),
> > > > > > +       /* CLK_CFG_28 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL,
> > > > > > "nfi1x_sel",
> > > > > > +               nfi1x_parents, 0x0170, 0x0174, 0x0178, 0,
> > > > > > 3, 7,
> > > > > > 0x010, 16),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_ECC_SEL, "ecc_sel",
> > > > > > +               ecc_parents, 0x0170, 0x0174, 0x0178, 8, 3,
> > > > > > 15,
> > > > > > 0x010, 17),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_LOCAL_BUS_SEL,
> > > > > > "audio_local_bus_sel",
> > > > > > +               audio_local_bus_parents, 0x0170, 0x0174,
> > > > > > 0x0178,
> > > > > > 16, 4, 23, 0x010, 18),
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINOR_SEL,
> > > > > > "spinor_sel",
> > > > > > +               spinor_parents, 0x0170, 0x0174, 0x0178, 24,
> > > > > > 2,
> > > > 
> > > > 31,
> > > > > > 0x010, 19),
> > > > > > +       /* CLK_CFG_29 */
> > > > > > +       MUX_GATE_CLR_SET_UPD(CLK_TOP_DVIO_DGI_REF_SEL,
> > > > > > "dvio_dgi_ref_sel",
> > > > > > +               dvio_dgi_ref_parents, 0x017C, 0x0180,
> > > > > > 0x0184, 0,
> > > > 
> > > > 3,
> > > > > > 7, 0x010, 20),
> > > > 
> > > > ULPOSC and ULPOSC_CORE?
> > > > 
> > 
> > 
> > 
> > ULPOSC and ULPOSC_CORE is always on and no other clock gate needs
> > to
> > reference it, so just remove it.
> 
> Please add placeholder comments describing them, specifically why
> they
> are missing from the driver. Are the clocks used at all in the
> hardware
> design? If so then it might be better to add them to the clock
> driver.
> 
> Also, even if they, including SCP and MCU above, are always on, it
> might
> still be nice to have driver support for them, just to be able to
> read
> their state from Linux. We could have CLK_IS_CRITICAL set so they
> don't
> get disabled, and CLK_GET_RATE_NOCACHE if the clocks are expected to
> be
> changed by firmware running alongside of Linux.
> 
> > > > > > +       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SRCK_SEL,
> > > > 
> > > > "srck_sel",
> > > > > > +               srck_parents, 0x017C, 0x0180, 0x0184, 24,
> > > > > > 1, 31,
> > > > > > 0x010, 23, CLK_IS_CRITICAL),
> > > > 
> > > > What happened to CLK_CFG_30~36?
> > > > 
> > 
> > The muxes in CLK_CFG_30 ~ 36 are not used, so just remove it from
> > CCF.
> 
> Please add placeholder comments about them.
> 
> > > > > > +       /* CLK_CFG_37 */
> > > > > > +       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_RSVD1_SEL,
> > > > 
> > > > "rsvd1_sel",
> > > > > > +               rsvd1_parents, 0x01DC, 0x01E0, 0x01E4, 0,
> > > > > > 3, 7,
> > > > > > 0x014, 20, CLK_IS_CRITICAL),
> > > > 
> > > > What about the other three?
> > > > 
> > 
> > 
> > "rsvd2" and "rsvd3" is not used, so remove it.
> 
> Same here.
> 
> To be honest, a "rsvd", which I interpret as "reserved", clock being
> used seems kind of contradicting. Do we know what hardware is using
> rsvd1?
> 
> > > > > > +};
> > > > > > +
> > > > > > +static struct mtk_composite top_muxes[] = {
> > > > > > +       /* CLK_MISC_CFG_3 */
> > > > > > +       MUX(CLK_TOP_MFG_FAST_SEL, "mfg_fast_sel",
> > > > 
> > > > mfg_fast_parents,
> > > > > > 0x0250, 8, 1),
> > > > > > +};
> > > > > > +
> > > > > > +static const struct mtk_composite top_adj_divs[] = {
> > > > > > +       DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0",
> > > > 
> > > > "i2si1_m_sel",
> > > > > > 0x0320, 0, 0x0328, 8, 0),
> > > > > > +       DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1",
> > > > 
> > > > "i2si2_m_sel",
> > > > > > 0x0320, 1, 0x0328, 8, 8),
> > > > > > +       DIV_GATE(CLK_TOP_APLL12_DIV2, "apll12_div2",
> > > > 
> > > > "i2so1_m_sel",
> > > > > > 0x0320, 2, 0x0328, 8, 16),
> > > > > > +       DIV_GATE(CLK_TOP_APLL12_DIV3, "apll12_div3",
> > > > 
> > > > "i2so2_m_sel",
> > > > > > 0x0320, 3, 0x0328, 8, 24),
> > > > > > +       DIV_GATE(CLK_TOP_APLL12_DIV4, "apll12_div4",
> > > > 
> > > > "aud_iec_sel",
> > > > > > 0x0320, 4, 0x0334, 8, 0),
> > > > 
> > > > What about 5~8?
> > > > 
> > > 
> > > div5 ~ 8 are not used in MT8195, so remove it.
> 
> Placeholder comments please.
> 
> [...]
> 
> > > > > > +static const struct mtk_gate_regs top0_cg_regs = {
> > > > > > +       .set_ofs = 0x238,
> > > > > > +       .clr_ofs = 0x238,
> > > > > > +       .sta_ofs = 0x238,
> > > > > > +};
> > > > > > +
> > > > > > +static const struct mtk_gate_regs top1_cg_regs = {
> > > > > > +       .set_ofs = 0x250,
> > > > > > +       .clr_ofs = 0x250,
> > > > > > +       .sta_ofs = 0x250,
> > > > > > +};
> > > > > > +
> > > > > > +#define GATE_TOP0_FLAGS(_id, _name, _parent, _shift,
> > > > > > _flag)            \
> > > > > > +       GATE_MTK_FLAGS(_id, _name, _parent, &top0_cg_regs,
> > > > > > _shift,      \
> > > > > > +               &mtk_clk_gate_ops_no_setclr_inv, _flag)
> > > > > > +
> > > > > > +#define GATE_TOP0(_id, _name, _parent,
> > > > 
> > > > _shift)                 \
> > > > > > +       GATE_TOP0_FLAGS(_id, _name, _parent, _shift, 0)
> > > > > > +
> > > > > > +#define GATE_TOP1(_id, _name, _parent,
> > > > 
> > > > _shift)                 \
> > > > > > +       GATE_MTK(_id, _name, _parent, &top1_cg_regs,
> > > > > > _shift,
> > > > > > &mtk_clk_gate_ops_no_setclr_inv)
> > > > > > +
> > > > > > +static const struct mtk_gate top_clks[] = {
> > > > > > +       /* TOP0 */
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_VPP0, "cfg_vpp0", "vpp_sel",
> > > > > > 0),
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_VPP1, "cfg_vpp1", "vpp_sel",
> > > > > > 1),
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_VDO0, "cfg_vdo0", "vpp_sel",
> > > > > > 2),
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_VDO1, "cfg_vdo1", "vpp_sel",
> > > > > > 3),
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_UNIPLL_SES, "cfg_unipll_ses",
> > > > > > "univpll_d2", 4),
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_26M_VPP0, "cfg_26m_vpp0",
> > > > 
> > > > "clk26m",
> > > > > > 5),
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_26M_VPP1, "cfg_26m_vpp1",
> > > > 
> > > > "clk26m",
> > > > > > 6),
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_26M_AUD, "cfg_26m_aud",
> > > > > > "clk26m",
> > > > 
> > > > 9),
> > > > > > +       GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_EAST,
> > > > > > "cfg_axi_east",
> > > > > > "axi_sel", 10, CLK_IS_CRITICAL),
> > > > > > +       GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_EAST_NORTH,
> > > > > > "cfg_axi_east_north", "axi_sel", 11,
> > > > > > +               CLK_IS_CRITICAL),
> > > > > > +       GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_NORTH,
> > > > > > "cfg_axi_north",
> > > > > > "axi_sel", 12, CLK_IS_CRITICAL),
> > > > > > +       GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_SOUTH,
> > > > > > "cfg_axi_south",
> > > > > > "axi_sel", 13, CLK_IS_CRITICAL),
> > > > > > +       GATE_TOP0(CLK_TOP_CFG_EXT_TEST, "cfg_ext_test",
> > > > > > "msdcpll_d2", 15),
> > > > > > +       /* TOP1 */
> > > > > > +       GATE_TOP1(CLK_TOP_SSUSB_REF, "ssusb_ref", "clk26m",
> > > > > > 0),
> > > > > > +       GATE_TOP1(CLK_TOP_SSUSB_PHY_REF, "ssusb_phy_ref",
> > > > 
> > > > "clk26m",
> > > > > > 1),
> > > > > > +       GATE_TOP1(CLK_TOP_SSUSB_P1_REF, "ssusb_p1_ref",
> > > > 
> > > > "clk26m",
> > > > > > 2),
> > > > > > +       GATE_TOP1(CLK_TOP_SSUSB_PHY_P1_REF,
> > > > > > "ssusb_phy_p1_ref",
> > > > > > "clk26m", 3),
> > > > > > +       GATE_TOP1(CLK_TOP_SSUSB_P2_REF, "ssusb_p2_ref",
> > > > 
> > > > "clk26m",
> > > > > > 4),
> > > > > > +       GATE_TOP1(CLK_TOP_SSUSB_PHY_P2_REF,
> > > > > > "ssusb_phy_p2_ref",
> > > > > > "clk26m", 5),
> > > > > > +       GATE_TOP1(CLK_TOP_SSUSB_P3_REF, "ssusb_p3_ref",
> > > > 
> > > > "clk26m",
> > > > > > 6),
> > > > > > +       GATE_TOP1(CLK_TOP_SSUSB_PHY_P3_REF,
> > > > > > "ssusb_phy_p3_ref",
> > > > > > "clk26m", 7),
> > > > > > +};
> > > > 
> > > > These should be grouped with the other TOPCKGEN clocks. Another
> > > > reason to
> > > > split this driver into multiple ones.
> > > > 
> > 
> > 
> > 
> > These clocks are "clock gate" in TOPCKGEN, so we separate the data
> > of
> > "clock gate" from "clock mux".
> 
> Right, but it gets really confusing when the driver is mixing clocks
> from different clock controllers. Code that gets used together should
> be grouped together. In this case, code for the same hardware block
> should be grouped together. So please split the drivers up if they
> end
> up being really big, and then group the remaining ones by hardware
> block first, then type second.
> 

I will separate the clocks here to different clock driver, each driver
only keep the clocks that provided by same IP block.

> > > > > > +
> > > > > > +static const struct mtk_gate_regs apmixed_cg_regs = {
> > > > > > +       .set_ofs = 0x8,
> > > > > > +       .clr_ofs = 0x8,
> > > > > > +       .sta_ofs = 0x8,
> > > > > > +};
> > > > > > +
> > > > > > +#define GATE_APMIXED(_id, _name, _parent,
> > > > > > _shift)                      \
> > > > > > +       GATE_MTK(_id, _name, _parent, &apmixed_cg_regs,
> > > > > > _shift,
> > > > > > &mtk_clk_gate_ops_no_setclr_inv)
> > > > > > +
> > > > > > +static const struct mtk_gate apmixed_clks[] = {
> > > > > > +       GATE_APMIXED(CLK_APMIXED_PLL_SSUSB26M,
> > > > > > "pll_ssusb26m",
> > > > > > "clk26m", 1),
> > > > > > +};
> > > > > > +
> > > > > > +#define MT8195_PLL_FMAX                (3800UL * MHZ)
> > > > > > +#define MT8195_PLL_FMIN                (1500UL * MHZ)
> > > > > > +#define MT8195_INTEGER_BITS    8
> > > > > > +
> > > > > > +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask,
> > > > 
> > > > _flags,      \
> > > > > > +                       _rst_bar_mask, _pcwbits, _pd_reg,
> > > > > > _pd_shift,    \
> > > > > > +                       _tuner_reg, _tuner_en_reg,
> > > > > > _tuner_en_bit,       \
> > > > > > +                       _pcw_reg, _pcw_shift,
> > > > > > _pcw_chg_reg,                             \
> > > > > > +                       _en_reg, _pll_en_bit)
> > > > > > {                                 \
> > > > > > +               .id =
> > > > > > _id,                                              \
> > > > > > +               .name =
> > > > > > _name,                                          \
> > > > > > +               .reg =
> > > > > > _reg,                                            \
> > > > > > +               .pwr_reg =
> > > > > > _pwr_reg,                                    \
> > > > > > +               .en_mask =
> > > > > > _en_mask,                                    \
> > > > > > +               .flags =
> > > > > > _flags,                                        \
> > > > > > +               .rst_bar_mask =
> > > > > > _rst_bar_mask,                          \
> > > > > > +               .fmax =
> > > > > > MT8195_PLL_FMAX,                                \
> > > > > > +               .fmin =
> > > > > > MT8195_PLL_FMIN,                                \
> > > > > > +               .pcwbits =
> > > > > > _pcwbits,                                    \
> > > > > > +               .pcwibits =
> > > > > > MT8195_INTEGER_BITS,                        \
> > > > > > +               .pd_reg =
> > > > > > _pd_reg,                                      \
> > > > > > +               .pd_shift =
> > > > > > _pd_shift,                                  \
> > > > > > +               .tuner_reg =
> > > > > > _tuner_reg,                                \
> > > > > > +               .tuner_en_reg =
> > > > > > _tuner_en_reg,                          \
> > > > > > +               .tuner_en_bit =
> > > > > > _tuner_en_bit,                          \
> > > > > > +               .pcw_reg =
> > > > > > _pcw_reg,                                    \
> > > > > > +               .pcw_shift =
> > > > > > _pcw_shift,                                \
> > > > > > +               .pcw_chg_reg =
> > > > > > _pcw_chg_reg,                            \
> > > > > > +               .en_reg =
> > > > > > _en_reg,                                      \
> > > > > > +               .pll_en_bit =
> > > > > > _pll_en_bit,                              \
> > > > > > +       }
> > > > > > +
> > > > > > +static const struct mtk_pll_data plls[] = {
> > > > > > +       PLL(CLK_APMIXED_NNAPLL, "nnapll", 0x0390, 0x03a0,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x0398, 24, 0, 0, 0, 0x0398, 0,
> > > > 
> > > > 0x0398,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_RESPLL, "respll", 0x0190, 0x0320,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x0198, 24, 0, 0, 0, 0x0198, 0,
> > > > 
> > > > 0x0198,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x0360, 0x0370,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x0368, 24, 0, 0, 0, 0x0368, 0,
> > > > 
> > > > 0x0368,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0710, 0x0720,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x0718, 24, 0, 0, 0, 0x0718, 0,
> > > > 
> > > > 0x0718,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_TVDPLL1, "tvdpll1", 0x00a0, 0x00b0,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x00a8, 24, 0, 0, 0, 0x00a8, 0,
> > > > 
> > > > 0x00a8,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_TVDPLL2, "tvdpll2", 0x00c0, 0x00d0,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x00c8, 24, 0, 0, 0, 0x00c8, 0,
> > > > 
> > > > 0x00c8,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_MMPLL, "mmpll", 0x00e0, 0x00f0,
> > > > 
> > > > 0xff000000,
> > > > > > +               HAVE_RST_BAR, BIT(23), 22, 0x00e8, 24, 0,
> > > > > > 0, 0,
> > > > > > 0x00e8, 0, 0x00e8, 0, 9),
> > > > > > +       PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x01d0, 0x01e0,
> > > > > > 0xff000000,
> > > > > > +               HAVE_RST_BAR, BIT(23), 22, 0x01d8, 24, 0,
> > > > > > 0, 0,
> > > > > > 0x01d8, 0, 0x01d8, 0, 9),
> > > > > > +       PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x0890, 0x08a0,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x0898, 24, 0, 0, 0, 0x0898, 0,
> > > > 
> > > > 0x0898,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_IMGPLL, "imgpll", 0x0100, 0x0110,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x0108, 24, 0, 0, 0, 0x0108, 0,
> > > > 
> > > > 0x0108,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x01f0, 0x0700,
> > > > > > 0xff000000,
> > > > > > +               HAVE_RST_BAR, BIT(23), 22, 0x01f8, 24, 0,
> > > > > > 0, 0,
> > > > > > 0x01f8, 0, 0x01f8, 0, 9),
> > > > > > +       PLL(CLK_APMIXED_HDMIPLL1, "hdmipll1", 0x08c0,
> > > > > > 0x08d0,
> > > > 
> > > > 0,
> > > > > > +               0, 0, 22, 0x08c8, 24, 0, 0, 0, 0x08c8, 0,
> > > > 
> > > > 0x08c8,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_HDMIPLL2, "hdmipll2", 0x0870,
> > > > > > 0x0880,
> > > > 
> > > > 0,
> > > > > > +               0, 0, 22, 0x0878, 24, 0, 0, 0, 0x0878, 0,
> > > > 
> > > > 0x0878,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_HDMIRX_APLL, "hdmirx_apll", 0x08e0,
> > > > 
> > > > 0x0dd4,
> > > > > > 0,
> > > > > > +               0, 0, 32, 0x08e8, 24, 0, 0, 0, 0x08ec, 0,
> > > > 
> > > > 0x08e8,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_USB1PLL, "usb1pll", 0x01a0, 0x01b0,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x01a8, 24, 0, 0, 0, 0x01a8, 0,
> > > > 
> > > > 0x01a8,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_ADSPPLL, "adsppll", 0x07e0, 0x07f0,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x07e8, 24, 0, 0, 0, 0x07e8, 0,
> > > > 
> > > > 0x07e8,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_APLL1, "apll1", 0x07c0, 0x0dc0, 0,
> > > > > > +               0, 0, 32, 0x07c8, 24, 0x0470, 0x0000, 12,
> > > > 
> > > > 0x07cc,
> > > > > > 0, 0x07c8, 0, 9),
> > > > > > +       PLL(CLK_APMIXED_APLL2, "apll2", 0x0780, 0x0dc4, 0,
> > > > > > +               0, 0, 32, 0x0788, 24, 0x0474, 0x0000, 13,
> > > > 
> > > > 0x078c,
> > > > > > 0, 0x0788, 0, 9),
> > > > > > +       PLL(CLK_APMIXED_APLL3, "apll3", 0x0760, 0x0dc8, 0,
> > > > > > +               0, 0, 32, 0x0768, 24, 0x0478, 0x0000, 14,
> > > > 
> > > > 0x076c,
> > > > > > 0, 0x0768, 0, 9),
> > > > > > +       PLL(CLK_APMIXED_APLL4, "apll4", 0x0740, 0x0dcc, 0,
> > > > > > +               0, 0, 32, 0x0748, 24, 0x047C, 0x0000, 15,
> > > > 
> > > > 0x074c,
> > > > > > 0, 0x0748, 0, 9),
> > > > > > +       PLL(CLK_APMIXED_APLL5, "apll5", 0x07a0, 0x0dd0,
> > > > 
> > > > 0x100000,
> > > > > > +               0, 0, 32, 0x07a8, 24, 0x0480, 0x0000, 16,
> > > > 
> > > > 0x07ac,
> > > > > > 0, 0x07a8, 0, 9),
> > > > > > +       PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x0340, 0x0350,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x0348, 24, 0, 0, 0, 0x0348, 0,
> > > > 
> > > > 0x0348,
> > > > > > 0, 9),
> > > > > > +       PLL(CLK_APMIXED_DGIPLL, "dgipll", 0x0150, 0x0160,
> > > > > > 0,
> > > > > > +               0, 0, 22, 0x0158, 24, 0, 0, 0, 0x0158, 0,
> > > > 
> > > > 0x0158,
> > > > > > 0, 9),
> > > > > > +};
> > > > > > +
> > > > > > +static struct clk_onecell_data *top_clk_data;
> > > > > > +
> > > > > > +static void clk_mt8195_top_init_early(struct device_node
> > > > 
> > > > *node)
> > > > > > +{
> > > > > > +       int i;
> > > > > > +
> > > > > > +       top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
> > > > > > +       if (!top_clk_data)
> > > > > > +               return;
> > > > > > +
> > > > > > +       for (i = 0; i < CLK_TOP_NR_CLK; i++)
> > > > > > +               top_clk_data->clks[i] = ERR_PTR(-
> > > > > > EPROBE_DEFER);
> > > > > > +
> > > > > > +       mtk_clk_register_factors(top_early_divs,
> > > > > > ARRAY_SIZE(top_early_divs), top_clk_data);
> > > > > > +
> > > > > > +       of_clk_add_provider(node, of_clk_src_onecell_get,
> > > > > > top_clk_data);
> > > > > > +}
> > > > > > +
> > > > > > +CLK_OF_DECLARE_DRIVER(mt8195_topckgen,
> > > > 
> > > > "mediatek,mt8195-topckgen",
> > > > > > +                       clk_mt8195_top_init_early);
> > > > > > +
> > > > > > +static int clk_mt8195_top_probe(struct platform_device
> > > > > > *pdev)
> > > > > > +{
> > > > > > +       struct device_node *node = pdev->dev.of_node;
> > > > > > +       int r;
> > > > > > +       void __iomem *base;
> > > > > > +
> > > > > > +       base = devm_platform_ioremap_resource(pdev, 0);
> > > > > > +       if (IS_ERR(base))
> > > > > > +               return PTR_ERR(base);
> > > > > > +
> > > > > > +       mtk_clk_register_fixed_clks(top_fixed_clks,
> > > > > > ARRAY_SIZE(top_fixed_clks),
> > > > > > +                       top_clk_data);
> > > > > > +       mtk_clk_register_factors(top_early_divs,
> > > > > > ARRAY_SIZE(top_early_divs), top_clk_data);
> > > > > > +       mtk_clk_register_factors(top_divs,
> > > > > > ARRAY_SIZE(top_divs),
> > > > > > top_clk_data);
> > > > > > +       mtk_clk_register_muxes(top_mtk_muxes,
> > > > > > ARRAY_SIZE(top_mtk_muxes), node,
> > > > > > +                       &mt8195_clk_lock, top_clk_data);
> > > > > > +       mtk_clk_register_composites(top_muxes,
> > > > > > ARRAY_SIZE(top_muxes), base,
> > > > > > +                       &mt8195_clk_lock, top_clk_data);
> > > > > > +       mtk_clk_register_composites(top_adj_divs,
> > > > > > ARRAY_SIZE(top_adj_divs), base,
> > > > > > +                       &mt8195_clk_lock, top_clk_data);
> > > > 
> > > > Future work: these functions probably should be made to return
> > > > errors.
> > > > 
> > > 
> > > 
> > > > > > +       r = mtk_clk_register_gates(node, top_clks,
> > > > > > ARRAY_SIZE(top_clks), top_clk_data);
> > > > > > +       if (r)
> > > > > > +               return r;
> > > > > > +
> > > > > > +       return of_clk_add_provider(node,
> > > > > > of_clk_src_onecell_get,
> > > > > > top_clk_data);
> > > > > > +}
> > > > > > +
> > > > > > +static int clk_mt8195_infra_ao_probe(struct
> > > > > > platform_device
> > > > 
> > > > *pdev)
> > > > > > +{
> > > > > > +       struct clk_onecell_data *clk_data;
> > > > > > +       struct device_node *node = pdev->dev.of_node;
> > > > > > +       int r;
> > > > > > +
> > > > > > +       clk_data = mtk_alloc_clk_data(CLK_INFRA_AO_NR_CLK);
> > > > > > +       if (!clk_data)
> > > > > > +               return -ENOMEM;
> > > > > > +
> > > > > > +       r = mtk_clk_register_gates(node, infra_ao_clks,
> > > > > > ARRAY_SIZE(infra_ao_clks), clk_data);
> > > > > > +       if (r)
> > > > > > +               return r;
> > > > > > +
> > > > > > +       return of_clk_add_provider(node,
> > > > > > of_clk_src_onecell_get,
> > > > > > clk_data);
> > > > 
> > > > You are leaking clk_data if mtk_clk_register_gates() or
> > > > of_clk_add_provider()
> > > > fail.
> > > > 
> > 
> > 
> > 
> > Ok, I will fix it include you mention below, thanks for you
> > comment.
> > 
> > 
> > > > > > +}
> > > > > > +
> > > > > > +static int clk_mt8195_apmixed_probe(struct platform_device
> > > > 
> > > > *pdev)
> > > > > > +{
> > > > > > +       struct clk_onecell_data *clk_data;
> > > > > > +       struct device_node *node = pdev->dev.of_node;
> > > > > > +       int r;
> > > > > > +
> > > > > > +       clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
> > > > > > +       if (!clk_data)
> > > > > > +               return -ENOMEM;
> > > > > > +
> > > > > > +       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls),
> > > > > > clk_data);
> > > > > > +       r = mtk_clk_register_gates(node, apmixed_clks,
> > > > > > ARRAY_SIZE(apmixed_clks), clk_data);
> > > > > > +       if (r)
> > > > > > +               return r;
> > > > > > +
> > > > > > +       return of_clk_add_provider(node,
> > > > > > of_clk_src_onecell_get,
> > > > > > clk_data);
> > > > 
> > > > Same here.
> > > > 
> > > 
> > > 
> > > > > > +}
> > > > > > +
> > > > > > +static int clk_mt8195_peri_ao_probe(struct platform_device
> > > > 
> > > > *pdev)
> > > > > > +{
> > > > > > +       struct clk_onecell_data *clk_data;
> > > > > > +       struct device_node *node = pdev->dev.of_node;
> > > > > > +       int r;
> > > > > > +
> > > > > > +       clk_data = mtk_alloc_clk_data(CLK_PERI_AO_NR_CLK);
> > > > > > +       if (!clk_data)
> > > > > > +               return -ENOMEM;
> > > > > > +
> > > > > > +       r = mtk_clk_register_gates(node, peri_ao_clks,
> > > > > > ARRAY_SIZE(peri_ao_clks), clk_data);
> > > > > > +       if (r)
> > > > > > +               return r;
> > > > > > +
> > > > > > +       return of_clk_add_provider(node,
> > > > > > of_clk_src_onecell_get,
> > > > > > clk_data);
> > > > 
> > > > And here.
> > > > 
> > > 
> > > 
> > > > > > +}
> > > > > > +
> > > > > > +static const struct of_device_id of_match_clk_mt8195[] = {
> > > > > > +       {
> > > > > > +               .compatible = "mediatek,mt8195-apmixedsys",
> > > > > > +               .data = clk_mt8195_apmixed_probe,
> > > > > > +       }, {
> > > > > > +               .compatible = "mediatek,mt8195-topckgen",
> > > > > > +               .data = clk_mt8195_top_probe,
> > > > > > +       }, {
> > > > > > +               .compatible = "mediatek,mt8195-
> > > > > > infracfg_ao",
> > > > > > +               .data = clk_mt8195_infra_ao_probe,
> > > > > > +       }, {
> > > > > > +               .compatible = "mediatek,mt8195-pericfg_ao",
> > > > > > +               .data = clk_mt8195_peri_ao_probe,
> > > > 
> > > > This file contains four drivers. They do not have depend on
> > > > each
> > > > other,
> > > > and do not need to be in the same file. Please split them into
> > > > different
> > > > files and preferably different patches so people reading them
> > > > don't
> > > > have
> > > > to look through unrelated data. Then you don't need the pointer
> > > > to
> > > > the
> > > > probe function.
> > > > 
> > 
> > 
> > 
> > Ok, I will split to different driver.
> > 
> > 
> > > > You can keep them under the same Kconfig symbol.
> > > > 
> > > 
> > > 
> > > > > > +       }, {
> > > > > > +               /* sentinel */
> > > > > > +       }
> > > > > > +};
> > > > > > +
> > > > > > +static int clk_mt8195_probe(struct platform_device *pdev)
> > > > > > +{
> > > > > > +       int (*clk_probe)(struct platform_device *pdev);
> > > > > > +       int r;
> > > > > > +
> > > > > > +       clk_probe = of_device_get_match_data(&pdev->dev);
> > > > > > +       if (!clk_probe)
> > > > > > +               return -EINVAL;
> > > > > > +
> > > > > > +       r = clk_probe(pdev);
> > > > > > +       if (r)
> > > > > > +               dev_err(&pdev->dev,
> > > > > > +                       "could not register clock provider:
> > > > > > %s:
> > > > > > %d\n",
> > > > > > +                       pdev->name, r);
> > > > > > +
> > > > > > +       return r;
> > > > > > +}
> > > > > > +
> > > > > > +static struct platform_driver clk_mt8195_drv = {
> > > > > > +       .probe = clk_mt8195_probe,
> > > > > > +       .driver = {
> > > > > > +               .name = "clk-mt8195",
> > > > > > +               .of_match_table = of_match_clk_mt8195,
> > > > > > +       },
> > > > > > +};
> > > > > > +
> > > > > > +static int __init clk_mt8195_init(void)
> > > > > > +{
> > > > > > +       return platform_driver_register(&clk_mt8195_drv);
> > > > > > +}
> > > > > > +
> > > > > > +arch_initcall(clk_mt8195_init);
> > > > 
> > > > Is there any particular reason for arch_initcall?
> > > > 
> > 
> > 
> > APMIXEDSYS/TOPCKGEN are clock source of others IP block and
> > PERICFG/INFRACFG provide peripheral and bus clocks control, so we
> > want
> > to init early.
> 
> Sure, but this should really be done through standard dependency
> handling, and not trying to sequence them by hand.
> 
> Is there an observable benefit to having arch_initcall() vs the
> standard
> order with builtin_platform_driver()? If so, this should be
> documented
> here as a justifcation for arch_initcall().
> 

I will use builtin_platform_driver like other subsys ip block
in next version.

Best Regards,
Chun-Jie

> 
> Regards
> ChenYu

From anshuman.khandual at arm.com  Tue Aug 10 21:52:29 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 10:22:29 +0530
Subject: [PATCH] KVM: arm64: Restrict IPA size to maximum 48 bits on 4K and
 16K page size
Message-ID: <1628657549-27584-1-git-send-email-anshuman.khandual@arm.com>

Even though ID_AA64MMFR0.PARANGE reports 52 bit PA size support, it cannot
be enabled as guest IPA size on 4K or 16K page size configurations. Hence
kvm_ipa_limit must be restricted to 48 bits. This change achieves required
IPA capping.

Before the commit c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA
size based on host configuration"), the problem here would have been just
latent via PHYS_MASK_SHIFT (which earlier in turn capped kvm_ipa_limit),
which remains capped at 48 bits on 4K and 16K configs.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Fixes: c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA size based on host configuration")
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.14-rc5

 arch/arm64/kvm/reset.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 20588220fe66..e66974c4b9d3 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -337,6 +337,15 @@ int kvm_set_ipa_limit(void)
 		return -EINVAL;
 	}
 
+	/*
+	 * IPA size beyond 48 bits could not be supported
+	 * on either 4K or 16K page size. Hence let's cap
+	 * it to 48 bits, in case it's reported as larger
+	 * on the system.
+	 */
+	if (!IS_ENABLED(CONFIG_ARM64_64K_PAGES))
+		parange = min(parange, (unsigned int)ID_AA64MMFR0_PARANGE_48);
+
 	kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange);
 	kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit,
 		 ((kvm_ipa_limit < KVM_PHYS_SHIFT) ?
-- 
2.20.1



From email2tema at gmail.com  Tue Aug 10 22:09:41 2021
From: email2tema at gmail.com (Artem Lapkin)
Date: Wed, 11 Aug 2021 13:09:41 +0800
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
Message-ID: <20210811050941.398360-1-art@khadas.com>

Add spdifin spdifout spdifout_b nodes for Amlogic SM1 SoCs.

Signed-off-by: Artem Lapkin <art at khadas.com>
---
 arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 40 ++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
index 3d8b1f4f2..1efdbb61e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
@@ -356,6 +356,33 @@ tdmin_lb: audio-controller at 3c0 {
 			status = "disabled";
 		};
 
+		spdifin: audio-controller at 400 {
+			compatible = "amlogic,g12a-spdifin",
+			"amlogic,axg-spdifin";
+			reg = <0x0 0x400 0x0 0x30>;
+			#sound-dai-cells = <0>;
+			sound-name-prefix = "SPDIFIN";
+			interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
+			clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
+			<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
+			clock-names = "pclk", "refclk";
+			resets = <&clkc_audio AUD_RESET_SPDIFIN>;
+			status = "disabled";
+		};
+
+		spdifout: audio-controller at 480 {
+			compatible = "amlogic,g12a-spdifout",
+			"amlogic,axg-spdifout";
+			reg = <0x0 0x480 0x0 0x50>;
+			#sound-dai-cells = <0>;
+			sound-name-prefix = "SPDIFOUT";
+			clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
+			<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
+			clock-names = "pclk", "mclk";
+			resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
+			status = "disabled";
+		};
+
 		tdmout_a: audio-controller at 500 {
 			compatible = "amlogic,sm1-tdmout";
 			reg = <0x0 0x500 0x0 0x40>;
@@ -401,6 +428,19 @@ tdmout_c: audio-controller at 580 {
 			status = "disabled";
 		};
 
+		spdifout_b: audio-controller at 680 {
+			compatible = "amlogic,g12a-spdifout",
+			"amlogic,axg-spdifout";
+			reg = <0x0 0x680 0x0 0x50>;
+			#sound-dai-cells = <0>;
+			sound-name-prefix = "SPDIFOUT_B";
+			clocks = <&clkc_audio AUD_CLKID_SPDIFOUT_B>,
+			<&clkc_audio AUD_CLKID_SPDIFOUT_B_CLK>;
+			clock-names = "pclk", "mclk";
+			resets = <&clkc_audio AUD_RESET_SPDIFOUT_B>;
+			status = "disabled";
+		};
+
 		toacodec: audio-controller at 740 {
 			compatible = "amlogic,sm1-toacodec",
 				     "amlogic,g12a-toacodec";
-- 
2.25.1



From viresh.kumar at linaro.org  Tue Aug 10 22:18:59 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 10:48:59 +0530
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <YRJym+Vn4bbwQzzs@google.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
Message-ID: <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>

On 10-08-21, 13:35, Quentin Perret wrote:
> On Tuesday 10 Aug 2021 at 13:06:47 (+0530), Viresh Kumar wrote:
> > Provide a cpufreq driver flag so drivers can ask the cpufreq core to register
> > with the EM core on their behalf.
> 
> Hmm, that's not quite what this does. This asks the cpufreq core to
> use *PM_OPP* to register an EM, which I think is kinda wrong to do from
> there IMO. The decision to use PM_OPP or another mechanism to register
> an EM belongs to platform specific code (drivers), so it is odd for the
> PM_OPP registration to have its own cpufreq flag but not the other ways.
> 
> As mentioned in another thread, the very reason to have PM_EM is to not
> depend on PM_OPP, so I'm worried about the direction of travel with this
> series TBH.

I had to use the pm-opp version, since almost everyone was using that.

On the other hand, there isn't a lot of OPP specific stuff in
dev_pm_opp_of_register_em(). It just uses dev_pm_opp_get_opp_count(),
that's all. This ended up in the OPP core, nothing else. Maybe we can
now move it back to the EM core and name it differently ?

> > This allows us to get rid of duplicated code
> > in the drivers and fix the unregistration part as well, which none of the
> > drivers have done until now.
> 
> This series adds more code than it removes,

Sadly yes :(

> and the unregistration is
> not a fix as we don't ever remove the EM tables by design, so not sure
> either of these points are valid arguments.

I think that design needs to be looked over again, it looks broken to
me everytime I land onto this code. I wonder why we don't unregister
stuff.

Lets say, I am working on the cpufreq driver and I want to test that
on my ARM machine. Rebooting a simpler board to test stuff out is
easy, but if I am working on an ARM server which is running lots of
other userspace stuff as well, I won't want to reboot the machine just
to test a different versions of the driver. I will rather want to
build the driver as module and insert/remove it again and again.

If the frequency table changes in between versions, this just breaks
as EM won't be updated again.

This breaks one of the most basic rules of Linux Kernel. Inserting a
module should have exactly the same final behavior every single time.
This model doesn't guarantee it. It simply looks broken.

> > This would also make the registration with EM core to happen only after policy
> > is fully initialized, and the EM core can do other stuff from in there, like
> > marking frequencies as inefficient (WIP). Though this patchset is useful without
> > that work being done and should be merged nevertheless.
> > 
> > This doesn't update scmi cpufreq driver for now as it is a special case and need
> > to be handled differently. Though we can make it work with this if required.
> 
> Note that we'll have more 'special cases' if other architectures start
> using PM_EM, which is what we have been trying to allow since the
> beginning, so that's worth keeping in mind.

Yes, we need to take care of all such special cases as well.

-- 
viresh


From viresh.kumar at linaro.org  Tue Aug 10 22:21:04 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 10:51:04 +0530
Subject: [PATCH] cpufreq: vexpress: Set CPUFREQ_IS_COOLING_DEV flag
Message-ID: <0efe0c7b1c07591f07a905021f455b033441784f.1628659212.git.viresh.kumar@linaro.org>

Reuse the cpufreq core's registration of cooling device by setting the
CPUFREQ_IS_COOLING_DEV flag. Set this only if bL switcher isn't enabled.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
Sudeep, is this broken ? I wonder why we didn't do it earlier.

 drivers/cpufreq/vexpress-spc-cpufreq.c | 22 +++-------------------
 1 file changed, 3 insertions(+), 19 deletions(-)

diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c
index 28c4c3254337..618b263434ca 100644
--- a/drivers/cpufreq/vexpress-spc-cpufreq.c
+++ b/drivers/cpufreq/vexpress-spc-cpufreq.c
@@ -15,7 +15,6 @@
 #include <linux/cpu.h>
 #include <linux/cpufreq.h>
 #include <linux/cpumask.h>
-#include <linux/cpu_cooling.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -47,7 +46,6 @@ static bool bL_switching_enabled;
 #define ACTUAL_FREQ(cluster, freq)  ((cluster == A7_CLUSTER) ? freq << 1 : freq)
 #define VIRT_FREQ(cluster, freq)    ((cluster == A7_CLUSTER) ? freq >> 1 : freq)
 
-static struct thermal_cooling_device *cdev[MAX_CLUSTERS];
 static struct clk *clk[MAX_CLUSTERS];
 static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1];
 static atomic_t cluster_usage[MAX_CLUSTERS + 1];
@@ -455,11 +453,6 @@ static int ve_spc_cpufreq_exit(struct cpufreq_policy *policy)
 	struct device *cpu_dev;
 	int cur_cluster = cpu_to_cluster(policy->cpu);
 
-	if (cur_cluster < MAX_CLUSTERS) {
-		cpufreq_cooling_unregister(cdev[cur_cluster]);
-		cdev[cur_cluster] = NULL;
-	}
-
 	cpu_dev = get_cpu_device(policy->cpu);
 	if (!cpu_dev) {
 		pr_err("%s: failed to get cpu%d device\n", __func__,
@@ -471,17 +464,6 @@ static int ve_spc_cpufreq_exit(struct cpufreq_policy *policy)
 	return 0;
 }
 
-static void ve_spc_cpufreq_ready(struct cpufreq_policy *policy)
-{
-	int cur_cluster = cpu_to_cluster(policy->cpu);
-
-	/* Do not register a cpu_cooling device if we are in IKS mode */
-	if (cur_cluster >= MAX_CLUSTERS)
-		return;
-
-	cdev[cur_cluster] = of_cpufreq_cooling_register(policy);
-}
-
 static struct cpufreq_driver ve_spc_cpufreq_driver = {
 	.name			= "vexpress-spc",
 	.flags			= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
@@ -492,7 +474,6 @@ static struct cpufreq_driver ve_spc_cpufreq_driver = {
 	.get			= ve_spc_cpufreq_get_rate,
 	.init			= ve_spc_cpufreq_init,
 	.exit			= ve_spc_cpufreq_exit,
-	.ready			= ve_spc_cpufreq_ready,
 	.attr			= cpufreq_generic_attr,
 };
 
@@ -552,6 +533,9 @@ static int ve_spc_cpufreq_probe(struct platform_device *pdev)
 	for (i = 0; i < MAX_CLUSTERS; i++)
 		mutex_init(&cluster_lock[i]);
 
+	if (!is_bL_switching_enabled())
+		ve_spc_cpufreq_driver.flags |= CPUFREQ_IS_COOLING_DEV;
+
 	ret = cpufreq_register_driver(&ve_spc_cpufreq_driver);
 	if (ret) {
 		pr_info("%s: Failed registering platform driver: %s, err: %d\n",
-- 
2.31.1.272.g89b43f80a514



From anshuman.khandual at arm.com  Tue Aug 10 22:32:05 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 11:02:05 +0530
Subject: [PATCH 1/5] KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as
 page size
In-Reply-To: <20210810132015.GA2946@willie-the-truck>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
 <20210810132015.GA2946@willie-the-truck>
Message-ID: <7ac63cc6-d35a-d455-f629-abea2932d312@arm.com>



On 8/10/21 6:50 PM, Will Deacon wrote:
> On Tue, Aug 10, 2021 at 12:32:37PM +0530, Anshuman Khandual wrote:
>> All instances here could just directly test against CONFIG_ARM64_XXK_PAGES
>> instead of evaluating via PAGE_SHIFT or PAGE_SIZE. With this change, there
>> will be no such usage left.
>>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: James Morse <james.morse at arm.com>
>> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: kvmarm at lists.cs.columbia.edu
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/kvm/hyp/pgtable.c | 6 +++---
>>  arch/arm64/mm/mmu.c          | 2 +-
>>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> Why is this better?

There are two improvements here.

1. Avoids using hard coded numerical shift values to determine the page size

	e.g PAGE_SHIFT = 16 for 64K

2. There are already instances of IS_ENABLED() construct checking for the page
   size. After this change there will be just a single method to test page size
   , rather than checking for either config, PAGE_SHIFT or PAGE_SIZE etc through
   out arm64. This change helps in that unification around IS_ENABLED().

There is another patch which drops remaining usage for PAGE_SIZE as well.

https://patchwork.kernel.org/project/linux-arm-kernel/patch/1628569782-30213-1-git-send-email-anshuman.khandual at arm.com/ 


From anshuman.khandual at arm.com  Tue Aug 10 22:34:46 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 11:04:46 +0530
Subject: [PATCH 1/5] KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as
 page size
In-Reply-To: <25ee7799069492f2501003faec7f9732@kernel.org>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
 <25ee7799069492f2501003faec7f9732@kernel.org>
Message-ID: <0b47c654-7e9b-a7ca-bdf4-f9607062200e@arm.com>



On 8/10/21 7:03 PM, Marc Zyngier wrote:
> On 2021-08-10 08:02, Anshuman Khandual wrote:
>> All instances here could just directly test against CONFIG_ARM64_XXK_PAGES
>> instead of evaluating via PAGE_SHIFT or PAGE_SIZE. With this change, there
>> will be no such usage left.
>>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: James Morse <james.morse at arm.com>
>> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: kvmarm at lists.cs.columbia.edu
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> ?arch/arm64/kvm/hyp/pgtable.c | 6 +++---
>> ?arch/arm64/mm/mmu.c????????? | 2 +-
>> ?2 files changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
>> index 05321f4165e3..a6112b6d6ef6 100644
>> --- a/arch/arm64/kvm/hyp/pgtable.c
>> +++ b/arch/arm64/kvm/hyp/pgtable.c
>> @@ -85,7 +85,7 @@ static bool kvm_level_supports_block_mapping(u32 level)
>> ????? * Reject invalid block mappings and don't bother with 4TB mappings for
>> ????? * 52-bit PAs.
>> ????? */
>> -??? return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
>> +??? return !(level == 0 || (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) && level == 1));
>> ?}
>>
>> ?static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level)
>> @@ -155,7 +155,7 @@ static u64 kvm_pte_to_phys(kvm_pte_t pte)
>> ?{
>> ???? u64 pa = pte & KVM_PTE_ADDR_MASK;
>>
>> -??? if (PAGE_SHIFT == 16)
>> +??? if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
>> ???????? pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
>>
>> ???? return pa;
>> @@ -165,7 +165,7 @@ static kvm_pte_t kvm_phys_to_pte(u64 pa)
>> ?{
>> ???? kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK;
>>
>> -??? if (PAGE_SHIFT == 16)
>> +??? if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
>> ???????? pte |= FIELD_PREP(KVM_PTE_ADDR_51_48, pa >> 48);
>>
>> ???? return pte;
>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>> index 9ff0de1b2b93..8fdfca179815 100644
>> --- a/arch/arm64/mm/mmu.c
>> +++ b/arch/arm64/mm/mmu.c
>> @@ -296,7 +296,7 @@ static void alloc_init_cont_pmd(pud_t *pudp,
>> unsigned long addr,
>> ?static inline bool use_1G_block(unsigned long addr, unsigned long next,
>> ???????????? unsigned long phys)
>> ?{
>> -??? if (PAGE_SHIFT != 12)
>> +??? if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
>> ???????? return false;
>>
>> ???? if (((addr | next | phys) & ~PUD_MASK) != 0)
> 
> I personally find it a lot less readable.
> 
> Also, there is no evaluation whatsoever. All the code guarded
> by a PAGE_SIZE/PAGE_SHIFT that doesn't match the configuration
> is dropped at compile time.

The primary idea here is to unify around IS_ENABLED(CONFIG_ARM64_XXK_PAGES)
usage in arm64, rather than having multiple methods to test page size when
ever required.


From viresh.kumar at linaro.org  Tue Aug 10 22:34:06 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 11:04:06 +0530
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
Message-ID: <20210811053406.jqwextgtnxhgsjd2@vireshk-i7>

On 11-08-21, 10:48, Viresh Kumar wrote:
> On 10-08-21, 13:35, Quentin Perret wrote:
> > This series adds more code than it removes,
> 
> Sadly yes :(
> 
> > and the unregistration is
> > not a fix as we don't ever remove the EM tables by design, so not sure
> > either of these points are valid arguments.
> 
> I think that design needs to be looked over again, it looks broken to
> me everytime I land onto this code. I wonder why we don't unregister
> stuff.

Coming back to this series. We have two options, based on what I
proposed here:

https://lore.kernel.org/linux-pm/20210811050327.3yxrk4kqxjjwaztx at vireshk-i7/

1. Let cpufreq core register with EM on behalf of cpufreq drivers.

2. Update drivers to use ->ready() callback to do this stuff.

I am fine with both :)

-- 
viresh


From anshuman.khandual at arm.com  Tue Aug 10 22:54:57 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 11:24:57 +0530
Subject: [PATCH 3/5] KVM: arm64: Drop check_kvm_target_cpu() based percpu
 probe
In-Reply-To: <20210810132822.GC2946@willie-the-truck>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-4-git-send-email-anshuman.khandual@arm.com>
 <20210810132822.GC2946@willie-the-truck>
Message-ID: <c7f87766-bf91-d0c1-ce9d-893506350020@arm.com>



On 8/10/21 6:58 PM, Will Deacon wrote:
> On Tue, Aug 10, 2021 at 12:32:39PM +0530, Anshuman Khandual wrote:
>> kvm_target_cpu() never returns a negative error code, so check_kvm_target()
>> would never have 'ret' filled with a negative error code. Hence the percpu
>> probe via check_kvm_target_cpu() does not make sense as its never going to
>> find an unsupported CPU, forcing kvm_arch_init() to exit early. Hence lets
>> just drop this percpu probe (and also check_kvm_target_cpu()) altogether.
>>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: James Morse <james.morse at arm.com>
>> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: kvmarm at lists.cs.columbia.edu
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/kvm/arm.c | 14 --------------
>>  1 file changed, 14 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>> index 19560e457c11..16f93678c17e 100644
>> --- a/arch/arm64/kvm/arm.c
>> +++ b/arch/arm64/kvm/arm.c
>> @@ -2010,11 +2010,6 @@ static int finalize_hyp_mode(void)
>>  	return 0;
>>  }
>>  
>> -static void check_kvm_target_cpu(void *ret)
>> -{
>> -	*(int *)ret = kvm_target_cpu();
>> -}
>> -
>>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
>>  {
>>  	struct kvm_vcpu *vcpu;
>> @@ -2074,7 +2069,6 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons)
>>  int kvm_arch_init(void *opaque)
>>  {
>>  	int err;
>> -	int ret, cpu;
>>  	bool in_hyp_mode;
>>  
>>  	if (!is_hyp_mode_available()) {
>> @@ -2089,14 +2083,6 @@ int kvm_arch_init(void *opaque)
>>  		kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \
>>  			 "Only trusted guests should be used on this system.\n");
>>  
>> -	for_each_online_cpu(cpu) {
>> -		smp_call_function_single(cpu, check_kvm_target_cpu, &ret, 1);
>> -		if (ret < 0) {
>> -			kvm_err("Error, CPU %d not supported!\n", cpu);
>> -			return -ENODEV;
>> -		}
>> -	}
> 
> Looks like kvm_target_cpu() *could* return an error at one time of day (at
> least on 32-bit), but agreed that this checking is no longer needed:
> 
> Acked-by: Will Deacon <will at kernel.org>
> 
> Perhaps it's worth making the return type of kvm_target_cpu() a u32 to
> make it a bit more explicit that you shouldn't be returning an error code
> there?

Sure, will change the return type to u32.


From tony at atomide.com  Tue Aug 10 23:10:53 2021
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 11 Aug 2021 09:10:53 +0300
Subject: [PATCH] bus: ti-sysc: Fix error handling for sysc_check_active_timer()
Message-ID: <20210811061053.32081-1-tony@atomide.com>

We have changed the return type for sysc_check_active_timer() from -EBUSY
to -ENXIO, but the gpt12 system timer fix still checks for -EBUSY. We are
also not returning on other errors like we did earlier as noted by
Pavel Machek <pavel at denx.de>.

Commit 3ff340e24c9d ("bus: ti-sysc: Fix gpt12 system timer issue with
reserved status") should have been updated for commit 65fb73676112
("bus: ti-sysc: suppress err msg for timers used as clockevent/source").

Let's fix the issue by checking for -ENXIO and returning on any other
errors as suggested by Pavel Machek <pavel at denx.de>.

Fixes: 3ff340e24c9d ("bus: ti-sysc: Fix gpt12 system timer issue with reserved status")
Depends-on: 65fb73676112 ("bus: ti-sysc: suppress err msg for timers used as clockevent/source")
Reported-by: Pavel Machek <pavel at denx.de>
Cc: Grygorii Strashko <grygorii.strashko at ti.com>
Cc: Jarkko Nikula <jarkko.nikula at bitmer.com>
Signed-off-by: Tony Lindgren <tony at atomide.com>
---
 drivers/bus/ti-sysc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -3097,8 +3097,10 @@ static int sysc_probe(struct platform_device *pdev)
 		return error;
 
 	error = sysc_check_active_timer(ddata);
-	if (error == -EBUSY)
+	if (error == -ENXIO)
 		ddata->reserved = true;
+	else if (error)
+		return error;
 
 	error = sysc_get_clocks(ddata);
 	if (error)
-- 
2.32.0


From tony at atomide.com  Tue Aug 10 23:12:15 2021
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 11 Aug 2021 09:12:15 +0300
Subject: [PATCH] bus: ti-sysc: Fix gpt12 system timer issue with reserved
 status
In-Reply-To: <YRJ2fyS6z1i/2W2e@atomide.com>
References: <20210611060224.36769-1-tony@atomide.com>
 <20210810124006.GA25121@amd> <YRJ2fyS6z1i/2W2e@atomide.com>
Message-ID: <YRNqP9rcJElbq6EB@atomide.com>

* Tony Lindgren <tony at atomide.com> [210810 12:52]:
> * Pavel Machek <pavel at denx.de> [210810 12:40]:
> > What is going on here? First, we silently ignore errors other than
> > EBUSY. Second, sysc_check_active_timer() can't return -EBUSY: it
> > returns either 0 or -ENXIO. (I checked 5.10-stable, mainline and
> > -next-20210806).
> 
> Thanks for spotting it, looks like there's now a conflict with commit
> 65fb73676112 ("bus: ti-sysc: suppress err msg for timers used as
> clockevent/source"). It seems we should also check for -ENXIO here
> too. And yeah it makes sens to return on other errors for sure.

FYI, fix posted at [0] below.

Regards,

Tony

[0] https://lore.kernel.org/linux-omap/20210811061053.32081-1-tony at atomide.com/T/#u


From pavel at denx.de  Tue Aug 10 23:22:31 2021
From: pavel at denx.de (Pavel Machek)
Date: Wed, 11 Aug 2021 08:22:31 +0200
Subject: [PATCH] bus: ti-sysc: Fix error handling for
 sysc_check_active_timer()
In-Reply-To: <20210811061053.32081-1-tony@atomide.com>
References: <20210811061053.32081-1-tony@atomide.com>
Message-ID: <20210811062231.GA16241@duo.ucw.cz>

On Wed 2021-08-11 09:10:53, Tony Lindgren wrote:
> We have changed the return type for sysc_check_active_timer() from -EBUSY
> to -ENXIO, but the gpt12 system timer fix still checks for -EBUSY. We are
> also not returning on other errors like we did earlier as noted by
> Pavel Machek <pavel at denx.de>.
> 
> Commit 3ff340e24c9d ("bus: ti-sysc: Fix gpt12 system timer issue with
> reserved status") should have been updated for commit 65fb73676112
> ("bus: ti-sysc: suppress err msg for timers used as clockevent/source").
> 
> Let's fix the issue by checking for -ENXIO and returning on any other
> errors as suggested by Pavel Machek <pavel at denx.de>.
> 
> Fixes: 3ff340e24c9d ("bus: ti-sysc: Fix gpt12 system timer issue with reserved status")
> Depends-on: 65fb73676112 ("bus: ti-sysc: suppress err msg for timers used as clockevent/source")
> Reported-by: Pavel Machek <pavel at denx.de>
> Cc: Grygorii Strashko <grygorii.strashko at ti.com>
> Cc: Jarkko Nikula <jarkko.nikula at bitmer.com>
> Signed-off-by: Tony Lindgren <tony at atomide.com>

Reviewed-by: Pavel Machek (CIP) <pavel at denx.de>

Best regards,
								Pavel
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210811/c75e7528/attachment-0001.sig>

From hch at infradead.org  Tue Aug 10 23:39:20 2021
From: hch at infradead.org (Christoph Hellwig)
Date: Wed, 11 Aug 2021 07:39:20 +0100
Subject: [PATCH v5 00/10] ARM: remove set_fs callers and implementation
In-Reply-To: <20210726141141.2839385-1-arnd@kernel.org>
References: <20210726141141.2839385-1-arnd@kernel.org>
Message-ID: <YRNwmGL2b52dQUuv@infradead.org>

>From my high-level perspective this looks great and I'd love to see it
merged:

Acked-by: Christoph Hellwig <hch at lst.de>


From krzysztof.kozlowski at canonical.com  Tue Aug 10 23:44:13 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 08:44:13 +0200
Subject: [PATCH v2 1/8] dt-bindings: clock: samsung: convert Exynos5250 to
 dtschema
In-Reply-To: <CAPLW+4njX-R2e66qcCz=OT_bYKTRLHTH4nFv==EEovJyjN8qAg@mail.gmail.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-2-krzysztof.kozlowski@canonical.com>
 <CAPLW+4njX-R2e66qcCz=OT_bYKTRLHTH4nFv==EEovJyjN8qAg@mail.gmail.com>
Message-ID: <48a205be-6a37-5acc-e2ee-fa18643711a9@canonical.com>

On 10/08/2021 19:51, Sam Protsenko wrote:
> On Tue, 10 Aug 2021 at 12:32, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Convert Samsung Exynos5250 clock controller bindings to DT schema format
>> using json-schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/clock/exynos5250-clock.txt       | 41 ----------------
>>  .../bindings/clock/samsung,exynos-clock.yaml  | 48 +++++++++++++++++++
>>  MAINTAINERS                                   |  1 +
>>  3 files changed, 49 insertions(+), 41 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>> deleted file mode 100644
>> index aff266a12eeb..000000000000
>> --- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>> +++ /dev/null
>> @@ -1,41 +0,0 @@
>> -* Samsung Exynos5250 Clock Controller
>> -
>> -The Exynos5250 clock controller generates and supplies clock to various
>> -controllers within the Exynos5250 SoC.
>> -
>> -Required Properties:
>> -
>> -- compatible: should be one of the following.
>> -  - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
>> -
>> -- reg: physical base address of the controller and length of memory mapped
>> -  region.
>> -
>> -- #clock-cells: should be 1.
>> -
>> -Each clock is assigned an identifier and client nodes can use this identifier
>> -to specify the clock which they consume.
>> -
>> -All available clocks are defined as preprocessor macros in
>> -dt-bindings/clock/exynos5250.h header and can be used in device
>> -tree sources.
>> -
>> -Example 1: An example of a clock controller node is listed below.
>> -
>> -       clock: clock-controller at 10010000 {
>> -               compatible = "samsung,exynos5250-clock";
>> -               reg = <0x10010000 0x30000>;
>> -               #clock-cells = <1>;
>> -       };
>> -
>> -Example 2: UART controller node that consumes the clock generated by the clock
>> -          controller. Refer to the standard clock bindings for information
>> -          about 'clocks' and 'clock-names' property.
>> -
>> -       serial at 13820000 {
>> -               compatible = "samsung,exynos4210-uart";
>> -               reg = <0x13820000 0x100>;
>> -               interrupts = <0 54 0>;
>> -               clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
>> -               clock-names = "uart", "clk_uart_baud0";
>> -       };
>> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> new file mode 100644
>> index 000000000000..cd6567bd8cc7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> @@ -0,0 +1,48 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/samsung,exynos-clock.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Samsung Exynos SoC clock controller
>> +
>> +maintainers:
>> +  - Chanwoo Choi <cw00.choi at samsung.com>
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
>> +  - Tomasz Figa <tomasz.figa at gmail.com>
>> +
>> +description: |
>> +  All available clocks are defined as preprocessor macros in
>> +  dt-bindings/clock/ headers.
>> +
>> +properties:
>> +  compatible:
>> +    const: samsung,exynos5250-clock
>> +
>> +  assigned-clocks: true
>> +  assigned-clock-parents: true
>> +  assigned-clock-rates: true
>> +  clocks: true
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +required:
>> +  - compatible
>> +  - "#clock-cells"
>> +  - reg
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/exynos5250.h>
>> +    clock: clock-controller at 10010000 {
>> +        compatible = "samsung,exynos5250-clock";
>> +        reg = <0x10010000 0x30000>;
>> +        #clock-cells = <1>;
>> +    };
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 36aee8517ab0..2dbacacac3f5 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -16491,6 +16491,7 @@ L:      linux-samsung-soc at vger.kernel.org
>>  S:     Supported
>>  T:     git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
>>  F:     Documentation/devicetree/bindings/clock/exynos*.txt
> 
> Are there any exynos*.txt bindings actually left after this series? If
> no, maybe it's worth to remove this line while at it.

Yes, there are. These are the bindings which expect specific  external
fixed clock and I don't know yet how to model it in dtschema.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Aug 10 23:45:19 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 08:45:19 +0200
Subject: [PATCH v2 2/8] dt-bindings: clock: samsung: add bindings for
 Exynos external clock
In-Reply-To: <CAPLW+4mKv0Azi4w2S=Ono1gpghmBtfy4QpaRBjtHkgrUGZVW_Q@mail.gmail.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-3-krzysztof.kozlowski@canonical.com>
 <CAPLW+4mKv0Azi4w2S=Ono1gpghmBtfy4QpaRBjtHkgrUGZVW_Q@mail.gmail.com>
Message-ID: <fb4cf910-8465-7efc-184f-eef691cf614d@canonical.com>

On 10/08/2021 19:49, Sam Protsenko wrote:
> On Tue, 10 Aug 2021 at 12:32, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Document the bindings for Samsung Exynos external to SoC
>> (oscclk/XXTI/XusbXTI) clock provided on boards.  The bindings are
>> already implemented in most of the Exynos clock drivers and DTS files.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
> 
> Just want to mention that remaining users of such fixed clocks can be
> converted to regular fixed-rate-clock, and then this binding can be
> removed along with samsung_clk_of_register_fixed_ext() API? Just a
> thought.

Removal of samsung_clk_of_register_fixed_ext() would cause ABI break,
probably acceptable for these devices. Yet still, someone would have to
do it and test it.



Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Aug 10 23:46:46 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 08:46:46 +0200
Subject: [PATCH v2 6/8] dt-bindings: clock: samsung: convert Exynos AudSS
 to dtschema
In-Reply-To: <CAPLW+4=tOpaNGs6vxwyVy7xaeX+w_jhtY2P2U8sZGvm6mdqh1Q@mail.gmail.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-7-krzysztof.kozlowski@canonical.com>
 <CAPLW+4=tOpaNGs6vxwyVy7xaeX+w_jhtY2P2U8sZGvm6mdqh1Q@mail.gmail.com>
Message-ID: <2f8ff138-4d34-619c-e137-099dc9251e25@canonical.com>

On 10/08/2021 19:46, Sam Protsenko wrote:
> On Tue, 10 Aug 2021 at 12:32, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
>> schema format using json-schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
>>  .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
>>  2 files changed, 79 insertions(+), 103 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>> deleted file mode 100644
>> index 6030afb10b5c..000000000000
>> --- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>> +++ /dev/null
>> @@ -1,103 +0,0 @@
>> -* Samsung Audio Subsystem Clock Controller
>> -
>> -The Samsung Audio Subsystem clock controller generates and supplies clocks
>> -to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
>> -binding described here is applicable to all SoCs in Exynos family.
>> -
>> -Required Properties:
>> -
>> -- compatible: should be one of the following:
>> -  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
>> -  - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
>> -    SoCs.
>> -  - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
>> -    SoCs.
>> -  - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
>> -    SoCs.
>> -- reg: physical base address and length of the controller's register set.
>> -
>> -- #clock-cells: should be 1.
>> -
>> -- clocks:
>> -  - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
>> -    is used if not specified.
>> -  - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
>> -    is used if not specified.
>> -  - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
>> -    specified.
>> -  - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
>> -    not specified.
>> -  - sclk_pcm_in: PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not
>> -    specified.
>> -
>> -- clock-names: Aliases for the above clocks. They should be "pll_ref",
>> -  "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
>> -
>> -Optional Properties:
>> -
>> -  - power-domains: a phandle to respective power domain node as described by
>> -    generic PM domain bindings (see power/power_domain.txt for more
>> -    information).
>> -
>> -The following is the list of clocks generated by the controller. Each clock is
>> -assigned an identifier and client nodes use this identifier to specify the
>> -clock which they consume. Some of the clocks are available only on a particular
>> -Exynos4 SoC and this is specified where applicable.
>> -
>> -Provided clocks:
>> -
>> -Clock           ID      SoC (if specific)
>> ------------------------------------------------
>> -
>> -mout_audss      0
>> -mout_i2s        1
>> -dout_srp        2
>> -dout_aud_bus    3
>> -dout_i2s        4
>> -srp_clk         5
>> -i2s_bus         6
>> -sclk_i2s        7
>> -pcm_bus         8
>> -sclk_pcm        9
>> -adma            10      Exynos5420
>> -
>> -Example 1: An example of a clock controller node using the default input
>> -          clock names is listed below.
>> -
>> -clock_audss: audss-clock-controller at 3810000 {
>> -       compatible = "samsung,exynos5250-audss-clock";
>> -       reg = <0x03810000 0x0C>;
>> -       #clock-cells = <1>;
>> -};
>> -
>> -Example 2: An example of a clock controller node with the input clocks
>> -           specified.
>> -
>> -clock_audss: audss-clock-controller at 3810000 {
>> -       compatible = "samsung,exynos5250-audss-clock";
>> -       reg = <0x03810000 0x0C>;
>> -       #clock-cells = <1>;
>> -       clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
>> -               <&ext_i2s_clk>;
>> -       clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
>> -};
>> -
>> -Example 3: I2S controller node that consumes the clock generated by the clock
>> -           controller. Refer to the standard clock bindings for information
>> -           about 'clocks' and 'clock-names' property.
>> -
>> -i2s0: i2s at 3830000 {
>> -       compatible = "samsung,i2s-v5";
>> -       reg = <0x03830000 0x100>;
>> -       dmas = <&pdma0 10
>> -               &pdma0 9
>> -               &pdma0 8>;
>> -       dma-names = "tx", "rx", "tx-sec";
>> -       clocks = <&clock_audss EXYNOS_I2S_BUS>,
>> -               <&clock_audss EXYNOS_I2S_BUS>,
>> -               <&clock_audss EXYNOS_SCLK_I2S>,
>> -               <&clock_audss EXYNOS_MOUT_AUDSS>,
>> -               <&clock_audss EXYNOS_MOUT_I2S>;
>> -       clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
>> -                     "mout_audss", "mout_i2s";
>> -};
> 
> Seems like some examples and "Provided clocks" table were dropped in
> in yaml binding. Also there is no description for example present in
> yaml file. Is that some redundant info and was dropped intentionally?
> I'm just worrying about losing some useful info during the conversion.

I don't see any point of having a clock consumer example in a clock
provider binding.


Best regards,
Krzysztof


From kishon at ti.com  Tue Aug 10 23:46:48 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:48 +0530
Subject: [PATCH v8 0/8] Add SR-IOV support in PCIe Endpoint Core
Message-ID: <20210811064656.15399-1-kishon@ti.com>

Patch series
*) Adds support to add virtual functions to enable endpoint controller
   which supports SR-IOV capability
*) Add support in Cadence endpoint driver to configure virtual functions
*) Enable pci_endpoint_test driver to create pci_device for virtual
   functions

v1 of the patch series can be found at [1]
v2 of the patch series can be found at [2]
v3 of the patch series can be found at [3]
v4 of the patch series can be found at [4]
v5 of the patch series can be found at [5]
v6 of the patch series can be found at [6]
v7 of the patch series can be found at [7]

Here both physical functions and virtual functions use the same
pci_endpoint_test driver and existing pcitest utility can be used
to test virtual functions as well.

Changes from v7:
1) Added conditional operator to consicely write code to configure BAR
   (Added a new patch to first simplify configuring BAR for physical
    function)
2) Return error if virtual function number is > 1 for configuring config
   space header

Changes from v6:
*) Rebased to 5.14-rc4

Changes from v5:
*) Rebased to 5.13-rc1

Changes from v4:
*) Added a fix in Cadence driver which was overwriting BAR configuration
   of physical function.
*) Didn't include Tom's Acked-by since Cadence driver is modified in
   this revision.

Changes from v3:
*) Fixed Rob's comment and added his Reviewed-by as suggested by him.

Changes from v2:
*) Fixed DT binding documentation comment by Rob
*) Fixed the error check in pci-epc-core.c

Changes from v1:
*) Re-based and Re-worked to latest kernel 5.10.0-rc2+ (now has generic
   binding for EP)

[1] -> http://lore.kernel.org/r/20191231113534.30405-1-kishon at ti.com
[2] -> http://lore.kernel.org/r/20201112175358.2653-1-kishon at ti.com
[3] -> https://lore.kernel.org/r/20210305050410.9201-1-kishon at ti.com
[4] -> http://lore.kernel.org/r/20210310160943.7606-1-kishon at ti.com
[5] -> https://lore.kernel.org/r/20210419083401.31628-1-kishon at ti.com
[6] -> http://lore.kernel.org/r/20210517074723.10212-1-kishon at ti.com
[7] -> https://lore.kernel.org/r/20210803050310.27122-1-kishon at ti.com

Kishon Vijay Abraham I (8):
  dt-bindings: PCI: pci-ep: Add binding to specify virtual function
  PCI: endpoint: Add support to add virtual function in endpoint core
  PCI: endpoint: Add support to link a physical function to a virtual
    function
  PCI: endpoint: Add virtual function number in pci_epc ops
  PCI: cadence: Simplify code to get register base address for
    configuring BAR
  PCI: cadence: Add support to configure virtual functions
  misc: pci_endpoint_test: Populate sriov_configure ops to configure
    SR-IOV device
  Documentation: PCI: endpoint/pci-endpoint-cfs: Guide to use SR-IOV

 .../PCI/endpoint/pci-endpoint-cfs.rst         |  12 +-
 .../devicetree/bindings/pci/pci-ep.yaml       |   7 +
 drivers/misc/pci_endpoint_test.c              |   1 +
 .../pci/controller/cadence/pcie-cadence-ep.c  | 194 +++++++++++++-----
 drivers/pci/controller/cadence/pcie-cadence.h |  11 +
 .../pci/controller/dwc/pcie-designware-ep.c   |  36 ++--
 drivers/pci/controller/pcie-rcar-ep.c         |  19 +-
 drivers/pci/controller/pcie-rockchip-ep.c     |  18 +-
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  89 ++++----
 drivers/pci/endpoint/functions/pci-epf-test.c |  74 ++++---
 drivers/pci/endpoint/pci-ep-cfs.c             |  24 +++
 drivers/pci/endpoint/pci-epc-core.c           | 134 ++++++++----
 drivers/pci/endpoint/pci-epf-core.c           | 144 ++++++++++++-
 include/linux/pci-epc.h                       |  57 ++---
 include/linux/pci-epf.h                       |  16 +-
 15 files changed, 611 insertions(+), 225 deletions(-)

-- 
2.17.1



From kishon at ti.com  Tue Aug 10 23:46:49 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:49 +0530
Subject: [PATCH v8 1/8] dt-bindings: PCI: pci-ep: Add binding to specify
 virtual function
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <20210811064656.15399-2-kishon@ti.com>

Add binding to specify virtual function (associated with each physical
function) in endpoint mode.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/pci/pci-ep.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/pci-ep.yaml b/Documentation/devicetree/bindings/pci/pci-ep.yaml
index 7847bbcd4a03..ccec51ab5247 100644
--- a/Documentation/devicetree/bindings/pci/pci-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/pci-ep.yaml
@@ -23,6 +23,13 @@ properties:
     default: 1
     maximum: 255
 
+  max-virtual-functions:
+    description: Array representing the number of virtual functions corresponding to each physical
+      function
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    minItems: 1
+    maxItems: 255
+
   max-link-speed:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [ 1, 2, 3, 4 ]
-- 
2.17.1



From kishon at ti.com  Tue Aug 10 23:46:50 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:50 +0530
Subject: [PATCH v8 2/8] PCI: endpoint: Add support to add virtual function in
 endpoint core
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <20210811064656.15399-3-kishon@ti.com>

Add support to add virtual function in endpoint core. The virtual
function can only be associated with a physical function instead of a
endpoint controller. Provide APIs to associate a virtual function with
a physical function here.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/endpoint/pci-epc-core.c |  2 +-
 drivers/pci/endpoint/pci-epf-core.c | 96 ++++++++++++++++++++++++++++-
 include/linux/pci-epf.h             | 16 ++++-
 3 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index adec9bee72cf..01c58ca84dcc 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -548,7 +548,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf,
 	u32 func_no;
 	int ret = 0;
 
-	if (IS_ERR_OR_NULL(epc))
+	if (IS_ERR_OR_NULL(epc) || epf->is_vf)
 		return -EINVAL;
 
 	if (type == PRIMARY_INTERFACE && epf->epc)
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index e9289d10f822..ae7107a3196e 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -62,13 +62,20 @@ EXPORT_SYMBOL_GPL(pci_epf_type_add_cfs);
  */
 void pci_epf_unbind(struct pci_epf *epf)
 {
+	struct pci_epf *epf_vf;
+
 	if (!epf->driver) {
 		dev_WARN(&epf->dev, "epf device not bound to driver\n");
 		return;
 	}
 
 	mutex_lock(&epf->lock);
-	epf->driver->ops->unbind(epf);
+	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		if (epf_vf->is_bound)
+			epf_vf->driver->ops->unbind(epf_vf);
+	}
+	if (epf->is_bound)
+		epf->driver->ops->unbind(epf);
 	mutex_unlock(&epf->lock);
 	module_put(epf->driver->owner);
 }
@@ -83,6 +90,7 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind);
  */
 int pci_epf_bind(struct pci_epf *epf)
 {
+	struct pci_epf *epf_vf;
 	int ret;
 
 	if (!epf->driver) {
@@ -94,13 +102,95 @@ int pci_epf_bind(struct pci_epf *epf)
 		return -EAGAIN;
 
 	mutex_lock(&epf->lock);
+	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		epf_vf->func_no = epf->func_no;
+		epf_vf->epc = epf->epc;
+		epf_vf->sec_epc = epf->sec_epc;
+		ret = epf_vf->driver->ops->bind(epf_vf);
+		if (ret)
+			goto ret;
+		epf_vf->is_bound = true;
+	}
+
 	ret = epf->driver->ops->bind(epf);
+	if (ret)
+		goto ret;
+	epf->is_bound = true;
+
+	mutex_unlock(&epf->lock);
+	return 0;
+
+ret:
 	mutex_unlock(&epf->lock);
+	pci_epf_unbind(epf);
 
 	return ret;
 }
 EXPORT_SYMBOL_GPL(pci_epf_bind);
 
+/**
+ * pci_epf_add_vepf() - associate virtual EP function to physical EP function
+ * @epf_pf: the physical EP function to which the virtual EP function should be
+ *   associated
+ * @epf_vf: the virtual EP function to be added
+ *
+ * A physical endpoint function can be associated with multiple virtual
+ * endpoint functions. Invoke pci_epf_add_epf() to add a virtual PCI endpoint
+ * function to a physical PCI endpoint function.
+ */
+int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf)
+{
+	u32 vfunc_no;
+
+	if (IS_ERR_OR_NULL(epf_pf) || IS_ERR_OR_NULL(epf_vf))
+		return -EINVAL;
+
+	if (epf_pf->epc || epf_vf->epc || epf_vf->epf_pf)
+		return -EBUSY;
+
+	if (epf_pf->sec_epc || epf_vf->sec_epc)
+		return -EBUSY;
+
+	mutex_lock(&epf_pf->lock);
+	vfunc_no = find_first_zero_bit(&epf_pf->vfunction_num_map,
+				       BITS_PER_LONG);
+	if (vfunc_no >= BITS_PER_LONG)
+		return -EINVAL;
+
+	set_bit(vfunc_no, &epf_pf->vfunction_num_map);
+	epf_vf->vfunc_no = vfunc_no;
+
+	epf_vf->epf_pf = epf_pf;
+	epf_vf->is_vf = true;
+
+	list_add_tail(&epf_vf->list, &epf_pf->pci_vepf);
+	mutex_unlock(&epf_pf->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_add_vepf);
+
+/**
+ * pci_epf_remove_vepf() - remove virtual EP function from physical EP function
+ * @epf_pf: the physical EP function from which the virtual EP function should
+ *   be removed
+ * @epf_vf: the virtual EP function to be removed
+ *
+ * Invoke to remove a virtual endpoint function from the physcial endpoint
+ * function.
+ */
+void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf)
+{
+	if (IS_ERR_OR_NULL(epf_pf) || IS_ERR_OR_NULL(epf_vf))
+		return;
+
+	mutex_lock(&epf_pf->lock);
+	clear_bit(epf_vf->vfunc_no, &epf_pf->vfunction_num_map);
+	list_del(&epf_vf->list);
+	mutex_unlock(&epf_pf->lock);
+}
+EXPORT_SYMBOL_GPL(pci_epf_remove_vepf);
+
 /**
  * pci_epf_free_space() - free the allocated PCI EPF register space
  * @epf: the EPF device from whom to free the memory
@@ -317,6 +407,10 @@ struct pci_epf *pci_epf_create(const char *name)
 		return ERR_PTR(-ENOMEM);
 	}
 
+	/* VFs are numbered starting with 1. So set BIT(0) by default */
+	epf->vfunction_num_map = 1;
+	INIT_LIST_HEAD(&epf->pci_vepf);
+
 	dev = &epf->dev;
 	device_initialize(dev);
 	dev->bus = &pci_epf_bus_type;
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 2debc27ba95e..043b4c9c7188 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -121,8 +121,10 @@ struct pci_epf_bar {
  * @bar: represents the BAR of EPF device
  * @msi_interrupts: number of MSI interrupts required by this function
  * @msix_interrupts: number of MSI-X interrupts required by this function
- * @func_no: unique function number within this endpoint device
+ * @func_no: unique (physical) function number within this endpoint device
+ * @vfunc_no: unique virtual function number within a physical function
  * @epc: the EPC device to which this EPF device is bound
+ * @epf_pf: the physical EPF device to which this virtual EPF device is bound
  * @driver: the EPF driver to which this EPF device is bound
  * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc
  * @nb: notifier block to notify EPF of any EPC events (like linkup)
@@ -133,6 +135,10 @@ struct pci_epf_bar {
  * @sec_epc_bar: represents the BAR of EPF device associated with secondary EPC
  * @sec_epc_func_no: unique (physical) function number within the secondary EPC
  * @group: configfs group associated with the EPF device
+ * @is_bound: indicates if bind notification to function driver has been invoked
+ * @is_vf: true - virtual function, false - physical function
+ * @vfunction_num_map: bitmap to manage virtual function number
+ * @pci_vepf: list of virtual endpoint functions associated with this function
  */
 struct pci_epf {
 	struct device		dev;
@@ -142,8 +148,10 @@ struct pci_epf {
 	u8			msi_interrupts;
 	u16			msix_interrupts;
 	u8			func_no;
+	u8			vfunc_no;
 
 	struct pci_epc		*epc;
+	struct pci_epf		*epf_pf;
 	struct pci_epf_driver	*driver;
 	struct list_head	list;
 	struct notifier_block   nb;
@@ -156,6 +164,10 @@ struct pci_epf {
 	struct pci_epf_bar	sec_epc_bar[6];
 	u8			sec_epc_func_no;
 	struct config_group	*group;
+	unsigned int		is_bound;
+	unsigned int		is_vf;
+	unsigned long		vfunction_num_map;
+	struct list_head	pci_vepf;
 };
 
 /**
@@ -199,4 +211,6 @@ int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
 struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf,
 					  struct config_group *group);
+int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);
+void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);
 #endif /* __LINUX_PCI_EPF_H */
-- 
2.17.1



From kishon at ti.com  Tue Aug 10 23:46:51 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:51 +0530
Subject: [PATCH v8 3/8] PCI: endpoint: Add support to link a physical function
 to a virtual function
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <20210811064656.15399-4-kishon@ti.com>

While the physical function has to be linked to endpoint controller, the
virtual function has to be linked to a physical function. Add support to
link a physical function to a virtual function in pci-ep-cfs.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/endpoint/pci-ep-cfs.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
index f3a8b833b479..999911801877 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -475,6 +475,28 @@ static struct configfs_attribute *pci_epf_attrs[] = {
 	NULL,
 };
 
+static int pci_epf_vepf_link(struct config_item *epf_pf_item,
+			     struct config_item *epf_vf_item)
+{
+	struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
+	struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
+	struct pci_epf *epf_pf = epf_pf_group->epf;
+	struct pci_epf *epf_vf = epf_vf_group->epf;
+
+	return pci_epf_add_vepf(epf_pf, epf_vf);
+}
+
+static void pci_epf_vepf_unlink(struct config_item *epf_pf_item,
+				struct config_item *epf_vf_item)
+{
+	struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
+	struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
+	struct pci_epf *epf_pf = epf_pf_group->epf;
+	struct pci_epf *epf_vf = epf_vf_group->epf;
+
+	pci_epf_remove_vepf(epf_pf, epf_vf);
+}
+
 static void pci_epf_release(struct config_item *item)
 {
 	struct pci_epf_group *epf_group = to_pci_epf_group(item);
@@ -487,6 +509,8 @@ static void pci_epf_release(struct config_item *item)
 }
 
 static struct configfs_item_operations pci_epf_ops = {
+	.allow_link		= pci_epf_vepf_link,
+	.drop_link		= pci_epf_vepf_unlink,
 	.release		= pci_epf_release,
 };
 
-- 
2.17.1



From kishon at ti.com  Tue Aug 10 23:46:52 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:52 +0530
Subject: [PATCH v8 4/8] PCI: endpoint: Add virtual function number in pci_epc
 ops
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <20210811064656.15399-5-kishon@ti.com>

Add virtual function number in pci_epc ops. EPC controller driver
can perform virtual function specific initialization based on the
virtual function number.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c  |  44 +++---
 .../pci/controller/dwc/pcie-designware-ep.c   |  36 ++---
 drivers/pci/controller/pcie-rcar-ep.c         |  19 +--
 drivers/pci/controller/pcie-rockchip-ep.c     |  18 +--
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  89 +++++++-----
 drivers/pci/endpoint/functions/pci-epf-test.c |  74 +++++-----
 drivers/pci/endpoint/pci-epc-core.c           | 132 +++++++++++++-----
 drivers/pci/endpoint/pci-epf-core.c           |  48 ++++++-
 include/linux/pci-epc.h                       |  57 ++++----
 9 files changed, 328 insertions(+), 189 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 897cdde02bd8..912a15be8bfd 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -16,7 +16,7 @@
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE		0x1
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY	0x3
 
-static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -47,7 +47,7 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				struct pci_epf_bar *epf_bar)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -117,7 +117,7 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				   struct pci_epf_bar *epf_bar)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -147,8 +147,8 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 	epf->epf_bar[bar] = NULL;
 }
 
-static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
-				 u64 pci_addr, size_t size)
+static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
+				 phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -169,7 +169,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
 	return 0;
 }
 
-static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -189,7 +189,7 @@ static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
 	clear_bit(r, &ep->ob_region_map);
 }
 
-static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 mmc)
+static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -209,7 +209,7 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 mmc)
 	return 0;
 }
 
-static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -230,7 +230,7 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
 	return mme;
 }
 
-static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -247,8 +247,9 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u16 interrupts,
-				 enum pci_barno bir, u32 offset)
+static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
+				 u16 interrupts, enum pci_barno bir,
+				 u32 offset)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -317,7 +318,8 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
 	writel(0, ep->irq_cpu_addr + offset);
 }
 
-static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 intx)
+static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
+					u8 intx)
 {
 	u16 cmd;
 
@@ -334,7 +336,7 @@ static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 intx)
 	return 0;
 }
 
-static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
+static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				     u8 interrupt_num)
 {
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -382,7 +384,7 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr, u8 interrupt_num,
 				    u32 entry_size, u32 *msi_data,
 				    u32 *msi_addr_offset)
@@ -419,7 +421,7 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
 	pci_addr &= GENMASK_ULL(63, 2);
 
 	for (i = 0; i < interrupt_num; i++) {
-		ret = cdns_pcie_ep_map_addr(epc, fn, addr,
+		ret = cdns_pcie_ep_map_addr(epc, fn, vfn, addr,
 					    pci_addr & ~pci_addr_mask,
 					    entry_size);
 		if (ret)
@@ -433,7 +435,7 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
+static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				      u16 interrupt_num)
 {
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
@@ -478,7 +480,7 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  enum pci_epc_irq_type type,
 				  u16 interrupt_num)
 {
@@ -486,13 +488,13 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
 
 	switch (type) {
 	case PCI_EPC_IRQ_LEGACY:
-		return cdns_pcie_ep_send_legacy_irq(ep, fn, 0);
+		return cdns_pcie_ep_send_legacy_irq(ep, fn, vfn, 0);
 
 	case PCI_EPC_IRQ_MSI:
-		return cdns_pcie_ep_send_msi_irq(ep, fn, interrupt_num);
+		return cdns_pcie_ep_send_msi_irq(ep, fn, vfn, interrupt_num);
 
 	case PCI_EPC_IRQ_MSIX:
-		return cdns_pcie_ep_send_msix_irq(ep, fn, interrupt_num);
+		return cdns_pcie_ep_send_msix_irq(ep, fn, vfn, interrupt_num);
 
 	default:
 		break;
@@ -531,7 +533,7 @@ static const struct pci_epc_features cdns_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &cdns_pcie_epc_features;
 }
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 8d028a88b375..998b698f4085 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -125,7 +125,7 @@ static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap)
 	return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap);
 }
 
-static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				   struct pci_epf_header *hdr)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -202,7 +202,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
 	return 0;
 }
 
-static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
+static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				 struct pci_epf_bar *epf_bar)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -217,7 +217,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
 	ep->epf_bar[bar] = NULL;
 }
 
-static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			      struct pci_epf_bar *epf_bar)
 {
 	int ret;
@@ -276,7 +276,7 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
 	return -EINVAL;
 }
 
-static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
+static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				  phys_addr_t addr)
 {
 	int ret;
@@ -292,9 +292,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
 	clear_bit(atu_index, ep->ob_window_map);
 }
 
-static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
-			       phys_addr_t addr,
-			       u64 pci_addr, size_t size)
+static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			       phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	int ret;
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -309,7 +308,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
 	return 0;
 }
 
-static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
+static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -333,7 +332,8 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
+static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			      u8 interrupts)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -358,7 +358,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 	return 0;
 }
 
-static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -382,8 +382,8 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-			       enum pci_barno bir, u32 offset)
+static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			       u16 interrupts, enum pci_barno bir, u32 offset)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -418,7 +418,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
 	return 0;
 }
 
-static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				enum pci_epc_irq_type type, u16 interrupt_num)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -450,7 +450,7 @@ static int dw_pcie_ep_start(struct pci_epc *epc)
 }
 
 static const struct pci_epc_features*
-dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 
@@ -525,14 +525,14 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 	aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1);
 	msg_addr = ((u64)msg_addr_upper) << 32 |
 			(msg_addr_lower & ~aligned_offset);
-	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
+	ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
 				  epc->mem->window.page_size);
 	if (ret)
 		return ret;
 
 	writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset);
 
-	dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
+	dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
 
 	return 0;
 }
@@ -593,14 +593,14 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	}
 
 	aligned_offset = msg_addr & (epc->mem->window.page_size - 1);
-	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,  msg_addr,
+	ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
 				  epc->mem->window.page_size);
 	if (ret)
 		return ret;
 
 	writel(msg_data, ep->msi_mem + aligned_offset);
 
-	dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
+	dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
 
 	return 0;
 }
diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
index b4a288e24aaf..6cee4e09acca 100644
--- a/drivers/pci/controller/pcie-rcar-ep.c
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -159,7 +159,7 @@ static int rcar_pcie_ep_get_pdata(struct rcar_pcie_endpoint *ep,
 	return 0;
 }
 
-static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -195,7 +195,7 @@ static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				struct pci_epf_bar *epf_bar)
 {
 	int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT;
@@ -246,7 +246,7 @@ static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
 	return 0;
 }
 
-static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				   struct pci_epf_bar *epf_bar)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -259,7 +259,8 @@ static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 	clear_bit(atu_index + 1, ep->ib_window_map);
 }
 
-static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
+static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
+				u8 interrupts)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
 	struct rcar_pcie *pcie = &ep->pcie;
@@ -272,7 +273,7 @@ static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
 	return 0;
 }
 
-static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
 	struct rcar_pcie *pcie = &ep->pcie;
@@ -285,7 +286,7 @@ static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
 	return ((flags & MSICAP0_MMESE_MASK) >> MSICAP0_MMESE_OFFSET);
 }
 
-static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				 phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -322,7 +323,7 @@ static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rcar_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void rcar_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -403,7 +404,7 @@ static int rcar_pcie_ep_assert_msi(struct rcar_pcie *pcie,
 	return 0;
 }
 
-static int rcar_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  enum pci_epc_irq_type type,
 				  u16 interrupt_num)
 {
@@ -451,7 +452,7 @@ static const struct pci_epc_features rcar_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-rcar_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+rcar_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &rcar_pcie_epc_features;
 }
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index 7631dc3961c1..5fb9ce6e536e 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -122,7 +122,7 @@ static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn,
 			    ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r));
 }
 
-static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 					 struct pci_epf_header *hdr)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -159,7 +159,7 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				    struct pci_epf_bar *epf_bar)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -227,7 +227,7 @@ static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				       struct pci_epf_bar *epf_bar)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -256,7 +256,7 @@ static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 			    ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar));
 }
 
-static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				     phys_addr_t addr, u64 pci_addr,
 				     size_t size)
 {
@@ -284,7 +284,7 @@ static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 					phys_addr_t addr)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -308,7 +308,7 @@ static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
 	clear_bit(r, &ep->ob_region_map);
 }
 
-static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
 				    u8 multi_msg_cap)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -329,7 +329,7 @@ static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
 	struct rockchip_pcie *rockchip = &ep->rockchip;
@@ -471,7 +471,7 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				      enum pci_epc_irq_type type,
 				      u16 interrupt_num)
 {
@@ -510,7 +510,7 @@ static const struct pci_epc_features rockchip_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &rockchip_pcie_epc_features;
 }
diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c b/drivers/pci/endpoint/functions/pci-epf-ntb.c
index bce274d02dcf..8b4756159f15 100644
--- a/drivers/pci/endpoint/functions/pci-epf-ntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c
@@ -87,6 +87,7 @@ struct epf_ntb {
 
 struct epf_ntb_epc {
 	u8 func_no;
+	u8 vfunc_no;
 	bool linkup;
 	bool is_msix;
 	int msix_bar;
@@ -143,14 +144,15 @@ static int epf_ntb_link_up(struct epf_ntb *ntb, bool link_up)
 	struct epf_ntb_epc *ntb_epc;
 	struct epf_ntb_ctrl *ctrl;
 	struct pci_epc *epc;
+	u8 func_no, vfunc_no;
 	bool is_msix;
-	u8 func_no;
 	int ret;
 
 	for (type = PRIMARY_INTERFACE; type <= SECONDARY_INTERFACE; type++) {
 		ntb_epc = ntb->epc[type];
 		epc = ntb_epc->epc;
 		func_no = ntb_epc->func_no;
+		vfunc_no = ntb_epc->vfunc_no;
 		is_msix = ntb_epc->is_msix;
 		ctrl = ntb_epc->reg;
 		if (link_up)
@@ -158,7 +160,7 @@ static int epf_ntb_link_up(struct epf_ntb *ntb, bool link_up)
 		else
 			ctrl->link_status &= ~LINK_STATUS_UP;
 		irq_type = is_msix ? PCI_EPC_IRQ_MSIX : PCI_EPC_IRQ_MSI;
-		ret = pci_epc_raise_irq(epc, func_no, irq_type, 1);
+		ret = pci_epc_raise_irq(epc, func_no, vfunc_no, irq_type, 1);
 		if (ret) {
 			dev_err(&epc->dev,
 				"%s intf: Failed to raise Link Up IRQ\n",
@@ -238,10 +240,10 @@ static int epf_ntb_configure_mw(struct epf_ntb *ntb,
 	enum pci_barno peer_barno;
 	struct epf_ntb_ctrl *ctrl;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	u64 addr, size;
 	int ret = 0;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -267,8 +269,9 @@ static int epf_ntb_configure_mw(struct epf_ntb *ntb,
 	}
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	ret = pci_epc_map_addr(epc, func_no, phys_addr, addr, size);
+	ret = pci_epc_map_addr(epc, func_no, vfunc_no, phys_addr, addr, size);
 	if (ret)
 		dev_err(&epc->dev,
 			"%s intf: Failed to map memory window %d address\n",
@@ -296,8 +299,8 @@ static void epf_ntb_teardown_mw(struct epf_ntb *ntb,
 	enum pci_barno peer_barno;
 	struct epf_ntb_ctrl *ctrl;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -311,8 +314,9 @@ static void epf_ntb_teardown_mw(struct epf_ntb *ntb,
 	if (mw + NTB_MW_OFFSET == BAR_DB_MW1)
 		phys_addr += ctrl->mw1_offset;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	pci_epc_unmap_addr(epc, func_no, phys_addr);
+	pci_epc_unmap_addr(epc, func_no, vfunc_no, phys_addr);
 }
 
 /**
@@ -385,8 +389,8 @@ static int epf_ntb_configure_msi(struct epf_ntb *ntb,
 	struct epf_ntb_ctrl *peer_ctrl;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 	int ret, i;
 
 	ntb_epc = ntb->epc[type];
@@ -400,8 +404,9 @@ static int epf_ntb_configure_msi(struct epf_ntb *ntb,
 
 	phys_addr = peer_epf_bar->phys_addr;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	ret = pci_epc_map_msi_irq(epc, func_no, phys_addr, db_count,
+	ret = pci_epc_map_msi_irq(epc, func_no, vfunc_no, phys_addr, db_count,
 				  db_entry_size, &db_data, &db_offset);
 	if (ret) {
 		dev_err(&epc->dev, "%s intf: Failed to map MSI IRQ\n",
@@ -491,10 +496,10 @@ static int epf_ntb_configure_msix(struct epf_ntb *ntb,
 	u32 db_entry_size, msg_data;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	size_t align;
 	u64 msg_addr;
-	u8 func_no;
 	int ret, i;
 
 	ntb_epc = ntb->epc[type];
@@ -512,12 +517,13 @@ static int epf_ntb_configure_msix(struct epf_ntb *ntb,
 	align = epc_features->align;
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	db_entry_size = peer_ctrl->db_entry_size;
 
 	for (i = 0; i < db_count; i++) {
 		msg_addr = ALIGN_DOWN(msix_tbl[i].msg_addr, align);
 		msg_data = msix_tbl[i].msg_data;
-		ret = pci_epc_map_addr(epc, func_no, phys_addr, msg_addr,
+		ret = pci_epc_map_addr(epc, func_no, vfunc_no, phys_addr, msg_addr,
 				       db_entry_size);
 		if (ret) {
 			dev_err(&epc->dev,
@@ -586,8 +592,8 @@ epf_ntb_teardown_db(struct epf_ntb *ntb, enum pci_epc_interface_type type)
 	struct pci_epf_bar *peer_epf_bar;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -597,8 +603,9 @@ epf_ntb_teardown_db(struct epf_ntb *ntb, enum pci_epc_interface_type type)
 	peer_epf_bar = &peer_ntb_epc->epf_bar[peer_barno];
 	phys_addr = peer_epf_bar->phys_addr;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	pci_epc_unmap_addr(epc, func_no, phys_addr);
+	pci_epc_unmap_addr(epc, func_no, vfunc_no, phys_addr);
 }
 
 /**
@@ -728,14 +735,15 @@ static void epf_ntb_peer_spad_bar_clear(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
 	epf_bar = &ntb_epc->epf_bar[barno];
-	pci_epc_clear_bar(epc, func_no, epf_bar);
+	pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 }
 
 /**
@@ -775,9 +783,9 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	struct pci_epf_bar *peer_epf_bar, *epf_bar;
 	enum pci_barno peer_barno, barno;
 	u32 peer_spad_offset;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	dev = &ntb->epf->dev;
@@ -790,6 +798,7 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
 	epf_bar = &ntb_epc->epf_bar[barno];
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	epc = ntb_epc->epc;
 
 	peer_spad_offset = peer_ntb_epc->reg->spad_offset;
@@ -798,7 +807,7 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	epf_bar->barno = barno;
 	epf_bar->flags = PCI_BASE_ADDRESS_MEM_TYPE_32;
 
-	ret = pci_epc_set_bar(epc, func_no, epf_bar);
+	ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 	if (ret) {
 		dev_err(dev, "%s intf: peer SPAD BAR set failed\n",
 			pci_epc_interface_string(type));
@@ -842,14 +851,15 @@ static void epf_ntb_config_sspad_bar_clear(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
 	epf_bar = &ntb_epc->epf_bar[barno];
-	pci_epc_clear_bar(epc, func_no, epf_bar);
+	pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 }
 
 /**
@@ -886,10 +896,10 @@ static int epf_ntb_config_sspad_bar_set(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct epf_ntb *ntb;
 	struct pci_epc *epc;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	ntb = ntb_epc->epf_ntb;
@@ -897,10 +907,11 @@ static int epf_ntb_config_sspad_bar_set(struct epf_ntb_epc *ntb_epc)
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
 	epf_bar = &ntb_epc->epf_bar[barno];
 
-	ret = pci_epc_set_bar(epc, func_no, epf_bar);
+	ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 	if (ret) {
 		dev_err(dev, "%s inft: Config/Status/SPAD BAR set failed\n",
 			pci_epc_interface_string(ntb_epc->type));
@@ -1214,17 +1225,18 @@ static void epf_ntb_db_mw_bar_clear(struct epf_ntb_epc *ntb_epc)
 	struct pci_epf_bar *epf_bar;
 	enum epf_ntb_bar bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	for (bar = BAR_DB_MW1; bar < BAR_MW4; bar++) {
 		barno = ntb_epc->epf_ntb_bar[bar];
 		epf_bar = &ntb_epc->epf_bar[barno];
-		pci_epc_clear_bar(epc, func_no, epf_bar);
+		pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 	}
 }
 
@@ -1263,10 +1275,10 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	const struct pci_epc_features *epc_features;
 	bool msix_capable, msi_capable;
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
 	u32 db_count;
-	u8 func_no;
 	int ret;
 
 	ntb_epc = ntb->epc[type];
@@ -1282,6 +1294,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	}
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	db_count = ntb->db_count;
 	if (db_count > MAX_DB_COUNT) {
@@ -1293,7 +1306,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	epc = ntb_epc->epc;
 
 	if (msi_capable) {
-		ret = pci_epc_set_msi(epc, func_no, db_count);
+		ret = pci_epc_set_msi(epc, func_no, vfunc_no, db_count);
 		if (ret) {
 			dev_err(dev, "%s intf: MSI configuration failed\n",
 				pci_epc_interface_string(type));
@@ -1302,7 +1315,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	}
 
 	if (msix_capable) {
-		ret = pci_epc_set_msix(epc, func_no, db_count,
+		ret = pci_epc_set_msix(epc, func_no, vfunc_no, db_count,
 				       ntb_epc->msix_bar,
 				       ntb_epc->msix_table_offset);
 		if (ret) {
@@ -1423,11 +1436,11 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 	u32 num_mws, db_count;
 	enum epf_ntb_bar bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
 	size_t align;
 	int ret, i;
-	u8 func_no;
 	u64 size;
 
 	ntb_epc = ntb->epc[type];
@@ -1437,6 +1450,7 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 	epc_features = ntb_epc->epc_features;
 	align = epc_features->align;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	epc = ntb_epc->epc;
 	num_mws = ntb->num_mws;
 	db_count = ntb->db_count;
@@ -1464,7 +1478,7 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 		barno = ntb_epc->epf_ntb_bar[bar];
 		epf_bar = &ntb_epc->epf_bar[barno];
 
-		ret = pci_epc_set_bar(epc, func_no, epf_bar);
+		ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 		if (ret) {
 			dev_err(dev, "%s intf: DoorBell BAR set failed\n",
 				pci_epc_interface_string(type));
@@ -1536,9 +1550,9 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 	const struct pci_epc_features *epc_features;
 	struct pci_epf_bar *epf_bar;
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epf *epf;
 	struct device *dev;
-	u8 func_no;
 
 	dev = &ntb->epf->dev;
 
@@ -1547,6 +1561,7 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 		return -ENOMEM;
 
 	epf = ntb->epf;
+	vfunc_no = epf->vfunc_no;
 	if (type == PRIMARY_INTERFACE) {
 		func_no = epf->func_no;
 		epf_bar = epf->bar;
@@ -1558,11 +1573,12 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 	ntb_epc->linkup = false;
 	ntb_epc->epc = epc;
 	ntb_epc->func_no = func_no;
+	ntb_epc->vfunc_no = vfunc_no;
 	ntb_epc->type = type;
 	ntb_epc->epf_bar = epf_bar;
 	ntb_epc->epf_ntb = ntb;
 
-	epc_features = pci_epc_get_features(epc, func_no);
+	epc_features = pci_epc_get_features(epc, func_no, vfunc_no);
 	if (!epc_features)
 		return -EINVAL;
 	ntb_epc->epc_features = epc_features;
@@ -1702,10 +1718,10 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 				      enum pci_epc_interface_type type)
 {
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct pci_epf *epf;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	ntb_epc = ntb->epc[type];
@@ -1713,6 +1729,7 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 	dev = &epf->dev;
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	ret = epf_ntb_config_sspad_bar_set(ntb->epc[type]);
 	if (ret) {
@@ -1742,11 +1759,13 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 		goto err_db_mw_bar_init;
 	}
 
-	ret = pci_epc_write_header(epc, func_no, epf->header);
-	if (ret) {
-		dev_err(dev, "%s intf: Configuration header write failed\n",
-			pci_epc_interface_string(type));
-		goto err_write_header;
+	if (vfunc_no <= 1) {
+		ret = pci_epc_write_header(epc, func_no, vfunc_no, epf->header);
+		if (ret) {
+			dev_err(dev, "%s intf: Configuration header write failed\n",
+				pci_epc_interface_string(type));
+			goto err_write_header;
+		}
 	}
 
 	INIT_DELAYED_WORK(&ntb->epc[type]->cmd_handler, epf_ntb_cmd_handler);
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index d2708ca4bece..90d84d3bc868 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -247,8 +247,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, src_phys_addr,
+			       reg->src_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map source address\n");
 		reg->status = STATUS_SRC_ADDR_INVALID;
@@ -263,8 +263,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 		goto err_src_map_addr;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, dst_phys_addr,
+			       reg->dst_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map destination address\n");
 		reg->status = STATUS_DST_ADDR_INVALID;
@@ -291,13 +291,13 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 	pci_epf_test_print_rate("COPY", reg->size, &start, &end, use_dma);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, dst_phys_addr);
 
 err_dst_addr:
 	pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
 
 err_src_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, src_phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, src_phys_addr);
 
 err_src_addr:
 	pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
@@ -331,8 +331,8 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, phys_addr,
+			       reg->src_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map address\n");
 		reg->status = STATUS_SRC_ADDR_INVALID;
@@ -386,7 +386,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 	kfree(buf);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, phys_addr);
 
 err_addr:
 	pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
@@ -419,8 +419,8 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, phys_addr,
+			       reg->dst_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map address\n");
 		reg->status = STATUS_DST_ADDR_INVALID;
@@ -479,7 +479,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 	kfree(buf);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, phys_addr);
 
 err_addr:
 	pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
@@ -501,13 +501,16 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq_type,
 
 	switch (irq_type) {
 	case IRQ_TYPE_LEGACY:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_LEGACY, 0);
 		break;
 	case IRQ_TYPE_MSI:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSI, irq);
 		break;
 	case IRQ_TYPE_MSIX:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX, irq);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSIX, irq);
 		break;
 	default:
 		dev_err(dev, "Failed to raise IRQ, unknown type\n");
@@ -542,7 +545,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 
 	if (command & COMMAND_RAISE_LEGACY_IRQ) {
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_LEGACY, 0);
 		goto reset_handler;
 	}
 
@@ -580,22 +584,22 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 	}
 
 	if (command & COMMAND_RAISE_MSI_IRQ) {
-		count = pci_epc_get_msi(epc, epf->func_no);
+		count = pci_epc_get_msi(epc, epf->func_no, epf->vfunc_no);
 		if (reg->irq_number > count || count <= 0)
 			goto reset_handler;
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI,
-				  reg->irq_number);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSI, reg->irq_number);
 		goto reset_handler;
 	}
 
 	if (command & COMMAND_RAISE_MSIX_IRQ) {
-		count = pci_epc_get_msix(epc, epf->func_no);
+		count = pci_epc_get_msix(epc, epf->func_no, epf->vfunc_no);
 		if (reg->irq_number > count || count <= 0)
 			goto reset_handler;
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX,
-				  reg->irq_number);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSIX, reg->irq_number);
 		goto reset_handler;
 	}
 
@@ -618,7 +622,8 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 		epf_bar = &epf->bar[bar];
 
 		if (epf_test->reg[bar]) {
-			pci_epc_clear_bar(epc, epf->func_no, epf_bar);
+			pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no,
+					  epf_bar);
 			pci_epf_free_space(epf, epf_test->reg[bar], bar,
 					   PRIMARY_INTERFACE);
 		}
@@ -650,7 +655,8 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
 		if (!!(epc_features->reserved_bar & (1 << bar)))
 			continue;
 
-		ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
+		ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
+				      epf_bar);
 		if (ret) {
 			pci_epf_free_space(epf, epf_test->reg[bar], bar,
 					   PRIMARY_INTERFACE);
@@ -674,16 +680,18 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 	bool msi_capable = true;
 	int ret;
 
-	epc_features = pci_epc_get_features(epc, epf->func_no);
+	epc_features = pci_epc_get_features(epc, epf->func_no, epf->vfunc_no);
 	if (epc_features) {
 		msix_capable = epc_features->msix_capable;
 		msi_capable = epc_features->msi_capable;
 	}
 
-	ret = pci_epc_write_header(epc, epf->func_no, header);
-	if (ret) {
-		dev_err(dev, "Configuration header write failed\n");
-		return ret;
+	if (epf->vfunc_no <= 1) {
+		ret = pci_epc_write_header(epc, epf->func_no, epf->vfunc_no, header);
+		if (ret) {
+			dev_err(dev, "Configuration header write failed\n");
+			return ret;
+		}
 	}
 
 	ret = pci_epf_test_set_bar(epf);
@@ -691,7 +699,8 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 		return ret;
 
 	if (msi_capable) {
-		ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
+		ret = pci_epc_set_msi(epc, epf->func_no, epf->vfunc_no,
+				      epf->msi_interrupts);
 		if (ret) {
 			dev_err(dev, "MSI configuration failed\n");
 			return ret;
@@ -699,7 +708,8 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 	}
 
 	if (msix_capable) {
-		ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts,
+		ret = pci_epc_set_msix(epc, epf->func_no, epf->vfunc_no,
+				       epf->msix_interrupts,
 				       epf_test->test_reg_bar,
 				       epf_test->msix_table_offset);
 		if (ret) {
@@ -832,7 +842,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 	if (WARN_ON_ONCE(!epc))
 		return -EINVAL;
 
-	epc_features = pci_epc_get_features(epc, epf->func_no);
+	epc_features = pci_epc_get_features(epc, epf->func_no, epf->vfunc_no);
 	if (!epc_features) {
 		dev_err(&epf->dev, "epc_features not implemented\n");
 		return -EOPNOTSUPP;
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 01c58ca84dcc..ecbb0fb3b653 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -137,24 +137,29 @@ EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar);
  * @epc: the features supported by *this* EPC device will be returned
  * @func_no: the features supported by the EPC device specific to the
  *	     endpoint function with func_no will be returned
+ * @vfunc_no: the features supported by the EPC device specific to the
+ *	     virtual endpoint function with vfunc_no will be returned
  *
  * Invoke to get the features provided by the EPC which may be
  * specific to an endpoint function. Returns pci_epc_features on success
  * and NULL for any failures.
  */
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
-						    u8 func_no)
+						    u8 func_no, u8 vfunc_no)
 {
 	const struct pci_epc_features *epc_features;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return NULL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return NULL;
+
 	if (!epc->ops->get_features)
 		return NULL;
 
 	mutex_lock(&epc->lock);
-	epc_features = epc->ops->get_features(epc, func_no);
+	epc_features = epc->ops->get_features(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	return epc_features;
@@ -205,13 +210,14 @@ EXPORT_SYMBOL_GPL(pci_epc_start);
 /**
  * pci_epc_raise_irq() - interrupt the host system
  * @epc: the EPC device which has to interrupt the host
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @type: specify the type of interrupt; legacy, MSI or MSI-X
  * @interrupt_num: the MSI or MSI-X interrupt number
  *
  * Invoke to raise an legacy, MSI or MSI-X interrupt
  */
-int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		      enum pci_epc_irq_type type, u16 interrupt_num)
 {
 	int ret;
@@ -219,11 +225,14 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->raise_irq)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->raise_irq(epc, func_no, type, interrupt_num);
+	ret = epc->ops->raise_irq(epc, func_no, vfunc_no, type, interrupt_num);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -235,6 +244,7 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
  *                         MSI data
  * @epc: the EPC device which has the MSI capability
  * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: the physical address of the outbound region
  * @interrupt_num: the MSI interrupt number
  * @entry_size: Size of Outbound address region for each interrupt
@@ -250,21 +260,25 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
  * physical address (in outbound region) of the other interface to ring
  * doorbell.
  */
-int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, phys_addr_t phys_addr,
-			u8 interrupt_num, u32 entry_size, u32 *msi_data,
-			u32 *msi_addr_offset)
+int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			phys_addr_t phys_addr, u8 interrupt_num, u32 entry_size,
+			u32 *msi_data, u32 *msi_addr_offset)
 {
 	int ret;
 
 	if (IS_ERR_OR_NULL(epc))
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->map_msi_irq)
 		return -EINVAL;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->map_msi_irq(epc, func_no, phys_addr, interrupt_num,
-				    entry_size, msi_data, msi_addr_offset);
+	ret = epc->ops->map_msi_irq(epc, func_no, vfunc_no, phys_addr,
+				    interrupt_num, entry_size, msi_data,
+				    msi_addr_offset);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -274,22 +288,26 @@ EXPORT_SYMBOL_GPL(pci_epc_map_msi_irq);
 /**
  * pci_epc_get_msi() - get the number of MSI interrupt numbers allocated
  * @epc: the EPC device to which MSI interrupts was requested
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  *
  * Invoke to get the number of MSI interrupts allocated by the RC
  */
-int pci_epc_get_msi(struct pci_epc *epc, u8 func_no)
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	int interrupt;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return 0;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return 0;
+
 	if (!epc->ops->get_msi)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	interrupt = epc->ops->get_msi(epc, func_no);
+	interrupt = epc->ops->get_msi(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	if (interrupt < 0)
@@ -304,12 +322,13 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msi);
 /**
  * pci_epc_set_msi() - set the number of MSI interrupt numbers required
  * @epc: the EPC device on which MSI has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @interrupts: number of MSI interrupts required by the EPF
  *
  * Invoke to set the required number of MSI interrupts.
  */
-int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no, u8 interrupts)
 {
 	int ret;
 	u8 encode_int;
@@ -318,13 +337,16 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 	    interrupts > 32)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_msi)
 		return 0;
 
 	encode_int = order_base_2(interrupts);
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_msi(epc, func_no, encode_int);
+	ret = epc->ops->set_msi(epc, func_no, vfunc_no, encode_int);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -334,22 +356,26 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msi);
 /**
  * pci_epc_get_msix() - get the number of MSI-X interrupt numbers allocated
  * @epc: the EPC device to which MSI-X interrupts was requested
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  *
  * Invoke to get the number of MSI-X interrupts allocated by the RC
  */
-int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)
+int pci_epc_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	int interrupt;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return 0;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return 0;
+
 	if (!epc->ops->get_msix)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	interrupt = epc->ops->get_msix(epc, func_no);
+	interrupt = epc->ops->get_msix(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	if (interrupt < 0)
@@ -362,15 +388,16 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msix);
 /**
  * pci_epc_set_msix() - set the number of MSI-X interrupt numbers required
  * @epc: the EPC device on which MSI-X has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @interrupts: number of MSI-X interrupts required by the EPF
  * @bir: BAR where the MSI-X table resides
  * @offset: Offset pointing to the start of MSI-X table
  *
  * Invoke to set the required number of MSI-X interrupts.
  */
-int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-		     enum pci_barno bir, u32 offset)
+int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		     u16 interrupts, enum pci_barno bir, u32 offset)
 {
 	int ret;
 
@@ -378,11 +405,15 @@ int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
 	    interrupts < 1 || interrupts > 2048)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_msix)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_msix(epc, func_no, interrupts - 1, bir, offset);
+	ret = epc->ops->set_msix(epc, func_no, vfunc_no, interrupts - 1, bir,
+				 offset);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -392,22 +423,26 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msix);
 /**
  * pci_epc_unmap_addr() - unmap CPU address from PCI address
  * @epc: the EPC device on which address is allocated
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: physical address of the local system
  *
  * Invoke to unmap the CPU address from PCI address.
  */
-void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr)
 {
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return;
+
 	if (!epc->ops->unmap_addr)
 		return;
 
 	mutex_lock(&epc->lock);
-	epc->ops->unmap_addr(epc, func_no, phys_addr);
+	epc->ops->unmap_addr(epc, func_no, vfunc_no, phys_addr);
 	mutex_unlock(&epc->lock);
 }
 EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
@@ -415,14 +450,15 @@ EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
 /**
  * pci_epc_map_addr() - map CPU address to PCI address
  * @epc: the EPC device on which address is allocated
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: physical address of the local system
  * @pci_addr: PCI address to which the physical address should be mapped
  * @size: the size of the allocation
  *
  * Invoke to map CPU address with PCI address.
  */
-int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		     phys_addr_t phys_addr, u64 pci_addr, size_t size)
 {
 	int ret;
@@ -430,11 +466,15 @@ int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->map_addr)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->map_addr(epc, func_no, phys_addr, pci_addr, size);
+	ret = epc->ops->map_addr(epc, func_no, vfunc_no, phys_addr, pci_addr,
+				 size);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -444,12 +484,13 @@ EXPORT_SYMBOL_GPL(pci_epc_map_addr);
 /**
  * pci_epc_clear_bar() - reset the BAR
  * @epc: the EPC device for which the BAR has to be cleared
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @epf_bar: the struct epf_bar that contains the BAR information
  *
  * Invoke to reset the BAR of the endpoint device.
  */
-void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		       struct pci_epf_bar *epf_bar)
 {
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
@@ -457,11 +498,14 @@ void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
 	     epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64))
 		return;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return;
+
 	if (!epc->ops->clear_bar)
 		return;
 
 	mutex_lock(&epc->lock);
-	epc->ops->clear_bar(epc, func_no, epf_bar);
+	epc->ops->clear_bar(epc, func_no, vfunc_no, epf_bar);
 	mutex_unlock(&epc->lock);
 }
 EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
@@ -469,12 +513,13 @@ EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
 /**
  * pci_epc_set_bar() - configure BAR in order for host to assign PCI addr space
  * @epc: the EPC device on which BAR has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @epf_bar: the struct epf_bar that contains the BAR information
  *
  * Invoke to configure the BAR of the endpoint device.
  */
-int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		    struct pci_epf_bar *epf_bar)
 {
 	int ret;
@@ -489,11 +534,14 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
 	     !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64)))
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_bar)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_bar(epc, func_no, epf_bar);
+	ret = epc->ops->set_bar(epc, func_no, vfunc_no, epf_bar);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -503,7 +551,8 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
 /**
  * pci_epc_write_header() - write standard configuration header
  * @epc: the EPC device to which the configuration header should be written
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @header: standard configuration header fields
  *
  * Invoke to write the configuration header to the endpoint controller. Every
@@ -511,7 +560,7 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
  * configuration header would be written. The callback function should write
  * the header fields to this dedicated location.
  */
-int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			 struct pci_epf_header *header)
 {
 	int ret;
@@ -519,11 +568,18 @@ int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
+	/* Only Virtual Function #1 has deviceID */
+	if (vfunc_no > 1)
+		return -EINVAL;
+
 	if (!epc->ops->write_header)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->write_header(epc, func_no, header);
+	ret = epc->ops->write_header(epc, func_no, vfunc_no, header);
 	mutex_unlock(&epc->lock);
 
 	return ret;
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index ae7107a3196e..d9e1a8dd1ceb 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -90,11 +90,14 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind);
  */
 int pci_epf_bind(struct pci_epf *epf)
 {
+	struct device *dev = &epf->dev;
 	struct pci_epf *epf_vf;
+	u8 func_no, vfunc_no;
+	struct pci_epc *epc;
 	int ret;
 
 	if (!epf->driver) {
-		dev_WARN(&epf->dev, "epf device not bound to driver\n");
+		dev_WARN(dev, "epf device not bound to driver\n");
 		return -EINVAL;
 	}
 
@@ -103,7 +106,50 @@ int pci_epf_bind(struct pci_epf *epf)
 
 	mutex_lock(&epf->lock);
 	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		vfunc_no = epf_vf->vfunc_no;
+
+		if (vfunc_no < 1) {
+			dev_err(dev, "Invalid virtual function number\n");
+			ret = -EINVAL;
+			goto ret;
+		}
+
+		epc = epf->epc;
+		func_no = epf->func_no;
+		if (!IS_ERR_OR_NULL(epc)) {
+			if (!epc->max_vfs) {
+				dev_err(dev, "No support for virt function\n");
+				ret = -EINVAL;
+				goto ret;
+			}
+
+			if (vfunc_no > epc->max_vfs[func_no]) {
+				dev_err(dev, "PF%d: Exceeds max vfunc number\n",
+					func_no);
+				ret = -EINVAL;
+				goto ret;
+			}
+		}
+
+		epc = epf->sec_epc;
+		func_no = epf->sec_epc_func_no;
+		if (!IS_ERR_OR_NULL(epc)) {
+			if (!epc->max_vfs) {
+				dev_err(dev, "No support for virt function\n");
+				ret = -EINVAL;
+				goto ret;
+			}
+
+			if (vfunc_no > epc->max_vfs[func_no]) {
+				dev_err(dev, "PF%d: Exceeds max vfunc number\n",
+					func_no);
+				ret = -EINVAL;
+				goto ret;
+			}
+		}
+
 		epf_vf->func_no = epf->func_no;
+		epf_vf->sec_epc_func_no = epf->sec_epc_func_no;
 		epf_vf->epc = epf->epc;
 		epf_vf->sec_epc = epf->sec_epc;
 		ret = epf_vf->driver->ops->bind(epf_vf);
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 50a649d33e68..a48778e1a4ee 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -62,31 +62,32 @@ pci_epc_interface_string(enum pci_epc_interface_type type)
  * @owner: the module owner containing the ops
  */
 struct pci_epc_ops {
-	int	(*write_header)(struct pci_epc *epc, u8 func_no,
+	int	(*write_header)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				struct pci_epf_header *hdr);
-	int	(*set_bar)(struct pci_epc *epc, u8 func_no,
+	int	(*set_bar)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			   struct pci_epf_bar *epf_bar);
-	void	(*clear_bar)(struct pci_epc *epc, u8 func_no,
+	void	(*clear_bar)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			     struct pci_epf_bar *epf_bar);
-	int	(*map_addr)(struct pci_epc *epc, u8 func_no,
+	int	(*map_addr)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			    phys_addr_t addr, u64 pci_addr, size_t size);
-	void	(*unmap_addr)(struct pci_epc *epc, u8 func_no,
+	void	(*unmap_addr)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			      phys_addr_t addr);
-	int	(*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts);
-	int	(*get_msi)(struct pci_epc *epc, u8 func_no);
-	int	(*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts,
-			    enum pci_barno, u32 offset);
-	int	(*get_msix)(struct pci_epc *epc, u8 func_no);
-	int	(*raise_irq)(struct pci_epc *epc, u8 func_no,
+	int	(*set_msi)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			   u8 interrupts);
+	int	(*get_msi)(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+	int	(*set_msix)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			    u16 interrupts, enum pci_barno, u32 offset);
+	int	(*get_msix)(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+	int	(*raise_irq)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			     enum pci_epc_irq_type type, u16 interrupt_num);
-	int	(*map_msi_irq)(struct pci_epc *epc, u8 func_no,
+	int	(*map_msi_irq)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			       phys_addr_t phys_addr, u8 interrupt_num,
 			       u32 entry_size, u32 *msi_data,
 			       u32 *msi_addr_offset);
 	int	(*start)(struct pci_epc *epc);
 	void	(*stop)(struct pci_epc *epc);
 	const struct pci_epc_features* (*get_features)(struct pci_epc *epc,
-						       u8 func_no);
+						       u8 func_no, u8 vfunc_no);
 	struct module *owner;
 };
 
@@ -128,6 +129,8 @@ struct pci_epc_mem {
  *       single window.
  * @num_windows: number of windows supported by device
  * @max_functions: max number of functions that can be configured in this EPC
+ * @max_vfs: Array indicating the maximum number of virtual functions that can
+ *   be associated with each physical function
  * @group: configfs group representing the PCI EPC device
  * @lock: mutex to protect pci_epc ops
  * @function_num_map: bitmap to manage physical function number
@@ -141,6 +144,7 @@ struct pci_epc {
 	struct pci_epc_mem		*mem;
 	unsigned int			num_windows;
 	u8				max_functions;
+	u8				*max_vfs;
 	struct config_group		*group;
 	/* mutex to protect against concurrent access of EP controller */
 	struct mutex			lock;
@@ -208,31 +212,32 @@ void pci_epc_linkup(struct pci_epc *epc);
 void pci_epc_init_notify(struct pci_epc *epc);
 void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
 			enum pci_epc_interface_type type);
-int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			 struct pci_epf_header *hdr);
-int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		    struct pci_epf_bar *epf_bar);
-void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		       struct pci_epf_bar *epf_bar);
-int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		     phys_addr_t phys_addr,
 		     u64 pci_addr, size_t size);
-void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr);
-int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
-int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);
-int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-		     enum pci_barno, u32 offset);
-int pci_epc_get_msix(struct pci_epc *epc, u8 func_no);
-int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		    u8 interrupts);
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		     u16 interrupts, enum pci_barno, u32 offset);
+int pci_epc_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr, u8 interrupt_num,
 			u32 entry_size, u32 *msi_data, u32 *msi_addr_offset);
-int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		      enum pci_epc_irq_type type, u16 interrupt_num);
 int pci_epc_start(struct pci_epc *epc);
 void pci_epc_stop(struct pci_epc *epc);
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
-						    u8 func_no);
+						    u8 func_no, u8 vfunc_no);
 enum pci_barno
 pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features);
 enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
-- 
2.17.1



From kishon at ti.com  Tue Aug 10 23:46:53 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:53 +0530
Subject: [PATCH v8 5/8] PCI: cadence: Simplify code to get register base
 address for configuring BAR
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <20210811064656.15399-6-kishon@ti.com>

No functional change. Simplify code to get register base address for
configuring PCI BAR.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c   | 18 ++++--------------
 drivers/pci/controller/cadence/pcie-cadence.h  |  2 ++
 2 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 912a15be8bfd..f337f0842400 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -97,13 +97,8 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
 			 addr1);
 
-	if (bar < BAR_4) {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
-		b = bar;
-	} else {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
-		b = bar - BAR_4;
-	}
+	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+	b = (bar < BAR_4) ? bar : bar - BAR_4;
 
 	cfg = cdns_pcie_readl(pcie, reg);
 	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
@@ -126,13 +121,8 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 	enum pci_barno bar = epf_bar->barno;
 	u32 reg, cfg, b, ctrl;
 
-	if (bar < BAR_4) {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
-		b = bar;
-	} else {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
-		b = bar - BAR_4;
-	}
+	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+	b = (bar < BAR_4) ? bar : bar - BAR_4;
 
 	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
 	cfg = cdns_pcie_readl(pcie, reg);
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 30db2d68c17a..d5b1fcf2c39d 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -46,6 +46,8 @@
 #define  CDNS_PCIE_LM_EP_ID_BUS_SHIFT	8
 
 /* Endpoint Function f BAR b Configuration Registers */
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn) \
+	(((bar) < 4) ? CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn))
 #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \
 	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
 #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
-- 
2.17.1



From kishon at ti.com  Tue Aug 10 23:46:54 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:54 +0530
Subject: [PATCH v8 6/8] PCI: cadence: Add support to configure virtual
 functions
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <20210811064656.15399-7-kishon@ti.com>

Now that support for SR-IOV is added in PCIe endpoint core, add support
to configure virtual functions in the Cadence PCIe EP driver.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c  | 136 +++++++++++++++---
 drivers/pci/controller/cadence/pcie-cadence.h |   9 ++
 2 files changed, 125 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index f337f0842400..443dd06dfcfc 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -16,11 +16,37 @@
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE		0x1
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY	0x3
 
+static u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn)
+{
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
+	u32 first_vf_offset, stride;
+
+	if (vfn == 0)
+		return fn;
+
+	first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_OFFSET);
+	stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +  PCI_SRIOV_VF_STRIDE);
+	fn = fn + first_vf_offset + ((vfn - 1) * stride);
+
+	return fn;
+}
+
 static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie *pcie = &ep->pcie;
+	u32 reg;
+
+	if (vfn > 1) {
+		dev_err(&epc->dev, "Only Virtual Function #1 has deviceID\n");
+		return -EINVAL;
+	} else if (vfn == 1) {
+		reg = cap + PCI_SRIOV_VF_DID;
+		cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid);
+		return 0;
+	}
 
 	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
 	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
@@ -92,21 +118,29 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 
 	addr0 = lower_32_bits(bar_phys);
 	addr1 = upper_32_bits(bar_phys);
-	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
-			 addr0);
-	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
-			 addr1);
 
 	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+	if (vfn == 1)
+		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
 	b = (bar < BAR_4) ? bar : bar - BAR_4;
 
-	cfg = cdns_pcie_readl(pcie, reg);
-	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
-		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
-	cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
-		CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
-	cdns_pcie_writel(pcie, reg, cfg);
+	if (vfn == 0 || vfn == 1) {
+		cfg = cdns_pcie_readl(pcie, reg);
+		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+		cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+			CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+		cdns_pcie_writel(pcie, reg, cfg);
+	}
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
+			 addr0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
+			 addr1);
+
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
 	epf->epf_bar[bar] = epf_bar;
 
 	return 0;
@@ -122,18 +156,25 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 	u32 reg, cfg, b, ctrl;
 
 	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+	if (vfn == 1)
+		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
 	b = (bar < BAR_4) ? bar : bar - BAR_4;
 
-	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
-	cfg = cdns_pcie_readl(pcie, reg);
-	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
-		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
-	cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
-	cdns_pcie_writel(pcie, reg, cfg);
+	if (vfn == 0 || vfn == 1) {
+		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
+		cfg = cdns_pcie_readl(pcie, reg);
+		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+		cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
+		cdns_pcie_writel(pcie, reg, cfg);
+	}
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0);
 
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
 	epf->epf_bar[bar] = NULL;
 }
 
@@ -151,6 +192,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 		return -EINVAL;
 	}
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
 	cdns_pcie_set_outbound_region(pcie, 0, fn, r, false, addr, pci_addr, size);
 
 	set_bit(r, &ep->ob_region_map);
@@ -186,6 +228,8 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
 	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
 	u16 flags;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/*
 	 * Set the Multiple Message Capable bitfield into the Message Control
 	 * register.
@@ -206,6 +250,8 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
 	u16 flags, mme;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/* Validate that the MSI feature is actually enabled. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
 	if (!(flags & PCI_MSI_FLAGS_ENABLE))
@@ -227,6 +273,8 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
 	u32 val, reg;
 
+	func_no = cdns_pcie_get_fn_from_vfn(pcie, func_no, vfunc_no);
+
 	reg = cap + PCI_MSIX_FLAGS;
 	val = cdns_pcie_ep_fn_readw(pcie, func_no, reg);
 	if (!(val & PCI_MSIX_FLAGS_ENABLE))
@@ -246,6 +294,8 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
 	u32 val, reg;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	reg = cap + PCI_MSIX_FLAGS;
 	val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
 	val &= ~PCI_MSIX_FLAGS_QSIZE;
@@ -265,8 +315,8 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
 	return 0;
 }
 
-static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
-				     u8 intx, bool is_asserted)
+static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
+				     bool is_asserted)
 {
 	struct cdns_pcie *pcie = &ep->pcie;
 	unsigned long flags;
@@ -335,6 +385,8 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 	u8 msi_count;
 	u64 pci_addr, pci_addr_mask = 0xff;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/* Check whether the MSI feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
 	if (!(flags & PCI_MSI_FLAGS_ENABLE))
@@ -388,6 +440,8 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 	int ret;
 	int i;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/* Check whether the MSI feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
 	if (!(flags & PCI_MSI_FLAGS_ENABLE))
@@ -438,6 +492,12 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 	u16 flags;
 	u8 bir;
 
+	epf = &ep->epf[fn];
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/* Check whether the MSI-X feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
 	if (!(flags & PCI_MSIX_FLAGS_ENABLE))
@@ -448,7 +508,6 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 	bir = tbl_offset & PCI_MSIX_TABLE_BIR;
 	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
 
-	epf = &ep->epf[fn];
 	msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
 	msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
 	msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
@@ -475,9 +534,15 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  u16 interrupt_num)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	struct device *dev = pcie->dev;
 
 	switch (type) {
 	case PCI_EPC_IRQ_LEGACY:
+		if (vfn > 0) {
+			dev_err(dev, "Cannot raise legacy interrupts for VF\n");
+			return -EINVAL;
+		}
 		return cdns_pcie_ep_send_legacy_irq(ep, fn, vfn, 0);
 
 	case PCI_EPC_IRQ_MSI:
@@ -515,6 +580,13 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
 	return 0;
 }
 
+static const struct pci_epc_features cdns_pcie_epc_vf_features = {
+	.linkup_notifier = false,
+	.msi_capable = true,
+	.msix_capable = true,
+	.align = 65536,
+};
+
 static const struct pci_epc_features cdns_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
@@ -525,7 +597,10 @@ static const struct pci_epc_features cdns_pcie_epc_features = {
 static const struct pci_epc_features*
 cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
-	return &cdns_pcie_epc_features;
+	if (!vfunc_no)
+		return &cdns_pcie_epc_features;
+
+	return &cdns_pcie_epc_vf_features;
 }
 
 static const struct pci_epc_ops cdns_pcie_epc_ops = {
@@ -551,9 +626,11 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *np = dev->of_node;
 	struct cdns_pcie *pcie = &ep->pcie;
+	struct cdns_pcie_epf *epf;
 	struct resource *res;
 	struct pci_epc *epc;
 	int ret;
+	int i;
 
 	pcie->is_rc = false;
 
@@ -598,6 +675,25 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	if (!ep->epf)
 		return -ENOMEM;
 
+	epc->max_vfs = devm_kcalloc(dev, epc->max_functions,
+				    sizeof(*epc->max_vfs), GFP_KERNEL);
+	if (!epc->max_vfs)
+		return -ENOMEM;
+
+	ret = of_property_read_u8_array(np, "max-virtual-functions",
+					epc->max_vfs, epc->max_functions);
+	if (ret == 0) {
+		for (i = 0; i < epc->max_functions; i++) {
+			epf = &ep->epf[i];
+			if (epc->max_vfs[i] == 0)
+				continue;
+			epf->epf = devm_kcalloc(dev, epc->max_vfs[i],
+						sizeof(*ep->epf), GFP_KERNEL);
+			if (!epf->epf)
+				return -ENOMEM;
+		}
+	}
+
 	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
 			       resource_size(pcie->mem_res), PAGE_SIZE);
 	if (ret < 0) {
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index d5b1fcf2c39d..b72de578b996 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -52,6 +52,12 @@
 	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
 #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
 	(CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn) \
+	(((bar) < 4) ? CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn))
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0280 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0284 + (fn) * 0x0008)
 #define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
 	(GENMASK(4, 0) << ((b) * 8))
 #define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
@@ -116,6 +122,7 @@
 
 #define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET	0x90
 #define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET	0xb0
+#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET	0x200
 
 /*
  * Root Port Registers (PCI configuration space for the root port function)
@@ -310,9 +317,11 @@ struct cdns_pcie_rc {
 
 /**
  * struct cdns_pcie_epf - Structure to hold info about endpoint function
+ * @epf: Info about virtual functions attached to the physical function
  * @epf_bar: reference to the pci_epf_bar for the six Base Address Registers
  */
 struct cdns_pcie_epf {
+	struct cdns_pcie_epf *epf;
 	struct pci_epf_bar *epf_bar[PCI_STD_NUM_BARS];
 };
 
-- 
2.17.1



From kishon at ti.com  Tue Aug 10 23:46:55 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:55 +0530
Subject: [PATCH v8 7/8] misc: pci_endpoint_test: Populate sriov_configure ops
 to configure SR-IOV device
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <20210811064656.15399-8-kishon@ti.com>

Populate sriov_configure ops with pci_sriov_configure_simple to
configure SR-IOV device.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/misc/pci_endpoint_test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 1b2868ca4f2a..c7ee34013485 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -978,6 +978,7 @@ static struct pci_driver pci_endpoint_test_driver = {
 	.id_table	= pci_endpoint_test_tbl,
 	.probe		= pci_endpoint_test_probe,
 	.remove		= pci_endpoint_test_remove,
+	.sriov_configure = pci_sriov_configure_simple,
 };
 module_pci_driver(pci_endpoint_test_driver);
 
-- 
2.17.1



From kishon at ti.com  Tue Aug 10 23:46:56 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 12:16:56 +0530
Subject: [PATCH v8 8/8] Documentation: PCI: endpoint/pci-endpoint-cfs: Guide
 to use SR-IOV
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <20210811064656.15399-9-kishon@ti.com>

Add Documentation to help users use PCI endpoint to create virtual
functions using configfs. An endpoint function is designated as a
virtual endpoint function device when it is linked to a physical
endpoint function device (instead of a endpoint controller).

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 Documentation/PCI/endpoint/pci-endpoint-cfs.rst | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/PCI/endpoint/pci-endpoint-cfs.rst b/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
index db609b97ad58..fb73345cfb8a 100644
--- a/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
+++ b/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
@@ -43,6 +43,7 @@ entries corresponding to EPF driver will be created by the EPF core.
 		.. <EPF Driver1>/
 			... <EPF Device 11>/
 			... <EPF Device 21>/
+			... <EPF Device 31>/
 		.. <EPF Driver2>/
 			... <EPF Device 12>/
 			... <EPF Device 22>/
@@ -68,6 +69,7 @@ created)
 				... subsys_vendor_id
 				... subsys_id
 				... interrupt_pin
+			        ... <Symlink EPF Device 31>/
                                 ... primary/
 			                ... <Symlink EPC Device1>/
                                 ... secondary/
@@ -79,6 +81,13 @@ interface should be added in 'primary' directory and symlink of endpoint
 controller connected to secondary interface should be added in 'secondary'
 directory.
 
+The <EPF Device> directory can have a list of symbolic links
+(<Symlink EPF Device 31>) to other <EPF Device>. These symbolic links should
+be created by the user to represent the virtual functions that are bound to
+the physical function. In the above directory structure <EPF Device 11> is a
+physical function and <EPF Device 31> is a virtual function. An EPF device once
+it's linked to another EPF device, cannot be linked to a EPC device.
+
 EPC Device
 ==========
 
@@ -98,7 +107,8 @@ entries corresponding to EPC device will be created by the EPC core.
 
 The <EPC Device> directory will have a list of symbolic links to
 <EPF Device>. These symbolic links should be created by the user to
-represent the functions present in the endpoint device.
+represent the functions present in the endpoint device. Only <EPF Device>
+that represents a physical function can be linked to a EPC device.
 
 The <EPC Device> directory will also have a *start* field. Once
 "1" is written to this field, the endpoint device will be ready to
-- 
2.17.1



From oupton at google.com  Wed Aug 11 00:02:05 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 11 Aug 2021 00:02:05 -0700
Subject: [PATCH 01/13] clocksource/arm_arch_timer: Drop CNT*_TVAL read
 accessors
In-Reply-To: <20210809152651.2297337-2-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-2-maz@kernel.org>
Message-ID: <CAOQ_Qsi00vkzX6fzRDDNQw+b+NXN_vZx+Tw0QG=952E=jq6yXQ@mail.gmail.com>

On Mon, Aug 9, 2021 at 8:27 AM Marc Zyngier <maz at kernel.org> wrote:
>
> The arch timer driver never reads the various TVAL registers, only
> writes to them. It is thus pointless to provide accessors
> for them and to implement errata workarounds.
>
> Drop these read-side accessors, and add a couple of BUG() statements
> for the time being. These statements will be removed further down
> the line.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Oliver Upton <oupton at google.com>

> ---
>  arch/arm/include/asm/arch_timer.h    |  6 ++--
>  arch/arm64/include/asm/arch_timer.h  | 17 ++---------
>  drivers/clocksource/arm_arch_timer.c | 44 ++--------------------------
>  3 files changed, 6 insertions(+), 61 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
> index 99175812d903..0c09afaa590d 100644
> --- a/arch/arm/include/asm/arch_timer.h
> +++ b/arch/arm/include/asm/arch_timer.h
> @@ -60,8 +60,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>                         asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> -                       asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
> -                       break;
> +                       BUG();
>                 }
>         } else if (access == ARCH_TIMER_VIRT_ACCESS) {
>                 switch (reg) {
> @@ -69,8 +68,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>                         asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> -                       asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
> -                       break;
> +                       BUG();
>                 }
>         }
>
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index 88d20f04c64a..8e3b2ac60c30 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -52,8 +52,6 @@ struct arch_timer_erratum_workaround {
>         enum arch_timer_erratum_match_type match_type;
>         const void *id;
>         const char *desc;
> -       u32 (*read_cntp_tval_el0)(void);
> -       u32 (*read_cntv_tval_el0)(void);
>         u64 (*read_cntpct_el0)(void);
>         u64 (*read_cntvct_el0)(void);
>         int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
> @@ -64,17 +62,6 @@ struct arch_timer_erratum_workaround {
>  DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
>                 timer_unstable_counter_workaround);
>
> -/* inline sysreg accessors that make erratum_handler() work */
> -static inline notrace u32 arch_timer_read_cntp_tval_el0(void)
> -{
> -       return read_sysreg(cntp_tval_el0);
> -}
> -
> -static inline notrace u32 arch_timer_read_cntv_tval_el0(void)
> -{
> -       return read_sysreg(cntv_tval_el0);
> -}
> -
>  static inline notrace u64 arch_timer_read_cntpct_el0(void)
>  {
>         return read_sysreg(cntpct_el0);
> @@ -135,14 +122,14 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>                 case ARCH_TIMER_REG_CTRL:
>                         return read_sysreg(cntp_ctl_el0);
>                 case ARCH_TIMER_REG_TVAL:
> -                       return arch_timer_reg_read_stable(cntp_tval_el0);
> +                       break;
>                 }
>         } else if (access == ARCH_TIMER_VIRT_ACCESS) {
>                 switch (reg) {
>                 case ARCH_TIMER_REG_CTRL:
>                         return read_sysreg(cntv_ctl_el0);
>                 case ARCH_TIMER_REG_TVAL:
> -                       return arch_timer_reg_read_stable(cntv_tval_el0);
> +                       break;
>                 }
>         }
>
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index be6d741d404c..9db5c16e31e7 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -141,8 +141,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
>                         val = readl_relaxed(timer->base + CNTP_CTL);
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> -                       val = readl_relaxed(timer->base + CNTP_TVAL);
> -                       break;
> +                       BUG();
>                 }
>         } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
>                 struct arch_timer *timer = to_arch_timer(clk);
> @@ -151,8 +150,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
>                         val = readl_relaxed(timer->base + CNTV_CTL);
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> -                       val = readl_relaxed(timer->base + CNTV_TVAL);
> -                       break;
> +                       BUG();
>                 }
>         } else {
>                 val = arch_timer_reg_read_cp15(access, reg);
> @@ -239,16 +237,6 @@ struct ate_acpi_oem_info {
>         _new;                                           \
>  })
>
> -static u32 notrace fsl_a008585_read_cntp_tval_el0(void)
> -{
> -       return __fsl_a008585_read_reg(cntp_tval_el0);
> -}
> -
> -static u32 notrace fsl_a008585_read_cntv_tval_el0(void)
> -{
> -       return __fsl_a008585_read_reg(cntv_tval_el0);
> -}
> -
>  static u64 notrace fsl_a008585_read_cntpct_el0(void)
>  {
>         return __fsl_a008585_read_reg(cntpct_el0);
> @@ -285,16 +273,6 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void)
>         _new;                                                   \
>  })
>
> -static u32 notrace hisi_161010101_read_cntp_tval_el0(void)
> -{
> -       return __hisi_161010101_read_reg(cntp_tval_el0);
> -}
> -
> -static u32 notrace hisi_161010101_read_cntv_tval_el0(void)
> -{
> -       return __hisi_161010101_read_reg(cntv_tval_el0);
> -}
> -
>  static u64 notrace hisi_161010101_read_cntpct_el0(void)
>  {
>         return __hisi_161010101_read_reg(cntpct_el0);
> @@ -379,16 +357,6 @@ static u64 notrace sun50i_a64_read_cntvct_el0(void)
>  {
>         return __sun50i_a64_read_reg(cntvct_el0);
>  }
> -
> -static u32 notrace sun50i_a64_read_cntp_tval_el0(void)
> -{
> -       return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0();
> -}
> -
> -static u32 notrace sun50i_a64_read_cntv_tval_el0(void)
> -{
> -       return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0();
> -}
>  #endif
>
>  #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
> @@ -438,8 +406,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>                 .match_type = ate_match_dt,
>                 .id = "fsl,erratum-a008585",
>                 .desc = "Freescale erratum a005858",
> -               .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
> -               .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
>                 .read_cntpct_el0 = fsl_a008585_read_cntpct_el0,
>                 .read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
>                 .set_next_event_phys = erratum_set_next_event_tval_phys,
> @@ -451,8 +417,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>                 .match_type = ate_match_dt,
>                 .id = "hisilicon,erratum-161010101",
>                 .desc = "HiSilicon erratum 161010101",
> -               .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
> -               .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
>                 .read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
>                 .read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
>                 .set_next_event_phys = erratum_set_next_event_tval_phys,
> @@ -462,8 +426,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>                 .match_type = ate_match_acpi_oem_info,
>                 .id = hisi_161010101_oem_info,
>                 .desc = "HiSilicon erratum 161010101",
> -               .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
> -               .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
>                 .read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
>                 .read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
>                 .set_next_event_phys = erratum_set_next_event_tval_phys,
> @@ -484,8 +446,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>                 .match_type = ate_match_dt,
>                 .id = "allwinner,erratum-unknown1",
>                 .desc = "Allwinner erratum UNKNOWN1",
> -               .read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0,
> -               .read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0,
>                 .read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
>                 .read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
>                 .set_next_event_phys = erratum_set_next_event_tval_phys,
> --
> 2.30.2
>


From fido_max at inbox.ru  Wed Aug 11 00:10:36 2021
From: fido_max at inbox.ru (Maxim Kochetkov)
Date: Wed, 11 Aug 2021 10:10:36 +0300
Subject: [PATCH] soc: fsl: qe: fix static checker warning
Message-ID: <20210811071036.44658-1-fido_max@inbox.ru>

The patch be7ecbd240b2: "soc: fsl: qe: convert QE interrupt
controller to platform_device" from Aug 3, 2021, leads to the
following static checker warning:

	drivers/soc/fsl/qe/qe_ic.c:438 qe_ic_init()
	warn: unsigned 'qe_ic->virq_low' is never less than zero.

In old variant irq_of_parse_and_map() returns zero if failed so
unsigned int for virq_high/virq_low was ok.
In new variant platform_get_irq() returns negative error codes
if failed so we need to use int for virq_high/virq_low.

Also simplify high_handler checking and remove the curly braces
to make checkpatch happy.

Fixes: be7ecbd240b2 ("soc: fsl: qe: convert QE interrupt controller to platform_device")
Signed-off-by: Maxim Kochetkov <fido_max at inbox.ru>
Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
---
 drivers/soc/fsl/qe/qe_ic.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c
index e710d554425d..bff34ee2150a 100644
--- a/drivers/soc/fsl/qe/qe_ic.c
+++ b/drivers/soc/fsl/qe/qe_ic.c
@@ -54,8 +54,8 @@ struct qe_ic {
 	struct irq_chip hc_irq;
 
 	/* VIRQ numbers of QE high/low irqs */
-	unsigned int virq_high;
-	unsigned int virq_low;
+	int virq_high;
+	int virq_low;
 };
 
 /*
@@ -435,9 +435,8 @@ static int qe_ic_init(struct platform_device *pdev)
 	qe_ic->virq_high = platform_get_irq(pdev, 0);
 	qe_ic->virq_low = platform_get_irq(pdev, 1);
 
-	if (qe_ic->virq_low < 0) {
+	if (qe_ic->virq_low < 0)
 		return -ENODEV;
-	}
 
 	if (qe_ic->virq_high != qe_ic->virq_low) {
 		low_handler = qe_ic_cascade_low;
@@ -459,7 +458,7 @@ static int qe_ic_init(struct platform_device *pdev)
 	irq_set_handler_data(qe_ic->virq_low, qe_ic);
 	irq_set_chained_handler(qe_ic->virq_low, low_handler);
 
-	if (qe_ic->virq_high && qe_ic->virq_high != qe_ic->virq_low) {
+	if (high_handler) {
 		irq_set_handler_data(qe_ic->virq_high, qe_ic);
 		irq_set_chained_handler(qe_ic->virq_high, high_handler);
 	}
-- 
2.31.1



From mchehab+huawei at kernel.org  Wed Aug 11 00:14:31 2021
From: mchehab+huawei at kernel.org (Mauro Carvalho Chehab)
Date: Wed, 11 Aug 2021 09:14:31 +0200
Subject: [PATCH] arm64: dts: HiSilicon: hi3660: address a PCI warning
Message-ID: <934f397d227ea589a16c89f1ee9c6f199c662093.1628666047.git.mchehab+huawei@kernel.org>

When the driver is registered, it produces a warning when
registering the PCI bridge:

	[    5.363450] pci_bus 0000:00: root bus resource [bus 00-01]
	[    5.396998] pci_bus 0000:01: busn_res: can not insert [bus 01-ff] under [bus 00-01] (conflicts with (null) [bus 00-01])
	[    5.284831] pci 0000:00:00.0: PCI bridge to [bus 01-ff]

The reason is that the bus-range is wrong. Address it.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
---
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index f1ec87c05842..cf2079590ad8 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -1002,7 +1002,7 @@ pcie at f4000000 {
 			      <0x0 0xf3f20000 0x0 0x40000>,
 			      <0x0 0xf5000000 0x0 0x2000>;
 			reg-names = "dbi", "apb", "phy", "config";
-			bus-range = <0x0  0x1>;
+			bus-range = <0x0  0xff>;
 			#address-cells = <3>;
 			#size-cells = <2>;
 			device_type = "pci";
-- 
2.31.1




From eizan at chromium.org  Wed Aug 11 00:15:15 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 11 Aug 2021 17:15:15 +1000
Subject: [PATCH] media: mtk-mdp: make mtk_mdp_comp_init static
Message-ID: <20210811171512.1.I4a34d99ace27ad2fe55e22c90244d3bba2c29bab@changeid>

This function isn't and doesn't need to be used outside of
mtk_mdp_comp.c

This patch depends on and is a follow-up to
https://patchwork.kernel.org/project/linux-mediatek/list/?series=524929

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
---

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 2 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 9527649de98e..2cf8f1864f8c 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -234,7 +234,7 @@ static const struct component_ops mtk_mdp_component_ops = {
 	.unbind = mtk_mdp_comp_unbind,
 };
 
-int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
+static int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 {
 	struct device_node *larb_node;
 	struct platform_device *larb_pdev;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index e3d6aef52869..aa6442cc8c1d 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -21,8 +21,6 @@ struct mtk_mdp_comp {
 	struct device		*larb_dev;
 };
 
-int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
-
 int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp);
 int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp);
 
-- 
2.32.0.605.g8dce9f2422-goog



From oupton at google.com  Wed Aug 11 00:15:56 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 11 Aug 2021 00:15:56 -0700
Subject: [PATCH 03/13] clocksource/arm_arch_timer: Move system register
 timer programming over to CVAL
In-Reply-To: <20210809152651.2297337-4-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-4-maz@kernel.org>
Message-ID: <CAOQ_QsiV=RaYMsYou8TcTf2ePtS0g1jgqpAHA7bni8MaPtL8zA@mail.gmail.com>

On Mon, Aug 9, 2021 at 8:27 AM Marc Zyngier <maz at kernel.org> wrote:
>
> In order to cope better with high frequency counters, move the
> programming of the timers from the countdown timer (TVAL) over
> to the comparator (CVAL).
>
> The programming model is slightly different, as we now need to
> read the current counter value to have an absolute deadline
> instead of a relative one.
>
> There is a small overhead to this change, which we will address
> in the following patches.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Oliver Upton <oupton at google.com>

> ---
>  arch/arm/include/asm/arch_timer.h    | 14 ++++++++----
>  arch/arm64/include/asm/arch_timer.h  | 16 +++++++++-----
>  drivers/clocksource/arm_arch_timer.c | 32 +++++++++++++++++++++++++---
>  include/clocksource/arm_arch_timer.h |  1 +
>  4 files changed, 51 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
> index 88075c7f4bfd..b48de9d26f27 100644
> --- a/arch/arm/include/asm/arch_timer.h
> +++ b/arch/arm/include/asm/arch_timer.h
> @@ -31,18 +31,22 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>                 case ARCH_TIMER_REG_CTRL:
>                         asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
>                         break;
> -               case ARCH_TIMER_REG_TVAL:
> -                       asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val));
> +               case ARCH_TIMER_REG_CVAL:
> +                       asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
>                         break;
> +               case ARCH_TIMER_REG_TVAL:
> +                       BUG();
>                 }
>         } else if (access == ARCH_TIMER_VIRT_ACCESS) {
>                 switch (reg) {
>                 case ARCH_TIMER_REG_CTRL:
>                         asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
>                         break;
> -               case ARCH_TIMER_REG_TVAL:
> -                       asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val));
> +               case ARCH_TIMER_REG_CVAL:
> +                       asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
>                         break;
> +               case ARCH_TIMER_REG_TVAL:
> +                       BUG();
>                 }
>         }
>
> @@ -60,6 +64,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>                         asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> +               case ARCH_TIMER_REG_CVAL:
>                         BUG();
>                 }
>         } else if (access == ARCH_TIMER_VIRT_ACCESS) {
> @@ -68,6 +73,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>                         asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> +               case ARCH_TIMER_REG_CVAL:
>                         BUG();
>                 }
>         }
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index 107afb721749..6ceb050ae7b9 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -96,18 +96,22 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>                 case ARCH_TIMER_REG_CTRL:
>                         write_sysreg(val, cntp_ctl_el0);
>                         break;
> -               case ARCH_TIMER_REG_TVAL:
> -                       write_sysreg(val, cntp_tval_el0);
> +               case ARCH_TIMER_REG_CVAL:
> +                       write_sysreg(val, cntp_cval_el0);
>                         break;
> +               case ARCH_TIMER_REG_TVAL:
> +                       BUG();
>                 }
>         } else if (access == ARCH_TIMER_VIRT_ACCESS) {
>                 switch (reg) {
>                 case ARCH_TIMER_REG_CTRL:
>                         write_sysreg(val, cntv_ctl_el0);
>                         break;
> -               case ARCH_TIMER_REG_TVAL:
> -                       write_sysreg(val, cntv_tval_el0);
> +               case ARCH_TIMER_REG_CVAL:
> +                       write_sysreg(val, cntv_cval_el0);
>                         break;
> +               case ARCH_TIMER_REG_TVAL:
> +                       BUG();
>                 }
>         }
>
> @@ -115,13 +119,14 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>  }
>
>  static __always_inline
> -u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
> +u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>  {
>         if (access == ARCH_TIMER_PHYS_ACCESS) {
>                 switch (reg) {
>                 case ARCH_TIMER_REG_CTRL:
>                         return read_sysreg(cntp_ctl_el0);
>                 case ARCH_TIMER_REG_TVAL:
> +               case ARCH_TIMER_REG_CVAL:
>                         break;
>                 }
>         } else if (access == ARCH_TIMER_VIRT_ACCESS) {
> @@ -129,6 +134,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>                 case ARCH_TIMER_REG_CTRL:
>                         return read_sysreg(cntv_ctl_el0);
>                 case ARCH_TIMER_REG_TVAL:
> +               case ARCH_TIMER_REG_CVAL:
>                         break;
>                 }
>         }
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 0b2bac3ef7ce..898a07dc01cd 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -112,6 +112,8 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
>                 case ARCH_TIMER_REG_TVAL:
>                         writel_relaxed((u32)val, timer->base + CNTP_TVAL);
>                         break;
> +               case ARCH_TIMER_REG_CVAL:
> +                       BUG();
>                 }
>         } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
>                 struct arch_timer *timer = to_arch_timer(clk);
> @@ -122,6 +124,8 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
>                 case ARCH_TIMER_REG_TVAL:
>                         writel_relaxed((u32)val, timer->base + CNTV_TVAL);
>                         break;
> +               case ARCH_TIMER_REG_CVAL:
> +                       BUG();
>                 }
>         } else {
>                 arch_timer_reg_write_cp15(access, reg, val);
> @@ -141,6 +145,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
>                         val = readl_relaxed(timer->base + CNTP_CTL);
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> +               case ARCH_TIMER_REG_CVAL:
>                         BUG();
>                 }
>         } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
> @@ -150,6 +155,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
>                         val = readl_relaxed(timer->base + CNTV_CTL);
>                         break;
>                 case ARCH_TIMER_REG_TVAL:
> +               case ARCH_TIMER_REG_CVAL:
>                         BUG();
>                 }
>         } else {
> @@ -687,10 +693,18 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
>                                            struct clock_event_device *clk)
>  {
>         unsigned long ctrl;
> +       u64 cnt;
> +
>         ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
>         ctrl |= ARCH_TIMER_CTRL_ENABLE;
>         ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
> -       arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
> +
> +       if (access == ARCH_TIMER_PHYS_ACCESS)
> +               cnt = __arch_counter_get_cntpct();
> +       else
> +               cnt = __arch_counter_get_cntvct();
> +
> +       arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk);
>         arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
>  }
>
> @@ -708,17 +722,29 @@ static int arch_timer_set_next_event_phys(unsigned long evt,
>         return 0;
>  }
>
> +static __always_inline void set_next_event_mem(const int access, unsigned long evt,
> +                                          struct clock_event_device *clk)
> +{
> +       unsigned long ctrl;
> +       ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
> +       ctrl |= ARCH_TIMER_CTRL_ENABLE;
> +       ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
> +
> +       arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
> +       arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
> +}
> +
>  static int arch_timer_set_next_event_virt_mem(unsigned long evt,
>                                               struct clock_event_device *clk)
>  {
> -       set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
> +       set_next_event_mem(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
>         return 0;
>  }
>
>  static int arch_timer_set_next_event_phys_mem(unsigned long evt,
>                                               struct clock_event_device *clk)
>  {
> -       set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
> +       set_next_event_mem(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
>         return 0;
>  }
>
> diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
> index 73c7139c866f..d59537afb29d 100644
> --- a/include/clocksource/arm_arch_timer.h
> +++ b/include/clocksource/arm_arch_timer.h
> @@ -25,6 +25,7 @@
>  enum arch_timer_reg {
>         ARCH_TIMER_REG_CTRL,
>         ARCH_TIMER_REG_TVAL,
> +       ARCH_TIMER_REG_CVAL,
>  };
>
>  enum arch_timer_ppi_nr {
> --
> 2.30.2
>


From mhiramat at kernel.org  Wed Aug 11 00:20:04 2021
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Wed, 11 Aug 2021 16:20:04 +0900
Subject: [PATCH v3 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210810055330.18924-3-liuqi115@huawei.com>
References: <20210810055330.18924-1-liuqi115@huawei.com>
 <20210810055330.18924-3-liuqi115@huawei.com>
Message-ID: <20210811162004.9b3349e6bda68e74e0a3a4ad@kernel.org>

Hi Qi,

Thanks for updating.

On Tue, 10 Aug 2021 13:53:30 +0800
Qi Liu <liuqi115 at huawei.com> wrote:

[...]
> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op,
> +				  struct kprobe *orig)
> +{
> +	kprobe_opcode_t *code, *buf;
> +	void **addrs;
> +	u32 insn;
> +	int ret, i;
> +
> +	addrs = kcalloc(TMPL_MAX_LENGTH, sizeof(void *), GFP_KERNEL);
> +	if (!addrs)
> +		return -ENOMEM;
> +
> +	buf = kcalloc(TMPL_MAX_LENGTH, sizeof(kprobe_opcode_t), GFP_KERNEL);
> +	if (!buf) {
> +		kfree(addrs);
> +		return -ENOMEM;
> +	}
> +
> +	code = get_optinsn_slot();
> +	if (!code) {
> +		kfree(addrs);
> +		kfree(buf);
> +		return -ENOMEM;
> +	}
> +
> +	if (!is_offset_in_range((unsigned long)code,
> +				(unsigned long)orig->addr + 8)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
> +				(unsigned long)optimized_callback)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
> +				(unsigned long)op->kp.addr + 4)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	memcpy(buf, optprobe_template_entry,
> +	       TMPL_END_IDX * sizeof(kprobe_opcode_t));
> +
> +	buf[TMPL_VAL_IDX] = FIELD_GET(GENMASK(31, 0), (unsigned long long)op);
> +	buf[TMPL_VAL_IDX + 1] =
> +		FIELD_GET(GENMASK(63, 32), (unsigned long long)op);
> +	buf[TMPL_RESTORE_ORIGN_INSN] = orig->opcode;
> +
> +	insn = aarch64_insn_gen_branch_imm(
> +		(unsigned long)(&code[TMPL_CALL_BACK]),
> +		(unsigned long)optimized_callback, AARCH64_INSN_BRANCH_LINK);
> +	buf[TMPL_CALL_BACK] = insn;
> +
> +	insn = aarch64_insn_gen_branch_imm(
> +		(unsigned long)(&code[TMPL_RESTORE_END]),
> +		(unsigned long)(op->kp.addr) + 4, AARCH64_INSN_BRANCH_NOLINK);
> +	buf[TMPL_RESTORE_END] = insn;
> +
> +	/* Setup template */
> +	for (i = 0; i < TMPL_MAX_LENGTH; i++)
> +		addrs[i] = code + i;
> +
> +	ret = aarch64_insn_patch_text(addrs, buf, TMPL_MAX_LENGTH);
> +	if (ret < 0)
> +		goto error;

OK, this part looks good to me.

> +
> +	flush_icache_range((unsigned long)code,
> +			   (unsigned long)(&code[TMPL_END_IDX]));
> +
> +	/* Set op->optinsn.insn means prepared. */
> +	op->optinsn.insn = code;
> +
> +out:
> +	kfree(addrs);
> +	kfree(buf);
> +	return ret;
> +
> +error:
> +	free_optinsn_slot(code, 0);
> +	goto out;
> +}
> +
> +void arch_optimize_kprobes(struct list_head *oplist)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		u32 insn;
> +
> +		WARN_ON(kprobe_disabled(&op->kp));
> +
> +		/*
> +		 * Backup instructions which will be replaced
> +		 * by jump address
> +		 */
> +		memcpy(op->optinsn.copied_insn, op->kp.addr,
> +			RELATIVEJUMP_SIZE);
> +		insn = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
> +				(unsigned long)op->optinsn.insn,
> +				AARCH64_INSN_BRANCH_NOLINK);
> +
> +		WARN_ON(insn == 0);
> +
> +		aarch64_insn_patch_text((void *)&(op->kp.addr), &insn, 1);

Can you also reduce the number of aarch64_insn_patch_text() here?
Since arch_optimize_kprobes() running in the workqueue context, you can
allocate memory. Thus, you can do something like this(not cleaned)

#define OPTPROBE_BATCH_SIZE 64

void arch_optimize_kprobes(struct list_head *oplist)
{
	struct optimized_kprobe *op, *tmp;
	void **addrs;
	u32 *insns;
	int i = 0;

	addrs = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(*addrs), GFP_KERNEL);
	insns = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(*insns), GFP_KERNEL);

	list_for_each_entry_safe(op, tmp, oplist, list) {
		memcpy(op->optinsn.copied_insn, op->kp.addr,
			RELATIVEJUMP_SIZE);
		addrs[i] = op->kp.addr;
		insns[i] = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
				(unsigned long)op->optinsn.insn,
				AARCH64_INSN_BRANCH_NOLINK);
		list_del_init(&op->list);
		if (++i == OPTPROBE_BATCH_SIZE)
			break;
	}
	aarch64_insn_patch_text(addrs, insns, i);

	kfree(addrs);
	kfree(insns);
}

Since the stop_machine() penalty is heavier than you think (especially,
if the machine has many cores), it must be avoided as much as possible.


> +
> +		list_del_init(&op->list);
> +	}
> +}
> +
> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
> +{
> +	arch_arm_kprobe(&op->kp);
> +}
> +
> +/*
> + * Recover original instructions and breakpoints from relative jumps.
> + * Caller must call with locking kprobe_mutex.
> + */
> +void arch_unoptimize_kprobes(struct list_head *oplist,
> +			    struct list_head *done_list)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		arch_unoptimize_kprobe(op);
> +		list_move(&op->list, done_list);
> +	}
> +}

Ditto.
You don't need to use arch_arm_kprobe() in this case.

Thank you,

> +
> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
> +{
> +	if (op->optinsn.insn) {
> +		free_optinsn_slot(op->optinsn.insn, 1);
> +		op->optinsn.insn = NULL;
> +	}
> +}
> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
> new file mode 100644
> index 000000000000..24d713d400cd
> --- /dev/null
> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * trampoline entry and return code for optprobes.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/assembler.h>
> +
> +	.global optprobe_template_entry
> +optprobe_template_entry:
> +	sub sp, sp, #PT_REGS_SIZE
> +	save_all_base_regs
> +	/* Get parameters to optimized_callback() */
> +	ldr	x0, 1f
> +	mov	x1, sp
> +	/* Branch to optimized_callback() */
> +	.global optprobe_template_call
> +optprobe_template_call:
> +	nop
> +	restore_all_base_regs
> +	ldr lr, [sp, #S_LR]
> +        add sp, sp, #PT_REGS_SIZE
> +	.global optprobe_template_restore_orig_insn
> +optprobe_template_restore_orig_insn:
> +	nop
> +	.global optprobe_template_restore_end
> +optprobe_template_restore_end:
> +	nop
> +	.global optprobe_template_end
> +optprobe_template_end:
> +	.global optprobe_template_val
> +optprobe_template_val:
> +	1:	.long 0
> +		.long 0
> +	.global optprobe_template_max_length
> +optprobe_template_max_length:
> -- 
> 2.17.1
> 


-- 
Masami Hiramatsu <mhiramat at kernel.org>


From lee.jones at linaro.org  Wed Aug 11 00:28:53 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 11 Aug 2021 08:28:53 +0100
Subject: [PATCH] MAINTAINERS: adjust ARM/NOMADIK/Ux500 ARCHITECTURES to
 file renaming
In-Reply-To: <20210810191724.24452-1-lukas.bulwahn@gmail.com>
References: <20210810191724.24452-1-lukas.bulwahn@gmail.com>
Message-ID: <YRN8NTvGUmEJ6VBN@google.com>

On Tue, 10 Aug 2021, Lukas Bulwahn wrote:

> Commit 8f00b3c41ae7 ("mfd: db8500-prcmu: Rename register header") renames
> dbx500-prcmu-regs.h to db8500-prcmu-regs.h in ./drivers/mfd/, but misses
> to adjust the ARM/NOMADIK/Ux500 ARCHITECTURES section in MAINTAINERS.
> 
> Hence, ./scripts/get_maintainer.pl --self-test=patterns complains:
> 
>   warning: no file matches    F:    drivers/mfd/dbx500*
> 
> Remove the obsolete file entry after this file renaming.
> 
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
> ---
> applies cleanly on next-20210810
> 
> Linus, Lee, please pick this patch on your -next tree on top of the patch
> mentioned above.
> 
>  MAINTAINERS | 1 -
>  1 file changed, 1 deletion(-)

Applied, thanks.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From arnd at kernel.org  Wed Aug 11 00:31:32 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 11 Aug 2021 09:31:32 +0200
Subject: [PATCH v5 00/10] ARM: remove set_fs callers and implementation
In-Reply-To: <YRNwmGL2b52dQUuv@infradead.org>
References: <20210726141141.2839385-1-arnd@kernel.org>
 <YRNwmGL2b52dQUuv@infradead.org>
Message-ID: <CAK8P3a3aCgy5z4sNWO_xbV2PwdrW1c6eavRYeMT3WE91eG65rw@mail.gmail.com>

On Wed, Aug 11, 2021 at 8:39 AM Christoph Hellwig <hch at infradead.org> wrote:
>
> From my high-level perspective this looks great and I'd love to see it
> merged:
>
> Acked-by: Christoph Hellwig <hch at lst.de>

Thank you for taking another look, and for the reminder. I've now added the
series to Russell's patch tracker.

       Arnd


From rppt at linux.ibm.com  Wed Aug 11 00:36:29 2021
From: rppt at linux.ibm.com (Mike Rapoport)
Date: Wed, 11 Aug 2021 10:36:29 +0300
Subject: [PATCH v3] memblock: make memblock_find_in_range method private
In-Reply-To: <7db20940-cbd9-e900-db28-774c5782601c@roeck-us.net>
References: <20210803064218.6611-1-rppt@kernel.org>
 <20210809190641.GA1176508@roeck-us.net>
 <YRLLpImNhZaLzs3z@kernel.org>
 <7db20940-cbd9-e900-db28-774c5782601c@roeck-us.net>
Message-ID: <YRN9/XrHiPUMdDPJ@linux.ibm.com>

On Tue, Aug 10, 2021 at 12:21:46PM -0700, Guenter Roeck wrote:
> On 8/10/21 11:55 AM, Mike Rapoport wrote:
> > On Mon, Aug 09, 2021 at 12:06:41PM -0700, Guenter Roeck wrote:
> > > On Tue, Aug 03, 2021 at 09:42:18AM +0300, Mike Rapoport wrote:
> > > > From: Mike Rapoport <rppt at linux.ibm.com>
> > > > 
> > > > There are a lot of uses of memblock_find_in_range() along with
> > > > memblock_reserve() from the times memblock allocation APIs did not exist.
> > > > 
> > > > memblock_find_in_range() is the very core of memblock allocations, so any
> > > > future changes to its internal behaviour would mandate updates of all the
> > > > users outside memblock.
> > > > 
> > > > Replace the calls to memblock_find_in_range() with an equivalent calls to
> > > > memblock_phys_alloc() and memblock_phys_alloc_range() and make
> > > > memblock_find_in_range() private method of memblock.
> > > > 
> > > > This simplifies the callers, ensures that (unlikely) errors in
> > > > memblock_reserve() are handled and improves maintainability of
> > > > memblock_find_in_range().
> > > > 
> > > > Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
> > > 
> > > I see a number of crashes in next-20210806 when booting x86 images from efi.
> > > 
> > > [    0.000000] efi: EFI v2.70 by EDK II
> > > [    0.000000] efi: SMBIOS=0x1fbcc000 ACPI=0x1fbfa000 ACPI 2.0=0x1fbfa014 MEMATTR=0x1f25f018
> > > [    0.000000] SMBIOS 2.8 present.
> > > [    0.000000] DMI: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
> > > [    0.000000] last_pfn = 0x1ff50 max_arch_pfn = 0x400000000
> > > [    0.000000] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT
> > > [    0.000000] Kernel panic - not syncing: alloc_low_pages: can not alloc memory
> > > [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.14.0-rc4-next-20210806 #1
> > > [    0.000000] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
> > > [    0.000000] Call Trace:
> > > [    0.000000]  ? dump_stack_lvl+0x57/0x7d
> > > [    0.000000]  ? panic+0xfc/0x2c6
> > > [    0.000000]  ? alloc_low_pages+0x117/0x156
> > > [    0.000000]  ? phys_pmd_init+0x234/0x342
> > > [    0.000000]  ? phys_pud_init+0x171/0x337
> > > [    0.000000]  ? __kernel_physical_mapping_init+0xec/0x276
> > > [    0.000000]  ? init_memory_mapping+0x1ea/0x2aa
> > > [    0.000000]  ? init_range_memory_mapping+0xdf/0x12e
> > > [    0.000000]  ? init_mem_mapping+0x1e9/0x26f
> > > [    0.000000]  ? setup_arch+0x5ff/0xb6d
> > > [    0.000000]  ? start_kernel+0x71/0x6b4
> > > [    0.000000]  ? secondary_startup_64_no_verify+0xc2/0xcb
> > > 
> > > Bisect points to this patch. Reverting it fixes the problem. Key seems to
> > > be the amount of memory configured in qemu; the problem is not seen if
> > > there is 1G or more of memory, but it is seen with all test boots with
> > > 512M or 256M of memory. It is also seen with almost all 32-bit efi boots.
> > > 
> > > The problem is not seen when booting without efi.
> > 
> > It looks like this change uncovered a problem in
> > x86::memory_map_top_down().
> > 
> > The allocation in alloc_low_pages() is limited by min_pfn_mapped and
> > max_pfn_mapped. The min_pfn_mapped is updated at every iteration of the
> > loop in memory_map_top_down, but there is another loop in
> > init_range_memory_mapping() that maps several regions below the current
> > min_pfn_mapped without updating this variable.
> > 
> > The memory layout in qemu with 256M of RAM and EFI enabled, causes
> > exhaustion of the memory limited by min_pfn_mapped and max_pfn_mapped
> > before min_pfn_mapped is updated.
> > 
> > Before this commit there was unconditional "reservation" of 2M in the end
> > of the memory that moved the initial min_pfn_mapped below the memory
> > reserved by EFI. The addition of check for xen_domain() removed this
> > reservation for !XEN and made alloc_low_pages() use the range already busy
> > with EFI data.
> > 
> > The patch below moves the update of min_pfn_mapped near the update of
> > max_pfn_mapped so that every time a new range is mapped both limits will be
> > updated accordingly.
> > 
> > diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
> > index 1152a29ce109..be279f6e5a0a 100644
> > --- a/arch/x86/mm/init.c
> > +++ b/arch/x86/mm/init.c
> > @@ -1,3 +1,4 @@
> > +#define DEBUG
> >   #include <linux/gfp.h>
> >   #include <linux/initrd.h>
> >   #include <linux/ioport.h>
> > @@ -485,6 +486,7 @@ static void add_pfn_range_mapped(unsigned long start_pfn, unsigned long end_pfn)
> >   	nr_pfn_mapped = clean_sort_range(pfn_mapped, E820_MAX_ENTRIES);
> >   	max_pfn_mapped = max(max_pfn_mapped, end_pfn);
> > +	min_pfn_mapped = min(min_pfn_mapped, start_pfn);
> >   	if (start_pfn < (1UL<<(32-PAGE_SHIFT)))
> >   		max_low_pfn_mapped = max(max_low_pfn_mapped,
> > @@ -643,7 +645,6 @@ static void __init memory_map_top_down(unsigned long map_start,
> >   		mapped_ram_size += init_range_memory_mapping(start,
> >   							last_start);
> >   		last_start = start;
> > -		min_pfn_mapped = last_start >> PAGE_SHIFT;
> >   		if (mapped_ram_size >= step_size)
> >   			step_size = get_new_step_size(step_size);
> >   	}
> 
> The offending patch was removed from next-20210810, but I applied the above change
> to next-20210809 and it does indeed fix the problem. If it is added as separate patch,
> please feel free to add
> 
> Tested-by: Guenter Roeck <linux at roeck-us.net>

Thanks!

I wonder now about that comment saying "xen has big range in reserved near
end of ram". Maybe it was the same issue with Xen and we can entirely drop
the reservation of the top 2M?

x86 folks, what do you say?

-- 
Sincerely yours,
Mike.


From o.rempel at pengutronix.de  Wed Aug 11 00:38:35 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Wed, 11 Aug 2021 09:38:35 +0200
Subject: [PATCH v1] ARM: dts: imx6qp-prtwd3: configure ENET_REF clock to 125MHz
Message-ID: <20210811073835.32082-1-o.rempel@pengutronix.de>

By default ENET_REF is configured to 50MHz, which is usable for the RMII
link. In case RGMII is used, we need 125MHz clock.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 arch/arm/boot/dts/imx6qp-prtwd3.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qp-prtwd3.dts b/arch/arm/boot/dts/imx6qp-prtwd3.dts
index 9cbe3386c51a..effe032273f7 100644
--- a/arch/arm/boot/dts/imx6qp-prtwd3.dts
+++ b/arch/arm/boot/dts/imx6qp-prtwd3.dts
@@ -256,6 +256,8 @@ can at 0 {
 &fec {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_enet>;
+	assigned-clocks = <&clks IMX6QDL_CLK_ENET_REF>;
+	assigned-clock-rates = <125000000>;
 	status = "okay";
 
 	phy-mode = "rgmii";
-- 
2.30.2



From liuqi115 at huawei.com  Wed Aug 11 00:51:07 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Wed, 11 Aug 2021 15:51:07 +0800
Subject: [PATCH v3 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210811162004.9b3349e6bda68e74e0a3a4ad@kernel.org>
References: <20210810055330.18924-1-liuqi115@huawei.com>
 <20210810055330.18924-3-liuqi115@huawei.com>
 <20210811162004.9b3349e6bda68e74e0a3a4ad@kernel.org>
Message-ID: <d0510f00-4745-add5-a8d9-cde35c296634@huawei.com>

Hi Masmi,

On 2021/8/11 15:20, Masami Hiramatsu wrote:
> Hi Qi,
> 
> Thanks for updating.
> 
> On Tue, 10 Aug 2021 13:53:30 +0800
> Qi Liu <liuqi115 at huawei.com> wrote:
> 

[...]

>> +void arch_optimize_kprobes(struct list_head *oplist)
>> +{
>> +	struct optimized_kprobe *op, *tmp;
>> +
>> +	list_for_each_entry_safe(op, tmp, oplist, list) {
>> +		u32 insn;
>> +
>> +		WARN_ON(kprobe_disabled(&op->kp));
>> +
>> +		/*
>> +		 * Backup instructions which will be replaced
>> +		 * by jump address
>> +		 */
>> +		memcpy(op->optinsn.copied_insn, op->kp.addr,
>> +			RELATIVEJUMP_SIZE);
>> +		insn = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
>> +				(unsigned long)op->optinsn.insn,
>> +				AARCH64_INSN_BRANCH_NOLINK);
>> +
>> +		WARN_ON(insn == 0);
>> +
>> +		aarch64_insn_patch_text((void *)&(op->kp.addr), &insn, 1);
> 
> Can you also reduce the number of aarch64_insn_patch_text() here?
> Since arch_optimize_kprobes() running in the workqueue context, you can
> allocate memory. Thus, you can do something like this(not cleaned)
> 
> #define OPTPROBE_BATCH_SIZE 64
> 
> void arch_optimize_kprobes(struct list_head *oplist)
> {
> 	struct optimized_kprobe *op, *tmp;
> 	void **addrs;
> 	u32 *insns;
> 	int i = 0;
> 
> 	addrs = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(*addrs), GFP_KERNEL);
> 	insns = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(*insns), GFP_KERNEL);
> 
> 	list_for_each_entry_safe(op, tmp, oplist, list) {
> 		memcpy(op->optinsn.copied_insn, op->kp.addr,
> 			RELATIVEJUMP_SIZE);
> 		addrs[i] = op->kp.addr;
> 		insns[i] = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
> 				(unsigned long)op->optinsn.insn,
> 				AARCH64_INSN_BRANCH_NOLINK);
> 		list_del_init(&op->list);
> 		if (++i == OPTPROBE_BATCH_SIZE)
> 			break;
> 	}
> 	aarch64_insn_patch_text(addrs, insns, i);
> 
> 	kfree(addrs);
> 	kfree(insns);
> }
> 
> Since the stop_machine() penalty is heavier than you think (especially,
> if the machine has many cores), it must be avoided as much as possible.
> 

got it, I'll fix this next time.
> 
>> +
>> +		list_del_init(&op->list);
>> +	}
>> +}
>> +
>> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
>> +{
>> +	arch_arm_kprobe(&op->kp);
>> +}
>> +
>> +/*
>> + * Recover original instructions and breakpoints from relative jumps.
>> + * Caller must call with locking kprobe_mutex.
>> + */
>> +void arch_unoptimize_kprobes(struct list_head *oplist,
>> +			    struct list_head *done_list)
>> +{
>> +	struct optimized_kprobe *op, *tmp;
>> +
>> +	list_for_each_entry_safe(op, tmp, oplist, list) {
>> +		arch_unoptimize_kprobe(op);
>> +		list_move(&op->list, done_list);
>> +	}
>> +}
> 
> Ditto.
> You don't need to use arch_arm_kprobe() in this case.
> 
> Thank you,
> 
thanks, will change this next time.

Qi
>> +
>> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
>> +{
>> +	if (op->optinsn.insn) {
>> +		free_optinsn_slot(op->optinsn.insn, 1);
>> +		op->optinsn.insn = NULL;
>> +	}
>> +}
>> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
>> new file mode 100644
>> index 000000000000..24d713d400cd
>> --- /dev/null
>> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
>> @@ -0,0 +1,37 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * trampoline entry and return code for optprobes.
>> + */
>> +
>> +#include <linux/linkage.h>
>> +#include <asm/asm-offsets.h>
>> +#include <asm/assembler.h>
>> +
>> +	.global optprobe_template_entry
>> +optprobe_template_entry:
>> +	sub sp, sp, #PT_REGS_SIZE
>> +	save_all_base_regs
>> +	/* Get parameters to optimized_callback() */
>> +	ldr	x0, 1f
>> +	mov	x1, sp
>> +	/* Branch to optimized_callback() */
>> +	.global optprobe_template_call
>> +optprobe_template_call:
>> +	nop
>> +	restore_all_base_regs
>> +	ldr lr, [sp, #S_LR]
>> +        add sp, sp, #PT_REGS_SIZE
>> +	.global optprobe_template_restore_orig_insn
>> +optprobe_template_restore_orig_insn:
>> +	nop
>> +	.global optprobe_template_restore_end
>> +optprobe_template_restore_end:
>> +	nop
>> +	.global optprobe_template_end
>> +optprobe_template_end:
>> +	.global optprobe_template_val
>> +optprobe_template_val:
>> +	1:	.long 0
>> +		.long 0
>> +	.global optprobe_template_max_length
>> +optprobe_template_max_length:
>> -- 
>> 2.17.1
>>
> 
> 



From lee.jones at linaro.org  Wed Aug 11 00:57:25 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 11 Aug 2021 08:57:25 +0100
Subject: [PATCH 1/1] genirq/cpuhotplug: Bump debugging information print
 down to KERN_DEBUG
In-Reply-To: <8735rhs7n6.ffs@tglx>
References: <20210617073136.315723-1-lee.jones@linaro.org>
 <8735rhs7n6.ffs@tglx>
Message-ID: <YROC5avuGQyBIpmD@google.com>

On Tue, 10 Aug 2021, Thomas Gleixner wrote:

> On Thu, Jun 17 2021 at 08:31, Lee Jones wrote:
> > This sort of information is only generally useful when debugging.
> >
> > No need to have these sprinkled through the kernel log otherwise.
> 
> Yes and no. 
> 
> > Cc: Thomas Gleixner <tglx at linutronix.de>
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> > ---
> >  kernel/irq/cpuhotplug.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c
> > index 02236b13b3599..cf8d4f75632e8 100644
> > --- a/kernel/irq/cpuhotplug.c
> > +++ b/kernel/irq/cpuhotplug.c
> > @@ -42,7 +42,7 @@ static inline bool irq_needs_fixup(struct irq_data *d)
> >  		 * If this happens then there was a missed IRQ fixup at some
> >  		 * point. Warn about it and enforce fixup.
> >  		 */
> > -		pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",
> 
> This one is clearly a warning as this should not happen. See the
> comments around that.
> 
> > +		pr_debug("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",
> >  			cpumask_pr_args(m), d->irq, cpu);
> >  		return true;
> >  	}
> > @@ -166,7 +166,7 @@ void irq_migrate_all_off_this_cpu(void)
> >  		raw_spin_unlock(&desc->lock);
> >  
> >  		if (affinity_broken) {
> > -			pr_warn_ratelimited("IRQ %u: no longer affine to CPU%u\n",
> > +			pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n",
> >  					    irq, smp_processor_id());
> 
> Maybe, but distro people might have opinions on that.

The trouble is, even if these are real warnings, they have an affect
on performance on real products.  To the point where so much logging
builds up during pre-release testing, that it sets off the watchdog(s)
on some high profile consumer devices.

What would you suggest?

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From qiangqing.zhang at nxp.com  Wed Aug 11 00:57:46 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Wed, 11 Aug 2021 07:57:46 +0000
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <YRKOGYwx1uVdsKoF@lunn.ch>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
 <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <YRKOGYwx1uVdsKoF@lunn.ch>
Message-ID: <VI1PR04MB6800EE08F70CC3F0DD53C991E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>


Hi Andrew,

> -----Original Message-----
> From: Andrew Lunn <andrew at lunn.ch>
> Sent: 2021?8?10? 22:33
> To: Joakim Zhang <qiangqing.zhang at nxp.com>
> Cc: Florian Fainelli <f.fainelli at gmail.com>; davem at davemloft.net;
> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> s.hauer at pengutronix.de; festevam at gmail.com; kernel at pengutronix.de;
> dl-linux-imx <linux-imx at nxp.com>; netdev at vger.kernel.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
> wakeup-irq" property
> 
> > > > 1) FEC controller has up to 4 interrupt lines and all of these are
> > > > routed to GIC
> > > interrupt controller.
> > > > 2) FEC has a wakeup interrupt signal and always are mixed with
> > > > other
> > > interrupt signals, and then output to one interrupt line.
> > > > 3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but
> > > > for i.MX8M
> > > serials, are mixed to int2 line.
> 
> So you need to know which of the interrupts listed is the wake up interrupt.
> 
> I can see a few ways to do this:
> 
> The FEC driver already has quirks. Add a quirk to fec_imx8mq_info and
> fec_imx8qm_info to indicate these should use int2.
> 
> or
> 
> Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
> 
>   b) two cells
>   ------------
>   The #interrupt-cells property is set to 2 and the first cell defines the
>   index of the interrupt within the controller, while the second cell is used
>   to specify any of the following flags:
>     - bits[3:0] trigger type and level flags
>         1 = low-to-high edge triggered
>         2 = high-to-low edge triggered
>         4 = active high level-sensitive
>         8 = active low level-sensitive
> 
> You could add
> 
>        18 = wakeup source
> 
> and extend to core to either do all the work for you, or tell you this interrupt is
> flagged as being a wakeup source. This solution has the advantage of it should
> be usable in other drivers.

Thanks a lot for your comments first!

I just look into the irq code, if we extend bit[5] to carry wakeup info ( due to bit[4] is used for IRQ_TYPE_PROBE), 
then configure it in the TYPE field of 'interrupts' property, so that interrupt controller would know which interrupt
is wakeup capable. 
I think there is no much work core would do, may just set this interrupt wakup capable. Another functionality is
driver side get this info to identify which mixed interrupt has wakeup capability, we can export symbol from kernel/irq/irqdomain.c.

The intention is to let driver know which interrupt is wakeup capable, I would choose to provider this in specific driver,
instead of interrupt controller, it seems to me that others may all choose this solution for wakeup mixed interrupt.

So I would prefer solution 1, it's easier and under-control. I can have a try if you strongly recommend solution 2.

Best Regards,
Joakim Zhang
> 	  Andrew

From sudeep.holla at arm.com  Wed Aug 11 00:57:43 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 11 Aug 2021 08:57:43 +0100
Subject: [GIT PULL] firmware: arm_scmi: Updates for v5.15
Message-ID: <20210811075743.707961-1-sudeep.holla@arm.com>

Hi ARM SoC Team,

Please pull !

Regards,
Sudeep

-->8

The following changes since commit bdb8742dc6f7c599c3d61959234fe4c23638727b:

  firmware: arm_scmi: Fix range check for the maximum number of pending messages (2021-07-13 11:42:20 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git tags/scmi-updates-5.15

for you to fetch changes up to c0397c85b53d0bc6b081ff22d0d07e8eae149bba:

  firmware: arm_scmi: Use WARN_ON() to check configured transports (2021-08-09 11:43:32 +0100)

----------------------------------------------------------------
SCMI Updates for v5.15

The bulk of the addition this time is mainly refactoring to add support
for Virtio transport for SCMI and the addition of the support itself.
The refactoring includes allowing transport specific init/exit calls,
making each transport as compile time configurable, supporting
monotonically increasing tokens instead of using the next available
free buffer index as the token for scmi messages which eases handling
concurrent and out-of-order messages which is a must have for virtio
transport.

Virtio support itself is conformant to the virtio SCMI device spec [1].
Virtio device id 32 has been reserved for the SCMI device [2].

Other than the virtio support, there is one bug fix in the probe failure
clean up path.

[1] https://github.com/oasis-tcs/virtio-spec/blob/master/virtio-scmi.tex
[2] https://www.oasis-open.org/committees/ballot.php?id=3496

----------------------------------------------------------------
Cristian Marussi (10):
      firmware: arm_scmi: Add support for type handling in common functions
      firmware: arm_scmi: Remove scmi_dump_header_dbg() helper
      firmware: arm_scmi: Add optional transport_init/exit support
      firmware: arm_scmi: Introduce monotonically increasing tokens
      firmware: arm_scmi: Handle concurrent and out-of-order messages
      firmware: arm_scmi: Make .clear_channel optional
      firmware: arm_scmi: Make polling mode optional
      firmware: arm_scmi: Make SCMI transports configurable
      firmware: arm_scmi: Add priv parameter to scmi_rx_callback
      firmware: arm_scmi: Use WARN_ON() to check configured transports

Igor Skalkin (4):
      firmware: arm_scmi: Make shmem support optional for transports
      firmware: arm_scmi: Add method to override max message number
      dt-bindings: arm: Add virtio transport for SCMI
      firmware: arm_scmi: Add virtio transport

Peter Hilber (2):
      firmware: arm_scmi: Add message passing abstractions for transports
      firmware: arm_scmi: Add optional link_supplier() transport op

Rishabh Bhatnagar (1):
      firmware: arm_scmi: Free mailbox channels if probe fails

kernel test robot (1):
      firmware: arm_scmi: Fix boolconv.cocci warnings

 .../devicetree/bindings/firmware/arm,scmi.yaml     |   8 +-
 MAINTAINERS                                        |   1 +
 drivers/firmware/Kconfig                           |  34 +-
 drivers/firmware/arm_scmi/Kconfig                  |  95 +++
 drivers/firmware/arm_scmi/Makefile                 |   8 +-
 drivers/firmware/arm_scmi/common.h                 | 113 +++-
 drivers/firmware/arm_scmi/driver.c                 | 686 +++++++++++++++++----
 drivers/firmware/arm_scmi/mailbox.c                |   2 +-
 drivers/firmware/arm_scmi/msg.c                    | 111 ++++
 drivers/firmware/arm_scmi/smc.c                    |   3 +-
 drivers/firmware/arm_scmi/virtio.c                 | 491 +++++++++++++++
 include/uapi/linux/virtio_ids.h                    |   1 +
 include/uapi/linux/virtio_scmi.h                   |  24 +
 13 files changed, 1429 insertions(+), 148 deletions(-)
 create mode 100644 drivers/firmware/arm_scmi/Kconfig
 create mode 100644 drivers/firmware/arm_scmi/msg.c
 create mode 100644 drivers/firmware/arm_scmi/virtio.c
 create mode 100644 include/uapi/linux/virtio_scmi.h


From steen.hegelund at microchip.com  Wed Aug 11 00:59:07 2021
From: steen.hegelund at microchip.com (Steen Hegelund)
Date: Wed, 11 Aug 2021 09:59:07 +0200
Subject: [PATCH net-next 0/2] Adding Frame DMA functionality to Sparx5
Message-ID: <20210811075909.543633-1-steen.hegelund@microchip.com>

This add frame DMA functionality to the Sparx5 platform.

Until now the Sparx5 SwitchDev driver has been using register based
injection and extraction when sending frames to/from the host CPU.

With this series the Frame DMA functionality now added.

The Frame DMA is only used if the Frame DMA interrupt is configured in the
device tree; otherwise the existing register based injection and extraction
is used.

The Sparx5 has two ports that can be used for sending and receiving frames,
but there are 8 channels that can be configured: 6 for injection and 2 for
extraction.

The additional channels can be used for more advanced scenarios e.g. where
virtual cores are used, but currently the driver only uses port 0 and
channel 0 and 6 respectively.

DCB (data control block) structures are passed to the Frame DMA with
suitable information about frame start/end etc, as well as pointers to DB
(data blocks) buffers.

The Frame DMA engine can use interrupts to signal back when the frames have
been injected or extracted.

There is a limitation on the DB alignment also for injection: Block must
start on 16byte boundaries, and this is why the driver currently copies the
data to into separate buffers.

The Sparx5 switch core needs a IFH (Internal Frame Header) to pass
information from the port to the switch core, and this header is added
before injection and stripped after extraction.

Steen Hegelund (2):
  net: sparx5: switchdev: adding frame DMA functionality
  arm64: dts: sparx5: Add the Sparx5 switch frame DMA support

 arch/arm64/boot/dts/microchip/sparx5.dtsi     |   5 +-
 .../net/ethernet/microchip/sparx5/Makefile    |   2 +-
 .../ethernet/microchip/sparx5/sparx5_fdma.c   | 595 ++++++++++++++++++
 .../ethernet/microchip/sparx5/sparx5_main.c   |  23 +-
 .../ethernet/microchip/sparx5/sparx5_main.h   |  69 ++
 .../ethernet/microchip/sparx5/sparx5_packet.c |  13 +-
 .../ethernet/microchip/sparx5/sparx5_port.c   |   2 +-
 .../ethernet/microchip/sparx5/sparx5_port.h   |   1 +
 8 files changed, 698 insertions(+), 12 deletions(-)
 create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c

--
2.32.0



From steen.hegelund at microchip.com  Wed Aug 11 00:59:08 2021
From: steen.hegelund at microchip.com (Steen Hegelund)
Date: Wed, 11 Aug 2021 09:59:08 +0200
Subject: [PATCH net-next 1/2] net: sparx5: switchdev: adding frame DMA
 functionality
In-Reply-To: <20210811075909.543633-1-steen.hegelund@microchip.com>
References: <20210811075909.543633-1-steen.hegelund@microchip.com>
Message-ID: <20210811075909.543633-2-steen.hegelund@microchip.com>

This add frame DMA functionality to the Sparx5 platform.

Ethernet frames can be extracted or injected autonomously to or from the
device?s DDR3/DDR3L memory and/or PCIe memory space. Linked list data
structures in memory are used for injecting or extracting Ethernet frames.
The FDMA generates interrupts when frame extraction or injection is done
and when the linked lists need updating.

The FDMA implements two extraction channels, one per switch core port
towards the VCore CPU system and a total of six injection channels.
Extraction channels are mapped one-to-one to the CPU ports, while injection
channels can be individually assigned to any CPU port.

- FDMA channel 0 through 5 corresponds to CPU port 0 injection direction
  FDMA_CH_CFG[channel].CH_INJ_PORT is set to 0.
- FDMA channel 0 through 5 corresponds to CPU port 1 injection direction when
  FDMA_CH_CFG[channel].CH_INJ_PORT is set to 1.
- FDMA channel 6 corresponds to CPU port 0 extraction direction.
- FDMA channel 7 corresponds to CPU port 1 extraction direction.

The FDMA implements a strict priority scheme among channels. Extraction
channels are prioritized over injection channels and secondarily channels
with higher channel number are prioritized over channels with lower number.
On the other hand, ports are being served on an equal-bandwidth principle
both on injection and extraction directions.  The equal-bandwidth principle
will not force an equal bandwidth. Instead, it ensures that the ports
perform at their best considering the operating conditions.

When more than one injection channel is enabled for injection on the same
CPU port, priority determines which channel can inject data. Ownership
is re-arbitrated on frame boundaries.

The FDMA processes linked lists of DMA Control Block Structures (DCBs). The
DCBs have the same basic structure for both injection and extraction. A DCB
must be placed on a 64-bit word-aligned address in memory. Each DCB has a
per-channel configurable amount of associated data blocks in memory, where
the frame data is stored.

The data blocks that are used by extraction channels must be placed on
64-bit word aligned addresses in memory, and their length must be a
multiple of 128 bytes.

A DCB carries the pointer to the next DCB of the linked list, the INFO word
which holds information for the DCB, and a pair of status word and memory
pointer for every data block that it is associated with.

Signed-off-by: Steen Hegelund <steen.hegelund at microchip.com>
---
 .../net/ethernet/microchip/sparx5/Makefile    |   2 +-
 .../ethernet/microchip/sparx5/sparx5_fdma.c   | 595 ++++++++++++++++++
 .../ethernet/microchip/sparx5/sparx5_main.c   |  23 +-
 .../ethernet/microchip/sparx5/sparx5_main.h   |  69 ++
 .../ethernet/microchip/sparx5/sparx5_packet.c |  13 +-
 .../ethernet/microchip/sparx5/sparx5_port.c   |   2 +-
 .../ethernet/microchip/sparx5/sparx5_port.h   |   1 +
 7 files changed, 695 insertions(+), 10 deletions(-)
 create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c

diff --git a/drivers/net/ethernet/microchip/sparx5/Makefile b/drivers/net/ethernet/microchip/sparx5/Makefile
index faa8f07a6b75..c271e86ee292 100644
--- a/drivers/net/ethernet/microchip/sparx5/Makefile
+++ b/drivers/net/ethernet/microchip/sparx5/Makefile
@@ -7,4 +7,4 @@ obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o

 sparx5-switch-objs  := sparx5_main.o sparx5_packet.o \
  sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \
- sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o
+ sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o sparx5_fdma.o
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
new file mode 100644
index 000000000000..4bd5c4be7a3c
--- /dev/null
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
@@ -0,0 +1,595 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Microchip Sparx5 Switch driver
+ *
+ * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
+ *
+ * The Sparx5 Chip Register Model can be browsed at this location:
+ * https://github.com/microchip-ung/sparx-5_reginfo
+ */
+
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/ip.h>
+#include <linux/dma-mapping.h>
+
+#include "sparx5_main_regs.h"
+#include "sparx5_main.h"
+#include "sparx5_port.h"
+
+#define FDMA_XTR_CHANNEL		6
+#define FDMA_INJ_CHANNEL		0
+
+#define FDMA_DCB_INFO_DATAL(x)		((x) & GENMASK(15, 0))
+#define FDMA_DCB_INFO_TOKEN		BIT(17)
+#define FDMA_DCB_INFO_INTR		BIT(18)
+#define FDMA_DCB_INFO_SW(x)		(((x) << 24) & GENMASK(31, 24))
+
+#define FDMA_DCB_STATUS_BLOCKL(x)	((x) & GENMASK(15, 0))
+#define FDMA_DCB_STATUS_SOF		BIT(16)
+#define FDMA_DCB_STATUS_EOF		BIT(17)
+#define FDMA_DCB_STATUS_INTR		BIT(18)
+#define FDMA_DCB_STATUS_DONE		BIT(19)
+#define FDMA_DCB_STATUS_BLOCKO(x)	(((x) << 20) & GENMASK(31, 20))
+#define FDMA_DCB_INVALID_DATA		0x1
+
+#define FDMA_XTR_BUFFER_SIZE		2048
+#define FDMA_WEIGHT			4
+
+/* Frame DMA DCB format
+ *
+ * +---------------------------+
+ * |         Next Ptr          |
+ * +---------------------------+
+ * |   Reserved  |    Info     |
+ * +---------------------------+
+ * |         Data0 Ptr         |
+ * +---------------------------+
+ * |   Reserved  |    Status0  |
+ * +---------------------------+
+ * |         Data1 Ptr         |
+ * +---------------------------+
+ * |   Reserved  |    Status1  |
+ * +---------------------------+
+ * |         Data2 Ptr         |
+ * +---------------------------+
+ * |   Reserved  |    Status2  |
+ * |-------------|-------------|
+ * |                           |
+ * |                           |
+ * |                           |
+ * |                           |
+ * |                           |
+ * |---------------------------|
+ * |         Data14 Ptr        |
+ * +-------------|-------------+
+ * |   Reserved  |    Status14 |
+ * +-------------|-------------+
+ */
+
+/* For each hardware DB there is an entry in this list and when the HW DB
+ * entry is used, this SW DB entry is moved to the back of the list
+ */
+struct sparx5_db {
+	struct list_head list;
+	void *cpu_addr;
+};
+
+static void sparx5_fdma_rx_add_dcb(struct sparx5_rx *rx,
+				   struct sparx5_rx_dcb_hw *dcb,
+				   u64 nextptr)
+{
+	int idx = 0;
+
+	/* Reset the status of the DB */
+	for (idx = 0; idx < FDMA_RX_DCB_MAX_DBS; ++idx) {
+		struct sparx5_db_hw *db = &dcb->db[idx];
+
+		db->status = FDMA_DCB_STATUS_INTR;
+	}
+	dcb->nextptr = FDMA_DCB_INVALID_DATA;
+	dcb->info = FDMA_DCB_INFO_DATAL(FDMA_XTR_BUFFER_SIZE);
+	rx->last_entry->nextptr = nextptr;
+	rx->last_entry = dcb;
+}
+
+static void sparx5_fdma_tx_add_dcb(struct sparx5_tx *tx,
+				   struct sparx5_tx_dcb_hw *dcb,
+				   u64 nextptr)
+{
+	int idx = 0;
+
+	/* Reset the status of the DB */
+	for (idx = 0; idx < FDMA_TX_DCB_MAX_DBS; ++idx) {
+		struct sparx5_db_hw *db = &dcb->db[idx];
+
+		db->status = FDMA_DCB_STATUS_DONE;
+	}
+	dcb->nextptr = FDMA_DCB_INVALID_DATA;
+	dcb->info = FDMA_DCB_INFO_DATAL(FDMA_XTR_BUFFER_SIZE);
+}
+
+static void sparx5_fdma_rx_activate(struct sparx5 *sparx5, struct sparx5_rx *rx)
+{
+	/* Write the buffer address in the LLP and LLP1 regs */
+	spx5_wr(((u64)rx->dma) & GENMASK(31, 0), sparx5,
+		FDMA_DCB_LLP(rx->channel_id));
+	spx5_wr(((u64)rx->dma) >> 32, sparx5, FDMA_DCB_LLP1(rx->channel_id));
+
+	/* Set the number of RX DBs to be used, and DB end-of-frame interrupt */
+	spx5_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_RX_DCB_MAX_DBS) |
+		FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) |
+		FDMA_CH_CFG_CH_INJ_PORT_SET(XTR_QUEUE),
+		sparx5, FDMA_CH_CFG(rx->channel_id));
+
+	/* Set the RX Watermark to max */
+	spx5_rmw(FDMA_XTR_CFG_XTR_FIFO_WM_SET(31), FDMA_XTR_CFG_XTR_FIFO_WM,
+		 sparx5,
+		 FDMA_XTR_CFG);
+
+	/* Start RX fdma */
+	spx5_rmw(FDMA_PORT_CTRL_XTR_STOP_SET(0), FDMA_PORT_CTRL_XTR_STOP,
+		 sparx5, FDMA_PORT_CTRL(0));
+
+	/* Enable RX channel DB interrupt */
+	spx5_rmw(BIT(rx->channel_id),
+		 BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
+		 sparx5, FDMA_INTR_DB_ENA);
+
+	/* Activate the RX channel */
+	spx5_wr(BIT(rx->channel_id), sparx5, FDMA_CH_ACTIVATE);
+}
+
+static void sparx5_fdma_rx_deactivate(struct sparx5 *sparx5, struct sparx5_rx *rx)
+{
+	/* Dectivate the RX channel */
+	spx5_rmw(0, BIT(rx->channel_id) & FDMA_CH_ACTIVATE_CH_ACTIVATE,
+		 sparx5, FDMA_CH_ACTIVATE);
+
+	/* Disable RX channel DB interrupt */
+	spx5_rmw(0, BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
+		 sparx5, FDMA_INTR_DB_ENA);
+
+	/* Stop RX fdma */
+	spx5_rmw(FDMA_PORT_CTRL_XTR_STOP_SET(1), FDMA_PORT_CTRL_XTR_STOP,
+		 sparx5, FDMA_PORT_CTRL(0));
+}
+
+static void sparx5_fdma_tx_activate(struct sparx5 *sparx5, struct sparx5_tx *tx)
+{
+	/* Write the buffer address in the LLP and LLP1 regs */
+	spx5_wr(((u64)tx->dma) & GENMASK(31, 0), sparx5,
+		FDMA_DCB_LLP(tx->channel_id));
+	spx5_wr(((u64)tx->dma) >> 32, sparx5, FDMA_DCB_LLP1(tx->channel_id));
+
+	/* Set the number of TX DBs to be used, and DB end-of-frame interrupt */
+	spx5_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_TX_DCB_MAX_DBS) |
+		FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) |
+		FDMA_CH_CFG_CH_INJ_PORT_SET(INJ_QUEUE),
+		sparx5, FDMA_CH_CFG(tx->channel_id));
+
+	/* Start TX fdma */
+	spx5_rmw(FDMA_PORT_CTRL_INJ_STOP_SET(0), FDMA_PORT_CTRL_INJ_STOP,
+		 sparx5, FDMA_PORT_CTRL(0));
+
+	/* Activate the channel */
+	spx5_wr(BIT(tx->channel_id), sparx5, FDMA_CH_ACTIVATE);
+}
+
+static void sparx5_fdma_tx_deactivate(struct sparx5 *sparx5, struct sparx5_tx *tx)
+{
+	/* Disable the channel */
+	spx5_rmw(0, BIT(tx->channel_id) & FDMA_CH_ACTIVATE_CH_ACTIVATE,
+		 sparx5, FDMA_CH_ACTIVATE);
+}
+
+static void sparx5_fdma_rx_reload(struct sparx5 *sparx5, struct sparx5_rx *rx)
+{
+	/* Reload the RX channel */
+	spx5_wr(BIT(rx->channel_id), sparx5, FDMA_CH_RELOAD);
+}
+
+static void sparx5_fdma_tx_reload(struct sparx5 *sparx5, struct sparx5_tx *tx)
+{
+	/* Reload the TX channel */
+	spx5_wr(BIT(tx->channel_id), sparx5, FDMA_CH_RELOAD);
+}
+
+static struct sk_buff *sparx5_fdma_rx_alloc_skb(struct sparx5_rx *rx)
+{
+	return __netdev_alloc_skb(rx->ndev, FDMA_XTR_BUFFER_SIZE,
+				  GFP_ATOMIC);
+}
+
+static bool sparx5_fdma_rx_get_frame(struct sparx5 *sparx5, struct sparx5_rx *rx)
+{
+	struct sparx5_db_hw *db_hw;
+	unsigned int packet_size;
+	struct sparx5_port *port;
+	struct sk_buff *new_skb;
+	struct frame_info fi;
+	struct sk_buff *skb;
+	dma_addr_t dma_addr;
+
+	/* Check if the DCB is done */
+	db_hw = &rx->dcb_entries[rx->dcb_index].db[rx->db_index];
+	if (unlikely(!(db_hw->status & FDMA_DCB_STATUS_DONE)))
+		return false;
+	skb = rx->skb[rx->dcb_index][rx->db_index];
+	/* Replace the DB entry with a new SKB */
+	new_skb = sparx5_fdma_rx_alloc_skb(rx);
+	if (unlikely(!new_skb))
+		return false;
+	/* Map the new skb data and set the new skb */
+	dma_addr = virt_to_phys(new_skb->data);
+	rx->skb[rx->dcb_index][rx->db_index] = new_skb;
+	db_hw->dataptr = dma_addr;
+	packet_size = FDMA_DCB_STATUS_BLOCKL(db_hw->status);
+	skb_put(skb, packet_size);
+	/* Now do the normal processing of the skb */
+	sparx5_ifh_parse((u32 *)skb->data, &fi);
+	/* Map to port netdev */
+	port = fi.src_port < SPX5_PORTS ?  sparx5->ports[fi.src_port] : NULL;
+	if (!port || !port->ndev) {
+		dev_err(sparx5->dev, "Data on inactive port %d\n", fi.src_port);
+		sparx5_xtr_flush(sparx5, XTR_QUEUE);
+		return false;
+	}
+	skb->dev = port->ndev;
+	skb_pull(skb, IFH_LEN * sizeof(u32));
+	if (likely(!(skb->dev->features & NETIF_F_RXFCS)))
+		skb_trim(skb, skb->len - ETH_FCS_LEN);
+	skb->protocol = eth_type_trans(skb, skb->dev);
+	/* Everything we see on an interface that is in the HW bridge
+	 * has already been forwarded
+	 */
+	if (test_bit(port->portno, sparx5->bridge_mask))
+		skb->offload_fwd_mark = 1;
+	skb->dev->stats.rx_bytes += skb->len;
+	skb->dev->stats.rx_packets++;
+	rx->packets++;
+	netif_receive_skb(skb);
+	return true;
+}
+
+static int sparx5_fdma_napi_callback(struct napi_struct *napi, int weight)
+{
+	struct sparx5_rx *rx = container_of(napi, struct sparx5_rx, napi);
+	struct sparx5 *sparx5 = container_of(rx, struct sparx5, rx);
+	int counter = 0;
+
+	while (counter < weight && sparx5_fdma_rx_get_frame(sparx5, rx)) {
+		struct sparx5_rx_dcb_hw *old_dcb;
+
+		rx->db_index++;
+		counter++;
+		/* Check if the DCB can be reused */
+		if (rx->db_index != FDMA_RX_DCB_MAX_DBS)
+			continue;
+		/* As the DCB  can be reused, just advance the dcb_index
+		 * pointer and set the nextptr in the DCB
+		 */
+		rx->db_index = 0;
+		old_dcb = &rx->dcb_entries[rx->dcb_index];
+		rx->dcb_index++;
+		rx->dcb_index &= FDMA_DCB_MAX - 1;
+		sparx5_fdma_rx_add_dcb(rx, old_dcb,
+				       rx->dma +
+				       ((unsigned long)old_dcb -
+					(unsigned long)rx->dcb_entries));
+	}
+	if (counter < weight) {
+		napi_complete_done(&rx->napi, counter);
+		spx5_rmw(BIT(rx->channel_id),
+			 BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
+			 sparx5, FDMA_INTR_DB_ENA);
+	}
+	if (counter)
+		sparx5_fdma_rx_reload(sparx5, rx);
+	return counter;
+}
+
+static struct sparx5_tx_dcb_hw *sparx5_fdma_next_dcb(struct sparx5_tx *tx,
+						     struct sparx5_tx_dcb_hw *dcb)
+{
+	struct sparx5_tx_dcb_hw *next_dcb;
+
+	next_dcb = dcb;
+	next_dcb++;
+	/* Handle wrap-around */
+	if ((unsigned long)next_dcb >=
+	    ((unsigned long)tx->first_entry + FDMA_DCB_MAX * sizeof(*dcb)))
+		next_dcb = tx->first_entry;
+	return next_dcb;
+}
+
+int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb)
+{
+	struct sparx5_tx_dcb_hw *next_dcb_hw;
+	struct sparx5_tx *tx = &sparx5->tx;
+	static bool first_time = true;
+	struct sparx5_db_hw *db_hw;
+	struct sparx5_db *db;
+
+	next_dcb_hw = sparx5_fdma_next_dcb(tx, tx->curr_entry);
+	db_hw = &next_dcb_hw->db[0];
+	if (!(db_hw->status & FDMA_DCB_STATUS_DONE))
+		tx->dropped++;
+	db = list_first_entry(&tx->db_list, struct sparx5_db, list);
+	list_move_tail(&db->list, &tx->db_list);
+	next_dcb_hw->nextptr = FDMA_DCB_INVALID_DATA;
+	tx->curr_entry->nextptr = tx->dma +
+		((unsigned long)next_dcb_hw -
+		 (unsigned long)tx->first_entry);
+	tx->curr_entry = next_dcb_hw;
+	memset(db->cpu_addr, 0, FDMA_XTR_BUFFER_SIZE);
+	memcpy(db->cpu_addr, ifh, IFH_LEN * 4);
+	memcpy(db->cpu_addr + IFH_LEN * 4, skb->data, skb->len);
+	db_hw->status = FDMA_DCB_STATUS_SOF |
+			FDMA_DCB_STATUS_EOF |
+			FDMA_DCB_STATUS_BLOCKO(0) |
+			FDMA_DCB_STATUS_BLOCKL(skb->len + IFH_LEN * 4 + 4);
+	if (first_time) {
+		sparx5_fdma_tx_activate(sparx5, tx);
+		first_time = false;
+	} else {
+		sparx5_fdma_tx_reload(sparx5, tx);
+	}
+	return NETDEV_TX_OK;
+}
+
+static int sparx5_fdma_rx_alloc(struct sparx5 *sparx5)
+{
+	struct sparx5_rx *rx = &sparx5->rx;
+	struct sparx5_rx_dcb_hw *dcb;
+	int idx, jdx;
+	int size;
+
+	size = sizeof(struct sparx5_rx_dcb_hw) * FDMA_DCB_MAX;
+	size = ALIGN(size, PAGE_SIZE);
+	rx->dcb_entries = devm_kzalloc(sparx5->dev, size, GFP_KERNEL);
+	if (!rx->dcb_entries)
+		return -ENOMEM;
+	rx->dma = virt_to_phys(rx->dcb_entries);
+	rx->last_entry = rx->dcb_entries;
+	rx->db_index = 0;
+	rx->dcb_index = 0;
+	/* Now for each dcb allocate the db */
+	for (idx = 0; idx < FDMA_DCB_MAX; ++idx) {
+		dcb = &rx->dcb_entries[idx];
+		dcb->info = 0;
+		/* For each db allocate an skb and map skb data pointer to the DB
+		 * dataptr. In this way when the frame is received the skb->data
+		 * will contain the frame, so no memcpy is needed
+		 */
+		for (jdx = 0; jdx < FDMA_RX_DCB_MAX_DBS; ++jdx) {
+			struct sparx5_db_hw *db_hw = &dcb->db[jdx];
+			dma_addr_t dma_addr;
+			struct sk_buff *skb;
+
+			skb = sparx5_fdma_rx_alloc_skb(rx);
+			if (!skb)
+				return -ENOMEM;
+
+			dma_addr = virt_to_phys(skb->data);
+			db_hw->dataptr = dma_addr;
+			db_hw->status = 0;
+			rx->skb[idx][jdx] = skb;
+		}
+		sparx5_fdma_rx_add_dcb(rx, dcb, rx->dma + sizeof(*dcb) * idx);
+	}
+	netif_napi_add(rx->ndev, &rx->napi, sparx5_fdma_napi_callback, FDMA_WEIGHT);
+	napi_enable(&rx->napi);
+	sparx5_fdma_rx_activate(sparx5, rx);
+	return 0;
+}
+
+static int sparx5_fdma_tx_alloc(struct sparx5 *sparx5)
+{
+	struct sparx5_tx *tx = &sparx5->tx;
+	struct sparx5_tx_dcb_hw *dcb;
+	int idx, jdx;
+	int size;
+
+	size = sizeof(struct sparx5_tx_dcb_hw) * FDMA_DCB_MAX;
+	size = ALIGN(size, PAGE_SIZE);
+	tx->curr_entry = devm_kzalloc(sparx5->dev, size, GFP_KERNEL);
+	if (!tx->curr_entry)
+		return -ENOMEM;
+	tx->dma = virt_to_phys(tx->curr_entry);
+	tx->first_entry = tx->curr_entry;
+	INIT_LIST_HEAD(&tx->db_list);
+	/* Now for each dcb allocate the db */
+	for (idx = 0; idx < FDMA_DCB_MAX; ++idx) {
+		dcb = &tx->curr_entry[idx];
+		dcb->info = 0;
+		/* TX databuffers must be 16byte aligned */
+		for (jdx = 0; jdx < FDMA_TX_DCB_MAX_DBS; ++jdx) {
+			struct sparx5_db_hw *db_hw = &dcb->db[jdx];
+			struct sparx5_db *db;
+			dma_addr_t phys;
+			void *cpu_addr;
+
+			cpu_addr = devm_kzalloc(sparx5->dev,
+						FDMA_XTR_BUFFER_SIZE,
+						GFP_KERNEL);
+			if (!cpu_addr)
+				return -ENOMEM;
+			phys = virt_to_phys(cpu_addr);
+			db_hw->dataptr = phys;
+			db_hw->status = 0;
+			db = devm_kzalloc(sparx5->dev, sizeof(*db), GFP_KERNEL);
+			db->cpu_addr = cpu_addr;
+			list_add_tail(&db->list, &tx->db_list);
+		}
+		sparx5_fdma_tx_add_dcb(tx, dcb, tx->dma + sizeof(*dcb) * idx);
+		/* Let the curr_entry to point to the last allocated entry */
+		if (idx == FDMA_DCB_MAX - 1)
+			tx->curr_entry = dcb;
+	}
+	return 0;
+}
+
+static void sparx5_fdma_rx_init(struct sparx5 *sparx5,
+				struct sparx5_rx *rx, int channel)
+{
+	int idx;
+
+	rx->channel_id = channel;
+	/* Fetch a netdev for SKB and NAPI use, any will do */
+	for (idx = 0; idx < SPX5_PORTS; ++idx) {
+		struct sparx5_port *port = sparx5->ports[idx];
+
+		if (port && port->ndev) {
+			rx->ndev = port->ndev;
+			break;
+		}
+	}
+}
+
+static void sparx5_fdma_tx_init(struct sparx5 *sparx5,
+				struct sparx5_tx *tx, int channel)
+{
+	tx->channel_id = channel;
+}
+
+irqreturn_t sparx5_fdma_handler(int irq, void *args)
+{
+	struct sparx5 *sparx5 = args;
+	u32 db = 0, err = 0;
+
+	db = spx5_rd(sparx5, FDMA_INTR_DB);
+	err = spx5_rd(sparx5, FDMA_INTR_ERR);
+	/* Clear interrupt */
+	if (db) {
+		spx5_wr(0, sparx5, FDMA_INTR_DB_ENA);
+		spx5_wr(db, sparx5, FDMA_INTR_DB);
+		napi_schedule(&sparx5->rx.napi);
+	}
+	if (err) {
+		u32 err_type = spx5_rd(sparx5, FDMA_ERRORS);
+
+		dev_err_ratelimited(sparx5->dev,
+				    "ERR: int: %#x, type: %#x\n",
+				    err, err_type);
+		spx5_wr(err, sparx5, FDMA_INTR_ERR);
+		spx5_wr(err_type, sparx5, FDMA_ERRORS);
+	}
+	return IRQ_HANDLED;
+}
+
+static void sparx5_fdma_injection_mode(struct sparx5 *sparx5)
+{
+	const int byte_swap = 1;
+	int portno;
+	int urgency;
+
+	/* Change mode to fdma extraction and injection */
+	spx5_wr(QS_XTR_GRP_CFG_MODE_SET(2) |
+		QS_XTR_GRP_CFG_STATUS_WORD_POS_SET(1) |
+		QS_XTR_GRP_CFG_BYTE_SWAP_SET(byte_swap),
+		sparx5, QS_XTR_GRP_CFG(XTR_QUEUE));
+	spx5_wr(QS_INJ_GRP_CFG_MODE_SET(2) |
+		QS_INJ_GRP_CFG_BYTE_SWAP_SET(byte_swap),
+		sparx5, QS_INJ_GRP_CFG(INJ_QUEUE));
+
+	/* CPU ports capture setup */
+	for (portno = SPX5_PORT_CPU_0; portno <= SPX5_PORT_CPU_1; portno++) {
+		/* ASM CPU port: No preamble, IFH, enable padding */
+		spx5_wr(ASM_PORT_CFG_PAD_ENA_SET(1) |
+			ASM_PORT_CFG_NO_PREAMBLE_ENA_SET(1) |
+			ASM_PORT_CFG_INJ_FORMAT_CFG_SET(1), /* 1 = IFH */
+			sparx5, ASM_PORT_CFG(portno));
+
+		/* Reset WM cnt to unclog queued frames */
+		spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_CNT_CLR_SET(1),
+			 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_CNT_CLR,
+			 sparx5,
+			 DSM_DEV_TX_STOP_WM_CFG(portno));
+
+		/* Set Disassembler Stop Watermark level */
+		spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM_SET(100),
+			 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM,
+			 sparx5,
+			 DSM_DEV_TX_STOP_WM_CFG(portno));
+
+		/* Enable port in queue system */
+		urgency = sparx5_port_fwd_urg(sparx5, SPEED_2500);
+		spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(1) |
+			 QFWD_SWITCH_PORT_MODE_FWD_URGENCY_SET(urgency),
+			 QFWD_SWITCH_PORT_MODE_PORT_ENA |
+			 QFWD_SWITCH_PORT_MODE_FWD_URGENCY,
+			 sparx5,
+			 QFWD_SWITCH_PORT_MODE(portno));
+
+		/* Disable Disassembler buffer underrun watchdog
+		 * to avoid truncated packets in XTR
+		 */
+		spx5_rmw(DSM_BUF_CFG_UNDERFLOW_WATCHDOG_DIS_SET(1),
+			 DSM_BUF_CFG_UNDERFLOW_WATCHDOG_DIS,
+			 sparx5,
+			 DSM_BUF_CFG(portno));
+
+		/* Disabling frame aging */
+		spx5_rmw(HSCH_PORT_MODE_AGE_DIS_SET(1),
+			 HSCH_PORT_MODE_AGE_DIS,
+			 sparx5,
+			 HSCH_PORT_MODE(portno));
+	}
+}
+
+int sparx5_fdma_start(struct sparx5 *sparx5)
+{
+	u32 proc_ctrl;
+	int err;
+
+	/* Reset FDMA state */
+	spx5_wr(FDMA_CTRL_NRESET_SET(0), sparx5, FDMA_CTRL);
+	spx5_wr(FDMA_CTRL_NRESET_SET(1), sparx5, FDMA_CTRL);
+
+	/* Force ACP caching but disable read/write allocation */
+	spx5_rmw(CPU_PROC_CTRL_ACP_CACHE_FORCE_ENA_SET(1) |
+		 CPU_PROC_CTRL_ACP_AWCACHE_SET(0) |
+		 CPU_PROC_CTRL_ACP_ARCACHE_SET(0),
+		 CPU_PROC_CTRL_ACP_CACHE_FORCE_ENA |
+		 CPU_PROC_CTRL_ACP_AWCACHE |
+		 CPU_PROC_CTRL_ACP_ARCACHE,
+		 sparx5, CPU_PROC_CTRL);
+
+	proc_ctrl = spx5_rd(sparx5, CPU_PROC_CTRL);
+	sparx5_fdma_injection_mode(sparx5);
+	sparx5_fdma_rx_init(sparx5, &sparx5->rx, FDMA_XTR_CHANNEL);
+	sparx5_fdma_tx_init(sparx5, &sparx5->tx, FDMA_INJ_CHANNEL);
+	err = sparx5_fdma_rx_alloc(sparx5);
+	if (err) {
+		dev_err(sparx5->dev, "Could not allocate RX buffers: %d\n", err);
+		return err;
+	}
+	err = sparx5_fdma_tx_alloc(sparx5);
+	if (err) {
+		dev_err(sparx5->dev, "Could not allocate TX buffers: %d\n", err);
+		return err;
+	}
+	return err;
+}
+
+static u32 sparx5_fdma_port_ctrl(struct sparx5 *sparx5)
+{
+	return spx5_rd(sparx5, FDMA_PORT_CTRL(0));
+}
+
+int sparx5_fdma_stop(struct sparx5 *sparx5)
+{
+	u32 val;
+
+	napi_disable(&sparx5->rx.napi);
+	/* Stop the fdma and channel interrupts */
+	sparx5_fdma_rx_deactivate(sparx5, &sparx5->rx);
+	sparx5_fdma_tx_deactivate(sparx5, &sparx5->tx);
+	/* Wait for the RX channel to stop */
+	read_poll_timeout(sparx5_fdma_port_ctrl, val,
+			  FDMA_PORT_CTRL_XTR_BUF_IS_EMPTY_GET(val) == 0,
+			  500, 10000, 0, sparx5);
+	return 0;
+}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index f666133a15de..cbece6e9bff2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -640,8 +640,23 @@ static int sparx5_start(struct sparx5 *sparx5)
 	sparx5_board_init(sparx5);
 	err = sparx5_register_notifier_blocks(sparx5);

-	/* Start register based INJ/XTR */
+	/* Start Frame DMA with fallback to register based INJ/XTR */
 	err = -ENXIO;
+	if (sparx5->fdma_irq >= 0) {
+		if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0)
+			err = devm_request_threaded_irq(sparx5->dev,
+							sparx5->fdma_irq,
+							NULL,
+							sparx5_fdma_handler,
+							IRQF_ONESHOT,
+							"sparx5-fdma", sparx5);
+		if (!err)
+			err = sparx5_fdma_start(sparx5);
+		if (err)
+			sparx5->fdma_irq = -ENXIO;
+	} else {
+		sparx5->fdma_irq = -ENXIO;
+	}
 	if (err && sparx5->xtr_irq >= 0) {
 		err = devm_request_irq(sparx5->dev, sparx5->xtr_irq,
 				       sparx5_xtr_handler, IRQF_SHARED,
@@ -766,6 +781,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 		sparx5->base_mac[5] = 0;
 	}

+	sparx5->fdma_irq = platform_get_irq_byname(sparx5->pdev, "fdma");
 	sparx5->xtr_irq = platform_get_irq_byname(sparx5->pdev, "xtr");

 	/* Read chip ID to check CPU interface */
@@ -824,6 +840,11 @@ static int mchp_sparx5_remove(struct platform_device *pdev)
 		disable_irq(sparx5->xtr_irq);
 		sparx5->xtr_irq = -ENXIO;
 	}
+	if (sparx5->fdma_irq) {
+		disable_irq(sparx5->fdma_irq);
+		sparx5->fdma_irq = -ENXIO;
+	}
+	sparx5_fdma_stop(sparx5);
 	sparx5_cleanup_ports(sparx5);
 	/* Unregister netdevs */
 	sparx5_unregister_notifier_blocks(sparx5);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 4d5f44c3a421..a1acc9b461f2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -73,8 +73,61 @@ enum sparx5_vlan_port_type {
 #define XTR_QUEUE     0
 #define INJ_QUEUE     0

+#define FDMA_DCB_MAX			64
+#define FDMA_RX_DCB_MAX_DBS		15
+#define FDMA_TX_DCB_MAX_DBS		1
+
 struct sparx5;

+struct sparx5_db_hw {
+	u64 dataptr;
+	u64 status;
+};
+
+struct sparx5_rx_dcb_hw {
+	u64 nextptr;
+	u64 info;
+	struct sparx5_db_hw db[FDMA_RX_DCB_MAX_DBS];
+};
+
+struct sparx5_tx_dcb_hw {
+	u64 nextptr;
+	u64 info;
+	struct sparx5_db_hw db[FDMA_TX_DCB_MAX_DBS];
+};
+
+/* Frame DMA receive state:
+ * For each DB, there is a SKB, and the skb data pointer is mapped in
+ * the DB. Once a frame is received the skb is given to the upper layers
+ * and a new skb is added to the dcb.
+ * When the db_index reached FDMA_RX_DCB_MAX_DBS the DB is reused.
+ */
+struct sparx5_rx {
+	struct sparx5_rx_dcb_hw *dcb_entries;
+	struct sparx5_rx_dcb_hw *last_entry;
+	struct sk_buff *skb[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS];
+	int db_index;
+	int dcb_index;
+	dma_addr_t dma;
+	struct napi_struct napi;
+	u32 channel_id;
+	struct net_device *ndev;
+	u64 packets;
+};
+
+/* Frame DMA transmit state:
+ * DCBs are chained using the DCBs nextptr field.
+ */
+struct sparx5_tx {
+	struct sparx5_tx_dcb_hw *curr_entry;
+	struct sparx5_tx_dcb_hw *first_entry;
+	struct list_head db_list;
+	dma_addr_t dma;
+	u32 channel_id;
+	u64 packets;
+	u64 dropped;
+};
+
 struct sparx5_port_config {
 	phy_interface_t portmode;
 	u32 bandwidth;
@@ -167,6 +220,10 @@ struct sparx5 {
 	bool sd_sgpio_remapping;
 	/* Register based inj/xtr */
 	int xtr_irq;
+	/* Frame DMA */
+	int fdma_irq;
+	struct sparx5_rx rx;
+	struct sparx5_tx tx;
 };

 /* sparx5_switchdev.c */
@@ -174,11 +231,23 @@ int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
 void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5);

 /* sparx5_packet.c */
+struct frame_info {
+	int src_port;
+};
+
+void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp);
+void sparx5_ifh_parse(u32 *ifh, struct frame_info *info);
 irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
 int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
 int sparx5_manual_injection_mode(struct sparx5 *sparx5);
 void sparx5_port_inj_timer_setup(struct sparx5_port *port);

+/* sparx5_fdma.c */
+int sparx5_fdma_start(struct sparx5 *sparx5);
+int sparx5_fdma_stop(struct sparx5 *sparx5);
+int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb);
+irqreturn_t sparx5_fdma_handler(int irq, void *args);
+
 /* sparx5_mactable.c */
 void sparx5_mact_pull_work(struct work_struct *work);
 int sparx5_mact_learn(struct sparx5 *sparx5, int port,
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
index 09ca7a3bafdc..dc7e5ea6ec15 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
@@ -20,11 +20,7 @@

 #define INJ_TIMEOUT_NS 50000

-struct frame_info {
-	int src_port;
-};
-
-static void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp)
+void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp)
 {
 	/* Start flush */
 	spx5_wr(QS_XTR_FLUSH_FLUSH_SET(BIT(grp)), sparx5, QS_XTR_FLUSH);
@@ -36,7 +32,7 @@ static void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp)
 	spx5_wr(0, sparx5, QS_XTR_FLUSH);
 }

-static void sparx5_ifh_parse(u32 *ifh, struct frame_info *info)
+void sparx5_ifh_parse(u32 *ifh, struct frame_info *info)
 {
 	u8 *xtr_hdr = (u8 *)ifh;

@@ -224,7 +220,10 @@ int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
 	struct sparx5 *sparx5 = port->sparx5;
 	int ret;

-	ret = sparx5_inject(sparx5, port->ifh, skb, dev);
+	if (sparx5->fdma_irq > 0)
+		ret = sparx5_fdma_xmit(sparx5, port->ifh, skb);
+	else
+		ret = sparx5_inject(sparx5, port->ifh, skb, dev);

 	if (ret == NETDEV_TX_OK) {
 		stats->tx_bytes += skb->len;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index d2e3250928bf..189a6a0a2e08 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -596,7 +596,7 @@ static int sparx5_port_max_tags_set(struct sparx5 *sparx5,
 	return 0;
 }

-static int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed)
+int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed)
 {
 	u32 clk_period_ps = 1600; /* 625Mhz for now */
 	u32 urg = 672000;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
index fd05ab6436d1..2f8043eac71b 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
@@ -89,5 +89,6 @@ int sparx5_get_port_status(struct sparx5 *sparx5,
 			   struct sparx5_port_status *status);

 void sparx5_port_enable(struct sparx5_port *port, bool enable);
+int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed);

 #endif	/* __SPARX5_PORT_H__ */
--
2.32.0



From steen.hegelund at microchip.com  Wed Aug 11 00:59:09 2021
From: steen.hegelund at microchip.com (Steen Hegelund)
Date: Wed, 11 Aug 2021 09:59:09 +0200
Subject: [PATCH net-next 2/2] arm64: dts: sparx5: Add the Sparx5 switch frame
 DMA support
In-Reply-To: <20210811075909.543633-1-steen.hegelund@microchip.com>
References: <20210811075909.543633-1-steen.hegelund@microchip.com>
Message-ID: <20210811075909.543633-3-steen.hegelund@microchip.com>

This adds the interrupt for the Sparx5 Frame DMA.

If this configuration is present the Sparx5 SwitchDev driver will use the
Frame DMA feature, and if not it will use register based injection and
extraction for sending and receiving frames to the CPU.

Signed-off-by: Steen Hegelund <steen.hegelund at microchip.com>
---
 arch/arm64/boot/dts/microchip/sparx5.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
index ad07fff40544..787ebcec121d 100644
--- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -471,8 +471,9 @@ switch: switch at 0x600000000 {
 				<0x6 0x10004000 0x7fc000>,
 				<0x6 0x11010000 0xaf0000>;
 			reg-names = "cpu", "dev", "gcb";
-			interrupt-names = "xtr";
-			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "xtr", "fdma";
+			interrupts =	<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
 			resets = <&reset 0>;
 			reset-names = "switch";
 		};
--
2.32.0



From qiangqing.zhang at nxp.com  Wed Aug 11 01:06:57 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Wed, 11 Aug 2021 08:06:57 +0000
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <90af8051-512d-1230-72a7-8bbcee984939@gmail.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
 <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <90af8051-512d-1230-72a7-8bbcee984939@gmail.com>
Message-ID: <VI1PR04MB6800F8425473916A82F050F5E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>


> -----Original Message-----
> From: Florian Fainelli <f.fainelli at gmail.com>
> Sent: 2021?8?11? 1:45
> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
> netdev at vger.kernel.org; devicetree at vger.kernel.org;
> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
> wakeup-irq" property
> 
> 
> 
> On 8/9/2021 7:21 PM, Joakim Zhang wrote:
> >
> > Hi Florian,
> >
> >> -----Original Message-----
> >> From: Florian Fainelli <f.fainelli at gmail.com>
> >> Sent: 2021?8?10? 2:40
> >> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
> >> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> >> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
> >> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
> >> netdev at vger.kernel.org; devicetree at vger.kernel.org;
> >> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> >> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add
> >> "fsl, wakeup-irq" property
> >>
> >>
> >>
> >> On 8/8/2021 10:08 PM, Joakim Zhang wrote:
> >>>
> >>> Hi Florian,
> >>>
> >>>> -----Original Message-----
> >>>> From: Florian Fainelli <f.fainelli at gmail.com>
> >>>> Sent: 2021?8?5? 17:18
> >>>> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
> >>>> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> >>>> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
> >>>> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
> >>>> netdev at vger.kernel.org; devicetree at vger.kernel.org;
> >>>> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> >>>> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add
> >>>> "fsl, wakeup-irq" property
> >>>>
> >>>>
> >>>>
> >>>> On 8/5/2021 12:46 AM, Joakim Zhang wrote:
> >>>>> Add "fsl,wakeup-irq" property for FEC controller to select wakeup
> >>>>> irq source.
> >>>>>
> >>>>> Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
> >>>>> Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
> >>>>
> >>>> Why are not you making use of the standard interrupts-extended
> >>>> property which allows different interrupt lines to be originating
> >>>> from different interrupt controllers, e.g.:
> >>>>
> >>>> interrupts-extended = <&gic GIC_SPI 112 4>, <&wakeup_intc 0>;
> >>>
> >>> Thanks.
> >>>
> >>> AFAIK, interrupts-extended should be used instead of interrupts when
> >>> a device is connected to multiple interrupt controllers as it
> >>> encodes a parent phandle with each interrupt specifier. However, for
> >>> FEC controller, all
> >> interrupt lines are originating from the same interrupt controllers.
> >>
> >> OK, so why this custom property then?
> >>
> >>>
> >>> 1) FEC controller has up to 4 interrupt lines and all of these are
> >>> routed to GIC
> >> interrupt controller.
> >>> 2) FEC has a wakeup interrupt signal and always are mixed with other
> >> interrupt signals, and then output to one interrupt line.
> >>> 3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but for
> >>> i.MX8M
> >> serials, are mixed to int2 line.
> >>> 4) Now driver treat int0 as the wakeup source by default, it is
> >>> broken for
> >> i.MX8M.
> >>
> >> I don't really know what to make of your response, it seems to me
> >> that you are carrying some legacy Device Tree properties that were
> >> invented when interrupts-extended did not exist and we did not know any
> better.
> >
> > As I described in former mail, it is not related to interrupts-extended
> property.
> >
> > Let's take a look, e.g.
> >
> > 1) arch/arm/boot/dts/imx7d.dtsi
> > interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
> > 		<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
> > 		<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
> > 		<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> > interrupt-names = "int0", "int1", "int2", "pps";
> >
> > For these 4 interrupts are originating from GIC interrupt controller,
> > "int0" for queue 0 and other interrupt signals, containing wakeup; "int1" for
> queue 1; "int2" for queue 2.
> >
> > 2) arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
> > 	<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
> > 	<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
> > 	<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
> > interrupt-names = "int0", "int1", "int2", "pps";
> >
> > For these 4 interrupts are also originating from GIC interrupt
> > controller, "int0" for queue 0; "int1" for queue 1; "int2" for queue 2 and other
> interrupt signals, containing wakeup.
> >
> > If we want to use WoL feature, we need invoke enable_irq_wake() to let
> > this specific interrupt line be a wakeup source. For FEC driver now,
> > it treats "int0" as wakeup interrupt by default. Obviously it's not fine for
> i.MX8M serials, since SoC mix wakeup interrupt signal into "int2", so I add this
> "fsl,wakeup-irq" custom property to indicate which interrupt line contains
> wakeup signal.
> >
> > Not sure if I have explained it clearly enough, from my point of view, I think
> interrupts-extended property can't fix this issue, right?
> 
> This is clearer, and indeed interrupts-extended won't fix that, however it seems
> to me that this is a problem that ought to be fixed at the interrupt
> controller/irq_chip level which should know and be told which interrupt lines
> can be made wake-up interrupts or not. From there on, the driver can test with
> enable_irq_wake() whether this has a chance of working or not.

How can we test with enable_irq_wake()? I agree that interrupt controller can recognize
wakeup interrupt is better. 

> It seems to me that the 'fsl,wakeup-irq' property ought to be within the
> interrupt controller Device Tree node (where it would be easier to validate that
> the specific interrupt line is correct) as opposed to within the consumer (FEC)
> Device Tree node.

Not quite understand, could you explain more?

> >
> > If there is any common properties can be used for it, please let me know. Or
> any other better solutions also be appreciated. Thanks.
> 
> There is a standard 'wakeup-source' boolean property that can be added
> to any Device Tree node to indicate it can be a wake-up source, but what
> you need here is a bitmask, so introducing a custom property may be
> appropriate here.

Yes, I know 'wakeup-source' boolean property that identify this DEVICE
can be a wakeup source, it's not related to interrupt.

Best Regards,
Joakim Zhang
> --
> Florian

From maz at kernel.org  Wed Aug 11 01:11:37 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 09:11:37 +0100
Subject: [PATCH 1/5] KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as
 page size
In-Reply-To: <0b47c654-7e9b-a7ca-bdf4-f9607062200e@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
 <25ee7799069492f2501003faec7f9732@kernel.org>
 <0b47c654-7e9b-a7ca-bdf4-f9607062200e@arm.com>
Message-ID: <87zgto9z9i.wl-maz@kernel.org>

On Wed, 11 Aug 2021 06:34:46 +0100,
Anshuman Khandual <anshuman.khandual at arm.com> wrote:
> 
> 
> 
> On 8/10/21 7:03 PM, Marc Zyngier wrote:
> > On 2021-08-10 08:02, Anshuman Khandual wrote:
> >> All instances here could just directly test against CONFIG_ARM64_XXK_PAGES
> >> instead of evaluating via PAGE_SHIFT or PAGE_SIZE. With this change, there
> >> will be no such usage left.
> >>
> >> Cc: Marc Zyngier <maz at kernel.org>
> >> Cc: James Morse <james.morse at arm.com>
> >> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
> >> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> >> Cc: Catalin Marinas <catalin.marinas at arm.com>
> >> Cc: Will Deacon <will at kernel.org>
> >> Cc: linux-arm-kernel at lists.infradead.org
> >> Cc: kvmarm at lists.cs.columbia.edu
> >> Cc: linux-kernel at vger.kernel.org
> >> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> >> ---
> >> ?arch/arm64/kvm/hyp/pgtable.c | 6 +++---
> >> ?arch/arm64/mm/mmu.c????????? | 2 +-
> >> ?2 files changed, 4 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> >> index 05321f4165e3..a6112b6d6ef6 100644
> >> --- a/arch/arm64/kvm/hyp/pgtable.c
> >> +++ b/arch/arm64/kvm/hyp/pgtable.c
> >> @@ -85,7 +85,7 @@ static bool kvm_level_supports_block_mapping(u32 level)
> >> ????? * Reject invalid block mappings and don't bother with 4TB mappings for
> >> ????? * 52-bit PAs.
> >> ????? */
> >> -??? return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
> >> +??? return !(level == 0 || (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) && level == 1));
> >> ?}
> >>
> >> ?static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level)
> >> @@ -155,7 +155,7 @@ static u64 kvm_pte_to_phys(kvm_pte_t pte)
> >> ?{
> >> ???? u64 pa = pte & KVM_PTE_ADDR_MASK;
> >>
> >> -??? if (PAGE_SHIFT == 16)
> >> +??? if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
> >> ???????? pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
> >>
> >> ???? return pa;
> >> @@ -165,7 +165,7 @@ static kvm_pte_t kvm_phys_to_pte(u64 pa)
> >> ?{
> >> ???? kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK;
> >>
> >> -??? if (PAGE_SHIFT == 16)
> >> +??? if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
> >> ???????? pte |= FIELD_PREP(KVM_PTE_ADDR_51_48, pa >> 48);
> >>
> >> ???? return pte;
> >> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> >> index 9ff0de1b2b93..8fdfca179815 100644
> >> --- a/arch/arm64/mm/mmu.c
> >> +++ b/arch/arm64/mm/mmu.c
> >> @@ -296,7 +296,7 @@ static void alloc_init_cont_pmd(pud_t *pudp,
> >> unsigned long addr,
> >> ?static inline bool use_1G_block(unsigned long addr, unsigned long next,
> >> ???????????? unsigned long phys)
> >> ?{
> >> -??? if (PAGE_SHIFT != 12)
> >> +??? if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
> >> ???????? return false;
> >>
> >> ???? if (((addr | next | phys) & ~PUD_MASK) != 0)
> > 
> > I personally find it a lot less readable.
> > 
> > Also, there is no evaluation whatsoever. All the code guarded
> > by a PAGE_SIZE/PAGE_SHIFT that doesn't match the configuration
> > is dropped at compile time.
> 
> The primary idea here is to unify around IS_ENABLED(CONFIG_ARM64_XXK_PAGES)
> usage in arm64, rather than having multiple methods to test page size when
> ever required.

I'm sorry, but I find the idiom extremely painful to parse. If you are
annoyed with the 'PAGE_SHIFT == 12/14/16', consider replacing it with
'PAGE_SIZE == SZ_4/16/64K' instead.

IS_ENABLED(CONFIG_ARM64_XXK_PAGES) also gives the wrong impression
that *multiple* page sizes can be selected at any given time. That's
obviously not the case, which actually makes PAGE_SIZE a much better
choice.

As things stand, I don't plan to take such a patch.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From geert at linux-m68k.org  Wed Aug 11 01:11:34 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:11:34 +0200
Subject: [PATCH v4 02/10] memblock: Add variables for usable memory
 limitation
In-Reply-To: <20210714135101.GB2441138@robh.at.kernel.org>
References: <cover.1626266516.git.geert+renesas@glider.be>
 <04c4d231fb03a3810d72a45c8a5bc2272c5975f3.1626266516.git.geert+renesas@glider.be>
 <20210714135101.GB2441138@robh.at.kernel.org>
Message-ID: <CAMuHMdVRPpHudj2svs_TYP9=GYkWFtJrG_+BHA7A+TVPdQ92aQ@mail.gmail.com>

On Wed, Jul 14, 2021 at 3:51 PM Rob Herring <robh at kernel.org> wrote:
> On Wed, Jul 14, 2021 at 02:50:12PM +0200, Geert Uytterhoeven wrote:
> > Add two global variables (cap_mem_addr and cap_mem_size) for storing a
> > base address and size, describing a limited region in which memory may
> > be considered available for use by the kernel.  If enabled, memory
> > outside of this range is not available for use.
> >
> > These variables can by filled by firmware-specific code, and used in
> > calls to memblock_cap_memory_range() by architecture-specific code.
> > An example user is the parser of the "linux,usable-memory-range"
> > property in the DT "/chosen" node.
> >
> > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> > ---
> > This is similar to how the initial ramdisk (phys_initrd_{start,size})
> > and ELF core headers (elfcorehdr_{addr,size})) are handled.
> >
> > Does there exist a suitable place in the common memblock code to call
> > "memblock_cap_memory_range(cap_mem_addr, cap_mem_size)", or does this
> > have to be done in architecture-specific code?
>
> Can't you just call it from early_init_dt_scan_usablemem? If the
> property is present, you want to call it. If the property is not
> present, nothing happens.

Seems to work fine when called from early_init_dt_scan_nodes().
Hence v5 will no longer need to touch memblock.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From denghuilong at cdjrlc.com  Wed Aug 11 01:20:41 2021
From: denghuilong at cdjrlc.com (Huilong Deng)
Date: Wed, 11 Aug 2021 16:20:41 +0800
Subject: [PATCH] ARM: NOMMU: Return true/false (not 1/0) from bool functions
Message-ID: <20210811082041.32309-1-denghuilong@cdjrlc.com>

./arch/arm/mm/nommu.c:59:8-9: WARNING: return of 0/1 in function
'security_extensions_enabled' with return type bool

Signed-off-by: Huilong Deng <denghuilong at cdjrlc.com>
---
 arch/arm/mm/nommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 2658f52903da..7256ac159acb 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -56,7 +56,7 @@ static inline bool security_extensions_enabled(void)
 	if ((read_cpuid_id() & 0x000f0000) == 0x000f0000)
 		return cpuid_feature_extract(CPUID_EXT_PFR1, 4) ||
 			cpuid_feature_extract(CPUID_EXT_PFR1, 20);
-	return 0;
+	return false;
 }
 
 unsigned long setup_vectors_base(void)
-- 
2.32.0



From f.fainelli at gmail.com  Wed Aug 11 01:36:56 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 11 Aug 2021 01:36:56 -0700
Subject: [PATCH net-next 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <20210810235529.GB30818@linux.intel.com>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
 <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
 <YREvDRkiuScyN8Ws@lunn.ch> <20210810235529.GB30818@linux.intel.com>
Message-ID: <f2a1f135-b77a-403d-5d2e-c497efc99df7@gmail.com>



On 8/10/2021 4:55 PM, Wong Vee Khee wrote:
> Hi Andrew,
> On Mon, Aug 09, 2021 at 03:35:09PM +0200, Andrew Lunn wrote:
>> On Mon, Aug 09, 2021 at 06:22:28PM +0800, Wong Vee Khee wrote:
>>> From: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>
>>>
>>> Unlike any other platforms, Intel AlderLake-S uses Synopsys SerDes where
>>> all the SerDes PLL configurations are controlled by the xPCS at the BIOS
>>> level. If the driver perform a xPCS soft reset on initialization, these
>>> settings will be switched back to the power on reset values.
>>>
>>> This changes the xpcs_create function to take in an additional argument
>>> to check if the platform request to skip xPCS soft reset during device
>>> initialization.
>>
>> Why not just call into the BIOS and ask it to configure the SERDES?
>> Isn't that what ACPI is all about, hiding the details from the OS? Or
>> did the BIOS writers not add a control method to do this?
>>
>>      Andrew
> 
> BIOS does configured the SerDes. The problem here is that all the
> configurations done by BIOS are being reset at xpcs_create().
> 
> We would want user of the pcs-xpcs module (stmmac, sja1105) to have
> control whether or not we need to perform to the soft reset in the
> xpcs_create() call.

I understood Andrew's response as suggesting to introduce the ability 
for xpcs_create() to make a BIOS call which would configure the SerDes 
after xpcs_soft_reset(). That way the current xpcs_create() signature 
would remain the same, but you could easily hook any post-reset 
initialization by making an appropriate BIOS call.
-- 
Florian


From qperret at google.com  Wed Aug 11 01:37:56 2021
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Aug 2021 09:37:56 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
Message-ID: <YROMZFHCor3pbhMr@google.com>

On Wednesday 11 Aug 2021 at 10:48:59 (+0530), Viresh Kumar wrote:
> On 10-08-21, 13:35, Quentin Perret wrote:
> > On Tuesday 10 Aug 2021 at 13:06:47 (+0530), Viresh Kumar wrote:
> > > Provide a cpufreq driver flag so drivers can ask the cpufreq core to register
> > > with the EM core on their behalf.
> > 
> > Hmm, that's not quite what this does. This asks the cpufreq core to
> > use *PM_OPP* to register an EM, which I think is kinda wrong to do from
> > there IMO. The decision to use PM_OPP or another mechanism to register
> > an EM belongs to platform specific code (drivers), so it is odd for the
> > PM_OPP registration to have its own cpufreq flag but not the other ways.
> > 
> > As mentioned in another thread, the very reason to have PM_EM is to not
> > depend on PM_OPP, so I'm worried about the direction of travel with this
> > series TBH.
> 
> I had to use the pm-opp version, since almost everyone was using that.
> 
> On the other hand, there isn't a lot of OPP specific stuff in
> dev_pm_opp_of_register_em(). It just uses dev_pm_opp_get_opp_count(),
> that's all. This ended up in the OPP core, nothing else. Maybe we can
> now move it back to the EM core and name it differently ?

Well it also uses dev_pm_opp_find_freq_ceil() and
dev_pm_opp_get_voltage(), so not sure how easy it will be to move, but
if it is possible no objection from me.

> > > This allows us to get rid of duplicated code
> > > in the drivers and fix the unregistration part as well, which none of the
> > > drivers have done until now.
> > 
> > This series adds more code than it removes,
> 
> Sadly yes :(
> 
> > and the unregistration is
> > not a fix as we don't ever remove the EM tables by design, so not sure
> > either of these points are valid arguments.
> 
> I think that design needs to be looked over again, it looks broken to
> me everytime I land onto this code. I wonder why we don't unregister
> stuff.
> 
> Lets say, I am working on the cpufreq driver and I want to test that
> on my ARM machine. Rebooting a simpler board to test stuff out is
> easy, but if I am working on an ARM server which is running lots of
> other userspace stuff as well, I won't want to reboot the machine just
> to test a different versions of the driver. I will rather want to
> build the driver as module and insert/remove it again and again.
> 
> If the frequency table changes in between versions, this just breaks
> as EM won't be updated again.
> 
> This breaks one of the most basic rules of Linux Kernel. Inserting a
> module should have exactly the same final behavior every single time.
> This model doesn't guarantee it. It simply looks broken.

Right but the EM is a description of the hardware, so it seemed fair
to assume this wouldn't change across the lifetime of the OS, similar
to the DT which we can't reload at run-time. Yes it can be a little odd
if you load/unload your driver module, but note that you generally can't
load two completely different drivers on a single system. You'll just
load the same one again and the hardware hasn't changed in the meantime,
so the previously loaded EM will still be correct. I hear your argument
about cpufreq driver development, but the locking involved to allow
'just' that is pretty involved, and nobody has complained about this
specific issue so far, so that didn't seem worth it. If we do have good
reasons to change the EM at runtime, then yes I think we should do it,
it just didn't seem like that was the case until now.


From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug 11 01:38:29 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed, 11 Aug 2021 17:38:29 +0900
Subject: [PATCH v6 2/3] PCI: visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20210811083830.784065-3-nobuhiro1.iwamatsu@toshiba.co.jp>

Add support to PCIe RC controller on Toshiba Visconti ARM SoCs. PCIe
controller is based of Synopsys DesignWare PCIe core.

Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>

v5 -> v6:
  - Remove unnecessary commit log.
  - Fix split line of visconti_add_pcie_port()

v4 -> v5:
  - Remove PCIE_BUS_OFFSET
  - Change link_up confirmation function of visconti_pcie_link_up().
  - Move setting event mask before dw_pcie_link_up().
  - Move the contents of visconti_pcie_power_on() to visconti_pcie_host_init().
  - Remove code for link_gen.

v3 -> v4:
  - Change variable from pci_addr to cpu_addr in visconti_pcie_cpu_addr_fixup().
  - Change the calculation method of CPU addres from subtraction to mask, and
    add comment.
  - Drop dma_set_mask_and_coherent().
  - Drop set MAX_MSI_IRQS.
  - Drop dev_dbg for Link speed.
  - Use use the dev_err_probe() to handle the devm_clk_get() failed.
  - Changed the redundant clock name.

v2 -> v3:
  - Update subject.
  - Wrap description in 75 columns.
  - Change config name to PCIE_VISCONTI_HOST.
  - Update Kconfig text.
  - Drop blank lines.
  - Adjusted to 80 columns.
  - Drop inline from functions for register access.
  - Changed function name from visconti_pcie_check_link_status to
    visconti_pcie_link_up.
  - Update to using dw_pcie_host_init().
  - Reorder these in the order of use in visconti_pcie_establish_link.
  - Rewrite visconti_pcie_host_init() without dw_pcie_setup_rc().
  - Change function name from  visconti_device_turnon() to
    visconti_pcie_power_on().
  - Unify formats such as dev_err().
  - Drop error label in visconti_add_pcie_port().

v1 -> v2:
  - Fix typo in commit message.
  - Drop "depends on OF && HAS_IOMEM" from Kconfig.
  - Stop using the pointer of struct dw_pcie.
  - Use _relaxed variant.
  - Drop dw_pcie_wait_for_link.
  - Drop dbi resource processing.
  - Drop MSI IRQ initialization processing.
---
 drivers/pci/controller/dwc/Kconfig         |   9 +
 drivers/pci/controller/dwc/Makefile        |   1 +
 drivers/pci/controller/dwc/pcie-visconti.c | 333 +++++++++++++++++++++
 3 files changed, 343 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-visconti.c

diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 423d35872ce4..7c3dcb86fcad 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -286,6 +286,15 @@ config PCIE_TEGRA194_EP
 	  in order to enable device-specific features PCIE_TEGRA194_EP must be
 	  selected. This uses the DesignWare core.
 
+config PCIE_VISCONTI_HOST
+	bool "Toshiba Visconti PCIe controllers"
+	depends on ARCH_VISCONTI || COMPILE_TEST
+	depends on PCI_MSI_IRQ_DOMAIN
+	select PCIE_DW_HOST
+	help
+	  Say Y here if you want PCIe controller support on Toshiba Visconti SoC.
+	  This driver supports TMPV7708 SoC.
+
 config PCIE_UNIPHIER
 	bool "Socionext UniPhier PCIe host controllers"
 	depends on ARCH_UNIPHIER || COMPILE_TEST
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index eca805c1a023..0b569d54deb3 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
 obj-$(CONFIG_PCI_MESON) += pci-meson.o
 obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
 obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
+obj-$(CONFIG_PCIE_VISCONTI_HOST) += pcie-visconti.o
 
 # The following drivers are for devices that use the generic ACPI
 # pci_root.c driver but don't support standard ECAM config access.
diff --git a/drivers/pci/controller/dwc/pcie-visconti.c b/drivers/pci/controller/dwc/pcie-visconti.c
new file mode 100644
index 000000000000..c3fb87c5e7e1
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-visconti.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DWC PCIe RC driver for Toshiba Visconti ARM SoC
+ *
+ * Copyright (C) 2021 Toshiba Electronic Device & Storage Corporation
+ * Copyright (C) 2021 TOSHIBA CORPORATION
+ *
+ * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/of_platform.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+#include <linux/types.h>
+
+#include "pcie-designware.h"
+#include "../../pci.h"
+
+struct visconti_pcie {
+	struct dw_pcie pci;
+	void __iomem *ulreg_base;
+	void __iomem *smu_base;
+	void __iomem *mpu_base;
+	struct clk *refclk;
+	struct clk *coreclk;
+	struct clk *auxclk;
+};
+
+#define PCIE_UL_REG_S_PCIE_MODE		0x00F4
+#define  PCIE_UL_REG_S_PCIE_MODE_EP	0x00
+#define  PCIE_UL_REG_S_PCIE_MODE_RC	0x04
+
+#define PCIE_UL_REG_S_PERSTN_CTRL	0x00F8
+#define  PCIE_UL_IOM_PCIE_PERSTN_I_EN	BIT(3)
+#define  PCIE_UL_DIRECT_PERSTN_EN	BIT(2)
+#define  PCIE_UL_PERSTN_OUT		BIT(1)
+#define  PCIE_UL_DIRECT_PERSTN		BIT(0)
+#define  PCIE_UL_REG_S_PERSTN_CTRL_INIT	(PCIE_UL_IOM_PCIE_PERSTN_I_EN | \
+					 PCIE_UL_DIRECT_PERSTN_EN | \
+					 PCIE_UL_DIRECT_PERSTN)
+
+#define PCIE_UL_REG_S_PHY_INIT_02	0x0104
+#define  PCIE_UL_PHY0_SRAM_EXT_LD_DONE	BIT(0)
+
+#define PCIE_UL_REG_S_PHY_INIT_03	0x0108
+#define  PCIE_UL_PHY0_SRAM_INIT_DONE	BIT(0)
+
+#define PCIE_UL_REG_S_INT_EVENT_MASK1	0x0138
+#define  PCIE_UL_CFG_PME_INT		BIT(0)
+#define  PCIE_UL_CFG_LINK_EQ_REQ_INT	BIT(1)
+#define  PCIE_UL_EDMA_INT0		BIT(2)
+#define  PCIE_UL_EDMA_INT1		BIT(3)
+#define  PCIE_UL_EDMA_INT2		BIT(4)
+#define  PCIE_UL_EDMA_INT3		BIT(5)
+#define  PCIE_UL_S_INT_EVENT_MASK1_ALL  (PCIE_UL_CFG_PME_INT | \
+					 PCIE_UL_CFG_LINK_EQ_REQ_INT | \
+					 PCIE_UL_EDMA_INT0 | \
+					 PCIE_UL_EDMA_INT1 | \
+					 PCIE_UL_EDMA_INT2 | \
+					 PCIE_UL_EDMA_INT3)
+
+#define PCIE_UL_REG_S_SB_MON		0x0198
+#define PCIE_UL_REG_S_SIG_MON		0x019C
+#define  PCIE_UL_CORE_RST_N_MON		BIT(0)
+
+#define PCIE_UL_REG_V_SII_DBG_00	0x0844
+#define PCIE_UL_REG_V_SII_GEN_CTRL_01	0x0860
+#define  PCIE_UL_APP_LTSSM_ENABLE	BIT(0)
+
+#define PCIE_UL_REG_V_PHY_ST_00		0x0864
+#define  PCIE_UL_SMLH_LINK_UP		BIT(0)
+
+#define PCIE_UL_REG_V_PHY_ST_02		0x0868
+#define  PCIE_UL_S_DETECT_ACT		0x01
+#define  PCIE_UL_S_L0			0x11
+
+#define PISMU_CKON_PCIE			0x0038
+#define  PISMU_CKON_PCIE_AUX_CLK	BIT(1)
+#define  PISMU_CKON_PCIE_MSTR_ACLK	BIT(0)
+
+#define PISMU_RSOFF_PCIE		0x0538
+#define  PISMU_RSOFF_PCIE_ULREG_RST_N	BIT(1)
+#define  PISMU_RSOFF_PCIE_PWR_UP_RST_N	BIT(0)
+
+#define PCIE_MPU_REG_MP_EN		0x0
+#define  MPU_MP_EN_DISABLE		BIT(0)
+
+/* Access registers in PCIe ulreg */
+static void visconti_ulreg_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
+{
+	writel_relaxed(val, pcie->ulreg_base + reg);
+}
+
+static u32 visconti_ulreg_readl(struct visconti_pcie *pcie, u32 reg)
+{
+	return readl_relaxed(pcie->ulreg_base + reg);
+}
+
+/* Access registers in PCIe smu */
+static void visconti_smu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
+{
+	writel_relaxed(val, pcie->smu_base + reg);
+}
+
+/* Access registers in PCIe mpu */
+static void visconti_mpu_writel(struct visconti_pcie *pcie, u32 val, u32 reg)
+{
+	writel_relaxed(val, pcie->mpu_base + reg);
+}
+
+static u32 visconti_mpu_readl(struct visconti_pcie *pcie, u32 reg)
+{
+	return readl_relaxed(pcie->mpu_base + reg);
+}
+
+static int visconti_pcie_link_up(struct dw_pcie *pci)
+{
+	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
+	void __iomem *addr = pcie->ulreg_base;
+	u32 val = readl_relaxed(addr + PCIE_UL_REG_V_PHY_ST_02);
+
+	return !!(val & PCIE_UL_S_L0);
+}
+
+static int visconti_pcie_start_link(struct dw_pcie *pci)
+{
+	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
+	void __iomem *addr = pcie->ulreg_base;
+	u32 val;
+	int ret;
+
+	visconti_ulreg_writel(pcie, PCIE_UL_APP_LTSSM_ENABLE,
+			      PCIE_UL_REG_V_SII_GEN_CTRL_01);
+
+	ret = readl_relaxed_poll_timeout(addr + PCIE_UL_REG_V_PHY_ST_02,
+					 val, (val & PCIE_UL_S_L0),
+					 90000, 100000);
+	if (ret)
+		return ret;
+
+	visconti_ulreg_writel(pcie, PCIE_UL_S_INT_EVENT_MASK1_ALL,
+			      PCIE_UL_REG_S_INT_EVENT_MASK1);
+
+	if (dw_pcie_link_up(pci)) {
+		val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
+		visconti_mpu_writel(pcie, val & ~MPU_MP_EN_DISABLE,
+				    PCIE_MPU_REG_MP_EN);
+	}
+
+	return 0;
+}
+
+static void visconti_pcie_stop_link(struct dw_pcie *pci)
+{
+	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
+	u32 val;
+
+	val = visconti_ulreg_readl(pcie, PCIE_UL_REG_V_SII_GEN_CTRL_01);
+	val &= ~PCIE_UL_APP_LTSSM_ENABLE;
+	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_V_SII_GEN_CTRL_01);
+
+	val = visconti_mpu_readl(pcie, PCIE_MPU_REG_MP_EN);
+	visconti_mpu_writel(pcie, val | MPU_MP_EN_DISABLE, PCIE_MPU_REG_MP_EN);
+}
+
+/*
+ * In this SoC specification, the CPU bus outputs the offset value from
+ * 0x40000000 to the PCIE bus, so 0x40000000 is subtracted from the CPU
+ * bus address. This 0x40000000 is also based on io_base from DT.
+ */
+static u64 visconti_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 cpu_addr)
+{
+	struct pcie_port *pp = &pci->pp;
+
+	return cpu_addr & ~pp->io_base;
+}
+
+static const struct dw_pcie_ops dw_pcie_ops = {
+	.cpu_addr_fixup = visconti_pcie_cpu_addr_fixup,
+	.link_up = visconti_pcie_link_up,
+	.start_link = visconti_pcie_start_link,
+	.stop_link = visconti_pcie_stop_link,
+};
+
+static int visconti_pcie_host_init(struct pcie_port *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct visconti_pcie *pcie = dev_get_drvdata(pci->dev);
+	void __iomem *addr;
+	int err;
+	u32 val;
+
+	visconti_smu_writel(pcie,
+			    PISMU_CKON_PCIE_AUX_CLK | PISMU_CKON_PCIE_MSTR_ACLK,
+			    PISMU_CKON_PCIE);
+	ndelay(250);
+
+	visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_ULREG_RST_N,
+			    PISMU_RSOFF_PCIE);
+	visconti_ulreg_writel(pcie, PCIE_UL_REG_S_PCIE_MODE_RC,
+			      PCIE_UL_REG_S_PCIE_MODE);
+
+	val = PCIE_UL_REG_S_PERSTN_CTRL_INIT;
+	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
+	udelay(100);
+
+	val |= PCIE_UL_PERSTN_OUT;
+	visconti_ulreg_writel(pcie, val, PCIE_UL_REG_S_PERSTN_CTRL);
+	udelay(100);
+
+	visconti_smu_writel(pcie, PISMU_RSOFF_PCIE_PWR_UP_RST_N,
+			    PISMU_RSOFF_PCIE);
+
+	addr = pcie->ulreg_base + PCIE_UL_REG_S_PHY_INIT_03;
+	err = readl_relaxed_poll_timeout(addr, val,
+					 (val & PCIE_UL_PHY0_SRAM_INIT_DONE),
+					 100, 1000);
+	if (err)
+		return err;
+
+	visconti_ulreg_writel(pcie, PCIE_UL_PHY0_SRAM_EXT_LD_DONE,
+			      PCIE_UL_REG_S_PHY_INIT_02);
+
+	addr = pcie->ulreg_base + PCIE_UL_REG_S_SIG_MON;
+	return readl_relaxed_poll_timeout(addr, val,
+					  (val & PCIE_UL_CORE_RST_N_MON), 100,
+					  1000);
+}
+
+static const struct dw_pcie_host_ops visconti_pcie_host_ops = {
+	.host_init = visconti_pcie_host_init,
+};
+
+static int visconti_get_resources(struct platform_device *pdev,
+				  struct visconti_pcie *pcie)
+{
+	struct device *dev = &pdev->dev;
+
+	pcie->ulreg_base = devm_platform_ioremap_resource_byname(pdev, "ulreg");
+	if (IS_ERR(pcie->ulreg_base))
+		return PTR_ERR(pcie->ulreg_base);
+
+	pcie->smu_base = devm_platform_ioremap_resource_byname(pdev, "smu");
+	if (IS_ERR(pcie->smu_base))
+		return PTR_ERR(pcie->smu_base);
+
+	pcie->mpu_base = devm_platform_ioremap_resource_byname(pdev, "mpu");
+	if (IS_ERR(pcie->mpu_base))
+		return PTR_ERR(pcie->mpu_base);
+
+	pcie->refclk = devm_clk_get(dev, "ref");
+	if (IS_ERR(pcie->refclk))
+		return dev_err_probe(dev, PTR_ERR(pcie->refclk),
+				     "Failed to get ref clock\n");
+
+	pcie->coreclk = devm_clk_get(dev, "core");
+	if (IS_ERR(pcie->coreclk))
+		return dev_err_probe(dev, PTR_ERR(pcie->coreclk),
+				     "Failed to get core clock\n");
+
+	pcie->auxclk = devm_clk_get(dev, "aux");
+	if (IS_ERR(pcie->auxclk))
+		return dev_err_probe(dev, PTR_ERR(pcie->auxclk),
+				     "Failed to get aux clock\n");
+
+	return 0;
+}
+
+static int visconti_add_pcie_port(struct visconti_pcie *pcie,
+				  struct platform_device *pdev)
+{
+	struct dw_pcie *pci = &pcie->pci;
+	struct pcie_port *pp = &pci->pp;
+	struct device *dev = &pdev->dev;
+
+	pp->irq = platform_get_irq_byname(pdev, "intr");
+	if (pp->irq < 0) {
+		dev_err(dev, "Interrupt intr is missing");
+		return pp->irq;
+	}
+
+	pp->ops = &visconti_pcie_host_ops;
+
+	return dw_pcie_host_init(pp);
+}
+
+static int visconti_pcie_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct visconti_pcie *pcie;
+	struct dw_pcie *pci;
+	int ret;
+
+	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	pci = &pcie->pci;
+	pci->dev = dev;
+	pci->ops = &dw_pcie_ops;
+
+	ret = visconti_get_resources(pdev, pcie);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, pcie);
+
+	return visconti_add_pcie_port(pcie, pdev);
+}
+
+static const struct of_device_id visconti_pcie_match[] = {
+	{ .compatible = "toshiba,visconti-pcie" },
+	{},
+};
+
+static struct platform_driver visconti_pcie_driver = {
+	.probe = visconti_pcie_probe,
+	.driver = {
+		.name = "visconti-pcie",
+		.of_match_table = visconti_pcie_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+builtin_platform_driver(visconti_pcie_driver);
-- 
2.32.0




From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug 11 01:38:27 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed, 11 Aug 2021 17:38:27 +0900
Subject: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host controller
 driver
Message-ID: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>

Hi,

This series is the PCIe driver for Toshiba's ARM SoC, Visconti[0].
This provides DT binding documentation, device driver, MAINTAINER files.

Best regards,
  Nobuhiro

[0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html

  dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
    v5 -> v6:
      - No update.
    v4 -> v5:
      - No update.
    v3 -> v4:
     - Changed the redundant clock name.
    v2 -> v3:
      - No update.
    v1 -> v2:
      - Remove white space.
      - Drop num-viewport and bus-range from required.
      - Drop status line from example.
      - Drop bus-range from required.
      - Removed lines defined in pci-bus.yaml from required.

  PCI: visconti: Add Toshiba Visconti PCIe host controller driver
    v5 -> v6:                                                                                                                                                                                                                                                                                                                         - Remove unnecessary commit log.                                                                                                                                                                                                                                                                                                - Fix split line of visconti_add_pcie_port() 
    v4 -> v5:
      - Remove PCIE_BUS_OFFSET
      - Change link_up confirmation function of visconti_pcie_link_up().
      - Move setting event mask before dw_pcie_link_up().
      - Move the contents of visconti_pcie_power_on() to visconti_pcie_host_init().
      - Remove code for link_gen.
    v3 -> v4:
      - Change variable from pci_addr to cpu_addr in visconti_pcie_cpu_addr_fixup().
      - Change the calculation method of CPU addres from subtraction to mask, and
        add comment.
      - Drop dma_set_mask_and_coherent().
      - Drop set MAX_MSI_IRQS.
      - Drop dev_dbg for Link speed.
      - Use use the dev_err_probe() to handle the devm_clk_get() failed.
      - Changed the redundant clock name.
    v2 -> v3:
      - Update subject.
      - Wrap description in 75 columns.
      - Change config name to PCIE_VISCONTI_HOST.
      - Update Kconfig text.
      - Drop empty lines.
      - Adjusted to 80 columns.
      - Drop inline from functions for register access.
      - Changed function name from visconti_pcie_check_link_status to
        visconti_pcie_link_up.
      - Update to using dw_pcie_host_init().
      - Reorder these in the order of use in visconti_pcie_establish_link().
      - Rewrite visconti_pcie_host_init() without dw_pcie_setup_rc().
      - Change function name from  visconti_device_turnon() to
        visconti_pcie_power_on().
      - Unify formats such as dev_err().
      - Drop error label in visconti_add_pcie_port(). 
    v1 -> v2:
      - Fix typo in commit message.
      - Drop "depends on OF && HAS_IOMEM" from Kconfig.
      - Stop using the pointer of struct dw_pcie.
      - Use _relaxed variant.
      - Drop dw_pcie_wait_for_link.
      - Drop dbi resource processing.
      - Drop MSI IRQ initialization processing.
  
  MAINTAINERS: Add entries for Toshiba Visconti PCIe controller
    v5 -> v6:
      - No update.
    v4 -> v5:
      - No update.
    v3 -> v4:
      - No update.
    v2 -> v3:
      - No update.
    v1 -> v2:
      - No update.

Nobuhiro Iwamatsu (3):
  dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
  PCI: visconti: Add Toshiba Visconti PCIe host controller driver
  MAINTAINERS: Add entries for Toshiba Visconti PCIe controller

 .../bindings/pci/toshiba,visconti-pcie.yaml   | 110 ++++++
 MAINTAINERS                                   |   2 +
 drivers/pci/controller/dwc/Kconfig            |   9 +
 drivers/pci/controller/dwc/Makefile           |   1 +
 drivers/pci/controller/dwc/pcie-visconti.c    | 333 ++++++++++++++++++
 5 files changed, 455 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-visconti.c

-- 
2.32.0



From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug 11 01:38:30 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed, 11 Aug 2021 17:38:30 +0900
Subject: [PATCH v6 3/3] MAINTAINERS: Add entries for Toshiba Visconti PCIe
 controller
In-Reply-To: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20210811083830.784065-4-nobuhiro1.iwamatsu@toshiba.co.jp>

Add entries for Toshiba Visconti PCIe controller binding and driver.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bd7aff0c120f..8554e02de0cc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2663,11 +2663,13 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iwamatsu/linux-visconti.git
 F:	Documentation/devicetree/bindings/arm/toshiba.yaml
 F:	Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
 F:	Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
+F:	Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
 F:	Documentation/devicetree/bindings/pinctrl/toshiba,tmpv7700-pinctrl.yaml
 F:	Documentation/devicetree/bindings/watchdog/toshiba,visconti-wdt.yaml
 F:	arch/arm64/boot/dts/toshiba/
 F:	drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
 F:	drivers/gpio/gpio-visconti.c
+F:	drivers/pci/controller/dwc/pcie-visconti.c
 F:	drivers/pinctrl/visconti/
 F:	drivers/watchdog/visconti_wdt.c
 N:	visconti
-- 
2.32.0




From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug 11 01:38:28 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Wed, 11 Aug 2021 17:38:28 +0900
Subject: [PATCH v6 1/3] dt-bindings: pci: Add DT binding for Toshiba Visconti
 PCIe controller
In-Reply-To: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20210811083830.784065-2-nobuhiro1.iwamatsu@toshiba.co.jp>

This commit adds the Device Tree binding documentation that allows
to describe the PCIe controller found in Toshiba Visconti SoCs.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>

v3 -> v4:
 - Changed the redundant clock name.

v2 -> v3:
 - No update.

v1 -> v2:
 - Remove white space.
 - Drop num-viewport and bus-range from required.
 - Drop status line from example.
 - Drop bus-range from required.
 - Removed lines defined in pci-bus.yaml from required.
---
 .../bindings/pci/toshiba,visconti-pcie.yaml   | 110 ++++++++++++++++++
 1 file changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
new file mode 100644
index 000000000000..60ec424cd07c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/toshiba,visconti-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Toshiba Visconti5 SoC PCIe Host Controller Device Tree Bindings
+
+maintainers:
+  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
+
+description:
+  Toshiba Visconti5 SoC PCIe host controller is based on the Synopsys DesignWare PCIe IP.
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+
+properties:
+  compatible:
+    const: toshiba,visconti-pcie
+
+  reg:
+    items:
+      - description: Data Bus Interface (DBI) registers.
+      - description: PCIe configuration space region.
+      - description: Visconti specific additional registers.
+      - description: Visconti specific SMU registers
+      - description: Visconti specific memory protection unit registers (MPU)
+
+  reg-names:
+    items:
+      - const: dbi
+      - const: config
+      - const: ulreg
+      - const: smu
+      - const: mpu
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PCIe reference clock
+      - description: PCIe system clock
+      - description: Auxiliary clock
+
+  clock-names:
+    items:
+      - const: ref
+      - const: core
+      - const: aux
+
+  num-lanes:
+    const: 2
+
+required:
+  - reg
+  - reg-names
+  - interrupts
+  - "#interrupt-cells"
+  - interrupt-map
+  - interrupt-map-mask
+  - num-lanes
+  - clocks
+  - clock-names
+  - max-link-speed
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pcie: pcie at 28400000 {
+            compatible = "toshiba,visconti-pcie";
+            reg = <0x0 0x28400000 0x0 0x00400000>,
+                  <0x0 0x70000000 0x0 0x10000000>,
+                  <0x0 0x28050000 0x0 0x00010000>,
+                  <0x0 0x24200000 0x0 0x00002000>,
+                  <0x0 0x24162000 0x0 0x00001000>;
+            reg-names  = "dbi", "config", "ulreg", "smu", "mpu";
+            device_type = "pci";
+            bus-range = <0x00 0xff>;
+            num-lanes = <2>;
+            num-viewport = <8>;
+
+            #address-cells = <3>;
+            #size-cells = <2>;
+            #interrupt-cells = <1>;
+            ranges = <0x81000000 0 0x40000000 0 0x40000000 0 0x00010000>,
+                     <0x82000000 0 0x50000000 0 0x50000000 0 0x20000000>;
+            interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+            interrupt-names = "intr";
+            interrupt-map-mask = <0 0 0 7>;
+            interrupt-map =
+                <0 0 0 1 &gic GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH
+                 0 0 0 2 &gic GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH
+                 0 0 0 3 &gic GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH
+                 0 0 0 4 &gic GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&extclk100mhz>, <&clk600mhz>, <&clk25mhz>;
+            clock-names = "ref", "core", "aux";
+            max-link-speed = <2>;
+        };
+    };
+...
-- 
2.32.0




From f.fainelli at gmail.com  Wed Aug 11 01:39:52 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 11 Aug 2021 01:39:52 -0700
Subject: [PATCH 1/3] PCI: brcmstb: Break register definitions into
 separate header
In-Reply-To: <ab2aa9e3-cdc7-1bc7-d493-8f3c991c3285@arm.com>
References: <20210805211200.491275-1-jeremy.linton@arm.com>
 <20210805211200.491275-2-jeremy.linton@arm.com>
 <f82761b1-fb7e-08b2-8bc3-c84d258e26d3@gmail.com>
 <ab2aa9e3-cdc7-1bc7-d493-8f3c991c3285@arm.com>
Message-ID: <ff7c598a-4c1d-7da0-f40a-f0c435e785d3@gmail.com>



On 8/10/2021 8:10 AM, Jeremy Linton wrote:
> Hi,
> 
> Thanks for taking a look at this!
> 
> 
> On 8/10/21 5:07 AM, Florian Fainelli wrote:
>>
>>
>> On 8/5/2021 2:11 PM, Jeremy Linton wrote:
>>> We are about to create a standalone ACPI quirk module for the
>>> bcmstb controller. Lets move the register definitions into a separate
>>> file so they can be shared between the APCI quirk and the normal
>>> host bridge driver.
>>>
>>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>>> ---
>>> ? drivers/pci/controller/pcie-brcmstb.c | 179 +------------------------
>>> ? drivers/pci/controller/pcie-brcmstb.h | 182 ++++++++++++++++++++++++++
>>> ? 2 files changed, 183 insertions(+), 178 deletions(-)
>>> ? create mode 100644 drivers/pci/controller/pcie-brcmstb.h
>>
>> You moved more than just register definitions into pcie-brcmstb.h you 
>> also moved internal structure definitions, enumerations, etc. which 
>> are not required since pcie-brcmstb-acpi.c does not access the 
>> brcm_pcie structure but open codes accesses to the MISC_STATUS 
>> register instead.
>>
>> There are no include guards added to this file (it is debatable 
>> whether we should add them), and it is also not covered by the 
>> existing BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE MAINTAINERS file 
>> entry.
> 
> Sure, I will reduce the .h to just the register definitions, guard it, 
> and tweak maintainers to cover pcie-brcmstb*.
> 
> 
>>
>> Given that there can be new platforms supported by this PCIe 
>> controller in the future possibly with the same limitations as the 
>> 2711, but with a seemingly different MISC_STATUS layout, you will have 
>> to think about a solution that scales, maybe we cross that bridge when 
>> we get there.
> 
> Yes, given I don't know what those changes are I can't predict how they 
> would have to be handled, or even if the platform would be a target of 
> the community maintaining the UEFI/ACPI port on the RPi. So punting on 
> that topic seems a reasonable solution at the moment. Better yet, more 
> of the linux community will see the advantage of the firmware interface 
> and this platform can utilize that method.

Ideally newer platforms would support ECAM and would not require a 
custom quirk if nothing else, we do have discussions about that right 
now, although it is not clear to me how it will materialize into a 
product that people can buy.
-- 
Florian


From krzysztof.kozlowski at canonical.com  Wed Aug 11 01:38:58 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 10:38:58 +0200
Subject: [PATCH 1/2] dt-bindings: ata: drop unused Exynos SATA bindings
Message-ID: <20210811083859.28234-1-krzysztof.kozlowski@canonical.com>

The Samsung Exynos SoC SATA bindings are not implemented in the kernel,
not used and superseded by generic
Documentation/devicetree/bindings/ata/ahci-platform.txt bindings.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/ata/exynos-sata.txt   | 30 -------------------
 1 file changed, 30 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/ata/exynos-sata.txt

diff --git a/Documentation/devicetree/bindings/ata/exynos-sata.txt b/Documentation/devicetree/bindings/ata/exynos-sata.txt
deleted file mode 100644
index cb48448247ea..000000000000
--- a/Documentation/devicetree/bindings/ata/exynos-sata.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-* Samsung AHCI SATA Controller
-
-SATA nodes are defined to describe on-chip Serial ATA controllers.
-Each SATA controller should have its own node.
-
-Required properties:
-- compatible		: compatible list, contains "samsung,exynos5-sata"
-- interrupts		: <interrupt mapping for SATA IRQ>
-- reg			: <registers mapping>
-- samsung,sata-freq	: <frequency in MHz>
-- phys			: Must contain exactly one entry as specified
-			  in phy-bindings.txt
-- phy-names		: Must be "sata-phy"
-
-Optional properties:
-- clocks		: Must contain an entry for each entry in clock-names.
-- clock-names		: Shall be "sata" for the external SATA bus clock,
-			  and "sclk_sata" for the internal controller clock.
-
-Example:
-	sata at 122f0000 {
-		compatible = "snps,dwc-ahci";
-		samsung,sata-freq = <66>;
-		reg = <0x122f0000 0x1ff>;
-		interrupts = <0 115 0>;
-		clocks = <&clock 277>, <&clock 143>;
-		clock-names = "sata", "sclk_sata";
-		phys = <&sata_phy>;
-		phy-names = "sata-phy";
-	};
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 11 01:38:59 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 10:38:59 +0200
Subject: [PATCH 2/2] ARM: dts: exynos: drop undocumented samsung,
 sata-freq property in Exynos5250
In-Reply-To: <20210811083859.28234-1-krzysztof.kozlowski@canonical.com>
References: <20210811083859.28234-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210811083859.28234-2-krzysztof.kozlowski@canonical.com>

The samsung,sata-freq property is not used (and not documented by
generic AHCI platform bindings), so can be safely dropped.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 2ea2caaca4e2..c8c41657988b 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -375,7 +375,6 @@ tmu: tmu at 10060000 {
 
 		sata: sata at 122f0000 {
 			compatible = "snps,dwc-ahci";
-			samsung,sata-freq = <66>;
 			reg = <0x122F0000 0x1ff>;
 			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&clock CLK_SATA>, <&clock CLK_SCLK_SATA>;
-- 
2.30.2



From wenst at chromium.org  Wed Aug 11 01:41:04 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 11 Aug 2021 16:41:04 +0800
Subject: [PATCH v4 3/8] i2c: mediatek: Reset the handshake signal between
 i2c and dma
In-Reply-To: <1626517079-9057-4-git-send-email-kewei.xu@mediatek.com>
References: <1626517079-9057-1-git-send-email-kewei.xu@mediatek.com>
 <1626517079-9057-4-git-send-email-kewei.xu@mediatek.com>
Message-ID: <CAGXv+5EGpUV0eaQ6duZ8y8u2dvc1y3uc2YwWP=07D+ZZpzMCvQ@mail.gmail.com>

Hi,

On Sat, Jul 17, 2021 at 6:29 PM Kewei Xu <kewei.xu at mediatek.com> wrote:
>
> Due to changes in the hardware design of the handshaking signal
> between i2c and dma, it is necessary to reset the handshaking
> signal before each transfer to ensure that the multi-msgs can
> be transferred correctly.

This also affects MT8192. Has this been tested on that SoC as well?

> Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
> ---
>  drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
> index 222ff765e55d..c0108387f34b 100644
> --- a/drivers/i2c/busses/i2c-mt65xx.c
> +++ b/drivers/i2c/busses/i2c-mt65xx.c
> @@ -47,6 +47,9 @@
>  #define I2C_RD_TRANAC_VALUE            0x0001
>  #define I2C_SCL_MIS_COMP_VALUE         0x0000
>  #define I2C_CHN_CLR_FLAG               0x0000
> +#define I2C_CLR_DEBUGCTR               0x0000
> +#define I2C_RELIABILITY                        0x0010
> +#define I2C_DMAACK_ENABLE              0x0008
>
>  #define I2C_DMA_CON_TX                 0x0000
>  #define I2C_DMA_CON_RX                 0x0001
> @@ -850,6 +853,17 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
>
>         reinit_completion(&i2c->msg_complete);
>
> +       if (i2c->dev_comp->apdma_sync) {
> +               mtk_i2c_writew(i2c, I2C_CLR_DEBUGCTR, OFFSET_DEBUGCTRL);
> +               writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_WARM_RST,
> +                      i2c->pdmabase + OFFSET_RST);
> +               writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);

I2C_DMA_WARM_RST is self-clearing. Is I2C_DMA_HANDSHAKE_RST not
self-clearing? If both are self-clearing, don't you need to wait and
check for them to cleared? If they aren't self-clearing, do you need
to delay some time for them to complete?

> +               mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST, OFFSET_SOFTRESET);
> +               mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET);

Same here. No time delay needed?

> +               mtk_i2c_writew(i2c, I2C_RELIABILITY | I2C_DMAACK_ENABLE,
> +                              OFFSET_DEBUGCTRL);

A comment explaining what the section above does would be nice. AFAICU
this is force resetting the DMA handling.


Regards
ChenYu

> +       }
> +
>         control_reg = mtk_i2c_readw(i2c, OFFSET_CONTROL) &
>                         ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
>         if ((i2c->speed_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) || (left_num >= 1))
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From ming.qian at nxp.com  Wed Aug 11 01:42:56 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:42:56 +0800
Subject: [PATCH v6 00/14] imx8q video decoder/encoder driver
Message-ID: <cover.1628671163.git.ming.qian@nxp.com>

Hi all,

This patch series adds support for
the imx8q video encoder and decoder
via the VPU block present in imx8q platforms.
Currently, support for IMX8QXP and IMX8QM is included.

It features decoding for the following formats:
- H.264
- HEVC
- MPEG4
- MPEG2
- VC1
- VP8

It features encoding for the following formats:
- H.264

The driver creates a separate device node for
the encoder and decoder.

Changelog:

v6:
- rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
- rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128

v5:
- move some definition from imx_vph.h to videodev2.h
- remove some unnecessary content
- add some documentation descriptions
- pass the lateset v4l2-compliance test

v4:
- redefine the memory-region in devicetree bindings documentation
- use v4l2's mechanism to implement synchronize queuing ioctl
- remove the unnecessary mutex ioctl_sync
- don't notify source change event if the parameters are same as previously established
- add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format

v3:
- don't make vpu device node a simple-bus
- trigger probing vpu core in the driver
- remove unnecessary vpu core index property

v2:
- fix dt bindings build error
- split driver patch into several parts to avoid exceeding bytes limit

Compliance
==========
# v4l2-compliance -d /dev/video0
v4l2-compliance 1.21.0-4834, 64 bits, 64-bit time_t
v4l2-compliance SHA: 7952c0042ccf 2021-08-04 13:17:37

Compliance test for vpu B0 device /dev/video0:

Driver Info:
	Driver name      : vpu B0
	Card type        : imx vpu decoder
	Bus info         : platform: imx8q-vpu
	Driver version   : 5.14.0
	Capabilities     : 0x84204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
	Detected Stateful Decoder

Required ioctls:
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video0 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 3 Private Controls: 0

Format ioctls:
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK (Not Supported)
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK (Not Supported)
	test Composing: OK
	test Scaling: OK (Not Supported)

Codec ioctls:
	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK

Buffer ioctls:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)

Total for vpu B0 device /dev/video0: 45, Succeeded: 45, Failed: 0, Warnings: 0

# v4l2-compliance -d /dev/video1
v4l2-compliance 1.21.0-4834, 64 bits, 64-bit time_t
v4l2-compliance SHA: 7952c0042ccf 2021-08-04 13:17:37

Compliance test for imx vpu encoder device /dev/video1:

Driver Info:
	Driver name      : imx vpu encoder
	Card type        : imx vpu encoder
	Bus info         : platform: imx8q-vpu
	Driver version   : 5.14.0
	Capabilities     : 0x84204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
	Detected Stateful Encoder

Required ioctls:
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video1 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 20 Private Controls: 0

Format ioctls:
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK
	test Composing: OK (Not Supported)
	test Scaling: OK (Not Supported)

Codec ioctls:
	test VIDIOC_(TRY_)ENCODER_CMD: OK
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)

Total for imx vpu encoder device /dev/video1: 45, Succeeded: 45, Failed: 0, Warnings: 0

Ming Qian (14):
  dt-bindings: media: imx8q: add imx video codec bindings
  media:Add nt8 and nt10 video format.
  media:Add v4l2 buf flag codec data.
  media: imx: imx8q: add imx8q vpu device driver
  media: imx: imx8q: add vpu core driver
  media: imx: imx8q: implement vpu core communication based on mailbox
  media: imx: imx8q: add vpu v4l2 m2m support
  media: imx: imx8q: add v4l2 m2m vpu encoder stateful driver
  media: imx: imx8q: add v4l2 m2m vpu decoder stateful driver
  media: imx: imx8q: implement windsor encoder rpc interface
  media: imx: imx8q: implement malone decoder rpc interface
  ARM64: dts: freescale: imx8q: add imx vpu codec entries
  firmware: imx: scu-pd: imx8q: add vpu mu resources
  MAINTAINERS: add NXP IMX8Q VPU CODEC V4L2 driver entry

 .../bindings/media/nxp,imx8q-vpu.yaml         |  178 ++
 .../userspace-api/media/v4l/buffer.rst        |    7 +
 .../media/v4l/pixfmt-yuv-planar.rst           |   15 +
 .../media/v4l/vidioc-dqevent.rst              |   12 +
 MAINTAINERS                                   |   10 +
 .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
 drivers/firmware/imx/scu-pd.c                 |    4 +
 drivers/media/platform/Kconfig                |    2 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/imx/Kconfig            |   19 +
 drivers/media/platform/imx/Makefile           |    1 +
 drivers/media/platform/imx/vpu-8q/Makefile    |   23 +
 drivers/media/platform/imx/vpu-8q/vdec.c      | 1682 ++++++++++++++++
 drivers/media/platform/imx/vpu-8q/venc.c      | 1383 ++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu.h       |  333 ++++
 drivers/media/platform/imx/vpu-8q/vpu_cmds.c  |  438 +++++
 drivers/media/platform/imx/vpu-8q/vpu_cmds.h  |   25 +
 drivers/media/platform/imx/vpu-8q/vpu_codec.h |   68 +
 drivers/media/platform/imx/vpu-8q/vpu_color.c |  192 ++
 drivers/media/platform/imx/vpu-8q/vpu_core.c  |  910 +++++++++
 drivers/media/platform/imx/vpu-8q/vpu_core.h  |   16 +
 drivers/media/platform/imx/vpu-8q/vpu_dbg.c   |  496 +++++
 drivers/media/platform/imx/vpu-8q/vpu_defs.h  |  186 ++
 .../media/platform/imx/vpu-8q/vpu_dev_imx8q.c |   73 +
 drivers/media/platform/imx/vpu-8q/vpu_drv.c   |  217 +++
 .../media/platform/imx/vpu-8q/vpu_helpers.c   |  453 +++++
 .../media/platform/imx/vpu-8q/vpu_helpers.h   |   72 +
 drivers/media/platform/imx/vpu-8q/vpu_imx8q.c |  218 +++
 drivers/media/platform/imx/vpu-8q/vpu_imx8q.h |  116 ++
 drivers/media/platform/imx/vpu-8q/vpu_log.h   |   44 +
 .../media/platform/imx/vpu-8q/vpu_malone.c    | 1687 +++++++++++++++++
 .../media/platform/imx/vpu-8q/vpu_malone.h    |   42 +
 drivers/media/platform/imx/vpu-8q/vpu_mbox.c  |  126 ++
 drivers/media/platform/imx/vpu-8q/vpu_mbox.h  |   16 +
 drivers/media/platform/imx/vpu-8q/vpu_msgs.c  |  412 ++++
 drivers/media/platform/imx/vpu-8q/vpu_msgs.h  |   14 +
 drivers/media/platform/imx/vpu-8q/vpu_rpc.c   |  257 +++
 drivers/media/platform/imx/vpu-8q/vpu_rpc.h   |  463 +++++
 drivers/media/platform/imx/vpu-8q/vpu_v4l2.c  |  654 +++++++
 drivers/media/platform/imx/vpu-8q/vpu_v4l2.h  |   44 +
 .../media/platform/imx/vpu-8q/vpu_windsor.c   | 1244 ++++++++++++
 .../media/platform/imx/vpu-8q/vpu_windsor.h   |   39 +
 drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
 include/linux/imx_vpu.h                       |   11 +
 include/uapi/linux/imx_vpu.h                  |   17 +
 include/uapi/linux/videodev2.h                |    5 +
 48 files changed, 12341 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
 create mode 100644 drivers/media/platform/imx/Kconfig
 create mode 100644 drivers/media/platform/imx/Makefile
 create mode 100644 drivers/media/platform/imx/vpu-8q/Makefile
 create mode 100644 drivers/media/platform/imx/vpu-8q/vdec.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/venc.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_cmds.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_cmds.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_codec.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_color.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_core.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_core.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_dbg.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_defs.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_drv.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_helpers.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_helpers.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_imx8q.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_imx8q.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_log.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_malone.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_malone.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_mbox.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_mbox.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_msgs.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_msgs.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_rpc.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_rpc.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_v4l2.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_v4l2.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_windsor.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_windsor.h
 create mode 100644 include/linux/imx_vpu.h
 create mode 100644 include/uapi/linux/imx_vpu.h

-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:42:57 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:42:57 +0800
Subject: [PATCH v6 01/14] dt-bindings: media: imx8q: add imx video codec
 bindings
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <74899fe01678641839be0eea7e3fd35214aad84c.1628671163.git.ming.qian@nxp.com>

Add devicetree binding documentation for IMX8Q Video Processing Unit IP

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/media/nxp,imx8q-vpu.yaml         | 178 ++++++++++++++++++
 1 file changed, 178 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml

diff --git a/Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
new file mode 100644
index 000000000000..04a040e5a9d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
@@ -0,0 +1,178 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/nxp,imx8q-vpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8Q video encode and decode accelerators
+
+maintainers:
+  - Ming Qian <ming.qian at nxp.com>
+  - Shijie Qin <shijie.qin at nxp.com>
+
+description: |-
+  The Amphion MXC video encoder(Windsor) and decoder(Malone) accelerators present
+  on NXP i.MX8Q SoCs.
+
+properties:
+  $nodename:
+    pattern: "^vpu@[0-9a-f]+$"
+
+  compatible:
+    oneOf:
+      - const: nxp,imx8qm-vpu
+      - const: nxp,imx8qxp-vpu
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^mailbox@[0-9a-f]+$":
+    description:
+      Each vpu encoder or decoder correspond a MU, which used for communication
+      between driver and firmware. Implement via mailbox on driver.
+    $ref: ../mailbox/fsl,mu.yaml#
+
+
+  "^vpu_core@[0-9a-f]+$":
+    description:
+      Each core correspond a decoder or encoder, need to configure them
+      separately. NXP i.MX8QM SoC has one decoder and two encoder, i.MX8QXP SoC
+      has one decoder and one encoder.
+    type: object
+
+    properties:
+      compatible:
+        oneOf:
+          - const: nxp,imx8q-vpu-decoder
+          - const: nxp,imx8q-vpu-encoder
+
+      reg:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+      mbox-names:
+        items:
+          - const: tx0
+          - const: tx1
+          - const: rx
+
+      mboxes:
+        description:
+          List of phandle of 2 MU channels for tx, 1 MU channel for rx.
+        maxItems: 3
+
+      memory-region:
+        description:
+          Phandle to the reserved memory nodes to be associated with the
+          remoteproc device. The reserved memory nodes should be carveout nodes,
+          and should be defined as per the bindings in
+          Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+        items:
+          - description: region reserved for firmware image sections.
+          - description: region used for RPC shared memory between firmware and
+                         driver.
+
+    required:
+      - compatible
+      - reg
+      - power-domains
+      - mbox-names
+      - mboxes
+      - memory-region
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  # Device node example for i.MX8QM platform:
+  - |
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    vpu: vpu at 2c000000 {
+      compatible = "nxp,imx8qm-vpu";
+      ranges = <0x2c000000 0x2c000000 0x2000000>;
+      reg = <0x2c000000 0x1000000>;
+      #address-cells = <1>;
+      #size-cells = <1>;
+      power-domains = <&pd IMX_SC_R_VPU>;
+
+      mu_m0: mailbox at 2d000000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d000000 0x20000>;
+        interrupts = <0 472 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+      };
+
+      mu1_m0: mailbox at 2d020000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d020000 0x20000>;
+        interrupts = <0 473 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+      };
+
+      mu2_m0: mailbox at 2d040000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d040000 0x20000>;
+        interrupts = <0 474 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+      };
+
+      vpu_core0: vpu_core at 2d080000 {
+        compatible = "nxp,imx8q-vpu-decoder";
+        reg = <0x2d080000 0x10000>;
+        power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu_m0 0 0>,
+                 <&mu_m0 0 1>,
+                 <&mu_m0 1 0>;
+        memory-region = <&decoder_boot>, <&decoder_rpc>;
+      };
+
+      vpu_core1: vpu_core at 2d090000 {
+        compatible = "nxp,imx8q-vpu-encoder";
+        reg = <0x2d090000 0x10000>;
+        power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu1_m0 0 0>,
+                 <&mu1_m0 0 1>,
+                 <&mu1_m0 1 0>;
+        memory-region = <&encoder1_boot>, <&encoder1_rpc>;
+      };
+
+      vpu_core2: vpu_core at 2d0a0000 {
+        reg = <0x2d0a0000 0x10000>;
+        compatible = "nxp,imx8q-vpu-encoder";
+        power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu2_m0 0 0>,
+                 <&mu2_m0 0 1>,
+                 <&mu2_m0 1 0>;
+        memory-region = <&encoder2_boot>, <&encoder2_rpc>;
+      };
+    };
+
+...
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Aug 11 01:43:05 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 10:43:05 +0200
Subject: [PATCH 1/2] dt-bindings: irqchip: convert Samsung Exynos IRQ combiner
 to dtschema
Message-ID: <20210811084306.28740-1-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos SoC Interrupt Combiner Controller bindings to DT
schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../samsung,exynos4210-combiner.txt           | 50 ----------
 .../samsung,exynos4210-combiner.yaml          | 96 +++++++++++++++++++
 2 files changed, 96 insertions(+), 50 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.txt b/Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.txt
deleted file mode 100644
index 19af687858a1..000000000000
--- a/Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-* Samsung Exynos Interrupt Combiner Controller
-
-Samsung's Exynos4 architecture includes a interrupt combiner controller which
-can combine interrupt sources as a group and provide a single interrupt request
-for the group. The interrupt request from each group are connected to a parent
-interrupt controller, such as GIC in case of Exynos4210.
-
-The interrupt combiner controller consists of multiple combiners. Up to eight
-interrupt sources can be connected to a combiner. The combiner outputs one
-combined interrupt for its eight interrupt sources. The combined interrupt
-is usually connected to a parent interrupt controller.
-
-A single node in the device tree is used to describe the interrupt combiner
-controller module (which includes multiple combiners). A combiner in the
-interrupt controller module shares config/control registers with other
-combiners. For example, a 32-bit interrupt enable/disable config register
-can accommodate up to 4 interrupt combiners (with each combiner supporting
-up to 8 interrupt sources).
-
-Required properties:
-- compatible: should be "samsung,exynos4210-combiner".
-- interrupt-controller: Identifies the node as an interrupt controller.
-- #interrupt-cells: should be <2>. The meaning of the cells are
-	* First Cell: Combiner Group Number.
-	* Second Cell: Interrupt number within the group.
-- reg: Base address and size of interrupt combiner registers.
-- interrupts: The list of interrupts generated by the combiners which are then
-    connected to a parent interrupt controller. The format of the interrupt
-    specifier depends in the interrupt parent controller.
-
-Optional properties:
-- samsung,combiner-nr: The number of interrupt combiners supported. If this
-  property is not specified, the default number of combiners is assumed
-  to be 16.
-
-
-Example:
-
-	The following is a an example from the Exynos4210 SoC dtsi file.
-
-	combiner:interrupt-controller at 10440000 {
-		compatible = "samsung,exynos4210-combiner";
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		reg = <0x10440000 0x1000>;
-		interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
-			     <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
-			     <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
-			     <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
-	};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.yaml b/Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.yaml
new file mode 100644
index 000000000000..d631b7589d50
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/samsung,exynos4210-combiner.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC Interrupt Combiner Controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  Samsung's Exynos4 architecture includes a interrupt combiner controller which
+  can combine interrupt sources as a group and provide a single interrupt
+  request for the group. The interrupt request from each group are connected to
+  a parent interrupt controller, such as GIC in case of Exynos4210.
+
+  The interrupt combiner controller consists of multiple combiners. Up to eight
+  interrupt sources can be connected to a combiner. The combiner outputs one
+  combined interrupt for its eight interrupt sources. The combined interrupt is
+  usually connected to a parent interrupt controller.
+
+  A single node in the device tree is used to describe the interrupt combiner
+  controller module (which includes multiple combiners). A combiner in the
+  interrupt controller module shares config/control registers with other
+  combiners. For example, a 32-bit interrupt enable/disable config register can
+  accommodate up to 4 interrupt combiners (with each combiner supporting up to
+  8 interrupt sources).
+
+allOf:
+  - $ref: /schemas/interrupt-controller.yaml#
+
+properties:
+  compatible:
+    const: samsung,exynos4210-combiner
+
+  interrupt-controller: true
+
+  interrupts:
+    minItems: 8
+    maxItems: 32
+
+  "#interrupt-cells":
+    description: |
+      The meaning of the cells are:
+        * First Cell: Combiner Group Number.
+        * Second Cell: Interrupt number within the group.
+    const: 2
+
+  reg:
+    maxItems: 1
+
+  samsung,combiner-nr:
+    description: |
+      The number of interrupt combiners supported.  Should match number
+      of interrupts set in "interrupts" property.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 8
+    maximum: 32
+    default: 16
+
+required:
+  - compatible
+  - interrupt-controller
+  - interrupts
+  - "#interrupt-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    interrupt-controller at 10440000 {
+        compatible = "samsung,exynos4210-combiner";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x10440000 0x1000>;
+        interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 11 01:43:06 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 10:43:06 +0200
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to dtschema
In-Reply-To: <20210811084306.28740-1-krzysztof.kozlowski@canonical.com>
References: <20210811084306.28740-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210811084306.28740-2-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos SoC True Random Number Generator bindings to DT
schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
 .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
 MAINTAINERS                                   |  2 +-
 3 files changed, 45 insertions(+), 18 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
 create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml

diff --git a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
deleted file mode 100644
index 5a613a4ec780..000000000000
--- a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Exynos True Random Number Generator
-
-Required properties:
-
-- compatible  : Should be "samsung,exynos5250-trng".
-- reg         : Specifies base physical address and size of the registers map.
-- clocks      : Phandle to clock-controller plus clock-specifier pair.
-- clock-names : "secss" as a clock name.
-
-Example:
-
-	rng at 10830600 {
-		compatible = "samsung,exynos5250-trng";
-		reg = <0x10830600 0x100>;
-		clocks = <&clock CLK_SSS>;
-		clock-names = "secss";
-	};
diff --git a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
new file mode 100644
index 000000000000..a50c34d5d199
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rng/samsung,exynos5250-trng.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC True Random Number Generator
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - ?ukasz Stelmach <l.stelmach at samsung.com>
+
+properties:
+  compatible:
+    const: samsung,exynos5250-trng
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: secss
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5250.h>
+
+    rng at 10830600 {
+        compatible = "samsung,exynos5250-trng";
+        reg = <0x10830600 0x100>;
+        clocks = <&clock CLK_SSS>;
+        clock-names = "secss";
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 4477215ef649..ebdb07a49b02 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16398,7 +16398,7 @@ SAMSUNG EXYNOS TRUE RANDOM NUMBER GENERATOR (TRNG) DRIVER
 M:	?ukasz Stelmach <l.stelmach at samsung.com>
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
+F:	Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
 F:	drivers/char/hw_random/exynos-trng.c
 
 SAMSUNG FRAMEBUFFER DRIVER
-- 
2.30.2



From ming.qian at nxp.com  Wed Aug 11 01:42:58 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:42:58 +0800
Subject: [PATCH v6 02/14] media:Add nt8 and nt10 video format.
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <981eee1270fb47658f7821d59525ff4c53c30644.1628671163.git.ming.qian@nxp.com>

NT8 is 8-bit tiled nv12 format used by amphion decoder.
NT10 is 10-bit tiled format used by amphion decoder.
The tile size is 8x128

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../userspace-api/media/v4l/pixfmt-yuv-planar.rst | 15 +++++++++++++++
 drivers/media/v4l2-core/v4l2-ioctl.c              |  2 ++
 include/uapi/linux/videodev2.h                    |  4 ++++
 3 files changed, 21 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
index 090c091affd2..ce3419d95691 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
@@ -254,6 +254,8 @@ of the luma plane.
 
 .. _V4L2-PIX-FMT-NV12MT:
 .. _V4L2-PIX-FMT-NV12MT-16X16:
+.. _V4L2_PIX_FMT_NV12_8L128:
+.. _V4L2_PIX_FMT_NV12_10BE_8L128:
 
 NV12MT and MV12MT_16X16
 -----------------------
@@ -276,6 +278,19 @@ If the vertical resolution is an odd number of macroblocks, the last row of
 macroblocks is stored in linear order. The layouts of the luma and chroma
 planes are identical.
 
+``V4L2_PIX_FMT_NV12_8L128`` stores pixel in 2D 8x128 tiles, and stores
+tiles linearly in memory. The line stride must be aligned to a multiple of 256.
+The image height must be aligned to a multiple of 128. The layouts of the
+luma and chroma planes are identical.
+
+``V4L2_PIX_FMT_NV12_10BE_8L128`` stores 10 bits pixel in 2D 8x128 tiles,
+and stores tiles linearly in memory. the data is arranged at the big end.
+The line stride must be aligned to a multiple of 256 bytes.  The image
+height must be aligned to a multiple of 128.  The layouts of the luma
+and chroma planes are identical. Note the tile size is 8bytes multiplied
+by 128 bytes, it means that the low bits and high bits of one pixel
+may be in differnt tiles.
+
 .. _nv12mt:
 
 .. kernel-figure:: nv12mt.svg
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 05d5db3d85e5..22f97a1cfbeb 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1367,6 +1367,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
+	case V4L2_PIX_FMT_NV12_8L128:		descr = "Y/CbCr 4:2:0 (8x128 Linear)"; break;
+	case V4L2_PIX_FMT_NV12_10BE_8L128:	descr = "Y/CbCr 4:2:0 10BE(8x128 Linear)"; break;
 
 	default:
 		/* Compressed formats */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 9260791b8438..167c0e40ec06 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -627,6 +627,10 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_YUV444M v4l2_fourcc('Y', 'M', '2', '4') /* 24  YUV444 planar */
 #define V4L2_PIX_FMT_YVU444M v4l2_fourcc('Y', 'M', '4', '2') /* 24  YVU444 planar */
 
+/* Tiled YUV formats */
+#define V4L2_PIX_FMT_NV12_8L128      v4l2_fourcc('N', 'A', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */
+#define V4L2_PIX_FMT_NV12_10BE_8L128 v4l2_fourcc('N', 'T', '1', '2') /* Y/CbCr 4:2:0 10-bit 8x128 tiles */
+
 /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
 #define V4L2_PIX_FMT_SGBRG8  v4l2_fourcc('G', 'B', 'R', 'G') /*  8  GBGB.. RGRG.. */
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:00 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:00 +0800
Subject: [PATCH v6 04/14] media: imx: imx8q: add imx8q vpu device driver
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <a0a5e02315390a2ebe94898c385f0a82db180390.1628671163.git.ming.qian@nxp.com>

IMX8Q SoCs feature a powerful video processing unit able to decode many
foramts and encode H.264.

The vpu IP is amphion malone decoder and windsor encoder.
This Driver is for this IP that is based on the v4l2 mem2mem framework.

Supported SoCs are: IMX8QXP, IMX8QM

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../media/v4l/vidioc-dqevent.rst              |  12 +
 drivers/media/platform/Kconfig                |   2 +
 drivers/media/platform/Makefile               |   2 +
 drivers/media/platform/imx/Kconfig            |  19 +
 drivers/media/platform/imx/Makefile           |   1 +
 drivers/media/platform/imx/vpu-8q/Makefile    |  23 ++
 drivers/media/platform/imx/vpu-8q/vpu.h       | 333 ++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_defs.h  | 186 ++++++++++
 .../media/platform/imx/vpu-8q/vpu_dev_imx8q.c |  73 ++++
 drivers/media/platform/imx/vpu-8q/vpu_drv.c   | 217 ++++++++++++
 include/linux/imx_vpu.h                       |  11 +
 include/uapi/linux/imx_vpu.h                  |  17 +
 12 files changed, 896 insertions(+)
 create mode 100644 drivers/media/platform/imx/Kconfig
 create mode 100644 drivers/media/platform/imx/Makefile
 create mode 100644 drivers/media/platform/imx/vpu-8q/Makefile
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_defs.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_drv.c
 create mode 100644 include/linux/imx_vpu.h
 create mode 100644 include/uapi/linux/imx_vpu.h

diff --git a/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst b/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
index 6eb40073c906..926e360758e1 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
@@ -185,6 +185,18 @@ call.
     * - ``V4L2_EVENT_PRIVATE_START``
       - 0x08000000
       - Base event number for driver-private events.
+    * - ``V4L2_EVENT_CODEC_ERROR``
+      - 0x08000001
+      - This event is triggered when some error occurs inside the codec engine,
+    usually it can be replaced by a POLLERR event, but in some cases, the POLLERR
+    may cause the application to exit, but this event can allow the application to
+    handle the codec error without exiting.
+    * - ``V4L2_EVENT_SKIP``
+      - 0x08000002
+      - This event is triggered when one frame is decoded, but it won't be outputed
+    to the display. So the application can't get this frame, and the input frame count
+    is dismatch with the output frame count. And this evevt is telling the client to
+    handle this case.
 
 
 .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.5cm}|
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 157c924686e4..0072672297d2 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -200,6 +200,8 @@ config VIDEO_TI_CAL_MC
 
 endif # VIDEO_TI_CAL
 
+source "drivers/media/platform/imx/Kconfig"
+
 endif # V4L_PLATFORM_DRIVERS
 
 menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 73ce083c2fc6..b159c69f58e0 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -86,3 +86,5 @@ obj-$(CONFIG_VIDEO_QCOM_VENUS)		+= qcom/venus/
 obj-y					+= sunxi/
 
 obj-$(CONFIG_VIDEO_MESON_GE2D)		+= meson/ge2d/
+
+obj-y					+= imx/
diff --git a/drivers/media/platform/imx/Kconfig b/drivers/media/platform/imx/Kconfig
new file mode 100644
index 000000000000..40cceb2cb526
--- /dev/null
+++ b/drivers/media/platform/imx/Kconfig
@@ -0,0 +1,19 @@
+#
+# Codec configuration
+#
+
+config MXC_VPU_8Q
+	tristate "Support for MXC 8Q VPU(Video Processing Unit) Codec"
+	depends on ARCH_MXC
+	depends on MEDIA_SUPPORT
+	depends on VIDEO_DEV
+	depends on VIDEO_V4L2
+	select V4L2_MEM2MEM_DEV
+	select VIDEOBUF2_DMA_CONTIG
+	select VIDEOBUF2_VMALLOC
+	default y
+	help
+	  This is a V4L2 driver for NXP MXC 8Q video accelerator hardware.
+	  It accelerates encoding and decoding operations on
+	  various NXP SoCs.
+	  To compile this driver as a module choose m here.
diff --git a/drivers/media/platform/imx/Makefile b/drivers/media/platform/imx/Makefile
new file mode 100644
index 000000000000..214f43ca390c
--- /dev/null
+++ b/drivers/media/platform/imx/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MXC_VPU_8Q) += vpu-8q/
diff --git a/drivers/media/platform/imx/vpu-8q/Makefile b/drivers/media/platform/imx/vpu-8q/Makefile
new file mode 100644
index 000000000000..ecc74b63d536
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/Makefile
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for NXP VPU driver
+
+vpu-8q-dev-objs += vpu_drv.o \
+			vpu_dev_imx8q.o
+
+vpu-8q-core-objs += vpu_core.o \
+			vpu_mbox.o \
+			vpu_v4l2.o \
+			vpu_helpers.o \
+			vpu_cmds.o \
+			vpu_msgs.o \
+			vpu_rpc.o \
+			vpu_imx8q.o \
+			vpu_windsor.o \
+			vpu_malone.o \
+			vpu_color.o \
+			vdec.o  \
+			venc.o \
+			vpu_dbg.o
+
+obj-$(CONFIG_MXC_VPU_8Q) += vpu-8q-dev.o
+obj-$(CONFIG_MXC_VPU_8Q) += vpu-8q-core.o
diff --git a/drivers/media/platform/imx/vpu-8q/vpu.h b/drivers/media/platform/imx/vpu-8q/vpu.h
new file mode 100644
index 000000000000..81f347d953ae
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu.h
@@ -0,0 +1,333 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_H
+#define _IMX_VPU_H
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-mem2mem.h>
+#include <linux/mailbox_client.h>
+#include <linux/mailbox_controller.h>
+#include <linux/kfifo.h>
+
+#define VPU_TIMEOUT		msecs_to_jiffies(1000)
+#define VPU_INST_NULL_ID	(-1L)
+#define VPU_MSG_BUFFER_SIZE	(8192)
+
+enum imx_plat_type {
+	IMX8QXP = 0,
+	IMX8QM  = 1,
+	IMX8DM,
+	IMX8DX,
+	PLAT_TYPE_RESERVED
+};
+
+enum vpu_core_type {
+	VPU_CORE_TYPE_ENC = 0,
+	VPU_CORE_TYPE_DEC = 0x10,
+};
+
+struct vpu_dev;
+struct vpu_resources {
+	enum imx_plat_type plat_type;
+	u32 mreg_base;
+	int (*setup)(struct vpu_dev *vpu);
+	int (*setup_encoder)(struct vpu_dev *vpu);
+	int (*setup_decoder)(struct vpu_dev *vpu);
+	int (*reset)(struct vpu_dev *vpu);
+};
+
+struct vpu_buffer {
+	void *virt;
+	dma_addr_t phys;
+	u32 length;
+	u32 bytesused;
+	struct device *dev;
+};
+
+struct vpu_dev {
+	void __iomem *base;
+	struct platform_device *pdev;
+	struct device *dev;
+	struct mutex lock;
+	const struct vpu_resources *res;
+	struct list_head cores;
+
+	struct v4l2_device v4l2_dev;
+	struct video_device *vdev_dec;
+	struct video_device *vdev_enc;
+
+	struct delayed_work watchdog_work;
+	void (*get_vpu)(struct vpu_dev *vpu);
+	void (*put_vpu)(struct vpu_dev *vpu);
+	void (*get_enc)(struct vpu_dev *vpu);
+	void (*put_enc)(struct vpu_dev *vpu);
+	void (*get_dec)(struct vpu_dev *vpu);
+	void (*put_dec)(struct vpu_dev *vpu);
+	atomic_t ref_vpu;
+	atomic_t ref_enc;
+	atomic_t ref_dec;
+
+	struct dentry *debugfs;
+};
+
+struct vpu_format {
+	u32 pixfmt;
+	unsigned int num_planes;
+	u32 type;
+	u32 flags;
+	u32 width;
+	u32 height;
+	u32 sizeimage[VIDEO_MAX_PLANES];
+	u32 bytesperline[VIDEO_MAX_PLANES];
+	u32 field;
+};
+
+struct vpu_core_resources {
+	enum vpu_core_type type;
+	const char *fwname;
+	u32 stride;
+	u32 max_width;
+	u32 min_width;
+	u32 step_width;
+	u32 max_height;
+	u32 min_height;
+	u32 step_height;
+	u32 rpc_size;
+	u32 fwlog_size;
+	u32 act_size;
+	bool standalone;
+};
+
+struct vpu_mbox {
+	char name[20];
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	bool block;
+};
+
+enum vpu_core_state {
+	VPU_CORE_DEINIT = 0,
+	VPU_CORE_ACTIVE,
+	VPU_CORE_SNAPSHOT,
+	VPU_CORE_HANG
+};
+
+struct vpu_core {
+	void __iomem *base;
+	struct platform_device *pdev;
+	struct device *dev;
+	struct device *parent;
+	struct device *pd;
+	struct device_link *pd_link;
+	struct mutex lock;
+	struct mutex cmd_lock;
+	struct list_head list;
+	enum vpu_core_type type;
+	int id;
+	const struct vpu_core_resources *res;
+	unsigned long instance_mask;
+	u32 supported_instance_count;
+	unsigned long hang_mask;
+	u32 request_count;
+	struct list_head instances;
+	enum vpu_core_state state;
+	u32 fw_version;
+
+	struct vpu_buffer fw;
+	struct vpu_buffer rpc;
+	struct vpu_buffer log;
+	struct vpu_buffer act;
+
+	struct vpu_mbox tx_type;
+	struct vpu_mbox tx_data;
+	struct vpu_mbox rx;
+	unsigned long cmd_seq;
+
+	wait_queue_head_t ack_wq;
+	struct completion cmp;
+	struct workqueue_struct *workqueue;
+	struct work_struct msg_work;
+	struct delayed_work msg_delayed_work;
+	struct kfifo msg_fifo;
+	void *msg_buffer;
+	unsigned int msg_buffer_size;
+
+	struct vpu_dev *vpu;
+	void *iface;
+
+	struct dentry *debugfs;
+	struct dentry *debugfs_fwlog;
+};
+
+enum vpu_codec_state {
+	VPU_CODEC_STATE_DEINIT = 1,
+	VPU_CODEC_STATE_CONFIGURED,
+	VPU_CODEC_STATE_START,
+	VPU_CODEC_STATE_STARTED,
+	VPU_CODEC_STATE_ACTIVE,
+	VPU_CODEC_STATE_SEEK,
+	VPU_CODEC_STATE_STOP,
+	VPU_CODEC_STATE_DRAIN,
+	VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE,
+};
+
+struct vpu_frame_info {
+	u32 type;
+	u32 id;
+	u32 sequence;
+	u32 luma;
+	u32 chroma_u;
+	u32 chroma_v;
+	u32 data_offset;
+	u32 flags;
+	u32 skipped;
+	s64 timestamp;
+};
+
+struct vpu_inst;
+struct vpu_inst_ops {
+	int (*ctrl_init)(struct vpu_inst *inst);
+	int (*start)(struct vpu_inst *inst, u32 type);
+	int (*stop)(struct vpu_inst *inst, u32 type);
+	int (*abort)(struct vpu_inst *inst);
+	bool (*check_ready)(struct vpu_inst *inst, unsigned int type);
+	void (*buf_done)(struct vpu_inst *inst, struct vpu_frame_info *frame);
+	void (*event_notify)(struct vpu_inst *inst, u32 event, void *data);
+	void (*release)(struct vpu_inst *inst);
+	void (*cleanup)(struct vpu_inst *inst);
+	void (*mem_request)(struct vpu_inst *inst,
+				u32 enc_frame_size,
+				u32 enc_frame_num,
+				u32 ref_frame_size,
+				u32 ref_frame_num,
+				u32 act_frame_size,
+				u32 act_frame_num);
+	void (*input_done)(struct vpu_inst *inst);
+	void (*stop_done)(struct vpu_inst *inst);
+	int (*process_output)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*process_capture)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*get_one_frame)(struct vpu_inst *inst, void *info);
+	void (*on_queue_empty)(struct vpu_inst *inst, u32 type);
+	int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);
+	void (*wait_prepare)(struct vpu_inst *inst);
+	void (*wait_finish)(struct vpu_inst *inst);
+};
+
+struct vpu_inst {
+	struct list_head list;
+	struct mutex lock;
+	struct vpu_core *core;
+	int id;
+
+	struct v4l2_fh fh;
+	struct v4l2_m2m_dev *m2m_dev;
+	struct v4l2_m2m_ctx *m2m_ctx;
+	struct v4l2_ctrl_handler ctrl_handler;
+	atomic_t ref_count;
+	int (*release)(struct vpu_inst *inst);
+
+	enum vpu_codec_state state;
+	enum vpu_core_type type;
+
+	struct workqueue_struct *workqueue;
+	struct work_struct msg_work;
+	struct kfifo msg_fifo;
+	u8 msg_buffer[VPU_MSG_BUFFER_SIZE];
+
+	struct vpu_buffer stream_buffer;
+	bool use_stream_buffer;
+	struct vpu_buffer act;
+
+	struct list_head cmd_q;
+	void *pending;
+
+	struct vpu_inst_ops *ops;
+	const struct vpu_format *formats;
+	struct vpu_format out_format;
+	struct vpu_format cap_format;
+	u32 min_buffer_cap;
+	u32 min_buffer_out;
+
+	struct v4l2_rect crop;
+	u32 colorspace;
+	u8 ycbcr_enc;
+	u8 quantization;
+	u8 xfer_func;
+	u32 sequence;
+	u32 extra_size;
+
+	u32 flows[16];
+	u32 flow_idx;
+
+	pid_t pid;
+	pid_t tgid;
+	struct dentry *debugfs;
+
+	void *priv;
+};
+
+#define call_vop(inst, op, args...)					\
+	((inst)->ops->op ? (inst)->ops->op(inst, ##args) : 0)		\
+
+enum {
+	VPU_BUF_STATE_IDLE = 0,
+	VPU_BUF_STATE_INUSE,
+	VPU_BUF_STATE_DECODED,
+	VPU_BUF_STATE_READY,
+	VPU_BUF_STATE_SKIP,
+	VPU_BUF_STATE_ERROR
+};
+
+struct vpu_vb2_buffer {
+	struct v4l2_m2m_buffer m2m_buf;
+	dma_addr_t luma;
+	dma_addr_t chroma_u;
+	dma_addr_t chroma_v;
+	unsigned int state;
+	u32 tag;
+};
+
+void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val);
+u32 vpu_readl(struct vpu_dev *vpu, u32 reg);
+
+static inline struct vpu_vb2_buffer *to_vpu_vb2_buffer(struct vb2_v4l2_buffer *vbuf)
+{
+	struct v4l2_m2m_buffer *m2m_buf = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+
+	return container_of(m2m_buf, struct vpu_vb2_buffer, m2m_buf);
+}
+
+static inline const char *vpu_core_type_desc(enum vpu_core_type type)
+{
+	return type == VPU_CORE_TYPE_ENC ? "encoder" : "decoder";
+}
+
+static inline struct vpu_inst *to_inst(struct file *filp)
+{
+	return container_of(filp->private_data, struct vpu_inst, fh);
+}
+
+#define ctrl_to_inst(ctrl)	\
+	container_of((ctrl)->handler, struct vpu_inst, ctrl_handler)
+
+int venc_create_video_device(struct vpu_dev *vpu);
+int vdec_create_video_device(struct vpu_dev *vpu);
+
+struct vpu_inst *vpu_inst_get(struct vpu_inst *inst);
+void vpu_inst_put(struct vpu_inst *inst);
+struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type);
+void vpu_release_core(struct vpu_core *core);
+int vpu_inst_register(struct vpu_inst *inst);
+int vpu_inst_unregister(struct vpu_inst *inst);
+
+int vpu_inst_create_dbgfs_file(struct vpu_inst *inst);
+int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst);
+int vpu_core_create_dbgfs_file(struct vpu_core *core);
+int vpu_core_remove_dbgfs_file(struct vpu_core *core);
+void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_defs.h b/drivers/media/platform/imx/vpu-8q/vpu_defs.h
new file mode 100644
index 000000000000..e8419ca34f92
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_defs.h
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_DEFS_H
+#define _IMX_VPU_DEFS_H
+
+enum MSG_TYPE {
+	INIT_DONE = 1,
+	PRC_BUF_OFFSET,
+	BOOT_ADDRESS,
+	COMMAND,
+	EVENT,
+};
+
+enum {
+	VPU_IRQ_CODE_BOOT_DONE = 0x55,
+	VPU_IRQ_CODE_SNAPSHOT_DONE = 0xa5,
+	VPU_IRQ_CODE_SYNC = 0xaa,
+};
+
+enum {
+	VPU_CMD_ID_NOOP = 0x0,
+	VPU_CMD_ID_CONFIGURE_CODEC,
+	VPU_CMD_ID_START,
+	VPU_CMD_ID_STOP,
+	VPU_CMD_ID_ABORT,
+	VPU_CMD_ID_RST_BUF,
+	VPU_CMD_ID_SNAPSHOT,
+	VPU_CMD_ID_FIRM_RESET,
+	VPU_CMD_ID_UPDATE_PARAMETER,
+	VPU_CMD_ID_FRAME_ENCODE,
+	VPU_CMD_ID_SKIP,
+	VPU_CMD_ID_PARSE_NEXT_SEQ,
+	VPU_CMD_ID_PARSE_NEXT_I,
+	VPU_CMD_ID_PARSE_NEXT_IP,
+	VPU_CMD_ID_PARSE_NEXT_ANY,
+	VPU_CMD_ID_DEC_PIC,
+	VPU_CMD_ID_FS_ALLOC,
+	VPU_CMD_ID_FS_RELEASE,
+	VPU_CMD_ID_TIMESTAMP,
+	VPU_CMD_ID_DEBUG
+};
+
+enum {
+	VPU_MSG_ID_NOOP = 0x100,
+	VPU_MSG_ID_RESET_DONE,
+	VPU_MSG_ID_START_DONE,
+	VPU_MSG_ID_STOP_DONE,
+	VPU_MSG_ID_ABORT_DONE,
+	VPU_MSG_ID_BUF_RST,
+	VPU_MSG_ID_MEM_REQUEST,
+	VPU_MSG_ID_PARAM_UPD_DONE,
+	VPU_MSG_ID_FRAME_INPUT_DONE,
+	VPU_MSG_ID_ENC_DONE,
+	VPU_MSG_ID_DEC_DONE,
+	VPU_MSG_ID_FRAME_REQ,
+	VPU_MSG_ID_FRAME_RELEASE,
+	VPU_MSG_ID_SEQ_HDR_FOUND,
+	VPU_MSG_ID_RES_CHANGE,
+	VPU_MSG_ID_PIC_HDR_FOUND,
+	VPU_MSG_ID_PIC_DECODED,
+	VPU_MSG_ID_PIC_EOS,
+	VPU_MSG_ID_FIFO_LOW,
+	VPU_MSG_ID_FIFO_HIGH,
+	VPU_MSG_ID_FIFO_EMPTY,
+	VPU_MSG_ID_FIFO_FULL,
+	VPU_MSG_ID_BS_ERROR,
+	VPU_MSG_ID_UNSUPPORTED,
+	VPU_MSG_ID_TIMESTAMP_INFO,
+
+	VPU_MSG_ID_FIRMWARE_XCPT,
+};
+
+enum VPU_ENC_MEMORY_RESOURSE {
+	MEM_RES_ENC,
+	MEM_RES_REF,
+	MEM_RES_ACT
+};
+
+enum VPU_DEC_MEMORY_RESOURCE {
+	MEM_RES_FRAME,
+	MEM_RES_MBI,
+	MEM_RES_DCP
+};
+
+enum VPU_SCODE_TYPE {
+	SCODE_PADDING_EOS = 1,
+	SCODE_PADDING_BUFFLUSH = 2,
+	SCODE_PADDING_ABORT = 3,
+	SCODE_SEQUENCE = 0x31,
+	SCODE_PICTURE = 0x32,
+	SCODE_SLICE = 0x33
+};
+
+struct vpu_pkt_mem_req_data {
+	u32 enc_frame_size;
+	u32 enc_frame_num;
+	u32 ref_frame_size;
+	u32 ref_frame_num;
+	u32 act_buf_size;
+	u32 act_buf_num;
+};
+
+struct vpu_enc_pic_info {
+	u32 frame_id;
+	u32 pic_type;
+	u32 skipped_frame;
+	u32 error_flag;
+	u32 psnr;
+	u32 frame_size;
+	u32 wptr;
+	u32 crc;
+	s64 timestamp;
+};
+
+struct vpu_dec_codec_info {
+	u32 pixfmt;
+	u32 num_ref_frms;
+	u32 num_dpb_frms;
+	u32 num_dfe_area;
+	u32 color_primaries;
+	u32 transfer_chars;
+	u32 matrix_coeffs;
+	u32 full_range;
+	u32 vui_present;
+	u32 progressive;
+	u32 width;
+	u32 height;
+	u32 decoded_width;
+	u32 decoded_height;
+	u32 frame_rate;
+	u32 dsp_asp_ratio;
+	u32 level_idc;
+	u32 bit_depth_luma;
+	u32 bit_depth_chroma;
+	u32 chroma_fmt;
+	u32 mvc_num_views;
+	u32 offset_x;
+	u32 offset_y;
+	u32 tag;
+	u32 sizeimage[VIDEO_MAX_PLANES];
+	u32 bytesperline[VIDEO_MAX_PLANES];
+	u32 mbi_size;
+	u32 dcp_size;
+	u32 stride;
+};
+
+struct vpu_dec_pic_info {
+	u32 id;
+	u32 luma;
+	u32 start;
+	u32 end;
+	u32 pic_size;
+	u32 stride;
+	u32 skipped;
+	s64 timestamp;
+	u32 consumed_count;
+};
+
+struct vpu_fs_info {
+	u32 id;
+	u32 type;
+	u32 tag;
+	u32 luma_addr;
+	u32 luma_size;
+	u32 chroma_addr;
+	u32 chromau_size;
+	u32 chromav_addr;
+	u32 chromav_size;
+	u32 bytesperline;
+	u32 not_displayed;
+};
+
+struct vpu_ts_info {
+	s64 timestamp;
+	u32 size;
+};
+
+#define BITRATE_STEP		(1024)
+#define BITRATE_MIN		(16 * BITRATE_STEP)
+#define BITRATE_MAX		(240 * 1024 * BITRATE_STEP)
+#define BITRATE_DEFAULT		(2 * 1024 * BITRATE_STEP)
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c b/drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c
new file mode 100644
index 000000000000..540b54b8b876
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include "vpu.h"
+#include "vpu_imx8q.h"
+
+int vpu_imx8q_setup_dec(struct vpu_dev *vpu)
+{
+	const off_t offset = DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL;
+
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET, 0x1f);
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_RESET_SET, 0xffffffff);
+
+	return 0;
+}
+
+int vpu_imx8q_setup_enc(struct vpu_dev *vpu)
+{
+	return 0;
+}
+
+int vpu_imx8q_setup(struct vpu_dev *vpu)
+{
+	const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+	u32 read_data;
+
+	read_data = vpu_readl(vpu, offset + 0x108);
+
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET, 0x1);
+	vpu_writel(vpu, offset + 0x190, 0xffffffff);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_XMEM_RESET_SET, 0xffffffff);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET, 0xE);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_CACHE_RESET_SET, 0x7);
+	vpu_writel(vpu, XMEM_CONTROL, 0x102);
+
+	read_data = vpu_readl(vpu, offset + 0x108);
+
+	return 0;
+}
+
+static int vpu_imx8q_reset_enc(struct vpu_dev *vpu)
+{
+	return 0;
+}
+
+static int vpu_imx8q_reset_dec(struct vpu_dev *vpu)
+{
+	const off_t offset = DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL;
+
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_RESET_CLR, 0xffffffff);
+
+	return 0;
+}
+
+int vpu_imx8q_reset(struct vpu_dev *vpu)
+{
+	const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_CACHE_RESET_CLR, 0x7);
+	vpu_imx8q_reset_enc(vpu);
+	vpu_imx8q_reset_dec(vpu);
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_drv.c b/drivers/media/platform/imx/vpu-8q/vpu_drv.c
new file mode 100644
index 000000000000..c9c7168b99e4
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_drv.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/dma-map-ops.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <linux/of_reserved_mem.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/debugfs.h>
+#include "vpu.h"
+#include "vpu_imx8q.h"
+
+void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val)
+{
+	writel(val, vpu->base + reg);
+}
+
+u32 vpu_readl(struct vpu_dev *vpu, u32 reg)
+{
+	return readl(vpu->base + reg);
+}
+
+static void vpu_dev_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_vpu) == 1 && vpu->res->setup)
+		vpu->res->setup(vpu);
+}
+
+static void vpu_dev_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_vpu);
+}
+
+static void vpu_enc_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_enc) == 1 && vpu->res->setup_encoder)
+		vpu->res->setup_encoder(vpu);
+}
+
+static void vpu_enc_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_enc);
+}
+
+static void vpu_dec_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_dec) == 1 && vpu->res->setup_decoder)
+		vpu->res->setup_decoder(vpu);
+}
+
+static void vpu_dec_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_dec);
+}
+
+static int vpu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_dev *vpu;
+	struct resource *r;
+	int ret;
+
+	pr_info("vpu probe %s\n", pdev->dev.of_node->name);
+	vpu = devm_kzalloc(dev, sizeof(*vpu), GFP_KERNEL);
+	if (!vpu)
+		return -ENOMEM;
+
+	vpu->pdev = pdev;
+	vpu->dev = dev;
+	mutex_init(&vpu->lock);
+	INIT_LIST_HEAD(&vpu->cores);
+	platform_set_drvdata(pdev, vpu);
+	atomic_set(&vpu->ref_vpu, 0);
+	atomic_set(&vpu->ref_enc, 0);
+	atomic_set(&vpu->ref_dec, 0);
+	vpu->get_vpu = vpu_dev_get;
+	vpu->put_vpu = vpu_dev_put;
+	vpu->get_enc = vpu_enc_get;
+	vpu->put_enc = vpu_enc_put;
+	vpu->get_dec = vpu_dec_get;
+	vpu->put_dec = vpu_dec_put;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	vpu->base = devm_ioremap_resource(dev, r);
+	if (IS_ERR(vpu->base))
+		return PTR_ERR(vpu->base);
+
+	vpu->res = of_device_get_match_data(dev);
+	if (!vpu->res)
+		return -ENODEV;
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret)
+		goto err_runtime_disable;
+
+	pm_runtime_put_sync(dev);
+
+	ret = v4l2_device_register(dev, &vpu->v4l2_dev);
+	if (ret)
+		goto err_vpu_deinit;
+
+	vpu->debugfs = debugfs_create_dir("vpu", NULL);
+
+	of_platform_populate(dev->of_node, NULL, NULL, dev);
+
+	return 0;
+
+err_vpu_deinit:
+err_runtime_disable:
+	pm_runtime_set_suspended(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int vpu_remove(struct platform_device *pdev)
+{
+	struct vpu_dev *vpu = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	ret = pm_runtime_get_sync(dev);
+	WARN_ON(ret < 0);
+
+	debugfs_remove_recursive(vpu->debugfs);
+	vpu->debugfs = NULL;
+
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+	v4l2_device_unregister(&vpu->v4l2_dev);
+	mutex_destroy(&vpu->lock);
+
+	return 0;
+}
+
+static int __maybe_unused vpu_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops vpu_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
+};
+
+struct vpu_resources imx8qxp_res = {
+	.plat_type = IMX8QXP,
+	.mreg_base = 0x40000000,
+	.setup = vpu_imx8q_setup,
+	.setup_encoder = vpu_imx8q_setup_enc,
+	.setup_decoder = vpu_imx8q_setup_dec,
+	.reset = vpu_imx8q_reset
+};
+
+struct vpu_resources imx8qm_res = {
+	.plat_type = IMX8QM,
+	.mreg_base = 0x40000000,
+	.setup = vpu_imx8q_setup,
+	.setup_encoder = vpu_imx8q_setup_enc,
+	.setup_decoder = vpu_imx8q_setup_dec,
+	.reset = vpu_imx8q_reset
+};
+
+static const struct of_device_id vpu_dt_match[] = {
+	{ .compatible = "nxp,imx8qxp-vpu", .data = &imx8qxp_res },
+	{ .compatible = "nxp,imx8qm-vpu", .data = &imx8qm_res },
+	{}
+};
+MODULE_DEVICE_TABLE(of, vpu_dt_match);
+
+static struct platform_driver imx_vpu_driver = {
+	.probe = vpu_probe,
+	.remove = vpu_remove,
+	.driver = {
+		.name = "imx-vpu",
+		.of_match_table = vpu_dt_match,
+		.pm = &vpu_pm_ops,
+	},
+};
+module_platform_driver(imx_vpu_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/imx_vpu.h b/include/linux/imx_vpu.h
new file mode 100644
index 000000000000..9d6fe1366fbc
--- /dev/null
+++ b/include/linux/imx_vpu.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef __LINUX_IMX_VPU_H
+#define __LINUX_IMX_VPU_H
+
+#include <uapi/linux/imx_vpu.h>
+
+#endif
diff --git a/include/uapi/linux/imx_vpu.h b/include/uapi/linux/imx_vpu.h
new file mode 100644
index 000000000000..d3af36750292
--- /dev/null
+++ b/include/uapi/linux/imx_vpu.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _UAPI__LINUX_IMX_VPU_H
+#define _UAPI__LINUX_IMX_VPU_H
+
+#include <linux/videodev2.h>
+
+/*imx v4l2 event*/
+//error happened in dec/enc
+#define V4L2_EVENT_CODEC_ERROR		(V4L2_EVENT_PRIVATE_START + 1)
+//frame loss in dec/enc
+#define V4L2_EVENT_SKIP			(V4L2_EVENT_PRIVATE_START + 2)
+
+#endif	//#ifndef _UAPI__LINUX_IMX_VPU_H
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:42:59 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:42:59 +0800
Subject: [PATCH v6 03/14] media:Add v4l2 buf flag codec data.
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <be578f1a32a47d24c03b9640c6a924b2a6507708.1628671163.git.ming.qian@nxp.com>

In some decoing scenarios, application may queue a buffer
that only contains codec config data, and the driver needs to
know whether is it a frame or not.
So we add a buf flag to tell this case.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 Documentation/userspace-api/media/v4l/buffer.rst | 7 +++++++
 include/uapi/linux/videodev2.h                   | 1 +
 2 files changed, 8 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/buffer.rst b/Documentation/userspace-api/media/v4l/buffer.rst
index e991ba73d873..11013bcf8a41 100644
--- a/Documentation/userspace-api/media/v4l/buffer.rst
+++ b/Documentation/userspace-api/media/v4l/buffer.rst
@@ -607,6 +607,13 @@ Buffer Flags
 	the format. Any subsequent call to the
 	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
 	but return an ``EPIPE`` error code.
+    * .. _`V4L2-BUF-FLAG-CODECCONFIG`:
+
+      - ``V4L2_BUF_FLAG_CODECCONFIG``
+      - 0x00200000
+      - The buffer only contains codec config data, eg. sps and pps.
+    Applications can set this bit when ``type`` refers to an output
+    stream, this flag is usually used by v4l2 decoder.
     * .. _`V4L2-BUF-FLAG-REQUEST-FD`:
 
       - ``V4L2_BUF_FLAG_REQUEST_FD``
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 167c0e40ec06..5bb0682b4a23 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1119,6 +1119,7 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv)
 #define V4L2_BUF_FLAG_TSTAMP_SRC_SOE		0x00010000
 /* mem2mem encoder/decoder */
 #define V4L2_BUF_FLAG_LAST			0x00100000
+#define V4L2_BUF_FLAG_CODECCONFIG		0x00200000
 /* request_fd is valid */
 #define V4L2_BUF_FLAG_REQUEST_FD		0x00800000
 
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:01 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:01 +0800
Subject: [PATCH v6 05/14] media: imx: imx8q: add vpu core driver
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <db77114ce57cf6f9035720e78a1938e7b2b7d33c.1628671163.git.ming.qian@nxp.com>

The vpu support encoder and decoder.
And it need mu core to handle it.
Each core will run either encoder or decoder firmware.

This driver is for support the vpu core.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vpu_codec.h |  68 ++
 drivers/media/platform/imx/vpu-8q/vpu_core.c  | 910 ++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_core.h  |  16 +
 drivers/media/platform/imx/vpu-8q/vpu_dbg.c   | 496 ++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_log.h   |  44 +
 drivers/media/platform/imx/vpu-8q/vpu_rpc.c   | 257 +++++
 drivers/media/platform/imx/vpu-8q/vpu_rpc.h   | 463 +++++++++
 7 files changed, 2254 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_codec.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_core.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_core.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_dbg.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_log.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_rpc.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_rpc.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_codec.h b/drivers/media/platform/imx/vpu-8q/vpu_codec.h
new file mode 100644
index 000000000000..80fc5a12050e
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_codec.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_CODEC_H
+#define _IMX_VPU_CODEC_H
+
+struct vpu_encode_params {
+	u32 input_format;
+	u32 codec_format;
+	u32 profile;
+	u32 tier;
+	u32 level;
+	u32 frame_rate_num;
+	u32 frame_rate_den;
+	u32 src_stride;
+	u32 src_width;
+	u32 src_height;
+	struct v4l2_rect crop;
+	u32 out_width;
+	u32 out_height;
+
+	u32 gop_length;
+	u32 bframes;
+
+	u32 rc_mode;
+	u32 bitrate;
+	u32 bitrate_min;
+	u32 bitrate_max;
+
+	u32 i_frame_qp;
+	u32 p_frame_qp;
+	u32 b_frame_qp;
+	u32 qp_min;
+	u32 qp_max;
+	u32 qp_min_i;
+	u32 qp_max_i;
+
+	struct {
+		u32 enable;
+		u32 idc;
+		u32 width;
+		u32 height;
+	} sar;
+
+	struct {
+		u32 primaries;
+		u32 transfer;
+		u32 matrix;
+		u32 full_range;
+	} color;
+};
+
+struct vpu_decode_params {
+	u32 codec_format;
+	u32 output_format;
+	u32 b_dis_reorder;
+	u32 b_non_frame;
+	u32 frame_count;
+	u32 end_flag;
+	struct {
+		u32 base;
+		u32 size;
+	} udata;
+};
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_core.c b/drivers/media/platform/imx/vpu-8q/vpu_core.c
new file mode 100644
index 000000000000..9ed14a6a034d
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_core.c
@@ -0,0 +1,910 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"CORE"
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_domain.h>
+#include <linux/firmware.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_mbox.h"
+#include "vpu_msgs.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+#include "vpu_cmds.h"
+
+unsigned int vpu_dbg_level = LVL_ERR | LVL_WARN | LVL_INFO;
+module_param(vpu_dbg_level, uint, 0644);
+
+void csr_writel(struct vpu_core *core, u32 reg, u32 val)
+{
+	writel(val, core->base + reg);
+}
+
+u32 csr_readl(struct vpu_core *core, u32 reg)
+{
+	return readl(core->base + reg);
+}
+
+static int vpu_core_load_firmware(struct vpu_core *core)
+{
+	const struct firmware *pfw = NULL;
+	int ret = 0;
+
+	WARN_ON(!core || !core->res || !core->res->fwname);
+	if (!core->fw.virt) {
+		core_err(core, "firmware buffer is not ready\n");
+		return -EINVAL;
+	}
+
+	ret = request_firmware(&pfw, core->res->fwname, core->dev);
+	core_dbg(core, LVL_DEBUG, "request_firmware %s : %d\n", core->res->fwname, ret);
+	if (ret) {
+		core_err(core, "request firmware %s failed, ret = %d\n",
+				core->res->fwname, ret);
+		return ret;
+	}
+
+	if (core->fw.length < pfw->size) {
+		core_err(core, "firmware buffer size want %ld, but %d\n",
+				pfw->size, core->fw.length);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	memset_io(core->fw.virt, 0, core->fw.length);
+	memcpy(core->fw.virt, pfw->data, pfw->size);
+	core->fw.bytesused = pfw->size;
+	ret = vpu_iface_on_firmware_loaded(core);
+exit:
+	release_firmware(pfw);
+	pfw = NULL;
+
+	return ret;
+}
+
+static int vpu_core_wait_boot_done(struct vpu_core *core)
+{
+	int ret;
+	u32 fw_version;
+
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		core_err(core, "boot timeout\n");
+		return -EINVAL;
+	}
+
+	fw_version = vpu_iface_get_version(core);
+	core_dbg(core, LVL_WARN, "firmware version : %d.%d.%d\n",
+			(fw_version >> 16) & 0xff,
+			(fw_version >> 8) & 0xff,
+			fw_version & 0xff);
+	core->supported_instance_count = vpu_iface_get_max_instance_count(core);
+	if (core->res->act_size) {
+		u32 count = core->act.length / core->res->act_size;
+
+		core->supported_instance_count = min(core->supported_instance_count, count);
+	}
+	core->fw_version = fw_version;
+
+	return 0;
+}
+
+static int vpu_core_boot(struct vpu_core *core, bool load)
+{
+	int ret;
+
+	WARN_ON(!core);
+
+	if (!core->res->standalone)
+		return 0;
+
+	core_dbg(core, LVL_WARN, "boot\n");
+	reinit_completion(&core->cmp);
+	if (load) {
+		ret = vpu_core_load_firmware(core);
+		if (ret)
+			return ret;
+	}
+
+	vpu_iface_boot_core(core);
+	return vpu_core_wait_boot_done(core);
+}
+
+static int vpu_core_shutdown(struct vpu_core *core)
+{
+	if (!core->res->standalone)
+		return 0;
+	return vpu_iface_shutdown_core(core);
+}
+
+static int vpu_core_restore(struct vpu_core *core)
+{
+	if (!core->res->standalone)
+		return 0;
+	return vpu_iface_restore_core(core);
+}
+
+static int __vpu_alloc_dma(struct device *dev, struct vpu_buffer *buf)
+{
+	gfp_t gfp = GFP_KERNEL | GFP_DMA32;
+
+	WARN_ON(!dev || !buf);
+
+	if (!buf->length)
+		return 0;
+
+	buf->virt = dma_alloc_coherent(dev, buf->length, &buf->phys, gfp);
+	if (!buf->virt)
+		return -ENOMEM;
+
+	buf->dev = dev;
+
+	return 0;
+}
+
+void vpu_free_dma(struct vpu_buffer *buf)
+{
+	WARN_ON(!buf);
+
+	if (!buf->virt || !buf->dev)
+		return;
+
+	dma_free_coherent(buf->dev, buf->length, buf->virt, buf->phys);
+	buf->virt = NULL;
+	buf->phys = 0;
+	buf->length = 0;
+	buf->bytesused = 0;
+	buf->dev = NULL;
+}
+
+int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf)
+{
+	WARN_ON(!core || !buf);
+
+	return __vpu_alloc_dma(core->dev, buf);
+}
+
+struct vpu_core *vpu_core_find_next_by_type(struct vpu_dev *vpu, u32 type)
+{
+	struct vpu_core *c;
+
+	WARN_ON(!vpu);
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		if (c->type == type)
+			return c;
+	}
+
+	return NULL;
+}
+
+int vpu_core_check_fmt(struct vpu_core *core, u32 pixelfmt)
+{
+	if (!core)
+		return -EINVAL;
+
+	if (vpu_iface_check_format(core, pixelfmt))
+		return 0;
+
+	return -EINVAL;
+}
+
+static void vpu_core_check_hang(struct vpu_core *core)
+{
+	if (core->hang_mask)
+		core->state = VPU_CORE_HANG;
+}
+
+struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 type)
+{
+	struct vpu_core *core = NULL;
+	int request_count = INT_MAX;
+	struct vpu_core *c;
+
+	WARN_ON(!vpu);
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		core_dbg(c, LVL_DEBUG, "instance_mask = 0x%lx, state = %d\n",
+				c->instance_mask,
+				c->state);
+		if (c->type != type)
+			continue;
+		if (c->state == VPU_CORE_DEINIT) {
+			core = c;
+			break;
+		}
+		vpu_core_check_hang(c);
+		if (c->state != VPU_CORE_ACTIVE)
+			continue;
+		if (c->request_count < request_count) {
+			request_count = c->request_count;
+			core = c;
+		}
+		if (!request_count)
+			break;
+	}
+
+	return core;
+}
+
+static bool vpu_core_is_exist(struct vpu_dev *vpu, struct vpu_core *core)
+{
+	struct vpu_core *c;
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		if (c == core)
+			return true;
+	}
+
+	return false;
+}
+
+static void vpu_core_get_vpu(struct vpu_core *core)
+{
+	core->vpu->get_vpu(core->vpu);
+	if (core->type == VPU_CORE_TYPE_ENC)
+		core->vpu->get_enc(core->vpu);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		core->vpu->get_dec(core->vpu);
+}
+
+int vpu_core_register(struct device *dev, struct vpu_core *core)
+{
+	struct vpu_dev *vpu = dev_get_drvdata(dev);
+	int ret = 0;
+
+	core_dbg(core, LVL_DEBUG, "register core\n");
+	if (vpu_core_is_exist(vpu, core))
+		return 0;
+
+	core->workqueue = alloc_workqueue("vpu", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (!core->workqueue) {
+		core_err(core, "fail to alloc workqueue\n");
+		return -ENOMEM;
+	}
+	INIT_WORK(&core->msg_work, vpu_msg_run_work);
+	INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work);
+	core->msg_buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE);
+	core->msg_buffer = vzalloc(core->msg_buffer_size);
+	if (!core->msg_buffer) {
+		core_err(core, "failed allocate buffer for fifo\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+	ret = kfifo_init(&core->msg_fifo, core->msg_buffer, core->msg_buffer_size);
+	if (ret) {
+		core_err(core, "failed init kfifo\n");
+		goto error;
+	}
+
+	list_add_tail(&core->list, &vpu->cores);
+
+	vpu_core_get_vpu(core);
+
+	if (core->type == VPU_CORE_TYPE_ENC && !vpu->vdev_enc)
+		venc_create_video_device(vpu);
+	if (core->type == VPU_CORE_TYPE_DEC && !vpu->vdev_dec)
+		vdec_create_video_device(vpu);
+
+	return 0;
+error:
+	if (core->msg_buffer) {
+		vfree(core->msg_buffer);
+		core->msg_buffer = NULL;
+	}
+	if (core->workqueue) {
+		destroy_workqueue(core->workqueue);
+		core->workqueue = NULL;
+	}
+	return ret;
+}
+
+static void vpu_core_put_vpu(struct vpu_core *core)
+{
+	if (core->type == VPU_CORE_TYPE_ENC)
+		core->vpu->put_enc(core->vpu);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		core->vpu->put_dec(core->vpu);
+	core->vpu->put_vpu(core->vpu);
+}
+
+int vpu_core_unregister(struct device *dev, struct vpu_core *core)
+{
+	struct vpu_dev *vpu = dev_get_drvdata(dev);
+
+	list_del_init(&core->list);
+
+	vpu_core_put_vpu(core);
+	core->vpu = NULL;
+	vfree(core->msg_buffer);
+	core->msg_buffer = NULL;
+
+	if (core->workqueue) {
+		cancel_work_sync(&core->msg_work);
+		cancel_delayed_work_sync(&core->msg_delayed_work);
+		destroy_workqueue(core->workqueue);
+		core->workqueue = NULL;
+	}
+
+	if (vpu_core_find_next_by_type(vpu, core->type))
+		return 0;
+
+	if (core->type == VPU_CORE_TYPE_ENC)
+		video_unregister_device(vpu->vdev_enc);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		video_unregister_device(vpu->vdev_dec);
+
+	return 0;
+}
+
+int vpu_core_acquire_instance(struct vpu_core *core)
+{
+	int id;
+
+	WARN_ON(!core);
+
+	id = ffz(core->instance_mask);
+	if (id >= core->supported_instance_count)
+		return -EINVAL;
+
+	set_bit(id, &core->instance_mask);
+
+	return id;
+}
+
+void vpu_core_release_instance(struct vpu_core *core, int id)
+{
+	WARN_ON(!core);
+
+	if (id < 0 || id >= core->supported_instance_count)
+		return;
+
+	clear_bit(id, &core->instance_mask);
+}
+
+struct vpu_inst *vpu_inst_get(struct vpu_inst *inst)
+{
+	if (!inst)
+		return NULL;
+
+	atomic_inc(&inst->ref_count);
+
+	return inst;
+}
+
+void vpu_inst_put(struct vpu_inst *inst)
+{
+	if (!inst)
+		return;
+	if (atomic_dec_and_test(&inst->ref_count)) {
+		if (inst->release)
+			inst->release(inst);
+	}
+}
+
+struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type)
+{
+	struct vpu_core *core = NULL;
+	int ret;
+
+	mutex_lock(&vpu->lock);
+
+	core = vpu_core_find_proper_by_type(vpu, type);
+	if (!core)
+		goto exit;
+
+	core_dbg(core, LVL_DEBUG, "is found\n");
+	mutex_lock(&core->lock);
+	pm_runtime_get_sync(core->dev);
+
+	if (core->state == VPU_CORE_DEINIT) {
+		ret = vpu_core_boot(core, true);
+		if (ret) {
+			pm_runtime_put_sync(core->dev);
+			mutex_unlock(&core->lock);
+			core = NULL;
+			goto exit;
+		}
+		core->state = VPU_CORE_ACTIVE;
+	}
+
+	core->request_count++;
+
+	mutex_unlock(&core->lock);
+exit:
+	mutex_unlock(&vpu->lock);
+
+	return core;
+}
+
+void vpu_release_core(struct vpu_core *core)
+{
+	if (!core)
+		return;
+
+	mutex_lock(&core->lock);
+	pm_runtime_put_sync(core->dev);
+	if (core->request_count)
+		core->request_count--;
+	mutex_unlock(&core->lock);
+}
+
+int vpu_inst_register(struct vpu_inst *inst)
+{
+	struct vpu_core *core;
+	int ret = 0;
+
+	WARN_ON(!inst || !inst->core);
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+	if (inst->id >= 0 && inst->id < core->supported_instance_count)
+		goto exit;
+
+	ret = vpu_core_acquire_instance(core);
+	if (ret < 0)
+		goto exit;
+
+	inst->id = ret;
+	list_add_tail(&inst->list, &core->instances);
+	ret = 0;
+	inst->pid = current->pid;
+	inst->tgid = current->tgid;
+	if (core->res->act_size) {
+		inst->act.phys = core->act.phys + core->res->act_size * inst->id;
+		inst->act.virt = core->act.virt + core->res->act_size * inst->id;
+		inst->act.length = core->res->act_size;
+	}
+	vpu_inst_create_dbgfs_file(inst);
+exit:
+	mutex_unlock(&core->lock);
+
+	if (ret)
+		core_err(core, "register instance fail\n");
+	return ret;
+}
+
+int vpu_inst_unregister(struct vpu_inst *inst)
+{
+	struct vpu_core *core;
+
+	WARN_ON(!inst);
+
+	core = inst->core;
+
+	vpu_clear_request(inst);
+	mutex_lock(&core->lock);
+	if (inst->id >= 0 && inst->id < core->supported_instance_count) {
+		vpu_inst_remove_dbgfs_file(inst);
+		list_del_init(&inst->list);
+		vpu_core_release_instance(core, inst->id);
+		inst->id = VPU_INST_NULL_ID;
+	}
+	vpu_core_check_hang(core);
+	if (core->state == VPU_CORE_HANG && !core->instance_mask) {
+		core_dbg(core, LVL_WARN, "reset hang core\n");
+		if (!vpu_core_sw_reset(core)) {
+			core->state = VPU_CORE_ACTIVE;
+			core->hang_mask = 0;
+		}
+	}
+	mutex_unlock(&core->lock);
+
+	return 0;
+}
+
+struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index)
+{
+	struct vpu_inst *inst = NULL;
+	struct vpu_inst *tmp;
+
+	mutex_lock(&core->lock);
+	if (!test_bit(index, &core->instance_mask))
+		goto exit;
+	list_for_each_entry(tmp, &core->instances, list) {
+		if (tmp->id == index) {
+			inst = vpu_inst_get(tmp);
+			break;
+		}
+	}
+exit:
+	mutex_unlock(&core->lock);
+
+	return inst;
+}
+
+static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np)
+{
+	struct device_node *node;
+	struct resource res;
+
+	if (of_count_phandle_with_args(np, "memory-region", NULL) < 2) {
+		core_err(core, "need 2 memory-region for boot and rpc\n");
+		return -ENODEV;
+	}
+
+	node = of_parse_phandle(np, "memory-region", 0);
+	if (!node) {
+		core_err(core, "boot-region of_parse_phandle error\n");
+		return -ENODEV;
+	}
+	if (of_address_to_resource(node, 0, &res)) {
+		core_err(core, "boot-region of_address_to_resource error\n");
+		return -EINVAL;
+	}
+	core->fw.phys = res.start;
+	core->fw.length = resource_size(&res);
+	core_dbg(core, LVL_INFO, "boot-region : <0x%llx, 0x%llx>\n",
+			res.start, resource_size(&res));
+
+	node = of_parse_phandle(np, "memory-region", 1);
+	if (!node) {
+		core_err(core, "rpc-region of_parse_phandle error\n");
+		return -ENODEV;
+	}
+	if (of_address_to_resource(node, 0, &res)) {
+		core_err(core, "rpc-region of_address_to_resource error\n");
+		return -EINVAL;
+	}
+	core->rpc.phys = res.start;
+	core->rpc.length = resource_size(&res);
+	core_dbg(core, LVL_DEBUG, "rpc-region : <0x%llx, 0x%llx>\n",
+			res.start, resource_size(&res));
+
+	if (core->rpc.length < core->res->rpc_size + core->res->fwlog_size) {
+		core_err(core, "the rpc-region <0x%llx, 0x%llx> is not enough\n",
+				res.start, resource_size(&res));
+		return -EINVAL;
+	}
+
+	core->fw.virt = ioremap_wc(core->fw.phys, core->fw.length);
+	core->rpc.virt = ioremap_wc(core->rpc.phys, core->rpc.length);
+	memset_io(core->rpc.virt, 0, core->rpc.length);
+
+	if (vpu_iface_check_memory_region(core,
+				core->rpc.phys,
+				core->rpc.length) != VPU_CORE_MEMORY_UNCACHED) {
+		core_err(core, "rpc region<0x%llx, 0x%x> isn't uncached\n",
+				core->rpc.phys,
+				core->rpc.length);
+		return -EINVAL;
+	}
+
+	core->log.phys = core->rpc.phys + core->res->rpc_size;
+	core->log.virt = core->rpc.virt + core->res->rpc_size;
+	core->log.length = core->res->fwlog_size;
+	core->act.phys = core->log.phys + core->log.length;
+	core->act.virt = core->log.virt + core->log.length;
+	core->act.length = core->rpc.length - core->res->rpc_size - core->log.length;
+	core->rpc.length = core->res->rpc_size;
+
+	return 0;
+}
+
+static int vpu_core_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_core *core;
+	struct vpu_dev *vpu = dev_get_drvdata(dev->parent);
+	struct vpu_shared_addr *iface;
+	u32 iface_data_size;
+	struct resource *r;
+	int ret;
+
+	vpu_dbg(LVL_WARN, "core %s probe\n", pdev->dev.of_node->name);
+	if (!vpu)
+		return -EINVAL;
+	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+
+	core->pdev = pdev;
+	core->dev = dev;
+	platform_set_drvdata(pdev, core);
+	core->vpu = vpu;
+	INIT_LIST_HEAD(&core->instances);
+	mutex_init(&core->lock);
+	mutex_init(&core->cmd_lock);
+	init_completion(&core->cmp);
+	init_waitqueue_head(&core->ack_wq);
+	core->state = VPU_CORE_DEINIT;
+
+	core->res = of_device_get_match_data(dev);
+	if (!core->res)
+		return -ENODEV;
+
+	core->type = core->res->type;
+	core->id = of_alias_get_id(dev->of_node, "vpu_core");
+	if (core->id < 0) {
+		vpu_err("can't get vpu core id\n");
+		return core->id;
+	}
+	ret = vpu_core_parse_dt(core, dev->of_node);
+	if (ret)
+		return ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		core_err(core, "fail to get core reg\n");
+		return -EINVAL;
+	}
+	core->base = devm_ioremap_resource(dev, r);
+	if (IS_ERR(core->base))
+		return PTR_ERR(core->base);
+	core_dbg(core, LVL_WARN, "reg : <0x%llx, 0x%llx>\n", r->start, resource_size(r));
+
+	if (!vpu_iface_check_codec(core)) {
+		core_err(core, "is not supported\n");
+		return -EINVAL;
+	}
+
+	ret = vpu_mbox_init(core);
+	if (ret)
+		return ret;
+
+	iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL);
+	if (!iface)
+		return -ENOMEM;
+
+	iface_data_size = vpu_iface_get_data_size(core);
+	if (iface_data_size) {
+		iface->priv = devm_kzalloc(dev, iface_data_size, GFP_KERNEL);
+		if (!iface->priv)
+			return -ENOMEM;
+	}
+
+	ret = vpu_iface_init(core, iface, &core->rpc, core->fw.phys);
+	if (ret) {
+		core_err(core, "init iface fail, ret = %d\n", ret);
+		return ret;
+	}
+
+	vpu_iface_config_system(core, vpu->res->mreg_base, vpu->base);
+	vpu_iface_set_log_buf(core, &core->log);
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret) {
+		pm_runtime_put_noidle(dev);
+		pm_runtime_set_suspended(dev);
+		goto err_runtime_disable;
+	}
+
+	if (vpu_iface_get_power_state(core))
+		ret = vpu_core_restore(core);
+	if (ret)
+		goto err_core_boot;
+
+	ret = vpu_core_register(dev->parent, core);
+	if (ret)
+		goto err_core_register;
+	core->parent = dev->parent;
+
+	pm_runtime_put_sync(dev);
+	vpu_core_create_dbgfs_file(core);
+
+	return 0;
+
+err_core_register:
+	vpu_core_shutdown(core);
+err_core_boot:
+	pm_runtime_put_sync(dev);
+err_runtime_disable:
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int vpu_core_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_core *core = platform_get_drvdata(pdev);
+	int ret;
+
+	vpu_core_remove_dbgfs_file(core);
+	ret = pm_runtime_get_sync(dev);
+	WARN_ON(ret < 0);
+
+	vpu_core_shutdown(core);
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+	vpu_core_unregister(core->parent, core);
+	iounmap(core->fw.virt);
+	iounmap(core->rpc.virt);
+	mutex_destroy(&core->lock);
+	mutex_destroy(&core->cmd_lock);
+
+	return 0;
+}
+
+static int __maybe_unused vpu_core_runtime_resume(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+
+	return vpu_mbox_request(core);
+}
+
+static int __maybe_unused vpu_core_runtime_suspend(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+
+	vpu_mbox_free(core);
+	return 0;
+}
+
+static void vpu_core_cancel_work(struct vpu_core *core)
+{
+	struct vpu_inst *inst = NULL;
+
+	cancel_work_sync(&core->msg_work);
+	cancel_delayed_work_sync(&core->msg_delayed_work);
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list)
+		cancel_work_sync(&inst->msg_work);
+	mutex_unlock(&core->lock);
+}
+
+static void vpu_core_resume_work(struct vpu_core *core)
+{
+	struct vpu_inst *inst = NULL;
+	unsigned long delay = msecs_to_jiffies(10);
+
+	queue_work(core->workqueue, &core->msg_work);
+	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list)
+		queue_work(inst->workqueue, &inst->msg_work);
+	mutex_unlock(&core->lock);
+}
+
+static int __maybe_unused vpu_core_resume(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (!core->res->standalone)
+		return 0;
+
+	mutex_lock(&core->lock);
+	pm_runtime_get_sync(dev);
+	vpu_core_get_vpu(core);
+	if (core->state != VPU_CORE_SNAPSHOT)
+		goto exit;
+
+	if (!vpu_iface_get_power_state(core)) {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_boot(core, false);
+			if (ret) {
+				core_err(core, "%s boot fail\n", __func__);
+				core->state = VPU_CORE_DEINIT;
+				goto exit;
+			}
+			core->state = VPU_CORE_ACTIVE;
+		} else {
+			core->state = VPU_CORE_DEINIT;
+		}
+	} else {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_sw_reset(core);
+			if (ret) {
+				core_err(core, "%s sw_reset fail\n", __func__);
+				core->state = VPU_CORE_HANG;
+				goto exit;
+			}
+		}
+		core->state = VPU_CORE_ACTIVE;
+	}
+
+exit:
+	pm_runtime_put_sync(dev);
+	mutex_unlock(&core->lock);
+
+	vpu_core_resume_work(core);
+	return ret;
+}
+
+static int __maybe_unused vpu_core_suspend(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (!core->res->standalone)
+		return 0;
+
+	mutex_lock(&core->lock);
+	if (core->state == VPU_CORE_ACTIVE) {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_snapshot(core);
+			if (ret) {
+				mutex_unlock(&core->lock);
+				return ret;
+			}
+		}
+
+		core->state = VPU_CORE_SNAPSHOT;
+	}
+	mutex_unlock(&core->lock);
+
+	vpu_core_cancel_work(core);
+
+	mutex_lock(&core->lock);
+	vpu_core_put_vpu(core);
+	mutex_unlock(&core->lock);
+	return ret;
+}
+
+static const struct dev_pm_ops vpu_core_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_core_runtime_suspend, vpu_core_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(vpu_core_suspend, vpu_core_resume)
+};
+
+static struct vpu_core_resources imx8q_enc = {
+	.type = VPU_CORE_TYPE_ENC,
+	.fwname = "vpu/vpu_fw_imx8_enc.bin",
+	.stride = 16,
+	.max_width = 1920,
+	.max_height = 1920,
+	.min_width = 64,
+	.min_height = 48,
+	.step_width = 2,
+	.step_height = 2,
+	.rpc_size = 0x80000,
+	.fwlog_size = 0x80000,
+	.act_size = 0xc0000,
+	.standalone = true,
+};
+
+static struct vpu_core_resources imx8q_dec = {
+	.type = VPU_CORE_TYPE_DEC,
+	.fwname = "vpu/vpu_fw_imx8_dec.bin",
+	.stride = 256,
+	.max_width = 8188,
+	.max_height = 8188,
+	.min_width = 16,
+	.min_height = 16,
+	.step_width = 1,
+	.step_height = 1,
+	.rpc_size = 0x80000,
+	.fwlog_size = 0x80000,
+	.standalone = true,
+};
+
+static const struct of_device_id vpu_core_dt_match[] = {
+	{ .compatible = "nxp,imx8q-vpu-encoder", .data = &imx8q_enc },
+	{ .compatible = "nxp,imx8q-vpu-decoder", .data = &imx8q_dec },
+	{}
+};
+MODULE_DEVICE_TABLE(of, vpu_core_dt_match);
+
+static struct platform_driver imx_vpu_core_driver = {
+	.probe = vpu_core_probe,
+	.remove = vpu_core_remove,
+	.driver = {
+		.name = "imx-vpu-core",
+		.of_match_table = vpu_core_dt_match,
+		.pm = &vpu_core_pm_ops,
+	},
+};
+module_platform_driver(imx_vpu_core_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_core.h b/drivers/media/platform/imx/vpu-8q/vpu_core.h
new file mode 100644
index 000000000000..86a628409144
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_core.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_CORE_H
+#define _IMX_VPU_CORE_H
+
+void csr_writel(struct vpu_core *core, u32 reg, u32 val);
+u32 csr_readl(struct vpu_core *core, u32 reg);
+int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf);
+void vpu_free_dma(struct vpu_buffer *buf);
+struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index);
+int vpu_core_check_fmt(struct vpu_core *core, u32 pixelfmt);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_dbg.c b/drivers/media/platform/imx/vpu-8q/vpu_dbg.c
new file mode 100644
index 000000000000..f90498546d0f
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_dbg.c
@@ -0,0 +1,496 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"DEBUG"
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-device.h>
+#include <linux/debugfs.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+
+struct print_buf_desc {
+	u32 start_h_phy;
+	u32 start_h_vir;
+	u32 start_m;
+	u32 bytes;
+	u32 read;
+	u32 write;
+	char buffer[0];
+};
+
+static char *vb2_stat_name[] = {
+	[VB2_BUF_STATE_DEQUEUED] = "dequeued",
+	[VB2_BUF_STATE_IN_REQUEST] = "in_request",
+	[VB2_BUF_STATE_PREPARING] = "preparing",
+	[VB2_BUF_STATE_QUEUED] = "queued",
+	[VB2_BUF_STATE_ACTIVE] = "active",
+	[VB2_BUF_STATE_DONE] = "done",
+	[VB2_BUF_STATE_ERROR] = "error",
+};
+
+static char *vpu_stat_name[] = {
+	[VPU_BUF_STATE_IDLE] = "idle",
+	[VPU_BUF_STATE_INUSE] = "inuse",
+	[VPU_BUF_STATE_DECODED] = "decoded",
+	[VPU_BUF_STATE_READY] = "ready",
+	[VPU_BUF_STATE_SKIP] = "skip",
+	[VPU_BUF_STATE_ERROR] = "error",
+};
+
+static int vpu_dbg_instance(struct seq_file *s, void *data)
+{
+	struct vpu_inst *inst = s->private;
+	char str[128];
+	int num;
+	struct vb2_queue *vq;
+	int i;
+
+	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(inst->type));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "state = %d\n", inst->state);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"min_buffer_out = %d, min_buffer_cap = %d\n",
+			inst->min_buffer_out, inst->min_buffer_cap);
+	if (seq_write(s, str, num))
+		return 0;
+
+
+	vq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	num = scnprintf(str, sizeof(str),
+			"output(%d) : fmt = %c%c%c%c %d x %d, %d;",
+			vb2_is_streaming(vq),
+			inst->out_format.pixfmt,
+			inst->out_format.pixfmt >> 8,
+			inst->out_format.pixfmt >> 16,
+			inst->out_format.pixfmt >> 24,
+			inst->out_format.width,
+			inst->out_format.height,
+			vq->last_buffer_dequeued);
+	if (seq_write(s, str, num))
+		return 0;
+	for (i = 0; i < inst->out_format.num_planes; i++) {
+		num = scnprintf(str, sizeof(str), " %d(%d)",
+				inst->out_format.sizeimage[i],
+				inst->out_format.bytesperline[i]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	if (seq_write(s, "\n", 1))
+		return 0;
+
+	vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	num = scnprintf(str, sizeof(str),
+			"capture(%d): fmt = %c%c%c%c %d x %d, %d;",
+			vb2_is_streaming(vq),
+			inst->cap_format.pixfmt,
+			inst->cap_format.pixfmt >> 8,
+			inst->cap_format.pixfmt >> 16,
+			inst->cap_format.pixfmt >> 24,
+			inst->cap_format.width,
+			inst->cap_format.height,
+			vq->last_buffer_dequeued);
+	if (seq_write(s, str, num))
+		return 0;
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		num = scnprintf(str, sizeof(str), " %d(%d)",
+				inst->cap_format.sizeimage[i],
+				inst->cap_format.bytesperline[i]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	if (seq_write(s, "\n", 1))
+		return 0;
+	num = scnprintf(str, sizeof(str), "crop: (%d, %d) %d x %d\n",
+			inst->crop.left,
+			inst->crop.top,
+			inst->crop.width,
+			inst->crop.height);
+	if (seq_write(s, str, num))
+		return 0;
+
+	vq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	for (i = 0; i < vq->num_buffers; i++) {
+		struct vb2_buffer *vb = vq->bufs[i];
+		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+		struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+		if (vb->state == VB2_BUF_STATE_DEQUEUED)
+			continue;
+		num = scnprintf(str, sizeof(str),
+				"output [%2d] state = %10s, %8s\n",
+				i, vb2_stat_name[vb->state],
+				vpu_stat_name[vpu_buf->state]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	for (i = 0; i < vq->num_buffers; i++) {
+		struct vb2_buffer *vb = vq->bufs[i];
+		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+		struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+		if (vb->state == VB2_BUF_STATE_DEQUEUED)
+			continue;
+		num = scnprintf(str, sizeof(str),
+				"capture[%2d] state = %10s, %8s\n",
+				i, vb2_stat_name[vb->state],
+				vpu_stat_name[vpu_buf->state]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);
+	if (seq_write(s, str, num))
+		return 0;
+
+	if (inst->use_stream_buffer) {
+		num = scnprintf(str, sizeof(str), "stream_buffer = %d / %d, [0x%llx, 0x%llx]\n",
+				vpu_helper_get_used_space(inst),
+				inst->stream_buffer.length,
+				inst->stream_buffer.phys,
+				inst->stream_buffer.phys + inst->stream_buffer.length);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&inst->msg_fifo));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "flow :\n");
+	if (seq_write(s, str, num))
+		return 0;
+
+	mutex_lock(&inst->core->cmd_lock);
+	for (i = 0; i < ARRAY_SIZE(inst->flows); i++) {
+		u32 idx = (inst->flow_idx + i) % (ARRAY_SIZE(inst->flows));
+
+		if (!inst->flows[idx])
+			continue;
+		num = scnprintf(str, sizeof(str), "\t[%s]0x%x\n",
+				inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C",
+				inst->flows[idx]);
+		if (seq_write(s, str, num)) {
+			mutex_unlock(&inst->core->cmd_lock);
+			return 0;
+		}
+	}
+	mutex_unlock(&inst->core->cmd_lock);
+
+	i = 0;
+	while (true) {
+		num = call_vop(inst, get_debug_info, str, sizeof(str), i++);
+		if (num <= 0)
+			break;
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	return 0;
+}
+
+static int vpu_dbg_core(struct seq_file *s, void *data)
+{
+	struct vpu_core *core = s->private;
+	struct vpu_shared_addr *iface = core->iface;
+	char str[128];
+	int num;
+
+	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(core->type));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "boot_region  = <0x%08llx, 0x%x>\n",
+			core->fw.phys, core->fw.length);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "rpc_region   = <0x%08llx, 0x%x> used = 0x%x\n",
+			core->rpc.phys, core->rpc.length, core->rpc.bytesused);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "fwlog_region = <0x%08llx, 0x%x>\n",
+			core->log.phys, core->log.length);
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "state = %d\n", core->state);
+	if (seq_write(s, str, num))
+		return 0;
+	if (core->state == VPU_CORE_DEINIT)
+		return 0;
+	num = scnprintf(str, sizeof(str), "fw version = %d.%d.%d\n",
+				(core->fw_version >> 16) & 0xff,
+				(core->fw_version >> 8) & 0xff,
+				core->fw_version & 0xff);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "instances = %d/%d (0x%02lx), %d\n",
+			hweight32(core->instance_mask),
+			core->supported_instance_count,
+			core->instance_mask,
+			core->request_count);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&core->msg_fifo));
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"cmd_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
+			iface->cmd_desc->start,
+			iface->cmd_desc->end,
+			iface->cmd_desc->wptr,
+			iface->cmd_desc->rptr);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"msg_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
+			iface->msg_desc->start,
+			iface->msg_desc->end,
+			iface->msg_desc->wptr,
+			iface->msg_desc->rptr);
+	if (seq_write(s, str, num))
+		return 0;
+
+	return 0;
+}
+
+static int vpu_dbg_fwlog(struct seq_file *s, void *data)
+{
+	struct vpu_core *core = s->private;
+	struct print_buf_desc *print_buf;
+	int length;
+	u32 rptr;
+	u32 wptr;
+	int ret = 0;
+
+	if (!core->log.virt || core->state == VPU_CORE_DEINIT)
+		return 0;
+
+	print_buf = core->log.virt;
+	rptr = print_buf->read;
+	wptr = print_buf->write;
+
+	if (rptr == wptr)
+		return 0;
+	else if (rptr < wptr)
+		length = wptr - rptr;
+	else
+		length = print_buf->bytes + wptr - rptr;
+
+	if (s->count + length >= s->size) {
+		s->count = s->size;
+		return 0;
+	}
+
+	if (rptr + length >= print_buf->bytes) {
+		int num = print_buf->bytes - rptr;
+
+		if (seq_write(s, print_buf->buffer + rptr, num))
+			ret = -1;
+		length -= num;
+		rptr = 0;
+	}
+
+	if (length) {
+		if (seq_write(s, print_buf->buffer + rptr, length))
+			ret = -1;
+		rptr += length;
+	}
+	if (!ret)
+		print_buf->read = rptr;
+
+	return 0;
+}
+
+static int vpu_dbg_inst_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_instance, inode->i_private);
+}
+
+static ssize_t vpu_dbg_inst_write(struct file *file,
+			const char __user *user_buf, size_t size, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct vpu_inst *inst = s->private;
+
+	vpu_session_debug(inst);
+
+	return size;
+}
+
+static ssize_t vpu_dbg_core_write(struct file *file,
+			const char __user *user_buf, size_t size, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct vpu_core *core = s->private;
+
+	pm_runtime_get_sync(core->dev);
+	mutex_lock(&core->lock);
+	if (core->state != VPU_CORE_DEINIT && !core->instance_mask) {
+		core_dbg(core, LVL_INFO, "reset core\n");
+		if (!vpu_core_sw_reset(core)) {
+			core->state = VPU_CORE_ACTIVE;
+			core->hang_mask = 0;
+		}
+	}
+	mutex_unlock(&core->lock);
+	pm_runtime_put_sync(core->dev);
+
+	return size;
+}
+
+static int vpu_dbg_core_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_core, inode->i_private);
+}
+
+static int vpu_dbg_fwlog_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_fwlog, inode->i_private);
+}
+
+static const struct file_operations vpu_dbg_inst_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_inst_open,
+	.release = single_release,
+	.read = seq_read,
+	.write = vpu_dbg_inst_write,
+};
+
+static const struct file_operations vpu_dbg_core_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_core_open,
+	.release = single_release,
+	.read = seq_read,
+	.write = vpu_dbg_core_write,
+};
+
+static const struct file_operations vpu_dbg_fwlog_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_fwlog_open,
+	.release = single_release,
+	.read = seq_read,
+};
+
+int vpu_inst_create_dbgfs_file(struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu;
+	char name[64];
+
+	if (!inst || !inst->core || !inst->core->vpu)
+		return -EINVAL;
+
+	vpu = inst->core->vpu;
+	if (!vpu->debugfs)
+		return -EINVAL;
+
+	if (inst->debugfs)
+		return 0;
+
+	scnprintf(name, sizeof(name), "instance.%d.%d",
+			inst->core->id, inst->id);
+	inst->debugfs = debugfs_create_file((const char *)name,
+				VERIFY_OCTAL_PERMISSIONS(0644),
+				vpu->debugfs,
+				inst,
+				&vpu_dbg_inst_fops);
+	if (!inst->debugfs) {
+		vpu_err("vpu create debugfs %s fail\n", name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst)
+{
+	if (!inst)
+		return 0;
+
+	debugfs_remove(inst->debugfs);
+	inst->debugfs = NULL;
+
+	return 0;
+}
+
+int vpu_core_create_dbgfs_file(struct vpu_core *core)
+{
+	struct vpu_dev *vpu;
+	char name[64];
+
+	if (!core || !core->vpu)
+		return -EINVAL;
+
+	vpu = core->vpu;
+	if (!vpu->debugfs)
+		return -EINVAL;
+
+	if (!core->debugfs) {
+		scnprintf(name, sizeof(name), "core.%d", core->id);
+		core->debugfs = debugfs_create_file((const char *)name,
+					VERIFY_OCTAL_PERMISSIONS(0644),
+					vpu->debugfs,
+					core,
+					&vpu_dbg_core_fops);
+		if (!core->debugfs) {
+			vpu_err("vpu create debugfs %s fail\n", name);
+			return -EINVAL;
+		}
+	}
+	if (!core->debugfs_fwlog) {
+		scnprintf(name, sizeof(name), "fwlog.%d", core->id);
+		core->debugfs_fwlog = debugfs_create_file((const char *)name,
+					VERIFY_OCTAL_PERMISSIONS(0444),
+					vpu->debugfs,
+					core,
+					&vpu_dbg_fwlog_fops);
+		if (!core->debugfs_fwlog) {
+			vpu_err("vpu create debugfs %s fail\n", name);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int vpu_core_remove_dbgfs_file(struct vpu_core *core)
+{
+	if (!core)
+		return 0;
+	debugfs_remove(core->debugfs);
+	core->debugfs = NULL;
+	debugfs_remove(core->debugfs_fwlog);
+	core->debugfs_fwlog = NULL;
+
+	return 0;
+}
+
+void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow)
+{
+	if (!inst)
+		return;
+
+	inst->flows[inst->flow_idx] = flow;
+	inst->flow_idx = (inst->flow_idx + 1) % (ARRAY_SIZE(inst->flows));
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_log.h b/drivers/media/platform/imx/vpu-8q/vpu_log.h
new file mode 100644
index 000000000000..f21818749f4d
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_log.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_LOG_H
+#define _IMX_VPU_LOG_H
+
+#define LVL_ERR		(1 << 0)
+#define LVL_WARN	(1 << 1)
+#define LVL_INFO	(1 << 2)
+#define LVL_DEBUG	(1 << 3)
+#define LVL_IRQ		(1 << 4)
+#define LVL_CMD		(1 << 5)
+#define LVL_EVT		(1 << 6)
+#define LVL_CTRL	(1 << 7)
+#define LVL_TS		(1 << 8)
+#define LVL_FLOW	(1 << 13)
+
+extern unsigned int vpu_dbg_level;
+
+#ifdef TAG
+#define vpu_dbg(level, fmt, arg...) \
+	do { \
+		if ((vpu_dbg_level & (level)) || ((level) & LVL_ERR)) \
+			pr_info("[VPU "TAG"]"fmt, ## arg); \
+	} while (0)
+#else
+#define vpu_dbg(level, fmt, arg...) \
+	do { \
+		if ((vpu_dbg_level & (level)) || ((level) & LVL_ERR)) \
+			pr_info("[VPU]"fmt, ## arg); \
+	} while (0)
+#endif
+
+#define vpu_err(fmt, arg...)	vpu_dbg(LVL_ERR, fmt, ##arg)
+#define inst_dbg(inst, level, fmt, arg...)		\
+		vpu_dbg(level, "[%d:%d] "fmt, inst->core->id, inst->id, ## arg)
+#define inst_err(inst, fmt, arg...)	inst_dbg(inst, LVL_ERR, fmt, ## arg)
+#define core_dbg(core, level, fmt, arg...)		\
+		vpu_dbg(level, "[%d] %s "fmt, core->id, vpu_core_type_desc(core->type), ## arg)
+#define core_err(core, fmt, arg...)	core_dbg(core, LVL_ERR, fmt, ## arg)
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_rpc.c b/drivers/media/platform/imx/vpu-8q/vpu_rpc.c
new file mode 100644
index 000000000000..0f10edf9485b
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_rpc.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"RPC"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/svc/misc.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_imx8q.h"
+#include "vpu_windsor.h"
+#include "vpu_malone.h"
+#include "vpu_log.h"
+
+u32 vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->check_memory_region)
+		return VPU_CORE_MEMORY_INVALID;
+
+	return ops->check_memory_region(core->fw.phys, addr, size);
+}
+
+u32 vpu_rpc_check_buffer_space(struct vpu_rpc_buffer_desc *desc, bool write)
+{
+	u32 ptr1;
+	u32 ptr2;
+	u32 size;
+
+	WARN_ON(!desc);
+
+	size = desc->end - desc->start;
+	if (write) {
+		ptr1 = desc->wptr;
+		ptr2 = desc->rptr;
+	} else {
+		ptr1 = desc->rptr;
+		ptr2 = desc->wptr;
+	}
+
+	if (ptr1 == ptr2) {
+		if (!write)
+			return 0;
+		else
+			return size;
+	}
+
+	return (ptr2 + size - ptr1) % size;
+}
+
+int vpu_rpc_send_cmd_buf(struct vpu_shared_addr *shared,
+			struct vpu_rpc_event *cmd)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 space = 0;
+	u32 *data;
+	u32 wptr;
+	u32 i;
+
+	WARN_ON(!shared || !shared->cmd_mem_vir || !cmd);
+
+	desc = shared->cmd_desc;
+	space = vpu_rpc_check_buffer_space(desc, true);
+	if (space < (((cmd->hdr.num + 1) << 2) + 16)) {
+		vpu_err("Cmd Buffer is no space for [%d] %d\n",
+				cmd->hdr.index, cmd->hdr.id);
+		return -EINVAL;
+	}
+	wptr = desc->wptr;
+	data = (u32 *)(shared->cmd_mem_vir + desc->wptr - desc->start);
+	*data = 0;
+	*data |= ((cmd->hdr.index & 0xff) << 24);
+	*data |= ((cmd->hdr.num & 0xff) << 16);
+	*data |= (cmd->hdr.id & 0x3fff);
+	wptr += 4;
+	data++;
+	if (wptr >= desc->end) {
+		wptr = desc->start;
+		data = shared->cmd_mem_vir;
+	}
+
+	for (i = 0; i < cmd->hdr.num; i++) {
+		*data = cmd->data[i];
+		wptr += 4;
+		data++;
+		if (wptr >= desc->end) {
+			wptr = desc->start;
+			data = shared->cmd_mem_vir;
+		}
+	}
+
+	/*update wptr after data is written*/
+	mb();
+	desc->wptr = wptr;
+
+	return 0;
+}
+
+bool vpu_rpc_check_msg(struct vpu_shared_addr *shared)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 space = 0;
+	u32 msgword;
+	u32 msgnum;
+
+	WARN_ON(!shared || !shared->msg_desc);
+
+	desc = shared->msg_desc;
+	space = vpu_rpc_check_buffer_space(desc, 0);
+	space = (space >> 2);
+
+	if (space) {
+		msgword = *(u32 *)(shared->msg_mem_vir + desc->rptr - desc->start);
+		msgnum = (msgword & 0xff0000) >> 16;
+		if (msgnum <= space)
+			return true;
+	}
+
+	return false;
+}
+
+int vpu_rpc_receive_msg_buf(struct vpu_shared_addr *shared, struct vpu_rpc_event *msg)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 *data;
+	u32 msgword;
+	u32 rptr;
+	u32 i;
+
+	WARN_ON(!shared || !shared->msg_desc || !msg);
+
+	if (!vpu_rpc_check_msg(shared))
+		return -EINVAL;
+
+	desc = shared->msg_desc;
+	data = (u32 *)(shared->msg_mem_vir + desc->rptr - desc->start);
+	rptr = desc->rptr;
+	msgword = *data;
+	data++;
+	rptr += 4;
+	if (rptr >= desc->end) {
+		rptr = desc->start;
+		data = shared->msg_mem_vir;
+	}
+
+	msg->hdr.index = (msgword >> 24) & 0xff;
+	msg->hdr.num = (msgword >> 16) & 0xff;
+	msg->hdr.id = msgword & 0x3fff;
+
+	for (i = 0; i < msg->hdr.num; i++) {
+		msg->data[i] = *data;
+		data++;
+		rptr += 4;
+		if (rptr >= desc->end) {
+			rptr = desc->start;
+			data = shared->msg_mem_vir;
+		}
+	}
+
+	/*update rptr after data is read*/
+	mb();
+	desc->rptr = rptr;
+
+	return 0;
+}
+
+struct vpu_iface_ops imx8q_rpc_ops[] = {
+	[VPU_CORE_TYPE_ENC] = {
+		.check_codec = vpu_imx8q_check_codec,
+		.check_fmt = vpu_imx8q_check_fmt,
+		.boot_core = vpu_imx8q_boot_core,
+		.get_power_state = vpu_imx8q_get_power_state,
+		.on_firmware_loaded = vpu_imx8q_on_firmware_loaded,
+		.get_data_size = vpu_windsor_get_data_size,
+		.check_memory_region = vpu_imx8q_check_memory_region,
+		.init_rpc = vpu_windsor_init_rpc,
+		.set_log_buf = vpu_windsor_set_log_buf,
+		.set_system_cfg = vpu_windsor_set_system_cfg,
+		.get_version = vpu_windsor_get_version,
+		.send_cmd_buf = vpu_rpc_send_cmd_buf,
+		.receive_msg_buf = vpu_rpc_receive_msg_buf,
+		.pack_cmd = vpu_windsor_pack_cmd,
+		.convert_msg_id = vpu_windsor_convert_msg_id,
+		.unpack_msg_data = vpu_windsor_unpack_msg_data,
+		.config_memory_resource = vpu_windsor_config_memory_resource,
+		.get_stream_buffer_size = vpu_windsor_get_stream_buffer_size,
+		.config_stream_buffer = vpu_windsor_config_stream_buffer,
+		.get_stream_buffer_desc = vpu_windsor_get_stream_buffer_desc,
+		.update_stream_buffer = vpu_windsor_update_stream_buffer,
+		.set_encode_params = vpu_windsor_set_encode_params,
+		.input_frame = vpu_windsor_input_frame,
+		.get_max_instance_count = vpu_windsor_get_max_instance_count,
+	},
+	[VPU_CORE_TYPE_DEC] = {
+		.check_codec = vpu_imx8q_check_codec,
+		.check_fmt = vpu_imx8q_check_fmt,
+		.boot_core = vpu_imx8q_boot_core,
+		.get_power_state = vpu_imx8q_get_power_state,
+		.on_firmware_loaded = vpu_imx8q_on_firmware_loaded,
+		.get_data_size = vpu_malone_get_data_size,
+		.check_memory_region = vpu_imx8q_check_memory_region,
+		.init_rpc = vpu_malone_init_rpc,
+		.set_log_buf = vpu_malone_set_log_buf,
+		.set_system_cfg = vpu_malone_set_system_cfg,
+		.get_version = vpu_malone_get_version,
+		.send_cmd_buf = vpu_rpc_send_cmd_buf,
+		.receive_msg_buf = vpu_rpc_receive_msg_buf,
+		.get_stream_buffer_size = vpu_malone_get_stream_buffer_size,
+		.config_stream_buffer = vpu_malone_config_stream_buffer,
+		.set_decode_params = vpu_malone_set_decode_params,
+		.pack_cmd = vpu_malone_pack_cmd,
+		.convert_msg_id = vpu_malone_convert_msg_id,
+		.unpack_msg_data = vpu_malone_unpack_msg_data,
+		.get_stream_buffer_desc = vpu_malone_get_stream_buffer_desc,
+		.update_stream_buffer = vpu_malone_update_stream_buffer,
+		.add_scode = vpu_malone_add_scode,
+		.input_frame = vpu_malone_input_frame,
+		.pre_send_cmd = vpu_malone_pre_cmd,
+		.post_send_cmd = vpu_malone_post_cmd,
+		.init_instance = vpu_malone_init_instance,
+		.get_max_instance_count = vpu_malone_get_max_instance_count,
+	},
+};
+
+struct vpu_iface_ops *vpu_iface_get(struct vpu_core *core)
+{
+	struct vpu_iface_ops *rpc_ops = NULL;
+	u32 size = 0;
+
+	WARN_ON(!core || !core->vpu || !core->vpu->res);
+
+	switch (core->vpu->res->plat_type) {
+	case IMX8QXP:
+	case IMX8QM:
+		rpc_ops = imx8q_rpc_ops;
+		size = ARRAY_SIZE(imx8q_rpc_ops);
+		break;
+	default:
+		return NULL;
+	}
+
+	if (core->type >= size)
+		return NULL;
+
+	return &rpc_ops[core->type];
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_rpc.h b/drivers/media/platform/imx/vpu-8q/vpu_rpc.h
new file mode 100644
index 000000000000..a2b009132eb5
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_rpc.h
@@ -0,0 +1,463 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_RPC_H
+#define _IMX_VPU_RPC_H
+
+#include <media/videobuf2-core.h>
+#include "vpu_codec.h"
+
+struct vpu_rpc_buffer_desc {
+	u32 wptr;
+	u32 rptr;
+	u32 start;
+	u32 end;
+};
+
+struct vpu_shared_addr {
+	void *iface;
+	struct vpu_rpc_buffer_desc *cmd_desc;
+	void *cmd_mem_vir;
+	struct vpu_rpc_buffer_desc *msg_desc;
+	void *msg_mem_vir;
+
+	unsigned long boot_addr;
+	struct vpu_core *core;
+	void *priv;
+};
+
+struct vpu_rpc_event_header {
+	u32 index;
+	u32 id;
+	u32 num;
+};
+
+struct vpu_rpc_event {
+	struct vpu_rpc_event_header hdr;
+	u32 data[256];
+};
+
+struct vpu_iface_ops {
+	bool (*check_codec)(enum vpu_core_type type);
+	bool (*check_fmt)(enum vpu_core_type type, u32 pixelfmt);
+	u32 (*get_data_size)(void);
+	u32 (*check_memory_region)(dma_addr_t base, dma_addr_t addr, u32 size);
+	int (*boot_core)(struct vpu_core *core);
+	int (*shutdown_core)(struct vpu_core *core);
+	int (*restore_core)(struct vpu_core *core);
+	int (*get_power_state)(struct vpu_core *core);
+	int (*on_firmware_loaded)(struct vpu_core *core);
+	void (*init_rpc)(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr);
+	void (*set_log_buf)(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log);
+	void (*set_system_cfg)(struct vpu_shared_addr *shared,
+			u32 regs_base, void __iomem *regs, u32 index);
+	void (*set_stream_cfg)(struct vpu_shared_addr *shared, u32 index);
+	u32 (*get_version)(struct vpu_shared_addr *shared);
+	u32 (*get_max_instance_count)(struct vpu_shared_addr *shared);
+	int (*get_stream_buffer_size)(struct vpu_shared_addr *shared);
+	int (*send_cmd_buf)(struct vpu_shared_addr *shared,
+			struct vpu_rpc_event *cmd);
+	int (*receive_msg_buf)(struct vpu_shared_addr *shared,
+			struct vpu_rpc_event *msg);
+	int (*pack_cmd)(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+	int (*convert_msg_id)(u32 msg_id);
+	int (*unpack_msg_data)(struct vpu_rpc_event *pkt, void *data);
+	int (*input_frame)(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*config_memory_resource)(struct vpu_shared_addr *shared,
+					u32 instance,
+					u32 type,
+					u32 index,
+					struct vpu_buffer *buf);
+	int (*config_stream_buffer)(struct vpu_shared_addr *shared,
+					u32 instance,
+					struct vpu_buffer *buf);
+	int (*update_stream_buffer)(struct vpu_shared_addr *shared,
+					u32 instance, u32 ptr, bool write);
+	int (*get_stream_buffer_desc)(struct vpu_shared_addr *shared,
+					u32 instance,
+					struct vpu_rpc_buffer_desc *desc);
+	int (*set_encode_params)(struct vpu_shared_addr *shared,
+			u32 instance,
+			struct vpu_encode_params *params, u32 update);
+	int (*set_decode_params)(struct vpu_shared_addr *shared,
+			u32 instance,
+			struct vpu_decode_params *params, u32 update);
+	int (*add_scode)(struct vpu_shared_addr *shared,
+				u32 instance,
+				struct vpu_buffer *stream_buffer,
+				u32 pixelformat,
+				u32 scode_type);
+	int (*pre_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
+	int (*post_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
+	int (*init_instance)(struct vpu_shared_addr *shared, u32 instance);
+};
+
+enum {
+	VPU_CORE_MEMORY_INVALID = 0,
+	VPU_CORE_MEMORY_CACHED,
+	VPU_CORE_MEMORY_UNCACHED
+};
+
+struct vpu_rpc_region_t {
+	dma_addr_t start;
+	dma_addr_t end;
+	dma_addr_t type;
+};
+
+struct vpu_iface_ops *vpu_iface_get(struct vpu_core *core);
+u32 vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size);
+
+static inline bool vpu_iface_check_codec(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->check_codec)
+		return ops->check_codec(core->type);
+
+	return true;
+}
+
+static inline bool vpu_iface_check_format(struct vpu_core *core, u32 pixelfmt)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->check_fmt)
+		return ops->check_fmt(core->type, pixelfmt);
+
+	return true;
+}
+
+static inline int vpu_iface_boot_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->boot_core)
+		return ops->boot_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_get_power_state(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->get_power_state)
+		return ops->get_power_state(core);
+	return 1;
+}
+
+static inline int vpu_iface_shutdown_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->shutdown_core)
+		return ops->shutdown_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_restore_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->restore_core)
+		return ops->restore_core(core);
+	return -EINVAL;
+}
+
+static inline int vpu_iface_on_firmware_loaded(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->on_firmware_loaded)
+		return ops->on_firmware_loaded(core);
+
+	return 0;
+}
+
+static inline u32 vpu_iface_get_data_size(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->get_data_size)
+		return 0;
+
+	return ops->get_data_size();
+}
+
+static inline int vpu_iface_init(struct vpu_core *core,
+				struct vpu_shared_addr *shared,
+				struct vpu_buffer *rpc,
+				dma_addr_t boot_addr)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->init_rpc)
+		return -EINVAL;
+
+	ops->init_rpc(shared, rpc, boot_addr);
+	core->iface = shared;
+	shared->core = core;
+	if (rpc->bytesused > rpc->length)
+		return -ENOSPC;
+	return 0;
+}
+
+static inline int vpu_iface_set_log_buf(struct vpu_core *core,
+					struct vpu_buffer *log)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops)
+		return -EINVAL;
+
+	if (ops->set_log_buf)
+		ops->set_log_buf(core->iface, log);
+
+	return 0;
+}
+
+static inline int vpu_iface_config_system(struct vpu_core *core,
+		u32 regs_base, void __iomem *regs)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops)
+		return -EINVAL;
+	if (ops->set_system_cfg)
+		ops->set_system_cfg(core->iface, regs_base, regs, core->id);
+
+	return 0;
+}
+
+static inline int vpu_iface_get_stream_buffer_size(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->get_stream_buffer_size)
+		return 0;
+
+	return ops->get_stream_buffer_size(core->iface);
+}
+
+static inline int vpu_iface_config_stream(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops)
+		return -EINVAL;
+	if (ops->set_stream_cfg)
+		ops->set_stream_cfg(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_send_cmd(struct vpu_core *core, struct vpu_rpc_event *cmd)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->send_cmd_buf)
+		return -EINVAL;
+
+	return ops->send_cmd_buf(core->iface, cmd);
+}
+
+static inline int vpu_iface_receive_msg(struct vpu_core *core, struct vpu_rpc_event *msg)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->receive_msg_buf)
+		return -EINVAL;
+
+	return ops->receive_msg_buf(core->iface, msg);
+}
+
+static inline int vpu_iface_pack_cmd(struct vpu_core *core,
+					struct vpu_rpc_event *pkt,
+					u32 index, u32 id, void *data)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->pack_cmd)
+		return -EINVAL;
+	return ops->pack_cmd(pkt, index, id, data);
+}
+
+static inline int vpu_iface_convert_msg_id(struct vpu_core *core, u32 msg_id)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->convert_msg_id)
+		return -EINVAL;
+
+	return ops->convert_msg_id(msg_id);
+}
+
+static inline int vpu_iface_unpack_msg_data(struct vpu_core *core,
+						struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->unpack_msg_data)
+		return -EINVAL;
+
+	return ops->unpack_msg_data(pkt, data);
+}
+
+static inline int vpu_iface_input_frame(struct vpu_inst *inst,
+						struct vb2_buffer *vb)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	if (!ops || !ops->input_frame)
+		return -EINVAL;
+
+	return ops->input_frame(inst->core->iface, inst, vb);
+}
+
+static inline int vpu_iface_config_memory_resource(struct vpu_inst *inst,
+			u32 type, u32 index, struct vpu_buffer *buf)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->config_memory_resource)
+		return -EINVAL;
+
+	return ops->config_memory_resource(inst->core->iface,
+					inst->id,
+					type, index, buf);
+}
+
+static inline int vpu_iface_config_stream_buffer(struct vpu_inst *inst,
+						struct vpu_buffer *buf)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->config_stream_buffer)
+		return -EINVAL;
+
+	return ops->config_stream_buffer(inst->core->iface, inst->id, buf);
+}
+
+static inline int vpu_iface_update_stream_buffer(struct vpu_inst *inst,
+						u32 ptr, bool write)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->update_stream_buffer)
+		return -EINVAL;
+
+	return ops->update_stream_buffer(inst->core->iface, inst->id, ptr, write);
+}
+
+static inline int vpu_iface_get_stream_buffer_desc(struct vpu_inst *inst,
+					struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->get_stream_buffer_desc)
+		return -EINVAL;
+
+	if (!desc)
+		return 0;
+
+	return ops->get_stream_buffer_desc(inst->core->iface, inst->id, desc);
+}
+
+static inline u32 vpu_iface_get_version(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->get_version)
+		return 0;
+
+	return ops->get_version(core->iface);
+}
+
+static inline u32 vpu_iface_get_max_instance_count(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->get_max_instance_count)
+		return 0;
+
+	return ops->get_max_instance_count(core->iface);
+}
+
+static inline int vpu_iface_set_encode_params(struct vpu_inst *inst,
+				struct vpu_encode_params *params, u32 update)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->set_encode_params)
+		return -EINVAL;
+
+	return ops->set_encode_params(inst->core->iface, inst->id, params, update);
+}
+
+static inline int vpu_iface_set_decode_params(struct vpu_inst *inst,
+				struct vpu_decode_params *params, u32 update)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->set_decode_params)
+		return -EINVAL;
+
+	return ops->set_decode_params(inst->core->iface, inst->id, params, update);
+}
+
+static inline int vpu_iface_add_scode(struct vpu_inst *inst, u32 scode_type)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->add_scode)
+		return -EINVAL;
+
+	return ops->add_scode(inst->core->iface, inst->id,
+				&inst->stream_buffer,
+				inst->out_format.pixfmt,
+				scode_type);
+}
+
+static inline int vpu_iface_pre_send_cmd(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (ops && ops->pre_send_cmd)
+		return ops->pre_send_cmd(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_post_send_cmd(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (ops && ops->post_send_cmd)
+		return ops->post_send_cmd(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_init_instance(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (ops && ops->init_instance)
+		return ops->init_instance(inst->core->iface, inst->id);
+
+	return 0;
+}
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:02 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:02 +0800
Subject: [PATCH v6 06/14] media: imx: imx8q: implement vpu core communication
 based on mailbox
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <7a945b82a4ce89d1fd8ded0b76b7c4ac5754ab6f.1628671163.git.ming.qian@nxp.com>

driver use mailbox to communicate with vpu core.
and there are a command buffer and a message buffer.
driver will write commands to the command buffer,
then trigger a vpu core interrupt
vpu core will write messages to the message buffer,
then trigger a cpu interrupt.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vpu_cmds.c | 438 +++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_cmds.h |  25 ++
 drivers/media/platform/imx/vpu-8q/vpu_mbox.c | 126 ++++++
 drivers/media/platform/imx/vpu-8q/vpu_mbox.h |  16 +
 drivers/media/platform/imx/vpu-8q/vpu_msgs.c | 412 +++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_msgs.h |  14 +
 6 files changed, 1031 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_cmds.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_cmds.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_mbox.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_mbox.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_msgs.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_msgs.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_cmds.c b/drivers/media/platform/imx/vpu-8q/vpu_cmds.c
new file mode 100644
index 000000000000..43dd32c2519d
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_cmds.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"CMD"
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_mbox.h"
+#include "vpu_log.h"
+
+struct vpu_cmd_request {
+	u32 request;
+	u32 response;
+	u32 handled;
+};
+
+struct vpu_cmd_t {
+	struct list_head list;
+	u32 id;
+	struct vpu_cmd_request *request;
+	struct vpu_rpc_event *pkt;
+	unsigned long key;
+};
+
+static struct vpu_cmd_request vpu_cmd_requests[] = {
+	{
+		.request = VPU_CMD_ID_CONFIGURE_CODEC,
+		.response = VPU_MSG_ID_MEM_REQUEST,
+		.handled = 1,
+	},
+	{
+		.request = VPU_CMD_ID_START,
+		.response = VPU_MSG_ID_START_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_STOP,
+		.response = VPU_MSG_ID_STOP_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_ABORT,
+		.response = VPU_MSG_ID_ABORT_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_RST_BUF,
+		.response = VPU_MSG_ID_BUF_RST,
+		.handled = 1,
+	},
+};
+
+int vpu_cmd_send(struct vpu_core *core, struct vpu_rpc_event *pkt)
+{
+	int ret = 0;
+
+	WARN_ON(!core || !pkt);
+
+	ret = vpu_iface_send_cmd(core, pkt);
+	if (ret)
+		return ret;
+
+	/*write cmd data to cmd buffer before trigger a cmd interrupt*/
+	mb();
+	vpu_mbox_send_type(core, COMMAND);
+
+	return ret;
+}
+
+struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data)
+{
+	struct vpu_cmd_t *cmd;
+	int i;
+	int ret;
+
+	cmd = vzalloc(sizeof(*cmd));
+	if (!cmd)
+		return NULL;
+
+	cmd->pkt = vzalloc(sizeof(*cmd->pkt));
+	if (!cmd->pkt) {
+		vfree(cmd);
+		return NULL;
+	}
+
+	cmd->id = id;
+	ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data);
+	if (ret) {
+		inst_err(inst, "iface pack cmd(%d) fail\n", id);
+		vfree(cmd->pkt);
+		vfree(cmd);
+		return NULL;
+	}
+	for (i = 0; i < ARRAY_SIZE(vpu_cmd_requests); i++) {
+		if (vpu_cmd_requests[i].request == id) {
+			cmd->request = &vpu_cmd_requests[i];
+			break;
+		}
+	}
+
+	return cmd;
+}
+
+void vpu_free_cmd(struct vpu_cmd_t *cmd)
+{
+	if (!cmd)
+		return;
+	if (cmd->pkt)
+		vfree(cmd->pkt);
+	vfree(cmd);
+}
+
+int vpu_session_process_cmd(struct vpu_inst *inst, struct vpu_cmd_t *cmd)
+{
+	int ret;
+
+	if (!inst || !cmd || !cmd->pkt)
+		return -EINVAL;
+
+	inst_dbg(inst, LVL_CMD, "send cmd(%d)\n", cmd->id);
+	vpu_iface_pre_send_cmd(inst);
+	ret = vpu_cmd_send(inst->core, cmd->pkt);
+	if (!ret) {
+		vpu_iface_post_send_cmd(inst);
+		vpu_inst_record_flow(inst, cmd->id);
+	} else {
+		inst_err(inst, "iface send cmd(%d) fail\n", cmd->id);
+	}
+
+	return ret;
+}
+
+void vpu_process_cmd_request(struct vpu_inst *inst)
+{
+	struct vpu_cmd_t *cmd;
+	struct vpu_cmd_t *tmp;
+
+	if (!inst || inst->pending)
+		return;
+
+	list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+		list_del_init(&cmd->list);
+		if (vpu_session_process_cmd(inst, cmd))
+			inst_err(inst, "process cmd(%d) fail\n", cmd->id);
+		if (cmd->request) {
+			inst->pending = (void *)cmd;
+			break;
+		}
+		vpu_free_cmd(cmd);
+	}
+}
+
+int vpu_request_cmd(struct vpu_inst *inst, u32 id, void *data,
+		unsigned long *key, int *sync)
+{
+	struct vpu_core *core;
+	struct vpu_cmd_t *cmd;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+	cmd = vpu_alloc_cmd(inst, id, data);
+	if (!cmd)
+		return -ENOMEM;
+
+	mutex_lock(&core->cmd_lock);
+	cmd->key = core->cmd_seq++;
+	if (key)
+		*key = cmd->key;
+	if (sync)
+		*sync = cmd->request ? true : false;
+	list_add_tail(&cmd->list, &inst->cmd_q);
+	vpu_process_cmd_request(inst);
+	mutex_unlock(&core->cmd_lock);
+
+	return 0;
+}
+
+void vpu_clear_pending(struct vpu_inst *inst)
+{
+	if (!inst || !inst->pending)
+		return;
+
+	vpu_free_cmd(inst->pending);
+	wake_up_all(&inst->core->ack_wq);
+	inst->pending = NULL;
+}
+
+bool vpu_check_response(struct vpu_cmd_t *cmd, u32 response, u32 handled)
+{
+	struct vpu_cmd_request *request;
+
+	if (!cmd || !cmd->request)
+		return false;
+
+	request = cmd->request;
+	if (request->response != response)
+		return false;
+	if (request->handled != handled)
+		return false;
+
+	return true;
+}
+
+int vpu_response_cmd(struct vpu_inst *inst, u32 response, u32 handled)
+{
+	struct vpu_core *core;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->cmd_lock);
+	if (vpu_check_response(inst->pending, response, handled))
+		vpu_clear_pending(inst);
+
+	vpu_process_cmd_request(inst);
+	mutex_unlock(&core->cmd_lock);
+
+	return 0;
+}
+
+void vpu_clear_request(struct vpu_inst *inst)
+{
+	struct vpu_cmd_t *cmd;
+	struct vpu_cmd_t *tmp;
+
+	mutex_lock(&inst->core->cmd_lock);
+	if (inst->pending)
+		vpu_clear_pending(inst);
+
+	list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+		list_del_init(&cmd->list);
+		vpu_free_cmd(cmd);
+	}
+	mutex_unlock(&inst->core->cmd_lock);
+}
+
+static bool check_is_responsed(struct vpu_inst *inst, unsigned long key)
+{
+	struct vpu_core *core = inst->core;
+	struct vpu_cmd_t *cmd;
+	bool flag = true;
+
+	mutex_lock(&core->cmd_lock);
+	cmd = inst->pending;
+	if (cmd && key == cmd->key) {
+		flag = false;
+		goto exit;
+	}
+	list_for_each_entry(cmd, &inst->cmd_q, list) {
+		if (key == cmd->key) {
+			flag = false;
+			break;
+		}
+	}
+exit:
+	mutex_unlock(&core->cmd_lock);
+
+	return flag;
+}
+
+static int sync_session_response(struct vpu_inst *inst, unsigned long key)
+{
+	struct vpu_core *core;
+	long ret;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+
+	call_vop(inst, wait_prepare);
+	ret = wait_event_timeout(core->ack_wq,
+			check_is_responsed(inst, key),
+			VPU_TIMEOUT);
+	call_vop(inst, wait_finish);
+
+	if (!check_is_responsed(inst, key)) {
+		inst_err(inst, "sync session timeout\n");
+		set_bit(inst->id, &core->hang_mask);
+		mutex_lock(&inst->core->cmd_lock);
+		vpu_clear_pending(inst);
+		mutex_unlock(&inst->core->cmd_lock);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+{
+	struct vpu_core *core;
+	unsigned long key;
+	int sync = false;
+	int ret = -EINVAL;
+
+	WARN_ON(!inst || !inst->core || inst->id < 0);
+	core = inst->core;
+
+	ret = vpu_request_cmd(inst, id, data, &key, &sync);
+	if (!ret && sync)
+		ret = sync_session_response(inst, key);
+
+	if (ret)
+		inst_err(inst, "send cmd(%d) fail\n", id);
+
+	return ret;
+}
+
+int vpu_session_configure_codec(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_CONFIGURE_CODEC, NULL);
+}
+
+int vpu_session_start(struct vpu_inst *inst)
+{
+	inst_dbg(inst, LVL_FLOW, "send start cmd\n");
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_START, NULL);
+}
+
+int vpu_session_stop(struct vpu_inst *inst)
+{
+	inst_dbg(inst, LVL_FLOW, "send stop cmd\n");
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_STOP, NULL);
+}
+
+int vpu_session_encode_frame(struct vpu_inst *inst, s64 timestamp)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FRAME_ENCODE, &timestamp);
+}
+
+int vpu_session_alloc_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FS_ALLOC, fs);
+}
+
+int vpu_session_release_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FS_RELEASE, fs);
+}
+
+int vpu_session_abort(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_ABORT, NULL);
+}
+
+int vpu_session_rst_buf(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_RST_BUF, NULL);
+}
+
+int vpu_session_fill_timestamp(struct vpu_inst *inst, struct vpu_ts_info *info)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_TIMESTAMP, info);
+}
+
+int vpu_session_update_parameters(struct vpu_inst *inst, void *arg)
+{
+	if (inst->type & VPU_CORE_TYPE_DEC)
+		vpu_iface_set_decode_params(inst, arg, 1);
+	else
+		vpu_iface_set_encode_params(inst, arg, 1);
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_UPDATE_PARAMETER, arg);
+}
+
+int vpu_session_debug(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_DEBUG, NULL);
+}
+
+int vpu_core_snapshot(struct vpu_core *core)
+{
+	struct vpu_inst *inst;
+	int ret;
+
+	WARN_ON(!core || list_empty(&core->instances));
+
+	inst = list_first_entry(&core->instances, struct vpu_inst, list);
+
+	reinit_completion(&core->cmp);
+	ret = vpu_session_send_cmd(inst, VPU_CMD_ID_SNAPSHOT, NULL);
+	if (ret)
+		return ret;
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		vpu_err("core[%d] snapshot timeout\n", core->id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_core_sw_reset(struct vpu_core *core)
+{
+	struct vpu_rpc_event pkt;
+	int ret;
+
+	WARN_ON(!core);
+
+	memset(&pkt, 0, sizeof(pkt));
+	vpu_iface_pack_cmd(core, &pkt, 0, VPU_CMD_ID_FIRM_RESET, NULL);
+
+	reinit_completion(&core->cmp);
+	mutex_lock(&core->cmd_lock);
+	ret = vpu_cmd_send(core, &pkt);
+	mutex_unlock(&core->cmd_lock);
+	if (ret)
+		return ret;
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		vpu_err("core[%d] sw reset timeout\n", core->id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_cmds.h b/drivers/media/platform/imx/vpu-8q/vpu_cmds.h
new file mode 100644
index 000000000000..e45f4a67ac37
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_cmds.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_CMDS_H
+#define _IMX_VPU_CMDS_H
+
+int vpu_session_configure_codec(struct vpu_inst *inst);
+int vpu_session_start(struct vpu_inst *inst);
+int vpu_session_stop(struct vpu_inst *inst);
+int vpu_session_abort(struct vpu_inst *inst);
+int vpu_session_rst_buf(struct vpu_inst *inst);
+int vpu_session_encode_frame(struct vpu_inst *inst, s64 timestamp);
+int vpu_session_alloc_fs(struct vpu_inst *inst, struct vpu_fs_info *fs);
+int vpu_session_release_fs(struct vpu_inst *inst, struct vpu_fs_info *fs);
+int vpu_session_fill_timestamp(struct vpu_inst *inst, struct vpu_ts_info *info);
+int vpu_session_update_parameters(struct vpu_inst *inst, void *arg);
+int vpu_core_snapshot(struct vpu_core *core);
+int vpu_core_sw_reset(struct vpu_core *core);
+int vpu_response_cmd(struct vpu_inst *inst, u32 response, u32 handled);
+void vpu_clear_request(struct vpu_inst *inst);
+int vpu_session_debug(struct vpu_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_mbox.c b/drivers/media/platform/imx/vpu-8q/vpu_mbox.c
new file mode 100644
index 000000000000..5f926837932f
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_mbox.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"MBOX"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include "vpu.h"
+#include "vpu_mbox.h"
+#include "vpu_msgs.h"
+#include "vpu_log.h"
+
+static void vpu_mbox_rx_callback(struct mbox_client *cl, void *msg)
+{
+	struct vpu_mbox *rx = container_of(cl, struct vpu_mbox, cl);
+	struct vpu_core *core = container_of(rx, struct vpu_core, rx);
+
+	vpu_isr(core, *(u32 *)msg);
+}
+
+static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox)
+{
+	struct mbox_chan *ch;
+	struct mbox_client *cl;
+
+	if (!dev || !mbox)
+		return -EINVAL;
+	if (mbox->ch)
+		return 0;
+
+	cl = &mbox->cl;
+	cl->dev = dev;
+	if (mbox->block) {
+		cl->tx_block = true;
+		cl->tx_tout = 1000;
+	} else {
+		cl->tx_block = false;
+	}
+	cl->knows_txdone = false;
+	cl->rx_callback = vpu_mbox_rx_callback;
+
+	ch = mbox_request_channel_byname(cl, mbox->name);
+	if (IS_ERR(ch)) {
+		vpu_err("Failed to request mbox chan %s, ret : %ld\n",
+				mbox->name, PTR_ERR(ch));
+		return PTR_ERR(ch);
+	}
+
+	mbox->ch = ch;
+	return 0;
+}
+
+int vpu_mbox_init(struct vpu_core *core)
+{
+	WARN_ON(!core);
+
+	scnprintf(core->tx_type.name, sizeof(core->tx_type.name) - 1, "tx0");
+	core->tx_type.block = true;
+
+	scnprintf(core->tx_data.name, sizeof(core->tx_data.name) - 1, "tx1");
+	core->tx_data.block = false;
+
+	scnprintf(core->rx.name, sizeof(core->rx.name) - 1, "rx");
+	core->rx.block = true;
+
+	return 0;
+}
+
+int vpu_mbox_request(struct vpu_core *core)
+{
+	int ret;
+
+	WARN_ON(!core);
+
+	ret = vpu_mbox_request_channel(core->dev, &core->tx_type);
+	if (ret)
+		goto error;
+	ret = vpu_mbox_request_channel(core->dev, &core->tx_data);
+	if (ret)
+		goto error;
+	ret = vpu_mbox_request_channel(core->dev, &core->rx);
+	if (ret)
+		goto error;
+
+	vpu_dbg(LVL_DEBUG, "mbox request\n");
+	return 0;
+error:
+	vpu_mbox_free(core);
+	return ret;
+}
+
+void vpu_mbox_free(struct vpu_core *core)
+{
+	WARN_ON(!core);
+
+	mbox_free_channel(core->tx_type.ch);
+	mbox_free_channel(core->tx_data.ch);
+	mbox_free_channel(core->rx.ch);
+	core->tx_type.ch = NULL;
+	core->tx_data.ch = NULL;
+	core->rx.ch = NULL;
+	vpu_dbg(LVL_DEBUG, "mbox free\n");
+}
+
+void vpu_mbox_send_type(struct vpu_core *core, u32 type)
+{
+	mbox_send_message(core->tx_type.ch, &type);
+}
+
+void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data)
+{
+	mbox_send_message(core->tx_data.ch, &data);
+	mbox_send_message(core->tx_type.ch, &type);
+}
+
+void vpu_mbox_enable_rx(struct vpu_dev *dev)
+{
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_mbox.h b/drivers/media/platform/imx/vpu-8q/vpu_mbox.h
new file mode 100644
index 000000000000..3893ad3a4f7a
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_mbox.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_MBOX_H
+#define _IMX_VPU_MBOX_H
+
+int vpu_mbox_init(struct vpu_core *core);
+int vpu_mbox_request(struct vpu_core *core);
+void vpu_mbox_free(struct vpu_core *core);
+void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data);
+void vpu_mbox_send_type(struct vpu_core *core, u32 type);
+void vpu_mbox_enable_rx(struct vpu_dev *dev);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_msgs.c b/drivers/media/platform/imx/vpu-8q/vpu_msgs.c
new file mode 100644
index 000000000000..d01150758f14
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_msgs.c
@@ -0,0 +1,412 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"MSG"
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_rpc.h"
+#include "vpu_mbox.h"
+#include "vpu_defs.h"
+#include "vpu_cmds.h"
+#include "vpu_v4l2.h"
+#include "vpu_log.h"
+
+#define VPU_PKT_HEADER_LENGTH		3
+
+struct vpu_msg_handler {
+	u32 id;
+	void (*done)(struct vpu_inst *inst, struct vpu_rpc_event *pkt);
+};
+
+void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	WARN_ON(!inst || !inst->core);
+
+	inst_dbg(inst, LVL_FLOW, "start done\n");
+}
+
+void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_pkt_mem_req_data req_data;
+
+	WARN_ON(!inst || !inst->core || !inst->ops);
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data);
+	inst_dbg(inst, LVL_FLOW, "mem request event : %d:%d %d:%d %d:%d\n",
+				req_data.enc_frame_size,
+				req_data.enc_frame_num,
+				req_data.ref_frame_size,
+				req_data.ref_frame_num,
+				req_data.act_buf_size,
+				req_data.act_buf_num);
+	call_vop(inst, mem_request,
+				req_data.enc_frame_size,
+				req_data.enc_frame_num,
+				req_data.ref_frame_size,
+				req_data.ref_frame_num,
+				req_data.act_buf_size,
+				req_data.act_buf_num);
+}
+
+void vpu_session_handle_stop_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	WARN_ON(!inst || !inst->core);
+
+	inst_dbg(inst, LVL_FLOW, "stop done\n");
+
+	call_vop(inst, stop_done);
+}
+
+void vpu_session_handle_seq_hdr(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_codec_info info;
+
+	WARN_ON(!inst || !inst->core);
+
+	info.stride = inst->core->res->stride;
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	call_vop(inst, event_notify, VPU_MSG_ID_SEQ_HDR_FOUND, &info);
+}
+
+void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	WARN_ON(!inst || !inst->core);
+
+	call_vop(inst, event_notify, VPU_MSG_ID_RES_CHANGE, NULL);
+}
+
+void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_enc_pic_info info;
+
+	WARN_ON(!inst || !inst->core);
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	inst_dbg(inst, LVL_DEBUG, "frame id = %d, wptr = 0x%x, size = %d\n",
+			info.frame_id, info.wptr, info.frame_size);
+	call_vop(inst, get_one_frame, &info);
+}
+
+void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_fs_info fs;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+	call_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs);
+}
+
+void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+
+	WARN_ON(!inst || !inst->core);
+
+	if (inst->core->type == VPU_CORE_TYPE_ENC) {
+		struct vpu_frame_info info;
+
+		memset(&info, 0, sizeof(info));
+		vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info.sequence);
+		inst_dbg(inst, LVL_DEBUG, "frame release:%d\n", info.sequence);
+		info.type = inst->out_format.type;
+		call_vop(inst, buf_done, &info);
+	} else if (inst->core->type == VPU_CORE_TYPE_DEC) {
+		struct vpu_fs_info fs;
+
+		vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+		call_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs);
+	}
+}
+
+void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+
+	WARN_ON(!inst || !inst->core);
+
+	inst_dbg(inst, LVL_DEBUG, "frame input done\n");
+	call_vop(inst, input_done);
+}
+
+void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_pic_info info;
+
+	WARN_ON(!inst || !inst->core);
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	call_vop(inst, get_one_frame, &info);
+}
+
+void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_pic_info info;
+	struct vpu_frame_info frame;
+
+	WARN_ON(!inst || !inst->core);
+
+	memset(&frame, 0, sizeof(frame));
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	if (inst->core->type == VPU_CORE_TYPE_DEC)
+		frame.type = inst->cap_format.type;
+	frame.id = info.id;
+	frame.luma = info.luma;
+	frame.skipped = info.skipped;
+	frame.timestamp = info.timestamp;
+
+	call_vop(inst, buf_done, &frame);
+}
+
+void vpu_session_handle_eos(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	call_vop(inst, event_notify, VPU_MSG_ID_PIC_EOS, NULL);
+}
+
+void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	call_vop(inst, event_notify, VPU_MSG_ID_UNSUPPORTED, NULL);
+	vpu_notify_codec_error(inst);
+}
+
+void vpu_session_handle_firmware_xcpt(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	char *str = (char *)pkt->data;
+
+	inst_err(inst, "%s firmware xcpt: %s\n",
+			vpu_core_type_desc(inst->core->type), str);
+	call_vop(inst, event_notify, VPU_MSG_ID_FIRMWARE_XCPT, NULL);
+	set_bit(inst->id, &inst->core->hang_mask);
+	vpu_notify_codec_error(inst);
+}
+
+struct vpu_msg_handler handlers[] = {
+	{VPU_MSG_ID_START_DONE, vpu_session_handle_start_done},
+	{VPU_MSG_ID_STOP_DONE, vpu_session_handle_stop_done},
+	{VPU_MSG_ID_MEM_REQUEST, vpu_session_handle_mem_request},
+	{VPU_MSG_ID_SEQ_HDR_FOUND, vpu_session_handle_seq_hdr},
+	{VPU_MSG_ID_RES_CHANGE, vpu_session_handle_resolution_change},
+	{VPU_MSG_ID_FRAME_INPUT_DONE, vpu_session_handle_input_done},
+	{VPU_MSG_ID_FRAME_REQ, vpu_session_handle_frame_request},
+	{VPU_MSG_ID_FRAME_RELEASE, vpu_session_handle_frame_release},
+	{VPU_MSG_ID_ENC_DONE, vpu_session_handle_enc_frame_done},
+	{VPU_MSG_ID_PIC_DECODED, vpu_session_handle_pic_decoded},
+	{VPU_MSG_ID_DEC_DONE, vpu_session_handle_pic_done},
+	{VPU_MSG_ID_PIC_EOS, vpu_session_handle_eos},
+	{VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error},
+	{VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt},
+};
+
+int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *msg)
+{
+	int ret;
+	u32 msg_id;
+	struct vpu_msg_handler *handler = NULL;
+	unsigned int i;
+
+	ret = vpu_iface_convert_msg_id(inst->core, msg->hdr.id);
+	if (ret < 0)
+		return -EINVAL;
+
+	msg_id = ret;
+	inst_dbg(inst, LVL_EVT, "receive event(%d)\n", msg_id);
+
+	for (i = 0; i < ARRAY_SIZE(handlers); i++) {
+		if (handlers[i].id == msg_id) {
+			handler = &handlers[i];
+			break;
+		}
+	}
+
+	if (handler && handler->done)
+		handler->done(inst, msg);
+
+	vpu_response_cmd(inst, msg_id, 1);
+
+	return 0;
+}
+
+static bool vpu_inst_receive_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	u32 bytes = sizeof(struct vpu_rpc_event_header);
+	u32 ret;
+
+	memset(pkt, 0, sizeof(*pkt));
+	if (kfifo_len(&inst->msg_fifo) < bytes)
+		return false;
+
+	ret = kfifo_out(&inst->msg_fifo, pkt, bytes);
+	if (ret != bytes)
+		return false;
+
+	if (pkt->hdr.num > 0) {
+		bytes = pkt->hdr.num * sizeof(u32);
+		ret = kfifo_out(&inst->msg_fifo, pkt->data, bytes);
+		if (ret != bytes)
+			return false;
+	}
+
+	return true;
+}
+
+void vpu_inst_run_work(struct work_struct *work)
+{
+	struct vpu_inst *inst = container_of(work, struct vpu_inst, msg_work);
+	struct vpu_rpc_event pkt;
+
+	while (vpu_inst_receive_msg(inst, &pkt))
+		vpu_session_handle_msg(inst, &pkt);
+}
+
+void vpu_inst_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	u32 bytes;
+	u32 id = pkt->hdr.id;
+	int ret;
+
+	if (!inst->workqueue) {
+		vpu_session_handle_msg(inst, pkt);
+		return;
+	}
+
+	bytes = sizeof(pkt->hdr) + pkt->hdr.num * sizeof(u32);
+	ret = kfifo_in(&inst->msg_fifo, pkt, bytes);
+	if (ret != bytes)
+		vpu_err("[%d:%d]overflow: %d\n", inst->core->id, inst->id, id);
+	queue_work(inst->workqueue, &inst->msg_work);
+}
+
+int vpu_handle_msg(struct vpu_core *core)
+{
+	struct vpu_rpc_event pkt;
+	struct vpu_inst *inst;
+	int ret;
+
+	memset(&pkt, 0, sizeof(pkt));
+	while (!vpu_iface_receive_msg(core, &pkt)) {
+		vpu_dbg(LVL_DEBUG, "event index = %d, id = %d, num = %d\n",
+				pkt.hdr.index, pkt.hdr.id, pkt.hdr.num);
+
+		ret = vpu_iface_convert_msg_id(core, pkt.hdr.id);
+		if (ret < 0)
+			continue;
+
+		inst = vpu_core_find_instance(core, pkt.hdr.index);
+		if (inst) {
+			vpu_response_cmd(inst, ret, 0);
+			mutex_lock(&core->cmd_lock);
+			vpu_inst_record_flow(inst, ret);
+			mutex_unlock(&core->cmd_lock);
+
+			vpu_inst_handle_msg(inst, &pkt);
+			vpu_inst_put(inst);
+		}
+		memset(&pkt, 0, sizeof(pkt));
+	}
+
+	return 0;
+}
+
+int vpu_isr_thread(struct vpu_core *core, u32 irq_code)
+{
+	WARN_ON(!core);
+
+	vpu_dbg(LVL_DEBUG, "core[%d] irq code = 0x%x\n", core->id, irq_code);
+	switch (irq_code) {
+	case VPU_IRQ_CODE_SYNC:
+		vpu_mbox_send_msg(core, PRC_BUF_OFFSET, core->rpc.phys - core->fw.phys);
+		vpu_mbox_send_msg(core, BOOT_ADDRESS, core->fw.phys);
+		vpu_mbox_send_msg(core, INIT_DONE, 2);
+		break;
+	case VPU_IRQ_CODE_BOOT_DONE:
+		break;
+	case VPU_IRQ_CODE_SNAPSHOT_DONE:
+		break;
+	default:
+		vpu_handle_msg(core);
+		break;
+	}
+
+	return 0;
+}
+
+static void vpu_core_run_msg_work(struct vpu_core *core)
+{
+	const unsigned int SIZE = sizeof(u32);
+
+	while (kfifo_len(&core->msg_fifo) >= SIZE) {
+		u32 data;
+
+		if (kfifo_out(&core->msg_fifo, &data, SIZE) == SIZE)
+			vpu_isr_thread(core, data);
+	}
+}
+
+void vpu_msg_run_work(struct work_struct *work)
+{
+	struct vpu_core *core = container_of(work, struct vpu_core, msg_work);
+	unsigned long delay = msecs_to_jiffies(10);
+
+	vpu_core_run_msg_work(core);
+	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
+}
+
+void vpu_msg_delayed_work(struct work_struct *work)
+{
+	struct vpu_core *core;
+	struct delayed_work *dwork;
+	u32 bytes = sizeof(bytes);
+	u32 i;
+
+	if (!work)
+		return;
+
+	dwork = to_delayed_work(work);
+	core = container_of(dwork, struct vpu_core, msg_delayed_work);
+	if (kfifo_len(&core->msg_fifo) >= bytes)
+		vpu_core_run_msg_work(core);
+
+	bytes = sizeof(struct vpu_rpc_event_header);
+	for (i = 0; i < core->supported_instance_count; i++) {
+		struct vpu_inst *inst = vpu_core_find_instance(core, i);
+
+		if (!inst)
+			continue;
+
+		if (inst->workqueue && kfifo_len(&inst->msg_fifo) >= bytes)
+			queue_work(inst->workqueue, &inst->msg_work);
+
+		vpu_inst_put(inst);
+	}
+}
+
+
+int vpu_isr(struct vpu_core *core, u32 irq)
+{
+	WARN_ON(!core);
+
+	vpu_dbg(LVL_DEBUG, "core[%d] irq code = 0x%x\n", core->id, irq);
+	switch (irq) {
+	case VPU_IRQ_CODE_SYNC:
+		break;
+	case VPU_IRQ_CODE_BOOT_DONE:
+		complete(&core->cmp);
+		break;
+	case VPU_IRQ_CODE_SNAPSHOT_DONE:
+		complete(&core->cmp);
+		break;
+	default:
+		break;
+	}
+
+	if (kfifo_in(&core->msg_fifo, &irq, sizeof(irq)) != sizeof(irq))
+		vpu_err("[%d]overflow: %d\n", core->id, irq);
+	queue_work(core->workqueue, &core->msg_work);
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_msgs.h b/drivers/media/platform/imx/vpu-8q/vpu_msgs.h
new file mode 100644
index 000000000000..fa8117cffa5a
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_msgs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_MSGS_H
+#define _IMX_VPU_MSGS_H
+
+int vpu_isr(struct vpu_core *core, u32 irq);
+void vpu_inst_run_work(struct work_struct *work);
+void vpu_msg_run_work(struct work_struct *work);
+void vpu_msg_delayed_work(struct work_struct *work);
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:03 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:03 +0800
Subject: [PATCH v6 07/14] media: imx: imx8q: add vpu v4l2 m2m support
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <d08ef8826a78ba23bc8958f11a2acb850cfe2621.1628671163.git.ming.qian@nxp.com>

vpu_v4l2.c implements the v4l2 m2m driver methods.
vpu_helpers.c implements the common helper functions
vpu_color.c converts the v4l2 colorspace with iso

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vpu_color.c | 192 +++++
 .../media/platform/imx/vpu-8q/vpu_helpers.c   | 453 ++++++++++++
 .../media/platform/imx/vpu-8q/vpu_helpers.h   |  72 ++
 drivers/media/platform/imx/vpu-8q/vpu_v4l2.c  | 654 ++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_v4l2.h  |  44 ++
 5 files changed, 1415 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_color.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_helpers.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_helpers.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_v4l2.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_v4l2.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_color.c b/drivers/media/platform/imx/vpu-8q/vpu_color.c
new file mode 100644
index 000000000000..29d1d5edc901
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_color.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"COLOR"
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <media/v4l2-device.h>
+#include "vpu.h"
+#include "vpu_helpers.h"
+
+static const u8 colorprimaries[] = {
+	0,
+	V4L2_COLORSPACE_REC709,        /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	V4L2_COLORSPACE_470_SYSTEM_M, /*Rec. ITU-R BT.470-6 System M*/
+	V4L2_COLORSPACE_470_SYSTEM_BG,/*Rec. ITU-R BT.470-6 System B, G*/
+	V4L2_COLORSPACE_SMPTE170M,    /*SMPTE170M*/
+	V4L2_COLORSPACE_SMPTE240M,    /*SMPTE240M*/
+	0,                            /*Generic film*/
+	V4L2_COLORSPACE_BT2020,       /*Rec. ITU-R BT.2020-2*/
+	0,                            /*SMPTE ST 428-1*/
+};
+
+static const u8 colortransfers[] = {
+	0,
+	V4L2_XFER_FUNC_709,      /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	0,                       /*Rec. ITU-R BT.470-6 System M*/
+	0,                       /*Rec. ITU-R BT.470-6 System B, G*/
+	V4L2_XFER_FUNC_709,      /*SMPTE170M*/
+	V4L2_XFER_FUNC_SMPTE240M,/*SMPTE240M*/
+	V4L2_XFER_FUNC_NONE,     /*Linear transfer characteristics*/
+	0,
+	0,
+	0,                       /*IEC 61966-2-4*/
+	0,                       /*Rec. ITU-R BT.1361-0 extended colour gamut*/
+	V4L2_XFER_FUNC_SRGB,     /*IEC 61966-2-1 sRGB or sYCC*/
+	V4L2_XFER_FUNC_709,      /*Rec. ITU-R BT.2020-2 (10 bit system)*/
+	V4L2_XFER_FUNC_709,      /*Rec. ITU-R BT.2020-2 (12 bit system)*/
+	V4L2_XFER_FUNC_SMPTE2084,/*SMPTE ST 2084*/
+	0,                       /*SMPTE ST 428-1*/
+	0                        /*Rec. ITU-R BT.2100-0 hybrid log-gamma (HLG)*/
+};
+
+static const u8 colormatrixcoefs[] = {
+	0,
+	V4L2_YCBCR_ENC_709,             /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	0,                              /*Title 47 Code of Federal Regulations*/
+	V4L2_YCBCR_ENC_601,             /*Rec. ITU-R BT.601-7 625*/
+	V4L2_YCBCR_ENC_601,             /*Rec. ITU-R BT.601-7 525*/
+	V4L2_YCBCR_ENC_SMPTE240M,       /*SMPTE240M*/
+	0,
+	V4L2_YCBCR_ENC_BT2020,          /*Rec. ITU-R BT.2020-2*/
+	V4L2_YCBCR_ENC_BT2020_CONST_LUM /*Rec. ITU-R BT.2020-2 constant*/
+};
+
+u32 vpu_color_cvrt_primaries_v2i(u32 primaries)
+{
+	return VPU_ARRAY_FIND(colorprimaries, primaries);
+}
+
+u32 vpu_color_cvrt_primaries_i2v(u32 primaries)
+{
+	return VPU_ARRAY_AT(colorprimaries, primaries);
+}
+
+u32 vpu_color_cvrt_transfers_v2i(u32 transfers)
+{
+	return VPU_ARRAY_FIND(colortransfers, transfers);
+}
+
+u32 vpu_color_cvrt_transfers_i2v(u32 transfers)
+{
+	return VPU_ARRAY_AT(colortransfers, transfers);
+}
+
+u32 vpu_color_cvrt_matrix_v2i(u32 matrix)
+{
+	return VPU_ARRAY_FIND(colormatrixcoefs, matrix);
+}
+
+u32 vpu_color_cvrt_matrix_i2v(u32 matrix)
+{
+	return VPU_ARRAY_AT(colormatrixcoefs, matrix);
+}
+
+u32 vpu_color_cvrt_full_range_v2i(u32 full_range)
+{
+	return (full_range == V4L2_QUANTIZATION_FULL_RANGE);
+}
+
+u32 vpu_color_cvrt_full_range_i2v(u32 full_range)
+{
+	if (full_range)
+		return V4L2_QUANTIZATION_FULL_RANGE;
+
+	return V4L2_QUANTIZATION_LIM_RANGE;
+}
+
+int vpu_color_check_primaries(u32 primaries)
+{
+	return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_transfers(u32 transfers)
+{
+	return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_matrix(u32 matrix)
+{
+	return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_full_range(u32 full_range)
+{
+	int ret = -EINVAL;
+
+	switch (full_range) {
+	case V4L2_QUANTIZATION_FULL_RANGE:
+	case V4L2_QUANTIZATION_LIM_RANGE:
+		ret = 0;
+		break;
+	default:
+		break;
+
+	}
+
+	return ret;
+}
+
+int vpu_color_get_default(u32 primaries,
+		u32 *ptransfers, u32 *pmatrix, u32 *pfull_range)
+{
+	u32 transfers;
+	u32 matrix;
+	u32 full_range;
+
+	switch (primaries) {
+	case V4L2_COLORSPACE_REC709:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_709;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	case V4L2_COLORSPACE_470_SYSTEM_M:
+	case V4L2_COLORSPACE_470_SYSTEM_BG:
+	case V4L2_COLORSPACE_SMPTE170M:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_601;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	case V4L2_COLORSPACE_SMPTE240M:
+		transfers = V4L2_XFER_FUNC_SMPTE240M;
+		matrix = V4L2_YCBCR_ENC_SMPTE240M;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	case V4L2_COLORSPACE_BT2020:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_BT2020;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	default:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_709;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	}
+
+	if (ptransfers)
+		*ptransfers = transfers;
+	if (pmatrix)
+		*pmatrix = matrix;
+	if (pfull_range)
+		*pfull_range = full_range;
+
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_helpers.c b/drivers/media/platform/imx/vpu-8q/vpu_helpers.c
new file mode 100644
index 000000000000..e4e9771b43d3
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_helpers.c
@@ -0,0 +1,453 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"HELPER"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_rpc.h"
+#include "vpu_helpers.h"
+#include "vpu_log.h"
+
+int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x)
+{
+	int i;
+
+	for (i = 0; i < size; i++) {
+		if (array[i] == x)
+			return i;
+	}
+
+	return 0;
+}
+
+bool vpu_helper_check_type(struct vpu_inst *inst, u32 type)
+{
+	const struct vpu_format *pfmt;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (vpu_core_check_fmt(inst->core, pfmt->pixfmt))
+			continue;
+		if (pfmt->type == type)
+			return true;
+	}
+
+	return false;
+}
+
+const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt)
+{
+	const struct vpu_format *pfmt;
+
+	if (!inst || !inst->formats)
+		return NULL;
+
+	if (vpu_core_check_fmt(inst->core, pixelfmt))
+		return NULL;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (vpu_core_check_fmt(inst->core, pfmt->pixfmt))
+			continue;
+
+		if (pfmt->pixfmt == pixelfmt && (!type || type == pfmt->type))
+			return pfmt;
+	}
+
+	return NULL;
+}
+
+const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index)
+{
+	const struct vpu_format *pfmt;
+	int i = 0;
+
+	if (!inst || !inst->formats)
+		return NULL;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (vpu_core_check_fmt(inst->core, pfmt->pixfmt))
+			continue;
+
+		if (pfmt->type == type) {
+			if (index == i)
+				return pfmt;
+			i++;
+		}
+	}
+
+	return NULL;
+}
+
+u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width)
+{
+	const struct vpu_core_resources *res;
+
+	if (!inst || !inst->core || !inst->core->res)
+		return width;
+
+	res = inst->core->res;
+	if (res->max_width)
+		width = clamp(width, res->min_width, res->max_width);
+	if (res->step_width)
+		width = ALIGN(width, res->step_width);
+
+	return width;
+}
+
+u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height)
+{
+	const struct vpu_core_resources *res;
+
+	if (!inst || !inst->core || !inst->core->res)
+		return height;
+
+	res = inst->core->res;
+	if (res->max_height)
+		height = clamp(height, res->min_height, res->max_height);
+	if (res->step_height)
+		height = ALIGN(height, res->step_height);
+
+	return height;
+}
+
+u32 vpu_helper_get_frame_size(u32 fmt, u32 width, u32 height)
+{
+	switch (fmt) {
+	case V4L2_PIX_FMT_NV12:
+		return ((width * 3) >> 1) * height;
+	default:
+		return width * height;
+	}
+}
+
+u32 get_nv12_plane_size(u32 width, u32 height, int plane_no,
+			u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 bytesperline;
+	u32 size = 0;
+
+	bytesperline = ALIGN(width, stride);
+	height = ALIGN(height, 2);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	else
+		size = bytesperline * height >> 1;
+
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+u32 get_tiled_8l128_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
+			u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 ws = 3;
+	u32 hs = 7;
+	u32 bitdepth = 8;
+	u32 bytesperline;
+	u32 size = 0;
+
+	if (interlaced)
+		hs++;
+	if (fmt == V4L2_PIX_FMT_NV12_10BE_8L128)
+		bitdepth = 10;
+	bytesperline = DIV_ROUND_UP(width * bitdepth, BITS_PER_BYTE);
+	bytesperline = ALIGN(bytesperline, 1 << ws);
+	bytesperline = ALIGN(bytesperline, stride);
+	height = ALIGN(height, 1 << hs);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	else if (plane_no == 1)
+		size = (bytesperline * ALIGN(height, 1 << (hs + 1))) >> 1;
+
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+u32 get_default_plane_size(u32 width, u32 height, int plane_no,
+			u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 bytesperline;
+	u32 size = 0;
+
+	bytesperline = ALIGN(width, stride);
+	if (plane_no == 0)
+		size = bytesperline * height;
+
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+u32 vpu_helper_get_plane_size(u32 fmt, u32 w, u32 h, int plane_no,
+		u32 stride, u32 interlaced, u32 *pbl)
+{
+	switch (fmt) {
+	case V4L2_PIX_FMT_NV12:
+		return get_nv12_plane_size(w, h, plane_no, stride, interlaced, pbl);
+	case V4L2_PIX_FMT_NV12_8L128:
+	case V4L2_PIX_FMT_NV12_10BE_8L128:
+		return get_tiled_8l128_plane_size(fmt, w, h, plane_no, stride, interlaced, pbl);
+	default:
+		return get_default_plane_size(w, h, plane_no, stride, interlaced, pbl);
+	}
+}
+
+u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
+					u32 *rptr, u32 size, void *dst)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !rptr || !dst)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *rptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+
+	if (offset < start || offset > end) {
+		vpu_err("rptr 0x%x is out of range [0x%x, 0x%x]\n",
+				offset, start, end);
+		return -EINVAL;
+	}
+
+	if (offset + size <= end) {
+		memcpy(dst, virt + (offset - start), size);
+	} else {
+		memcpy(dst, virt + (offset - start), end - offset);
+		memcpy(dst + end - offset, virt, size + offset - end);
+	}
+
+	*rptr = vpu_helper_step_walk(stream_buffer, offset, size);
+	return size;
+}
+
+u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
+				u32 *wptr, u32 size, void *src)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !wptr || !src)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *wptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+	if (offset < start || offset > end) {
+		vpu_err("wptr 0x%x is out of range [0x%x, 0x%x]\n",
+				offset, start, end);
+		return -EINVAL;
+	}
+
+	if (offset + size <= end) {
+		memcpy(virt + (offset - start), src, size);
+	} else {
+		memcpy(virt + (offset - start), src, end - offset);
+		memcpy(virt, src + end - offset, size + offset - end);
+	}
+
+	*wptr = vpu_helper_step_walk(stream_buffer, offset, size);
+
+	return size;
+}
+
+u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
+				u32 *wptr, u8 val, u32 size)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !wptr)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *wptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+	if (offset < start || offset > end) {
+		vpu_err("wptr 0x%x is out of range [0x%x, 0x%x]\n",
+				offset, start, end);
+		return -EINVAL;
+	}
+
+	if (offset + size <= end) {
+		memset(virt + (offset - start), val, size);
+	} else {
+		memset(virt + (offset - start), val, end - offset);
+		memset(virt, val, size + offset - end);
+	}
+
+	offset += size;
+	if (offset >= end)
+		offset -= stream_buffer->length;
+
+	*wptr = offset;
+
+	return size;
+}
+
+u32 vpu_helper_get_free_space(struct vpu_inst *inst)
+{
+	struct vpu_rpc_buffer_desc desc;
+
+	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
+		return 0;
+
+	if (desc.rptr > desc.wptr)
+		return desc.rptr - desc.wptr;
+	else if (desc.rptr < desc.wptr)
+		return (desc.end - desc.start + desc.rptr - desc.wptr);
+	else
+		return desc.end - desc.start;
+}
+
+u32 vpu_helper_get_used_space(struct vpu_inst *inst)
+{
+	struct vpu_rpc_buffer_desc desc;
+
+	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
+		return 0;
+
+	if (desc.wptr > desc.rptr)
+		return desc.wptr - desc.rptr;
+	else if (desc.wptr < desc.rptr)
+		return (desc.end - desc.start + desc.wptr - desc.rptr);
+	else
+		return 0;
+}
+
+int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vpu_inst *inst = ctrl_to_inst(ctrl);
+
+	switch (ctrl->id) {
+	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+		ctrl->val = inst->min_buffer_cap;
+		break;
+	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
+		ctrl->val = inst->min_buffer_out;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+u32 vpu_helper_calc_coprime(u32 *a, u32 *b)
+{
+	int m = *a;
+	int n = *b;
+
+	if (m == 0)
+		return n;
+	if (n == 0)
+		return m;
+
+	while (n != 0) {
+		int tmp = m % n;
+
+		m = n;
+		n = tmp;
+	}
+	*a = (*a) / m;
+	*b = (*b) / m;
+
+	return m;
+}
+
+#define READ_BYTE(buffer, pos)	(*(u8 *)((buffer)->virt + ((pos) % buffer->length)))
+int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
+			u32 pixelformat, u32 offset, u32 bytesused)
+{
+	u32 start_code;
+	int start_code_size;
+	u32 val = 0;
+	int i;
+	int ret = -EINVAL;
+
+	if (!stream_buffer || !stream_buffer->virt)
+		return -EINVAL;
+
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_H264:
+		start_code_size = 4;
+		start_code = 0x00000001;
+		break;
+	default:
+		return 0;
+	}
+
+	for (i = 0; i < bytesused; i++) {
+		val = (val << 8) | READ_BYTE(stream_buffer, offset + i);
+		if (i < start_code_size - 1)
+			continue;
+		if (val == start_code) {
+			ret = i + 1 - start_code_size;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src)
+{
+	u32 i;
+
+	if (!pairs || !cnt)
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		if (pairs[i].src == src)
+			return pairs[i].dst;
+	}
+
+	return -EINVAL;
+}
+
+int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst)
+{
+	u32 i;
+
+	if (!pairs || !cnt)
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		if (pairs[i].dst == dst)
+			return pairs[i].src;
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_helpers.h b/drivers/media/platform/imx/vpu-8q/vpu_helpers.h
new file mode 100644
index 000000000000..8fdd6b488fae
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_helpers.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_HELPERS_H
+#define _IMX_VPU_HELPERS_H
+
+struct vpu_pair {
+	u32 src;
+	u32 dst;
+};
+
+#define MAKE_TIMESTAMP(s, ns)		(((s32)(s) * NSEC_PER_SEC) + (ns))
+#define VPU_INVALID_TIMESTAMP		MAKE_TIMESTAMP(-1, 0)
+#define	VPU_ARRAY_AT(array, i)		(((i) < ARRAY_SIZE(array)) ? array[i] : 0)
+#define VPU_ARRAY_FIND(array, x)	vpu_helper_find_in_array_u8(array, ARRAY_SIZE(array), x)
+
+int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x);
+bool vpu_helper_check_type(struct vpu_inst *inst, u32 type);
+const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt);
+const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index);
+u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width);
+u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height);
+u32 vpu_helper_get_frame_size(u32 fmt, u32 width, u32 height);
+u32 vpu_helper_get_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
+					u32 stride, u32 interlaced, u32 *pbl);
+u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
+					u32 *rptr, u32 size, void *dst);
+u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
+				u32 *wptr, u32 size, void *src);
+u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
+				u32 *wptr, u8 val, u32 size);
+u32 vpu_helper_get_free_space(struct vpu_inst *inst);
+u32 vpu_helper_get_used_space(struct vpu_inst *inst);
+int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
+u32 vpu_helper_calc_coprime(u32 *a, u32 *b);
+void vpu_helper_get_kmp_next(const u8 *pattern, int *next, int size);
+int vpu_helper_kmp_search(u8 *s, int s_len, const u8 *p, int p_len, int *next);
+int vpu_helper_kmp_search_in_stream_buffer(struct vpu_buffer *stream_buffer,
+					u32 offset, int bytesused,
+					const u8 *p, int p_len, int *next);
+int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
+			u32 pixelformat, u32 offset, u32 bytesused);
+
+static inline u32 vpu_helper_step_walk(struct vpu_buffer *stream_buffer, u32 pos, u32 step)
+{
+	pos += step;
+	if (pos > stream_buffer->phys + stream_buffer->length)
+		pos -= stream_buffer->length;
+
+	return pos;
+}
+
+int vpu_color_check_primaries(u32 primaries);
+int vpu_color_check_transfers(u32 transfers);
+int vpu_color_check_matrix(u32 matrix);
+int vpu_color_check_full_range(u32 full_range);
+u32 vpu_color_cvrt_primaries_v2i(u32 primaries);
+u32 vpu_color_cvrt_primaries_i2v(u32 primaries);
+u32 vpu_color_cvrt_transfers_v2i(u32 transfers);
+u32 vpu_color_cvrt_transfers_i2v(u32 transfers);
+u32 vpu_color_cvrt_matrix_v2i(u32 matrix);
+u32 vpu_color_cvrt_matrix_i2v(u32 matrix);
+u32 vpu_color_cvrt_full_range_v2i(u32 full_range);
+u32 vpu_color_cvrt_full_range_i2v(u32 full_range);
+int vpu_color_get_default(u32 primaries,
+		u32 *ptransfers, u32 *pmatrix, u32 *pfull_range);
+
+int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);
+int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_v4l2.c b/drivers/media/platform/imx/vpu-8q/vpu_v4l2.c
new file mode 100644
index 000000000000..b1f24f5e3922
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_v4l2.c
@@ -0,0 +1,654 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"V4L2"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include <linux/imx_vpu.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_v4l2.h"
+#include "vpu_msgs.h"
+#include "vpu_helpers.h"
+#include "vpu_log.h"
+
+void vpu_inst_lock(struct vpu_inst *inst)
+{
+	mutex_lock(&inst->lock);
+}
+
+void vpu_inst_unlock(struct vpu_inst *inst)
+{
+	mutex_unlock(&inst->lock);
+}
+
+dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no)
+{
+	return vb2_dma_contig_plane_dma_addr(vb, plane_no) +
+			vb->planes[plane_no].data_offset;
+}
+
+unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
+{
+	if (plane_no >= vb->num_planes)
+		return 0;
+	return vb2_plane_size(vb, plane_no) - vb->planes[plane_no].data_offset;
+}
+
+void vpu_v4l2_set_error(struct vpu_inst *inst)
+{
+	struct vb2_queue *src_q;
+	struct vb2_queue *dst_q;
+
+	src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	if (src_q)
+		src_q->error = 1;
+	if (dst_q)
+		dst_q->error = 1;
+}
+
+int vpu_notify_eos(struct vpu_inst *inst)
+{
+	const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_EOS
+	};
+
+	inst_dbg(inst, LVL_FLOW, "notify eos event\n");
+	v4l2_event_queue_fh(&inst->fh, &ev);
+
+	return 0;
+}
+
+int vpu_notify_source_change(struct vpu_inst *inst)
+{
+	const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_SOURCE_CHANGE,
+		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
+	};
+
+	inst_dbg(inst, LVL_FLOW, "notify source change event\n");
+	v4l2_event_queue_fh(&inst->fh, &ev);
+	return 0;
+}
+
+int vpu_notify_skip(struct vpu_inst *inst)
+{
+	const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_SKIP,
+		.u.data[0] = 0xff,
+	};
+
+	inst_dbg(inst, LVL_FLOW, "notify skip event\n");
+	v4l2_event_queue_fh(&inst->fh, &ev);
+
+	return 0;
+}
+
+int vpu_notify_codec_error(struct vpu_inst *inst)
+{
+	const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_CODEC_ERROR,
+	};
+
+	inst_dbg(inst, LVL_FLOW, "notify error event\n");
+	v4l2_event_queue_fh(&inst->fh, &ev);
+	vpu_v4l2_set_error(inst);
+
+	return 0;
+}
+
+const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst,
+		 struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	u32 type = f->type;
+	u32 stride;
+	u32 bytesperline;
+	u32 sizeimage;
+	const struct vpu_format *fmt;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, type, pixmp->pixelformat);
+	if (!fmt) {
+		fmt = vpu_helper_enum_format(inst, type, 0);
+		if (!fmt)
+			return NULL;
+		pixmp->pixelformat = fmt->pixfmt;
+	}
+
+	stride = inst->core->res->stride;
+	pixmp->width = vpu_helper_valid_frame_width(inst, pixmp->width);
+	pixmp->height = vpu_helper_valid_frame_height(inst, pixmp->height);
+	pixmp->flags = fmt->flags;
+	pixmp->num_planes = fmt->num_planes;
+	if (pixmp->field == V4L2_FIELD_ANY)
+		pixmp->field = V4L2_FIELD_NONE;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		sizeimage = vpu_helper_get_plane_size(pixmp->pixelformat,
+				pixmp->width, pixmp->height, i, stride,
+				pixmp->field == V4L2_FIELD_INTERLACED ? 1 : 0,
+				&bytesperline);
+		if ((s32)(pixmp->plane_fmt[i].bytesperline) <= 0)
+			pixmp->plane_fmt[i].bytesperline = bytesperline;
+		if ((s32)(pixmp->plane_fmt[i].sizeimage) <= 0)
+			pixmp->plane_fmt[i].sizeimage = sizeimage;
+		if (pixmp->plane_fmt[i].bytesperline < bytesperline)
+			pixmp->plane_fmt[i].bytesperline = bytesperline;
+		if (pixmp->plane_fmt[i].sizeimage <= sizeimage)
+			pixmp->plane_fmt[i].sizeimage = sizeimage;
+	}
+
+	return fmt;
+}
+
+static bool vpu_check_ready(struct vpu_inst *inst, u32 type)
+{
+	if (!inst)
+		return false;
+	if (inst->state == VPU_CODEC_STATE_DEINIT || inst->id < 0)
+		return false;
+	if (!inst->ops->check_ready)
+		return true;
+	return call_vop(inst, check_ready, type);
+}
+
+int vpu_process_output_buffer(struct vpu_inst *inst)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vpu_vb2_buffer *vpu_buf = NULL;
+
+	if (!inst)
+		return -EINVAL;
+
+	if (!vpu_check_ready(inst, inst->out_format.type))
+		return -EINVAL;
+
+	v4l2_m2m_for_each_src_buf(inst->m2m_ctx, buf) {
+		vpu_buf = container_of(buf, struct vpu_vb2_buffer, m2m_buf);
+		if (vpu_buf->state == VPU_BUF_STATE_IDLE)
+			break;
+		vpu_buf = NULL;
+	}
+
+	if (!vpu_buf)
+		return -EINVAL;
+
+	inst_dbg(inst, LVL_DEBUG, "frame id = %d / %d\n",
+			vpu_buf->m2m_buf.vb.sequence, inst->sequence);
+	return call_vop(inst, process_output, &vpu_buf->m2m_buf.vb.vb2_buf);
+}
+
+int vpu_process_capture_buffer(struct vpu_inst *inst)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vpu_vb2_buffer *vpu_buf = NULL;
+
+	if (!inst)
+		return -EINVAL;
+
+	if (!vpu_check_ready(inst, inst->cap_format.type))
+		return -EINVAL;
+
+	v4l2_m2m_for_each_dst_buf(inst->m2m_ctx, buf) {
+		vpu_buf = container_of(buf, struct vpu_vb2_buffer, m2m_buf);
+		if (vpu_buf->state == VPU_BUF_STATE_IDLE)
+			break;
+		vpu_buf = NULL;
+	}
+	if (!vpu_buf)
+		return -EINVAL;
+
+	return call_vop(inst, process_capture, &vpu_buf->m2m_buf.vb.vb2_buf);
+}
+
+struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst,
+						u32 type, u32 sequence)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		v4l2_m2m_for_each_src_buf(inst->m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->sequence == sequence)
+				break;
+			vbuf = NULL;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf(inst->m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->sequence == sequence)
+				break;
+			vbuf = NULL;
+		}
+	}
+
+	return vbuf;
+}
+
+struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst,
+						u32 type, u32 idx)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		v4l2_m2m_for_each_src_buf(inst->m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->vb2_buf.index == idx)
+				break;
+			vbuf = NULL;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf(inst->m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->vb2_buf.index == idx)
+				break;
+			vbuf = NULL;
+		}
+	}
+
+	return vbuf;
+}
+
+int vpu_get_num_buffers(struct vpu_inst *inst, u32 type)
+{
+	struct vb2_queue *q;
+
+	if (!inst || !inst->m2m_ctx)
+		return -EINVAL;
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	else
+		q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+
+	return q->num_buffers;
+}
+
+static void vpu_m2m_device_run(void *priv)
+{
+}
+
+static void vpu_m2m_job_abort(void *priv)
+{
+	struct vpu_inst *inst = priv;
+
+	v4l2_m2m_job_finish(inst->m2m_dev, inst->m2m_ctx);
+}
+
+static const struct v4l2_m2m_ops vpu_m2m_ops = {
+	.device_run = vpu_m2m_device_run,
+	.job_abort = vpu_m2m_job_abort
+};
+
+static int vpu_vb2_queue_setup(struct vb2_queue *vq,
+				unsigned int *buf_count,
+				unsigned int *plane_count,
+				unsigned int psize[],
+				struct device *allocators[])
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(vq);
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, vq->type);
+
+	if (*plane_count) {
+		if (*plane_count != cur_fmt->num_planes)
+			return -EINVAL;
+		for (i = 0; i < cur_fmt->num_planes; i++) {
+			if (psize[i] < cur_fmt->sizeimage[i])
+				return -EINVAL;
+		}
+	}
+
+	*plane_count = cur_fmt->num_planes;
+	for (i = 0; i < cur_fmt->num_planes; i++)
+		psize[i] = cur_fmt->sizeimage[i];
+
+	inst_dbg(inst, LVL_FLOW, "%s queue setup : %u; %u, %u\n",
+			vpu_type_name(vq->type),
+			*buf_count,
+			psize[0], psize[1]);
+
+	return 0;
+}
+
+static int vpu_vb2_buf_init(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+
+	return 0;
+}
+
+static void vpu_vb2_buf_cleanup(struct vb2_buffer *vb)
+{
+}
+
+static int vpu_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+	struct vpu_format *cur_fmt;
+	u32 i;
+
+	cur_fmt = vpu_get_format(inst, vb->type);
+	if (vb->num_planes != cur_fmt->num_planes)
+		return -EINVAL;
+	for (i = 0; i < cur_fmt->num_planes; i++) {
+		if (vpu_get_vb_length(vb, i) < cur_fmt->sizeimage[i]) {
+			inst_err(inst, "%s buf[%d] is invalid\n",
+					vpu_type_name(vb->type),
+					vb->index);
+			vpu_buf->state = VPU_BUF_STATE_ERROR;
+		}
+	}
+
+	return 0;
+}
+
+static void vpu_vb2_buf_finish(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_queue *q = vb->vb2_queue;
+
+	if (vbuf->flags & V4L2_BUF_FLAG_LAST)
+		vpu_notify_eos(inst);
+
+	if (list_empty(&q->done_list))
+		call_vop(inst, on_queue_empty, q->type);
+}
+
+void vpu_vb2_buffers_return(struct vpu_inst *inst,
+		unsigned int type, enum vb2_buffer_state state)
+{
+	struct vb2_v4l2_buffer *buf;
+
+	if (!inst || !inst->m2m_ctx)
+		return;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	} else {
+		while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	}
+}
+
+static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(q);
+	int ret;
+
+	vpu_inst_unlock(inst);
+	ret = vpu_inst_register(inst);
+	vpu_inst_lock(inst);
+	if (ret)
+		return ret;
+
+	vpu_inst_get(inst);
+	inst_dbg(inst, LVL_FLOW, "%s start streaming : %d\n",
+			vpu_type_name(q->type), q->num_buffers);
+	call_vop(inst, start, q->type);
+	vb2_clear_last_buffer_dequeued(q);
+
+	return 0;
+}
+
+static void vpu_vb2_stop_streaming(struct vb2_queue *q)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(q);
+
+	inst_dbg(inst, LVL_FLOW, "%s stop streaming\n", vpu_type_name(q->type));
+
+	call_vop(inst, stop, q->type);
+	vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_ERROR);
+	if (V4L2_TYPE_IS_OUTPUT(q->type))
+		inst->sequence = 0;
+
+	vpu_inst_put(inst);
+}
+
+static void vpu_vb2_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+
+	inst_dbg(inst, LVL_DEBUG, "%s buf queue\n", vpu_type_name(vb->type));
+
+	if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
+		vbuf->sequence = inst->sequence++;
+		if ((s64)vb->timestamp < 0)
+			vb->timestamp = VPU_INVALID_TIMESTAMP;
+	}
+
+	v4l2_m2m_buf_queue(inst->m2m_ctx, vbuf);
+	vpu_process_output_buffer(inst);
+	vpu_process_capture_buffer(inst);
+}
+
+static struct vb2_ops vpu_vb2_ops = {
+	.queue_setup        = vpu_vb2_queue_setup,
+	.buf_init           = vpu_vb2_buf_init,
+	.buf_cleanup        = vpu_vb2_buf_cleanup,
+	.buf_prepare        = vpu_vb2_buf_prepare,
+	.buf_finish         = vpu_vb2_buf_finish,
+	.start_streaming    = vpu_vb2_start_streaming,
+	.stop_streaming     = vpu_vb2_stop_streaming,
+	.buf_queue          = vpu_vb2_buf_queue,
+	.wait_prepare       = vb2_ops_wait_prepare,
+	.wait_finish        = vb2_ops_wait_finish,
+};
+
+static int vpu_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
+			  struct vb2_queue *dst_vq)
+{
+	struct vpu_inst *inst = priv;
+	int ret;
+
+	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	src_vq->ops = &vpu_vb2_ops;
+	src_vq->mem_ops = &vb2_dma_contig_memops;
+	if (inst->type == VPU_CORE_TYPE_DEC && inst->use_stream_buffer)
+		src_vq->mem_ops = &vb2_vmalloc_memops;
+	src_vq->drv_priv = inst;
+	src_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
+	src_vq->allow_zero_bytesused = 1;
+	src_vq->min_buffers_needed = 1;
+	src_vq->dev = inst->core->dev;
+	src_vq->lock = &inst->lock;
+	ret = vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->ops = &vpu_vb2_ops;
+	dst_vq->mem_ops = &vb2_dma_contig_memops;
+	if (inst->type == VPU_CORE_TYPE_ENC && inst->use_stream_buffer)
+		dst_vq->mem_ops = &vb2_vmalloc_memops;
+	dst_vq->drv_priv = inst;
+	dst_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
+	dst_vq->allow_zero_bytesused = 1;
+	dst_vq->min_buffers_needed = 1;
+	dst_vq->dev = inst->core->dev;
+	dst_vq->lock = &inst->lock;
+	ret = vb2_queue_init(dst_vq);
+	if (ret) {
+		vb2_queue_release(src_vq);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int vpu_v4l2_release(struct vpu_inst *inst)
+{
+	struct vpu_core *core = inst->core;
+
+	inst_dbg(inst, LVL_FLOW, "%s\n", __func__);
+
+	vpu_release_core(core);
+
+	if (inst->workqueue) {
+		cancel_work_sync(&inst->msg_work);
+		destroy_workqueue(inst->workqueue);
+		inst->workqueue = NULL;
+	}
+	if (inst->m2m_ctx) {
+		v4l2_m2m_ctx_release(inst->m2m_ctx);
+		inst->m2m_ctx = NULL;
+	}
+	if (inst->m2m_dev) {
+		v4l2_m2m_release(inst->m2m_dev);
+		inst->m2m_dev = NULL;
+	}
+
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+	mutex_destroy(&inst->lock);
+	v4l2_fh_del(&inst->fh);
+	v4l2_fh_exit(&inst->fh);
+
+	call_vop(inst, cleanup);
+
+	return 0;
+}
+
+int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu = video_drvdata(file);
+	struct video_device *vdev;
+	struct vpu_core *core = NULL;
+	int ret = 0;
+
+	WARN_ON(!file || !inst || !inst->ops);
+
+	if (inst->type == VPU_CORE_TYPE_ENC)
+		vdev = vpu->vdev_enc;
+	else
+		vdev = vpu->vdev_dec;
+
+	mutex_init(&inst->lock);
+	INIT_LIST_HEAD(&inst->cmd_q);
+
+	inst->id = VPU_INST_NULL_ID;
+	inst->release = vpu_v4l2_release;
+	inst->core = vpu_request_core(vpu, inst->type);
+
+	core = inst->core;
+	if (!core) {
+		vpu_err("there is no core for %s\n",
+			vpu_core_type_desc(inst->type));
+		return -EINVAL;
+	}
+
+	inst->min_buffer_cap = 2;
+	inst->min_buffer_out = 2;
+
+	ret = call_vop(inst, ctrl_init);
+	if (ret)
+		goto error;
+
+	inst->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops);
+	if (IS_ERR(inst->m2m_dev)) {
+		vpu_err("v4l2_m2m_init fail\n");
+		ret = PTR_ERR(inst->m2m_dev);
+		goto error;
+	}
+
+	inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev,
+					inst, vpu_m2m_queue_init);
+	if (IS_ERR(inst->m2m_ctx)) {
+		vpu_err("v4l2_m2m_ctx_init fail\n");
+		ret = PTR_ERR(inst->m2m_dev);
+		goto error;
+	}
+
+	v4l2_fh_init(&inst->fh, vdev);
+	v4l2_fh_add(&inst->fh);
+	inst->fh.ctrl_handler = &inst->ctrl_handler;
+	inst->fh.m2m_ctx = inst->m2m_ctx;
+	file->private_data = &inst->fh;
+	inst->state = VPU_CODEC_STATE_DEINIT;
+	inst->workqueue = alloc_workqueue("vpu_inst", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (inst->workqueue) {
+		INIT_WORK(&inst->msg_work, vpu_inst_run_work);
+		ret = kfifo_init(&inst->msg_fifo,
+				inst->msg_buffer,
+				roundup_pow_of_two(sizeof(inst->msg_buffer)));
+		if (ret) {
+			destroy_workqueue(inst->workqueue);
+			inst->workqueue = NULL;
+		}
+	}
+	atomic_set(&inst->ref_count, 0);
+	vpu_inst_get(inst);
+	vpu_dbg(LVL_FLOW, "open, tgid = %d, pid = %d\n", inst->tgid, inst->pid);
+
+	return 0;
+error:
+	if (inst->m2m_ctx) {
+		v4l2_m2m_ctx_release(inst->m2m_ctx);
+		inst->m2m_ctx = NULL;
+	}
+	if (inst->m2m_dev) {
+		v4l2_m2m_release(inst->m2m_dev);
+		inst->m2m_dev = NULL;
+	}
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+	vpu_release_core(inst->core);
+
+	return ret;
+}
+
+int vpu_v4l2_close(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vb2_queue *src_q;
+	struct vb2_queue *dst_q;
+
+	inst_dbg(inst, LVL_FLOW, "close\n");
+	src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	vpu_inst_lock(inst);
+	if (vb2_is_streaming(src_q))
+		v4l2_m2m_streamoff(file, inst->m2m_ctx, src_q->type);
+	if (vb2_is_streaming(dst_q))
+		v4l2_m2m_streamoff(file, inst->m2m_ctx, dst_q->type);
+	vpu_inst_unlock(inst);
+
+	call_vop(inst, release);
+	vpu_inst_unregister(inst);
+	vpu_inst_put(inst);
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_v4l2.h b/drivers/media/platform/imx/vpu-8q/vpu_v4l2.h
new file mode 100644
index 000000000000..204217b47cf5
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_v4l2.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_V4L2_H
+#define _IMX_VPU_V4L2_H
+
+void vpu_inst_lock(struct vpu_inst *inst);
+void vpu_inst_unlock(struct vpu_inst *inst);
+
+int vpu_v4l2_open(struct file *file, struct vpu_inst *inst);
+int vpu_v4l2_close(struct file *file);
+
+const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f);
+int vpu_process_output_buffer(struct vpu_inst *inst);
+int vpu_process_capture_buffer(struct vpu_inst *inst);
+struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence);
+struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx);
+void vpu_v4l2_set_error(struct vpu_inst *inst);
+int vpu_notify_eos(struct vpu_inst *inst);
+int vpu_notify_source_change(struct vpu_inst *inst);
+int vpu_notify_skip(struct vpu_inst *inst);
+int vpu_notify_codec_error(struct vpu_inst *inst);
+void vpu_vb2_buffers_return(struct vpu_inst *inst,
+		unsigned int type, enum vb2_buffer_state state);
+int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
+
+dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no);
+unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no);
+static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return &inst->out_format;
+	else
+		return &inst->cap_format;
+}
+
+static inline char *vpu_type_name(u32 type)
+{
+	return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture";
+}
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:04 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:04 +0800
Subject: [PATCH v6 08/14] media: imx: imx8q: add v4l2 m2m vpu encoder stateful
 driver
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <32aea4740a4e15fbd52be433d5ca9b35e7c1913f.1628671163.git.ming.qian@nxp.com>

This consists of video encoder implementation plus encoder controls.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/venc.c | 1383 ++++++++++++++++++++++
 1 file changed, 1383 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/venc.c

diff --git a/drivers/media/platform/imx/vpu-8q/venc.c b/drivers/media/platform/imx/vpu-8q/venc.c
new file mode 100644
index 000000000000..d210daed38fa
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/venc.c
@@ -0,0 +1,1383 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"ENC"
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/ktime.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include <linux/imx_vpu.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+
+#define VENC_OUTPUT_ENABLE	(1 << 0)
+#define VENC_CAPTURE_ENABLE	(1 << 1)
+#define VENC_ENABLE_MASK	(VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)
+#define VENC_MAX_BUF_CNT	8
+
+struct venc_t {
+	struct vpu_encode_params params;
+	u32 request_key_frame;
+	u32 input_ready;
+	u32 cpb_size;
+	bool bitrate_change;
+
+	struct vpu_buffer enc[VENC_MAX_BUF_CNT];
+	struct vpu_buffer ref[VENC_MAX_BUF_CNT];
+	struct vpu_buffer act[VENC_MAX_BUF_CNT];
+	struct list_head frames;
+	u32 frame_count;
+	u32 encode_count;
+	u32 ready_count;
+	u32 enable;
+	u32 stopped;
+
+	u32 skipped_count;
+	u32 skipped_bytes;
+
+	wait_queue_head_t wq;
+};
+
+struct venc_frame_t {
+	struct list_head list;
+	struct vpu_enc_pic_info info;
+	u32 bytesused;
+	s64 timestamp;
+};
+
+static const struct vpu_format venc_formats[] = {
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{0, 0, 0, 0},
+};
+
+static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "imx vpu encoder", sizeof(cap->driver));
+	strscpy(cap->card, "imx vpu encoder", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform: imx8q-vpu", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_format *fmt;
+
+	memset(f->reserved, 0, sizeof(f->reserved));
+	fmt = vpu_helper_enum_format(inst, f->type, f->index);
+	if (!fmt)
+		return -EINVAL;
+
+	f->pixelformat = fmt->pixfmt;
+	f->flags = fmt->flags;
+
+	return 0;
+}
+
+static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	if (!fsize || fsize->index)
+		return -EINVAL;
+
+	if (!vpu_helper_find_format(inst, 0, fsize->pixel_format))
+		return -EINVAL;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.max_width = inst->core->res->max_width;
+	fsize->stepwise.max_height = inst->core->res->max_height;
+	fsize->stepwise.min_width = inst->core->res->min_width;
+	fsize->stepwise.min_height = inst->core->res->min_height;
+	fsize->stepwise.step_width = inst->core->res->step_width;
+	fsize->stepwise.step_height = inst->core->res->step_height;
+
+	return 0;
+}
+
+static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	if (!fival || fival->index)
+		return -EINVAL;
+
+	if (!vpu_helper_find_format(inst, 0, fival->pixel_format))
+		return -EINVAL;
+
+	if (!fival->width || !fival->height)
+		return -EINVAL;
+
+	if (fival->width < inst->core->res->min_width ||
+		fival->width > inst->core->res->max_width ||
+		fival->height < inst->core->res->min_height ||
+		fival->height > inst->core->res->max_height)
+		return -EINVAL;
+
+	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
+	fival->stepwise.min.numerator = 1;
+	fival->stepwise.min.denominator = USHRT_MAX;
+	fival->stepwise.max.numerator = USHRT_MAX;
+	fival->stepwise.max.denominator = 1;
+	fival->stepwise.step.numerator = 1;
+	fival->stepwise.step.denominator = 1;
+
+	return 0;
+}
+
+static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	pixmp->pixelformat = cur_fmt->pixfmt;
+	pixmp->num_planes = cur_fmt->num_planes;
+	pixmp->width = cur_fmt->width;
+	pixmp->height = cur_fmt->height;
+	pixmp->field = cur_fmt->field;
+	pixmp->flags = cur_fmt->flags;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+	}
+
+	f->fmt.pix_mp.colorspace = venc->params.color.primaries;
+	f->fmt.pix_mp.xfer_func = venc->params.color.transfer;
+	f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix;
+	f->fmt.pix_mp.quantization = venc->params.color.full_range;
+
+	return 0;
+}
+
+static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	vpu_try_fmt_common(inst, f);
+
+	return 0;
+}
+
+static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_format *fmt;
+	struct vpu_format *cur_fmt;
+	struct vb2_queue *q;
+	struct venc_t *venc = inst->priv;
+	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+	int i;
+
+	q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+	if (vb2_is_streaming(q))
+		return -EBUSY;
+
+	fmt = vpu_try_fmt_common(inst, f);
+	if (!fmt)
+		return -EINVAL;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	cur_fmt->pixfmt = fmt->pixfmt;
+	cur_fmt->num_planes = fmt->num_planes;
+	cur_fmt->type = fmt->type;
+	cur_fmt->flags = fmt->flags;
+	cur_fmt->width = pix_mp->width;
+	cur_fmt->height = pix_mp->height;
+	for (i = 0; i < fmt->num_planes; i++) {
+		cur_fmt->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
+		cur_fmt->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
+	}
+
+	if (pix_mp->field != V4L2_FIELD_ANY)
+		cur_fmt->field = pix_mp->field;
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+		venc->params.input_format = cur_fmt->pixfmt;
+		venc->params.src_stride = cur_fmt->bytesperline[0];
+		venc->params.src_width = cur_fmt->width;
+		venc->params.src_height = cur_fmt->height;
+		venc->params.crop.left = 0;
+		venc->params.crop.top = 0;
+		venc->params.crop.width = cur_fmt->width;
+		venc->params.crop.height = cur_fmt->height;
+	} else {
+		venc->params.codec_format = cur_fmt->pixfmt;
+		venc->params.out_width = cur_fmt->width;
+		venc->params.out_height = cur_fmt->height;
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+		if (!vpu_color_check_primaries(pix_mp->colorspace)) {
+			venc->params.color.primaries = pix_mp->colorspace;
+			vpu_color_get_default(venc->params.color.primaries,
+						&venc->params.color.transfer,
+						&venc->params.color.matrix,
+						&venc->params.color.full_range);
+		}
+		if (!vpu_color_check_transfers(pix_mp->xfer_func))
+			venc->params.color.transfer = pix_mp->xfer_func;
+		if (!vpu_color_check_matrix(pix_mp->ycbcr_enc))
+			venc->params.color.matrix = pix_mp->ycbcr_enc;
+		if (!vpu_color_check_full_range(pix_mp->quantization))
+			venc->params.color.full_range = pix_mp->quantization;
+	}
+
+	pix_mp->colorspace = venc->params.color.primaries;
+	pix_mp->xfer_func = venc->params.color.transfer;
+	pix_mp->ycbcr_enc = venc->params.color.matrix;
+	pix_mp->quantization = venc->params.color.full_range;
+
+	return 0;
+}
+
+static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
+
+	if (!parm)
+		return -EINVAL;
+
+	if (!vpu_helper_check_type(inst, parm->type))
+		return -EINVAL;
+
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.readbuffers = 0;
+	timeperframe->numerator = venc->params.frame_rate_num;
+	timeperframe->denominator = venc->params.frame_rate_den;
+
+	return 0;
+}
+
+static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
+
+	if (!parm)
+		return -EINVAL;
+
+	if (!vpu_helper_check_type(inst, parm->type))
+		return -EINVAL;
+
+	if (!timeperframe->numerator)
+		timeperframe->numerator = venc->params.frame_rate_num;
+	if (!timeperframe->denominator)
+		timeperframe->denominator = venc->params.frame_rate_den;
+
+	venc->params.frame_rate_num = timeperframe->numerator;
+	venc->params.frame_rate_den = timeperframe->denominator;
+
+	vpu_helper_calc_coprime(&venc->params.frame_rate_num,
+				&venc->params.frame_rate_den);
+
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	memset(parm->parm.capture.reserved,
+			0, sizeof(parm->parm.capture.reserved));
+
+	return 0;
+}
+
+static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->out_format.width;
+		s->r.height = inst->out_format.height;
+		break;
+	case V4L2_SEL_TGT_CROP:
+		s->r = venc->params.crop;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int venc_valid_crop(struct venc_t *venc, struct vpu_core *core)
+{
+	struct v4l2_rect *rect = NULL;
+	u32 min_width;
+	u32 min_height;
+	u32 src_width;
+	u32 src_height;
+
+	rect = &venc->params.crop;
+	min_width = core->res->min_width;
+	min_height = core->res->min_height;
+	src_width = venc->params.src_width;
+	src_height = venc->params.src_height;
+
+	if (rect->width == 0 || rect->height == 0)
+		return -EINVAL;
+	if (rect->left > src_width - min_width ||
+		rect->top > src_height - min_height)
+		return -EINVAL;
+
+	rect->width = min(rect->width, src_width - rect->left);
+	rect->width = max_t(u32, rect->width, min_width);
+
+	rect->height = min(rect->height, src_height - rect->top);
+	rect->height = max_t(u32, rect->height, min_height);
+
+	return 0;
+}
+
+static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_core_resources *res = inst->core->res;
+	struct venc_t *venc = inst->priv;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return -EINVAL;
+	if (s->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	venc->params.crop.left = ALIGN(s->r.left, res->step_width);
+	venc->params.crop.top = ALIGN(s->r.top, res->step_height);
+	venc->params.crop.width = ALIGN(s->r.width, res->step_width);
+	venc->params.crop.height = ALIGN(s->r.height, res->step_height);
+	if (venc_valid_crop(venc, inst->core)) {
+		venc->params.crop.left = 0;
+		venc->params.crop.top = 0;
+		venc->params.crop.width = venc->params.src_width;
+		venc->params.crop.height = venc->params.src_height;
+	}
+
+	inst->crop = venc->params.crop;
+
+	return 0;
+}
+
+static int venc_response_eos(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_DRAIN)
+		return 0;
+
+	if (v4l2_m2m_num_src_bufs_ready(inst->m2m_ctx))
+		return 0;
+
+	if (!venc->input_ready)
+		return 0;
+
+	venc->input_ready = false;
+	inst_dbg(inst, LVL_FLOW, "stop\n");
+	ret = vpu_session_stop(inst);
+	if (ret)
+		return ret;
+	inst->state = VPU_CODEC_STATE_STOP;
+	wake_up_all(&venc->wq);
+
+	return 0;
+}
+
+static int venc_request_eos(struct vpu_inst *inst)
+{
+	inst->state = VPU_CODEC_STATE_DRAIN;
+	venc_response_eos(inst);
+
+	return 0;
+}
+
+static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd)
+{
+	struct vpu_inst *inst = to_inst(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
+	if (ret)
+		return ret;
+
+	vpu_inst_lock(inst);
+	if (cmd->cmd == V4L2_ENC_CMD_STOP) {
+		if (inst->state == VPU_CODEC_STATE_DEINIT)
+			vpu_notify_eos(inst);
+		else
+			venc_request_eos(inst);
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct v4l2_ioctl_ops venc_ioctl_ops = {
+	.vidioc_querycap               = venc_querycap,
+	.vidioc_enum_fmt_vid_cap       = venc_enum_fmt,
+	.vidioc_enum_fmt_vid_out       = venc_enum_fmt,
+	.vidioc_enum_framesizes        = venc_enum_framesizes,
+	.vidioc_enum_frameintervals    = venc_enum_frameintervals,
+	.vidioc_g_fmt_vid_cap_mplane   = venc_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane   = venc_g_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = venc_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane = venc_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane   = venc_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane   = venc_s_fmt,
+	.vidioc_g_parm                 = venc_g_parm,
+	.vidioc_s_parm                 = venc_s_parm,
+	.vidioc_g_selection            = venc_g_selection,
+	.vidioc_s_selection            = venc_s_selection,
+	.vidioc_try_encoder_cmd        = v4l2_m2m_ioctl_try_encoder_cmd,
+	.vidioc_encoder_cmd            = venc_encoder_cmd,
+	.vidioc_subscribe_event        = venc_subscribe_event,
+	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
+	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
+	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
+	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
+};
+
+static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vpu_inst *inst = ctrl_to_inst(ctrl);
+	struct venc_t *venc = inst->priv;
+	int ret = 0;
+
+	vpu_inst_lock(inst);
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		venc->params.profile = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		venc->params.level = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		venc->params.rc_mode = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		if (ctrl->val != venc->params.bitrate)
+			venc->bitrate_change = true;
+		venc->params.bitrate = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		venc->params.gop_length = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+		venc->params.bframes = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+		venc->params.i_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+		venc->params.p_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+		venc->params.b_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
+		venc->request_key_frame = 1;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
+		venc->cpb_size = ctrl->val * 1024;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
+		venc->params.sar.enable = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
+		venc->params.sar.idc = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
+		venc->params.sar.width = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
+		venc->params.sar.height = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops venc_ctrl_ops = {
+	.s_ctrl = venc_op_s_ctrl,
+	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+};
+
+static int venc_ctrl_init(struct vpu_inst *inst)
+{
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
+	if (ret)
+		return ret;
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+			V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+			~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+			  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+			  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
+			V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+			V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+			0x0,
+			V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+			0x0,
+			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_BITRATE,
+			BITRATE_MIN,
+			BITRATE_MAX,
+			BITRATE_STEP,
+			BITRATE_DEFAULT);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1);
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
+			V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
+			0x0,
+			V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
+			0, USHRT_MAX, 1, 1);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
+			0, USHRT_MAX, 1, 1);
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+			V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+			~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+			V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
+
+	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
+	if (ret) {
+		inst_err(inst, "setup ctrls fail, ret = %d\n", ret);
+		v4l2_ctrl_handler_free(&inst->ctrl_handler);
+		return ret;
+	}
+
+	return 0;
+}
+
+static bool venc_check_ready(struct vpu_inst *inst, unsigned int type)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vpu_helper_get_free_space(inst) < venc->cpb_size)
+			return false;
+		return venc->input_ready;
+	}
+
+	return true;
+}
+
+static u32 venc_get_enable_mask(u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return VENC_OUTPUT_ENABLE;
+	else
+		return VENC_CAPTURE_ENABLE;
+}
+
+static void venc_set_enable(struct venc_t *venc, u32 type, int enable)
+{
+	u32 mask = venc_get_enable_mask(type);
+
+	if (enable)
+		venc->enable |= mask;
+	else
+		venc->enable &= ~mask;
+}
+
+static u32 venc_get_enable(struct venc_t *venc, u32 type)
+{
+	return venc->enable & venc_get_enable_mask(type);
+}
+
+static void venc_input_done(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	vpu_inst_lock(inst);
+	venc->input_ready = true;
+	vpu_process_output_buffer(inst);
+	venc_response_eos(inst);
+	vpu_inst_unlock(inst);
+}
+
+/*
+ * It's hardware limitation, that there may be several bytes
+ * redundant data at the beginning of frame.
+ * For android platform, the redundant data may cause cts test fail
+ * So driver will strip them
+ */
+static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame)
+{
+	struct venc_t *venc;
+	int skipped;
+
+	if (!inst || !frame || !frame->bytesused)
+		return -EINVAL;
+
+	venc = inst->priv;
+	skipped = vpu_helper_find_startcode(&inst->stream_buffer,
+				inst->cap_format.pixfmt,
+				frame->info.wptr - inst->stream_buffer.phys,
+				frame->bytesused);
+	if (skipped > 0) {
+		frame->bytesused -= skipped;
+		frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer,
+						frame->info.wptr, skipped);
+		venc->skipped_bytes += skipped;
+		venc->skipped_count++;
+	}
+
+	return 0;
+}
+
+static int venc_get_one_encoded_frame(struct vpu_inst *inst,
+					struct venc_frame_t *frame,
+					struct vb2_v4l2_buffer *vbuf)
+{
+	struct venc_t *venc = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+
+	if (!vbuf)
+		return -EAGAIN;
+
+	if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {
+		inst_dbg(inst, LVL_DEBUG,
+				"type %d is disabled, frame sequence %d\n",
+				vbuf->vb2_buf.type, frame->info.frame_id);
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return 0;
+	}
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	if (frame->bytesused > vbuf->vb2_buf.planes[0].length) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return -ENOMEM;
+	}
+
+	venc_precheck_encoded_frame(inst, frame);
+
+	if (frame->bytesused) {
+		u32 rptr = frame->info.wptr;
+		void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
+
+		vpu_helper_copy_from_stream_buffer(&inst->stream_buffer,
+			&rptr, frame->bytesused, dst);
+		vpu_iface_update_stream_buffer(inst, rptr, 0);
+	}
+	vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);
+	vbuf->sequence = frame->info.frame_id;
+	vbuf->vb2_buf.timestamp = frame->info.timestamp;
+	vbuf->flags |= frame->info.pic_type;
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+	inst_dbg(inst, LVL_TS, "[OUTPUT TS]%32lld\n", frame->info.timestamp);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+	venc->ready_count++;
+
+	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+		inst_dbg(inst, LVL_DEBUG, "[%d]Iframe\n", frame->info.frame_id);
+
+	return 0;
+}
+
+static int venc_get_encoded_frames(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+	struct venc_frame_t *frame;
+	struct venc_frame_t *tmp;
+
+	if (!inst || !inst->priv)
+		return -EINVAL;
+
+	venc = inst->priv;
+	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
+		if (venc_get_one_encoded_frame(inst, frame,
+					v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
+			break;
+		list_del_init(&frame->list);
+		vfree(frame);
+	}
+
+	return 0;
+}
+
+static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
+{
+	struct vpu_enc_pic_info *info = arg;
+	struct venc_frame_t *frame;
+	struct venc_t *venc;
+	int ret = 0;
+
+	if (!inst || !info)
+		return -EINVAL;
+	venc = inst->priv;
+	frame = vzalloc(sizeof(*frame));
+	if (!frame)
+		return -ENOMEM;
+
+	memcpy(&frame->info, info, sizeof(frame->info));
+	frame->bytesused = info->frame_size;
+
+	vpu_inst_lock(inst);
+	list_add_tail(&frame->list, &venc->frames);
+	venc->encode_count++;
+	venc_get_encoded_frames(inst);
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static void venc_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+{
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_vb2_buffer *vpu_buf;
+
+	if (!inst || !frame)
+		return;
+
+	inst_dbg(inst, LVL_DEBUG, "buf done : type = %d, sequence = %d\n",
+			frame->type, frame->sequence);
+
+	vpu_inst_lock(inst);
+	if (!venc_get_enable(inst->priv, frame->type)) {
+		inst_dbg(inst, LVL_DEBUG,
+				"type %d is disabled, frame sequence %d\n",
+				frame->type, frame->sequence);
+		goto exit;
+	}
+	vbuf = vpu_find_buf_by_sequence(inst, frame->type, frame->sequence);
+	if (!vbuf) {
+		inst_err(inst, "can't find buf: type %d, sequence %d\n",
+				frame->type, frame->sequence);
+		goto exit;
+	}
+
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+	if (V4L2_TYPE_IS_OUTPUT(frame->type))
+		v4l2_m2m_src_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	else
+		v4l2_m2m_dst_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+exit:
+	vpu_inst_unlock(inst);
+}
+
+static int venc_append_empty_frame(struct vpu_inst *inst)
+{
+	struct venc_frame_t *frame;
+	struct venc_t *venc;
+
+	if (!inst || !inst->priv)
+		return -EINVAL;
+
+	venc = inst->priv;
+	frame = vzalloc(sizeof(*frame));
+	if (!frame)
+		return -ENOMEM;
+
+	frame->bytesused = 0;
+	frame->info.pic_type = V4L2_BUF_FLAG_LAST;
+	frame->info.frame_id = inst->sequence;
+
+	list_add_tail(&frame->list, &venc->frames);
+	venc_get_encoded_frames(inst);
+
+	return 0;
+}
+
+static void venc_stop_done(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "append empty frame\n");
+
+	vpu_inst_lock(inst);
+	venc_append_empty_frame(inst);
+	venc->stopped = true;
+	vpu_inst_unlock(inst);
+
+	wake_up_all(&venc->wq);
+}
+
+static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)
+{
+}
+
+static void venc_release(struct vpu_inst *inst)
+{
+}
+
+static void venc_cleanup(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+
+	if (!inst)
+		return;
+
+	venc = inst->priv;
+	if (venc)
+		vfree(venc);
+	inst->priv = NULL;
+	vfree(inst);
+}
+
+static int venc_start_session(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+	int stream_buffer_size;
+	int ret;
+
+	venc_set_enable(venc, type, 1);
+	if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK)
+		return 0;
+
+	vpu_iface_init_instance(inst);
+	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
+	if (stream_buffer_size > 0) {
+		inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3);
+		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
+		if (ret)
+			goto error;
+
+		inst->use_stream_buffer = true;
+		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
+	}
+
+	ret = vpu_iface_set_encode_params(inst, &venc->params, 0);
+	if (ret)
+		goto error;
+	ret = vpu_session_configure_codec(inst);
+	if (ret)
+		goto error;
+
+	inst->state = VPU_CODEC_STATE_CONFIGURED;
+	/*vpu_iface_config_memory_resource*/
+
+	/*config enc expert mode parameter*/
+	ret = vpu_iface_set_encode_params(inst, &venc->params, 1);
+	if (ret)
+		goto error;
+
+	ret = vpu_session_start(inst);
+	if (ret)
+		goto error;
+	inst->state = VPU_CODEC_STATE_STARTED;
+
+	venc->bitrate_change = false;
+	venc->input_ready = true;
+	venc->frame_count = 0;
+	venc->encode_count = 0;
+	venc->ready_count = 0;
+	venc->stopped = false;
+	vpu_process_output_buffer(inst);
+	if (venc->frame_count == 0)
+		inst_err(inst, "there is no input when starting\n");
+
+	return 0;
+error:
+	venc_set_enable(venc, type, 0);
+	inst->state = VPU_CODEC_STATE_DEINIT;
+
+	vpu_free_dma(&inst->stream_buffer);
+	return ret;
+}
+
+static void venc_cleanup_mem_resource(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+	u32 i;
+
+	WARN_ON(!inst || !inst->priv || !inst->core);
+
+	venc = inst->priv;
+
+	for (i = 0; i < ARRAY_SIZE(venc->enc); i++)
+		vpu_free_dma(&venc->enc[i]);
+	for (i = 0; i < ARRAY_SIZE(venc->ref); i++)
+		vpu_free_dma(&venc->ref[i]);
+	for (i = 0; i < ARRAY_SIZE(venc->act); i++)
+		vpu_free_dma(&venc->act[i]);
+}
+
+static void venc_request_mem_resource(struct vpu_inst *inst,
+				u32 enc_frame_size,
+				u32 enc_frame_num,
+				u32 ref_frame_size,
+				u32 ref_frame_num,
+				u32 act_frame_size,
+				u32 act_frame_num)
+{
+	struct venc_t *venc;
+	u32 i;
+	int ret;
+
+	WARN_ON(!inst || !inst->priv || !inst->core);
+
+	venc = inst->priv;
+
+	if (enc_frame_num > ARRAY_SIZE(venc->enc)) {
+		inst_err(inst, "enc num(%d) is out of range\n", enc_frame_num);
+		return;
+	}
+	if (ref_frame_num > ARRAY_SIZE(venc->ref)) {
+		inst_err(inst, "ref num(%d) is out of range\n", ref_frame_num);
+		return;
+	}
+	if (act_frame_num > ARRAY_SIZE(venc->act)) {
+		inst_err(inst, "act num(%d) is out of range\n", act_frame_num);
+		return;
+	}
+
+	for (i = 0; i < enc_frame_num; i++) {
+		venc->enc[i].length = enc_frame_size;
+		ret = vpu_alloc_dma(inst->core, &venc->enc[i]);
+		if (ret) {
+			venc_cleanup_mem_resource(inst);
+			return;
+		}
+	}
+	for (i = 0; i < ref_frame_num; i++) {
+		venc->ref[i].length = ref_frame_size;
+		ret = vpu_alloc_dma(inst->core, &venc->ref[i]);
+		if (ret) {
+			venc_cleanup_mem_resource(inst);
+			return;
+		}
+	}
+	if (act_frame_num != 1 || act_frame_size > inst->act.length) {
+		venc_cleanup_mem_resource(inst);
+		return;
+	}
+	venc->act[0].length = act_frame_size;
+	venc->act[0].phys = inst->act.phys;
+	venc->act[0].virt = inst->act.virt;
+
+	for (i = 0; i < enc_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]);
+	for (i = 0; i < ref_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]);
+	for (i = 0; i < act_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]);
+}
+
+static void venc_cleanup_frames(struct venc_t *venc)
+{
+	struct venc_frame_t *frame;
+	struct venc_frame_t *tmp;
+
+	if (!list_empty(&venc->frames))
+		vpu_dbg(LVL_DEBUG, "Warning some encoded frames are dropped\n");
+
+	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
+		list_del_init(&frame->list);
+		vfree(frame);
+	}
+}
+
+static int venc_stop_session(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+
+	venc_set_enable(venc, type, 0);
+	if (venc->enable & VENC_ENABLE_MASK)
+		return 0;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	if (inst->state != VPU_CODEC_STATE_STOP)
+		venc_request_eos(inst);
+
+	call_vop(inst, wait_prepare);
+	if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) {
+		set_bit(inst->id, &inst->core->hang_mask);
+		vpu_session_debug(inst);
+	}
+	call_vop(inst, wait_finish);
+
+	inst->state = VPU_CODEC_STATE_DEINIT;
+	venc_cleanup_frames(inst->priv);
+	vpu_free_dma(&inst->stream_buffer);
+	venc_cleanup_mem_resource(inst);
+
+	return 0;
+}
+
+static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct venc_t *venc = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_vb2_buffer *vpu_buf = NULL;
+	u32 flags;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return -EINVAL;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	if (inst->state == VPU_CODEC_STATE_STARTED)
+		inst->state = VPU_CODEC_STATE_ACTIVE;
+
+	flags = vbuf->flags;
+	if (venc->request_key_frame) {
+		vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+		venc->request_key_frame = 0;
+	}
+	if (venc->bitrate_change) {
+		vpu_session_update_parameters(inst, &venc->params);
+		venc->bitrate_change = false;
+	}
+	inst_dbg(inst, LVL_TS, "[INPUT  TS]%32lld\n", vb->timestamp);
+	vpu_iface_input_frame(inst, vb);
+	vbuf->flags = flags;
+	venc->input_ready = false;
+	venc->frame_count++;
+	vpu_buf->state = VPU_BUF_STATE_INUSE;
+
+	return 0;
+}
+
+static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct venc_t *venc;
+	struct venc_frame_t *frame = NULL;
+	struct vb2_v4l2_buffer *vbuf;
+	int ret;
+
+	venc = inst->priv;
+	if (list_empty(&venc->frames))
+		return -EINVAL;
+
+	frame = list_first_entry(&venc->frames, struct venc_frame_t, list);
+	vbuf = to_vb2_v4l2_buffer(vb);
+	v4l2_m2m_dst_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	ret = venc_get_one_encoded_frame(inst, frame, vbuf);
+	if (ret)
+		return ret;
+
+	list_del_init(&frame->list);
+	vfree(frame);
+	return 0;
+}
+
+static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct venc_t *venc = inst->priv;
+	int num = -1;
+
+	switch (i) {
+	case 0:
+		num = scnprintf(str, size, "profile = %d\n", venc->params.profile);
+		break;
+	case 1:
+		num = scnprintf(str, size, "level = %d\n", venc->params.level);
+		break;
+	case 2:
+		num = scnprintf(str, size, "fps = %d/%d\n",
+				venc->params.frame_rate_num,
+				venc->params.frame_rate_den);
+		break;
+	case 3:
+		num = scnprintf(str, size, "%d x %d -> %d x %d\n",
+				venc->params.src_width,
+				venc->params.src_height,
+				venc->params.out_width,
+				venc->params.out_height);
+		break;
+	case 4:
+		num = scnprintf(str, size, "(%d, %d)  %d x %d\n",
+				venc->params.crop.left,
+				venc->params.crop.top,
+				venc->params.crop.width,
+				venc->params.crop.height);
+		break;
+	case 5:
+		num = scnprintf(str, size,
+				"enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n",
+				venc->enable,
+				venc->frame_count, venc->encode_count,
+				venc->ready_count,
+				venc->stopped);
+		break;
+	case 6:
+		num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length);
+		break;
+	case 7:
+		num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes);
+		break;
+	case 8:
+		num = scnprintf(str, size, "rc: mode = %d, bitrate = %d, qp = %d\n",
+				venc->params.rc_mode,
+				venc->params.bitrate,
+				venc->params.i_frame_qp);
+		break;
+	case 9:
+		num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n",
+				venc->params.sar.enable,
+				venc->params.sar.idc,
+				venc->params.sar.width,
+				venc->params.sar.height);
+
+		break;
+	case 10:
+		num = scnprintf(str, size,
+				"colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n",
+				venc->params.color.primaries,
+				venc->params.color.transfer,
+				venc->params.color.matrix,
+				venc->params.color.full_range);
+		break;
+	case 11:
+		num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n",
+				venc->skipped_count, venc->skipped_bytes);
+		break;
+	default:
+		break;
+	}
+
+	return num;
+}
+
+static struct vpu_inst_ops venc_inst_ops = {
+	.ctrl_init = venc_ctrl_init,
+	.check_ready = venc_check_ready,
+	.input_done = venc_input_done,
+	.get_one_frame = venc_frame_encoded,
+	.buf_done = venc_buf_done,
+	.stop_done = venc_stop_done,
+	.event_notify = venc_event_notify,
+	.release = venc_release,
+	.cleanup = venc_cleanup,
+	.start = venc_start_session,
+	.mem_request = venc_request_mem_resource,
+	.stop = venc_stop_session,
+	.process_output = venc_process_output,
+	.process_capture = venc_process_capture,
+	.get_debug_info = venc_get_debug_info,
+	.wait_prepare = vpu_inst_unlock,
+	.wait_finish = vpu_inst_lock,
+};
+
+static void venc_init(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc;
+	struct v4l2_format f;
+	struct v4l2_streamparm parm;
+
+	venc = inst->priv;
+	venc->params.qp_min = 1;
+	venc->params.qp_max = 51;
+	venc->params.qp_min_i = 1;
+	venc->params.qp_max_i = 51;
+	venc->params.bitrate_max = BITRATE_MAX;
+	venc->params.bitrate_min = BITRATE_MIN;
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	f.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
+	venc_s_fmt(file, &inst->fh, &f);
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	venc_s_fmt(file, &inst->fh, &f);
+
+	memset(&parm, 0, sizeof(parm));
+	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	parm.parm.capture.timeperframe.numerator = 1;
+	parm.parm.capture.timeperframe.denominator = 30;
+	venc_s_parm(file, &inst->fh, &parm);
+}
+
+int venc_open(struct file *file)
+{
+	struct vpu_inst *inst;
+	struct venc_t *venc;
+	int ret;
+
+	inst = vzalloc(sizeof(*inst));
+	if (!inst)
+		return -ENOMEM;
+
+	venc = vzalloc(sizeof(*venc));
+	if (!venc) {
+		vfree(inst);
+		return -ENOMEM;
+	}
+
+	inst->ops = &venc_inst_ops;
+	inst->formats = venc_formats;
+	inst->type = VPU_CORE_TYPE_ENC;
+	inst->priv = venc;
+	INIT_LIST_HEAD(&venc->frames);
+	init_waitqueue_head(&venc->wq);
+
+	ret = vpu_v4l2_open(file, inst);
+	if (ret) {
+		vfree(venc);
+		vfree(inst);
+		return ret;
+	}
+
+	venc_init(file);
+
+	return 0;
+}
+
+static const struct v4l2_file_operations venc_fops = {
+	.owner = THIS_MODULE,
+	.open = venc_open,
+	.release = vpu_v4l2_close,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = v4l2_m2m_fop_poll,
+	.mmap = v4l2_m2m_fop_mmap,
+};
+
+int venc_create_video_device(struct vpu_dev *vpu)
+{
+	struct video_device *venc;
+	int ret;
+
+	if (!vpu)
+		return -EINVAL;
+
+	if (vpu->vdev_enc)
+		return 0;
+
+	venc = video_device_alloc();
+	if (!venc) {
+		vpu_err("alloc vpu encoder video device fail\n");
+		return -ENOMEM;
+	}
+	strscpy(venc->name, "imx-vpu-encoder", sizeof(venc->name));
+	venc->release = video_device_release;
+	venc->fops = &venc_fops;
+	venc->ioctl_ops = &venc_ioctl_ops;
+	venc->vfl_dir = VFL_DIR_M2M;
+	venc->v4l2_dev = &vpu->v4l2_dev;
+	venc->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+
+	ret = video_register_device(venc, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		video_device_release(venc);
+		return ret;
+	}
+	video_set_drvdata(venc, vpu);
+	vpu->vdev_enc = venc;
+
+	return 0;
+}
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:05 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:05 +0800
Subject: [PATCH v6 09/14] media: imx: imx8q: add v4l2 m2m vpu decoder stateful
 driver
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <9fd4468f1e1a0ba101f104329c632fa80274a439.1628671163.git.ming.qian@nxp.com>

This consists of video decoder implementation plus decoder controls.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vdec.c | 1682 ++++++++++++++++++++++
 1 file changed, 1682 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vdec.c

diff --git a/drivers/media/platform/imx/vpu-8q/vdec.c b/drivers/media/platform/imx/vpu-8q/vdec.c
new file mode 100644
index 000000000000..a974ce0a3f07
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vdec.c
@@ -0,0 +1,1682 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"DEC"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include <linux/imx_vpu.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+
+#define VDEC_FRAME_DEPTH		256
+
+struct vdec_fs_info {
+	char name[8];
+	u32 type;
+	u32 max_count;
+	u32 req_count;
+	u32 count;
+	u32 index;
+	u32 size;
+	struct vpu_buffer buffer[32];
+	u32 tag;
+};
+
+struct vdec_t {
+	u32 seq_hdr_found;
+	struct vpu_buffer udata;
+	struct vpu_decode_params params;
+	struct vpu_dec_codec_info codec_info;
+	enum vpu_codec_state state;
+
+	struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
+	u32 req_frame_count;
+	struct vdec_fs_info mbi;
+	struct vdec_fs_info dcp;
+	u32 seq_tag;
+
+	u32 decoded_frame_count;
+	u32 display_frame_count;
+	u32 eos_received;
+	u32 eos_subscribed;
+	bool is_source_changed;
+	u32 source_change;
+	u32 drain;
+	u32 ts_pre_count;
+	u32 frame_depth;
+	s64 ts_start;
+	s64 ts_input;
+	s64 timestamp;
+};
+
+static const struct vpu_format vdec_formats[] = {
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12_8L128,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12_10BE_8L128,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264_MVC,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_HEVC,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_MPEG2,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_MPEG4,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_XVID,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VP8,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H263,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{0, 0, 0, 0},
+};
+
+static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
+	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+};
+
+static int vdec_ctrl_init(struct vpu_inst *inst)
+{
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
+	if (ret)
+		return ret;
+
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+			V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+			V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
+	if (ret) {
+		inst_err(inst, "setup ctrls fail, ret = %d\n", ret);
+		v4l2_ctrl_handler_free(&inst->ctrl_handler);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int vdec_handle_eos(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+
+	if (!vdec->eos_received)
+		return 0;
+
+	if (!vdec->eos_subscribed)
+		return 0;
+
+	if (!list_empty(&dst_q->done_list))
+		return 0;
+
+	dst_q->last_buffer_dequeued = true;
+	vpu_notify_eos(inst);
+	vdec->eos_received--;
+
+	return 0;
+}
+
+static void vdec_handle_resolution_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_queue *q;
+
+	if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		return;
+	if (!vdec->source_change)
+		return;
+
+	q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	if (!list_empty(&q->done_list))
+		return;
+
+	vdec->source_change--;
+	vpu_notify_source_change(inst);
+}
+
+static int vdec_update_state(struct vpu_inst *inst,
+		enum vpu_codec_state state, u32 force)
+{
+	struct vdec_t *vdec = inst->priv;
+	enum vpu_codec_state pre_state = inst->state;
+
+	if (state == VPU_CODEC_STATE_SEEK) {
+		if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec->state = inst->state;
+		else
+			vdec->state = VPU_CODEC_STATE_ACTIVE;
+	}
+	if (inst->state != VPU_CODEC_STATE_SEEK || force)
+		inst->state = state;
+	else if (state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE;
+
+	inst_dbg(inst, LVL_FLOW, "state : %d -> %d\n", pre_state, inst->state);
+
+	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		vdec_handle_resolution_change(inst);
+
+	return 0;
+}
+
+static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "vpu B0", sizeof(cap->driver));
+	strscpy(cap->card, "imx vpu decoder", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform: imx8q-vpu", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int ret = -EINVAL;
+
+	vpu_inst_lock(inst);
+	if (!V4L2_TYPE_IS_OUTPUT(f->type) && vdec->seq_hdr_found) {
+		if (f->index == 0) {
+			f->pixelformat = inst->cap_format.pixfmt;
+			f->flags = inst->cap_format.flags;
+			ret = 0;
+		}
+	} else {
+		fmt = vpu_helper_enum_format(inst, f->type, f->index);
+		memset(f->reserved, 0, sizeof(f->reserved));
+		if (!fmt)
+			goto exit;
+
+		f->pixelformat = fmt->pixfmt;
+		f->flags = fmt->flags;
+		ret = 0;
+	}
+
+exit:
+	vpu_inst_unlock(inst);
+	return ret;
+}
+
+static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	pixmp->pixelformat = cur_fmt->pixfmt;
+	pixmp->num_planes = cur_fmt->num_planes;
+	pixmp->width = cur_fmt->width;
+	pixmp->height = cur_fmt->height;
+	pixmp->field = cur_fmt->field;
+	pixmp->flags = cur_fmt->flags;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+	}
+
+	f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+
+	inst_dbg(inst, LVL_DEBUG, "%s g_fmt: %c%c%c%c %dx%d %d,%d, %d,%d\n",
+			vpu_type_name(f->type),
+			f->fmt.pix_mp.pixelformat,
+			f->fmt.pix_mp.pixelformat >> 8,
+			f->fmt.pix_mp.pixelformat >> 16,
+			f->fmt.pix_mp.pixelformat >> 24,
+			f->fmt.pix_mp.width,
+			f->fmt.pix_mp.height,
+			pixmp->plane_fmt[0].sizeimage,
+			pixmp->plane_fmt[1].sizeimage,
+			pixmp->plane_fmt[0].bytesperline,
+			pixmp->plane_fmt[1].bytesperline);
+
+	return 0;
+}
+
+static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_try_fmt_common(inst, f);
+
+	vpu_inst_lock(inst);
+	if (vdec->seq_hdr_found) {
+		f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+		f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+		f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+		f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+	} else {
+		f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+		f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+		f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+		f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	const struct vpu_format *fmt;
+	struct vpu_format *cur_fmt;
+	struct vb2_queue *q;
+	struct vdec_t *vdec;
+	int i;
+
+	vdec = inst->priv;
+	q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+	if (vb2_is_streaming(q))
+		return -EBUSY;
+
+	fmt = vpu_try_fmt_common(inst, f);
+	if (!fmt)
+		return -EINVAL;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	vpu_inst_lock(inst);
+	cur_fmt->pixfmt = fmt->pixfmt;
+	cur_fmt->type = fmt->type;
+	if (V4L2_TYPE_IS_OUTPUT(f->type) || vdec->seq_hdr_found <= 0) {
+		cur_fmt->num_planes = fmt->num_planes;
+		cur_fmt->flags = fmt->flags;
+		cur_fmt->width = pixmp->width;
+		cur_fmt->height = pixmp->height;
+		for (i = 0; i < fmt->num_planes; i++) {
+			cur_fmt->sizeimage[i] = pixmp->plane_fmt[i].sizeimage;
+			cur_fmt->bytesperline[i] = pixmp->plane_fmt[i].bytesperline;
+		}
+		if (pixmp->field != V4L2_FIELD_ANY)
+			cur_fmt->field = pixmp->field;
+	} else {
+		pixmp->num_planes = cur_fmt->num_planes;
+		pixmp->width = cur_fmt->width;
+		pixmp->height = cur_fmt->height;
+		for (i = 0; i < pixmp->num_planes; i++) {
+			pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+			pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+		}
+		pixmp->field = cur_fmt->field;
+	}
+	if (V4L2_TYPE_IS_OUTPUT(f->type))
+		vdec->params.codec_format = cur_fmt->pixfmt;
+	else
+		vdec->params.output_format = cur_fmt->pixfmt;
+
+	if (!vdec->seq_hdr_found) {
+		vdec->codec_info.color_primaries = f->fmt.pix_mp.colorspace;
+		vdec->codec_info.transfer_chars = f->fmt.pix_mp.xfer_func;
+		vdec->codec_info.matrix_coeffs = f->fmt.pix_mp.ycbcr_enc;
+		vdec->codec_info.full_range = f->fmt.pix_mp.quantization;
+
+		inst->crop.left = 0;
+		inst->crop.top = 0;
+		inst->crop.width = cur_fmt->width;
+		inst->crop.height = cur_fmt->height;
+	} else {
+		f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+		f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+		f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+		f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+	}
+
+	vpu_inst_unlock(inst);
+
+	inst_dbg(inst, LVL_FLOW, "%s s_fmt: %c%c%c%c %dx%d %u,%u, %u,%u\n",
+			vpu_type_name(f->type),
+			f->fmt.pix_mp.pixelformat,
+			f->fmt.pix_mp.pixelformat >> 8,
+			f->fmt.pix_mp.pixelformat >> 16,
+			f->fmt.pix_mp.pixelformat >> 24,
+			f->fmt.pix_mp.width,
+			f->fmt.pix_mp.height,
+			pixmp->plane_fmt[0].sizeimage,
+			pixmp->plane_fmt[1].sizeimage,
+			pixmp->plane_fmt[0].bytesperline,
+			pixmp->plane_fmt[1].bytesperline);
+
+	return 0;
+}
+
+static int vdec_g_selection(struct file *file, void *fh,
+					struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+			s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_COMPOSE:
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE_PADDED:
+		s->r = inst->crop;
+		break;
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->cap_format.width;
+		s->r.height = inst->cap_format.height;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_drain(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!vdec->drain)
+		return 0;
+
+	if (v4l2_m2m_num_src_bufs_ready(inst->m2m_ctx))
+		return 0;
+
+	if (!vdec->params.frame_count) {
+		vpu_notify_eos(inst);
+		return 0;
+	}
+
+	vpu_iface_add_scode(inst, SCODE_PADDING_EOS);
+	vdec->params.end_flag = 1;
+	vpu_iface_set_decode_params(inst, &vdec->params, 1);
+	vdec->drain = 0;
+	inst_dbg(inst, LVL_FLOW, "append eos\n");
+
+	return 0;
+}
+
+static int vdec_cmd_stop(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "stop cmd\n");
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT) {
+		vpu_notify_eos(inst);
+	} else {
+		vdec->drain = 1;
+		vdec_drain(inst);
+	}
+
+	return 0;
+}
+
+static int vdec_decoder_cmd(struct file *file,
+		void *fh,
+		struct v4l2_decoder_cmd *cmd)
+{
+	struct vpu_inst *inst = to_inst(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
+	if (ret)
+		return ret;
+
+	vpu_inst_lock(inst);
+	switch (cmd->cmd) {
+	case V4L2_DEC_CMD_STOP:
+		vdec_cmd_stop(inst);
+		break;
+	default:
+		break;
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int vdec_subscribe_event(struct v4l2_fh *fh,
+		const struct v4l2_event_subscription *sub)
+{
+	struct vpu_inst *inst = container_of(fh, struct vpu_inst, fh);
+	struct vdec_t *vdec = inst->priv;
+
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		vdec->eos_subscribed = true;
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	case V4L2_EVENT_SOURCE_CHANGE:
+		return v4l2_src_change_event_subscribe(fh, sub);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	case V4L2_EVENT_SKIP:
+	case V4L2_EVENT_CODEC_ERROR:
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_unsubscribe_event(struct v4l2_fh *fh,
+				const struct v4l2_event_subscription *sub)
+{
+	struct vpu_inst *inst = container_of(fh, struct vpu_inst, fh);
+	struct vdec_t *vdec = inst->priv;
+	int ret;
+
+	ret = v4l2_event_unsubscribe(fh, sub);
+	if (ret)
+		return ret;
+
+	if (sub->type == V4L2_EVENT_EOS)
+		vdec->eos_subscribed = false;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
+	.vidioc_querycap               = vdec_querycap,
+	.vidioc_enum_fmt_vid_cap       = vdec_enum_fmt,
+	.vidioc_enum_fmt_vid_out       = vdec_enum_fmt,
+	.vidioc_g_fmt_vid_cap_mplane   = vdec_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane   = vdec_g_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane = vdec_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane   = vdec_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane   = vdec_s_fmt,
+	.vidioc_g_selection            = vdec_g_selection,
+	.vidioc_try_decoder_cmd        = v4l2_m2m_ioctl_try_decoder_cmd,
+	.vidioc_decoder_cmd            = vdec_decoder_cmd,
+	.vidioc_subscribe_event        = vdec_subscribe_event,
+	.vidioc_unsubscribe_event      = vdec_unsubscribe_event,
+	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
+	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
+	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
+	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
+};
+
+static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vdec->ts_pre_count >= vdec->frame_depth)
+			return false;
+		return true;
+	}
+
+	if (vdec->req_frame_count || vdec->eos_received)
+		return true;
+
+	return false;
+}
+
+static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_dec_pic_info *info = arg;
+	struct vpu_vb2_buffer *vpu_buf;
+	int ret = 0;
+
+	if (!info || info->id >= ARRAY_SIZE(vdec->slots))
+		return -EINVAL;
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec->slots[info->id];
+	if (!vpu_buf) {
+		inst_err(inst, "decoded invalid frame[%d]\n", info->id);
+		ret = -EINVAL;
+		goto exit;
+	}
+	if (vpu_buf->state == VPU_BUF_STATE_DECODED)
+		inst_dbg(inst, LVL_INFO, "buf[%d] has been decoded\n", info->id);
+	vpu_buf->state = VPU_BUF_STATE_DECODED;
+	vdec->decoded_frame_count++;
+	if (vdec->ts_pre_count >= info->consumed_count)
+		vdec->ts_pre_count -= info->consumed_count;
+	else
+		vdec->ts_pre_count = 0;
+exit:
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma)
+{
+	struct vdec_t *vdec = inst->priv;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
+		if (!vdec->slots[i])
+			continue;
+		if (luma == vdec->slots[i]->luma)
+			return vdec->slots[i];
+	}
+
+	return NULL;
+}
+
+static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!frame)
+		return;
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec_find_buffer(inst, frame->luma);
+	vpu_inst_unlock(inst);
+	if (!vpu_buf) {
+		inst_err(inst, "can't find buffer, id = %d, addr = 0x%x\n",
+				frame->id, frame->luma);
+		return;
+	}
+	if (frame->skipped) {
+		inst_dbg(inst, LVL_DEBUG, "frame skip\n");
+		vpu_notify_skip(inst);
+		return;
+	}
+
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vbuf->vb2_buf.index != frame->id)
+		inst_err(inst, "buffer id(%d, %d) dismatch\n",
+				vbuf->vb2_buf.index, frame->id);
+
+	if (vpu_buf->state != VPU_BUF_STATE_DECODED)
+		inst_err(inst, "buffer(%d) ready without decoded\n", frame->id);
+	vpu_buf->state = VPU_BUF_STATE_READY;
+	vb2_set_plane_payload(&vbuf->vb2_buf, 0, inst->cap_format.sizeimage[0]);
+	vb2_set_plane_payload(&vbuf->vb2_buf, 1, inst->cap_format.sizeimage[1]);
+	vbuf->vb2_buf.timestamp = frame->timestamp;
+	vbuf->field = inst->cap_format.field;
+	inst_dbg(inst, LVL_TS, "[OUTPUT TS]%32lld\n", frame->timestamp);
+
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+	vpu_inst_lock(inst);
+	vdec->timestamp = frame->timestamp;
+	vdec->display_frame_count++;
+	vpu_inst_unlock(inst);
+	inst_dbg(inst, LVL_DEBUG, "decoded : %d, display : %d\n",
+			vdec->decoded_frame_count, vdec->display_frame_count);
+}
+
+static void vdec_stop_done(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_inst_lock(inst);
+	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 0);
+	vdec->seq_hdr_found = 0;
+	vpu_inst_unlock(inst);
+}
+
+static bool vdec_check_source_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+	if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt)
+		return true;
+	if (inst->cap_format.width != vdec->codec_info.decoded_width)
+		return true;
+	if (inst->cap_format.height != vdec->codec_info.decoded_height)
+		return true;
+	if (vpu_get_num_buffers(inst, inst->cap_format.type) < inst->min_buffer_cap)
+		return true;
+	if (inst->crop.left != vdec->codec_info.offset_x)
+		return true;
+	if (inst->crop.top != vdec->codec_info.offset_y)
+		return true;
+	if (inst->crop.width != vdec->codec_info.width)
+		return true;
+	if (inst->crop.height != vdec->codec_info.height)
+		return true;
+	if (fmt && inst->cap_format.num_planes != fmt->num_planes)
+		return true;
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		if (inst->cap_format.bytesperline[i] != vdec->codec_info.bytesperline[i])
+			return true;
+		if (inst->cap_format.sizeimage[i] != vdec->codec_info.sizeimage[i])
+			return true;
+	}
+
+	return false;
+}
+
+static void vdec_init_fmt(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+	inst->out_format.width = vdec->codec_info.width;
+	inst->out_format.height = vdec->codec_info.height;
+	inst->cap_format.width = vdec->codec_info.decoded_width;
+	inst->cap_format.height = vdec->codec_info.decoded_height;
+	inst->cap_format.pixfmt = vdec->codec_info.pixfmt;
+	if (fmt) {
+		inst->cap_format.num_planes = fmt->num_planes;
+		inst->cap_format.flags = fmt->flags;
+	}
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		inst->cap_format.bytesperline[i] = vdec->codec_info.bytesperline[i];
+		inst->cap_format.sizeimage[i] = vdec->codec_info.sizeimage[i];
+	}
+	if (vdec->codec_info.progressive)
+		inst->cap_format.field = V4L2_FIELD_NONE;
+	else
+		inst->cap_format.field = V4L2_FIELD_INTERLACED;
+	if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT)
+		vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709;
+	if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
+		vdec->codec_info.transfer_chars = V4L2_XFER_FUNC_709;
+	if (vdec->codec_info.matrix_coeffs == V4L2_YCBCR_ENC_DEFAULT)
+		vdec->codec_info.matrix_coeffs = V4L2_YCBCR_ENC_709;
+	if (vdec->codec_info.full_range == V4L2_QUANTIZATION_DEFAULT)
+		vdec->codec_info.full_range = V4L2_QUANTIZATION_LIM_RANGE;
+}
+
+static void vdec_init_crop(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst->crop.left = vdec->codec_info.offset_x;
+	inst->crop.top = vdec->codec_info.offset_y;
+	inst->crop.width = vdec->codec_info.width;
+	inst->crop.height = vdec->codec_info.height;
+}
+
+static void vdec_init_mbi(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec->mbi.size = vdec->codec_info.mbi_size;
+	vdec->mbi.max_count = ARRAY_SIZE(vdec->mbi.buffer);
+	scnprintf(vdec->mbi.name, sizeof(vdec->mbi.name), "mbi");
+	vdec->mbi.type = MEM_RES_MBI;
+	vdec->mbi.tag = vdec->seq_tag;
+}
+
+static void vdec_init_dcp(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec->dcp.size = vdec->codec_info.dcp_size;
+	vdec->dcp.max_count = ARRAY_SIZE(vdec->dcp.buffer);
+	scnprintf(vdec->dcp.name, sizeof(vdec->dcp.name), "dcp");
+	vdec->dcp.type = MEM_RES_DCP;
+	vdec->dcp.tag = vdec->seq_tag;
+}
+
+static void vdec_request_one_fs(struct vdec_fs_info *fs)
+{
+	WARN_ON(!fs);
+
+	fs->req_count++;
+	if (fs->req_count > fs->max_count) {
+		vpu_err("error:request %s over %d\n", fs->name, fs->max_count);
+		fs->req_count = fs->max_count;
+	}
+}
+
+static int vdec_alloc_fs_buffer(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	struct vpu_buffer *buffer;
+
+	if (!inst || !fs || !fs->size)
+		return -EINVAL;
+
+	if (fs->count >= fs->req_count)
+		return -EINVAL;
+
+	buffer = &fs->buffer[fs->count];
+	if (buffer->virt && buffer->length >= fs->size)
+		return 0;
+
+	vpu_free_dma(buffer);
+	buffer->length = fs->size;
+	return vpu_alloc_dma(inst->core, buffer);
+}
+
+static void vdec_alloc_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	int ret;
+
+	while (fs->count < fs->req_count) {
+		ret = vdec_alloc_fs_buffer(inst, fs);
+		if (ret)
+			break;
+		fs->count++;
+	}
+}
+
+static void vdec_clear_fs(struct vdec_fs_info *fs)
+{
+	u32 i;
+
+	if (!fs)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(fs->buffer); i++)
+		vpu_free_dma(&fs->buffer[i]);
+	memset(fs, 0, sizeof(*fs));
+}
+
+static int vdec_response_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	struct vpu_fs_info info;
+	int ret;
+
+	if (fs->index >= fs->count)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.id = fs->index;
+	info.type = fs->type;
+	info.tag = fs->tag;
+	info.luma_addr = fs->buffer[fs->index].phys;
+	info.luma_size = fs->buffer[fs->index].length;
+	ret = vpu_session_alloc_fs(inst, &info);
+	if (ret)
+		return ret;
+
+	fs->index++;
+	return 0;
+}
+
+static int vdec_response_frame_abnormal(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_fs_info info;
+
+	if (!vdec->req_frame_count)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.type = MEM_RES_FRAME;
+	info.tag = vdec->seq_tag + 0xf0;
+	vpu_session_alloc_fs(inst, &info);
+	vdec->req_frame_count--;
+
+	return 0;
+}
+
+static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vpu_fs_info info;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_ACTIVE)
+		return -EINVAL;
+
+	if (!vdec->req_frame_count)
+		return -EINVAL;
+
+	if (!vbuf)
+		return -EINVAL;
+
+	if (vdec->slots[vbuf->vb2_buf.index]) {
+		inst_err(inst, "repeat alloc fs %d\n", vbuf->vb2_buf.index);
+		return -EINVAL;
+	}
+
+	inst_dbg(inst, LVL_DEBUG, "inst->state = %d, alloc fs %d, tag = 0x%x\n",
+		inst->state, vbuf->vb2_buf.index, vdec->seq_tag);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	memset(&info, 0, sizeof(info));
+	info.id = vbuf->vb2_buf.index;
+	info.type = MEM_RES_FRAME;
+	info.tag = vdec->seq_tag;
+	info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
+	info.luma_size = inst->cap_format.sizeimage[0];
+	info.chroma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 1);
+	info.chromau_size = inst->cap_format.sizeimage[1];
+	info.bytesperline = inst->cap_format.bytesperline[0];
+	ret = vpu_session_alloc_fs(inst, &info);
+	if (ret)
+		return ret;
+
+	vpu_buf->tag = info.tag;
+	vpu_buf->luma = info.luma_addr;
+	vpu_buf->chroma_u = info.chromau_size;
+	vpu_buf->chroma_v = 0;
+	vpu_buf->state = VPU_BUF_STATE_INUSE;
+	vdec->slots[info.id] = vpu_buf;
+	vdec->req_frame_count--;
+
+	return 0;
+}
+
+static void vdec_response_fs_request(struct vpu_inst *inst, bool force)
+{
+	struct vdec_t *vdec = inst->priv;
+	int i;
+	int ret;
+
+	if (force) {
+		for (i = vdec->req_frame_count; i > 0; i--)
+			vdec_response_frame_abnormal(inst);
+		return;
+	}
+
+	for (i = vdec->req_frame_count; i > 0; i--) {
+		ret = vpu_process_capture_buffer(inst);
+		if (ret)
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+
+	for (i = vdec->mbi.index; i < vdec->mbi.count; i++) {
+		if (vdec_response_fs(inst, &vdec->mbi))
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+	for (i = vdec->dcp.index; i < vdec->dcp.count; i++) {
+		if (vdec_response_fs(inst, &vdec->dcp))
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+}
+
+static void vdec_response_fs_release(struct vpu_inst *inst, u32 id, u32 tag)
+{
+	struct vpu_fs_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.id = id;
+	info.tag = tag;
+	vpu_session_release_fs(inst, &info);
+}
+
+static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	if (!inst || !vbuf)
+		return;
+
+	if (vbuf->vb2_buf.state != VB2_BUF_STATE_ACTIVE)
+		return;
+	if (vpu_find_buf_by_idx(inst, vbuf->vb2_buf.type, vbuf->vb2_buf.index))
+		return;
+	v4l2_m2m_buf_queue(inst->m2m_ctx, vbuf);
+}
+
+static void vdec_clear_slots(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
+		if (!vdec->slots[i])
+			continue;
+
+		vpu_buf = vdec->slots[i];
+		vbuf = &vpu_buf->m2m_buf.vb;
+		if (vpu_buf->tag == vdec->seq_tag)
+			inst_dbg(inst, LVL_WARN, "clear slot[%d], %d, %d\n",
+				i,
+				vdec->slots[i]->state,
+				vbuf->vb2_buf.state);
+
+		vdec_response_fs_release(inst, i, vpu_buf->tag);
+		vdec_recycle_buffer(inst, vbuf);
+		vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
+		vdec->slots[i] = NULL;
+	}
+}
+
+static void vdec_event_seq_hdr(struct vpu_inst *inst,
+				struct vpu_dec_codec_info *hdr)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_inst_lock(inst);
+	memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
+
+	inst_dbg(inst, LVL_FLOW, "%d x %d, crop : (%d, %d) %d x %d\n",
+			vdec->codec_info.decoded_width,
+			vdec->codec_info.decoded_height,
+			vdec->codec_info.offset_x,
+			vdec->codec_info.offset_y,
+			vdec->codec_info.width,
+			vdec->codec_info.height);
+	inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms;
+	vdec->is_source_changed = vdec_check_source_change(inst);
+	vdec_init_fmt(inst);
+	vdec_init_crop(inst);
+	vdec_init_mbi(inst);
+	vdec_init_dcp(inst);
+	if (!vdec->seq_hdr_found) {
+		vdec->seq_tag = vdec->codec_info.tag;
+		if (vdec->is_source_changed) {
+			vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+			vpu_notify_source_change(inst);
+			vdec->is_source_changed = false;
+		}
+	}
+	if (vdec->seq_tag != vdec->codec_info.tag) {
+		vdec_response_fs_request(inst, true);
+		inst_dbg(inst, LVL_DEBUG, "seq tag change: %d -> %d\n",
+				vdec->seq_tag, vdec->codec_info.tag);
+	}
+	vdec->seq_hdr_found++;
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_resolution_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "resolution change\n");
+	vpu_inst_lock(inst);
+	vdec->seq_tag = vdec->codec_info.tag;
+	vdec_clear_fs(&vdec->mbi);
+	vdec_clear_fs(&vdec->dcp);
+	vdec_clear_slots(inst);
+	vdec_init_mbi(inst);
+	vdec_init_dcp(inst);
+	if (vdec->is_source_changed) {
+		vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+		vdec->source_change++;
+		vdec_handle_resolution_change(inst);
+		vdec->is_source_changed = false;
+	}
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!fs)
+		return;
+
+	vpu_inst_lock(inst);
+
+	switch (fs->type) {
+	case MEM_RES_FRAME:
+		vdec->req_frame_count++;
+		break;
+	case MEM_RES_MBI:
+		vdec_request_one_fs(&vdec->mbi);
+		break;
+	case MEM_RES_DCP:
+		vdec_request_one_fs(&vdec->dcp);
+		break;
+	default:
+		break;
+	}
+
+	vdec_alloc_fs(inst, &vdec->mbi);
+	vdec_alloc_fs(inst, &vdec->dcp);
+
+	vdec_response_fs_request(inst, false);
+
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
+		return;
+	if (fs->type != MEM_RES_FRAME)
+		return;
+
+	if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
+		inst_err(inst, "invalid fs(%d) to release\n", fs->id);
+		return;
+	}
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec->slots[fs->id];
+	vdec->slots[fs->id] = NULL;
+
+	if (!vpu_buf) {
+		inst_dbg(inst, LVL_DEBUG, "fs[%d] has bee released\n", fs->id);
+		goto exit;
+	}
+
+	if (vpu_buf->state == VPU_BUF_STATE_DECODED) {
+		inst_dbg(inst, LVL_DEBUG, "this frame is skipped\n");
+		vpu_notify_skip(inst);
+	}
+
+	vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vpu_buf->state != VPU_BUF_STATE_READY)
+		vdec_recycle_buffer(inst, vbuf);
+
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+	vpu_process_capture_buffer(inst);
+
+exit:
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_eos(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "eos\n");
+	vpu_inst_lock(inst);
+	vdec->eos_received++;
+	vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
+	vpu_process_capture_buffer(inst);
+	vdec_handle_eos(inst);
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_notify(struct vpu_inst *inst, u32 event, void *data)
+{
+	switch (event) {
+	case VPU_MSG_ID_SEQ_HDR_FOUND:
+		vdec_event_seq_hdr(inst, data);
+		break;
+	case VPU_MSG_ID_RES_CHANGE:
+		vdec_event_resolution_change(inst);
+		break;
+	case VPU_MSG_ID_FRAME_REQ:
+		vdec_event_req_fs(inst, data);
+		break;
+	case VPU_MSG_ID_FRAME_RELEASE:
+		vdec_evnet_rel_fs(inst, data);
+		break;
+	case VPU_MSG_ID_PIC_EOS:
+		vdec_event_eos(inst);
+		break;
+	default:
+		break;
+	}
+}
+
+static int vdec_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vpu_rpc_buffer_desc desc;
+	s64 timestamp;
+	u32 free_space;
+	int ret;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	inst_dbg(inst, LVL_DEBUG, "dec output [%d] %d : %ld\n",
+		vbuf->sequence, vb->index, vb2_get_plane_payload(vb, 0));
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return -EINVAL;
+
+	if (inst->state == VPU_CODEC_STATE_STARTED)
+		vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
+
+	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
+	if (ret)
+		return ret;
+
+	free_space = vpu_helper_get_free_space(inst);
+	if (free_space < vb2_get_plane_payload(vb, 0) + 0x40000)
+		return -ENOMEM;
+
+	timestamp = vb->timestamp;
+	if (timestamp >= 0 && vdec->ts_start < 0)
+		vdec->ts_start = timestamp;
+	if (vdec->ts_input < timestamp)
+		vdec->ts_input = timestamp;
+
+	ret = vpu_iface_input_frame(inst, vb);
+	if (ret < 0)
+		return -ENOMEM;
+
+	inst_dbg(inst, LVL_TS, "[INPUT  TS]%32lld\n", vb->timestamp);
+	vdec->ts_pre_count++;
+	vdec->params.frame_count++;
+
+	v4l2_m2m_src_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+
+	if (vdec->drain)
+		vdec_drain(inst);
+
+	return 0;
+}
+
+static int vdec_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	int ret;
+
+	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		return -EINVAL;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+
+	if (vdec->eos_received) {
+		if (vdec->eos_subscribed) {
+			vdec_handle_eos(inst);
+		} else {
+			vb2_set_plane_payload(vb, 0, 0);
+			vb2_set_plane_payload(vb, 1, 0);
+			vbuf->flags |= V4L2_BUF_FLAG_LAST;
+			v4l2_m2m_dst_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+			v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+			vdec->eos_received--;
+		}
+		return 0;
+	}
+
+	ret = vdec_response_frame(inst, vbuf);
+	if (ret)
+		return ret;
+	v4l2_m2m_dst_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	return 0;
+}
+
+static void vdec_on_queue_emtpy(struct vpu_inst *inst, u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return;
+
+	vdec_handle_resolution_change(inst);
+	vdec_handle_eos(inst);
+}
+
+static void vdec_abort(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_rpc_buffer_desc desc;
+	int ret;
+
+	inst_dbg(inst, LVL_FLOW, "abort, inst->state = %d\n", inst->state);
+	vpu_iface_add_scode(inst, SCODE_PADDING_ABORT);
+	vdec->params.end_flag = 1;
+	vpu_iface_set_decode_params(inst, &vdec->params, 1);
+
+	vpu_session_abort(inst);
+
+	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
+	if (!ret)
+		vpu_iface_update_stream_buffer(inst, desc.rptr, 1);
+
+	vpu_session_rst_buf(inst);
+	inst_dbg(inst, LVL_FLOW, "input : %d, decoded : %d, display : %d\n",
+			vdec->params.frame_count,
+			vdec->decoded_frame_count,
+			vdec->display_frame_count);
+	vdec->params.end_flag = 0;
+	vdec->drain = 0;
+	vdec->ts_pre_count = 0;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+	vdec->params.frame_count = 0;
+	vdec->decoded_frame_count = 0;
+	vdec->display_frame_count = 0;
+}
+
+static void vdec_release(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "release\n");
+	vpu_inst_lock(inst);
+	vdec_clear_slots(inst);
+	if (inst->state != VPU_CODEC_STATE_DEINIT)
+		vpu_session_stop(inst);
+	vdec_clear_fs(&vdec->mbi);
+	vdec_clear_fs(&vdec->dcp);
+	vpu_free_dma(&vdec->udata);
+	vpu_free_dma(&inst->stream_buffer);
+	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 1);
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_cleanup(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec;
+
+	if (!inst)
+		return;
+
+	vdec = inst->priv;
+	if (vdec)
+		vfree(vdec);
+	inst->priv = NULL;
+	vfree(inst);
+}
+
+static void vdec_init_params(struct vdec_t *vdec)
+{
+	vdec->params.frame_count = 0;
+	vdec->params.end_flag = 0;
+}
+
+static int vdec_start(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	int stream_buffer_size;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	inst_dbg(inst, LVL_FLOW, "start\n");
+	vdec->udata.length = 0x1000;
+	ret = vpu_alloc_dma(inst->core, &vdec->udata);
+	if (ret) {
+		inst_err(inst, "alloc udata fail\n");
+		goto error;
+	}
+
+	vpu_iface_init_instance(inst);
+	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
+	if (stream_buffer_size > 0) {
+		inst->stream_buffer.length = stream_buffer_size;
+		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
+		if (ret) {
+			inst_err(inst, "alloc stream buffer fail\n");
+			goto error;
+		}
+		inst->use_stream_buffer = true;
+		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
+	}
+
+	vdec->params.udata.base = vdec->udata.phys;
+	vdec->params.udata.size = vdec->udata.length;
+	ret = vpu_iface_set_decode_params(inst, &vdec->params, 0);
+	if (ret) {
+		inst_err(inst, "set decode params fail\n");
+		goto error;
+	}
+
+	vdec_init_params(vdec);
+	ret = vpu_session_start(inst);
+	if (ret) {
+		inst_err(inst, "start fail\n");
+		goto error;
+	}
+
+	vdec_update_state(inst, VPU_CODEC_STATE_STARTED, 0);
+
+	return 0;
+error:
+	vpu_free_dma(&vdec->udata);
+	vpu_free_dma(&inst->stream_buffer);
+	return ret;
+}
+
+static int vdec_start_session(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+	int ret = 0;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT) {
+		if (V4L2_TYPE_IS_OUTPUT(type)) {
+			ret = vdec_start(inst);
+			if (ret)
+				return ret;
+		}
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (inst->state == VPU_CODEC_STATE_SEEK)
+			vdec_update_state(inst, vdec->state, 1);
+		vdec->eos_received = 0;
+		vpu_process_output_buffer(inst);
+	} else {
+		if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
+		vpu_process_capture_buffer(inst);
+	}
+	if (inst->state == VPU_CODEC_STATE_ACTIVE)
+		vdec_response_fs_request(inst, false);
+
+	return ret;
+}
+
+static int vdec_stop_session(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
+		vdec->drain = 0;
+	} else {
+		if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec_abort(inst);
+
+		vdec->eos_received = 0;
+		vdec_clear_slots(inst);
+	}
+
+	return 0;
+}
+
+static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct vdec_t *vdec = inst->priv;
+	int num = -1;
+
+	switch (i) {
+	case 0:
+		num = scnprintf(str, size,
+				"req_frame_count = %d\ninterlaced = %d\n",
+				vdec->req_frame_count,
+				vdec->codec_info.progressive ? 0 : 1);
+		break;
+	case 1:
+		num = scnprintf(str, size,
+				"mbi: size = 0x%x request = %d, alloc = %d, response = %d\n",
+				vdec->mbi.size,
+				vdec->mbi.req_count,
+				vdec->mbi.count,
+				vdec->mbi.index);
+		break;
+	case 2:
+		num = scnprintf(str, size,
+				"dcp: size = 0x%x request = %d, alloc = %d, response = %d\n",
+				vdec->dcp.size,
+				vdec->dcp.req_count,
+				vdec->dcp.count,
+				vdec->dcp.index);
+		break;
+	case 3:
+		num = scnprintf(str, size, "input_frame_count = %d\n", vdec->params.frame_count);
+		break;
+	case 4:
+		num = scnprintf(str, size, "decoded_frame_count = %d\n", vdec->decoded_frame_count);
+		break;
+	case 5:
+		num = scnprintf(str, size, "display_frame_count = %d\n", vdec->display_frame_count);
+		break;
+	case 6:
+		num = scnprintf(str, size, "drain = %d, eos = %d, source_change = %d\n",
+				vdec->drain, vdec->eos_received, vdec->source_change);
+		break;
+	case 7:
+		num = scnprintf(str, size, "ts_pre_count = %d, frame_depth = %d\n",
+				vdec->ts_pre_count, vdec->frame_depth);
+		break;
+	case 8:
+		num = scnprintf(str, size, "b_dis_reorder = %d, b_non_frame = %d\n",
+				vdec->params.b_dis_reorder,
+				vdec->params.b_non_frame);
+		break;
+	case 9:
+	{
+		s64 timestamp = vdec->timestamp;
+		s64 ts_start = vdec->ts_start;
+		s64 ts_input = vdec->ts_input;
+
+		num = scnprintf(str, size, "timestamp = %9lld.%09lld(%9lld.%09lld, %9lld.%09lld)\n",
+				timestamp / NSEC_PER_SEC,
+				timestamp % NSEC_PER_SEC,
+				ts_start / NSEC_PER_SEC,
+				ts_start % NSEC_PER_SEC,
+				ts_input / NSEC_PER_SEC,
+				ts_input % NSEC_PER_SEC);
+	}
+		break;
+	default:
+		break;
+	}
+
+	return num;
+}
+
+static struct vpu_inst_ops vdec_inst_ops = {
+	.ctrl_init = vdec_ctrl_init,
+	.check_ready = vdec_check_ready,
+	.buf_done = vdec_buf_done,
+	.get_one_frame = vdec_frame_decoded,
+	.stop_done = vdec_stop_done,
+	.event_notify = vdec_event_notify,
+	.release = vdec_release,
+	.cleanup = vdec_cleanup,
+	.start = vdec_start_session,
+	.stop = vdec_stop_session,
+	.process_output = vdec_process_output,
+	.process_capture = vdec_process_capture,
+	.on_queue_empty = vdec_on_queue_emtpy,
+	.get_debug_info = vdec_get_debug_info,
+	.wait_prepare = vpu_inst_unlock,
+	.wait_finish = vpu_inst_lock,
+};
+
+static void vdec_init(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec;
+	struct v4l2_format f;
+
+	vdec = inst->priv;
+	vdec->frame_depth = VDEC_FRAME_DEPTH;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	vdec_s_fmt(file, &inst->fh, &f);
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_8L128;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	vdec_s_fmt(file, &inst->fh, &f);
+}
+
+int vdec_open(struct file *file)
+{
+	struct vpu_inst *inst;
+	struct vdec_t *vdec;
+	int ret;
+
+	inst = vzalloc(sizeof(*inst));
+	if (!inst)
+		return -ENOMEM;
+
+	vdec = vzalloc(sizeof(*vdec));
+	if (!vdec) {
+		vfree(inst);
+		return -ENOMEM;
+	}
+
+	inst->ops = &vdec_inst_ops;
+	inst->formats = vdec_formats;
+	inst->type = VPU_CORE_TYPE_DEC;
+	inst->priv = vdec;
+
+	ret = vpu_v4l2_open(file, inst);
+	if (ret) {
+		vdec_cleanup(inst);
+		return ret;
+	}
+
+	vdec_init(file);
+
+	return 0;
+}
+
+__poll_t vdec_poll(struct file *file, poll_table *wait)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vb2_queue *src_q, *dst_q;
+	__poll_t ret;
+
+	ret = v4l2_m2m_fop_poll(file, wait);
+	src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	if (vb2_is_streaming(src_q) && !vb2_is_streaming(dst_q))
+		ret &= (~EPOLLERR);
+
+	return ret;
+}
+
+static const struct v4l2_file_operations vdec_fops = {
+	.owner = THIS_MODULE,
+	.open = vdec_open,
+	.release = vpu_v4l2_close,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = vdec_poll,
+	.mmap = v4l2_m2m_fop_mmap,
+};
+
+int vdec_create_video_device(struct vpu_dev *vpu)
+{
+	struct video_device *vdec;
+	int ret;
+
+	if (!vpu)
+		return -EINVAL;
+
+	if (vpu->vdev_dec)
+		return 0;
+
+	vdec = video_device_alloc();
+	if (!vdec) {
+		vpu_err("alloc vpu decoder video device fail\n");
+		return -ENOMEM;
+	}
+	strscpy(vdec->name, "imx-vpu-decoder", sizeof(vdec->name));
+	vdec->release = video_device_release;
+	vdec->fops = &vdec_fops;
+	vdec->ioctl_ops = &vdec_ioctl_ops;
+	vdec->vfl_dir = VFL_DIR_M2M;
+	vdec->v4l2_dev = &vpu->v4l2_dev;
+	vdec->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+
+	ret = video_register_device(vdec, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		video_device_release(vdec);
+		return ret;
+	}
+	video_set_drvdata(vdec, vpu);
+	vpu->vdev_dec = vdec;
+
+	return 0;
+}
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:06 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:06 +0800
Subject: [PATCH v6 10/14] media: imx: imx8q: implement windsor encoder rpc
 interface
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <aa51962b851fe8d0d7cafe6f13b5a2141010bacc.1628671163.git.ming.qian@nxp.com>

This part implements the windsor encoder rpc interface.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vpu_imx8q.c |  218 +++
 drivers/media/platform/imx/vpu-8q/vpu_imx8q.h |  116 ++
 .../media/platform/imx/vpu-8q/vpu_windsor.c   | 1244 +++++++++++++++++
 .../media/platform/imx/vpu-8q/vpu_windsor.h   |   39 +
 4 files changed, 1617 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_imx8q.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_imx8q.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_windsor.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_windsor.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_imx8q.c b/drivers/media/platform/imx/vpu-8q/vpu_imx8q.c
new file mode 100644
index 000000000000..0ec840f07e77
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_imx8q.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"IMX8Q"
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_imx8q.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+
+#define IMX8Q_CSR_CM0Px_ADDR_OFFSET			0x00000000
+#define IMX8Q_CSR_CM0Px_CPUWAIT				0x00000004
+
+#ifdef CONFIG_IMX_SCU
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/svc/misc.h>
+
+#define VPU_DISABLE_BITS			0x7
+#define VPU_IMX_DECODER_FUSE_OFFSET		14
+#define VPU_ENCODER_MASK			0x1
+#define VPU_DECODER_MASK			0x3UL
+#define VPU_DECODER_H264_MASK			0x2UL
+#define VPU_DECODER_HEVC_MASK			0x1UL
+
+static u32 imx8q_fuse;
+
+struct vpu_sc_msg_misc {
+	struct imx_sc_rpc_msg hdr;
+	u32 word;
+} __packed;
+#endif
+
+int vpu_imx8q_set_system_cfg_common(struct vpu_rpc_system_config *config,
+		u32 regs, u32 core_id)
+{
+	if (!config)
+		return -EINVAL;
+
+	switch (core_id) {
+	case 0:
+		config->malone_base_addr[0] = regs + DEC_MFD_XREG_SLV_BASE;
+		config->num_malones = 1;
+		config->num_windsors = 0;
+		break;
+	case 1:
+		config->windsor_base_addr[0] = regs + ENC_MFD_XREG_SLV_0_BASE;
+		config->num_windsors = 1;
+		config->num_malones = 0;
+		break;
+	case 2:
+		config->windsor_base_addr[0] = regs + ENC_MFD_XREG_SLV_1_BASE;
+		config->num_windsors = 1;
+		config->num_malones = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (config->num_windsors) {
+		config->windsor_irq_pin[0x0][0x0] = WINDSOR_PAL_IRQ_PIN_L;
+		config->windsor_irq_pin[0x0][0x1] = WINDSOR_PAL_IRQ_PIN_H;
+	}
+
+	config->malone_base_addr[0x1] = 0x0;
+	config->hif_offset[0x0] = MFD_HIF;
+	config->hif_offset[0x1] = 0x0;
+
+	config->dpv_base_addr = 0x0;
+	config->dpv_irq_pin = 0x0;
+	config->pixif_base_addr = regs + DEC_MFD_XREG_SLV_BASE + MFD_PIX_IF;
+	config->cache_base_addr[0] = regs + MC_CACHE_0_BASE;
+	config->cache_base_addr[1] = regs + MC_CACHE_1_BASE;
+
+	return 0;
+}
+
+int vpu_imx8q_boot_core(struct vpu_core *core)
+{
+	csr_writel(core, IMX8Q_CSR_CM0Px_ADDR_OFFSET, core->fw.phys);
+	csr_writel(core, IMX8Q_CSR_CM0Px_CPUWAIT, 0);
+	return 0;
+}
+
+int vpu_imx8q_get_power_state(struct vpu_core *core)
+{
+	if (csr_readl(core, IMX8Q_CSR_CM0Px_CPUWAIT) == 1)
+		return 0;
+	return 1;
+}
+
+int vpu_imx8q_on_firmware_loaded(struct vpu_core *core)
+{
+	u8 *p;
+
+	p = core->fw.virt;
+	p[16] = core->vpu->res->plat_type;
+	p[17] = core->id;
+	p[18] = 1;
+
+	return 0;
+}
+
+u32 vpu_imx8q_check_memory_region(dma_addr_t base, dma_addr_t addr, u32 size)
+{
+	const struct vpu_rpc_region_t imx8q_regions[] = {
+		{0x00000000, 0x08000000, VPU_CORE_MEMORY_CACHED},
+		{0x08000000, 0x10000000, VPU_CORE_MEMORY_UNCACHED},
+		{0x10000000, 0x20000000, VPU_CORE_MEMORY_CACHED},
+		{0x20000000, 0x40000000, VPU_CORE_MEMORY_UNCACHED}
+	};
+	int i;
+
+	if (addr < base)
+		return VPU_CORE_MEMORY_INVALID;
+
+	addr -= base;
+	for (i = 0; i < ARRAY_SIZE(imx8q_regions); i++) {
+		const struct vpu_rpc_region_t *region = &imx8q_regions[i];
+
+		if (addr >= region->start && addr + size < region->end)
+			return region->type;
+	}
+
+	return VPU_CORE_MEMORY_INVALID;
+}
+
+#ifdef CONFIG_IMX_SCU
+u32 vpu_imx8q_get_fuse(void)
+{
+	static u32 fuse_got;
+	struct imx_sc_ipc *ipc;
+	struct vpu_sc_msg_misc msg;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	if (fuse_got)
+		return imx8q_fuse;
+
+	ret = imx_scu_get_handle(&ipc);
+	if (ret) {
+		vpu_err("error: scu get handle fail: %d\n", ret);
+		return 0;
+	}
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_MISC;
+	hdr->func = IMX_SC_MISC_FUNC_OTP_FUSE_READ;
+	hdr->size = 2;
+
+	msg.word = VPU_DISABLE_BITS;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return 0;
+
+	imx8q_fuse = msg.word;
+	fuse_got = 1;
+	vpu_dbg(LVL_INFO, "imx8q fuse = 0x%x\n", imx8q_fuse);
+	return imx8q_fuse;
+}
+
+bool vpu_imx8q_check_codec(enum vpu_core_type type)
+{
+	u32 fuse = vpu_imx8q_get_fuse();
+
+	if (type == VPU_CORE_TYPE_ENC) {
+		if (fuse & VPU_ENCODER_MASK)
+			return false;
+	} else if (type == VPU_CORE_TYPE_DEC) {
+		fuse >>= VPU_IMX_DECODER_FUSE_OFFSET;
+		fuse &= VPU_DECODER_MASK;
+
+		if (fuse == VPU_DECODER_MASK)
+			return false;
+	}
+	return true;
+}
+
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt)
+{
+	u32 fuse = vpu_imx8q_get_fuse();
+
+	if (type == VPU_CORE_TYPE_DEC) {
+		fuse >>= VPU_IMX_DECODER_FUSE_OFFSET;
+		fuse &= VPU_DECODER_MASK;
+
+		if (fuse == VPU_DECODER_HEVC_MASK && pixelfmt == V4L2_PIX_FMT_HEVC)
+			return false;
+		if (fuse == VPU_DECODER_H264_MASK && pixelfmt == V4L2_PIX_FMT_H264)
+			return false;
+		if (fuse == VPU_DECODER_MASK)
+			return false;
+	}
+
+	return true;
+}
+#else
+bool vpu_imx8q_check_codec(enum vpu_core_type type)
+{
+	return true;
+}
+
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt)
+{
+	return true;
+}
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_imx8q.h b/drivers/media/platform/imx/vpu-8q/vpu_imx8q.h
new file mode 100644
index 000000000000..e8b1fa1da9c0
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_imx8q.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_8Q_H
+#define _IMX_VPU_8Q_H
+
+#define SCB_XREG_SLV_BASE                               0x00000000
+#define SCB_SCB_BLK_CTRL                                0x00070000
+#define SCB_BLK_CTRL_XMEM_RESET_SET                     0x00000090
+#define SCB_BLK_CTRL_CACHE_RESET_SET                    0x000000A0
+#define SCB_BLK_CTRL_CACHE_RESET_CLR                    0x000000A4
+#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET                 0x00000100
+
+#define XMEM_CONTROL                                    0x00041000
+
+#define	MC_CACHE_0_BASE					0x00060000
+#define	MC_CACHE_1_BASE					0x00068000
+
+#define DEC_MFD_XREG_SLV_BASE                           0x00180000
+#define ENC_MFD_XREG_SLV_0_BASE				0x00800000
+#define ENC_MFD_XREG_SLV_1_BASE				0x00A00000
+
+#define MFD_HIF                                         0x0001C000
+#define MFD_HIF_MSD_REG_INTERRUPT_STATUS                0x00000018
+#define MFD_SIF                                         0x0001D000
+#define MFD_SIF_CTRL_STATUS                             0x000000F0
+#define MFD_SIF_INTR_STATUS                             0x000000F4
+#define MFD_MCX                                         0x00020800
+#define MFD_MCX_OFF                                     0x00000020
+#define MFD_PIX_IF					0x00020000
+
+#define MFD_BLK_CTRL                                    0x00030000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_SET                  0x00000000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR                  0x00000004
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET           0x00000100
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR           0x00000104
+
+#define VID_API_NUM_STREAMS				8
+#define VID_API_MAX_BUF_PER_STR				3
+#define VID_API_MAX_NUM_MVC_VIEWS			4
+#define MEDIAIP_MAX_NUM_MALONES				2
+#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS			2
+#define MEDIAIP_MAX_NUM_WINDSORS			1
+#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS		2
+#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS			2
+#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS			1
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS			4
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS			4
+
+#define WINDSOR_PAL_IRQ_PIN_L				0x4
+#define WINDSOR_PAL_IRQ_PIN_H				0x5
+
+struct vpu_rpc_system_config {
+	u32 cfg_cookie;
+
+	u32 num_malones;
+	u32 malone_base_addr[MEDIAIP_MAX_NUM_MALONES];
+	u32 hif_offset[MEDIAIP_MAX_NUM_MALONES];
+	u32 malone_irq_pin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+	u32 malone_irq_target[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+
+	u32 num_windsors;
+	u32 windsor_base_addr[MEDIAIP_MAX_NUM_WINDSORS];
+	u32 windsor_irq_pin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+	u32 windsor_irq_target[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+
+	u32 cmd_irq_pin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+	u32 cmd_irq_target[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+
+	u32 msg_irq_pin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+	u32 msg_irq_target[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+
+	u32 sys_clk_freq;
+	u32 num_timers;
+	u32 timer_base_addr;
+	u32 timer_irq_pin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+	u32 timer_irq_target[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+	u32 timer_slots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
+
+	u32 gic_base_addr;
+	u32 uart_base_addr;
+
+	u32 dpv_base_addr;
+	u32 dpv_irq_pin;
+	u32 dpv_irq_target;
+
+	u32 pixif_base_addr;
+
+	u32 pal_trace_level;
+	u32 pal_trace_destination;
+
+	u32 pal_trace_level1;
+	u32 pal_trace_destination1;
+
+	u32 uHeapBase;
+	u32 uHeapSize;
+
+	u32 cache_base_addr[2];
+};
+
+int vpu_imx8q_setup_dec(struct vpu_dev *vpu);
+int vpu_imx8q_setup_enc(struct vpu_dev *vpu);
+int vpu_imx8q_setup(struct vpu_dev *vpu);
+int vpu_imx8q_reset(struct vpu_dev *vpu);
+int vpu_imx8q_set_system_cfg_common(struct vpu_rpc_system_config *config,
+		u32 regs, u32 core_id);
+int vpu_imx8q_boot_core(struct vpu_core *core);
+int vpu_imx8q_get_power_state(struct vpu_core *core);
+int vpu_imx8q_on_firmware_loaded(struct vpu_core *core);
+u32 vpu_imx8q_check_memory_region(dma_addr_t base, dma_addr_t addr, u32 size);
+bool vpu_imx8q_check_codec(enum vpu_core_type type);
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_windsor.c b/drivers/media/platform/imx/vpu-8q/vpu_windsor.c
new file mode 100644
index 000000000000..fbd2c1a37aa9
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_windsor.c
@@ -0,0 +1,1244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"WINDSOR"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_v4l2.h"
+#include "vpu_log.h"
+#include "vpu_imx8q.h"
+#include "vpu_windsor.h"
+
+#define CMD_SIZE				2560
+#define MSG_SIZE				25600
+#define WINDSOR_USER_DATA_WORDS			16
+#define WINDSOR_MAX_SRC_FRAMES			0x6
+#define WINDSOR_MAX_REF_FRAMES			0x3
+#define WINDSOR_BITRATE_UNIT			1024
+#define WINDSOR_H264_EXTENDED_SAR		255
+
+enum {
+	GTB_ENC_CMD_NOOP        = 0x0,
+	GTB_ENC_CMD_STREAM_START,
+	GTB_ENC_CMD_FRAME_ENCODE,
+	GTB_ENC_CMD_FRAME_SKIP,
+	GTB_ENC_CMD_STREAM_STOP,
+	GTB_ENC_CMD_PARAMETER_UPD,
+	GTB_ENC_CMD_TERMINATE,
+	GTB_ENC_CMD_SNAPSHOT,
+	GTB_ENC_CMD_ROLL_SNAPSHOT,
+	GTB_ENC_CMD_LOCK_SCHEDULER,
+	GTB_ENC_CMD_UNLOCK_SCHEDULER,
+	GTB_ENC_CMD_CONFIGURE_CODEC,
+	GTB_ENC_CMD_DEAD_MARK,
+	GTB_ENC_CMD_FIRM_RESET,
+	GTB_ENC_CMD_FW_STATUS,
+	GTB_ENC_CMD_RESERVED
+};
+
+enum {
+	VID_API_EVENT_UNDEFINED = 0x0,
+	VID_API_ENC_EVENT_RESET_DONE = 0x1,
+	VID_API_ENC_EVENT_START_DONE,
+	VID_API_ENC_EVENT_STOP_DONE,
+	VID_API_ENC_EVENT_TERMINATE_DONE,
+	VID_API_ENC_EVENT_FRAME_INPUT_DONE,
+	VID_API_ENC_EVENT_FRAME_DONE,
+	VID_API_ENC_EVENT_FRAME_RELEASE,
+	VID_API_ENC_EVENT_PARA_UPD_DONE,
+	VID_API_ENC_EVENT_MEM_REQUEST,
+	VID_API_ENC_EVENT_FIRMWARE_XCPT,
+	VID_API_ENC_EVENT_RESERVED
+};
+
+enum {
+	MEDIAIP_ENC_PIC_TYPE_B_FRAME = 0,
+	MEDIAIP_ENC_PIC_TYPE_P_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_I_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_IDR_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_BI_FRAME
+};
+
+struct windsor_iface {
+	u32 exec_base_addr;
+	u32 exec_area_size;
+	struct vpu_rpc_buffer_desc cmd_buffer_desc;
+	struct vpu_rpc_buffer_desc msg_buffer_desc;
+	u32 cmd_int_enable[VID_API_NUM_STREAMS];
+	u32 fw_version;
+	u32 mvd_fw_offset;
+	u32 max_streams;
+	u32 ctrl_iface[VID_API_NUM_STREAMS];
+	struct vpu_rpc_system_config system_config;
+	u32 api_version;
+	struct vpu_rpc_buffer_desc log_buffer_desc;
+};
+
+struct windsor_ctrl_iface {
+	u32 enc_yuv_buffer_desc;
+	u32 enc_stream_buffer_desc;
+	u32 enc_expert_mode_param;
+	u32 enc_param;
+	u32 enc_mem_pool;
+	u32 enc_encoding_status;
+	u32 enc_dsa_status;
+};
+
+struct vpu_enc_yuv_desc {
+	u32 frame_id;
+	u32 luma_base;
+	u32 chroma_base;
+	u32 param_idx;
+	u32 key_frame;
+};
+
+struct vpu_enc_calib_params {
+	u32 use_ame;
+
+	u32 cme_mvx_max;
+	u32 cme_mvy_max;
+	u32 ame_prefresh_y0;
+	u32 ame_prefresh_y1;
+	u32 fme_min_sad;
+	u32 cme_min_sad;
+
+	u32 fme_pred_int_weight;
+	u32 fme_pred_hp_weight;
+	u32 fme_pred_qp_weight;
+	u32 fme_cost_weight;
+	u32 fme_act_thold;
+	u32 fme_sad_thold;
+	u32 fme_zero_sad_thold;
+
+	u32 fme_lrg_mvx_lmt;
+	u32 fme_lrg_mvy_lmt;
+	u32 fme_force_mode;
+	u32 fme_force4mvcost;
+	u32 fme_force2mvcost;
+
+	u32 h264_inter_thrd;
+
+	u32 i16x16_mode_cost;
+	u32 i4x4_mode_lambda;
+	u32 i8x8_mode_lambda;
+
+	u32 inter_mod_mult;
+	u32 inter_sel_mult;
+	u32 inter_bid_cost;
+	u32 inter_bwd_cost;
+	u32 inter_4mv_cost;
+	s32 one_mv_i16_cost;
+	s32 one_mv_i4x4_cost;
+	s32 one_mv_i8x8_cost;
+	s32 two_mv_i16_cost;
+	s32 two_mv_i4x4_cost;
+	s32 two_mv_i8x8_cost;
+	s32 four_mv_i16_cost;
+	s32 four_mv_i4x4_cost;
+	s32 four_mv_i8x8_cost;
+
+	u32 intra_pred_enab;
+	u32 intra_chr_pred;
+	u32 intra16_pred;
+	u32 intra4x4_pred;
+	u32 intra8x8_pred;
+
+	u32 cb_base;
+	u32 cb_size;
+	u32 cb_head_room;
+
+	u32 mem_page_width;
+	u32 mem_page_height;
+	u32 mem_total_size;
+	u32 mem_chunk_phys_addr;
+	u32 mem_chunk_virt_addr;
+	u32 mem_chunk_size;
+	u32 mem_y_stride;
+	u32 mem_uv_stride;
+
+	u32 split_wr_enab;
+	u32 split_wr_req_size;
+	u32 split_rd_enab;
+	u32 split_rd_req_size;
+};
+
+struct vpu_enc_config_params {
+	u32 param_change;
+	u32 start_frame;
+	u32 end_frame;
+	u32 userdata_enable;
+	u32 userdata_id[4];
+	u32 userdata_message[WINDSOR_USER_DATA_WORDS];
+	u32 userdata_length;
+	u32 h264_profile_idc;
+	u32 h264_level_idc;
+	u32 h264_au_delimiter;
+	u32 h264_seq_end_code;
+	u32 h264_recovery_points;
+	u32 h264_vui_parameters;
+	u32 h264_aspect_ratio_present;
+	u32 h264_aspect_ratio_sar_width;
+	u32 h264_aspect_ratio_sar_height;
+	u32 h264_overscan_present;
+	u32 h264_video_type_present;
+	u32 h264_video_format;
+	u32 h264_video_full_range;
+	u32 h264_video_colour_descriptor;
+	u32 h264_video_colour_primaries;
+	u32 h264_video_transfer_char;
+	u32 h264_video_matrix_coeff;
+	u32 h264_chroma_loc_info_present;
+	u32 h264_chroma_loc_type_top;
+	u32 h264_chroma_loc_type_bot;
+	u32 h264_timing_info_present;
+	u32 h264_buffering_period_present;
+	u32 h264_low_delay_hrd_flag;
+	u32 aspect_ratio;
+	u32 test_mode;                  // Automated firmware test mode
+	u32 dsa_test_mode;              // Automated test mode for the DSA.
+	u32 fme_test_mode;              // Automated test mode for the fme
+	u32 cbr_row_mode;               //0: FW mode; 1: HW mode
+	u32 windsor_mode;               //0: normal mode; 1: intra only mode; 2: intra+0MV mode
+	u32 encode_mode;                // H264, VC1, MPEG2, DIVX
+	u32 frame_width;                // display width
+	u32 frame_height;               // display height
+	u32 enc_frame_width;            // encoding width, should be 16-pix align
+	u32 enc_frame_height;           // encoding height, should be 16-pix aligned
+	u32 frame_rate_num;
+	u32 frame_rate_den;
+	u32 vi_field_source;
+	u32 vi_frame_width;
+	u32 vi_frame_height;
+	u32 crop_frame_width;
+	u32 crop_frame_height;
+	u32 crop_x_start_posn;
+	u32 crop_y_start_posn;
+	u32 mode422;
+	u32 mode_yuy2;
+	u32 dsa_luma_en;
+	u32 dsa_chroma_en;
+	u32 dsa_ext_hfilt_en;
+	u32 dsa_di_en;
+	u32 dsa_di_top_ref;
+	u32 dsa_vertf_disable;
+	u32 dsa_disable_pwb;
+	u32 dsa_hor_phase;
+	u32 dsa_ver_phase;
+	u32 dsa_iac_enable;
+	u32 iac_sc_threshold;
+	u32 iac_vm_threshold;
+	u32 iac_skip_mode;
+	u32 iac_grp_width;
+	u32 iac_grp_height;
+	u32 rate_control_mode;
+	u32 rate_control_resolution;
+	u32 buffer_size;
+	u32 buffer_level_init;
+	u32 buffer_I_bit_budget;
+	u32 top_field_first;
+	u32 intra_lum_qoffset;
+	u32 intra_chr_qoffset;
+	u32 inter_lum_qoffset;
+	u32 inter_chr_qoffset;
+	u32 use_def_scaling_mtx;
+	u32 inter_8x8_enab;
+	u32 inter_4x4_enab;
+	u32 fme_enable_qpel;
+	u32 fme_enable_hpel;
+	u32 fme_nozeromv;
+	u32 fme_predmv_en;
+	u32 fme_pred_2mv4mv;
+	u32 fme_smallsadthresh;
+	u32 ame_en_lmvc;
+	u32 ame_x_mult;
+	u32 cme_enable_4mv;
+	u32 cme_enable_1mv;
+	u32 hme_enable_16x8mv;
+	u32 hme_enable_8x16mv;
+	u32 cme_mv_weight;
+	u32 cme_mv_cost;
+	u32 ame_mult_mv;
+	u32 ame_shift_mv;
+	u32 hme_forceto1mv_en;
+	u32 hme_2mv_cost;
+	u32 hme_pred_mode;
+	u32 hme_sc_rnge;
+	u32 hme_sw_rnge;
+	u32 output_format;
+	u32 timestamp_enab;
+	u32 initial_pts_enab;
+	u32 initial_pts;
+};
+
+struct vpu_enc_static_params {
+	u32 param_change;
+	u32 gop_length;
+	u32 rate_control_bitrate;
+	u32 rate_control_bitrate_min;
+	u32 rate_control_bitrate_max;
+	u32 rate_control_content_models;
+	u32 rate_control_iframe_maxsize;
+	u32 rate_control_qp_init;
+	u32 rate_control_islice_qp;
+	u32 rate_control_pslice_qp;
+	u32 rate_control_bslice_qp;
+	u32 adaptive_quantization;
+	u32 aq_variance;
+	u32 cost_optimization;
+	u32 fdlp_mode;
+	u32 enable_isegbframes;
+	u32 enable_adaptive_keyratio;
+	u32 keyratio_imin;
+	u32 keyratio_imax;
+	u32 keyratio_pmin;
+	u32 keyratio_pmax;
+	u32 keyratio_bmin;
+	u32 keyratio_bmax;
+	s32 keyratio_istep;
+	s32 keyratio_pstep;
+	s32 keyratio_bstep;
+	u32 enable_paff;
+	u32 enable_b_frame_ref;
+	u32 enable_adaptive_gop;
+	u32 enable_closed_gop;
+	u32 open_gop_refresh_freq;
+	u32 enable_adaptive_sc;
+	u32 enable_fade_detection;
+	s32 fade_detection_threshold;
+	u32 enable_repeat_b;
+	u32 enable_low_delay_b;
+};
+
+struct vpu_enc_dynamic_params {
+	u32 param_change;
+	u32 rows_per_slice;
+	u32 mbaff_enable;
+	u32 dbf_enable;
+	u32 field_source;
+	u32 gop_b_length;
+	u32 mb_group_size;
+	u32 cbr_rows_per_group;
+	u32 skip_enable;
+	u32 pts_bits_0_to_31;
+	u32 pts_bit_32;
+	u32 rm_expsv_cff;
+	u32 const_ipred;
+	s32 chr_qp_offset;
+	u32 intra_mb_qp_offset;
+	u32 h264_cabac_init_method;
+	u32 h264_cabac_init_idc;
+	u32 h264_cabac_enable;
+	s32 alpha_c0_offset_div2;
+	s32 beta_offset_div2;
+	u32 intra_prefresh_y0;
+	u32 intra_prefresh_y1;
+	u32 dbg_dump_rec_src;
+};
+
+struct vpu_enc_expert_mode_param {
+	struct vpu_enc_calib_params calib_param;
+	struct vpu_enc_config_params config_param;
+	struct vpu_enc_static_params static_param;
+	struct vpu_enc_dynamic_params dynamic_param;
+};
+
+enum MEDIAIP_ENC_FMT {
+	MEDIAIP_ENC_FMT_H264 = 0,
+	MEDIAIP_ENC_FMT_VC1,
+	MEDIAIP_ENC_FMT_MPEG2,
+	MEDIAIP_ENC_FMT_MPEG4SP,
+	MEDIAIP_ENC_FMT_H263,
+	MEDIAIP_ENC_FMT_MPEG1,
+	MEDIAIP_ENC_FMT_SHORT_HEADER,
+	MEDIAIP_ENC_FMT_NULL
+};
+
+enum MEDIAIP_ENC_PROFILE {
+	MEDIAIP_ENC_PROF_MPEG2_SP = 0,
+	MEDIAIP_ENC_PROF_MPEG2_MP,
+	MEDIAIP_ENC_PROF_MPEG2_HP,
+	MEDIAIP_ENC_PROF_H264_BP,
+	MEDIAIP_ENC_PROF_H264_MP,
+	MEDIAIP_ENC_PROF_H264_HP,
+	MEDIAIP_ENC_PROF_MPEG4_SP,
+	MEDIAIP_ENC_PROF_MPEG4_ASP,
+	MEDIAIP_ENC_PROF_VC1_SP,
+	MEDIAIP_ENC_PROF_VC1_MP,
+	MEDIAIP_ENC_PROF_VC1_AP
+};
+
+enum MEDIAIP_ENC_BITRATE_MODE {
+	MEDIAIP_ENC_BITRATE_MODE_VBR          = 0x00000001,
+	MEDIAIP_ENC_BITRATE_MODE_CBR          = 0x00000002,
+	MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP  = 0x00000004
+};
+
+struct vpu_enc_memory_resource {
+	u32 phys;
+	u32 virt;
+	u32 size;
+};
+
+struct vpu_enc_param {
+	enum MEDIAIP_ENC_FMT codec_mode;
+	enum MEDIAIP_ENC_PROFILE profile;
+	u32 level;
+
+	struct vpu_enc_memory_resource enc_mem_desc;
+
+	u32 frame_rate;
+	u32 src_stride;
+	u32 src_width;
+	u32 src_height;
+	u32 src_offset_x;
+	u32 src_offset_y;
+	u32 src_crop_width;
+	u32 src_crop_height;
+	u32 out_width;
+	u32 out_height;
+	u32 iframe_interval;
+	u32 bframes;
+	u32 low_latency_mode;
+
+	enum MEDIAIP_ENC_BITRATE_MODE  bitrate_mode;
+	u32 target_bitrate;
+	u32 max_bitrate;
+	u32 min_bitrate;
+	u32 init_slice_qp;
+};
+
+struct vpu_enc_mem_pool {
+	struct vpu_enc_memory_resource enc_frames[WINDSOR_MAX_SRC_FRAMES];
+	struct vpu_enc_memory_resource ref_frames[WINDSOR_MAX_REF_FRAMES];
+	struct vpu_enc_memory_resource act_frame;
+};
+
+struct vpu_enc_encoding_status {
+	u32   frame_id;
+	u32   error_flag;   //Error type
+	u32   mb_y;
+	u32   mb_x;
+	u32   reserved[12];
+
+};
+
+struct vpu_enc_dsa_status {
+	u32   frame_id;
+	u32   dsa_cyle;
+	u32   mb_y;
+	u32   mb_x;
+	u32   reserved[4];
+};
+
+struct vpu_enc_ctrl {
+	struct vpu_enc_yuv_desc *yuv_desc;
+	struct vpu_rpc_buffer_desc *stream_desc;
+	struct vpu_enc_expert_mode_param *expert;
+	struct vpu_enc_param *param;
+	struct vpu_enc_mem_pool *pool;
+	struct vpu_enc_encoding_status *status;
+	struct vpu_enc_dsa_status *dsa;
+};
+
+struct vpu_enc_host_ctrls {
+	struct vpu_enc_ctrl ctrls[VID_API_NUM_STREAMS];
+};
+
+struct windsor_pic_info {
+	u32 frame_id;
+	u32 pic_encod_done;
+	u32 pic_type;
+	u32 skipped_frame;
+	u32 error_flag;
+	u32 psnr;
+	u32 flush_done;
+	u32 mb_y;
+	u32 mb_x;
+	u32 frame_size;
+	u32 frame_enc_ttl_cycles;
+	u32 frame_enc_ttl_frm_cycles;
+	u32 frame_enc_ttl_slc_cycles;
+	u32 frame_enc_ttl_enc_cycles;
+	u32 frame_enc_ttl_hme_cycles;
+	u32 frame_enc_ttl_dsa_cycles;
+	u32 frame_enc_fw_cycles;
+	u32 frame_crc;
+	u32 num_interrupts_1;
+	u32 num_interrupts_2;
+	u32 poc;
+	u32 ref_info;
+	u32 pic_num;
+	u32 pic_activity;
+	u32 scene_change;
+	u32 mb_stats;
+	u32 enc_cache_count0;
+	u32 enc_cache_count1;
+	u32 mtl_wr_strb_cnt;
+	u32 mtl_rd_strb_cnt;
+	u32 str_buff_wptr;
+	u32 diagnosticEvents;
+	u32 proc_iacc_tot_rd_cnt;
+	u32 proc_dacc_tot_rd_cnt;
+	u32 proc_dacc_tot_wr_cnt;
+	u32 proc_dacc_reg_rd_cnt;
+	u32 proc_dacc_reg_wr_cnt;
+	u32 proc_dacc_rng_rd_cnt;
+	u32 proc_dacc_rng_wr_cnt;
+	s32 tv_s;
+	u32 tv_ns;
+};
+
+u32 vpu_windsor_get_data_size(void)
+{
+	return sizeof(struct vpu_enc_host_ctrls);
+}
+
+static struct vpu_enc_yuv_desc *get_yuv_desc(struct vpu_shared_addr *shared,
+						u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].yuv_desc;
+}
+
+static struct vpu_enc_mem_pool *get_mem_pool(struct vpu_shared_addr *shared,
+						u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].pool;
+}
+
+static struct vpu_rpc_buffer_desc *get_stream_buf_desc(struct vpu_shared_addr *shared,
+							u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].stream_desc;
+}
+
+static struct vpu_enc_expert_mode_param *get_expert_param(struct vpu_shared_addr *shared,
+							u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].expert;
+}
+
+static struct vpu_enc_param *get_enc_param(struct vpu_shared_addr *shared,
+						u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].param;
+}
+
+static u32 get_ptr(u32 ptr)
+{
+	return (ptr | 0x80000000);
+}
+
+void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr)
+{
+	unsigned long base_phy_addr;
+	unsigned long phy_addr;
+	unsigned long offset;
+	struct windsor_iface *iface;
+	struct windsor_ctrl_iface *ctrl;
+	struct vpu_enc_host_ctrls *hcs;
+	unsigned int i;
+
+	WARN_ON(!shared || !shared->priv);
+	WARN_ON(!rpc || !rpc->phys || !rpc->length || rpc->phys < boot_addr);
+
+	base_phy_addr = rpc->phys - boot_addr;
+	iface = rpc->virt;
+	shared->iface = iface;
+	shared->boot_addr = boot_addr;
+	hcs = shared->priv;
+
+	iface->exec_base_addr = base_phy_addr;
+	iface->exec_area_size = rpc->length;
+
+	offset = sizeof(struct windsor_iface);
+	phy_addr = base_phy_addr + offset;
+	shared->cmd_desc = &iface->cmd_buffer_desc;
+	shared->cmd_mem_vir = rpc->virt + offset;
+	iface->cmd_buffer_desc.start =
+	iface->cmd_buffer_desc.rptr =
+	iface->cmd_buffer_desc.wptr = phy_addr;
+	iface->cmd_buffer_desc.end = iface->cmd_buffer_desc.start + CMD_SIZE;
+
+	offset += CMD_SIZE;
+	phy_addr = base_phy_addr + offset;
+	shared->msg_desc = &iface->msg_buffer_desc;
+	shared->msg_mem_vir = rpc->virt + offset;
+	iface->msg_buffer_desc.start =
+	iface->msg_buffer_desc.wptr =
+	iface->msg_buffer_desc.rptr = phy_addr;
+	iface->msg_buffer_desc.end = iface->msg_buffer_desc.start + MSG_SIZE;
+
+	offset += MSG_SIZE;
+	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {
+		iface->ctrl_iface[i] = base_phy_addr + offset;
+		offset += sizeof(struct windsor_ctrl_iface);
+	}
+	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {
+		ctrl = rpc->virt + (iface->ctrl_iface[i] - base_phy_addr);
+
+		ctrl->enc_yuv_buffer_desc = base_phy_addr + offset;
+		hcs->ctrls[i].yuv_desc = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_yuv_desc);
+
+		ctrl->enc_stream_buffer_desc = base_phy_addr + offset;
+		hcs->ctrls[i].stream_desc = rpc->virt + offset;
+		offset += sizeof(struct vpu_rpc_buffer_desc);
+
+		ctrl->enc_expert_mode_param = base_phy_addr + offset;
+		hcs->ctrls[i].expert = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_expert_mode_param);
+
+		ctrl->enc_param = base_phy_addr + offset;
+		hcs->ctrls[i].param = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_param);
+
+		ctrl->enc_mem_pool = base_phy_addr + offset;
+		hcs->ctrls[i].pool = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_mem_pool);
+
+		ctrl->enc_encoding_status = base_phy_addr + offset;
+		hcs->ctrls[i].status = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_encoding_status);
+
+		ctrl->enc_dsa_status = base_phy_addr + offset;
+		hcs->ctrls[i].dsa = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_dsa_status);
+	}
+
+	rpc->bytesused = offset;
+}
+
+void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log)
+{
+	struct windsor_iface *iface;
+
+	WARN_ON(!shared || !log || !log->phys);
+
+	vpu_dbg(LVL_DEBUG, "set log area <0x%llx, 0x%x> (0x%lx)\n",
+			log->phys, log->length, shared->boot_addr);
+	iface = shared->iface;
+	iface->log_buffer_desc.start =
+	iface->log_buffer_desc.wptr =
+	iface->log_buffer_desc.rptr = log->phys - shared->boot_addr;
+	iface->log_buffer_desc.end = iface->log_buffer_desc.start + log->length;
+}
+
+void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id)
+{
+	struct windsor_iface *iface;
+	struct vpu_rpc_system_config *config;
+
+	WARN_ON(!shared || !shared->iface);
+
+	iface = shared->iface;
+	config = &iface->system_config;
+
+	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);
+}
+
+int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared)
+{
+	return 0x300000;
+}
+
+static struct vpu_pair windsor_cmds[] = {
+	{VPU_CMD_ID_CONFIGURE_CODEC, GTB_ENC_CMD_CONFIGURE_CODEC},
+	{VPU_CMD_ID_START, GTB_ENC_CMD_STREAM_START},
+	{VPU_CMD_ID_STOP, GTB_ENC_CMD_STREAM_STOP},
+	{VPU_CMD_ID_FRAME_ENCODE, GTB_ENC_CMD_FRAME_ENCODE},
+	{VPU_CMD_ID_SNAPSHOT, GTB_ENC_CMD_SNAPSHOT},
+	{VPU_CMD_ID_FIRM_RESET, GTB_ENC_CMD_FIRM_RESET},
+	{VPU_CMD_ID_UPDATE_PARAMETER, GTB_ENC_CMD_PARAMETER_UPD},
+	{VPU_CMD_ID_DEBUG, GTB_ENC_CMD_FW_STATUS}
+};
+
+static struct vpu_pair windsor_msgs[] = {
+	{VPU_MSG_ID_RESET_DONE, VID_API_ENC_EVENT_RESET_DONE},
+	{VPU_MSG_ID_START_DONE, VID_API_ENC_EVENT_START_DONE},
+	{VPU_MSG_ID_STOP_DONE, VID_API_ENC_EVENT_STOP_DONE},
+	{VPU_MSG_ID_FRAME_INPUT_DONE, VID_API_ENC_EVENT_FRAME_INPUT_DONE},
+	{VPU_MSG_ID_ENC_DONE, VID_API_ENC_EVENT_FRAME_DONE},
+	{VPU_MSG_ID_FRAME_RELEASE, VID_API_ENC_EVENT_FRAME_RELEASE},
+	{VPU_MSG_ID_MEM_REQUEST, VID_API_ENC_EVENT_MEM_REQUEST},
+	{VPU_MSG_ID_PARAM_UPD_DONE, VID_API_ENC_EVENT_PARA_UPD_DONE},
+	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_ENC_EVENT_FIRMWARE_XCPT},
+};
+
+int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)
+{
+	int ret;
+	s64 timestamp;
+
+	WARN_ON(!pkt);
+
+	ret = vpu_find_dst_by_src(windsor_cmds, ARRAY_SIZE(windsor_cmds), id);
+	if (ret < 0)
+		return ret;
+	pkt->hdr.id = ret;
+	pkt->hdr.num = 0;
+	pkt->hdr.index = index;
+	if (id == VPU_CMD_ID_FRAME_ENCODE) {
+		pkt->hdr.num = 2;
+		timestamp = *(s64 *)data;
+		if (timestamp < 0) {
+			pkt->data[0] = (u32)-1;
+			pkt->data[1] = 0;
+		} else {
+			pkt->data[0] = timestamp / NSEC_PER_SEC;
+			pkt->data[1] = timestamp % NSEC_PER_SEC;
+		}
+	}
+
+	return 0;
+}
+
+int vpu_windsor_convert_msg_id(u32 id)
+{
+	return vpu_find_src_by_dst(windsor_msgs, ARRAY_SIZE(windsor_msgs), id);
+}
+
+static void vpu_windsor_unpack_pic_info(struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_enc_pic_info *info = data;
+	struct windsor_pic_info *windsor = (struct windsor_pic_info *)pkt->data;
+
+	info->frame_id = windsor->frame_id;
+	switch (windsor->pic_type) {
+	case MEDIAIP_ENC_PIC_TYPE_I_FRAME:
+	case MEDIAIP_ENC_PIC_TYPE_IDR_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_KEYFRAME;
+		break;
+	case MEDIAIP_ENC_PIC_TYPE_P_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_PFRAME;
+		break;
+	case MEDIAIP_ENC_PIC_TYPE_B_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_BFRAME;
+		break;
+	default:
+		break;
+	}
+	info->skipped_frame = windsor->skipped_frame;
+	info->error_flag = windsor->error_flag;
+	info->psnr = windsor->psnr;
+	info->frame_size = windsor->frame_size;
+	info->wptr = get_ptr(windsor->str_buff_wptr);
+	info->crc = windsor->frame_crc;
+	info->timestamp = MAKE_TIMESTAMP(windsor->tv_s, windsor->tv_ns);
+}
+
+static void vpu_windsor_unpack_mem_req(struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_pkt_mem_req_data *req_data = data;
+
+	req_data->enc_frame_size = pkt->data[0];
+	req_data->enc_frame_num = pkt->data[1];
+	req_data->ref_frame_size = pkt->data[2];
+	req_data->ref_frame_num = pkt->data[3];
+	req_data->act_buf_size = pkt->data[4];
+	req_data->act_buf_num = 1;
+}
+
+int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)
+{
+	if (!pkt || !data)
+		return -EINVAL;
+
+	switch (pkt->hdr.id) {
+	case VID_API_ENC_EVENT_FRAME_DONE:
+		vpu_windsor_unpack_pic_info(pkt, data);
+		break;
+	case VID_API_ENC_EVENT_MEM_REQUEST:
+		vpu_windsor_unpack_mem_req(pkt, data);
+		break;
+	case VID_API_ENC_EVENT_FRAME_RELEASE:
+		*(u32 *)data = pkt->data[0];
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_fill_yuv_frame(struct vpu_shared_addr *shared,
+				u32 instance,
+				struct vb2_buffer *vb)
+{
+	struct vpu_enc_yuv_desc *desc;
+	struct vb2_v4l2_buffer *vbuf;
+
+	WARN_ON(!shared || !vb || instance >= VID_API_NUM_STREAMS);
+
+	desc = get_yuv_desc(shared, instance);
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	vpu_dbg(LVL_DEBUG, "fill yuv with id : %d\n", vbuf->sequence);
+	desc->frame_id = vbuf->sequence;
+	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+		desc->key_frame = 1;
+	else
+		desc->key_frame = 0;
+	desc->luma_base = vpu_get_vb_phy_addr(vb, 0);
+	desc->chroma_base = vpu_get_vb_phy_addr(vb, 1);
+
+	return 0;
+}
+
+int vpu_windsor_input_frame(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	vpu_windsor_fill_yuv_frame(shared, inst->id, vb);
+	return vpu_session_encode_frame(inst, vb->timestamp);
+}
+
+int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,
+					u32 instance,
+					u32 type,
+					u32 index,
+					struct vpu_buffer *buf)
+{
+	struct vpu_enc_mem_pool *pool;
+	struct vpu_enc_memory_resource *res;
+
+	WARN_ON(!shared || !buf || instance >= VID_API_NUM_STREAMS);
+
+	pool = get_mem_pool(shared, instance);
+
+	switch (type) {
+	case MEM_RES_ENC:
+		res = &pool->enc_frames[index];
+		break;
+	case MEM_RES_REF:
+		res = &pool->ref_frames[index];
+		break;
+	case MEM_RES_ACT:
+		res = &pool->act_frame;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	res->phys = buf->phys;
+	res->virt = buf->phys - shared->boot_addr;
+	res->size = buf->length;
+
+	vpu_dbg(LVL_DEBUG, "[%d] type = %d, phys = 0x%x, size = 0x%x\n",
+			instance, type, res->phys, res->size);
+
+	return 0;
+}
+
+int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance,
+					struct vpu_buffer *buf)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	struct vpu_enc_expert_mode_param *expert;
+
+	desc = get_stream_buf_desc(shared, instance);
+	expert = get_expert_param(shared, instance);
+
+	desc->start = desc->wptr = desc->rptr = buf->phys;
+	desc->end = buf->phys + buf->length;
+
+	vpu_dbg(LVL_DEBUG, "stream_buf:[0x%x, 0x%x]\n", desc->start, desc->end);
+
+	expert->calib_param.mem_chunk_phys_addr = 0;
+	expert->calib_param.mem_chunk_virt_addr = 0;
+	expert->calib_param.mem_chunk_size = 0;
+	expert->calib_param.cb_base = buf->phys;
+	expert->calib_param.cb_size = buf->length;
+
+	return 0;
+}
+
+static void vpu_windsor_update_wptr(struct vpu_rpc_buffer_desc *desc, u32 wptr)
+{
+	u32 pre_wptr = get_ptr(desc->wptr);
+	u32 new_wptr = get_ptr(wptr);
+	u32 rptr = get_ptr(desc->rptr);
+	u32 size = get_ptr(desc->end) - get_ptr(desc->start);
+	u32 space = (rptr + size - pre_wptr) % size;
+	u32 step = (new_wptr + size - pre_wptr) % size;
+
+	if (space && step > space)
+		vpu_err("update wptr from 0x%x to 0x%x, cross over rptr 0x%x\n",
+				pre_wptr, new_wptr, rptr);
+
+	desc->wptr = wptr;
+}
+
+static void vpu_windsor_update_rptr(struct vpu_rpc_buffer_desc *desc, u32 rptr)
+{
+	u32 pre_rptr = get_ptr(desc->rptr);
+	u32 new_rptr = get_ptr(rptr);
+	u32 wptr = get_ptr(desc->wptr);
+	u32 size = get_ptr(desc->end) - get_ptr(desc->start);
+	u32 space = (wptr + size - pre_rptr) % size;
+	u32 step = (new_rptr + size - pre_rptr) % size;
+
+	if (step > space)
+		vpu_err("update rptr from 0x%x to 0x%x, cross over wptr 0x%x\n",
+				pre_rptr, new_rptr, wptr);
+
+	desc->rptr = rptr;
+}
+
+int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance, u32 ptr, bool write)
+{
+	struct vpu_rpc_buffer_desc *desc;
+
+	desc = get_stream_buf_desc(shared, instance);
+
+	/*update wptr/rptr after data is written or read*/
+	mb();
+	if (write)
+		vpu_windsor_update_wptr(desc, ptr);
+	else
+		vpu_windsor_update_rptr(desc, ptr);
+
+	return 0;
+}
+
+int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_rpc_buffer_desc *rpc_desc;
+
+	rpc_desc = get_stream_buf_desc(shared, instance);
+	if (desc) {
+		desc->wptr = get_ptr(rpc_desc->wptr);
+		desc->rptr = get_ptr(rpc_desc->rptr);
+		desc->start = get_ptr(rpc_desc->start);
+		desc->end = get_ptr(rpc_desc->end);
+	}
+
+	return 0;
+}
+
+u32 vpu_windsor_get_version(struct vpu_shared_addr *shared)
+{
+	struct windsor_iface *iface;
+
+	WARN_ON(!shared || !shared->iface);
+
+	iface = shared->iface;
+	return iface->fw_version;
+}
+
+static int vpu_windsor_set_frame_rate(struct vpu_enc_expert_mode_param *expert,
+				struct vpu_encode_params *params)
+{
+	expert->config_param.frame_rate_num = params->frame_rate_num;
+	expert->config_param.frame_rate_den = params->frame_rate_den;
+
+	return 0;
+}
+
+static int vpu_windsor_set_format(struct vpu_enc_param *param, u32 pixelformat)
+{
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_H264:
+		param->codec_mode = MEDIAIP_ENC_FMT_H264;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_set_profile(struct vpu_enc_param *param, u32 profile)
+{
+	switch (profile) {
+	case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+		param->profile = MEDIAIP_ENC_PROF_H264_BP;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+		param->profile = MEDIAIP_ENC_PROF_H264_MP;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+		param->profile = MEDIAIP_ENC_PROF_H264_HP;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const u32 h264_level[] = {
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_0] = 10,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1B]  = 14,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_1] = 11,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_2] = 12,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_3] = 13,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_0] = 20,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_1] = 21,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_2] = 22,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_0] = 30,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_1] = 31,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_2] = 32,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_0] = 40,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_1] = 41,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_2] = 42,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_5_0] = 50,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_5_1] = 51
+};
+
+static int vpu_windsor_set_level(struct vpu_enc_param *param, u32 level)
+{
+
+	if (level >= ARRAY_SIZE(h264_level))
+		return -EINVAL;
+
+	param->level = h264_level[level];
+
+	return 0;
+}
+
+static int vpu_windsor_set_size(struct vpu_enc_param *windsor,
+				struct vpu_encode_params *params)
+{
+	windsor->src_stride = params->src_stride;
+	windsor->src_width = params->src_width;
+	windsor->src_height = params->src_height;
+	windsor->src_offset_x = params->crop.left;
+	windsor->src_offset_y = params->crop.top;
+	windsor->src_crop_width = params->crop.width;
+	windsor->src_crop_height = params->crop.height;
+	windsor->out_width = params->out_width;
+	windsor->out_height = params->out_height;
+
+	vpu_dbg(LVL_DEBUG, "%d %dx%d (%d,%d) %dx%d, %dx%d\n",
+			windsor->src_stride,
+			windsor->src_width,
+			windsor->src_height,
+			windsor->src_offset_x,
+			windsor->src_offset_y,
+			windsor->src_crop_width,
+			windsor->src_crop_height,
+			windsor->out_width,
+			windsor->out_height);
+	return 0;
+}
+
+static int vpu_windsor_set_gop(struct vpu_enc_param *param, u32 gop)
+{
+	param->iframe_interval = gop;
+
+	return 0;
+}
+
+static int vpu_windsor_set_bframes(struct vpu_enc_param *param, u32 bframes)
+{
+	if (bframes) {
+		param->low_latency_mode = 0;
+		param->bframes = bframes;
+	} else {
+		param->low_latency_mode = 1;
+		param->bframes = 0;
+	}
+
+	if (param->low_latency_mode)
+		vpu_dbg(LVL_DEBUG, "low latency mode\n");
+
+	return 0;
+}
+
+static int vpu_windsor_set_bitrate_mode(struct vpu_enc_param *param, u32 mode)
+{
+	switch (mode) {
+	case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP;
+		break;
+	case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CBR;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u32 vpu_windsor_bitrate(u32 bitrate)
+{
+	return DIV_ROUND_CLOSEST(bitrate, WINDSOR_BITRATE_UNIT);
+}
+
+static int vpu_windsor_set_bitrate(struct vpu_enc_param *windsor,
+				struct vpu_encode_params *params)
+{
+	windsor->target_bitrate = vpu_windsor_bitrate(params->bitrate);
+	windsor->min_bitrate = vpu_windsor_bitrate(params->bitrate_min);
+	windsor->max_bitrate = vpu_windsor_bitrate(params->bitrate_max);
+
+	return 0;
+}
+
+static int vpu_windsor_set_qp(struct vpu_enc_expert_mode_param *expert,
+			struct vpu_encode_params *params)
+{
+	expert->static_param.rate_control_islice_qp = params->i_frame_qp;
+	expert->static_param.rate_control_pslice_qp = params->p_frame_qp;
+	expert->static_param.rate_control_bslice_qp = params->b_frame_qp;
+
+	return 0;
+}
+
+static int vpu_windsor_set_sar(struct vpu_enc_expert_mode_param *expert,
+			struct vpu_encode_params *params)
+{
+	expert->config_param.h264_aspect_ratio_present = params->sar.enable;
+	if (params->sar.idc == V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED)
+		expert->config_param.aspect_ratio = WINDSOR_H264_EXTENDED_SAR;
+	else
+		expert->config_param.aspect_ratio = params->sar.idc;
+	expert->config_param.h264_aspect_ratio_sar_width = params->sar.width;
+	expert->config_param.h264_aspect_ratio_sar_height = params->sar.height;
+
+
+	return 0;
+}
+
+static int vpu_windsor_set_color(struct vpu_enc_expert_mode_param *expert,
+			struct vpu_encode_params *params)
+{
+	expert->config_param.h264_video_type_present = 1;
+	expert->config_param.h264_video_format = 5;
+	expert->config_param.h264_video_colour_descriptor = 1;
+	expert->config_param.h264_video_colour_primaries =
+		vpu_color_cvrt_primaries_v2i(params->color.primaries);
+	expert->config_param.h264_video_transfer_char =
+		vpu_color_cvrt_transfers_v2i(params->color.transfer);
+	expert->config_param.h264_video_matrix_coeff =
+		vpu_color_cvrt_matrix_v2i(params->color.matrix);
+	expert->config_param.h264_video_full_range =
+		vpu_color_cvrt_full_range_v2i(params->color.full_range);
+	return 0;
+}
+
+static int vpu_windsor_update_bitrate(struct vpu_shared_addr *shared,
+				u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_param *windsor;
+	struct vpu_enc_expert_mode_param *expert;
+
+	windsor = get_enc_param(shared, instance);
+	expert = get_expert_param(shared, instance);
+
+	if (windsor->bitrate_mode != MEDIAIP_ENC_BITRATE_MODE_CBR)
+		return 0;
+	if (params->rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+		return 0;
+	if (vpu_windsor_bitrate(params->bitrate) == windsor->target_bitrate)
+		return 0;
+
+	vpu_windsor_set_bitrate(windsor, params);
+	expert->static_param.rate_control_bitrate = windsor->target_bitrate;
+	expert->static_param.rate_control_bitrate_min = windsor->min_bitrate;
+	expert->static_param.rate_control_bitrate_max = windsor->max_bitrate;
+
+	return 0;
+}
+
+static int vpu_windsor_set_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_param *windsor;
+	int ret;
+
+	windsor = get_enc_param(shared, instance);
+
+	if (params->input_format != V4L2_PIX_FMT_NV12)
+		return -EINVAL;
+
+	ret = vpu_windsor_set_format(windsor, params->codec_format);
+	if (ret)
+		return ret;
+	vpu_windsor_set_profile(windsor, params->profile);
+	vpu_windsor_set_level(windsor, params->level);
+	vpu_windsor_set_size(windsor, params);
+	vpu_windsor_set_gop(windsor, params->gop_length);
+	vpu_windsor_set_bframes(windsor, params->bframes);
+	vpu_windsor_set_bitrate_mode(windsor, params->rc_mode);
+	vpu_windsor_set_bitrate(windsor, params);
+	windsor->init_slice_qp = params->i_frame_qp;
+
+	if (!params->frame_rate_num)
+		return -EINVAL;
+	windsor->frame_rate = params->frame_rate_den / params->frame_rate_num;
+
+	return 0;
+}
+
+static int vpu_windsor_update_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_expert_mode_param *expert;
+
+	expert = get_expert_param(shared, instance);
+
+	vpu_windsor_set_frame_rate(expert, params);
+	vpu_windsor_set_qp(expert, params);
+	vpu_windsor_set_sar(expert, params);
+	vpu_windsor_set_color(expert, params);
+	vpu_windsor_update_bitrate(shared, instance, params);
+	/*expert->config_param.iac_sc_threshold = 0;*/
+
+	return 0;
+}
+
+int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_encode_params *params, u32 update)
+{
+	if (!params)
+		return -EINVAL;
+
+	if (!update)
+		return vpu_windsor_set_params(shared, instance, params);
+	else
+		return vpu_windsor_update_params(shared, instance, params);
+}
+
+u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared)
+{
+	struct windsor_iface *iface;
+
+	WARN_ON(!shared || !shared->iface);
+
+	iface = shared->iface;
+
+	return iface->max_streams;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_windsor.h b/drivers/media/platform/imx/vpu-8q/vpu_windsor.h
new file mode 100644
index 000000000000..42545cd2b882
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_windsor.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_WINDSOR_H
+#define _IMX_VPU_WINDSOR_H
+
+u32 vpu_windsor_get_data_size(void);
+void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr);
+void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log);
+void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id);
+int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared);
+int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt,
+			u32 index, u32 id, void *data);
+int vpu_windsor_convert_msg_id(u32 msg_id);
+int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data);
+int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,
+			u32 instance, u32 type, u32 index,
+			struct vpu_buffer *buf);
+int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,
+			u32 instance, struct vpu_buffer *buf);
+int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,
+			u32 instance, u32 ptr, bool write);
+int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+			u32 instance, struct vpu_rpc_buffer_desc *desc);
+u32 vpu_windsor_get_version(struct vpu_shared_addr *shared);
+int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,
+			u32 instance,
+			struct vpu_encode_params *params,
+			u32 update);
+int vpu_windsor_input_frame(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb);
+u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared);
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:07 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:07 +0800
Subject: [PATCH v6 11/14] media: imx: imx8q: implement malone decoder rpc
 interface
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <a6c3e0891612b465d7d20db3849523127b0b2ddf.1628671163.git.ming.qian@nxp.com>

This part implements the malone decoder rpc interface.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../media/platform/imx/vpu-8q/vpu_malone.c    | 1687 +++++++++++++++++
 .../media/platform/imx/vpu-8q/vpu_malone.h    |   42 +
 2 files changed, 1729 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_malone.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_malone.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_malone.c b/drivers/media/platform/imx/vpu-8q/vpu_malone.c
new file mode 100644
index 000000000000..51f78fd3247d
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_malone.c
@@ -0,0 +1,1687 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"MALONE"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <linux/videodev2.h>
+#include <linux/imx_vpu.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_log.h"
+#include "vpu_imx8q.h"
+#include "vpu_malone.h"
+
+#define CMD_SIZE			25600
+#define MSG_SIZE			25600
+#define CODEC_SIZE			0x1000
+#define JPEG_SIZE			0x1000
+#define SEQ_SIZE			0x1000
+#define GOP_SIZE			0x1000
+#define PIC_SIZE			0x1000
+#define QMETER_SIZE			0x1000
+#define DBGLOG_SIZE			0x10000
+#define DEBUG_SIZE			0x80000
+#define ENG_SIZE			0x1000
+#define MALONE_SKIPPED_FRAME_ID		0x555
+
+#define MALONE_ALIGN_MBI		0x800
+#define MALONE_DCP_CHUNK_BIT		16
+#define MALONE_DCP_SIZE_MAX		0x3000000
+#define MALONE_DCP_SIZE_MIN		0x100000
+#define MALONE_DCP_FIXED_MB_ALLOC	250
+
+#define CONFIG_SET(val, cfg, pos, mask)		\
+		(*(cfg) |= (((val) << (pos)) & (mask)))
+//x means source data , y means destination data
+#define STREAM_CONFIG_FORMAT_SET(x, y)		CONFIG_SET(x, y, 0, 0x0000000F)
+#define STREAM_CONFIG_STRBUFIDX_SET(x, y)	CONFIG_SET(x, y, 8, 0x00000300)
+#define STREAM_CONFIG_NOSEQ_SET(x, y)		CONFIG_SET(x, y, 10, 0x00000400)
+#define STREAM_CONFIG_DEBLOCK_SET(x, y)		CONFIG_SET(x, y, 11, 0x00000800)
+#define STREAM_CONFIG_DERING_SET(x, y)		CONFIG_SET(x, y, 12, 0x00001000)
+#define STREAM_CONFIG_IBWAIT_SET(x, y)		CONFIG_SET(x, y, 13, 0x00002000)
+#define STREAM_CONFIG_FBC_SET(x, y)		CONFIG_SET(x, y, 14, 0x00004000)
+#define STREAM_CONFIG_PLAY_MODE_SET(x, y)	CONFIG_SET(x, y, 16, 0x00030000)
+#define STREAM_CONFIG_ENABLE_DCP_SET(x, y)	CONFIG_SET(x, y, 20, 0x00100000)
+#define STREAM_CONFIG_NUM_STR_BUF_SET(x, y)	CONFIG_SET(x, y, 21, 0x00600000)
+#define STREAM_CONFIG_MALONE_USAGE_SET(x, y)	CONFIG_SET(x, y, 23, 0x01800000)
+#define STREAM_CONFIG_MULTI_VID_SET(x, y)	CONFIG_SET(x, y, 25, 0x02000000)
+#define STREAM_CONFIG_OBFUSC_EN_SET(x, y)	CONFIG_SET(x, y, 26, 0x04000000)
+#define STREAM_CONFIG_RC4_EN_SET(x, y)		CONFIG_SET(x, y, 27, 0x08000000)
+#define STREAM_CONFIG_MCX_SET(x, y)		CONFIG_SET(x, y, 28, 0x10000000)
+#define STREAM_CONFIG_PES_SET(x, y)		CONFIG_SET(x, y, 29, 0x20000000)
+#define STREAM_CONFIG_NUM_DBE_SET(x, y)		CONFIG_SET(x, y, 30, 0x40000000)
+#define STREAM_CONFIG_FS_CTRL_MODE_SET(x, y)	CONFIG_SET(x, y, 31, 0x80000000)
+
+enum vpu_malone_stream_input_mode {
+	INVALID_MODE = 0,
+	FRAME_LVL,
+	NON_FRAME_LVL
+};
+
+enum vpu_malone_format {
+	MALONE_FMT_NULL = 0x0,
+	MALONE_FMT_AVC  = 0x1,
+	MALONE_FMT_MP2  = 0x2,
+	MALONE_FMT_VC1  = 0x3,
+	MALONE_FMT_AVS  = 0x4,
+	MALONE_FMT_ASP  = 0x5,
+	MALONE_FMT_JPG  = 0x6,
+	MALONE_FMT_RV   = 0x7,
+	MALONE_FMT_VP6  = 0x8,
+	MALONE_FMT_SPK  = 0x9,
+	MALONE_FMT_VP8  = 0xA,
+	MALONE_FMT_HEVC = 0xB,
+	MALONE_FMT_LAST = MALONE_FMT_HEVC
+};
+
+enum {
+	VID_API_CMD_NULL              = 0x00,
+	VID_API_CMD_PARSE_NEXT_SEQ    = 0x01,
+	VID_API_CMD_PARSE_NEXT_I      = 0x02,
+	VID_API_CMD_PARSE_NEXT_IP     = 0x03,
+	VID_API_CMD_PARSE_NEXT_ANY    = 0x04,
+	VID_API_CMD_DEC_PIC           = 0x05,
+	VID_API_CMD_UPDATE_ES_WR_PTR  = 0x06,
+	VID_API_CMD_UPDATE_ES_RD_PTR  = 0x07,
+	VID_API_CMD_UPDATE_UDATA      = 0x08,
+	VID_API_CMD_GET_FSINFO        = 0x09,
+	VID_API_CMD_SKIP_PIC          = 0x0a,
+	VID_API_CMD_DEC_CHUNK         = 0x0b,
+	VID_API_CMD_START             = 0x10,
+	VID_API_CMD_STOP              = 0x11,
+	VID_API_CMD_ABORT             = 0x12,
+	VID_API_CMD_RST_BUF           = 0x13,
+	VID_API_CMD_FS_RELEASE        = 0x15,
+	VID_API_CMD_MEM_REGION_ATTACH = 0x16,
+	VID_API_CMD_MEM_REGION_DETACH = 0x17,
+	VID_API_CMD_MVC_VIEW_SELECT   = 0x18,
+	VID_API_CMD_FS_ALLOC          = 0x19,
+	VID_API_CMD_DBG_GET_STATUS    = 0x1C,
+	VID_API_CMD_DBG_START_LOG     = 0x1D,
+	VID_API_CMD_DBG_STOP_LOG      = 0x1E,
+	VID_API_CMD_DBG_DUMP_LOG      = 0x1F,
+	VID_API_CMD_YUV_READY         = 0x20,
+	VID_API_CMD_TS                = 0x21,
+
+	VID_API_CMD_FIRM_RESET        = 0x40,
+
+	VID_API_CMD_SNAPSHOT          = 0xAA,
+	VID_API_CMD_ROLL_SNAPSHOT     = 0xAB,
+	VID_API_CMD_LOCK_SCHEDULER    = 0xAC,
+	VID_API_CMD_UNLOCK_SCHEDULER  = 0xAD,
+	VID_API_CMD_CQ_FIFO_DUMP      = 0xAE,
+	VID_API_CMD_DBG_FIFO_DUMP     = 0xAF,
+	VID_API_CMD_SVC_ILP           = 0xBB,
+	VID_API_CMD_FW_STATUS         = 0xF0,
+	VID_API_CMD_INVALID           = 0xFF
+};
+
+enum {
+	VID_API_EVENT_NULL			= 0x00,
+	VID_API_EVENT_RESET_DONE		= 0x01,
+	VID_API_EVENT_SEQ_HDR_FOUND		= 0x02,
+	VID_API_EVENT_PIC_HDR_FOUND		= 0x03,
+	VID_API_EVENT_PIC_DECODED		= 0x04,
+	VID_API_EVENT_FIFO_LOW			= 0x05,
+	VID_API_EVENT_FIFO_HIGH			= 0x06,
+	VID_API_EVENT_FIFO_EMPTY		= 0x07,
+	VID_API_EVENT_FIFO_FULL			= 0x08,
+	VID_API_EVENT_BS_ERROR			= 0x09,
+	VID_API_EVENT_UDATA_FIFO_UPTD		= 0x0A,
+	VID_API_EVENT_RES_CHANGE		= 0x0B,
+	VID_API_EVENT_FIFO_OVF			= 0x0C,
+	VID_API_EVENT_CHUNK_DECODED		= 0x0D,
+	VID_API_EVENT_REQ_FRAME_BUFF		= 0x10,
+	VID_API_EVENT_FRAME_BUFF_RDY		= 0x11,
+	VID_API_EVENT_REL_FRAME_BUFF		= 0x12,
+	VID_API_EVENT_STR_BUF_RST		= 0x13,
+	VID_API_EVENT_RET_PING			= 0x14,
+	VID_API_EVENT_QMETER			= 0x15,
+	VID_API_EVENT_STR_FMT_CHANGE		= 0x16,
+	VID_API_EVENT_FIRMWARE_XCPT		= 0x17,
+	VID_API_EVENT_START_DONE		= 0x18,
+	VID_API_EVENT_STOPPED			= 0x19,
+	VID_API_EVENT_ABORT_DONE		= 0x1A,
+	VID_API_EVENT_FINISHED			= 0x1B,
+	VID_API_EVENT_DBG_STAT_UPDATE		= 0x1C,
+	VID_API_EVENT_DBG_LOG_STARTED		= 0x1D,
+	VID_API_EVENT_DBG_LOG_STOPPED		= 0x1E,
+	VID_API_EVENT_DBG_LOG_UPDATED		= 0x1F,
+	VID_API_EVENT_DBG_MSG_DEC		= 0x20,
+	VID_API_EVENT_DEC_SC_ERR		= 0x21,
+	VID_API_EVENT_CQ_FIFO_DUMP		= 0x22,
+	VID_API_EVENT_DBG_FIFO_DUMP		= 0x23,
+	VID_API_EVENT_DEC_CHECK_RES		= 0x24,
+	VID_API_EVENT_DEC_CFG_INFO		= 0x25,
+	VID_API_EVENT_UNSUPPORTED_STREAM	= 0x26,
+	VID_API_EVENT_STR_SUSPENDED		= 0x30,
+	VID_API_EVENT_SNAPSHOT_DONE		= 0x40,
+	VID_API_EVENT_FW_STATUS                 = 0xF0,
+	VID_API_EVENT_INVALID			= 0xFF
+};
+
+struct vpu_malone_buffer_desc {
+	struct vpu_rpc_buffer_desc buffer;
+	u32 low;
+	u32 high;
+};
+
+struct vpu_malone_str_buffer {
+	u32 wptr;
+	u32 rptr;
+	u32 start;
+	u32 end;
+	u32 lwm;
+};
+
+struct vpu_malone_picth_info {
+	u32 frame_pitch;
+};
+
+struct vpu_malone_table_desc {
+	u32 array_base;
+	u32 size;
+};
+
+struct vpu_malone_dbglog_desc {
+	u32 addr;
+	u32 size;
+	u32 level;
+	u32 reserved;
+};
+
+struct vpu_malone_frame_buffer {
+	u32 addr;
+	u32 size;
+};
+
+struct vpu_malone_udata {
+	u32 base;
+	u32 total_size;
+	u32 slot_size;
+};
+
+struct vpu_malone_buffer_info {
+	u32 stream_input_mode;
+	u32 stream_pic_input_count;
+	u32 stream_pic_parsed_count;
+	u32 stream_buffer_threshold;
+	u32 stream_pic_end_flag;
+};
+
+struct vpu_malone_encrypt_info {
+	u32 rec4key[8];
+	u32 obfusc;
+};
+
+struct malone_iface {
+	u32 exec_base_addr;
+	u32 exec_area_size;
+	struct vpu_malone_buffer_desc cmd_buffer_desc;
+	struct vpu_malone_buffer_desc msg_buffer_desc;
+	u32 cmd_int_enable[VID_API_NUM_STREAMS];
+	struct vpu_malone_picth_info stream_pitch_info[VID_API_NUM_STREAMS];
+	u32 stream_config[VID_API_NUM_STREAMS];
+	struct vpu_malone_table_desc codec_param_tab_desc;
+	struct vpu_malone_table_desc jpeg_param_tab_desc;
+	u32 stream_buffer_desc[VID_API_NUM_STREAMS][VID_API_MAX_BUF_PER_STR];
+	struct vpu_malone_table_desc seq_info_tab_desc;
+	struct vpu_malone_table_desc pic_info_tab_desc;
+	struct vpu_malone_table_desc gop_info_tab_desc;
+	struct vpu_malone_table_desc qmeter_info_tab_desc;
+	u32 stream_error[VID_API_NUM_STREAMS];
+	u32 fw_version;
+	u32 fw_offset;
+	u32 max_streams;
+	struct vpu_malone_dbglog_desc dbglog_desc;
+	struct vpu_rpc_buffer_desc api_cmd_buffer_desc[VID_API_NUM_STREAMS];
+	struct vpu_malone_udata udata_buffer[VID_API_NUM_STREAMS];
+	struct vpu_malone_buffer_desc debug_buffer_desc;
+	struct vpu_malone_buffer_desc eng_access_buff_desc[VID_API_NUM_STREAMS];
+	u32 encrypt_info[VID_API_NUM_STREAMS];
+	struct vpu_rpc_system_config system_cfg;
+	u32 api_version;
+	struct vpu_malone_buffer_info stream_buff_info[VID_API_NUM_STREAMS];
+};
+
+struct malone_jpg_params {
+	u32 rotation_angle;
+	u32 horiz_scale_factor;
+	u32 vert_scale_factor;
+	u32 rotation_mode;
+	u32 rgb_mode;
+	u32 chunk_mode; /* 0 ~ 1 */
+	u32 last_chunk; /* 0 ~ 1 */
+	u32 chunk_rows; /* 0 ~ 255 */
+	u32 num_bytes;
+	u32 jpg_crop_x;
+	u32 jpg_crop_y;
+	u32 jpg_crop_width;
+	u32 jpg_crop_height;
+	u32 jpg_mjpeg_mode;
+	u32 jpg_mjpeg_interlaced;
+};
+
+struct malone_codec_params {
+	u32 disp_imm;
+	u32 fourcc;
+	u32 codec_version;
+	u32 frame_rate;
+	u32 dbglog_enable;
+	u32 bsdma_lwm;
+	u32 bbd_coring;
+	u32 bbd_s_thr_row;
+	u32 bbd_p_thr_row;
+	u32 bbd_s_thr_logo_row;
+	u32 bbd_p_thr_logo_row;
+	u32 bbd_s_thr_col;
+	u32 bbd_p_thr_col;
+	u32 bbd_chr_thr_row;
+	u32 bbd_chr_thr_col;
+	u32 bbd_uv_mid_level;
+	u32 bbd_excl_win_mb_left;
+	u32 bbd_excl_win_mb_right;
+};
+
+struct malone_padding_scode {
+	u32 scode_type;
+	u32 pixelformat;
+	u32 data[2];
+};
+
+struct malone_fmt_mapping {
+	u32 pixelformat;
+	enum vpu_malone_format malone_format;
+};
+
+struct malone_scode_t {
+	struct vpu_inst *inst;
+	struct vb2_buffer *vb;
+	u32 wptr;
+	u32 need_data;
+};
+
+struct malone_scode_handler {
+	u32 pixelformat;
+	int (*insert_scode_seq)(struct malone_scode_t *scode);
+	int (*insert_scode_pic)(struct malone_scode_t *scode);
+};
+
+struct vpu_dec_ctrl {
+	struct malone_codec_params *codec_param;
+	struct malone_jpg_params *jpg;
+	void *seq_mem;
+	void *pic_mem;
+	void *gop_mem;
+	void *qmeter_mem;
+	void *dbglog_mem;
+	struct vpu_malone_str_buffer *str_buf[VID_API_NUM_STREAMS];
+	u32 buf_addr[VID_API_NUM_STREAMS];
+};
+
+u32 vpu_malone_get_data_size(void)
+{
+	return sizeof(struct vpu_dec_ctrl);
+}
+
+void vpu_malone_init_rpc(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr)
+{
+	struct malone_iface *iface;
+	struct vpu_dec_ctrl *hc;
+	unsigned long base_phy_addr;
+	unsigned long phy_addr;
+	unsigned long offset;
+	unsigned int i;
+
+	WARN_ON(!shared || !shared->priv);
+	WARN_ON(!rpc || !rpc->phys || !rpc->length || rpc->phys < boot_addr);
+
+	iface = rpc->virt;
+	base_phy_addr = rpc->phys - boot_addr;
+	hc = shared->priv;
+
+	shared->iface = iface;
+	shared->boot_addr = boot_addr;
+
+	iface->exec_base_addr = base_phy_addr;
+	iface->exec_area_size = rpc->length;
+
+	offset = sizeof(struct malone_iface);
+	phy_addr = base_phy_addr + offset;
+
+	shared->cmd_desc = &iface->cmd_buffer_desc.buffer;
+	shared->cmd_mem_vir = rpc->virt + offset;
+	iface->cmd_buffer_desc.buffer.start =
+	iface->cmd_buffer_desc.buffer.rptr =
+	iface->cmd_buffer_desc.buffer.wptr = phy_addr;
+	iface->cmd_buffer_desc.buffer.end = iface->cmd_buffer_desc.buffer.start + CMD_SIZE;
+	offset += CMD_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	shared->msg_desc = &iface->msg_buffer_desc.buffer;
+	shared->msg_mem_vir = rpc->virt + offset;
+	iface->msg_buffer_desc.buffer.start =
+	iface->msg_buffer_desc.buffer.wptr =
+	iface->msg_buffer_desc.buffer.rptr = phy_addr;
+	iface->msg_buffer_desc.buffer.end = iface->msg_buffer_desc.buffer.start + MSG_SIZE;
+	offset += MSG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->codec_param_tab_desc.array_base = phy_addr;
+	hc->codec_param = rpc->virt + offset;
+	offset += CODEC_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->jpeg_param_tab_desc.array_base = phy_addr;
+	hc->jpg = rpc->virt + offset;
+	offset += JPEG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->seq_info_tab_desc.array_base = phy_addr;
+	hc->seq_mem = rpc->virt + offset;
+	offset += SEQ_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->pic_info_tab_desc.array_base = phy_addr;
+	hc->pic_mem = rpc->virt + offset;
+	offset += PIC_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->gop_info_tab_desc.array_base = phy_addr;
+	hc->gop_mem = rpc->virt + offset;
+	offset += GOP_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->qmeter_info_tab_desc.array_base = phy_addr;
+	hc->qmeter_mem = rpc->virt + offset;
+	offset += QMETER_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->dbglog_desc.addr = phy_addr;
+	iface->dbglog_desc.size = DBGLOG_SIZE;
+	hc->dbglog_mem = rpc->virt + offset;
+	offset += DBGLOG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		iface->eng_access_buff_desc[i].buffer.start =
+		iface->eng_access_buff_desc[i].buffer.wptr =
+		iface->eng_access_buff_desc[i].buffer.rptr = phy_addr;
+		iface->eng_access_buff_desc[i].buffer.end =
+			iface->eng_access_buff_desc[i].buffer.start + ENG_SIZE;
+		offset += ENG_SIZE;
+		phy_addr = base_phy_addr + offset;
+	}
+
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		iface->encrypt_info[i] = phy_addr;
+		offset += sizeof(struct vpu_malone_encrypt_info);
+		phy_addr = base_phy_addr + offset;
+	}
+
+	rpc->bytesused = offset;
+}
+
+void vpu_malone_set_log_buf(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log)
+{
+	struct malone_iface *iface;
+
+	WARN_ON(!shared || !log || !log->phys);
+	vpu_dbg(LVL_DEBUG, "set log area <0x%llx, 0x%x> (0x%lx)\n",
+			log->phys, log->length, shared->boot_addr);
+	iface = shared->iface;
+	iface->debug_buffer_desc.buffer.start =
+	iface->debug_buffer_desc.buffer.wptr =
+	iface->debug_buffer_desc.buffer.rptr = log->phys - shared->boot_addr;
+	iface->debug_buffer_desc.buffer.end = iface->debug_buffer_desc.buffer.start + log->length;
+}
+
+static u32 get_str_buffer_offset(u32 instance)
+{
+	return DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * instance;
+}
+
+void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id)
+{
+	struct malone_iface *iface;
+	struct vpu_rpc_system_config *config;
+	struct vpu_dec_ctrl *hc;
+	int i;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	iface = shared->iface;
+	config = &iface->system_cfg;
+	hc = shared->priv;
+
+	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		u32 offset = get_str_buffer_offset(i);
+
+		hc->buf_addr[i] = regs_base + offset;
+		hc->str_buf[i] = regs + offset;
+	}
+}
+
+u32 vpu_malone_get_version(struct vpu_shared_addr *shared)
+{
+	struct malone_iface *iface;
+
+	WARN_ON(!shared || !shared->iface);
+
+	iface = shared->iface;
+	return iface->fw_version;
+}
+
+int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared)
+{
+	return 0xc00000;
+}
+
+int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance,
+					struct vpu_buffer *buf)
+{
+	struct malone_iface *iface;
+	struct vpu_dec_ctrl *hc;
+	struct vpu_malone_str_buffer *str_buf;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	iface = shared->iface;
+	hc = shared->priv;
+	str_buf = hc->str_buf[instance];
+	str_buf->wptr = str_buf->rptr = str_buf->start = buf->phys;
+	str_buf->end = buf->phys + buf->length;
+	str_buf->lwm = 0x1;
+
+	iface->stream_buffer_desc[instance][0] = hc->buf_addr[instance];
+
+	return 0;
+}
+
+int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_dec_ctrl *hc;
+	struct vpu_malone_str_buffer *str_buf;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	hc = shared->priv;
+	str_buf = hc->str_buf[instance];
+
+	if (desc) {
+		desc->wptr = str_buf->wptr;
+		desc->rptr = str_buf->rptr;
+		desc->start = str_buf->start;
+		desc->end = str_buf->end;
+	}
+
+	return 0;
+}
+
+static void vpu_malone_update_wptr(struct vpu_malone_str_buffer *str_buf,
+					u32 wptr)
+{
+	u32 size = str_buf->end - str_buf->start;
+	u32 space = (str_buf->rptr + size - str_buf->wptr) % size;
+	u32 step = (wptr + size - str_buf->wptr) % size;
+
+	if (space && step > space)
+		vpu_err("update wptr from 0x%x to 0x%x, cross over rptr 0x%x\n",
+				str_buf->wptr, wptr, str_buf->rptr);
+
+	/*update wptr after data is written*/
+	mb();
+	str_buf->wptr = wptr;
+}
+
+static void vpu_malone_update_rptr(struct vpu_malone_str_buffer *str_buf,
+					u32 rptr)
+{
+	u32 size = str_buf->end - str_buf->start;
+	u32 space = (str_buf->wptr + size - str_buf->rptr) % size;
+	u32 step = (rptr + size - str_buf->rptr) % size;
+
+	if (step > space)
+		vpu_err("update rptr from 0x%x to 0x%x, cross over wptr 0x%x\n",
+				str_buf->rptr, rptr, str_buf->wptr);
+	/*update rptr after data is read*/
+	mb();
+	str_buf->rptr = rptr;
+}
+
+int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance, u32 ptr, bool write)
+{
+	struct vpu_dec_ctrl *hc;
+	struct vpu_malone_str_buffer *str_buf;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	hc = shared->priv;
+	str_buf = hc->str_buf[instance];
+
+	if (write)
+		vpu_malone_update_wptr(str_buf, ptr);
+	else
+		vpu_malone_update_rptr(str_buf, ptr);
+
+	return 0;
+}
+
+static struct malone_fmt_mapping fmt_mappings[] = {
+	{V4L2_PIX_FMT_H264,        MALONE_FMT_AVC},
+	{V4L2_PIX_FMT_H264_MVC,    MALONE_FMT_AVC},
+	{V4L2_PIX_FMT_HEVC,        MALONE_FMT_HEVC},
+	{V4L2_PIX_FMT_VC1_ANNEX_G, MALONE_FMT_VC1},
+	{V4L2_PIX_FMT_VC1_ANNEX_L, MALONE_FMT_VC1},
+	{V4L2_PIX_FMT_MPEG2,       MALONE_FMT_MP2},
+	{V4L2_PIX_FMT_MPEG4,       MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_XVID,        MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_H263,        MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_JPEG,        MALONE_FMT_JPG},
+	{V4L2_PIX_FMT_VP8,         MALONE_FMT_VP8},
+};
+
+static enum vpu_malone_format vpu_malone_format_remap(u32 pixelformat)
+{
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(fmt_mappings); i++) {
+		if (pixelformat == fmt_mappings[i].pixelformat)
+			return fmt_mappings[i].malone_format;
+	}
+
+	return MALONE_FMT_NULL;
+}
+
+static void vpu_malone_set_stream_cfg(struct vpu_shared_addr *shared,
+		u32 instance, enum vpu_malone_format malone_format)
+{
+	struct malone_iface *iface;
+	u32 *curr_str_cfg;
+
+	iface = shared->iface;
+	curr_str_cfg = &iface->stream_config[instance];
+
+	*curr_str_cfg = 0;
+	STREAM_CONFIG_FORMAT_SET(malone_format, curr_str_cfg);
+	STREAM_CONFIG_STRBUFIDX_SET(0, curr_str_cfg);
+	STREAM_CONFIG_NOSEQ_SET(0, curr_str_cfg);
+	STREAM_CONFIG_DEBLOCK_SET(0, curr_str_cfg);
+	STREAM_CONFIG_DERING_SET(0, curr_str_cfg);
+	STREAM_CONFIG_PLAY_MODE_SET(0x3, curr_str_cfg);
+	STREAM_CONFIG_FS_CTRL_MODE_SET(0x1, curr_str_cfg);
+	STREAM_CONFIG_ENABLE_DCP_SET(1, curr_str_cfg);
+	STREAM_CONFIG_NUM_STR_BUF_SET(1, curr_str_cfg);
+	STREAM_CONFIG_MALONE_USAGE_SET(1, curr_str_cfg);
+	STREAM_CONFIG_MULTI_VID_SET(0, curr_str_cfg);
+	STREAM_CONFIG_OBFUSC_EN_SET(0, curr_str_cfg);
+	STREAM_CONFIG_RC4_EN_SET(0, curr_str_cfg);
+	STREAM_CONFIG_MCX_SET(1, curr_str_cfg);
+	STREAM_CONFIG_PES_SET(0, curr_str_cfg);
+	STREAM_CONFIG_NUM_DBE_SET(1, curr_str_cfg);
+}
+
+static int vpu_malone_set_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_decode_params *params)
+{
+	struct malone_iface *iface;
+	struct vpu_dec_ctrl *hc;
+	enum vpu_malone_format malone_format;
+
+	iface = shared->iface;
+	hc = shared->priv;
+	malone_format = vpu_malone_format_remap(params->codec_format);
+	iface->udata_buffer[instance].base = params->udata.base;
+	iface->udata_buffer[instance].slot_size = params->udata.size;
+
+	vpu_malone_set_stream_cfg(shared, instance, malone_format);
+
+	if (malone_format == MALONE_FMT_JPG) {
+		//1:JPGD_MJPEG_MODE_A; 2:JPGD_MJPEG_MODE_B
+		hc->jpg[instance].jpg_mjpeg_mode = 1;
+		//0: JPGD_MJPEG_PROGRESSIVE
+		hc->jpg[instance].jpg_mjpeg_interlaced = 0;
+	}
+
+	hc->codec_param[instance].disp_imm = params->b_dis_reorder ? 1 : 0;
+	hc->codec_param[instance].dbglog_enable = 0;
+	iface->dbglog_desc.level = 0;
+
+	if (params->b_non_frame)
+		iface->stream_buff_info[instance].stream_input_mode = NON_FRAME_LVL;
+	else
+		iface->stream_buff_info[instance].stream_input_mode = FRAME_LVL;
+	iface->stream_buff_info[instance].stream_buffer_threshold = 0;
+	iface->stream_buff_info[instance].stream_pic_input_count = 0;
+
+	return 0;
+}
+
+static bool vpu_malone_is_non_frame_mode(struct vpu_shared_addr *shared,
+					u32 instance)
+{
+	struct malone_iface *iface;
+
+	iface = shared->iface;
+	if (iface->stream_buff_info[instance].stream_input_mode == NON_FRAME_LVL)
+		return true;
+
+	return false;
+}
+
+static int vpu_malone_update_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_decode_params *params)
+{
+	struct malone_iface *iface;
+
+	iface = shared->iface;
+
+	if (params->end_flag)
+		iface->stream_buff_info[instance].stream_pic_end_flag = params->end_flag;
+	params->end_flag = 0;
+
+	return 0;
+}
+
+int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_decode_params *params, u32 update)
+{
+	if (!params)
+		return -EINVAL;
+
+	if (!update)
+		return vpu_malone_set_params(shared, instance, params);
+	else
+		return vpu_malone_update_params(shared, instance, params);
+}
+
+static struct vpu_pair malone_cmds[] = {
+	{VPU_CMD_ID_START, VID_API_CMD_START},
+	{VPU_CMD_ID_STOP, VID_API_CMD_STOP},
+	{VPU_CMD_ID_ABORT, VID_API_CMD_ABORT},
+	{VPU_CMD_ID_RST_BUF, VID_API_CMD_RST_BUF},
+	{VPU_CMD_ID_SNAPSHOT, VID_API_CMD_SNAPSHOT},
+	{VPU_CMD_ID_FIRM_RESET, VID_API_CMD_FIRM_RESET},
+	{VPU_CMD_ID_FS_ALLOC, VID_API_CMD_FS_ALLOC},
+	{VPU_CMD_ID_FS_RELEASE, VID_API_CMD_FS_RELEASE},
+	{VPU_CMD_ID_TIMESTAMP, VID_API_CMD_TS},
+	{VPU_CMD_ID_DEBUG, VID_API_CMD_FW_STATUS},
+};
+
+static struct vpu_pair malone_msgs[] = {
+	{VPU_MSG_ID_RESET_DONE, VID_API_EVENT_RESET_DONE},
+	{VPU_MSG_ID_START_DONE, VID_API_EVENT_START_DONE},
+	{VPU_MSG_ID_STOP_DONE, VID_API_EVENT_STOPPED},
+	{VPU_MSG_ID_ABORT_DONE, VID_API_EVENT_ABORT_DONE},
+	{VPU_MSG_ID_BUF_RST, VID_API_EVENT_STR_BUF_RST},
+	{VPU_MSG_ID_PIC_EOS, VID_API_EVENT_FINISHED},
+	{VPU_MSG_ID_SEQ_HDR_FOUND, VID_API_EVENT_SEQ_HDR_FOUND},
+	{VPU_MSG_ID_RES_CHANGE, VID_API_EVENT_RES_CHANGE},
+	{VPU_MSG_ID_PIC_HDR_FOUND, VID_API_EVENT_PIC_HDR_FOUND},
+	{VPU_MSG_ID_PIC_DECODED, VID_API_EVENT_PIC_DECODED},
+	{VPU_MSG_ID_DEC_DONE, VID_API_EVENT_FRAME_BUFF_RDY},
+	{VPU_MSG_ID_FRAME_REQ, VID_API_EVENT_REQ_FRAME_BUFF},
+	{VPU_MSG_ID_FRAME_RELEASE, VID_API_EVENT_REL_FRAME_BUFF},
+	{VPU_MSG_ID_FIFO_LOW, VID_API_EVENT_FIFO_LOW},
+	{VPU_MSG_ID_BS_ERROR, VID_API_EVENT_BS_ERROR},
+	{VPU_MSG_ID_UNSUPPORTED, VID_API_EVENT_UNSUPPORTED_STREAM},
+	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_EVENT_FIRMWARE_XCPT},
+};
+
+static void vpu_malone_pack_fs_alloc(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *fs)
+{
+	const u32 fs_type[] = {
+		[MEM_RES_FRAME] = 0,
+		[MEM_RES_MBI] = 1,
+		[MEM_RES_DCP] = 2,
+	};
+
+	pkt->hdr.num = 7;
+	pkt->data[0] = fs->id | (fs->tag << 24);
+	pkt->data[1] = fs->luma_addr;
+	if (fs->type == MEM_RES_FRAME) {
+		/*
+		 * if luma_addr equal to chroma_addr,
+		 * means luma(plane[0]) and chromau(plane[1]) used the
+		 * same fd -- usage of NXP codec2. Need to manually
+		 * offset chroma addr.
+		 */
+		if (fs->luma_addr == fs->chroma_addr)
+			fs->chroma_addr = fs->luma_addr + fs->luma_size;
+		pkt->data[2] = fs->luma_addr + fs->luma_size / 2;
+		pkt->data[3] = fs->chroma_addr;
+		pkt->data[4] = fs->chroma_addr + fs->chromau_size / 2;
+		pkt->data[5] = fs->bytesperline;
+	} else {
+		pkt->data[2] = fs->luma_size;
+		pkt->data[3] = 0;
+		pkt->data[4] = 0;
+		pkt->data[5] = 0;
+	}
+	pkt->data[6] = fs_type[fs->type];
+}
+
+static void vpu_malone_pack_fs_release(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *fs)
+{
+	pkt->hdr.num = 1;
+	pkt->data[0] = fs->id | (fs->tag << 24);
+}
+
+static void vpu_malone_pack_timestamp(struct vpu_rpc_event *pkt,
+					struct vpu_ts_info *info)
+{
+	pkt->hdr.num = 3;
+	if (info->timestamp < 0) {
+		pkt->data[0] = (u32)-1;
+		pkt->data[1] = 0;
+	} else {
+		pkt->data[0] = info->timestamp / NSEC_PER_SEC;
+		pkt->data[1] = info->timestamp % NSEC_PER_SEC;
+	}
+	pkt->data[2] = info->size;
+}
+
+int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)
+{
+	int ret;
+
+	WARN_ON(!pkt);
+
+	ret = vpu_find_dst_by_src(malone_cmds, ARRAY_SIZE(malone_cmds), id);
+	if (ret < 0)
+		return ret;
+
+	pkt->hdr.id = ret;
+	pkt->hdr.num = 0;
+	pkt->hdr.index = index;
+
+	switch (id) {
+	case VPU_CMD_ID_FS_ALLOC:
+		vpu_malone_pack_fs_alloc(pkt, data);
+		break;
+	case VPU_CMD_ID_FS_RELEASE:
+		vpu_malone_pack_fs_release(pkt, data);
+		break;
+	case VPU_CMD_ID_TIMESTAMP:
+		vpu_malone_pack_timestamp(pkt, data);
+		break;
+	}
+
+	pkt->hdr.index = index;
+	return 0;
+}
+
+int vpu_malone_convert_msg_id(u32 id)
+{
+	return vpu_find_src_by_dst(malone_msgs, ARRAY_SIZE(malone_msgs), id);
+}
+
+static void vpu_malone_fill_planes(struct vpu_dec_codec_info *info)
+{
+	u32 interlaced = info->progressive ? 0 : 1;
+
+	info->sizeimage[0] = vpu_helper_get_plane_size(info->pixfmt,
+			info->decoded_width, info->decoded_height,
+			0, info->stride, interlaced,
+			&info->bytesperline[0]);
+	info->sizeimage[1] = vpu_helper_get_plane_size(info->pixfmt,
+			info->decoded_width, info->decoded_height,
+			1, info->stride, interlaced,
+			&info->bytesperline[1]);
+}
+
+void vpu_malone_init_seq_hdr(struct vpu_dec_codec_info *info)
+{
+	u32 chunks = info->num_dfe_area >> MALONE_DCP_CHUNK_BIT;
+
+	vpu_malone_fill_planes(info);
+
+	info->mbi_size = (info->sizeimage[0] + info->sizeimage[1]) >> 2;
+	info->mbi_size = ALIGN(info->mbi_size, MALONE_ALIGN_MBI);
+
+	info->dcp_size = MALONE_DCP_SIZE_MAX;
+	if (chunks) {
+		u32 mb_num;
+		u32 mb_w;
+		u32 mb_h;
+
+		mb_w = DIV_ROUND_UP(info->decoded_width, 16);
+		mb_h = DIV_ROUND_UP(info->decoded_height, 16);
+		mb_num = mb_w * mb_h;
+		info->dcp_size = mb_num * MALONE_DCP_FIXED_MB_ALLOC * chunks;
+		info->dcp_size = clamp_t(u32, info->dcp_size,
+					MALONE_DCP_SIZE_MIN, MALONE_DCP_SIZE_MAX);
+	}
+}
+
+static void vpu_malone_unpack_seq_hdr(struct vpu_rpc_event *pkt,
+					struct vpu_dec_codec_info *info)
+{
+	info->num_ref_frms = pkt->data[0];
+	info->num_dpb_frms = pkt->data[1];
+	info->num_dfe_area = pkt->data[2];
+	info->progressive = pkt->data[3];
+	info->width = pkt->data[5];
+	info->height = pkt->data[4];
+	info->decoded_width = pkt->data[12];
+	info->decoded_height = pkt->data[11];
+	info->frame_rate = pkt->data[8];
+	info->dsp_asp_ratio = pkt->data[9];
+	info->level_idc = pkt->data[10];
+	info->bit_depth_luma = pkt->data[13];
+	info->bit_depth_chroma = pkt->data[14];
+	info->chroma_fmt = pkt->data[15];
+	info->color_primaries = vpu_color_cvrt_primaries_i2v(pkt->data[16]);
+	info->transfer_chars = vpu_color_cvrt_transfers_i2v(pkt->data[17]);
+	info->matrix_coeffs = vpu_color_cvrt_matrix_i2v(pkt->data[18]);
+	info->full_range = vpu_color_cvrt_full_range_i2v(pkt->data[19]);
+	info->vui_present = pkt->data[20];
+	info->mvc_num_views = pkt->data[21];
+	info->offset_x = pkt->data[23];
+	info->offset_y = pkt->data[25];
+	info->tag = pkt->data[27];
+	if (info->bit_depth_luma > 8)
+		info->pixfmt = V4L2_PIX_FMT_NV12_10BE_8L128;
+	else
+		info->pixfmt = V4L2_PIX_FMT_NV12_8L128;
+	vpu_malone_init_seq_hdr(info);
+}
+
+static void vpu_malone_unpack_pic_info(struct vpu_rpc_event *pkt,
+					struct vpu_dec_pic_info *info)
+{
+	info->id = pkt->data[7];
+	info->luma = pkt->data[0];
+	info->start = pkt->data[10];
+	info->end = pkt->data[12];
+	info->pic_size = pkt->data[11];
+	info->stride = pkt->data[5];
+	info->consumed_count = pkt->data[13];
+	if (info->id == MALONE_SKIPPED_FRAME_ID)
+		info->skipped = 1;
+	else
+		info->skipped = 0;
+}
+
+static void vpu_malone_unpack_req_frame(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *info)
+{
+	info->type = pkt->data[1];
+}
+
+static void vpu_malone_unpack_rel_frame(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *info)
+{
+	info->id = pkt->data[0];
+	info->type = pkt->data[1];
+	info->not_displayed = pkt->data[2];
+}
+
+static void vpu_malone_unpack_buff_rdy(struct vpu_rpc_event *pkt,
+					struct vpu_dec_pic_info *info)
+{
+	info->id = pkt->data[0];
+	info->luma = pkt->data[1];
+	info->stride = pkt->data[3];
+	if (info->id == MALONE_SKIPPED_FRAME_ID)
+		info->skipped = 1;
+	else
+		info->skipped = 0;
+	info->timestamp = MAKE_TIMESTAMP(pkt->data[9], pkt->data[10]);
+}
+
+int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)
+{
+	if (!pkt || !data)
+		return -EINVAL;
+
+	switch (pkt->hdr.id) {
+	case VID_API_EVENT_SEQ_HDR_FOUND:
+		vpu_malone_unpack_seq_hdr(pkt, data);
+		break;
+	case VID_API_EVENT_PIC_DECODED:
+		vpu_malone_unpack_pic_info(pkt, data);
+		break;
+	case VID_API_EVENT_REQ_FRAME_BUFF:
+		vpu_malone_unpack_req_frame(pkt, data);
+		break;
+	case VID_API_EVENT_REL_FRAME_BUFF:
+		vpu_malone_unpack_rel_frame(pkt, data);
+		break;
+	case VID_API_EVENT_FRAME_BUFF_RDY:
+		vpu_malone_unpack_buff_rdy(pkt, data);
+		break;
+	}
+
+	return 0;
+}
+
+static const struct malone_padding_scode padding_scodes[] = {
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H264,        {0x0B010000, 0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H264_MVC,    {0x0B010000, 0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_HEVC,        {0x4A010000, 0x20}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_MPEG2,       {0xCC010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_MPEG4,       {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_XVID,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H263,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VP8,         {0x34010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0xefff0000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H264,        {0x0B010000, 0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H264_MVC,    {0x0B010000, 0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_HEVC,        {0x4A010000, 0x20}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_MPEG2,       {0xb7010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_MPEG4,       {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_XVID,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H263,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VP8,         {0x34010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0x0, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264,        {0x15010000, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC,    {0x15010000, 0x0}},
+};
+static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0};
+
+static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt)
+{
+	const struct malone_padding_scode *s;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(padding_scodes); i++) {
+		s = &padding_scodes[i];
+
+		if (s->scode_type == type && s->pixelformat == fmt)
+			return s;
+	}
+
+	if (type != SCODE_PADDING_BUFFLUSH)
+		return &padding_scode_dft;
+
+	return NULL;
+}
+
+static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer,
+			struct vpu_malone_str_buffer *str_buf,
+			u32 pixelformat, u32 scode_type)
+{
+	u32 wptr;
+	u32 size;
+	u32 total_size = 0;
+	const struct malone_padding_scode *ps;
+	const u32 padding_size = 4096;
+	int ret;
+
+	ps = get_padding_scode(scode_type, pixelformat);
+	if (!ps)
+		return -EINVAL;
+
+	wptr = str_buf->wptr;
+	size = ALIGN(wptr, 4) - wptr;
+	if (size)
+		vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size);
+	total_size += size;
+
+	size = sizeof(ps->data);
+	ret = vpu_helper_copy_to_stream_buffer(stream_buffer, &wptr, size, (void *)ps->data);
+	if (ret < size)
+		return -EINVAL;
+	total_size += size;
+
+	size = padding_size - sizeof(ps->data);
+	vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size);
+	total_size += size;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+	return total_size;
+}
+
+int vpu_malone_add_scode(struct vpu_shared_addr *shared,
+				u32 instance,
+				struct vpu_buffer *stream_buffer,
+				u32 pixelformat,
+				u32 scode_type)
+{
+	struct vpu_dec_ctrl *hc;
+	struct vpu_malone_str_buffer *str_buf;
+	int ret = -EINVAL;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	hc = shared->priv;
+	str_buf = hc->str_buf[instance];
+
+	switch (scode_type) {
+	case SCODE_PADDING_EOS:
+	case SCODE_PADDING_ABORT:
+	case SCODE_PADDING_BUFFLUSH:
+		ret = vpu_malone_add_padding_scode(stream_buffer,
+				str_buf, pixelformat, scode_type);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+#define MALONE_PAYLOAD_HEADER_SIZE		16
+#define MALONE_CODEC_VERSION_ID			0x1
+#define MALONE_CODEC_ID_VC1_SIMPLE		0x10
+#define MALONE_CODEC_ID_VC1_MAIN		0x11
+#define MALONE_CODEC_ID_ARV8			0x28
+#define MALONE_CODEC_ID_ARV9			0x29
+#define MALONE_CODEC_ID_VP6			0x36
+#define MALONE_CODEC_ID_VP8			0x36
+#define MALONE_CODEC_ID_DIVX3			0x38
+#define MALONE_CODEC_ID_SPK			0x39
+
+#define MALONE_VP8_IVF_SEQ_HEADER_LEN		32
+#define MALONE_VP8_IVF_FRAME_HEADER_LEN		8
+
+#define MALONE_VC1_RCV_CODEC_V1_VERSION		0x85
+#define MALONE_VC1_RCV_CODEC_V2_VERSION		0xC5
+#define MALONE_VC1_RCV_NUM_FRAMES		0xFF
+#define MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE	4
+#define MALONE_VC1_RCV_SEQ_HEADER_LEN		20
+#define MALONE_VC1_RCV_PIC_HEADER_LEN		4
+#define MALONE_VC1_NAL_HEADER_LEN		4
+#define MALONE_VC1_CONTAIN_NAL(data)		((data & 0x00FFFFFF) == 0x00010000)
+
+
+static void set_payload_hdr(u8 *dst, u32 scd_type, u32 codec_id,
+		u32 buffer_size, u32 width, u32 height)
+{
+	unsigned int payload_size;
+	/* payload_size = buffer_size + itself_size(16) - start_code(4) */
+	payload_size = buffer_size + 12;
+
+	dst[0] = 0x00;
+	dst[1] = 0x00;
+	dst[2] = 0x01;
+	dst[3] = scd_type;
+
+	/* length */
+	dst[4] = ((payload_size>>16)&0xff);
+	dst[5] = ((payload_size>>8)&0xff);
+	dst[6] = 0x4e;
+	dst[7] = ((payload_size>>0)&0xff);
+
+	/* Codec ID and Version */
+	dst[8] = codec_id;
+	dst[9] = MALONE_CODEC_VERSION_ID;
+
+	/* width */
+	dst[10] = ((width>>8)&0xff);
+	dst[11] = ((width>>0)&0xff);
+	dst[12] = 0x58;
+
+	/* height */
+	dst[13] = ((height>>8)&0xff);
+	dst[14] = ((height>>0)&0xff);
+	dst[15] = 0x50;
+}
+
+static void set_vp8_ivf_seqhdr(u8 *dst, u32 width, u32 height)
+{
+	/* 0-3byte signature "DKIF" */
+	dst[0] = 0x44;
+	dst[1] = 0x4b;
+	dst[2] = 0x49;
+	dst[3] = 0x46;
+	/* 4-5byte version: should be 0*/
+	dst[4] = 0x00;
+	dst[5] = 0x00;
+	/* 6-7 length of Header */
+	dst[6] = MALONE_VP8_IVF_SEQ_HEADER_LEN;
+	dst[7] = MALONE_VP8_IVF_SEQ_HEADER_LEN >> 8;
+	/* 8-11 VP8 fourcc */
+	dst[8] = 0x56;
+	dst[9] = 0x50;
+	dst[10] = 0x38;
+	dst[11] = 0x30;
+	/* 12-13 width in pixels */
+	dst[12] = width;
+	dst[13] = width >> 8;
+	/* 14-15 height in pixels */
+	dst[14] = height;
+	dst[15] = height >> 8;
+	/* 16-19 frame rate */
+	dst[16] = 0xe8;
+	dst[17] = 0x03;
+	dst[18] = 0x00;
+	dst[19] = 0x00;
+	/* 20-23 time scale */
+	dst[20] = 0x01;
+	dst[21] = 0x00;
+	dst[22] = 0x00;
+	dst[23] = 0x00;
+	/* 24-27 number frames */
+	dst[24] = 0xdf;
+	dst[25] = 0xf9;
+	dst[26] = 0x09;
+	dst[27] = 0x00;
+	/* 28-31 reserved */
+}
+
+static void set_vp8_ivf_pichdr(u8 *dst, u32 frame_size)
+{
+	/*
+	 * firmware just parse 64-bit timestamp(8 bytes).
+	 * As not transfer timestamp to firmware, use default value(ZERO).
+	 * No need to do anything here
+	 */
+}
+
+static void set_vc1_rcv_seqhdr(u8 *dst, u8 *src, u32 width, u32 height)
+{
+	u32 frames = MALONE_VC1_RCV_NUM_FRAMES;
+	u32 ext_data_size = MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE;
+
+	/* 0-2 Number of frames, used default value 0xFF */
+	dst[0] = frames;
+	dst[1] = frames >> 8;
+	dst[2] = frames >> 16;
+
+	/* 3 RCV version, used V1 */
+	dst[3] = MALONE_VC1_RCV_CODEC_V1_VERSION;
+
+	/* 4-7 extension data size */
+	dst[4] = ext_data_size;
+	dst[5] = ext_data_size >> 8;
+	dst[6] = ext_data_size >> 16;
+	dst[7] = ext_data_size >> 24;
+	/* 8-11 extension data */
+	dst[8] = src[0];
+	dst[9] = src[1];
+	dst[10] = src[2];
+	dst[11] = src[3];
+
+	/* height */
+	dst[12] = height;
+	dst[13] = (height >> 8) & 0xff;
+	dst[14] = (height >> 16) & 0xff;
+	dst[15] = (height >> 24) & 0xff;
+	/* width */
+	dst[16] = width;
+	dst[17] = (width >> 8) & 0xff;
+	dst[18] = (width >> 16) & 0xff;
+	dst[19] = (width >> 24) & 0xff;
+}
+
+static void set_vc1_rcv_pichdr(u8 *dst, u32 buffer_size)
+{
+	dst[0] = buffer_size;
+	dst[1] = buffer_size >> 8;
+	dst[2] = buffer_size >> 16;
+	dst[3] = buffer_size >> 24;
+}
+
+static void create_vc1_nal_pichdr(u8 *dst)
+{
+	/* need insert nal header: special ID */
+	dst[0] = 0x0;
+	dst[1] = 0x0;
+	dst[2] = 0x01;
+	dst[3] = 0x0D;
+}
+
+static int vpu_malone_insert_scode_seq(struct malone_scode_t *scode, u32 codec_id, u32 ext_size)
+{
+	u8 hdr[MALONE_PAYLOAD_HEADER_SIZE];
+	int ret;
+
+	set_payload_hdr(hdr,
+			SCODE_SEQUENCE,
+			codec_id,
+			ext_size,
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(hdr),
+						hdr);
+	return ret;
+}
+
+static int vpu_malone_insert_scode_pic(struct malone_scode_t *scode, u32 codec_id, u32 ext_size)
+{
+	u8 hdr[MALONE_PAYLOAD_HEADER_SIZE];
+	int ret;
+
+	set_payload_hdr(hdr,
+			SCODE_PICTURE,
+			codec_id,
+			ext_size + vb2_get_plane_payload(scode->vb, 0),
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(hdr),
+						hdr);
+	return 0;
+}
+
+static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode)
+{
+	struct vb2_v4l2_buffer *vbuf;
+	u8 nal_hdr[MALONE_VC1_NAL_HEADER_LEN];
+	u32 *data = NULL;
+
+	vbuf = to_vb2_v4l2_buffer(scode->vb);
+	data = vb2_plane_vaddr(scode->vb, 0);
+
+	if (vbuf->sequence == 0 || (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG))
+		return 0;
+	if (MALONE_VC1_CONTAIN_NAL(*data))
+		return 0;
+
+	create_vc1_nal_pichdr(nal_hdr);
+	return vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(nal_hdr),
+						nal_hdr);
+}
+
+static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN];
+
+	scode->need_data = 0;
+
+	ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VC1_SIMPLE,
+					  sizeof(rcv_seqhdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vc1_rcv_seqhdr(rcv_seqhdr,
+			   vb2_plane_vaddr(scode->vb, 0),
+			   scode->inst->out_format.width,
+			   scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(rcv_seqhdr),
+						rcv_seqhdr);
+
+	if (ret < 0)
+		return ret;
+	size += ret;
+	return size;
+}
+
+static int vpu_malone_insert_scode_vc1_l_pic(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 rcv_pichdr[MALONE_VC1_RCV_PIC_HEADER_LEN];
+
+	ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VC1_SIMPLE,
+					  sizeof(rcv_pichdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vc1_rcv_pichdr(rcv_pichdr, vb2_get_plane_payload(scode->vb, 0));
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(rcv_pichdr),
+						rcv_pichdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+	return size;
+}
+
+static int vpu_malone_insert_scode_vp8_seq(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 ivf_hdr[MALONE_VP8_IVF_SEQ_HEADER_LEN];
+
+	ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vp8_ivf_seqhdr(ivf_hdr,
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(ivf_hdr),
+						ivf_hdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+
+	return size;
+}
+
+static int vpu_malone_insert_scode_vp8_pic(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 ivf_hdr[MALONE_VP8_IVF_FRAME_HEADER_LEN] = {0};
+
+	ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vp8_ivf_pichdr(ivf_hdr, vb2_get_plane_payload(scode->vb, 0));
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(ivf_hdr),
+						ivf_hdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+
+	return size;
+}
+
+static const struct malone_scode_handler scode_handlers[] = {
+	{
+		/* fix me, need to swap return operation after gstreamer swap */
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.insert_scode_seq = vpu_malone_insert_scode_vc1_l_seq,
+		.insert_scode_pic = vpu_malone_insert_scode_vc1_l_pic,
+	},
+	{
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.insert_scode_pic = vpu_malone_insert_scode_vc1_g_pic,
+	},
+	{
+		.pixelformat = V4L2_PIX_FMT_VP8,
+		.insert_scode_seq = vpu_malone_insert_scode_vp8_seq,
+		.insert_scode_pic = vpu_malone_insert_scode_vp8_pic,
+	},
+};
+
+const struct malone_scode_handler *get_scode_handler(u32 pixelformat)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(scode_handlers); i++) {
+		if (scode_handlers[i].pixelformat == pixelformat)
+			return &scode_handlers[i];
+	}
+
+	return NULL;
+}
+
+static int vpu_malone_insert_scode(struct malone_scode_t *scode, u32 type)
+{
+	const struct malone_scode_handler *handler;
+	int ret = 0;
+
+	if (!scode || !scode->inst || !scode->vb)
+		return 0;
+
+	scode->need_data = 1;
+	handler = get_scode_handler(scode->inst->out_format.pixfmt);
+	if (!handler)
+		return 0;
+
+	switch (type) {
+	case SCODE_SEQUENCE:
+		if (handler->insert_scode_seq)
+			ret = handler->insert_scode_seq(scode);
+		break;
+	case SCODE_PICTURE:
+		if (handler->insert_scode_pic)
+			ret = handler->insert_scode_pic(scode);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer *str_buf,
+				struct vpu_inst *inst, struct vb2_buffer *vb,
+				u32 disp_imm)
+{
+	struct malone_scode_t scode;
+	struct vb2_v4l2_buffer *vbuf;
+	u32 wptr;
+	int size = 0;
+	int ret = 0;
+
+	wptr = str_buf->wptr;
+
+	/*add scode: SCODE_SEQUENCE, SCODE_PICTURE, SCODE_SLICE*/
+	vbuf = to_vb2_v4l2_buffer(vb);
+	scode.inst = inst;
+	scode.vb = vb;
+	scode.wptr = wptr;
+	scode.need_data = 1;
+	if (vbuf->sequence == 0 || (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG))
+		ret = vpu_malone_insert_scode(&scode, SCODE_SEQUENCE);
+
+	if (ret < 0)
+		return -ENOMEM;
+	size += ret;
+	wptr = scode.wptr;
+	if (!scode.need_data) {
+		vpu_malone_update_wptr(str_buf, wptr);
+		return size;
+	}
+
+	ret = vpu_malone_insert_scode(&scode, SCODE_PICTURE);
+	if (ret < 0)
+		return -ENOMEM;
+	size += ret;
+	wptr = scode.wptr;
+
+	ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer,
+						&wptr,
+						vb2_get_plane_payload(vb, 0),
+						vb2_plane_vaddr(vb, 0));
+	if (ret < vb2_get_plane_payload(vb, 0))
+		return -ENOMEM;
+	size += ret;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+
+	if (disp_imm && !(vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG)) {
+		ret = vpu_malone_add_scode(inst->core->iface,
+					     inst->id,
+					     &inst->stream_buffer,
+					     inst->out_format.pixfmt,
+					     SCODE_PADDING_BUFFLUSH);
+		if (ret < 0)
+			return ret;
+		size += ret;
+	}
+
+	return size;
+}
+
+static int vpu_malone_input_stream_data(struct vpu_malone_str_buffer *str_buf,
+				struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf;
+	u32 wptr;
+	int ret = 0;
+
+	wptr = str_buf->wptr;
+	vbuf = to_vb2_v4l2_buffer(vb);
+	ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer,
+						&wptr,
+						vb2_get_plane_payload(vb, 0),
+						vb2_plane_vaddr(vb, 0));
+	if (ret < vb2_get_plane_payload(vb, 0))
+		return -ENOMEM;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+
+	return ret;
+}
+
+static int vpu_malone_input_ts(struct vpu_inst *inst, s64  timestamp, u32 size)
+{
+	struct vpu_ts_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.timestamp = timestamp;
+	info.size = size;
+
+	return vpu_session_fill_timestamp(inst, &info);
+}
+
+int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vpu_dec_ctrl *hc;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_malone_str_buffer *str_buf;
+	u32 disp_imm = 0;
+	u32 size;
+	int ret;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+	hc = shared->priv;
+	str_buf = hc->str_buf[inst->id];
+	disp_imm = hc->codec_param[inst->id].disp_imm;
+
+	if (vpu_malone_is_non_frame_mode(shared, inst->id))
+		ret = vpu_malone_input_stream_data(str_buf, inst, vb);
+	else
+		ret = vpu_malone_input_frame_data(str_buf, inst, vb, disp_imm);
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	/*
+	 * if buffer only contain codec data, and the timestamp is invalid,
+	 * don't put the invalid timestamp to resync
+	 * merge the data to next frame
+	 */
+	vbuf = to_vb2_v4l2_buffer(vb);
+	if ((vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) && (s64)vb->timestamp < 0) {
+		inst->extra_size += size;
+		return 0;
+	}
+	if (inst->extra_size) {
+		size += inst->extra_size;
+		inst->extra_size = 0;
+	}
+
+	ret = vpu_malone_input_ts(inst, vb->timestamp, size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static bool vpu_malone_check_ready(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface;
+	struct vpu_rpc_buffer_desc *desc;
+	u32 size;
+	u32 rptr;
+	u32 wptr;
+	u32 used;
+
+	iface = shared->iface;
+	desc = &iface->api_cmd_buffer_desc[instance];
+	size = desc->end - desc->start;
+	rptr = desc->rptr;
+	wptr = desc->wptr;
+	used = (wptr + size - rptr) % size;
+	if (!size || used < size / 2)
+		return true;
+
+	vpu_dbg(LVL_DEBUG, "[%d]api cmd used = %d/%d\n", instance, used, size);
+
+	return false;
+}
+
+bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance)
+{
+	u32 cnt = 0;
+
+	while (!vpu_malone_check_ready(shared, instance)) {
+		if (cnt > 30)
+			return false;
+		mdelay(1);
+		cnt++;
+	}
+	return true;
+}
+
+int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance)
+{
+	if (!vpu_malone_is_ready(shared, instance)) {
+		vpu_err("[%d] is not ready\n", instance);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface;
+	struct vpu_rpc_buffer_desc *desc;
+
+	iface = shared->iface;
+	desc = &iface->api_cmd_buffer_desc[instance];
+	desc->wptr++;
+	if (desc->wptr == desc->end)
+		desc->wptr = desc->start;
+
+	return 0;
+}
+
+int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface;
+	struct vpu_rpc_buffer_desc *desc;
+
+	iface = shared->iface;
+	desc = &iface->api_cmd_buffer_desc[instance];
+	desc->wptr = desc->rptr;
+	if (desc->wptr == desc->end)
+		desc->wptr = desc->start;
+
+	return 0;
+}
+
+u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared)
+{
+	struct malone_iface *iface = shared->iface;
+
+	return iface->max_streams;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_malone.h b/drivers/media/platform/imx/vpu-8q/vpu_malone.h
new file mode 100644
index 000000000000..22c834a030a9
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_malone.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_MALONE_H
+#define _IMX_VPU_MALONE_H
+
+u32 vpu_malone_get_data_size(void);
+void vpu_malone_init_rpc(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr);
+void vpu_malone_set_log_buf(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log);
+void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id);
+u32 vpu_malone_get_version(struct vpu_shared_addr *shared);
+int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared);
+int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance, struct vpu_buffer *buf);
+int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_rpc_buffer_desc *desc);
+int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance, u32 ptr, bool write);
+int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_decode_params *params, u32 update);
+int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+int vpu_malone_convert_msg_id(u32 msg_id);
+int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data);
+int vpu_malone_add_scode(struct vpu_shared_addr *shared,
+				u32 instance,
+				struct vpu_buffer *stream_buffer,
+				u32 pixelformat,
+				u32 scode_type);
+int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb);
+bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance);
+u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared);
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:08 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:08 +0800
Subject: [PATCH v6 12/14] ARM64: dts: freescale: imx8q: add imx vpu codec
 entries
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <fc8af80f3f31e195761990b5bad434099e5c7669.1628671163.git.ming.qian@nxp.com>

Add the Video Processing Unit node for IMX8Q SoC.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi | 72 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 17 +++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    | 24 +++++++
 3 files changed, 113 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
new file mode 100644
index 000000000000..f2dde6d14ca3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ *	Dong Aisheng <aisheng.dong at nxp.com>
+ */
+
+vpu: vpu at 2c000000 {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0x2c000000 0x0 0x2c000000 0x2000000>;
+	reg = <0 0x2c000000 0 0x1000000>;
+	power-domains = <&pd IMX_SC_R_VPU>;
+	status = "disabled";
+
+	mu_m0: mailbox at 2d000000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d000000 0x20000>;
+		interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+		status = "okay";
+	};
+
+	mu1_m0: mailbox at 2d020000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d020000 0x20000>;
+		interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+		status = "okay";
+	};
+
+	mu2_m0: mailbox at 2d040000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d040000 0x20000>;
+		interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+		status = "disabled";
+	};
+
+	vpu_core0: vpu_core at 2d080000 {
+		reg = <0x2d080000 0x10000>;
+		compatible = "nxp,imx8q-vpu-decoder";
+		power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu_m0 0 0>,
+			<&mu_m0 0 1>,
+			<&mu_m0 1 0>;
+		status = "disabled";
+	};
+	vpu_core1: vpu_core at 2d090000 {
+		reg = <0x2d090000 0x10000>;
+		compatible = "nxp,imx8q-vpu-encoder";
+		power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu1_m0 0 0>,
+			<&mu1_m0 0 1>,
+			<&mu1_m0 1 0>;
+		status = "disabled";
+	};
+	vpu_core2: vpu_core at 2d0a0000 {
+		reg = <0x2d0a0000 0x10000>;
+		compatible = "nxp,imx8q-vpu-encoder";
+		power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu2_m0 0 0>,
+			<&mu2_m0 0 1>,
+			<&mu2_m0 1 0>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 863232a47004..05495b60beb8 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -196,6 +196,23 @@ &usdhc2 {
 	status = "okay";
 };
 
+&vpu {
+	compatible = "nxp,imx8qxp-vpu";
+	status = "okay";
+};
+
+&vpu_core0 {
+	reg = <0x2d040000 0x10000>;
+	memory-region = <&decoder_boot>, <&decoder_rpc>;
+	status = "okay";
+};
+
+&vpu_core1 {
+	reg = <0x2d050000 0x10000>;
+	memory-region = <&encoder_boot>, <&encoder_rpc>;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl_fec1: fec1grp {
 		fsl,pins = <
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 1e6b4995091e..6b421cfa5534 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -46,6 +46,9 @@ aliases {
 		serial1 = &lpuart1;
 		serial2 = &lpuart2;
 		serial3 = &lpuart3;
+		vpu_core0 = &vpu_core0;
+		vpu_core1 = &vpu_core1;
+		vpu_core2 = &vpu_core2;
 	};
 
 	cpus {
@@ -134,10 +137,30 @@ reserved-memory {
 		#size-cells = <2>;
 		ranges;
 
+		decoder_boot: decoder-boot at 84000000 {
+			reg = <0 0x84000000 0 0x2000000>;
+			no-map;
+		};
+
+		encoder_boot: encoder-boot at 86000000 {
+			reg = <0 0x86000000 0 0x200000>;
+			no-map;
+		};
+
+		decoder_rpc: decoder-rpc at 0x92000000 {
+			reg = <0 0x92000000 0 0x100000>;
+			no-map;
+		};
+
 		dsp_reserved: dsp at 92400000 {
 			reg = <0 0x92400000 0 0x2000000>;
 			no-map;
 		};
+
+		encoder_rpc: encoder-rpc at 0x94400000 {
+			reg = <0 0x94400000 0 0x700000>;
+			no-map;
+		};
 	};
 
 	pmu {
@@ -258,6 +281,7 @@ map0 {
 	};
 
 	/* sorted in register address */
+	#include "imx8-ss-vpu.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"
 	#include "imx8-ss-ddr.dtsi"
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:09 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:09 +0800
Subject: [PATCH v6 13/14] firmware: imx: scu-pd: imx8q: add vpu mu resources
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <6d0d2b8677ba40b8007aa46a02b676838f9b27d3.1628671163.git.ming.qian@nxp.com>

the vpu core depends on the mu resources.
if they're missed, the vpu can't work.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/firmware/imx/scu-pd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index ff6569c4a53b..af3d057e6421 100644
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -155,6 +155,10 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
 	{ "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },
 	{ "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },
 	{ "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, false, 0 },
+	{ "vpu-enc1", IMX_SC_R_VPU_ENC_1, 1, false, 0 },
+	{ "vpu-mu0", IMX_SC_R_VPU_MU_0, 1, false, 0 },
+	{ "vpu-mu1", IMX_SC_R_VPU_MU_1, 1, false, 0 },
+	{ "vpu-mu2", IMX_SC_R_VPU_MU_2, 1, false, 0 },
 
 	/* GPU SS */
 	{ "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, true, 0 },
-- 
2.32.0



From ming.qian at nxp.com  Wed Aug 11 01:43:10 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 11 Aug 2021 16:43:10 +0800
Subject: [PATCH v6 14/14] MAINTAINERS: add NXP IMX8Q VPU CODEC V4L2 driver
 entry
In-Reply-To: <cover.1628671163.git.ming.qian@nxp.com>
References: <cover.1628671163.git.ming.qian@nxp.com>
Message-ID: <2d1fc6f2be99f96e34a1074485e936f6bfb4b1f5.1628671163.git.ming.qian@nxp.com>

Add NXP IMX8Q VPU CODEC v4l2 driver entry

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 524eabe50d79..77d30a55983a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13416,6 +13416,16 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/imx8-jpeg.yaml
 F:	drivers/media/platform/imx-jpeg
 
+NXP i.MX 8QXP/8QM VPU CODEC V4L2 DRIVER
+M:	Ming Qian <ming.qian at nxp.com>
+M:	Shijie Qin <shijie.qin at nxp.com>
+M:	Zhou Peng <eagle.zhou at nxp.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
+F:	drivers/media/platform/imx/vpu-8q/
+F:	include/uapi/linux/imx_vpu.h
+
 NZXT-KRAKEN2 HARDWARE MONITORING DRIVER
 M:	Jonas Malaco <jonas at protocubo.io>
 L:	linux-hwmon at vger.kernel.org
-- 
2.32.0



From shameerali.kolothum.thodi at huawei.com  Wed Aug 11 01:47:34 2021
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Wed, 11 Aug 2021 08:47:34 +0000
Subject: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU schedule out
In-Reply-To: <20210803153036.GA31125@willie-the-truck>
References: <20210729104009.382-1-shameerali.kolothum.thodi@huawei.com>
 <20210729104009.382-5-shameerali.kolothum.thodi@huawei.com>
 <20210803114034.GB30853@willie-the-truck>
 <ee2863107d614ef8a36006b5aa912eca@huawei.com>
 <20210803153036.GA31125@willie-the-truck>
Message-ID: <99805c8519d14491a33f98592bf30a54@huawei.com>

Hi Will,

> -----Original Message-----
> From: Will Deacon [mailto:will at kernel.org]
> Sent: 03 August 2021 16:31
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org; maz at kernel.org; catalin.marinas at arm.com;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Linuxarm
> <linuxarm at huawei.com>
> Subject: Re: [PATCH v3 4/4] KVM: arm64: Clear active_vmids on vCPU
> schedule out

[...]
 
> I think we have to be really careful not to run into the "suspended
> animation" problem described in ae120d9edfe9 ("ARM: 7767/1: let the ASID
> allocator handle suspended animation") if we go down this road.
> 
> Maybe something along the lines of:
> 
> ROLLOVER
> 
>   * Take lock
>   * Inc generation
>     => This will force everybody down the slow path
>   * Record active VMIDs
>   * Broadcast TLBI
>     => Only active VMIDs can be dirty
>     => Reserve active VMIDs and mark as allocated
> 
> VCPU SCHED IN
> 
>   * Set active VMID
>   * Check generation
>   * If mismatch then:
>         * Take lock
>         * Try to match a reserved VMID
>         * If no reserved VMID, allocate new
> 
> VCPU SCHED OUT
> 
>   * Clear active VMID
> 
> but I'm not daft enough to think I got it right first time. I think it
> needs both implementing *and* modelling in TLA+ before we merge it!

I attempted to implement the above algo as below. It seems to be
working in both 16-bit vmid and 4-bit vmid test setup. Though I am
not quite sure this Is exactly what you had in mind above and covers
all corner cases.

Please take a look and let me know.
(The diff below is against this v3 series)

Thanks,
Shameer

--->8<----

--- a/arch/arm64/kvm/vmid.c
+++ b/arch/arm64/kvm/vmid.c
@@ -43,7 +43,7 @@ static void flush_context(void)
        bitmap_clear(vmid_map, 0, NUM_USER_VMIDS);

        for_each_possible_cpu(cpu) {
-               vmid = atomic64_xchg_relaxed(&per_cpu(active_vmids, cpu), 0);
+               vmid = atomic64_read(&per_cpu(active_vmids, cpu));

                /* Preserve reserved VMID */
                if (vmid == 0)
@@ -125,32 +125,17 @@ void kvm_arm_vmid_clear_active(void)
 void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
 {
        unsigned long flags;
-       u64 vmid, old_active_vmid;
+       u64 vmid;

        vmid = atomic64_read(&kvm_vmid->id);
-
-       /*
-        * Please refer comments in check_and_switch_context() in
-        * arch/arm64/mm/context.c.
-        */
-       old_active_vmid = atomic64_read(this_cpu_ptr(&active_vmids));
-       if (old_active_vmid && vmid_gen_match(vmid) &&
-           atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_vmids),
-                                    old_active_vmid, vmid))
+       if (vmid_gen_match(vmid)) {
+               atomic64_set(this_cpu_ptr(&active_vmids), vmid);
                return;
-
-       raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
-
-       /* Check that our VMID belongs to the current generation. */
-       vmid = atomic64_read(&kvm_vmid->id);
-       if (!vmid_gen_match(vmid)) {
-               vmid = new_vmid(kvm_vmid);
-               atomic64_set(&kvm_vmid->id, vmid);
        }

-
+       raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
+       vmid = new_vmid(kvm_vmid);
+       atomic64_set(&kvm_vmid->id, vmid);
        atomic64_set(this_cpu_ptr(&active_vmids), vmid);
        raw_spin_unlock_irqrestore(&cpu_vmid_lock, flags);
 }
--->8<----






From linus.walleij at linaro.org  Wed Aug 11 01:48:51 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 10:48:51 +0200
Subject: [PATCH v4 1/3] arm: dts: mt8135: Move pinfunc to
 include/dt-bindings/pinctrl
In-Reply-To: <d48087c2-ddff-0c58-c7e6-a0ba526a393f@gmail.com>
References: <20210804044033.3047296-1-hsinyi@chromium.org>
 <d48087c2-ddff-0c58-c7e6-a0ba526a393f@gmail.com>
Message-ID: <CACRpkdb39r+AraKaAocB2qX+eLDdRvx3zFyvf0nqvEwFg_QdXg@mail.gmail.com>

On Thu, Aug 5, 2021 at 11:02 AM Matthias Brugger <matthias.bgg at gmail.com> wrote:

> Hi Linus,
>
> On 04/08/2021 06:40, Hsin-Yi Wang wrote:
> > Move mt8135-pinfunc.h into include/dt-bindings/pinctrl so that we can
> > include it in yaml examples.
> >
> > Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
> > ---
> >  arch/arm/boot/dts/mt8135.dtsi                                   | 2 +-
> >  .../boot/dts => include/dt-bindings/pinctrl}/mt8135-pinfunc.h   | 0
> >  2 files changed, 1 insertion(+), 1 deletion(-)
> >  rename {arch/arm/boot/dts => include/dt-bindings/pinctrl}/mt8135-pinfunc.h (100%)
> >
>
> If that's fine with you, I'll take patch 1+2 through my tree. IMHO the best for
> patch 3 would be to go through your tree.
>
> Sounds good?

It can't be done that way. Patch 3 depends on patch 1+2 to get the
include file into the right place for patch 3/3 to compile. (YAML
check.)

I will apply all three and then provide an immutable branch that you
can pull in to your tree as well. This is usually what we do with
cross-tree dependencies.

Yours,
Linus Walleij


From daniel at 0x0f.com  Wed Aug 11 01:49:24 2021
From: daniel at 0x0f.com (Daniel Palmer)
Date: Wed, 11 Aug 2021 17:49:24 +0900
Subject: [PATCH v3] mtd: spinand: add support for Foresee FS35ND0*G parts
Message-ID: <20210811084924.52293-1-daniel@0x0f.com>

Add support for the various Foresee FS35ND0*G parts manufactured by Longsys.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>

Link: https://datasheet.lcsc.com/szlcsc/2008121142_FORESEE-FS35ND01G-S1Y2QWFI000_C719495.pdf
---
 Changes since v2:
 - Originally I only had the 1Gbit version of this chip, now I have the 2Gbit and 4Gbit
   variations so I've added support for those too. There is no datasheet for the bigger
   chips but they are documented in a flashing tool from an SoC vendor so I took the parameters
   from there.
 - Previous versions of this patch only had single io read cache variants. My SPI flash driver
   now supports dual and quad io for reading so I added and tested those modes too.
   My driver/hardware only supports single io for writing so those are still left out.
 - Implemented proper logic for checking the ECC status.
 - Combined with the previous patch for 1-filling the OOB in the page buffer before writing
   I have been using this for a few months now without anything getting broken.
 
 drivers/mtd/nand/spi/Makefile  |   2 +-
 drivers/mtd/nand/spi/core.c    |   1 +
 drivers/mtd/nand/spi/longsys.c | 134 +++++++++++++++++++++++++++++++++
 include/linux/mtd/spinand.h    |   1 +
 4 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/nand/spi/longsys.c

diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
index 9662b9c1d5a9..1d6819022e43 100644
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
+spinand-objs := core.o gigadevice.o longsys.o macronix.o micron.o paragon.o toshiba.o winbond.o
 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 446ba8d43fbc..48f635d5c1ff 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -895,6 +895,7 @@ static const struct nand_ops spinand_ops = {
 
 static const struct spinand_manufacturer *spinand_manufacturers[] = {
 	&gigadevice_spinand_manufacturer,
+	&longsys_spinand_manufacturer,
 	&macronix_spinand_manufacturer,
 	&micron_spinand_manufacturer,
 	&paragon_spinand_manufacturer,
diff --git a/drivers/mtd/nand/spi/longsys.c b/drivers/mtd/nand/spi/longsys.c
new file mode 100644
index 000000000000..ee38f8728262
--- /dev/null
+++ b/drivers/mtd/nand/spi/longsys.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Daniel Palmer <daniel at thingy.jp>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_LONGSYS			0xCD
+#define FS35ND01G_S1Y2_STATUS_ECC_0_3_BITFLIPS	(0 << 4)
+#define FS35ND01G_S1Y2_STATUS_ECC_4_BITFLIPS	(1 << 4)
+#define FS35ND01G_S1Y2_STATUS_ECC_UNCORRECTABLE	(2 << 4)
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+		SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+		SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+static int fs35nd01g_s1y2_ooblayout_ecc(struct mtd_info *mtd, int section,
+					struct mtd_oob_region *region)
+{
+	if (section > 3)
+		return -ERANGE;
+
+	/* ECC is not user accessible */
+	region->offset = 0;
+	region->length = 0;
+
+	return 0;
+}
+
+static int fs35nd01g_s1y2_ooblayout_free(struct mtd_info *mtd, int section,
+				    struct mtd_oob_region *region)
+{
+	if (section > 3)
+		return -ERANGE;
+
+	/*
+	 * No ECC data is stored in the accessible OOB so the full 16 bytes
+	 * of each spare region is available to the user. Apparently also
+	 * covered by the internal ECC.
+	 */
+	if (section) {
+		region->offset = 16 * section;
+		region->length = 16;
+	} else {
+		/* First byte in spare0 area is used for bad block marker */
+		region->offset = 1;
+		region->length = 15;
+	}
+
+	return 0;
+}
+
+static const struct mtd_ooblayout_ops fs35nd01g_s1y2_ooblayout = {
+	.ecc = fs35nd01g_s1y2_ooblayout_ecc,
+	.free = fs35nd01g_s1y2_ooblayout_free,
+};
+
+static int fs35nd01g_s1y2_ecc_get_status(struct spinand_device *spinand,
+					u8 status)
+{
+	switch (status & STATUS_ECC_MASK) {
+	case FS35ND01G_S1Y2_STATUS_ECC_0_3_BITFLIPS:
+		return 3;
+	/*
+	 * The datasheet says *successful* with 4 bits flipped.
+	 * nandbiterrs always complains that the read reported
+	 * successful but the data is incorrect.
+	 */
+	case FS35ND01G_S1Y2_STATUS_ECC_4_BITFLIPS:
+		return 4;
+	case FS35ND01G_S1Y2_STATUS_ECC_UNCORRECTABLE:
+		return -EBADMSG;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static const struct spinand_info longsys_spinand_table[] = {
+	SPINAND_INFO("FS35ND01G-S1Y2",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEA, 0x11),
+		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+		     NAND_ECCREQ(4, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&fs35nd01g_s1y2_ooblayout,
+				     fs35nd01g_s1y2_ecc_get_status)),
+	SPINAND_INFO("FS35ND02G-S3Y2",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB, 0x11),
+		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
+		     NAND_ECCREQ(4, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&fs35nd01g_s1y2_ooblayout,
+				     fs35nd01g_s1y2_ecc_get_status)),
+	SPINAND_INFO("FS35ND04G-S2Y2",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEC, 0x11),
+		     NAND_MEMORG(1, 2048, 64, 64, 4096, 40, 1, 1, 1),
+		     NAND_ECCREQ(4, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&fs35nd01g_s1y2_ooblayout,
+				     fs35nd01g_s1y2_ecc_get_status)),
+};
+
+static const struct spinand_manufacturer_ops longsys_spinand_manuf_ops = {
+};
+
+const struct spinand_manufacturer longsys_spinand_manufacturer = {
+	.id = SPINAND_MFR_LONGSYS,
+	.name = "Longsys",
+	.chips = longsys_spinand_table,
+	.nchips = ARRAY_SIZE(longsys_spinand_table),
+	.ops = &longsys_spinand_manuf_ops,
+};
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6988956b8492..f6c38528bb03 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -261,6 +261,7 @@ struct spinand_manufacturer {
 
 /* SPI NAND manufacturers */
 extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
+extern const struct spinand_manufacturer longsys_spinand_manufacturer;
 extern const struct spinand_manufacturer macronix_spinand_manufacturer;
 extern const struct spinand_manufacturer micron_spinand_manufacturer;
 extern const struct spinand_manufacturer paragon_spinand_manufacturer;
-- 
2.32.0



From geert+renesas at glider.be  Wed Aug 11 01:51:02 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:51:02 +0200
Subject: [PATCH v5 4/9] of: fdt: Add generic support for handling usable
 memory range property
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <3bd69bada93ee59b7d23c38b3527fc1654e19343.1628670468.git.geert+renesas@glider.be>

Add support for handling the "linux,usable-memory-range" property in the
"/chosen" node to the FDT core code.  This can co-exist safely with the
architecture-specific handling, until the latter has been removed.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
About the change to chosen.txt: I have a similar change for
schemas/chosen.yaml in dt-schema.

v5:
  - Handle the actual capping in generic code, too,

v4:
  - New.
---
 Documentation/devicetree/bindings/chosen.txt |  6 ++--
 drivers/of/fdt.c                             | 30 ++++++++++++++++++++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/chosen.txt b/Documentation/devicetree/bindings/chosen.txt
index 5b0b94eb2d04e79d..1cc3aa10dcb10588 100644
--- a/Documentation/devicetree/bindings/chosen.txt
+++ b/Documentation/devicetree/bindings/chosen.txt
@@ -79,9 +79,9 @@ a different secondary CPU release mechanism)
 linux,usable-memory-range
 -------------------------
 
-This property (arm64 only) holds a base address and size, describing a
-limited region in which memory may be considered available for use by
-the kernel. Memory outside of this range is not available for use.
+This property holds a base address and size, describing a limited region in
+which memory may be considered available for use by the kernel. Memory outside
+of this range is not available for use.
 
 This property describes a limitation: memory within this range is only
 valid when also described through another mechanism that the kernel
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 99be3e03af29089f..bc041d8141e86e62 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -956,6 +956,32 @@ static void __init early_init_dt_check_for_elfcorehdr(unsigned long node)
 		 elfcorehdr_addr, elfcorehdr_size);
 }
 
+static phys_addr_t cap_mem_addr;
+static phys_addr_t cap_mem_size;
+
+/**
+ * early_init_dt_check_for_usable_mem_range - Decode usable memory range
+ * location from flat tree
+ * @node: reference to node containing usable memory range location ('chosen')
+ */
+static void __init early_init_dt_check_for_usable_mem_range(unsigned long node)
+{
+	const __be32 *prop;
+	int len;
+
+	pr_debug("Looking for usable-memory-range property... ");
+
+	prop = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);
+	if (!prop || (len < (dt_root_addr_cells + dt_root_size_cells)))
+		return;
+
+	cap_mem_addr = dt_mem_next_cell(dt_root_addr_cells, &prop);
+	cap_mem_size = dt_mem_next_cell(dt_root_size_cells, &prop);
+
+	pr_debug("cap_mem_start=%pa cap_mem_size=%pa\n", &cap_mem_addr,
+		 &cap_mem_size);
+}
+
 #ifdef CONFIG_SERIAL_EARLYCON
 
 int __init early_init_dt_scan_chosen_stdout(void)
@@ -1104,6 +1130,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 
 	early_init_dt_check_for_initrd(node);
 	early_init_dt_check_for_elfcorehdr(node);
+	early_init_dt_check_for_usable_mem_range(node);
 
 	/* Retrieve command line */
 	p = of_get_flat_dt_prop(node, "bootargs", &l);
@@ -1258,6 +1285,9 @@ void __init early_init_dt_scan_nodes(void)
 
 	/* Setup memory, calling early_init_dt_add_memory_arch */
 	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+	/* Handle linux,usable-memory-range property */
+	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
 }
 
 bool __init early_init_dt_scan(void *params)
-- 
2.25.1



From geert+renesas at glider.be  Wed Aug 11 01:51:05 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:51:05 +0200
Subject: [PATCH v5 7/9] arm64: kdump: Remove custom linux,elfcorehdr handling
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <3b8f801f9b92066855e87f3079fafc153ab20f69.1628670468.git.geert+renesas@glider.be>

Remove the architecture-specific code for handling the
"linux,elfcorehdr" property under the "/chosen" node in DT, as the
platform-agnostic handling in the FDT core code already takes care of
this.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v5:
  - Remove all handling, not just parsing,

v4:
  - s/handlng/parsing/ in patch description.
---
 arch/arm64/mm/init.c | 53 --------------------------------------------
 1 file changed, 53 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2917ff2430..bac4f06bb7d900a2 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -124,57 +124,6 @@ static void __init reserve_crashkernel(void)
 }
 #endif /* CONFIG_KEXEC_CORE */
 
-#ifdef CONFIG_CRASH_DUMP
-static int __init early_init_dt_scan_elfcorehdr(unsigned long node,
-		const char *uname, int depth, void *data)
-{
-	const __be32 *reg;
-	int len;
-
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
-
-	reg = of_get_flat_dt_prop(node, "linux,elfcorehdr", &len);
-	if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
-		return 1;
-
-	elfcorehdr_addr = dt_mem_next_cell(dt_root_addr_cells, &reg);
-	elfcorehdr_size = dt_mem_next_cell(dt_root_size_cells, &reg);
-
-	return 1;
-}
-
-/*
- * reserve_elfcorehdr() - reserves memory for elf core header
- *
- * This function reserves the memory occupied by an elf core header
- * described in the device tree. This region contains all the
- * information about primary kernel's core image and is used by a dump
- * capture kernel to access the system memory on primary kernel.
- */
-static void __init reserve_elfcorehdr(void)
-{
-	of_scan_flat_dt(early_init_dt_scan_elfcorehdr, NULL);
-
-	if (!elfcorehdr_size)
-		return;
-
-	if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) {
-		pr_warn("elfcorehdr is overlapped\n");
-		return;
-	}
-
-	memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
-
-	pr_info("Reserving %lldKB of memory at 0x%llx for elfcorehdr\n",
-		elfcorehdr_size >> 10, elfcorehdr_addr);
-}
-#else
-static void __init reserve_elfcorehdr(void)
-{
-}
-#endif /* CONFIG_CRASH_DUMP */
-
 /*
  * Return the maximum physical address for a zone accessible by the given bits
  * limit. If DRAM starts above 32-bit, expand the zone to the maximum
@@ -395,8 +344,6 @@ void __init arm64_memblock_init(void)
 
 	early_init_fdt_scan_reserved_mem();
 
-	reserve_elfcorehdr();
-
 	high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
 }
 
-- 
2.25.1



From geert+renesas at glider.be  Wed Aug 11 01:51:00 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:51:00 +0200
Subject: [PATCH v5 2/9] crash_dump: Make elfcorehdr address/size symbols
 always visible
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <ba965ca613c0cc82c1ec2fe353ee34fb13b36474.1628670468.git.geert+renesas@glider.be>

Make the forward declarations of elfcorehdr_addr and elfcorehdr_size,
and the definitions of ELFCORE_ADDR_MAX and ELFCORE_ADDR_ERR always
available, like is done for phys_initrd_start and phys_initrd_size.
Code referring to these symbols can then just check for
IS_ENABLED(CONFIG_CRASH_DUMP), instead of requiring conditional
compilation using an #ifdef, thus preparing to increase compile
coverage.

Suggested-by: Rob Herring <robh+dt at kernel.org>
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v5:
  - Make ELFCORE_ADDR_{MAX,ERR} visible, too,

v4:
  - New.
---
 include/linux/crash_dump.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index a5192b718dbe4f9a..2618577a4d6da77e 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -10,13 +10,14 @@
 
 #include <linux/pgtable.h> /* for pgprot_t */
 
-#ifdef CONFIG_CRASH_DUMP
+/* For IS_ENABLED(CONFIG_CRASH_DUMP) */
 #define ELFCORE_ADDR_MAX	(-1ULL)
 #define ELFCORE_ADDR_ERR	(-2ULL)
 
 extern unsigned long long elfcorehdr_addr;
 extern unsigned long long elfcorehdr_size;
 
+#ifdef CONFIG_CRASH_DUMP
 extern int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size);
 extern void elfcorehdr_free(unsigned long long addr);
 extern ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos);
-- 
2.25.1



From geert+renesas at glider.be  Wed Aug 11 01:50:58 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:50:58 +0200
Subject: [PATCH v5 0/9] Add generic support for kdump DT properties
Message-ID: <cover.1628670468.git.geert+renesas@glider.be>

	Hi all,

This patch series adds generic support for parsing DT properties related
to crash dump kernels ("linux,elfcorehdr" and "linux,elfcorehdr" under
the "/chosen" node), makes use of it on arm32, and performs a few
cleanups.  It is an evolution of the combination of [1] and [2].

The series consists of 6 parts:
  1. Patch 1 prepares architecture-specific code (needed for MIPS only)
     to avoid duplicating elf core header reservation later.
  2. Patch 2 prepares the visibility of variables used to hold
     information retrieved from the DT properties.
  3. Patches 3-5 add support to the FDT core for handling the
     properties.
     This can co-exist safely with architecture-specific handling, until
     the latter has been removed.
  4. Patch 6 removes the non-standard handling of "linux,elfcorehdr" on
     riscv.
  5. Patches 7-8 convert arm64 to use the generic handling instead of
     its own implementation.
  6. Patch 9 adds support for kdump properties to arm32.
     The corresponding patch for kexec-tools is "[PATCH] arm: kdump: Add
     DT properties to crash dump kernel's DTB"[3], which is still valid.

Changes compared to v4[4]:
  - New patch "[PATCH v5 1/9] MIPS: Avoid future duplicate elf core
    header reservation",
  - Drop "memblock: Add variables for usable memory limitation", as this
    is now handled in FDT core code,
  - Make ELFCORE_ADDR_{MAX,ERR} visible, too,
  - Handle the actual elf core header reservation and memory capping in
    FDT core code,
  - Add Reviewed-by, Acked-by,
  - Remove all architecture-specific handling on arm64,
  - Drop "arm64: kdump: Use IS_ENABLED(CONFIG_CRASH_DUMP) instead of
    #ifdef", as the affected code is gone,
  - Remove the addition of "linux,elfcorehdr" and
    "linux,usable-memory-range" handling to arch/arm/mm/init.c.

Changes compared to older versions:
  - Make elfcorehdr_{addr,size} always visible,
  - Add variables for usable memory limitation,
  - Use IS_ENABLED() instead of #ifdef (incl. initrd and arm64),
  - Clarify what architecture-specific code is still responsible for,
  - Add generic support for parsing linux,usable-memory-range,
  - Remove custom linux,usable-memory-range parsing on arm64,
  - Use generic handling on ARM.
  
This has been tested with kexec/kdump on arm32 and arm64, and
boot-tested on riscv64 and DT-less MIPS.

Thanks!

[1] "[PATCH v3] ARM: Parse kdump DT properties"
    https://lore.kernel.org/r/20210317113130.2554368-1-geert+renesas at glider.be/
[2] "[PATCH 0/3] Add generic-support for linux,elfcorehdr and fix riscv"
    https://lore.kernel.org/r/cover.1623780059.git.geert+renesas at glider.be/
[3] "[PATCH] arm: kdump: Add DT properties to crash dump kernel's DTB"
    https://lore.kernel.org/r/20200902154129.6358-1-geert+renesas at glider.be/
[4] "[PATCH v4 00/10] Add generic support for kdump DT properties"
    https://lore.kernel.org/r/cover.1626266516.git.geert+renesas at glider.be

Geert Uytterhoeven (9):
  MIPS: Avoid future duplicate elf core header reservation
  crash_dump: Make elfcorehdr address/size symbols always visible
  of: fdt: Add generic support for handling elf core headers property
  of: fdt: Add generic support for handling usable memory range property
  of: fdt: Use IS_ENABLED(CONFIG_BLK_DEV_INITRD) instead of #ifdef
  riscv: Remove non-standard linux,elfcorehdr handling
  arm64: kdump: Remove custom linux,elfcorehdr handling
  arm64: kdump: Remove custom linux,usable-memory-range handling
  ARM: uncompress: Parse "linux,usable-memory-range" DT property

 Documentation/devicetree/bindings/chosen.txt  | 12 +--
 .../arm/boot/compressed/fdt_check_mem_start.c | 48 ++++++++--
 arch/arm64/mm/init.c                          | 88 -----------------
 arch/mips/kernel/setup.c                      |  3 +-
 arch/riscv/mm/init.c                          | 20 ----
 drivers/of/fdt.c                              | 94 +++++++++++++++++--
 include/linux/crash_dump.h                    |  3 +-
 7 files changed, 139 insertions(+), 129 deletions(-)

-- 
2.25.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


From geert+renesas at glider.be  Wed Aug 11 01:50:59 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:50:59 +0200
Subject: [PATCH v5 1/9] MIPS: Avoid future duplicate elf core header
 reservation
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>

Prepare for early_init_fdt_scan_reserved_mem() reserving the memory
occupied by an elf core header described in the device tree.
As arch_mem_init() calls early_init_fdt_scan_reserved_mem() before
mips_reserve_vmcore(), the latter needs to check if the memory has
already been reserved before.

Note that mips_reserve_vmcore() cannot just be removed, as not all MIPS
systems use DT.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v5:
  - New.
---
 arch/mips/kernel/setup.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 23a140327a0bac1b..4693add05743d78b 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -429,7 +429,8 @@ static void __init mips_reserve_vmcore(void)
 	pr_info("Reserving %ldKB of memory at %ldKB for kdump\n",
 		(unsigned long)elfcorehdr_size >> 10, (unsigned long)elfcorehdr_addr >> 10);
 
-	memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
+	if (!memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)
+		memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
 #endif
 }
 
-- 
2.25.1



From linus.walleij at linaro.org  Wed Aug 11 01:53:29 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 10:53:29 +0200
Subject: [PATCH v4 1/3] arm: dts: mt8135: Move pinfunc to
 include/dt-bindings/pinctrl
In-Reply-To: <20210804044033.3047296-1-hsinyi@chromium.org>
References: <20210804044033.3047296-1-hsinyi@chromium.org>
Message-ID: <CACRpkdaC-vD2Op-ZzJY8uWQUoS8WH5UPd0FPpWYkExXDg-5biQ@mail.gmail.com>

Hi Hsin-Yi, Matthias,

I have applied all three patches on this immutable branch:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git/log/?h=ib-mt8135

Then I merged this branch into the pinctrl "devel" branch for
v5.15.

Matthias can pull the same branch into his MT SoC tree so
that the hashes will match up in the merge window. No rebasing.

The same patches will then come in to Torvalds in two ways
with the same hashes and match perfectly.

Yours,
Linus Walleij


From krzysztof.kozlowski at canonical.com  Wed Aug 11 01:51:28 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 10:51:28 +0200
Subject: [GIT PULL 2/2] arm64: dts: samsung: DT64 for v5.15
In-Reply-To: <20210811085128.30103-1-krzysztof.kozlowski@canonical.com>
References: <20210811085128.30103-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210811085128.30103-2-krzysztof.kozlowski@canonical.com>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.15

for you to fetch changes up to 01c72cad790cb6cd3ccbe4c1402b6cb6c6bbffd0:

  arm64: dts: exynos: correct GIC CPU interfaces address range on Exynos7 (2021-08-09 12:36:41 +0200)

----------------------------------------------------------------
Samsung DTS ARM64 changes for v5.15

1. Add CPU topology and cache information to Exynos DTSI files.
2. Correct GIC CPU interfaces address range on Exynos7.

----------------------------------------------------------------
Alim Akhtar (2):
      arm64: dts: exynos: Add cpu cache information to Exynos7
      arm64: dts: exynos: Add cpu cache information to Exynos5433

Krzysztof Kozlowski (2):
      arm64: dts: exynos: add CPU topology to Exynos5433
      arm64: dts: exynos: correct GIC CPU interfaces address range on Exynos7

 arch/arm64/boot/dts/exynos/exynos5433.dtsi | 102 +++++++++++++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos7.dtsi    |  37 ++++++++++-
 2 files changed, 138 insertions(+), 1 deletion(-)


From krzysztof.kozlowski at canonical.com  Wed Aug 11 01:51:27 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 11 Aug 2021 10:51:27 +0200
Subject: [GIT PULL 1/2] ARM: dts: samsung: DT for v5.15
Message-ID: <20210811085128.30103-1-krzysztof.kozlowski@canonical.com>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt-5.15

for you to fetch changes up to 6cad6db75231a18f25dc7d610d5a0683160ac545:

  ARM: dts: exynos: add CPU topology to Exynos5422 (2021-08-05 09:24:04 +0200)

----------------------------------------------------------------
Samsung DTS ARM changes for v5.15

Add CPU topology to all Exynos DTSI files.

----------------------------------------------------------------
Krzysztof Kozlowski (7):
      ARM: dts: exynos: add CPU topology to Exynos3250
      ARM: dts: exynos: add CPU topology to Exynos4210
      ARM: dts: exynos: add CPU topology to Exynos4412
      ARM: dts: exynos: add CPU topology to Exynos5250
      ARM: dts: exynos: add CPU topology to Exynos5260
      ARM: dts: exynos: add CPU topology to Exynos5420
      ARM: dts: exynos: add CPU topology to Exynos5422

 arch/arm/boot/dts/exynos3250.dtsi      | 11 ++++++++++
 arch/arm/boot/dts/exynos4210.dtsi      | 11 ++++++++++
 arch/arm/boot/dts/exynos4412.dtsi      | 17 +++++++++++++++
 arch/arm/boot/dts/exynos5250.dtsi      | 11 ++++++++++
 arch/arm/boot/dts/exynos5260.dtsi      | 38 ++++++++++++++++++++++++++++------
 arch/arm/boot/dts/exynos5420-cpus.dtsi | 32 ++++++++++++++++++++++++++++
 arch/arm/boot/dts/exynos5422-cpus.dtsi | 32 ++++++++++++++++++++++++++++
 7 files changed, 146 insertions(+), 6 deletions(-)


From vladimir.murzin at arm.com  Wed Aug 11 01:58:42 2021
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Wed, 11 Aug 2021 09:58:42 +0100
Subject: [PATCH] ARM: NOMMU: Return true/false (not 1/0) from bool
 functions
In-Reply-To: <20210811082041.32309-1-denghuilong@cdjrlc.com>
References: <20210811082041.32309-1-denghuilong@cdjrlc.com>
Message-ID: <1e30b659-a91a-58f6-f9aa-d0f0259eb9e8@arm.com>

On 8/11/21 9:20 AM, Huilong Deng wrote:
> ./arch/arm/mm/nommu.c:59:8-9: WARNING: return of 0/1 in function
> 'security_extensions_enabled' with return type bool
> 
> Signed-off-by: Huilong Deng <denghuilong at cdjrlc.com>
> ---
>  arch/arm/mm/nommu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
> index 2658f52903da..7256ac159acb 100644
> --- a/arch/arm/mm/nommu.c
> +++ b/arch/arm/mm/nommu.c
> @@ -56,7 +56,7 @@ static inline bool security_extensions_enabled(void)
>  	if ((read_cpuid_id() & 0x000f0000) == 0x000f0000)
>  		return cpuid_feature_extract(CPUID_EXT_PFR1, 4) ||
>  			cpuid_feature_extract(CPUID_EXT_PFR1, 20);
> -	return 0;
> +	return false;
>  }
>  
>  unsigned long setup_vectors_base(void)
> 

Reviewed-by: Vladimir Murzin <vladimir.murzin at arm.com>

Please, submit it into RMK's Patch system [1]

[1] https://www.armlinux.org.uk/developer/patches/

Cheers
Vladimir


From maz at kernel.org  Wed Aug 11 02:01:32 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 10:01:32 +0100
Subject: [PATCH v6 17/21] KVM: arm64: Allow userspace to configure a
 guest's counter-timer offset
In-Reply-To: <CAOQ_Qsjn4UK81qBj-uPzoejNc4GAnZXPi=mvcoVi15N0_kayAw@mail.gmail.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-18-oupton@google.com>
 <87a6lpbmbb.wl-maz@kernel.org>
 <CAOQ_Qsjn4UK81qBj-uPzoejNc4GAnZXPi=mvcoVi15N0_kayAw@mail.gmail.com>
Message-ID: <87wnos9wyb.wl-maz@kernel.org>

On Tue, 10 Aug 2021 18:55:12 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Tue, Aug 10, 2021 at 3:56 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Wed, 04 Aug 2021 09:58:15 +0100,
> > Oliver Upton <oupton at google.com> wrote:

[...]

> > > diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
> > > index 73c7139c866f..7252ffa3d675 100644
> > > --- a/include/clocksource/arm_arch_timer.h
> > > +++ b/include/clocksource/arm_arch_timer.h
> > > @@ -21,6 +21,7 @@
> > >  #define CNTHCTL_EVNTEN                       (1 << 2)
> > >  #define CNTHCTL_EVNTDIR                      (1 << 3)
> > >  #define CNTHCTL_EVNTI                        (0xF << 4)
> > > +#define CNTHCTL_ECV                  (1 << 12)
> > >
> > >  enum arch_timer_reg {
> > >       ARCH_TIMER_REG_CTRL,
> >
> > You also want to document that SCR_EL3.ECVEn has to be set to 1 for
> > this to work (see Documentation/arm64/booting.txt). And if it isn't,
> > the firmware better handle the CNTPOFF_EL2 traps correctly...
> 
> I'll grab the popcorn now ;-) Adding docs for this, good idea.
> 
> > What firmware did you use for this? I think we need to update the boot
> > wrapper, but that's something that can be done in parallel.
> 
> I had actually just done a direct boot from ARM-TF -> Linux, nothing
> else in between.

Ah, right. I tend to use the boot-wrapper[1] to build a single binary
that contains the 'boot loader', DT and kernel. Using ATF is probably
more representative of the final thing, but the boot-wrapper is dead
easy to hack on...

Thanks,

	M.

[1] git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git

-- 
Without deviation from the norm, progress is not possible.


From linus.walleij at linaro.org  Wed Aug 11 02:05:38 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 11:05:38 +0200
Subject: [PATCH] dt-bindings: pinctrl: mt8195: Use real world values for
 drive-strength arguments
In-Reply-To: <20210726111941.1447057-1-wenst@chromium.org>
References: <20210726111941.1447057-1-wenst@chromium.org>
Message-ID: <CACRpkdYgTeqWz=S+HfLAhd4M3HYESkhvOEBbS6_185PYUzzxWQ@mail.gmail.com>

On Mon, Jul 26, 2021 at 1:19 PM Chen-Yu Tsai <wenst at chromium.org> wrote:

> The original binding submission for MT8195 pinctrl described the
> possible drive strength values in micro-amps in its description, but
> then proceeded to list register values in its device tree binding
> constraints.
>
> However, the macros used with the Mediatek pinctrl bindings directly
> specify the drive strength in micro-amps, instead of hardware register
> values. The current driver implementation in Linux does convert the
> value from micro-amps to hardware register values. This implementation
> is also used with MT7622 and MT8183, which use real world values in
> their device trees.
>
> Given the above, it was likely an oversight to use the raw register
> values in the binding. Correct the values in the binding. Also drop
> the description since the binding combined with its parent,
> pinctrl/pincfg.yaml, the binding is now self-describing.
>
> Fixes: 7f7663899d94 ("dt-bindings: pinctrl: mt8195: add pinctrl file and binding document")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Patch applied.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Aug 11 02:08:12 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 11:08:12 +0200
Subject: [PATCH] RFC: ARM: dts: Proposed Goramo MultiLink device tree
In-Reply-To: <CAMuHMdWRHSiZH_Xz9tVUaK19TMkUtnTv06etp9Zi-yfhYxSVwQ@mail.gmail.com>
References: <20210728234520.2799053-1-linus.walleij@linaro.org>
 <CAMuHMdWRHSiZH_Xz9tVUaK19TMkUtnTv06etp9Zi-yfhYxSVwQ@mail.gmail.com>
Message-ID: <CACRpkdZ8gtXt1gbJb+sZRgWORsk6wu6j7fsZ1_qy=SyvYhOj=w@mail.gmail.com>

On Thu, Jul 29, 2021 at 2:16 PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:

> Hi Linus,
(...)
> Can't the existing drivers/gpio/gpio-74x164.c be used?
> See also Documentation/devicetree/bindings/gpio/fairchild,74hc595.yaml

Sadly no. The way this device is used for GPIO is very
different. The former used a version of SPI and this has
to hammer GPIO lines directly, and has to use a special
strobe signal to propagate values out to pins.

Yours,
Linus Walleij


From viresh.kumar at linaro.org  Wed Aug 11 02:13:21 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 14:43:21 +0530
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <YROMZFHCor3pbhMr@google.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
 <YROMZFHCor3pbhMr@google.com>
Message-ID: <20210811091321.xtb776q4t6cwyanx@vireshk-i7>

On 11-08-21, 09:37, Quentin Perret wrote:
> On Wednesday 11 Aug 2021 at 10:48:59 (+0530), Viresh Kumar wrote:
> > I had to use the pm-opp version, since almost everyone was using that.
> > 
> > On the other hand, there isn't a lot of OPP specific stuff in
> > dev_pm_opp_of_register_em(). It just uses dev_pm_opp_get_opp_count(),
> > that's all. This ended up in the OPP core, nothing else. Maybe we can
> > now move it back to the EM core and name it differently ?
> 
> Well it also uses dev_pm_opp_find_freq_ceil() and
> dev_pm_opp_get_voltage(), so not sure how easy it will be to move, but
> if it is possible no objection from me.

What uses these routines ? dev_pm_opp_of_register_em() ? I am not able
to see that at least :(

> Right but the EM is a description of the hardware, so it seemed fair
> to assume this wouldn't change across the lifetime of the OS, similar
> to the DT which we can't reload at run-time. Yes it can be a little odd
> if you load/unload your driver module, but note that you generally can't
> load two completely different drivers on a single system. You'll just
> load the same one again and the hardware hasn't changed in the meantime,
> so the previously loaded EM will still be correct.

Yeah, it will be the same driver but a different version of it, which
may have updated the freq table. For me the EM is attached to the
freq-table, and the freq-table is not available anymore after the
driver is gone.

Anyway, I will leave that for you guys to decide :)

> I hear your argument
> about cpufreq driver development, but the locking involved to allow
> 'just' that is pretty involved, and nobody has complained about this
> specific issue so far, so that didn't seem worth it. If we do have good
> reasons to change the EM at runtime, then yes I think we should do it,
> it just didn't seem like that was the case until now.

-- 
viresh


From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:38 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:38 +0800
Subject: [PATCH v2 7/9] phy: phy-mtk-hdmi: convert to
 devm_platform_ioremap_resource
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-7-git-send-email-chunfeng.yun@mediatek.com>

Use devm_platform_ioremap_resource to simplify code

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-hdmi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index 8ad8f717ef43..5fb4217fb8e0 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -100,7 +100,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_hdmi_phy *hdmi_phy;
-	struct resource *mem;
 	struct clk *ref_clk;
 	const char *ref_clk_name;
 	struct clk_init_data clk_init = {
@@ -116,11 +115,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 	if (!hdmi_phy)
 		return -ENOMEM;
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi_phy->regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(hdmi_phy->regs)) {
+	hdmi_phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(hdmi_phy->regs))
 		return PTR_ERR(hdmi_phy->regs);
-	}
 
 	ref_clk = devm_clk_get(dev, "pll_ref");
 	if (IS_ERR(ref_clk)) {
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:40 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:40 +0800
Subject: [PATCH v2 9/9] phy: phy-mtk-mipi-dsi: convert to
 devm_platform_ioremap_resource
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-9-git-send-email-chunfeng.yun@mediatek.com>

Use devm_platform_ioremap_resource to simplify code

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 61c942fbf4a1..28ad9403c441 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -130,7 +130,6 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_mipi_tx *mipi_tx;
-	struct resource *mem;
 	const char *ref_clk_name;
 	struct clk *ref_clk;
 	struct clk_init_data clk_init = {
@@ -148,11 +147,9 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mipi_tx->regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(mipi_tx->regs)) {
+	mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(mipi_tx->regs))
 		return PTR_ERR(mipi_tx->regs);
-	}
 
 	ref_clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(ref_clk)) {
-- 
2.25.1

From maz at kernel.org  Wed Aug 11 02:22:26 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 10:22:26 +0100
Subject: [PATCH][boot-wrapper] aarch64: Enable ECV to allow access to
 CNTPOFF_EL2
Message-ID: <20210811092226.2316583-1-maz@kernel.org>

If the implemnentation supports ID_AA64MMFR0_EL1.ECV==2,
set SCR_EL3.ECVEn to allow EL2 access to CNTPOFF_EL2.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/aarch64/boot.S | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 7f208b5..f0aa3cb 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -54,10 +54,17 @@ ASM_FUNC(_start)
 1:
 	/* Enable FGT if present */
 	mrs	x1, id_aa64mmfr0_el1
-	ubfx	x1, x1, #56, #4
-	cbz	x1, 1f
+	ubfx	x2, x1, #56, #4
+	cbz	x2, 1f
 
 	orr	x0, x0, #(1 << 27)		// FGT enable
+1:
+	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
+	ubfx	x2, x1, #60, #4
+	cmp	x2, #2
+	bne	1f
+
+	orr	x0, x0, #(1 << 28)		// ECV enable
 1:
 	/* Enable MTE if present */
 	mrs	x10, id_aa64pfr1_el1
-- 
2.30.2



From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:32 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:32 +0800
Subject: [PATCH v2 1/9] dt-bindings: phy: mediatek: tphy: support type switch
 by pericfg
Message-ID: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>

Add support type switch by pericfg register between USB3, PCIe,
SATA, SGMII, this is used to replace the way through efuse or
jumper.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add reviewed-by Rob
---
 .../devicetree/bindings/phy/mediatek,tphy.yaml   | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 838852cb8527..9e6c0f43f1c6 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -201,6 +201,22 @@ patternProperties:
           Specify the flag to enable BC1.2 if support it
         type: boolean
 
+      mediatek,syscon-type:
+        $ref: /schemas/types.yaml#/definitions/phandle-array
+        maxItems: 1
+        description:
+          A phandle to syscon used to access the register of type switch,
+          the field should always be 3 cells long.
+        items:
+          items:
+            - description:
+                The first cell represents a phandle to syscon
+            - description:
+                The second cell represents the register offset
+            - description:
+                The third cell represents the index of config segment
+              enum: [0, 1, 2, 3]
+
     required:
       - reg
       - "#phy-cells"
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:36 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:36 +0800
Subject: [PATCH v2 5/9] phy: phy-mtk-tphy: remove error log of ioremap failure
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-5-git-send-email-chunfeng.yun@mediatek.com>

devm_ioremap_resource() will print log if error happens.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 9d4b34298137..cdcef865fe9e 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1306,7 +1306,6 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 
 		instance->port_base = devm_ioremap_resource(subdev, &res);
 		if (IS_ERR(instance->port_base)) {
-			dev_err(subdev, "failed to remap phy regs\n");
 			retval = PTR_ERR(instance->port_base);
 			goto put_child;
 		}
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:33 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:33 +0800
Subject: [PATCH v2 2/9] phy: phy-mtk-tphy: use clock bulk to get clocks
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-2-git-send-email-chunfeng.yun@mediatek.com>

Use clock bulk helpers to get/enable/disable clocks

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 43 +++++++++--------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 33000b38fd1b..3259210f08a1 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -280,6 +280,8 @@
 #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
 
+#define TPHY_CLKS_CNT	2
+
 enum mtk_phy_version {
 	MTK_PHY_V1 = 1,
 	MTK_PHY_V2,
@@ -318,8 +320,7 @@ struct mtk_phy_instance {
 		struct u2phy_banks u2_banks;
 		struct u3phy_banks u3_banks;
 	};
-	struct clk *ref_clk;	/* reference clock of (digital) phy */
-	struct clk *da_ref_clk;	/* reference clock of analog phy */
+	struct clk_bulk_data clks[TPHY_CLKS_CNT];
 	u32 index;
 	u8 type;
 	int eye_src;
@@ -974,18 +975,9 @@ static int mtk_phy_init(struct phy *phy)
 	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
 	int ret;
 
-	ret = clk_prepare_enable(instance->ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable ref_clk\n");
+	ret = clk_bulk_prepare_enable(TPHY_CLKS_CNT, instance->clks);
+	if (ret)
 		return ret;
-	}
-
-	ret = clk_prepare_enable(instance->da_ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable da_ref\n");
-		clk_disable_unprepare(instance->ref_clk);
-		return ret;
-	}
 
 	switch (instance->type) {
 	case PHY_TYPE_USB2:
@@ -1003,8 +995,7 @@ static int mtk_phy_init(struct phy *phy)
 		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
-		clk_disable_unprepare(instance->ref_clk);
-		clk_disable_unprepare(instance->da_ref_clk);
+		clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
 		return -EINVAL;
 	}
 
@@ -1047,8 +1038,7 @@ static int mtk_phy_exit(struct phy *phy)
 	if (instance->type == PHY_TYPE_USB2)
 		u2_phy_instance_exit(tphy, instance);
 
-	clk_disable_unprepare(instance->ref_clk);
-	clk_disable_unprepare(instance->da_ref_clk);
+	clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
 	return 0;
 }
 
@@ -1211,6 +1201,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 	port = 0;
 	for_each_child_of_node(np, child_np) {
 		struct mtk_phy_instance *instance;
+		struct clk_bulk_data *clks;
 		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1247,20 +1238,12 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		phy_set_drvdata(phy, instance);
 		port++;
 
-		instance->ref_clk = devm_clk_get_optional(&phy->dev, "ref");
-		if (IS_ERR(instance->ref_clk)) {
-			dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->ref_clk);
+		clks = instance->clks;
+		clks[0].id = "ref";     /* digital (& analog) clock */
+		clks[1].id = "da_ref";  /* analog clock */
+		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
+		if (retval)
 			goto put_child;
-		}
-
-		instance->da_ref_clk =
-			devm_clk_get_optional(&phy->dev, "da_ref");
-		if (IS_ERR(instance->da_ref_clk)) {
-			dev_err(dev, "failed to get da_ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->da_ref_clk);
-			goto put_child;
-		}
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:37 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:37 +0800
Subject: [PATCH v2 6/9] phy: phy-mtk-ufs: use clock bulk to get clocks
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-6-git-send-email-chunfeng.yun@mediatek.com>

Use clock bulk helpers to get/enable/disable clocks

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-ufs.c | 44 ++++++++----------------------
 1 file changed, 11 insertions(+), 33 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-ufs.c b/drivers/phy/mediatek/phy-mtk-ufs.c
index 769b00b038d8..a6af06941203 100644
--- a/drivers/phy/mediatek/phy-mtk-ufs.c
+++ b/drivers/phy/mediatek/phy-mtk-ufs.c
@@ -31,11 +31,12 @@
 #define FRC_CDR_ISO_EN              BIT(19)
 #define CDR_ISO_EN                  BIT(20)
 
+#define UFSPHY_CLKS_CNT    2
+
 struct ufs_mtk_phy {
 	struct device *dev;
 	void __iomem *mmio;
-	struct clk *mp_clk;
-	struct clk *unipro_clk;
+	struct clk_bulk_data clks[UFSPHY_CLKS_CNT];
 };
 
 static inline u32 mphy_readl(struct ufs_mtk_phy *phy, u32 reg)
@@ -74,20 +75,11 @@ static struct ufs_mtk_phy *get_ufs_mtk_phy(struct phy *generic_phy)
 static int ufs_mtk_phy_clk_init(struct ufs_mtk_phy *phy)
 {
 	struct device *dev = phy->dev;
+	struct clk_bulk_data *clks = phy->clks;
 
-	phy->unipro_clk = devm_clk_get(dev, "unipro");
-	if (IS_ERR(phy->unipro_clk)) {
-		dev_err(dev, "failed to get clock: unipro");
-		return PTR_ERR(phy->unipro_clk);
-	}
-
-	phy->mp_clk = devm_clk_get(dev, "mp");
-	if (IS_ERR(phy->mp_clk)) {
-		dev_err(dev, "failed to get clock: mp");
-		return PTR_ERR(phy->mp_clk);
-	}
-
-	return 0;
+	clks[0].id = "unipro";
+	clks[1].id = "mp";
+	return devm_clk_bulk_get(dev, UFSPHY_CLKS_CNT, clks);
 }
 
 static void ufs_mtk_phy_set_active(struct ufs_mtk_phy *phy)
@@ -150,26 +142,13 @@ static int ufs_mtk_phy_power_on(struct phy *generic_phy)
 	struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy);
 	int ret;
 
-	ret = clk_prepare_enable(phy->unipro_clk);
-	if (ret) {
-		dev_err(phy->dev, "unipro_clk enable failed %d\n", ret);
-		goto out;
-	}
-
-	ret = clk_prepare_enable(phy->mp_clk);
-	if (ret) {
-		dev_err(phy->dev, "mp_clk enable failed %d\n", ret);
-		goto out_unprepare_unipro_clk;
-	}
+	ret = clk_bulk_prepare_enable(UFSPHY_CLKS_CNT, phy->clks);
+	if (ret)
+		return ret;
 
 	ufs_mtk_phy_set_active(phy);
 
 	return 0;
-
-out_unprepare_unipro_clk:
-	clk_disable_unprepare(phy->unipro_clk);
-out:
-	return ret;
 }
 
 static int ufs_mtk_phy_power_off(struct phy *generic_phy)
@@ -178,8 +157,7 @@ static int ufs_mtk_phy_power_off(struct phy *generic_phy)
 
 	ufs_mtk_phy_set_deep_hibern(phy);
 
-	clk_disable_unprepare(phy->unipro_clk);
-	clk_disable_unprepare(phy->mp_clk);
+	clk_bulk_disable_unprepare(UFSPHY_CLKS_CNT, phy->clks);
 
 	return 0;
 }
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:34 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:34 +0800
Subject: [PATCH v2 3/9] phy: phy-mtk-tphy: support type switch by pericfg
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-3-git-send-email-chunfeng.yun@mediatek.com>

Add support type switch between USB3, PCIe, SATA and SGMII by
pericfg register, this is used to take the place of efuse or
jumper.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 84 ++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 3259210f08a1..a6502058a1a5 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -10,11 +10,13 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 
 /* version V1 sub-banks offset base address */
 /* banks shared by multiple phys */
@@ -280,6 +282,14 @@
 #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
 
+/* PHY switch between pcie/usb3/sgmii/sata */
+#define USB_PHY_SWITCH_CTRL	0x0
+#define RG_PHY_SW_TYPE		GENMASK(3, 0)
+#define RG_PHY_SW_PCIE		0x0
+#define RG_PHY_SW_USB3		0x1
+#define RG_PHY_SW_SGMII		0x2
+#define RG_PHY_SW_SATA		0x3
+
 #define TPHY_CLKS_CNT	2
 
 enum mtk_phy_version {
@@ -322,7 +332,10 @@ struct mtk_phy_instance {
 	};
 	struct clk_bulk_data clks[TPHY_CLKS_CNT];
 	u32 index;
-	u8 type;
+	u32 type;
+	struct regmap *type_sw;
+	u32 type_sw_reg;
+	u32 type_sw_index;
 	int eye_src;
 	int eye_vrt;
 	int eye_term;
@@ -969,6 +982,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
 	}
 }
 
+/* type switch for usb3/pcie/sgmii/sata */
+static int phy_type_syscon_get(struct mtk_phy_instance *instance,
+			       struct device_node *dn)
+{
+	struct of_phandle_args args;
+	int ret;
+
+	/* type switch function is optional */
+	if (!of_property_read_bool(dn, "mediatek,syscon-type"))
+		return 0;
+
+	ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
+					       2, 0, &args);
+	if (ret)
+		return ret;
+
+	instance->type_sw_reg = args.args[0];
+	instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
+	instance->type_sw = syscon_node_to_regmap(args.np);
+	of_node_put(args.np);
+	dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
+		 instance->type_sw_reg, instance->type_sw_index);
+
+	return PTR_ERR_OR_ZERO(instance->type_sw);
+}
+
+static int phy_type_set(struct mtk_phy_instance *instance)
+{
+	int type;
+	u32 mask;
+
+	if (!instance->type_sw)
+		return 0;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB3:
+		type = RG_PHY_SW_USB3;
+		break;
+	case PHY_TYPE_PCIE:
+		type = RG_PHY_SW_PCIE;
+		break;
+	case PHY_TYPE_SGMII:
+		type = RG_PHY_SW_SGMII;
+		break;
+	case PHY_TYPE_SATA:
+		type = RG_PHY_SW_SATA;
+		break;
+	case PHY_TYPE_USB2:
+	default:
+		return 0;
+	}
+
+	mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE);
+	regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type);
+
+	return 0;
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -993,6 +1064,9 @@ static int mtk_phy_init(struct phy *phy)
 	case PHY_TYPE_SATA:
 		sata_phy_instance_init(tphy, instance);
 		break;
+	case PHY_TYPE_SGMII:
+		/* nothing to do, only used to set type */
+		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
 		clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
@@ -1081,7 +1155,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	if (!(instance->type == PHY_TYPE_USB2 ||
 	      instance->type == PHY_TYPE_USB3 ||
 	      instance->type == PHY_TYPE_PCIE ||
-	      instance->type == PHY_TYPE_SATA)) {
+	      instance->type == PHY_TYPE_SATA ||
+	      instance->type == PHY_TYPE_SGMII)) {
 		dev_err(dev, "unsupported device type: %d\n", instance->type);
 		return ERR_PTR(-EINVAL);
 	}
@@ -1100,6 +1175,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	}
 
 	phy_parse_property(tphy, instance);
+	phy_type_set(instance);
 
 	return instance->phy;
 }
@@ -1244,6 +1320,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
 		if (retval)
 			goto put_child;
+
+		retval = phy_type_syscon_get(instance, child_np);
+		if (retval)
+			goto put_child;
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.25.1

From linus.walleij at linaro.org  Wed Aug 11 02:23:14 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 11:23:14 +0200
Subject: [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin
 controller
In-Reply-To: <20210802062212.73220-8-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-8-icenowy@sipeed.com>
Message-ID: <CACRpkdaPf76ORB4wHGZdnzszb16SMUa_PEoPqhuBP+Wpfk0Hmg@mail.gmail.com>

On Mon, Aug 2, 2021 at 8:23 AM Icenowy Zheng <icenowy at sipeed.com> wrote:

> Allwinner R329 SoC has two pin controllers similar to ones on previous
> SoCs, one in CPUX power domain and another in CPUS.
>
> This patch adds support for the CPUX domain pin controller.
>
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>

Can you send the pin control changes separately?
Also the bindings.

Then they can be reviewed and merged separately so I
don't have to pick out the stuff I can apply.

Yours,
Linus Walleij


From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:39 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:39 +0800
Subject: [PATCH v2 8/9] phy: phy-mtk-mipi-dsi: remove dummy assignment of
 error number
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-8-git-send-email-chunfeng.yun@mediatek.com>

Return the error number directly without assignment

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 01cf31633019..61c942fbf4a1 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -203,10 +203,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 	phy_set_drvdata(phy, mipi_tx);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-	if (IS_ERR(phy_provider)) {
-		ret = PTR_ERR(phy_provider);
-		return ret;
-	}
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
 
 	mipi_tx->dev = dev;
 
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 02:18:35 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 11 Aug 2021 17:18:35 +0800
Subject: [PATCH v2 4/9] phy: phy-mtk-tphy: print error log using child device
In-Reply-To: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628673520-23537-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628673520-23537-4-git-send-email-chunfeng.yun@mediatek.com>

Print error log using child devices instead of parent device.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index a6502058a1a5..9d4b34298137 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1278,6 +1278,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 	for_each_child_of_node(np, child_np) {
 		struct mtk_phy_instance *instance;
 		struct clk_bulk_data *clks;
+		struct device *subdev;
 		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1295,16 +1296,17 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 			goto put_child;
 		}
 
+		subdev = &phy->dev;
 		retval = of_address_to_resource(child_np, 0, &res);
 		if (retval) {
-			dev_err(dev, "failed to get address resource(id-%d)\n",
+			dev_err(subdev, "failed to get address resource(id-%d)\n",
 				port);
 			goto put_child;
 		}
 
-		instance->port_base = devm_ioremap_resource(&phy->dev, &res);
+		instance->port_base = devm_ioremap_resource(subdev, &res);
 		if (IS_ERR(instance->port_base)) {
-			dev_err(dev, "failed to remap phy regs\n");
+			dev_err(subdev, "failed to remap phy regs\n");
 			retval = PTR_ERR(instance->port_base);
 			goto put_child;
 		}
@@ -1317,7 +1319,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		clks = instance->clks;
 		clks[0].id = "ref";     /* digital (& analog) clock */
 		clks[1].id = "da_ref";  /* analog clock */
-		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
+		retval = devm_clk_bulk_get_optional(subdev, TPHY_CLKS_CNT, clks);
 		if (retval)
 			goto put_child;
 
-- 
2.25.1

From westermann at google.com  Wed Aug 11 02:31:21 2021
From: westermann at google.com (Floris Westermann)
Date: Wed, 11 Aug 2021 09:31:21 +0000
Subject: [PATCH v6 00/17] Introduce SCMI transport based on VirtIO
In-Reply-To: <20210712141833.6628-1-cristian.marussi@arm.com>
References: <20210712141833.6628-1-cristian.marussi@arm.com>
Message-ID: <YROY6YntswWxfaub@google.com>

Hi Cristian,

I am currently working on an interface for VMs to communicate their
performance requirements to the hosts by passing through cpu frequency
adjustments.

Your patch looks very interesting but I have some questions:


On Mon, Jul 12, 2021 at 03:18:16PM +0100, Cristian Marussi wrote:
>
> The series has been tested using an emulated fake SCMI device and also a
> proper SCP-fw stack running through QEMU vhost-users, with the SCMI stack
> compiled, in both cases, as builtin and as a loadable module, running tests
> against mocked SCMI Sensors using HWMON and IIO interfaces to check the
> functionality of notifications and sync/async commands.
>
> Virtio-scmi support has been exercised in the following testing scenario
> on a JUNO board:
>
>  - normal sync/async command transfers
>  - notifications
>  - concurrent delivery of correlated response and delayed responses
>  - out-of-order delivery of delayed responses before related responses
>  - unexpected delayed response delivery for sync commands
>  - late delivery of timed-out responses and delayed responses
>
> Some basic regression testing against mailbox transport has been performed
> for commands and notifications too.
>
> No sensible overhead in total handling time of commands and notifications
> has been observed, even though this series do indeed add a considerable
> amount of code to execute on TX path.
> More test and measurements could be needed in these regards.
>

Can you share any data and benchmarks using you fake SCMI device.
Also, could you provide the emulated device code so that the results can
be reproduced.


Cheers,
Floris


From qperret at google.com  Wed Aug 11 02:34:09 2021
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Aug 2021 10:34:09 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <20210811091321.xtb776q4t6cwyanx@vireshk-i7>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
 <YROMZFHCor3pbhMr@google.com>
 <20210811091321.xtb776q4t6cwyanx@vireshk-i7>
Message-ID: <YROZkbMEMAeXMt1W@google.com>

On Wednesday 11 Aug 2021 at 14:43:21 (+0530), Viresh Kumar wrote:
> On 11-08-21, 09:37, Quentin Perret wrote:
> > On Wednesday 11 Aug 2021 at 10:48:59 (+0530), Viresh Kumar wrote:
> > > I had to use the pm-opp version, since almost everyone was using that.
> > > 
> > > On the other hand, there isn't a lot of OPP specific stuff in
> > > dev_pm_opp_of_register_em(). It just uses dev_pm_opp_get_opp_count(),
> > > that's all. This ended up in the OPP core, nothing else. Maybe we can
> > > now move it back to the EM core and name it differently ?
> > 
> > Well it also uses dev_pm_opp_find_freq_ceil() and
> > dev_pm_opp_get_voltage(), so not sure how easy it will be to move, but
> > if it is possible no objection from me.
> 
> What uses these routines ? dev_pm_opp_of_register_em() ? I am not able
> to see that at least :(

Yep, it's not immediately obvious, but see how it sets the struct
em_data_callback to point at _get_power() where the actual energy
calculation is done. So strictly speaking _get_power() is what uses
these routines, but it goes in hand with dev_pm_opp_of_register_em() so
I guess the same reasoning applies.

> > Right but the EM is a description of the hardware, so it seemed fair
> > to assume this wouldn't change across the lifetime of the OS, similar
> > to the DT which we can't reload at run-time. Yes it can be a little odd
> > if you load/unload your driver module, but note that you generally can't
> > load two completely different drivers on a single system. You'll just
> > load the same one again and the hardware hasn't changed in the meantime,
> > so the previously loaded EM will still be correct.
> 
> Yeah, it will be the same driver but a different version of it, which
> may have updated the freq table. For me the EM is attached to the
> freq-table, and the freq-table is not available anymore after the
> driver is gone.
> 
> Anyway, I will leave that for you guys to decide :)

IIUC Lukasz is working on something that should allow changing the EM at
run-time, so hopefully it'll enable this use-case as well, but we'll see :)


From viresh.kumar at linaro.org  Wed Aug 11 02:36:18 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 15:06:18 +0530
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <YROZkbMEMAeXMt1W@google.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
 <YROMZFHCor3pbhMr@google.com>
 <20210811091321.xtb776q4t6cwyanx@vireshk-i7>
 <YROZkbMEMAeXMt1W@google.com>
Message-ID: <20210811093618.7ncznvblttk6hjlt@vireshk-i7>

On 11-08-21, 10:34, Quentin Perret wrote:
> Yep, it's not immediately obvious, but see how it sets the struct
> em_data_callback to point at _get_power() where the actual energy
> calculation is done. So strictly speaking _get_power() is what uses
> these routines, but it goes in hand with dev_pm_opp_of_register_em() so
> I guess the same reasoning applies.

My bad.

-- 
viresh


From maz at kernel.org  Wed Aug 11 02:36:37 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 10:36:37 +0100
Subject: [PATCH] KVM: arm64: Restrict IPA size to maximum 48 bits on 4K
 and 16K page size
In-Reply-To: <1628657549-27584-1-git-send-email-anshuman.khandual@arm.com>
References: <1628657549-27584-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <87v94c9vbu.wl-maz@kernel.org>

On Wed, 11 Aug 2021 05:52:29 +0100,
Anshuman Khandual <anshuman.khandual at arm.com> wrote:
> 
> Even though ID_AA64MMFR0.PARANGE reports 52 bit PA size support, it cannot
> be enabled as guest IPA size on 4K or 16K page size configurations. Hence
> kvm_ipa_limit must be restricted to 48 bits. This change achieves required
> IPA capping.
> 
> Before the commit c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA
> size based on host configuration"), the problem here would have been just
> latent via PHYS_MASK_SHIFT (which earlier in turn capped kvm_ipa_limit),
> which remains capped at 48 bits on 4K and 16K configs.
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: James Morse <james.morse at arm.com>
> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-kernel at vger.kernel.org
> Fixes: c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA size based on host configuration")
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
> This applies on v5.14-rc5
> 
>  arch/arm64/kvm/reset.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 20588220fe66..e66974c4b9d3 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -337,6 +337,15 @@ int kvm_set_ipa_limit(void)
>  		return -EINVAL;
>  	}
>  
> +	/*
> +	 * IPA size beyond 48 bits could not be supported
> +	 * on either 4K or 16K page size. Hence let's cap
> +	 * it to 48 bits, in case it's reported as larger
> +	 * on the system.
> +	 */
> +	if (!IS_ENABLED(CONFIG_ARM64_64K_PAGES))

As per our earlier discussion, please use (PAGE_SIZE != SZ_64K)
instead. This is in keeping with the rest of the file.

> +		parange = min(parange, (unsigned int)ID_AA64MMFR0_PARANGE_48);
> +

Also, please move it next to the point where we assign parange.

>  	kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange);
>  	kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit,
>  		 ((kvm_ipa_limit < KVM_PHYS_SHIFT) ?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From anshuman.khandual at arm.com  Wed Aug 11 02:37:36 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 15:07:36 +0530
Subject: [PATCH 1/5] KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as
 page size
In-Reply-To: <87zgto9z9i.wl-maz@kernel.org>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
 <25ee7799069492f2501003faec7f9732@kernel.org>
 <0b47c654-7e9b-a7ca-bdf4-f9607062200e@arm.com> <87zgto9z9i.wl-maz@kernel.org>
Message-ID: <4a4d320e-f09c-5198-d3cb-397d837190b1@arm.com>



On 8/11/21 1:41 PM, Marc Zyngier wrote:
> On Wed, 11 Aug 2021 06:34:46 +0100,
> Anshuman Khandual <anshuman.khandual at arm.com> wrote:
>>
>>
>>
>> On 8/10/21 7:03 PM, Marc Zyngier wrote:
>>> On 2021-08-10 08:02, Anshuman Khandual wrote:
>>>> All instances here could just directly test against CONFIG_ARM64_XXK_PAGES
>>>> instead of evaluating via PAGE_SHIFT or PAGE_SIZE. With this change, there
>>>> will be no such usage left.
>>>>
>>>> Cc: Marc Zyngier <maz at kernel.org>
>>>> Cc: James Morse <james.morse at arm.com>
>>>> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
>>>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>>> Cc: Will Deacon <will at kernel.org>
>>>> Cc: linux-arm-kernel at lists.infradead.org
>>>> Cc: kvmarm at lists.cs.columbia.edu
>>>> Cc: linux-kernel at vger.kernel.org
>>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>>>> ---
>>>> ?arch/arm64/kvm/hyp/pgtable.c | 6 +++---
>>>> ?arch/arm64/mm/mmu.c????????? | 2 +-
>>>> ?2 files changed, 4 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
>>>> index 05321f4165e3..a6112b6d6ef6 100644
>>>> --- a/arch/arm64/kvm/hyp/pgtable.c
>>>> +++ b/arch/arm64/kvm/hyp/pgtable.c
>>>> @@ -85,7 +85,7 @@ static bool kvm_level_supports_block_mapping(u32 level)
>>>> ????? * Reject invalid block mappings and don't bother with 4TB mappings for
>>>> ????? * 52-bit PAs.
>>>> ????? */
>>>> -??? return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
>>>> +??? return !(level == 0 || (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) && level == 1));
>>>> ?}
>>>>
>>>> ?static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level)
>>>> @@ -155,7 +155,7 @@ static u64 kvm_pte_to_phys(kvm_pte_t pte)
>>>> ?{
>>>> ???? u64 pa = pte & KVM_PTE_ADDR_MASK;
>>>>
>>>> -??? if (PAGE_SHIFT == 16)
>>>> +??? if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
>>>> ???????? pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
>>>>
>>>> ???? return pa;
>>>> @@ -165,7 +165,7 @@ static kvm_pte_t kvm_phys_to_pte(u64 pa)
>>>> ?{
>>>> ???? kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK;
>>>>
>>>> -??? if (PAGE_SHIFT == 16)
>>>> +??? if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
>>>> ???????? pte |= FIELD_PREP(KVM_PTE_ADDR_51_48, pa >> 48);
>>>>
>>>> ???? return pte;
>>>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
>>>> index 9ff0de1b2b93..8fdfca179815 100644
>>>> --- a/arch/arm64/mm/mmu.c
>>>> +++ b/arch/arm64/mm/mmu.c
>>>> @@ -296,7 +296,7 @@ static void alloc_init_cont_pmd(pud_t *pudp,
>>>> unsigned long addr,
>>>> ?static inline bool use_1G_block(unsigned long addr, unsigned long next,
>>>> ???????????? unsigned long phys)
>>>> ?{
>>>> -??? if (PAGE_SHIFT != 12)
>>>> +??? if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
>>>> ???????? return false;
>>>>
>>>> ???? if (((addr | next | phys) & ~PUD_MASK) != 0)
>>>
>>> I personally find it a lot less readable.
>>>
>>> Also, there is no evaluation whatsoever. All the code guarded
>>> by a PAGE_SIZE/PAGE_SHIFT that doesn't match the configuration
>>> is dropped at compile time.
>>
>> The primary idea here is to unify around IS_ENABLED(CONFIG_ARM64_XXK_PAGES)
>> usage in arm64, rather than having multiple methods to test page size when
>> ever required.
> 
> I'm sorry, but I find the idiom extremely painful to parse. If you are

Okay, it was not explained very well. My bad.

> annoyed with the 'PAGE_SHIFT == 12/14/16', consider replacing it with
> 'PAGE_SIZE == SZ_4/16/64K' instead.

Sure, understood. But the problem here is not with PAGE_SHIFT/PAGE_SIZE
based tests but rather having multiple ways of doing the same thing in
arm64 tree. Please find further explanation below.

> 
> IS_ENABLED(CONFIG_ARM64_XXK_PAGES) also gives the wrong impression
> that *multiple* page sizes can be selected at any given time. That's
> obviously not the case, which actually makes PAGE_SIZE a much better
> choice.

PAGE_SHIFT and PAGE_SIZE are derived from CONFIG_ARM64_XXK_PAGES. Hence
why not just directly use the original user selected config option that
eventually decides PAGE_SHIFT and PAGE_SIZE.

config ARM64_PAGE_SHIFT
        int
        default 16 if ARM64_64K_PAGES
        default 14 if ARM64_16K_PAGES
        default 12

arch/arm64/include/asm/page-def.h:#define PAGE_SHIFT	CONFIG_ARM64_PAGE_SHIFT
arch/arm64/include/asm/page-def.h:#define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)

Also there are already similar IS_ENABLED() instances which do not
create much confusion. The point here being, to have just a single
method that checks compiled page size support, instead of three
different ways of doing the same thing.

- IS_ENABLED(CONFIG_ARM64_XXK_PAGES)
- if (PAGE_SHIFT == XX)
- if (PAGE_SIZE == XX)

$git grep IS_ENABLED arch/arm64/ | grep PAGES

arch/arm64/include/asm/vmalloc.h:	return IS_ENABLED(CONFIG_ARM64_4K_PAGES) &&
arch/arm64/mm/mmu.c:		BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
arch/arm64/mm/mmu.c:		BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));

> 
> As things stand, I don't plan to take such a patch.

Sure, will drop it from the series if the above explanation and
the rationale for the patch still does not convince you.

> 
> Thanks,
> 
> 	M.
> 


From geert at linux-m68k.org  Wed Aug 11 02:38:14 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 11:38:14 +0200
Subject: [PATCH v4 2/3] drivers/soc/renesas: Prefer memcpy over strcpy
In-Reply-To: <20210808125012.4715-3-len.baker@gmx.com>
References: <20210808125012.4715-1-len.baker@gmx.com>
 <20210808125012.4715-3-len.baker@gmx.com>
Message-ID: <CAMuHMdV7ZM9oZG-KU4Ap+H4YehnyGoZn+jsdiJ20GwMFNh+6uQ@mail.gmail.com>

On Sun, Aug 8, 2021 at 4:50 PM Len Baker <len.baker at gmx.com> wrote:
> strcpy() performs no bounds checking on the destination buffer. This
> could result in linear overflows beyond the end of the buffer, leading
> to all kinds of misbehaviors. So, use memcpy() as a safe replacement.
>
> This is a previous step in the path to remove the strcpy() function
> entirely from the kernel.
>
> Signed-off-by: Len Baker <len.baker at gmx.com>

Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
i.e. will queue in renesas-devel for v5.15.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From will at kernel.org  Wed Aug 11 02:44:58 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Aug 2021 10:44:58 +0100
Subject: [PATCH] arm64: head: avoid over-mapping in map_memory
In-Reply-To: <20210810152756.23903-1-mark.rutland@arm.com>
References: <20210810152756.23903-1-mark.rutland@arm.com>
Message-ID: <20210811094457.GA4426@willie-the-truck>

Hi Mark,

On Tue, Aug 10, 2021 at 04:27:56PM +0100, Mark Rutland wrote:
> The `compute_indices` and `populate_entries` macros operate on inclusive
> bounds, and thus the `map_memory` macro which uses them also operates
> on inclusive bounds.
> 
> We pass `_end` and `_idmap_text_end` to `map_memory`, but these are
> exclusive bounds, and if one of these is sufficiently aligned (as a
> result of kernel configuration, physical placement, and KASLR), then:
> 
> * In `compute_indices`, the computed `iend` will be in the page/block *after*
>   the final byte of the intended mapping.
> 
> * In `populate_entries`, an unnecessary entry will be created at the end
>   of each level of table. At the leaf level, this entry will map up to
>   SWAPPER_BLOCK_SIZE bytes of physical addresses that we did not intend
>   to map.
> 
> As we may map up to SWAPPER_BLOCK_SIZE bytes more than intended, we may
> violate the boot protocol and map physical address past the 2MiB-aligned
> end address we are permitted to map. As we map these with Normal memory
> attributes, this may result in further problems depending on what these
> physical addresses correspond to.
> 
> Fix this by subtracting one from the end address in both cases, such
> that we always use inclusive bounds. For clarity, comments are updated
> to more clearly document that the macros expect inclusive bounds.

I think the comments are already clear for populate_entries and map_memory,
so just adding something to compute_indices should suffice. As-is, your
patch leaves populate_entries inconsistent with the others.

That aside, I don't think any amount of comments will help because it's
just plain weird for vend to be inclusive for map_memory, no? Given that
both (all) callers got this wrong, I'd be inclined to say that map_memory
should take an exclusive 'vend' as you'd normally expect and it can adjust
it before using the helper macros (which should perhaps have 'inclusive' in
their names).

Although we currently preserve 'vend' in map_memory, that doesn't appear to
be necessary so we can just move it to the list of clobbers in the comment
nobody reads.

Will


From qperret at google.com  Wed Aug 11 02:48:39 2021
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Aug 2021 10:48:39 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <20210811053406.jqwextgtnxhgsjd2@vireshk-i7>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
 <20210811053406.jqwextgtnxhgsjd2@vireshk-i7>
Message-ID: <YROc95YKA1Y/TfYI@google.com>

On Wednesday 11 Aug 2021 at 11:04:06 (+0530), Viresh Kumar wrote:
> On 11-08-21, 10:48, Viresh Kumar wrote:
> > On 10-08-21, 13:35, Quentin Perret wrote:
> > > This series adds more code than it removes,
> > 
> > Sadly yes :(
> > 
> > > and the unregistration is
> > > not a fix as we don't ever remove the EM tables by design, so not sure
> > > either of these points are valid arguments.
> > 
> > I think that design needs to be looked over again, it looks broken to
> > me everytime I land onto this code. I wonder why we don't unregister
> > stuff.
> 
> Coming back to this series. We have two options, based on what I
> proposed here:
> 
> https://lore.kernel.org/linux-pm/20210811050327.3yxrk4kqxjjwaztx at vireshk-i7/
> 
> 1. Let cpufreq core register with EM on behalf of cpufreq drivers.

If we're going that route, I think we should allow _all_ possible
EM registration methods (via PM_OPP or else) to be done that way.
Otherwise we're creating an inconsitency in how the EM is registered
(e.g. from the ->init() cpufreq callback for some, or from cpufreq core
for others) which is problematic as we risk building features that
assume loading is done at a certain time, which won't work for some
platforms.

> 2. Update drivers to use ->ready() callback to do this stuff.

I think this should work, but perhaps will be a bit tricky for cpufreq
driver developers as they need to have a pretty good understanding of
the stack to know that they should do the registration from here and not
->init() for instance. Suggested alternative: we introduce a ->register_em()
callback to cpufreq_driver, and turn dev_pm_opp_of_register_em() into a
valid handler for this callback. This should 'document' things a bit
better, avoid some of the problems your other series tried to achieve, and
allow us to call the EM registration in exactly the right place from
cpufreq core. On the plus side, we could easily make this work for e.g.
the SCMI driver which would only need to provide its own version of
->register_em().

Thoughts?


From dqfext at gmail.com  Wed Aug 11 02:50:43 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed, 11 Aug 2021 17:50:43 +0800
Subject: [PATCH net-next] net: dsa: mt7530: fix VLAN traffic leaks again
Message-ID: <20210811095043.1700061-1-dqfext@gmail.com>

When a port leaves a VLAN-aware bridge, the current code does not clear
other ports' matrix field bit. If the bridge is later set to VLAN-unaware
mode, traffic in the bridge may leak to that port.

Remove the VLAN filtering check in mt7530_port_bridge_leave.

Fixes: 474a2ddaa192 ("net: dsa: mt7530: fix VLAN traffic leaks")
Fixes: 83163f7dca56 ("net: dsa: mediatek: add VLAN support for MT7530")
Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 drivers/net/dsa/mt7530.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 53e6150e95b6..77e0205e4e59 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1315,11 +1315,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 		/* Remove this port from the port matrix of the other ports
 		 * in the same bridge. If the port is disabled, port matrix
 		 * is kept and not being setup until the port becomes enabled.
-		 * And the other port's port matrix cannot be broken when the
-		 * other port is still a VLAN-aware port.
 		 */
-		if (dsa_is_user_port(ds, i) && i != port &&
-		   !dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) {
+		if (dsa_is_user_port(ds, i) && i != port) {
 			if (dsa_to_port(ds, i)->bridge_dev != bridge)
 				continue;
 			if (priv->ports[i].enable)
-- 
2.25.1



From viresh.kumar at linaro.org  Wed Aug 11 02:53:11 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 15:23:11 +0530
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <YROc95YKA1Y/TfYI@google.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
 <20210811053406.jqwextgtnxhgsjd2@vireshk-i7>
 <YROc95YKA1Y/TfYI@google.com>
Message-ID: <20210811095311.e6wnma2ubkqdtuic@vireshk-i7>

On 11-08-21, 10:48, Quentin Perret wrote:
> I think this should work, but perhaps will be a bit tricky for cpufreq
> driver developers as they need to have a pretty good understanding of
> the stack to know that they should do the registration from here and not
> ->init() for instance. Suggested alternative: we introduce a ->register_em()
> callback to cpufreq_driver, and turn dev_pm_opp_of_register_em() into a
> valid handler for this callback. This should 'document' things a bit
> better, avoid some of the problems your other series tried to achieve, and
> allow us to call the EM registration in exactly the right place from
> cpufreq core. On the plus side, we could easily make this work for e.g.
> the SCMI driver which would only need to provide its own version of
> ->register_em().
> 
> Thoughts?

I had exactly the same thing in mind, but was thinking of two
callbacks, to register and unregister. But yeah, we aren't going to
register for now at least :)

I wasn't sure if that should be done or not, since we also have
ready() callback. So was reluctant to suggest it earlier. But that can
work well as well.

-- 
viresh


From geert+renesas at glider.be  Wed Aug 11 01:51:04 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:51:04 +0200
Subject: [PATCH v5 6/9] riscv: Remove non-standard linux,elfcorehdr handling
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <41c75d6ee3114ae6304f8afe0051895af91200ee.1628670468.git.geert+renesas@glider.be>

RISC-V uses platform-specific code to locate the elf core header in
memory.  However, this does not conform to the standard
"linux,elfcorehdr" DT bindings, as it relies on a reserved memory node
with the "linux,elfcorehdr" compatible value, instead of on a
"linux,elfcorehdr" property under the "/chosen" node.

The non-compliant code can just be removed, as the standard behavior is
already implemented by platform-agnostic handling in the FDT core code.

Fixes: 5640975003d0234d ("RISC-V: Add crash kernel support")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Palmer Dabbelt <palmerdabbelt at google.com>
Acked-by: Palmer Dabbelt <palmerdabbelt at google.com>
---
v5:
  - Add Reviewed-by, Acked-by,

v4:
  - No changes.
---
 arch/riscv/mm/init.c | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 88134cc288d9a60b..3f284b2d327166af 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -860,26 +860,6 @@ static void __init reserve_crashkernel(void)
 }
 #endif /* CONFIG_KEXEC_CORE */
 
-#ifdef CONFIG_CRASH_DUMP
-/*
- * We keep track of the ELF core header of the crashed
- * kernel with a reserved-memory region with compatible
- * string "linux,elfcorehdr". Here we register a callback
- * to populate elfcorehdr_addr/size when this region is
- * present. Note that this region will be marked as
- * reserved once we call early_init_fdt_scan_reserved_mem()
- * later on.
- */
-static int __init elfcore_hdr_setup(struct reserved_mem *rmem)
-{
-	elfcorehdr_addr = rmem->base;
-	elfcorehdr_size = rmem->size;
-	return 0;
-}
-
-RESERVEDMEM_OF_DECLARE(elfcorehdr, "linux,elfcorehdr", elfcore_hdr_setup);
-#endif
-
 void __init paging_init(void)
 {
 	setup_bootmem();
-- 
2.25.1



From geert+renesas at glider.be  Wed Aug 11 01:51:07 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:51:07 +0200
Subject: [PATCH v5 9/9] ARM: uncompress: Parse "linux,
 usable-memory-range" DT property
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <5b71846020ce8b715423734365fa4f94aa65d77a.1628670468.git.geert+renesas@glider.be>

Add support for parsing the "linux,usable-memory-range" DT property.
This property is used to describe the usable memory reserved for the
crash dump kernel, and thus makes the memory reservation explicit.
If present, Linux no longer needs to mask the program counter, and rely
on the "mem=" kernel parameter to obtain the start and size of usable
memory.

For backwards compatibility, the traditional method to derive the start
of memory is still used if "linux,usable-memory-range" is absent.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
The corresponding patch for kexec-tools is "[PATCH] arm: kdump: Add DT
properties to crash dump kernel's DTB", which is still valid:
https://lore.kernel.org/linux-arm-kernel/20200902154129.6358-1-geert+renesas at glider.be/

v5:
  - Remove the addition of "linux,elfcorehdr" and
    "linux,usable-memory-range" handling to arch/arm/mm/init.c,

v4:
  - Remove references to architectures in chosen.txt, to avoid having to
    change this again when more architectures copy kdump support,
  - Remove the architecture-specific code for parsing
    "linux,usable-memory-range" and "linux,elfcorehdr", as the FDT core
    code now takes care of this,
  - Move chosen.txt change to patch changing the FDT core,
  - Use IS_ENABLED(CONFIG_CRASH_DUMP) instead of #ifdef,

v3:
  - Rebase on top of accepted solution for DTB memory information
    handling, which is part of v5.12-rc1,

v2:
  - Rebase on top of reworked DTB memory information handling.
---
 .../arm/boot/compressed/fdt_check_mem_start.c | 48 ++++++++++++++++---
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/compressed/fdt_check_mem_start.c b/arch/arm/boot/compressed/fdt_check_mem_start.c
index 62450d824c3ca180..9291a2661bdfe57f 100644
--- a/arch/arm/boot/compressed/fdt_check_mem_start.c
+++ b/arch/arm/boot/compressed/fdt_check_mem_start.c
@@ -55,16 +55,17 @@ static uint64_t get_val(const fdt32_t *cells, uint32_t ncells)
  * DTB, and, if out-of-range, replace it by the real start address.
  * To preserve backwards compatibility (systems reserving a block of memory
  * at the start of physical memory, kdump, ...), the traditional method is
- * always used if it yields a valid address.
+ * used if it yields a valid address, unless the "linux,usable-memory-range"
+ * property is present.
  *
  * Return value: start address of physical memory to use
  */
 uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
 {
-	uint32_t addr_cells, size_cells, base;
+	uint32_t addr_cells, size_cells, usable_base, base;
 	uint32_t fdt_mem_start = 0xffffffff;
-	const fdt32_t *reg, *endp;
-	uint64_t size, end;
+	const fdt32_t *usable, *reg, *endp;
+	uint64_t size, usable_end, end;
 	const char *type;
 	int offset, len;
 
@@ -80,6 +81,27 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
 	if (addr_cells > 2 || size_cells > 2)
 		return mem_start;
 
+	/*
+	 * Usable memory in case of a crash dump kernel
+	 * This property describes a limitation: memory within this range is
+	 * only valid when also described through another mechanism
+	 */
+	usable = get_prop(fdt, "/chosen", "linux,usable-memory-range",
+			  (addr_cells + size_cells) * sizeof(fdt32_t));
+	if (usable) {
+		size = get_val(usable + addr_cells, size_cells);
+		if (!size)
+			return mem_start;
+
+		if (addr_cells > 1 && fdt32_ld(usable)) {
+			/* Outside 32-bit address space */
+			return mem_start;
+		}
+
+		usable_base = fdt32_ld(usable + addr_cells - 1);
+		usable_end = usable_base + size;
+	}
+
 	/* Walk all memory nodes and regions */
 	for (offset = fdt_next_node(fdt, -1, NULL); offset >= 0;
 	     offset = fdt_next_node(fdt, offset, NULL)) {
@@ -107,7 +129,20 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
 
 			base = fdt32_ld(reg + addr_cells - 1);
 			end = base + size;
-			if (mem_start >= base && mem_start < end) {
+			if (usable) {
+				/*
+				 * Clip to usable range, which takes precedence
+				 * over mem_start
+				 */
+				if (base < usable_base)
+					base = usable_base;
+
+				if (end > usable_end)
+					end = usable_end;
+
+				if (end <= base)
+					continue;
+			} else if (mem_start >= base && mem_start < end) {
 				/* Calculated address is valid, use it */
 				return mem_start;
 			}
@@ -123,7 +158,8 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
 	}
 
 	/*
-	 * The calculated address is not usable.
+	 * The calculated address is not usable, or was overridden by the
+	 * "linux,usable-memory-range" property.
 	 * Use the lowest usable physical memory address from the DTB instead,
 	 * and make sure this is a multiple of 2 MiB for phys/virt patching.
 	 */
-- 
2.25.1



From geert+renesas at glider.be  Wed Aug 11 01:51:03 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:51:03 +0200
Subject: [PATCH v5 5/9] of: fdt: Use IS_ENABLED(CONFIG_BLK_DEV_INITRD) instead
 of #ifdef
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <604c13747f09d800da6a7c12f661e1ec146f1dfd.1628670468.git.geert+renesas@glider.be>

Replace the conditional compilation using "#ifdef CONFIG_BLK_DEV_INITRD"
by a check for "IS_ENABLED(CONFIG_BLK_DEV_INITRD)", to increase compile
coverage and to simplify the code.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v5:
  - No changes,

v4:
  - New.
---
 drivers/of/fdt.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index bc041d8141e86e62..0142b9334559baec 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -880,7 +880,6 @@ const void * __init of_flat_dt_match_machine(const void *default_match,
 	return best_data;
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
 static void __early_init_dt_declare_initrd(unsigned long start,
 					   unsigned long end)
 {
@@ -906,6 +905,9 @@ static void __init early_init_dt_check_for_initrd(unsigned long node)
 	int len;
 	const __be32 *prop;
 
+	if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
+		return;
+
 	pr_debug("Looking for initrd properties... ");
 
 	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
@@ -924,11 +926,6 @@ static void __init early_init_dt_check_for_initrd(unsigned long node)
 
 	pr_debug("initrd_start=0x%llx  initrd_end=0x%llx\n", start, end);
 }
-#else
-static inline void early_init_dt_check_for_initrd(unsigned long node)
-{
-}
-#endif /* CONFIG_BLK_DEV_INITRD */
 
 /**
  * early_init_dt_check_for_elfcorehdr - Decode elfcorehdr location from flat
-- 
2.25.1



From geert+renesas at glider.be  Wed Aug 11 01:51:01 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:51:01 +0200
Subject: [PATCH v5 3/9] of: fdt: Add generic support for handling elf core
 headers property
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <c7e46e50aaf87ef49bdaa61358d25b122f32b7df.1628670468.git.geert+renesas@glider.be>

There are two methods to specify the location of the elf core headers:
using the "elfcorehdr=" kernel parameter, as handled by generic code in
kernel/crash_dump.c, or using the "linux,elfcorehdr" property under the
"/chosen" node in the Device Tree, as handled by architecture-specific
code in arch/arm64/mm/init.c.

Extend support for "linux,elfcorehdr" to all platforms supporting DT by
adding platform-agnostic handling for handling this property to the FDT
core code.  This can co-exist safely with the architecture-specific
handling, until the latter has been removed.

This requires moving the call to of_scan_flat_dt() up, as the code
scanning the "/chosen" node now needs to be aware of the values of
"#address-cells" and "#size-cells".

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Notes:
  1. To avoid reserving the region twice, this depends on "MIPS: Avoid
     duplicate elf core header reservation",
  2. IA64 also has custom code to reserve the region, but is not
     affected, as IA64 does not use DT,
  3. About the change to chosen.txt: I have a similar change for
     schemas/chosen.yaml in dt-schema.

v5:
  - Handle the actual reservation in generic code, too,

v4:
  - Use IS_ENABLED() instead of #ifdef,
  - Clarify what architecture-specific code is still responsible for.
---
 Documentation/devicetree/bindings/chosen.txt |  6 +-
 drivers/of/fdt.c                             | 59 +++++++++++++++++++-
 2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/chosen.txt b/Documentation/devicetree/bindings/chosen.txt
index 45e79172a646c537..5b0b94eb2d04e79d 100644
--- a/Documentation/devicetree/bindings/chosen.txt
+++ b/Documentation/devicetree/bindings/chosen.txt
@@ -106,9 +106,9 @@ respectively, of the root node.
 linux,elfcorehdr
 ----------------
 
-This property (currently used only on arm64) holds the memory range,
-the address and the size, of the elf core header which mainly describes
-the panicked kernel's memory layout as PT_LOAD segments of elf format.
+This property holds the memory range, the address and the size, of the elf
+core header which mainly describes the panicked kernel's memory layout as
+PT_LOAD segments of elf format.
 e.g.
 
 / {
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 9e5074d52879649b..99be3e03af29089f 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -8,6 +8,7 @@
 
 #define pr_fmt(fmt)	"OF: fdt: " fmt
 
+#include <linux/crash_dump.h>
 #include <linux/crc32.h>
 #include <linux/kernel.h>
 #include <linux/initrd.h>
@@ -581,6 +582,30 @@ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname,
 	return 0;
 }
 
+/*
+ * reserve_elfcorehdr() - reserves memory for elf core header
+ *
+ * This function reserves the memory occupied by an elf core header
+ * described in the device tree. This region contains all the
+ * information about primary kernel's core image and is used by a dump
+ * capture kernel to access the system memory on primary kernel.
+ */
+static void __init reserve_elfcorehdr(void)
+{
+	if (!IS_ENABLED(CONFIG_CRASH_DUMP) || !elfcorehdr_size)
+		return;
+
+	if (memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)) {
+		pr_warn("elfcorehdr is overlapped\n");
+		return;
+	}
+
+	memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
+
+	pr_info("Reserving %llu KiB of memory at 0x%llx for elfcorehdr\n",
+		elfcorehdr_size >> 10, elfcorehdr_addr);
+}
+
 /**
  * early_init_fdt_scan_reserved_mem() - create reserved memory regions
  *
@@ -606,6 +631,7 @@ void __init early_init_fdt_scan_reserved_mem(void)
 
 	of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
 	fdt_init_reserved_mem();
+	reserve_elfcorehdr();
 }
 
 /**
@@ -904,6 +930,32 @@ static inline void early_init_dt_check_for_initrd(unsigned long node)
 }
 #endif /* CONFIG_BLK_DEV_INITRD */
 
+/**
+ * early_init_dt_check_for_elfcorehdr - Decode elfcorehdr location from flat
+ * tree
+ * @node: reference to node containing elfcorehdr location ('chosen')
+ */
+static void __init early_init_dt_check_for_elfcorehdr(unsigned long node)
+{
+	const __be32 *prop;
+	int len;
+
+	if (!IS_ENABLED(CONFIG_CRASH_DUMP))
+		return;
+
+	pr_debug("Looking for elfcorehdr property... ");
+
+	prop = of_get_flat_dt_prop(node, "linux,elfcorehdr", &len);
+	if (!prop || (len < (dt_root_addr_cells + dt_root_size_cells)))
+		return;
+
+	elfcorehdr_addr = dt_mem_next_cell(dt_root_addr_cells, &prop);
+	elfcorehdr_size = dt_mem_next_cell(dt_root_size_cells, &prop);
+
+	pr_debug("elfcorehdr_start=0x%llx elfcorehdr_size=0x%llx\n",
+		 elfcorehdr_addr, elfcorehdr_size);
+}
+
 #ifdef CONFIG_SERIAL_EARLYCON
 
 int __init early_init_dt_scan_chosen_stdout(void)
@@ -1051,6 +1103,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 		return 0;
 
 	early_init_dt_check_for_initrd(node);
+	early_init_dt_check_for_elfcorehdr(node);
 
 	/* Retrieve command line */
 	p = of_get_flat_dt_prop(node, "bootargs", &l);
@@ -1195,14 +1248,14 @@ void __init early_init_dt_scan_nodes(void)
 {
 	int rc = 0;
 
+	/* Initialize {size,address}-cells info */
+	of_scan_flat_dt(early_init_dt_scan_root, NULL);
+
 	/* Retrieve various information from the /chosen node */
 	rc = of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
 	if (!rc)
 		pr_warn("No chosen node found, continuing without\n");
 
-	/* Initialize {size,address}-cells info */
-	of_scan_flat_dt(early_init_dt_scan_root, NULL);
-
 	/* Setup memory, calling early_init_dt_add_memory_arch */
 	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
 }
-- 
2.25.1



From geert+renesas at glider.be  Wed Aug 11 01:51:06 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 10:51:06 +0200
Subject: [PATCH v5 8/9] arm64: kdump: Remove custom linux,
 usable-memory-range handling
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <7356c531c49a24b4a55577bf8e46d93f4d8ae460.1628670468.git.geert+renesas@glider.be>

Remove the architecture-specific code for handling the
"linux,usable-memory-range" property under the "/chosen" node in DT, as
the platform-agnostic FDT core code already takes care of this.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v5:
  - Remove all handling, not just parsing,

v4:
  - New.
---
 arch/arm64/mm/init.c | 35 -----------------------------------
 1 file changed, 35 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index bac4f06bb7d900a2..4e90a1d170587376 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -197,45 +197,10 @@ static int __init early_mem(char *p)
 }
 early_param("mem", early_mem);
 
-static int __init early_init_dt_scan_usablemem(unsigned long node,
-		const char *uname, int depth, void *data)
-{
-	struct memblock_region *usablemem = data;
-	const __be32 *reg;
-	int len;
-
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
-
-	reg = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);
-	if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells)))
-		return 1;
-
-	usablemem->base = dt_mem_next_cell(dt_root_addr_cells, &reg);
-	usablemem->size = dt_mem_next_cell(dt_root_size_cells, &reg);
-
-	return 1;
-}
-
-static void __init fdt_enforce_memory_region(void)
-{
-	struct memblock_region reg = {
-		.size = 0,
-	};
-
-	of_scan_flat_dt(early_init_dt_scan_usablemem, &reg);
-
-	if (reg.size)
-		memblock_cap_memory_range(reg.base, reg.size);
-}
-
 void __init arm64_memblock_init(void)
 {
 	const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
 
-	/* Handle linux,usable-memory-range property */
-	fdt_enforce_memory_region();
-
 	/* Remove memory above our supported physical address size */
 	memblock_remove(1ULL << PHYS_MASK_SHIFT, ULLONG_MAX);
 
-- 
2.25.1



From maz at kernel.org  Wed Aug 11 02:56:03 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 10:56:03 +0100
Subject: [PATCH V2] KVM: arm64: perf: Replace '0xf' instances with
 ID_AA64DFR0_PMUVER_IMP_DEF
In-Reply-To: <1628652427-24695-1-git-send-email-anshuman.khandual@arm.com>
References: <1628652427-24695-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <87tujw9ufg.wl-maz@kernel.org>

On Wed, 11 Aug 2021 04:27:06 +0100,
Anshuman Khandual <anshuman.khandual at arm.com> wrote:
> 
> ID_AA64DFR0_PMUVER_IMP_DEF which indicate implementation defined PMU, never
> actually gets used although there are '0xf' instances scattered all around.
> Just do the macro replacement to improve readability.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

For some reason I don't understand, b4 doesn't want to cherry-pick
this patch from the list. I've applied it manually to
kvm-arm64/misc-5.15.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From olteanv at gmail.com  Wed Aug 11 03:01:22 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Wed, 11 Aug 2021 13:01:22 +0300
Subject: [PATCH net-next] net: dsa: mt7530: fix VLAN traffic leaks again
In-Reply-To: <20210811095043.1700061-1-dqfext@gmail.com>
References: <20210811095043.1700061-1-dqfext@gmail.com>
Message-ID: <20210811100122.hntia6od6qdc6dvd@skbuf>

On Wed, Aug 11, 2021 at 05:50:43PM +0800, DENG Qingfang wrote:
> When a port leaves a VLAN-aware bridge, the current code does not clear
> other ports' matrix field bit. If the bridge is later set to VLAN-unaware
> mode, traffic in the bridge may leak to that port.
> 
> Remove the VLAN filtering check in mt7530_port_bridge_leave.
> 
> Fixes: 474a2ddaa192 ("net: dsa: mt7530: fix VLAN traffic leaks")
> Fixes: 83163f7dca56 ("net: dsa: mediatek: add VLAN support for MT7530")
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---

That hunk looked indeed very strange when I went over it with commit
'net: dsa: remove the "dsa_to_port in a loop" antipattern from drivers',
so I'm happy to see it go away.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From will at kernel.org  Wed Aug 11 03:09:06 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Aug 2021 11:09:06 +0100
Subject: [PATCH RFC 2/8] iommu/arm-smmu-v3: Add and use static helper
 function arm_smmu_cmdq_issue_cmd_with_sync()
In-Reply-To: <b9fa05b5-d3ee-5c79-c8b8-b908e533646a@huawei.com>
References: <20210626110130.2416-1-thunder.leizhen@huawei.com>
 <20210626110130.2416-3-thunder.leizhen@huawei.com>
 <20210810182454.GB3296@willie-the-truck>
 <b9fa05b5-d3ee-5c79-c8b8-b908e533646a@huawei.com>
Message-ID: <20210811100905.GB4426@willie-the-truck>

On Wed, Aug 11, 2021 at 10:16:39AM +0800, Leizhen (ThunderTown) wrote:
> 
> 
> On 2021/8/11 2:24, Will Deacon wrote:
> > On Sat, Jun 26, 2021 at 07:01:24PM +0800, Zhen Lei wrote:
> >> The obvious key to the performance optimization of commit 587e6c10a7ce
> >> ("iommu/arm-smmu-v3: Reduce contention during command-queue insertion") is
> >> to allow multiple cores to insert commands in parallel after a brief mutex
> >> contention.
> >>
> >> Obviously, inserting as many commands at a time as possible can reduce the
> >> number of times the mutex contention participates, thereby improving the
> >> overall performance. At least it reduces the number of calls to function
> >> arm_smmu_cmdq_issue_cmdlist().
> >>
> >> Therefore, function arm_smmu_cmdq_issue_cmd_with_sync() is added to insert
> >> the 'cmd+sync' commands at a time.
> >>
> >> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> >> ---
> >>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 33 +++++++++++++--------
> >>  1 file changed, 21 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> >> index 2433d3c29b49ff2..a5361153ca1d6a4 100644
> >> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> >> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> >> @@ -858,11 +858,25 @@ static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
> >>  	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
> >>  }
> >>  
> >> -static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
> >> +static int __maybe_unused arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
> >>  {
> >>  	return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
> >>  }
> >>  
> >> +static int arm_smmu_cmdq_issue_cmd_with_sync(struct arm_smmu_device *smmu,
> >> +					     struct arm_smmu_cmdq_ent *ent)
> >> +{
> >> +	u64 cmd[CMDQ_ENT_DWORDS];
> >> +
> >> +	if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
> >> +		dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
> >> +			 ent->opcode);
> >> +		return -EINVAL;
> >> +	}
> >> +
> >> +	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, true);
> >> +}
> > 
> > This function is almost identical to arm_smmu_cmdq_issue_cmd(). How about
> > moving the guts out into a helper:
> > 
> > 	static int __arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
> > 					     struct arm_smmu_cmdq_ent *ent,
> > 					     bool sync);
> > 
> > and then having arm_smmu_cmdq_issue_cmd_with_sync() and
> > arm_smmu_cmdq_issue_cmd() wrap that?
> 
> OK, I will do it.
> 
> How about remove arm_smmu_cmdq_issue_sync()? It's unused now.

Sure.

Will


From mark.rutland at arm.com  Wed Aug 11 03:09:31 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 11 Aug 2021 11:09:31 +0100
Subject: [PATCH] arm64: head: avoid over-mapping in map_memory
In-Reply-To: <20210811094457.GA4426@willie-the-truck>
References: <20210810152756.23903-1-mark.rutland@arm.com>
 <20210811094457.GA4426@willie-the-truck>
Message-ID: <20210811100905.GA72303@C02TD0UTHF1T.local>

On Wed, Aug 11, 2021 at 10:44:58AM +0100, Will Deacon wrote:
> Hi Mark,
> 
> On Tue, Aug 10, 2021 at 04:27:56PM +0100, Mark Rutland wrote:
> > The `compute_indices` and `populate_entries` macros operate on inclusive
> > bounds, and thus the `map_memory` macro which uses them also operates
> > on inclusive bounds.
> > 
> > We pass `_end` and `_idmap_text_end` to `map_memory`, but these are
> > exclusive bounds, and if one of these is sufficiently aligned (as a
> > result of kernel configuration, physical placement, and KASLR), then:
> > 
> > * In `compute_indices`, the computed `iend` will be in the page/block *after*
> >   the final byte of the intended mapping.
> > 
> > * In `populate_entries`, an unnecessary entry will be created at the end
> >   of each level of table. At the leaf level, this entry will map up to
> >   SWAPPER_BLOCK_SIZE bytes of physical addresses that we did not intend
> >   to map.
> > 
> > As we may map up to SWAPPER_BLOCK_SIZE bytes more than intended, we may
> > violate the boot protocol and map physical address past the 2MiB-aligned
> > end address we are permitted to map. As we map these with Normal memory
> > attributes, this may result in further problems depending on what these
> > physical addresses correspond to.
> > 
> > Fix this by subtracting one from the end address in both cases, such
> > that we always use inclusive bounds. For clarity, comments are updated
> > to more clearly document that the macros expect inclusive bounds.
> 
> I think the comments are already clear for populate_entries and map_memory,
> so just adding something to compute_indices should suffice. As-is, your
> patch leaves populate_entries inconsistent with the others.

Sorry, I'd left that in a separate patch that also renamed index/eindex
to istart/iend for consistency with compute_indices. I should have
folded that change in.

> That aside, I don't think any amount of comments will help because it's
> just plain weird for vend to be inclusive for map_memory, no?

I guess; I have no strong feeling either way.

> Given that both (all) callers got this wrong, I'd be inclined to say
> that map_memory should take an exclusive 'vend' as you'd normally
> expect and it can adjust it before using the helper macros (which
> should perhaps have 'inclusive' in their names).

Sure, I'm also happy with that.

> Although we currently preserve 'vend' in map_memory, that doesn't
> appear to be necessary so we can just move it to the list of clobbers
> in the comment nobody reads.

Works for me.

Thanks,
Mark.


From will at kernel.org  Wed Aug 11 03:12:25 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Aug 2021 11:12:25 +0100
Subject: [PATCH] arm64/mm: Define ID_AA64MMFR0_TGRAN_2_SHIFT
In-Reply-To: <1628569782-30213-1-git-send-email-anshuman.khandual@arm.com>
References: <1628569782-30213-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210811101225.GC4426@willie-the-truck>

On Tue, Aug 10, 2021 at 09:59:42AM +0530, Anshuman Khandual wrote:
> Streamline the Stage-2 TGRAN value extraction from ID_AA64MMFR0 register by
> adding a page size agnostic ID_AA64MMFR0_TGRAN_2_SHIFT. This is similar to
> the existing Stage-1 TGRAN shift i.e ID_AA64MMFR0_TGRAN_SHIFT.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: kvmarm at lists.cs.columbia.edu
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
> This applies on v5.14-rc5.
> 
>  arch/arm64/include/asm/sysreg.h |  3 +++
>  arch/arm64/kvm/reset.c          | 17 ++---------------
>  2 files changed, 5 insertions(+), 15 deletions(-)

Acked-by: Will Deacon <will at kernel.org>

Will


From qperret at google.com  Wed Aug 11 03:12:47 2021
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Aug 2021 11:12:47 +0100
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <20210811095311.e6wnma2ubkqdtuic@vireshk-i7>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
 <20210811053406.jqwextgtnxhgsjd2@vireshk-i7>
 <YROc95YKA1Y/TfYI@google.com>
 <20210811095311.e6wnma2ubkqdtuic@vireshk-i7>
Message-ID: <YROin5WudmmEPard@google.com>

On Wednesday 11 Aug 2021 at 15:23:11 (+0530), Viresh Kumar wrote:
> On 11-08-21, 10:48, Quentin Perret wrote:
> > I think this should work, but perhaps will be a bit tricky for cpufreq
> > driver developers as they need to have a pretty good understanding of
> > the stack to know that they should do the registration from here and not
> > ->init() for instance. Suggested alternative: we introduce a ->register_em()
> > callback to cpufreq_driver, and turn dev_pm_opp_of_register_em() into a
> > valid handler for this callback. This should 'document' things a bit
> > better, avoid some of the problems your other series tried to achieve, and
> > allow us to call the EM registration in exactly the right place from
> > cpufreq core. On the plus side, we could easily make this work for e.g.
> > the SCMI driver which would only need to provide its own version of
> > ->register_em().
> > 
> > Thoughts?
> 
> I had exactly the same thing in mind, but was thinking of two
> callbacks, to register and unregister. But yeah, we aren't going to
> register for now at least :)

Ack, we probably want both once we unregister things.

> I wasn't sure if that should be done or not, since we also have
> ready() callback. So was reluctant to suggest it earlier. But that can
> work well as well.

I think using the ready() callback can work just fine as long as we
document clearly it is important to register the EM from there and not
anywhere else. The dedicated em_register() callback makes that a bit
clearer and should avoid a bit of boilerplate in the driver, but it's
not a big deal really, so I'm happy either way ;)


From m.tretter at pengutronix.de  Wed Aug 11 03:12:47 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 11 Aug 2021 12:12:47 +0200
Subject: [PATCH v3 1/2] arm64: zynqmp: Enable xlnx, zynqmp-dwc3 driver
 for xilinx boards
In-Reply-To: <640a3bc0dc3e32560d3e84c2f78b5ae561396eb0.1628244703.git.michal.simek@xilinx.com>
References: <cover.1628244703.git.michal.simek@xilinx.com>
 <640a3bc0dc3e32560d3e84c2f78b5ae561396eb0.1628244703.git.michal.simek@xilinx.com>
Message-ID: <20210811101247.GC27204@pengutronix.de>

On Fri, 06 Aug 2021 12:12:07 +0200, Michal Simek wrote:
> The commit 84770f028fab ("usb: dwc3: Add driver for Xilinx platforms")
> finally add proper support for Xilinx dwc3 driver. This patch is adding DT
> description for it.
> 
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>

Reviewed-by: Michael Tretter <m.tretter at pengutronix.de>

> ---
> 
> Changes in v3:
> - usb node name fix, remove undocumented properties reported by Michael Tretter
> - Also remove status property from dwc3_0/1 nodes reported by Michael
>   Tretter
> - Move USB3 PHY properties from DWC3 node to USB node - reported by Manish
>   Narani
> 
> Changes in v2:
> - New patch in the series
> 
>  .../dts/xilinx/zynqmp-zc1751-xm015-dc1.dts    |  8 ++-
>  .../dts/xilinx/zynqmp-zc1751-xm016-dc2.dts    |  7 +++
>  .../dts/xilinx/zynqmp-zc1751-xm017-dc3.dts    | 14 +++++
>  .../boot/dts/xilinx/zynqmp-zcu100-revC.dts    | 14 ++++-
>  .../boot/dts/xilinx/zynqmp-zcu102-revA.dts    |  8 ++-
>  .../boot/dts/xilinx/zynqmp-zcu104-revA.dts    |  8 ++-
>  .../boot/dts/xilinx/zynqmp-zcu104-revC.dts    |  8 ++-
>  .../boot/dts/xilinx/zynqmp-zcu106-revA.dts    |  8 ++-
>  .../boot/dts/xilinx/zynqmp-zcu111-revA.dts    |  8 ++-
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 60 +++++++++++++++----
>  10 files changed, 122 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
> index d93fe2efa39d..b05be2552826 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
> @@ -27,6 +27,7 @@ aliases {
>  		rtc0 = &rtc;
>  		serial0 = &uart0;
>  		spi0 = &qspi;
> +		usb0 = &usb0;
>  	};
>  
>  	chosen {
> @@ -404,9 +405,14 @@ &usb0 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb0_default>;
> -	dr_mode = "host";
>  	phy-names = "usb3-phy";
>  	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "host";
> +	snps,usb3_lpm_capable;
>  	maximum-speed = "super-speed";
>  };
>  
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
> index cd61550c52e5..938b76bd0527 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
> @@ -26,6 +26,7 @@ aliases {
>  		serial1 = &uart1;
>  		spi0 = &spi0;
>  		spi1 = &spi1;
> +		usb0 = &usb1;
>  	};
>  
>  	chosen {
> @@ -479,7 +480,13 @@ &usb1 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb1_default>;
> +};
> +
> +&dwc3_1 {
> +	status = "okay";
>  	dr_mode = "host";
> +	snps,usb3_lpm_capable;
> +	maximum-speed = "super-speed";
>  };
>  
>  &uart0 {
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> index ba7f1f21c579..4394ec3b6a23 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> @@ -24,6 +24,8 @@ aliases {
>  		rtc0 = &rtc;
>  		serial0 = &uart0;
>  		serial1 = &uart1;
> +		usb0 = &usb0;
> +		usb1 = &usb1;
>  	};
>  
>  	chosen {
> @@ -147,11 +149,23 @@ &uart1 {
>  
>  &usb0 {
>  	status = "okay";
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
>  	dr_mode = "host";
> +	snps,usb3_lpm_capable;
> +	maximum-speed = "super-speed";
>  };
>  
>  /* ULPI SMSC USB3320 */
>  &usb1 {
>  	status = "okay";
> +};
> +
> +&dwc3_1 {
> +	status = "okay";
>  	dr_mode = "host";
> +	snps,usb3_lpm_capable;
> +	maximum-speed = "super-speed";
>  };
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> index 80415e202814..f6aad4159ccd 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> @@ -30,6 +30,8 @@ aliases {
>  		serial2 = &dcc;
>  		spi0 = &spi0;
>  		spi1 = &spi1;
> +		usb0 = &usb0;
> +		usb1 = &usb1;
>  		mmc0 = &sdhci0;
>  		mmc1 = &sdhci1;
>  	};
> @@ -537,9 +539,13 @@ &usb0 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb0_default>;
> -	dr_mode = "peripheral";
>  	phy-names = "usb3-phy";
>  	phys = <&psgtr 2 PHY_TYPE_USB3 0 0>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "peripheral";
>  	maximum-speed = "super-speed";
>  };
>  
> @@ -548,9 +554,13 @@ &usb1 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb1_default>;
> -	dr_mode = "host";
>  	phy-names = "usb3-phy";
>  	phys = <&psgtr 3 PHY_TYPE_USB3 1 0>;
> +};
> +
> +&dwc3_1 {
> +	status = "okay";
> +	dr_mode = "host";
>  	maximum-speed = "super-speed";
>  };
>  
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> index 3d8d14ef1ede..7b9a88b125d1 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> @@ -31,6 +31,7 @@ aliases {
>  		serial1 = &uart1;
>  		serial2 = &dcc;
>  		spi0 = &qspi;
> +		usb0 = &usb0;
>  	};
>  
>  	chosen {
> @@ -997,9 +998,14 @@ &usb0 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb0_default>;
> -	dr_mode = "host";
>  	phy-names = "usb3-phy";
>  	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "host";
> +	snps,usb3_lpm_capable;
>  	maximum-speed = "super-speed";
>  };
>  
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
> index 86fff3632c7d..bd8f20f3223d 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
> @@ -29,6 +29,7 @@ aliases {
>  		serial1 = &uart1;
>  		serial2 = &dcc;
>  		spi0 = &qspi;
> +		usb0 = &usb0;
>  	};
>  
>  	chosen {
> @@ -481,9 +482,14 @@ &usb0 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb0_default>;
> -	dr_mode = "host";
>  	phy-names = "usb3-phy";
>  	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "host";
> +	snps,usb3_lpm_capable;
>  	maximum-speed = "super-speed";
>  };
>  
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
> index 2a872d439804..96feaad30166 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
> @@ -29,6 +29,7 @@ aliases {
>  		serial1 = &uart1;
>  		serial2 = &dcc;
>  		spi0 = &qspi;
> +		usb0 = &usb0;
>  	};
>  
>  	chosen {
> @@ -493,9 +494,14 @@ &usb0 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb0_default>;
> -	dr_mode = "host";
>  	phy-names = "usb3-phy";
>  	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "host";
> +	snps,usb3_lpm_capable;
>  	maximum-speed = "super-speed";
>  };
>  
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> index 057c04352591..20b7c75bb1d3 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> @@ -31,6 +31,7 @@ aliases {
>  		serial1 = &uart1;
>  		serial2 = &dcc;
>  		spi0 = &qspi;
> +		usb0 = &usb0;
>  	};
>  
>  	chosen {
> @@ -990,9 +991,14 @@ &usb0 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb0_default>;
> -	dr_mode = "host";
>  	phy-names = "usb3-phy";
>  	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "host";
> +	snps,usb3_lpm_capable;
>  	maximum-speed = "super-speed";
>  };
>  
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> index e1fff62a4cd5..e36df6adbeee 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> @@ -30,6 +30,7 @@ aliases {
>  		serial0 = &uart0;
>  		serial1 = &dcc;
>  		spi0 = &qspi;
> +		usb0 = &usb0;
>  	};
>  
>  	chosen {
> @@ -827,9 +828,14 @@ &usb0 {
>  	status = "okay";
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_usb0_default>;
> -	dr_mode = "host";
>  	phy-names = "usb3-phy";
>  	phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "host";
> +	snps,usb3_lpm_capable;
>  	maximum-speed = "super-speed";
>  };
>  
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index b5fde9dddca5..74e66443e4ce 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -2,7 +2,7 @@
>  /*
>   * dts file for Xilinx ZynqMP
>   *
> - * (C) Copyright 2014 - 2019, Xilinx, Inc.
> + * (C) Copyright 2014 - 2021, Xilinx, Inc.
>   *
>   * Michal Simek <michal.simek at xilinx.com>
>   *
> @@ -805,24 +805,58 @@ uart1: serial at ff010000 {
>  			power-domains = <&zynqmp_firmware PD_UART_1>;
>  		};
>  
> -		usb0: usb at fe200000 {
> -			compatible = "snps,dwc3";
> +		usb0: usb at ff9d0000 {
> +			#address-cells = <2>;
> +			#size-cells = <2>;
>  			status = "disabled";
> -			interrupt-parent = <&gic>;
> -			interrupts = <0 65 4>;
> -			reg = <0x0 0xfe200000 0x0 0x40000>;
> -			clock-names = "clk_xin", "clk_ahb";
> +			compatible = "xlnx,zynqmp-dwc3";
> +			reg = <0x0 0xff9d0000 0x0 0x100>;
> +			clock-names = "bus_clk", "ref_clk";
>  			power-domains = <&zynqmp_firmware PD_USB_0>;
> +			resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>,
> +				 <&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>,
> +				 <&zynqmp_reset ZYNQMP_RESET_USB0_APB>;
> +			reset-names = "usb_crst", "usb_hibrst", "usb_apbrst";
> +			ranges;
> +
> +			dwc3_0: usb at fe200000 {
> +				compatible = "snps,dwc3";
> +				reg = <0x0 0xfe200000 0x0 0x40000>;
> +				interrupt-parent = <&gic>;
> +				interrupt-names = "dwc_usb3", "otg";
> +				interrupts = <0 65 4>, <0 69 4>;
> +				#stream-id-cells = <1>;
> +				iommus = <&smmu 0x860>;
> +				snps,quirk-frame-length-adjustment = <0x20>;
> +				/* dma-coherent; */
> +			};
>  		};
>  
> -		usb1: usb at fe300000 {
> -			compatible = "snps,dwc3";
> +		usb1: usb at ff9e0000 {
> +			#address-cells = <2>;
> +			#size-cells = <2>;
>  			status = "disabled";
> -			interrupt-parent = <&gic>;
> -			interrupts = <0 70 4>;
> -			reg = <0x0 0xfe300000 0x0 0x40000>;
> -			clock-names = "clk_xin", "clk_ahb";
> +			compatible = "xlnx,zynqmp-dwc3";
> +			reg = <0x0 0xff9e0000 0x0 0x100>;
> +			clock-names = "bus_clk", "ref_clk";
>  			power-domains = <&zynqmp_firmware PD_USB_1>;
> +			resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>,
> +				 <&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>,
> +				 <&zynqmp_reset ZYNQMP_RESET_USB1_APB>;
> +			reset-names = "usb_crst", "usb_hibrst", "usb_apbrst";
> +			ranges;
> +
> +			dwc3_1: usb at fe300000 {
> +				compatible = "snps,dwc3";
> +				reg = <0x0 0xfe300000 0x0 0x40000>;
> +				interrupt-parent = <&gic>;
> +				interrupt-names = "dwc_usb3", "otg";
> +				interrupts = <0 70 4>, <0 74 4>;
> +				#stream-id-cells = <1>;
> +				iommus = <&smmu 0x861>;
> +				snps,quirk-frame-length-adjustment = <0x20>;
> +				/* dma-coherent; */
> +			};
>  		};
>  
>  		watchdog0: watchdog at fd4d0000 {
> -- 
> 2.32.0
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Michael Tretter             |
Steuerwalder Str. 21                       | https://www.pengutronix.de/ |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From maz at kernel.org  Wed Aug 11 03:13:29 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 11:13:29 +0100
Subject: [PATCH 1/5] KVM: arm64: Drop direct PAGE_[SHIFT|SIZE] usage as
 page size
In-Reply-To: <4a4d320e-f09c-5198-d3cb-397d837190b1@arm.com>
References: <1628578961-29097-1-git-send-email-anshuman.khandual@arm.com>
 <1628578961-29097-2-git-send-email-anshuman.khandual@arm.com>
 <25ee7799069492f2501003faec7f9732@kernel.org>
 <0b47c654-7e9b-a7ca-bdf4-f9607062200e@arm.com>
 <87zgto9z9i.wl-maz@kernel.org>
 <4a4d320e-f09c-5198-d3cb-397d837190b1@arm.com>
Message-ID: <87sfzg9tme.wl-maz@kernel.org>

On Wed, 11 Aug 2021 10:37:36 +0100,
Anshuman Khandual <anshuman.khandual at arm.com> wrote:
> 
> 
> 
> On 8/11/21 1:41 PM, Marc Zyngier wrote:
> > On Wed, 11 Aug 2021 06:34:46 +0100,
> > Anshuman Khandual <anshuman.khandual at arm.com> wrote:
> >>
> >>
> >>
> >> On 8/10/21 7:03 PM, Marc Zyngier wrote:
> >>> On 2021-08-10 08:02, Anshuman Khandual wrote:
> >>>> All instances here could just directly test against CONFIG_ARM64_XXK_PAGES
> >>>> instead of evaluating via PAGE_SHIFT or PAGE_SIZE. With this change, there
> >>>> will be no such usage left.
> >>>>
> >>>> Cc: Marc Zyngier <maz at kernel.org>
> >>>> Cc: James Morse <james.morse at arm.com>
> >>>> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
> >>>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> >>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
> >>>> Cc: Will Deacon <will at kernel.org>
> >>>> Cc: linux-arm-kernel at lists.infradead.org
> >>>> Cc: kvmarm at lists.cs.columbia.edu
> >>>> Cc: linux-kernel at vger.kernel.org
> >>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> >>>> ---
> >>>> ?arch/arm64/kvm/hyp/pgtable.c | 6 +++---
> >>>> ?arch/arm64/mm/mmu.c????????? | 2 +-
> >>>> ?2 files changed, 4 insertions(+), 4 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> >>>> index 05321f4165e3..a6112b6d6ef6 100644
> >>>> --- a/arch/arm64/kvm/hyp/pgtable.c
> >>>> +++ b/arch/arm64/kvm/hyp/pgtable.c
> >>>> @@ -85,7 +85,7 @@ static bool kvm_level_supports_block_mapping(u32 level)
> >>>> ????? * Reject invalid block mappings and don't bother with 4TB mappings for
> >>>> ????? * 52-bit PAs.
> >>>> ????? */
> >>>> -??? return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1));
> >>>> +??? return !(level == 0 || (!IS_ENABLED(CONFIG_ARM64_4K_PAGES) && level == 1));
> >>>> ?}
> >>>>
> >>>> ?static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level)
> >>>> @@ -155,7 +155,7 @@ static u64 kvm_pte_to_phys(kvm_pte_t pte)
> >>>> ?{
> >>>> ???? u64 pa = pte & KVM_PTE_ADDR_MASK;
> >>>>
> >>>> -??? if (PAGE_SHIFT == 16)
> >>>> +??? if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
> >>>> ???????? pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48;
> >>>>
> >>>> ???? return pa;
> >>>> @@ -165,7 +165,7 @@ static kvm_pte_t kvm_phys_to_pte(u64 pa)
> >>>> ?{
> >>>> ???? kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK;
> >>>>
> >>>> -??? if (PAGE_SHIFT == 16)
> >>>> +??? if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
> >>>> ???????? pte |= FIELD_PREP(KVM_PTE_ADDR_51_48, pa >> 48);
> >>>>
> >>>> ???? return pte;
> >>>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> >>>> index 9ff0de1b2b93..8fdfca179815 100644
> >>>> --- a/arch/arm64/mm/mmu.c
> >>>> +++ b/arch/arm64/mm/mmu.c
> >>>> @@ -296,7 +296,7 @@ static void alloc_init_cont_pmd(pud_t *pudp,
> >>>> unsigned long addr,
> >>>> ?static inline bool use_1G_block(unsigned long addr, unsigned long next,
> >>>> ???????????? unsigned long phys)
> >>>> ?{
> >>>> -??? if (PAGE_SHIFT != 12)
> >>>> +??? if (!IS_ENABLED(CONFIG_ARM64_4K_PAGES))
> >>>> ???????? return false;
> >>>>
> >>>> ???? if (((addr | next | phys) & ~PUD_MASK) != 0)
> >>>
> >>> I personally find it a lot less readable.
> >>>
> >>> Also, there is no evaluation whatsoever. All the code guarded
> >>> by a PAGE_SIZE/PAGE_SHIFT that doesn't match the configuration
> >>> is dropped at compile time.
> >>
> >> The primary idea here is to unify around IS_ENABLED(CONFIG_ARM64_XXK_PAGES)
> >> usage in arm64, rather than having multiple methods to test page size when
> >> ever required.
> > 
> > I'm sorry, but I find the idiom extremely painful to parse. If you are
> 
> Okay, it was not explained very well. My bad.
> 
> > annoyed with the 'PAGE_SHIFT == 12/14/16', consider replacing it with
> > 'PAGE_SIZE == SZ_4/16/64K' instead.
> 
> Sure, understood. But the problem here is not with PAGE_SHIFT/PAGE_SIZE
> based tests but rather having multiple ways of doing the same thing in
> arm64 tree. Please find further explanation below.
> 
> > 
> > IS_ENABLED(CONFIG_ARM64_XXK_PAGES) also gives the wrong impression
> > that *multiple* page sizes can be selected at any given time. That's
> > obviously not the case, which actually makes PAGE_SIZE a much better
> > choice.
> 
> PAGE_SHIFT and PAGE_SIZE are derived from CONFIG_ARM64_XXK_PAGES. Hence
> why not just directly use the original user selected config option that
> eventually decides PAGE_SHIFT and PAGE_SIZE.
> 
> config ARM64_PAGE_SHIFT
>         int
>         default 16 if ARM64_64K_PAGES
>         default 14 if ARM64_16K_PAGES
>         default 12
> 
> arch/arm64/include/asm/page-def.h:#define PAGE_SHIFT	CONFIG_ARM64_PAGE_SHIFT
> arch/arm64/include/asm/page-def.h:#define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)

I'm sorry, but that's only a build system artefact. PAGE_SIZE/SHIFT is
what we use in the kernel at large, not IS_ENABLED(BLAH). It is short,
to the point, and it is guaranteed to be what it says on the tin.

If by some miracle you were going to enable multiple *simultaneous*
page sizes support in the arm64 kernel, I'd certainly look at things
differently. Thankfully, this isn't the case.

> Also there are already similar IS_ENABLED() instances which do not
> create much confusion. The point here being, to have just a single
> method that checks compiled page size support, instead of three
> different ways of doing the same thing.
> 
> - IS_ENABLED(CONFIG_ARM64_XXK_PAGES)
> - if (PAGE_SHIFT == XX)
> - if (PAGE_SIZE == XX)
> 
> $git grep IS_ENABLED arch/arm64/ | grep PAGES
> 
> arch/arm64/include/asm/vmalloc.h:	return IS_ENABLED(CONFIG_ARM64_4K_PAGES) &&
> arch/arm64/mm/mmu.c:		BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
> arch/arm64/mm/mmu.c:		BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));

3 instances are hardly a convincing argument.

maz at hot-poop:~/arm-platforms$ git grep -w PAGE_SIZE | grep  '== SZ'
arch/powerpc/include/asm/nohash/32/mmu-8xx.h:	if (PAGE_SIZE == SZ_16K)
fs/btrfs/disk-io.c:	if ((PAGE_SIZE == SZ_4K && sectorsize != PAGE_SIZE) ||
fs/btrfs/disk-io.c:	    (PAGE_SIZE == SZ_64K && (sectorsize != SZ_4K &&
fs/btrfs/disk-io.c:	if (PAGE_SIZE == SZ_64K && sectorsize == SZ_4K) {

Look, I win! :-)

> > 
> > As things stand, I don't plan to take such a patch.
> 
> Sure, will drop it from the series if the above explanation and
> the rationale for the patch still does not convince you.

It really doesn't. This is only a bike-shedding exercise, which
introduce pointless churn.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From viresh.kumar at linaro.org  Wed Aug 11 03:14:49 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 15:44:49 +0530
Subject: [PATCH 0/8] cpufreq: Auto-register with energy model
In-Reply-To: <YROin5WudmmEPard@google.com>
References: <cover.1628579170.git.viresh.kumar@linaro.org>
 <YRJym+Vn4bbwQzzs@google.com>
 <20210811051859.ihjzhvrnuct2knvy@vireshk-i7>
 <20210811053406.jqwextgtnxhgsjd2@vireshk-i7>
 <YROc95YKA1Y/TfYI@google.com>
 <20210811095311.e6wnma2ubkqdtuic@vireshk-i7>
 <YROin5WudmmEPard@google.com>
Message-ID: <20210811101449.c2533ediwboeplqj@vireshk-i7>

On 11-08-21, 11:12, Quentin Perret wrote:
> I think using the ready() callback can work just fine as long as we
> document clearly it is important to register the EM from there and not
> anywhere else. The dedicated em_register() callback makes that a bit
> clearer and should avoid a bit of boilerplate in the driver, but it's
> not a big deal really, so I'm happy either way ;)

Yeah, I think just the same. It is better to have register_em as a
separate call. I was just wondering if it is the right choice :)

Anyway, I think ready() will get removed pretty soon, so register_em()
will work well. I will redo this series and send it.

-- 
viresh


From maz at kernel.org  Wed Aug 11 03:20:43 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 11:20:43 +0100
Subject: [PATCH] arm64/mm: Define ID_AA64MMFR0_TGRAN_2_SHIFT
In-Reply-To: <1628569782-30213-1-git-send-email-anshuman.khandual@arm.com>
References: <1628569782-30213-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <162867723686.2542565.13397724425351239179.b4-ty@kernel.org>

On Tue, 10 Aug 2021 09:59:42 +0530, Anshuman Khandual wrote:
> Streamline the Stage-2 TGRAN value extraction from ID_AA64MMFR0 register by
> adding a page size agnostic ID_AA64MMFR0_TGRAN_2_SHIFT. This is similar to
> the existing Stage-1 TGRAN shift i.e ID_AA64MMFR0_TGRAN_SHIFT.

Applied to kvm-arm64/misc-5.15, thanks!

[1/1] arm64/mm: Define ID_AA64MMFR0_TGRAN_2_SHIFT
      commit: 9efb41493ddfb19c7b3d0a21d68be6279520144f

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From will at kernel.org  Wed Aug 11 03:30:12 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Aug 2021 11:30:12 +0100
Subject: [PATCHv4] iommu/arm-smmu: Optimize ->tlb_flush_walk() for qcom
 implementation
In-Reply-To: <20210811060725.25221-1-saiprakash.ranjan@codeaurora.org>
References: <20210811060725.25221-1-saiprakash.ranjan@codeaurora.org>
Message-ID: <20210811103011.GD4426@willie-the-truck>

On Wed, Aug 11, 2021 at 11:37:25AM +0530, Sai Prakash Ranjan wrote:
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index f7da8953afbe..3904b598e0f9 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -327,9 +327,16 @@ static void arm_smmu_tlb_inv_range_s2(unsigned long iova, size_t size,
>  static void arm_smmu_tlb_inv_walk_s1(unsigned long iova, size_t size,
>  				     size_t granule, void *cookie)
>  {
> -	arm_smmu_tlb_inv_range_s1(iova, size, granule, cookie,
> -				  ARM_SMMU_CB_S1_TLBIVA);
> -	arm_smmu_tlb_sync_context(cookie);
> +	struct arm_smmu_domain *smmu_domain = cookie;
> +	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
> +
> +	if (cfg->flush_walk_prefer_tlbiasid) {
> +		arm_smmu_tlb_inv_context_s1(cookie);

Hmm, this introduces an unconditional wmb() if tlbiasid is preferred. I
think that should be predicated on ARM_SMMU_FEAT_COHERENT_WALK like it is
for the by-VA ops. Worth doing as a separate patch.

> +	} else {
> +		arm_smmu_tlb_inv_range_s1(iova, size, granule, cookie,
> +					  ARM_SMMU_CB_S1_TLBIVA);
> +		arm_smmu_tlb_sync_context(cookie);
> +	}
>  }
>  
>  static void arm_smmu_tlb_add_page_s1(struct iommu_iotlb_gather *gather,
> @@ -765,8 +772,10 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
>  		.iommu_dev	= smmu->dev,
>  	};
>  
> -	if (!iommu_get_dma_strict(domain))
> +	if (!iommu_get_dma_strict(domain)) {
>  		pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
> +		cfg->flush_walk_prefer_tlbiasid = true;

This is going to interact badly with Robin's series to allow dynamic
transition to non-strict mode, as we don't have a mechanism to switch
over to the by-ASID behaviour. Yes, it should _work_, but it's ugly having
different TLBI behaviour just because of the how the domain became
non-strict.

Robin -- I think this originated from your idea at [1]. Any idea how to make
it work with your other series, or shall we drop this part for now and leave
the TLB invalidation behaviour the same for now?

Will

[1] https://lore.kernel.org/r/da62ff1c-9b49-34d3-69a1-1a674e4a30f7 at arm.com


From john.garry at huawei.com  Wed Aug 11 03:31:08 2021
From: john.garry at huawei.com (John Garry)
Date: Wed, 11 Aug 2021 11:31:08 +0100
Subject: [PATCH RFC 2/8] iommu/arm-smmu-v3: Add and use static helper
 function arm_smmu_cmdq_issue_cmd_with_sync()
In-Reply-To: <20210811100905.GB4426@willie-the-truck>
References: <20210626110130.2416-1-thunder.leizhen@huawei.com>
 <20210626110130.2416-3-thunder.leizhen@huawei.com>
 <20210810182454.GB3296@willie-the-truck>
 <b9fa05b5-d3ee-5c79-c8b8-b908e533646a@huawei.com>
 <20210811100905.GB4426@willie-the-truck>
Message-ID: <d551f31d-4edc-db28-fb08-41a130a5d97f@huawei.com>

>>>> Obviously, inserting as many commands at a time as possible can reduce the
>>>> number of times the mutex contention participates, thereby improving the
>>>> overall performance. At least it reduces the number of calls to function
>>>> arm_smmu_cmdq_issue_cmdlist().
>>>>
>>>> Therefore, function arm_smmu_cmdq_issue_cmd_with_sync() is added to insert
>>>> the 'cmd+sync' commands at a time.
>>>>
>>>> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
>>>> ---
>>>>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 33 +++++++++++++--------
>>>>   1 file changed, 21 insertions(+), 12 deletions(-)
>>>>
>>>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> index 2433d3c29b49ff2..a5361153ca1d6a4 100644
>>>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> @@ -858,11 +858,25 @@ static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
>>>>   	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
>>>>   }
>>>>   
>>>> -static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
>>>> +static int __maybe_unused arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
>>>>   {
>>>>   	return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
>>>>   }
>>>>   
>>>> +static int arm_smmu_cmdq_issue_cmd_with_sync(struct arm_smmu_device *smmu,
>>>> +					     struct arm_smmu_cmdq_ent *ent)
>>>> +{
>>>> +	u64 cmd[CMDQ_ENT_DWORDS];
>>>> +
>>>> +	if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
>>>> +		dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
>>>> +			 ent->opcode);
>>>> +		return -EINVAL;

Are any of the errors returned from the "issue command" functions 
actually consumed? I couldn't see it on mainline code from a brief browse.

>>>> +	}
>>>> +
>>>> +	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, true);

Thanks,
John


From will at kernel.org  Wed Aug 11 03:33:45 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Aug 2021 11:33:45 +0100
Subject: [PATCH RFC 2/8] iommu/arm-smmu-v3: Add and use static helper
 function arm_smmu_cmdq_issue_cmd_with_sync()
In-Reply-To: <d551f31d-4edc-db28-fb08-41a130a5d97f@huawei.com>
References: <20210626110130.2416-1-thunder.leizhen@huawei.com>
 <20210626110130.2416-3-thunder.leizhen@huawei.com>
 <20210810182454.GB3296@willie-the-truck>
 <b9fa05b5-d3ee-5c79-c8b8-b908e533646a@huawei.com>
 <20210811100905.GB4426@willie-the-truck>
 <d551f31d-4edc-db28-fb08-41a130a5d97f@huawei.com>
Message-ID: <20210811103344.GA4736@willie-the-truck>

On Wed, Aug 11, 2021 at 11:31:08AM +0100, John Garry wrote:
> > > > > Obviously, inserting as many commands at a time as possible can reduce the
> > > > > number of times the mutex contention participates, thereby improving the
> > > > > overall performance. At least it reduces the number of calls to function
> > > > > arm_smmu_cmdq_issue_cmdlist().
> > > > > 
> > > > > Therefore, function arm_smmu_cmdq_issue_cmd_with_sync() is added to insert
> > > > > the 'cmd+sync' commands at a time.
> > > > > 
> > > > > Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> > > > > ---
> > > > >   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 33 +++++++++++++--------
> > > > >   1 file changed, 21 insertions(+), 12 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > > > index 2433d3c29b49ff2..a5361153ca1d6a4 100644
> > > > > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > > > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > > > @@ -858,11 +858,25 @@ static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
> > > > >   	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
> > > > >   }
> > > > > -static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
> > > > > +static int __maybe_unused arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
> > > > >   {
> > > > >   	return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
> > > > >   }
> > > > > +static int arm_smmu_cmdq_issue_cmd_with_sync(struct arm_smmu_device *smmu,
> > > > > +					     struct arm_smmu_cmdq_ent *ent)
> > > > > +{
> > > > > +	u64 cmd[CMDQ_ENT_DWORDS];
> > > > > +
> > > > > +	if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
> > > > > +		dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
> > > > > +			 ent->opcode);
> > > > > +		return -EINVAL;
> 
> Are any of the errors returned from the "issue command" functions actually
> consumed? I couldn't see it on mainline code from a brief browse.

I don't think so. Can we actually propagate them?

Will


From m.tretter at pengutronix.de  Wed Aug 11 03:36:21 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 11 Aug 2021 12:36:21 +0200
Subject: [PATCH] reset: reset-zynqmp: Fixed the argument data type
In-Reply-To: <925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek@xilinx.com>
References: <925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek@xilinx.com>
Message-ID: <20210811103621.GA23827@pengutronix.de>

On Wed, 23 Jun 2021 13:46:20 +0200, Michal Simek wrote:
> From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> 
> This patch changes the data type of the variable 'val' from
> int to u32.
> 
> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> Addresses-Coverity: argument of type "int *" is incompatible with parameter of type "u32 *"
> ---
> 
>  drivers/reset/reset-zynqmp.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
> index daa425e74c96..59dc0ff9af9e 100644
> --- a/drivers/reset/reset-zynqmp.c
> +++ b/drivers/reset/reset-zynqmp.c
> @@ -53,7 +53,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
>  			       unsigned long id)
>  {
>  	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
> -	int val, err;
> +	int err;
> +	u32 val;

The function returns val as int instead of u32. While this shouldn't be a
problem in this case, maybe there should be an additional check just to be
sure?

Michael

>  
>  	err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val);
>  	if (err)
> -- 
> 2.32.0


From ardb at kernel.org  Wed Aug 11 03:40:28 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 11 Aug 2021 12:40:28 +0200
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <YRKtEDycefrZLB3X@infradead.org>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
 <YRKtEDycefrZLB3X@infradead.org>
Message-ID: <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>

On Tue, 10 Aug 2021 at 18:46, Christoph Hellwig <hch at infradead.org> wrote:
>
> On Mon, Aug 02, 2021 at 04:23:57PM +0100, Lorenzo Pieralisi wrote:
> > Add a __force attribute to the void* cast in acpi_os_map_iomem()
> > to prevent sparse warnings.
>
> Err, no.  These annotation are there for a reason and need to
> be propagated instead.  And independent of that a __force cast
> without a comment explaining it is a complete no-go.

The whole problem we are solving here is that ACPI, being based on
x86, conflates MMIO mappings with memory mappings, and has been using
the same underlying infrastructure for either. On arm64, this is not
sufficient, given that the semantics of uncached memory vs device are
different (the former permits unaligned accesses and clear cacheline
instructions, but the latter doesn't). A recent optimization applied
to memcpy() on arm64 (which now relies more on unaligned accesses for
performance) has uncovered an issue where firmware tables being mapped
non-cacheable by the ACPI core will end up using device mappings,
which causes memcpy() to choke on their contents.

So propagating the annotation makes no sense, as we are creating a
memory mapping using the iomem primitive. I wouldn't object to a
comment being added, but I think the context should have been obvious
to anyone who had bothered to look at the entire series.


From anshuman.khandual at arm.com  Wed Aug 11 03:43:18 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 16:13:18 +0530
Subject: [PATCH] KVM: arm64: Restrict IPA size to maximum 48 bits on 4K
 and 16K page size
In-Reply-To: <87v94c9vbu.wl-maz@kernel.org>
References: <1628657549-27584-1-git-send-email-anshuman.khandual@arm.com>
 <87v94c9vbu.wl-maz@kernel.org>
Message-ID: <acffb56d-8d35-93dc-f96e-61f763bda876@arm.com>



On 8/11/21 3:06 PM, Marc Zyngier wrote:
> On Wed, 11 Aug 2021 05:52:29 +0100,
> Anshuman Khandual <anshuman.khandual at arm.com> wrote:
>>
>> Even though ID_AA64MMFR0.PARANGE reports 52 bit PA size support, it cannot
>> be enabled as guest IPA size on 4K or 16K page size configurations. Hence
>> kvm_ipa_limit must be restricted to 48 bits. This change achieves required
>> IPA capping.
>>
>> Before the commit c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA
>> size based on host configuration"), the problem here would have been just
>> latent via PHYS_MASK_SHIFT (which earlier in turn capped kvm_ipa_limit),
>> which remains capped at 48 bits on 4K and 16K configs.
>>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: James Morse <james.morse at arm.com>
>> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
>> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: kvmarm at lists.cs.columbia.edu
>> Cc: linux-kernel at vger.kernel.org
>> Fixes: c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA size based on host configuration")
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> This applies on v5.14-rc5
>>
>>  arch/arm64/kvm/reset.c | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>>
>> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
>> index 20588220fe66..e66974c4b9d3 100644
>> --- a/arch/arm64/kvm/reset.c
>> +++ b/arch/arm64/kvm/reset.c
>> @@ -337,6 +337,15 @@ int kvm_set_ipa_limit(void)
>>  		return -EINVAL;
>>  	}
>>  
>> +	/*
>> +	 * IPA size beyond 48 bits could not be supported
>> +	 * on either 4K or 16K page size. Hence let's cap
>> +	 * it to 48 bits, in case it's reported as larger
>> +	 * on the system.
>> +	 */
>> +	if (!IS_ENABLED(CONFIG_ARM64_64K_PAGES))
> 
> As per our earlier discussion, please use (PAGE_SIZE != SZ_64K)
> instead. This is in keeping with the rest of the file.

Sure, will change.

> 
>> +		parange = min(parange, (unsigned int)ID_AA64MMFR0_PARANGE_48);
>> +
> 
> Also, please move it next to the point where we assign parange.

Sure, will move.


> 
>>  	kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange);
>>  	kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit,
>>  		 ((kvm_ipa_limit < KVM_PHYS_SHIFT) ?
> 
> Thanks,
> 
> 	M.
> 


From will at kernel.org  Wed Aug 11 03:44:53 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Aug 2021 11:44:53 +0100
Subject: [PATCH v2] arm64: clean vdso & vdso32 files
In-Reply-To: <20210810231755.1743524-1-adelg@google.com>
References: <20210810231755.1743524-1-adelg@google.com>
Message-ID: <162867629652.1666047.1258247021655645030.b4-ty@kernel.org>

On Tue, 10 Aug 2021 23:17:55 +0000, Andrew Delgadillo wrote:
> commit a5b8ca97fbf8 ("arm64: do not descend to vdso directories twice")
> changes the cleaning behavior of arm64's vdso files, in that vdso.lds,
> vdso.so, and vdso.so.dbg are not removed upon a 'make clean/mrproper':
> 
> $ make defconfig ARCH=arm64
> $ make ARCH=arm64
> $ make mrproper ARCH=arm64
> $ git clean -nxdf
> Would remove arch/arm64/kernel/vdso/vdso.lds
> Would remove arch/arm64/kernel/vdso/vdso.so
> Would remove arch/arm64/kernel/vdso/vdso.so.dbg
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: clean vdso & vdso32 files
      https://git.kernel.org/arm64/c/017f5fb9ce79

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Wed Aug 11 03:44:54 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 11 Aug 2021 11:44:54 +0100
Subject: [PATCH V2] arm64/perf: Replace '0xf' instances with
 ID_AA64DFR0_PMUVER_IMP_DEF
In-Reply-To: <1628652427-24695-2-git-send-email-anshuman.khandual@arm.com>
References: <1628652427-24695-1-git-send-email-anshuman.khandual@arm.com>
 <1628652427-24695-2-git-send-email-anshuman.khandual@arm.com>
Message-ID: <162867613362.1661207.9902910168999427938.b4-ty@kernel.org>

On Wed, 11 Aug 2021 08:57:07 +0530, Anshuman Khandual wrote:
> ID_AA64DFR0_PMUVER_IMP_DEF which indicate implementation defined PMU, never
> actually gets used although there are '0xf' instances scattered all around.
> Just do the macro replacement to improve readability.

Applied to will (for-next/perf), thanks!

[1/1] arm64/perf: Replace '0xf' instances with ID_AA64DFR0_PMUVER_IMP_DEF
      https://git.kernel.org/will/c/fd264b310579

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From tangbin at cmss.chinamobile.com  Wed Aug 11 03:51:36 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Wed, 11 Aug 2021 18:51:36 +0800
Subject: [PATCH] serial: stm32: fix the conditional expression writing
Message-ID: <20210811105136.25392-1-tangbin@cmss.chinamobile.com>

In the function stm32_usart_init_port, intent of the code maybe when
irq returns a value of zero, the return should be '-ENODEV'. But the
conditional expression '? :' maybe clerical error, it should be
'?:' to make '-ENODEV' work.
But in fact, as the example in platform.c is
  * int irq = platform_get_irq(pdev, 0);
  * if (irq < 0)
  * return irq;
So the return value of zero is unnecessary to check, at last remove
the unnecessary '?: -ENODEV'.

Co-developed-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 drivers/tty/serial/stm32-usart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index ef793b3b4..090822cd1 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -1034,8 +1034,8 @@ static int stm32_usart_init_port(struct stm32_port *stm32port,
 	int ret, irq;
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq <= 0)
-		return irq ? : -ENODEV;
+	if (irq < 0)
+		return irq;
 
 	port->iotype	= UPIO_MEM;
 	port->flags	= UPF_BOOT_AUTOCONF;
-- 
2.20.1.windows.1





From sven at svenpeter.dev  Wed Aug 11 03:58:10 2021
From: sven at svenpeter.dev (Sven Peter)
Date: Wed, 11 Aug 2021 12:58:10 +0200
Subject: [PATCH] iommu: APPLE_DART should depend on ARCH_APPLE
In-Reply-To: <44fcf525273b32c9afcd7e99acbd346d47f0e047.1628603162.git.geert+renesas@glider.be>
References: <44fcf525273b32c9afcd7e99acbd346d47f0e047.1628603162.git.geert+renesas@glider.be>
Message-ID: <ae4e4b9f-add0-4ab2-9c82-04124b1862b7@www.fastmail.com>

Good catch, thanks!

Acked-by: Sven Peter <sven at svenpeter.dev>

Sven

On Tue, Aug 10, 2021, at 15:47, Geert Uytterhoeven wrote:
> The Apple DART (Device Address Resolution Table) IOMMU is only present
> on Apple ARM SoCs like the M1.  Hence add a dependency on ARCH_APPLE, to
> prevent asking the user about this driver when configuring a kernel
> without support for the Apple Silicon SoC family.
> 
> Fixes: 05ce9d20d699b093 ("iommu/dart: Add DART iommu driver")
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
>  drivers/iommu/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index dfe81da483e9e073..e908b8222e4ed679 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -292,7 +292,7 @@ config SPAPR_TCE_IOMMU
>  
>  config APPLE_DART
>  	tristate "Apple DART IOMMU Support"
> -	depends on ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64)
> +	depends on ARCH_APPLE || (COMPILE_TEST && !GENERIC_ATOMIC64)
>  	select IOMMU_API
>  	select IOMMU_IO_PGTABLE_LPAE
>  	default ARCH_APPLE
> -- 
> 2.25.1
> 
> 


From anshuman.khandual at arm.com  Wed Aug 11 04:11:15 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 11 Aug 2021 16:41:15 +0530
Subject: [PATCH V2] KVM: arm64: Restrict IPA size to maximum 48 bits on 4K and
 16K page size
Message-ID: <1628680275-16578-1-git-send-email-anshuman.khandual@arm.com>

Even though ID_AA64MMFR0.PARANGE reports 52 bit PA size support, it cannot
be enabled as guest IPA size on 4K or 16K page size configurations. Hence
kvm_ipa_limit must be restricted to 48 bits. This change achieves required
IPA capping.

Before the commit c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA
size based on host configuration"), the problem here would have been just
latent via PHYS_MASK_SHIFT (which earlier in turn capped kvm_ipa_limit),
which remains capped at 48 bits on 4K and 16K configs.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Fixes: c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA size based on host configuration")
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.14-rc5

Changes in V2:

- Replaced IS_ENABLED() based check with PAGE_SIZE based one per Marc
- Moved the conditional code block near parange assignment per Marc

Changes in V1:

https://lore.kernel.org/lkml/1628657549-27584-1-git-send-email-anshuman.khandual at arm.com/

 arch/arm64/kvm/reset.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index cba7872..78d4bd8 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -317,6 +317,14 @@ int kvm_set_ipa_limit(void)
 	mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 	parange = cpuid_feature_extract_unsigned_field(mmfr0,
 				ID_AA64MMFR0_PARANGE_SHIFT);
+	/*
+	 * IPA size beyond 48 bits could not be supported
+	 * on either 4K or 16K page size. Hence let's cap
+	 * it to 48 bits, in case it's reported as larger
+	 * on the system.
+	 */
+	if (PAGE_SIZE != SZ_64K)
+		parange = min(parange, (unsigned int)ID_AA64MMFR0_PARANGE_48);
 
 	/*
 	 * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at
-- 
2.7.4



From eizan at chromium.org  Wed Aug 11 04:15:25 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 11 Aug 2021 21:15:25 +1000
Subject: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components
In-Reply-To: <014b8075-8588-d741-e6f2-edc0567e8c8f@collabora.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
 <0aff1abb-734f-c714-6ecc-c906862255c3@collabora.com>
 <CAOak1e8n6JpNKODfM57OTtbCNz8UBbj+wefwipVWP_Ep6SHmHA@mail.gmail.com>
 <014b8075-8588-d741-e6f2-edc0567e8c8f@collabora.com>
Message-ID: <CAOak1e-+v1e+x1SE_Pr2T8eH+gyLikBL6J243ry5tkWAVVx7tA@mail.gmail.com>

Hi Dafna,

On Mon, Aug 9, 2021 at 5:53 PM Dafna Hirschfeld
<dafna.hirschfeld at collabora.com> wrote:
> You can send it also as a separate patch. I don't care too much.

Great. I've sent a separate patch to make mtk_mdp_comp_init static in
https://patchwork.kernel.org/project/linux-mediatek/list/?series=529639

I will continue with further work to use the clk_blk_* API.

Thanks,

Eizan


From john.garry at huawei.com  Wed Aug 11 04:15:14 2021
From: john.garry at huawei.com (John Garry)
Date: Wed, 11 Aug 2021 12:15:14 +0100
Subject: [PATCH RFC 2/8] iommu/arm-smmu-v3: Add and use static helper
 function arm_smmu_cmdq_issue_cmd_with_sync()
In-Reply-To: <20210811103344.GA4736@willie-the-truck>
References: <20210626110130.2416-1-thunder.leizhen@huawei.com>
 <20210626110130.2416-3-thunder.leizhen@huawei.com>
 <20210810182454.GB3296@willie-the-truck>
 <b9fa05b5-d3ee-5c79-c8b8-b908e533646a@huawei.com>
 <20210811100905.GB4426@willie-the-truck>
 <d551f31d-4edc-db28-fb08-41a130a5d97f@huawei.com>
 <20210811103344.GA4736@willie-the-truck>
Message-ID: <1dcf5fe0-6ae0-2df6-9d2a-bda6a4f885ac@huawei.com>

>>>>>>
>>>>>> Therefore, function arm_smmu_cmdq_issue_cmd_with_sync() is added to insert
>>>>>> the 'cmd+sync' commands at a time.
>>>>>>
>>>>>> Signed-off-by: Zhen Lei<thunder.leizhen at huawei.com>
>>>>>> ---
>>>>>>    drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 33 +++++++++++++--------
>>>>>>    1 file changed, 21 insertions(+), 12 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>>>> index 2433d3c29b49ff2..a5361153ca1d6a4 100644
>>>>>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>>>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>>>> @@ -858,11 +858,25 @@ static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
>>>>>>    	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
>>>>>>    }
>>>>>> -static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
>>>>>> +static int __maybe_unused arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
>>>>>>    {
>>>>>>    	return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
>>>>>>    }
>>>>>> +static int arm_smmu_cmdq_issue_cmd_with_sync(struct arm_smmu_device *smmu,
>>>>>> +					     struct arm_smmu_cmdq_ent *ent)
>>>>>> +{
>>>>>> +	u64 cmd[CMDQ_ENT_DWORDS];
>>>>>> +
>>>>>> +	if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
>>>>>> +		dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
>>>>>> +			 ent->opcode);
>>>>>> +		return -EINVAL;
>> Are any of the errors returned from the "issue command" functions actually
>> consumed? I couldn't see it on mainline code from a brief browse.
> I don't think so.

I don't think so either.

> Can we actually propagate them?

There does appear to be some places, here's one I found:

arm_smmu_page_response() -> arm_smmu_cmdq_issue_cmd(), and 
arm_smmu_page_response is set to arm_smmu_ops.page_response, which 
returns an int

Thanks,
John


From lkp at intel.com  Wed Aug 11 04:17:35 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 11 Aug 2021 19:17:35 +0800
Subject: [keystone:for_5.15/drivers-soc] BUILD SUCCESS
 62e8ce8506f5a998796dbdd93363fbed3342d379
Message-ID: <6113b1cf.xblrPLiWiTkCLxzP%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git for_5.15/drivers-soc
branch HEAD: 62e8ce8506f5a998796dbdd93363fbed3342d379  dt-bindings: soc: ti: pruss: Add dma-coherent property

elapsed time: 727m

configs tested: 155
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210811
powerpc                         wii_defconfig
arm                             ezx_defconfig
powerpc                     kmeter1_defconfig
powerpc                      makalu_defconfig
um                           x86_64_defconfig
sh                               j2_defconfig
mips                          rb532_defconfig
sh                        dreamcast_defconfig
xtensa                         virt_defconfig
sh                           se7722_defconfig
m68k                        m5307c3_defconfig
arc                         haps_hs_defconfig
arc                     nsimosci_hs_defconfig
powerpc               mpc834x_itxgp_defconfig
powerpc                      acadia_defconfig
arm                  colibri_pxa270_defconfig
arm                          imote2_defconfig
powerpc                     powernv_defconfig
ia64                                defconfig
m68k                       m5249evb_defconfig
powerpc                      ppc44x_defconfig
s390                          debug_defconfig
powerpc                 mpc834x_itx_defconfig
nds32                               defconfig
mips                           jazz_defconfig
mips                           rs90_defconfig
powerpc                           allnoconfig
m68k                             alldefconfig
powerpc                    adder875_defconfig
mips                      bmips_stb_defconfig
sh                           se7712_defconfig
mips                        qi_lb60_defconfig
powerpc                     pseries_defconfig
sh                           se7724_defconfig
arm64                            alldefconfig
powerpc                        cell_defconfig
riscv                          rv32_defconfig
xtensa                  nommu_kc705_defconfig
arm                       aspeed_g4_defconfig
mips                         bigsur_defconfig
sh                          sdk7786_defconfig
sh                            hp6xx_defconfig
nds32                             allnoconfig
powerpc                     mpc83xx_defconfig
mips                      loongson3_defconfig
microblaze                      mmu_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a004-20210810
x86_64               randconfig-a006-20210810
x86_64               randconfig-a003-20210810
x86_64               randconfig-a005-20210810
x86_64               randconfig-a002-20210810
x86_64               randconfig-a001-20210810
i386                 randconfig-a004-20210810
i386                 randconfig-a002-20210810
i386                 randconfig-a001-20210810
i386                 randconfig-a003-20210810
i386                 randconfig-a006-20210810
i386                 randconfig-a005-20210810
i386                 randconfig-a004-20210811
i386                 randconfig-a001-20210811
i386                 randconfig-a002-20210811
i386                 randconfig-a003-20210811
i386                 randconfig-a006-20210811
i386                 randconfig-a005-20210811
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
i386                 randconfig-a011-20210811
i386                 randconfig-a015-20210811
i386                 randconfig-a014-20210811
i386                 randconfig-a013-20210811
i386                 randconfig-a016-20210811
i386                 randconfig-a012-20210811
i386                 randconfig-a011-20210810
i386                 randconfig-a015-20210810
i386                 randconfig-a013-20210810
i386                 randconfig-a014-20210810
i386                 randconfig-a016-20210810
i386                 randconfig-a012-20210810
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210811
x86_64               randconfig-c001-20210810
x86_64               randconfig-a013-20210810
x86_64               randconfig-a011-20210810
x86_64               randconfig-a012-20210810
x86_64               randconfig-a016-20210810
x86_64               randconfig-a014-20210810
x86_64               randconfig-a015-20210810
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809
x86_64               randconfig-a004-20210811
x86_64               randconfig-a006-20210811
x86_64               randconfig-a003-20210811
x86_64               randconfig-a002-20210811
x86_64               randconfig-a005-20210811
x86_64               randconfig-a001-20210811

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug 11 04:17:32 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 11 Aug 2021 19:17:32 +0800
Subject: [keystone:next] BUILD SUCCESS cb293d3b430e35dbc1e8425869f27624355ff10a
Message-ID: <6113b1cc.PKf07/R2vMWdtd55%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git next
branch HEAD: cb293d3b430e35dbc1e8425869f27624355ff10a  Merge branch 'for_5.15/drivers-soc' into next

elapsed time: 727m

configs tested: 155
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210811
powerpc                         wii_defconfig
arm                             ezx_defconfig
powerpc                     kmeter1_defconfig
powerpc                      makalu_defconfig
um                           x86_64_defconfig
sh                               j2_defconfig
mips                          rb532_defconfig
sh                        dreamcast_defconfig
xtensa                         virt_defconfig
sh                           se7722_defconfig
m68k                        m5307c3_defconfig
arc                         haps_hs_defconfig
arc                     nsimosci_hs_defconfig
powerpc               mpc834x_itxgp_defconfig
powerpc                      acadia_defconfig
arm                  colibri_pxa270_defconfig
arm                          imote2_defconfig
powerpc                     powernv_defconfig
ia64                                defconfig
m68k                       m5249evb_defconfig
powerpc                      ppc44x_defconfig
s390                          debug_defconfig
powerpc                 mpc834x_itx_defconfig
nds32                               defconfig
mips                           jazz_defconfig
mips                           rs90_defconfig
powerpc                           allnoconfig
m68k                             alldefconfig
powerpc                    adder875_defconfig
mips                      bmips_stb_defconfig
sh                           se7712_defconfig
mips                        qi_lb60_defconfig
powerpc                     pseries_defconfig
sh                           se7724_defconfig
arm64                            alldefconfig
powerpc                        cell_defconfig
riscv                          rv32_defconfig
xtensa                  nommu_kc705_defconfig
arm                       aspeed_g4_defconfig
mips                         bigsur_defconfig
sh                          sdk7786_defconfig
sh                            hp6xx_defconfig
nds32                             allnoconfig
powerpc                     mpc83xx_defconfig
mips                      loongson3_defconfig
microblaze                      mmu_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a004-20210810
x86_64               randconfig-a006-20210810
x86_64               randconfig-a003-20210810
x86_64               randconfig-a005-20210810
x86_64               randconfig-a002-20210810
x86_64               randconfig-a001-20210810
i386                 randconfig-a004-20210810
i386                 randconfig-a002-20210810
i386                 randconfig-a001-20210810
i386                 randconfig-a003-20210810
i386                 randconfig-a006-20210810
i386                 randconfig-a005-20210810
i386                 randconfig-a004-20210811
i386                 randconfig-a001-20210811
i386                 randconfig-a002-20210811
i386                 randconfig-a003-20210811
i386                 randconfig-a006-20210811
i386                 randconfig-a005-20210811
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
i386                 randconfig-a011-20210811
i386                 randconfig-a015-20210811
i386                 randconfig-a014-20210811
i386                 randconfig-a013-20210811
i386                 randconfig-a016-20210811
i386                 randconfig-a012-20210811
i386                 randconfig-a011-20210810
i386                 randconfig-a015-20210810
i386                 randconfig-a013-20210810
i386                 randconfig-a014-20210810
i386                 randconfig-a016-20210810
i386                 randconfig-a012-20210810
i386                 randconfig-a012-20210809
i386                 randconfig-a015-20210809
i386                 randconfig-a011-20210809
i386                 randconfig-a013-20210809
i386                 randconfig-a014-20210809
i386                 randconfig-a016-20210809
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210811
x86_64               randconfig-c001-20210810
x86_64               randconfig-a013-20210810
x86_64               randconfig-a011-20210810
x86_64               randconfig-a012-20210810
x86_64               randconfig-a016-20210810
x86_64               randconfig-a014-20210810
x86_64               randconfig-a015-20210810
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809
x86_64               randconfig-a004-20210811
x86_64               randconfig-a006-20210811
x86_64               randconfig-a003-20210811
x86_64               randconfig-a002-20210811
x86_64               randconfig-a005-20210811
x86_64               randconfig-a001-20210811

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From semen.protsenko at linaro.org  Wed Aug 11 04:20:02 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:20:02 +0300
Subject: [PATCH v2 7/8] clk: samsung: Add Exynos850 clock driver stub
In-Reply-To: <bb69e79d-55a8-2090-e51c-fdfea755cf99@samsung.com>
References: <20210806152146.16107-1-semen.protsenko@linaro.org>
 <20210806152146.16107-8-semen.protsenko@linaro.org>
 <3add6f87-7293-e1ae-8f9e-c69e9de18cf5@canonical.com>
 <CGME20210809194915eucas1p19999295aef3127f95ffe4c75a8acc63f@eucas1p1.samsung.com>
 <CAPLW+4=-uUcoLCjjBAC2K5NLswnXGXW1qrsTJrb_uZDgOQ5Ehw@mail.gmail.com>
 <bb69e79d-55a8-2090-e51c-fdfea755cf99@samsung.com>
Message-ID: <CAPLW+4mPrPSeukiJY6DmpEz0V=bjEYbjzLTnJ28T01yqoQY=mg@mail.gmail.com>

On Tue, 10 Aug 2021 at 10:55, Sylwester Nawrocki <s.nawrocki at samsung.com> wrote:
>
> On 09.08.2021 21:48, Sam Protsenko wrote:
> >>> +/* Will be extracted to bindings header once proper clk driver is implemented */
> >>> +#define OSCCLK               1
> >>> +#define DOUT_UART    2
> >>> +#define CLK_NR_CLKS  3
> >>> +
> >>> +/* Fixed rate clocks generated outside the SoC */
> >>> +static struct samsung_fixed_rate_clock exynos850_fixed_rate_ext_clks[] __initdata = {
> >>> +     FRATE(OSCCLK, "fin_pll", NULL, 0, 26000000),
> >>> +};
> >>> +
> >>> +/*
> >>> + * Model the UART clock as a fixed-rate clock for now, to make serial driver
> >>> + * work. This clock is already configured in the bootloader.
> >>> + */
> >>> +static const struct samsung_fixed_rate_clock exynos850_peri_clks[] __initconst = {
> >>> +     FRATE(DOUT_UART, "DOUT_UART", NULL, 0, 200000000),
> >>> +};
> >>> +
> >>> +static const struct of_device_id ext_clk_match[] __initconst = {
> >>> +     { .compatible = "samsung,exynos850-oscclk" },
> >>
> >> One more thing - I am not sure anymore if this is correct. AFAIR, we
> >> wanted to drop compatibles for external clocks.
> >>
> > I'll remove oscclk from the clock driver and device tree. It's not
> > needed right now anyway, as that driver is just a stub.
> >
> > But I'd still like to know the proper way to define external clocks. I
> > can see that in exynos7.dtsi and exynos5433.dtsi there is just regular
> > fixed clock defined for "oscclk" (or "fin_pll"), and then that clock
> > is referenced in corresponding clock driver by its
> > 'clock-output-names' property. I guess that approach is the
> > recommended one?
>
> Yes, we should use generic "fixed-clock" in DT to model the external
> root clock. Registering the external clock from within the CMU driver
> is a legacy method that predates generic "fixed-clock" and should be
> avoided.
>

Thanks for confirming this. I'll go with generic fixed clock in my
clock patch series then.

> That said I think this temporary stub driver is not needed at all,
> you could well define a fixed clock in DT and reference it in the UART
> node, as Krzysztof suggested.
>

Ok, I'll remove the stub clock driver in v3. Using fixed clock in
device tree for serial seems to work fine.

> --
> Regards,
> Sylwester


From maz at kernel.org  Wed Aug 11 04:25:34 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 12:25:34 +0100
Subject: [PATCH v4 00/21] Track shared pages at EL2 in protected mode
In-Reply-To: <20210809152448.1810400-1-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
Message-ID: <162868104087.2706016.2089522816364249636.b4-ty@kernel.org>

On Mon, 9 Aug 2021 16:24:27 +0100, Quentin Perret wrote:
> This is v4 of the patch series previously posted here:
> 
> https://lore.kernel.org/lkml/20210729132818.4091769-1-qperret at google.com/
> 
> This series aims to improve how the nVHE hypervisor tracks ownership of
> memory pages when running in protected mode ("kvm-arm.mode=protected" on
> the kernel command line).
> 
> [...]

Applied to next, thanks!

[01/21] KVM: arm64: Add hyp_spin_is_locked() for basic locking assertions at EL2
        commit: d21292f13f1f0721d60e8122e2db46bea8cf6950
[02/21] KVM: arm64: Introduce hyp_assert_lock_held()
        commit: 8e049e0daf23aa380c264e5e15e4c64ea5497ed7
[03/21] KVM: arm64: Provide the host_stage2_try() helper macro
        commit: 1bac49d490cbc813f407a5c9806e464bf4a300c9
[05/21] KVM: arm64: Expose page-table helpers
        commit: 51add457733bbc4a442fc280d73d14bfe262e4a0
[06/21] KVM: arm64: Optimize host memory aborts
        commit: c4f0935e4d957bfcea25ad76860445660a60f3fd
[07/21] KVM: arm64: Rename KVM_PTE_LEAF_ATTR_S2_IGNORED
        commit: 178cac08d588e7406a09351a992f57892d8d9cc9
[08/21] KVM: arm64: Don't overwrite software bits with owner id
        commit: 8a0282c68121e53ab17413283cfed408a47e1a2a
[09/21] KVM: arm64: Tolerate re-creating hyp mappings to set software bits
        commit: b53846c5f279cb5329b82f19a7d313f02cb9d21c
[10/21] KVM: arm64: Enable forcing page-level stage-2 mappings
        commit: 5651311941105ca077d3ab74dd4a92e646ecf7fb
[11/21] KVM: arm64: Allow populating software bits
        commit: 4505e9b624cefafa4b75d8a28e72f32076c33375
[12/21] KVM: arm64: Add helpers to tag shared pages in SW bits
        commit: ec250a67ea8db6209918a389554cf3aec0395b1f
[13/21] KVM: arm64: Expose host stage-2 manipulation helpers
        commit: 39257da0e04e5cdb1e4a3ca715dc3d949fe8b059
[14/21] KVM: arm64: Expose pkvm_hyp_id
        commit: 2d77e238badb022adb364332b7d6a1d627f77145
[15/21] KVM: arm64: Introduce addr_is_memory()
        commit: e009dce1292c37cf8ee7c33e0887ad3c642f980f
[16/21] KVM: arm64: Enable retrieving protections attributes of PTEs
        commit: 9024b3d0069ab4b8ef70cf55f0ee09e61f3a0747
[17/21] KVM: arm64: Mark host bss and rodata section as shared
        commit: 2c50166c62ba7f3c23c1bbdbb9324db462ddc97b
[18/21] KVM: arm64: Remove __pkvm_mark_hyp
        commit: ad0e0139a8e163245d8f44ab4f6ec3bc9b08034d
[19/21] KVM: arm64: Refactor protected nVHE stage-1 locking
        commit: f9370010e92638f66473baf342e19de940403362
[20/21] KVM: arm64: Restrict EL2 stage-1 changes in protected mode
        commit: 66c57edd3bc79e3527daaae8123f72ecd1e3fa25
[21/21] KVM: arm64: Make __pkvm_create_mappings static
        commit: 64a80fb766f9a91e26930bfc56d8e7c12425df12

Note that patch #4 has been used as the base for this series,
and is already part of the mapping level rework.

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From michal.simek at xilinx.com  Wed Aug 11 04:29:40 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Wed, 11 Aug 2021 13:29:40 +0200
Subject: [PATCH] reset: reset-zynqmp: Fixed the argument data type
In-Reply-To: <20210811103621.GA23827@pengutronix.de>
References: <925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek@xilinx.com>
 <20210811103621.GA23827@pengutronix.de>
Message-ID: <d3bdc4c8-1e31-e1ac-e192-c7bff74eb4af@xilinx.com>



On 8/11/21 12:36 PM, Michael Tretter wrote:
> On Wed, 23 Jun 2021 13:46:20 +0200, Michal Simek wrote:
>> From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
>>
>> This patch changes the data type of the variable 'val' from
>> int to u32.
>>
>> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
>> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
>> Addresses-Coverity: argument of type "int *" is incompatible with parameter of type "u32 *"
>> ---
>>
>>  drivers/reset/reset-zynqmp.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
>> index daa425e74c96..59dc0ff9af9e 100644
>> --- a/drivers/reset/reset-zynqmp.c
>> +++ b/drivers/reset/reset-zynqmp.c
>> @@ -53,7 +53,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
>>  			       unsigned long id)
>>  {
>>  	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
>> -	int val, err;
>> +	int err;
>> +	u32 val;
> 
> The function returns val as int instead of u32. While this shouldn't be a
> problem in this case, maybe there should be an additional check just to be
> sure?

As far as I can tell coverity is not reporting any issue around it.
And when I look at internal of that function in firmware this function
in case of success returns only 0 or 1 that's why I don't think we need
to do anything with it.

Thanks,
Michal


From semen.protsenko at linaro.org  Wed Aug 11 04:48:20 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:48:20 +0300
Subject: [PATCH v3 0/7] Add minimal support for Exynos850 SoC
Message-ID: <20210811114827.27322-1-semen.protsenko@linaro.org>

This patch series adds initial platform support for Samsung Exynos850
SoC [1]. With this patchset it's possible to run the kernel with BusyBox
rootfs as a RAM disk. More advanced platform support (like MMC driver
additions) will be added later. The idea is to keep the first submission
minimal to ease the review, and then build up on top of that.

[1] https://www.samsung.com/semiconductor/minisite/exynos/products/mobileprocessor/exynos-850/

Changes in v3:
 * Removed the stub clock driver; uart clock is modeled as generic fixed
   clock in dts for now
 * See also changes in each particular patch

Changes in v2:
 * Rebased on top of current linux-mainline
 * Removed patch ("pinctrl: samsung: Fix pinctrl bank pin count"); it
   was sent separately, as it's an independent fix
 * Made the patch ("dt-bindings: pinctrl: samsung: Add Exynos850 doc")
   to be the first in series
 * Removed patch ("MAINTAINERS: Changes in v2"); will add that later,
   when proper clock driver is implemented
 * Removed patch ("dt-bindings: clock: Add bindings for Exynos850 clock
   controller"); will add clock bindings later, when proper clock driver
   is implemented
 * Removed patch ("dt-bindings: interrupt-controller: Add IRQ constants
   for Exynos850"), and used hard-coded IRQ numbers in dts instead
 * See also changes in each particular patch

Sam Protsenko (7):
  dt-bindings: pinctrl: samsung: Add Exynos850 doc
  pinctrl: samsung: Add Exynos850 SoC specific data
  dt-bindings: serial: samsung: Add Exynos850 doc
  tty: serial: samsung: Init USI to keep clocks running
  tty: serial: samsung: Fix driver data macros style
  tty: serial: samsung: Add Exynos850 SoC data
  arm64: dts: exynos: Add Exynos850 SoC support

 .../bindings/pinctrl/samsung-pinctrl.txt      |   1 +
 .../bindings/serial/samsung_uart.yaml         |   1 +
 .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos850.dtsi     | 261 ++++++
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 116 +++
 drivers/pinctrl/samsung/pinctrl-exynos.h      |  29 +
 drivers/pinctrl/samsung/pinctrl-samsung.c     |   2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |   1 +
 drivers/tty/serial/samsung_tty.c              |  49 +-
 include/linux/serial_s3c.h                    |   9 +
 10 files changed, 1214 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi

-- 
2.30.2



From semen.protsenko at linaro.org  Wed Aug 11 04:48:21 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:48:21 +0300
Subject: [PATCH v3 1/7] dt-bindings: pinctrl: samsung: Add Exynos850 doc
In-Reply-To: <20210811114827.27322-1-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
Message-ID: <20210811114827.27322-2-semen.protsenko@linaro.org>

Document compatible string for Exynos850 SoC. Nothing else is changed,
as Exynos850 SoC uses already existing samsung pinctrl driver.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - None

Changes in v2:
  - This patch was made the first in the series

 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 38a1416fd2cd..e7a1b1880375 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -22,6 +22,7 @@ Required Properties:
   - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
   - "samsung,exynos5433-pinctrl": for Exynos5433 compatible pin-controller.
   - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
+  - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
-- 
2.30.2



From semen.protsenko at linaro.org  Wed Aug 11 04:48:22 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:48:22 +0300
Subject: [PATCH v3 2/7] pinctrl: samsung: Add Exynos850 SoC specific data
In-Reply-To: <20210811114827.27322-1-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
Message-ID: <20210811114827.27322-3-semen.protsenko@linaro.org>

Add Samsung Exynos850 SoC specific data to enable pinctrl support for
all platforms based on Exynos850.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - Added const qualifier to exynos850_bank_type_* structs
  - Added const and __initconst qualifiers to exynos850_pin_banks*[]
    arrays
  - Renamed EXYNOS9_* mactos to EXYNOS850_*

Changes in v2:
  - Removed .suspend/.resume callbacks, as retention registers are not
    implemented yet for Exynos850
  - Removed .eint_gpio_init for AUD domain, as there are no external
    interrupts available for that domain

 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 116 ++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-exynos.h      |  29 +++++
 drivers/pinctrl/samsung/pinctrl-samsung.c     |   2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |   1 +
 4 files changed, 148 insertions(+)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index b6e56422a700..616c7840927f 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -40,6 +40,24 @@ static const struct samsung_pin_bank_type exynos5433_bank_type_alive = {
 	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
 };
 
+/*
+ * Bank type for non-alive type. Bit fields:
+ * CON: 4, DAT: 1, PUD: 4, DRV: 4, CONPDN: 2, PUDPDN: 4
+ */
+static const struct samsung_pin_bank_type exynos850_bank_type_off  = {
+	.fld_width = { 4, 1, 4, 4, 2, 4, },
+	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
+};
+
+/*
+ * Bank type for alive type. Bit fields:
+ * CON: 4, DAT: 1, PUD: 4, DRV: 4
+ */
+static const struct samsung_pin_bank_type exynos850_bank_type_alive = {
+	.fld_width = { 4, 1, 4, 4, },
+	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
+};
+
 /* Pad retention control code for accessing PMU regmap */
 static atomic_t exynos_shared_retention_refcnt;
 
@@ -422,3 +440,101 @@ const struct samsung_pinctrl_of_match_data exynos7_of_data __initconst = {
 	.ctrl		= exynos7_pin_ctrl,
 	.num_ctrl	= ARRAY_SIZE(exynos7_pin_ctrl),
 };
+
+/* pin banks of exynos850 pin-controller 0 (ALIVE) */
+static const struct samsung_pin_bank_data exynos850_pin_banks0[] __initconst = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS850_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
+	EXYNOS850_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
+	EXYNOS850_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
+	EXYNOS850_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
+	EXYNOS850_PIN_BANK_EINTW(4, 0x080, "gpa4", 0x10),
+	EXYNOS850_PIN_BANK_EINTN(3, 0x0A0, "gpq0"),
+};
+
+/* pin banks of exynos850 pin-controller 1 (CMGP) */
+static const struct samsung_pin_bank_data exynos850_pin_banks1[] __initconst = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS850_PIN_BANK_EINTW(1, 0x000, "gpm0", 0x00),
+	EXYNOS850_PIN_BANK_EINTW(1, 0x020, "gpm1", 0x04),
+	EXYNOS850_PIN_BANK_EINTW(1, 0x040, "gpm2", 0x08),
+	EXYNOS850_PIN_BANK_EINTW(1, 0x060, "gpm3", 0x0C),
+	EXYNOS850_PIN_BANK_EINTW(1, 0x080, "gpm4", 0x10),
+	EXYNOS850_PIN_BANK_EINTW(1, 0x0A0, "gpm5", 0x14),
+	EXYNOS850_PIN_BANK_EINTW(1, 0x0C0, "gpm6", 0x18),
+	EXYNOS850_PIN_BANK_EINTW(1, 0x0E0, "gpm7", 0x1C),
+};
+
+/* pin banks of exynos850 pin-controller 2 (AUD) */
+static const struct samsung_pin_bank_data exynos850_pin_banks2[] __initconst = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS850_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x020, "gpb1", 0x04),
+};
+
+/* pin banks of exynos850 pin-controller 3 (HSI) */
+static const struct samsung_pin_bank_data exynos850_pin_banks3[] __initconst = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS850_PIN_BANK_EINTG(6, 0x000, "gpf2", 0x00),
+};
+
+/* pin banks of exynos850 pin-controller 4 (CORE) */
+static const struct samsung_pin_bank_data exynos850_pin_banks4[] __initconst = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpf0", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x020, "gpf1", 0x04),
+};
+
+/* pin banks of exynos850 pin-controller 5 (PERI) */
+static const struct samsung_pin_bank_data exynos850_pin_banks5[] __initconst = {
+	/* Must start with EINTG banks, ordered by EINT group number. */
+	EXYNOS850_PIN_BANK_EINTG(2, 0x000, "gpg0", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(6, 0x020, "gpp0", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(4, 0x040, "gpp1", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(4, 0x060, "gpp2", 0x0C),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpg1", 0x10),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0A0, "gpg2", 0x14),
+	EXYNOS850_PIN_BANK_EINTG(1, 0x0C0, "gpg3", 0x18),
+	EXYNOS850_PIN_BANK_EINTG(3, 0x0E0, "gpc0", 0x1C),
+	EXYNOS850_PIN_BANK_EINTG(6, 0x100, "gpc1", 0x20),
+};
+
+static const struct samsung_pin_ctrl exynos850_pin_ctrl[] __initconst = {
+	{
+		/* pin-controller instance 0 ALIVE data */
+		.pin_banks	= exynos850_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks0),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.eint_wkup_init = exynos_eint_wkup_init,
+	}, {
+		/* pin-controller instance 1 CMGP data */
+		.pin_banks	= exynos850_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks1),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.eint_wkup_init = exynos_eint_wkup_init,
+	}, {
+		/* pin-controller instance 2 AUD data */
+		.pin_banks	= exynos850_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks2),
+	}, {
+		/* pin-controller instance 3 HSI data */
+		.pin_banks	= exynos850_pin_banks3,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks3),
+		.eint_gpio_init = exynos_eint_gpio_init,
+	}, {
+		/* pin-controller instance 4 CORE data */
+		.pin_banks	= exynos850_pin_banks4,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks4),
+		.eint_gpio_init = exynos_eint_gpio_init,
+	}, {
+		/* pin-controller instance 5 PERI data */
+		.pin_banks	= exynos850_pin_banks5,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks5),
+		.eint_gpio_init = exynos_eint_gpio_init,
+	},
+};
+
+const struct samsung_pinctrl_of_match_data exynos850_of_data __initconst = {
+	.ctrl		= exynos850_pin_ctrl,
+	.num_ctrl	= ARRAY_SIZE(exynos850_pin_ctrl),
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
index da1ec13697e7..bfad1ced8017 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.h
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
@@ -108,6 +108,35 @@
 		.pctl_res_idx   = pctl_idx,			\
 	}							\
 
+#define EXYNOS850_PIN_BANK_EINTN(pins, reg, id)			\
+	{							\
+		.type		= &exynos850_bank_type_alive,	\
+		.pctl_offset	= reg,				\
+		.nr_pins	= pins,				\
+		.eint_type	= EINT_TYPE_NONE,		\
+		.name		= id				\
+	}
+
+#define EXYNOS850_PIN_BANK_EINTG(pins, reg, id, offs)		\
+	{							\
+		.type		= &exynos850_bank_type_off,	\
+		.pctl_offset	= reg,				\
+		.nr_pins	= pins,				\
+		.eint_type	= EINT_TYPE_GPIO,		\
+		.eint_offset	= offs,				\
+		.name		= id				\
+	}
+
+#define EXYNOS850_PIN_BANK_EINTW(pins, reg, id, offs)		\
+	{							\
+		.type		= &exynos850_bank_type_alive,	\
+		.pctl_offset	= reg,				\
+		.nr_pins	= pins,				\
+		.eint_type	= EINT_TYPE_WKUP,		\
+		.eint_offset	= offs,				\
+		.name		= id				\
+	}
+
 /**
  * struct exynos_weint_data: irq specific data for all the wakeup interrupts
  * generated by the external wakeup interrupt controller.
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 2975b4369f32..2a0fc63516f1 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1264,6 +1264,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = &exynos5433_of_data },
 	{ .compatible = "samsung,exynos7-pinctrl",
 		.data = &exynos7_of_data },
+	{ .compatible = "samsung,exynos850-pinctrl",
+		.data = &exynos850_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index de44f8ec330b..4c2149e9c544 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -339,6 +339,7 @@ extern const struct samsung_pinctrl_of_match_data exynos5410_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos5420_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos5433_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
+extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
-- 
2.30.2



From semen.protsenko at linaro.org  Wed Aug 11 04:48:23 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:48:23 +0300
Subject: [PATCH v3 3/7] dt-bindings: serial: samsung: Add Exynos850 doc
In-Reply-To: <20210811114827.27322-1-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
Message-ID: <20210811114827.27322-4-semen.protsenko@linaro.org>

Add compatible string for Exynos850 SoC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - None

Changes in v2:
  - None

 Documentation/devicetree/bindings/serial/samsung_uart.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
index f064e5b76cf1..2940afb874b3 100644
--- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml
+++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
@@ -26,6 +26,7 @@ properties:
           - samsung,s3c6400-uart
           - samsung,s5pv210-uart
           - samsung,exynos4210-uart
+          - samsung,exynos850-uart
 
   reg:
     maxItems: 1
-- 
2.30.2



From semen.protsenko at linaro.org  Wed Aug 11 04:48:24 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:48:24 +0300
Subject: [PATCH v3 4/7] tty: serial: samsung: Init USI to keep clocks running
In-Reply-To: <20210811114827.27322-1-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
Message-ID: <20210811114827.27322-5-semen.protsenko@linaro.org>

UART block is a part of USI (Universal Serial Interface) IP-core in
Samsung SoCs since Exynos9810 (e.g. in Exynos850). USI allows one to
enable one of three types of serial interface: UART, SPI or I2C. That's
possible because USI shares almost all internal circuits within each
protocol. USI also provides some additional registers so it's possible
to configure it.

One USI register called USI_OPTION has reset value of 0x0. Because of
this the clock gating behavior is controlled by hardware (HWACG =
Hardware Auto Clock Gating), which simply means the serial won't work
after reset as is. In order to make it work, USI_OPTION[2:1] bits must
be set to 0b01, so that HWACG is controlled manually (by software).
Bits meaning:
  - CLKREQ_ON = 1: clock is continuously provided to IP
  - CLKSTOP_ON = 0: drive IP_CLKREQ to High (needs to be set along with
                    CLKREQ_ON = 1)

USI is not present on older chips, like s3c2410, s3c2412, s3c2440,
s3c6400, s5pv210, exynos5433, exynos4210. So the new boolean field
'.has_usi' was added to struct s3c24xx_uart_info. USI registers will be
only actually accessed when '.has_usi' field is set to "1".

This feature is needed for further serial enablement on Exynos850, but
some other new Exynos chips (like Exynos9810) may benefit from this
feature as well.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - Added Reviewed-by tag by Krzysztof

Changes in v2:
  - Non-intrusive modification of USI registers
  - Improved comments
  - Rearranged USI register definitions to conform with existing style

 drivers/tty/serial/samsung_tty.c | 32 +++++++++++++++++++++++++++++++-
 include/linux/serial_s3c.h       |  9 +++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 9fbc61151c2e..b8034c1168e0 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -65,6 +65,7 @@ enum s3c24xx_port_type {
 struct s3c24xx_uart_info {
 	char			*name;
 	enum s3c24xx_port_type	type;
+	unsigned int		has_usi;
 	unsigned int		port_type;
 	unsigned int		fifosize;
 	unsigned long		rx_fifomask;
@@ -1352,6 +1353,28 @@ static int apple_s5l_serial_startup(struct uart_port *port)
 	return ret;
 }
 
+static void exynos_usi_init(struct uart_port *port)
+{
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+	struct s3c24xx_uart_info *info = ourport->info;
+	unsigned int val;
+
+	if (!info->has_usi)
+		return;
+
+	/* Clear the software reset of USI block (it's set at startup) */
+	val = rd_regl(port, USI_CON);
+	val &= ~USI_CON_RESET_MASK;
+	wr_regl(port, USI_CON, val);
+	udelay(1);
+
+	/* Continuously provide the clock to USI IP w/o gating (for Rx mode) */
+	val = rd_regl(port, USI_OPTION);
+	val &= ~USI_OPTION_HWACG_MASK;
+	val |= USI_OPTION_HWACG_CLKREQ_ON;
+	wr_regl(port, USI_OPTION, val);
+}
+
 /* power power management control */
 
 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
@@ -1379,6 +1402,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
 		if (!IS_ERR(ourport->baudclk))
 			clk_prepare_enable(ourport->baudclk);
 
+		exynos_usi_init(port);
 		break;
 	default:
 		dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level);
@@ -2102,6 +2126,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 	if (ret)
 		pr_warn("uart: failed to enable baudclk\n");
 
+	exynos_usi_init(port);
+
 	/* Keep all interrupts masked and cleared */
 	switch (ourport->info->type) {
 	case TYPE_S3C6400:
@@ -2750,10 +2776,11 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 #endif
 
 #if defined(CONFIG_ARCH_EXYNOS)
-#define EXYNOS_COMMON_SERIAL_DRV_DATA				\
+#define EXYNOS_COMMON_SERIAL_DRV_DATA_USI(_has_usi)		\
 	.info = &(struct s3c24xx_uart_info) {			\
 		.name		= "Samsung Exynos UART",	\
 		.type		= TYPE_S3C6400,			\
+		.has_usi	= _has_usi,			\
 		.port_type	= PORT_S3C6400,			\
 		.has_divslot	= 1,				\
 		.rx_fifomask	= S5PV210_UFSTAT_RXMASK,	\
@@ -2773,6 +2800,9 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
 		.has_fracval	= 1,				\
 	}							\
 
+#define EXYNOS_COMMON_SERIAL_DRV_DATA				\
+	EXYNOS_COMMON_SERIAL_DRV_DATA_USI(0)
+
 static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
 	EXYNOS_COMMON_SERIAL_DRV_DATA,
 	.fifosize = { 256, 64, 16, 16 },
diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h
index f6c3323fc4c5..cf0de4a86640 100644
--- a/include/linux/serial_s3c.h
+++ b/include/linux/serial_s3c.h
@@ -27,6 +27,15 @@
 #define S3C2410_UERSTAT	  (0x14)
 #define S3C2410_UFSTAT	  (0x18)
 #define S3C2410_UMSTAT	  (0x1C)
+#define USI_CON		  (0xC4)
+#define USI_OPTION	  (0xC8)
+
+#define USI_CON_RESET			(1<<0)
+#define USI_CON_RESET_MASK		(1<<0)
+
+#define USI_OPTION_HWACG_CLKREQ_ON	(1<<1)
+#define USI_OPTION_HWACG_CLKSTOP_ON	(1<<2)
+#define USI_OPTION_HWACG_MASK		(3<<1)
 
 #define S3C2410_LCON_CFGMASK	  ((0xF<<3)|(0x3))
 
-- 
2.30.2



From semen.protsenko at linaro.org  Wed Aug 11 04:48:25 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:48:25 +0300
Subject: [PATCH v3 5/7] tty: serial: samsung: Fix driver data macros style
In-Reply-To: <20210811114827.27322-1-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
Message-ID: <20210811114827.27322-6-semen.protsenko@linaro.org>

Make checkpatch happy by fixing this error:

    ERROR: Macros with complex values should be enclosed in parentheses

Although this change is made to keep macros consistent with consequent
patches (adding driver data for new SoC), it's intentionally added as a
separate patch to ease possible porting efforts in future.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - None

Changes in v2:
  - Added Reviewed-by tag by Krzysztof Kozlowski

 drivers/tty/serial/samsung_tty.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index b8034c1168e0..130bdc978e93 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -2816,8 +2816,8 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
 #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
 #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data)
 #else
-#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
-#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL
+#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
+#define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
 #endif
 
 #ifdef CONFIG_ARCH_APPLE
-- 
2.30.2



From semen.protsenko at linaro.org  Wed Aug 11 04:48:26 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:48:26 +0300
Subject: [PATCH v3 6/7] tty: serial: samsung: Add Exynos850 SoC data
In-Reply-To: <20210811114827.27322-1-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
Message-ID: <20210811114827.27322-7-semen.protsenko@linaro.org>

Add serial driver data for Exynos850 SoC. This driver data is basically
reusing EXYNOS_COMMON_SERIAL_DRV_DATA, which is common for all Exynos
chips, but also enables USI init, which was added in previous commit:
"tty: serial: samsung: Init USI to keep clocks running".

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
  - Added Reviewed-by tag by Krzysztof

Changes in v2:
  - Fixed default fifo sizes

 drivers/tty/serial/samsung_tty.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index 130bdc978e93..a069e7bb858f 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -2813,11 +2813,19 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = {
 	.fifosize = { 64, 256, 16, 256 },
 };
 
+static struct s3c24xx_serial_drv_data exynos850_serial_drv_data = {
+	EXYNOS_COMMON_SERIAL_DRV_DATA_USI(1),
+	.fifosize = { 256, 64, 64, 64 },
+};
+
 #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
 #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data)
+#define EXYNOS850_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos850_serial_drv_data)
+
 #else
 #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
 #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
+#define EXYNOS850_SERIAL_DRV_DATA ((kernel_ulong_t)NULL)
 #endif
 
 #ifdef CONFIG_ARCH_APPLE
@@ -2873,6 +2881,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = {
 	}, {
 		.name		= "s5l-uart",
 		.driver_data	= S5L_SERIAL_DRV_DATA,
+	}, {
+		.name		= "exynos850-uart",
+		.driver_data	= EXYNOS850_SERIAL_DRV_DATA,
 	},
 	{ },
 };
@@ -2896,6 +2907,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = {
 		.data = (void *)EXYNOS5433_SERIAL_DRV_DATA },
 	{ .compatible = "apple,s5l-uart",
 		.data = (void *)S5L_SERIAL_DRV_DATA },
+	{ .compatible = "samsung,exynos850-uart",
+		.data = (void *)EXYNOS850_SERIAL_DRV_DATA },
 	{},
 };
 MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
-- 
2.30.2



From semen.protsenko at linaro.org  Wed Aug 11 04:48:27 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 11 Aug 2021 14:48:27 +0300
Subject: [PATCH v3 7/7] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <20210811114827.27322-1-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
Message-ID: <20210811114827.27322-8-semen.protsenko@linaro.org>

Samsung Exynos850 is ARMv8-based mobile-oriented SoC.

This patch adds minimal SoC support by including next Device Tree nodes:

1. Octa cores (Cortex-A55), supporting PSCI v1.0
2. ARM architecture timer (armv8-timer)
3. Interrupt controller (GIC-400)
4. Pinctrl nodes for GPIO
5. Serial node

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
Changes in v3:
 - Used generic fixed clock for serial

Changes in v2:
 * Commit message:
   - Documented added dts features instead of CPU features

 * exynos850-usi.dtsi:
   - Removed, moved everything to exynos850.dtsi

 * exynos850.dtsi:
   - Root node:
     - Added comment about engineering name (Exynos3830)
     - Renamed pinctrl nodes, adding domain names
     - Used hard coded IRQ numbers instead of named constants everywhere
     - Added soc node, moved next nodes there: gic, clock, pinctrls and
       serial
     - Used address-cells=1 for soc node and removed unneeded 0x0 from
       reg properties
     - Moved exynos850-pinctrl.dtsi include line to the end of
       exynos850.dtsi
     - Coding style fixes
   - cpus:
     - Used address-cells=1 for cpus node
     - Renamed cpu at 0001 to cpu at 1, and so on
     - Left only "arm,cortex-a55" for cpus compatible
     - Renamed reg = <0x0001> to <0x1> for cpus
   - armv8 timer:
     - Add comment about missing HV timer IRQ to armv8 timer node
     - Removed not existing properties from armv8 timer node
     - Fixed cpu number in CPU_MASK()
     - Removed obsolete clock-frequency property
   - GIC:
     - Fixed GIC type to be GIC-400
     - Fixed size of GIC's 2nd region to be 0x2000
   - serial node:
     - Hard coded clock number for serial_0 for now; will replace with
       named const once proper clock driver is implemented
     - Removed gate_uart_clk0 clock from serial_0, as that clock is not
       supported in serial driver anyway (yet)
   - clock node:
     - Fixed clock controller node name (@0x12.. -> @12..)

 * exynos850-pinctrl.dtsi:
   - Referenced pinctrl nodes instead of defining those again in root node
   - Fixed interrupt-cells (3 -> 2)
   - Fixed USI related comments for pin config nodes
   - Removed decon_f_te_* and fm_lna_en nodes (won't be used)
   - Reordered pin config nodes by pin numbers
   - Improved all comments
   - Used existing named constants for pin-function and pin-pud
   - Fixed node names (used hyphens instead of underscore)
   - Fixed warnings found in W=1 build

 .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos850.dtsi     | 261 ++++++
 2 files changed, 1009 insertions(+)
 create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi

diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
new file mode 100644
index 000000000000..ba5d5f33e2f6
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
@@ -0,0 +1,748 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (C) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
+ * tree nodes in this file.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_alive {
+	gpa0: gpa0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa1: gpa1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa2: gpa2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa3: gpa3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa4: gpa4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpq0: gpq0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* I2C5 (also called CAM_PMIC_I2C in TRM) */
+	i2c5_bus: i2c5-bus {
+		samsung,pins = "gpa3-5", "gpa3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* I2C6 (also called MOTOR_I2C in TRM) */
+	i2c6_bus: i2c6-bus {
+		samsung,pins = "gpa3-7", "gpa4-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI: UART */
+	uart0_bus: uart0-bus {
+		samsung,pins = "gpq0-0", "gpq0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+};
+
+&pinctrl_cmgp {
+	gpm0: gpm0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm1: gpm1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm2: gpm2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm3: gpm3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm4: gpm4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm5: gpm5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	/* USI_CMGP0: HSI2C function */
+	hsi2c3_bus: hsi2c3-bus {
+		samsung,pins = "gpm0-0", "gpm1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI_CMGP0: UART function (4 pins, Auto Flow Control) */
+	uart1_bus_single: uart1-bus {
+		samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP0: UART function (2 pins, Non-Auto Flow Control) */
+	uart1_bus_dual: uart1-bus-dual {
+		samsung,pins = "gpm0-0", "gpm1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP0: SPI function */
+	spi1_bus: spi1-bus {
+		samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi1_cs: spi1-cs {
+		samsung,pins = "gpm3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi1_cs_func: spi1-cs-func {
+		samsung,pins = "gpm3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI_CMGP1: HSI2C function */
+	hsi2c4_bus: hsi2c4-bus {
+		samsung,pins = "gpm4-0", "gpm5-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI_CMGP1: UART function (4 pins, Auto Flow Control) */
+	uart2_bus_single: uart2-bus {
+		samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP1: UART function (2 pins, Non-Auto Flow Control) */
+	uart2_bus_dual: uart2-bus-dual {
+		samsung,pins = "gpm4-0", "gpm5-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP1: SPI function */
+	spi2_bus: spi2-bus {
+		samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi2_cs: spi2-cs {
+		samsung,pins = "gpm7-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi2_cs_func: spi2-cs-func {
+		samsung,pins = "gpm7-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+};
+
+&pinctrl_aud {
+	gpb0: gpb0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	aud_codec_mclk: aud-codec-mclk {
+		samsung,pins = "gpb0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_codec_mclk_idle: aud-codec-mclk-idle {
+		samsung,pins = "gpb0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s0_bus: aud-i2s0-bus {
+		samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s0_idle: aud-i2s0-idle {
+		samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s1_bus: aud-i2s1-bus {
+		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s1_idle: aud-i2s1-idle {
+		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_fm_bus: aud-fm-bus {
+		samsung,pins = "gpb1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_fm_idle: aud-fm-idle {
+		samsung,pins = "gpb1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+};
+
+&pinctrl_hsi {
+	gpf2: gpf2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sd2_clk: sd2-clk {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_clk_fast_slew_rate_1x: sd2-clk-fast-slew-rate-1x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	sd2_clk_fast_slew_rate_1_5x: sd2-clk-fast-slew-rate-1-5x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <1>;
+	};
+
+	sd2_clk_fast_slew_rate_2x: sd2-clk-fast-slew-rate-2x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_clk_fast_slew_rate_2_5x: sd2-clk-fast-slew-rate-2-5x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_clk_fast_slew_rate_3x: sd2-clk-fast-slew-rate-3x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <4>;
+	};
+
+	sd2_clk_fast_slew_rate_4x: sd2-clk-fast-slew-rate-4x {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <5>;
+	};
+
+	sd2_cmd: sd2-cmd {
+		samsung,pins = "gpf2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <2>;
+	 };
+
+	sd2_bus1: sd2-bus-width1 {
+		samsung,pins = "gpf2-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_bus4: sd2-bus-width4 {
+		samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd2_pins_as_pdn: sd2-pins-as-pdn {
+		samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+			       "gpf2-4", "gpf2-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+};
+
+&pinctrl_core {
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sd0_clk: sd0-clk {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_clk_fast_slew_rate_1x: sd0-clk-fast-slew-rate-1x {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <1>;
+	};
+
+	sd0_clk_fast_slew_rate_2x: sd0-clk-fast-slew-rate-2x {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd0_clk_fast_slew_rate_3x: sd0-clk-fast-slew-rate-3x {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sd0_clk_fast_slew_rate_4x: sd0-clk-fast-slew-rate-4x {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_cmd: sd0-cmd {
+		samsung,pins = "gpf0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_rdqs: sd0-rdqs {
+		samsung,pins = "gpf0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_nreset: sd0-nreset {
+		samsung,pins = "gpf0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus1: sd0-bus-width1 {
+		samsung,pins = "gpf1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus4: sd0-bus-width4 {
+		samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd0_bus8: sd0-bus-width8 {
+		samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <3>;
+	};
+};
+
+&pinctrl_peri {
+	gpg0: gpg0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp0: gpp0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+	gpp1: gpp1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp2: gpp2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc0: gpc0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc1: gpc1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* USI: HSI2C0 */
+	hsi2c0_bus: hsi2c0-bus {
+		samsung,pins = "gpc1-0", "gpc1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI: HSI2C1 */
+	hsi2c1_bus: hsi2c1-bus {
+		samsung,pins = "gpc1-2", "gpc1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI: HSI2C2 */
+	hsi2c2_bus: hsi2c2-bus {
+		samsung,pins = "gpc1-4", "gpc1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	/* USI: SPI */
+	spi0_bus: spi0-bus {
+		samsung,pins = "gpp2-0", "gpp2-2", "gpp2-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi0_cs: spi0-cs {
+		samsung,pins = "gpp2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	spi0_cs_func: spi0-cs-func {
+		samsung,pins = "gpp2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c0_bus: i2c0-bus {
+		samsung,pins = "gpp0-0", "gpp0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c1_bus: i2c1-bus {
+		samsung,pins = "gpp0-2", "gpp0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c2_bus: i2c2-bus {
+		samsung,pins = "gpp0-4", "gpp0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c3_bus: i2c3-bus {
+		samsung,pins = "gpp1-0", "gpp1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	i2c4_bus: i2c4-bus {
+		samsung,pins = "gpp1-2", "gpp1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <0>;
+	};
+
+	sensor_mclk0_in: sensor-mclk0-in {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk0_out: sensor-mclk0-out {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk0_fn: sensor-mclk0-fn {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk1_in: sensor-mclk1-in {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk1_out: sensor-mclk1-out {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk1_fn: sensor-mclk1-fn {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk2_in: sensor-mclk2-in {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk2_out: sensor-mclk2-out {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <2>;
+	};
+
+	sensor_mclk2_fn: sensor-mclk2-fn {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <2>;
+	};
+
+	xclkout: xclkout {
+		samsung,pins = "gpq0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
new file mode 100644
index 000000000000..2360f142159f
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung Exynos850 SoC device tree source
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Samsung Exynos850 SoC device nodes are listed in this file.
+ * Exynos based board files can include this file and provide
+ * values for board specific bindings.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	/* Also known under engineering name Exynos3830 */
+	compatible = "samsung,exynos850";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	aliases {
+		pinctrl0 = &pinctrl_alive;
+		pinctrl1 = &pinctrl_cmgp;
+		pinctrl2 = &pinctrl_aud;
+		pinctrl3 = &pinctrl_hsi;
+		pinctrl4 = &pinctrl_core;
+		pinctrl5 = &pinctrl_peri;
+		serial0 = &serial_0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+				core2 {
+					cpu = <&cpu2>;
+				};
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+				core1 {
+					cpu = <&cpu5>;
+				};
+				core2 {
+					cpu = <&cpu6>;
+				};
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0>;
+			enable-method = "psci";
+		};
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x1>;
+			enable-method = "psci";
+		};
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x2>;
+			enable-method = "psci";
+		};
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x3>;
+			enable-method = "psci";
+		};
+		cpu4: cpu at 4 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+		};
+		cpu5: cpu at 5 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x101>;
+			enable-method = "psci";
+		};
+		cpu6: cpu at 6 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x102>;
+			enable-method = "psci";
+		};
+		cpu7: cpu at 7 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x103>;
+			enable-method = "psci";
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		/* Hypervisor Virtual Timer interrupt is not wired to GIC */
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) |
+					  IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x0 0x20000000>;
+
+		gic: interrupt-controller at 12a01000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			reg = <0x12a01000 0x1000>,
+			      <0x12a02000 0x2000>,
+			      <0x12a04000 0x2000>,
+			      <0x12a06000 0x2000>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) |
+						 IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		/*
+		 * Keep the stub clock for serial driver, until proper clock
+		 * driver is implemented.
+		 */
+		uart_clock: uart-clock {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <200000000>;
+			clock-output-names = "uart";
+		};
+
+		pinctrl_alive: pinctrl at 11850000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x11850000 0x1000>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos7-wakeup-eint";
+			};
+		};
+
+		pinctrl_cmgp: pinctrl at 11c30000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x11c30000 0x1000>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos7-wakeup-eint";
+			};
+		};
+
+		pinctrl_aud: pinctrl at 14a60000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x14a60000 0x1000>;
+		};
+
+		pinctrl_hsi: pinctrl at 13430000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x13430000 0x1000>;
+			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_core: pinctrl at 12070000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x12070000 0x1000>;
+			interrupts = <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_peri: pinctrl at 139b0000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x139b0000 0x1000>;
+			interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		/* USI: UART */
+		serial_0: uart at 13820000 {
+			compatible = "samsung,exynos850-uart";
+			reg = <0x13820000 0x100>;
+			interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_bus>;
+			clocks = <&uart_clock>;
+			clock-names = "uart";
+			status = "disabled";
+		};
+	};
+};
+
+#include "exynos850-pinctrl.dtsi"
-- 
2.30.2



From thunder.leizhen at huawei.com  Wed Aug 11 04:48:48 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Wed, 11 Aug 2021 19:48:48 +0800
Subject: [PATCH 0/4] Prepare for ECMDQ support
Message-ID: <20210811114852.2429-1-thunder.leizhen@huawei.com>

RFC --> v1
1. Resend the patches for ECMDQ preparation and remove the patches for ECMDQ implementation.
2. Patch 2 is modified. Other patches remain unchanged.
   1) Add static helper __arm_smmu_cmdq_issue_cmd(), and make arm_smmu_cmdq_issue_cmd()
      and arm_smmu_cmdq_issue_cmd_with_sync() implement based on it.
   2) Remove unused arm_smmu_cmdq_issue_sync().

RFC:
https://www.spinics.net/lists/arm-kernel/msg904879.html


Zhen Lei (4):
  iommu/arm-smmu-v3: Use command queue batching helpers to improve
    performance
  iommu/arm-smmu-v3: Add and use static helper function
    arm_smmu_cmdq_issue_cmd_with_sync()
  iommu/arm-smmu-v3: Add and use static helper function
    arm_smmu_get_cmdq()
  iommu/arm-smmu-v3: Extract reusable function
    __arm_smmu_cmdq_skip_err()

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 71 ++++++++++++---------
 1 file changed, 42 insertions(+), 29 deletions(-)

-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Wed Aug 11 04:48:52 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Wed, 11 Aug 2021 19:48:52 +0800
Subject: [PATCH 4/4] iommu/arm-smmu-v3: Extract reusable function
 __arm_smmu_cmdq_skip_err()
In-Reply-To: <20210811114852.2429-1-thunder.leizhen@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
Message-ID: <20210811114852.2429-5-thunder.leizhen@huawei.com>

When SMMU_GERROR.CMDQP_ERR is different to SMMU_GERRORN.CMDQP_ERR, it
indicates that one or more errors have been encountered on a command queue
control page interface. We need to traverse all ECMDQs in that control
page to find all errors. For each ECMDQ error handling, it is much the
same as the CMDQ error handling. This common processing part is extracted
as a new function __arm_smmu_cmdq_skip_err().

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index be2df5ad2eb51b8..597cc0ff5ef40f0 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -359,7 +359,8 @@ static void arm_smmu_cmdq_build_sync_cmd(u64 *cmd, struct arm_smmu_device *smmu,
 	arm_smmu_cmdq_build_cmd(cmd, &ent);
 }
 
-static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
+static void __arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu,
+				     struct arm_smmu_queue *q)
 {
 	static const char * const cerror_str[] = {
 		[CMDQ_ERR_CERROR_NONE_IDX]	= "No error",
@@ -370,7 +371,6 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
 
 	int i;
 	u64 cmd[CMDQ_ENT_DWORDS];
-	struct arm_smmu_queue *q = &smmu->cmdq.q;
 	u32 cons = readl_relaxed(q->cons_reg);
 	u32 idx = FIELD_GET(CMDQ_CONS_ERR, cons);
 	struct arm_smmu_cmdq_ent cmd_sync = {
@@ -417,6 +417,11 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
 	queue_write(Q_ENT(q, cons), cmd, q->ent_dwords);
 }
 
+static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
+{
+	__arm_smmu_cmdq_skip_err(smmu, &smmu->cmdq.q);
+}
+
 /*
  * Command queue locking.
  * This is a form of bastardised rwlock with the following major changes:
-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Wed Aug 11 04:48:50 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Wed, 11 Aug 2021 19:48:50 +0800
Subject: [PATCH 2/4] iommu/arm-smmu-v3: Add and use static helper function
 arm_smmu_cmdq_issue_cmd_with_sync()
In-Reply-To: <20210811114852.2429-1-thunder.leizhen@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
Message-ID: <20210811114852.2429-3-thunder.leizhen@huawei.com>

The obvious key to the performance optimization of commit 587e6c10a7ce
("iommu/arm-smmu-v3: Reduce contention during command-queue insertion") is
to allow multiple cores to insert commands in parallel after a brief mutex
contention.

Obviously, inserting as many commands at a time as possible can reduce the
number of times the mutex contention participates, thereby improving the
overall performance. At least it reduces the number of calls to function
arm_smmu_cmdq_issue_cmdlist().

Therefore, function arm_smmu_cmdq_issue_cmd_with_sync() is added to insert
the 'cmd+sync' commands at a time.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 35 +++++++++++----------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index c81cd929047f573..282f95659580267 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -845,8 +845,9 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 	return ret;
 }
 
-static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
-				   struct arm_smmu_cmdq_ent *ent)
+static int __arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
+				     struct arm_smmu_cmdq_ent *ent,
+				     bool sync)
 {
 	u64 cmd[CMDQ_ENT_DWORDS];
 
@@ -856,12 +857,19 @@ static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
 		return -EINVAL;
 	}
 
-	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
+	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, sync);
 }
 
-static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
+static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
+				   struct arm_smmu_cmdq_ent *ent)
 {
-	return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
+	return __arm_smmu_cmdq_issue_cmd(smmu, ent, false);
+}
+
+static int arm_smmu_cmdq_issue_cmd_with_sync(struct arm_smmu_device *smmu,
+					     struct arm_smmu_cmdq_ent *ent)
+{
+	return __arm_smmu_cmdq_issue_cmd(smmu, ent, true);
 }
 
 static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu,
@@ -929,8 +937,7 @@ void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid)
 		.tlbi.asid = asid,
 	};
 
-	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-	arm_smmu_cmdq_issue_sync(smmu);
+	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 }
 
 static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
@@ -1211,8 +1218,7 @@ static void arm_smmu_sync_ste_for_sid(struct arm_smmu_device *smmu, u32 sid)
 		},
 	};
 
-	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-	arm_smmu_cmdq_issue_sync(smmu);
+	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 }
 
 static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
@@ -1824,8 +1830,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
 	} else {
 		cmd.opcode	= CMDQ_OP_TLBI_S12_VMALL;
 		cmd.tlbi.vmid	= smmu_domain->s2_cfg.vmid;
-		arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-		arm_smmu_cmdq_issue_sync(smmu);
+		arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 	}
 	arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
 }
@@ -3339,18 +3344,16 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 
 	/* Invalidate any cached configuration */
 	cmd.opcode = CMDQ_OP_CFGI_ALL;
-	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-	arm_smmu_cmdq_issue_sync(smmu);
+	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 
 	/* Invalidate any stale TLB entries */
 	if (smmu->features & ARM_SMMU_FEAT_HYP) {
 		cmd.opcode = CMDQ_OP_TLBI_EL2_ALL;
-		arm_smmu_cmdq_issue_cmd(smmu, &cmd);
+		arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 	}
 
 	cmd.opcode = CMDQ_OP_TLBI_NSNH_ALL;
-	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-	arm_smmu_cmdq_issue_sync(smmu);
+	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 
 	/* Event queue */
 	writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE);
-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Wed Aug 11 04:48:49 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Wed, 11 Aug 2021 19:48:49 +0800
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching helpers to
 improve performance
In-Reply-To: <20210811114852.2429-1-thunder.leizhen@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
Message-ID: <20210811114852.2429-2-thunder.leizhen@huawei.com>

The obvious key to the performance optimization of commit 587e6c10a7ce
("iommu/arm-smmu-v3: Reduce contention during command-queue insertion") is
to allow multiple cores to insert commands in parallel after a brief mutex
contention.

Obviously, inserting as many commands at a time as possible can reduce the
number of times the mutex contention participates, thereby improving the
overall performance. At least it reduces the number of calls to function
arm_smmu_cmdq_issue_cmdlist().

Therefore, use command queue batching helpers to insert multiple commands
at a time.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 235f9bdaeaf223b..c81cd929047f573 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1747,15 +1747,16 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
 {
 	int i;
 	struct arm_smmu_cmdq_ent cmd;
+	struct arm_smmu_cmdq_batch cmds = {};
 
 	arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
 
 	for (i = 0; i < master->num_streams; i++) {
 		cmd.atc.sid = master->streams[i].id;
-		arm_smmu_cmdq_issue_cmd(master->smmu, &cmd);
+		arm_smmu_cmdq_batch_add(master->smmu, &cmds, &cmd);
 	}
 
-	return arm_smmu_cmdq_issue_sync(master->smmu);
+	return arm_smmu_cmdq_batch_submit(master->smmu, &cmds);
 }
 
 int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Wed Aug 11 04:48:51 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Wed, 11 Aug 2021 19:48:51 +0800
Subject: [PATCH 3/4] iommu/arm-smmu-v3: Add and use static helper function
 arm_smmu_get_cmdq()
In-Reply-To: <20210811114852.2429-1-thunder.leizhen@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
Message-ID: <20210811114852.2429-4-thunder.leizhen@huawei.com>

One SMMU has only one normal CMDQ. Therefore, this CMDQ is used regardless
of the core on which the command is inserted. It can be referenced
directly through "smmu->cmdq". However, one SMMU has multiple ECMDQs, and
the ECMDQ used by the core on which the command insertion is executed may
be different. So the helper function arm_smmu_get_cmdq() is added, which
returns the CMDQ/ECMDQ that the current core should use. Currently, the
code that supports ECMDQ is not added. just simply returns "&smmu->cmdq".

Many subfunctions of arm_smmu_cmdq_issue_cmdlist() use "&smmu->cmdq" or
"&smmu->cmdq.q" directly. To support ECMDQ, they need to call the newly
added function arm_smmu_get_cmdq() instead.

Note that normal CMDQ is still required until ECMDQ is available.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 ++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 282f95659580267..be2df5ad2eb51b8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -335,10 +335,14 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 	return 0;
 }
 
+static struct arm_smmu_cmdq *arm_smmu_get_cmdq(struct arm_smmu_device *smmu)
+{
+	return &smmu->cmdq;
+}
+
 static void arm_smmu_cmdq_build_sync_cmd(u64 *cmd, struct arm_smmu_device *smmu,
-					 u32 prod)
+					 struct arm_smmu_queue *q, u32 prod)
 {
-	struct arm_smmu_queue *q = &smmu->cmdq.q;
 	struct arm_smmu_cmdq_ent ent = {
 		.opcode = CMDQ_OP_CMD_SYNC,
 	};
@@ -579,7 +583,7 @@ static int arm_smmu_cmdq_poll_until_not_full(struct arm_smmu_device *smmu,
 {
 	unsigned long flags;
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	int ret = 0;
 
 	/*
@@ -595,7 +599,7 @@ static int arm_smmu_cmdq_poll_until_not_full(struct arm_smmu_device *smmu,
 
 	queue_poll_init(smmu, &qp);
 	do {
-		llq->val = READ_ONCE(smmu->cmdq.q.llq.val);
+		llq->val = READ_ONCE(cmdq->q.llq.val);
 		if (!queue_full(llq))
 			break;
 
@@ -614,7 +618,7 @@ static int __arm_smmu_cmdq_poll_until_msi(struct arm_smmu_device *smmu,
 {
 	int ret = 0;
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	u32 *cmd = (u32 *)(Q_ENT(&cmdq->q, llq->prod));
 
 	queue_poll_init(smmu, &qp);
@@ -637,12 +641,12 @@ static int __arm_smmu_cmdq_poll_until_consumed(struct arm_smmu_device *smmu,
 					       struct arm_smmu_ll_queue *llq)
 {
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	u32 prod = llq->prod;
 	int ret = 0;
 
 	queue_poll_init(smmu, &qp);
-	llq->val = READ_ONCE(smmu->cmdq.q.llq.val);
+	llq->val = READ_ONCE(cmdq->q.llq.val);
 	do {
 		if (queue_consumed(llq, prod))
 			break;
@@ -732,7 +736,7 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 	u32 prod;
 	unsigned long flags;
 	bool owner;
-	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	struct arm_smmu_ll_queue llq = {
 		.max_n_shift = cmdq->q.llq.max_n_shift,
 	}, head = llq;
@@ -772,7 +776,7 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 	arm_smmu_cmdq_write_entries(cmdq, cmds, llq.prod, n);
 	if (sync) {
 		prod = queue_inc_prod_n(&llq, n);
-		arm_smmu_cmdq_build_sync_cmd(cmd_sync, smmu, prod);
+		arm_smmu_cmdq_build_sync_cmd(cmd_sync, smmu, &cmdq->q, prod);
 		queue_write(Q_ENT(&cmdq->q, prod), cmd_sync, CMDQ_ENT_DWORDS);
 
 		/*
-- 
2.26.0.106.g9fadedd



From tangbin at cmss.chinamobile.com  Wed Aug 11 04:55:23 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Wed, 11 Aug 2021 19:55:23 +0800
Subject: [PATCH] ASoC: stm32: spdifrx: Delete unnecessary check in the probe
 function
Message-ID: <20210811115523.17232-1-tangbin@cmss.chinamobile.com>

The function stm32_spdifrx_parse_of() is only called by the function
stm32_spdifrx_probe(), and the probe function is only called with
an openfirmware platform device. Therefore there is no need to check
the device_node in probe function.

Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 sound/soc/stm/stm32_spdifrx.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
index 48145f553..8fe822903 100644
--- a/sound/soc/stm/stm32_spdifrx.c
+++ b/sound/soc/stm/stm32_spdifrx.c
@@ -908,13 +908,9 @@ static const struct of_device_id stm32_spdifrx_ids[] = {
 static int stm32_spdifrx_parse_of(struct platform_device *pdev,
 				  struct stm32_spdifrx_data *spdifrx)
 {
-	struct device_node *np = pdev->dev.of_node;
 	const struct of_device_id *of_id;
 	struct resource *res;
 
-	if (!np)
-		return -ENODEV;
-
 	of_id = of_match_device(stm32_spdifrx_ids, &pdev->dev);
 	if (of_id)
 		spdifrx->regmap_conf =
-- 
2.20.1.windows.1





From broonie at kernel.org  Wed Aug 11 04:58:46 2021
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Aug 2021 12:58:46 +0100
Subject: [PATCH] ASoC: stm32: spdifrx: Delete unnecessary check in the
 probe function
In-Reply-To: <20210811115523.17232-1-tangbin@cmss.chinamobile.com>
References: <20210811115523.17232-1-tangbin@cmss.chinamobile.com>
Message-ID: <20210811115846.GC4167@sirena.org.uk>

On Wed, Aug 11, 2021 at 07:55:23PM +0800, Tang Bin wrote:
> The function stm32_spdifrx_parse_of() is only called by the function
> stm32_spdifrx_probe(), and the probe function is only called with
> an openfirmware platform device. Therefore there is no need to check
> the device_node in probe function.

What is the benefit of not doing the check?  It seems like reasonable
defensive programming.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210811/e9a4f328/attachment.sig>

From viresh.kumar at linaro.org  Wed Aug 11 04:58:38 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 17:28:38 +0530
Subject: [PATCH V2 0/9] cpufreq: Auto-register with energy model
Message-ID: <cover.1628682874.git.viresh.kumar@linaro.org>

Many cpufreq drivers register with the energy model for each policy and
do exactly the same thing. Follow the footsteps of thermal-cooling, to
get it done from the cpufreq core itself.

Provide a new callback, which will be called, if present, by the cpufreq
core at the right moment (more on that in the code's comment). Also
provide a generic implementation that uses dev_pm_opp_of_register_em().

This also allows us to register with the EM at a later point of time,
compared to ->init(), from where the EM core can access cpufreq policy
directly using cpufreq_cpu_get() type of helpers and perform other work,
like marking few frequencies inefficient, this will be done separately.

This is build/boot tested by the bot for a couple of boards.

https://gitlab.com/vireshk/pmko/-/pipelines/351525873

Note that I haven't picked any of the Reviewed-by tags from the first version
since the idea is very much changed here.

V1->V2:
- Add a callback instead of flag.
- Register before governor is initialized.
- Update scmi driver as well.
- Don't unregister from the EM core.

--
Viresh

Viresh Kumar (9):
  cpufreq: Auto-register with energy model if asked
  cpufreq: dt: Use auto-registration for energy model
  cpufreq: imx6q: Use auto-registration for energy model
  cpufreq: mediatek: Use auto-registration for energy model
  cpufreq: omap: Use auto-registration for energy model
  cpufreq: qcom-cpufreq-hw: Use auto-registration for energy model
  cpufreq: scpi: Use auto-registration for energy model
  cpufreq: vexpress: Use auto-registration for energy model
  cpufreq: scmi: Use .register_em() callback

 drivers/cpufreq/cpufreq-dt.c           |  3 +-
 drivers/cpufreq/cpufreq.c              | 12 ++++++
 drivers/cpufreq/imx6q-cpufreq.c        |  2 +-
 drivers/cpufreq/mediatek-cpufreq.c     |  3 +-
 drivers/cpufreq/omap-cpufreq.c         |  2 +-
 drivers/cpufreq/qcom-cpufreq-hw.c      |  3 +-
 drivers/cpufreq/scmi-cpufreq.c         | 55 +++++++++++++++-----------
 drivers/cpufreq/scpi-cpufreq.c         |  3 +-
 drivers/cpufreq/vexpress-spc-cpufreq.c |  3 +-
 include/linux/cpufreq.h                | 14 +++++++
 10 files changed, 65 insertions(+), 35 deletions(-)

-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 04:58:41 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 17:28:41 +0530
Subject: [PATCH V2 3/9] cpufreq: imx6q: Use auto-registration for energy model
In-Reply-To: <cover.1628682874.git.viresh.kumar@linaro.org>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
Message-ID: <69cd4b06c671fabf828c853a7dd6ea6225357d42.1628682874.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback with
cpufreq_register_em_with_opp() to automatically register with the EM
core.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/imx6q-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 5bf5fc759881..90beb26ed34e 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -192,7 +192,6 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
 	policy->clk = clks[ARM].clk;
 	cpufreq_generic_init(policy, freq_table, transition_latency);
 	policy->suspend_freq = max_freq;
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
 
 	return 0;
 }
@@ -204,6 +203,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
 	.target_index = imx6q_set_target,
 	.get = cpufreq_generic_get,
 	.init = imx6q_cpufreq_init,
+	.register_em = cpufreq_register_em_with_opp,
 	.name = "imx6q-cpufreq",
 	.attr = cpufreq_generic_attr,
 	.suspend = cpufreq_generic_suspend,
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 04:58:42 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 17:28:42 +0530
Subject: [PATCH V2 4/9] cpufreq: mediatek: Use auto-registration for energy
 model
In-Reply-To: <cover.1628682874.git.viresh.kumar@linaro.org>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
Message-ID: <c643714aa4e525aea4d54c2fd35950c046555621.1628682874.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback with
cpufreq_register_em_with_opp() to automatically register with the EM
core.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/mediatek-cpufreq.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
index 87019d5a9547..866163883b48 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -448,8 +448,6 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy)
 	policy->driver_data = info;
 	policy->clk = info->cpu_clk;
 
-	dev_pm_opp_of_register_em(info->cpu_dev, policy->cpus);
-
 	return 0;
 }
 
@@ -471,6 +469,7 @@ static struct cpufreq_driver mtk_cpufreq_driver = {
 	.get = cpufreq_generic_get,
 	.init = mtk_cpufreq_init,
 	.exit = mtk_cpufreq_exit,
+	.register_em = cpufreq_register_em_with_opp,
 	.name = "mtk-cpufreq",
 	.attr = cpufreq_generic_attr,
 };
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 04:58:45 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 17:28:45 +0530
Subject: [PATCH V2 7/9] cpufreq: scpi: Use auto-registration for energy model
In-Reply-To: <cover.1628682874.git.viresh.kumar@linaro.org>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
Message-ID: <29c65db2dfcbfebdb291a3056cc2adaca8b34cec.1628682874.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback with
cpufreq_register_em_with_opp() to automatically register with the EM
core.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/scpi-cpufreq.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
index d6a698a1b5d1..bda3e7d42964 100644
--- a/drivers/cpufreq/scpi-cpufreq.c
+++ b/drivers/cpufreq/scpi-cpufreq.c
@@ -163,8 +163,6 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
 
 	policy->fast_switch_possible = false;
 
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
-
 	return 0;
 
 out_free_cpufreq_table:
@@ -200,6 +198,7 @@ static struct cpufreq_driver scpi_cpufreq_driver = {
 	.init	= scpi_cpufreq_init,
 	.exit	= scpi_cpufreq_exit,
 	.target_index	= scpi_cpufreq_set_target,
+	.register_em	= cpufreq_register_em_with_opp,
 };
 
 static int scpi_cpufreq_probe(struct platform_device *pdev)
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 04:58:46 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 17:28:46 +0530
Subject: [PATCH V2 8/9] cpufreq: vexpress: Use auto-registration for energy
 model
In-Reply-To: <cover.1628682874.git.viresh.kumar@linaro.org>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
Message-ID: <0bc6387893ea7215da658943ddaa2208f5f3e239.1628682874.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback with
cpufreq_register_em_with_opp() to automatically register with the EM
core.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/vexpress-spc-cpufreq.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c
index ab56813b7256..284b6bd040b1 100644
--- a/drivers/cpufreq/vexpress-spc-cpufreq.c
+++ b/drivers/cpufreq/vexpress-spc-cpufreq.c
@@ -440,8 +440,6 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy)
 	policy->freq_table = freq_table[cur_cluster];
 	policy->cpuinfo.transition_latency = 1000000; /* 1 ms */
 
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
-
 	if (is_bL_switching_enabled())
 		per_cpu(cpu_last_req_freq, policy->cpu) =
 						clk_get_cpu_rate(policy->cpu);
@@ -475,6 +473,7 @@ static struct cpufreq_driver ve_spc_cpufreq_driver = {
 	.get			= ve_spc_cpufreq_get_rate,
 	.init			= ve_spc_cpufreq_init,
 	.exit			= ve_spc_cpufreq_exit,
+	.register_em		= cpufreq_register_em_with_opp,
 	.attr			= cpufreq_generic_attr,
 };
 
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 04:58:47 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 11 Aug 2021 17:28:47 +0530
Subject: [PATCH V2 9/9] cpufreq: scmi: Use .register_em() callback
In-Reply-To: <cover.1628682874.git.viresh.kumar@linaro.org>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
Message-ID: <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback to register with the EM
after the cpufreq policy is properly initialized.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/scmi-cpufreq.c | 55 ++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 23 deletions(-)

diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index 75f818d04b48..b916c9e22921 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -22,7 +22,9 @@
 
 struct scmi_data {
 	int domain_id;
+	int nr_opp;
 	struct device *cpu_dev;
+	cpumask_var_t opp_shared_cpus;
 };
 
 static struct scmi_protocol_handle *ph;
@@ -123,9 +125,6 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	struct device *cpu_dev;
 	struct scmi_data *priv;
 	struct cpufreq_frequency_table *freq_table;
-	struct em_data_callback em_cb = EM_DATA_CB(scmi_get_cpu_power);
-	cpumask_var_t opp_shared_cpus;
-	bool power_scale_mw;
 
 	cpu_dev = get_cpu_device(policy->cpu);
 	if (!cpu_dev) {
@@ -133,9 +132,15 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 		return -ENODEV;
 	}
 
-	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL))
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
 
+	if (!zalloc_cpumask_var(&priv->opp_shared_cpus, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto out_free_priv;
+	}
+
 	/* Obtain CPUs that share SCMI performance controls */
 	ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
 	if (ret) {
@@ -148,14 +153,14 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	 * The OPP 'sharing cpus' info may come from DT through an empty opp
 	 * table and opp-shared.
 	 */
-	ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, opp_shared_cpus);
-	if (ret || !cpumask_weight(opp_shared_cpus)) {
+	ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->opp_shared_cpus);
+	if (ret || !cpumask_weight(priv->opp_shared_cpus)) {
 		/*
 		 * Either opp-table is not set or no opp-shared was found.
 		 * Use the CPU mask from SCMI to designate CPUs sharing an OPP
 		 * table.
 		 */
-		cpumask_copy(opp_shared_cpus, policy->cpus);
+		cpumask_copy(priv->opp_shared_cpus, policy->cpus);
 	}
 
 	 /*
@@ -180,7 +185,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 			goto out_free_opp;
 		}
 
-		ret = dev_pm_opp_set_sharing_cpus(cpu_dev, opp_shared_cpus);
+		ret = dev_pm_opp_set_sharing_cpus(cpu_dev, priv->opp_shared_cpus);
 		if (ret) {
 			dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
 				__func__, ret);
@@ -188,21 +193,13 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 			goto out_free_opp;
 		}
 
-		power_scale_mw = perf_ops->power_scale_mw_get(ph);
-		em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb,
-					    opp_shared_cpus, power_scale_mw);
-	}
-
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		ret = -ENOMEM;
-		goto out_free_opp;
+		priv->nr_opp = nr_opp;
 	}
 
 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
 	if (ret) {
 		dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
-		goto out_free_priv;
+		goto out_free_opp;
 	}
 
 	priv->cpu_dev = cpu_dev;
@@ -223,17 +220,16 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	policy->fast_switch_possible =
 		perf_ops->fast_switch_possible(ph, cpu_dev);
 
-	free_cpumask_var(opp_shared_cpus);
 	return 0;
 
-out_free_priv:
-	kfree(priv);
-
 out_free_opp:
 	dev_pm_opp_remove_all_dynamic(cpu_dev);
 
 out_free_cpumask:
-	free_cpumask_var(opp_shared_cpus);
+	free_cpumask_var(priv->opp_shared_cpus);
+
+out_free_priv:
+	kfree(priv);
 
 	return ret;
 }
@@ -244,11 +240,23 @@ static int scmi_cpufreq_exit(struct cpufreq_policy *policy)
 
 	dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
 	dev_pm_opp_remove_all_dynamic(priv->cpu_dev);
+	free_cpumask_var(priv->opp_shared_cpus);
 	kfree(priv);
 
 	return 0;
 }
 
+static void scmi_cpufreq_register_em(struct cpufreq_policy *policy)
+{
+	struct em_data_callback em_cb = EM_DATA_CB(scmi_get_cpu_power);
+	bool power_scale_mw = perf_ops->power_scale_mw_get(ph);
+	struct scmi_data *priv = policy->driver_data;
+
+	em_dev_register_perf_domain(get_cpu_device(policy->cpu), priv->nr_opp,
+				    &em_cb, priv->opp_shared_cpus,
+				    power_scale_mw);
+}
+
 static struct cpufreq_driver scmi_cpufreq_driver = {
 	.name	= "scmi",
 	.flags	= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
@@ -261,6 +269,7 @@ static struct cpufreq_driver scmi_cpufreq_driver = {
 	.get	= scmi_cpufreq_get_rate,
 	.init	= scmi_cpufreq_init,
 	.exit	= scmi_cpufreq_exit,
+	.register_em	= scmi_cpufreq_register_em,
 };
 
 static int scmi_cpufreq_probe(struct scmi_device *sdev)
-- 
2.31.1.272.g89b43f80a514



From kishon at ti.com  Wed Aug 11 05:07:19 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 17:37:19 +0530
Subject: [PATCH v2 2/3] PCI: j721e: Add PCI legacy interrupt support for
 J721E
In-Reply-To: <875ywdbhta.wl-maz@kernel.org>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-3-kishon@ti.com> <87h7g5w8d8.wl-maz@kernel.org>
 <c20be7ae-e4a7-c3ba-f1c9-e4ff2aae0a66@ti.com> <87o8a7arew.wl-maz@kernel.org>
 <7646c75e-29de-1edc-225c-57feeaa80118@ti.com> <875ywdbhta.wl-maz@kernel.org>
Message-ID: <9638f916-d0da-9c0e-6f01-b90c986decfd@ti.com>

Hi Marc,

On 10/08/21 6:03 pm, Marc Zyngier wrote:
> On Mon, 09 Aug 2021 15:58:38 +0100,
> Kishon Vijay Abraham I <kishon at ti.com> wrote:
>>
>> Hi Marc,
>>
>> On 09/08/21 3:09 pm, Marc Zyngier wrote:
>>> On Mon, 09 Aug 2021 05:50:10 +0100,
>>> Kishon Vijay Abraham I <kishon at ti.com> wrote:
>>>>
>>>> Hi Marc,
>>>>
>>>> On 04/08/21 8:43 pm, Marc Zyngier wrote:
>>>>> On Wed, 04 Aug 2021 14:29:11 +0100,
>>>>> Kishon Vijay Abraham I <kishon at ti.com> wrote:
>>>>>>
>>>>>> Add PCI legacy interrupt support for J721E. J721E has a single HW
>>>>>> interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
>>>>>> The HW interrupt line connected to GIC is a pulse interrupt whereas
>>>>>> the legacy interrupts by definition is level interrupt. In order to
>>>>>> provide level interrupt functionality to edge interrupt line, PCIe
>>>>>> in J721E has provided IRQ_EOI register.
>>>>>>
>>>>>> However due to Errata ID #i2094 ([1]), EOI feature is not enabled in HW
>>>>>> and only a single pulse interrupt will be generated for every
>>>>>> ASSERT_INTx/DEASSERT_INTx.
>>>>>
>>>>> So my earlier remark stands. If you get a single edge, how do you
>>>>> handle a level that is still high after having handled the interrupt
>>>>> on hardware that has this bug?
>>>>
>>>> Right, this hardware (J721E) has a bug but was fixed in J7200 (Patch 3/3
>>>> handles that).
>>>
>>> But how do you make it work with J721E? Is it even worth supporting if
>>> (as I expect) it is unreliable?
>>
>> I've seen at-least the NVMe devices triggers the interrupts again and
>> the data transfer completes. But I agree, this is unreliable.
> 
> Then I don't think you should add INTx support for this system. It is
> bound to be a support burden, and will reflect badly on the whole
> platform. Focusing on J7200 is probably the best thing to do.

Okay, will drop this patch from the series and have INTx support only
for J7200.

Thanks
Kishon


From tglx at linutronix.de  Wed Aug 11 05:08:38 2021
From: tglx at linutronix.de (Thomas Gleixner)
Date: Wed, 11 Aug 2021 14:08:38 +0200
Subject: [PATCH 1/1] genirq/cpuhotplug: Bump debugging information print
 down to KERN_DEBUG
In-Reply-To: <YROC5avuGQyBIpmD@google.com>
References: <20210617073136.315723-1-lee.jones@linaro.org>
 <8735rhs7n6.ffs@tglx> <YROC5avuGQyBIpmD@google.com>
Message-ID: <87fsvgp4jd.ffs@tglx>

On Wed, Aug 11 2021 at 08:57, Lee Jones wrote:
> On Tue, 10 Aug 2021, Thomas Gleixner wrote:
>> > @@ -42,7 +42,7 @@ static inline bool irq_needs_fixup(struct irq_data *d)
>> >  		 * If this happens then there was a missed IRQ fixup at some
>> >  		 * point. Warn about it and enforce fixup.
>> >  		 */
>> > -		pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",
>> 
>> This one is clearly a warning as this should not happen. See the
>> comments around that.
>> 
>> > +		pr_debug("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",
>> >  			cpumask_pr_args(m), d->irq, cpu);
>> >  		return true;
>> >  	}
>> > @@ -166,7 +166,7 @@ void irq_migrate_all_off_this_cpu(void)
>> >  		raw_spin_unlock(&desc->lock);
>> >  
>> >  		if (affinity_broken) {
>> > -			pr_warn_ratelimited("IRQ %u: no longer affine to CPU%u\n",
>> > +			pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n",
>> >  					    irq, smp_processor_id());
>> 
>> Maybe, but distro people might have opinions on that.
>
> The trouble is, even if these are real warnings, they have an affect
> on performance on real products.  To the point where so much logging
> builds up during pre-release testing, that it sets off the watchdog(s)
> on some high profile consumer devices.

I'm fine with making the second one debug, but the first one really
should not trigger at all.

Thanks,

        tglx


From tangbin at cmss.chinamobile.com  Wed Aug 11 05:09:00 2021
From: tangbin at cmss.chinamobile.com (tangbin)
Date: Wed, 11 Aug 2021 20:09:00 +0800
Subject: [PATCH] ASoC: stm32: spdifrx: Delete unnecessary check in
 theprobe function
In-Reply-To: <20210811115846.GC4167@sirena.org.uk>
References: <20210811115523.17232-1-tangbin@cmss.chinamobile.com>
 <20210811115846.GC4167@sirena.org.uk>
Message-ID: <7ddb13ee-2ca6-bf8d-2a83-9896d29176c5@cmss.chinamobile.com>

Hi Mark:

On 2021/8/11 19:58, Mark Brown wrote:
> On Wed, Aug 11, 2021 at 07:55:23PM +0800, Tang Bin wrote:
>> The function stm32_spdifrx_parse_of() is only called by the function
>> stm32_spdifrx_probe(), and the probe function is only called with
>> an openfirmware platform device. Therefore there is no need to check
>> the device_node in probe function.
> What is the benefit of not doing the check?  It seems like reasonable
> defensive programming.

I think it's unnecessary, because we all know than the probe function is 
only trigger if

the device and the driver matches, and the trigger mode is just Device 
Tree. So the device_node

must be exist in the probe function if it works. That's the reason why I 
think it's redundant.

Thanks

Tang Bin





From chun-jie.chen at mediatek.com  Wed Aug 11 05:12:38 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 11 Aug 2021 20:12:38 +0800
Subject: [v6 2/2] arm64: dts: mediatek: Correct UART0 bus clock of MT8192
In-Reply-To: <913973ef-e3ee-5015-a010-b436fe620e1c@gmail.com>
References: <20210727023205.20319-1-chun-jie.chen@mediatek.com>
 <20210727023205.20319-3-chun-jie.chen@mediatek.com>
 <CAATdQgC-X6pijkgTBsWJJKp__J6N=7JNKHQJmOMvTAjivwPM5w@mail.gmail.com>
 <a48525422d4c953a2dac2a907895c20b9fd6d232.camel@mediatek.com>
 <913973ef-e3ee-5015-a010-b436fe620e1c@gmail.com>
Message-ID: <ba4174599b40b5cc2f6397bb9b8772f75b945365.camel@mediatek.com>

On Thu, 2021-08-05 at 17:44 +0200, Matthias Brugger wrote:
> 
> On 30/07/2021 04:43, Chun-Jie Chen wrote:
> > On Wed, 2021-07-28 at 14:14 +0800, Ikjoon Jang wrote:
> > > Hi,
> > > 
> > > On Tue, Jul 27, 2021 at 10:43 AM Chun-Jie Chen
> > > <chun-jie.chen at mediatek.com> wrote:
> > > > 
> > > > infra_uart0 clock is the real one what uart0 uses as bus clock.
> > > > 
> > > > Signed-off-by: Weiyi Lu <weiyi.lu at mediatek.com>
> > > > Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > > > ---
> > > >  arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> > > > b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> > > > index c7c7d4e017ae..9810f1d441da 100644
> > > > --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> > > > +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> > > > @@ -327,7 +327,7 @@
> > > >                                      "mediatek,mt6577-uart";
> > > >                         reg = <0 0x11002000 0 0x1000>;
> > > >                         interrupts = <GIC_SPI 109
> > > > IRQ_TYPE_LEVEL_HIGH 0>;
> > > > -                       clocks = <&clk26m>, <&clk26m>;
> > > > +                       clocks = <&clk26m>, <&infracfg
> > > > CLK_INFRA_UART0>;
> > > >                         clock-names = "baud", "bus";
> > > >                         status = "disabled";
> > > >                 };
> > > 
> > > There're many other nodes still having only clk26m. Will you
> > > update
> > > them too?
> > > 
> > 
> > Others will be updated by IP owner.
> > 
> 
> As it seems we will have some time before this can be merged, could
> you help
> work with the other IP owners to get one big patch that updates all
> clocks?
> 
> Thanks a lot,
> Matthias
> 

Ok, I will update all clock setting (uart/nor_flash/i2c/spi) in
mt8192.dtsi at the latest kernel version. Did you suggest to merge all
to one patch or separate to different patches but put in same
series?

Best Regards,
Chun-Jie

> > Best Regards,
> > Chun-Jie
> > 
> > > > --
> > > > 2.18.0
> > > > _______________________________________________
> > > > Linux-mediatek mailing list
> > > > Linux-mediatek at lists.infradead.org
> > > > 
> > 
> > 
https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!1bIz6X2EiFbigCImzQmbqtezIFfl1LRBuPOYTqBdl5wfx8b-zp0zQP68R7RhaIcAAXXF$
> > > >  

From zajec5 at gmail.com  Wed Aug 11 05:15:31 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Wed, 11 Aug 2021 14:15:31 +0200
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
Message-ID: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>

Hi,

I just tried upgrading from the old good LTS kernel 5.10 and I
discovered that my bcm4908 boards don't boot anymore with the 5.14-rc5.


The problem is kernel doesn't seem to start booting at all. I see CFE
bootloader messages:

Starting program at 0x0000000000080000
/memory = 0x40000000

and then nothing. Normally the first kernel line should follow like a:
Linux version 5.11.0-rc4 (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #30 SMP Wed Aug 11 14:01:00 CEST 2021


I have zero knowledge of low level arm64 or assembler stuff. I also
don't own any bcm4908 development board or bcm4908 datasheets.

All I could do to help debugging this regression was bisecting. The
first bad commit (I verified it after bisecting process) is:

commit 0c93df9622d4d921bcd0dc83f71fed9e98f5119f
Author: Marc Zyngier <maz at kernel.org>
Date:   Mon Feb 8 09:57:14 2021 +0000

     arm64: Initialise as nVHE before switching to VHE

     As we are aiming to be able to control whether we enable VHE or
     not, let's always drop down to EL1 first, and only then upgrade
     to VHE if at all possible.

     This means that if the kernel is booted at EL2, we always start
     with a nVHE init, drop to EL1 to initialise the the kernel, and
     only then upgrade the kernel EL to EL2 if possible (the process
     is obviously shortened for secondary CPUs).

     The resume path is handled similarly to a secondary CPU boot.

     Signed-off-by: Marc Zyngier <maz at kernel.org>
     Acked-by: David Brazdil <dbrazdil at google.com>
     Acked-by: Catalin Marinas <catalin.marinas at arm.com>
     Link: https://lore.kernel.org/r/20210208095732.3267263-6-maz at kernel.org
     [will: Avoid calling switch_to_vhe twice on kaslr path]
     Signed-off-by: Will Deacon <will at kernel.org>


Could you look at this issue, please? I'm happy to test any patches or
provide any extra info I can obtain using kernel 5.11.


My defconfig for bcm4908 is:

CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="${BR_BINARIES_DIR}/rootfs.cpio"
CONFIG_ARCH_BCM4908=y
CONFIG_NR_CPUS=4
CONFIG_CMDLINE="earlycon=bcm63xx_uart,0xff800640"
CONFIG_CMDLINE_FORCE=y
CONFIG_PCI=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_BRCMSTB=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_SERIAL_BCM63XX=y
CONFIG_SERIAL_BCM63XX_CONSOLE=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_SLAVE=y
CONFIG_SPI=y
CONFIG_PINCTRL=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_THERMAL=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_DMADEVICES=y
CONFIG_RESET_CONTROLLER=y


From broonie at kernel.org  Wed Aug 11 05:19:55 2021
From: broonie at kernel.org (Mark Brown)
Date: Wed, 11 Aug 2021 13:19:55 +0100
Subject: [PATCH] ASoC: stm32: spdifrx: Delete unnecessary check in
 theprobe function
In-Reply-To: <7ddb13ee-2ca6-bf8d-2a83-9896d29176c5@cmss.chinamobile.com>
References: <20210811115523.17232-1-tangbin@cmss.chinamobile.com>
 <20210811115846.GC4167@sirena.org.uk>
 <7ddb13ee-2ca6-bf8d-2a83-9896d29176c5@cmss.chinamobile.com>
Message-ID: <20210811121955.GD4167@sirena.org.uk>

On Wed, Aug 11, 2021 at 08:09:00PM +0800, tangbin wrote:
> On 2021/8/11 19:58, Mark Brown wrote:
> > On Wed, Aug 11, 2021 at 07:55:23PM +0800, Tang Bin wrote:

> > > The function stm32_spdifrx_parse_of() is only called by the function
> > > stm32_spdifrx_probe(), and the probe function is only called with
> > > an openfirmware platform device. Therefore there is no need to check
> > > the device_node in probe function.

> > What is the benefit of not doing the check?  It seems like reasonable
> > defensive programming.

> I think it's unnecessary, because we all know than the probe function is
> only trigger if

> the device and the driver matches, and the trigger mode is just Device Tree.
> So the device_node

> must be exist in the probe function if it works. That's the reason why I
> think it's redundant.

I see why it is redundant, I don't see what problem this redudnancy
causes.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210811/e3187e5d/attachment.sig>

From robin.murphy at arm.com  Wed Aug 11 05:21:16 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:16 +0100
Subject: [PATCH v4 02/24] iommu/amd: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <648e74e7422caa6a7db7fb0c36813c7bd2007af8.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/amd/iommu.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 52fe2326042a..0fd98d35d73b 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1918,16 +1918,7 @@ static struct iommu_domain *amd_iommu_domain_alloc(unsigned type)
 	domain->domain.geometry.aperture_end   = ~0ULL;
 	domain->domain.geometry.force_aperture = true;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&domain->domain) == -ENOMEM)
-		goto free_domain;
-
 	return &domain->domain;
-
-free_domain:
-	protection_domain_free(domain);
-
-	return NULL;
 }
 
 static void amd_iommu_domain_free(struct iommu_domain *dom)
@@ -1944,9 +1935,6 @@ static void amd_iommu_domain_free(struct iommu_domain *dom)
 	if (!dom)
 		return;
 
-	if (dom->type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&domain->domain);
-
 	if (domain->flags & PD_IOMMUV2_MASK)
 		free_gcr3_table(domain);
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:14 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:14 +0100
Subject: [PATCH v4 00/24] iommu: Refactor DMA domain strictness
Message-ID: <cover.1628682048.git.robin.murphy@arm.com>

v1: https://lore.kernel.org/linux-iommu/cover.1626888444.git.robin.murphy at arm.com/
v2: https://lore.kernel.org/linux-iommu/cover.1627468308.git.robin.murphy at arm.com/
v3: https://lore.kernel.org/linux-iommu/cover.1628094600.git.robin.murphy at arm.com/

Hi all,

I'm hoping this is good to go now. Changes from v3 are minimal, just
rolling back patch #2 to the non-broken version, and tidying up the
final patch as documented there.

Cheers,
Robin.


CC: Marek Szyprowski <m.szyprowski at samsung.com>
CC: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
CC: Geert Uytterhoeven <geert+renesas at glider.be>
CC: Yong Wu <yong.wu at mediatek.com>
CC: Heiko Stuebner <heiko at sntech.de>
CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
CC: Maxime Ripard <mripard at kernel.org>
CC: Jean-Philippe Brucker <jean-philippe at linaro.org>


Robin Murphy (24):
  iommu: Pull IOVA cookie management into the core
  iommu/amd: Drop IOVA cookie management
  iommu/arm-smmu: Drop IOVA cookie management
  iommu/vt-d: Drop IOVA cookie management
  iommu/exynos: Drop IOVA cookie management
  iommu/ipmmu-vmsa: Drop IOVA cookie management
  iommu/mtk: Drop IOVA cookie management
  iommu/rockchip: Drop IOVA cookie management
  iommu/sprd: Drop IOVA cookie management
  iommu/sun50i: Drop IOVA cookie management
  iommu/virtio: Drop IOVA cookie management
  iommu/dma: Unexport IOVA cookie management
  iommu/dma: Remove redundant "!dev" checks
  iommu: Indicate queued flushes via gather data
  iommu/io-pgtable: Remove non-strict quirk
  iommu: Introduce explicit type for non-strict DMA domains
  iommu/amd: Prepare for multiple DMA domain types
  iommu/arm-smmu: Prepare for multiple DMA domain types
  iommu/vt-d: Prepare for multiple DMA domain types
  iommu: Express DMA strictness via the domain type
  iommu: Expose DMA domain strictness via sysfs
  iommu: Only log strictness for DMA domains
  iommu: Merge strictness and domain type configs
  iommu: Allow enabling non-strict mode dynamically

 .../ABI/testing/sysfs-kernel-iommu_groups     |  6 +-
 .../admin-guide/kernel-parameters.txt         |  8 +-
 drivers/iommu/Kconfig                         | 80 +++++++++----------
 drivers/iommu/amd/iommu.c                     | 21 +----
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 11 +--
 drivers/iommu/arm/arm-smmu/arm-smmu.c         | 19 ++---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c       |  9 ---
 drivers/iommu/dma-iommu.c                     | 58 ++++++++------
 drivers/iommu/exynos-iommu.c                  | 19 +----
 drivers/iommu/intel/iommu.c                   | 23 ++----
 drivers/iommu/io-pgtable-arm-v7s.c            | 12 +--
 drivers/iommu/io-pgtable-arm.c                | 12 +--
 drivers/iommu/iommu.c                         | 56 ++++++++-----
 drivers/iommu/iova.c                          | 14 +++-
 drivers/iommu/ipmmu-vmsa.c                    | 28 +------
 drivers/iommu/mtk_iommu.c                     |  7 --
 drivers/iommu/mtk_iommu_v1.c                  |  1 -
 drivers/iommu/rockchip-iommu.c                | 12 +--
 drivers/iommu/sprd-iommu.c                    |  7 --
 drivers/iommu/sun50i-iommu.c                  | 13 +--
 drivers/iommu/virtio-iommu.c                  |  8 --
 include/linux/dma-iommu.h                     |  6 ++
 include/linux/io-pgtable.h                    |  5 --
 include/linux/iommu.h                         | 23 +++++-
 24 files changed, 184 insertions(+), 274 deletions(-)

-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:15 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:15 +0100
Subject: [PATCH v4 01/24] iommu: Pull IOVA cookie management into the core
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <46a2c0e7419c7d1d931762dc7b6a69fa082d199a.1628682048.git.robin.murphy@arm.com>

Now that everyone has converged on iommu-dma for IOMMU_DOMAIN_DMA
support, we can abandon the notion of drivers being responsible for the
cookie type, and consolidate all the management into the core code.

CC: Yong Wu <yong.wu at mediatek.com>
CC: Chunyan Zhang <chunyan.zhang at unisoc.com>
CC: Maxime Ripard <mripard at kernel.org>
Tested-by: Heiko Stuebner <heiko at sntech.de>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Use a simpler temporary check instead of trying to be clever with
    the error code
---
 drivers/iommu/iommu.c | 7 +++++++
 include/linux/iommu.h | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index f2cda9950bd5..b65fcc66ffa4 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -7,6 +7,7 @@
 #define pr_fmt(fmt)    "iommu: " fmt
 
 #include <linux/device.h>
+#include <linux/dma-iommu.h>
 #include <linux/kernel.h>
 #include <linux/bits.h>
 #include <linux/bug.h>
@@ -1946,6 +1947,11 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
 
+	/* Temporarily avoid -EEXIST while drivers still get their own cookies */
+	if (type == IOMMU_DOMAIN_DMA && !domain->iova_cookie && iommu_get_dma_cookie(domain)) {
+		iommu_domain_free(domain);
+		domain = NULL;
+	}
 	return domain;
 }
 
@@ -1957,6 +1963,7 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc);
 
 void iommu_domain_free(struct iommu_domain *domain)
 {
+	iommu_put_dma_cookie(domain);
 	domain->ops->domain_free(domain);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_free);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 4997c78e2670..141779d76035 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -40,6 +40,7 @@ struct iommu_domain;
 struct notifier_block;
 struct iommu_sva;
 struct iommu_fault_event;
+struct iommu_dma_cookie;
 
 /* iommu fault flags */
 #define IOMMU_FAULT_READ	0x0
@@ -86,7 +87,7 @@ struct iommu_domain {
 	iommu_fault_handler_t handler;
 	void *handler_token;
 	struct iommu_domain_geometry geometry;
-	void *iova_cookie;
+	struct iommu_dma_cookie *iova_cookie;
 };
 
 enum iommu_cap {
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:17 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:17 +0100
Subject: [PATCH v4 03/24] iommu/arm-smmu: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <7ae3680dad9735cc69c3618866666896bd11e031.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  7 -------
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 15 ++++-----------
 drivers/iommu/arm/arm-smmu/qcom_iommu.c     |  9 ---------
 3 files changed, 4 insertions(+), 27 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 6346f21726f4..4c648da447bf 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1984,12 +1984,6 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 	if (!smmu_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&smmu_domain->domain)) {
-		kfree(smmu_domain);
-		return NULL;
-	}
-
 	mutex_init(&smmu_domain->init_mutex);
 	INIT_LIST_HEAD(&smmu_domain->devices);
 	spin_lock_init(&smmu_domain->devices_lock);
@@ -2021,7 +2015,6 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-	iommu_put_dma_cookie(domain);
 	free_io_pgtable_ops(smmu_domain->pgtbl_ops);
 
 	/* Free the CD and ASID, if we allocated them */
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index ac21170fa208..970d9e4dcd69 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -868,10 +868,10 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 {
 	struct arm_smmu_domain *smmu_domain;
 
-	if (type != IOMMU_DOMAIN_UNMANAGED &&
-	    type != IOMMU_DOMAIN_DMA &&
-	    type != IOMMU_DOMAIN_IDENTITY)
-		return NULL;
+	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_IDENTITY) {
+		if (using_legacy_binding || type != IOMMU_DOMAIN_DMA)
+			return NULL;
+	}
 	/*
 	 * Allocate the domain and initialise some of its data structures.
 	 * We can't really do anything meaningful until we've added a
@@ -881,12 +881,6 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 	if (!smmu_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA && (using_legacy_binding ||
-	    iommu_get_dma_cookie(&smmu_domain->domain))) {
-		kfree(smmu_domain);
-		return NULL;
-	}
-
 	mutex_init(&smmu_domain->init_mutex);
 	spin_lock_init(&smmu_domain->cb_lock);
 
@@ -901,7 +895,6 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 	 * Free the domain resources. We assume that all devices have
 	 * already been detached.
 	 */
-	iommu_put_dma_cookie(domain);
 	arm_smmu_destroy_domain_context(domain);
 	kfree(smmu_domain);
 }
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 021cf8f65ffc..b91874cb6cf3 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -10,7 +10,6 @@
 #include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
@@ -335,12 +334,6 @@ static struct iommu_domain *qcom_iommu_domain_alloc(unsigned type)
 	if (!qcom_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&qcom_domain->domain)) {
-		kfree(qcom_domain);
-		return NULL;
-	}
-
 	mutex_init(&qcom_domain->init_mutex);
 	spin_lock_init(&qcom_domain->pgtbl_lock);
 
@@ -351,8 +344,6 @@ static void qcom_iommu_domain_free(struct iommu_domain *domain)
 {
 	struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
 
-	iommu_put_dma_cookie(domain);
-
 	if (qcom_domain->iommu) {
 		/*
 		 * NOTE: unmap can be called after client device is powered
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:18 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:18 +0100
Subject: [PATCH v4 04/24] iommu/vt-d: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <e9dbe3b6108f8538e17e0c5f59f8feeb714f51a4.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/intel/iommu.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index c12cc955389a..7e168634c433 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1979,10 +1979,6 @@ static void domain_exit(struct dmar_domain *domain)
 	/* Remove associated devices and clear attached or cached domains */
 	domain_remove_dev_info(domain);
 
-	/* destroy iovas */
-	if (domain->domain.type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&domain->domain);
-
 	if (domain->pgd) {
 		struct page *freelist;
 
@@ -4544,10 +4540,6 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 			return NULL;
 		}
 
-		if (type == IOMMU_DOMAIN_DMA &&
-		    iommu_get_dma_cookie(&dmar_domain->domain))
-			return NULL;
-
 		domain = &dmar_domain->domain;
 		domain->geometry.aperture_start = 0;
 		domain->geometry.aperture_end   =
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:19 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:19 +0100
Subject: [PATCH v4 05/24] iommu/exynos: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <12d88cbf44e57faa4f0512760e7ed3a9cba05ca8.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Acked-by: Marek Szyprowski <m.szyprowski at samsung.com>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/exynos-iommu.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index d0fbf1d10e18..939ffa768986 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -21,7 +21,6 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
-#include <linux/dma-iommu.h>
 
 typedef u32 sysmmu_iova_t;
 typedef u32 sysmmu_pte_t;
@@ -735,20 +734,16 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
 	/* Check if correct PTE offsets are initialized */
 	BUG_ON(PG_ENT_SHIFT < 0 || !dma_dev);
 
+	if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED)
+		return NULL;
+
 	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 	if (!domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA) {
-		if (iommu_get_dma_cookie(&domain->domain) != 0)
-			goto err_pgtable;
-	} else if (type != IOMMU_DOMAIN_UNMANAGED) {
-		goto err_pgtable;
-	}
-
 	domain->pgtable = (sysmmu_pte_t *)__get_free_pages(GFP_KERNEL, 2);
 	if (!domain->pgtable)
-		goto err_dma_cookie;
+		goto err_pgtable;
 
 	domain->lv2entcnt = (short *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
 	if (!domain->lv2entcnt)
@@ -779,9 +774,6 @@ static struct iommu_domain *exynos_iommu_domain_alloc(unsigned type)
 	free_pages((unsigned long)domain->lv2entcnt, 1);
 err_counter:
 	free_pages((unsigned long)domain->pgtable, 2);
-err_dma_cookie:
-	if (type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&domain->domain);
 err_pgtable:
 	kfree(domain);
 	return NULL;
@@ -809,9 +801,6 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 
-	if (iommu_domain->type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(iommu_domain);
-
 	dma_unmap_single(dma_dev, virt_to_phys(domain->pgtable), LV1TABLE_SIZE,
 			 DMA_TO_DEVICE);
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:20 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:20 +0100
Subject: [PATCH v4 06/24] iommu/ipmmu-vmsa: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <dc5513293942d81f84edf61b354b236e5ac51dc2.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh at renesas.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/ipmmu-vmsa.c | 28 ++++------------------------
 1 file changed, 4 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 51ea6f00db2f..d38ff29a76e8 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -8,7 +8,6 @@
 
 #include <linux/bitmap.h>
 #include <linux/delay.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/export.h>
@@ -564,10 +563,13 @@ static irqreturn_t ipmmu_irq(int irq, void *dev)
  * IOMMU Operations
  */
 
-static struct iommu_domain *__ipmmu_domain_alloc(unsigned type)
+static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
 {
 	struct ipmmu_vmsa_domain *domain;
 
+	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+		return NULL;
+
 	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 	if (!domain)
 		return NULL;
@@ -577,27 +579,6 @@ static struct iommu_domain *__ipmmu_domain_alloc(unsigned type)
 	return &domain->io_domain;
 }
 
-static struct iommu_domain *ipmmu_domain_alloc(unsigned type)
-{
-	struct iommu_domain *io_domain = NULL;
-
-	switch (type) {
-	case IOMMU_DOMAIN_UNMANAGED:
-		io_domain = __ipmmu_domain_alloc(type);
-		break;
-
-	case IOMMU_DOMAIN_DMA:
-		io_domain = __ipmmu_domain_alloc(type);
-		if (io_domain && iommu_get_dma_cookie(io_domain)) {
-			kfree(io_domain);
-			io_domain = NULL;
-		}
-		break;
-	}
-
-	return io_domain;
-}
-
 static void ipmmu_domain_free(struct iommu_domain *io_domain)
 {
 	struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
@@ -606,7 +587,6 @@ static void ipmmu_domain_free(struct iommu_domain *io_domain)
 	 * Free the domain resources. We assume that all devices have already
 	 * been detached.
 	 */
-	iommu_put_dma_cookie(io_domain);
 	ipmmu_domain_destroy_context(domain);
 	free_io_pgtable_ops(domain->iop);
 	kfree(domain);
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:21 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:21 +0100
Subject: [PATCH v4 07/24] iommu/mtk: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <b856648e7ee2b1017e7c7c02e2ddd50eaf72cbf7.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

CC: Yong Wu <yong.wu at mediatek.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded includes
---
 drivers/iommu/mtk_iommu.c    | 7 -------
 drivers/iommu/mtk_iommu_v1.c | 1 -
 2 files changed, 8 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6f7c69688ce2..185694eb4456 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -9,7 +9,6 @@
 #include <linux/component.h>
 #include <linux/device.h>
 #include <linux/dma-direct.h>
-#include <linux/dma-iommu.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -441,17 +440,11 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
 	if (!dom)
 		return NULL;
 
-	if (iommu_get_dma_cookie(&dom->domain)) {
-		kfree(dom);
-		return NULL;
-	}
-
 	return &dom->domain;
 }
 
 static void mtk_iommu_domain_free(struct iommu_domain *domain)
 {
-	iommu_put_dma_cookie(domain);
 	kfree(to_mtk_domain(domain));
 }
 
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 778e66f5f1aa..be22fcf988ce 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -13,7 +13,6 @@
 #include <linux/component.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
-#include <linux/dma-iommu.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:22 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:22 +0100
Subject: [PATCH v4 08/24] iommu/rockchip: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <aff51e2da1e431987ae5fdafa62a6a7c4bd042dc.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Tested-by: Heiko Stuebner <heiko at sntech.de>
Acked-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/rockchip-iommu.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 9febfb7f3025..5cb260820eda 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -10,7 +10,6 @@
 #include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/device.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
@@ -1074,10 +1073,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 	if (!rk_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&rk_domain->domain))
-		goto err_free_domain;
-
 	/*
 	 * rk32xx iommus use a 2 level pagetable.
 	 * Each level1 (dt) and level2 (pt) table has 1024 4-byte entries.
@@ -1085,7 +1080,7 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 	 */
 	rk_domain->dt = (u32 *)get_zeroed_page(GFP_KERNEL | GFP_DMA32);
 	if (!rk_domain->dt)
-		goto err_put_cookie;
+		goto err_free_domain;
 
 	rk_domain->dt_dma = dma_map_single(dma_dev, rk_domain->dt,
 					   SPAGE_SIZE, DMA_TO_DEVICE);
@@ -1106,9 +1101,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type)
 
 err_free_dt:
 	free_page((unsigned long)rk_domain->dt);
-err_put_cookie:
-	if (type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&rk_domain->domain);
 err_free_domain:
 	kfree(rk_domain);
 
@@ -1137,8 +1129,6 @@ static void rk_iommu_domain_free(struct iommu_domain *domain)
 			 SPAGE_SIZE, DMA_TO_DEVICE);
 	free_page((unsigned long)rk_domain->dt);
 
-	if (domain->type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&rk_domain->domain);
 	kfree(rk_domain);
 }
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:23 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:23 +0100
Subject: [PATCH v4 09/24] iommu/sprd: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <4e7fc6e523cb4b63fb13f5be10041eb24c0dcb1e.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Acked-by: Chunyan Zhang <zhang.lyra at gmail.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/sprd-iommu.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c
index 73dfd9946312..27ac818b0354 100644
--- a/drivers/iommu/sprd-iommu.c
+++ b/drivers/iommu/sprd-iommu.c
@@ -8,7 +8,6 @@
 
 #include <linux/clk.h>
 #include <linux/device.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/iommu.h>
@@ -144,11 +143,6 @@ static struct iommu_domain *sprd_iommu_domain_alloc(unsigned int domain_type)
 	if (!dom)
 		return NULL;
 
-	if (iommu_get_dma_cookie(&dom->domain)) {
-		kfree(dom);
-		return NULL;
-	}
-
 	spin_lock_init(&dom->pgtlock);
 
 	dom->domain.geometry.aperture_start = 0;
@@ -161,7 +155,6 @@ static void sprd_iommu_domain_free(struct iommu_domain *domain)
 {
 	struct sprd_iommu_domain *dom = to_sprd_domain(domain);
 
-	iommu_put_dma_cookie(domain);
 	kfree(dom);
 }
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:24 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:24 +0100
Subject: [PATCH v4 10/24] iommu/sun50i: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <147edb0ba59be563df19cec3e63e621aa65b7b68.1628682048.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

CC: Maxime Ripard <mripard at kernel.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Also remove unneeded include
---
 drivers/iommu/sun50i-iommu.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index 181bb1c3437c..92997021e188 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -7,7 +7,6 @@
 #include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/dma-direction.h>
-#include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/errno.h>
@@ -610,14 +609,10 @@ static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
 	if (!sun50i_domain)
 		return NULL;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&sun50i_domain->domain))
-		goto err_free_domain;
-
 	sun50i_domain->dt = (u32 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
 						    get_order(DT_SIZE));
 	if (!sun50i_domain->dt)
-		goto err_put_cookie;
+		goto err_free_domain;
 
 	refcount_set(&sun50i_domain->refcnt, 1);
 
@@ -627,10 +622,6 @@ static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
 
 	return &sun50i_domain->domain;
 
-err_put_cookie:
-	if (type == IOMMU_DOMAIN_DMA)
-		iommu_put_dma_cookie(&sun50i_domain->domain);
-
 err_free_domain:
 	kfree(sun50i_domain);
 
@@ -644,8 +635,6 @@ static void sun50i_iommu_domain_free(struct iommu_domain *domain)
 	free_pages((unsigned long)sun50i_domain->dt, get_order(DT_SIZE));
 	sun50i_domain->dt = NULL;
 
-	iommu_put_dma_cookie(domain);
-
 	kfree(sun50i_domain);
 }
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:25 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:25 +0100
Subject: [PATCH v4 11/24] iommu/virtio: Drop IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <f05cd2d0a0f414de3180e2536c7656faf1e52418.1628682049.git.robin.murphy@arm.com>

The core code bakes its own cookies now.

Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/virtio-iommu.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 6abdcab7273b..80930ce04a16 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -598,12 +598,6 @@ static struct iommu_domain *viommu_domain_alloc(unsigned type)
 	spin_lock_init(&vdomain->mappings_lock);
 	vdomain->mappings = RB_ROOT_CACHED;
 
-	if (type == IOMMU_DOMAIN_DMA &&
-	    iommu_get_dma_cookie(&vdomain->domain)) {
-		kfree(vdomain);
-		return NULL;
-	}
-
 	return &vdomain->domain;
 }
 
@@ -643,8 +637,6 @@ static void viommu_domain_free(struct iommu_domain *domain)
 {
 	struct viommu_domain *vdomain = to_viommu_domain(domain);
 
-	iommu_put_dma_cookie(domain);
-
 	/* Free all remaining mappings (size 2^64) */
 	viommu_del_mappings(vdomain, 0, 0);
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:26 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:26 +0100
Subject: [PATCH v4 12/24] iommu/dma: Unexport IOVA cookie management
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <c7bb7e336be13933ed7e44bad97dd885eec88ace.1628682049.git.robin.murphy@arm.com>

IOVA cookies are now got and put by core code, so we no longer need to
export these to modular drivers. The export for getting MSI cookies
stays, since VFIO can still be a module, but it was already relying on
someone else putting them, so that aspect is unaffected.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/dma-iommu.c | 7 -------
 drivers/iommu/iommu.c     | 3 +--
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 98ba927aee1a..10067fbc4309 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -98,9 +98,6 @@ static struct iommu_dma_cookie *cookie_alloc(enum iommu_dma_cookie_type type)
 /**
  * iommu_get_dma_cookie - Acquire DMA-API resources for a domain
  * @domain: IOMMU domain to prepare for DMA-API usage
- *
- * IOMMU drivers should normally call this from their domain_alloc
- * callback when domain->type == IOMMU_DOMAIN_DMA.
  */
 int iommu_get_dma_cookie(struct iommu_domain *domain)
 {
@@ -113,7 +110,6 @@ int iommu_get_dma_cookie(struct iommu_domain *domain)
 
 	return 0;
 }
-EXPORT_SYMBOL(iommu_get_dma_cookie);
 
 /**
  * iommu_get_msi_cookie - Acquire just MSI remapping resources
@@ -151,8 +147,6 @@ EXPORT_SYMBOL(iommu_get_msi_cookie);
  * iommu_put_dma_cookie - Release a domain's DMA mapping resources
  * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie() or
  *          iommu_get_msi_cookie()
- *
- * IOMMU drivers should normally call this from their domain_free callback.
  */
 void iommu_put_dma_cookie(struct iommu_domain *domain)
 {
@@ -172,7 +166,6 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
 	kfree(cookie);
 	domain->iova_cookie = NULL;
 }
-EXPORT_SYMBOL(iommu_put_dma_cookie);
 
 /**
  * iommu_dma_get_resv_regions - Reserved region driver helper
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index b65fcc66ffa4..fa8109369f74 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1947,8 +1947,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
 
-	/* Temporarily avoid -EEXIST while drivers still get their own cookies */
-	if (type == IOMMU_DOMAIN_DMA && !domain->iova_cookie && iommu_get_dma_cookie(domain)) {
+	if (type == IOMMU_DOMAIN_DMA && iommu_get_dma_cookie(domain)) {
 		iommu_domain_free(domain);
 		domain = NULL;
 	}
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:27 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:27 +0100
Subject: [PATCH v4 13/24] iommu/dma: Remove redundant "!dev" checks
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <06024523c080364390016550065e3cfe8031367e.1628682049.git.robin.murphy@arm.com>

iommu_dma_init_domain() is now only called from iommu_setup_dma_ops(),
which has already assumed dev to be non-NULL.

Reviewed-by: John Garry <john.garry at huawei.com>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/dma-iommu.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 10067fbc4309..e28396cea6eb 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -363,7 +363,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 
 	init_iova_domain(iovad, 1UL << order, base_pfn);
 
-	if (!cookie->fq_domain && (!dev || !dev_is_untrusted(dev)) &&
+	if (!cookie->fq_domain && !dev_is_untrusted(dev) &&
 	    domain->ops->flush_iotlb_all && !iommu_get_dma_strict(domain)) {
 		if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
 					  iommu_dma_entry_dtor))
@@ -372,9 +372,6 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 			cookie->fq_domain = domain;
 	}
 
-	if (!dev)
-		return 0;
-
 	return iova_reserve_iommu_regions(dev, domain);
 }
 
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:28 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:28 +0100
Subject: [PATCH v4 14/24] iommu: Indicate queued flushes via gather data
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <bf5f8e2ad84e48c712ccbf80fa8c610594c7595f.1628682049.git.robin.murphy@arm.com>

Since iommu_iotlb_gather exists to help drivers optimise flushing for a
given unmap request, it is also the logical place to indicate whether
the unmap is strict or not, and thus help them further optimise for
whether to expect a sync or a flush_all subsequently. As part of that,
it also seems fair to make the flush queue code take responsibility for
enforcing the really subtle ordering requirement it brings, so that we
don't need to worry about forgetting that if new drivers want to add
flush queue support, and can consolidate the existing versions.

While we're adding to the kerneldoc, also fill in some info for
@freelist which was overlooked previously.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: New
---
 drivers/iommu/dma-iommu.c | 1 +
 drivers/iommu/iova.c      | 7 +++++++
 include/linux/iommu.h     | 8 +++++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index e28396cea6eb..d63b30a7dc82 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -474,6 +474,7 @@ static void __iommu_dma_unmap(struct device *dev, dma_addr_t dma_addr,
 	dma_addr -= iova_off;
 	size = iova_align(iovad, size + iova_off);
 	iommu_iotlb_gather_init(&iotlb_gather);
+	iotlb_gather.queued = cookie->fq_domain;
 
 	unmapped = iommu_unmap_fast(domain, dma_addr, size, &iotlb_gather);
 	WARN_ON(unmapped != size);
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index b6cf5f16123b..2ad73fb2e94e 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -637,6 +637,13 @@ void queue_iova(struct iova_domain *iovad,
 	unsigned long flags;
 	unsigned idx;
 
+	/*
+	 * Order against the IOMMU driver's pagetable update from unmapping
+	 * @pte, to guarantee that iova_domain_flush() observes that if called
+	 * from a different CPU before we release the lock below.
+	 */
+	smp_wmb();
+
 	spin_lock_irqsave(&fq->lock, flags);
 
 	/*
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 141779d76035..f7679f6684b1 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -161,16 +161,22 @@ enum iommu_dev_features {
  * @start: IOVA representing the start of the range to be flushed
  * @end: IOVA representing the end of the range to be flushed (inclusive)
  * @pgsize: The interval at which to perform the flush
+ * @freelist: Removed pages to free after sync
+ * @queued: Indicates that the flush will be queued
  *
  * This structure is intended to be updated by multiple calls to the
  * ->unmap() function in struct iommu_ops before eventually being passed
- * into ->iotlb_sync().
+ * into ->iotlb_sync(). Drivers can add pages to @freelist to be freed after
+ * ->iotlb_sync() or ->iotlb_flush_all() have cleared all cached references to
+ * them. @queued is set to indicate when ->iotlb_flush_all() will be called
+ * later instead of ->iotlb_sync(), so drivers may optimise accordingly.
  */
 struct iommu_iotlb_gather {
 	unsigned long		start;
 	unsigned long		end;
 	size_t			pgsize;
 	struct page		*freelist;
+	bool			queued;
 };
 
 /**
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:29 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:29 +0100
Subject: [PATCH v4 15/24] iommu/io-pgtable: Remove non-strict quirk
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <155b5c621cd8936472e273a8b07a182f62c6c20d.1628682049.git.robin.murphy@arm.com>

IO_PGTABLE_QUIRK_NON_STRICT was never a very comfortable fit, since it's
not a quirk of the pagetable format itself. Now that we have a more
appropriate way to convey non-strict unmaps, though, this last of the
non-quirk quirks can also go, and with the flush queue code also now
enforcing its own ordering we can have a lovely cleanup all round.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: New
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  3 ---
 drivers/iommu/arm/arm-smmu/arm-smmu.c       |  3 ---
 drivers/iommu/io-pgtable-arm-v7s.c          | 12 ++----------
 drivers/iommu/io-pgtable-arm.c              | 12 ++----------
 include/linux/io-pgtable.h                  |  5 -----
 5 files changed, 4 insertions(+), 31 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 4c648da447bf..d9c93d8d193d 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2174,9 +2174,6 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain,
 		.iommu_dev	= smmu->dev,
 	};
 
-	if (!iommu_get_dma_strict(domain))
-		pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
-
 	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
 	if (!pgtbl_ops)
 		return -ENOMEM;
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 970d9e4dcd69..a325d4769c17 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -765,9 +765,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 		.iommu_dev	= smmu->dev,
 	};
 
-	if (!iommu_get_dma_strict(domain))
-		pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
-
 	if (smmu->impl && smmu->impl->init_context) {
 		ret = smmu->impl->init_context(smmu_domain, &pgtbl_cfg, dev);
 		if (ret)
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index 5db90d7ce2ec..e84478d39705 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -700,14 +700,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
 						ARM_V7S_BLOCK_SIZE(lvl + 1));
 				ptep = iopte_deref(pte[i], lvl, data);
 				__arm_v7s_free_table(ptep, lvl + 1, data);
-			} else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
-				/*
-				 * Order the PTE update against queueing the IOVA, to
-				 * guarantee that a flush callback from a different CPU
-				 * has observed it before the TLBIALL can be issued.
-				 */
-				smp_wmb();
-			} else {
+			} else if (!gather->queued) {
 				io_pgtable_tlb_add_page(iop, gather, iova, blk_size);
 			}
 			iova += blk_size;
@@ -791,8 +784,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
 
 	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
 			    IO_PGTABLE_QUIRK_NO_PERMS |
-			    IO_PGTABLE_QUIRK_ARM_MTK_EXT |
-			    IO_PGTABLE_QUIRK_NON_STRICT))
+			    IO_PGTABLE_QUIRK_ARM_MTK_EXT))
 		return NULL;
 
 	/* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 053df4048a29..48a5bd8f571d 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -638,14 +638,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 				io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
 							  ARM_LPAE_GRANULE(data));
 				__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
-			} else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
-				/*
-				 * Order the PTE update against queueing the IOVA, to
-				 * guarantee that a flush callback from a different CPU
-				 * has observed it before the TLBIALL can be issued.
-				 */
-				smp_wmb();
-			} else {
+			} else if (!gather->queued) {
 				io_pgtable_tlb_add_page(iop, gather, iova + i * size, size);
 			}
 
@@ -825,7 +818,6 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 	bool tg1;
 
 	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
-			    IO_PGTABLE_QUIRK_NON_STRICT |
 			    IO_PGTABLE_QUIRK_ARM_TTBR1 |
 			    IO_PGTABLE_QUIRK_ARM_OUTER_WBWA))
 		return NULL;
@@ -929,7 +921,7 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 	typeof(&cfg->arm_lpae_s2_cfg.vtcr) vtcr = &cfg->arm_lpae_s2_cfg.vtcr;
 
 	/* The NS quirk doesn't apply at stage 2 */
-	if (cfg->quirks & ~(IO_PGTABLE_QUIRK_NON_STRICT))
+	if (cfg->quirks)
 		return NULL;
 
 	data = arm_lpae_alloc_pgtable(cfg);
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index c43f3b899d2a..9ba6d9ea316e 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -73,10 +73,6 @@ struct io_pgtable_cfg {
 	 *	to support up to 35 bits PA where the bit32, bit33 and bit34 are
 	 *	encoded in the bit9, bit4 and bit5 of the PTE respectively.
 	 *
-	 * IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs
-	 *	on unmap, for DMA domains using the flush queue mechanism for
-	 *	delayed invalidation.
-	 *
 	 * IO_PGTABLE_QUIRK_ARM_TTBR1: (ARM LPAE format) Configure the table
 	 *	for use in the upper half of a split address space.
 	 *
@@ -86,7 +82,6 @@ struct io_pgtable_cfg {
 	#define IO_PGTABLE_QUIRK_ARM_NS		BIT(0)
 	#define IO_PGTABLE_QUIRK_NO_PERMS	BIT(1)
 	#define IO_PGTABLE_QUIRK_ARM_MTK_EXT	BIT(3)
-	#define IO_PGTABLE_QUIRK_NON_STRICT	BIT(4)
 	#define IO_PGTABLE_QUIRK_ARM_TTBR1	BIT(5)
 	#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA	BIT(6)
 	unsigned long			quirks;
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:30 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:30 +0100
Subject: [PATCH v4 16/24] iommu: Introduce explicit type for non-strict DMA
 domains
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <08cd2afaf6b63c58ad49acec3517c9b32c2bb946.1628682049.git.robin.murphy@arm.com>

Promote the difference between strict and non-strict DMA domains from an
internal detail to a distinct domain feature and type, to pave the road
for exposing it through the sysfs default domain interface.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/dma-iommu.c |  2 +-
 drivers/iommu/iommu.c     |  8 ++++++--
 include/linux/iommu.h     | 11 +++++++++++
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index d63b30a7dc82..207c8febdac9 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1312,7 +1312,7 @@ void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
 	 * The IOMMU core code allocates the default DMA domain, which the
 	 * underlying IOMMU driver needs to support via the dma-iommu layer.
 	 */
-	if (domain->type == IOMMU_DOMAIN_DMA) {
+	if (iommu_is_dma_domain(domain)) {
 		if (iommu_dma_init_domain(domain, dma_base, dma_limit, dev))
 			goto out_err;
 		dev->dma_ops = &iommu_dma_ops;
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index fa8109369f74..982545234cf3 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -115,6 +115,7 @@ static const char *iommu_domain_type_str(unsigned int t)
 	case IOMMU_DOMAIN_UNMANAGED:
 		return "Unmanaged";
 	case IOMMU_DOMAIN_DMA:
+	case IOMMU_DOMAIN_DMA_FQ:
 		return "Translated";
 	default:
 		return "Unknown";
@@ -552,6 +553,9 @@ static ssize_t iommu_group_show_type(struct iommu_group *group,
 		case IOMMU_DOMAIN_DMA:
 			type = "DMA\n";
 			break;
+		case IOMMU_DOMAIN_DMA_FQ:
+			type = "DMA-FQ\n";
+			break;
 		}
 	}
 	mutex_unlock(&group->mutex);
@@ -765,7 +769,7 @@ static int iommu_create_device_direct_mappings(struct iommu_group *group,
 	unsigned long pg_size;
 	int ret = 0;
 
-	if (!domain || domain->type != IOMMU_DOMAIN_DMA)
+	if (!domain || !iommu_is_dma_domain(domain))
 		return 0;
 
 	BUG_ON(!domain->pgsize_bitmap);
@@ -1947,7 +1951,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
 
-	if (type == IOMMU_DOMAIN_DMA && iommu_get_dma_cookie(domain)) {
+	if (iommu_is_dma_domain(domain) && iommu_get_dma_cookie(domain)) {
 		iommu_domain_free(domain);
 		domain = NULL;
 	}
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index f7679f6684b1..5629ae42951f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -61,6 +61,7 @@ struct iommu_domain_geometry {
 #define __IOMMU_DOMAIN_DMA_API	(1U << 1)  /* Domain for use in DMA-API
 					      implementation              */
 #define __IOMMU_DOMAIN_PT	(1U << 2)  /* Domain is identity mapped   */
+#define __IOMMU_DOMAIN_DMA_FQ	(1U << 3)  /* DMA-API uses flush queue    */
 
 /*
  * This are the possible domain-types
@@ -73,12 +74,17 @@ struct iommu_domain_geometry {
  *	IOMMU_DOMAIN_DMA	- Internally used for DMA-API implementations.
  *				  This flag allows IOMMU drivers to implement
  *				  certain optimizations for these domains
+ *	IOMMU_DOMAIN_DMA_FQ	- As above, but definitely using batched TLB
+ *				  invalidation.
  */
 #define IOMMU_DOMAIN_BLOCKED	(0U)
 #define IOMMU_DOMAIN_IDENTITY	(__IOMMU_DOMAIN_PT)
 #define IOMMU_DOMAIN_UNMANAGED	(__IOMMU_DOMAIN_PAGING)
 #define IOMMU_DOMAIN_DMA	(__IOMMU_DOMAIN_PAGING |	\
 				 __IOMMU_DOMAIN_DMA_API)
+#define IOMMU_DOMAIN_DMA_FQ	(__IOMMU_DOMAIN_PAGING |	\
+				 __IOMMU_DOMAIN_DMA_API |	\
+				 __IOMMU_DOMAIN_DMA_FQ)
 
 struct iommu_domain {
 	unsigned type;
@@ -90,6 +96,11 @@ struct iommu_domain {
 	struct iommu_dma_cookie *iova_cookie;
 };
 
+static inline bool iommu_is_dma_domain(struct iommu_domain *domain)
+{
+	return domain->type & __IOMMU_DOMAIN_DMA_API;
+}
+
 enum iommu_cap {
 	IOMMU_CAP_CACHE_COHERENCY,	/* IOMMU can enforce cache coherent DMA
 					   transactions */
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:31 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:31 +0100
Subject: [PATCH v4 17/24] iommu/amd: Prepare for multiple DMA domain types
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <6450b4f39a5a086d505297b4a53ff1e4a7a0fe7c.1628682049.git.robin.murphy@arm.com>

The DMA ops reset/setup can simply be unconditional, since
iommu-dma already knows only to touch DMA domains.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/amd/iommu.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 0fd98d35d73b..02f9b4fffe90 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -1707,14 +1707,9 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev)
 
 static void amd_iommu_probe_finalize(struct device *dev)
 {
-	struct iommu_domain *domain;
-
 	/* Domains are initialized for this device - have a look what we ended up with */
-	domain = iommu_get_domain_for_dev(dev);
-	if (domain->type == IOMMU_DOMAIN_DMA)
-		iommu_setup_dma_ops(dev, 0, U64_MAX);
-	else
-		set_dma_ops(dev, NULL);
+	set_dma_ops(dev, NULL);
+	iommu_setup_dma_ops(dev, 0, U64_MAX);
 }
 
 static void amd_iommu_release_device(struct device *dev)
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:32 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:32 +0100
Subject: [PATCH v4 18/24] iommu/arm-smmu: Prepare for multiple DMA domain types
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <8f217ef285bd0bb9456c27ef622d2efdbbca1ad8.1628682049.git.robin.murphy@arm.com>

In preparation for the strict vs. non-strict decision for DMA domains to
be expressed in the domain type, make sure we expose our flush queue
awareness by accepting the new domain type.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 1 +
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index d9c93d8d193d..883a99cb10c1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1972,6 +1972,7 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 
 	if (type != IOMMU_DOMAIN_UNMANAGED &&
 	    type != IOMMU_DOMAIN_DMA &&
+	    type != IOMMU_DOMAIN_DMA_FQ &&
 	    type != IOMMU_DOMAIN_IDENTITY)
 		return NULL;
 
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index a325d4769c17..1d013b1d7bb2 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -866,7 +866,8 @@ static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
 	struct arm_smmu_domain *smmu_domain;
 
 	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_IDENTITY) {
-		if (using_legacy_binding || type != IOMMU_DOMAIN_DMA)
+		if (using_legacy_binding ||
+		    (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_DMA_FQ))
 			return NULL;
 	}
 	/*
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:33 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:33 +0100
Subject: [PATCH v4 19/24] iommu/vt-d: Prepare for multiple DMA domain types
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <31a8ef868d593a2f3826a6a120edee81815375a7.1628682049.git.robin.murphy@arm.com>

In preparation for the strict vs. non-strict decision for DMA domains
to be expressed in the domain type, make sure we expose our flush queue
awareness by accepting the new domain type, and test the specific
feature flag where we want to identify DMA domains in general. The DMA
ops reset/setup can simply be made unconditional, since iommu-dma
already knows only to touch DMA domains.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/intel/iommu.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 7e168634c433..8fc46c9d6b96 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -582,7 +582,7 @@ struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
 	int iommu_id;
 
 	/* si_domain and vm domain should not get here. */
-	if (WARN_ON(domain->domain.type != IOMMU_DOMAIN_DMA))
+	if (WARN_ON(!iommu_is_dma_domain(&domain->domain)))
 		return NULL;
 
 	for_each_domain_iommu(iommu_id, domain)
@@ -1034,7 +1034,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
 			pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
 			if (domain_use_first_level(domain)) {
 				pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US;
-				if (domain->domain.type == IOMMU_DOMAIN_DMA)
+				if (iommu_is_dma_domain(&domain->domain))
 					pteval |= DMA_FL_PTE_ACCESS;
 			}
 			if (cmpxchg64(&pte->val, 0ULL, pteval))
@@ -2345,7 +2345,7 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
 	if (domain_use_first_level(domain)) {
 		attr |= DMA_FL_PTE_XD | DMA_FL_PTE_US;
 
-		if (domain->domain.type == IOMMU_DOMAIN_DMA) {
+		if (iommu_is_dma_domain(&domain->domain)) {
 			attr |= DMA_FL_PTE_ACCESS;
 			if (prot & DMA_PTE_WRITE)
 				attr |= DMA_FL_PTE_DIRTY;
@@ -4528,6 +4528,7 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 
 	switch (type) {
 	case IOMMU_DOMAIN_DMA:
+	case IOMMU_DOMAIN_DMA_FQ:
 	case IOMMU_DOMAIN_UNMANAGED:
 		dmar_domain = alloc_domain(0);
 		if (!dmar_domain) {
@@ -5197,12 +5198,8 @@ static void intel_iommu_release_device(struct device *dev)
 
 static void intel_iommu_probe_finalize(struct device *dev)
 {
-	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
-
-	if (domain && domain->type == IOMMU_DOMAIN_DMA)
-		iommu_setup_dma_ops(dev, 0, U64_MAX);
-	else
-		set_dma_ops(dev, NULL);
+	set_dma_ops(dev, NULL);
+	iommu_setup_dma_ops(dev, 0, U64_MAX);
 }
 
 static void intel_iommu_get_resv_regions(struct device *device,
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:34 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:34 +0100
Subject: [PATCH v4 20/24] iommu: Express DMA strictness via the domain type
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <47083d69155577f1367877b1594921948c366eb3.1628682049.git.robin.murphy@arm.com>

Eliminate the iommu_get_dma_strict() indirection and pipe the
information through the domain type from the beginning. Besides
the flow simplification this also has several nice side-effects:

 - Automatically implies strict mode for untrusted devices by
   virtue of their IOMMU_DOMAIN_DMA override.
 - Ensures that we only end up using flush queues for drivers
   which are aware of them and can actually benefit.
 - Allows us to handle flush queue init failure by falling back
   to strict mode instead of leaving it to possibly blow up later.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Remember to update iommu_def_domain_type accordingly from
    iommu_set_dma_strict() too
---
 drivers/iommu/dma-iommu.c | 10 ++++++----
 drivers/iommu/iommu.c     | 14 +++++---------
 include/linux/iommu.h     |  1 -
 3 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 207c8febdac9..01fa83229118 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -363,13 +363,15 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 
 	init_iova_domain(iovad, 1UL << order, base_pfn);
 
-	if (!cookie->fq_domain && !dev_is_untrusted(dev) &&
-	    domain->ops->flush_iotlb_all && !iommu_get_dma_strict(domain)) {
+	/* If the FQ fails we can simply fall back to strict mode */
+	if (domain->type == IOMMU_DOMAIN_DMA_FQ && !cookie->fq_domain) {
 		if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
-					  iommu_dma_entry_dtor))
+					  iommu_dma_entry_dtor)) {
 			pr_warn("iova flush queue initialization failed\n");
-		else
+			domain->type = IOMMU_DOMAIN_DMA;
+		} else {
 			cookie->fq_domain = domain;
+		}
 	}
 
 	return iova_reserve_iommu_regions(dev, domain);
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 982545234cf3..55ca5bf3cafc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -136,6 +136,9 @@ static int __init iommu_subsys_init(void)
 		}
 	}
 
+	if (!iommu_default_passthrough() && !iommu_dma_strict)
+		iommu_def_domain_type = IOMMU_DOMAIN_DMA_FQ;
+
 	pr_info("Default domain type: %s %s\n",
 		iommu_domain_type_str(iommu_def_domain_type),
 		(iommu_cmd_line & IOMMU_CMD_LINE_DMA_API) ?
@@ -355,17 +358,10 @@ early_param("iommu.strict", iommu_dma_setup);
 void iommu_set_dma_strict(void)
 {
 	iommu_dma_strict = true;
+	if (iommu_def_domain_type == IOMMU_DOMAIN_DMA_FQ)
+		iommu_def_domain_type = IOMMU_DOMAIN_DMA;
 }
 
-bool iommu_get_dma_strict(struct iommu_domain *domain)
-{
-	/* only allow lazy flushing for DMA domains */
-	if (domain->type == IOMMU_DOMAIN_DMA)
-		return iommu_dma_strict;
-	return true;
-}
-EXPORT_SYMBOL_GPL(iommu_get_dma_strict);
-
 static ssize_t iommu_group_attr_show(struct kobject *kobj,
 				     struct attribute *__attr, char *buf)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 5629ae42951f..923a8d1c5e39 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -504,7 +504,6 @@ int iommu_set_pgtable_quirks(struct iommu_domain *domain,
 		unsigned long quirks);
 
 void iommu_set_dma_strict(void);
-bool iommu_get_dma_strict(struct iommu_domain *domain);
 
 extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev,
 			      unsigned long iova, int flags);
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:35 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:35 +0100
Subject: [PATCH v4 21/24] iommu: Expose DMA domain strictness via sysfs
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <0e08da5ed4069fd3473cfbadda758ca983becdbf.1628682049.git.robin.murphy@arm.com>

The sysfs interface for default domain types exists primarily so users
can choose the performance/security tradeoff relevant to their own
workload. As such, the choice between the policies for DMA domains fits
perfectly as an additional point on that scale - downgrading a
particular device from a strict default to non-strict may be enough to
let it reach the desired level of performance, while still retaining
more peace of mind than with a wide-open identity domain. Now that we've
abstracted non-strict mode as a distinct type of DMA domain, allow it to
be chosen through the user interface as well.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: John Garry <john.garry at huawei.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Summarise the implications in the documentation for completeness
---
 Documentation/ABI/testing/sysfs-kernel-iommu_groups | 6 +++++-
 drivers/iommu/iommu.c                               | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-kernel-iommu_groups b/Documentation/ABI/testing/sysfs-kernel-iommu_groups
index eae2f1c1e11e..b15af6a5bc08 100644
--- a/Documentation/ABI/testing/sysfs-kernel-iommu_groups
+++ b/Documentation/ABI/testing/sysfs-kernel-iommu_groups
@@ -42,8 +42,12 @@ Description:	/sys/kernel/iommu_groups/<grp_id>/type shows the type of default
 		========  ======================================================
 		DMA       All the DMA transactions from the device in this group
 		          are translated by the iommu.
+		DMA-FQ    As above, but using batched invalidation to lazily
+		          remove translations after use. This may offer reduced
+			  overhead at the cost of reduced memory protection.
 		identity  All the DMA transactions from the device in this group
-		          are not translated by the iommu.
+		          are not translated by the iommu. Maximum performance
+			  but zero protection.
 		auto      Change to the type the device was booted with.
 		========  ======================================================
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 55ca5bf3cafc..b141161d5bbc 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3267,6 +3267,8 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
 		req_type = IOMMU_DOMAIN_IDENTITY;
 	else if (sysfs_streq(buf, "DMA"))
 		req_type = IOMMU_DOMAIN_DMA;
+	else if (sysfs_streq(buf, "DMA-FQ"))
+		req_type = IOMMU_DOMAIN_DMA_FQ;
 	else if (sysfs_streq(buf, "auto"))
 		req_type = 0;
 	else
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:36 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:36 +0100
Subject: [PATCH v4 22/24] iommu: Only log strictness for DMA domains
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <9d2bcba880c6d517d0751ed8bd4960853030b4d7.1628682049.git.robin.murphy@arm.com>

When passthrough is enabled, the default strictness policy becomes
irrelevant, since any subsequent runtime override to a DMA domain type
now embodies an explicit choice of strictness as well. Save on noise by
only logging the default policy when it is meaningfully in effect.

Reviewed-by: John Garry <john.garry at huawei.com>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/iommu.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index b141161d5bbc..63face36fc49 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -144,10 +144,11 @@ static int __init iommu_subsys_init(void)
 		(iommu_cmd_line & IOMMU_CMD_LINE_DMA_API) ?
 			"(set via kernel command line)" : "");
 
-	pr_info("DMA domain TLB invalidation policy: %s mode %s\n",
-		iommu_dma_strict ? "strict" : "lazy",
-		(iommu_cmd_line & IOMMU_CMD_LINE_STRICT) ?
-			"(set via kernel command line)" : "");
+	if (!iommu_default_passthrough())
+		pr_info("DMA domain TLB invalidation policy: %s mode %s\n",
+			iommu_dma_strict ? "strict" : "lazy",
+			(iommu_cmd_line & IOMMU_CMD_LINE_STRICT) ?
+				"(set via kernel command line)" : "");
 
 	return 0;
 }
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:37 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:37 +0100
Subject: [PATCH v4 23/24] iommu: Merge strictness and domain type configs
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <d04af35b9c0f2a1d39605d7a9b451f5e1f0c7736.1628682049.git.robin.murphy@arm.com>

To parallel the sysfs behaviour, merge the new build-time option
for DMA domain strictness into the default domain type choice.

Suggested-by: Joerg Roedel <joro at 8bytes.org>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe at linaro.org>
Reviewed-by: John Garry <john.garry at huawei.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Remember to update parameter documentation as well
---
 .../admin-guide/kernel-parameters.txt         |  8 +-
 drivers/iommu/Kconfig                         | 80 +++++++++----------
 drivers/iommu/iommu.c                         |  2 +-
 3 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 90b525cf0ec2..19192b39952a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2045,11 +2045,9 @@
 			1 - Strict mode.
 			  DMA unmap operations invalidate IOMMU hardware TLBs
 			  synchronously.
-			unset - Use value of CONFIG_IOMMU_DEFAULT_{LAZY,STRICT}.
-			Note: on x86, the default behaviour depends on the
-			equivalent driver-specific parameters, but a strict
-			mode explicitly specified by either method takes
-			precedence.
+			unset - Use value of CONFIG_IOMMU_DEFAULT_DMA_{LAZY,STRICT}.
+			Note: on x86, strict mode specified via one of the
+			legacy driver-specific options takes precedence.
 
 	iommu.passthrough=
 			[ARM64, X86] Configure DMA to bypass the IOMMU by default.
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c84da8205be7..6e06f876d75a 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -79,55 +79,55 @@ config IOMMU_DEBUGFS
 	  debug/iommu directory, and then populate a subdirectory with
 	  entries as required.
 
-config IOMMU_DEFAULT_PASSTHROUGH
-	bool "IOMMU passthrough by default"
-	depends on IOMMU_API
-	help
-	  Enable passthrough by default, removing the need to pass in
-	  iommu.passthrough=on or iommu=pt through command line. If this
-	  is enabled, you can still disable with iommu.passthrough=off
-	  or iommu=nopt depending on the architecture.
-
-	  If unsure, say N here.
-
 choice
-	prompt "IOMMU default DMA IOTLB invalidation mode"
-	depends on IOMMU_DMA
-
-	default IOMMU_DEFAULT_LAZY if (AMD_IOMMU || INTEL_IOMMU)
-	default IOMMU_DEFAULT_STRICT
+	prompt "IOMMU default domain type"
+	depends on IOMMU_API
+	default IOMMU_DEFAULT_DMA_LAZY if AMD_IOMMU || INTEL_IOMMU
+	default IOMMU_DEFAULT_DMA_STRICT
 	help
-	  This option allows an IOMMU DMA IOTLB invalidation mode to be
-	  chosen at build time, to override the default mode of each ARCH,
-	  removing the need to pass in kernel parameters through command line.
-	  It is still possible to provide common boot params to override this
-	  config.
+	  Choose the type of IOMMU domain used to manage DMA API usage by
+	  device drivers. The options here typically represent different
+	  levels of tradeoff between robustness/security and performance,
+	  depending on the IOMMU driver. Not all IOMMUs support all options.
+	  This choice can be overridden at boot via the command line, and for
+	  some devices also at runtime via sysfs.
 
 	  If unsure, keep the default.
 
-config IOMMU_DEFAULT_STRICT
-	bool "strict"
+config IOMMU_DEFAULT_DMA_STRICT
+	bool "Translated - Strict"
 	help
-	  For every IOMMU DMA unmap operation, the flush operation of IOTLB and
-	  the free operation of IOVA are guaranteed to be done in the unmap
-	  function.
+	  Trusted devices use translation to restrict their access to only
+	  DMA-mapped pages, with strict TLB invalidation on unmap. Equivalent
+	  to passing "iommu.passthrough=0 iommu.strict=1" on the command line.
 
-config IOMMU_DEFAULT_LAZY
-	bool "lazy"
+	  Untrusted devices always use this mode, with an additional layer of
+	  bounce-buffering such that they cannot gain access to any unrelated
+	  data within a mapped page.
+
+config IOMMU_DEFAULT_DMA_LAZY
+	bool "Translated - Lazy"
 	help
-	  Support lazy mode, where for every IOMMU DMA unmap operation, the
-	  flush operation of IOTLB and the free operation of IOVA are deferred.
-	  They are only guaranteed to be done before the related IOVA will be
-	  reused.
+	  Trusted devices use translation to restrict their access to only
+	  DMA-mapped pages, but with "lazy" batched TLB invalidation. This
+	  mode allows higher performance with some IOMMUs due to reduced TLB
+	  flushing, but at the cost of reduced isolation since devices may be
+	  able to access memory for some time after it has been unmapped.
+	  Equivalent to passing "iommu.passthrough=0 iommu.strict=0" on the
+	  command line.
 
-	  The isolation provided in this mode is not as secure as STRICT mode,
-	  such that a vulnerable time window may be created between the DMA
-	  unmap and the mappings cached in the IOMMU IOTLB or device TLB
-	  finally being invalidated, where the device could still access the
-	  memory which has already been unmapped by the device driver.
-	  However this mode may provide better performance in high throughput
-	  scenarios, and is still considerably more secure than passthrough
-	  mode or no IOMMU.
+	  If this mode is not supported by the IOMMU driver, the effective
+	  runtime default will fall back to IOMMU_DEFAULT_DMA_STRICT.
+
+config IOMMU_DEFAULT_PASSTHROUGH
+	bool "Passthrough"
+	help
+	  Trusted devices are identity-mapped, giving them unrestricted access
+	  to memory with minimal performance overhead. Equivalent to passing
+	  "iommu.passthrough=1" (historically "iommu=pt") on the command line.
+
+	  If this mode is not supported by the IOMMU driver, the effective
+	  runtime default will fall back to IOMMU_DEFAULT_DMA_STRICT.
 
 endchoice
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 63face36fc49..480ad6a538a9 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -31,7 +31,7 @@ static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
 
 static unsigned int iommu_def_domain_type __read_mostly;
-static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_STRICT);
+static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);
 static u32 iommu_cmd_line __read_mostly;
 
 struct iommu_group {
-- 
2.25.1



From robin.murphy at arm.com  Wed Aug 11 05:21:38 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 13:21:38 +0100
Subject: [PATCH v4 24/24] iommu: Allow enabling non-strict mode dynamically
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <d652966348c78457c38bf18daf369272a4ebc2c9.1628682049.git.robin.murphy@arm.com>

Allocating and enabling a flush queue is in fact something we can
reasonably do while a DMA domain is active, without having to rebuild it
from scratch. Thus we can allow a strict -> non-strict transition from
sysfs without requiring to unbind the device's driver, which is of
particular interest to users who want to make selective relaxations to
critical devices like the one serving their root filesystem.

Disabling and draining a queue also seems technically possible to
achieve without rebuilding the whole domain, but would certainly be more
involved. Furthermore there's not such a clear use-case for tightening
up security *after* the device may already have done whatever it is that
you don't trust it not to do, so we only consider the relaxation case.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>

---

v3: Actually think about concurrency, rework most of the fq data
    accesses to be (hopefully) safe and comment it all

v4: Squash in simplified iommu_dma_init_fq() refactor, clean up previous
    barrier from init_iova_flush_queue(), drop rogue header change
    (turns out there's a whole other rabbit hole of iova_fq cleanup to
    venture down after this...)

---
 drivers/iommu/dma-iommu.c | 47 ++++++++++++++++++++++++++-------------
 drivers/iommu/iommu.c     | 17 ++++++++++----
 drivers/iommu/iova.c      | 11 ++++-----
 include/linux/dma-iommu.h |  6 +++++
 4 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 01fa83229118..27f98a29f49a 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -310,6 +310,30 @@ static bool dev_is_untrusted(struct device *dev)
 	return dev_is_pci(dev) && to_pci_dev(dev)->untrusted;
 }
 
+/* sysfs updates are serialised by the mutex of the group owning @domain */
+int iommu_dma_init_fq(struct iommu_domain *domain)
+{
+	struct iommu_dma_cookie *cookie = domain->iova_cookie;
+	int ret;
+
+	if (cookie->fq_domain)
+		return 0;
+
+	ret = init_iova_flush_queue(&cookie->iovad, iommu_dma_flush_iotlb_all,
+				    iommu_dma_entry_dtor);
+	if (ret) {
+		pr_warn("iova flush queue initialization failed\n");
+		return ret;
+	}
+	/*
+	 * Prevent incomplete iovad->fq being observable. Pairs with path from
+	 * __iommu_dma_unmap() through iommu_dma_free_iova() to queue_iova()
+	 */
+	smp_wmb();
+	WRITE_ONCE(cookie->fq_domain, domain);
+	return 0;
+}
+
 /**
  * iommu_dma_init_domain - Initialise a DMA mapping domain
  * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie()
@@ -364,15 +388,8 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
 	init_iova_domain(iovad, 1UL << order, base_pfn);
 
 	/* If the FQ fails we can simply fall back to strict mode */
-	if (domain->type == IOMMU_DOMAIN_DMA_FQ && !cookie->fq_domain) {
-		if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all,
-					  iommu_dma_entry_dtor)) {
-			pr_warn("iova flush queue initialization failed\n");
-			domain->type = IOMMU_DOMAIN_DMA;
-		} else {
-			cookie->fq_domain = domain;
-		}
-	}
+	if (domain->type == IOMMU_DOMAIN_DMA_FQ && iommu_dma_init_fq(domain))
+		domain->type = IOMMU_DOMAIN_DMA;
 
 	return iova_reserve_iommu_regions(dev, domain);
 }
@@ -447,17 +464,17 @@ static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain,
 }
 
 static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie,
-		dma_addr_t iova, size_t size, struct page *freelist)
+		dma_addr_t iova, size_t size, struct iommu_iotlb_gather *gather)
 {
 	struct iova_domain *iovad = &cookie->iovad;
 
 	/* The MSI case is only ever cleaning up its most recent allocation */
 	if (cookie->type == IOMMU_DMA_MSI_COOKIE)
 		cookie->msi_iova -= size;
-	else if (cookie->fq_domain)	/* non-strict mode */
+	else if (gather && gather->queued)
 		queue_iova(iovad, iova_pfn(iovad, iova),
 				size >> iova_shift(iovad),
-				(unsigned long)freelist);
+				(unsigned long)gather->freelist);
 	else
 		free_iova_fast(iovad, iova_pfn(iovad, iova),
 				size >> iova_shift(iovad));
@@ -476,14 +493,14 @@ static void __iommu_dma_unmap(struct device *dev, dma_addr_t dma_addr,
 	dma_addr -= iova_off;
 	size = iova_align(iovad, size + iova_off);
 	iommu_iotlb_gather_init(&iotlb_gather);
-	iotlb_gather.queued = cookie->fq_domain;
+	iotlb_gather.queued = READ_ONCE(cookie->fq_domain);
 
 	unmapped = iommu_unmap_fast(domain, dma_addr, size, &iotlb_gather);
 	WARN_ON(unmapped != size);
 
-	if (!cookie->fq_domain)
+	if (!iotlb_gather.queued)
 		iommu_iotlb_sync(domain, &iotlb_gather);
-	iommu_dma_free_iova(cookie, dma_addr, size, iotlb_gather.freelist);
+	iommu_dma_free_iova(cookie, dma_addr, size, &iotlb_gather);
 }
 
 static void __iommu_dma_unmap_swiotlb(struct device *dev, dma_addr_t dma_addr,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 480ad6a538a9..135d274d6d9f 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3203,6 +3203,14 @@ static int iommu_change_dev_def_domain(struct iommu_group *group,
 		goto out;
 	}
 
+	/* We can bring up a flush queue without tearing down the domain */
+	if (type == IOMMU_DOMAIN_DMA_FQ && prev_dom->type == IOMMU_DOMAIN_DMA) {
+		ret = iommu_dma_init_fq(prev_dom);
+		if (!ret)
+			prev_dom->type = IOMMU_DOMAIN_DMA_FQ;
+		goto out;
+	}
+
 	/* Sets group->default_domain to the newly allocated domain */
 	ret = iommu_group_alloc_default_domain(dev->bus, group, type);
 	if (ret)
@@ -3243,9 +3251,9 @@ static int iommu_change_dev_def_domain(struct iommu_group *group,
 }
 
 /*
- * Changing the default domain through sysfs requires the users to ubind the
- * drivers from the devices in the iommu group. Return failure if this doesn't
- * meet.
+ * Changing the default domain through sysfs requires the users to unbind the
+ * drivers from the devices in the iommu group, except for a DMA -> DMA-FQ
+ * transition. Return failure if this isn't met.
  *
  * We need to consider the race between this and the device release path.
  * device_lock(dev) is used here to guarantee that the device release path
@@ -3321,7 +3329,8 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
 
 	/* Check if the device in the group still has a driver bound to it */
 	device_lock(dev);
-	if (device_is_bound(dev)) {
+	if (device_is_bound(dev) && !(req_type == IOMMU_DOMAIN_DMA_FQ &&
+	    group->default_domain->type == IOMMU_DOMAIN_DMA)) {
 		pr_err_ratelimited("Device is still bound to driver\n");
 		ret = -EBUSY;
 		goto out;
diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index 2ad73fb2e94e..0af42fb93a49 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -121,8 +121,6 @@ int init_iova_flush_queue(struct iova_domain *iovad,
 		spin_lock_init(&fq->lock);
 	}
 
-	smp_wmb();
-
 	iovad->fq = queue;
 
 	timer_setup(&iovad->fq_timer, fq_flush_timeout, 0);
@@ -633,17 +631,20 @@ void queue_iova(struct iova_domain *iovad,
 		unsigned long pfn, unsigned long pages,
 		unsigned long data)
 {
-	struct iova_fq *fq = raw_cpu_ptr(iovad->fq);
+	struct iova_fq *fq;
 	unsigned long flags;
 	unsigned idx;
 
 	/*
 	 * Order against the IOMMU driver's pagetable update from unmapping
 	 * @pte, to guarantee that iova_domain_flush() observes that if called
-	 * from a different CPU before we release the lock below.
+	 * from a different CPU before we release the lock below. Full barrier
+	 * so it also pairs with iommu_dma_init_fq() to avoid seeing partially
+	 * written fq state here.
 	 */
-	smp_wmb();
+	smp_mb();
 
+	fq = raw_cpu_ptr(iovad->fq);
 	spin_lock_irqsave(&fq->lock, flags);
 
 	/*
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index 758ca4694257..24607dc3c2ac 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -20,6 +20,7 @@ void iommu_put_dma_cookie(struct iommu_domain *domain);
 
 /* Setup call for arch DMA mapping code */
 void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit);
+int iommu_dma_init_fq(struct iommu_domain *domain);
 
 /* The DMA API isn't _quite_ the whole story, though... */
 /*
@@ -54,6 +55,11 @@ static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base,
 {
 }
 
+static inline int iommu_dma_init_fq(struct iommu_domain *domain)
+{
+	return -EINVAL;
+}
+
 static inline int iommu_get_dma_cookie(struct iommu_domain *domain)
 {
 	return -ENODEV;
-- 
2.25.1



From pbonzini at redhat.com  Wed Aug 11 05:23:24 2021
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Wed, 11 Aug 2021 14:23:24 +0200
Subject: [PATCH v6 01/21] KVM: x86: Fix potential race in KVM_GET_CLOCK
In-Reply-To: <20210804085819.846610-2-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-2-oupton@google.com>
Message-ID: <78eeaf83-2bfa-8452-1301-a607fba7fa0c@redhat.com>

On 04/08/21 10:57, Oliver Upton wrote:
> Sean noticed that KVM_GET_CLOCK was checking kvm_arch.use_master_clock
> outside of the pvclock sync lock. This is problematic, as the clock
> value written to the user may or may not actually correspond to a stable
> TSC.
> 
> Fix the race by populating the entire kvm_clock_data structure behind
> the pvclock_gtod_sync_lock.
> 
> Suggested-by: Sean Christopherson <seanjc at google.com>
> Signed-off-by: Oliver Upton <oupton at google.com>
> ---
>   arch/x86/kvm/x86.c | 39 ++++++++++++++++++++++++++++-----------
>   1 file changed, 28 insertions(+), 11 deletions(-)

I had a completely independent patch that fixed the same race.  It unifies
the read sides of tsc_write_lock and pvclock_gtod_sync_lock into a seqcount
(and replaces pvclock_gtod_sync_lock with kvm->lock on the write side).

I attach it now (based on https://lore.kernel.org/kvm/20210811102356.3406687-1-pbonzini at redhat.com/T/#t),
but the testing was extremely light so I'm not sure I will be able to include
it in 5.15.

Paolo

-------------- 8< -------------
From: Paolo Bonzini <pbonzini at redhat.com>
Date: Thu, 8 Apr 2021 05:03:44 -0400
Subject: [PATCH] kvm: x86: protect masterclock with a seqcount

Protect the reference point for kvmclock with a seqcount, so that
kvmclock updates for all vCPUs can proceed in parallel.  Xen runstate
updates will also run in parallel and not bounce the kvmclock cacheline.

This also makes it possible to use KVM_REQ_CLOCK_UPDATE (which will
block on the seqcount) to prevent entering in the guests until
pvclock_update_vm_gtod_copy is complete, and thus to get rid of
KVM_REQ_MCLOCK_INPROGRESS.

nr_vcpus_matched_tsc is updated outside pvclock_update_vm_gtod_copy
though, so a spinlock must be kept for that one.

Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/locking.rst
index 8138201efb09..ed41da172e02 100644
--- a/Documentation/virt/kvm/locking.rst
+++ b/Documentation/virt/kvm/locking.rst
@@ -29,6 +29,8 @@ The acquisition orders for mutexes are as follows:
  
  On x86:
  
+- the seqcount kvm->arch.pvclock_sc is written under kvm->lock.
+
  - vcpu->mutex is taken outside kvm->arch.hyperv.hv_lock
  
  - kvm->arch.mmu_lock is an rwlock.  kvm->arch.tdp_mmu_pages_lock is
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 20daaf67a5bf..6889aab92362 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -68,8 +68,7 @@
  #define KVM_REQ_PMI			KVM_ARCH_REQ(11)
  #define KVM_REQ_SMI			KVM_ARCH_REQ(12)
  #define KVM_REQ_MASTERCLOCK_UPDATE	KVM_ARCH_REQ(13)
-#define KVM_REQ_MCLOCK_INPROGRESS \
-	KVM_ARCH_REQ_FLAGS(14, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
+/* 14 unused */
  #define KVM_REQ_SCAN_IOAPIC \
  	KVM_ARCH_REQ_FLAGS(15, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
  #define KVM_REQ_GLOBAL_CLOCK_UPDATE	KVM_ARCH_REQ(16)
@@ -1067,6 +1066,11 @@ struct kvm_arch {
  
  	unsigned long irq_sources_bitmap;
  	s64 kvmclock_offset;
+
+	/*
+	 * This also protects nr_vcpus_matched_tsc which is read from a
+	 * preemption-disabled region, so it must be a raw spinlock.
+	 */
  	raw_spinlock_t tsc_write_lock;
  	u64 last_tsc_nsec;
  	u64 last_tsc_write;
@@ -1077,7 +1081,7 @@ struct kvm_arch {
  	u64 cur_tsc_generation;
  	int nr_vcpus_matched_tsc;
  
-	spinlock_t pvclock_gtod_sync_lock;
+	seqcount_mutex_t pvclock_sc;
  	bool use_master_clock;
  	u64 master_kernel_ns;
  	u64 master_cycle_now;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 74145a3fd4f2..7d73c5560260 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2533,9 +2533,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
  	vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
  
  	kvm_vcpu_write_tsc_offset(vcpu, offset);
-	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
  
-	spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags);
  	if (!matched) {
  		kvm->arch.nr_vcpus_matched_tsc = 0;
  	} else if (!already_matched) {
@@ -2543,7 +2541,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
  	}
  
  	kvm_track_tsc_matching(vcpu);
-	spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags);
+	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
  }
  
  static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
@@ -2730,9 +2728,7 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm)
  	struct kvm_arch *ka = &kvm->arch;
  	int vclock_mode;
  	bool host_tsc_clocksource, vcpus_matched;
-
-	vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 ==
-			atomic_read(&kvm->online_vcpus));
+	unsigned long flags;
  
  	/*
  	 * If the host uses TSC clock, then passthrough TSC as stable
@@ -2742,9 +2738,14 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm)
  					&ka->master_kernel_ns,
  					&ka->master_cycle_now);
  
+	raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
+	vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 ==
+			atomic_read(&kvm->online_vcpus));
+
  	ka->use_master_clock = host_tsc_clocksource && vcpus_matched
  				&& !ka->backwards_tsc_observed
  				&& !ka->boot_vcpu_runs_old_kvmclock;
+	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
  
  	if (ka->use_master_clock)
  		atomic_set(&kvm_guest_has_master_clock, 1);
@@ -2758,25 +2759,26 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm)
  static void kvm_start_pvclock_update(struct kvm *kvm)
  {
  	struct kvm_arch *ka = &kvm->arch;
-	kvm_make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
  
-	/* no guest entries from this point */
-	spin_lock_irq(&ka->pvclock_gtod_sync_lock);
+	mutex_lock(&kvm->lock);
+	/*
+	 * write_seqcount_begin disables preemption.  This is needed not just
+	 * to avoid livelock, but also because the preempt notifier is a reader
+	 * for ka->pvclock_sc.
+	 */
+	write_seqcount_begin(&ka->pvclock_sc);
+	kvm_make_all_cpus_request(kvm,
+		KVM_REQ_CLOCK_UPDATE | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP);
+
+	/* no guest entries from this point until write_seqcount_end */
  }
  
  static void kvm_end_pvclock_update(struct kvm *kvm)
  {
  	struct kvm_arch *ka = &kvm->arch;
-	struct kvm_vcpu *vcpu;
-	int i;
  
-	spin_unlock_irq(&ka->pvclock_gtod_sync_lock);
-	kvm_for_each_vcpu(i, vcpu, kvm)
-		kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
-
-	/* guest entries allowed */
-	kvm_for_each_vcpu(i, vcpu, kvm)
-		kvm_clear_request(KVM_REQ_MCLOCK_INPROGRESS, vcpu);
+	write_seqcount_end(&ka->pvclock_sc);
+	mutex_unlock(&kvm->lock);
  }
  
  static void kvm_update_masterclock(struct kvm *kvm)
@@ -2787,27 +2789,21 @@ static void kvm_update_masterclock(struct kvm *kvm)
  	kvm_end_pvclock_update(kvm);
  }
  
-u64 get_kvmclock_ns(struct kvm *kvm)
+static u64 __get_kvmclock_ns(struct kvm *kvm)
  {
  	struct kvm_arch *ka = &kvm->arch;
  	struct pvclock_vcpu_time_info hv_clock;
-	unsigned long flags;
  	u64 ret;
  
-	spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
-	if (!ka->use_master_clock) {
-		spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
+	if (!ka->use_master_clock)
  		return get_kvmclock_base_ns() + ka->kvmclock_offset;
-	}
-
-	hv_clock.tsc_timestamp = ka->master_cycle_now;
-	hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
-	spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
  
  	/* both __this_cpu_read() and rdtsc() should be on the same cpu */
  	get_cpu();
  
  	if (__this_cpu_read(cpu_tsc_khz)) {
+		hv_clock.tsc_timestamp = ka->master_cycle_now;
+		hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
  		kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
  				   &hv_clock.tsc_shift,
  				   &hv_clock.tsc_to_system_mul);
@@ -2816,6 +2812,19 @@ u64 get_kvmclock_ns(struct kvm *kvm)
  		ret = get_kvmclock_base_ns() + ka->kvmclock_offset;
  
  	put_cpu();
+	return ret;
+}
+
+u64 get_kvmclock_ns(struct kvm *kvm)
+{
+	struct kvm_arch *ka = &kvm->arch;
+	unsigned seq;
+	u64 ret;
+
+	do {
+		seq = read_seqcount_begin(&ka->pvclock_sc);
+		ret = __get_kvmclock_ns(kvm);
+	} while (read_seqcount_retry(&ka->pvclock_sc, seq));
  
  	return ret;
  }
@@ -2882,6 +2891,7 @@ static void kvm_setup_pvclock_page(struct kvm_vcpu *v,
  static int kvm_guest_time_update(struct kvm_vcpu *v)
  {
  	unsigned long flags, tgt_tsc_khz;
+	unsigned seq;
  	struct kvm_vcpu_arch *vcpu = &v->arch;
  	struct kvm_arch *ka = &v->kvm->arch;
  	s64 kernel_ns;
@@ -2896,13 +2906,14 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
  	 * If the host uses TSC clock, then passthrough TSC as stable
  	 * to the guest.
  	 */
-	spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
-	use_master_clock = ka->use_master_clock;
-	if (use_master_clock) {
-		host_tsc = ka->master_cycle_now;
-		kernel_ns = ka->master_kernel_ns;
-	}
-	spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
+	seq = read_seqcount_begin(&ka->pvclock_sc);
+	do {
+		use_master_clock = ka->use_master_clock;
+		if (use_master_clock) {
+			host_tsc = ka->master_cycle_now;
+			kernel_ns = ka->master_kernel_ns;
+		}
+	} while (read_seqcount_retry(&ka->pvclock_sc, seq));
  
  	/* Keep irq disabled to prevent changes to the clock */
  	local_irq_save(flags);
@@ -6098,11 +6109,13 @@ long kvm_arch_vm_ioctl(struct file *filp,
  	}
  	case KVM_GET_CLOCK: {
  		struct kvm_clock_data user_ns;
-		u64 now_ns;
+		unsigned seq;
  
-		now_ns = get_kvmclock_ns(kvm);
-		user_ns.clock = now_ns;
-		user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0;
+		do {
+			seq = read_seqcount_begin(&kvm->arch.pvclock_sc);
+			user_ns.clock = __get_kvmclock_ns(kvm);
+			user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0;
+		} while (read_seqcount_retry(&kvm->arch.pvclock_sc, seq));
  		memset(&user_ns.pad, 0, sizeof(user_ns.pad));
  
  		r = -EFAULT;
@@ -11144,8 +11157,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
  
  	raw_spin_lock_init(&kvm->arch.tsc_write_lock);
  	mutex_init(&kvm->arch.apic_map_lock);
-	spin_lock_init(&kvm->arch.pvclock_gtod_sync_lock);
-
+	seqcount_mutex_init(&kvm->arch.pvclock_sc, &kvm->lock);
  	kvm->arch.kvmclock_offset = -get_kvmclock_base_ns();
  	pvclock_update_vm_gtod_copy(kvm);
  



From tangbin at cmss.chinamobile.com  Wed Aug 11 05:28:23 2021
From: tangbin at cmss.chinamobile.com (tangbin)
Date: Wed, 11 Aug 2021 20:28:23 +0800
Subject: [PATCH] ASoC: stm32: spdifrx: Delete unnecessary check in the
 probe function
In-Reply-To: <20210811121955.GD4167@sirena.org.uk>
References: <20210811115523.17232-1-tangbin@cmss.chinamobile.com>
 <20210811115846.GC4167@sirena.org.uk>
 <7ddb13ee-2ca6-bf8d-2a83-9896d29176c5@cmss.chinamobile.com>
 <20210811121955.GD4167@sirena.org.uk>
Message-ID: <d0fa7aa5-b64b-7d4a-a80d-ec2f6dec5712@cmss.chinamobile.com>

Hi Mark:

On 2021/8/11 20:19, Mark Brown wrote:
> On Wed, Aug 11, 2021 at 08:09:00PM +0800, tangbin wrote:
>> On 2021/8/11 19:58, Mark Brown wrote:
>>> On Wed, Aug 11, 2021 at 07:55:23PM +0800, Tang Bin wrote:
>>>> The function stm32_spdifrx_parse_of() is only called by the function
>>>> stm32_spdifrx_probe(), and the probe function is only called with
>>>> an openfirmware platform device. Therefore there is no need to check
>>>> the device_node in probe function.
>>> What is the benefit of not doing the check?  It seems like reasonable
>>> defensive programming.
>> I think it's unnecessary, because we all know than the probe function is
>> only trigger if
>> the device and the driver matches, and the trigger mode is just Device Tree.
>> So the device_node
>> must be exist in the probe function if it works. That's the reason why I
>> think it's redundant.
> I see why it is redundant, I don't see what problem this redudnancy
> causes.

Maybe not, just be redundant. If you think that's ok, just drop this patch.

I'm sorry to trouble you.

Thanks

Tang Bin





From kishon at ti.com  Wed Aug 11 05:26:57 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 17:56:57 +0530
Subject: [PATCH v2 0/6] PCI: Add support for J7200 and AM64
In-Reply-To: <20210803105252.GD11252@lpieralisi>
References: <20210803074932.19820-1-kishon@ti.com>
 <20210803105252.GD11252@lpieralisi>
Message-ID: <ea0c5f77-9034-872b-a25e-d4acc6c0947c@ti.com>

Hi Lorenzo,

On 03/08/21 4:22 pm, Lorenzo Pieralisi wrote:
> On Tue, Aug 03, 2021 at 01:19:26PM +0530, Kishon Vijay Abraham I wrote:
>> This series adds the compatible specific to J7200 and AM64 and
>> applies the erratas and configuration specific to them.
>>
>> This series also includes Nadeem's patch that adds a quirk in
>> Cadence driver which is used by J7200 [1].
>>
>> The DT binding for both J7200 and AM64 is already merged.
>>
>> v1 of the patch series can be found at [2]
>>
>> Changes from v1:
>> 1) As suggested by Bjorn, used unsigned int :1, instead of bool for
>> structure members
>> 2) Removed using unnecessary local variables and also fixed some
>> code alignment
>>
>> [1] -> https://lore.kernel.org/r/20210528155626.21793-1-nadeem at cadence.com
>> [2] -> https://lore.kernel.org/r/20210706105035.9915-1-kishon at ti.com
>>
>> Kishon Vijay Abraham I (5):
>>   PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
>>   PCI: j721e: Add PCIe support for J7200
>>   PCI: j721e: Add PCIe support for AM64
>>   misc: pci_endpoint_test: Do not request or allocate IRQs in probe
>>   misc: pci_endpoint_test: Add deviceID for AM64 and J7200
>>
>> Nadeem Athani (1):
>>   PCI: cadence: Add quirk flag to set minimum delay in LTSSM
>>     Detect.Quiet state
>>
>>  drivers/misc/pci_endpoint_test.c              | 27 ++++++--
>>  drivers/pci/controller/cadence/pci-j721e.c    | 61 +++++++++++++++++--
>>  .../pci/controller/cadence/pcie-cadence-ep.c  |  4 ++
>>  .../controller/cadence/pcie-cadence-host.c    |  3 +
>>  drivers/pci/controller/cadence/pcie-cadence.c | 17 ++++++
>>  drivers/pci/controller/cadence/pcie-cadence.h | 17 +++++-
>>  6 files changed, 117 insertions(+), 12 deletions(-)
> 
> I am not convinced about patch (5) the rest of the series can be
> merged (even though I assume patch (6) depends on (5)).

I'll drop patch 5, fix your other comments and send a new revision.

Thanks,
Kishon


From kishon at ti.com  Wed Aug 11 05:33:31 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:03:31 +0530
Subject: [PATCH v3 0/5] PCI: Add support for J7200 and AM64
Message-ID: <20210811123336.31357-1-kishon@ti.com>

This series adds the compatible specific to J7200 and AM64 and
applies the erratas and configuration specific to them.

This series also includes Nadeem's patch that adds a quirk in
Cadence driver which is used by J7200 [1].

The DT binding for both J7200 and AM64 is already merged.

v1 of the patch series can be found at [2]
v2 of the patch series can be found at [3]

Changes from v2:
1) Drop the patch that does not request or allocate IRQs in probe for
J721E/AM654
2) Fix other minor comments given by Lorenzo

Changes from v1:
1) As suggested by Bjorn, used unsigned int :1, instead of bool for
structure members
2) Removed using unnecessary local variables and also fixed some
code alignment

[1] -> https://lore.kernel.org/r/20210528155626.21793-1-nadeem at cadence.com
[2] -> https://lore.kernel.org/r/20210706105035.9915-1-kishon at ti.com
[3] -> https://lore.kernel.org/r/20210803074932.19820-1-kishon at ti.com

Kishon Vijay Abraham I (4):
  PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
  PCI: j721e: Add PCIe support for J7200
  PCI: j721e: Add PCIe support for AM64
  misc: pci_endpoint_test: Add deviceID for AM64 and J7200

Nadeem Athani (1):
  PCI: cadence: Add quirk flag to set minimum delay in LTSSM
    Detect.Quiet state

 drivers/misc/pci_endpoint_test.c              |  8 +++
 drivers/pci/controller/cadence/pci-j721e.c    | 61 +++++++++++++++++--
 .../pci/controller/cadence/pcie-cadence-ep.c  |  4 ++
 .../controller/cadence/pcie-cadence-host.c    |  3 +
 drivers/pci/controller/cadence/pcie-cadence.c | 16 +++++
 drivers/pci/controller/cadence/pcie-cadence.h | 17 +++++-
 6 files changed, 103 insertions(+), 6 deletions(-)

-- 
2.17.1



From kishon at ti.com  Wed Aug 11 05:33:32 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:03:32 +0530
Subject: [PATCH v3 1/5] PCI: cadence: Use bitfield for *quirk_retrain_flag*
 instead of bool
In-Reply-To: <20210811123336.31357-1-kishon@ti.com>
References: <20210811123336.31357-1-kishon@ti.com>
Message-ID: <20210811123336.31357-2-kishon@ti.com>

No functional change. As we are intending to add additional 1-bit
members in struct j721e_pcie_data/struct cdns_pcie_rc, use bitfields
instead of bool since it takes less space. As discussed in [1],
the preference is to use bitfileds instead of bool inside structures.

[1] -> https://lore.kernel.org/linux-fsdevel/CA+55aFzKQ6Pj18TB8p4Yr0M4t+S+BsiHH=BJNmn=76-NcjTj-g at mail.gmail.com/

Suggested-by: Bjorn Helgaas <bhelgaas at google.com>
Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c    | 2 +-
 drivers/pci/controller/cadence/pcie-cadence.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 35e61048e133..0c5813b230b4 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -66,7 +66,7 @@ enum j721e_pcie_mode {
 
 struct j721e_pcie_data {
 	enum j721e_pcie_mode	mode;
-	bool quirk_retrain_flag;
+	unsigned int		quirk_retrain_flag:1;
 };
 
 static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index b72de578b996..6f97fb4e58a6 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -312,7 +312,7 @@ struct cdns_pcie_rc {
 	u32			vendor_id;
 	u32			device_id;
 	bool			avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
-	bool                    quirk_retrain_flag;
+	unsigned int		quirk_retrain_flag:1;
 };
 
 /**
-- 
2.17.1



From kishon at ti.com  Wed Aug 11 05:33:33 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:03:33 +0530
Subject: [PATCH v3 2/5] PCI: cadence: Add quirk flag to set minimum delay in
 LTSSM Detect.Quiet state
In-Reply-To: <20210811123336.31357-1-kishon@ti.com>
References: <20210811123336.31357-1-kishon@ti.com>
Message-ID: <20210811123336.31357-3-kishon@ti.com>

From: Nadeem Athani <nadeem at cadence.com>

PCIe fails to link up if SERDES lanes not used by PCIe are assigned to
another protocol. For example, link training fails if lanes 2 and 3 are
assigned to another protocol while lanes 0 and 1 are used for PCIe to
form a two lane link. This failure is due to an incorrect tie-off on an
internal status signal indicating electrical idle.

Status signals going from SERDES to PCIe Controller are tied-off when a
lane is not assigned to PCIe. Signal indicating electrical idle is
incorrectly tied-off to a state that indicates non-idle. As a result,
PCIe sees unused lanes to be out of electrical idle and this causes
LTSSM to exit Detect.Quiet state without waiting for 12ms timeout to
occur. If a receiver is not detected on the first receiver detection
attempt in Detect.Active state, LTSSM goes back to Detect.Quiet and
again moves forward to Detect.Active state without waiting for 12ms as
required by PCIe base specification. Since wait time in Detect.Quiet is
skipped, multiple receiver detect operations are performed back-to-back
without allowing time for capacitance on the transmit lines to
discharge. This causes subsequent receiver detection to always fail even
if a receiver gets connected eventually.

Add a quirk flag "quirk_detect_quiet_flag" to program the minimum
time the LTSSM should wait on entering Detect.Quiet state here.
This has to be set for J7200 as it has an incorrect tie-off on unused
lanes.

Signed-off-by: Nadeem Athani <nadeem at cadence.com>
Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pcie-cadence-ep.c |  4 ++++
 .../pci/controller/cadence/pcie-cadence-host.c   |  3 +++
 drivers/pci/controller/cadence/pcie-cadence.c    | 16 ++++++++++++++++
 drivers/pci/controller/cadence/pcie-cadence.h    | 15 +++++++++++++++
 4 files changed, 38 insertions(+)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 443dd06dfcfc..f021ca0b5f01 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -711,6 +711,10 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
 	/* Reserve region 0 for IRQs */
 	set_bit(0, &ep->ob_region_map);
+
+	if (ep->quirk_detect_quiet_flag)
+		cdns_pcie_detect_quiet_min_delay_set(&ep->pcie);
+
 	spin_lock_init(&ep->lock);
 
 	return 0;
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index ae1c55503513..fb96d37a135c 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -498,6 +498,9 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 		return PTR_ERR(rc->cfg_base);
 	rc->cfg_res = res;
 
+	if (rc->quirk_detect_quiet_flag)
+		cdns_pcie_detect_quiet_min_delay_set(&rc->pcie);
+
 	ret = cdns_pcie_start_link(pcie);
 	if (ret) {
 		dev_err(dev, "Failed to start link\n");
diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
index 3c3646502d05..52767f26048f 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.c
+++ b/drivers/pci/controller/cadence/pcie-cadence.c
@@ -7,6 +7,22 @@
 
 #include "pcie-cadence.h"
 
+void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie)
+{
+	u32 delay = 0x3;
+	u32 ltssm_control_cap;
+
+	/*
+	 * Set the LTSSM Detect Quiet state min. delay to 2ms.
+	 */
+	ltssm_control_cap = cdns_pcie_readl(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP);
+	ltssm_control_cap = ((ltssm_control_cap &
+			    ~CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK) |
+			    CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay));
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_LTSSM_CONTROL_CAP, ltssm_control_cap);
+}
+
 void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
 				   u32 r, bool is_io,
 				   u64 cpu_addr, u64 pci_addr, size_t size)
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 6f97fb4e58a6..5bad4542b8a9 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -198,6 +198,14 @@
 /* AXI link down register */
 #define CDNS_PCIE_AT_LINKDOWN (CDNS_PCIE_AT_BASE + 0x0824)
 
+/* LTSSM Capabilities register */
+#define CDNS_PCIE_LTSSM_CONTROL_CAP             (CDNS_PCIE_LM_BASE + 0x0054)
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK  GENMASK(2, 1)
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT 1
+#define  CDNS_PCIE_DETECT_QUIET_MIN_DELAY(delay) \
+	 (((delay) << CDNS_PCIE_DETECT_QUIET_MIN_DELAY_SHIFT) & \
+	 CDNS_PCIE_DETECT_QUIET_MIN_DELAY_MASK)
+
 enum cdns_pcie_rp_bar {
 	RP_BAR_UNDEFINED = -1,
 	RP_BAR0,
@@ -304,6 +312,7 @@ struct cdns_pcie {
  * @avail_ib_bar: Satus of RP_BAR0, RP_BAR1 and	RP_NO_BAR if it's free or
  *                available
  * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
+ * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
  */
 struct cdns_pcie_rc {
 	struct cdns_pcie	pcie;
@@ -313,6 +322,7 @@ struct cdns_pcie_rc {
 	u32			device_id;
 	bool			avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
 	unsigned int		quirk_retrain_flag:1;
+	unsigned int		quirk_detect_quiet_flag:1;
 };
 
 /**
@@ -345,6 +355,7 @@ struct cdns_pcie_epf {
  *        registers fields (RMW) accessible by both remote RC and EP to
  *        minimize time between read and write
  * @epf: Structure to hold info about endpoint function
+ * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk
  */
 struct cdns_pcie_ep {
 	struct cdns_pcie	pcie;
@@ -359,6 +370,7 @@ struct cdns_pcie_ep {
 	/* protect writing to PCI_STATUS while raising legacy interrupts */
 	spinlock_t		lock;
 	struct cdns_pcie_epf	*epf;
+	unsigned int		quirk_detect_quiet_flag:1;
 };
 
 
@@ -519,6 +531,9 @@ static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	return 0;
 }
 #endif
+
+void cdns_pcie_detect_quiet_min_delay_set(struct cdns_pcie *pcie);
+
 void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
 				   u32 r, bool is_io,
 				   u64 cpu_addr, u64 pci_addr, size_t size);
-- 
2.17.1



From kishon at ti.com  Wed Aug 11 05:33:34 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:03:34 +0530
Subject: [PATCH v3 3/5] PCI: j721e: Add PCIe support for J7200
In-Reply-To: <20210811123336.31357-1-kishon@ti.com>
References: <20210811123336.31357-1-kishon@ti.com>
Message-ID: <20210811123336.31357-4-kishon@ti.com>

J7200 has the same PCIe IP as in J721E with minor changes in the
wrapper. J7200 allows byte access of bridge configuration space
registers and the register field for LINK_DOWN interrupt is different.
J7200 also requires "quirk_detect_quiet_flag" to be set. Configure these
changes as part of driver data applicable only to J7200.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 40 +++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 0c5813b230b4..10b13b728284 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -27,6 +27,7 @@
 #define STATUS_REG_SYS_2	0x508
 #define STATUS_CLR_REG_SYS_2	0x708
 #define LINK_DOWN		BIT(1)
+#define J7200_LINK_DOWN		BIT(10)
 
 #define J721E_PCIE_USER_CMD_STATUS	0x4
 #define LINK_TRAINING_ENABLE		BIT(0)
@@ -57,6 +58,7 @@ struct j721e_pcie {
 	struct cdns_pcie	*cdns_pcie;
 	void __iomem		*user_cfg_base;
 	void __iomem		*intd_cfg_base;
+	u32			linkdown_irq_regfield;
 };
 
 enum j721e_pcie_mode {
@@ -67,6 +69,9 @@ enum j721e_pcie_mode {
 struct j721e_pcie_data {
 	enum j721e_pcie_mode	mode;
 	unsigned int		quirk_retrain_flag:1;
+	unsigned int		quirk_detect_quiet_flag:1;
+	u32			linkdown_irq_regfield;
+	unsigned int		byte_access_allowed:1;
 };
 
 static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
@@ -98,12 +103,12 @@ static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
 	u32 reg;
 
 	reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
-	if (!(reg & LINK_DOWN))
+	if (!(reg & pcie->linkdown_irq_regfield))
 		return IRQ_NONE;
 
 	dev_err(dev, "LINK DOWN!\n");
 
-	j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN);
+	j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, pcie->linkdown_irq_regfield);
 	return IRQ_HANDLED;
 }
 
@@ -112,7 +117,7 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
 	u32 reg;
 
 	reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2);
-	reg |= LINK_DOWN;
+	reg |= pcie->linkdown_irq_regfield;
 	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
 }
 
@@ -284,10 +289,25 @@ static struct pci_ops cdns_ti_pcie_host_ops = {
 static const struct j721e_pcie_data j721e_pcie_rc_data = {
 	.mode = PCI_MODE_RC,
 	.quirk_retrain_flag = true,
+	.byte_access_allowed = false,
+	.linkdown_irq_regfield = LINK_DOWN,
 };
 
 static const struct j721e_pcie_data j721e_pcie_ep_data = {
 	.mode = PCI_MODE_EP,
+	.linkdown_irq_regfield = LINK_DOWN,
+};
+
+static const struct j721e_pcie_data j7200_pcie_rc_data = {
+	.mode = PCI_MODE_RC,
+	.quirk_detect_quiet_flag = true,
+	.linkdown_irq_regfield = J7200_LINK_DOWN,
+	.byte_access_allowed = true,
+};
+
+static const struct j721e_pcie_data j7200_pcie_ep_data = {
+	.mode = PCI_MODE_EP,
+	.quirk_detect_quiet_flag = true,
 };
 
 static const struct of_device_id of_j721e_pcie_match[] = {
@@ -299,6 +319,14 @@ static const struct of_device_id of_j721e_pcie_match[] = {
 		.compatible = "ti,j721e-pcie-ep",
 		.data = &j721e_pcie_ep_data,
 	},
+	{
+		.compatible = "ti,j7200-pcie-host",
+		.data = &j7200_pcie_rc_data,
+	},
+	{
+		.compatible = "ti,j7200-pcie-ep",
+		.data = &j7200_pcie_ep_data,
+	},
 	{},
 };
 
@@ -332,6 +360,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 
 	pcie->dev = dev;
 	pcie->mode = mode;
+	pcie->linkdown_irq_regfield = data->linkdown_irq_regfield;
 
 	base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg");
 	if (IS_ERR(base))
@@ -391,9 +420,11 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 			goto err_get_sync;
 		}
 
-		bridge->ops = &cdns_ti_pcie_host_ops;
+		if (!data->byte_access_allowed)
+			bridge->ops = &cdns_ti_pcie_host_ops;
 		rc = pci_host_bridge_priv(bridge);
 		rc->quirk_retrain_flag = data->quirk_retrain_flag;
+		rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
 
 		cdns_pcie = &rc->pcie;
 		cdns_pcie->dev = dev;
@@ -459,6 +490,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 			ret = -ENOMEM;
 			goto err_get_sync;
 		}
+		ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
 
 		cdns_pcie = &ep->pcie;
 		cdns_pcie->dev = dev;
-- 
2.17.1



From kishon at ti.com  Wed Aug 11 05:33:36 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:03:36 +0530
Subject: [PATCH v3 5/5] misc: pci_endpoint_test: Add deviceID for AM64 and
 J7200
In-Reply-To: <20210811123336.31357-1-kishon@ti.com>
References: <20210811123336.31357-1-kishon@ti.com>
Message-ID: <20210811123336.31357-6-kishon@ti.com>

Add device ID specific to AM64 and J7200 in pci_endpoint_test so that
endpoints configured with those deviceIDs can use pci_endpoint_test
driver.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/misc/pci_endpoint_test.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index c7ee34013485..8811a98fa9ab 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -69,6 +69,8 @@
 #define FLAG_USE_DMA				BIT(0)
 
 #define PCI_DEVICE_ID_TI_AM654			0xb00c
+#define PCI_DEVICE_ID_TI_J7200			0xb00f
+#define PCI_DEVICE_ID_TI_AM64			0xb010
 #define PCI_DEVICE_ID_LS1088A			0x80c0
 
 #define is_am654_pci_dev(pdev)		\
@@ -969,6 +971,12 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E),
 	  .driver_data = (kernel_ulong_t)&j721e_data,
 	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J7200),
+	  .driver_data = (kernel_ulong_t)&j721e_data,
+	},
+	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM64),
+	  .driver_data = (kernel_ulong_t)&j721e_data,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
-- 
2.17.1



From kishon at ti.com  Wed Aug 11 05:33:35 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:03:35 +0530
Subject: [PATCH v3 4/5] PCI: j721e: Add PCIe support for AM64
In-Reply-To: <20210811123336.31357-1-kishon@ti.com>
References: <20210811123336.31357-1-kishon@ti.com>
Message-ID: <20210811123336.31357-5-kishon@ti.com>

AM64 has the same PCIe IP as in J7200 with certain erratas not
applicable (quirk_detect_quiet_flag). Add support for "ti,am64-pcie-host"
compatible and "ti,am64-pcie-ep" compatible that is specific to AM64.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 10b13b728284..ffb176d288cd 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -310,6 +310,17 @@ static const struct j721e_pcie_data j7200_pcie_ep_data = {
 	.quirk_detect_quiet_flag = true,
 };
 
+static const struct j721e_pcie_data am64_pcie_rc_data = {
+	.mode = PCI_MODE_RC,
+	.linkdown_irq_regfield = J7200_LINK_DOWN,
+	.byte_access_allowed = true,
+};
+
+static const struct j721e_pcie_data am64_pcie_ep_data = {
+	.mode = PCI_MODE_EP,
+	.linkdown_irq_regfield = J7200_LINK_DOWN,
+};
+
 static const struct of_device_id of_j721e_pcie_match[] = {
 	{
 		.compatible = "ti,j721e-pcie-host",
@@ -327,6 +338,14 @@ static const struct of_device_id of_j721e_pcie_match[] = {
 		.compatible = "ti,j7200-pcie-ep",
 		.data = &j7200_pcie_ep_data,
 	},
+	{
+		.compatible = "ti,am64-pcie-host",
+		.data = &am64_pcie_rc_data,
+	},
+	{
+		.compatible = "ti,am64-pcie-ep",
+		.data = &am64_pcie_ep_data,
+	},
 	{},
 };
 
-- 
2.17.1



From rogerq at kernel.org  Wed Aug 11 05:38:13 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 11 Aug 2021 15:38:13 +0300
Subject: [PATCH v15 0/6] usb: misc: Add onboard_usb_hub driver
In-Reply-To: <YRFOnhJkB2vi/zwD@google.com>
References: <20210727004118.2583774-1-mka@chromium.org>
 <YRFOnhJkB2vi/zwD@google.com>
Message-ID: <8a8cae28-6617-76d3-1742-3f151a149069@kernel.org>

Hi Matthias,

On 09/08/2021 18:49, Matthias Kaehlcke wrote:
> Hi Greg,
> 
> Just wanted to check if this series is still on your radar. Is
> there anything that blocks it from landing (further ACKs, ...)?
> 
> Thanks
> 
> Matthias
> 
> On Mon, Jul 26, 2021 at 05:41:12PM -0700, Matthias Kaehlcke wrote:
>> This series adds:
>> - the onboard_usb_hub_driver
>> - glue in the xhci-plat driver to create and destroy the
>>   onboard_usb_hub platform devices if needed
>> - a device tree binding for the Realtek RTS5411 USB hub controller
>> - device tree changes that add RTS5411 entries for the QCA SC7180
>>   based boards trogdor and lazor
>> - a couple of stubs for platform device functions to avoid
>>   unresolved symbols with certain kernel configs
>>
>> The main issue the driver addresses is that a USB hub needs to be
>> powered before it can be discovered. For discrete onboard hubs (an
>> example for such a hub is the Realtek RTS5411) this is often solved
>> by supplying the hub with an 'always-on' regulator, which is kind
>> of a hack. Some onboard hubs may require further initialization
>> steps, like changing the state of a GPIO or enabling a clock, which
>> requires even more hacks. This driver creates a platform device
>> representing the hub which performs the necessary initialization.
>> Currently it only supports switching on a single regulator, support
>> for multiple regulators or other actions can be added as needed.
>> Different initialization sequences can be supported based on the
>> compatible string.
>>
>> Besides performing the initialization the driver can be configured
>> to power the hub off during system suspend. This can help to extend
>> battery life on battery powered devices which have no requirements
>> to keep the hub powered during suspend. The driver can also be
>> configured to leave the hub powered when a wakeup capable USB device
>> is connected when suspending, and power it off otherwise.
>>
>> Changes in v15:
>> - adjusted dependencies of USB_DWC3_CORE to make sure it can only
>>   be enabled when at least one of USB_DWC3_HOST, USB_DWC3_GADGET
>>   or USB_DWC3_DUAL_ROLE is selectable
>>
>> Changes in v14:
>> - rebased on top of v5.14-rc1
>> - dropped DT binding patch which landed in v5.13
>>
>> Changes in v13:
>> - added patch "usb: Specify dependency on USB_XHCI_PLATFORM with
>>   'depends on'" to the series to avoid Kconfig conflicts
>> - added patch "arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM"
>>   to the series to keep effective defconfig unchanged
>>
>> Changes in v12:
>> - onboard_hub driver: use IS_ENABLED(CONFIG_USB_ONBOARD_HUB_MODULE)
>>   in onboard_hub.h to also check for the driver built as module
>> - onboard_hub_driver: include onboard_hub.h again to make sure there
>>   are prototype declarations for the public functions
>>
>> Changes in v11:
>> - support multiple onboard hubs connected to the same parent
>> - don't include ?onboard_hub.h? from the onboard hub driver
>>
>> Changes in v10:
>> - always use of_is_onboard_usb_hub() stub unless ONBOARD_USB_HUB=y/m
>> - keep 'regulator-boot-on' property for pp3300_hub
>>
>> Changes in v9:
>> - added dependency on ONBOARD_USB_HUB (or !!ONBOARD_USB_HUB) to
>>   USB_PLATFORM_XHCI
>>
>> Changes in v7:
>> - updated DT binding
>> - series rebased on qcom/arm64-for-5.13
>>
>> Changes in v6:
>> - updated summary
>>
>> Changes in v5:
>> - cover letter added
>>
>> Matthias Kaehlcke (6):
>>   usb: misc: Add onboard_usb_hub driver
>>   of/platform: Add stubs for of_platform_device_create/destroy()
>>   arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM
>>   usb: Specify dependencies on USB_XHCI_PLATFORM with 'depends on'
>>   usb: host: xhci-plat: Create platform device for onboard hubs in
>>     probe()
>>   arm64: dts: qcom: sc7180-trogdor: Add nodes for onboard USB hub
>>
>>  .../sysfs-bus-platform-onboard-usb-hub        |   8 +
>>  MAINTAINERS                                   |   7 +
>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r0.dts |  19 +-
>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r1.dts |  12 +-
>>  .../arm64/boot/dts/qcom/sc7180-trogdor-r1.dts |  19 +-
>>  arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |  19 +-
>>  arch/arm64/configs/defconfig                  |   1 +
>>  drivers/usb/cdns3/Kconfig                     |   2 +-
>>  drivers/usb/dwc3/Kconfig                      |   5 +-
>>  drivers/usb/host/Kconfig                      |   5 +-

These Kconfig changes are causing the resulting .config to be different.
For example, if I start with omap2plus_defconfig, the resulting .config
before and after your series is different as shown below

:/work/linux$ diff /tmp/.config .config
1902d1901
< # CONFIG_HISI_HIKEY_USB is not set
4992c4991
< CONFIG_USB_XHCI_PLATFORM=m
---
> # CONFIG_USB_XHCI_PLATFORM is not set
5073,5075c5072
< # CONFIG_USB_DWC3_HOST is not set
< # CONFIG_USB_DWC3_GADGET is not set
< CONFIG_USB_DWC3_DUAL_ROLE=y
---
> CONFIG_USB_DWC3_GADGET=y
5173a5171
> # CONFIG_USB_ONBOARD_HUB is not set
5285c5283
< CONFIG_USB_ROLE_SWITCH=m
---
> # CONFIG_USB_ROLE_SWITCH is not set

I would expect the same issues for multi_v7_defconfig and multi_v8_defconfig as well.
I'm ok to update the relevant defconfigs files so that the resulting .config is identical to
before your series. Thanks!

--
cheers,
-roger


From kishon at ti.com  Wed Aug 11 05:38:44 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:08:44 +0530
Subject: [PATCH 0/2] PCI: Add legacy interrupt support in pci-j721e
Message-ID: <20210811123846.31921-1-kishon@ti.com>

Patch series adds support for legacy interrupt in pci-j721e. There are
two HW implementations of legacy interrupt controller, one specific to
J721E and the other for J7200/AM64.

In both these implementations, the legacy interrupt is connect to pulse
interrupt of GIC and level to pulse is handled by configuring EOI
register. EOI to convert level to pulse is broken in J721E due to an
errata but is functional in J7200. Hence legacy interrupt support is not
added for J721E

v1 of the patch series can be found @ [1]
Patch series is created on top of [2]

Changes from v2:
1) Dropped legacy interrupt support for J721e
2) Enable legacy interrupts registers in .irq_enable callback

Changes from v1:
1) Only the legacy interrupt specific part is sent as part of this
series. Rest are split and sent as a separate series [2]
2) Created irq_chip for legacy interrupt and used it's ops for enabling,
disabling the interrupts.

[1] -> http://lore.kernel.org/r/20210325090936.9306-1-kishon at ti.com
[2] -> https://lore.kernel.org/linux-omap/20210811123336.31357-1-kishon at ti.com/

Kishon Vijay Abraham I (2):
  dt-bindings: PCI: ti,j721e: Add bindings to specify legacy interrupts
  PCI: j721e: Add PCI legacy interrupt support for J7200

 .../bindings/pci/ti,j721e-pci-host.yaml       |  15 +++
 drivers/pci/controller/cadence/pci-j721e.c    | 119 ++++++++++++++++++
 2 files changed, 134 insertions(+)

-- 
2.17.1



From kishon at ti.com  Wed Aug 11 05:38:45 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:08:45 +0530
Subject: [PATCH 1/2] dt-bindings: PCI: ti,
 j721e: Add bindings to specify legacy interrupts
In-Reply-To: <20210811123846.31921-1-kishon@ti.com>
References: <20210811123846.31921-1-kishon@ti.com>
Message-ID: <20210811123846.31921-2-kishon@ti.com>

Add bindings to specify interrupt controller for legacy interrupts.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../bindings/pci/ti,j721e-pci-host.yaml           | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
index cc900202df29..f461d7b4c0cc 100644
--- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
+++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
@@ -74,6 +74,11 @@ properties:
 
   msi-map: true
 
+patternProperties:
+  "interrupt-controller":
+    type: object
+    description: interrupt controller to handle legacy interrupts.
+
 required:
   - compatible
   - reg
@@ -97,6 +102,8 @@ unevaluatedProperties: false
 
 examples:
   - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
     #include <dt-bindings/soc/ti,sci_pm_domain.h>
     #include <dt-bindings/gpio/gpio.h>
 
@@ -131,5 +138,13 @@ examples:
             ranges = <0x01000000 0x0 0x10001000  0x00 0x10001000  0x0 0x0010000>,
                      <0x02000000 0x0 0x10011000  0x00 0x10011000  0x0 0x7fef000>;
             dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
+
+
+            pcie0_intc: interrupt-controller {
+                    interrupt-controller;
+                    #interrupt-cells = <1>;
+                    interrupt-parent = <&gic500>;
+                    interrupts = <GIC_SPI 312 IRQ_TYPE_EDGE_RISING>;
+            };
         };
     };
-- 
2.17.1



From kishon at ti.com  Wed Aug 11 05:38:46 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 11 Aug 2021 18:08:46 +0530
Subject: [PATCH 2/2] PCI: j721e: Add PCI legacy interrupt support for J7200
In-Reply-To: <20210811123846.31921-1-kishon@ti.com>
References: <20210811123846.31921-1-kishon@ti.com>
Message-ID: <20210811123846.31921-3-kishon@ti.com>

Add PCI legacy interrupt support for J7200. J7200 has a single HW
interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
The HW interrupt line connected to GIC is a pulse interrupt whereas
the legacy interrupts by definition is level interrupt. In order to
provide level interrupt functionality to edge interrupt line, PCIe
in J7200 has provided USER_EOI_REG register. When the SW writes to
USER_EOI_REG register after handling the interrupt, the IP checks the
state of legacy interrupt and re-triggers pulse interrupt invoking
the handler again.

Due to Errata ID #i2094 ([1]), EOI feature is not enabled in J721E
and only a single pulse interrupt will be generated for every
ASSERT_INTx/DEASSERT_INTx. Hence legacy interrupt is not enabled in
J721E.

[1] -> J721E DRA829/TDA4VM Processors Silicon Revision 1.1/1.0 SPRZ455A ?
       DECEMBER 2020 ? REVISED AUGUST 2021
       (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf)

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 119 +++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index ffb176d288cd..4e786d6b89e0 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -29,12 +29,24 @@
 #define LINK_DOWN		BIT(1)
 #define J7200_LINK_DOWN		BIT(10)
 
+#define ENABLE_REG_SYS_1	0x104
+#define STATUS_REG_SYS_1	0x504
+#define SYS1_INTx_EN(num)	(1 << (22 + (num)))
+
 #define J721E_PCIE_USER_CMD_STATUS	0x4
 #define LINK_TRAINING_ENABLE		BIT(0)
 
 #define J721E_PCIE_USER_LINKSTATUS	0x14
 #define LINK_STATUS			GENMASK(1, 0)
 
+#define USER_EOI_REG		0xC8
+enum eoi_reg {
+	EOI_DOWNSTREAM_INTERRUPT,
+	EOI_FLR_INTERRUPT,
+	EOI_LEGACY_INTERRUPT,
+	EOI_POWER_STATE_INTERRUPT,
+};
+
 enum link_status {
 	NO_RECEIVERS_DETECTED,
 	LINK_TRAINING_IN_PROGRESS,
@@ -59,6 +71,7 @@ struct j721e_pcie {
 	void __iomem		*user_cfg_base;
 	void __iomem		*intd_cfg_base;
 	u32			linkdown_irq_regfield;
+	struct irq_domain	*legacy_irq_domain;
 };
 
 enum j721e_pcie_mode {
@@ -121,6 +134,108 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
 	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
 }
 
+static void j721e_pcie_legacy_irq_handler(struct irq_desc *desc)
+{
+	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int i, virq;
+	u32 reg;
+
+	chained_irq_enter(chip, desc);
+
+	reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_1);
+	for (i = 0; i < PCI_NUM_INTX; i++) {
+		if (!(reg & SYS1_INTx_EN(i)))
+			continue;
+
+		virq = irq_find_mapping(pcie->legacy_irq_domain, i);
+		generic_handle_irq(virq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void j721e_pcie_irq_eoi(struct irq_data *data)
+{
+	struct j721e_pcie *pcie = irq_data_get_irq_chip_data(data);
+
+	j721e_pcie_user_writel(pcie, USER_EOI_REG, EOI_LEGACY_INTERRUPT);
+}
+
+static void j721e_pcie_irq_enable(struct irq_data *data)
+{
+	struct j721e_pcie *pcie = irq_data_get_irq_chip_data(data);
+	u32 reg;
+
+	reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_1);
+	reg |= SYS1_INTx_EN(irqd_to_hwirq(data));
+	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_1, reg);
+}
+
+static void j721e_pcie_irq_disable(struct irq_data *data)
+{
+	struct j721e_pcie *pcie = irq_data_get_irq_chip_data(data);
+	u32 reg;
+
+	reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_1);
+	reg &= ~SYS1_INTx_EN(irqd_to_hwirq(data));
+	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_1, reg);
+}
+
+struct irq_chip j721e_pcie_irq_chip = {
+	.name		= "J721E-PCIE-INTX",
+	.irq_eoi	= j721e_pcie_irq_eoi,
+	.irq_enable	= j721e_pcie_irq_enable,
+	.irq_disable	= j721e_pcie_irq_disable,
+};
+
+static int j721e_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq)
+{
+	struct j721e_pcie *pcie = domain->host_data;
+
+	irq_set_chip_and_handler(irq, &j721e_pcie_irq_chip, handle_fasteoi_irq);
+	irq_set_chip_data(irq, pcie);
+
+	return 0;
+}
+
+static const struct irq_domain_ops j721e_pcie_intx_domain_ops = {
+	.map = j721e_pcie_intx_map,
+};
+
+static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
+{
+	struct irq_domain *legacy_irq_domain;
+	struct device *dev = pcie->dev;
+	struct device_node *node = dev->of_node;
+	struct device_node *intc_node;
+	int irq;
+
+	intc_node = of_get_child_by_name(node, "interrupt-controller");
+	if (!intc_node) {
+		dev_dbg(dev, "interrupt-controller node is absent. Legacy INTR not supported\n");
+		return 0;
+	}
+
+	irq = irq_of_parse_and_map(intc_node, 0);
+	if (!irq) {
+		dev_err(dev, "Failed to parse and map legacy irq\n");
+		return -EINVAL;
+	}
+
+	irq_set_chained_handler_and_data(irq, j721e_pcie_legacy_irq_handler, pcie);
+
+	legacy_irq_domain = irq_domain_add_linear(intc_node, PCI_NUM_INTX,
+						  &j721e_pcie_intx_domain_ops, pcie);
+	if (!legacy_irq_domain) {
+		dev_err(dev, "Failed to add irq domain for legacy irqs\n");
+		return -EINVAL;
+	}
+	pcie->legacy_irq_domain = legacy_irq_domain;
+
+	return 0;
+}
+
 static int j721e_pcie_start_link(struct cdns_pcie *cdns_pcie)
 {
 	struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
@@ -433,6 +548,10 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 			goto err_get_sync;
 		}
 
+		ret = j721e_pcie_config_legacy_irq(pcie);
+		if (ret < 0)
+			goto err_get_sync;
+
 		bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
 		if (!bridge) {
 			ret = -ENOMEM;
-- 
2.17.1



From maz at kernel.org  Wed Aug 11 05:50:11 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 13:50:11 +0100
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
Message-ID: <87r1f09md8.wl-maz@kernel.org>

Hi Rafa?,

On Wed, 11 Aug 2021 13:15:31 +0100,
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> 
> Hi,
> 
> I just tried upgrading from the old good LTS kernel 5.10 and I
> discovered that my bcm4908 boards don't boot anymore with the 5.14-rc5.
> 
> 
> The problem is kernel doesn't seem to start booting at all. I see CFE
> bootloader messages:
> 
> Starting program at 0x0000000000080000
> /memory = 0x40000000
> 
> and then nothing. Normally the first kernel line should follow like a:
> Linux version 5.11.0-rc4 (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #30 SMP Wed Aug 11 14:01:00 CEST 2021
> 
> 
> I have zero knowledge of low level arm64 or assembler stuff. I also
> don't own any bcm4908 development board or bcm4908 datasheets.
> 
> All I could do to help debugging this regression was bisecting. The
> first bad commit (I verified it after bisecting process) is:
> 
> commit 0c93df9622d4d921bcd0dc83f71fed9e98f5119f
> Author: Marc Zyngier <maz at kernel.org>
> Date:   Mon Feb 8 09:57:14 2021 +0000
> 
>     arm64: Initialise as nVHE before switching to VHE
> 
>     As we are aiming to be able to control whether we enable VHE or
>     not, let's always drop down to EL1 first, and only then upgrade
>     to VHE if at all possible.
> 
>     This means that if the kernel is booted at EL2, we always start
>     with a nVHE init, drop to EL1 to initialise the the kernel, and
>     only then upgrade the kernel EL to EL2 if possible (the process
>     is obviously shortened for secondary CPUs).
> 
>     The resume path is handled similarly to a secondary CPU boot.
> 
>     Signed-off-by: Marc Zyngier <maz at kernel.org>
>     Acked-by: David Brazdil <dbrazdil at google.com>
>     Acked-by: Catalin Marinas <catalin.marinas at arm.com>
>     Link: https://lore.kernel.org/r/20210208095732.3267263-6-maz at kernel.org
>     [will: Avoid calling switch_to_vhe twice on kaslr path]
>     Signed-off-by: Will Deacon <will at kernel.org>
> 
> 
> Could you look at this issue, please? I'm happy to test any patches or
> provide any extra info I can obtain using kernel 5.11.
> 
> 
> My defconfig for bcm4908 is:

[...]

I don't think the dconfig is that relevant (nothing you quote here
would have an impact that early in the boot process).

On the other hand, a description of the platform (what CPUs does it
have) and how it boots (VHE, non-VHE, booted at EL2 or not) would be
extremely useful. At minimum, a boot log of a working kernel could
help.

Florian: is it something you are seeing on your own systems?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From rogerq at kernel.org  Wed Aug 11 05:56:15 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 11 Aug 2021 15:56:15 +0300
Subject: [PATCH v15 0/6] usb: misc: Add onboard_usb_hub driver
In-Reply-To: <8a8cae28-6617-76d3-1742-3f151a149069@kernel.org>
References: <20210727004118.2583774-1-mka@chromium.org>
 <YRFOnhJkB2vi/zwD@google.com>
 <8a8cae28-6617-76d3-1742-3f151a149069@kernel.org>
Message-ID: <ddd60682-c957-2897-768e-96c9d25c148a@kernel.org>



On 11/08/2021 15:38, Roger Quadros wrote:
> Hi Matthias,
> 
> On 09/08/2021 18:49, Matthias Kaehlcke wrote:
>> Hi Greg,
>>
>> Just wanted to check if this series is still on your radar. Is
>> there anything that blocks it from landing (further ACKs, ...)?
>>
>> Thanks
>>
>> Matthias
>>
>> On Mon, Jul 26, 2021 at 05:41:12PM -0700, Matthias Kaehlcke wrote:
>>> This series adds:
>>> - the onboard_usb_hub_driver
>>> - glue in the xhci-plat driver to create and destroy the
>>>   onboard_usb_hub platform devices if needed
>>> - a device tree binding for the Realtek RTS5411 USB hub controller
>>> - device tree changes that add RTS5411 entries for the QCA SC7180
>>>   based boards trogdor and lazor
>>> - a couple of stubs for platform device functions to avoid
>>>   unresolved symbols with certain kernel configs
>>>
>>> The main issue the driver addresses is that a USB hub needs to be
>>> powered before it can be discovered. For discrete onboard hubs (an
>>> example for such a hub is the Realtek RTS5411) this is often solved
>>> by supplying the hub with an 'always-on' regulator, which is kind
>>> of a hack. Some onboard hubs may require further initialization
>>> steps, like changing the state of a GPIO or enabling a clock, which
>>> requires even more hacks. This driver creates a platform device
>>> representing the hub which performs the necessary initialization.
>>> Currently it only supports switching on a single regulator, support
>>> for multiple regulators or other actions can be added as needed.
>>> Different initialization sequences can be supported based on the
>>> compatible string.
>>>
>>> Besides performing the initialization the driver can be configured
>>> to power the hub off during system suspend. This can help to extend
>>> battery life on battery powered devices which have no requirements
>>> to keep the hub powered during suspend. The driver can also be
>>> configured to leave the hub powered when a wakeup capable USB device
>>> is connected when suspending, and power it off otherwise.
>>>
>>> Changes in v15:
>>> - adjusted dependencies of USB_DWC3_CORE to make sure it can only
>>>   be enabled when at least one of USB_DWC3_HOST, USB_DWC3_GADGET
>>>   or USB_DWC3_DUAL_ROLE is selectable
>>>
>>> Changes in v14:
>>> - rebased on top of v5.14-rc1
>>> - dropped DT binding patch which landed in v5.13
>>>
>>> Changes in v13:
>>> - added patch "usb: Specify dependency on USB_XHCI_PLATFORM with
>>>   'depends on'" to the series to avoid Kconfig conflicts
>>> - added patch "arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM"
>>>   to the series to keep effective defconfig unchanged
>>>
>>> Changes in v12:
>>> - onboard_hub driver: use IS_ENABLED(CONFIG_USB_ONBOARD_HUB_MODULE)
>>>   in onboard_hub.h to also check for the driver built as module
>>> - onboard_hub_driver: include onboard_hub.h again to make sure there
>>>   are prototype declarations for the public functions
>>>
>>> Changes in v11:
>>> - support multiple onboard hubs connected to the same parent
>>> - don't include ?onboard_hub.h? from the onboard hub driver
>>>
>>> Changes in v10:
>>> - always use of_is_onboard_usb_hub() stub unless ONBOARD_USB_HUB=y/m
>>> - keep 'regulator-boot-on' property for pp3300_hub
>>>
>>> Changes in v9:
>>> - added dependency on ONBOARD_USB_HUB (or !!ONBOARD_USB_HUB) to
>>>   USB_PLATFORM_XHCI
>>>
>>> Changes in v7:
>>> - updated DT binding
>>> - series rebased on qcom/arm64-for-5.13
>>>
>>> Changes in v6:
>>> - updated summary
>>>
>>> Changes in v5:
>>> - cover letter added
>>>
>>> Matthias Kaehlcke (6):
>>>   usb: misc: Add onboard_usb_hub driver
>>>   of/platform: Add stubs for of_platform_device_create/destroy()
>>>   arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM
>>>   usb: Specify dependencies on USB_XHCI_PLATFORM with 'depends on'
>>>   usb: host: xhci-plat: Create platform device for onboard hubs in
>>>     probe()
>>>   arm64: dts: qcom: sc7180-trogdor: Add nodes for onboard USB hub
>>>
>>>  .../sysfs-bus-platform-onboard-usb-hub        |   8 +
>>>  MAINTAINERS                                   |   7 +
>>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r0.dts |  19 +-
>>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r1.dts |  12 +-
>>>  .../arm64/boot/dts/qcom/sc7180-trogdor-r1.dts |  19 +-
>>>  arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |  19 +-
>>>  arch/arm64/configs/defconfig                  |   1 +
>>>  drivers/usb/cdns3/Kconfig                     |   2 +-
>>>  drivers/usb/dwc3/Kconfig                      |   5 +-
>>>  drivers/usb/host/Kconfig                      |   5 +-
> 
> These Kconfig changes are causing the resulting .config to be different.
> For example, if I start with omap2plus_defconfig, the resulting .config
> before and after your series is different as shown below
> 
> :/work/linux$ diff /tmp/.config .config
> 1902d1901
> < # CONFIG_HISI_HIKEY_USB is not set
> 4992c4991
> < CONFIG_USB_XHCI_PLATFORM=m
> ---
>> # CONFIG_USB_XHCI_PLATFORM is not set
> 5073,5075c5072
> < # CONFIG_USB_DWC3_HOST is not set
> < # CONFIG_USB_DWC3_GADGET is not set
> < CONFIG_USB_DWC3_DUAL_ROLE=y
> ---
>> CONFIG_USB_DWC3_GADGET=y
> 5173a5171
>> # CONFIG_USB_ONBOARD_HUB is not set
> 5285c5283
> < CONFIG_USB_ROLE_SWITCH=m
> ---
>> # CONFIG_USB_ROLE_SWITCH is not set
> 
> I would expect the same issues for multi_v7_defconfig and multi_v8_defconfig as well.

Sorry I meant defconfig for arm64, not multi_v8_defconfig.

I checked that for arm64 defconfig it is ok.

> I'm ok to update the relevant defconfigs files so that the resulting .config is identical to
> before your series. Thanks!

With the below patch you can fix it for omap2plus_defconfig and multi_v7_defconfig.

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index d9abaae118dd..8c175ab37377 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -787,6 +787,7 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_USB=y
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
 CONFIG_USB_XHCI_MVEBU=y
 CONFIG_USB_XHCI_TEGRA=m
 CONFIG_USB_EHCI_HCD=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 2ac2418084ab..a015fb04fa25 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -562,6 +562,7 @@ CONFIG_USB=m
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_MON=m
 CONFIG_USB_XHCI_HCD=m
+CONFIG_USB_XHCI_PLATFORM=m
 CONFIG_USB_EHCI_HCD=m
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_ACM=m

--
cheers,
-roger


From linus.walleij at linaro.org  Wed Aug 11 05:59:48 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 14:59:48 +0200
Subject: [PATCH V2 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <20210805174219.3000667-4-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-4-piyush.mehta@xilinx.com>
Message-ID: <CACRpkdZ=WRhTTQOvQcDEQhbf5Fone0GHopZfJhsQfsS-NRQUUw@mail.gmail.com>

Hi Piyush,

thanks for your patch!

Can you explain one thing to me: since this is now a GPIO driver
that means "General Purpos Input/Output", then these bits are
accessed like this:

On Thu, Aug 5, 2021 at 7:43 PM Piyush Mehta <piyush.mehta at xilinx.com> wrote:

> +       ret = zynqmp_pm_bootmode_read(&bootpin_val);

This does not look very general purpose. These seem to be all about
boot mode, right?

So can you explain why this should be a GPIO driver at all?

I understand it is sometimes convenient to describe stuff as GPIO even
if it is not (for example to get a convenient userspace interface) but
as maintainers
we really need to make sure that the subsystem is not being abused
for things not GPIO.

Yours,
Linus Walleij


From lkp at intel.com  Wed Aug 11 06:00:43 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 11 Aug 2021 21:00:43 +0800
Subject: [xlnx:xlnx_rebase_v5.10 1403/1760] include/linux/mtd/cfi.h:62:2:
 warning: No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
Message-ID: <202108112126.8MyNQWzX-lkp@intel.com>

Hi Amit,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   bf98c1493fb23bfd7e2678498b7e337ce2cd1d53
commit: 0ee2a65f834c5d35ad3ce580c4772d9cf7da2937 [1403/1760] spi: spi-zynq-qspi: Add dual parallal and stacked support
config: riscv-randconfig-r042-20210810 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d39ebdae674c8efc84ebe8dc32716ec353220530)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/0ee2a65f834c5d35ad3ce580c4772d9cf7da2937
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 0ee2a65f834c5d35ad3ce580c4772d9cf7da2937
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/spi/spi-mem.c:10:
   In file included from include/linux/mtd/spi-nor.h:10:
>> include/linux/mtd/cfi.h:62:2: warning: No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. [-W#warnings]
   #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
    ^
   1 warning generated.


vim +62 include/linux/mtd/cfi.h

^1da177e4c3f41 Linus Torvalds  2005-04-16  60  
241651d04d672f David Woodhouse 2007-09-06  61  #ifndef cfi_interleave
241651d04d672f David Woodhouse 2007-09-06 @62  #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
241651d04d672f David Woodhouse 2007-09-06  63  static inline int cfi_interleave(void *cfi)
241651d04d672f David Woodhouse 2007-09-06  64  {
241651d04d672f David Woodhouse 2007-09-06  65  	BUG();
241651d04d672f David Woodhouse 2007-09-06  66  	return 0;
241651d04d672f David Woodhouse 2007-09-06  67  }
241651d04d672f David Woodhouse 2007-09-06  68  #endif
241651d04d672f David Woodhouse 2007-09-06  69  

:::::: The code at line 62 was first introduced by commit
:::::: 241651d04d672fb685b2874707016cbbf95931e5 [MTD] Fix CFI build error when no map width or interleave supported

:::::: TO: David Woodhouse <dwmw2 at infradead.org>
:::::: CC: David Woodhouse <dwmw2 at infradead.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 35008 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210811/bc72a8fc/attachment-0001.gz>

From pbonzini at redhat.com  Wed Aug 11 06:05:29 2021
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Wed, 11 Aug 2021 15:05:29 +0200
Subject: [PATCH v6 00/21] KVM: Add idempotent controls for migrating
 system counter state
In-Reply-To: <20210804085819.846610-1-oupton@google.com>
References: <20210804085819.846610-1-oupton@google.com>
Message-ID: <927240ff-a4f4-fcc6-ae1b-92cefeda9e59@redhat.com>

On 04/08/21 10:57, Oliver Upton wrote:
> KVM's current means of saving/restoring system counters is plagued with
> temporal issues. At least on ARM64 and x86, we migrate the guest's
> system counter by-value through the respective guest system register
> values (cntvct_el0, ia32_tsc). Restoring system counters by-value is
> brittle as the state is not idempotent: the host system counter is still
> oscillating between the attempted save and restore. Furthermore, VMMs
> may wish to transparently live migrate guest VMs, meaning that they
> include the elapsed time due to live migration blackout in the guest
> system counter view. The VMM thread could be preempted for any number of
> reasons (scheduler, L0 hypervisor under nested) between the time that
> it calculates the desired guest counter value and when KVM actually sets
> this counter state.
> 
> Despite the value-based interface that we present to userspace, KVM
> actually has idempotent guest controls by way of system counter offsets.
> We can avoid all of the issues associated with a value-based interface
> by abstracting these offset controls in new ioctls. This series
> introduces new vCPU device attributes to provide userspace access to the
> vCPU's system counter offset.
> 
> Patch 1 addresses a possible race in KVM_GET_CLOCK where
> use_master_clock is read outside of the pvclock_gtod_sync_lock.
> 
> Patch 2 adopts Paolo's suggestion, augmenting the KVM_{GET,SET}_CLOCK
> ioctls to provide userspace with a (host_tsc, realtime) instant. This is
> essential for a VMM to perform precise migration of the guest's system
> counters.
> 
> Patches 3-4 are some preparatory changes for exposing the TSC offset to
> userspace. Patch 5 provides a vCPU attribute to provide userspace access
> to the TSC offset.
> 
> Patches 6-7 implement a test for the new additions to
> KVM_{GET,SET}_CLOCK.
> 
> Patch 8 fixes some assertions in the kvm device attribute helpers.
> 
> Patches 9-10 implement at test for the tsc offset attribute introduced in
> patch 5.

The x86 parts look good, except that patch 3 is a bit redundant with my 
idea of altogether getting rid of the pvclock_gtod_sync_lock.  That said 
I agree that patches 1 and 2 (and extracting kvm_vm_ioctl_get_clock and 
kvm_vm_ioctl_set_clock) should be done before whatever locking changes 
have to be done.

Time is ticking for 5.15 due to my vacation, I'll see if I have some 
time to look at it further next week.

I agree that arm64 can be done separately from x86.

Paolo



From linus.walleij at linaro.org  Wed Aug 11 06:08:35 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 15:08:35 +0200
Subject: [PATCH V2 1/3] firmware: zynqmp: Add MMIO read and write support
 for PS_MODE pin
In-Reply-To: <20210805174219.3000667-2-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-2-piyush.mehta@xilinx.com>
Message-ID: <CACRpkdYo5e7uTJJRqnK1R4QLtUzRGNbsvNvm-47UFZOr4_R9Cw@mail.gmail.com>

On Thu, Aug 5, 2021 at 7:42 PM Piyush Mehta <piyush.mehta at xilinx.com> wrote:

> Add Xilinx ZynqMP firmware MMIO APIs support to set and get PS_MODE
> pins value and status. These APIs create an interface path between
> mode pin controller driver and low-level API to access GPIO pins.
>
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> ---
> Changes in v2:
> - Added Xilinx ZynqMP firmware MMIO API support to set and get pin
>   value and status.

I doubt this is "GPIO".
General Purpose? I think not. It seems to be about boot mode.

If you need a userspace ABI, then add sysfs files to this firmware
driver instead of bridging it to the GPIO subsystem.

However I can be argued down from usecases etc that it is used as
GPIO but I need to push back on this.

Yours,
Linus Walleij


From tangbin at cmss.chinamobile.com  Wed Aug 11 06:15:12 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Wed, 11 Aug 2021 21:15:12 +0800
Subject: [PATCH] ARM/smp_twd: Cleanup the unnecessary cast
Message-ID: <20210811131512.940-1-tangbin@cmss.chinamobile.com>

It's not necessary to specify 'int' castingfor 'PTR_ERR(twd_clk)'.

Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 arch/arm/kernel/smp_twd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 9a14f721a..423e9079d 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -199,7 +199,7 @@ static void twd_get_clock(struct device_node *np)
 		twd_clk = clk_get_sys("smp_twd", NULL);
 
 	if (IS_ERR(twd_clk)) {
-		pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
+		pr_err("smp_twd: clock not found %d\n", PTR_ERR(twd_clk));
 		return;
 	}
 
-- 
2.20.1.windows.1





From qperret at google.com  Wed Aug 11 06:17:39 2021
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Aug 2021 14:17:39 +0100
Subject: [PATCH V2 9/9] cpufreq: scmi: Use .register_em() callback
In-Reply-To: <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
 <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
Message-ID: <YRPN8zjp1wqkHg6t@google.com>

On Wednesday 11 Aug 2021 at 17:28:47 (+0530), Viresh Kumar wrote:
> Set the newly added .register_em() callback to register with the EM
> after the cpufreq policy is properly initialized.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>  drivers/cpufreq/scmi-cpufreq.c | 55 ++++++++++++++++++++--------------
>  1 file changed, 32 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
> index 75f818d04b48..b916c9e22921 100644
> --- a/drivers/cpufreq/scmi-cpufreq.c
> +++ b/drivers/cpufreq/scmi-cpufreq.c
> @@ -22,7 +22,9 @@
>  
>  struct scmi_data {
>  	int domain_id;
> +	int nr_opp;
>  	struct device *cpu_dev;
> +	cpumask_var_t opp_shared_cpus;

Can we use policy->related_cpus and friends directly in the callback
instead? That should simplify the patch a bit.

Also, we can probably afford calling dev_pm_opp_get_opp_count() from the
em_register callback as it is not a hot path, which would avoid wasting
some 'resident' memory here that is only used during init.

Thanks,
Quentin


From wsa+renesas at sang-engineering.com  Wed Aug 11 06:24:23 2021
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Wed, 11 Aug 2021 15:24:23 +0200
Subject: [PATCH 1/7] i2c: at91-master: : use proper DMAENGINE API for
 termination
In-Reply-To: <20210623095942.3325-2-wsa+renesas@sang-engineering.com>
References: <20210623095942.3325-1-wsa+renesas@sang-engineering.com>
 <20210623095942.3325-2-wsa+renesas@sang-engineering.com>
Message-ID: <YRPPh6ucRfL/gGZG@shikoro>

On Wed, Jun 23, 2021 at 11:59:35AM +0200, Wolfram Sang wrote:
> dmaengine_terminate_all() is deprecated in favor of explicitly saying if
> it should be sync or async. Here, we want dmaengine_terminate_sync()
> because there is no other synchronization code in the driver to handle
> an async case.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210811/2bf4fd99/attachment-0001.sig>

From wsa+renesas at sang-engineering.com  Wed Aug 11 06:24:29 2021
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Wed, 11 Aug 2021 15:24:29 +0200
Subject: [PATCH 2/7] i2c: imx: : use proper DMAENGINE API for termination
In-Reply-To: <20210623095942.3325-3-wsa+renesas@sang-engineering.com>
References: <20210623095942.3325-1-wsa+renesas@sang-engineering.com>
 <20210623095942.3325-3-wsa+renesas@sang-engineering.com>
Message-ID: <YRPPjYkEI0g4YWe/@shikoro>

On Wed, Jun 23, 2021 at 11:59:36AM +0200, Wolfram Sang wrote:
> dmaengine_terminate_all() is deprecated in favor of explicitly saying if
> it should be sync or async. Here, we want dmaengine_terminate_sync()
> because there is no other synchronization code in the driver to handle
> an async case.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210811/2b969f3b/attachment.sig>

From wsa+renesas at sang-engineering.com  Wed Aug 11 06:24:33 2021
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Wed, 11 Aug 2021 15:24:33 +0200
Subject: [PATCH 3/7] i2c: mxs: : use proper DMAENGINE API for termination
In-Reply-To: <20210623095942.3325-4-wsa+renesas@sang-engineering.com>
References: <20210623095942.3325-1-wsa+renesas@sang-engineering.com>
 <20210623095942.3325-4-wsa+renesas@sang-engineering.com>
Message-ID: <YRPPkVBcDKeCEP41@shikoro>

On Wed, Jun 23, 2021 at 11:59:37AM +0200, Wolfram Sang wrote:
> dmaengine_terminate_all() is deprecated in favor of explicitly saying if
> it should be sync or async. Here, we want dmaengine_terminate_sync()
> because there is no other synchronization code in the driver to handle
> an async case.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210811/28b46210/attachment.sig>

From wsa+renesas at sang-engineering.com  Wed Aug 11 06:26:17 2021
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Wed, 11 Aug 2021 15:26:17 +0200
Subject: [PATCH 0/7] i2c: use proper DMAENGINE API for termination
In-Reply-To: <20210623095942.3325-1-wsa+renesas@sang-engineering.com>
References: <20210623095942.3325-1-wsa+renesas@sang-engineering.com>
Message-ID: <YRPP+f1tZXVSJ0Tb@shikoro>

On Wed, Jun 23, 2021 at 11:59:34AM +0200, Wolfram Sang wrote:
> dmaengine_terminate_all() is deprecated in favor of explicitly saying if
> it should be sync or async. Update the drivers I audited.

I applied the patches now, except for i2c-rcar and i2c-stm32f7 where
this approach can't be used because of interrupt context. I will check
for i2c-rcar how to do this properly and Alain for i2c-stm32f7 and we
will resend then.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210811/34d59390/attachment.sig>

From michal.simek at xilinx.com  Wed Aug 11 06:29:46 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Wed, 11 Aug 2021 15:29:46 +0200
Subject: [PATCH V2 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <CACRpkdZ=WRhTTQOvQcDEQhbf5Fone0GHopZfJhsQfsS-NRQUUw@mail.gmail.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-4-piyush.mehta@xilinx.com>
 <CACRpkdZ=WRhTTQOvQcDEQhbf5Fone0GHopZfJhsQfsS-NRQUUw@mail.gmail.com>
Message-ID: <974df9ef-6cdb-cb7b-2b9d-2eddaf1171f7@xilinx.com>

Hi Linus,

On 8/11/21 2:59 PM, Linus Walleij wrote:
> Hi Piyush,
> 
> thanks for your patch!
> 
> Can you explain one thing to me: since this is now a GPIO driver
> that means "General Purpos Input/Output", then these bits are
> accessed like this:
> 
> On Thu, Aug 5, 2021 at 7:43 PM Piyush Mehta <piyush.mehta at xilinx.com> wrote:
> 
>> +       ret = zynqmp_pm_bootmode_read(&bootpin_val);
> 
> This does not look very general purpose. These seem to be all about
> boot mode, right?
> 
> So can you explain why this should be a GPIO driver at all?
> 
> I understand it is sometimes convenient to describe stuff as GPIO even
> if it is not (for example to get a convenient userspace interface) but
> as maintainers
> we really need to make sure that the subsystem is not being abused
> for things not GPIO.

They are bootmode pins because that pins are designed and used by ROM to
get information which boot device should be used.
But after this is it is really behaving as generic purpose I/O pins.
Xilinx is using them for years for usb phy resets. I have also seen them
to be used for other reset functionality.
And that's exactly what we are trying to do here by this driver. Because
usb hubs/phys have reset normally connected via gpio pin which is
toggled. And we have boards where these resets are connected via these
pins or via hard gpio IP or via i2c-gpio expanders that's why IMHO this
option should be designed in the same way to have gpio reset
functionality added dwc3 and based on DT/board bootmode gpio, ps gpio,
pl gpio, i2c gpio or gpio over power regulators, etc will be used.

Please let me know if you want to get more information about it.

Thanks,
Michal



From lutovinova at ispras.ru  Wed Aug 11 06:32:28 2021
From: lutovinova at ispras.ru (Nadezda Lutovinova)
Date: Wed, 11 Aug 2021 16:32:28 +0300
Subject: [PATCH] media: s5p-mfc: Add checking to s5p_mfc_probe().
Message-ID: <20210811133228.14657-1-lutovinova@ispras.ru>

If of_device_get_match_data() return NULL,
then null pointer dereference occurs in  s5p_mfc_init_pm().
The patch adds checking if dev->variant is NULL.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Nadezda Lutovinova <lutovinova at ispras.ru>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index eba2b9f040df..b56ff75cb9cc 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1288,6 +1288,10 @@ static int s5p_mfc_probe(struct platform_device *pdev)
 	}
 
 	dev->variant = of_device_get_match_data(&pdev->dev);
+	if (!dev->variant) {
+		dev_err(&pdev->dev, "Failed to get device MFC hardware variant information\n");
+		return -ENOENT;
+	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
-- 
2.17.1



From linux at armlinux.org.uk  Wed Aug 11 06:31:22 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 11 Aug 2021 14:31:22 +0100
Subject: [PATCH] ARM/smp_twd: Cleanup the unnecessary cast
In-Reply-To: <20210811131512.940-1-tangbin@cmss.chinamobile.com>
References: <20210811131512.940-1-tangbin@cmss.chinamobile.com>
Message-ID: <20210811133121.GV22278@shell.armlinux.org.uk>

On Wed, Aug 11, 2021 at 09:15:12PM +0800, Tang Bin wrote:
> It's not necessary to specify 'int' castingfor 'PTR_ERR(twd_clk)'.
> 
> Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
> ---
>  arch/arm/kernel/smp_twd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
> index 9a14f721a..423e9079d 100644
> --- a/arch/arm/kernel/smp_twd.c
> +++ b/arch/arm/kernel/smp_twd.c
> @@ -199,7 +199,7 @@ static void twd_get_clock(struct device_node *np)
>  		twd_clk = clk_get_sys("smp_twd", NULL);
>  
>  	if (IS_ERR(twd_clk)) {
> -		pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
> +		pr_err("smp_twd: clock not found %d\n", PTR_ERR(twd_clk));

Sorry, NAK.

This change _will_ produce a compiler warning. "%d" expects an argument
of type "int", but PTR_ERR() returns a type of "long". Sorry, but the
cast is entirely necessary.

A better solution today would be to get rid of the PTR_ERR() entirely
and use %pe, which will get us a textual description of the error when
the appropriate kernel configuration option is enabled.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linus.walleij at linaro.org  Wed Aug 11 06:33:37 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 15:33:37 +0200
Subject: [PATCH] MAINTAINERS: adjust ARM/NOMADIK/Ux500 ARCHITECTURES to
 file renaming
In-Reply-To: <20210810191724.24452-1-lukas.bulwahn@gmail.com>
References: <20210810191724.24452-1-lukas.bulwahn@gmail.com>
Message-ID: <CACRpkdaoheT3b8oZkQCUOVw9bdioG+b5BW4T5-Hj8dHoD5yX0Q@mail.gmail.com>

On Tue, Aug 10, 2021 at 9:17 PM Lukas Bulwahn <lukas.bulwahn at gmail.com> wrote:

> Commit 8f00b3c41ae7 ("mfd: db8500-prcmu: Rename register header") renames
> dbx500-prcmu-regs.h to db8500-prcmu-regs.h in ./drivers/mfd/, but misses
> to adjust the ARM/NOMADIK/Ux500 ARCHITECTURES section in MAINTAINERS.
>
> Hence, ./scripts/get_maintainer.pl --self-test=patterns complains:
>
>   warning: no file matches    F:    drivers/mfd/dbx500*
>
> Remove the obsolete file entry after this file renaming.
>
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
> ---
> applies cleanly on next-20210810
>
> Linus, Lee, please pick this patch on your -next tree on top of the patch
> mentioned above.

Thanks for fixing this Lukas, I see Lee already applied the patch!

Yours,
Linus Walleij


From Codrin.Ciubotariu at microchip.com  Wed Aug 11 06:34:44 2021
From: Codrin.Ciubotariu at microchip.com (Codrin.Ciubotariu at microchip.com)
Date: Wed, 11 Aug 2021 13:34:44 +0000
Subject: [PATCH 1/7] i2c: at91-master: : use proper DMAENGINE API for
 termination
In-Reply-To: <YRPPh6ucRfL/gGZG@shikoro>
References: <20210623095942.3325-1-wsa+renesas@sang-engineering.com>
 <20210623095942.3325-2-wsa+renesas@sang-engineering.com>
 <YRPPh6ucRfL/gGZG@shikoro>
Message-ID: <de55cf2e-e97d-276a-838f-4ed432928411@microchip.com>

On 11.08.2021 16:24, Wolfram Sang wrote:
> On Wed, Jun 23, 2021 at 11:59:35AM +0200, Wolfram Sang wrote:
>> dmaengine_terminate_all() is deprecated in favor of explicitly saying if
>> it should be sync or async. Here, we want dmaengine_terminate_sync()
>> because there is no other synchronization code in the driver to handle
>> an async case.
>>
>> Signed-off-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
> 
> Applied to for-next, thanks!
> 

just saw it now, there is a double : :  in the subject. Maybe you could 
fix it if it's not too late...

Thanks and best regards,
Codrin


From arnd at arndb.de  Wed Aug 11 06:46:23 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 11 Aug 2021 15:46:23 +0200
Subject: [PATCH V2 1/3] firmware: zynqmp: Add MMIO read and write support
 for PS_MODE pin
In-Reply-To: <CACRpkdYo5e7uTJJRqnK1R4QLtUzRGNbsvNvm-47UFZOr4_R9Cw@mail.gmail.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-2-piyush.mehta@xilinx.com>
 <CACRpkdYo5e7uTJJRqnK1R4QLtUzRGNbsvNvm-47UFZOr4_R9Cw@mail.gmail.com>
Message-ID: <CAK8P3a3ZdZSdiX6_AeSW4qSFhUp+wKrUe6S5z5bKDtcU068sjQ@mail.gmail.com>

On Wed, Aug 11, 2021 at 3:08 PM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Thu, Aug 5, 2021 at 7:42 PM Piyush Mehta <piyush.mehta at xilinx.com> wrote:
>
> > Add Xilinx ZynqMP firmware MMIO APIs support to set and get PS_MODE
> > pins value and status. These APIs create an interface path between
> > mode pin controller driver and low-level API to access GPIO pins.
> >
> > Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> > ---
> > Changes in v2:
> > - Added Xilinx ZynqMP firmware MMIO API support to set and get pin
> >   value and status.
>
> I doubt this is "GPIO".
> General Purpose? I think not. It seems to be about boot mode.

Agreed.

> If you need a userspace ABI, then add sysfs files to this firmware
> driver instead of bridging it to the GPIO subsystem.

I don't really want custom user interfaces in firmware drivers either.

What is the high-level description of the 'PS_MODE' here? Is
this perhaps something we already have a user interface for?

       Arnd


From tangbin at cmss.chinamobile.com  Wed Aug 11 06:47:10 2021
From: tangbin at cmss.chinamobile.com (tangbin)
Date: Wed, 11 Aug 2021 21:47:10 +0800
Subject: [PATCH] ARM/smp_twd: Cleanup the unnecessary cast
In-Reply-To: <20210811133121.GV22278@shell.armlinux.org.uk>
References: <20210811131512.940-1-tangbin@cmss.chinamobile.com>
 <20210811133121.GV22278@shell.armlinux.org.uk>
Message-ID: <54505b20-a9c6-9ade-dced-cb4c24df0770@cmss.chinamobile.com>

Hi Russell:

On 2021/8/11 21:31, Russell King (Oracle) wrote:
> On Wed, Aug 11, 2021 at 09:15:12PM +0800, Tang Bin wrote:
>> It's not necessary to specify 'int' castingfor 'PTR_ERR(twd_clk)'.
>>
>> Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
>> ---
>>   arch/arm/kernel/smp_twd.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
>> index 9a14f721a..423e9079d 100644
>> --- a/arch/arm/kernel/smp_twd.c
>> +++ b/arch/arm/kernel/smp_twd.c
>> @@ -199,7 +199,7 @@ static void twd_get_clock(struct device_node *np)
>>   		twd_clk = clk_get_sys("smp_twd", NULL);
>>   
>>   	if (IS_ERR(twd_clk)) {
>> -		pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
>> +		pr_err("smp_twd: clock not found %d\n", PTR_ERR(twd_clk));
> Sorry, NAK.
>
> This change _will_ produce a compiler warning. "%d" expects an argument
> of type "int", but PTR_ERR() returns a type of "long". Sorry, but the
> cast is entirely necessary.
>
> A better solution today would be to get rid of the PTR_ERR() entirely
> and use %pe, which will get us a textual description of the error when
> the appropriate kernel configuration option is enabled.
>
Got it, Thanks.
>




From mark.rutland at arm.com  Wed Aug 11 06:55:58 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 11 Aug 2021 14:55:58 +0100
Subject: [PATCH][boot-wrapper] aarch64: Enable ECV to allow access to
 CNTPOFF_EL2
In-Reply-To: <20210811092226.2316583-1-maz@kernel.org>
References: <20210811092226.2316583-1-maz@kernel.org>
Message-ID: <20210811135558.GB72303@C02TD0UTHF1T.local>

On Wed, Aug 11, 2021 at 10:22:26AM +0100, Marc Zyngier wrote:
> If the implemnentation supports ID_AA64MMFR0_EL1.ECV==2,
> set SCR_EL3.ECVEn to allow EL2 access to CNTPOFF_EL2.

I was about to ask if that was a typo (why is this in an MMFR?), but
that is what the ARM ARM says!

> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/aarch64/boot.S | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 7f208b5..f0aa3cb 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -54,10 +54,17 @@ ASM_FUNC(_start)
>  1:
>  	/* Enable FGT if present */
>  	mrs	x1, id_aa64mmfr0_el1
> -	ubfx	x1, x1, #56, #4
> -	cbz	x1, 1f
> +	ubfx	x2, x1, #56, #4
> +	cbz	x2, 1f
>  
>  	orr	x0, x0, #(1 << 27)		// FGT enable
> +1:
> +	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
> +	ubfx	x2, x1, #60, #4
> +	cmp	x2, #2
> +	bne	1f

We need to check ID_AA64MMFR0_EL1.ECV >= 2 (to handle any futrue
variants) so the conditional branch needs to be something like `b.lt`.

> +
> +	orr	x0, x0, #(1 << 28)		// ECV enable

Aside from the above, this looks good to me, and I plan to apply this
with the below tweaks (updated patch below):

* Use b.lt, as above

* To keep each check self-contained, the ECV check will read
  id_aa64mmfr0_el1 itself. That removes the need to keep x1 around, and
  so we can leave the FGT check as-is.

  As part of some cleanup, I'm planning to move this to C, where feature
  checks will read ID fields via a helepr that implicitly reads the
  register, like:

  if (read_reg_field(ID_AA64MMFR0_EL1, ECV) >= 2)
  	scr |= SCR_EL3_ECVEN;

Thanks,
Mark.
---->8----
>From bc6a9380eb3c5afc96735a54d455f2487df48700 Mon Sep 17 00:00:00 2001
From: Marc Zyngier <maz at kernel.org>
Date: Wed, 11 Aug 2021 10:22:26 +0100
Subject: [PATCH] aarch64: Enable ECV to allow access to CNTPOFF_EL2

If the implemnentation supports ID_AA64MMFR0_EL1.ECV==2,
set SCR_EL3.ECVEn to allow EL2 access to CNTPOFF_EL2.

Signed-off-by: Marc Zyngier <maz at kernel.org>
[Mark: read id_aa64mmfr0_el1 separately, s/bne/b.lt/]
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch64/boot.S | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 7f208b5..2215f7e 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -59,6 +59,14 @@ ASM_FUNC(_start)
 
 	orr	x0, x0, #(1 << 27)		// FGT enable
 1:
+	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
+	mrs	x1, id_aa64mmfr0_el1
+	ubfx	x1, x1, #60, #4
+	cmp	x1, #2
+	b.lt	1f
+
+	orr	x0, x0, #(1 << 28)		// ECV enable
+1:
 	/* Enable MTE if present */
 	mrs	x10, id_aa64pfr1_el1
 	ubfx	x10, x10, #8, #4
-- 
2.11.0



From dsahern at gmail.com  Wed Aug 11 06:56:59 2021
From: dsahern at gmail.com (David Ahern)
Date: Wed, 11 Aug 2021 07:56:59 -0600
Subject: [PATCH net-next v3] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <20210810123327.15998-1-rocco.yue@mediatek.com>
References: <c0a6f817-0225-c863-722c-19c798daaa4b@gmail.com>
 <20210810123327.15998-1-rocco.yue@mediatek.com>
Message-ID: <25dcf6e8-cdd6-6339-f499-5c3100a7d8c4@gmail.com>

On 8/10/21 6:33 AM, Rocco Yue wrote:
> On Mon, 2021-08-09 at 16:43 -0600, David Ahern wrote:
>> On 8/9/21 8:01 AM, Rocco Yue wrote:
> 
>> +
>>>  #ifdef CONFIG_SYSCTL
>>>  
>>>  static int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
>>> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
>>> index c467c6419893..a04164cbd77f 100644
>>> --- a/net/ipv6/ndisc.c
>>> +++ b/net/ipv6/ndisc.c
>>> @@ -1496,6 +1496,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
>>>  		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
>>>  		mtu = ntohl(n);
>>>  
>>> +		if (in6_dev->ra_mtu != mtu) {
>>> +			in6_dev->ra_mtu = mtu;
>>> +			inet6_iframtu_notify(in6_dev);
>>> +			ND_PRINTK(2, info, "update ra_mtu to %d\n", in6_dev->ra_mtu);
>>> +		}
>>> +
>>>  		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
>>>  			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
>>>  		} else if (in6_dev->cnf.mtu6 != mtu) {
>>
>> Since this MTU is getting reported via af_info infrastructure,
>> rtmsg_ifinfo should be sufficient.
>>
>> From there use 'ip monitor' to make sure you are not generating multiple
>> notifications; you may only need this on the error path.
> 
> Hi David,
> 
> To avoid generating multiple notifications, I added a separate ramtu notify
> function in this patch, and I added RTNLGRP_IPV6_IFINFO nl_mgrp to the ipmonitor.c
> to verify this patch was as expected.
> 
> I look at the rtmsg_ifinfo code, it should be appropriate and I will use it and
> verify it.
> 
> But there's one thing, I'm sorry I didn't fully understand the meaning of this
> sentence "you may only need this on the error path". Honestly, I'm not sure what
> the error patch refers to, do you mean "if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu)" ?
> 

looks like nothing under:
    if (ndopts.nd_opts_mtu && in6_dev->cnf.accept_ra_mtu) {

    }

is going to send a link notification so you can just replace
inet6_iframtu_notify with rtmsg_ifinfo in your proposed change.


From lorenzo.pieralisi at arm.com  Wed Aug 11 07:01:57 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 11 Aug 2021 15:01:57 +0100
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
 <YRKtEDycefrZLB3X@infradead.org>
 <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
Message-ID: <20210811140157.GA28658@e123427-lin.cambridge.arm.com>

On Wed, Aug 11, 2021 at 12:40:28PM +0200, Ard Biesheuvel wrote:
> On Tue, 10 Aug 2021 at 18:46, Christoph Hellwig <hch at infradead.org> wrote:
> >
> > On Mon, Aug 02, 2021 at 04:23:57PM +0100, Lorenzo Pieralisi wrote:
> > > Add a __force attribute to the void* cast in acpi_os_map_iomem()
> > > to prevent sparse warnings.
> >
> > Err, no.  These annotation are there for a reason and need to
> > be propagated instead.  And independent of that a __force cast
> > without a comment explaining it is a complete no-go.
> 
> The whole problem we are solving here is that ACPI, being based on
> x86, conflates MMIO mappings with memory mappings, and has been using
> the same underlying infrastructure for either. On arm64, this is not
> sufficient, given that the semantics of uncached memory vs device are
> different (the former permits unaligned accesses and clear cacheline
> instructions, but the latter doesn't). A recent optimization applied
> to memcpy() on arm64 (which now relies more on unaligned accesses for
> performance) has uncovered an issue where firmware tables being mapped
> non-cacheable by the ACPI core will end up using device mappings,
> which causes memcpy() to choke on their contents.
> 
> So propagating the annotation makes no sense, as we are creating a
> memory mapping using the iomem primitive. I wouldn't object to a
> comment being added, but I think the context should have been obvious
> to anyone who had bothered to look at the entire series.

I can add a comment and respin. Basically a __force attribute is
added to ignore a sparse warning that's been ignored for aeons
anyway - I will add the rationale above.

drivers/acpi/osl.c:379:17: warning: cast removes address space '__iomem' of expression


From michal.simek at xilinx.com  Wed Aug 11 07:04:28 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Wed, 11 Aug 2021 16:04:28 +0200
Subject: [PATCH V2 1/3] firmware: zynqmp: Add MMIO read and write support
 for PS_MODE pin
In-Reply-To: <CAK8P3a3ZdZSdiX6_AeSW4qSFhUp+wKrUe6S5z5bKDtcU068sjQ@mail.gmail.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-2-piyush.mehta@xilinx.com>
 <CACRpkdYo5e7uTJJRqnK1R4QLtUzRGNbsvNvm-47UFZOr4_R9Cw@mail.gmail.com>
 <CAK8P3a3ZdZSdiX6_AeSW4qSFhUp+wKrUe6S5z5bKDtcU068sjQ@mail.gmail.com>
Message-ID: <6f067aa8-27e2-3579-54e5-419f940f628d@xilinx.com>

Hi Arnd,

On 8/11/21 3:46 PM, Arnd Bergmann wrote:
> On Wed, Aug 11, 2021 at 3:08 PM Linus Walleij <linus.walleij at linaro.org> wrote:
>>
>> On Thu, Aug 5, 2021 at 7:42 PM Piyush Mehta <piyush.mehta at xilinx.com> wrote:
>>
>>> Add Xilinx ZynqMP firmware MMIO APIs support to set and get PS_MODE
>>> pins value and status. These APIs create an interface path between
>>> mode pin controller driver and low-level API to access GPIO pins.
>>>
>>> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
>>> ---
>>> Changes in v2:
>>> - Added Xilinx ZynqMP firmware MMIO API support to set and get pin
>>>   value and status.
>>
>> I doubt this is "GPIO".
>> General Purpose? I think not. It seems to be about boot mode.
> 
> Agreed.

here is register description.

https://www.xilinx.com/html_docs/registers/ug1087/crl_apb___boot_pin_ctrl.html#

> 
>> If you need a userspace ABI, then add sysfs files to this firmware
>> driver instead of bridging it to the GPIO subsystem.
> 
> I don't really want custom user interfaces in firmware drivers either.
> 
> What is the high-level description of the 'PS_MODE' here? Is
> this perhaps something we already have a user interface for?

The reason why this can't be mapped as memory mapped device is that it
is in IP which has be secure. That's why routing is done via firmware
driver.

Based on
https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf

page 46

PS_MODE Input/Output Dedicated 4-bit boot mode pins sampled on POR
deassertion

It means ROM just capture boot mode at start that's why they have
special meaning and after it is free to use for whatever purpose you
want which seems to pretty much as generic purpose I/O.

I wrote more comments in reply to Linus already.

Thanks,
Michal


From lukasz.luba at arm.com  Wed Aug 11 07:09:13 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Wed, 11 Aug 2021 15:09:13 +0100
Subject: [PATCH V2 9/9] cpufreq: scmi: Use .register_em() callback
In-Reply-To: <YRPN8zjp1wqkHg6t@google.com>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
 <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
 <YRPN8zjp1wqkHg6t@google.com>
Message-ID: <b02cff82-d242-f783-6f29-78e734f78e26@arm.com>



On 8/11/21 2:17 PM, Quentin Perret wrote:
> On Wednesday 11 Aug 2021 at 17:28:47 (+0530), Viresh Kumar wrote:
>> Set the newly added .register_em() callback to register with the EM
>> after the cpufreq policy is properly initialized.
>>
>> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
>> ---
>>   drivers/cpufreq/scmi-cpufreq.c | 55 ++++++++++++++++++++--------------
>>   1 file changed, 32 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
>> index 75f818d04b48..b916c9e22921 100644
>> --- a/drivers/cpufreq/scmi-cpufreq.c
>> +++ b/drivers/cpufreq/scmi-cpufreq.c
>> @@ -22,7 +22,9 @@
>>   
>>   struct scmi_data {
>>   	int domain_id;
>> +	int nr_opp;
>>   	struct device *cpu_dev;
>> +	cpumask_var_t opp_shared_cpus;
> 
> Can we use policy->related_cpus and friends directly in the callback

Unfortunately not. This tricky setup code was introduced because we may
have a platform with per-CPU policy, so single bit set in
policy->related_cpus, but we want EAS to be still working on set
of CPUs. That's why we construct temporary cpumask and pass it to EM.

> instead? That should simplify the patch a bit.
> 
> Also, we can probably afford calling dev_pm_opp_get_opp_count() from the
> em_register callback as it is not a hot path, which would avoid wasting
> some 'resident' memory here that is only used during init.
> 
> Thanks,
> Quentin
> 


From hch at infradead.org  Wed Aug 11 07:08:24 2021
From: hch at infradead.org (Christoph Hellwig)
Date: Wed, 11 Aug 2021 15:08:24 +0100
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
 <YRKtEDycefrZLB3X@infradead.org>
 <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
Message-ID: <YRPZ2Kqb/MFggHzQ@infradead.org>

On Wed, Aug 11, 2021 at 12:40:28PM +0200, Ard Biesheuvel wrote:
> The whole problem we are solving here is that ACPI, being based on
> x86, conflates MMIO mappings with memory mappings, and has been using
> the same underlying infrastructure for either.

So let's fix that problem instead of papering over it.


From andrew at lunn.ch  Wed Aug 11 07:20:56 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 11 Aug 2021 16:20:56 +0200
Subject: [PATCH net-next 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <f2a1f135-b77a-403d-5d2e-c497efc99df7@gmail.com>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
 <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
 <YREvDRkiuScyN8Ws@lunn.ch> <20210810235529.GB30818@linux.intel.com>
 <f2a1f135-b77a-403d-5d2e-c497efc99df7@gmail.com>
Message-ID: <YRPcyHTc2FJeEoqk@lunn.ch>

> > BIOS does configured the SerDes. The problem here is that all the
> > configurations done by BIOS are being reset at xpcs_create().
> > 
> > We would want user of the pcs-xpcs module (stmmac, sja1105) to have
> > control whether or not we need to perform to the soft reset in the
> > xpcs_create() call.
> 
> I understood Andrew's response as suggesting to introduce the ability for
> xpcs_create() to make a BIOS call which would configure the SerDes after
> xpcs_soft_reset().

Yes. Exactly. That is what ACPI is for, so we should use it for this.

     Andrew


From qperret at google.com  Wed Aug 11 07:39:31 2021
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Aug 2021 15:39:31 +0100
Subject: [PATCH V2 9/9] cpufreq: scmi: Use .register_em() callback
In-Reply-To: <b02cff82-d242-f783-6f29-78e734f78e26@arm.com>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
 <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
 <YRPN8zjp1wqkHg6t@google.com>
 <b02cff82-d242-f783-6f29-78e734f78e26@arm.com>
Message-ID: <YRPhI3AOAJLpQnjT@google.com>

On Wednesday 11 Aug 2021 at 15:09:13 (+0100), Lukasz Luba wrote:
> 
> 
> On 8/11/21 2:17 PM, Quentin Perret wrote:
> > On Wednesday 11 Aug 2021 at 17:28:47 (+0530), Viresh Kumar wrote:
> > > Set the newly added .register_em() callback to register with the EM
> > > after the cpufreq policy is properly initialized.
> > > 
> > > Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> > > ---
> > >   drivers/cpufreq/scmi-cpufreq.c | 55 ++++++++++++++++++++--------------
> > >   1 file changed, 32 insertions(+), 23 deletions(-)
> > > 
> > > diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
> > > index 75f818d04b48..b916c9e22921 100644
> > > --- a/drivers/cpufreq/scmi-cpufreq.c
> > > +++ b/drivers/cpufreq/scmi-cpufreq.c
> > > @@ -22,7 +22,9 @@
> > >   struct scmi_data {
> > >   	int domain_id;
> > > +	int nr_opp;
> > >   	struct device *cpu_dev;
> > > +	cpumask_var_t opp_shared_cpus;
> > 
> > Can we use policy->related_cpus and friends directly in the callback
> 
> Unfortunately not. This tricky setup code was introduced because we may
> have a platform with per-CPU policy, so single bit set in
> policy->related_cpus, but we want EAS to be still working on set
> of CPUs. That's why we construct temporary cpumask and pass it to EM.

Aha, I see this now. Hmm, those platforms better have AMUs then,
otherwise PELT signals will be wonky ...

I was going to suggest using dev_pm_opp_get_sharing_cpus() from the
callback instead, but maybe that's overkill as we'd need to allocate a
temporary cpumask and all. So n/m this patch should be fine as is.


From linus.walleij at linaro.org  Wed Aug 11 07:45:04 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 16:45:04 +0200
Subject: [PATCH V2 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <974df9ef-6cdb-cb7b-2b9d-2eddaf1171f7@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-4-piyush.mehta@xilinx.com>
 <CACRpkdZ=WRhTTQOvQcDEQhbf5Fone0GHopZfJhsQfsS-NRQUUw@mail.gmail.com>
 <974df9ef-6cdb-cb7b-2b9d-2eddaf1171f7@xilinx.com>
Message-ID: <CACRpkdZ5owo0rfOqysLpu+La+0p5SgNkjW6OFbG9tsOmtNJEtA@mail.gmail.com>

On Wed, Aug 11, 2021 at 3:30 PM Michal Simek <michal.simek at xilinx.com> wrote:

> They are bootmode pins because that pins are designed and used by ROM to
> get information which boot device should be used.
> But after this is it is really behaving as generic purpose I/O pins.
> Xilinx is using them for years for usb phy resets. I have also seen them
> to be used for other reset functionality.

OK if they are used for general purpose tasks then a GPIO driver
is fine, I was worried that it was just a way to read these pins from
userspace.

Go ahead with this patch series!

Yours,
Linus Walleij


From maz at kernel.org  Wed Aug 11 07:45:21 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 15:45:21 +0100
Subject: [PATCH][boot-wrapper] aarch64: Enable ECV to allow access to
 CNTPOFF_EL2
In-Reply-To: <20210811135558.GB72303@C02TD0UTHF1T.local>
References: <20210811092226.2316583-1-maz@kernel.org>
 <20210811135558.GB72303@C02TD0UTHF1T.local>
Message-ID: <87lf589h1a.wl-maz@kernel.org>

On Wed, 11 Aug 2021 14:55:58 +0100,
Mark Rutland <mark.rutland at arm.com> wrote:
> 
> On Wed, Aug 11, 2021 at 10:22:26AM +0100, Marc Zyngier wrote:
> > If the implemnentation supports ID_AA64MMFR0_EL1.ECV==2,
> > set SCR_EL3.ECVEn to allow EL2 access to CNTPOFF_EL2.
> 
> I was about to ask if that was a typo (why is this in an MMFR?), but
> that is what the ARM ARM says!

I was just as surprised. PFR would have made a lot more sense, but I
guess someone wanted to use these last four bits as quickly as
possible... ;-)

> 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/aarch64/boot.S | 11 +++++++++--
> >  1 file changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> > index 7f208b5..f0aa3cb 100644
> > --- a/arch/aarch64/boot.S
> > +++ b/arch/aarch64/boot.S
> > @@ -54,10 +54,17 @@ ASM_FUNC(_start)
> >  1:
> >  	/* Enable FGT if present */
> >  	mrs	x1, id_aa64mmfr0_el1
> > -	ubfx	x1, x1, #56, #4
> > -	cbz	x1, 1f
> > +	ubfx	x2, x1, #56, #4
> > +	cbz	x2, 1f
> >  
> >  	orr	x0, x0, #(1 << 27)		// FGT enable
> > +1:
> > +	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
> > +	ubfx	x2, x1, #60, #4
> > +	cmp	x2, #2
> > +	bne	1f
> 
> We need to check ID_AA64MMFR0_EL1.ECV >= 2 (to handle any futrue
> variants) so the conditional branch needs to be something like `b.lt`.

Good point. I'm surprised ECV3 hasn't hit yet! :D

> > +
> > +	orr	x0, x0, #(1 << 28)		// ECV enable
> 
> Aside from the above, this looks good to me, and I plan to apply this
> with the below tweaks (updated patch below):
> 
> * Use b.lt, as above
> 
> * To keep each check self-contained, the ECV check will read
>   id_aa64mmfr0_el1 itself. That removes the need to keep x1 around, and
>   so we can leave the FGT check as-is.
> 
>   As part of some cleanup, I'm planning to move this to C, where feature
>   checks will read ID fields via a helepr that implicitly reads the
>   register, like:
> 
>   if (read_reg_field(ID_AA64MMFR0_EL1, ECV) >= 2)
>   	scr |= SCR_EL3_ECVEN;

If you are actively rewriting this, maybe don't bother with the patch
and just add this as part of your rewrite.

> 
> Thanks,
> Mark.
> ---->8----
> From bc6a9380eb3c5afc96735a54d455f2487df48700 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <maz at kernel.org>
> Date: Wed, 11 Aug 2021 10:22:26 +0100
> Subject: [PATCH] aarch64: Enable ECV to allow access to CNTPOFF_EL2
> 
> If the implemnentation supports ID_AA64MMFR0_EL1.ECV==2,
> set SCR_EL3.ECVEn to allow EL2 access to CNTPOFF_EL2.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> [Mark: read id_aa64mmfr0_el1 separately, s/bne/b.lt/]
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  arch/aarch64/boot.S | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 7f208b5..2215f7e 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -59,6 +59,14 @@ ASM_FUNC(_start)
>  
>  	orr	x0, x0, #(1 << 27)		// FGT enable
>  1:
> +	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
> +	mrs	x1, id_aa64mmfr0_el1
> +	ubfx	x1, x1, #60, #4
> +	cmp	x1, #2
> +	b.lt	1f
> +
> +	orr	x0, x0, #(1 << 28)		// ECV enable
> +1:
>  	/* Enable MTE if present */
>  	mrs	x10, id_aa64pfr1_el1
>  	ubfx	x10, x10, #8, #4

Otherwise looks fine to me.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From mark.rutland at arm.com  Wed Aug 11 07:49:23 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 11 Aug 2021 15:49:23 +0100
Subject: [PATCH][boot-wrapper] aarch64: Enable ECV to allow access to
 CNTPOFF_EL2
In-Reply-To: <87lf589h1a.wl-maz@kernel.org>
References: <20210811092226.2316583-1-maz@kernel.org>
 <20210811135558.GB72303@C02TD0UTHF1T.local>
 <87lf589h1a.wl-maz@kernel.org>
Message-ID: <20210811144923.GC72303@C02TD0UTHF1T.local>

On Wed, Aug 11, 2021 at 03:45:21PM +0100, Marc Zyngier wrote:
> On Wed, 11 Aug 2021 14:55:58 +0100,
> Mark Rutland <mark.rutland at arm.com> wrote:
> > 
> > On Wed, Aug 11, 2021 at 10:22:26AM +0100, Marc Zyngier wrote:
> > > If the implemnentation supports ID_AA64MMFR0_EL1.ECV==2,
> > > set SCR_EL3.ECVEn to allow EL2 access to CNTPOFF_EL2.
> > 
> > I was about to ask if that was a typo (why is this in an MMFR?), but
> > that is what the ARM ARM says!
> 
> I was just as surprised. PFR would have made a lot more sense, but I
> guess someone wanted to use these last four bits as quickly as
> possible... ;-)
> 
> > 
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > ---
> > >  arch/aarch64/boot.S | 11 +++++++++--
> > >  1 file changed, 9 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> > > index 7f208b5..f0aa3cb 100644
> > > --- a/arch/aarch64/boot.S
> > > +++ b/arch/aarch64/boot.S
> > > @@ -54,10 +54,17 @@ ASM_FUNC(_start)
> > >  1:
> > >  	/* Enable FGT if present */
> > >  	mrs	x1, id_aa64mmfr0_el1
> > > -	ubfx	x1, x1, #56, #4
> > > -	cbz	x1, 1f
> > > +	ubfx	x2, x1, #56, #4
> > > +	cbz	x2, 1f
> > >  
> > >  	orr	x0, x0, #(1 << 27)		// FGT enable
> > > +1:
> > > +	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
> > > +	ubfx	x2, x1, #60, #4
> > > +	cmp	x2, #2
> > > +	bne	1f
> > 
> > We need to check ID_AA64MMFR0_EL1.ECV >= 2 (to handle any futrue
> > variants) so the conditional branch needs to be something like `b.lt`.
> 
> Good point. I'm surprised ECV3 hasn't hit yet! :D
> 
> > > +
> > > +	orr	x0, x0, #(1 << 28)		// ECV enable
> > 
> > Aside from the above, this looks good to me, and I plan to apply this
> > with the below tweaks (updated patch below):
> > 
> > * Use b.lt, as above
> > 
> > * To keep each check self-contained, the ECV check will read
> >   id_aa64mmfr0_el1 itself. That removes the need to keep x1 around, and
> >   so we can leave the FGT check as-is.
> > 
> >   As part of some cleanup, I'm planning to move this to C, where feature
> >   checks will read ID fields via a helepr that implicitly reads the
> >   register, like:
> > 
> >   if (read_reg_field(ID_AA64MMFR0_EL1, ECV) >= 2)
> >   	scr |= SCR_EL3_ECVEN;
> 
> If you are actively rewriting this, maybe don't bother with the patch
> and just add this as part of your rewrite.

There's a bunch of preparatory stuff to fix first, so I've applied this
patch (with those alterations) for now.

Thanks,
Mark.


From lorenzo.pieralisi at arm.com  Wed Aug 11 07:55:08 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 11 Aug 2021 15:55:08 +0100
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <YRPZ2Kqb/MFggHzQ@infradead.org>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
 <YRKtEDycefrZLB3X@infradead.org>
 <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
 <YRPZ2Kqb/MFggHzQ@infradead.org>
Message-ID: <20210811145508.GA3650@lpieralisi>

On Wed, Aug 11, 2021 at 03:08:24PM +0100, Christoph Hellwig wrote:
> On Wed, Aug 11, 2021 at 12:40:28PM +0200, Ard Biesheuvel wrote:
> > The whole problem we are solving here is that ACPI, being based on
> > x86, conflates MMIO mappings with memory mappings, and has been using
> > the same underlying infrastructure for either.
> 
> So let's fix that problem instead of papering over it.

Patch (3) in this series is a fix - I would ask whether it makes
sense to merge patches (2-3) now and think about reworking the current
ACPI IO/MEM mapping API later, it can be an invasive change for a fix,
assuming we agree on how to rework the ACPI IO/MEM mapping API.

Lorenzo


From maz at kernel.org  Wed Aug 11 07:58:23 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 15:58:23 +0100
Subject: [PATCH 2/2] PCI: j721e: Add PCI legacy interrupt support for J7200
In-Reply-To: <20210811123846.31921-3-kishon@ti.com>
References: <20210811123846.31921-1-kishon@ti.com>
 <20210811123846.31921-3-kishon@ti.com>
Message-ID: <87k0ks9gfk.wl-maz@kernel.org>

On Wed, 11 Aug 2021 13:38:46 +0100,
Kishon Vijay Abraham I <kishon at ti.com> wrote:
> 
> Add PCI legacy interrupt support for J7200. J7200 has a single HW
> interrupt line for all the four legacy interrupts INTA/INTB/INTC/INTD.
> The HW interrupt line connected to GIC is a pulse interrupt whereas
> the legacy interrupts by definition is level interrupt. In order to
> provide level interrupt functionality to edge interrupt line, PCIe
> in J7200 has provided USER_EOI_REG register. When the SW writes to
> USER_EOI_REG register after handling the interrupt, the IP checks the
> state of legacy interrupt and re-triggers pulse interrupt invoking
> the handler again.
> 
> Due to Errata ID #i2094 ([1]), EOI feature is not enabled in J721E
> and only a single pulse interrupt will be generated for every
> ASSERT_INTx/DEASSERT_INTx. Hence legacy interrupt is not enabled in
> J721E.

How do you prevent this from being enabled on an affected platform?
Just by virtue of not having the interrupt-controller property in DT?
In which case, it may be useful to clarify this in the DT binding and
say that it is only valid on J7200.

> 
> [1] -> J721E DRA829/TDA4VM Processors Silicon Revision 1.1/1.0 SPRZ455A ?
>        DECEMBER 2020 ? REVISED AUGUST 2021
>        (https://www.ti.com/lit/er/sprz455a/sprz455a.pdf)
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  drivers/pci/controller/cadence/pci-j721e.c | 119 +++++++++++++++++++++
>  1 file changed, 119 insertions(+)
> 
> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
> index ffb176d288cd..4e786d6b89e0 100644
> --- a/drivers/pci/controller/cadence/pci-j721e.c
> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> @@ -29,12 +29,24 @@
>  #define LINK_DOWN		BIT(1)
>  #define J7200_LINK_DOWN		BIT(10)
>  
> +#define ENABLE_REG_SYS_1	0x104
> +#define STATUS_REG_SYS_1	0x504
> +#define SYS1_INTx_EN(num)	(1 << (22 + (num)))
> +
>  #define J721E_PCIE_USER_CMD_STATUS	0x4
>  #define LINK_TRAINING_ENABLE		BIT(0)
>  
>  #define J721E_PCIE_USER_LINKSTATUS	0x14
>  #define LINK_STATUS			GENMASK(1, 0)
>  
> +#define USER_EOI_REG		0xC8
> +enum eoi_reg {
> +	EOI_DOWNSTREAM_INTERRUPT,
> +	EOI_FLR_INTERRUPT,
> +	EOI_LEGACY_INTERRUPT,
> +	EOI_POWER_STATE_INTERRUPT,
> +};
> +
>  enum link_status {
>  	NO_RECEIVERS_DETECTED,
>  	LINK_TRAINING_IN_PROGRESS,
> @@ -59,6 +71,7 @@ struct j721e_pcie {
>  	void __iomem		*user_cfg_base;
>  	void __iomem		*intd_cfg_base;
>  	u32			linkdown_irq_regfield;
> +	struct irq_domain	*legacy_irq_domain;
>  };
>  
>  enum j721e_pcie_mode {
> @@ -121,6 +134,108 @@ static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
>  	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
>  }
>  
> +static void j721e_pcie_legacy_irq_handler(struct irq_desc *desc)
> +{
> +	struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	int i, virq;
> +	u32 reg;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_1);
> +	for (i = 0; i < PCI_NUM_INTX; i++) {
> +		if (!(reg & SYS1_INTx_EN(i)))
> +			continue;
> +
> +		virq = irq_find_mapping(pcie->legacy_irq_domain, i);
> +		generic_handle_irq(virq);

Please use generic_handle_domain_irq().

> +	}
> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +static void j721e_pcie_irq_eoi(struct irq_data *data)
> +{
> +	struct j721e_pcie *pcie = irq_data_get_irq_chip_data(data);
> +
> +	j721e_pcie_user_writel(pcie, USER_EOI_REG, EOI_LEGACY_INTERRUPT);
> +}
> +
> +static void j721e_pcie_irq_enable(struct irq_data *data)
> +{
> +	struct j721e_pcie *pcie = irq_data_get_irq_chip_data(data);
> +	u32 reg;
> +
> +	reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_1);
> +	reg |= SYS1_INTx_EN(irqd_to_hwirq(data));
> +	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_1, reg);

RMW of a register shared between interrupts without a lock. It will
eventually end badly.

> +}
> +
> +static void j721e_pcie_irq_disable(struct irq_data *data)
> +{
> +	struct j721e_pcie *pcie = irq_data_get_irq_chip_data(data);
> +	u32 reg;
> +
> +	reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_1);
> +	reg &= ~SYS1_INTx_EN(irqd_to_hwirq(data));
> +	j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_1, reg);

Same thing.

> +}
> +
> +struct irq_chip j721e_pcie_irq_chip = {
> +	.name		= "J721E-PCIE-INTX",
> +	.irq_eoi	= j721e_pcie_irq_eoi,
> +	.irq_enable	= j721e_pcie_irq_enable,
> +	.irq_disable	= j721e_pcie_irq_disable,
> +};
> +
> +static int j721e_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq)
> +{
> +	struct j721e_pcie *pcie = domain->host_data;
> +
> +	irq_set_chip_and_handler(irq, &j721e_pcie_irq_chip, handle_fasteoi_irq);
> +	irq_set_chip_data(irq, pcie);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops j721e_pcie_intx_domain_ops = {
> +	.map = j721e_pcie_intx_map,
> +};
> +
> +static int j721e_pcie_config_legacy_irq(struct j721e_pcie *pcie)
> +{
> +	struct irq_domain *legacy_irq_domain;
> +	struct device *dev = pcie->dev;
> +	struct device_node *node = dev->of_node;
> +	struct device_node *intc_node;
> +	int irq;
> +
> +	intc_node = of_get_child_by_name(node, "interrupt-controller");
> +	if (!intc_node) {
> +		dev_dbg(dev, "interrupt-controller node is absent. Legacy INTR not supported\n");
> +		return 0;
> +	}
> +
> +	irq = irq_of_parse_and_map(intc_node, 0);
> +	if (!irq) {
> +		dev_err(dev, "Failed to parse and map legacy irq\n");
> +		return -EINVAL;
> +	}
> +
> +	irq_set_chained_handler_and_data(irq, j721e_pcie_legacy_irq_handler, pcie);

At this stage, you now have enabled the mux interrupt, and it can fire
at will (who knows what state the enabled bits are, given that you
don't initialise them?). However, you still haven't allocated the
domain. What could possibly go wrong?

Please initialise all the interrupts to their disabled state, and only
register the handler once all the data structures have been populated.

> +
> +	legacy_irq_domain = irq_domain_add_linear(intc_node, PCI_NUM_INTX,
> +						  &j721e_pcie_intx_domain_ops, pcie);
> +	if (!legacy_irq_domain) {
> +		dev_err(dev, "Failed to add irq domain for legacy irqs\n");
> +		return -EINVAL;
> +	}
> +	pcie->legacy_irq_domain = legacy_irq_domain;
> +
> +	return 0;
> +}
> +
>  static int j721e_pcie_start_link(struct cdns_pcie *cdns_pcie)
>  {
>  	struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
> @@ -433,6 +548,10 @@ static int j721e_pcie_probe(struct platform_device *pdev)
>  			goto err_get_sync;
>  		}
>  
> +		ret = j721e_pcie_config_legacy_irq(pcie);
> +		if (ret < 0)
> +			goto err_get_sync;
> +
>  		bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
>  		if (!bridge) {
>  			ret = -ENOMEM;

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Wed Aug 11 08:02:44 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 16:02:44 +0100
Subject: [PATCH V2] KVM: arm64: Restrict IPA size to maximum 48 bits on 4K
 and 16K page size
In-Reply-To: <1628680275-16578-1-git-send-email-anshuman.khandual@arm.com>
References: <1628680275-16578-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <162869415426.2969316.15859233360100994637.b4-ty@kernel.org>

On Wed, 11 Aug 2021 16:41:15 +0530, Anshuman Khandual wrote:
> Even though ID_AA64MMFR0.PARANGE reports 52 bit PA size support, it cannot
> be enabled as guest IPA size on 4K or 16K page size configurations. Hence
> kvm_ipa_limit must be restricted to 48 bits. This change achieves required
> IPA capping.
> 
> Before the commit c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA
> size based on host configuration"), the problem here would have been just
> latent via PHYS_MASK_SHIFT (which earlier in turn capped kvm_ipa_limit),
> which remains capped at 48 bits on 4K and 16K configs.

Applied to next, thanks!

[1/1] KVM: arm64: Restrict IPA size to maximum 48 bits on 4K and 16K page size
      commit: 5e5df9571c319fb107d7a523cc96fcc99961ee70

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From linus.walleij at linaro.org  Wed Aug 11 08:12:16 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 17:12:16 +0200
Subject: [PATCH V2 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <20210805174219.3000667-4-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-4-piyush.mehta@xilinx.com>
Message-ID: <CACRpkdYGD3s_7QEMa2cgx+5XFFJK_VwcN_km-Dbtr35hCSoFtw@mail.gmail.com>

On Thu, Aug 5, 2021 at 7:43 PM Piyush Mehta <piyush.mehta at xilinx.com> wrote:

> This patch adds driver support for the zynqmp modepin GPIO controller.
> GPIO modepin driver set and get the value and status of the PS_MODE pin,
> based on device-tree pin configuration. These four mode pins are
> configurable as input/output. The mode pin has a control register, which
> have lower four-bits [0:3] are configurable as input/output, next four-bits
> can be used for reading the data  as input[4:7], and next setting the
> output pin state output[8:11].
>
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> ---
> Changes in v2:

After discussion with Michal:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Aug 11 08:14:20 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 11 Aug 2021 17:14:20 +0200
Subject: [PATCH V2 1/3] firmware: zynqmp: Add MMIO read and write support
 for PS_MODE pin
In-Reply-To: <20210805174219.3000667-2-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-2-piyush.mehta@xilinx.com>
Message-ID: <CACRpkdbZouNdL43=nVLZd3hOeVQTLOZT=5FHGuM+3q3Ah2M9yQ@mail.gmail.com>

On Thu, Aug 5, 2021 at 7:42 PM Piyush Mehta <piyush.mehta at xilinx.com> wrote:

> Add Xilinx ZynqMP firmware MMIO APIs support to set and get PS_MODE
> pins value and status. These APIs create an interface path between
> mode pin controller driver and low-level API to access GPIO pins.
>
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> ---
> Changes in v2:

After Michals description of how this is controlling USB
PHY and misc resets I'm OK with the concept.
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From maz at kernel.org  Wed Aug 11 08:22:43 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 16:22:43 +0100
Subject: [PATCH v6 13/21] KVM: arm64: Allow userspace to configure a
 vCPU's virtual offset
In-Reply-To: <CAOQ_Qsjiyp_HQLhgFfF-o7T=Qpe+djL9KCFjAU2xmj8OXhAf4w@mail.gmail.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-14-oupton@google.com>
 <87czqlbq15.wl-maz@kernel.org>
 <CAOQ_Qsjiyp_HQLhgFfF-o7T=Qpe+djL9KCFjAU2xmj8OXhAf4w@mail.gmail.com>
Message-ID: <87h7fw9fb0.wl-maz@kernel.org>

On Tue, 10 Aug 2021 10:44:01 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Tue, Aug 10, 2021 at 2:35 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Wed, 04 Aug 2021 09:58:11 +0100,
> > Oliver Upton <oupton at google.com> wrote:
> > >
> > > Allow userspace to access the guest's virtual counter-timer offset
> > > through the ONE_REG interface. The value read or written is defined to
> > > be an offset from the guest's physical counter-timer. Add some
> > > documentation to clarify how a VMM should use this and the existing
> > > CNTVCT_EL0.
> > >
> > > Signed-off-by: Oliver Upton <oupton at google.com>
> > > ---
> > >  Documentation/virt/kvm/api.rst    | 10 ++++++++++
> > >  arch/arm64/include/uapi/asm/kvm.h |  1 +
> > >  arch/arm64/kvm/arch_timer.c       | 11 +++++++++++
> > >  arch/arm64/kvm/guest.c            |  6 +++++-
> > >  include/kvm/arm_arch_timer.h      |  1 +
> > >  5 files changed, 28 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> > > index 8d4a3471ad9e..28a65dc89985 100644
> > > --- a/Documentation/virt/kvm/api.rst
> > > +++ b/Documentation/virt/kvm/api.rst
> > > @@ -2487,6 +2487,16 @@ arm64 system registers have the following id bit patterns::
> > >       derived from the register encoding for CNTV_CVAL_EL0.  As this is
> > >       API, it must remain this way.
> > >
> > > +.. warning::
> > > +
> > > +     The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from
> > > +     the guest's view of the physical counter-timer.
> > > +
> > > +     Userspace should use either KVM_REG_ARM_TIMER_OFFSET or
> > > +     KVM_REG_ARM_TIMER_CVAL to pause and resume a guest's virtual
> >
> > You probably mean KVM_REG_ARM_TIMER_CNT here, despite the broken
> > encoding.
> 
> Indeed I do!
> 
> >
> > > +     counter-timer. Mixed use of these registers could result in an
> > > +     unpredictable guest counter value.
> > > +
> > >  arm64 firmware pseudo-registers have the following bit pattern::
> > >
> > >    0x6030 0000 0014 <regno:16>
> > > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> > > index b3edde68bc3e..949a31bc10f0 100644
> > > --- a/arch/arm64/include/uapi/asm/kvm.h
> > > +++ b/arch/arm64/include/uapi/asm/kvm.h
> > > @@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags {
> > >  #define KVM_REG_ARM_TIMER_CTL                ARM64_SYS_REG(3, 3, 14, 3, 1)
> > >  #define KVM_REG_ARM_TIMER_CVAL               ARM64_SYS_REG(3, 3, 14, 0, 2)
> > >  #define KVM_REG_ARM_TIMER_CNT                ARM64_SYS_REG(3, 3, 14, 3, 2)
> > > +#define KVM_REG_ARM_TIMER_OFFSET     ARM64_SYS_REG(3, 4, 14, 0, 3)
> >
> > I don't think we can use the encoding for CNTPOFF_EL2 here, as it will
> > eventually clash with a NV guest using the same feature for its own
> > purpose. We don't want this offset to overlap with any of the existing
> > features.
> >
> > I actually liked your previous proposal of controlling the physical
> > offset via a device property, as it clearly indicated that you were
> > dealing with non-architectural state.
> 
> That's actually exactly what I did here :) That said, the macro name
> is horribly obfuscated from CNTVOFF_EL2. I did this for the sake of
> symmetry with other virtual counter-timer registers above, though this
> may warrant special casing given the fact that we have a similarly
> named device attribute to handle the physical offset.

Gah, you are of course right. Ignore my rambling. The name is fine (or
at least in keeping with existing quality level of the making).

For the physical offset, something along the lines of
KVM_ARM_VCPU_TIMER_PHYS_OFFSET is probably right (but feel free to be
creative, I'm terrible at this stuff [1]).

Thanks,

	M.

[1] https://twitter.com/codinghorror/status/506010907021828096?lang=en

-- 
Without deviation from the norm, progress is not possible.


From cristian.marussi at arm.com  Wed Aug 11 08:26:41 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 11 Aug 2021 16:26:41 +0100
Subject: [PATCH v6 00/17] Introduce SCMI transport based on VirtIO
In-Reply-To: <YROY6YntswWxfaub@google.com>
References: <20210712141833.6628-1-cristian.marussi@arm.com>
 <YROY6YntswWxfaub@google.com>
Message-ID: <20210811152641.GX6592@e120937-lin>

On Wed, Aug 11, 2021 at 09:31:21AM +0000, Floris Westermann wrote:
> Hi Cristian,
> 

Hi Floris,

> I am currently working on an interface for VMs to communicate their
> performance requirements to the hosts by passing through cpu frequency
> adjustments.
> 

So something like looking up SCMI requests from VMs in the hypervisor
and act on VM underlying hw accordingly ? Where the SCMI server is meant
to live ?

> Your patch looks very interesting but I have some questions:
> 

Happy to hear that, a new V7 (with minor cleanups) which is (hopefully)
being pulled these days is at:

https://lore.kernel.org/linux-arm-kernel/20210803131024.40280-1-cristian.marussi at arm.com/
> 
> On Mon, Jul 12, 2021 at 03:18:16PM +0100, Cristian Marussi wrote:
> >
> > The series has been tested using an emulated fake SCMI device and also a
> > proper SCP-fw stack running through QEMU vhost-users, with the SCMI stack
> > compiled, in both cases, as builtin and as a loadable module, running tests
> > against mocked SCMI Sensors using HWMON and IIO interfaces to check the
> > functionality of notifications and sync/async commands.
> >
> > Virtio-scmi support has been exercised in the following testing scenario
> > on a JUNO board:
> >
> >  - normal sync/async command transfers
> >  - notifications
> >  - concurrent delivery of correlated response and delayed responses
> >  - out-of-order delivery of delayed responses before related responses
> >  - unexpected delayed response delivery for sync commands
> >  - late delivery of timed-out responses and delayed responses
> >
> > Some basic regression testing against mailbox transport has been performed
> > for commands and notifications too.
> >
> > No sensible overhead in total handling time of commands and notifications
> > has been observed, even though this series do indeed add a considerable
> > amount of code to execute on TX path.
> > More test and measurements could be needed in these regards.
> >
> 
> Can you share any data and benchmarks using you fake SCMI device.
> Also, could you provide the emulated device code so that the results can
> be reproduced.
> 

Not really, because the testing based on the fake SCMI VirtIO device was
purely functional, just to exercise some rare limit conditions not
easily reproducible with a regular SCMI stack, I've made no benchmark
using the fake emulated SCMI virtio device because it mimics VirtIO
transfers but there's not even an host/guest in my fake emulation.
Moreover is a hacked driver+userspace blob not really in a state to be
shared :P

While developing this series I needed somehow to be able to let the Kernel
SCMI-agent in the guest "speak" some basic SCMI commands and notifs to
some SCMI server platform sitting somewhere across the new VirtIO SCMI
transport, which basically means that it's not enough to create an SCMI
VirtIO device reachable from the VirtIO layer, the SCMI stack itself
(or part of it) must live behind such device somehow/somewhere to be
able to receive meaningful replies.

One proper way to do that is to use some QEMU/SCP-fw vhost-users support
cooked by Linaro (not in the upstream for now) so as to basically run a
full proper SCP SCMI-platform fw stack in host userspace and let it speak
to a guest through the new scmi virtio transport and the vhost-users magic:
the drawback of this kind of approach is that it made hard to test limit
conditions like stale or out-of-order SCMI replies because to do so you
have to patch the official SCP/SCMI stack to behave badly and out-of specs,
which is not something is designed to do. (and also the fact that the
vhost-users QEMU/SCP-fw solution was only available later during devel).
Hence the emulation hack for testing rare limit conditions.

Now, the emulation hack, beside really ugly, is clearly a totally fake
VirtIO environment (there's not even a guest really...) and, as said, it
just served the need to exercise the SCMI virtio transport code enough to
test anomalous and bad-behaving SCMI commands flows and notifications and
as such made really no sense to be used as a performance testbed.

In fact, what I was really meaning (poorly) while saying:

> > No sensible overhead in total handling time of commands and notifications
> > has been observed, even though this series do indeed add a considerable
> > amount of code to execute on TX path.

is that I have NOT seen any sensible overhead/slowdown in the context of
OTHER real SCMI transports (like mailboxes), because the virtio series
contains a number of preliminary SCMI common core changes unrelated to
virtio (monotonic tokens/handle concurrent and out-of-order replies) that,
even though easing the devel of SCMI virtio, are really needed and used
by any other existent SCMI transport, so my fear was to introduce some
common slowdown in the core: in those regards only, I said that I have
not seen (looking at cmd traces) any slowdown with such additional core
changes even though more code is clearly now run in the TX path.
(contention can indeed only happen under very rare limit conditions)

Having said that (sorry for the flood of words) what I can give you are
a few traces (non statistically significant probably) showing the typical
round-trip time for some plain SCMI command sensor requests on an idle
system (JUNO)

In both cases the sensors being read are mocked, so the time is purely
related to SCMI core stack and virtio exchanges (i.e. there's no delay
introduced by reading real hw sensors)


-> Using a proper SCP-fw/QEMU vhost-users stack:

root at deb-guest:~# cat /sys/class/hwmon/hwmon0/temp1_input 
             cat-195     [000] ....  7044.614295: scmi_xfer_begin: transfer_id=27 msg_id=6 protocol_id=21 seq=27 poll=0
25000
          <idle>-0       [000] d.h3  7044.615342: scmi_rx_done: transfer_id=27 msg_id=6 protocol_id=21 seq=27 msg_type=0
             cat-195     [000] ....  7044.615420: scmi_xfer_end: transfer_id=27 msg_id=6 protocol_id=21 seq=27 status=0

root at deb-guest:~# cat /sys/class/hwmon/hwmon0/temp1_input 
             cat-196     [000] ....  7049.200349: scmi_xfer_begin: transfer_id=28 msg_id=6 protocol_id=21 seq=28 poll=0
          <idle>-0       [000] d.h3  7049.202053: scmi_rx_done: transfer_id=28 msg_id=6 protocol_id=21 seq=28 msg_type=0
             cat-196     [000] ....  7049.202152: scmi_xfer_end: transfer_id=28 msg_id=6 protocol_id=21 seq=28 status=0
25000

root at deb-guest:~# cat /sys/class/hwmon/hwmon0/temp1_input 
             cat-197     [000] ....  7053.699713: scmi_xfer_begin: transfer_id=29 msg_id=6 protocol_id=21 seq=29 poll=0
25000
          <idle>-0       [000] d.H3  7053.700366: scmi_rx_done: transfer_id=29 msg_id=6 protocol_id=21 seq=29 msg_type=0
             cat-197     [000] ....  7053.700468: scmi_xfer_end: transfer_id=29 msg_id=6 protocol_id=21 seq=29 status=0

root at deb-guest:~# cat /sys/class/hwmon/hwmon0/temp1_input 
             cat-198     [001] ....  7058.944442: scmi_xfer_begin: transfer_id=30 msg_id=6 protocol_id=21 seq=30 poll=0
             cat-173     [000] d.h2  7058.944959: scmi_rx_done: transfer_id=30 msg_id=6 protocol_id=21 seq=30 msg_type=0
             cat-198     [001] ....  7058.945500: scmi_xfer_end: transfer_id=30 msg_id=6 protocol_id=21 seq=30 status=0
25000

root at deb-guest:~# cat /sys/class/hwmon/hwmon0/temp1_input 
             cat-199     [000] ....  7064.598797: scmi_xfer_begin: transfer_id=31 msg_id=6 protocol_id=21 seq=31 poll=0
25000
          <idle>-0       [000] d.h3  7064.599710: scmi_rx_done: transfer_id=31 msg_id=6 protocol_id=21 seq=31 msg_type=0
             cat-199     [000] ....  7064.599787: scmi_xfer_end: transfer_id=31 msg_id=6 protocol_id=21 seq=31 status=0



-> Using the fake hack SCMI device that relays packets to userspace:

             cat-1306    [000] ....  7614.373161: scmi_xfer_begin: transfer_id=78 msg_id=6 protocol_id=21 seq=78 poll=0
 scmi_sniffer_ng-342     [000] d.h2  7614.373699: scmi_rx_done: transfer_id=78 msg_id=6 protocol_id=21 seq=78 msg_type=0
             cat-1306    [000] ....  7614.377653: scmi_xfer_end: transfer_id=78 msg_id=6 protocol_id=21 seq=78 status=0


             cat-1308    [004] ....  7626.677176: scmi_xfer_begin: transfer_id=79 msg_id=6 protocol_id=21 seq=79 poll=0
 scmi_sniffer_ng-342     [000] d.h2  7626.677653: scmi_rx_done: transfer_id=79 msg_id=6 protocol_id=21 seq=79 msg_type=0
             cat-1308    [004] ....  7626.677705: scmi_xfer_end: transfer_id=79 msg_id=6 protocol_id=21 seq=79 status=0


             cat-1309    [004] ....  7631.249412: scmi_xfer_begin: transfer_id=80 msg_id=6 protocol_id=21 seq=80 poll=0
 scmi_sniffer_ng-342     [000] d.h2  7631.250182: scmi_rx_done: transfer_id=80 msg_id=6 protocol_id=21 seq=80 msg_type=0
             cat-1309    [004] ....  7631.250237: scmi_xfer_end: transfer_id=80 msg_id=6 protocol_id=21 seq=80 status=0

             cat-1312    [004] ....  7642.210034: scmi_xfer_begin: transfer_id=81 msg_id=6 protocol_id=21 seq=81 poll=0
 scmi_sniffer_ng-342     [000] d.h2  7642.210514: scmi_rx_done: transfer_id=81 msg_id=6 protocol_id=21 seq=81 msg_type=0
             cat-1312    [004] ....  7642.210567: scmi_xfer_end: transfer_id=81 msg_id=6 protocol_id=21 seq=81 status=0

             cat-1314    [003] ....  7645.810775: scmi_xfer_begin: transfer_id=82 msg_id=6 protocol_id=21 seq=82 poll=0
 scmi_sniffer_ng-342     [000] d.h2  7645.811255: scmi_rx_done: transfer_id=82 msg_id=6 protocol_id=21 seq=82 msg_type=0
             cat-1314    [003] ....  7645.811307: scmi_xfer_end: transfer_id=82 msg_id=6 protocol_id=21 seq=82 status=0


In both cases SCMI requests are effectively relayed to userspace so
that's probably the reason timings are similar. (despite the hackish
internals of latter solution)

Not sure if all the above madness helped you at all :D

Thanks,
Cristian



From geert at linux-m68k.org  Wed Aug 11 08:35:26 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 11 Aug 2021 17:35:26 +0200
Subject: [PATCH v5 1/9] MIPS: Avoid future duplicate elf core header
 reservation
In-Reply-To: <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>
Message-ID: <CAMuHMdVFJ_qGs0V7f+XhfD6v3WnkMJ98fO31sCRSNaeS89XXUQ@mail.gmail.com>

On Wed, Aug 11, 2021 at 10:51 AM Geert Uytterhoeven
<geert+renesas at glider.be> wrote:
> Prepare for early_init_fdt_scan_reserved_mem() reserving the memory
> occupied by an elf core header described in the device tree.
> As arch_mem_init() calls early_init_fdt_scan_reserved_mem() before
> mips_reserve_vmcore(), the latter needs to check if the memory has
> already been reserved before.
>
> Note that mips_reserve_vmcore() cannot just be removed, as not all MIPS
> systems use DT.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> v5:
>   - New.
> ---
>  arch/mips/kernel/setup.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> index 23a140327a0bac1b..4693add05743d78b 100644
> --- a/arch/mips/kernel/setup.c
> +++ b/arch/mips/kernel/setup.c
> @@ -429,7 +429,8 @@ static void __init mips_reserve_vmcore(void)
>         pr_info("Reserving %ldKB of memory at %ldKB for kdump\n",
>                 (unsigned long)elfcorehdr_size >> 10, (unsigned long)elfcorehdr_addr >> 10);
>
> -       memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
> +       if (!memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)

As pointed out by lkp, there's a closing parenthesis missing.

/me hides back under his rock.

> +               memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
>  #endif

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From boqun.feng at gmail.com  Wed Aug 11 08:36:14 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Wed, 11 Aug 2021 23:36:14 +0800
Subject: [RFC 0/5] PCI: Use the private field of pci_host_bridge for ACPI
 device
Message-ID: <20210811153619.88922-1-boqun.feng@gmail.com>

Hi Lorenzo,

As our previous discussion, I make a patchset showing the required
effort if we want to use ->private in pci_host_bridge to store ACPI
device pointer on ARM64. This patchset is mostly for discussion purpose.

This patchset is based onto the v5 of my Hyper-V PCI on ARM64 patchset:

	https://lore.kernel.org/lkml/20210726180657.142727-1-boqun.feng at gmail.com/

, and I've tested it with other code under development to fully enable
Hyper-V virtual PCI on ARM64.

Regards,
Boqun


Boqun Feng (5):
  PCI: Introduce pci_create_root_bus_priv()
  PCI/ACPI: Store ACPI device information in the host bridge structure
  PCI: hv: Set NULL as the ACPI device for the PCI host bridge
  arm64: PCI: Retrieve ACPI device information directly from host
    bridges
  PCI: hv: Remove the dependency of pci_config_window

 arch/arm64/kernel/pci.c             | 14 +-------------
 drivers/acpi/pci_root.c             |  5 +++--
 drivers/pci/controller/pci-hyperv.c | 20 +++++++++++++++-----
 drivers/pci/probe.c                 | 15 ++++++++++++---
 include/linux/pci-acpi.h            |  5 +++++
 include/linux/pci.h                 |  3 +++
 6 files changed, 39 insertions(+), 23 deletions(-)

-- 
2.32.0



From boqun.feng at gmail.com  Wed Aug 11 08:36:15 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Wed, 11 Aug 2021 23:36:15 +0800
Subject: [RFC 1/5] PCI: Introduce pci_create_root_bus_priv()
In-Reply-To: <20210811153619.88922-1-boqun.feng@gmail.com>
References: <20210811153619.88922-1-boqun.feng@gmail.com>
Message-ID: <20210811153619.88922-2-boqun.feng@gmail.com>

In order to allow root bus creation to populate the ->private of the
pci_host_bridge at the same, pci_create_root_bus_priv() is introduced.
The new function will be used to support passing the corresponding ACPI
device as the ->private field when creating the PCI root bus.

No functional change.

Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
---
 drivers/pci/probe.c | 15 ++++++++++++---
 include/linux/pci.h |  3 +++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ea7f2a57e2f5..8f5fea2a7bd9 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2991,13 +2991,14 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
 {
 }
 
-struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+struct pci_bus *pci_create_root_bus_priv(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources,
+		void *private, size_t priv_size)
 {
 	int error;
 	struct pci_host_bridge *bridge;
 
-	bridge = pci_alloc_host_bridge(0);
+	bridge = pci_alloc_host_bridge(priv_size);
 	if (!bridge)
 		return NULL;
 
@@ -3008,6 +3009,9 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	bridge->busnr = bus;
 	bridge->ops = ops;
 
+	if (priv_size)
+		memcpy(bridge->private, private, priv_size);
+
 	error = pci_register_host_bridge(bridge);
 	if (error < 0)
 		goto err_out;
@@ -3018,6 +3022,11 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	put_device(&bridge->dev);
 	return NULL;
 }
+struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	return pci_create_root_bus_priv(parent, bus, ops, sysdata, resources, NULL, 0);
+}
 EXPORT_SYMBOL_GPL(pci_create_root_bus);
 
 int pci_host_probe(struct pci_host_bridge *bridge)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 01aa201e1df0..119356312979 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1041,6 +1041,9 @@ void pcibios_scan_specific_bus(int busn);
 struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
+struct pci_bus *pci_create_root_bus_priv(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources,
+		void *private, size_t priv_size);
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
 				    struct list_head *resources);
-- 
2.32.0



From boqun.feng at gmail.com  Wed Aug 11 08:36:16 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Wed, 11 Aug 2021 23:36:16 +0800
Subject: [RFC 2/5] PCI/ACPI: Store ACPI device information in the host bridge
 structure
In-Reply-To: <20210811153619.88922-1-boqun.feng@gmail.com>
References: <20210811153619.88922-1-boqun.feng@gmail.com>
Message-ID: <20210811153619.88922-3-boqun.feng@gmail.com>

In order to decouple the ACPI device information of a PCI host bridge
from the sysdata, ->private of pci_host_bridge is used to store the ACPI
device, and it's done by the new pci_create_root_bus_priv().

A reader function is also added, to retrieve the ACPI device information
in pci_host_bridge.

Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
---
 drivers/acpi/pci_root.c  | 5 +++--
 include/linux/pci-acpi.h | 5 +++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d7deedf3548e..82824841cbda 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -894,8 +894,9 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 
 	pci_acpi_root_add_resources(info);
 	pci_add_resource(&info->resources, &root->secondary);
-	bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
-				  sysdata, &info->resources);
+	bus = pci_create_root_bus_priv(NULL, busnum, ops->pci_ops, sysdata,
+				       &info->resources, &root->device,
+				       sizeof(struct acpi_device *));
 	if (!bus)
 		goto out_release_info;
 
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 5ba475ca9078..21d4cc80aa55 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -80,6 +80,11 @@ extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 					    struct acpi_pci_root_ops *ops,
 					    struct acpi_pci_root_info *info,
 					    void *sd);
+static inline struct acpi_device *
+acpi_pci_root_device(struct pci_host_bridge *bridge)
+{
+	return *((struct acpi_device **)bridge->private);
+}
 
 void acpi_pci_add_bus(struct pci_bus *bus);
 void acpi_pci_remove_bus(struct pci_bus *bus);
-- 
2.32.0



From boqun.feng at gmail.com  Wed Aug 11 08:36:17 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Wed, 11 Aug 2021 23:36:17 +0800
Subject: [RFC 3/5] PCI: hv: Set NULL as the ACPI device for the PCI host bridge
In-Reply-To: <20210811153619.88922-1-boqun.feng@gmail.com>
References: <20210811153619.88922-1-boqun.feng@gmail.com>
Message-ID: <20210811153619.88922-4-boqun.feng@gmail.com>

A PCI host bridge of Hyper-V doesn't have the corresponding ACPI device,
therefore a NULL pointer needs to be set as the ->private of
pci_host_bridge since for platforms with ACPI ->private is used to store
the ACPI device information for the host bridges.

And since kzalloc() is used to allocate pci_host_bridge, as a result,
what is needed is just setting the correct size of ->private, kzalloc()
will zero the field as if set a NULL pointer to it.

Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
---
 drivers/pci/controller/pci-hyperv.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 62dbe98d1fe1..fd3792b5edcc 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -3021,7 +3021,12 @@ static int hv_pci_probe(struct hv_device *hdev,
 	 */
 	BUILD_BUG_ON(sizeof(*hbus) > HV_HYP_PAGE_SIZE);
 
-	bridge = devm_pci_alloc_host_bridge(&hdev->device, 0);
+	/*
+	 * devm_pci_alloc_host_bridge() use kzalloc(), and we want to set
+	 * ->private as a NULL pointer, therefore no need to set ->private after
+	 * allocation.
+	 */
+	bridge = devm_pci_alloc_host_bridge(&hdev->device, sizeof(struct acpi_device *));
 	if (!bridge)
 		return -ENOMEM;
 
-- 
2.32.0



From boqun.feng at gmail.com  Wed Aug 11 08:36:18 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Wed, 11 Aug 2021 23:36:18 +0800
Subject: [RFC 4/5] arm64: PCI: Retrieve ACPI device information directly from
 host bridges
In-Reply-To: <20210811153619.88922-1-boqun.feng@gmail.com>
References: <20210811153619.88922-1-boqun.feng@gmail.com>
Message-ID: <20210811153619.88922-5-boqun.feng@gmail.com>

Now since we store the corresponding ACPI device pointer in the
->private of pci_host_bridge, use it instead of the sysdata to retrieve
the ACPI device information. Doing this decouples the dependency on the
pci_config_window structure in Hyper-V virtual PCI, because passing a
NULL pointer as the ACPI device is the soly reason of the dependency.

The decoupling avoids adding pci_config_window in hv_pcibus_dev and also
makes the code cleaner.

Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
---
 arch/arm64/kernel/pci.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 2276689b5411..783971749eb7 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -82,25 +82,13 @@ int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
 
 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
-	struct pci_config_window *cfg;
 	struct acpi_device *adev;
 	struct device *bus_dev;
 
 	if (acpi_disabled)
 		return 0;
 
-	cfg = bridge->bus->sysdata;
-
-	/*
-	 * On Hyper-V there is no corresponding ACPI device for a root bridge,
-	 * therefore ->parent is set as NULL by the driver. And set 'adev' as
-	 * NULL in this case because there is no proper ACPI device.
-	 */
-	if (!cfg->parent)
-		adev = NULL;
-	else
-		adev = to_acpi_device(cfg->parent);
-
+	adev = acpi_pci_root_device(bridge);
 	bus_dev = &bridge->bus->dev;
 
 	ACPI_COMPANION_SET(&bridge->dev, adev);
-- 
2.32.0



From boqun.feng at gmail.com  Wed Aug 11 08:36:19 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Wed, 11 Aug 2021 23:36:19 +0800
Subject: [RFC 5/5] PCI: hv: Remove the dependency of pci_config_window
In-Reply-To: <20210811153619.88922-1-boqun.feng@gmail.com>
References: <20210811153619.88922-1-boqun.feng@gmail.com>
Message-ID: <20210811153619.88922-6-boqun.feng@gmail.com>

The ACPI device information is now correctly set via ->private of
pci_host_bridge, therefore no need to use pci_config_window in
hv_pcibus_device, so remove it.

Note we still need an empty pci_sysdata structure for non-x86, because
it's x86-specific.

Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
---
 drivers/pci/controller/pci-hyperv.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index fd3792b5edcc..f2b977ef7b84 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -448,12 +448,17 @@ enum hv_pcibus_state {
 	hv_pcibus_maximum
 };
 
+/*
+ * Defines a empty struct for non-x86 architecture, this is OK because we only
+ * use this field as an "anchor" to get back to hv_pcibus_device object on
+ * non-x86 architecture.
+ */
+#ifndef CONFIG_X86
+struct pci_sysdata { };
+#endif
+
 struct hv_pcibus_device {
-#ifdef CONFIG_X86
 	struct pci_sysdata sysdata;
-#elif defined(CONFIG_ARM64)
-	struct pci_config_window sysdata;
-#endif
 	struct pci_host_bridge *bridge;
 	struct fwnode_handle *fwnode;
 	/* Protocol version negotiated with the host */
-- 
2.32.0



From lukasz.luba at arm.com  Wed Aug 11 08:52:55 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Wed, 11 Aug 2021 16:52:55 +0100
Subject: [PATCH V2 9/9] cpufreq: scmi: Use .register_em() callback
In-Reply-To: <YRPhI3AOAJLpQnjT@google.com>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
 <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
 <YRPN8zjp1wqkHg6t@google.com> <b02cff82-d242-f783-6f29-78e734f78e26@arm.com>
 <YRPhI3AOAJLpQnjT@google.com>
Message-ID: <31d73514-0d60-3239-a727-0ae483f11c31@arm.com>



On 8/11/21 3:39 PM, Quentin Perret wrote:
> On Wednesday 11 Aug 2021 at 15:09:13 (+0100), Lukasz Luba wrote:
>>
>>
>> On 8/11/21 2:17 PM, Quentin Perret wrote:
>>> On Wednesday 11 Aug 2021 at 17:28:47 (+0530), Viresh Kumar wrote:
>>>> Set the newly added .register_em() callback to register with the EM
>>>> after the cpufreq policy is properly initialized.
>>>>
>>>> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
>>>> ---
>>>>    drivers/cpufreq/scmi-cpufreq.c | 55 ++++++++++++++++++++--------------
>>>>    1 file changed, 32 insertions(+), 23 deletions(-)
>>>>
>>>> diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
>>>> index 75f818d04b48..b916c9e22921 100644
>>>> --- a/drivers/cpufreq/scmi-cpufreq.c
>>>> +++ b/drivers/cpufreq/scmi-cpufreq.c
>>>> @@ -22,7 +22,9 @@
>>>>    struct scmi_data {
>>>>    	int domain_id;
>>>> +	int nr_opp;
>>>>    	struct device *cpu_dev;
>>>> +	cpumask_var_t opp_shared_cpus;
>>>
>>> Can we use policy->related_cpus and friends directly in the callback
>>
>> Unfortunately not. This tricky setup code was introduced because we may
>> have a platform with per-CPU policy, so single bit set in
>> policy->related_cpus, but we want EAS to be still working on set
>> of CPUs. That's why we construct temporary cpumask and pass it to EM.
> 
> Aha, I see this now. Hmm, those platforms better have AMUs then,
> otherwise PELT signals will be wonky ...

That's the plan, to have the AMUs. We suggest that, but reality would
tell... ;)

> 
> I was going to suggest using dev_pm_opp_get_sharing_cpus() from the
> callback instead, but maybe that's overkill as we'd need to allocate a
> temporary cpumask and all. So n/m this patch should be fine as is.
> 


From robin.murphy at arm.com  Wed Aug 11 08:53:25 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 11 Aug 2021 16:53:25 +0100
Subject: [PATCHv4] iommu/arm-smmu: Optimize ->tlb_flush_walk() for qcom
 implementation
In-Reply-To: <20210811103011.GD4426@willie-the-truck>
References: <20210811060725.25221-1-saiprakash.ranjan@codeaurora.org>
 <20210811103011.GD4426@willie-the-truck>
Message-ID: <7be65300-632a-8626-e5da-13bc9e276763@arm.com>

On 2021-08-11 11:30, Will Deacon wrote:
> On Wed, Aug 11, 2021 at 11:37:25AM +0530, Sai Prakash Ranjan wrote:
>> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> index f7da8953afbe..3904b598e0f9 100644
>> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
>> @@ -327,9 +327,16 @@ static void arm_smmu_tlb_inv_range_s2(unsigned long iova, size_t size,
>>   static void arm_smmu_tlb_inv_walk_s1(unsigned long iova, size_t size,
>>   				     size_t granule, void *cookie)
>>   {
>> -	arm_smmu_tlb_inv_range_s1(iova, size, granule, cookie,
>> -				  ARM_SMMU_CB_S1_TLBIVA);
>> -	arm_smmu_tlb_sync_context(cookie);
>> +	struct arm_smmu_domain *smmu_domain = cookie;
>> +	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>> +
>> +	if (cfg->flush_walk_prefer_tlbiasid) {
>> +		arm_smmu_tlb_inv_context_s1(cookie);
> 
> Hmm, this introduces an unconditional wmb() if tlbiasid is preferred. I
> think that should be predicated on ARM_SMMU_FEAT_COHERENT_WALK like it is
> for the by-VA ops. Worth doing as a separate patch.
> 
>> +	} else {
>> +		arm_smmu_tlb_inv_range_s1(iova, size, granule, cookie,
>> +					  ARM_SMMU_CB_S1_TLBIVA);
>> +		arm_smmu_tlb_sync_context(cookie);
>> +	}
>>   }
>>   
>>   static void arm_smmu_tlb_add_page_s1(struct iommu_iotlb_gather *gather,
>> @@ -765,8 +772,10 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
>>   		.iommu_dev	= smmu->dev,
>>   	};
>>   
>> -	if (!iommu_get_dma_strict(domain))
>> +	if (!iommu_get_dma_strict(domain)) {
>>   		pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
>> +		cfg->flush_walk_prefer_tlbiasid = true;
> 
> This is going to interact badly with Robin's series to allow dynamic
> transition to non-strict mode, as we don't have a mechanism to switch
> over to the by-ASID behaviour. Yes, it should _work_, but it's ugly having
> different TLBI behaviour just because of the how the domain became
> non-strict.
> 
> Robin -- I think this originated from your idea at [1]. Any idea how to make
> it work with your other series, or shall we drop this part for now and leave
> the TLB invalidation behaviour the same for now?

Yeah, I'd say drop it - I'm currently half an hour into a first attempt 
at removing io_pgtable_tlb_flush_walk() entirely, which would make it 
moot for non-strict anyway.

Robin.


From john.garry at huawei.com  Wed Aug 11 08:49:26 2021
From: john.garry at huawei.com (John Garry)
Date: Wed, 11 Aug 2021 23:49:26 +0800
Subject: [PATCH] iommu/arm-smmu-v3: Stop pre-zeroing batch commands
Message-ID: <1628696966-88386-1-git-send-email-john.garry@huawei.com>

Pre-zeroing the batched commands structure is inefficient, as individual
commands are zeroed later in arm_smmu_cmdq_build_cmd(). The size is quite
large and commonly most commands won't even be used:

	struct arm_smmu_cmdq_batch cmds = {};
345c:	52800001 	mov	w1, #0x0                   	// #0
3460:	d2808102 	mov	x2, #0x408                 	// #1032
3464:	910143a0 	add	x0, x29, #0x50
3468:	94000000 	bl	0 <memset>

Stop pre-zeroing the complete structure and only zero the num member.

Signed-off-by: John Garry <john.garry at huawei.com>

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index cbc57edfa4e2..2a4f3fb938f6 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1082,7 +1082,7 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
 	size_t i;
 	unsigned long flags;
 	struct arm_smmu_master *master;
-	struct arm_smmu_cmdq_batch cmds = {};
+	struct arm_smmu_cmdq_batch cmds;
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	struct arm_smmu_cmdq_ent cmd = {
 		.opcode	= CMDQ_OP_CFGI_CD,
@@ -1092,6 +1092,8 @@ static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
 		},
 	};
 
+	cmds.num = 0;
+
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
 	list_for_each_entry(master, &smmu_domain->devices, domain_head) {
 		for (i = 0; i < master->num_streams; i++) {
@@ -1908,7 +1910,7 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
 	unsigned long flags;
 	struct arm_smmu_cmdq_ent cmd;
 	struct arm_smmu_master *master;
-	struct arm_smmu_cmdq_batch cmds = {};
+	struct arm_smmu_cmdq_batch cmds;
 
 	if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_ATS))
 		return 0;
@@ -1932,6 +1934,8 @@ int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
 
 	arm_smmu_atc_inv_to_cmd(ssid, iova, size, &cmd);
 
+	cmds.num = 0;
+
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
 	list_for_each_entry(master, &smmu_domain->devices, domain_head) {
 		if (!master->ats_enabled)
@@ -1980,7 +1984,7 @@ static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd,
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	unsigned long end = iova + size, num_pages = 0, tg = 0;
 	size_t inv_range = granule;
-	struct arm_smmu_cmdq_batch cmds = {};
+	struct arm_smmu_cmdq_batch cmds;
 
 	if (!size)
 		return;
@@ -1998,6 +2002,8 @@ static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd,
 		num_pages = size >> tg;
 	}
 
+	cmds.num = 0;
+
 	while (iova < end) {
 		if (smmu->features & ARM_SMMU_FEAT_RANGE_INV) {
 			/*
-- 
2.26.2



From jason-jh.lin at mediatek.com  Wed Aug 11 09:06:49 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Thu, 12 Aug 2021 00:06:49 +0800
Subject: [PATCH v6 2/7] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys0
In-Reply-To: <28cc4599-6eda-4784-3d8f-4570c9ab60e8@gmail.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-3-jason-jh.lin@mediatek.com>
 <28cc4599-6eda-4784-3d8f-4570c9ab60e8@gmail.com>
Message-ID: <35e543ebb1dd389a0530ec48ebca8298816a2378.camel@mediatek.com>

Hi Matthias,

On Fri, 2021-08-06 at 13:28 +0200, Matthias Brugger wrote:
> Hi Jason,
> 
> On 05/08/2021 22:52, jason-jh.lin wrote:
> > Add mt8195 vdosys0 clock driver name and routing table to
> > the driver data of mtk-mmsys.
> > 
> 
> I'd like to see the implementation of vdosys1 as well, to better
> understand why
> we need two compatibles.

Do you mean I have to merge this patch and [1] into the same patch? or
just add [1] at the same series? or just include [1] at commit message?
[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20210722094551.15255-10-nancy.lin at mediatek.com/

> 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> > This patch is base on [1]
> > 
> > [1] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
> > 
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-2-jason-jh.lin at mediatek.com/__;!!CTRNKA9wMg0ARbw!21Mclcdx-qMIpoqPQOZd_-TuzoUfzzJ8UBC_RDzmvz5ISZQjfJIAhhJDKYBClDfOZb71$
> >  
> 
> Please add the binding description to this series.

OK, I'll add the binding patch into this series. 

> 
> > ---
> >  drivers/soc/mediatek/mt8195-mmsys.h    | 96
> > ++++++++++++++++++++++++++
> >  drivers/soc/mediatek/mtk-mmsys.c       | 11 +++
> >  include/linux/soc/mediatek/mtk-mmsys.h |  9 +++
> >  3 files changed, 116 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h
> > 
> > diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
> > b/drivers/soc/mediatek/mt8195-mmsys.h
> > new file mode 100644
> > index 000000000000..9339a786ec5d
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> > @@ -0,0 +1,96 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +
> > +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
> > +#define __SOC_MEDIATEK_MT8195_MMSYS_H
> > +
> > +#define MT8195_VDO0_OVL_MOUT_EN					
> > 0xf14
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			
> > BIT(0)
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			
> > BIT(1)
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
> > +#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			
> > BIT(4)
> > +#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			
> > BIT(5)
> > +#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
> > +
> > +#define MT8195_VDO0_SEL_IN					0xf34
> > +#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		(0 <<
> > 0)
> > +#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		(1 <<
> > 0)
> > +#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		(2 <<
> > 0)
> > +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		
> > (0 << 4)
> > +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		(1 <<
> > 4)
> > +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		
> > (0 << 5)
> > +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		(1 <<
> > 5)
> > +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		(0 <<
> > 8)
> > +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		
> > (1 << 8)
> > +#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		
> > (0 << 9)
> > +#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		(0 <<
> > 12)
> > +#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			
> > (1 << 12)
> > +#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		(2 <<
> > 12)
> > +#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			
> > (0 << 16)
> > +#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			
> > (1 << 16)
> > +#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			
> > (0 << 17)
> > +#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			(1 <<
> > 17)
> > +#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			
> > (0 << 20)
> > +#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			
> > (1 << 20)
> > +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		
> > (0 << 21)
> > +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		
> > (1 << 21)
> > +#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			
> > (0 << 22)
> > +#define MT8195_SEL_IN_DISP_WDMA0_FROM_VPP_MERGE			
> > (1 << 22)
> > +
> > +#define MT8195_VDO0_SEL_OUT					
> > 0xf38
> > +#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		(0 <<
> > 0)
> > +#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			(1 <<
> > 0)
> > +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		(0 <<
> > 1)
> > +#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			
> > (1 << 1)
> > +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		(2 <<
> > 1)
> > +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			
> > (0 << 4)
> > +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			
> > (1 << 4)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DSI1				
> > (0 << 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			(1 <<
> > 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			
> > (2 << 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			
> > (3 << 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			
> > (4 << 8)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			
> > (0 << 11)
> > +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA0			
> > (1 << 11)
> > +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			(0 <<
> > 12)
> > +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		(1 <<
> > 12)
> > +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			
> > (2 << 12)
> > +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			(0 <<
> > 16)
> > +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			
> > (1 << 16)
> > +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 <<
> > 16)
> > +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			
> > (3 << 16)
> > +
> > +static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[]
> > = {
> > +	{
> > +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> > +		MT8195_VDO0_OVL_MOUT_EN,
> > MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
> 
> Please update the struct to the new version that includes a mask
> field.
> 

OK, I'll add [2] before my patch and also test it on mt8195 SoC
platform.
[2] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20210729070549.5514-1-linux at fw-web.de/


> Regards,
> Matthias
-- 
Regards,
Jason-JH Lin <jason-jh.lin at mediatek.com>

From jason-jh.lin at mediatek.com  Wed Aug 11 09:12:54 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Thu, 12 Aug 2021 00:12:54 +0800
Subject: [PATCH v6 6/7] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <CAAOTY_9PRNyoegE2QewoKHCR3mfP9Szh3JMW4bL1WcRcC4Yk3A@mail.gmail.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-7-jason-jh.lin@mediatek.com>
 <CAAOTY_9PRNyoegE2QewoKHCR3mfP9Szh3JMW4bL1WcRcC4Yk3A@mail.gmail.com>
Message-ID: <dc520ebecebd9799ebdc2daecc777af26038cfca.camel@mediatek.com>

On Sat, 2021-08-07 at 01:10 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?6? ?? ??4:52???
> > 
> > Add MERGE engine file:
> > MERGE module is used to merge two slice-per-line inputs
> > into one side-by-side output.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> > This patch is base on [1]
> > 
> > [1] dt-bindings: mediatek: display: add mt8195 SoC binding
> > 
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-5-jason-jh.lin at mediatek.com/__;!!CTRNKA9wMg0ARbw!yUTG6rzENI8VUIZjGy5JTWKNX2TyyJn_wn66Wnx2J2GxzFaIhl21IuF8ZlfTqAyj6ahi$
> >  
> > ---
> >  drivers/gpu/drm/mediatek/Makefile           |   1 +
> >  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
> >  drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 263
> > ++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   4 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
> >  6 files changed, 277 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > 
> > diff --git a/drivers/gpu/drm/mediatek/Makefile
> > b/drivers/gpu/drm/mediatek/Makefile
> > index dc54a7a69005..538e0087a44c 100644
> > --- a/drivers/gpu/drm/mediatek/Makefile
> > +++ b/drivers/gpu/drm/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >  mediatek-drm-y := mtk_disp_ccorr.o \
> >                   mtk_disp_color.o \
> >                   mtk_disp_gamma.o \
> > +                 mtk_disp_merge.o \
> >                   mtk_disp_ovl.o \
> >                   mtk_disp_rdma.o \
> >                   mtk_drm_crtc.o \
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > index cafd9df2d63b..f407cd9d873e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > @@ -46,6 +46,14 @@ void mtk_gamma_set_common(void __iomem *regs,
> > struct drm_crtc_state *state);
> >  void mtk_gamma_start(struct device *dev);
> >  void mtk_gamma_stop(struct device *dev);
> > 
> > +int mtk_merge_clk_enable(struct device *dev);
> > +void mtk_merge_clk_disable(struct device *dev);
> > +void mtk_merge_config(struct device *dev, unsigned int width,
> > +                     unsigned int height, unsigned int vrefresh,
> > +                     unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> > +void mtk_merge_start(struct device *dev);
> > +void mtk_merge_stop(struct device *dev);
> > +
> >  void mtk_ovl_bgclr_in_on(struct device *dev);
> >  void mtk_ovl_bgclr_in_off(struct device *dev);
> >  void mtk_ovl_bypass_shadow(struct device *dev);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > new file mode 100644
> > index 000000000000..f3d262792054
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > @@ -0,0 +1,263 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/component.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/soc/mediatek/mtk-cmdq.h>
> > +
> > +#include "mtk_drm_ddp_comp.h"
> > +#include "mtk_drm_drv.h"
> > +#include "mtk_disp_drv.h"
> > +
> > +#define DISP_REG_MERGE_CTRL            0x000
> > +#define MERGE_EN                       1
> 
> One more indent for the bitwise value.

OK, I'll fix this.
> 
> > +#define DISP_REG_MERGE_CFG_0           0x010
> > +#define DISP_REG_MERGE_CFG_4           0x020
> > +#define DISP_REG_MERGE_CFG_10          0x038
> > +/* no swap */
> > +#define SWAP_MODE                      0
> > +#define FLD_SWAP_MODE                  GENMASK(4, 0)
> > +#define DISP_REG_MERGE_CFG_12          0x040
> > +#define CFG_10_10_1PI_2PO_BUF_MODE     6
> > +#define CFG_10_10_2PI_2PO_BUF_MODE     8
> > +#define FLD_CFG_MERGE_MODE             GENMASK(4, 0)
> > +#define DISP_REG_MERGE_CFG_24          0x070
> > +#define DISP_REG_MERGE_CFG_25          0x074
> > +#define DISP_REG_MERGE_CFG_36          0x0a0
> > +#define ULTRA_EN                       1
> > +#define PREULTRA_EN                    1
> > +#define HALT_FOR_DVFS_EN               0
> > +#define FLD_ULTRA_EN                   GENMASK(0, 0)
> > +#define FLD_PREULTRA_EN                        GENMASK(4, 4)
> > +#define FLD_HALT_FOR_DVFS_EN           GENMASK(8, 8)
> > +#define DISP_REG_MERGE_CFG_37          0x0a4
> > +/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
> > +#define BUFFER_MODE                    3
> > +#define FLD_BUFFER_MODE                        GENMASK(1, 0)
> > +#define DISP_REG_MERGE_CFG_38          0x0a8
> > +#define FLD_VDE_BLOCK_ULTRA            GENMASK(0, 0)
> > +#define FLD_VALID_TH_BLOCK_ULTRA       GENMASK(4, 4)
> > +#define FLD_ULTRA_FIFO_VALID_TH                GENMASK(31, 16)
> > +#define DISP_REG_MERGE_CFG_39          0x0ac
> > +#define FLD_NVDE_FORCE_PREULTRA                GENMASK(8, 8)
> > +#define FLD_NVALID_TH_FORCE_PREULTRA   GENMASK(12, 12)
> > +#define FLD_PREULTRA_FIFO_VALID_TH     GENMASK(31, 16)
> > +#define DISP_REG_MERGE_CFG_40          0x0b0
> > +/* 6 us, 600M pixel/sec */
> > +#define ULTRA_TH_LOW                   (6 * 600)
> > +/* 8 us, 600M pixel/sec */
> > +#define ULTRA_TH_HIGH                  (8 * 600)
> > +#define FLD_ULTRA_TH_LOW               GENMASK(15, 0)
> > +#define FLD_ULTRA_TH_HIGH              GENMASK(31, 16)
> > +#define DISP_REG_MERGE_CFG_41          0x0b4
> > +/* 8 us, 600M pixel/sec */
> > +#define PREULTRA_TH_LOW                        (8 * 600)
> > +/* 9 us, 600M pixel/sec */
> 
> Add comment that "6 us ~ 9us is experience value and max mmsys clock
> frequency is 594MHz", and I think you should use 594 instead of 600.
> 
> Regards,
> Chun-Kuang.
> 
OK, I'll add this comment and use 594 instead of 600.

Regards,
Jason-JH.Lin

> > +#define PREULTRA_TH_HIGH               (9 * 600)
> > +#define FLD_PREULTRA_TH_LOW            GENMASK(15, 0)
> > +#define FLD_PREULTRA_TH_HIGH           GENMASK(31, 16)
> > +
> > +struct mtk_disp_merge {
> > +       void __iomem *regs;
> > +       struct clk *clk;
> > +       struct clk *async_clk;
> > +       struct cmdq_client_reg          cmdq_reg;
> > +       bool                            fifo_en;
> > +};
> > +
> > +void mtk_merge_start(struct device *dev)
> > +{
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +
> > +       writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
> > +}
> > +
> > +void mtk_merge_stop(struct device *dev)
> > +{
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +
> > +       writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
> > +}
> > +
> > +static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
> > +                                  struct cmdq_pkt *handle)
> > +{
> > +       mtk_ddp_write_mask(handle, ULTRA_EN | PREULTRA_EN << 4 |
> > HALT_FOR_DVFS_EN << 8,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_REG_MERGE_CFG_36,
> > +                          FLD_ULTRA_EN | FLD_PREULTRA_EN |
> > FLD_HALT_FOR_DVFS_EN);
> > +
> > +       mtk_ddp_write_mask(handle, BUFFER_MODE,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_REG_MERGE_CFG_37,
> > +                          FLD_BUFFER_MODE);
> > +
> > +       mtk_ddp_write_mask(handle, 0,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_REG_MERGE_CFG_38,
> > +                          FLD_VDE_BLOCK_ULTRA |
> > FLD_VALID_TH_BLOCK_ULTRA |
> > +                          FLD_ULTRA_FIFO_VALID_TH);
> > +
> > +       mtk_ddp_write_mask(handle, 0,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_REG_MERGE_CFG_39,
> > +                          FLD_NVDE_FORCE_PREULTRA |
> > FLD_NVALID_TH_FORCE_PREULTRA |
> > +                          FLD_PREULTRA_FIFO_VALID_TH);
> > +
> > +       mtk_ddp_write_mask(handle, ULTRA_TH_LOW | ULTRA_TH_HIGH <<
> > 16,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_REG_MERGE_CFG_40,
> > +                          FLD_ULTRA_TH_LOW | FLD_ULTRA_TH_HIGH);
> > +
> > +       mtk_ddp_write_mask(handle, PREULTRA_TH_LOW |
> > PREULTRA_TH_HIGH << 16,
> > +                          &priv->cmdq_reg, priv->regs,
> > DISP_REG_MERGE_CFG_41,
> > +                          FLD_PREULTRA_TH_LOW |
> > FLD_PREULTRA_TH_HIGH);
> > +}
> > +
> > +void mtk_merge_config(struct device *dev, unsigned int w,
> > +                     unsigned int h, unsigned int vrefresh,
> > +                     unsigned int bpc, struct cmdq_pkt *handle)
> > +{
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +       unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
> > +
> > +       if (!h || !w) {
> > +               dev_err(dev, "%s: input width(%d) or height(%d) is
> > invalid\n", __func__, w, h);
> > +               return;
> > +       }
> > +
> > +       if (priv->fifo_en) {
> > +               mtk_merge_fifo_setting(priv, handle);
> > +               mode = CFG_10_10_2PI_2PO_BUF_MODE;
> > +       }
> > +
> > +       mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv-
> > >regs,
> > +                     DISP_REG_MERGE_CFG_0);
> > +       mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv-
> > >regs,
> > +                     DISP_REG_MERGE_CFG_4);
> > +       mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv-
> > >regs,
> > +                     DISP_REG_MERGE_CFG_24);
> > +       mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv-
> > >regs,
> > +                     DISP_REG_MERGE_CFG_25);
> > +       mtk_ddp_write_mask(handle, SWAP_MODE, &priv->cmdq_reg,
> > priv->regs,
> > +                          DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
> > +       mtk_ddp_write_mask(handle, mode, &priv->cmdq_reg, priv-
> > >regs,
> > +                          DISP_REG_MERGE_CFG_12,
> > FLD_CFG_MERGE_MODE);
> > +}
> > +
> > +int mtk_merge_clk_enable(struct device *dev)
> > +{
> > +       int ret = 0;
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +
> > +       ret = clk_prepare_enable(priv->clk);
> > +       if (ret)
> > +               pr_err("merge clk prepare enable failed\n");
> > +
> > +       if (priv->async_clk) {
> > +               ret = clk_prepare_enable(priv->async_clk);
> > +               if (ret)
> > +                       pr_err("async clk prepare enable
> > failed\n");
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +void mtk_merge_clk_disable(struct device *dev)
> > +{
> > +       struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> > +
> > +       if (priv->async_clk)
> > +               clk_disable_unprepare(priv->async_clk);
> > +
> > +       clk_disable_unprepare(priv->clk);
> > +}
> > +
> > +static int mtk_disp_merge_bind(struct device *dev, struct device
> > *master,
> > +                              void *data)
> > +{
> > +       return 0;
> > +}
> > +
> > +static void mtk_disp_merge_unbind(struct device *dev, struct
> > device *master,
> > +                                 void *data)
> > +{
> > +}
> > +
> > +static const struct component_ops mtk_disp_merge_component_ops = {
> > +       .bind   = mtk_disp_merge_bind,
> > +       .unbind = mtk_disp_merge_unbind,
> > +};
> > +
> > +static int mtk_disp_merge_probe(struct platform_device *pdev)
> > +{
> > +       struct device *dev = &pdev->dev;
> > +       struct resource *res;
> > +       struct mtk_disp_merge *priv;
> > +       int ret;
> > +
> > +       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +       if (!priv)
> > +               return -ENOMEM;
> > +
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       priv->regs = devm_ioremap_resource(dev, res);
> > +       if (IS_ERR(priv->regs)) {
> > +               dev_err(dev, "failed to ioremap merge\n");
> > +               return PTR_ERR(priv->regs);
> > +       }
> > +
> > +       priv->clk = devm_clk_get(dev, NULL);
> > +       if (IS_ERR(priv->clk)) {
> > +               dev_err(dev, "failed to get merge clk\n");
> > +               return PTR_ERR(priv->clk);
> > +       }
> > +
> > +       priv->async_clk = of_clk_get(dev->of_node, 1);
> > +       if (IS_ERR(priv->async_clk)) {
> > +               ret = PTR_ERR(priv->async_clk);
> > +               dev_dbg(dev, "No merge async clock: %d\n", ret);
> > +               priv->async_clk = NULL;
> > +       }
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +       ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
> > +       if (ret)
> > +               dev_dbg(dev, "get mediatek,gce-client-reg
> > fail!\n");
> > +#endif
> > +
> > +       priv->fifo_en = of_property_read_bool(dev->of_node,
> > +                                             "mediatek,merge-fifo-
> > en");
> > +
> > +       platform_set_drvdata(pdev, priv);
> > +
> > +       ret = component_add(dev, &mtk_disp_merge_component_ops);
> > +       if (ret != 0)
> > +               dev_err(dev, "Failed to add component: %d\n", ret);
> > +
> > +       return ret;
> > +}
> > +
> > +static int mtk_disp_merge_remove(struct platform_device *pdev)
> > +{
> > +       component_del(&pdev->dev, &mtk_disp_merge_component_ops);
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id mtk_disp_merge_driver_dt_match[]
> > = {
> > +       { .compatible = "mediatek,mt8195-disp-merge", },
> > +       {},
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
> > +
> > +struct platform_driver mtk_disp_merge_driver = {
> > +       .probe = mtk_disp_merge_probe,
> > +       .remove = mtk_disp_merge_remove,
> > +       .driver = {
> > +               .name = "mediatek-disp-merge",
> > +               .owner = THIS_MODULE,
> > +               .of_match_table = mtk_disp_merge_driver_dt_match,
> > +       },
> > +};
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index 560be6bc9d0e..b42a47c06956 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -25,6 +25,7 @@ enum mtk_ddp_comp_type {
> >         MTK_DISP_DITHER,
> >         MTK_DISP_DSC,
> >         MTK_DISP_GAMMA,
> > +       MTK_DISP_MERGE,
> >         MTK_DISP_MUTEX,
> >         MTK_DISP_OD,
> >         MTK_DISP_OVL,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index a95dc1006b82..5eb9c0a04447 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -532,13 +532,14 @@ static int mtk_drm_probe(struct
> > platform_device *pdev)
> >                 private->comp_node[comp_id] = of_node_get(node);
> > 
> >                 /*
> > -                * Currently only the CCORR, COLOR, GAMMA, OVL,
> > RDMA, DSI, and DPI
> > +                * Currently only the CCORR, COLOR, GAMMA, MERGE,
> > OVL, RDMA, DSI, and DPI
> >                  * blocks have separate component platform drivers
> > and initialize their own
> >                  * DDP component structure. The others are
> > initialized here.
> >                  */
> >                 if (comp_type == MTK_DISP_CCORR ||
> >                     comp_type == MTK_DISP_COLOR ||
> >                     comp_type == MTK_DISP_GAMMA ||
> > +                   comp_type == MTK_DISP_MERGE ||
> >                     comp_type == MTK_DISP_OVL ||
> >                     comp_type == MTK_DISP_OVL_2L ||
> >                     comp_type == MTK_DISP_RDMA ||
> > @@ -639,6 +640,7 @@ static struct platform_driver * const
> > mtk_drm_drivers[] = {
> >         &mtk_disp_ccorr_driver,
> >         &mtk_disp_color_driver,
> >         &mtk_disp_gamma_driver,
> > +       &mtk_disp_merge_driver,
> >         &mtk_disp_ovl_driver,
> >         &mtk_disp_rdma_driver,
> >         &mtk_dpi_driver,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > index 637f5669e895..0fa417219a69 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> > @@ -49,6 +49,7 @@ struct mtk_drm_private {
> >  extern struct platform_driver mtk_disp_ccorr_driver;
> >  extern struct platform_driver mtk_disp_color_driver;
> >  extern struct platform_driver mtk_disp_gamma_driver;
> > +extern struct platform_driver mtk_disp_merge_driver;
> >  extern struct platform_driver mtk_disp_ovl_driver;
> >  extern struct platform_driver mtk_disp_rdma_driver;
> >  extern struct platform_driver mtk_dpi_driver;
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From andrew at lunn.ch  Wed Aug 11 09:16:16 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 11 Aug 2021 18:16:16 +0200
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <VI1PR04MB6800EE08F70CC3F0DD53C991E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
 <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <YRKOGYwx1uVdsKoF@lunn.ch>
 <VI1PR04MB6800EE08F70CC3F0DD53C991E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>
Message-ID: <YRP30Mb8NaD4FjQj@lunn.ch>

> So I would prefer solution 1, it's easier and under-control.

Hi Joakim

Using quirks is fine by me.

      Andrew


From jason-jh.lin at mediatek.com  Wed Aug 11 09:16:28 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Thu, 12 Aug 2021 00:16:28 +0800
Subject: [PATCH v6 5/7] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <CAAOTY__f9TmyUaZe8O5aAfebftJc2B7BWchhZ8DWk+SWKTDF-w@mail.gmail.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-6-jason-jh.lin@mediatek.com>
 <CAAOTY__f9TmyUaZe8O5aAfebftJc2B7BWchhZ8DWk+SWKTDF-w@mail.gmail.com>
Message-ID: <54f152350fa983ba06d8f9507be02eb68d9ab7a1.camel@mediatek.com>

Hi CK,

On Sat, 2021-08-07 at 00:44 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?6? ?? ??4:52???
> > 
> > DSC is designed for real-time systems with real-time compression,
> > transmission, decompression and display.
> > The DSC standard is a specification of the algorithms used for
> > compressing and decompressing image display streams, including
> > the specification of the syntax and semantics of the compressed
> > video bit stream.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> > This patch is base on [1]
> > 
> > [1] dt-bindings: mediatek: add mediatek, dsc.yaml for mt8195 SoC
> > binding
> > 
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210805171346.24249-4-jason-jh.lin at mediatek.com/__;!!CTRNKA9wMg0ARbw!z1RWCIbQoMLarG_-uxUAQS__rpGyCB2Xk7IFVb_Vbo-RoXrWDE4cLvcERABbW11zbL1o$
> >  
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 62
> > +++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
> >  2 files changed, 63 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 328ee19f931e..24c7b004fe4d 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -43,6 +43,12 @@
> >  #define DITHER_LSB_ERR_SHIFT_G(x)              (((x) & 0x7) << 12)
> >  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
> > 
> > +#define DISP_REG_DSC_CON                       0x0000
> > +#define DSC_EN                                 BIT(0)
> > +#define DSC_DUAL_INOUT                         BIT(2)
> > +#define DSC_BYPASS                             BIT(4)
> > +#define DSC_UFOE_SEL                           BIT(16)
> > +
> >  #define DISP_REG_OD_EN                         0x0000
> >  #define DISP_REG_OD_CFG                                0x0020
> >  #define OD_RELAYMODE                           BIT(0)
> > @@ -209,6 +215,35 @@ static void mtk_dither_set(struct device *dev,
> > unsigned int bpc,
> >                               DISP_DITHERING, cmdq_pkt);
> >  }
> > 
> > +static void mtk_dsc_config(struct device *dev, unsigned int w,
> > +                          unsigned int h, unsigned int vrefresh,
> > +                          unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       /* dsc bypass mode */
> > +       mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg,
> > priv->regs,
> > +                          DISP_REG_DSC_CON, DSC_BYPASS);
> > +       mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, 
> > priv->regs,
> > +                          DISP_REG_DSC_CON, DSC_UFOE_SEL);
> > +       mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv-
> > >cmdq_reg, priv->regs,
> > +                          DISP_REG_DSC_CON, DSC_DUAL_INOUT);
> > +}
> > +
> > +static void mtk_dsc_start(struct device *dev)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       writel_relaxed(DSC_EN, &priv->regs + DISP_REG_DSC_CON);
> > +}
> > +
> > +static void mtk_dsc_stop(struct device *dev)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
> > +}
> > +
> >  static void mtk_od_config(struct device *dev, unsigned int w,
> >                           unsigned int h, unsigned int vrefresh,
> >                           unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > @@ -272,6 +307,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi
> > = {
> >         .stop = mtk_dpi_stop,
> >  };
> > 
> > +static const struct mtk_ddp_comp_funcs ddp_dsc = {
> > +       .clk_enable = mtk_ddp_clk_enable,
> > +       .clk_disable = mtk_ddp_clk_disable,
> > +       .config = mtk_dsc_config,
> > +       .start = mtk_dsc_start,
> > +       .stop = mtk_dsc_stop,
> > +};
> > +
> >  static const struct mtk_ddp_comp_funcs ddp_dsi = {
> >         .start = mtk_dsi_ddp_start,
> >         .stop = mtk_dsi_ddp_stop,
> > @@ -286,6 +329,14 @@ static const struct mtk_ddp_comp_funcs
> > ddp_gamma = {
> >         .stop = mtk_gamma_stop,
> >  };
> > 
> > +static const struct mtk_ddp_comp_funcs ddp_merge = {
> > +       .clk_enable = mtk_merge_clk_enable,
> > +       .clk_disable = mtk_merge_clk_disable,
> > +       .start = mtk_merge_start,
> > +       .stop = mtk_merge_stop,
> > +       .config = mtk_merge_config,
> > +};
> 
> Move the merge modification to the patch of merge.
> > +
> >  static const struct mtk_ddp_comp_funcs ddp_od = {
> >         .clk_enable = mtk_ddp_clk_enable,
> >         .clk_disable = mtk_ddp_clk_disable,
> > @@ -333,7 +384,9 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >         [MTK_DISP_CCORR] = "ccorr",
> >         [MTK_DISP_COLOR] = "color",
> >         [MTK_DISP_DITHER] = "dither",
> > +       [MTK_DISP_DSC] = "dsc",
> >         [MTK_DISP_GAMMA] = "gamma",
> > +       [MTK_DISP_MERGE] = "merge",
> 
> Ditto.
> 
> >         [MTK_DISP_MUTEX] = "mutex",
> >         [MTK_DISP_OD] = "od",
> >         [MTK_DISP_OVL] = "ovl",
> > @@ -362,11 +415,19 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
> >         [DDP_COMPONENT_DITHER]  = { MTK_DISP_DITHER,    0,
> > &ddp_dither },
> >         [DDP_COMPONENT_DPI0]    = { MTK_DPI,            0, &ddp_dpi
> > },
> >         [DDP_COMPONENT_DPI1]    = { MTK_DPI,            1, &ddp_dpi
> > },
> > +       [DDP_COMPONENT_DSC0]    = { MTK_DISP_DSC,       0, &ddp_dsc
> > },
> > +       [DDP_COMPONENT_DSC1]    = { MTK_DISP_DSC,       1, &ddp_dsc
> > },
> >         [DDP_COMPONENT_DSI0]    = { MTK_DSI,            0, &ddp_dsi
> > },
> >         [DDP_COMPONENT_DSI1]    = { MTK_DSI,            1, &ddp_dsi
> > },
> >         [DDP_COMPONENT_DSI2]    = { MTK_DSI,            2, &ddp_dsi
> > },
> >         [DDP_COMPONENT_DSI3]    = { MTK_DSI,            3, &ddp_dsi
> > },
> >         [DDP_COMPONENT_GAMMA]   = { MTK_DISP_GAMMA,     0,
> > &ddp_gamma },
> > +       [DDP_COMPONENT_MERGE0]  = { MTK_DISP_MERGE,     0,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE1]  = { MTK_DISP_MERGE,     1,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE2]  = { MTK_DISP_MERGE,     2,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE3]  = { MTK_DISP_MERGE,     3,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE4]  = { MTK_DISP_MERGE,     4,
> > &ddp_merge },
> > +       [DDP_COMPONENT_MERGE5]  = { MTK_DISP_MERGE,     5,
> > &ddp_merge },
> 
> Ditto.
> 
> >         [DDP_COMPONENT_OD0]     = { MTK_DISP_OD,        0, &ddp_od
> > },
> >         [DDP_COMPONENT_OD1]     = { MTK_DISP_OD,        1, &ddp_od
> > },
> >         [DDP_COMPONENT_OVL0]    = { MTK_DISP_OVL,       0, &ddp_ovl
> > },
> > @@ -497,6 +558,7 @@ int mtk_ddp_comp_init(struct device_node *node,
> > struct mtk_ddp_comp *comp,
> >             type == MTK_DISP_CCORR ||
> >             type == MTK_DISP_COLOR ||
> >             type == MTK_DISP_GAMMA ||
> > +           type == MTK_DISP_MERGE ||
> 
> Ditto.
> 
> Regards,
> Chun-Kuang.
> 

OK, I'll move them into MERGE patch.

Regards,
Jason-JH.Lin
> >             type == MTK_DISP_OVL ||
> >             type == MTK_DISP_OVL_2L ||
> >             type == MTK_DISP_PWM ||
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index d317b944df66..560be6bc9d0e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
> >         MTK_DISP_CCORR,
> >         MTK_DISP_COLOR,
> >         MTK_DISP_DITHER,
> > +       MTK_DISP_DSC,
> >         MTK_DISP_GAMMA,
> >         MTK_DISP_MUTEX,
> >         MTK_DISP_OD,
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From jason-jh.lin at mediatek.com  Wed Aug 11 09:23:46 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Thu, 12 Aug 2021 00:23:46 +0800
Subject: [PATCH v6 4/7] drm/mediatek: adjust to the alphabetic order for
 mediatek-drm
In-Reply-To: <CAAOTY_9EajkTgyjV2F3K+S-Y=yZUbRg2maE34e73=FOnJsgjRg@mail.gmail.com>
References: <20210805205226.24880-1-jason-jh.lin@mediatek.com>
 <20210805205226.24880-5-jason-jh.lin@mediatek.com>
 <CAAOTY_9EajkTgyjV2F3K+S-Y=yZUbRg2maE34e73=FOnJsgjRg@mail.gmail.com>
Message-ID: <040fe02a1cc1de4b055d92f09322ad6aafb21565.camel@mediatek.com>

Hi CK,

On Mon, 2021-08-09 at 22:34 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?6? ?? ??4:52???
> > 
> > 1. Adjust to the alphabetic order for the define, function, struct
> >    and array in mediatek-drm driver
> > 2. Remove the unsed define in mtk_drm_ddp_comp.c
> 
> Separate the 2nd part to another patch.

OK, I'll separate them.

> 
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 180 +++++++++-------
> > ----
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  22 +--
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  76 ++++-----
> >  3 files changed, 133 insertions(+), 145 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 75bc00e17fc4..328ee19f931e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -20,50 +20,36 @@
> >  #include "mtk_drm_ddp_comp.h"
> >  #include "mtk_drm_crtc.h"
> > 
> > -#define DISP_OD_EN                             0x0000
> > -#define DISP_OD_INTEN                          0x0008
> > -#define DISP_OD_INTSTA                         0x000c
> > -#define DISP_OD_CFG                            0x0020
> > -#define DISP_OD_SIZE                           0x0030
> > -#define DISP_DITHER_5                          0x0114
> > -#define DISP_DITHER_7                          0x011c
> > -#define DISP_DITHER_15                         0x013c
> > -#define DISP_DITHER_16                         0x0140
> > -
> > -#define DISP_REG_UFO_START                     0x0000
> > -
> > -#define DISP_AAL_EN                            0x0000
> > -#define DISP_AAL_SIZE                          0x0030
> > +#define DISP_REG_AAL_EN                                0x0000
> > +#define AAL_EN                                 BIT(0)
> > +#define DISP_REG_AAL_SIZE                      0x0030
> > 
> > -#define DISP_DITHER_EN                         0x0000
> > +#define DISP_REG_DITHER_EN                     0x0000
> 
> I think we should not change the register name just for alphabetic
> order. We list the register in the order of its address.
> If you have another reason to change register name, add another patch
> to do this.
> 
> Regards,
> Chun-Kuang.

I think using DISP_REG prifix can identify the macro of register offset
and register value.

So I'll revert the changing of register name in this alphabetic order
patch and send this into another patch.

Regards,
Jason-JH.Lin
> 
> >  #define DITHER_EN                              BIT(0)
> > -#define DISP_DITHER_CFG                                0x0020
> > +#define DISP_REG_DITHER_CFG                    0x0020
> >  #define DITHER_RELAY_MODE                      BIT(0)
> >  #define DITHER_ENGINE_EN                       BIT(1)
> > -#define DISP_DITHER_SIZE                       0x0030
> > -
> > -#define LUT_10BIT_MASK                         0x03ff
> > -
> > -#define OD_RELAYMODE                           BIT(0)
> > -
> > -#define UFO_BYPASS                             BIT(2)
> > -
> > -#define AAL_EN                                 BIT(0)
> > -
> >  #define DISP_DITHERING                         BIT(2)
> > +#define DISP_REG_DITHER_SIZE                   0x0030
> > +#define DISP_REG_DITHER_5                      0x0114
> > +#define DISP_REG_DITHER_7                      0x011c
> > +#define DISP_REG_DITHER_15                     0x013c
> >  #define DITHER_LSB_ERR_SHIFT_R(x)              (((x) & 0x7) << 28)
> > -#define DITHER_OVFLW_BIT_R(x)                  (((x) & 0x7) << 24)
> >  #define DITHER_ADD_LSHIFT_R(x)                 (((x) & 0x7) << 20)
> > -#define DITHER_ADD_RSHIFT_R(x)                 (((x) & 0x7) << 16)
> >  #define DITHER_NEW_BIT_MODE                    BIT(0)
> > +#define DISP_REG_DITHER_16                     0x0140
> >  #define DITHER_LSB_ERR_SHIFT_B(x)              (((x) & 0x7) << 28)
> > -#define DITHER_OVFLW_BIT_B(x)                  (((x) & 0x7) << 24)
> >  #define DITHER_ADD_LSHIFT_B(x)                 (((x) & 0x7) << 20)
> > -#define DITHER_ADD_RSHIFT_B(x)                 (((x) & 0x7) << 16)
> >  #define DITHER_LSB_ERR_SHIFT_G(x)              (((x) & 0x7) << 12)
> > -#define DITHER_OVFLW_BIT_G(x)                  (((x) & 0x7) << 8)
> >  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
> > -#define DITHER_ADD_RSHIFT_G(x)                 (((x) & 0x7) << 0)
> > +
> > +#define DISP_REG_OD_EN                         0x0000
> > +#define DISP_REG_OD_CFG                                0x0020
> > +#define OD_RELAYMODE                           BIT(0)
> > +#define DISP_REG_OD_SIZE                       0x0030
> > +
> > +#define DISP_REG_UFO_START                     0x0000
> > +#define UFO_BYPASS                             BIT(2)
> > 
> >  struct mtk_ddp_comp_dev {
> >         struct clk *clk;
> > @@ -116,20 +102,6 @@ void mtk_ddp_write_mask(struct cmdq_pkt
> > *cmdq_pkt, unsigned int value,
> >  #endif
> >  }
> > 
> > -static int mtk_ddp_clk_enable(struct device *dev)
> > -{
> > -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > -
> > -       return clk_prepare_enable(priv->clk);
> > -}
> > -
> > -static void mtk_ddp_clk_disable(struct device *dev)
> > -{
> > -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > -
> > -       clk_disable_unprepare(priv->clk);
> > -}
> > -
> >  void mtk_dither_set_common(void __iomem *regs, struct
> > cmdq_client_reg *cmdq_reg,
> >                            unsigned int bpc, unsigned int cfg,
> >                            unsigned int dither_en, struct cmdq_pkt
> > *cmdq_pkt)
> > @@ -139,55 +111,35 @@ void mtk_dither_set_common(void __iomem
> > *regs, struct cmdq_client_reg *cmdq_reg,
> >                 return;
> > 
> >         if (bpc >= MTK_MIN_BPC) {
> > -               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs,
> > DISP_DITHER_5);
> > -               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs,
> > DISP_DITHER_7);
> > +               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs,
> > DISP_REG_DITHER_5);
> > +               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs,
> > DISP_REG_DITHER_7);
> >                 mtk_ddp_write(cmdq_pkt,
> >                               DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC -
> > bpc) |
> >                               DITHER_ADD_LSHIFT_R(MTK_MAX_BPC -
> > bpc) |
> >                               DITHER_NEW_BIT_MODE,
> > -                             cmdq_reg, regs, DISP_DITHER_15);
> > +                             cmdq_reg, regs, DISP_REG_DITHER_15);
> >                 mtk_ddp_write(cmdq_pkt,
> >                               DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC -
> > bpc) |
> >                               DITHER_ADD_LSHIFT_B(MTK_MAX_BPC -
> > bpc) |
> >                               DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC -
> > bpc) |
> >                               DITHER_ADD_LSHIFT_G(MTK_MAX_BPC -
> > bpc),
> > -                             cmdq_reg, regs, DISP_DITHER_16);
> > +                             cmdq_reg, regs, DISP_REG_DITHER_16);
> >                 mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs,
> > cfg);
> >         }
> >  }
> > 
> > -static void mtk_dither_set(struct device *dev, unsigned int bpc,
> > -                   unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
> > -{
> > -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > -
> > -       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc,
> > cfg,
> > -                             DISP_DITHERING, cmdq_pkt);
> > -}
> > -
> > -static void mtk_od_config(struct device *dev, unsigned int w,
> > -                         unsigned int h, unsigned int vrefresh,
> > -                         unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > -{
> > -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > -
> > -       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv-
> > >regs, DISP_OD_SIZE);
> > -       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg,
> > priv->regs, DISP_OD_CFG);
> > -       mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
> > -}
> > -
> > -static void mtk_od_start(struct device *dev)
> > +static int mtk_ddp_clk_enable(struct device *dev)
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       writel(1, priv->regs + DISP_OD_EN);
> > +       return clk_prepare_enable(priv->clk);
> >  }
> > 
> > -static void mtk_ufoe_start(struct device *dev)
> > +static void mtk_ddp_clk_disable(struct device *dev)
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
> > +       clk_disable_unprepare(priv->clk);
> >  }
> > 
> >  static void mtk_aal_config(struct device *dev, unsigned int w,
> > @@ -196,7 +148,7 @@ static void mtk_aal_config(struct device *dev,
> > unsigned int w,
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv-
> > >regs, DISP_AAL_SIZE);
> > +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv-
> > >regs, DISP_REG_AAL_SIZE);
> >  }
> > 
> >  static void mtk_aal_gamma_set(struct device *dev, struct
> > drm_crtc_state *state)
> > @@ -210,14 +162,14 @@ static void mtk_aal_start(struct device *dev)
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       writel(AAL_EN, priv->regs + DISP_AAL_EN);
> > +       writel(AAL_EN, priv->regs + DISP_REG_AAL_EN);
> >  }
> > 
> >  static void mtk_aal_stop(struct device *dev)
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       writel_relaxed(0x0, priv->regs + DISP_AAL_EN);
> > +       writel_relaxed(0x0, priv->regs + DISP_REG_AAL_EN);
> >  }
> > 
> >  static void mtk_dither_config(struct device *dev, unsigned int w,
> > @@ -226,9 +178,11 @@ static void mtk_dither_config(struct device
> > *dev, unsigned int w,
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv-
> > >regs, DISP_DITHER_SIZE);
> > -       mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, 
> > priv->regs, DISP_DITHER_CFG);
> > -       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc,
> > DISP_DITHER_CFG,
> > +       mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv-
> > >regs,
> > +                     DISP_REG_DITHER_SIZE);
> > +       mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, 
> > priv->regs,
> > +                     DISP_REG_DITHER_CFG);
> > +       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc,
> > DISP_REG_DITHER_CFG,
> >                               DITHER_ENGINE_EN, cmdq_pkt);
> >  }
> > 
> > @@ -236,14 +190,48 @@ static void mtk_dither_start(struct device
> > *dev)
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
> > +       writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
> >  }
> > 
> >  static void mtk_dither_stop(struct device *dev)
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
> > +       writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
> > +}
> > +
> > +static void mtk_dither_set(struct device *dev, unsigned int bpc,
> > +                          unsigned int cfg, struct cmdq_pkt
> > *cmdq_pkt)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc,
> > cfg,
> > +                             DISP_DITHERING, cmdq_pkt);
> > +}
> > +
> > +static void mtk_od_config(struct device *dev, unsigned int w,
> > +                         unsigned int h, unsigned int vrefresh,
> > +                         unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv-
> > >regs, DISP_REG_OD_SIZE);
> > +       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg,
> > priv->regs, DISP_REG_OD_CFG);
> > +       mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
> > +}
> > +
> > +static void mtk_od_start(struct device *dev)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       writel(1, priv->regs + DISP_REG_OD_EN);
> > +}
> > +
> > +static void mtk_ufoe_start(struct device *dev)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
> >  }
> > 
> >  static const struct mtk_ddp_comp_funcs ddp_aal = {
> > @@ -340,22 +328,22 @@ static const struct mtk_ddp_comp_funcs
> > ddp_ufoe = {
> >  };
> > 
> >  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX]
> > = {
> > +       [MTK_DISP_AAL] = "aal",
> > +       [MTK_DISP_BLS] = "bls",
> > +       [MTK_DISP_CCORR] = "ccorr",
> > +       [MTK_DISP_COLOR] = "color",
> > +       [MTK_DISP_DITHER] = "dither",
> > +       [MTK_DISP_GAMMA] = "gamma",
> > +       [MTK_DISP_MUTEX] = "mutex",
> > +       [MTK_DISP_OD] = "od",
> >         [MTK_DISP_OVL] = "ovl",
> >         [MTK_DISP_OVL_2L] = "ovl-2l",
> > +       [MTK_DISP_PWM] = "pwm",
> >         [MTK_DISP_RDMA] = "rdma",
> > -       [MTK_DISP_WDMA] = "wdma",
> > -       [MTK_DISP_COLOR] = "color",
> > -       [MTK_DISP_CCORR] = "ccorr",
> > -       [MTK_DISP_AAL] = "aal",
> > -       [MTK_DISP_GAMMA] = "gamma",
> > -       [MTK_DISP_DITHER] = "dither",
> >         [MTK_DISP_UFOE] = "ufoe",
> > -       [MTK_DSI] = "dsi",
> > +       [MTK_DISP_WDMA] = "wdma",
> >         [MTK_DPI] = "dpi",
> > -       [MTK_DISP_PWM] = "pwm",
> > -       [MTK_DISP_MUTEX] = "mutex",
> > -       [MTK_DISP_OD] = "od",
> > -       [MTK_DISP_BLS] = "bls",
> > +       [MTK_DSI] = "dsi",
> >  };
> > 
> >  struct mtk_ddp_comp_match {
> > @@ -509,12 +497,12 @@ int mtk_ddp_comp_init(struct device_node
> > *node, struct mtk_ddp_comp *comp,
> >             type == MTK_DISP_CCORR ||
> >             type == MTK_DISP_COLOR ||
> >             type == MTK_DISP_GAMMA ||
> > -           type == MTK_DPI ||
> > -           type == MTK_DSI ||
> >             type == MTK_DISP_OVL ||
> >             type == MTK_DISP_OVL_2L ||
> >             type == MTK_DISP_PWM ||
> > -           type == MTK_DISP_RDMA)
> > +           type == MTK_DISP_RDMA ||
> > +           type == MTK_DPI ||
> > +           type == MTK_DSI)
> >                 return 0;
> > 
> >         priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index bb914d976cf5..d317b944df66 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -18,22 +18,22 @@ struct mtk_plane_state;
> >  struct drm_crtc_state;
> > 
> >  enum mtk_ddp_comp_type {
> > -       MTK_DISP_OVL,
> > -       MTK_DISP_OVL_2L,
> > -       MTK_DISP_RDMA,
> > -       MTK_DISP_WDMA,
> > -       MTK_DISP_COLOR,
> > +       MTK_DISP_AAL,
> > +       MTK_DISP_BLS,
> >         MTK_DISP_CCORR,
> > +       MTK_DISP_COLOR,
> >         MTK_DISP_DITHER,
> > -       MTK_DISP_AAL,
> >         MTK_DISP_GAMMA,
> > -       MTK_DISP_UFOE,
> > -       MTK_DSI,
> > -       MTK_DPI,
> > -       MTK_DISP_PWM,
> >         MTK_DISP_MUTEX,
> >         MTK_DISP_OD,
> > -       MTK_DISP_BLS,
> > +       MTK_DISP_OVL,
> > +       MTK_DISP_OVL_2L,
> > +       MTK_DISP_PWM,
> > +       MTK_DISP_RDMA,
> > +       MTK_DISP_UFOE,
> > +       MTK_DISP_WDMA,
> > +       MTK_DPI,
> > +       MTK_DSI,
> >         MTK_DDP_COMP_TYPE_MAX,
> >  };
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index b46bdb8985da..a95dc1006b82 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -396,50 +396,20 @@ static const struct component_master_ops
> > mtk_drm_ops = {
> >  };
> > 
> >  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
> > -       { .compatible = "mediatek,mt2701-disp-ovl",
> > -         .data = (void *)MTK_DISP_OVL },
> > -       { .compatible = "mediatek,mt8173-disp-ovl",
> > -         .data = (void *)MTK_DISP_OVL },
> > -       { .compatible = "mediatek,mt8183-disp-ovl",
> > -         .data = (void *)MTK_DISP_OVL },
> > -       { .compatible = "mediatek,mt8183-disp-ovl-2l",
> > -         .data = (void *)MTK_DISP_OVL_2L },
> > -       { .compatible = "mediatek,mt2701-disp-rdma",
> > -         .data = (void *)MTK_DISP_RDMA },
> > -       { .compatible = "mediatek,mt8173-disp-rdma",
> > -         .data = (void *)MTK_DISP_RDMA },
> > -       { .compatible = "mediatek,mt8183-disp-rdma",
> > -         .data = (void *)MTK_DISP_RDMA },
> > -       { .compatible = "mediatek,mt8173-disp-wdma",
> > -         .data = (void *)MTK_DISP_WDMA },
> > +       { .compatible = "mediatek,mt8173-disp-aal",
> > +         .data = (void *)MTK_DISP_AAL},
> >         { .compatible = "mediatek,mt8183-disp-ccorr",
> >           .data = (void *)MTK_DISP_CCORR },
> >         { .compatible = "mediatek,mt2701-disp-color",
> >           .data = (void *)MTK_DISP_COLOR },
> >         { .compatible = "mediatek,mt8173-disp-color",
> >           .data = (void *)MTK_DISP_COLOR },
> > -       { .compatible = "mediatek,mt8173-disp-aal",
> > -         .data = (void *)MTK_DISP_AAL},
> > +       { .compatible = "mediatek,mt8183-disp-dither",
> > +         .data = (void *)MTK_DISP_DITHER },
> >         { .compatible = "mediatek,mt8173-disp-gamma",
> >           .data = (void *)MTK_DISP_GAMMA, },
> >         { .compatible = "mediatek,mt8183-disp-gamma",
> >           .data = (void *)MTK_DISP_GAMMA, },
> > -       { .compatible = "mediatek,mt8183-disp-dither",
> > -         .data = (void *)MTK_DISP_DITHER },
> > -       { .compatible = "mediatek,mt8173-disp-ufoe",
> > -         .data = (void *)MTK_DISP_UFOE },
> > -       { .compatible = "mediatek,mt2701-dsi",
> > -         .data = (void *)MTK_DSI },
> > -       { .compatible = "mediatek,mt8173-dsi",
> > -         .data = (void *)MTK_DSI },
> > -       { .compatible = "mediatek,mt8183-dsi",
> > -         .data = (void *)MTK_DSI },
> > -       { .compatible = "mediatek,mt2701-dpi",
> > -         .data = (void *)MTK_DPI },
> > -       { .compatible = "mediatek,mt8173-dpi",
> > -         .data = (void *)MTK_DPI },
> > -       { .compatible = "mediatek,mt8183-dpi",
> > -         .data = (void *)MTK_DPI },
> >         { .compatible = "mediatek,mt2701-disp-mutex",
> >           .data = (void *)MTK_DISP_MUTEX },
> >         { .compatible = "mediatek,mt2712-disp-mutex",
> > @@ -448,12 +418,42 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >           .data = (void *)MTK_DISP_MUTEX },
> >         { .compatible = "mediatek,mt8183-disp-mutex",
> >           .data = (void *)MTK_DISP_MUTEX },
> > +       { .compatible = "mediatek,mt8173-disp-od",
> > +         .data = (void *)MTK_DISP_OD },
> > +       { .compatible = "mediatek,mt2701-disp-ovl",
> > +         .data = (void *)MTK_DISP_OVL },
> > +       { .compatible = "mediatek,mt8173-disp-ovl",
> > +         .data = (void *)MTK_DISP_OVL },
> > +       { .compatible = "mediatek,mt8183-disp-ovl",
> > +         .data = (void *)MTK_DISP_OVL },
> > +       { .compatible = "mediatek,mt8183-disp-ovl-2l",
> > +         .data = (void *)MTK_DISP_OVL_2L },
> >         { .compatible = "mediatek,mt2701-disp-pwm",
> >           .data = (void *)MTK_DISP_BLS },
> >         { .compatible = "mediatek,mt8173-disp-pwm",
> >           .data = (void *)MTK_DISP_PWM },
> > -       { .compatible = "mediatek,mt8173-disp-od",
> > -         .data = (void *)MTK_DISP_OD },
> > +       { .compatible = "mediatek,mt2701-disp-rdma",
> > +         .data = (void *)MTK_DISP_RDMA },
> > +       { .compatible = "mediatek,mt8173-disp-rdma",
> > +         .data = (void *)MTK_DISP_RDMA },
> > +       { .compatible = "mediatek,mt8183-disp-rdma",
> > +         .data = (void *)MTK_DISP_RDMA },
> > +       { .compatible = "mediatek,mt8173-disp-ufoe",
> > +         .data = (void *)MTK_DISP_UFOE },
> > +       { .compatible = "mediatek,mt8173-disp-wdma",
> > +         .data = (void *)MTK_DISP_WDMA },
> > +       { .compatible = "mediatek,mt2701-dpi",
> > +         .data = (void *)MTK_DPI },
> > +       { .compatible = "mediatek,mt8173-dpi",
> > +         .data = (void *)MTK_DPI },
> > +       { .compatible = "mediatek,mt8183-dpi",
> > +         .data = (void *)MTK_DPI },
> > +       { .compatible = "mediatek,mt2701-dsi",
> > +         .data = (void *)MTK_DSI },
> > +       { .compatible = "mediatek,mt8173-dsi",
> > +         .data = (void *)MTK_DSI },
> > +       { .compatible = "mediatek,mt8183-dsi",
> > +         .data = (void *)MTK_DSI },
> >         { }
> >  };
> > 
> > @@ -542,8 +542,8 @@ static int mtk_drm_probe(struct platform_device
> > *pdev)
> >                     comp_type == MTK_DISP_OVL ||
> >                     comp_type == MTK_DISP_OVL_2L ||
> >                     comp_type == MTK_DISP_RDMA ||
> > -                   comp_type == MTK_DSI ||
> > -                   comp_type == MTK_DPI) {
> > +                   comp_type == MTK_DPI ||
> > +                   comp_type == MTK_DSI) {
> >                         dev_info(dev, "Adding component match for
> > %pOF\n",
> >                                  node);
> >                         drm_of_component_match_add(dev, &match,
> > compare_of,
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From lukasz.luba at arm.com  Wed Aug 11 09:32:09 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Wed, 11 Aug 2021 17:32:09 +0100
Subject: [PATCH V2 9/9] cpufreq: scmi: Use .register_em() callback
In-Reply-To: <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
 <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
Message-ID: <143a03df-d858-b2de-a2cc-983c35d71e53@arm.com>



On 8/11/21 12:58 PM, Viresh Kumar wrote:
> Set the newly added .register_em() callback to register with the EM
> after the cpufreq policy is properly initialized.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>   drivers/cpufreq/scmi-cpufreq.c | 55 ++++++++++++++++++++--------------
>   1 file changed, 32 insertions(+), 23 deletions(-)

>   
> +static void scmi_cpufreq_register_em(struct cpufreq_policy *policy)
> +{
> +	struct em_data_callback em_cb = EM_DATA_CB(scmi_get_cpu_power);
> +	bool power_scale_mw = perf_ops->power_scale_mw_get(ph);
> +	struct scmi_data *priv = policy->driver_data;
> +
> +	em_dev_register_perf_domain(get_cpu_device(policy->cpu), priv->nr_opp,
> +				    &em_cb, priv->opp_shared_cpus,
> +				    power_scale_mw);

I would free the priv->opp_shared_cpus mask here, since we don't
need it anymore and memory can be reclaimed. Don't forget this
setup would be called N CPUs times, on this per-CPU policy platform.

If freed here, then also there wouldn't be a need to free it in
scmi_cpufreq_exit() so you can remove it from there.

> +}
> +
>   static struct cpufreq_driver scmi_cpufreq_driver = {
>   	.name	= "scmi",
>   	.flags	= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
> @@ -261,6 +269,7 @@ static struct cpufreq_driver scmi_cpufreq_driver = {
>   	.get	= scmi_cpufreq_get_rate,
>   	.init	= scmi_cpufreq_init,
>   	.exit	= scmi_cpufreq_exit,
> +	.register_em	= scmi_cpufreq_register_em,
>   };
>   
>   static int scmi_cpufreq_probe(struct scmi_device *sdev)
> 

I will test&review this patch on Monday when I re-flash custom FW to my
Juno (just to be sure that this per-CPU cpufreq + shared EM/EAS works).


From zajec5 at gmail.com  Wed Aug 11 09:55:07 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Wed, 11 Aug 2021 18:55:07 +0200
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <87r1f09md8.wl-maz@kernel.org>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
Message-ID: <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>

On 11.08.2021 14:50, Marc Zyngier wrote:
> On Wed, 11 Aug 2021 13:15:31 +0100,
> Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>>
>> Hi,
>>
>> I just tried upgrading from the old good LTS kernel 5.10 and I
>> discovered that my bcm4908 boards don't boot anymore with the 5.14-rc5.
>>
>>
>> The problem is kernel doesn't seem to start booting at all. I see CFE
>> bootloader messages:
>>
>> Starting program at 0x0000000000080000
>> /memory = 0x40000000
>>
>> and then nothing. Normally the first kernel line should follow like a:
>> Linux version 5.11.0-rc4 (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #30 SMP Wed Aug 11 14:01:00 CEST 2021
>>
>>
>> I have zero knowledge of low level arm64 or assembler stuff. I also
>> don't own any bcm4908 development board or bcm4908 datasheets.
>>
>> All I could do to help debugging this regression was bisecting. The
>> first bad commit (I verified it after bisecting process) is:
>>
>> commit 0c93df9622d4d921bcd0dc83f71fed9e98f5119f
>> Author: Marc Zyngier <maz at kernel.org>
>> Date:   Mon Feb 8 09:57:14 2021 +0000
>>
>>      arm64: Initialise as nVHE before switching to VHE
>>
>>      As we are aiming to be able to control whether we enable VHE or
>>      not, let's always drop down to EL1 first, and only then upgrade
>>      to VHE if at all possible.
>>
>>      This means that if the kernel is booted at EL2, we always start
>>      with a nVHE init, drop to EL1 to initialise the the kernel, and
>>      only then upgrade the kernel EL to EL2 if possible (the process
>>      is obviously shortened for secondary CPUs).
>>
>>      The resume path is handled similarly to a secondary CPU boot.
>>
>>      Signed-off-by: Marc Zyngier <maz at kernel.org>
>>      Acked-by: David Brazdil <dbrazdil at google.com>
>>      Acked-by: Catalin Marinas <catalin.marinas at arm.com>
>>      Link: https://lore.kernel.org/r/20210208095732.3267263-6-maz at kernel.org
>>      [will: Avoid calling switch_to_vhe twice on kaslr path]
>>      Signed-off-by: Will Deacon <will at kernel.org>
>>
>>
>> Could you look at this issue, please? I'm happy to test any patches or
>> provide any extra info I can obtain using kernel 5.11.
>>
>>
>> My defconfig for bcm4908 is:
> 
> [...]
> 
> I don't think the dconfig is that relevant (nothing you quote here
> would have an impact that early in the boot process).
> 
> On the other hand, a description of the platform (what CPUs does it
> have) and how it boots (VHE, non-VHE, booted at EL2 or not) would be
> extremely useful. At minimum, a boot log of a working kernel could
> help.

Thank you for your patience & reply.

BCM4908 is Broadcom's 64-bit platform with Broadcom's own Brahma-B53
CPU(s). I don't know how it boots. Is that something I can find out
from a running system?

For DTS SoC description you can check:
arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi

See below for bootlog and /proc/cpuinfo. Please note I seem to have
console misconfigured and early part of log appears twice (nothing
really harmful).

Starting program at 0x0000000000080000
/memory = 0x40000000
WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
Booting Linux on physical CPU 0x0000000000 [0x420f1000]
Linux version 5.11.22-g40462c7f0649 (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #9 SMP Wed Aug 11 18:39:58 CEST 2021
Machine model: Asus GT-AC5300
earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
printk: bootconsole [bcm63xx_uart0] enabled
efi: UEFI not found.
[Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
Zone ranges:
   DMA      [mem 0x0000000000000000-0x000000003fffffff]
   DMA32    empty
   Normal   empty
Movable zone start for each node
Early memory node ranges
   node   0: [mem 0x0000000000000000-0x000000003fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
percpu: Embedded 17 pages/cpu s37856 r0 d31776 u69632
Detected VIPT I-cache on CPU0
CPU features: detected: ARM erratum 843419
Built 1 zonelists, mobility grouping on.  Total pages: 258048
Kernel command line: earlycon=bcm63xx_uart,0xff800640
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 1020660K/1048576K available (3584K kernel code, 650K rwdata, 684K rodata, 2368K init, 229K bss, 27916K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
GIC: Using split EOI/Deactivate mode
random: get_random_bytes called from start_kernel+0x33c/0x524 with crng_init=0
arch_timer: cp15 timer(s) running at 50.00MHz (phys).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
Console: colour dummy device 80x25
printk: console [tty0] enabled
printk: bootconsole [bcm63xx_uart0] disabled
Booting Linux on physical CPU 0x0000000000 [0x420f1000]
Linux version 5.11.22-g40462c7f0649 (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #9 SMP Wed Aug 11 18:39:58 CEST 2021
Machine model: Asus GT-AC5300
earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
printk: bootconsole [bcm63xx_uart0] enabled
efi: UEFI not found.
[Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
Zone ranges:
   DMA      [mem 0x0000000000000000-0x000000003fffffff]
   DMA32    empty
   Normal   empty
Movable zone start for each node
Early memory node ranges
   node   0: [mem 0x0000000000000000-0x000000003fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
percpu: Embedded 17 pages/cpu s37856 r0 d31776 u69632
Detected VIPT I-cache on CPU0
CPU features: detected: ARM erratum 843419
Built 1 zonelists, mobility grouping on.  Total pages: 258048
Kernel command line: earlycon=bcm63xx_uart,0xff800640
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 1020660K/1048576K available (3584K kernel code, 650K rwdata, 684K rodata, 2368K init, 229K bss, 27916K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
GIC: Using split EOI/Deactivate mode
random: get_random_bytes called from start_kernel+0x33c/0x524 with crng_init=0
arch_timer: cp15 timer(s) running at 50.00MHz (phys).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
Console: colour dummy device 80x25
printk: console [tty0] enabled
printk: bootconsole [bcm63xx_uart0] disabled
Calibrating delay loop (skipped), value calculated using timer frequency.. 100.00 BogoMIPS (lpj=200000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
rcu: Hierarchical SRCU implementation.
EFI services will not be available.
smp: Bringing up secondary CPUs ...
Detected VIPT I-cache on CPU1
CPU1: Booted secondary processor 0x0000000001 [0x420f1000]
Detected VIPT I-cache on CPU2
CPU2: Booted secondary processor 0x0000000002 [0x420f1000]
Detected VIPT I-cache on CPU3
CPU3: Booted secondary processor 0x0000000003 [0x420f1000]
smp: Brought up 1 node, 4 CPUs
SMP: Total of 4 processors activated.
CPU features: detected: 32-bit EL0 Support
CPU features: detected: CRC32 instructions
CPU: All CPU(s) started at EL2
alternatives: patching kernel code
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
pinctrl core: initialized pinctrl subsystem
DMI not present or invalid.
DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
thermal_sys: Registered thermal governor 'step_wise'
ASID allocator initialised with 65536 entries
iommu: Default domain type: Translated
vgaarb: loaded
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
clocksource: Switched to clocksource arch_sys_counter
PCI: CLS 0 bytes, default 64
workingset: timestamp_bits=62 max_order=18 bucket_order=0
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
io scheduler mq-deadline registered
io scheduler kyber registered
basic-mmio-gpio: probe of ff800500.gpio-controller failed with error -22
ff800640.serial: ttyS0 at MMIO 0xff800640 (irq = 17, base_baud = 1562500) is a bcm63xx_uart
printk: console [ttyS0] enabled
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ehci-platform: EHCI generic platform driver
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-pci: OHCI PCI platform driver
ohci-platform: OHCI generic platform driver
i2c /dev entries driver
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
Freeing unused kernel memory: 2368K
Run /init as init process
tmpfs: Unknown parameter 'mode'
mount: mounting tmpfs: Unknown parameter 'mode'
tmpfs on /dev/shtmpfs: Unknown parameter 'mode'
m failed: Invalid argument
mount: mounting tmpfs on /tmp failed: Invalid argument
mount: mounting tmpfs on /run failed: Invalid argument
Starting syslogd: OK
Starting klogd: random: dd: uninitialized urandom read (512 bytes read)
OK
Running sysctl: OK
Saving random seed: OK
Starting network: ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
FAIL

Welcome to Buildroot
buildroot login:

# cat /proc/cpuinfo
processor       : 0
BogoMIPS        : 100.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
CPU implementer : 0x42
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0x100
CPU revision    : 0

processor       : 1
BogoMIPS        : 100.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
CPU implementer : 0x42
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0x100
CPU revision    : 0

processor       : 2
BogoMrandom: fast init done
IPS     : 100.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
CPU implementer : 0x42
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0x100
CPU revision    : 0

processor       : 3
BogoMIPS        : 100.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 cpuid
CPU implementer : 0x42
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0x100
CPU revision    : 0


From wenst at chromium.org  Wed Aug 11 10:15:05 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Thu, 12 Aug 2021 01:15:05 +0800
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
Message-ID: <20210811171505.1502090-1-wenst@chromium.org>

When non-secure priorities are used, compared to the raw priority set,
the value read back from RPR is also right-shifted by one and the
highest bit set.

Add a macro to do the modifications to the raw priority when doing the
comparison against the RPR value. This corrects the pseudo-NMI behavior
when non-secure priorities in the GIC are used. Tested on 5.10 with
the "IPI as pseudo-NMI" series [1] applied on MT8195.

[1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg at linaro.org/

Fixes: 336780590990 ("irqchip/gic-v3: Support pseudo-NMIs when SCR_EL3.FIQ == 0")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/irqchip/irq-gic-v3.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e0f4debe64e1..e7a0b55413db 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -100,6 +100,15 @@ EXPORT_SYMBOL(gic_pmr_sync);
 DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities);
 EXPORT_SYMBOL(gic_nonsecure_priorities);
 
+#define GICD_INT_RPR_PRI(priority)					\
+	({								\
+		u32 __priority = (priority);				\
+		if (static_branch_unlikely(&gic_nonsecure_priorities))	\
+			__priority = 0x80 | (__priority >> 1);		\
+									\
+		__priority;						\
+	})
+
 /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
 static refcount_t *ppi_nmi_refs;
 
@@ -687,7 +696,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
 		return;
 
 	if (gic_supports_nmi() &&
-	    unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) {
+	    unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) {
 		gic_handle_nmi(irqnr, regs);
 		return;
 	}
-- 
2.32.0.605.g8dce9f2422-goog



From robh at kernel.org  Wed Aug 11 10:24:53 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 11:24:53 -0600
Subject: [PATCH v5,
 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8192
In-Reply-To: <20210811025801.21597-14-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
Message-ID: <1628702693.304754.3975941.nullmailer@robh.at.kernel.org>

On Wed, 11 Aug 2021 10:57:59 +0800, Yunfei Dong wrote:
> Adds decoder dt-bindings for mt8192.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
> v5: no changes
> 
> This patch depends on "Mediatek MT8192 clock support"[1].
> 
> The definition of decoder clocks are in mt8192-clk.h, need to include them in case of build fail [1].
> 
> [1]https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> ---
>  .../media/mediatek,vcodec-comp-decoder.yaml   | 172 ++++++++++++++++++
>  1 file changed, 172 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
./Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml: $id: relative path/filename doesn't match actual path or filename
	expected: http://devicetree.org/schemas/media/mediatek,vcodec-comp-decoder.yaml#
Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dts:22:18: fatal error: dt-bindings/clock/mt8192-clk.h: No such file or directory
   22 |         #include <dt-bindings/clock/mt8192-clk.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1515556

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From qperret at google.com  Wed Aug 11 10:36:25 2021
From: qperret at google.com (Quentin Perret)
Date: Wed, 11 Aug 2021 18:36:25 +0100
Subject: [PATCH] KVM: arm64: Return -EPERM from __pkvm_host_share_hyp()
Message-ID: <20210811173630.2536721-1-qperret@google.com>

Fix the error code returned by __pkvm_host_share_hyp() when the
host attempts to share with EL2 a page that has already been shared with
another entity.

Reported-by: Will Deacon <will at kernel.org>
Signed-off-by: Quentin Perret <qperret at google.com>
---
This patch fixes a bug introduced in the stage-2 ownership series which
is already queued in kvmarm/next:

https://lore.kernel.org/lkml/20210809152448.1810400-1-qperret at google.com/

I've starred at this code for hours, but that clearly was not enough. Oh
well ...
---
 arch/arm64/kvm/hyp/nvhe/mem_protect.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 8165390d3ec9..6ec695311498 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -404,7 +404,7 @@ int __pkvm_host_share_hyp(u64 pfn)
 	cur = kvm_pgtable_hyp_pte_prot(pte);
 	prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED);
 	if (!check_prot(cur, prot, ~prot))
-		ret = EPERM;
+		ret = -EPERM;
 	goto unlock;
 
 map_shared:
-- 
2.32.0.605.g8dce9f2422-goog



From robh at kernel.org  Wed Aug 11 10:41:09 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 11:41:09 -0600
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <20210811025801.21597-14-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
Message-ID: <YRQLtd+IyISzlreI@robh.at.kernel.org>

On Wed, Aug 11, 2021 at 10:57:59AM +0800, Yunfei Dong wrote:
> Adds decoder dt-bindings for mt8192.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
> v5: no changes
> 
> This patch depends on "Mediatek MT8192 clock support"[1].
> 
> The definition of decoder clocks are in mt8192-clk.h, need to include them in case of build fail [1].
> 
> [1]https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> ---
>  .../media/mediatek,vcodec-comp-decoder.yaml   | 172 ++++++++++++++++++
>  1 file changed, 172 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> new file mode 100644
> index 000000000000..083c89933917
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> @@ -0,0 +1,172 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Video Decode Accelerator With Component
> +
> +maintainers:
> +  - Yunfei Dong <yunfei.dong at mediatek.com>
> +
> +description: |+
> +  Mediatek Video Decode is the video decode hardware present in Mediatek
> +  SoCs which supports high resolution decoding functionalities. Required
> +  master and component node.
> +
> +properties:
> +  compatible:
> +    oneOf:

Don't need 'oneOf' when only one entry.

> +      - enum:
> +          - mediatek,mt8192-vcodec-dec  # for lat hardware
> +          - mediatek,mtk-vcodec-lat     # for core hardware
> +          - mediatek,mtk-vcodec-core
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 5
> +
> +  clock-names:
> +    items:
> +      - const: vdec-sel
> +      - const: vdec-soc-vdec
> +      - const: vdec-soc-lat
> +      - const: vdec-vdec
> +      - const: vdec-top
> +

> +  assigned-clocks: true
> +
> +  assigned-clock-parents: true

Don't need these 2. Always valid if 'clocks' is present.

> +
> +  power-domains:
> +    maxItems: 1
> +
> +  iommus:
> +    minItems: 1
> +    maxItems: 32
> +    description: |
> +      List of the hardware port in respective IOMMU block for current Socs.
> +      Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +  dma-ranges:
> +    maxItems: 1
> +    description: |
> +      Describes the physical address space of IOMMU maps to memory.
> +
> +  mediatek,scp:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1
> +    description:
> +      Describes point to scp.
> +
> +required:
> +      - compatible
> +      - reg
> +      - iommus
> +      - dma-ranges
> +
> +allOf:
> +  - if: #master node
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - mediatek,mt8192-vcodec-dec  # for lat hardware
> +
> +    then:
> +      required:
> +        - mediatek,scp
> +
> +  - if: #component node
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - mediatek,mtk-vcodec-lat     # for core hardware
> +              - mediatek,mtk-vcodec-core
> +
> +    then:
> +      required:
> +        - interrupts
> +        - clocks
> +        - clock-names
> +        - assigned-clocks
> +        - assigned-clock-parents
> +        - power-domains
> +
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/memory/mt8192-larb-port.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/mt8192-clk.h>
> +    #include <dt-bindings/power/mt8192-power.h>
> +
> +    vcodec_dec: vcodec_dec at 16000000 {
> +        compatible = "mediatek,mt8192-vcodec-dec";
> +        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
> +        mediatek,scp = <&scp>;
> +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
> +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> +    };
> +
> +    vcodec_lat: vcodec_lat at 0x16010000 {
> +        compatible = "mediatek,mtk-vcodec-lat";
> +        reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
> +        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
> +        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
> +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> +             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
> +             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
> +             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
> +             <&topckgen CLK_TOP_MAINPLL_D4>;
> +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> +              "vdec-vdec", "vdec-top";
> +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
> +    };
> +
> +    vcodec_core: vcodec_core at 0x16025000 {
> +        compatible = "mediatek,mtk-vcodec-core";
> +        reg = <0 0x16025000 0 0x1000>;		/* VDEC_CORE_MISC */
> +        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
> +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
> +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> +             <&vdecsys CLK_VDEC_VDEC>,
> +             <&vdecsys CLK_VDEC_LAT>,
> +             <&vdecsys CLK_VDEC_LARB1>,
> +             <&topckgen CLK_TOP_MAINPLL_D4>;
> +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> +              "vdec-vdec", "vdec-top";
> +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
> +    };
> -- 
> 2.25.1
> 
> 


From robh at kernel.org  Wed Aug 11 10:50:34 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 11:50:34 -0600
Subject: [PATCH v6 1/3] dt-bindings: pci: Add DT binding for Toshiba
 Visconti PCIe controller
In-Reply-To: <20210811083830.784065-2-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210811083830.784065-2-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <YRQN6paKB1772KJD@robh.at.kernel.org>

On Wed, Aug 11, 2021 at 05:38:28PM +0900, Nobuhiro Iwamatsu wrote:
> This commit adds the Device Tree binding documentation that allows
> to describe the PCIe controller found in Toshiba Visconti SoCs.
> 
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> 
> v3 -> v4:
>  - Changed the redundant clock name.
> 
> v2 -> v3:
>  - No update.
> 
> v1 -> v2:
>  - Remove white space.
>  - Drop num-viewport and bus-range from required.
>  - Drop status line from example.
>  - Drop bus-range from required.
>  - Removed lines defined in pci-bus.yaml from required.
> ---
>  .../bindings/pci/toshiba,visconti-pcie.yaml   | 110 ++++++++++++++++++
>  1 file changed, 110 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml

I already applied this, why are you sending it again?

Rob


From laurent.pinchart at ideasonboard.com  Wed Aug 11 10:59:32 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 11 Aug 2021 20:59:32 +0300
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <20210811025801.21597-14-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
Message-ID: <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>

Hi Yunfei,

Thank you for the patch.

On Wed, Aug 11, 2021 at 10:57:59AM +0800, Yunfei Dong wrote:
> Adds decoder dt-bindings for mt8192.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
> v5: no changes
> 
> This patch depends on "Mediatek MT8192 clock support"[1].
> 
> The definition of decoder clocks are in mt8192-clk.h, need to include them in case of build fail [1].
> 
> [1]https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> ---
>  .../media/mediatek,vcodec-comp-decoder.yaml   | 172 ++++++++++++++++++
>  1 file changed, 172 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> new file mode 100644
> index 000000000000..083c89933917
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> @@ -0,0 +1,172 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Video Decode Accelerator With Component
> +
> +maintainers:
> +  - Yunfei Dong <yunfei.dong at mediatek.com>
> +
> +description: |+
> +  Mediatek Video Decode is the video decode hardware present in Mediatek
> +  SoCs which supports high resolution decoding functionalities. Required
> +  master and component node.

This should explain how the three IP cores relate to each other.

> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - mediatek,mt8192-vcodec-dec  # for lat hardware
> +          - mediatek,mtk-vcodec-lat     # for core hardware
> +          - mediatek,mtk-vcodec-core
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 5
> +
> +  clock-names:
> +    items:
> +      - const: vdec-sel
> +      - const: vdec-soc-vdec
> +      - const: vdec-soc-lat
> +      - const: vdec-vdec
> +      - const: vdec-top
> +
> +  assigned-clocks: true
> +
> +  assigned-clock-parents: true
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  iommus:
> +    minItems: 1
> +    maxItems: 32
> +    description: |
> +      List of the hardware port in respective IOMMU block for current Socs.
> +      Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +  dma-ranges:
> +    maxItems: 1
> +    description: |
> +      Describes the physical address space of IOMMU maps to memory.
> +
> +  mediatek,scp:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1
> +    description:
> +      Describes point to scp.
> +
> +required:
> +      - compatible
> +      - reg
> +      - iommus
> +      - dma-ranges
> +
> +allOf:
> +  - if: #master node
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - mediatek,mt8192-vcodec-dec  # for lat hardware
> +
> +    then:
> +      required:
> +        - mediatek,scp
> +
> +  - if: #component node
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - mediatek,mtk-vcodec-lat     # for core hardware
> +              - mediatek,mtk-vcodec-core
> +
> +    then:
> +      required:
> +        - interrupts
> +        - clocks
> +        - clock-names
> +        - assigned-clocks
> +        - assigned-clock-parents
> +        - power-domains
> +
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/memory/mt8192-larb-port.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/mt8192-clk.h>
> +    #include <dt-bindings/power/mt8192-power.h>
> +
> +    vcodec_dec: vcodec_dec at 16000000 {
> +        compatible = "mediatek,mt8192-vcodec-dec";
> +        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
> +        mediatek,scp = <&scp>;
> +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
> +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> +    };
> +
> +    vcodec_lat: vcodec_lat at 0x16010000 {
> +        compatible = "mediatek,mtk-vcodec-lat";
> +        reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
> +        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
> +        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
> +             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
> +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> +             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
> +             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
> +             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
> +             <&topckgen CLK_TOP_MAINPLL_D4>;
> +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> +              "vdec-vdec", "vdec-top";
> +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
> +    };
> +
> +    vcodec_core: vcodec_core at 0x16025000 {
> +        compatible = "mediatek,mtk-vcodec-core";
> +        reg = <0 0x16025000 0 0x1000>;		/* VDEC_CORE_MISC */
> +        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
> +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
> +             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
> +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> +             <&vdecsys CLK_VDEC_VDEC>,
> +             <&vdecsys CLK_VDEC_LAT>,
> +             <&vdecsys CLK_VDEC_LARB1>,
> +             <&topckgen CLK_TOP_MAINPLL_D4>;
> +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> +              "vdec-vdec", "vdec-top";
> +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
> +    };

I'm a bit late in the game, reviewing v5 only, but I'm wondering if
those IP cores need to be modelled in separate nodes. It would be much
easier, from a software point of view, to have a single node, with
multiple register ranges.

Are some of those IP cores used in different SoCs, combined in different
ways, that make a modular design better ?

-- 
Regards,

Laurent Pinchart


From robh at kernel.org  Wed Aug 11 11:04:38 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 12:04:38 -0600
Subject: [PATCH v1] dt-bindings: timer: fsl,imxgpt: add optional osc_per
 clock
In-Reply-To: <20210803072958.4815-1-o.rempel@pengutronix.de>
References: <20210803072958.4815-1-o.rempel@pengutronix.de>
Message-ID: <YRQRNrLXIYERa6FT@robh.at.kernel.org>

On Tue, Aug 03, 2021 at 09:29:58AM +0200, Oleksij Rempel wrote:
> Add optional osc_per and fix dts validation warnings on imx6 SoCs.
> 
> Fixes: df8cad689eae ("dt-bindings: timer: Convert i.MX GPT to json-schema")

I don't think you can say the above commit was broken.

> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> ---
>  .../devicetree/bindings/timer/fsl,imxgpt.yaml   | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> index a4f51f46b7a1..e496dd9f4988 100644
> --- a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> +++ b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> @@ -43,11 +43,15 @@ properties:
>      items:
>        - description: SoC GPT ipg clock
>        - description: SoC GPT per clock
> +      - description: optional SoC GPT oscillator
> +    minItems: 2

The 3rd clock is valid on every version of the h/w?

>  
>    clock-names:
>      items:
>        - const: ipg
>        - const: per
> +      - const: osc_per
> +    minItems: 2
>  
>  required:
>    - compatible
> @@ -70,3 +74,16 @@ examples:
>                   <&clks IMX27_CLK_PER1_GATE>;
>          clock-names = "ipg", "per";
>      };
> +
> +  - |
> +    #include <dt-bindings/clock/imx6qdl-clock.h>
> +
> +    timer at 2098000 {
> +        compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
> +        reg = <0x02098000 0x4000>;
> +        interrupts = <26>;
> +        clocks = <&clks IMX6QDL_CLK_GPT_IPG>,
> +                 <&clks IMX6QDL_CLK_GPT_IPG_PER>,
> +                 <&clks IMX6QDL_CLK_GPT_3M>;
> +        clock-names = "ipg", "per", "osc_per";
> +    };
> -- 
> 2.30.2
> 
> 


From dsahern at gmail.com  Wed Aug 11 11:05:54 2021
From: dsahern at gmail.com (David Ahern)
Date: Wed, 11 Aug 2021 12:05:54 -0600
Subject: [PATCH net-next v3] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <25dcf6e8-cdd6-6339-f499-5c3100a7d8c4@gmail.com>
References: <c0a6f817-0225-c863-722c-19c798daaa4b@gmail.com>
 <20210810123327.15998-1-rocco.yue@mediatek.com>
 <25dcf6e8-cdd6-6339-f499-5c3100a7d8c4@gmail.com>
Message-ID: <4624cc10-1fc8-12cd-e9e1-9585f5b496a0@gmail.com>

On 8/11/21 7:56 AM, David Ahern wrote:
> On 8/10/21 6:33 AM, Rocco Yue wrote:
>> On Mon, 2021-08-09 at 16:43 -0600, David Ahern wrote:
>>> On 8/9/21 8:01 AM, Rocco Yue wrote:
>>
>>> +
>>>>  #ifdef CONFIG_SYSCTL
>>>>  
>>>>  static int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
>>>> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
>>>> index c467c6419893..a04164cbd77f 100644
>>>> --- a/net/ipv6/ndisc.c
>>>> +++ b/net/ipv6/ndisc.c
>>>> @@ -1496,6 +1496,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
>>>>  		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
>>>>  		mtu = ntohl(n);
>>>>  
>>>> +		if (in6_dev->ra_mtu != mtu) {
>>>> +			in6_dev->ra_mtu = mtu;
>>>> +			inet6_iframtu_notify(in6_dev);
>>>> +			ND_PRINTK(2, info, "update ra_mtu to %d\n", in6_dev->ra_mtu);
>>>> +		}
>>>> +
>>>>  		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
>>>>  			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
>>>>  		} else if (in6_dev->cnf.mtu6 != mtu) {
>>>
>>> Since this MTU is getting reported via af_info infrastructure,
>>> rtmsg_ifinfo should be sufficient.
>>>
>>> From there use 'ip monitor' to make sure you are not generating multiple
>>> notifications; you may only need this on the error path.
>>
>> Hi David,
>>
>> To avoid generating multiple notifications, I added a separate ramtu notify
>> function in this patch, and I added RTNLGRP_IPV6_IFINFO nl_mgrp to the ipmonitor.c
>> to verify this patch was as expected.
>>
>> I look at the rtmsg_ifinfo code, it should be appropriate and I will use it and
>> verify it.
>>
>> But there's one thing, I'm sorry I didn't fully understand the meaning of this
>> sentence "you may only need this on the error path". Honestly, I'm not sure what
>> the error patch refers to, do you mean "if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu)" ?
>>
> 
> looks like nothing under:
>     if (ndopts.nd_opts_mtu && in6_dev->cnf.accept_ra_mtu) {
> 
>     }
> 
> is going to send a link notification so you can just replace
> inet6_iframtu_notify with rtmsg_ifinfo in your proposed change.
> 

Taking a deeper dive on the code, you do not need to call rtmsg_ifinfo.
Instead, the existing:

        /*
         *      Send a notify if RA changed managed/otherconf flags or
timer settings
         */
        if (send_ifinfo_notify)
                inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);

is called too early. For one the RA can change the MTU and that is done
after this notify.

I think if you moved this down to the out:

out:
        /*
         *      Send a notify if RA changed managed/otherconf flags or
timer settings
         */
        if (send_ifinfo_notify)
                inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);

and then set send_ifinfo_notify when the mtu is *changed* by the RA you
should be good.


From robh at kernel.org  Wed Aug 11 11:11:22 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 12:11:22 -0600
Subject: [PATCH v2 03/15] dt-bindings: Add generic bindings for PECI
In-Reply-To: <20210803113134.2262882-4-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-4-iwona.winiarska@intel.com>
Message-ID: <YRQSyjFcS8bAfqDU@robh.at.kernel.org>

On Tue, 03 Aug 2021 13:31:22 +0200, Iwona Winiarska wrote:
> Add device tree bindings for the PECI controller.
> 
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> ---
>  .../bindings/peci/peci-controller.yaml        | 33 +++++++++++++++++++
>  1 file changed, 33 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/peci/peci-controller.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Wed Aug 11 11:11:48 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 12:11:48 -0600
Subject: [PATCH v2 04/15] dt-bindings: Add bindings for peci-aspeed
In-Reply-To: <20210803113134.2262882-5-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-5-iwona.winiarska@intel.com>
Message-ID: <YRQS5IigFxo5DVCH@robh.at.kernel.org>

On Tue, 03 Aug 2021 13:31:23 +0200, Iwona Winiarska wrote:
> Add device tree bindings for the peci-aspeed controller driver.
> 
> Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> ---
>  .../devicetree/bindings/peci/peci-aspeed.yaml | 109 ++++++++++++++++++
>  1 file changed, 109 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From maz at kernel.org  Wed Aug 11 11:31:36 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 19:31:36 +0100
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
In-Reply-To: <20210811171505.1502090-1-wenst@chromium.org>
References: <20210811171505.1502090-1-wenst@chromium.org>
Message-ID: <87fsvfal4n.wl-maz@kernel.org>

+ Alex, who introduced this.

On Wed, 11 Aug 2021 18:15:05 +0100,
Chen-Yu Tsai <wenst at chromium.org> wrote:
> 
> When non-secure priorities are used, compared to the raw priority set,
> the value read back from RPR is also right-shifted by one and the
> highest bit set.
> 
> Add a macro to do the modifications to the raw priority when doing the
> comparison against the RPR value. This corrects the pseudo-NMI behavior
> when non-secure priorities in the GIC are used. Tested on 5.10 with
> the "IPI as pseudo-NMI" series [1] applied on MT8195.
> 
> [1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg at linaro.org/
> 
> Fixes: 336780590990 ("irqchip/gic-v3: Support pseudo-NMIs when SCR_EL3.FIQ == 0")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/irqchip/irq-gic-v3.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index e0f4debe64e1..e7a0b55413db 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -100,6 +100,15 @@ EXPORT_SYMBOL(gic_pmr_sync);
>  DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities);
>  EXPORT_SYMBOL(gic_nonsecure_priorities);
>  
> +#define GICD_INT_RPR_PRI(priority)					\
> +	({								\
> +		u32 __priority = (priority);				\
> +		if (static_branch_unlikely(&gic_nonsecure_priorities))	\
> +			__priority = 0x80 | (__priority >> 1);		\
> +									\
> +		__priority;						\

This doesn't reflect what the pseudocode says of a read of ICC_RPR_EL1
AFAICS. When the priority is activated, it is indeed shifted. But a
read of RPR does appear to shift things back (and you loose the lowest
bit in the process). Please see 'aarch64/support/ICC_RPR_EL1' in the
architecture spec.

Can you confirm that SCR_EL3.FIQ is set on your system?

Thanks,

	M.

> +	})
> +
>  /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
>  static refcount_t *ppi_nmi_refs;
>  
> @@ -687,7 +696,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
>  		return;
>  
>  	if (gic_supports_nmi() &&
> -	    unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) {
> +	    unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) {
>  		gic_handle_nmi(irqnr, regs);
>  		return;
>  	}


-- 
Without deviation from the norm, progress is not possible.


From robh at kernel.org  Wed Aug 11 11:35:59 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 12:35:59 -0600
Subject: [PATCH v3 1/5] dt-bindings: leds: Add binding for qcom-spmi-flash
In-Reply-To: <20210803162641.1525980-2-nfraprado@collabora.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
 <20210803162641.1525980-2-nfraprado@collabora.com>
Message-ID: <YRQYjwaZCcm6blHT@robh.at.kernel.org>

On Tue, Aug 03, 2021 at 01:26:37PM -0300, N?colas F. R. A. Prado wrote:
> Add devicetree binding for Qualcomm's SPMI Flash LEDs which are part of
> the PM8941 PMIC. These LEDs are used both as lantern and camera flash on
> phones based on the MSM8974 SoC, like the Nexus 5.
> 
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
> 
> Changes in v3:
> - Removed clamp-curr, headroom, startup-dly and safety-timer properties since
>   they didn't impact the behavior. They're now hardcoded in the driver (patch 2)
> - Added valid ranges for led-max-microamp, flash-max-microamp and
>   flash-max-timeout-us
> - Removed dt-bindings header file that held some constants (moved to inside the
>   driver in patch 2)
> 
> Added in v2
> 
>  .../bindings/leds/leds-qcom-spmi-flash.yaml   | 93 +++++++++++++++++++
>  1 file changed, 93 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml
> 
> diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml
> new file mode 100644
> index 000000000000..da674d73c033
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/leds/leds-qcom-spmi-flash.yaml
> @@ -0,0 +1,93 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/leds/leds-qcom-spmi-flash.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm SPMI Flash LEDs
> +
> +maintainers:
> +  - N?colas F. R. A. Prado <n at nfraprado.net>
> +
> +description: |
> +  The Qualcomm SPMI Flash LEDs are part of Qualcomm PMICs and are used primarily
> +  as a camera or video flash. They can also be used as a lantern when on torch
> +  mode.
> +  The PMIC is connected to Host processor via SPMI bus.
> +
> +properties:
> +  compatible:
> +    const: qcom,spmi-flash-leds
> +
> +  reg:
> +    maxItems: 1
> +
> +  flash-boost-supply:
> +    description: SMBB regulator for LED flash mode
> +
> +  torch-boost-supply:
> +    description: SMBB regulator for LED torch mode
> +
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0
> +
> +patternProperties:
> +  "^led@[0-1]$":
> +    type: object
> +    $ref: common.yaml#
> +
> +    properties:
> +      reg:
> +        maxItems: 1

Instead of maxItems, this would be a bit more specific:

enum: [ 0, 1 ]

With that,

Reviewed-by: Rob Herring <robh at kernel.org>

> +
> +      led-max-microamp:
> +        minimum: 12500
> +        maximum: 200000
> +        multipleOf: 12500
> +
> +      flash-max-microamp:
> +        minimum: 12500
> +        maximum: 1000000
> +        multipleOf: 12500
> +
> +      flash-max-timeout-us:
> +        minimum: 10000
> +        maximum: 1280000
> +        multipleOf: 10000
> +
> +    required:
> +      - reg
> +
> +required:
> +  - compatible
> +  - reg
> +  - flash-boost-supply
> +  - torch-boost-supply
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/leds/common.h>
> +
> +    spmi-flash-leds at d300 {
> +        compatible = "qcom,spmi-flash-leds";
> +        reg = <0xd300 0x100>;
> +        flash-boost-supply = <&pm8941_5vs1>;
> +        torch-boost-supply = <&pm8941_5v>;
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        led at 0 {
> +            reg = <0>;
> +            function = LED_FUNCTION_FLASH;
> +            color = <LED_COLOR_ID_WHITE>;
> +            led-max-microamp = <200000>;
> +            flash-max-microamp = <1000000>;
> +            flash-max-timeout-us = <1280000>;
> +        };
> +    };
> +...
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Wed Aug 11 11:40:23 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 12:40:23 -0600
Subject: [PATCH v4 1/3] dt-bindings: vendor-prefixes: Add an entry for
 SKOV A/S
In-Reply-To: <20210804043439.11757-2-o.rempel@pengutronix.de>
References: <20210804043439.11757-1-o.rempel@pengutronix.de>
 <20210804043439.11757-2-o.rempel@pengutronix.de>
Message-ID: <YRQZl94LsG9smzI0@robh.at.kernel.org>

On Wed, 04 Aug 2021 06:34:37 +0200, Oleksij Rempel wrote:
> Add "skov" entry for the SKOV A/S: https://www.skov.com/en/
> 
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

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


From robh at kernel.org  Wed Aug 11 11:40:36 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 12:40:36 -0600
Subject: [PATCH v4 2/3] dt-bindings: arm: fsl: add SKOV imx6q and imx6dl
 based boards
In-Reply-To: <20210804043439.11757-3-o.rempel@pengutronix.de>
References: <20210804043439.11757-1-o.rempel@pengutronix.de>
 <20210804043439.11757-3-o.rempel@pengutronix.de>
Message-ID: <YRQZpGn/+XfDy4Gj@robh.at.kernel.org>

On Wed, 04 Aug 2021 06:34:38 +0200, Oleksij Rempel wrote:
> Add SKOV imx6q/dl LT2, LT6 and mi1010ait-1cp1 boards.
> 
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> ---
>  Documentation/devicetree/bindings/arm/fsl.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 

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


From maz at kernel.org  Wed Aug 11 11:43:02 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 19:43:02 +0100
Subject: [PATCH] KVM: arm64: Return -EPERM from __pkvm_host_share_hyp()
In-Reply-To: <20210811173630.2536721-1-qperret@google.com>
References: <20210811173630.2536721-1-qperret@google.com>
Message-ID: <162870737148.2970653.12931848949565086445.b4-ty@kernel.org>

On Wed, 11 Aug 2021 18:36:25 +0100, Quentin Perret wrote:
> Fix the error code returned by __pkvm_host_share_hyp() when the
> host attempts to share with EL2 a page that has already been shared with
> another entity.

Applied to next, thanks!

[1/1] KVM: arm64: Return -EPERM from __pkvm_host_share_hyp()
      commit: 12593568d7319c34c72038ea799ab1bd0f0eb01c

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From robh at kernel.org  Wed Aug 11 11:53:20 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 12:53:20 -0600
Subject: [PATCH v4 1/4] dt-bindings: clock: Add DT bindings for PLL of
 Toshiba Visconti TMPV770x SoC
In-Reply-To: <20210804092244.390376-2-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210804092244.390376-2-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <YRQcoD6xhxCf2gy8@robh.at.kernel.org>

On Wed, 04 Aug 2021 18:22:41 +0900, Nobuhiro Iwamatsu wrote:
> Add device tree bindings for PLL of Toshiba Visconti TMPV770x SoC series.
> 
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> ---
>  .../clock/toshiba,tmpv770x-pipllct.yaml       | 57 +++++++++++++++++++
>  1 file changed, 57 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Wed Aug 11 11:53:52 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 11 Aug 2021 12:53:52 -0600
Subject: [PATCH v4 2/4] dt-bindings: clock: Add DT bindings for SMU of
 Toshiba Visconti TMPV770x SoC
In-Reply-To: <20210804092244.390376-3-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210804092244.390376-3-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <YRQcwD7771ncxtMT@robh.at.kernel.org>

On Wed, 04 Aug 2021 18:22:42 +0900, Nobuhiro Iwamatsu wrote:
> Add device tree bindings for SMU (System Management Unit) controller of
> Toshiba Visconti TMPV770x SoC series.
> 
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> ---
>  .../clock/toshiba,tmpv770x-pismu.yaml         |  50 +++++
>  include/dt-bindings/clock/toshiba,tmpv770x.h  | 181 ++++++++++++++++++
>  include/dt-bindings/reset/toshiba,tmpv770x.h  |  41 ++++
>  3 files changed, 272 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
>  create mode 100644 include/dt-bindings/clock/toshiba,tmpv770x.h
>  create mode 100644 include/dt-bindings/reset/toshiba,tmpv770x.h
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From oupton at google.com  Wed Aug 11 11:56:22 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 11 Aug 2021 11:56:22 -0700
Subject: [PATCH v6 00/21] KVM: Add idempotent controls for migrating
 system counter state
In-Reply-To: <927240ff-a4f4-fcc6-ae1b-92cefeda9e59@redhat.com>
References: <20210804085819.846610-1-oupton@google.com>
 <927240ff-a4f4-fcc6-ae1b-92cefeda9e59@redhat.com>
Message-ID: <CAOQ_Qsjby+z_kU49_s0PDKo5c3V-UD+FRg-2PcPycNq-p2gPVg@mail.gmail.com>

On Wed, Aug 11, 2021 at 6:05 AM Paolo Bonzini <pbonzini at redhat.com> wrote:
>
> On 04/08/21 10:57, Oliver Upton wrote:
> > KVM's current means of saving/restoring system counters is plagued with
> > temporal issues. At least on ARM64 and x86, we migrate the guest's
> > system counter by-value through the respective guest system register
> > values (cntvct_el0, ia32_tsc). Restoring system counters by-value is
> > brittle as the state is not idempotent: the host system counter is still
> > oscillating between the attempted save and restore. Furthermore, VMMs
> > may wish to transparently live migrate guest VMs, meaning that they
> > include the elapsed time due to live migration blackout in the guest
> > system counter view. The VMM thread could be preempted for any number of
> > reasons (scheduler, L0 hypervisor under nested) between the time that
> > it calculates the desired guest counter value and when KVM actually sets
> > this counter state.
> >
> > Despite the value-based interface that we present to userspace, KVM
> > actually has idempotent guest controls by way of system counter offsets.
> > We can avoid all of the issues associated with a value-based interface
> > by abstracting these offset controls in new ioctls. This series
> > introduces new vCPU device attributes to provide userspace access to the
> > vCPU's system counter offset.
> >
> > Patch 1 addresses a possible race in KVM_GET_CLOCK where
> > use_master_clock is read outside of the pvclock_gtod_sync_lock.
> >
> > Patch 2 adopts Paolo's suggestion, augmenting the KVM_{GET,SET}_CLOCK
> > ioctls to provide userspace with a (host_tsc, realtime) instant. This is
> > essential for a VMM to perform precise migration of the guest's system
> > counters.
> >
> > Patches 3-4 are some preparatory changes for exposing the TSC offset to
> > userspace. Patch 5 provides a vCPU attribute to provide userspace access
> > to the TSC offset.
> >
> > Patches 6-7 implement a test for the new additions to
> > KVM_{GET,SET}_CLOCK.
> >
> > Patch 8 fixes some assertions in the kvm device attribute helpers.
> >
> > Patches 9-10 implement at test for the tsc offset attribute introduced in
> > patch 5.
>
> The x86 parts look good, except that patch 3 is a bit redundant with my
> idea of altogether getting rid of the pvclock_gtod_sync_lock.  That said
> I agree that patches 1 and 2 (and extracting kvm_vm_ioctl_get_clock and
> kvm_vm_ioctl_set_clock) should be done before whatever locking changes
> have to be done.

Following up on patch 3.

> Time is ticking for 5.15 due to my vacation, I'll see if I have some
> time to look at it further next week.
>
> I agree that arm64 can be done separately from x86.

Marc, just a disclaimer:

I'm going to separate these two series, although there will still
exist dependencies in the selftests changes. Otherwise, kernel changes
are disjoint.

--
Thanks,
Oliver


From maz at kernel.org  Wed Aug 11 12:01:25 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 11 Aug 2021 20:01:25 +0100
Subject: [PATCH v6 00/21] KVM: Add idempotent controls for migrating
 system counter state
In-Reply-To: <CAOQ_Qsjby+z_kU49_s0PDKo5c3V-UD+FRg-2PcPycNq-p2gPVg@mail.gmail.com>
References: <20210804085819.846610-1-oupton@google.com>
 <927240ff-a4f4-fcc6-ae1b-92cefeda9e59@redhat.com>
 <CAOQ_Qsjby+z_kU49_s0PDKo5c3V-UD+FRg-2PcPycNq-p2gPVg@mail.gmail.com>
Message-ID: <87eeazajqy.wl-maz@kernel.org>

On Wed, 11 Aug 2021 19:56:22 +0100,
Oliver Upton <oupton at google.com> wrote:

[...]

> > Time is ticking for 5.15 due to my vacation, I'll see if I have some
> > time to look at it further next week.
> >
> > I agree that arm64 can be done separately from x86.
> 
> Marc, just a disclaimer:
> 
> I'm going to separate these two series, although there will still
> exist dependencies in the selftests changes. Otherwise, kernel changes
> are disjoint.

No problem. The selftests can even sit in a third series if that makes
it easier.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From andrew at lunn.ch  Wed Aug 11 12:14:48 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 11 Aug 2021 21:14:48 +0200
Subject: [PATCH] ARM: dts: vf610-zii-dev-rev-b: Remove #address-cells and
 #size-cells property from at93c46d dt node
In-Reply-To: <20210810064420.9489-1-a-govindraju@ti.com>
References: <20210810064420.9489-1-a-govindraju@ti.com>
Message-ID: <YRQhqHEl8wu2KZz+@lunn.ch>

On Tue, Aug 10, 2021 at 12:14:20PM +0530, Aswath Govindraju wrote:
Hi Aswath

You did not put a To: in the email, so it is unclear which maintainer
you expect to pickup this patch.

> Remove #address-cells and #size-cells property from at93c46d device tree
> node as it does not have child nodes.
> 
> Fixes: 1556063fde42 ("ARM: dts: vf610-zii-dev: Add ZII development board.")
> Signed-off-by: Aswath Govindraju <a-govindraju at ti.com>

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From lkp at intel.com  Wed Aug 11 13:08:20 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 04:08:20 +0800
Subject: [PATCH] ARM/smp_twd: Cleanup the unnecessary cast
In-Reply-To: <20210811131512.940-1-tangbin@cmss.chinamobile.com>
References: <20210811131512.940-1-tangbin@cmss.chinamobile.com>
Message-ID: <202108120407.vvfWQHm8-lkp@intel.com>

Hi Tang,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on xlnx/master]
[also build test WARNING on arm/for-next keystone/next soc/for-next rockchip/for-next arm64/for-next/core shawnguo/for-next clk/clk-next linus/master v5.14-rc5 next-20210811]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Tang-Bin/ARM-smp_twd-Cleanup-the-unnecessary-cast/20210811-211613
base:   https://github.com/Xilinx/linux-xlnx master
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/d796b458f195f35962a4ca889134f542e2186b1f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Tang-Bin/ARM-smp_twd-Cleanup-the-unnecessary-cast/20210811-211613
        git checkout d796b458f195f35962a4ca889134f542e2186b1f
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:7,
                    from include/linux/kernel.h:16,
                    from arch/arm/kernel/smp_twd.c:9:
   arch/arm/kernel/smp_twd.c: In function 'twd_get_clock':
>> include/linux/kern_levels.h:5:18: warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
       5 | #define KERN_SOH "\001"  /* ASCII Start Of Header */
         |                  ^~~~~~
   include/linux/kern_levels.h:11:18: note: in expansion of macro 'KERN_SOH'
      11 | #define KERN_ERR KERN_SOH "3" /* error conditions */
         |                  ^~~~~~~~
   include/linux/printk.h:343:9: note: in expansion of macro 'KERN_ERR'
     343 |  printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
         |         ^~~~~~~~
   arch/arm/kernel/smp_twd.c:202:3: note: in expansion of macro 'pr_err'
     202 |   pr_err("smp_twd: clock not found %d\n", PTR_ERR(twd_clk));
         |   ^~~~~~


vim +5 include/linux/kern_levels.h

314ba3520e513a Joe Perches 2012-07-30  4  
04d2c8c83d0e3a Joe Perches 2012-07-30 @5  #define KERN_SOH	"\001"		/* ASCII Start Of Header */
04d2c8c83d0e3a Joe Perches 2012-07-30  6  #define KERN_SOH_ASCII	'\001'
04d2c8c83d0e3a Joe Perches 2012-07-30  7  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 53822 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/6880fd58/attachment-0001.gz>

From s.shtylyov at omp.ru  Wed Aug 11 13:12:52 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Wed, 11 Aug 2021 23:12:52 +0300
Subject: [PATCH v2 0/5] Correctly handle plaform_get_irq()'s result in the
 i2C drivers
In-Reply-To: <3712e871-bf2f-32c5-f9c2-2968c42087f8@omp.ru>
References: <3712e871-bf2f-32c5-f9c2-2968c42087f8@omp.ru>
Message-ID: <83767306-be1b-3bcd-723c-92483b4cc612@omp.ru>

On 7/4/21 5:32 PM, Sergey Shtylyov wrote:

> Here are 5 patches against the 'i2c/for-current' branch of Wolfram's 'linux.git' repo.
> The affected drivers call platform_get_irq() but mis-interprete its result -- they consider
> IRQ0 as error and (sometimes) the real error codes as valid IRQs... :-/
> 
> [1/5] i2c: hix5hd2: fix IRQ check
> [2/5] i2c: mt65xx: fix IRQ check
> [3/5] i2c: pmcmsp: fix IRQ check
> [4/5] i2c: s3c2410: fix IRQ check
> [5/5] i2c: xlp9xx: fix main IRQ check

   Wolfram, hat's up with this series (its status in the patchwork is still "new")? 

MBR, Sergey


From valentin.schneider at arm.com  Wed Aug 11 13:13:50 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Wed, 11 Aug 2021 21:13:50 +0100
Subject: [PATCH v3 0/4] rcu, arm64: PREEMPT_RT fixlets
Message-ID: <20210811201354.1976839-1-valentin.schneider@arm.com>

Hi folks,

this is v3 of:

  https://lore.kernel.org/lkml/20210721115118.729943-1-valentin.schneider at arm.com/

respun from Frederic and Paul's helpful feedback. Tested atop v5.14-rc5-rt8 with
the v1 patches reverted. There, commit 

  d76e0926d835 ("rcu/nocb: Use the rcuog CPU's ->nocb_timer")

prevents the NOCB offload warning from firing if there are no NOCB CPUs (which
is sensible). Adding a single NOCB CPU brings the warning back, which patch 3
fixes.

Revisions
=========

v2 -> v3
++++++++

o Rebased and tested against v5.14-rc5-rt8
o Dropped affinity check from is_pcpu_safe() (Boqun)
o Renamed is_pcpu_safe() to migratable() (Boqun, Mike)

v1 -> v2
++++++++

o Rebased and tested against v5.14-rc4-rt6
o Picked rcutorture patch patch from
  https://lore.kernel.org/lkml/20210803225437.3612591-2-valentin.schneider at arm.com/
o Added a local_lock to protect NOCB offload state under PREEMPT_RT (Frederic,
  Paul)

Valentin Schneider (4):
  rcutorture: Don't disable softirqs with preemption disabled when
    PREEMPT_RT
  sched: Introduce migratable()
  rcu/nocb: Protect NOCB state via local_lock() under PREEMPT_RT
  arm64: mm: Make arch_faults_on_old_pte() check for migratability

 arch/arm64/include/asm/pgtable.h |  2 +-
 include/linux/sched.h            | 10 ++++
 kernel/rcu/rcutorture.c          |  2 +
 kernel/rcu/tree.c                |  4 ++
 kernel/rcu/tree.h                |  4 ++
 kernel/rcu/tree_plugin.h         | 82 ++++++++++++++++++++++++++++----
 6 files changed, 94 insertions(+), 10 deletions(-)

--
2.25.1



From valentin.schneider at arm.com  Wed Aug 11 13:13:51 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Wed, 11 Aug 2021 21:13:51 +0100
Subject: [PATCH v3 1/4] rcutorture: Don't disable softirqs with preemption
 disabled when PREEMPT_RT
In-Reply-To: <20210811201354.1976839-1-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
Message-ID: <20210811201354.1976839-2-valentin.schneider@arm.com>

Running RCU torture with CONFIG_PREEMPT_RT under v5.14-rc4-rt6 triggers:

[    8.755472] DEBUG_LOCKS_WARN_ON(this_cpu_read(softirq_ctrl.cnt))
[    8.755482] WARNING: CPU: 1 PID: 137 at kernel/softirq.c:172 __local_bh_disable_ip (kernel/softirq.c:172 (discriminator 31))
[    8.755500] Modules linked in:
[    8.755506] CPU: 1 PID: 137 Comm: rcu_torture_rea Not tainted 5.14.0-rc4-rt6 #171
[    8.755514] Hardware name: ARM Juno development board (r0) (DT)
[    8.755518] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
[    8.755622] Call trace:
[    8.755624] __local_bh_disable_ip (kernel/softirq.c:172 (discriminator 31))
[    8.755633] rcutorture_one_extend (kernel/rcu/rcutorture.c:1453)
[    8.755640] rcu_torture_one_read (kernel/rcu/rcutorture.c:1601 kernel/rcu/rcutorture.c:1645)
[    8.755645] rcu_torture_reader (kernel/rcu/rcutorture.c:1737)
[    8.755650] kthread (kernel/kthread.c:327)
[    8.755656] ret_from_fork (arch/arm64/kernel/entry.S:783)
[    8.755663] irq event stamp: 11959
[    8.755666] hardirqs last enabled at (11959): __rcu_read_unlock (kernel/rcu/tree_plugin.h:695 kernel/rcu/tree_plugin.h:451)
[    8.755675] hardirqs last disabled at (11958): __rcu_read_unlock (kernel/rcu/tree_plugin.h:661 kernel/rcu/tree_plugin.h:451)
[    8.755683] softirqs last enabled at (11950): __local_bh_enable_ip (./arch/arm64/include/asm/irqflags.h:85 kernel/softirq.c:261)
[    8.755692] softirqs last disabled at (11942): rcutorture_one_extend (./include/linux/bottom_half.h:19 kernel/rcu/rcutorture.c:1441)

Per this warning, softirqs cannot be disabled in a non-preemptible region
under CONFIG_PREEMPT_RT. Adjust RCU torture accordingly.

Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
---
 kernel/rcu/rcutorture.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index eecd1caef71d..4f3db1d3170d 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1548,6 +1548,8 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
 	 * them on non-RT.
 	 */
 	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
+		/* Can't disable bh in atomic context under PREEMPT_RT */
+		mask &= ~(RCUTORTURE_RDR_ATOM_BH | RCUTORTURE_RDR_ATOM_RBH);
 		/*
 		 * Can't release the outermost rcu lock in an irq disabled
 		 * section without preemption also being disabled, if irqs
-- 
2.25.1



From valentin.schneider at arm.com  Wed Aug 11 13:13:52 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Wed, 11 Aug 2021 21:13:52 +0100
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <20210811201354.1976839-1-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
Message-ID: <20210811201354.1976839-3-valentin.schneider@arm.com>

Some areas use preempt_disable() + preempt_enable() to safely access
per-CPU data. The PREEMPT_RT folks have shown this can also be done by
keeping preemption enabled and instead disabling migration (and acquiring a
sleepable lock, if relevant).

Introduce a helper which checks whether the current task can be migrated
elsewhere, IOW if it is pinned to its local CPU in the current
context. This can help determining if per-CPU properties can be safely
accessed.

Note that CPU affinity is not checked here, as a preemptible task can have
its affinity changed at any given time (including if it has
PF_NO_SETAFFINITY, when hotplug gets involved).

Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
---
 include/linux/sched.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index debc960f41e3..8ba7b4a7ee69 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
 #endif
 }
 
+/* Is the current task guaranteed to stay on its current CPU? */
+static inline bool migratable(void)
+{
+#ifdef CONFIG_SMP
+	return preemptible() && !current->migration_disabled;
+#else
+	return true;
+#endif
+}
+
 /* Per-process atomic flags. */
 #define PFA_NO_NEW_PRIVS		0	/* May not gain new privileges. */
 #define PFA_SPREAD_PAGE			1	/* Spread page cache over cpuset */
-- 
2.25.1



From valentin.schneider at arm.com  Wed Aug 11 13:13:53 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Wed, 11 Aug 2021 21:13:53 +0100
Subject: [PATCH v3 3/4] rcu/nocb: Protect NOCB state via local_lock() under
 PREEMPT_RT
In-Reply-To: <20210811201354.1976839-1-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
Message-ID: <20210811201354.1976839-4-valentin.schneider@arm.com>

Warning
=======

Running v5.13-rt1 on my arm64 Juno board triggers:

[    0.156302] =============================
[    0.160416] WARNING: suspicious RCU usage
[    0.164529] 5.13.0-rt1 #20 Not tainted
[    0.168300] -----------------------------
[    0.172409] kernel/rcu/tree_plugin.h:69 Unsafe read of RCU_NOCB offloaded state!
[    0.179920]
[    0.179920] other info that might help us debug this:
[    0.179920]
[    0.188037]
[    0.188037] rcu_scheduler_active = 1, debug_locks = 1
[    0.194677] 3 locks held by rcuc/0/11:
[    0.198448] #0: ffff00097ef10cf8 ((softirq_ctrl.lock).lock){+.+.}-{2:2}, at: __local_bh_disable_ip (./include/linux/rcupdate.h:662 kernel/softirq.c:171)
[    0.208709] #1: ffff80001205e5f0 (rcu_read_lock){....}-{1:2}, at: rt_spin_lock (kernel/locking/spinlock_rt.c:43 (discriminator 4))
[    0.217134] #2: ffff80001205e5f0 (rcu_read_lock){....}-{1:2}, at: __local_bh_disable_ip (kernel/softirq.c:169)
[    0.226428]
[    0.226428] stack backtrace:
[    0.230889] CPU: 0 PID: 11 Comm: rcuc/0 Not tainted 5.13.0-rt1 #20
[    0.237100] Hardware name: ARM Juno development board (r0) (DT)
[    0.243041] Call trace:
[    0.245497] dump_backtrace (arch/arm64/kernel/stacktrace.c:163)
[    0.249185] show_stack (arch/arm64/kernel/stacktrace.c:219)
[    0.252522] dump_stack (lib/dump_stack.c:122)
[    0.255947] lockdep_rcu_suspicious (kernel/locking/lockdep.c:6439)
[    0.260328] rcu_rdp_is_offloaded (kernel/rcu/tree_plugin.h:69 kernel/rcu/tree_plugin.h:58)
[    0.264537] rcu_core (kernel/rcu/tree.c:2332 kernel/rcu/tree.c:2398 kernel/rcu/tree.c:2777)
[    0.267786] rcu_cpu_kthread (./include/linux/bottom_half.h:32 kernel/rcu/tree.c:2876)
[    0.271644] smpboot_thread_fn (kernel/smpboot.c:165 (discriminator 3))
[    0.275767] kthread (kernel/kthread.c:321)
[    0.279013] ret_from_fork (arch/arm64/kernel/entry.S:1005)

In this case, this is the RCU core kthread accessing the local CPU's
rdp. Before that, rcu_cpu_kthread() invokes local_bh_disable().

Under !CONFIG_PREEMPT_RT (and rcutree.use_softirq=0), this ends up
incrementing the preempt_count, which satisfies the "local non-preemptible
read" of rcu_rdp_is_offloaded().

Under CONFIG_PREEMPT_RT however, this becomes

  local_lock(&softirq_ctrl.lock)

which, under the same config, is migrate_disable() + rt_spin_lock(). As
pointed out by Frederic, this is not sufficient to safely access an rdp's
offload state, as the RCU core kthread can be preempted by a kworker
executing rcu_nocb_rdp_offload() [1].

Introduce a local_lock to serialize an rdp's offload state while the rdp's
associated core kthread is executing rcu_core().

rcu_core() preemptability considerations
========================================

As pointed out by Paul [2], keeping rcu_check_quiescent_state() preemptible
(which is the case under CONFIG_PREEMPT_RT) requires some consideration.

note_gp_changes() itself runs with irqs off, and enters
__note_gp_changes() with rnp->lock held (raw_spinlock), thus is safe vs
preemption.

rdp->core_needs_qs *could* change after being read by the RCU core
kthread if it then gets preempted. Consider, with
CONFIG_RCU_STRICT_GRACE_PERIOD:

  rcuc/x                                   task_foo

    rcu_check_quiescent_state()
    `\
      rdp->core_needs_qs == true
			     <PREEMPT>
					   rcu_read_unlock()
					   `\
					     rcu_preempt_deferred_qs_irqrestore()
					     `\
					       rcu_report_qs_rdp()
					       `\
						 rdp->core_needs_qs := false;

This would let rcuc/x's rcu_check_quiescent_state() proceed further down to
rcu_report_qs_rdp(), but if task_foo's earlier rcu_report_qs_rdp()
invocation would have cleared the rdp grpmask from the rnp mask, so
rcuc/x's invocation would simply bail.

Since rcu_report_qs_rdp() can be safely invoked, even if rdp->core_needs_qs
changed, it appears safe to keep rcu_check_quiescent_state() preemptible.

[1]: http://lore.kernel.org/r/20210727230814.GC283787 at lothringen
[2]: http://lore.kernel.org/r/20210729010445.GO4397 at paulmck-ThinkPad-P17-Gen-1
Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
---
 kernel/rcu/tree.c        |  4 ++
 kernel/rcu/tree.h        |  4 ++
 kernel/rcu/tree_plugin.h | 82 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 51f24ecd94b2..caadfec994f3 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -87,6 +87,7 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_data, rcu_data) = {
 	.dynticks = ATOMIC_INIT(RCU_DYNTICK_CTRL_CTR),
 #ifdef CONFIG_RCU_NOCB_CPU
 	.cblist.flags = SEGCBLIST_SOFTIRQ_ONLY,
+	.nocb_local_lock =  INIT_LOCAL_LOCK(nocb_local_lock),
 #endif
 };
 static struct rcu_state rcu_state = {
@@ -2853,10 +2854,12 @@ static void rcu_cpu_kthread(unsigned int cpu)
 {
 	unsigned int *statusp = this_cpu_ptr(&rcu_data.rcu_cpu_kthread_status);
 	char work, *workp = this_cpu_ptr(&rcu_data.rcu_cpu_has_work);
+	struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
 	int spincnt;
 
 	trace_rcu_utilization(TPS("Start CPU kthread at rcu_run"));
 	for (spincnt = 0; spincnt < 10; spincnt++) {
+		rcu_nocb_local_lock(rdp);
 		local_bh_disable();
 		*statusp = RCU_KTHREAD_RUNNING;
 		local_irq_disable();
@@ -2866,6 +2869,7 @@ static void rcu_cpu_kthread(unsigned int cpu)
 		if (work)
 			rcu_core();
 		local_bh_enable();
+		rcu_nocb_local_unlock(rdp);
 		if (*workp == 0) {
 			trace_rcu_utilization(TPS("End CPU kthread at rcu_wait"));
 			*statusp = RCU_KTHREAD_WAITING;
diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
index 305cf6aeb408..aa6831255fec 100644
--- a/kernel/rcu/tree.h
+++ b/kernel/rcu/tree.h
@@ -210,6 +210,8 @@ struct rcu_data {
 	struct timer_list nocb_timer;	/* Enforce finite deferral. */
 	unsigned long nocb_gp_adv_time;	/* Last call_rcu() CB adv (jiffies). */
 
+	local_lock_t nocb_local_lock;
+
 	/* The following fields are used by call_rcu, hence own cacheline. */
 	raw_spinlock_t nocb_bypass_lock ____cacheline_internodealigned_in_smp;
 	struct rcu_cblist nocb_bypass;	/* Lock-contention-bypass CB list. */
@@ -445,6 +447,8 @@ static void rcu_nocb_unlock(struct rcu_data *rdp);
 static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
 				       unsigned long flags);
 static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp);
+static void rcu_nocb_local_lock(struct rcu_data *rdp);
+static void rcu_nocb_local_unlock(struct rcu_data *rdp);
 #ifdef CONFIG_RCU_NOCB_CPU
 static void __init rcu_organize_nocb_kthreads(void);
 #define rcu_nocb_lock_irqsave(rdp, flags)				\
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 0ff5e4fb933e..11c4ff00afde 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -21,6 +21,17 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
 	return lockdep_is_held(&rdp->nocb_lock);
 }
 
+static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
+{
+	return lockdep_is_held(
+#ifdef CONFIG_PREEMPT_RT
+		&rdp->nocb_local_lock.lock
+#else
+		&rdp->nocb_local_lock
+#endif
+	);
+}
+
 static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
 {
 	/* Race on early boot between thread creation and assignment */
@@ -38,7 +49,10 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
 {
 	return 0;
 }
-
+static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
+{
+	return 0;
+}
 static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
 {
 	return false;
@@ -46,23 +60,44 @@ static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
 
 #endif /* #ifdef CONFIG_RCU_NOCB_CPU */
 
+/*
+ * Is a local read of the rdp's offloaded state safe and stable?
+ * See rcu_nocb_local_lock() & family.
+ */
+static inline bool rcu_local_offload_access_safe(struct rcu_data *rdp)
+{
+	if (!preemptible())
+		return true;
+
+	if (!migratable()) {
+		if (!IS_ENABLED(CONFIG_RCU_NOCB))
+			return true;
+
+		return rcu_lockdep_is_held_nocb_local(rdp);
+	}
+
+	return false;
+}
+
 static bool rcu_rdp_is_offloaded(struct rcu_data *rdp)
 {
 	/*
-	 * In order to read the offloaded state of an rdp is a safe
-	 * and stable way and prevent from its value to be changed
-	 * under us, we must either hold the barrier mutex, the cpu
-	 * hotplug lock (read or write) or the nocb lock. Local
-	 * non-preemptible reads are also safe. NOCB kthreads and
-	 * timers have their own means of synchronization against the
-	 * offloaded state updaters.
+	 * In order to read the offloaded state of an rdp is a safe and stable
+	 * way and prevent from its value to be changed under us, we must either...
 	 */
 	RCU_LOCKDEP_WARN(
+		// ...hold the barrier mutex...
 		!(lockdep_is_held(&rcu_state.barrier_mutex) ||
+		  // ... the cpu hotplug lock (read or write)...
 		  (IS_ENABLED(CONFIG_HOTPLUG_CPU) && lockdep_is_cpus_held()) ||
+		  // ... or the NOCB lock.
 		  rcu_lockdep_is_held_nocb(rdp) ||
+		  // Local reads still require the local state to remain stable
+		  // (preemption disabled / local lock held)
 		  (rdp == this_cpu_ptr(&rcu_data) &&
-		   !(IS_ENABLED(CONFIG_PREEMPT_COUNT) && preemptible())) ||
+		   rcu_local_offload_access_safe(rdp)) ||
+		  // NOCB kthreads and timers have their own means of synchronization
+		  // against the offloaded state updaters.
 		  rcu_current_is_nocb_kthread(rdp)),
 		"Unsafe read of RCU_NOCB offloaded state"
 	);
@@ -1629,6 +1664,22 @@ static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
 	}
 }
 
+/*
+ * The invocation of rcu_core() within the RCU core kthreads remains preemptible
+ * under PREEMPT_RT, thus the offload state of a CPU could change while
+ * said kthreads are preempted. Prevent this from happening by protecting the
+ * offload state with a local_lock().
+ */
+static void rcu_nocb_local_lock(struct rcu_data *rdp)
+{
+	local_lock(&rcu_data.nocb_local_lock);
+}
+
+static void rcu_nocb_local_unlock(struct rcu_data *rdp)
+{
+	local_unlock(&rcu_data.nocb_local_lock);
+}
+
 /* Lockdep check that ->cblist may be safely accessed. */
 static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp)
 {
@@ -2396,6 +2447,7 @@ static int rdp_offload_toggle(struct rcu_data *rdp,
 	if (rdp->nocb_cb_sleep)
 		rdp->nocb_cb_sleep = false;
 	rcu_nocb_unlock_irqrestore(rdp, flags);
+	rcu_nocb_local_unlock(rdp);
 
 	/*
 	 * Ignore former value of nocb_cb_sleep and force wake up as it could
@@ -2427,6 +2479,7 @@ static long rcu_nocb_rdp_deoffload(void *arg)
 
 	pr_info("De-offloading %d\n", rdp->cpu);
 
+	rcu_nocb_local_lock(rdp);
 	rcu_nocb_lock_irqsave(rdp, flags);
 	/*
 	 * Flush once and for all now. This suffices because we are
@@ -2509,6 +2562,7 @@ static long rcu_nocb_rdp_offload(void *arg)
 	 * Can't use rcu_nocb_lock_irqsave() while we are in
 	 * SEGCBLIST_SOFTIRQ_ONLY mode.
 	 */
+	rcu_nocb_local_lock(rdp);
 	raw_spin_lock_irqsave(&rdp->nocb_lock, flags);
 
 	/*
@@ -2868,6 +2922,16 @@ static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
 	local_irq_restore(flags);
 }
 
+/* No ->nocb_local_lock to acquire. */
+static void rcu_nocb_local_lock(struct rcu_data *rdp)
+{
+}
+
+/* No ->nocb_local_lock to release. */
+static void rcu_nocb_local_unlock(struct rcu_data *rdp)
+{
+}
+
 /* Lockdep check that ->cblist may be safely accessed. */
 static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp)
 {
-- 
2.25.1



From valentin.schneider at arm.com  Wed Aug 11 13:13:54 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Wed, 11 Aug 2021 21:13:54 +0100
Subject: [PATCH v3 4/4] arm64: mm: Make arch_faults_on_old_pte() check for
 migratability
In-Reply-To: <20210811201354.1976839-1-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
Message-ID: <20210811201354.1976839-5-valentin.schneider@arm.com>

arch_faults_on_old_pte() relies on the calling context being
non-preemptible. CONFIG_PREEMPT_RT turns the PTE lock into a sleepable
spinlock, which doesn't disable preemption once acquired, triggering the
warning in arch_faults_on_old_pte().

It does however disable migration, ensuring the task remains on the same
CPU during the entirety of the critical section, making the read of
cpu_has_hw_af() safe and stable.

Make arch_faults_on_old_pte() check migratable() instead of preemptible().

Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
---
 arch/arm64/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index f09bf5c02891..8c0de3234b20 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -995,7 +995,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
  */
 static inline bool arch_faults_on_old_pte(void)
 {
-	WARN_ON(preemptible());
+	WARN_ON(migratable());
 
 	return !cpu_has_hw_af();
 }
-- 
2.25.1



From s.shtylyov at omp.ru  Wed Aug 11 13:14:24 2021
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Wed, 11 Aug 2021 23:14:24 +0300
Subject: [PATCH v2 0/5] Correctly handle plaform_get_irq()'s result in the
 i2C drivers
In-Reply-To: <83767306-be1b-3bcd-723c-92483b4cc612@omp.ru>
References: <3712e871-bf2f-32c5-f9c2-2968c42087f8@omp.ru>
 <83767306-be1b-3bcd-723c-92483b4cc612@omp.ru>
Message-ID: <cb7f1d92-7fdb-1ac9-a764-7f9996ba5742@omp.ru>

On 8/11/21 11:12 PM, Sergey Shtylyov wrote:

>> Here are 5 patches against the 'i2c/for-current' branch of Wolfram's 'linux.git' repo.
>> The affected drivers call platform_get_irq() but mis-interprete its result -- they consider
>> IRQ0 as error and (sometimes) the real error codes as valid IRQs... :-/
>>
>> [1/5] i2c: hix5hd2: fix IRQ check
>> [2/5] i2c: mt65xx: fix IRQ check
>> [3/5] i2c: pmcmsp: fix IRQ check
>> [4/5] i2c: s3c2410: fix IRQ check
>> [5/5] i2c: xlp9xx: fix main IRQ check
> 
>    Wolfram, hat's up with this series (its status in the patchwork is still "new")? 

   What's, of/c. :-)

MBR, Sergey



From kuba at kernel.org  Wed Aug 11 15:31:32 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Wed, 11 Aug 2021 15:31:32 -0700
Subject: [PATCH net-next 1/2] net: sparx5: switchdev: adding frame DMA
 functionality
In-Reply-To: <20210811075909.543633-2-steen.hegelund@microchip.com>
References: <20210811075909.543633-1-steen.hegelund@microchip.com>
 <20210811075909.543633-2-steen.hegelund@microchip.com>
Message-ID: <20210811153132.63480934@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Wed, 11 Aug 2021 09:59:08 +0200 Steen Hegelund wrote:
> This add frame DMA functionality to the Sparx5 platform.
> 
> Ethernet frames can be extracted or injected autonomously to or from the
> device?s DDR3/DDR3L memory and/or PCIe memory space. Linked list data
> structures in memory are used for injecting or extracting Ethernet frames.
> The FDMA generates interrupts when frame extraction or injection is done
> and when the linked lists need updating.

Something to fix:

drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c: In function ?sparx5_fdma_start?:
drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c:544:6: warning: variable ?proc_ctrl? set but not used [-Wunused-but-set-variable]
  544 |  u32 proc_ctrl;
      |      ^~~~~~~~~


From chunkuang.hu at kernel.org  Wed Aug 11 16:05:31 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 12 Aug 2021 07:05:31 +0800
Subject: [PATCH v2] drm/mediatek: add AAL output size configuration
In-Reply-To: <20210810025503.16353-1-jason-jh.lin@mediatek.com>
References: <20210810025503.16353-1-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_8+wnXxetnvijkc1FCN=bPuq8sO4psoTpjT9gS-4nieMw@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?10? ?? ??10:55???
>
> To avoid the output width and height is incorrect,
> AAL_OUTPUT_SIZE configuration should be set.

Applied to mediatek-drm-fixes [1], thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-fixes

Regards,
Chun-Kuang.

>
> Fixes: 0664d1392c26 ("drm/mediatek: Add AAL engine basic function")
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> Change in v2:
> - fix to one line
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 75bc00e17fc4..50d20562e612 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -34,6 +34,7 @@
>
>  #define DISP_AAL_EN                            0x0000
>  #define DISP_AAL_SIZE                          0x0030
> +#define DISP_AAL_OUTPUT_SIZE                   0x04d8
>
>  #define DISP_DITHER_EN                         0x0000
>  #define DITHER_EN                              BIT(0)
> @@ -197,6 +198,7 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
>         mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
> +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_OUTPUT_SIZE);
>  }
>
>  static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
> --
> 2.18.0
>


From chunkuang.hu at kernel.org  Wed Aug 11 16:05:57 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 12 Aug 2021 07:05:57 +0800
Subject: [PATCH v2] drm/mediatek: Add component_del in OVL and COLOR
 remove function
In-Reply-To: <20210810040148.17157-1-jason-jh.lin@mediatek.com>
References: <20210810040148.17157-1-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_9+G92rhKCiZZS39VCjo6g3Zj+Ag=SeEuRtbP3c=jsSug@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?10? ?? ??12:02???
>
> Add component_del in OVL and COLOR remove function.

Applied to mediatek-drm-fixes [1], thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-fixes

Regards,
Chun-Kuang.

>
> Fixes: ff1395609e20 ("drm/mediatek: Move mtk_ddp_comp_init() from sub driver to DRM driver")
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> Change in v2:
> - add component_del function in COLOR remove function
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_color.c | 2 ++
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c   | 2 ++
>  2 files changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
> index 6f4c80bbc0eb..473f5bb5cbad 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
> @@ -133,6 +133,8 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
>
>  static int mtk_disp_color_remove(struct platform_device *pdev)
>  {
> +       component_del(&pdev->dev, &mtk_disp_color_component_ops);
> +
>         return 0;
>  }
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index fa9d79963cd3..5326989d5206 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -423,6 +423,8 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
>
>  static int mtk_disp_ovl_remove(struct platform_device *pdev)
>  {
> +       component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
> +
>         return 0;
>  }
>
> --
> 2.18.0
>


From chunkuang.hu at kernel.org  Wed Aug 11 17:19:54 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 12 Aug 2021 08:19:54 +0800
Subject: [PATCH v4] drm/mediatek: clear pending flag when cmdq packet is
 done.
In-Reply-To: <1628646468-29775-2-git-send-email-yongqiang.niu@mediatek.com>
References: <1628646468-29775-1-git-send-email-yongqiang.niu@mediatek.com>
 <1628646468-29775-2-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <CAAOTY_-qigNtPJETHsE8YaVqxctrZ7Y+a31f5eqOVHXPowuucw@mail.gmail.com>

Hi, Yongqiang:

Yongqiang Niu <yongqiang.niu at mediatek.com> ? 2021?8?11? ?? ??9:48???
>
> In cmdq mode, packet may be flushed before it is executed, so
> the pending flag should be cleared after cmdq packet is done.

Applied to mediatek-drm-next [1], thanks.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next

Regards,
Chun-Kuang.

>
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 47 +++++++++++++++++++++++++++++----
>  1 file changed, 42 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 4c25e33..89f093d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -267,6 +267,36 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
>  {
>         struct mtk_drm_crtc *mtk_crtc = container_of(cl, struct mtk_drm_crtc, cmdq_cl);
>         struct cmdq_cb_data *data = mssg;
> +       struct mtk_crtc_state *state;
> +       unsigned int i;
> +
> +       state = to_mtk_crtc_state(mtk_crtc->base.state);
> +
> +       state->pending_config = false;
> +
> +       if (mtk_crtc->pending_planes) {
> +               for (i = 0; i < mtk_crtc->layer_nr; i++) {
> +                       struct drm_plane *plane = &mtk_crtc->planes[i];
> +                       struct mtk_plane_state *plane_state;
> +
> +                       plane_state = to_mtk_plane_state(plane->state);
> +
> +                       plane_state->pending.config = false;
> +               }
> +               mtk_crtc->pending_planes = false;
> +       }
> +
> +       if (mtk_crtc->pending_async_planes) {
> +               for (i = 0; i < mtk_crtc->layer_nr; i++) {
> +                       struct drm_plane *plane = &mtk_crtc->planes[i];
> +                       struct mtk_plane_state *plane_state;
> +
> +                       plane_state = to_mtk_plane_state(plane->state);
> +
> +                       plane_state->pending.async_config = false;
> +               }
> +               mtk_crtc->pending_async_planes = false;
> +       }
>
>         mtk_crtc->cmdq_vblank_cnt = 0;
>         mtk_drm_cmdq_pkt_destroy(mtk_crtc->cmdq_chan, data->pkt);
> @@ -423,7 +453,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
>                                     state->pending_vrefresh, 0,
>                                     cmdq_handle);
>
> -               state->pending_config = false;
> +               if (!cmdq_handle)
> +                       state->pending_config = false;
>         }
>
>         if (mtk_crtc->pending_planes) {
> @@ -443,9 +474,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
>                                 mtk_ddp_comp_layer_config(comp, local_layer,
>                                                           plane_state,
>                                                           cmdq_handle);
> -                       plane_state->pending.config = false;
> +                       if (!cmdq_handle)
> +                               plane_state->pending.config = false;
>                 }
> -               mtk_crtc->pending_planes = false;
> +
> +               if (!cmdq_handle)
> +                       mtk_crtc->pending_planes = false;
>         }
>
>         if (mtk_crtc->pending_async_planes) {
> @@ -465,9 +499,12 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
>                                 mtk_ddp_comp_layer_config(comp, local_layer,
>                                                           plane_state,
>                                                           cmdq_handle);
> -                       plane_state->pending.async_config = false;
> +                       if (!cmdq_handle)
> +                               plane_state->pending.async_config = false;
>                 }
> -               mtk_crtc->pending_async_planes = false;
> +
> +               if (!cmdq_handle)
> +                       mtk_crtc->pending_async_planes = false;
>         }
>  }
>
> --
> 1.8.1.1.dirty
>


From chunfeng.yun at mediatek.com  Wed Aug 11 20:32:59 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 11:32:59 +0800
Subject: [PATCH 3/6] usb: cdnsp: fix the wrong mult value for HS isoc or intr
In-Reply-To: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628739182-30089-3-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
of endpoint descriptor, not include bit[12:11] anymore, so use
usb_endpoint_maxp_mult() instead.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/cdns3/cdnsp-mem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
index a47948a1623f..ad9aee3f1e39 100644
--- a/drivers/usb/cdns3/cdnsp-mem.c
+++ b/drivers/usb/cdns3/cdnsp-mem.c
@@ -882,7 +882,7 @@ static u32 cdnsp_get_endpoint_max_burst(struct usb_gadget *g,
 	if (g->speed == USB_SPEED_HIGH &&
 	    (usb_endpoint_xfer_isoc(pep->endpoint.desc) ||
 	     usb_endpoint_xfer_int(pep->endpoint.desc)))
-		return (usb_endpoint_maxp(pep->endpoint.desc) & 0x1800) >> 11;
+		return usb_endpoint_maxp_mult(pep->endpoint.desc) - 1;
 
 	return 0;
 }
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 20:32:58 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 11:32:58 +0800
Subject: [PATCH 2/6] usb: mtu3: fix the wrong HS mult value
In-Reply-To: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628739182-30089-2-git-send-email-chunfeng.yun@mediatek.com>

Use usb_endpoint_maxp() and usb_endpoint_maxp_mult() seperately
to get maxpacket and mult.
Meanwhile fix the bug that should use @mult but not @burst
to save mult value.

Fixes: 4d79e042ed8b ("usb: mtu3: add support for usb3.1 IP")
Cc: stable <stable at vger.kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/mtu3/mtu3_gadget.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 5e21ba05ebf0..a399fd84c71f 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -64,14 +64,12 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 	u32 interval = 0;
 	u32 mult = 0;
 	u32 burst = 0;
-	int max_packet;
 	int ret;
 
 	desc = mep->desc;
 	comp_desc = mep->comp_desc;
 	mep->type = usb_endpoint_type(desc);
-	max_packet = usb_endpoint_maxp(desc);
-	mep->maxp = max_packet & GENMASK(10, 0);
+	mep->maxp = usb_endpoint_maxp(desc);
 
 	switch (mtu->g.speed) {
 	case USB_SPEED_SUPER:
@@ -92,7 +90,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
 			interval = clamp_val(interval, 1, 16) - 1;
-			burst = (max_packet & GENMASK(12, 11)) >> 11;
+			mult = usb_endpoint_maxp_mult(desc) - 1;
 		}
 		break;
 	default:
-- 
2.25.1

From lkp at intel.com  Wed Aug 11 20:33:27 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 11:33:27 +0800
Subject: [xlnx:xlnx_rebase_v5.10 625/1760] drivers/of/configfs.c:134:9:
 warning: no previous prototype for function 'cfs_overlay_item_dtbo_read'
Message-ID: <202108121120.21EsCbQ0-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   bf98c1493fb23bfd7e2678498b7e337ce2cd1d53
commit: e6de170decc96254704d77b4726ad658c6a2f42c [625/1760] OF: DT-Overlay configfs interface (v8)
config: s390-randconfig-r011-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/e6de170decc96254704d77b4726ad658c6a2f42c
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout e6de170decc96254704d77b4726ad658c6a2f42c
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/of/configfs.c:134:9: warning: no previous prototype for function 'cfs_overlay_item_dtbo_read' [-Wmissing-prototypes]
   ssize_t cfs_overlay_item_dtbo_read(struct config_item *item,
           ^
   drivers/of/configfs.c:134:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   ssize_t cfs_overlay_item_dtbo_read(struct config_item *item,
   ^
   static 
>> drivers/of/configfs.c:156:9: warning: no previous prototype for function 'cfs_overlay_item_dtbo_write' [-Wmissing-prototypes]
   ssize_t cfs_overlay_item_dtbo_write(struct config_item *item,
           ^
   drivers/of/configfs.c:156:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   ssize_t cfs_overlay_item_dtbo_write(struct config_item *item,
   ^
   static 
   2 warnings generated.

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for MFD_SUN6I_PRCM
   Depends on HAS_IOMEM && (ARCH_SUNXI || COMPILE_TEST
   Selected by
   - CLK_SUNXI_PRCM_SUN6I && COMMON_CLK && CLK_SUNXI
   - CLK_SUNXI_PRCM_SUN8I && COMMON_CLK && CLK_SUNXI


vim +/cfs_overlay_item_dtbo_read +134 drivers/of/configfs.c

   133	
 > 134	ssize_t cfs_overlay_item_dtbo_read(struct config_item *item,
   135					   void *buf, size_t max_count)
   136	{
   137		struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
   138	
   139		pr_debug("%s: buf=%p max_count=%zu\n", __func__, buf, max_count);
   140	
   141		if (!overlay->dtbo)
   142			return 0;
   143	
   144		/* copy if buffer provided */
   145		if (buf) {
   146			/* the buffer must be large enough */
   147			if (overlay->dtbo_size > max_count)
   148				return -ENOSPC;
   149	
   150			memcpy(buf, overlay->dtbo, overlay->dtbo_size);
   151		}
   152	
   153		return overlay->dtbo_size;
   154	}
   155	
 > 156	ssize_t cfs_overlay_item_dtbo_write(struct config_item *item,
   157					    const void *buf, size_t count)
   158	{
   159		struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
   160		int err;
   161	
   162		/* if it's set do not allow changes */
   163		if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
   164			return -EPERM;
   165	
   166		/* copy the contents */
   167		overlay->dtbo = kmemdup(buf, count, GFP_KERNEL);
   168		if (!overlay->dtbo)
   169			return -ENOMEM;
   170	
   171		overlay->dtbo_size = count;
   172	
   173		err = create_overlay(overlay, overlay->dtbo);
   174		if (err < 0)
   175			goto out_err;
   176	
   177		return count;
   178	
   179	out_err:
   180		kfree(overlay->dtbo);
   181		overlay->dtbo = NULL;
   182		overlay->dtbo_size = 0;
   183	
   184		return err;
   185	}
   186	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 17107 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/6462e87e/attachment-0001.gz>

From chunfeng.yun at mediatek.com  Wed Aug 11 20:33:00 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 11:33:00 +0800
Subject: [PATCH 4/6] usb: gadget: tegra-xudc: fix the wrong mult value for HS
 isoc or intr
In-Reply-To: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628739182-30089-4-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
of endpoint descriptor, not includes bit[12:11] anymore, so use
usb_endpoint_maxp_mult() instead.
Meanwhile no need AND 0x7ff when get maxp, remove it.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/gadget/udc/tegra-xudc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index a54d1cef17db..40a7417e7ae4 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -1610,7 +1610,7 @@ static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep)
 	u16 maxpacket, maxburst = 0, esit = 0;
 	u32 val;
 
-	maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
+	maxpacket = usb_endpoint_maxp(desc);
 	if (xudc->gadget.speed == USB_SPEED_SUPER) {
 		if (!usb_endpoint_xfer_control(desc))
 			maxburst = comp_desc->bMaxBurst;
@@ -1621,7 +1621,7 @@ static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep)
 		   (usb_endpoint_xfer_int(desc) ||
 		    usb_endpoint_xfer_isoc(desc))) {
 		if (xudc->gadget.speed == USB_SPEED_HIGH) {
-			maxburst = (usb_endpoint_maxp(desc) >> 11) & 0x3;
+			maxburst = usb_endpoint_maxp_mult(desc) - 1;
 			if (maxburst == 0x3) {
 				dev_warn(xudc->dev,
 					 "invalid endpoint maxburst\n");
-- 
2.25.1

From lkp at intel.com  Wed Aug 11 20:39:27 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 11:39:27 +0800
Subject: [xlnx:xlnx_rebase_v5.10 1363/1760]
 drivers/uio/uio_xilinx_ai_engine.c:39:6: warning: variable 'irq' set but not
 used
Message-ID: <202108121122.IdzjKXeG-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   bf98c1493fb23bfd7e2678498b7e337ce2cd1d53
commit: b0c3669ae8f124715469bae21ac86b25f3c48cf6 [1363/1760] uio: Add the UIO driver for AI engine
config: arm-randconfig-r016-20210812 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/b0c3669ae8f124715469bae21ac86b25f3c48cf6
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout b0c3669ae8f124715469bae21ac86b25f3c48cf6
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   drivers/uio/uio_xilinx_ai_engine.c: In function 'xilinx_ai_engine_debugfs_write':
>> drivers/uio/uio_xilinx_ai_engine.c:39:6: warning: variable 'irq' set but not used [-Wunused-but-set-variable]
      39 |  int irq, ret;
         |      ^~~


vim +/irq +39 drivers/uio/uio_xilinx_ai_engine.c

    33	
    34	static ssize_t xilinx_ai_engine_debugfs_write(struct file *f,
    35						      const char __user *buf,
    36						      size_t size, loff_t *pos)
    37	{
    38		struct irq_domain *irq_sim_domain = file_inode(f)->i_private;
  > 39		int irq, ret;
    40	
    41		irq = irq_find_mapping(irq_sim_domain, 1);
    42		ret = irq_set_irqchip_state(1, IRQCHIP_STATE_PENDING, true);
    43		if (ret)
    44			return ret;
    45	
    46		return size;
    47	}
    48	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 33144 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/3f23f821/attachment-0001.gz>

From chunfeng.yun at mediatek.com  Wed Aug 11 20:33:01 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 11:33:01 +0800
Subject: [PATCH 5/6] usb: gadget: bdc: remove unnecessary AND operation when
 get ep maxp
In-Reply-To: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628739182-30089-5-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() already returns actual max packet size, no need
AND 0x7ff.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/gadget/udc/bdc/bdc_cmd.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.c b/drivers/usb/gadget/udc/bdc/bdc_cmd.c
index 995f79c79f96..67887316a1a6 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_cmd.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.c
@@ -153,7 +153,6 @@ int bdc_config_ep(struct bdc *bdc, struct bdc_ep *ep)
 	si = clamp_val(si, 1, 16) - 1;
 
 	mps = usb_endpoint_maxp(desc);
-	mps &= 0x7ff;
 	param2 |= mps << MP_SHIFT;
 	param2 |= usb_endpoint_type(desc) << EPT_SHIFT;
 
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 20:32:57 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 11:32:57 +0800
Subject: [PATCH 1/6] usb: mtu3: restore HS function when set SS/SSP
Message-ID: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>

Due to HS function is disabled when set as FS, need restore
it when set as SS/SSP.

Fixes: dc4c1aa7eae9 ("usb: mtu3: add ->udc_set_speed()")
Cc: stable <stable at vger.kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/mtu3/mtu3_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index 562f4357831e..6403f01947b2 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -227,11 +227,13 @@ static void mtu3_set_speed(struct mtu3 *mtu, enum usb_device_speed speed)
 		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		break;
 	case USB_SPEED_SUPER:
+		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		mtu3_clrbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	case USB_SPEED_SUPER_PLUS:
-			mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
+		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
+		mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	default:
-- 
2.25.1

From chunfeng.yun at mediatek.com  Wed Aug 11 20:33:02 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 11:33:02 +0800
Subject: [PATCH 6/6] usb: gadget: remove unnecessary AND operation when get ep
 maxp
In-Reply-To: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628739182-30089-6-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() already returns actual max packet size, no need
AND 0x7ff.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 include/linux/usb/gadget.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 75c7538e350a..f181c84310b6 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -491,7 +491,7 @@ extern char *usb_get_gadget_udc_name(void);
  */
 static inline size_t usb_ep_align(struct usb_ep *ep, size_t len)
 {
-	int max_packet_size = (size_t)usb_endpoint_maxp(ep->desc) & 0x7ff;
+	int max_packet_size = (size_t)usb_endpoint_maxp(ep->desc);
 
 	return round_up(len, max_packet_size);
 }
-- 
2.25.1

From lkp at intel.com  Wed Aug 11 20:45:09 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 11:45:09 +0800
Subject: [xlnx:xlnx_rebase_v5.10 1018/1760]
 drivers/clk/clk-xlnx-clock-wizard-v.c:119:21: warning: cast from pointer to
 integer of different size
Message-ID: <202108121103.XJmMq1bE-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   bf98c1493fb23bfd7e2678498b7e337ce2cd1d53
commit: 81494997bdd4943edc98a4d7689dd28db2960307 [1018/1760] clocking-wizard: Add versal clocking wizard support
config: i386-randconfig-r013-20210812 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/Xilinx/linux-xlnx/commit/81494997bdd4943edc98a4d7689dd28db2960307
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 81494997bdd4943edc98a4d7689dd28db2960307
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   drivers/clk/clk-xlnx-clock-wizard-v.c: In function 'clk_wzrd_recalc_rate':
>> drivers/clk/clk-xlnx-clock-wizard-v.c:119:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     119 |    (void __iomem *)((u64)divider->base + divider->offset);
         |                     ^
>> drivers/clk/clk-xlnx-clock-wizard-v.c:119:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     119 |    (void __iomem *)((u64)divider->base + divider->offset);
         |    ^
   drivers/clk/clk-xlnx-clock-wizard-v.c: In function 'clk_wzrd_dynamic_reconfig':
   drivers/clk/clk-xlnx-clock-wizard-v.c:149:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     149 |    (void __iomem *)((u64)divider->base + divider->offset);
         |                     ^
   drivers/clk/clk-xlnx-clock-wizard-v.c:149:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     149 |    (void __iomem *)((u64)divider->base + divider->offset);
         |    ^


vim +119 drivers/clk/clk-xlnx-clock-wizard-v.c

   113	
   114	static unsigned long clk_wzrd_recalc_rate(struct clk_hw *hw,
   115						  unsigned long parent_rate)
   116	{
   117		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   118		void __iomem *div_addr =
 > 119				(void __iomem *)((u64)divider->base + divider->offset);
   120		unsigned int vall, valh;
   121		u32 div;
   122		u32 p5en, edge, prediv2;
   123		u32 all;
   124	
   125		edge = !!(readl(div_addr) & BIT(8));
   126		p5en = !!(readl(div_addr) & BIT(13));
   127		prediv2 = !!(readl(div_addr) & BIT(11));
   128		vall = readl(div_addr + 4) & 0xff;
   129		valh = readl(div_addr + 4) >> 8;
   130		all = valh + vall + edge;
   131		if (!all)
   132			all = 1;
   133		div = (prediv2 + 1) * (all + (prediv2 * p5en) / 2);
   134		return  DIV_ROUND_UP_ULL((u64)parent_rate, div);
   135	}
   136	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 30829 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/148c95a1/attachment-0001.gz>

From viresh.kumar at linaro.org  Wed Aug 11 20:53:16 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Aug 2021 09:23:16 +0530
Subject: [PATCH V2 9/9] cpufreq: scmi: Use .register_em() callback
In-Reply-To: <YRPN8zjp1wqkHg6t@google.com>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
 <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
 <YRPN8zjp1wqkHg6t@google.com>
Message-ID: <20210812035316.jen62wsrl4tlbrpm@vireshk-i7>

On 11-08-21, 14:17, Quentin Perret wrote:
> Also, we can probably afford calling dev_pm_opp_get_opp_count() from the
> em_register callback as it is not a hot path, which would avoid wasting
> some 'resident' memory here that is only used during init.

We also need to make sure that OPPs are available in init(), else we
fail. So, we can't really move that out.

-- 
viresh


From zajec5 at gmail.com  Wed Aug 11 20:59:30 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Thu, 12 Aug 2021 05:59:30 +0200
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
Message-ID: <56f4913b-25b0-7dfd-35bd-5c43ff4b65c3@gmail.com>

On 11.08.2021 14:15, Rafa? Mi?ecki wrote:
> All I could do to help debugging this regression was bisecting. The
> first bad commit (I verified it after bisecting process) is:
> 
> commit 0c93df9622d4d921bcd0dc83f71fed9e98f5119f
> Author: Marc Zyngier <maz at kernel.org>
> Date:?? Mon Feb 8 09:57:14 2021 +0000
> 
>  ??? arm64: Initialise as nVHE before switching to VHE
> 
>  ??? As we are aiming to be able to control whether we enable VHE or
>  ??? not, let's always drop down to EL1 first, and only then upgrade
>  ??? to VHE if at all possible.
> 
>  ??? This means that if the kernel is booted at EL2, we always start
>  ??? with a nVHE init, drop to EL1 to initialise the the kernel, and
>  ??? only then upgrade the kernel EL to EL2 if possible (the process
>  ??? is obviously shortened for secondary CPUs).
> 
>  ??? The resume path is handled similarly to a secondary CPU boot.
> 
>  ??? Signed-off-by: Marc Zyngier <maz at kernel.org>
>  ??? Acked-by: David Brazdil <dbrazdil at google.com>
>  ??? Acked-by: Catalin Marinas <catalin.marinas at arm.com>
>  ??? Link: https://lore.kernel.org/r/20210208095732.3267263-6-maz at kernel.org
>  ??? [will: Avoid calling switch_to_vhe twice on kaslr path]
>  ??? Signed-off-by: Will Deacon <will at kernel.org>

FWIW I confirmed it's about the above commit.

***

On top of 5.12.19 I can do:

git revert \
d077cb3cb90470f8bd7dbe357a474e13589390b9 \
e2df464173f0b585adb958a09536eae2cd1dbefd \
0c93df9622d4d921bcd0dc83f71fed9e98f5119f

to get a booting kernel (the first 2 commits need to be reverted to
allow a clean revert of the 0c93df9622d4).

***

On top of 5.13.9 I can do:

git revert \
2d726d0db6ac479d91bf74490455badd34af6b1d \
d077cb3cb90470f8bd7dbe357a474e13589390b9 \
e2df464173f0b585adb958a09536eae2cd1dbefd \
0c93df9622d4d921bcd0dc83f71fed9e98f5119f

to get a booting kernel too.


From houwenlong93 at linux.alibaba.com  Wed Aug 11 21:02:19 2021
From: houwenlong93 at linux.alibaba.com (Hou Wenlong)
Date: Thu, 12 Aug 2021 12:02:19 +0800
Subject: [PATCH v2 1/2] KVM: Refactor kvm_arch_vcpu_fault() to return a struct
 page pointer
In-Reply-To: <YRQcZqCWwVH8bCGc@google.com>
References: <YRQcZqCWwVH8bCGc@google.com>
Message-ID: <1c510b24fc1d7cbae8aa4b69c0799ebd32e65b82.1628739116.git.houwenlong93@linux.alibaba.com>

From: Sean Christopherson <seanjc at google.com>

Refactor kvm_arch_vcpu_fault() to return 'struct page *' instead of
'vm_fault_t' to simplify architecture specific implementations that do
more than return SIGBUS.  Currently this only applies to s390, but a
future patch will move x86's pio_data handling into x86 where it belongs.

No functional changed intended.

Cc: Hou Wenlong <houwenlong93 at linux.alibaba.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
Signed-off-by: Hou Wenlong <houwenlong93 at linux.alibaba.com>
---
 arch/arm64/kvm/arm.c       |  4 ++--
 arch/mips/kvm/mips.c       |  4 ++--
 arch/powerpc/kvm/powerpc.c |  4 ++--
 arch/s390/kvm/kvm-s390.c   | 12 ++++--------
 arch/x86/kvm/x86.c         |  4 ++--
 include/linux/kvm_host.h   |  2 +-
 virt/kvm/kvm_main.c        |  5 ++++-
 7 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..83f4ffe3e4f2 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -161,9 +161,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	return ret;
 }
 
-vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
+struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
 {
-	return VM_FAULT_SIGBUS;
+	return NULL;
 }
 
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index af9dd029a4e1..ae79874e6fd2 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -1053,9 +1053,9 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 	return -ENOIOCTLCMD;
 }
 
-vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
+struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
 {
-	return VM_FAULT_SIGBUS;
+	return NULL;
 }
 
 int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index be33b5321a76..b9c21f9ab784 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -2090,9 +2090,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 	return r;
 }
 
-vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
+struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
 {
-	return VM_FAULT_SIGBUS;
+	return NULL;
 }
 
 static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 02574d7b3612..e1b69833e228 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -4979,17 +4979,13 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 	return r;
 }
 
-vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
+struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
 {
 #ifdef CONFIG_KVM_S390_UCONTROL
-	if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
-		 && (kvm_is_ucontrol(vcpu->kvm))) {
-		vmf->page = virt_to_page(vcpu->arch.sie_block);
-		get_page(vmf->page);
-		return 0;
-	}
+	if (vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET && kvm_is_ucontrol(vcpu->kvm))
+		return virt_to_page(vcpu->arch.sie_block);
 #endif
-	return VM_FAULT_SIGBUS;
+	return NULL;
 }
 
 /* Section: memory related */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3cedc7cc132a..1e3bbe5cd33a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5347,9 +5347,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 	return r;
 }
 
-vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
+struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
 {
-	return VM_FAULT_SIGBUS;
+	return NULL;
 }
 
 static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 492d183dd7d0..a949de534722 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -995,7 +995,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
 			unsigned int ioctl, unsigned long arg);
 long kvm_arch_vcpu_ioctl(struct file *filp,
 			 unsigned int ioctl, unsigned long arg);
-vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
+struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
 
 int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext);
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 30d322519253..f7d21418971b 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3448,7 +3448,10 @@ static vm_fault_t kvm_vcpu_fault(struct vm_fault *vmf)
 		    &vcpu->dirty_ring,
 		    vmf->pgoff - KVM_DIRTY_LOG_PAGE_OFFSET);
 	else
-		return kvm_arch_vcpu_fault(vcpu, vmf);
+		page = kvm_arch_vcpu_fault(vcpu, vmf);
+	if (!page)
+		return VM_FAULT_SIGBUS;
+
 	get_page(page);
 	vmf->page = page;
 	return 0;
-- 
2.31.1



From billy_tsai at aspeedtech.com  Wed Aug 11 21:09:40 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Thu, 12 Aug 2021 12:09:40 +0800
Subject: [v11 0/2] Support pwm driver for aspeed ast26xx
Message-ID: <20210812040942.5365-1-billy_tsai@aspeedtech.com>

The legacy driver of aspeed pwm is binding with tach controller and it
doesn't follow the pwm framworks usage. In addition, the pwm register
usage of the 6th generation of ast26xx has drastic change. So these
patch serials add the new aspeed pwm driver to fix up the problem above.

Change since v10:
- pwm-aspeed-ast2600.c
  - Add more comment to explain the feature of PWM
  - Fix the naming of some parameters.
  - Set pin_enable and clk_enable at the same time.
  - Always set fixed divisor to hw register when apply.

Change since v9:
- dt-bindings:
  - Change the naming of tach subnode channel setting property to
  aspeed,tach-ch.
- pwm-aspeed-ast2600.c
  - Fix the naming of some parameters.
  - Capitalise error messages.
  - Handling potentially mult overflow when .apply

Change since v8:
- pwm-aspeed-ast2600.c
  - Replace "* _BITULL(div_h)" to "<< div_h"
  - Fix duty_cycle precision problem.
  - Add the comment about the formula of duty_cycle.

Change since v7:
- pwm-aspeed-g6.c
  - Rename the driver: pwm-aspeed-g6.c -> pwm-aspeed-ast2600.c.
  - Macro remove "_CH" part of the register name.
  - Unroll the aspeed_pwm_get_period and remove it.
  - Simplify the formula to get duty_pt
  - Reduce the number of writing register. Organize all the fields and
    write them at once.

Change since v6:
- dt-bindings:
  - Add blank line between each DT property.
  - Change the sub-node name from fan to tach-ch.
- pwm-aspeed-g6.c
  - Merge aspeed_pwm_set_period and aspeed_pwm_set_duty into .apply.
  - Convert the factor type to u64 when calculating the period value.
  - Using ROUND_UP strategy to calculate div_h for finer resolution.

Change since v5:
- pwm-aspeed-g6.c suggested by Uwe Kleine-K?nig
  - Move the divide at the end of the calculation.
  - Unified the prefix of the function name.
  - Use div64_u64 to calculate the divider of frequency.

Change since v4:
- dt_binding:
  - pwm/tach yaml: Replace child-node with additionalProperties
  - pwm-tach yaml: Replace child-node with patternProperties
- pwm-aspeed-g6.c suggested by Uwe Kleine-K?nig
  - The bit definitions contained the name of the register.
  - Remove single caller function and fold it to the caller.
  - Avoid to divide by the result of a division.
  - Remove unnecessary condition in .apply().
  - Use goto for error handling

Changes since v3:
- Add the dt_binding for aspeed,ast2600-tach.
- Describe the pwm/tach as child-node of pwm-tach mfd.
- Complete the properties of pwm node.

Changes since v2:
- Remove the tach node, #address-cells and #size-cells from pwm-tach.yaml
- Add clocks and reset properties to pwm-tach.yaml
- Kconfig/Makfile sorted alphabetically
- pwm-aspeed-g6.c suggested by Uwe Kleine-K?nig
  - Add more hardware descriptions at top of the driver.
  - Remove unused api request and free
  - Move the initialize settings of all pwm channel to probe.
  - Change the method of getting the approximate period.
  - Read the hardware register values to fill the state for .get_state()

Changes since v1:
- Fix the dt_binding_check fail suggested by Rob Herring
- Add depends to PWM_ASPEED_G6 configure suggested by Uwe Kleine-Konig
- pwm-aspeed-g6.c suggested by Uwe Kleine-K?nig
  - Fix license header
  - Use bitfiled.h macro to define register fields
  - Implement .remove device function
  - Implement .get_state pwm api

Billy Tsai (2):
  dt-bindings: Add bindings for aspeed pwm-tach.
  pwm: Add Aspeed ast2600 PWM support

 .../bindings/hwmon/aspeed,ast2600-tach.yaml   |  68 ++++
 .../bindings/mfd/aspeed,ast2600-pwm-tach.yaml |  76 ++++
 .../bindings/pwm/aspeed,ast2600-pwm.yaml      |  64 ++++
 drivers/pwm/Kconfig                           |  10 +
 drivers/pwm/Makefile                          |   1 +
 drivers/pwm/pwm-aspeed-ast2600.c              | 327 ++++++++++++++++++
 6 files changed, 546 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/aspeed,ast2600-tach.yaml
 create mode 100644 Documentation/devicetree/bindings/mfd/aspeed,ast2600-pwm-tach.yaml
 create mode 100644 Documentation/devicetree/bindings/pwm/aspeed,ast2600-pwm.yaml
 create mode 100644 drivers/pwm/pwm-aspeed-ast2600.c

-- 
2.25.1



From billy_tsai at aspeedtech.com  Wed Aug 11 21:09:41 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Thu, 12 Aug 2021 12:09:41 +0800
Subject: [v11 1/2] dt-bindings: Add bindings for aspeed pwm-tach.
In-Reply-To: <20210812040942.5365-1-billy_tsai@aspeedtech.com>
References: <20210812040942.5365-1-billy_tsai@aspeedtech.com>
Message-ID: <20210812040942.5365-2-billy_tsai@aspeedtech.com>

This patch adds device binding for aspeed pwm-tach device which is a
multi-function device include pwm and tach function and pwm/tach device
bindings which should be the child-node of pwm-tach device.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 .../bindings/hwmon/aspeed,ast2600-tach.yaml   | 68 +++++++++++++++++
 .../bindings/mfd/aspeed,ast2600-pwm-tach.yaml | 76 +++++++++++++++++++
 .../bindings/pwm/aspeed,ast2600-pwm.yaml      | 64 ++++++++++++++++
 3 files changed, 208 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/aspeed,ast2600-tach.yaml
 create mode 100644 Documentation/devicetree/bindings/mfd/aspeed,ast2600-pwm-tach.yaml
 create mode 100644 Documentation/devicetree/bindings/pwm/aspeed,ast2600-pwm.yaml

diff --git a/Documentation/devicetree/bindings/hwmon/aspeed,ast2600-tach.yaml b/Documentation/devicetree/bindings/hwmon/aspeed,ast2600-tach.yaml
new file mode 100644
index 000000000000..dded50a049fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/aspeed,ast2600-tach.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2021 Aspeed, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/aspeed,ast2600-tach.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed Ast2600 Tach controller
+
+maintainers:
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+description: |
+  The Aspeed Tach controller can support upto 16 fan input.
+  This module is part of the ast2600-pwm-tach multi-function device. For more
+  details see ../mfd/aspeed,ast2600-pwm-tach.yaml.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2600-tach
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  pinctrl-0: true
+
+  pinctrl-names:
+    const: default
+
+required:
+  - compatible
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties:
+  type: object
+  properties:
+    aspeed,tach-ch:
+      description:
+        The tach channel used for this node.
+      maxItems: 1
+
+    aspeed,min-rpm:
+      description:
+        define the minimal revolutions per minute of the measure fan
+        used to calculate the sample period of tach
+      default: 1000
+
+    aspeed,pulse-pr:
+      description:
+        Value specifying the number of pulses per revolution of the
+        monitored FAN.
+      default: 2
+
+    aspeed,tach-div:
+      description:
+        define the tachometer clock divider as an integer. Formula of
+        tach clock = clock source / (2^tach-div)^2
+      minimum: 0
+      maximum: 15
+      default: 5
+
+  required:
+    - reg
diff --git a/Documentation/devicetree/bindings/mfd/aspeed,ast2600-pwm-tach.yaml b/Documentation/devicetree/bindings/mfd/aspeed,ast2600-pwm-tach.yaml
new file mode 100644
index 000000000000..1eaf6fab2752
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/aspeed,ast2600-pwm-tach.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2021 Aspeed, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/aspeed,ast2600-pwm-tach.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PWM Tach controller Device Tree Bindings
+
+description: |
+  The PWM Tach controller is represented as a multi-function device which
+  includes:
+    PWM
+    Tach
+
+maintainers:
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - aspeed,ast2600-pwm-tach
+      - const: syscon
+      - const: simple-mfd
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+
+patternProperties:
+  "^pwm(@[0-9a-f]+)?$":
+    $ref: ../pwm/aspeed,ast2600-pwm.yaml
+
+  "^tach(@[0-9a-f]+)?$":
+    $ref: ../hwmon/aspeed,ast2600-tach.yaml
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/ast2600-clock.h>
+    pwm_tach: pwm_tach at 1e610000 {
+      compatible = "aspeed,ast2600-pwm-tach", "syscon", "simple-mfd";
+      reg = <0x1e610000 0x100>;
+      clocks = <&syscon ASPEED_CLK_AHB>;
+      resets = <&syscon ASPEED_RESET_PWM>;
+
+      pwm: pwm {
+        compatible = "aspeed,ast2600-pwm";
+        #address-cells = <1>;
+        #size-cells = <0>;
+        #pwm-cells = <3>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_pwm0_default>;
+      };
+
+      tach: tach {
+        compatible = "aspeed,ast2600-tach";
+        #address-cells = <1>;
+        #size-cells = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_tach0_default>;
+      };
+    };
diff --git a/Documentation/devicetree/bindings/pwm/aspeed,ast2600-pwm.yaml b/Documentation/devicetree/bindings/pwm/aspeed,ast2600-pwm.yaml
new file mode 100644
index 000000000000..f501f8a769df
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/aspeed,ast2600-pwm.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2021 Aspeed, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/aspeed,ast2600-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed Ast2600 PWM controller
+
+maintainers:
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+description: |
+  The Aspeed PWM controller can support upto 16 PWM outputs.
+  This module is part of the ast2600-pwm-tach multi-function device. For more
+  details see ../mfd/aspeed,ast2600-pwm-tach.yaml.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2600-pwm
+
+  "#pwm-cells":
+    const: 3
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  pinctrl-0: true
+
+  pinctrl-names:
+    const: default
+
+required:
+  - compatible
+  - "#pwm-cells"
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties:
+  description: Set extend properties for each pwm channel.
+  type: object
+  properties:
+    reg:
+      description:
+        The pwm channel index.
+      maxItems: 1
+
+    aspeed,wdt-reload-enable:
+      type: boolean
+      description:
+        Enable the function of wdt reset reload duty point.
+
+    aspeed,wdt-reload-duty-point:
+      description:
+        Define the duty point after wdt reset, 0 = 100%
+      minimum: 0
+      maximum: 255
+
+  required:
+    - reg
-- 
2.25.1



From billy_tsai at aspeedtech.com  Wed Aug 11 21:09:42 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Thu, 12 Aug 2021 12:09:42 +0800
Subject: [v11 2/2] pwm: Add Aspeed ast2600 PWM support
In-Reply-To: <20210812040942.5365-1-billy_tsai@aspeedtech.com>
References: <20210812040942.5365-1-billy_tsai@aspeedtech.com>
Message-ID: <20210812040942.5365-3-billy_tsai@aspeedtech.com>

This patch add the support of PWM controller which can be found at aspeed
ast2600 soc. The pwm supoorts up to 16 channels and it's part function
of multi-function device "pwm-tach controller".

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/pwm/Kconfig              |  10 +
 drivers/pwm/Makefile             |   1 +
 drivers/pwm/pwm-aspeed-ast2600.c | 327 +++++++++++++++++++++++++++++++
 3 files changed, 338 insertions(+)
 create mode 100644 drivers/pwm/pwm-aspeed-ast2600.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 63be5362fd3a..b0d26f6c2a8f 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -51,6 +51,16 @@ config PWM_AB8500
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-ab8500.
 
+config PWM_ASPEED_AST2600
+	tristate "Aspeed ast2600 PWM support"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	depends on HAVE_CLK && HAS_IOMEM
+	help
+	  This driver provides support for Aspeed ast2600 PWM controllers.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-aspeed-ast2600.
+
 config PWM_ATMEL
 	tristate "Atmel PWM support"
 	depends on OF
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index cbdcd55d69ee..ada454f9129a 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PWM)		+= core.o
 obj-$(CONFIG_PWM_SYSFS)		+= sysfs.o
 obj-$(CONFIG_PWM_AB8500)	+= pwm-ab8500.o
+obj-$(CONFIG_PWM_ASPEED_AST2600)	+= pwm-aspeed-ast2600.o
 obj-$(CONFIG_PWM_ATMEL)		+= pwm-atmel.o
 obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)	+= pwm-atmel-hlcdc.o
 obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
diff --git a/drivers/pwm/pwm-aspeed-ast2600.c b/drivers/pwm/pwm-aspeed-ast2600.c
new file mode 100644
index 000000000000..f89ce1d4cd67
--- /dev/null
+++ b/drivers/pwm/pwm-aspeed-ast2600.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 Aspeed Technology Inc.
+ *
+ * PWM controller driver for Aspeed ast2600 SoCs.
+ * This drivers doesn't support earlier version of the IP.
+ *
+ * The formula of pwm period duration:
+ * period duration = ((DIV_L + 1) * (PERIOD + 1) << DIV_H) / input-clk
+ *
+ * The formula of pwm duty cycle duration:
+ * duty cycle duration = period duration * DUTY_CYCLE_FALLING_POINT / (PERIOD + 1)
+ * = ((DIV_L + 1) * DUTY_CYCLE_FALLING_POINT << DIV_H) / input-clk
+ *
+ * The software driver fixes the period to 255, which causes the high-frequency
+ * precision of the PWM to be coarse, in exchange for the fineness of the duty cycle.
+ *
+ * Register usage:
+ * PIN_ENABLE: When it is unset the pwm controller will emit inactive level to the extern.
+ * Use to determine whether the PWM channel is enabled or disabled
+ * CLK_ENABLE: When it is unset the pwm controller will assert the duty counter reset and
+ * emit inactive level to the PIN_ENABLE mux after that the driver can still change the pwm period
+ * and duty and the value will apply when CLK_ENABLE be set again.
+ * Use to determine whether duty_cycle bigger than 0.
+ * PWM_ASPEED_CTRL_INVERSE: When it is toggled the output value will inverse immediately.
+ * PWM_ASPEED_DUTY_CYCLE_FALLING_POINT/PWM_ASPEED_DUTY_CYCLE_RISING_POINT: When these two
+ * values are equal it means the duty cycle = 100%.
+ *
+ * The glitch may generate at:
+ * - Enabled changing when the duty_cycle bigger than 0% and less than 100%.
+ * - Polarity changing when the duty_cycle bigger than 0% and less than 100%.
+ * - Set duty cycle to 0% from other values.
+ *
+ * Limitations:
+ * - When changing both duty cycle and period, we cannot prevent in
+ *   software that the output might produce a period with mixed
+ *   settings.
+ * - Disabling the PWM doesn't complete the current period.
+ *
+ * Improvements:
+ * - When only changing one of duty cycle or period, our pwm controller will not
+ *   generate the glitch, the configure will change at next cycle of pwm.
+ *   This improvement can disable/enable through PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE.
+ */
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+#include <linux/reset.h>
+#include <linux/regmap.h>
+#include <linux/bitfield.h>
+#include <linux/slab.h>
+#include <linux/pwm.h>
+#include <linux/math64.h>
+
+/* The channel number of Aspeed pwm controller */
+#define PWM_ASPEED_NR_PWMS 16
+
+/* PWM Control Register */
+#define PWM_ASPEED_CTRL(ch) ((ch) * 0x10 + 0x00)
+#define PWM_ASPEED_CTRL_LOAD_SEL_RISING_AS_WDT BIT(19)
+#define PWM_ASPEED_CTRL_DUTY_LOAD_AS_WDT_ENABLE BIT(18)
+#define PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE BIT(17)
+#define PWM_ASPEED_CTRL_CLK_ENABLE BIT(16)
+#define PWM_ASPEED_CTRL_LEVEL_OUTPUT BIT(15)
+#define PWM_ASPEED_CTRL_INVERSE BIT(14)
+#define PWM_ASPEED_CTRL_OPEN_DRAIN_ENABLE BIT(13)
+#define PWM_ASPEED_CTRL_PIN_ENABLE BIT(12)
+#define PWM_ASPEED_CTRL_CLK_DIV_H GENMASK(11, 8)
+#define PWM_ASPEED_CTRL_CLK_DIV_L GENMASK(7, 0)
+
+/* PWM Duty Cycle Register */
+#define PWM_ASPEED_DUTY_CYCLE(ch) ((ch) * 0x10 + 0x04)
+#define PWM_ASPEED_DUTY_CYCLE_PERIOD GENMASK(31, 24)
+#define PWM_ASPEED_DUTY_CYCLE_POINT_AS_WDT GENMASK(23, 16)
+#define PWM_ASPEED_DUTY_CYCLE_FALLING_POINT GENMASK(15, 8)
+#define PWM_ASPEED_DUTY_CYCLE_RISING_POINT GENMASK(7, 0)
+
+/* PWM fixed value */
+#define PWM_ASPEED_FIXED_PERIOD FIELD_MAX(PWM_ASPEED_DUTY_CYCLE_PERIOD)
+
+struct aspeed_pwm_data {
+	struct pwm_chip chip;
+	struct clk *clk;
+	struct regmap *regmap;
+	struct reset_control *reset;
+};
+
+static inline struct aspeed_pwm_data *
+aspeed_pwm_chip_to_data(struct pwm_chip *chip)
+{
+	return container_of(chip, struct aspeed_pwm_data, chip);
+}
+
+static void aspeed_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+				 struct pwm_state *state)
+{
+	struct device *dev = chip->dev;
+	struct aspeed_pwm_data *priv = aspeed_pwm_chip_to_data(chip);
+	u32 hwpwm = pwm->hwpwm;
+	bool polarity,	pin_en, clk_en;
+	u32 duty_pt, val;
+	unsigned long rate;
+	u64 div_h, div_l, duty_cycle_period, dividend;
+
+	regmap_read(priv->regmap, PWM_ASPEED_CTRL(hwpwm), &val);
+	polarity = FIELD_GET(PWM_ASPEED_CTRL_INVERSE, val);
+	pin_en = FIELD_GET(PWM_ASPEED_CTRL_PIN_ENABLE, val);
+	clk_en = FIELD_GET(PWM_ASPEED_CTRL_CLK_ENABLE, val);
+	div_h = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_H, val);
+	div_l = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_L, val);
+	regmap_read(priv->regmap, PWM_ASPEED_DUTY_CYCLE(hwpwm), &val);
+	duty_pt = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, val);
+	duty_cycle_period = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_PERIOD, val);
+
+	rate = clk_get_rate(priv->clk);
+
+	/*
+	 * This multiplication doesn't overflow, the upper bound is
+	 * 1000000000 * 256 * 256 << 15 = 0x1dcd650000000000
+	 */
+	dividend = (u64)NSEC_PER_SEC * (div_l + 1) * (duty_cycle_period + 1)
+		       << div_h;
+	state->period = DIV_ROUND_UP_ULL(dividend, rate);
+
+	if (clk_en && duty_pt) {
+		dividend = (u64)NSEC_PER_SEC * (div_l + 1) * duty_pt
+				 << div_h;
+		state->duty_cycle = DIV_ROUND_UP_ULL(dividend, rate);
+	} else
+		state->duty_cycle = clk_en ? state->period : 0;
+	state->polarity = polarity ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
+	state->enabled = pin_en;
+	dev_dbg(dev, "get period: %lldns, duty_cycle: %lldns", state->period,
+		state->duty_cycle);
+}
+
+static int aspeed_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			    const struct pwm_state *state)
+{
+	struct device *dev = chip->dev;
+	struct aspeed_pwm_data *priv = aspeed_pwm_chip_to_data(chip);
+	u32 hwpwm = pwm->hwpwm, duty_pt;
+	unsigned long rate;
+	u64 div_h, div_l, divisor;
+	bool clk_en;
+
+	dev_dbg(dev, "expect period: %lldns, duty_cycle: %lldns", state->period,
+		state->duty_cycle);
+
+	rate = clk_get_rate(priv->clk);
+	if (state->period > div64_u64(ULLONG_MAX, (u64)rate))
+		return -ERANGE;
+	/*
+	 * Pick the smallest value for div_h so that div_l can be the biggest
+	 * which results in a finer resolution near the target period value.
+	 */
+	divisor = (u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1) *
+		  (FIELD_MAX(PWM_ASPEED_CTRL_CLK_DIV_L) + 1);
+	div_h = order_base_2(DIV64_U64_ROUND_UP(rate * state->period, divisor));
+	if (div_h > 0xf)
+		div_h = 0xf;
+
+	divisor = ((u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1)) << div_h;
+	div_l = div64_u64(rate * state->period, divisor);
+
+	if (div_l == 0)
+		return -ERANGE;
+
+	div_l -= 1;
+
+	if (div_l > 255)
+		div_l = 255;
+
+	dev_dbg(dev, "clk source: %ld div_h %lld, div_l : %lld\n", rate, div_h,
+		div_l);
+	/* duty_pt = duty_cycle * (PERIOD + 1) / period */
+	duty_pt = div64_u64(state->duty_cycle * rate,
+			    (u64)NSEC_PER_SEC * (div_l + 1) << div_h);
+	dev_dbg(dev, "duty_cycle = %lld, duty_pt = %d\n", state->duty_cycle,
+		 duty_pt);
+
+	/*
+	 * Fixed DUTY_CYCLE_PERIOD to its max value to get a
+	 * fine-grained resolution for duty_cycle at the expense of a
+	 * coarser period resolution.
+	 */
+	regmap_update_bits(priv->regmap, PWM_ASPEED_DUTY_CYCLE(hwpwm),
+			   PWM_ASPEED_DUTY_CYCLE_PERIOD,
+			   FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_PERIOD,
+				      PWM_ASPEED_FIXED_PERIOD));
+	if (duty_pt == 0)
+		/* emit inactive level and assert the duty counter reset */
+		clk_en = 0;
+	else {
+		clk_en = 1;
+		if (duty_pt >= (PWM_ASPEED_FIXED_PERIOD + 1))
+			duty_pt = 0;
+		regmap_update_bits(
+			priv->regmap, PWM_ASPEED_DUTY_CYCLE(hwpwm),
+			PWM_ASPEED_DUTY_CYCLE_RISING_POINT |
+				PWM_ASPEED_DUTY_CYCLE_FALLING_POINT,
+			FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT,
+				   duty_pt));
+	}
+
+	regmap_update_bits(
+		priv->regmap, PWM_ASPEED_CTRL(hwpwm),
+		PWM_ASPEED_CTRL_CLK_DIV_H | PWM_ASPEED_CTRL_CLK_DIV_L |
+			PWM_ASPEED_CTRL_PIN_ENABLE |
+			PWM_ASPEED_CTRL_CLK_ENABLE | PWM_ASPEED_CTRL_INVERSE,
+		FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_H, div_h) |
+			FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_L, div_l) |
+			FIELD_PREP(PWM_ASPEED_CTRL_PIN_ENABLE, state->enabled) |
+			FIELD_PREP(PWM_ASPEED_CTRL_CLK_ENABLE, clk_en) |
+			FIELD_PREP(PWM_ASPEED_CTRL_INVERSE, state->polarity));
+	return 0;
+}
+
+static const struct pwm_ops aspeed_pwm_ops = {
+	.apply = aspeed_pwm_apply,
+	.get_state = aspeed_pwm_get_state,
+	.owner = THIS_MODULE,
+};
+
+static int aspeed_pwm_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret;
+	struct aspeed_pwm_data *priv;
+	struct device_node *np;
+	struct platform_device *parent_dev;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	np = pdev->dev.parent->of_node;
+	if (!of_device_is_compatible(np, "aspeed,ast2600-pwm-tach"))
+		return dev_err_probe(dev, -ENODEV,
+				     "Unsupported pwm device binding\n");
+
+	priv->regmap = syscon_node_to_regmap(np);
+	if (IS_ERR(priv->regmap))
+		return dev_err_probe(dev, PTR_ERR(priv->regmap),
+				     "Couldn't get regmap\n");
+
+	parent_dev = of_find_device_by_node(np);
+	priv->clk = devm_clk_get(&parent_dev->dev, 0);
+	if (IS_ERR(priv->clk))
+		return dev_err_probe(dev, PTR_ERR(priv->clk),
+				     "Couldn't get clock\n");
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		return dev_err_probe(dev, ret, "Couldn't enable clock\n");
+
+	priv->reset = devm_reset_control_get_shared(&parent_dev->dev, NULL);
+	if (IS_ERR(priv->reset)) {
+		ret = dev_err_probe(dev, PTR_ERR(priv->reset),
+				    "Get reset failed\n");
+		goto err_disable_clk;
+	}
+	ret = reset_control_deassert(priv->reset);
+	if (ret) {
+		dev_err_probe(dev, ret, "Couldn't deassert reset control\n");
+		goto err_disable_clk;
+	}
+
+	priv->chip.dev = dev;
+	priv->chip.ops = &aspeed_pwm_ops;
+	priv->chip.npwm = PWM_ASPEED_NR_PWMS;
+
+	ret = pwmchip_add(&priv->chip);
+	if (ret < 0) {
+		dev_err_probe(dev, ret, "Failed to add PWM chip\n");
+		goto err_assert_reset;
+	}
+	dev_set_drvdata(dev, priv);
+	return 0;
+err_assert_reset:
+	reset_control_assert(priv->reset);
+err_disable_clk:
+	clk_disable_unprepare(priv->clk);
+	return ret;
+}
+
+static int aspeed_pwm_remove(struct platform_device *dev)
+{
+	struct aspeed_pwm_data *priv = platform_get_drvdata(dev);
+
+	pwmchip_remove(&priv->chip);
+	reset_control_assert(priv->reset);
+	clk_disable_unprepare(priv->clk);
+
+	return 0;
+}
+
+static const struct of_device_id of_pwm_match_table[] = {
+	{
+		.compatible = "aspeed,ast2600-pwm",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_pwm_match_table);
+
+static struct platform_driver aspeed_pwm_driver = {
+	.probe = aspeed_pwm_probe,
+	.remove	= aspeed_pwm_remove,
+	.driver	= {
+		.name = "aspeed-pwm",
+		.of_match_table = of_pwm_match_table,
+	},
+};
+
+module_platform_driver(aspeed_pwm_driver);
+
+MODULE_AUTHOR("Billy Tsai <billy_tsai at aspeedtech.com>");
+MODULE_DESCRIPTION("Aspeed ast2600 PWM device driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From billy_tsai at aspeedtech.com  Wed Aug 11 21:14:23 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Thu, 12 Aug 2021 04:14:23 +0000
Subject: [v10 2/2] pwm: Add Aspeed ast2600 PWM support
In-Reply-To: <20210716031412.19258-3-billy_tsai@aspeedtech.com>
References: <20210716031412.19258-1-billy_tsai@aspeedtech.com>
 <20210716031412.19258-3-billy_tsai@aspeedtech.com>
Message-ID: <08A89C49-0625-49DF-A0FC-1AC6AA6307D4@aspeedtech.com>

I have sent the v11 patch. Suspend this one.

Best Regards,
Billy Tsai

?On 2021/7/16, 11:14 AM, "Billy Tsai" <billy_tsai at aspeedtech.com> wrote:

    This patch add the support of PWM controller which can be found at aspeed
    ast2600 soc. The pwm supoorts up to 16 channels and it's part function
    of multi-function device "pwm-tach controller".

    Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
    ---
     drivers/pwm/Kconfig              |  10 +
     drivers/pwm/Makefile             |   1 +
     drivers/pwm/pwm-aspeed-ast2600.c | 322 +++++++++++++++++++++++++++++++
     3 files changed, 333 insertions(+)
     create mode 100644 drivers/pwm/pwm-aspeed-ast2600.c

    diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
    index 63be5362fd3a..b0d26f6c2a8f 100644
    --- a/drivers/pwm/Kconfig
    +++ b/drivers/pwm/Kconfig
    @@ -51,6 +51,16 @@ config PWM_AB8500
     	  To compile this driver as a module, choose M here: the module
     	  will be called pwm-ab8500.

    +config PWM_ASPEED_AST2600
    +	tristate "Aspeed ast2600 PWM support"
    +	depends on ARCH_ASPEED || COMPILE_TEST
    +	depends on HAVE_CLK && HAS_IOMEM
    +	help
    +	  This driver provides support for Aspeed ast2600 PWM controllers.
    +
    +	  To compile this driver as a module, choose M here: the module
    +	  will be called pwm-aspeed-ast2600.
    +
     config PWM_ATMEL
     	tristate "Atmel PWM support"
     	depends on OF
    diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
    index cbdcd55d69ee..ada454f9129a 100644
    --- a/drivers/pwm/Makefile
    +++ b/drivers/pwm/Makefile
    @@ -2,6 +2,7 @@
     obj-$(CONFIG_PWM)		+= core.o
     obj-$(CONFIG_PWM_SYSFS)		+= sysfs.o
     obj-$(CONFIG_PWM_AB8500)	+= pwm-ab8500.o
    +obj-$(CONFIG_PWM_ASPEED_AST2600)	+= pwm-aspeed-ast2600.o
     obj-$(CONFIG_PWM_ATMEL)		+= pwm-atmel.o
     obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)	+= pwm-atmel-hlcdc.o
     obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
    diff --git a/drivers/pwm/pwm-aspeed-ast2600.c b/drivers/pwm/pwm-aspeed-ast2600.c
    new file mode 100644
    index 000000000000..8758ce7432eb
    --- /dev/null
    +++ b/drivers/pwm/pwm-aspeed-ast2600.c
    @@ -0,0 +1,322 @@
    +// SPDX-License-Identifier: GPL-2.0-or-later
    +/*
    + * Copyright (C) 2021 Aspeed Technology Inc.
    + *
    + * PWM controller driver for Aspeed ast2600 SoCs.
    + * This drivers doesn't support earlier version of the IP.
    + *
    + * The formula of pwm period duration:
    + * period duration = ((DIV_L + 1) * (PERIOD + 1) << DIV_H) / input-clk
    + *
    + * The formula of pwm duty cycle duration:
    + * duty cycle duration = period duration * DUTY_CYCLE_FALLING_POINT / (PERIOD + 1)
    + * = ((DIV_L + 1) * DUTY_CYCLE_FALLING_POINT << DIV_H) / input-clk
    + *
    + * The software driver fixes the period to 255, which causes the high-frequency
    + * precision of the PWM to be coarse, in exchange for the fineness of the duty cycle.
    + *
    + * Register usage:
    + * PIN_ENABLE: When it is unset the pwm controller will always output low to the extern.
    + * Use to determine whether the PWM channel is enabled or disabled
    + * CLK_ENABLE: When it is unset the pwm controller will reset the duty counter to 0 and
    + * output low to the PIN_ENABLE mux after that the driver can still change the pwm period
    + * and duty and the value will apply when CLK_ENABLE be set again.
    + * Use to determine whether duty_cycle bigger than 0.
    + * PWM_ASPEED_CTRL_INVERSE: When it is toggled the output value will inverse immediately.
    + * PWM_ASPEED_DUTY_CYCLE_FALLING_POINT/PWM_ASPEED_DUTY_CYCLE_RISING_POINT: When these two
    + * values are equal it means the duty cycle = 100%.
    + *
    + * Limitations:
    + * - When changing both duty cycle and period, we cannot prevent in
    + *   software that the output might produce a period with mixed
    + *   settings.
    + * - Disabling the PWM doesn't complete the current period.
    + *
    + * Improvements:
    + * - When only changing one of duty cycle or period, our pwm controller will not
    + *   generate the glitch, the configure will change at next cycle of pwm.
    + *   This improvement can disable/enable through PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE.
    + */
    +
    +#include <linux/clk.h>
    +#include <linux/errno.h>
    +#include <linux/io.h>
    +#include <linux/kernel.h>
    +#include <linux/mfd/syscon.h>
    +#include <linux/module.h>
    +#include <linux/of_platform.h>
    +#include <linux/of_device.h>
    +#include <linux/platform_device.h>
    +#include <linux/sysfs.h>
    +#include <linux/reset.h>
    +#include <linux/regmap.h>
    +#include <linux/bitfield.h>
    +#include <linux/slab.h>
    +#include <linux/pwm.h>
    +#include <linux/math64.h>
    +
    +/* The channel number of Aspeed pwm controller */
    +#define PWM_ASPEED_NR_PWMS 16
    +
    +/* PWM Control Register */
    +#define PWM_ASPEED_CTRL(ch) ((ch) * 0x10 + 0x00)
    +#define PWM_ASPEED_CTRL_LOAD_SEL_RISING_AS_WDT BIT(19)
    +#define PWM_ASPEED_CTRL_DUTY_LOAD_AS_WDT_ENABLE BIT(18)
    +#define PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE BIT(17)
    +#define PWM_ASPEED_CTRL_CLK_ENABLE BIT(16)
    +#define PWM_ASPEED_CTRL_LEVEL_OUTPUT BIT(15)
    +#define PWM_ASPEED_CTRL_INVERSE BIT(14)
    +#define PWM_ASPEED_CTRL_OPEN_DRAIN_ENABLE BIT(13)
    +#define PWM_ASPEED_CTRL_PIN_ENABLE BIT(12)
    +#define PWM_ASPEED_CTRL_CLK_DIV_H GENMASK(11, 8)
    +#define PWM_ASPEED_CTRL_CLK_DIV_L GENMASK(7, 0)
    +
    +/* PWM Duty Cycle Register */
    +#define PWM_ASPEED_DUTY_CYCLE(ch) ((ch) * 0x10 + 0x04)
    +#define PWM_ASPEED_DUTY_CYCLE_PERIOD GENMASK(31, 24)
    +#define PWM_ASPEED_DUTY_CYCLE_POINT_AS_WDT GENMASK(23, 16)
    +#define PWM_ASPEED_DUTY_CYCLE_FALLING_POINT GENMASK(15, 8)
    +#define PWM_ASPEED_DUTY_CYCLE_RISING_POINT GENMASK(7, 0)
    +
    +/* PWM fixed value */
    +#define PWM_ASPEED_FIXED_PERIOD FIELD_MAX(PWM_ASPEED_DUTY_CYCLE_PERIOD)
    +
    +struct aspeed_pwm_data {
    +	struct pwm_chip chip;
    +	struct clk *clk;
    +	struct regmap *regmap;
    +	struct reset_control *reset;
    +};
    +
    +static inline struct aspeed_pwm_data *
    +aspeed_pwm_chip_to_data(struct pwm_chip *chip)
    +{
    +	return container_of(chip, struct aspeed_pwm_data, chip);
    +}
    +
    +static void aspeed_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
    +				 struct pwm_state *state)
    +{
    +	struct device *dev = chip->dev;
    +	struct aspeed_pwm_data *priv = aspeed_pwm_chip_to_data(chip);
    +	u32 index = pwm->hwpwm;
    +	bool polarity,	pin_en, clk_en;
    +	u32 duty_pt, val;
    +	unsigned long rate;
    +	u64 div_h, div_l, duty_cycle_period, dividend;
    +
    +	regmap_read(priv->regmap, PWM_ASPEED_CTRL(index), &val);
    +	polarity = FIELD_GET(PWM_ASPEED_CTRL_INVERSE, val);
    +	pin_en = FIELD_GET(PWM_ASPEED_CTRL_PIN_ENABLE, val);
    +	clk_en = FIELD_GET(PWM_ASPEED_CTRL_CLK_ENABLE, val);
    +	div_h = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_H, val);
    +	div_l = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_L, val);
    +	regmap_read(priv->regmap, PWM_ASPEED_DUTY_CYCLE(index), &val);
    +	duty_pt = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, val);
    +	duty_cycle_period = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_PERIOD, val);
    +
    +	rate = clk_get_rate(priv->clk);
    +
    +	/*
    +	 * This multiplication doesn't overflow, the upper bound is
    +	 * 1000000000 * 256 * 256 << 15 = 0x1dcd650000000000
    +	 */
    +	dividend = (u64)NSEC_PER_SEC * (div_l + 1) * (duty_cycle_period + 1)
    +		       << div_h;
    +	state->period = DIV_ROUND_UP_ULL(dividend, rate);
    +
    +	if (clk_en && duty_pt) {
    +		dividend = (u64)NSEC_PER_SEC * (div_l + 1) * duty_pt
    +				 << div_h;
    +		state->duty_cycle = DIV_ROUND_UP_ULL(dividend, rate);
    +	} else
    +		state->duty_cycle = clk_en ? state->period : 0;
    +	state->polarity = polarity ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
    +	state->enabled = pin_en;
    +	dev_dbg(dev, "get period: %lldns, duty_cycle: %lldns", state->period,
    +		state->duty_cycle);
    +}
    +
    +static int aspeed_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
    +			    const struct pwm_state *state)
    +{
    +	struct device *dev = chip->dev;
    +	struct aspeed_pwm_data *priv = aspeed_pwm_chip_to_data(chip);
    +	u32 hwpwm = pwm->hwpwm, duty_pt;
    +	unsigned long rate;
    +	u64 div_h, div_l, divisor;
    +	bool clk_en;
    +
    +	dev_dbg(dev, "expect period: %lldns, duty_cycle: %lldns", state->period,
    +		state->duty_cycle);
    +
    +	rate = clk_get_rate(priv->clk);
    +	if (state->period > div64_u64(ULLONG_MAX, (u64)rate))
    +		return -ERANGE;
    +	/*
    +	 * Pick the smallest value for div_h so that div_l can be the biggest
    +	 * which results in a finer resolution near the target period value.
    +	 */
    +	divisor = (u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1) *
    +		  (FIELD_MAX(PWM_ASPEED_CTRL_CLK_DIV_L) + 1);
    +	div_h = order_base_2(DIV64_U64_ROUND_UP(rate * state->period, divisor));
    +	if (div_h > 0xf)
    +		div_h = 0xf;
    +
    +	divisor = ((u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1)) << div_h;
    +	div_l = div64_u64(rate * state->period, divisor);
    +
    +	if (div_l == 0)
    +		return -ERANGE;
    +
    +	div_l -= 1;
    +
    +	if (div_l > 255)
    +		div_l = 255;
    +
    +	dev_dbg(dev, "clk source: %ld div_h %lld, div_l : %lld\n", rate, div_h,
    +		div_l);
    +	/* duty_pt = duty_cycle * (PERIOD + 1) / period */
    +	duty_pt = div64_u64(state->duty_cycle * rate,
    +			    (u64)NSEC_PER_SEC * (div_l + 1) << div_h);
    +	dev_dbg(dev, "duty_cycle = %lld, duty_pt = %d\n", state->duty_cycle,
    +		 duty_pt);
    +
    +	regmap_update_bits(priv->regmap, PWM_ASPEED_CTRL(hwpwm),
    +			   PWM_ASPEED_CTRL_PIN_ENABLE,
    +			   state->enabled ? PWM_ASPEED_CTRL_PIN_ENABLE : 0);
    +
    +	if (duty_pt == 0)
    +		clk_en = 0;
    +	else {
    +		clk_en = 1;
    +		if (duty_pt >= (PWM_ASPEED_FIXED_PERIOD + 1))
    +			duty_pt = 0;
    +		/*
    +		 * Fixed DUTY_CYCLE_PERIOD to its max value to get a
    +		 * fine-grained resolution for duty_cycle at the expense of a
    +		 * coarser period resolution.
    +		 */
    +		regmap_update_bits(
    +			priv->regmap, PWM_ASPEED_DUTY_CYCLE(hwpwm),
    +			PWM_ASPEED_DUTY_CYCLE_PERIOD |
    +				PWM_ASPEED_DUTY_CYCLE_RISING_POINT |
    +				PWM_ASPEED_DUTY_CYCLE_FALLING_POINT,
    +			FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_PERIOD,
    +				   PWM_ASPEED_FIXED_PERIOD) |
    +				FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT,
    +					   duty_pt));
    +	}
    +
    +	regmap_update_bits(
    +		priv->regmap, PWM_ASPEED_CTRL(hwpwm),
    +		PWM_ASPEED_CTRL_CLK_DIV_H | PWM_ASPEED_CTRL_CLK_DIV_L |
    +			PWM_ASPEED_CTRL_CLK_ENABLE | PWM_ASPEED_CTRL_INVERSE,
    +		FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_H, div_h) |
    +			FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_L, div_l) |
    +			FIELD_PREP(PWM_ASPEED_CTRL_CLK_ENABLE, clk_en) |
    +			FIELD_PREP(PWM_ASPEED_CTRL_INVERSE, state->polarity));
    +	return 0;
    +}
    +
    +static const struct pwm_ops aspeed_pwm_ops = {
    +	.apply = aspeed_pwm_apply,
    +	.get_state = aspeed_pwm_get_state,
    +	.owner = THIS_MODULE,
    +};
    +
    +static int aspeed_pwm_probe(struct platform_device *pdev)
    +{
    +	struct device *dev = &pdev->dev;
    +	int ret;
    +	struct aspeed_pwm_data *priv;
    +	struct device_node *np;
    +	struct platform_device *parent_dev;
    +
    +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    +	if (!priv)
    +		return -ENOMEM;
    +
    +	np = pdev->dev.parent->of_node;
    +	if (!of_device_is_compatible(np, "aspeed,ast2600-pwm-tach"))
    +		return dev_err_probe(dev, -ENODEV,
    +				     "Unsupported pwm device binding\n");
    +
    +	priv->regmap = syscon_node_to_regmap(np);
    +	if (IS_ERR(priv->regmap))
    +		return dev_err_probe(dev, PTR_ERR(priv->regmap),
    +				     "Couldn't get regmap\n");
    +
    +	parent_dev = of_find_device_by_node(np);
    +	priv->clk = devm_clk_get(&parent_dev->dev, 0);
    +	if (IS_ERR(priv->clk))
    +		return dev_err_probe(dev, PTR_ERR(priv->clk),
    +				     "Couldn't get clock\n");
    +
    +	ret = clk_prepare_enable(priv->clk);
    +	if (ret)
    +		return dev_err_probe(dev, ret, "Couldn't enable clock\n");
    +
    +	priv->reset = devm_reset_control_get_shared(&parent_dev->dev, NULL);
    +	if (IS_ERR(priv->reset)) {
    +		ret = dev_err_probe(dev, PTR_ERR(priv->reset),
    +				    "Get reset failed\n");
    +		goto err_disable_clk;
    +	}
    +	ret = reset_control_deassert(priv->reset);
    +	if (ret) {
    +		dev_err_probe(dev, ret, "Couldn't deassert reset control\n");
    +		goto err_disable_clk;
    +	}
    +
    +	priv->chip.dev = dev;
    +	priv->chip.ops = &aspeed_pwm_ops;
    +	priv->chip.npwm = PWM_ASPEED_NR_PWMS;
    +
    +	ret = pwmchip_add(&priv->chip);
    +	if (ret < 0) {
    +		dev_err_probe(dev, ret, "Failed to add PWM chip\n");
    +		goto err_assert_reset;
    +	}
    +	dev_set_drvdata(dev, priv);
    +	return 0;
    +err_assert_reset:
    +	reset_control_assert(priv->reset);
    +err_disable_clk:
    +	clk_disable_unprepare(priv->clk);
    +	return ret;
    +}
    +
    +static int aspeed_pwm_remove(struct platform_device *dev)
    +{
    +	struct aspeed_pwm_data *priv = platform_get_drvdata(dev);
    +
    +	pwmchip_remove(&priv->chip);
    +	reset_control_assert(priv->reset);
    +	clk_disable_unprepare(priv->clk);
    +
    +	return 0;
    +}
    +
    +static const struct of_device_id of_pwm_match_table[] = {
    +	{
    +		.compatible = "aspeed,ast2600-pwm",
    +	},
    +	{},
    +};
    +MODULE_DEVICE_TABLE(of, of_pwm_match_table);
    +
    +static struct platform_driver aspeed_pwm_driver = {
    +	.probe = aspeed_pwm_probe,
    +	.remove	= aspeed_pwm_remove,
    +	.driver	= {
    +		.name = "aspeed-pwm",
    +		.of_match_table = of_pwm_match_table,
    +	},
    +};
    +
    +module_platform_driver(aspeed_pwm_driver);
    +
    +MODULE_AUTHOR("Billy Tsai <billy_tsai at aspeedtech.com>");
    +MODULE_DESCRIPTION("Aspeed ast2600 PWM device driver");
    +MODULE_LICENSE("GPL v2");
    -- 
    2.25.1



From viresh.kumar at linaro.org  Wed Aug 11 21:22:04 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Aug 2021 09:52:04 +0530
Subject: [PATCH V2 9/9] cpufreq: scmi: Use .register_em() callback
In-Reply-To: <143a03df-d858-b2de-a2cc-983c35d71e53@arm.com>
References: <cover.1628682874.git.viresh.kumar@linaro.org>
 <6094d891b4cb0cba3357e2894c8a4431c4c65e67.1628682874.git.viresh.kumar@linaro.org>
 <143a03df-d858-b2de-a2cc-983c35d71e53@arm.com>
Message-ID: <20210812042204.lxugyjxa2cyz45ib@vireshk-i7>

On 11-08-21, 17:32, Lukasz Luba wrote:
> 
> 
> On 8/11/21 12:58 PM, Viresh Kumar wrote:
> > Set the newly added .register_em() callback to register with the EM
> > after the cpufreq policy is properly initialized.
> > 
> > Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> > ---
> >   drivers/cpufreq/scmi-cpufreq.c | 55 ++++++++++++++++++++--------------
> >   1 file changed, 32 insertions(+), 23 deletions(-)
> 
> > +static void scmi_cpufreq_register_em(struct cpufreq_policy *policy)
> > +{
> > +	struct em_data_callback em_cb = EM_DATA_CB(scmi_get_cpu_power);
> > +	bool power_scale_mw = perf_ops->power_scale_mw_get(ph);
> > +	struct scmi_data *priv = policy->driver_data;
> > +
> > +	em_dev_register_perf_domain(get_cpu_device(policy->cpu), priv->nr_opp,
> > +				    &em_cb, priv->opp_shared_cpus,
> > +				    power_scale_mw);
> 
> I would free the priv->opp_shared_cpus mask here, since we don't
> need it anymore and memory can be reclaimed.

Yes, we don't need it anymore, but this isn't a good place to undo
what init() has done. Moreover, it is possible that register_em() may
not get called at all, if some error has occurred after init() has
successfully returned. It is always better to use exit() for such
things. It won't hurt a lot to keep this around anyway.

> Don't forget this
> setup would be called N CPUs times, on this per-CPU policy platform.

Yes, but EM will just ignore this call. Though I have made a change
here now to check for non-zero nr_opp to avoid the unnecessary call.

> If freed here, then also there wouldn't be a need to free it in
> scmi_cpufreq_exit() so you can remove it from there.

-- 
viresh


From a-govindraju at ti.com  Wed Aug 11 21:27:21 2021
From: a-govindraju at ti.com (Aswath Govindraju)
Date: Thu, 12 Aug 2021 09:57:21 +0530
Subject: [PATCH] ARM: dts: vf610-zii-dev-rev-b: Remove #address-cells and
 #size-cells property from at93c46d dt node
In-Reply-To: <YRQhqHEl8wu2KZz+@lunn.ch>
References: <20210810064420.9489-1-a-govindraju@ti.com>
 <YRQhqHEl8wu2KZz+@lunn.ch>
Message-ID: <1cd133b5-5242-3394-5dc8-50a641dabf3a@ti.com>

Hi Andrew,

On 12/08/21 12:44 am, Andrew Lunn wrote:
> On Tue, Aug 10, 2021 at 12:14:20PM +0530, Aswath Govindraju wrote:
> Hi Aswath
> 
> You did not put a To: in the email, so it is unclear which maintainer
> you expect to pickup this patch.
> 

Thank you for pointing it out and the review.

>From the MAINTAINERS documentation I see that Shawn Guo, and Sascha
Hauer are the maintainers for this file.

Thanks,
Aswath

>> Remove #address-cells and #size-cells property from at93c46d device tree
>> node as it does not have child nodes.
>>
>> Fixes: 1556063fde42 ("ARM: dts: vf610-zii-dev: Add ZII development board.")
>> Signed-off-by: Aswath Govindraju <a-govindraju at ti.com>
> 
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>
> 
>     Andrew
> 



From lkp at intel.com  Wed Aug 11 21:27:20 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 12:27:20 +0800
Subject: [xlnx:xlnx_rebase_v5.10 961/1760]
 drivers/irqchip/irq-xilinx-intc.c:175:10: error: implicit declaration of
 function 'handle_domain_irq'
Message-ID: <202108121213.rRvBL6hW-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   bf98c1493fb23bfd7e2678498b7e337ce2cd1d53
commit: ec26ada995b2cdeda14911845e1884150e099d5b [961/1760] irqchip: xilinx: Use handle_domain_irq()
config: s390-randconfig-r011-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/ec26ada995b2cdeda14911845e1884150e099d5b
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout ec26ada995b2cdeda14911845e1884150e099d5b
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:19:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x000000ffUL) << 24) |            \
                     ^
   In file included from drivers/irqchip/irq-xilinx-intc.c:13:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
                     ^
   In file included from drivers/irqchip/irq-xilinx-intc.c:13:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
                     ^
   In file included from drivers/irqchip/irq-xilinx-intc.c:13:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
                     ^
   In file included from drivers/irqchip/irq-xilinx-intc.c:13:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32'
           __fswab32(x))
                     ^
   In file included from drivers/irqchip/irq-xilinx-intc.c:13:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   drivers/irqchip/irq-xilinx-intc.c:173:17: error: no member named 'read_fn' in 'struct xintc_irq_chip'
                   hwirq = irqc->read_fn(irqc->base + IVR);
                           ~~~~  ^
>> drivers/irqchip/irq-xilinx-intc.c:175:10: error: implicit declaration of function 'handle_domain_irq' [-Werror,-Wimplicit-function-declaration]
                           ret = handle_domain_irq(irqc->root_domain, hwirq, regs);
                                 ^
   drivers/irqchip/irq-xilinx-intc.c:192:2: error: use of undeclared identifier 'ret'
           ret = of_property_read_u32(intc, "cpu-id", &cpu_id);
           ^
   drivers/irqchip/irq-xilinx-intc.c:193:6: error: use of undeclared identifier 'ret'
           if (ret < 0)
               ^
   drivers/irqchip/irq-xilinx-intc.c:213:2: error: use of undeclared identifier 'ret'
           ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &irqc->nr_irq);
           ^
   drivers/irqchip/irq-xilinx-intc.c:214:6: error: use of undeclared identifier 'ret'
           if (ret < 0) {
               ^
   drivers/irqchip/irq-xilinx-intc.c:219:2: error: use of undeclared identifier 'ret'
           ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &irqc->intr_mask);
           ^
   drivers/irqchip/irq-xilinx-intc.c:220:6: error: use of undeclared identifier 'ret'
           if (ret < 0) {
               ^
   drivers/irqchip/irq-xilinx-intc.c:252:3: error: use of undeclared identifier 'ret'
                   ret = -EINVAL;
                   ^
   drivers/irqchip/irq-xilinx-intc.c:257:3: error: use of undeclared identifier 'irq'; did you mean 'irqc'?
                   irq = irq_of_parse_and_map(intc, 0);
                   ^~~
                   irqc
   drivers/irqchip/irq-xilinx-intc.c:188:25: note: 'irqc' declared here
           struct xintc_irq_chip *irqc;
                                  ^
   drivers/irqchip/irq-xilinx-intc.c:257:7: warning: incompatible integer to pointer conversion assigning to 'struct xintc_irq_chip *' from 'unsigned int' [-Wint-conversion]
                   irq = irq_of_parse_and_map(intc, 0);
                       ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/irqchip/irq-xilinx-intc.c:258:7: error: use of undeclared identifier 'irq'; did you mean 'irqc'?
                   if (irq) {
                       ^~~
                       irqc
   drivers/irqchip/irq-xilinx-intc.c:188:25: note: 'irqc' declared here
           struct xintc_irq_chip *irqc;
                                  ^
   drivers/irqchip/irq-xilinx-intc.c:259:37: error: use of undeclared identifier 'irq'; did you mean 'irqc'?
                           irq_set_chained_handler_and_data(irq,
                                                            ^~~
                                                            irqc
   drivers/irqchip/irq-xilinx-intc.c:188:25: note: 'irqc' declared here
           struct xintc_irq_chip *irqc;
                                  ^
   drivers/irqchip/irq-xilinx-intc.c:264:4: error: use of undeclared identifier 'ret'
                           ret = -EINVAL;
                           ^
   drivers/irqchip/irq-xilinx-intc.c:278:9: error: use of undeclared identifier 'ret'
           return ret;
                  ^
   21 warnings and 14 errors generated.

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for MFD_SUN6I_PRCM
   Depends on HAS_IOMEM && (ARCH_SUNXI || COMPILE_TEST
   Selected by
   - CLK_SUNXI_PRCM_SUN6I && COMMON_CLK && CLK_SUNXI
   - CLK_SUNXI_PRCM_SUN8I && COMMON_CLK && CLK_SUNXI


vim +/handle_domain_irq +175 drivers/irqchip/irq-xilinx-intc.c

   165	
   166	static void xil_intc_handle_irq(struct pt_regs *regs)
   167	{
   168		int ret;
   169		unsigned int hwirq, cpu_id = smp_processor_id();
   170		struct xintc_irq_chip *irqc = per_cpu_ptr(&primary_intc, cpu_id);
   171	
   172		do {
   173			hwirq = irqc->read_fn(irqc->base + IVR);
   174			if (hwirq != -1U) {
 > 175				ret = handle_domain_irq(irqc->root_domain, hwirq, regs);
   176				WARN_ONCE(ret, "cpu %d: Unhandled HWIRQ %d\n",
   177					  cpu_id, hwirq);
   178				continue;
   179			}
   180	
   181			break;
   182		} while (1);
   183	}
   184	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 17178 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/14f05743/attachment-0001.gz>

From viresh.kumar at linaro.org  Wed Aug 11 21:35:13 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Aug 2021 10:05:13 +0530
Subject: [PATCH V3 0/9] Add callback to register with energy model
Message-ID: <cover.1628742634.git.viresh.kumar@linaro.org>

Many cpufreq drivers register with the energy model for each policy and
do exactly the same thing. Follow the footsteps of thermal-cooling, to
get it done from the cpufreq core itself.

Provide a new callback, which will be called, if present, by the cpufreq
core at the right moment (more on that in the code's comment). Also
provide a generic implementation that uses dev_pm_opp_of_register_em().

This also allows us to register with the EM at a later point of time,
compared to ->init(), from where the EM core can access cpufreq policy
directly using cpufreq_cpu_get() type of helpers and perform other work,
like marking few frequencies inefficient, this will be done separately.

This is build/boot tested by the bot for a couple of boards.

https://gitlab.com/vireshk/pmko/-/pipelines/351965580

FWIW, I have queued up the series for linux-next to get more testing, but your
reviews are welcome. Thanks.

V2->V3:
- Drop the auto-register part from all logs, this isn't called auto registration
  anymore.
- Call register_em() only for new policies.
- Update scmi driver to register with EM only when required.
- Add Rby tags.

V1->V2:
- Add a callback instead of flag.
- Register before governor is initialized.
- Update scmi driver as well.
- Don't unregister from the EM core.

--
Viresh

Viresh Kumar (9):
  cpufreq: Add callback to register with energy model
  cpufreq: dt: Use .register_em() to register with energy model
  cpufreq: imx6q: Use .register_em() to register with energy model
  cpufreq: mediatek: Use .register_em() to register with energy model
  cpufreq: omap: Use .register_em() to register with energy model
  cpufreq: qcom-cpufreq-hw: Use .register_em() to register with energy
    model
  cpufreq: scpi: Use .register_em() to register with energy model
  cpufreq: vexpress: Use .register_em() to register with energy model
  cpufreq: scmi: Use .register_em() to register with energy model

 drivers/cpufreq/cpufreq-dt.c           |  3 +-
 drivers/cpufreq/cpufreq.c              | 13 ++++++
 drivers/cpufreq/imx6q-cpufreq.c        |  2 +-
 drivers/cpufreq/mediatek-cpufreq.c     |  3 +-
 drivers/cpufreq/omap-cpufreq.c         |  2 +-
 drivers/cpufreq/qcom-cpufreq-hw.c      |  3 +-
 drivers/cpufreq/scmi-cpufreq.c         | 65 +++++++++++++++++---------
 drivers/cpufreq/scpi-cpufreq.c         |  3 +-
 drivers/cpufreq/vexpress-spc-cpufreq.c |  3 +-
 include/linux/cpufreq.h                | 14 ++++++
 10 files changed, 76 insertions(+), 35 deletions(-)

-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 21:35:16 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Aug 2021 10:05:16 +0530
Subject: [PATCH V3 3/9] cpufreq: imx6q: Use .register_em() to register with
 energy model
In-Reply-To: <cover.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <fcd300c685d5152e76a811c492b0e6eccde29717.1628742634.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback with
cpufreq_register_em_with_opp() to register with the EM core.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/imx6q-cpufreq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 5bf5fc759881..90beb26ed34e 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -192,7 +192,6 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
 	policy->clk = clks[ARM].clk;
 	cpufreq_generic_init(policy, freq_table, transition_latency);
 	policy->suspend_freq = max_freq;
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
 
 	return 0;
 }
@@ -204,6 +203,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
 	.target_index = imx6q_set_target,
 	.get = cpufreq_generic_get,
 	.init = imx6q_cpufreq_init,
+	.register_em = cpufreq_register_em_with_opp,
 	.name = "imx6q-cpufreq",
 	.attr = cpufreq_generic_attr,
 	.suspend = cpufreq_generic_suspend,
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 21:35:17 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Aug 2021 10:05:17 +0530
Subject: [PATCH V3 4/9] cpufreq: mediatek: Use .register_em() to register with
 energy model
In-Reply-To: <cover.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <3701fd64a3fb947fc805ca0d108ab87562a9659b.1628742634.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback with
cpufreq_register_em_with_opp() to register with the EM core.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/mediatek-cpufreq.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
index 87019d5a9547..866163883b48 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -448,8 +448,6 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy)
 	policy->driver_data = info;
 	policy->clk = info->cpu_clk;
 
-	dev_pm_opp_of_register_em(info->cpu_dev, policy->cpus);
-
 	return 0;
 }
 
@@ -471,6 +469,7 @@ static struct cpufreq_driver mtk_cpufreq_driver = {
 	.get = cpufreq_generic_get,
 	.init = mtk_cpufreq_init,
 	.exit = mtk_cpufreq_exit,
+	.register_em = cpufreq_register_em_with_opp,
 	.name = "mtk-cpufreq",
 	.attr = cpufreq_generic_attr,
 };
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 21:35:20 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Aug 2021 10:05:20 +0530
Subject: [PATCH V3 7/9] cpufreq: scpi: Use .register_em() to register with
 energy model
In-Reply-To: <cover.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <a214649dfcbc812ddf6b3906315da166caf01964.1628742634.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback with
cpufreq_register_em_with_opp() to register with the EM core.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/scpi-cpufreq.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c
index d6a698a1b5d1..bda3e7d42964 100644
--- a/drivers/cpufreq/scpi-cpufreq.c
+++ b/drivers/cpufreq/scpi-cpufreq.c
@@ -163,8 +163,6 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
 
 	policy->fast_switch_possible = false;
 
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
-
 	return 0;
 
 out_free_cpufreq_table:
@@ -200,6 +198,7 @@ static struct cpufreq_driver scpi_cpufreq_driver = {
 	.init	= scpi_cpufreq_init,
 	.exit	= scpi_cpufreq_exit,
 	.target_index	= scpi_cpufreq_set_target,
+	.register_em	= cpufreq_register_em_with_opp,
 };
 
 static int scpi_cpufreq_probe(struct platform_device *pdev)
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 21:35:21 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Aug 2021 10:05:21 +0530
Subject: [PATCH V3 8/9] cpufreq: vexpress: Use .register_em() to register with
 energy model
In-Reply-To: <cover.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <b64eea485feb5cfb18e74e100dea49c917d4474a.1628742634.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback with
cpufreq_register_em_with_opp() to register with the EM core.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/vexpress-spc-cpufreq.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c
index ab56813b7256..284b6bd040b1 100644
--- a/drivers/cpufreq/vexpress-spc-cpufreq.c
+++ b/drivers/cpufreq/vexpress-spc-cpufreq.c
@@ -440,8 +440,6 @@ static int ve_spc_cpufreq_init(struct cpufreq_policy *policy)
 	policy->freq_table = freq_table[cur_cluster];
 	policy->cpuinfo.transition_latency = 1000000; /* 1 ms */
 
-	dev_pm_opp_of_register_em(cpu_dev, policy->cpus);
-
 	if (is_bL_switching_enabled())
 		per_cpu(cpu_last_req_freq, policy->cpu) =
 						clk_get_cpu_rate(policy->cpu);
@@ -475,6 +473,7 @@ static struct cpufreq_driver ve_spc_cpufreq_driver = {
 	.get			= ve_spc_cpufreq_get_rate,
 	.init			= ve_spc_cpufreq_init,
 	.exit			= ve_spc_cpufreq_exit,
+	.register_em		= cpufreq_register_em_with_opp,
 	.attr			= cpufreq_generic_attr,
 };
 
-- 
2.31.1.272.g89b43f80a514



From viresh.kumar at linaro.org  Wed Aug 11 21:35:22 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 12 Aug 2021 10:05:22 +0530
Subject: [PATCH V3 9/9] cpufreq: scmi: Use .register_em() to register with
 energy model
In-Reply-To: <cover.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <8158488baa1ea1aebd09c8d256db7420051d05ac.1628742634.git.viresh.kumar@linaro.org>

Set the newly added .register_em() callback to register with the EM
after the cpufreq policy is properly initialized.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/scmi-cpufreq.c | 65 ++++++++++++++++++++++------------
 1 file changed, 42 insertions(+), 23 deletions(-)

diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index 75f818d04b48..1e0cd4d165f0 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -22,7 +22,9 @@
 
 struct scmi_data {
 	int domain_id;
+	int nr_opp;
 	struct device *cpu_dev;
+	cpumask_var_t opp_shared_cpus;
 };
 
 static struct scmi_protocol_handle *ph;
@@ -123,9 +125,6 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	struct device *cpu_dev;
 	struct scmi_data *priv;
 	struct cpufreq_frequency_table *freq_table;
-	struct em_data_callback em_cb = EM_DATA_CB(scmi_get_cpu_power);
-	cpumask_var_t opp_shared_cpus;
-	bool power_scale_mw;
 
 	cpu_dev = get_cpu_device(policy->cpu);
 	if (!cpu_dev) {
@@ -133,9 +132,15 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 		return -ENODEV;
 	}
 
-	if (!zalloc_cpumask_var(&opp_shared_cpus, GFP_KERNEL))
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
 		return -ENOMEM;
 
+	if (!zalloc_cpumask_var(&priv->opp_shared_cpus, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto out_free_priv;
+	}
+
 	/* Obtain CPUs that share SCMI performance controls */
 	ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
 	if (ret) {
@@ -148,14 +153,14 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	 * The OPP 'sharing cpus' info may come from DT through an empty opp
 	 * table and opp-shared.
 	 */
-	ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, opp_shared_cpus);
-	if (ret || !cpumask_weight(opp_shared_cpus)) {
+	ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->opp_shared_cpus);
+	if (ret || !cpumask_weight(priv->opp_shared_cpus)) {
 		/*
 		 * Either opp-table is not set or no opp-shared was found.
 		 * Use the CPU mask from SCMI to designate CPUs sharing an OPP
 		 * table.
 		 */
-		cpumask_copy(opp_shared_cpus, policy->cpus);
+		cpumask_copy(priv->opp_shared_cpus, policy->cpus);
 	}
 
 	 /*
@@ -180,7 +185,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 			goto out_free_opp;
 		}
 
-		ret = dev_pm_opp_set_sharing_cpus(cpu_dev, opp_shared_cpus);
+		ret = dev_pm_opp_set_sharing_cpus(cpu_dev, priv->opp_shared_cpus);
 		if (ret) {
 			dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
 				__func__, ret);
@@ -188,21 +193,13 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 			goto out_free_opp;
 		}
 
-		power_scale_mw = perf_ops->power_scale_mw_get(ph);
-		em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb,
-					    opp_shared_cpus, power_scale_mw);
-	}
-
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		ret = -ENOMEM;
-		goto out_free_opp;
+		priv->nr_opp = nr_opp;
 	}
 
 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
 	if (ret) {
 		dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
-		goto out_free_priv;
+		goto out_free_opp;
 	}
 
 	priv->cpu_dev = cpu_dev;
@@ -223,17 +220,16 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	policy->fast_switch_possible =
 		perf_ops->fast_switch_possible(ph, cpu_dev);
 
-	free_cpumask_var(opp_shared_cpus);
 	return 0;
 
-out_free_priv:
-	kfree(priv);
-
 out_free_opp:
 	dev_pm_opp_remove_all_dynamic(cpu_dev);
 
 out_free_cpumask:
-	free_cpumask_var(opp_shared_cpus);
+	free_cpumask_var(priv->opp_shared_cpus);
+
+out_free_priv:
+	kfree(priv);
 
 	return ret;
 }
@@ -244,11 +240,33 @@ static int scmi_cpufreq_exit(struct cpufreq_policy *policy)
 
 	dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
 	dev_pm_opp_remove_all_dynamic(priv->cpu_dev);
+	free_cpumask_var(priv->opp_shared_cpus);
 	kfree(priv);
 
 	return 0;
 }
 
+static void scmi_cpufreq_register_em(struct cpufreq_policy *policy)
+{
+	struct em_data_callback em_cb = EM_DATA_CB(scmi_get_cpu_power);
+	bool power_scale_mw = perf_ops->power_scale_mw_get(ph);
+	struct scmi_data *priv = policy->driver_data;
+
+	/*
+	 * This callback will be called for each policy, but we don't need to
+	 * register with EM every time. Despite not being part of the same
+	 * policy, some CPUs may still share their perf-domains, and a CPU from
+	 * another policy may already have registered with EM on behalf of CPUs
+	 * of this policy.
+	 */
+	if (!priv->nr_opp)
+		return;
+
+	em_dev_register_perf_domain(get_cpu_device(policy->cpu), priv->nr_opp,
+				    &em_cb, priv->opp_shared_cpus,
+				    power_scale_mw);
+}
+
 static struct cpufreq_driver scmi_cpufreq_driver = {
 	.name	= "scmi",
 	.flags	= CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
@@ -261,6 +279,7 @@ static struct cpufreq_driver scmi_cpufreq_driver = {
 	.get	= scmi_cpufreq_get_rate,
 	.init	= scmi_cpufreq_init,
 	.exit	= scmi_cpufreq_exit,
+	.register_em	= scmi_cpufreq_register_em,
 };
 
 static int scmi_cpufreq_probe(struct scmi_device *sdev)
-- 
2.31.1.272.g89b43f80a514



From anshuman.khandual at arm.com  Wed Aug 11 22:09:49 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 10:39:49 +0530
Subject: [PATCH V2 0/5] KVM: arm64: General cleanups
Message-ID: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>

This series contains mostly unrelated general cleanups. This series applies
on v5.14-rc5 and has been boot tested with different page sized guests.

Changes in V2:

- Dropped the first patch regarding PAGE_[SHIFT|SIZE] per Marc
- Added remaining ID_AA64MMFR0_PARANGE_ macros and ARM64_MIN_PARANGE_BITS per Marc
- Dropped memory and cycle reference from commit message in [PATCH 3/5]
- Changed return value as u32 in kvm_target_cpu() per Will

Changes in V1:

https://lore.kernel.org/lkml/1628578961-29097-1-git-send-email-anshuman.khandual at arm.com/

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (5):
  arm64/mm: Add remaining ID_AA64MMFR0_PARANGE_ macros
  KVM: arm64: Use ARM64_MIN_PARANGE_BITS as the minimum supported IPA
  KVM: arm64: Drop init_common_resources()
  KVM: arm64: Drop check_kvm_target_cpu() based percpu probe
  KVM: arm64: Drop unused REQUIRES_VIRT

 arch/arm64/include/asm/cpufeature.h | 14 +++++++-------
 arch/arm64/include/asm/kvm_host.h   |  2 +-
 arch/arm64/include/asm/sysreg.h     |  7 +++++++
 arch/arm64/kvm/arm.c                | 27 ++-------------------------
 arch/arm64/kvm/guest.c              |  4 ++--
 arch/arm64/kvm/reset.c              |  2 +-
 6 files changed, 20 insertions(+), 36 deletions(-)

-- 
2.20.1



From anshuman.khandual at arm.com  Wed Aug 11 22:09:50 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 10:39:50 +0530
Subject: [PATCH V2 1/5] arm64/mm: Add remaining ID_AA64MMFR0_PARANGE_ macros
In-Reply-To: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
References: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628744994-16623-2-git-send-email-anshuman.khandual@arm.com>

Currently there are macros only for 48 and 52 bits parange value extracted
from the ID_AA64MMFR0.PARANGE field. This change completes the enumeration
and updates the helper id_aa64mmfr0_parange_to_phys_shift(). While here it
also defines ARM64_MIN_PARANGE_BITS as the absolute minimum shift value PA
range which could be supported on a given platform.

Cc: Marc Zyngier <maz at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/cpufeature.h | 14 +++++++-------
 arch/arm64/include/asm/sysreg.h     |  7 +++++++
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 9bb9d11750d7..8633bdb21f33 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -781,13 +781,13 @@ extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
 static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
 {
 	switch (parange) {
-	case 0: return 32;
-	case 1: return 36;
-	case 2: return 40;
-	case 3: return 42;
-	case 4: return 44;
-	case 5: return 48;
-	case 6: return 52;
+	case ID_AA64MMFR0_PARANGE_32: return 32;
+	case ID_AA64MMFR0_PARANGE_36: return 36;
+	case ID_AA64MMFR0_PARANGE_40: return 40;
+	case ID_AA64MMFR0_PARANGE_42: return 42;
+	case ID_AA64MMFR0_PARANGE_44: return 44;
+	case ID_AA64MMFR0_PARANGE_48: return 48;
+	case ID_AA64MMFR0_PARANGE_52: return 52;
 	/*
 	 * A future PE could use a value unknown to the kernel.
 	 * However, by the "D10.1.4 Principles of the ID scheme
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7b9c3acba684..504e909129ea 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -853,9 +853,16 @@
 #define ID_AA64MMFR0_TGRAN64_SUPPORTED	0x0
 #define ID_AA64MMFR0_TGRAN16_NI		0x0
 #define ID_AA64MMFR0_TGRAN16_SUPPORTED	0x1
+#define ID_AA64MMFR0_PARANGE_32		0x0
+#define ID_AA64MMFR0_PARANGE_36		0x1
+#define ID_AA64MMFR0_PARANGE_40		0x2
+#define ID_AA64MMFR0_PARANGE_42		0x3
+#define ID_AA64MMFR0_PARANGE_44		0x4
 #define ID_AA64MMFR0_PARANGE_48		0x5
 #define ID_AA64MMFR0_PARANGE_52		0x6
 
+#define ARM64_MIN_PARANGE_BITS		32
+
 #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_DEFAULT	0x0
 #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE	0x1
 #define ID_AA64MMFR0_TGRAN_2_SUPPORTED_MIN	0x2
-- 
2.20.1



From anshuman.khandual at arm.com  Wed Aug 11 22:09:52 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 10:39:52 +0530
Subject: [PATCH V2 3/5] KVM: arm64: Drop init_common_resources()
In-Reply-To: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
References: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628744994-16623-4-git-send-email-anshuman.khandual@arm.com>

Could do without this additional indirection via init_common_resources() by
just calling kvm_set_ipa_limit() directly instead.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kvm/arm.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..19560e457c11 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1696,11 +1696,6 @@ static bool init_psci_relay(void)
 	return true;
 }
 
-static int init_common_resources(void)
-{
-	return kvm_set_ipa_limit();
-}
-
 static int init_subsystems(void)
 {
 	int err = 0;
@@ -2102,7 +2097,7 @@ int kvm_arch_init(void *opaque)
 		}
 	}
 
-	err = init_common_resources();
+	err = kvm_set_ipa_limit();
 	if (err)
 		return err;
 
-- 
2.20.1



From anshuman.khandual at arm.com  Wed Aug 11 22:09:53 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 10:39:53 +0530
Subject: [PATCH V2 4/5] KVM: arm64: Drop check_kvm_target_cpu() based percpu
 probe
In-Reply-To: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
References: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628744994-16623-5-git-send-email-anshuman.khandual@arm.com>

kvm_target_cpu() never returns a negative error code, so check_kvm_target()
would never have 'ret' filled with a negative error code. Hence the percpu
probe via check_kvm_target_cpu() does not make sense as its never going to
find an unsupported CPU, forcing kvm_arch_init() to exit early. Hence lets
just drop this percpu probe (and also check_kvm_target_cpu()) altogether.

While here, this also changes kvm_target_cpu() return type to a u32, making
it explicit that an error code will not be returned from this function.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  2 +-
 arch/arm64/kvm/arm.c              | 16 +---------------
 arch/arm64/kvm/guest.c            |  4 ++--
 3 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 41911585ae0c..26bbd84a02de 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -66,7 +66,7 @@ DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
 extern unsigned int kvm_sve_max_vl;
 int kvm_arm_init_sve(void);
 
-int __attribute_const__ kvm_target_cpu(void);
+u32 __attribute_const__ kvm_target_cpu(void);
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
 void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 19560e457c11..ee9b1166f330 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1035,7 +1035,7 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
 			       const struct kvm_vcpu_init *init)
 {
 	unsigned int i, ret;
-	int phys_target = kvm_target_cpu();
+	u32 phys_target = kvm_target_cpu();
 
 	if (init->target != phys_target)
 		return -EINVAL;
@@ -2010,11 +2010,6 @@ static int finalize_hyp_mode(void)
 	return 0;
 }
 
-static void check_kvm_target_cpu(void *ret)
-{
-	*(int *)ret = kvm_target_cpu();
-}
-
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
 {
 	struct kvm_vcpu *vcpu;
@@ -2074,7 +2069,6 @@ void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons)
 int kvm_arch_init(void *opaque)
 {
 	int err;
-	int ret, cpu;
 	bool in_hyp_mode;
 
 	if (!is_hyp_mode_available()) {
@@ -2089,14 +2083,6 @@ int kvm_arch_init(void *opaque)
 		kvm_info("Guests without required CPU erratum workarounds can deadlock system!\n" \
 			 "Only trusted guests should be used on this system.\n");
 
-	for_each_online_cpu(cpu) {
-		smp_call_function_single(cpu, check_kvm_target_cpu, &ret, 1);
-		if (ret < 0) {
-			kvm_err("Error, CPU %d not supported!\n", cpu);
-			return -ENODEV;
-		}
-	}
-
 	err = kvm_set_ipa_limit();
 	if (err)
 		return err;
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 1dfb83578277..8ce850fa7b49 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -842,7 +842,7 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
-int __attribute_const__ kvm_target_cpu(void)
+u32 __attribute_const__ kvm_target_cpu(void)
 {
 	unsigned long implementor = read_cpuid_implementor();
 	unsigned long part_number = read_cpuid_part_number();
@@ -874,7 +874,7 @@ int __attribute_const__ kvm_target_cpu(void)
 
 int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
 {
-	int target = kvm_target_cpu();
+	u32 target = kvm_target_cpu();
 
 	if (target < 0)
 		return -ENODEV;
-- 
2.20.1



From anshuman.khandual at arm.com  Wed Aug 11 22:09:51 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 10:39:51 +0530
Subject: [PATCH V2 2/5] KVM: arm64: Use ARM64_MIN_PARANGE_BITS as the minimum
 supported IPA
In-Reply-To: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
References: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628744994-16623-3-git-send-email-anshuman.khandual@arm.com>

Drop hard coded value for the minimum supported IPA range bits (i.e 32).
Instead use ARM64_MIN_PARANGE_BITS which improves the code readability.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kvm/reset.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index cba7872d69a8..acf309698f33 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -369,7 +369,7 @@ int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type)
 	phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
 	if (phys_shift) {
 		if (phys_shift > kvm_ipa_limit ||
-		    phys_shift < 32)
+		    phys_shift < ARM64_MIN_PARANGE_BITS)
 			return -EINVAL;
 	} else {
 		phys_shift = KVM_PHYS_SHIFT;
-- 
2.20.1



From anshuman.khandual at arm.com  Wed Aug 11 22:09:54 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 10:39:54 +0530
Subject: [PATCH V2 5/5] KVM: arm64: Drop unused REQUIRES_VIRT
In-Reply-To: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
References: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1628744994-16623-6-git-send-email-anshuman.khandual@arm.com>

This seems like a residue from the past. REQUIRES_VIRT is no more available
. Hence it can just be dropped along with the related code section.

Cc: Marc Zyngier <maz at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: kvmarm at lists.cs.columbia.edu
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kvm/arm.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index ee9b1166f330..d779a29c5607 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -42,10 +42,6 @@
 #include <kvm/arm_pmu.h>
 #include <kvm/arm_psci.h>
 
-#ifdef REQUIRES_VIRT
-__asm__(".arch_extension	virt");
-#endif
-
 static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT;
 DEFINE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);
 
-- 
2.20.1



From email2tema at gmail.com  Wed Aug 11 22:10:59 2021
From: email2tema at gmail.com (Artem Lapkin)
Date: Thu, 12 Aug 2021 13:10:59 +0800
Subject: [PATCH] arm64: dts: meson: sm1-khadas-vim3l use one sound node
 configuration with VIM3
Message-ID: <20210812051059.1103641-1-art@khadas.com>

Khadas VIM3L board sound configuration same as Khadas VIM3, its already
defined in meson-khadas-vim3.dtsi and no need overwrite it with different
card names and routing configurations.

Signed-off-by: Artem Lapkin <art at khadas.com>
---
 .../boot/dts/amlogic/meson-sm1-khadas-vim3l.dts     | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts
index f2c098143..06de0b1ce 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts
@@ -32,19 +32,6 @@ vddcpu: regulator-vddcpu {
 		regulator-boot-on;
 		regulator-always-on;
 	};
-
-	sound {
-		model = "G12B-KHADAS-VIM3L";
-		audio-routing = "TDMOUT_A IN 0", "FRDDR_A OUT 0",
-				"TDMOUT_A IN 1", "FRDDR_B OUT 0",
-				"TDMOUT_A IN 2", "FRDDR_C OUT 0",
-				"TDM_A Playback", "TDMOUT_A OUT",
-				"TDMIN_A IN 0", "TDM_A Capture",
-				"TDMIN_A IN 13", "TDM_A Loopback",
-				"TODDR_A IN 0", "TDMIN_A OUT",
-				"TODDR_B IN 0", "TDMIN_A OUT",
-				"TODDR_C IN 0", "TDMIN_A OUT";
-	};
 };
 
 &cpu0 {
-- 
2.25.1



From o.rempel at pengutronix.de  Wed Aug 11 22:18:55 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Thu, 12 Aug 2021 07:18:55 +0200
Subject: [PATCH v1] dt-bindings: timer: fsl,imxgpt: add optional osc_per
 clock
In-Reply-To: <YRQRNrLXIYERa6FT@robh.at.kernel.org>
References: <20210803072958.4815-1-o.rempel@pengutronix.de>
 <YRQRNrLXIYERa6FT@robh.at.kernel.org>
Message-ID: <20210812051855.vrwisusfqkbb5v6a@pengutronix.de>

On Wed, Aug 11, 2021 at 12:04:38PM -0600, Rob Herring wrote:
> On Tue, Aug 03, 2021 at 09:29:58AM +0200, Oleksij Rempel wrote:
> > Add optional osc_per and fix dts validation warnings on imx6 SoCs.
> > 
> > Fixes: df8cad689eae ("dt-bindings: timer: Convert i.MX GPT to json-schema")
> 
> I don't think you can say the above commit was broken.
>
> > Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> > ---
> >  .../devicetree/bindings/timer/fsl,imxgpt.yaml   | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> > index a4f51f46b7a1..e496dd9f4988 100644
> > --- a/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> > +++ b/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> > @@ -43,11 +43,15 @@ properties:
> >      items:
> >        - description: SoC GPT ipg clock
> >        - description: SoC GPT per clock
> > +      - description: optional SoC GPT oscillator
> > +    minItems: 2
> 
> The 3rd clock is valid on every version of the h/w?

No.

Regards,
Oleksij
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From balbi at kernel.org  Wed Aug 11 22:40:03 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Thu, 12 Aug 2021 08:40:03 +0300
Subject: [PATCH v2 4/9] usb: gadget: udc: s3c2410: add IRQ check
In-Reply-To: <bd69b22c-b484-5a1f-c798-78d4b78405f2@omp.ru>
References: <47bacc02-4e34-3208-779c-7072a6261782@omp.ru>
 <bd69b22c-b484-5a1f-c798-78d4b78405f2@omp.ru>
Message-ID: <87sfzfz0dz.fsf@kernel.org>


Sergey Shtylyov <s.shtylyov at omp.ru> writes:

> The driver neglects to check the result of platform_get_irq()'s call and
> blithely passes the negative error codes to request_irq() (which takes
> *unsigned* IRQ #), causing it to fail with -EINVAL, overriding an original
> error code. Stop calling request_irq() with the invalid IRQ #s.
>
> Fixes: 188db4435ac6 ("usb: gadget: s3c: use platform resources")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

Acked-by: Felipe Balbi <balbi at kernel.org>

-- 
balbi


From wangkefeng.wang at huawei.com  Wed Aug 11 23:07:36 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Thu, 12 Aug 2021 14:07:36 +0800
Subject: [PATCH v3 0/3] arm64: support page mapping percpu first chunk
 allocator
In-Reply-To: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
Message-ID: <9b75f4e5-a675-1227-0476-43fc21509086@huawei.com>

Hi Catalin and Will?

The drivers/base/arch_numa.c is only shared by riscv and arm64,

and the change from patch2 won't broke riscv.

Could all patches be merged by arm64 tree? or any new comments?

Many thanks.

On 2021/8/9 17:37, Kefeng Wang wrote:
> Percpu embedded first chunk allocator is the firstly option, but it
> could fails on ARM64, eg,
>    "percpu: max_distance=0x5fcfdc640000 too large for vmalloc space 0x781fefff0000"
>    "percpu: max_distance=0x600000540000 too large for vmalloc space 0x7dffb7ff0000"
>    "percpu: max_distance=0x5fff9adb0000 too large for vmalloc space 0x5dffb7ff0000"
>
> then we could meet "WARNING: CPU: 15 PID: 461 at vmalloc.c:3087 pcpu_get_vm_areas+0x488/0x838",
> even the system could not boot successfully.
>
> Let's implement page mapping percpu first chunk allocator as a fallback
> to the embedding allocator to increase the robustness of the system.
>
> Also fix a crash when both NEED_PER_CPU_PAGE_FIRST_CHUNK and KASAN_VMALLOC enabled.
>
> Tested on ARM64 qemu with cmdline "percpu_alloc=page" based on v5.14-rc5.
>
> v3:
> - search for a range that fits instead of always picking the end from
>    vmalloc area suggested by Catalin.
> - use NUMA_NO_NODE to avoid "virt_to_phys used for non-linear address:"
>    issue in arm64 kasan_populate_early_vm_area_shadow().
> - add Acked-by: Marco Elver <elver at google.com> to patch v3
>
> V2:
> - fix build error when CONFIG_KASAN disabled, found by lkp at intel.com
> - drop wrong __weak comment from kasan_populate_early_vm_area_shadow(),
>    found by Marco Elver <elver at google.com>
>
> Kefeng Wang (3):
>    vmalloc: Choose a better start address in vm_area_register_early()
>    arm64: Support page mapping percpu first chunk allocator
>    kasan: arm64: Fix pcpu_page_first_chunk crash with KASAN_VMALLOC
>
>   arch/arm64/Kconfig         |  4 ++
>   arch/arm64/mm/kasan_init.c | 16 ++++++++
>   drivers/base/arch_numa.c   | 82 +++++++++++++++++++++++++++++++++-----
>   include/linux/kasan.h      |  6 +++
>   mm/kasan/init.c            |  5 +++
>   mm/vmalloc.c               | 17 +++++---
>   6 files changed, 115 insertions(+), 15 deletions(-)
>


From balbi at kernel.org  Wed Aug 11 23:49:36 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Thu, 12 Aug 2021 09:49:36 +0300
Subject: [PATCH 2/6] usb: mtu3: fix the wrong HS mult value
In-Reply-To: <1628739182-30089-2-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
 <1628739182-30089-2-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <87pmujyx5f.fsf@kernel.org>


Chunfeng Yun <chunfeng.yun at mediatek.com> writes:

> Use usb_endpoint_maxp() and usb_endpoint_maxp_mult() seperately
> to get maxpacket and mult.
> Meanwhile fix the bug that should use @mult but not @burst
> to save mult value.

I really think you should split this into two patches. One which *only*
fixes the bug and another (patch 2) which *only* corrects the use
usb_endpoint_maxp()

-- 
balbi


From maz at kernel.org  Wed Aug 11 23:51:23 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 07:51:23 +0100
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
Message-ID: <87czqj9mvo.wl-maz@kernel.org>

On Wed, 11 Aug 2021 17:55:07 +0100,
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> 
> On 11.08.2021 14:50, Marc Zyngier wrote:
> > On Wed, 11 Aug 2021 13:15:31 +0100,
> > Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> >> 
> >> Hi,
> >> 
> >> I just tried upgrading from the old good LTS kernel 5.10 and I
> >> discovered that my bcm4908 boards don't boot anymore with the 5.14-rc5.
> >> 
> >> 
> >> The problem is kernel doesn't seem to start booting at all. I see CFE
> >> bootloader messages:
> >> 
> >> Starting program at 0x0000000000080000
> >> /memory = 0x40000000
> >> 
> >> and then nothing. Normally the first kernel line should follow like a:
> >> Linux version 5.11.0-rc4 (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #30 SMP Wed Aug 11 14:01:00 CEST 2021
> >> 
> >> 
> >> I have zero knowledge of low level arm64 or assembler stuff. I also
> >> don't own any bcm4908 development board or bcm4908 datasheets.
> >> 
> >> All I could do to help debugging this regression was bisecting. The
> >> first bad commit (I verified it after bisecting process) is:
> >> 
> >> commit 0c93df9622d4d921bcd0dc83f71fed9e98f5119f
> >> Author: Marc Zyngier <maz at kernel.org>
> >> Date:   Mon Feb 8 09:57:14 2021 +0000
> >> 
> >>      arm64: Initialise as nVHE before switching to VHE
> >> 
> >>      As we are aiming to be able to control whether we enable VHE or
> >>      not, let's always drop down to EL1 first, and only then upgrade
> >>      to VHE if at all possible.
> >> 
> >>      This means that if the kernel is booted at EL2, we always start
> >>      with a nVHE init, drop to EL1 to initialise the the kernel, and
> >>      only then upgrade the kernel EL to EL2 if possible (the process
> >>      is obviously shortened for secondary CPUs).
> >> 
> >>      The resume path is handled similarly to a secondary CPU boot.
> >> 
> >>      Signed-off-by: Marc Zyngier <maz at kernel.org>
> >>      Acked-by: David Brazdil <dbrazdil at google.com>
> >>      Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> >>      Link: https://lore.kernel.org/r/20210208095732.3267263-6-maz at kernel.org
> >>      [will: Avoid calling switch_to_vhe twice on kaslr path]
> >>      Signed-off-by: Will Deacon <will at kernel.org>
> >> 
> >> 
> >> Could you look at this issue, please? I'm happy to test any patches or
> >> provide any extra info I can obtain using kernel 5.11.
> >> 
> >> 
> >> My defconfig for bcm4908 is:
> > 
> > [...]
> > 
> > I don't think the dconfig is that relevant (nothing you quote here
> > would have an impact that early in the boot process).
> > 
> > On the other hand, a description of the platform (what CPUs does it
> > have) and how it boots (VHE, non-VHE, booted at EL2 or not) would be
> > extremely useful. At minimum, a boot log of a working kernel could
> > help.
> 
> Thank you for your patience & reply.
> 
> BCM4908 is Broadcom's 64-bit platform with Broadcom's own Brahma-B53
> CPU(s). I don't know how it boots. Is that something I can find out
> from a running system?
> 
> For DTS SoC description you can check:
> arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
> 
> See below for bootlog and /proc/cpuinfo. Please note I seem to have
> console misconfigured and early part of log appears twice (nothing
> really harmful).
> 
> Starting program at 0x0000000000080000
> /memory = 0x40000000
> WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
> WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
> WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
> Booting Linux on physical CPU 0x0000000000 [0x420f1000]
> Linux version 5.11.22-g40462c7f0649 (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #9 SMP Wed Aug 11 18:39:58 CEST 2021
> Machine model: Asus GT-AC5300
> earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
> printk: bootconsole [bcm63xx_uart0] enabled
> efi: UEFI not found.
> [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
> Zone ranges:
>   DMA      [mem 0x0000000000000000-0x000000003fffffff]
>   DMA32    empty
>   Normal   empty
> Movable zone start for each node
> Early memory node ranges
>   node   0: [mem 0x0000000000000000-0x000000003fffffff]
> Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
> percpu: Embedded 17 pages/cpu s37856 r0 d31776 u69632
> Detected VIPT I-cache on CPU0
> CPU features: detected: ARM erratum 843419
> Built 1 zonelists, mobility grouping on.  Total pages: 258048
> Kernel command line: earlycon=bcm63xx_uart,0xff800640
> Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
> Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
> mem auto-init: stack:off, heap alloc:off, heap free:off
> Memory: 1020660K/1048576K available (3584K kernel code, 650K rwdata, 684K rodata, 2368K init, 229K bss, 27916K reserved, 0K cma-reserved)
> SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
> rcu: Hierarchical RCU implementation.
> rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
> NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
> GIC: Using split EOI/Deactivate mode
> random: get_random_bytes called from start_kernel+0x33c/0x524 with crng_init=0
> arch_timer: cp15 timer(s) running at 50.00MHz (phys).
> clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
> sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
> Console: colour dummy device 80x25
> printk: console [tty0] enabled
> printk: bootconsole [bcm63xx_uart0] disabled
> Booting Linux on physical CPU 0x0000000000 [0x420f1000]
> Linux version 5.11.22-g40462c7f0649 (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #9 SMP Wed Aug 11 18:39:58 CEST 2021
> Machine model: Asus GT-AC5300
> earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
> printk: bootconsole [bcm63xx_uart0] enabled
> efi: UEFI not found.
> [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
> Zone ranges:
>   DMA      [mem 0x0000000000000000-0x000000003fffffff]
>   DMA32    empty
>   Normal   empty
> Movable zone start for each node
> Early memory node ranges
>   node   0: [mem 0x0000000000000000-0x000000003fffffff]
> Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
> percpu: Embedded 17 pages/cpu s37856 r0 d31776 u69632
> Detected VIPT I-cache on CPU0
> CPU features: detected: ARM erratum 843419
> Built 1 zonelists, mobility grouping on.  Total pages: 258048
> Kernel command line: earlycon=bcm63xx_uart,0xff800640
> Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
> Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
> mem auto-init: stack:off, heap alloc:off, heap free:off
> Memory: 1020660K/1048576K available (3584K kernel code, 650K rwdata, 684K rodata, 2368K init, 229K bss, 27916K reserved, 0K cma-reserved)
> SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
> rcu: Hierarchical RCU implementation.
> rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
> NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
> GIC: Using split EOI/Deactivate mode
> random: get_random_bytes called from start_kernel+0x33c/0x524 with crng_init=0
> arch_timer: cp15 timer(s) running at 50.00MHz (phys).
> clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
> sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
> Console: colour dummy device 80x25
> printk: console [tty0] enabled
> printk: bootconsole [bcm63xx_uart0] disabled
> Calibrating delay loop (skipped), value calculated using timer frequency.. 100.00 BogoMIPS (lpj=200000)
> pid_max: default: 32768 minimum: 301
> Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
> Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
> rcu: Hierarchical SRCU implementation.
> EFI services will not be available.
> smp: Bringing up secondary CPUs ...
> Detected VIPT I-cache on CPU1
> CPU1: Booted secondary processor 0x0000000001 [0x420f1000]
> Detected VIPT I-cache on CPU2
> CPU2: Booted secondary processor 0x0000000002 [0x420f1000]
> Detected VIPT I-cache on CPU3
> CPU3: Booted secondary processor 0x0000000003 [0x420f1000]
> smp: Brought up 1 node, 4 CPUs
> SMP: Total of 4 processors activated.
> CPU features: detected: 32-bit EL0 Support
> CPU features: detected: CRC32 instructions
> CPU: All CPU(s) started at EL2

Interestingly, all your CPUs are booting at EL2. Which is great.  Can
you try and enable KVM on your existing 5.10 kernel? Just selecting
CONFIG_KVM should be enough. Does it boot correctly with KVM enabled?

My suspicion is that the firmware doesn't set SCR_EL3.HCE, and that
the HVC instruction UNDEFs at EL1. That would be bad news.

Please let me know.

	M.

-- 
Without deviation from the norm, progress is not possible.


From balbi at kernel.org  Wed Aug 11 23:51:03 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Thu, 12 Aug 2021 09:51:03 +0300
Subject: [PATCH 3/6] usb: cdnsp: fix the wrong mult value for HS isoc or
 intr
In-Reply-To: <1628739182-30089-3-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
 <1628739182-30089-3-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <87mtpnyx3g.fsf@kernel.org>


Chunfeng Yun <chunfeng.yun at mediatek.com> writes:

> usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
> of endpoint descriptor, not include bit[12:11] anymore, so use
> usb_endpoint_maxp_mult() instead.
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  drivers/usb/cdns3/cdnsp-mem.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
> index a47948a1623f..ad9aee3f1e39 100644
> --- a/drivers/usb/cdns3/cdnsp-mem.c
> +++ b/drivers/usb/cdns3/cdnsp-mem.c
> @@ -882,7 +882,7 @@ static u32 cdnsp_get_endpoint_max_burst(struct usb_gadget *g,
>  	if (g->speed == USB_SPEED_HIGH &&
>  	    (usb_endpoint_xfer_isoc(pep->endpoint.desc) ||
>  	     usb_endpoint_xfer_int(pep->endpoint.desc)))
> -		return (usb_endpoint_maxp(pep->endpoint.desc) & 0x1800) >> 11;
> +		return usb_endpoint_maxp_mult(pep->endpoint.desc) - 1;

this looks like a bugfix. Do we need to Cc stable here?

In any case:

Acked-by: Felipe Balbi <balbi at kernel.org>

-- 
balbi


From balbi at kernel.org  Wed Aug 11 23:51:52 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Thu, 12 Aug 2021 09:51:52 +0300
Subject: [PATCH 4/6] usb: gadget: tegra-xudc: fix the wrong mult value
 for HS isoc or intr
In-Reply-To: <1628739182-30089-4-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
 <1628739182-30089-4-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <87k0kryx20.fsf@kernel.org>


Chunfeng Yun <chunfeng.yun at mediatek.com> writes:

> usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
> of endpoint descriptor, not includes bit[12:11] anymore, so use
> usb_endpoint_maxp_mult() instead.
> Meanwhile no need AND 0x7ff when get maxp, remove it.
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  drivers/usb/gadget/udc/tegra-xudc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
> index a54d1cef17db..40a7417e7ae4 100644
> --- a/drivers/usb/gadget/udc/tegra-xudc.c
> +++ b/drivers/usb/gadget/udc/tegra-xudc.c
> @@ -1610,7 +1610,7 @@ static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep)
>  	u16 maxpacket, maxburst = 0, esit = 0;
>  	u32 val;
>  
> -	maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
> +	maxpacket = usb_endpoint_maxp(desc);
>  	if (xudc->gadget.speed == USB_SPEED_SUPER) {
>  		if (!usb_endpoint_xfer_control(desc))
>  			maxburst = comp_desc->bMaxBurst;
> @@ -1621,7 +1621,7 @@ static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep)
>  		   (usb_endpoint_xfer_int(desc) ||
>  		    usb_endpoint_xfer_isoc(desc))) {
>  		if (xudc->gadget.speed == USB_SPEED_HIGH) {
> -			maxburst = (usb_endpoint_maxp(desc) >> 11) & 0x3;
> +			maxburst = usb_endpoint_maxp_mult(desc) - 1;

this looks like a bug fix. Before this change, maxburst was always 0,
right?

In any case:

Acked-by: Felipe Balbi <balbi at kernel.org>

-- 
balbi


From balbi at kernel.org  Wed Aug 11 23:52:34 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Thu, 12 Aug 2021 09:52:34 +0300
Subject: [PATCH 5/6] usb: gadget: bdc: remove unnecessary AND operation
 when get ep maxp
In-Reply-To: <1628739182-30089-5-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
 <1628739182-30089-5-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <87h7fvyx1e.fsf@kernel.org>


Chunfeng Yun <chunfeng.yun at mediatek.com> writes:

> usb_endpoint_maxp() already returns actual max packet size, no need
> AND 0x7ff.
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Acked-by: Felipe Balbi <balbi at kernel.org>

-- 
balbi


From balbi at kernel.org  Wed Aug 11 23:52:58 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Thu, 12 Aug 2021 09:52:58 +0300
Subject: [PATCH 6/6] usb: gadget: remove unnecessary AND operation when
 get ep maxp
In-Reply-To: <1628739182-30089-6-git-send-email-chunfeng.yun@mediatek.com>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
 <1628739182-30089-6-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <87eeazyx0o.fsf@kernel.org>


Chunfeng Yun <chunfeng.yun at mediatek.com> writes:

> usb_endpoint_maxp() already returns actual max packet size, no need
> AND 0x7ff.
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Acked-by: Felipe Balbi <balbi at kernel.org>

-- 
balbi


From rppt at kernel.org  Wed Aug 11 23:59:05 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 12 Aug 2021 09:59:05 +0300
Subject: [PATCH v4 0/2] memblock: make memblock_find_in_range method private
Message-ID: <20210812065907.20046-1-rppt@kernel.org>

From: Mike Rapoport <rppt at linux.ibm.com>

Hi,

This is v4 of "memblock: make memblock_find_in_range method private" patch
that essentially replaces memblock_find_in_range() + memblock_reserve()
calls with equivalent calls to memblock_phys_alloc() and prevents usage of
memblock_find_in_range() outside memblock itself.

The patch uncovered an issue with top down memory mapping on x86 and this
version has a preparation patch that addresses this issue.

Guenter, I didn't add your Tested-by because the patch that addresses the
crashes differs from the one you've tested.

v4: 
* Add patch that prevents the crashes reported by Guenter Roeck on x86/i386
  on QEMU with 256M or 512M of memory and EFI boot enabled.
* Add Acked-by and Reviewed-by, thanks everybidy!

v3: https://lore.kernel.org/lkml/20210803064218.6611-1-rppt at kernel.org
* simplify check for exact crash kerenl allocation on arm, per Rob
* make crash_max unsigned long long on arm64, per Rob

v2: https://lore.kernel.org/lkml/20210802063737.22733-1-rppt at kernel.org
* don't change error message in arm::reserve_crashkernel(), per Russell

v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org

Mike Rapoport (2):
  x86/mm: memory_map_top_down: remove spurious reservation of upper 2M
  memblock: make memblock_find_in_range method private

 arch/arm/kernel/setup.c           | 20 +++++---------
 arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
 arch/arm64/mm/init.c              | 36 ++++++++-----------------
 arch/mips/kernel/setup.c          | 14 +++++-----
 arch/riscv/mm/init.c              | 44 ++++++++++---------------------
 arch/s390/kernel/setup.c          | 10 ++++---
 arch/x86/kernel/aperture_64.c     |  5 ++--
 arch/x86/mm/init.c                | 27 +++++++------------
 arch/x86/mm/numa.c                |  5 ++--
 arch/x86/mm/numa_emulation.c      |  5 ++--
 arch/x86/realmode/init.c          |  2 +-
 drivers/acpi/tables.c             |  5 ++--
 drivers/base/arch_numa.c          |  5 +---
 drivers/of/of_reserved_mem.c      | 12 ++++++---
 include/linux/memblock.h          |  2 --
 mm/memblock.c                     |  2 +-
 16 files changed, 76 insertions(+), 127 deletions(-)


base-commit: ff1176468d368232b684f75e82563369208bc371
-- 
2.28.0



From rppt at kernel.org  Wed Aug 11 23:59:06 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 12 Aug 2021 09:59:06 +0300
Subject: [PATCH v4 1/2] x86/mm: memory_map_top_down: remove spurious
 reservation of upper 2M
In-Reply-To: <20210812065907.20046-1-rppt@kernel.org>
References: <20210812065907.20046-1-rppt@kernel.org>
Message-ID: <20210812065907.20046-2-rppt@kernel.org>

From: Mike Rapoport <rppt at linux.ibm.com>

memory_map_top_down() function skips the upper 2M in the beginning and maps
them in the end because

	"xen has big range in reserved near end of ram, skip it at first"

It appears, though, that the root cause was that there was not enough
memory in the range [min_pfn_mapped, max_pfn_mapped] to allocate page
tables from that range in alloc_low_pages() because min_pfn_mapped didn't
reflect that actual minimal pfn that was already mapped but remained close
to the end of the range being mapped by memory_map_top_down().

This happened because min_pfn_mapped is updated at every iteration of the
loop in memory_map_top_down(), but there is another loop in
init_range_memory_mapping() that maps several regions below the current
min_pfn_mapped without updating this variable.

Move the update of min_pfn_mapped to add_pfn_range_mapped() next to the
update of max_pfn_mapped so that every time a new range is mapped both
limits will be updated accordingly, and remove the spurious "reservation"
of upper 2M.

Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
---
 arch/x86/mm/init.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 75ef19aa8903..87150961fdca 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -486,6 +486,7 @@ static void add_pfn_range_mapped(unsigned long start_pfn, unsigned long end_pfn)
 	nr_pfn_mapped = clean_sort_range(pfn_mapped, E820_MAX_ENTRIES);
 
 	max_pfn_mapped = max(max_pfn_mapped, end_pfn);
+	min_pfn_mapped = min(min_pfn_mapped, start_pfn);
 
 	if (start_pfn < (1UL<<(32-PAGE_SHIFT)))
 		max_low_pfn_mapped = max(max_low_pfn_mapped,
@@ -605,20 +606,14 @@ static unsigned long __init get_new_step_size(unsigned long step_size)
 static void __init memory_map_top_down(unsigned long map_start,
 				       unsigned long map_end)
 {
-	unsigned long real_end, last_start;
-	unsigned long step_size;
-	unsigned long addr;
+	unsigned long real_end = ALIGN_DOWN(map_end, PMD_SIZE);
+	unsigned long last_start = real_end;
+	/* step_size need to be small so pgt_buf from BRK could cover it */
+	unsigned long step_size = PMD_SIZE;
 	unsigned long mapped_ram_size = 0;
 
-	/* xen has big range in reserved near end of ram, skip it at first.*/
-	addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE);
-	real_end = addr + PMD_SIZE;
-
-	/* step_size need to be small so pgt_buf from BRK could cover it */
-	step_size = PMD_SIZE;
 	max_pfn_mapped = 0; /* will get exact value next */
 	min_pfn_mapped = real_end >> PAGE_SHIFT;
-	last_start = real_end;
 
 	/*
 	 * We start from the top (end of memory) and go to the bottom.
@@ -638,7 +633,6 @@ static void __init memory_map_top_down(unsigned long map_start,
 		mapped_ram_size += init_range_memory_mapping(start,
 							last_start);
 		last_start = start;
-		min_pfn_mapped = last_start >> PAGE_SHIFT;
 		if (mapped_ram_size >= step_size)
 			step_size = get_new_step_size(step_size);
 	}
-- 
2.28.0



From rppt at kernel.org  Wed Aug 11 23:59:07 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 12 Aug 2021 09:59:07 +0300
Subject: [PATCH v4 2/2] memblock: make memblock_find_in_range method private
In-Reply-To: <20210812065907.20046-1-rppt@kernel.org>
References: <20210812065907.20046-1-rppt@kernel.org>
Message-ID: <20210812065907.20046-3-rppt@kernel.org>

From: Mike Rapoport <rppt at linux.ibm.com>

There are a lot of uses of memblock_find_in_range() along with
memblock_reserve() from the times memblock allocation APIs did not exist.

memblock_find_in_range() is the very core of memblock allocations, so any
future changes to its internal behaviour would mandate updates of all the
users outside memblock.

Replace the calls to memblock_find_in_range() with an equivalent calls to
memblock_phys_alloc() and memblock_phys_alloc_range() and make
memblock_find_in_range() private method of memblock.

This simplifies the callers, ensures that (unlikely) errors in
memblock_reserve() are handled and improves maintainability of
memblock_find_in_range().

Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
Acked-by: Kirill A. Shutemov <kirill.shtuemov at linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
Acked-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Acked-by: Nick Kossifidis <mick at ics.forth.gr>
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm/kernel/setup.c           | 20 +++++---------
 arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
 arch/arm64/mm/init.c              | 36 ++++++++-----------------
 arch/mips/kernel/setup.c          | 14 +++++-----
 arch/riscv/mm/init.c              | 44 ++++++++++---------------------
 arch/s390/kernel/setup.c          | 10 ++++---
 arch/x86/kernel/aperture_64.c     |  5 ++--
 arch/x86/mm/init.c                | 11 ++++----
 arch/x86/mm/numa.c                |  5 ++--
 arch/x86/mm/numa_emulation.c      |  5 ++--
 arch/x86/realmode/init.c          |  2 +-
 drivers/acpi/tables.c             |  5 ++--
 drivers/base/arch_numa.c          |  5 +---
 drivers/of/of_reserved_mem.c      | 12 ++++++---
 include/linux/memblock.h          |  2 --
 mm/memblock.c                     |  2 +-
 16 files changed, 71 insertions(+), 116 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index f97eb2371672..284a80c0b6e1 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
 		unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
 		if (crash_max > lowmem_max)
 			crash_max = lowmem_max;
-		crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
-						    crash_size, CRASH_ALIGN);
+
+		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+						       CRASH_ALIGN, crash_max);
 		if (!crash_base) {
 			pr_err("crashkernel reservation failed - No suitable area found.\n");
 			return;
 		}
 	} else {
+		unsigned long long crash_max = crash_base + crash_size;
 		unsigned long long start;
 
-		start = memblock_find_in_range(crash_base,
-					       crash_base + crash_size,
-					       crash_size, SECTION_SIZE);
-		if (start != crash_base) {
+		start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
+						  crash_base, crash_max);
+		if (!start) {
 			pr_err("crashkernel reservation failed - memory is in use.\n");
 			return;
 		}
 	}
 
-	ret = memblock_reserve(crash_base, crash_size);
-	if (ret < 0) {
-		pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
-			(unsigned long)crash_base);
-		return;
-	}
-
 	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
 		(unsigned long)(crash_size >> 20),
 		(unsigned long)(crash_base >> 20),
diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c
index d654921dd09b..578670e3f608 100644
--- a/arch/arm64/kvm/hyp/reserved_mem.c
+++ b/arch/arm64/kvm/hyp/reserved_mem.c
@@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
 	 * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
 	 */
 	hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
-	hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
-					      ALIGN(hyp_mem_size, PMD_SIZE),
-					      PMD_SIZE);
+	hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
+					   PMD_SIZE);
 	if (!hyp_mem_base)
-		hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
-						      hyp_mem_size, PAGE_SIZE);
+		hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
 	else
 		hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
 
@@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
 		kvm_err("Failed to reserve hyp memory\n");
 		return;
 	}
-	memblock_reserve(hyp_mem_base, hyp_mem_size);
 
 	kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
 		 hyp_mem_base);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2917ff..0bffd2d1854f 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
 	unsigned long long crash_base, crash_size;
+	unsigned long long crash_max = arm64_dma_phys_limit;
 	int ret;
 
 	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
@@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
 
 	crash_size = PAGE_ALIGN(crash_size);
 
-	if (crash_base == 0) {
-		/* Current arm64 boot protocol requires 2MB alignment */
-		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
-				crash_size, SZ_2M);
-		if (crash_base == 0) {
-			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
-				crash_size);
-			return;
-		}
-	} else {
-		/* User specifies base address explicitly. */
-		if (!memblock_is_region_memory(crash_base, crash_size)) {
-			pr_warn("cannot reserve crashkernel: region is not memory\n");
-			return;
-		}
+	/* User specifies base address explicitly. */
+	if (crash_base)
+		crash_max = crash_base + crash_size;
 
-		if (memblock_is_region_reserved(crash_base, crash_size)) {
-			pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
-			return;
-		}
-
-		if (!IS_ALIGNED(crash_base, SZ_2M)) {
-			pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
-			return;
-		}
+	/* Current arm64 boot protocol requires 2MB alignment */
+	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
+					       crash_base, crash_max);
+	if (!crash_base) {
+		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
+			crash_size);
+		return;
 	}
-	memblock_reserve(crash_base, crash_size);
 
 	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 23a140327a0b..f979adfd4fc2 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -452,8 +452,9 @@ static void __init mips_parse_crashkernel(void)
 		return;
 
 	if (crash_base <= 0) {
-		crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX,
-							crash_size, CRASH_ALIGN);
+		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+						       CRASH_ALIGN,
+						       CRASH_ADDR_MAX);
 		if (!crash_base) {
 			pr_warn("crashkernel reservation failed - No suitable area found.\n");
 			return;
@@ -461,8 +462,9 @@ static void __init mips_parse_crashkernel(void)
 	} else {
 		unsigned long long start;
 
-		start = memblock_find_in_range(crash_base, crash_base + crash_size,
-						crash_size, 1);
+		start = memblock_phys_alloc_range(crash_size, 1,
+						  crash_base,
+						  crash_base + crash_size);
 		if (start != crash_base) {
 			pr_warn("Invalid memory region reserved for crash kernel\n");
 			return;
@@ -656,10 +658,6 @@ static void __init arch_mem_init(char **cmdline_p)
 	mips_reserve_vmcore();
 
 	mips_parse_crashkernel();
-#ifdef CONFIG_KEXEC
-	if (crashk_res.start != crashk_res.end)
-		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
-#endif
 	device_tree_init();
 
 	/*
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index a14bf3910eec..88649337c568 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -812,38 +812,22 @@ static void __init reserve_crashkernel(void)
 
 	crash_size = PAGE_ALIGN(crash_size);
 
-	if (crash_base == 0) {
-		/*
-		 * Current riscv boot protocol requires 2MB alignment for
-		 * RV64 and 4MB alignment for RV32 (hugepage size)
-		 */
-		crash_base = memblock_find_in_range(search_start, search_end,
-						    crash_size, PMD_SIZE);
-
-		if (crash_base == 0) {
-			pr_warn("crashkernel: couldn't allocate %lldKB\n",
-				crash_size >> 10);
-			return;
-		}
-	} else {
-		/* User specifies base address explicitly. */
-		if (!memblock_is_region_memory(crash_base, crash_size)) {
-			pr_warn("crashkernel: requested region is not memory\n");
-			return;
-		}
-
-		if (memblock_is_region_reserved(crash_base, crash_size)) {
-			pr_warn("crashkernel: requested region is reserved\n");
-			return;
-		}
-
+	if (crash_base) {
+		search_start = crash_base;
+		search_end = crash_base + crash_size;
+	}
 
-		if (!IS_ALIGNED(crash_base, PMD_SIZE)) {
-			pr_warn("crashkernel: requested region is misaligned\n");
-			return;
-		}
+	/*
+	 * Current riscv boot protocol requires 2MB alignment for
+	 * RV64 and 4MB alignment for RV32 (hugepage size)
+	 */
+	crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
+					       search_start, search_end);
+	if (crash_base == 0) {
+		pr_warn("crashkernel: couldn't allocate %lldKB\n",
+			crash_size >> 10);
+		return;
 	}
-	memblock_reserve(crash_base, crash_size);
 
 	pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index ff0f9e838916..3d9efee0f43c 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -626,8 +626,9 @@ static void __init reserve_crashkernel(void)
 			return;
 		}
 		low = crash_base ?: low;
-		crash_base = memblock_find_in_range(low, high, crash_size,
-						    KEXEC_CRASH_MEM_ALIGN);
+		crash_base = memblock_phys_alloc_range(crash_size,
+						       KEXEC_CRASH_MEM_ALIGN,
+						       low, high);
 	}
 
 	if (!crash_base) {
@@ -636,14 +637,15 @@ static void __init reserve_crashkernel(void)
 		return;
 	}
 
-	if (register_memory_notifier(&kdump_mem_nb))
+	if (register_memory_notifier(&kdump_mem_nb)) {
+		memblock_free(crash_base, crash_size);
 		return;
+	}
 
 	if (!OLDMEM_BASE && MACHINE_IS_VM)
 		diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
 	crashk_res.start = crash_base;
 	crashk_res.end = crash_base + crash_size - 1;
-	memblock_remove(crash_base, crash_size);
 	pr_info("Reserving %lluMB of memory at %lluMB "
 		"for crashkernel (System RAM: %luMB)\n",
 		crash_size >> 20, crash_base >> 20,
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 294ed4392a0e..10562885f5fc 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -109,14 +109,13 @@ static u32 __init allocate_aperture(void)
 	 * memory. Unfortunately we cannot move it up because that would
 	 * make the IOMMU useless.
 	 */
-	addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR,
-				      aper_size, aper_size);
+	addr = memblock_phys_alloc_range(aper_size, aper_size,
+					 GART_MIN_ADDR, GART_MAX_ADDR);
 	if (!addr) {
 		pr_err("Cannot allocate aperture memory hole [mem %#010lx-%#010lx] (%uKB)\n",
 		       addr, addr + aper_size - 1, aper_size >> 10);
 		return 0;
 	}
-	memblock_reserve(addr, aper_size);
 	pr_info("Mapping aperture over RAM [mem %#010lx-%#010lx] (%uKB)\n",
 		addr, addr + aper_size - 1, aper_size >> 10);
 	register_nosave_region(addr >> PAGE_SHIFT,
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 87150961fdca..18ed4332d707 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -26,6 +26,7 @@
 #include <asm/pti.h>
 #include <asm/text-patching.h>
 #include <asm/memtype.h>
+#include <xen/xen.h>
 
 /*
  * We need to define the tracepoints somewhere, and tlb.c
@@ -127,14 +128,12 @@ __ref void *alloc_low_pages(unsigned int num)
 		unsigned long ret = 0;
 
 		if (min_pfn_mapped < max_pfn_mapped) {
-			ret = memblock_find_in_range(
+			ret = memblock_phys_alloc_range(
+					PAGE_SIZE * num, PAGE_SIZE,
 					min_pfn_mapped << PAGE_SHIFT,
-					max_pfn_mapped << PAGE_SHIFT,
-					PAGE_SIZE * num , PAGE_SIZE);
+					max_pfn_mapped << PAGE_SHIFT);
 		}
-		if (ret)
-			memblock_reserve(ret, PAGE_SIZE * num);
-		else if (can_use_brk_pgt)
+		if (!ret && can_use_brk_pgt)
 			ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE));
 
 		if (!ret)
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index e94da744386f..a1b5c71099e6 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -376,15 +376,14 @@ static int __init numa_alloc_distance(void)
 	cnt++;
 	size = cnt * cnt * sizeof(numa_distance[0]);
 
-	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
-				      size, PAGE_SIZE);
+	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0,
+					 PFN_PHYS(max_pfn_mapped));
 	if (!phys) {
 		pr_warn("Warning: can't allocate distance table!\n");
 		/* don't retry until explicitly reset */
 		numa_distance = (void *)1LU;
 		return -ENOMEM;
 	}
-	memblock_reserve(phys, size);
 
 	numa_distance = __va(phys);
 	numa_distance_cnt = cnt;
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
index 87d77cc52f86..737491b13728 100644
--- a/arch/x86/mm/numa_emulation.c
+++ b/arch/x86/mm/numa_emulation.c
@@ -447,13 +447,12 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
 	if (numa_dist_cnt) {
 		u64 phys;
 
-		phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
-					      phys_size, PAGE_SIZE);
+		phys = memblock_phys_alloc_range(phys_size, PAGE_SIZE, 0,
+						 PFN_PHYS(max_pfn_mapped));
 		if (!phys) {
 			pr_warn("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
 			goto no_emu;
 		}
-		memblock_reserve(phys, phys_size);
 		phys_dist = __va(phys);
 
 		for (i = 0; i < numa_dist_cnt; i++)
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 6534c92d0f83..31b5856010cb 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -28,7 +28,7 @@ void __init reserve_real_mode(void)
 	WARN_ON(slab_is_available());
 
 	/* Has to be under 1M so we can execute real-mode AP code. */
-	mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
+	mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
 	if (!mem)
 		pr_info("No sub-1M memory is available for the trampoline\n");
 	else
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index a37a1532a575..f9383736fa0f 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -583,8 +583,8 @@ void __init acpi_table_upgrade(void)
 	}
 
 	acpi_tables_addr =
-		memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
-				       all_tables_size, PAGE_SIZE);
+		memblock_phys_alloc_range(all_tables_size, PAGE_SIZE,
+					  0, ACPI_TABLE_UPGRADE_MAX_PHYS);
 	if (!acpi_tables_addr) {
 		WARN_ON(1);
 		return;
@@ -599,7 +599,6 @@ void __init acpi_table_upgrade(void)
 	 * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
 	 * works fine.
 	 */
-	memblock_reserve(acpi_tables_addr, all_tables_size);
 	arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
 
 	/*
diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index 4cc4e117727d..46c503486e96 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -279,13 +279,10 @@ static int __init numa_alloc_distance(void)
 	int i, j;
 
 	size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
-	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
-				      size, PAGE_SIZE);
+	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, PFN_PHYS(max_pfn));
 	if (WARN_ON(!phys))
 		return -ENOMEM;
 
-	memblock_reserve(phys, size);
-
 	numa_distance = __va(phys);
 	numa_distance_cnt = nr_node_ids;
 
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index fd3964d24224..59c1390cdf42 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -33,18 +33,22 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
 	phys_addr_t *res_base)
 {
 	phys_addr_t base;
+	int err = 0;
 
 	end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
 	align = !align ? SMP_CACHE_BYTES : align;
-	base = memblock_find_in_range(start, end, size, align);
+	base = memblock_phys_alloc_range(size, align, start, end);
 	if (!base)
 		return -ENOMEM;
 
 	*res_base = base;
-	if (nomap)
-		return memblock_mark_nomap(base, size);
+	if (nomap) {
+		err = memblock_mark_nomap(base, size);
+		if (err)
+			memblock_free(base, size);
+	}
 
-	return memblock_reserve(base, size);
+	return err;
 }
 
 /*
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 4a53c3ca86bd..b066024c62e3 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -99,8 +99,6 @@ void memblock_discard(void);
 static inline void memblock_discard(void) {}
 #endif
 
-phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
-				   phys_addr_t size, phys_addr_t align);
 void memblock_allow_resize(void);
 int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
 int memblock_add(phys_addr_t base, phys_addr_t size);
diff --git a/mm/memblock.c b/mm/memblock.c
index de7b553baa50..28a813d9e955 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -315,7 +315,7 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
  * Return:
  * Found address on success, 0 on failure.
  */
-phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
+static phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
 					phys_addr_t end, phys_addr_t size,
 					phys_addr_t align)
 {
-- 
2.28.0



From tony at atomide.com  Thu Aug 12 00:03:42 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 12 Aug 2021 10:03:42 +0300
Subject: [GIT PULL 1/3] Two missed omap Kconfig patches for v5.15
Message-ID: <pull-1628751694-126144@atomide.com>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit 8d5a937f10ed091e14fc57a4158f59983e2934cf:

  MAINTAINERS: Adopt SanCloud dts files as supported (2021-07-27 11:54:52 +0300)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/soc-late-signed

for you to fetch changes up to 4297d1c0834af97fe992ec7bf766f0a262ce5ffc:

  arm: omap2: Drop the unused OMAP_PACKAGE_* KConfig entries (2021-08-06 09:40:26 +0300)

----------------------------------------------------------------
Two missed SoC changes for omaps for v5.15

I managed to miss applying two out of three Kconfig changes earlier
to drop unused entries, here are the missed changes.

----------------------------------------------------------------
Peter Robinson (2):
      arm: omap2: Drop obsolete MACH_OMAP3_PANDORA entry
      arm: omap2: Drop the unused OMAP_PACKAGE_* KConfig entries

 arch/arm/mach-omap2/Kconfig | 18 ------------------
 1 file changed, 18 deletions(-)


From tony at atomide.com  Thu Aug 12 00:03:43 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 12 Aug 2021 10:03:43 +0300
Subject: [GIT PULL 2/3] Drop pm_runtime_irq_safe() for smartreflex for v5.15
In-Reply-To: <pull-1628751694-126144@atomide.com>
References: <pull-1628751694-126144@atomide.com>
Message-ID: <pull-1628751694-126144@atomide.com-2>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit fdc07ca0724dd8ad00c22909a1464dc73ed6783e:

  Merge branch 'omap-for-v5.14/ti-sysc' into omap-for-v5.15/ti-sysc (2021-07-27 12:02:24 +0300)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/sr-signed

for you to fetch changes up to 74953a9136cfd650dd994daded520528f737b7b3:

  soc: ti: Remove pm_runtime_irq_safe() usage for smartreflex (2021-08-06 09:53:59 +0300)

----------------------------------------------------------------
Drop pm_runtime_irq_safe() usage for smartreflex for v5.15

We now have cleard pm_runtime_irq_safe() usage for all TI SoCs
in Linux next except for smartreflex and 8250_omap. This change
removes pm_runtime_irq_safe() usage for smartreflex, the
8250_omap depends on pending serial layer PM changes.

----------------------------------------------------------------
Tony Lindgren (1):
      soc: ti: Remove pm_runtime_irq_safe() usage for smartreflex

 drivers/bus/ti-sysc.c             |  6 ++---
 drivers/soc/ti/smartreflex.c      | 52 +++++++++++++++++----------------------
 include/linux/power/smartreflex.h |  2 ++
 3 files changed, 26 insertions(+), 34 deletions(-)


From tony at atomide.com  Thu Aug 12 00:03:44 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 12 Aug 2021 10:03:44 +0300
Subject: [GIT PULL 3/3] Changes for am3 cpsw and SanCloud for v5.15
In-Reply-To: <pull-1628751694-126144@atomide.com>
References: <pull-1628751694-126144@atomide.com>
Message-ID: <pull-1628751694-126144@atomide.com-3>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit 8c054cd2818ea08555efe24a2ffde330833c2f3f:

  ARM: dts: am57xx: Add PRUSS MDIO controller nodes (2021-08-03 15:25:14 +0300)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/dt-am3-signed

for you to fetch changes up to 29fabf5274bfb89124918840c79851659a25ba79:

  ARM: dts: am335x-sancloud-bbe: Drop usb wifi comment (2021-08-10 09:52:41 +0300)

----------------------------------------------------------------
Changes for am3 cpsw and SanCloud for v5.15

A series of changes to update am3 to use cpsw switch driver and
few updates to earlier SanCloud changes. The plan was to send the
cpsw switch driver changes earlier but looks like I never tagged
the mail thread in my inbox to apply for v5.15.

----------------------------------------------------------------
Grygorii Strashko (16):
      ARM: dts: am335x-baltos: switch to new cpsw switch drv
      ARM: dts: am335x-nano: switch to new cpsw switch drv
      ARM: dts: am335x-chiliboard: switch to new cpsw switch drv
      ARM: dts: am335x-cm-t335: switch to new cpsw switch drv
      ARM: dts: am335x-igep0033: switch to new cpsw switch drv
      ARM: dts: am335x-lxm: switch to new cpsw switch drv
      ARM: dts: am335x-moxa-uc: switch to new cpsw switch drv
      ARM: dts: am335x-myirtech: switch to new cpsw switch drv
      ARM: dts: am335x-osd3358-sm-red: switch to new cpsw switch drv
      ARM: dts: am335x-pdu001: switch to new cpsw switch drv
      ARM: dts: am335x-pepper: switch to new cpsw switch drv
      ARM: dts: am335x-phycore: switch to new cpsw switch drv
      ARM: dts: am335x-shc: switch to new cpsw switch drv
      ARM: dts: am335x-sl50: switch to new cpsw switch drv
      ARM: dts: am33xx: update ethernet aliases
      ARM: dts: am335x-bone: switch to new cpsw switch drv

Paul Barker (2):
      ARM: dts: am335x-sancloud-bbe: Fix missing pinctrl refs
      ARM: dts: am335x-sancloud-bbe: Drop usb wifi comment

 arch/arm/boot/dts/am335x-baltos-ir2110.dts        | 10 +++---
 arch/arm/boot/dts/am335x-baltos-ir3220.dts        |  8 ++---
 arch/arm/boot/dts/am335x-baltos-ir5221.dts        |  8 ++---
 arch/arm/boot/dts/am335x-baltos.dtsi              |  5 ++-
 arch/arm/boot/dts/am335x-bone-common.dtsi         | 13 +++++---
 arch/arm/boot/dts/am335x-boneblack-wireless.dts   |  2 +-
 arch/arm/boot/dts/am335x-bonegreen-wireless.dts   |  2 +-
 arch/arm/boot/dts/am335x-chiliboard.dts           | 13 +++++---
 arch/arm/boot/dts/am335x-cm-t335.dts              | 13 +++++---
 arch/arm/boot/dts/am335x-igep0033.dtsi            | 12 +++----
 arch/arm/boot/dts/am335x-lxm.dts                  | 14 ++++-----
 arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi | 12 +++----
 arch/arm/boot/dts/am335x-moxa-uc-2101.dts         |  7 ++---
 arch/arm/boot/dts/am335x-moxa-uc-8100-common.dtsi | 16 ++++------
 arch/arm/boot/dts/am335x-myirtech-myc.dtsi        | 25 ++++++++-------
 arch/arm/boot/dts/am335x-myirtech-myd.dts         | 18 ++++++-----
 arch/arm/boot/dts/am335x-nano.dts                 | 13 ++++----
 arch/arm/boot/dts/am335x-netcan-plus-1xx.dts      | 10 +++---
 arch/arm/boot/dts/am335x-netcom-plus-2xx.dts      | 10 +++---
 arch/arm/boot/dts/am335x-netcom-plus-8xx.dts      | 10 +++---
 arch/arm/boot/dts/am335x-osd3358-sm-red.dts       | 13 +++++---
 arch/arm/boot/dts/am335x-pcm-953.dtsi             | 10 +++---
 arch/arm/boot/dts/am335x-pdu001.dts               | 14 ++++-----
 arch/arm/boot/dts/am335x-pepper.dts               | 14 ++++-----
 arch/arm/boot/dts/am335x-phycore-som.dtsi         | 14 +++++----
 arch/arm/boot/dts/am335x-regor.dtsi               | 11 +++----
 arch/arm/boot/dts/am335x-sancloud-bbe-common.dtsi | 37 +++-------------------
 arch/arm/boot/dts/am335x-sancloud-bbe.dts         |  4 +++
 arch/arm/boot/dts/am335x-shc.dts                  | 38 +++++++++++++----------
 arch/arm/boot/dts/am335x-sl50.dts                 | 12 ++++---
 arch/arm/boot/dts/am335x-wega.dtsi                | 11 +++----
 arch/arm/boot/dts/am33xx.dtsi                     |  4 +--
 32 files changed, 194 insertions(+), 209 deletions(-)


From steen.hegelund at microchip.com  Thu Aug 12 00:04:24 2021
From: steen.hegelund at microchip.com (Steen Hegelund)
Date: Thu, 12 Aug 2021 09:04:24 +0200
Subject: [PATCH net-next 1/2] net: sparx5: switchdev: adding frame DMA
 functionality
In-Reply-To: <20210811153132.63480934@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
References: <20210811075909.543633-1-steen.hegelund@microchip.com>
 <20210811075909.543633-2-steen.hegelund@microchip.com>
 <20210811153132.63480934@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
Message-ID: <e37f35e5ec73a7b7a3d6f692e0764411e74c7486.camel@microchip.com>

Hej Jacub,

On Wed, 2021-08-11 at 15:31 -0700, Jakub Kicinski wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Wed, 11 Aug 2021 09:59:08 +0200 Steen Hegelund wrote:
> > This add frame DMA functionality to the Sparx5 platform.
> > 
> > Ethernet frames can be extracted or injected autonomously to or from the
> > device?s DDR3/DDR3L memory and/or PCIe memory space. Linked list data
> > structures in memory are used for injecting or extracting Ethernet frames.
> > The FDMA generates interrupts when frame extraction or injection is done
> > and when the linked lists need updating.
> 
> Something to fix:
> 
> drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c: In function ?sparx5_fdma_start?:
> drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c:544:6: warning: variable ?proc_ctrl? set but
> not used [-Wunused-but-set-variable]
> ? 544 |? u32 proc_ctrl;
> ????? |????? ^~~~~~~~~

Will do.

Thanks for the review.

BR
Steen



From lkp at intel.com  Thu Aug 12 00:10:31 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 15:10:31 +0800
Subject: [xlnx:xlnx_rebase_v5.10 861/1760] drivers/hwmon/pmbus/tps544.c:67:9:
 error: too few arguments to function 'pmbus_read_word_data'
Message-ID: <202108121524.pETrSFGP-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   bf98c1493fb23bfd7e2678498b7e337ce2cd1d53
commit: 0bae0f6f49084612f2df5dc148733573fc96f863 [861/1760] pmbus: Add new tps544 power regulator driver
config: m68k-randconfig-r014-20210812 (attached as .config)
compiler: m68k-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/0bae0f6f49084612f2df5dc148733573fc96f863
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 0bae0f6f49084612f2df5dc148733573fc96f863
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash drivers/hwmon/pmbus/ drivers/irqchip/ drivers/misc/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/hwmon/pmbus/tps544.c: In function 'tps544_read_word_data':
>> drivers/hwmon/pmbus/tps544.c:67:9: error: too few arguments to function 'pmbus_read_word_data'
      67 |  return pmbus_read_word_data(client, page, reg);
         |         ^~~~~~~~~~~~~~~~~~~~
   In file included from drivers/hwmon/pmbus/tps544.c:16:
   drivers/hwmon/pmbus/pmbus.h:479:5: note: declared here
     479 | int pmbus_read_word_data(struct i2c_client *client, int page, int phase,
         |     ^~~~~~~~~~~~~~~~~~~~
   drivers/hwmon/pmbus/tps544.c: In function 'tps544_probe':
>> drivers/hwmon/pmbus/tps544.c:287:23: error: assignment to 'int (*)(struct i2c_client *, int,  int,  int)' from incompatible pointer type 'int (*)(struct i2c_client *, int,  int)' [-Werror=incompatible-pointer-types]
     287 |  info->read_word_data = tps544_read_word_data;
         |                       ^
>> drivers/hwmon/pmbus/tps544.c:320:32: error: passing argument 2 of 'pmbus_do_probe' from incompatible pointer type [-Werror=incompatible-pointer-types]
     320 |  return pmbus_do_probe(client, id, info);
         |                                ^~
         |                                |
         |                                const struct i2c_device_id *
   In file included from drivers/hwmon/pmbus/tps544.c:16:
   drivers/hwmon/pmbus/pmbus.h:492:73: note: expected 'struct pmbus_driver_info *' but argument is of type 'const struct i2c_device_id *'
     492 | int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info);
         |                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
>> drivers/hwmon/pmbus/tps544.c:320:9: error: too many arguments to function 'pmbus_do_probe'
     320 |  return pmbus_do_probe(client, id, info);
         |         ^~~~~~~~~~~~~~
   In file included from drivers/hwmon/pmbus/tps544.c:16:
   drivers/hwmon/pmbus/pmbus.h:492:5: note: declared here
     492 | int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info);
         |     ^~~~~~~~~~~~~~
   drivers/hwmon/pmbus/tps544.c: In function 'tps544_read_word_data':
   drivers/hwmon/pmbus/tps544.c:68:1: error: control reaches end of non-void function [-Werror=return-type]
      68 | }
         | ^
   cc1: some warnings being treated as errors


vim +/pmbus_read_word_data +67 drivers/hwmon/pmbus/tps544.c

    64	
    65	static int tps544_read_word_data(struct i2c_client *client, int page, int reg)
    66	{
  > 67		return pmbus_read_word_data(client, page, reg);
    68	}
    69	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 28829 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/cd70549c/attachment-0001.gz>

From maz at kernel.org  Thu Aug 12 00:26:48 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 08:26:48 +0100
Subject: [PATCH v3 05/13] genirq: Let purely flow-masked ONESHOT irqs
 through unmask_threaded_irq()
In-Reply-To: <20210629125010.458872-6-valentin.schneider@arm.com>
References: <20210629125010.458872-1-valentin.schneider@arm.com>
 <20210629125010.458872-6-valentin.schneider@arm.com>
Message-ID: <87bl639l8n.wl-maz@kernel.org>

On Tue, 29 Jun 2021 13:50:02 +0100,
Valentin Schneider <valentin.schneider at arm.com> wrote:
> 
> A subsequent patch will let IRQs end up in irq_finalize_oneshot() without
> IRQD_IRQ_MASKED, but with IRQD_IRQ_FLOW_MASKED set instead. Let such IRQs
> receive their final ->irq_eoi().
> 
> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
> ---
>  kernel/irq/manage.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> index ef30b4762947..e6d6d32ddcbc 100644
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -1107,7 +1107,7 @@ static void irq_finalize_oneshot(struct irq_desc *desc,
>  	desc->threads_oneshot &= ~action->thread_mask;
>  
>  	if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) &&
> -	    irqd_irq_masked(&desc->irq_data))
> +	    (irqd_irq_masked(&desc->irq_data) | irqd_irq_flow_masked(&desc->irq_data)))
>  		unmask_threaded_irq(desc);

The bitwise OR looks pretty odd. It is probably fine given that both
side of the expression are bool, but still. I can fix this locally.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From zajec5 at gmail.com  Thu Aug 12 00:32:02 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Thu, 12 Aug 2021 09:32:02 +0200
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <87czqj9mvo.wl-maz@kernel.org>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
Message-ID: <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>

On 12.08.2021 08:51, Marc Zyngier wrote:
> Interestingly, all your CPUs are booting at EL2. Which is great.  Can
> you try and enable KVM on your existing 5.10 kernel? Just selecting
> CONFIG_KVM should be enough. Does it boot correctly with KVM enabled?
> 
> My suspicion is that the firmware doesn't set SCR_EL3.HCE, and that
> the HVC instruction UNDEFs at EL1. That would be bad news.

Interesting! I had to enable CONFIG_VIRTUALIZATION and CONFIG_NET first.
First I verified kernel built with those options still boots. It does.

Then I enabled CONFIG_KVM and kernel seems to hang around switching from
bootconsole to the console.

Starting program at 0x0000000000080000
/memory = 0x40000000
WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
Booting Linux on physical CPU 0x0000000000 [0x420f1000]
Linux version 5.11.22-g0453a426c37b (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #8 SMP Thu Aug 12 09:25:55 CEST 2021
Machine model: Asus GT-AC5300
earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
printk: bootconsole [bcm63xx_uart0] enabled
efi: UEFI not found.
[Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
Zone ranges:
   DMA      [mem 0x0000000000000000-0x000000003fffffff]
   DMA32    empty
   Normal   empty
Movable zone start for each node
Early memory node ranges
   node   0: [mem 0x0000000000000000-0x000000003fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
percpu: Embedded 18 pages/cpu s43904 r0 d29824 u73728
Detected VIPT I-cache on CPU0
CPU features: detected: ARM erratum 843419
Built 1 zonelists, mobility grouping on.  Total pages: 258048
Kernel command line: earlycon=bcm63xx_uart,0xff800640
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 1019556K/1048576K available (4352K kernel code, 678K rwdata, 860K rodata, 2496K init, 232K bss, 29020K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
GIC: Using split EOI/Deactivate mode
random: get_random_bytes called from start_kernel+0x33c/0x52c with crng_init=0
arch_timer: cp15 timer(s) running at 50.00MHz (phys).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
Console: colour dummy device 80x25
printk: console [tty0] enabled
printk: bootconsole [bcm63xx_uart0] disabled


(Unless it's a false conclusion and CONFIG_KVM just breaks console
somehow)


Enabling CONFIG_KVM resulted in enablig few more options but I believe
it's actually CONFIG_KVM itself that affects booting process.

--- config-nokvm        2021-08-12 09:21:50.670046231 +0200
+++ config-kvm  2021-08-12 09:22:35.897103038 +0200
@@ -292,6 +292,7 @@
  CONFIG_ARM64_ERRATUM_824069=y
  CONFIG_ARM64_ERRATUM_819472=y
  CONFIG_ARM64_ERRATUM_832075=y
+CONFIG_ARM64_ERRATUM_834220=y
  CONFIG_ARM64_ERRATUM_843419=y
  CONFIG_ARM64_ERRATUM_1024718=y
  CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
@@ -502,8 +503,21 @@

  CONFIG_ARCH_SUPPORTS_ACPI=y
  # CONFIG_ACPI is not set
+CONFIG_IRQ_BYPASS_MANAGER=y
  CONFIG_VIRTUALIZATION=y
-# CONFIG_KVM is not set
+CONFIG_KVM=y
+CONFIG_HAVE_KVM_IRQCHIP=y
+CONFIG_HAVE_KVM_IRQFD=y
+CONFIG_HAVE_KVM_IRQ_ROUTING=y
+CONFIG_HAVE_KVM_EVENTFD=y
+CONFIG_KVM_MMIO=y
+CONFIG_HAVE_KVM_MSI=y
+CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
+CONFIG_KVM_VFIO=y
+CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y
+CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
+CONFIG_HAVE_KVM_IRQ_BYPASS=y
+CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y

  #
  # General architecture-dependent options
@@ -616,6 +630,7 @@
  # CONFIG_IOSCHED_BFQ is not set
  # end of IO Schedulers

+CONFIG_PREEMPT_NOTIFIERS=y
  CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y
  CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y
  CONFIG_ARCH_INLINE_SPIN_LOCK=y
@@ -712,6 +727,7 @@
  CONFIG_MIGRATION=y
  CONFIG_PHYS_ADDR_T_64BIT=y
  CONFIG_BOUNCE=y
+CONFIG_MMU_NOTIFIER=y
  # CONFIG_KSM is not set
  CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
  CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
@@ -2508,6 +2524,7 @@
  CONFIG_DECOMPRESS_LZ4=y
  CONFIG_DECOMPRESS_ZSTD=y
  CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_INTERVAL_TREE=y
  CONFIG_HAS_IOMEM=y
  CONFIG_HAS_IOPORT_MAP=y
  CONFIG_HAS_DMA=y


From wsa at kernel.org  Thu Aug 12 00:39:43 2021
From: wsa at kernel.org (Wolfram Sang)
Date: Thu, 12 Aug 2021 09:39:43 +0200
Subject: [PATCH v5 1/3] i2c: aspeed: Add slave_enable() to toggle slave
 mode
In-Reply-To: <20210714033833.11640-2-quan@os.amperecomputing.com>
References: <20210714033833.11640-1-quan@os.amperecomputing.com>
 <20210714033833.11640-2-quan@os.amperecomputing.com>
Message-ID: <YRTQP9sX0hkTJMTx@shikoro>

Hi all,

On Wed, Jul 14, 2021 at 10:38:31AM +0700, Quan Nguyen wrote:
> Slave needs time to prepare the response data before Master could
> enquiry via read transaction. However, there is no mechanism for
> i2c-aspeed Slave to notify Master that it needs more time to process
> and this make Master side to time out when trying to get the response.
> 
> This commit introduces the slave_enable() callback in struct
> i2c_algorithm for Slave to temporary stop the Slave mode while working
> on the response and re-enable the Slave when response data ready.

Sorry that I couldn't chime in earlier, but NAK!

>  include/linux/i2c.h             |  2 ++

@Corey: Please do not change this file without my ACK. It is not a
trivial change but an API extenstion and that should really be acked by
the subsystem maintainer, in this case me. I was really surprised to see
this in linux-next already.

@all: Plus, I neither like the API (because it doesn't look generic to
me but mostly handling one issue needed here) nor do I fully understand
the use case. Normally, when a read is requested and the backend needs
time to deliver the data, the hardware should stretch the SCL clock
until some data register is finally written to. If it doesn't do it for
whatever reason, this is a quirky hardware in my book and needs handling
in the driver only. So, what is special with this HW? Can't we solve it
differently?

All the best,

   Wolfram

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/538be065/attachment.sig>

From maz at kernel.org  Thu Aug 12 00:49:05 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 08:49:05 +0100
Subject: [PATCH v3 02/13] genirq: Define ack_irq() and eoi_irq() helpers
In-Reply-To: <20210629125010.458872-3-valentin.schneider@arm.com>
References: <20210629125010.458872-1-valentin.schneider@arm.com>
 <20210629125010.458872-3-valentin.schneider@arm.com>
Message-ID: <87a6ln9k7i.wl-maz@kernel.org>

On Tue, 29 Jun 2021 13:49:59 +0100,
Valentin Schneider <valentin.schneider at arm.com> wrote:
> 
> The newly-added IRQCHIP_AUTOMASKS_FLOW flag requires some additional
> bookkeeping around chip->{irq_ack, irq_eoi}() calls. Define wrappers around
> those chip callbacks to drive the IRQD_IRQ_FLOW_MASKED state of an IRQ when
> the chip has the IRQCHIP_AUTOMASKS_FLOW flag.
> 
> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
> ---
>  kernel/irq/chip.c      | 16 ++++++++++++++++
>  kernel/irq/internals.h |  2 ++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> index 21a21baa1366..793dbd8307b9 100644
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -408,6 +408,22 @@ void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
>  	cpumask_clear_cpu(cpu, desc->percpu_enabled);
>  }
>  
> +void ack_irq(struct irq_desc *desc)
> +{
> +	desc->irq_data.chip->irq_ack(&desc->irq_data);
> +
> +	if (desc->irq_data.chip->flags & IRQCHIP_AUTOMASKS_FLOW)
> +		irq_state_set_flow_masked(desc);
> +}
> +
> +void eoi_irq(struct irq_desc *desc)
> +{
> +	desc->irq_data.chip->irq_eoi(&desc->irq_data);
> +
> +	if (desc->irq_data.chip->flags & IRQCHIP_AUTOMASKS_FLOW)
> +		irq_state_clr_flow_masked(desc);

I just realised that this has a good chance to result in a mess with
KVM, and specially the way we let the vGIC deactivate an interrupt
directly from the guest, without any SW intervention (the magic HW bit
in the LRs).

With this, interrupts routed to a guest (such as the timers) will
always have the IRQD_IRQ_FLOW_MASKED flag set, which will never be
cleared.

I wonder whether this have a chance to interact badly with
mask/unmask, or with the rest of the flow...

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From tony at atomide.com  Thu Aug 12 00:53:25 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 12 Aug 2021 10:53:25 +0300
Subject: [GIT PULL] soc: Keystone driver update for v5.15
In-Reply-To: <0A637A41-2353-4900-962C-DBE50BBDE75A@oracle.com>
References: <0A637A41-2353-4900-962C-DBE50BBDE75A@oracle.com>
Message-ID: <YRTTdcg+lj1/vH0L@atomide.com>

* Santosh Shilimkar <santosh.shilimkar at oracle.com> [210810 23:47]:
> Tony Lindgren (1):
>       soc: ti: Remove pm_runtime_irq_safe() usage for smartreflex

Thanks for picking this one up, I also just sent a pull request for it,
my pull request can now be just ignored as that's a single commit
in it.

Regards,

Tony


From tony at atomide.com  Thu Aug 12 00:54:56 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 12 Aug 2021 10:54:56 +0300
Subject: [GIT PULL 2/3] Drop pm_runtime_irq_safe() for smartreflex for
 v5.15
In-Reply-To: <pull-1628751694-126144@atomide.com-2>
References: <pull-1628751694-126144@atomide.com>
 <pull-1628751694-126144@atomide.com-2>
Message-ID: <YRTT0Oejj22qNAL+@atomide.com>

Hi,

* Tony Lindgren <tony at atomide.com> [210812 07:04]:
> From: "Tony Lindgren" <tony at atomide.com>
> 
> The following changes since commit fdc07ca0724dd8ad00c22909a1464dc73ed6783e:
> 
>   Merge branch 'omap-for-v5.14/ti-sysc' into omap-for-v5.15/ti-sysc (2021-07-27 12:02:24 +0300)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/sr-signed
> 
> for you to fetch changes up to 74953a9136cfd650dd994daded520528f737b7b3:
> 
>   soc: ti: Remove pm_runtime_irq_safe() usage for smartreflex (2021-08-06 09:53:59 +0300)
> 
> ----------------------------------------------------------------
> Drop pm_runtime_irq_safe() usage for smartreflex for v5.15
> 
> We now have cleard pm_runtime_irq_safe() usage for all TI SoCs
> in Linux next except for smartreflex and 8250_omap. This change
> removes pm_runtime_irq_safe() usage for smartreflex, the
> 8250_omap depends on pending serial layer PM changes.

Looks like Santosh already queued up this patch and sent a pull request,
so my pull request for this change can be just ignored.

Regrds,

Tony


> ----------------------------------------------------------------
> Tony Lindgren (1):
>       soc: ti: Remove pm_runtime_irq_safe() usage for smartreflex
> 
>  drivers/bus/ti-sysc.c             |  6 ++---
>  drivers/soc/ti/smartreflex.c      | 52 +++++++++++++++++----------------------
>  include/linux/power/smartreflex.h |  2 ++
>  3 files changed, 26 insertions(+), 34 deletions(-)


From zajec5 at gmail.com  Thu Aug 12 00:56:57 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Thu, 12 Aug 2021 09:56:57 +0200
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
Message-ID: <7fee376c-2099-6d88-0be8-ba57633e0965@gmail.com>

On 12.08.2021 09:32, Rafa? Mi?ecki wrote:
> (Unless it's a false conclusion and CONFIG_KVM just breaks console
> somehow)

That was a false conclusion. I modified kernel/printk/printk.c and set
keep_bootcon = 1

A full log with important part below:

Starting program at 0x0000000000080000
/memory = 0x40000000
WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
Booting Linux on physical CPU 0x0000000000 [0x420f1000]
Linux version 5.11.22-g0453a426c37b-dirty (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #12 SMP Thu Aug 12 09:54:11 CEST 2021
Machine model: Asus GT-AC5300
earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
printk: bootconsole [bcm63xx_uart0] enabled
efi: UEFI not found.
[Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
Zone ranges:
   DMA      [mem 0x0000000000000000-0x000000003fffffff]
   DMA32    empty
   Normal   empty
Movable zone start for each node
Early memory node ranges
   node   0: [mem 0x0000000000000000-0x000000003fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
percpu: Embedded 18 pages/cpu s43904 r0 d29824 u73728
Detected VIPT I-cache on CPU0
CPU features: detected: ARM erratum 843419
Built 1 zonelists, mobility grouping on.  Total pages: 258048
Kernel command line: earlycon=bcm63xx_uart,0xff800640
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 1019556K/1048576K available (4352K kernel code, 678K rwdata, 860K rodata, 2496K init, 232K bss, 29020K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
GIC: Using split EOI/Deactivate mode
random: get_random_bytes called from start_kernel+0x33c/0x52c with crng_init=0
arch_timer: cp15 timer(s) running at 50.00MHz (phys).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
Console: colour dummy device 80x25
printk: console [tty0] enabled
Calibrating delay loop (skipped), value calculated using timer frequency.. 100.00 BogoMIPS (lpj=200000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
rcu: Hierarchical SRCU implementation.
EFI services will not be available.
smp: Bringing up secondary CPUs ...
Detected VIPT I-cache on CPU1
CPU1: Booted secondary processor 0x0000000001 [0x420f1000]
Detected VIPT I-cache on CPU2
CPU2: Booted secondary processor 0x0000000002 [0x420f1000]
Detected VIPT I-cache on CPU3
CPU3: Booted secondary processor 0x0000000003 [0x420f1000]
smp: Brought up 1 node, 4 CPUs
SMP: Total of 4 processors activated.
CPU features: detected: 32-bit EL0 Support
CPU features: detected: CRC32 instructions
CPU features: detected: 32-bit EL1 Support
CPU: All CPU(s) started at EL2
alternatives: patching kernel code
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
pinctrl core: initialized pinctrl subsystem
DMI not present or invalid.
NET: Registered protocol family 16
DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
thermal_sys: Registered thermal governor 'step_wise'
ASID allocator initialised with 65536 entries
iommu: Default domain type: Translated
vgaarb: loaded
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
clocksource: Switched to clocksource arch_sys_counter
PCI: CLS 0 bytes, default 64
kvm [1]: IPA Size Limit: 40 bits
------------[ cut here ]------------
------------[ cut here ]------------
------------[ cut here ]------------
kernel BUG at arch/arm64/kernel/traps.c:406!
kernel BUG at arch/arm64/kernel/traps.c:406!
Internal error: Oops - BUG: 0 [#1] SMP
CPU: 3 PID: 0 Comm: swapper/3 Not tainted 5.11.22-g0453a426c37b-dirty #12
Hardware name: Asus GT-AC5300 (DT)
pstate: 00000085 (nzcv daIf -PAN -UAO -TCO BTYPE=--)
pc : do_undefinstr+0x204/0x230
lr : do_undefinstr+0x218/0x230
sp : ffffffc01001bcc0
x29: ffffffc01001bcc0 x28: ffffff80010a0a80
x27: 00000000000000e0 x26: ffffffc01001c000
x25: ffffffc010018000 x24: ffffffc0108a9000
x23: 0000000080000085 x22: 00000000d4000002
x21: ffffffc0108cd0d8 x20: ffffff80010a0a80
x19: ffffffc01001bd40 x18: 0000000000000030
x17: fbfffafbffffffff x16: 0000000000000048
x15: 0000046366960998 x14: 0000000000000017
x13: 0000000000000001 x12: 0000000000000001
x11: 0000000000000000 x10: 0000000000000003
x9 : 0000000000000000 x8 : 0000000000000000
x7 : ffffff803fde8600 x6 : 0000000000000001
x5 : 0000000000000000 x4 : ffffff80010a0a80
x3 : 00000000d5300000 x2 : ffffffc01082ce68
x1 : ffffffc0108cd0e8 x0 : 0000000080000085
Call trace:
  do_undefinstr+0x204/0x230
  el1_undef+0x30/0x50
  el1_sync_handler+0x8c/0xd0
  el1_sync+0x78/0x100
  __hyp_reset_vectors+0x4/0x91d0
  _kvm_arch_hardware_enable+0x3c/0x60
  flush_smp_call_function_queue+0x14c/0x260
  generic_smp_call_function_single_interrupt+0x14/0x20
  ipi_handler+0x9c/0xd0
  handle_percpu_devid_irq+0x84/0x150
  generic_handle_irq+0x34/0x50
  __handle_domain_irq+0x64/0xc0
  gic_handle_irq+0x78/0xa0
  el1_irq+0xbc/0x140
  arch_cpu_idle+0x18/0x30
  default_idle_call+0x20/0x70
  do_idle+0xc8/0x130
  cpu_startup_entry+0x24/0x50
  secondary_start_kernel+0x130/0x160
Code: 9a81d000 d50342df 17ffffa3 f9001bf7 (d4210000)
---[ end trace 6a2bdc7bc6eb54af ]---
Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt
SMP: stopping secondary CPUs
kernel BUG at arch/arm64/kernel/traps.c:406!
SMP: failed to stop secondary CPUs 1-3
Kernel Offset: disabled
CPU features: 0x00240002,24002000
Memory Limit: none
---[ end Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt ]---


From maz at kernel.org  Thu Aug 12 00:57:57 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 08:57:57 +0100
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
Message-ID: <878s179jsq.wl-maz@kernel.org>

On Thu, 12 Aug 2021 08:32:02 +0100,
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> 
> On 12.08.2021 08:51, Marc Zyngier wrote:
> > Interestingly, all your CPUs are booting at EL2. Which is great.  Can
> > you try and enable KVM on your existing 5.10 kernel? Just selecting
> > CONFIG_KVM should be enough. Does it boot correctly with KVM enabled?
> > 
> > My suspicion is that the firmware doesn't set SCR_EL3.HCE, and that
> > the HVC instruction UNDEFs at EL1. That would be bad news.
> 
> Interesting! I had to enable CONFIG_VIRTUALIZATION and CONFIG_NET first.
> First I verified kernel built with those options still boots. It does.
> 
> Then I enabled CONFIG_KVM and kernel seems to hang around switching from
> bootconsole to the console.
> 
> Starting program at 0x0000000000080000
> /memory = 0x40000000
> WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
> WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
> WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
> Booting Linux on physical CPU 0x0000000000 [0x420f1000]
> Linux version 5.11.22-g0453a426c37b (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #8 SMP Thu Aug 12 09:25:55 CEST 2021
> Machine model: Asus GT-AC5300
> earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
> printk: bootconsole [bcm63xx_uart0] enabled
> efi: UEFI not found.
> [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
> Zone ranges:
>   DMA      [mem 0x0000000000000000-0x000000003fffffff]
>   DMA32    empty
>   Normal   empty
> Movable zone start for each node
> Early memory node ranges
>   node   0: [mem 0x0000000000000000-0x000000003fffffff]
> Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
> percpu: Embedded 18 pages/cpu s43904 r0 d29824 u73728
> Detected VIPT I-cache on CPU0
> CPU features: detected: ARM erratum 843419
> Built 1 zonelists, mobility grouping on.  Total pages: 258048
> Kernel command line: earlycon=bcm63xx_uart,0xff800640
> Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
> Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
> mem auto-init: stack:off, heap alloc:off, heap free:off
> Memory: 1019556K/1048576K available (4352K kernel code, 678K rwdata, 860K rodata, 2496K init, 232K bss, 29020K reserved, 0K cma-reserved)
> SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
> rcu: Hierarchical RCU implementation.
> rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
> NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
> GIC: Using split EOI/Deactivate mode
> random: get_random_bytes called from start_kernel+0x33c/0x52c with crng_init=0
> arch_timer: cp15 timer(s) running at 50.00MHz (phys).
> clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
> sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
> Console: colour dummy device 80x25
> printk: console [tty0] enabled
> printk: bootconsole [bcm63xx_uart0] disabled
> 
> 
> (Unless it's a false conclusion and CONFIG_KVM just breaks console
> somehow)

No, that's because you don't pass the right console to your
kernel. Add something like "console=ttyS0,115200" to the kernel
command line, which will show what you are missing, as well as stop
the double-logging.

Anyway, the fact that it stops booting when you enable KVM confirms my
suspicion. The firmware on this system is probably crap enough not to
enable HVC. Let's confirm it further: please apply the patch below on
top of mainline and tell me that it now boots fine...

Are you in a position where you can actually fix the firmware? Or is
it some closed-source blob?

Broadcom folks: can you lease check whether the firmware on this
system correctly configures SCR_EL3.HCE?

Thanks,

	M.

diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 43d212618834..fc95b103ef42 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -238,7 +238,7 @@ SYM_FUNC_START(switch_to_vhe)
 
 	// Turn the world upside down
 	mov	x0, #HVC_VHE_RESTART
-	hvc	#0
+//	hvc	#0
 1:
 	ret
 SYM_FUNC_END(switch_to_vhe)

-- 
Without deviation from the norm, progress is not possible.


From lkp at intel.com  Thu Aug 12 01:02:08 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 16:02:08 +0800
Subject: [xlnx:xlnx_rebase_v5.10 917/1761]
 drivers/misc/jesd204b/jesd_phy.c:97:6: warning: variable 'pll' set but not
 used
Message-ID: <202108121601.GqQx7NYa-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   e14d4574ca81a569ee6d07e03271f2ae2dad38e4
commit: 99ac99c4c6134cc12abee1f845a897eafb125ba3 [917/1761] misc: jesd204b driver support
config: m68k-randconfig-r014-20210812 (attached as .config)
compiler: m68k-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/99ac99c4c6134cc12abee1f845a897eafb125ba3
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 99ac99c4c6134cc12abee1f845a897eafb125ba3
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   drivers/misc/jesd204b/jesd_phy.c: In function 'read_plls':
>> drivers/misc/jesd204b/jesd_phy.c:97:6: warning: variable 'pll' set but not used [-Wunused-but-set-variable]
      97 |  int pll = st->pll;
         |      ^~~
   drivers/misc/jesd204b/jesd_phy.c: At top level:
>> drivers/misc/jesd204b/jesd_phy.c:172:6: warning: no previous prototype for 'jesd204_phy_set_speed' [-Wmissing-prototypes]
     172 | void jesd204_phy_set_speed(struct jesd204b_phy_state *st, u32 band)
         |      ^~~~~~~~~~~~~~~~~~~~~


vim +/pll +97 drivers/misc/jesd204b/jesd_phy.c

    93	
    94	static void read_plls(struct jesd204b_phy_state *st)
    95	{
    96		int i;
  > 97		int pll = st->pll;
    98		u32 no_of_common_drp_interfaces = 1;
    99	
   100		if (st->pll == CPLL)
   101			no_of_common_drp_interfaces = jesd204b_phy_read(
   102							st, NR_TRANS_DRP_INTERFACES);
   103		else
   104			no_of_common_drp_interfaces = jesd204b_phy_read(
   105							st, NR_COMMON_DRP_INTERFACES);
   106	
   107		for (i = 0; i < no_of_common_drp_interfaces; i++) {
   108			jesd204b_phy_write(st, CHANNEL_XCVR_SEL, i);
   109			pll = jesd204b_phy_read(st, CHANNEL_XCVR_TXPLL);
   110			pll = jesd204b_phy_read(st, CHANNEL_XCVR_RXPLL);
   111		}
   112	}
   113	
   114	static void configure_plls(struct jesd204b_phy_state *st, u32 pll)
   115	{
   116		int i;
   117		u32 no_of_common_drp_interfaces;
   118	
   119		if (pll == CPLL)
   120			no_of_common_drp_interfaces = jesd204b_phy_read(
   121							st, NR_TRANS_DRP_INTERFACES);
   122		else
   123			no_of_common_drp_interfaces = jesd204b_phy_read(
   124							st, NR_COMMON_DRP_INTERFACES);
   125	
   126		for (i = 0; i < no_of_common_drp_interfaces; i++) {
   127			jesd204b_phy_write(st, CHANNEL_XCVR_SEL, i);
   128			jesd204b_phy_write(st, CHANNEL_XCVR_TXPLL, pll);
   129			jesd204b_phy_write(st, CHANNEL_XCVR_RXPLL, pll);
   130		}
   131	}
   132	
   133	static void configure_channel_drp(struct jesd204b_phy_state *st, u32 setting)
   134	{
   135		u32 i, j, addr, temp, no_of_common_drp_interfaces;
   136		u32 no_channel_drp_reg = GTX7S_QPLL_NUM_CHANNEL_DRP_REGS;
   137	
   138		no_of_common_drp_interfaces = jesd204b_phy_read(
   139						st, NR_TRANS_DRP_INTERFACES);
   140	
   141		if (st->pll == CPLL)
   142			no_channel_drp_reg = GTX7S_CPLL_NUM_CHANNEL_DRP_REGS;
   143		for (i = 0; i < no_of_common_drp_interfaces; i++) {
   144			jesd204b_phy_write(st, CHANNEL_DRP_BASE, i);
   145			for (j = 0; j < no_channel_drp_reg; j++) {
   146				/* Get the register address */
   147				if (st->pll == QPLL) {
   148					addr = get_gtx7s_qpll_address_lut(j);
   149	
   150					/* Read the register */
   151					temp = read_channel_drp_reg(st, addr);
   152	
   153					temp &= (0xFFFF ^ (get_gtx7s_qpll_mask_lut(j)));
   154					temp |= ((get_gtx7s_qpll_param_lut(j, setting)
   155							<< get_gtx7s_qpll_offset_lut(j))
   156							& get_gtx7s_qpll_mask_lut(j));
   157				} else {
   158					addr = get_gtx7s_cpll_address_lut(j);
   159	
   160					temp = read_channel_drp_reg(st, addr);
   161	
   162					temp &= (0xFFFF ^ (get_gtx7s_cpll_mask_lut(j)));
   163					temp |= ((get_gtx7s_cpll_param_lut(j, setting)
   164							<< get_gtx7s_cpll_offset_lut(j))
   165							& get_gtx7s_cpll_mask_lut(j));
   166				}
   167				write_channel_drp_reg(st, addr, temp);
   168			}
   169		}
   170	}
   171	
 > 172	void jesd204_phy_set_speed(struct jesd204b_phy_state *st, u32 band)
   173	{
   174		/* make sure we have the correct PLL's selected. */
   175		configure_channel_drp(st, band);
   176	}
   177	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 28885 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/ee05911c/attachment-0001.gz>

From lkp at intel.com  Thu Aug 12 01:04:54 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 16:04:54 +0800
Subject: [xlnx:xlnx_rebase_v5.10 137/1761]
 drivers/misc/xilinx_flex_pm.c:235:53: error: too many arguments to function
 call, expected 2, have 3
Message-ID: <202108121652.OOehWY7B-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   e14d4574ca81a569ee6d07e03271f2ae2dad38e4
commit: a488ba0fdc7388872e2b5ae378612d4e7ea70cb0 [137/1761] misc: xilinx_flex: Add support for the flex noc Performance Monitor
config: s390-randconfig-r012-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/a488ba0fdc7388872e2b5ae378612d4e7ea70cb0
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout a488ba0fdc7388872e2b5ae378612d4e7ea70cb0
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=s390 SHELL=/bin/bash drivers/crypto/xilinx/ drivers/fpga/ drivers/media/i2c/ drivers/misc/ drivers/net/ethernet/xilinx/ drivers/regulator/ drivers/s390/net/ drivers/s390/scsi/ drivers/staging/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:19:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x000000ffUL) << 24) |            \
                     ^
   In file included from drivers/misc/xilinx_flex_pm.c:10:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
                     ^
   In file included from drivers/misc/xilinx_flex_pm.c:10:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
                     ^
   In file included from drivers/misc/xilinx_flex_pm.c:10:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
                     ^
   In file included from drivers/misc/xilinx_flex_pm.c:10:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32'
           __fswab32(x))
                     ^
   In file included from drivers/misc/xilinx_flex_pm.c:10:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> drivers/misc/xilinx_flex_pm.c:235:53: error: too many arguments to function call, expected 2, have 3
                           ret = zynqmp_pm_probe_counter_write(domain, reg, val);
                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~              ^~~
   include/linux/firmware/xlnx-zynqmp.h:914:19: note: 'zynqmp_pm_probe_counter_write' declared here
   static inline int zynqmp_pm_probe_counter_write(u32 reg, u32 value)
                     ^
   drivers/misc/xilinx_flex_pm.c:252:53: error: too many arguments to function call, expected 2, have 3
                           ret = zynqmp_pm_probe_counter_write(domain, reg, val);
                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~              ^~~
   include/linux/firmware/xlnx-zynqmp.h:914:19: note: 'zynqmp_pm_probe_counter_write' declared here
   static inline int zynqmp_pm_probe_counter_write(u32 reg, u32 value)
                     ^
   20 warnings and 2 errors generated.


vim +235 drivers/misc/xilinx_flex_pm.c

   152	
   153	/**
   154	 * xflex_sysfs_cmd - Implements sysfs operations
   155	 * @dev: Device structure
   156	 * @buf: Value to write
   157	 * @cmd: sysfs cmd
   158	 *
   159	 * Return: value read from the sysfs cmd on success and negative error code
   160	 *		otherwise.
   161	 */
   162	static int xflex_sysfs_cmd(struct device *dev, const char *buf,
   163				   enum xflex_sysfs_cmd_codes cmd)
   164	{
   165		struct xflex_dev_info *flexpm = to_xflex_dev_info(dev);
   166		u32 domain, src, offset, reg, val, counter;
   167		int ret;
   168		u32 pm_api_ret[4] = {0, 0, 0, 0};
   169	
   170		mutex_lock(&flexpm->mutex);
   171	
   172		switch (cmd) {
   173		case XFLEX_GET_COUNTER_LPD_WRRSP:
   174			reg = flexpm->counterid_lpd | FPM_WRRSP_L | FPM_VAL;
   175			domain = FPM_LPD;
   176	
   177			break;
   178	
   179		case XFLEX_GET_COUNTER_LPD_WRREQ:
   180			reg = flexpm->counterid_lpd | FPM_WRRSP_L | FPM_VAL;
   181			domain = FPM_LPD;
   182	
   183			break;
   184	
   185		case XFLEX_GET_COUNTER_LPD_RDRSP:
   186			reg = flexpm->counterid_lpd | FPM_RDRSP_L | FPM_VAL;
   187			domain = FPM_LPD;
   188	
   189			break;
   190	
   191		case XFLEX_GET_COUNTER_LPD_RDREQ:
   192			reg = flexpm->counterid_lpd | FPM_RDREQ_L | FPM_VAL;
   193			domain = FPM_LPD;
   194	
   195			break;
   196	
   197		case XFLEX_SET_COUNTER_LPD:
   198			ret = kstrtou32(buf, 0, &val);
   199			if (ret < 0)
   200				goto exit_unlock;
   201	
   202			flexpm->counterid_lpd = val;
   203			reset_default(dev, val, FPM_LPD);
   204			break;
   205	
   206		case XFLEX_SET_PORT_COUNTER_FPD:
   207			ret = kstrtou32(buf, 0, &val);
   208			if (ret < 0)
   209				goto exit_unlock;
   210	
   211			counter = flexpm->counterid_fpd * FPM_COUNTER_OFFSET;
   212			offset = FPM_PORT_SEL_OFFSET + counter * FPM_COUNTER_OFFSET;
   213			fpm_reg(flexpm->basefpd, val, offset);
   214			break;
   215	
   216		case XFLEX_SET_PORT_COUNTER_LPD:
   217			ret = kstrtou32(buf, 0, &val);
   218			if (ret < 0)
   219				goto exit_unlock;
   220	
   221			counter = flexpm->counterid_lpd * FPM_COUNTER_OFFSET;
   222			offset = FPM_PORT_SEL_OFFSET + counter * FPM_COUNTER_OFFSET;
   223			fpm_reg(flexpm->baselpd, val, offset);
   224			break;
   225	
   226		case XFLEX_SET_SRC_COUNTER_LPD:
   227			reg = flexpm->counterid_lpd;
   228			domain = FPM_LPD;
   229			ret = kstrtou32(buf, 0, &val);
   230			if (ret < 0)
   231				goto exit_unlock;
   232	
   233			for (src = 0; src < FPM_NUM_COUNTERS; src++) {
   234				reg = reg | FPM_SRC | (src << FPM_PROBE_SHIFT);
 > 235				ret = zynqmp_pm_probe_counter_write(domain, reg, val);
   236				if (ret < 0) {
   237					dev_err(dev, "Counter write error %d\n", ret);
   238					goto exit_unlock;
   239				}
   240			}
   241			break;
   242	
   243		case XFLEX_SET_SRC_COUNTER_FPD:
   244			reg = flexpm->counterid_fpd;
   245			domain = FPM_FPD;
   246			ret = kstrtou32(buf, 0, &val);
   247			if (ret < 0)
   248				goto exit_unlock;
   249	
   250			for (src = 0; src < FPM_NUM_COUNTERS; src++) {
   251				reg = reg | FPM_SRC | (src << FPM_PROBE_SHIFT);
   252				ret = zynqmp_pm_probe_counter_write(domain, reg, val);
   253				if (ret < 0) {
   254					dev_err(dev, "Counter write error %d\n", ret);
   255					goto exit_unlock;
   256				}
   257			}
   258			break;
   259	
   260		case XFLEX_SET_COUNTER_FPD:
   261			ret = kstrtou32(buf, 0, &val);
   262			if (ret < 0)
   263				goto exit_unlock;
   264	
   265			flexpm->counterid_fpd = val;
   266			reset_default(dev, val, FPM_FPD);
   267			break;
   268	
   269		case XFLEX_GET_COUNTER_FPD_WRRSP:
   270			reg = flexpm->counterid_fpd | FPM_WRRSP_L | FPM_VAL;
   271			domain = FPM_FPD;
   272	
   273			break;
   274	
   275		case XFLEX_GET_COUNTER_FPD_WRREQ:
   276			reg = flexpm->counterid_fpd | FPM_WRREQ_L | FPM_VAL;
   277			domain = FPM_FPD;
   278	
   279			break;
   280	
   281		case XFLEX_GET_COUNTER_FPD_RDRSP:
   282			reg = flexpm->counterid_fpd | FPM_RDRSP_L | FPM_VAL;
   283			domain = FPM_FPD;
   284	
   285			break;
   286	
   287		case XFLEX_GET_COUNTER_FPD_RDREQ:
   288			reg = flexpm->counterid_fpd | FPM_RDREQ_L | FPM_VAL;
   289			domain = FPM_FPD;
   290	
   291			break;
   292	
   293		default:
   294			dev_err(dev, "Invalid option\n");
   295			break;
   296		}
   297	
   298		ret = zynqmp_pm_probe_counter_read(domain, reg, &pm_api_ret[0]);
   299	
   300		if (ret < 0) {
   301			dev_err(dev, "Counter read error %d\n", ret);
   302			return ret;
   303		}
   304		mutex_unlock(&flexpm->mutex);
   305		return pm_api_ret[1];
   306	
   307	exit_unlock:
   308		mutex_unlock(&flexpm->mutex);
   309		return ret;
   310	}
   311	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 32693 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/49f87224/attachment-0001.gz>

From krzysztof.kozlowski at canonical.com  Thu Aug 12 01:17:32 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 12 Aug 2021 10:17:32 +0200
Subject: [PATCH v3 7/7] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <20210811114827.27322-8-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
 <20210811114827.27322-8-semen.protsenko@linaro.org>
Message-ID: <f0e892ce-acd0-7acc-4881-dd67dda6fb38@canonical.com>

On 11/08/2021 13:48, Sam Protsenko wrote:
> Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
> 
> This patch adds minimal SoC support by including next Device Tree nodes:
> 
> 1. Octa cores (Cortex-A55), supporting PSCI v1.0
> 2. ARM architecture timer (armv8-timer)
> 3. Interrupt controller (GIC-400)
> 4. Pinctrl nodes for GPIO
> 5. Serial node
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v3:
>  - Used generic fixed clock for serial
> 
> Changes in v2:
>  * Commit message:
>    - Documented added dts features instead of CPU features
> 
>  * exynos850-usi.dtsi:
>    - Removed, moved everything to exynos850.dtsi
> 
>  * exynos850.dtsi:
>    - Root node:
>      - Added comment about engineering name (Exynos3830)
>      - Renamed pinctrl nodes, adding domain names
>      - Used hard coded IRQ numbers instead of named constants everywhere
>      - Added soc node, moved next nodes there: gic, clock, pinctrls and
>        serial
>      - Used address-cells=1 for soc node and removed unneeded 0x0 from
>        reg properties
>      - Moved exynos850-pinctrl.dtsi include line to the end of
>        exynos850.dtsi
>      - Coding style fixes
>    - cpus:
>      - Used address-cells=1 for cpus node
>      - Renamed cpu at 0001 to cpu at 1, and so on
>      - Left only "arm,cortex-a55" for cpus compatible
>      - Renamed reg = <0x0001> to <0x1> for cpus
>    - armv8 timer:
>      - Add comment about missing HV timer IRQ to armv8 timer node
>      - Removed not existing properties from armv8 timer node
>      - Fixed cpu number in CPU_MASK()
>      - Removed obsolete clock-frequency property
>    - GIC:
>      - Fixed GIC type to be GIC-400
>      - Fixed size of GIC's 2nd region to be 0x2000
>    - serial node:
>      - Hard coded clock number for serial_0 for now; will replace with
>        named const once proper clock driver is implemented
>      - Removed gate_uart_clk0 clock from serial_0, as that clock is not
>        supported in serial driver anyway (yet)
>    - clock node:
>      - Fixed clock controller node name (@0x12.. -> @12..)
> 
>  * exynos850-pinctrl.dtsi:
>    - Referenced pinctrl nodes instead of defining those again in root node
>    - Fixed interrupt-cells (3 -> 2)
>    - Fixed USI related comments for pin config nodes
>    - Removed decon_f_te_* and fm_lna_en nodes (won't be used)
>    - Reordered pin config nodes by pin numbers
>    - Improved all comments
>    - Used existing named constants for pin-function and pin-pud
>    - Fixed node names (used hyphens instead of underscore)
>    - Fixed warnings found in W=1 build
> 
>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 261 ++++++
>  2 files changed, 1009 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> new file mode 100644
> index 000000000000..ba5d5f33e2f6
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> @@ -0,0 +1,748 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
> + *
> + * Copyright (C) 2017 Samsung Electronics Co., Ltd.
> + * Copyright (C) 2021 Linaro Ltd.
> + *
> + * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
> + * tree nodes in this file.
> + */
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/pinctrl/samsung.h>
> +
> +&pinctrl_alive {
> +	gpa0: gpa0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpa1: gpa1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpa2: gpa2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpa3: gpa3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpa4: gpa4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpq0: gpq0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	/* I2C5 (also called CAM_PMIC_I2C in TRM) */
> +	i2c5_bus: i2c5-bus {
> +		samsung,pins = "gpa3-5", "gpa3-6";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	/* I2C6 (also called MOTOR_I2C in TRM) */
> +	i2c6_bus: i2c6-bus {
> +		samsung,pins = "gpa3-7", "gpa4-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	/* USI: UART */
> +	uart0_bus: uart0-bus {
> +		samsung,pins = "gpq0-0", "gpq0-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +	};
> +};
> +
> +&pinctrl_cmgp {
> +	gpm0: gpm0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpm1: gpm1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpm2: gpm2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpm3: gpm3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpm4: gpm4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpm5: gpm5 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	/* USI_CMGP0: HSI2C function */
> +	hsi2c3_bus: hsi2c3-bus {
> +		samsung,pins = "gpm0-0", "gpm1-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;

There are also macros for DRV.

I assume you checked whether the actual values of FUNC/PULL/DRV macros
match Exynos850 datasheet.

> +	};
> +
> +	/* USI_CMGP0: UART function (4 pins, Auto Flow Control) */
> +	uart1_bus_single: uart1-bus {
> +		samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +	};
> +
> +	/* USI_CMGP0: UART function (2 pins, Non-Auto Flow Control) */
> +	uart1_bus_dual: uart1-bus-dual {
> +		samsung,pins = "gpm0-0", "gpm1-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +	};
> +
> +	/* USI_CMGP0: SPI function */
> +	spi1_bus: spi1-bus {
> +		samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	spi1_cs: spi1-cs {
> +		samsung,pins = "gpm3-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	spi1_cs_func: spi1-cs-func {
> +		samsung,pins = "gpm3-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	/* USI_CMGP1: HSI2C function */
> +	hsi2c4_bus: hsi2c4-bus {
> +		samsung,pins = "gpm4-0", "gpm5-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	/* USI_CMGP1: UART function (4 pins, Auto Flow Control) */
> +	uart2_bus_single: uart2-bus {
> +		samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +	};
> +
> +	/* USI_CMGP1: UART function (2 pins, Non-Auto Flow Control) */
> +	uart2_bus_dual: uart2-bus-dual {
> +		samsung,pins = "gpm4-0", "gpm5-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +	};
> +
> +	/* USI_CMGP1: SPI function */
> +	spi2_bus: spi2-bus {
> +		samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	spi2_cs: spi2-cs {
> +		samsung,pins = "gpm7-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	spi2_cs_func: spi2-cs-func {
> +		samsung,pins = "gpm7-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +};
> +
> +&pinctrl_aud {
> +	gpb0: gpb0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb1: gpb1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	aud_codec_mclk: aud-codec-mclk {
> +		samsung,pins = "gpb0-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +
> +	aud_codec_mclk_idle: aud-codec-mclk-idle {
> +		samsung,pins = "gpb0-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +
> +	aud_i2s0_bus: aud-i2s0-bus {
> +		samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +
> +	aud_i2s0_idle: aud-i2s0-idle {
> +		samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +
> +	aud_i2s1_bus: aud-i2s1-bus {
> +		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +
> +	aud_i2s1_idle: aud-i2s1-idle {
> +		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +
> +	aud_fm_bus: aud-fm-bus {
> +		samsung,pins = "gpb1-4";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +
> +	aud_fm_idle: aud-fm-idle {
> +		samsung,pins = "gpb1-4";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +};
> +
> +&pinctrl_hsi {
> +	gpf2: gpf2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	sd2_clk: sd2-clk {
> +		samsung,pins = "gpf2-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <2>;
> +	};
> +
> +	sd2_clk_fast_slew_rate_1x: sd2-clk-fast-slew-rate-1x {
> +		samsung,pins = "gpf2-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	sd2_clk_fast_slew_rate_1_5x: sd2-clk-fast-slew-rate-1-5x {
> +		samsung,pins = "gpf2-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <1>;
> +	};
> +
> +	sd2_clk_fast_slew_rate_2x: sd2-clk-fast-slew-rate-2x {
> +		samsung,pins = "gpf2-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <2>;
> +	};
> +
> +	sd2_clk_fast_slew_rate_2_5x: sd2-clk-fast-slew-rate-2-5x {
> +		samsung,pins = "gpf2-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <3>;
> +	};
> +
> +	sd2_clk_fast_slew_rate_3x: sd2-clk-fast-slew-rate-3x {
> +		samsung,pins = "gpf2-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <4>;
> +	};
> +
> +	sd2_clk_fast_slew_rate_4x: sd2-clk-fast-slew-rate-4x {
> +		samsung,pins = "gpf2-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <5>;
> +	};
> +
> +	sd2_cmd: sd2-cmd {
> +		samsung,pins = "gpf2-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <2>;
> +	 };
> +
> +	sd2_bus1: sd2-bus-width1 {
> +		samsung,pins = "gpf2-2";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <2>;
> +	};
> +
> +	sd2_bus4: sd2-bus-width4 {
> +		samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <2>;
> +	};
> +
> +	sd2_pins_as_pdn: sd2-pins-as-pdn {
> +		samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
> +			       "gpf2-4", "gpf2-5";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +	};
> +};
> +
> +&pinctrl_core {
> +	gpf0: gpf0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf1: gpf1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	sd0_clk: sd0-clk {
> +		samsung,pins = "gpf0-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <3>;
> +	};
> +
> +	sd0_clk_fast_slew_rate_1x: sd0-clk-fast-slew-rate-1x {
> +		samsung,pins = "gpf0-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <1>;
> +	};
> +
> +	sd0_clk_fast_slew_rate_2x: sd0-clk-fast-slew-rate-2x {
> +		samsung,pins = "gpf0-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <2>;
> +	};
> +
> +	sd0_clk_fast_slew_rate_3x: sd0-clk-fast-slew-rate-3x {
> +		samsung,pins = "gpf0-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <2>;
> +	};
> +
> +	sd0_clk_fast_slew_rate_4x: sd0-clk-fast-slew-rate-4x {
> +		samsung,pins = "gpf0-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <3>;
> +	};
> +
> +	sd0_cmd: sd0-cmd {
> +		samsung,pins = "gpf0-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <3>;
> +	};
> +
> +	sd0_rdqs: sd0-rdqs {
> +		samsung,pins = "gpf0-2";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +		samsung,pin-drv = <3>;
> +	};
> +
> +	sd0_nreset: sd0-nreset {
> +		samsung,pins = "gpf0-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <3>;
> +	};
> +
> +	sd0_bus1: sd0-bus-width1 {
> +		samsung,pins = "gpf1-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <3>;
> +	};
> +
> +	sd0_bus4: sd0-bus-width4 {
> +		samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <3>;
> +	};
> +
> +	sd0_bus8: sd0-bus-width8 {
> +		samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <3>;
> +	};
> +};
> +
> +&pinctrl_peri {
> +	gpg0: gpg0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpp0: gpp0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +	gpp1: gpp1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpp2: gpp2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg1: gpg1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg2: gpg2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg3: gpg3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpc0: gpc0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpc1: gpc1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	/* USI: HSI2C0 */
> +	hsi2c0_bus: hsi2c0-bus {
> +		samsung,pins = "gpc1-0", "gpc1-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	/* USI: HSI2C1 */
> +	hsi2c1_bus: hsi2c1-bus {
> +		samsung,pins = "gpc1-2", "gpc1-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	/* USI: HSI2C2 */
> +	hsi2c2_bus: hsi2c2-bus {
> +		samsung,pins = "gpc1-4", "gpc1-5";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	/* USI: SPI */
> +	spi0_bus: spi0-bus {
> +		samsung,pins = "gpp2-0", "gpp2-2", "gpp2-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	spi0_cs: spi0-cs {
> +		samsung,pins = "gpp2-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	spi0_cs_func: spi0-cs-func {
> +		samsung,pins = "gpp2-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	i2c0_bus: i2c0-bus {
> +		samsung,pins = "gpp0-0", "gpp0-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	i2c1_bus: i2c1-bus {
> +		samsung,pins = "gpp0-2", "gpp0-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	i2c2_bus: i2c2-bus {
> +		samsung,pins = "gpp0-4", "gpp0-5";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	i2c3_bus: i2c3-bus {
> +		samsung,pins = "gpp1-0", "gpp1-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	i2c4_bus: i2c4-bus {
> +		samsung,pins = "gpp1-2", "gpp1-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	sensor_mclk0_in: sensor-mclk0-in {
> +		samsung,pins = "gpc0-0";

All these gpc0 go before hsi2c0_bus node (to have them ordered by
datasheet pin name).

> +		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <2>;
> +	};
> +

Rest looks good but anyway will wait for the board DTS. :)

Best regards,
Krzysztof


From zajec5 at gmail.com  Thu Aug 12 01:24:14 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Thu, 12 Aug 2021 10:24:14 +0200
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <878s179jsq.wl-maz@kernel.org>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
 <878s179jsq.wl-maz@kernel.org>
Message-ID: <764732f3-6cd7-bd18-4c83-1b851c29b2a4@gmail.com>

On 12.08.2021 09:57, Marc Zyngier wrote:
> On Thu, 12 Aug 2021 08:32:02 +0100,
> Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>>
>> On 12.08.2021 08:51, Marc Zyngier wrote:
>>> Interestingly, all your CPUs are booting at EL2. Which is great.  Can
>>> you try and enable KVM on your existing 5.10 kernel? Just selecting
>>> CONFIG_KVM should be enough. Does it boot correctly with KVM enabled?
>>>
>>> My suspicion is that the firmware doesn't set SCR_EL3.HCE, and that
>>> the HVC instruction UNDEFs at EL1. That would be bad news.
>>
>> Interesting! I had to enable CONFIG_VIRTUALIZATION and CONFIG_NET first.
>> First I verified kernel built with those options still boots. It does.
>>
>> Then I enabled CONFIG_KVM and kernel seems to hang around switching from
>> bootconsole to the console.
>>
>> Starting program at 0x0000000000080000
>> /memory = 0x40000000
>> WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
>> WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
>> WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
>> Booting Linux on physical CPU 0x0000000000 [0x420f1000]
>> Linux version 5.11.22-g0453a426c37b (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #8 SMP Thu Aug 12 09:25:55 CEST 2021
>> Machine model: Asus GT-AC5300
>> earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
>> printk: bootconsole [bcm63xx_uart0] enabled
>> efi: UEFI not found.
>> [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
>> Zone ranges:
>>    DMA      [mem 0x0000000000000000-0x000000003fffffff]
>>    DMA32    empty
>>    Normal   empty
>> Movable zone start for each node
>> Early memory node ranges
>>    node   0: [mem 0x0000000000000000-0x000000003fffffff]
>> Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
>> percpu: Embedded 18 pages/cpu s43904 r0 d29824 u73728
>> Detected VIPT I-cache on CPU0
>> CPU features: detected: ARM erratum 843419
>> Built 1 zonelists, mobility grouping on.  Total pages: 258048
>> Kernel command line: earlycon=bcm63xx_uart,0xff800640
>> Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
>> Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
>> mem auto-init: stack:off, heap alloc:off, heap free:off
>> Memory: 1019556K/1048576K available (4352K kernel code, 678K rwdata, 860K rodata, 2496K init, 232K bss, 29020K reserved, 0K cma-reserved)
>> SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
>> rcu: Hierarchical RCU implementation.
>> rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
>> NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
>> GIC: Using split EOI/Deactivate mode
>> random: get_random_bytes called from start_kernel+0x33c/0x52c with crng_init=0
>> arch_timer: cp15 timer(s) running at 50.00MHz (phys).
>> clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
>> sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
>> Console: colour dummy device 80x25
>> printk: console [tty0] enabled
>> printk: bootconsole [bcm63xx_uart0] disabled
>>
>>
>> (Unless it's a false conclusion and CONFIG_KVM just breaks console
>> somehow)
> 
> No, that's because you don't pass the right console to your
> kernel. Add something like "console=ttyS0,115200" to the kernel
> command line, which will show what you are missing, as well as stop
> the double-logging.
> 
> Anyway, the fact that it stops booting when you enable KVM confirms my
> suspicion. The firmware on this system is probably crap enough not to
> enable HVC. Let's confirm it further: please apply the patch below on
> top of mainline and tell me that it now boots fine...

Thanks for the patch! It workarounds the issue. See below.


> Are you in a position where you can actually fix the firmware? Or is
> it some closed-source blob?

I'm just an end-user with no access to CFE sources and without any
business contact as Broadcom :(


> diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> index 43d212618834..fc95b103ef42 100644
> --- a/arch/arm64/kernel/hyp-stub.S
> +++ b/arch/arm64/kernel/hyp-stub.S
> @@ -238,7 +238,7 @@ SYM_FUNC_START(switch_to_vhe)
>   
>   	// Turn the world upside down
>   	mov	x0, #HVC_VHE_RESTART
> -	hvc	#0
> +//	hvc	#0
>   1:
>   	ret
>   SYM_FUNC_END(switch_to_vhe)

This allows me to boot 5.13.9 and 5.14-rc5 without any reverts!

Enabling CONFIG_KVM still results in the:
Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt

Starting program at 0x0000000000080000
/memory = 0x40000000
WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
Booting Linux on physical CPU 0x0000000000 [0x420f1000]
Linux version 5.14.0-rc5-g9c6405c34362-dirty (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #4 SMP Thu Aug 12 10:11:31 CEST 2021
Machine model: Asus GT-AC5300
earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
printk: bootconsole [bcm63xx_uart0] enabled
efi: UEFI not found.
[Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
Zone ranges:
   DMA      [mem 0x0000000000000000-0x000000003fffffff]
   DMA32    empty
   Normal   empty
Movable zone start for each node
Early memory node ranges
   node   0: [mem 0x0000000000000000-0x000000003fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
percpu: Embedded 17 pages/cpu s38112 r0 d31520 u69632
Detected VIPT I-cache on CPU0
CPU features: detected: ARM erratum 843419
Built 1 zonelists, mobility grouping on.  Total pages: 258048
Kernel command line: earlycon=bcm63xx_uart,0xff800640
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 1020452K/1048576K available (3648K kernel code, 654K rwdata, 708K rodata, 2432K init, 228K bss, 28124K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
Root IRQ handler: gic_handle_irq
GIC: Using split EOI/Deactivate mode
random: get_random_bytes called from start_kernel+0x4a0/0x6dc with crng_init=0
arch_timer: cp15 timer(s) running at 50.00MHz (phys).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
Console: colour dummy device 80x25
printk: console [tty0] enabled
printk: bootconsole [bcm63xx_uart0] disabled
Booting Linux on physical CPU 0x0000000000 [0x420f1000]
Linux version 5.14.0-rc5-g9c6405c34362-dirty (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #4 SMP Thu Aug 12 10:11:31 CEST 2021
Machine model: Asus GT-AC5300
earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
printk: bootconsole [bcm63xx_uart0] enabled
efi: UEFI not found.
[Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
Zone ranges:
   DMA      [mem 0x0000000000000000-0x000000003fffffff]
   DMA32    empty
   Normal   empty
Movable zone start for each node
Early memory node ranges
   node   0: [mem 0x0000000000000000-0x000000003fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
percpu: Embedded 17 pages/cpu s38112 r0 d31520 u69632
Detected VIPT I-cache on CPU0
CPU features: detected: ARM erratum 843419
Built 1 zonelists, mobility grouping on.  Total pages: 258048
Kernel command line: earlycon=bcm63xx_uart,0xff800640
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 1020452K/1048576K available (3648K kernel code, 654K rwdata, 708K rodata, 2432K init, 228K bss, 28124K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
Root IRQ handler: gic_handle_irq
GIC: Using split EOI/Deactivate mode
random: get_random_bytes called from start_kernel+0x4a0/0x6dc with crng_init=0
arch_timer: cp15 timer(s) running at 50.00MHz (phys).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
Console: colour dummy device 80x25
printk: console [tty0] enabled
printk: bootconsole [bcm63xx_uart0] disabled
Calibrating delay loop (skipped), value calculated using timer frequency.. 100.00 BogoMIPS (lpj=200000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
rcu: Hierarchical SRCU implementation.
EFI services will not be available.
smp: Bringing up secondary CPUs ...
Detected VIPT I-cache on CPU1
CPU1: Booted secondary processor 0x0000000001 [0x420f1000]
Detected VIPT I-cache on CPU2
CPU2: Booted secondary processor 0x0000000002 [0x420f1000]
Detected VIPT I-cache on CPU3
CPU3: Booted secondary processor 0x0000000003 [0x420f1000]
smp: Brought up 1 node, 4 CPUs
SMP: Total of 4 processors activated.
CPU features: detected: 32-bit EL0 Support
CPU features: detected: CRC32 instructions
CPU: All CPU(s) started at EL2
alternatives: patching kernel code
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
pinctrl core: initialized pinctrl subsystem
DMI not present or invalid.
DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
thermal_sys: Registered thermal governor 'step_wise'
ASID allocator initialised with 65536 entries
iommu: Default domain type: Translated
vgaarb: loaded
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
clocksource: Switched to clocksource arch_sys_counter
PCI: CLS 0 bytes, default 64
workingset: timestamp_bits=62 max_order=18 bucket_order=0
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
io scheduler mq-deadline registered
io scheduler kyber registered
basic-mmio-gpio: probe of ff800500.gpio-controller failed with error -22
ff800640.serial: ttyS0 at MMIO 0xff800640 (irq = 24, base_baud = 1562500) is a bcm63xx_uart
printk: console [ttyS0] enabled
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ehci-platform: EHCI generic platform driver
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-pci: OHCI PCI platform driver
ohci-platform: OHCI generic platform driver
i2c /dev entries driver
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
brcmstb-usb-phy 8000c200.usb-phy: Clock not found in Device Tree
brcmstb-usb-phy 8000c200.usb-phy: USB3.0 clock not found in Device Tree
brcmstb-usb-phy 8000c200.usb-phy: Suspend Clock not found in Device Tree
brcmstb-usb-phy 8000c200.usb-phy: IRQ wake not found
brcmstb-usb-phy 8000c200.usb-phy: IRQ wakeup not found
brcmstb-usb-phy 8000c200.usb-phy: Wake interrupt missing, system wake not supported
ehci-platform 8000c300.usb: EHCI Host Controller
ehci-platform 8000c300.usb: new USB bus registered, assigned bus number 1
ehci-platform 8000c300.usb: irq 19, io mem 0x8000c300
ehci-platform 8000c300.usb: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
ohci-platform 8000c400.usb: Generic Platform OHCI controller
ohci-platform 8000c400.usb: new USB bus registered, assigned bus number 2
ohci-platform 8000c400.usb: irq 20, io mem 0x8000c400
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 2 ports detected
xhci-hcd 8000d000.usb: xHCI Host Controller
xhci-hcd 8000d000.usb: new USB bus registered, assigned bus number 3
xhci-hcd 8000d000.usb: hcc params 0x0250f17c hci version 0x100 quirks 0x0000000000010010
xhci-hcd 8000d000.usb: irq 21, io mem 0x8000d000
hub 3-0:1.0: USB hub found
hub 3-0:1.0: config failed, hub doesn't have any ports! (err -19)
xhci-hcd 8000d000.usb: xHCI Host Controller
xhci-hcd 8000d000.usb: new USB bus registered, assigned bus number 4
xhci-hcd 8000d000.usb: Host supports USB 3.0 SuperSpeed
usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
hub 4-0:1.0: USB hub found
hub 4-0:1.0: 2 ports detected
Freeing unused kernel memory: 2432K
Run /init as init process
tmpfs: Unknown parameter 'mode'
mount: mounting tmpfs: Unknown parameter 'mode'
tmpfs on /dev/shtmpfs: Unknown parameter 'mode'
m failed: Invalid argument
mount: mounting tmpfs on /tmp failed: Invalid argument
mount: mounting tmpfs on /run failed: Invalid argument
Starting syslogd: OK
Starting klogd: OK
Runnirandom: dd: uninitialized urandom read (512 bytes read)
ng sysctl: OK
Saving random seed: OK
Starting network: ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
ip: socket: Function not implemented
FAIL

Welcome to Buildroot
buildroot login:


From maz at kernel.org  Thu Aug 12 01:24:17 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 09:24:17 +0100
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <7fee376c-2099-6d88-0be8-ba57633e0965@gmail.com>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
 <7fee376c-2099-6d88-0be8-ba57633e0965@gmail.com>
Message-ID: <877dgr9iku.wl-maz@kernel.org>

On Thu, 12 Aug 2021 08:56:57 +0100,
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> 
> On 12.08.2021 09:32, Rafa? Mi?ecki wrote:
> > (Unless it's a false conclusion and CONFIG_KVM just breaks console
> > somehow)
> 
> That was a false conclusion. I modified kernel/printk/printk.c and set
> keep_bootcon = 1
> 
> A full log with important part below:

[...]

> kernel BUG at arch/arm64/kernel/traps.c:406!
> Internal error: Oops - BUG: 0 [#1] SMP
> CPU: 3 PID: 0 Comm: swapper/3 Not tainted 5.11.22-g0453a426c37b-dirty #12
> Hardware name: Asus GT-AC5300 (DT)
> pstate: 00000085 (nzcv daIf -PAN -UAO -TCO BTYPE=--)
> pc : do_undefinstr+0x204/0x230
> lr : do_undefinstr+0x218/0x230
> sp : ffffffc01001bcc0
> x29: ffffffc01001bcc0 x28: ffffff80010a0a80
> x27: 00000000000000e0 x26: ffffffc01001c000
> x25: ffffffc010018000 x24: ffffffc0108a9000
> x23: 0000000080000085 x22: 00000000d4000002
> x21: ffffffc0108cd0d8 x20: ffffff80010a0a80
> x19: ffffffc01001bd40 x18: 0000000000000030
> x17: fbfffafbffffffff x16: 0000000000000048
> x15: 0000046366960998 x14: 0000000000000017
> x13: 0000000000000001 x12: 0000000000000001
> x11: 0000000000000000 x10: 0000000000000003
> x9 : 0000000000000000 x8 : 0000000000000000
> x7 : ffffff803fde8600 x6 : 0000000000000001
> x5 : 0000000000000000 x4 : ffffff80010a0a80
> x3 : 00000000d5300000 x2 : ffffffc01082ce68
> x1 : ffffffc0108cd0e8 x0 : 0000000080000085
> Call trace:
>  do_undefinstr+0x204/0x230
>  el1_undef+0x30/0x50
>  el1_sync_handler+0x8c/0xd0
>  el1_sync+0x78/0x100
>  __hyp_reset_vectors+0x4/0x91d0
>  _kvm_arch_hardware_enable+0x3c/0x60

And here's the proof. The first HVC we issue ends up generating an
UNDEF, and the kernel legitimately panics. It is just that from 5.12,
we always use HVC even if you don't have KVM enabled. Or kexec. Or
anything else that requires jumping back to EL2, despite having booted
at... EL2. Nonsense.

I'll have to go and think of how to handle this. This may end-up being
a command-line option if we cannot easily handle the UNDEF that early
at boot time.

	M.

-- 
Without deviation from the norm, progress is not possible.


From f.fainelli at gmail.com  Thu Aug 12 01:33:10 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 12 Aug 2021 01:33:10 -0700
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <878s179jsq.wl-maz@kernel.org>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
 <878s179jsq.wl-maz@kernel.org>
Message-ID: <a02714d9-9446-2834-eb84-1790c640a58a@gmail.com>



On 8/12/2021 12:57 AM, Marc Zyngier wrote:
> On Thu, 12 Aug 2021 08:32:02 +0100,
> Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>>
>> On 12.08.2021 08:51, Marc Zyngier wrote:
>>> Interestingly, all your CPUs are booting at EL2. Which is great.  Can
>>> you try and enable KVM on your existing 5.10 kernel? Just selecting
>>> CONFIG_KVM should be enough. Does it boot correctly with KVM enabled?
>>>
>>> My suspicion is that the firmware doesn't set SCR_EL3.HCE, and that
>>> the HVC instruction UNDEFs at EL1. That would be bad news.
>>
>> Interesting! I had to enable CONFIG_VIRTUALIZATION and CONFIG_NET first.
>> First I verified kernel built with those options still boots. It does.
>>
>> Then I enabled CONFIG_KVM and kernel seems to hang around switching from
>> bootconsole to the console.
>>
>> Starting program at 0x0000000000080000
>> /memory = 0x40000000
>> WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
>> WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
>> WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
>> Booting Linux on physical CPU 0x0000000000 [0x420f1000]
>> Linux version 5.11.22-g0453a426c37b (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #8 SMP Thu Aug 12 09:25:55 CEST 2021
>> Machine model: Asus GT-AC5300
>> earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
>> printk: bootconsole [bcm63xx_uart0] enabled
>> efi: UEFI not found.
>> [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
>> Zone ranges:
>>    DMA      [mem 0x0000000000000000-0x000000003fffffff]
>>    DMA32    empty
>>    Normal   empty
>> Movable zone start for each node
>> Early memory node ranges
>>    node   0: [mem 0x0000000000000000-0x000000003fffffff]
>> Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
>> percpu: Embedded 18 pages/cpu s43904 r0 d29824 u73728
>> Detected VIPT I-cache on CPU0
>> CPU features: detected: ARM erratum 843419
>> Built 1 zonelists, mobility grouping on.  Total pages: 258048
>> Kernel command line: earlycon=bcm63xx_uart,0xff800640
>> Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
>> Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
>> mem auto-init: stack:off, heap alloc:off, heap free:off
>> Memory: 1019556K/1048576K available (4352K kernel code, 678K rwdata, 860K rodata, 2496K init, 232K bss, 29020K reserved, 0K cma-reserved)
>> SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
>> rcu: Hierarchical RCU implementation.
>> rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
>> NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
>> GIC: Using split EOI/Deactivate mode
>> random: get_random_bytes called from start_kernel+0x33c/0x52c with crng_init=0
>> arch_timer: cp15 timer(s) running at 50.00MHz (phys).
>> clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
>> sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
>> Console: colour dummy device 80x25
>> printk: console [tty0] enabled
>> printk: bootconsole [bcm63xx_uart0] disabled
>>
>>
>> (Unless it's a false conclusion and CONFIG_KVM just breaks console
>> somehow)
> 
> No, that's because you don't pass the right console to your
> kernel. Add something like "console=ttyS0,115200" to the kernel
> command line, which will show what you are missing, as well as stop
> the double-logging.
> 
> Anyway, the fact that it stops booting when you enable KVM confirms my
> suspicion. The firmware on this system is probably crap enough not to
> enable HVC. Let's confirm it further: please apply the patch below on
> top of mainline and tell me that it now boots fine...
> 
> Are you in a position where you can actually fix the firmware? Or is
> it some closed-source blob?

This is a closed source blob, but you ought to be able to load a custom 
EL3 stub that could fix things up, in premise at least.

> 
> Broadcom folks: can you lease check whether the firmware on this
> system correctly configures SCR_EL3.HCE?

Let me confirm that with the responsible folks.
-- 
Florian


From f.fainelli at gmail.com  Thu Aug 12 01:33:29 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 12 Aug 2021 01:33:29 -0700
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <87czqj9mvo.wl-maz@kernel.org>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
Message-ID: <fd676170-eb9d-6c15-f2d0-ddc551ef82f2@gmail.com>



On 8/11/2021 11:51 PM, Marc Zyngier wrote:
[snip]
>> CPU: All CPU(s) started at EL2
> 
> Interestingly, all your CPUs are booting at EL2. Which is great.  Can
> you try and enable KVM on your existing 5.10 kernel? Just selecting
> CONFIG_KVM should be enough. Does it boot correctly with KVM enabled?
> 
> My suspicion is that the firmware doesn't set SCR_EL3.HCE, and that
> the HVC instruction UNDEFs at EL1. That would be bad news.

Other Brahma-B53 devices that we work with (set-top box and cable modem 
chips) boot 5.12 and beyond correctly, and indeed, our EL3 firmware 
sets-up SCR_EL3.HCE.
-- 
Florian


From will at kernel.org  Thu Aug 12 01:46:01 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 09:46:01 +0100
Subject: [PATCH v3 06/15] KVM: arm64: Restore mdcr_el2 from vcpu
In-Reply-To: <CA+EHjTweLPu+DQ8hR9kEW0LrawtaoAoXR_+HmSEZpP-XOEm2qg@mail.gmail.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-7-tabba@google.com>
 <20210720145258.axhqog3abdvtpqhw@gator>
 <CA+EHjTweLPu+DQ8hR9kEW0LrawtaoAoXR_+HmSEZpP-XOEm2qg@mail.gmail.com>
Message-ID: <20210812084600.GA5912@willie-the-truck>

On Wed, Jul 21, 2021 at 08:37:21AM +0100, Fuad Tabba wrote:
> On Tue, Jul 20, 2021 at 3:53 PM Andrew Jones <drjones at redhat.com> wrote:
> >
> > On Mon, Jul 19, 2021 at 05:03:37PM +0100, Fuad Tabba wrote:
> > > On deactivating traps, restore the value of mdcr_el2 from the
> > > newly created and preserved host value vcpu context, rather than
> > > directly reading the hardware register.
> > >
> > > Up until and including this patch the two values are the same,
> > > i.e., the hardware register and the vcpu one. A future patch will
> > > be changing the value of mdcr_el2 on activating traps, and this
> > > ensures that its value will be restored.
> > >
> > > No functional change intended.
> >
> > I'm probably missing something, but I can't convince myself that the host
> > will end up with the same mdcr_el2 value after deactivating traps after
> > this patch as before. We clearly now restore whatever we had when
> > activating traps (presumably whatever we configured at init_el2_state
> > time), but is that equivalent to what we had before with the masking and
> > ORing that this patch drops?
> 
> You're right. I thought that these were actually being initialized to
> the same values, but having a closer look at the code the mdcr values
> are not the same as pre-patch. I will fix this.

Can you elaborate on the issue here, please? I was just looking at this
but aren't you now relying on __init_el2_debug to configure this, which
should be fine?

Will


From lkp at intel.com  Thu Aug 12 01:47:18 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 12 Aug 2021 16:47:18 +0800
Subject: [xlnx:xlnx_rebase_v5.10 961/1761]
 drivers/irqchip/irq-xilinx-intc.c:175:10: error: implicit declaration of
 function 'handle_domain_irq'; did you mean 'handle_bad_irq'?
Message-ID: <202108121611.B7ZVnQrk-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   e14d4574ca81a569ee6d07e03271f2ae2dad38e4
commit: ec26ada995b2cdeda14911845e1884150e099d5b [961/1761] irqchip: xilinx: Use handle_domain_irq()
config: m68k-randconfig-r014-20210812 (attached as .config)
compiler: m68k-linux-gcc (GCC) 10.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/ec26ada995b2cdeda14911845e1884150e099d5b
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout ec26ada995b2cdeda14911845e1884150e099d5b
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-10.3.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/irqchip/irq-xilinx-intc.c: In function 'xil_intc_handle_irq':
   drivers/irqchip/irq-xilinx-intc.c:173:15: error: 'struct xintc_irq_chip' has no member named 'read_fn'
     173 |   hwirq = irqc->read_fn(irqc->base + IVR);
         |               ^~
>> drivers/irqchip/irq-xilinx-intc.c:175:10: error: implicit declaration of function 'handle_domain_irq'; did you mean 'handle_bad_irq'? [-Werror=implicit-function-declaration]
     175 |    ret = handle_domain_irq(irqc->root_domain, hwirq, regs);
         |          ^~~~~~~~~~~~~~~~~
         |          handle_bad_irq
   drivers/irqchip/irq-xilinx-intc.c: In function 'xilinx_intc_of_init':
   drivers/irqchip/irq-xilinx-intc.c:192:2: error: 'ret' undeclared (first use in this function)
     192 |  ret = of_property_read_u32(intc, "cpu-id", &cpu_id);
         |  ^~~
   drivers/irqchip/irq-xilinx-intc.c:192:2: note: each undeclared identifier is reported only once for each function it appears in
   drivers/irqchip/irq-xilinx-intc.c:257:3: error: 'irq' undeclared (first use in this function); did you mean 'irqc'?
     257 |   irq = irq_of_parse_and_map(intc, 0);
         |   ^~~
         |   irqc
   drivers/irqchip/irq-xilinx-intc.c:189:19: warning: unused variable 'intc_dev' [-Wunused-variable]
     189 |  struct irq_chip *intc_dev;
         |                   ^~~~~~~~
   drivers/irqchip/irq-xilinx-intc.c:280:1: error: control reaches end of non-void function [-Werror=return-type]
     280 | }
         | ^
   cc1: some warnings being treated as errors


vim +175 drivers/irqchip/irq-xilinx-intc.c

   165	
   166	static void xil_intc_handle_irq(struct pt_regs *regs)
   167	{
   168		int ret;
   169		unsigned int hwirq, cpu_id = smp_processor_id();
   170		struct xintc_irq_chip *irqc = per_cpu_ptr(&primary_intc, cpu_id);
   171	
   172		do {
   173			hwirq = irqc->read_fn(irqc->base + IVR);
   174			if (hwirq != -1U) {
 > 175				ret = handle_domain_irq(irqc->root_domain, hwirq, regs);
   176				WARN_ONCE(ret, "cpu %d: Unhandled HWIRQ %d\n",
   177					  cpu_id, hwirq);
   178				continue;
   179			}
   180	
   181			break;
   182		} while (1);
   183	}
   184	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 28879 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/ff7e61a7/attachment-0001.gz>

From will at kernel.org  Thu Aug 12 01:58:58 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 09:58:58 +0100
Subject: [PATCH v3 01/15] KVM: arm64: placeholder to check if VM is
 protected
In-Reply-To: <20210719160346.609914-2-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-2-tabba@google.com>
Message-ID: <20210812085857.GB5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:32PM +0100, Fuad Tabba wrote:
> Add a function to check whether a VM is protected (under pKVM).
> Since the creation of protected VMs isn't enabled yet, this is a
> placeholder that always returns false. The intention is for this
> to become a check for protected VMs in the future (see Will's RFC
> [*]).
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> 
> [*] https://lore.kernel.org/kvmarm/20210603183347.1695-1-will at kernel.org/

You can make this a Link: tag.

Anyway, I think it makes lots of sense to decouple this from the user-ABI
series:

Acked-by: Will Deacon <will at kernel.org>

Will


From will at kernel.org  Thu Aug 12 01:59:09 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 09:59:09 +0100
Subject: [PATCH v3 02/15] KVM: arm64: Remove trailing whitespace in comment
In-Reply-To: <20210719160346.609914-3-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-3-tabba@google.com>
Message-ID: <20210812085908.GC5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:33PM +0100, Fuad Tabba wrote:
> Remove trailing whitespace from comment in trap_dbgauthstatus_el1().
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index f6f126eb6ac1..80a6e41cadad 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -318,14 +318,14 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
>  /*
>   * We want to avoid world-switching all the DBG registers all the
>   * time:
> - * 
> + *
>   * - If we've touched any debug register, it is likely that we're
>   *   going to touch more of them. It then makes sense to disable the
>   *   traps and start doing the save/restore dance
>   * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is
>   *   then mandatory to save/restore the registers, as the guest
>   *   depends on them.
> - * 
> + *
>   * For this, we use a DIRTY bit, indicating the guest has modified the
>   * debug registers, used as follow:
>   *

I'd usually be against these sorts of changes but given you're in the
area...

Acked-by: Will Deacon <will at kernel.org>

Will


From will at kernel.org  Thu Aug 12 01:59:20 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 09:59:20 +0100
Subject: [PATCH v3 05/15] KVM: arm64: Refactor sys_regs.h, c for nVHE reuse
In-Reply-To: <20210719160346.609914-6-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-6-tabba@google.com>
Message-ID: <20210812085919.GD5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:36PM +0100, Fuad Tabba wrote:
> Refactor sys_regs.h and sys_regs.c to make it easier to reuse
> common code. It will be used in nVHE in a later patch.
> 
> Note that the refactored code uses __inline_bsearch for find_reg
> instead of bsearch to avoid copying the bsearch code for nVHE.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/sysreg.h |  3 +++
>  arch/arm64/kvm/sys_regs.c       | 30 +-----------------------------
>  arch/arm64/kvm/sys_regs.h       | 31 +++++++++++++++++++++++++++++++
>  3 files changed, 35 insertions(+), 29 deletions(-)

With the naming change suggested by Drew:

Acked-by: Will Deacon <will at kernel.org.

Will


From will at kernel.org  Thu Aug 12 01:59:29 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 09:59:29 +0100
Subject: [PATCH v3 07/15] KVM: arm64: Track value of cptr_el2 in struct
 kvm_vcpu_arch
In-Reply-To: <20210719160346.609914-8-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-8-tabba@google.com>
Message-ID: <20210812085929.GE5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:38PM +0100, Fuad Tabba wrote:
> Track the baseline guest value for cptr_el2 in struct
> kvm_vcpu_arch, similar to the other registers that control traps.
> Use this value when setting cptr_el2 for the guest.
> 
> Currently this value is unchanged (CPTR_EL2_DEFAULT), but future
> patches will set trapping bits based on features supported for
> the guest.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 1 +
>  arch/arm64/kvm/arm.c              | 1 +
>  arch/arm64/kvm/hyp/nvhe/switch.c  | 2 +-
>  3 files changed, 3 insertions(+), 1 deletion(-)

Acked-by: Will Deacon <will at kernel.org>

Will


From will at kernel.org  Thu Aug 12 01:59:39 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 09:59:39 +0100
Subject: [PATCH v3 08/15] KVM: arm64: Add feature register flag definitions
In-Reply-To: <20210719160346.609914-9-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-9-tabba@google.com>
Message-ID: <20210812085939.GF5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:39PM +0100, Fuad Tabba wrote:
> Add feature register flag definitions to clarify which features
> might be supported.
> 
> Consolidate the various ID_AA64PFR0_ELx flags for all ELs.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/cpufeature.h |  4 ++--
>  arch/arm64/include/asm/sysreg.h     | 12 ++++++++----
>  arch/arm64/kernel/cpufeature.c      |  8 ++++----
>  3 files changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 9bb9d11750d7..b7d9bb17908d 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -602,14 +602,14 @@ static inline bool id_aa64pfr0_32bit_el1(u64 pfr0)
>  {
>  	u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_SHIFT);
>  
> -	return val == ID_AA64PFR0_EL1_32BIT_64BIT;
> +	return val == ID_AA64PFR0_ELx_32BIT_64BIT;
>  }
>  
>  static inline bool id_aa64pfr0_32bit_el0(u64 pfr0)
>  {
>  	u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL0_SHIFT);
>  
> -	return val == ID_AA64PFR0_EL0_32BIT_64BIT;
> +	return val == ID_AA64PFR0_ELx_32BIT_64BIT;
>  }
>  
>  static inline bool id_aa64pfr0_sve(u64 pfr0)
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 326f49e7bd42..0b773037251c 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -784,14 +784,13 @@
>  #define ID_AA64PFR0_AMU			0x1
>  #define ID_AA64PFR0_SVE			0x1
>  #define ID_AA64PFR0_RAS_V1		0x1
> +#define ID_AA64PFR0_RAS_ANY		0xf

This doesn't correspond to an architectural definition afaict: the manual
says that any values other than 0, 1 or 2 are "reserved" so we should avoid
defining our own definitions here.

Will


From will at kernel.org  Thu Aug 12 01:59:53 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 09:59:53 +0100
Subject: [PATCH v3 09/15] KVM: arm64: Add config register bit definitions
In-Reply-To: <20210719160346.609914-10-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-10-tabba@google.com>
Message-ID: <20210812085952.GG5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:40PM +0100, Fuad Tabba wrote:
> Add hardware configuration register bit definitions for HCR_EL2
> and MDCR_EL2. Future patches toggle these hyp configuration
> register bits to trap on certain accesses.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_arm.h | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)

I checked all of these against the Arm ARM and they look correct to me:

Acked-by: Will Deacon <will at kernel.org>

Will


From dawei.chien at mediatek.com  Thu Aug 12 01:58:29 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:29 +0800
Subject: [V11,
 PATCH 02/19] dt-bindings: mediatek: add compatible for MT8195 dvfsrc
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-3-dawei.chien@mediatek.com>

This adds dt-binding documentation of dvfsrc for Mediatek MT8195
SoCs Platform.

Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml
index f2b67b99921b..ec3feaf1ef73 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml
@@ -25,6 +25,7 @@ properties:
       - mediatek,mt6873-dvfsrc
       - mediatek,mt8183-dvfsrc
       - mediatek,mt8192-dvfsrc
+      - mediatek,mt8195-dvfsrc
 
   '#interconnect-cells':
     const: 1
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:31 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:31 +0800
Subject: [V11,PATCH 04/19] soc: mediatek: add driver for dvfsrc support
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-5-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Add dvfsrc driver for MT6873/MT8183/MT8192

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 drivers/soc/mediatek/Kconfig            |  11 +
 drivers/soc/mediatek/Makefile           |   1 +
 drivers/soc/mediatek/mtk-dvfsrc.c       | 421 ++++++++++++++++++++++++++++++++
 include/linux/soc/mediatek/mtk_dvfsrc.h |  35 +++
 4 files changed, 468 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
 create mode 100644 include/linux/soc/mediatek/mtk_dvfsrc.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index fdd8bc08569e..2dcf02384639 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -26,6 +26,17 @@ config MTK_DEVAPC
 	  The violation information is logged for further analysis or
 	  countermeasures.
 
+config MTK_DVFSRC
+	tristate "MediaTek DVFSRC Support"
+	depends on ARCH_MEDIATEK
+	help
+	  Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
+	  and frequency scaling resource collector) found
+	  on different MediaTek SoCs. The DVFSRC is a proprietary
+	  hardware which is used to collect all the requests from
+	  system and turn into the decision of minimum Vcore voltage
+	  and minimum DRAM frequency to fulfill those requests.
+
 config MTK_INFRACFG
 	bool "MediaTek INFRACFG Support"
 	select REGMAP
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 90270f8114ed..365d14fd7d49 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
 obj-$(CONFIG_MTK_DEVAPC) += mtk-devapc.o
+obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
new file mode 100644
index 000000000000..6ef167cf55bd
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -0,0 +1,421 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk_dvfsrc.h>
+#include <linux/soc/mediatek/mtk_sip_svc.h>
+
+#define DVFSRC_IDLE     0x00
+#define DVFSRC_GET_TARGET_LEVEL(x)  (((x) >> 0) & 0x0000ffff)
+#define DVFSRC_GET_CURRENT_LEVEL(x) (((x) >> 16) & 0x0000ffff)
+#define kbps_to_mbps(x) ((x) / 1000)
+
+#define POLL_TIMEOUT        1000
+#define STARTUP_TIME        1
+
+#define MTK_SIP_DVFSRC_INIT		0x00
+
+#define DVFSRC_OPP_DESC(_opp_table)	\
+{	\
+	.opps = _opp_table,	\
+	.num_opp = ARRAY_SIZE(_opp_table),	\
+}
+
+struct dvfsrc_opp {
+	u32 vcore_opp;
+	u32 dram_opp;
+};
+
+struct dvfsrc_opp_desc {
+	const struct dvfsrc_opp *opps;
+	u32 num_opp;
+};
+
+struct mtk_dvfsrc;
+struct dvfsrc_soc_data {
+	const int *regs;
+	const struct dvfsrc_opp_desc *opps_desc;
+	int (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
+	int (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
+	u32 (*get_vcore_level)(struct mtk_dvfsrc *dvfsrc);
+	u32 (*get_vcp_level)(struct mtk_dvfsrc *dvfsrc);
+	void (*set_dram_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
+	void (*set_dram_peak_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
+	void (*set_dram_hrtbw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
+	void (*set_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	void (*set_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	void (*set_vscp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	int (*wait_for_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+	int (*wait_for_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+};
+
+struct mtk_dvfsrc {
+	struct device *dev;
+	struct platform_device *icc;
+	struct platform_device *regulator;
+	const struct dvfsrc_soc_data *dvd;
+	int dram_type;
+	const struct dvfsrc_opp_desc *curr_opps;
+	void __iomem *regs;
+	spinlock_t req_lock;
+	struct mutex pstate_lock;
+	struct notifier_block scpsys_notifier;
+};
+
+static u32 dvfsrc_read(struct mtk_dvfsrc *dvfs, u32 offset)
+{
+	return readl(dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+static void dvfsrc_write(struct mtk_dvfsrc *dvfs, u32 offset, u32 val)
+{
+	writel(val, dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+#define dvfsrc_rmw(dvfs, offset, val, mask, shift) \
+	dvfsrc_write(dvfs, offset, \
+		(dvfsrc_read(dvfs, offset) & ~(mask << shift)) | (val << shift))
+
+enum dvfsrc_regs {
+	DVFSRC_SW_REQ,
+	DVFSRC_SW_REQ2,
+	DVFSRC_LEVEL,
+	DVFSRC_TARGET_LEVEL,
+	DVFSRC_SW_BW,
+	DVFSRC_SW_PEAK_BW,
+	DVFSRC_SW_HRT_BW,
+	DVFSRC_VCORE_REQUEST,
+};
+
+static const int mt8183_regs[] = {
+	[DVFSRC_SW_REQ] =	0x4,
+	[DVFSRC_SW_REQ2] =	0x8,
+	[DVFSRC_LEVEL] =	0xDC,
+	[DVFSRC_SW_BW] =	0x160,
+};
+
+static const struct dvfsrc_opp *get_current_opp(struct mtk_dvfsrc *dvfsrc)
+{
+	int level;
+
+	level = dvfsrc->dvd->get_current_level(dvfsrc);
+	return &dvfsrc->curr_opps->opps[level];
+}
+
+static int dvfsrc_is_idle(struct mtk_dvfsrc *dvfsrc)
+{
+	if (!dvfsrc->dvd->get_target_level)
+		return true;
+
+	return dvfsrc->dvd->get_target_level(dvfsrc);
+}
+
+static int dvfsrc_wait_for_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *curr;
+
+	return readx_poll_timeout_atomic(get_current_opp, dvfsrc, curr,
+					 curr->vcore_opp >= level, STARTUP_TIME,
+					 POLL_TIMEOUT);
+}
+
+static int mt8183_wait_for_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *target, *curr;
+	int ret;
+
+	target = &dvfsrc->curr_opps->opps[level];
+	ret = readx_poll_timeout(get_current_opp, dvfsrc, curr,
+				 curr->dram_opp >= target->dram_opp &&
+				 curr->vcore_opp >= target->vcore_opp,
+				 STARTUP_TIME, POLL_TIMEOUT);
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "timeout, target: %u, dram: %d, vcore: %d\n", level,
+			 curr->dram_opp, curr->vcore_opp);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mt8183_get_target_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return DVFSRC_GET_TARGET_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+}
+
+static int mt8183_get_current_level(struct mtk_dvfsrc *dvfsrc)
+{
+	int level;
+
+	/* HW level 0 is begin from 0x10000 */
+	level = DVFSRC_GET_CURRENT_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+	/* Array index start from 0 */
+	return ffs(level) - 1;
+}
+
+static u32 mt8183_get_vcore_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return (dvfsrc_read(dvfsrc, DVFSRC_SW_REQ2) >> 2) & 0x3;
+}
+
+static void mt8183_set_dram_bw(struct mtk_dvfsrc *dvfsrc, u64 bw)
+{
+	dvfsrc_write(dvfsrc, DVFSRC_SW_BW, div_u64(kbps_to_mbps(bw), 100));
+}
+
+static void mt8183_set_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	int vcore_opp, dram_opp;
+	const struct dvfsrc_opp *opp;
+
+	/* translate pstate to dvfsrc level, and set it to DVFSRC HW */
+	opp = &dvfsrc->curr_opps->opps[level];
+	vcore_opp = opp->vcore_opp;
+	dram_opp = opp->dram_opp;
+
+	dev_dbg(dvfsrc->dev, "vcore_opp: %d, dram_opp: %d\n",
+		vcore_opp, dram_opp);
+	dvfsrc_write(dvfsrc, DVFSRC_SW_REQ, dram_opp | vcore_opp << 2);
+}
+
+static void mt8183_set_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	dvfsrc_write(dvfsrc, DVFSRC_SW_REQ2, level << 2);
+}
+
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data)
+{
+	int ret, state;
+	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+	dev_dbg(dvfsrc->dev, "cmd: %d, data: %llu\n", cmd, data);
+
+	switch (cmd) {
+	case MTK_DVFSRC_CMD_BW_REQUEST:
+		dvfsrc->dvd->set_dram_bw(dvfsrc, data);
+		return;
+	case MTK_DVFSRC_CMD_PEAK_BW_REQUEST:
+		if (dvfsrc->dvd->set_dram_peak_bw)
+			dvfsrc->dvd->set_dram_peak_bw(dvfsrc, data);
+		return;
+	case MTK_DVFSRC_CMD_OPP_REQUEST:
+		if (dvfsrc->dvd->set_opp_level)
+			dvfsrc->dvd->set_opp_level(dvfsrc, data);
+		break;
+	case MTK_DVFSRC_CMD_VCORE_REQUEST:
+		dvfsrc->dvd->set_vcore_level(dvfsrc, data);
+		break;
+	case MTK_DVFSRC_CMD_HRTBW_REQUEST:
+		if (dvfsrc->dvd->set_dram_hrtbw)
+			dvfsrc->dvd->set_dram_hrtbw(dvfsrc, data);
+		else
+			return;
+		break;
+	case MTK_DVFSRC_CMD_VSCP_REQUEST:
+		dvfsrc->dvd->set_vscp_level(dvfsrc, data);
+		break;
+	default:
+		dev_err(dvfsrc->dev, "unknown command: %d\n", cmd);
+		return;
+	}
+
+	/* DVFSRC needs to wait at least 2T(~196ns) to handle request
+	 * after receiving command
+	 */
+	udelay(STARTUP_TIME);
+
+	ret = readx_poll_timeout(dvfsrc_is_idle, dvfsrc,
+				 state, state == DVFSRC_IDLE,
+				 STARTUP_TIME, POLL_TIMEOUT);
+
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "%d: idle timeout, data: %llu, last: %d -> %d\n",
+			 cmd, data,
+			 dvfsrc->dvd->get_current_level(dvfsrc),
+			 dvfsrc->dvd->get_target_level(dvfsrc));
+		return;
+	}
+
+	/* The previous change may be requested by previous request.
+	 * So we delay 1us, then start checking opp is reached enough.
+	 */
+	udelay(STARTUP_TIME);
+
+	if (cmd == MTK_DVFSRC_CMD_OPP_REQUEST)
+		ret = dvfsrc->dvd->wait_for_opp_level(dvfsrc, data);
+	else
+		ret = dvfsrc->dvd->wait_for_vcore_level(dvfsrc, data);
+
+	if (ret < 0) {
+		dev_warn(dvfsrc->dev,
+			 "%d: wait timeout, data: %llu, last: %d -> %d\n",
+			 cmd, data,
+			 dvfsrc->dvd->get_current_level(dvfsrc),
+			 dvfsrc->dvd->get_target_level(dvfsrc));
+	}
+
+}
+EXPORT_SYMBOL(mtk_dvfsrc_send_request);
+
+int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data)
+{
+	struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+	switch (cmd) {
+	case MTK_DVFSRC_CMD_VCORE_LEVEL_QUERY:
+		*data = dvfsrc->dvd->get_vcore_level(dvfsrc);
+		break;
+	case MTK_DVFSRC_CMD_VSCP_LEVEL_QUERY:
+		*data = dvfsrc->dvd->get_vcp_level(dvfsrc);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_dvfsrc_query_info);
+
+static int mtk_dvfsrc_probe(struct platform_device *pdev)
+{
+	struct arm_smccc_res ares;
+	struct resource *res;
+	struct mtk_dvfsrc *dvfsrc;
+	int ret;
+
+	dvfsrc = devm_kzalloc(&pdev->dev, sizeof(*dvfsrc), GFP_KERNEL);
+	if (!dvfsrc)
+		return -ENOMEM;
+
+	dvfsrc->dvd = of_device_get_match_data(&pdev->dev);
+	dvfsrc->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dvfsrc->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dvfsrc->regs))
+		return PTR_ERR(dvfsrc->regs);
+
+	spin_lock_init(&dvfsrc->req_lock);
+	mutex_init(&dvfsrc->pstate_lock);
+
+	arm_smccc_smc(MTK_SIP_VCOREFS_CONTROL, MTK_SIP_DVFSRC_INIT, 0, 0, 0,
+		0, 0, 0, &ares);
+
+	if (!ares.a0) {
+		dvfsrc->dram_type = ares.a1;
+		dev_info(dvfsrc->dev, "dram_type: %d\n", dvfsrc->dram_type);
+	} else {
+		dev_err(dvfsrc->dev, "init fails: %lu\n", ares.a0);
+		return ares.a0;
+	}
+
+	dvfsrc->curr_opps = &dvfsrc->dvd->opps_desc[dvfsrc->dram_type];
+	platform_set_drvdata(pdev, dvfsrc);
+
+	dvfsrc->regulator = platform_device_register_data(dvfsrc->dev,
+			"mtk-dvfsrc-regulator", -1, NULL, 0);
+	if (IS_ERR(dvfsrc->regulator)) {
+		dev_err(dvfsrc->dev, "Failed create regulator device\n");
+		ret = PTR_ERR(dvfsrc->regulator);
+		goto err;
+	}
+
+	dvfsrc->icc = platform_device_register_data(dvfsrc->dev,
+			"mediatek-emi-icc", -1, NULL, 0);
+	if (IS_ERR(dvfsrc->icc)) {
+		dev_err(dvfsrc->dev, "Failed create icc device\n");
+		ret = PTR_ERR(dvfsrc->icc);
+		goto unregister_regulator;
+	}
+
+	ret = devm_of_platform_populate(&pdev->dev);
+	if (ret)
+		platform_device_unregister(dvfsrc->icc);
+
+	return 0;
+
+unregister_regulator:
+	platform_device_unregister(dvfsrc->regulator);
+err:
+	return ret;
+}
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4[] = {
+	{0, 0}, {0, 1}, {0, 2}, {1, 2},
+};
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp3[] = {
+	{0, 0}, {0, 1}, {1, 1}, {1, 2},
+};
+
+static const struct dvfsrc_opp_desc dvfsrc_opp_mt8183_desc[] = {
+	DVFSRC_OPP_DESC(dvfsrc_opp_mt8183_lp4),
+	DVFSRC_OPP_DESC(dvfsrc_opp_mt8183_lp3),
+	DVFSRC_OPP_DESC(dvfsrc_opp_mt8183_lp3),
+};
+
+static const struct dvfsrc_soc_data mt8183_data = {
+	.opps_desc = dvfsrc_opp_mt8183_desc,
+	.regs = mt8183_regs,
+	.get_target_level = mt8183_get_target_level,
+	.get_current_level = mt8183_get_current_level,
+	.get_vcore_level = mt8183_get_vcore_level,
+	.set_dram_bw = mt8183_set_dram_bw,
+	.set_opp_level = mt8183_set_opp_level,
+	.set_vcore_level = mt8183_set_vcore_level,
+	.wait_for_opp_level = mt8183_wait_for_opp_level,
+	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level,
+};
+
+static int mtk_dvfsrc_remove(struct platform_device *pdev)
+{
+	struct mtk_dvfsrc *dvfsrc = platform_get_drvdata(pdev);
+
+	platform_device_unregister(dvfsrc->regulator);
+	platform_device_unregister(dvfsrc->icc);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_dvfsrc_of_match[] = {
+	{
+		.compatible = "mediatek,mt8183-dvfsrc",
+		.data = &mt8183_data,
+	}, {
+		/* sentinel */
+	},
+};
+
+static struct platform_driver mtk_dvfsrc_driver = {
+	.probe	= mtk_dvfsrc_probe,
+	.remove	= mtk_dvfsrc_remove,
+	.driver = {
+		.name = "mtk-dvfsrc",
+		.of_match_table = of_match_ptr(mtk_dvfsrc_of_match),
+	},
+};
+
+static int __init mtk_dvfsrc_init(void)
+{
+	return platform_driver_register(&mtk_dvfsrc_driver);
+}
+subsys_initcall(mtk_dvfsrc_init);
+
+static void __exit mtk_dvfsrc_exit(void)
+{
+	platform_driver_unregister(&mtk_dvfsrc_driver);
+}
+module_exit(mtk_dvfsrc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MTK DVFSRC driver");
diff --git a/include/linux/soc/mediatek/mtk_dvfsrc.h b/include/linux/soc/mediatek/mtk_dvfsrc.h
new file mode 100644
index 000000000000..823eff9bb19f
--- /dev/null
+++ b/include/linux/soc/mediatek/mtk_dvfsrc.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __SOC_MTK_DVFSRC_H
+#define __SOC_MTK_DVFSRC_H
+
+#define MTK_DVFSRC_CMD_BW_REQUEST		0
+#define MTK_DVFSRC_CMD_OPP_REQUEST		1
+#define MTK_DVFSRC_CMD_VCORE_REQUEST		2
+#define MTK_DVFSRC_CMD_HRTBW_REQUEST		3
+#define MTK_DVFSRC_CMD_VSCP_REQUEST		4
+#define MTK_DVFSRC_CMD_PEAK_BW_REQUEST		5
+
+#define MTK_DVFSRC_CMD_VCORE_LEVEL_QUERY	0
+#define MTK_DVFSRC_CMD_VSCP_LEVEL_QUERY		1
+
+#if IS_ENABLED(CONFIG_MTK_DVFSRC)
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data);
+int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd, int *data);
+
+#else
+
+static inline void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd,
+					   u64 data)
+{ return -ENODEV; }
+
+static inline int mtk_dvfsrc_query_info(const struct device *dev, u32 cmd,
+					int *data);
+{ return -ENODEV; }
+
+#endif /* CONFIG_MTK_DVFSRC */
+
+#endif
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:33 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:33 +0800
Subject: [V11,PATCH 06/19] soc: mediatek: add support for mt8195
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-7-dawei.chien@mediatek.com>

add support for mt8195

Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 drivers/soc/mediatek/mtk-dvfsrc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index 1f053367eabe..692846d8b233 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -505,6 +505,9 @@ static const struct of_device_id mtk_dvfsrc_of_match[] = {
 	}, {
 		.compatible = "mediatek,mt6873-dvfsrc",
 		.data = &mt6873_data,
+	}, {
+		.compatible = "mediatek,mt8195-dvfsrc",
+		.data = &mt6873_data,
 	}, {
 		/* sentinel */
 	},
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:28 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:28 +0800
Subject: [V11,PATCH 01/19] dt-bindings: soc: Add dvfsrc driver bindings
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-2-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Document the binding for enabling dvfsrc on MediaTek SoC.

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/soc/mediatek/dvfsrc.yaml   | 67 ++++++++++++++++++++++
 include/dt-bindings/interconnect/mtk,mt8183-emi.h  | 21 +++++++
 2 files changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml
 create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h

diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml
new file mode 100644
index 000000000000..f2b67b99921b
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/mediatek/dvfsrc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: MediaTek dynamic voltage and frequency scaling resource collector (DVFSRC)
+
+description: |
+  The Dynamic Voltage and Frequency Scaling Resource Collector (DVFSRC) is a
+  HW module which is used to collect all the requests from both software and
+  hardware and turn into the decision of minimum operating voltage and minimum
+  DRAM frequency to fulfill those requests.
+
+maintainers:
+  - henryc.chen <henryc.chen at mediatek.com>
+
+properties:
+  reg:
+    maxItems: 1
+    description: DVFSRC common register address and length.
+
+  compatible:
+    enum:
+      - mediatek,mt6873-dvfsrc
+      - mediatek,mt8183-dvfsrc
+      - mediatek,mt8192-dvfsrc
+
+  '#interconnect-cells':
+    const: 1
+
+  dvfsrc-vcore:
+    type: object
+    description:
+      The DVFSRC regulator is modelled as a subdevice of the DVFSRC.
+      Because DVFSRC can request power directly via register read/write, likes
+      vcore which is a core power of mt8183. As such, the DVFSRC regulator
+      requires that DVFSRC nodes be present.
+    $ref: /schemas/regulator/regulator.yaml#
+
+required:
+  - compatible
+  - reg
+  - "#interconnect-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interconnect/mtk,mt8183-emi.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        dvfsrc at 10012000 {
+            compatible = "mediatek,mt8183-dvfsrc";
+            reg = <0 0x10012000 0 0x1000>;
+            #interconnect-cells = <1>;
+            dvfsrc_vcore: dvfsrc-vcore {
+                    regulator-name = "dvfsrc-vcore";
+                    regulator-min-microvolt = <725000>;
+                    regulator-max-microvolt = <800000>;
+                    regulator-always-on;
+            };
+        };
+    };
diff --git a/include/dt-bindings/interconnect/mtk,mt8183-emi.h b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
new file mode 100644
index 000000000000..dfd143f87885
--- /dev/null
+++ b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+#define __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+
+#define MT8183_SLAVE_DDR_EMI			0
+#define MT8183_MASTER_MCUSYS			1
+#define MT8183_MASTER_GPU			2
+#define MT8183_MASTER_MMSYS			3
+#define MT8183_MASTER_MM_VPU			4
+#define MT8183_MASTER_MM_DISP			5
+#define MT8183_MASTER_MM_VDEC			6
+#define MT8183_MASTER_MM_VENC			7
+#define MT8183_MASTER_MM_CAM			8
+#define MT8183_MASTER_MM_IMG			9
+#define MT8183_MASTER_MM_MDP			10
+
+#endif
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:35 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:35 +0800
Subject: [V11,PATCH 08/19] arm64: dts: mt8192: add dvfsrc related nodes
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-9-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Enable dvfsrc on mt8192 platform.

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 9757138a8bbd..c70a3bf744fa 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -282,6 +282,12 @@
 			#interrupt-cells = <2>;
 		};
 
+		ddr_emi: dvfsrc at 10012000 {
+			compatible = "mediatek,mt8192-dvfsrc",
+				     "mediatek,mt6873-dvfsrc";
+			reg = <0 0x10012000 0 0x1000>;
+		};
+
 		systimer: timer at 10017000 {
 			compatible = "mediatek,mt8192-timer",
 				     "mediatek,mt6765-timer";
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:37 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:37 +0800
Subject: [V11, PATCH 10/19] dt-bindings: interconnect: add MT6873 interconnect
 dt-bindings
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-11-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Add interconnect provider dt-bindings for MT6873.

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 include/dt-bindings/interconnect/mtk,mt6873-emi.h | 41 +++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 include/dt-bindings/interconnect/mtk,mt6873-emi.h

diff --git a/include/dt-bindings/interconnect/mtk,mt6873-emi.h b/include/dt-bindings/interconnect/mtk,mt6873-emi.h
new file mode 100644
index 000000000000..0b20011df010
--- /dev/null
+++ b/include/dt-bindings/interconnect/mtk,mt6873-emi.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_MTK_MT6873_EMI_H
+#define __DT_BINDINGS_INTERCONNECT_MTK_MT6873_EMI_H
+
+#define MT6873_SLAVE_DDR_EMI		0
+#define MT6873_MASTER_MCUSYS		1
+#define MT6873_MASTER_GPUSYS		2
+#define MT6873_MASTER_MMSYS		3
+#define MT6873_MASTER_MM_VPU		4
+#define MT6873_MASTER_MM_DISP		5
+#define MT6873_MASTER_MM_VDEC		6
+#define MT6873_MASTER_MM_VENC		7
+#define MT6873_MASTER_MM_CAM		8
+#define MT6873_MASTER_MM_IMG		9
+#define MT6873_MASTER_MM_MDP		10
+#define MT6873_MASTER_VPUSYS		11
+#define MT6873_MASTER_VPU_0		12
+#define MT6873_MASTER_VPU_1		13
+#define MT6873_MASTER_MDLASYS		14
+#define MT6873_MASTER_MDLA_0		15
+#define MT6873_MASTER_UFS		16
+#define MT6873_MASTER_PCIE		17
+#define MT6873_MASTER_USB		18
+#define MT6873_MASTER_DBGIF		19
+#define MT6873_SLAVE_HRT_DDR_EMI	20
+#define MT6873_MASTER_HRT_MMSYS		21
+#define MT6873_MASTER_HRT_MM_DISP	22
+#define MT6873_MASTER_HRT_MM_VDEC	23
+#define MT6873_MASTER_HRT_MM_VENC	24
+#define MT6873_MASTER_HRT_MM_CAM	25
+#define MT6873_MASTER_HRT_MM_IMG	26
+#define MT6873_MASTER_HRT_MM_MDP	27
+#define MT6873_MASTER_HRT_DBGIF		28
+#define MT6873_MASTER_WIFI		29
+#define MT6873_MASTER_BT		30
+#define MT6873_MASTER_NETSYS		31
+#endif
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:43 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:43 +0800
Subject: [V11,PATCH 16/19] arm64: dts: mt8183: add dvfsrc related nodes
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-17-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Add DDR EMI provider dictating dram interconnect bus performance found on
MT8192-based platforms

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 7ad4cf646579..86f85c34c88a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -7,6 +7,7 @@
 
 #include <dt-bindings/clock/mt8183-clk.h>
 #include <dt-bindings/gce/mt8183-gce.h>
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/memory/mt8183-larb-port.h>
@@ -586,6 +587,7 @@
 		ddr_emi: dvfsrc at 10012000 {
 			compatible = "mediatek,mt8183-dvfsrc";
 			reg = <0 0x10012000 0 0x1000>;
+			#interconnect-cells = <1>;
 		};
 
 		pwrap: pwrap at 1000d000 {
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:41 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:41 +0800
Subject: [V11,PATCH 14/19] interconnect: mediatek: add initial bandwidth
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-15-dawei.chien@mediatek.com>

support get_bw function for suitable initial bandwidth

Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 drivers/interconnect/mediatek/mtk-emi.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
index 379dab77ebfd..80e2707698be 100644
--- a/drivers/interconnect/mediatek/mtk-emi.c
+++ b/drivers/interconnect/mediatek/mtk-emi.c
@@ -271,6 +271,14 @@ static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
 	return ret;
 }
 
+static int emi_icc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
+{
+	*avg = 0;
+	*peak = 0;
+
+	return 0;
+}
+
 static int emi_icc_remove(struct platform_device *pdev);
 static int emi_icc_probe(struct platform_device *pdev)
 {
@@ -308,6 +316,7 @@ static int emi_icc_probe(struct platform_device *pdev)
 	provider->set = emi_icc_set;
 	provider->aggregate = emi_icc_aggregate;
 	provider->xlate = of_icc_xlate_onecell;
+	provider->get_bw = emi_icc_get_bw;
 	INIT_LIST_HEAD(&provider->nodes);
 	provider->data = data;
 
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:46 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:46 +0800
Subject: [V11,PATCH 19/19] arm64: dts: mt8195: add dvfsrc related nodes
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-20-dawei.chien@mediatek.com>

Add DDR EMI provider dictating dram interconnect bus performance
found on MT8195-based platforms

Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 19430f324ee1..b010aed83906 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include <dt-bindings/clock/mt8195-clk.h>
+#include <dt-bindings/interconnect/mtk,mt8195-emi.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/power/mt8195-power.h>
@@ -689,6 +690,7 @@
 		ddr_emi: dvfsrc at 10012000 {
 			compatible = "mediatek,mt8195-dvfsrc";
 			reg = <0 0x10012000 0 0x1000>;
+			#interconnect-cells = <1>;
 		};
 
 		systimer: timer at 10017000 {
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:32 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:32 +0800
Subject: [V11,PATCH 05/19] soc: mediatek: add support for mt6873
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-6-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

add support for mt6873

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
 drivers/soc/mediatek/mtk-dvfsrc.c | 114 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index 6ef167cf55bd..1f053367eabe 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -102,6 +102,16 @@ static const int mt8183_regs[] = {
 	[DVFSRC_SW_BW] =	0x160,
 };
 
+static const int mt6873_regs[] = {
+	[DVFSRC_SW_REQ] =		0xC,
+	[DVFSRC_LEVEL] =		0xD44,
+	[DVFSRC_SW_PEAK_BW] =		0x278,
+	[DVFSRC_SW_BW] =		0x26C,
+	[DVFSRC_SW_HRT_BW] =		0x290,
+	[DVFSRC_TARGET_LEVEL] =		0xD48,
+	[DVFSRC_VCORE_REQUEST] =	0x6C,
+};
+
 static const struct dvfsrc_opp *get_current_opp(struct mtk_dvfsrc *dvfsrc)
 {
 	int level;
@@ -127,6 +137,78 @@ static int dvfsrc_wait_for_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
 					 POLL_TIMEOUT);
 }
 
+static int mt6873_get_target_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return dvfsrc_read(dvfsrc, DVFSRC_TARGET_LEVEL);
+}
+
+static int mt6873_get_current_level(struct mtk_dvfsrc *dvfsrc)
+{
+	u32 curr_level;
+
+	/* HW level 0 is begin from 0x1, and max opp is 0x1*/
+	curr_level = ffs(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+	if (curr_level > dvfsrc->curr_opps->num_opp)
+		curr_level = 0;
+	else
+		curr_level = dvfsrc->curr_opps->num_opp - curr_level;
+
+	return curr_level;
+}
+
+static int mt6873_wait_for_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	const struct dvfsrc_opp *target, *curr;
+
+	target = &dvfsrc->curr_opps->opps[level];
+	return readx_poll_timeout_atomic(get_current_opp, dvfsrc, curr,
+		curr->dram_opp >= target->dram_opp,
+		STARTUP_TIME, POLL_TIMEOUT);
+}
+
+static u32 mt6873_get_vcore_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return (dvfsrc_read(dvfsrc, DVFSRC_SW_REQ) >> 4) & 0x7;
+}
+
+static u32 mt6873_get_vcp_level(struct mtk_dvfsrc *dvfsrc)
+{
+	return (dvfsrc_read(dvfsrc, DVFSRC_VCORE_REQUEST) >> 12) & 0x7;
+}
+
+static void mt6873_set_dram_bw(struct mtk_dvfsrc *dvfsrc, u64 bw)
+{
+	bw = div_u64(kbps_to_mbps(bw), 100);
+	bw = min_t(u64, bw, 0xFF);
+	dvfsrc_write(dvfsrc, DVFSRC_SW_BW, bw);
+}
+
+static void mt6873_set_dram_peak_bw(struct mtk_dvfsrc *dvfsrc, u64 bw)
+{
+	bw = div_u64(kbps_to_mbps(bw), 100);
+	bw = min_t(u64, bw, 0xFF);
+	dvfsrc_write(dvfsrc, DVFSRC_SW_PEAK_BW, bw);
+}
+
+static void mt6873_set_dram_hrtbw(struct mtk_dvfsrc *dvfsrc, u64 bw)
+{
+	bw = div_u64((kbps_to_mbps(bw) + 29), 30);
+	bw = min_t(u64, bw, 0x3FF);
+	dvfsrc_write(dvfsrc, DVFSRC_SW_HRT_BW, bw);
+}
+
+static void mt6873_set_vcore_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	spin_lock(&dvfsrc->req_lock);
+	dvfsrc_rmw(dvfsrc, DVFSRC_SW_REQ, level, 0x7, 4);
+	spin_unlock(&dvfsrc->req_lock);
+}
+
+static void mt6873_set_vscp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+	dvfsrc_rmw(dvfsrc, DVFSRC_VCORE_REQUEST, level, 0x7, 12);
+}
+
 static int mt8183_wait_for_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
 {
 	const struct dvfsrc_opp *target, *curr;
@@ -377,6 +459,35 @@ static const struct dvfsrc_soc_data mt8183_data = {
 	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level,
 };
 
+static const struct dvfsrc_opp dvfsrc_opp_mt6873_lp4[] = {
+	{0, 0}, {1, 0}, {2, 0}, {3, 0},
+	{0, 1}, {1, 1}, {2, 1}, {3, 1},
+	{0, 2}, {1, 2}, {2, 2}, {3, 2},
+	{1, 3}, {2, 3}, {3, 3}, {1, 4},
+	{2, 4}, {3, 4}, {2, 5}, {3, 5},
+	{3, 6},
+};
+
+static const struct dvfsrc_opp_desc dvfsrc_opp_mt6873_desc[] = {
+	DVFSRC_OPP_DESC(dvfsrc_opp_mt6873_lp4),
+};
+
+static const struct dvfsrc_soc_data mt6873_data = {
+	.opps_desc = dvfsrc_opp_mt6873_desc,
+	.regs = mt6873_regs,
+	.get_target_level = mt6873_get_target_level,
+	.get_current_level = mt6873_get_current_level,
+	.get_vcore_level = mt6873_get_vcore_level,
+	.get_vcp_level = mt6873_get_vcp_level,
+	.set_dram_bw = mt6873_set_dram_bw,
+	.set_dram_peak_bw = mt6873_set_dram_peak_bw,
+	.set_dram_hrtbw = mt6873_set_dram_hrtbw,
+	.set_vcore_level = mt6873_set_vcore_level,
+	.set_vscp_level = mt6873_set_vscp_level,
+	.wait_for_opp_level = mt6873_wait_for_opp_level,
+	.wait_for_vcore_level = dvfsrc_wait_for_vcore_level,
+};
+
 static int mtk_dvfsrc_remove(struct platform_device *pdev)
 {
 	struct mtk_dvfsrc *dvfsrc = platform_get_drvdata(pdev);
@@ -391,6 +502,9 @@ static const struct of_device_id mtk_dvfsrc_of_match[] = {
 	{
 		.compatible = "mediatek,mt8183-dvfsrc",
 		.data = &mt8183_data,
+	}, {
+		.compatible = "mediatek,mt6873-dvfsrc",
+		.data = &mt6873_data,
 	}, {
 		/* sentinel */
 	},
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:30 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:30 +0800
Subject: [V11,
 PATCH 03/19] soc: mediatek: add header for mediatek SIP interface
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-4-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Add a header to collect SIPs and add one SIP call to initialize power
management hardware for the SIP interface defined to access the SPM
handling vcore voltage and ddr rate changes on mt8183 (and most likely
later socs).

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
Signed-off-by: Arvin Wang <arvin.wang at mediatek.com>
---
 include/linux/soc/mediatek/mtk_sip_svc.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/linux/soc/mediatek/mtk_sip_svc.h b/include/linux/soc/mediatek/mtk_sip_svc.h
index 082398e0cfb1..079bbcb361ba 100644
--- a/include/linux/soc/mediatek/mtk_sip_svc.h
+++ b/include/linux/soc/mediatek/mtk_sip_svc.h
@@ -22,4 +22,8 @@
 	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, MTK_SIP_SMC_CONVENTION, \
 			   ARM_SMCCC_OWNER_SIP, fn_id)
 
+/* VCOREFS */
+#define MTK_SIP_VCOREFS_CONTROL \
+	MTK_SIP_SMC_CMD(0x506)
+
 #endif
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:36 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:36 +0800
Subject: [V11,PATCH 09/19] arm64: dts: mt8195: add dvfsrc related nodes
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-10-dawei.chien@mediatek.com>

Enable dvfsrc on mt8195 platform.

Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index c146a91c6272..19430f324ee1 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -686,6 +686,11 @@
 			#clock-cells = <1>;
 		};
 
+		ddr_emi: dvfsrc at 10012000 {
+			compatible = "mediatek,mt8195-dvfsrc";
+			reg = <0 0x10012000 0 0x1000>;
+		};
+
 		systimer: timer at 10017000 {
 			compatible = "mediatek,mt8195-timer", "mediatek,mt6765-timer";
 			reg = <0 0x10017000 0 0x1000>;
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:27 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:27 +0800
Subject: [PATCH 00/19] Add driver for dvfsrc, support for interconnect
Message-ID: <20210812085846.2628-1-dawei.chien@mediatek.com>

This series is based on v5.14-rc1.

The patchsets add support for MediaTek hardware module named DVFSRC
(dynamic voltage and frequency scaling resource collector). The DVFSRC is
a HW module which is used to collect all the requests from both software
and hardware and turn into the decision of minimum operating voltage and
minimum DRAM frequency to fulfill those requests.

So, This series is to implement the dvfsrc driver to collect all the
requests of operating voltage or DRAM bandwidth from other device drivers
likes GPU/Camera through 3 frameworks basically:

1. interconnect framework: to aggregate the bandwidth
   requirements from different clients

[1] https://patchwork.kernel.org/cover/10766329/

There has a hw module "DRAM scheduler", which used to control the
throughput.
The DVFSRC will collect forecast data of dram bandwidth from
SW consumers(camera/gpu...), and according the forecast to change the DRAM
frequency

2. Regualtor framework: to handle the operating voltage requirement from
   user or cosumer which not belong any power domain

Changes in V11:
* rebase all patches on v5.14-rc1.
* support platform mt8195.
* add initial bw in mediatek interconnect driver.
* add one more pcie client in mediatek interconnect driver.
* add compatible for MT8195 dvfsrc.

Changes in V10:
* rebase all patches on v5.13-rc1
* add acked TAG for interconnect provider driver (Georgi)
* update comment message for typos. (Georgi)
* update cover leter for typos.

Changes in V9:
* modify the configuration of dvfsrc.yaml. (Rob)

Changes in V8:
* Fixed the dt_binding_check error of dvfsrc.yaml. (Rob)
* Remove Kconfig dependency of DVFSRC

Changes in V7:
* Fixed the dt_binding_check error of dvfsrc.yaml. (Rob)
* Fixed the checkpatch complains of "Signed-off-by:
email name mismatch". (Georgi)
* Fixed coding style of interconnect driver. (Georgi)
* Update comment of the years to 2021. (Georgi)

Changes in V6:
* Remove the performace state support, because the request from consumer
can be replaced by using interconnect and regulator framework.
* Update the DT patches and convert them to DT schema. (Georgi)
* Modify the comment format and coding style. (Mark)

Changes in V5:
* Support more platform mt6873/mt8192
* Drop the compatible and interconnect provider node and make the parent
node an interconnect provider. (Rob/Georgi)
* Make modification of interconnect driver from coding suggestion. (Georgi)
* Move interconnect diagram into the commit text of patch. (Georgi)
* Register the interconnect provider as a platform sub-device. (Georgi)

Changes in V4:
* Add acked TAG on dt-bindings patches. (Rob)
* Declaration of emi_icc_aggregate since the prototype of aggregate
function has changed meanwhile. (Georgi)
* Used emi_icc_remove instead of icc_provider_del on probe. (Georgi)
* Add dvfsrc regulator driver into series.
* Bug fixed of mt8183_get_current_level.
* Add mutex protection for pstate operation on dvfsrc_set_performance.

Changes in V3:
* Remove RFC from the subject prefix of the series
* Combine dt-binding patch and move interconnect dt-binding document into
dvfsrc. (Rob)
* Remove unused header, add unit descirption to the bandwidth, rename
compatible name on interconnect driver. (Georgi)
* Fixed some coding style: check flow, naming, used readx_poll_timeout
on dvfsrc driver. (Ryan)
* Rename interconnect driver mt8183.c to mtk-emi.c
* Rename interconnect header mtk,mt8183.h to mtk,emi.h
* mtk-scpsys.c: Add opp table check first to avoid OF runtime parse failed

Changes in RFC V2:
* Remove the DT property dram_type. (Rob)
* Used generic dts property 'opp-level' to get the performace
state. (Stephen)
* Remove unnecessary dependency config on Kconfig. (Stephen)
* Remove unused header file, fixed some coding style issue, typo,
error handling on dvfsrc driver. (Nicolas/Stephen)
* Remove irq handler on dvfsrc driver. (Stephen)
* Remove init table on dvfsrc driver, combine hw init on trustzone.
* Add interconnect support of mt8183 to aggregate the emi bandwidth.
(Georgi)

v10: https://patchwork.kernel.org/project/linux-mediatek/list/?series=494095
V9: https://patchwork.kernel.org/project/linux-mediatek/list/?series=440389
V8: https://patchwork.kernel.org/project/linux-mediatek/list/?series=421713
V7: https://patchwork.kernel.org/project/linux-mediatek/list/?series=411057
V6: https://patchwork.kernel.org/project/linux-mediatek/list/?series=406077
V5: https://patchwork.kernel.org/project/linux-mediatek/list/?series=348065
V4: https://lore.kernel.org/patchwork/cover/1209284/
V3: https://patchwork.kernel.org/cover/11118867/
RFC V2: https://lore.kernel.org/patchwork/patch/1068113/
RFC V1: https://lore.kernel.org/patchwork/cover/1028535/

Dawei Chien (8):
  dt-bindings: mediatek: add compatible for MT8195 dvfsrc
  soc: mediatek: add support for mt8195
  arm64: dts: mt8195: add dvfsrc related nodes
  dt-bindings: interconnect: add MT8195 interconnect dt-bindings
  interconnect: mediatek: add support for mt8195
  interconnect: mediatek: add initial bandwidth
  regulator: mediatek: add support for mt8195
  arm64: dts: mt8195: add dvfsrc related nodes

Henry Chen (11):
  dt-bindings: soc: Add dvfsrc driver bindings
  soc: mediatek: add header for mediatek SIP interface
  soc: mediatek: add driver for dvfsrc support
  soc: mediatek: add support for mt6873
  arm64: dts: mt8183: add dvfsrc related nodes
  arm64: dts: mt8192: add dvfsrc related nodes
  dt-bindings: interconnect: add MT6873 interconnect dt-bindings
  interconnect: mediatek: Add interconnect provider driver
  arm64: dts: mt8183: add dvfsrc related nodes
  arm64: dts: mt8192: add dvfsrc related nodes
  arm64: dts: mt8192: add dvfsrc regulator nodes

 .../devicetree/bindings/soc/mediatek/dvfsrc.yaml   |  68 +++
 arch/arm64/boot/dts/mediatek/mt8183.dtsi           |   7 +
 arch/arm64/boot/dts/mediatek/mt8192.dtsi           |  14 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi           |   7 +
 drivers/interconnect/Kconfig                       |   1 +
 drivers/interconnect/Makefile                      |   1 +
 drivers/interconnect/mediatek/Kconfig              |  13 +
 drivers/interconnect/mediatek/Makefile             |   3 +
 drivers/interconnect/mediatek/mtk-emi.c            | 385 +++++++++++++++
 drivers/regulator/mtk-dvfsrc-regulator.c           |  23 +
 drivers/soc/mediatek/Kconfig                       |  11 +
 drivers/soc/mediatek/Makefile                      |   1 +
 drivers/soc/mediatek/mtk-dvfsrc.c                  | 538 +++++++++++++++++++++
 include/dt-bindings/interconnect/mtk,mt6873-emi.h  |  41 ++
 include/dt-bindings/interconnect/mtk,mt8183-emi.h  |  21 +
 include/dt-bindings/interconnect/mtk,mt8195-emi.h  |  42 ++
 include/linux/soc/mediatek/mtk_dvfsrc.h            |  35 ++
 include/linux/soc/mediatek/mtk_sip_svc.h           |   4 +
 18 files changed, 1215 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml
 create mode 100644 drivers/interconnect/mediatek/Kconfig
 create mode 100644 drivers/interconnect/mediatek/Makefile
 create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
 create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
 create mode 100644 include/dt-bindings/interconnect/mtk,mt6873-emi.h
 create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h
 create mode 100644 include/dt-bindings/interconnect/mtk,mt8195-emi.h
 create mode 100644 include/linux/soc/mediatek/mtk_dvfsrc.h

-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:39 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:39 +0800
Subject: [V11,
 PATCH 12/19] interconnect: mediatek: Add interconnect provider driver
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-13-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Introduce Mediatek MT6873/MT8183/MT8192 specific provider driver
using the interconnect framework.

             ICC provider         ICC Nodes
                              ----          ----
             ---------       |CPU |   |--- |VPU |
    -----   |         |-----  ----    |     ----
   |DRAM |--|DRAM     |       ----    |     ----
   |     |--|scheduler|----- |GPU |   |--- |DISP|
   |     |--|(EMI)    |       ----    |     ----
   |     |--|         |       -----   |     ----
    -----   |         |----- |MMSYS|--|--- |VDEC|
             ---------        -----   |     ----
               /|\                    |     ----
                |change DRAM freq     |--- |VENC|
             ----------               |     ----
            |  DVFSR   |              |
            |          |              |     ----
             ----------               |--- |IMG |
                                      |     ----
                                      |     ----
                                      |--- |CAM |
                                            ----
Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
Reviewed-by: Georgi Djakov <georgi.djakov at linaro.org>
---
 drivers/interconnect/Kconfig            |   1 +
 drivers/interconnect/Makefile           |   1 +
 drivers/interconnect/mediatek/Kconfig   |  13 ++
 drivers/interconnect/mediatek/Makefile  |   3 +
 drivers/interconnect/mediatek/mtk-emi.c | 331 ++++++++++++++++++++++++++++++++
 5 files changed, 349 insertions(+)
 create mode 100644 drivers/interconnect/mediatek/Kconfig
 create mode 100644 drivers/interconnect/mediatek/Makefile
 create mode 100644 drivers/interconnect/mediatek/mtk-emi.c

diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
index d637a89d4695..da91f847aabd 100644
--- a/drivers/interconnect/Kconfig
+++ b/drivers/interconnect/Kconfig
@@ -12,6 +12,7 @@ menuconfig INTERCONNECT
 if INTERCONNECT
 
 source "drivers/interconnect/imx/Kconfig"
+source "drivers/interconnect/mediatek/Kconfig"
 source "drivers/interconnect/qcom/Kconfig"
 source "drivers/interconnect/samsung/Kconfig"
 
diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
index 97d393fd638d..d697500d99f0 100644
--- a/drivers/interconnect/Makefile
+++ b/drivers/interconnect/Makefile
@@ -5,5 +5,6 @@ icc-core-objs				:= core.o bulk.o
 
 obj-$(CONFIG_INTERCONNECT)		+= icc-core.o
 obj-$(CONFIG_INTERCONNECT_IMX)		+= imx/
+obj-$(CONFIG_INTERCONNECT_MTK)		+= mediatek/
 obj-$(CONFIG_INTERCONNECT_QCOM)		+= qcom/
 obj-$(CONFIG_INTERCONNECT_SAMSUNG)	+= samsung/
diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
new file mode 100644
index 000000000000..ec98d6a80f55
--- /dev/null
+++ b/drivers/interconnect/mediatek/Kconfig
@@ -0,0 +1,13 @@
+config INTERCONNECT_MTK
+	bool "Mediatek Network-on-Chip interconnect drivers"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  Support for Mediatek's Network-on-Chip interconnect hardware.
+
+config INTERCONNECT_MTK_EMI
+	tristate "Mediatek EMI interconnect driver"
+	depends on INTERCONNECT_MTK
+	depends on (MTK_DVFSRC && OF) || COMPILE_TEST
+	help
+	  This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
+	  platforms.
diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
new file mode 100644
index 000000000000..353842b2c273
--- /dev/null
+++ b/drivers/interconnect/mediatek/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
\ No newline at end of file
diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
new file mode 100644
index 000000000000..8d650be62b90
--- /dev/null
+++ b/drivers/interconnect/mediatek/mtk-emi.c
@@ -0,0 +1,331 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk_dvfsrc.h>
+#include <dt-bindings/interconnect/mtk,mt6873-emi.h>
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
+
+enum mtk_icc_name {
+	SLAVE_DDR_EMI,
+	MASTER_MCUSYS,
+	MASTER_GPUSYS,
+	MASTER_MMSYS,
+	MASTER_MM_VPU,
+	MASTER_MM_DISP,
+	MASTER_MM_VDEC,
+	MASTER_MM_VENC,
+	MASTER_MM_CAM,
+	MASTER_MM_IMG,
+	MASTER_MM_MDP,
+	MASTER_VPUSYS,
+	MASTER_VPU_PORT_0,
+	MASTER_VPU_PORT_1,
+	MASTER_MDLASYS,
+	MASTER_MDLA_PORT_0,
+	MASTER_UFS,
+	MASTER_PCIE,
+	MASTER_USB,
+	MASTER_WIFI,
+	MASTER_BT,
+	MASTER_NETSYS,
+	MASTER_DBGIF,
+
+	SLAVE_HRT_DDR_EMI,
+	MASTER_HRT_MMSYS,
+	MASTER_HRT_MM_DISP,
+	MASTER_HRT_MM_VDEC,
+	MASTER_HRT_MM_VENC,
+	MASTER_HRT_MM_CAM,
+	MASTER_HRT_MM_IMG,
+	MASTER_HRT_MM_MDP,
+	MASTER_HRT_DBGIF,
+};
+
+#define MT8183_MAX_LINKS	1
+
+/**
+ * struct mtk_icc_node - Mediatek specific interconnect nodes
+ * @name: the node name used in debugfs
+ * @ep : the type of this endpoint
+ * @id: a unique node identifier
+ * @links: an array of nodes where we can go next while traversing
+ * @num_links: the total number of @links
+ * @sum_avg: current sum aggregate value of all avg bw kBps requests
+ * @max_peak: current max aggregate value of all peak bw kBps requests
+ */
+struct mtk_icc_node {
+	unsigned char *name;
+	int ep;
+	u16 id;
+	u16 links[MT8183_MAX_LINKS];
+	u16 num_links;
+	u64 sum_avg;
+	u64 max_peak;
+};
+
+struct mtk_icc_desc {
+	struct mtk_icc_node **nodes;
+	size_t num_nodes;
+};
+
+#define DEFINE_MNODE(_name, _id, _ep, ...)	\
+		static struct mtk_icc_node _name = {			\
+		.name = #_name,						\
+		.id = _id,						\
+		.ep = _ep,						\
+		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
+		.links = { __VA_ARGS__ },				\
+}
+
+DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1);
+DEFINE_MNODE(mcusys, MASTER_MCUSYS, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(gpu, MASTER_GPUSYS, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mmsys, MASTER_MMSYS, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_img, MASTER_MM_IMG, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 0, MASTER_MMSYS);
+DEFINE_MNODE(vpusys, MASTER_VPUSYS, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(vpu_port_0, MASTER_VPU_PORT_0, 0, MASTER_VPUSYS);
+DEFINE_MNODE(vpu_port_1, MASTER_VPU_PORT_1, 0, MASTER_VPUSYS);
+DEFINE_MNODE(mdlasys, MASTER_MDLASYS, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mdla_port_0, MASTER_MDLA_PORT_0, 0, MASTER_MDLASYS);
+DEFINE_MNODE(ufs, MASTER_UFS, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(pcie, MASTER_PCIE, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(usb, MASTER_USB, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(wifi, MASTER_WIFI, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(bt, MASTER_BT, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(netsys, MASTER_NETSYS, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(dbgif, MASTER_DBGIF, 0, SLAVE_DDR_EMI);
+
+DEFINE_MNODE(hrt_ddr_emi, SLAVE_HRT_DDR_EMI, 2);
+DEFINE_MNODE(hrt_mmsys, MASTER_HRT_MMSYS, 0, SLAVE_HRT_DDR_EMI);
+DEFINE_MNODE(hrt_mm_disp, MASTER_HRT_MM_DISP, 0, MASTER_HRT_MMSYS);
+DEFINE_MNODE(hrt_mm_vdec, MASTER_HRT_MM_VDEC, 0, MASTER_HRT_MMSYS);
+DEFINE_MNODE(hrt_mm_venc, MASTER_HRT_MM_VENC, 0, MASTER_HRT_MMSYS);
+DEFINE_MNODE(hrt_mm_cam, MASTER_HRT_MM_CAM, 0, MASTER_HRT_MMSYS);
+DEFINE_MNODE(hrt_mm_img, MASTER_HRT_MM_IMG, 0, MASTER_HRT_MMSYS);
+DEFINE_MNODE(hrt_mm_mdp, MASTER_HRT_MM_MDP, 0, MASTER_HRT_MMSYS);
+DEFINE_MNODE(hrt_dbgif, MASTER_HRT_DBGIF, 0, SLAVE_HRT_DDR_EMI);
+
+static struct mtk_icc_node *mt8183_icc_nodes[] = {
+	[MT8183_SLAVE_DDR_EMI] = &ddr_emi,
+	[MT8183_MASTER_MCUSYS] = &mcusys,
+	[MT8183_MASTER_GPU] = &gpu,
+	[MT8183_MASTER_MMSYS] = &mmsys,
+	[MT8183_MASTER_MM_VPU] = &mm_vpu,
+	[MT8183_MASTER_MM_DISP] = &mm_disp,
+	[MT8183_MASTER_MM_VDEC] = &mm_vdec,
+	[MT8183_MASTER_MM_VENC] = &mm_venc,
+	[MT8183_MASTER_MM_CAM] = &mm_cam,
+	[MT8183_MASTER_MM_IMG] = &mm_img,
+	[MT8183_MASTER_MM_MDP] = &mm_mdp,
+};
+
+static const struct mtk_icc_desc mt8183_icc = {
+	.nodes = mt8183_icc_nodes,
+	.num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
+};
+
+static struct mtk_icc_node *mt6873_icc_nodes[] = {
+	[MT6873_SLAVE_DDR_EMI] = &ddr_emi,
+	[MT6873_MASTER_MCUSYS] = &mcusys,
+	[MT6873_MASTER_GPUSYS] = &gpu,
+	[MT6873_MASTER_MMSYS] = &mmsys,
+	[MT6873_MASTER_MM_VPU] = &mm_vpu,
+	[MT6873_MASTER_MM_DISP] = &mm_disp,
+	[MT6873_MASTER_MM_VDEC] = &mm_vdec,
+	[MT6873_MASTER_MM_VENC] = &mm_venc,
+	[MT6873_MASTER_MM_CAM] = &mm_cam,
+	[MT6873_MASTER_MM_IMG] = &mm_img,
+	[MT6873_MASTER_MM_MDP] = &mm_mdp,
+	[MT6873_MASTER_VPUSYS] = &vpusys,
+	[MT6873_MASTER_VPU_0] = &vpu_port_0,
+	[MT6873_MASTER_VPU_1] = &vpu_port_1,
+	[MT6873_MASTER_MDLASYS] = &mdlasys,
+	[MT6873_MASTER_MDLA_0] = &mdla_port_0,
+	[MT6873_MASTER_UFS] = &ufs,
+	[MT6873_MASTER_PCIE] = &pcie,
+	[MT6873_MASTER_USB] = &usb,
+	[MT6873_MASTER_WIFI] = &wifi,
+	[MT6873_MASTER_BT] = &bt,
+	[MT6873_MASTER_NETSYS] = &netsys,
+	[MT6873_MASTER_DBGIF] = &dbgif,
+
+	[MT6873_SLAVE_HRT_DDR_EMI] = &hrt_ddr_emi,
+	[MT6873_MASTER_HRT_MMSYS] = &hrt_mmsys,
+	[MT6873_MASTER_HRT_MM_DISP] = &hrt_mm_disp,
+	[MT6873_MASTER_HRT_MM_VDEC] = &hrt_mm_vdec,
+	[MT6873_MASTER_HRT_MM_VENC] = &hrt_mm_venc,
+	[MT6873_MASTER_HRT_MM_CAM] = &hrt_mm_cam,
+	[MT6873_MASTER_HRT_MM_IMG] = &hrt_mm_img,
+	[MT6873_MASTER_HRT_MM_MDP] = &hrt_mm_mdp,
+	[MT6873_MASTER_HRT_DBGIF] = &hrt_dbgif,
+};
+
+static struct mtk_icc_desc mt6873_icc = {
+	.nodes = mt6873_icc_nodes,
+	.num_nodes = ARRAY_SIZE(mt6873_icc_nodes),
+};
+
+static const struct of_device_id emi_icc_of_match[] = {
+	{ .compatible = "mediatek,mt8183-dvfsrc", .data = &mt8183_icc },
+	{ .compatible = "mediatek,mt8192-dvfsrc", .data = &mt6873_icc },
+	{ .compatible = "mediatek,mt6873-dvfsrc", .data = &mt6873_icc },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, emi_icc_of_match);
+
+static int emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+			     u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	struct mtk_icc_node *in;
+
+	in = node->data;
+
+	*agg_avg += avg_bw;
+	*agg_peak = max_t(u32, *agg_peak, peak_bw);
+
+	in->sum_avg = *agg_avg;
+	in->max_peak = *agg_peak;
+
+	return 0;
+}
+
+static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	int ret = 0;
+	struct mtk_icc_node *node;
+
+	node = dst->data;
+
+	if (node->ep == 1) {
+		mtk_dvfsrc_send_request(src->provider->dev,
+					MTK_DVFSRC_CMD_PEAK_BW_REQUEST,
+					node->max_peak);
+		mtk_dvfsrc_send_request(src->provider->dev,
+					MTK_DVFSRC_CMD_BW_REQUEST,
+					node->sum_avg);
+	} else if (node->ep == 2) {
+		mtk_dvfsrc_send_request(src->provider->dev,
+					MTK_DVFSRC_CMD_HRTBW_REQUEST,
+					node->sum_avg);
+	}
+
+	return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev);
+static int emi_icc_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	const struct mtk_icc_desc *desc;
+	struct device *dev = &pdev->dev;
+	struct icc_node *node;
+	struct icc_onecell_data *data;
+	struct icc_provider *provider;
+	struct mtk_icc_node **mnodes;
+	size_t num_nodes, i, j;
+	int ret;
+
+	match = of_match_node(emi_icc_of_match, dev->parent->of_node);
+
+	if (!match) {
+		dev_err(dev, "invalid compatible string\n");
+		return -ENODEV;
+	}
+
+	desc = match->data;
+	mnodes = desc->nodes;
+	num_nodes = desc->num_nodes;
+
+	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
+			    GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	provider->dev = pdev->dev.parent;
+	provider->set = emi_icc_set;
+	provider->aggregate = emi_icc_aggregate;
+	provider->xlate = of_icc_xlate_onecell;
+	INIT_LIST_HEAD(&provider->nodes);
+	provider->data = data;
+
+	ret = icc_provider_add(provider);
+	if (ret) {
+		dev_err(&pdev->dev, "error adding interconnect provider\n");
+		return ret;
+	}
+
+	for (i = 0; i < num_nodes; i++) {
+		node = icc_node_create(mnodes[i]->id);
+		if (IS_ERR(node)) {
+			ret = PTR_ERR(node);
+			goto err;
+		}
+
+		node->name = mnodes[i]->name;
+		node->data = mnodes[i];
+		icc_node_add(node, provider);
+
+		for (j = 0; j < mnodes[i]->num_links; j++)
+			icc_link_create(node, mnodes[i]->links[j]);
+
+		data->nodes[i] = node;
+	}
+	data->num_nodes = num_nodes;
+
+	platform_set_drvdata(pdev, provider);
+
+	return 0;
+err:
+	icc_nodes_remove(provider);
+	icc_provider_del(provider);
+	return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev)
+{
+	struct icc_provider *provider = platform_get_drvdata(pdev);
+
+	icc_nodes_remove(provider);
+	return icc_provider_del(provider);
+}
+
+static struct platform_driver emi_icc_driver = {
+	.probe = emi_icc_probe,
+	.remove = emi_icc_remove,
+	.driver = {
+		.name = "mediatek-emi-icc",
+	},
+};
+
+static int __init mtk_emi_icc_init(void)
+{
+	return platform_driver_register(&emi_icc_driver);
+}
+subsys_initcall(mtk_emi_icc_init);
+
+static void __exit mtk_emi_icc_exit(void)
+{
+	platform_driver_unregister(&emi_icc_driver);
+}
+module_exit(mtk_emi_icc_exit);
+
+MODULE_AUTHOR("Henry Chen <henryc.chen at mediatek.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.14.1

From david at redhat.com  Thu Aug 12 02:04:58 2021
From: david at redhat.com (David Hildenbrand)
Date: Thu, 12 Aug 2021 11:04:58 +0200
Subject: [PATCH v2 1/2] KVM: Refactor kvm_arch_vcpu_fault() to return a
 struct page pointer
In-Reply-To: <1c510b24fc1d7cbae8aa4b69c0799ebd32e65b82.1628739116.git.houwenlong93@linux.alibaba.com>
References: <YRQcZqCWwVH8bCGc@google.com>
 <1c510b24fc1d7cbae8aa4b69c0799ebd32e65b82.1628739116.git.houwenlong93@linux.alibaba.com>
Message-ID: <98adbd3c-ec6f-5689-1686-2a8a7909951a@redhat.com>

On 12.08.21 06:02, Hou Wenlong wrote:
> From: Sean Christopherson <seanjc at google.com>
> 
> Refactor kvm_arch_vcpu_fault() to return 'struct page *' instead of
> 'vm_fault_t' to simplify architecture specific implementations that do
> more than return SIGBUS.  Currently this only applies to s390, but a
> future patch will move x86's pio_data handling into x86 where it belongs.
> 
> No functional changed intended.
> 
> Cc: Hou Wenlong <houwenlong93 at linux.alibaba.com>
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> Signed-off-by: Hou Wenlong <houwenlong93 at linux.alibaba.com>
> ---
>   arch/arm64/kvm/arm.c       |  4 ++--
>   arch/mips/kvm/mips.c       |  4 ++--
>   arch/powerpc/kvm/powerpc.c |  4 ++--
>   arch/s390/kvm/kvm-s390.c   | 12 ++++--------
>   arch/x86/kvm/x86.c         |  4 ++--
>   include/linux/kvm_host.h   |  2 +-
>   virt/kvm/kvm_main.c        |  5 ++++-
>   7 files changed, 17 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e9a2b8f27792..83f4ffe3e4f2 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -161,9 +161,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>   	return ret;
>   }
>   
> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>   {
> -	return VM_FAULT_SIGBUS;
> +	return NULL;
>   }
>   
>   
> diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
> index af9dd029a4e1..ae79874e6fd2 100644
> --- a/arch/mips/kvm/mips.c
> +++ b/arch/mips/kvm/mips.c
> @@ -1053,9 +1053,9 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
>   	return -ENOIOCTLCMD;
>   }
>   
> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>   {
> -	return VM_FAULT_SIGBUS;
> +	return NULL;
>   }
>   
>   int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index be33b5321a76..b9c21f9ab784 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -2090,9 +2090,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
>   	return r;
>   }
>   
> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>   {
> -	return VM_FAULT_SIGBUS;
> +	return NULL;
>   }
>   
>   static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo)
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index 02574d7b3612..e1b69833e228 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -4979,17 +4979,13 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
>   	return r;
>   }
>   
> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>   {
>   #ifdef CONFIG_KVM_S390_UCONTROL
> -	if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
> -		 && (kvm_is_ucontrol(vcpu->kvm))) {
> -		vmf->page = virt_to_page(vcpu->arch.sie_block);
> -		get_page(vmf->page);
> -		return 0;
> -	}
> +	if (vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET && kvm_is_ucontrol(vcpu->kvm))
> +		return virt_to_page(vcpu->arch.sie_block);
>   #endif
> -	return VM_FAULT_SIGBUS;
> +	return NULL;
>   }
>   
>   /* Section: memory related */
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 3cedc7cc132a..1e3bbe5cd33a 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -5347,9 +5347,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
>   	return r;
>   }
>   
> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>   {
> -	return VM_FAULT_SIGBUS;
> +	return NULL;
>   }
>   
>   static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr)
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 492d183dd7d0..a949de534722 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -995,7 +995,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
>   			unsigned int ioctl, unsigned long arg);
>   long kvm_arch_vcpu_ioctl(struct file *filp,
>   			 unsigned int ioctl, unsigned long arg);
> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
>   
>   int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext);
>   
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 30d322519253..f7d21418971b 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -3448,7 +3448,10 @@ static vm_fault_t kvm_vcpu_fault(struct vm_fault *vmf)
>   		    &vcpu->dirty_ring,
>   		    vmf->pgoff - KVM_DIRTY_LOG_PAGE_OFFSET);
>   	else
> -		return kvm_arch_vcpu_fault(vcpu, vmf);
> +		page = kvm_arch_vcpu_fault(vcpu, vmf);
> +	if (!page)
> +		return VM_FAULT_SIGBUS;
> +
>   	get_page(page);
>   	vmf->page = page;
>   	return 0;
> 

Reviewed-by: David Hildenbrand <david at redhat.com>

But at the same time I wonder if we should just get rid of 
CONFIG_KVM_S390_UCONTROL and consequently kvm_arch_vcpu_fault().


In practice CONFIG_KVM_S390_UCONTROL, is never enabled in any reasonable 
kernel build and consequently it's never tested; further, exposing the 
sie_block to user space allows user space to generate random SIE 
validity intercepts.

CONFIG_KVM_S390_UCONTROL feels like something that should just be 
maintained out of tree by someone who really needs to hack deep into hw 
virtualization for testing purposes etc.

-- 
Thanks,

David / dhildenb



From dawei.chien at mediatek.com  Thu Aug 12 01:58:38 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:38 +0800
Subject: [V11, PATCH 11/19] dt-bindings: interconnect: add MT8195 interconnect
 dt-bindings
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-12-dawei.chien@mediatek.com>

Add interconnect provider dt-bindings for MT8195

Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 include/dt-bindings/interconnect/mtk,mt8195-emi.h | 42 +++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 include/dt-bindings/interconnect/mtk,mt8195-emi.h

diff --git a/include/dt-bindings/interconnect/mtk,mt8195-emi.h b/include/dt-bindings/interconnect/mtk,mt8195-emi.h
new file mode 100644
index 000000000000..c7e8b805f8bd
--- /dev/null
+++ b/include/dt-bindings/interconnect/mtk,mt8195-emi.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_MTK_MT8195_EMI_H
+#define __DT_BINDINGS_INTERCONNECT_MTK_MT8195_EMI_H
+
+#define MT8195_SLAVE_DDR_EMI		0
+#define MT8195_MASTER_MCUSYS		1
+#define MT8195_MASTER_GPUSYS		2
+#define MT8195_MASTER_MMSYS		3
+#define MT8195_MASTER_MM_VPU		4
+#define MT8195_MASTER_MM_DISP		5
+#define MT8195_MASTER_MM_VDEC		6
+#define MT8195_MASTER_MM_VENC		7
+#define MT8195_MASTER_MM_CAM		8
+#define MT8195_MASTER_MM_IMG		9
+#define MT8195_MASTER_MM_MDP		10
+#define MT8195_MASTER_VPUSYS		11
+#define MT8195_MASTER_VPU_0		12
+#define MT8195_MASTER_VPU_1		13
+#define MT8195_MASTER_MDLASYS		14
+#define MT8195_MASTER_MDLA_0		15
+#define MT8195_MASTER_UFS		16
+#define MT8195_MASTER_PCIE_0		17
+#define MT8195_MASTER_PCIE_1		18
+#define MT8195_MASTER_USB		19
+#define MT8195_MASTER_DBGIF		20
+#define MT8195_SLAVE_HRT_DDR_EMI	21
+#define MT8195_MASTER_HRT_MMSYS		22
+#define MT8195_MASTER_HRT_MM_DISP	23
+#define MT8195_MASTER_HRT_MM_VDEC	24
+#define MT8195_MASTER_HRT_MM_VENC	25
+#define MT8195_MASTER_HRT_MM_CAM	26
+#define MT8195_MASTER_HRT_MM_IMG	27
+#define MT8195_MASTER_HRT_MM_MDP	28
+#define MT8195_MASTER_HRT_DBGIF		29
+#define MT8195_MASTER_WIFI		30
+#define MT8195_MASTER_BT		31
+#define MT8195_MASTER_NETSYS		32
+#endif
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:45 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:45 +0800
Subject: [V11,PATCH 18/19] arm64: dts: mt8192: add dvfsrc regulator nodes
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-19-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Add dvfsrc regulator nodes which is for MT8192-based platforms

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index ab3dabcc722e..6aad5ff0646c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -288,6 +288,12 @@
 				     "mediatek,mt6873-dvfsrc";
 			reg = <0 0x10012000 0 0x1000>;
 			#interconnect-cells = <1>;
+			dvfsrc_vcore: dvfsrc-vcore {
+				regulator-name = "dvfsrc-vcore";
+				regulator-min-microvolt = <575000>;
+				regulator-max-microvolt = <725000>;
+				regulator-always-on;
+			};
 		};
 
 		systimer: timer at 10017000 {
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:42 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:42 +0800
Subject: [V11,PATCH 15/19] regulator: mediatek: add support for mt8195
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-16-dawei.chien@mediatek.com>

add platform data on mt8195

Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 drivers/regulator/mtk-dvfsrc-regulator.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/regulator/mtk-dvfsrc-regulator.c b/drivers/regulator/mtk-dvfsrc-regulator.c
index d3d876198d6e..1bd6e67b1de5 100644
--- a/drivers/regulator/mtk-dvfsrc-regulator.c
+++ b/drivers/regulator/mtk-dvfsrc-regulator.c
@@ -140,6 +140,25 @@ static const struct dvfsrc_regulator_init_data regulator_mt6873_data = {
 	.regulator_info = &mt6873_regulators[0],
 };
 
+static const unsigned int mt8195_voltages[] = {
+	550000,
+	600000,
+	650000,
+	750000,
+};
+
+static struct dvfsrc_regulator mt8195_regulators[] = {
+	MT_DVFSRC_REGULAR("dvfsrc-vcore", VCORE,
+			  mt8195_voltages),
+	MT_DVFSRC_REGULAR("dvfsrc-vscp", VSCP,
+			  mt8195_voltages),
+};
+
+static const struct dvfsrc_regulator_init_data regulator_mt8195_data = {
+	.size = ARRAY_SIZE(mt8195_regulators),
+	.regulator_info = &mt8195_regulators[0],
+};
+
 static const struct of_device_id mtk_dvfsrc_regulator_match[] = {
 	{
 		.compatible = "mediatek,mt8183-dvfsrc",
@@ -150,6 +169,10 @@ static const struct of_device_id mtk_dvfsrc_regulator_match[] = {
 	}, {
 		.compatible = "mediatek,mt6873-dvfsrc",
 		.data = &regulator_mt6873_data,
+	}, {
+		.compatible = "mediatek,mt8195-dvfsrc",
+		.data = &regulator_mt8195_data,
+	}, {
 	}, {
 		/* sentinel */
 	},
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:44 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:44 +0800
Subject: [V11,PATCH 17/19] arm64: dts: mt8192: add dvfsrc related nodes
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-18-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Add DDR EMI provider dictating dram interconnect bus performance found on
MT8183-based platforms

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index c70a3bf744fa..ab3dabcc722e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -5,6 +5,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/interconnect/mtk,mt6873-emi.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/mt8192-pinfunc.h>
@@ -286,6 +287,7 @@
 			compatible = "mediatek,mt8192-dvfsrc",
 				     "mediatek,mt6873-dvfsrc";
 			reg = <0 0x10012000 0 0x1000>;
+			#interconnect-cells = <1>;
 		};
 
 		systimer: timer at 10017000 {
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:40 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:40 +0800
Subject: [V11,PATCH 13/19] interconnect: mediatek: add support for mt8195
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-14-dawei.chien@mediatek.com>

add platform data of mt8195

Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
---
 drivers/interconnect/mediatek/mtk-emi.c | 51 +++++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
index 8d650be62b90..379dab77ebfd 100644
--- a/drivers/interconnect/mediatek/mtk-emi.c
+++ b/drivers/interconnect/mediatek/mtk-emi.c
@@ -12,6 +12,7 @@
 #include <linux/soc/mediatek/mtk_dvfsrc.h>
 #include <dt-bindings/interconnect/mtk,mt6873-emi.h>
 #include <dt-bindings/interconnect/mtk,mt8183-emi.h>
+#include <dt-bindings/interconnect/mtk,mt8195-emi.h>
 
 enum mtk_icc_name {
 	SLAVE_DDR_EMI,
@@ -31,7 +32,8 @@ enum mtk_icc_name {
 	MASTER_MDLASYS,
 	MASTER_MDLA_PORT_0,
 	MASTER_UFS,
-	MASTER_PCIE,
+	MASTER_PCIE_0,
+	MASTER_PCIE_1,
 	MASTER_USB,
 	MASTER_WIFI,
 	MASTER_BT,
@@ -102,7 +104,8 @@ DEFINE_MNODE(vpu_port_1, MASTER_VPU_PORT_1, 0, MASTER_VPUSYS);
 DEFINE_MNODE(mdlasys, MASTER_MDLASYS, 0, SLAVE_DDR_EMI);
 DEFINE_MNODE(mdla_port_0, MASTER_MDLA_PORT_0, 0, MASTER_MDLASYS);
 DEFINE_MNODE(ufs, MASTER_UFS, 0, SLAVE_DDR_EMI);
-DEFINE_MNODE(pcie, MASTER_PCIE, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(pcie_0, MASTER_PCIE_0, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(pcie_1, MASTER_PCIE_1, 0, SLAVE_DDR_EMI);
 DEFINE_MNODE(usb, MASTER_USB, 0, SLAVE_DDR_EMI);
 DEFINE_MNODE(wifi, MASTER_WIFI, 0, SLAVE_DDR_EMI);
 DEFINE_MNODE(bt, MASTER_BT, 0, SLAVE_DDR_EMI);
@@ -156,7 +159,7 @@ static struct mtk_icc_node *mt6873_icc_nodes[] = {
 	[MT6873_MASTER_MDLASYS] = &mdlasys,
 	[MT6873_MASTER_MDLA_0] = &mdla_port_0,
 	[MT6873_MASTER_UFS] = &ufs,
-	[MT6873_MASTER_PCIE] = &pcie,
+	[MT6873_MASTER_PCIE] = &pcie_0,
 	[MT6873_MASTER_USB] = &usb,
 	[MT6873_MASTER_WIFI] = &wifi,
 	[MT6873_MASTER_BT] = &bt,
@@ -179,10 +182,52 @@ static struct mtk_icc_desc mt6873_icc = {
 	.num_nodes = ARRAY_SIZE(mt6873_icc_nodes),
 };
 
+static struct mtk_icc_node *mt8195_icc_nodes[] = {
+	[MT8195_SLAVE_DDR_EMI] = &ddr_emi,
+	[MT8195_MASTER_MCUSYS] = &mcusys,
+	[MT8195_MASTER_GPUSYS] = &gpu,
+	[MT8195_MASTER_MMSYS] = &mmsys,
+	[MT8195_MASTER_MM_VPU] = &mm_vpu,
+	[MT8195_MASTER_MM_DISP] = &mm_disp,
+	[MT8195_MASTER_MM_VDEC] = &mm_vdec,
+	[MT8195_MASTER_MM_VENC] = &mm_venc,
+	[MT8195_MASTER_MM_CAM] = &mm_cam,
+	[MT8195_MASTER_MM_IMG] = &mm_img,
+	[MT8195_MASTER_MM_MDP] = &mm_mdp,
+	[MT8195_MASTER_VPUSYS] = &vpusys,
+	[MT8195_MASTER_VPU_0] = &vpu_port_0,
+	[MT8195_MASTER_VPU_1] = &vpu_port_1,
+	[MT8195_MASTER_MDLASYS] = &mdlasys,
+	[MT8195_MASTER_MDLA_0] = &mdla_port_0,
+	[MT8195_MASTER_UFS] = &ufs,
+	[MT8195_MASTER_PCIE_0] = &pcie_0,
+	[MT8195_MASTER_PCIE_1] = &pcie_1,
+	[MT8195_MASTER_USB] = &usb,
+	[MT8195_MASTER_WIFI] = &wifi,
+	[MT8195_MASTER_BT] = &bt,
+	[MT8195_MASTER_NETSYS] = &netsys,
+	[MT8195_MASTER_DBGIF] = &dbgif,
+	[MT8195_SLAVE_HRT_DDR_EMI] = &hrt_ddr_emi,
+	[MT8195_MASTER_HRT_MMSYS] = &hrt_mmsys,
+	[MT8195_MASTER_HRT_MM_DISP] = &hrt_mm_disp,
+	[MT8195_MASTER_HRT_MM_VDEC] = &hrt_mm_vdec,
+	[MT8195_MASTER_HRT_MM_VENC] = &hrt_mm_venc,
+	[MT8195_MASTER_HRT_MM_CAM] = &hrt_mm_cam,
+	[MT8195_MASTER_HRT_MM_IMG] = &hrt_mm_img,
+	[MT8195_MASTER_HRT_MM_MDP] = &hrt_mm_mdp,
+	[MT8195_MASTER_HRT_DBGIF] = &hrt_dbgif,
+};
+
+static struct mtk_icc_desc mt8195_icc = {
+	.nodes = mt8195_icc_nodes,
+	.num_nodes = ARRAY_SIZE(mt8195_icc_nodes),
+};
+
 static const struct of_device_id emi_icc_of_match[] = {
 	{ .compatible = "mediatek,mt8183-dvfsrc", .data = &mt8183_icc },
 	{ .compatible = "mediatek,mt8192-dvfsrc", .data = &mt6873_icc },
 	{ .compatible = "mediatek,mt6873-dvfsrc", .data = &mt6873_icc },
+	{ .compatible = "mediatek,mt8195-dvfsrc", .data = &mt8195_icc },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, emi_icc_of_match);
-- 
2.14.1

From dawei.chien at mediatek.com  Thu Aug 12 01:58:34 2021
From: dawei.chien at mediatek.com (Dawei Chien)
Date: Thu, 12 Aug 2021 16:58:34 +0800
Subject: [V11,PATCH 07/19] arm64: dts: mt8183: add dvfsrc related nodes
In-Reply-To: <20210812085846.2628-1-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
Message-ID: <20210812085846.2628-8-dawei.chien@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Enable dvfsrc on mt8183 platform.

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index f90df6439c08..7ad4cf646579 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -583,6 +583,11 @@
 			#clock-cells = <1>;
 		};
 
+		ddr_emi: dvfsrc at 10012000 {
+			compatible = "mediatek,mt8183-dvfsrc";
+			reg = <0 0x10012000 0 0x1000>;
+		};
+
 		pwrap: pwrap at 1000d000 {
 			compatible = "mediatek,mt8183-pwrap";
 			reg = <0 0x1000d000 0 0x1000>;
-- 
2.14.1

From anshuman.khandual at arm.com  Thu Aug 12 02:13:32 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 14:43:32 +0530
Subject: [RFC V2 10/10] arm64/mm: Enable CONFIG_ARM64_PA_BITS_52 on
 CONFIG_ARM64_[4K|16K]_PAGES
In-Reply-To: <20210805172314.GF6719@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-11-git-send-email-anshuman.khandual@arm.com>
 <20210805172314.GF6719@arm.com>
Message-ID: <a3eb7cc3-8f31-c70b-1830-830e10605d50@arm.com>



On 8/5/21 10:53 PM, Catalin Marinas wrote:
> On Mon, Jul 26, 2021 at 12:07:25PM +0530, Anshuman Khandual wrote:
>> All required FEAT_LPA2 components for 52 bit PA range are already in place.
>> Just enable CONFIG_ARM64_PA_BITS_52 on 4K and 16K pages which would select
>> CONFIG_ARM64_PA_BITS_52_LPA2 activating 52 bit PA range via FEAT_LPA2.
>>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/Kconfig | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 1999ac6..ce139415 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -952,9 +952,9 @@ config ARM64_PA_BITS_48
>>  
>>  config ARM64_PA_BITS_52
>>  	bool "52-bit (ARMv8.2)"
>> -	depends on ARM64_64K_PAGES
>>  	depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
>>  	select ARM64_PA_BITS_52_LPA if ARM64_64K_PAGES
>> +	select ARM64_PA_BITS_52_LPA2 if (ARM64_4K_PAGES  || ARM64_16K_PAGES)
>>  	help
>>  	  Enable support for a 52-bit physical address space, introduced as
>>  	  part of the ARMv8.2-LPA extension.
> 
> If you do it this way, the text here needs updating and the 8.2
> architecture version removed.

Sure, will update as required.


From anshuman.khandual at arm.com  Thu Aug 12 02:15:37 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 14:45:37 +0530
Subject: [RFC V2 01/10] mm/mmap: Dynamically initialize protection_map[]
In-Reply-To: <20210805170318.GB6719@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-2-git-send-email-anshuman.khandual@arm.com>
 <20210805170318.GB6719@arm.com>
Message-ID: <d52e8af9-61af-45c2-837b-5a489e7e2916@arm.com>



On 8/5/21 10:33 PM, Catalin Marinas wrote:
> On Mon, Jul 26, 2021 at 12:07:16PM +0530, Anshuman Khandual wrote:
>> The protection_map[] elements (__PXXX and __SXXX) might sometimes contain
>> runtime variables in certain platforms like arm64 preventing a successful
>> build because of the current static initialization. So it just defers the
>> initialization until mmmap_init() via a new helper init_protection_map().
>>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  mm/mmap.c | 26 ++++++++++++++++++++++----
>>  1 file changed, 22 insertions(+), 4 deletions(-)
>>
>> diff --git a/mm/mmap.c b/mm/mmap.c
>> index ca54d36..a95b078 100644
>> --- a/mm/mmap.c
>> +++ b/mm/mmap.c
>> @@ -100,10 +100,7 @@ static void unmap_region(struct mm_struct *mm,
>>   *								w: (no) no
>>   *								x: (yes) yes
>>   */
>> -pgprot_t protection_map[16] __ro_after_init = {
>> -	__P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
>> -	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
>> -};
>> +pgprot_t protection_map[16] __ro_after_init;
> 
> Mips, x86, sparc, arm32, m68k all adjust protection_map[] during boot.
> Could we do something similar here and avoid changing the generic code?

If __P[000..111] and __S[000..111] be made dummy values (e.g 0 or something
standard prot temporarily), hence the compilation problem could be avoided.
Later in the platform code, protection_map[] could be adjusted with actual
prot values which would involve variable.


From tabba at google.com  Thu Aug 12 02:21:01 2021
From: tabba at google.com (Fuad Tabba)
Date: Thu, 12 Aug 2021 11:21:01 +0200
Subject: [PATCH v3 08/15] KVM: arm64: Add feature register flag definitions
In-Reply-To: <20210812085939.GF5912@willie-the-truck>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-9-tabba@google.com>
 <20210812085939.GF5912@willie-the-truck>
Message-ID: <CA+EHjTyXtVXEU7FMq53rmrgWuiikPzNnWJ7cj4EJkR5FCgj6Sg@mail.gmail.com>

Hi Will,

On Thu, Aug 12, 2021 at 10:59 AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Jul 19, 2021 at 05:03:39PM +0100, Fuad Tabba wrote:
> > Add feature register flag definitions to clarify which features
> > might be supported.
> >
> > Consolidate the various ID_AA64PFR0_ELx flags for all ELs.
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/include/asm/cpufeature.h |  4 ++--
> >  arch/arm64/include/asm/sysreg.h     | 12 ++++++++----
> >  arch/arm64/kernel/cpufeature.c      |  8 ++++----
> >  3 files changed, 14 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> > index 9bb9d11750d7..b7d9bb17908d 100644
> > --- a/arch/arm64/include/asm/cpufeature.h
> > +++ b/arch/arm64/include/asm/cpufeature.h
> > @@ -602,14 +602,14 @@ static inline bool id_aa64pfr0_32bit_el1(u64 pfr0)
> >  {
> >       u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_SHIFT);
> >
> > -     return val == ID_AA64PFR0_EL1_32BIT_64BIT;
> > +     return val == ID_AA64PFR0_ELx_32BIT_64BIT;
> >  }
> >
> >  static inline bool id_aa64pfr0_32bit_el0(u64 pfr0)
> >  {
> >       u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL0_SHIFT);
> >
> > -     return val == ID_AA64PFR0_EL0_32BIT_64BIT;
> > +     return val == ID_AA64PFR0_ELx_32BIT_64BIT;
> >  }
> >
> >  static inline bool id_aa64pfr0_sve(u64 pfr0)
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 326f49e7bd42..0b773037251c 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -784,14 +784,13 @@
> >  #define ID_AA64PFR0_AMU                      0x1
> >  #define ID_AA64PFR0_SVE                      0x1
> >  #define ID_AA64PFR0_RAS_V1           0x1
> > +#define ID_AA64PFR0_RAS_ANY          0xf
>
> This doesn't correspond to an architectural definition afaict: the manual
> says that any values other than 0, 1 or 2 are "reserved" so we should avoid
> defining our own definitions here.

I'll add a ID_AA64PFR0_RAS_V2 definition in that case and use it for
the checking later. That would achieve the same goal and I wouldn't be
adding definitions to the reserved area.

Cheers,
/fuad


From tabba at google.com  Thu Aug 12 02:22:03 2021
From: tabba at google.com (Fuad Tabba)
Date: Thu, 12 Aug 2021 11:22:03 +0200
Subject: [PATCH v3 01/15] KVM: arm64: placeholder to check if VM is
 protected
In-Reply-To: <20210812085857.GB5912@willie-the-truck>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-2-tabba@google.com>
 <20210812085857.GB5912@willie-the-truck>
Message-ID: <CA+EHjTx++8neadZ=i5Gu-mCeZFC=CBLJ4bd_=QefBoHBb5Qe9Q@mail.gmail.com>

Hi Will,


On Thu, Aug 12, 2021 at 10:59 AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Jul 19, 2021 at 05:03:32PM +0100, Fuad Tabba wrote:
> > Add a function to check whether a VM is protected (under pKVM).
> > Since the creation of protected VMs isn't enabled yet, this is a
> > placeholder that always returns false. The intention is for this
> > to become a check for protected VMs in the future (see Will's RFC
> > [*]).
> >
> > No functional change intended.
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> >
> > [*] https://lore.kernel.org/kvmarm/20210603183347.1695-1-will at kernel.org/
>
> You can make this a Link: tag.

Of course. Thanks!
/fuad
> Anyway, I think it makes lots of sense to decouple this from the user-ABI
> series:
>
> Acked-by: Will Deacon <will at kernel.org>
>
> Will


From adrian.hunter at intel.com  Thu Aug 12 02:23:53 2021
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Thu, 12 Aug 2021 12:23:53 +0300
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210809112727.596876-3-leo.yan@linaro.org>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-3-leo.yan@linaro.org>
Message-ID: <7b37bb70-2b0a-ea8d-9ebe-0d5df9b3a733@intel.com>

On 9/08/21 2:27 pm, Leo Yan wrote:
> When perf runs in compat mode (kernel in 64-bit mode and the perf is in
> 32-bit mode), the 64-bit value atomicity in the user space cannot be
> assured, E.g. on some architectures, the 64-bit value accessing is split
> into two instructions, one is for the low 32-bit word accessing and
> another is for the high 32-bit word.
> 
> This patch introduces weak functions compat_auxtrace_mmap__read_head()
> and compat_auxtrace_mmap__write_tail(), as their naming indicates, when
> perf tool works in compat mode, it uses these two functions to access
> the AUX head and tail.  These two functions can allow the perf tool to
> work properly in certain conditions, e.g. when perf tool works in
> snapshot mode with only using AUX head pointer, or perf tool uses the
> AUX buffer and the incremented tail is not bigger than 4GB.
> 
> When perf tool cannot handle the case when the AUX tail is bigger than
> 4GB, the function compat_auxtrace_mmap__write_tail() returns -1 and
> tells the caller to bail out for the error.
> 
> These two functions are declared as weak attribute, this allows to
> implement arch specific functions if any arch can support the 64-bit
> value atomicity in compat mode.
> 
> Suggested-by: Adrian Hunter <adrian.hunter at intel.com>
> Signed-off-by: Leo Yan <leo.yan at linaro.org>

Acked-by: Adrian Hunter <adrian.hunter at intel.com>

> ---
>  tools/perf/util/auxtrace.c | 88 ++++++++++++++++++++++++++++++++++++--
>  tools/perf/util/auxtrace.h | 22 ++++++++--
>  2 files changed, 103 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
> index f33f09b8b535..60975df05d54 100644
> --- a/tools/perf/util/auxtrace.c
> +++ b/tools/perf/util/auxtrace.c
> @@ -1669,6 +1669,82 @@ int perf_event__process_auxtrace_error(struct perf_session *session,
>  	return 0;
>  }
>  
> +/*
> + * In the compat mode kernel runs in 64-bit and perf tool runs in 32-bit mode,
> + * 32-bit perf tool cannot access 64-bit value atomically, which might lead to
> + * the issues caused by the below sequence on multiple CPUs: when perf tool
> + * accesses either the load operation or the store operation for 64-bit value,
> + * on some architectures the operation is divided into two instructions, one
> + * is for accessing the low 32-bit value and another is for the high 32-bit;
> + * thus these two user operations can give the kernel chances to access the
> + * 64-bit value, and thus leads to the unexpected load values.
> + *
> + *   kernel (64-bit)                        user (32-bit)
> + *
> + *   if (LOAD ->aux_tail) { --,             LOAD ->aux_head_lo
> + *       STORE $aux_data      |       ,--->
> + *       FLUSH $aux_data      |       |     LOAD ->aux_head_hi
> + *       STORE ->aux_head   --|-------`     smp_rmb()
> + *   }                        |             LOAD $data
> + *                            |             smp_mb()
> + *                            |             STORE ->aux_tail_lo
> + *                            `----------->
> + *                                          STORE ->aux_tail_hi
> + *
> + * For this reason, it's impossible for the perf tool to work correctly when
> + * the AUX head or tail is bigger than 4GB (more than 32 bits length); and we
> + * can not simply limit the AUX ring buffer to less than 4GB, the reason is
> + * the pointers can be increased monotonically, whatever the buffer size it is,
> + * at the end the head and tail can be bigger than 4GB and carry out to the
> + * high 32-bit.
> + *
> + * To mitigate the issues and improve the user experience, we can allow the
> + * perf tool working in certain conditions and bail out with error if detect
> + * any overflow cannot be handled.
> + *
> + * For reading the AUX head, it reads out the values for three times, and
> + * compares the high 4 bytes of the values between the first time and the last
> + * time, if there has no change for high 4 bytes injected by the kernel during
> + * the user reading sequence, it's safe for use the second value.
> + *
> + * When update the AUX tail and detects any carrying in the high 32 bits, it
> + * means there have two store operations in user space and it cannot promise
> + * the atomicity for 64-bit write, so return '-1' in this case to tell the
> + * caller an overflow error has happened.
> + */
> +u64 __weak compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> +{
> +	struct perf_event_mmap_page *pc = mm->userpg;
> +	u64 first, second, last;
> +	u64 mask = (u64)(UINT32_MAX) << 32;
> +
> +	do {
> +		first = READ_ONCE(pc->aux_head);
> +		/* Ensure all reads are done after we read the head */
> +		smp_rmb();
> +		second = READ_ONCE(pc->aux_head);
> +		/* Ensure all reads are done after we read the head */
> +		smp_rmb();
> +		last = READ_ONCE(pc->aux_head);
> +	} while ((first & mask) != (last & mask));
> +
> +	return second;
> +}
> +
> +int __weak compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
> +{
> +	struct perf_event_mmap_page *pc = mm->userpg;
> +	u64 mask = (u64)(UINT32_MAX) << 32;
> +
> +	if (tail & mask)
> +		return -1;
> +
> +	/* Ensure all reads are done before we write the tail out */
> +	smp_mb();
> +	WRITE_ONCE(pc->aux_tail, tail);
> +	return 0;
> +}
> +
>  static int __auxtrace_mmap__read(struct mmap *map,
>  				 struct auxtrace_record *itr,
>  				 struct perf_tool *tool, process_auxtrace_t fn,
> @@ -1680,8 +1756,9 @@ static int __auxtrace_mmap__read(struct mmap *map,
>  	size_t size, head_off, old_off, len1, len2, padding;
>  	union perf_event ev;
>  	void *data1, *data2;
> +	int kernel_is_64_bit = perf_env__kernel_is_64_bit(evsel__env(NULL));
>  
> -	head = auxtrace_mmap__read_head(mm);
> +	head = auxtrace_mmap__read_head(mm, kernel_is_64_bit);
>  
>  	if (snapshot &&
>  	    auxtrace_record__find_snapshot(itr, mm->idx, mm, data, &head, &old))
> @@ -1764,10 +1841,13 @@ static int __auxtrace_mmap__read(struct mmap *map,
>  	mm->prev = head;
>  
>  	if (!snapshot) {
> -		auxtrace_mmap__write_tail(mm, head);
> -		if (itr->read_finish) {
> -			int err;
> +		int err;
> +
> +		err = auxtrace_mmap__write_tail(mm, head, kernel_is_64_bit);
> +		if (err < 0)
> +			return err;
>  
> +		if (itr->read_finish) {
>  			err = itr->read_finish(itr, mm->idx);
>  			if (err < 0)
>  				return err;
> diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
> index d68a5e80b217..5f383908ca6e 100644
> --- a/tools/perf/util/auxtrace.h
> +++ b/tools/perf/util/auxtrace.h
> @@ -440,23 +440,39 @@ struct auxtrace_cache;
>  
>  #ifdef HAVE_AUXTRACE_SUPPORT
>  
> -static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> +u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm);
> +int compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail);
> +
> +static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm,
> +					   int kernel_is_64_bit __maybe_unused)
>  {
>  	struct perf_event_mmap_page *pc = mm->userpg;
> -	u64 head = READ_ONCE(pc->aux_head);
> +	u64 head;
> +
> +#if BITS_PER_LONG == 32
> +	if (kernel_is_64_bit)
> +		return compat_auxtrace_mmap__read_head(mm);
> +#endif
> +	head = READ_ONCE(pc->aux_head);
>  
>  	/* Ensure all reads are done after we read the head */
>  	smp_rmb();
>  	return head;
>  }
>  
> -static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
> +static inline int auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail,
> +					    int kernel_is_64_bit __maybe_unused)
>  {
>  	struct perf_event_mmap_page *pc = mm->userpg;
>  
> +#if BITS_PER_LONG == 32
> +	if (kernel_is_64_bit)
> +		return compat_auxtrace_mmap__write_tail(mm, tail);
> +#endif
>  	/* Ensure all reads are done before we write the tail out */
>  	smp_mb();
>  	WRITE_ONCE(pc->aux_tail, tail);
> +	return 0;
>  }
>  
>  int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
> 



From tabba at google.com  Thu Aug 12 02:28:50 2021
From: tabba at google.com (Fuad Tabba)
Date: Thu, 12 Aug 2021 11:28:50 +0200
Subject: [PATCH v3 06/15] KVM: arm64: Restore mdcr_el2 from vcpu
In-Reply-To: <20210812084600.GA5912@willie-the-truck>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-7-tabba@google.com>
 <20210720145258.axhqog3abdvtpqhw@gator>
 <CA+EHjTweLPu+DQ8hR9kEW0LrawtaoAoXR_+HmSEZpP-XOEm2qg@mail.gmail.com>
 <20210812084600.GA5912@willie-the-truck>
Message-ID: <CA+EHjTx7q+DeR2dNL9X6jLcqtr=ZZ5YN4WsnnbOUPvtQZP1dSQ@mail.gmail.com>

Hi Will,

On Thu, Aug 12, 2021 at 10:46 AM Will Deacon <will at kernel.org> wrote:
>
> On Wed, Jul 21, 2021 at 08:37:21AM +0100, Fuad Tabba wrote:
> > On Tue, Jul 20, 2021 at 3:53 PM Andrew Jones <drjones at redhat.com> wrote:
> > >
> > > On Mon, Jul 19, 2021 at 05:03:37PM +0100, Fuad Tabba wrote:
> > > > On deactivating traps, restore the value of mdcr_el2 from the
> > > > newly created and preserved host value vcpu context, rather than
> > > > directly reading the hardware register.
> > > >
> > > > Up until and including this patch the two values are the same,
> > > > i.e., the hardware register and the vcpu one. A future patch will
> > > > be changing the value of mdcr_el2 on activating traps, and this
> > > > ensures that its value will be restored.
> > > >
> > > > No functional change intended.
> > >
> > > I'm probably missing something, but I can't convince myself that the host
> > > will end up with the same mdcr_el2 value after deactivating traps after
> > > this patch as before. We clearly now restore whatever we had when
> > > activating traps (presumably whatever we configured at init_el2_state
> > > time), but is that equivalent to what we had before with the masking and
> > > ORing that this patch drops?
> >
> > You're right. I thought that these were actually being initialized to
> > the same values, but having a closer look at the code the mdcr values
> > are not the same as pre-patch. I will fix this.
>
> Can you elaborate on the issue here, please? I was just looking at this
> but aren't you now relying on __init_el2_debug to configure this, which
> should be fine?

I *think* that it should be fine, but as Drew pointed out, the host
does not end up with the same mdcr_el2 value after the deactivation in
this patch as it did after deactivation before this patch. In my v4
(not sent out yet), I have fixed it to ensure that the host does end
up with the same value as the one before this patch. That should make
it easier to check that there's no functional change.

I'll look into it further, and if I can convince myself that there
aren't any issues and that this patch makes the code cleaner, I will
add it as a separate patch instead to make reviewing easier.

Thanks,
/fuad

> Will


From ikjn at chromium.org  Thu Aug 12 02:31:45 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Thu, 12 Aug 2021 17:31:45 +0800
Subject: [RFC PATCH] usb: xhci-mtk: handle bandwidth table rollover
In-Reply-To: <7b48f4c132a8b4b3819282e961fbe8b3ed753069.camel@mediatek.com>
References: <20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid>
 <YRDxTodNNqtnpPpn@kroah.com>
 <CAATdQgDSCzZtiDSQk94CYHfSb9Mq28OH7-RdaTZNv3oPrW3nkQ@mail.gmail.com>
 <7b48f4c132a8b4b3819282e961fbe8b3ed753069.camel@mediatek.com>
Message-ID: <CAATdQgD1paUUmWhiLVq-+zq0V6=RTJw89ggk=R6cBUZO+5dB-Q@mail.gmail.com>

HI,

On Wed, Aug 11, 2021 at 5:02 PM Chunfeng Yun (???)
<Chunfeng.Yun at mediatek.com> wrote:
>
> On Mon, 2021-08-09 at 17:42 +0800, Ikjoon Jang wrote:
> > On Mon, Aug 9, 2021 at 5:11 PM Greg Kroah-Hartman
> > <gregkh at linuxfoundation.org> wrote:
> > >
> > > On Mon, Aug 09, 2021 at 04:59:29PM +0800, Ikjoon Jang wrote:
> > > > xhci-mtk has 64 slots for periodic bandwidth calculations and
> > > > each
> > > > slot represents byte budgets on a microframe. When an endpoint's
> > > > allocation sits on the boundary of the table, byte budgets' slot
> > > > should be rolled over but the current implementation doesn't.
> > > >
> > > > This patch applies a 6 bits mask to the microframe index to
> > > > handle
> > > > its rollover 64 slots and prevent out-of-bounds array access.
> > > >
> > > > Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
> > > > ---
> > > >
> > > >  drivers/usb/host/xhci-mtk-sch.c | 79 +++++++++----------------
> > > > --------
> > > >  drivers/usb/host/xhci-mtk.h     |  1 +
> > > >  2 files changed, 23 insertions(+), 57 deletions(-)
> > >
> > > Why is this "RFC"?  What needs to be addressed in this change
> > > before it
> > > can be accepted?
> >
> > sorry, I had to mention why this is RFC:
> >
> > I simply don't know about the details of the xhci-mtk internals.
> > It was okay from my tests with mt8173 and I think this will be
> > harmless
> > as this is "better than before".
> >
> > But when I removed get_esit_boundary(), I really have no idea why
> > it was there. I'm wondering if there was another reason of that
> > function
> > other than just preventing out-of-bounds. Maybe chunfeng can answer
> > this?
> We use @esit to prevent out-of-bounds array access. it's not a ring,
> can't insert out-of-bounds value into head slot.

Thanks, so that function was only for out-of-bounds array access.
then I think we just can remove that function and use it as a ring.
Can you tell me _why_ it can't be used as a ring?

I think a transaction (e.g. esit_boundary = 7) can start its first SSPLIT
from Y_7 (offset = 7). But will that allocation be matched with this?

-               if ((offset + sch_ep->num_budget_microframes) > esit_boundary)
-                       break;

I mean I'm not sure why this is needed.

Until now, I couldn't find a way to accept the USB audio headset
with a configuration of { INT-IN 64 + ISOC-OUT 384 + ISOC-IN 192 }
without this patch.

>
> >
> > Thanks!
> >
> > >
> > > thanks,
> > >
> > > greg k-h


From miles.chen at mediatek.com  Thu Aug 12 02:35:16 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Thu, 12 Aug 2021 17:35:16 +0800
Subject: [PATCH 1/4] clk: composite: export clk_register_composite
In-Reply-To: <20210812093519.3550-1-miles.chen@mediatek.com>
References: <20210812093519.3550-1-miles.chen@mediatek.com>
Message-ID: <20210812093519.3550-2-miles.chen@mediatek.com>

To support module build of mediatek clk drivers,
it is necessary to export clk_register_composite.

Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/clk-composite.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 0506046a5f4b..c7b97fb0051b 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -362,6 +362,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 		return ERR_CAST(hw);
 	return hw->clk;
 }
+EXPORT_SYMBOL_GPL(clk_register_composite);
 
 struct clk *clk_register_composite_pdata(struct device *dev, const char *name,
 			const struct clk_parent_data *parent_data,
-- 
2.18.0

From miles.chen at mediatek.com  Thu Aug 12 02:35:19 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Thu, 12 Aug 2021 17:35:19 +0800
Subject: [PATCH 4/4] clk: mediatek: use tristate for COMMON_CLK_MEDAITEK and
 COMMON_CLK_MT6779
In-Reply-To: <20210812093519.3550-1-miles.chen@mediatek.com>
References: <20210812093519.3550-1-miles.chen@mediatek.com>
Message-ID: <20210812093519.3550-5-miles.chen@mediatek.com>

Now we have all necessary exported symbols, change
COMMON_CLK_MEDAITEK and COMMON_CLK_MT6779* to tristate.

Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/Kconfig | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 886e2d9fced5..62ed2054a849 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -6,7 +6,7 @@ menu "Clock driver for MediaTek SoC"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 
 config COMMON_CLK_MEDIATEK
-	bool
+	tristate
 	select RESET_CONTROLLER
 	help
 	  MediaTek SoCs' clock support.
@@ -204,7 +204,7 @@ config COMMON_CLK_MT6765_MIPI2BSYS
          This driver supports MediaTek MT6765 mipi2bsys clocks.
 
 config COMMON_CLK_MT6779
-	bool "Clock driver for MediaTek MT6779"
+	tristate "Clock driver for MediaTek MT6779"
 	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
 	select COMMON_CLK_MEDIATEK
 	default ARCH_MEDIATEK && ARM64
@@ -212,49 +212,49 @@ config COMMON_CLK_MT6779
 	  This driver supports MediaTek MT6779 basic clocks.
 
 config COMMON_CLK_MT6779_MMSYS
-	bool "Clock driver for MediaTek MT6779 mmsys"
+	tristate "Clock driver for MediaTek MT6779 mmsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 mmsys clocks.
 
 config COMMON_CLK_MT6779_IMGSYS
-	bool "Clock driver for MediaTek MT6779 imgsys"
+	tristate "Clock driver for MediaTek MT6779 imgsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 imgsys clocks.
 
 config COMMON_CLK_MT6779_IPESYS
-	bool "Clock driver for MediaTek MT6779 ipesys"
+	tristate "Clock driver for MediaTek MT6779 ipesys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 ipesys clocks.
 
 config COMMON_CLK_MT6779_CAMSYS
-	bool "Clock driver for MediaTek MT6779 camsys"
+	tristate "Clock driver for MediaTek MT6779 camsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 camsys clocks.
 
 config COMMON_CLK_MT6779_VDECSYS
-	bool "Clock driver for MediaTek MT6779 vdecsys"
+	tristate "Clock driver for MediaTek MT6779 vdecsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 vdecsys clocks.
 
 config COMMON_CLK_MT6779_VENCSYS
-	bool "Clock driver for MediaTek MT6779 vencsys"
+	tristate "Clock driver for MediaTek MT6779 vencsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 vencsys clocks.
 
 config COMMON_CLK_MT6779_MFGCFG
-	bool "Clock driver for MediaTek MT6779 mfgcfg"
+	tristate "Clock driver for MediaTek MT6779 mfgcfg"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 mfgcfg clocks.
 
 config COMMON_CLK_MT6779_AUDSYS
-	bool "Clock driver for Mediatek MT6779 audsys"
+	tristate "Clock driver for Mediatek MT6779 audsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports Mediatek MT6779 audsys clocks.
-- 
2.18.0

From miles.chen at mediatek.com  Thu Aug 12 02:35:15 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Thu, 12 Aug 2021 17:35:15 +0800
Subject: [PATCH 0/4] clk: mediatek: modularize COMMON_CLK_MT6779
Message-ID: <20210812093519.3550-1-miles.chen@mediatek.com>

This patch set makes COMMON_CLK_MEDIATEK and COMMON_CLK_MT6779*
be able to built as kernel modules. Necessary symbols are exported
in this patch.

In previous discussion [1], Stephen commented that there must
be a user before exporting a symbol:

"
Is the mediatek driver compilable as a module? Last time I checked it
wasn't a module. I want an upstream modular driver that uses the symbol.
Otherwise we're exporting symbols when it doesn't need to be.
"

[1] https://lore.kernel.org/patchwork/patch/1278089/

Miles Chen (4):
  clk: composite: export clk_register_composite
  clk: mediatek: modularize COMMON_CLK_MEDIATEK
  clk: mediatek: modularize COMMON_CLK_MT6779*
  clk: mediatek: use tristate for COMMON_CLK_MEDAITEK and
    COMMON_CLK_MT6779

 drivers/clk/clk-composite.c            |  1 +
 drivers/clk/mediatek/Kconfig           | 20 ++++++++++----------
 drivers/clk/mediatek/clk-apmixed.c     |  3 +++
 drivers/clk/mediatek/clk-cpumux.c      |  3 +++
 drivers/clk/mediatek/clk-gate.c        |  8 ++++++++
 drivers/clk/mediatek/clk-mt6779-aud.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-cam.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-img.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-ipe.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-mfg.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-mm.c   |  2 ++
 drivers/clk/mediatek/clk-mt6779-vdec.c |  2 ++
 drivers/clk/mediatek/clk-mt6779-venc.c |  2 ++
 drivers/clk/mediatek/clk-mt6779.c      |  2 ++
 drivers/clk/mediatek/clk-mtk.c         |  8 ++++++++
 drivers/clk/mediatek/clk-mux.c         |  4 ++++
 drivers/clk/mediatek/clk-pll.c         |  4 ++++
 drivers/clk/mediatek/reset.c           |  2 ++
 18 files changed, 61 insertions(+), 10 deletions(-)

-- 
2.18.0

From miles.chen at mediatek.com  Thu Aug 12 02:35:18 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Thu, 12 Aug 2021 17:35:18 +0800
Subject: [PATCH 3/4] clk: mediatek: support COMMON_CLK_MT6779 module build
In-Reply-To: <20210812093519.3550-1-miles.chen@mediatek.com>
References: <20210812093519.3550-1-miles.chen@mediatek.com>
Message-ID: <20210812093519.3550-4-miles.chen@mediatek.com>

To support COMMON_CLK_MT6779* module build,
add MODULE_LICENSE and export necessary symbols.

Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mt6779-aud.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-cam.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-img.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-ipe.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-mfg.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-mm.c   | 2 ++
 drivers/clk/mediatek/clk-mt6779-vdec.c | 2 ++
 drivers/clk/mediatek/clk-mt6779-venc.c | 2 ++
 drivers/clk/mediatek/clk-mt6779.c      | 2 ++
 9 files changed, 18 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mt6779-aud.c b/drivers/clk/mediatek/clk-mt6779-aud.c
index 11b209f95e25..439c0bc94b73 100644
--- a/drivers/clk/mediatek/clk-mt6779-aud.c
+++ b/drivers/clk/mediatek/clk-mt6779-aud.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -115,3 +116,4 @@ static struct platform_driver clk_mt6779_aud_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_aud_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-cam.c b/drivers/clk/mediatek/clk-mt6779-cam.c
index 244d4208b7fb..c99ddb210b70 100644
--- a/drivers/clk/mediatek/clk-mt6779-cam.c
+++ b/drivers/clk/mediatek/clk-mt6779-cam.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -64,3 +65,4 @@ static struct platform_driver clk_mt6779_cam_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_cam_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-img.c b/drivers/clk/mediatek/clk-mt6779-img.c
index 26292a45c613..bf652052879c 100644
--- a/drivers/clk/mediatek/clk-mt6779-img.c
+++ b/drivers/clk/mediatek/clk-mt6779-img.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -56,3 +57,4 @@ static struct platform_driver clk_mt6779_img_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_img_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-ipe.c b/drivers/clk/mediatek/clk-mt6779-ipe.c
index bb519075639c..a1a1c9cb329a 100644
--- a/drivers/clk/mediatek/clk-mt6779-ipe.c
+++ b/drivers/clk/mediatek/clk-mt6779-ipe.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -58,3 +59,4 @@ static struct platform_driver clk_mt6779_ipe_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_ipe_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-mfg.c b/drivers/clk/mediatek/clk-mt6779-mfg.c
index c6ee2a89c070..9bf48c56d852 100644
--- a/drivers/clk/mediatek/clk-mt6779-mfg.c
+++ b/drivers/clk/mediatek/clk-mt6779-mfg.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -53,3 +54,4 @@ static struct platform_driver clk_mt6779_mfg_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_mfg_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-mm.c b/drivers/clk/mediatek/clk-mt6779-mm.c
index 059c1a41ac7a..d5ead5531026 100644
--- a/drivers/clk/mediatek/clk-mt6779-mm.c
+++ b/drivers/clk/mediatek/clk-mt6779-mm.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -106,3 +107,4 @@ static struct platform_driver clk_mt6779_mm_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_mm_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-vdec.c b/drivers/clk/mediatek/clk-mt6779-vdec.c
index 1900da2586a1..ff7390e4c5f5 100644
--- a/drivers/clk/mediatek/clk-mt6779-vdec.c
+++ b/drivers/clk/mediatek/clk-mt6779-vdec.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -65,3 +66,4 @@ static struct platform_driver clk_mt6779_vdec_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_vdec_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-venc.c b/drivers/clk/mediatek/clk-mt6779-venc.c
index b41d1f859edc..489bf64346e3 100644
--- a/drivers/clk/mediatek/clk-mt6779-venc.c
+++ b/drivers/clk/mediatek/clk-mt6779-venc.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -56,3 +57,4 @@ static struct platform_driver clk_mt6779_venc_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_venc_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c
index 6e0d3a166729..9825385c9f94 100644
--- a/drivers/clk/mediatek/clk-mt6779.c
+++ b/drivers/clk/mediatek/clk-mt6779.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -1314,3 +1315,4 @@ static int __init clk_mt6779_init(void)
 }
 
 arch_initcall(clk_mt6779_init);
+MODULE_LICENSE("GPL");
-- 
2.18.0

From miles.chen at mediatek.com  Thu Aug 12 02:35:17 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Thu, 12 Aug 2021 17:35:17 +0800
Subject: [PATCH 2/4] clk: mediatek: support COMMON_CLK_MEDIATEK module build
In-Reply-To: <20210812093519.3550-1-miles.chen@mediatek.com>
References: <20210812093519.3550-1-miles.chen@mediatek.com>
Message-ID: <20210812093519.3550-3-miles.chen@mediatek.com>

To support COMMON_CLK_MEDIATEK module build,
add MODULE_LICENSE and export necessary symbols.

Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-apmixed.c | 3 +++
 drivers/clk/mediatek/clk-cpumux.c  | 3 +++
 drivers/clk/mediatek/clk-gate.c    | 8 ++++++++
 drivers/clk/mediatek/clk-mtk.c     | 8 ++++++++
 drivers/clk/mediatek/clk-mux.c     | 4 ++++
 drivers/clk/mediatek/clk-pll.c     | 4 ++++
 drivers/clk/mediatek/reset.c       | 2 ++
 7 files changed, 32 insertions(+)

diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c
index 258d128370f2..caa9119413f1 100644
--- a/drivers/clk/mediatek/clk-apmixed.c
+++ b/drivers/clk/mediatek/clk-apmixed.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/slab.h>
 
@@ -97,3 +98,5 @@ struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
 
 	return clk;
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index 79fe09028742..f85c755c9fc1 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -6,6 +6,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/mfd/syscon.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include "clk-mtk.h"
@@ -106,3 +107,5 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 
 	return 0;
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index a35cf0b22150..b02d2f74dd0d 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clkdev.h>
+#include <linux/module.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
@@ -122,24 +123,28 @@ const struct clk_ops mtk_clk_gate_ops_setclr = {
 	.enable		= mtk_cg_enable,
 	.disable	= mtk_cg_disable,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr);
 
 const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
 	.is_enabled	= mtk_cg_bit_is_set,
 	.enable		= mtk_cg_enable_inv,
 	.disable	= mtk_cg_disable_inv,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr_inv);
 
 const struct clk_ops mtk_clk_gate_ops_no_setclr = {
 	.is_enabled	= mtk_cg_bit_is_cleared,
 	.enable		= mtk_cg_enable_no_setclr,
 	.disable	= mtk_cg_disable_no_setclr,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr);
 
 const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
 	.is_enabled	= mtk_cg_bit_is_set,
 	.enable		= mtk_cg_enable_inv_no_setclr,
 	.disable	= mtk_cg_disable_inv_no_setclr,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
 
 struct clk *mtk_clk_register_gate(
 		const char *name,
@@ -181,3 +186,6 @@ struct clk *mtk_clk_register_gate(
 
 	return clk;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_gate);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index cec1c8a27211..cb2dabe60aaf 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clkdev.h>
+#include <linux/module.h>
 #include <linux/mfd/syscon.h>
 #include <linux/device.h>
 
@@ -41,6 +42,7 @@ struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
 
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(mtk_alloc_clk_data);
 
 void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 		int num, struct clk_onecell_data *clk_data)
@@ -67,6 +69,7 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 			clk_data->clks[rc->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks);
 
 void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 		int num, struct clk_onecell_data *clk_data)
@@ -93,6 +96,7 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 			clk_data->clks[ff->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
 
 int mtk_clk_register_gates_with_dev(struct device_node *node,
 		const struct mtk_gate *clks,
@@ -145,6 +149,7 @@ int mtk_clk_register_gates(struct device_node *node,
 	return mtk_clk_register_gates_with_dev(node,
 		clks, num, clk_data, NULL);
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
 
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
@@ -258,6 +263,7 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
 			clk_data->clks[mc->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_composites);
 
 void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			int num, void __iomem *base, spinlock_t *lock,
@@ -286,3 +292,5 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			clk_data->clks[mcd->id] = clk;
 	}
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index b0c61709bacc..a507eea26cc7 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -8,6 +8,7 @@
 #include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/mfd/syscon.h>
+#include <linux/module.h>
 
 #include "clk-mtk.h"
 #include "clk-mux.h"
@@ -190,3 +191,6 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_muxes);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index f440f2cd0b69..399e7b4297c8 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -7,6 +7,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/clkdev.h>
 #include <linux/delay.h>
@@ -368,3 +369,6 @@ void mtk_clk_register_plls(struct device_node *node,
 		clk_data->clks[pll->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
index cb939c071b0c..9079bfc29ec0 100644
--- a/drivers/clk/mediatek/reset.c
+++ b/drivers/clk/mediatek/reset.c
@@ -137,3 +137,5 @@ void mtk_register_reset_controller_set_clr(struct device_node *np,
 	mtk_register_reset_controller_common(np, num_regs, regofs,
 		&mtk_reset_ops_set_clr);
 }
+
+MODULE_LICENSE("GPL");
-- 
2.18.0

From will at kernel.org  Thu Aug 12 02:45:55 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 10:45:55 +0100
Subject: [PATCH v3 11/15] KVM: arm64: Add trap handlers for protected VMs
In-Reply-To: <20210719160346.609914-12-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-12-tabba@google.com>
Message-ID: <20210812094554.GH5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:42PM +0100, Fuad Tabba wrote:
> Add trap handlers for protected VMs. These are mainly for Sys64
> and debug traps.
> 
> No functional change intended as these are not hooked in yet to
> the guest exit handlers introduced earlier. So even when trapping
> is triggered, the exit handlers would let the host handle it, as
> before.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_fixed_config.h | 178 +++++++++
>  arch/arm64/include/asm/kvm_host.h         |   2 +
>  arch/arm64/include/asm/kvm_hyp.h          |   3 +
>  arch/arm64/kvm/Makefile                   |   2 +-
>  arch/arm64/kvm/arm.c                      |  11 +
>  arch/arm64/kvm/hyp/nvhe/Makefile          |   2 +-
>  arch/arm64/kvm/hyp/nvhe/sys_regs.c        | 443 ++++++++++++++++++++++
>  arch/arm64/kvm/pkvm.c                     | 183 +++++++++
>  8 files changed, 822 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm64/include/asm/kvm_fixed_config.h
>  create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c
>  create mode 100644 arch/arm64/kvm/pkvm.c
> 
> diff --git a/arch/arm64/include/asm/kvm_fixed_config.h b/arch/arm64/include/asm/kvm_fixed_config.h
> new file mode 100644
> index 000000000000..b39a5de2c4b9
> --- /dev/null
> +++ b/arch/arm64/include/asm/kvm_fixed_config.h
> @@ -0,0 +1,178 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2021 Google LLC
> + * Author: Fuad Tabba <tabba at google.com>
> + */
> +
> +#ifndef __ARM64_KVM_FIXED_CONFIG_H__
> +#define __ARM64_KVM_FIXED_CONFIG_H__
> +
> +#include <asm/sysreg.h>
> +
> +/*
> + * This file contains definitions for features to be allowed or restricted for
> + * guest virtual machines as a baseline, depending on what mode KVM is running
> + * in and on the type of guest is running.

s/is running/that is running/

> + *
> + * The features are represented as the highest allowed value for a feature in
> + * the feature id registers. If the field is set to all ones (i.e., 0b1111),
> + * then it's only restricted by what the system allows. If the feature is set to
> + * another value, then that value would be the maximum value allowed and
> + * supported in pKVM, even if the system supports a higher value.

Given that some fields are signed whereas others are unsigned, I think the
wording could be a bit tighter here when it refers to "maximum".

> + *
> + * Some features are forced to a certain value, in which case a SET bitmap is
> + * used to force these values.
> + */
> +
> +
> +/*
> + * Allowed features for protected guests (Protected KVM)
> + *
> + * The approach taken here is to allow features that are:
> + * - needed by common Linux distributions (e.g., flooating point)

s/flooating/floating

> + * - are trivial, e.g., supporting the feature doesn't introduce or require the
> + * tracking of additional state

... in KVM.

> + * - not trapable

s/not trapable/cannot be trapped/

> + */
> +
> +/*
> + * - Floating-point and Advanced SIMD:
> + *	Don't require much support other than maintaining the context, which KVM
> + *	already has.

I'd rework this sentence. We have to support fpsimd because Linux guests
rely on it.

> + * - AArch64 guests only (no support for AArch32 guests):
> + *	Simplify support in case of asymmetric AArch32 systems.

I don't think asymmetric systems come into this really; AArch32 on its
own adds lots of complexity in trap handling, emulation, condition codes
etc. Restricting guests to AArch64 means we don't have to worry about the
AArch32 exception model or emulation of 32-bit instructions.

> + * - RAS (v1)
> + *	v1 doesn't require much additional support, but later versions do.

Be more specific?

> + * - Data Independent Timing
> + *	Trivial
> + * Remaining features are not supported either because they require too much
> + * support from KVM, or risk leaking guest data.

I think we should drop this sentence -- it makes it sounds like we can't
be arsed :)

> + */
> +#define PVM_ID_AA64PFR0_ALLOW (\
> +	FEATURE(ID_AA64PFR0_FP) | \
> +	FIELD_PREP(FEATURE(ID_AA64PFR0_EL0), ID_AA64PFR0_ELx_64BIT_ONLY) | \
> +	FIELD_PREP(FEATURE(ID_AA64PFR0_EL1), ID_AA64PFR0_ELx_64BIT_ONLY) | \
> +	FIELD_PREP(FEATURE(ID_AA64PFR0_EL2), ID_AA64PFR0_ELx_64BIT_ONLY) | \
> +	FIELD_PREP(FEATURE(ID_AA64PFR0_EL3), ID_AA64PFR0_ELx_64BIT_ONLY) | \
> +	FIELD_PREP(FEATURE(ID_AA64PFR0_RAS), ID_AA64PFR0_RAS_V1) | \

I think having the FIELD_PREP entries in the ALLOW mask is quite confusing
here -- naively you would expect to be able to bitwise-and the host register
value with the ALLOW mask and get the sanitised version back, but with these
here you have to go field-by-field to compute the common value.

So perhaps move those into a PVM_ID_AA64PFR0_RESTRICT mask or something?
Then pvm_access_id_aa64pfr0() will become a little easier to read, I think.

> +	FEATURE(ID_AA64PFR0_ASIMD) | \
> +	FEATURE(ID_AA64PFR0_DIT) \
> +	)
> +
> +/*
> + * - Branch Target Identification
> + * - Speculative Store Bypassing
> + *	These features are trivial to support
> + */
> +#define PVM_ID_AA64PFR1_ALLOW (\
> +	FEATURE(ID_AA64PFR1_BT) | \
> +	FEATURE(ID_AA64PFR1_SSBS) \
> +	)
> +
> +/*
> + * No support for Scalable Vectors:
> + *	Requires additional support from KVM

Perhaps expand on "support" here? E.g. "context-switching and trapping
support at EL2".

> + */
> +#define PVM_ID_AA64ZFR0_ALLOW (0ULL)
> +
> +/*
> + * No support for debug, including breakpoints, and watchpoints:
> + *	Reduce complexity and avoid exposing/leaking guest data
> + *
> + * NOTE: The Arm architecture mandates support for at least the Armv8 debug
> + * architecture, which would include at least 2 hardware breakpoints and
> + * watchpoints. Providing that support to protected guests adds considerable
> + * state and complexity, and risks leaking guest data. Therefore, the reserved
> + * value of 0 is used for debug-related fields.
> + */

I think the complexity of the debug architecture is a good reason to avoid
exposing it here, but I don't understand how providing breakpoints or
watchpoints to a guest could risk leaking guest data. What is the specific
threat here?

> +#define PVM_ID_AA64DFR0_ALLOW (0ULL)
> +
> +/*
> + * These features are chosen because they are supported by KVM and to limit the
> + * confiruation state space and make it more deterministic.

s/confiruation/configuration/

However, I don't agree that this provides determinism since we're not
forcing any particular values, but rather filtering the values from the
host.

> + * - 40-bit IPA

This seems more about not supporting KVM_CAP_ARM_VM_IPA_SIZE for now.

> + * - 16-bit ASID
> + * - Mixed-endian
> + * - Distinction between Secure and Non-secure Memory
> + * - Mixed-endian at EL0 only
> + * - Non-context synchronizing exception entry and exit

These all seem to fall into the "cannot trap" category, so we just advertise
whatever we've got.

> + */
> +#define PVM_ID_AA64MMFR0_ALLOW (\
> +	FIELD_PREP(FEATURE(ID_AA64MMFR0_PARANGE), ID_AA64MMFR0_PARANGE_40) | \
> +	FIELD_PREP(FEATURE(ID_AA64MMFR0_ASID), ID_AA64MMFR0_ASID_16) | \
> +	FEATURE(ID_AA64MMFR0_BIGENDEL) | \
> +	FEATURE(ID_AA64MMFR0_SNSMEM) | \
> +	FEATURE(ID_AA64MMFR0_BIGENDEL0) | \
> +	FEATURE(ID_AA64MMFR0_EXS) \
> +	)
> +
> +/*
> + * - 64KB granule not supported
> + */
> +#define PVM_ID_AA64MMFR0_SET (\
> +	FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN64), ID_AA64MMFR0_TGRAN64_NI) \
> +	)

Why not, and can we actually prevent the guest from doing that?

> +/*
> + * These features are chosen because they are supported by KVM and to limit the
> + * confiruation state space and make it more deterministic.

It's that typo again ;) But my comment from before still applies -- I don't
think an ALLOW mask adds hugely to the determinism.

> + * - Hardware translation table updates to Access flag and Dirty state
> + * - Number of VMID bits from CPU
> + * - Hierarchical Permission Disables
> + * - Privileged Access Never
> + * - SError interrupt exceptions from speculative reads
> + * - Enhanced Translation Synchronization

As before, I think this is a mixture of "trivial" and "cannot trap"
features.

> + */
> +#define PVM_ID_AA64MMFR1_ALLOW (\
> +	FEATURE(ID_AA64MMFR1_HADBS) | \
> +	FEATURE(ID_AA64MMFR1_VMIDBITS) | \
> +	FEATURE(ID_AA64MMFR1_HPD) | \
> +	FEATURE(ID_AA64MMFR1_PAN) | \
> +	FEATURE(ID_AA64MMFR1_SPECSEI) | \
> +	FEATURE(ID_AA64MMFR1_ETS) \
> +	)
> +
> +/*
> + * These features are chosen because they are supported by KVM and to limit the
> + * confiruation state space and make it more deterministic.

<same comment>

> + * - Common not Private translations
> + * - User Access Override
> + * - IESB bit in the SCTLR_ELx registers
> + * - Unaligned single-copy atomicity and atomic functions
> + * - ESR_ELx.EC value on an exception by read access to feature ID space
> + * - TTL field in address operations.
> + * - Break-before-make sequences when changing translation block size
> + * - E0PDx mechanism
> + */
> +#define PVM_ID_AA64MMFR2_ALLOW (\
> +	FEATURE(ID_AA64MMFR2_CNP) | \
> +	FEATURE(ID_AA64MMFR2_UAO) | \
> +	FEATURE(ID_AA64MMFR2_IESB) | \
> +	FEATURE(ID_AA64MMFR2_AT) | \
> +	FEATURE(ID_AA64MMFR2_IDS) | \
> +	FEATURE(ID_AA64MMFR2_TTL) | \
> +	FEATURE(ID_AA64MMFR2_BBM) | \
> +	FEATURE(ID_AA64MMFR2_E0PD) \
> +	)
> +
> +/*
> + * Allow all features in this register because they are trivial to support, or
> + * are already supported by KVM:
> + * - LS64
> + * - XS
> + * - I8MM
> + * - DGB
> + * - BF16
> + * - SPECRES
> + * - SB
> + * - FRINTTS
> + * - PAuth
> + * - FPAC
> + * - LRCPC
> + * - FCMA
> + * - JSCVT
> + * - DPB
> + */
> +#define PVM_ID_AA64ISAR1_ALLOW (~0ULL)
> +
> +#endif /* __ARM64_KVM_FIXED_CONFIG_H__ */
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index ac67d5699c68..e1ceadd69575 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -780,6 +780,8 @@ static inline bool kvm_vm_is_protected(struct kvm *kvm)
>  	return false;
>  }
>  
> +void kvm_init_protected_traps(struct kvm_vcpu *vcpu);
> +
>  int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
>  bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
>  
> diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
> index 657d0c94cf82..3f4866322f85 100644
> --- a/arch/arm64/include/asm/kvm_hyp.h
> +++ b/arch/arm64/include/asm/kvm_hyp.h
> @@ -115,7 +115,10 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
>  void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
>  #endif
>  
> +extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
> +extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
>  extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
>  extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
> +extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
>  
>  #endif /* __ARM64_KVM_HYP_H__ */
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index 989bb5dad2c8..0be63f5c495f 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -14,7 +14,7 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
>  	 $(KVM)/vfio.o $(KVM)/irqchip.o $(KVM)/binary_stats.o \
>  	 arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \
>  	 inject_fault.o va_layout.o handle_exit.o \
> -	 guest.o debug.o reset.o sys_regs.o \
> +	 guest.o debug.o pkvm.o reset.o sys_regs.o \
>  	 vgic-sys-reg-v3.o fpsimd.o pmu.o \
>  	 arch_timer.o trng.o\
>  	 vgic/vgic.o vgic/vgic-init.o \
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 14b12f2c08c0..3f28549aff0d 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -618,6 +618,14 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
>  
>  	ret = kvm_arm_pmu_v3_enable(vcpu);
>  
> +	/*
> +	 * Initialize traps for protected VMs.
> +	 * NOTE: Move  trap initialization to EL2 once the code is in place for
> +	 * maintaining protected VM state at EL2 instead of the host.
> +	 */
> +	if (kvm_vm_is_protected(kvm))
> +		kvm_init_protected_traps(vcpu);
> +
>  	return ret;
>  }
>  
> @@ -1781,8 +1789,11 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
>  	void *addr = phys_to_virt(hyp_mem_base);
>  	int ret;
>  
> +	kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> +	kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
>  	kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
>  	kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
> +	kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
>  
>  	ret = create_hyp_mappings(addr, addr + hyp_mem_size, PAGE_HYP);
>  	if (ret)
> diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
> index 5df6193fc430..a23f417a0c20 100644
> --- a/arch/arm64/kvm/hyp/nvhe/Makefile
> +++ b/arch/arm64/kvm/hyp/nvhe/Makefile
> @@ -14,7 +14,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
>  
>  obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
>  	 hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
> -	 cache.o setup.o mm.o mem_protect.o
> +	 cache.o setup.o mm.o mem_protect.o sys_regs.o
>  obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
>  	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
>  obj-y += $(lib-objs)
> diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> new file mode 100644
> index 000000000000..6c7230aa70e9
> --- /dev/null
> +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> @@ -0,0 +1,443 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2021 Google LLC
> + * Author: Fuad Tabba <tabba at google.com>
> + */
> +
> +#include <linux/kvm_host.h>
> +
> +#include <asm/kvm_asm.h>
> +#include <asm/kvm_emulate.h>
> +#include <asm/kvm_fixed_config.h>
> +#include <asm/kvm_mmu.h>
> +
> +#include <hyp/adjust_pc.h>
> +
> +#include "../../sys_regs.h"
> +
> +/*
> + * Copies of the host's CPU features registers holding sanitized values.
> + */
> +u64 id_aa64pfr0_el1_sys_val;
> +u64 id_aa64pfr1_el1_sys_val;
> +u64 id_aa64mmfr2_el1_sys_val;
> +
> +/*
> + * Inject an unknown/undefined exception to the guest.
> + */
> +static void inject_undef(struct kvm_vcpu *vcpu)
> +{
> +	u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
> +
> +	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 |
> +			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
> +			     KVM_ARM64_PENDING_EXCEPTION);
> +
> +	__kvm_adjust_pc(vcpu);
> +
> +	write_sysreg_el1(esr, SYS_ESR);
> +	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
> +}
> +
> +/*
> + * Accessor for undefined accesses.
> + */
> +static bool undef_access(struct kvm_vcpu *vcpu,
> +			 struct sys_reg_params *p,
> +			 const struct sys_reg_desc *r)
> +{
> +	inject_undef(vcpu);
> +	return false;
> +}
> +
> +/*
> + * Accessors for feature registers.
> + *
> + * If access is allowed, set the regval to the protected VM's view of the
> + * register and return true.
> + * Otherwise, inject an undefined exception and return false.
> + */
> +
> +/*
> + * Returns the minimum feature supported and allowed.
> + */
> +static u64 get_min_feature(u64 feature, u64 allowed_features,
> +			   u64 supported_features)
> +{
> +	const u64 allowed_feature = FIELD_GET(feature, allowed_features);
> +	const u64 supported_feature = FIELD_GET(feature, supported_features);
> +
> +	return min(allowed_feature, supported_feature);

Careful here: this is an unsigned comparison, yet some fields are signed.
cpufeature.c uses the S_ARM64_FTR_BITS and ARM64_FTR_BITS to declare signed
and unsigned fields respectively.

Will


From will at kernel.org  Thu Aug 12 02:46:18 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 10:46:18 +0100
Subject: [PATCH v3 12/15] KVM: arm64: Move sanitized copies of CPU features
In-Reply-To: <20210719160346.609914-13-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-13-tabba@google.com>
Message-ID: <20210812094617.GI5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:43PM +0100, Fuad Tabba wrote:
> Move the sanitized copies of the CPU feature registers to the
> recently created sys_regs.c. This consolidates all copies in a
> more relevant file.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 6 ------
>  arch/arm64/kvm/hyp/nvhe/sys_regs.c    | 2 ++
>  2 files changed, 2 insertions(+), 6 deletions(-)

Acked-by: Will Deacon <will at kernel.org>

Will


From f.fainelli at gmail.com  Thu Aug 12 02:46:16 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 12 Aug 2021 02:46:16 -0700
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <VI1PR04MB6800F8425473916A82F050F5E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
 <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <90af8051-512d-1230-72a7-8bbcee984939@gmail.com>
 <VI1PR04MB6800F8425473916A82F050F5E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>
Message-ID: <e3834192-249a-576e-daa0-fb2fac177397@gmail.com>



On 8/11/2021 1:06 AM, Joakim Zhang wrote:
> 
>> -----Original Message-----
>> From: Florian Fainelli <f.fainelli at gmail.com>
>> Sent: 2021?8?11? 1:45
>> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
>> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
>> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
>> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
>> netdev at vger.kernel.org; devicetree at vger.kernel.org;
>> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
>> wakeup-irq" property
>>
>>
>>
>> On 8/9/2021 7:21 PM, Joakim Zhang wrote:
>>>
>>> Hi Florian,
>>>
>>>> -----Original Message-----
>>>> From: Florian Fainelli <f.fainelli at gmail.com>
>>>> Sent: 2021?8?10? 2:40
>>>> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
>>>> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
>>>> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
>>>> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
>>>> netdev at vger.kernel.org; devicetree at vger.kernel.org;
>>>> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
>>>> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add
>>>> "fsl, wakeup-irq" property
>>>>
>>>>
>>>>
>>>> On 8/8/2021 10:08 PM, Joakim Zhang wrote:
>>>>>
>>>>> Hi Florian,
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Florian Fainelli <f.fainelli at gmail.com>
>>>>>> Sent: 2021?8?5? 17:18
>>>>>> To: Joakim Zhang <qiangqing.zhang at nxp.com>; davem at davemloft.net;
>>>>>> kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
>>>>>> s.hauer at pengutronix.de; festevam at gmail.com; andrew at lunn.ch
>>>>>> Cc: kernel at pengutronix.de; dl-linux-imx <linux-imx at nxp.com>;
>>>>>> netdev at vger.kernel.org; devicetree at vger.kernel.org;
>>>>>> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
>>>>>> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add
>>>>>> "fsl, wakeup-irq" property
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 8/5/2021 12:46 AM, Joakim Zhang wrote:
>>>>>>> Add "fsl,wakeup-irq" property for FEC controller to select wakeup
>>>>>>> irq source.
>>>>>>>
>>>>>>> Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
>>>>>>> Signed-off-by: Joakim Zhang <qiangqing.zhang at nxp.com>
>>>>>>
>>>>>> Why are not you making use of the standard interrupts-extended
>>>>>> property which allows different interrupt lines to be originating
>>>>>> from different interrupt controllers, e.g.:
>>>>>>
>>>>>> interrupts-extended = <&gic GIC_SPI 112 4>, <&wakeup_intc 0>;
>>>>>
>>>>> Thanks.
>>>>>
>>>>> AFAIK, interrupts-extended should be used instead of interrupts when
>>>>> a device is connected to multiple interrupt controllers as it
>>>>> encodes a parent phandle with each interrupt specifier. However, for
>>>>> FEC controller, all
>>>> interrupt lines are originating from the same interrupt controllers.
>>>>
>>>> OK, so why this custom property then?
>>>>
>>>>>
>>>>> 1) FEC controller has up to 4 interrupt lines and all of these are
>>>>> routed to GIC
>>>> interrupt controller.
>>>>> 2) FEC has a wakeup interrupt signal and always are mixed with other
>>>> interrupt signals, and then output to one interrupt line.
>>>>> 3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but for
>>>>> i.MX8M
>>>> serials, are mixed to int2 line.
>>>>> 4) Now driver treat int0 as the wakeup source by default, it is
>>>>> broken for
>>>> i.MX8M.
>>>>
>>>> I don't really know what to make of your response, it seems to me
>>>> that you are carrying some legacy Device Tree properties that were
>>>> invented when interrupts-extended did not exist and we did not know any
>> better.
>>>
>>> As I described in former mail, it is not related to interrupts-extended
>> property.
>>>
>>> Let's take a look, e.g.
>>>
>>> 1) arch/arm/boot/dts/imx7d.dtsi
>>> interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
>>> 		<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
>>> 		<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
>>> 		<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
>>> interrupt-names = "int0", "int1", "int2", "pps";
>>>
>>> For these 4 interrupts are originating from GIC interrupt controller,
>>> "int0" for queue 0 and other interrupt signals, containing wakeup; "int1" for
>> queue 1; "int2" for queue 2.
>>>
>>> 2) arch/arm64/boot/dts/freescale/imx8mq.dtsi
>>> interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
>>> 	<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
>>> 	<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
>>> 	<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
>>> interrupt-names = "int0", "int1", "int2", "pps";
>>>
>>> For these 4 interrupts are also originating from GIC interrupt
>>> controller, "int0" for queue 0; "int1" for queue 1; "int2" for queue 2 and other
>> interrupt signals, containing wakeup.
>>>
>>> If we want to use WoL feature, we need invoke enable_irq_wake() to let
>>> this specific interrupt line be a wakeup source. For FEC driver now,
>>> it treats "int0" as wakeup interrupt by default. Obviously it's not fine for
>> i.MX8M serials, since SoC mix wakeup interrupt signal into "int2", so I add this
>> "fsl,wakeup-irq" custom property to indicate which interrupt line contains
>> wakeup signal.
>>>
>>> Not sure if I have explained it clearly enough, from my point of view, I think
>> interrupts-extended property can't fix this issue, right?
>>
>> This is clearer, and indeed interrupts-extended won't fix that, however it seems
>> to me that this is a problem that ought to be fixed at the interrupt
>> controller/irq_chip level which should know and be told which interrupt lines
>> can be made wake-up interrupts or not. From there on, the driver can test with
>> enable_irq_wake() whether this has a chance of working or not.
> 
> How can we test with enable_irq_wake()? I agree that interrupt controller can recognize
> wakeup interrupt is better.

If enable_irq_wake() returns -ENOTSUPP you would know that wake-up for 
that interrupt controller's line is not capable of wake-up?

> 
>> It seems to me that the 'fsl,wakeup-irq' property ought to be within the
>> interrupt controller Device Tree node (where it would be easier to validate that
>> the specific interrupt line is correct) as opposed to within the consumer (FEC)
>> Device Tree node.
> 
> Not quite understand, could you explain more?

What I mean is that if you need to express which interrupt lines within 
an interrupt controller are capable of wake-up, then there should be a 
property that tells us that and that property needs to be within the 
interrupt controller, not within the consumer of that interrupt since 
the consumer has no idea how the system is wired up. Andrew's suggestion 
is sort of the same thing, except that it punts the responsibility of 
specifying the interrupt's capability towards the consumer of that 
interrupt.
-- 
Florian


From wenst at chromium.org  Thu Aug 12 02:47:51 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Thu, 12 Aug 2021 17:47:51 +0800
Subject: [PATCH 0/2] arm64: dts: rockchip: Add Scarlet Dumo Variant
Message-ID: <20210812094753.2359087-1-wenst@chromium.org>

Hi,

A variant of the Chrome OS Gru-Scarlet device is missing in upstream.
This variant, dumo, is the same as the Innolux display panel variant,
but requires a specific calibration variant for its WiFi module.

I'm not sure if it's better to inherit from gru-scarlet-innolux. I kept
them separate from now, like in downstream ChromeOS kernel v4.4.

The series is based on linux-next-20210812. Please have a look.


Regards
ChenYu


Chen-Yu Tsai (2):
  dt-bindings: arm: rockchip: Add gru-scarlet-dumo board
  arm64: dts: rockchip: rk3399: Add gru-scarlet-dumo board

 .../devicetree/bindings/arm/rockchip.yaml     | 28 +++++++++++++
 arch/arm64/boot/dts/rockchip/Makefile         |  1 +
 .../dts/rockchip/rk3399-gru-scarlet-dumo.dts  | 41 +++++++++++++++++++
 3 files changed, 70 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts

-- 
2.32.0.605.g8dce9f2422-goog



From wenst at chromium.org  Thu Aug 12 02:47:53 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Thu, 12 Aug 2021 17:47:53 +0800
Subject: [PATCH 2/2] arm64: dts: rockchip: rk3399: Add gru-scarlet-dumo board
In-Reply-To: <20210812094753.2359087-1-wenst@chromium.org>
References: <20210812094753.2359087-1-wenst@chromium.org>
Message-ID: <20210812094753.2359087-3-wenst@chromium.org>

Dumo is another variant of Scarlet, also known as the ASUS Chromebook
Tablet CT100. This is almost the same as Scarlet-Innolux, but uses a
board-specific calibration variant for the WiFi module.

Add a new device tree for it.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 arch/arm64/boot/dts/rockchip/Makefile         |  1 +
 .../dts/rockchip/rk3399-gru-scarlet-dumo.dts  | 41 +++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 12a8b6cacdbd..479906f3ad7b 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -25,6 +25,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-ficus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-bob.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-scarlet-dumo.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-scarlet-inx.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-scarlet-kd.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-hugsun-x99.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts
new file mode 100644
index 000000000000..853e88455e75
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Gru-Scarlet Rev5+ (SKU-0) board device tree source
+ *
+ * Copyright 2021 Google LLC.
+ */
+
+/dts-v1/;
+
+#include "rk3399-gru-scarlet.dtsi"
+
+/ {
+	model = "Google Scarlet";
+	compatible = "google,scarlet-rev15-sku0", "google,scarlet-rev15",
+		     "google,scarlet-rev14-sku0", "google,scarlet-rev14",
+		     "google,scarlet-rev13-sku0", "google,scarlet-rev13",
+		     "google,scarlet-rev12-sku0", "google,scarlet-rev12",
+		     "google,scarlet-rev11-sku0", "google,scarlet-rev11",
+		     "google,scarlet-rev10-sku0", "google,scarlet-rev10",
+		     "google,scarlet-rev9-sku0",  "google,scarlet-rev9",
+		     "google,scarlet-rev8-sku0",  "google,scarlet-rev8",
+		     "google,scarlet-rev7-sku0",  "google,scarlet-rev7",
+		     "google,scarlet-rev6-sku0",  "google,scarlet-rev6",
+		     "google,scarlet-rev5-sku0",  "google,scarlet-rev5",
+		     "google,scarlet", "google,gru", "rockchip,rk3399";
+};
+
+&mipi_panel {
+	compatible = "innolux,p097pfg";
+	avdd-supply = <&ppvarp_lcd>;
+	avee-supply = <&ppvarn_lcd>;
+};
+
+&pci_rootport {
+	wifi at 0,0 {
+		compatible = "qcom,ath10k";
+		reg = <0x00010000 0x0 0x00000000 0x0 0x00000000>,
+		      <0x03010010 0x0 0x00000000 0x0 0x00200000>;
+		qcom,ath10k-calibration-variant = "GO_DUMO";
+	};
+};
-- 
2.32.0.605.g8dce9f2422-goog



From wenst at chromium.org  Thu Aug 12 02:47:52 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Thu, 12 Aug 2021 17:47:52 +0800
Subject: [PATCH 1/2] dt-bindings: arm: rockchip: Add gru-scarlet-dumo board
In-Reply-To: <20210812094753.2359087-1-wenst@chromium.org>
References: <20210812094753.2359087-1-wenst@chromium.org>
Message-ID: <20210812094753.2359087-2-wenst@chromium.org>

Dumo is another variant of Scarlet, also known as the ASUS Chromebook
Tablet CT100. This is almost the same as Scarlet-Innolux, but uses a
specific calibration variant for the WiFi module.

Add an entry for the board compatibles.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 .../devicetree/bindings/arm/rockchip.yaml     | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index aa9a4fd4fc20..4aed16176434 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -298,6 +298,34 @@ properties:
           - const: google,veyron
           - const: rockchip,rk3288
 
+      - description: Google Scarlet - Dumo (ASUS Chromebook Tablet CT100)
+        items:
+          - const: google,scarlet-rev15-sku0
+          - const: google,scarlet-rev15
+          - const: google,scarlet-rev14-sku0
+          - const: google,scarlet-rev14
+          - const: google,scarlet-rev13-sku0
+          - const: google,scarlet-rev13
+          - const: google,scarlet-rev12-sku0
+          - const: google,scarlet-rev12
+          - const: google,scarlet-rev11-sku0
+          - const: google,scarlet-rev11
+          - const: google,scarlet-rev10-sku0
+          - const: google,scarlet-rev10
+          - const: google,scarlet-rev9-sku0
+          - const: google,scarlet-rev9
+          - const: google,scarlet-rev8-sku0
+          - const: google,scarlet-rev8
+          - const: google,scarlet-rev7-sku0
+          - const: google,scarlet-rev7
+          - const: google,scarlet-rev6-sku0
+          - const: google,scarlet-rev6
+          - const: google,scarlet-rev5-sku0
+          - const: google,scarlet-rev5
+          - const: google,scarlet
+          - const: google,gru
+          - const: rockchip,rk3399
+
       - description: Google Scarlet - Kingdisplay (Acer Chromebook Tab 10)
         items:
           - const: google,scarlet-rev15-sku7
-- 
2.32.0.605.g8dce9f2422-goog



From will at kernel.org  Thu Aug 12 02:49:14 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 10:49:14 +0100
Subject: [PATCH v3 06/15] KVM: arm64: Restore mdcr_el2 from vcpu
In-Reply-To: <CA+EHjTx7q+DeR2dNL9X6jLcqtr=ZZ5YN4WsnnbOUPvtQZP1dSQ@mail.gmail.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-7-tabba@google.com>
 <20210720145258.axhqog3abdvtpqhw@gator>
 <CA+EHjTweLPu+DQ8hR9kEW0LrawtaoAoXR_+HmSEZpP-XOEm2qg@mail.gmail.com>
 <20210812084600.GA5912@willie-the-truck>
 <CA+EHjTx7q+DeR2dNL9X6jLcqtr=ZZ5YN4WsnnbOUPvtQZP1dSQ@mail.gmail.com>
Message-ID: <20210812094914.GJ5912@willie-the-truck>

Hey Fuad,

On Thu, Aug 12, 2021 at 11:28:50AM +0200, Fuad Tabba wrote:
> On Thu, Aug 12, 2021 at 10:46 AM Will Deacon <will at kernel.org> wrote:
> >
> > On Wed, Jul 21, 2021 at 08:37:21AM +0100, Fuad Tabba wrote:
> > > On Tue, Jul 20, 2021 at 3:53 PM Andrew Jones <drjones at redhat.com> wrote:
> > > >
> > > > On Mon, Jul 19, 2021 at 05:03:37PM +0100, Fuad Tabba wrote:
> > > > > On deactivating traps, restore the value of mdcr_el2 from the
> > > > > newly created and preserved host value vcpu context, rather than
> > > > > directly reading the hardware register.
> > > > >
> > > > > Up until and including this patch the two values are the same,
> > > > > i.e., the hardware register and the vcpu one. A future patch will
> > > > > be changing the value of mdcr_el2 on activating traps, and this
> > > > > ensures that its value will be restored.
> > > > >
> > > > > No functional change intended.
> > > >
> > > > I'm probably missing something, but I can't convince myself that the host
> > > > will end up with the same mdcr_el2 value after deactivating traps after
> > > > this patch as before. We clearly now restore whatever we had when
> > > > activating traps (presumably whatever we configured at init_el2_state
> > > > time), but is that equivalent to what we had before with the masking and
> > > > ORing that this patch drops?
> > >
> > > You're right. I thought that these were actually being initialized to
> > > the same values, but having a closer look at the code the mdcr values
> > > are not the same as pre-patch. I will fix this.
> >
> > Can you elaborate on the issue here, please? I was just looking at this
> > but aren't you now relying on __init_el2_debug to configure this, which
> > should be fine?
> 
> I *think* that it should be fine, but as Drew pointed out, the host
> does not end up with the same mdcr_el2 value after the deactivation in
> this patch as it did after deactivation before this patch. In my v4
> (not sent out yet), I have fixed it to ensure that the host does end
> up with the same value as the one before this patch. That should make
> it easier to check that there's no functional change.
> 
> I'll look into it further, and if I can convince myself that there
> aren't any issues and that this patch makes the code cleaner, I will
> add it as a separate patch instead to make reviewing easier.

Cheers. I think the new code might actually be better, as things like
MDCR_EL2.E2PB are RES0 if SPE is not implemented. The init code takes care
to set those only if if probes SPE first, whereas the code you're removing
doesn't seem to check that.

Will


From will at kernel.org  Thu Aug 12 02:53:39 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 10:53:39 +0100
Subject: [PATCH v3 13/15] KVM: arm64: Trap access to pVM restricted
 features
In-Reply-To: <20210719160346.609914-14-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-14-tabba@google.com>
Message-ID: <20210812095338.GK5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:44PM +0100, Fuad Tabba wrote:
> Trap accesses to restricted features for VMs running in protected
> mode.
> 
> Access to feature registers are emulated, and only supported
> features are exposed to protected VMs.
> 
> Accesses to restricted registers as well as restricted
> instructions are trapped, and an undefined exception is injected
> into the protected guests, i.e., with EC = 0x0 (unknown reason).
> This EC is the one used, according to the Arm Architecture
> Reference Manual, for unallocated or undefined system registers
> or instructions.
> 
> Only affects the functionality of protected VMs. Otherwise,
> should not affect non-protected VMs when KVM is running in
> protected mode.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  3 ++
>  arch/arm64/kvm/hyp/nvhe/switch.c        | 52 ++++++++++++++++++-------
>  2 files changed, 41 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 5a2b89b96c67..8431f1514280 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -33,6 +33,9 @@
>  extern struct exception_table_entry __start___kvm_ex_table;
>  extern struct exception_table_entry __stop___kvm_ex_table;
>  
> +int kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu);
> +int kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu);
> +
>  /* Check whether the FP regs were dirtied while in the host-side run loop: */
>  static inline bool update_fp_enabled(struct kvm_vcpu *vcpu)
>  {
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index 36da423006bd..99bbbba90094 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -158,30 +158,54 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
>  		write_sysreg(pmu->events_host, pmcntenset_el0);
>  }
>  
> +/**
> + * Handle system register accesses for protected VMs.
> + *
> + * Return 1 if handled, or 0 if not.
> + */
> +static int handle_pvm_sys64(struct kvm_vcpu *vcpu)
> +{
> +	return kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)) ?
> +			     kvm_handle_pvm_sys64(vcpu) :
> +			     0;
> +}

Why don't we move the kvm_vm_is_protected() check into
kvm_get_hyp_exit_handler() so we can avoid adding it to each handler
instead?

Either way:

Acked-by: Will Deacon <will at kernel.org>

Will


From will at kernel.org  Thu Aug 12 02:57:44 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 10:57:44 +0100
Subject: [PATCH v3 14/15] KVM: arm64: Handle protected guests at 32 bits
In-Reply-To: <20210719160346.609914-15-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-15-tabba@google.com>
Message-ID: <20210812095743.GL5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:45PM +0100, Fuad Tabba wrote:
> Protected KVM does not support protected AArch32 guests. However,
> it is possible for the guest to force run AArch32, potentially
> causing problems. Add an extra check so that if the hypervisor
> catches the guest doing that, it can prevent the guest from
> running again by resetting vcpu->arch.target and returning
> ARM_EXCEPTION_IL.
> 
> Adapted from commit 22f553842b14 ("KVM: arm64: Handle Asymmetric
> AArch32 systems")
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/kvm/hyp/include/hyp/switch.h | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 8431f1514280..f09343e15a80 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -23,6 +23,7 @@
>  #include <asm/kprobes.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
> +#include <asm/kvm_fixed_config.h>
>  #include <asm/kvm_hyp.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/fpsimd.h>
> @@ -477,6 +478,29 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  			write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
>  	}
>  
> +	/*
> +	 * Protected VMs might not be allowed to run in AArch32. The check below
> +	 * is based on the one in kvm_arch_vcpu_ioctl_run().
> +	 * The ARMv8 architecture doesn't give the hypervisor a mechanism to
> +	 * prevent a guest from dropping to AArch32 EL0 if implemented by the
> +	 * CPU. If the hypervisor spots a guest in such a state ensure it is
> +	 * handled, and don't trust the host to spot or fix it.
> +	 */
> +	if (unlikely(is_nvhe_hyp_code() &&
> +		     kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)) &&
> +		     FIELD_GET(FEATURE(ID_AA64PFR0_EL0),
> +			       PVM_ID_AA64PFR0_ALLOW) <
> +			     ID_AA64PFR0_ELx_32BIT_64BIT &&
> +		     vcpu_mode_is_32bit(vcpu))) {
> +		/*
> +		 * As we have caught the guest red-handed, decide that it isn't
> +		 * fit for purpose anymore by making the vcpu invalid.
> +		 */
> +		vcpu->arch.target = -1;
> +		*exit_code = ARM_EXCEPTION_IL;
> +		goto exit;
> +	}

Would this be better off inside the nvhe-specific run loop? Seems like we
could elide fixup_guest_exit() altogether if we've detect that we're in
AArch32 state when we shouldn't be and it would keep the code off the shared
path.

Will


From will at kernel.org  Thu Aug 12 02:59:40 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 12 Aug 2021 10:59:40 +0100
Subject: [PATCH v3 15/15] KVM: arm64: Restrict protected VM capabilities
In-Reply-To: <20210719160346.609914-16-tabba@google.com>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-16-tabba@google.com>
Message-ID: <20210812095938.GM5912@willie-the-truck>

On Mon, Jul 19, 2021 at 05:03:46PM +0100, Fuad Tabba wrote:
> Restrict protected VM capabilities based on the
> fixed-configuration for protected VMs.
> 
> No functional change intended in current KVM-supported modes
> (nVHE, VHE).
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_fixed_config.h | 10 ++++
>  arch/arm64/kvm/arm.c                      | 63 ++++++++++++++++++++++-
>  arch/arm64/kvm/pkvm.c                     | 30 +++++++++++
>  3 files changed, 102 insertions(+), 1 deletion(-)

This patch looks good to me, but I'd be inclined to add this to the user-ABI
series given that it's really all user-facing and, without a functional
kvm_vm_is_protected(), isn't serving much purpose.

Cheers,

Will


From patchwork-bot+netdevbpf at kernel.org  Thu Aug 12 03:00:06 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 12 Aug 2021 10:00:06 +0000
Subject: [PATCH net-next] net: dsa: mt7530: fix VLAN traffic leaks again
In-Reply-To: <20210811095043.1700061-1-dqfext@gmail.com>
References: <20210811095043.1700061-1-dqfext@gmail.com>
Message-ID: <162876240687.6902.14605902617499288116.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (refs/heads/master):

On Wed, 11 Aug 2021 17:50:43 +0800 you wrote:
> When a port leaves a VLAN-aware bridge, the current code does not clear
> other ports' matrix field bit. If the bridge is later set to VLAN-unaware
> mode, traffic in the bridge may leak to that port.
> 
> Remove the VLAN filtering check in mt7530_port_bridge_leave.
> 
> Fixes: 474a2ddaa192 ("net: dsa: mt7530: fix VLAN traffic leaks")
> Fixes: 83163f7dca56 ("net: dsa: mediatek: add VLAN support for MT7530")
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> 
> [...]

Here is the summary with links:
  - [net-next] net: dsa: mt7530: fix VLAN traffic leaks again
    https://git.kernel.org/netdev/net-next/c/7428022b50d0

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From herbert at gondor.apana.org.au  Thu Aug 12 03:04:37 2021
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 12 Aug 2021 18:04:37 +0800
Subject: [PATCH v2] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <20210803063149.2821093-1-mudongliangabcd@gmail.com>
References: <20210803063149.2821093-1-mudongliangabcd@gmail.com>
Message-ID: <20210812100437.GA5055@gondor.apana.org.au>

On Tue, Aug 03, 2021 at 02:31:38PM +0800, Dongliang Mu wrote:
>
> -theend:
> -	kfree(buf);
> +err_result:
>  	kfree(result);
> -	crypto_finalize_hash_request(engine, breq, err);
> +err_buf:
> +	kfree(buf);
> +out:
> +	if (!err)
> +		crypto_finalize_hash_request(engine, breq, err);
>  	return 0;

This does not look right.  You're returning zero in case of an error

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From anshuman.khandual at arm.com  Thu Aug 12 03:09:47 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 12 Aug 2021 15:39:47 +0530
Subject: [RFC V2 05/10] arm64/mm: Add CONFIG_ARM64_PA_BITS_52_[LPA|LPA2]
In-Reply-To: <20210805172550.GG6719@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-6-git-send-email-anshuman.khandual@arm.com>
 <20210805172550.GG6719@arm.com>
Message-ID: <44a3f3e2-ee11-09b1-69cf-210aa2f6ddb5@arm.com>



On 8/5/21 10:55 PM, Catalin Marinas wrote:
> On Mon, Jul 26, 2021 at 12:07:20PM +0530, Anshuman Khandual wrote:
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index b5b13a9..1999ac6 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -934,6 +934,12 @@ config ARM64_VA_BITS
>>  	default 48 if ARM64_VA_BITS_48
>>  	default 52 if ARM64_VA_BITS_52
>>  
>> +config ARM64_PA_BITS_52_LPA
>> +	bool
>> +
>> +config ARM64_PA_BITS_52_LPA2
>> +	bool
>> +
>>  choice
>>  	prompt "Physical address space size"
>>  	default ARM64_PA_BITS_48
>> @@ -948,6 +954,7 @@ config ARM64_PA_BITS_52
>>  	bool "52-bit (ARMv8.2)"
>>  	depends on ARM64_64K_PAGES
>>  	depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
>> +	select ARM64_PA_BITS_52_LPA if ARM64_64K_PAGES
>>  	help
>>  	  Enable support for a 52-bit physical address space, introduced as
>>  	  part of the ARMv8.2-LPA extension.
> 
> Do we actually need to bother with LPA, LPA2 options? We could just add

These are internal configs for code organization purpose, which otherwise
becomes bit entangled. Basically these configs just imply the following
combinations being selected together.

- ARM64_PA_BITS_52_LPA	: ARM64_64K_PAGES && ARM64_PA_BITS_52
- ARM64_PA_BITS_52_LPA2	: (ARM64_4K_PAGES || ARM64_16K_PAGES) && ARM64_PA_BITS_52

There are some benefits here

- ARM64_PA_BITS_52_[LPA|LPA2] helps in avoiding writing out code blocks for
  these above combinations in various different places, keeps it clean.

- Cleanly encapsulates ARM64_PA_BITS_52 implementation into two different
  logical code blocks depending on the respective HW features enabling it
  i.e FEAT_LPA and FEAT_LPA2. This is important because there are distinct
  pte <----> phys encodings, ptdump handling, setting TCR_DS, FEAT_LPA2
  detection, PTE sharability attribute handling which are dependent on how
  52 bits PA is implemented.

> an extra defined(ARM64_64K_PAGES) in places, it may be easier to follow
> in a few years time when we won't remember what LPA or LPA2 was. I

Are you suggesting that over the years, folks might forget about LPA/LPA2
details and might have to look back in arch/arm64/Kconfig to figure this
out, which is not desirable ? But would not that be an acceptable trade
off given the encapsulation it helps achieve ?

> haven't got to the rest of the patches but it may just be simpler to
> define the shifts separately for 52-bit based on 4K/16K/64K and ignore
> the LPA/LPA2 distinction altogether (we'll still keep it for CPUID
> checking though).
> 

Sure. After you have gone through and reviewed rest of the series, if it
still appears that dropping LPA/LPA2 distinction here would be simpler
from a long term perspective, will be happy to change it accordingly.


From sven at svenpeter.dev  Thu Aug 12 03:09:42 2021
From: sven at svenpeter.dev (Sven Peter)
Date: Thu, 12 Aug 2021 12:09:42 +0200
Subject: [PATCH] irqchip/apple-aic: fix irq_disable from within irq handlers
Message-ID: <20210812100942.17206-1-sven@svenpeter.dev>

When disable_irq_nosync for an interrupt is called from within its
interrupt handler, this interrupt is only marked as disabled with the
intention to mask it when it triggers again.
The AIC hardware however automatically masks the interrupt when it is read.
aic_irq_eoi then unmasks it again if it's not disabled *and* not masked.
This results in a state mismatch between the hardware state and the
state kept in irq_data: The hardware interrupt is masked but
IRQD_IRQ_MASKED is not set. Any further calls to unmask_irq will directly
return and the interrupt can never be enabled again.

Fix this by keeping the hardware and irq_data state in sync by unmasking in
aic_irq_eoi if and only if the irq_data state also assumes the interrupt to
be unmasked.

Fixes: 76cde2639411 ("irqchip/apple-aic: Add support for the Apple Interrupt Controller")
Signed-off-by: Sven Peter <sven at svenpeter.dev>
---
 drivers/irqchip/irq-apple-aic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
index b8c06bd8659e..6fc145aacaf0 100644
--- a/drivers/irqchip/irq-apple-aic.c
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -226,7 +226,7 @@ static void aic_irq_eoi(struct irq_data *d)
 	 * Reading the interrupt reason automatically acknowledges and masks
 	 * the IRQ, so we just unmask it here if needed.
 	 */
-	if (!irqd_irq_disabled(d) && !irqd_irq_masked(d))
+	if (!irqd_irq_masked(d))
 		aic_irq_unmask(d);
 }
 
-- 
2.25.1



From maz at kernel.org  Thu Aug 12 03:13:16 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 11:13:16 +0100
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <764732f3-6cd7-bd18-4c83-1b851c29b2a4@gmail.com>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
 <878s179jsq.wl-maz@kernel.org>
 <764732f3-6cd7-bd18-4c83-1b851c29b2a4@gmail.com>
Message-ID: <875ywb9dj7.wl-maz@kernel.org>

On Thu, 12 Aug 2021 09:24:14 +0100,
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> 
> On 12.08.2021 09:57, Marc Zyngier wrote:
> > On Thu, 12 Aug 2021 08:32:02 +0100,
> > Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> >> 
> >> On 12.08.2021 08:51, Marc Zyngier wrote:
> >>> Interestingly, all your CPUs are booting at EL2. Which is great.  Can
> >>> you try and enable KVM on your existing 5.10 kernel? Just selecting
> >>> CONFIG_KVM should be enough. Does it boot correctly with KVM enabled?
> >>> 
> >>> My suspicion is that the firmware doesn't set SCR_EL3.HCE, and that
> >>> the HVC instruction UNDEFs at EL1. That would be bad news.
> >> 
> >> Interesting! I had to enable CONFIG_VIRTUALIZATION and CONFIG_NET first.
> >> First I verified kernel built with those options still boots. It does.
> >> 
> >> Then I enabled CONFIG_KVM and kernel seems to hang around switching from
> >> bootconsole to the console.
> >> 
> >> Starting program at 0x0000000000080000
> >> /memory = 0x40000000
> >> WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
> >> WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
> >> WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
> >> Booting Linux on physical CPU 0x0000000000 [0x420f1000]
> >> Linux version 5.11.22-g0453a426c37b (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #8 SMP Thu Aug 12 09:25:55 CEST 2021
> >> Machine model: Asus GT-AC5300
> >> earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
> >> printk: bootconsole [bcm63xx_uart0] enabled
> >> efi: UEFI not found.
> >> [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
> >> Zone ranges:
> >>    DMA      [mem 0x0000000000000000-0x000000003fffffff]
> >>    DMA32    empty
> >>    Normal   empty
> >> Movable zone start for each node
> >> Early memory node ranges
> >>    node   0: [mem 0x0000000000000000-0x000000003fffffff]
> >> Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
> >> percpu: Embedded 18 pages/cpu s43904 r0 d29824 u73728
> >> Detected VIPT I-cache on CPU0
> >> CPU features: detected: ARM erratum 843419
> >> Built 1 zonelists, mobility grouping on.  Total pages: 258048
> >> Kernel command line: earlycon=bcm63xx_uart,0xff800640
> >> Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
> >> Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
> >> mem auto-init: stack:off, heap alloc:off, heap free:off
> >> Memory: 1019556K/1048576K available (4352K kernel code, 678K rwdata, 860K rodata, 2496K init, 232K bss, 29020K reserved, 0K cma-reserved)
> >> SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
> >> rcu: Hierarchical RCU implementation.
> >> rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
> >> NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
> >> GIC: Using split EOI/Deactivate mode
> >> random: get_random_bytes called from start_kernel+0x33c/0x52c with crng_init=0
> >> arch_timer: cp15 timer(s) running at 50.00MHz (phys).
> >> clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
> >> sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
> >> Console: colour dummy device 80x25
> >> printk: console [tty0] enabled
> >> printk: bootconsole [bcm63xx_uart0] disabled
> >> 
> >> 
> >> (Unless it's a false conclusion and CONFIG_KVM just breaks console
> >> somehow)
> > 
> > No, that's because you don't pass the right console to your
> > kernel. Add something like "console=ttyS0,115200" to the kernel
> > command line, which will show what you are missing, as well as stop
> > the double-logging.
> > 
> > Anyway, the fact that it stops booting when you enable KVM confirms my
> > suspicion. The firmware on this system is probably crap enough not to
> > enable HVC. Let's confirm it further: please apply the patch below on
> > top of mainline and tell me that it now boots fine...
> 
> Thanks for the patch! It workarounds the issue. See below.
> 
> 
> > Are you in a position where you can actually fix the firmware? Or is
> > it some closed-source blob?
> 
> I'm just an end-user with no access to CFE sources and without any
> business contact as Broadcom :(

I feared that would be the case. Florian's reply seems to indicate
that the "upstream" firmware implementation is correct, so the OEM
must have fumbled it somehow...

> > diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> > index 43d212618834..fc95b103ef42 100644
> > --- a/arch/arm64/kernel/hyp-stub.S
> > +++ b/arch/arm64/kernel/hyp-stub.S
> > @@ -238,7 +238,7 @@ SYM_FUNC_START(switch_to_vhe)
> >     	// Turn the world upside down
> >   	mov	x0, #HVC_VHE_RESTART
> > -	hvc	#0
> > +//	hvc	#0
> >   1:
> >   	ret
> >   SYM_FUNC_END(switch_to_vhe)
> 
> This allows me to boot 5.13.9 and 5.14-rc5 without any reverts!
> 
> Enabling CONFIG_KVM still results in the:
> Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt

That's expected. Can you please check the patch below? It should
result in a booting kernel which actually survives having KVM compiled
in. It should even display a warning telling you that your setup is
completely buggered.

That's obviously not the final version, but probably a good enough
approximation.

Thanks,

	M.


diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 43d212618834..74a130808b38 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -46,6 +46,14 @@ SYM_CODE_END(__hyp_stub_vectors)
 	.align 11
 
 SYM_CODE_START_LOCAL(elx_sync)
+	mrs	x4, CurrentEL
+	cmp	x4, #CurrentEL_EL1
+	b.ne	0f
+	mrs	x4, esr_el1
+	eor	x4, x4, #ESR_ELx_IL
+	cbz	x4, el1_undef
+
+0:
 	cmp	x0, #HVC_SET_VECTORS
 	b.ne	1f
 	msr	vbar_el2, x1
@@ -71,6 +79,18 @@ SYM_CODE_START_LOCAL(elx_sync)
 
 9:	mov	x0, xzr
 	eret
+
+el1_undef:
+	# Downgrade the sucker to EL1...
+	adr_l	x1, __boot_cpu_mode
+	mov	w0, #BOOT_CPU_MODE_EL1
+	str	w0, [x1]
+
+	mrs	x0, elr_el1
+	add	x0, x0, #4
+	msr	elr_el1, x0
+	mov_q	x0, HVC_STUB_ERR
+	eret
 SYM_CODE_END(elx_sync)
 
 // nVHE? No way! Give me the real thing!
@@ -236,6 +256,19 @@ SYM_FUNC_START(switch_to_vhe)
 	cmp	x0, #CurrentEL_EL1
 	b.ne	1f
 
+	// Check that HVC actually works...
+	adr_l	x1, __hyp_stub_vectors
+	msr	vbar_el1, x1
+	isb
+	mov	x0, #HVC_RESET_VECTORS
+	hvc	#0
+	adr_l	x1, vectors
+	msr	vbar_el1, x1
+	isb
+	mov_q	x1, HVC_STUB_ERR
+	cmp	x0, x1
+	b.eq	1f
+
 	// Turn the world upside down
 	mov	x0, #HVC_VHE_RESTART
 	hvc	#0

-- 
Without deviation from the norm, progress is not possible.


From mudongliangabcd at gmail.com  Thu Aug 12 03:24:25 2021
From: mudongliangabcd at gmail.com (Dongliang Mu)
Date: Thu, 12 Aug 2021 18:24:25 +0800
Subject: [PATCH v2] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <20210812100437.GA5055@gondor.apana.org.au>
References: <20210803063149.2821093-1-mudongliangabcd@gmail.com>
 <20210812100437.GA5055@gondor.apana.org.au>
Message-ID: <CAD-N9QWGgBBddi5kwTNANKVVdWaQRwagMHvaH592B5GDALpBrg@mail.gmail.com>

On Thu, Aug 12, 2021 at 6:05 PM Herbert Xu <herbert at gondor.apana.org.au> wrote:
>
> On Tue, Aug 03, 2021 at 02:31:38PM +0800, Dongliang Mu wrote:
> >
> > -theend:
> > -     kfree(buf);
> > +err_result:
> >       kfree(result);
> > -     crypto_finalize_hash_request(engine, breq, err);
> > +err_buf:
> > +     kfree(buf);
> > +out:
> > +     if (!err)
> > +             crypto_finalize_hash_request(engine, breq, err);
> >       return 0;
>
> This does not look right.  You're returning zero in case of an error

Hi Herbert,

Corentin Labbe said,

For the error code, I am not sure it is needed, error code is already
given to user via crypto_finalize_hash_request().
The "return 0" is for crypto/crypto_engine API, returning an error
will not change anything since we dont have retry_support.

So I propose you to focus on dma_map_xxx() fix patch.

See details in [1]. P.S., my previous patch returns err variable.

[1] https://lkml.org/lkml/2021/7/26/164


>
> Cheers,
> --
> Email: Herbert Xu <herbert at gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From herbert at gondor.apana.org.au  Thu Aug 12 03:29:54 2021
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 12 Aug 2021 18:29:54 +0800
Subject: [PATCH v2] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <CAD-N9QWGgBBddi5kwTNANKVVdWaQRwagMHvaH592B5GDALpBrg@mail.gmail.com>
References: <20210803063149.2821093-1-mudongliangabcd@gmail.com>
 <20210812100437.GA5055@gondor.apana.org.au>
 <CAD-N9QWGgBBddi5kwTNANKVVdWaQRwagMHvaH592B5GDALpBrg@mail.gmail.com>
Message-ID: <20210812102954.GA5569@gondor.apana.org.au>

On Thu, Aug 12, 2021 at 06:24:25PM +0800, Dongliang Mu wrote:
> On Thu, Aug 12, 2021 at 6:05 PM Herbert Xu <herbert at gondor.apana.org.au> wrote:
> >
> > On Tue, Aug 03, 2021 at 02:31:38PM +0800, Dongliang Mu wrote:
> > >
> > > -theend:
> > > -     kfree(buf);
> > > +err_result:
> > >       kfree(result);
> > > -     crypto_finalize_hash_request(engine, breq, err);
> > > +err_buf:
> > > +     kfree(buf);
> > > +out:
> > > +     if (!err)
> > > +             crypto_finalize_hash_request(engine, breq, err);
> > >       return 0;
> >
> > This does not look right.  You're returning zero in case of an error
> 
> Hi Herbert,
> 
> Corentin Labbe said,
> 
> For the error code, I am not sure it is needed, error code is already
> given to user via crypto_finalize_hash_request().

Yes but your patch changes this.  You're now skipping the finalize
call and thus throwing away err if it's not zero.

If it's supposed to do this you need to explain it in your patch
submission.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From mudongliangabcd at gmail.com  Thu Aug 12 03:40:20 2021
From: mudongliangabcd at gmail.com (Dongliang Mu)
Date: Thu, 12 Aug 2021 18:40:20 +0800
Subject: [PATCH v2] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <20210812102954.GA5569@gondor.apana.org.au>
References: <20210803063149.2821093-1-mudongliangabcd@gmail.com>
 <20210812100437.GA5055@gondor.apana.org.au>
 <CAD-N9QWGgBBddi5kwTNANKVVdWaQRwagMHvaH592B5GDALpBrg@mail.gmail.com>
 <20210812102954.GA5569@gondor.apana.org.au>
Message-ID: <CAD-N9QU6r-yLBvJUpV+xy4pgOFnrtquBymthG7k5ddHt20APzg@mail.gmail.com>

On Thu, Aug 12, 2021 at 6:30 PM Herbert Xu <herbert at gondor.apana.org.au> wrote:
>
> On Thu, Aug 12, 2021 at 06:24:25PM +0800, Dongliang Mu wrote:
> > On Thu, Aug 12, 2021 at 6:05 PM Herbert Xu <herbert at gondor.apana.org.au> wrote:
> > >
> > > On Tue, Aug 03, 2021 at 02:31:38PM +0800, Dongliang Mu wrote:
> > > >
> > > > -theend:
> > > > -     kfree(buf);
> > > > +err_result:
> > > >       kfree(result);
> > > > -     crypto_finalize_hash_request(engine, breq, err);
> > > > +err_buf:
> > > > +     kfree(buf);
> > > > +out:
> > > > +     if (!err)
> > > > +             crypto_finalize_hash_request(engine, breq, err);
> > > >       return 0;
> > >
> > > This does not look right.  You're returning zero in case of an error
> >
> > Hi Herbert,
> >
> > Corentin Labbe said,
> >
> > For the error code, I am not sure it is needed, error code is already
> > given to user via crypto_finalize_hash_request().
>
> Yes but your patch changes this.  You're now skipping the finalize
> call and thus throwing away err if it's not zero.
>

I see. Thanks for your comment.

I agree with you and would like to modify "return 0" to "return err"
in the next version.  Even if the parent function does not care about
the return value, it is still necessary to keep the right return
value.

Corentin, how do you think?

> If it's supposed to do this you need to explain it in your patch
> submission.
>
> Cheers,
> --
> Email: Herbert Xu <herbert at gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From herbert at gondor.apana.org.au  Thu Aug 12 03:43:18 2021
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 12 Aug 2021 18:43:18 +0800
Subject: [PATCH v2] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <CAD-N9QU6r-yLBvJUpV+xy4pgOFnrtquBymthG7k5ddHt20APzg@mail.gmail.com>
References: <20210803063149.2821093-1-mudongliangabcd@gmail.com>
 <20210812100437.GA5055@gondor.apana.org.au>
 <CAD-N9QWGgBBddi5kwTNANKVVdWaQRwagMHvaH592B5GDALpBrg@mail.gmail.com>
 <20210812102954.GA5569@gondor.apana.org.au>
 <CAD-N9QU6r-yLBvJUpV+xy4pgOFnrtquBymthG7k5ddHt20APzg@mail.gmail.com>
Message-ID: <20210812104318.GA5780@gondor.apana.org.au>

On Thu, Aug 12, 2021 at 06:40:20PM +0800, Dongliang Mu wrote:
>
> I agree with you and would like to modify "return 0" to "return err"
> in the next version.  Even if the parent function does not care about
> the return value, it is still necessary to keep the right return
> value.

Well if the parent is ignoring the error then returning the error
there obviously isn't going to help.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From geert+renesas at glider.be  Thu Aug 12 04:24:13 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:13 +0200
Subject: [PATCH v2 23/29] arm64: dts: renesas: Add support for
 M3NULCB+Kingfisher with R-Car M3Ne-2G
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <0d2061798f9e86b3b24a7c8a54ea1e18f9199849.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Pro and Kingfisher combo
equipped with an R-Car M3Ne-2G SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 .../boot/dts/renesas/r8a779m5-ulcb-kf.dts     | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m5-ulcb-kf.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 9bee0eab5e2c2577..13446aecdfccb080 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -85,5 +85,6 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-ulcb.dtb
+dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m5-ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a779m5-ulcb-kf.dts
new file mode 100644
index 0000000000000000..79ccf581be1bf5ad
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m5-ulcb-kf.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the M3NULCB Kingfisher board with R-Car M3Ne-2G
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77965-ulcb-kf.dts
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+#include "r8a779m5-ulcb.dts"
+#include "ulcb-kf.dtsi"
+
+/ {
+	model = "Renesas M3NULCB Kingfisher board based on r8a779m5";
+	compatible = "shimafuji,kingfisher", "renesas,m3nulcb",
+		     "renesas,r8a779m5", "renesas,r8a77965";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:10 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:10 +0200
Subject: [PATCH v2 20/29] arm64: dts: renesas: Add support for
 M3NULCB+Kingfisher with R-Car M3Ne
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <ad0c91c52a913ec2c2311ae5c83f27cd4bf140ed.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Pro and Kingfisher combo
equipped with an R-Car M3Ne SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 .../boot/dts/renesas/r8a779m4-ulcb-kf.dts     | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m4-ulcb-kf.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 45a004035e216c14..2f82cb497ba66a86 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -81,5 +81,6 @@ dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-ulcb.dtb
+dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m4-ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a779m4-ulcb-kf.dts
new file mode 100644
index 0000000000000000..dd9d97bb2f4edcaf
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m4-ulcb-kf.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the M3NULCB Kingfisher board with R-Car M3Ne
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77965-ulcb-kf.dts
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+#include "r8a779m4-ulcb.dts"
+#include "ulcb-kf.dtsi"
+
+/ {
+	model = "Renesas M3NULCB Kingfisher board based on r8a779m4";
+	compatible = "shimafuji,kingfisher", "renesas,m3nulcb",
+		     "renesas,r8a779m4", "renesas,r8a77965";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:59 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:59 +0200
Subject: [PATCH v2 09/29] arm64: dts: renesas: Add Renesas R8A779M6 SoC support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <004e837531de4160ac4815fe7836b1f05d6fad85.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car E3e (R8A779M6) SoC, which is a
different grading of the R-Car E3 (R8A77990) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - No changes.
---
 arch/arm64/boot/dts/renesas/r8a779m6.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m6.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r8a779m6.dtsi b/arch/arm64/boot/dts/renesas/r8a779m6.dtsi
new file mode 100644
index 0000000000000000..afe3cabfb898c6e6
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m6.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the R-Car E3e (R8A779M6) SoC
+ *
+ * Copyright (C) 2021 Glider bv
+ */
+
+#include "r8a77990.dtsi"
+
+/ {
+	compatible = "renesas,r8a779m6", "renesas,r8a77990";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:08 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:08 +0200
Subject: [PATCH v2 18/29] arm64: dts: renesas: Add support for Salvator-XS
 with R-Car M3Ne
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <563a113a8180d7c4563cf5515a98879110886eb8.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas Salvator-X 2nd version development board
equipped with an R-Car M3Ne SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  2 ++
 .../boot/dts/renesas/r8a779m4-salvator-xs.dts | 36 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m4-salvator-xs.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index b55314feb8abdf98..2ab938d4b62c1317 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -79,4 +79,6 @@ dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb-kf.dtb
 
+dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-salvator-xs.dtb
+
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m4-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a779m4-salvator-xs.dts
new file mode 100644
index 0000000000000000..3a283b3ec116f9ca
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m4-salvator-xs.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the Salvator-X 2nd version board with R-Car M3Ne
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77965-salvator-xs.dts
+ * Copyright (C) 2017 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a779m4.dtsi"
+#include "salvator-xs.dtsi"
+
+/ {
+	model = "Renesas Salvator-X 2nd version board based on r8a779m4";
+	compatible = "renesas,salvator-xs", "renesas,r8a779m4",
+		     "renesas,r8a77965";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x78000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock6 1>,
+		 <&x21_clk>,
+		 <&versaclock6 2>;
+	clock-names = "du.0", "du.1", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.3";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:11 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:11 +0200
Subject: [PATCH v2 21/29] arm64: dts: renesas: Add support for Salvator-XS
 with R-Car M3Ne-2G
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <efced5c7ff71b0a0ae359be12112e0d4dfb21a72.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas Salvator-X 2nd version development board
equipped with an R-Car M3Ne-2G SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  2 ++
 .../boot/dts/renesas/r8a779m5-salvator-xs.dts | 36 +++++++++++++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m5-salvator-xs.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 2f82cb497ba66a86..5c47615525fc9203 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -83,4 +83,6 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-ulcb-kf.dtb
 
+dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs.dtb
+
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m5-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a779m5-salvator-xs.dts
new file mode 100644
index 0000000000000000..c0341a88d641c837
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m5-salvator-xs.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the Salvator-X 2nd version board with R-Car M3Ne-2G
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77965-salvator-xs.dts
+ * Copyright (C) 2017 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a779m5.dtsi"
+#include "salvator-xs.dtsi"
+
+/ {
+	model = "Renesas Salvator-X 2nd version board based on r8a779m5";
+	compatible = "renesas,salvator-xs", "renesas,r8a779m5",
+		     "renesas,r8a77965";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x78000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock6 1>,
+		 <&x21_clk>,
+		 <&versaclock6 2>;
+	clock-names = "du.0", "du.1", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.3";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:52 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:52 +0200
Subject: [PATCH v2 02/29] soc: renesas: Identify more R-Car Gen3e SoCs
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <ccf2206b24147b3d977e4119bbdefaedceb28644.1628766192.git.geert+renesas@glider.be>

Add support for identifying the remaining R-Car Gen3e SoCs: R-Car H3e
(R8A779M0), M3e (R8A779M2), M3Ne (R8A779M4), M3Ne-2G (R8A779M5), E3e
(R8A779M6), D3e (R8A779M7), and H3Ne (R8A779M8).

As these are different gradings of the already supported R-Car Gen3
SoCs, support for them is enabled through the existing ARCH_R8A779*
configuration symbols.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - Drop new soc_rcar_*3*e, just use the existing soc_rcar_*3*.
---
 drivers/soc/renesas/Kconfig       | 7 +++++--
 drivers/soc/renesas/renesas-soc.c | 7 +++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index a736b32555f21904..7f7c8f72d5f2b67a 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -191,6 +191,7 @@ config ARCH_R8A77995
 	select SYSC_R8A77995
 	help
 	  This enables support for the Renesas R-Car D3 SoC.
+	  This includes different gradings like R-Car D3e.
 
 config ARCH_R8A77990
 	bool "ARM64 Platform support for R-Car E3"
@@ -198,6 +199,7 @@ config ARCH_R8A77990
 	select SYSC_R8A77990
 	help
 	  This enables support for the Renesas R-Car E3 SoC.
+	  This includes different gradings like R-Car E3e.
 
 config ARCH_R8A77950
 	bool "ARM64 Platform support for R-Car H3 ES1.x"
@@ -213,7 +215,7 @@ config ARCH_R8A77951
 	help
 	  This enables support for the Renesas R-Car H3 SoC (revisions 2.0 and
 	  later).
-	  This includes different gradings like R-Car H3e-2G.
+	  This includes different gradings like R-Car H3e, H3e-2G, and H3Ne.
 
 config ARCH_R8A77965
 	bool "ARM64 Platform support for R-Car M3-N"
@@ -221,6 +223,7 @@ config ARCH_R8A77965
 	select SYSC_R8A77965
 	help
 	  This enables support for the Renesas R-Car M3-N SoC.
+	  This includes different gradings like R-Car M3Ne and M3Ne-2G.
 
 config ARCH_R8A77960
 	bool "ARM64 Platform support for R-Car M3-W"
@@ -235,7 +238,7 @@ config ARCH_R8A77961
 	select SYSC_R8A77961
 	help
 	  This enables support for the Renesas R-Car M3-W+ SoC.
-	  This includes different gradings like R-Car M3e-2G.
+	  This includes different gradings like R-Car M3e and M3e-2G.
 
 config ARCH_R8A77980
 	bool "ARM64 Platform support for R-Car V3H"
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
index dab9f5a0aad00233..7961b0be1850922d 100644
--- a/drivers/soc/renesas/renesas-soc.c
+++ b/drivers/soc/renesas/renesas-soc.c
@@ -285,17 +285,22 @@ static const struct of_device_id renesas_socs[] __initconst = {
 	{ .compatible = "renesas,r8a7795",	.data = &soc_rcar_h3 },
 #endif
 #ifdef CONFIG_ARCH_R8A77951
+	{ .compatible = "renesas,r8a779m0",	.data = &soc_rcar_h3 },
 	{ .compatible = "renesas,r8a779m1",	.data = &soc_rcar_h3 },
+	{ .compatible = "renesas,r8a779m8",	.data = &soc_rcar_h3 },
 #endif
 #ifdef CONFIG_ARCH_R8A77960
 	{ .compatible = "renesas,r8a7796",	.data = &soc_rcar_m3_w },
 #endif
 #ifdef CONFIG_ARCH_R8A77961
 	{ .compatible = "renesas,r8a77961",	.data = &soc_rcar_m3_w },
+	{ .compatible = "renesas,r8a779m2",	.data = &soc_rcar_m3_w },
 	{ .compatible = "renesas,r8a779m3",	.data = &soc_rcar_m3_w },
 #endif
 #ifdef CONFIG_ARCH_R8A77965
 	{ .compatible = "renesas,r8a77965",	.data = &soc_rcar_m3_n },
+	{ .compatible = "renesas,r8a779m4",	.data = &soc_rcar_m3_n },
+	{ .compatible = "renesas,r8a779m5",	.data = &soc_rcar_m3_n },
 #endif
 #ifdef CONFIG_ARCH_R8A77970
 	{ .compatible = "renesas,r8a77970",	.data = &soc_rcar_v3m },
@@ -305,9 +310,11 @@ static const struct of_device_id renesas_socs[] __initconst = {
 #endif
 #ifdef CONFIG_ARCH_R8A77990
 	{ .compatible = "renesas,r8a77990",	.data = &soc_rcar_e3 },
+	{ .compatible = "renesas,r8a779m6",	.data = &soc_rcar_e3 },
 #endif
 #ifdef CONFIG_ARCH_R8A77995
 	{ .compatible = "renesas,r8a77995",	.data = &soc_rcar_d3 },
+	{ .compatible = "renesas,r8a779m7",	.data = &soc_rcar_d3 },
 #endif
 #ifdef CONFIG_ARCH_R8A779A0
 	{ .compatible = "renesas,r8a779a0",	.data = &soc_rcar_v3u },
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:54 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:54 +0200
Subject: [PATCH v2 04/29] arm64: dts: renesas: Factor out Ebisu board support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <df275772dea0a4fa88d1bffa96ce048eaa7d5308.1628766192.git.geert+renesas@glider.be>

Move the common parts for the Renesas Ebisu board to ebisu.dtsi, to
avoid future duplication of board descriptions.

Change a reference in a comment from "r8a77990" to "R-Car E3(e)", to
prepare for the advent of "R-Car E3e".

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Replace "E3" by "E3(e)",
  - Add Reviewed-by,
  - Rebased.
---
 .../{r8a77990-ebisu.dts => ebisu.dtsi}        |  10 +-
 .../arm64/boot/dts/renesas/r8a77990-ebisu.dts | 788 +-----------------
 2 files changed, 5 insertions(+), 793 deletions(-)
 copy arch/arm64/boot/dts/renesas/{r8a77990-ebisu.dts => ebisu.dtsi} (98%)

diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/ebisu.dtsi
similarity index 98%
copy from arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
copy to arch/arm64/boot/dts/renesas/ebisu.dtsi
index 9c7146084ea1c779..54f88bb7e5920296 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
+++ b/arch/arm64/boot/dts/renesas/ebisu.dtsi
@@ -1,18 +1,16 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the Ebisu board with R-Car E3
+ * Device Tree Source for the Ebisu board
  *
  * Copyright (C) 2018 Renesas Electronics Corp.
  */
 
-/dts-v1/;
-#include "r8a77990.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 
 / {
-	model = "Renesas Ebisu board based on r8a77990";
-	compatible = "renesas,ebisu", "renesas,r8a77990";
+	model = "Renesas Ebisu board";
+	compatible = "renesas,ebisu";
 
 	aliases {
 		serial0 = &scif2;
@@ -313,7 +311,7 @@ phy0: ethernet-phy at 0 {
 		 * TX clock internal delay mode is required for reliable
 		 * 1Gbps communication using the KSZ9031RNX phy present on
 		 * the Ebisu board, however, TX clock internal delay mode
-		 * isn't supported on r8a77990.  Thus, limit speed to
+		 * isn't supported on R-Car E3(e).  Thus, limit speed to
 		 * 100Mbps for reliable communication.
 		 */
 		max-speed = <100>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
index 9c7146084ea1c779..9da0fd08f8c46b35 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
@@ -7,795 +7,9 @@
 
 /dts-v1/;
 #include "r8a77990.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
+#include "ebisu.dtsi"
 
 / {
 	model = "Renesas Ebisu board based on r8a77990";
 	compatible = "renesas,ebisu", "renesas,r8a77990";
-
-	aliases {
-		serial0 = &scif2;
-		ethernet0 = &avb;
-		mmc0 = &sdhi3;
-		mmc1 = &sdhi0;
-		mmc2 = &sdhi1;
-	};
-
-	chosen {
-		bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
-		stdout-path = "serial0:115200n8";
-	};
-
-	audio_clkout: audio-clkout {
-		/*
-		 * This is same as <&rcar_sound 0>
-		 * but needed to avoid cs2000/rcar_sound probe dead-lock
-		 */
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <11289600>;
-	};
-
-	backlight: backlight {
-		compatible = "pwm-backlight";
-		pwms = <&pwm3 0 50000>;
-
-		brightness-levels = <512 511 505 494 473 440 392 327 241 133 0>;
-		default-brightness-level = <10>;
-
-		power-supply = <&reg_12p0v>;
-	};
-
-	cvbs-in {
-		compatible = "composite-video-connector";
-		label = "CVBS IN";
-
-		port {
-			cvbs_con: endpoint {
-				remote-endpoint = <&adv7482_ain7>;
-			};
-		};
-	};
-
-	hdmi-in {
-		compatible = "hdmi-connector";
-		label = "HDMI IN";
-		type = "a";
-
-		port {
-			hdmi_in_con: endpoint {
-				remote-endpoint = <&adv7482_hdmi>;
-			};
-		};
-	};
-
-	hdmi-out {
-		compatible = "hdmi-connector";
-		type = "a";
-
-		port {
-			hdmi_con_out: endpoint {
-				remote-endpoint = <&adv7511_out>;
-			};
-		};
-	};
-
-	keys {
-		compatible = "gpio-keys";
-
-		pinctrl-0 = <&keys_pins>;
-		pinctrl-names = "default";
-
-		key-1 {
-			gpios = <&gpio5 10 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_1>;
-			label = "SW4-1";
-			wakeup-source;
-			debounce-interval = <20>;
-		};
-		key-2 {
-			gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_2>;
-			label = "SW4-2";
-			wakeup-source;
-			debounce-interval = <20>;
-		};
-		key-3 {
-			gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_3>;
-			label = "SW4-3";
-			wakeup-source;
-			debounce-interval = <20>;
-		};
-		key-4 {
-			gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_4>;
-			label = "SW4-4";
-			wakeup-source;
-			debounce-interval = <20>;
-		};
-	};
-
-	lvds-decoder {
-		compatible = "thine,thc63lvd1024";
-		vcc-supply = <&reg_3p3v>;
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				reg = <0>;
-				thc63lvd1024_in: endpoint {
-					remote-endpoint = <&lvds0_out>;
-				};
-			};
-
-			port at 2 {
-				reg = <2>;
-				thc63lvd1024_out: endpoint {
-					remote-endpoint = <&adv7511_in>;
-				};
-			};
-		};
-	};
-
-	memory at 48000000 {
-		device_type = "memory";
-		/* first 128MB is reserved for secure area. */
-		reg = <0x0 0x48000000 0x0 0x38000000>;
-	};
-
-	reg_1p8v: regulator0 {
-		compatible = "regulator-fixed";
-		regulator-name = "fixed-1.8V";
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-
-	reg_3p3v: regulator1 {
-		compatible = "regulator-fixed";
-		regulator-name = "fixed-3.3V";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-
-	reg_12p0v: regulator2 {
-		compatible = "regulator-fixed";
-		regulator-name = "D12.0V";
-		regulator-min-microvolt = <12000000>;
-		regulator-max-microvolt = <12000000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-
-	rsnd_ak4613: sound {
-		compatible = "simple-audio-card";
-
-		simple-audio-card,name = "rsnd-ak4613";
-		simple-audio-card,format = "left_j";
-		simple-audio-card,bitclock-master = <&sndcpu>;
-		simple-audio-card,frame-master = <&sndcpu>;
-
-		sndcodec: simple-audio-card,codec {
-			sound-dai = <&ak4613>;
-		};
-
-		sndcpu: simple-audio-card,cpu {
-			sound-dai = <&rcar_sound>;
-		};
-	};
-
-	vbus0_usb2: regulator-vbus0-usb2 {
-		compatible = "regulator-fixed";
-
-		regulator-name = "USB20_VBUS_CN";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-
-		gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	vcc_sdhi0: regulator-vcc-sdhi0 {
-		compatible = "regulator-fixed";
-
-		regulator-name = "SDHI0 Vcc";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-
-		gpio = <&gpio5 17 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	vccq_sdhi0: regulator-vccq-sdhi0 {
-		compatible = "regulator-gpio";
-
-		regulator-name = "SDHI0 VccQ";
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <3300000>;
-
-		gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
-		gpios-states = <1>;
-		states = <3300000 1>, <1800000 0>;
-	};
-
-	vcc_sdhi1: regulator-vcc-sdhi1 {
-		compatible = "regulator-fixed";
-
-		regulator-name = "SDHI1 Vcc";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-
-		gpio = <&gpio0 4 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
-
-	vccq_sdhi1: regulator-vccq-sdhi1 {
-		compatible = "regulator-gpio";
-
-		regulator-name = "SDHI1 VccQ";
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <3300000>;
-
-		gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
-		gpios-states = <1>;
-		states = <3300000 1>, <1800000 0>;
-	};
-
-	vga {
-		compatible = "vga-connector";
-
-		port {
-			vga_in: endpoint {
-				remote-endpoint = <&adv7123_out>;
-			};
-		};
-	};
-
-	vga-encoder {
-		compatible = "adi,adv7123";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				reg = <0>;
-				adv7123_in: endpoint {
-					remote-endpoint = <&du_out_rgb>;
-				};
-			};
-			port at 1 {
-				reg = <1>;
-				adv7123_out: endpoint {
-					remote-endpoint = <&vga_in>;
-				};
-			};
-		};
-	};
-
-	x12_clk: x12 {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <24576000>;
-	};
-
-	x13_clk: x13 {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <74250000>;
-	};
-};
-
-&audio_clk_a {
-	clock-frequency = <22579200>;
-};
-
-&avb {
-	pinctrl-0 = <&avb_pins>;
-	pinctrl-names = "default";
-	phy-handle = <&phy0>;
-	status = "okay";
-
-	phy0: ethernet-phy at 0 {
-		rxc-skew-ps = <1500>;
-		reg = <0>;
-		interrupt-parent = <&gpio2>;
-		interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
-		reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
-		/*
-		 * TX clock internal delay mode is required for reliable
-		 * 1Gbps communication using the KSZ9031RNX phy present on
-		 * the Ebisu board, however, TX clock internal delay mode
-		 * isn't supported on r8a77990.  Thus, limit speed to
-		 * 100Mbps for reliable communication.
-		 */
-		max-speed = <100>;
-	};
-};
-
-&canfd {
-	pinctrl-0 = <&canfd0_pins>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	channel0 {
-		status = "okay";
-	};
-};
-
-&csi40 {
-	status = "okay";
-
-	ports {
-		port at 0 {
-			csi40_in: endpoint {
-				clock-lanes = <0>;
-				data-lanes = <1 2>;
-				remote-endpoint = <&adv7482_txa>;
-			};
-		};
-	};
-};
-
-&du {
-	pinctrl-0 = <&du_pins>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	clocks = <&cpg CPG_MOD 724>,
-		 <&cpg CPG_MOD 723>,
-		 <&x13_clk>;
-	clock-names = "du.0", "du.1", "dclkin.0";
-
-	ports {
-		port at 0 {
-			endpoint {
-				remote-endpoint = <&adv7123_in>;
-			};
-		};
-	};
-};
-
-&ehci0 {
-	dr_mode = "otg";
-	status = "okay";
-};
-
-&extal_clk {
-	clock-frequency = <48000000>;
-};
-
-&hsusb {
-	dr_mode = "otg";
-	status = "okay";
-};
-
-&i2c0 {
-	status = "okay";
-
-	io_expander: gpio at 20 {
-		compatible = "onnn,pca9654";
-		reg = <0x20>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		interrupt-parent = <&gpio2>;
-		interrupts = <22 IRQ_TYPE_LEVEL_LOW>;
-	};
-
-	hdmi-encoder at 39 {
-		compatible = "adi,adv7511w";
-		reg = <0x39>;
-		interrupt-parent = <&gpio1>;
-		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
-
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				reg = <0>;
-				adv7511_in: endpoint {
-					remote-endpoint = <&thc63lvd1024_out>;
-				};
-			};
-
-			port at 1 {
-				reg = <1>;
-				adv7511_out: endpoint {
-					remote-endpoint = <&hdmi_con_out>;
-				};
-			};
-		};
-	};
-
-	video-receiver at 70 {
-		compatible = "adi,adv7482";
-		reg = <0x70>;
-
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		interrupt-parent = <&gpio0>;
-		interrupt-names = "intrq1", "intrq2";
-		interrupts = <7 IRQ_TYPE_LEVEL_LOW>,
-			     <17 IRQ_TYPE_LEVEL_LOW>;
-
-		port at 7 {
-			reg = <7>;
-
-			adv7482_ain7: endpoint {
-				remote-endpoint = <&cvbs_con>;
-			};
-		};
-
-		port at 8 {
-			reg = <8>;
-
-			adv7482_hdmi: endpoint {
-				remote-endpoint = <&hdmi_in_con>;
-			};
-		};
-
-		port at a {
-			reg = <10>;
-
-			adv7482_txa: endpoint {
-				clock-lanes = <0>;
-				data-lanes = <1 2>;
-				remote-endpoint = <&csi40_in>;
-			};
-		};
-	};
-};
-
-&i2c3 {
-	status = "okay";
-
-	ak4613: codec at 10 {
-		compatible = "asahi-kasei,ak4613";
-		#sound-dai-cells = <0>;
-		reg = <0x10>;
-		clocks = <&rcar_sound 3>;
-
-		asahi-kasei,in1-single-end;
-		asahi-kasei,in2-single-end;
-		asahi-kasei,out1-single-end;
-		asahi-kasei,out2-single-end;
-		asahi-kasei,out3-single-end;
-		asahi-kasei,out4-single-end;
-		asahi-kasei,out5-single-end;
-		asahi-kasei,out6-single-end;
-	};
-
-	cs2000: clk-multiplier at 4f {
-		#clock-cells = <0>;
-		compatible = "cirrus,cs2000-cp";
-		reg = <0x4f>;
-		clocks = <&audio_clkout>, <&x12_clk>;
-		clock-names = "clk_in", "ref_clk";
-
-		assigned-clocks = <&cs2000>;
-		assigned-clock-rates = <24576000>; /* 1/1 divide */
-	};
-};
-
-&i2c_dvfs {
-	status = "okay";
-
-	clock-frequency = <400000>;
-
-	pmic: pmic at 30 {
-		pinctrl-0 = <&irq0_pins>;
-		pinctrl-names = "default";
-
-		compatible = "rohm,bd9571mwv";
-		reg = <0x30>;
-		interrupt-parent = <&intc_ex>;
-		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		rohm,ddr-backup-power = <0x1>;
-		rohm,rstbmode-level;
-	};
-
-	eeprom at 50 {
-		compatible = "rohm,br24t01", "atmel,24c01";
-		reg = <0x50>;
-		pagesize = <8>;
-	};
-};
-
-&lvds0 {
-	status = "okay";
-
-	clocks = <&cpg CPG_MOD 727>,
-		 <&x13_clk>,
-		 <&extal_clk>;
-	clock-names = "fck", "dclkin.0", "extal";
-
-	ports {
-		port at 1 {
-			lvds0_out: endpoint {
-				remote-endpoint = <&thc63lvd1024_in>;
-			};
-		};
-	};
-};
-
-&lvds1 {
-	/*
-	 * Even though the LVDS1 output is not connected, the encoder must be
-	 * enabled to supply a pixel clock to the DU for the DPAD output when
-	 * LVDS0 is in use.
-	 */
-	status = "okay";
-
-	clocks = <&cpg CPG_MOD 727>,
-		 <&x13_clk>,
-		 <&extal_clk>;
-	clock-names = "fck", "dclkin.0", "extal";
-};
-
-&ohci0 {
-	dr_mode = "otg";
-	status = "okay";
-};
-
-&pcie_bus_clk {
-	clock-frequency = <100000000>;
-};
-
-&pciec0 {
-	status = "okay";
-};
-
-&pfc {
-	avb_pins: avb {
-		groups = "avb_link", "avb_mii";
-		function = "avb";
-	};
-
-	canfd0_pins: canfd0 {
-		groups = "canfd0_data";
-		function = "canfd0";
-	};
-
-	du_pins: du {
-		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
-		function = "du";
-	};
-
-	irq0_pins: irq0 {
-		groups = "intc_ex_irq0";
-		function = "intc_ex";
-	};
-
-	keys_pins: keys {
-		pins = "GP_5_10", "GP_5_11", "GP_5_12", "GP_5_13";
-		bias-pull-up;
-	};
-
-	pwm3_pins: pwm3 {
-		groups = "pwm3_b";
-		function = "pwm3";
-	};
-
-	pwm5_pins: pwm5 {
-		groups = "pwm5_a";
-		function = "pwm5";
-	};
-
-	scif2_pins: scif2 {
-		groups = "scif2_data_a";
-		function = "scif2";
-	};
-
-	sdhi0_pins: sd0 {
-		groups = "sdhi0_data4", "sdhi0_ctrl";
-		function = "sdhi0";
-		power-source = <3300>;
-	};
-
-	sdhi0_pins_uhs: sd0_uhs {
-		groups = "sdhi0_data4", "sdhi0_ctrl";
-		function = "sdhi0";
-		power-source = <1800>;
-	};
-
-	sdhi1_pins: sd1 {
-		groups = "sdhi1_data4", "sdhi1_ctrl";
-		function = "sdhi1";
-		power-source = <3300>;
-	};
-
-	sdhi1_pins_uhs: sd1_uhs {
-		groups = "sdhi1_data4", "sdhi1_ctrl";
-		function = "sdhi1";
-		power-source = <1800>;
-	};
-
-	sdhi3_pins: sd3 {
-		groups = "sdhi3_data8", "sdhi3_ctrl", "sdhi3_ds";
-		function = "sdhi3";
-		power-source = <1800>;
-	};
-
-	sound_clk_pins: sound_clk {
-		groups = "audio_clk_a", "audio_clk_b_a", "audio_clk_c_a",
-			 "audio_clkout_a", "audio_clkout1_a";
-		function = "audio_clk";
-	};
-
-	sound_pins: sound {
-		groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data";
-		function = "ssi";
-	};
-
-	usb0_pins: usb {
-		groups = "usb0_b", "usb0_id";
-		function = "usb0";
-	};
-
-	usb30_pins: usb30 {
-		groups = "usb30";
-		function = "usb30";
-	};
-};
-
-&pwm3 {
-	pinctrl-0 = <&pwm3_pins>;
-	pinctrl-names = "default";
-
-	status = "okay";
-};
-
-&pwm5 {
-	pinctrl-0 = <&pwm5_pins>;
-	pinctrl-names = "default";
-
-	status = "okay";
-};
-
-&rcar_sound {
-	pinctrl-0 = <&sound_pins>, <&sound_clk_pins>;
-	pinctrl-names = "default";
-
-	/* Single DAI */
-	#sound-dai-cells = <0>;
-
-	/* audio_clkout0/1/2/3 */
-	#clock-cells = <1>;
-	clock-frequency = <12288000 11289600>;
-
-	status = "okay";
-
-	/* update <audio_clk_b> to <cs2000> */
-	clocks = <&cpg CPG_MOD 1005>,
-		 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>,
-		 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>,
-		 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>,
-		 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>,
-		 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>,
-		 <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>,
-		 <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>,
-		 <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>,
-		 <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>,
-		 <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>,
-		 <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
-		 <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
-		 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
-		 <&audio_clk_a>, <&cs2000>, <&audio_clk_c>,
-		 <&cpg CPG_CORE R8A77990_CLK_ZA2>;
-
-	rcar_sound,dai {
-		dai0 {
-			playback = <&ssi0>, <&src0>, <&dvc0>;
-			capture  = <&ssi1>, <&src1>, <&dvc1>;
-		};
-	};
-
-};
-
-&rwdt {
-	timeout-sec = <60>;
-	status = "okay";
-};
-
-&scif2 {
-	pinctrl-0 = <&scif2_pins>;
-	pinctrl-names = "default";
-
-	status = "okay";
-};
-
-&sdhi0 {
-	pinctrl-0 = <&sdhi0_pins>;
-	pinctrl-1 = <&sdhi0_pins_uhs>;
-	pinctrl-names = "default", "state_uhs";
-
-	vmmc-supply = <&vcc_sdhi0>;
-	vqmmc-supply = <&vccq_sdhi0>;
-	cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
-	wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
-	bus-width = <4>;
-	sd-uhs-sdr50;
-	sd-uhs-sdr104;
-	status = "okay";
-};
-
-&sdhi1 {
-	pinctrl-0 = <&sdhi1_pins>;
-	pinctrl-1 = <&sdhi1_pins_uhs>;
-	pinctrl-names = "default", "state_uhs";
-
-	vmmc-supply = <&vcc_sdhi1>;
-	vqmmc-supply = <&vccq_sdhi1>;
-	cd-gpios = <&gpio3 14 GPIO_ACTIVE_LOW>;
-	bus-width = <4>;
-	sd-uhs-sdr50;
-	sd-uhs-sdr104;
-	status = "okay";
-};
-
-&sdhi3 {
-	/* used for on-board 8bit eMMC */
-	pinctrl-0 = <&sdhi3_pins>;
-	pinctrl-1 = <&sdhi3_pins>;
-	pinctrl-names = "default", "state_uhs";
-
-	vmmc-supply = <&reg_3p3v>;
-	vqmmc-supply = <&reg_1p8v>;
-	mmc-hs200-1_8v;
-	mmc-hs400-1_8v;
-	bus-width = <8>;
-	no-sd;
-	no-sdio;
-	non-removable;
-	full-pwr-cycle-in-suspend;
-	status = "okay";
-};
-
-&ssi1 {
-	shared-pin;
-};
-
-&usb2_phy0 {
-	pinctrl-0 = <&usb0_pins>;
-	pinctrl-names = "default";
-
-	vbus-supply = <&vbus0_usb2>;
-	status = "okay";
-};
-
-&usb3_peri0 {
-	companion = <&xhci0>;
-	status = "okay";
-};
-
-&vin4 {
-	status = "okay";
-};
-
-&vin5 {
-	status = "okay";
-};
-
-&xhci0 {
-	pinctrl-0 = <&usb30_pins>;
-	pinctrl-names = "default";
-
-	status = "okay";
 };
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:03 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:03 +0200
Subject: [PATCH v2 13/29] arm64: dts: renesas: Add support for H3ULCB with
 R-Car H3e
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <edf398660fca5668f48df0ed59fa83b2f7bb22a6.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Premier equipped with an
R-Car H3e SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 arch/arm64/boot/dts/renesas/r8a779m0-ulcb.dts | 53 +++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m0-ulcb.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 69bdf8e92a459f1f..a18f9b9d2a335c78 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -64,6 +64,7 @@ dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb
 dtb-$(CONFIG_ARCH_R8A779A0) += r8a779a0-falcon.dtb
 
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m0-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77951) += r8a779m0-ulcb.dtb
 
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m0-ulcb.dts b/arch/arm64/boot/dts/renesas/r8a779m0-ulcb.dts
new file mode 100644
index 0000000000000000..57ae7866582f9a41
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m0-ulcb.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the H3ULCB (R-Car Starter Kit Premier) with R-Car H3e
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77951-ulcb.dts
+ * Copyright (C) 2016 Renesas Electronics Corp.
+ * Copyright (C) 2016 Cogent Embedded, Inc.
+ */
+
+/dts-v1/;
+#include "r8a779m0.dtsi"
+#include "ulcb.dtsi"
+
+/ {
+	model = "Renesas H3ULCB board based on r8a779m0";
+	compatible = "renesas,h3ulcb", "renesas,r8a779m0", "renesas,r8a7795";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x38000000>;
+	};
+
+	memory at 500000000 {
+		device_type = "memory";
+		reg = <0x5 0x00000000 0x0 0x40000000>;
+	};
+
+	memory at 600000000 {
+		device_type = "memory";
+		reg = <0x6 0x00000000 0x0 0x40000000>;
+	};
+
+	memory at 700000000 {
+		device_type = "memory";
+		reg = <0x7 0x00000000 0x0 0x40000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 722>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock5 1>,
+		 <&versaclock5 3>,
+		 <&versaclock5 4>,
+		 <&versaclock5 2>;
+	clock-names = "du.0", "du.1", "du.2", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:12 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:12 +0200
Subject: [PATCH v2 22/29] arm64: dts: renesas: Add support for M3NULCB with
 R-Car M3Ne-2G
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <8e4974f3440ca8f07de6f31c9ed4158baa67c0c3.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Pro equipped with an R-Car
M3Ne-2 SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 arch/arm64/boot/dts/renesas/r8a779m5-ulcb.dts | 36 +++++++++++++++++++
 2 files changed, 37 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m5-ulcb.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 5c47615525fc9203..9bee0eab5e2c2577 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -84,5 +84,6 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-ulcb.dtb
 
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m5-ulcb.dts b/arch/arm64/boot/dts/renesas/r8a779m5-ulcb.dts
new file mode 100644
index 0000000000000000..17242ec02a65ad93
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m5-ulcb.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the M3NULCB (R-Car Starter Kit Pro) with R-Car M3Ne-2G
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77965-ulcb.dts
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+/dts-v1/;
+#include "r8a779m5.dtsi"
+#include "ulcb.dtsi"
+
+/ {
+	model = "Renesas M3NULCB board based on r8a779m5";
+	compatible = "renesas,m3nulcb", "renesas,r8a779m5", "renesas,r8a77965";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x78000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock5 1>,
+		 <&versaclock5 3>,
+		 <&versaclock5 2>;
+	clock-names = "du.0", "du.1", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.3";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:05 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:05 +0200
Subject: [PATCH v2 15/29] arm64: dts: renesas: Add support for Salvator-XS
 with R-Car M3e
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <92fe53005a154972c7556b21622912576b48e520.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas Salvator-X 2nd version development
board equipped with an R-Car M3e SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  2 +
 .../boot/dts/renesas/r8a779m2-salvator-xs.dts | 46 +++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m2-salvator-xs.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 5b31402f8579b19b..2c542b2f1c9fe092 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -71,6 +71,8 @@ dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb-kf.dtb
 
+dtb-$(CONFIG_ARCH_R8A77961) += r8a779m2-salvator-xs.dtb
+
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb-kf.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m2-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a779m2-salvator-xs.dts
new file mode 100644
index 0000000000000000..27b114efef9d417d
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m2-salvator-xs.dts
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the Salvator-X 2nd version board with R-Car M3e
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77961-salvator-xs.dts
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a779m2.dtsi"
+#include "salvator-xs.dtsi"
+
+/ {
+	model = "Renesas Salvator-X 2nd version board based on r8a779m2";
+	compatible = "renesas,salvator-xs", "renesas,r8a779m2",
+		     "renesas,r8a77961";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x78000000>;
+	};
+
+	memory at 480000000 {
+		device_type = "memory";
+		reg = <0x4 0x80000000 0x0 0x80000000>;
+	};
+
+	memory at 600000000 {
+		device_type = "memory";
+		reg = <0x6 0x00000000 0x1 0x00000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 722>,
+		 <&versaclock6 1>,
+		 <&x21_clk>,
+		 <&versaclock6 2>;
+	clock-names = "du.0", "du.1", "du.2",
+		      "dclkin.0", "dclkin.1", "dclkin.2";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:50 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:50 +0200
Subject: [PATCH v2 00/29] arm64: renesas: Add support for more R-Car Gen3e
 SoCs and boards
Message-ID: <cover.1628766192.git.geert+renesas@glider.be>

	Hi all,

The new R-Car Gen3e SoCs are different gradings of the existing R-Car
Gen3 SoCs.  This patch series adds support for the remaining R-Car Gen3e
SoCs.

Changes compared to v1 (not posted publicly):
  - Drop "mmc: renesas_sdhi: Add support for more R-Car Gen3e SoCs"
    (obsoleted by "[PATCH v4] mmc: host: renesas_sdhi: Refactor
    renesas_sdhi_probe()"[1]),
  - Drop "ravb: Add support for R-Car E3e and D3e" (not needed as the
    affected code is meant for legacy DTBs only),
  - Drop "usb: gadget: udc: renesas_usb3: Add support for R-Car E3e"
    (obsoleted by "[PATCH] usb: gadget: udc: renesas_usb3: Fix
    soc_device_match() abuse"[2]),
  - Typo s/R8A779M/R8A779M0/,
  - Add Reviewed-by,
  - Drop new soc_rcar_*3*e, just use the existing soc_rcar_*3*.
  - Drop bogus "based" in model name,
  - Replace "D3" by "D3(e)", and "E3" by "E3(e)".

This has been tested on Salvator-XS with R-Car H3 ES2.0 and M3-N ES1.0,
Salvator-X with R-Car M3-W ES1.0, Ebisu-4D with R-Car E3 ES1.0, and
Draak with R-Car D3 ES1.0.

For testing, a branch with dependencies and fixups for prototyping R-Car
Gen3e development on older Gen3 SoCs can be found at[3].

Thanks for your comments!

[1] https://lore.kernel.org/r/20210729103234.480743-1-yoshihiro.shimoda.uh at renesas.com
[2] https://lore.kernel.org/r/760981fb4cd110d7cbfc9dcffa365e7c8b25c6e5.1628696960.git.geert+renesas at glider.be
[3] https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/log/?h=topic/rcar-gen3e-extra-v2

Geert Uytterhoeven (29):
  dt-bindings: arm: renesas: Document more R-Car Gen3e Socs and boards
  soc: renesas: Identify more R-Car Gen3e SoCs
  arm64: dts: renesas: Factor out Draak board support
  arm64: dts: renesas: Factor out Ebisu board support
  arm64: dts: renesas: Add Renesas R8A779M0 SoC support
  arm64: dts: renesas: Add Renesas R8A779M2 SoC support
  arm64: dts: renesas: Add Renesas R8A779M4 SoC support
  arm64: dts: renesas: Add Renesas R8A779M5 SoC support
  arm64: dts: renesas: Add Renesas R8A779M6 SoC support
  arm64: dts: renesas: Add Renesas R8A779M7 SoC support
  arm64: dts: renesas: Add Renesas R8A779M8 SoC support
  arm64: dts: renesas: Add support for Salvator-XS with R-Car H3e
  arm64: dts: renesas: Add support for H3ULCB with R-Car H3e
  arm64: dts: renesas: Add support for H3ULCB+Kingfisher with R-Car H3e
  arm64: dts: renesas: Add support for Salvator-XS with R-Car M3e
  arm64: dts: renesas: Add support for M3ULCB with R-Car M3e
  arm64: dts: renesas: Add support for M3ULCB+Kingfisher with R-Car M3e
  arm64: dts: renesas: Add support for Salvator-XS with R-Car M3Ne
  arm64: dts: renesas: Add support for M3NULCB with R-Car M3Ne
  arm64: dts: renesas: Add support for M3NULCB+Kingfisher with R-Car
    M3Ne
  arm64: dts: renesas: Add support for Salvator-XS with R-Car M3Ne-2G
  arm64: dts: renesas: Add support for M3NULCB with R-Car M3Ne-2G
  arm64: dts: renesas: Add support for M3NULCB+Kingfisher with R-Car
    M3Ne-2G
  arm64: dts: renesas: Add support for Ebisu with R-Car E3e
  arm64: dts: renesas: Add support for Draak with R-Car D3e
  arm64: dts: renesas: Add support for Salvator-XS with R-Car H3Ne
  arm64: dts: renesas: Add support for H3ULCB with R-Car H3Ne
  arm64: dts: renesas: Add support for H3ULCB+Kingfisher with R-Car H3Ne
  [RFC] arm64: dts: renesas: r8a779m5: Add Cortex-A57 2 GHz opp

 .../devicetree/bindings/arm/renesas.yaml      |  61 ++
 arch/arm64/boot/dts/renesas/Makefile          |  24 +
 .../{r8a77995-draak.dts => draak.dtsi}        |  10 +-
 .../{r8a77990-ebisu.dts => ebisu.dtsi}        |  10 +-
 .../arm64/boot/dts/renesas/r8a77990-ebisu.dts | 788 +-----------------
 .../arm64/boot/dts/renesas/r8a77995-draak.dts | 671 +--------------
 .../boot/dts/renesas/r8a779m0-salvator-xs.dts |  53 ++
 .../boot/dts/renesas/r8a779m0-ulcb-kf.dts     |  19 +
 arch/arm64/boot/dts/renesas/r8a779m0-ulcb.dts |  53 ++
 arch/arm64/boot/dts/renesas/r8a779m0.dtsi     |  12 +
 .../boot/dts/renesas/r8a779m2-salvator-xs.dts |  46 +
 .../boot/dts/renesas/r8a779m2-ulcb-kf.dts     |  18 +
 arch/arm64/boot/dts/renesas/r8a779m2-ulcb.dts |  45 +
 arch/arm64/boot/dts/renesas/r8a779m2.dtsi     |  12 +
 .../boot/dts/renesas/r8a779m4-salvator-xs.dts |  36 +
 .../boot/dts/renesas/r8a779m4-ulcb-kf.dts     |  19 +
 arch/arm64/boot/dts/renesas/r8a779m4-ulcb.dts |  36 +
 arch/arm64/boot/dts/renesas/r8a779m4.dtsi     |  12 +
 .../boot/dts/renesas/r8a779m5-salvator-xs.dts |  36 +
 .../boot/dts/renesas/r8a779m5-ulcb-kf.dts     |  19 +
 arch/arm64/boot/dts/renesas/r8a779m5-ulcb.dts |  36 +
 arch/arm64/boot/dts/renesas/r8a779m5.dtsi     |  21 +
 .../arm64/boot/dts/renesas/r8a779m6-ebisu.dts |  18 +
 arch/arm64/boot/dts/renesas/r8a779m6.dtsi     |  12 +
 .../arm64/boot/dts/renesas/r8a779m7-draak.dts |  19 +
 arch/arm64/boot/dts/renesas/r8a779m7.dtsi     |  12 +
 .../boot/dts/renesas/r8a779m8-salvator-xs.dts |  53 ++
 .../boot/dts/renesas/r8a779m8-ulcb-kf.dts     |  19 +
 arch/arm64/boot/dts/renesas/r8a779m8-ulcb.dts |  52 ++
 arch/arm64/boot/dts/renesas/r8a779m8.dtsi     |  12 +
 drivers/soc/renesas/Kconfig                   |   7 +-
 drivers/soc/renesas/renesas-soc.c             |   7 +
 32 files changed, 777 insertions(+), 1471 deletions(-)
 copy arch/arm64/boot/dts/renesas/{r8a77995-draak.dts => draak.dtsi} (97%)
 copy arch/arm64/boot/dts/renesas/{r8a77990-ebisu.dts => ebisu.dtsi} (98%)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m0-salvator-xs.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m0-ulcb-kf.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m0-ulcb.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m0.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m2-salvator-xs.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m2-ulcb-kf.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m2-ulcb.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m2.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m4-salvator-xs.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m4-ulcb-kf.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m4-ulcb.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m4.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m5-salvator-xs.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m5-ulcb-kf.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m5-ulcb.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m5.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m6-ebisu.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m6.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m7-draak.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m7.dtsi
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m8-salvator-xs.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m8-ulcb-kf.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m8-ulcb.dts
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m8.dtsi

-- 
2.25.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


From geert+renesas at glider.be  Thu Aug 12 04:24:07 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:07 +0200
Subject: [PATCH v2 17/29] arm64: dts: renesas: Add support for
 M3ULCB+Kingfisher with R-Car M3e
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <ee0caf7946b2bef7ba6efb77cd43c2f7f2cb3afc.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Pro and Kingfisher combo
equipped with an R-Car M3e SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile           |  1 +
 .../boot/dts/renesas/r8a779m2-ulcb-kf.dts      | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m2-ulcb-kf.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index eb744f7876751699..b55314feb8abdf98 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -73,6 +73,7 @@ dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m2-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m2-ulcb.dtb
+dtb-$(CONFIG_ARCH_R8A77961) += r8a779m2-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m2-ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a779m2-ulcb-kf.dts
new file mode 100644
index 0000000000000000..27c642553860fdf8
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m2-ulcb-kf.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the M3ULCB Kingfisher board with R-Car M3e
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77961-ulcb-kf.dts
+ * Copyright (C) 2020 Eugeniu Rosca <rosca.eugeniu at gmail.com>
+ */
+
+#include "r8a779m2-ulcb.dts"
+#include "ulcb-kf.dtsi"
+
+/ {
+	model = "Renesas M3ULCB Kingfisher board based on r8a779m2";
+	compatible = "shimafuji,kingfisher", "renesas,m3ulcb",
+		     "renesas,r8a779m2", "renesas,r8a77961";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:00 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:00 +0200
Subject: [PATCH v2 10/29] arm64: dts: renesas: Add Renesas R8A779M7 SoC support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <2aa5b34d5b50f757092bc6442bb59a8534f2ff24.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car D3e (R8A779M7) SoC, which is a
different grading of the R-Car D3 (R8A77995) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - No changes.
---
 arch/arm64/boot/dts/renesas/r8a779m7.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m7.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r8a779m7.dtsi b/arch/arm64/boot/dts/renesas/r8a779m7.dtsi
new file mode 100644
index 0000000000000000..4958babc52fd81ea
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m7.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the R-Car D3e (R8A779M7) SoC
+ *
+ * Copyright (C) 2021 Glider bv
+ */
+
+#include "r8a77995.dtsi"
+
+/ {
+	compatible = "renesas,r8a779m7", "renesas,r8a77995";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:01 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:01 +0200
Subject: [PATCH v2 11/29] arm64: dts: renesas: Add Renesas R8A779M8 SoC support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <99ff5658889e22ea8e723733e6972c27370930bf.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car H3Ne (R8A779M8) SoC, which is a
different grading of the R-Car H3-N (R8A77951) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - No changes.
---
 arch/arm64/boot/dts/renesas/r8a779m8.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m8.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r8a779m8.dtsi b/arch/arm64/boot/dts/renesas/r8a779m8.dtsi
new file mode 100644
index 0000000000000000..752440b0c40f7c22
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m8.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the R-Car H3Ne (R8A779M8) SoC
+ *
+ * Copyright (C) 2021 Glider bv
+ */
+
+#include "r8a77951.dtsi"
+
+/ {
+	compatible = "renesas,r8a779m8", "renesas,r8a7795";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:04 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:04 +0200
Subject: [PATCH v2 14/29] arm64: dts: renesas: Add support for
 H3ULCB+Kingfisher with R-Car H3e
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <a21065484ebcb72c1a8684b63c39784201d3c74d.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Premier and Kingfisher
combo equipped with an R-Car H3e SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 .../boot/dts/renesas/r8a779m0-ulcb-kf.dts     | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m0-ulcb-kf.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index a18f9b9d2a335c78..5b31402f8579b19b 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -65,6 +65,7 @@ dtb-$(CONFIG_ARCH_R8A779A0) += r8a779a0-falcon.dtb
 
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m0-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m0-ulcb.dtb
+dtb-$(CONFIG_ARCH_R8A77951) += r8a779m0-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m0-ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a779m0-ulcb-kf.dts
new file mode 100644
index 0000000000000000..76c40d63cf95f1b3
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m0-ulcb-kf.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the H3ULCB Kingfisher board with R-Car H3e
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77951-ulcb-kf.dts
+ * Copyright (C) 2017 Renesas Electronics Corp.
+ * Copyright (C) 2017 Cogent Embedded, Inc.
+ */
+
+#include "r8a779m0-ulcb.dts"
+#include "ulcb-kf.dtsi"
+
+/ {
+	model = "Renesas H3ULCB Kingfisher board based on r8a779m0";
+	compatible = "shimafuji,kingfisher", "renesas,h3ulcb",
+		     "renesas,r8a779m0", "renesas,r8a7795";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:06 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:06 +0200
Subject: [PATCH v2 16/29] arm64: dts: renesas: Add support for M3ULCB with
 R-Car M3e
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <79685f0f7b46cd490d948fe642dd71381c8685e0.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Pro equipped with an R-Car
M3e SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 arch/arm64/boot/dts/renesas/r8a779m2-ulcb.dts | 45 +++++++++++++++++++
 2 files changed, 46 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m2-ulcb.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 2c542b2f1c9fe092..eb744f7876751699 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m2-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77961) += r8a779m2-ulcb.dtb
 
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m2-ulcb.dts b/arch/arm64/boot/dts/renesas/r8a779m2-ulcb.dts
new file mode 100644
index 0000000000000000..22edd2476ec40f28
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m2-ulcb.dts
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the M3ULCB (R-Car Starter Kit Pro) with R-Car M3e
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77961-ulcb.dts
+ * Copyright (C) 2020 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a779m2.dtsi"
+#include "ulcb.dtsi"
+
+/ {
+	model = "Renesas M3ULCB board based on r8a779m2";
+	compatible = "renesas,m3ulcb", "renesas,r8a779m2", "renesas,r8a77961";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x78000000>;
+	};
+
+	memory at 480000000 {
+		device_type = "memory";
+		reg = <0x4 0x80000000 0x0 0x80000000>;
+	};
+
+	memory at 600000000 {
+		device_type = "memory";
+		reg = <0x6 0x00000000 0x1 0x00000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 722>,
+		 <&versaclock5 1>,
+		 <&versaclock5 3>,
+		 <&versaclock5 2>;
+	clock-names = "du.0", "du.1", "du.2",
+		      "dclkin.0", "dclkin.1", "dclkin.2";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:53 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:53 +0200
Subject: [PATCH v2 03/29] arm64: dts: renesas: Factor out Draak board support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <32618abb48004793f2e030d29b3a038edc05f136.1628766192.git.geert+renesas@glider.be>

Move the common parts for the Renesas Draak board to draak.dtsi, to
avoid future duplication of board descriptions.

Change a reference in a comment from "r8a77995" to "R-Car D3(e)", to
prepare for the advent of "R-Car D3e".

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Drop bogus "based" in model name,
  - Replace "D3" by "D3(e)",
  - Add Reviewed-by,
  - Rebased.
---
 .../{r8a77995-draak.dts => draak.dtsi}        |  10 +-
 .../arm64/boot/dts/renesas/r8a77995-draak.dts | 671 +-----------------
 2 files changed, 5 insertions(+), 676 deletions(-)
 copy arch/arm64/boot/dts/renesas/{r8a77995-draak.dts => draak.dtsi} (97%)

diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/draak.dtsi
similarity index 97%
copy from arch/arm64/boot/dts/renesas/r8a77995-draak.dts
copy to arch/arm64/boot/dts/renesas/draak.dtsi
index 1ac15aa05b823ba9..ff799ab73f8a479d 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/draak.dtsi
@@ -1,19 +1,17 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the Draak board with R-Car D3
+ * Device Tree Source for the Draak board
  *
  * Copyright (C) 2016-2018 Renesas Electronics Corp.
  * Copyright (C) 2017 Glider bvba
  */
 
-/dts-v1/;
-#include "r8a77995.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 
 / {
-	model = "Renesas Draak board based on r8a77995";
-	compatible = "renesas,draak", "renesas,r8a77995";
+	model = "Renesas Draak board";
+	compatible = "renesas,draak";
 
 	aliases {
 		serial0 = &scif2;
@@ -253,7 +251,7 @@ phy0: ethernet-phy at 0 {
 		 * TX clock internal delay mode is required for reliable
 		 * 1Gbps communication using the KSZ9031RNX phy present on
 		 * the Draak board, however, TX clock internal delay mode
-		 * isn't supported on r8a77995.  Thus, limit speed to
+		 * isn't supported on R-Car D3(e).  Thus, limit speed to
 		 * 100Mbps for reliable communication.
 		 */
 		max-speed = <100>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
index 1ac15aa05b823ba9..384825617fcff1ff 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
+++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts
@@ -8,678 +8,9 @@
 
 /dts-v1/;
 #include "r8a77995.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
+#include "draak.dtsi"
 
 / {
 	model = "Renesas Draak board based on r8a77995";
 	compatible = "renesas,draak", "renesas,r8a77995";
-
-	aliases {
-		serial0 = &scif2;
-		ethernet0 = &avb;
-	};
-
-	audio_clkout: audio-clkout {
-		/*
-		 * This is same as <&rcar_sound 0>
-		 * but needed to avoid cs2000/rcar_sound probe dead-lock
-		 */
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <12288000>;
-	};
-
-	backlight: backlight {
-		compatible = "pwm-backlight";
-		pwms = <&pwm1 0 50000>;
-
-		brightness-levels = <512 511 505 494 473 440 392 327 241 133 0>;
-		default-brightness-level = <10>;
-
-		power-supply = <&reg_12p0v>;
-		enable-gpios = <&gpio4 0 GPIO_ACTIVE_HIGH>;
-	};
-
-	chosen {
-		bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
-		stdout-path = "serial0:115200n8";
-	};
-
-	composite-in {
-		compatible = "composite-video-connector";
-
-		port {
-			composite_con_in: endpoint {
-				remote-endpoint = <&adv7180_in>;
-			};
-		};
-	};
-
-	hdmi-in {
-		compatible = "hdmi-connector";
-		type = "a";
-
-		port {
-			hdmi_con_in: endpoint {
-				remote-endpoint = <&adv7612_in>;
-			};
-		};
-	};
-
-	hdmi-out {
-		compatible = "hdmi-connector";
-		type = "a";
-
-		port {
-			hdmi_con_out: endpoint {
-				remote-endpoint = <&adv7511_out>;
-			};
-		};
-	};
-
-	keys {
-		compatible = "gpio-keys";
-
-		pinctrl-0 = <&keys_pins>;
-		pinctrl-names = "default";
-
-		key-1 {
-			gpios = <&gpio4 12 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_1>;
-			label = "SW56-1";
-			wakeup-source;
-			debounce-interval = <20>;
-		};
-		key-2 {
-			gpios = <&gpio4 13 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_2>;
-			label = "SW56-2";
-			wakeup-source;
-			debounce-interval = <20>;
-		};
-		key-3 {
-			gpios = <&gpio4 14 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_3>;
-			label = "SW56-3";
-			wakeup-source;
-			debounce-interval = <20>;
-		};
-		key-4 {
-			gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_4>;
-			label = "SW56-4";
-			wakeup-source;
-			debounce-interval = <20>;
-		};
-	};
-
-	lvds-decoder {
-		compatible = "thine,thc63lvd1024";
-		vcc-supply = <&reg_3p3v>;
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				reg = <0>;
-				thc63lvd1024_in: endpoint {
-					remote-endpoint = <&lvds0_out>;
-				};
-			};
-
-			port at 2 {
-				reg = <2>;
-				thc63lvd1024_out: endpoint {
-					remote-endpoint = <&adv7511_in>;
-				};
-			};
-		};
-	};
-
-	memory at 48000000 {
-		device_type = "memory";
-		/* first 128MB is reserved for secure area. */
-		reg = <0x0 0x48000000 0x0 0x18000000>;
-	};
-
-	reg_1p8v: regulator-1p8v {
-		compatible = "regulator-fixed";
-		regulator-name = "fixed-1.8V";
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-
-	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_12p0v: regulator-12p0v {
-		compatible = "regulator-fixed";
-		regulator-name = "D12.0V";
-		regulator-min-microvolt = <12000000>;
-		regulator-max-microvolt = <12000000>;
-		regulator-boot-on;
-		regulator-always-on;
-	};
-
-	sound_card: sound {
-		compatible = "audio-graph-card";
-
-		dais = <&rsnd_port0	/* ak4613 */
-			/* HDMI is not yet supported */
-		>;
-	};
-
-	vga {
-		compatible = "vga-connector";
-
-		port {
-			vga_in: endpoint {
-				remote-endpoint = <&adv7123_out>;
-			};
-		};
-	};
-
-	vga-encoder {
-		compatible = "adi,adv7123";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				reg = <0>;
-				adv7123_in: endpoint {
-					remote-endpoint = <&du_out_rgb>;
-				};
-			};
-			port at 1 {
-				reg = <1>;
-				adv7123_out: endpoint {
-					remote-endpoint = <&vga_in>;
-				};
-			};
-		};
-	};
-
-	x12_clk: x12 {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <74250000>;
-	};
-
-	x19_clk: x19 {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <24576000>;
-	};
-};
-
-&audio_clk_b {
-	/*
-	 * X11 is connected to VI4_FIELD/SCIF_CLK/AUDIO_CLKB,
-	 * and R-Car Sound uses AUDIO_CLKB.
-	 * Note is that schematic indicates VI4_FIELD conection only
-	 * not AUDIO_CLKB at SoC page.
-	 * And this VI4_FIELD/SCIF_CLK/AUDIO_CLKB is connected to SW60.
-	 * SW60 should be 1-2.
-	 */
-
-	clock-frequency = <22579200>;
-};
-
-&avb {
-	pinctrl-0 = <&avb0_pins>;
-	pinctrl-names = "default";
-	renesas,no-ether-link;
-	phy-handle = <&phy0>;
-	status = "okay";
-
-	phy0: ethernet-phy at 0 {
-		rxc-skew-ps = <1500>;
-		reg = <0>;
-		interrupt-parent = <&gpio5>;
-		interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
-		/*
-		 * TX clock internal delay mode is required for reliable
-		 * 1Gbps communication using the KSZ9031RNX phy present on
-		 * the Draak board, however, TX clock internal delay mode
-		 * isn't supported on r8a77995.  Thus, limit speed to
-		 * 100Mbps for reliable communication.
-		 */
-		max-speed = <100>;
-	};
-};
-
-&can0 {
-	pinctrl-0 = <&can0_pins>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&can1 {
-	pinctrl-0 = <&can1_pins>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&du {
-	pinctrl-0 = <&du_pins>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	clocks = <&cpg CPG_MOD 724>,
-		 <&cpg CPG_MOD 723>,
-		 <&x12_clk>;
-	clock-names = "du.0", "du.1", "dclkin.0";
-
-	ports {
-		port at 0 {
-			endpoint {
-				remote-endpoint = <&adv7123_in>;
-			};
-		};
-	};
-};
-
-&ehci0 {
-	dr_mode = "host";
-	status = "okay";
-};
-
-&extal_clk {
-	clock-frequency = <48000000>;
-};
-
-&hsusb {
-	dr_mode = "host";
-	status = "okay";
-};
-
-&i2c0 {
-	pinctrl-0 = <&i2c0_pins>;
-	pinctrl-names = "default";
-	status = "okay";
-
-	ak4613: codec at 10 {
-		compatible = "asahi-kasei,ak4613";
-		#sound-dai-cells = <0>;
-		reg = <0x10>;
-		clocks = <&rcar_sound 0>; /* audio_clkout */
-
-		asahi-kasei,in1-single-end;
-		asahi-kasei,in2-single-end;
-		asahi-kasei,out1-single-end;
-		asahi-kasei,out2-single-end;
-		asahi-kasei,out3-single-end;
-		asahi-kasei,out4-single-end;
-		asahi-kasei,out5-single-end;
-		asahi-kasei,out6-single-end;
-
-		port {
-			ak4613_endpoint: endpoint {
-				remote-endpoint = <&rsnd_for_ak4613>;
-			};
-		};
-	};
-
-	composite-in at 20 {
-		compatible = "adi,adv7180cp";
-		reg = <0x20>;
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				reg = <0>;
-				adv7180_in: endpoint {
-					remote-endpoint = <&composite_con_in>;
-				};
-			};
-
-			port at 3 {
-				reg = <3>;
-
-				/*
-				 * The VIN4 video input path is shared between
-				 * CVBS and HDMI inputs through SW[49-53]
-				 * switches.
-				 *
-				 * CVBS is the default selection, link it to
-				 * VIN4 here.
-				 */
-				adv7180_out: endpoint {
-					remote-endpoint = <&vin4_in>;
-				};
-			};
-		};
-
-	};
-
-	hdmi-encoder at 39 {
-		compatible = "adi,adv7511w";
-		reg = <0x39>, <0x3f>, <0x3c>, <0x38>;
-		reg-names = "main", "edid", "cec", "packet";
-		interrupt-parent = <&gpio1>;
-		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
-
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				reg = <0>;
-				adv7511_in: endpoint {
-					remote-endpoint = <&thc63lvd1024_out>;
-				};
-			};
-
-			port at 1 {
-				reg = <1>;
-				adv7511_out: endpoint {
-					remote-endpoint = <&hdmi_con_out>;
-				};
-			};
-		};
-	};
-
-	hdmi-decoder at 4c {
-		compatible = "adi,adv7612";
-		reg = <0x4c>;
-		default-input = <0>;
-
-		ports {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			port at 0 {
-				reg = <0>;
-
-				adv7612_in: endpoint {
-					remote-endpoint = <&hdmi_con_in>;
-				};
-			};
-
-			port at 2 {
-				reg = <2>;
-
-				/*
-				 * The VIN4 video input path is shared between
-				 * CVBS and HDMI inputs through SW[49-53]
-				 * switches.
-				 *
-				 * CVBS is the default selection, leave HDMI
-				 * not connected here.
-				 */
-				adv7612_out: endpoint {
-					pclk-sample = <0>;
-					hsync-active = <0>;
-					vsync-active = <0>;
-				};
-			};
-		};
-	};
-
-	cs2000: clk-multiplier at 4f {
-		#clock-cells = <0>;
-		compatible = "cirrus,cs2000-cp";
-		reg = <0x4f>;
-		clocks = <&audio_clkout>, <&x19_clk>; /* audio_clkout_1, x19 */
-		clock-names = "clk_in", "ref_clk";
-
-		assigned-clocks = <&cs2000>;
-		assigned-clock-rates = <24576000>; /* 1/1 divide */
-	};
-
-	eeprom at 50 {
-		compatible = "rohm,br24t01", "atmel,24c01";
-		reg = <0x50>;
-		pagesize = <8>;
-	};
-};
-
-&i2c1 {
-	pinctrl-0 = <&i2c1_pins>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&lvds0 {
-	status = "okay";
-
-	clocks = <&cpg CPG_MOD 727>,
-		 <&x12_clk>,
-		 <&extal_clk>;
-	clock-names = "fck", "dclkin.0", "extal";
-
-	ports {
-		port at 1 {
-			lvds0_out: endpoint {
-				remote-endpoint = <&thc63lvd1024_in>;
-			};
-		};
-	};
-};
-
-&lvds1 {
-	/*
-	 * Even though the LVDS1 output is not connected, the encoder must be
-	 * enabled to supply a pixel clock to the DU for the DPAD output when
-	 * LVDS0 is in use.
-	 */
-	status = "okay";
-
-	clocks = <&cpg CPG_MOD 727>,
-		 <&x12_clk>,
-		 <&extal_clk>;
-	clock-names = "fck", "dclkin.0", "extal";
-};
-
-&ohci0 {
-	dr_mode = "host";
-	status = "okay";
-};
-
-&pfc {
-	avb0_pins: avb {
-		groups = "avb0_link", "avb0_mdio", "avb0_mii";
-		function = "avb0";
-	};
-
-	can0_pins: can0 {
-		groups = "can0_data_a";
-		function = "can0";
-	};
-
-	can1_pins: can1 {
-		groups = "can1_data_a";
-		function = "can1";
-	};
-
-	du_pins: du {
-		groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0";
-		function = "du";
-	};
-
-	i2c0_pins: i2c0 {
-		groups = "i2c0";
-		function = "i2c0";
-	};
-
-	i2c1_pins: i2c1 {
-		groups = "i2c1";
-		function = "i2c1";
-	};
-
-	keys_pins: keys {
-		pins = "GP_4_12", "GP_4_13", "GP_4_14", "GP_4_15";
-		bias-pull-up;
-	};
-
-	pwm0_pins: pwm0 {
-		groups = "pwm0_c";
-		function = "pwm0";
-	};
-
-	pwm1_pins: pwm1 {
-		groups = "pwm1_c";
-		function = "pwm1";
-	};
-
-	scif2_pins: scif2 {
-		groups = "scif2_data";
-		function = "scif2";
-	};
-
-	sdhi2_pins: sd2 {
-		groups = "mmc_data8", "mmc_ctrl";
-		function = "mmc";
-		power-source = <1800>;
-	};
-
-	sdhi2_pins_uhs: sd2_uhs {
-		groups = "mmc_data8", "mmc_ctrl";
-		function = "mmc";
-		power-source = <1800>;
-	};
-
-	sound_pins: sound {
-		groups = "ssi34_ctrl", "ssi3_data", "ssi4_data_a";
-		function = "ssi";
-	};
-
-	sound_clk_pins: sound-clk {
-		groups = "audio_clk_a", "audio_clk_b",
-			 "audio_clkout", "audio_clkout1";
-		function = "audio_clk";
-	};
-
-	usb0_pins: usb0 {
-		groups = "usb0";
-		function = "usb0";
-	};
-
-	vin4_pins_cvbs: vin4 {
-		groups = "vin4_data8", "vin4_sync", "vin4_clk";
-		function = "vin4";
-	};
-};
-
-&pwm0 {
-	pinctrl-0 = <&pwm0_pins>;
-	pinctrl-names = "default";
-
-	status = "okay";
-};
-
-&pwm1 {
-	pinctrl-0 = <&pwm1_pins>;
-	pinctrl-names = "default";
-
-	status = "okay";
-};
-
-&rcar_sound {
-	pinctrl-0 = <&sound_pins>, <&sound_clk_pins>;
-	pinctrl-names = "default";
-
-	/* Single DAI */
-	#sound-dai-cells = <0>;
-
-	/* audio_clkout0/1 */
-	#clock-cells = <1>;
-	clock-frequency = <12288000 11289600>;
-
-	status = "okay";
-
-	clocks = <&cpg CPG_MOD 1005>,
-		 <&cpg CPG_MOD 1011>, <&cpg CPG_MOD 1012>,
-		 <&cpg CPG_MOD 1025>, <&cpg CPG_MOD 1026>,
-		 <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
-		 <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>,
-		 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>,
-		 <&cs2000>, <&audio_clk_b>,
-		 <&cpg CPG_CORE R8A77995_CLK_ZA2>;
-
-	ports {
-		rsnd_port0: port {
-			rsnd_for_ak4613: endpoint {
-				remote-endpoint = <&ak4613_endpoint>;
-				dai-format = "left_j";
-				bitclock-master = <&rsnd_for_ak4613>;
-				frame-master = <&rsnd_for_ak4613>;
-				playback = <&ssi3>, <&src5>, <&dvc0>;
-				capture  = <&ssi4>, <&src6>, <&dvc1>;
-			};
-		};
-	};
-};
-
-&rwdt {
-	timeout-sec = <60>;
-	status = "okay";
-};
-
-&scif2 {
-	pinctrl-0 = <&scif2_pins>;
-	pinctrl-names = "default";
-
-	status = "okay";
-};
-
-&sdhi2 {
-	/* used for on-board eMMC */
-	pinctrl-0 = <&sdhi2_pins>;
-	pinctrl-1 = <&sdhi2_pins_uhs>;
-	pinctrl-names = "default", "state_uhs";
-
-	vmmc-supply = <&reg_3p3v>;
-	vqmmc-supply = <&reg_1p8v>;
-	bus-width = <8>;
-	mmc-hs200-1_8v;
-	no-sd;
-	no-sdio;
-	non-removable;
-	status = "okay";
-};
-
-&ssi4 {
-	shared-pin;
-};
-
-&usb2_phy0 {
-	pinctrl-0 = <&usb0_pins>;
-	pinctrl-names = "default";
-
-	renesas,no-otg-pins;
-	status = "okay";
-};
-
-&vin4 {
-	pinctrl-0 = <&vin4_pins_cvbs>;
-	pinctrl-names = "default";
-
-	status = "okay";
-
-	ports {
-		port {
-			vin4_in: endpoint {
-				remote-endpoint = <&adv7180_out>;
-			};
-		};
-	};
 };
-- 
2.25.1



From joro at 8bytes.org  Thu Aug 12 04:27:01 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Thu, 12 Aug 2021 13:27:01 +0200
Subject: [PATCH] iommu: APPLE_DART should depend on ARCH_APPLE
In-Reply-To: <44fcf525273b32c9afcd7e99acbd346d47f0e047.1628603162.git.geert+renesas@glider.be>
References: <44fcf525273b32c9afcd7e99acbd346d47f0e047.1628603162.git.geert+renesas@glider.be>
Message-ID: <YRUFhQ9B7goYvsuN@8bytes.org>

On Tue, Aug 10, 2021 at 03:47:19PM +0200, Geert Uytterhoeven wrote:
> The Apple DART (Device Address Resolution Table) IOMMU is only present
> on Apple ARM SoCs like the M1.  Hence add a dependency on ARCH_APPLE, to
> prevent asking the user about this driver when configuring a kernel
> without support for the Apple Silicon SoC family.
> 
> Fixes: 05ce9d20d699b093 ("iommu/dart: Add DART iommu driver")
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
>  drivers/iommu/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index dfe81da483e9e073..e908b8222e4ed679 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -292,7 +292,7 @@ config SPAPR_TCE_IOMMU
>  
>  config APPLE_DART
>  	tristate "Apple DART IOMMU Support"
> -	depends on ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64)
> +	depends on ARCH_APPLE || (COMPILE_TEST && !GENERIC_ATOMIC64)
>  	select IOMMU_API
>  	select IOMMU_IO_PGTABLE_LPAE
>  	default ARCH_APPLE

Dropped the Fixes tag, as this doesn't fix any real issue. Otherwise
applied with adjusted subject (iommu: -> iommu/dart:), Thanks.


From herbert at gondor.apana.org.au  Thu Aug 12 04:36:05 2021
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 12 Aug 2021 19:36:05 +0800
Subject: [PATCH] crypto: sun8i-ce - use kfree_sensitive to clear and free
 sensitive data
In-Reply-To: <20210803125525.72603-1-wangborong@cdjrlc.com>
References: <20210803125525.72603-1-wangborong@cdjrlc.com>
Message-ID: <20210812113605.GA561@gondor.apana.org.au>

On Tue, Aug 03, 2021 at 12:55:25PM +0000, Jason Wang wrote:
> The kfree_sensitive is a kernel API to clear sensitive information
> that should not be leaked to other future users of the same memory
> objects and free the memory. Its function is the same as the
> combination  of memzero_explicit and kfree. Thus, we can replace the
> combination APIs with the single kfree_sensitive API.
> 
> Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
> ---
>  drivers/crypto/allwinner/sun8i-ce/sun8i-ce-prng.c | 9 +++------
>  drivers/crypto/allwinner/sun8i-ce/sun8i-ce-trng.c | 3 +--
>  2 files changed, 4 insertions(+), 8 deletions(-)

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From alexandru.elisei at arm.com  Thu Aug 12 04:51:34 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 12 Aug 2021 12:51:34 +0100
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
In-Reply-To: <87fsvfal4n.wl-maz@kernel.org>
References: <20210811171505.1502090-1-wenst@chromium.org>
 <87fsvfal4n.wl-maz@kernel.org>
Message-ID: <79eabae1-e4a3-7a12-7aa0-3680569584e5@arm.com>

Hi,

After re-familiarizing myself with the spec, it starting to look to me like indeed
there's something not quite right (read as: totally broken) with my patch.

Arm IHI 0069F, the pseudocode for reading ICC_RPR_EL1 (page 11-797), says that the
priority returned is unchanged if SCTLR_EL3.FIQ == 0. This means that the
ICC_RPR_EL1 read will return the secure view (the value as it is stored by the
GIC) of the priority, so for pseudo-nmis it will return (GICD_INT_NMI_PRI >> 1) |
0x80, which definitely != GICD_INT_NMI_PRI. This is further confirmed by this
statement on page 4-67:

"When GICD_CTLR.DS == 0, [..] For Non-secure access to ICC_PMR_EL1 and ICC_RPR_EL1
when SCR_EL3.FIQ == 0:
The Secure, unshifted view applies."

I don't know how I missed that during testing.

Did a quick test on the model with PMU NMIs (GICD_CTRL.DS = 0, SCTLR_EL2.FIQ = 0),
gic_handle_nmi() was not being called at all, but when I changed the comparison to
gic_read_rpr() == ((GICD_INT_NMI_PRI >> 1) | 0x80), NMIs were being correctly
handled again.

Will try to run some more tests on real hardware and see if I can confirm this.

Thanks,

Alex

On 8/11/21 7:31 PM, Marc Zyngier wrote:
> + Alex, who introduced this.
>
> On Wed, 11 Aug 2021 18:15:05 +0100,
> Chen-Yu Tsai <wenst at chromium.org> wrote:
>> When non-secure priorities are used, compared to the raw priority set,
>> the value read back from RPR is also right-shifted by one and the
>> highest bit set.
>>
>> Add a macro to do the modifications to the raw priority when doing the
>> comparison against the RPR value. This corrects the pseudo-NMI behavior
>> when non-secure priorities in the GIC are used. Tested on 5.10 with
>> the "IPI as pseudo-NMI" series [1] applied on MT8195.
>>
>> [1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg at linaro.org/
>>
>> Fixes: 336780590990 ("irqchip/gic-v3: Support pseudo-NMIs when SCR_EL3.FIQ == 0")
>> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>> ---
>>  drivers/irqchip/irq-gic-v3.c | 11 ++++++++++-
>>  1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index e0f4debe64e1..e7a0b55413db 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -100,6 +100,15 @@ EXPORT_SYMBOL(gic_pmr_sync);
>>  DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities);
>>  EXPORT_SYMBOL(gic_nonsecure_priorities);
>>  
>> +#define GICD_INT_RPR_PRI(priority)					\
>> +	({								\
>> +		u32 __priority = (priority);				\
>> +		if (static_branch_unlikely(&gic_nonsecure_priorities))	\
>> +			__priority = 0x80 | (__priority >> 1);		\
>> +									\
>> +		__priority;						\
> This doesn't reflect what the pseudocode says of a read of ICC_RPR_EL1
> AFAICS. When the priority is activated, it is indeed shifted. But a
> read of RPR does appear to shift things back (and you loose the lowest
> bit in the process). Please see 'aarch64/support/ICC_RPR_EL1' in the
> architecture spec.
>
> Can you confirm that SCR_EL3.FIQ is set on your system?
>
> Thanks,
>
> 	M.
>
>> +	})
>> +
>>  /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
>>  static refcount_t *ppi_nmi_refs;
>>  
>> @@ -687,7 +696,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
>>  		return;
>>  
>>  	if (gic_supports_nmi() &&
>> -	    unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) {
>> +	    unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) {
>>  		gic_handle_nmi(irqnr, regs);
>>  		return;
>>  	}
>


From geert+renesas at glider.be  Thu Aug 12 04:23:57 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:57 +0200
Subject: [PATCH v2 07/29] arm64: dts: renesas: Add Renesas R8A779M4 SoC support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <52aa6dcf6682f54fa2bf53491ef7de5173192a73.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car M3Ne (R8A779M4) SoC, which is a
different grading of the R-Car M3-N (R8A77965) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - No changes.
---
 arch/arm64/boot/dts/renesas/r8a779m4.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m4.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r8a779m4.dtsi b/arch/arm64/boot/dts/renesas/r8a779m4.dtsi
new file mode 100644
index 0000000000000000..d7fbb6c05502678c
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m4.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the R-Car M3Ne (R8A779M4) SoC
+ *
+ * Copyright (C) 2021 Glider bv
+ */
+
+#include "r8a77965.dtsi"
+
+/ {
+	compatible = "renesas,r8a779m4", "renesas,r8a77965";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:19 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:19 +0200
Subject: [PATCH v2 29/29] [RFC] arm64: dts: renesas: r8a779m5: Add Cortex-A57
 2 GHz opp
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <bbfb67c95e0c2bc3312bf46b7a28b6baa452786a.1628766192.git.geert+renesas@glider.be>

Add a preliminary operating point for running the Cortex-A57 CPU cores
on R-Car M3Ne-2G at 2 GHz.

The opp-microvolt value depends on a future update of the Electrical
Characteristics for R-Car M3Ne-2G.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - Change 2 GHz opp from 1020000 ?V to 960000 ?V, as per informal
    communication.
---
 arch/arm64/boot/dts/renesas/r8a779m5.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a779m5.dtsi b/arch/arm64/boot/dts/renesas/r8a779m5.dtsi
index f0ef765f6cf87319..5ab9bbdd419be3cd 100644
--- a/arch/arm64/boot/dts/renesas/r8a779m5.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779m5.dtsi
@@ -10,3 +10,12 @@
 / {
 	compatible = "renesas,r8a779m5", "renesas,r8a77965";
 };
+
+&cluster0_opp {
+	opp-2000000000 {
+		opp-hz = /bits/ 64 <2000000000>;
+		opp-microvolt = <960000>;	// FIXME TBC
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:17 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:17 +0200
Subject: [PATCH v2 27/29] arm64: dts: renesas: Add support for H3ULCB with
 R-Car H3Ne
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <1858660058f491e5a836d026bd68051f4511d010.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Premier equipped with an
R-Car H3Ne SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 arch/arm64/boot/dts/renesas/r8a779m8-ulcb.dts | 52 +++++++++++++++++++
 2 files changed, 53 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m8-ulcb.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index a14642a9e45a2a4b..c7d2b91a833b00b8 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -92,5 +92,6 @@ dtb-$(CONFIG_ARCH_R8A77990) += r8a779m6-ebisu.dtb
 dtb-$(CONFIG_ARCH_R8A77995) += r8a779m7-draak.dtb
 
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m8-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77951) += r8a779m8-ulcb.dtb
 
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m8-ulcb.dts b/arch/arm64/boot/dts/renesas/r8a779m8-ulcb.dts
new file mode 100644
index 0000000000000000..d91ae596a6bf1f02
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m8-ulcb.dts
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the H3ULCB (R-Car Starter Kit Premier) with R-Car H3Ne
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77951-ulcb.dts
+ * Copyright (C) 2016 Cogent Embedded, Inc.
+ */
+
+/dts-v1/;
+#include "r8a779m8.dtsi"
+#include "ulcb.dtsi"
+
+/ {
+	model = "Renesas H3ULCB board based on r8a779m8";
+	compatible = "renesas,h3ulcb", "renesas,r8a779m8", "renesas,r8a7795";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x38000000>;
+	};
+
+	memory at 500000000 {
+		device_type = "memory";
+		reg = <0x5 0x00000000 0x0 0x40000000>;
+	};
+
+	memory at 600000000 {
+		device_type = "memory";
+		reg = <0x6 0x00000000 0x0 0x40000000>;
+	};
+
+	memory at 700000000 {
+		device_type = "memory";
+		reg = <0x7 0x00000000 0x0 0x40000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 722>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock5 1>,
+		 <&versaclock5 3>,
+		 <&versaclock5 4>,
+		 <&versaclock5 2>;
+	clock-names = "du.0", "du.1", "du.2", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:18 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:18 +0200
Subject: [PATCH v2 28/29] arm64: dts: renesas: Add support for
 H3ULCB+Kingfisher with R-Car H3Ne
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <c4a0d7889c08ec0239e0dda1c31f24c8320b4d98.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Premier and Kingfisher
combo equipped with an R-Car H3Ne SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 .../boot/dts/renesas/r8a779m8-ulcb-kf.dts     | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m8-ulcb-kf.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index c7d2b91a833b00b8..498f1c4a3b271b93 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -93,5 +93,6 @@ dtb-$(CONFIG_ARCH_R8A77995) += r8a779m7-draak.dtb
 
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m8-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m8-ulcb.dtb
+dtb-$(CONFIG_ARCH_R8A77951) += r8a779m8-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m8-ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a779m8-ulcb-kf.dts
new file mode 100644
index 0000000000000000..3a2c80fb1a3d271f
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m8-ulcb-kf.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the H3ULCB Kingfisher board with R-Car H3Ne
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77951-ulcb-kf.dts
+ * Copyright (C) 2017 Renesas Electronics Corp.
+ * Copyright (C) 2017 Cogent Embedded, Inc.
+ */
+
+#include "r8a779m8-ulcb.dts"
+#include "ulcb-kf.dtsi"
+
+/ {
+	model = "Renesas H3ULCB Kingfisher board based on r8a779m8";
+	compatible = "shimafuji,kingfisher", "renesas,h3ulcb",
+		     "renesas,r8a779m8", "renesas,r8a7795";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:09 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:09 +0200
Subject: [PATCH v2 19/29] arm64: dts: renesas: Add support for M3NULCB with
 R-Car M3Ne
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <dc9b46ab77a7846d70506ddecb841bd6fd04258c.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car Starter Kit Pro equipped with an R-Car
M3Ne SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  1 +
 arch/arm64/boot/dts/renesas/r8a779m4-ulcb.dts | 36 +++++++++++++++++++
 2 files changed, 37 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m4-ulcb.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 2ab938d4b62c1317..45a004035e216c14 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -80,5 +80,6 @@ dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77961) += r8a779m3-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77965) += r8a779m4-ulcb.dtb
 
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m4-ulcb.dts b/arch/arm64/boot/dts/renesas/r8a779m4-ulcb.dts
new file mode 100644
index 0000000000000000..632f1c72ad8fe6e0
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m4-ulcb.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the M3NULCB (R-Car Starter Kit Pro) with R-Car M3Ne
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77965-ulcb.dts
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+/dts-v1/;
+#include "r8a779m4.dtsi"
+#include "ulcb.dtsi"
+
+/ {
+	model = "Renesas M3NULCB board based on r8a779m4";
+	compatible = "renesas,m3nulcb", "renesas,r8a779m4", "renesas,r8a77965";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x78000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock5 1>,
+		 <&versaclock5 3>,
+		 <&versaclock5 2>;
+	clock-names = "du.0", "du.1", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.3";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:02 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:02 +0200
Subject: [PATCH v2 12/29] arm64: dts: renesas: Add support for Salvator-XS
 with R-Car H3e
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <aa680c5f52864b0f5f7e2f82993bf92f0b17b680.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas Salvator-X 2nd version development
board equipped with an R-Car H3e SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  2 +
 .../boot/dts/renesas/r8a779m0-salvator-xs.dts | 53 +++++++++++++++++++
 2 files changed, 55 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m0-salvator-xs.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 15a53b5139669aa6..69bdf8e92a459f1f 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -63,6 +63,8 @@ dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb
 
 dtb-$(CONFIG_ARCH_R8A779A0) += r8a779a0-falcon.dtb
 
+dtb-$(CONFIG_ARCH_R8A77951) += r8a779m0-salvator-xs.dtb
+
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-ulcb-kf.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m0-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a779m0-salvator-xs.dts
new file mode 100644
index 0000000000000000..571c5e42240a6308
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m0-salvator-xs.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the Salvator-X 2nd version board with R-Car H3e
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77951-salvator-xs.dts
+ * Copyright (C) 2015-2017 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a779m0.dtsi"
+#include "salvator-xs.dtsi"
+
+/ {
+	model = "Renesas Salvator-X 2nd version board based on r8a779m0";
+	compatible = "renesas,salvator-xs", "renesas,r8a779m0",
+		     "renesas,r8a7795";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x38000000>;
+	};
+
+	memory at 500000000 {
+		device_type = "memory";
+		reg = <0x5 0x00000000 0x0 0x40000000>;
+	};
+
+	memory at 600000000 {
+		device_type = "memory";
+		reg = <0x6 0x00000000 0x0 0x40000000>;
+	};
+
+	memory at 700000000 {
+		device_type = "memory";
+		reg = <0x7 0x00000000 0x0 0x40000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 722>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock6 1>,
+		 <&x21_clk>,
+		 <&x22_clk>,
+		 <&versaclock6 2>;
+	clock-names = "du.0", "du.1", "du.2", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:16 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:16 +0200
Subject: [PATCH v2 26/29] arm64: dts: renesas: Add support for Salvator-XS
 with R-Car H3Ne
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <05b3152c6bc84113642c861123c3371450c32170.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas Salvator-X 2nd version development
board equipped with an R-Car H3Ne SiP.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  2 +
 .../boot/dts/renesas/r8a779m8-salvator-xs.dts | 53 +++++++++++++++++++
 2 files changed, 55 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m8-salvator-xs.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 6c2810d39f5a7871..a14642a9e45a2a4b 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -91,4 +91,6 @@ dtb-$(CONFIG_ARCH_R8A77990) += r8a779m6-ebisu.dtb
 
 dtb-$(CONFIG_ARCH_R8A77995) += r8a779m7-draak.dtb
 
+dtb-$(CONFIG_ARCH_R8A77951) += r8a779m8-salvator-xs.dtb
+
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m8-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a779m8-salvator-xs.dts
new file mode 100644
index 0000000000000000..ddb0edb03db4e30c
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m8-salvator-xs.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the Salvator-X 2nd version board with R-Car H3Ne
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77951-salvator-xs.dts
+ * Copyright (C) 2015-2017 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a779m8.dtsi"
+#include "salvator-xs.dtsi"
+
+/ {
+	model = "Renesas Salvator-X 2nd version board based on r8a779m8";
+	compatible = "renesas,salvator-xs", "renesas,r8a779m8",
+		     "renesas,r8a7795";
+
+	memory at 48000000 {
+		device_type = "memory";
+		/* first 128MB is reserved for secure area. */
+		reg = <0x0 0x48000000 0x0 0x38000000>;
+	};
+
+	memory at 500000000 {
+		device_type = "memory";
+		reg = <0x5 0x00000000 0x0 0x40000000>;
+	};
+
+	memory at 600000000 {
+		device_type = "memory";
+		reg = <0x6 0x00000000 0x0 0x40000000>;
+	};
+
+	memory at 700000000 {
+		device_type = "memory";
+		reg = <0x7 0x00000000 0x0 0x40000000>;
+	};
+};
+
+&du {
+	clocks = <&cpg CPG_MOD 724>,
+		 <&cpg CPG_MOD 723>,
+		 <&cpg CPG_MOD 722>,
+		 <&cpg CPG_MOD 721>,
+		 <&versaclock6 1>,
+		 <&x21_clk>,
+		 <&x22_clk>,
+		 <&versaclock6 2>;
+	clock-names = "du.0", "du.1", "du.2", "du.3",
+		      "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:51 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:51 +0200
Subject: [PATCH v2 01/29] dt-bindings: arm: renesas: Document more R-Car Gen3e
 Socs and boards
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <55271d405112f327753945072cde5d158ab815b1.1628766192.git.geert+renesas@glider.be>

Document the compatible values for the remaining R-Car Gen3e SoCs: R-Car
H3e (R8A779M0), M3e (R8A779M2), M3Ne (R8A779M4), M3Ne-2G (R8A779M5), E3e
(R8A779M6), D3e (R8A779M7), and H3Ne (R8A779M8).  These are different
gradings of R-Car Gen3 SoCs.

All R-Car Gen3e on-SoC devices are identical to the devices on the
corresponding R-Car Gen3 SoCs, and thus just use the compatible values
for the latter.  The root compatible properties do gain an additional
value, to sort out integration issues if they ever arise.

Document the use of these SoCs on the Salvator-XS, ULCB (with and
without Kingfisher extension), Ebisu, and Draak development boards.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Typo s/R8A779M/R8A779M0/,
  - Add Reviewed-by.
---
 .../devicetree/bindings/arm/renesas.yaml      | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/renesas.yaml b/Documentation/devicetree/bindings/arm/renesas.yaml
index 8a11918866b86482..5172065078014f39 100644
--- a/Documentation/devicetree/bindings/arm/renesas.yaml
+++ b/Documentation/devicetree/bindings/arm/renesas.yaml
@@ -255,12 +255,19 @@ properties:
               - enum:
                   - renesas,h3ulcb
                   - renesas,m3ulcb
+                  - renesas,m3nulcb
               - enum:
+                  - renesas,r8a779m0
                   - renesas,r8a779m1
+                  - renesas,r8a779m2
                   - renesas,r8a779m3
+                  - renesas,r8a779m4
+                  - renesas,r8a779m5
+                  - renesas,r8a779m8
               - enum:
                   - renesas,r8a7795
                   - renesas,r8a77961
+                  - renesas,r8a77965
 
       - description: R-Car M3-N (R8A77965)
         items:
@@ -308,6 +315,14 @@ properties:
           - const: renesas,falcon-cpu
           - const: renesas,r8a779a0
 
+      - description: R-Car H3e (R8A779M0)
+        items:
+          - enum:
+              - renesas,h3ulcb      # H3ULCB (R-Car Starter Kit Premier)
+              - renesas,salvator-xs # Salvator-XS (Salvator-X 2nd version)
+          - const: renesas,r8a779m0
+          - const: renesas,r8a7795
+
       - description: R-Car H3e-2G (R8A779M1)
         items:
           - enum:
@@ -316,6 +331,14 @@ properties:
           - const: renesas,r8a779m1
           - const: renesas,r8a7795
 
+      - description: R-Car M3e (R8A779M2)
+        items:
+          - enum:
+              - renesas,m3ulcb      # M3ULCB (R-Car Starter Kit Pro)
+              - renesas,salvator-xs # Salvator-XS (Salvator-X 2nd version)
+          - const: renesas,r8a779m2
+          - const: renesas,r8a77961
+
       - description: R-Car M3e-2G (R8A779M3)
         items:
           - enum:
@@ -324,6 +347,44 @@ properties:
           - const: renesas,r8a779m3
           - const: renesas,r8a77961
 
+      - description: R-Car M3Ne (R8A779M4)
+        items:
+          - enum:
+              - renesas,m3nulcb     # M3NULCB (R-Car Starter Kit Pro)
+              - renesas,salvator-xs # Salvator-XS (Salvator-X 2nd version)
+          - const: renesas,r8a779m4
+          - const: renesas,r8a77965
+
+      - description: R-Car M3Ne-2G (R8A779M5)
+        items:
+          - enum:
+              - renesas,m3nulcb     # M3NULCB (R-Car Starter Kit Pro)
+              - renesas,salvator-xs # Salvator-XS (Salvator-X 2nd version)
+          - const: renesas,r8a779m5
+          - const: renesas,r8a77965
+
+      - description: R-Car E3e (R8A779M6)
+        items:
+          - enum:
+              - renesas,ebisu       # Ebisu
+          - const: renesas,r8a779m6
+          - const: renesas,r8a77990
+
+      - description: R-Car D3e (R8A779M7)
+        items:
+          - enum:
+              - renesas,draak       # Draak
+          - const: renesas,r8a779m7
+          - const: renesas,r8a77995
+
+      - description: R-Car H3Ne (R8A779M8)
+        items:
+          - enum:
+              - renesas,h3ulcb      # H3ULCB (R-Car Starter Kit Premier)
+              - renesas,salvator-xs # Salvator-XS (Salvator-X 2nd version)
+          - const: renesas,r8a779m8
+          - const: renesas,r8a7795
+
       - description: RZ/N1D (R9A06G032)
         items:
           - enum:
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:15 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:15 +0200
Subject: [PATCH v2 25/29] arm64: dts: renesas: Add support for Draak with
 R-Car D3e
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <78c137e09008d232d4f34fe86cc5a83162ba2393.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas Draak development board equipped with an
R-Car D3e SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile          |  2 ++
 .../arm64/boot/dts/renesas/r8a779m7-draak.dts | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m7-draak.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index c28c36efa10021c5..6c2810d39f5a7871 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -89,4 +89,6 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77990) += r8a779m6-ebisu.dtb
 
+dtb-$(CONFIG_ARCH_R8A77995) += r8a779m7-draak.dtb
+
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m7-draak.dts b/arch/arm64/boot/dts/renesas/r8a779m7-draak.dts
new file mode 100644
index 0000000000000000..cf9005b32aeb8344
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m7-draak.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the Draak board with R-Car D3e
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77995-draak.dts
+ * Copyright (C) 2016-2018 Renesas Electronics Corp.
+ * Copyright (C) 2017 Glider bvba
+ */
+
+/dts-v1/;
+#include "r8a779m7.dtsi"
+#include "draak.dtsi"
+
+/ {
+	model = "Renesas Draak board based on r8a779m7";
+	compatible = "renesas,draak", "renesas,r8a779m7", "renesas,r8a77995";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:55 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:55 +0200
Subject: [PATCH v2 05/29] arm64: dts: renesas: Add Renesas R8A779M0 SoC support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <a82a72bec176fd5bdd71c392aa325eb0917ee81a.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car H3e (R8A779M0) SoC, which is a
different grading of the R-Car H3 ES3.0 (R8A77951) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - No changes.
---
 arch/arm64/boot/dts/renesas/r8a779m0.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m0.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r8a779m0.dtsi b/arch/arm64/boot/dts/renesas/r8a779m0.dtsi
new file mode 100644
index 0000000000000000..6fb1979cc0414abf
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m0.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the R-Car H3e (R8A779M0) SoC
+ *
+ * Copyright (C) 2021 Glider bv
+ */
+
+#include "r8a77951.dtsi"
+
+/ {
+	compatible = "renesas,r8a779m0", "renesas,r8a7795";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:56 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:56 +0200
Subject: [PATCH v2 06/29] arm64: dts: renesas: Add Renesas R8A779M2 SoC support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <2303577cac91aa6d98e7f2c72e36841f6218e53f.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car M3e (R8A779M2) SoC, which is a
different grading of the R-Car M3-W+ (R8A77961) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - No changes.
---
 arch/arm64/boot/dts/renesas/r8a779m2.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m2.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r8a779m2.dtsi b/arch/arm64/boot/dts/renesas/r8a779m2.dtsi
new file mode 100644
index 0000000000000000..324627340b86ad9e
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m2.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the R-Car M3e (R8A779M2) SoC
+ *
+ * Copyright (C) 2021 Glider bv
+ */
+
+#include "r8a77961.dtsi"
+
+/ {
+	compatible = "renesas,r8a779m2", "renesas,r8a77961";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:24:14 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:24:14 +0200
Subject: [PATCH v2 24/29] arm64: dts: renesas: Add support for Ebisu with
 R-Car E3e
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <aa90507abc4f3c4bca478884c3611bf4c5a346c0.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas Ebisu development board equipped with an
R-Car E3e SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
v2:
  - Add Reviewed-by.
---
 arch/arm64/boot/dts/renesas/Makefile           |  2 ++
 arch/arm64/boot/dts/renesas/r8a779m6-ebisu.dts | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m6-ebisu.dts

diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 13446aecdfccb080..c28c36efa10021c5 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -87,4 +87,6 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-ulcb-kf.dtb
 
+dtb-$(CONFIG_ARCH_R8A77990) += r8a779m6-ebisu.dtb
+
 dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a779m6-ebisu.dts b/arch/arm64/boot/dts/renesas/r8a779m6-ebisu.dts
new file mode 100644
index 0000000000000000..baff1f823546d85e
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m6-ebisu.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the Ebisu board with R-Car E3e
+ *
+ * Copyright (C) 2021 Glider bv
+ *
+ * Based on r8a77990-ebisu.dts
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+#include "r8a779m6.dtsi"
+#include "ebisu.dtsi"
+
+/ {
+	model = "Renesas Ebisu board based on r8a779m6";
+	compatible = "renesas,ebisu", "renesas,r8a779m6", "renesas,r8a77990";
+};
-- 
2.25.1



From geert+renesas at glider.be  Thu Aug 12 04:23:58 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Thu, 12 Aug 2021 13:23:58 +0200
Subject: [PATCH v2 08/29] arm64: dts: renesas: Add Renesas R8A779M5 SoC support
In-Reply-To: <cover.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
Message-ID: <2ed19a0e009d3e7afb330086b69c8724465b88cc.1628766192.git.geert+renesas@glider.be>

Add support for the Renesas R-Car M3Ne-2G (R8A779M5) SoC, which is a
different grading of the R-Car M3-N (R8A77965) SoC.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v2:
  - No changes.
---
 arch/arm64/boot/dts/renesas/r8a779m5.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 arch/arm64/boot/dts/renesas/r8a779m5.dtsi

diff --git a/arch/arm64/boot/dts/renesas/r8a779m5.dtsi b/arch/arm64/boot/dts/renesas/r8a779m5.dtsi
new file mode 100644
index 0000000000000000..f0ef765f6cf87319
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779m5.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 or MIT)
+/*
+ * Device Tree Source for the R-Car M3Ne-2G (R8A779M5) SoC
+ *
+ * Copyright (C) 2021 Glider bv
+ */
+
+#include "r8a77965.dtsi"
+
+/ {
+	compatible = "renesas,r8a779m5", "renesas,r8a77965";
+};
-- 
2.25.1



From thierry.reding at gmail.com  Thu Aug 12 05:26:15 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 12 Aug 2021 14:26:15 +0200
Subject: [PATCH 1/3] dt-bindings: tegra: Document NVIDIA Jetson TX2 NX
 developer kit
Message-ID: <20210812122617.2378605-1-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

The Jetson TX2 NX Developer Kit is the same form factor as Jetson Nano,
but uses the more powerful Tegra186 SoC for added performance.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 Documentation/devicetree/bindings/arm/tegra.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml
index d99b9d513ecf..53aab932ffd0 100644
--- a/Documentation/devicetree/bindings/arm/tegra.yaml
+++ b/Documentation/devicetree/bindings/arm/tegra.yaml
@@ -154,6 +154,7 @@ properties:
       - items:
           - enum:
               - nvidia,p2771-0000
+              - nvidia,p3509-0000+p3636-0001
           - const: nvidia,tegra186
       - items:
           - enum:
-- 
2.32.0



From thierry.reding at gmail.com  Thu Aug 12 05:26:16 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 12 Aug 2021 14:26:16 +0200
Subject: [PATCH 2/3] arm64: tegra: Add PWM nodes on Tegra186
In-Reply-To: <20210812122617.2378605-1-thierry.reding@gmail.com>
References: <20210812122617.2378605-1-thierry.reding@gmail.com>
Message-ID: <20210812122617.2378605-2-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

These PWMs can be used for fan or LED backlight control. Add the device
tree nodes for all existing controllers found on Tegra186 SoCs. None of
these are enabled by default, which is left for the board DTS files to
do when necessary.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 88 ++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 5c45fab0c9ab..cce3db252ea5 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -548,6 +548,83 @@ gen9_i2c: i2c at 31e0000 {
 		status = "disabled";
 	};
 
+	pwm1: pwm at 3280000 {
+		compatible = "nvidia,tegra186-pwm";
+		reg = <0x0 0x3280000 0x0 0x10000>;
+		clocks = <&bpmp TEGRA186_CLK_PWM1>;
+		clock-names = "pwm";
+		resets = <&bpmp TEGRA186_RESET_PWM1>;
+		reset-names = "pwm";
+		status = "disabled";
+		#pwm-cells = <2>;
+	};
+
+	pwm2: pwm at 3290000 {
+		compatible = "nvidia,tegra186-pwm";
+		reg = <0x0 0x3290000 0x0 0x10000>;
+		clocks = <&bpmp TEGRA186_CLK_PWM2>;
+		clock-names = "pwm";
+		resets = <&bpmp TEGRA186_RESET_PWM2>;
+		reset-names = "pwm";
+		status = "disabled";
+		#pwm-cells = <2>;
+	};
+
+	pwm3: pwm at 32a0000 {
+		compatible = "nvidia,tegra186-pwm";
+		reg = <0x0 0x32a0000 0x0 0x10000>;
+		clocks = <&bpmp TEGRA186_CLK_PWM3>;
+		clock-names = "pwm";
+		resets = <&bpmp TEGRA186_RESET_PWM3>;
+		reset-names = "pwm";
+		status = "disabled";
+		#pwm-cells = <2>;
+	};
+
+	pwm5: pwm at 32c0000 {
+		compatible = "nvidia,tegra186-pwm";
+		reg = <0x0 0x32c0000 0x0 0x10000>;
+		clocks = <&bpmp TEGRA186_CLK_PWM5>;
+		clock-names = "pwm";
+		resets = <&bpmp TEGRA186_RESET_PWM5>;
+		reset-names = "pwm";
+		status = "disabled";
+		#pwm-cells = <2>;
+	};
+
+	pwm6: pwm at 32d0000 {
+		compatible = "nvidia,tegra186-pwm";
+		reg = <0x0 0x32d0000 0x0 0x10000>;
+		clocks = <&bpmp TEGRA186_CLK_PWM6>;
+		clock-names = "pwm";
+		resets = <&bpmp TEGRA186_RESET_PWM6>;
+		reset-names = "pwm";
+		status = "disabled";
+		#pwm-cells = <2>;
+	};
+
+	pwm7: pwm at 32e0000 {
+		compatible = "nvidia,tegra186-pwm";
+		reg = <0x0 0x32e0000 0x0 0x10000>;
+		clocks = <&bpmp TEGRA186_CLK_PWM7>;
+		clock-names = "pwm";
+		resets = <&bpmp TEGRA186_RESET_PWM7>;
+		reset-names = "pwm";
+		status = "disabled";
+		#pwm-cells = <2>;
+	};
+
+	pwm8: pwm at 32f0000 {
+		compatible = "nvidia,tegra186-pwm";
+		reg = <0x0 0x32f0000 0x0 0x10000>;
+		clocks = <&bpmp TEGRA186_CLK_PWM8>;
+		clock-names = "pwm";
+		resets = <&bpmp TEGRA186_RESET_PWM8>;
+		reset-names = "pwm";
+		status = "disabled";
+		#pwm-cells = <2>;
+	};
+
 	sdmmc1: mmc at 3400000 {
 		compatible = "nvidia,tegra186-sdhci";
 		reg = <0x0 0x03400000 0x0 0x10000>;
@@ -947,6 +1024,17 @@ gpio_aon: gpio at c2f0000 {
 		#interrupt-cells = <2>;
 	};
 
+	pwm4: pwm at c340000 {
+		compatible = "nvidia,tegra186-pwm";
+		reg = <0x0 0xc340000 0x0 0x10000>;
+		clocks = <&bpmp TEGRA186_CLK_PWM4>;
+		clock-names = "pwm";
+		resets = <&bpmp TEGRA186_RESET_PWM4>;
+		reset-names = "pwm";
+		status = "disabled";
+		#pwm-cells = <2>;
+	};
+
 	pmc: pmc at c360000 {
 		compatible = "nvidia,tegra186-pmc";
 		reg = <0 0x0c360000 0 0x10000>,
-- 
2.32.0



From thierry.reding at gmail.com  Thu Aug 12 05:26:17 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 12 Aug 2021 14:26:17 +0200
Subject: [PATCH 3/3] arm64: tegra: Add NVIDIA Jetson TX2 NX Developer Kit
 support
In-Reply-To: <20210812122617.2378605-1-thierry.reding@gmail.com>
References: <20210812122617.2378605-1-thierry.reding@gmail.com>
Message-ID: <20210812122617.2378605-3-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

The Jetson TX2 NX Developer Kit is very similar to the Jetson Nano, but
uses the more powerful Tegra186 SoC.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 arch/arm64/boot/dts/nvidia/Makefile           |   1 +
 .../nvidia/tegra186-p3509-0000+p3636-0001.dts | 718 ++++++++++++++++++
 2 files changed, 719 insertions(+)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts

diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
index e13fb1070472..c80f7dc2935e 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -7,6 +7,7 @@ dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p3450-0000.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-smaug.dtb
 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2894-0050-a08.dtb
 dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-0000.dtb
+dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p3509-0000+p3636-0001.dtb
 dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p2972-0000.dtb
 dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p3509-0000+p3668-0000.dtb
 dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p3509-0000+p3668-0001.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts b/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts
new file mode 100644
index 000000000000..936b106e73db
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts
@@ -0,0 +1,718 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/mfd/max77620.h>
+
+#include "tegra186.dtsi"
+
+/ {
+	model = "NVIDIA Jetson TX2 NX Developer Kit";
+	compatible = "nvidia,p3509-0000+p3636-0001", "nvidia,tegra186";
+
+	aliases {
+		ethernet0 = "/ethernet at 2490000";
+		i2c0 = "/bpmp/i2c";
+		i2c1 = "/i2c at 3160000";
+		i2c2 = "/i2c at c240000";
+		i2c3 = "/i2c at 3180000";
+		i2c4 = "/i2c at 3190000";
+		i2c5 = "/i2c at 31c0000";
+		i2c6 = "/i2c at c250000";
+		i2c7 = "/i2c at 31e0000";
+		mmc0 = "/mmc at 3460000";
+		serial0 = &uarta;
+	};
+
+	chosen {
+		bootargs = "earlycon console=ttyS0,115200n8";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x70000000>;
+	};
+
+	ethernet at 2490000 {
+		status = "okay";
+
+		phy-reset-gpios = <&gpio_aon TEGRA186_AON_GPIO(AA, 6) GPIO_ACTIVE_LOW>;
+		phy-handle = <&phy>;
+		phy-mode = "rgmii-id";
+
+		mdio {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			phy: phy at 0 {
+				compatible = "ethernet-phy-ieee802.3-c22";
+				reg = <0x0>;
+				interrupt-parent = <&gpio_aon>;
+				interrupts = <TEGRA186_AON_GPIO(AA, 7) IRQ_TYPE_LEVEL_LOW>;
+				#phy-cells = <0>;
+			};
+		};
+	};
+
+	memory-controller at 2c00000 {
+		status = "okay";
+	};
+
+	timer at 3010000 {
+		status = "okay";
+	};
+
+	serial at 3100000 {
+		status = "okay";
+	};
+
+	i2c at 3160000 {
+		status = "okay";
+	};
+
+	i2c at 3180000 {
+		status = "okay";
+
+		power-monitor at 40 {
+			compatible = "ti,ina3221";
+			reg = <0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			channel at 0 {
+				reg = <0>;
+				label = "VDD_IN";
+				shunt-resistor-micro-ohms = <5>;
+			};
+
+			channel at 1 {
+				reg = <1>;
+				label = "VDD_CPU_GPU";
+				shunt-resistor-micro-ohms = <5>;
+			};
+
+			channel at 2 {
+				reg = <2>;
+				label = "VDD_SOC";
+				shunt-resistor-micro-ohms = <>;
+			};
+		};
+	};
+
+	ddc: i2c at 3190000 {
+		status = "okay";
+	};
+
+	i2c at 31c0000 {
+		status = "okay";
+	};
+
+	i2c at 31e0000 {
+		status = "okay";
+	};
+
+	/* SDMMC4 (eMMC) */
+	mmc at 3460000 {
+		status = "okay";
+		bus-width = <8>;
+		non-removable;
+
+		vqmmc-supply = <&vdd_1v8_ap>;
+		vmmc-supply = <&vdd_3v3_sys>;
+	};
+
+	hda at 3510000 {
+		nvidia,model = "jetson-tx2-hda";
+		status = "okay";
+	};
+
+	padctl at 3520000 {
+		status = "okay";
+
+		avdd-pll-erefeut-supply = <&vdd_1v8_pll>;
+		avdd-usb-supply = <&vdd_3v3_sys>;
+		vclamp-usb-supply = <&vdd_1v8>;
+		vddio-hsic-supply = <&gnd>;
+
+		pads {
+			usb2 {
+				status = "okay";
+
+				lanes {
+					micro_b: usb2-0 {
+						nvidia,function = "xusb";
+						status = "okay";
+					};
+
+					usb2-1 {
+						nvidia,function = "xusb";
+						status = "okay";
+					};
+
+					usb2-2 {
+						nvidia,function = "xusb";
+						status = "okay";
+					};
+				};
+			};
+
+			usb3 {
+				status = "okay";
+
+				lanes {
+					usb3-1 {
+						nvidia,function = "xusb";
+						status = "okay";
+					};
+				};
+			};
+		};
+
+		ports {
+			usb2-0 {
+				status = "okay";
+				mode = "otg";
+				vbus-supply = <&vdd_5v0_sys>;
+				usb-role-switch;
+
+				connector {
+					compatible = "gpio-usb-b-connector",
+						     "usb-b-connector";
+					label = "micro-USB";
+					type = "micro";
+					vbus-gpios = <&gpio
+						      TEGRA186_MAIN_GPIO(L, 4)
+						      GPIO_ACTIVE_LOW>;
+					id-gpios = <&pmic 0 GPIO_ACTIVE_HIGH>;
+				};
+			};
+
+			usb2-1 {
+				status = "okay";
+				mode = "host";
+
+				vbus-supply = <&vdd_5v0_sys>;
+			};
+
+			usb2-2 {
+				status = "okay";
+				mode = "host";
+
+				vbus-supply = <&vdd_5v0_sys>;
+			};
+
+			usb3-1 {
+				nvidia,usb2-companion = <1>;
+				vbus-supply = <&vdd_5v0_sys>;
+				status = "okay";
+			};
+		};
+	};
+
+	usb at 3530000 {
+		status = "okay";
+
+		phys = <&{/padctl at 3520000/pads/usb2/lanes/usb2-0}>,
+		       <&{/padctl at 3520000/pads/usb2/lanes/usb2-1}>,
+		       <&{/padctl at 3520000/pads/usb2/lanes/usb2-2}>,
+		       <&{/padctl at 3520000/pads/usb3/lanes/usb3-1}>;
+		phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-1";
+	};
+
+	usb at 3550000 {
+		status = "okay";
+
+		phys = <&micro_b>;
+		phy-names = "usb2-0";
+	};
+
+	hsp at 3c00000 {
+		status = "okay";
+	};
+
+	i2c at c240000 {
+		status = "okay";
+	};
+
+	i2c at c250000 {
+		status = "okay";
+
+		/* module ID EEPROM */
+		eeprom at 50 {
+			compatible = "atmel,24c02";
+			reg = <0x50>;
+
+			label = "module";
+			vcc-supply = <&vdd_1v8>;
+			address-width = <8>;
+			pagesize = <8>;
+			size = <256>;
+			read-only;
+		};
+
+		/* carrier board ID EEPROM */
+		eeprom at 57 {
+			compatible = "atmel,24c02";
+			reg = <0x57>;
+
+			label = "system";
+			vcc-supply = <&vdd_1v8>;
+			address-width = <8>;
+			pagesize = <8>;
+			size = <256>;
+			read-only;
+		};
+	};
+
+	rtc at c2a0000 {
+		status = "okay";
+	};
+
+	pwm at c340000 {
+		status = "okay";
+	};
+
+	pmc at c360000 {
+		nvidia,invert-interrupt;
+	};
+
+	pcie at 10003000 {
+		status = "okay";
+
+		dvdd-pex-supply = <&vdd_pex>;
+		hvdd-pex-pll-supply = <&vdd_1v8>;
+		hvdd-pex-supply = <&vdd_1v8>;
+		vddio-pexctl-aud-supply = <&vdd_1v8>;
+
+		pci at 1,0 {
+			nvidia,num-lanes = <2>;
+			status = "okay";
+		};
+
+		pci at 2,0 {
+			nvidia,num-lanes = <1>;
+			status = "disabled";
+		};
+
+		pci at 3,0 {
+			nvidia,num-lanes = <1>;
+			status = "okay";
+		};
+	};
+
+	host1x at 13e00000 {
+		status = "okay";
+
+		dpaux at 15040000 {
+			status = "okay";
+		};
+
+		display-hub at 15200000 {
+			status = "okay";
+		};
+
+		dsi at 15300000 {
+			status = "disabled";
+		};
+
+		/* DP */
+		sor at 15540000 {
+			status = "okay";
+
+			avdd-io-hdmi-dp-supply = <&vdd_hdmi_1v05>;
+			vdd-hdmi-dp-pll-supply = <&vdd_1v8_ap>;
+
+			nvidia,dpaux = <&dpaux>;
+		};
+
+		/* HDMI */
+		sor at 15580000 {
+			status = "okay";
+
+			avdd-io-hdmi-dp-supply = <&vdd_hdmi_1v05>;
+			vdd-hdmi-dp-pll-supply = <&vdd_1v8_ap>;
+			hdmi-supply = <&vdd_hdmi>;
+
+			nvidia,ddc-i2c-bus = <&ddc>;
+			nvidia,hpd-gpio = <&gpio TEGRA186_MAIN_GPIO(P, 1)
+						 GPIO_ACTIVE_LOW>;
+		};
+
+		dpaux at 155c0000 {
+			status = "okay";
+		};
+	};
+
+	gpu at 17000000 {
+		status = "okay";
+	};
+
+	fan: fan {
+		compatible = "pwm-fan";
+		pwms = <&pwm4 0 45334>;
+
+		cooling-levels = <0 64 128 255>;
+		#cooling-cells = <2>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		power {
+			label = "Power";
+			gpios = <&gpio_aon TEGRA186_AON_GPIO(FF, 0)
+					   GPIO_ACTIVE_LOW>;
+			linux,input-type = <EV_KEY>;
+			linux,code = <KEY_POWER>;
+			debounce-interval = <10>;
+			wakeup-event-action = <EV_ACT_ASSERTED>;
+			wakeup-source;
+		};
+
+		volume-up {
+			label = "Volume Up";
+			gpios = <&gpio_aon TEGRA186_AON_GPIO(FF, 1)
+					   GPIO_ACTIVE_LOW>;
+			linux,input-type = <EV_KEY>;
+			linux,code = <KEY_VOLUMEUP>;
+			debounce-interval = <10>;
+		};
+
+		volume-down {
+			label = "Volume Down";
+			gpios = <&gpio_aon TEGRA186_AON_GPIO(FF, 2)
+					   GPIO_ACTIVE_LOW>;
+			linux,input-type = <EV_KEY>;
+			linux,code = <KEY_VOLUMEDOWN>;
+			debounce-interval = <10>;
+		};
+	};
+
+	cpus {
+		cpu at 0 {
+			enable-method = "psci";
+		};
+
+		cpu at 1 {
+			enable-method = "psci";
+		};
+
+		cpu at 2 {
+			enable-method = "psci";
+		};
+
+		cpu at 3 {
+			enable-method = "psci";
+		};
+
+		cpu at 4 {
+			enable-method = "psci";
+		};
+
+		cpu at 5 {
+			enable-method = "psci";
+		};
+	};
+
+	bpmp {
+		i2c {
+			status = "okay";
+
+			pmic: pmic at 3c {
+				compatible = "maxim,max77620";
+				reg = <0x3c>;
+
+				interrupt-parent = <&pmc>;
+				interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+				#interrupt-cells = <2>;
+				interrupt-controller;
+
+				#gpio-cells = <2>;
+				gpio-controller;
+
+				pinctrl-names = "default";
+				pinctrl-0 = <&max77620_default>;
+
+				max77620_default: pinmux {
+					gpio0 {
+						pins = "gpio0";
+						function = "gpio";
+					};
+
+					gpio1 {
+						pins = "gpio1";
+						function = "fps-out";
+						maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
+					};
+
+					gpio2 {
+						pins = "gpio2";
+						function = "fps-out";
+						maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
+					};
+
+					gpio3 {
+						pins = "gpio3";
+						function = "fps-out";
+						maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
+					};
+
+					gpio4 {
+						pins = "gpio4";
+						function = "32k-out1";
+						drive-push-pull = <1>;
+					};
+
+					gpio5 {
+						pins = "gpio5";
+						function = "gpio";
+						drive-push-pull = <0>;
+					};
+
+					gpio6 {
+						pins = "gpio6";
+						function = "gpio";
+						drive-push-pull = <1>;
+					};
+
+					gpio7 {
+						pins = "gpio7";
+						function = "gpio";
+						drive-push-pull = <1>;
+					};
+				};
+
+				fps {
+					fps0 {
+						maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
+						maxim,shutdown-fps-time-period-us = <640>;
+					};
+
+					fps1 {
+						maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
+						maxim,shutdown-fps-time-period-us = <640>;
+					};
+
+					fps2 {
+						maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
+						maxim,shutdown-fps-time-period-us = <640>;
+					};
+				};
+
+				regulators {
+					in-sd0-supply = <&vdd_5v0_sys>;
+					in-sd1-supply = <&vdd_5v0_sys>;
+					in-sd2-supply = <&vdd_5v0_sys>;
+					in-sd3-supply = <&vdd_5v0_sys>;
+
+					in-ldo0-1-supply = <&vdd_5v0_sys>;
+					in-ldo2-supply = <&vdd_5v0_sys>;
+					in-ldo3-5-supply = <&vdd_5v0_sys>;
+					in-ldo4-6-supply = <&vdd_1v8>;
+					in-ldo7-8-supply = <&avdd_dsi_csi>;
+
+					sd0 {
+						regulator-name = "VDD_DDR_1V1_PMIC";
+						regulator-min-microvolt = <1100000>;
+						regulator-max-microvolt = <1100000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					avdd_dsi_csi: sd1 {
+						regulator-name = "AVDD_DSI_CSI_1V2";
+						regulator-min-microvolt = <1200000>;
+						regulator-max-microvolt = <1200000>;
+					};
+
+					vdd_1v8: sd2 {
+						regulator-name = "VDD_1V8";
+						regulator-min-microvolt = <1800000>;
+						regulator-max-microvolt = <1800000>;
+					};
+
+					vdd_3v3_sys: sd3 {
+						regulator-name = "VDD_3V3_SYS";
+						regulator-min-microvolt = <3300000>;
+						regulator-max-microvolt = <3300000>;
+					};
+
+					vdd_1v8_pll: ldo0 {
+						regulator-name = "VDD_1V8_AP_PLL";
+						regulator-min-microvolt = <1800000>;
+						regulator-max-microvolt = <1800000>;
+					};
+
+					ldo2 {
+						regulator-name = "VDDIO_3V3_AOHV";
+						regulator-min-microvolt = <3300000>;
+						regulator-max-microvolt = <3300000>;
+						regulator-always-on;
+						regulator-boot-on;
+					};
+
+					vddio_sdmmc1: ldo3 {
+						regulator-name = "VDDIO_SDMMC1_AP";
+						regulator-min-microvolt = <1800000>;
+						regulator-max-microvolt = <3300000>;
+					};
+
+					ldo4 {
+						regulator-name = "VDD_RTC";
+						regulator-min-microvolt = <1000000>;
+						regulator-max-microvolt = <1000000>;
+					};
+
+					vddio_sdmmc3: ldo5 {
+						regulator-name = "VDDIO_SDMMC3_AP";
+						regulator-min-microvolt = <2800000>;
+						regulator-max-microvolt = <2800000>;
+					};
+
+					vdd_hdmi_1v05: ldo7 {
+						regulator-name = "VDD_HDMI_1V05";
+						regulator-min-microvolt = <1050000>;
+						regulator-max-microvolt = <1050000>;
+					};
+
+					vdd_pex: ldo8 {
+						regulator-name = "VDD_PEX_1V05";
+						regulator-min-microvolt = <1050000>;
+						regulator-max-microvolt = <1050000>;
+					};
+				};
+			};
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		status = "okay";
+		method = "smc";
+	};
+
+	gnd: regulator at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "GND";
+		regulator-min-microvolt = <0>;
+		regulator-max-microvolt = <0>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vdd_5v0_sys: regulator at 1 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDD_5V0_SYS";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+		regulator-boot-on;
+	};
+
+	vdd_1v8_ap: regulator at 2 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDD_1V8_AP";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+
+		gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+
+		vin-supply = <&vdd_1v8>;
+	};
+
+	vdd_hdmi: regulator at 3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDD_5V0_HDMI_CON";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+
+		vin-supply = <&vdd_5v0_sys>;
+	};
+
+	thermal-zones {
+		cpu {
+			polling-delay = <0>;
+			polling-delay-passive = <500>;
+			status = "okay";
+
+			trips {
+				cpu_trip_critical: critical {
+					temperature = <96500>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+
+				cpu_trip_hot: hot {
+					temperature = <79000>;
+					hysteresis = <2000>;
+					type = "hot";
+				};
+
+				cpu_trip_active: active {
+					temperature = <62000>;
+					hysteresis = <2000>;
+					type = "active";
+				};
+
+				cpu_trip_passive: passive {
+					temperature = <45000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+			};
+
+			cooling-maps {
+				cpu-critical {
+					cooling-device = <&fan 3 3>;
+					trip = <&cpu_trip_critical>;
+				};
+
+				cpu-hot {
+					cooling-device = <&fan 2 2>;
+					trip = <&cpu_trip_hot>;
+				};
+
+				cpu-active {
+					cooling-device = <&fan 1 1>;
+					trip = <&cpu_trip_active>;
+				};
+
+				cpu-passive {
+					cooling-device = <&fan 0 0>;
+					trip = <&cpu_trip_passive>;
+				};
+			};
+		};
+
+		gpu {
+			polling-delay = <0>;
+			polling-delay-passive = <500>;
+			status = "okay";
+
+			trips {
+				gpu_alert0: critical {
+					temperature = <99000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+
+		aux {
+			polling-delay = <0>;
+			polling-delay-passive = <500>;
+			status = "okay";
+
+			trips {
+				aux_alert0: critical {
+					temperature = <90000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+	};
+};
-- 
2.32.0



From zajec5 at gmail.com  Thu Aug 12 05:29:56 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Thu, 12 Aug 2021 14:29:56 +0200
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <875ywb9dj7.wl-maz@kernel.org>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
 <878s179jsq.wl-maz@kernel.org>
 <764732f3-6cd7-bd18-4c83-1b851c29b2a4@gmail.com>
 <875ywb9dj7.wl-maz@kernel.org>
Message-ID: <d8ad8fde-ae94-3cc6-06f8-b0ad6d5e27b7@gmail.com>

On 12.08.2021 12:13, Marc Zyngier wrote:
> On Thu, 12 Aug 2021 09:24:14 +0100,
> Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>>
>> On 12.08.2021 09:57, Marc Zyngier wrote:
>>> On Thu, 12 Aug 2021 08:32:02 +0100,
>>> Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>>>>
>>>> On 12.08.2021 08:51, Marc Zyngier wrote:
>>>>> Interestingly, all your CPUs are booting at EL2. Which is great.  Can
>>>>> you try and enable KVM on your existing 5.10 kernel? Just selecting
>>>>> CONFIG_KVM should be enough. Does it boot correctly with KVM enabled?
>>>>>
>>>>> My suspicion is that the firmware doesn't set SCR_EL3.HCE, and that
>>>>> the HVC instruction UNDEFs at EL1. That would be bad news.
>>>>
>>>> Interesting! I had to enable CONFIG_VIRTUALIZATION and CONFIG_NET first.
>>>> First I verified kernel built with those options still boots. It does.
>>>>
>>>> Then I enabled CONFIG_KVM and kernel seems to hang around switching from
>>>> bootconsole to the console.
>>>>
>>>> Starting program at 0x0000000000080000
>>>> /memory = 0x40000000
>>>> WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
>>>> WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
>>>> WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
>>>> Booting Linux on physical CPU 0x0000000000 [0x420f1000]
>>>> Linux version 5.11.22-g0453a426c37b (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #8 SMP Thu Aug 12 09:25:55 CEST 2021
>>>> Machine model: Asus GT-AC5300
>>>> earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
>>>> printk: bootconsole [bcm63xx_uart0] enabled
>>>> efi: UEFI not found.
>>>> [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
>>>> Zone ranges:
>>>>     DMA      [mem 0x0000000000000000-0x000000003fffffff]
>>>>     DMA32    empty
>>>>     Normal   empty
>>>> Movable zone start for each node
>>>> Early memory node ranges
>>>>     node   0: [mem 0x0000000000000000-0x000000003fffffff]
>>>> Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
>>>> percpu: Embedded 18 pages/cpu s43904 r0 d29824 u73728
>>>> Detected VIPT I-cache on CPU0
>>>> CPU features: detected: ARM erratum 843419
>>>> Built 1 zonelists, mobility grouping on.  Total pages: 258048
>>>> Kernel command line: earlycon=bcm63xx_uart,0xff800640
>>>> Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
>>>> Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
>>>> mem auto-init: stack:off, heap alloc:off, heap free:off
>>>> Memory: 1019556K/1048576K available (4352K kernel code, 678K rwdata, 860K rodata, 2496K init, 232K bss, 29020K reserved, 0K cma-reserved)
>>>> SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
>>>> rcu: Hierarchical RCU implementation.
>>>> rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
>>>> NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
>>>> GIC: Using split EOI/Deactivate mode
>>>> random: get_random_bytes called from start_kernel+0x33c/0x52c with crng_init=0
>>>> arch_timer: cp15 timer(s) running at 50.00MHz (phys).
>>>> clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
>>>> sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
>>>> Console: colour dummy device 80x25
>>>> printk: console [tty0] enabled
>>>> printk: bootconsole [bcm63xx_uart0] disabled
>>>>
>>>>
>>>> (Unless it's a false conclusion and CONFIG_KVM just breaks console
>>>> somehow)
>>>
>>> No, that's because you don't pass the right console to your
>>> kernel. Add something like "console=ttyS0,115200" to the kernel
>>> command line, which will show what you are missing, as well as stop
>>> the double-logging.
>>>
>>> Anyway, the fact that it stops booting when you enable KVM confirms my
>>> suspicion. The firmware on this system is probably crap enough not to
>>> enable HVC. Let's confirm it further: please apply the patch below on
>>> top of mainline and tell me that it now boots fine...
>>
>> Thanks for the patch! It workarounds the issue. See below.
>>
>>
>>> Are you in a position where you can actually fix the firmware? Or is
>>> it some closed-source blob?
>>
>> I'm just an end-user with no access to CFE sources and without any
>> business contact as Broadcom :(
> 
> I feared that would be the case. Florian's reply seems to indicate
> that the "upstream" firmware implementation is correct, so the OEM
> must have fumbled it somehow...

Please note that Broadcom has many business units, many teams and from
my understanding they often don't cooperate properly.

It's likely that BCM4908 BU screwed something up. Or maybe it's a matter
of CFE vs. U-Boot?

Florian: does your team (set-top box and cable modem devices) use CFE or
U-Boot with kernels 5.12+?

It's very unlikely it's a single OEM that broke CFE with custom
modifications. This problem affects all 3 devices I own:
1. Netgear R8000P
2. TP-Link Archer C2300 V1
3. Asus GT-AC5300


>>> diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
>>> index 43d212618834..fc95b103ef42 100644
>>> --- a/arch/arm64/kernel/hyp-stub.S
>>> +++ b/arch/arm64/kernel/hyp-stub.S
>>> @@ -238,7 +238,7 @@ SYM_FUNC_START(switch_to_vhe)
>>>      	// Turn the world upside down
>>>    	mov	x0, #HVC_VHE_RESTART
>>> -	hvc	#0
>>> +//	hvc	#0
>>>    1:
>>>    	ret
>>>    SYM_FUNC_END(switch_to_vhe)
>>
>> This allows me to boot 5.13.9 and 5.14-rc5 without any reverts!
>>
>> Enabling CONFIG_KVM still results in the:
>> Kernel panic - not syncing: Oops - BUG: Fatal exception in interrupt
> 
> That's expected. Can you please check the patch below? It should
> result in a booting kernel which actually survives having KVM compiled
> in. It should even display a warning telling you that your setup is
> completely buggered.
> 
> That's obviously not the final version, but probably a good enough
> approximation.

It seems to work! Kernel has booted and I saw:
CPU: CPUs started in inconsistent modes
WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/smp.c:426 smp_cpus_done+0x8c/0xc8
(...)
kvm [1]: HYP mode not available


Starting program at 0x0000000000080000
/memory = 0x40000000
WARNING: Node's property /reserved-memory/dt_reserved_buffer is not defined
WARNING: Node's property /reserved-memory/dt_reserved_flow is not defined
WARNING: Node's property /reserved-memory/dt_reserved_dhd2 is not defined
Booting Linux on physical CPU 0x0000000000 [0x420f1000]
Linux version 5.14.0-rc5-g8bad1731c752-dirty (rmilecki at localhost.localdomain) (aarch64-buildroot-linux-uclibc-gcc.br_real (Buildroot -g91617ed) 9.3.0, GNU ld (GNU Binutils) 2.33.1) #23 SMP Thu Aug 12 14:20:52 CEST 2021
Machine model: Asus GT-AC5300
earlycon: bcm63xx_uart0 at MMIO 0x00000000ff800640 (options '')
printk: bootconsole [bcm63xx_uart0] enabled
efi: UEFI not found.
[Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader!
Zone ranges:
   DMA      [mem 0x0000000000000000-0x000000003fffffff]
   DMA32    empty
   Normal   empty
Movable zone start for each node
Early memory node ranges
   node   0: [mem 0x0000000000000000-0x000000003fffffff]
Initmem setup node 0 [mem 0x0000000000000000-0x000000003fffffff]
percpu: Embedded 18 pages/cpu s44568 r0 d29160 u73728
Detected VIPT I-cache on CPU0
CPU features: detected: ARM erratum 843419
Built 1 zonelists, mobility grouping on.  Total pages: 258048
Kernel command line: earlycon=bcm63xx_uart,0xff800640 console=ttyS0,115200
Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
mem auto-init: stack:off, heap alloc:off, heap free:off
Memory: 1017496K/1048576K available (5824K kernel code, 762K rwdata, 1100K rodata, 2624K init, 259K bss, 31080K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
Root IRQ handler: gic_handle_irq
random: get_random_bytes called from start_kernel+0x4a0/0x6dc with crng_init=0
arch_timer: cp15 timer(s) running at 50.00MHz (virt).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
Console: colour dummy device 80x25
Calibrating delay loop (skipped), value calculated using timer frequency.. 100.00 BogoMIPS (lpj=200000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
rcu: Hierarchical SRCU implementation.
EFI services will not be available.
smp: Bringing up secondary CPUs ...
Detected VIPT I-cache on CPU1
CPU1: Booted secondary processor 0x0000000001 [0x420f1000]
Detected VIPT I-cache on CPU2
CPU2: Booted secondary processor 0x0000000002 [0x420f1000]
Detected VIPT I-cache on CPU3
CPU3: Booted secondary processor 0x0000000003 [0x420f1000]
smp: Brought up 1 node, 4 CPUs
SMP: Total of 4 processors activated.
CPU features: detected: 32-bit EL0 Support
CPU features: detected: 32-bit EL1 Support
CPU features: detected: CRC32 instructions
------------[ cut here ]------------
CPU: CPUs started in inconsistent modes
WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/smp.c:426 smp_cpus_done+0x8c/0xc8
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.14.0-rc5-g8bad1731c752-dirty #23
Hardware name: Asus GT-AC5300 (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
pc : smp_cpus_done+0x8c/0xc8
lr : smp_cpus_done+0x8c/0xc8
sp : ffffffc01002be00
x29: ffffffc01002be00 x28: 0000000000000000 x27: 0000000000000000
x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
x23: ffffffc010ab4000 x22: 0000000000000000 x21: 0000000000000000
x20: ffffffc0107b7e74 x19: ffffffc010a78000 x18: 0000000000000001
x17: ffffffc010a9ee40 x16: 0000000000000000 x15: 0000424c5a953180
x14: fffffffffffc0ef7 x13: 0000000000000037 x12: ffffff80010b03b0
x11: 00000000ffffffea x10: ffffffc010a5eb50 x9 : 0000000000000001
x8 : 0000000000000001 x7 : 0000000000017fe8 x6 : c0000000ffffefff
x5 : 0000000000057fa8 x4 : 0000000000000000 x3 : 0000000000000000
x2 : 00000000ffffffff x1 : 33e2e90440df2000 x0 : 0000000000000000
Call trace:
  smp_cpus_done+0x8c/0xc8
  smp_init+0x68/0x78
  kernel_init_freeable+0xd0/0x214
  kernel_init+0x24/0x120
  ret_from_fork+0x10/0x18
---[ end trace 773cbee471955c5a ]---
alternatives: patching kernel code
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
pinctrl core: initialized pinctrl subsystem
DMI not present or invalid.
NET: Registered PF_NETLINK/PF_ROUTE protocol family
DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
thermal_sys: Registered thermal governor 'step_wise'
ASID allocator initialised with 65536 entries
iommu: Default domain type: Translated
vgaarb: loaded
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
clocksource: Switched to clocksource arch_sys_counter
NET: Registered PF_INET protocol family
IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
TCP: Hash tables configured (established 8192 bind 8192)
UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
NET: Registered PF_UNIX/PF_LOCAL protocol family
PCI: CLS 0 bytes, default 64
kvm [1]: HYP mode not available
workingset: timestamp_bits=62 max_order=18 bucket_order=0
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
io scheduler mq-deadline registered
io scheduler kyber registered
????? console [ttyS0] enabled 0xff800640 (irq = 24, base_baud = 1562500) is a bcm63xx_uart
printk: console [ttyS0] enabled
printk: bootconsole [bcm63xx_uart0] disabled
printk: bootconsole [bcm63xx_uart0] disabled
nand: device found, Manufacturer ID: 0xc8, Chip ID: 0xda
nand: ESMT NAND 256MiB 3,3V 8-bit
nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
bcm63138_nand ff801800.nand: detected 256MiB total, 128KiB blocks, 2KiB pages, 16B OOB, 8-bit, BCH-4
Bad block table found at page 131008, version 0x01
Bad block table found at page 130944, version 0x01
3 fixed-partitions partitions found on MTD device brcmnand.0
Creating 3 MTD partitions on "brcmnand.0":
0x000000000000-0x000000100000 : "cferom"
0x000000100000-0x000005800000 : "firmware"
0x000005800000-0x00000af00000 : "backup"
libphy: Fixed MDIO Bus: probed
libphy: unimac MII bus: probed
unimac-mdio 800c05c0.mdio: Broadcom UniMAC MDIO bus
libphy: sf2 slave mii: probed
brcm-sf2 80080000.ethernet-switch: found switch: BCM4908, rev 0
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ehci-platform: EHCI generic platform driver
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
ohci-pci: OHCI PCI platform driver
ohci-platform: OHCI generic platform driver
i2c /dev entries driver
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
NET: Registered PF_INET6 protocol family
Segment Routing with IPv6
sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
NET: Registered PF_PACKET protocol family
8021q: 802.1Q VLAN Support v1.8
brcmstb-usb-phy 8000c200.usb-phy: Clock not found in Device Tree
brcmstb-usb-phy 8000c200.usb-phy: USB3.0 clock not found in Device Tree
brcmstb-usb-phy 8000c200.usb-phy: Suspend Clock not found in Device Tree
brcmstb-usb-phy 8000c200.usb-phy: IRQ wake not found
brcmstb-usb-phy 8000c200.usb-phy: IRQ wakeup not found
brcmstb-usb-phy 8000c200.usb-phy: Wake interrupt missing, system wake not supported
libphy: sf2 slave mii: probed
brcm-sf2 80080000.ethernet-switch: found switch: BCM4908, rev 0
brcm-sf2 80080000.ethernet-switch lan2 (uninitialized): PHY [800c05c0.mdio--1:08] driver [Generic PHY] (irq=POLL)
brcm-sf2 80080000.ethernet-switch lan1 (uninitialized): PHY [800c05c0.mdio--1:09] driver [Generic PHY] (irq=POLL)
brcm-sf2 80080000.ethernet-switch lan6 (uninitialized): PHY [800c05c0.mdio--1:0a] driver [Generic PHY] (irq=POLL)
brcm-sf2 80080000.ethernet-switch lan5 (uninitialized): PHY [800c05c0.mdio--1:0b] driver [Generic PHY] (irq=POLL)
brcm-sf2 80080000.ethernet-switch: configuring for fixed/internal link mode
eth0: mtu greater than device maximum
bcm4908_enet 80002000.ethernet eth0: error -22 setting MTU to 1504 to include DSA overhead
DSA: tree 0 setup
brcm-sf2 80080000.ethernet-switch: Starfighter 2 top: 4.07, core: 5.00, IRQs: 22, 23
brcm-sf2 80080000.ethernet-switch: Link is Up - 1Gbps/Full - flow control off
ehci-platform 8000c300.usb: EHCI Host Controller
ehci-platform 8000c300.usb: new USB bus registered, assigned bus number 1
ehci-platform 8000c300.usb: irq 19, io mem 0x8000c300
ehci-platform 8000c300.usb: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
ohci-platform 8000c400.usb: Generic Platform OHCI controller
ohci-platform 8000c400.usb: new USB bus registered, assigned bus number 2
ohci-platform 8000c400.usb: irq 20, io mem 0x8000c400
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 2 ports detected
xhci-hcd 8000d000.usb: xHCI Host Controller
xhci-hcd 8000d000.usb: new USB bus registered, assigned bus number 3
xhci-hcd 8000d000.usb: hcc params 0x0250f17c hci version 0x100 quirks 0x0000000000010010
xhci-hcd 8000d000.usb: irq 21, io mem 0x8000d000
hub 3-0:1.0: USB hub found
hub 3-0:1.0: config failed, hub doesn't have any ports! (err -19)
xhci-hcd 8000d000.usb: xHCI Host Controller
xhci-hcd 8000d000.usb: new USB bus registered, assigned bus number 4
xhci-hcd 8000d000.usb: Host supports USB 3.0 SuperSpeed
usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
hub 4-0:1.0: USB hub found
hub 4-0:1.0: 2 ports detected
Freeing unused kernel memory: 2624K
Run /init as init process
tmpfs: Unknown parameter 'mode'
mount: mounting tmpfs: Unknown parameter 'mode'
tmpfs on /dev/shtmpfs: Unknown parameter 'mode'
m failed: Invalid argument
mount: mounting tmpfs on /tmp failed: Invalid argument
mount: mounting tmpfs on /run failed: Invalid argument
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Savrandom: dd: uninitialized urandom read (512 bytes read)
ing random seed: OK
Starting network: brcm-sf2 80080000.ethernet-switch lan1: configuring for phy/internal link mode
8021q: adding VLAN 0 to HW filter on device lan1
brcm-sf2 80080000.ethernet-switch lan2: configuring for phy/internal link mode
8021q: adding VLAN 0 to HW filter on device lan2
br-lan: port 1(lan1) entered blocking state
br-lan: port 1(lan1) entered disabled state
device lan1 entered promiscuous mode
device eth0 entered promiscuous mode
br-lan: port 2(lan2) entered blocking state
br-lan: port 2(lan2) entered disabled state
device lan2 entered promiscuous mode
OK

Welcome to Buildroot
buildroot login: brcm-sf2 80080000.ethernet-switch lan1: Link is Up - 1Gbps/Full - flow control rx/tx
IPv6: ADDRCONF(NETDEV_CHANGE): lan1: link becomes ready
br-lan: port 1(lan1) entered blocking state
br-lan: port 1(lan1) entered forwarding state
IPv6: ADDRCONF(NETDEV_CHANGE): br-lan: link becomes ready

Welcome to Buildroot
buildroot login:


From wangkefeng.wang at huawei.com  Thu Aug 12 05:36:02 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Thu, 12 Aug 2021 20:36:02 +0800
Subject: [PATCH -next] trap: Cleanup trap_init()
Message-ID: <20210812123602.76356-1-wangkefeng.wang@huawei.com>

There are some empty trap_init() in different ARCHs, introduce
a new weak trap_init() function to cleanup them.

Cc: Vineet Gupta <vgupta at kernel.org>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Yoshinori Sato <ysato at users.sourceforge.jp>
Cc: Ley Foon Tan <ley.foon.tan at intel.com>
Cc: Jonas Bonn <jonas at southpole.se>
Cc: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
Cc: Stafford Horne <shorne at gmail.com>
Cc: James E.J. Bottomley <James.Bottomley at HansenPartnership.com>
Cc: Helge Deller <deller at gmx.de>
Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Cc: Paul Mackerras <paulus at samba.org>
Cc: Paul Walmsley <palmerdabbelt at google.com>
Cc: Jeff Dike <jdike at addtoit.com>
Cc: Richard Weinberger <richard at nod.at>
Cc: Anton Ivanov <anton.ivanov at cambridgegreys.com>
Cc: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 arch/arc/kernel/traps.c      | 5 -----
 arch/arm/kernel/traps.c      | 5 -----
 arch/h8300/kernel/traps.c    | 4 ----
 arch/hexagon/kernel/traps.c  | 4 ----
 arch/nds32/kernel/traps.c    | 5 -----
 arch/nios2/kernel/traps.c    | 5 -----
 arch/openrisc/kernel/traps.c | 5 -----
 arch/parisc/kernel/traps.c   | 4 ----
 arch/powerpc/kernel/traps.c  | 5 -----
 arch/riscv/kernel/traps.c    | 5 -----
 arch/um/kernel/trap.c        | 4 ----
 init/main.c                  | 2 ++
 12 files changed, 2 insertions(+), 51 deletions(-)

diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c
index 57235e5c0cea..6b83e3f2b41c 100644
--- a/arch/arc/kernel/traps.c
+++ b/arch/arc/kernel/traps.c
@@ -20,11 +20,6 @@
 #include <asm/unaligned.h>
 #include <asm/kprobes.h>
 
-void __init trap_init(void)
-{
-	return;
-}
-
 void die(const char *str, struct pt_regs *regs, unsigned long address)
 {
 	show_kernel_fault_diag(str, regs, address);
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 64308e3a5d0c..e9b4f2b49bd8 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -781,11 +781,6 @@ void abort(void)
 	panic("Oops failed to kill thread");
 }
 
-void __init trap_init(void)
-{
-	return;
-}
-
 #ifdef CONFIG_KUSER_HELPERS
 static void __init kuser_init(void *vectors)
 {
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
index 5d8b969cd8f3..bdbe988d8dbc 100644
--- a/arch/h8300/kernel/traps.c
+++ b/arch/h8300/kernel/traps.c
@@ -39,10 +39,6 @@ void __init base_trap_init(void)
 {
 }
 
-void __init trap_init(void)
-{
-}
-
 asmlinkage void set_esp0(unsigned long ssp)
 {
 	current->thread.esp0 = ssp;
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index 904134b37232..edfc35dafeb1 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -28,10 +28,6 @@
 #define TRAP_SYSCALL	1
 #define TRAP_DEBUG	0xdb
 
-void __init trap_init(void)
-{
-}
-
 #ifdef CONFIG_GENERIC_BUG
 /* Maybe should resemble arch/sh/kernel/traps.c ?? */
 int is_valid_bugaddr(unsigned long addr)
diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
index ee0d9ae192a5..f06421c645af 100644
--- a/arch/nds32/kernel/traps.c
+++ b/arch/nds32/kernel/traps.c
@@ -183,11 +183,6 @@ void __pgd_error(const char *file, int line, unsigned long val)
 }
 
 extern char *exception_vector, *exception_vector_end;
-void __init trap_init(void)
-{
-	return;
-}
-
 void __init early_trap_init(void)
 {
 	unsigned long ivb = 0;
diff --git a/arch/nios2/kernel/traps.c b/arch/nios2/kernel/traps.c
index b172da4eb1a9..596986a74a26 100644
--- a/arch/nios2/kernel/traps.c
+++ b/arch/nios2/kernel/traps.c
@@ -105,11 +105,6 @@ void show_stack(struct task_struct *task, unsigned long *stack,
 	printk("%s\n", loglvl);
 }
 
-void __init trap_init(void)
-{
-	/* Nothing to do here */
-}
-
 /* Breakpoint handler */
 asmlinkage void breakpoint_c(struct pt_regs *fp)
 {
diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 4d61333c2623..aa1e709405ac 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -231,11 +231,6 @@ void unhandled_exception(struct pt_regs *regs, int ea, int vector)
 	die("Oops", regs, 9);
 }
 
-void __init trap_init(void)
-{
-	/* Nothing needs to be done */
-}
-
 asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
 {
 	force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 8d8441d4562a..747c328fb886 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -859,7 +859,3 @@ void  __init early_trap_init(void)
 
 	initialize_ivt(&fault_vector_20);
 }
-
-void __init trap_init(void)
-{
-}
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index e103b89234cd..91efb5c6f2f3 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -2209,11 +2209,6 @@ DEFINE_INTERRUPT_HANDLER(kernel_bad_stack)
 	die("Bad kernel stack pointer", regs, SIGABRT);
 }
 
-void __init trap_init(void)
-{
-}
-
-
 #ifdef CONFIG_PPC_EMULATED_STATS
 
 #define WARN_EMULATED_SETUP(type)	.type = { .name = #type }
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 0a98fd0ddfe9..0daaa3e4630d 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -199,11 +199,6 @@ int is_valid_bugaddr(unsigned long pc)
 }
 #endif /* CONFIG_GENERIC_BUG */
 
-/* stvec & scratch is already set from head.S */
-void __init trap_init(void)
-{
-}
-
 #ifdef CONFIG_VMAP_STACK
 static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)],
 		overflow_stack)__aligned(16);
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index ad12f78bda7e..3198c4767387 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -311,7 +311,3 @@ void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
 {
 	do_IRQ(WINCH_IRQ, regs);
 }
-
-void trap_init(void)
-{
-}
diff --git a/init/main.c b/init/main.c
index 4b4897b791fd..863e5087263d 100644
--- a/init/main.c
+++ b/init/main.c
@@ -775,6 +775,8 @@ void __init __weak poking_init(void) { }
 
 void __init __weak pgtable_cache_init(void) { }
 
+void __init __weak trap_init(void) { }
+
 bool initcall_debug;
 core_param(initcall_debug, initcall_debug, bool, 0644);
 
-- 
2.26.2



From linux at armlinux.org.uk  Thu Aug 12 05:41:41 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 12 Aug 2021 13:41:41 +0100
Subject: [PATCH -next] trap: Cleanup trap_init()
In-Reply-To: <20210812123602.76356-1-wangkefeng.wang@huawei.com>
References: <20210812123602.76356-1-wangkefeng.wang@huawei.com>
Message-ID: <20210812124141.GY22278@shell.armlinux.org.uk>

On Thu, Aug 12, 2021 at 08:36:02PM +0800, Kefeng Wang wrote:
> There are some empty trap_init() in different ARCHs, introduce
> a new weak trap_init() function to cleanup them.
> 
> Cc: Vineet Gupta <vgupta at kernel.org>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Yoshinori Sato <ysato at users.sourceforge.jp>
> Cc: Ley Foon Tan <ley.foon.tan at intel.com>
> Cc: Jonas Bonn <jonas at southpole.se>
> Cc: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
> Cc: Stafford Horne <shorne at gmail.com>
> Cc: James E.J. Bottomley <James.Bottomley at HansenPartnership.com>
> Cc: Helge Deller <deller at gmx.de>
> Cc: Michael Ellerman <mpe at ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> Cc: Paul Mackerras <paulus at samba.org>
> Cc: Paul Walmsley <palmerdabbelt at google.com>
> Cc: Jeff Dike <jdike at addtoit.com>
> Cc: Richard Weinberger <richard at nod.at>
> Cc: Anton Ivanov <anton.ivanov at cambridgegreys.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>

For 32-bit arm:

Acked-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From maz at kernel.org  Thu Aug 12 05:57:46 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 13:57:46 +0100
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <d8ad8fde-ae94-3cc6-06f8-b0ad6d5e27b7@gmail.com>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
 <878s179jsq.wl-maz@kernel.org>
 <764732f3-6cd7-bd18-4c83-1b851c29b2a4@gmail.com>
 <875ywb9dj7.wl-maz@kernel.org>
 <d8ad8fde-ae94-3cc6-06f8-b0ad6d5e27b7@gmail.com>
Message-ID: <8735reakhh.wl-maz@kernel.org>

On Thu, 12 Aug 2021 13:29:56 +0100,
Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> 
> On 12.08.2021 12:13, Marc Zyngier wrote:
> > On Thu, 12 Aug 2021 09:24:14 +0100,
> > Rafa? Mi?ecki <zajec5 at gmail.com> wrote:

[...]

> >> I'm just an end-user with no access to CFE sources and without any
> >> business contact as Broadcom :(
> > 
> > I feared that would be the case. Florian's reply seems to indicate
> > that the "upstream" firmware implementation is correct, so the OEM
> > must have fumbled it somehow...
> 
> Please note that Broadcom has many business units, many teams and from
> my understanding they often don't cooperate properly.

I bet some team sampled an early version of the firmware that included
the bug and never looked back. You can also tell the level of quality
by the fact that it uses spin-tables to boot, that the interrupt
controller node is incomplete...

> It's likely that BCM4908 BU screwed something up. Or maybe it's a matter
> of CFE vs. U-Boot?

It is a matter of whatever is running at EL3 and doing the basic setup
of the CPUs.
> 
> Florian: does your team (set-top box and cable modem devices) use CFE or
> U-Boot with kernels 5.12+?
> 
> It's very unlikely it's a single OEM that broke CFE with custom
> modifications. This problem affects all 3 devices I own:
> 1. Netgear R8000P
> 2. TP-Link Archer C2300 V1
> 3. Asus GT-AC5300

They probably all use the same pre-cast design with some sort of
value-add on top.

[...]

> > That's expected. Can you please check the patch below? It should
> > result in a booting kernel which actually survives having KVM compiled
> > in. It should even display a warning telling you that your setup is
> > completely buggered.
> > 
> > That's obviously not the final version, but probably a good enough
> > approximation.
> 
> It seems to work! Kernel has booted and I saw:
> CPU: CPUs started in inconsistent modes
> WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/smp.c:426 smp_cpus_done+0x8c/0xc8
> (...)
> kvm [1]: HYP mode not available

Right. So there is some hope. Maybe. I'm not sure I want to maintain
this crap though.

[...]

> nand: device found, Manufacturer ID: 0xc8, Chip ID: 0xda
> nand: ESMT NAND 256MiB 3,3V 8-bit
> nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
> bcm63138_nand ff801800.nand: detected 256MiB total, 128KiB blocks, 2KiB pages, 16B OOB, 8-bit, BCH-4
> Bad block table found at page 131008, version 0x01
> Bad block table found at page 130944, version 0x01
> 3 fixed-partitions partitions found on MTD device brcmnand.0
> Creating 3 MTD partitions on "brcmnand.0":
> 0x000000000000-0x000000100000 : "cferom"
> 0x000000100000-0x000005800000 : "firmware"
> 0x000005800000-0x00000af00000 : "backup"

So here's your chance! You have the firmware image here (I guess
"cferom" is the one). It'd be interesting to disassemble it, find out
where SCR_EL3 is set, patch it and never look back.

Only kidding.

	M.

-- 
Without deviation from the norm, progress is not possible.


From tabba at google.com  Thu Aug 12 06:08:36 2021
From: tabba at google.com (Fuad Tabba)
Date: Thu, 12 Aug 2021 15:08:36 +0200
Subject: [PATCH v3 14/15] KVM: arm64: Handle protected guests at 32 bits
In-Reply-To: <20210812095743.GL5912@willie-the-truck>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-15-tabba@google.com>
 <20210812095743.GL5912@willie-the-truck>
Message-ID: <CA+EHjTzE1w-ePBw+JZw-+ScSKWYExKw9HNTo8rNJAJnAUNf6tw@mail.gmail.com>

Hi Will,


On Thu, Aug 12, 2021 at 11:57 AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Jul 19, 2021 at 05:03:45PM +0100, Fuad Tabba wrote:
> > Protected KVM does not support protected AArch32 guests. However,
> > it is possible for the guest to force run AArch32, potentially
> > causing problems. Add an extra check so that if the hypervisor
> > catches the guest doing that, it can prevent the guest from
> > running again by resetting vcpu->arch.target and returning
> > ARM_EXCEPTION_IL.
> >
> > Adapted from commit 22f553842b14 ("KVM: arm64: Handle Asymmetric
> > AArch32 systems")
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/hyp/switch.h | 24 ++++++++++++++++++++++++
> >  1 file changed, 24 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > index 8431f1514280..f09343e15a80 100644
> > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > @@ -23,6 +23,7 @@
> >  #include <asm/kprobes.h>
> >  #include <asm/kvm_asm.h>
> >  #include <asm/kvm_emulate.h>
> > +#include <asm/kvm_fixed_config.h>
> >  #include <asm/kvm_hyp.h>
> >  #include <asm/kvm_mmu.h>
> >  #include <asm/fpsimd.h>
> > @@ -477,6 +478,29 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
> >                       write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
> >       }
> >
> > +     /*
> > +      * Protected VMs might not be allowed to run in AArch32. The check below
> > +      * is based on the one in kvm_arch_vcpu_ioctl_run().
> > +      * The ARMv8 architecture doesn't give the hypervisor a mechanism to
> > +      * prevent a guest from dropping to AArch32 EL0 if implemented by the
> > +      * CPU. If the hypervisor spots a guest in such a state ensure it is
> > +      * handled, and don't trust the host to spot or fix it.
> > +      */
> > +     if (unlikely(is_nvhe_hyp_code() &&
> > +                  kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)) &&
> > +                  FIELD_GET(FEATURE(ID_AA64PFR0_EL0),
> > +                            PVM_ID_AA64PFR0_ALLOW) <
> > +                          ID_AA64PFR0_ELx_32BIT_64BIT &&
> > +                  vcpu_mode_is_32bit(vcpu))) {
> > +             /*
> > +              * As we have caught the guest red-handed, decide that it isn't
> > +              * fit for purpose anymore by making the vcpu invalid.
> > +              */
> > +             vcpu->arch.target = -1;
> > +             *exit_code = ARM_EXCEPTION_IL;
> > +             goto exit;
> > +     }
>
> Would this be better off inside the nvhe-specific run loop? Seems like we
> could elide fixup_guest_exit() altogether if we've detect that we're in
> AArch32 state when we shouldn't be and it would keep the code off the shared
> path.

Yes, it makes more sense and would result in cleaner code to have it
there, especially in the future where there's likely to be a separate
run loop for protected VMs. I'll move it.

Thanks,
/fuad
> Will


From hch at lst.de  Thu Aug 12 06:09:14 2021
From: hch at lst.de ('Christoph Hellwig')
Date: Thu, 12 Aug 2021 15:09:14 +0200
Subject: add support for the global coherent pool to the dma core
In-Reply-To: <03d501d783c4$1d3f10e0$57bd32a0$@codeaurora.org>
References: <20210712061704.4162464-1-hch@lst.de>
 <03d501d783c4$1d3f10e0$57bd32a0$@codeaurora.org>
Message-ID: <20210812130914.GA22352@lst.de>

On Wed, Jul 28, 2021 at 10:20:34AM -0500, Brian Cain wrote:
> > this series adds support for using the global coherent (aka uncached)
> > pool to the generic dma-direct code and then switches arm-nommu and
> > hexagon over to it, together with a bunch of cleanups.
> 
> Christoph,
> 
> Thanks for sending this -- I will take a look and give some feedback soon.

Any chance you'll get to this in the next days?  I'd love to merge this
series for the current merge window with a little time in linux-next.


From maz at kernel.org  Thu Aug 12 06:09:20 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 14:09:20 +0100
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
In-Reply-To: <79eabae1-e4a3-7a12-7aa0-3680569584e5@arm.com>
References: <20210811171505.1502090-1-wenst@chromium.org>
 <87fsvfal4n.wl-maz@kernel.org>
 <79eabae1-e4a3-7a12-7aa0-3680569584e5@arm.com>
Message-ID: <871r6yajy7.wl-maz@kernel.org>

On Thu, 12 Aug 2021 12:51:34 +0100,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi,
> 
> After re-familiarizing myself with the spec, it starting to look to
> me like indeed there's something not quite right (read as: totally
> broken) with my patch.
> 
> Arm IHI 0069F, the pseudocode for reading ICC_RPR_EL1 (page 11-797),
> says that the priority returned is unchanged if SCTLR_EL3.FIQ ==
> 0.

Sure, but look at what ICC_RPR_EL1 does for FIQ==1:

<quote>
if HaveEL(EL3) && !IsSecure() && SCR_EL3.FIQ == '1' then
    // A Non-secure GIC access and Group 0 inaccessible to Non-secure.
        if pPriority<7> == '0' then
	    // Priority is in Secure half and not visible to Non-secure
	    Priority = Zeros();
        elsif !IsOnes(pPriority) then
	    // Non-secure access and not idle, so physical priority must be shifted
            pPriority<7:0> = (pPriority AND PRIMask())<6:0>:'0';

return ZeroExtend(pPriority);
</quote>

See how the the priority is shifted *left* (bits [6:0] end up in
[7:1])?

> This means that the ICC_RPR_EL1 read will return the secure view
> (the value as it is stored by the GIC) of the priority, so for
> pseudo-nmis it will return (GICD_INT_NMI_PRI >> 1) | 0x80, which
> definitely != GICD_INT_NMI_PRI.

That's not my reading of the pseudocode.

> This is further confirmed by this statement on page 4-67:
> 
> "When GICD_CTLR.DS == 0, [..] For Non-secure access to ICC_PMR_EL1
> and ICC_RPR_EL1 when SCR_EL3.FIQ == 0: The Secure, unshifted view
> applies."
> 
> I don't know how I missed that during testing.
> 
> Did a quick test on the model with PMU NMIs (GICD_CTRL.DS = 0,
> SCTLR_EL2.FIQ = 0), gic_handle_nmi() was not being called at all,

0? Really????

> but when I changed the comparison to gic_read_rpr() ==
> ((GICD_INT_NMI_PRI >> 1) | 0x80), NMIs were being correctly handled
> again.

You have completely lost me. This contradicts what you have written
above.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From chunfeng.yun at mediatek.com  Thu Aug 12 06:11:30 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:11:30 +0800
Subject: [PATCH v2 2/7] usb: mtu3: use @mult for HS isoc or intr
In-Reply-To: <1628773895-304-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628773895-304-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628773895-304-2-git-send-email-chunfeng.yun@mediatek.com>

For HS isoc or intr, should use @mult but not @burst
to save mult value.

Fixes: 4d79e042ed8b ("usb: mtu3: add support for usb3.1 IP")
Cc: stable <stable at vger.kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: new patch, split from [2/6] suggested by Felipe
---
 drivers/usb/mtu3/mtu3_gadget.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 5e21ba05ebf0..635ad277cb13 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -92,7 +92,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
 			interval = clamp_val(interval, 1, 16) - 1;
-			burst = (max_packet & GENMASK(12, 11)) >> 11;
+			mult = (max_packet & GENMASK(12, 11)) >> 11;
 		}
 		break;
 	default:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 06:11:29 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:11:29 +0800
Subject: [PATCH v2 1/7] usb: mtu3: restore HS function when set SS/SSP
Message-ID: <1628773895-304-1-git-send-email-chunfeng.yun@mediatek.com>

Due to HS function is disabled when set as FS, need restore
it when set as SS/SSP.

Fixes: dc4c1aa7eae9 ("usb: mtu3: add ->udc_set_speed()")
Cc: stable <stable at vger.kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/usb/mtu3/mtu3_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index 562f4357831e..6403f01947b2 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -227,11 +227,13 @@ static void mtu3_set_speed(struct mtu3 *mtu, enum usb_device_speed speed)
 		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		break;
 	case USB_SPEED_SUPER:
+		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		mtu3_clrbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	case USB_SPEED_SUPER_PLUS:
-			mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
+		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
+		mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	default:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 06:17:57 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:17:57 +0800
Subject: [PATCH v2 1/7] usb: mtu3: restore HS function when set SS/SSP
Message-ID: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>

Due to HS function is disabled when set as FS, need restore
it when set as SS/SSP.

Fixes: dc4c1aa7eae9 ("usb: mtu3: add ->udc_set_speed()")
Cc: stable <stable at vger.kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/usb/mtu3/mtu3_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index 562f4357831e..6403f01947b2 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -227,11 +227,13 @@ static void mtu3_set_speed(struct mtu3 *mtu, enum usb_device_speed speed)
 		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		break;
 	case USB_SPEED_SUPER:
+		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		mtu3_clrbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	case USB_SPEED_SUPER_PLUS:
-			mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
+		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
+		mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	default:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 06:17:59 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:17:59 +0800
Subject: [PATCH v2 3/7] usb: mtu3: fix the wrong HS mult value
In-Reply-To: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628774283-475-3-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() returns actual max packet size, @mult will
always be zero, fix it by using usb_endpoint_maxp_mult() instead
to get mult.

Fixes: 4d79e042ed8b ("usb: mtu3: add support for usb3.1 IP")
Cc: stable <stable at vger.kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: split two patch [v2 2/7],[v2 3/7] suggested by Felipe
---
 drivers/usb/mtu3/mtu3_gadget.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 635ad277cb13..a399fd84c71f 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -64,14 +64,12 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 	u32 interval = 0;
 	u32 mult = 0;
 	u32 burst = 0;
-	int max_packet;
 	int ret;
 
 	desc = mep->desc;
 	comp_desc = mep->comp_desc;
 	mep->type = usb_endpoint_type(desc);
-	max_packet = usb_endpoint_maxp(desc);
-	mep->maxp = max_packet & GENMASK(10, 0);
+	mep->maxp = usb_endpoint_maxp(desc);
 
 	switch (mtu->g.speed) {
 	case USB_SPEED_SUPER:
@@ -92,7 +90,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
 			interval = clamp_val(interval, 1, 16) - 1;
-			mult = (max_packet & GENMASK(12, 11)) >> 11;
+			mult = usb_endpoint_maxp_mult(desc) - 1;
 		}
 		break;
 	default:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 06:18:02 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:18:02 +0800
Subject: [PATCH v2 6/7] usb: gadget: bdc: remove unnecessary AND operation
 when get ep maxp
In-Reply-To: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628774283-475-6-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() already returns actual max packet size, no need
AND 0x7ff.

Acked-by: Felipe Balbi <balbi at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add acked-by felipe
---
 drivers/usb/gadget/udc/bdc/bdc_cmd.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.c b/drivers/usb/gadget/udc/bdc/bdc_cmd.c
index 995f79c79f96..67887316a1a6 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_cmd.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.c
@@ -153,7 +153,6 @@ int bdc_config_ep(struct bdc *bdc, struct bdc_ep *ep)
 	si = clamp_val(si, 1, 16) - 1;
 
 	mps = usb_endpoint_maxp(desc);
-	mps &= 0x7ff;
 	param2 |= mps << MP_SHIFT;
 	param2 |= usb_endpoint_type(desc) << EPT_SHIFT;
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 06:18:00 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:18:00 +0800
Subject: [PATCH v2 4/7] usb: cdnsp: fix the wrong mult value for HS isoc or
 intr
In-Reply-To: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628774283-475-4-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
of endpoint descriptor, not include bit[12:11] anymore, so use
usb_endpoint_maxp_mult() instead.

Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
Cc: stable <stable at vger.kernel.org>
Acked-by: Felipe Balbi <balbi at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add fixes, cc suggested by Felipe
---
 drivers/usb/cdns3/cdnsp-mem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
index a47948a1623f..ad9aee3f1e39 100644
--- a/drivers/usb/cdns3/cdnsp-mem.c
+++ b/drivers/usb/cdns3/cdnsp-mem.c
@@ -882,7 +882,7 @@ static u32 cdnsp_get_endpoint_max_burst(struct usb_gadget *g,
 	if (g->speed == USB_SPEED_HIGH &&
 	    (usb_endpoint_xfer_isoc(pep->endpoint.desc) ||
 	     usb_endpoint_xfer_int(pep->endpoint.desc)))
-		return (usb_endpoint_maxp(pep->endpoint.desc) & 0x1800) >> 11;
+		return usb_endpoint_maxp_mult(pep->endpoint.desc) - 1;
 
 	return 0;
 }
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 06:18:03 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:18:03 +0800
Subject: [PATCH v2 7/7] usb: gadget: remove unnecessary AND operation when get
 ep maxp
In-Reply-To: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628774283-475-7-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() already returns actual max packet size, no need
AND 0x7ff.

Acked-by: Felipe Balbi <balbi at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add acked-by felipe
---
 include/linux/usb/gadget.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 75c7538e350a..f181c84310b6 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -491,7 +491,7 @@ extern char *usb_get_gadget_udc_name(void);
  */
 static inline size_t usb_ep_align(struct usb_ep *ep, size_t len)
 {
-	int max_packet_size = (size_t)usb_endpoint_maxp(ep->desc) & 0x7ff;
+	int max_packet_size = (size_t)usb_endpoint_maxp(ep->desc);
 
 	return round_up(len, max_packet_size);
 }
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 06:17:58 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:17:58 +0800
Subject: [PATCH v2 2/7] usb: mtu3: use @mult for HS isoc or intr
In-Reply-To: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628774283-475-2-git-send-email-chunfeng.yun@mediatek.com>

For HS isoc or intr, should use @mult but not @burst
to save mult value.

Fixes: 4d79e042ed8b ("usb: mtu3: add support for usb3.1 IP")
Cc: stable <stable at vger.kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: new patch, split from [2/6] suggested by Felipe
---
 drivers/usb/mtu3/mtu3_gadget.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 5e21ba05ebf0..635ad277cb13 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -92,7 +92,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
 			interval = clamp_val(interval, 1, 16) - 1;
-			burst = (max_packet & GENMASK(12, 11)) >> 11;
+			mult = (max_packet & GENMASK(12, 11)) >> 11;
 		}
 		break;
 	default:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 06:11:31 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:11:31 +0800
Subject: [PATCH v2 3/7] usb: mtu3: fix the wrong HS mult value
In-Reply-To: <1628773895-304-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628773895-304-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628773895-304-3-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() returns actual max packet size, @mult will
always be zero, fix it by using usb_endpoint_maxp_mult() instead
to get mult.

Fixes: 4d79e042ed8b ("usb: mtu3: add support for usb3.1 IP")
Cc: stable <stable at vger.kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: split two patch [v2 2/7],[v2 3/7] suggested by Felipe
---
 drivers/usb/mtu3/mtu3_gadget.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 635ad277cb13..a399fd84c71f 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -64,14 +64,12 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 	u32 interval = 0;
 	u32 mult = 0;
 	u32 burst = 0;
-	int max_packet;
 	int ret;
 
 	desc = mep->desc;
 	comp_desc = mep->comp_desc;
 	mep->type = usb_endpoint_type(desc);
-	max_packet = usb_endpoint_maxp(desc);
-	mep->maxp = max_packet & GENMASK(10, 0);
+	mep->maxp = usb_endpoint_maxp(desc);
 
 	switch (mtu->g.speed) {
 	case USB_SPEED_SUPER:
@@ -92,7 +90,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
 			interval = clamp_val(interval, 1, 16) - 1;
-			mult = (max_packet & GENMASK(12, 11)) >> 11;
+			mult = usb_endpoint_maxp_mult(desc) - 1;
 		}
 		break;
 	default:
-- 
2.18.0

From madvenka at linux.microsoft.com  Thu Aug 12 06:24:31 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 08:24:31 -0500
Subject: [RFC PATCH v7 0/4] arm64: Reorganize the unwinder and implement stack
 trace reliability checks
In-Reply-To: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
Message-ID: <20210812132435.6143-1-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Make all stack walking functions use arch_stack_walk()
======================================================

Currently, there are multiple functions in ARM64 code that walk the
stack using start_backtrace() and unwind_frame(). Convert all of
them to use arch_stack_walk(). This makes maintenance easier.

Reorganize the unwinder code for better consistency and maintenance
===================================================================

Rename unwinder functions to unwind_*() similar to other architectures
for naming consistency.

Annotate all of the unwind_*() functions with notrace so they cannot be
ftraced and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe
code can call the unwinder.

Redefine the unwinder loop and make it similar to other architectures.
Define the following:

	unwind_start(&frame, task, fp, pc);
	while (unwind_consume(&frame, consume_entry, cookie))
		unwind_next(&frame);
	return !unwind_failed(&frame);

unwind_start()
	Same as the original start_backtrace().

unwind_consume()
	This new function does two things:

	- Calls consume_entry() to consume the return PC.

	- Implements checks to determine whether the unwind should continue
	  or terminate.

unwind_next()
	Same as the original unwind_frame() except:

	- the stack trace termination check has been moved from here to
	  unwind_consume(). So, unwind_next() assumes that the fp is valid.

	- unwind_frame() used to return an error value. This function only
	  sets internal state and does not return anything. The state is
	  retrieved via a helper. See next.

unwind_failed()
	Return a boolean to indicate whether the stack trace completed
	successfully or failed. arch_stack_walk() ignores the return
	value. But arch_stack_walk_reliable() in the future will look
	at the return value.

Unwind status
	Introduce a new flag called "failed" in struct stackframe. Set this
	flag when an error is encountered. If this flag is set, terminate
	the unwind. Also, let the unwinder return the status to the caller.

Reliability checks
==================

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_is_reliable() that will detect
these cases and return a boolean.

Introduce a new argument to unwind() called "need_reliable" so a caller
can tell unwind() that it requires a reliable stack trace. For such a
caller, any unreliability in the stack trace must be treated as a fatal
error and the unwind must be aborted.

Call unwind_is_reliable() from unwind_consume() like this:

	if (frame->need_reliable && !unwind_is_reliable(frame)) {
		frame->failed = true;
		return false;
	}

arch_stack_walk() passes "false" for need_reliable because its callers
don't care about reliability. arch_stack_walk() is used for debug and
test purposes.

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except for two things:

	- It passes "true" for need_reliable.

	- It returns -EINVAL if unwind() aborts.

Introduce the first reliability check in unwind_is_reliable() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future. Until all of the
checks are in place, arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

SYM_CODE check
==============

SYM_CODE functions do not follow normal calling conventions. They cannot
be unwound reliably using the frame pointer. Collect the address ranges
of these functions in a special section called "sym_code_functions".

In unwind_is_reliable(), check the return PC against these ranges. If a
match is found, then consider the stack trace unreliable. This is the
second reliability check introduced by this work.

Last stack frame
----------------

If a SYM_CODE function occurs in the very last frame in the stack trace,
then the stack trace is not considered unreliable. This is because there
is no more unwinding to do. Examples:

	- EL0 exception stack traces end in the top level EL0 exception
	  handlers.

	- All kernel thread stack traces end in ret_from_fork().
---
Changelog:

v7:
	From Mark Rutland:

	- Make the unwinder loop similar to other architectures.

	- Keep details to within the unwinder functions and return a simple
	  boolean to the caller.

	- Convert some of the current code that contains unwinder logic to
	  simply use arch_stack_walk(). I have converted all of them.

	- Do not copy sym_code_functions[]. Just place it in rodata for now.

	- Have the main loop check for termination conditions rather than
	  having unwind_frame() check for them. In other words, let
	  unwind_frame() assume that the fp is valid.

	- Replace the big comment for SYM_CODE functions with a shorter
	  comment.

		/*
		 * As SYM_CODE functions don't follow the usual calling
		 * conventions, we assume by default that any SYM_CODE function
		 * cannot be unwound reliably.
		 *
		 * Note that this includes:
		 *
		 * - Exception handlers and entry assembly
		 * - Trampoline assembly (e.g., ftrace, kprobes)
		 * - Hypervisor-related assembly
		 * - Hibernation-related assembly
		 * - CPU start-stop, suspend-resume assembly
		 * - Kernel relocation assembly
		 */

v6:
	From Mark Rutland:

	- The per-frame reliability concept and flag are acceptable. But more
	  work is needed to make the per-frame checks more accurate and more
	  complete. E.g., some code reorg is being worked on that will help.

	  I have now removed the frame->reliable flag and deleted the whole
	  concept of per-frame status. This is orthogonal to this patch series.
	  Instead, I have improved the unwinder to return proper return codes
	  so a caller can take appropriate action without needing per-frame
	  status.

	- Remove the mention of PLTs and update the comment.

	  I have replaced the comment above the call to __kernel_text_address()
	  with the comment suggested by Mark Rutland.

	Other comments:

	- Other comments on the per-frame stuff are not relevant because
	  that approach is not there anymore.

v5:
	From Keiya Nobuta:
	
	- The term blacklist(ed) is not to be used anymore. I have changed it
	  to unreliable. So, the function unwinder_blacklisted() has been
	  changed to unwinder_is_unreliable().

	From Mark Brown:

	- Add a comment for the "reliable" flag in struct stackframe. The
	  reliability attribute is not complete until all the checks are
	  in place. Added a comment above struct stackframe.

	- Include some of the comments in the cover letter in the actual
	  code so that we can compare it with the reliable stack trace
	  requirements document for completeness. I have added a comment:

	  	- above unwinder_is_unreliable() that lists the requirements
		  that are addressed by the function.

		- above the __kernel_text_address() call about all the cases
		  the call covers.

v4:
	From Mark Brown:

	- I was checking the return PC with __kernel_text_address() before
	  the Function Graph trace handling. Mark Brown felt that all the
	  reliability checks should be performed on the original return PC
	  once that is obtained. So, I have moved all the reliability checks
	  to after the Function Graph Trace handling code in the unwinder.
	  Basically, the unwinder should perform PC translations first (for
	  rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
	  Then, the reliability checks should be applied to the resulting
	  PC.

	- Mark said to improve the naming of the new functions so they don't
	  collide with existing ones. I have used a prefix "unwinder_" for
	  all the new functions.

	From Josh Poimboeuf:

	- In the error scenarios in the unwinder, the reliable flag in the
	  stack frame should be set. Implemented this.

	- Some of the other comments are not relevant to the new code as
	  I have taken a different approach in the new code. That is why
	  I have not made those changes. E.g., Ard wanted me to add the
	  "const" keyword to the global section array. That array does not
	  exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
	  the same array in a for loop.

	Other changes:

	- Add a new definition for SYM_CODE_END() that adds the address
	  range of the function to a special section called
	  "sym_code_functions".

	- Include the new section under initdata in vmlinux.lds.S.

	- Define an early_initcall() to copy the contents of the
	  "sym_code_functions" section to an array by the same name.

	- Define a function unwinder_blacklisted() that compares a return
	  PC against sym_code_sections[]. If there is a match, mark the
	  stack trace unreliable. Call this from unwind_frame().

v3:
	- Implemented a sym_code_ranges[] array to contains sections bounds
	  for text sections that contain SYM_CODE_*() functions. The unwinder
	  checks each return PC against the sections. If it falls in any of
	  the sections, the stack trace is marked unreliable.

	- Moved SYM_CODE functions from .text and .init.text into a new
	  text section called ".code.text". Added this section to
	  vmlinux.lds.S and sym_code_ranges[].

	- Fixed the logic in the unwinder that handles Function Graph
	  Tracer return trampoline.

	- Removed all the previous code that handles:
		- ftrace entry code for traced function
		- special_functions[] array that lists individual functions
		- kretprobe_trampoline() special case

v2
	- Removed the terminating entry { 0, 0 } in special_functions[]
	  and replaced it with the idiom { /* sentinel */ }.

	- Change the ftrace trampoline entry ftrace_graph_call in
	  special_functions[] to ftrace_call + 4 and added explanatory
	  comments.

	- Unnested #ifdefs in special_functions[] for FTRACE.

v1
	- Define a bool field in struct stackframe. This will indicate if
	  a stack trace is reliable.

	- Implement a special_functions[] array that will be populated
	  with special functions in which the stack trace is considered
	  unreliable.
	
	- Using kallsyms_lookup(), get the address ranges for the special
	  functions and record them.

	- Implement an is_reliable_function(pc). This function will check
	  if a given return PC falls in any of the special functions. If
	  it does, the stack trace is unreliable.

	- Implement check_reliability() function that will check if a
	  stack frame is reliable. Call is_reliable_function() from
	  check_reliability().

	- Before a return PC is checked against special_funtions[], it
	  must be validates as a proper kernel text address. Call
	  __kernel_text_address() from check_reliability().

	- Finally, call check_reliability() from unwind_frame() for
	  each stack frame.

	- Add EL1 exception handlers to special_functions[].

		el1_sync();
		el1_irq();
		el1_error();
		el1_sync_invalid();
		el1_irq_invalid();
		el1_fiq_invalid();
		el1_error_invalid();

	- The above functions are currently defined as LOCAL symbols.
	  Make them global so that they can be referenced from the
	  unwinder code.

	- Add FTRACE trampolines to special_functions[]:

		ftrace_graph_call()
		ftrace_graph_caller()
		return_to_handler()

	- Add the kretprobe trampoline to special functions[]:

		kretprobe_trampoline()

Previous versions and discussion
================================

v6: https://lore.kernel.org/linux-arm-kernel/20210630223356.58714-1-madvenka at linux.microsoft.com/
v5: https://lore.kernel.org/linux-arm-kernel/20210526214917.20099-1-madvenka at linux.microsoft.com/
v4: https://lore.kernel.org/linux-arm-kernel/20210516040018.128105-1-madvenka at linux.microsoft.com/
v3: https://lore.kernel.org/linux-arm-kernel/20210503173615.21576-1-madvenka at linux.microsoft.com/
v2: https://lore.kernel.org/linux-arm-kernel/20210405204313.21346-1-madvenka at linux.microsoft.com/
v1: https://lore.kernel.org/linux-arm-kernel/20210330190955.13707-1-madvenka at linux.microsoft.com/
Madhavan T. Venkataraman (4):
  arm64: Make all stack walking functions use arch_stack_walk()
  arm64: Reorganize the unwinder code for better consistency and
    maintenance
  arm64: Introduce stack trace reliability checks in the unwinder
  arm64: Create a list of SYM_CODE functions, check return PC against
    list

 arch/arm64/include/asm/linkage.h    |  12 ++
 arch/arm64/include/asm/sections.h   |   1 +
 arch/arm64/include/asm/stacktrace.h |  16 +-
 arch/arm64/kernel/perf_callchain.c  |   5 +-
 arch/arm64/kernel/process.c         |  39 ++--
 arch/arm64/kernel/return_address.c  |   6 +-
 arch/arm64/kernel/stacktrace.c      | 291 ++++++++++++++++++++--------
 arch/arm64/kernel/time.c            |  22 ++-
 arch/arm64/kernel/vmlinux.lds.S     |  10 +
 9 files changed, 277 insertions(+), 125 deletions(-)


base-commit: 36a21d51725af2ce0700c6ebcb6b9594aac658a6
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 06:24:32 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 08:24:32 -0500
Subject: [RFC PATCH v7 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210812132435.6143-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812132435.6143-1-madvenka@linux.microsoft.com>
Message-ID: <20210812132435.6143-2-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Currently, there are multiple functions in ARM64 code that walk the
stack using start_backtrace() and unwind_frame(). Convert all of
them to use arch_stack_walk(). This makes maintenance easier.

Here is the list of functions:

	perf_callchain_kernel()
	get_wchan()
	return_address()
	dump_backtrace()
	profile_pc()

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  3 ---
 arch/arm64/kernel/perf_callchain.c  |  5 +---
 arch/arm64/kernel/process.c         | 39 ++++++++++++++++++-----------
 arch/arm64/kernel/return_address.c  |  6 +----
 arch/arm64/kernel/stacktrace.c      | 38 +++-------------------------
 arch/arm64/kernel/time.c            | 22 +++++++++-------
 6 files changed, 43 insertions(+), 70 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 8aebc00c1718..e43dea1c6b41 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -61,9 +61,6 @@ struct stackframe {
 #endif
 };
 
-extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
-extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
-			    bool (*fn)(void *, unsigned long), void *data);
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 			   const char *loglvl);
 
diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 4a72c2727309..2f289013c9c9 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -147,15 +147,12 @@ static bool callchain_trace(void *data, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
-	struct stackframe frame;
-
 	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
 
-	start_backtrace(&frame, regs->regs[29], regs->pc);
-	walk_stackframe(current, &frame, callchain_trace, entry);
+	arch_stack_walk(callchain_trace, entry, current, regs);
 }
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index c8989b999250..52c12fd26407 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -544,11 +544,28 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
 	return last;
 }
 
+struct wchan_info {
+	unsigned long	pc;
+	int		count;
+};
+
+static bool get_wchan_cb(void *arg, unsigned long pc)
+{
+	struct wchan_info *wchan_info = arg;
+
+	if (!in_sched_functions(pc)) {
+		wchan_info->pc = pc;
+		return false;
+	}
+	wchan_info->count--;
+	return !!wchan_info->count;
+}
+
 unsigned long get_wchan(struct task_struct *p)
 {
-	struct stackframe frame;
-	unsigned long stack_page, ret = 0;
-	int count = 0;
+	unsigned long stack_page;
+	struct wchan_info wchan_info;
+
 	if (!p || p == current || task_is_running(p))
 		return 0;
 
@@ -556,20 +573,12 @@ unsigned long get_wchan(struct task_struct *p)
 	if (!stack_page)
 		return 0;
 
-	start_backtrace(&frame, thread_saved_fp(p), thread_saved_pc(p));
+	wchan_info.pc = 0;
+	wchan_info.count = 16;
+	arch_stack_walk(get_wchan_cb, &wchan_info, p, NULL);
 
-	do {
-		if (unwind_frame(p, &frame))
-			goto out;
-		if (!in_sched_functions(frame.pc)) {
-			ret = frame.pc;
-			goto out;
-		}
-	} while (count++ < 16);
-
-out:
 	put_task_stack(p);
-	return ret;
+	return wchan_info.pc;
 }
 
 unsigned long arch_align_stack(unsigned long sp)
diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c
index a6d18755652f..92a0f4d434e4 100644
--- a/arch/arm64/kernel/return_address.c
+++ b/arch/arm64/kernel/return_address.c
@@ -35,15 +35,11 @@ NOKPROBE_SYMBOL(save_return_addr);
 void *return_address(unsigned int level)
 {
 	struct return_address_data data;
-	struct stackframe frame;
 
 	data.level = level + 2;
 	data.addr = NULL;
 
-	start_backtrace(&frame,
-			(unsigned long)__builtin_frame_address(0),
-			(unsigned long)return_address);
-	walk_stackframe(current, &frame, save_return_addr, &data);
+	arch_stack_walk(save_return_addr, &data, current, NULL);
 
 	if (!data.level)
 		return data.addr;
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 8982a2b78acf..1800310f92be 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -151,23 +151,21 @@ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
 }
 NOKPROBE_SYMBOL(walk_stackframe);
 
-static void dump_backtrace_entry(unsigned long where, const char *loglvl)
+static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
+	char *loglvl = arg;
 	printk("%s %pSb\n", loglvl, (void *)where);
+	return true;
 }
 
 void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 		    const char *loglvl)
 {
-	struct stackframe frame;
-	int skip = 0;
-
 	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
 
 	if (regs) {
 		if (user_mode(regs))
 			return;
-		skip = 1;
 	}
 
 	if (!tsk)
@@ -176,36 +174,8 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 	if (!try_get_task_stack(tsk))
 		return;
 
-	if (tsk == current) {
-		start_backtrace(&frame,
-				(unsigned long)__builtin_frame_address(0),
-				(unsigned long)dump_backtrace);
-	} else {
-		/*
-		 * task blocked in __switch_to
-		 */
-		start_backtrace(&frame,
-				thread_saved_fp(tsk),
-				thread_saved_pc(tsk));
-	}
-
 	printk("%sCall trace:\n", loglvl);
-	do {
-		/* skip until specified stack frame */
-		if (!skip) {
-			dump_backtrace_entry(frame.pc, loglvl);
-		} else if (frame.fp == regs->regs[29]) {
-			skip = 0;
-			/*
-			 * Mostly, this is the case where this function is
-			 * called in panic/abort. As exception handler's
-			 * stack frame does not contain the corresponding pc
-			 * at which an exception has taken place, use regs->pc
-			 * instead.
-			 */
-			dump_backtrace_entry(regs->pc, loglvl);
-		}
-	} while (!unwind_frame(tsk, &frame));
+	arch_stack_walk(dump_backtrace_entry, (void *)loglvl, tsk, regs);
 
 	put_task_stack(tsk);
 }
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index eebbc8d7123e..671b3038a772 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -32,22 +32,26 @@
 #include <asm/stacktrace.h>
 #include <asm/paravirt.h>
 
+static bool profile_pc_cb(void *arg, unsigned long pc)
+{
+	unsigned long *prof_pc = arg;
+
+	if (in_lock_functions(pc))
+		return true;
+	*prof_pc = pc;
+	return false;
+}
+
 unsigned long profile_pc(struct pt_regs *regs)
 {
-	struct stackframe frame;
+	unsigned long prof_pc = 0;
 
 	if (!in_lock_functions(regs->pc))
 		return regs->pc;
 
-	start_backtrace(&frame, regs->regs[29], regs->pc);
-
-	do {
-		int ret = unwind_frame(NULL, &frame);
-		if (ret < 0)
-			return 0;
-	} while (in_lock_functions(frame.pc));
+	arch_stack_walk(profile_pc_cb, &prof_pc, current, regs);
 
-	return frame.pc;
+	return prof_pc;
 }
 EXPORT_SYMBOL(profile_pc);
 
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 06:24:34 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 08:24:34 -0500
Subject: [RFC PATCH v7 3/4] arm64: Introduce stack trace reliability checks in
 the unwinder
In-Reply-To: <20210812132435.6143-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812132435.6143-1-madvenka@linux.microsoft.com>
Message-ID: <20210812132435.6143-4-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_is_reliable() that will detect
these cases and return a boolean.

Introduce a new argument to unwind() called "need_reliable" so a caller
can tell unwind() that it requires a reliable stack trace. For such a
caller, any unreliability in the stack trace must be treated as a fatal
error and the unwind must be aborted.

Call unwind_is_reliable() from unwind_consume() like this:

	if (frame->need_reliable && !unwind_is_reliable(frame)) {
		frame->failed = true;
		return false;
	}

In other words, if the return PC in the stackframe falls in unreliable code,
then it cannot be unwound reliably.

arch_stack_walk() will pass "false" for need_reliable because its callers
don't care about reliability. arch_stack_walk() is used for debug and
test purposes.

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except for two things:

	- It passes "true" for need_reliable.

	- It returns -EINVAL if unwind() says that the stack trace is
	  unreliable.

Introduce the first reliability check in unwind_is_reliable() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future. Until all of the
checks are in place, arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  4 ++
 arch/arm64/kernel/stacktrace.c      | 63 +++++++++++++++++++++++++++--
 2 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 407007376e97..65ea151da5da 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -53,6 +53,9 @@ struct stack_info {
  *               replacement lr value in the ftrace graph stack.
  *
  * @failed:      Unwind failed.
+ *
+ * @need_reliable The caller needs a reliable stack trace. Treat any
+ *                unreliability as a fatal error.
  */
 struct stackframe {
 	struct task_struct *task;
@@ -65,6 +68,7 @@ struct stackframe {
 	int graph;
 #endif
 	bool failed;
+	bool need_reliable;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index ec8f5163c4d0..b60f8a20ba64 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -34,7 +34,8 @@
 
 static void notrace unwind_start(struct stackframe *frame,
 				 struct task_struct *task,
-				 unsigned long fp, unsigned long pc)
+				 unsigned long fp, unsigned long pc,
+				 bool need_reliable)
 {
 	frame->task = task;
 	frame->fp = fp;
@@ -56,6 +57,7 @@ static void notrace unwind_start(struct stackframe *frame,
 	frame->prev_fp = 0;
 	frame->prev_type = STACK_TYPE_UNKNOWN;
 	frame->failed = false;
+	frame->need_reliable = need_reliable;
 }
 
 NOKPROBE_SYMBOL(unwind_start);
@@ -178,6 +180,23 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
 	barrier();
 }
 
+/*
+ * Check the stack frame for conditions that make further unwinding unreliable.
+ */
+static bool notrace unwind_is_reliable(struct stackframe *frame)
+{
+	/*
+	 * If the PC is not a known kernel text address, then we cannot
+	 * be sure that a subsequent unwind will be reliable, as we
+	 * don't know that the code follows our unwind requirements.
+	 */
+	if (!__kernel_text_address(frame->pc))
+		return false;
+	return true;
+}
+
+NOKPROBE_SYMBOL(unwind_is_reliable);
+
 static bool notrace unwind_consume(struct stackframe *frame,
 				   stack_trace_consume_fn consume_entry,
 				   void *cookie)
@@ -197,6 +216,12 @@ static bool notrace unwind_consume(struct stackframe *frame,
 		/* Final frame; nothing to unwind */
 		return false;
 	}
+
+	if (frame->need_reliable && !unwind_is_reliable(frame)) {
+		/* Cannot unwind to the next frame reliably. */
+		frame->failed = true;
+		return false;
+	}
 	return true;
 }
 
@@ -210,11 +235,12 @@ static inline bool unwind_failed(struct stackframe *frame)
 /* Core unwind function */
 static bool notrace unwind(stack_trace_consume_fn consume_entry, void *cookie,
 			   struct task_struct *task,
-			   unsigned long fp, unsigned long pc)
+			   unsigned long fp, unsigned long pc,
+			   bool need_reliable)
 {
 	struct stackframe frame;
 
-	unwind_start(&frame, task, fp, pc);
+	unwind_start(&frame, task, fp, pc, need_reliable);
 	while (unwind_consume(&frame, consume_entry, cookie))
 		unwind_next(&frame);
 	return !unwind_failed(&frame);
@@ -245,7 +271,36 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 		fp = thread_saved_fp(task);
 		pc = thread_saved_pc(task);
 	}
-	unwind(consume_entry, cookie, task, fp, pc);
+	unwind(consume_entry, cookie, task, fp, pc, false);
+}
+
+/*
+ * arch_stack_walk_reliable() may not be used for livepatch until all of
+ * the reliability checks are in place in unwind_consume(). However,
+ * debug and test code can choose to use it even if all the checks are not
+ * in place.
+ */
+noinline int notrace arch_stack_walk_reliable(stack_trace_consume_fn consume_fn,
+					      void *cookie,
+					      struct task_struct *task)
+{
+	unsigned long fp, pc;
+
+	if (!task)
+		task = current;
+
+	if (task == current) {
+		/* Skip arch_stack_walk_reliable() in the stack trace. */
+		fp = (unsigned long)__builtin_frame_address(1);
+		pc = (unsigned long)__builtin_return_address(0);
+	} else {
+		/* Caller guarantees that the task is not running. */
+		fp = thread_saved_fp(task);
+		pc = thread_saved_pc(task);
+	}
+	if (unwind(consume_fn, cookie, task, fp, pc, true))
+		return 0;
+	return -EINVAL;
 }
 
 #endif
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 06:24:35 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 08:24:35 -0500
Subject: [RFC PATCH v7 4/4] arm64: Create a list of SYM_CODE functions,
 check return PC against list
In-Reply-To: <20210812132435.6143-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812132435.6143-1-madvenka@linux.microsoft.com>
Message-ID: <20210812132435.6143-5-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

SYM_CODE functions don't follow the usual calling conventions. Check if the
return PC in a stack frame falls in any of these. If it does, consider the
stack trace unreliable.

Define a special section for unreliable functions
=================================================

Define a SYM_CODE_END() macro for arm64 that adds the function address
range to a new section called "sym_code_functions".

Linker file
===========

Include the "sym_code_functions" section under read-only data in
vmlinux.lds.S.

Initialization
==============

Define an early_initcall() to create a sym_code_functions[] array from
the linker data.

Unwinder check
==============

Add a reliability check in unwind_is_reliable() that compares a return
PC with sym_code_functions[]. If there is a match, then return failure.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/linkage.h  | 12 +++++++
 arch/arm64/include/asm/sections.h |  1 +
 arch/arm64/kernel/stacktrace.c    | 53 +++++++++++++++++++++++++++++++
 arch/arm64/kernel/vmlinux.lds.S   | 10 ++++++
 4 files changed, 76 insertions(+)

diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index 9906541a6861..616bad74e297 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -68,4 +68,16 @@
 		SYM_FUNC_END_ALIAS(x);		\
 		SYM_FUNC_END_ALIAS(__pi_##x)
 
+/*
+ * Record the address range of each SYM_CODE function in a struct code_range
+ * in a special section.
+ */
+#define SYM_CODE_END(name)				\
+	SYM_END(name, SYM_T_NONE)			;\
+	99:						;\
+	.pushsection "sym_code_functions", "aw"		;\
+	.quad	name					;\
+	.quad	99b					;\
+	.popsection
+
 #endif
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
index e4ad9db53af1..c84c71063d6e 100644
--- a/arch/arm64/include/asm/sections.h
+++ b/arch/arm64/include/asm/sections.h
@@ -21,5 +21,6 @@ extern char __exittext_begin[], __exittext_end[];
 extern char __irqentry_text_start[], __irqentry_text_end[];
 extern char __mmuoff_data_start[], __mmuoff_data_end[];
 extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
+extern char __sym_code_functions_start[], __sym_code_functions_end[];
 
 #endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b60f8a20ba64..26dbdd4fff77 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,6 +18,31 @@
 #include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
+struct code_range {
+	unsigned long	start;
+	unsigned long	end;
+};
+
+static struct code_range	*sym_code_functions;
+static int			num_sym_code_functions;
+
+int __init init_sym_code_functions(void)
+{
+	size_t size = (unsigned long)__sym_code_functions_end -
+		      (unsigned long)__sym_code_functions_start;
+
+	sym_code_functions = (struct code_range *)__sym_code_functions_start;
+	/*
+	 * Order it so that sym_code_functions is not visible before
+	 * num_sym_code_functions.
+	 */
+	smp_mb();
+	num_sym_code_functions = size / sizeof(struct code_range);
+
+	return 0;
+}
+early_initcall(init_sym_code_functions);
+
 /*
  * AArch64 PCS assigns the frame pointer to x29.
  *
@@ -185,6 +210,10 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
  */
 static bool notrace unwind_is_reliable(struct stackframe *frame)
 {
+	const struct code_range *range;
+	unsigned long pc;
+	int i;
+
 	/*
 	 * If the PC is not a known kernel text address, then we cannot
 	 * be sure that a subsequent unwind will be reliable, as we
@@ -192,6 +221,30 @@ static bool notrace unwind_is_reliable(struct stackframe *frame)
 	 */
 	if (!__kernel_text_address(frame->pc))
 		return false;
+
+	/*
+	 * Check the return PC against sym_code_functions[]. If there is a
+	 * match, then the consider the stack frame unreliable.
+	 *
+	 * As SYM_CODE functions don't follow the usual calling conventions,
+	 * we assume by default that any SYM_CODE function cannot be unwound
+	 * reliably.
+	 *
+	 * Note that this includes:
+	 *
+	 * - Exception handlers and entry assembly
+	 * - Trampoline assembly (e.g., ftrace, kprobes)
+	 * - Hypervisor-related assembly
+	 * - Hibernation-related assembly
+	 * - CPU start-stop, suspend-resume assembly
+	 * - Kernel relocation assembly
+	 */
+	pc = frame->pc;
+	for (i = 0; i < num_sym_code_functions; i++) {
+		range = &sym_code_functions[i];
+		if (pc >= range->start && pc < range->end)
+			return false;
+	}
 	return true;
 }
 
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 709d2c433c5e..2bf769f45b54 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -111,6 +111,14 @@ jiffies = jiffies_64;
 #define TRAMP_TEXT
 #endif
 
+#define SYM_CODE_FUNCTIONS				\
+	. = ALIGN(16);					\
+	.symcode : AT(ADDR(.symcode) - LOAD_OFFSET) {	\
+		__sym_code_functions_start = .;		\
+		KEEP(*(sym_code_functions))		\
+		__sym_code_functions_end = .;		\
+	}
+
 /*
  * The size of the PE/COFF section that covers the kernel image, which
  * runs from _stext to _edata, must be a round multiple of the PE/COFF
@@ -196,6 +204,8 @@ SECTIONS
 	swapper_pg_dir = .;
 	. += PAGE_SIZE;
 
+	SYM_CODE_FUNCTIONS
+
 	. = ALIGN(SEGMENT_ALIGN);
 	__init_begin = .;
 	__inittext_begin = .;
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 06:24:33 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 08:24:33 -0500
Subject: [RFC PATCH v7 2/4] arm64: Reorganize the unwinder code for better
 consistency and maintenance
In-Reply-To: <20210812132435.6143-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812132435.6143-1-madvenka@linux.microsoft.com>
Message-ID: <20210812132435.6143-3-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Renaming of unwinder functions
==============================

Rename unwinder functions to unwind_*() similar to other architectures
for naming consistency. More on this below.

unwind function attributes
==========================

Mark all of the unwind_*() functions with notrace so they cannot be ftraced
and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe code
can call the unwinder.

start_backtrace()
=================

start_backtrace() is only called by arch_stack_walk(). Make it static.
Rename start_backtrace() to unwind_start() for naming consistency.

unwind_frame()
==============

Rename this to unwind_next() for naming consistency.

Replace walk_stackframe() with unwind()
=======================================

walk_stackframe() contains the unwinder loop that walks the stack
frames. Currently, start_backtrace() and walk_stackframe() are called
separately. They should be combined in the same function. Also, the
loop in walk_stackframe() should be simplified and should look like
the unwind loops in other architectures such as X86 and S390.

Remove walk_stackframe(). Define a new function called "unwind()" in
its place. Define the following unwinder loop:

	unwind_start(&frame, task, fp, pc);
	while (unwind_consume(&frame, consume_entry, cookie))
		unwind_next(&frame);
	return !unwind_failed(&frame);

unwind_start()
	Same as the original start_backtrace().

unwind_consume()
	This is a new function that calls the callback function to
	consume the PC in a stackframe. Do it this way so that checks
	can be performed before and after the callback to determine
	whether the unwind should continue or terminate.

unwind_next()
	Same as the original unwind_frame() except for two things:

		- the stack trace termination check has been moved from
		  here to unwind_consume(). So, unwind_next() is always
		  called on a valid fp.

		- unwind_frame() used to return an error value. This
		  function does not return anything.

unwind_failed()
	Return a boolean to indicate if the stack trace completed
	successfully or failed. arch_stack_walk() ignores the return
	value. But arch_stack_walk_reliable() in the future will look
	at the return value.

Unwind status
=============

Introduce a new flag called "failed" in struct stackframe. unwind_next()
and unwind_consume() will set this flag when an error is encountered and
unwind_consume() will check this flag. This is in keeping with other
architectures.

The failed flags is accessed via the helper unwind_failed().

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |   9 +-
 arch/arm64/kernel/stacktrace.c      | 145 ++++++++++++++++++----------
 2 files changed, 99 insertions(+), 55 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index e43dea1c6b41..407007376e97 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -34,6 +34,8 @@ struct stack_info {
  * A snapshot of a frame record or fp/lr register values, along with some
  * accounting information necessary for robust unwinding.
  *
+ * @task:        The task whose stack is being unwound.
+ *
  * @fp:          The fp value in the frame record (or the real fp)
  * @pc:          The lr value in the frame record (or the real lr)
  *
@@ -49,8 +51,11 @@ struct stack_info {
  *
  * @graph:       When FUNCTION_GRAPH_TRACER is selected, holds the index of a
  *               replacement lr value in the ftrace graph stack.
+ *
+ * @failed:      Unwind failed.
  */
 struct stackframe {
+	struct task_struct *task;
 	unsigned long fp;
 	unsigned long pc;
 	DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
@@ -59,6 +64,7 @@ struct stackframe {
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	int graph;
 #endif
+	bool failed;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
@@ -145,7 +151,4 @@ static inline bool on_accessible_stack(const struct task_struct *tsk,
 	return false;
 }
 
-void start_backtrace(struct stackframe *frame, unsigned long fp,
-		     unsigned long pc);
-
 #endif	/* __ASM_STACKTRACE_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 1800310f92be..ec8f5163c4d0 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -32,10 +32,11 @@
  *	add	sp, sp, #0x10
  */
 
-
-void start_backtrace(struct stackframe *frame, unsigned long fp,
-		     unsigned long pc)
+static void notrace unwind_start(struct stackframe *frame,
+				 struct task_struct *task,
+				 unsigned long fp, unsigned long pc)
 {
+	frame->task = task;
 	frame->fp = fp;
 	frame->pc = pc;
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -45,7 +46,7 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
 	/*
 	 * Prime the first unwind.
 	 *
-	 * In unwind_frame() we'll check that the FP points to a valid stack,
+	 * In unwind_next() we'll check that the FP points to a valid stack,
 	 * which can't be STACK_TYPE_UNKNOWN, and the first unwind will be
 	 * treated as a transition to whichever stack that happens to be. The
 	 * prev_fp value won't be used, but we set it to 0 such that it is
@@ -54,8 +55,11 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
 	bitmap_zero(frame->stacks_done, __NR_STACK_TYPES);
 	frame->prev_fp = 0;
 	frame->prev_type = STACK_TYPE_UNKNOWN;
+	frame->failed = false;
 }
 
+NOKPROBE_SYMBOL(unwind_start);
+
 /*
  * Unwind from one frame record (A) to the next frame record (B).
  *
@@ -63,26 +67,26 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
+static void notrace unwind_next(struct stackframe *frame)
 {
 	unsigned long fp = frame->fp;
 	struct stack_info info;
+	struct task_struct *tsk = frame->task;
 
-	if (!tsk)
-		tsk = current;
-
-	/* Final frame; nothing to unwind */
-	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
-		return -ENOENT;
-
-	if (fp & 0x7)
-		return -EINVAL;
+	if (fp & 0x7) {
+		frame->failed = true;
+		return;
+	}
 
-	if (!on_accessible_stack(tsk, fp, 16, &info))
-		return -EINVAL;
+	if (!on_accessible_stack(tsk, fp, 16, &info)) {
+		frame->failed = true;
+		return;
+	}
 
-	if (test_bit(info.type, frame->stacks_done))
-		return -EINVAL;
+	if (test_bit(info.type, frame->stacks_done)) {
+		frame->failed = true;
+		return;
+	}
 
 	/*
 	 * As stacks grow downward, any valid record on the same stack must be
@@ -98,15 +102,17 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
 	 * stack.
 	 */
 	if (info.type == frame->prev_type) {
-		if (fp <= frame->prev_fp)
-			return -EINVAL;
+		if (fp <= frame->prev_fp) {
+			frame->failed = true;
+			return;
+		}
 	} else {
 		set_bit(frame->prev_type, frame->stacks_done);
 	}
 
 	/*
 	 * Record this frame record's values and location. The prev_fp and
-	 * prev_type are only meaningful to the next unwind_frame() invocation.
+	 * prev_type are only meaningful to the next unwind_next() invocation.
 	 */
 	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
 	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
@@ -124,32 +130,18 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
 		 * So replace it to an original value.
 		 */
 		ret_stack = ftrace_graph_get_ret_stack(tsk, frame->graph++);
-		if (WARN_ON_ONCE(!ret_stack))
-			return -EINVAL;
+		if (WARN_ON_ONCE(!ret_stack)) {
+			frame->failed = true;
+			return;
+		}
 		frame->pc = ret_stack->ret;
 	}
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
 	frame->pc = ptrauth_strip_insn_pac(frame->pc);
-
-	return 0;
 }
-NOKPROBE_SYMBOL(unwind_frame);
 
-void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
-			     bool (*fn)(void *, unsigned long), void *data)
-{
-	while (1) {
-		int ret;
-
-		if (!fn(data, frame->pc))
-			break;
-		ret = unwind_frame(tsk, frame);
-		if (ret < 0)
-			break;
-	}
-}
-NOKPROBE_SYMBOL(walk_stackframe);
+NOKPROBE_SYMBOL(unwind_next);
 
 static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
@@ -186,25 +178,74 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
 	barrier();
 }
 
+static bool notrace unwind_consume(struct stackframe *frame,
+				   stack_trace_consume_fn consume_entry,
+				   void *cookie)
+{
+	if (frame->failed) {
+		/* PC is suspect. Cannot consume it. */
+		return false;
+	}
+
+	if (!consume_entry(cookie, frame->pc)) {
+		/* Caller terminated the unwind. */
+		frame->failed = true;
+		return false;
+	}
+
+	if (frame->fp == (unsigned long)task_pt_regs(frame->task)->stackframe) {
+		/* Final frame; nothing to unwind */
+		return false;
+	}
+	return true;
+}
+
+NOKPROBE_SYMBOL(unwind_consume);
+
+static inline bool unwind_failed(struct stackframe *frame)
+{
+	return frame->failed;
+}
+
+/* Core unwind function */
+static bool notrace unwind(stack_trace_consume_fn consume_entry, void *cookie,
+			   struct task_struct *task,
+			   unsigned long fp, unsigned long pc)
+{
+	struct stackframe frame;
+
+	unwind_start(&frame, task, fp, pc);
+	while (unwind_consume(&frame, consume_entry, cookie))
+		unwind_next(&frame);
+	return !unwind_failed(&frame);
+}
+
+NOKPROBE_SYMBOL(unwind);
+
 #ifdef CONFIG_STACKTRACE
 
 noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 			      void *cookie, struct task_struct *task,
 			      struct pt_regs *regs)
 {
-	struct stackframe frame;
+	unsigned long fp, pc;
+
+	if (!task)
+		task = current;
 
-	if (regs)
-		start_backtrace(&frame, regs->regs[29], regs->pc);
-	else if (task == current)
-		start_backtrace(&frame,
-				(unsigned long)__builtin_frame_address(1),
-				(unsigned long)__builtin_return_address(0));
-	else
-		start_backtrace(&frame, thread_saved_fp(task),
-				thread_saved_pc(task));
-
-	walk_stackframe(task, &frame, consume_entry, cookie);
+	if (regs) {
+		fp = regs->regs[29];
+		pc = regs->pc;
+	} else if (task == current) {
+		/* Skip arch_stack_walk() in the stack trace. */
+		fp = (unsigned long)__builtin_frame_address(1);
+		pc = (unsigned long)__builtin_return_address(0);
+	} else {
+		/* Caller guarantees that the task is not running. */
+		fp = thread_saved_fp(task);
+		pc = thread_saved_pc(task);
+	}
+	unwind(consume_entry, cookie, task, fp, pc);
 }
 
 #endif
-- 
2.25.1



From chunfeng.yun at mediatek.com  Thu Aug 12 06:18:01 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 12 Aug 2021 21:18:01 +0800
Subject: [PATCH v2 5/7] usb: gadget: tegra-xudc: fix the wrong mult value for
 HS isoc or intr
In-Reply-To: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628774283-475-5-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
of endpoint descriptor, not includes bit[12:11] anymore, so use
usb_endpoint_maxp_mult() instead.
Meanwhile no need AND 0x7ff when get maxp, remove it.

Fixes: 49db427232fe ("usb: gadget: Add UDC driver for tegra XUSB device mode controller")
Cc: stable <stable at vger.kernel.org>
Acked-by: Felipe Balbi <balbi at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2:
  add fixes, cc;
  add acked-by felipe;
---
 drivers/usb/gadget/udc/tegra-xudc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index a54d1cef17db..40a7417e7ae4 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -1610,7 +1610,7 @@ static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep)
 	u16 maxpacket, maxburst = 0, esit = 0;
 	u32 val;
 
-	maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
+	maxpacket = usb_endpoint_maxp(desc);
 	if (xudc->gadget.speed == USB_SPEED_SUPER) {
 		if (!usb_endpoint_xfer_control(desc))
 			maxburst = comp_desc->bMaxBurst;
@@ -1621,7 +1621,7 @@ static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep)
 		   (usb_endpoint_xfer_int(desc) ||
 		    usb_endpoint_xfer_isoc(desc))) {
 		if (xudc->gadget.speed == USB_SPEED_HIGH) {
-			maxburst = (usb_endpoint_maxp(desc) >> 11) & 0x3;
+			maxburst = usb_endpoint_maxp_mult(desc) - 1;
 			if (maxburst == 0x3) {
 				dev_warn(xudc->dev,
 					 "invalid endpoint maxburst\n");
-- 
2.18.0

From valentin.schneider at arm.com  Thu Aug 12 06:36:11 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Thu, 12 Aug 2021 14:36:11 +0100
Subject: [PATCH v3 02/13] genirq: Define ack_irq() and eoi_irq() helpers
In-Reply-To: <87a6ln9k7i.wl-maz@kernel.org>
References: <20210629125010.458872-1-valentin.schneider@arm.com>
 <20210629125010.458872-3-valentin.schneider@arm.com>
 <87a6ln9k7i.wl-maz@kernel.org>
Message-ID: <877dgq9450.mognet@arm.com>

On 12/08/21 08:49, Marc Zyngier wrote:
> On Tue, 29 Jun 2021 13:49:59 +0100,
> Valentin Schneider <valentin.schneider at arm.com> wrote:
>> +void eoi_irq(struct irq_desc *desc)
>> +{
>> +	desc->irq_data.chip->irq_eoi(&desc->irq_data);
>> +
>> +	if (desc->irq_data.chip->flags & IRQCHIP_AUTOMASKS_FLOW)
>> +		irq_state_clr_flow_masked(desc);
>
> I just realised that this has a good chance to result in a mess with
> KVM, and specially the way we let the vGIC deactivate an interrupt
> directly from the guest, without any SW intervention (the magic HW bit
> in the LRs).
>

I didn't think to consider those. It can't ever be simple, can it...

> With this, interrupts routed to a guest (such as the timers) will
> always have the IRQD_IRQ_FLOW_MASKED flag set, which will never be
> cleared.
>
> I wonder whether this have a chance to interact badly with
> mask/unmask, or with the rest of the flow...
>

Isn't it the other way around? That is, eoi_irq() will clear
IRQD_IRQ_FLOW_MASKED regardless of what happens within chip->irq_eoi(),
so we would end up with !IRQD_IRQ_FLOW_MASKED even if the (physical) IRQ
remains Active (irqd_is_forwarded_to_vcpu() case).

This does not entirely match reality (if the IRQ is still Active then it is
still "flow-masked"), but AFAICT this doesn't impact our handling of
forwarded IRQs: IRQD_IRQ_FLOW_MASKED is only really relevant from ack_irq()
to eoi_irq(), and deactivation-from-the-guest (propagated via LR.HW=1)
happens after that.


From valentin.schneider at arm.com  Thu Aug 12 06:36:35 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Thu, 12 Aug 2021 14:36:35 +0100
Subject: [PATCH v3 05/13] genirq: Let purely flow-masked ONESHOT irqs
 through unmask_threaded_irq()
In-Reply-To: <87bl639l8n.wl-maz@kernel.org>
References: <20210629125010.458872-1-valentin.schneider@arm.com>
 <20210629125010.458872-6-valentin.schneider@arm.com>
 <87bl639l8n.wl-maz@kernel.org>
Message-ID: <875ywa944c.mognet@arm.com>

On 12/08/21 08:26, Marc Zyngier wrote:
> On Tue, 29 Jun 2021 13:50:02 +0100,
> Valentin Schneider <valentin.schneider at arm.com> wrote:
>> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
>> index ef30b4762947..e6d6d32ddcbc 100644
>> --- a/kernel/irq/manage.c
>> +++ b/kernel/irq/manage.c
>> @@ -1107,7 +1107,7 @@ static void irq_finalize_oneshot(struct irq_desc *desc,
>>  	desc->threads_oneshot &= ~action->thread_mask;
>>  
>>  	if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) &&
>> -	    irqd_irq_masked(&desc->irq_data))
>> +	    (irqd_irq_masked(&desc->irq_data) | irqd_irq_flow_masked(&desc->irq_data)))
>>  		unmask_threaded_irq(desc);
>
> The bitwise OR looks pretty odd. It is probably fine given that both
> side of the expression are bool, but still. I can fix this locally.
>

Thomas suggested that back in v1:

  https://lore.kernel.org/lkml/87v98v4lan.ffs at nanos.tec.linutronix.de/

I did look at the (arm64) disassembly diff back then and was convinced by
what I saw, though I'd have to go do that again as I can't remember much
else.

> Thanks,
>
> 	M.
>
> -- 
> Without deviation from the norm, progress is not possible.


From minyard at acm.org  Thu Aug 12 06:36:55 2021
From: minyard at acm.org (Corey Minyard)
Date: Thu, 12 Aug 2021 08:36:55 -0500
Subject: [Openipmi-developer] [PATCH v5 1/3] i2c: aspeed: Add
 slave_enable() to toggle slave mode
In-Reply-To: <YRTQP9sX0hkTJMTx@shikoro>
References: <20210714033833.11640-1-quan@os.amperecomputing.com>
 <20210714033833.11640-2-quan@os.amperecomputing.com>
 <YRTQP9sX0hkTJMTx@shikoro>
Message-ID: <20210812133655.GT3406@minyard.net>

On Thu, Aug 12, 2021 at 09:39:43AM +0200, Wolfram Sang wrote:
> Hi all,
> 
> On Wed, Jul 14, 2021 at 10:38:31AM +0700, Quan Nguyen wrote:
> > Slave needs time to prepare the response data before Master could
> > enquiry via read transaction. However, there is no mechanism for
> > i2c-aspeed Slave to notify Master that it needs more time to process
> > and this make Master side to time out when trying to get the response.
> > 
> > This commit introduces the slave_enable() callback in struct
> > i2c_algorithm for Slave to temporary stop the Slave mode while working
> > on the response and re-enable the Slave when response data ready.
> 
> Sorry that I couldn't chime in earlier, but NAK!
> 
> >  include/linux/i2c.h             |  2 ++
> 
> @Corey: Please do not change this file without my ACK. It is not a
> trivial change but an API extenstion and that should really be acked by
> the subsystem maintainer, in this case me. I was really surprised to see
> this in linux-next already.

I am sorry, I'll pull it out.

-corey

> 
> @all: Plus, I neither like the API (because it doesn't look generic to
> me but mostly handling one issue needed here) nor do I fully understand
> the use case. Normally, when a read is requested and the backend needs
> time to deliver the data, the hardware should stretch the SCL clock
> until some data register is finally written to. If it doesn't do it for
> whatever reason, this is a quirky hardware in my book and needs handling
> in the driver only. So, what is special with this HW? Can't we solve it
> differently?
> 
> All the best,
> 
>    Wolfram
> 




> _______________________________________________
> Openipmi-developer mailing list
> Openipmi-developer at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/openipmi-developer



From jon.lin at rock-chips.com  Thu Aug 12 06:45:43 2021
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 12 Aug 2021 21:45:43 +0800
Subject: [PATCH v13 3/6] arm64: dts: rockchip: Add SFC to PX30
In-Reply-To: <20210812134546.31340-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
Message-ID: <20210812134546.31340-4-jon.lin@rock-chips.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add a devicetree entry for the Rockchip SFC for the PX30 SOC.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
Changes in v1: None

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

diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index 248ebb61aa79..5c5ef853b4a9 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -974,6 +974,18 @@
 		status = "disabled";
 	};
 
+	sfc: spi at ff3a0000 {
+		compatible = "rockchip,sfc";
+		reg = <0x0 0xff3a0000 0x0 0x4000>;
+		interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+		clock-names = "clk_sfc", "hclk_sfc";
+		pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus4>;
+		pinctrl-names = "default";
+		power-domains = <&power PX30_PD_MMC_NAND>;
+		status = "disabled";
+	};
+
 	nfc: nand-controller at ff3b0000 {
 		compatible = "rockchip,px30-nfc";
 		reg = <0x0 0xff3b0000 0x0 0x4000>;
@@ -1973,6 +1985,32 @@
 			};
 		};
 
+		sfc {
+			sfc_bus4: sfc-bus4 {
+				rockchip,pins =
+					<1 RK_PA0 3 &pcfg_pull_none>,
+					<1 RK_PA1 3 &pcfg_pull_none>,
+					<1 RK_PA2 3 &pcfg_pull_none>,
+					<1 RK_PA3 3 &pcfg_pull_none>;
+			};
+
+			sfc_bus2: sfc-bus2 {
+				rockchip,pins =
+					<1 RK_PA0 3 &pcfg_pull_none>,
+					<1 RK_PA1 3 &pcfg_pull_none>;
+			};
+
+			sfc_cs0: sfc-cs0 {
+				rockchip,pins =
+					<1 RK_PA4 3 &pcfg_pull_none>;
+			};
+
+			sfc_clk: sfc-clk {
+				rockchip,pins =
+					<1 RK_PB1 3 &pcfg_pull_none>;
+			};
+		};
+
 		lcdc {
 			lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin {
 				rockchip,pins =
-- 
2.17.1





From jon.lin at rock-chips.com  Thu Aug 12 06:45:41 2021
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 12 Aug 2021 21:45:41 +0800
Subject: [PATCH v13 1/6] dt-bindings: rockchip-sfc: Bindings for Rockchip
 serial flash controller
In-Reply-To: <20210812134546.31340-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
Message-ID: <20210812134546.31340-2-jon.lin@rock-chips.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add bindings for the Rockchip serial flash controller. New device
specific parameter of rockchip,sfc-no-dma included in documentation.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

Changes in v13: None
Changes in v12:
- Remove useless oneOf lable
- Add sfc controller discription

Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8:
- Fix indent 4 to 2 in yaml

Changes in v7:
- Fix up the sclk_sfc parent error in rk3036
- Unify to "rockchip,sfc" compatible id because all the feature update
  will have a new IP version, so the driver is used for the SFC IP in
  all SoCs
- Change to use node "sfc" to name the SFC pinctrl group
- Add subnode reg property check
- Add rockchip_sfc_adjust_op_size to workaround in CMD + DUMMY case
- Limit max_iosize to 32KB

Changes in v6:
- Add support in device trees for rv1126(Declared in series 5 but not
  submitted)
- Change to use "clk_sfc" "hclk_sfc" as clock lable, since it does not
  affect interpretation and has been widely used
- Support sfc tx_dual, tx_quad(Declared in series 5 but not submitted)
- Simplify the code, such as remove "rockchip_sfc_register_all"(Declared
  in series 5 but not submitted)
- Support SFC ver4 ver5(Declared in series 5 but not submitted)
- Add author Chris Morgan and Jon Lin to spi-rockchip-sfc.c
- Change to use devm_spi_alloc_master and spi_unregister_master

Changes in v5:
- Add support in device trees for rv1126
- Support sfc tx_dual, tx_quad
- Simplify the code, such as remove "rockchip_sfc_register_all"
- Support SFC ver4 ver5

Changes in v4:
- Changing patch back to an "RFC". An engineer from Rockchip
  reached out to me to let me know they are working on this patch for
  upstream, I am submitting this v4 for the community to see however
  I expect Jon Lin (jon.lin at rock-chips.com) will submit new patches
  soon and these are the ones we should pursue for mainlining. Jon's
  patch series should include support for more hardware than this
  series.
- Clean up documentation more and ensure it is correct per
  make dt_binding_check.
- Add support in device trees for rk3036, rk3308, and rv1108.
- Add ahb clock (hclk_sfc) support for rk3036.
- Change rockchip_sfc_wait_fifo_ready() to use a switch statement.
- Change IRQ code to only mark IRQ as handled if it handles the
  specific IRQ (DMA transfer finish) it is supposed to handle.

Changes in v3:
- Changed the name of the clocks to sfc/ahb (from clk-sfc/clk-hsfc).
- Changed the compatible string from rockchip,sfc to
  rockchip,rk3036-sfc. A quick glance at the datasheets suggests this
  driver should work for the PX30, RK180x, RK3036, RK312x, RK3308 and
  RV1108 SoCs, and possibly more. However, I am currently only able
  to test this on a PX30 (an RK3326). The technical reference manuals
  appear to list the same registers for each device.
- Corrected devicetree documentation for formatting and to note these
  changes.
- Replaced the maintainer with Heiko Stuebner and myself, as we will
  take ownership of this going forward.
- Noted that the device (per the reference manual) supports 4 CS, but
  I am only able to test a single CS (CS 0).
- Reordered patches to comply with upstream rules.

Changes in v2:
- Reimplemented driver using spi-mem subsystem.
- Removed power management code as I couldn't get it working properly.
- Added device tree bindings for Odroid Go Advance.

Changes in v1:
hanges made in this new series versus the v8 of the old series:
- Added function to read spi-rx-bus-width from device tree, in the
  event that the SPI chip supports 4x mode but only has 2 pins
  wired (such as the Odroid Go Advance).
- Changed device tree documentation from txt to yaml format.
- Made "reset" message a dev_dbg from a dev_info.
- Changed read and write fifo functions to remove redundant checks.
- Changed the write and read from relaxed to non-relaxed when
  starting the DMA transfer or reading the DMA IRQ.
- Changed from dma_coerce_mask_and_coherent to just
  dma_set_mask_and_coherent.
- Changed name of get_if_type to rockchip_sfc_get_if_type.

 .../devicetree/bindings/spi/rockchip-sfc.yaml | 91 +++++++++++++++++++
 1 file changed, 91 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/rockchip-sfc.yaml

diff --git a/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml b/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml
new file mode 100644
index 000000000000..339fb39529f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/rockchip-sfc.yaml
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/rockchip-sfc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip Serial Flash Controller (SFC)
+
+maintainers:
+  - Heiko Stuebner <heiko at sntech.de>
+  - Chris Morgan <macromorgan at hotmail.com>
+
+allOf:
+  - $ref: spi-controller.yaml#
+
+properties:
+  compatible:
+    const: rockchip,sfc
+    description:
+      The rockchip sfc controller is a standalone IP with version register,
+      and the driver can handle all the feature difference inside the IP
+      depending on the version register.
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Bus Clock
+      - description: Module Clock
+
+  clock-names:
+    items:
+      - const: clk_sfc
+      - const: hclk_sfc
+
+  power-domains:
+    maxItems: 1
+
+  rockchip,sfc-no-dma:
+    description: Disable DMA and utilize FIFO mode only
+    type: boolean
+
+patternProperties:
+  "^flash@[0-3]$":
+    type: object
+    properties:
+      reg:
+        minimum: 0
+        maximum: 3
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/px30-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/power/px30-power.h>
+
+    sfc: spi at ff3a0000 {
+        compatible = "rockchip,sfc";
+        reg = <0xff3a0000 0x4000>;
+        interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+        clock-names = "clk_sfc", "hclk_sfc";
+        pinctrl-0 = <&sfc_clk &sfc_cs &sfc_bus2>;
+        pinctrl-names = "default";
+        power-domains = <&power PX30_PD_MMC_NAND>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        flash at 0 {
+            compatible = "jedec,spi-nor";
+            reg = <0>;
+            spi-max-frequency = <108000000>;
+            spi-rx-bus-width = <2>;
+            spi-tx-bus-width = <2>;
+        };
+    };
+
+...
-- 
2.17.1





From jon.lin at rock-chips.com  Thu Aug 12 06:45:40 2021
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 12 Aug 2021 21:45:40 +0800
Subject: [PATCH v13 0/6] Add Rockchip SFC(serial flash controller) support
Message-ID: <20210812134546.31340-1-jon.lin@rock-chips.com>



Changes in v13:
- Provide independent interfaces to obtain RX TX FIFO status respectively
- Add more debug information
- Depress DMA limitation

Changes in v12:
- Remove useless oneOf lable
- Add sfc controller discription
- Remove the limitation of SFC_MIN_SPEED_HZ
- Add IRQ_NONE method for irq handler
- Add SPI_MASTER_HALF_DUPLEX flags
- Add sfc interrupt mask bits and status register initial progress

Changes in v11:
- The tx is set to 1 for Odroid Go Advance device

Changes in v10:
- Fix dma transfer logic

Changes in v9:
- Separate DMA IRQ setting and wait_completion from DMA fifo transfer
  function to make dma_status_poll be possible(Which I will implement
  in u-boot)
- Add SFC Kconfig detail comment

Changes in v8:
- Fix indent 4 to 2 in yaml

Changes in v7:
- Fix up the sclk_sfc parent error in rk3036
- Unify to "rockchip,sfc" compatible id because all the feature update
  will have a new IP version, so the driver is used for the SFC IP in
  all SoCs
- Change to use node "sfc" to name the SFC pinctrl group
- Add subnode reg property check
- Add rockchip_sfc_adjust_op_size to workaround in CMD + DUMMY case
- Limit max_iosize to 32KB

Changes in v6:
- Add support in device trees for rv1126(Declared in series 5 but not
  submitted)
- Change to use "clk_sfc" "hclk_sfc" as clock lable, since it does not
  affect interpretation and has been widely used
- Support sfc tx_dual, tx_quad(Declared in series 5 but not submitted)
- Simplify the code, such as remove "rockchip_sfc_register_all"(Declared
  in series 5 but not submitted)
- Support SFC ver4 ver5(Declared in series 5 but not submitted)
- Add author Chris Morgan and Jon Lin to spi-rockchip-sfc.c
- Change to use devm_spi_alloc_master and spi_unregister_master

Changes in v5:
- Add support in device trees for rv1126
- Support sfc tx_dual, tx_quad
- Simplify the code, such as remove "rockchip_sfc_register_all"
- Support SFC ver4 ver5

Changes in v4:
- Changing patch back to an "RFC". An engineer from Rockchip
  reached out to me to let me know they are working on this patch for
  upstream, I am submitting this v4 for the community to see however
  I expect Jon Lin (jon.lin at rock-chips.com) will submit new patches
  soon and these are the ones we should pursue for mainlining. Jon's
  patch series should include support for more hardware than this
  series.
- Clean up documentation more and ensure it is correct per
  make dt_binding_check.
- Add support in device trees for rk3036, rk3308, and rv1108.
- Add ahb clock (hclk_sfc) support for rk3036.
- Change rockchip_sfc_wait_fifo_ready() to use a switch statement.
- Change IRQ code to only mark IRQ as handled if it handles the
  specific IRQ (DMA transfer finish) it is supposed to handle.

Changes in v3:
- Changed the name of the clocks to sfc/ahb (from clk-sfc/clk-hsfc).
- Changed the compatible string from rockchip,sfc to
  rockchip,rk3036-sfc. A quick glance at the datasheets suggests this
  driver should work for the PX30, RK180x, RK3036, RK312x, RK3308 and
  RV1108 SoCs, and possibly more. However, I am currently only able
  to test this on a PX30 (an RK3326). The technical reference manuals
  appear to list the same registers for each device.
- Corrected devicetree documentation for formatting and to note these
  changes.
- Replaced the maintainer with Heiko Stuebner and myself, as we will
  take ownership of this going forward.
- Noted that the device (per the reference manual) supports 4 CS, but
  I am only able to test a single CS (CS 0).
- Reordered patches to comply with upstream rules.

Changes in v2:
- Reimplemented driver using spi-mem subsystem.
- Removed power management code as I couldn't get it working properly.
- Added device tree bindings for Odroid Go Advance.

Changes in v1:
hanges made in this new series versus the v8 of the old series:
- Added function to read spi-rx-bus-width from device tree, in the
  event that the SPI chip supports 4x mode but only has 2 pins
  wired (such as the Odroid Go Advance).
- Changed device tree documentation from txt to yaml format.
- Made "reset" message a dev_dbg from a dev_info.
- Changed read and write fifo functions to remove redundant checks.
- Changed the write and read from relaxed to non-relaxed when
  starting the DMA transfer or reading the DMA IRQ.
- Changed from dma_coerce_mask_and_coherent to just
  dma_set_mask_and_coherent.
- Changed name of get_if_type to rockchip_sfc_get_if_type.

Chris Morgan (6):
  dt-bindings: rockchip-sfc: Bindings for Rockchip serial flash
    controller
  spi: rockchip-sfc: add rockchip serial flash controller
  arm64: dts: rockchip: Add SFC to PX30
  arm: dts: rockchip: Add SFC to RV1108
  arm64: dts: rockchip: Add SFC to RK3308
  arm64: dts: rockchip: Enable SFC for Odroid Go Advance

 .../devicetree/bindings/spi/rockchip-sfc.yaml |  91 +++
 arch/arm/boot/dts/rv1108.dtsi                 |  37 +
 arch/arm64/boot/dts/rockchip/px30.dtsi        |  38 +
 arch/arm64/boot/dts/rockchip/rk3308.dtsi      |  37 +
 .../boot/dts/rockchip/rk3326-odroid-go2.dts   |  16 +
 drivers/spi/Kconfig                           |  12 +
 drivers/spi/Makefile                          |   1 +
 drivers/spi/spi-rockchip-sfc.c                | 694 ++++++++++++++++++
 8 files changed, 926 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/rockchip-sfc.yaml
 create mode 100644 drivers/spi/spi-rockchip-sfc.c

-- 
2.17.1





From jon.lin at rock-chips.com  Thu Aug 12 06:45:42 2021
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 12 Aug 2021 21:45:42 +0800
Subject: [PATCH v13 2/6] spi: rockchip-sfc: add rockchip serial flash
 controller
In-Reply-To: <20210812134546.31340-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
Message-ID: <20210812134546.31340-3-jon.lin@rock-chips.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add the rockchip serial flash controller (SFC) driver.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

Changes in v13:
- Provide independent interfaces to obtain RX TX FIFO status respectively
- Add more debug information
- Depress DMA limitation

Changes in v12:
- Remove the limitation of SFC_MIN_SPEED_HZ
- Add IRQ_NONE method for irq handler
- Add SPI_MASTER_HALF_DUPLEX flags
- Add sfc interrupt mask bits and status register initial progress

Changes in v11: None
Changes in v10:
- Fix dma transfer logic

Changes in v9:
- Separate DMA IRQ setting and wait_completion from DMA fifo transfer
  function to make dma_status_poll be possible(Which I will implement
  in u-boot)
- Add SFC Kconfig detail comment

Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
Changes in v1: None

 drivers/spi/Kconfig            |  12 +
 drivers/spi/Makefile           |   1 +
 drivers/spi/spi-rockchip-sfc.c | 694 +++++++++++++++++++++++++++++++++
 3 files changed, 707 insertions(+)
 create mode 100644 drivers/spi/spi-rockchip-sfc.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index e71a4c514f7b..83e352b0c8f9 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -658,6 +658,18 @@ config SPI_ROCKCHIP
 	  The main usecase of this controller is to use spi flash as boot
 	  device.
 
+config SPI_ROCKCHIP_SFC
+	tristate "Rockchip Serial Flash Controller (SFC)"
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	depends on HAS_IOMEM && HAS_DMA
+	help
+	  This enables support for Rockchip serial flash controller. This
+	  is a specialized controller used to access SPI flash on some
+	  Rockchip SOCs.
+
+	  ROCKCHIP SFC supports DMA and PIO modes. When DMA is not available,
+	  the driver automatically falls back to PIO mode.
+
 config SPI_RB4XX
 	tristate "Mikrotik RB4XX SPI master"
 	depends on SPI_MASTER && ATH79
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 13e54c45e9df..699db95c8441 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_SPI_QCOM_GENI)		+= spi-geni-qcom.o
 obj-$(CONFIG_SPI_QCOM_QSPI)		+= spi-qcom-qspi.o
 obj-$(CONFIG_SPI_QUP)			+= spi-qup.o
 obj-$(CONFIG_SPI_ROCKCHIP)		+= spi-rockchip.o
+obj-$(CONFIG_SPI_ROCKCHIP_SFC)		+= spi-rockchip-sfc.o
 obj-$(CONFIG_SPI_RB4XX)			+= spi-rb4xx.o
 obj-$(CONFIG_MACH_REALTEK_RTL)		+= spi-realtek-rtl.o
 obj-$(CONFIG_SPI_RPCIF)			+= spi-rpc-if.o
diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
new file mode 100644
index 000000000000..7c4d47fe80c2
--- /dev/null
+++ b/drivers/spi/spi-rockchip-sfc.c
@@ -0,0 +1,694 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Rockchip Serial Flash Controller Driver
+ *
+ * Copyright (c) 2017-2021, Rockchip Inc.
+ * Author: Shawn Lin <shawn.lin at rock-chips.com>
+ *	   Chris Morgan <macroalpha82 at gmail.com>
+ *	   Jon Lin <Jon.lin at rock-chips.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi-mem.h>
+
+/* System control */
+#define SFC_CTRL			0x0
+#define  SFC_CTRL_PHASE_SEL_NEGETIVE	BIT(1)
+#define  SFC_CTRL_CMD_BITS_SHIFT	8
+#define  SFC_CTRL_ADDR_BITS_SHIFT	10
+#define  SFC_CTRL_DATA_BITS_SHIFT	12
+
+/* Interrupt mask */
+#define SFC_IMR				0x4
+#define  SFC_IMR_RX_FULL		BIT(0)
+#define  SFC_IMR_RX_UFLOW		BIT(1)
+#define  SFC_IMR_TX_OFLOW		BIT(2)
+#define  SFC_IMR_TX_EMPTY		BIT(3)
+#define  SFC_IMR_TRAN_FINISH		BIT(4)
+#define  SFC_IMR_BUS_ERR		BIT(5)
+#define  SFC_IMR_NSPI_ERR		BIT(6)
+#define  SFC_IMR_DMA			BIT(7)
+
+/* Interrupt clear */
+#define SFC_ICLR			0x8
+#define  SFC_ICLR_RX_FULL		BIT(0)
+#define  SFC_ICLR_RX_UFLOW		BIT(1)
+#define  SFC_ICLR_TX_OFLOW		BIT(2)
+#define  SFC_ICLR_TX_EMPTY		BIT(3)
+#define  SFC_ICLR_TRAN_FINISH		BIT(4)
+#define  SFC_ICLR_BUS_ERR		BIT(5)
+#define  SFC_ICLR_NSPI_ERR		BIT(6)
+#define  SFC_ICLR_DMA			BIT(7)
+
+/* FIFO threshold level */
+#define SFC_FTLR			0xc
+#define  SFC_FTLR_TX_SHIFT		0
+#define  SFC_FTLR_TX_MASK		0x1f
+#define  SFC_FTLR_RX_SHIFT		8
+#define  SFC_FTLR_RX_MASK		0x1f
+
+/* Reset FSM and FIFO */
+#define SFC_RCVR			0x10
+#define  SFC_RCVR_RESET			BIT(0)
+
+/* Enhanced mode */
+#define SFC_AX				0x14
+
+/* Address Bit number */
+#define SFC_ABIT			0x18
+
+/* Interrupt status */
+#define SFC_ISR				0x1c
+#define  SFC_ISR_RX_FULL_SHIFT		BIT(0)
+#define  SFC_ISR_RX_UFLOW_SHIFT		BIT(1)
+#define  SFC_ISR_TX_OFLOW_SHIFT		BIT(2)
+#define  SFC_ISR_TX_EMPTY_SHIFT		BIT(3)
+#define  SFC_ISR_TX_FINISH_SHIFT	BIT(4)
+#define  SFC_ISR_BUS_ERR_SHIFT		BIT(5)
+#define  SFC_ISR_NSPI_ERR_SHIFT		BIT(6)
+#define  SFC_ISR_DMA_SHIFT		BIT(7)
+
+/* FIFO status */
+#define SFC_FSR				0x20
+#define  SFC_FSR_TX_IS_FULL		BIT(0)
+#define  SFC_FSR_TX_IS_EMPTY		BIT(1)
+#define  SFC_FSR_RX_IS_EMPTY		BIT(2)
+#define  SFC_FSR_RX_IS_FULL		BIT(3)
+#define  SFC_FSR_TXLV_MASK		GENMASK(12, 8)
+#define  SFC_FSR_TXLV_SHIFT		8
+#define  SFC_FSR_RXLV_MASK		GENMASK(20, 16)
+#define  SFC_FSR_RXLV_SHIFT		16
+
+/* FSM status */
+#define SFC_SR				0x24
+#define  SFC_SR_IS_IDLE			0x0
+#define  SFC_SR_IS_BUSY			0x1
+
+/* Raw interrupt status */
+#define SFC_RISR			0x28
+#define  SFC_RISR_RX_FULL		BIT(0)
+#define  SFC_RISR_RX_UNDERFLOW		BIT(1)
+#define  SFC_RISR_TX_OVERFLOW		BIT(2)
+#define  SFC_RISR_TX_EMPTY		BIT(3)
+#define  SFC_RISR_TRAN_FINISH		BIT(4)
+#define  SFC_RISR_BUS_ERR		BIT(5)
+#define  SFC_RISR_NSPI_ERR		BIT(6)
+#define  SFC_RISR_DMA			BIT(7)
+
+/* Version */
+#define SFC_VER				0x2C
+#define  SFC_VER_3			0x3
+#define  SFC_VER_4			0x4
+#define  SFC_VER_5			0x5
+
+/* Delay line controller resiter */
+#define SFC_DLL_CTRL0			0x3C
+#define SFC_DLL_CTRL0_SCLK_SMP_DLL	BIT(15)
+#define SFC_DLL_CTRL0_DLL_MAX_VER4	0xFFU
+#define SFC_DLL_CTRL0_DLL_MAX_VER5	0x1FFU
+
+/* Master trigger */
+#define SFC_DMA_TRIGGER			0x80
+#define SFC_DMA_TRIGGER_START		1
+
+/* Src or Dst addr for master */
+#define SFC_DMA_ADDR			0x84
+
+/* Length control register extension 32GB */
+#define SFC_LEN_CTRL			0x88
+#define SFC_LEN_CTRL_TRB_SEL		1
+#define SFC_LEN_EXT			0x8C
+
+/* Command */
+#define SFC_CMD				0x100
+#define  SFC_CMD_IDX_SHIFT		0
+#define  SFC_CMD_DUMMY_SHIFT		8
+#define  SFC_CMD_DIR_SHIFT		12
+#define  SFC_CMD_DIR_RD			0
+#define  SFC_CMD_DIR_WR			1
+#define  SFC_CMD_ADDR_SHIFT		14
+#define  SFC_CMD_ADDR_0BITS		0
+#define  SFC_CMD_ADDR_24BITS		1
+#define  SFC_CMD_ADDR_32BITS		2
+#define  SFC_CMD_ADDR_XBITS		3
+#define  SFC_CMD_TRAN_BYTES_SHIFT	16
+#define  SFC_CMD_CS_SHIFT		30
+
+/* Address */
+#define SFC_ADDR			0x104
+
+/* Data */
+#define SFC_DATA			0x108
+
+/* The controller and documentation reports that it supports up to 4 CS
+ * devices (0-3), however I have only been able to test a single CS (CS 0)
+ * due to the configuration of my device.
+ */
+#define SFC_MAX_CHIPSELECT_NUM		4
+
+/* The SFC can transfer max 16KB - 1 at one time
+ * we set it to 15.5KB here for alignment.
+ */
+#define SFC_MAX_IOSIZE_VER3		(512 * 31)
+
+/* DMA is only enabled for large data transmission */
+#define SFC_DMA_TRANS_THRETHOLD		(0x40)
+
+/* Maximum clock values from datasheet suggest keeping clock value under
+ * 150MHz. No minimum or average value is suggested.
+ */
+#define SFC_MAX_SPEED		(150 * 1000 * 1000)
+
+struct rockchip_sfc {
+	struct device *dev;
+	void __iomem *regbase;
+	struct clk *hclk;
+	struct clk *clk;
+	u32 frequency;
+	/* virtual mapped addr for dma_buffer */
+	void *buffer;
+	dma_addr_t dma_buffer;
+	struct completion cp;
+	bool use_dma;
+	u32 max_iosize;
+	u16 version;
+};
+
+static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
+{
+	int err;
+	u32 status;
+
+	writel_relaxed(SFC_RCVR_RESET, sfc->regbase + SFC_RCVR);
+
+	err = readl_poll_timeout(sfc->regbase + SFC_RCVR, status,
+				 !(status & SFC_RCVR_RESET), 20,
+				 jiffies_to_usecs(HZ));
+	if (err)
+		dev_err(sfc->dev, "SFC reset never finished\n");
+
+	/* Still need to clear the masked interrupt from RISR */
+	writel_relaxed(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
+
+	dev_dbg(sfc->dev, "reset\n");
+
+	return err;
+}
+
+static u16 rockchip_sfc_get_version(struct rockchip_sfc *sfc)
+{
+	return  (u16)(readl(sfc->regbase + SFC_VER) & 0xffff);
+}
+
+static u32 rockchip_sfc_get_max_iosize(struct rockchip_sfc *sfc)
+{
+	return SFC_MAX_IOSIZE_VER3;
+}
+
+static void rockchip_sfc_irq_unmask(struct rockchip_sfc *sfc, u32 mask)
+{
+	u32 reg;
+
+	/* Enable transfer complete interrupt */
+	reg = readl(sfc->regbase + SFC_IMR);
+	reg &= ~mask;
+	writel(reg, sfc->regbase + SFC_IMR);
+}
+
+static void rockchip_sfc_irq_mask(struct rockchip_sfc *sfc, u32 mask)
+{
+	u32 reg;
+
+	/* Disable transfer finish interrupt */
+	reg = readl(sfc->regbase + SFC_IMR);
+	reg |= mask;
+	writel(reg, sfc->regbase + SFC_IMR);
+}
+
+static int rockchip_sfc_init(struct rockchip_sfc *sfc)
+{
+	writel(0, sfc->regbase + SFC_CTRL);
+	writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
+	rockchip_sfc_irq_mask(sfc, 0xFFFFFFFF);
+	if (rockchip_sfc_get_version(sfc) >= SFC_VER_4)
+		writel(SFC_LEN_CTRL_TRB_SEL, sfc->regbase + SFC_LEN_CTRL);
+
+	return 0;
+}
+
+static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
+{
+	int ret = 0;
+	u32 status;
+
+	ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
+				 status & SFC_FSR_TXLV_MASK, 0,
+				 timeout_us);
+	if (ret) {
+		dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
+
+		ret = -ETIMEDOUT;
+	}
+
+	return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
+}
+
+static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
+{
+	int ret = 0;
+	u32 status;
+
+	ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
+				 status & SFC_FSR_RXLV_MASK, 0,
+				 timeout_us);
+	if (ret) {
+		dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n");
+
+		ret = -ETIMEDOUT;
+	}
+
+	return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
+}
+
+static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op)
+{
+	if (unlikely(op->dummy.nbytes && !op->addr.nbytes)) {
+		/*
+		 * SFC not support output DUMMY cycles right after CMD cycles, so
+		 * treat it as ADDR cycles.
+		 */
+		op->addr.nbytes = op->dummy.nbytes;
+		op->addr.buswidth = op->dummy.buswidth;
+		op->addr.val = 0xFFFFFFFFF;
+
+		op->dummy.nbytes = 0;
+	}
+}
+
+static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
+				   struct spi_mem *mem,
+				   const struct spi_mem_op *op,
+				   u32 len)
+{
+	u32 ctrl = 0, cmd = 0;
+
+	/* set CMD */
+	cmd = op->cmd.opcode;
+	ctrl |= ((op->cmd.buswidth >> 1) << SFC_CTRL_CMD_BITS_SHIFT);
+
+	/* set ADDR */
+	if (op->addr.nbytes) {
+		if (op->addr.nbytes == 4) {
+			cmd |= SFC_CMD_ADDR_32BITS << SFC_CMD_ADDR_SHIFT;
+		} else if (op->addr.nbytes == 3) {
+			cmd |= SFC_CMD_ADDR_24BITS << SFC_CMD_ADDR_SHIFT;
+		} else {
+			cmd |= SFC_CMD_ADDR_XBITS << SFC_CMD_ADDR_SHIFT;
+			writel(op->addr.nbytes * 8 - 1, sfc->regbase + SFC_ABIT);
+		}
+
+		ctrl |= ((op->addr.buswidth >> 1) << SFC_CTRL_ADDR_BITS_SHIFT);
+	}
+
+	/* set DUMMY */
+	if (op->dummy.nbytes) {
+		if (op->dummy.buswidth == 4)
+			cmd |= op->dummy.nbytes * 2 << SFC_CMD_DUMMY_SHIFT;
+		else if (op->dummy.buswidth == 2)
+			cmd |= op->dummy.nbytes * 4 << SFC_CMD_DUMMY_SHIFT;
+		else
+			cmd |= op->dummy.nbytes * 8 << SFC_CMD_DUMMY_SHIFT;
+	}
+
+	/* set DATA */
+	if (sfc->version >= SFC_VER_4) /* Clear it if no data to transfer */
+		writel(len, sfc->regbase + SFC_LEN_EXT);
+	else
+		cmd |= len << SFC_CMD_TRAN_BYTES_SHIFT;
+	if (len) {
+		if (op->data.dir == SPI_MEM_DATA_OUT)
+			cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT;
+
+		ctrl |= ((op->data.buswidth >> 1) << SFC_CTRL_DATA_BITS_SHIFT);
+	}
+	if (!len && op->addr.nbytes)
+		cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT;
+
+	/* set the Controller */
+	ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
+	cmd |= mem->spi->chip_select << SFC_CMD_CS_SHIFT;
+
+	dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
+		op->addr.nbytes, op->addr.buswidth,
+		op->dummy.nbytes, op->dummy.buswidth);
+	dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
+		ctrl, cmd, op->addr.val, len);
+
+	writel(ctrl, sfc->regbase + SFC_CTRL);
+	writel(cmd, sfc->regbase + SFC_CMD);
+	if (op->addr.nbytes)
+		writel(op->addr.val, sfc->regbase + SFC_ADDR);
+
+	return 0;
+}
+
+static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int len)
+{
+	u8 bytes = len & 0x3;
+	u32 dwords;
+	int tx_level;
+	u32 write_words;
+	u32 tmp = 0;
+
+	dwords = len >> 2;
+	while (dwords) {
+		tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
+		if (tx_level < 0)
+			return tx_level;
+		write_words = min_t(u32, tx_level, dwords);
+		iowrite32_rep(sfc->regbase + SFC_DATA, buf, write_words);
+		buf += write_words << 2;
+		dwords -= write_words;
+	}
+
+	/* write the rest non word aligned bytes */
+	if (bytes) {
+		tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
+		if (tx_level < 0)
+			return tx_level;
+		memcpy(&tmp, buf, bytes);
+		writel(tmp, sfc->regbase + SFC_DATA);
+	}
+
+	return len;
+}
+
+static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
+{
+	u8 bytes = len & 0x3;
+	u32 dwords;
+	u8 read_words;
+	int rx_level;
+	int tmp;
+
+	/* word aligned access only */
+	dwords = len >> 2;
+	while (dwords) {
+		rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
+		if (rx_level < 0)
+			return rx_level;
+		read_words = min_t(u32, rx_level, dwords);
+		ioread32_rep(sfc->regbase + SFC_DATA, buf, read_words);
+		buf += read_words << 2;
+		dwords -= read_words;
+	}
+
+	/* read the rest non word aligned bytes */
+	if (bytes) {
+		rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
+		if (rx_level < 0)
+			return rx_level;
+		tmp = readl(sfc->regbase + SFC_DATA);
+		memcpy(buf, &tmp, bytes);
+	}
+
+	return len;
+}
+
+static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t dma_buf, size_t len)
+{
+	writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
+	writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR);
+	writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER);
+
+	return len;
+}
+
+static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,
+				       const struct spi_mem_op *op, u32 len)
+{
+	dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len);
+
+	if (op->data.dir == SPI_MEM_DATA_OUT)
+		return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len);
+	else
+		return rockchip_sfc_read_fifo(sfc, op->data.buf.in, len);
+}
+
+static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
+				      const struct spi_mem_op *op, u32 len)
+{
+	int ret;
+
+	dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
+
+	if (op->data.dir == SPI_MEM_DATA_OUT)
+		memcpy_toio(sfc->buffer, op->data.buf.out, len);
+
+	ret = rockchip_sfc_fifo_transfer_dma(sfc, sfc->dma_buffer, len);
+	if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) {
+		dev_err(sfc->dev, "DMA wait for transfer finish timeout\n");
+		ret = -ETIMEDOUT;
+	}
+	rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA);
+	if (op->data.dir == SPI_MEM_DATA_IN)
+		memcpy_fromio(op->data.buf.in, sfc->buffer, len);
+
+	return ret;
+}
+
+static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
+{
+	int ret = 0;
+	u32 status;
+
+	ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
+				 !(status & SFC_SR_IS_BUSY),
+				 20, timeout_us);
+	if (ret) {
+		dev_err(sfc->dev, "wait sfc idle timeout\n");
+		rockchip_sfc_reset(sfc);
+
+		ret = -EIO;
+	}
+
+	return ret;
+}
+
+static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+	struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master);
+	u32 len = op->data.nbytes;
+	int ret;
+
+	if (unlikely(mem->spi->max_speed_hz != sfc->frequency)) {
+		ret = clk_set_rate(sfc->clk, mem->spi->max_speed_hz);
+		if (ret)
+			return ret;
+		sfc->frequency = mem->spi->max_speed_hz;
+		dev_dbg(sfc->dev, "set_freq=%dHz real_freq=%ldHz\n",
+			sfc->frequency, clk_get_rate(sfc->clk));
+	}
+
+	rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
+	rockchip_sfc_xfer_setup(sfc, mem, op, len);
+	if (len) {
+		if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD) {
+			init_completion(&sfc->cp);
+			rockchip_sfc_irq_unmask(sfc, SFC_IMR_DMA);
+			ret = rockchip_sfc_xfer_data_dma(sfc, op, len);
+		} else {
+			ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
+		}
+
+		if (ret != len) {
+			dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);
+
+			return -EIO;
+		}
+	}
+
+	return rockchip_sfc_xfer_done(sfc, 100000);
+}
+
+static int rockchip_sfc_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+{
+	struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master);
+
+	op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
+
+	return 0;
+}
+
+static const struct spi_controller_mem_ops rockchip_sfc_mem_ops = {
+	.exec_op = rockchip_sfc_exec_mem_op,
+	.adjust_op_size = rockchip_sfc_adjust_op_size,
+};
+
+static irqreturn_t rockchip_sfc_irq_handler(int irq, void *dev_id)
+{
+	struct rockchip_sfc *sfc = dev_id;
+	u32 reg;
+
+	reg = readl(sfc->regbase + SFC_RISR);
+
+	/* Clear interrupt */
+	writel_relaxed(reg, sfc->regbase + SFC_ICLR);
+
+	if (reg & SFC_RISR_DMA) {
+		complete(&sfc->cp);
+
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int rockchip_sfc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct spi_master *master;
+	struct resource *res;
+	struct rockchip_sfc *sfc;
+	int ret;
+
+	master = devm_spi_alloc_master(&pdev->dev, sizeof(*sfc));
+	if (!master)
+		return -ENOMEM;
+
+	master->flags = SPI_MASTER_HALF_DUPLEX;
+	master->mem_ops = &rockchip_sfc_mem_ops;
+	master->dev.of_node = pdev->dev.of_node;
+	master->mode_bits = SPI_TX_QUAD | SPI_TX_DUAL | SPI_RX_QUAD | SPI_RX_DUAL;
+	master->max_speed_hz = SFC_MAX_SPEED;
+	master->num_chipselect = SFC_MAX_CHIPSELECT_NUM;
+
+	sfc = spi_master_get_devdata(master);
+	sfc->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	sfc->regbase = devm_ioremap_resource(dev, res);
+	if (IS_ERR(sfc->regbase))
+		return PTR_ERR(sfc->regbase);
+
+	sfc->clk = devm_clk_get(&pdev->dev, "clk_sfc");
+	if (IS_ERR(sfc->clk)) {
+		dev_err(&pdev->dev, "Failed to get sfc interface clk\n");
+		return PTR_ERR(sfc->clk);
+	}
+
+	sfc->hclk = devm_clk_get(&pdev->dev, "hclk_sfc");
+	if (IS_ERR(sfc->hclk)) {
+		dev_err(&pdev->dev, "Failed to get sfc ahb clk\n");
+		return PTR_ERR(sfc->hclk);
+	}
+
+	sfc->use_dma = !of_property_read_bool(sfc->dev->of_node,
+					      "rockchip,sfc-no-dma");
+
+	if (sfc->use_dma) {
+		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+		if (ret) {
+			dev_warn(dev, "Unable to set dma mask\n");
+			return ret;
+		}
+
+		sfc->buffer = dmam_alloc_coherent(dev, SFC_MAX_IOSIZE_VER3,
+						  &sfc->dma_buffer,
+						  GFP_KERNEL);
+		if (!sfc->buffer)
+			return -ENOMEM;
+	}
+
+	ret = clk_prepare_enable(sfc->hclk);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to enable ahb clk\n");
+		goto err_hclk;
+	}
+
+	ret = clk_prepare_enable(sfc->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to enable interface clk\n");
+		goto err_clk;
+	}
+
+	/* Find the irq */
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0) {
+		dev_err(dev, "Failed to get the irq\n");
+		goto err_irq;
+	}
+
+	ret = devm_request_irq(dev, ret, rockchip_sfc_irq_handler,
+			       0, pdev->name, sfc);
+	if (ret) {
+		dev_err(dev, "Failed to request irq\n");
+
+		return ret;
+	}
+
+	ret = rockchip_sfc_init(sfc);
+	if (ret)
+		goto err_irq;
+
+	sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
+	sfc->version = rockchip_sfc_get_version(sfc);
+
+	ret = spi_register_master(master);
+	if (ret)
+		goto err_irq;
+
+	return 0;
+
+err_irq:
+	clk_disable_unprepare(sfc->clk);
+err_clk:
+	clk_disable_unprepare(sfc->hclk);
+err_hclk:
+	return ret;
+}
+
+static int rockchip_sfc_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct rockchip_sfc *sfc = platform_get_drvdata(pdev);
+
+	spi_unregister_master(master);
+
+	clk_disable_unprepare(sfc->clk);
+	clk_disable_unprepare(sfc->hclk);
+
+	return 0;
+}
+
+static const struct of_device_id rockchip_sfc_dt_ids[] = {
+	{ .compatible = "rockchip,sfc"},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rockchip_sfc_dt_ids);
+
+static struct platform_driver rockchip_sfc_driver = {
+	.driver = {
+		.name	= "rockchip-sfc",
+		.of_match_table = rockchip_sfc_dt_ids,
+	},
+	.probe	= rockchip_sfc_probe,
+	.remove	= rockchip_sfc_remove,
+};
+module_platform_driver(rockchip_sfc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Rockchip Serial Flash Controller Driver");
+MODULE_AUTHOR("Shawn Lin <shawn.lin at rock-chips.com>");
+MODULE_AUTHOR("Chris Morgan <macromorgan at hotmail.com>");
+MODULE_AUTHOR("Jon Lin <Jon.lin at rock-chips.com>");
-- 
2.17.1





From jon.lin at rock-chips.com  Thu Aug 12 06:45:44 2021
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 12 Aug 2021 21:45:44 +0800
Subject: [PATCH v13 4/6] arm: dts: rockchip: Add SFC to RV1108
In-Reply-To: <20210812134546.31340-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
Message-ID: <20210812134546.31340-5-jon.lin@rock-chips.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add a devicetree entry for the Rockchip SFC for the RV1108 SOC.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
Changes in v1: None

 arch/arm/boot/dts/rv1108.dtsi | 37 +++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi
index 9bd0acf3b708..6ec9b25a9e0a 100644
--- a/arch/arm/boot/dts/rv1108.dtsi
+++ b/arch/arm/boot/dts/rv1108.dtsi
@@ -536,6 +536,17 @@
 		status = "disabled";
 	};
 
+	sfc: spi at 301c0000 {
+		compatible = "rockchip,sfc";
+		reg = <0x301c0000 0x4000>;
+		interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+		clock-names = "clk_sfc", "hclk_sfc";
+		pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus4>;
+		pinctrl-names = "default";
+		status = "disabled";
+	};
+
 	gmac: eth at 30200000 {
 		compatible = "rockchip,rv1108-gmac";
 		reg = <0x30200000 0x10000>;
@@ -704,6 +715,32 @@
 			};
 		};
 
+		sfc {
+			sfc_bus4: sfc-bus4 {
+				rockchip,pins =
+					<2 RK_PA0 3 &pcfg_pull_none>,
+					<2 RK_PA1 3 &pcfg_pull_none>,
+					<2 RK_PA2 3 &pcfg_pull_none>,
+					<2 RK_PA3 3 &pcfg_pull_none>;
+			};
+
+			sfc_bus2: sfc-bus2 {
+				rockchip,pins =
+					<2 RK_PA0 3 &pcfg_pull_none>,
+					<2 RK_PA1 3 &pcfg_pull_none>;
+			};
+
+			sfc_cs0: sfc-cs0 {
+				rockchip,pins =
+					<2 RK_PB4 3 &pcfg_pull_none>;
+			};
+
+			sfc_clk: sfc-clk {
+				rockchip,pins =
+					<2 RK_PB7 2 &pcfg_pull_none>;
+			};
+		};
+
 		gmac {
 			rmii_pins: rmii-pins {
 				rockchip,pins =	<1 RK_PC5 2 &pcfg_pull_none>,
-- 
2.17.1





From jon.lin at rock-chips.com  Thu Aug 12 06:46:38 2021
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 12 Aug 2021 21:46:38 +0800
Subject: [PATCH v13 5/6] arm64: dts: rockchip: Add SFC to RK3308
In-Reply-To: <20210812134546.31340-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
Message-ID: <20210812134639.31586-1-jon.lin@rock-chips.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add a devicetree entry for the Rockchip SFC for the RK3308 SOC.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
Changes in v1: None

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

diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
index a185901aba9a..ce6f4a28d169 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
@@ -731,6 +731,17 @@
 		status = "disabled";
 	};
 
+	sfc: spi at ff4c0000 {
+		compatible = "rockchip,sfc";
+		reg = <0x0 0xff4c0000 0x0 0x4000>;
+		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+		clock-names = "clk_sfc", "hclk_sfc";
+		pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus4>;
+		pinctrl-names = "default";
+		status = "disabled";
+	};
+
 	cru: clock-controller at ff500000 {
 		compatible = "rockchip,rk3308-cru";
 		reg = <0x0 0xff500000 0x0 0x1000>;
@@ -1004,6 +1015,32 @@
 			};
 		};
 
+		sfc {
+			sfc_bus4: sfc-bus4 {
+				rockchip,pins =
+					<3 RK_PA0 3 &pcfg_pull_none>,
+					<3 RK_PA1 3 &pcfg_pull_none>,
+					<3 RK_PA2 3 &pcfg_pull_none>,
+					<3 RK_PA3 3 &pcfg_pull_none>;
+			};
+
+			sfc_bus2: sfc-bus2 {
+				rockchip,pins =
+					<3 RK_PA0 3 &pcfg_pull_none>,
+					<3 RK_PA1 3 &pcfg_pull_none>;
+			};
+
+			sfc_cs0: sfc-cs0 {
+				rockchip,pins =
+					<3 RK_PA4 3 &pcfg_pull_none>;
+			};
+
+			sfc_clk: sfc-clk {
+				rockchip,pins =
+					<3 RK_PA5 3 &pcfg_pull_none>;
+			};
+		};
+
 		gmac {
 			rmii_pins: rmii-pins {
 				rockchip,pins =
-- 
2.17.1





From jon.lin at rock-chips.com  Thu Aug 12 06:46:39 2021
From: jon.lin at rock-chips.com (Jon Lin)
Date: Thu, 12 Aug 2021 21:46:39 +0800
Subject: [PATCH v13 6/6] arm64: dts: rockchip: Enable SFC for Odroid Go Advance
In-Reply-To: <20210812134639.31586-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
 <20210812134639.31586-1-jon.lin@rock-chips.com>
Message-ID: <20210812134639.31586-2-jon.lin@rock-chips.com>

From: Chris Morgan <macromorgan at hotmail.com>

This enables the Rockchip Serial Flash Controller for the Odroid Go
Advance. Note that while the attached SPI NOR flash and the controller
both support quad read mode, only 2 of the required 4 pins are present.
The rx bus width is set to 2 for this reason, and tx bus width is set
to 1 for compatibility reasons.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

Changes in v13: None
Changes in v12: None
Changes in v11:
- The tx is set to 1 for Odroid Go Advance device

Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None
Changes in v1: None

 .../boot/dts/rockchip/rk3326-odroid-go2.dts      | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts b/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts
index 7fc674a99a6c..35218c2771a2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts
@@ -517,6 +517,22 @@
 	status = "okay";
 };
 
+&sfc {
+	pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>;
+	pinctrl-names = "default";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <108000000>;
+		spi-rx-bus-width = <2>;
+		spi-tx-bus-width = <1>;
+	};
+};
+
 &tsadc {
 	status = "okay";
 };
-- 
2.17.1





From ikjn at chromium.org  Thu Aug 12 06:47:22 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Thu, 12 Aug 2021 21:47:22 +0800
Subject: [RFC PATCH] usb: xhci-mtk: handle bandwidth table rollover
In-Reply-To: <efcd999aaf83cf73ed2f4f4b9efa1bb93efd2523.camel@mediatek.com>
References: <20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid>
 <YRDxTodNNqtnpPpn@kroah.com>
 <CAATdQgDSCzZtiDSQk94CYHfSb9Mq28OH7-RdaTZNv3oPrW3nkQ@mail.gmail.com>
 <7b48f4c132a8b4b3819282e961fbe8b3ed753069.camel@mediatek.com>
 <CAATdQgD1paUUmWhiLVq-+zq0V6=RTJw89ggk=R6cBUZO+5dB-Q@mail.gmail.com>
 <efcd999aaf83cf73ed2f4f4b9efa1bb93efd2523.camel@mediatek.com>
Message-ID: <CAATdQgATOhAcr7uMyxAvZCdngMaa-bbG3GDpun11LHOHeLqMjQ@mail.gmail.com>

oops sorry I sent a prior mail in HTML.
Resend this mail in plain text.

On Thu, Aug 12, 2021 at 7:49 PM Chunfeng Yun (???)
<Chunfeng.Yun at mediatek.com> wrote:
>
> On Thu, 2021-08-12 at 17:31 +0800, Ikjoon Jang wrote:
> > HI,
> >
> > On Wed, Aug 11, 2021 at 5:02 PM Chunfeng Yun (???)
> > <Chunfeng.Yun at mediatek.com> wrote:
> > >
> > > On Mon, 2021-08-09 at 17:42 +0800, Ikjoon Jang wrote:
> > > > On Mon, Aug 9, 2021 at 5:11 PM Greg Kroah-Hartman
> > > > <gregkh at linuxfoundation.org> wrote:
> > > > >
> > > > > On Mon, Aug 09, 2021 at 04:59:29PM +0800, Ikjoon Jang wrote:
> > > > > > xhci-mtk has 64 slots for periodic bandwidth calculations and
> > > > > > each
> > > > > > slot represents byte budgets on a microframe. When an
> > > > > > endpoint's
> > > > > > allocation sits on the boundary of the table, byte budgets'
> > > > > > slot
> > > > > > should be rolled over but the current implementation doesn't.
> > > > > >
> > > > > > This patch applies a 6 bits mask to the microframe index to
> > > > > > handle
> > > > > > its rollover 64 slots and prevent out-of-bounds array access.
> > > > > >
> > > > > > Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
> > > > > > ---
> > > > > >
> > > > > >  drivers/usb/host/xhci-mtk-sch.c | 79 +++++++++------------
> > > > > > ----
> > > > > > --------
> > > > > >  drivers/usb/host/xhci-mtk.h     |  1 +
> > > > > >  2 files changed, 23 insertions(+), 57 deletions(-)
> > > > >
> > > > > Why is this "RFC"?  What needs to be addressed in this change
> > > > > before it
> > > > > can be accepted?
> > > >
> > > > sorry, I had to mention why this is RFC:
> > > >
> > > > I simply don't know about the details of the xhci-mtk internals.
> > > > It was okay from my tests with mt8173 and I think this will be
> > > > harmless
> > > > as this is "better than before".
> > > >
> > > > But when I removed get_esit_boundary(), I really have no idea why
> > > > it was there. I'm wondering if there was another reason of that
> > > > function
> > > > other than just preventing out-of-bounds. Maybe chunfeng can
> > > > answer
> > > > this?
> > >
> > > We use @esit to prevent out-of-bounds array access. it's not a
> > > ring,
> > > can't insert out-of-bounds value into head slot.
> >
> > Thanks, so that function was only for out-of-bounds array access.
> > then I think we just can remove that function and use it as a ring.
> > Can you tell me _why_ it can't be used as a ring?
> Treat it as a period, roll over slot equals to put it into the next
> period.
>
> >
> > I think a transaction (e.g. esit_boundary = 7) can start its first
> > SSPLIT
> > from Y_7 (offset = 7). But will that allocation be matched with this?
> >
> > -               if ((offset + sch_ep->num_budget_microframes) >
> > esit_boundary)
> > -                       break;
> >
> > I mean I'm not sure why this is needed.
> Prevent out-of-bounds.
>
> >
> > Until now, I couldn't find a way to accept the USB audio headset
> > with a configuration of { INT-IN 64 + ISOC-OUT 384 + ISOC-IN 192 }
> > without this patch.
> what is the interval value of each endpoint?

interrupt ep is 2ms and others are 1ms
Thanks.

>
> >
> > >
> > > >
> > > > Thanks!
> > > >
> > > > >
> > > > > thanks,
> > > > >
> > > > > greg k-h


From wangkefeng.wang at huawei.com  Thu Aug 12 06:51:46 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Thu, 12 Aug 2021 21:51:46 +0800
Subject: [PATCH v3 0/6] ARM: mm: cleanup page fault and fix pxn process
 issue
In-Reply-To: <a0c4b967-0dba-24eb-1c8d-580de1948e1c@huawei.com>
References: <20210610123556.171328-1-wangkefeng.wang@huawei.com>
 <a0c4b967-0dba-24eb-1c8d-580de1948e1c@huawei.com>
Message-ID: <a0f57e1f-0777-b072-ac5f-4cc4789cee9f@huawei.com>


On 2021/7/31 14:42, Kefeng Wang wrote:
>
> On 2021/6/10 20:35, Kefeng Wang wrote:
>> The patchset cleanup ARM page fault handle to improve readability,
>> fix the page table entries printing and fix infinite loop in the
>> page fault handler when user code execution with privilege mode if
>> ARM_LPAE enabled.
>
> Hi? Russell? I make some changes according your advise, could you give 
> me
>
> some comments about this patchset, I want to make sure that whether they
>
> can be sent to? the ARM patch system,? many thanks.

Keep ping...

>
>> v3:
>> - drop the fix about page table printing
>> - kill page table base print instead of printing the physical address
>> - only die when permission fault both kernel-mode and user code 
>> execution
>> ?? with privilege mode
>> - drop LPAE specific
>>


From Hari.PrasathGE at microchip.com  Thu Aug 12 07:07:57 2021
From: Hari.PrasathGE at microchip.com (Hari Prasath)
Date: Thu, 12 Aug 2021 19:37:57 +0530
Subject: [PATCH 1/2] ARM: at91: dts: sama5d29: Add dtsi file for sama5d29
Message-ID: <20210812140758.28273-1-Hari.PrasathGE@microchip.com>

A new dtsi file for sama5d29 SoC is added which basically inherits the sama5d2
dtsi with the mac controller compatible property updated.

Signed-off-by: Hari Prasath <Hari.PrasathGE at microchip.com>
---
 arch/arm/boot/dts/sama5d29.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 arch/arm/boot/dts/sama5d29.dtsi

diff --git a/arch/arm/boot/dts/sama5d29.dtsi b/arch/arm/boot/dts/sama5d29.dtsi
new file mode 100644
index 000000000000..e8cc73c0619f
--- /dev/null
+++ b/arch/arm/boot/dts/sama5d29.dtsi
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * sama5d29.dtsi - Device Tree Include file for SAMA5D29 SoC of the SAMA5D2
+ * family.
+ *
+ *  Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ *
+ *  Author: Hari Prasath <Hari.PrasathGE at microchip.com>
+ *
+ */
+
+#include "sama5d2.dtsi"
+
+&macb0 {
+compatible = "atmel,sama5d29-gem";
+};
-- 
2.17.1



From Hari.PrasathGE at microchip.com  Thu Aug 12 07:07:58 2021
From: Hari.PrasathGE at microchip.com (Hari Prasath)
Date: Thu, 12 Aug 2021 19:37:58 +0530
Subject: [PATCH 2/2] ARM: at91: dts: at91-sama5d2_xplained: Add comments for
 sama5d29
In-Reply-To: <20210812140758.28273-1-Hari.PrasathGE@microchip.com>
References: <20210812140758.28273-1-Hari.PrasathGE@microchip.com>
Message-ID: <20210812140758.28273-2-Hari.PrasathGE@microchip.com>

Add comments for the end user for modifying the DTS file for
instantiating the sama5d29 SoC.

Signed-off-by: Hari Prasath <Hari.PrasathGE at microchip.com>
---
 arch/arm/boot/dts/at91-sama5d2_xplained.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
index 627b7bf88d83..faa30063d9a9 100644
--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
@@ -6,6 +6,11 @@
  *                2015 Nicolas Ferre <nicolas.ferre at atmel.com>
  */
 /dts-v1/;
+/*
+ * Replace the line below with "sama5d29.dtsi" in order to instantiate the
+ * sama5d29 SoC of the sama5d2 family.Otherwise, leave it unchanged when
+ * using sama5d27 SoC for instance.
+ */
 #include "sama5d2.dtsi"
 #include "sama5d2-pinfunc.h"
 #include <dt-bindings/mfd/atmel-flexcom.h>
-- 
2.17.1



From thierry.reding at gmail.com  Thu Aug 12 07:17:12 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 12 Aug 2021 16:17:12 +0200
Subject: [PATCH] arm64: tegra: Add missing interconnects property for USB on
 Tegra186
Message-ID: <20210812141712.2394152-1-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

The device tree node for the XUDC (USB device mode controller) is
missing the interconnects property that describes the path to memory for
the controller. Add the property so that the things like the DMA mask
can be set by the operating system.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index d1e20dbc5f4b..5c45fab0c9ab 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -826,6 +826,9 @@ usb at 3550000 {
 			 <&bpmp TEGRA186_CLK_XUSB_CORE_SS>,
 			 <&bpmp TEGRA186_CLK_XUSB_FS>;
 		clock-names = "dev", "ss", "ss_src", "fs_src";
+		interconnects = <&mc TEGRA186_MEMORY_CLIENT_XUSB_DEVR &emc>,
+				<&mc TEGRA186_MEMORY_CLIENT_XUSB_DEVW &emc>;
+		interconnect-names = "dma-mem", "write";
 		iommus = <&smmu TEGRA186_SID_XUSB_DEV>;
 		power-domains = <&bpmp TEGRA186_POWER_DOMAIN_XUSBB>,
 				<&bpmp TEGRA186_POWER_DOMAIN_XUSBA>;
-- 
2.32.0



From alexandru.elisei at arm.com  Thu Aug 12 07:24:03 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 12 Aug 2021 15:24:03 +0100
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
In-Reply-To: <871r6yajy7.wl-maz@kernel.org>
References: <20210811171505.1502090-1-wenst@chromium.org>
 <87fsvfal4n.wl-maz@kernel.org> <79eabae1-e4a3-7a12-7aa0-3680569584e5@arm.com>
 <871r6yajy7.wl-maz@kernel.org>
Message-ID: <061bafb6-b0fe-bd7c-1567-a642d3ddd4a5@arm.com>

Hi Marc,

On 8/12/21 2:09 PM, Marc Zyngier wrote:
> On Thu, 12 Aug 2021 12:51:34 +0100,
> Alexandru Elisei <alexandru.elisei at arm.com> wrote:
>> Hi,
>>
>> After re-familiarizing myself with the spec, it starting to look to
>> me like indeed there's something not quite right (read as: totally
>> broken) with my patch.
>>
>> Arm IHI 0069F, the pseudocode for reading ICC_RPR_EL1 (page 11-797),
>> says that the priority returned is unchanged if SCTLR_EL3.FIQ ==
>> 0.
> Sure, but look at what ICC_RPR_EL1 does for FIQ==1:
>
> <quote>
> if HaveEL(EL3) && !IsSecure() && SCR_EL3.FIQ == '1' then
>     // A Non-secure GIC access and Group 0 inaccessible to Non-secure.
>         if pPriority<7> == '0' then
> 	    // Priority is in Secure half and not visible to Non-secure
> 	    Priority = Zeros();
>         elsif !IsOnes(pPriority) then
> 	    // Non-secure access and not idle, so physical priority must be shifted
>             pPriority<7:0> = (pPriority AND PRIMask())<6:0>:'0';
>
> return ZeroExtend(pPriority);
> </quote>
>
> See how the the priority is shifted *left* (bits [6:0] end up in
> [7:1])?

Yes, when SCR_EL3.FIQ=1, but gic_nonsecure_priorities is enabled when
SCR_EL3.FIQ=0 (gic_has_group0()). In that case ICC_RPR_EL1 returns (what I assume
to be) the highest priority interrupt from ICC_AP0R_EL1, ICC_AP1R_EL1NS and
ICC_AP1R_EL1S. Isn't that the secure view (or Distributor value) of the priority?

>
>> This means that the ICC_RPR_EL1 read will return the secure view
>> (the value as it is stored by the GIC) of the priority, so for
>> pseudo-nmis it will return (GICD_INT_NMI_PRI >> 1) | 0x80, which
>> definitely != GICD_INT_NMI_PRI.
> That's not my reading of the pseudocode.
>
>> This is further confirmed by this statement on page 4-67:
>>
>> "When GICD_CTLR.DS == 0, [..] For Non-secure access to ICC_PMR_EL1
>> and ICC_RPR_EL1 when SCR_EL3.FIQ == 0: The Secure, unshifted view
>> applies."
>>
>> I don't know how I missed that during testing.
>>
>> Did a quick test on the model with PMU NMIs (GICD_CTRL.DS = 0,
>> SCTLR_EL2.FIQ = 0), gic_handle_nmi() was not being called at all,
> 0? Really????

Yes, I was also very surprised myself, I was certain that I tested my patch on the
model with PMU NMIs. Here's what I did to get this result, I would very much
appreciate anyone pointing out what I did wrong here.

$ git diff
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e0f4debe64e1..749748df2466 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -623,6 +623,8 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
??????? bool irqs_enabled = interrupts_enabled(regs);
??????? int err;
?
+?????? panic("Pseudo-NMI");
+
??????? if (irqs_enabled)
??????????????? nmi_enter();
?
@@ -1654,8 +1656,10 @@ static void gic_enable_nmi_support(void)
???????? * be in the non-secure range, we use a different PMR value to mask IRQs
???????? * and the rest of the values that we use remain unchanged.
???????? */
-?????? if (gic_has_group0() && !gic_dist_security_disabled())
+?????? if (gic_has_group0() && !gic_dist_security_disabled()) {
+?????????????? pr_info("enabling gic_nonsecure_priorities");
??????????????? static_branch_enable(&gic_nonsecure_priorities);
+?????? }
?
??????? static_branch_enable(&supports_pseudo_nmis);
?
And a truncated log for FVP:

Boot-wrapper v0.2

[..]
[??? 0.000000] Kernel command line: earlycon=pl011,0x1c090000 console=ttyAMA0
kpti=off root=/dev/vda irqchip.gicv3_pseudo_nmi=1
[..]
[??? 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[??? 0.000000] GICv3: GIC: Using split EOI/Deactivate mode
[??? 0.000000] GICv3: 224 SPIs implemented
[??? 0.000000] GICv3: 0 Extended SPIs implemented
[??? 0.000000] GICv3: Distributor has no Range Selector support
[??? 0.000000] Root IRQ handler: gic_handle_irq
[??? 0.000000] GICv3: 16 PPIs implemented
[??? 0.000000] GICv3: CPU0: found redistributor 0 region 0:0x000000002f100000
[??? 0.000000] GICv3: Pseudo-NMIs enabled using relaxed ICC_PMR_EL1 synchronisation
[??? 0.000000] GICv3: enabling gic_nonsecure_priorities
[..]
[??? 0.037784] armv8-pmu pmu: hw perfevents: no interrupt-affinity property, guessing.
[??? 0.037901] hw perfevents: enabled with armv8_pmuv3 PMU driver, 9 counters
available, using NMIs
[..]
# cat /proc/interrupts
?????????? CPU0?????? CPU1?????? CPU2?????? CPU3??????
? 9:????????? 0????????? 0????????? 0????????? 0???? GICv3? 25 Level???? vgic
?11:????????? 0????????? 0????????? 0????????? 0???? GICv3? 30 Level???? kvm guest
ptimer
?12:????????? 0????????? 0????????? 0????????? 0???? GICv3? 27 Level???? kvm guest
vtimer
?13:???????? 83???????? 77???????? 69???????? 88???? GICv3? 26 Level???? arch_timer
?16:????????? 0????????? 0????????? 0????????? 0???? GICv3? 92 Level???? arm-pmu
?17:????????? 0????????? 0????????? 0????????? 0???? GICv3? 93 Level???? arm-pmu
?18:????????? 0????????? 0????????? 0????????? 0???? GICv3? 94 Level???? arm-pmu
?19:????????? 0????????? 0????????? 0????????? 0???? GICv3? 95 Level???? arm-pmu
?22:????????? 0????????? 0????????? 0????????? 0???? GICv3? 47 Level???? eth0
?24:???????? 33????????? 0????????? 0????????? 0???? GICv3? 37 Level???? uart-pl011
?29:????????? 0????????? 0????????? 0????????? 0???? GICv3? 36 Level???? rtc-pl031
?31:??????? 138????????? 0????????? 0????????? 0???? GICv3? 74 Level???? virtio0
IPI0:?????? 251??????? 334??????? 252??????? 172?????? Rescheduling interrupts
IPI1:??????? 26???????? 23???????? 10???????? 20?????? Function call interrupts
IPI2:???????? 0????????? 0????????? 0????????? 0?????? CPU stop interrupts
IPI3:???????? 0????????? 0????????? 0????????? 0?????? CPU stop (for crash dump)
interrupts
IPI4:???????? 0????????? 0????????? 0????????? 0?????? Timer broadcast interrupts
IPI5:???????? 0????????? 0????????? 0????????? 0?????? IRQ work interrupts
IPI6:???????? 0????????? 0????????? 0????????? 0?????? CPU wake-up interrupts
Err:????????? 0
# perf record -a -- sleep 5

^C[ perf record: Woken up 1 times to write data ]
[??? 6.908820] random: perf: uninitialized urandom read (6 bytes read)

[??? 7.596139] random: perf: uninitialized urandom read (6 bytes read)
[ perf record: Captured and wrote 0.013 MB perf.data (24 samples) ]

#
# cat /proc/interrupts
?????????? CPU0?????? CPU1?????? CPU2?????? CPU3??????
? 9:????????? 0????????? 0????????? 0????????? 0???? GICv3? 25 Level???? vgic
?11:????????? 0????????? 0????????? 0????????? 0???? GICv3? 30 Level???? kvm guest
ptimer
?12:????????? 0????????? 0????????? 0????????? 0???? GICv3? 27 Level???? kvm guest
vtimer
?13:??????? 546??????? 115???????? 82??????? 132???? GICv3? 26 Level???? arch_timer
?16:????????? 6????????? 0????????? 0????????? 0???? GICv3? 92 Level???? arm-pmu
?17:????????? 0???????? 10????????? 0????????? 0???? GICv3? 93 Level???? arm-pmu
?18:????????? 0????????? 0????????? 4????????? 0???? GICv3? 94 Level???? arm-pmu
?19:????????? 0????????? 0????????? 0????????? 4???? GICv3? 95 Level???? arm-pmu
?22:????????? 0????????? 0????????? 0????????? 0???? GICv3? 47 Level???? eth0
?24:???????? 80????????? 0????????? 0????????? 0???? GICv3? 37 Level???? uart-pl011
?29:????????? 0????????? 0????????? 0????????? 0???? GICv3? 36 Level???? rtc-pl031
?31:??????? 195????????? 0????????? 0????????? 0???? GICv3? 74 Level???? virtio0
IPI0:?????? 259??????? 367??????? 263??????? 224?????? Rescheduling interrupts
IPI1:??????? 27???????? 51???????? 16???????? 24?????? Function call interrupts
IPI2:???????? 0????????? 0????????? 0????????? 0?????? CPU stop interrupts
IPI3:???????? 0????????? 0????????? 0????????? 0?????? CPU stop (for crash dump)
interrupts
IPI4:???????? 0????????? 0????????? 0????????? 0?????? Timer broadcast interrupts
IPI5:???????? 0????????? 0????????? 0????????? 0?????? IRQ work interrupts
IPI6:???????? 0????????? 0????????? 0????????? 0?????? CPU wake-up interrupts
Err:????????? 0
#

With this change to the driver:

$ git diff
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e0f4debe64e1..e58e62ab64fe 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -623,6 +623,8 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
??????? bool irqs_enabled = interrupts_enabled(regs);
??????? int err;
?
+?????? panic("Pseudo-NMI");
+
??????? if (irqs_enabled)
??????????????? nmi_enter();
?
@@ -687,7 +689,7 @@ static asmlinkage void __exception_irq_entry
gic_handle_irq(struct pt_regs *regs
??????????????? return;
?
??????? if (gic_supports_nmi() &&
-?????????? unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) {
+?????????? unlikely(gic_read_rpr() == ((GICD_INT_NMI_PRI >> 1) | 0x80))) {
??????????????? gic_handle_nmi(irqnr, regs);
??????????????? return;
??????? }
@@ -1654,8 +1656,10 @@ static void gic_enable_nmi_support(void)
???????? * be in the non-secure range, we use a different PMR value to mask IRQs
???????? * and the rest of the values that we use remain unchanged.
???????? */
-?????? if (gic_has_group0() && !gic_dist_security_disabled())
+?????? if (gic_has_group0() && !gic_dist_security_disabled()) {
+?????????????? pr_info("enabling gic_nonsecure_priorities");
??????????????? static_branch_enable(&gic_nonsecure_priorities);
+?????? }
?
??????? static_branch_enable(&supports_pseudo_nmis);
?

This is what I get from FVP (also truncated):

Boot-wrapper v0.2

[..]
[??? 0.000000] Kernel command line: earlycon=pl011,0x1c090000 console=ttyAMA0
kpti=off root=/dev/vda irqchip.gicv3_pseudo_nmi=1
[..]
[??? 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[??? 0.000000] GICv3: GIC: Using split EOI/Deactivate mode
[??? 0.000000] GICv3: 224 SPIs implemented
[??? 0.000000] GICv3: 0 Extended SPIs implemented
[??? 0.000000] GICv3: Distributor has no Range Selector support
[??? 0.000000] Root IRQ handler: gic_handle_irq
[??? 0.000000] GICv3: 16 PPIs implemented
[??? 0.000000] GICv3: CPU0: found redistributor 0 region 0:0x000000002f100000
[??? 0.000000] GICv3: Pseudo-NMIs enabled using relaxed ICC_PMR_EL1 synchronisation
[??? 0.000000] GICv3: enabling gic_nonsecure_priorities
[..]
[??? 0.037749] armv8-pmu pmu: hw perfevents: no interrupt-affinity property, guessing.
[??? 0.037860] hw perfevents: enabled with armv8_pmuv3 PMU driver, 9 counters
available, using NMIs
[..]
# perf record -a -- sleep 10
[??? 3.556669] Kernel panic - not syncing: Pseudo-NMI
[??? 3.556676] CPU: 0 PID: 145 Comm: perf Not tainted 5.14.0-rc5-dirty #23
[??? 3.556690] Hardware name: FVP Base (DT)
[??? 3.556692] Call trace:
[??? 3.556700]? dump_backtrace+0x0/0x19c
[??? 3.556710]? show_stack+0x1c/0x70
[??? 3.556725]? dump_stack_lvl+0x68/0x84
[??? 3.556729]? dump_stack+0x1c/0x38
[??? 3.556741]? panic+0x16c/0x340
[??? 3.556750]? gic_handle_irq+0x178/0x1a4
[??? 3.556760]? call_on_irq_stack+0x2c/0x58
[??? 3.556776]? do_interrupt_handler+0x54/0x60
[??? 3.556791]? el1_interrupt+0x30/0xa0
[??? 3.556800]? el1h_64_irq_handler+0x1c/0x2c
[??? 3.556809]? el1h_64_irq+0x78/0x7c
[??? 3.556819]? do_vfs_ioctl+0x90/0xd30
[??? 3.556830]? __arm64_sys_ioctl+0x88/0xf0
[??? 3.556842]? invoke_syscall+0x48/0x114
[??? 3.556849]? el0_svc_common+0x48/0x17c
[??? 3.556859]? do_el0_svc+0x2c/0x94
[??? 3.556873]? el0_svc+0x2c/0x5c
[??? 3.556879]? el0t_64_sync_handler+0xa8/0x130
[??? 3.556889]? el0t_64_sync+0x198/0x19c
[??? 3.556907] SMP: stopping secondary CPUs
[??? 3.556919] Kernel Offset: 0x57c5cb480000 from 0xffff800010000000
[??? 3.556922] PHYS_OFFSET: 0xffffebb580000000
[??? 3.556930] CPU features: 0x000000c1,ff3d4eef
[??? 3.556940] Memory Limit: none
[??? 3.556949] ---[ end Kernel panic - not syncing: Pseudo-NMI ]---

>
>> but when I changed the comparison to gic_read_rpr() ==
>> ((GICD_INT_NMI_PRI >> 1) | 0x80), NMIs were being correctly handled
>> again.
> You have completely lost me. This contradicts what you have written
> above.

I don't see how that is the case - ICC_RPR_EL1 contains the priority value as seen
by the Distributor, and non-secure priorities get right-shifted when
SCR_EL3.FIQ=0, meaning that GICD_INT_NMI_PRI becomes (GICD_INT_NMI_PRI >> 1) |
0x80 in the Distributor. Can you elaborate where I'm contradicting myself?

Thanks,

Alex



From quic_qiancai at quicinc.com  Thu Aug 12 07:31:46 2021
From: quic_qiancai at quicinc.com (Qian Cai)
Date: Thu, 12 Aug 2021 10:31:46 -0400
Subject: [PATCH v5] arm pl011 serial: support multi-irq request
In-Reply-To: <bddf2712-72f4-2e20-da17-33b3de08f769@gmail.com>
References: <1625103512-30182-1-git-send-email-hptsfb@gmail.com>
 <60f007b3-bb01-dd0a-b1a2-a6da62a486e5@quicinc.com>
 <3b60d054-4e22-62fa-c31b-29b146495a65@gmail.com>
 <a1843494-5c8e-1ec8-5b98-df318db40922@quicinc.com>
 <7535ae2f-6a12-8203-0498-8ac85ab0d9a7@arm.com>
 <290c01ec-173f-755f-788e-2a33a69586e8@quicinc.com>
 <e98962f3-9232-4abf-ec27-a7524a9e786d@arm.com>
 <bddf2712-72f4-2e20-da17-33b3de08f769@gmail.com>
Message-ID: <0819592c-1baa-e98d-9118-5abde8b8c562@quicinc.com>



On 7/26/2021 10:57 PM, Bing Fan wrote:
> hello,
> 
> Thanks very much for analysis. And i have get the cause of the problem.
> 
> I will add pl011_allocate_multi_irqs/pl011_release_multi_irqs functions for amba drivers,
> 
> and call them in pl011_startup/pl011_shutdown respectively.
> 
> 
> Reserved pl011_allocate_irq/pl011_release_irq functions for platform drivers.
> 
> Please help to confirm, is this ok?

Bing, are you still working on this? It is getting annoying that this commit will also
cause the whole serial console useless and the system unable to login. I am happy to
help if needed.



From linux at roeck-us.net  Thu Aug 12 07:40:01 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 12 Aug 2021 07:40:01 -0700
Subject: [PATCH v4 0/2] memblock: make memblock_find_in_range method
 private
In-Reply-To: <20210812065907.20046-1-rppt@kernel.org>
References: <20210812065907.20046-1-rppt@kernel.org>
Message-ID: <20210812144001.GA837928@roeck-us.net>

Mike,

On Thu, Aug 12, 2021 at 09:59:05AM +0300, Mike Rapoport wrote:
> From: Mike Rapoport <rppt at linux.ibm.com>
> 
> Hi,
> 
> This is v4 of "memblock: make memblock_find_in_range method private" patch
> that essentially replaces memblock_find_in_range() + memblock_reserve()
> calls with equivalent calls to memblock_phys_alloc() and prevents usage of
> memblock_find_in_range() outside memblock itself.
> 
> The patch uncovered an issue with top down memory mapping on x86 and this
> version has a preparation patch that addresses this issue.
> 
> Guenter, I didn't add your Tested-by because the patch that addresses the
> crashes differs from the one you've tested.
> 

Unfortunately I am still seeing crashes.

1G of memory, x86_64:

[    0.000000] efi: EFI v2.70 by EDK II
[    0.000000] efi: SMBIOS=0x3fbcc000 ACPI=0x3fbfa000 ACPI 2.0=0x3fbfa014 MEMATTR=0x3f229018 
[    0.000000] SMBIOS 2.8 present.
[    0.000000] DMI: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
[    0.000000] tsc: Fast TSC calibration using PIT
[    0.000000] tsc: Detected 3792.807 MHz processor
[    0.001816] last_pfn = 0x3ff50 max_arch_pfn = 0x400000000
[    0.002595] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT  
[    0.022989] Using GB pages for direct mapping
[    0.025601] Kernel panic - not syncing: alloc_low_pages: can not alloc memory
[    0.025910] CPU: 0 PID: 0 Comm: swapper Not tainted 5.14.0-rc5+ #1
[    0.026133] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
[    0.026462] Call Trace:
[    0.026942]  ? dump_stack_lvl+0x57/0x7d
[    0.027475]  ? panic+0x10a/0x2de
[    0.027600]  ? alloc_low_pages+0x117/0x156
[    0.027704]  ? phys_pmd_init+0x234/0x342
[    0.027817]  ? phys_pud_init+0x171/0x337
[    0.027926]  ? __kernel_physical_mapping_init+0xec/0x276
[    0.028062]  ? init_memory_mapping+0x1ea/0x2ca
[    0.028199]  ? init_range_memory_mapping+0xdf/0x12e
[    0.028326]  ? init_mem_mapping+0x1e9/0x261
[    0.028432]  ? setup_arch+0x5ff/0xb6d
[    0.028535]  ? start_kernel+0x71/0x6b4
[    0.028636]  ? secondary_startup_64_no_verify+0xc2/0xcb
[    0.029479] ---[ end Kernel panic - not syncing: alloc_low_pages: can not alloc memory ]---

Complete log:
https://kerneltests.org/builders/qemu-x86_64-testing/builds/67/steps/qemubuildcommand/logs/stdio

x86, default memory size, all efi boots affected:

[    0.025676] BUG: unable to handle page fault for address: cf3c1000
[    0.025932] #PF: supervisor write access in kernel mode
[    0.026022] #PF: error_code(0x0002) - not-present page
[    0.026122] *pde = 00000000
[    0.026308] Oops: 0002 [#1] SMP
[    0.026468] CPU: 0 PID: 0 Comm: swapper Not tainted 5.14.0-rc5+ #1
[    0.026616] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
[    0.026848] EIP: alloc_low_pages+0xa0/0x13f
[    0.027355] Code: 00 74 77 a3 cc ba 62 ca 8b 45 f0 8d 90 00 00 0c 00 31 c0 c1 e2 0c 85 f6 74 16 89 d7 b9 00 04 00 00 83 c3 01 81 c2 00 10 00 00 <f3> ab 39 f3 75 ea 8b 45 f0 8d 65 f4 5b 5e c1 e0 0c 5f 5d 2d 00 00
[    0.027802] EAX: 00000000 EBX: 00000001 ECX: 00000400 EDX: cf3c2000
[    0.027903] ESI: 00000001 EDI: cf3c1000 EBP: ca389e28 ESP: ca389e18
[    0.028006] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 EFLAGS: 00200086
[    0.028125] CR0: 80050033 CR2: cf3c1000 CR3: 0a69f000 CR4: 00040690
[    0.028287] Call Trace:
[    0.028603]  one_page_table_init+0x15/0x6d
[    0.028751]  kernel_physical_mapping_init+0xdd/0x19b
[    0.028839]  init_memory_mapping+0x146/0x1f1
[    0.028921]  init_range_memory_mapping+0xfe/0x144
[    0.029001]  init_mem_mapping+0x145/0x185
[    0.029066]  setup_arch+0x5ff/0xa75
[    0.029128]  ? vprintk+0x4c/0x100
[    0.029187]  start_kernel+0x66/0x5ba
[    0.029246]  ? set_intr_gate+0x42/0x55
[    0.029306]  ? early_idt_handler_common+0x44/0x44
[    0.029380]  i386_start_kernel+0x43/0x45
[    0.029441]  startup_32_smp+0x161/0x164
[    0.029567] Modules linked in:
[    0.029776] CR2: 00000000cf3c1000
[    0.030406] random: get_random_bytes called from oops_exit+0x35/0x60 with crng_init=0
[    0.031121] ---[ end trace 544692cd05e387e2 ]---
[    0.031357] EIP: alloc_low_pages+0xa0/0x13f
[    0.031427] Code: 00 74 77 a3 cc ba 62 ca 8b 45 f0 8d 90 00 00 0c 00 31 c0 c1 e2 0c 85 f6 74 16 89 d7 b9 00 04 00 00 83 c3 01 81 c2 00 10 00 00 <f3> ab 39 f3 75 ea 8b 45 f0 8d 65 f4 5b 5e c1 e0 0c 5f 5d 2d 00 00
[    0.031698] EAX: 00000000 EBX: 00000001 ECX: 00000400 EDX: cf3c2000
[    0.031787] ESI: 00000001 EDI: cf3c1000 EBP: ca389e28 ESP: ca389e18
[    0.031876] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 EFLAGS: 00200086
[    0.031972] CR0: 80050033 CR2: cf3c1000 CR3: 0a69f000 CR4: 00040690
[    0.032198] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.032521] ---[ end Kernel panic - not syncing: Attempted to kill the idle
task! ]--

Complete log: 
https://kerneltests.org/builders/qemu-x86-testing/builds/65/steps/qemubuildcommand/logs/stdio

Guenter


From maz at kernel.org  Thu Aug 12 07:45:25 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 15:45:25 +0100
Subject: [PATCH v3 02/13] genirq: Define ack_irq() and eoi_irq() helpers
In-Reply-To: <877dgq9450.mognet@arm.com>
References: <20210629125010.458872-1-valentin.schneider@arm.com>
 <20210629125010.458872-3-valentin.schneider@arm.com>
 <87a6ln9k7i.wl-maz@kernel.org> <877dgq9450.mognet@arm.com>
Message-ID: <87y29690xm.wl-maz@kernel.org>

On Thu, 12 Aug 2021 14:36:11 +0100,
Valentin Schneider <valentin.schneider at arm.com> wrote:
> 
> On 12/08/21 08:49, Marc Zyngier wrote:
> > On Tue, 29 Jun 2021 13:49:59 +0100,
> > Valentin Schneider <valentin.schneider at arm.com> wrote:
> >> +void eoi_irq(struct irq_desc *desc)
> >> +{
> >> +	desc->irq_data.chip->irq_eoi(&desc->irq_data);
> >> +
> >> +	if (desc->irq_data.chip->flags & IRQCHIP_AUTOMASKS_FLOW)
> >> +		irq_state_clr_flow_masked(desc);
> >
> > I just realised that this has a good chance to result in a mess with
> > KVM, and specially the way we let the vGIC deactivate an interrupt
> > directly from the guest, without any SW intervention (the magic HW bit
> > in the LRs).
> >
> 
> I didn't think to consider those. It can't ever be simple, can it...
> 
> > With this, interrupts routed to a guest (such as the timers) will
> > always have the IRQD_IRQ_FLOW_MASKED flag set, which will never be
> > cleared.
> >
> > I wonder whether this have a chance to interact badly with
> > mask/unmask, or with the rest of the flow...
> >
> 
> Isn't it the other way around? That is, eoi_irq() will clear
> IRQD_IRQ_FLOW_MASKED regardless of what happens within chip->irq_eoi(),
> so we would end up with !IRQD_IRQ_FLOW_MASKED even if the (physical) IRQ
> remains Active (irqd_is_forwarded_to_vcpu() case).

Ah, I missed (again) that we always clear the flag, no matter what.

> This does not entirely match reality (if the IRQ is still Active then it is
> still "flow-masked"), but AFAICT this doesn't impact our handling of
> forwarded IRQs: IRQD_IRQ_FLOW_MASKED is only really relevant from ack_irq()
> to eoi_irq(), and deactivation-from-the-guest (propagated via LR.HW=1)
> happens after that.

Right. So we can have an active interrupt that is not flow-masked.
That's counter-intuitive, but that's the GIC architecture for you...

I'll take the series for a ride in -next. If anything breaks, we
should know pretty soon.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Thu Aug 12 07:45:50 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 15:45:50 +0100
Subject: [PATCH v3 05/13] genirq: Let purely flow-masked ONESHOT irqs
 through unmask_threaded_irq()
In-Reply-To: <875ywa944c.mognet@arm.com>
References: <20210629125010.458872-1-valentin.schneider@arm.com>
 <20210629125010.458872-6-valentin.schneider@arm.com>
 <87bl639l8n.wl-maz@kernel.org> <875ywa944c.mognet@arm.com>
Message-ID: <87wnoq90wx.wl-maz@kernel.org>

On Thu, 12 Aug 2021 14:36:35 +0100,
Valentin Schneider <valentin.schneider at arm.com> wrote:
> 
> On 12/08/21 08:26, Marc Zyngier wrote:
> > On Tue, 29 Jun 2021 13:50:02 +0100,
> > Valentin Schneider <valentin.schneider at arm.com> wrote:
> >> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> >> index ef30b4762947..e6d6d32ddcbc 100644
> >> --- a/kernel/irq/manage.c
> >> +++ b/kernel/irq/manage.c
> >> @@ -1107,7 +1107,7 @@ static void irq_finalize_oneshot(struct irq_desc *desc,
> >>  	desc->threads_oneshot &= ~action->thread_mask;
> >>  
> >>  	if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) &&
> >> -	    irqd_irq_masked(&desc->irq_data))
> >> +	    (irqd_irq_masked(&desc->irq_data) | irqd_irq_flow_masked(&desc->irq_data)))
> >>  		unmask_threaded_irq(desc);
> >
> > The bitwise OR looks pretty odd. It is probably fine given that both
> > side of the expression are bool, but still. I can fix this locally.
> >
> 
> Thomas suggested that back in v1:
> 
>   https://lore.kernel.org/lkml/87v98v4lan.ffs at nanos.tec.linutronix.de/
> 
> I did look at the (arm64) disassembly diff back then and was convinced by
> what I saw, though I'd have to go do that again as I can't remember much
> else.

Ah, fair enough.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From biju.das.jz at bp.renesas.com  Thu Aug 12 08:18:06 2021
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Thu, 12 Aug 2021 16:18:06 +0100
Subject: [PATCH v6 1/3] arm64: defconfig: Enable RZ/G2L USBPHY control driver
In-Reply-To: <20210812151808.7916-1-biju.das.jz@bp.renesas.com>
References: <20210812151808.7916-1-biju.das.jz@bp.renesas.com>
Message-ID: <20210812151808.7916-2-biju.das.jz@bp.renesas.com>

RZ/G2L SoC supports USBPHY control,so enable it in ARM64 defconfig.

Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v5->v6:
 * Sorted alphabetically.
v4->v5:
 * No dependencies now. Binding and driver patches accepted for reset/next
v3->v4:
 * No Change.
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c7cf0d1ad34e..0db4925fb788 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1102,6 +1102,7 @@ CONFIG_QCOM_PDC=y
 CONFIG_RESET_IMX7=y
 CONFIG_RESET_QCOM_AOSS=y
 CONFIG_RESET_QCOM_PDC=m
+CONFIG_RESET_RZG2L_USBPHY_CTRL=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_PHY_XGENE=y
 CONFIG_PHY_SUN4I_USB=y
-- 
2.17.1



From broonie at kernel.org  Thu Aug 12 08:23:31 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 12 Aug 2021 16:23:31 +0100
Subject: [RFC PATCH v7 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210812132435.6143-2-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812132435.6143-1-madvenka@linux.microsoft.com>
 <20210812132435.6143-2-madvenka@linux.microsoft.com>
Message-ID: <20210812152331.GA4239@sirena.org.uk>

On Thu, Aug 12, 2021 at 08:24:32AM -0500, madvenka at linux.microsoft.com wrote:

> Here is the list of functions:
> 
> 	perf_callchain_kernel()
> 	get_wchan()
> 	return_address()
> 	dump_backtrace()
> 	profile_pc()

I've not actually gone through this properly yet but my first thought is
that for clarity this should be split out into a patch per user plus one
to delete the old interface  - I'd not worry about it unless it needs to
get resubmitted though.

It'll definitely be good to get this done!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210812/5aa006db/attachment.sig>

From vgomonovych at marvell.com  Thu Aug 12 08:26:14 2021
From: vgomonovych at marvell.com (Vasyl Gomonovych)
Date: Thu, 12 Aug 2021 08:26:14 -0700
Subject: [PATCH] firmware: arm_sdei: Print sdei event number in hex
Message-ID: <20210812152615.28930-1-vgomonovych@marvell.com>

SDEI specified event numbers in hexadecimal format.
Change event number format to hexadecimal to make
it easier for the reader to recognize the proper event.

Signed-off-by: Vasyl Gomonovych <vgomonovych at marvell.com>
---
 drivers/firmware/arm_sdei.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
index a7e762c352f9..66d2869d03f7 100644
--- a/drivers/firmware/arm_sdei.c
+++ b/drivers/firmware/arm_sdei.c
@@ -496,7 +496,7 @@ int sdei_event_unregister(u32 event_num)
 	mutex_lock(&sdei_events_lock);
 	event = sdei_event_find(event_num);
 	if (!event) {
-		pr_warn("Event %u not registered\n", event_num);
+		pr_warn("Event 0x%x not registered\n", event_num);
 		err = -ENOENT;
 		goto unlock;
 	}
@@ -579,7 +579,7 @@ int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg)
 
 	mutex_lock(&sdei_events_lock);
 	if (sdei_event_find(event_num)) {
-		pr_warn("Event %u already registered\n", event_num);
+		pr_warn("Event 0x%x already registered\n", event_num);
 		err = -EBUSY;
 		goto unlock;
 	}
@@ -587,7 +587,7 @@ int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg)
 	event = sdei_event_create(event_num, cb, arg);
 	if (IS_ERR(event)) {
 		err = PTR_ERR(event);
-		pr_warn("Failed to create event %u: %d\n", event_num, err);
+		pr_warn("Failed to create event 0x%x: %d\n", event_num, err);
 		goto unlock;
 	}
 
@@ -605,7 +605,7 @@ int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg)
 
 	if (err) {
 		sdei_event_destroy(event);
-		pr_warn("Failed to register event %u: %d\n", event_num, err);
+		pr_warn("Failed to register event 0x%x: %d\n", event_num, err);
 		goto cpu_unlock;
 	}
 
@@ -635,7 +635,7 @@ static int sdei_reregister_shared(void)
 					sdei_entry_point, event->registered,
 					SDEI_EVENT_REGISTER_RM_ANY, 0);
 			if (err) {
-				pr_err("Failed to re-register event %u\n",
+				pr_err("Failed to re-register event 0x%x\n",
 				       event->event_num);
 				sdei_event_destroy_llocked(event);
 				break;
@@ -645,7 +645,7 @@ static int sdei_reregister_shared(void)
 		if (event->reenable) {
 			err = sdei_api_event_enable(event->event_num);
 			if (err) {
-				pr_err("Failed to re-enable event %u\n",
+				pr_err("Failed to re-enable event 0x%x\n",
 				       event->event_num);
 				break;
 			}
@@ -670,7 +670,7 @@ static int sdei_cpuhp_down(unsigned int cpu)
 
 		err = sdei_do_local_call(_local_event_unregister, event);
 		if (err) {
-			pr_err("Failed to unregister event %u: %d\n",
+			pr_err("Failed to unregister event 0x%x: %d\n",
 			       event->event_num, err);
 		}
 	}
@@ -693,7 +693,7 @@ static int sdei_cpuhp_up(unsigned int cpu)
 		if (event->reregister) {
 			err = sdei_do_local_call(_local_event_register, event);
 			if (err) {
-				pr_err("Failed to re-register event %u: %d\n",
+				pr_err("Failed to re-register event 0x%x: %d\n",
 				       event->event_num, err);
 			}
 		}
@@ -701,7 +701,7 @@ static int sdei_cpuhp_up(unsigned int cpu)
 		if (event->reenable) {
 			err = sdei_do_local_call(_local_event_enable, event);
 			if (err) {
-				pr_err("Failed to re-enable event %u: %d\n",
+				pr_err("Failed to re-enable event 0x%x: %d\n",
 				       event->event_num, err);
 			}
 		}
@@ -1095,7 +1095,7 @@ int sdei_event_handler(struct pt_regs *regs,
 
 	err = arg->callback(event_num, regs, arg->callback_arg);
 	if (err)
-		pr_err_ratelimited("event %u on CPU %u failed with error: %d\n",
+		pr_err_ratelimited("event 0x%x on CPU 0x%x failed with error: %d\n",
 				   event_num, smp_processor_id(), err);
 
 	return err;
-- 
2.17.1



From afaerber at suse.de  Thu Aug 12 08:30:38 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Thu, 12 Aug 2021 17:30:38 +0200
Subject: [PATCH 8/8] MAINTAINERS: Add an entry for NXP S32G2 boards
In-Reply-To: <20210809080346.GO30984@dragon>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-9-clin@suse.com>
 <32310c2a-9800-8b04-b6ac-d8ada044c0f8@kernel.org>
 <20210809080346.GO30984@dragon>
Message-ID: <3c65f75d-724f-a438-1e22-6baeb745a8e5@suse.de>

Hello Shawn and Krzysztof,

On 09.08.21 10:03, Shawn Guo wrote:
> On Thu, Aug 05, 2021 at 09:49:51AM +0200, Krzysztof Kozlowski wrote:
>> On 05/08/2021 08:54, Chester Lin wrote:
>>> Add a new entry for the maintenance of NXP S32G2 DT files.
>>>
>>> Signed-off-by: Chester Lin <clin at suse.com>
>>> ---
>>>  MAINTAINERS | 6 ++++++
>>>  1 file changed, 6 insertions(+)
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 36aee8517ab0..3c6ba6cefd8f 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -2281,6 +2281,12 @@ F:	arch/arm/boot/dts/nuvoton-wpcm450*
>>>  F:	arch/arm/mach-npcm/wpcm450.c
>>>  F:	drivers/*/*wpcm*
>>>  
>>> +ARM/NXP S32G2 ARCHITECTURE

Suggestion from NXP is to use the broader S32G name.

>>> +M:	Chester Lin <clin at suse.com>
>>> +L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>>> +S:	Maintained
>>> +F:	arch/arm64/boot/dts/freescale/s32g2*
>>
>> I support the idea of sub-sub-architecture maintainers but I think idea
>> of in-file addresses was preferred:
>> https://lore.kernel.org/lkml/20200830122922.3884-1-shawnguo at kernel.org/

I had specifically asked Chester to add a MAINTAINERS section.

Is your apparent suggestion of not accepting this MAINTAINERS patch
based on the assumption that we're dealing with only one email address
in three files? What do you see as the threshold to warrant a section?

>From my point of view, above MAINTAINERS entry is incomplete, as we
should CC the full team working on S32G for patch review, not just
Chester himself.
So that would in my mind have been additional R: and L: entries in that
MAINTAINERS section.

> Thanks for reminding that the patch didn't land.  I just resent it with
> your Reviewed-by tag added.  Thanks!

Your above patch does not make clear to me what syntax we should use for
adding email addresses to .dts[i] files now:

https://lore.kernel.org/lkml/20210809081033.GQ30984 at dragon/

Especially when not dealing with file authors.

I get the impression it is not a replacement for an F: wildcard used in
MAINTAINERS, but rather a complement?

Please understand that this is not about a single .dts file, as your
patch suggests, but about a complete SoC family consisting of s32g*.dts*
as well as in the future drivers specific to this platform. It seems way
easier to specify the list of maintainers/reviewers in MAINTAINERS once
with suitable wildcard paths, than copying them into each and every
.dtsi and .dts file and driver .c/.h and later needing to sync multiple
places. If a bot or user has fixes or cleanups for the S32G code, we
want to know about it, so that NXP can consider it for their BSP
branches and SUSE for our SLE branches, and obviously for follow-up
patch series that are already in the works and waiting on this one.

Once merged, I would expect Chester or someone from NXP to set up an
S32G tree on kernel.org that gets integrated into linux-next and sends
pull requests to the SoC tree maintainers without bothering i.MX and
Layerscape maintainers. Did you handle that differently for S32V?

Thanks,
Andreas

P.S. Have you checked or considered whether your script change might
start to CC non-existing email addresses, since we wouldn't be allowed
to remove them from copyright or authorship statements to prevent that?

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From pbonzini at redhat.com  Thu Aug 12 08:41:22 2021
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Thu, 12 Aug 2021 17:41:22 +0200
Subject: [PATCH v2 1/2] KVM: Refactor kvm_arch_vcpu_fault() to return a
 struct page pointer
In-Reply-To: <98adbd3c-ec6f-5689-1686-2a8a7909951a@redhat.com>
References: <YRQcZqCWwVH8bCGc@google.com>
 <1c510b24fc1d7cbae8aa4b69c0799ebd32e65b82.1628739116.git.houwenlong93@linux.alibaba.com>
 <98adbd3c-ec6f-5689-1686-2a8a7909951a@redhat.com>
Message-ID: <d29447d4-a1b4-7f12-7bbc-8dc24cb38b72@redhat.com>

On 12/08/21 11:04, David Hildenbrand wrote:
> 
> Reviewed-by: David Hildenbrand <david at redhat.com>
> 
> But at the same time I wonder if we should just get rid of 
> CONFIG_KVM_S390_UCONTROL and consequently kvm_arch_vcpu_fault().
> 
> In practice CONFIG_KVM_S390_UCONTROL, is never enabled in any reasonable 
> kernel build and consequently it's never tested; further, exposing the 
> sie_block to user space allows user space to generate random SIE 
> validity intercepts.
> 
> CONFIG_KVM_S390_UCONTROL feels like something that should just be 
> maintained out of tree by someone who really needs to hack deep into hw 
> virtualization for testing purposes etc.

I have no preference either way.  It should definitely have selftests, 
but in x86 land there are some features that are not covered by QEMU and 
were nevertheless accepted upstream with selftests.

Paolo



From afaerber at suse.de  Thu Aug 12 08:46:16 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Thu, 12 Aug 2021 17:46:16 +0200
Subject: [PATCH 1/8] dt-bindings: arm: fsl: add NXP S32G2 boards
In-Reply-To: <20210805065429.27485-2-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-2-clin@suse.com>
Message-ID: <bcb3ddd8-23c9-81c9-7d05-b475311068ec@suse.de>

Hello Rob and NXP,

On 05.08.21 08:54, Chester Lin wrote:
> Add bindings for S32G2's evaluation board (S32G-VNP-EVB) and reference
> design 2 board ( S32G-VNP-RDB2).
> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  Documentation/devicetree/bindings/arm/fsl.yaml | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
> index e2097011c4b0..3914aa09e503 100644
> --- a/Documentation/devicetree/bindings/arm/fsl.yaml
> +++ b/Documentation/devicetree/bindings/arm/fsl.yaml
> @@ -983,6 +983,13 @@ properties:
>            - const: solidrun,lx2160a-cex7
>            - const: fsl,lx2160a
>  
> +      - description: S32G2 based Boards
> +        items:
> +          - enum:
> +              - fsl,s32g274a-evb
> +              - fsl,s32g274a-rdb2

@Rob: Should for new boards the description: syntax be used also for
enums? Or just at SoC level, and for board enums still traditional #
comments?

> +          - const: fsl,s32g2

@NXP: Is it sufficient here to have s32g2, or should we call this
s32g274a and adjust the description above to S32G274A?

Related, is the trailing A for Arm, like for the Layerscape chips? I.e.,
not for Alpha or rev.A or something that will change for non-eval chips?

> +
>        - description: S32V234 based Boards
>          items:
>            - enum:

Otherwise,

Reviewed-by: Andreas F?rber <afaerber at suse.de>

Thanks,
Andreas

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From krzk at kernel.org  Thu Aug 12 08:54:23 2021
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 12 Aug 2021 17:54:23 +0200
Subject: [PATCH 8/8] MAINTAINERS: Add an entry for NXP S32G2 boards
In-Reply-To: <3c65f75d-724f-a438-1e22-6baeb745a8e5@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-9-clin@suse.com>
 <32310c2a-9800-8b04-b6ac-d8ada044c0f8@kernel.org>
 <20210809080346.GO30984@dragon>
 <3c65f75d-724f-a438-1e22-6baeb745a8e5@suse.de>
Message-ID: <fab0d8a6-515a-86a8-daa3-12f37bdf004d@kernel.org>

On 12/08/2021 17:30, Andreas F?rber wrote:
> Hello Shawn and Krzysztof,
> 
> On 09.08.21 10:03, Shawn Guo wrote:
>> On Thu, Aug 05, 2021 at 09:49:51AM +0200, Krzysztof Kozlowski wrote:
>>> On 05/08/2021 08:54, Chester Lin wrote:
>>>> Add a new entry for the maintenance of NXP S32G2 DT files.
>>>>
>>>> Signed-off-by: Chester Lin <clin at suse.com>
>>>> ---
>>>>  MAINTAINERS | 6 ++++++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>>> index 36aee8517ab0..3c6ba6cefd8f 100644
>>>> --- a/MAINTAINERS
>>>> +++ b/MAINTAINERS
>>>> @@ -2281,6 +2281,12 @@ F:	arch/arm/boot/dts/nuvoton-wpcm450*
>>>>  F:	arch/arm/mach-npcm/wpcm450.c
>>>>  F:	drivers/*/*wpcm*
>>>>  
>>>> +ARM/NXP S32G2 ARCHITECTURE
> 
> Suggestion from NXP is to use the broader S32G name.
> 
>>>> +M:	Chester Lin <clin at suse.com>
>>>> +L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>>>> +S:	Maintained
>>>> +F:	arch/arm64/boot/dts/freescale/s32g2*
>>>
>>> I support the idea of sub-sub-architecture maintainers but I think idea
>>> of in-file addresses was preferred:
>>> https://lore.kernel.org/lkml/20200830122922.3884-1-shawnguo at kernel.org/
> 
> I had specifically asked Chester to add a MAINTAINERS section.
> 
> Is your apparent suggestion of not accepting this MAINTAINERS patch
> based on the assumption that we're dealing with only one email address
> in three files? What do you see as the threshold to warrant a section?
> 
> From my point of view, above MAINTAINERS entry is incomplete, as we
> should CC the full team working on S32G for patch review, not just
> Chester himself.
> So that would in my mind have been additional R: and L: entries in that
> MAINTAINERS section.

I assumed this is a sub-sub-architecture (something coming from
Layerscape or i.MX) but it seems it's not, therefore I don't mind having
separate entry in MAINTAINERS. The idea of in-file maintainers was for
specific boards and SoCs belonging to existing sub-architectures.

I agree with your following reasons.

> 
>> Thanks for reminding that the patch didn't land.  I just resent it with
>> your Reviewed-by tag added.  Thanks!
> 
> Your above patch does not make clear to me what syntax we should use for
> adding email addresses to .dts[i] files now:
> 
> https://lore.kernel.org/lkml/20210809081033.GQ30984 at dragon/
> 
> Especially when not dealing with file authors.
> 
> I get the impression it is not a replacement for an F: wildcard used in
> MAINTAINERS, but rather a complement?
> 
> Please understand that this is not about a single .dts file, as your
> patch suggests, but about a complete SoC family consisting of s32g*.dts*
> as well as in the future drivers specific to this platform. It seems way
> easier to specify the list of maintainers/reviewers in MAINTAINERS once
> with suitable wildcard paths, than copying them into each and every
> .dtsi and .dts file and driver .c/.h and later needing to sync multiple
> places. If a bot or user has fixes or cleanups for the S32G code, we
> want to know about it, so that NXP can consider it for their BSP
> branches and SUSE for our SLE branches, and obviously for follow-up
> patch series that are already in the works and waiting on this one.
> 
> Once merged, I would expect Chester or someone from NXP to set up an
> S32G tree on kernel.org that gets integrated into linux-next and sends
> pull requests to the SoC tree maintainers without bothering i.MX and
> Layerscape maintainers. Did you handle that differently for S32V?
> 
> Thanks,
> Andreas
> 
> P.S. Have you checked or considered whether your script change might
> start to CC non-existing email addresses, since we wouldn't be allowed
> to remove them from copyright or authorship statements to prevent that?

The same can happen for DT bindings maintainers.

Best regards,
Krzysztof


From afaerber at suse.de  Thu Aug 12 09:04:44 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Thu, 12 Aug 2021 18:04:44 +0200
Subject: [PATCH 2/8] dt-bindings: serial: fsl-linflexuart: convert to
 json-schema format
In-Reply-To: <20210805065429.27485-3-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-3-clin@suse.com>
Message-ID: <1ff13837-e6ca-c476-376d-b4f80450a259@suse.de>

On 05.08.21 08:54, Chester Lin wrote:
> Convert the FSL LINFlexD UART binding to json-schema.
> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  .../bindings/serial/fsl,s32-linflexuart.txt   | 22 ---------
>  .../bindings/serial/fsl,s32-linflexuart.yaml  | 48 +++++++++++++++++++
>  2 files changed, 48 insertions(+), 22 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
>  create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml

Thanks for your effort, Chester.

> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> deleted file mode 100644
> index f1bbe0826be5..000000000000
> --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -* Freescale LINFlexD UART
> -
> -The LINFlexD controller implements several LIN protocol versions, as well as
> -support for full-duplex UART communication through 8-bit and 9-bit frames.
> -
> -See chapter 47 ("LINFlexD") in the reference manual[1].
> -
> -Required properties:
> -- compatible :
> -  - "fsl,s32v234-linflexuart" for LINFlexD configured in UART mode, which
> -    is compatible with the one integrated on S32V234 SoC
> -- reg : Address and length of the register set for the device
> -- interrupts : Should contain uart interrupt
> -
> -Example:
> -uart0: serial at 40053000 {
> -	compatible = "fsl,s32v234-linflexuart";
> -	reg = <0x0 0x40053000 0x0 0x1000>;
> -	interrupts = <0 59 4>;
> -};
> -
> -[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM
> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> new file mode 100644
> index 000000000000..acfe34706ccb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> @@ -0,0 +1,48 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

Since this is dual-licensed and BSD-2-Clause would seem compatible with
GPLv3, this could probably be s/GPL-2.0-only/GPL-2.0-or-later/ ? Not a
blocker.

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/serial/fsl,s32-linflexuart.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale LINFlexD UART
> +
> +description: |
> +  The LINFlexD controller implements several LIN protocol versions, as well
> +  as support for full-duplex UART communication through 8-bit and 9-bit
> +  frames. See chapter 47 ("LINFlexD") in the reference manual
> +  https://www.nxp.com/webapp/Download?colCode=S32V234RM.
> +
> +maintainers:
> +  - Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> +  - Rob Herring <robh at kernel.org>

@Shawn: I assume we need both of them to ack this (or an S32V maintainer
to volunteer), since they were not named in the .txt file before?

> +
> +allOf:
> +  - $ref: "serial.yaml"
> +
> +properties:
> +  compatible:
> +    description: The LINFlexD controller on S32V234 SoC, which can be
> +      configured in UART mode.
> +    items:
> +      - const: fsl,s32v234-linflexuart
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    serial at 40053000 {
> +        compatible = "fsl,s32v234-linflexuart";
> +        reg = <0x40053000 0x1000>;
> +        interrupts = <0 59 4>;
> +    };

Otherwise looking sane,

Reviewed-by: Andreas F?rber <afaerber at suse.de>

Thanks,
Andreas

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From sergei.shtylyov at gmail.com  Thu Aug 12 09:15:01 2021
From: sergei.shtylyov at gmail.com (Sergei Shtylyov)
Date: Thu, 12 Aug 2021 19:15:01 +0300
Subject: [PATCH v2 6/7] usb: gadget: bdc: remove unnecessary AND operation
 when get ep maxp
In-Reply-To: <1628774283-475-6-git-send-email-chunfeng.yun@mediatek.com>
References: <1628774283-475-1-git-send-email-chunfeng.yun@mediatek.com>
 <1628774283-475-6-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <4e751ea2-7e42-3378-397f-7bf913752da2@gmail.com>

On 8/12/21 4:18 PM, Chunfeng Yun wrote:

> usb_endpoint_maxp() already returns actual max packet size, no need

  "No ndeed to", perhaps?

> AND 0x7ff.
> 
> Acked-by: Felipe Balbi <balbi at kernel.org>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
[...]

MBR, Sergei


From afaerber at suse.de  Thu Aug 12 09:27:57 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Thu, 12 Aug 2021 18:27:57 +0200
Subject: [PATCH 3/8] dt-bindings: serial: fsl-linflexuart: Add compatible
 for S32G2
In-Reply-To: <20210805065429.27485-4-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-4-clin@suse.com>
Message-ID: <96c02ee6-cd3a-59df-0b3b-1632bb355019@suse.de>

On 05.08.21 08:54, Chester Lin wrote:
> Add a compatible string for the uart binding of NXP S32G2 platforms. Here
> we use "s32v234-linflexuart" as fallback since the current linflexuart
> driver still works on S32G2.
> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  .../bindings/serial/fsl,s32-linflexuart.yaml  | 26 ++++++++++++++++---
>  1 file changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> index acfe34706ccb..e731f3f6cea4 100644
> --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> @@ -21,10 +21,20 @@ allOf:
>  
>  properties:
>    compatible:
> -    description: The LINFlexD controller on S32V234 SoC, which can be
> -      configured in UART mode.
> -    items:
> -      - const: fsl,s32v234-linflexuart
> +    minItems: 1
> +    maxItems: 2

Are these necessary for oneOf?

> +    oneOf:
> +      - description: The LINFlexD controller on S32G2 SoC, which can be
> +          configured in UART mode.
> +        items:
> +          - enum:
> +              - fsl,s32g2-linflexuart
> +          - const: fsl,s32v234-linflexuart

This reads inconsistent to me: Either this oneOf is for S32G2 only, then
please turn the enum into a const. Or change the description to "on SoCs
compatible with S32V234" if we expect the enum list to grow.

I believe the idea here was to avoid unnecessary driver compatible and
earlycon compatible additions, while preparing for eventual quirks
specific to S32G2.

@NXP: Should this be s32g2- like above or s32g274a- specifically? Do you
agree this is a useful thing to prepare here, as opposed to using only
s32v234- in the s32g2* DT?

I assume the ordering is done alphabetically as S32G < S32V;
alternatively we might order S32V234 first and then the compatible ones.

> +
> +      - description: The LINFlexD controller on S32V234 SoC, which can be
> +          configured in UART mode.
> +        items:
> +          - const: fsl,s32v234-linflexuart

To minimize this S32G2 patch, would it be valid to do oneOf for the
single S32V in the preceding patch already? Then we would avoid the text
movement and re-indentation above and more easily see the lines newly
getting added for S32G2.

>  
>    reg:
>      maxItems: 1
> @@ -41,8 +51,16 @@ unevaluatedProperties: false
>  
>  examples:
>    - |
> +    /* S32V234 */

Could this be:
  - description: S32V234
    |
?

>      serial at 40053000 {
>          compatible = "fsl,s32v234-linflexuart";
>          reg = <0x40053000 0x1000>;
>          interrupts = <0 59 4>;
>      };
> +
> +    /* S32G2 */

This should not be part of the S32V example, but a new one:

  - |

(or with description, as discussed above)

> +    serial at 401c8000 {
> +        compatible = "fsl,s32g2-linflexuart", "fsl,s32v234-linflexuart";

Potentially affected by naming discussions above.

> +        reg = <0x401c8000 0x3000>;
> +        interrupts = <0 82 1>;
> +    };

Regards,
Andreas

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From madvenka at linux.microsoft.com  Thu Aug 12 09:30:41 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Thu, 12 Aug 2021 11:30:41 -0500
Subject: [RFC PATCH v7 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210812152331.GA4239@sirena.org.uk>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812132435.6143-1-madvenka@linux.microsoft.com>
 <20210812132435.6143-2-madvenka@linux.microsoft.com>
 <20210812152331.GA4239@sirena.org.uk>
Message-ID: <3c8b7882-047f-089d-a0e4-e62aedd6e045@linux.microsoft.com>



On 8/12/21 10:23 AM, Mark Brown wrote:
> On Thu, Aug 12, 2021 at 08:24:32AM -0500, madvenka at linux.microsoft.com wrote:
> 
>> Here is the list of functions:
>>
>> 	perf_callchain_kernel()
>> 	get_wchan()
>> 	return_address()
>> 	dump_backtrace()
>> 	profile_pc()
> 
> I've not actually gone through this properly yet but my first thought is
> that for clarity this should be split out into a patch per user plus one
> to delete the old interface  - I'd not worry about it unless it needs to
> get resubmitted though.
> 

OK. I will address it in the next version.

> It'll definitely be good to get this done!

Yes. Thanks!

Madhavan


From paulmck at kernel.org  Thu Aug 12 09:47:30 2021
From: paulmck at kernel.org (Paul E. McKenney)
Date: Thu, 12 Aug 2021 09:47:30 -0700
Subject: [PATCH v3 1/4] rcutorture: Don't disable softirqs with
 preemption disabled when PREEMPT_RT
In-Reply-To: <20210811201354.1976839-2-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
Message-ID: <20210812164730.GX4126399@paulmck-ThinkPad-P17-Gen-1>

On Wed, Aug 11, 2021 at 09:13:51PM +0100, Valentin Schneider wrote:
> Running RCU torture with CONFIG_PREEMPT_RT under v5.14-rc4-rt6 triggers:
> 
> [    8.755472] DEBUG_LOCKS_WARN_ON(this_cpu_read(softirq_ctrl.cnt))
> [    8.755482] WARNING: CPU: 1 PID: 137 at kernel/softirq.c:172 __local_bh_disable_ip (kernel/softirq.c:172 (discriminator 31))
> [    8.755500] Modules linked in:
> [    8.755506] CPU: 1 PID: 137 Comm: rcu_torture_rea Not tainted 5.14.0-rc4-rt6 #171
> [    8.755514] Hardware name: ARM Juno development board (r0) (DT)
> [    8.755518] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
> [    8.755622] Call trace:
> [    8.755624] __local_bh_disable_ip (kernel/softirq.c:172 (discriminator 31))
> [    8.755633] rcutorture_one_extend (kernel/rcu/rcutorture.c:1453)
> [    8.755640] rcu_torture_one_read (kernel/rcu/rcutorture.c:1601 kernel/rcu/rcutorture.c:1645)
> [    8.755645] rcu_torture_reader (kernel/rcu/rcutorture.c:1737)
> [    8.755650] kthread (kernel/kthread.c:327)
> [    8.755656] ret_from_fork (arch/arm64/kernel/entry.S:783)
> [    8.755663] irq event stamp: 11959
> [    8.755666] hardirqs last enabled at (11959): __rcu_read_unlock (kernel/rcu/tree_plugin.h:695 kernel/rcu/tree_plugin.h:451)
> [    8.755675] hardirqs last disabled at (11958): __rcu_read_unlock (kernel/rcu/tree_plugin.h:661 kernel/rcu/tree_plugin.h:451)
> [    8.755683] softirqs last enabled at (11950): __local_bh_enable_ip (./arch/arm64/include/asm/irqflags.h:85 kernel/softirq.c:261)
> [    8.755692] softirqs last disabled at (11942): rcutorture_one_extend (./include/linux/bottom_half.h:19 kernel/rcu/rcutorture.c:1441)
> 
> Per this warning, softirqs cannot be disabled in a non-preemptible region
> under CONFIG_PREEMPT_RT. Adjust RCU torture accordingly.
> 
> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>

Looks sensible for -rt, but of course does not apply on mainline or -rcu.

Acked-by: Paul E. McKenney <paulmck at kernel.org>

> ---
>  kernel/rcu/rcutorture.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index eecd1caef71d..4f3db1d3170d 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -1548,6 +1548,8 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
>  	 * them on non-RT.
>  	 */
>  	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> +		/* Can't disable bh in atomic context under PREEMPT_RT */
> +		mask &= ~(RCUTORTURE_RDR_ATOM_BH | RCUTORTURE_RDR_ATOM_RBH);
>  		/*
>  		 * Can't release the outermost rcu lock in an irq disabled
>  		 * section without preemption also being disabled, if irqs
> -- 
> 2.25.1
> 


From andriy.shevchenko at linux.intel.com  Thu Aug 12 10:00:22 2021
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 12 Aug 2021 20:00:22 +0300
Subject: [PATCH v4 1/4] clk: fractional-divider: Export approximation
 algorithm to the CCF users
Message-ID: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>

At least one user currently duplicates some functions that are provided
by fractional divider module. Let's export approximation algorithm and
replace the open-coded variant.

As a bonus the exported function will get better documentation in place.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Tested-by: Heiko Stuebner <heiko at sntech.de>
Acked-by: Heiko Stuebner <heiko at sntech.de>
---
v4: rebased on top of latest CLK codebase
 drivers/clk/clk-fractional-divider.c | 11 +++++++----
 drivers/clk/clk-fractional-divider.h |  9 +++++++++
 drivers/clk/rockchip/clk.c           | 17 +++--------------
 3 files changed, 19 insertions(+), 18 deletions(-)
 create mode 100644 drivers/clk/clk-fractional-divider.h

diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index b1e556f20911..535d299af646 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -14,6 +14,8 @@
 #include <linux/slab.h>
 #include <linux/rational.h>
 
+#include "clk-fractional-divider.h"
+
 static inline u32 clk_fd_readl(struct clk_fractional_divider *fd)
 {
 	if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
@@ -68,9 +70,10 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
 	return ret;
 }
 
-static void clk_fd_general_approximation(struct clk_hw *hw, unsigned long rate,
-					 unsigned long *parent_rate,
-					 unsigned long *m, unsigned long *n)
+void clk_fractional_divider_general_approximation(struct clk_hw *hw,
+						  unsigned long rate,
+						  unsigned long *parent_rate,
+						  unsigned long *m, unsigned long *n)
 {
 	struct clk_fractional_divider *fd = to_clk_fd(hw);
 	unsigned long scale;
@@ -102,7 +105,7 @@ static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
 	if (fd->approximation)
 		fd->approximation(hw, rate, parent_rate, &m, &n);
 	else
-		clk_fd_general_approximation(hw, rate, parent_rate, &m, &n);
+		clk_fractional_divider_general_approximation(hw, rate, parent_rate, &m, &n);
 
 	ret = (u64)*parent_rate * m;
 	do_div(ret, n);
diff --git a/drivers/clk/clk-fractional-divider.h b/drivers/clk/clk-fractional-divider.h
new file mode 100644
index 000000000000..4fa359a12ef4
--- /dev/null
+++ b/drivers/clk/clk-fractional-divider.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+struct clk_hw;
+
+void clk_fractional_divider_general_approximation(struct clk_hw *hw,
+						  unsigned long rate,
+						  unsigned long *parent_rate,
+						  unsigned long *m,
+						  unsigned long *n);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 049e5e0b64f6..b7be7e11b0df 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -22,6 +22,8 @@
 #include <linux/regmap.h>
 #include <linux/reboot.h>
 #include <linux/rational.h>
+
+#include "../clk-fractional-divider.h"
 #include "clk.h"
 
 /*
@@ -178,10 +180,8 @@ static void rockchip_fractional_approximation(struct clk_hw *hw,
 		unsigned long rate, unsigned long *parent_rate,
 		unsigned long *m, unsigned long *n)
 {
-	struct clk_fractional_divider *fd = to_clk_fd(hw);
 	unsigned long p_rate, p_parent_rate;
 	struct clk_hw *p_parent;
-	unsigned long scale;
 
 	p_rate = clk_hw_get_rate(clk_hw_get_parent(hw));
 	if ((rate * 20 > p_rate) && (p_rate % rate != 0)) {
@@ -190,18 +190,7 @@ static void rockchip_fractional_approximation(struct clk_hw *hw,
 		*parent_rate = p_parent_rate;
 	}
 
-	/*
-	 * Get rate closer to *parent_rate to guarantee there is no overflow
-	 * for m and n. In the result it will be the nearest rate left shifted
-	 * by (scale - fd->nwidth) bits.
-	 */
-	scale = fls_long(*parent_rate / rate - 1);
-	if (scale > fd->nwidth)
-		rate <<= scale - fd->nwidth;
-
-	rational_best_approximation(rate, *parent_rate,
-			GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
-			m, n);
+	clk_fractional_divider_general_approximation(hw, rate, parent_rate, m, n);
 }
 
 static struct clk *rockchip_clk_register_frac_branch(
-- 
2.30.2



From andriy.shevchenko at linux.intel.com  Thu Aug 12 10:00:24 2021
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 12 Aug 2021 20:00:24 +0300
Subject: [PATCH v4 3/4] clk: fractional-divider: Introduce POWER_OF_TWO_PS flag
In-Reply-To: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20210812170025.67074-3-andriy.shevchenko@linux.intel.com>

The newly introduced POWER_OF_TWO_PS flag, when set, makes the flow
to skip the assumption that the caller will use an additional 2^scale
prescaler to get the desired clock rate.

Reported-by: Liu Ying <victor.liu at nxp.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
v4: rebased on top of latest CLK codebase

 drivers/acpi/acpi_lpss.c             |  4 ++--
 drivers/clk/clk-fractional-divider.c | 10 ++++++----
 drivers/mfd/intel-lpss.c             |  3 ++-
 include/linux/clk-provider.h         | 11 +++++++++--
 4 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 7f163074e4e4..30b1f511c2af 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -436,8 +436,8 @@ static int register_device_clock(struct acpi_device *adev,
 		if (!clk_name)
 			return -ENOMEM;
 		clk = clk_register_fractional_divider(NULL, clk_name, parent,
-						      0, prv_base,
-						      1, 15, 16, 15, 0, NULL);
+						      CLK_FRAC_DIVIDER_POWER_OF_TWO_PS,
+						      prv_base, 1, 15, 16, 15, 0, NULL);
 		parent = clk_name;
 
 		clk_name = kasprintf(GFP_KERNEL, "%s-update", devname);
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 535d299af646..6a3ed82fdae9 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -76,16 +76,18 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
 						  unsigned long *m, unsigned long *n)
 {
 	struct clk_fractional_divider *fd = to_clk_fd(hw);
-	unsigned long scale;
 
 	/*
 	 * Get rate closer to *parent_rate to guarantee there is no overflow
 	 * for m and n. In the result it will be the nearest rate left shifted
 	 * by (scale - fd->nwidth) bits.
 	 */
-	scale = fls_long(*parent_rate / rate - 1);
-	if (scale > fd->nwidth)
-		rate <<= scale - fd->nwidth;
+	if (fd->flags & CLK_FRAC_DIVIDER_POWER_OF_TWO_PS) {
+		unsigned long scale = fls_long(*parent_rate / rate - 1);
+
+		if (scale > fd->nwidth)
+			rate <<= scale - fd->nwidth;
+	}
 
 	rational_best_approximation(rate, *parent_rate,
 			GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
index a9bf10bee796..0e15afc39f54 100644
--- a/drivers/mfd/intel-lpss.c
+++ b/drivers/mfd/intel-lpss.c
@@ -301,7 +301,8 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss,
 
 	snprintf(name, sizeof(name), "%s-div", devname);
 	tmp = clk_register_fractional_divider(NULL, name, __clk_get_name(tmp),
-					      0, lpss->priv, 1, 15, 16, 15, 0,
+					      CLK_FRAC_DIVIDER_POWER_OF_TWO_PS,
+					      lpss->priv, 1, 15, 16, 15, 0,
 					      NULL);
 	if (IS_ERR(tmp))
 		return PTR_ERR(tmp);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index d8609aef2394..f59c875271a0 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -1001,6 +1001,12 @@ struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
  * CLK_FRAC_DIVIDER_BIG_ENDIAN - By default little endian register accesses are
  *	used for the divider register.  Setting this flag makes the register
  *	accesses big endian.
+ * CLK_FRAC_DIVIDER_POWER_OF_TWO_PS - By default the resulting fraction might
+ *	be saturated and the caller will get quite far from the good enough
+ *	approximation. Instead the caller may require, by setting this flag,
+ *	to shift left by a few bits in case, when the asked one is quite small
+ *	to satisfy the desired range of denominator. It assumes that on the
+ *	caller's side the power-of-two capable prescaler exists.
  */
 struct clk_fractional_divider {
 	struct clk_hw	hw;
@@ -1020,8 +1026,9 @@ struct clk_fractional_divider {
 
 #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
 
-#define CLK_FRAC_DIVIDER_ZERO_BASED	BIT(0)
-#define CLK_FRAC_DIVIDER_BIG_ENDIAN	BIT(1)
+#define CLK_FRAC_DIVIDER_ZERO_BASED		BIT(0)
+#define CLK_FRAC_DIVIDER_BIG_ENDIAN		BIT(1)
+#define CLK_FRAC_DIVIDER_POWER_OF_TWO_PS	BIT(2)
 
 struct clk *clk_register_fractional_divider(struct device *dev,
 		const char *name, const char *parent_name, unsigned long flags,
-- 
2.30.2



From andriy.shevchenko at linux.intel.com  Thu Aug 12 10:00:25 2021
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 12 Aug 2021 20:00:25 +0300
Subject: [PATCH v4 4/4] clk: fractional-divider: Document the arithmetics used
 behind the code
In-Reply-To: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20210812170025.67074-4-andriy.shevchenko@linux.intel.com>

It appears that some code lines raise the question why they are needed
and how they are participated in the calculus of the resulting values.

Document this in a form of the top comment in the module file.

Reported-by: Liu Ying <victor.liu at nxp.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
v4: rebased on top of latest CLK codebase

 drivers/clk/clk-fractional-divider.c | 35 +++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 6a3ed82fdae9..b4f365d97bd0 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -3,8 +3,39 @@
  * Copyright (C) 2014 Intel Corporation
  *
  * Adjustable fractional divider clock implementation.
- * Output rate = (m / n) * parent_rate.
  * Uses rational best approximation algorithm.
+ *
+ * Output is calculated as
+ *
+ *	rate = (m / n) * parent_rate				(1)
+ *
+ * This is useful when on die we have a prescaler block which asks for
+ * m (numerator) and n (denominator) values to be provided to satisfy
+ * the (1) as much as possible.
+ *
+ * Since m and n have the limitation by a range, e.g.
+ *
+ *	n >= 1, n < N_width, where N_width = 2^nwidth		(2)
+ *
+ * for some cases the output may be saturated. Hence, from (1) and (2),
+ * assuming the worst case when m = 1, the inequality
+ *
+ *	floor(log2(parent_rate / rate)) <= nwidth		(3)
+ *
+ * may be derived. Thus, in cases when
+ *
+ *	(parent_rate / rate) >> N_width				(4)
+ *
+ * we might scale up the rate by 2^scale (see the description of
+ * CLK_FRAC_DIVIDER_POWER_OF_TWO_PS for additional information), where
+ *
+ *	scale = floor(log2(parent_rate / rate)) - nwidth	(5)
+ *
+ * and assume that the IP, that needs m and n, has also its own
+ * prescaler, which is capable to divide by 2^scale. In this way
+ * we get the denominator to satisfy the desired range (2) and
+ * at the same time much much better result of m and n than simple
+ * saturated values.
  */
 
 #include <linux/clk-provider.h>
@@ -81,6 +112,8 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
 	 * Get rate closer to *parent_rate to guarantee there is no overflow
 	 * for m and n. In the result it will be the nearest rate left shifted
 	 * by (scale - fd->nwidth) bits.
+	 *
+	 * For the detailed explanation see the top comment in this file.
 	 */
 	if (fd->flags & CLK_FRAC_DIVIDER_POWER_OF_TWO_PS) {
 		unsigned long scale = fls_long(*parent_rate / rate - 1);
-- 
2.30.2



From andriy.shevchenko at linux.intel.com  Thu Aug 12 10:00:23 2021
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 12 Aug 2021 20:00:23 +0300
Subject: [PATCH v4 2/4] clk: fractional-divider: Hide
 clk_fractional_divider_ops from wide audience
In-Reply-To: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
Message-ID: <20210812170025.67074-2-andriy.shevchenko@linux.intel.com>

The providers are all located in drivers/clk/ and hence no need
to export the clock operations to wider audience. Hide them by
moving to drivers/clk/clk-fractional-divider.h.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
v4: rebased on top of latest CLK codebase, fixed compilation error

 drivers/clk/clk-fractional-divider.h | 2 ++
 drivers/clk/imx/clk-composite-7ulp.c | 1 +
 include/linux/clk-provider.h         | 1 -
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-fractional-divider.h b/drivers/clk/clk-fractional-divider.h
index 4fa359a12ef4..aaaef90b2777 100644
--- a/drivers/clk/clk-fractional-divider.h
+++ b/drivers/clk/clk-fractional-divider.h
@@ -2,6 +2,8 @@
 
 struct clk_hw;
 
+extern const struct clk_ops clk_fractional_divider_ops;
+
 void clk_fractional_divider_general_approximation(struct clk_hw *hw,
 						  unsigned long rate,
 						  unsigned long *parent_rate,
diff --git a/drivers/clk/imx/clk-composite-7ulp.c b/drivers/clk/imx/clk-composite-7ulp.c
index 7c4f31b31eb0..d85ba78abbb1 100644
--- a/drivers/clk/imx/clk-composite-7ulp.c
+++ b/drivers/clk/imx/clk-composite-7ulp.c
@@ -10,6 +10,7 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 
+#include "../clk-fractional-divider.h"
 #include "clk.h"
 
 #define PCG_PCS_SHIFT	24
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 7be81d5fcf8c..d8609aef2394 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -1023,7 +1023,6 @@ struct clk_fractional_divider {
 #define CLK_FRAC_DIVIDER_ZERO_BASED	BIT(0)
 #define CLK_FRAC_DIVIDER_BIG_ENDIAN	BIT(1)
 
-extern const struct clk_ops clk_fractional_divider_ops;
 struct clk *clk_register_fractional_divider(struct device *dev,
 		const char *name, const char *parent_name, unsigned long flags,
 		void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth,
-- 
2.30.2



From mka at chromium.org  Thu Aug 12 10:08:31 2021
From: mka at chromium.org (Matthias Kaehlcke)
Date: Thu, 12 Aug 2021 10:08:31 -0700
Subject: [PATCH v15 0/6] usb: misc: Add onboard_usb_hub driver
In-Reply-To: <ddd60682-c957-2897-768e-96c9d25c148a@kernel.org>
References: <20210727004118.2583774-1-mka@chromium.org>
 <YRFOnhJkB2vi/zwD@google.com>
 <8a8cae28-6617-76d3-1742-3f151a149069@kernel.org>
 <ddd60682-c957-2897-768e-96c9d25c148a@kernel.org>
Message-ID: <YRVVjwNprk7l1jUk@google.com>

Hi Roger,

On Wed, Aug 11, 2021 at 03:56:15PM +0300, Roger Quadros wrote:
> 
> 
> On 11/08/2021 15:38, Roger Quadros wrote:
> > Hi Matthias,
> > 
> > On 09/08/2021 18:49, Matthias Kaehlcke wrote:
> >> Hi Greg,
> >>
> >> Just wanted to check if this series is still on your radar. Is
> >> there anything that blocks it from landing (further ACKs, ...)?
> >>
> >> Thanks
> >>
> >> Matthias
> >>
> >> On Mon, Jul 26, 2021 at 05:41:12PM -0700, Matthias Kaehlcke wrote:
> >>> This series adds:
> >>> - the onboard_usb_hub_driver
> >>> - glue in the xhci-plat driver to create and destroy the
> >>>   onboard_usb_hub platform devices if needed
> >>> - a device tree binding for the Realtek RTS5411 USB hub controller
> >>> - device tree changes that add RTS5411 entries for the QCA SC7180
> >>>   based boards trogdor and lazor
> >>> - a couple of stubs for platform device functions to avoid
> >>>   unresolved symbols with certain kernel configs
> >>>
> >>> The main issue the driver addresses is that a USB hub needs to be
> >>> powered before it can be discovered. For discrete onboard hubs (an
> >>> example for such a hub is the Realtek RTS5411) this is often solved
> >>> by supplying the hub with an 'always-on' regulator, which is kind
> >>> of a hack. Some onboard hubs may require further initialization
> >>> steps, like changing the state of a GPIO or enabling a clock, which
> >>> requires even more hacks. This driver creates a platform device
> >>> representing the hub which performs the necessary initialization.
> >>> Currently it only supports switching on a single regulator, support
> >>> for multiple regulators or other actions can be added as needed.
> >>> Different initialization sequences can be supported based on the
> >>> compatible string.
> >>>
> >>> Besides performing the initialization the driver can be configured
> >>> to power the hub off during system suspend. This can help to extend
> >>> battery life on battery powered devices which have no requirements
> >>> to keep the hub powered during suspend. The driver can also be
> >>> configured to leave the hub powered when a wakeup capable USB device
> >>> is connected when suspending, and power it off otherwise.
> >>>
> >>> Changes in v15:
> >>> - adjusted dependencies of USB_DWC3_CORE to make sure it can only
> >>>   be enabled when at least one of USB_DWC3_HOST, USB_DWC3_GADGET
> >>>   or USB_DWC3_DUAL_ROLE is selectable
> >>>
> >>> Changes in v14:
> >>> - rebased on top of v5.14-rc1
> >>> - dropped DT binding patch which landed in v5.13
> >>>
> >>> Changes in v13:
> >>> - added patch "usb: Specify dependency on USB_XHCI_PLATFORM with
> >>>   'depends on'" to the series to avoid Kconfig conflicts
> >>> - added patch "arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM"
> >>>   to the series to keep effective defconfig unchanged
> >>>
> >>> Changes in v12:
> >>> - onboard_hub driver: use IS_ENABLED(CONFIG_USB_ONBOARD_HUB_MODULE)
> >>>   in onboard_hub.h to also check for the driver built as module
> >>> - onboard_hub_driver: include onboard_hub.h again to make sure there
> >>>   are prototype declarations for the public functions
> >>>
> >>> Changes in v11:
> >>> - support multiple onboard hubs connected to the same parent
> >>> - don't include ?onboard_hub.h? from the onboard hub driver
> >>>
> >>> Changes in v10:
> >>> - always use of_is_onboard_usb_hub() stub unless ONBOARD_USB_HUB=y/m
> >>> - keep 'regulator-boot-on' property for pp3300_hub
> >>>
> >>> Changes in v9:
> >>> - added dependency on ONBOARD_USB_HUB (or !!ONBOARD_USB_HUB) to
> >>>   USB_PLATFORM_XHCI
> >>>
> >>> Changes in v7:
> >>> - updated DT binding
> >>> - series rebased on qcom/arm64-for-5.13
> >>>
> >>> Changes in v6:
> >>> - updated summary
> >>>
> >>> Changes in v5:
> >>> - cover letter added
> >>>
> >>> Matthias Kaehlcke (6):
> >>>   usb: misc: Add onboard_usb_hub driver
> >>>   of/platform: Add stubs for of_platform_device_create/destroy()
> >>>   arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM
> >>>   usb: Specify dependencies on USB_XHCI_PLATFORM with 'depends on'
> >>>   usb: host: xhci-plat: Create platform device for onboard hubs in
> >>>     probe()
> >>>   arm64: dts: qcom: sc7180-trogdor: Add nodes for onboard USB hub
> >>>
> >>>  .../sysfs-bus-platform-onboard-usb-hub        |   8 +
> >>>  MAINTAINERS                                   |   7 +
> >>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r0.dts |  19 +-
> >>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r1.dts |  12 +-
> >>>  .../arm64/boot/dts/qcom/sc7180-trogdor-r1.dts |  19 +-
> >>>  arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |  19 +-
> >>>  arch/arm64/configs/defconfig                  |   1 +
> >>>  drivers/usb/cdns3/Kconfig                     |   2 +-
> >>>  drivers/usb/dwc3/Kconfig                      |   5 +-
> >>>  drivers/usb/host/Kconfig                      |   5 +-
> > 
> > These Kconfig changes are causing the resulting .config to be different.
> > For example, if I start with omap2plus_defconfig, the resulting .config
> > before and after your series is different as shown below
> > 
> > :/work/linux$ diff /tmp/.config .config
> > 1902d1901
> > < # CONFIG_HISI_HIKEY_USB is not set
> > 4992c4991
> > < CONFIG_USB_XHCI_PLATFORM=m
> > ---
> >> # CONFIG_USB_XHCI_PLATFORM is not set
> > 5073,5075c5072
> > < # CONFIG_USB_DWC3_HOST is not set
> > < # CONFIG_USB_DWC3_GADGET is not set
> > < CONFIG_USB_DWC3_DUAL_ROLE=y
> > ---
> >> CONFIG_USB_DWC3_GADGET=y
> > 5173a5171
> >> # CONFIG_USB_ONBOARD_HUB is not set
> > 5285c5283
> > < CONFIG_USB_ROLE_SWITCH=m
> > ---
> >> # CONFIG_USB_ROLE_SWITCH is not set
> > 
> > I would expect the same issues for multi_v7_defconfig and multi_v8_defconfig as well.
> 
> Sorry I meant defconfig for arm64, not multi_v8_defconfig.
> 
> I checked that for arm64 defconfig it is ok.
> 
> > I'm ok to update the relevant defconfigs files so that the resulting .config is identical to
> > before your series. Thanks!
> 
> With the below patch you can fix it for omap2plus_defconfig and multi_v7_defconfig.
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index d9abaae118dd..8c175ab37377 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -787,6 +787,7 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
>  CONFIG_USB=y
>  CONFIG_USB_OTG=y
>  CONFIG_USB_XHCI_HCD=y
> +CONFIG_USB_XHCI_PLATFORM=y
>  CONFIG_USB_XHCI_MVEBU=y
>  CONFIG_USB_XHCI_TEGRA=m
>  CONFIG_USB_EHCI_HCD=y
> diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
> index 2ac2418084ab..a015fb04fa25 100644
> --- a/arch/arm/configs/omap2plus_defconfig
> +++ b/arch/arm/configs/omap2plus_defconfig
> @@ -562,6 +562,7 @@ CONFIG_USB=m
>  CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
>  CONFIG_USB_MON=m
>  CONFIG_USB_XHCI_HCD=m
> +CONFIG_USB_XHCI_PLATFORM=m
>  CONFIG_USB_EHCI_HCD=m
>  CONFIG_USB_OHCI_HCD=m
>  CONFIG_USB_ACM=m

Thanks for testing!

I completely forgot that arm32 has all these different defconfigs.

While trying to adjust qcom_defconfig I came across something that confuses
me. The original defconfig results in:

# CONFIG_USB_XHCI_HCD is not set
CONFIG_USB_DWC3_DUAL_ROLE=y

My assumption was that xHCI support is need for dwc3 dual mode (which is
made explicit by https://lore.kernel.org/patchwork/patch/1468240/), is
that incorrect? Maybe without xHCI support the controller can still
operate in USB 2.0 dual role mode?


From afaerber at suse.de  Thu Aug 12 10:26:28 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Thu, 12 Aug 2021 19:26:28 +0200
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <20210805065429.27485-5-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-5-clin@suse.com>
Message-ID: <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>

Hi Chester et al.,

On 05.08.21 08:54, Chester Lin wrote:
> Add an initial dtsi file for generic SoC features of NXP S32G2.
> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  arch/arm64/boot/dts/freescale/s32g2.dtsi | 98 ++++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
> 
> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> new file mode 100644
> index 000000000000..3321819c1a2d
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi

Note: This DT is for running on the Cortex-A53 cores, but S32G2 also has
Cortex-M7 cores. For Vybrid SoCs, DTs later got contributed to also run
on its Cortex-M4 core:

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf610.dtsi
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf500.dtsi
vs.
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf610m4.dtsi

Should we plan for this in our file naming here and in following patches
(e.g., s32g2-a53* vs. s32g2-m7*)? To me, a later concatenation of
s32g274am7* would look awkward, and s32g274a-m7* would sort between -evb
and -rdb2.

> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> +/*

 * NXP S32G2 SoC family
 *
?

@NXP: Are any models other than 274A in the queue that we should
distinguish between s32g2.dtsi and s32g274a.dtsi here already?

> + * Copyright (c) 2021 SUSE LLC
> + */
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {
> +	compatible = "fsl,s32g2";
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu at 0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x0>;
> +			enable-method = "psci";
> +			next-level-cache = <&cluster0_l2>;
> +		};
> +
> +		cpu1: cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x1>;
> +			enable-method = "psci";
> +			next-level-cache = <&cluster0_l2>;
> +		};
> +
> +		cpu2: cpu at 100 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x100>;
> +			enable-method = "psci";
> +			next-level-cache = <&cluster1_l2>;
> +		};
> +
> +		cpu3: cpu at 101 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a53";
> +			reg = <0x101>;
> +			enable-method = "psci";
> +			next-level-cache = <&cluster1_l2>;
> +		};
> +
> +		cluster0_l2: l2-cache0 {
> +			compatible = "cache";
> +		};
> +
> +		cluster1_l2: l2-cache1 {
> +			compatible = "cache";
> +		};
> +	};
> +
> +	pmu {
> +		compatible = "arm,cortex-a53-pmu";
> +		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;

interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;

> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-1.0";
> +		method = "smc";
> +	};

Should we move this into a /firmware node, to group with future OP-TEE?

> +
> +	soc {
> +		compatible = "simple-bus";
> +		interrupt-parent = <&gic>;

Duplicate, already set on root node.

> +		#address-cells = <2>;
> +		#size-cells = <2>;

Why? Does it have any peripherals that go beyond 32-bit space?
For 64-bit Realtek platforms Rob had asked me to use 1, if possible.
I do understand that for /memory nodes we do have high-memory addresses,
so 2 for the root node looks correct.

> +

Please drop this white line.

> +		ranges;

According to Rob, the /soc ranges should exclude any RAM ranges for
safety reasons. Compare:

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/realtek/rtd129x.dtsi

If you're lacking the maximum RAM areas to carve out, NXP is in CC to
help out :) and the EVB and RDB2 boards should give you starting numbers
that could be enlarged later if needed.

> +
> +		gic: interrupt-controller at 50800000 {
> +			compatible = "arm,gic-v3";
> +			#interrupt-cells = <3>;
> +			interrupt-controller;
> +			reg = <0 0x50800000 0 0x10000>,
> +			      <0 0x50880000 0 0x200000>,
> +			      <0 0x50400000 0 0x2000>,
> +			      <0 0x50410000 0 0x2000>,
> +			      <0 0x50420000 0 0x2000>;

Please order reg after compatible by convention, and sort
interrupt-controller or at least #interrupt-cells (applying to
consumers) last, after the below one applying to this device itself.

> +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
> +						 IRQ_TYPE_LEVEL_HIGH)>;
> +		};

CC'ing Marc for additional GIC scrutiny, often the sizes are wrong.

> +	};
> +};

Thanks,
Andreas

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From bbudiredla at marvell.com  Thu Aug 12 10:42:07 2021
From: bbudiredla at marvell.com (Bhaskara Budiredla)
Date: Thu, 12 Aug 2021 23:12:07 +0530
Subject: [PATCH v3 0/2] drivers: perf: Add Marvell CN10K LLC-TAD pmu driver
Message-ID: <20210812174209.1970-1-bbudiredla@marvell.com>

This series introduces performance monitor driver to Last-level-cache
tag-and-data (LLC-TAD) PMU which is an intergral part of Marvell CN10K SoCs.
The configuration and functionality of the TAD PMU is covered in patch 1.
The device tree bindings are dealt in patch 2.

v3:
 - rebased on kernel v5.14-rc5
 - disable sampling events via PERF_PMU_CAP_NO_INTERRUPT (Will Deacon)
 - convert tad pmu bindings to schema (Will Deacon)
 - replace tighter semantics with *_relaxed() accesses (Will Deacon)
 - use PMU_EVENT_ATTR_ID generic macro (Will Deacon)
 - allow cleanup of allocations through devm_kcalloc() (Will Deacon)

v2:
 - rebased on kernel v5.13-rc3

Bhaskara Budiredla (2):
  drivers: perf: Add LLC-TAD perf counter support
  dt-bindings: perf: Add YAML schemas for Marvell CN10K LLC-TAD PMU
    bindings

 .../bindings/perf/marvell-cn10k-tad.yaml      |  45 ++
 drivers/perf/Kconfig                          |   7 +
 drivers/perf/Makefile                         |   1 +
 drivers/perf/marvell_cn10k_tad_pmu.c          | 429 ++++++++++++++++++
 4 files changed, 482 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml
 create mode 100644 drivers/perf/marvell_cn10k_tad_pmu.c

-- 
2.17.1



From bbudiredla at marvell.com  Thu Aug 12 10:42:08 2021
From: bbudiredla at marvell.com (Bhaskara Budiredla)
Date: Thu, 12 Aug 2021 23:12:08 +0530
Subject: [PATCH 1/2] drivers: perf: Add LLC-TAD perf counter support
In-Reply-To: <20210812174209.1970-1-bbudiredla@marvell.com>
References: <20210812174209.1970-1-bbudiredla@marvell.com>
Message-ID: <20210812174209.1970-2-bbudiredla@marvell.com>

This driver adds support for Last-level cache tag-and-data unit
(LLC-TAD) PMU that is featured in some of the Marvell's CN10K
infrastructure silicons.

The LLC is divided into 2N slices distributed across N Mesh tiles
in a single-socket configuration. The driver always configures the
same counter for all of the TADs. The user would end up effectively
reserving one of eight counters in every TAD to look across all TADs.
The occurrences of events are aggregated and presented to the user
at the end of an application run. The driver does not provide a way
for the user to partition TADs so that different TADs are used for
different applications.

The event counters are zeroed on start event counting to avoid any
rollover issues. TAD perf counters are 64-bit, so it's not currently
possible to overflow event counters at current mesh and core
frequencies.

To measure tad pmu events use perf tool stat command. For instance:

perf stat -e tad_dat_msh_in_dss,tad_req_msh_out_any <application>
perf stat -e tad_alloc_any,tad_hit_any,tad_tag_rd <application>

Signed-off-by: Bhaskara Budiredla <bbudiredla at marvell.com>
---
 drivers/perf/Kconfig                 |   7 +
 drivers/perf/Makefile                |   1 +
 drivers/perf/marvell_cn10k_tad_pmu.c | 429 +++++++++++++++++++++++++++
 3 files changed, 437 insertions(+)
 create mode 100644 drivers/perf/marvell_cn10k_tad_pmu.c

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 77522e5efe11..73dca11f8080 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -137,6 +137,13 @@ config ARM_DMC620_PMU
 	  Support for PMU events monitoring on the ARM DMC-620 memory
 	  controller.
 
+config MARVELL_CN10K_TAD_PMU
+	tristate "Marvell CN10K LLC-TAD PMU"
+	depends on ARM64
+	help
+	  Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
+	  performance monitors on CN10K family silicons.
+
 source "drivers/perf/hisilicon/Kconfig"
 
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 5260b116c7da..2db5418d5b0a 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
+obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
new file mode 100644
index 000000000000..fec8b90d52d2
--- /dev/null
+++ b/drivers/perf/marvell_cn10k_tad_pmu.c
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell CN10K LLC-TAD perf driver
+ *
+ * Copyright (C) 2021 Marvell.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) "tad_pmu: " fmt
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/cpuhotplug.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+#include <linux/arm-smccc.h>
+
+#define TAD_PFC_OFFSET		0x0800
+#define TAD_PFC(counter)	(TAD_PFC_OFFSET | (counter << 3))
+#define TAD_PRF_OFFSET		0x0900
+#define TAD_PRF(counter)	(TAD_PRF_OFFSET | (counter << 3))
+#define TAD_PRF_CNTSEL_MASK	0xFF
+#define TAD_MAX_COUNTERS	8
+
+#define to_tad_pmu(p) (container_of(p, struct tad_pmu, pmu))
+
+struct tad_region {
+	void __iomem	*base;
+};
+
+struct tad_pmu {
+	struct pmu pmu;
+	struct tad_region *regions;
+	u32 region_cnt;
+	unsigned int cpu;
+	struct hlist_node node;
+	struct perf_event *events[TAD_MAX_COUNTERS];
+	DECLARE_BITMAP(counters_map, TAD_MAX_COUNTERS);
+};
+
+static int tad_pmu_cpuhp_state;
+
+static void tad_pmu_event_counter_read(struct perf_event *event)
+{
+	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u32 counter_idx = hwc->idx;
+	u64 delta, prev, new;
+	int i;
+
+	do {
+		prev = local64_read(&hwc->prev_count);
+		for (i = 0, new = 0; i < tad_pmu->region_cnt; i++)
+			new += readq(tad_pmu->regions[i].base +
+				     TAD_PFC(counter_idx));
+	} while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev);
+
+	delta = (new - prev) & GENMASK_ULL(63, 0);
+	local64_add(delta, &event->count);
+}
+
+static void tad_pmu_event_counter_stop(struct perf_event *event, int flags)
+{
+	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u32 counter_idx = hwc->idx;
+	int i;
+
+	/* TAD()_PFC() stop counting on the write
+	 * which sets TAD()_PRF()[CNTSEL] == 0
+	 */
+	for (i = 0; i < tad_pmu->region_cnt; i++)
+		writeq_relaxed(0, tad_pmu->regions[i].base +
+			       TAD_PRF(counter_idx));
+
+	tad_pmu_event_counter_read(event);
+	hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+}
+
+static void tad_pmu_event_counter_start(struct perf_event *event, int flags)
+{
+	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u32 event_idx = event->attr.config;
+	u32 counter_idx = hwc->idx;
+	u64 reg_val;
+	int i;
+
+	hwc->state = 0;
+
+	/* Typically TAD_PFC() are zeroed to start counting */
+	for (i = 0; i < tad_pmu->region_cnt; i++)
+		writeq_relaxed(0, tad_pmu->regions[i].base +
+			       TAD_PFC(counter_idx));
+
+	/* TAD()_PFC() start counting on the write
+	 * which sets TAD()_PRF()[CNTSEL] != 0
+	 */
+	for (i = 0; i < tad_pmu->region_cnt; i++) {
+		reg_val = readq_relaxed(tad_pmu->regions[i].base +
+					TAD_PRF(counter_idx));
+		reg_val |= (event_idx & 0xFF);
+		writeq_relaxed(reg_val,	tad_pmu->regions[i].base +
+			       TAD_PRF(counter_idx));
+	}
+}
+
+static void tad_pmu_event_counter_del(struct perf_event *event, int flags)
+{
+	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	tad_pmu_event_counter_stop(event, flags | PERF_EF_UPDATE);
+	tad_pmu->events[idx] = NULL;
+	clear_bit(idx, tad_pmu->counters_map);
+}
+
+static int tad_pmu_event_counter_add(struct perf_event *event, int flags)
+{
+	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+
+	/* Get a free counter for this event */
+	idx = find_first_zero_bit(tad_pmu->counters_map, TAD_MAX_COUNTERS);
+	if (idx == TAD_MAX_COUNTERS)
+		return -EAGAIN;
+
+	set_bit(idx, tad_pmu->counters_map);
+
+	hwc->idx = idx;
+	hwc->state = PERF_HES_STOPPED;
+	tad_pmu->events[idx] = event;
+
+	if (flags & PERF_EF_START)
+		tad_pmu_event_counter_start(event, flags);
+
+	return 0;
+}
+
+static int tad_pmu_event_init(struct perf_event *event)
+{
+	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
+
+	if (!event->attr.disabled)
+		return -EINVAL;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	if (event->state != PERF_EVENT_STATE_OFF)
+		return -EINVAL;
+
+	event->cpu = tad_pmu->cpu;
+	event->hw.idx = -1;
+	event->hw.config_base = event->attr.config;
+
+	return 0;
+}
+
+static ssize_t tad_pmu_event_show(struct device *dev,
+				struct device_attribute *attr, char *page)
+{
+	struct perf_pmu_events_attr *pmu_attr;
+
+	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
+	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+}
+
+#define TAD_PMU_EVENT_ATTR(name, config)			\
+	PMU_EVENT_ATTR_ID(name, tad_pmu_event_show, config)
+
+static struct attribute *tad_pmu_event_attrs[] = {
+	TAD_PMU_EVENT_ATTR(tad_none, 0x0),
+	TAD_PMU_EVENT_ATTR(tad_req_msh_in_any, 0x1),
+	TAD_PMU_EVENT_ATTR(tad_req_msh_in_mn, 0x2),
+	TAD_PMU_EVENT_ATTR(tad_req_msh_in_exlmn, 0x3),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_any, 0x4),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_mn, 0x5),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_exlmn, 0x6),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_dss, 0x7),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_retry_dss, 0x8),
+	TAD_PMU_EVENT_ATTR(tad_dat_msh_in_any, 0x9),
+	TAD_PMU_EVENT_ATTR(tad_dat_msh_in_dss, 0xa),
+	TAD_PMU_EVENT_ATTR(tad_req_msh_out_any, 0xb),
+	TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_rd, 0xc),
+	TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_wr, 0xd),
+	TAD_PMU_EVENT_ATTR(tad_req_msh_out_evict, 0xe),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_any, 0xf),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_retry_exlmn, 0x10),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_retry_mn, 0x11),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_exlmn, 0x12),
+	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_mn, 0x13),
+	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_any, 0x14),
+	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_mn, 0x15),
+	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_exlmn, 0x16),
+	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_any, 0x17),
+	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_fill, 0x18),
+	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_dss, 0x19),
+	TAD_PMU_EVENT_ATTR(tad_alloc_dtg, 0x1a),
+	TAD_PMU_EVENT_ATTR(tad_alloc_ltg, 0x1b),
+	TAD_PMU_EVENT_ATTR(tad_alloc_any, 0x1c),
+	TAD_PMU_EVENT_ATTR(tad_hit_dtg, 0x1d),
+	TAD_PMU_EVENT_ATTR(tad_hit_ltg, 0x1e),
+	TAD_PMU_EVENT_ATTR(tad_hit_any, 0x1f),
+	TAD_PMU_EVENT_ATTR(tad_tag_rd, 0x20),
+	TAD_PMU_EVENT_ATTR(tad_dat_rd, 0x21),
+	TAD_PMU_EVENT_ATTR(tad_dat_rd_byp, 0x22),
+	TAD_PMU_EVENT_ATTR(tad_ifb_occ, 0x23),
+	TAD_PMU_EVENT_ATTR(tad_req_occ, 0x24),
+	NULL,
+};
+
+static const struct attribute_group tad_pmu_events_attr_group = {
+	.name = "events",
+	.attrs = tad_pmu_event_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-7");
+
+static struct attribute *tad_pmu_format_attrs[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group tad_pmu_format_attr_group = {
+	.name = "format",
+	.attrs = tad_pmu_format_attrs,
+};
+
+static ssize_t tad_pmu_cpumask_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct tad_pmu *tad_pmu = to_tad_pmu(dev_get_drvdata(dev));
+
+	return cpumap_print_to_pagebuf(true, buf, cpumask_of(tad_pmu->cpu));
+}
+
+static DEVICE_ATTR(cpumask, 0444, tad_pmu_cpumask_show, NULL);
+
+static struct attribute *tad_pmu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static struct attribute_group tad_pmu_cpumask_attr_group = {
+	.attrs = tad_pmu_cpumask_attrs,
+};
+
+static const struct attribute_group *tad_pmu_attr_groups[] = {
+	&tad_pmu_events_attr_group,
+	&tad_pmu_format_attr_group,
+	&tad_pmu_cpumask_attr_group,
+	NULL,
+};
+
+static int tad_pmu_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct tad_region *regions;
+	struct tad_pmu *tad_pmu;
+	struct resource *res;
+	u32 tad_pmu_page_size;
+	u32 tad_page_size;
+	u32 tad_cnt;
+	int i, ret;
+	char *name;
+
+	tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu), GFP_KERNEL);
+	if (!tad_pmu)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, tad_pmu);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Mem resource not found\n");
+		return -ENODEV;
+	}
+
+	ret = of_property_read_u32(node, "tad-page-size", &tad_page_size);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't find tad-page-size property\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "tad-pmu-page-size",
+				   &tad_pmu_page_size);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't find tad-pmu-page-size property\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(node, "tad-cnt", &tad_cnt);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't find tad-cnt property\n");
+		return ret;
+	}
+
+	regions = devm_kcalloc(&pdev->dev, tad_cnt,
+			       sizeof(*regions), GFP_KERNEL);
+	if (!regions)
+		return -ENOMEM;
+
+	/* ioremap the distributed TAD pmu regions */
+	for (i = 0; i < tad_cnt && res->start < res->end; i++) {
+		regions[i].base = devm_ioremap(&pdev->dev,
+					       res->start,
+					       tad_pmu_page_size);
+		if (IS_ERR(regions[i].base)) {
+			dev_err(&pdev->dev, "TAD%d ioremap fail\n", i);
+			return -ENOMEM;
+		}
+		res->start += tad_page_size;
+	}
+
+	tad_pmu->regions = regions;
+	tad_pmu->region_cnt = tad_cnt;
+
+	tad_pmu->pmu = (struct pmu) {
+
+		.module		= THIS_MODULE,
+		.attr_groups	= tad_pmu_attr_groups,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
+				  PERF_PMU_CAP_NO_INTERRUPT,
+		.task_ctx_nr	= perf_invalid_context,
+
+		.event_init	= tad_pmu_event_init,
+		.add		= tad_pmu_event_counter_add,
+		.del		= tad_pmu_event_counter_del,
+		.start		= tad_pmu_event_counter_start,
+		.stop		= tad_pmu_event_counter_stop,
+		.read		= tad_pmu_event_counter_read,
+	};
+
+	tad_pmu->cpu = raw_smp_processor_id();
+
+	/* Register pmu instance for cpu hotplug */
+	ret = cpuhp_state_add_instance_nocalls(tad_pmu_cpuhp_state,
+					       &tad_pmu->node);
+	if (ret) {
+		dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
+		return ret;
+	}
+
+	name = "tad";
+	ret = perf_pmu_register(&tad_pmu->pmu, name, -1);
+	if (ret)
+		cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
+						    &tad_pmu->node);
+
+	return ret;
+}
+
+static int tad_pmu_remove(struct platform_device *pdev)
+{
+	struct tad_pmu *pmu = platform_get_drvdata(pdev);
+
+	cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
+						&pmu->node);
+	perf_pmu_unregister(&pmu->pmu);
+
+	return 0;
+}
+
+static const struct of_device_id tad_pmu_of_match[] = {
+	{ .compatible = "marvell,cn10k-tad-pmu", },
+	{},
+};
+
+static struct platform_driver tad_pmu_driver = {
+	.driver         = {
+		.name   = "cn10k_tad_pmu",
+		.of_match_table = of_match_ptr(tad_pmu_of_match),
+		.suppress_bind_attrs = true,
+	},
+	.probe          = tad_pmu_probe,
+	.remove         = tad_pmu_remove,
+};
+
+static int tad_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct tad_pmu *pmu = hlist_entry_safe(node, struct tad_pmu, node);
+	unsigned int target;
+
+	if (cpu != pmu->cpu)
+		return 0;
+
+	target = cpumask_any_but(cpu_online_mask, cpu);
+	if (target >= nr_cpu_ids)
+		return 0;
+
+	perf_pmu_migrate_context(&pmu->pmu, cpu, target);
+	pmu->cpu = target;
+
+	return 0;
+}
+
+static int __init tad_pmu_init(void)
+{
+	int ret;
+
+	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+				      "perf/cn10k/tadpmu:online",
+				      NULL,
+				      tad_pmu_offline_cpu);
+	if (ret < 0)
+		return ret;
+	tad_pmu_cpuhp_state = ret;
+	return platform_driver_register(&tad_pmu_driver);
+}
+
+static void __exit tad_pmu_exit(void)
+{
+	platform_driver_unregister(&tad_pmu_driver);
+	cpuhp_remove_multi_state(tad_pmu_cpuhp_state);
+}
+
+module_init(tad_pmu_init);
+module_exit(tad_pmu_exit);
+
+MODULE_DESCRIPTION("Marvell CN10K LLC-TAD Perf driver");
+MODULE_AUTHOR("Bhaskara Budiredla <bbudiredla at marvell.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1



From bbudiredla at marvell.com  Thu Aug 12 10:42:09 2021
From: bbudiredla at marvell.com (Bhaskara Budiredla)
Date: Thu, 12 Aug 2021 23:12:09 +0530
Subject: [PATCH 2/2] dt-bindings: perf: Add YAML schemas for Marvell CN10K
 LLC-TAD pmu bindings
In-Reply-To: <20210812174209.1970-1-bbudiredla@marvell.com>
References: <20210812174209.1970-1-bbudiredla@marvell.com>
Message-ID: <20210812174209.1970-3-bbudiredla@marvell.com>

Add device tree bindings for Last-level-cache Tag-and-data
(LLC-TAD) unit PMU for Marvell CN10K SoCs.

Signed-off-by: Bhaskara Budiredla <bbudiredla at marvell.com>
---
 .../bindings/perf/marvell-cn10k-tad.yaml      | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml

diff --git a/Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml b/Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml
new file mode 100644
index 000000000000..f66c5c31ecd8
--- /dev/null
+++ b/Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/perf/marvell-cn10k-tad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell CN10K LLC-TAD performance monitor
+
+maintainers:
+  - Bhaskara Budiredla <bbudiredla at marvell.com>
+
+description: |
+  The Tag-and-Data units (TADs) maintain coherence and contain CN10K
+  shared on-chip last level cache (LLC). The tad pmu measures the
+  performance of last-level cache. Each tad pmu supports up to eight
+  counters.
+
+  The DT setup comprises of number of tad blocks, the sizes of pmu
+  regions, tad blocks and overall base address of the HW.
+
+properties:
+  compatible:
+    const: marvell,cn10k-tad-pmu
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - tad-cnt
+  - tad-page-size
+  - tad-pmu-page-size
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    tad_pmu at 0x87e280000000 {
+        compatible = "marvell,cn10k-tad-pmu";
+        tad-cnt = <1>;
+        tad-page-size = <0x1000>;
+        tad-pmu-page-size = <0x1000>;
+        reg = <0x87e2 0x80000000 0x0 0x1000>;
+    };
-- 
2.17.1



From afaerber at suse.de  Thu Aug 12 10:42:38 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Thu, 12 Aug 2021 19:42:38 +0200
Subject: [PATCH 5/8] arm64: dts: s32g2: add serial/uart support
In-Reply-To: <20210805065429.27485-6-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-6-clin@suse.com>
Message-ID: <93978882-4b47-4c4a-cd43-60cb5bcdf471@suse.de>

Hi Chester et al.,

On 05.08.21 08:54, Chester Lin wrote:
> Add serial/uart support for NXP S32G2.

You might mention here that (following our initial stub) this commit is
now apparently based on the CodeAurora BSP branch foo (and therefore
adding its last-year copyright below and separate from 4/8).

> 

@NXP: If there are downstream Signed-off-bys that you would like to see
included for this portion here, please speak up.

> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  arch/arm64/boot/dts/freescale/s32g2.dtsi | 31 ++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> index 3321819c1a2d..0076eacad8a6 100644
> --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
>  /*
>   * Copyright (c) 2021 SUSE LLC
> + * Copyright 2017-2020 NXP

@NXP: Should this be updated to include 2021 from your latest BSP
releases? Do you want it visually aligned by adding the ASCII-art?

>   */
>  
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
> @@ -11,6 +12,12 @@ / {
>  	#address-cells = <2>;
>  	#size-cells = <2>;
>  
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +	};

Note: In the past there had been controversies as to whether to define
aliases globally for a SoC or in a .dts specific to a board's usage.
In this case it does not seem to matter much, as uart0 is being used as
console on the reference boards.

> +
>  	cpus {
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> @@ -82,6 +89,30 @@ soc {
>  
>  		ranges;
>  
> +		uart0: serial at 401c8000 {
> +			compatible = "fsl,s32g2-linflexuart",
> +				     "fsl,s32v234-linflexuart";
> +			reg = <0 0x401c8000 0 0x3000>;
> +			interrupts = <GIC_SPI 82 IRQ_TYPE_EDGE_RISING>;
> +			status = "disabled";
> +		};
> +
> +		uart1: serial at 401cc000 {
> +			compatible = "fsl,s32g2-linflexuart",
> +				     "fsl,s32v234-linflexuart";
> +			reg = <0 0x401cc000 0 0x3000>;
> +			interrupts = <GIC_SPI 83 IRQ_TYPE_EDGE_RISING>;
> +			status = "disabled";
> +		};
> +
> +		uart2: serial at 402bc000 {
> +			compatible = "fsl,s32g2-linflexuart",
> +				     "fsl,s32v234-linflexuart";
> +			reg = <0 0x402bc000 0 0x3000>;
> +			interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
> +			status = "disabled";
> +		};
> +
>  		gic: interrupt-controller at 50800000 {
>  			compatible = "arm,gic-v3";
>  			#interrupt-cells = <3>;

Regards,
Andreas

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From semen.protsenko at linaro.org  Thu Aug 12 10:42:42 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 12 Aug 2021 20:42:42 +0300
Subject: [PATCH v3 7/7] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <f0e892ce-acd0-7acc-4881-dd67dda6fb38@canonical.com>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
 <20210811114827.27322-8-semen.protsenko@linaro.org>
 <f0e892ce-acd0-7acc-4881-dd67dda6fb38@canonical.com>
Message-ID: <CAPLW+4=2msw44EjujeTUvcYJ701iZTPwkVoO3UzZyakspev20A@mail.gmail.com>

On Thu, 12 Aug 2021 at 11:17, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 11/08/2021 13:48, Sam Protsenko wrote:
> > Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
> >
> > This patch adds minimal SoC support by including next Device Tree nodes:
> >
> > 1. Octa cores (Cortex-A55), supporting PSCI v1.0
> > 2. ARM architecture timer (armv8-timer)
> > 3. Interrupt controller (GIC-400)
> > 4. Pinctrl nodes for GPIO
> > 5. Serial node
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> > Changes in v3:
> >  - Used generic fixed clock for serial
> >
> > Changes in v2:
> >  * Commit message:
> >    - Documented added dts features instead of CPU features
> >
> >  * exynos850-usi.dtsi:
> >    - Removed, moved everything to exynos850.dtsi
> >
> >  * exynos850.dtsi:
> >    - Root node:
> >      - Added comment about engineering name (Exynos3830)
> >      - Renamed pinctrl nodes, adding domain names
> >      - Used hard coded IRQ numbers instead of named constants everywhere
> >      - Added soc node, moved next nodes there: gic, clock, pinctrls and
> >        serial
> >      - Used address-cells=1 for soc node and removed unneeded 0x0 from
> >        reg properties
> >      - Moved exynos850-pinctrl.dtsi include line to the end of
> >        exynos850.dtsi
> >      - Coding style fixes
> >    - cpus:
> >      - Used address-cells=1 for cpus node
> >      - Renamed cpu at 0001 to cpu at 1, and so on
> >      - Left only "arm,cortex-a55" for cpus compatible
> >      - Renamed reg = <0x0001> to <0x1> for cpus
> >    - armv8 timer:
> >      - Add comment about missing HV timer IRQ to armv8 timer node
> >      - Removed not existing properties from armv8 timer node
> >      - Fixed cpu number in CPU_MASK()
> >      - Removed obsolete clock-frequency property
> >    - GIC:
> >      - Fixed GIC type to be GIC-400
> >      - Fixed size of GIC's 2nd region to be 0x2000
> >    - serial node:
> >      - Hard coded clock number for serial_0 for now; will replace with
> >        named const once proper clock driver is implemented
> >      - Removed gate_uart_clk0 clock from serial_0, as that clock is not
> >        supported in serial driver anyway (yet)
> >    - clock node:
> >      - Fixed clock controller node name (@0x12.. -> @12..)
> >
> >  * exynos850-pinctrl.dtsi:
> >    - Referenced pinctrl nodes instead of defining those again in root node
> >    - Fixed interrupt-cells (3 -> 2)
> >    - Fixed USI related comments for pin config nodes
> >    - Removed decon_f_te_* and fm_lna_en nodes (won't be used)
> >    - Reordered pin config nodes by pin numbers
> >    - Improved all comments
> >    - Used existing named constants for pin-function and pin-pud
> >    - Fixed node names (used hyphens instead of underscore)
> >    - Fixed warnings found in W=1 build
> >
> >  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
> >  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 261 ++++++
> >  2 files changed, 1009 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > new file mode 100644
> > index 000000000000..ba5d5f33e2f6
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > @@ -0,0 +1,748 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
> > + *
> > + * Copyright (C) 2017 Samsung Electronics Co., Ltd.
> > + * Copyright (C) 2021 Linaro Ltd.
> > + *
> > + * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
> > + * tree nodes in this file.
> > + */
> > +
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/pinctrl/samsung.h>
> > +
> > +&pinctrl_alive {
> > +     gpa0: gpa0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpa1: gpa1 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpa2: gpa2 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpa3: gpa3 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpa4: gpa4 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpq0: gpq0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     /* I2C5 (also called CAM_PMIC_I2C in TRM) */
> > +     i2c5_bus: i2c5-bus {
> > +             samsung,pins = "gpa3-5", "gpa3-6";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     /* I2C6 (also called MOTOR_I2C in TRM) */
> > +     i2c6_bus: i2c6-bus {
> > +             samsung,pins = "gpa3-7", "gpa4-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     /* USI: UART */
> > +     uart0_bus: uart0-bus {
> > +             samsung,pins = "gpq0-0", "gpq0-1";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +     };
> > +};
> > +
> > +&pinctrl_cmgp {
> > +     gpm0: gpm0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpm1: gpm1 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpm2: gpm2 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpm3: gpm3 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpm4: gpm4 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpm5: gpm5 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     /* USI_CMGP0: HSI2C function */
> > +     hsi2c3_bus: hsi2c3-bus {
> > +             samsung,pins = "gpm0-0", "gpm1-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
>
> There are also macros for DRV.
>

Unfortunately, existing DRV macros won't work for Exynos850. DRV
constants have different meaning for different GPIO domains in
Exynos850, so I thought introducing several groups of DRV constants
might be confusing. But please let me know if you still want me do
that.

> I assume you checked whether the actual values of FUNC/PULL/DRV macros
> match Exynos850 datasheet.
>

Yep, they are good.

> > +     };
> > +
> > +     /* USI_CMGP0: UART function (4 pins, Auto Flow Control) */
> > +     uart1_bus_single: uart1-bus {
> > +             samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +     };
> > +
> > +     /* USI_CMGP0: UART function (2 pins, Non-Auto Flow Control) */
> > +     uart1_bus_dual: uart1-bus-dual {
> > +             samsung,pins = "gpm0-0", "gpm1-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +     };
> > +
> > +     /* USI_CMGP0: SPI function */
> > +     spi1_bus: spi1-bus {
> > +             samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     spi1_cs: spi1-cs {
> > +             samsung,pins = "gpm3-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     spi1_cs_func: spi1-cs-func {
> > +             samsung,pins = "gpm3-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     /* USI_CMGP1: HSI2C function */
> > +     hsi2c4_bus: hsi2c4-bus {
> > +             samsung,pins = "gpm4-0", "gpm5-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     /* USI_CMGP1: UART function (4 pins, Auto Flow Control) */
> > +     uart2_bus_single: uart2-bus {
> > +             samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +     };
> > +
> > +     /* USI_CMGP1: UART function (2 pins, Non-Auto Flow Control) */
> > +     uart2_bus_dual: uart2-bus-dual {
> > +             samsung,pins = "gpm4-0", "gpm5-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +     };
> > +
> > +     /* USI_CMGP1: SPI function */
> > +     spi2_bus: spi2-bus {
> > +             samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     spi2_cs: spi2-cs {
> > +             samsung,pins = "gpm7-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     spi2_cs_func: spi2-cs-func {
> > +             samsung,pins = "gpm7-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +};
> > +
> > +&pinctrl_aud {
> > +     gpb0: gpb0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpb1: gpb1 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     aud_codec_mclk: aud-codec-mclk {
> > +             samsung,pins = "gpb0-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +
> > +     aud_codec_mclk_idle: aud-codec-mclk-idle {
> > +             samsung,pins = "gpb0-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +
> > +     aud_i2s0_bus: aud-i2s0-bus {
> > +             samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +
> > +     aud_i2s0_idle: aud-i2s0-idle {
> > +             samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +
> > +     aud_i2s1_bus: aud-i2s1-bus {
> > +             samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +
> > +     aud_i2s1_idle: aud-i2s1-idle {
> > +             samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +
> > +     aud_fm_bus: aud-fm-bus {
> > +             samsung,pins = "gpb1-4";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +
> > +     aud_fm_idle: aud-fm-idle {
> > +             samsung,pins = "gpb1-4";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +};
> > +
> > +&pinctrl_hsi {
> > +     gpf2: gpf2 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     sd2_clk: sd2-clk {
> > +             samsung,pins = "gpf2-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <2>;
> > +     };
> > +
> > +     sd2_clk_fast_slew_rate_1x: sd2-clk-fast-slew-rate-1x {
> > +             samsung,pins = "gpf2-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     sd2_clk_fast_slew_rate_1_5x: sd2-clk-fast-slew-rate-1-5x {
> > +             samsung,pins = "gpf2-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <1>;
> > +     };
> > +
> > +     sd2_clk_fast_slew_rate_2x: sd2-clk-fast-slew-rate-2x {
> > +             samsung,pins = "gpf2-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <2>;
> > +     };
> > +
> > +     sd2_clk_fast_slew_rate_2_5x: sd2-clk-fast-slew-rate-2-5x {
> > +             samsung,pins = "gpf2-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +
> > +     sd2_clk_fast_slew_rate_3x: sd2-clk-fast-slew-rate-3x {
> > +             samsung,pins = "gpf2-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <4>;
> > +     };
> > +
> > +     sd2_clk_fast_slew_rate_4x: sd2-clk-fast-slew-rate-4x {
> > +             samsung,pins = "gpf2-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <5>;
> > +     };
> > +
> > +     sd2_cmd: sd2-cmd {
> > +             samsung,pins = "gpf2-1";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <2>;
> > +      };
> > +
> > +     sd2_bus1: sd2-bus-width1 {
> > +             samsung,pins = "gpf2-2";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <2>;
> > +     };
> > +
> > +     sd2_bus4: sd2-bus-width4 {
> > +             samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <2>;
> > +     };
> > +
> > +     sd2_pins_as_pdn: sd2-pins-as-pdn {
> > +             samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
> > +                            "gpf2-4", "gpf2-5";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +     };
> > +};
> > +
> > +&pinctrl_core {
> > +     gpf0: gpf0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpf1: gpf1 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     sd0_clk: sd0-clk {
> > +             samsung,pins = "gpf0-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +
> > +     sd0_clk_fast_slew_rate_1x: sd0-clk-fast-slew-rate-1x {
> > +             samsung,pins = "gpf0-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <1>;
> > +     };
> > +
> > +     sd0_clk_fast_slew_rate_2x: sd0-clk-fast-slew-rate-2x {
> > +             samsung,pins = "gpf0-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <2>;
> > +     };
> > +
> > +     sd0_clk_fast_slew_rate_3x: sd0-clk-fast-slew-rate-3x {
> > +             samsung,pins = "gpf0-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <2>;
> > +     };
> > +
> > +     sd0_clk_fast_slew_rate_4x: sd0-clk-fast-slew-rate-4x {
> > +             samsung,pins = "gpf0-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +
> > +     sd0_cmd: sd0-cmd {
> > +             samsung,pins = "gpf0-1";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +
> > +     sd0_rdqs: sd0-rdqs {
> > +             samsung,pins = "gpf0-2";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +
> > +     sd0_nreset: sd0-nreset {
> > +             samsung,pins = "gpf0-3";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +
> > +     sd0_bus1: sd0-bus-width1 {
> > +             samsung,pins = "gpf1-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +
> > +     sd0_bus4: sd0-bus-width4 {
> > +             samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +
> > +     sd0_bus8: sd0-bus-width8 {
> > +             samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <3>;
> > +     };
> > +};
> > +
> > +&pinctrl_peri {
> > +     gpg0: gpg0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpp0: gpp0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +     gpp1: gpp1 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpp2: gpp2 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpg1: gpg1 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpg2: gpg2 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpg3: gpg3 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpc0: gpc0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     gpc1: gpc1 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     /* USI: HSI2C0 */
> > +     hsi2c0_bus: hsi2c0-bus {
> > +             samsung,pins = "gpc1-0", "gpc1-1";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     /* USI: HSI2C1 */
> > +     hsi2c1_bus: hsi2c1-bus {
> > +             samsung,pins = "gpc1-2", "gpc1-3";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     /* USI: HSI2C2 */
> > +     hsi2c2_bus: hsi2c2-bus {
> > +             samsung,pins = "gpc1-4", "gpc1-5";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     /* USI: SPI */
> > +     spi0_bus: spi0-bus {
> > +             samsung,pins = "gpp2-0", "gpp2-2", "gpp2-3";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     spi0_cs: spi0-cs {
> > +             samsung,pins = "gpp2-1";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     spi0_cs_func: spi0-cs-func {
> > +             samsung,pins = "gpp2-1";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     i2c0_bus: i2c0-bus {
> > +             samsung,pins = "gpp0-0", "gpp0-1";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     i2c1_bus: i2c1-bus {
> > +             samsung,pins = "gpp0-2", "gpp0-3";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     i2c2_bus: i2c2-bus {
> > +             samsung,pins = "gpp0-4", "gpp0-5";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     i2c3_bus: i2c3-bus {
> > +             samsung,pins = "gpp1-0", "gpp1-1";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     i2c4_bus: i2c4-bus {
> > +             samsung,pins = "gpp1-2", "gpp1-3";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     sensor_mclk0_in: sensor-mclk0-in {
> > +             samsung,pins = "gpc0-0";
>
> All these gpc0 go before hsi2c0_bus node (to have them ordered by
> datasheet pin name).
>

Done.

> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +             samsung,pin-drv = <2>;
> > +     };
> > +
>
> Rest looks good but anyway will wait for the board DTS. :)
>

Sure. I'll probably send next patch series only when the board gets
announced, and will include board's dts of course.

> Best regards,
> Krzysztof


From afaerber at suse.de  Thu Aug 12 11:00:01 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Thu, 12 Aug 2021 20:00:01 +0200
Subject: [PATCH 6/8] arm64: dts: s32g2: add VNP-EVB and VNP-RDB2 support
In-Reply-To: <20210805065429.27485-7-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-7-clin@suse.com>
Message-ID: <aef2fab4-078e-330b-28d0-1da964985f83@suse.de>

Hi Chester et al.,

On 05.08.21 08:54, Chester Lin wrote:
> Add initial device-trees of NXP S32G2's Evaluation Board (S32G-VNP-EVB)
> and Reference Design 2 Board (S32G-VNP-RDB2).

"Reference Design Board 2"?

> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  arch/arm64/boot/dts/freescale/Makefile        |  2 ++
>  .../arm64/boot/dts/freescale/s32g274a-evb.dts | 21 ++++++++++++++++
>  .../boot/dts/freescale/s32g274a-rdb2.dts      | 25 +++++++++++++++++++
>  3 files changed, 48 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-evb.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> 
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 4b4785d86324..2886ddd42894 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -67,4 +67,6 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-ai_ml.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
>  
> +dtb-$(CONFIG_ARCH_S32) += s32g274a-evb.dtb
> +dtb-$(CONFIG_ARCH_S32) += s32g274a-rdb2.dtb

@NXP: Note that since there's no distinction between S32V and S32G on
the Kconfig level, we decided not to add a white line here. If you wish
to visually separate them, that could be changed.

For reference:

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/Kconfig.platforms

speaks about S32 (without V), so did not need to get updated for S32G2.

>  dtb-$(CONFIG_ARCH_S32) += s32v234-evb.dtb
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> new file mode 100644
> index 000000000000..a1ae5031730a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> +/*
> + * Copyright (c) 2021 SUSE LLC
> + */
> +
> +/dts-v1/;
> +
> +#include "s32g2.dtsi"
> +
> +/ {
> +	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
> +	compatible = "fsl,s32g274a-evb", "fsl,s32g2";
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +};
> +

Is there any marking on the PCB that a /* ... */ comment could reference
here? Right now uart0 is close to stdout-path above, but that will
change once more device nodes get added and enabled alphabetically.

> +&uart0 {
> +	status = "okay";

No clock-frequency or clocks property needed?

> +};
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> new file mode 100644
> index 000000000000..b2faae306b70
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> @@ -0,0 +1,25 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> +/*
> + * Copyright (c) 2021 SUSE LLC
> + */
> +
> +/dts-v1/;
> +
> +#include "s32g2.dtsi"
> +
> +/ {
> +	model = "NXP S32G2 Reference Design 2 (S32G-VNP-RDB2)";

"Board" missing.

> +	compatible = "fsl,s32g274a-rdb2", "fsl,s32g2";
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +};
> +

Comment please.

> +&uart0 {
> +	status = "okay";

No clock-frequency or clocks property needed?

> +};
> +
> +&uart1 {
> +	status = "okay";
> +};

What is uart1? Please add a comment. Does it actually work without
clocks property?

Thanks,
Andreas

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From lkp at intel.com  Thu Aug 12 11:06:34 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 02:06:34 +0800
Subject: [xlnx:master 14/59] ERROR: modpost: "dwc3_gadget_exit_hibernation"
 [drivers/usb/dwc3/dwc3.ko] undefined!
Message-ID: <202108130230.2OIYc5pC-lkp@intel.com>

Hi Quanyang,

First bad commit (maybe != root cause):

tree:   https://github.com/Xilinx/linux-xlnx master
head:   af88f405134da108f814cfdf5eac9f2b60f2b800
commit: a5f3af6d255f3ccdd766a2424ef61cb2acef2083 [14/59] rtc: zynqmp: fix linking failure for ARCH arm
config: i386-randconfig-a005-20210812 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/Xilinx/linux-xlnx/commit/a5f3af6d255f3ccdd766a2424ef61cb2acef2083
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx master
        git checkout a5f3af6d255f3ccdd766a2424ef61cb2acef2083
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "dwc3_gadget_exit_hibernation" [drivers/usb/dwc3/dwc3.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 44077 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/c9cbe56a/attachment-0001.gz>

From Jonathan.Cameron at Huawei.com  Thu Aug 12 11:07:25 2021
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Thu, 12 Aug 2021 19:07:25 +0100
Subject: [PATCH v1 1/2] iio: mtk-auxadc: add support IIO_CHAN_INFO_RAW case
In-Reply-To: <20210812054844.30575-2-hui.liu@mediatek.com>
References: <20210812054844.30575-1-hui.liu@mediatek.com>
 <20210812054844.30575-2-hui.liu@mediatek.com>
Message-ID: <20210812190725.00007449@Huawei.com>

On Thu, 12 Aug 2021 13:48:43 +0800
Hui Liu <hui.liu at mediatek.com> wrote:

> Add support IIO_CHAN_INFO_RAW case.
Why?

We almost never support both RAW and PROCESSED as userspace should be
fine to use either.  There are a few reasons we've let drivers do
this but I would like know why it matters to you and it definitely
needs to be in the patch description.

> 
> Signed-off-by: Hui Liu <hui.liu at mediatek.com>
> ---
>  drivers/iio/adc/mt6577_auxadc.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c
> index 79c1dd68b909..e995d43287b2 100644
> --- a/drivers/iio/adc/mt6577_auxadc.c
> +++ b/drivers/iio/adc/mt6577_auxadc.c
> @@ -60,7 +60,8 @@ static const struct mtk_auxadc_compatible mt6765_compat = {
>  		.type = IIO_VOLTAGE,				    \
>  		.indexed = 1,					    \
>  		.channel = (idx),				    \
> -		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	    \
> +				      BIT(IIO_CHAN_INFO_PROCESSED), \
>  }
>  
>  static const struct iio_chan_spec mt6577_auxadc_iio_channels[] = {
> @@ -181,6 +182,19 @@ static int mt6577_auxadc_read_raw(struct iio_dev *indio_dev,
>  	struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
>  
>  	switch (info) {
> +	case IIO_CHAN_INFO_RAW:
> +		*val = mt6577_auxadc_read(indio_dev, chan);
> +		if (*val < 0) {
> +			dev_notice(indio_dev->dev.parent,
> +				"failed to sample data on channel[%d]\n",
> +				chan->channel);
> +			return *val;
> +		}
> +		if (adc_dev->dev_comp->sample_data_cali)
> +			*val = mt_auxadc_get_cali_data(*val, true);
> +
> +		return IIO_VAL_INT;
> +
>  	case IIO_CHAN_INFO_PROCESSED:
>  		*val = mt6577_auxadc_read(indio_dev, chan);
>  		if (*val < 0) {



From afaerber at suse.de  Thu Aug 12 11:25:00 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Thu, 12 Aug 2021 20:25:00 +0200
Subject: [PATCH 7/8] arm64: dts: s32g2: add memory nodes for evb and rdb2
In-Reply-To: <20210805065429.27485-8-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-8-clin@suse.com>
Message-ID: <17ab7b71-2dbe-0c66-e180-4cc2e8310441@suse.de>

Hi Chester et al.,

On 05.08.21 08:54, Chester Lin wrote:
> Add memory nodes for S32G-VNP-EVB and S32G-VNP-RDB2 since they have fixed
> RAM size.

You can drop "since they have fixed RAM size" - if they didn't, you
would simply choose the lowest size and rely on the bootloader (U-Boot)
to overwrite it with the actually detected size.

Please expand why this patch is separate - BSP based, I assume?

> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  arch/arm64/boot/dts/freescale/s32g274a-evb.dts  | 8 ++++++++
>  arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts | 8 ++++++++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> index a1ae5031730a..cd41f0af5dd8 100644
> --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
>  /*
>   * Copyright (c) 2021 SUSE LLC
> + * Copyright 2019-2020 NXP

@NXP: Please review year, alignment. Do any Signed-off-bys apply?

>   */
>  
>  /dts-v1/;
> @@ -14,6 +15,13 @@ / {
>  	chosen {
>  		stdout-path = "serial0:115200n8";
>  	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		/* 4GB RAM */

This looks strange to me - either put /* 4 GiB RAM */ before the node,
three lines above, and/or append comment /* 2 GiB */ on each line below.
Note the space, and suggest to be precise about factor 1024 vs. 1000.

> +		reg = <0 0x80000000 0 0x80000000>,

Note that this gives you the range to use for the .dtsi /soc node:
Address 0x0 with size 0x80000000 gets mapped to 0x0 0x0, excluding the
upper 0x80000000 for the RAM here. Or address 0x0 0x0 for two /soc cells
if there are high-memory peripherals.

> +		      <8 0x80000000 0 0x80000000>;

Maybe use 0x8 here and 0x0 above? (second 0 stays same, so don't mind)

> +	};
>  };
>  
>  &uart0 {
> diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> index b2faae306b70..8fbbf3b45eb8 100644
> --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
>  /*
>   * Copyright (c) 2021 SUSE LLC
> + * Copyright 2019-2020 NXP

@NXP: 2021?

>   */
>  
>  /dts-v1/;
> @@ -14,6 +15,13 @@ / {
>  	chosen {
>  		stdout-path = "serial0:115200n8";
>  	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		/* 4GB RAM */
> +		reg = <0 0x80000000 0 0x80000000>,
> +		      <8 0x80000000 0 0x80000000>;
> +	};

Same comments as for EVB.

>  };
>  
>  &uart0 {

Regards,
Andreas

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From f.fainelli at gmail.com  Thu Aug 12 11:29:04 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 12 Aug 2021 20:29:04 +0200
Subject: arm64 regression in kernel 5.12 related to the (n)VHE
In-Reply-To: <8735reakhh.wl-maz@kernel.org>
References: <53f3a2d2-22f8-edee-2507-d41a4090dad7@gmail.com>
 <87r1f09md8.wl-maz@kernel.org>
 <dd87408f-b805-11db-fc60-4047ad131bb1@gmail.com>
 <87czqj9mvo.wl-maz@kernel.org>
 <a3e48b20-6049-7f79-6541-f2fada690784@gmail.com>
 <878s179jsq.wl-maz@kernel.org>
 <764732f3-6cd7-bd18-4c83-1b851c29b2a4@gmail.com>
 <875ywb9dj7.wl-maz@kernel.org>
 <d8ad8fde-ae94-3cc6-06f8-b0ad6d5e27b7@gmail.com>
 <8735reakhh.wl-maz@kernel.org>
Message-ID: <9145f63b-2f05-983f-c95b-46513acd262e@gmail.com>



On 8/12/2021 2:57 PM, Marc Zyngier wrote:
> On Thu, 12 Aug 2021 13:29:56 +0100,
> Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>>
>> On 12.08.2021 12:13, Marc Zyngier wrote:
>>> On Thu, 12 Aug 2021 09:24:14 +0100,
>>> Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> 
> [...]
> 
>>>> I'm just an end-user with no access to CFE sources and without any
>>>> business contact as Broadcom :(
>>>
>>> I feared that would be the case. Florian's reply seems to indicate
>>> that the "upstream" firmware implementation is correct, so the OEM
>>> must have fumbled it somehow...
>>
>> Please note that Broadcom has many business units, many teams and from
>> my understanding they often don't cooperate properly.
> 
> I bet some team sampled an early version of the firmware that included
> the bug and never looked back. You can also tell the level of quality
> by the fact that it uses spin-tables to boot, that the interrupt
> controller node is incomplete...
> 
>> It's likely that BCM4908 BU screwed something up. Or maybe it's a matter
>> of CFE vs. U-Boot?
> 
> It is a matter of whatever is running at EL3 and doing the basic setup
> of the CPUs.



>>
>> Florian: does your team (set-top box and cable modem devices) use CFE or
>> U-Boot with kernels 5.12+?

Set-top-box and cable modem devices use a different boot loader (called 
BOLT) and a different EL3 firmware than the 4908 implementation, 
although we don't use virtualization we did pay attention to the 
register set-up.

Just got confirmation from the team that authored the 4908 CFE that they 
*do not* set SCR_EL3.HCE on the premise that they do not use 
virtualization....

>>
>> It's very unlikely it's a single OEM that broke CFE with custom
>> modifications. This problem affects all 3 devices I own:
>> 1. Netgear R8000P
>> 2. TP-Link Archer C2300 V1
>> 3. Asus GT-AC5300
> 
> They probably all use the same pre-cast design with some sort of
> value-add on top.

Yes indeed.

> 
> [...]
> 
>>> That's expected. Can you please check the patch below? It should
>>> result in a booting kernel which actually survives having KVM compiled
>>> in. It should even display a warning telling you that your setup is
>>> completely buggered.
>>>
>>> That's obviously not the final version, but probably a good enough
>>> approximation.
>>
>> It seems to work! Kernel has booted and I saw:
>> CPU: CPUs started in inconsistent modes
>> WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/smp.c:426 smp_cpus_done+0x8c/0xc8
>> (...)
>> kvm [1]: HYP mode not available
> 
> Right. So there is some hope. Maybe. I'm not sure I want to maintain
> this crap though.
> 
> [...]
> 
>> nand: device found, Manufacturer ID: 0xc8, Chip ID: 0xda
>> nand: ESMT NAND 256MiB 3,3V 8-bit
>> nand: 256 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
>> bcm63138_nand ff801800.nand: detected 256MiB total, 128KiB blocks, 2KiB pages, 16B OOB, 8-bit, BCH-4
>> Bad block table found at page 131008, version 0x01
>> Bad block table found at page 130944, version 0x01
>> 3 fixed-partitions partitions found on MTD device brcmnand.0
>> Creating 3 MTD partitions on "brcmnand.0":
>> 0x000000000000-0x000000100000 : "cferom"
>> 0x000000100000-0x000005800000 : "firmware"
>> 0x000005800000-0x00000af00000 : "backup"
> 
> So here's your chance! You have the firmware image here (I guess
> "cferom" is the one). It'd be interesting to disassemble it, find out
> where SCR_EL3 is set, patch it and never look back.
> 
> Only kidding.
> 
> 	M.
> 

-- 
Florian


From madvenka at linux.microsoft.com  Thu Aug 12 11:31:48 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Thu, 12 Aug 2021 13:31:48 -0500
Subject: [RFC PATCH v7 0/4] arm64: Reorganize the unwinder and implement
 stack trace reliability checks
In-Reply-To: <20210812132435.6143-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812132435.6143-1-madvenka@linux.microsoft.com>
Message-ID: <3a71bd4a-dc3c-eb66-6555-2f96877499f4@linux.microsoft.com>

The messages are not threaded properly.

I will resend the whole series with proper threading.

I apologize.

Madhavan

On 8/12/21 8:24 AM, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Make all stack walking functions use arch_stack_walk()
> ======================================================
> 
> Currently, there are multiple functions in ARM64 code that walk the
> stack using start_backtrace() and unwind_frame(). Convert all of
> them to use arch_stack_walk(). This makes maintenance easier.
> 
> Reorganize the unwinder code for better consistency and maintenance
> ===================================================================
> 
> Rename unwinder functions to unwind_*() similar to other architectures
> for naming consistency.
> 
> Annotate all of the unwind_*() functions with notrace so they cannot be
> ftraced and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe
> code can call the unwinder.
> 
> Redefine the unwinder loop and make it similar to other architectures.
> Define the following:
> 
> 	unwind_start(&frame, task, fp, pc);
> 	while (unwind_consume(&frame, consume_entry, cookie))
> 		unwind_next(&frame);
> 	return !unwind_failed(&frame);
> 
> unwind_start()
> 	Same as the original start_backtrace().
> 
> unwind_consume()
> 	This new function does two things:
> 
> 	- Calls consume_entry() to consume the return PC.
> 
> 	- Implements checks to determine whether the unwind should continue
> 	  or terminate.
> 
> unwind_next()
> 	Same as the original unwind_frame() except:
> 
> 	- the stack trace termination check has been moved from here to
> 	  unwind_consume(). So, unwind_next() assumes that the fp is valid.
> 
> 	- unwind_frame() used to return an error value. This function only
> 	  sets internal state and does not return anything. The state is
> 	  retrieved via a helper. See next.
> 
> unwind_failed()
> 	Return a boolean to indicate whether the stack trace completed
> 	successfully or failed. arch_stack_walk() ignores the return
> 	value. But arch_stack_walk_reliable() in the future will look
> 	at the return value.
> 
> Unwind status
> 	Introduce a new flag called "failed" in struct stackframe. Set this
> 	flag when an error is encountered. If this flag is set, terminate
> 	the unwind. Also, let the unwinder return the status to the caller.
> 
> Reliability checks
> ==================
> 
> There are some kernel features and conditions that make a stack trace
> unreliable. Callers may require the unwinder to detect these cases.
> E.g., livepatch.
> 
> Introduce a new function called unwind_is_reliable() that will detect
> these cases and return a boolean.
> 
> Introduce a new argument to unwind() called "need_reliable" so a caller
> can tell unwind() that it requires a reliable stack trace. For such a
> caller, any unreliability in the stack trace must be treated as a fatal
> error and the unwind must be aborted.
> 
> Call unwind_is_reliable() from unwind_consume() like this:
> 
> 	if (frame->need_reliable && !unwind_is_reliable(frame)) {
> 		frame->failed = true;
> 		return false;
> 	}
> 
> arch_stack_walk() passes "false" for need_reliable because its callers
> don't care about reliability. arch_stack_walk() is used for debug and
> test purposes.
> 
> Introduce arch_stack_walk_reliable() for ARM64. This works like
> arch_stack_walk() except for two things:
> 
> 	- It passes "true" for need_reliable.
> 
> 	- It returns -EINVAL if unwind() aborts.
> 
> Introduce the first reliability check in unwind_is_reliable() - If
> a return PC is not a valid kernel text address, consider the stack
> trace unreliable. It could be some generated code.
> 
> Other reliability checks will be added in the future. Until all of the
> checks are in place, arch_stack_walk_reliable() may not be used by
> livepatch. But it may be used by debug and test code.
> 
> SYM_CODE check
> ==============
> 
> SYM_CODE functions do not follow normal calling conventions. They cannot
> be unwound reliably using the frame pointer. Collect the address ranges
> of these functions in a special section called "sym_code_functions".
> 
> In unwind_is_reliable(), check the return PC against these ranges. If a
> match is found, then consider the stack trace unreliable. This is the
> second reliability check introduced by this work.
> 
> Last stack frame
> ----------------
> 
> If a SYM_CODE function occurs in the very last frame in the stack trace,
> then the stack trace is not considered unreliable. This is because there
> is no more unwinding to do. Examples:
> 
> 	- EL0 exception stack traces end in the top level EL0 exception
> 	  handlers.
> 
> 	- All kernel thread stack traces end in ret_from_fork().
> ---
> Changelog:
> 
> v7:
> 	From Mark Rutland:
> 
> 	- Make the unwinder loop similar to other architectures.
> 
> 	- Keep details to within the unwinder functions and return a simple
> 	  boolean to the caller.
> 
> 	- Convert some of the current code that contains unwinder logic to
> 	  simply use arch_stack_walk(). I have converted all of them.
> 
> 	- Do not copy sym_code_functions[]. Just place it in rodata for now.
> 
> 	- Have the main loop check for termination conditions rather than
> 	  having unwind_frame() check for them. In other words, let
> 	  unwind_frame() assume that the fp is valid.
> 
> 	- Replace the big comment for SYM_CODE functions with a shorter
> 	  comment.
> 
> 		/*
> 		 * As SYM_CODE functions don't follow the usual calling
> 		 * conventions, we assume by default that any SYM_CODE function
> 		 * cannot be unwound reliably.
> 		 *
> 		 * Note that this includes:
> 		 *
> 		 * - Exception handlers and entry assembly
> 		 * - Trampoline assembly (e.g., ftrace, kprobes)
> 		 * - Hypervisor-related assembly
> 		 * - Hibernation-related assembly
> 		 * - CPU start-stop, suspend-resume assembly
> 		 * - Kernel relocation assembly
> 		 */
> 
> v6:
> 	From Mark Rutland:
> 
> 	- The per-frame reliability concept and flag are acceptable. But more
> 	  work is needed to make the per-frame checks more accurate and more
> 	  complete. E.g., some code reorg is being worked on that will help.
> 
> 	  I have now removed the frame->reliable flag and deleted the whole
> 	  concept of per-frame status. This is orthogonal to this patch series.
> 	  Instead, I have improved the unwinder to return proper return codes
> 	  so a caller can take appropriate action without needing per-frame
> 	  status.
> 
> 	- Remove the mention of PLTs and update the comment.
> 
> 	  I have replaced the comment above the call to __kernel_text_address()
> 	  with the comment suggested by Mark Rutland.
> 
> 	Other comments:
> 
> 	- Other comments on the per-frame stuff are not relevant because
> 	  that approach is not there anymore.
> 
> v5:
> 	From Keiya Nobuta:
> 	
> 	- The term blacklist(ed) is not to be used anymore. I have changed it
> 	  to unreliable. So, the function unwinder_blacklisted() has been
> 	  changed to unwinder_is_unreliable().
> 
> 	From Mark Brown:
> 
> 	- Add a comment for the "reliable" flag in struct stackframe. The
> 	  reliability attribute is not complete until all the checks are
> 	  in place. Added a comment above struct stackframe.
> 
> 	- Include some of the comments in the cover letter in the actual
> 	  code so that we can compare it with the reliable stack trace
> 	  requirements document for completeness. I have added a comment:
> 
> 	  	- above unwinder_is_unreliable() that lists the requirements
> 		  that are addressed by the function.
> 
> 		- above the __kernel_text_address() call about all the cases
> 		  the call covers.
> 
> v4:
> 	From Mark Brown:
> 
> 	- I was checking the return PC with __kernel_text_address() before
> 	  the Function Graph trace handling. Mark Brown felt that all the
> 	  reliability checks should be performed on the original return PC
> 	  once that is obtained. So, I have moved all the reliability checks
> 	  to after the Function Graph Trace handling code in the unwinder.
> 	  Basically, the unwinder should perform PC translations first (for
> 	  rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
> 	  Then, the reliability checks should be applied to the resulting
> 	  PC.
> 
> 	- Mark said to improve the naming of the new functions so they don't
> 	  collide with existing ones. I have used a prefix "unwinder_" for
> 	  all the new functions.
> 
> 	From Josh Poimboeuf:
> 
> 	- In the error scenarios in the unwinder, the reliable flag in the
> 	  stack frame should be set. Implemented this.
> 
> 	- Some of the other comments are not relevant to the new code as
> 	  I have taken a different approach in the new code. That is why
> 	  I have not made those changes. E.g., Ard wanted me to add the
> 	  "const" keyword to the global section array. That array does not
> 	  exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
> 	  the same array in a for loop.
> 
> 	Other changes:
> 
> 	- Add a new definition for SYM_CODE_END() that adds the address
> 	  range of the function to a special section called
> 	  "sym_code_functions".
> 
> 	- Include the new section under initdata in vmlinux.lds.S.
> 
> 	- Define an early_initcall() to copy the contents of the
> 	  "sym_code_functions" section to an array by the same name.
> 
> 	- Define a function unwinder_blacklisted() that compares a return
> 	  PC against sym_code_sections[]. If there is a match, mark the
> 	  stack trace unreliable. Call this from unwind_frame().
> 
> v3:
> 	- Implemented a sym_code_ranges[] array to contains sections bounds
> 	  for text sections that contain SYM_CODE_*() functions. The unwinder
> 	  checks each return PC against the sections. If it falls in any of
> 	  the sections, the stack trace is marked unreliable.
> 
> 	- Moved SYM_CODE functions from .text and .init.text into a new
> 	  text section called ".code.text". Added this section to
> 	  vmlinux.lds.S and sym_code_ranges[].
> 
> 	- Fixed the logic in the unwinder that handles Function Graph
> 	  Tracer return trampoline.
> 
> 	- Removed all the previous code that handles:
> 		- ftrace entry code for traced function
> 		- special_functions[] array that lists individual functions
> 		- kretprobe_trampoline() special case
> 
> v2
> 	- Removed the terminating entry { 0, 0 } in special_functions[]
> 	  and replaced it with the idiom { /* sentinel */ }.
> 
> 	- Change the ftrace trampoline entry ftrace_graph_call in
> 	  special_functions[] to ftrace_call + 4 and added explanatory
> 	  comments.
> 
> 	- Unnested #ifdefs in special_functions[] for FTRACE.
> 
> v1
> 	- Define a bool field in struct stackframe. This will indicate if
> 	  a stack trace is reliable.
> 
> 	- Implement a special_functions[] array that will be populated
> 	  with special functions in which the stack trace is considered
> 	  unreliable.
> 	
> 	- Using kallsyms_lookup(), get the address ranges for the special
> 	  functions and record them.
> 
> 	- Implement an is_reliable_function(pc). This function will check
> 	  if a given return PC falls in any of the special functions. If
> 	  it does, the stack trace is unreliable.
> 
> 	- Implement check_reliability() function that will check if a
> 	  stack frame is reliable. Call is_reliable_function() from
> 	  check_reliability().
> 
> 	- Before a return PC is checked against special_funtions[], it
> 	  must be validates as a proper kernel text address. Call
> 	  __kernel_text_address() from check_reliability().
> 
> 	- Finally, call check_reliability() from unwind_frame() for
> 	  each stack frame.
> 
> 	- Add EL1 exception handlers to special_functions[].
> 
> 		el1_sync();
> 		el1_irq();
> 		el1_error();
> 		el1_sync_invalid();
> 		el1_irq_invalid();
> 		el1_fiq_invalid();
> 		el1_error_invalid();
> 
> 	- The above functions are currently defined as LOCAL symbols.
> 	  Make them global so that they can be referenced from the
> 	  unwinder code.
> 
> 	- Add FTRACE trampolines to special_functions[]:
> 
> 		ftrace_graph_call()
> 		ftrace_graph_caller()
> 		return_to_handler()
> 
> 	- Add the kretprobe trampoline to special functions[]:
> 
> 		kretprobe_trampoline()
> 
> Previous versions and discussion
> ================================
> 
> v6: https://lore.kernel.org/linux-arm-kernel/20210630223356.58714-1-madvenka at linux.microsoft.com/
> v5: https://lore.kernel.org/linux-arm-kernel/20210526214917.20099-1-madvenka at linux.microsoft.com/
> v4: https://lore.kernel.org/linux-arm-kernel/20210516040018.128105-1-madvenka at linux.microsoft.com/
> v3: https://lore.kernel.org/linux-arm-kernel/20210503173615.21576-1-madvenka at linux.microsoft.com/
> v2: https://lore.kernel.org/linux-arm-kernel/20210405204313.21346-1-madvenka at linux.microsoft.com/
> v1: https://lore.kernel.org/linux-arm-kernel/20210330190955.13707-1-madvenka at linux.microsoft.com/
> Madhavan T. Venkataraman (4):
>   arm64: Make all stack walking functions use arch_stack_walk()
>   arm64: Reorganize the unwinder code for better consistency and
>     maintenance
>   arm64: Introduce stack trace reliability checks in the unwinder
>   arm64: Create a list of SYM_CODE functions, check return PC against
>     list
> 
>  arch/arm64/include/asm/linkage.h    |  12 ++
>  arch/arm64/include/asm/sections.h   |   1 +
>  arch/arm64/include/asm/stacktrace.h |  16 +-
>  arch/arm64/kernel/perf_callchain.c  |   5 +-
>  arch/arm64/kernel/process.c         |  39 ++--
>  arch/arm64/kernel/return_address.c  |   6 +-
>  arch/arm64/kernel/stacktrace.c      | 291 ++++++++++++++++++++--------
>  arch/arm64/kernel/time.c            |  22 ++-
>  arch/arm64/kernel/vmlinux.lds.S     |  10 +
>  9 files changed, 277 insertions(+), 125 deletions(-)
> 
> 
> base-commit: 36a21d51725af2ce0700c6ebcb6b9594aac658a6
> 


From madvenka at linux.microsoft.com  Thu Aug 12 11:35:54 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 13:35:54 -0500
Subject: [RFC PATCH v7 0/4] arm64: Reorganize the unwinder and implement stack
 trace reliability checks
In-Reply-To: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
Message-ID: <20210812183559.22693-1-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Make all stack walking functions use arch_stack_walk()
======================================================

Currently, there are multiple functions in ARM64 code that walk the
stack using start_backtrace() and unwind_frame(). Convert all of
them to use arch_stack_walk(). This makes maintenance easier.

Reorganize the unwinder code for better consistency and maintenance
===================================================================

Rename unwinder functions to unwind_*() similar to other architectures
for naming consistency.

Annotate all of the unwind_*() functions with notrace so they cannot be
ftraced and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe
code can call the unwinder.

Redefine the unwinder loop and make it similar to other architectures.
Define the following:

	unwind_start(&frame, task, fp, pc);
	while (unwind_consume(&frame, consume_entry, cookie))
		unwind_next(&frame);
	return !unwind_failed(&frame);

unwind_start()
	Same as the original start_backtrace().

unwind_consume()
	This new function does two things:

	- Calls consume_entry() to consume the return PC.

	- Implements checks to determine whether the unwind should continue
	  or terminate.

unwind_next()
	Same as the original unwind_frame() except:

	- the stack trace termination check has been moved from here to
	  unwind_consume(). So, unwind_next() assumes that the fp is valid.

	- unwind_frame() used to return an error value. This function only
	  sets internal state and does not return anything. The state is
	  retrieved via a helper. See next.

unwind_failed()
	Return a boolean to indicate whether the stack trace completed
	successfully or failed. arch_stack_walk() ignores the return
	value. But arch_stack_walk_reliable() in the future will look
	at the return value.

Unwind status
	Introduce a new flag called "failed" in struct stackframe. Set this
	flag when an error is encountered. If this flag is set, terminate
	the unwind. Also, let the unwinder return the status to the caller.

Reliability checks
==================

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_is_reliable() that will detect
these cases and return a boolean.

Introduce a new argument to unwind() called "need_reliable" so a caller
can tell unwind() that it requires a reliable stack trace. For such a
caller, any unreliability in the stack trace must be treated as a fatal
error and the unwind must be aborted.

Call unwind_is_reliable() from unwind_consume() like this:

	if (frame->need_reliable && !unwind_is_reliable(frame)) {
		frame->failed = true;
		return false;
	}

arch_stack_walk() passes "false" for need_reliable because its callers
don't care about reliability. arch_stack_walk() is used for debug and
test purposes.

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except for two things:

	- It passes "true" for need_reliable.

	- It returns -EINVAL if unwind() aborts.

Introduce the first reliability check in unwind_is_reliable() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future. Until all of the
checks are in place, arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

SYM_CODE check
==============

SYM_CODE functions do not follow normal calling conventions. They cannot
be unwound reliably using the frame pointer. Collect the address ranges
of these functions in a special section called "sym_code_functions".

In unwind_is_reliable(), check the return PC against these ranges. If a
match is found, then consider the stack trace unreliable. This is the
second reliability check introduced by this work.

Last stack frame
----------------

If a SYM_CODE function occurs in the very last frame in the stack trace,
then the stack trace is not considered unreliable. This is because there
is no more unwinding to do. Examples:

	- EL0 exception stack traces end in the top level EL0 exception
	  handlers.

	- All kernel thread stack traces end in ret_from_fork().
---
Changelog:

v7:
	From Mark Rutland:

	- Make the unwinder loop similar to other architectures.

	- Keep details to within the unwinder functions and return a simple
	  boolean to the caller.

	- Convert some of the current code that contains unwinder logic to
	  simply use arch_stack_walk(). I have converted all of them.

	- Do not copy sym_code_functions[]. Just place it in rodata for now.

	- Have the main loop check for termination conditions rather than
	  having unwind_frame() check for them. In other words, let
	  unwind_frame() assume that the fp is valid.

	- Replace the big comment for SYM_CODE functions with a shorter
	  comment.

		/*
		 * As SYM_CODE functions don't follow the usual calling
		 * conventions, we assume by default that any SYM_CODE function
		 * cannot be unwound reliably.
		 *
		 * Note that this includes:
		 *
		 * - Exception handlers and entry assembly
		 * - Trampoline assembly (e.g., ftrace, kprobes)
		 * - Hypervisor-related assembly
		 * - Hibernation-related assembly
		 * - CPU start-stop, suspend-resume assembly
		 * - Kernel relocation assembly
		 */

v6:
	From Mark Rutland:

	- The per-frame reliability concept and flag are acceptable. But more
	  work is needed to make the per-frame checks more accurate and more
	  complete. E.g., some code reorg is being worked on that will help.

	  I have now removed the frame->reliable flag and deleted the whole
	  concept of per-frame status. This is orthogonal to this patch series.
	  Instead, I have improved the unwinder to return proper return codes
	  so a caller can take appropriate action without needing per-frame
	  status.

	- Remove the mention of PLTs and update the comment.

	  I have replaced the comment above the call to __kernel_text_address()
	  with the comment suggested by Mark Rutland.

	Other comments:

	- Other comments on the per-frame stuff are not relevant because
	  that approach is not there anymore.

v5:
	From Keiya Nobuta:
	
	- The term blacklist(ed) is not to be used anymore. I have changed it
	  to unreliable. So, the function unwinder_blacklisted() has been
	  changed to unwinder_is_unreliable().

	From Mark Brown:

	- Add a comment for the "reliable" flag in struct stackframe. The
	  reliability attribute is not complete until all the checks are
	  in place. Added a comment above struct stackframe.

	- Include some of the comments in the cover letter in the actual
	  code so that we can compare it with the reliable stack trace
	  requirements document for completeness. I have added a comment:

	  	- above unwinder_is_unreliable() that lists the requirements
		  that are addressed by the function.

		- above the __kernel_text_address() call about all the cases
		  the call covers.

v4:
	From Mark Brown:

	- I was checking the return PC with __kernel_text_address() before
	  the Function Graph trace handling. Mark Brown felt that all the
	  reliability checks should be performed on the original return PC
	  once that is obtained. So, I have moved all the reliability checks
	  to after the Function Graph Trace handling code in the unwinder.
	  Basically, the unwinder should perform PC translations first (for
	  rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
	  Then, the reliability checks should be applied to the resulting
	  PC.

	- Mark said to improve the naming of the new functions so they don't
	  collide with existing ones. I have used a prefix "unwinder_" for
	  all the new functions.

	From Josh Poimboeuf:

	- In the error scenarios in the unwinder, the reliable flag in the
	  stack frame should be set. Implemented this.

	- Some of the other comments are not relevant to the new code as
	  I have taken a different approach in the new code. That is why
	  I have not made those changes. E.g., Ard wanted me to add the
	  "const" keyword to the global section array. That array does not
	  exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
	  the same array in a for loop.

	Other changes:

	- Add a new definition for SYM_CODE_END() that adds the address
	  range of the function to a special section called
	  "sym_code_functions".

	- Include the new section under initdata in vmlinux.lds.S.

	- Define an early_initcall() to copy the contents of the
	  "sym_code_functions" section to an array by the same name.

	- Define a function unwinder_blacklisted() that compares a return
	  PC against sym_code_sections[]. If there is a match, mark the
	  stack trace unreliable. Call this from unwind_frame().

v3:
	- Implemented a sym_code_ranges[] array to contains sections bounds
	  for text sections that contain SYM_CODE_*() functions. The unwinder
	  checks each return PC against the sections. If it falls in any of
	  the sections, the stack trace is marked unreliable.

	- Moved SYM_CODE functions from .text and .init.text into a new
	  text section called ".code.text". Added this section to
	  vmlinux.lds.S and sym_code_ranges[].

	- Fixed the logic in the unwinder that handles Function Graph
	  Tracer return trampoline.

	- Removed all the previous code that handles:
		- ftrace entry code for traced function
		- special_functions[] array that lists individual functions
		- kretprobe_trampoline() special case

v2
	- Removed the terminating entry { 0, 0 } in special_functions[]
	  and replaced it with the idiom { /* sentinel */ }.

	- Change the ftrace trampoline entry ftrace_graph_call in
	  special_functions[] to ftrace_call + 4 and added explanatory
	  comments.

	- Unnested #ifdefs in special_functions[] for FTRACE.

v1
	- Define a bool field in struct stackframe. This will indicate if
	  a stack trace is reliable.

	- Implement a special_functions[] array that will be populated
	  with special functions in which the stack trace is considered
	  unreliable.
	
	- Using kallsyms_lookup(), get the address ranges for the special
	  functions and record them.

	- Implement an is_reliable_function(pc). This function will check
	  if a given return PC falls in any of the special functions. If
	  it does, the stack trace is unreliable.

	- Implement check_reliability() function that will check if a
	  stack frame is reliable. Call is_reliable_function() from
	  check_reliability().

	- Before a return PC is checked against special_funtions[], it
	  must be validates as a proper kernel text address. Call
	  __kernel_text_address() from check_reliability().

	- Finally, call check_reliability() from unwind_frame() for
	  each stack frame.

	- Add EL1 exception handlers to special_functions[].

		el1_sync();
		el1_irq();
		el1_error();
		el1_sync_invalid();
		el1_irq_invalid();
		el1_fiq_invalid();
		el1_error_invalid();

	- The above functions are currently defined as LOCAL symbols.
	  Make them global so that they can be referenced from the
	  unwinder code.

	- Add FTRACE trampolines to special_functions[]:

		ftrace_graph_call()
		ftrace_graph_caller()
		return_to_handler()

	- Add the kretprobe trampoline to special functions[]:

		kretprobe_trampoline()

Previous versions and discussion
================================

v6: https://lore.kernel.org/linux-arm-kernel/20210630223356.58714-1-madvenka at linux.microsoft.com/
v5: https://lore.kernel.org/linux-arm-kernel/20210526214917.20099-1-madvenka at linux.microsoft.com/
v4: https://lore.kernel.org/linux-arm-kernel/20210516040018.128105-1-madvenka at linux.microsoft.com/
v3: https://lore.kernel.org/linux-arm-kernel/20210503173615.21576-1-madvenka at linux.microsoft.com/
v2: https://lore.kernel.org/linux-arm-kernel/20210405204313.21346-1-madvenka at linux.microsoft.com/
v1: https://lore.kernel.org/linux-arm-kernel/20210330190955.13707-1-madvenka at linux.microsoft.com/
Madhavan T. Venkataraman (4):
  arm64: Make all stack walking functions use arch_stack_walk()
  arm64: Reorganize the unwinder code for better consistency and
    maintenance
  arm64: Introduce stack trace reliability checks in the unwinder
  arm64: Create a list of SYM_CODE functions, check return PC against
    list

 arch/arm64/include/asm/linkage.h    |  12 ++
 arch/arm64/include/asm/sections.h   |   1 +
 arch/arm64/include/asm/stacktrace.h |  16 +-
 arch/arm64/kernel/perf_callchain.c  |   5 +-
 arch/arm64/kernel/process.c         |  39 ++--
 arch/arm64/kernel/return_address.c  |   6 +-
 arch/arm64/kernel/stacktrace.c      | 291 ++++++++++++++++++++--------
 arch/arm64/kernel/time.c            |  22 ++-
 arch/arm64/kernel/vmlinux.lds.S     |  10 +
 9 files changed, 277 insertions(+), 125 deletions(-)


base-commit: 36a21d51725af2ce0700c6ebcb6b9594aac658a6
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 11:35:55 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 13:35:55 -0500
Subject: [RFC PATCH v7 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210812183559.22693-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812183559.22693-1-madvenka@linux.microsoft.com>
Message-ID: <20210812183559.22693-2-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Currently, there are multiple functions in ARM64 code that walk the
stack using start_backtrace() and unwind_frame(). Convert all of
them to use arch_stack_walk(). This makes maintenance easier.

Here is the list of functions:

	perf_callchain_kernel()
	get_wchan()
	return_address()
	dump_backtrace()
	profile_pc()

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  3 ---
 arch/arm64/kernel/perf_callchain.c  |  5 +---
 arch/arm64/kernel/process.c         | 39 ++++++++++++++++++-----------
 arch/arm64/kernel/return_address.c  |  6 +----
 arch/arm64/kernel/stacktrace.c      | 38 +++-------------------------
 arch/arm64/kernel/time.c            | 22 +++++++++-------
 6 files changed, 43 insertions(+), 70 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 8aebc00c1718..e43dea1c6b41 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -61,9 +61,6 @@ struct stackframe {
 #endif
 };
 
-extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
-extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
-			    bool (*fn)(void *, unsigned long), void *data);
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 			   const char *loglvl);
 
diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 4a72c2727309..2f289013c9c9 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -147,15 +147,12 @@ static bool callchain_trace(void *data, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
-	struct stackframe frame;
-
 	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
 
-	start_backtrace(&frame, regs->regs[29], regs->pc);
-	walk_stackframe(current, &frame, callchain_trace, entry);
+	arch_stack_walk(callchain_trace, entry, current, regs);
 }
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index c8989b999250..52c12fd26407 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -544,11 +544,28 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
 	return last;
 }
 
+struct wchan_info {
+	unsigned long	pc;
+	int		count;
+};
+
+static bool get_wchan_cb(void *arg, unsigned long pc)
+{
+	struct wchan_info *wchan_info = arg;
+
+	if (!in_sched_functions(pc)) {
+		wchan_info->pc = pc;
+		return false;
+	}
+	wchan_info->count--;
+	return !!wchan_info->count;
+}
+
 unsigned long get_wchan(struct task_struct *p)
 {
-	struct stackframe frame;
-	unsigned long stack_page, ret = 0;
-	int count = 0;
+	unsigned long stack_page;
+	struct wchan_info wchan_info;
+
 	if (!p || p == current || task_is_running(p))
 		return 0;
 
@@ -556,20 +573,12 @@ unsigned long get_wchan(struct task_struct *p)
 	if (!stack_page)
 		return 0;
 
-	start_backtrace(&frame, thread_saved_fp(p), thread_saved_pc(p));
+	wchan_info.pc = 0;
+	wchan_info.count = 16;
+	arch_stack_walk(get_wchan_cb, &wchan_info, p, NULL);
 
-	do {
-		if (unwind_frame(p, &frame))
-			goto out;
-		if (!in_sched_functions(frame.pc)) {
-			ret = frame.pc;
-			goto out;
-		}
-	} while (count++ < 16);
-
-out:
 	put_task_stack(p);
-	return ret;
+	return wchan_info.pc;
 }
 
 unsigned long arch_align_stack(unsigned long sp)
diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c
index a6d18755652f..92a0f4d434e4 100644
--- a/arch/arm64/kernel/return_address.c
+++ b/arch/arm64/kernel/return_address.c
@@ -35,15 +35,11 @@ NOKPROBE_SYMBOL(save_return_addr);
 void *return_address(unsigned int level)
 {
 	struct return_address_data data;
-	struct stackframe frame;
 
 	data.level = level + 2;
 	data.addr = NULL;
 
-	start_backtrace(&frame,
-			(unsigned long)__builtin_frame_address(0),
-			(unsigned long)return_address);
-	walk_stackframe(current, &frame, save_return_addr, &data);
+	arch_stack_walk(save_return_addr, &data, current, NULL);
 
 	if (!data.level)
 		return data.addr;
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 8982a2b78acf..1800310f92be 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -151,23 +151,21 @@ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
 }
 NOKPROBE_SYMBOL(walk_stackframe);
 
-static void dump_backtrace_entry(unsigned long where, const char *loglvl)
+static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
+	char *loglvl = arg;
 	printk("%s %pSb\n", loglvl, (void *)where);
+	return true;
 }
 
 void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 		    const char *loglvl)
 {
-	struct stackframe frame;
-	int skip = 0;
-
 	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
 
 	if (regs) {
 		if (user_mode(regs))
 			return;
-		skip = 1;
 	}
 
 	if (!tsk)
@@ -176,36 +174,8 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 	if (!try_get_task_stack(tsk))
 		return;
 
-	if (tsk == current) {
-		start_backtrace(&frame,
-				(unsigned long)__builtin_frame_address(0),
-				(unsigned long)dump_backtrace);
-	} else {
-		/*
-		 * task blocked in __switch_to
-		 */
-		start_backtrace(&frame,
-				thread_saved_fp(tsk),
-				thread_saved_pc(tsk));
-	}
-
 	printk("%sCall trace:\n", loglvl);
-	do {
-		/* skip until specified stack frame */
-		if (!skip) {
-			dump_backtrace_entry(frame.pc, loglvl);
-		} else if (frame.fp == regs->regs[29]) {
-			skip = 0;
-			/*
-			 * Mostly, this is the case where this function is
-			 * called in panic/abort. As exception handler's
-			 * stack frame does not contain the corresponding pc
-			 * at which an exception has taken place, use regs->pc
-			 * instead.
-			 */
-			dump_backtrace_entry(regs->pc, loglvl);
-		}
-	} while (!unwind_frame(tsk, &frame));
+	arch_stack_walk(dump_backtrace_entry, (void *)loglvl, tsk, regs);
 
 	put_task_stack(tsk);
 }
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index eebbc8d7123e..671b3038a772 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -32,22 +32,26 @@
 #include <asm/stacktrace.h>
 #include <asm/paravirt.h>
 
+static bool profile_pc_cb(void *arg, unsigned long pc)
+{
+	unsigned long *prof_pc = arg;
+
+	if (in_lock_functions(pc))
+		return true;
+	*prof_pc = pc;
+	return false;
+}
+
 unsigned long profile_pc(struct pt_regs *regs)
 {
-	struct stackframe frame;
+	unsigned long prof_pc = 0;
 
 	if (!in_lock_functions(regs->pc))
 		return regs->pc;
 
-	start_backtrace(&frame, regs->regs[29], regs->pc);
-
-	do {
-		int ret = unwind_frame(NULL, &frame);
-		if (ret < 0)
-			return 0;
-	} while (in_lock_functions(frame.pc));
+	arch_stack_walk(profile_pc_cb, &prof_pc, current, regs);
 
-	return frame.pc;
+	return prof_pc;
 }
 EXPORT_SYMBOL(profile_pc);
 
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 11:35:56 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 13:35:56 -0500
Subject: [RFC PATCH v7 2/4] arm64: Reorganize the unwinder code for better
 consistency and maintenance
In-Reply-To: <20210812183559.22693-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812183559.22693-1-madvenka@linux.microsoft.com>
Message-ID: <20210812183559.22693-3-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Renaming of unwinder functions
==============================

Rename unwinder functions to unwind_*() similar to other architectures
for naming consistency. More on this below.

unwind function attributes
==========================

Mark all of the unwind_*() functions with notrace so they cannot be ftraced
and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe code
can call the unwinder.

start_backtrace()
=================

start_backtrace() is only called by arch_stack_walk(). Make it static.
Rename start_backtrace() to unwind_start() for naming consistency.

unwind_frame()
==============

Rename this to unwind_next() for naming consistency.

Replace walk_stackframe() with unwind()
=======================================

walk_stackframe() contains the unwinder loop that walks the stack
frames. Currently, start_backtrace() and walk_stackframe() are called
separately. They should be combined in the same function. Also, the
loop in walk_stackframe() should be simplified and should look like
the unwind loops in other architectures such as X86 and S390.

Remove walk_stackframe(). Define a new function called "unwind()" in
its place. Define the following unwinder loop:

	unwind_start(&frame, task, fp, pc);
	while (unwind_consume(&frame, consume_entry, cookie))
		unwind_next(&frame);
	return !unwind_failed(&frame);

unwind_start()
	Same as the original start_backtrace().

unwind_consume()
	This is a new function that calls the callback function to
	consume the PC in a stackframe. Do it this way so that checks
	can be performed before and after the callback to determine
	whether the unwind should continue or terminate.

unwind_next()
	Same as the original unwind_frame() except for two things:

		- the stack trace termination check has been moved from
		  here to unwind_consume(). So, unwind_next() is always
		  called on a valid fp.

		- unwind_frame() used to return an error value. This
		  function does not return anything.

unwind_failed()
	Return a boolean to indicate if the stack trace completed
	successfully or failed. arch_stack_walk() ignores the return
	value. But arch_stack_walk_reliable() in the future will look
	at the return value.

Unwind status
=============

Introduce a new flag called "failed" in struct stackframe. unwind_next()
and unwind_consume() will set this flag when an error is encountered and
unwind_consume() will check this flag. This is in keeping with other
architectures.

The failed flags is accessed via the helper unwind_failed().

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |   9 +-
 arch/arm64/kernel/stacktrace.c      | 145 ++++++++++++++++++----------
 2 files changed, 99 insertions(+), 55 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index e43dea1c6b41..407007376e97 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -34,6 +34,8 @@ struct stack_info {
  * A snapshot of a frame record or fp/lr register values, along with some
  * accounting information necessary for robust unwinding.
  *
+ * @task:        The task whose stack is being unwound.
+ *
  * @fp:          The fp value in the frame record (or the real fp)
  * @pc:          The lr value in the frame record (or the real lr)
  *
@@ -49,8 +51,11 @@ struct stack_info {
  *
  * @graph:       When FUNCTION_GRAPH_TRACER is selected, holds the index of a
  *               replacement lr value in the ftrace graph stack.
+ *
+ * @failed:      Unwind failed.
  */
 struct stackframe {
+	struct task_struct *task;
 	unsigned long fp;
 	unsigned long pc;
 	DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
@@ -59,6 +64,7 @@ struct stackframe {
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	int graph;
 #endif
+	bool failed;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
@@ -145,7 +151,4 @@ static inline bool on_accessible_stack(const struct task_struct *tsk,
 	return false;
 }
 
-void start_backtrace(struct stackframe *frame, unsigned long fp,
-		     unsigned long pc);
-
 #endif	/* __ASM_STACKTRACE_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 1800310f92be..ec8f5163c4d0 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -32,10 +32,11 @@
  *	add	sp, sp, #0x10
  */
 
-
-void start_backtrace(struct stackframe *frame, unsigned long fp,
-		     unsigned long pc)
+static void notrace unwind_start(struct stackframe *frame,
+				 struct task_struct *task,
+				 unsigned long fp, unsigned long pc)
 {
+	frame->task = task;
 	frame->fp = fp;
 	frame->pc = pc;
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -45,7 +46,7 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
 	/*
 	 * Prime the first unwind.
 	 *
-	 * In unwind_frame() we'll check that the FP points to a valid stack,
+	 * In unwind_next() we'll check that the FP points to a valid stack,
 	 * which can't be STACK_TYPE_UNKNOWN, and the first unwind will be
 	 * treated as a transition to whichever stack that happens to be. The
 	 * prev_fp value won't be used, but we set it to 0 such that it is
@@ -54,8 +55,11 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
 	bitmap_zero(frame->stacks_done, __NR_STACK_TYPES);
 	frame->prev_fp = 0;
 	frame->prev_type = STACK_TYPE_UNKNOWN;
+	frame->failed = false;
 }
 
+NOKPROBE_SYMBOL(unwind_start);
+
 /*
  * Unwind from one frame record (A) to the next frame record (B).
  *
@@ -63,26 +67,26 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
+static void notrace unwind_next(struct stackframe *frame)
 {
 	unsigned long fp = frame->fp;
 	struct stack_info info;
+	struct task_struct *tsk = frame->task;
 
-	if (!tsk)
-		tsk = current;
-
-	/* Final frame; nothing to unwind */
-	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
-		return -ENOENT;
-
-	if (fp & 0x7)
-		return -EINVAL;
+	if (fp & 0x7) {
+		frame->failed = true;
+		return;
+	}
 
-	if (!on_accessible_stack(tsk, fp, 16, &info))
-		return -EINVAL;
+	if (!on_accessible_stack(tsk, fp, 16, &info)) {
+		frame->failed = true;
+		return;
+	}
 
-	if (test_bit(info.type, frame->stacks_done))
-		return -EINVAL;
+	if (test_bit(info.type, frame->stacks_done)) {
+		frame->failed = true;
+		return;
+	}
 
 	/*
 	 * As stacks grow downward, any valid record on the same stack must be
@@ -98,15 +102,17 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
 	 * stack.
 	 */
 	if (info.type == frame->prev_type) {
-		if (fp <= frame->prev_fp)
-			return -EINVAL;
+		if (fp <= frame->prev_fp) {
+			frame->failed = true;
+			return;
+		}
 	} else {
 		set_bit(frame->prev_type, frame->stacks_done);
 	}
 
 	/*
 	 * Record this frame record's values and location. The prev_fp and
-	 * prev_type are only meaningful to the next unwind_frame() invocation.
+	 * prev_type are only meaningful to the next unwind_next() invocation.
 	 */
 	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
 	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
@@ -124,32 +130,18 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
 		 * So replace it to an original value.
 		 */
 		ret_stack = ftrace_graph_get_ret_stack(tsk, frame->graph++);
-		if (WARN_ON_ONCE(!ret_stack))
-			return -EINVAL;
+		if (WARN_ON_ONCE(!ret_stack)) {
+			frame->failed = true;
+			return;
+		}
 		frame->pc = ret_stack->ret;
 	}
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
 	frame->pc = ptrauth_strip_insn_pac(frame->pc);
-
-	return 0;
 }
-NOKPROBE_SYMBOL(unwind_frame);
 
-void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
-			     bool (*fn)(void *, unsigned long), void *data)
-{
-	while (1) {
-		int ret;
-
-		if (!fn(data, frame->pc))
-			break;
-		ret = unwind_frame(tsk, frame);
-		if (ret < 0)
-			break;
-	}
-}
-NOKPROBE_SYMBOL(walk_stackframe);
+NOKPROBE_SYMBOL(unwind_next);
 
 static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
@@ -186,25 +178,74 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
 	barrier();
 }
 
+static bool notrace unwind_consume(struct stackframe *frame,
+				   stack_trace_consume_fn consume_entry,
+				   void *cookie)
+{
+	if (frame->failed) {
+		/* PC is suspect. Cannot consume it. */
+		return false;
+	}
+
+	if (!consume_entry(cookie, frame->pc)) {
+		/* Caller terminated the unwind. */
+		frame->failed = true;
+		return false;
+	}
+
+	if (frame->fp == (unsigned long)task_pt_regs(frame->task)->stackframe) {
+		/* Final frame; nothing to unwind */
+		return false;
+	}
+	return true;
+}
+
+NOKPROBE_SYMBOL(unwind_consume);
+
+static inline bool unwind_failed(struct stackframe *frame)
+{
+	return frame->failed;
+}
+
+/* Core unwind function */
+static bool notrace unwind(stack_trace_consume_fn consume_entry, void *cookie,
+			   struct task_struct *task,
+			   unsigned long fp, unsigned long pc)
+{
+	struct stackframe frame;
+
+	unwind_start(&frame, task, fp, pc);
+	while (unwind_consume(&frame, consume_entry, cookie))
+		unwind_next(&frame);
+	return !unwind_failed(&frame);
+}
+
+NOKPROBE_SYMBOL(unwind);
+
 #ifdef CONFIG_STACKTRACE
 
 noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 			      void *cookie, struct task_struct *task,
 			      struct pt_regs *regs)
 {
-	struct stackframe frame;
+	unsigned long fp, pc;
+
+	if (!task)
+		task = current;
 
-	if (regs)
-		start_backtrace(&frame, regs->regs[29], regs->pc);
-	else if (task == current)
-		start_backtrace(&frame,
-				(unsigned long)__builtin_frame_address(1),
-				(unsigned long)__builtin_return_address(0));
-	else
-		start_backtrace(&frame, thread_saved_fp(task),
-				thread_saved_pc(task));
-
-	walk_stackframe(task, &frame, consume_entry, cookie);
+	if (regs) {
+		fp = regs->regs[29];
+		pc = regs->pc;
+	} else if (task == current) {
+		/* Skip arch_stack_walk() in the stack trace. */
+		fp = (unsigned long)__builtin_frame_address(1);
+		pc = (unsigned long)__builtin_return_address(0);
+	} else {
+		/* Caller guarantees that the task is not running. */
+		fp = thread_saved_fp(task);
+		pc = thread_saved_pc(task);
+	}
+	unwind(consume_entry, cookie, task, fp, pc);
 }
 
 #endif
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 11:35:57 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 13:35:57 -0500
Subject: [RFC PATCH v7 3/4] arm64: Introduce stack trace reliability checks in
 the unwinder
In-Reply-To: <20210812183559.22693-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812183559.22693-1-madvenka@linux.microsoft.com>
Message-ID: <20210812183559.22693-4-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_is_reliable() that will detect
these cases and return a boolean.

Introduce a new argument to unwind() called "need_reliable" so a caller
can tell unwind() that it requires a reliable stack trace. For such a
caller, any unreliability in the stack trace must be treated as a fatal
error and the unwind must be aborted.

Call unwind_is_reliable() from unwind_consume() like this:

	if (frame->need_reliable && !unwind_is_reliable(frame)) {
		frame->failed = true;
		return false;
	}

In other words, if the return PC in the stackframe falls in unreliable code,
then it cannot be unwound reliably.

arch_stack_walk() will pass "false" for need_reliable because its callers
don't care about reliability. arch_stack_walk() is used for debug and
test purposes.

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except for two things:

	- It passes "true" for need_reliable.

	- It returns -EINVAL if unwind() says that the stack trace is
	  unreliable.

Introduce the first reliability check in unwind_is_reliable() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future. Until all of the
checks are in place, arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  4 ++
 arch/arm64/kernel/stacktrace.c      | 63 +++++++++++++++++++++++++++--
 2 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 407007376e97..65ea151da5da 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -53,6 +53,9 @@ struct stack_info {
  *               replacement lr value in the ftrace graph stack.
  *
  * @failed:      Unwind failed.
+ *
+ * @need_reliable The caller needs a reliable stack trace. Treat any
+ *                unreliability as a fatal error.
  */
 struct stackframe {
 	struct task_struct *task;
@@ -65,6 +68,7 @@ struct stackframe {
 	int graph;
 #endif
 	bool failed;
+	bool need_reliable;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index ec8f5163c4d0..b60f8a20ba64 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -34,7 +34,8 @@
 
 static void notrace unwind_start(struct stackframe *frame,
 				 struct task_struct *task,
-				 unsigned long fp, unsigned long pc)
+				 unsigned long fp, unsigned long pc,
+				 bool need_reliable)
 {
 	frame->task = task;
 	frame->fp = fp;
@@ -56,6 +57,7 @@ static void notrace unwind_start(struct stackframe *frame,
 	frame->prev_fp = 0;
 	frame->prev_type = STACK_TYPE_UNKNOWN;
 	frame->failed = false;
+	frame->need_reliable = need_reliable;
 }
 
 NOKPROBE_SYMBOL(unwind_start);
@@ -178,6 +180,23 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
 	barrier();
 }
 
+/*
+ * Check the stack frame for conditions that make further unwinding unreliable.
+ */
+static bool notrace unwind_is_reliable(struct stackframe *frame)
+{
+	/*
+	 * If the PC is not a known kernel text address, then we cannot
+	 * be sure that a subsequent unwind will be reliable, as we
+	 * don't know that the code follows our unwind requirements.
+	 */
+	if (!__kernel_text_address(frame->pc))
+		return false;
+	return true;
+}
+
+NOKPROBE_SYMBOL(unwind_is_reliable);
+
 static bool notrace unwind_consume(struct stackframe *frame,
 				   stack_trace_consume_fn consume_entry,
 				   void *cookie)
@@ -197,6 +216,12 @@ static bool notrace unwind_consume(struct stackframe *frame,
 		/* Final frame; nothing to unwind */
 		return false;
 	}
+
+	if (frame->need_reliable && !unwind_is_reliable(frame)) {
+		/* Cannot unwind to the next frame reliably. */
+		frame->failed = true;
+		return false;
+	}
 	return true;
 }
 
@@ -210,11 +235,12 @@ static inline bool unwind_failed(struct stackframe *frame)
 /* Core unwind function */
 static bool notrace unwind(stack_trace_consume_fn consume_entry, void *cookie,
 			   struct task_struct *task,
-			   unsigned long fp, unsigned long pc)
+			   unsigned long fp, unsigned long pc,
+			   bool need_reliable)
 {
 	struct stackframe frame;
 
-	unwind_start(&frame, task, fp, pc);
+	unwind_start(&frame, task, fp, pc, need_reliable);
 	while (unwind_consume(&frame, consume_entry, cookie))
 		unwind_next(&frame);
 	return !unwind_failed(&frame);
@@ -245,7 +271,36 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 		fp = thread_saved_fp(task);
 		pc = thread_saved_pc(task);
 	}
-	unwind(consume_entry, cookie, task, fp, pc);
+	unwind(consume_entry, cookie, task, fp, pc, false);
+}
+
+/*
+ * arch_stack_walk_reliable() may not be used for livepatch until all of
+ * the reliability checks are in place in unwind_consume(). However,
+ * debug and test code can choose to use it even if all the checks are not
+ * in place.
+ */
+noinline int notrace arch_stack_walk_reliable(stack_trace_consume_fn consume_fn,
+					      void *cookie,
+					      struct task_struct *task)
+{
+	unsigned long fp, pc;
+
+	if (!task)
+		task = current;
+
+	if (task == current) {
+		/* Skip arch_stack_walk_reliable() in the stack trace. */
+		fp = (unsigned long)__builtin_frame_address(1);
+		pc = (unsigned long)__builtin_return_address(0);
+	} else {
+		/* Caller guarantees that the task is not running. */
+		fp = thread_saved_fp(task);
+		pc = thread_saved_pc(task);
+	}
+	if (unwind(consume_fn, cookie, task, fp, pc, true))
+		return 0;
+	return -EINVAL;
 }
 
 #endif
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 11:35:58 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 13:35:58 -0500
Subject: [RFC PATCH v7 4/4] arm64: Create a list of SYM_CODE functions,
 check return PC against list
In-Reply-To: <20210812183559.22693-1-madvenka@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812183559.22693-1-madvenka@linux.microsoft.com>
Message-ID: <20210812183559.22693-5-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

SYM_CODE functions don't follow the usual calling conventions. Check if the
return PC in a stack frame falls in any of these. If it does, consider the
stack trace unreliable.

Define a special section for unreliable functions
=================================================

Define a SYM_CODE_END() macro for arm64 that adds the function address
range to a new section called "sym_code_functions".

Linker file
===========

Include the "sym_code_functions" section under read-only data in
vmlinux.lds.S.

Initialization
==============

Define an early_initcall() to create a sym_code_functions[] array from
the linker data.

Unwinder check
==============

Add a reliability check in unwind_is_reliable() that compares a return
PC with sym_code_functions[]. If there is a match, then return failure.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/linkage.h  | 12 +++++++
 arch/arm64/include/asm/sections.h |  1 +
 arch/arm64/kernel/stacktrace.c    | 53 +++++++++++++++++++++++++++++++
 arch/arm64/kernel/vmlinux.lds.S   | 10 ++++++
 4 files changed, 76 insertions(+)

diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index 9906541a6861..616bad74e297 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -68,4 +68,16 @@
 		SYM_FUNC_END_ALIAS(x);		\
 		SYM_FUNC_END_ALIAS(__pi_##x)
 
+/*
+ * Record the address range of each SYM_CODE function in a struct code_range
+ * in a special section.
+ */
+#define SYM_CODE_END(name)				\
+	SYM_END(name, SYM_T_NONE)			;\
+	99:						;\
+	.pushsection "sym_code_functions", "aw"		;\
+	.quad	name					;\
+	.quad	99b					;\
+	.popsection
+
 #endif
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
index e4ad9db53af1..c84c71063d6e 100644
--- a/arch/arm64/include/asm/sections.h
+++ b/arch/arm64/include/asm/sections.h
@@ -21,5 +21,6 @@ extern char __exittext_begin[], __exittext_end[];
 extern char __irqentry_text_start[], __irqentry_text_end[];
 extern char __mmuoff_data_start[], __mmuoff_data_end[];
 extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
+extern char __sym_code_functions_start[], __sym_code_functions_end[];
 
 #endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b60f8a20ba64..26dbdd4fff77 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,6 +18,31 @@
 #include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
+struct code_range {
+	unsigned long	start;
+	unsigned long	end;
+};
+
+static struct code_range	*sym_code_functions;
+static int			num_sym_code_functions;
+
+int __init init_sym_code_functions(void)
+{
+	size_t size = (unsigned long)__sym_code_functions_end -
+		      (unsigned long)__sym_code_functions_start;
+
+	sym_code_functions = (struct code_range *)__sym_code_functions_start;
+	/*
+	 * Order it so that sym_code_functions is not visible before
+	 * num_sym_code_functions.
+	 */
+	smp_mb();
+	num_sym_code_functions = size / sizeof(struct code_range);
+
+	return 0;
+}
+early_initcall(init_sym_code_functions);
+
 /*
  * AArch64 PCS assigns the frame pointer to x29.
  *
@@ -185,6 +210,10 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
  */
 static bool notrace unwind_is_reliable(struct stackframe *frame)
 {
+	const struct code_range *range;
+	unsigned long pc;
+	int i;
+
 	/*
 	 * If the PC is not a known kernel text address, then we cannot
 	 * be sure that a subsequent unwind will be reliable, as we
@@ -192,6 +221,30 @@ static bool notrace unwind_is_reliable(struct stackframe *frame)
 	 */
 	if (!__kernel_text_address(frame->pc))
 		return false;
+
+	/*
+	 * Check the return PC against sym_code_functions[]. If there is a
+	 * match, then the consider the stack frame unreliable.
+	 *
+	 * As SYM_CODE functions don't follow the usual calling conventions,
+	 * we assume by default that any SYM_CODE function cannot be unwound
+	 * reliably.
+	 *
+	 * Note that this includes:
+	 *
+	 * - Exception handlers and entry assembly
+	 * - Trampoline assembly (e.g., ftrace, kprobes)
+	 * - Hypervisor-related assembly
+	 * - Hibernation-related assembly
+	 * - CPU start-stop, suspend-resume assembly
+	 * - Kernel relocation assembly
+	 */
+	pc = frame->pc;
+	for (i = 0; i < num_sym_code_functions; i++) {
+		range = &sym_code_functions[i];
+		if (pc >= range->start && pc < range->end)
+			return false;
+	}
 	return true;
 }
 
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 709d2c433c5e..2bf769f45b54 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -111,6 +111,14 @@ jiffies = jiffies_64;
 #define TRAMP_TEXT
 #endif
 
+#define SYM_CODE_FUNCTIONS				\
+	. = ALIGN(16);					\
+	.symcode : AT(ADDR(.symcode) - LOAD_OFFSET) {	\
+		__sym_code_functions_start = .;		\
+		KEEP(*(sym_code_functions))		\
+		__sym_code_functions_end = .;		\
+	}
+
 /*
  * The size of the PE/COFF section that covers the kernel image, which
  * runs from _stext to _edata, must be a round multiple of the PE/COFF
@@ -196,6 +204,8 @@ SECTIONS
 	swapper_pg_dir = .;
 	. += PAGE_SIZE;
 
+	SYM_CODE_FUNCTIONS
+
 	. = ALIGN(SEGMENT_ALIGN);
 	__init_begin = .;
 	__inittext_begin = .;
-- 
2.25.1



From macromorgan at hotmail.com  Thu Aug 12 11:39:31 2021
From: macromorgan at hotmail.com (Chris Morgan)
Date: Thu, 12 Aug 2021 13:39:31 -0500
Subject: [PATCH v13 2/6] spi: rockchip-sfc: add rockchip serial flash
 controller
In-Reply-To: <20210812134546.31340-3-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
 <20210812134546.31340-3-jon.lin@rock-chips.com>
Message-ID: <SN6PR06MB534290CBF30901280C221FBDA5F99@SN6PR06MB5342.namprd06.prod.outlook.com>

On Thu, Aug 12, 2021 at 09:45:42PM +0800, Jon Lin wrote:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Add the rockchip serial flash controller (SFC) driver.
> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> Signed-off-by: Jon Lin <jon.lin at rock-chips.com>

Tested-by: Chris Morgan <macromorgan at hotmail.com>
Successfully tested these changes.

> ---
> 
> Changes in v13:
> - Provide independent interfaces to obtain RX TX FIFO status respectively
> - Add more debug information
> - Depress DMA limitation
> 
> Changes in v12:
> - Remove the limitation of SFC_MIN_SPEED_HZ
> - Add IRQ_NONE method for irq handler
> - Add SPI_MASTER_HALF_DUPLEX flags
> - Add sfc interrupt mask bits and status register initial progress
> 
> Changes in v11: None
> Changes in v10:
> - Fix dma transfer logic
> 
> Changes in v9:
> - Separate DMA IRQ setting and wait_completion from DMA fifo transfer
>   function to make dma_status_poll be possible(Which I will implement
>   in u-boot)
> - Add SFC Kconfig detail comment
> 
> Changes in v8: None
> Changes in v7: None
> Changes in v6: None
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> Changes in v1: None
> 
>  drivers/spi/Kconfig            |  12 +
>  drivers/spi/Makefile           |   1 +
>  drivers/spi/spi-rockchip-sfc.c | 694 +++++++++++++++++++++++++++++++++
>  3 files changed, 707 insertions(+)
>  create mode 100644 drivers/spi/spi-rockchip-sfc.c
> 
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index e71a4c514f7b..83e352b0c8f9 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -658,6 +658,18 @@ config SPI_ROCKCHIP
>  	  The main usecase of this controller is to use spi flash as boot
>  	  device.
>  
> +config SPI_ROCKCHIP_SFC
> +	tristate "Rockchip Serial Flash Controller (SFC)"
> +	depends on ARCH_ROCKCHIP || COMPILE_TEST
> +	depends on HAS_IOMEM && HAS_DMA
> +	help
> +	  This enables support for Rockchip serial flash controller. This
> +	  is a specialized controller used to access SPI flash on some
> +	  Rockchip SOCs.
> +
> +	  ROCKCHIP SFC supports DMA and PIO modes. When DMA is not available,
> +	  the driver automatically falls back to PIO mode.
> +
>  config SPI_RB4XX
>  	tristate "Mikrotik RB4XX SPI master"
>  	depends on SPI_MASTER && ATH79
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 13e54c45e9df..699db95c8441 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -95,6 +95,7 @@ obj-$(CONFIG_SPI_QCOM_GENI)		+= spi-geni-qcom.o
>  obj-$(CONFIG_SPI_QCOM_QSPI)		+= spi-qcom-qspi.o
>  obj-$(CONFIG_SPI_QUP)			+= spi-qup.o
>  obj-$(CONFIG_SPI_ROCKCHIP)		+= spi-rockchip.o
> +obj-$(CONFIG_SPI_ROCKCHIP_SFC)		+= spi-rockchip-sfc.o
>  obj-$(CONFIG_SPI_RB4XX)			+= spi-rb4xx.o
>  obj-$(CONFIG_MACH_REALTEK_RTL)		+= spi-realtek-rtl.o
>  obj-$(CONFIG_SPI_RPCIF)			+= spi-rpc-if.o
> diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
> new file mode 100644
> index 000000000000..7c4d47fe80c2
> --- /dev/null
> +++ b/drivers/spi/spi-rockchip-sfc.c
> @@ -0,0 +1,694 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Rockchip Serial Flash Controller Driver
> + *
> + * Copyright (c) 2017-2021, Rockchip Inc.
> + * Author: Shawn Lin <shawn.lin at rock-chips.com>
> + *	   Chris Morgan <macroalpha82 at gmail.com>
> + *	   Jon Lin <Jon.lin at rock-chips.com>
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/completion.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/iopoll.h>
> +#include <linux/mm.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/interrupt.h>
> +#include <linux/spi/spi-mem.h>
> +
> +/* System control */
> +#define SFC_CTRL			0x0
> +#define  SFC_CTRL_PHASE_SEL_NEGETIVE	BIT(1)
> +#define  SFC_CTRL_CMD_BITS_SHIFT	8
> +#define  SFC_CTRL_ADDR_BITS_SHIFT	10
> +#define  SFC_CTRL_DATA_BITS_SHIFT	12
> +
> +/* Interrupt mask */
> +#define SFC_IMR				0x4
> +#define  SFC_IMR_RX_FULL		BIT(0)
> +#define  SFC_IMR_RX_UFLOW		BIT(1)
> +#define  SFC_IMR_TX_OFLOW		BIT(2)
> +#define  SFC_IMR_TX_EMPTY		BIT(3)
> +#define  SFC_IMR_TRAN_FINISH		BIT(4)
> +#define  SFC_IMR_BUS_ERR		BIT(5)
> +#define  SFC_IMR_NSPI_ERR		BIT(6)
> +#define  SFC_IMR_DMA			BIT(7)
> +
> +/* Interrupt clear */
> +#define SFC_ICLR			0x8
> +#define  SFC_ICLR_RX_FULL		BIT(0)
> +#define  SFC_ICLR_RX_UFLOW		BIT(1)
> +#define  SFC_ICLR_TX_OFLOW		BIT(2)
> +#define  SFC_ICLR_TX_EMPTY		BIT(3)
> +#define  SFC_ICLR_TRAN_FINISH		BIT(4)
> +#define  SFC_ICLR_BUS_ERR		BIT(5)
> +#define  SFC_ICLR_NSPI_ERR		BIT(6)
> +#define  SFC_ICLR_DMA			BIT(7)
> +
> +/* FIFO threshold level */
> +#define SFC_FTLR			0xc
> +#define  SFC_FTLR_TX_SHIFT		0
> +#define  SFC_FTLR_TX_MASK		0x1f
> +#define  SFC_FTLR_RX_SHIFT		8
> +#define  SFC_FTLR_RX_MASK		0x1f
> +
> +/* Reset FSM and FIFO */
> +#define SFC_RCVR			0x10
> +#define  SFC_RCVR_RESET			BIT(0)
> +
> +/* Enhanced mode */
> +#define SFC_AX				0x14
> +
> +/* Address Bit number */
> +#define SFC_ABIT			0x18
> +
> +/* Interrupt status */
> +#define SFC_ISR				0x1c
> +#define  SFC_ISR_RX_FULL_SHIFT		BIT(0)
> +#define  SFC_ISR_RX_UFLOW_SHIFT		BIT(1)
> +#define  SFC_ISR_TX_OFLOW_SHIFT		BIT(2)
> +#define  SFC_ISR_TX_EMPTY_SHIFT		BIT(3)
> +#define  SFC_ISR_TX_FINISH_SHIFT	BIT(4)
> +#define  SFC_ISR_BUS_ERR_SHIFT		BIT(5)
> +#define  SFC_ISR_NSPI_ERR_SHIFT		BIT(6)
> +#define  SFC_ISR_DMA_SHIFT		BIT(7)
> +
> +/* FIFO status */
> +#define SFC_FSR				0x20
> +#define  SFC_FSR_TX_IS_FULL		BIT(0)
> +#define  SFC_FSR_TX_IS_EMPTY		BIT(1)
> +#define  SFC_FSR_RX_IS_EMPTY		BIT(2)
> +#define  SFC_FSR_RX_IS_FULL		BIT(3)
> +#define  SFC_FSR_TXLV_MASK		GENMASK(12, 8)
> +#define  SFC_FSR_TXLV_SHIFT		8
> +#define  SFC_FSR_RXLV_MASK		GENMASK(20, 16)
> +#define  SFC_FSR_RXLV_SHIFT		16
> +
> +/* FSM status */
> +#define SFC_SR				0x24
> +#define  SFC_SR_IS_IDLE			0x0
> +#define  SFC_SR_IS_BUSY			0x1
> +
> +/* Raw interrupt status */
> +#define SFC_RISR			0x28
> +#define  SFC_RISR_RX_FULL		BIT(0)
> +#define  SFC_RISR_RX_UNDERFLOW		BIT(1)
> +#define  SFC_RISR_TX_OVERFLOW		BIT(2)
> +#define  SFC_RISR_TX_EMPTY		BIT(3)
> +#define  SFC_RISR_TRAN_FINISH		BIT(4)
> +#define  SFC_RISR_BUS_ERR		BIT(5)
> +#define  SFC_RISR_NSPI_ERR		BIT(6)
> +#define  SFC_RISR_DMA			BIT(7)
> +
> +/* Version */
> +#define SFC_VER				0x2C
> +#define  SFC_VER_3			0x3
> +#define  SFC_VER_4			0x4
> +#define  SFC_VER_5			0x5
> +
> +/* Delay line controller resiter */
> +#define SFC_DLL_CTRL0			0x3C
> +#define SFC_DLL_CTRL0_SCLK_SMP_DLL	BIT(15)
> +#define SFC_DLL_CTRL0_DLL_MAX_VER4	0xFFU
> +#define SFC_DLL_CTRL0_DLL_MAX_VER5	0x1FFU
> +
> +/* Master trigger */
> +#define SFC_DMA_TRIGGER			0x80
> +#define SFC_DMA_TRIGGER_START		1
> +
> +/* Src or Dst addr for master */
> +#define SFC_DMA_ADDR			0x84
> +
> +/* Length control register extension 32GB */
> +#define SFC_LEN_CTRL			0x88
> +#define SFC_LEN_CTRL_TRB_SEL		1
> +#define SFC_LEN_EXT			0x8C
> +
> +/* Command */
> +#define SFC_CMD				0x100
> +#define  SFC_CMD_IDX_SHIFT		0
> +#define  SFC_CMD_DUMMY_SHIFT		8
> +#define  SFC_CMD_DIR_SHIFT		12
> +#define  SFC_CMD_DIR_RD			0
> +#define  SFC_CMD_DIR_WR			1
> +#define  SFC_CMD_ADDR_SHIFT		14
> +#define  SFC_CMD_ADDR_0BITS		0
> +#define  SFC_CMD_ADDR_24BITS		1
> +#define  SFC_CMD_ADDR_32BITS		2
> +#define  SFC_CMD_ADDR_XBITS		3
> +#define  SFC_CMD_TRAN_BYTES_SHIFT	16
> +#define  SFC_CMD_CS_SHIFT		30
> +
> +/* Address */
> +#define SFC_ADDR			0x104
> +
> +/* Data */
> +#define SFC_DATA			0x108
> +
> +/* The controller and documentation reports that it supports up to 4 CS
> + * devices (0-3), however I have only been able to test a single CS (CS 0)
> + * due to the configuration of my device.
> + */
> +#define SFC_MAX_CHIPSELECT_NUM		4
> +
> +/* The SFC can transfer max 16KB - 1 at one time
> + * we set it to 15.5KB here for alignment.
> + */
> +#define SFC_MAX_IOSIZE_VER3		(512 * 31)
> +
> +/* DMA is only enabled for large data transmission */
> +#define SFC_DMA_TRANS_THRETHOLD		(0x40)
> +
> +/* Maximum clock values from datasheet suggest keeping clock value under
> + * 150MHz. No minimum or average value is suggested.
> + */
> +#define SFC_MAX_SPEED		(150 * 1000 * 1000)
> +
> +struct rockchip_sfc {
> +	struct device *dev;
> +	void __iomem *regbase;
> +	struct clk *hclk;
> +	struct clk *clk;
> +	u32 frequency;
> +	/* virtual mapped addr for dma_buffer */
> +	void *buffer;
> +	dma_addr_t dma_buffer;
> +	struct completion cp;
> +	bool use_dma;
> +	u32 max_iosize;
> +	u16 version;
> +};
> +
> +static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
> +{
> +	int err;
> +	u32 status;
> +
> +	writel_relaxed(SFC_RCVR_RESET, sfc->regbase + SFC_RCVR);
> +
> +	err = readl_poll_timeout(sfc->regbase + SFC_RCVR, status,
> +				 !(status & SFC_RCVR_RESET), 20,
> +				 jiffies_to_usecs(HZ));
> +	if (err)
> +		dev_err(sfc->dev, "SFC reset never finished\n");
> +
> +	/* Still need to clear the masked interrupt from RISR */
> +	writel_relaxed(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
> +
> +	dev_dbg(sfc->dev, "reset\n");
> +
> +	return err;
> +}
> +
> +static u16 rockchip_sfc_get_version(struct rockchip_sfc *sfc)
> +{
> +	return  (u16)(readl(sfc->regbase + SFC_VER) & 0xffff);
> +}
> +
> +static u32 rockchip_sfc_get_max_iosize(struct rockchip_sfc *sfc)
> +{
> +	return SFC_MAX_IOSIZE_VER3;
> +}
> +
> +static void rockchip_sfc_irq_unmask(struct rockchip_sfc *sfc, u32 mask)
> +{
> +	u32 reg;
> +
> +	/* Enable transfer complete interrupt */
> +	reg = readl(sfc->regbase + SFC_IMR);
> +	reg &= ~mask;
> +	writel(reg, sfc->regbase + SFC_IMR);
> +}
> +
> +static void rockchip_sfc_irq_mask(struct rockchip_sfc *sfc, u32 mask)
> +{
> +	u32 reg;
> +
> +	/* Disable transfer finish interrupt */
> +	reg = readl(sfc->regbase + SFC_IMR);
> +	reg |= mask;
> +	writel(reg, sfc->regbase + SFC_IMR);
> +}
> +
> +static int rockchip_sfc_init(struct rockchip_sfc *sfc)
> +{
> +	writel(0, sfc->regbase + SFC_CTRL);
> +	writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
> +	rockchip_sfc_irq_mask(sfc, 0xFFFFFFFF);
> +	if (rockchip_sfc_get_version(sfc) >= SFC_VER_4)
> +		writel(SFC_LEN_CTRL_TRB_SEL, sfc->regbase + SFC_LEN_CTRL);
> +
> +	return 0;
> +}
> +
> +static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
> +{
> +	int ret = 0;
> +	u32 status;
> +
> +	ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
> +				 status & SFC_FSR_TXLV_MASK, 0,
> +				 timeout_us);
> +	if (ret) {
> +		dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
> +
> +		ret = -ETIMEDOUT;
> +	}
> +
> +	return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
> +}
> +
> +static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
> +{
> +	int ret = 0;
> +	u32 status;
> +
> +	ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
> +				 status & SFC_FSR_RXLV_MASK, 0,
> +				 timeout_us);
> +	if (ret) {
> +		dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n");
> +
> +		ret = -ETIMEDOUT;
> +	}
> +
> +	return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
> +}
> +
> +static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op)
> +{
> +	if (unlikely(op->dummy.nbytes && !op->addr.nbytes)) {
> +		/*
> +		 * SFC not support output DUMMY cycles right after CMD cycles, so
> +		 * treat it as ADDR cycles.
> +		 */
> +		op->addr.nbytes = op->dummy.nbytes;
> +		op->addr.buswidth = op->dummy.buswidth;
> +		op->addr.val = 0xFFFFFFFFF;
> +
> +		op->dummy.nbytes = 0;
> +	}
> +}
> +
> +static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
> +				   struct spi_mem *mem,
> +				   const struct spi_mem_op *op,
> +				   u32 len)
> +{
> +	u32 ctrl = 0, cmd = 0;
> +
> +	/* set CMD */
> +	cmd = op->cmd.opcode;
> +	ctrl |= ((op->cmd.buswidth >> 1) << SFC_CTRL_CMD_BITS_SHIFT);
> +
> +	/* set ADDR */
> +	if (op->addr.nbytes) {
> +		if (op->addr.nbytes == 4) {
> +			cmd |= SFC_CMD_ADDR_32BITS << SFC_CMD_ADDR_SHIFT;
> +		} else if (op->addr.nbytes == 3) {
> +			cmd |= SFC_CMD_ADDR_24BITS << SFC_CMD_ADDR_SHIFT;
> +		} else {
> +			cmd |= SFC_CMD_ADDR_XBITS << SFC_CMD_ADDR_SHIFT;
> +			writel(op->addr.nbytes * 8 - 1, sfc->regbase + SFC_ABIT);
> +		}
> +
> +		ctrl |= ((op->addr.buswidth >> 1) << SFC_CTRL_ADDR_BITS_SHIFT);
> +	}
> +
> +	/* set DUMMY */
> +	if (op->dummy.nbytes) {
> +		if (op->dummy.buswidth == 4)
> +			cmd |= op->dummy.nbytes * 2 << SFC_CMD_DUMMY_SHIFT;
> +		else if (op->dummy.buswidth == 2)
> +			cmd |= op->dummy.nbytes * 4 << SFC_CMD_DUMMY_SHIFT;
> +		else
> +			cmd |= op->dummy.nbytes * 8 << SFC_CMD_DUMMY_SHIFT;
> +	}
> +
> +	/* set DATA */
> +	if (sfc->version >= SFC_VER_4) /* Clear it if no data to transfer */
> +		writel(len, sfc->regbase + SFC_LEN_EXT);
> +	else
> +		cmd |= len << SFC_CMD_TRAN_BYTES_SHIFT;
> +	if (len) {
> +		if (op->data.dir == SPI_MEM_DATA_OUT)
> +			cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT;
> +
> +		ctrl |= ((op->data.buswidth >> 1) << SFC_CTRL_DATA_BITS_SHIFT);
> +	}
> +	if (!len && op->addr.nbytes)
> +		cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT;
> +
> +	/* set the Controller */
> +	ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
> +	cmd |= mem->spi->chip_select << SFC_CMD_CS_SHIFT;
> +
> +	dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
> +		op->addr.nbytes, op->addr.buswidth,
> +		op->dummy.nbytes, op->dummy.buswidth);
> +	dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
> +		ctrl, cmd, op->addr.val, len);
> +
> +	writel(ctrl, sfc->regbase + SFC_CTRL);
> +	writel(cmd, sfc->regbase + SFC_CMD);
> +	if (op->addr.nbytes)
> +		writel(op->addr.val, sfc->regbase + SFC_ADDR);
> +
> +	return 0;
> +}
> +
> +static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int len)
> +{
> +	u8 bytes = len & 0x3;
> +	u32 dwords;
> +	int tx_level;
> +	u32 write_words;
> +	u32 tmp = 0;
> +
> +	dwords = len >> 2;
> +	while (dwords) {
> +		tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
> +		if (tx_level < 0)
> +			return tx_level;
> +		write_words = min_t(u32, tx_level, dwords);
> +		iowrite32_rep(sfc->regbase + SFC_DATA, buf, write_words);
> +		buf += write_words << 2;
> +		dwords -= write_words;
> +	}
> +
> +	/* write the rest non word aligned bytes */
> +	if (bytes) {
> +		tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
> +		if (tx_level < 0)
> +			return tx_level;
> +		memcpy(&tmp, buf, bytes);
> +		writel(tmp, sfc->regbase + SFC_DATA);
> +	}
> +
> +	return len;
> +}
> +
> +static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
> +{
> +	u8 bytes = len & 0x3;
> +	u32 dwords;
> +	u8 read_words;
> +	int rx_level;
> +	int tmp;
> +
> +	/* word aligned access only */
> +	dwords = len >> 2;
> +	while (dwords) {
> +		rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
> +		if (rx_level < 0)
> +			return rx_level;
> +		read_words = min_t(u32, rx_level, dwords);
> +		ioread32_rep(sfc->regbase + SFC_DATA, buf, read_words);
> +		buf += read_words << 2;
> +		dwords -= read_words;
> +	}
> +
> +	/* read the rest non word aligned bytes */
> +	if (bytes) {
> +		rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
> +		if (rx_level < 0)
> +			return rx_level;
> +		tmp = readl(sfc->regbase + SFC_DATA);
> +		memcpy(buf, &tmp, bytes);
> +	}
> +
> +	return len;
> +}
> +
> +static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t dma_buf, size_t len)
> +{
> +	writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
> +	writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR);
> +	writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER);
> +
> +	return len;
> +}
> +
> +static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,
> +				       const struct spi_mem_op *op, u32 len)
> +{
> +	dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len);
> +
> +	if (op->data.dir == SPI_MEM_DATA_OUT)
> +		return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len);
> +	else
> +		return rockchip_sfc_read_fifo(sfc, op->data.buf.in, len);
> +}
> +
> +static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
> +				      const struct spi_mem_op *op, u32 len)
> +{
> +	int ret;
> +
> +	dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
> +
> +	if (op->data.dir == SPI_MEM_DATA_OUT)
> +		memcpy_toio(sfc->buffer, op->data.buf.out, len);
> +
> +	ret = rockchip_sfc_fifo_transfer_dma(sfc, sfc->dma_buffer, len);
> +	if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) {
> +		dev_err(sfc->dev, "DMA wait for transfer finish timeout\n");
> +		ret = -ETIMEDOUT;
> +	}
> +	rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA);
> +	if (op->data.dir == SPI_MEM_DATA_IN)
> +		memcpy_fromio(op->data.buf.in, sfc->buffer, len);
> +
> +	return ret;
> +}
> +
> +static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
> +{
> +	int ret = 0;
> +	u32 status;
> +
> +	ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
> +				 !(status & SFC_SR_IS_BUSY),
> +				 20, timeout_us);
> +	if (ret) {
> +		dev_err(sfc->dev, "wait sfc idle timeout\n");
> +		rockchip_sfc_reset(sfc);
> +
> +		ret = -EIO;
> +	}
> +
> +	return ret;
> +}
> +
> +static int rockchip_sfc_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
> +{
> +	struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master);
> +	u32 len = op->data.nbytes;
> +	int ret;
> +
> +	if (unlikely(mem->spi->max_speed_hz != sfc->frequency)) {
> +		ret = clk_set_rate(sfc->clk, mem->spi->max_speed_hz);
> +		if (ret)
> +			return ret;
> +		sfc->frequency = mem->spi->max_speed_hz;
> +		dev_dbg(sfc->dev, "set_freq=%dHz real_freq=%ldHz\n",
> +			sfc->frequency, clk_get_rate(sfc->clk));
> +	}
> +
> +	rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
> +	rockchip_sfc_xfer_setup(sfc, mem, op, len);
> +	if (len) {
> +		if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD) {
> +			init_completion(&sfc->cp);
> +			rockchip_sfc_irq_unmask(sfc, SFC_IMR_DMA);
> +			ret = rockchip_sfc_xfer_data_dma(sfc, op, len);
> +		} else {
> +			ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
> +		}
> +
> +		if (ret != len) {
> +			dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);
> +
> +			return -EIO;
> +		}
> +	}
> +
> +	return rockchip_sfc_xfer_done(sfc, 100000);
> +}
> +
> +static int rockchip_sfc_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
> +{
> +	struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master);
> +
> +	op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
> +
> +	return 0;
> +}
> +
> +static const struct spi_controller_mem_ops rockchip_sfc_mem_ops = {
> +	.exec_op = rockchip_sfc_exec_mem_op,
> +	.adjust_op_size = rockchip_sfc_adjust_op_size,
> +};
> +
> +static irqreturn_t rockchip_sfc_irq_handler(int irq, void *dev_id)
> +{
> +	struct rockchip_sfc *sfc = dev_id;
> +	u32 reg;
> +
> +	reg = readl(sfc->regbase + SFC_RISR);
> +
> +	/* Clear interrupt */
> +	writel_relaxed(reg, sfc->regbase + SFC_ICLR);
> +
> +	if (reg & SFC_RISR_DMA) {
> +		complete(&sfc->cp);
> +
> +		return IRQ_HANDLED;
> +	}
> +
> +	return IRQ_NONE;
> +}
> +
> +static int rockchip_sfc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct spi_master *master;
> +	struct resource *res;
> +	struct rockchip_sfc *sfc;
> +	int ret;
> +
> +	master = devm_spi_alloc_master(&pdev->dev, sizeof(*sfc));
> +	if (!master)
> +		return -ENOMEM;
> +
> +	master->flags = SPI_MASTER_HALF_DUPLEX;
> +	master->mem_ops = &rockchip_sfc_mem_ops;
> +	master->dev.of_node = pdev->dev.of_node;
> +	master->mode_bits = SPI_TX_QUAD | SPI_TX_DUAL | SPI_RX_QUAD | SPI_RX_DUAL;
> +	master->max_speed_hz = SFC_MAX_SPEED;
> +	master->num_chipselect = SFC_MAX_CHIPSELECT_NUM;
> +
> +	sfc = spi_master_get_devdata(master);
> +	sfc->dev = dev;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	sfc->regbase = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(sfc->regbase))
> +		return PTR_ERR(sfc->regbase);
> +
> +	sfc->clk = devm_clk_get(&pdev->dev, "clk_sfc");
> +	if (IS_ERR(sfc->clk)) {
> +		dev_err(&pdev->dev, "Failed to get sfc interface clk\n");
> +		return PTR_ERR(sfc->clk);
> +	}
> +
> +	sfc->hclk = devm_clk_get(&pdev->dev, "hclk_sfc");
> +	if (IS_ERR(sfc->hclk)) {
> +		dev_err(&pdev->dev, "Failed to get sfc ahb clk\n");
> +		return PTR_ERR(sfc->hclk);
> +	}
> +
> +	sfc->use_dma = !of_property_read_bool(sfc->dev->of_node,
> +					      "rockchip,sfc-no-dma");
> +
> +	if (sfc->use_dma) {
> +		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
> +		if (ret) {
> +			dev_warn(dev, "Unable to set dma mask\n");
> +			return ret;
> +		}
> +
> +		sfc->buffer = dmam_alloc_coherent(dev, SFC_MAX_IOSIZE_VER3,
> +						  &sfc->dma_buffer,
> +						  GFP_KERNEL);
> +		if (!sfc->buffer)
> +			return -ENOMEM;
> +	}
> +
> +	ret = clk_prepare_enable(sfc->hclk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to enable ahb clk\n");
> +		goto err_hclk;
> +	}
> +
> +	ret = clk_prepare_enable(sfc->clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to enable interface clk\n");
> +		goto err_clk;
> +	}
> +
> +	/* Find the irq */
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to get the irq\n");
> +		goto err_irq;
> +	}
> +
> +	ret = devm_request_irq(dev, ret, rockchip_sfc_irq_handler,
> +			       0, pdev->name, sfc);
> +	if (ret) {
> +		dev_err(dev, "Failed to request irq\n");
> +
> +		return ret;
> +	}
> +
> +	ret = rockchip_sfc_init(sfc);
> +	if (ret)
> +		goto err_irq;
> +
> +	sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
> +	sfc->version = rockchip_sfc_get_version(sfc);
> +
> +	ret = spi_register_master(master);
> +	if (ret)
> +		goto err_irq;
> +
> +	return 0;
> +
> +err_irq:
> +	clk_disable_unprepare(sfc->clk);
> +err_clk:
> +	clk_disable_unprepare(sfc->hclk);
> +err_hclk:
> +	return ret;
> +}
> +
> +static int rockchip_sfc_remove(struct platform_device *pdev)
> +{
> +	struct spi_master *master = platform_get_drvdata(pdev);
> +	struct rockchip_sfc *sfc = platform_get_drvdata(pdev);
> +
> +	spi_unregister_master(master);
> +
> +	clk_disable_unprepare(sfc->clk);
> +	clk_disable_unprepare(sfc->hclk);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id rockchip_sfc_dt_ids[] = {
> +	{ .compatible = "rockchip,sfc"},
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, rockchip_sfc_dt_ids);
> +
> +static struct platform_driver rockchip_sfc_driver = {
> +	.driver = {
> +		.name	= "rockchip-sfc",
> +		.of_match_table = rockchip_sfc_dt_ids,
> +	},
> +	.probe	= rockchip_sfc_probe,
> +	.remove	= rockchip_sfc_remove,
> +};
> +module_platform_driver(rockchip_sfc_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("Rockchip Serial Flash Controller Driver");
> +MODULE_AUTHOR("Shawn Lin <shawn.lin at rock-chips.com>");
> +MODULE_AUTHOR("Chris Morgan <macromorgan at hotmail.com>");
> +MODULE_AUTHOR("Jon Lin <Jon.lin at rock-chips.com>");
> -- 
> 2.17.1
> 
> 
> 


From madvenka at linux.microsoft.com  Thu Aug 12 11:45:22 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Thu, 12 Aug 2021 13:45:22 -0500
Subject: [RFC PATCH v7 0/4] arm64: Reorganize the unwinder and implement
 stack trace reliability checks
In-Reply-To: <3a71bd4a-dc3c-eb66-6555-2f96877499f4@linux.microsoft.com>
References: <3f2aab69a35c243c5e97f47c4ad84046355f5b90>
 <20210812132435.6143-1-madvenka@linux.microsoft.com>
 <3a71bd4a-dc3c-eb66-6555-2f96877499f4@linux.microsoft.com>
Message-ID: <f3e313cc-57d3-bac1-f4a6-d953c3a026b4@linux.microsoft.com>

My mailer is screwing up.

I will resend the whole series as version 8 instead of version 7 to avoid further
confusion.

Thunderbird, sometimes! Again, I am so sorry.

Madhavan

On 8/12/21 1:31 PM, Madhavan T. Venkataraman wrote:
> The messages are not threaded properly.
> 
> I will resend the whole series with proper threading.
> 
> I apologize.
> 
> Madhavan
> 
> On 8/12/21 8:24 AM, madvenka at linux.microsoft.com wrote:
>> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
>>
>> Make all stack walking functions use arch_stack_walk()
>> ======================================================
>>
>> Currently, there are multiple functions in ARM64 code that walk the
>> stack using start_backtrace() and unwind_frame(). Convert all of
>> them to use arch_stack_walk(). This makes maintenance easier.
>>
>> Reorganize the unwinder code for better consistency and maintenance
>> ===================================================================
>>
>> Rename unwinder functions to unwind_*() similar to other architectures
>> for naming consistency.
>>
>> Annotate all of the unwind_*() functions with notrace so they cannot be
>> ftraced and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe
>> code can call the unwinder.
>>
>> Redefine the unwinder loop and make it similar to other architectures.
>> Define the following:
>>
>> 	unwind_start(&frame, task, fp, pc);
>> 	while (unwind_consume(&frame, consume_entry, cookie))
>> 		unwind_next(&frame);
>> 	return !unwind_failed(&frame);
>>
>> unwind_start()
>> 	Same as the original start_backtrace().
>>
>> unwind_consume()
>> 	This new function does two things:
>>
>> 	- Calls consume_entry() to consume the return PC.
>>
>> 	- Implements checks to determine whether the unwind should continue
>> 	  or terminate.
>>
>> unwind_next()
>> 	Same as the original unwind_frame() except:
>>
>> 	- the stack trace termination check has been moved from here to
>> 	  unwind_consume(). So, unwind_next() assumes that the fp is valid.
>>
>> 	- unwind_frame() used to return an error value. This function only
>> 	  sets internal state and does not return anything. The state is
>> 	  retrieved via a helper. See next.
>>
>> unwind_failed()
>> 	Return a boolean to indicate whether the stack trace completed
>> 	successfully or failed. arch_stack_walk() ignores the return
>> 	value. But arch_stack_walk_reliable() in the future will look
>> 	at the return value.
>>
>> Unwind status
>> 	Introduce a new flag called "failed" in struct stackframe. Set this
>> 	flag when an error is encountered. If this flag is set, terminate
>> 	the unwind. Also, let the unwinder return the status to the caller.
>>
>> Reliability checks
>> ==================
>>
>> There are some kernel features and conditions that make a stack trace
>> unreliable. Callers may require the unwinder to detect these cases.
>> E.g., livepatch.
>>
>> Introduce a new function called unwind_is_reliable() that will detect
>> these cases and return a boolean.
>>
>> Introduce a new argument to unwind() called "need_reliable" so a caller
>> can tell unwind() that it requires a reliable stack trace. For such a
>> caller, any unreliability in the stack trace must be treated as a fatal
>> error and the unwind must be aborted.
>>
>> Call unwind_is_reliable() from unwind_consume() like this:
>>
>> 	if (frame->need_reliable && !unwind_is_reliable(frame)) {
>> 		frame->failed = true;
>> 		return false;
>> 	}
>>
>> arch_stack_walk() passes "false" for need_reliable because its callers
>> don't care about reliability. arch_stack_walk() is used for debug and
>> test purposes.
>>
>> Introduce arch_stack_walk_reliable() for ARM64. This works like
>> arch_stack_walk() except for two things:
>>
>> 	- It passes "true" for need_reliable.
>>
>> 	- It returns -EINVAL if unwind() aborts.
>>
>> Introduce the first reliability check in unwind_is_reliable() - If
>> a return PC is not a valid kernel text address, consider the stack
>> trace unreliable. It could be some generated code.
>>
>> Other reliability checks will be added in the future. Until all of the
>> checks are in place, arch_stack_walk_reliable() may not be used by
>> livepatch. But it may be used by debug and test code.
>>
>> SYM_CODE check
>> ==============
>>
>> SYM_CODE functions do not follow normal calling conventions. They cannot
>> be unwound reliably using the frame pointer. Collect the address ranges
>> of these functions in a special section called "sym_code_functions".
>>
>> In unwind_is_reliable(), check the return PC against these ranges. If a
>> match is found, then consider the stack trace unreliable. This is the
>> second reliability check introduced by this work.
>>
>> Last stack frame
>> ----------------
>>
>> If a SYM_CODE function occurs in the very last frame in the stack trace,
>> then the stack trace is not considered unreliable. This is because there
>> is no more unwinding to do. Examples:
>>
>> 	- EL0 exception stack traces end in the top level EL0 exception
>> 	  handlers.
>>
>> 	- All kernel thread stack traces end in ret_from_fork().
>> ---
>> Changelog:
>>
>> v7:
>> 	From Mark Rutland:
>>
>> 	- Make the unwinder loop similar to other architectures.
>>
>> 	- Keep details to within the unwinder functions and return a simple
>> 	  boolean to the caller.
>>
>> 	- Convert some of the current code that contains unwinder logic to
>> 	  simply use arch_stack_walk(). I have converted all of them.
>>
>> 	- Do not copy sym_code_functions[]. Just place it in rodata for now.
>>
>> 	- Have the main loop check for termination conditions rather than
>> 	  having unwind_frame() check for them. In other words, let
>> 	  unwind_frame() assume that the fp is valid.
>>
>> 	- Replace the big comment for SYM_CODE functions with a shorter
>> 	  comment.
>>
>> 		/*
>> 		 * As SYM_CODE functions don't follow the usual calling
>> 		 * conventions, we assume by default that any SYM_CODE function
>> 		 * cannot be unwound reliably.
>> 		 *
>> 		 * Note that this includes:
>> 		 *
>> 		 * - Exception handlers and entry assembly
>> 		 * - Trampoline assembly (e.g., ftrace, kprobes)
>> 		 * - Hypervisor-related assembly
>> 		 * - Hibernation-related assembly
>> 		 * - CPU start-stop, suspend-resume assembly
>> 		 * - Kernel relocation assembly
>> 		 */
>>
>> v6:
>> 	From Mark Rutland:
>>
>> 	- The per-frame reliability concept and flag are acceptable. But more
>> 	  work is needed to make the per-frame checks more accurate and more
>> 	  complete. E.g., some code reorg is being worked on that will help.
>>
>> 	  I have now removed the frame->reliable flag and deleted the whole
>> 	  concept of per-frame status. This is orthogonal to this patch series.
>> 	  Instead, I have improved the unwinder to return proper return codes
>> 	  so a caller can take appropriate action without needing per-frame
>> 	  status.
>>
>> 	- Remove the mention of PLTs and update the comment.
>>
>> 	  I have replaced the comment above the call to __kernel_text_address()
>> 	  with the comment suggested by Mark Rutland.
>>
>> 	Other comments:
>>
>> 	- Other comments on the per-frame stuff are not relevant because
>> 	  that approach is not there anymore.
>>
>> v5:
>> 	From Keiya Nobuta:
>> 	
>> 	- The term blacklist(ed) is not to be used anymore. I have changed it
>> 	  to unreliable. So, the function unwinder_blacklisted() has been
>> 	  changed to unwinder_is_unreliable().
>>
>> 	From Mark Brown:
>>
>> 	- Add a comment for the "reliable" flag in struct stackframe. The
>> 	  reliability attribute is not complete until all the checks are
>> 	  in place. Added a comment above struct stackframe.
>>
>> 	- Include some of the comments in the cover letter in the actual
>> 	  code so that we can compare it with the reliable stack trace
>> 	  requirements document for completeness. I have added a comment:
>>
>> 	  	- above unwinder_is_unreliable() that lists the requirements
>> 		  that are addressed by the function.
>>
>> 		- above the __kernel_text_address() call about all the cases
>> 		  the call covers.
>>
>> v4:
>> 	From Mark Brown:
>>
>> 	- I was checking the return PC with __kernel_text_address() before
>> 	  the Function Graph trace handling. Mark Brown felt that all the
>> 	  reliability checks should be performed on the original return PC
>> 	  once that is obtained. So, I have moved all the reliability checks
>> 	  to after the Function Graph Trace handling code in the unwinder.
>> 	  Basically, the unwinder should perform PC translations first (for
>> 	  rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
>> 	  Then, the reliability checks should be applied to the resulting
>> 	  PC.
>>
>> 	- Mark said to improve the naming of the new functions so they don't
>> 	  collide with existing ones. I have used a prefix "unwinder_" for
>> 	  all the new functions.
>>
>> 	From Josh Poimboeuf:
>>
>> 	- In the error scenarios in the unwinder, the reliable flag in the
>> 	  stack frame should be set. Implemented this.
>>
>> 	- Some of the other comments are not relevant to the new code as
>> 	  I have taken a different approach in the new code. That is why
>> 	  I have not made those changes. E.g., Ard wanted me to add the
>> 	  "const" keyword to the global section array. That array does not
>> 	  exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
>> 	  the same array in a for loop.
>>
>> 	Other changes:
>>
>> 	- Add a new definition for SYM_CODE_END() that adds the address
>> 	  range of the function to a special section called
>> 	  "sym_code_functions".
>>
>> 	- Include the new section under initdata in vmlinux.lds.S.
>>
>> 	- Define an early_initcall() to copy the contents of the
>> 	  "sym_code_functions" section to an array by the same name.
>>
>> 	- Define a function unwinder_blacklisted() that compares a return
>> 	  PC against sym_code_sections[]. If there is a match, mark the
>> 	  stack trace unreliable. Call this from unwind_frame().
>>
>> v3:
>> 	- Implemented a sym_code_ranges[] array to contains sections bounds
>> 	  for text sections that contain SYM_CODE_*() functions. The unwinder
>> 	  checks each return PC against the sections. If it falls in any of
>> 	  the sections, the stack trace is marked unreliable.
>>
>> 	- Moved SYM_CODE functions from .text and .init.text into a new
>> 	  text section called ".code.text". Added this section to
>> 	  vmlinux.lds.S and sym_code_ranges[].
>>
>> 	- Fixed the logic in the unwinder that handles Function Graph
>> 	  Tracer return trampoline.
>>
>> 	- Removed all the previous code that handles:
>> 		- ftrace entry code for traced function
>> 		- special_functions[] array that lists individual functions
>> 		- kretprobe_trampoline() special case
>>
>> v2
>> 	- Removed the terminating entry { 0, 0 } in special_functions[]
>> 	  and replaced it with the idiom { /* sentinel */ }.
>>
>> 	- Change the ftrace trampoline entry ftrace_graph_call in
>> 	  special_functions[] to ftrace_call + 4 and added explanatory
>> 	  comments.
>>
>> 	- Unnested #ifdefs in special_functions[] for FTRACE.
>>
>> v1
>> 	- Define a bool field in struct stackframe. This will indicate if
>> 	  a stack trace is reliable.
>>
>> 	- Implement a special_functions[] array that will be populated
>> 	  with special functions in which the stack trace is considered
>> 	  unreliable.
>> 	
>> 	- Using kallsyms_lookup(), get the address ranges for the special
>> 	  functions and record them.
>>
>> 	- Implement an is_reliable_function(pc). This function will check
>> 	  if a given return PC falls in any of the special functions. If
>> 	  it does, the stack trace is unreliable.
>>
>> 	- Implement check_reliability() function that will check if a
>> 	  stack frame is reliable. Call is_reliable_function() from
>> 	  check_reliability().
>>
>> 	- Before a return PC is checked against special_funtions[], it
>> 	  must be validates as a proper kernel text address. Call
>> 	  __kernel_text_address() from check_reliability().
>>
>> 	- Finally, call check_reliability() from unwind_frame() for
>> 	  each stack frame.
>>
>> 	- Add EL1 exception handlers to special_functions[].
>>
>> 		el1_sync();
>> 		el1_irq();
>> 		el1_error();
>> 		el1_sync_invalid();
>> 		el1_irq_invalid();
>> 		el1_fiq_invalid();
>> 		el1_error_invalid();
>>
>> 	- The above functions are currently defined as LOCAL symbols.
>> 	  Make them global so that they can be referenced from the
>> 	  unwinder code.
>>
>> 	- Add FTRACE trampolines to special_functions[]:
>>
>> 		ftrace_graph_call()
>> 		ftrace_graph_caller()
>> 		return_to_handler()
>>
>> 	- Add the kretprobe trampoline to special functions[]:
>>
>> 		kretprobe_trampoline()
>>
>> Previous versions and discussion
>> ================================
>>
>> v6: https://lore.kernel.org/linux-arm-kernel/20210630223356.58714-1-madvenka at linux.microsoft.com/
>> v5: https://lore.kernel.org/linux-arm-kernel/20210526214917.20099-1-madvenka at linux.microsoft.com/
>> v4: https://lore.kernel.org/linux-arm-kernel/20210516040018.128105-1-madvenka at linux.microsoft.com/
>> v3: https://lore.kernel.org/linux-arm-kernel/20210503173615.21576-1-madvenka at linux.microsoft.com/
>> v2: https://lore.kernel.org/linux-arm-kernel/20210405204313.21346-1-madvenka at linux.microsoft.com/
>> v1: https://lore.kernel.org/linux-arm-kernel/20210330190955.13707-1-madvenka at linux.microsoft.com/
>> Madhavan T. Venkataraman (4):
>>   arm64: Make all stack walking functions use arch_stack_walk()
>>   arm64: Reorganize the unwinder code for better consistency and
>>     maintenance
>>   arm64: Introduce stack trace reliability checks in the unwinder
>>   arm64: Create a list of SYM_CODE functions, check return PC against
>>     list
>>
>>  arch/arm64/include/asm/linkage.h    |  12 ++
>>  arch/arm64/include/asm/sections.h   |   1 +
>>  arch/arm64/include/asm/stacktrace.h |  16 +-
>>  arch/arm64/kernel/perf_callchain.c  |   5 +-
>>  arch/arm64/kernel/process.c         |  39 ++--
>>  arch/arm64/kernel/return_address.c  |   6 +-
>>  arch/arm64/kernel/stacktrace.c      | 291 ++++++++++++++++++++--------
>>  arch/arm64/kernel/time.c            |  22 ++-
>>  arch/arm64/kernel/vmlinux.lds.S     |  10 +
>>  9 files changed, 277 insertions(+), 125 deletions(-)
>>
>>
>> base-commit: 36a21d51725af2ce0700c6ebcb6b9594aac658a6
>>


From vgupta at kernel.org  Thu Aug 12 11:57:49 2021
From: vgupta at kernel.org (Vineet Gupta)
Date: Thu, 12 Aug 2021 11:57:49 -0700
Subject: [PATCH -next] trap: Cleanup trap_init()
In-Reply-To: <20210812123602.76356-1-wangkefeng.wang@huawei.com>
References: <20210812123602.76356-1-wangkefeng.wang@huawei.com>
Message-ID: <b49eed44-0837-906c-8779-4fffb5609653@kernel.org>

On 8/12/21 5:36 AM, Kefeng Wang wrote:
> There are some empty trap_init() in different ARCHs, introduce
> a new weak trap_init() function to cleanup them.
>
> Cc: Vineet Gupta<vgupta at kernel.org>
> Cc: Russell King<linux at armlinux.org.uk>
> Cc: Yoshinori Sato<ysato at users.sourceforge.jp>
> Cc: Ley Foon Tan<ley.foon.tan at intel.com>
> Cc: Jonas Bonn<jonas at southpole.se>
> Cc: Stefan Kristiansson<stefan.kristiansson at saunalahti.fi>
> Cc: Stafford Horne<shorne at gmail.com>
> Cc: James E.J. Bottomley<James.Bottomley at HansenPartnership.com>
> Cc: Helge Deller<deller at gmx.de>
> Cc: Michael Ellerman<mpe at ellerman.id.au>
> Cc: Benjamin Herrenschmidt<benh at kernel.crashing.org>
> Cc: Paul Mackerras<paulus at samba.org>
> Cc: Paul Walmsley<palmerdabbelt at google.com>
> Cc: Jeff Dike<jdike at addtoit.com>
> Cc: Richard Weinberger<richard at nod.at>
> Cc: Anton Ivanov<anton.ivanov at cambridgegreys.com>
> Cc: Andrew Morton<akpm at linux-foundation.org>
> Signed-off-by: Kefeng Wang<wangkefeng.wang at huawei.com>
> ---
>   arch/arc/kernel/traps.c      | 5 -----

Acked-by: Vineet Gupta <vgupt at kernel.org>? #arch/arc


From maz at kernel.org  Thu Aug 12 12:02:09 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 20:02:09 +0100
Subject: [PATCH 1/5] arm64: Directly expand __init_el2_nvhe_prepare_eret where
 needed
In-Reply-To: <20210812190213.2601506-1-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
Message-ID: <20210812190213.2601506-2-maz@kernel.org>

As we are about to enable taking exceptions extremely early,
it becomes pointless to pre-populate SPSR_EL2 in init_el2_state.

We already have the stuck-in-VHE handling code that needs some
special casing, so let's bite the bullet and get rid of the macros
by expanding them where needed.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h | 6 ------
 arch/arm64/kernel/head.S           | 2 ++
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 21fa330f498d..0b5c8033eaf2 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -164,11 +164,6 @@
 .Lskip_fgt_\@:
 .endm
 
-.macro __init_el2_nvhe_prepare_eret
-	mov	x0, #INIT_PSTATE_EL1
-	msr	spsr_el2, x0
-.endm
-
 /**
  * Initialize EL2 registers to sane values. This should be called early on all
  * cores that were booted in EL2. Note that everything gets initialised as
@@ -189,7 +184,6 @@
 	__init_el2_nvhe_cptr
 	__init_el2_nvhe_sve
 	__init_el2_fgt
-	__init_el2_nvhe_prepare_eret
 .endm
 
 #endif /* __ARM_KVM_INIT_H__ */
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c5c994a73a64..9d5aa56a98cc 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -547,6 +547,8 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
 	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
 	msr	sctlr_el1, x0
 
+	mov_q	x0, INIT_PSTATE_EL1
+	msr	spsr_el2, x0
 	msr	elr_el2, lr
 	mov	w0, #BOOT_CPU_MODE_EL2
 	eret
-- 
2.30.2



From maz at kernel.org  Thu Aug 12 12:02:08 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 20:02:08 +0100
Subject: [PATCH 0/5] arm64: Survival kit for SCR_EL3.HCE==0 conditions
Message-ID: <20210812190213.2601506-1-maz@kernel.org>

Anyone vaguely familiar with the ARMv8 architecture would quickly
understand that entering the kernel at EL2 without enabling the HVC
instruction is... living dangerously. But as it turns out [0], there
is a whole range of (*cough*) "high quality" (*cough*) Broadcom
systems out there configured exactly like that.

If you are speechless, I'm right with you.

These machines have stopped being able to boot an upstream kernel
since 5.12, where we changed the way we switch from nVHE to VHE, as
this relies on the HVC instruction being usable... It is also worth
noting that these systems have never been able to use KVM. Or kexec.

This small series addresses the issue by detecting an UNDEFing HVC in
a fairly controlled environment, and in this case pretend that we have
booted at EL1. It also documents the requirement for SCR_EL3.HCE to be
set to *1* if the kernel is entered at EL2. Turns out that we really
have to state the obvious.

This has been tested on a FVP model with a hacked-up boot-wrapper.

Note that I really don't think any of this is -stable material, except
maybe for the documentation. It isn't 5.14 material either. Best case,
this is 5.15, or maybe even later. If ever.

	M. (drink required)

[0] https://lore.kernel.org/r/53f3a2d2-22f8-edee-2507-d41a4090dad7 at gmail.com

Marc Zyngier (5):
  arm64: Directly expand __init_el2_nvhe_prepare_eret where needed
  arm64: Handle UNDEF in the EL2 stub vectors
  arm64: Detect disabled HVC early
  arm64: Warn on booting at EL2 with HVC disabled
  arm64: Document the requirement for SCR_EL3.HCE

 Documentation/arm64/booting.rst    |  5 +++++
 arch/arm64/include/asm/el2_setup.h |  6 ------
 arch/arm64/include/asm/virt.h      | 10 +++++++++
 arch/arm64/kernel/head.S           | 34 ++++++++++++++++++++++++++++++
 arch/arm64/kernel/hyp-stub.S       | 19 ++++++++++++++++-
 arch/arm64/kernel/smp.c            |  3 +++
 6 files changed, 70 insertions(+), 7 deletions(-)

-- 
2.30.2



From maz at kernel.org  Thu Aug 12 12:02:12 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 20:02:12 +0100
Subject: [PATCH 4/5] arm64: Warn on booting at EL2 with HVC disabled
In-Reply-To: <20210812190213.2601506-1-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
Message-ID: <20210812190213.2601506-5-maz@kernel.org>

Now that we are able to paper over the gigantic stupidity that
booting at EL2 with SCR_EL3.HCE==0 is, let's taint WARN_TAINT()
when detecting this situation.

Yes, this is *LOUD*.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/virt.h | 10 ++++++++++
 arch/arm64/kernel/head.S      | 10 ++++++++++
 arch/arm64/kernel/smp.c       |  3 +++
 3 files changed, 23 insertions(+)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 7379f35ae2c6..89bf5ae522da 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -49,6 +49,9 @@
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
 
+/* Flags associated to the boot mode */
+#define BOOT_CPU_MODE_DOWNGRADED (1 << 0)
+
 #ifndef __ASSEMBLY__
 
 #include <asm/ptrace.h>
@@ -67,6 +70,13 @@
  */
 extern u32 __boot_cpu_mode[2];
 
+/*
+ * __boot_cpu_mode_flags records events that are associated with CPUs
+ * coming online. A CPU having been downgraded from EL2 to EL1 because
+ * of HVC not being enabled will have BOOT_CPU_MODE_DOWNGRADED set.
+ */
+extern u32 __boot_cpu_mode_flags[1];
+
 void __hyp_set_vectors(phys_addr_t phys_vector_base);
 void __hyp_reset_vectors(void);
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index d6b2b05f5d3a..fdad6805868b 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -530,7 +530,13 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
 	/*
 	 * HVC is unusable, so pretend we actually booted at EL1.
 	 * Once we have left EL2, there will be no going back.
+	 * set_cpu_boot_mode_flag will do the necessary CMOs for us.
 	 */
+	adr_l	x1, __boot_cpu_mode_flags
+	ldr	w0, [x1]
+	orr	w0, w0, BOOT_CPU_MODE_DOWNGRADED
+	str	w0, [x1]
+
 	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
 	msr	sctlr_el1, x0
 
@@ -623,6 +629,10 @@ SYM_DATA_START(__early_cpu_boot_status)
 	.quad 	0
 SYM_DATA_END(__early_cpu_boot_status)
 
+SYM_DATA_START(__boot_cpu_mode_flags)
+	.long	0
+SYM_DATA_END(__boot_cpu_mode_flags)
+
 	.popsection
 
 	/*
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 6f6ff072acbd..43fad7ca9110 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -425,6 +425,9 @@ static void __init hyp_mode_check(void)
 	else if (is_hyp_mode_mismatched())
 		WARN_TAINT(1, TAINT_CPU_OUT_OF_SPEC,
 			   "CPU: CPUs started in inconsistent modes");
+	else if (__boot_cpu_mode_flags[0] & BOOT_CPU_MODE_DOWNGRADED)
+		WARN_TAINT(1, TAINT_CPU_OUT_OF_SPEC,
+			   "CPU: CPUs downgraded to EL1, HVC disabled");
 	else
 		pr_info("CPU: All CPU(s) started at EL1\n");
 	if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode()) {
-- 
2.30.2



From maz at kernel.org  Thu Aug 12 12:02:13 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 20:02:13 +0100
Subject: [PATCH 5/5] arm64: Document the requirement for SCR_EL3.HCE
In-Reply-To: <20210812190213.2601506-1-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
Message-ID: <20210812190213.2601506-6-maz@kernel.org>

It is amazing that we never documented this absolutely basic
requirement: if you boot the kernel at EL2, you'd better
enable the HVC instruction from EL3.

Really, just do it.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 Documentation/arm64/booting.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
index a9192e7a231b..6c729d0c4bc2 100644
--- a/Documentation/arm64/booting.rst
+++ b/Documentation/arm64/booting.rst
@@ -212,6 +212,11 @@ Before jumping into the kernel, the following conditions must be met:
   - The value of SCR_EL3.FIQ must be the same as the one present at boot
     time whenever the kernel is executing.
 
+  For all systems:
+  - If EL3 is present and the kernel is entered at EL2:
+
+    - SCR_EL3.HCE (bit 8) must be initialised to 0b1.
+
   For systems with a GICv3 interrupt controller to be used in v3 mode:
   - If EL3 is present:
 
-- 
2.30.2



From maz at kernel.org  Thu Aug 12 12:02:10 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 20:02:10 +0100
Subject: [PATCH 2/5] arm64: Handle UNDEF in the EL2 stub vectors
In-Reply-To: <20210812190213.2601506-1-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
Message-ID: <20210812190213.2601506-3-maz@kernel.org>

As we want to handle the silly case where HVC has been disabled
from EL3, augment our ability to handle exception at EL2.

Check for unknown exceptions (usually UNDEF) coming from EL2,
and treat them as a failing HVC call into the stubs. While
this isn't great and obviously doesn't catter for the gigantic
range of possible exceptions, it isn't any worse than what we
have today.

Just don't try and use it for anything else.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kernel/hyp-stub.S | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 43d212618834..026a34515b21 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -46,7 +46,16 @@ SYM_CODE_END(__hyp_stub_vectors)
 	.align 11
 
 SYM_CODE_START_LOCAL(elx_sync)
-	cmp	x0, #HVC_SET_VECTORS
+	mrs	x4, spsr_el2
+	and	x4, x4, #PSR_MODE_MASK
+	orr	x4, x4, #1
+	cmp	x4, #PSR_MODE_EL2h
+	b.ne	0f
+	mrs	x4, esr_el2
+	eor	x4, x4, #ESR_ELx_IL
+	cbz	x4, el2_undef
+
+0:	cmp	x0, #HVC_SET_VECTORS
 	b.ne	1f
 	msr	vbar_el2, x1
 	b	9f
@@ -71,6 +80,14 @@ SYM_CODE_START_LOCAL(elx_sync)
 
 9:	mov	x0, xzr
 	eret
+
+el2_undef:
+	// Assumes this was a HVC that went really wrong...
+	mrs	x0, elr_el2
+	add	x0, x0, #4
+	msr	elr_el2, x0
+	mov_q	x0, HVC_STUB_ERR
+	eret
 SYM_CODE_END(elx_sync)
 
 // nVHE? No way! Give me the real thing!
-- 
2.30.2



From maz at kernel.org  Thu Aug 12 12:02:11 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 12 Aug 2021 20:02:11 +0100
Subject: [PATCH 3/5] arm64: Detect disabled HVC early
In-Reply-To: <20210812190213.2601506-1-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
Message-ID: <20210812190213.2601506-4-maz@kernel.org>

Having HVC disabled from EL3 while the kernel is entered at EL2
is a complete nightmare.

We end-up taking an UNDEF at the worse possible moment (checking
for VHE) and even if we didn't, having KVM enabled would signify
the premature end of the kernel.

Instead, try and detect this stupid case by issuing a HVC
for HVC_RESET_VECTORS, which does nothing when the stubs
are live. If we get HVC_STUB_ERR back, that's because the
UNDEF handler has kicked in.

In this situation, close your eyes, block your nose, and gracefully
pretend we have booted at EL1.

Reported-by: Rafa? Mi?ecki <zajec5 at gmail.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kernel/head.S | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 9d5aa56a98cc..d6b2b05f5d3a 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -519,6 +519,28 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
 	msr	vbar_el2, x0
 	isb
 
+	// Check that HVC actually works...
+	mov	x0, #HVC_RESET_VECTORS
+	hvc	#0
+
+	mov_q	x1, HVC_STUB_ERR
+	cmp	x0, x1
+	b.ne	0f
+
+	/*
+	 * HVC is unusable, so pretend we actually booted at EL1.
+	 * Once we have left EL2, there will be no going back.
+	 */
+	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
+	msr	sctlr_el1, x0
+
+	mov_q	x0, INIT_PSTATE_EL1
+	msr	spsr_el2, x0
+	msr	elr_el2, lr
+	mov_q	w0, BOOT_CPU_MODE_EL1
+	eret
+
+0:
 	/*
 	 * Fruity CPUs seem to have HCR_EL2.E2H set to RES1,
 	 * making it impossible to start in nVHE mode. Is that
-- 
2.30.2



From madvenka at linux.microsoft.com  Thu Aug 12 12:05:59 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 14:05:59 -0500
Subject: [RFC PATCH v8 0/4] arm64: Reorganize the unwinder and implement stack
 trace reliability checks
In-Reply-To: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
Message-ID: <20210812190603.25326-1-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Make all stack walking functions use arch_stack_walk()
======================================================

Currently, there are multiple functions in ARM64 code that walk the
stack using start_backtrace() and unwind_frame(). Convert all of
them to use arch_stack_walk(). This makes maintenance easier.

Reorganize the unwinder code for better consistency and maintenance
===================================================================

Rename unwinder functions to unwind_*() similar to other architectures
for naming consistency.

Annotate all of the unwind_*() functions with notrace so they cannot be
ftraced and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe
code can call the unwinder.

Redefine the unwinder loop and make it similar to other architectures.
Define the following:

	unwind_start(&frame, task, fp, pc);
	while (unwind_consume(&frame, consume_entry, cookie))
		unwind_next(&frame);
	return !unwind_failed(&frame);

unwind_start()
	Same as the original start_backtrace().

unwind_consume()
	This new function does two things:

	- Calls consume_entry() to consume the return PC.

	- Implements checks to determine whether the unwind should continue
	  or terminate.

unwind_next()
	Same as the original unwind_frame() except:

	- the stack trace termination check has been moved from here to
	  unwind_consume(). So, unwind_next() assumes that the fp is valid.

	- unwind_frame() used to return an error value. This function only
	  sets internal state and does not return anything. The state is
	  retrieved via a helper. See next.

unwind_failed()
	Return a boolean to indicate whether the stack trace completed
	successfully or failed. arch_stack_walk() ignores the return
	value. But arch_stack_walk_reliable() in the future will look
	at the return value.

Unwind status
	Introduce a new flag called "failed" in struct stackframe. Set this
	flag when an error is encountered. If this flag is set, terminate
	the unwind. Also, let the unwinder return the status to the caller.

Reliability checks
==================

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_is_reliable() that will detect
these cases and return a boolean.

Introduce a new argument to unwind() called "need_reliable" so a caller
can tell unwind() that it requires a reliable stack trace. For such a
caller, any unreliability in the stack trace must be treated as a fatal
error and the unwind must be aborted.

Call unwind_is_reliable() from unwind_consume() like this:

	if (frame->need_reliable && !unwind_is_reliable(frame)) {
		frame->failed = true;
		return false;
	}

arch_stack_walk() passes "false" for need_reliable because its callers
don't care about reliability. arch_stack_walk() is used for debug and
test purposes.

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except for two things:

	- It passes "true" for need_reliable.

	- It returns -EINVAL if unwind() aborts.

Introduce the first reliability check in unwind_is_reliable() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future. Until all of the
checks are in place, arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

SYM_CODE check
==============

SYM_CODE functions do not follow normal calling conventions. They cannot
be unwound reliably using the frame pointer. Collect the address ranges
of these functions in a special section called "sym_code_functions".

In unwind_is_reliable(), check the return PC against these ranges. If a
match is found, then consider the stack trace unreliable. This is the
second reliability check introduced by this work.

Last stack frame
----------------

If a SYM_CODE function occurs in the very last frame in the stack trace,
then the stack trace is not considered unreliable. This is because there
is no more unwinding to do. Examples:

	- EL0 exception stack traces end in the top level EL0 exception
	  handlers.

	- All kernel thread stack traces end in ret_from_fork().
---
Changelog:

v8:
	From Mark Rutland:

	- Make the unwinder loop similar to other architectures.

	- Keep details to within the unwinder functions and return a simple
	  boolean to the caller.

	- Convert some of the current code that contains unwinder logic to
	  simply use arch_stack_walk(). I have converted all of them.

	- Do not copy sym_code_functions[]. Just place it in rodata for now.

	- Have the main loop check for termination conditions rather than
	  having unwind_frame() check for them. In other words, let
	  unwind_frame() assume that the fp is valid.

	- Replace the big comment for SYM_CODE functions with a shorter
	  comment.

		/*
		 * As SYM_CODE functions don't follow the usual calling
		 * conventions, we assume by default that any SYM_CODE function
		 * cannot be unwound reliably.
		 *
		 * Note that this includes:
		 *
		 * - Exception handlers and entry assembly
		 * - Trampoline assembly (e.g., ftrace, kprobes)
		 * - Hypervisor-related assembly
		 * - Hibernation-related assembly
		 * - CPU start-stop, suspend-resume assembly
		 * - Kernel relocation assembly
		 */

v7:
	The Mailer screwed up the threading on this. So, I have resent this
	same series as version 8 with proper threading to avoid confusion.
v6:
	From Mark Rutland:

	- The per-frame reliability concept and flag are acceptable. But more
	  work is needed to make the per-frame checks more accurate and more
	  complete. E.g., some code reorg is being worked on that will help.

	  I have now removed the frame->reliable flag and deleted the whole
	  concept of per-frame status. This is orthogonal to this patch series.
	  Instead, I have improved the unwinder to return proper return codes
	  so a caller can take appropriate action without needing per-frame
	  status.

	- Remove the mention of PLTs and update the comment.

	  I have replaced the comment above the call to __kernel_text_address()
	  with the comment suggested by Mark Rutland.

	Other comments:

	- Other comments on the per-frame stuff are not relevant because
	  that approach is not there anymore.

v5:
	From Keiya Nobuta:
	
	- The term blacklist(ed) is not to be used anymore. I have changed it
	  to unreliable. So, the function unwinder_blacklisted() has been
	  changed to unwinder_is_unreliable().

	From Mark Brown:

	- Add a comment for the "reliable" flag in struct stackframe. The
	  reliability attribute is not complete until all the checks are
	  in place. Added a comment above struct stackframe.

	- Include some of the comments in the cover letter in the actual
	  code so that we can compare it with the reliable stack trace
	  requirements document for completeness. I have added a comment:

	  	- above unwinder_is_unreliable() that lists the requirements
		  that are addressed by the function.

		- above the __kernel_text_address() call about all the cases
		  the call covers.

v4:
	From Mark Brown:

	- I was checking the return PC with __kernel_text_address() before
	  the Function Graph trace handling. Mark Brown felt that all the
	  reliability checks should be performed on the original return PC
	  once that is obtained. So, I have moved all the reliability checks
	  to after the Function Graph Trace handling code in the unwinder.
	  Basically, the unwinder should perform PC translations first (for
	  rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
	  Then, the reliability checks should be applied to the resulting
	  PC.

	- Mark said to improve the naming of the new functions so they don't
	  collide with existing ones. I have used a prefix "unwinder_" for
	  all the new functions.

	From Josh Poimboeuf:

	- In the error scenarios in the unwinder, the reliable flag in the
	  stack frame should be set. Implemented this.

	- Some of the other comments are not relevant to the new code as
	  I have taken a different approach in the new code. That is why
	  I have not made those changes. E.g., Ard wanted me to add the
	  "const" keyword to the global section array. That array does not
	  exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
	  the same array in a for loop.

	Other changes:

	- Add a new definition for SYM_CODE_END() that adds the address
	  range of the function to a special section called
	  "sym_code_functions".

	- Include the new section under initdata in vmlinux.lds.S.

	- Define an early_initcall() to copy the contents of the
	  "sym_code_functions" section to an array by the same name.

	- Define a function unwinder_blacklisted() that compares a return
	  PC against sym_code_sections[]. If there is a match, mark the
	  stack trace unreliable. Call this from unwind_frame().

v3:
	- Implemented a sym_code_ranges[] array to contains sections bounds
	  for text sections that contain SYM_CODE_*() functions. The unwinder
	  checks each return PC against the sections. If it falls in any of
	  the sections, the stack trace is marked unreliable.

	- Moved SYM_CODE functions from .text and .init.text into a new
	  text section called ".code.text". Added this section to
	  vmlinux.lds.S and sym_code_ranges[].

	- Fixed the logic in the unwinder that handles Function Graph
	  Tracer return trampoline.

	- Removed all the previous code that handles:
		- ftrace entry code for traced function
		- special_functions[] array that lists individual functions
		- kretprobe_trampoline() special case

v2
	- Removed the terminating entry { 0, 0 } in special_functions[]
	  and replaced it with the idiom { /* sentinel */ }.

	- Change the ftrace trampoline entry ftrace_graph_call in
	  special_functions[] to ftrace_call + 4 and added explanatory
	  comments.

	- Unnested #ifdefs in special_functions[] for FTRACE.

v1
	- Define a bool field in struct stackframe. This will indicate if
	  a stack trace is reliable.

	- Implement a special_functions[] array that will be populated
	  with special functions in which the stack trace is considered
	  unreliable.
	
	- Using kallsyms_lookup(), get the address ranges for the special
	  functions and record them.

	- Implement an is_reliable_function(pc). This function will check
	  if a given return PC falls in any of the special functions. If
	  it does, the stack trace is unreliable.

	- Implement check_reliability() function that will check if a
	  stack frame is reliable. Call is_reliable_function() from
	  check_reliability().

	- Before a return PC is checked against special_funtions[], it
	  must be validates as a proper kernel text address. Call
	  __kernel_text_address() from check_reliability().

	- Finally, call check_reliability() from unwind_frame() for
	  each stack frame.

	- Add EL1 exception handlers to special_functions[].

		el1_sync();
		el1_irq();
		el1_error();
		el1_sync_invalid();
		el1_irq_invalid();
		el1_fiq_invalid();
		el1_error_invalid();

	- The above functions are currently defined as LOCAL symbols.
	  Make them global so that they can be referenced from the
	  unwinder code.

	- Add FTRACE trampolines to special_functions[]:

		ftrace_graph_call()
		ftrace_graph_caller()
		return_to_handler()

	- Add the kretprobe trampoline to special functions[]:

		kretprobe_trampoline()

Previous versions and discussion
================================

v7: Mailer screwed up the threading. Sent the same as v8 with proper threading.
v6: https://lore.kernel.org/linux-arm-kernel/20210630223356.58714-1-madvenka at linux.microsoft.com/
v5: https://lore.kernel.org/linux-arm-kernel/20210526214917.20099-1-madvenka at linux.microsoft.com/
v4: https://lore.kernel.org/linux-arm-kernel/20210516040018.128105-1-madvenka at linux.microsoft.com/
v3: https://lore.kernel.org/linux-arm-kernel/20210503173615.21576-1-madvenka at linux.microsoft.com/
v2: https://lore.kernel.org/linux-arm-kernel/20210405204313.21346-1-madvenka at linux.microsoft.com/
v1: https://lore.kernel.org/linux-arm-kernel/20210330190955.13707-1-madvenka at linux.microsoft.com/
Madhavan T. Venkataraman (4):
  arm64: Make all stack walking functions use arch_stack_walk()
  arm64: Reorganize the unwinder code for better consistency and
    maintenance
  arm64: Introduce stack trace reliability checks in the unwinder
  arm64: Create a list of SYM_CODE functions, check return PC against
    list

 arch/arm64/include/asm/linkage.h    |  12 ++
 arch/arm64/include/asm/sections.h   |   1 +
 arch/arm64/include/asm/stacktrace.h |  16 +-
 arch/arm64/kernel/perf_callchain.c  |   5 +-
 arch/arm64/kernel/process.c         |  39 ++--
 arch/arm64/kernel/return_address.c  |   6 +-
 arch/arm64/kernel/stacktrace.c      | 291 ++++++++++++++++++++--------
 arch/arm64/kernel/time.c            |  22 ++-
 arch/arm64/kernel/vmlinux.lds.S     |  10 +
 9 files changed, 277 insertions(+), 125 deletions(-)


base-commit: 36a21d51725af2ce0700c6ebcb6b9594aac658a6
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 12:06:00 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 14:06:00 -0500
Subject: [RFC PATCH v8 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210812190603.25326-1-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
Message-ID: <20210812190603.25326-2-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Currently, there are multiple functions in ARM64 code that walk the
stack using start_backtrace() and unwind_frame(). Convert all of
them to use arch_stack_walk(). This makes maintenance easier.

Here is the list of functions:

	perf_callchain_kernel()
	get_wchan()
	return_address()
	dump_backtrace()
	profile_pc()

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  3 ---
 arch/arm64/kernel/perf_callchain.c  |  5 +---
 arch/arm64/kernel/process.c         | 39 ++++++++++++++++++-----------
 arch/arm64/kernel/return_address.c  |  6 +----
 arch/arm64/kernel/stacktrace.c      | 38 +++-------------------------
 arch/arm64/kernel/time.c            | 22 +++++++++-------
 6 files changed, 43 insertions(+), 70 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 8aebc00c1718..e43dea1c6b41 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -61,9 +61,6 @@ struct stackframe {
 #endif
 };
 
-extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
-extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
-			    bool (*fn)(void *, unsigned long), void *data);
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 			   const char *loglvl);
 
diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 4a72c2727309..2f289013c9c9 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -147,15 +147,12 @@ static bool callchain_trace(void *data, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
-	struct stackframe frame;
-
 	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
 
-	start_backtrace(&frame, regs->regs[29], regs->pc);
-	walk_stackframe(current, &frame, callchain_trace, entry);
+	arch_stack_walk(callchain_trace, entry, current, regs);
 }
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index c8989b999250..52c12fd26407 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -544,11 +544,28 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
 	return last;
 }
 
+struct wchan_info {
+	unsigned long	pc;
+	int		count;
+};
+
+static bool get_wchan_cb(void *arg, unsigned long pc)
+{
+	struct wchan_info *wchan_info = arg;
+
+	if (!in_sched_functions(pc)) {
+		wchan_info->pc = pc;
+		return false;
+	}
+	wchan_info->count--;
+	return !!wchan_info->count;
+}
+
 unsigned long get_wchan(struct task_struct *p)
 {
-	struct stackframe frame;
-	unsigned long stack_page, ret = 0;
-	int count = 0;
+	unsigned long stack_page;
+	struct wchan_info wchan_info;
+
 	if (!p || p == current || task_is_running(p))
 		return 0;
 
@@ -556,20 +573,12 @@ unsigned long get_wchan(struct task_struct *p)
 	if (!stack_page)
 		return 0;
 
-	start_backtrace(&frame, thread_saved_fp(p), thread_saved_pc(p));
+	wchan_info.pc = 0;
+	wchan_info.count = 16;
+	arch_stack_walk(get_wchan_cb, &wchan_info, p, NULL);
 
-	do {
-		if (unwind_frame(p, &frame))
-			goto out;
-		if (!in_sched_functions(frame.pc)) {
-			ret = frame.pc;
-			goto out;
-		}
-	} while (count++ < 16);
-
-out:
 	put_task_stack(p);
-	return ret;
+	return wchan_info.pc;
 }
 
 unsigned long arch_align_stack(unsigned long sp)
diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c
index a6d18755652f..92a0f4d434e4 100644
--- a/arch/arm64/kernel/return_address.c
+++ b/arch/arm64/kernel/return_address.c
@@ -35,15 +35,11 @@ NOKPROBE_SYMBOL(save_return_addr);
 void *return_address(unsigned int level)
 {
 	struct return_address_data data;
-	struct stackframe frame;
 
 	data.level = level + 2;
 	data.addr = NULL;
 
-	start_backtrace(&frame,
-			(unsigned long)__builtin_frame_address(0),
-			(unsigned long)return_address);
-	walk_stackframe(current, &frame, save_return_addr, &data);
+	arch_stack_walk(save_return_addr, &data, current, NULL);
 
 	if (!data.level)
 		return data.addr;
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 8982a2b78acf..1800310f92be 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -151,23 +151,21 @@ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
 }
 NOKPROBE_SYMBOL(walk_stackframe);
 
-static void dump_backtrace_entry(unsigned long where, const char *loglvl)
+static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
+	char *loglvl = arg;
 	printk("%s %pSb\n", loglvl, (void *)where);
+	return true;
 }
 
 void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 		    const char *loglvl)
 {
-	struct stackframe frame;
-	int skip = 0;
-
 	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
 
 	if (regs) {
 		if (user_mode(regs))
 			return;
-		skip = 1;
 	}
 
 	if (!tsk)
@@ -176,36 +174,8 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 	if (!try_get_task_stack(tsk))
 		return;
 
-	if (tsk == current) {
-		start_backtrace(&frame,
-				(unsigned long)__builtin_frame_address(0),
-				(unsigned long)dump_backtrace);
-	} else {
-		/*
-		 * task blocked in __switch_to
-		 */
-		start_backtrace(&frame,
-				thread_saved_fp(tsk),
-				thread_saved_pc(tsk));
-	}
-
 	printk("%sCall trace:\n", loglvl);
-	do {
-		/* skip until specified stack frame */
-		if (!skip) {
-			dump_backtrace_entry(frame.pc, loglvl);
-		} else if (frame.fp == regs->regs[29]) {
-			skip = 0;
-			/*
-			 * Mostly, this is the case where this function is
-			 * called in panic/abort. As exception handler's
-			 * stack frame does not contain the corresponding pc
-			 * at which an exception has taken place, use regs->pc
-			 * instead.
-			 */
-			dump_backtrace_entry(regs->pc, loglvl);
-		}
-	} while (!unwind_frame(tsk, &frame));
+	arch_stack_walk(dump_backtrace_entry, (void *)loglvl, tsk, regs);
 
 	put_task_stack(tsk);
 }
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index eebbc8d7123e..671b3038a772 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -32,22 +32,26 @@
 #include <asm/stacktrace.h>
 #include <asm/paravirt.h>
 
+static bool profile_pc_cb(void *arg, unsigned long pc)
+{
+	unsigned long *prof_pc = arg;
+
+	if (in_lock_functions(pc))
+		return true;
+	*prof_pc = pc;
+	return false;
+}
+
 unsigned long profile_pc(struct pt_regs *regs)
 {
-	struct stackframe frame;
+	unsigned long prof_pc = 0;
 
 	if (!in_lock_functions(regs->pc))
 		return regs->pc;
 
-	start_backtrace(&frame, regs->regs[29], regs->pc);
-
-	do {
-		int ret = unwind_frame(NULL, &frame);
-		if (ret < 0)
-			return 0;
-	} while (in_lock_functions(frame.pc));
+	arch_stack_walk(profile_pc_cb, &prof_pc, current, regs);
 
-	return frame.pc;
+	return prof_pc;
 }
 EXPORT_SYMBOL(profile_pc);
 
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 12:06:01 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 14:06:01 -0500
Subject: [RFC PATCH v8 2/4] arm64: Reorganize the unwinder code for better
 consistency and maintenance
In-Reply-To: <20210812190603.25326-1-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
Message-ID: <20210812190603.25326-3-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Renaming of unwinder functions
==============================

Rename unwinder functions to unwind_*() similar to other architectures
for naming consistency. More on this below.

unwind function attributes
==========================

Mark all of the unwind_*() functions with notrace so they cannot be ftraced
and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe code
can call the unwinder.

start_backtrace()
=================

start_backtrace() is only called by arch_stack_walk(). Make it static.
Rename start_backtrace() to unwind_start() for naming consistency.

unwind_frame()
==============

Rename this to unwind_next() for naming consistency.

Replace walk_stackframe() with unwind()
=======================================

walk_stackframe() contains the unwinder loop that walks the stack
frames. Currently, start_backtrace() and walk_stackframe() are called
separately. They should be combined in the same function. Also, the
loop in walk_stackframe() should be simplified and should look like
the unwind loops in other architectures such as X86 and S390.

Remove walk_stackframe(). Define a new function called "unwind()" in
its place. Define the following unwinder loop:

	unwind_start(&frame, task, fp, pc);
	while (unwind_consume(&frame, consume_entry, cookie))
		unwind_next(&frame);
	return !unwind_failed(&frame);

unwind_start()
	Same as the original start_backtrace().

unwind_consume()
	This is a new function that calls the callback function to
	consume the PC in a stackframe. Do it this way so that checks
	can be performed before and after the callback to determine
	whether the unwind should continue or terminate.

unwind_next()
	Same as the original unwind_frame() except for two things:

		- the stack trace termination check has been moved from
		  here to unwind_consume(). So, unwind_next() is always
		  called on a valid fp.

		- unwind_frame() used to return an error value. This
		  function does not return anything.

unwind_failed()
	Return a boolean to indicate if the stack trace completed
	successfully or failed. arch_stack_walk() ignores the return
	value. But arch_stack_walk_reliable() in the future will look
	at the return value.

Unwind status
=============

Introduce a new flag called "failed" in struct stackframe. unwind_next()
and unwind_consume() will set this flag when an error is encountered and
unwind_consume() will check this flag. This is in keeping with other
architectures.

The failed flags is accessed via the helper unwind_failed().

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |   9 +-
 arch/arm64/kernel/stacktrace.c      | 145 ++++++++++++++++++----------
 2 files changed, 99 insertions(+), 55 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index e43dea1c6b41..407007376e97 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -34,6 +34,8 @@ struct stack_info {
  * A snapshot of a frame record or fp/lr register values, along with some
  * accounting information necessary for robust unwinding.
  *
+ * @task:        The task whose stack is being unwound.
+ *
  * @fp:          The fp value in the frame record (or the real fp)
  * @pc:          The lr value in the frame record (or the real lr)
  *
@@ -49,8 +51,11 @@ struct stack_info {
  *
  * @graph:       When FUNCTION_GRAPH_TRACER is selected, holds the index of a
  *               replacement lr value in the ftrace graph stack.
+ *
+ * @failed:      Unwind failed.
  */
 struct stackframe {
+	struct task_struct *task;
 	unsigned long fp;
 	unsigned long pc;
 	DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
@@ -59,6 +64,7 @@ struct stackframe {
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	int graph;
 #endif
+	bool failed;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
@@ -145,7 +151,4 @@ static inline bool on_accessible_stack(const struct task_struct *tsk,
 	return false;
 }
 
-void start_backtrace(struct stackframe *frame, unsigned long fp,
-		     unsigned long pc);
-
 #endif	/* __ASM_STACKTRACE_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 1800310f92be..ec8f5163c4d0 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -32,10 +32,11 @@
  *	add	sp, sp, #0x10
  */
 
-
-void start_backtrace(struct stackframe *frame, unsigned long fp,
-		     unsigned long pc)
+static void notrace unwind_start(struct stackframe *frame,
+				 struct task_struct *task,
+				 unsigned long fp, unsigned long pc)
 {
+	frame->task = task;
 	frame->fp = fp;
 	frame->pc = pc;
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -45,7 +46,7 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
 	/*
 	 * Prime the first unwind.
 	 *
-	 * In unwind_frame() we'll check that the FP points to a valid stack,
+	 * In unwind_next() we'll check that the FP points to a valid stack,
 	 * which can't be STACK_TYPE_UNKNOWN, and the first unwind will be
 	 * treated as a transition to whichever stack that happens to be. The
 	 * prev_fp value won't be used, but we set it to 0 such that it is
@@ -54,8 +55,11 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
 	bitmap_zero(frame->stacks_done, __NR_STACK_TYPES);
 	frame->prev_fp = 0;
 	frame->prev_type = STACK_TYPE_UNKNOWN;
+	frame->failed = false;
 }
 
+NOKPROBE_SYMBOL(unwind_start);
+
 /*
  * Unwind from one frame record (A) to the next frame record (B).
  *
@@ -63,26 +67,26 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
+static void notrace unwind_next(struct stackframe *frame)
 {
 	unsigned long fp = frame->fp;
 	struct stack_info info;
+	struct task_struct *tsk = frame->task;
 
-	if (!tsk)
-		tsk = current;
-
-	/* Final frame; nothing to unwind */
-	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
-		return -ENOENT;
-
-	if (fp & 0x7)
-		return -EINVAL;
+	if (fp & 0x7) {
+		frame->failed = true;
+		return;
+	}
 
-	if (!on_accessible_stack(tsk, fp, 16, &info))
-		return -EINVAL;
+	if (!on_accessible_stack(tsk, fp, 16, &info)) {
+		frame->failed = true;
+		return;
+	}
 
-	if (test_bit(info.type, frame->stacks_done))
-		return -EINVAL;
+	if (test_bit(info.type, frame->stacks_done)) {
+		frame->failed = true;
+		return;
+	}
 
 	/*
 	 * As stacks grow downward, any valid record on the same stack must be
@@ -98,15 +102,17 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
 	 * stack.
 	 */
 	if (info.type == frame->prev_type) {
-		if (fp <= frame->prev_fp)
-			return -EINVAL;
+		if (fp <= frame->prev_fp) {
+			frame->failed = true;
+			return;
+		}
 	} else {
 		set_bit(frame->prev_type, frame->stacks_done);
 	}
 
 	/*
 	 * Record this frame record's values and location. The prev_fp and
-	 * prev_type are only meaningful to the next unwind_frame() invocation.
+	 * prev_type are only meaningful to the next unwind_next() invocation.
 	 */
 	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
 	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
@@ -124,32 +130,18 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
 		 * So replace it to an original value.
 		 */
 		ret_stack = ftrace_graph_get_ret_stack(tsk, frame->graph++);
-		if (WARN_ON_ONCE(!ret_stack))
-			return -EINVAL;
+		if (WARN_ON_ONCE(!ret_stack)) {
+			frame->failed = true;
+			return;
+		}
 		frame->pc = ret_stack->ret;
 	}
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
 	frame->pc = ptrauth_strip_insn_pac(frame->pc);
-
-	return 0;
 }
-NOKPROBE_SYMBOL(unwind_frame);
 
-void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
-			     bool (*fn)(void *, unsigned long), void *data)
-{
-	while (1) {
-		int ret;
-
-		if (!fn(data, frame->pc))
-			break;
-		ret = unwind_frame(tsk, frame);
-		if (ret < 0)
-			break;
-	}
-}
-NOKPROBE_SYMBOL(walk_stackframe);
+NOKPROBE_SYMBOL(unwind_next);
 
 static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
@@ -186,25 +178,74 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
 	barrier();
 }
 
+static bool notrace unwind_consume(struct stackframe *frame,
+				   stack_trace_consume_fn consume_entry,
+				   void *cookie)
+{
+	if (frame->failed) {
+		/* PC is suspect. Cannot consume it. */
+		return false;
+	}
+
+	if (!consume_entry(cookie, frame->pc)) {
+		/* Caller terminated the unwind. */
+		frame->failed = true;
+		return false;
+	}
+
+	if (frame->fp == (unsigned long)task_pt_regs(frame->task)->stackframe) {
+		/* Final frame; nothing to unwind */
+		return false;
+	}
+	return true;
+}
+
+NOKPROBE_SYMBOL(unwind_consume);
+
+static inline bool unwind_failed(struct stackframe *frame)
+{
+	return frame->failed;
+}
+
+/* Core unwind function */
+static bool notrace unwind(stack_trace_consume_fn consume_entry, void *cookie,
+			   struct task_struct *task,
+			   unsigned long fp, unsigned long pc)
+{
+	struct stackframe frame;
+
+	unwind_start(&frame, task, fp, pc);
+	while (unwind_consume(&frame, consume_entry, cookie))
+		unwind_next(&frame);
+	return !unwind_failed(&frame);
+}
+
+NOKPROBE_SYMBOL(unwind);
+
 #ifdef CONFIG_STACKTRACE
 
 noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 			      void *cookie, struct task_struct *task,
 			      struct pt_regs *regs)
 {
-	struct stackframe frame;
+	unsigned long fp, pc;
+
+	if (!task)
+		task = current;
 
-	if (regs)
-		start_backtrace(&frame, regs->regs[29], regs->pc);
-	else if (task == current)
-		start_backtrace(&frame,
-				(unsigned long)__builtin_frame_address(1),
-				(unsigned long)__builtin_return_address(0));
-	else
-		start_backtrace(&frame, thread_saved_fp(task),
-				thread_saved_pc(task));
-
-	walk_stackframe(task, &frame, consume_entry, cookie);
+	if (regs) {
+		fp = regs->regs[29];
+		pc = regs->pc;
+	} else if (task == current) {
+		/* Skip arch_stack_walk() in the stack trace. */
+		fp = (unsigned long)__builtin_frame_address(1);
+		pc = (unsigned long)__builtin_return_address(0);
+	} else {
+		/* Caller guarantees that the task is not running. */
+		fp = thread_saved_fp(task);
+		pc = thread_saved_pc(task);
+	}
+	unwind(consume_entry, cookie, task, fp, pc);
 }
 
 #endif
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 12:06:02 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 14:06:02 -0500
Subject: [RFC PATCH v8 3/4] arm64: Introduce stack trace reliability checks in
 the unwinder
In-Reply-To: <20210812190603.25326-1-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
Message-ID: <20210812190603.25326-4-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_is_reliable() that will detect
these cases and return a boolean.

Introduce a new argument to unwind() called "need_reliable" so a caller
can tell unwind() that it requires a reliable stack trace. For such a
caller, any unreliability in the stack trace must be treated as a fatal
error and the unwind must be aborted.

Call unwind_is_reliable() from unwind_consume() like this:

	if (frame->need_reliable && !unwind_is_reliable(frame)) {
		frame->failed = true;
		return false;
	}

In other words, if the return PC in the stackframe falls in unreliable code,
then it cannot be unwound reliably.

arch_stack_walk() will pass "false" for need_reliable because its callers
don't care about reliability. arch_stack_walk() is used for debug and
test purposes.

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except for two things:

	- It passes "true" for need_reliable.

	- It returns -EINVAL if unwind() says that the stack trace is
	  unreliable.

Introduce the first reliability check in unwind_is_reliable() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future. Until all of the
checks are in place, arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  4 ++
 arch/arm64/kernel/stacktrace.c      | 63 +++++++++++++++++++++++++++--
 2 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 407007376e97..65ea151da5da 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -53,6 +53,9 @@ struct stack_info {
  *               replacement lr value in the ftrace graph stack.
  *
  * @failed:      Unwind failed.
+ *
+ * @need_reliable The caller needs a reliable stack trace. Treat any
+ *                unreliability as a fatal error.
  */
 struct stackframe {
 	struct task_struct *task;
@@ -65,6 +68,7 @@ struct stackframe {
 	int graph;
 #endif
 	bool failed;
+	bool need_reliable;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index ec8f5163c4d0..b60f8a20ba64 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -34,7 +34,8 @@
 
 static void notrace unwind_start(struct stackframe *frame,
 				 struct task_struct *task,
-				 unsigned long fp, unsigned long pc)
+				 unsigned long fp, unsigned long pc,
+				 bool need_reliable)
 {
 	frame->task = task;
 	frame->fp = fp;
@@ -56,6 +57,7 @@ static void notrace unwind_start(struct stackframe *frame,
 	frame->prev_fp = 0;
 	frame->prev_type = STACK_TYPE_UNKNOWN;
 	frame->failed = false;
+	frame->need_reliable = need_reliable;
 }
 
 NOKPROBE_SYMBOL(unwind_start);
@@ -178,6 +180,23 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
 	barrier();
 }
 
+/*
+ * Check the stack frame for conditions that make further unwinding unreliable.
+ */
+static bool notrace unwind_is_reliable(struct stackframe *frame)
+{
+	/*
+	 * If the PC is not a known kernel text address, then we cannot
+	 * be sure that a subsequent unwind will be reliable, as we
+	 * don't know that the code follows our unwind requirements.
+	 */
+	if (!__kernel_text_address(frame->pc))
+		return false;
+	return true;
+}
+
+NOKPROBE_SYMBOL(unwind_is_reliable);
+
 static bool notrace unwind_consume(struct stackframe *frame,
 				   stack_trace_consume_fn consume_entry,
 				   void *cookie)
@@ -197,6 +216,12 @@ static bool notrace unwind_consume(struct stackframe *frame,
 		/* Final frame; nothing to unwind */
 		return false;
 	}
+
+	if (frame->need_reliable && !unwind_is_reliable(frame)) {
+		/* Cannot unwind to the next frame reliably. */
+		frame->failed = true;
+		return false;
+	}
 	return true;
 }
 
@@ -210,11 +235,12 @@ static inline bool unwind_failed(struct stackframe *frame)
 /* Core unwind function */
 static bool notrace unwind(stack_trace_consume_fn consume_entry, void *cookie,
 			   struct task_struct *task,
-			   unsigned long fp, unsigned long pc)
+			   unsigned long fp, unsigned long pc,
+			   bool need_reliable)
 {
 	struct stackframe frame;
 
-	unwind_start(&frame, task, fp, pc);
+	unwind_start(&frame, task, fp, pc, need_reliable);
 	while (unwind_consume(&frame, consume_entry, cookie))
 		unwind_next(&frame);
 	return !unwind_failed(&frame);
@@ -245,7 +271,36 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 		fp = thread_saved_fp(task);
 		pc = thread_saved_pc(task);
 	}
-	unwind(consume_entry, cookie, task, fp, pc);
+	unwind(consume_entry, cookie, task, fp, pc, false);
+}
+
+/*
+ * arch_stack_walk_reliable() may not be used for livepatch until all of
+ * the reliability checks are in place in unwind_consume(). However,
+ * debug and test code can choose to use it even if all the checks are not
+ * in place.
+ */
+noinline int notrace arch_stack_walk_reliable(stack_trace_consume_fn consume_fn,
+					      void *cookie,
+					      struct task_struct *task)
+{
+	unsigned long fp, pc;
+
+	if (!task)
+		task = current;
+
+	if (task == current) {
+		/* Skip arch_stack_walk_reliable() in the stack trace. */
+		fp = (unsigned long)__builtin_frame_address(1);
+		pc = (unsigned long)__builtin_return_address(0);
+	} else {
+		/* Caller guarantees that the task is not running. */
+		fp = thread_saved_fp(task);
+		pc = thread_saved_pc(task);
+	}
+	if (unwind(consume_fn, cookie, task, fp, pc, true))
+		return 0;
+	return -EINVAL;
 }
 
 #endif
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 12:06:03 2021
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Thu, 12 Aug 2021 14:06:03 -0500
Subject: [RFC PATCH v8 4/4] arm64: Create a list of SYM_CODE functions,
 check return PC against list
In-Reply-To: <20210812190603.25326-1-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
Message-ID: <20210812190603.25326-5-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

SYM_CODE functions don't follow the usual calling conventions. Check if the
return PC in a stack frame falls in any of these. If it does, consider the
stack trace unreliable.

Define a special section for unreliable functions
=================================================

Define a SYM_CODE_END() macro for arm64 that adds the function address
range to a new section called "sym_code_functions".

Linker file
===========

Include the "sym_code_functions" section under read-only data in
vmlinux.lds.S.

Initialization
==============

Define an early_initcall() to create a sym_code_functions[] array from
the linker data.

Unwinder check
==============

Add a reliability check in unwind_is_reliable() that compares a return
PC with sym_code_functions[]. If there is a match, then return failure.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/linkage.h  | 12 +++++++
 arch/arm64/include/asm/sections.h |  1 +
 arch/arm64/kernel/stacktrace.c    | 53 +++++++++++++++++++++++++++++++
 arch/arm64/kernel/vmlinux.lds.S   | 10 ++++++
 4 files changed, 76 insertions(+)

diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index 9906541a6861..616bad74e297 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -68,4 +68,16 @@
 		SYM_FUNC_END_ALIAS(x);		\
 		SYM_FUNC_END_ALIAS(__pi_##x)
 
+/*
+ * Record the address range of each SYM_CODE function in a struct code_range
+ * in a special section.
+ */
+#define SYM_CODE_END(name)				\
+	SYM_END(name, SYM_T_NONE)			;\
+	99:						;\
+	.pushsection "sym_code_functions", "aw"		;\
+	.quad	name					;\
+	.quad	99b					;\
+	.popsection
+
 #endif
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
index e4ad9db53af1..c84c71063d6e 100644
--- a/arch/arm64/include/asm/sections.h
+++ b/arch/arm64/include/asm/sections.h
@@ -21,5 +21,6 @@ extern char __exittext_begin[], __exittext_end[];
 extern char __irqentry_text_start[], __irqentry_text_end[];
 extern char __mmuoff_data_start[], __mmuoff_data_end[];
 extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
+extern char __sym_code_functions_start[], __sym_code_functions_end[];
 
 #endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b60f8a20ba64..26dbdd4fff77 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,6 +18,31 @@
 #include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
+struct code_range {
+	unsigned long	start;
+	unsigned long	end;
+};
+
+static struct code_range	*sym_code_functions;
+static int			num_sym_code_functions;
+
+int __init init_sym_code_functions(void)
+{
+	size_t size = (unsigned long)__sym_code_functions_end -
+		      (unsigned long)__sym_code_functions_start;
+
+	sym_code_functions = (struct code_range *)__sym_code_functions_start;
+	/*
+	 * Order it so that sym_code_functions is not visible before
+	 * num_sym_code_functions.
+	 */
+	smp_mb();
+	num_sym_code_functions = size / sizeof(struct code_range);
+
+	return 0;
+}
+early_initcall(init_sym_code_functions);
+
 /*
  * AArch64 PCS assigns the frame pointer to x29.
  *
@@ -185,6 +210,10 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
  */
 static bool notrace unwind_is_reliable(struct stackframe *frame)
 {
+	const struct code_range *range;
+	unsigned long pc;
+	int i;
+
 	/*
 	 * If the PC is not a known kernel text address, then we cannot
 	 * be sure that a subsequent unwind will be reliable, as we
@@ -192,6 +221,30 @@ static bool notrace unwind_is_reliable(struct stackframe *frame)
 	 */
 	if (!__kernel_text_address(frame->pc))
 		return false;
+
+	/*
+	 * Check the return PC against sym_code_functions[]. If there is a
+	 * match, then the consider the stack frame unreliable.
+	 *
+	 * As SYM_CODE functions don't follow the usual calling conventions,
+	 * we assume by default that any SYM_CODE function cannot be unwound
+	 * reliably.
+	 *
+	 * Note that this includes:
+	 *
+	 * - Exception handlers and entry assembly
+	 * - Trampoline assembly (e.g., ftrace, kprobes)
+	 * - Hypervisor-related assembly
+	 * - Hibernation-related assembly
+	 * - CPU start-stop, suspend-resume assembly
+	 * - Kernel relocation assembly
+	 */
+	pc = frame->pc;
+	for (i = 0; i < num_sym_code_functions; i++) {
+		range = &sym_code_functions[i];
+		if (pc >= range->start && pc < range->end)
+			return false;
+	}
 	return true;
 }
 
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 709d2c433c5e..2bf769f45b54 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -111,6 +111,14 @@ jiffies = jiffies_64;
 #define TRAMP_TEXT
 #endif
 
+#define SYM_CODE_FUNCTIONS				\
+	. = ALIGN(16);					\
+	.symcode : AT(ADDR(.symcode) - LOAD_OFFSET) {	\
+		__sym_code_functions_start = .;		\
+		KEEP(*(sym_code_functions))		\
+		__sym_code_functions_end = .;		\
+	}
+
 /*
  * The size of the PE/COFF section that covers the kernel image, which
  * runs from _stext to _edata, must be a round multiple of the PE/COFF
@@ -196,6 +204,8 @@ SECTIONS
 	swapper_pg_dir = .;
 	. += PAGE_SIZE;
 
+	SYM_CODE_FUNCTIONS
+
 	. = ALIGN(SEGMENT_ALIGN);
 	__init_begin = .;
 	__inittext_begin = .;
-- 
2.25.1



From madvenka at linux.microsoft.com  Thu Aug 12 12:17:43 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Thu, 12 Aug 2021 14:17:43 -0500
Subject: [RFC PATCH v8 0/4] arm64: Reorganize the unwinder and implement
 stack trace reliability checks
In-Reply-To: <20210812190603.25326-1-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
Message-ID: <5b832c8c-3b8f-9cb4-0c3c-85a6cca52d43@linux.microsoft.com>

OK. So, this time the threading is proper. Please review version 8.
It is identical to version 7 except for the version number and
threading.

Please disregard all emails sent as RFC PATCH v7 for this series. Again,
apologies for screwing the threading up.

Madhavan

On 8/12/21 2:05 PM, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Make all stack walking functions use arch_stack_walk()
> ======================================================
> 
> Currently, there are multiple functions in ARM64 code that walk the
> stack using start_backtrace() and unwind_frame(). Convert all of
> them to use arch_stack_walk(). This makes maintenance easier.
> 
> Reorganize the unwinder code for better consistency and maintenance
> ===================================================================
> 
> Rename unwinder functions to unwind_*() similar to other architectures
> for naming consistency.
> 
> Annotate all of the unwind_*() functions with notrace so they cannot be
> ftraced and NOKPROBE_SYMBOL() so they cannot be kprobed. Ftrace and Kprobe
> code can call the unwinder.
> 
> Redefine the unwinder loop and make it similar to other architectures.
> Define the following:
> 
> 	unwind_start(&frame, task, fp, pc);
> 	while (unwind_consume(&frame, consume_entry, cookie))
> 		unwind_next(&frame);
> 	return !unwind_failed(&frame);
> 
> unwind_start()
> 	Same as the original start_backtrace().
> 
> unwind_consume()
> 	This new function does two things:
> 
> 	- Calls consume_entry() to consume the return PC.
> 
> 	- Implements checks to determine whether the unwind should continue
> 	  or terminate.
> 
> unwind_next()
> 	Same as the original unwind_frame() except:
> 
> 	- the stack trace termination check has been moved from here to
> 	  unwind_consume(). So, unwind_next() assumes that the fp is valid.
> 
> 	- unwind_frame() used to return an error value. This function only
> 	  sets internal state and does not return anything. The state is
> 	  retrieved via a helper. See next.
> 
> unwind_failed()
> 	Return a boolean to indicate whether the stack trace completed
> 	successfully or failed. arch_stack_walk() ignores the return
> 	value. But arch_stack_walk_reliable() in the future will look
> 	at the return value.
> 
> Unwind status
> 	Introduce a new flag called "failed" in struct stackframe. Set this
> 	flag when an error is encountered. If this flag is set, terminate
> 	the unwind. Also, let the unwinder return the status to the caller.
> 
> Reliability checks
> ==================
> 
> There are some kernel features and conditions that make a stack trace
> unreliable. Callers may require the unwinder to detect these cases.
> E.g., livepatch.
> 
> Introduce a new function called unwind_is_reliable() that will detect
> these cases and return a boolean.
> 
> Introduce a new argument to unwind() called "need_reliable" so a caller
> can tell unwind() that it requires a reliable stack trace. For such a
> caller, any unreliability in the stack trace must be treated as a fatal
> error and the unwind must be aborted.
> 
> Call unwind_is_reliable() from unwind_consume() like this:
> 
> 	if (frame->need_reliable && !unwind_is_reliable(frame)) {
> 		frame->failed = true;
> 		return false;
> 	}
> 
> arch_stack_walk() passes "false" for need_reliable because its callers
> don't care about reliability. arch_stack_walk() is used for debug and
> test purposes.
> 
> Introduce arch_stack_walk_reliable() for ARM64. This works like
> arch_stack_walk() except for two things:
> 
> 	- It passes "true" for need_reliable.
> 
> 	- It returns -EINVAL if unwind() aborts.
> 
> Introduce the first reliability check in unwind_is_reliable() - If
> a return PC is not a valid kernel text address, consider the stack
> trace unreliable. It could be some generated code.
> 
> Other reliability checks will be added in the future. Until all of the
> checks are in place, arch_stack_walk_reliable() may not be used by
> livepatch. But it may be used by debug and test code.
> 
> SYM_CODE check
> ==============
> 
> SYM_CODE functions do not follow normal calling conventions. They cannot
> be unwound reliably using the frame pointer. Collect the address ranges
> of these functions in a special section called "sym_code_functions".
> 
> In unwind_is_reliable(), check the return PC against these ranges. If a
> match is found, then consider the stack trace unreliable. This is the
> second reliability check introduced by this work.
> 
> Last stack frame
> ----------------
> 
> If a SYM_CODE function occurs in the very last frame in the stack trace,
> then the stack trace is not considered unreliable. This is because there
> is no more unwinding to do. Examples:
> 
> 	- EL0 exception stack traces end in the top level EL0 exception
> 	  handlers.
> 
> 	- All kernel thread stack traces end in ret_from_fork().
> ---
> Changelog:
> 
> v8:
> 	From Mark Rutland:
> 
> 	- Make the unwinder loop similar to other architectures.
> 
> 	- Keep details to within the unwinder functions and return a simple
> 	  boolean to the caller.
> 
> 	- Convert some of the current code that contains unwinder logic to
> 	  simply use arch_stack_walk(). I have converted all of them.
> 
> 	- Do not copy sym_code_functions[]. Just place it in rodata for now.
> 
> 	- Have the main loop check for termination conditions rather than
> 	  having unwind_frame() check for them. In other words, let
> 	  unwind_frame() assume that the fp is valid.
> 
> 	- Replace the big comment for SYM_CODE functions with a shorter
> 	  comment.
> 
> 		/*
> 		 * As SYM_CODE functions don't follow the usual calling
> 		 * conventions, we assume by default that any SYM_CODE function
> 		 * cannot be unwound reliably.
> 		 *
> 		 * Note that this includes:
> 		 *
> 		 * - Exception handlers and entry assembly
> 		 * - Trampoline assembly (e.g., ftrace, kprobes)
> 		 * - Hypervisor-related assembly
> 		 * - Hibernation-related assembly
> 		 * - CPU start-stop, suspend-resume assembly
> 		 * - Kernel relocation assembly
> 		 */
> 
> v7:
> 	The Mailer screwed up the threading on this. So, I have resent this
> 	same series as version 8 with proper threading to avoid confusion.
> v6:
> 	From Mark Rutland:
> 
> 	- The per-frame reliability concept and flag are acceptable. But more
> 	  work is needed to make the per-frame checks more accurate and more
> 	  complete. E.g., some code reorg is being worked on that will help.
> 
> 	  I have now removed the frame->reliable flag and deleted the whole
> 	  concept of per-frame status. This is orthogonal to this patch series.
> 	  Instead, I have improved the unwinder to return proper return codes
> 	  so a caller can take appropriate action without needing per-frame
> 	  status.
> 
> 	- Remove the mention of PLTs and update the comment.
> 
> 	  I have replaced the comment above the call to __kernel_text_address()
> 	  with the comment suggested by Mark Rutland.
> 
> 	Other comments:
> 
> 	- Other comments on the per-frame stuff are not relevant because
> 	  that approach is not there anymore.
> 
> v5:
> 	From Keiya Nobuta:
> 	
> 	- The term blacklist(ed) is not to be used anymore. I have changed it
> 	  to unreliable. So, the function unwinder_blacklisted() has been
> 	  changed to unwinder_is_unreliable().
> 
> 	From Mark Brown:
> 
> 	- Add a comment for the "reliable" flag in struct stackframe. The
> 	  reliability attribute is not complete until all the checks are
> 	  in place. Added a comment above struct stackframe.
> 
> 	- Include some of the comments in the cover letter in the actual
> 	  code so that we can compare it with the reliable stack trace
> 	  requirements document for completeness. I have added a comment:
> 
> 	  	- above unwinder_is_unreliable() that lists the requirements
> 		  that are addressed by the function.
> 
> 		- above the __kernel_text_address() call about all the cases
> 		  the call covers.
> 
> v4:
> 	From Mark Brown:
> 
> 	- I was checking the return PC with __kernel_text_address() before
> 	  the Function Graph trace handling. Mark Brown felt that all the
> 	  reliability checks should be performed on the original return PC
> 	  once that is obtained. So, I have moved all the reliability checks
> 	  to after the Function Graph Trace handling code in the unwinder.
> 	  Basically, the unwinder should perform PC translations first (for
> 	  rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
> 	  Then, the reliability checks should be applied to the resulting
> 	  PC.
> 
> 	- Mark said to improve the naming of the new functions so they don't
> 	  collide with existing ones. I have used a prefix "unwinder_" for
> 	  all the new functions.
> 
> 	From Josh Poimboeuf:
> 
> 	- In the error scenarios in the unwinder, the reliable flag in the
> 	  stack frame should be set. Implemented this.
> 
> 	- Some of the other comments are not relevant to the new code as
> 	  I have taken a different approach in the new code. That is why
> 	  I have not made those changes. E.g., Ard wanted me to add the
> 	  "const" keyword to the global section array. That array does not
> 	  exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
> 	  the same array in a for loop.
> 
> 	Other changes:
> 
> 	- Add a new definition for SYM_CODE_END() that adds the address
> 	  range of the function to a special section called
> 	  "sym_code_functions".
> 
> 	- Include the new section under initdata in vmlinux.lds.S.
> 
> 	- Define an early_initcall() to copy the contents of the
> 	  "sym_code_functions" section to an array by the same name.
> 
> 	- Define a function unwinder_blacklisted() that compares a return
> 	  PC against sym_code_sections[]. If there is a match, mark the
> 	  stack trace unreliable. Call this from unwind_frame().
> 
> v3:
> 	- Implemented a sym_code_ranges[] array to contains sections bounds
> 	  for text sections that contain SYM_CODE_*() functions. The unwinder
> 	  checks each return PC against the sections. If it falls in any of
> 	  the sections, the stack trace is marked unreliable.
> 
> 	- Moved SYM_CODE functions from .text and .init.text into a new
> 	  text section called ".code.text". Added this section to
> 	  vmlinux.lds.S and sym_code_ranges[].
> 
> 	- Fixed the logic in the unwinder that handles Function Graph
> 	  Tracer return trampoline.
> 
> 	- Removed all the previous code that handles:
> 		- ftrace entry code for traced function
> 		- special_functions[] array that lists individual functions
> 		- kretprobe_trampoline() special case
> 
> v2
> 	- Removed the terminating entry { 0, 0 } in special_functions[]
> 	  and replaced it with the idiom { /* sentinel */ }.
> 
> 	- Change the ftrace trampoline entry ftrace_graph_call in
> 	  special_functions[] to ftrace_call + 4 and added explanatory
> 	  comments.
> 
> 	- Unnested #ifdefs in special_functions[] for FTRACE.
> 
> v1
> 	- Define a bool field in struct stackframe. This will indicate if
> 	  a stack trace is reliable.
> 
> 	- Implement a special_functions[] array that will be populated
> 	  with special functions in which the stack trace is considered
> 	  unreliable.
> 	
> 	- Using kallsyms_lookup(), get the address ranges for the special
> 	  functions and record them.
> 
> 	- Implement an is_reliable_function(pc). This function will check
> 	  if a given return PC falls in any of the special functions. If
> 	  it does, the stack trace is unreliable.
> 
> 	- Implement check_reliability() function that will check if a
> 	  stack frame is reliable. Call is_reliable_function() from
> 	  check_reliability().
> 
> 	- Before a return PC is checked against special_funtions[], it
> 	  must be validates as a proper kernel text address. Call
> 	  __kernel_text_address() from check_reliability().
> 
> 	- Finally, call check_reliability() from unwind_frame() for
> 	  each stack frame.
> 
> 	- Add EL1 exception handlers to special_functions[].
> 
> 		el1_sync();
> 		el1_irq();
> 		el1_error();
> 		el1_sync_invalid();
> 		el1_irq_invalid();
> 		el1_fiq_invalid();
> 		el1_error_invalid();
> 
> 	- The above functions are currently defined as LOCAL symbols.
> 	  Make them global so that they can be referenced from the
> 	  unwinder code.
> 
> 	- Add FTRACE trampolines to special_functions[]:
> 
> 		ftrace_graph_call()
> 		ftrace_graph_caller()
> 		return_to_handler()
> 
> 	- Add the kretprobe trampoline to special functions[]:
> 
> 		kretprobe_trampoline()
> 
> Previous versions and discussion
> ================================
> 
> v7: Mailer screwed up the threading. Sent the same as v8 with proper threading.
> v6: https://lore.kernel.org/linux-arm-kernel/20210630223356.58714-1-madvenka at linux.microsoft.com/
> v5: https://lore.kernel.org/linux-arm-kernel/20210526214917.20099-1-madvenka at linux.microsoft.com/
> v4: https://lore.kernel.org/linux-arm-kernel/20210516040018.128105-1-madvenka at linux.microsoft.com/
> v3: https://lore.kernel.org/linux-arm-kernel/20210503173615.21576-1-madvenka at linux.microsoft.com/
> v2: https://lore.kernel.org/linux-arm-kernel/20210405204313.21346-1-madvenka at linux.microsoft.com/
> v1: https://lore.kernel.org/linux-arm-kernel/20210330190955.13707-1-madvenka at linux.microsoft.com/
> Madhavan T. Venkataraman (4):
>   arm64: Make all stack walking functions use arch_stack_walk()
>   arm64: Reorganize the unwinder code for better consistency and
>     maintenance
>   arm64: Introduce stack trace reliability checks in the unwinder
>   arm64: Create a list of SYM_CODE functions, check return PC against
>     list
> 
>  arch/arm64/include/asm/linkage.h    |  12 ++
>  arch/arm64/include/asm/sections.h   |   1 +
>  arch/arm64/include/asm/stacktrace.h |  16 +-
>  arch/arm64/kernel/perf_callchain.c  |   5 +-
>  arch/arm64/kernel/process.c         |  39 ++--
>  arch/arm64/kernel/return_address.c  |   6 +-
>  arch/arm64/kernel/stacktrace.c      | 291 ++++++++++++++++++++--------
>  arch/arm64/kernel/time.c            |  22 ++-
>  arch/arm64/kernel/vmlinux.lds.S     |  10 +
>  9 files changed, 277 insertions(+), 125 deletions(-)
> 
> 
> base-commit: 36a21d51725af2ce0700c6ebcb6b9594aac658a6
> 


From alexandre.belloni at bootlin.com  Thu Aug 12 12:26:22 2021
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Thu, 12 Aug 2021 21:26:22 +0200
Subject: [PATCH 2/2] ARM: at91: dts: at91-sama5d2_xplained: Add comments
 for sama5d29
In-Reply-To: <20210812140758.28273-2-Hari.PrasathGE@microchip.com>
References: <20210812140758.28273-1-Hari.PrasathGE@microchip.com>
 <20210812140758.28273-2-Hari.PrasathGE@microchip.com>
Message-ID: <YRV13nfgpEEuOOxB@piout.net>

Hello,

On 12/08/2021 19:37:58+0530, Hari Prasath wrote:
> Add comments for the end user for modifying the DTS file for
> instantiating the sama5d29 SoC.
> 
> Signed-off-by: Hari Prasath <Hari.PrasathGE at microchip.com>
> ---
>  arch/arm/boot/dts/at91-sama5d2_xplained.dts | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
> index 627b7bf88d83..faa30063d9a9 100644
> --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
> +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
> @@ -6,6 +6,11 @@
>   *                2015 Nicolas Ferre <nicolas.ferre at atmel.com>
>   */
>  /dts-v1/;
> +/*
> + * Replace the line below with "sama5d29.dtsi" in order to instantiate the
> + * sama5d29 SoC of the sama5d2 family.Otherwise, leave it unchanged when
> + * using sama5d27 SoC for instance.
> + */

I guess it would be better to have a at91-sama5d29_xplained.dts (and we
should have had a at91-sama5d27_xplained.dts), else, you can't create an
image that will support both variants.


-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From sboyd at kernel.org  Thu Aug 12 12:33:19 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 12 Aug 2021 12:33:19 -0700
Subject: [PATCH v4 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <20210806082818.k3awj72j2yb2bbhe@pali>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
 <20210802144529.1520-4-pali@kernel.org>
 <162820981926.19113.12529765873453602213@swboyd.mtv.corp.google.com>
 <20210806082818.k3awj72j2yb2bbhe@pali>
Message-ID: <162879679919.19113.10297499909721773583@swboyd.mtv.corp.google.com>

Quoting Pali (2021-08-06 01:28:18)
> On Thursday 05 August 2021 17:30:19 Stephen Boyd wrote:
> > > diff --git a/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> > > new file mode 100644
> > > index 000000000000..5ef04f3affda
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> > > @@ -0,0 +1,49 @@
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/clock/marvell,armada-3700-uart-clock#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +title: Marvell Armada 3720 UART clocks
> > 
> > Please add a newline here
> > 
> > > +properties:
> > > +  compatible:
> > > +    const: marvell,armada-3700-uart-clock
> > 
> > Please add a newline here
> > 
> > > +  reg:
> > > +    items:
> > > +      - description: UART Clock Control Register
> > > +      - description: UART 2 Baud Rate Divisor Register
> > 
> > Please add a newline here
> > 
> > > +  clocks:
> > > +    description: |
> > > +      List of parent clocks suitable for UART from following set:
> > > +        "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal"
> > > +      UART clock can use one from this set and when more are provided
> > > +      then kernel would choose and configure the most suitable one.
> > > +      It is suggest to specify at least one TBG clock to achieve
> > > +      baudrates above 230400 and also to specify clock which bootloader
> > > +      used for UART (most probably xtal) for smooth boot log on UART.
> > 
> > Please use items and const like clock-names for the clocks property.
> 
> It is already there, see below.
> 
> > The description makes me feel like the DT is configuring the choices
> > available.
> 
> See description. It is kernel (driver) who is choosing one clock from
> the set and then configure it a UART clock.

Can that be done with assigned-clock-parents?

> 
> > Ideally, the clocks and clock-names properties are fixed in
> > length and never change unless the compatible changes.
> > 
> > Please add a newline here
> > 
> > > +  clock-names:
> > > +    items:
> > > +      - const: TBG-A-P
> > > +      - const: TBG-B-P
> > > +      - const: TBG-A-S
> > > +      - const: TBG-B-S
> > > +      - const: xtal
> > > +    minItems: 1
> > > +    maxItems: 5
> > 
> > Please add a newline here
> > 
> > > +  '#clock-cells':
> > > +    const: 1
> > 
> > Please add a newline here
> > 
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - clocks
> > > +  - clock-names
> > > +  - '#clock-cells'
> > 
> > Please add a newline here
> > 
> > > +additionalProperties: false
> > 
> > Please add a newline here
> > 
> > > +examples:
> > > +  - |
> > > +    uartclk: uartclk at 12000 {
> > > +      compatible = "marvell,armada-3700-uart-clock";
> > > +      reg = <0x12010 0x4>, <0x12210 0x4>;

The reg property looks like this is poking a mux that is part of a
larger device. What device is this actually part of? The uart hardware?

> > > +      clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>, <&xtalclk>;
> > > +      clock-names = "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal";


From zajec5 at gmail.com  Thu Aug 12 12:47:18 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Thu, 12 Aug 2021 21:47:18 +0200
Subject: [PATCH 3/5] arm64: Detect disabled HVC early
In-Reply-To: <20210812190213.2601506-4-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-4-maz@kernel.org>
Message-ID: <11c7b042-885f-ad48-7c5f-ad3dbd8f0340@gmail.com>

On 12.08.2021 21:02, Marc Zyngier wrote:
> Having HVC disabled from EL3 while the kernel is entered at EL2
> is a complete nightmare.
> 
> We end-up taking an UNDEF at the worse possible moment (checking
> for VHE) and even if we didn't, having KVM enabled would signify
> the premature end of the kernel.
> 
> Instead, try and detect this stupid case by issuing a HVC
> for HVC_RESET_VECTORS, which does nothing when the stubs
> are live. If we get HVC_STUB_ERR back, that's because the
> UNDEF handler has kicked in.
> 
> In this situation, close your eyes, block your nose, and gracefully
> pretend we have booted at EL1.
> 
> Reported-by: Rafa? Mi?ecki <zajec5 at gmail.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

This does the trick.

Tested-by: Rafa? Mi?ecki <rafal at milecki.pl>


From sboyd at kernel.org  Thu Aug 12 12:56:35 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 12 Aug 2021 12:56:35 -0700
Subject: [PATCH v4 1/4] clk: fractional-divider: Export approximation
 algorithm to the CCF users
In-Reply-To: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
Message-ID: <162879819529.19113.6409882476721828944@swboyd.mtv.corp.google.com>

Quoting Andy Shevchenko (2021-08-12 10:00:22)
> At least one user currently duplicates some functions that are provided
> by fractional divider module. Let's export approximation algorithm and
> replace the open-coded variant.
> 
> As a bonus the exported function will get better documentation in place.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Tested-by: Heiko Stuebner <heiko at sntech.de>
> Acked-by: Heiko Stuebner <heiko at sntech.de>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Aug 12 12:56:40 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 12 Aug 2021 12:56:40 -0700
Subject: [PATCH v4 2/4] clk: fractional-divider: Hide
 clk_fractional_divider_ops from wide audience
In-Reply-To: <20210812170025.67074-2-andriy.shevchenko@linux.intel.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
 <20210812170025.67074-2-andriy.shevchenko@linux.intel.com>
Message-ID: <162879820032.19113.3430851588211208927@swboyd.mtv.corp.google.com>

Quoting Andy Shevchenko (2021-08-12 10:00:23)
> The providers are all located in drivers/clk/ and hence no need
> to export the clock operations to wider audience. Hide them by
> moving to drivers/clk/clk-fractional-divider.h.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Aug 12 12:56:46 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 12 Aug 2021 12:56:46 -0700
Subject: [PATCH v4 3/4] clk: fractional-divider: Introduce POWER_OF_TWO_PS
 flag
In-Reply-To: <20210812170025.67074-3-andriy.shevchenko@linux.intel.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
 <20210812170025.67074-3-andriy.shevchenko@linux.intel.com>
Message-ID: <162879820623.19113.17032663481008109735@swboyd.mtv.corp.google.com>

Quoting Andy Shevchenko (2021-08-12 10:00:24)
> The newly introduced POWER_OF_TWO_PS flag, when set, makes the flow
> to skip the assumption that the caller will use an additional 2^scale
> prescaler to get the desired clock rate.
> 
> Reported-by: Liu Ying <victor.liu at nxp.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Aug 12 12:56:51 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 12 Aug 2021 12:56:51 -0700
Subject: [PATCH v4 4/4] clk: fractional-divider: Document the arithmetics
 used behind the code
In-Reply-To: <20210812170025.67074-4-andriy.shevchenko@linux.intel.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
 <20210812170025.67074-4-andriy.shevchenko@linux.intel.com>
Message-ID: <162879821159.19113.17550166363142634282@swboyd.mtv.corp.google.com>

Quoting Andy Shevchenko (2021-08-12 10:00:25)
> It appears that some code lines raise the question why they are needed
> and how they are participated in the calculus of the resulting values.
> 
> Document this in a form of the top comment in the module file.
> 
> Reported-by: Liu Ying <victor.liu at nxp.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> ---

Applied to clk-next


From dev at lynxeye.de  Thu Aug 12 12:47:12 2021
From: dev at lynxeye.de (Lucas Stach)
Date: Thu, 12 Aug 2021 21:47:12 +0200
Subject: [PATCH] arm64: dts: imx8mq-reform2: add sound support
Message-ID: <20210812194712.300116-1-dev@lynxeye.de>

This adds sound support to the Reform2.

It differs from the downstream implementation in that the codec
is used as the BCLK and FSYNC master and the i.MX8MQ only supplies
a fixed 25MHz MCLK from the oscillator. This allows to support
a wider range of audio rates by using the codec PLL and to shut
down the audio PLLs on the i.MX8MQ SoC side.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 .../boot/dts/freescale/imx8mq-mnt-reform2.dts | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts b/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
index 099b0472db5d..2535268f0984 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
@@ -40,6 +40,24 @@ reg_main_usb: regulator-main-usb {
 		regulator-max-microvolt = <5000000>;
 		vin-supply = <&reg_main_5v>;
 	};
+
+	sound {
+		compatible = "fsl,imx-audio-wm8960";
+		audio-cpu = <&sai2>;
+		audio-codec = <&wm8960>;
+		audio-routing =
+			"Headphone Jack", "HP_L",
+			"Headphone Jack", "HP_R",
+			"Ext Spk", "SPK_LP",
+			"Ext Spk", "SPK_LN",
+			"Ext Spk", "SPK_RP",
+			"Ext Spk", "SPK_RN",
+			"LINPUT1", "Mic Jack",
+			"Mic Jack", "MICB",
+			"LINPUT2", "Line In Jack",
+			"RINPUT2", "Line In Jack";
+		model = "wm8960-audio";
+	};
 };
 
 &fec1 {
@@ -51,6 +69,14 @@ &i2c3 {
 	pinctrl-0 = <&pinctrl_i2c3>;
 	status = "okay";
 
+	wm8960: codec at 1a {
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+		clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;
+	};
+
 	rtc at 68 {
 		compatible = "nxp,pcf8523";
 		reg = <0x68>;
@@ -89,6 +115,17 @@ &reg_soc_gpu_vpu {
 	vin-supply = <&reg_main_5v>;
 };
 
+&sai2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai2>;
+	assigned-clocks = <&clk IMX8MQ_CLK_SAI2>;
+	assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+	assigned-clock-rates = <25000000>;
+	fsl,sai-mclk-direction-output;
+	fsl,sai-asynchronous;
+	status = "okay";
+};
+
 &snvs_rtc {
 	status = "disabled";
 };
@@ -144,6 +181,18 @@ MX8MQ_IOMUXC_SAI5_RXD2_GPIO3_IO23		0x16
 		>;
 	};
 
+	pinctrl_sai2: sai2grp {
+		fsl,pins = <
+			MX8MQ_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0		0xd6
+			MX8MQ_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC		0xd6
+			MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK		0xd6
+			MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC		0xd6
+			MX8MQ_IOMUXC_SAI2_RXC_SAI2_RX_BCLK		0xd6
+			MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK		0xd6
+			MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0		0xd6
+		>;
+	};
+
 	pinctrl_uart2: uart2grp {
 		fsl,pins = <
 			MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX		0x45
-- 
2.31.1



From festevam at gmail.com  Thu Aug 12 12:57:06 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 12 Aug 2021 16:57:06 -0300
Subject: [PATCH] arm64: dts: imx8mq-reform2: add sound support
In-Reply-To: <20210812194712.300116-1-dev@lynxeye.de>
References: <20210812194712.300116-1-dev@lynxeye.de>
Message-ID: <CAOMZO5DNdG683NZr8gvFNBR6W-H7_1hPqTvQCU73pNpN5P2mEg@mail.gmail.com>

Hi Lucas,

On Thu, Aug 12, 2021 at 4:47 PM Lucas Stach <dev at lynxeye.de> wrote:
>
> This adds sound support to the Reform2.
>
> It differs from the downstream implementation in that the codec
> is used as the BCLK and FSYNC master and the i.MX8MQ only supplies
> a fixed 25MHz MCLK from the oscillator. This allows to support
> a wider range of audio rates by using the codec PLL and to shut
> down the audio PLLs on the i.MX8MQ SoC side.
>
> Signed-off-by: Lucas Stach <dev at lynxeye.de>

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From zajec5 at gmail.com  Thu Aug 12 12:58:06 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Thu, 12 Aug 2021 21:58:06 +0200
Subject: [PATCH 4/5] arm64: Warn on booting at EL2 with HVC disabled
In-Reply-To: <20210812190213.2601506-5-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-5-maz@kernel.org>
Message-ID: <c13ee5ca-84e2-6615-375f-9e7e7f6b490f@gmail.com>

On 12.08.2021 21:02, Marc Zyngier wrote:
> Now that we are able to paper over the gigantic stupidity that
> booting at EL2 with SCR_EL3.HCE==0 is, let's taint WARN_TAINT()
> when detecting this situation.
> 
> Yes, this is *LOUD*.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Tested-by: Rafa? Mi?ecki <rafal at milecki.pl>

This replaces:
CPU: All CPU(s) started at EL1

with:
------------[ cut here ]------------
CPU: CPUs downgraded to EL1, HVC disabled
WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/smp.c:429 smp_cpus_done+0xac/0xe8
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.14.0-rc5-g86fc10657896 #41
Hardware name: Asus GT-AC5300 (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
pc : smp_cpus_done+0xac/0xe8
lr : smp_cpus_done+0xac/0xe8
sp : ffffffc01002be00
x29: ffffffc01002be00 x28: 0000000000000000 x27: 0000000000000000
x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
x23: ffffffc010ab4000 x22: 0000000000000000 x21: 0000000000000000
x20: ffffffc0107b7e74 x19: ffffffc010a78000 x18: 0000000000000001
x17: ffffffc010a9ee40 x16: 0000000000000000 x15: 000042496b0a18f2
x14: fffffffffffc0f87 x13: 0000000000000039 x12: ffffff80010b03b0
x11: 00000000ffffffea x10: ffffffc010a5eb50 x9 : 0000000000000001
x8 : 0000000000000001 x7 : 0000000000017fe8 x6 : c0000000ffffefff
x5 : 0000000000057fa8 x4 : 0000000000000000 x3 : 0000000000000000
x2 : 00000000ffffffff x1 : a8d68d1fd96fdc00 x0 : 0000000000000000
Call trace:
  smp_cpus_done+0xac/0xe8
  smp_init+0x68/0x78
  kernel_init_freeable+0xd0/0x214
  kernel_init+0x24/0x120
  ret_from_fork+0x10/0x18
---[ end trace a7d4af835e9d6e6b ]---


BEFORE:

smp: Bringing up secondary CPUs ...
Detected VIPT I-cache on CPU1
CPU1: Booted secondary processor 0x0000000001 [0x420f1000]
Detected VIPT I-cache on CPU2
CPU2: Booted secondary processor 0x0000000002 [0x420f1000]
Detected VIPT I-cache on CPU3
CPU3: Booted secondary processor 0x0000000003 [0x420f1000]
smp: Brought up 1 node, 4 CPUs
SMP: Total of 4 processors activated.
CPU features: detected: 32-bit EL0 Support
CPU features: detected: 32-bit EL1 Support
CPU features: detected: CRC32 instructions
CPU: All CPU(s) started at EL1


AFTER:

smp: Bringing up secondary CPUs ...
Detected VIPT I-cache on CPU1
CPU1: Booted secondary processor 0x0000000001 [0x420f1000]
Detected VIPT I-cache on CPU2
CPU2: Booted secondary processor 0x0000000002 [0x420f1000]
Detected VIPT I-cache on CPU3
CPU3: Booted secondary processor 0x0000000003 [0x420f1000]
smp: Brought up 1 node, 4 CPUs
SMP: Total of 4 processors activated.
CPU features: detected: 32-bit EL0 Support
CPU features: detected: 32-bit EL1 Support
CPU features: detected: CRC32 instructions
------------[ cut here ]------------
CPU: CPUs downgraded to EL1, HVC disabled
WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/smp.c:429 smp_cpus_done+0xac/0xe8
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.14.0-rc5-g86fc10657896 #41
Hardware name: Asus GT-AC5300 (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
pc : smp_cpus_done+0xac/0xe8
lr : smp_cpus_done+0xac/0xe8
sp : ffffffc01002be00
x29: ffffffc01002be00 x28: 0000000000000000 x27: 0000000000000000
x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
x23: ffffffc010ab4000 x22: 0000000000000000 x21: 0000000000000000
x20: ffffffc0107b7e74 x19: ffffffc010a78000 x18: 0000000000000001
x17: ffffffc010a9ee40 x16: 0000000000000000 x15: 000042496b0a18f2
x14: fffffffffffc0f87 x13: 0000000000000039 x12: ffffff80010b03b0
x11: 00000000ffffffea x10: ffffffc010a5eb50 x9 : 0000000000000001
x8 : 0000000000000001 x7 : 0000000000017fe8 x6 : c0000000ffffefff
x5 : 0000000000057fa8 x4 : 0000000000000000 x3 : 0000000000000000
x2 : 00000000ffffffff x1 : a8d68d1fd96fdc00 x0 : 0000000000000000
Call trace:
  smp_cpus_done+0xac/0xe8
  smp_init+0x68/0x78
  kernel_init_freeable+0xd0/0x214
  kernel_init+0x24/0x120
  ret_from_fork+0x10/0x18
---[ end trace a7d4af835e9d6e6b ]---


From pali at kernel.org  Thu Aug 12 13:08:04 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 12 Aug 2021 22:08:04 +0200
Subject: [PATCH v4 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell,armada-3700-uart-clock
In-Reply-To: <162879679919.19113.10297499909721773583@swboyd.mtv.corp.google.com>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210802144529.1520-1-pali@kernel.org>
 <20210802144529.1520-4-pali@kernel.org>
 <162820981926.19113.12529765873453602213@swboyd.mtv.corp.google.com>
 <20210806082818.k3awj72j2yb2bbhe@pali>
 <162879679919.19113.10297499909721773583@swboyd.mtv.corp.google.com>
Message-ID: <20210812200804.i4kbcs6ut27mapd3@pali>

On Thursday 12 August 2021 12:33:19 Stephen Boyd wrote:
> Quoting Pali (2021-08-06 01:28:18)
> > On Thursday 05 August 2021 17:30:19 Stephen Boyd wrote:
> > > > diff --git a/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> > > > new file mode 100644
> > > > index 000000000000..5ef04f3affda
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> > > > @@ -0,0 +1,49 @@
> > > > +# SPDX-License-Identifier: GPL-2.0
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/clock/marvell,armada-3700-uart-clock#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +title: Marvell Armada 3720 UART clocks
> > > 
> > > Please add a newline here
> > > 
> > > > +properties:
> > > > +  compatible:
> > > > +    const: marvell,armada-3700-uart-clock
> > > 
> > > Please add a newline here
> > > 
> > > > +  reg:
> > > > +    items:
> > > > +      - description: UART Clock Control Register
> > > > +      - description: UART 2 Baud Rate Divisor Register
> > > 
> > > Please add a newline here
> > > 
> > > > +  clocks:
> > > > +    description: |
> > > > +      List of parent clocks suitable for UART from following set:
> > > > +        "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal"
> > > > +      UART clock can use one from this set and when more are provided
> > > > +      then kernel would choose and configure the most suitable one.
> > > > +      It is suggest to specify at least one TBG clock to achieve
> > > > +      baudrates above 230400 and also to specify clock which bootloader
> > > > +      used for UART (most probably xtal) for smooth boot log on UART.
> > > 
> > > Please use items and const like clock-names for the clocks property.
> > 
> > It is already there, see below.
> > 
> > > The description makes me feel like the DT is configuring the choices
> > > available.
> > 
> > See description. It is kernel (driver) who is choosing one clock from
> > the set and then configure it a UART clock.
> 
> Can that be done with assigned-clock-parents?

I'm not sure if it is possible. Frequencies of "TBG-A-P", "TBG-B-P",
"TBG-A-S" and "TBG-B-S" clocks are set by firmware and frequency of
"xtal" by strapping pin. So they are not static constants. And also
kernel cannot change frequency of these clocks.

Driver reads frequencies of these clocks and choose the one which is the
most suitable for UART at runtime.

> > > Ideally, the clocks and clock-names properties are fixed in
> > > length and never change unless the compatible changes.
> > > 
> > > Please add a newline here
> > > 
> > > > +  clock-names:
> > > > +    items:
> > > > +      - const: TBG-A-P
> > > > +      - const: TBG-B-P
> > > > +      - const: TBG-A-S
> > > > +      - const: TBG-B-S
> > > > +      - const: xtal
> > > > +    minItems: 1
> > > > +    maxItems: 5
> > > 
> > > Please add a newline here
> > > 
> > > > +  '#clock-cells':
> > > > +    const: 1
> > > 
> > > Please add a newline here
> > > 
> > > > +required:
> > > > +  - compatible
> > > > +  - reg
> > > > +  - clocks
> > > > +  - clock-names
> > > > +  - '#clock-cells'
> > > 
> > > Please add a newline here
> > > 
> > > > +additionalProperties: false
> > > 
> > > Please add a newline here
> > > 
> > > > +examples:
> > > > +  - |
> > > > +    uartclk: uartclk at 12000 {
> > > > +      compatible = "marvell,armada-3700-uart-clock";
> > > > +      reg = <0x12010 0x4>, <0x12210 0x4>;
> 
> The reg property looks like this is poking a mux that is part of a
> larger device. What device is this actually part of? The uart hardware?

Yes, UART hardware.

> > > > +      clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>, <&xtalclk>;
> > > > +      clock-names = "TBG-A-P", "TBG-B-P", "TBG-A-S", "TBG-B-S", "xtal";


From broonie at kernel.org  Thu Aug 12 13:11:43 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 12 Aug 2021 21:11:43 +0100
Subject: [PATCH] arm64/sve: Add some comments for sve_save/load_state()
Message-ID: <20210812201143.35578-1-broonie@kernel.org>

The use of macros for the actual function bodies means legibility is always
going to be a bit of a challenge, especially while we can't rely on SVE
support in the toolchain, but this helps a little.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/entry-fpsimd.S | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index 0a7a64753878..196e921f61de 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -33,11 +33,24 @@ SYM_FUNC_END(fpsimd_load_state)
 
 #ifdef CONFIG_ARM64_SVE
 
+/*
+ * Save the SVE state
+ *
+ * x0 - pointer to buffer for state
+ * x1 - pointer to storage for FPSR
+ */
 SYM_FUNC_START(sve_save_state)
 	sve_save 0, x1, 2
 	ret
 SYM_FUNC_END(sve_save_state)
 
+/*
+ * Load the SVE state
+ *
+ * x0 - pointer to buffer for state
+ * x1 - pointer to storage for FPSR
+ * x2 - VQ-1
+ */
 SYM_FUNC_START(sve_load_state)
 	sve_load 0, x1, x2, 3, x4
 	ret
-- 
2.20.1



From arnd at kernel.org  Thu Aug 12 13:41:30 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:41:30 +0200
Subject: [GIT PULL 1/3] SoC changes for omaps for v5.15
In-Reply-To: <pull-1628153040-834155@atomide.com>
References: <pull-1628153040-834155@atomide.com>
Message-ID: <162880088338.1372369.14302259325676706777.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Thu, 5 Aug 2021 11:46:42 +0300, Tony Lindgren wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/soc-signed
> 
> [...]

Merged into arm/soc, thanks!

merge commit: c8d9a986d0f2466d11ffd07e66fed9f4a34631a7

       Arnd


From arnd at kernel.org  Thu Aug 12 13:41:31 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:41:31 +0200
Subject: [GIT PULL 1/3] Two missed omap Kconfig patches for v5.15
In-Reply-To: <pull-1628751694-126144@atomide.com>
References: <pull-1628751694-126144@atomide.com>
Message-ID: <162880088346.1372369.540207205848005898.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Thu, 12 Aug 2021 10:03:42 +0300, Tony Lindgren wrote:
> The following changes since commit 8d5a937f10ed091e14fc57a4158f59983e2934cf:
> 
>   MAINTAINERS: Adopt SanCloud dts files as supported (2021-07-27 11:54:52 +0300)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/soc-late-signed
> 
> [...]

Merged into arm/soc, thanks!

merge commit: e694952772a7df091a6cffe828409843f53c9822

       Arnd


From pgwipeout at gmail.com  Thu Aug 12 13:41:09 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:09 -0400
Subject: [PATCH v2 1/8] dt-bindings: soc: rockchip: add rk3568-usb2phy-grf
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-2-pgwipeout@gmail.com>

Add the documentation for the rk3568-usb2phy-grf node, which is separate
from the usb2phy node on this chip.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 Documentation/devicetree/bindings/soc/rockchip/grf.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
index fa010df51a5c..78ff91db0f06 100644
--- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
+++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
@@ -15,6 +15,7 @@ properties:
       - items:
           - enum:
               - rockchip,rk3288-sgrf
+              - rockchip,rk3568-usb2phy-grf
               - rockchip,rv1108-usbgrf
           - const: syscon
       - items:
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:08 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:08 -0400
Subject: [PATCH v2 0/8] phy-rockchip-inno-usb2: support rk356x usb2phy
Message-ID: <20210812204116.2303617-1-pgwipeout@gmail.com>

Good Afternoon,

This is my series to support the usb2 phy devices on the rk356x.
The rk356x phy has a single muxed interrupt and has moved the usb2phy
nodes out of the grf and into their own nodes.
The phy needs to tie back into the grf for register control, similar to
the rv1108.
By moving the phys into their own nodes, they now have full
#address_cells = 2 register addresses, but they still reside below the 32bit
mmio range.

This driver series only supports the host configuration for the rk356x.
I have have tested it on the following:
rk3566 - Pine64 Quartz64 Model A
rk3399 - Pine64 Rockpro64

Please provide feedback and comments as you see fit.

Changelog:
v2:
- correct the order of the usb2phy-grf dt-bindings patch, thanks Johan
- correct the conditional requirements of phy-rockchip-inno-usb2, thanks
  Johan
- drop increase generic-ohci clocks patch, thanks Heiko
- correct rk356x.dtsi ordering
- fix a dtbs-check callout

Peter Geis (8):
  dt-bindings: soc: rockchip: add rk3568-usb2phy-grf
  dt-bindings: phy: phy-rockchip-inno-usb2: add rk3568 documentation
  phy: phy-rockchip-inno-usb2: support #address_cells = 2
  phy: phy-rockchip-inno-usb2: support standalone phy nodes
  phy: phy-rockchip-inno-usb2: support muxed interrupts
  phy: phy-rockchip-inno-usb2: add rk3568 support
  arm64: dts: rockchip: add usb2 nodes to rk3568 device tree
  arm64: dts: rockchip: add Quartz64-A usb2 support

 .../bindings/phy/phy-rockchip-inno-usb2.yaml  |  31 ++-
 .../devicetree/bindings/soc/rockchip/grf.yaml |   1 +
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   |  52 ++++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |  98 +++++++
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 259 ++++++++++++++----
 5 files changed, 383 insertions(+), 58 deletions(-)

-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:10 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:10 -0400
Subject: [PATCH v2 2/8] dt-bindings: phy: phy-rockchip-inno-usb2: add rk3568
 documentation
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-3-pgwipeout@gmail.com>

The rk3568 usb2phy node is a standalone node with a single muxed
interrupt.
Add documentation for it to phy-rockchip-inno-usb2.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 .../bindings/phy/phy-rockchip-inno-usb2.yaml  | 31 ++++++++++++++++---
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
index 5bebd86bf8b6..d2a749c3f9a3 100644
--- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
@@ -18,6 +18,7 @@ properties:
       - rockchip,rk3328-usb2phy
       - rockchip,rk3366-usb2phy
       - rockchip,rk3399-usb2phy
+      - rockchip,rk3568-usb2phy
       - rockchip,rv1108-usb2phy
 
   reg:
@@ -50,6 +51,9 @@ properties:
     description:
       Phandle to the extcon device providing the cable state for the otg phy.
 
+  interrupts:
+    description: Muxed interrupt for both ports
+
   rockchip,usbgrf:
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
@@ -78,8 +82,6 @@ properties:
 
     required:
       - "#phy-cells"
-      - interrupts
-      - interrupt-names
 
   otg-port:
     type: object
@@ -109,8 +111,6 @@ properties:
 
     required:
       - "#phy-cells"
-      - interrupts
-      - interrupt-names
 
 required:
   - compatible
@@ -120,6 +120,29 @@ required:
   - host-port
   - otg-port
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: rockchip,rk3568-usb2phy
+      then:
+        properties:
+          interrupts:
+            maxItems: 1
+        required:
+          - interrupts
+      else:
+        properties:
+          host-port:
+            required:
+              - interrupts
+              - interrupt-names
+          otg-port:
+            required:
+              - interrupts
+              - interrupt-names
+
 additionalProperties: false
 
 examples:
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:11 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:11 -0400
Subject: [PATCH v2 3/8] phy: phy-rockchip-inno-usb2: support #address_cells = 2
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-4-pgwipeout@gmail.com>

New Rockchip devices have the usb phy nodes as standalone devices.
These nodes have register nodes with #address_cells = 2, but only use 32
bit addresses.

Adjust the driver to check if the returned address is "0", and adjust
the index in that case.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index beacac1dd253..5d2916143df7 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -1098,12 +1098,21 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 		rphy->usbgrf = NULL;
 	}
 
-	if (of_property_read_u32(np, "reg", &reg)) {
+	if (of_property_read_u32_index(np, "reg", 0, &reg)) {
 		dev_err(dev, "the reg property is not assigned in %pOFn node\n",
 			np);
 		return -EINVAL;
 	}
 
+	/* support address_cells=2 */
+	if (reg == 0) {
+		if (of_property_read_u32_index(np, "reg", 1, &reg)) {
+			dev_err(dev, "the reg property is not assigned in %pOFn node\n",
+				np);
+			return -EINVAL;
+		}
+	}
+
 	rphy->dev = dev;
 	phy_cfgs = match->data;
 	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:12 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:12 -0400
Subject: [PATCH v2 4/8] phy: phy-rockchip-inno-usb2: support standalone phy
 nodes
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-5-pgwipeout@gmail.com>

New Rockchip devices have the usb2 phy devices as standalone nodes
instead of children of the grf node.
Allow the driver to find the grf node from a phandle.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 5d2916143df7..84a0c1d697da 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -1081,12 +1081,19 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	if (!dev->parent || !dev->parent->of_node)
-		return -EINVAL;
+	if (!dev->parent || !dev->parent->of_node) {
+		rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
+		if (IS_ERR(rphy->grf)) {
+			dev_err(dev, "failed to locate usbgrf\n");
+			return PTR_ERR(rphy->grf);
+		}
+	}
 
-	rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
-	if (IS_ERR(rphy->grf))
-		return PTR_ERR(rphy->grf);
+	else {
+		rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
+			if (IS_ERR(rphy->grf))
+				return PTR_ERR(rphy->grf);
+	}
 
 	if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
 		rphy->usbgrf =
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:13 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:13 -0400
Subject: [PATCH v2 5/8] phy: phy-rockchip-inno-usb2: support muxed interrupts
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-6-pgwipeout@gmail.com>

The rk3568 usb2phy has a single muxed interrupt that handles all
interrupts.
Allow the driver to plug in only a single interrupt as necessary.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 168 +++++++++++++-----
 1 file changed, 119 insertions(+), 49 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 84a0c1d697da..fdeb2e7c937a 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -204,6 +204,7 @@ struct rockchip_usb2phy_port {
  * @dcd_retries: The retry count used to track Data contact
  *		 detection process.
  * @edev: extcon device for notification registration
+ * @irq: muxed interrupt for single irq configuration
  * @phy_cfg: phy register configuration, assigned by driver data.
  * @ports: phy port instance.
  */
@@ -218,6 +219,7 @@ struct rockchip_usb2phy {
 	enum power_supply_type	chg_type;
 	u8			dcd_retries;
 	struct extcon_dev	*edev;
+	int			irq;
 	const struct rockchip_usb2phy_cfg	*phy_cfg;
 	struct rockchip_usb2phy_port	ports[USB2PHY_NUM_PORTS];
 };
@@ -934,6 +936,102 @@ static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
 		return IRQ_NONE;
 }
 
+static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
+{
+	struct rockchip_usb2phy *rphy = data;
+	struct rockchip_usb2phy_port *rport;
+	irqreturn_t ret = IRQ_NONE;
+	unsigned int index;
+
+	for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
+		rport = &rphy->ports[index];
+		if (!rport->phy)
+			continue;
+
+		/* Handle linestate irq for both otg port and host port */
+		ret = rockchip_usb2phy_linestate_irq(irq, rport);
+	}
+
+	return ret;
+}
+
+static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy,
+					  struct rockchip_usb2phy_port *rport,
+					  struct device_node *child_np)
+{
+	int ret;
+
+	/*
+	 * If the usb2 phy used combined irq for otg and host port,
+	 * don't need to init otg and host port irq separately.
+	 */
+	if (rphy->irq > 0)
+		return 0;
+
+	switch (rport->port_id) {
+	case USB2PHY_PORT_HOST:
+		rport->ls_irq = of_irq_get_byname(child_np, "linestate");
+		if (rport->ls_irq < 0) {
+			dev_err(rphy->dev, "no linestate irq provided\n");
+			return rport->ls_irq;
+		}
+
+		ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
+						rockchip_usb2phy_linestate_irq,
+						IRQF_ONESHOT,
+						"rockchip_usb2phy", rport);
+		if (ret) {
+			dev_err(rphy->dev, "failed to request linestate irq handle\n");
+			return ret;
+		}
+		break;
+	case USB2PHY_PORT_OTG:
+		/*
+		 * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
+		 * interrupts muxed together, so probe the otg-mux interrupt first,
+		 * if not found, then look for the regular interrupts one by one.
+		 */
+		rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
+		if (rport->otg_mux_irq > 0) {
+			ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
+							NULL,
+							rockchip_usb2phy_otg_mux_irq,
+							IRQF_ONESHOT,
+							"rockchip_usb2phy_otg",
+							rport);
+			if (ret) {
+				dev_err(rphy->dev,
+					"failed to request otg-mux irq handle\n");
+				return ret;
+			}
+		} else {
+			rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
+			if (rport->bvalid_irq < 0) {
+				dev_err(rphy->dev, "no vbus valid irq provided\n");
+				ret = rport->bvalid_irq;
+				return ret;
+			}
+
+			ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
+							NULL,
+							rockchip_usb2phy_bvalid_irq,
+							IRQF_ONESHOT,
+							"rockchip_usb2phy_bvalid",
+							rport);
+			if (ret) {
+				dev_err(rphy->dev,
+					"failed to request otg-bvalid irq handle\n");
+				return ret;
+			}
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
 					   struct rockchip_usb2phy_port *rport,
 					   struct device_node *child_np)
@@ -947,18 +1045,9 @@ static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
 	mutex_init(&rport->mutex);
 	INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
 
-	rport->ls_irq = of_irq_get_byname(child_np, "linestate");
-	if (rport->ls_irq < 0) {
-		dev_err(rphy->dev, "no linestate irq provided\n");
-		return rport->ls_irq;
-	}
-
-	ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
-					rockchip_usb2phy_linestate_irq,
-					IRQF_ONESHOT,
-					"rockchip_usb2phy", rport);
+	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
 	if (ret) {
-		dev_err(rphy->dev, "failed to request linestate irq handle\n");
+		dev_err(rphy->dev, "failed to setup host irq\n");
 		return ret;
 	}
 
@@ -1007,44 +1096,10 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
 	INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
 	INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
 
-	/*
-	 * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate
-	 * interrupts muxed together, so probe the otg-mux interrupt first,
-	 * if not found, then look for the regular interrupts one by one.
-	 */
-	rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
-	if (rport->otg_mux_irq > 0) {
-		ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
-						NULL,
-						rockchip_usb2phy_otg_mux_irq,
-						IRQF_ONESHOT,
-						"rockchip_usb2phy_otg",
-						rport);
-		if (ret) {
-			dev_err(rphy->dev,
-				"failed to request otg-mux irq handle\n");
-			goto out;
-		}
-	} else {
-		rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
-		if (rport->bvalid_irq < 0) {
-			dev_err(rphy->dev, "no vbus valid irq provided\n");
-			ret = rport->bvalid_irq;
-			goto out;
-		}
-
-		ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
-						NULL,
-						rockchip_usb2phy_bvalid_irq,
-						IRQF_ONESHOT,
-						"rockchip_usb2phy_bvalid",
-						rport);
-		if (ret) {
-			dev_err(rphy->dev,
-				"failed to request otg-bvalid irq handle\n");
-			goto out;
-		}
-	}
+	ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
+	if (ret) {
+		dev_err(rphy->dev, "failed to init irq for host port\n");
+		goto out;
 
 	if (!IS_ERR(rphy->edev)) {
 		rport->event_nb.notifier_call = rockchip_otg_event;
@@ -1124,6 +1179,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	phy_cfgs = match->data;
 	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
 	rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
+	rphy->irq = platform_get_irq(pdev, 0);
 	platform_set_drvdata(pdev, rphy);
 
 	ret = rockchip_usb2phy_extcon_register(rphy);
@@ -1201,6 +1257,20 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
 	}
 
 	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	if (rphy->irq > 0) {
+		ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
+						rockchip_usb2phy_irq,
+						IRQF_ONESHOT,
+						"rockchip_usb2phy",
+						rphy);
+		if (ret) {
+			dev_err(rphy->dev,
+				"failed to request usb2phy irq handle\n");
+			goto put_child;
+		}
+	}
+
 	return PTR_ERR_OR_ZERO(provider);
 
 put_child:
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:14 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:14 -0400
Subject: [PATCH v2 6/8] phy: phy-rockchip-inno-usb2: add rk3568 support
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-7-pgwipeout@gmail.com>

The rk3568 usb2phy is a standalone device with a single muxed interrupt.
Add support for the registers to the usb2phy driver.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 65 +++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index fdeb2e7c937a..74420c439a07 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -1100,6 +1100,7 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
 	if (ret) {
 		dev_err(rphy->dev, "failed to init irq for host port\n");
 		goto out;
+	}
 
 	if (!IS_ERR(rphy->edev)) {
 		rport->event_nb.notifier_call = rockchip_otg_event;
@@ -1509,6 +1510,69 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
+	{
+		.reg = 0xfe8a0000,
+		.num_ports	= 2,
+		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0, 0x1d1 },
+				.bvalid_det_en	= { 0x0080, 2, 2, 0, 1 },
+				.bvalid_det_st	= { 0x0084, 2, 2, 0, 1 },
+				.bvalid_det_clr = { 0x0088, 2, 2, 0, 1 },
+				.utmi_avalid	= { 0x00c0, 10, 10, 0, 1 },
+				.utmi_bvalid	= { 0x00c0, 9, 9, 0, 1 },
+			},
+			[USB2PHY_PORT_HOST] = {
+				/* Select suspend control from controller */
+				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d2 },
+				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
+				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
+				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
+				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
+			}
+		},
+		.chg_det = {
+			.opmode		= { 0x0000, 3, 0, 5, 1 },
+			.cp_det		= { 0x00c0, 24, 24, 0, 1 },
+			.dcp_det	= { 0x00c0, 23, 23, 0, 1 },
+			.dp_det		= { 0x00c0, 25, 25, 0, 1 },
+			.idm_sink_en	= { 0x0008, 8, 8, 0, 1 },
+			.idp_sink_en	= { 0x0008, 7, 7, 0, 1 },
+			.idp_src_en	= { 0x0008, 9, 9, 0, 1 },
+			.rdm_pdwn_en	= { 0x0008, 10, 10, 0, 1 },
+			.vdm_src_en	= { 0x0008, 12, 12, 0, 1 },
+			.vdp_src_en	= { 0x0008, 11, 11, 0, 1 },
+		},
+	},
+	{
+		.reg = 0xfe8b0000,
+		.num_ports	= 2,
+		.clkout_ctl	= { 0x0008, 4, 4, 1, 0 },
+		.port_cfgs	= {
+			[USB2PHY_PORT_OTG] = {
+				.phy_sus	= { 0x0000, 8, 0, 0x1d2, 0x1d1 },
+				.ls_det_en	= { 0x0080, 0, 0, 0, 1 },
+				.ls_det_st	= { 0x0084, 0, 0, 0, 1 },
+				.ls_det_clr	= { 0x0088, 0, 0, 0, 1 },
+				.utmi_ls	= { 0x00c0, 5, 4, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 7, 7, 0, 1 }
+			},
+			[USB2PHY_PORT_HOST] = {
+				.phy_sus	= { 0x0004, 8, 0, 0x1d2, 0x1d1 },
+				.ls_det_en	= { 0x0080, 1, 1, 0, 1 },
+				.ls_det_st	= { 0x0084, 1, 1, 0, 1 },
+				.ls_det_clr	= { 0x0088, 1, 1, 0, 1 },
+				.utmi_ls	= { 0x00c0, 17, 16, 0, 1 },
+				.utmi_hstdet	= { 0x00c0, 19, 19, 0, 1 }
+			}
+		},
+	},
+	{ /* sentinel */ }
+};
+
 static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
 	{
 		.reg = 0x100,
@@ -1558,6 +1622,7 @@ static const struct of_device_id rockchip_usb2phy_dt_match[] = {
 	{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
 	{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
 	{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
+	{ .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
 	{ .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
 	{}
 };
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:15 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:15 -0400
Subject: [PATCH v2 7/8] arm64: dts: rockchip: add usb2 nodes to rk3568 device
 tree
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-8-pgwipeout@gmail.com>

Add the requisite nodes to the rk3568 device tree to enable the usb2
device controllers.
Includes the usb2phy nodes, usb2phy grf nodes, and usb2 controller
nodes.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 98 ++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 322971318d5a..2abd9241c91f 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -200,6 +200,50 @@ gic: interrupt-controller at fd400000 {
 		msi-controller;
 	};
 
+	usb_host0_ehci: usb at fd800000 {
+		compatible = "generic-ehci";
+		reg = <0x0 0xfd800000 0x0 0x40000>;
+		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
+			 <&cru PCLK_USB>;
+		phys = <&u2phy1_otg>;
+		phy-names = "usb";
+		status = "disabled";
+	};
+
+	usb_host0_ohci: usb at fd840000 {
+		compatible = "generic-ohci";
+		reg = <0x0 0xfd840000 0x0 0x40000>;
+		interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
+			 <&cru PCLK_USB>;
+		phys = <&u2phy1_otg>;
+		phy-names = "usb";
+		status = "disabled";
+	};
+
+	usb_host1_ehci: usb at fd880000 {
+		compatible = "generic-ehci";
+		reg = <0x0 0xfd880000 0x0 0x40000>;
+		interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
+			 <&cru PCLK_USB>;
+		phys = <&u2phy1_host>;
+		phy-names = "usb";
+		status = "disabled";
+	};
+
+	usb_host1_ohci: usb at fd8c0000 {
+		compatible = "generic-ohci";
+		reg = <0x0 0xfd8c0000 0x0 0x40000>;
+		interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
+			 <&cru PCLK_USB>;
+		phys = <&u2phy1_host>;
+		phy-names = "usb";
+		status = "disabled";
+	};
+
 	pmugrf: syscon at fdc20000 {
 		compatible = "rockchip,rk3568-pmugrf", "syscon", "simple-mfd";
 		reg = <0x0 0xfdc20000 0x0 0x10000>;
@@ -210,6 +254,16 @@ grf: syscon at fdc60000 {
 		reg = <0x0 0xfdc60000 0x0 0x10000>;
 	};
 
+	usb2phy0_grf: syscon at fdca0000 {
+		compatible = "rockchip,rk3568-usb2phy-grf", "syscon";
+		reg = <0x0 0xfdca0000 0x0 0x8000>;
+	};
+
+	usb2phy1_grf: syscon at fdca8000 {
+		compatible = "rockchip,rk3568-usb2phy-grf", "syscon";
+		reg = <0x0 0xfdca8000 0x0 0x8000>;
+	};
+
 	pmucru: clock-controller at fdd00000 {
 		compatible = "rockchip,rk3568-pmucru";
 		reg = <0x0 0xfdd00000 0x0 0x1000>;
@@ -738,6 +792,50 @@ saradc: saradc at fe720000 {
 		status = "disabled";
 	};
 
+	usb2phy0: usb2-phy at fe8a0000 {
+		compatible = "rockchip,rk3568-usb2phy";
+		reg = <0x0 0xfe8a0000 0x0 0x10000>;
+		clocks = <&pmucru CLK_USBPHY0_REF>;
+		clock-names = "phyclk";
+		clock-output-names = "clk_usbphy0_480m";
+		interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+		rockchip,usbgrf = <&usb2phy0_grf>;
+		#clock-cells = <0>;
+		status = "disabled";
+
+		u2phy0_host: host-port {
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		u2phy0_otg: otg-port {
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+	};
+
+	usb2phy1: usb2-phy at fe8b0000 {
+		compatible = "rockchip,rk3568-usb2phy";
+		reg = <0x0 0xfe8b0000 0x0 0x10000>;
+		clocks = <&pmucru CLK_USBPHY1_REF>;
+		clock-names = "phyclk";
+		clock-output-names = "clk_usbphy1_480m";
+		interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+		rockchip,usbgrf = <&usb2phy1_grf>;
+		#clock-cells = <0>;
+		status = "disabled";
+
+		u2phy1_host: host-port {
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		u2phy1_otg: otg-port {
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+	};
+
 	pinctrl: pinctrl {
 		compatible = "rockchip,rk3568-pinctrl";
 		rockchip,grf = <&grf>;
-- 
2.25.1



From pgwipeout at gmail.com  Thu Aug 12 13:41:16 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 12 Aug 2021 16:41:16 -0400
Subject: [PATCH v2 8/8] arm64: dts: rockchip: add Quartz64-A usb2 support
In-Reply-To: <20210812204116.2303617-1-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
Message-ID: <20210812204116.2303617-9-pgwipeout@gmail.com>

Add the nodes and regulators to enable usb2 support on the Quartz64
Model A.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index a3cdb6c2bec6..53ea5c13076b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -75,6 +75,22 @@ vcc5v0_usb: vcc5v0_usb {
 		vin-supply = <&vcc12v_dcin>;
 	};
 
+	/* all four ports are controlled by one gpio
+	 * the host ports are sourced from vcc5v0_usb
+	 * the otg port is sourced from vcc5v0_midu
+	 */
+	vcc5v0_usb20_host: vcc5v0_usb20_host {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb20_host";
+		enable-active-high;
+		gpio = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb20_host_en>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
 	vcc3v3_sd: vcc3v3_sd {
 		compatible = "regulator-fixed";
 		enable-active-low;
@@ -367,6 +383,12 @@ pmic_int_l: pmic-int-l {
 		};
 	};
 
+	usb2 {
+		vcc5v0_usb20_host_en: vcc5v0-usb20-host-en {
+			rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	vcc_sd {
 		vcc_sd_h: vcc-sd-h {
 			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -424,3 +446,33 @@ bluetooth {
 &uart2 {
 	status = "okay";
 };
+
+&u2phy1_host {
+	phy-supply = <&vcc5v0_usb20_host>;
+	status = "okay";
+};
+
+&u2phy1_otg {
+	phy-supply = <&vcc5v0_usb20_host>;
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
-- 
2.25.1



From arnd at kernel.org  Thu Aug 12 13:44:01 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:44:01 +0200
Subject: [PATCH] bus: ixp4xx: return on error in ixp4xx_exp_probe()
In-Reply-To: <20210807230016.3607666-1-linus.walleij@linaro.org>
References: <20210807230016.3607666-1-linus.walleij@linaro.org>
Message-ID: <162880092600.1372486.9999578242110413401.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sun, 8 Aug 2021 01:00:16 +0200, Linus Walleij wrote:
> This code was intended to return an error code if regmap_read() fails
> but the return statement was missing.

Applied to arm/drivers, thanks!

[1/1] bus: ixp4xx: return on error in ixp4xx_exp_probe()
      commit: d2c334f49c8305ff8ce31ea33183977a2935ba55

       Arnd


From arnd at kernel.org  Thu Aug 12 13:44:02 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:44:02 +0200
Subject: [GIT PULL] drivers: soc: mediatek: updates for v5.15
In-Reply-To: <49fc7bef-20db-b98c-9437-dd9e4d00e870@gmail.com>
References: <49fc7bef-20db-b98c-9437-dd9e4d00e870@gmail.com>
Message-ID: <162880092618.1372486.1035988848948197417.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 9 Aug 2021 14:19:57 +0200, Matthias Brugger wrote:
> Hi Arnd,
> 
> Please have a look for the updates of the SoC drivers for Mediatek. If you
> wonder why there is no binding patch for the MT8365 mmsys: The binding was
> converted to YAML. This got taken by Rob. To minimize merge conflicts I left it
> to him to take other mmsys binding patches. Unfortunately there is one mmsys
> binding patch taken by Stephen through the clock tree. So there will be a
> trivial merge conflict (although not in your tree). A bit of a mess this time,
> I'll try to make sure that the bindings for drivers/soc will go through my tree
> in the future (which will make my life easier as well...).
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: a8c371f0cfe7224e4bc3f3f0495e54a035107653

       Arnd


From arnd at kernel.org  Thu Aug 12 13:44:03 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:44:03 +0200
Subject: [GIT PULL] soc: Keystone driver update for v5.15
In-Reply-To: <0A637A41-2353-4900-962C-DBE50BBDE75A@oracle.com>
References: <0A637A41-2353-4900-962C-DBE50BBDE75A@oracle.com>
Message-ID: <162880092637.1372486.15700318335948204747.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 10 Aug 2021 23:38:07 +0000, Santosh Shilimkar wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/drivers_soc_for_5.15
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 866e1691ed5beee933c0f8c9268963c33377ede6

       Arnd


From arnd at kernel.org  Thu Aug 12 13:44:05 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:44:05 +0200
Subject: [GIT PULL] firmware: arm_scmi: Updates for v5.15
In-Reply-To: <20210811075743.707961-1-sudeep.holla@arm.com>
References: <20210811075743.707961-1-sudeep.holla@arm.com>
Message-ID: <162880092646.1372486.6295796989855269180.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 11 Aug 2021 08:57:43 +0100, Sudeep Holla wrote:
> Please pull !
> 
> Regards,
> Sudeep
> 
> -->8
> 
> The following changes since commit bdb8742dc6f7c599c3d61959234fe4c23638727b:
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 1bb24be00c8c360e5e3072301d5f49eac86b384f

       Arnd


From arnd at kernel.org  Thu Aug 12 13:44:04 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:44:04 +0200
Subject: [GIT PULL] i.MX eCSPI errata handling for 5.15
In-Reply-To: <20210809071838.GF30984@dragon>
References: <20210809071838.GF30984@dragon>
Message-ID: <162880092609.1372486.17696747808216287202.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 9 Aug 2021 15:18:39 +0800, Shawn Guo wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-ecspi-5.15
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: a41461b6c400442fce28f706b7e9d03d3cab8f9e

       Arnd


From arnd at kernel.org  Thu Aug 12 13:44:06 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:44:06 +0200
Subject: [GIT PULL 2/3] Driver changes for ti-sysc for v5.15
In-Reply-To: <pull-1628153040-834155@atomide.com-2>
References: <pull-1628153040-834155@atomide.com>
 <pull-1628153040-834155@atomide.com-2>
Message-ID: <162880092575.1372486.4843530883005898506.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Thu, 5 Aug 2021 11:46:43 +0300, Tony Lindgren wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/ti-sysc-signed
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 74953a9136cfd650dd994daded520528f737b7b3

       Arnd


From arnd at kernel.org  Thu Aug 12 13:44:07 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 22:44:07 +0200
Subject: [GIT PULL 2/3] Drop pm_runtime_irq_safe() for smartreflex for
 v5.15
In-Reply-To: <pull-1628751694-126144@atomide.com-2>
References: <pull-1628751694-126144@atomide.com>
 <pull-1628751694-126144@atomide.com-2>
Message-ID: <162880092655.1372486.6465059399635399754.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Thu, 12 Aug 2021 10:03:43 +0300, Tony Lindgren wrote:
> The following changes since commit fdc07ca0724dd8ad00c22909a1464dc73ed6783e:
> 
>   Merge branch 'omap-for-v5.14/ti-sysc' into omap-for-v5.15/ti-sysc (2021-07-27 12:02:24 +0300)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/sr-signed
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 699fe4b190da7da239f70166288d792129acff21

       Arnd


From lkp at intel.com  Thu Aug 12 13:51:21 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 04:51:21 +0800
Subject: [xlnx:master 11243/12376] ERROR: modpost: "update_stripe"
 [drivers/spi/spi-zynqmp-gqspi.ko] undefined!
Message-ID: <202108130411.YcPcfcld-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   af88f405134da108f814cfdf5eac9f2b60f2b800
commit: ffc5cb8494ba2abe218134584b22fd874b71d504 [11243/12376] spi: Update ZynqMP and Versal QSPI controller driver
config: x86_64-randconfig-p002-20210812 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/Xilinx/linux-xlnx/commit/ffc5cb8494ba2abe218134584b22fd874b71d504
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx master
        git checkout ffc5cb8494ba2abe218134584b22fd874b71d504
        # save the attached .config to linux build tree
        make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "update_stripe" [drivers/spi/spi-zynqmp-gqspi.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 33786 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/87c43bfe/attachment-0001.gz>

From arnd at kernel.org  Thu Aug 12 14:05:35 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:35 +0200
Subject: [GIT PULL] STM32 DT changes for v5.15 #1
In-Reply-To: <e4f0bea3-4065-38d5-f1b2-007e4094c4a8@foss.st.com>
References: <e4f0bea3-4065-38d5-f1b2-007e4094c4a8@foss.st.com>
Message-ID: <162880206112.1376011.3171809385171083085.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 6 Aug 2021 12:58:17 +0200, Alexandre TORGUE wrote:
> Please consider this first round of STM32 DT updates for v5.15. A small
> PR containing mainly dtbs_check warnings fix for ST and DH boards.
> 
> regards
> Alex
> 
> The following changes since commit 15f68f027ebd961b99a1c420f96ff3838c5e4450:
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 57798ff216ebf1145bbbd5ea014ad65a72c1d064

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:36 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:36 +0200
Subject: [GIT PULL 1/2] ARM: dts: samsung: DT for v5.15
In-Reply-To: <20210811085128.30103-1-krzysztof.kozlowski@canonical.com>
References: <20210811085128.30103-1-krzysztof.kozlowski@canonical.com>
Message-ID: <162880206174.1376011.6163720025669210158.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 11 Aug 2021 10:51:27 +0200, Krzysztof Kozlowski wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt-5.15
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 0b72a27e1d5d2dc54d289a147411229fa0ed2084

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:37 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:37 +0200
Subject: [GIT PULL 2/2] arm64: dts: samsung: DT64 for v5.15
In-Reply-To: <20210811085128.30103-2-krzysztof.kozlowski@canonical.com>
References: <20210811085128.30103-1-krzysztof.kozlowski@canonical.com>
 <20210811085128.30103-2-krzysztof.kozlowski@canonical.com>
Message-ID: <162880206183.1376011.8279173071110124884.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 11 Aug 2021 10:51:28 +0200, Krzysztof Kozlowski wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.15
> 
> [...]

Merged into arm/dt, thanks!

merge commit: f73979109bc11a0ed26b6deeb403fb5d05676ffc

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:38 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:38 +0200
Subject: [GIT PULL] IXP4xx DTS updates for v5.15
In-Reply-To: <CACRpkdY19AvWT--OcmEKbwFue_EcThVs7uZeHkzORten7xj-RA@mail.gmail.com>
References: <CACRpkdY19AvWT--OcmEKbwFue_EcThVs7uZeHkzORten7xj-RA@mail.gmail.com>
Message-ID: <162880206121.1376011.11565462796731927482.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 9 Aug 2021 02:15:57 +0200, Linus Walleij wrote:
> this is the big DTS update for IXP4xx for kernel v5.15.
> 
> There is still some two device trees that need some more work
> and some of these may need some additional hammering before
> they are perfect(TM) but the basic functionality for all these systems
> should be there and we can proceed to delete some boardfiles
> as soon as we have successful boots on them all or we get tired of
> waiting for someone to test them.
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 34827ffe3502285ce9f588e7427089aff46df790

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:39 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:39 +0200
Subject: [GIT PULL] arm64: dts updates for v5.15
In-Reply-To: <26c4026a-9f26-d5a3-c30f-439120a4eaa0@gmail.com>
References: <26c4026a-9f26-d5a3-c30f-439120a4eaa0@gmail.com>
Message-ID: <162880206138.1376011.17456680023998324459.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 9 Aug 2021 14:20:11 +0200, Matthias Brugger wrote:
> Please have a look for the arm64 DTS updates. This time we only have smaller
> changes for existing boards, but no new HW. But don't worry, probably for v5.16
> we will see some new SoCs.
> 
> Regards,
> Matthias

Merged into arm/dt, thanks!

merge commit: 261a910d6cb7f6079974aa61d31124483832911a

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:40 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:40 +0200
Subject: [GIT PULL] ARM: dts32 updates for v5.15
In-Reply-To: <289ded1c-dae7-54ef-6b56-9433bfcaf9de@gmail.com>
References: <289ded1c-dae7-54ef-6b56-9433bfcaf9de@gmail.com>
Message-ID: <162880206129.1376011.4763501085198621615.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 9 Aug 2021 14:20:03 +0200, Matthias Brugger wrote:
> Please have a look on the single patch in this pull request for arm32 MediaTek.
> 
> Thanks,
> Matthias

Merged into arm/dt, thanks!

merge commit: eaf05c1fdc14ed04a47c8632db5ed45010fccd09

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:41 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:41 +0200
Subject: [GIT PULL] arm64: dts: amlogic updates for v5.15
In-Reply-To: <032895d9-62b6-6c9e-b04b-9c3d316f27ec@baylibre.com>
References: <032895d9-62b6-6c9e-b04b-9c3d316f27ec@baylibre.com>
Message-ID: <162880206156.1376011.2609050470436484899.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 10 Aug 2021 09:44:35 +0200, Neil Armstrong wrote:
> Here's the ARM64 DT changes for v5.15:
> - nanoki-k2: enable bluetooth
> - khadas vim & vim2: improve wifi
> 
> Neil
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
> [...]

Merged into arm/dt, thanks!

merge commit: bcbe4bd39d47bc75c8842477d6f577977d526045

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:42 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:42 +0200
Subject: [GIT PULL] arm: dts: amlogic updates for v5.15
In-Reply-To: <87519792-c9e7-76a6-5db5-0e955286b564@baylibre.com>
References: <87519792-c9e7-76a6-5db5-0e955286b564@baylibre.com>
Message-ID: <162880206165.1376011.6655305408575524550.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 10 Aug 2021 09:45:21 +0200, Neil Armstrong wrote:
> Here's Amlogic ARM DT changes for v5.15:
> - meson8: use a default higher default GPU clock to solve probe failure
> - meson: add AIU audio controller and codec for ec100
> - meson8b: fix pwm regulator supply property name
> 
> Neil
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
> [...]

Merged into arm/dt, thanks!

merge commit: c2632c3afead6e4c6208f90348d142ce1bb372a2

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:43 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:43 +0200
Subject: arm64: dts: TI K3 updates for v5.15
In-Reply-To: <20210809130631.pfvntcichsyeekbo@festive>
References: <20210809130631.pfvntcichsyeekbo@festive>
Message-ID: <162880206147.1376011.10431613497274194194.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 9 Aug 2021 08:06:31 -0500, Nishanth Menon wrote:
> Here is the DT updates for 5.15. Just minor additions this time around.
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 5f49f22db4a82285fbd76b34026051712fdc28ac

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:44 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:44 +0200
Subject: [GIT PULL] STi DT update for v5.15 #1
In-Reply-To: <1d95209f-9cb4-47a3-2696-7a93df7cdc05@foss.st.com>
References: <1d95209f-9cb4-47a3-2696-7a93df7cdc05@foss.st.com>
Message-ID: <162880206103.1376011.9460289595883893367.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 6 Aug 2021 09:45:12 +0200, Patrice CHOTARD wrote:
> This STi DT update is dedicated for v5.15.
> It provides mainly clocks update and introduces a new board.
> 
> Thanks
> Patrice
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
> [...]

Merged into arm/dt, thanks!

merge commit: f3e22d32e4ddef2980ff9c9c401f7b948030e0be

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:45 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:45 +0200
Subject: [GIT PULL 3/3] Changes for am3 cpsw and SanCloud for v5.15
In-Reply-To: <pull-1628751694-126144@atomide.com-3>
References: <pull-1628751694-126144@atomide.com>
 <pull-1628751694-126144@atomide.com-3>
Message-ID: <162880206192.1376011.3718743864242008546.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Thu, 12 Aug 2021 10:03:44 +0300, Tony Lindgren wrote:
> The following changes since commit 8c054cd2818ea08555efe24a2ffde330833c2f3f:
> 
>   ARM: dts: am57xx: Add PRUSS MDIO controller nodes (2021-08-03 15:25:14 +0300)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/dt-am3-signed
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 81b6a285737700c2e04ef0893617b80481b6b4b7

       Arnd


From arnd at kernel.org  Thu Aug 12 14:05:46 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:05:46 +0200
Subject: [GIT PULL 3/3] Devicetree changes for omaps for v5.15
In-Reply-To: <pull-1628153040-834155@atomide.com-3>
References: <pull-1628153040-834155@atomide.com>
 <pull-1628153040-834155@atomide.com-3>
Message-ID: <162880206094.1376011.11267731078560363684.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Thu, 5 Aug 2021 11:46:44 +0300, Tony Lindgren wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.15/dt-signed
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 1c7ba565e70365763ea780666a3eee679344b962

       Arnd


From arnd at kernel.org  Thu Aug 12 14:08:39 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:08:39 +0200
Subject: [GIT PULL] ARM: multi_v7_defconfig: amlogic updates for v5.15
In-Reply-To: <8e2b5139-86e6-0da3-75c4-d8df66448d51@baylibre.com>
References: <8e2b5139-86e6-0da3-75c4-d8df66448d51@baylibre.com>
Message-ID: <162880251654.1376866.17026578806860861616.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 10 Aug 2021 09:46:59 +0200, Neil Armstrong wrote:
> Here's a single multi_v7_defconfig change for v5.15 to enable CONFIG_MMC_MESON_MX_SDHC controller used on meson8/8b
> 
> Neil
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> [...]

Merged into arm/defconfig, thanks!

merge commit: 20904527a70de3aff43edafdf5d18b0f6f976f59

       Arnd


From arnd at kernel.org  Thu Aug 12 14:08:40 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 12 Aug 2021 23:08:40 +0200
Subject: [GIT PULL v2] ARM: at91: defconfig for 5.15
In-Reply-To: <20210809134521.10155-1-nicolas.ferre@microchip.com>
References: <CAK8P3a1Ru-qawBWtbmfJm-jiPpJTRJ9zSufXHNCZvxt1RCMFBA@mail.gmail.com>
 <20210809134521.10155-1-nicolas.ferre@microchip.com>
Message-ID: <162880251645.1376866.7366771530454558975.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 9 Aug 2021 15:45:21 +0200, nicolas.ferre at microchip.com wrote:
> Arnd, Olof,
> 
> Here is the second attept about defconfig changes for 5.15 which contains
> addition for SAMA7G5.
> 
> v1 --> v2:
> - add more information to the tag message for explaining why we prefer
>   a new sama7_defconfig file.
> 
> [...]

Merged into arm/defconfig, thanks!

merge commit: b528dede9bca2afc262b841757fa994bd035cb43

       Arnd


From valentin.schneider at arm.com  Thu Aug 12 14:38:11 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Thu, 12 Aug 2021 22:38:11 +0100
Subject: [PATCH v3 05/13] genirq: Let purely flow-masked ONESHOT irqs
 through unmask_threaded_irq()
In-Reply-To: <87wnoq90wx.wl-maz@kernel.org>
References: <20210629125010.458872-1-valentin.schneider@arm.com>
 <20210629125010.458872-6-valentin.schneider@arm.com>
 <87bl639l8n.wl-maz@kernel.org> <875ywa944c.mognet@arm.com>
 <87wnoq90wx.wl-maz@kernel.org>
Message-ID: <87zgtm7398.mognet@arm.com>

On 12/08/21 15:45, Marc Zyngier wrote:
> On Thu, 12 Aug 2021 14:36:35 +0100,
> Valentin Schneider <valentin.schneider at arm.com> wrote:
>> 
>> On 12/08/21 08:26, Marc Zyngier wrote:
>> > On Tue, 29 Jun 2021 13:50:02 +0100,
>> > Valentin Schneider <valentin.schneider at arm.com> wrote:
>> >> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
>> >> index ef30b4762947..e6d6d32ddcbc 100644
>> >> --- a/kernel/irq/manage.c
>> >> +++ b/kernel/irq/manage.c
>> >> @@ -1107,7 +1107,7 @@ static void irq_finalize_oneshot(struct irq_desc *desc,
>> >>  	desc->threads_oneshot &= ~action->thread_mask;
>> >>  
>> >>  	if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) &&
>> >> -	    irqd_irq_masked(&desc->irq_data))
>> >> +	    (irqd_irq_masked(&desc->irq_data) | irqd_irq_flow_masked(&desc->irq_data)))
>> >>  		unmask_threaded_irq(desc);
>> >
>> > The bitwise OR looks pretty odd. It is probably fine given that both
>> > side of the expression are bool, but still. I can fix this locally.
>> >
>> 
>> Thomas suggested that back in v1:
>> 
>>   https://lore.kernel.org/lkml/87v98v4lan.ffs at nanos.tec.linutronix.de/
>> 
>> I did look at the (arm64) disassembly diff back then and was convinced by
>> what I saw, though I'd have to go do that again as I can't remember much
>> else.
>
> Ah, fair enough.
>

Either I didn't have my glasses on or had a different output back then, but
I'm not so convinced anymore... (same result on both Ubuntu GCC 9.3.0 and
10.2 GCC release from Arm):


Logical OR:

     8f8:	b9400020 	ldr	w0, [x1]
     8fc:	3787fea0 	tbnz	w0, #16, 8d0 <irq_finalize_oneshot.part.0+0x60>
     900:	37880040 	tbnz	w0, #17, 908 <irq_finalize_oneshot.part.0+0x98>
     904:	36fffe60 	tbz	w0, #31, 8d0 <irq_finalize_oneshot.part.0+0x60>
     908:	aa1303e0 	mov	x0, x19
     90c:	94000000 	bl	0 <unmask_threaded_irq>

Bitwise OR (aka the patch):

     8f8:	b9400020 	ldr	w0, [x1]
     8fc:	3787fea0 	tbnz	w0, #16, 8d0 <irq_finalize_oneshot.part.0+0x60>
     900:	f26f001f 	tst	x0, #0x20000
     904:	7a400801 	ccmp	w0, #0x0, #0x1, eq  // eq = none
     908:	54fffe4a 	b.ge	8d0 <irq_finalize_oneshot.part.0+0x60>  // b.tcont
     90c:	aa1303e0 	mov	x0, x19
     910:	94000000 	bl	0 <unmask_threaded_irq>

If I get this right...

- TST sets the Z condition flag if bit 17 (masked) isn't set
- CCMP sets the condition flags to
  - the same as SUBS(flags, 0) if bit 17 wasn't set
  - NZCV=0001 otherwise
- B.GE branches if N==V

Soooo

- if we have bit 17 set, NZCV=0001, B.GE doesn't branch
- if we don't have bit 17 but bit 31 (flow-masked), NZCV=1000 because
  this is signed 32-bit, so having bit 31 set makes the result of
  SUBS(flags, 0) negative, B.GE doesn't branch
- if we have neither, NZCV=0XX0, B.GE branches

So this does appear to do the right thing, at the cost of an extra
instruction and a profound sense of dread to whoever stares at the
disassembly. I guess it does save us a branch which could be
mispredicted...

> Thanks,
>
> 	M.
>
> -- 
> Without deviation from the norm, progress is not possible.


From leoyang.li at nxp.com  Thu Aug 12 16:09:28 2021
From: leoyang.li at nxp.com (Li Yang)
Date: Thu, 12 Aug 2021 18:09:28 -0500
Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
 LX2160A UART
In-Reply-To: <AS8PR04MB8946913A8B97C18240ADBAEA8FF79@AS8PR04MB8946.eurprd04.prod.outlook.com>
References: <20210615131605.616-1-thunder.leizhen@huawei.com>
 <20210615131605.616-2-thunder.leizhen@huawei.com>
 <AS8PR04MB8946D0EB15D631346F4D13198FF69@AS8PR04MB8946.eurprd04.prod.outlook.com>
 <03d7c7be-2f19-9fdf-2a4e-f49a62bb82f6@huawei.com>
 <AS8PR04MB8946913A8B97C18240ADBAEA8FF79@AS8PR04MB8946.eurprd04.prod.outlook.com>
Message-ID: <CADRPPNQaM+-LfacBJLQPYjk3df_p0VuF9rx933T6bTQOcgYacw@mail.gmail.com>

On Tue, Aug 10, 2021 at 1:28 AM Leo Li <leoyang.li at nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Leizhen (ThunderTown) <thunder.leizhen at huawei.com>
> > Sent: Monday, August 9, 2021 8:28 PM
> > To: Leo Li <leoyang.li at nxp.com>; Shawn Guo <shawnguo at kernel.org>; Rob
> > Herring <robh+dt at kernel.org>; Mark Kettenis <mark.kettenis at xs4all.nl>;
> > devicetree <devicetree at vger.kernel.org>; linux-arm-kernel <linux-arm-
> > kernel at lists.infradead.org>; linux-kernel <linux-kernel at vger.kernel.org>
> > Subject: Re: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
> > LX2160A UART
> >
> >
> >
> > On 2021/8/10 6:52, Leo Li wrote:
> > >
> > >
> > >> -----Original Message-----
> > >> From: Zhen Lei <thunder.leizhen at huawei.com>
> > >> Sent: Tuesday, June 15, 2021 8:16 AM
> > >> To: Shawn Guo <shawnguo at kernel.org>; Leo Li <leoyang.li at nxp.com>;
> > Rob
> > >> Herring <robh+dt at kernel.org>; Mark Kettenis
> > >> <mark.kettenis at xs4all.nl>; devicetree <devicetree at vger.kernel.org>;
> > >> linux-arm-kernel <linux-arm- kernel at lists.infradead.org>;
> > >> linux-kernel <linux-kernel at vger.kernel.org>
> > >> Cc: Zhen Lei <thunder.leizhen at huawei.com>
> > >> Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible
> > >> string of LX2160A UART
> > >>
> > >> Mark Kettenis told us that:
> > >> According to the NXP documentation, the LX2160A has a real PL011 UART.
> > >>
> > >> Therefore, rewrite it to the compatible string of pl011. The property
> > >> "current- speed" specific to "arm,sbsa-uart" is also deleted.
> > >
> > > Sorry that I missed the discussion on the v1.  But looks like this change
> > breaks the LX2160 boot.  The AMBA matching doesn't seem to work.  And
> > the console is not registered correctly.
> >
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.k
> > ernel.org%2Flinux-arm-kernel%2Fcba3a29f-92b5-072a-9a27-
> > 60240f072dad%40huawei.com%2F&amp;data=04%7C01%7Cleoyang.li%40nx
> > p.com%7C9986b52f71724d7f6ae108d95b9e1d9b%7C686ea1d3bc2b4c6fa92cd
> > 99c5c301635%7C0%7C0%7C637641556923909225%7CUnknown%7CTWFpbGZ
> > sb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6M
> > n0%3D%7C1000&amp;sdata=wReesSfMj1hV2iPTN0%2F%2B%2Fb%2BKJH8xF
> > LLcDgOMfjx731I%3D&amp;reserved=0
> >
> > Maybe we should fall back to v1.
>
> I didn't look into the problem in detail.  Probably it is because of lacking the clock properties needed by the AMBA bus?
>

After reading through the history of sbsa-uart,  I think that I would
prefer us to fall back to v1 to be compatible with sbsa-uart rather
than changing it to be compatible with pl011.  Although the hardware
is actually compatible with the pl011, it would be better for us to
follow the newer SBSA standard to leave advanced configuration to
firmware and just expose the simple standard interface to OS.

Regards,
Leo

> >
> > >
> > > [    0.639055] OF: amba_device_add() failed (-2) for /soc/serial at 21c0000
> > > [    0.645612] OF: amba_device_add() failed (-2) for /soc/serial at 21d0000
> > >
> > >>
> > >> Suggested-by: Shawn Guo <shawnguo at kernel.org>
> > >> Suggested-by: Mark Kettenis <mark.kettenis at xs4all.nl>
> > >> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> > >> ---
> > >>  arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 12 ++++--------
> > >>  1 file changed, 4 insertions(+), 8 deletions(-)
> > >>
> > >> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> > >> b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> > >> index c4b1a59ba424..d2e6f7285674 100644
> > >> --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> > >> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
> > >> @@ -920,34 +920,30 @@ QORIQ_CLK_PLL_DIV(8)>,
> > >>            };
> > >>
> > >>            uart0: serial at 21c0000 {
> > >> -                  compatible = "arm,sbsa-uart","arm,pl011";
> > >> +                  compatible = "arm,pl011", "arm,primecell";
> > >>                    reg = <0x0 0x21c0000 0x0 0x1000>;
> > >>                    interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> > >> -                  current-speed = <115200>;
> > >>                    status = "disabled";
> > >>            };
> > >>
> > >>            uart1: serial at 21d0000 {
> > >> -                  compatible = "arm,sbsa-uart","arm,pl011";
> > >> +                  compatible = "arm,pl011", "arm,primecell";
> > >>                    reg = <0x0 0x21d0000 0x0 0x1000>;
> > >>                    interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
> > >> -                  current-speed = <115200>;
> > >>                    status = "disabled";
> > >>            };
> > >>
> > >>            uart2: serial at 21e0000 {
> > >> -                  compatible = "arm,sbsa-uart","arm,pl011";
> > >> +                  compatible = "arm,pl011", "arm,primecell";
> > >>                    reg = <0x0 0x21e0000 0x0 0x1000>;
> > >>                    interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
> > >> -                  current-speed = <115200>;
> > >>                    status = "disabled";
> > >>            };
> > >>
> > >>            uart3: serial at 21f0000 {
> > >> -                  compatible = "arm,sbsa-uart","arm,pl011";
> > >> +                  compatible = "arm,pl011", "arm,primecell";
> > >>                    reg = <0x0 0x21f0000 0x0 0x1000>;
> > >>                    interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> > >> -                  current-speed = <115200>;
> > >>                    status = "disabled";
> > >>            };
> > >>
> > >> --
> > >> 2.25.1
> > >>
> > >
> > > .
> > >


From swboyd at chromium.org  Thu Aug 12 17:16:10 2021
From: swboyd at chromium.org (Stephen Boyd)
Date: Thu, 12 Aug 2021 17:16:10 -0700
Subject: [PATCH 0/3] soc: qcom: Add download mode support for QTI platforms
In-Reply-To: <cover.1628757036.git.saiprakash.ranjan@codeaurora.org>
References: <cover.1628757036.git.saiprakash.ranjan@codeaurora.org>
Message-ID: <CAE-0n52PzadMxB_4h2DGJGLO++Bu_PCSsxS8NHe+cuhv=Mw0sA@mail.gmail.com>

Quoting Sai Prakash Ranjan (2021-08-12 02:17:39)
> Collecting ramdumps on QTI platforms mainly require two things,
> SDI (System Debug Image) enabled firmware and kernel support to
> configure download mode cookies and SDI settings. Ramdumps can
> be collected once the system enters the download mode. To enter
> download mode, magic values or cookies need to be set in IMEM
> which is used by firmware to decide to enter download mode or not.
> Download mode cookies remain the same across targets and SDI disable
> register needs to be set or SDI needs to be disabled in case of normal
> reboot since ramdumps are supposed to be for crash debugging and
> not for every reboot. This series adds the kernel support required
> to enter download mode.

I don't recall if we discussed this on the list, but I'd really prefer
that we don't make kernel changes to support this beyond implementing
PSCI SYSTEM_RESET2 support and then some sort of vendor specific (or if
ARM is willing to update the spec then ARM specific) reset command on
panic reboot paths. The idea is to set the cookie in the bootloader
before the kernel is booted, then any insta-reboots/watchdogs would go
into download mode, no special init code required to lay down the cookie
or clear it on normal reboot. The normal reboot PSCI call would clear
the cookie in the firmware, in case something goes wrong after the
kernel hands off control to PSCI, and then panics that want to go into
download mode would make the SYSTEM_RESET2 reboot call into PSCI that
sets the cookie.

Maybe it could be a linux specific psci number or maybe we could
configure the reboot call in the psci node to be this specific number so
that it can be different based on the firmware implementation if
consolidating around a single number doesn't work. Either way, that all
seems manageable and we can keep these cookie details out of the kernel
and the reboot/panic paths.

>
> Currently this series doesn't add support for android targets where
> a couple of SCM calls are required to set/unset the download mode
> cookies and SDI configuration but can be easily added gradually to
> the same driver, so as of now only chrome platforms are supported
> and tested.
>
> Sai Prakash Ranjan (3):
>   soc: qcom: Add download mode support
>   dt-bindings: msm: Add QTI download mode support binding
>   arm64: dts: qcom: sc7180: Add IMEM, pil info and download mode region
>
>  .../bindings/arm/msm/qcom,dload-mode.yaml     |  53 ++++++
>  MAINTAINERS                                   |   7 +
>  arch/arm64/boot/dts/qcom/sc7180.dtsi          |  21 +++
>  drivers/soc/qcom/Kconfig                      |  10 ++
>  drivers/soc/qcom/Makefile                     |   1 +
>  drivers/soc/qcom/download_mode.c              | 152 ++++++++++++++++++
>  6 files changed, 244 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,dload-mode.yaml
>  create mode 100644 drivers/soc/qcom/download_mode.c


From paulmck at kernel.org  Thu Aug 12 17:20:45 2021
From: paulmck at kernel.org (Paul E. McKenney)
Date: Thu, 12 Aug 2021 17:20:45 -0700
Subject: [PATCH v3 3/4] rcu/nocb: Protect NOCB state via local_lock()
 under PREEMPT_RT
In-Reply-To: <20210811201354.1976839-4-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-4-valentin.schneider@arm.com>
Message-ID: <20210813002045.GZ4126399@paulmck-ThinkPad-P17-Gen-1>

On Wed, Aug 11, 2021 at 09:13:53PM +0100, Valentin Schneider wrote:
> Warning
> =======
> 
> Running v5.13-rt1 on my arm64 Juno board triggers:
> 
> [    0.156302] =============================
> [    0.160416] WARNING: suspicious RCU usage
> [    0.164529] 5.13.0-rt1 #20 Not tainted
> [    0.168300] -----------------------------
> [    0.172409] kernel/rcu/tree_plugin.h:69 Unsafe read of RCU_NOCB offloaded state!
> [    0.179920]
> [    0.179920] other info that might help us debug this:
> [    0.179920]
> [    0.188037]
> [    0.188037] rcu_scheduler_active = 1, debug_locks = 1
> [    0.194677] 3 locks held by rcuc/0/11:
> [    0.198448] #0: ffff00097ef10cf8 ((softirq_ctrl.lock).lock){+.+.}-{2:2}, at: __local_bh_disable_ip (./include/linux/rcupdate.h:662 kernel/softirq.c:171)
> [    0.208709] #1: ffff80001205e5f0 (rcu_read_lock){....}-{1:2}, at: rt_spin_lock (kernel/locking/spinlock_rt.c:43 (discriminator 4))
> [    0.217134] #2: ffff80001205e5f0 (rcu_read_lock){....}-{1:2}, at: __local_bh_disable_ip (kernel/softirq.c:169)
> [    0.226428]
> [    0.226428] stack backtrace:
> [    0.230889] CPU: 0 PID: 11 Comm: rcuc/0 Not tainted 5.13.0-rt1 #20
> [    0.237100] Hardware name: ARM Juno development board (r0) (DT)
> [    0.243041] Call trace:
> [    0.245497] dump_backtrace (arch/arm64/kernel/stacktrace.c:163)
> [    0.249185] show_stack (arch/arm64/kernel/stacktrace.c:219)
> [    0.252522] dump_stack (lib/dump_stack.c:122)
> [    0.255947] lockdep_rcu_suspicious (kernel/locking/lockdep.c:6439)
> [    0.260328] rcu_rdp_is_offloaded (kernel/rcu/tree_plugin.h:69 kernel/rcu/tree_plugin.h:58)
> [    0.264537] rcu_core (kernel/rcu/tree.c:2332 kernel/rcu/tree.c:2398 kernel/rcu/tree.c:2777)
> [    0.267786] rcu_cpu_kthread (./include/linux/bottom_half.h:32 kernel/rcu/tree.c:2876)
> [    0.271644] smpboot_thread_fn (kernel/smpboot.c:165 (discriminator 3))
> [    0.275767] kthread (kernel/kthread.c:321)
> [    0.279013] ret_from_fork (arch/arm64/kernel/entry.S:1005)
> 
> In this case, this is the RCU core kthread accessing the local CPU's
> rdp. Before that, rcu_cpu_kthread() invokes local_bh_disable().
> 
> Under !CONFIG_PREEMPT_RT (and rcutree.use_softirq=0), this ends up
> incrementing the preempt_count, which satisfies the "local non-preemptible
> read" of rcu_rdp_is_offloaded().
> 
> Under CONFIG_PREEMPT_RT however, this becomes
> 
>   local_lock(&softirq_ctrl.lock)
> 
> which, under the same config, is migrate_disable() + rt_spin_lock(). As
> pointed out by Frederic, this is not sufficient to safely access an rdp's
> offload state, as the RCU core kthread can be preempted by a kworker
> executing rcu_nocb_rdp_offload() [1].
> 
> Introduce a local_lock to serialize an rdp's offload state while the rdp's
> associated core kthread is executing rcu_core().
> 
> rcu_core() preemptability considerations
> ========================================
> 
> As pointed out by Paul [2], keeping rcu_check_quiescent_state() preemptible
> (which is the case under CONFIG_PREEMPT_RT) requires some consideration.
> 
> note_gp_changes() itself runs with irqs off, and enters
> __note_gp_changes() with rnp->lock held (raw_spinlock), thus is safe vs
> preemption.
> 
> rdp->core_needs_qs *could* change after being read by the RCU core
> kthread if it then gets preempted. Consider, with
> CONFIG_RCU_STRICT_GRACE_PERIOD:
> 
>   rcuc/x                                   task_foo
> 
>     rcu_check_quiescent_state()
>     `\
>       rdp->core_needs_qs == true
> 			     <PREEMPT>
> 					   rcu_read_unlock()
> 					   `\
> 					     rcu_preempt_deferred_qs_irqrestore()
> 					     `\
> 					       rcu_report_qs_rdp()
> 					       `\
> 						 rdp->core_needs_qs := false;
> 
> This would let rcuc/x's rcu_check_quiescent_state() proceed further down to
> rcu_report_qs_rdp(), but if task_foo's earlier rcu_report_qs_rdp()
> invocation would have cleared the rdp grpmask from the rnp mask, so
> rcuc/x's invocation would simply bail.
> 
> Since rcu_report_qs_rdp() can be safely invoked, even if rdp->core_needs_qs
> changed, it appears safe to keep rcu_check_quiescent_state() preemptible.

Another concern...

During the preemption of rcu_check_quiescent_state() someone might report
a quiescent state on behalf of CPU x (perhaps due to its having recently
been idle) and then the RCU grace-period kthread might start running on
CPU x, where it might initialize a new grace period in rcu_gp_init().
It can then invoke __note_gp_changes(), also on CPU x.

If preempted as shown above just after checking >core_needs_qs, the
->cpu_no_qs.b.norm field will be set by the grace-period kthread, which
will cause the rcu_check_quiescent_state() function's subsequent check
of ->cpu_no_qs.b.norm to take an early exit.  So OK here.

On the other hand, if preempted just after the rcu_check_quiescent_state()
function's check of ->cpu_no_qs.b.norm, the later invocation of
rcu_report_qs_rdp() should take an early exit due to ->gp_seq mismatch.
So OK here.

However, this should be added to the commit log.  Might be a big commit
log, but mass storage is cheap these days.  ;-)

This needs a review of each and every manipulation of ->core_needs_qs
and ->cpu_no_qs.b.norm.  For example, the preemptions will cause the
scheduler to invoke RCU's context-switch hooks, which also mess with
->cpu_no_qs.b.norm.  I can get to that some time next week (or tomorrow,
if things go better than expected), but it would be good for you (and
others) to check as well.

Frederic should look this over, but I am taking a quick pass in the
meantime.  Please see below.

							Thanx, Paul

> [1]: http://lore.kernel.org/r/20210727230814.GC283787 at lothringen
> [2]: http://lore.kernel.org/r/20210729010445.GO4397 at paulmck-ThinkPad-P17-Gen-1
> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
> ---
>  kernel/rcu/tree.c        |  4 ++
>  kernel/rcu/tree.h        |  4 ++
>  kernel/rcu/tree_plugin.h | 82 +++++++++++++++++++++++++++++++++++-----
>  3 files changed, 81 insertions(+), 9 deletions(-)
> 
> diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> index 51f24ecd94b2..caadfec994f3 100644
> --- a/kernel/rcu/tree.c
> +++ b/kernel/rcu/tree.c
> @@ -87,6 +87,7 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_data, rcu_data) = {
>  	.dynticks = ATOMIC_INIT(RCU_DYNTICK_CTRL_CTR),
>  #ifdef CONFIG_RCU_NOCB_CPU
>  	.cblist.flags = SEGCBLIST_SOFTIRQ_ONLY,
> +	.nocb_local_lock =  INIT_LOCAL_LOCK(nocb_local_lock),
>  #endif
>  };
>  static struct rcu_state rcu_state = {
> @@ -2853,10 +2854,12 @@ static void rcu_cpu_kthread(unsigned int cpu)
>  {
>  	unsigned int *statusp = this_cpu_ptr(&rcu_data.rcu_cpu_kthread_status);
>  	char work, *workp = this_cpu_ptr(&rcu_data.rcu_cpu_has_work);
> +	struct rcu_data *rdp = this_cpu_ptr(&rcu_data);
>  	int spincnt;
>  
>  	trace_rcu_utilization(TPS("Start CPU kthread at rcu_run"));
>  	for (spincnt = 0; spincnt < 10; spincnt++) {
> +		rcu_nocb_local_lock(rdp);
>  		local_bh_disable();
>  		*statusp = RCU_KTHREAD_RUNNING;
>  		local_irq_disable();
> @@ -2866,6 +2869,7 @@ static void rcu_cpu_kthread(unsigned int cpu)
>  		if (work)
>  			rcu_core();
>  		local_bh_enable();
> +		rcu_nocb_local_unlock(rdp);
>  		if (*workp == 0) {
>  			trace_rcu_utilization(TPS("End CPU kthread at rcu_wait"));
>  			*statusp = RCU_KTHREAD_WAITING;
> diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
> index 305cf6aeb408..aa6831255fec 100644
> --- a/kernel/rcu/tree.h
> +++ b/kernel/rcu/tree.h
> @@ -210,6 +210,8 @@ struct rcu_data {
>  	struct timer_list nocb_timer;	/* Enforce finite deferral. */
>  	unsigned long nocb_gp_adv_time;	/* Last call_rcu() CB adv (jiffies). */
>  
> +	local_lock_t nocb_local_lock;

Should this go near the beginning of the structure, given that code
paths taking this lock tend to access ->cpu_no_qs, ->core_needs_qs,
and so on?

Given that it is used to protect core processing (not just offloaded
callbacks), might ->core_local_lock be a better name?

Please keep in mind that you can build kernels that offload callbacks
but that still use softirq for RCU core processing.  And vice versa,
that is, kernels that use rcuc kthreads but do not offload callbacks.

> +
>  	/* The following fields are used by call_rcu, hence own cacheline. */
>  	raw_spinlock_t nocb_bypass_lock ____cacheline_internodealigned_in_smp;
>  	struct rcu_cblist nocb_bypass;	/* Lock-contention-bypass CB list. */
> @@ -445,6 +447,8 @@ static void rcu_nocb_unlock(struct rcu_data *rdp);
>  static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
>  				       unsigned long flags);
>  static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp);
> +static void rcu_nocb_local_lock(struct rcu_data *rdp);
> +static void rcu_nocb_local_unlock(struct rcu_data *rdp);
>  #ifdef CONFIG_RCU_NOCB_CPU
>  static void __init rcu_organize_nocb_kthreads(void);
>  #define rcu_nocb_lock_irqsave(rdp, flags)				\
> diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
> index 0ff5e4fb933e..11c4ff00afde 100644
> --- a/kernel/rcu/tree_plugin.h
> +++ b/kernel/rcu/tree_plugin.h
> @@ -21,6 +21,17 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
>  	return lockdep_is_held(&rdp->nocb_lock);
>  }
>  
> +static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
> +{
> +	return lockdep_is_held(
> +#ifdef CONFIG_PREEMPT_RT
> +		&rdp->nocb_local_lock.lock
> +#else
> +		&rdp->nocb_local_lock
> +#endif

It would be good if this was abstracted.  Or is this the only place
in the kernel that needs this #ifdef?  Maybe a lockdep_is_held_rt()
or lockdep_is_held_local(), as the case may be?

> +	);
> +}
> +
>  static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
>  {
>  	/* Race on early boot between thread creation and assignment */
> @@ -38,7 +49,10 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
>  {
>  	return 0;
>  }
> -
> +static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
> +{
> +	return 0;

This is backwards of normal lockdep practice, which defaults to locks
always held.  And that will be what happens once lockdep has detected
its first deadlock, correct?  At which point, this function and its
earlier instance will be in conflict.

Or is there some subtle reason why this conflict would be OK?

> +}
>  static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
>  {
>  	return false;
> @@ -46,23 +60,44 @@ static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
>  
>  #endif /* #ifdef CONFIG_RCU_NOCB_CPU */
>  
> +/*
> + * Is a local read of the rdp's offloaded state safe and stable?
> + * See rcu_nocb_local_lock() & family.
> + */
> +static inline bool rcu_local_offload_access_safe(struct rcu_data *rdp)
> +{
> +	if (!preemptible())
> +		return true;
> +
> +	if (!migratable()) {
> +		if (!IS_ENABLED(CONFIG_RCU_NOCB))

Do we also need to consult the use_softirq module parameter that controls
whether or not there are rcuc kthreads?

Actually, if !IS_ENABLED(CONFIG_RCU_NOCB) then rcu_rdp_is_offloaded()
can simply return false without bothering with the RCU_LOCKDEP_WARN().
Might be worth getting that out of the way of the RCU_LOCKDEP_WARN()
condition.  ;-)

> +			return true;
> +
> +		return rcu_lockdep_is_held_nocb_local(rdp);
> +	}
> +
> +	return false;
> +}
> +
>  static bool rcu_rdp_is_offloaded(struct rcu_data *rdp)
>  {
>  	/*
> -	 * In order to read the offloaded state of an rdp is a safe
> -	 * and stable way and prevent from its value to be changed
> -	 * under us, we must either hold the barrier mutex, the cpu
> -	 * hotplug lock (read or write) or the nocb lock. Local
> -	 * non-preemptible reads are also safe. NOCB kthreads and
> -	 * timers have their own means of synchronization against the
> -	 * offloaded state updaters.
> +	 * In order to read the offloaded state of an rdp is a safe and stable
> +	 * way and prevent from its value to be changed under us, we must either...
>  	 */
>  	RCU_LOCKDEP_WARN(
> +		// ...hold the barrier mutex...
>  		!(lockdep_is_held(&rcu_state.barrier_mutex) ||
> +		  // ... the cpu hotplug lock (read or write)...
>  		  (IS_ENABLED(CONFIG_HOTPLUG_CPU) && lockdep_is_cpus_held()) ||
> +		  // ... or the NOCB lock.
>  		  rcu_lockdep_is_held_nocb(rdp) ||
> +		  // Local reads still require the local state to remain stable
> +		  // (preemption disabled / local lock held)
>  		  (rdp == this_cpu_ptr(&rcu_data) &&
> -		   !(IS_ENABLED(CONFIG_PREEMPT_COUNT) && preemptible())) ||
> +		   rcu_local_offload_access_safe(rdp)) ||
> +		  // NOCB kthreads and timers have their own means of synchronization
> +		  // against the offloaded state updaters.
>  		  rcu_current_is_nocb_kthread(rdp)),
>  		"Unsafe read of RCU_NOCB offloaded state"
>  	);
> @@ -1629,6 +1664,22 @@ static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
>  	}
>  }
>  
> +/*
> + * The invocation of rcu_core() within the RCU core kthreads remains preemptible
> + * under PREEMPT_RT, thus the offload state of a CPU could change while
> + * said kthreads are preempted. Prevent this from happening by protecting the
> + * offload state with a local_lock().
> + */
> +static void rcu_nocb_local_lock(struct rcu_data *rdp)
> +{
> +	local_lock(&rcu_data.nocb_local_lock);
> +}
> +
> +static void rcu_nocb_local_unlock(struct rcu_data *rdp)
> +{
> +	local_unlock(&rcu_data.nocb_local_lock);
> +}
> +
>  /* Lockdep check that ->cblist may be safely accessed. */
>  static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp)
>  {
> @@ -2396,6 +2447,7 @@ static int rdp_offload_toggle(struct rcu_data *rdp,
>  	if (rdp->nocb_cb_sleep)
>  		rdp->nocb_cb_sleep = false;
>  	rcu_nocb_unlock_irqrestore(rdp, flags);
> +	rcu_nocb_local_unlock(rdp);
>  
>  	/*
>  	 * Ignore former value of nocb_cb_sleep and force wake up as it could
> @@ -2427,6 +2479,7 @@ static long rcu_nocb_rdp_deoffload(void *arg)
>  
>  	pr_info("De-offloading %d\n", rdp->cpu);
>  
> +	rcu_nocb_local_lock(rdp);
>  	rcu_nocb_lock_irqsave(rdp, flags);
>  	/*
>  	 * Flush once and for all now. This suffices because we are
> @@ -2509,6 +2562,7 @@ static long rcu_nocb_rdp_offload(void *arg)
>  	 * Can't use rcu_nocb_lock_irqsave() while we are in
>  	 * SEGCBLIST_SOFTIRQ_ONLY mode.
>  	 */
> +	rcu_nocb_local_lock(rdp);
>  	raw_spin_lock_irqsave(&rdp->nocb_lock, flags);

These look plausible at first glance, but it would be good for Frederic
to look at the exact placement of these rcu_nocb_local_lock() and
rcu_nocb_local_unlock() calls.

>  	/*
> @@ -2868,6 +2922,16 @@ static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
>  	local_irq_restore(flags);
>  }
>  
> +/* No ->nocb_local_lock to acquire. */
> +static void rcu_nocb_local_lock(struct rcu_data *rdp)
> +{
> +}
> +
> +/* No ->nocb_local_lock to release. */
> +static void rcu_nocb_local_unlock(struct rcu_data *rdp)
> +{
> +}
> +
>  /* Lockdep check that ->cblist may be safely accessed. */
>  static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp)
>  {
> -- 
> 2.25.1
> 


From joel at jms.id.au  Thu Aug 12 18:29:17 2021
From: joel at jms.id.au (Joel Stanley)
Date: Fri, 13 Aug 2021 01:29:17 +0000
Subject: [PATCH v2 4/6] ARM: dts: aspeed: Add Facebook Cloudripper
 (AST2600) BMC
In-Reply-To: <20210805222818.8391-5-rentao.bupt@gmail.com>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
 <20210805222818.8391-5-rentao.bupt@gmail.com>
Message-ID: <CACPK8XcV5On2D4D+SXnfw1M0owwfCL4Su19jOEA7yWpq+T3jLw@mail.gmail.com>

On Thu, 5 Aug 2021 at 22:28, <rentao.bupt at gmail.com> wrote:
> +&mdio1 {
> +       status = "okay";

You're enabling this but it looks like it's unused?

> +};
> +
> +&mdio3 {
> +       status = "okay";
> +
> +       ethphy1: ethernet-phy at 13 {
> +               compatible = "ethernet-phy-ieee802.3-c22";
> +               reg = <0x0d>;
> +       };
> +};
> +
> +&mac3 {
> +       status = "okay";
> +       phy-mode = "rgmii";
> +       phy-handle = <&ethphy1>;
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_rgmii4_default>;
> +};


From rex-bc.chen at mediatek.com  Thu Aug 12 19:06:30 2021
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Fri, 13 Aug 2021 10:06:30 +0800
Subject: [V1] drm/panel: panel-simple: Add delay for LG LP120UP1
Message-ID: <20210813020630.12052-1-rex-bc.chen@mediatek.com>

Add power sequence for LG LP120UP1.

Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 21939d4..15cefb0 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -2886,6 +2886,11 @@ static const struct panel_desc lg_lp120up1 = {
 		.width = 267,
 		.height = 183,
 	},
+	.delay = {
+		.prepare = 200,
+		.enable = 50,
+		.unprepare = 500,
+	},
 	.connector_type = DRM_MODE_CONNECTOR_eDP,
 };
 
-- 
2.6.4

From mpe at ellerman.id.au  Thu Aug 12 19:27:58 2021
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Fri, 13 Aug 2021 12:27:58 +1000
Subject: [PATCH -next] trap: Cleanup trap_init()
In-Reply-To: <20210812123602.76356-1-wangkefeng.wang@huawei.com>
References: <20210812123602.76356-1-wangkefeng.wang@huawei.com>
Message-ID: <87czqim635.fsf@mpe.ellerman.id.au>

Kefeng Wang <wangkefeng.wang at huawei.com> writes:
> There are some empty trap_init() in different ARCHs, introduce
> a new weak trap_init() function to cleanup them.
>
> Cc: Vineet Gupta <vgupta at kernel.org>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Yoshinori Sato <ysato at users.sourceforge.jp>
> Cc: Ley Foon Tan <ley.foon.tan at intel.com>
> Cc: Jonas Bonn <jonas at southpole.se>
> Cc: Stefan Kristiansson <stefan.kristiansson at saunalahti.fi>
> Cc: Stafford Horne <shorne at gmail.com>
> Cc: James E.J. Bottomley <James.Bottomley at HansenPartnership.com>
> Cc: Helge Deller <deller at gmx.de>
> Cc: Michael Ellerman <mpe at ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> Cc: Paul Mackerras <paulus at samba.org>
> Cc: Paul Walmsley <palmerdabbelt at google.com>
> Cc: Jeff Dike <jdike at addtoit.com>
> Cc: Richard Weinberger <richard at nod.at>
> Cc: Anton Ivanov <anton.ivanov at cambridgegreys.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  arch/arc/kernel/traps.c      | 5 -----
>  arch/arm/kernel/traps.c      | 5 -----
>  arch/h8300/kernel/traps.c    | 4 ----
>  arch/hexagon/kernel/traps.c  | 4 ----
>  arch/nds32/kernel/traps.c    | 5 -----
>  arch/nios2/kernel/traps.c    | 5 -----
>  arch/openrisc/kernel/traps.c | 5 -----
>  arch/parisc/kernel/traps.c   | 4 ----
>  arch/powerpc/kernel/traps.c  | 5 -----

Acked-by: Michael Ellerman <mpe at ellerman.id.au> (powerpc)

cheers


From hongbo.wang at nxp.com  Thu Aug 12 20:01:55 2021
From: hongbo.wang at nxp.com (hongbo.wang at nxp.com)
Date: Fri, 13 Aug 2021 11:01:55 +0800
Subject: [PATCH v1] arm64: dts: fsl: ls1028a-rdb: Add dts file to choose swp5
 as dsa master
Message-ID: <20210813030155.23097-1-hongbo.wang@nxp.com>

From: hongbo wang <hongbo.wang at nxp.com>

some use cases want to use swp4-eno2 link as ordinary data path,
so we can enable swp5 as dsa master, the data from kernel can
be transmitted to eno3, then send to swp5 via internal link, switch will
forward it to swp0-3.

the data to kernel will come from swp0-3, and received by kernel
via swp5-eno3 link.

Signed-off-by: hongbo wang <hongbo.wang at nxp.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  1 +
 .../fsl-ls1028a-rdb-dsa-swp5-eno3.dts         | 27 +++++++++++++++++++
 2 files changed, 28 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb-dsa-swp5-eno3.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 25806c4924cb..032aaf52079a 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3-ads2.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb-dsa-swp5-eno3.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-frwy.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb-dsa-swp5-eno3.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb-dsa-swp5-eno3.dts
new file mode 100644
index 000000000000..a88396c137a1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb-dsa-swp5-eno3.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for NXP LS1028A RDB with dsa master swp5-eno3.
+ *
+ * Copyright 2018-2021 NXP
+ *
+ * Hongbo Wang <hongbo.wang at nxp.com>
+ *
+ */
+
+/dts-v1/;
+#include "fsl-ls1028a-rdb.dts"
+
+&enetc_port3 {
+	status = "okay";
+};
+
+&mscc_felix_port4 {
+	label = "swp4";
+	/delete-property/ ethernet;
+	status = "okay";
+};
+
+&mscc_felix_port5 {
+	ethernet = <&enetc_port3>;
+	status = "okay";
+};
-- 
2.27.0



From miles.chen at mediatek.com  Thu Aug 12 20:24:26 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Fri, 13 Aug 2021 11:24:26 +0800
Subject: [RESEND PATCH 1/4] clk: composite: export clk_register_composite
In-Reply-To: <20210813032429.14715-1-miles.chen@mediatek.com>
References: <20210813032429.14715-1-miles.chen@mediatek.com>
Message-ID: <20210813032429.14715-2-miles.chen@mediatek.com>

To support module build of mediatek clk drivers,
it is necessary to export clk_register_composite.

Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Hanks Chen <hanks.chen at mediatek.com>
Cc: Wendell Lin <wendell.lin at mediatek.com>
Cc: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/clk-composite.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 0506046a5f4b..c7b97fb0051b 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -362,6 +362,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 		return ERR_CAST(hw);
 	return hw->clk;
 }
+EXPORT_SYMBOL_GPL(clk_register_composite);
 
 struct clk *clk_register_composite_pdata(struct device *dev, const char *name,
 			const struct clk_parent_data *parent_data,
-- 
2.18.0

From miles.chen at mediatek.com  Thu Aug 12 20:24:25 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Fri, 13 Aug 2021 11:24:25 +0800
Subject: [RESEND PATCH 0/4] clk: mediatek: modularize COMMON_CLK_MT6779
Message-ID: <20210813032429.14715-1-miles.chen@mediatek.com>

This patch set makes COMMON_CLK_MEDIATEK and COMMON_CLK_MT6779*
be able to built as kernel modules. Necessary symbols are exported
in this patch.

In previous discussion [1], Stephen commented that there must
be a user before exporting a symbol:

"
Is the mediatek driver compilable as a module? Last time I checked it
wasn't a module. I want an upstream modular driver that uses the symbol.
Otherwise we're exporting symbols when it doesn't need to be.
"

[1] https://lore.kernel.org/patchwork/patch/1278089/

Miles Chen (4):
  clk: composite: export clk_register_composite
  clk: mediatek: modularize COMMON_CLK_MEDIATEK
  clk: mediatek: modularize COMMON_CLK_MT6779*
  clk: mediatek: use tristate for COMMON_CLK_MEDAITEK and
    COMMON_CLK_MT6779

 drivers/clk/clk-composite.c            |  1 +
 drivers/clk/mediatek/Kconfig           | 20 ++++++++++----------
 drivers/clk/mediatek/clk-apmixed.c     |  3 +++
 drivers/clk/mediatek/clk-cpumux.c      |  3 +++
 drivers/clk/mediatek/clk-gate.c        |  8 ++++++++
 drivers/clk/mediatek/clk-mt6779-aud.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-cam.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-img.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-ipe.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-mfg.c  |  2 ++
 drivers/clk/mediatek/clk-mt6779-mm.c   |  2 ++
 drivers/clk/mediatek/clk-mt6779-vdec.c |  2 ++
 drivers/clk/mediatek/clk-mt6779-venc.c |  2 ++
 drivers/clk/mediatek/clk-mt6779.c      |  2 ++
 drivers/clk/mediatek/clk-mtk.c         |  8 ++++++++
 drivers/clk/mediatek/clk-mux.c         |  4 ++++
 drivers/clk/mediatek/clk-pll.c         |  4 ++++
 drivers/clk/mediatek/reset.c           |  2 ++
 18 files changed, 61 insertions(+), 10 deletions(-)

-- 
2.18.0

From miles.chen at mediatek.com  Thu Aug 12 20:24:29 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Fri, 13 Aug 2021 11:24:29 +0800
Subject: [RESEND PATCH 4/4] clk: mediatek: use tristate for
 COMMON_CLK_MEDAITEK and COMMON_CLK_MT6779
In-Reply-To: <20210813032429.14715-1-miles.chen@mediatek.com>
References: <20210813032429.14715-1-miles.chen@mediatek.com>
Message-ID: <20210813032429.14715-5-miles.chen@mediatek.com>

Now we have all necessary exported symbols, change
COMMON_CLK_MEDAITEK and COMMON_CLK_MT6779* to tristate.

Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Hanks Chen <hanks.chen at mediatek.com>
Cc: Wendell Lin <wendell.lin at mediatek.com>
Cc: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/Kconfig | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 886e2d9fced5..62ed2054a849 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -6,7 +6,7 @@ menu "Clock driver for MediaTek SoC"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 
 config COMMON_CLK_MEDIATEK
-	bool
+	tristate
 	select RESET_CONTROLLER
 	help
 	  MediaTek SoCs' clock support.
@@ -204,7 +204,7 @@ config COMMON_CLK_MT6765_MIPI2BSYS
          This driver supports MediaTek MT6765 mipi2bsys clocks.
 
 config COMMON_CLK_MT6779
-	bool "Clock driver for MediaTek MT6779"
+	tristate "Clock driver for MediaTek MT6779"
 	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
 	select COMMON_CLK_MEDIATEK
 	default ARCH_MEDIATEK && ARM64
@@ -212,49 +212,49 @@ config COMMON_CLK_MT6779
 	  This driver supports MediaTek MT6779 basic clocks.
 
 config COMMON_CLK_MT6779_MMSYS
-	bool "Clock driver for MediaTek MT6779 mmsys"
+	tristate "Clock driver for MediaTek MT6779 mmsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 mmsys clocks.
 
 config COMMON_CLK_MT6779_IMGSYS
-	bool "Clock driver for MediaTek MT6779 imgsys"
+	tristate "Clock driver for MediaTek MT6779 imgsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 imgsys clocks.
 
 config COMMON_CLK_MT6779_IPESYS
-	bool "Clock driver for MediaTek MT6779 ipesys"
+	tristate "Clock driver for MediaTek MT6779 ipesys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 ipesys clocks.
 
 config COMMON_CLK_MT6779_CAMSYS
-	bool "Clock driver for MediaTek MT6779 camsys"
+	tristate "Clock driver for MediaTek MT6779 camsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 camsys clocks.
 
 config COMMON_CLK_MT6779_VDECSYS
-	bool "Clock driver for MediaTek MT6779 vdecsys"
+	tristate "Clock driver for MediaTek MT6779 vdecsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 vdecsys clocks.
 
 config COMMON_CLK_MT6779_VENCSYS
-	bool "Clock driver for MediaTek MT6779 vencsys"
+	tristate "Clock driver for MediaTek MT6779 vencsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 vencsys clocks.
 
 config COMMON_CLK_MT6779_MFGCFG
-	bool "Clock driver for MediaTek MT6779 mfgcfg"
+	tristate "Clock driver for MediaTek MT6779 mfgcfg"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 mfgcfg clocks.
 
 config COMMON_CLK_MT6779_AUDSYS
-	bool "Clock driver for Mediatek MT6779 audsys"
+	tristate "Clock driver for Mediatek MT6779 audsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports Mediatek MT6779 audsys clocks.
-- 
2.18.0

From miles.chen at mediatek.com  Thu Aug 12 20:24:27 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Fri, 13 Aug 2021 11:24:27 +0800
Subject: [RESEND PATCH 2/4] clk: mediatek: support COMMON_CLK_MEDIATEK module
 build
In-Reply-To: <20210813032429.14715-1-miles.chen@mediatek.com>
References: <20210813032429.14715-1-miles.chen@mediatek.com>
Message-ID: <20210813032429.14715-3-miles.chen@mediatek.com>

To support COMMON_CLK_MEDIATEK module build,
add MODULE_LICENSE and export necessary symbols.

Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Hanks Chen <hanks.chen at mediatek.com>
Cc: Wendell Lin <wendell.lin at mediatek.com>
Cc: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-apmixed.c | 3 +++
 drivers/clk/mediatek/clk-cpumux.c  | 3 +++
 drivers/clk/mediatek/clk-gate.c    | 8 ++++++++
 drivers/clk/mediatek/clk-mtk.c     | 8 ++++++++
 drivers/clk/mediatek/clk-mux.c     | 4 ++++
 drivers/clk/mediatek/clk-pll.c     | 4 ++++
 drivers/clk/mediatek/reset.c       | 2 ++
 7 files changed, 32 insertions(+)

diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c
index 258d128370f2..caa9119413f1 100644
--- a/drivers/clk/mediatek/clk-apmixed.c
+++ b/drivers/clk/mediatek/clk-apmixed.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/slab.h>
 
@@ -97,3 +98,5 @@ struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
 
 	return clk;
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index 79fe09028742..f85c755c9fc1 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -6,6 +6,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/mfd/syscon.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include "clk-mtk.h"
@@ -106,3 +107,5 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 
 	return 0;
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index a35cf0b22150..b02d2f74dd0d 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clkdev.h>
+#include <linux/module.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
@@ -122,24 +123,28 @@ const struct clk_ops mtk_clk_gate_ops_setclr = {
 	.enable		= mtk_cg_enable,
 	.disable	= mtk_cg_disable,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr);
 
 const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
 	.is_enabled	= mtk_cg_bit_is_set,
 	.enable		= mtk_cg_enable_inv,
 	.disable	= mtk_cg_disable_inv,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr_inv);
 
 const struct clk_ops mtk_clk_gate_ops_no_setclr = {
 	.is_enabled	= mtk_cg_bit_is_cleared,
 	.enable		= mtk_cg_enable_no_setclr,
 	.disable	= mtk_cg_disable_no_setclr,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr);
 
 const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
 	.is_enabled	= mtk_cg_bit_is_set,
 	.enable		= mtk_cg_enable_inv_no_setclr,
 	.disable	= mtk_cg_disable_inv_no_setclr,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
 
 struct clk *mtk_clk_register_gate(
 		const char *name,
@@ -181,3 +186,6 @@ struct clk *mtk_clk_register_gate(
 
 	return clk;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_gate);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index cec1c8a27211..cb2dabe60aaf 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clkdev.h>
+#include <linux/module.h>
 #include <linux/mfd/syscon.h>
 #include <linux/device.h>
 
@@ -41,6 +42,7 @@ struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
 
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(mtk_alloc_clk_data);
 
 void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 		int num, struct clk_onecell_data *clk_data)
@@ -67,6 +69,7 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 			clk_data->clks[rc->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks);
 
 void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 		int num, struct clk_onecell_data *clk_data)
@@ -93,6 +96,7 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 			clk_data->clks[ff->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
 
 int mtk_clk_register_gates_with_dev(struct device_node *node,
 		const struct mtk_gate *clks,
@@ -145,6 +149,7 @@ int mtk_clk_register_gates(struct device_node *node,
 	return mtk_clk_register_gates_with_dev(node,
 		clks, num, clk_data, NULL);
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
 
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
@@ -258,6 +263,7 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
 			clk_data->clks[mc->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_composites);
 
 void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			int num, void __iomem *base, spinlock_t *lock,
@@ -286,3 +292,5 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			clk_data->clks[mcd->id] = clk;
 	}
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index b0c61709bacc..a507eea26cc7 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -8,6 +8,7 @@
 #include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/mfd/syscon.h>
+#include <linux/module.h>
 
 #include "clk-mtk.h"
 #include "clk-mux.h"
@@ -190,3 +191,6 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_muxes);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index f440f2cd0b69..399e7b4297c8 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -7,6 +7,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/clkdev.h>
 #include <linux/delay.h>
@@ -368,3 +369,6 @@ void mtk_clk_register_plls(struct device_node *node,
 		clk_data->clks[pll->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
index cb939c071b0c..9079bfc29ec0 100644
--- a/drivers/clk/mediatek/reset.c
+++ b/drivers/clk/mediatek/reset.c
@@ -137,3 +137,5 @@ void mtk_register_reset_controller_set_clr(struct device_node *np,
 	mtk_register_reset_controller_common(np, num_regs, regofs,
 		&mtk_reset_ops_set_clr);
 }
+
+MODULE_LICENSE("GPL");
-- 
2.18.0

From miles.chen at mediatek.com  Thu Aug 12 20:24:28 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Fri, 13 Aug 2021 11:24:28 +0800
Subject: [RESEND PATCH 3/4] clk: mediatek: support COMMON_CLK_MT6779 module
 build
In-Reply-To: <20210813032429.14715-1-miles.chen@mediatek.com>
References: <20210813032429.14715-1-miles.chen@mediatek.com>
Message-ID: <20210813032429.14715-4-miles.chen@mediatek.com>

To support COMMON_CLK_MT6779* module build,
add MODULE_LICENSE and export necessary symbols.

Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Hanks Chen <hanks.chen at mediatek.com>
Cc: Wendell Lin <wendell.lin at mediatek.com>
Cc: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mt6779-aud.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-cam.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-img.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-ipe.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-mfg.c  | 2 ++
 drivers/clk/mediatek/clk-mt6779-mm.c   | 2 ++
 drivers/clk/mediatek/clk-mt6779-vdec.c | 2 ++
 drivers/clk/mediatek/clk-mt6779-venc.c | 2 ++
 drivers/clk/mediatek/clk-mt6779.c      | 2 ++
 9 files changed, 18 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mt6779-aud.c b/drivers/clk/mediatek/clk-mt6779-aud.c
index 11b209f95e25..439c0bc94b73 100644
--- a/drivers/clk/mediatek/clk-mt6779-aud.c
+++ b/drivers/clk/mediatek/clk-mt6779-aud.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -115,3 +116,4 @@ static struct platform_driver clk_mt6779_aud_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_aud_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-cam.c b/drivers/clk/mediatek/clk-mt6779-cam.c
index 244d4208b7fb..c99ddb210b70 100644
--- a/drivers/clk/mediatek/clk-mt6779-cam.c
+++ b/drivers/clk/mediatek/clk-mt6779-cam.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -64,3 +65,4 @@ static struct platform_driver clk_mt6779_cam_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_cam_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-img.c b/drivers/clk/mediatek/clk-mt6779-img.c
index 26292a45c613..bf652052879c 100644
--- a/drivers/clk/mediatek/clk-mt6779-img.c
+++ b/drivers/clk/mediatek/clk-mt6779-img.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -56,3 +57,4 @@ static struct platform_driver clk_mt6779_img_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_img_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-ipe.c b/drivers/clk/mediatek/clk-mt6779-ipe.c
index bb519075639c..a1a1c9cb329a 100644
--- a/drivers/clk/mediatek/clk-mt6779-ipe.c
+++ b/drivers/clk/mediatek/clk-mt6779-ipe.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -58,3 +59,4 @@ static struct platform_driver clk_mt6779_ipe_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_ipe_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-mfg.c b/drivers/clk/mediatek/clk-mt6779-mfg.c
index c6ee2a89c070..9bf48c56d852 100644
--- a/drivers/clk/mediatek/clk-mt6779-mfg.c
+++ b/drivers/clk/mediatek/clk-mt6779-mfg.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -53,3 +54,4 @@ static struct platform_driver clk_mt6779_mfg_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_mfg_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-mm.c b/drivers/clk/mediatek/clk-mt6779-mm.c
index 059c1a41ac7a..d5ead5531026 100644
--- a/drivers/clk/mediatek/clk-mt6779-mm.c
+++ b/drivers/clk/mediatek/clk-mt6779-mm.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -106,3 +107,4 @@ static struct platform_driver clk_mt6779_mm_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_mm_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-vdec.c b/drivers/clk/mediatek/clk-mt6779-vdec.c
index 1900da2586a1..ff7390e4c5f5 100644
--- a/drivers/clk/mediatek/clk-mt6779-vdec.c
+++ b/drivers/clk/mediatek/clk-mt6779-vdec.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -65,3 +66,4 @@ static struct platform_driver clk_mt6779_vdec_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_vdec_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-venc.c b/drivers/clk/mediatek/clk-mt6779-venc.c
index b41d1f859edc..489bf64346e3 100644
--- a/drivers/clk/mediatek/clk-mt6779-venc.c
+++ b/drivers/clk/mediatek/clk-mt6779-venc.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -56,3 +57,4 @@ static struct platform_driver clk_mt6779_venc_drv = {
 };
 
 builtin_platform_driver(clk_mt6779_venc_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c
index 6e0d3a166729..9825385c9f94 100644
--- a/drivers/clk/mediatek/clk-mt6779.c
+++ b/drivers/clk/mediatek/clk-mt6779.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -1314,3 +1315,4 @@ static int __init clk_mt6779_init(void)
 }
 
 arch_initcall(clk_mt6779_init);
+MODULE_LICENSE("GPL");
-- 
2.18.0

From clin at suse.com  Thu Aug 12 20:28:04 2021
From: clin at suse.com (Chester Lin)
Date: Fri, 13 Aug 2021 11:28:04 +0800
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-5-clin@suse.com>
 <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>
Message-ID: <YRXmxD5u7drotWxP@linux-8mug>

On Thu, Aug 12, 2021 at 07:26:28PM +0200, Andreas F?rber wrote:
> Hi Chester et al.,
> 
> On 05.08.21 08:54, Chester Lin wrote:
> > Add an initial dtsi file for generic SoC features of NXP S32G2.
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  arch/arm64/boot/dts/freescale/s32g2.dtsi | 98 ++++++++++++++++++++++++
> >  1 file changed, 98 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > new file mode 100644
> > index 000000000000..3321819c1a2d
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> 
> Note: This DT is for running on the Cortex-A53 cores, but S32G2 also has
> Cortex-M7 cores. For Vybrid SoCs, DTs later got contributed to also run
> on its Cortex-M4 core:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf610.dtsi
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf500.dtsi
> vs.
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf610m4.dtsi
> 
> Should we plan for this in our file naming here and in following patches
> (e.g., s32g2-a53* vs. s32g2-m7*)? To me, a later concatenation of
> s32g274am7* would look awkward, and s32g274a-m7* would sort between -evb
> and -rdb2.
> 
> > @@ -0,0 +1,98 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> > +/*
> 
>  * NXP S32G2 SoC family
>  *
> ?

Will add it.

> 
> @NXP: Are any models other than 274A in the queue that we should
> distinguish between s32g2.dtsi and s32g274a.dtsi here already?
> 
> > + * Copyright (c) 2021 SUSE LLC
> > + */
> > +
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +
> > +/ {
> > +	compatible = "fsl,s32g2";
> > +	interrupt-parent = <&gic>;
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> > +
> > +	cpus {
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +
> > +		cpu0: cpu at 0 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x0>;
> > +			enable-method = "psci";
> > +			next-level-cache = <&cluster0_l2>;
> > +		};
> > +
> > +		cpu1: cpu at 1 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x1>;
> > +			enable-method = "psci";
> > +			next-level-cache = <&cluster0_l2>;
> > +		};
> > +
> > +		cpu2: cpu at 100 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x100>;
> > +			enable-method = "psci";
> > +			next-level-cache = <&cluster1_l2>;
> > +		};
> > +
> > +		cpu3: cpu at 101 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a53";
> > +			reg = <0x101>;
> > +			enable-method = "psci";
> > +			next-level-cache = <&cluster1_l2>;
> > +		};
> > +
> > +		cluster0_l2: l2-cache0 {
> > +			compatible = "cache";
> > +		};
> > +
> > +		cluster1_l2: l2-cache1 {
> > +			compatible = "cache";
> > +		};
> > +	};
> > +
> > +	pmu {
> > +		compatible = "arm,cortex-a53-pmu";
> > +		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
> 
> interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;

Actually I traced the pmu_parse_irqs() and found that this SoC never falls into
the pmu_has_irq_affinity() check because it's a percpu IRQ so the flow ends at
pmu_parse_percpu_irq(). But it looks good to me to have an interrupt-affinity
to indicate that each core has an associated PPI for PMU events as the binding
file has suggested.

> 
> > +	};
> > +
> > +	timer {
> > +		compatible = "arm,armv8-timer";
> > +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> > +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> > +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> > +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> > +	};
> > +
> > +	psci {
> > +		compatible = "arm,psci-1.0";
> > +		method = "smc";
> > +	};
> 
> Should we move this into a /firmware node, to group with future OP-TEE?
> 

So far I can only see a few examples [e.g. ti/k3-*] which add the psci node
into /firmware but logically we should do it.

> > +
> > +	soc {
> > +		compatible = "simple-bus";
> > +		interrupt-parent = <&gic>;
> 
> Duplicate, already set on root node.

Will remove it.

> 
> > +		#address-cells = <2>;
> > +		#size-cells = <2>;
> 
> Why? Does it have any peripherals that go beyond 32-bit space?
> For 64-bit Realtek platforms Rob had asked me to use 1, if possible.
> I do understand that for /memory nodes we do have high-memory addresses,
> so 2 for the root node looks correct.

Actually it's a limitation due to [PATCH 7/8] "arm64: dts: s32g2: add memory
nodes for evb and rdb2", which adds memory nodes to indicate maximum system
RAM size combined by two separated memory banks, and the second bank starts
from the offset 0x880000000 so that's why we need 64-bit address space here.
Please feel free to let me know if any suggestion.

> 
> > +
> 
> Please drop this white line.
> 

Will do.

> > +		ranges;
> 
> According to Rob, the /soc ranges should exclude any RAM ranges for
> safety reasons. Compare:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/realtek/rtd129x.dtsi
> 
> If you're lacking the maximum RAM areas to carve out, NXP is in CC to
> help out :) and the EVB and RDB2 boards should give you starting numbers
> that could be enlarged later if needed.

I added memory nodes in [PATCH 7/8] "arm64: dts: s32g2: add memory nodes for
evb and rdb2" to describe maximum RAM areas, which are based on the information
we found in NXP BSP and boards.

@NXP: Please feel free to correct me if anything wrong, thanks.

> 
> > +
> > +		gic: interrupt-controller at 50800000 {
> > +			compatible = "arm,gic-v3";
> > +			#interrupt-cells = <3>;
> > +			interrupt-controller;
> > +			reg = <0 0x50800000 0 0x10000>,
> > +			      <0 0x50880000 0 0x200000>,
> > +			      <0 0x50400000 0 0x2000>,
> > +			      <0 0x50410000 0 0x2000>,
> > +			      <0 0x50420000 0 0x2000>;
> 
> Please order reg after compatible by convention, and sort
> interrupt-controller or at least #interrupt-cells (applying to
> consumers) last, after the below one applying to this device itself.
> 

Will do.

> > +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
> > +						 IRQ_TYPE_LEVEL_HIGH)>;
> > +		};
> 
> CC'ing Marc for additional GIC scrutiny, often the sizes are wrong.
> 

IIRC, gic-v3 shouldn't have this kind of interrupt specifier. It's my fault and
will fix it. Feel free to let me know if any suggestions.

> > +	};
> > +};
> 
> Thanks,
> Andreas
> 
> -- 
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 N?rnberg, Germany
> GF: Felix Imend?rffer
> HRB 36809 (AG N?rnberg)
> 



From rentao.bupt at gmail.com  Thu Aug 12 20:40:17 2021
From: rentao.bupt at gmail.com (Tao Ren)
Date: Thu, 12 Aug 2021 20:40:17 -0700
Subject: [PATCH v2 4/6] ARM: dts: aspeed: Add Facebook Cloudripper
 (AST2600) BMC
In-Reply-To: <CACPK8XcV5On2D4D+SXnfw1M0owwfCL4Su19jOEA7yWpq+T3jLw@mail.gmail.com>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
 <20210805222818.8391-5-rentao.bupt@gmail.com>
 <CACPK8XcV5On2D4D+SXnfw1M0owwfCL4Su19jOEA7yWpq+T3jLw@mail.gmail.com>
Message-ID: <20210813034016.GA21895@taoren-ubuntu-R90MNF91>

On Fri, Aug 13, 2021 at 01:29:17AM +0000, Joel Stanley wrote:
> On Thu, 5 Aug 2021 at 22:28, <rentao.bupt at gmail.com> wrote:
> > +&mdio1 {
> > +       status = "okay";
> 
> You're enabling this but it looks like it's unused?

Thanks Joel for the careful review. The MDIO controller is not paired
with BMC MAC; instead, it's connected to the MDC/MDIO interface of the
on-board switch (whose ports are connected to BMC, Host and front panel
management port).

In other word, the MDIO controller is used, but we do need some user
space scripts to control the controller. What's your suggestion? For
example, should I add some comments to explain the purpose?


Cheers,

Tao

> 
> > +};
> > +
> > +&mdio3 {
> > +       status = "okay";
> > +
> > +       ethphy1: ethernet-phy at 13 {
> > +               compatible = "ethernet-phy-ieee802.3-c22";
> > +               reg = <0x0d>;
> > +       };
> > +};
> > +
> > +&mac3 {
> > +       status = "okay";
> > +       phy-mode = "rgmii";
> > +       phy-handle = <&ethphy1>;
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&pinctrl_rgmii4_default>;
> > +};


From joel at jms.id.au  Thu Aug 12 21:13:23 2021
From: joel at jms.id.au (Joel Stanley)
Date: Fri, 13 Aug 2021 04:13:23 +0000
Subject: [PATCH v2 4/6] ARM: dts: aspeed: Add Facebook Cloudripper
 (AST2600) BMC
In-Reply-To: <20210813034016.GA21895@taoren-ubuntu-R90MNF91>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
 <20210805222818.8391-5-rentao.bupt@gmail.com>
 <CACPK8XcV5On2D4D+SXnfw1M0owwfCL4Su19jOEA7yWpq+T3jLw@mail.gmail.com>
 <20210813034016.GA21895@taoren-ubuntu-R90MNF91>
Message-ID: <CACPK8XeoV8DqDNYFgK97r-Q0DebNjrmgUTydKSYmGt+3x=-vOQ@mail.gmail.com>

On Fri, 13 Aug 2021 at 03:40, Tao Ren <rentao.bupt at gmail.com> wrote:
>
> On Fri, Aug 13, 2021 at 01:29:17AM +0000, Joel Stanley wrote:
> > On Thu, 5 Aug 2021 at 22:28, <rentao.bupt at gmail.com> wrote:
> > > +&mdio1 {
> > > +       status = "okay";
> >
> > You're enabling this but it looks like it's unused?
>
> Thanks Joel for the careful review. The MDIO controller is not paired
> with BMC MAC; instead, it's connected to the MDC/MDIO interface of the
> on-board switch (whose ports are connected to BMC, Host and front panel
> management port).

I see!

>
> In other word, the MDIO controller is used, but we do need some user
> space scripts to control the controller. What's your suggestion? For
> example, should I add some comments to explain the purpose?

Yes, that would make sense.

I've applied your patch, so if you want to add comments please send a
diff against this tree:

https://git.kernel.org/pub/scm/linux/kernel/git/joel/bmc.git/log/?h=dt-for-v5.15


From quic_tsoni at quicinc.com  Thu Aug 12 21:31:08 2021
From: quic_tsoni at quicinc.com (Trilok Soni)
Date: Thu, 12 Aug 2021 21:31:08 -0700
Subject: [PATCH 0/3] soc: qcom: Add download mode support for QTI platforms
In-Reply-To: <CAE-0n52PzadMxB_4h2DGJGLO++Bu_PCSsxS8NHe+cuhv=Mw0sA@mail.gmail.com>
References: <cover.1628757036.git.saiprakash.ranjan@codeaurora.org>
 <CAE-0n52PzadMxB_4h2DGJGLO++Bu_PCSsxS8NHe+cuhv=Mw0sA@mail.gmail.com>
Message-ID: <0178821e-a8cd-87c8-640c-4928201a3b5a@quicinc.com>

Stephen,

On 8/12/2021 5:16 PM, Stephen Boyd wrote:
> Quoting Sai Prakash Ranjan (2021-08-12 02:17:39)
>> Collecting ramdumps on QTI platforms mainly require two things,
>> SDI (System Debug Image) enabled firmware and kernel support to
>> configure download mode cookies and SDI settings. Ramdumps can
>> be collected once the system enters the download mode. To enter
>> download mode, magic values or cookies need to be set in IMEM
>> which is used by firmware to decide to enter download mode or not.
>> Download mode cookies remain the same across targets and SDI disable
>> register needs to be set or SDI needs to be disabled in case of normal
>> reboot since ramdumps are supposed to be for crash debugging and
>> not for every reboot. This series adds the kernel support required
>> to enter download mode.
> 
> I don't recall if we discussed this on the list, but I'd really prefer
> that we don't make kernel changes to support this beyond implementing
> PSCI SYSTEM_RESET2 support and then some sort of vendor specific (or if
> ARM is willing to update the spec then ARM specific) reset command on
> panic reboot paths. The idea is to set the cookie in the bootloader
> before the kernel is booted, then any insta-reboots/watchdogs would go
> into download mode, no special init code required to lay down the cookie
>>   create mode 100644 drivers/soc/qcom/download_mode.c

Some discussion by Elliot on the PSCI_SYSTEM_RESET2 and vendor bits was 
done here. You may want to check.

https://lkml.org/lkml/2020/2/24/1137

---Trilok Soni


From ikjn at chromium.org  Thu Aug 12 22:26:30 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Fri, 13 Aug 2021 13:26:30 +0800
Subject: [PATCH 04/11] usb: xhci-mtk: fix use-after-free of mtk->hcd
In-Reply-To: <1627635002-24521-4-git-send-email-chunfeng.yun@mediatek.com>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
 <1627635002-24521-4-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <CAATdQgBeFHJV+=phaEBaXpKwMJygtGVzxJ0yC5hfvijpgwVMAg@mail.gmail.com>

On Fri, Jul 30, 2021 at 4:50 PM Chunfeng Yun <chunfeng.yun at mediatek.com> wrote:
>
>  BUG: KASAN: use-after-free in usb_hcd_is_primary_hcd+0x38/0x60
>  Call trace:
>   dump_backtrace+0x0/0x3dc
>   show_stack+0x20/0x2c
>   dump_stack+0x15c/0x1d4
>   print_address_description+0x7c/0x510
>   kasan_report+0x164/0x1ac
>   __asan_report_load8_noabort+0x44/0x50
>   usb_hcd_is_primary_hcd+0x38/0x60
>   xhci_mtk_runtime_suspend+0x68/0x148
>   pm_generic_runtime_suspend+0x90/0xac
>   __rpm_callback+0xb8/0x1f4
>   rpm_callback+0x54/0x1d0
>   rpm_suspend+0x4e0/0xc84
>   __pm_runtime_suspend+0xc4/0x114
>   xhci_mtk_probe+0xa58/0xd00
>
> This may happen when probe fails, needn't suspend it synchronously,
> fix it by using pm_runtime_put_noidle().
>
> Reported-by: Pi Hsun <pihsun at google.com>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Reviewed-and-Tested-by: Ikjoon Jang <ikjn at chromium.org>


> ---
>  drivers/usb/host/xhci-mtk.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
> index 2548976bcf05..cb27569186a0 100644
> --- a/drivers/usb/host/xhci-mtk.c
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -569,7 +569,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
>         xhci_mtk_ldos_disable(mtk);
>
>  disable_pm:
> -       pm_runtime_put_sync_autosuspend(dev);
> +       pm_runtime_put_noidle(dev);
>         pm_runtime_disable(dev);
>         return ret;
>  }
> --
> 2.18.0
>


From sam.shih at mediatek.com  Thu Aug 12 22:22:21 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Fri, 13 Aug 2021 13:22:21 +0800
Subject: [PATCH 01/12] dt-bindings: clock: mediatek: document clk
 bindings for mediatek mt7986 SoC
In-Reply-To: <CAGXv+5F1tPC8W6FcBqn4TdoOrSmFUr4GWpD3hQC9QsPi3o__=g@mail.gmail.com>
References: <20210726071439.14248-1-sam.shih@mediatek.com>
 <20210726071439.14248-2-sam.shih@mediatek.com>
 <CAGXv+5GeEBAkXKfA=S7XGOLYtCRihP5ov6kSiw+eevPAi74GAQ@mail.gmail.com>
 <083a0e8fdd07c0f940285dce2dc26cb0f5e798a6.camel@mediatek.com>
 <CAGXv+5F1tPC8W6FcBqn4TdoOrSmFUr4GWpD3hQC9QsPi3o__=g@mail.gmail.com>
Message-ID: <8b14d7a730bd787a9d162d368a2d3aae64256ca6.camel@mediatek.com>

Hi,

Sorry for the late reply,I have prepared v2 patches, but for some of your suggestions, I think
it is a bit difficult to apply to our drivers.


On Fri, 2021-07-30 at 14:30 +0800, Chen-Yu Tsai wrote:
> On Fri, Jul 30, 2021 at 2:01 PM Sam Shih <sam.shih at mediatek.com>
> wrote:
> > 
> > Hi,
> > 
> > On Mon, 2021-07-26 at 17:20 +0800, Chen-Yu Tsai wrote:
> > > Furthermore, based on the driver patch and the fact that they
> > > share
> > > the
> > > same compatible string, it seems you shouldn't need to have two
> > > compatible
> > > strings for two identical hardware blocks. The need for separate
> > > entries
> > > to have different clock names is an implementation detail. Please
> > > consider
> > > using and supporting clock-output-names.
> > > 
> > > Also, please check out the MT8195 clock driver series [1]. I'm
> > > guessing
> > > a lot of the comments apply to this one as well.
> > > 
> > > Regards
> > > ChenYu
> > > 
> > > [1]
> > > 
https://urldefense.com/v3/__https://lore.kernel.org/linux-mediatek/20210616224743.5109-1-chun-jie.chen at mediatek.com/T/*t__;Iw!!CTRNKA9wMg0ARbw!29pb4TJiGHLvLbYJgDB2Dhf8Mpw5VU8zV-W3NrMan_RPQrtWT2EdRTyyjWpu0nZE$
> > > 
> > > 
> > 
> > I have organized your comments in "Mediatek MT8195 clock support"
> > series into the following list, reply to your here:
> > 
> > > dt-binding: Move the not-to-be-exposed clock to driver directory
> > > or
> > > simply left out
> > 
> > Okay, thanks for your comment, I will update this in the next patch
> > set
> 
> See the following file for an example:
> 
> 

> https://urldefense.com/v3/__https://elixir.bootlin.com/linux/latest/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.h__;!!CTRNKA9wMg0ARbw!3--UEpFFGeZ_WTCaWsj_9vbbb4SSE1vPCILFleThzpa1nq7mveFfQMDqbacdT5I6$ 
> 
> drivers would not be able to use the non-exported intermediate
> clocks.
> 
Thanks, I well delete some clocks that are not expected to be use in
device tree.

> > > describe some of the clock relations between the various clock
> > > controllers
> > 
> > I have checked the files in
> > "Documentation/devicetree/bindings/arm/mediatek", It seems that all
> > MediaTek SoC clocks are simply described by each controller, like
> > "mediatek,infracfg.txt" and "mediatek,topckgen.txt", and those
> > document
> > only include compatible strings information and examples.
> > Can we insert the clock relationship of MT7986 directlly in common
> > documents?
> 
> What I meant was that since each clock controller hardware block has
> one or many clock inputs, these should be described in the binding
> as required "clocks" and "clock-names" properties.
> 
> So it's not about describing the actual relationship or clock tree,
> but just having the inputs accurately described.
> 
> > Or we should add a new "mediatek,mt7986-clock.yaml" and move
> > compatible
> > strings information and example to this file, and insert clock
> > relationship descriptions to this file? Wouldn?t it be strange to
> > skip
> > existing files and create a new one?
> 
> I think that is a question for the device tree binding maintainer,
> Rob.
> At least for Mediatek stuff, there seem to be many separate files.
> 
> > > external oscillator's case, the oscillator is described in the
> > > device
> > > tree
> > 
> > Yes, we have "clkxtal" in the DT, which stands for external
> > oscillator,
> > All clocks in apmixedsys use "clkxtal" as the parent clock
> 
> So for the apmixedsys device node, it would at least have something
> like:
> 
>     clocks = <&clkxtal>;
>     clock-names = "xtal";
> 
> For topckgen, since it has xtal and some PLLs from apmixedsys as
> inputs:
> 
>     clocks = <&clkxtal>, <&apmixedsys CLK_ID_PLLXXX>, <&apmixedsys
> CLK_ID_PLLYYY>;
>     clock-names = "xtal", "pllXXX", "pllYYY"
> 
> The above is just an example. You should adapt it to fit your
> hardware
> description. And the bindings should describe what is required. Note
> that the clock names used here are local to this device node. They do
> not need to match what the clock driver uses for the global name. So
> just go with something descriptive.
> 
> The point is, cross hardware block dependencies should be clearly
> described
> in the device tree, instead of implicitly buried in the clock
> drivers.
> 

Make cross hardware block dependencies clearly described in the device
tree seems unsuitable between "topck" and "infra" block of mt7986.

In your example, passing "clkxtal" from the device tree seems ok. Even
for topckgen, passing "clkxtal", "pllXXX", "pllYYY" from the device
tree and using these clocks as the parent clock of topckgen also seems
to work. It is feasible because it is not much clock between these two
hardware blocks.

But for the clock releationship between "topckg" and "infra", they are
very complicated in hardware design. There are dozens of clocks and
interact with each other. If we want to describe these relationships in
the device tree, we need to use a big array inside the device tree and
make device tree looks very messy. Therefore, our previous method of
writing a clock driver is to use the global clock and descripbe the
clock releationship inside the clock driver.

               ______   ________    ________
    clkxtal --|      |  |       |.x.|       |
              |apmix.|--| topck |.x.| infra |
              |      |--|       |.x.|_______|
              |      |  |       |   ________
              |______|  |       |--|        |
                        |       |--| ethsys |
                        |_______|  |________|

Maybe we should keep the clock relationship in our clock driver like
the previous mediatek clock drivers.


> > > Dual license please (and the dts files).
> > 
> > Okay, thanks for your comment, I will update this in the next patch
> > set
> > 
> > > Why are this and other 1:1 factor clks needed? They look like
> > > placeholders. Please remove them.
> > 
> > Okay, thanks for your comment, I will update this in the next patch
> > set
> 
> Ideally the clock driver would use the device tree to get local
> references
> for this, but that is going to require some rework to Mediatek's
> common
> clock code.
> 

To transfer the clock relationship through the device tree, it is
necessary to make modifications to the common part of the mtk clock
driver that has been merged, and may also modify other mediatek clock
drivers.

Let's move to the source code:
	
apmixedsys {
    ...
}
	
topckgen {
    ...
    clocks = ... , <&apmixedsys NET2PLL> , ... ;
    clock-names = ... , "net2pll" , ... ;
}

char *parent_name;
    for each clk in <device_tree_node>:
        parent_name = __clk_get_name(of_clk_get(np, i))
	
(armada-37xx-tbg.c use this method to get global name of parent clock)

Ideally, we should use the parent_name variable above to create a
clock, But mtk_fixed_factor expects input const strings
	
void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, ...)
	
struct mtk_fixed_factor {
    ...
    const char *name;
    const char *parent;
    ...
};

So we still need to use pre-defined clock name in static const clock
table even we can get clock name as variable from device tree.


static const struct mtk_fixed_factor top_divs[] __initconst = {
    ...
    FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", "net2pll", 1, 8),
    FACTOR(CK_TOP_NET2_D3_D2, "net2_d3_d2", "net2pll", 1, 2),
    ...
}



> > > Merge duplicate parent instances
> > 
> > We have considered this in the MT7986 basic clock driver, but I
> > will
> > check again. If corrections are needed, I will make changes in the
> > next
> > patch set.
> > 
> > > Leaking clk_data if some function return fail
> > 
> > Okay, thanks for your comment, I will update this in the next patch
> > set
> > 
> > > This file contains four drivers. They do not have depend on each
> > > other, and do not need to be in the same file. Please split them
> > > into
> > > differen files and preferably different patches
> > 
> > Okay, thanks for your comment, I will separate those clock drivers
> > in
> > the next patch set
> > 
> > > Is there any particular reason for arch_initcall
> > 
> > We have considered this in MT7986 basic clock driver, and use
> > CLK_OF_DECLARE instead of arch_initcall.
> 
> Having to sequence clock registration manually is likely a symptom of
> inadequate clock dependency handling. So if the drivers are only
> using
> global clock names to describe parents, what happens is that even if
> the parent isn't in the system yet, the registration is allowed to
> succeed. However since the parent clock isn't available yet, any
> calculations involving it, such as calculating clock rates, will
> yield invalid results, such as 0 clock rate.
> 
> > Another question:
> > Should the clock patches in "Add basic SoC support for MediaTek
> > mt7986"
> > need to be separated into another patch series, such as MT8195
> > "Mediatek MT8195 clock support" ?
> 
> Nope. The MT8195 team seems to be splitting things up by module, with
> the device tree being its own separate module. Ideally you want to
> send
> drivers along with the related device tree changes, so people
> reviewing
> can get a sense of how things work. And if the hardware is publicly
> available, people can actually test the changes. We can't do that if
> the
> device tree changes aren't bundled together.
> 
OK, I will keep clock patches and basic part patches in the same series
(patches v2)


Regards,
Sam
Thanks, I will delete some clocks that are not expected to b

From wenst at chromium.org  Thu Aug 12 23:15:50 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 13 Aug 2021 14:15:50 +0800
Subject: [PATCH 01/12] dt-bindings: clock: mediatek: document clk bindings
 for mediatek mt7986 SoC
In-Reply-To: <8b14d7a730bd787a9d162d368a2d3aae64256ca6.camel@mediatek.com>
References: <20210726071439.14248-1-sam.shih@mediatek.com>
 <20210726071439.14248-2-sam.shih@mediatek.com>
 <CAGXv+5GeEBAkXKfA=S7XGOLYtCRihP5ov6kSiw+eevPAi74GAQ@mail.gmail.com>
 <083a0e8fdd07c0f940285dce2dc26cb0f5e798a6.camel@mediatek.com>
 <CAGXv+5F1tPC8W6FcBqn4TdoOrSmFUr4GWpD3hQC9QsPi3o__=g@mail.gmail.com>
 <8b14d7a730bd787a9d162d368a2d3aae64256ca6.camel@mediatek.com>
Message-ID: <CAGXv+5GxXRqJqZURagNc4z=am0jhqP05eq0i64+kf457yfRoAw@mail.gmail.com>

On Fri, Aug 13, 2021 at 1:22 PM Sam Shih <sam.shih at mediatek.com> wrote:
>
> Hi,
>
> Sorry for the late reply,I have prepared v2 patches, but for some of your suggestions, I think
> it is a bit difficult to apply to our drivers.
>
>
> On Fri, 2021-07-30 at 14:30 +0800, Chen-Yu Tsai wrote:
> > On Fri, Jul 30, 2021 at 2:01 PM Sam Shih <sam.shih at mediatek.com>
> > wrote:
> > >
> > > Hi,
> > >
> > > On Mon, 2021-07-26 at 17:20 +0800, Chen-Yu Tsai wrote:
> > > > Furthermore, based on the driver patch and the fact that they
> > > > share
> > > > the
> > > > same compatible string, it seems you shouldn't need to have two
> > > > compatible
> > > > strings for two identical hardware blocks. The need for separate
> > > > entries
> > > > to have different clock names is an implementation detail. Please
> > > > consider
> > > > using and supporting clock-output-names.
> > > >
> > > > Also, please check out the MT8195 clock driver series [1]. I'm
> > > > guessing
> > > > a lot of the comments apply to this one as well.
> > > >
> > > > Regards
> > > > ChenYu
> > > >
> > > > [1]
> > > >
> https://urldefense.com/v3/__https://lore.kernel.org/linux-mediatek/20210616224743.5109-1-chun-jie.chen at mediatek.com/T/*t__;Iw!!CTRNKA9wMg0ARbw!29pb4TJiGHLvLbYJgDB2Dhf8Mpw5VU8zV-W3NrMan_RPQrtWT2EdRTyyjWpu0nZE$
> > > >
> > > >
> > >
> > > I have organized your comments in "Mediatek MT8195 clock support"
> > > series into the following list, reply to your here:
> > >
> > > > dt-binding: Move the not-to-be-exposed clock to driver directory
> > > > or
> > > > simply left out
> > >
> > > Okay, thanks for your comment, I will update this in the next patch
> > > set
> >
> > See the following file for an example:
> >
> >
>
> > https://urldefense.com/v3/__https://elixir.bootlin.com/linux/latest/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.h__;!!CTRNKA9wMg0ARbw!3--UEpFFGeZ_WTCaWsj_9vbbb4SSE1vPCILFleThzpa1nq7mveFfQMDqbacdT5I6$
> >
> > drivers would not be able to use the non-exported intermediate
> > clocks.
> >
> Thanks, I well delete some clocks that are not expected to be use in
> device tree.
>
> > > > describe some of the clock relations between the various clock
> > > > controllers
> > >
> > > I have checked the files in
> > > "Documentation/devicetree/bindings/arm/mediatek", It seems that all
> > > MediaTek SoC clocks are simply described by each controller, like
> > > "mediatek,infracfg.txt" and "mediatek,topckgen.txt", and those
> > > document
> > > only include compatible strings information and examples.
> > > Can we insert the clock relationship of MT7986 directlly in common
> > > documents?
> >
> > What I meant was that since each clock controller hardware block has
> > one or many clock inputs, these should be described in the binding
> > as required "clocks" and "clock-names" properties.
> >
> > So it's not about describing the actual relationship or clock tree,
> > but just having the inputs accurately described.
> >
> > > Or we should add a new "mediatek,mt7986-clock.yaml" and move
> > > compatible
> > > strings information and example to this file, and insert clock
> > > relationship descriptions to this file? Wouldn?t it be strange to
> > > skip
> > > existing files and create a new one?
> >
> > I think that is a question for the device tree binding maintainer,
> > Rob.
> > At least for Mediatek stuff, there seem to be many separate files.
> >
> > > > external oscillator's case, the oscillator is described in the
> > > > device
> > > > tree
> > >
> > > Yes, we have "clkxtal" in the DT, which stands for external
> > > oscillator,
> > > All clocks in apmixedsys use "clkxtal" as the parent clock
> >
> > So for the apmixedsys device node, it would at least have something
> > like:
> >
> >     clocks = <&clkxtal>;
> >     clock-names = "xtal";
> >
> > For topckgen, since it has xtal and some PLLs from apmixedsys as
> > inputs:
> >
> >     clocks = <&clkxtal>, <&apmixedsys CLK_ID_PLLXXX>, <&apmixedsys
> > CLK_ID_PLLYYY>;
> >     clock-names = "xtal", "pllXXX", "pllYYY"
> >
> > The above is just an example. You should adapt it to fit your
> > hardware
> > description. And the bindings should describe what is required. Note
> > that the clock names used here are local to this device node. They do
> > not need to match what the clock driver uses for the global name. So
> > just go with something descriptive.
> >
> > The point is, cross hardware block dependencies should be clearly
> > described
> > in the device tree, instead of implicitly buried in the clock
> > drivers.
> >
>
> Make cross hardware block dependencies clearly described in the device
> tree seems unsuitable between "topck" and "infra" block of mt7986.
>
> In your example, passing "clkxtal" from the device tree seems ok. Even
> for topckgen, passing "clkxtal", "pllXXX", "pllYYY" from the device
> tree and using these clocks as the parent clock of topckgen also seems
> to work. It is feasible because it is not much clock between these two
> hardware blocks.
>
> But for the clock releationship between "topckg" and "infra", they are
> very complicated in hardware design. There are dozens of clocks and
> interact with each other. If we want to describe these relationships in
> the device tree, we need to use a big array inside the device tree and
> make device tree looks very messy. Therefore, our previous method of
> writing a clock driver is to use the global clock and descripbe the
> clock releationship inside the clock driver.
>
>                ______   ________    ________
>     clkxtal --|      |  |       |.x.|       |
>               |apmix.|--| topck |.x.| infra |
>               |      |--|       |.x.|_______|
>               |      |  |       |   ________
>               |______|  |       |--|        |
>                         |       |--| ethsys |
>                         |_______|  |________|
>
> Maybe we should keep the clock relationship in our clock driver like
> the previous mediatek clock drivers.

Are you saying that some clocks in topck have inputs from infra?
If so, then that's a nasty circular dependency to deal with.

And to be fair, many Mediatek device tree bindings already take a large
number of clocks, so I think adding a few more isn't too bad.

> > > > Dual license please (and the dts files).
> > >
> > > Okay, thanks for your comment, I will update this in the next patch
> > > set
> > >
> > > > Why are this and other 1:1 factor clks needed? They look like
> > > > placeholders. Please remove them.
> > >
> > > Okay, thanks for your comment, I will update this in the next patch
> > > set
> >
> > Ideally the clock driver would use the device tree to get local
> > references
> > for this, but that is going to require some rework to Mediatek's
> > common
> > clock code.
> >
>
> To transfer the clock relationship through the device tree, it is
> necessary to make modifications to the common part of the mtk clock
> driver that has been merged, and may also modify other mediatek clock
> drivers.
>
> Let's move to the source code:
>
> apmixedsys {
>     ...
> }
>
> topckgen {
>     ...
>     clocks = ... , <&apmixedsys NET2PLL> , ... ;
>     clock-names = ... , "net2pll" , ... ;
> }
>
> char *parent_name;
>     for each clk in <device_tree_node>:
>         parent_name = __clk_get_name(of_clk_get(np, i))
>
> (armada-37xx-tbg.c use this method to get global name of parent clock)
>
> Ideally, we should use the parent_name variable above to create a
> clock, But mtk_fixed_factor expects input const strings
>
> void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, ...)
>
> struct mtk_fixed_factor {
>     ...
>     const char *name;
>     const char *parent;
>     ...
> };
>
> So we still need to use pre-defined clock name in static const clock
> table even we can get clock name as variable from device tree.
>
>
> static const struct mtk_fixed_factor top_divs[] __initconst = {
>     ...
>     FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", "net2pll", 1, 8),
>     FACTOR(CK_TOP_NET2_D3_D2, "net2_d3_d2", "net2pll", 1, 2),
>     ...
> }

Right. I'm not asking you to do this right away. This will end up being
a long migration over multiple releases. But it makes sense to get the
device tree bindings sorted out first.

I believe the solution is to move to `struct clk_parent_data` to replace
the pure strings. New internal APIs for the Mediatek clock driver would
need to be added, and all the drivers slowly migrated over. Probably also
a good time to migrate to clk_hw_*_register.


ChenYu




> > > > Merge duplicate parent instances
> > >
> > > We have considered this in the MT7986 basic clock driver, but I
> > > will
> > > check again. If corrections are needed, I will make changes in the
> > > next
> > > patch set.
> > >
> > > > Leaking clk_data if some function return fail
> > >
> > > Okay, thanks for your comment, I will update this in the next patch
> > > set
> > >
> > > > This file contains four drivers. They do not have depend on each
> > > > other, and do not need to be in the same file. Please split them
> > > > into
> > > > differen files and preferably different patches
> > >
> > > Okay, thanks for your comment, I will separate those clock drivers
> > > in
> > > the next patch set
> > >
> > > > Is there any particular reason for arch_initcall
> > >
> > > We have considered this in MT7986 basic clock driver, and use
> > > CLK_OF_DECLARE instead of arch_initcall.
> >
> > Having to sequence clock registration manually is likely a symptom of
> > inadequate clock dependency handling. So if the drivers are only
> > using
> > global clock names to describe parents, what happens is that even if
> > the parent isn't in the system yet, the registration is allowed to
> > succeed. However since the parent clock isn't available yet, any
> > calculations involving it, such as calculating clock rates, will
> > yield invalid results, such as 0 clock rate.
> >
> > > Another question:
> > > Should the clock patches in "Add basic SoC support for MediaTek
> > > mt7986"
> > > need to be separated into another patch series, such as MT8195
> > > "Mediatek MT8195 clock support" ?
> >
> > Nope. The MT8195 team seems to be splitting things up by module, with
> > the device tree being its own separate module. Ideally you want to
> > send
> > drivers along with the related device tree changes, so people
> > reviewing
> > can get a sense of how things work. And if the hardware is publicly
> > available, people can actually test the changes. We can't do that if
> > the
> > device tree changes aren't bundled together.
> >
> OK, I will keep clock patches and basic part patches in the same series
> (patches v2)
>
>
> Regards,
> Sam
> Thanks, I will delete some clocks that are not expected to b


From rentao.bupt at gmail.com  Thu Aug 12 23:19:00 2021
From: rentao.bupt at gmail.com (rentao.bupt at gmail.com)
Date: Thu, 12 Aug 2021 23:19:00 -0700
Subject: [PATCH] ARM: dts: aspeed: cloudripper: Add comments for "mdio1"
Message-ID: <20210813061900.24539-1-rentao.bupt@gmail.com>

From: Tao Ren <rentao.bupt at gmail.com>

Add some comments to explain the purpose of "mdio1" controller: it's
connected to the MDC/MDIO interface of the on-board management switch.

Signed-off-by: Tao Ren <rentao.bupt at gmail.com>
---
 arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
index 01ec3ce0a29d..9c6271a17ae8 100644
--- a/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
@@ -96,6 +96,11 @@
 	status = "okay";
 };
 
+/*
+ * "mdio1" is connected to the MDC/MDIO interface of the on-board
+ * management switch (whose ports are connected to BMC, Host and front
+ * panel ethernet port).
+ */
 &mdio1 {
 	status = "okay";
 };
-- 
2.17.1



From rentao.bupt at gmail.com  Thu Aug 12 23:24:35 2021
From: rentao.bupt at gmail.com (Tao Ren)
Date: Thu, 12 Aug 2021 23:24:35 -0700
Subject: [PATCH] ARM: dts: aspeed: minipack: Update flash partition table
In-Reply-To: <20210720002704.7390-1-rentao.bupt@gmail.com>
References: <20210720002704.7390-1-rentao.bupt@gmail.com>
Message-ID: <20210813062435.GA24497@taoren-ubuntu-R90MNF91>

Hi Joel,

Looks like the patch is not included in "dt-for-v5.15". Any comments? Or
should I send v2 if the email was not delivered?


Cheers,

Tao

On Mon, Jul 19, 2021 at 05:27:04PM -0700, rentao.bupt at gmail.com wrote:
> From: Tao Ren <rentao.bupt at gmail.com>
> 
> Update firmware flash "data0" partition size from 4MB to 8MB for larger
> persistent storage on minipack BMC.
> 
> Signed-off-by: Tao Ren <rentao.bupt at gmail.com>
> ---
>  arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
> index 9eb23e874f19..230d16cd9967 100644
> --- a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
> +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
> @@ -265,19 +265,19 @@
>  		};
>  
>  		/*
> -		 * FIT image: 59.5 MB.
> +		 * FIT image: 55.5 MB.
>  		 */
>  		fit at 80000 {
> -			reg = <0x80000 0x3b80000>;
> +			reg = <0x80000 0x3780000>;
>  			label = "fit";
>  		};
>  
>  		/*
> -		 * "data0" partition (4MB) is reserved for persistent
> +		 * "data0" partition (8MB) is reserved for persistent
>  		 * data store.
>  		 */
>  		data0 at 3800000 {
> -			reg = <0x3c00000 0x400000>;
> +			reg = <0x3800000 0x800000>;
>  			label = "data0";
>  		};
>  
> -- 
> 2.17.1
> 


From chunfeng.yun at mediatek.com  Thu Aug 12 23:30:47 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 13 Aug 2021 14:30:47 +0800
Subject: [PATCH v3 1/7] usb: mtu3: restore HS function when set SS/SSP
Message-ID: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>

Due to HS function is disabled when set as FS, need restore
it when set as SS/SSP.

Fixes: dc4c1aa7eae9 ("usb: mtu3: add ->udc_set_speed()")
Cc: stable at vger.kernel.org
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: fix invalid email format for stable
v2: no changes
---
 drivers/usb/mtu3/mtu3_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index 562f4357831e..6403f01947b2 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -227,11 +227,13 @@ static void mtu3_set_speed(struct mtu3 *mtu, enum usb_device_speed speed)
 		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		break;
 	case USB_SPEED_SUPER:
+		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
 		mtu3_clrbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	case USB_SPEED_SUPER_PLUS:
-			mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
+		mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, HS_ENABLE);
+		mtu3_setbits(mtu->ippc_base, SSUSB_U3_CTRL(0),
 			     SSUSB_U3_PORT_SSP_SPEED);
 		break;
 	default:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 23:30:49 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 13 Aug 2021 14:30:49 +0800
Subject: [PATCH v3 3/7] usb: mtu3: fix the wrong HS mult value
In-Reply-To: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628836253-7432-3-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() returns actual max packet size, @mult will
always be zero, fix it by using usb_endpoint_maxp_mult() instead
to get mult.

Fixes: 4d79e042ed8b ("usb: mtu3: add support for usb3.1 IP")
Cc: stable at vger.kernel.org
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: fix invalid email format for stable
v2: split two patch [v2 2/7],[v2 3/7] suggested by Felipe
---
 drivers/usb/mtu3/mtu3_gadget.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 635ad277cb13..a399fd84c71f 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -64,14 +64,12 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 	u32 interval = 0;
 	u32 mult = 0;
 	u32 burst = 0;
-	int max_packet;
 	int ret;
 
 	desc = mep->desc;
 	comp_desc = mep->comp_desc;
 	mep->type = usb_endpoint_type(desc);
-	max_packet = usb_endpoint_maxp(desc);
-	mep->maxp = max_packet & GENMASK(10, 0);
+	mep->maxp = usb_endpoint_maxp(desc);
 
 	switch (mtu->g.speed) {
 	case USB_SPEED_SUPER:
@@ -92,7 +90,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
 			interval = clamp_val(interval, 1, 16) - 1;
-			mult = (max_packet & GENMASK(12, 11)) >> 11;
+			mult = usb_endpoint_maxp_mult(desc) - 1;
 		}
 		break;
 	default:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 23:30:48 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 13 Aug 2021 14:30:48 +0800
Subject: [PATCH v3 2/7] usb: mtu3: use @mult for HS isoc or intr
In-Reply-To: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628836253-7432-2-git-send-email-chunfeng.yun@mediatek.com>

For HS isoc or intr, should use @mult but not @burst
to save mult value.

Fixes: 4d79e042ed8b ("usb: mtu3: add support for usb3.1 IP")
Cc: stable at vger.kernel.org
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: fix invalid email format for stable
v2: new patch, split from [2/6] suggested by Felipe
---
 drivers/usb/mtu3/mtu3_gadget.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 5e21ba05ebf0..635ad277cb13 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -92,7 +92,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
 			interval = clamp_val(interval, 1, 16) - 1;
-			burst = (max_packet & GENMASK(12, 11)) >> 11;
+			mult = (max_packet & GENMASK(12, 11)) >> 11;
 		}
 		break;
 	default:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 23:30:52 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 13 Aug 2021 14:30:52 +0800
Subject: [PATCH v3 6/7] usb: gadget: bdc: remove unnecessary AND operation
 when get ep maxp
In-Reply-To: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628836253-7432-6-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() already returns actual max packet size, no need
to AND 0x7ff.

Acked-by: Felipe Balbi <balbi at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: fix typo suggested by Sergei
v2: add acked-by felipe
---
 drivers/usb/gadget/udc/bdc/bdc_cmd.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.c b/drivers/usb/gadget/udc/bdc/bdc_cmd.c
index 995f79c79f96..67887316a1a6 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_cmd.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.c
@@ -153,7 +153,6 @@ int bdc_config_ep(struct bdc *bdc, struct bdc_ep *ep)
 	si = clamp_val(si, 1, 16) - 1;
 
 	mps = usb_endpoint_maxp(desc);
-	mps &= 0x7ff;
 	param2 |= mps << MP_SHIFT;
 	param2 |= usb_endpoint_type(desc) << EPT_SHIFT;
 
-- 
2.18.0

From rogerq at kernel.org  Thu Aug 12 23:35:53 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 13 Aug 2021 09:35:53 +0300
Subject: [PATCH v15 0/6] usb: misc: Add onboard_usb_hub driver
In-Reply-To: <YRVVjwNprk7l1jUk@google.com>
References: <20210727004118.2583774-1-mka@chromium.org>
 <YRFOnhJkB2vi/zwD@google.com>
 <8a8cae28-6617-76d3-1742-3f151a149069@kernel.org>
 <ddd60682-c957-2897-768e-96c9d25c148a@kernel.org>
 <YRVVjwNprk7l1jUk@google.com>
Message-ID: <166449bc-4c33-b923-f53d-6df4f83dc267@kernel.org>

Hi Matthias,

On 12/08/2021 20:08, Matthias Kaehlcke wrote:
> Hi Roger,
> 
> On Wed, Aug 11, 2021 at 03:56:15PM +0300, Roger Quadros wrote:
>>
>>
>> On 11/08/2021 15:38, Roger Quadros wrote:
>>> Hi Matthias,
>>>
>>> On 09/08/2021 18:49, Matthias Kaehlcke wrote:
>>>> Hi Greg,
>>>>
>>>> Just wanted to check if this series is still on your radar. Is
>>>> there anything that blocks it from landing (further ACKs, ...)?
>>>>
>>>> Thanks
>>>>
>>>> Matthias
>>>>
>>>> On Mon, Jul 26, 2021 at 05:41:12PM -0700, Matthias Kaehlcke wrote:
>>>>> This series adds:
>>>>> - the onboard_usb_hub_driver
>>>>> - glue in the xhci-plat driver to create and destroy the
>>>>>   onboard_usb_hub platform devices if needed
>>>>> - a device tree binding for the Realtek RTS5411 USB hub controller
>>>>> - device tree changes that add RTS5411 entries for the QCA SC7180
>>>>>   based boards trogdor and lazor
>>>>> - a couple of stubs for platform device functions to avoid
>>>>>   unresolved symbols with certain kernel configs
>>>>>
>>>>> The main issue the driver addresses is that a USB hub needs to be
>>>>> powered before it can be discovered. For discrete onboard hubs (an
>>>>> example for such a hub is the Realtek RTS5411) this is often solved
>>>>> by supplying the hub with an 'always-on' regulator, which is kind
>>>>> of a hack. Some onboard hubs may require further initialization
>>>>> steps, like changing the state of a GPIO or enabling a clock, which
>>>>> requires even more hacks. This driver creates a platform device
>>>>> representing the hub which performs the necessary initialization.
>>>>> Currently it only supports switching on a single regulator, support
>>>>> for multiple regulators or other actions can be added as needed.
>>>>> Different initialization sequences can be supported based on the
>>>>> compatible string.
>>>>>
>>>>> Besides performing the initialization the driver can be configured
>>>>> to power the hub off during system suspend. This can help to extend
>>>>> battery life on battery powered devices which have no requirements
>>>>> to keep the hub powered during suspend. The driver can also be
>>>>> configured to leave the hub powered when a wakeup capable USB device
>>>>> is connected when suspending, and power it off otherwise.
>>>>>
>>>>> Changes in v15:
>>>>> - adjusted dependencies of USB_DWC3_CORE to make sure it can only
>>>>>   be enabled when at least one of USB_DWC3_HOST, USB_DWC3_GADGET
>>>>>   or USB_DWC3_DUAL_ROLE is selectable
>>>>>
>>>>> Changes in v14:
>>>>> - rebased on top of v5.14-rc1
>>>>> - dropped DT binding patch which landed in v5.13
>>>>>
>>>>> Changes in v13:
>>>>> - added patch "usb: Specify dependency on USB_XHCI_PLATFORM with
>>>>>   'depends on'" to the series to avoid Kconfig conflicts
>>>>> - added patch "arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM"
>>>>>   to the series to keep effective defconfig unchanged
>>>>>
>>>>> Changes in v12:
>>>>> - onboard_hub driver: use IS_ENABLED(CONFIG_USB_ONBOARD_HUB_MODULE)
>>>>>   in onboard_hub.h to also check for the driver built as module
>>>>> - onboard_hub_driver: include onboard_hub.h again to make sure there
>>>>>   are prototype declarations for the public functions
>>>>>
>>>>> Changes in v11:
>>>>> - support multiple onboard hubs connected to the same parent
>>>>> - don't include ?onboard_hub.h? from the onboard hub driver
>>>>>
>>>>> Changes in v10:
>>>>> - always use of_is_onboard_usb_hub() stub unless ONBOARD_USB_HUB=y/m
>>>>> - keep 'regulator-boot-on' property for pp3300_hub
>>>>>
>>>>> Changes in v9:
>>>>> - added dependency on ONBOARD_USB_HUB (or !!ONBOARD_USB_HUB) to
>>>>>   USB_PLATFORM_XHCI
>>>>>
>>>>> Changes in v7:
>>>>> - updated DT binding
>>>>> - series rebased on qcom/arm64-for-5.13
>>>>>
>>>>> Changes in v6:
>>>>> - updated summary
>>>>>
>>>>> Changes in v5:
>>>>> - cover letter added
>>>>>
>>>>> Matthias Kaehlcke (6):
>>>>>   usb: misc: Add onboard_usb_hub driver
>>>>>   of/platform: Add stubs for of_platform_device_create/destroy()
>>>>>   arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM
>>>>>   usb: Specify dependencies on USB_XHCI_PLATFORM with 'depends on'
>>>>>   usb: host: xhci-plat: Create platform device for onboard hubs in
>>>>>     probe()
>>>>>   arm64: dts: qcom: sc7180-trogdor: Add nodes for onboard USB hub
>>>>>
>>>>>  .../sysfs-bus-platform-onboard-usb-hub        |   8 +
>>>>>  MAINTAINERS                                   |   7 +
>>>>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r0.dts |  19 +-
>>>>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r1.dts |  12 +-
>>>>>  .../arm64/boot/dts/qcom/sc7180-trogdor-r1.dts |  19 +-
>>>>>  arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |  19 +-
>>>>>  arch/arm64/configs/defconfig                  |   1 +
>>>>>  drivers/usb/cdns3/Kconfig                     |   2 +-
>>>>>  drivers/usb/dwc3/Kconfig                      |   5 +-
>>>>>  drivers/usb/host/Kconfig                      |   5 +-
>>>
>>> These Kconfig changes are causing the resulting .config to be different.
>>> For example, if I start with omap2plus_defconfig, the resulting .config
>>> before and after your series is different as shown below
>>>
>>> :/work/linux$ diff /tmp/.config .config
>>> 1902d1901
>>> < # CONFIG_HISI_HIKEY_USB is not set
>>> 4992c4991
>>> < CONFIG_USB_XHCI_PLATFORM=m
>>> ---
>>>> # CONFIG_USB_XHCI_PLATFORM is not set
>>> 5073,5075c5072
>>> < # CONFIG_USB_DWC3_HOST is not set
>>> < # CONFIG_USB_DWC3_GADGET is not set
>>> < CONFIG_USB_DWC3_DUAL_ROLE=y
>>> ---
>>>> CONFIG_USB_DWC3_GADGET=y
>>> 5173a5171
>>>> # CONFIG_USB_ONBOARD_HUB is not set
>>> 5285c5283
>>> < CONFIG_USB_ROLE_SWITCH=m
>>> ---
>>>> # CONFIG_USB_ROLE_SWITCH is not set
>>>
>>> I would expect the same issues for multi_v7_defconfig and multi_v8_defconfig as well.
>>
>> Sorry I meant defconfig for arm64, not multi_v8_defconfig.
>>
>> I checked that for arm64 defconfig it is ok.
>>
>>> I'm ok to update the relevant defconfigs files so that the resulting .config is identical to
>>> before your series. Thanks!
>>
>> With the below patch you can fix it for omap2plus_defconfig and multi_v7_defconfig.
>>
>> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
>> index d9abaae118dd..8c175ab37377 100644
>> --- a/arch/arm/configs/multi_v7_defconfig
>> +++ b/arch/arm/configs/multi_v7_defconfig
>> @@ -787,6 +787,7 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
>>  CONFIG_USB=y
>>  CONFIG_USB_OTG=y
>>  CONFIG_USB_XHCI_HCD=y
>> +CONFIG_USB_XHCI_PLATFORM=y
>>  CONFIG_USB_XHCI_MVEBU=y
>>  CONFIG_USB_XHCI_TEGRA=m
>>  CONFIG_USB_EHCI_HCD=y
>> diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
>> index 2ac2418084ab..a015fb04fa25 100644
>> --- a/arch/arm/configs/omap2plus_defconfig
>> +++ b/arch/arm/configs/omap2plus_defconfig
>> @@ -562,6 +562,7 @@ CONFIG_USB=m
>>  CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
>>  CONFIG_USB_MON=m
>>  CONFIG_USB_XHCI_HCD=m
>> +CONFIG_USB_XHCI_PLATFORM=m
>>  CONFIG_USB_EHCI_HCD=m
>>  CONFIG_USB_OHCI_HCD=m
>>  CONFIG_USB_ACM=m
> 
> Thanks for testing!
> 
> I completely forgot that arm32 has all these different defconfigs.
> 
> While trying to adjust qcom_defconfig I came across something that confuses
> me. The original defconfig results in:
> 
> # CONFIG_USB_XHCI_HCD is not set
> CONFIG_USB_DWC3_DUAL_ROLE=y

The original Kconfig was:

> config USB_DWC3_DUAL_ROLE
>         bool "Dual Role mode"
>         depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3))
>         depends on (EXTCON=y || EXTCON=USB_DWC3)

Which means USB_DWC3_DUAL_ROLE can be enabled even without CONFIG_USB_XHCI_HCD.

All the dual role code does is add/remove the host/gadget controller platform devices.
It doesn't care whether there is a driver for it or not.
i.e. there is no build dependency on CONFIG_USB_XHCI_HCD.

> 
> My assumption was that xHCI support is need for dwc3 dual mode (which is
> made explicit by https://lore.kernel.org/patchwork/patch/1468240/), is
> that incorrect? Maybe without xHCI support the controller can still
> operate in USB 2.0 dual role mode?
> 

Without xHCI support the host functionality will not work at all on dwc3 dual role.
So I think your Kconfig changes for USB_DWC3_DUAL_ROLE to depend on USB_XHCI_PLATFORM
are correct.

cheers,
-roger


From chunfeng.yun at mediatek.com  Thu Aug 12 23:30:50 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 13 Aug 2021 14:30:50 +0800
Subject: [PATCH v3 4/7] usb: cdnsp: fix the wrong mult value for HS isoc or
 intr
In-Reply-To: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628836253-7432-4-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
of endpoint descriptor, not include bit[12:11] anymore, so use
usb_endpoint_maxp_mult() instead.

Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
Cc: stable at vger.kernel.org
Acked-by: Felipe Balbi <balbi at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: fix invalid email format for stable
v2: add fixes, cc suggested by Felipe
---
 drivers/usb/cdns3/cdnsp-mem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
index a47948a1623f..ad9aee3f1e39 100644
--- a/drivers/usb/cdns3/cdnsp-mem.c
+++ b/drivers/usb/cdns3/cdnsp-mem.c
@@ -882,7 +882,7 @@ static u32 cdnsp_get_endpoint_max_burst(struct usb_gadget *g,
 	if (g->speed == USB_SPEED_HIGH &&
 	    (usb_endpoint_xfer_isoc(pep->endpoint.desc) ||
 	     usb_endpoint_xfer_int(pep->endpoint.desc)))
-		return (usb_endpoint_maxp(pep->endpoint.desc) & 0x1800) >> 11;
+		return usb_endpoint_maxp_mult(pep->endpoint.desc) - 1;
 
 	return 0;
 }
-- 
2.18.0

From inki.dae at samsung.com  Thu Aug 12 23:50:56 2021
From: inki.dae at samsung.com (Inki Dae)
Date: Fri, 13 Aug 2021 15:50:56 +0900
Subject: [RFC PATCH 06/17] drm/exynos: dsi: Handle exynos specifics via
 driver_data
In-Reply-To: <YP2el40V3K4R7ner@ravnborg.org>
References: <20210704090230.26489-1-jagan@amarulasolutions.com>
 <20210704090230.26489-7-jagan@amarulasolutions.com>
 <CGME20210725172551epcas1p31dff839439ac37757cf061405b5ac65c@epcas1p3.samsung.com>
 <YP2el40V3K4R7ner@ravnborg.org>
Message-ID: <79ef7f71-b167-2368-e0fd-d4ccaee596c2@samsung.com>

Hi,

21. 7. 26. ?? 2:25? Sam Ravnborg ?(?) ? ?:
> On Sun, Jul 04, 2021 at 02:32:19PM +0530, Jagan Teki wrote:
>> Exynos DSI driver is actually a Samsung MIPI DSIM bridge
>> IP which is also used in i.MX8MM platforms.
>>
>> Right now the existing driver has some exynos drm specific
>> code bases like te_irq, crtc and component_ops.
>>
>> In order to switch this driver into a common bridge driver
>> We can see 2 options to handle the exynos specific code.
>>
>> A. Drop the component_ops, and rework other specifics.
>>    This may lead to more foundation work as it requires
>>    more changes in exynos drm drivers stack.
>>
>> B. Handle the exynos specifics via driver data, and make
>>    the common bridge work in different platforms and plan
>>    for option A in future.
>>
>> So, this patch is trying to add option B) changes to handle
>> exynos specifics via driver_data.
> 
> We really should find someone that has the time, energy, knowledge and
> hardware that can include device_link support once anf for all for
> bridges.
> Then we would avoid hacks like this.
> 
> I see no other options at the moment, but look forward for a better
> solution.
> 
> 	Sam
> 

I'm not sure that it's correct to share this mipi dsi driver with I.MX8MM SoC even though it's a same IP because this MIPI DSI device isn't peripheral device but in SoC.
It would mean that Exynos MIPI DSI device depends on SoC architecture, and Exynos and I.MX series are totally different SoC. So if we share the same driver for the MIPI DSI device then many things we didn't predict may happen in the future. I don't want to make Jagan's efforts in vain for the community but clarify whether this is correct way or not. If this is only the way we have to go then we could more focus on actual solution not such hack. Impossible work with Jagan alone I think.

So let's get started with a question,
- Is MIPI-DSI bridge device or Encoder device? I think that MIPI-DSI is a Encoder device managed by atomic KMS. If MIPI-DSI should be handled as bridge device then does now drm bridge framework provide everything to share one driver with one more SoC? I mean something that drm bridge has to consider for such driver support, which is shared with one more SoC.  


And Display mode - VIDEO and COMMAND mode - is generic type of MIPI DSI, and also componentised subsystem is a generic solution to resolve probing order issue not Exynos specific feature. These are driver specific ones not Exynos SoC I think. As SoC specific things should be considered, I think MIPI DSI Driver - interrupt handler and probing order things are really specific to device driver - should be separated but we could share the control part of the device.

I was busy with other projects so didn't care of Linux DRM world so there may be my missing something.

Thanks,
Inki Dae

> 
>>
>> Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
>> ---
>>  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 37 +++++++++++++++++++------
>>  1 file changed, 29 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
>> index 99a1b8c22313..53d878d4d2d7 100644
>> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
>> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
>> @@ -250,6 +250,7 @@ struct exynos_dsi_driver_data {
>>  	unsigned int wait_for_reset;
>>  	unsigned int num_bits_resol;
>>  	const unsigned int *reg_values;
>> +	bool exynos_specific;
>>  };
>>  
>>  struct exynos_dsi {
>> @@ -459,6 +460,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
>>  	.wait_for_reset = 1,
>>  	.num_bits_resol = 11,
>>  	.reg_values = reg_values,
>> +	.exynos_specific = true,
>>  };
>>  
>>  static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
>> @@ -471,6 +473,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
>>  	.wait_for_reset = 1,
>>  	.num_bits_resol = 11,
>>  	.reg_values = reg_values,
>> +	.exynos_specific = true,
>>  };
>>  
>>  static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
>> @@ -481,6 +484,7 @@ static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
>>  	.wait_for_reset = 1,
>>  	.num_bits_resol = 11,
>>  	.reg_values = reg_values,
>> +	.exynos_specific = true,
>>  };
>>  
>>  static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
>> @@ -492,6 +496,7 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
>>  	.wait_for_reset = 0,
>>  	.num_bits_resol = 12,
>>  	.reg_values = exynos5433_reg_values,
>> +	.exynos_specific = true,
>>  };
>>  
>>  static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
>> @@ -503,6 +508,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
>>  	.wait_for_reset = 1,
>>  	.num_bits_resol = 12,
>>  	.reg_values = exynos5422_reg_values,
>> +	.exynos_specific = true,
>>  };
>>  
>>  static const struct of_device_id exynos_dsi_of_match[] = {
>> @@ -1484,7 +1490,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
>>  	 * If attached panel device is for command mode one, dsi should register
>>  	 * TE interrupt handler.
>>  	 */
>> -	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
>> +	if (dsi->driver_data->exynos_specific &&
>> +	    !(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
>>  		int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
>>  		if (ret)
>>  			return ret;
>> @@ -1495,8 +1502,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
>>  	dsi->lanes = device->lanes;
>>  	dsi->format = device->format;
>>  	dsi->mode_flags = device->mode_flags;
>> -	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
>> -			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
>> +	if (dsi->driver_data->exynos_specific)
>> +		exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
>> +					    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
>>  
>>  	mutex_unlock(&drm->mode_config.mutex);
>>  
>> @@ -1515,7 +1523,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
>>  	if (drm->mode_config.poll_enabled)
>>  		drm_kms_helper_hotplug_event(drm);
>>  
>> -	exynos_dsi_unregister_te_irq(dsi);
>> +	if (dsi->driver_data->exynos_specific)
>> +		exynos_dsi_unregister_te_irq(dsi);
>>  
>>  	return 0;
>>  }
>> @@ -1737,6 +1746,15 @@ static int exynos_dsi_probe(struct platform_device *pdev)
>>  	if (ret)
>>  		return ret;
>>  
>> +	if (!dsi->driver_data->exynos_specific) {
>> +		ret = mipi_dsi_host_register(&dsi->dsi_host);
>> +		if (ret) {
>> +			dev_err(dev, "failed to register mipi dsi host: %d\n",
>> +				ret);
>> +			return ret;
>> +		}
>> +	}
>> +
>>  	platform_set_drvdata(pdev, dsi);
>>  
>>  	pm_runtime_enable(dev);
>> @@ -1747,9 +1765,11 @@ static int exynos_dsi_probe(struct platform_device *pdev)
>>  
>>  	drm_bridge_add(&dsi->bridge);
>>  
>> -	ret = component_add(dev, &exynos_dsi_component_ops);
>> -	if (ret)
>> -		goto err_disable_runtime;
>> +	if (dsi->driver_data->exynos_specific) {
>> +		ret = component_add(dev, &exynos_dsi_component_ops);
>> +		if (ret)
>> +			goto err_disable_runtime;
>> +	}
>>  
>>  	return 0;
>>  
>> @@ -1767,7 +1787,8 @@ static int exynos_dsi_remove(struct platform_device *pdev)
>>  
>>  	pm_runtime_disable(&pdev->dev);
>>  
>> -	component_del(&pdev->dev, &exynos_dsi_component_ops);
>> +	if (dsi->driver_data->exynos_specific)
>> +		component_del(&pdev->dev, &exynos_dsi_component_ops);
>>  
>>  	return 0;
>>  }
>> -- 
>> 2.25.1
> 


From chunfeng.yun at mediatek.com  Thu Aug 12 23:30:53 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 13 Aug 2021 14:30:53 +0800
Subject: [PATCH v3 7/7] usb: gadget: remove unnecessary AND operation when get
 ep maxp
In-Reply-To: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628836253-7432-7-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() already returns actual max packet size, no need
to AND 0x7ff.

Acked-by: Felipe Balbi <balbi at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: fix typo suggested by Sergei
v2: add acked-by felipe
---
 include/linux/usb/gadget.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 75c7538e350a..f181c84310b6 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -491,7 +491,7 @@ extern char *usb_get_gadget_udc_name(void);
  */
 static inline size_t usb_ep_align(struct usb_ep *ep, size_t len)
 {
-	int max_packet_size = (size_t)usb_endpoint_maxp(ep->desc) & 0x7ff;
+	int max_packet_size = (size_t)usb_endpoint_maxp(ep->desc);
 
 	return round_up(len, max_packet_size);
 }
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 12 23:30:51 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 13 Aug 2021 14:30:51 +0800
Subject: [PATCH v3 5/7] usb: gadget: tegra-xudc: fix the wrong mult value for
 HS isoc or intr
In-Reply-To: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1628836253-7432-5-git-send-email-chunfeng.yun@mediatek.com>

usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
of endpoint descriptor, not includes bit[12:11] anymore, so use
usb_endpoint_maxp_mult() instead.
Meanwhile no need AND 0x7ff when get maxp, remove it.

Fixes: 49db427232fe ("usb: gadget: Add UDC driver for tegra XUSB device mode controller")
Cc: stable at vger.kernel.org
Acked-by: Felipe Balbi <balbi at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: fix invalid email format for stable
v2:
  add fixes, cc;
  add acked-by felipe;
---
 drivers/usb/gadget/udc/tegra-xudc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c
index a54d1cef17db..40a7417e7ae4 100644
--- a/drivers/usb/gadget/udc/tegra-xudc.c
+++ b/drivers/usb/gadget/udc/tegra-xudc.c
@@ -1610,7 +1610,7 @@ static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep)
 	u16 maxpacket, maxburst = 0, esit = 0;
 	u32 val;
 
-	maxpacket = usb_endpoint_maxp(desc) & 0x7ff;
+	maxpacket = usb_endpoint_maxp(desc);
 	if (xudc->gadget.speed == USB_SPEED_SUPER) {
 		if (!usb_endpoint_xfer_control(desc))
 			maxburst = comp_desc->bMaxBurst;
@@ -1621,7 +1621,7 @@ static void tegra_xudc_ep_context_setup(struct tegra_xudc_ep *ep)
 		   (usb_endpoint_xfer_int(desc) ||
 		    usb_endpoint_xfer_isoc(desc))) {
 		if (xudc->gadget.speed == USB_SPEED_HIGH) {
-			maxburst = (usb_endpoint_maxp(desc) >> 11) & 0x3;
+			maxburst = usb_endpoint_maxp_mult(desc) - 1;
 			if (maxburst == 0x3) {
 				dev_warn(xudc->dev,
 					 "invalid endpoint maxburst\n");
-- 
2.18.0

From sam.shih at mediatek.com  Thu Aug 12 23:40:43 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Fri, 13 Aug 2021 14:40:43 +0800
Subject: [PATCH 01/12] dt-bindings: clock: mediatek: document clk
 bindings for mediatek mt7986 SoC
In-Reply-To: <CAGXv+5GxXRqJqZURagNc4z=am0jhqP05eq0i64+kf457yfRoAw@mail.gmail.com>
References: <20210726071439.14248-1-sam.shih@mediatek.com>
 <20210726071439.14248-2-sam.shih@mediatek.com>
 <CAGXv+5GeEBAkXKfA=S7XGOLYtCRihP5ov6kSiw+eevPAi74GAQ@mail.gmail.com>
 <083a0e8fdd07c0f940285dce2dc26cb0f5e798a6.camel@mediatek.com>
 <CAGXv+5F1tPC8W6FcBqn4TdoOrSmFUr4GWpD3hQC9QsPi3o__=g@mail.gmail.com>
 <8b14d7a730bd787a9d162d368a2d3aae64256ca6.camel@mediatek.com>
 <CAGXv+5GxXRqJqZURagNc4z=am0jhqP05eq0i64+kf457yfRoAw@mail.gmail.com>
Message-ID: <f91c94440879c9755dc2b85d891766a82f1e6cb5.camel@mediatek.com>

On Fri, 2021-08-13 at 14:15 +0800, Chen-Yu Tsai wrote:
> On Fri, Aug 13, 2021 at 1:22 PM Sam Shih <sam.shih at mediatek.com>
> wrote:
> > 
> > Hi,
> > 
> > Sorry for the late reply,I have prepared v2 patches, but for some
> > of your suggestions, I think
> > it is a bit difficult to apply to our drivers.
> > 
> > 
> > On Fri, 2021-07-30 at 14:30 +0800, Chen-Yu Tsai wrote:
> > > On Fri, Jul 30, 2021 at 2:01 PM Sam Shih <sam.shih at mediatek.com>
> > > wrote:
> > > > 
> > > > Hi,
> > > > 
> > > > On Mon, 2021-07-26 at 17:20 +0800, Chen-Yu Tsai wrote:
> > > > > Furthermore, based on the driver patch and the fact that they
> > > > > share
> > > > > the
> > > > > same compatible string, it seems you shouldn't need to have
> > > > > two
> > > > > compatible
> > > > > strings for two identical hardware blocks. The need for
> > > > > separate
> > > > > entries
> > > > > to have different clock names is an implementation detail.
> > > > > Please
> > > > > consider
> > > > > using and supporting clock-output-names.
> > > > > 
> > > > > Also, please check out the MT8195 clock driver series [1].
> > > > > I'm
> > > > > guessing
> > > > > a lot of the comments apply to this one as well.
> > > > > 
> > > > > Regards
> > > > > ChenYu
> > > > > 
> > > > > [1]
> > > > > 
> > 
> > 
https://urldefense.com/v3/__https://lore.kernel.org/linux-mediatek/20210616224743.5109-1-chun-jie.chen at mediatek.com/T/*t__;Iw!!CTRNKA9wMg0ARbw!29pb4TJiGHLvLbYJgDB2Dhf8Mpw5VU8zV-W3NrMan_RPQrtWT2EdRTyyjWpu0nZE$
> > > > > 
> > > > > 
> > > > 
> > > > I have organized your comments in "Mediatek MT8195 clock
> > > > support"
> > > > series into the following list, reply to your here:
> > > > 
> > > > > dt-binding: Move the not-to-be-exposed clock to driver
> > > > > directory
> > > > > or
> > > > > simply left out
> > > > 
> > > > Okay, thanks for your comment, I will update this in the next
> > > > patch
> > > > set
> > > 
> > > See the following file for an example:
> > > 
> > > 
> > > 
https://urldefense.com/v3/__https://elixir.bootlin.com/linux/latest/source/drivers/clk/sunxi-ng/ccu-sun50i-a64.h__;!!CTRNKA9wMg0ARbw!3--UEpFFGeZ_WTCaWsj_9vbbb4SSE1vPCILFleThzpa1nq7mveFfQMDqbacdT5I6$
> > > 
> > > drivers would not be able to use the non-exported intermediate
> > > clocks.
> > > 
> > 
> > Thanks, I well delete some clocks that are not expected to be use
> > in
> > device tree.
> > 
> > > > > describe some of the clock relations between the various
> > > > > clock
> > > > > controllers
> > > > 
> > > > I have checked the files in
> > > > "Documentation/devicetree/bindings/arm/mediatek", It seems that
> > > > all
> > > > MediaTek SoC clocks are simply described by each controller,
> > > > like
> > > > "mediatek,infracfg.txt" and "mediatek,topckgen.txt", and those
> > > > document
> > > > only include compatible strings information and examples.
> > > > Can we insert the clock relationship of MT7986 directlly in
> > > > common
> > > > documents?
> > > 
> > > What I meant was that since each clock controller hardware block
> > > has
> > > one or many clock inputs, these should be described in the
> > > binding
> > > as required "clocks" and "clock-names" properties.
> > > 
> > > So it's not about describing the actual relationship or clock
> > > tree,
> > > but just having the inputs accurately described.
> > > 
> > > > Or we should add a new "mediatek,mt7986-clock.yaml" and move
> > > > compatible
> > > > strings information and example to this file, and insert clock
> > > > relationship descriptions to this file? Wouldn?t it be strange
> > > > to
> > > > skip
> > > > existing files and create a new one?
> > > 
> > > I think that is a question for the device tree binding
> > > maintainer,
> > > Rob.
> > > At least for Mediatek stuff, there seem to be many separate
> > > files.
> > > 
> > > > > external oscillator's case, the oscillator is described in
> > > > > the
> > > > > device
> > > > > tree
> > > > 
> > > > Yes, we have "clkxtal" in the DT, which stands for external
> > > > oscillator,
> > > > All clocks in apmixedsys use "clkxtal" as the parent clock
> > > 
> > > So for the apmixedsys device node, it would at least have
> > > something
> > > like:
> > > 
> > >     clocks = <&clkxtal>;
> > >     clock-names = "xtal";
> > > 
> > > For topckgen, since it has xtal and some PLLs from apmixedsys as
> > > inputs:
> > > 
> > >     clocks = <&clkxtal>, <&apmixedsys CLK_ID_PLLXXX>,
> > > <&apmixedsys
> > > CLK_ID_PLLYYY>;
> > >     clock-names = "xtal", "pllXXX", "pllYYY"
> > > 
> > > The above is just an example. You should adapt it to fit your
> > > hardware
> > > description. And the bindings should describe what is required.
> > > Note
> > > that the clock names used here are local to this device node.
> > > They do
> > > not need to match what the clock driver uses for the global name.
> > > So
> > > just go with something descriptive.
> > > 
> > > The point is, cross hardware block dependencies should be clearly
> > > described
> > > in the device tree, instead of implicitly buried in the clock
> > > drivers.
> > > 
> > 
> > Make cross hardware block dependencies clearly described in the
> > device
> > tree seems unsuitable between "topck" and "infra" block of mt7986.
> > 
> > In your example, passing "clkxtal" from the device tree seems ok.
> > Even
> > for topckgen, passing "clkxtal", "pllXXX", "pllYYY" from the device
> > tree and using these clocks as the parent clock of topckgen also
> > seems
> > to work. It is feasible because it is not much clock between these
> > two
> > hardware blocks.
> > 
> > But for the clock releationship between "topckg" and "infra", they
> > are
> > very complicated in hardware design. There are dozens of clocks and
> > interact with each other. If we want to describe these
> > relationships in
> > the device tree, we need to use a big array inside the device tree
> > and
> > make device tree looks very messy. Therefore, our previous method
> > of
> > writing a clock driver is to use the global clock and descripbe the
> > clock releationship inside the clock driver.
> > 
> >                ______   ________    ________
> >     clkxtal --|      |  |       |.x.|       |
> >               |apmix.|--| topck |.x.| infra |
> >               |      |--|       |.x.|_______|
> >               |      |  |       |   ________
> >               |______|  |       |--|        |
> >                         |       |--| ethsys |
> >                         |_______|  |________|
> > 
> > Maybe we should keep the clock relationship in our clock driver
> > like
> > the previous mediatek clock drivers.
> 
> Are you saying that some clocks in topck have inputs from infra?
> If so, then that's a nasty circular dependency to deal with.
> 
Sorry I didn't express it very clearly, I mean that there are many
clock?connections between "ckgen" and "infra" (unlike apmixedsys and
ckgen). Although most of the clocks in "infra" is derived from "ckgen".
But if we want to use the device tree, we will need to pass dozens of
clocks.

> And to be fair, many Mediatek device tree bindings already take a
> large
> number of clocks, so I think adding a few more isn't too bad.
> 
It will become something like:

clocks = <&topckgen CLK_TOP_NFI1X>,<&topckgen
CLK_TOP_USB_EQ_RX250M>,<&topckgen CLK_TOP_USB_TX250M>,<&topckgen
CLK_TOP_USB_LN0_CK>,<&topckgen CLK_TOP_USB_CDR_CK>,<&topckgen
CLK_TOP_SPINFI_BCK>,<&topckgen CLK_TOP_I2C_BCK>,<&topckgen
CLK_TOP_PEXTP_TL>,<&topckgen CLK_TOP_EMMC_250M>,<&topckgen
CLK_TOP_EMMC_416M>,<&topckgen CLK_TOP_F_26M_ADC_CK>,<&topckgen
CLK_TOP_SYSAXI>,<&topckgen CLK_TOP_NETSYS_WED_MCU>,<&topckgen
CLK_TOP_NETSYS_2X>,<&topckgen CLK_TOP_SGM_325M>,<&topckgen
CLK_TOP_A1SYS>,<&topckgen CLK_TOP_EIP_B>,<&topckgen
CLK_TOP_F26M>,<&topckgen CLK_TOP_AUD_L>,<&topckgen
CLK_TOP_A_TUNER>,<&topckgen CLK_TOP_U2U3_REF>,<&topckgen
CLK_TOP_U2U3_SYS>,<&topckgen CLK_TOP_U2U3_XHCI>,<&topckgen
CLK_TOP_AP2CNN_HOST>,<&topckgen CLK_TOP_NFI1X_SEL>,<&topckgen
CLK_TOP_SPINFI_SEL>,<&topckgen CLK_TOP_SPI_SEL>,<&topckgen
CLK_TOP_SPIM_MST_SEL>,<&topckgen CLK_TOP_UART_SEL>,<&topckgen
CLK_TOP_PWM_SEL>,<&topckgen CLK_TOP_I2C_SEL>,<&topckgen
CLK_TOP_PEXTP_TL_SEL>,<&topckgen CLK_TOP_EMMC_250M_SEL>,<&topckgen
CLK_TOP_EMMC_416M_SEL>,<&topckgen CLK_TOP_F_26M_ADC_SEL>,<&topckgen
CLK_TOP_DRAMC_SEL>,<&topckgen CLK_TOP_DRAMC_MD32_SEL>,<&topckgen
CLK_TOP_SYSAXI_SEL>,<&topckgen CLK_TOP_SYSAPB_SEL>,<&topckgen
CLK_TOP_ARM_DB_MAIN_SEL>,<&topckgen CLK_TOP_ARM_DB_JTSEL>,<&topckgen
CLK_TOP_NETSYS_SEL>,<&topckgen CLK_TOP_NETSYS_500M_SEL>,<&topckgen
CLK_TOP_NETSYS_MCU_SEL>,<&topckgen CLK_TOP_NETSYS_2X_SEL>,<&topckgen
CLK_TOP_SGM_325M_SEL>,<&topckgen CLK_TOP_SGM_REG_SEL>,<&topckgen
CLK_TOP_A1SYS_SEL>,<&topckgen CLK_TOP_CONN_MCUSYS_SEL>,<&topckgen
CLK_TOP_EIP_B_SEL>,<&topckgen CLK_TOP_PCIE_PHY_SEL>,<&topckgen
CLK_TOP_USB3_PHY_SEL>,<&topckgen CLK_TOP_F26M_SEL>,<&topckgen
CLK_TOP_AUD_L_SEL>,<&topckgen CLK_TOP_A_TUNER_SEL>,<&topckgen
CLK_TOP_U2U3_SEL>,<&topckgen CLK_TOP_U2U3_SYS_SEL>,<&topckgen
CLK_TOP_U2U3_XHCI_SEL>,<&topckgen CLK_TOP_DA_U2_REFSEL>,<&topckgen
CLK_TOP_DA_U2_CK_1P_SEL>,<&topckgen CLK_TOP_AP2CNN_HOST_SEL>;

I don't think this is okay in device tree...


> > > > > Dual license please (and the dts files).
> > > > 
> > > > Okay, thanks for your comment, I will update this in the next
> > > > patch
> > > > set
> > > > 
> > > > > Why are this and other 1:1 factor clks needed? They look like
> > > > > placeholders. Please remove them.
> > > > 
> > > > Okay, thanks for your comment, I will update this in the next
> > > > patch
> > > > set
> > > 
> > > Ideally the clock driver would use the device tree to get local
> > > references
> > > for this, but that is going to require some rework to Mediatek's
> > > common
> > > clock code.
> > > 
> > 
> > To transfer the clock relationship through the device tree, it is
> > necessary to make modifications to the common part of the mtk clock
> > driver that has been merged, and may also modify other mediatek
> > clock
> > drivers.
> > 
> > Let's move to the source code:
> > 
> > apmixedsys {
> >     ...
> > }
> > 
> > topckgen {
> >     ...
> >     clocks = ... , <&apmixedsys NET2PLL> , ... ;
> >     clock-names = ... , "net2pll" , ... ;
> > }
> > 
> > char *parent_name;
> >     for each clk in <device_tree_node>:
> >         parent_name = __clk_get_name(of_clk_get(np, i))
> > 
> > (armada-37xx-tbg.c use this method to get global name of parent
> > clock)
> > 
> > Ideally, we should use the parent_name variable above to create a
> > clock, But mtk_fixed_factor expects input const strings
> > 
> > void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
> > ...)
> > 
> > struct mtk_fixed_factor {
> >     ...
> >     const char *name;
> >     const char *parent;
> >     ...
> > };
> > 
> > So we still need to use pre-defined clock name in static const
> > clock
> > table even we can get clock name as variable from device tree.
> > 
> > 
> > static const struct mtk_fixed_factor top_divs[] __initconst = {
> >     ...
> >     FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", "net2pll", 1, 8),
> >     FACTOR(CK_TOP_NET2_D3_D2, "net2_d3_d2", "net2pll", 1, 2),
> >     ...
> > }
> 
> Right. I'm not asking you to do this right away. This will end up
> being
> a long migration over multiple releases. But it makes sense to get
> the
> device tree bindings sorted out first.
> 
> I believe the solution is to move to `struct clk_parent_data` to
> replace
> the pure strings. New internal APIs for the Mediatek clock driver
> would
> need to be added, and all the drivers slowly migrated over. Probably
> also
> a good time to migrate to clk_hw_*_register.
> 
> 
> ChenYu
> 
> 
> 
> 
> > > > > Merge duplicate parent instances
> > > > 
> > > > We have considered this in the MT7986 basic clock driver, but I
> > > > will
> > > > check again. If corrections are needed, I will make changes in
> > > > the
> > > > next
> > > > patch set.
> > > > 
> > > > > Leaking clk_data if some function return fail
> > > > 
> > > > Okay, thanks for your comment, I will update this in the next
> > > > patch
> > > > set
> > > > 
> > > > > This file contains four drivers. They do not have depend on
> > > > > each
> > > > > other, and do not need to be in the same file. Please split
> > > > > them
> > > > > into
> > > > > differen files and preferably different patches
> > > > 
> > > > Okay, thanks for your comment, I will separate those clock
> > > > drivers
> > > > in
> > > > the next patch set
> > > > 
> > > > > Is there any particular reason for arch_initcall
> > > > 
> > > > We have considered this in MT7986 basic clock driver, and use
> > > > CLK_OF_DECLARE instead of arch_initcall.
> > > 
> > > Having to sequence clock registration manually is likely a
> > > symptom of
> > > inadequate clock dependency handling. So if the drivers are only
> > > using
> > > global clock names to describe parents, what happens is that even
> > > if
> > > the parent isn't in the system yet, the registration is allowed
> > > to
> > > succeed. However since the parent clock isn't available yet, any
> > > calculations involving it, such as calculating clock rates, will
> > > yield invalid results, such as 0 clock rate.
> > > 
> > > > Another question:
> > > > Should the clock patches in "Add basic SoC support for MediaTek
> > > > mt7986"
> > > > need to be separated into another patch series, such as MT8195
> > > > "Mediatek MT8195 clock support" ?
> > > 
> > > Nope. The MT8195 team seems to be splitting things up by module,
> > > with
> > > the device tree being its own separate module. Ideally you want
> > > to
> > > send
> > > drivers along with the related device tree changes, so people
> > > reviewing
> > > can get a sense of how things work. And if the hardware is
> > > publicly
> > > available, people can actually test the changes. We can't do that
> > > if
> > > the
> > > device tree changes aren't bundled together.
> > > 
> > 
> > OK, I will keep clock patches and basic part patches in the same
> > series
> > (patches v2)
> > 


Regards,
Sam

> > Thanks, I will delete some clocks that are not expected to b

From maz at kernel.org  Thu Aug 12 23:42:41 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 13 Aug 2021 07:42:41 +0100
Subject: [GIT PULL] KVM/arm64 fixes for 5.14, take #2
Message-ID: <20210813064241.2603475-1-maz@kernel.org>

Hi Paolo,

Here's the second batch of KVM/arm64 fixes for 5.14, and hopefully the
last for this cycle. We have another MTE fix from Steven, but also
have an off-by-one bug squashed by David in the protected memory path.

Please pull,

	M.

The following changes since commit 5cf17746b302aa32a4f200cc6ce38865bfe4cf94:

  KVM: arm64: selftests: get-reg-list: actually enable pmu regs in pmu sublist (2021-07-14 11:55:18 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-fixes-5.14-2

for you to fetch changes up to c4d7c51845af9542d42cd18a25c570583abf2768:

  KVM: arm64: Fix race when enabling KVM_ARM_CAP_MTE (2021-07-29 17:34:01 +0100)

----------------------------------------------------------------
KVM/arm64 fixes for 5.14, take #2

- Plug race between enabling MTE and creating vcpus
- Fix off-by-one bug when checking whether an address range is RAM

----------------------------------------------------------------
David Brazdil (1):
      KVM: arm64: Fix off-by-one in range_is_memory

Steven Price (1):
      KVM: arm64: Fix race when enabling KVM_ARM_CAP_MTE

 arch/arm64/kvm/arm.c                  | 12 ++++++++----
 arch/arm64/kvm/hyp/nvhe/mem_protect.c |  2 +-
 2 files changed, 9 insertions(+), 5 deletions(-)


From yong.wu at mediatek.com  Thu Aug 12 23:52:56 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:52:56 +0800
Subject: [PATCH v2 01/29] dt-bindings: mediatek: mt8195: Add binding for MM
 IOMMU
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-2-yong.wu@mediatek.com>

This patch adds descriptions for mt8195 IOMMU which also use ARM
Short-Descriptor translation table format.

In mt8195, there are two smi-common HW and IOMMU, one is for vdo(video
output), the other is for vpp(video processing pipe). They connects
with different smi-larbs, then some setting(larbid_remap) is different.
Differentiate them with the compatible string.

Something like this:

    IOMMU(VDO)          IOMMU(VPP)
       |                   |
  SMI_COMMON_VDO      SMI_COMMON_VPP
  ---------------     ----------------
  |      |   ...      |      |     ...
larb0 larb2  ...    larb1 larb3    ...

Another change is that we have a new IOMMU that is for infra master like
PCIe and USB. The infra master don't have the larb and ports, thus we
rename the port header file to mt8195-memory-port.h rather than
mt8195-larb-port.h.

Also, the IOMMU is not only for MM, thus, we don't call it "m4u" which
means "MultiMedia Memory Management UNIT". thus, use the "iommu" as the
compatiable string.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/iommu/mediatek,iommu.yaml        |   7 +
 .../dt-bindings/memory/mt8195-memory-port.h   | 390 ++++++++++++++++++
 2 files changed, 397 insertions(+)
 create mode 100644 include/dt-bindings/memory/mt8195-memory-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index 0f26fe14c8e2..9b04630158c8 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -77,6 +77,8 @@ properties:
           - mediatek,mt8173-m4u  # generation two
           - mediatek,mt8183-m4u  # generation two
           - mediatek,mt8192-m4u  # generation two
+          - mediatek,mt8195-iommu-vdo        # generation two
+          - mediatek,mt8195-iommu-vpp        # generation two
 
       - description: mt7623 generation one
         items:
@@ -118,6 +120,7 @@ properties:
       dt-binding/memory/mt8173-larb-port.h for mt8173,
       dt-binding/memory/mt8183-larb-port.h for mt8183,
       dt-binding/memory/mt8192-larb-port.h for mt8192.
+      dt-binding/memory/mt8195-memory-port.h for mt8195.
 
   power-domains:
     maxItems: 1
@@ -139,6 +142,8 @@ allOf:
               - mediatek,mt2712-m4u
               - mediatek,mt8173-m4u
               - mediatek,mt8192-m4u
+              - mediatek,mt8195-iommu-vdo
+              - mediatek,mt8195-iommu-vpp
 
     then:
       required:
@@ -149,6 +154,8 @@ allOf:
         compatible:
           enum:
             - mediatek,mt8192-m4u
+            - mediatek,mt8195-iommu-vdo
+            - mediatek,mt8195-iommu-vpp
 
     then:
       required:
diff --git a/include/dt-bindings/memory/mt8195-memory-port.h b/include/dt-bindings/memory/mt8195-memory-port.h
new file mode 100644
index 000000000000..783bcae8cdea
--- /dev/null
+++ b/include/dt-bindings/memory/mt8195-memory-port.h
@@ -0,0 +1,390 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yong Wu <yong.wu at mediatek.com>
+ */
+#ifndef _DT_BINDINGS_MEMORY_MT8195_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT8195_LARB_PORT_H_
+
+#include <dt-bindings/memory/mtk-memory-port.h>
+
+/*
+ * MM IOMMU supports 16GB dma address. We separate it to four ranges:
+ * 0 ~ 4G; 4G ~ 8G; 8G ~ 12G; 12G ~ 16G. we could adjust these master
+ * locate an banks. BUT:
+ * a) Make sure all the ports inside a larb are in one range.
+ * b) The iova of any master can NOT cross the 4G/8G/12G boundary.
+ *
+ * This is the suggested mapping in this SoC:
+ *
+ * modules    dma-address-region	larbs-ports
+ * disp         0 ~ 4G                  larb0/1/2/3
+ * vcodec      4G ~ 8G                  larb19/20/21/22/23/24
+ * cam/mdp     8G ~ 12G                 the other larbs.
+ * N/A         12G ~ 16G
+ * CCU0   0x24000_0000 ~ 0x243ff_ffff   larb18: port 0/1
+ * CCU1   0x24400_0000 ~ 0x247ff_ffff   larb18: port 2/3
+ *
+ * This SoC have two IOMMU HWs, this is the detailed connected information:
+ * iommu-vdo: larb0/2/5/7/9/10/11/13/17/19/21/24/25/28
+ * iommu-vpp: larb1/3/4/6/8/12/14/16/18/20/22/23/26/27
+ */
+
+/* mm iommu ports */
+/* larb0 */
+#define M4U_PORT_L0_DISP_RDMA0			MTK_M4U_ID(0, 0)
+#define M4U_PORT_L0_DISP_WDMA0			MTK_M4U_ID(0, 1)
+#define M4U_PORT_L0_DISP_OVL0_RDMA0		MTK_M4U_ID(0, 2)
+#define M4U_PORT_L0_DISP_OVL0_RDMA1		MTK_M4U_ID(0, 3)
+#define M4U_PORT_L0_DISP_OVL0_HDR		MTK_M4U_ID(0, 4)
+#define M4U_PORT_L0_DISP_FAKE0			MTK_M4U_ID(0, 5)
+
+/* larb1 */
+#define M4U_PORT_L1_DISP_RDMA0			MTK_M4U_ID(1, 0)
+#define M4U_PORT_L1_DISP_WDMA0			MTK_M4U_ID(1, 1)
+#define M4U_PORT_L1_DISP_OVL0_RDMA0		MTK_M4U_ID(1, 2)
+#define M4U_PORT_L1_DISP_OVL0_RDMA1		MTK_M4U_ID(1, 3)
+#define M4U_PORT_L1_DISP_OVL0_HDR		MTK_M4U_ID(1, 4)
+#define M4U_PORT_L1_DISP_FAKE0			MTK_M4U_ID(1, 5)
+
+/* larb2 */
+#define M4U_PORT_L2_MDP_RDMA0			MTK_M4U_ID(2, 0)
+#define M4U_PORT_L2_MDP_RDMA2			MTK_M4U_ID(2, 1)
+#define M4U_PORT_L2_MDP_RDMA4			MTK_M4U_ID(2, 2)
+#define M4U_PORT_L2_MDP_RDMA6			MTK_M4U_ID(2, 3)
+#define M4U_PORT_L2_DISP_FAKE1			MTK_M4U_ID(2, 4)
+
+/* larb3 */
+#define M4U_PORT_L3_MDP_RDMA1			MTK_M4U_ID(3, 0)
+#define M4U_PORT_L3_MDP_RDMA3			MTK_M4U_ID(3, 1)
+#define M4U_PORT_L3_MDP_RDMA5			MTK_M4U_ID(3, 2)
+#define M4U_PORT_L3_MDP_RDMA7			MTK_M4U_ID(3, 3)
+#define M4U_PORT_L3_HDR_DS			MTK_M4U_ID(3, 4)
+#define M4U_PORT_L3_HDR_ADL			MTK_M4U_ID(3, 5)
+#define M4U_PORT_L3_DISP_FAKE1			MTK_M4U_ID(3, 6)
+
+/* larb4 */
+#define M4U_PORT_L4_MDP_RDMA			MTK_M4U_ID(4, 0)
+#define M4U_PORT_L4_MDP_FG			MTK_M4U_ID(4, 1)
+#define M4U_PORT_L4_MDP_OVL			MTK_M4U_ID(4, 2)
+#define M4U_PORT_L4_MDP_WROT			MTK_M4U_ID(4, 3)
+#define M4U_PORT_L4_FAKE			MTK_M4U_ID(4, 4)
+
+/* larb5 */
+#define M4U_PORT_L5_SVPP1_MDP_RDMA		MTK_M4U_ID(5, 0)
+#define M4U_PORT_L5_SVPP1_MDP_FG		MTK_M4U_ID(5, 1)
+#define M4U_PORT_L5_SVPP1_MDP_OVL		MTK_M4U_ID(5, 2)
+#define M4U_PORT_L5_SVPP1_MDP_WROT		MTK_M4U_ID(5, 3)
+#define M4U_PORT_L5_SVPP2_MDP_RDMA		MTK_M4U_ID(5, 4)
+#define M4U_PORT_L5_SVPP2_MDP_FG		MTK_M4U_ID(5, 5)
+#define M4U_PORT_L5_SVPP2_MDP_WROT		MTK_M4U_ID(5, 6)
+#define M4U_PORT_L5_FAKE			MTK_M4U_ID(5, 7)
+
+/* larb6 */
+#define M4U_PORT_L6_SVPP3_MDP_RDMA		MTK_M4U_ID(6, 0)
+#define M4U_PORT_L6_SVPP3_MDP_FG		MTK_M4U_ID(6, 1)
+#define M4U_PORT_L6_SVPP3_MDP_WROT		MTK_M4U_ID(6, 2)
+#define M4U_PORT_L6_FAKE			MTK_M4U_ID(6, 3)
+
+/* larb7 */
+#define M4U_PORT_L7_IMG_WPE_RDMA0		MTK_M4U_ID(7, 0)
+#define M4U_PORT_L7_IMG_WPE_RDMA1		MTK_M4U_ID(7, 1)
+#define M4U_PORT_L7_IMG_WPE_WDMA0		MTK_M4U_ID(7, 2)
+
+/* larb8 */
+#define M4U_PORT_L8_IMG_WPE_RDMA0		MTK_M4U_ID(8, 0)
+#define M4U_PORT_L8_IMG_WPE_RDMA1		MTK_M4U_ID(8, 1)
+#define M4U_PORT_L8_IMG_WPE_WDMA0		MTK_M4U_ID(8, 2)
+
+/* larb9 */
+#define M4U_PORT_L9_IMG_IMGI_T1_A		MTK_M4U_ID(9, 0)
+#define M4U_PORT_L9_IMG_IMGBI_T1_A		MTK_M4U_ID(9, 1)
+#define M4U_PORT_L9_IMG_IMGCI_T1_A		MTK_M4U_ID(9, 2)
+#define M4U_PORT_L9_IMG_SMTI_T1_A		MTK_M4U_ID(9, 3)
+#define M4U_PORT_L9_IMG_TNCSTI_T1_A		MTK_M4U_ID(9, 4)
+#define M4U_PORT_L9_IMG_TNCSTI_T4_A		MTK_M4U_ID(9, 5)
+#define M4U_PORT_L9_IMG_YUVO_T1_A		MTK_M4U_ID(9, 6)
+#define M4U_PORT_L9_IMG_TIMGO_T1_A		MTK_M4U_ID(9, 7)
+#define M4U_PORT_L9_IMG_YUVO_T2_A		MTK_M4U_ID(9, 8)
+#define M4U_PORT_L9_IMG_IMGI_T1_B		MTK_M4U_ID(9, 9)
+#define M4U_PORT_L9_IMG_IMGBI_T1_B		MTK_M4U_ID(9, 10)
+#define M4U_PORT_L9_IMG_IMGCI_T1_B		MTK_M4U_ID(9, 11)
+#define M4U_PORT_L9_IMG_YUVO_T5_A		MTK_M4U_ID(9, 12)
+#define M4U_PORT_L9_IMG_SMTI_T1_B		MTK_M4U_ID(9, 13)
+#define M4U_PORT_L9_IMG_TNCSO_T1_A		MTK_M4U_ID(9, 14)
+#define M4U_PORT_L9_IMG_SMTO_T1_A		MTK_M4U_ID(9, 15)
+#define M4U_PORT_L9_IMG_TNCSTO_T1_A		MTK_M4U_ID(9, 16)
+#define M4U_PORT_L9_IMG_YUVO_T2_B		MTK_M4U_ID(9, 17)
+#define M4U_PORT_L9_IMG_YUVO_T5_B		MTK_M4U_ID(9, 18)
+#define M4U_PORT_L9_IMG_SMTO_T1_B		MTK_M4U_ID(9, 19)
+
+/* larb10 */
+#define M4U_PORT_L10_IMG_IMGI_D1_A		MTK_M4U_ID(10, 0)
+#define M4U_PORT_L10_IMG_IMGCI_D1_A		MTK_M4U_ID(10, 1)
+#define M4U_PORT_L10_IMG_DEPI_D1_A		MTK_M4U_ID(10, 2)
+#define M4U_PORT_L10_IMG_DMGI_D1_A		MTK_M4U_ID(10, 3)
+#define M4U_PORT_L10_IMG_VIPI_D1_A		MTK_M4U_ID(10, 4)
+#define M4U_PORT_L10_IMG_TNRWI_D1_A		MTK_M4U_ID(10, 5)
+#define M4U_PORT_L10_IMG_RECI_D1_A		MTK_M4U_ID(10, 6)
+#define M4U_PORT_L10_IMG_SMTI_D1_A		MTK_M4U_ID(10, 7)
+#define M4U_PORT_L10_IMG_SMTI_D6_A		MTK_M4U_ID(10, 8)
+#define M4U_PORT_L10_IMG_PIMGI_P1_A		MTK_M4U_ID(10, 9)
+#define M4U_PORT_L10_IMG_PIMGBI_P1_A		MTK_M4U_ID(10, 10)
+#define M4U_PORT_L10_IMG_PIMGCI_P1_A		MTK_M4U_ID(10, 11)
+#define M4U_PORT_L10_IMG_PIMGI_P1_B		MTK_M4U_ID(10, 12)
+#define M4U_PORT_L10_IMG_PIMGBI_P1_B		MTK_M4U_ID(10, 13)
+#define M4U_PORT_L10_IMG_PIMGCI_P1_B		MTK_M4U_ID(10, 14)
+#define M4U_PORT_L10_IMG_IMG3O_D1_A		MTK_M4U_ID(10, 15)
+#define M4U_PORT_L10_IMG_IMG4O_D1_A		MTK_M4U_ID(10, 16)
+#define M4U_PORT_L10_IMG_IMG3CO_D1_A		MTK_M4U_ID(10, 17)
+#define M4U_PORT_L10_IMG_FEO_D1_A		MTK_M4U_ID(10, 18)
+#define M4U_PORT_L10_IMG_IMG2O_D1_A		MTK_M4U_ID(10, 19)
+#define M4U_PORT_L10_IMG_TNRWO_D1_A		MTK_M4U_ID(10, 20)
+#define M4U_PORT_L10_IMG_SMTO_D1_A		MTK_M4U_ID(10, 21)
+#define M4U_PORT_L10_IMG_WROT_P1_A		MTK_M4U_ID(10, 22)
+#define M4U_PORT_L10_IMG_WROT_P1_B		MTK_M4U_ID(10, 23)
+
+/* larb11 */
+#define M4U_PORT_L11_IMG_WPE_EIS_RDMA0_A	MTK_M4U_ID(11, 0)
+#define M4U_PORT_L11_IMG_WPE_EIS_RDMA1_A	MTK_M4U_ID(11, 1)
+#define M4U_PORT_L11_IMG_WPE_EIS_WDMA0_A	MTK_M4U_ID(11, 2)
+#define M4U_PORT_L11_IMG_WPE_TNR_RDMA0_A	MTK_M4U_ID(11, 3)
+#define M4U_PORT_L11_IMG_WPE_TNR_RDMA1_A	MTK_M4U_ID(11, 4)
+#define M4U_PORT_L11_IMG_WPE_TNR_WDMA0_A	MTK_M4U_ID(11, 5)
+#define M4U_PORT_L11_IMG_WPE_EIS_CQ0_A		MTK_M4U_ID(11, 6)
+#define M4U_PORT_L11_IMG_WPE_EIS_CQ1_A		MTK_M4U_ID(11, 7)
+#define M4U_PORT_L11_IMG_WPE_TNR_CQ0_A		MTK_M4U_ID(11, 8)
+#define M4U_PORT_L11_IMG_WPE_TNR_CQ1_A		MTK_M4U_ID(11, 9)
+
+/* larb12 */
+#define M4U_PORT_L12_IMG_FDVT_RDA		MTK_M4U_ID(12, 0)
+#define M4U_PORT_L12_IMG_FDVT_RDB		MTK_M4U_ID(12, 1)
+#define M4U_PORT_L12_IMG_FDVT_WRA		MTK_M4U_ID(12, 2)
+#define M4U_PORT_L12_IMG_FDVT_WRB		MTK_M4U_ID(12, 3)
+#define M4U_PORT_L12_IMG_ME_RDMA		MTK_M4U_ID(12, 4)
+#define M4U_PORT_L12_IMG_ME_WDMA		MTK_M4U_ID(12, 5)
+#define M4U_PORT_L12_IMG_DVS_RDMA		MTK_M4U_ID(12, 6)
+#define M4U_PORT_L12_IMG_DVS_WDMA		MTK_M4U_ID(12, 7)
+#define M4U_PORT_L12_IMG_DVP_RDMA		MTK_M4U_ID(12, 8)
+#define M4U_PORT_L12_IMG_DVP_WDMA		MTK_M4U_ID(12, 9)
+
+/* larb13 */
+#define M4U_PORT_L13_CAM_CAMSV_CQI_E1		MTK_M4U_ID(13, 0)
+#define M4U_PORT_L13_CAM_CAMSV_CQI_E2		MTK_M4U_ID(13, 1)
+#define M4U_PORT_L13_CAM_GCAMSV_A_IMGO_0	MTK_M4U_ID(13, 2)
+#define M4U_PORT_L13_CAM_SCAMSV_A_IMGO_0	MTK_M4U_ID(13, 3)
+#define M4U_PORT_L13_CAM_GCAMSV_B_IMGO_0	MTK_M4U_ID(13, 4)
+#define M4U_PORT_L13_CAM_GCAMSV_B_IMGO_1	MTK_M4U_ID(13, 5)
+#define M4U_PORT_L13_CAM_GCAMSV_A_UFEO_0	MTK_M4U_ID(13, 6)
+#define M4U_PORT_L13_CAM_GCAMSV_B_UFEO_0	MTK_M4U_ID(13, 7)
+#define M4U_PORT_L13_CAM_PDAI_0			MTK_M4U_ID(13, 8)
+#define M4U_PORT_L13_CAM_FAKE			MTK_M4U_ID(13, 9)
+
+/* larb14 */
+#define M4U_PORT_L14_CAM_GCAMSV_A_IMGO_1	MTK_M4U_ID(14, 0)
+#define M4U_PORT_L14_CAM_SCAMSV_A_IMGO_1	MTK_M4U_ID(14, 1)
+#define M4U_PORT_L14_CAM_GCAMSV_B_IMGO_0	MTK_M4U_ID(14, 2)
+#define M4U_PORT_L14_CAM_GCAMSV_B_IMGO_1	MTK_M4U_ID(14, 3)
+#define M4U_PORT_L14_CAM_SCAMSV_B_IMGO_0	MTK_M4U_ID(14, 4)
+#define M4U_PORT_L14_CAM_SCAMSV_B_IMGO_1	MTK_M4U_ID(14, 5)
+#define M4U_PORT_L14_CAM_IPUI			MTK_M4U_ID(14, 6)
+#define M4U_PORT_L14_CAM_IPU2I			MTK_M4U_ID(14, 7)
+#define M4U_PORT_L14_CAM_IPUO			MTK_M4U_ID(14, 8)
+#define M4U_PORT_L14_CAM_IPU2O			MTK_M4U_ID(14, 9)
+#define M4U_PORT_L14_CAM_IPU3O			MTK_M4U_ID(14, 10)
+#define M4U_PORT_L14_CAM_GCAMSV_A_UFEO_1	MTK_M4U_ID(14, 11)
+#define M4U_PORT_L14_CAM_GCAMSV_B_UFEO_1	MTK_M4U_ID(14, 12)
+#define M4U_PORT_L14_CAM_PDAI_1			MTK_M4U_ID(14, 13)
+#define M4U_PORT_L14_CAM_PDAO			MTK_M4U_ID(14, 14)
+
+/* larb15: null */
+
+/* larb16 */
+#define M4U_PORT_L16_CAM_IMGO_R1		MTK_M4U_ID(16, 0)
+#define M4U_PORT_L16_CAM_CQI_R1			MTK_M4U_ID(16, 1)
+#define M4U_PORT_L16_CAM_CQI_R2			MTK_M4U_ID(16, 2)
+#define M4U_PORT_L16_CAM_BPCI_R1		MTK_M4U_ID(16, 3)
+#define M4U_PORT_L16_CAM_LSCI_R1		MTK_M4U_ID(16, 4)
+#define M4U_PORT_L16_CAM_RAWI_R2		MTK_M4U_ID(16, 5)
+#define M4U_PORT_L16_CAM_RAWI_R3		MTK_M4U_ID(16, 6)
+#define M4U_PORT_L16_CAM_UFDI_R2		MTK_M4U_ID(16, 7)
+#define M4U_PORT_L16_CAM_UFDI_R3		MTK_M4U_ID(16, 8)
+#define M4U_PORT_L16_CAM_RAWI_R4		MTK_M4U_ID(16, 9)
+#define M4U_PORT_L16_CAM_RAWI_R5		MTK_M4U_ID(16, 10)
+#define M4U_PORT_L16_CAM_AAI_R1			MTK_M4U_ID(16, 11)
+#define M4U_PORT_L16_CAM_FHO_R1			MTK_M4U_ID(16, 12)
+#define M4U_PORT_L16_CAM_AAO_R1			MTK_M4U_ID(16, 13)
+#define M4U_PORT_L16_CAM_TSFSO_R1		MTK_M4U_ID(16, 14)
+#define M4U_PORT_L16_CAM_FLKO_R1		MTK_M4U_ID(16, 15)
+
+/* larb17 */
+#define M4U_PORT_L17_CAM_YUVO_R1		MTK_M4U_ID(17, 0)
+#define M4U_PORT_L17_CAM_YUVO_R3		MTK_M4U_ID(17, 1)
+#define M4U_PORT_L17_CAM_YUVCO_R1		MTK_M4U_ID(17, 2)
+#define M4U_PORT_L17_CAM_YUVO_R2		MTK_M4U_ID(17, 3)
+#define M4U_PORT_L17_CAM_RZH1N2TO_R1		MTK_M4U_ID(17, 4)
+#define M4U_PORT_L17_CAM_DRZS4NO_R1		MTK_M4U_ID(17, 5)
+#define M4U_PORT_L17_CAM_TNCSO_R1		MTK_M4U_ID(17, 6)
+
+/* larb18 */
+#define M4U_PORT_L18_CAM_CCUI			MTK_M4U_ID(18, 0)
+#define M4U_PORT_L18_CAM_CCUO			MTK_M4U_ID(18, 1)
+#define M4U_PORT_L18_CAM_CCUI2			MTK_M4U_ID(18, 2)
+#define M4U_PORT_L18_CAM_CCUO2			MTK_M4U_ID(18, 3)
+
+/* larb19 */
+#define M4U_PORT_L19_VENC_RCPU			MTK_M4U_ID(19, 0)
+#define M4U_PORT_L19_VENC_REC			MTK_M4U_ID(19, 1)
+#define M4U_PORT_L19_VENC_BSDMA			MTK_M4U_ID(19, 2)
+#define M4U_PORT_L19_VENC_SV_COMV		MTK_M4U_ID(19, 3)
+#define M4U_PORT_L19_VENC_RD_COMV		MTK_M4U_ID(19, 4)
+#define M4U_PORT_L19_VENC_NBM_RDMA		MTK_M4U_ID(19, 5)
+#define M4U_PORT_L19_VENC_NBM_RDMA_LITE		MTK_M4U_ID(19, 6)
+#define M4U_PORT_L19_JPGENC_Y_RDMA		MTK_M4U_ID(19, 7)
+#define M4U_PORT_L19_JPGENC_C_RDMA		MTK_M4U_ID(19, 8)
+#define M4U_PORT_L19_JPGENC_Q_TABLE		MTK_M4U_ID(19, 9)
+#define M4U_PORT_L19_VENC_SUB_W_LUMA		MTK_M4U_ID(19, 10)
+#define M4U_PORT_L19_VENC_FCS_NBM_RDMA		MTK_M4U_ID(19, 11)
+#define M4U_PORT_L19_JPGENC_BSDMA		MTK_M4U_ID(19, 12)
+#define M4U_PORT_L19_JPGDEC_WDMA0		MTK_M4U_ID(19, 13)
+#define M4U_PORT_L19_JPGDEC_BSDMA0		MTK_M4U_ID(19, 14)
+#define M4U_PORT_L19_VENC_NBM_WDMA		MTK_M4U_ID(19, 15)
+#define M4U_PORT_L19_VENC_NBM_WDMA_LITE		MTK_M4U_ID(19, 16)
+#define M4U_PORT_L19_VENC_FCS_NBM_WDMA		MTK_M4U_ID(19, 17)
+#define M4U_PORT_L19_JPGDEC_WDMA1		MTK_M4U_ID(19, 18)
+#define M4U_PORT_L19_JPGDEC_BSDMA1		MTK_M4U_ID(19, 19)
+#define M4U_PORT_L19_JPGDEC_BUFF_OFFSET1	MTK_M4U_ID(19, 20)
+#define M4U_PORT_L19_JPGDEC_BUFF_OFFSET0	MTK_M4U_ID(19, 21)
+#define M4U_PORT_L19_VENC_CUR_LUMA		MTK_M4U_ID(19, 22)
+#define M4U_PORT_L19_VENC_CUR_CHROMA		MTK_M4U_ID(19, 23)
+#define M4U_PORT_L19_VENC_REF_LUMA		MTK_M4U_ID(19, 24)
+#define M4U_PORT_L19_VENC_REF_CHROMA		MTK_M4U_ID(19, 25)
+#define M4U_PORT_L19_VENC_SUB_R_CHROMA		MTK_M4U_ID(19, 26)
+
+/* larb20 */
+#define M4U_PORT_L20_VENC_RCPU			MTK_M4U_ID(20, 0)
+#define M4U_PORT_L20_VENC_REC			MTK_M4U_ID(20, 1)
+#define M4U_PORT_L20_VENC_BSDMA			MTK_M4U_ID(20, 2)
+#define M4U_PORT_L20_VENC_SV_COMV		MTK_M4U_ID(20, 3)
+#define M4U_PORT_L20_VENC_RD_COMV		MTK_M4U_ID(20, 4)
+#define M4U_PORT_L20_VENC_NBM_RDMA		MTK_M4U_ID(20, 5)
+#define M4U_PORT_L20_VENC_NBM_RDMA_LITE		MTK_M4U_ID(20, 6)
+#define M4U_PORT_L20_JPGENC_Y_RDMA		MTK_M4U_ID(20, 7)
+#define M4U_PORT_L20_JPGENC_C_RDMA		MTK_M4U_ID(20, 8)
+#define M4U_PORT_L20_JPGENC_Q_TABLE		MTK_M4U_ID(20, 9)
+#define M4U_PORT_L20_VENC_SUB_W_LUMA		MTK_M4U_ID(20, 10)
+#define M4U_PORT_L20_VENC_FCS_NBM_RDMA		MTK_M4U_ID(20, 11)
+#define M4U_PORT_L20_JPGENC_BSDMA		MTK_M4U_ID(20, 12)
+#define M4U_PORT_L20_JPGDEC_WDMA0		MTK_M4U_ID(20, 13)
+#define M4U_PORT_L20_JPGDEC_BSDMA0		MTK_M4U_ID(20, 14)
+#define M4U_PORT_L20_VENC_NBM_WDMA		MTK_M4U_ID(20, 15)
+#define M4U_PORT_L20_VENC_NBM_WDMA_LITE		MTK_M4U_ID(20, 16)
+#define M4U_PORT_L20_VENC_FCS_NBM_WDMA		MTK_M4U_ID(20, 17)
+#define M4U_PORT_L20_JPGDEC_WDMA1		MTK_M4U_ID(20, 18)
+#define M4U_PORT_L20_JPGDEC_BSDMA1		MTK_M4U_ID(20, 19)
+#define M4U_PORT_L20_JPGDEC_BUFF_OFFSET1	MTK_M4U_ID(20, 20)
+#define M4U_PORT_L20_JPGDEC_BUFF_OFFSET0	MTK_M4U_ID(20, 21)
+#define M4U_PORT_L20_VENC_CUR_LUMA		MTK_M4U_ID(20, 22)
+#define M4U_PORT_L20_VENC_CUR_CHROMA		MTK_M4U_ID(20, 23)
+#define M4U_PORT_L20_VENC_REF_LUMA		MTK_M4U_ID(20, 24)
+#define M4U_PORT_L20_VENC_REF_CHROMA		MTK_M4U_ID(20, 25)
+#define M4U_PORT_L20_VENC_SUB_R_CHROMA		MTK_M4U_ID(20, 26)
+
+/* larb21 */
+#define M4U_PORT_L21_VDEC_MC_EXT		MTK_M4U_ID(21, 0)
+#define M4U_PORT_L21_VDEC_UFO_EXT		MTK_M4U_ID(21, 1)
+#define M4U_PORT_L21_VDEC_PP_EXT		MTK_M4U_ID(21, 2)
+#define M4U_PORT_L21_VDEC_PRED_RD_EXT		MTK_M4U_ID(21, 3)
+#define M4U_PORT_L21_VDEC_PRED_WR_EXT		MTK_M4U_ID(21, 4)
+#define M4U_PORT_L21_VDEC_PPWRAP_EXT		MTK_M4U_ID(21, 5)
+#define M4U_PORT_L21_VDEC_TILE_EXT		MTK_M4U_ID(21, 6)
+#define M4U_PORT_L21_VDEC_VLD_EXT		MTK_M4U_ID(21, 7)
+#define M4U_PORT_L21_VDEC_VLD2_EXT		MTK_M4U_ID(21, 8)
+#define M4U_PORT_L21_VDEC_AVC_MV_EXT		MTK_M4U_ID(21, 9)
+
+/* larb22 */
+#define M4U_PORT_L22_VDEC_MC_EXT		MTK_M4U_ID(22, 0)
+#define M4U_PORT_L22_VDEC_UFO_EXT		MTK_M4U_ID(22, 1)
+#define M4U_PORT_L22_VDEC_PP_EXT		MTK_M4U_ID(22, 2)
+#define M4U_PORT_L22_VDEC_PRED_RD_EXT		MTK_M4U_ID(22, 3)
+#define M4U_PORT_L22_VDEC_PRED_WR_EXT		MTK_M4U_ID(22, 4)
+#define M4U_PORT_L22_VDEC_PPWRAP_EXT		MTK_M4U_ID(22, 5)
+#define M4U_PORT_L22_VDEC_TILE_EXT		MTK_M4U_ID(22, 6)
+#define M4U_PORT_L22_VDEC_VLD_EXT		MTK_M4U_ID(22, 7)
+#define M4U_PORT_L22_VDEC_VLD2_EXT		MTK_M4U_ID(22, 8)
+#define M4U_PORT_L22_VDEC_AVC_MV_EXT		MTK_M4U_ID(22, 9)
+
+/* larb23 */
+#define M4U_PORT_L23_VDEC_UFO_ENC_EXT		MTK_M4U_ID(23, 0)
+#define M4U_PORT_L23_VDEC_RDMA_EXT		MTK_M4U_ID(23, 1)
+
+/* larb24 */
+#define M4U_PORT_L24_VDEC_LAT0_VLD_EXT		MTK_M4U_ID(24, 0)
+#define M4U_PORT_L24_VDEC_LAT0_VLD2_EXT		MTK_M4U_ID(24, 1)
+#define M4U_PORT_L24_VDEC_LAT0_AVC_MC_EXT	MTK_M4U_ID(24, 2)
+#define M4U_PORT_L24_VDEC_LAT0_PRED_RD_EXT	MTK_M4U_ID(24, 3)
+#define M4U_PORT_L24_VDEC_LAT0_TILE_EXT		MTK_M4U_ID(24, 4)
+#define M4U_PORT_L24_VDEC_LAT0_WDMA_EXT		MTK_M4U_ID(24, 5)
+#define M4U_PORT_L24_VDEC_LAT1_VLD_EXT		MTK_M4U_ID(24, 6)
+#define M4U_PORT_L24_VDEC_LAT1_VLD2_EXT		MTK_M4U_ID(24, 7)
+#define M4U_PORT_L24_VDEC_LAT1_AVC_MC_EXT	MTK_M4U_ID(24, 8)
+#define M4U_PORT_L24_VDEC_LAT1_PRED_RD_EXT	MTK_M4U_ID(24, 9)
+#define M4U_PORT_L24_VDEC_LAT1_TILE_EXT		MTK_M4U_ID(24, 10)
+#define M4U_PORT_L24_VDEC_LAT1_WDMA_EXT		MTK_M4U_ID(24, 11)
+
+/* larb25 */
+#define M4U_PORT_L25_CAM_MRAW0_LSCI_M1		MTK_M4U_ID(25, 0)
+#define M4U_PORT_L25_CAM_MRAW0_CQI_M1		MTK_M4U_ID(25, 1)
+#define M4U_PORT_L25_CAM_MRAW0_CQI_M2		MTK_M4U_ID(25, 2)
+#define M4U_PORT_L25_CAM_MRAW0_IMGO_M1		MTK_M4U_ID(25, 3)
+#define M4U_PORT_L25_CAM_MRAW0_IMGBO_M1		MTK_M4U_ID(25, 4)
+#define M4U_PORT_L25_CAM_MRAW2_LSCI_M1		MTK_M4U_ID(25, 5)
+#define M4U_PORT_L25_CAM_MRAW2_CQI_M1		MTK_M4U_ID(25, 6)
+#define M4U_PORT_L25_CAM_MRAW2_CQI_M2		MTK_M4U_ID(25, 7)
+#define M4U_PORT_L25_CAM_MRAW2_IMGO_M1		MTK_M4U_ID(25, 8)
+#define M4U_PORT_L25_CAM_MRAW2_IMGBO_M1		MTK_M4U_ID(25, 9)
+#define M4U_PORT_L25_CAM_MRAW0_AFO_M1		MTK_M4U_ID(25, 10)
+#define M4U_PORT_L25_CAM_MRAW2_AFO_M1		MTK_M4U_ID(25, 11)
+
+/* larb26 */
+#define M4U_PORT_L26_CAM_MRAW1_LSCI_M1		MTK_M4U_ID(26, 0)
+#define M4U_PORT_L26_CAM_MRAW1_CQI_M1		MTK_M4U_ID(26, 1)
+#define M4U_PORT_L26_CAM_MRAW1_CQI_M2		MTK_M4U_ID(26, 2)
+#define M4U_PORT_L26_CAM_MRAW1_IMGO_M1		MTK_M4U_ID(26, 3)
+#define M4U_PORT_L26_CAM_MRAW1_IMGBO_M1		MTK_M4U_ID(26, 4)
+#define M4U_PORT_L26_CAM_MRAW3_LSCI_M1		MTK_M4U_ID(26, 5)
+#define M4U_PORT_L26_CAM_MRAW3_CQI_M1		MTK_M4U_ID(26, 6)
+#define M4U_PORT_L26_CAM_MRAW3_CQI_M2		MTK_M4U_ID(26, 7)
+#define M4U_PORT_L26_CAM_MRAW3_IMGO_M1		MTK_M4U_ID(26, 8)
+#define M4U_PORT_L26_CAM_MRAW3_IMGBO_M1		MTK_M4U_ID(26, 9)
+#define M4U_PORT_L26_CAM_MRAW1_AFO_M1		MTK_M4U_ID(26, 10)
+#define M4U_PORT_L26_CAM_MRAW3_AFO_M1		MTK_M4U_ID(26, 11)
+
+/* larb27 */
+#define M4U_PORT_L27_CAM_IMGO_R1		MTK_M4U_ID(27, 0)
+#define M4U_PORT_L27_CAM_CQI_R1			MTK_M4U_ID(27, 1)
+#define M4U_PORT_L27_CAM_CQI_R2			MTK_M4U_ID(27, 2)
+#define M4U_PORT_L27_CAM_BPCI_R1		MTK_M4U_ID(27, 3)
+#define M4U_PORT_L27_CAM_LSCI_R1		MTK_M4U_ID(27, 4)
+#define M4U_PORT_L27_CAM_RAWI_R2		MTK_M4U_ID(27, 5)
+#define M4U_PORT_L27_CAM_RAWI_R3		MTK_M4U_ID(27, 6)
+#define M4U_PORT_L27_CAM_UFDI_R2		MTK_M4U_ID(27, 7)
+#define M4U_PORT_L27_CAM_UFDI_R3		MTK_M4U_ID(27, 8)
+#define M4U_PORT_L27_CAM_RAWI_R4		MTK_M4U_ID(27, 9)
+#define M4U_PORT_L27_CAM_RAWI_R5		MTK_M4U_ID(27, 10)
+#define M4U_PORT_L27_CAM_AAI_R1			MTK_M4U_ID(27, 11)
+#define M4U_PORT_L27_CAM_FHO_R1			MTK_M4U_ID(27, 12)
+#define M4U_PORT_L27_CAM_AAO_R1			MTK_M4U_ID(27, 13)
+#define M4U_PORT_L27_CAM_TSFSO_R1		MTK_M4U_ID(27, 14)
+#define M4U_PORT_L27_CAM_FLKO_R1		MTK_M4U_ID(27, 15)
+
+/* larb28 */
+#define M4U_PORT_L28_CAM_YUVO_R1		MTK_M4U_ID(28, 0)
+#define M4U_PORT_L28_CAM_YUVO_R3		MTK_M4U_ID(28, 1)
+#define M4U_PORT_L28_CAM_YUVCO_R1		MTK_M4U_ID(28, 2)
+#define M4U_PORT_L28_CAM_YUVO_R2		MTK_M4U_ID(28, 3)
+#define M4U_PORT_L28_CAM_RZH1N2TO_R1		MTK_M4U_ID(28, 4)
+#define M4U_PORT_L28_CAM_DRZS4NO_R1		MTK_M4U_ID(28, 5)
+#define M4U_PORT_L28_CAM_TNCSO_R1		MTK_M4U_ID(28, 6)
+
+#endif
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:00 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:00 +0800
Subject: [PATCH v2 05/29] iommu/mediatek: Add 12G~16G support for multi domains
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-6-yong.wu@mediatek.com>

In mt8192, we preassign 0-4G; 4G-8G; 8G-12G for different multimedia
engines. This depends on the "dma-ranges=" in the iommu consumer's dtsi
node.

Adds 12G-16G region here. and reword the previous comment. we don't limit
which master locate in which region.

CCU still is 8G-12G. Don't change it here.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 287dfc0fc6f8..259ff7b90ff3 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -179,10 +179,12 @@ static const struct mtk_iommu_iova_region single_domain[] = {
 };
 
 static const struct mtk_iommu_iova_region mt8192_multi_dom[] = {
-	{ .iova_base = 0x0,		.size = SZ_4G},		/* disp: 0 ~ 4G */
+	{ .iova_base = 0x0,		.size = SZ_4G},		/* 0 ~ 4G */
 	#if IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)
-	{ .iova_base = SZ_4G,		.size = SZ_4G},		/* vdec: 4G ~ 8G */
-	{ .iova_base = SZ_4G * 2,	.size = SZ_4G},		/* CAM/MDP: 8G ~ 12G */
+	{ .iova_base = SZ_4G,		.size = SZ_4G},		/* 4G ~ 8G */
+	{ .iova_base = SZ_4G * 2,	.size = SZ_4G},		/* 8G ~ 12G */
+	{ .iova_base = SZ_4G * 3,	.size = SZ_4G},		/* 12G ~ 16G */
+
 	{ .iova_base = 0x240000000ULL,	.size = 0x4000000},	/* CCU0 */
 	{ .iova_base = 0x244000000ULL,	.size = 0x4000000},	/* CCU1 */
 	#endif
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:04 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:04 +0800
Subject: [PATCH v2 09/29] iommu/mediatek: Add tlb_lock in tlb_flush_all
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-10-yong.wu@mediatek.com>

The tlb_flush_all also touches the registers about tlb operations.
Add spinlock in it to protect the tlb registers. If flush_all is called
from tlb_flush_range, then no need this spinlock as tlb_flush_range
already hold the tlb_lock.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 1e18fff76e61..d64139ab59d0 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -205,15 +205,24 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
 	return container_of(dom, struct mtk_iommu_domain, domain);
 }
 
-static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
+static void __mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 {
-	if (pm_runtime_get_if_in_use(data->dev) <= 0)
-		return;
-
 	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
 		       data->base + data->plat_data->inv_sel_reg);
 	writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
 	wmb(); /* Make sure the tlb flush all done */
+}
+
+static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
+{
+	unsigned long flags;
+
+	if (pm_runtime_get_if_in_use(data->dev) <= 0)
+		return;
+
+	spin_lock_irqsave(&data->tlb_lock, flags);
+	__mtk_iommu_tlb_flush_all(data);
+	spin_unlock_irqrestore(&data->tlb_lock, flags);
 
 	pm_runtime_put(data->dev);
 }
@@ -251,7 +260,7 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 		if (ret) {
 			dev_warn(data->dev,
 				 "Partial TLB flush timed out, falling back to full flush\n");
-			mtk_iommu_tlb_flush_all(data);
+			__mtk_iommu_tlb_flush_all(data);
 		}
 		/* Clear the CPE status */
 		writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:06 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:06 +0800
Subject: [PATCH v2 11/29] iommu/mediatek: Always pm_runtime_get while tlb flush
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-12-yong.wu@mediatek.com>

Prepare for 2 HWs that sharing pgtable in different power-domains.

The previous SoC don't have PM. Only mt8192 has power-domain,
and it is display's power-domain which nearly always is enabled.

When there are 2 M4U HWs, it may has problem.
In this function, we get the pm_status via the m4u dev, but it don't
reflect the real power-domain status of the HW since there may be other
HW also use that power-domain.

Currently we could not get the real power-domain status, thus always
pm_runtime_get here.

Prepare for mt8195, thus, no need fix tags here.

This patch may drop the performance, we expect the user could
pm_runtime_get_sync before dma_alloc_attrs which need tlb ops.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index add23a36a5e2..abc721a1da21 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -238,8 +238,11 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 
 	for_each_m4u(data, head) {
 		if (has_pm) {
-			if (pm_runtime_get_if_in_use(data->dev) <= 0)
+			ret = pm_runtime_resume_and_get(data->dev);
+			if (ret < 0) {
+				dev_err(data->dev, "tlb flush: pm get fail %d.\n", ret);
 				continue;
+			}
 		}
 
 		spin_lock_irqsave(&data->tlb_lock, flags);
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:13 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:13 +0800
Subject: [PATCH v2 18/29] iommu/mediatek: Add PCIe support
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-19-yong.wu@mediatek.com>

Currently the code for of_iommu_configure_dev_id is like this:

static int of_iommu_configure_dev_id(struct device_node *master_np,
                                     struct device *dev,
                                     const u32 *id)
{
       struct of_phandle_args iommu_spec = { .args_count = 1 };

       err = of_map_id(master_np, *id, "iommu-map",
                       "iommu-map-mask", &iommu_spec.np,
                       iommu_spec.args);
...
}

It supports only one id output. BUT our PCIe HW has two ID(one is for
writing, the other is for reading). I'm not sure if we should change
of_map_id to support output MAX_PHANDLE_ARGS.

Here add the solution in ourselve drivers. If it's pcie case, enable one
more bit.

Not all infra iommu support PCIe, thus add a PCIe support flag here.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 45b34f4e99fb..b7a31f3a1bcf 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -21,6 +21,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
@@ -133,6 +134,7 @@
 #define MTK_IOMMU_TYPE_MM		(0x0 << 13)
 #define MTK_IOMMU_TYPE_INFRA		(0x1 << 13)
 #define MTK_IOMMU_TYPE_MASK		(0x3 << 13)
+#define IFA_IOMMU_PCIe_SUPPORT		BIT(15)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x)	(!!(((pdata)->flags) & (_x)))
 
@@ -409,8 +411,12 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 				larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
 		} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) {
 			peri_mmuen_msk = BIT(portid);
-			peri_mmuen = enable ? peri_mmuen_msk : 0;
 
+			/* PCIdev has only one output id, enable the next writing bit for PCIe */
+			if (dev_is_pci(dev))
+				peri_mmuen_msk |= BIT(portid + 1);
+
+			peri_mmuen = enable ? peri_mmuen_msk : 0;
 			ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1,
 						 peri_mmuen_msk, peri_mmuen);
 			if (ret)
@@ -996,6 +1002,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
 		if (ret)
 			goto out_bus_set_null;
+	} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
+		   MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIe_SUPPORT)) {
+		#ifdef CONFIG_PCI
+		if (!iommu_present(&pci_bus_type)) {
+			ret = bus_set_iommu(&pci_bus_type, &mtk_iommu_ops);
+			if (ret) /* PCIe fail don't affect platform_bus. */
+				goto out_list_del;
+		}
+		#endif
 	}
 	return ret;
 
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:15 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:15 +0800
Subject: [PATCH v2 20/29] iommu/mediatek: Only adjust code about register base
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-21-yong.wu@mediatek.com>

No functional change. Use "base" instead of the data->base. This is
avoid to touch too many lines in the next patches.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 45 +++++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index d7eec20f0476..48162e156486 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -248,6 +248,7 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 	struct list_head *head = data->hw_list;
 	bool has_pm = !!data->dev->pm_domain;
 	unsigned long flags;
+	void __iomem *base;
 	int ret;
 	u32 tmp;
 
@@ -260,19 +261,19 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 			}
 		}
 
+		base = data->base;
+
 		spin_lock_irqsave(&data->tlb_lock, flags);
 		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
-			       data->base + data->plat_data->inv_sel_reg);
+			       base + data->plat_data->inv_sel_reg);
 
-		writel_relaxed(MTK_IOMMU_TLB_ADDR(iova),
-			       data->base + REG_MMU_INVLD_START_A);
+		writel_relaxed(MTK_IOMMU_TLB_ADDR(iova), base + REG_MMU_INVLD_START_A);
 		writel_relaxed(MTK_IOMMU_TLB_ADDR(iova + size - 1),
-			       data->base + REG_MMU_INVLD_END_A);
-		writel_relaxed(F_MMU_INV_RANGE,
-			       data->base + REG_MMU_INVALIDATE);
+			       base + REG_MMU_INVLD_END_A);
+		writel_relaxed(F_MMU_INV_RANGE, base + REG_MMU_INVALIDATE);
 
 		/* tlb sync */
-		ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE,
+		ret = readl_poll_timeout_atomic(base + REG_MMU_CPE_DONE,
 						tmp, tmp != 0, 10, 1000);
 		if (ret) {
 			dev_warn(data->dev,
@@ -280,7 +281,7 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 			__mtk_iommu_tlb_flush_all(data);
 		}
 		/* Clear the CPE status */
-		writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
+		writel_relaxed(0, base + REG_MMU_CPE_DONE);
 		spin_unlock_irqrestore(&data->tlb_lock, flags);
 
 		if (has_pm)
@@ -294,23 +295,25 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	struct mtk_iommu_domain *dom = data->m4u_dom;
 	unsigned int fault_larb = 0, fault_port = 0, sub_comm = 0;
 	u32 int_state, regval, va34_32, pa34_32;
+	const struct mtk_iommu_plat_data *plat_data = data->plat_data;
+	void __iomem *base = data->base;
 	u64 fault_iova, fault_pa;
 	bool layer, write;
 
 	/* Read error info from registers */
-	int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1);
+	int_state = readl_relaxed(base + REG_MMU_FAULT_ST1);
 	if (int_state & F_REG_MMU0_FAULT_MASK) {
-		regval = readl_relaxed(data->base + REG_MMU0_INT_ID);
-		fault_iova = readl_relaxed(data->base + REG_MMU0_FAULT_VA);
-		fault_pa = readl_relaxed(data->base + REG_MMU0_INVLD_PA);
+		regval = readl_relaxed(base + REG_MMU0_INT_ID);
+		fault_iova = readl_relaxed(base + REG_MMU0_FAULT_VA);
+		fault_pa = readl_relaxed(base + REG_MMU0_INVLD_PA);
 	} else {
-		regval = readl_relaxed(data->base + REG_MMU1_INT_ID);
-		fault_iova = readl_relaxed(data->base + REG_MMU1_FAULT_VA);
-		fault_pa = readl_relaxed(data->base + REG_MMU1_INVLD_PA);
+		regval = readl_relaxed(base + REG_MMU1_INT_ID);
+		fault_iova = readl_relaxed(base + REG_MMU1_FAULT_VA);
+		fault_pa = readl_relaxed(base + REG_MMU1_INVLD_PA);
 	}
 	layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
 	write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
-	if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
+	if (MTK_IOMMU_HAS_FLAG(plat_data, IOVA_34_EN)) {
 		va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
 		fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
 		fault_iova |= (u64)va34_32 << 32;
@@ -318,12 +321,12 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
 	fault_pa |= (u64)pa34_32 << 32;
 
-	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+	if (MTK_IOMMU_IS_TYPE(plat_data, MTK_IOMMU_TYPE_MM)) {
 		fault_port = F_MMU_INT_ID_PORT_ID(regval);
-		if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
+		if (MTK_IOMMU_HAS_FLAG(plat_data, HAS_SUB_COMM_2BITS)) {
 			fault_larb = F_MMU_INT_ID_COMM_ID(regval);
 			sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
-		} else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
+		} else if (MTK_IOMMU_HAS_FLAG(plat_data, HAS_SUB_COMM_3BITS)) {
 			fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
 			sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
 		} else {
@@ -342,9 +345,9 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	}
 
 	/* Interrupt clear */
-	regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL0);
+	regval = readl_relaxed(base + REG_MMU_INT_CONTROL0);
 	regval |= F_INT_CLR_BIT;
-	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
+	writel_relaxed(regval, base + REG_MMU_INT_CONTROL0);
 
 	mtk_iommu_tlb_flush_all(data);
 
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:17 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:17 +0800
Subject: [PATCH v2 22/29] iommu/mediatek: Add mtk_iommu_bank_data structure
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-23-yong.wu@mediatek.com>

Prepare for supporting multi-banks for the IOMMU HW, No functional change.

Add a new structure(mtk_iommu_bank_data) for each a bank. Each a bank have
the independent HW base/IRQ, and each a bank has its special iommu-domain
(independent pgtable), thus, also move the domain information and tlb_lock
into it.

In previous SoC, we have only one bank which could be treated as bank0(
bankid always is 0 for the previous SoC).

After adding this structure, the tlb operations and irq could use
bank_data as parameter.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 151 +++++++++++++++++++++-----------------
 drivers/iommu/mtk_iommu.h |  24 +++++-
 2 files changed, 105 insertions(+), 70 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 26ac7c4cc3fe..c69a6f6dcc5a 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -147,7 +147,7 @@ struct mtk_iommu_domain {
 	struct io_pgtable_cfg		cfg;
 	struct io_pgtable_ops		*iop;
 
-	struct mtk_iommu_data		*data;
+	struct mtk_iommu_bank_data	*bank;
 	struct iommu_domain		domain;
 };
 
@@ -220,33 +220,35 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
 	return container_of(dom, struct mtk_iommu_domain, domain);
 }
 
-static void __mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
+static void __mtk_iommu_tlb_flush_all(struct mtk_iommu_bank_data *bank)
 {
 	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
-		       data->base + data->plat_data->inv_sel_reg);
-	writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
+		       bank->base + bank->pdata->plat_data->inv_sel_reg);
+	writel_relaxed(F_ALL_INVLD, bank->base + REG_MMU_INVALIDATE);
 	wmb(); /* Make sure the tlb flush all done */
 }
 
-static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
+static void mtk_iommu_tlb_flush_all(struct mtk_iommu_bank_data *bank)
 {
 	unsigned long flags;
 
-	if (pm_runtime_get_if_in_use(data->dev) <= 0)
+	if (pm_runtime_get_if_in_use(bank->pdev) <= 0)
 		return;
 
-	spin_lock_irqsave(&data->tlb_lock, flags);
-	__mtk_iommu_tlb_flush_all(data);
-	spin_unlock_irqrestore(&data->tlb_lock, flags);
+	spin_lock_irqsave(&bank->tlb_lock, flags);
+	__mtk_iommu_tlb_flush_all(bank);
+	spin_unlock_irqrestore(&bank->tlb_lock, flags);
 
-	pm_runtime_put(data->dev);
+	pm_runtime_put(bank->pdev);
 }
 
 static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
-					   struct mtk_iommu_data *data)
+					   struct mtk_iommu_bank_data *bank)
 {
-	struct list_head *head = data->hw_list;
-	bool has_pm = !!data->dev->pm_domain;
+	struct list_head *head = bank->pdata->hw_list;
+	bool has_pm = !!bank->pdev->pm_domain;
+	struct mtk_iommu_bank_data *curbank;
+	struct mtk_iommu_data *data;
 	unsigned long flags;
 	void __iomem *base;
 	int ret;
@@ -261,9 +263,10 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 			}
 		}
 
-		base = data->base;
+		curbank = &data->bank[bank->id];
+		base = curbank->base;
 
-		spin_lock_irqsave(&data->tlb_lock, flags);
+		spin_lock_irqsave(&curbank->tlb_lock, flags);
 		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
 			       base + data->plat_data->inv_sel_reg);
 
@@ -278,11 +281,11 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 		if (ret) {
 			dev_warn(data->dev,
 				 "Partial TLB flush timed out, falling back to full flush\n");
-			__mtk_iommu_tlb_flush_all(data);
+			__mtk_iommu_tlb_flush_all(curbank);
 		}
 		/* Clear the CPE status */
 		writel_relaxed(0, base + REG_MMU_CPE_DONE);
-		spin_unlock_irqrestore(&data->tlb_lock, flags);
+		spin_unlock_irqrestore(&curbank->tlb_lock, flags);
 
 		if (has_pm)
 			pm_runtime_put(data->dev);
@@ -291,12 +294,13 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 
 static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
-	struct mtk_iommu_data *data = dev_id;
-	struct mtk_iommu_domain *dom = data->m4u_dom;
+	struct mtk_iommu_bank_data *bank = dev_id;
+	struct mtk_iommu_data *data = bank->pdata;
+	struct mtk_iommu_domain *dom = bank->m4u_dom;
 	unsigned int fault_larb = 0, fault_port = 0, sub_comm = 0;
 	u32 int_state, regval, va34_32, pa34_32;
 	const struct mtk_iommu_plat_data *plat_data = data->plat_data;
-	void __iomem *base = data->base;
+	void __iomem *base = bank->base;
 	u64 fault_iova, fault_pa;
 	bool layer, write;
 
@@ -335,10 +339,10 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 		fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
 	}
 
-	if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
+	if (report_iommu_fault(&dom->domain, bank->pdev, fault_iova,
 			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
 		dev_err_ratelimited(
-			data->dev,
+			bank->pdev,
 			"fault type=0x%x iova=0x%llx pa=0x%llx master=0x%x(larb=%d port=%d) layer=%d %s\n",
 			int_state, fault_iova, fault_pa, regval, fault_larb, fault_port,
 			layer, write ? "write" : "read");
@@ -349,7 +353,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	regval |= F_INT_CLR_BIT;
 	writel_relaxed(regval, base + REG_MMU_INT_CONTROL0);
 
-	mtk_iommu_tlb_flush_all(data);
+	mtk_iommu_tlb_flush_all(bank);
 
 	return IRQ_HANDLED;
 }
@@ -436,12 +440,14 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
 				     unsigned int domid)
 {
 	const struct mtk_iommu_iova_region *region;
-
-	/* Use the exist domain as there is only one pgtable here. */
-	if (data->m4u_dom) {
-		dom->iop = data->m4u_dom->iop;
-		dom->cfg = data->m4u_dom->cfg;
-		dom->domain.pgsize_bitmap = data->m4u_dom->cfg.pgsize_bitmap;
+	struct mtk_iommu_domain	*m4u_dom;
+
+	/* Always use bank0 in sharing pgtable case */
+	m4u_dom = data->bank[0].m4u_dom;
+	if (m4u_dom) {
+		dom->iop = m4u_dom->iop;
+		dom->cfg = m4u_dom->cfg;
+		dom->domain.pgsize_bitmap = m4u_dom->cfg.pgsize_bitmap;
 		goto update_iova_region;
 	}
 
@@ -508,23 +514,26 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata;
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 	struct list_head *hw_list = data->hw_list;
+	struct mtk_iommu_bank_data *bank;
 	struct device *m4udev = data->dev;
+	unsigned int bankid = 0;
 	int ret, domid;
 
 	domid = mtk_iommu_get_domain_id(dev, data->plat_data);
 	if (domid < 0)
 		return domid;
 
-	if (!dom->data) {
+	bank = &data->bank[bankid];
+	if (!dom->bank) {
 		/* Data is in the frstdata in sharing pgtable case. */
 		frstdata = mtk_iommu_get_frst_data(hw_list);
 
 		if (mtk_iommu_domain_finalise(dom, frstdata, domid))
 			return -ENODEV;
-		dom->data = data;
+		dom->bank = bank;
 	}
 
-	if (!data->m4u_dom) { /* Initialize the M4U HW */
+	if (!bank->m4u_dom) { /* Initialize the M4U HW */
 		ret = pm_runtime_resume_and_get(m4udev);
 		if (ret < 0)
 			return ret;
@@ -534,9 +543,9 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 			pm_runtime_put(m4udev);
 			return ret;
 		}
-		data->m4u_dom = dom;
+		bank->m4u_dom = dom;
 		writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
-		       data->base + REG_MMU_PT_BASE_ADDR);
+		       bank->base + REG_MMU_PT_BASE_ADDR);
 
 		pm_runtime_put(m4udev);
 	}
@@ -558,7 +567,7 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
 	/* The "4GB mode" M4U physically can not use the lower remap of Dram. */
-	if (dom->data->enable_4GB)
+	if (dom->bank->pdata->enable_4GB)
 		paddr |= BIT_ULL(32);
 
 	/* Synchronize with the tlb_lock */
@@ -583,7 +592,7 @@ static void mtk_iommu_flush_iotlb_all(struct iommu_domain *domain)
 {
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
-	mtk_iommu_tlb_flush_all(dom->data);
+	mtk_iommu_tlb_flush_all(dom->bank);
 }
 
 static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
@@ -592,7 +601,7 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 	size_t length = gather->end - gather->start + 1;
 
-	mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->data);
+	mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->bank);
 }
 
 static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
@@ -600,7 +609,7 @@ static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
 {
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
-	mtk_iommu_tlb_flush_range_sync(iova, size, dom->data);
+	mtk_iommu_tlb_flush_range_sync(iova, size, dom->bank);
 }
 
 static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
@@ -610,7 +619,7 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
 	phys_addr_t pa;
 
 	pa = dom->iop->iova_to_phys(dom->iop, iova);
-	if (dom->data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
+	if (dom->bank->pdata->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
 		pa &= ~BIT_ULL(32);
 
 	return pa;
@@ -739,16 +748,17 @@ static const struct iommu_ops mtk_iommu_ops = {
 
 static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 {
+	const struct mtk_iommu_bank_data *bank0 = &data->bank[0];
 	u32 regval;
 
 	if (data->plat_data->m4u_plat == M4U_MT8173) {
 		regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
 			 F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173;
 	} else {
-		regval = readl_relaxed(data->base + REG_MMU_CTRL_REG);
+		regval = readl_relaxed(bank0->base + REG_MMU_CTRL_REG);
 		regval |= F_MMU_TF_PROT_TO_PROGRAM_ADDR;
 	}
-	writel_relaxed(regval, data->base + REG_MMU_CTRL_REG);
+	writel_relaxed(regval, bank0->base + REG_MMU_CTRL_REG);
 
 	if (data->enable_4GB &&
 	    MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_VLD_PA_RNG)) {
@@ -757,31 +767,31 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		 * 0x1_0000_0000 to 0x1_ffff_ffff. here record bit[32:30].
 		 */
 		regval = F_MMU_VLD_PA_RNG(7, 4);
-		writel_relaxed(regval, data->base + REG_MMU_VLD_PA_RNG);
+		writel_relaxed(regval, bank0->base + REG_MMU_VLD_PA_RNG);
 	}
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, DCM_DISABLE))
-		writel_relaxed(F_MMU_DCM, data->base + REG_MMU_DCM_DIS);
+		writel_relaxed(F_MMU_DCM, bank0->base + REG_MMU_DCM_DIS);
 	else
-		writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
+		writel_relaxed(0, bank0->base + REG_MMU_DCM_DIS);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) {
 		/* write command throttling mode */
-		regval = readl_relaxed(data->base + REG_MMU_WR_LEN_CTRL);
+		regval = readl_relaxed(bank0->base + REG_MMU_WR_LEN_CTRL);
 		regval &= ~F_MMU_WR_THROT_DIS_MASK;
-		writel_relaxed(regval, data->base + REG_MMU_WR_LEN_CTRL);
+		writel_relaxed(regval, bank0->base + REG_MMU_WR_LEN_CTRL);
 	}
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, RESET_AXI)) {
 		/* The register is called STANDARD_AXI_MODE in this case */
 		regval = 0;
 	} else {
-		regval = readl_relaxed(data->base + REG_MMU_MISC_CTRL);
+		regval = readl_relaxed(bank0->base + REG_MMU_MISC_CTRL);
 		if (MTK_IOMMU_HAS_FLAG(data->plat_data, NOT_STD_AXI_MODE))
 			regval &= ~F_MMU_STANDARD_AXI_MODE_MASK;
 		if (MTK_IOMMU_HAS_FLAG(data->plat_data, OUT_ORDER_WR_EN))
 			regval &= ~F_MMU_IN_ORDER_WR_EN_MASK;
 	}
-	writel_relaxed(regval, data->base + REG_MMU_MISC_CTRL);
+	writel_relaxed(regval, bank0->base + REG_MMU_MISC_CTRL);
 
 	regval = F_L2_MULIT_HIT_EN |
 		F_TABLE_WALK_FAULT_INT_EN |
@@ -789,7 +799,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		F_MISS_FIFO_OVERFLOW_INT_EN |
 		F_PREFETCH_FIFO_ERR_INT_EN |
 		F_MISS_FIFO_ERR_INT_EN;
-	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
+	writel_relaxed(regval, bank0->base + REG_MMU_INT_CONTROL0);
 
 	regval = F_INT_TRANSLATION_FAULT |
 		F_INT_MAIN_MULTI_HIT_FAULT |
@@ -798,19 +808,19 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		F_INT_TLB_MISS_FAULT |
 		F_INT_MISS_TRANSACTION_FIFO_FAULT |
 		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
-	writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
+	writel_relaxed(regval, bank0->base + REG_MMU_INT_MAIN_CONTROL);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
 		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
 	else
 		regval = lower_32_bits(data->protect_base) |
 			 upper_32_bits(data->protect_base);
-	writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
+	writel_relaxed(regval, bank0->base + REG_MMU_IVRP_PADDR);
 
-	if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
-			     dev_name(data->dev), (void *)data)) {
-		writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR);
-		dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq);
+	if (devm_request_irq(bank0->pdev, bank0->irq, mtk_iommu_isr, 0,
+			     dev_name(bank0->pdev), (void *)bank0)) {
+		writel_relaxed(0, bank0->base + REG_MMU_PT_BASE_ADDR);
+		dev_err(bank0->pdev, "Failed @ IRQ-%d Request\n", bank0->irq);
 		return -ENODEV;
 	}
 
@@ -904,6 +914,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	int                     ret;
 	u32			val;
 	char                    *p;
+	struct mtk_iommu_bank_data *bank;
+	void __iomem		*base;
 
 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 	if (!data)
@@ -941,14 +953,20 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(data->base))
-		return PTR_ERR(data->base);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
 	ioaddr = res->start;
 
-	data->irq = platform_get_irq(pdev, 0);
-	if (data->irq < 0)
-		return data->irq;
+	bank = &data->bank[0];
+	bank->id = 0;
+	bank->base = base;
+	bank->irq = platform_get_irq(pdev, 0);
+	if (bank->irq < 0)
+		return bank->irq;
+	bank->pdev = dev;
+	bank->pdata = data;
+	spin_lock_init(&bank->tlb_lock);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) {
 		data->bclk = devm_clk_get(dev, "bclk");
@@ -984,8 +1002,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	if (ret)
 		goto out_sysfs_remove;
 
-	spin_lock_init(&data->tlb_lock);
-
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) {
 		list_add_tail(&data->list, data->plat_data->hw_list);
 		data->hw_list = data->plat_data->hw_list;
@@ -1035,6 +1051,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 static int mtk_iommu_remove(struct platform_device *pdev)
 {
 	struct mtk_iommu_data *data = platform_get_drvdata(pdev);
+	struct mtk_iommu_bank_data *bank = &data->bank[0];
 
 	iommu_device_sysfs_remove(&data->iommu);
 	iommu_device_unregister(&data->iommu);
@@ -1046,7 +1063,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
 		device_link_remove(data->smicomm_dev, &pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	devm_free_irq(&pdev->dev, data->irq, data);
+	devm_free_irq(&pdev->dev, bank->irq, bank);
 	component_master_del(&pdev->dev, &mtk_iommu_com_ops);
 	return 0;
 }
@@ -1055,7 +1072,7 @@ static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
 	struct mtk_iommu_suspend_reg *reg = &data->reg;
-	void __iomem *base = data->base;
+	void __iomem *base = data->bank[0].base;
 
 	reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL);
 	reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL);
@@ -1073,8 +1090,8 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
 	struct mtk_iommu_suspend_reg *reg = &data->reg;
-	struct mtk_iommu_domain *m4u_dom = data->m4u_dom;
-	void __iomem *base = data->base;
+	struct mtk_iommu_domain *m4u_dom = data->bank[0].m4u_dom;
+	void __iomem *base = data->bank[0].base;
 	int ret;
 
 	ret = clk_prepare_enable(data->bclk);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index e7ede1123624..80dc08468eda 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -24,6 +24,8 @@
 
 #define MTK_IOMMU_GROUP_MAX	8
 
+#define MTK_IOMMU_BANK_MAX	5
+
 struct mtk_iommu_suspend_reg {
 	union {
 		u32			standard_axi_mode;/* v1 */
@@ -65,17 +67,33 @@ struct mtk_iommu_plat_data {
 
 struct mtk_iommu_domain;
 
-struct mtk_iommu_data {
+struct mtk_iommu_bank_data {
 	void __iomem			*base;
 	int				irq;
+	unsigned int			id;
+	struct device			*pdev;
+	struct mtk_iommu_data		*pdata;   /* parent data */
+	spinlock_t			tlb_lock; /* lock for tlb range flush */
+	struct mtk_iommu_domain		*m4u_dom; /* Each bank has a domain */
+};
+
+struct mtk_iommu_data {
+	union {
+		struct { /* only for gen1 */
+			void __iomem		*base;
+			int			irq;
+			struct mtk_iommu_domain	*m4u_dom;
+		};
+
+		/* only for gen2 that support multi-banks */
+		struct mtk_iommu_bank_data	bank[MTK_IOMMU_BANK_MAX];
+	};
 	struct device			*dev;
 	struct clk			*bclk;
 	phys_addr_t			protect_base; /* protect memory base */
 	struct mtk_iommu_suspend_reg	reg;
-	struct mtk_iommu_domain		*m4u_dom;
 	struct iommu_group		*m4u_group[MTK_IOMMU_GROUP_MAX];
 	bool                            enable_4GB;
-	spinlock_t			tlb_lock; /* lock for tlb range flush */
 
 	struct iommu_device		iommu;
 	const struct mtk_iommu_plat_data *plat_data;
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:52:57 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:52:57 +0800
Subject: [PATCH v2 02/29] dt-bindings: mediatek: mt8195: Add binding for infra
 IOMMU
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-3-yong.wu@mediatek.com>

In mt8195, we have a new IOMMU that is for INFRA IOMMU. its masters
mainly are PCIe and USB. Different with MM IOMMU, all these masters
connect with IOMMU directly, there is no mediatek,larbs property for
infra IOMMU.

Another thing is about PCIe ports. currently the function
"of_iommu_configure_dev_id" only support the id number is 1, But our
PCIe have two ports, one is for reading and the other is for writing.
see more about the PCIe patch in this patchset. Thus, I only list
the reading id here and add the other id in our driver.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
Change note: use "contains" commented from Rob.
---
 .../bindings/iommu/mediatek,iommu.yaml         | 13 ++++++++++++-
 .../dt-bindings/memory/mt8195-memory-port.h    | 18 ++++++++++++++++++
 include/dt-bindings/memory/mtk-memory-port.h   |  2 ++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index 9b04630158c8..c528a299afa9 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -79,6 +79,7 @@ properties:
           - mediatek,mt8192-m4u  # generation two
           - mediatek,mt8195-iommu-vdo        # generation two
           - mediatek,mt8195-iommu-vpp        # generation two
+          - mediatek,mt8195-iommu-infra      # generation two
 
       - description: mt7623 generation one
         items:
@@ -129,7 +130,6 @@ required:
   - compatible
   - reg
   - interrupts
-  - mediatek,larbs
   - '#iommu-cells'
 
 allOf:
@@ -161,6 +161,17 @@ allOf:
       required:
         - power-domains
 
+  - if: # The IOMMUs don't have larbs.
+      not:
+        properties:
+          compatible:
+            contains:
+              const: mediatek,mt8195-iommu-infra
+
+    then:
+      required:
+        - mediatek,larbs
+
 additionalProperties: false
 
 examples:
diff --git a/include/dt-bindings/memory/mt8195-memory-port.h b/include/dt-bindings/memory/mt8195-memory-port.h
index 783bcae8cdea..9882877cda9d 100644
--- a/include/dt-bindings/memory/mt8195-memory-port.h
+++ b/include/dt-bindings/memory/mt8195-memory-port.h
@@ -387,4 +387,22 @@
 #define M4U_PORT_L28_CAM_DRZS4NO_R1		MTK_M4U_ID(28, 5)
 #define M4U_PORT_L28_CAM_TNCSO_R1		MTK_M4U_ID(28, 6)
 
+/* Infra iommu ports */
+/* PCIe1: read: BIT16; write BIT17. */
+#define IOMMU_PORT_INFRA_PCIE1			MTK_IFAIOMMU_PERI_ID(16)
+/* PCIe0: read: BIT18; write BIT19. */
+#define IOMMU_PORT_INFRA_PCIE0			MTK_IFAIOMMU_PERI_ID(18)
+#define IOMMU_PORT_INFRA_SSUSB_P3_R		MTK_IFAIOMMU_PERI_ID(20)
+#define IOMMU_PORT_INFRA_SSUSB_P3_W		MTK_IFAIOMMU_PERI_ID(21)
+#define IOMMU_PORT_INFRA_SSUSB_P2_R		MTK_IFAIOMMU_PERI_ID(22)
+#define IOMMU_PORT_INFRA_SSUSB_P2_W		MTK_IFAIOMMU_PERI_ID(23)
+#define IOMMU_PORT_INFRA_SSUSB_P1_1_R		MTK_IFAIOMMU_PERI_ID(24)
+#define IOMMU_PORT_INFRA_SSUSB_P1_1_W		MTK_IFAIOMMU_PERI_ID(25)
+#define IOMMU_PORT_INFRA_SSUSB_P1_0_R		MTK_IFAIOMMU_PERI_ID(26)
+#define IOMMU_PORT_INFRA_SSUSB_P1_0_W		MTK_IFAIOMMU_PERI_ID(27)
+#define IOMMU_PORT_INFRA_SSUSB2_R		MTK_IFAIOMMU_PERI_ID(28)
+#define IOMMU_PORT_INFRA_SSUSB2_W		MTK_IFAIOMMU_PERI_ID(29)
+#define IOMMU_PORT_INFRA_SSUSB_R		MTK_IFAIOMMU_PERI_ID(30)
+#define IOMMU_PORT_INFRA_SSUSB_W		MTK_IFAIOMMU_PERI_ID(31)
+
 #endif
diff --git a/include/dt-bindings/memory/mtk-memory-port.h b/include/dt-bindings/memory/mtk-memory-port.h
index 7d64103209af..2f68a0511a25 100644
--- a/include/dt-bindings/memory/mtk-memory-port.h
+++ b/include/dt-bindings/memory/mtk-memory-port.h
@@ -12,4 +12,6 @@
 #define MTK_M4U_TO_LARB(id)		(((id) >> 5) & 0x1f)
 #define MTK_M4U_TO_PORT(id)		((id) & 0x1f)
 
+#define MTK_IFAIOMMU_PERI_ID(port)	MTK_M4U_ID(0, port)
+
 #endif
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:10 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:10 +0800
Subject: [PATCH v2 15/29] iommu/mediatek: Contain MM IOMMU flow with the MM
 TYPE
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-16-yong.wu@mediatek.com>

Prepare for supporting INFRA_IOMMU, and APU_IOMMU later.

For Infra IOMMU/APU IOMMU, it doesn't have the "larb""port". thus, Use
the MM flag contain the MM_IOMMU special flow, Also, it moves a big
chunk code about parsing the mediatek,larbs into a function, this is
only needed for MM IOMMU. and all the current SoC are MM_IOMMU.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 190 +++++++++++++++++++++-----------------
 1 file changed, 107 insertions(+), 83 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 20d15f80dd6e..a4479916ad33 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -288,7 +288,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
 	struct mtk_iommu_data *data = dev_id;
 	struct mtk_iommu_domain *dom = data->m4u_dom;
-	unsigned int fault_larb, fault_port, sub_comm = 0;
+	unsigned int fault_larb = 0, fault_port = 0, sub_comm = 0;
 	u32 int_state, regval, va34_32, pa34_32;
 	u64 fault_iova, fault_pa;
 	bool layer, write;
@@ -314,17 +314,19 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
 	fault_pa |= (u64)pa34_32 << 32;
 
-	fault_port = F_MMU_INT_ID_PORT_ID(regval);
-	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
-		fault_larb = F_MMU_INT_ID_COMM_ID(regval);
-		sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
-	} else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
-		fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
-		sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
-	} else {
-		fault_larb = F_MMU_INT_ID_LARB_ID(regval);
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+		fault_port = F_MMU_INT_ID_PORT_ID(regval);
+		if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
+			fault_larb = F_MMU_INT_ID_COMM_ID(regval);
+			sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
+		} else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
+			fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
+			sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
+		} else {
+			fault_larb = F_MMU_INT_ID_LARB_ID(regval);
+		}
+		fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
 	}
-	fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
 
 	if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
 			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
@@ -388,19 +390,21 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 		larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
 		portid = MTK_M4U_TO_PORT(fwspec->ids[i]);
 
-		larb_mmu = &data->larb_imu[larbid];
+		if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+			larb_mmu = &data->larb_imu[larbid];
 
-		region = data->plat_data->iova_region + domid;
-		larb_mmu->bank[portid] = upper_32_bits(region->iova_base);
+			region = data->plat_data->iova_region + domid;
+			larb_mmu->bank[portid] = upper_32_bits(region->iova_base);
 
-		dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n",
-			enable ? "enable" : "disable", dev_name(larb_mmu->dev),
-			portid, domid, larb_mmu->bank[portid]);
+			dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n",
+				enable ? "enable" : "disable", dev_name(larb_mmu->dev),
+				portid, domid, larb_mmu->bank[portid]);
 
-		if (enable)
-			larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
-		else
-			larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+			if (enable)
+				larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
+			else
+				larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+		}
 	}
 }
 
@@ -796,19 +800,75 @@ static const struct component_master_ops mtk_iommu_com_ops = {
 	.unbind		= mtk_iommu_unbind,
 };
 
+static int mtk_iommu_mm_dts_parse(struct device *dev,
+				  struct component_match **match,
+				  struct mtk_iommu_data *data)
+{
+	struct platform_device	*plarbdev;
+	struct device_link	*link;
+	struct device_node *larbnode, *smicomm_node;
+	int i, larb_nr, ret;
+
+	larb_nr = of_count_phandle_with_args(dev->of_node, "mediatek,larbs", NULL);
+	if (larb_nr < 0)
+		return larb_nr;
+
+	for (i = 0; i < larb_nr; i++) {
+		u32 id;
+
+		larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
+		if (!larbnode)
+			return -EINVAL;
+
+		if (!of_device_is_available(larbnode)) {
+			of_node_put(larbnode);
+			continue;
+		}
+
+		ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id);
+		if (ret)/* The id is consecutive if there is no this property */
+			id = i;
+
+		plarbdev = of_find_device_by_node(larbnode);
+		if (!plarbdev) {
+			of_node_put(larbnode);
+			return -EPROBE_DEFER;
+		}
+		data->larb_imu[id].dev = &plarbdev->dev;
+
+		component_match_add_release(dev, match, release_of,
+					    compare_of, larbnode);
+	}
+
+	/* Get smi-common dev from the last larb. */
+	smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
+	if (!smicomm_node)
+		return -EINVAL;
+
+	plarbdev = of_find_device_by_node(smicomm_node);
+	of_node_put(smicomm_node);
+	data->smicomm_dev = &plarbdev->dev;
+
+	link = device_link_add(data->smicomm_dev, dev,
+			       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+
+	if (!link) {
+		dev_err(dev, "Unable link %s.\n", dev_name(data->smicomm_dev));
+		return PTR_ERR(link);
+	}
+	return 0;
+}
+
 static int mtk_iommu_probe(struct platform_device *pdev)
 {
 	struct mtk_iommu_data   *data;
 	struct device           *dev = &pdev->dev;
-	struct device_node	*larbnode, *smicomm_node;
-	struct platform_device	*plarbdev;
-	struct device_link	*link;
 	struct resource         *res;
 	resource_size_t		ioaddr;
 	struct component_match  *match = NULL;
 	struct regmap		*infracfg;
 	void                    *protect;
-	int                     i, larb_nr, ret;
+	int                     ret;
 	u32			val;
 	char                    *p;
 
@@ -863,55 +923,12 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 			return PTR_ERR(data->bclk);
 	}
 
-	larb_nr = of_count_phandle_with_args(dev->of_node,
-					     "mediatek,larbs", NULL);
-	if (larb_nr < 0)
-		return larb_nr;
-
-	for (i = 0; i < larb_nr; i++) {
-		u32 id;
-
-		larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
-		if (!larbnode)
-			return -EINVAL;
-
-		if (!of_device_is_available(larbnode)) {
-			of_node_put(larbnode);
-			continue;
-		}
-
-		ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id);
-		if (ret)/* The id is consecutive if there is no this property */
-			id = i;
-
-		plarbdev = of_find_device_by_node(larbnode);
-		if (!plarbdev) {
-			of_node_put(larbnode);
-			return -EPROBE_DEFER;
-		}
-		data->larb_imu[id].dev = &plarbdev->dev;
-
-		component_match_add_release(dev, &match, release_of,
-					    compare_of, larbnode);
-	}
-
-	/* Get smi-common dev from the last larb. */
-	smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
-	if (!smicomm_node)
-		return -EINVAL;
-
-	plarbdev = of_find_device_by_node(smicomm_node);
-	of_node_put(smicomm_node);
-	data->smicomm_dev = &plarbdev->dev;
-
 	pm_runtime_enable(dev);
 
-	link = device_link_add(data->smicomm_dev, dev,
-			DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
-	if (!link) {
-		dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev));
-		ret = -EINVAL;
-		goto out_runtime_disable;
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+		ret = mtk_iommu_mm_dts_parse(dev, &match, data);
+		if (ret)
+			goto out_runtime_disable;
 	}
 
 	platform_set_drvdata(pdev, data);
@@ -942,9 +959,11 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 			goto out_list_del;
 	}
 
-	ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
-	if (ret)
-		goto out_bus_set_null;
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+		ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
+		if (ret)
+			goto out_bus_set_null;
+	}
 	return ret;
 
 out_bus_set_null:
@@ -955,7 +974,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 out_sysfs_remove:
 	iommu_device_sysfs_remove(&data->iommu);
 out_link_remove:
-	device_link_remove(data->smicomm_dev, dev);
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
+		device_link_remove(data->smicomm_dev, dev);
 out_runtime_disable:
 	pm_runtime_disable(dev);
 	return ret;
@@ -972,7 +992,8 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 		bus_set_iommu(&platform_bus_type, NULL);
 
 	clk_disable_unprepare(data->bclk);
-	device_link_remove(data->smicomm_dev, &pdev->dev);
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
+		device_link_remove(data->smicomm_dev, &pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	devm_free_irq(&pdev->dev, data->irq, data);
 	component_master_del(&pdev->dev, &mtk_iommu_com_ops);
@@ -1039,7 +1060,7 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = {
 static const struct mtk_iommu_plat_data mt2712_data = {
 	.m4u_plat     = M4U_MT2712,
 	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE |
-			NOT_STD_AXI_MODE,
+			NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
 	.hw_list      = &m4ulist,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
@@ -1050,7 +1071,7 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 static const struct mtk_iommu_plat_data mt6779_data = {
 	.m4u_plat      = M4U_MT6779,
 	.flags         = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN |
-			 NOT_STD_AXI_MODE,
+			 NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
 	.iova_region   = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1059,7 +1080,8 @@ static const struct mtk_iommu_plat_data mt6779_data = {
 
 static const struct mtk_iommu_plat_data mt8167_data = {
 	.m4u_plat     = M4U_MT8167,
-	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
+	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
+			MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1069,7 +1091,8 @@ static const struct mtk_iommu_plat_data mt8167_data = {
 static const struct mtk_iommu_plat_data mt8173_data = {
 	.m4u_plat     = M4U_MT8173,
 	.flags	      = HAS_4GB_MODE | HAS_BCLK | RESET_AXI |
-			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
+			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
+			MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1078,7 +1101,7 @@ static const struct mtk_iommu_plat_data mt8173_data = {
 
 static const struct mtk_iommu_plat_data mt8183_data = {
 	.m4u_plat     = M4U_MT8183,
-	.flags        = RESET_AXI,
+	.flags        = RESET_AXI | MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1088,7 +1111,8 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 static const struct mtk_iommu_plat_data mt8192_data = {
 	.m4u_plat       = M4U_MT8192,
 	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
-			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE,
+			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE |
+			  MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
 	.iova_region    = mt8192_multi_dom,
 	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:23 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:23 +0800
Subject: [PATCH v2 28/29] iommu/mediatek: Backup/restore regsiters for multi
 banks
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-29-yong.wu@mediatek.com>

Each bank has some independent registers. thus backup/restore them for
each a bank when suspend and resume.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 39 +++++++++++++++++++++++++++------------
 drivers/iommu/mtk_iommu.h | 14 +++++++++++---
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 142ee8f3a560..3d474eedce3e 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1135,16 +1135,23 @@ static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
 	struct mtk_iommu_suspend_reg *reg = &data->reg;
-	void __iomem *base = data->bank[0].base;
+	void __iomem *base;
+	int i = 0;
 
+	base = data->bank[i].base;
 	reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL);
 	reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL);
 	reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM_DIS);
 	reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG);
-	reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0);
-	reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
-	reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR);
 	reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG);
+	do {
+		if (!data->plat_data->bank_enable[i])
+			continue;
+		base = data->bank[i].base;
+		reg->int_control[i] = readl_relaxed(base + REG_MMU_INT_CONTROL0);
+		reg->int_main_control[i] = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
+		reg->ivrp_paddr[i] = readl_relaxed(base + REG_MMU_IVRP_PADDR);
+	} while (++i < data->plat_data->bank_nr);
 	clk_disable_unprepare(data->bclk);
 	return 0;
 }
@@ -1153,9 +1160,9 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
 	struct mtk_iommu_suspend_reg *reg = &data->reg;
-	struct mtk_iommu_domain *m4u_dom = data->bank[0].m4u_dom;
-	void __iomem *base = data->bank[0].base;
-	int ret;
+	struct mtk_iommu_domain *m4u_dom;
+	void __iomem *base;
+	int ret, i = 0;
 
 	ret = clk_prepare_enable(data->bclk);
 	if (ret) {
@@ -1167,18 +1174,26 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
 	 * Uppon first resume, only enable the clk and return, since the values of the
 	 * registers are not yet set.
 	 */
-	if (!m4u_dom)
+	if (!reg->wr_len_ctrl)
 		return 0;
 
+	base = data->bank[i].base;
 	writel_relaxed(reg->wr_len_ctrl, base + REG_MMU_WR_LEN_CTRL);
 	writel_relaxed(reg->misc_ctrl, base + REG_MMU_MISC_CTRL);
 	writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS);
 	writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG);
-	writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
-	writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
-	writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
 	writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG);
-	writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, base + REG_MMU_PT_BASE_ADDR);
+	do {
+		m4u_dom = data->bank[i].m4u_dom;
+		if (!data->plat_data->bank_enable[i] || !m4u_dom)
+			continue;
+		base = data->bank[i].base;
+		writel_relaxed(reg->int_control[i], base + REG_MMU_INT_CONTROL0);
+		writel_relaxed(reg->int_main_control[i], base + REG_MMU_INT_MAIN_CONTROL);
+		writel_relaxed(reg->ivrp_paddr[i], base + REG_MMU_IVRP_PADDR);
+		writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
+		       base + REG_MMU_PT_BASE_ADDR);
+	} while (++i < data->plat_data->bank_nr);
 	return 0;
 }
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 905d8740dbcf..279c6c3ee56f 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -33,11 +33,19 @@ struct mtk_iommu_suspend_reg {
 	};
 	u32				dcm_dis;
 	u32				ctrl_reg;
-	u32				int_control0;
-	u32				int_main_control;
-	u32				ivrp_paddr;
 	u32				vld_pa_rng;
 	u32				wr_len_ctrl;
+	union {
+		struct { /* only for gen1 */
+			u32		int_control0;
+		};
+
+		struct { /* only for gen2 that support multi-banks */
+			u32		int_control[MTK_IOMMU_BANK_MAX];
+			u32		int_main_control[MTK_IOMMU_BANK_MAX];
+			u32		ivrp_paddr[MTK_IOMMU_BANK_MAX];
+		};
+	};
 };
 
 enum mtk_iommu_plat {
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:22 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:22 +0800
Subject: [PATCH v2 27/29] iommu/mediatek: Initialise/Remove for multi bank dev
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-28-yong.wu@mediatek.com>

The registers for each bank of the IOMMU base are in order, delta is
0x1000. Initialise the base for each bank.

For all the previous SoC, we only have bank0. thus use "do {} while()"
to allow bank0 always go.

When removing the device, Not always all the banks are initialised, it
depend on if there is masters for some banks. thus, use a register to
confirm this.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 51 +++++++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index ce83569eec21..142ee8f3a560 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -113,6 +113,7 @@
 #define F_MMU_INT_ID_PORT_ID(a)			(((a) >> 2) & 0x1f)
 
 #define MTK_PROTECT_PA_ALIGN			256
+#define MTK_IOMMU_BANK_SZ			0x1000
 
 #define PERICFG_IOMMU_1				0x714
 
@@ -945,11 +946,11 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	struct mtk_iommu_data   *data;
 	struct device           *dev = &pdev->dev;
 	struct resource         *res;
-	resource_size_t		ioaddr;
+	resource_size_t		ioaddr, size;
 	struct component_match  *match = NULL;
 	struct regmap		*infracfg;
 	void                    *protect;
-	int                     ret;
+	int                     ret, i = 0;
 	u32			val;
 	char                    *p;
 	struct mtk_iommu_bank_data *bank;
@@ -991,20 +992,31 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	size = resource_size(res);
+	if (size < data->plat_data->bank_nr * MTK_IOMMU_BANK_SZ) {
+		dev_err(dev, "banknr %d. res %pR is not enough.\n",
+			data->plat_data->bank_nr, res);
+		return -EINVAL;
+	}
 	base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 	ioaddr = res->start;
 
-	bank = &data->bank[0];
-	bank->id = 0;
-	bank->base = base;
-	bank->irq = platform_get_irq(pdev, 0);
-	if (bank->irq < 0)
-		return bank->irq;
-	bank->pdev = dev;
-	bank->pdata = data;
-	spin_lock_init(&bank->tlb_lock);
+	do {
+		if (!data->plat_data->bank_enable[i])
+			continue;
+		bank = &data->bank[i];
+		bank->id = i;
+		bank->base = base + i * MTK_IOMMU_BANK_SZ;
+
+		bank->irq = platform_get_irq(pdev, i);
+		if (bank->irq < 0)
+			return bank->irq;
+		bank->pdev = dev;
+		bank->pdata = data;
+		spin_lock_init(&bank->tlb_lock);
+	} while (++i < data->plat_data->bank_nr);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) {
 		data->bclk = devm_clk_get(dev, "bclk");
@@ -1089,7 +1101,9 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 static int mtk_iommu_remove(struct platform_device *pdev)
 {
 	struct mtk_iommu_data *data = platform_get_drvdata(pdev);
-	struct mtk_iommu_bank_data *bank = &data->bank[0];
+	struct mtk_iommu_bank_data *bank;
+	bool bank_hwinit;
+	int i;
 
 	iommu_device_sysfs_remove(&data->iommu);
 	iommu_device_unregister(&data->iommu);
@@ -1101,7 +1115,18 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
 		device_link_remove(data->smicomm_dev, &pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	devm_free_irq(&pdev->dev, bank->irq, bank);
+	for (i = 0; i < data->plat_data->bank_nr; i++) {
+		bank = &data->bank[i];
+		/*
+		 * Use a register value to confirm if this bank HW is initialised.
+		 * If the bank has no consumer, the bank HW still won't be
+		 * initialised even though bank_enable is true.
+		 */
+		bank_hwinit = !!readl_relaxed(bank->base + REG_MMU_PT_BASE_ADDR);
+		if (!bank_hwinit)
+			continue;
+		devm_free_irq(&pdev->dev, bank->irq, bank);
+	}
 	component_master_del(&pdev->dev, &mtk_iommu_com_ops);
 	return 0;
 }
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:05 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:05 +0800
Subject: [PATCH v2 10/29] iommu/mediatek: Remove the granule in the tlb flush
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-11-yong.wu@mediatek.com>

The MediaTek IOMMU don't care about granule when tlb flushing.
Remove this variable.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index d64139ab59d0..add23a36a5e2 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -228,7 +228,6 @@ static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 }
 
 static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
-					   size_t granule,
 					   struct mtk_iommu_data *data)
 {
 	struct list_head *head = data->hw_list;
@@ -550,8 +549,7 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 	size_t length = gather->end - gather->start + 1;
 
-	mtk_iommu_tlb_flush_range_sync(gather->start, length, gather->pgsize,
-				       dom->data);
+	mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->data);
 }
 
 static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
@@ -559,7 +557,7 @@ static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
 {
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
-	mtk_iommu_tlb_flush_range_sync(iova, size, size, dom->data);
+	mtk_iommu_tlb_flush_range_sync(iova, size, dom->data);
 }
 
 static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:11 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:11 +0800
Subject: [PATCH v2 16/29] iommu/mediatek: Adjust device link when it is
 sub-common
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-17-yong.wu@mediatek.com>

For MM IOMMU, We always add device link between smi-common and IOMMU HW.
In mt8195, we add smi-sub-common. Thus, if the node is sub-common, we still
need find again to get smi-common, then do device link.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index a4479916ad33..a72241724adb 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -845,6 +845,17 @@ static int mtk_iommu_mm_dts_parse(struct device *dev,
 	if (!smicomm_node)
 		return -EINVAL;
 
+	/* Find smi-common again if this is smi-sub-common */
+	if (of_property_read_bool(smicomm_node, "mediatek,smi_sub_common")) {
+		of_node_put(smicomm_node); /* put the sub common */
+
+		smicomm_node = of_parse_phandle(smicomm_node, "mediatek,smi", 0);
+		if (!smicomm_node) {
+			dev_err(dev, "sub-comm has no common.\n");
+			return -EINVAL;
+		}
+	}
+
 	plarbdev = of_find_device_by_node(smicomm_node);
 	of_node_put(smicomm_node);
 	data->smicomm_dev = &plarbdev->dev;
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:14 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:14 +0800
Subject: [PATCH v2 19/29] iommu/mediatek: Add mt8195 support
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-20-yong.wu@mediatek.com>

mt8195 has 3 IOMMU, containing 2 MM IOMMUs, one is for vdo, the other
is for vpp. and 1 INFRA IOMMU.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 42 +++++++++++++++++++++++++++++++++++++++
 drivers/iommu/mtk_iommu.h |  1 +
 2 files changed, 43 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b7a31f3a1bcf..d7eec20f0476 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1168,6 +1168,45 @@ static const struct mtk_iommu_plat_data mt8192_data = {
 			   {0, 14, 16}, {0, 13, 18, 17}},
 };
 
+static const struct mtk_iommu_plat_data mt8195_data_infra = {
+	.m4u_plat	  = M4U_MT8195,
+	.flags            = WR_THROT_EN | DCM_DISABLE |
+			    MTK_IOMMU_TYPE_INFRA | IFA_IOMMU_PCIe_SUPPORT,
+	.pericfg_comp_str = "mediatek,mt8195-pericfg_ao",
+	.inv_sel_reg      = REG_MMU_INV_SEL_GEN2,
+	.iova_region      = single_domain,
+	.iova_region_nr   = ARRAY_SIZE(single_domain),
+};
+
+static const struct mtk_iommu_plat_data mt8195_data_vdo = {
+	.m4u_plat	= M4U_MT8195,
+	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
+			  WR_THROT_EN | NOT_STD_AXI_MODE | IOVA_34_EN |
+			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
+	.hw_list        = &m4ulist,
+	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.iova_region	= mt8192_multi_dom,
+	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
+	.larbid_remap   = {{2, 0}, {21}, {24}, {7}, {19}, {9, 10, 11},
+			   {13, 17, 15/* 17b */, 25}, {5}},
+};
+
+static const struct mtk_iommu_plat_data mt8195_data_vpp = {
+	.m4u_plat	= M4U_MT8195,
+	.flags          = HAS_BCLK | HAS_SUB_COMM_3BITS | OUT_ORDER_WR_EN |
+			  WR_THROT_EN | NOT_STD_AXI_MODE | IOVA_34_EN |
+			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
+	.hw_list        = &m4ulist,
+	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.iova_region	= mt8192_multi_dom,
+	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
+	.larbid_remap   = {{1}, {3}, {22, 0, 0, 0, 23}, {8},
+			   {20}, {12},
+			   /* 16: 16a; 29: 16b; 30: CCUtop0; 31: CCUtop1 */
+			   {14, 16, 29, 26, 30, 31, 18},
+			   {4, 0, 0, 0, 6}},
+};
+
 static const struct of_device_id mtk_iommu_of_ids[] = {
 	{ .compatible = "mediatek,mt2712-m4u", .data = &mt2712_data},
 	{ .compatible = "mediatek,mt6779-m4u", .data = &mt6779_data},
@@ -1175,6 +1214,9 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
 	{ .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
 	{ .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
 	{ .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data},
+	{ .compatible = "mediatek,mt8195-iommu-infra", .data = &mt8195_data_infra},
+	{ .compatible = "mediatek,mt8195-iommu-vdo",   .data = &mt8195_data_vdo},
+	{ .compatible = "mediatek,mt8195-iommu-vpp",   .data = &mt8195_data_vpp},
 	{}
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 676d306af046..e7ede1123624 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -46,6 +46,7 @@ enum mtk_iommu_plat {
 	M4U_MT8173,
 	M4U_MT8183,
 	M4U_MT8192,
+	M4U_MT8195,
 };
 
 struct mtk_iommu_iova_region;
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:07 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:07 +0800
Subject: [PATCH v2 12/29] iommu/mediatek: Always enable output PA over 32bits
 in isr
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-13-yong.wu@mediatek.com>

Currently the output PA[32:33] is contained by the flag IOVA_34.
This is not right. the iova_34 has no relation with pa[32:33], the 32bits
iova still could map to pa[32:33]. Move it out from the flag.

No need fix tag since currently only mt8192 use the calulation and it
always has this IOVA_34 flag.

Prepare for the IOMMU that still use IOVA 32bits but its dram size may be
over 4GB.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index abc721a1da21..a831e56a90eb 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -297,11 +297,11 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
 		va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
-		pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
 		fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
 		fault_iova |= (u64)va34_32 << 32;
-		fault_pa |= (u64)pa34_32 << 32;
 	}
+	pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
+	fault_pa |= (u64)pa34_32 << 32;
 
 	fault_port = F_MMU_INT_ID_PORT_ID(regval);
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:52:55 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:52:55 +0800
Subject: [PATCH v2 00/29] MT8195 IOMMU SUPPORT
Message-ID: <20210813065324.29220-1-yong.wu@mediatek.com>

This patchset add mt8195 iommu support.

mt8195 have 3 IOMMU HWs. 2 IOMMU HW is for multimedia, and 1 IOMMU HW is
for infra-master, like PCIe/USB.

About the 2 MM IOMMU HW, something like this:

        IOMMU(VDO)          IOMMU(VPP)
           |                   |
      SMI_COMMON(VDO)      SMI_COMMON(VPP)
      ---------------     ----------------
      |      |   ...      |      |     ...
    larb0 larb2  ...    larb1 larb3    ...

these two MM IOMMU HW share a pgtable.

About the INFRA IOMMU, it don't have larbs, the master connects the iommu
directly. It use a independent pgtable.

Also, mt8195 IOMMU bank supports.Normally the IOMMU register size only
is 0x1000. In this IOMMU HW, the register size is 5 * 0x1000. each 0x1000
is a bank. the banks' register look like this:
     ----------------------------------------
     |bank0  | bank1 | bank2 | bank3 | bank4|
     ----------------------------------------
     |global |
     |control|         null
     |regs   |
     -----------------------------------------
     |bank   |bank   |bank   |bank   |bank   |
     |regs   |regs   |regs   |regs   |regs   |
     |       |       |       |       |       |
     -----------------------------------------
All the banks share some global control registers, and each bank have its
special bank registers, like pgtable base register, tlb operation registers,
the fault status registers.
 
In mt8195, we enable this bank feature for infra iommu, We put PCIe in bank0
and USB in bank4. they have independent pgtable.

patch[1..19]:  support mt8195 iommu. 
patch[20..29]: support bank feature.

TODO: there is another APU_IOMMU in mt8195, this should depend on APU patches.
thus, we need add that feature after that.

Change note:
v2: 1) Base on v5.14-rc1.
    2) Fix build fail for arm32.
    3) Fix dt-binding issue from Rob.
    4) Fix the bank issue when tlb flush. v1 always use bank->base.
    5) Adjust devlink with smi-common since the node may be smi-sub-common.
    6) other changes: like reword some commit message(removing many
       "This patch..."); seperate serveral patches.

v1: https://lore.kernel.org/linux-mediatek/20210630023504.18177-1-yong.wu at mediatek.com/
    Base on v5.13-rc1.

Yong Wu (29):
  dt-bindings: mediatek: mt8195: Add binding for MM IOMMU
  dt-bindings: mediatek: mt8195: Add binding for infra IOMMU
  iommu/mediatek: Fix 2 HW sharing pgtable issue
  iommu/mediatek: Adapt sharing and non-sharing pgtable case
  iommu/mediatek: Add 12G~16G support for multi domains
  iommu/mediatek: Add a flag DCM_DISABLE
  iommu/mediatek: Add a flag NON_STD_AXI
  iommu/mediatek: Remove for_each_m4u in tlb_sync_all
  iommu/mediatek: Add tlb_lock in tlb_flush_all
  iommu/mediatek: Remove the granule in the tlb flush
  iommu/mediatek: Always pm_runtime_get while tlb flush
  iommu/mediatek: Always enable output PA over 32bits in isr
  iommu/mediatek: Add SUB_COMMON_3BITS flag
  iommu/mediatek: Add IOMMU_TYPE flag
  iommu/mediatek: Contain MM IOMMU flow with the MM TYPE
  iommu/mediatek: Adjust device link when it is sub-common
  iommu/mediatek: Add infra iommu support
  iommu/mediatek: Add PCIe support
  iommu/mediatek: Add mt8195 support
  iommu/mediatek: Only adjust code about register base
  iommu/mediatek: Just move code position in hw_init
  iommu/mediatek: Add mtk_iommu_bank_data structure
  iommu/mediatek: Initialise bank HW for each a bank
  iommu/mediatek: Add bank_nr and bank_enable
  iommu/mediatek: Change the domid to iova_region_id
  iommu/mediatek: Get the proper bankid for multi banks
  iommu/mediatek: Initialise/Remove for multi bank dev
  iommu/mediatek: Backup/restore regsiters for multi banks
  iommu/mediatek: mt8195: Enable multi banks for infra iommu

 .../bindings/iommu/mediatek,iommu.yaml        |  20 +-
 drivers/iommu/mtk_iommu.c                     | 792 ++++++++++++------
 drivers/iommu/mtk_iommu.h                     |  55 +-
 .../dt-bindings/memory/mt8195-memory-port.h   | 408 +++++++++
 include/dt-bindings/memory/mtk-memory-port.h  |   2 +
 5 files changed, 1010 insertions(+), 267 deletions(-)
 create mode 100644 include/dt-bindings/memory/mt8195-memory-port.h

-- 
2.18.0


From yong.wu at mediatek.com  Thu Aug 12 23:53:18 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:18 +0800
Subject: [PATCH v2 23/29] iommu/mediatek: Initialise bank HW for each a bank
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-24-yong.wu@mediatek.com>

The mt8195 IOMMU HW max support 5 banks, and regarding the banks'
registers, it looks like:

 ----------------------------------------
 |bank0  | bank1 | bank2 | bank3 | bank4|
 ----------------------------------------
 |global |
 |control|         null
 |regs   |
 -----------------------------------------
 |bank   |bank   |bank   |bank   |bank   |
 |regs   |regs   |regs   |regs   |regs   |
 |       |       |       |       |       |
 -----------------------------------------

Each bank has some special bank registers and it share bank0's global
control registers. this patch initialise the bank hw with the bankid.

In the hw_init, we always initialise bank0's control register since
we don't know if the bank0 is initialised.

Additionally, About each bank's register base, always delta 0x1000.
like bank[x + 1] = bank[x] + 0x1000.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index c69a6f6dcc5a..cd86151c5181 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -153,7 +153,7 @@ struct mtk_iommu_domain {
 
 static const struct iommu_ops mtk_iommu_ops;
 
-static int mtk_iommu_hw_init(const struct mtk_iommu_data *data);
+static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int bankid);
 
 #define MTK_IOMMU_TLB_ADDR(iova) ({					\
 	dma_addr_t _addr = iova;					\
@@ -533,12 +533,12 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 		dom->bank = bank;
 	}
 
-	if (!bank->m4u_dom) { /* Initialize the M4U HW */
+	if (!bank->m4u_dom) { /* Initialize the M4U HW for each a BANK */
 		ret = pm_runtime_resume_and_get(m4udev);
 		if (ret < 0)
 			return ret;
 
-		ret = mtk_iommu_hw_init(data);
+		ret = mtk_iommu_hw_init(data, bankid);
 		if (ret) {
 			pm_runtime_put(m4udev);
 			return ret;
@@ -746,11 +746,16 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.owner		= THIS_MODULE,
 };
 
-static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
+static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int bankid)
 {
+	const struct mtk_iommu_bank_data *bankx = &data->bank[bankid];
 	const struct mtk_iommu_bank_data *bank0 = &data->bank[0];
 	u32 regval;
 
+	/*
+	 * Global control settings are in bank0. May re-init these global registers
+	 * since no sure if there is bank0 consumers.
+	 */
 	if (data->plat_data->m4u_plat == M4U_MT8173) {
 		regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
 			 F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173;
@@ -793,13 +798,14 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 	}
 	writel_relaxed(regval, bank0->base + REG_MMU_MISC_CTRL);
 
+	/* Independent settings for each bank */
 	regval = F_L2_MULIT_HIT_EN |
 		F_TABLE_WALK_FAULT_INT_EN |
 		F_PREETCH_FIFO_OVERFLOW_INT_EN |
 		F_MISS_FIFO_OVERFLOW_INT_EN |
 		F_PREFETCH_FIFO_ERR_INT_EN |
 		F_MISS_FIFO_ERR_INT_EN;
-	writel_relaxed(regval, bank0->base + REG_MMU_INT_CONTROL0);
+	writel_relaxed(regval, bankx->base + REG_MMU_INT_CONTROL0);
 
 	regval = F_INT_TRANSLATION_FAULT |
 		F_INT_MAIN_MULTI_HIT_FAULT |
@@ -808,19 +814,19 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		F_INT_TLB_MISS_FAULT |
 		F_INT_MISS_TRANSACTION_FIFO_FAULT |
 		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
-	writel_relaxed(regval, bank0->base + REG_MMU_INT_MAIN_CONTROL);
+	writel_relaxed(regval, bankx->base + REG_MMU_INT_MAIN_CONTROL);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
 		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
 	else
 		regval = lower_32_bits(data->protect_base) |
 			 upper_32_bits(data->protect_base);
-	writel_relaxed(regval, bank0->base + REG_MMU_IVRP_PADDR);
+	writel_relaxed(regval, bankx->base + REG_MMU_IVRP_PADDR);
 
-	if (devm_request_irq(bank0->pdev, bank0->irq, mtk_iommu_isr, 0,
-			     dev_name(bank0->pdev), (void *)bank0)) {
-		writel_relaxed(0, bank0->base + REG_MMU_PT_BASE_ADDR);
-		dev_err(bank0->pdev, "Failed @ IRQ-%d Request\n", bank0->irq);
+	if (devm_request_irq(bankx->pdev, bankx->irq, mtk_iommu_isr, 0,
+			     dev_name(bankx->pdev), (void *)bankx)) {
+		writel_relaxed(0, bankx->base + REG_MMU_PT_BASE_ADDR);
+		dev_err(bankx->pdev, "Failed @ IRQ-%d Request\n", bankx->irq);
 		return -ENODEV;
 	}
 
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:24 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:24 +0800
Subject: [PATCH v2 29/29] iommu/mediatek: mt8195: Enable multi banks for infra
 iommu
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-30-yong.wu@mediatek.com>

Enable the multi-bank functions for infra-iommu. We put PCIE in bank0
and USB in the last bank(bank4). and we don't use the other banks
currently, disable them.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 3d474eedce3e..5c4905e70362 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1283,8 +1283,11 @@ static const struct mtk_iommu_plat_data mt8195_data_infra = {
 	.flags            = WR_THROT_EN | DCM_DISABLE |
 			    MTK_IOMMU_TYPE_INFRA | IFA_IOMMU_PCIe_SUPPORT,
 	.pericfg_comp_str = "mediatek,mt8195-pericfg_ao",
-	.bank_nr	  = 1,
-	.bank_enable      = {true},
+	.bank_nr	  = 5,
+	.bank_enable      = {true, false, false, false, true},
+	.bank_portmsk     = {[0] = GENMASK(19, 16),     /* PCIe */
+			     [4] = GENMASK(31, 20),     /* USB */
+			    },
 	.inv_sel_reg      = REG_MMU_INV_SEL_GEN2,
 	.iova_region      = single_domain,
 	.iova_region_nr   = ARRAY_SIZE(single_domain),
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:02 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:02 +0800
Subject: [PATCH v2 07/29] iommu/mediatek: Add a flag NON_STD_AXI
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-8-yong.wu@mediatek.com>

Add a new flag NON_STD_AXI, All the previous SoC support this flag.
Prepare for adding infra and apu iommu which don't support this.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index bd50f3020bc1..175065b76509 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -123,6 +123,7 @@
 #define IOVA_34_EN			BIT(8)
 #define SHARE_PGTABLE			BIT(9) /* 2 HW share pgtable */
 #define DCM_DISABLE			BIT(10)
+#define NOT_STD_AXI_MODE		BIT(11)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -753,7 +754,8 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		regval = 0;
 	} else {
 		regval = readl_relaxed(data->base + REG_MMU_MISC_CTRL);
-		regval &= ~F_MMU_STANDARD_AXI_MODE_MASK;
+		if (MTK_IOMMU_HAS_FLAG(data->plat_data, NOT_STD_AXI_MODE))
+			regval &= ~F_MMU_STANDARD_AXI_MODE_MASK;
 		if (MTK_IOMMU_HAS_FLAG(data->plat_data, OUT_ORDER_WR_EN))
 			regval &= ~F_MMU_IN_ORDER_WR_EN_MASK;
 	}
@@ -1016,7 +1018,8 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = {
 
 static const struct mtk_iommu_plat_data mt2712_data = {
 	.m4u_plat     = M4U_MT2712,
-	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE,
+	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE |
+			NOT_STD_AXI_MODE,
 	.hw_list      = &m4ulist,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
@@ -1026,7 +1029,8 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 
 static const struct mtk_iommu_plat_data mt6779_data = {
 	.m4u_plat      = M4U_MT6779,
-	.flags         = HAS_SUB_COMM | OUT_ORDER_WR_EN | WR_THROT_EN,
+	.flags         = HAS_SUB_COMM | OUT_ORDER_WR_EN | WR_THROT_EN |
+			 NOT_STD_AXI_MODE,
 	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
 	.iova_region   = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1035,7 +1039,7 @@ static const struct mtk_iommu_plat_data mt6779_data = {
 
 static const struct mtk_iommu_plat_data mt8167_data = {
 	.m4u_plat     = M4U_MT8167,
-	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR,
+	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1045,7 +1049,7 @@ static const struct mtk_iommu_plat_data mt8167_data = {
 static const struct mtk_iommu_plat_data mt8173_data = {
 	.m4u_plat     = M4U_MT8173,
 	.flags	      = HAS_4GB_MODE | HAS_BCLK | RESET_AXI |
-			HAS_LEGACY_IVRP_PADDR,
+			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1064,7 +1068,7 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 static const struct mtk_iommu_plat_data mt8192_data = {
 	.m4u_plat       = M4U_MT8192,
 	.flags          = HAS_BCLK | HAS_SUB_COMM | OUT_ORDER_WR_EN |
-			  WR_THROT_EN | IOVA_34_EN,
+			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
 	.iova_region    = mt8192_multi_dom,
 	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:52:58 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:52:58 +0800
Subject: [PATCH v2 03/29] iommu/mediatek: Fix 2 HW sharing pgtable issue
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-4-yong.wu@mediatek.com>

In the commit 4f956c97d26b ("iommu/mediatek: Move domain_finalise into
attach_device"), I overlooked the sharing pgtable case.
After that commit, the "data" in the mtk_iommu_domain_finalise always is
the data of the current IOMMU HW. Fix this for the sharing pgtable case.

Only affect mt2712 which is the only SoC that share pgtable currently.

Fixes: 4f956c97d26b ("iommu/mediatek: Move domain_finalise into attach_device")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6f7c69688ce2..2fd2a3ae88f0 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -458,7 +458,7 @@ static void mtk_iommu_domain_free(struct iommu_domain *domain)
 static int mtk_iommu_attach_device(struct iommu_domain *domain,
 				   struct device *dev)
 {
-	struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
+	struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata;
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 	struct device *m4udev = data->dev;
 	int ret, domid;
@@ -468,7 +468,10 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 		return domid;
 
 	if (!dom->data) {
-		if (mtk_iommu_domain_finalise(dom, data, domid))
+		/* Data is in the frstdata in sharing pgtable case. */
+		frstdata = mtk_iommu_get_m4u_data();
+
+		if (mtk_iommu_domain_finalise(dom, frstdata, domid))
 			return -ENODEV;
 		dom->data = data;
 	}
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:03 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:03 +0800
Subject: [PATCH v2 08/29] iommu/mediatek: Remove for_each_m4u in tlb_sync_all
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-9-yong.wu@mediatek.com>

The tlb_sync_all is called from these three functions:
a) flush_iotlb_all: it will be called for each a iommu HW.
b) tlb_flush_range_sync: it already has for_each_m4u.
c) in irq: some IOMMU HW translation fault, Only need flush itself.

Thus, No need for_each_m4u in this tlb_sync_all. Remove it.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 175065b76509..1e18fff76e61 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -207,19 +207,15 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
 
 static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 {
-	struct list_head *head = data->hw_list;
-
-	for_each_m4u(data, head) {
-		if (pm_runtime_get_if_in_use(data->dev) <= 0)
-			continue;
+	if (pm_runtime_get_if_in_use(data->dev) <= 0)
+		return;
 
-		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
-			       data->base + data->plat_data->inv_sel_reg);
-		writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
-		wmb(); /* Make sure the tlb flush all done */
+	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
+		       data->base + data->plat_data->inv_sel_reg);
+	writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
+	wmb(); /* Make sure the tlb flush all done */
 
-		pm_runtime_put(data->dev);
-	}
+	pm_runtime_put(data->dev);
 }
 
 static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:21 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:21 +0800
Subject: [PATCH v2 26/29] iommu/mediatek: Get the proper bankid for multi banks
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-27-yong.wu@mediatek.com>

We preassign some ports in a special bank via the new defined
bank_portmsk. Put it in the plat_data means it is not expected to be
adjusted dynamically.

If the iommu id in the iommu consumer's dtsi node is inside this
bank_portmsk, then we switch it to this special iommu bank, and initialise
the IOMMU bank HW.

Each a bank has the independent pgtable(4GB iova range). Each a bank
is a independent iommu domain/group. Currently we don't separate different
iova ranges inside a bank.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 38 +++++++++++++++++++++++++++++++++++---
 drivers/iommu/mtk_iommu.h |  1 +
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 29b9ab528774..ce83569eec21 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -358,6 +358,30 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static unsigned int mtk_iommu_get_bank_id(struct device *dev,
+					  const struct mtk_iommu_plat_data *plat_data)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	unsigned int i, portmsk = 0, bankid = 0; /* bank default is 0 */
+
+	if (plat_data->bank_nr == 1)
+		return bankid;
+
+	for (i = 0; i < fwspec->num_ids; i++)
+		portmsk |= BIT(MTK_M4U_TO_PORT(fwspec->ids[i]));
+
+	for (i = 0; i < plat_data->bank_nr; i++) {
+		if (!plat_data->bank_enable[i])
+			continue;
+
+		if (portmsk & plat_data->bank_portmsk[i]) {
+			bankid = i;
+			break;
+		}
+	}
+	return bankid;
+}
+
 static int mtk_iommu_get_iova_region_id(struct device *dev,
 					const struct mtk_iommu_plat_data *plat_data)
 {
@@ -516,13 +540,14 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	struct list_head *hw_list = data->hw_list;
 	struct mtk_iommu_bank_data *bank;
 	struct device *m4udev = data->dev;
-	unsigned int bankid = 0;
+	unsigned int bankid;
 	int ret, region_id;
 
 	region_id = mtk_iommu_get_iova_region_id(dev, data->plat_data);
 	if (region_id < 0)
 		return region_id;
 
+	bankid = mtk_iommu_get_bank_id(dev, data->plat_data);
 	bank = &data->bank[bankid];
 	if (!dom->bank) {
 		/* Data is in the frstdata in sharing pgtable case. */
@@ -653,6 +678,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	struct mtk_iommu_data *c_data = dev_iommu_priv_get(dev), *data;
 	struct list_head *hw_list = c_data->hw_list;
 	struct iommu_group *group;
+	unsigned int bankid, groupid;
 	int regionid;
 
 	data = mtk_iommu_get_frst_data(hw_list);
@@ -662,12 +688,18 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	regionid = mtk_iommu_get_iova_region_id(dev, data->plat_data);
 	if (regionid < 0)
 		return ERR_PTR(regionid);
+	bankid = mtk_iommu_get_bank_id(dev, data->plat_data);
 
-	group = data->m4u_group[regionid];
+	/*
+	 * If the bank function is enabled, each a bank is a iommu group/domain.
+	 * otherwise, each a iova region is a iommu group/domain.
+	 */
+	groupid = bankid ? bankid : regionid;
+	group = data->m4u_group[groupid];
 	if (!group) {
 		group = iommu_group_alloc();
 		if (!IS_ERR(group))
-			data->m4u_group[regionid] = group;
+			data->m4u_group[groupid] = group;
 	} else {
 		iommu_group_ref_get(group);
 	}
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 7a8d6a233d14..905d8740dbcf 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -65,6 +65,7 @@ struct mtk_iommu_plat_data {
 
 	unsigned int        bank_nr;
 	bool                bank_enable[MTK_IOMMU_BANK_MAX];
+	unsigned int        bank_portmsk[MTK_IOMMU_BANK_MAX];
 	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
 };
 
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:19 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:19 +0800
Subject: [PATCH v2 24/29] iommu/mediatek: Add bank_nr and bank_enable
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-25-yong.wu@mediatek.com>

Prepare for supporting multi banks, Adds two variables in the plat_data:
bank_nr: the bank number that this SoC support;
bank_enable: list if the banks is enabled.

Add them for all the current SoC, bank_nr always is 1 and only
bank_enable[0] is enabled.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 18 ++++++++++++++++++
 drivers/iommu/mtk_iommu.h |  3 +++
 2 files changed, 21 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index cd86151c5181..5b9891b2be6c 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1137,6 +1137,8 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 			NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
 	.hw_list      = &m4ulist,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+	.bank_nr      = 1,
+	.bank_enable  = {true},
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}},
@@ -1147,6 +1149,8 @@ static const struct mtk_iommu_plat_data mt6779_data = {
 	.flags         = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN |
 			 NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
+	.bank_nr       = 1,
+	.bank_enable   = {true},
 	.iova_region   = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap  = {{0}, {1}, {2}, {3}, {5}, {7, 8}, {10}, {9}},
@@ -1157,6 +1161,8 @@ static const struct mtk_iommu_plat_data mt8167_data = {
 	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
 			MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+	.bank_nr      = 1,
+	.bank_enable  = {true},
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap = {{0}, {1}, {2}}, /* Linear mapping. */
@@ -1168,6 +1174,8 @@ static const struct mtk_iommu_plat_data mt8173_data = {
 			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
 			MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+	.bank_nr      = 1,
+	.bank_enable  = {true},
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}}, /* Linear mapping. */
@@ -1177,6 +1185,8 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 	.m4u_plat     = M4U_MT8183,
 	.flags        = RESET_AXI | MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+	.bank_nr      = 1,
+	.bank_enable  = {true},
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}},
@@ -1188,6 +1198,8 @@ static const struct mtk_iommu_plat_data mt8192_data = {
 			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE |
 			  MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.bank_nr        = 1,
+	.bank_enable    = {true},
 	.iova_region    = mt8192_multi_dom,
 	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
 	.larbid_remap   = {{0}, {1}, {4, 5}, {7}, {2}, {9, 11, 19, 20},
@@ -1199,6 +1211,8 @@ static const struct mtk_iommu_plat_data mt8195_data_infra = {
 	.flags            = WR_THROT_EN | DCM_DISABLE |
 			    MTK_IOMMU_TYPE_INFRA | IFA_IOMMU_PCIe_SUPPORT,
 	.pericfg_comp_str = "mediatek,mt8195-pericfg_ao",
+	.bank_nr	  = 1,
+	.bank_enable      = {true},
 	.inv_sel_reg      = REG_MMU_INV_SEL_GEN2,
 	.iova_region      = single_domain,
 	.iova_region_nr   = ARRAY_SIZE(single_domain),
@@ -1211,6 +1225,8 @@ static const struct mtk_iommu_plat_data mt8195_data_vdo = {
 			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
 	.hw_list        = &m4ulist,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.bank_nr	= 1,
+	.bank_enable    = {true},
 	.iova_region	= mt8192_multi_dom,
 	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
 	.larbid_remap   = {{2, 0}, {21}, {24}, {7}, {19}, {9, 10, 11},
@@ -1224,6 +1240,8 @@ static const struct mtk_iommu_plat_data mt8195_data_vpp = {
 			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
 	.hw_list        = &m4ulist,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.bank_nr	= 1,
+	.bank_enable    = {true},
 	.iova_region	= mt8192_multi_dom,
 	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
 	.larbid_remap   = {{1}, {3}, {22, 0, 0, 0, 23}, {8},
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 80dc08468eda..7a8d6a233d14 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -62,6 +62,9 @@ struct mtk_iommu_plat_data {
 	struct list_head			*hw_list;
 	unsigned int				iova_region_nr;
 	const struct mtk_iommu_iova_region	*iova_region;
+
+	unsigned int        bank_nr;
+	bool                bank_enable[MTK_IOMMU_BANK_MAX];
 	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
 };
 
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:09 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:09 +0800
Subject: [PATCH v2 14/29] iommu/mediatek: Add IOMMU_TYPE flag
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-15-yong.wu@mediatek.com>

Add IOMMU_TYPE definition. In the mt8195, we have another IOMMU_TYPE:
infra iommu, also there will be another APU_IOMMU, thus, use 2bits for the
IOMMU_TYPE.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index f75fbfd951e0..20d15f80dd6e 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -127,9 +127,17 @@
 #define SHARE_PGTABLE			BIT(10) /* 2 HW share pgtable */
 #define DCM_DISABLE			BIT(11)
 #define NOT_STD_AXI_MODE		BIT(12)
+/* 2 bits: iommu type */
+#define MTK_IOMMU_TYPE_MM		(0x0 << 13)
+#define MTK_IOMMU_TYPE_INFRA		(0x1 << 13)
+#define MTK_IOMMU_TYPE_MASK		(0x3 << 13)
 
-#define MTK_IOMMU_HAS_FLAG(pdata, _x) \
-		((((pdata)->flags) & (_x)) == (_x))
+#define MTK_IOMMU_HAS_FLAG(pdata, _x)	(!!(((pdata)->flags) & (_x)))
+
+#define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask)	\
+				((((pdata)->flags) & (mask)) == (_x))
+#define MTK_IOMMU_IS_TYPE(pdata, _x)	MTK_IOMMU_HAS_FLAG_MASK(pdata, _x,\
+							MTK_IOMMU_TYPE_MASK)
 
 struct mtk_iommu_domain {
 	struct io_pgtable_cfg		cfg;
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:08 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:08 +0800
Subject: [PATCH v2 13/29] iommu/mediatek: Add SUB_COMMON_3BITS flag
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-14-yong.wu@mediatek.com>

In prevous SoC, the sub common id occupy 2 bits. the mt8195's sub common
id has 3bits. Add a new flag for this. and rename the prevous flag to
_2BITS. For readable, I put these two flags together, then move the
other flags. no functional change.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 26 ++++++++++++++++----------
 drivers/iommu/mtk_iommu.h |  2 +-
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index a831e56a90eb..f75fbfd951e0 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -106,6 +106,8 @@
 #define REG_MMU1_INT_ID				0x154
 #define F_MMU_INT_ID_COMM_ID(a)			(((a) >> 9) & 0x7)
 #define F_MMU_INT_ID_SUB_COMM_ID(a)		(((a) >> 7) & 0x3)
+#define F_MMU_INT_ID_COMM_ID_EXT(a)		(((a) >> 10) & 0x7)
+#define F_MMU_INT_ID_SUB_COMM_ID_EXT(a)		(((a) >> 7) & 0x7)
 #define F_MMU_INT_ID_LARB_ID(a)			(((a) >> 7) & 0x7)
 #define F_MMU_INT_ID_PORT_ID(a)			(((a) >> 2) & 0x1f)
 
@@ -117,13 +119,14 @@
 #define HAS_VLD_PA_RNG			BIT(2)
 #define RESET_AXI			BIT(3)
 #define OUT_ORDER_WR_EN			BIT(4)
-#define HAS_SUB_COMM			BIT(5)
-#define WR_THROT_EN			BIT(6)
-#define HAS_LEGACY_IVRP_PADDR		BIT(7)
-#define IOVA_34_EN			BIT(8)
-#define SHARE_PGTABLE			BIT(9) /* 2 HW share pgtable */
-#define DCM_DISABLE			BIT(10)
-#define NOT_STD_AXI_MODE		BIT(11)
+#define HAS_SUB_COMM_2BITS		BIT(5)
+#define HAS_SUB_COMM_3BITS		BIT(6)
+#define WR_THROT_EN			BIT(7)
+#define HAS_LEGACY_IVRP_PADDR		BIT(8)
+#define IOVA_34_EN			BIT(9)
+#define SHARE_PGTABLE			BIT(10) /* 2 HW share pgtable */
+#define DCM_DISABLE			BIT(11)
+#define NOT_STD_AXI_MODE		BIT(12)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -304,9 +307,12 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	fault_pa |= (u64)pa34_32 << 32;
 
 	fault_port = F_MMU_INT_ID_PORT_ID(regval);
-	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
 		fault_larb = F_MMU_INT_ID_COMM_ID(regval);
 		sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
+	} else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
+		fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
+		sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
 	} else {
 		fault_larb = F_MMU_INT_ID_LARB_ID(regval);
 	}
@@ -1035,7 +1041,7 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 
 static const struct mtk_iommu_plat_data mt6779_data = {
 	.m4u_plat      = M4U_MT6779,
-	.flags         = HAS_SUB_COMM | OUT_ORDER_WR_EN | WR_THROT_EN |
+	.flags         = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN |
 			 NOT_STD_AXI_MODE,
 	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
 	.iova_region   = single_domain,
@@ -1073,7 +1079,7 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 
 static const struct mtk_iommu_plat_data mt8192_data = {
 	.m4u_plat       = M4U_MT8192,
-	.flags          = HAS_BCLK | HAS_SUB_COMM | OUT_ORDER_WR_EN |
+	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
 			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
 	.iova_region    = mt8192_multi_dom,
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 027a42396557..5b32277fee99 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -20,7 +20,7 @@
 #include <dt-bindings/memory/mtk-memory-port.h>
 
 #define MTK_LARB_COM_MAX	8
-#define MTK_LARB_SUBCOM_MAX	4
+#define MTK_LARB_SUBCOM_MAX	8
 
 #define MTK_IOMMU_GROUP_MAX	8
 
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:01 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:01 +0800
Subject: [PATCH v2 06/29] iommu/mediatek: Add a flag DCM_DISABLE
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-7-yong.wu@mediatek.com>

In the infra iommu, we should disable DCM. add a new flag for this.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 259ff7b90ff3..bd50f3020bc1 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -52,6 +52,8 @@
 #define F_MMU_STANDARD_AXI_MODE_MASK		(BIT(3) | BIT(19))
 
 #define REG_MMU_DCM_DIS				0x050
+#define F_MMU_DCM				BIT(8)
+
 #define REG_MMU_WR_LEN_CTRL			0x054
 #define F_MMU_WR_THROT_DIS_MASK			(BIT(5) | BIT(21))
 
@@ -120,6 +122,7 @@
 #define HAS_LEGACY_IVRP_PADDR		BIT(7)
 #define IOVA_34_EN			BIT(8)
 #define SHARE_PGTABLE			BIT(9) /* 2 HW share pgtable */
+#define DCM_DISABLE			BIT(10)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -733,7 +736,11 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		regval = F_MMU_VLD_PA_RNG(7, 4);
 		writel_relaxed(regval, data->base + REG_MMU_VLD_PA_RNG);
 	}
-	writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, DCM_DISABLE))
+		writel_relaxed(F_MMU_DCM, data->base + REG_MMU_DCM_DIS);
+	else
+		writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
+
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) {
 		/* write command throttling mode */
 		regval = readl_relaxed(data->base + REG_MMU_WR_LEN_CTRL);
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:20 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:20 +0800
Subject: [PATCH v2 25/29] iommu/mediatek: Change the domid to iova_region_id
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-26-yong.wu@mediatek.com>

Prepare for adding bankid, also no functional change.

In the previous SoC, each a iova_region is a domain; In the multi-banks
case, each a bank is a domain; then the original function name
"mtk_iommu_get_domain_id" is not proper. the name "iova_region_id"
should be proper. this patch only rename the domid to iova_region_id.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 46 +++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 5b9891b2be6c..29b9ab528774 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -358,8 +358,8 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int mtk_iommu_get_domain_id(struct device *dev,
-				   const struct mtk_iommu_plat_data *plat_data)
+static int mtk_iommu_get_iova_region_id(struct device *dev,
+					const struct mtk_iommu_plat_data *plat_data)
 {
 	const struct mtk_iommu_iova_region *rgn = plat_data->iova_region;
 	const struct bus_dma_region *dma_rgn = dev->dma_range_map;
@@ -389,7 +389,7 @@ static int mtk_iommu_get_domain_id(struct device *dev,
 }
 
 static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
-			    bool enable, unsigned int domid)
+			    bool enable, unsigned int regionid)
 {
 	struct mtk_smi_larb_iommu    *larb_mmu;
 	unsigned int                 larbid, portid;
@@ -405,12 +405,12 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 		if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
 			larb_mmu = &data->larb_imu[larbid];
 
-			region = data->plat_data->iova_region + domid;
+			region = data->plat_data->iova_region + regionid;
 			larb_mmu->bank[portid] = upper_32_bits(region->iova_base);
 
-			dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n",
+			dev_dbg(dev, "%s iommu for larb(%s) port %d region %d rgn-bank %d.\n",
 				enable ? "enable" : "disable", dev_name(larb_mmu->dev),
-				portid, domid, larb_mmu->bank[portid]);
+				portid, regionid, larb_mmu->bank[portid]);
 
 			if (enable)
 				larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
@@ -437,7 +437,7 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 
 static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
 				     struct mtk_iommu_data *data,
-				     unsigned int domid)
+				     unsigned int region_id)
 {
 	const struct mtk_iommu_iova_region *region;
 	struct mtk_iommu_domain	*m4u_dom;
@@ -476,7 +476,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
 
 update_iova_region:
 	/* Update the iova region for this domain */
-	region = data->plat_data->iova_region + domid;
+	region = data->plat_data->iova_region + region_id;
 	dom->domain.geometry.aperture_start = region->iova_base;
 	dom->domain.geometry.aperture_end = region->iova_base + region->size - 1;
 	dom->domain.geometry.force_aperture = true;
@@ -517,18 +517,18 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	struct mtk_iommu_bank_data *bank;
 	struct device *m4udev = data->dev;
 	unsigned int bankid = 0;
-	int ret, domid;
+	int ret, region_id;
 
-	domid = mtk_iommu_get_domain_id(dev, data->plat_data);
-	if (domid < 0)
-		return domid;
+	region_id = mtk_iommu_get_iova_region_id(dev, data->plat_data);
+	if (region_id < 0)
+		return region_id;
 
 	bank = &data->bank[bankid];
 	if (!dom->bank) {
 		/* Data is in the frstdata in sharing pgtable case. */
 		frstdata = mtk_iommu_get_frst_data(hw_list);
 
-		if (mtk_iommu_domain_finalise(dom, frstdata, domid))
+		if (mtk_iommu_domain_finalise(dom, frstdata, region_id))
 			return -ENODEV;
 		dom->bank = bank;
 	}
@@ -550,7 +550,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 		pm_runtime_put(m4udev);
 	}
 
-	return mtk_iommu_config(data, dev, true, domid);
+	return mtk_iommu_config(data, dev, true, region_id);
 }
 
 static void mtk_iommu_detach_device(struct iommu_domain *domain,
@@ -653,21 +653,21 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	struct mtk_iommu_data *c_data = dev_iommu_priv_get(dev), *data;
 	struct list_head *hw_list = c_data->hw_list;
 	struct iommu_group *group;
-	int domid;
+	int regionid;
 
 	data = mtk_iommu_get_frst_data(hw_list);
 	if (!data)
 		return ERR_PTR(-ENODEV);
 
-	domid = mtk_iommu_get_domain_id(dev, data->plat_data);
-	if (domid < 0)
-		return ERR_PTR(domid);
+	regionid = mtk_iommu_get_iova_region_id(dev, data->plat_data);
+	if (regionid < 0)
+		return ERR_PTR(regionid);
 
-	group = data->m4u_group[domid];
+	group = data->m4u_group[regionid];
 	if (!group) {
 		group = iommu_group_alloc();
 		if (!IS_ERR(group))
-			data->m4u_group[domid] = group;
+			data->m4u_group[regionid] = group;
 	} else {
 		iommu_group_ref_get(group);
 	}
@@ -700,14 +700,14 @@ static void mtk_iommu_get_resv_regions(struct device *dev,
 				       struct list_head *head)
 {
 	struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
-	unsigned int domid = mtk_iommu_get_domain_id(dev, data->plat_data), i;
+	unsigned int regionid = mtk_iommu_get_iova_region_id(dev, data->plat_data), i;
 	const struct mtk_iommu_iova_region *resv, *curdom;
 	struct iommu_resv_region *region;
 	int prot = IOMMU_WRITE | IOMMU_READ;
 
-	if ((int)domid < 0)
+	if ((int)regionid < 0)
 		return;
-	curdom = data->plat_data->iova_region + domid;
+	curdom = data->plat_data->iova_region + regionid;
 	for (i = 0; i < data->plat_data->iova_region_nr; i++) {
 		resv = data->plat_data->iova_region + i;
 
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:16 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:16 +0800
Subject: [PATCH v2 21/29] iommu/mediatek: Just move code position in hw_init
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-22-yong.wu@mediatek.com>

No functional change too. mt8195 IOMMU support bank functions.
some global control settings are in bank0. and the other banks have
their bank independent setting. Here only move the global control
settings and the independent registers together.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 48 +++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 48162e156486..26ac7c4cc3fe 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -750,30 +750,6 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 	}
 	writel_relaxed(regval, data->base + REG_MMU_CTRL_REG);
 
-	regval = F_L2_MULIT_HIT_EN |
-		F_TABLE_WALK_FAULT_INT_EN |
-		F_PREETCH_FIFO_OVERFLOW_INT_EN |
-		F_MISS_FIFO_OVERFLOW_INT_EN |
-		F_PREFETCH_FIFO_ERR_INT_EN |
-		F_MISS_FIFO_ERR_INT_EN;
-	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
-
-	regval = F_INT_TRANSLATION_FAULT |
-		F_INT_MAIN_MULTI_HIT_FAULT |
-		F_INT_INVALID_PA_FAULT |
-		F_INT_ENTRY_REPLACEMENT_FAULT |
-		F_INT_TLB_MISS_FAULT |
-		F_INT_MISS_TRANSACTION_FIFO_FAULT |
-		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
-	writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
-
-	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
-		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
-	else
-		regval = lower_32_bits(data->protect_base) |
-			 upper_32_bits(data->protect_base);
-	writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
-
 	if (data->enable_4GB &&
 	    MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_VLD_PA_RNG)) {
 		/*
@@ -807,6 +783,30 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 	}
 	writel_relaxed(regval, data->base + REG_MMU_MISC_CTRL);
 
+	regval = F_L2_MULIT_HIT_EN |
+		F_TABLE_WALK_FAULT_INT_EN |
+		F_PREETCH_FIFO_OVERFLOW_INT_EN |
+		F_MISS_FIFO_OVERFLOW_INT_EN |
+		F_PREFETCH_FIFO_ERR_INT_EN |
+		F_MISS_FIFO_ERR_INT_EN;
+	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
+
+	regval = F_INT_TRANSLATION_FAULT |
+		F_INT_MAIN_MULTI_HIT_FAULT |
+		F_INT_INVALID_PA_FAULT |
+		F_INT_ENTRY_REPLACEMENT_FAULT |
+		F_INT_TLB_MISS_FAULT |
+		F_INT_MISS_TRANSACTION_FIFO_FAULT |
+		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
+	writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
+
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
+		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
+	else
+		regval = lower_32_bits(data->protect_base) |
+			 upper_32_bits(data->protect_base);
+	writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
+
 	if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
 			     dev_name(data->dev), (void *)data)) {
 		writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR);
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:53:12 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:53:12 +0800
Subject: [PATCH v2 17/29] iommu/mediatek: Add infra iommu support
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-18-yong.wu@mediatek.com>

The infra iommu enable bits in mt8195 is in the pericfg register segment,
use regmap to update it.

If infra iommu master translation fault, It don't have the larbid/portid,
thus print out the whole register value.

Since regmap_update_bits may fail, add return value for mtk_iommu_config.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 36 +++++++++++++++++++++++++++++-------
 drivers/iommu/mtk_iommu.h |  3 +++
 2 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index a72241724adb..45b34f4e99fb 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -113,6 +113,8 @@
 
 #define MTK_PROTECT_PA_ALIGN			256
 
+#define PERICFG_IOMMU_1				0x714
+
 #define HAS_4GB_MODE			BIT(0)
 /* HW will use the EMI clock if there isn't the "bclk". */
 #define HAS_BCLK			BIT(1)
@@ -332,8 +334,8 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
 		dev_err_ratelimited(
 			data->dev,
-			"fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d layer=%d %s\n",
-			int_state, fault_iova, fault_pa, fault_larb, fault_port,
+			"fault type=0x%x iova=0x%llx pa=0x%llx master=0x%x(larb=%d port=%d) layer=%d %s\n",
+			int_state, fault_iova, fault_pa, regval, fault_larb, fault_port,
 			layer, write ? "write" : "read");
 	}
 
@@ -377,14 +379,15 @@ static int mtk_iommu_get_domain_id(struct device *dev,
 	return -EINVAL;
 }
 
-static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
-			     bool enable, unsigned int domid)
+static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
+			    bool enable, unsigned int domid)
 {
 	struct mtk_smi_larb_iommu    *larb_mmu;
 	unsigned int                 larbid, portid;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	const struct mtk_iommu_iova_region *region;
-	int i;
+	u32 peri_mmuen, peri_mmuen_msk;
+	int i, ret = 0;
 
 	for (i = 0; i < fwspec->num_ids; ++i) {
 		larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
@@ -404,8 +407,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 				larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
 			else
 				larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+		} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) {
+			peri_mmuen_msk = BIT(portid);
+			peri_mmuen = enable ? peri_mmuen_msk : 0;
+
+			ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1,
+						 peri_mmuen_msk, peri_mmuen);
+			if (ret)
+				dev_err(dev, "%s iommu(%s) inframaster 0x%x fail(%d).\n",
+					enable ? "enable" : "disable",
+					dev_name(data->dev), peri_mmuen_msk, ret);
 		}
 	}
+	return ret;
 }
 
 static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
@@ -518,8 +532,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 		pm_runtime_put(m4udev);
 	}
 
-	mtk_iommu_config(data, dev, true, domid);
-	return 0;
+	return mtk_iommu_config(data, dev, true, domid);
 }
 
 static void mtk_iommu_detach_device(struct iommu_domain *domain,
@@ -940,6 +953,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		ret = mtk_iommu_mm_dts_parse(dev, &match, data);
 		if (ret)
 			goto out_runtime_disable;
+	} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
+		   data->plat_data->pericfg_comp_str) {
+		infracfg = syscon_regmap_lookup_by_compatible(data->plat_data->pericfg_comp_str);
+		if (IS_ERR(infracfg)) {
+			ret = PTR_ERR(infracfg);
+			goto out_runtime_disable;
+		}
+
+		data->pericfg = infracfg;
 	}
 
 	platform_set_drvdata(pdev, data);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 5b32277fee99..676d306af046 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -55,6 +55,7 @@ struct mtk_iommu_plat_data {
 	u32                 flags;
 	u32                 inv_sel_reg;
 
+	char					*pericfg_comp_str;
 	struct list_head			*hw_list;
 	unsigned int				iova_region_nr;
 	const struct mtk_iommu_iova_region	*iova_region;
@@ -80,6 +81,8 @@ struct mtk_iommu_data {
 	struct device			*smicomm_dev;
 
 	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
+	struct regmap			*pericfg;
+
 
 	/*
 	 * In the sharing pgtable case, list data->list to the global list like m4ulist.
-- 
2.18.0

From yong.wu at mediatek.com  Thu Aug 12 23:52:59 2021
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 13 Aug 2021 14:52:59 +0800
Subject: [PATCH v2 04/29] iommu/mediatek: Adapt sharing and non-sharing
 pgtable case
In-Reply-To: <20210813065324.29220-1-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
Message-ID: <20210813065324.29220-5-yong.wu@mediatek.com>

In previous mt2712, Both IOMMUs are MM IOMMU, and they will share pgtable.
However in the latest SoC, another is infra IOMMU, there is no reason to
share pgtable between MM with INFRA IOMMU. This patch manage to
implement the two case(sharing and non-sharing pgtable).

Currently we use for_each_m4u to loop the 2 HWs. Add the list_head into
this macro.
In the sharing pgtable case, the list_head is the global "m4ulist".
In the non-sharing pgtable case, the list_head is hw_list_head which is a
variable in the "data". then for_each_m4u will only loop itself.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 47 ++++++++++++++++++++++-----------------
 drivers/iommu/mtk_iommu.h |  7 ++++++
 2 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 2fd2a3ae88f0..287dfc0fc6f8 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -119,6 +119,7 @@
 #define WR_THROT_EN			BIT(6)
 #define HAS_LEGACY_IVRP_PADDR		BIT(7)
 #define IOVA_34_EN			BIT(8)
+#define SHARE_PGTABLE			BIT(9) /* 2 HW share pgtable */
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -166,7 +167,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data);
 
 static LIST_HEAD(m4ulist);	/* List all the M4U HWs */
 
-#define for_each_m4u(data)	list_for_each_entry(data, &m4ulist, list)
+#define for_each_m4u(data, head)  list_for_each_entry(data, head, list)
 
 struct mtk_iommu_iova_region {
 	dma_addr_t		iova_base;
@@ -187,21 +188,10 @@ static const struct mtk_iommu_iova_region mt8192_multi_dom[] = {
 	#endif
 };
 
-/*
- * There may be 1 or 2 M4U HWs, But we always expect they are in the same domain
- * for the performance.
- *
- * Here always return the mtk_iommu_data of the first probed M4U where the
- * iommu domain information is recorded.
- */
-static struct mtk_iommu_data *mtk_iommu_get_m4u_data(void)
+/* If 2 M4U share a domain(use the same hwlist), Put the corresponding info in first data.*/
+static struct mtk_iommu_data *mtk_iommu_get_frst_data(struct list_head *hwlist)
 {
-	struct mtk_iommu_data *data;
-
-	for_each_m4u(data)
-		return data;
-
-	return NULL;
+	return list_first_entry(hwlist, struct mtk_iommu_data, list);
 }
 
 static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
@@ -211,7 +201,9 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
 
 static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 {
-	for_each_m4u(data) {
+	struct list_head *head = data->hw_list;
+
+	for_each_m4u(data, head) {
 		if (pm_runtime_get_if_in_use(data->dev) <= 0)
 			continue;
 
@@ -228,12 +220,13 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 					   size_t granule,
 					   struct mtk_iommu_data *data)
 {
+	struct list_head *head = data->hw_list;
 	bool has_pm = !!data->dev->pm_domain;
 	unsigned long flags;
 	int ret;
 	u32 tmp;
 
-	for_each_m4u(data) {
+	for_each_m4u(data, head) {
 		if (has_pm) {
 			if (pm_runtime_get_if_in_use(data->dev) <= 0)
 				continue;
@@ -460,6 +453,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 {
 	struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata;
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+	struct list_head *hw_list = data->hw_list;
 	struct device *m4udev = data->dev;
 	int ret, domid;
 
@@ -469,7 +463,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 
 	if (!dom->data) {
 		/* Data is in the frstdata in sharing pgtable case. */
-		frstdata = mtk_iommu_get_m4u_data();
+		frstdata = mtk_iommu_get_frst_data(hw_list);
 
 		if (mtk_iommu_domain_finalise(dom, frstdata, domid))
 			return -ENODEV;
@@ -595,10 +589,12 @@ static void mtk_iommu_release_device(struct device *dev)
 
 static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 {
-	struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
+	struct mtk_iommu_data *c_data = dev_iommu_priv_get(dev), *data;
+	struct list_head *hw_list = c_data->hw_list;
 	struct iommu_group *group;
 	int domid;
 
+	data = mtk_iommu_get_frst_data(hw_list);
 	if (!data)
 		return ERR_PTR(-ENODEV);
 
@@ -899,7 +895,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		goto out_sysfs_remove;
 
 	spin_lock_init(&data->tlb_lock);
-	list_add_tail(&data->list, &m4ulist);
+
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) {
+		list_add_tail(&data->list, data->plat_data->hw_list);
+		data->hw_list = data->plat_data->hw_list;
+	} else {
+		INIT_LIST_HEAD(&data->hw_list_head);
+		list_add_tail(&data->list, &data->hw_list_head);
+		data->hw_list = &data->hw_list_head;
+	}
 
 	if (!iommu_present(&platform_bus_type)) {
 		ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_ops);
@@ -1003,7 +1007,8 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = {
 
 static const struct mtk_iommu_plat_data mt2712_data = {
 	.m4u_plat     = M4U_MT2712,
-	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG,
+	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE,
+	.hw_list      = &m4ulist,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index f81fa8862ed0..027a42396557 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -55,6 +55,7 @@ struct mtk_iommu_plat_data {
 	u32                 flags;
 	u32                 inv_sel_reg;
 
+	struct list_head			*hw_list;
 	unsigned int				iova_region_nr;
 	const struct mtk_iommu_iova_region	*iova_region;
 	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
@@ -80,6 +81,12 @@ struct mtk_iommu_data {
 
 	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
 
+	/*
+	 * In the sharing pgtable case, list data->list to the global list like m4ulist.
+	 * In the non-sharing pgtable case, list data->list to the itself hw_list_head.
+	 */
+	struct list_head		*hw_list;
+	struct list_head		hw_list_head;
 	struct list_head		list;
 	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
 };
-- 
2.18.0

From afaerber at suse.de  Fri Aug 13 00:05:56 2021
From: afaerber at suse.de (=?UTF-8?Q?Andreas_F=c3=a4rber?=)
Date: Fri, 13 Aug 2021 09:05:56 +0200
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <YRXmxD5u7drotWxP@linux-8mug>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-5-clin@suse.com>
 <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de> <YRXmxD5u7drotWxP@linux-8mug>
Message-ID: <78dc940b-4893-6355-8ccc-adb99a846081@suse.de>

Hi Chester,

On 13.08.21 05:28, Chester Lin wrote:
> On Thu, Aug 12, 2021 at 07:26:28PM +0200, Andreas F?rber wrote:
>> On 05.08.21 08:54, Chester Lin wrote:
>>> Add an initial dtsi file for generic SoC features of NXP S32G2.
>>>
>>> Signed-off-by: Chester Lin <clin at suse.com>
>>> ---
>>>  arch/arm64/boot/dts/freescale/s32g2.dtsi | 98 ++++++++++++++++++++++++
>>>  1 file changed, 98 insertions(+)
>>>  create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
>>>
>>> diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>>> new file mode 100644
>>> index 000000000000..3321819c1a2d
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
>>
>> Note: This DT is for running on the Cortex-A53 cores, but S32G2 also has
>> Cortex-M7 cores. For Vybrid SoCs, DTs later got contributed to also run
>> on its Cortex-M4 core:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf610.dtsi
>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf500.dtsi
>> vs.
>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm/boot/dts/vf610m4.dtsi
>>
>> Should we plan for this in our file naming here and in following patches
>> (e.g., s32g2-a53* vs. s32g2-m7*)? To me, a later concatenation of
>> s32g274am7* would look awkward, and s32g274a-m7* would sort between -evb
>> and -rdb2.
>>
>>> @@ -0,0 +1,98 @@
>>> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
>>> +/*
>>
>>  * NXP S32G2 SoC family
>>  *
>> ?
> 
> Will add it.
> 
>>
>> @NXP: Are any models other than 274A in the queue that we should
>> distinguish between s32g2.dtsi and s32g274a.dtsi here already?
>>
>>> + * Copyright (c) 2021 SUSE LLC
>>> + */
>>> +
>>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>>> +
>>> +/ {
>>> +	compatible = "fsl,s32g2";
>>> +	interrupt-parent = <&gic>;
>>> +	#address-cells = <2>;
>>> +	#size-cells = <2>;
[...]
>>> +	pmu {
>>> +		compatible = "arm,cortex-a53-pmu";
>>> +		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
>>
>> interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
> 
> Actually I traced the pmu_parse_irqs() and found that this SoC never falls into
> the pmu_has_irq_affinity() check because it's a percpu IRQ so the flow ends at
> pmu_parse_percpu_irq(). But it looks good to me to have an interrupt-affinity
> to indicate that each core has an associated PPI for PMU events as the binding
> file has suggested.

My comment was based on the DT binding requesting it also for PPI and
previous review requests for me to add it elsewhere, so it's quite
possible that your code analysis is correct.

FWIW also the cache nodes were not evaluated last time I checked,
although the specs do show those nodes and properties.

https://github.com/devicetree-org/devicetree-specification/blob/v0.3/source/devicenodes.rst

>>> +	};
[...]
>>> +
>>> +	soc {
>>> +		compatible = "simple-bus";
[...]
>>> +		#address-cells = <2>;
>>> +		#size-cells = <2>;
>>
>> Why? Does it have any peripherals that go beyond 32-bit space?
>> For 64-bit Realtek platforms Rob had asked me to use 1, if possible.
>> I do understand that for /memory nodes we do have high-memory addresses,
>> so 2 for the root node looks correct.
> 
> Actually it's a limitation due to [PATCH 7/8] "arm64: dts: s32g2: add memory
> nodes for evb and rdb2", which adds memory nodes to indicate maximum system
> RAM size combined by two separated memory banks, and the second bank starts
> from the offset 0x880000000 so that's why we need 64-bit address space here.
> Please feel free to let me know if any suggestion.

The /memory nodes are on the root node and thus only use #address-cells
and #size-cells from /, not from /soc here. Thus the only criterium is
whether something within /soc needs it.
PCI controllers may have 3 address cells, SPI/I2C controllers 1, so you
can have multiple sizes within one DT, you just need suitable ranges
wherever mappings to the parent address space are needed.
(I thought you had that distinction in an earlier draft I reviewed.)

Similarly, /reserved-memory would be outside the /soc node and use the
root node's #(address|size)-cells.

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt

Note: I'm assuming that if someone were to add a DT for the Cortex-M7s,
the address space mapping of any shared peripherals will likely differ,
as would the interrupts obviously, so I assume no direct .dtsi sharing
of /soc sub-nodes could sensibly be applied here.

@NXP: Please correct me if I'm wrong in either M7 not having access to
DDR RAM or large enough SRAM for Linux or another DT-consuming OS (and
this line of thinking not being applicable then) or you having use cases
to factor out some of the /soc sub-nodes for sharing between the two
(which would then give another reason for #address-/size-cells = <1> for
32-bit Cortex-M7).

[...]
>>> +		ranges;
>>
>> According to Rob, the /soc ranges should exclude any RAM ranges for
>> safety reasons. Compare:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/boot/dts/realtek/rtd129x.dtsi
>>
>> If you're lacking the maximum RAM areas to carve out, NXP is in CC to
>> help out :) and the EVB and RDB2 boards should give you starting numbers
>> that could be enlarged later if needed.
> 
> I added memory nodes in [PATCH 7/8] "arm64: dts: s32g2: add memory nodes for
> evb and rdb2" to describe maximum RAM areas, which are based on the information
> we found in NXP BSP and boards.

Yes, as discussed in 7/8, you should be using here:

		ranges = <0x0 0 0x0 0x80000000>; /* excluding 4 GiB RAM */

https://github.com/devicetree-org/devicetree-specification/blob/v0.3/source/devicetree-basics.rst

> @NXP: Please feel free to correct me if anything wrong, thanks.
> 
>>
>>> +
>>> +		gic: interrupt-controller at 50800000 {
>>> +			compatible = "arm,gic-v3";
>>> +			#interrupt-cells = <3>;
>>> +			interrupt-controller;
>>> +			reg = <0 0x50800000 0 0x10000>,
>>> +			      <0 0x50880000 0 0x200000>,
>>> +			      <0 0x50400000 0 0x2000>,
>>> +			      <0 0x50410000 0 0x2000>,
>>> +			      <0 0x50420000 0 0x2000>;
>>
>> Please order reg after compatible by convention, and sort
>> interrupt-controller or at least #interrupt-cells (applying to
>> consumers) last, after the below one applying to this device itself.
>>
> 
> Will do.
> 
>>> +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
>>> +						 IRQ_TYPE_LEVEL_HIGH)>;
>>> +		};
>>
>> CC'ing Marc for additional GIC scrutiny, often the sizes are wrong.
>>
> 
> IIRC, gic-v3 shouldn't have this kind of interrupt specifier. It's my fault and
> will fix it. Feel free to let me know if any suggestions.

You probably mean the GIC_CPU_MASK_SIMPLE()?

			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml

The interrupts property will be used by KVM (or possibly Xen) for vGIC.
Please ensure that the Kconfig you use for testing has KVM enabled.

>>> +	};
>>> +};

Cheers,
Andreas

-- 
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer
HRB 36809 (AG N?rnberg)


From anshuman.khandual at arm.com  Fri Aug 13 00:16:57 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 13 Aug 2021 12:46:57 +0530
Subject: [RFC V2 01/10] mm/mmap: Dynamically initialize protection_map[]
In-Reply-To: <d52e8af9-61af-45c2-837b-5a489e7e2916@arm.com>
References: <1627281445-12445-1-git-send-email-anshuman.khandual@arm.com>
 <1627281445-12445-2-git-send-email-anshuman.khandual@arm.com>
 <20210805170318.GB6719@arm.com>
 <d52e8af9-61af-45c2-837b-5a489e7e2916@arm.com>
Message-ID: <4bbe8b21-cc19-81ac-b53f-8e418a164e1b@arm.com>



On 8/12/21 2:45 PM, Anshuman Khandual wrote:
> 
> 
> On 8/5/21 10:33 PM, Catalin Marinas wrote:
>> On Mon, Jul 26, 2021 at 12:07:16PM +0530, Anshuman Khandual wrote:
>>> The protection_map[] elements (__PXXX and __SXXX) might sometimes contain
>>> runtime variables in certain platforms like arm64 preventing a successful
>>> build because of the current static initialization. So it just defers the
>>> initialization until mmmap_init() via a new helper init_protection_map().
>>>
>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>>> ---
>>>  mm/mmap.c | 26 ++++++++++++++++++++++----
>>>  1 file changed, 22 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/mm/mmap.c b/mm/mmap.c
>>> index ca54d36..a95b078 100644
>>> --- a/mm/mmap.c
>>> +++ b/mm/mmap.c
>>> @@ -100,10 +100,7 @@ static void unmap_region(struct mm_struct *mm,
>>>   *								w: (no) no
>>>   *								x: (yes) yes
>>>   */
>>> -pgprot_t protection_map[16] __ro_after_init = {
>>> -	__P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
>>> -	__S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
>>> -};
>>> +pgprot_t protection_map[16] __ro_after_init;
>>
>> Mips, x86, sparc, arm32, m68k all adjust protection_map[] during boot.
>> Could we do something similar here and avoid changing the generic code?
> 
> If __P[000..111] and __S[000..111] be made dummy values (e.g 0 or something
> standard prot temporarily), hence the compilation problem could be avoided.
> Later in the platform code, protection_map[] could be adjusted with actual
> prot values which would involve variable.
> 

Following change seems to work without any problem. Using __pgprot(0) as an
temporary protection value should be okay, as vm_get_page_prot() which uses
protection_map[] should never be called before mem_init() ?

 arch/arm64/include/asm/pgtable-prot.h | 34 +++++++++++++++++-----------------
 arch/arm64/mm/init.c                  | 22 ++++++++++++++++++++++
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 7032f04..539503a 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -88,23 +88,23 @@ extern bool arm64_use_ng_mappings;
 #define PAGE_READONLY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
 #define PAGE_EXECONLY		__pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
 
-#define __P000  PAGE_NONE
-#define __P001  PAGE_READONLY
-#define __P010  PAGE_READONLY
-#define __P011  PAGE_READONLY
-#define __P100  PAGE_EXECONLY
-#define __P101  PAGE_READONLY_EXEC
-#define __P110  PAGE_READONLY_EXEC
-#define __P111  PAGE_READONLY_EXEC
-
-#define __S000  PAGE_NONE
-#define __S001  PAGE_READONLY
-#define __S010  PAGE_SHARED
-#define __S011  PAGE_SHARED
-#define __S100  PAGE_EXECONLY
-#define __S101  PAGE_READONLY_EXEC
-#define __S110  PAGE_SHARED_EXEC
-#define __S111  PAGE_SHARED_EXEC
+#define __P000  __pgprot(0)
+#define __P001  __pgprot(0)
+#define __P010  __pgprot(0)
+#define __P011  __pgprot(0)
+#define __P100  __pgprot(0)
+#define __P101  __pgprot(0)
+#define __P110  __pgprot(0)
+#define __P111  __pgprot(0)
+
+#define __S000  __pgprot(0)
+#define __S001  __pgprot(0)
+#define __S010  __pgprot(0)
+#define __S011  __pgprot(0)
+#define __S100  __pgprot(0)
+#define __S101  __pgprot(0)
+#define __S110  __pgprot(0)
+#define __S111  __pgprot(0)
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2..51662b3 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -448,6 +448,27 @@ void __init bootmem_init(void)
 	memblock_dump_all();
 }
 
+static void init_protection_map(void)
+{
+	protection_map[0] = PAGE_NONE;
+	protection_map[1] = PAGE_READONLY;
+	protection_map[2] = PAGE_READONLY;
+	protection_map[3] = PAGE_READONLY;
+	protection_map[4] = PAGE_READONLY;
+	protection_map[5] = PAGE_READONLY_EXEC;
+	protection_map[6] = PAGE_READONLY_EXEC;
+	protection_map[7] = PAGE_READONLY_EXEC;
+
+	protection_map[8] = PAGE_NONE;
+	protection_map[9] = PAGE_READONLY;
+	protection_map[10] = PAGE_SHARED;
+	protection_map[11] = PAGE_SHARED;
+	protection_map[12] = PAGE_EXECONLY;
+	protection_map[13] = PAGE_READONLY_EXEC;
+	protection_map[14] = PAGE_SHARED_EXEC;
+	protection_map[15] = PAGE_SHARED_EXEC;
+}
+
 /*
  * mem_init() marks the free areas in the mem_map and tells us how much memory
  * is free.  This is done after various parts of the system have claimed their
@@ -489,6 +510,7 @@ void __init mem_init(void)
 		 */
 		sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;
 	}
+	init_protection_map();
 }
 
 void free_initmem(void)
-- 
2.7.4




From krzysztof.kozlowski at canonical.com  Fri Aug 13 00:41:00 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 13 Aug 2021 09:41:00 +0200
Subject: [PATCH v3 0/7] Add minimal support for Exynos850 SoC
In-Reply-To: <20210811114827.27322-1-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
Message-ID: <162884044884.8593.17144936297459767250.b4-ty@canonical.com>

On Wed, 11 Aug 2021 14:48:20 +0300, Sam Protsenko wrote:
> This patch series adds initial platform support for Samsung Exynos850
> SoC [1]. With this patchset it's possible to run the kernel with BusyBox
> rootfs as a RAM disk. More advanced platform support (like MMC driver
> additions) will be added later. The idea is to keep the first submission
> minimal to ease the review, and then build up on top of that.
> 
> [1] https://www.samsung.com/semiconductor/minisite/exynos/products/mobileprocessor/exynos-850/
> 
> [...]

Applied, thanks!

[1/7] dt-bindings: pinctrl: samsung: Add Exynos850 doc
      commit: 71b833b329d65236285cc73f4528f08c7d3c274c
[2/7] pinctrl: samsung: Add Exynos850 SoC specific data
      commit: cdd3d945dcec0d0dab845175dc9400ab54512aa6

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From rocco.yue at mediatek.com  Fri Aug 13 01:07:40 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Fri, 13 Aug 2021 16:07:40 +0800
Subject: [PATCH net-next v3] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <4624cc10-1fc8-12cd-e9e1-9585f5b496a0@gmail.com>
References: <4624cc10-1fc8-12cd-e9e1-9585f5b496a0@gmail.com>
Message-ID: <20210813080740.31571-1-rocco.yue@mediatek.com>

On Wed, 2021-08-11 at 12:05 -0600, David Ahern wrote:
> On 8/11/21 7:56 AM, David Ahern wrote:
>> On 8/10/21 6:33 AM, Rocco Yue wrote:
>>> On Mon, 2021-08-09 at 16:43 -0600, David Ahern wrote:
>>>>
>>>> Since this MTU is getting reported via af_info infrastructure,
>>>> rtmsg_ifinfo should be sufficient.
>>>>
>>>> From there use 'ip monitor' to make sure you are not generating multiple
>>>> notifications; you may only need this on the error path.
>>>
>>> Hi David,
>>>
>>> To avoid generating multiple notifications, I added a separate ramtu notify
>>> function in this patch, and I added RTNLGRP_IPV6_IFINFO nl_mgrp to the ipmonitor.c
>>> to verify this patch was as expected.
>>>
>>> I look at the rtmsg_ifinfo code, it should be appropriate and I will use it and
>>> verify it.
>>>
>>> But there's one thing, I'm sorry I didn't fully understand the meaning of this
>>> sentence "you may only need this on the error path". Honestly, I'm not sure what
>>> the error patch refers to, do you mean "if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu)" ?
>>>
>> 
>> looks like nothing under:
>>     if (ndopts.nd_opts_mtu && in6_dev->cnf.accept_ra_mtu) {
>> 
>>     }
>> 
>> is going to send a link notification so you can just replace
>> inet6_iframtu_notify with rtmsg_ifinfo in your proposed change.
>> 
> 
> Taking a deeper dive on the code, you do not need to call rtmsg_ifinfo.
> Instead, the existing:
> 
>         /*
>          *      Send a notify if RA changed managed/otherconf flags or
> timer settings
>          */
>         if (send_ifinfo_notify)
>                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
> 
> is called too early. For one the RA can change the MTU and that is done
> after this notify.
> 
> I think if you moved this down to the out:
> 
> out:
>         /*
>          *      Send a notify if RA changed managed/otherconf flags or
> timer settings
>          */
>         if (send_ifinfo_notify)
>                 inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
> 
> and then set send_ifinfo_notify when the mtu is *changed* by the RA you
> should be good.

Hi David,

Thanks for your suggestion,
this looks like a better choice without adding a separate notification function,
I will modify it and push the next iteration .

Best Regards,
Rocco

From xuwei5 at hisilicon.com  Fri Aug 13 01:30:01 2021
From: xuwei5 at hisilicon.com (Wei Xu)
Date: Fri, 13 Aug 2021 16:30:01 +0800
Subject: [PATCH] arm64: dts: HiSilicon: hi3660: address a PCI warning
In-Reply-To: <934f397d227ea589a16c89f1ee9c6f199c662093.1628666047.git.mchehab+huawei@kernel.org>
References: <934f397d227ea589a16c89f1ee9c6f199c662093.1628666047.git.mchehab+huawei@kernel.org>
Message-ID: <61162D89.2070901@hisilicon.com>

Hi Mauro,

On 2021/8/11 15:14, Mauro Carvalho Chehab wrote:
> When the driver is registered, it produces a warning when
> registering the PCI bridge:
> 
> 	[    5.363450] pci_bus 0000:00: root bus resource [bus 00-01]
> 	[    5.396998] pci_bus 0000:01: busn_res: can not insert [bus 01-ff] under [bus 00-01] (conflicts with (null) [bus 00-01])
> 	[    5.284831] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
> 
> The reason is that the bus-range is wrong. Address it.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>

Thanks!
Applied to the hisilicon arm64 dt tree.

Best Regards,
Wei

> ---
>  arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
> index f1ec87c05842..cf2079590ad8 100644
> --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
> +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
> @@ -1002,7 +1002,7 @@ pcie at f4000000 {
>  			      <0x0 0xf3f20000 0x0 0x40000>,
>  			      <0x0 0xf5000000 0x0 0x2000>;
>  			reg-names = "dbi", "apb", "phy", "config";
> -			bus-range = <0x0  0x1>;
> +			bus-range = <0x0  0xff>;
>  			#address-cells = <3>;
>  			#size-cells = <2>;
>  			device_type = "pci";
> 


From clin at suse.com  Fri Aug 13 01:47:40 2021
From: clin at suse.com (Chester Lin)
Date: Fri, 13 Aug 2021 16:47:40 +0800
Subject: [PATCH 6/8] arm64: dts: s32g2: add VNP-EVB and VNP-RDB2 support
In-Reply-To: <aef2fab4-078e-330b-28d0-1da964985f83@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-7-clin@suse.com>
 <aef2fab4-078e-330b-28d0-1da964985f83@suse.de>
Message-ID: <YRYxrElAu1aPQrSb@linux-8mug>

On Thu, Aug 12, 2021 at 08:00:01PM +0200, Andreas F?rber wrote:
> Hi Chester et al.,
> 
> On 05.08.21 08:54, Chester Lin wrote:
> > Add initial device-trees of NXP S32G2's Evaluation Board (S32G-VNP-EVB)
> > and Reference Design 2 Board (S32G-VNP-RDB2).
> 
> "Reference Design Board 2"?

It looks better. Will fix it.

> 
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  arch/arm64/boot/dts/freescale/Makefile        |  2 ++
> >  .../arm64/boot/dts/freescale/s32g274a-evb.dts | 21 ++++++++++++++++
> >  .../boot/dts/freescale/s32g274a-rdb2.dts      | 25 +++++++++++++++++++
> >  3 files changed, 48 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> >  create mode 100644 arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> > index 4b4785d86324..2886ddd42894 100644
> > --- a/arch/arm64/boot/dts/freescale/Makefile
> > +++ b/arch/arm64/boot/dts/freescale/Makefile
> > @@ -67,4 +67,6 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-ai_ml.dtb
> >  dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
> >  dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
> >  
> > +dtb-$(CONFIG_ARCH_S32) += s32g274a-evb.dtb
> > +dtb-$(CONFIG_ARCH_S32) += s32g274a-rdb2.dtb
> 
> @NXP: Note that since there's no distinction between S32V and S32G on
> the Kconfig level, we decided not to add a white line here. If you wish
> to visually separate them, that could be changed.
> 
> For reference:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/arch/arm64/Kconfig.platforms
> 
> speaks about S32 (without V), so did not need to get updated for S32G2.
> 
> >  dtb-$(CONFIG_ARCH_S32) += s32v234-evb.dtb
> > diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> > new file mode 100644
> > index 000000000000..a1ae5031730a
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> > @@ -0,0 +1,21 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> > +/*
> > + * Copyright (c) 2021 SUSE LLC
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "s32g2.dtsi"
> > +
> > +/ {
> > +	model = "NXP S32G2 Evaluation Board (S32G-VNP-EVB)";
> > +	compatible = "fsl,s32g274a-evb", "fsl,s32g2";
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +};
> > +
> 
> Is there any marking on the PCB that a /* ... */ comment could reference
> here? Right now uart0 is close to stdout-path above, but that will
> change once more device nodes get added and enabled alphabetically.
> 

Yes, it's marked as "UART J58". Will add it in v2.

> > +&uart0 {
> > +	status = "okay";
> 
> No clock-frequency or clocks property needed?
> 

As a minimum support patch, it can still reply on TF-A's clock settings so no
clock property is required at the moment.

> > +};
> > diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > new file mode 100644
> > index 000000000000..b2faae306b70
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > @@ -0,0 +1,25 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> > +/*
> > + * Copyright (c) 2021 SUSE LLC
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "s32g2.dtsi"
> > +
> > +/ {
> > +	model = "NXP S32G2 Reference Design 2 (S32G-VNP-RDB2)";
> 
> "Board" missing.

This model name is based on what I can find on the official main page of RDB2,
which is shorter without having an additional "Board" string:

https://www.nxp.com/design/designs/s32g-reference-design-2-for-vehicle-network-processing:S32G-VNP-RDB2

But having a "Board" looks good to me as well.

> 
> > +	compatible = "fsl,s32g274a-rdb2", "fsl,s32g2";
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +};
> > +
> 
> Comment please.
> 
> > +&uart0 {
> > +	status = "okay";
> 
> No clock-frequency or clocks property needed?
> 

Same as what I have explained in the evb dts.

> > +};
> > +
> > +&uart1 {
> > +	status = "okay";
> > +};
> 
> What is uart1? Please add a comment. Does it actually work without
> clocks property?
> 

RDB2 has an additional serial port [uart1] on the board. Please see:
https://www.nxp.com/document/guide/get-started-with-the-s32g-reference-design-board-2-for-vehicle-network-processing:GS-S32G-VNP-RDB2

It's the same as the uart0, the uart1 is also driven by the same set of clks
[S32GEN1_CLK_LINFLEXD, S32GEN1_CLK_LIN_BAUD] according to the downstream TF-A:
https://source.codeaurora.org/external/autobsps32/arm-trusted-firmware/tree/drivers/nxp/s32g/clk/s32gen1_scmi_ids.c?h=release/bsp29.0-2.3#n44

> Thanks,
> Andreas
> 
> -- 
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 N?rnberg, Germany
> GF: Felix Imend?rffer
> HRB 36809 (AG N?rnberg)
> 



From heiko at sntech.de  Fri Aug 13 01:51:39 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 13 Aug 2021 10:51:39 +0200
Subject: [PATCH v3] arm64: dts: rockchip: add thermal fan control to
 rockpro64
In-Reply-To: <20210730151727.729822-1-pgwipeout@gmail.com>
References: <20210730151727.729822-1-pgwipeout@gmail.com>
Message-ID: <162884469492.2596417.6101553398444696759.b4-ty@sntech.de>

On Fri, 30 Jul 2021 11:17:27 -0400, Peter Geis wrote:
> The rockpro64 had a fan node since
> commit 5882d65c1691 ("arm64: dts: rockchip: Add PWM fan for RockPro64")
> however it was never tied into the thermal driver for automatic control.
> 
> Add the links to the thermal node to permit the kernel to handle this
> automatically.
> Borrowed from the (rk3399-khadas-edge.dtsi).

Applied, thanks!

[1/1] arm64: dts: rockchip: add thermal fan control to rockpro64
      commit: 440f361af90acff36eb3d89c1f03debeab7b3fb8

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Fri Aug 13 01:51:41 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 13 Aug 2021 10:51:41 +0200
Subject: [PATCH 0/2] arm64: dts: rockchip: Add Scarlet Dumo Variant
In-Reply-To: <20210812094753.2359087-1-wenst@chromium.org>
References: <20210812094753.2359087-1-wenst@chromium.org>
Message-ID: <162884469491.2596417.3007403443594611487.b4-ty@sntech.de>

On Thu, 12 Aug 2021 17:47:51 +0800, Chen-Yu Tsai wrote:
> A variant of the Chrome OS Gru-Scarlet device is missing in upstream.
> This variant, dumo, is the same as the Innolux display panel variant,
> but requires a specific calibration variant for its WiFi module.
> 
> I'm not sure if it's better to inherit from gru-scarlet-innolux. I kept
> them separate from now, like in downstream ChromeOS kernel v4.4.
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: arm: rockchip: Add gru-scarlet-dumo board
      commit: 1aec043e2bcfc28a7b3946c852c89c008cfceb30
[2/2] arm64: dts: rockchip: rk3399: Add gru-scarlet-dumo board
      commit: ae328485ba0d5e2e0ff058438afbd8371badbc19

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Fri Aug 13 01:51:40 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 13 Aug 2021 10:51:40 +0200
Subject: [PATCH] arm64: dts: rockchip: Setup USB typec port as datarole on
In-Reply-To: <20210805220426.2693062-1-strit@manjaro.org>
References: <20210805220426.2693062-1-strit@manjaro.org>
Message-ID: <162884469491.2596417.6630020779304962035.b4-ty@sntech.de>

On Fri, 6 Aug 2021 00:04:27 +0200, Dan Johansen wrote:
> Some chargers try to put the charged device into device data
> role. Before this commit this condition caused the tcpm state machine to
> issue a hard reset due to a capability missmatch.

Applied, thanks!

[1/1] arm64: dts: rockchip: Setup USB typec port as datarole on
      commit: d34a2131ab59c8bb0786de693729fbd1aeef1049

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From will at kernel.org  Fri Aug 13 02:05:40 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 13 Aug 2021 10:05:40 +0100
Subject: [PATCH 3/5] arm64: Detect disabled HVC early
In-Reply-To: <20210812190213.2601506-4-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-4-maz@kernel.org>
Message-ID: <20210813090539.GA7536@willie-the-truck>

On Thu, Aug 12, 2021 at 08:02:11PM +0100, Marc Zyngier wrote:
> Having HVC disabled from EL3 while the kernel is entered at EL2
> is a complete nightmare.
> 
> We end-up taking an UNDEF at the worse possible moment (checking
> for VHE) and even if we didn't, having KVM enabled would signify
> the premature end of the kernel.
> 
> Instead, try and detect this stupid case by issuing a HVC
> for HVC_RESET_VECTORS, which does nothing when the stubs
> are live. If we get HVC_STUB_ERR back, that's because the
> UNDEF handler has kicked in.
> 
> In this situation, close your eyes, block your nose, and gracefully
> pretend we have booted at EL1.
> 
> Reported-by: Rafa? Mi?ecki <zajec5 at gmail.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kernel/head.S | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 9d5aa56a98cc..d6b2b05f5d3a 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -519,6 +519,28 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
>  	msr	vbar_el2, x0
>  	isb
>  
> +	// Check that HVC actually works...
> +	mov	x0, #HVC_RESET_VECTORS
> +	hvc	#0
> +
> +	mov_q	x1, HVC_STUB_ERR
> +	cmp	x0, x1
> +	b.ne	0f
> +
> +	/*
> +	 * HVC is unusable, so pretend we actually booted at EL1.
> +	 * Once we have left EL2, there will be no going back.
> +	 */

This comment got me thinking...

	.macro	host_hvc0
	mrs	xzr, actlr_el1
	.endm

then set HCR_EL2.TACR=1 while we still can and match the ISS against a
constant in the handler. Too awful?

Will


From lkp at intel.com  Fri Aug 13 02:22:50 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 17:22:50 +0800
Subject: [soc:omap/smartreflex] BUILD SUCCESS
 74953a9136cfd650dd994daded520528f737b7b3
Message-ID: <611639ea.R7ALKHDU0UlGsfRe%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git omap/smartreflex
branch HEAD: 74953a9136cfd650dd994daded520528f737b7b3  soc: ti: Remove pm_runtime_irq_safe() usage for smartreflex

elapsed time: 10199m

configs tested: 265
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210805
powerpc                     mpc5200_defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
mips                        workpad_defconfig
powerpc                     mpc83xx_defconfig
mips                           ip32_defconfig
h8300                            alldefconfig
powerpc                 mpc85xx_cds_defconfig
sparc                       sparc64_defconfig
sh                            migor_defconfig
sh                  sh7785lcr_32bit_defconfig
arm                              alldefconfig
sh                          polaris_defconfig
powerpc                      bamboo_defconfig
powerpc                       holly_defconfig
powerpc                mpc7448_hpc2_defconfig
powerpc                        cell_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
arm                       aspeed_g4_defconfig
mips                        qi_lb60_defconfig
sh                              ul2_defconfig
sh                           se7619_defconfig
arm                          moxart_defconfig
mips                           jazz_defconfig
powerpc                      arches_defconfig
microblaze                          defconfig
sh                           se7721_defconfig
mips                         tb0219_defconfig
arm                       mainstone_defconfig
powerpc                     mpc512x_defconfig
um                                  defconfig
sh                          rsk7264_defconfig
sh                   rts7751r2dplus_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
mips                  cavium_octeon_defconfig
mips                     loongson2k_defconfig
sh                          sdk7780_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
arm                       imx_v6_v7_defconfig
ia64                        generic_defconfig
mips                        bcm47xx_defconfig
xtensa                    xip_kc705_defconfig
sh                          kfr2r09_defconfig
i386                             alldefconfig
sh                   sh7724_generic_defconfig
arm                            hisi_defconfig
mips                         tb0226_defconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
mips                          ath25_defconfig
s390                          debug_defconfig
openrisc                  or1klitex_defconfig
arc                    vdk_hs38_smp_defconfig
csky                                defconfig
xtensa                              defconfig
powerpc                    sam440ep_defconfig
powerpc                      mgcoge_defconfig
powerpc                       ebony_defconfig
mips                        jmr3927_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
m68k                        m5307c3_defconfig
powerpc                        fsp2_defconfig
arm                      footbridge_defconfig
arm                           spitz_defconfig
powerpc                     stx_gp3_defconfig
arm                     davinci_all_defconfig
arm                       omap2plus_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                            gpr_defconfig
mips                           ip28_defconfig
sh                           se7722_defconfig
sh                               j2_defconfig
mips                           xway_defconfig
s390                                defconfig
sh                      rts7751r2d1_defconfig
powerpc                     sequoia_defconfig
arm                      pxa255-idp_defconfig
powerpc                     taishan_defconfig
mips                      loongson3_defconfig
mips                     decstation_defconfig
powerpc                     ppa8548_defconfig
arc                        nsimosci_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                        icon_defconfig
arm                     am200epdkit_defconfig
powerpc                          allmodconfig
arm                  colibri_pxa300_defconfig
mips                     loongson1b_defconfig
powerpc                      acadia_defconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
arm                        mvebu_v5_defconfig
powerpc                      katmai_defconfig
arm                       versatile_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a005-20210805
i386                 randconfig-a004-20210805
i386                 randconfig-a002-20210805
i386                 randconfig-a006-20210805
i386                 randconfig-a003-20210805
i386                 randconfig-a001-20210805
i386                 randconfig-a005-20210806
i386                 randconfig-a004-20210806
i386                 randconfig-a002-20210806
i386                 randconfig-a006-20210806
i386                 randconfig-a003-20210806
i386                 randconfig-a001-20210806
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210806
i386                 randconfig-a011-20210806
i386                 randconfig-a015-20210806
i386                 randconfig-a013-20210806
i386                 randconfig-a014-20210806
i386                 randconfig-a016-20210806
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-c001-20210805
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 02:22:54 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 17:22:54 +0800
Subject: [soc:omap/dt] BUILD SUCCESS 8c054cd2818ea08555efe24a2ffde330833c2f3f
Message-ID: <611639ee.qEhrMnrW+PyRFtFE%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git omap/dt
branch HEAD: 8c054cd2818ea08555efe24a2ffde330833c2f3f  ARM: dts: am57xx: Add PRUSS MDIO controller nodes

elapsed time: 14162m

configs tested: 180
configs skipped: 137

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210803
mips                           ip28_defconfig
arm                        cerfcube_defconfig
arm                        neponset_defconfig
arc                        nsimosci_defconfig
powerpc                     mpc5200_defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
i386                             alldefconfig
mips                      fuloong2e_defconfig
mips                           mtx1_defconfig
arm                           u8500_defconfig
arm                            dove_defconfig
h8300                            alldefconfig
sh                           se7619_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
riscv                    nommu_k210_defconfig
m68k                       m5208evb_defconfig
x86_64                           alldefconfig
powerpc                     pseries_defconfig
mips                            gpr_defconfig
mips                      maltaaprp_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
powerpc                     mpc512x_defconfig
openrisc                 simple_smp_defconfig
powerpc                     ppa8548_defconfig
xtensa                    xip_kc705_defconfig
sh                          kfr2r09_defconfig
sh                           se7722_defconfig
arm                         socfpga_defconfig
mips                         db1xxx_defconfig
powerpc                   lite5200b_defconfig
arm                           omap1_defconfig
sparc                       sparc32_defconfig
arm                     davinci_all_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
s390                             allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a004-20210802
i386                 randconfig-a005-20210802
i386                 randconfig-a002-20210802
i386                 randconfig-a006-20210802
i386                 randconfig-a001-20210802
i386                 randconfig-a003-20210802
i386                 randconfig-a004-20210803
i386                 randconfig-a005-20210803
i386                 randconfig-a002-20210803
i386                 randconfig-a006-20210803
i386                 randconfig-a001-20210803
i386                 randconfig-a003-20210803
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a012-20210802
x86_64               randconfig-a016-20210802
x86_64               randconfig-a013-20210802
x86_64               randconfig-a011-20210802
x86_64               randconfig-a014-20210802
x86_64               randconfig-a015-20210802
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a012-20210803
i386                 randconfig-a011-20210803
i386                 randconfig-a015-20210803
i386                 randconfig-a013-20210803
i386                 randconfig-a014-20210803
i386                 randconfig-a016-20210803
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
x86_64               randconfig-a002-20210803
x86_64               randconfig-a004-20210803
x86_64               randconfig-a006-20210803
x86_64               randconfig-a003-20210803
x86_64               randconfig-a001-20210803
x86_64               randconfig-a005-20210803
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-c001-20210803
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a012-20210803
x86_64               randconfig-a016-20210803
x86_64               randconfig-a013-20210803
x86_64               randconfig-a011-20210803
x86_64               randconfig-a014-20210803
x86_64               randconfig-a015-20210803

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 02:22:38 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 17:22:38 +0800
Subject: [soc:mediatek/dt] BUILD SUCCESS
 293cb6b0ea19e628388959da4baa9558e891afc0
Message-ID: <611639de.gSULzlFoQtzwONeG%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git mediatek/dt
branch HEAD: 293cb6b0ea19e628388959da4baa9558e891afc0  arm: dts: mt7623: increase passive cooling trip

elapsed time: 12440m

configs tested: 258
configs skipped: 129

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210805
arm                     eseries_pxa_defconfig
powerpc                      walnut_defconfig
mips                 decstation_r4k_defconfig
m68k                          multi_defconfig
arm                              alldefconfig
powerpc                     mpc5200_defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
powerpc                     powernv_defconfig
sh                          kfr2r09_defconfig
powerpc                          g5_defconfig
powerpc                 canyonlands_defconfig
m68k                        stmark2_defconfig
arm                       aspeed_g4_defconfig
mips                        qi_lb60_defconfig
powerpc                       holly_defconfig
sh                              ul2_defconfig
sh                           se7619_defconfig
powerpc                      pcm030_defconfig
arm                            pleb_defconfig
arm                           u8500_defconfig
arm                         palmz72_defconfig
sh                           se7343_defconfig
powerpc                     kilauea_defconfig
powerpc                      cm5200_defconfig
arm                            xcep_defconfig
mips                             allmodconfig
powerpc                      acadia_defconfig
sh                   rts7751r2dplus_defconfig
arm                          gemini_defconfig
mips                          malta_defconfig
mips                        bcm47xx_defconfig
powerpc                     tqm8548_defconfig
sh                          rsk7201_defconfig
sh                          rsk7269_defconfig
arc                            hsdk_defconfig
arm                        keystone_defconfig
arm                         s3c2410_defconfig
mips                        workpad_defconfig
um                             i386_defconfig
sh                        sh7785lcr_defconfig
arm                            mps2_defconfig
arm                         lpc18xx_defconfig
arm                       cns3420vb_defconfig
mips                         mpc30x_defconfig
mips                        nlm_xlr_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
m68k                          hp300_defconfig
xtensa                         virt_defconfig
sh                          polaris_defconfig
arm                       spear13xx_defconfig
mips                       lemote2f_defconfig
xtensa                    xip_kc705_defconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
mips                          ath25_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
openrisc                  or1klitex_defconfig
powerpc                    amigaone_defconfig
m68k                          atari_defconfig
arm                        spear3xx_defconfig
sh                      rts7751r2d1_defconfig
powerpc                     sequoia_defconfig
arm                      pxa255-idp_defconfig
powerpc                     taishan_defconfig
mips                      loongson3_defconfig
mips                      fuloong2e_defconfig
powerpc                 mpc8560_ads_defconfig
m68k                       m5249evb_defconfig
riscv                    nommu_virt_defconfig
arm                           viper_defconfig
arm                     davinci_all_defconfig
mips                           gcw0_defconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
arm                             pxa_defconfig
mips                     loongson2k_defconfig
parisc                           alldefconfig
mips                     loongson1b_defconfig
arm                         s5pv210_defconfig
powerpc                     ppa8548_defconfig
powerpc                        icon_defconfig
sh                          rsk7203_defconfig
s390                                defconfig
mips                        nlm_xlp_defconfig
powerpc                     tqm8541_defconfig
sh                             sh03_defconfig
riscv                            allyesconfig
i386                                defconfig
sh                           se7705_defconfig
arm                         cm_x300_defconfig
arc                          axs101_defconfig
powerpc                      ep88xc_defconfig
m68k                            mac_defconfig
arm                         orion5x_defconfig
powerpc                      chrp32_defconfig
powerpc                     tqm5200_defconfig
powerpc                     ep8248e_defconfig
m68k                           sun3_defconfig
sh                         ecovec24_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
mips                             allyesconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
i386                 randconfig-a005-20210805
i386                 randconfig-a004-20210805
i386                 randconfig-a002-20210805
i386                 randconfig-a006-20210805
i386                 randconfig-a003-20210805
i386                 randconfig-a001-20210805
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                    nommu_k210_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210804
x86_64               randconfig-c001-20210812
x86_64               randconfig-c001-20210805
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 02:22:44 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 17:22:44 +0800
Subject: [soc:mediatek/dt64] BUILD SUCCESS
 ce5db043d2e8811f30de3ebb5d9e6bd8a33596c4
Message-ID: <611639e4.FTcgYq0p3Gocg6k7%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git mediatek/dt64
branch HEAD: ce5db043d2e8811f30de3ebb5d9e6bd8a33596c4  dt-bindings: mediatek: Add optional mediatek,gce-events property

elapsed time: 9623m

configs tested: 257
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210807
i386                 randconfig-c001-20210805
powerpc                     mpc5200_defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
arm                       aspeed_g4_defconfig
powerpc                  mpc866_ads_defconfig
powerpc                      mgcoge_defconfig
powerpc                 mpc832x_mds_defconfig
sparc                       sparc64_defconfig
sh                            migor_defconfig
sh                  sh7785lcr_32bit_defconfig
arm                              alldefconfig
sh                          polaris_defconfig
powerpc                      bamboo_defconfig
powerpc                       holly_defconfig
powerpc                mpc7448_hpc2_defconfig
powerpc                        cell_defconfig
powerpc                 mpc837x_rdb_defconfig
mips                malta_qemu_32r6_defconfig
sh                           se7343_defconfig
sh                             shx3_defconfig
m68k                        stmark2_defconfig
sparc                            alldefconfig
arm                          moxart_defconfig
mips                           jazz_defconfig
powerpc                      arches_defconfig
microblaze                          defconfig
sh                           se7721_defconfig
i386                             alldefconfig
mips                      fuloong2e_defconfig
mips                           mtx1_defconfig
arm                           u8500_defconfig
arm                       imx_v4_v5_defconfig
arm                         axm55xx_defconfig
powerpc                     tqm5200_defconfig
sh                        sh7763rdp_defconfig
h8300                    h8300h-sim_defconfig
mips                        workpad_defconfig
powerpc                          g5_defconfig
sh                        sh7785lcr_defconfig
arm                            mps2_defconfig
sh                   rts7751r2dplus_defconfig
sh                          rsk7264_defconfig
mips                        qi_lb60_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
riscv                    nommu_k210_defconfig
m68k                       m5208evb_defconfig
x86_64                           alldefconfig
powerpc                     pseries_defconfig
mips                            gpr_defconfig
mips                      maltaaprp_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
arm                       imx_v6_v7_defconfig
ia64                        generic_defconfig
mips                        bcm47xx_defconfig
xtensa                    xip_kc705_defconfig
sh                          kfr2r09_defconfig
mips                         tb0287_defconfig
arm64                            alldefconfig
arc                            hsdk_defconfig
powerpc                    sam440ep_defconfig
powerpc                       ebony_defconfig
sh                   secureedge5410_defconfig
mips                        jmr3927_defconfig
m68k                        m5307c3_defconfig
powerpc                        fsp2_defconfig
arm                      footbridge_defconfig
arm                           spitz_defconfig
powerpc                     stx_gp3_defconfig
mips                           ip28_defconfig
sh                           se7722_defconfig
sh                               j2_defconfig
mips                           xway_defconfig
s390                                defconfig
arm                       mainstone_defconfig
arm                   milbeaut_m10v_defconfig
powerpc                     taishan_defconfig
powerpc                     mpc83xx_defconfig
arm                         nhk8815_defconfig
arm                     davinci_all_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
sh                        edosk7760_defconfig
arm                           tegra_defconfig
csky                                defconfig
arm                     am200epdkit_defconfig
powerpc                          allmodconfig
arm                      jornada720_defconfig
m68k                       m5249evb_defconfig
arm                          badge4_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
i386                 randconfig-a005-20210805
i386                 randconfig-a004-20210805
i386                 randconfig-a002-20210805
i386                 randconfig-a006-20210805
i386                 randconfig-a003-20210805
i386                 randconfig-a001-20210805
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
i386                 randconfig-a012-20210806
i386                 randconfig-a011-20210806
i386                 randconfig-a015-20210806
i386                 randconfig-a013-20210806
i386                 randconfig-a014-20210806
i386                 randconfig-a016-20210806
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210808
x86_64               randconfig-c001-20210812
x86_64               randconfig-c001-20210805
x86_64               randconfig-c001-20210804
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 02:22:48 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 17:22:48 +0800
Subject: [soc:mediatek/drivers] BUILD SUCCESS
 25423731956b3d72bc35d336227c88ada49148e8
Message-ID: <611639e8.79ZMFvoLbPPeak6t%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git mediatek/drivers
branch HEAD: 25423731956b3d72bc35d336227c88ada49148e8  soc: mediatek: mmsys: Fix missing UFOE component in mt8173 table routing

elapsed time: 9730m

configs tested: 291
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210805
i386                 randconfig-c001-20210807
powerpc                     mpc5200_defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
arm                       aspeed_g4_defconfig
powerpc                  mpc866_ads_defconfig
powerpc                      mgcoge_defconfig
powerpc                 mpc832x_mds_defconfig
sparc                       sparc64_defconfig
sh                            migor_defconfig
sh                  sh7785lcr_32bit_defconfig
arm                              alldefconfig
sh                          polaris_defconfig
powerpc                      bamboo_defconfig
powerpc                       holly_defconfig
powerpc                mpc7448_hpc2_defconfig
powerpc                        cell_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
mips                malta_qemu_32r6_defconfig
sh                           se7343_defconfig
sh                             shx3_defconfig
m68k                        stmark2_defconfig
arc                     haps_hs_smp_defconfig
m68k                        m5307c3_defconfig
arm                          pcm027_defconfig
arm                         lpc32xx_defconfig
sh                           sh2007_defconfig
mips                        nlm_xlp_defconfig
sparc                            alldefconfig
arm                          moxart_defconfig
mips                           jazz_defconfig
powerpc                      arches_defconfig
microblaze                          defconfig
sh                           se7721_defconfig
arm                       imx_v4_v5_defconfig
arm                         axm55xx_defconfig
powerpc                     tqm5200_defconfig
sh                        sh7763rdp_defconfig
h8300                    h8300h-sim_defconfig
mips                        workpad_defconfig
powerpc                          g5_defconfig
sh                        sh7785lcr_defconfig
arm                            mps2_defconfig
sh                   rts7751r2dplus_defconfig
sh                          rsk7264_defconfig
mips                        qi_lb60_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
arm                       imx_v6_v7_defconfig
ia64                        generic_defconfig
mips                        bcm47xx_defconfig
xtensa                    xip_kc705_defconfig
sh                          kfr2r09_defconfig
mips                           mtx1_defconfig
sh                            titan_defconfig
mips                          rb532_defconfig
m68k                            mac_defconfig
powerpc                 mpc836x_mds_defconfig
mips                         tb0287_defconfig
arm64                            alldefconfig
arc                            hsdk_defconfig
s390                          debug_defconfig
openrisc                  or1klitex_defconfig
arc                    vdk_hs38_smp_defconfig
csky                                defconfig
mips                           ip32_defconfig
xtensa                              defconfig
powerpc                    sam440ep_defconfig
powerpc                       ebony_defconfig
mips                        jmr3927_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
powerpc                        fsp2_defconfig
arm                      footbridge_defconfig
arm                           spitz_defconfig
powerpc                     stx_gp3_defconfig
mips                           ip28_defconfig
sh                           se7722_defconfig
mips                           xway_defconfig
s390                                defconfig
sh                               j2_defconfig
arm                       mainstone_defconfig
arm                   milbeaut_m10v_defconfig
powerpc                     taishan_defconfig
powerpc                     mpc83xx_defconfig
arm                         nhk8815_defconfig
arm                     davinci_all_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                     ppa8548_defconfig
powerpc                        icon_defconfig
sh                                  defconfig
m68k                          atari_defconfig
sh                        edosk7760_defconfig
arm                           tegra_defconfig
arm                     am200epdkit_defconfig
powerpc                          allmodconfig
m68k                       m5249evb_defconfig
arm                          badge4_defconfig
powerpc                          allyesconfig
xtensa                  audio_kc705_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
i386                 randconfig-a005-20210805
i386                 randconfig-a004-20210805
i386                 randconfig-a002-20210805
i386                 randconfig-a006-20210805
i386                 randconfig-a003-20210805
i386                 randconfig-a001-20210805
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
x86_64               randconfig-a016-20210808
x86_64               randconfig-a012-20210808
x86_64               randconfig-a013-20210808
x86_64               randconfig-a011-20210808
x86_64               randconfig-a014-20210808
x86_64               randconfig-a015-20210808
i386                 randconfig-a012-20210806
i386                 randconfig-a011-20210806
i386                 randconfig-a015-20210806
i386                 randconfig-a013-20210806
i386                 randconfig-a014-20210806
i386                 randconfig-a016-20210806
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a012-20210808
i386                 randconfig-a015-20210808
i386                 randconfig-a011-20210808
i386                 randconfig-a013-20210808
i386                 randconfig-a014-20210808
i386                 randconfig-a016-20210808
i386                 randconfig-a012-20210804
i386                 randconfig-a011-20210804
i386                 randconfig-a015-20210804
i386                 randconfig-a013-20210804
i386                 randconfig-a014-20210804
i386                 randconfig-a016-20210804
i386                 randconfig-a012-20210805
i386                 randconfig-a011-20210805
i386                 randconfig-a015-20210805
i386                 randconfig-a013-20210805
i386                 randconfig-a014-20210805
i386                 randconfig-a016-20210805
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210808
x86_64               randconfig-c001-20210812
x86_64               randconfig-c001-20210805
x86_64               randconfig-c001-20210804
x86_64               randconfig-c001-20210806
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 02:23:03 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 17:23:03 +0800
Subject: [soc:omap/soc-late] BUILD SUCCESS
 4297d1c0834af97fe992ec7bf766f0a262ce5ffc
Message-ID: <611639f7.OZht4Dphrx79rszB%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git omap/soc-late
branch HEAD: 4297d1c0834af97fe992ec7bf766f0a262ce5ffc  arm: omap2: Drop the unused OMAP_PACKAGE_* KConfig entries

elapsed time: 10199m

configs tested: 246
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210805
powerpc                     mpc5200_defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
mips                        workpad_defconfig
powerpc                     mpc83xx_defconfig
mips                           ip32_defconfig
h8300                            alldefconfig
powerpc                 mpc85xx_cds_defconfig
sparc                       sparc64_defconfig
sh                            migor_defconfig
sh                  sh7785lcr_32bit_defconfig
arm                              alldefconfig
sh                          polaris_defconfig
powerpc                      bamboo_defconfig
powerpc                       holly_defconfig
powerpc                mpc7448_hpc2_defconfig
powerpc                        cell_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                          moxart_defconfig
mips                           jazz_defconfig
powerpc                      arches_defconfig
microblaze                          defconfig
sh                           se7721_defconfig
i386                             alldefconfig
mips                      fuloong2e_defconfig
mips                           mtx1_defconfig
arm                           u8500_defconfig
mips                         tb0219_defconfig
arm                       mainstone_defconfig
powerpc                     mpc512x_defconfig
um                                  defconfig
sh                          rsk7264_defconfig
mips                        qi_lb60_defconfig
sh                   rts7751r2dplus_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
mips                  cavium_octeon_defconfig
mips                     loongson2k_defconfig
sh                          sdk7780_defconfig
riscv                    nommu_k210_defconfig
m68k                       m5208evb_defconfig
x86_64                           alldefconfig
powerpc                     pseries_defconfig
mips                            gpr_defconfig
mips                      maltaaprp_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
arm                       imx_v6_v7_defconfig
ia64                        generic_defconfig
mips                        bcm47xx_defconfig
xtensa                    xip_kc705_defconfig
sh                          kfr2r09_defconfig
sh                   sh7724_generic_defconfig
arm                            hisi_defconfig
mips                         tb0226_defconfig
powerpc                    sam440ep_defconfig
powerpc                      mgcoge_defconfig
powerpc                       ebony_defconfig
sh                   secureedge5410_defconfig
mips                        jmr3927_defconfig
m68k                        m5307c3_defconfig
powerpc                        fsp2_defconfig
arm                      footbridge_defconfig
arm                           spitz_defconfig
powerpc                     stx_gp3_defconfig
arm                     davinci_all_defconfig
arm                       omap2plus_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                           ip28_defconfig
sh                           se7722_defconfig
sh                               j2_defconfig
mips                           xway_defconfig
s390                                defconfig
sh                      rts7751r2d1_defconfig
powerpc                     sequoia_defconfig
arm                      pxa255-idp_defconfig
powerpc                     taishan_defconfig
mips                      loongson3_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
csky                                defconfig
arm                     am200epdkit_defconfig
powerpc                          allmodconfig
arm                      jornada720_defconfig
arm                  colibri_pxa300_defconfig
s390                          debug_defconfig
mips                     loongson1b_defconfig
powerpc                      acadia_defconfig
sh                     sh7710voipgw_defconfig
arm                    vt8500_v6_v7_defconfig
arm                        mvebu_v5_defconfig
powerpc                      katmai_defconfig
arm                       versatile_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
i386                 randconfig-a005-20210805
i386                 randconfig-a004-20210805
i386                 randconfig-a002-20210805
i386                 randconfig-a006-20210805
i386                 randconfig-a003-20210805
i386                 randconfig-a001-20210805
i386                 randconfig-a005-20210806
i386                 randconfig-a004-20210806
i386                 randconfig-a002-20210806
i386                 randconfig-a006-20210806
i386                 randconfig-a003-20210806
i386                 randconfig-a001-20210806
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210806
i386                 randconfig-a011-20210806
i386                 randconfig-a015-20210806
i386                 randconfig-a013-20210806
i386                 randconfig-a014-20210806
i386                 randconfig-a016-20210806
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-c001-20210805
x86_64               randconfig-c001-20210804
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 02:22:59 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 17:22:59 +0800
Subject: [soc:sti/dt] BUILD SUCCESS
 f9807f9cb396544ab6bdb4f4451505211ca602f7
Message-ID: <611639f3.tjhiDBnyTGz5LU1/%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git sti/dt
branch HEAD: f9807f9cb396544ab6bdb4f4451505211ca602f7  ARM: dts: sti: remove clk_ignore_unused from bootargs for stih410-b2260

elapsed time: 10150m

configs tested: 261
configs skipped: 128

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210804
i386                 randconfig-c001-20210805
i386                 randconfig-c001-20210812
powerpc                     mpc5200_defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
mips                        workpad_defconfig
powerpc                     mpc83xx_defconfig
mips                           ip32_defconfig
h8300                            alldefconfig
powerpc                 mpc85xx_cds_defconfig
sparc                       sparc64_defconfig
sh                            migor_defconfig
sh                  sh7785lcr_32bit_defconfig
arm                              alldefconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
arm                       aspeed_g4_defconfig
mips                        qi_lb60_defconfig
powerpc                       holly_defconfig
sh                              ul2_defconfig
sh                           se7619_defconfig
powerpc                   microwatt_defconfig
arm                        neponset_defconfig
mips                        bcm63xx_defconfig
powerpc                 mpc8315_rdb_defconfig
arm                          moxart_defconfig
mips                           jazz_defconfig
powerpc                      arches_defconfig
microblaze                          defconfig
sh                           se7721_defconfig
mips                         tb0219_defconfig
arm                       mainstone_defconfig
powerpc                     mpc512x_defconfig
um                                  defconfig
riscv                            allmodconfig
m68k                        m5407c3_defconfig
arm                          badge4_defconfig
arm                       multi_v4t_defconfig
arm                         orion5x_defconfig
sh                          rsk7264_defconfig
sh                   rts7751r2dplus_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
arm                       imx_v6_v7_defconfig
ia64                        generic_defconfig
mips                        bcm47xx_defconfig
xtensa                    xip_kc705_defconfig
sh                          kfr2r09_defconfig
i386                             alldefconfig
sh                   sh7724_generic_defconfig
sh                          sdk7780_defconfig
arm                            hisi_defconfig
mips                         tb0226_defconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
mips                          ath25_defconfig
arm                     davinci_all_defconfig
sh                           se7750_defconfig
nios2                            allyesconfig
arm                            lart_defconfig
parisc                generic-64bit_defconfig
sh                        apsh4ad0a_defconfig
powerpc                    sam440ep_defconfig
powerpc                      mgcoge_defconfig
powerpc                       ebony_defconfig
mips                        jmr3927_defconfig
sh                          polaris_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
m68k                        m5307c3_defconfig
powerpc                        fsp2_defconfig
arm                      footbridge_defconfig
arm                           spitz_defconfig
powerpc                     stx_gp3_defconfig
mips                           ip28_defconfig
sh                           se7722_defconfig
sh                               j2_defconfig
mips                           xway_defconfig
s390                                defconfig
sh                      rts7751r2d1_defconfig
powerpc                     sequoia_defconfig
arm                      pxa255-idp_defconfig
powerpc                     taishan_defconfig
mips                      loongson3_defconfig
sh                           se7705_defconfig
mips                     decstation_defconfig
powerpc64                           defconfig
powerpc                    klondike_defconfig
mips                 decstation_r4k_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                     ppa8548_defconfig
powerpc                        icon_defconfig
csky                                defconfig
arm                     am200epdkit_defconfig
powerpc                          allmodconfig
arm                    vt8500_v6_v7_defconfig
arm                        mvebu_v5_defconfig
powerpc                      katmai_defconfig
arm                       versatile_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20210805
x86_64               randconfig-a006-20210805
x86_64               randconfig-a004-20210805
x86_64               randconfig-a003-20210805
x86_64               randconfig-a001-20210805
x86_64               randconfig-a005-20210805
i386                 randconfig-a005-20210804
i386                 randconfig-a004-20210804
i386                 randconfig-a002-20210804
i386                 randconfig-a006-20210804
i386                 randconfig-a003-20210804
i386                 randconfig-a001-20210804
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a005-20210805
i386                 randconfig-a004-20210805
i386                 randconfig-a002-20210805
i386                 randconfig-a006-20210805
i386                 randconfig-a003-20210805
i386                 randconfig-a001-20210805
i386                 randconfig-a005-20210806
i386                 randconfig-a004-20210806
i386                 randconfig-a002-20210806
i386                 randconfig-a006-20210806
i386                 randconfig-a003-20210806
i386                 randconfig-a001-20210806
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a012-20210804
x86_64               randconfig-a016-20210804
x86_64               randconfig-a011-20210804
x86_64               randconfig-a013-20210804
x86_64               randconfig-a014-20210804
x86_64               randconfig-a015-20210804
i386                 randconfig-a012-20210806
i386                 randconfig-a011-20210806
i386                 randconfig-a015-20210806
i386                 randconfig-a013-20210806
i386                 randconfig-a014-20210806
i386                 randconfig-a016-20210806
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-c001-20210805
x86_64               randconfig-a002-20210804
x86_64               randconfig-a006-20210804
x86_64               randconfig-a004-20210804
x86_64               randconfig-a003-20210804
x86_64               randconfig-a001-20210804
x86_64               randconfig-a005-20210804
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a012-20210805
x86_64               randconfig-a016-20210805
x86_64               randconfig-a011-20210805
x86_64               randconfig-a013-20210805
x86_64               randconfig-a014-20210805
x86_64               randconfig-a015-20210805

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 02:22:57 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 17:22:57 +0800
Subject: [soc:omap/cpsw-dt] BUILD SUCCESS
 29fabf5274bfb89124918840c79851659a25ba79
Message-ID: <611639f1.k1z6eGj7ebYEnv2g%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git omap/cpsw-dt
branch HEAD: 29fabf5274bfb89124918840c79851659a25ba79  ARM: dts: am335x-sancloud-bbe: Drop usb wifi comment

elapsed time: 4441m

configs tested: 185
configs skipped: 132

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
powerpc                     mpc5200_defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
powerpc                     pq2fads_defconfig
arc                         haps_hs_defconfig
arc                    vdk_hs38_smp_defconfig
arm                         vf610m4_defconfig
m68k                          multi_defconfig
i386                             alldefconfig
mips                      fuloong2e_defconfig
mips                           mtx1_defconfig
arm                           u8500_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
riscv                    nommu_k210_defconfig
m68k                       m5208evb_defconfig
x86_64                           alldefconfig
powerpc                     pseries_defconfig
mips                            gpr_defconfig
mips                      maltaaprp_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
xtensa                    xip_kc705_defconfig
sh                          kfr2r09_defconfig
sh                          landisk_defconfig
openrisc                         alldefconfig
arm                           stm32_defconfig
powerpc                      ppc64e_defconfig
powerpc                     tqm8540_defconfig
riscv                          rv32_defconfig
arm                       omap2plus_defconfig
powerpc                      bamboo_defconfig
mips                        bcm47xx_defconfig
mips                   sb1250_swarm_defconfig
arm                     davinci_all_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
sh                          sdk7786_defconfig
arm                            pleb_defconfig
s390                       zfcpdump_defconfig
arc                        vdk_hs38_defconfig
powerpc                 mpc8540_ads_defconfig
arm                         lubbock_defconfig
arm                         palmz72_defconfig
m68k                        m5272c3_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a004-20210810
x86_64               randconfig-a006-20210810
x86_64               randconfig-a003-20210810
x86_64               randconfig-a005-20210810
x86_64               randconfig-a002-20210810
x86_64               randconfig-a001-20210810
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210810
i386                 randconfig-a015-20210810
i386                 randconfig-a013-20210810
i386                 randconfig-a014-20210810
i386                 randconfig-a016-20210810
i386                 randconfig-a012-20210810
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                            allyesconfig
riscv                               defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-c001-20210810
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a013-20210810
x86_64               randconfig-a011-20210810
x86_64               randconfig-a012-20210810
x86_64               randconfig-a016-20210810
x86_64               randconfig-a014-20210810
x86_64               randconfig-a015-20210810
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From andriy.shevchenko at linux.intel.com  Fri Aug 13 02:43:22 2021
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 13 Aug 2021 12:43:22 +0300
Subject: [PATCH v4 1/4] clk: fractional-divider: Export approximation
 algorithm to the CCF users
In-Reply-To: <162879819529.19113.6409882476721828944@swboyd.mtv.corp.google.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
 <162879819529.19113.6409882476721828944@swboyd.mtv.corp.google.com>
Message-ID: <YRY+uoTrBjkdh4Zj@smile.fi.intel.com>

On Thu, Aug 12, 2021 at 12:56:35PM -0700, Stephen Boyd wrote:
> Quoting Andy Shevchenko (2021-08-12 10:00:22)
> > At least one user currently duplicates some functions that are provided
> > by fractional divider module. Let's export approximation algorithm and
> > replace the open-coded variant.
> > 
> > As a bonus the exported function will get better documentation in place.
> Applied to clk-next

Thank you, Stephen!

-- 
With Best Regards,
Andy Shevchenko




From radu-nicolae.pirea at oss.nxp.com  Fri Aug 13 02:54:53 2021
From: radu-nicolae.pirea at oss.nxp.com (Radu Nicolae Pirea (NXP OSS))
Date: Fri, 13 Aug 2021 12:54:53 +0300
Subject: [PATCH 5/8] arm64: dts: s32g2: add serial/uart support
In-Reply-To: <93978882-4b47-4c4a-cd43-60cb5bcdf471@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-6-clin@suse.com>
 <93978882-4b47-4c4a-cd43-60cb5bcdf471@suse.de>
Message-ID: <8a38d66032f875d35834e50943aa02786e2a0517.camel@oss.nxp.com>

Hi Andreas
On Thu, 2021-08-12 at 19:42 +0200, Andreas F?rber wrote:
> Hi Chester et al.,
> 
> On 05.08.21 08:54, Chester Lin wrote:
> > Add serial/uart support for NXP S32G2.
> 
> You might mention here that (following our initial stub) this commit
> is
> now apparently based on the CodeAurora BSP branch foo (and therefore
> adding its last-year copyright below and separate from 4/8).
> 
> > 
> 
> @NXP: If there are downstream Signed-off-bys that you would like to
> see
> included for this portion here, please speak up.

Larisa signed-off should be added.
Signed-off-by: Larisa Grigore <larisa.grigore at nxp.com>

> 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> > ?arch/arm64/boot/dts/freescale/s32g2.dtsi | 31
> > ++++++++++++++++++++++++
> > ?1 file changed, 31 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > index 3321819c1a2d..0076eacad8a6 100644
> > --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > @@ -1,6 +1,7 @@
> > ?// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> > ?/*
> > ? * Copyright (c) 2021 SUSE LLC
> > + * Copyright 2017-2020 NXP
> 
> @NXP: Should this be updated to include 2021 from your latest BSP
> releases? Do you want it visually aligned by adding the ASCII-art?

Yes for both questions. The copyright year sould be updated to 2021 and
should be visually aligned.

> 
> > ? */
> > ?
> > ?#include <dt-bindings/interrupt-controller/arm-gic.h>
> > @@ -11,6 +12,12 @@ / {
> > ????????#address-cells = <2>;
> > ????????#size-cells = <2>;
> > ?
> > +???????aliases {
> > +???????????????serial0 = &uart0;
> > +???????????????serial1 = &uart1;
> > +???????????????serial2 = &uart2;
> > +???????};
> 
> Note: In the past there had been controversies as to whether to
> define
> aliases globally for a SoC or in a .dts specific to a board's usage.
> In this case it does not seem to matter much, as uart0 is being used
> as
> console on the reference boards.
> 
> > +
> > ????????cpus {
> > ????????????????#address-cells = <1>;
> > ????????????????#size-cells = <0>;
> > @@ -82,6 +89,30 @@ soc {
> > ?
> > ????????????????ranges;
> > ?
> > +???????????????uart0: serial at 401c8000 {
> > +???????????????????????compatible = "fsl,s32g2-linflexuart",
> > +??????????????????????????????????? "fsl,s32v234-linflexuart";
> > +???????????????????????reg = <0 0x401c8000 0 0x3000>;
> > +???????????????????????interrupts = <GIC_SPI 82
> > IRQ_TYPE_EDGE_RISING>;
> > +???????????????????????status = "disabled";
> > +???????????????};
> > +
> > +???????????????uart1: serial at 401cc000 {
> > +???????????????????????compatible = "fsl,s32g2-linflexuart",
> > +??????????????????????????????????? "fsl,s32v234-linflexuart";
> > +???????????????????????reg = <0 0x401cc000 0 0x3000>;
> > +???????????????????????interrupts = <GIC_SPI 83
> > IRQ_TYPE_EDGE_RISING>;
> > +???????????????????????status = "disabled";
> > +???????????????};
> > +
> > +???????????????uart2: serial at 402bc000 {
> > +???????????????????????compatible = "fsl,s32g2-linflexuart",
> > +??????????????????????????????????? "fsl,s32v234-linflexuart";
> > +???????????????????????reg = <0 0x402bc000 0 0x3000>;
> > +???????????????????????interrupts = <GIC_SPI 84
> > IRQ_TYPE_EDGE_RISING>;
> > +???????????????????????status = "disabled";
> > +???????????????};
> > +
> > ????????????????gic: interrupt-controller at 50800000 {
> > ????????????????????????compatible = "arm,gic-v3";
> > ????????????????????????#interrupt-cells = <3>;
> 
> Regards,
> Andreas
> 




From chiawei_wang at aspeedtech.com  Thu Aug 12 22:47:57 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Fri, 13 Aug 2021 13:47:57 +0800
Subject: [PATCH 1/2] soc: aspeed: Add LPC mailbox support
In-Reply-To: <20210813054758.13189-1-chiawei_wang@aspeedtech.com>
References: <20210813054758.13189-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210813054758.13189-2-chiawei_wang@aspeedtech.com>

The LPC mailbox controller consists of multiple general
registers for the communication between the Host and the BMC.
The interrupts for data update signaling are also introduced.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 drivers/soc/aspeed/Kconfig           |  10 +
 drivers/soc/aspeed/Makefile          |   9 +-
 drivers/soc/aspeed/aspeed-lpc-mbox.c | 415 +++++++++++++++++++++++++++
 3 files changed, 430 insertions(+), 4 deletions(-)
 create mode 100644 drivers/soc/aspeed/aspeed-lpc-mbox.c

diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
index 243ca196e6ad..5b31a6e2620c 100644
--- a/drivers/soc/aspeed/Kconfig
+++ b/drivers/soc/aspeed/Kconfig
@@ -24,6 +24,16 @@ config ASPEED_LPC_SNOOP
 	  allows the BMC to listen on and save the data written by
 	  the host to an arbitrary LPC I/O port.
 
+config ASPEED_LPC_MAILBOX
+	tristate "ASPEED LPC mailbox support"
+	select REGMAP
+	select MFD_SYSCON
+	default ARCH_ASPEED
+	help
+	  Provides a driver to control the LPC mailbox which possesses
+	  up to 32 data registers for the communication between the Host
+	  and the BMC over LPC.
+
 config ASPEED_P2A_CTRL
 	tristate "ASPEED P2A (VGA MMIO to BMC) bridge control"
 	select REGMAP
diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
index fcab7192e1a4..cde6b4514c97 100644
--- a/drivers/soc/aspeed/Makefile
+++ b/drivers/soc/aspeed/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_ASPEED_LPC_CTRL)	+= aspeed-lpc-ctrl.o
-obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
-obj-$(CONFIG_ASPEED_P2A_CTRL)	+= aspeed-p2a-ctrl.o
-obj-$(CONFIG_ASPEED_SOCINFO)	+= aspeed-socinfo.o
+obj-$(CONFIG_ASPEED_LPC_CTRL)		+= aspeed-lpc-ctrl.o
+obj-$(CONFIG_ASPEED_LPC_SNOOP)		+= aspeed-lpc-snoop.o
+obj-$(CONFIG_ASPEED_LPC_MAILBOX)	+= aspeed-lpc-mbox.o
+obj-$(CONFIG_ASPEED_P2A_CTRL)		+= aspeed-p2a-ctrl.o
+obj-$(CONFIG_ASPEED_SOCINFO)		+= aspeed-socinfo.o
diff --git a/drivers/soc/aspeed/aspeed-lpc-mbox.c b/drivers/soc/aspeed/aspeed-lpc-mbox.c
new file mode 100644
index 000000000000..ac8f4c5fbbb1
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-lpc-mbox.c
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2017 IBM Corporation
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define DEVICE_NAME	"aspeed-mbox"
+
+#define ASPEED_MBOX_DR(dr, n)	(dr + (n * 4))
+#define ASPEED_MBOX_STR(str, n)	(str + (n / 8) * 4)
+#define ASPEED_MBOX_BIE(bie, n)	(bie + (n / 8) * 4)
+#define ASPEED_MBOX_HIE(hie, n) (hie + (n / 8) * 4)
+
+#define ASPEED_MBOX_BCR_RECV	BIT(7)
+#define ASPEED_MBOX_BCR_MASK	BIT(1)
+#define ASPEED_MBOX_BCR_SEND	BIT(0)
+
+/* ioctl code */
+#define ASPEED_MBOX_IOCTL		0xA3
+#define ASPEED_MBOX_IOCTL_GET_SIZE	\
+	_IOR(ASPEED_MBOX_IOCTL, 0, struct aspeed_mbox_ioctl_data)
+
+struct aspeed_mbox_ioctl_data {
+	unsigned int data;
+};
+
+struct aspeed_mbox_model {
+	unsigned int dr_num;
+
+	/* offsets to the MBOX registers */
+	unsigned int dr;
+	unsigned int str;
+	unsigned int bcr;
+	unsigned int hcr;
+	unsigned int bie;
+	unsigned int hie;
+};
+
+struct aspeed_mbox {
+	struct miscdevice miscdev;
+	struct regmap *map;
+	unsigned int base;
+	wait_queue_head_t queue;
+	struct mutex mutex;
+	const struct aspeed_mbox_model *model;
+};
+
+static atomic_t aspeed_mbox_open_count = ATOMIC_INIT(0);
+
+static u8 aspeed_mbox_inb(struct aspeed_mbox *mbox, int reg)
+{
+	/*
+	 * The mbox registers are actually only one byte but are addressed
+	 * four bytes apart. The other three bytes are marked 'reserved',
+	 * they *should* be zero but lets not rely on it.
+	 * I am going to rely on the fact we can casually read/write to them...
+	 */
+	unsigned int val = 0xff; /* If regmap throws an error return 0xff */
+	int rc = regmap_read(mbox->map, mbox->base + reg, &val);
+
+	if (rc)
+		dev_err(mbox->miscdev.parent, "regmap_read() failed with "
+			"%d (reg: 0x%08x)\n", rc, reg);
+
+	return val & 0xff;
+}
+
+static void aspeed_mbox_outb(struct aspeed_mbox *mbox, u8 data, int reg)
+{
+	int rc = regmap_write(mbox->map, mbox->base + reg, data);
+
+	if (rc)
+		dev_err(mbox->miscdev.parent, "regmap_write() failed with "
+			"%d (data: %u reg: 0x%08x)\n", rc, data, reg);
+}
+
+static struct aspeed_mbox *file_mbox(struct file *file)
+{
+	return container_of(file->private_data, struct aspeed_mbox, miscdev);
+}
+
+static int aspeed_mbox_open(struct inode *inode, struct file *file)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+
+	if (atomic_inc_return(&aspeed_mbox_open_count) == 1) {
+		/*
+		 * Clear the interrupt status bit if it was left on and unmask
+		 * interrupts.
+		 * ASPEED_MBOX_BCR_RECV bit is W1C, this also unmasks in 1 step
+		 */
+		aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_RECV, model->bcr);
+		return 0;
+	}
+
+	atomic_dec(&aspeed_mbox_open_count);
+	return -EBUSY;
+}
+
+static ssize_t aspeed_mbox_read(struct file *file, char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+	char __user *p = buf;
+	ssize_t ret;
+	int i;
+
+	if (!access_ok(buf, count))
+		return -EFAULT;
+
+	if (count + *ppos > model->dr_num)
+		return -EINVAL;
+
+	if (file->f_flags & O_NONBLOCK) {
+		if (!(aspeed_mbox_inb(mbox, model->bcr) &
+				ASPEED_MBOX_BCR_RECV))
+			return -EAGAIN;
+	} else if (wait_event_interruptible(mbox->queue,
+				aspeed_mbox_inb(mbox, model->bcr) &
+				ASPEED_MBOX_BCR_RECV)) {
+		return -ERESTARTSYS;
+	}
+
+	mutex_lock(&mbox->mutex);
+
+	for (i = *ppos; count > 0 && i < model->dr_num; i++) {
+		uint8_t reg = aspeed_mbox_inb(mbox, ASPEED_MBOX_DR(model->dr, i));
+
+		ret = __put_user(reg, p);
+		if (ret)
+			goto out_unlock;
+
+		p++;
+		count--;
+	}
+
+	/* ASPEED_MBOX_BCR_RECV bit is write to clear, this also unmasks in 1 step */
+	aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_RECV, model->bcr);
+	ret = p - buf;
+
+out_unlock:
+	mutex_unlock(&mbox->mutex);
+	return ret;
+}
+
+static ssize_t aspeed_mbox_write(struct file *file, const char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+	const char __user *p = buf;
+	ssize_t ret;
+	char c;
+	int i;
+
+	if (!access_ok(buf, count))
+		return -EFAULT;
+
+	if (count + *ppos > model->dr_num)
+		return -EINVAL;
+
+	mutex_lock(&mbox->mutex);
+
+	for (i = *ppos; count > 0 && i < model->dr_num; i++) {
+		ret = __get_user(c, p);
+		if (ret)
+			goto out_unlock;
+
+		aspeed_mbox_outb(mbox, c, ASPEED_MBOX_DR(model->dr, i));
+		p++;
+		count--;
+	}
+
+	aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_SEND, model->bcr);
+	ret = p - buf;
+
+out_unlock:
+	mutex_unlock(&mbox->mutex);
+	return ret;
+}
+
+static unsigned int aspeed_mbox_poll(struct file *file, poll_table *wait)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+	unsigned int mask = 0;
+
+	poll_wait(file, &mbox->queue, wait);
+
+	if (aspeed_mbox_inb(mbox, model->bcr) & ASPEED_MBOX_BCR_RECV)
+		mask |= POLLIN;
+
+	return mask;
+}
+
+static int aspeed_mbox_release(struct inode *inode, struct file *file)
+{
+	atomic_dec(&aspeed_mbox_open_count);
+	return 0;
+}
+
+static long aspeed_mbox_ioctl(struct file *file, unsigned int cmd,
+				 unsigned long param)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+	struct aspeed_mbox_ioctl_data data;
+	long ret;
+
+	switch (cmd) {
+	case ASPEED_MBOX_IOCTL_GET_SIZE:
+		data.data = model->dr_num;
+		ret = copy_to_user((void __user *)param, &data, sizeof(data));
+		break;
+	default:
+		ret = -ENOTTY;
+	}
+	return ret;
+}
+
+static const struct file_operations aspeed_mbox_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_seek_end_llseek,
+	.read		= aspeed_mbox_read,
+	.write		= aspeed_mbox_write,
+	.open		= aspeed_mbox_open,
+	.release	= aspeed_mbox_release,
+	.poll		= aspeed_mbox_poll,
+	.unlocked_ioctl	= aspeed_mbox_ioctl,
+};
+
+static irqreturn_t aspeed_mbox_irq(int irq, void *arg)
+{
+	struct aspeed_mbox *mbox = arg;
+	const struct aspeed_mbox_model *model = mbox->model;
+
+	if (!(aspeed_mbox_inb(mbox, model->bcr) & ASPEED_MBOX_BCR_RECV))
+		return IRQ_NONE;
+
+	/*
+	 * Leave the status bit set so that we know the data is for us,
+	 * clear it once it has been read.
+	 */
+
+	/* Mask it off, we'll clear it when we the data gets read */
+	aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_MASK, model->bcr);
+
+	wake_up(&mbox->queue);
+	return IRQ_HANDLED;
+}
+
+static int aspeed_mbox_config_irq(struct aspeed_mbox *mbox,
+		struct platform_device *pdev)
+{
+	const struct aspeed_mbox_model *model = mbox->model;
+	struct device *dev = &pdev->dev;
+	int i, rc, irq;
+
+	irq = irq_of_parse_and_map(dev->of_node, 0);
+	if (!irq)
+		return -ENODEV;
+
+	rc = devm_request_irq(dev, irq, aspeed_mbox_irq,
+			IRQF_SHARED, DEVICE_NAME, mbox);
+	if (rc < 0) {
+		dev_err(dev, "Unable to request IRQ %d\n", irq);
+		return rc;
+	}
+
+	/*
+	 * Disable all register based interrupts.
+	 */
+	for (i = 0; i < model->dr_num / 8; ++i)
+		aspeed_mbox_outb(mbox, 0x00, ASPEED_MBOX_BIE(model->bie, i));
+
+	/* These registers are write one to clear. Clear them. */
+	for (i = 0; i < model->dr_num / 8; ++i)
+		aspeed_mbox_outb(mbox, 0xff, ASPEED_MBOX_STR(model->str, i));
+
+	aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_RECV, model->bcr);
+	return 0;
+}
+
+static int aspeed_mbox_probe(struct platform_device *pdev)
+{
+	struct aspeed_mbox *mbox;
+	struct device *dev;
+	int rc;
+
+	dev = &pdev->dev;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	dev_set_drvdata(&pdev->dev, mbox);
+
+	rc = of_property_read_u32(dev->of_node, "reg", &mbox->base);
+	if (rc) {
+		dev_err(dev, "Couldn't read reg device tree property\n");
+		return rc;
+	}
+
+	mbox->model = of_device_get_match_data(dev);
+	if (IS_ERR(mbox->model)) {
+		dev_err(dev, "Couldn't get model data\n");
+		return -ENODEV;
+	}
+
+	mbox->map = syscon_node_to_regmap(
+			pdev->dev.parent->of_node);
+	if (IS_ERR(mbox->map)) {
+		dev_err(dev, "Couldn't get regmap\n");
+		return -ENODEV;
+	}
+
+	mutex_init(&mbox->mutex);
+	init_waitqueue_head(&mbox->queue);
+
+	mbox->miscdev.minor = MISC_DYNAMIC_MINOR;
+	mbox->miscdev.name = DEVICE_NAME;
+	mbox->miscdev.fops = &aspeed_mbox_fops;
+	mbox->miscdev.parent = dev;
+	rc = misc_register(&mbox->miscdev);
+	if (rc) {
+		dev_err(dev, "Unable to register device\n");
+		return rc;
+	}
+
+	rc = aspeed_mbox_config_irq(mbox, pdev);
+	if (rc) {
+		dev_err(dev, "Failed to configure IRQ\n");
+		misc_deregister(&mbox->miscdev);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int aspeed_mbox_remove(struct platform_device *pdev)
+{
+	struct aspeed_mbox *mbox = dev_get_drvdata(&pdev->dev);
+
+	misc_deregister(&mbox->miscdev);
+
+	return 0;
+}
+
+static const struct aspeed_mbox_model ast2400_model = {
+	.dr_num = 16,
+	.dr	= 0x0,
+	.str = 0x40,
+	.bcr = 0x48,
+	.hcr = 0x4c,
+	.bie = 0x50,
+	.hie = 0x58,
+};
+
+static const struct aspeed_mbox_model ast2500_model = {
+	.dr_num = 16,
+	.dr	= 0x0,
+	.str = 0x40,
+	.bcr = 0x48,
+	.hcr = 0x4c,
+	.bie = 0x50,
+	.hie = 0x58,
+};
+
+static const struct aspeed_mbox_model ast2600_model = {
+	.dr_num = 32,
+	.dr	= 0x0,
+	.str = 0x80,
+	.bcr = 0x90,
+	.hcr = 0x94,
+	.bie = 0xa0,
+	.hie = 0xb0,
+};
+
+static const struct of_device_id aspeed_mbox_match[] = {
+	{ .compatible = "aspeed,ast2400-mbox",
+	  .data = &ast2400_model },
+	{ .compatible = "aspeed,ast2500-mbox",
+	  .data = &ast2500_model },
+	{ .compatible = "aspeed,ast2600-mbox",
+	  .data = &ast2600_model },
+	{ },
+};
+
+static struct platform_driver aspeed_mbox_driver = {
+	.driver = {
+		.name		= DEVICE_NAME,
+		.of_match_table = aspeed_mbox_match,
+	},
+	.probe = aspeed_mbox_probe,
+	.remove = aspeed_mbox_remove,
+};
+
+module_platform_driver(aspeed_mbox_driver);
+MODULE_DEVICE_TABLE(of, aspeed_mbox_match);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cyril Bur <cyrilbur at gmail.com>");
+MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang at aspeedtech.com");
+MODULE_DESCRIPTION("Aspeed mailbox device driver");
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Thu Aug 12 22:47:56 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Fri, 13 Aug 2021 13:47:56 +0800
Subject: [PATCH 0/2] aspeed: Add LPC mailbox support
Message-ID: <20210813054758.13189-1-chiawei_wang@aspeedtech.com>

Add driver support for the LPC mailbox controller of ASPEED SoCs.

Chia-Wei Wang (2):
  soc: aspeed: Add LPC mailbox support
  ARM: dts: aspeed: Add mailbox to device tree

 arch/arm/boot/dts/aspeed-g4.dtsi     |   7 +
 arch/arm/boot/dts/aspeed-g5.dtsi     |   8 +-
 arch/arm/boot/dts/aspeed-g6.dtsi     |   7 +
 drivers/soc/aspeed/Kconfig           |  10 +
 drivers/soc/aspeed/Makefile          |   9 +-
 drivers/soc/aspeed/aspeed-lpc-mbox.c | 415 +++++++++++++++++++++++++++
 6 files changed, 451 insertions(+), 5 deletions(-)
 create mode 100644 drivers/soc/aspeed/aspeed-lpc-mbox.c

-- 
2.17.1



From chiawei_wang at aspeedtech.com  Thu Aug 12 22:47:58 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Fri, 13 Aug 2021 13:47:58 +0800
Subject: [PATCH 2/2] ARM: dts: aspeed: Add mailbox to device tree
In-Reply-To: <20210813054758.13189-1-chiawei_wang@aspeedtech.com>
References: <20210813054758.13189-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210813054758.13189-3-chiawei_wang@aspeedtech.com>

Add mailbox to the device tree for Aspeed AST24xx/AST25xx/AST26xx SoCs.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 arch/arm/boot/dts/aspeed-g4.dtsi | 7 +++++++
 arch/arm/boot/dts/aspeed-g5.dtsi | 8 +++++++-
 arch/arm/boot/dts/aspeed-g6.dtsi | 7 +++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index c5aeb3cf3a09..6298d69df415 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -383,6 +383,13 @@
 					interrupts = <8>;
 					status = "disabled";
 				};
+
+				mbox: mbox at 200 {
+					compatible = "aspeed,ast2500-mbox";
+					reg = <0x200 0x30>;
+					interrupts = <46>;
+					status = "disabled";
+				};
 			};
 
 			uart2: serial at 1e78d000 {
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 329eaeef66fb..ab9453d7803c 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -497,13 +497,19 @@
 					reg = <0xa0 0x24 0xc8 0x8>;
 				};
 
-
 				ibt: ibt at 140 {
 					compatible = "aspeed,ast2500-ibt-bmc";
 					reg = <0x140 0x18>;
 					interrupts = <8>;
 					status = "disabled";
 				};
+
+				mbox: mbox at 200 {
+					compatible = "aspeed,ast2500-mbox";
+					reg = <0x200 0x30>;
+					interrupts = <46>;
+					status = "disabled";
+				};
 			};
 
 			uart2: serial at 1e78d000 {
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index f96607b7b4e2..09b286f2ece2 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -529,6 +529,13 @@
 					interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
 					status = "disabled";
 				};
+
+				mbox: mbox at 200 {
+					compatible = "aspeed,ast2600-mbox";
+					reg = <0x200 0xc0>;
+					interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+					status = "disabled";
+				};
 			};
 
 			sdc: sdc at 1e740000 {
-- 
2.17.1



From geert at linux-m68k.org  Fri Aug 13 02:55:12 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 13 Aug 2021 11:55:12 +0200
Subject: [PATCH 5/5] arm64: defconfig: Enable RIIC
In-Reply-To: <CAMuHMdV5FE24t__Xa0d5uTA2FPTitn69tDPFqQhpRGz3uvrckg@mail.gmail.com>
References: <20210611165624.30749-1-biju.das.jz@bp.renesas.com>
 <20210611165624.30749-6-biju.das.jz@bp.renesas.com>
 <CAMuHMdV5FE24t__Xa0d5uTA2FPTitn69tDPFqQhpRGz3uvrckg@mail.gmail.com>
Message-ID: <CAMuHMdX_=2t5xoybwgmTFqfkDRhq7BPVoU9qC=CB88qrJpoPSA@mail.gmail.com>

On Mon, Jun 14, 2021 at 2:45 PM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> On Fri, Jun 11, 2021 at 6:56 PM Biju Das <biju.das.jz at bp.renesas.com> wrote:
> > Enable RIIC driver support for Renesas RZ/G2L based platforms.
> >
> > Signed-off-by: Biju Das <biju.das.jz at bp.renesas.com>
> > Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas at glider.be>
> i.e. will queue in renesas-devel for v5.15.

Given we don't have any i2c users yet in the RZ/G2L board DTS files,
I'm postponing this to v5.16.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From p.zabel at pengutronix.de  Fri Aug 13 03:02:15 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Fri, 13 Aug 2021 12:02:15 +0200
Subject: [v11 2/2] pwm: Add Aspeed ast2600 PWM support
In-Reply-To: <20210812040942.5365-3-billy_tsai@aspeedtech.com>
References: <20210812040942.5365-1-billy_tsai@aspeedtech.com>
 <20210812040942.5365-3-billy_tsai@aspeedtech.com>
Message-ID: <5da35c2030e57621fa56795cd193e727f53205fe.camel@pengutronix.de>

Hi Billy,

On Thu, 2021-08-12 at 12:09 +0800, Billy Tsai wrote:
> This patch add the support of PWM controller which can be found at aspeed
> ast2600 soc. The pwm supoorts up to 16 channels and it's part function
> of multi-function device "pwm-tach controller".
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
[...]
> diff --git a/drivers/pwm/pwm-aspeed-ast2600.c b/drivers/pwm/pwm-aspeed-ast2600.c
> new file mode 100644
> index 000000000000..f89ce1d4cd67
> --- /dev/null
> +++ b/drivers/pwm/pwm-aspeed-ast2600.c
> @@ -0,0 +1,327 @@
[...]
> +static int aspeed_pwm_probe(struct platform_device *pdev)
> +{
[...]
> +	priv->clk = devm_clk_get(&parent_dev->dev, 0);
> +	if (IS_ERR(priv->clk))
> +		return dev_err_probe(dev, PTR_ERR(priv->clk),
> +				     "Couldn't get clock\n");
> +
> +	ret = clk_prepare_enable(priv->clk);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Couldn't enable clock\n");
> +
> +	priv->reset = devm_reset_control_get_shared(&parent_dev->dev, NULL);
> +	if (IS_ERR(priv->reset)) {
> +		ret = dev_err_probe(dev, PTR_ERR(priv->reset),
> +				    "Get reset failed\n");
> +		goto err_disable_clk;
> +	}

I suggest to request the reset control before enabling the clock. That
way you can simplify the error path and avoid enabling the clock in case
of reset_control_get failure.

regards
Philipp


From geert+renesas at glider.be  Fri Aug 13 03:22:36 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 13 Aug 2021 12:22:36 +0200
Subject: [GIT PULL 2/2] Renesas driver updates for v5.15 (take two)
In-Reply-To: <cover.1628849621.git.geert+renesas@glider.be>
References: <cover.1628849621.git.geert+renesas@glider.be>
Message-ID: <cover.1628849625.git.geert+renesas@glider.be>

The following changes since commit bfe6b5590ce6cab81b3ee51b4541bd1d0b18b3b2:

  soc: renesas: Identify R-Car H3e-2G and M3e-2G (2021-07-27 09:27:19 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-drivers-for-v5.15-tag2

for you to fetch changes up to 148bcca9ad0488d623aa36b21ac152bb056a1ae4:

  soc: renesas: Prefer memcpy() over strcpy() (2021-08-12 12:36:57 +0200)

----------------------------------------------------------------
Renesas driver updates for v5.15 (take two)

  - Prefer memcpy() over strcpy().

----------------------------------------------------------------
Len Baker (1):
      soc: renesas: Prefer memcpy() over strcpy()

 drivers/soc/renesas/r8a779a0-sysc.c | 6 ++++--
 drivers/soc/renesas/rcar-sysc.c     | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)


From geert+renesas at glider.be  Fri Aug 13 03:22:35 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 13 Aug 2021 12:22:35 +0200
Subject: [GIT PULL 1/2] Renesas ARM DT updates for v5.15 (take two)
In-Reply-To: <cover.1628849621.git.geert+renesas@glider.be>
References: <cover.1628849621.git.geert+renesas@glider.be>
Message-ID: <cover.1628849623.git.geert+renesas@glider.be>

The following changes since commit 651f8cffade8615bb4fce1ecb3a929892c5e60d7:

  arm64: dts: renesas: r8a77961: Add iommus to ipmmu_ds[01] related nodes (2021-07-30 15:07:25 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-arm-dt-for-v5.15-tag2

for you to fetch changes up to 13bf92e6dec0e2be1ef0c7dd483f2d8b34eaa905:

  dt-bindings: i2c: renesas,riic: Make interrupt-names required (2021-08-12 12:43:41 +0200)

----------------------------------------------------------------
Renesas ARM DT updates for v5.15 (take two)

  - Pin control, ADC, and CANFD support for the RZ/G2L SoC,
  - Add interrupt-names properties to the Renesas RZ/A and RZ/G2L I2C
    Bus Interface.

----------------------------------------------------------------
Geert Uytterhoeven (5):
      Merge tag 'renesas-r9a07g044-dt-binding-defs-tag2' into HEAD
      dt-bindings: i2c: renesas,riic: Add interrupt-names
      ARM: dts: rza: Add I2C interrupt-names
      arm64: dts: renesas: r9a07g044: Add I2C interrupt-names
      dt-bindings: i2c: renesas,riic: Make interrupt-names required

Lad Prabhakar (4):
      dt-bindings: clock: r9a07g044-cpg: Add entry for P0_DIV2 core clock
      arm64: dts: renesas: r9a07g044: Add pinctrl node
      arm64: dts: renesas: r9a07g044: Add ADC node
      arm64: dts: renesas: r9a07g044: Add CANFD node

 .../devicetree/bindings/i2c/renesas,riic.yaml      |  30 ++++--
 arch/arm/boot/dts/r7s72100.dtsi                    |   8 ++
 arch/arm/boot/dts/r7s9210.dtsi                     |   8 ++
 arch/arm64/boot/dts/renesas/r9a07g044.dtsi         | 104 +++++++++++++++++++++
 include/dt-bindings/clock/r9a07g044-cpg.h          |   1 +
 5 files changed, 143 insertions(+), 8 deletions(-)


From geert+renesas at glider.be  Fri Aug 13 03:22:34 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 13 Aug 2021 12:22:34 +0200
Subject: [GIT PULL 0/2] Renesas SoC updates for v5.15 (take two)
Message-ID: <cover.1628849621.git.geert+renesas@glider.be>

	Hi soc folks,

This is my second pull request for the inclusion of Renesas SoC updates
for v5.15.

It consists of two parts:

  [GIT PULL 1/2] Renesas ARM DT updates for v5.15 (take two)

    - Pin control, ADC, and CANFD support for the RZ/G2L SoC,
    - Add interrupt-names properties to the Renesas RZ/A and RZ/G2L I2C
      Bus Interface.

  [GIT PULL 2/2] Renesas driver updates for v5.15 (take two)

    - Prefer memcpy() over strcpy().

Note that the first part includes another update (append-only) to the
Renesas RZ/G2L DT Binding Definitions, which are shared by driver and DT
source files, and thus included in multiple pull requests:
  - "[GIT PULL] clk: renesas: Updates for v5.15" (for clk),
  - "[GIT PULL 1/2] Renesas ARM DT updates for v5.15 (take two)" (for
    soc).

Thanks for pulling!

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


From oupton at google.com  Fri Aug 13 03:39:42 2021
From: oupton at google.com (Oliver Upton)
Date: Fri, 13 Aug 2021 03:39:42 -0700
Subject: [PATCH v6 01/21] KVM: x86: Fix potential race in KVM_GET_CLOCK
In-Reply-To: <78eeaf83-2bfa-8452-1301-a607fba7fa0c@redhat.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-2-oupton@google.com>
 <78eeaf83-2bfa-8452-1301-a607fba7fa0c@redhat.com>
Message-ID: <CAOQ_QsiwzKpaXUadGR6cWC2k0pg1P4QgkAxNdo0gpVAP1P3hSQ@mail.gmail.com>

Hi Paolo,

On Wed, Aug 11, 2021 at 5:23 AM Paolo Bonzini <pbonzini at redhat.com> wrote:
>
> On 04/08/21 10:57, Oliver Upton wrote:
> > Sean noticed that KVM_GET_CLOCK was checking kvm_arch.use_master_clock
> > outside of the pvclock sync lock. This is problematic, as the clock
> > value written to the user may or may not actually correspond to a stable
> > TSC.
> >
> > Fix the race by populating the entire kvm_clock_data structure behind
> > the pvclock_gtod_sync_lock.
> >
> > Suggested-by: Sean Christopherson <seanjc at google.com>
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > ---
> >   arch/x86/kvm/x86.c | 39 ++++++++++++++++++++++++++++-----------
> >   1 file changed, 28 insertions(+), 11 deletions(-)
>
> I had a completely independent patch that fixed the same race.  It unifies
> the read sides of tsc_write_lock and pvclock_gtod_sync_lock into a seqcount
> (and replaces pvclock_gtod_sync_lock with kvm->lock on the write side).

Might it make sense to fix this issue under the existing locking
scheme, then shift to what you're proposing? I say that, but the
locking change in 03/21 would most certainly have a short lifetime
until this patch supersedes it.

> I attach it now (based on https://lore.kernel.org/kvm/20210811102356.3406687-1-pbonzini at redhat.com/T/#t),
> but the testing was extremely light so I'm not sure I will be able to include
> it in 5.15.
>
> Paolo
>
> -------------- 8< -------------
> From: Paolo Bonzini <pbonzini at redhat.com>
> Date: Thu, 8 Apr 2021 05:03:44 -0400
> Subject: [PATCH] kvm: x86: protect masterclock with a seqcount
>
> Protect the reference point for kvmclock with a seqcount, so that
> kvmclock updates for all vCPUs can proceed in parallel.  Xen runstate
> updates will also run in parallel and not bounce the kvmclock cacheline.
>
> This also makes it possible to use KVM_REQ_CLOCK_UPDATE (which will
> block on the seqcount) to prevent entering in the guests until
> pvclock_update_vm_gtod_copy is complete, and thus to get rid of
> KVM_REQ_MCLOCK_INPROGRESS.
>
> nr_vcpus_matched_tsc is updated outside pvclock_update_vm_gtod_copy
> though, so a spinlock must be kept for that one.
>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
>
> diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/locking.rst
> index 8138201efb09..ed41da172e02 100644
> --- a/Documentation/virt/kvm/locking.rst
> +++ b/Documentation/virt/kvm/locking.rst
> @@ -29,6 +29,8 @@ The acquisition orders for mutexes are as follows:
>
>   On x86:
>
> +- the seqcount kvm->arch.pvclock_sc is written under kvm->lock.
> +
>   - vcpu->mutex is taken outside kvm->arch.hyperv.hv_lock
>
>   - kvm->arch.mmu_lock is an rwlock.  kvm->arch.tdp_mmu_pages_lock is
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 20daaf67a5bf..6889aab92362 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -68,8 +68,7 @@
>   #define KVM_REQ_PMI                   KVM_ARCH_REQ(11)
>   #define KVM_REQ_SMI                   KVM_ARCH_REQ(12)
>   #define KVM_REQ_MASTERCLOCK_UPDATE    KVM_ARCH_REQ(13)
> -#define KVM_REQ_MCLOCK_INPROGRESS \
> -       KVM_ARCH_REQ_FLAGS(14, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
> +/* 14 unused */
>   #define KVM_REQ_SCAN_IOAPIC \
>         KVM_ARCH_REQ_FLAGS(15, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
>   #define KVM_REQ_GLOBAL_CLOCK_UPDATE   KVM_ARCH_REQ(16)
> @@ -1067,6 +1066,11 @@ struct kvm_arch {
>
>         unsigned long irq_sources_bitmap;
>         s64 kvmclock_offset;
> +
> +       /*
> +        * This also protects nr_vcpus_matched_tsc which is read from a
> +        * preemption-disabled region, so it must be a raw spinlock.
> +        */
>         raw_spinlock_t tsc_write_lock;
>         u64 last_tsc_nsec;
>         u64 last_tsc_write;
> @@ -1077,7 +1081,7 @@ struct kvm_arch {
>         u64 cur_tsc_generation;
>         int nr_vcpus_matched_tsc;
>
> -       spinlock_t pvclock_gtod_sync_lock;
> +       seqcount_mutex_t pvclock_sc;
>         bool use_master_clock;
>         u64 master_kernel_ns;
>         u64 master_cycle_now;
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 74145a3fd4f2..7d73c5560260 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2533,9 +2533,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
>         vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
>
>         kvm_vcpu_write_tsc_offset(vcpu, offset);
> -       raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
>
> -       spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags);
>         if (!matched) {
>                 kvm->arch.nr_vcpus_matched_tsc = 0;
>         } else if (!already_matched) {
> @@ -2543,7 +2541,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
>         }
>
>         kvm_track_tsc_matching(vcpu);
> -       spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags);
> +       raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
>   }
>
>   static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
> @@ -2730,9 +2728,7 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm)
>         struct kvm_arch *ka = &kvm->arch;
>         int vclock_mode;
>         bool host_tsc_clocksource, vcpus_matched;
> -
> -       vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 ==
> -                       atomic_read(&kvm->online_vcpus));
> +       unsigned long flags;
>
>         /*
>          * If the host uses TSC clock, then passthrough TSC as stable
> @@ -2742,9 +2738,14 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm)
>                                         &ka->master_kernel_ns,
>                                         &ka->master_cycle_now);
>
> +       raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
> +       vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 ==
> +                       atomic_read(&kvm->online_vcpus));
> +
>         ka->use_master_clock = host_tsc_clocksource && vcpus_matched
>                                 && !ka->backwards_tsc_observed
>                                 && !ka->boot_vcpu_runs_old_kvmclock;
> +       raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
>
>         if (ka->use_master_clock)
>                 atomic_set(&kvm_guest_has_master_clock, 1);
> @@ -2758,25 +2759,26 @@ static void pvclock_update_vm_gtod_copy(struct kvm *kvm)
>   static void kvm_start_pvclock_update(struct kvm *kvm)
>   {
>         struct kvm_arch *ka = &kvm->arch;
> -       kvm_make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS);
>
> -       /* no guest entries from this point */
> -       spin_lock_irq(&ka->pvclock_gtod_sync_lock);
> +       mutex_lock(&kvm->lock);
> +       /*
> +        * write_seqcount_begin disables preemption.  This is needed not just
> +        * to avoid livelock, but also because the preempt notifier is a reader
> +        * for ka->pvclock_sc.
> +        */
> +       write_seqcount_begin(&ka->pvclock_sc);
> +       kvm_make_all_cpus_request(kvm,
> +               KVM_REQ_CLOCK_UPDATE | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP);
> +
> +       /* no guest entries from this point until write_seqcount_end */
>   }
>
>   static void kvm_end_pvclock_update(struct kvm *kvm)
>   {
>         struct kvm_arch *ka = &kvm->arch;
> -       struct kvm_vcpu *vcpu;
> -       int i;
>
> -       spin_unlock_irq(&ka->pvclock_gtod_sync_lock);
> -       kvm_for_each_vcpu(i, vcpu, kvm)
> -               kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
> -
> -       /* guest entries allowed */
> -       kvm_for_each_vcpu(i, vcpu, kvm)
> -               kvm_clear_request(KVM_REQ_MCLOCK_INPROGRESS, vcpu);
> +       write_seqcount_end(&ka->pvclock_sc);
> +       mutex_unlock(&kvm->lock);
>   }
>
>   static void kvm_update_masterclock(struct kvm *kvm)
> @@ -2787,27 +2789,21 @@ static void kvm_update_masterclock(struct kvm *kvm)
>         kvm_end_pvclock_update(kvm);
>   }
>
> -u64 get_kvmclock_ns(struct kvm *kvm)
> +static u64 __get_kvmclock_ns(struct kvm *kvm)
>   {
>         struct kvm_arch *ka = &kvm->arch;
>         struct pvclock_vcpu_time_info hv_clock;
> -       unsigned long flags;
>         u64 ret;
>
> -       spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
> -       if (!ka->use_master_clock) {
> -               spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
> +       if (!ka->use_master_clock)
>                 return get_kvmclock_base_ns() + ka->kvmclock_offset;
> -       }
> -
> -       hv_clock.tsc_timestamp = ka->master_cycle_now;
> -       hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
> -       spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
>
>         /* both __this_cpu_read() and rdtsc() should be on the same cpu */
>         get_cpu();
>
>         if (__this_cpu_read(cpu_tsc_khz)) {
> +               hv_clock.tsc_timestamp = ka->master_cycle_now;
> +               hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
>                 kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
>                                    &hv_clock.tsc_shift,
>                                    &hv_clock.tsc_to_system_mul);
> @@ -2816,6 +2812,19 @@ u64 get_kvmclock_ns(struct kvm *kvm)
>                 ret = get_kvmclock_base_ns() + ka->kvmclock_offset;
>
>         put_cpu();
> +       return ret;
> +}
> +
> +u64 get_kvmclock_ns(struct kvm *kvm)
> +{
> +       struct kvm_arch *ka = &kvm->arch;
> +       unsigned seq;
> +       u64 ret;
> +
> +       do {
> +               seq = read_seqcount_begin(&ka->pvclock_sc);
> +               ret = __get_kvmclock_ns(kvm);
> +       } while (read_seqcount_retry(&ka->pvclock_sc, seq));
>
>         return ret;
>   }
> @@ -2882,6 +2891,7 @@ static void kvm_setup_pvclock_page(struct kvm_vcpu *v,
>   static int kvm_guest_time_update(struct kvm_vcpu *v)
>   {
>         unsigned long flags, tgt_tsc_khz;
> +       unsigned seq;
>         struct kvm_vcpu_arch *vcpu = &v->arch;
>         struct kvm_arch *ka = &v->kvm->arch;
>         s64 kernel_ns;
> @@ -2896,13 +2906,14 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
>          * If the host uses TSC clock, then passthrough TSC as stable
>          * to the guest.
>          */
> -       spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
> -       use_master_clock = ka->use_master_clock;
> -       if (use_master_clock) {
> -               host_tsc = ka->master_cycle_now;
> -               kernel_ns = ka->master_kernel_ns;
> -       }
> -       spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
> +       seq = read_seqcount_begin(&ka->pvclock_sc);
> +       do {
> +               use_master_clock = ka->use_master_clock;
> +               if (use_master_clock) {
> +                       host_tsc = ka->master_cycle_now;
> +                       kernel_ns = ka->master_kernel_ns;
> +               }
> +       } while (read_seqcount_retry(&ka->pvclock_sc, seq));
>
>         /* Keep irq disabled to prevent changes to the clock */
>         local_irq_save(flags);
> @@ -6098,11 +6109,13 @@ long kvm_arch_vm_ioctl(struct file *filp,
>         }
>         case KVM_GET_CLOCK: {
>                 struct kvm_clock_data user_ns;
> -               u64 now_ns;
> +               unsigned seq;
>
> -               now_ns = get_kvmclock_ns(kvm);
> -               user_ns.clock = now_ns;
> -               user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0;
> +               do {
> +                       seq = read_seqcount_begin(&kvm->arch.pvclock_sc);
> +                       user_ns.clock = __get_kvmclock_ns(kvm);
> +                       user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0;
> +               } while (read_seqcount_retry(&kvm->arch.pvclock_sc, seq));
>                 memset(&user_ns.pad, 0, sizeof(user_ns.pad));
>
>                 r = -EFAULT;
> @@ -11144,8 +11157,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>
>         raw_spin_lock_init(&kvm->arch.tsc_write_lock);
>         mutex_init(&kvm->arch.apic_map_lock);
> -       spin_lock_init(&kvm->arch.pvclock_gtod_sync_lock);
> -
> +       seqcount_mutex_init(&kvm->arch.pvclock_sc, &kvm->lock);
>         kvm->arch.kvmclock_offset = -get_kvmclock_base_ns();
>         pvclock_update_vm_gtod_copy(kvm);
>
>

This all looks good to me, so:

Reviewed-by: Oliver Upton <oupton at google.com>

Definitely supplants 03/21 from my series. If you'd rather take your
own for this entire series then I can rework around this patch and
resend.

--
Thanks,
Oliver


From lkp at intel.com  Fri Aug 13 03:41:00 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 18:41:00 +0800
Subject: [soc:arm/dt] BUILD SUCCESS
 81b6a285737700c2e04ef0893617b80481b6b4b7
Message-ID: <61164c3c.edOinBotsu0AlP8h%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/dt
branch HEAD: 81b6a285737700c2e04ef0893617b80481b6b4b7  Merge tag 'omap-for-v5.15/dt-am3-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/dt

elapsed time: 723m

configs tested: 142
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
arm                    vt8500_v6_v7_defconfig
sh                           se7751_defconfig
powerpc                     ep8248e_defconfig
sh                           sh2007_defconfig
m68k                        stmark2_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
mips                          ath25_defconfig
s390                          debug_defconfig
openrisc                  or1klitex_defconfig
arc                    vdk_hs38_smp_defconfig
csky                                defconfig
mips                           ip32_defconfig
xtensa                              defconfig
sh                          polaris_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
arm                     davinci_all_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
riscv                             allnoconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                     ppa8548_defconfig
powerpc                        icon_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 03:41:09 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 18:41:09 +0800
Subject: [soc:for-next] BUILD SUCCESS ffc192c8170562be3fd1c0ccbe6001e915d997d7
Message-ID: <61164c45.n6vuSWzQAJSzLePb%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: ffc192c8170562be3fd1c0ccbe6001e915d997d7  soc: document merges

elapsed time: 723m

configs tested: 129
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
arm                       aspeed_g4_defconfig
mips                        qi_lb60_defconfig
powerpc                       holly_defconfig
sh                              ul2_defconfig
sh                           se7619_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
mips                          ath25_defconfig
s390                          debug_defconfig
openrisc                  or1klitex_defconfig
arc                    vdk_hs38_smp_defconfig
csky                                defconfig
mips                           ip32_defconfig
xtensa                              defconfig
sh                          polaris_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
mips                        workpad_defconfig
mips                     decstation_defconfig
powerpc                        cell_defconfig
powerpc                     ppa8548_defconfig
arc                        nsimosci_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                        icon_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Aug 13 03:41:06 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 18:41:06 +0800
Subject: [soc:arm/defconfig] BUILD SUCCESS
 20904527a70de3aff43edafdf5d18b0f6f976f59
Message-ID: <61164c42.uWwbFr6/oo/3vMQY%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/defconfig
branch HEAD: 20904527a70de3aff43edafdf5d18b0f6f976f59  Merge tag 'amlogic-arm-configs-for-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux into arm/defconfig

elapsed time: 723m

configs tested: 122
configs skipped: 91

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
arm                       aspeed_g4_defconfig
mips                        qi_lb60_defconfig
powerpc                       holly_defconfig
sh                              ul2_defconfig
sh                           se7619_defconfig
mips                  maltasmvp_eva_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
mips                          ath25_defconfig
s390                          debug_defconfig
openrisc                  or1klitex_defconfig
arc                    vdk_hs38_smp_defconfig
csky                                defconfig
mips                           ip32_defconfig
xtensa                              defconfig
sh                          polaris_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                     ppa8548_defconfig
powerpc                        icon_defconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From pbonzini at redhat.com  Fri Aug 13 03:44:26 2021
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Fri, 13 Aug 2021 12:44:26 +0200
Subject: [PATCH v6 01/21] KVM: x86: Fix potential race in KVM_GET_CLOCK
In-Reply-To: <CAOQ_QsiwzKpaXUadGR6cWC2k0pg1P4QgkAxNdo0gpVAP1P3hSQ@mail.gmail.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-2-oupton@google.com>
 <78eeaf83-2bfa-8452-1301-a607fba7fa0c@redhat.com>
 <CAOQ_QsiwzKpaXUadGR6cWC2k0pg1P4QgkAxNdo0gpVAP1P3hSQ@mail.gmail.com>
Message-ID: <0b415872-7a67-d38b-ae01-62c38b365be0@redhat.com>

On 13/08/21 12:39, Oliver Upton wrote:
> Might it make sense to fix this issue under the existing locking
> scheme, then shift to what you're proposing? I say that, but the
> locking change in 03/21 would most certainly have a short lifetime
> until this patch supersedes it.

Yes, definitely.  The seqcount change would definitely go in much later. 
  Extracting KVM_{GET,SET}_CLOCK to separate function would also be a 
patch of its own.  Give me a few more days of frantic KVM Forum 
preparation. :)

Paolo



From clin at suse.com  Fri Aug 13 04:11:04 2021
From: clin at suse.com (Chester Lin)
Date: Fri, 13 Aug 2021 19:11:04 +0800
Subject: [PATCH 2/8] dt-bindings: serial: fsl-linflexuart: convert to
 json-schema format
In-Reply-To: <1ff13837-e6ca-c476-376d-b4f80450a259@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-3-clin@suse.com>
 <1ff13837-e6ca-c476-376d-b4f80450a259@suse.de>
Message-ID: <YRZTSJPFLFFIR+gx@linux-8mug>

Hi Andreas,

On Thu, Aug 12, 2021 at 06:04:44PM +0200, Andreas F?rber wrote:
> On 05.08.21 08:54, Chester Lin wrote:
> > Convert the FSL LINFlexD UART binding to json-schema.
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  .../bindings/serial/fsl,s32-linflexuart.txt   | 22 ---------
> >  .../bindings/serial/fsl,s32-linflexuart.yaml  | 48 +++++++++++++++++++
> >  2 files changed, 48 insertions(+), 22 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> >  create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> 
> Thanks for your effort, Chester.
> 
> > diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> > deleted file mode 100644
> > index f1bbe0826be5..000000000000
> > --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> > +++ /dev/null
> > @@ -1,22 +0,0 @@
> > -* Freescale LINFlexD UART
> > -
> > -The LINFlexD controller implements several LIN protocol versions, as well as
> > -support for full-duplex UART communication through 8-bit and 9-bit frames.
> > -
> > -See chapter 47 ("LINFlexD") in the reference manual[1].
> > -
> > -Required properties:
> > -- compatible :
> > -  - "fsl,s32v234-linflexuart" for LINFlexD configured in UART mode, which
> > -    is compatible with the one integrated on S32V234 SoC
> > -- reg : Address and length of the register set for the device
> > -- interrupts : Should contain uart interrupt
> > -
> > -Example:
> > -uart0: serial at 40053000 {
> > -	compatible = "fsl,s32v234-linflexuart";
> > -	reg = <0x0 0x40053000 0x0 0x1000>;
> > -	interrupts = <0 59 4>;
> > -};
> > -
> > -[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM
> > diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > new file mode 100644
> > index 000000000000..acfe34706ccb
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > @@ -0,0 +1,48 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> 
> Since this is dual-licensed and BSD-2-Clause would seem compatible with
> GPLv3, this could probably be s/GPL-2.0-only/GPL-2.0-or-later/ ? Not a
> blocker.

There's no license identifier in the original file so it's not a problem to
choose "GPL-2.0-or-later".

> 
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/serial/fsl,s32-linflexuart.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Freescale LINFlexD UART
> > +
> > +description: |
> > +  The LINFlexD controller implements several LIN protocol versions, as well
> > +  as support for full-duplex UART communication through 8-bit and 9-bit
> > +  frames. See chapter 47 ("LINFlexD") in the reference manual
> > +  https://www.nxp.com/webapp/Download?colCode=S32V234RM.
> > +
> > +maintainers:
> > +  - Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> > +  - Rob Herring <robh at kernel.org>
> 
> @Shawn: I assume we need both of them to ack this (or an S32V maintainer
> to volunteer), since they were not named in the .txt file before?
> 
> > +
> > +allOf:
> > +  - $ref: "serial.yaml"
> > +
> > +properties:
> > +  compatible:
> > +    description: The LINFlexD controller on S32V234 SoC, which can be
> > +      configured in UART mode.
> > +    items:
> > +      - const: fsl,s32v234-linflexuart
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    serial at 40053000 {
> > +        compatible = "fsl,s32v234-linflexuart";
> > +        reg = <0x40053000 0x1000>;
> > +        interrupts = <0 59 4>;
> > +    };
> 
> Otherwise looking sane,
> 
> Reviewed-by: Andreas F?rber <afaerber at suse.de>
> 
> Thanks,
> Andreas
> 
> -- 
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 N?rnberg, Germany
> GF: Felix Imend?rffer
> HRB 36809 (AG N?rnberg)
> 



From krzk at kernel.org  Fri Aug 13 04:28:40 2021
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 13 Aug 2021 13:28:40 +0200
Subject: [PATCH 2/8] dt-bindings: serial: fsl-linflexuart: convert to
 json-schema format
In-Reply-To: <YRZTSJPFLFFIR+gx@linux-8mug>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-3-clin@suse.com>
 <1ff13837-e6ca-c476-376d-b4f80450a259@suse.de> <YRZTSJPFLFFIR+gx@linux-8mug>
Message-ID: <0b42dc7e-a7c1-fe41-e39a-89627d44cbe4@kernel.org>

On 13/08/2021 13:11, Chester Lin wrote:
> Hi Andreas,
> 
> On Thu, Aug 12, 2021 at 06:04:44PM +0200, Andreas F?rber wrote:
>> On 05.08.21 08:54, Chester Lin wrote:
>>> Convert the FSL LINFlexD UART binding to json-schema.
>>>
>>> Signed-off-by: Chester Lin <clin at suse.com>
>>> ---
>>>  .../bindings/serial/fsl,s32-linflexuart.txt   | 22 ---------
>>>  .../bindings/serial/fsl,s32-linflexuart.yaml  | 48 +++++++++++++++++++
>>>  2 files changed, 48 insertions(+), 22 deletions(-)
>>>  delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
>>>  create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
>>
>> Thanks for your effort, Chester.
>>
>>> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
>>> deleted file mode 100644
>>> index f1bbe0826be5..000000000000
>>> --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
>>> +++ /dev/null
>>> @@ -1,22 +0,0 @@
>>> -* Freescale LINFlexD UART
>>> -
>>> -The LINFlexD controller implements several LIN protocol versions, as well as
>>> -support for full-duplex UART communication through 8-bit and 9-bit frames.
>>> -
>>> -See chapter 47 ("LINFlexD") in the reference manual[1].
>>> -
>>> -Required properties:
>>> -- compatible :
>>> -  - "fsl,s32v234-linflexuart" for LINFlexD configured in UART mode, which
>>> -    is compatible with the one integrated on S32V234 SoC
>>> -- reg : Address and length of the register set for the device
>>> -- interrupts : Should contain uart interrupt
>>> -
>>> -Example:
>>> -uart0: serial at 40053000 {
>>> -	compatible = "fsl,s32v234-linflexuart";
>>> -	reg = <0x0 0x40053000 0x0 0x1000>;
>>> -	interrupts = <0 59 4>;
>>> -};
>>> -
>>> -[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM
>>> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
>>> new file mode 100644
>>> index 000000000000..acfe34706ccb
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
>>> @@ -0,0 +1,48 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>
>> Since this is dual-licensed and BSD-2-Clause would seem compatible with
>> GPLv3, this could probably be s/GPL-2.0-only/GPL-2.0-or-later/ ? Not a
>> blocker.
> 
> There's no license identifier in the original file so it's not a problem to
> choose "GPL-2.0-or-later".

That is not entirely correct. If there is no explicit license in the
file, it's kernel's default so GPL-2.0-only. You cannot relicense
derivative work without getting permission from authors and copyright
holders.

However if you did not copy the text/description from original bindings,
your work won't be derivative so you can relicense it.

Best regards,
Krzysztof


From dan.carpenter at oracle.com  Fri Aug 13 04:33:38 2021
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Fri, 13 Aug 2021 14:33:38 +0300
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference in
 probe
Message-ID: <20210813113338.GA30697@kili>

If devm_regulator_get_optional() returns an error pointer, then we
should return it to the user.  The current code makes an exception
for -ENODEV that will result in an error pointer dereference on the
next line when it calls regulator_enable().  Remove the exception.

Fixes: e1229e884e19 ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver")
Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
---
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 20cef2e06f66..2d0ffd3c4e16 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -225,9 +225,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
 	/* DON'T MOVE ME: must be enable before PHY init */
 	rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
 	if (IS_ERR(rockchip->vpcie3v3))
-		if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV)
-			return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
-					"failed to get vpcie3v3 regulator\n");
+		return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
+				     "failed to get vpcie3v3 regulator\n");
 
 	ret = regulator_enable(rockchip->vpcie3v3);
 	if (ret) {
-- 
2.20.1



From lkp at intel.com  Fri Aug 13 04:33:26 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 13 Aug 2021 19:33:26 +0800
Subject: [xlnx:xlnx_rebase_v5.10 813/1761]
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1141:3: warning:
 comparison of distinct pointer types ('unsigned long *' and 'typeof (flags)
 *' (aka 'unsigned int *'))
Message-ID: <202108131920.UYU6n66W-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   e14d4574ca81a569ee6d07e03271f2ae2dad38e4
commit: 1b5d1c43433b3ec5407db48688e717285e7edafe [813/1761] net: xilinx: axiethernet: Add check for transmit data FIFO vacancy
config: s390-randconfig-r012-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/1b5d1c43433b3ec5407db48688e717285e7edafe
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 1b5d1c43433b3ec5407db48688e717285e7edafe
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
                     ^
   In file included from drivers/net/ethernet/xilinx/xilinx_axienet_main.c:28:
   In file included from include/linux/etherdevice.h:20:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
                     ^
   In file included from drivers/net/ethernet/xilinx/xilinx_axienet_main.c:28:
   In file included from include/linux/etherdevice.h:20:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
                     ^
   In file included from drivers/net/ethernet/xilinx/xilinx_axienet_main.c:28:
   In file included from include/linux/etherdevice.h:20:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32'
           __fswab32(x))
                     ^
   In file included from drivers/net/ethernet/xilinx/xilinx_axienet_main.c:28:
   In file included from include/linux/etherdevice.h:20:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:31:
   In file included from include/linux/dma-mapping.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1141:3: warning: comparison of distinct pointer types ('unsigned long *' and 'typeof (flags) *' (aka 'unsigned int *')) [-Wcompare-distinct-pointer-types]
                   spin_lock_irqsave(&lp->ptp_tx_lock, flags);
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/spinlock.h:384:2: note: expanded from macro 'spin_lock_irqsave'
           raw_spin_lock_irqsave(spinlock_check(lock), flags);     \
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/spinlock.h:251:3: note: expanded from macro 'raw_spin_lock_irqsave'
                   typecheck(unsigned long, flags);        \
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/typecheck.h:12:18: note: expanded from macro 'typecheck'
           (void)(&__dummy == &__dummy2); \
                  ~~~~~~~~ ^  ~~~~~~~~~
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:702:12: warning: unused function 'axienet_free_tx_chain' [-Wunused-function]
   static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
              ^
   In file included from drivers/net/ethernet/xilinx/xilinx_axienet_main.c:25:
   In file included from include/linux/clk.h:13:
   In file included from include/linux/kernel.h:12:
   In file included from include/linux/bitops.h:29:
   arch/s390/include/asm/bitops.h:90:4: error: invalid operand in inline asm: 'ni	$0,${1:b}'
                           "ni     %0,%b1\n"
                           ^
   arch/s390/include/asm/bitops.h:90:4: error: invalid operand in inline asm: 'ni	$0,${1:b}'
   arch/s390/include/asm/bitops.h:90:4: error: invalid operand in inline asm: 'ni	$0,${1:b}'
   arch/s390/include/asm/bitops.h:69:4: error: invalid operand in inline asm: 'oi	$0,${1:b}'
                           "oi     %0,%b1\n"
                           ^
   arch/s390/include/asm/bitops.h:69:4: error: invalid operand in inline asm: 'oi	$0,${1:b}'
   22 warnings and 5 errors generated.


vim +1141 drivers/net/ethernet/xilinx/xilinx_axienet_main.c

  1118	
  1119		if (msg_type == TX_TS_OP_NOOP) {
  1120			buf[0] = TX_TS_OP_NOOP;
  1121		} else if (msg_type == TX_TS_OP_ONESTEP) {
  1122			buf[0] = TX_TS_OP_ONESTEP;
  1123			buf[1] = TX_TS_CSUM_UPDATE;
  1124			buf[4] = TX_PTP_TS_OFFSET;
  1125			buf[6] = TX_PTP_CSUM_OFFSET;
  1126		} else {
  1127			buf[0] = TX_TS_OP_TWOSTEP;
  1128			buf[2] = cur_p->ptp_tx_ts_tag & 0xFF;
  1129			buf[3] = (cur_p->ptp_tx_ts_tag >> 8) & 0xFF;
  1130		}
  1131	
  1132		if (lp->axienet_config->mactype == XAXIENET_1G ||
  1133		    lp->axienet_config->mactype == XAXIENET_2_5G) {
  1134			memcpy(&val, buf, AXIENET_TS_HEADER_LEN);
  1135			swab64s(&val);
  1136			memcpy(buf, &val, AXIENET_TS_HEADER_LEN);
  1137		} else if (lp->axienet_config->mactype == XAXIENET_10G_25G ||
  1138			   lp->axienet_config->mactype == XAXIENET_MRMAC) {
  1139			memcpy(&tmp, buf, XXVENET_TS_HEADER_LEN);
  1140			/* Check for Transmit Data FIFO Vacancy */
> 1141			spin_lock_irqsave(&lp->ptp_tx_lock, flags);
  1142			if (!axienet_txts_ior(lp, XAXIFIFO_TXTS_TDFV)) {
  1143				spin_unlock_irqrestore(&lp->ptp_tx_lock, flags);
  1144				return NETDEV_TX_BUSY;
  1145			}
  1146			axienet_txts_iow(lp, XAXIFIFO_TXTS_TXFD, tmp);
  1147			axienet_txts_iow(lp, XAXIFIFO_TXTS_TLR,
  1148					 XXVENET_TS_HEADER_LEN);
  1149			spin_unlock_irqrestore(&lp->ptp_tx_lock, flags);
  1150		}
  1151	
  1152		return 0;
  1153	}
  1154	#endif
  1155	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 32779 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/88af4840/attachment-0001.gz>

From clin at suse.com  Fri Aug 13 04:43:17 2021
From: clin at suse.com (Chester Lin)
Date: Fri, 13 Aug 2021 19:43:17 +0800
Subject: [PATCH 2/8] dt-bindings: serial: fsl-linflexuart: convert to
 json-schema format
In-Reply-To: <0b42dc7e-a7c1-fe41-e39a-89627d44cbe4@kernel.org>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-3-clin@suse.com>
 <1ff13837-e6ca-c476-376d-b4f80450a259@suse.de>
 <YRZTSJPFLFFIR+gx@linux-8mug>
 <0b42dc7e-a7c1-fe41-e39a-89627d44cbe4@kernel.org>
Message-ID: <YRZa1ZX0gJb/yDrw@linux-8mug>

On Fri, Aug 13, 2021 at 01:28:40PM +0200, Krzysztof Kozlowski wrote:
> On 13/08/2021 13:11, Chester Lin wrote:
> > Hi Andreas,
> > 
> > On Thu, Aug 12, 2021 at 06:04:44PM +0200, Andreas F?rber wrote:
> >> On 05.08.21 08:54, Chester Lin wrote:
> >>> Convert the FSL LINFlexD UART binding to json-schema.
> >>>
> >>> Signed-off-by: Chester Lin <clin at suse.com>
> >>> ---
> >>>  .../bindings/serial/fsl,s32-linflexuart.txt   | 22 ---------
> >>>  .../bindings/serial/fsl,s32-linflexuart.yaml  | 48 +++++++++++++++++++
> >>>  2 files changed, 48 insertions(+), 22 deletions(-)
> >>>  delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> >>>  create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> >>
> >> Thanks for your effort, Chester.
> >>
> >>> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> >>> deleted file mode 100644
> >>> index f1bbe0826be5..000000000000
> >>> --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> >>> +++ /dev/null
> >>> @@ -1,22 +0,0 @@
> >>> -* Freescale LINFlexD UART
> >>> -
> >>> -The LINFlexD controller implements several LIN protocol versions, as well as
> >>> -support for full-duplex UART communication through 8-bit and 9-bit frames.
> >>> -
> >>> -See chapter 47 ("LINFlexD") in the reference manual[1].
> >>> -
> >>> -Required properties:
> >>> -- compatible :
> >>> -  - "fsl,s32v234-linflexuart" for LINFlexD configured in UART mode, which
> >>> -    is compatible with the one integrated on S32V234 SoC
> >>> -- reg : Address and length of the register set for the device
> >>> -- interrupts : Should contain uart interrupt
> >>> -
> >>> -Example:
> >>> -uart0: serial at 40053000 {
> >>> -	compatible = "fsl,s32v234-linflexuart";
> >>> -	reg = <0x0 0x40053000 0x0 0x1000>;
> >>> -	interrupts = <0 59 4>;
> >>> -};
> >>> -
> >>> -[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM
> >>> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> >>> new file mode 100644
> >>> index 000000000000..acfe34706ccb
> >>> --- /dev/null
> >>> +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> >>> @@ -0,0 +1,48 @@
> >>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >>
> >> Since this is dual-licensed and BSD-2-Clause would seem compatible with
> >> GPLv3, this could probably be s/GPL-2.0-only/GPL-2.0-or-later/ ? Not a
> >> blocker.
> > 
> > There's no license identifier in the original file so it's not a problem to
> > choose "GPL-2.0-or-later".
> 
> That is not entirely correct. If there is no explicit license in the
> file, it's kernel's default so GPL-2.0-only. You cannot relicense
> derivative work without getting permission from authors and copyright
> holders.
> 
> However if you did not copy the text/description from original bindings,
> your work won't be derivative so you can relicense it.
> 

Sorry for my misunderstanding and thanks for the reminder.

Regards,
Chester



From julia.lawall at inria.fr  Fri Aug 13 04:47:19 2021
From: julia.lawall at inria.fr (Julia Lawall)
Date: Fri, 13 Aug 2021 13:47:19 +0200 (CEST)
Subject: [xlnx:master 11563/12376]
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c:3003:47-48:
 WARNING this kind of initialization is deprecated
 (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialized-var)
 (fwd)
Message-ID: <alpine.DEB.2.22.394.2108131346210.6034@hadrien>

Please check the initialization of a variable to itself on line 3001.

thanks,
julia

---------- Forwarded message ----------
Date: Fri, 13 Aug 2021 18:44:39 +0800
From: kernel test robot <lkp at intel.com>
To: kbuild at lists.01.org
Cc: lkp at intel.com, Julia Lawall <julia.lawall at lip6.fr>
Subject: [xlnx:master 11563/12376]
    drivers/net/ethernet/xilinx/xilinx_axienet_main.c:3003:47-48: WARNING this
    kind of initialization is deprecated
    (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialize
    d-var)

CC: kbuild-all at lists.01.org
CC: linux-arm-kernel at lists.infradead.org
TO: Vishal Sagar <vishal.sagar at xilinx.com>
CC: Michal Simek <monstr at monstr.eu>
CC: Hyun Kwon <hyun.kwon at xilinx.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   af88f405134da108f814cfdf5eac9f2b60f2b800
commit: be1a315c549bd2d6be07219a14335d2e156db988 [11563/12376] staging: xlnxsync: Fix the uapi header license
:::::: branch date: 2 days ago
:::::: commit date: 5 months ago
config: x86_64-randconfig-c022-20210812 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>
Reported-by: Julia Lawall <julia.lawall at lip6.fr>


cocci warnings: (new ones prefixed by >>)
>> drivers/net/ethernet/xilinx/xilinx_axienet_main.c:3003:47-48: WARNING this kind of initialization is deprecated (https://www.kernel.org/doc/html/latest/process/deprecated.html#uninitialized-var)

vim +3003 drivers/net/ethernet/xilinx/xilinx_axienet_main.c

7033a0f491129a Appana Durga Kedareswara Rao 2020-01-24  2986
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2987  /**
2be586205ca2b8 Srikanth Thokala             2015-05-05  2988   * axienet_probe - Axi Ethernet probe function.
95219aa538e11d Srikanth Thokala             2015-05-05  2989   * @pdev:	Pointer to platform device structure.
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2990   *
b0d081c524b46c Michal Simek                 2015-05-05  2991   * Return: 0, on success
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2992   *	    Non-zero error value on failure.
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2993   *
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2994   * This is the probe routine for Axi Ethernet driver. This is called before
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2995   * any other driver routines are invoked. It allocates and sets up the Ethernet
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2996   * device. Parses through device tree and populates fields of
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2997   * axienet_local. It registers the Ethernet device.
8a3b7a252dca9f Daniel Borkmann              2012-01-19  2998   */
2be586205ca2b8 Srikanth Thokala             2015-05-05  2999  static int axienet_probe(struct platform_device *pdev)
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3000  {
4c3b5b0773df3a Appana Durga Kedareswara Rao 2021-01-22  3001  	int (*axienet_clk_init)(struct platform_device *pdev,
4c3b5b0773df3a Appana Durga Kedareswara Rao 2021-01-22  3002  				struct clk **axi_aclk, struct clk **axis_clk,
4c3b5b0773df3a Appana Durga Kedareswara Rao 2021-01-22 @3003  				struct clk **ref_clk, struct clk **tmpclk) =
4c3b5b0773df3a Appana Durga Kedareswara Rao 2021-01-22  3004  					axienet_clk_init;
3135d19569c063 Appana Durga Kedareswara Rao 2021-01-22  3005  	int ret = 0;
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3006  	struct device_node *np;
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3007  	struct axienet_local *lp;
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3008  	struct net_device *ndev;
da90e38003e2f0 Tobias Klauser               2016-12-07  3009  	const void *mac_addr;
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3010  	struct resource *ethres;
8495659bf93c8e Srikanth Thokala             2015-05-05  3011  	u32 value;
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3012  	u16 num_queues = XAE_MAX_QUEUES;
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3013  	bool is_tsn = false;
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3014
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3015  	is_tsn = of_property_read_bool(pdev->dev.of_node, "xlnx,tsn");
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3016  	ret = of_property_read_u16(pdev->dev.of_node, "xlnx,num-queues",
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3017  				   &num_queues);
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3018  	if (ret) {
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3019  		if (!is_tsn) {
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3020  #ifndef CONFIG_AXIENET_HAS_MCDMA
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3021  			num_queues = 1;
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3022  #endif
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3023  		}
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3024  	}
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3025  #ifdef CONFIG_XILINX_TSN
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3026  	if (is_tsn && (num_queues < XAE_TSN_MIN_QUEUES ||
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3027  		       num_queues > XAE_MAX_QUEUES))
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3028  		num_queues = XAE_MAX_QUEUES;
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3029  #endif
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3030
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3031  	ndev = alloc_etherdev_mq(sizeof(*lp), num_queues);
41de8d4cff21a2 Joe Perches                  2012-01-29  3032  	if (!ndev)
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3033  		return -ENOMEM;
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3034
95219aa538e11d Srikanth Thokala             2015-05-05  3035  	platform_set_drvdata(pdev, ndev);
e5971b124969cf Pranavi Somisetty            2021-01-22  3036  #ifdef CONFIG_XILINX_TSN
fb5a7597eefba7 Shravya Kumbham              2021-01-22  3037  	bool slave = false;
e5971b124969cf Pranavi Somisetty            2021-01-22  3038  	if (is_tsn) {
e5971b124969cf Pranavi Somisetty            2021-01-22  3039  		slave = of_property_read_bool(pdev->dev.of_node,
e5971b124969cf Pranavi Somisetty            2021-01-22  3040  					      "xlnx,tsn-slave");
e5971b124969cf Pranavi Somisetty            2021-01-22  3041  		if (slave)
e5971b124969cf Pranavi Somisetty            2021-01-22  3042  			snprintf(ndev->name, sizeof(ndev->name), "eth2");
e5971b124969cf Pranavi Somisetty            2021-01-22  3043  		else
e5971b124969cf Pranavi Somisetty            2021-01-22  3044  			snprintf(ndev->name, sizeof(ndev->name), "eth1");
e5971b124969cf Pranavi Somisetty            2021-01-22  3045  	}
e5971b124969cf Pranavi Somisetty            2021-01-22  3046  #endif
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3047
95219aa538e11d Srikanth Thokala             2015-05-05  3048  	SET_NETDEV_DEV(ndev, &pdev->dev);
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3049  	ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
28e24c62ab3062 Eric Dumazet                 2013-12-02  3050  	ndev->features = NETIF_F_SG;
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3051  	ndev->netdev_ops = &axienet_netdev_ops;
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3052  	ndev->ethtool_ops = &axienet_ethtool_ops;
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3053
d894be57ca92c8 Jarod Wilson                 2016-10-20  3054  	/* MTU range: 64 - 9000 */
d894be57ca92c8 Jarod Wilson                 2016-10-20  3055  	ndev->min_mtu = 64;
d894be57ca92c8 Jarod Wilson                 2016-10-20  3056  	ndev->max_mtu = XAE_JUMBO_MTU;
d894be57ca92c8 Jarod Wilson                 2016-10-20  3057
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3058  	lp = netdev_priv(ndev);
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3059  	lp->ndev = ndev;
95219aa538e11d Srikanth Thokala             2015-05-05  3060  	lp->dev = &pdev->dev;
8a3b7a252dca9f Daniel Borkmann              2012-01-19  3061  	lp->options = XAE_OPTION_DEFAULTS;
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3062  	lp->num_tx_queues = num_queues;
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3063  	lp->num_rx_queues = num_queues;
c5d8859a13f5f3 Saurabh Sengar               2021-01-22  3064  	lp->is_tsn = is_tsn;
8b09ca823ffb4e Robert Hancock               2019-06-06  3065  	lp->rx_bd_num = RX_BD_NUM_DEFAULT;
8b09ca823ffb4e Robert Hancock               2019-06-06  3066  	lp->tx_bd_num = TX_BD_NUM_DEFAULT;
8d6d4d04f7ed81 Saurabh Sengar               2021-01-22  3067

:::::: The code at line 3003 was first introduced by commit
:::::: 4c3b5b0773df3a73938529634e562784458aeb90 net: axienet: Add clock support

:::::: TO: Appana Durga Kedareswara Rao <appana.durga.rao at xilinx.com>
:::::: CC: Michal Simek <michal.simek at xilinx.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 37056 bytes
Desc: 
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/9f7b1370/attachment-0001.gz>

From ben.tseng at mediatek.com  Fri Aug 13 04:54:08 2021
From: ben.tseng at mediatek.com (Ben Tseng)
Date: Fri, 13 Aug 2021 19:54:08 +0800
Subject: [PATCH v8] thermal: mediatek: add another get_temp ops for
 thermal sensors
In-Reply-To: <eeb2a96d-5cd0-ef11-b16e-872d9f3dcb09@linaro.org>
References: <20210603110042.21688-1-ben.tseng@mediatek.com>
 <eeb2a96d-5cd0-ef11-b16e-872d9f3dcb09@linaro.org>
Message-ID: <c419fd718799cd2352d5deaadfb1eae805538e70.camel@mediatek.com>

Dear Daniel,

Sorry for the late reply


On Mon, 2021-06-14 at 18:58 +0200, Daniel Lezcano wrote:
> On 03/06/2021 13:00, Ben Tseng wrote:
> > From: Michael Kao <michael.kao at mediatek.com>
> > 
> > Provide thermal zone to read thermal sensor
> > in the SoC. We can read all the thermal sensors
> > value in the SoC by the node /sys/class/thermal/
> > 
> > In mtk_thermal_bank_temperature, return -EAGAIN instead of -EACCESS
> > on the first read of sensor that often are bogus values.
> > This can avoid following warning on boot:
> > 
> >   thermal thermal_zone6: failed to read out thermal zone (-13)
> > 
> > Signed-off-by: Michael Kao <michael.kao at mediatek.com>
> > Signed-off-by: Ben Tseng <ben.tseng at mediatek.com>
> > 
> > ---
> > 
> > This patchset supports for MT8183 chip to mtk_thermal.c.
> > Add thermal zone of all the thermal sensor in SoC for
> > another get temperatrue. They don't need to thermal throttle.
> > And we bind coolers for thermal zone nodes of cpu_thermal.
> > 
> > Changes in V8:
> >     - Rebase to kernel-v5.13-rc1
> >     - Resend
> > 
> > Changes in v7:
> >     - Fix build error in v6.
> > 
> > Changes in v6:
> >     - Rebase to kernel-5.11-rc1.
> >     - [1/3]
> >         - add interrupts property.
> >     - [2/3]
> >         - add the Tested-by in the commit message.
> >     - [3/3]
> >         - use the mt->conf->msr[id] instead of conf->msr[id] in the
> >           _get_sensor_temp and mtk_thermal_bank_temperature.
> >         - remove the redundant space in _get_sensor_temp and
> >           mtk_read_sensor_temp.
> >         - change kmalloc to dev_kmalloc in mtk_thermal_probe.
> > 
> > Changes in v5:
> >     - Rebase to kernel-5.9-rc1.
> >     - Revise the title of cover letter.
> >     - Drop "[v4,7/7] thermal: mediatek: use spinlock to protect
> > PTPCORESEL"
> >     - [2/2]
> >         -  Add the judgement to the version of raw_to_mcelsius.
> > 
> > Changes in v4:
> >     - Rebase to kernel-5.6-rc1.
> >     - [1/7]
> >         - Squash thermal zone settings in the dtsi from [v3,5/8]
> >           arm64: dts: mt8183: Increase polling frequency for CPU
> > thermal zone.
> >         - Remove the property of interrupts and mediatek,hw-reset-
> > temp.
> >     - [2/7]
> >         - Correct commit message.
> >     - [4/7]
> >         - Change the target temperature to the 80C and change the
> > commit message.
> >     - [6/7]
> >         - Adjust newline alignment.
> >         - Fix the judgement on the return value of registering
> > thermal zone.
> > 
> > Changes in v3:
> >     - Rebase to kernel-5.5-rc1.
> >     - [1/8]
> >         - Update sustainable power of cpu, tzts1~5 and tztsABB.
> >     - [7/8]
> >         - Bypass the failure that non cpu_thermal sensor is not
> > find in thermal-zones
> >           in dts, which is normal for mt8173, so prompt a warning
> > here instead of
> >           failing.
> > 
> > 	Return -EAGAIN instead of -EACCESS on the first read of sensor
> > that
> >         often are bogus values. This can avoid following warning on
> > boot:
> > 
> >           thermal thermal_zone6: failed to read out thermal zone (-
> > 13)
> > 
> > Changes in v2:
> >     - [1/8]
> >         - Add the sustainable-power,trips,cooling-maps to the
> > tzts1~tztsABB.
> >     - [4/8]
> >         - Add the min opp of cpu throttle.
> > 
> > Matthias Kaehlcke (1):
> >   arm64: dts: mt8183: Configure CPU cooling
> > 
> > Michael Kao (2):
> >   thermal: mediatek: add another get_temp ops for thermal sensors
> >   arm64: dts: mt8183: add thermal zone node
> > ---
> >  drivers/thermal/mtk_thermal.c | 100
> > +++++++++++++++++++++++++++++++-----------
> >  1 file changed, 75 insertions(+), 25 deletions(-)
> > 
> > diff --git a/drivers/thermal/mtk_thermal.c
> > b/drivers/thermal/mtk_thermal.c
> > index 97e8678..b6bee451 100644
> > --- a/drivers/thermal/mtk_thermal.c
> > +++ b/drivers/thermal/mtk_thermal.c
> > @@ -245,6 +245,11 @@ enum mtk_thermal_version {
> >  
> >  struct mtk_thermal;
> >  
> > +struct mtk_thermal_zone {
> > +	struct mtk_thermal *mt;
> > +	int id;
> > +};
> 
> How does it differ from 'struct mtk_thermal_bank' ?

"truct mtk_thermal_zone" is duplicated. It will be removed next version

> 
> >  struct thermal_bank_cfg {
> >  	unsigned int num_sensors;
> >  	const int *sensors;
> > @@ -637,6 +642,30 @@ static void mtk_thermal_put_bank(struct
> > mtk_thermal_bank *bank)
> >  		mutex_unlock(&mt->lock);
> >  }
> >  
> > +static u32 _get_sensor_temp(struct mtk_thermal *mt, int id)
> > +{
> > +	u32 raw;
> > +	int temp;
> > +
> > +	raw = readl(mt->thermal_base + mt->conf->msr[id]);
> > +
> > +	if (mt->conf->version == MTK_THERMAL_V1)
> > +		temp = raw_to_mcelsius_v1(mt, id, raw);
> > +	else
> > +		temp = raw_to_mcelsius_v2(mt, id, raw);
> 
> Please add the proper conversion function as a callback and set it at
> probe time, instead of checking at every call.
> 

Thanks for your advisement. V1 or V2 will be assigned to a function
pointer during probe.

> > +	/*
> > +	 * The first read of a sensor often contains very high bogus
> > +	 * temperature value. Filter these out so that the system does
> > +	 * not immediately shut down.
> > +	 */
> 
> If it happens only once, why not call this function at probe time so
> this test won't be needed.
> 

It's exist in previous upstream version, and old chips should be
compatible. So we need to keep this filter to avoid wrong sensor
reading.

> > +	if (temp > 200000)
> > +		return -EAGAIN;
> > +	else
> > +		return temp;
> > +}
> > +
> >  /**
> >   * mtk_thermal_bank_temperature - get the temperature of a bank
> >   * @bank:	The bank
> > @@ -647,28 +676,11 @@ static void mtk_thermal_put_bank(struct
> > mtk_thermal_bank *bank)
> >  static int mtk_thermal_bank_temperature(struct mtk_thermal_bank
> > *bank)
> >  {
> >  	struct mtk_thermal *mt = bank->mt;
> > -	const struct mtk_thermal_data *conf = mt->conf;
> >  	int i, temp = INT_MIN, max = INT_MIN;
> > -	u32 raw;
> > -
> > -	for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
> > -		raw = readl(mt->thermal_base + conf->msr[i]);
> >  
> > -		if (mt->conf->version == MTK_THERMAL_V1) {
> > -			temp = raw_to_mcelsius_v1(
> > -				mt, conf->bank_data[bank-
> > >id].sensors[i], raw);
> > -		} else {
> > -			temp = raw_to_mcelsius_v2(
> > -				mt, conf->bank_data[bank-
> > >id].sensors[i], raw);
> > -		}
> > +	for (i = 0; i < mt->conf->bank_data[bank->id].num_sensors; i++)
> > {
> >  
> > -		/*
> > -		 * The first read of a sensor often contains very high
> > bogus
> > -		 * temperature value. Filter these out so that the
> > system does
> > -		 * not immediately shut down.
> > -		 */
> > -		if (temp > 200000)
> > -			temp = 0;
> > +		temp = _get_sensor_temp(mt, i);
> >  
> >  		if (temp > max)
> >  			max = temp;
> > @@ -679,7 +691,8 @@ static int mtk_thermal_bank_temperature(struct
> > mtk_thermal_bank *bank)
> >  
> >  static int mtk_read_temp(void *data, int *temperature)
> >  {
> > -	struct mtk_thermal *mt = data;
> > +	struct mtk_thermal_zone *tz = data;
> > +	struct mtk_thermal *mt = tz->mt;
> >  	int i;
> >  	int tempmax = INT_MIN;
> >  
> > @@ -698,10 +711,28 @@ static int mtk_read_temp(void *data, int
> > *temperature)
> >  	return 0;
> >  }
> >  
> > +static int mtk_read_sensor_temp(void *data, int *temperature)
> > +{
> > +	struct mtk_thermal_zone *tz = data;
> > +	struct mtk_thermal *mt = tz->mt;
> > +	int id = tz->id - 1;
> > +
> > +	if (id < 0)
> > +		return -EACCES;
> 
> How this can happen ?
> 

tz->id > 0 is always true. It will be removed in next version.


> > 
> > +	*temperature = _get_sensor_temp(mt, id);
> > +
> > +	return 0;
> > +}
> > +
> >  static const struct thermal_zone_of_device_ops mtk_thermal_ops = {
> >  	.get_temp = mtk_read_temp,
> >  };
> >  
> > +static const struct thermal_zone_of_device_ops
> > mtk_thermal_sensor_ops = {
> > +	.get_temp = mtk_read_sensor_temp,
> > +};
> > +
> >  static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
> >  				  u32 apmixed_phys_base, u32
> > auxadc_phys_base,
> >  				  int ctrl_id)
> > @@ -992,6 +1023,7 @@ static int mtk_thermal_probe(struct
> > platform_device *pdev)
> >  	u64 auxadc_phys_base, apmixed_phys_base;
> >  	struct thermal_zone_device *tzdev;
> >  	void __iomem *apmixed_base, *auxadc_base;
> > +	struct mtk_thermal_zone *tz;
> >  
> >  	mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
> >  	if (!mt)
> > @@ -1080,11 +1112,29 @@ static int mtk_thermal_probe(struct
> > platform_device *pdev)
> >  
> >  	platform_set_drvdata(pdev, mt);
> >  
> > -	tzdev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, mt,
> > -						     &mtk_thermal_ops);
> > -	if (IS_ERR(tzdev)) {
> > -		ret = PTR_ERR(tzdev);
> > -		goto err_disable_clk_peri_therm;
> > +	for (i = 0; i < mt->conf->num_sensors + 1; i++) {
> > +		tz = devm_kmalloc(&pdev->dev, sizeof(*tz), GFP_KERNEL);
> > +		if (!tz)
> > +			return -ENOMEM;
> > +
> > +		tz->mt = mt;
> > +		tz->id = i;
> > +
> > +		tzdev = devm_thermal_zone_of_sensor_register(&pdev-
> > >dev, i, tz, (i == 0) ?
> > +							     &mtk_therm
> > al_ops :
> > +							     &mtk_therm
> > al_sensor_ops);
> > +
> > +		if (IS_ERR(tzdev)) {
> > +			if (PTR_ERR(tzdev) == -ENODEV) {
> > +				dev_warn(&pdev->dev,
> > +					 "sensor %d not registered in
> > thermal zone in dt\n", i);
> > +				continue;
> > +			}
> > +			if (PTR_ERR(tzdev) == -EACCES) {
> > +				ret = PTR_ERR(tzdev);
> > +				goto err_disable_clk_peri_therm;
> > +			}
> 
> If the error is none of the above, the loop continues. Is that what
> you
> want ?

Next version, As soon as thermal zone register fail, break and return.

> > +		}
> >  	}
> >  
> >  	return 0;
> > 
> 
> 

From robh at kernel.org  Fri Aug 13 05:11:07 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 07:11:07 -0500
Subject: [PATCH 2/2] dt-bindings: perf: Add YAML schemas for Marvell CN10K
 LLC-TAD pmu bindings
In-Reply-To: <20210812174209.1970-3-bbudiredla@marvell.com>
References: <20210812174209.1970-1-bbudiredla@marvell.com>
 <20210812174209.1970-3-bbudiredla@marvell.com>
Message-ID: <1628856667.648308.3179071.nullmailer@robh.at.kernel.org>

On Thu, 12 Aug 2021 23:12:09 +0530, Bhaskara Budiredla wrote:
> Add device tree bindings for Last-level-cache Tag-and-data
> (LLC-TAD) unit PMU for Marvell CN10K SoCs.
> 
> Signed-off-by: Bhaskara Budiredla <bbudiredla at marvell.com>
> ---
>  .../bindings/perf/marvell-cn10k-tad.yaml      | 45 +++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/perf/marvell-cn10k-tad.example.dts:19.32-25.11: Warning (unit_address_format): /example-0/tad_pmu at 0x87e280000000: unit name should not have leading "0x"
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/perf/marvell-cn10k-tad.example.dt.yaml: example-0: tad_pmu at 0x87e280000000:reg:0: [34786, 2147483648, 0, 4096] is too long
	From schema: /usr/local/lib/python3.8/dist-packages/dtschema/schemas/reg.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/perf/marvell-cn10k-tad.example.dt.yaml: example-0: 'tad_pmu at 0x87e280000000' does not match any of the regexes: '.*-names$', '.*-supply$', '^#.*-cells$', '^#[a-zA-Z0-9,+\\-._]{0,63}$', '^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}$', '^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$', '^__.*__$', 'pinctrl-[0-9]+'
	From schema: /usr/local/lib/python3.8/dist-packages/dtschema/schemas/dt-core.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/perf/marvell-cn10k-tad.example.dt.yaml: tad_pmu at 0x87e280000000: 'tad-cnt', 'tad-page-size', 'tad-pmu-page-size' do not match any of the regexes: 'pinctrl-[0-9]+'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1516395

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From laurent.pinchart at ideasonboard.com  Fri Aug 13 05:16:33 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 13 Aug 2021 15:16:33 +0300
Subject: [RFC PATCH 06/17] drm/exynos: dsi: Handle exynos specifics via
 driver_data
In-Reply-To: <79ef7f71-b167-2368-e0fd-d4ccaee596c2@samsung.com>
References: <20210704090230.26489-1-jagan@amarulasolutions.com>
 <20210704090230.26489-7-jagan@amarulasolutions.com>
 <CGME20210725172551epcas1p31dff839439ac37757cf061405b5ac65c@epcas1p3.samsung.com>
 <YP2el40V3K4R7ner@ravnborg.org>
 <79ef7f71-b167-2368-e0fd-d4ccaee596c2@samsung.com>
Message-ID: <YRZioZvYrU99fQxJ@pendragon.ideasonboard.com>

Hi Inki,

On Fri, Aug 13, 2021 at 03:50:56PM +0900, Inki Dae wrote:
> 21. 7. 26. ?? 2:25? Sam Ravnborg ?(?) ? ?:
> > On Sun, Jul 04, 2021 at 02:32:19PM +0530, Jagan Teki wrote:
> >> Exynos DSI driver is actually a Samsung MIPI DSIM bridge
> >> IP which is also used in i.MX8MM platforms.
> >>
> >> Right now the existing driver has some exynos drm specific
> >> code bases like te_irq, crtc and component_ops.
> >>
> >> In order to switch this driver into a common bridge driver
> >> We can see 2 options to handle the exynos specific code.
> >>
> >> A. Drop the component_ops, and rework other specifics.
> >>    This may lead to more foundation work as it requires
> >>    more changes in exynos drm drivers stack.
> >>
> >> B. Handle the exynos specifics via driver data, and make
> >>    the common bridge work in different platforms and plan
> >>    for option A in future.
> >>
> >> So, this patch is trying to add option B) changes to handle
> >> exynos specifics via driver_data.
> > 
> > We really should find someone that has the time, energy, knowledge and
> > hardware that can include device_link support once anf for all for
> > bridges.
> > Then we would avoid hacks like this.
> > 
> > I see no other options at the moment, but look forward for a better
> > solution.
> 
> I'm not sure that it's correct to share this mipi dsi driver with
> I.MX8MM SoC even though it's a same IP because this MIPI DSI device
> isn't peripheral device but in SoC.
>
> It would mean that Exynos MIPI DSI device depends on SoC architecture,
> and Exynos and I.MX series are totally different SoC. So if we share
> the same driver for the MIPI DSI device then many things we didn't
> predict may happen in the future.

Isn't that true for external components true thought ? Any driver shared
by multiple systems will face this issue, where it will be developed
with some use cases in mind, and regressions may happen when the driver
is then extended to support other use cases not required for the
original platform.

In general we don't want multiple drivers for the same IP core unless
there are valid technical reasons for that. It's the whole point of the
device tree, being able to describe how IP cores are integrated, so that
code can be reused across platforms. Of course, integration differences
between SoCs can sometimes vary wildly and require some amount of glue
code.

> I don't want to make Jagan's efforts
> in vain for the community but clarify whether this is correct way or
> not. If this is only the way we have to go then we could more focus on
> actual solution not such hack. Impossible work with Jagan alone I
> think.

I do agree that we need more correct solutions and less hacks in general
:-) The issues faced on Exynos also exist on other platforms, so it
would be much better to solve them well once that duplicating
implementations with less test coverage and reviews. There have been
efforts in the past to address some of these issues, which have resulted
in solutions such as the component framework. However, I'd argued that
we've never taken it to the last step, and have always stopped with half
solutions. The component framework, for instance, is painful to use, and
the handling of .remove() in most drivers is completely broken because
of that (not just because of that though, we have issues in the DRM core
that make hot-unplug just impossible to handle safetly).

> So let's get started with a question,
> - Is MIPI-DSI bridge device or Encoder device? I think that MIPI-DSI
> is a Encoder device managed by atomic KMS. If MIPI-DSI should be
> handled as bridge device then does now drm bridge framework provide
> everything to share one driver with one more SoC? I mean something
> that drm bridge has to consider for such driver support, which is
> shared with one more SoC.

The DRM "encoder" concept was a bit of a historical mistake that we are
stuck with as drm_encoder is exposed to userspace. It comes from a time
where nobody was envisioning chaining multiple encoders. DRM is moving
to modelling every component after the CRTC as a bridge. This brings
much more flexibility, and in that model, the drm_encoder becomes more
or less a stub.

The DRM bridge API has been extended in the past to support more
features, and if anything is still missing that makes it difficult to
move away from drm_encoder, we can of course address the issues in
drm_bridge.

> And Display mode - VIDEO and COMMAND mode - is generic type of MIPI
> DSI, and also componentised subsystem is a generic solution to resolve
> probing order issue not Exynos specific feature. These are driver
> specific ones not Exynos SoC I think. As SoC specific things should be
> considered, I think MIPI DSI Driver - interrupt handler and probing
> order things are really specific to device driver - should be
> separated but we could share the control part of the device.
> 
> I was busy with other projects so didn't care of Linux DRM world so
> there may be my missing something.
> 
> >> Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
> >> ---
> >>  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 37 +++++++++++++++++++------
> >>  1 file changed, 29 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> >> index 99a1b8c22313..53d878d4d2d7 100644
> >> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> >> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
> >> @@ -250,6 +250,7 @@ struct exynos_dsi_driver_data {
> >>  	unsigned int wait_for_reset;
> >>  	unsigned int num_bits_resol;
> >>  	const unsigned int *reg_values;
> >> +	bool exynos_specific;
> >>  };
> >>  
> >>  struct exynos_dsi {
> >> @@ -459,6 +460,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
> >>  	.wait_for_reset = 1,
> >>  	.num_bits_resol = 11,
> >>  	.reg_values = reg_values,
> >> +	.exynos_specific = true,
> >>  };
> >>  
> >>  static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
> >> @@ -471,6 +473,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
> >>  	.wait_for_reset = 1,
> >>  	.num_bits_resol = 11,
> >>  	.reg_values = reg_values,
> >> +	.exynos_specific = true,
> >>  };
> >>  
> >>  static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
> >> @@ -481,6 +484,7 @@ static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
> >>  	.wait_for_reset = 1,
> >>  	.num_bits_resol = 11,
> >>  	.reg_values = reg_values,
> >> +	.exynos_specific = true,
> >>  };
> >>  
> >>  static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
> >> @@ -492,6 +496,7 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
> >>  	.wait_for_reset = 0,
> >>  	.num_bits_resol = 12,
> >>  	.reg_values = exynos5433_reg_values,
> >> +	.exynos_specific = true,
> >>  };
> >>  
> >>  static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
> >> @@ -503,6 +508,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
> >>  	.wait_for_reset = 1,
> >>  	.num_bits_resol = 12,
> >>  	.reg_values = exynos5422_reg_values,
> >> +	.exynos_specific = true,
> >>  };
> >>  
> >>  static const struct of_device_id exynos_dsi_of_match[] = {
> >> @@ -1484,7 +1490,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
> >>  	 * If attached panel device is for command mode one, dsi should register
> >>  	 * TE interrupt handler.
> >>  	 */
> >> -	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
> >> +	if (dsi->driver_data->exynos_specific &&
> >> +	    !(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
> >>  		int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
> >>  		if (ret)
> >>  			return ret;
> >> @@ -1495,8 +1502,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
> >>  	dsi->lanes = device->lanes;
> >>  	dsi->format = device->format;
> >>  	dsi->mode_flags = device->mode_flags;
> >> -	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
> >> -			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
> >> +	if (dsi->driver_data->exynos_specific)
> >> +		exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
> >> +					    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
> >>  
> >>  	mutex_unlock(&drm->mode_config.mutex);
> >>  
> >> @@ -1515,7 +1523,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
> >>  	if (drm->mode_config.poll_enabled)
> >>  		drm_kms_helper_hotplug_event(drm);
> >>  
> >> -	exynos_dsi_unregister_te_irq(dsi);
> >> +	if (dsi->driver_data->exynos_specific)
> >> +		exynos_dsi_unregister_te_irq(dsi);
> >>  
> >>  	return 0;
> >>  }
> >> @@ -1737,6 +1746,15 @@ static int exynos_dsi_probe(struct platform_device *pdev)
> >>  	if (ret)
> >>  		return ret;
> >>  
> >> +	if (!dsi->driver_data->exynos_specific) {
> >> +		ret = mipi_dsi_host_register(&dsi->dsi_host);
> >> +		if (ret) {
> >> +			dev_err(dev, "failed to register mipi dsi host: %d\n",
> >> +				ret);
> >> +			return ret;
> >> +		}
> >> +	}
> >> +
> >>  	platform_set_drvdata(pdev, dsi);
> >>  
> >>  	pm_runtime_enable(dev);
> >> @@ -1747,9 +1765,11 @@ static int exynos_dsi_probe(struct platform_device *pdev)
> >>  
> >>  	drm_bridge_add(&dsi->bridge);
> >>  
> >> -	ret = component_add(dev, &exynos_dsi_component_ops);
> >> -	if (ret)
> >> -		goto err_disable_runtime;
> >> +	if (dsi->driver_data->exynos_specific) {
> >> +		ret = component_add(dev, &exynos_dsi_component_ops);
> >> +		if (ret)
> >> +			goto err_disable_runtime;
> >> +	}
> >>  
> >>  	return 0;
> >>  
> >> @@ -1767,7 +1787,8 @@ static int exynos_dsi_remove(struct platform_device *pdev)
> >>  
> >>  	pm_runtime_disable(&pdev->dev);
> >>  
> >> -	component_del(&pdev->dev, &exynos_dsi_component_ops);
> >> +	if (dsi->driver_data->exynos_specific)
> >> +		component_del(&pdev->dev, &exynos_dsi_component_ops);
> >>  
> >>  	return 0;
> >>  }

-- 
Regards,

Laurent Pinchart


From kansho at chromium.org  Fri Aug 13 05:19:56 2021
From: kansho at chromium.org (Kansho Nishida)
Date: Fri, 13 Aug 2021 21:19:56 +0900
Subject: [PATCH 0/1] dt-bindings: mediatek: update audio binding documentation
Message-ID: <20210813121957.3089816-1-kansho@chromium.org>


Hi Matthias,

Thank you for your merging! This patch updates the binding description.

Regards,
Kansho



Kansho Nishida (1):
  dt-bindings: mediatek: update audio binding documentation

 .../devicetree/bindings/arm/mediatek/mediatek,audsys.txt      | 4 ++--
 arch/arm64/boot/dts/mediatek/mt7622.dtsi                      | 4 ++--
 arch/arm64/boot/dts/mediatek/mt8183.dtsi                      | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

-- 
2.33.0.rc1.237.g0d66db33f3-goog



From kansho at chromium.org  Fri Aug 13 05:19:57 2021
From: kansho at chromium.org (Kansho Nishida)
Date: Fri, 13 Aug 2021 21:19:57 +0900
Subject: [PATCH 1/1] dt-bindings: mediatek: update audio binding documentation
In-Reply-To: <20210813121957.3089816-1-kansho@chromium.org>
References: <20210813121957.3089816-1-kansho@chromium.org>
Message-ID: <20210813211947.1.Iaddd8d9fd3ce70ac40663afb9d6fa5b76ef0c38a@changeid>

This patch updates audio binding documentation.
And change audio node names in dts files in the same manner.

Signed-off-by: Kansho Nishida <kansho at chromium.org>
---

 .../devicetree/bindings/arm/mediatek/mediatek,audsys.txt      | 4 ++--
 arch/arm64/boot/dts/mediatek/mt7622.dtsi                      | 4 ++--
 arch/arm64/boot/dts/mediatek/mt8183.dtsi                      | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
index 699776be1dd3..409a425cbdd3 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
@@ -28,12 +28,12 @@ For common binding part and usage, refer to
 
 Example:
 
-	audsys: clock-controller at 11220000 {
+	audsys: audio-controller at 11220000 {
 		compatible = "mediatek,mt7622-audsys", "syscon";
 		reg = <0 0x11220000 0 0x2000>;
 		#clock-cells = <1>;
 
-		afe: audio-controller {
+		afe: mt7622-audio {
 			...
 		};
 	};
diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index 890a942ec608..a54c9cc2063d 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -590,12 +590,12 @@ uart4: serial at 11019000 {
 		status = "disabled";
 	};
 
-	audsys: clock-controller at 11220000 {
+	audsys: audio-controller at 11220000 {
 		compatible = "mediatek,mt7622-audsys", "syscon";
 		reg = <0 0x11220000 0 0x2000>;
 		#clock-cells = <1>;
 
-		afe: audio-controller {
+		afe: mt7622-audio {
 			compatible = "mediatek,mt7622-audio";
 			interrupts =  <GIC_SPI 144 IRQ_TYPE_LEVEL_LOW>,
 				      <GIC_SPI 145 IRQ_TYPE_LEVEL_LOW>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 9ea4c5001b1e..189e3545226e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1119,7 +1119,7 @@ audiosys: audio-controller at 11220000 {
 			compatible = "mediatek,mt8183-audiosys", "syscon";
 			reg = <0 0x11220000 0 0x1000>;
 			#clock-cells = <1>;
-			afe: mt8183-afe-pcm {
+			afe: mt8183-audio {
 				compatible = "mediatek,mt8183-audio";
 				interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_LOW>;
 				resets = <&watchdog MT8183_TOPRGU_AUDIO_SW_RST>;
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From krzysztof.kozlowski at canonical.com  Fri Aug 13 05:54:14 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 13 Aug 2021 14:54:14 +0200
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to dtschema
Message-ID: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos5422 SoC frequency and voltage scaling for
Dynamic Memory Controller to DT schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
 .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
 MAINTAINERS                                   |   2 +-
 3 files changed, 138 insertions(+), 85 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt b/Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
deleted file mode 100644
index 02e4a1f862f1..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-* Exynos5422 frequency and voltage scaling for Dynamic Memory Controller device
-
-The Samsung Exynos5422 SoC has DMC (Dynamic Memory Controller) to which the DRAM
-memory chips are connected. The driver is to monitor the controller in runtime
-and switch frequency and voltage. To monitor the usage of the controller in
-runtime, the driver uses the PPMU (Platform Performance Monitoring Unit), which
-is able to measure the current load of the memory.
-When 'userspace' governor is used for the driver, an application is able to
-switch the DMC and memory frequency.
-
-Required properties for DMC device for Exynos5422:
-- compatible: Should be "samsung,exynos5422-dmc".
-- clocks : list of clock specifiers, must contain an entry for each
-  required entry in clock-names for CLK_FOUT_SPLL, CLK_MOUT_SCLK_SPLL,
-  CLK_FF_DOUT_SPLL2, CLK_FOUT_BPLL, CLK_MOUT_BPLL, CLK_SCLK_BPLL,
-  CLK_MOUT_MX_MSPLL_CCORE, CLK_MOUT_MX_MSPLL_CCORE_PHY, CLK_MOUT_MCLK_CDREX,
-- clock-names : should include "fout_spll", "mout_sclk_spll", "ff_dout_spll2",
-  "fout_bpll", "mout_bpll", "sclk_bpll", "mout_mx_mspll_ccore",
-  "mout_mclk_cdrex"  entries
-- devfreq-events : phandles for PPMU devices connected to this DMC.
-- vdd-supply : phandle for voltage regulator which is connected.
-- reg : registers of two CDREX controllers.
-- operating-points-v2 : phandle for OPPs described in v2 definition.
-- device-handle : phandle of the connected DRAM memory device. For more
-	information please refer to documentation file:
-	Documentation/devicetree/bindings/ddr/lpddr3.txt
-- devfreq-events : phandles of the PPMU events used by the controller.
-- samsung,syscon-clk : phandle of the clock register set used by the controller,
-	these registers are used for enabling a 'pause' feature and are not
-	exposed by clock framework but they must be used in a safe way.
-	The register offsets are in the driver code and specyfic for this SoC
-	type.
-
-Optional properties for DMC device for Exynos5422:
-- interrupt-parent : The parent interrupt controller.
-- interrupts : Contains the IRQ line numbers for the DMC internal performance
-  event counters in DREX0 and DREX1 channels. Align with specification of the
-  interrupt line(s) in the interrupt-parent controller.
-- interrupt-names : IRQ names "drex_0" and "drex_1", the order should be the
-  same as in the 'interrupts' list above.
-
-Example:
-
-	ppmu_dmc0_0: ppmu at 10d00000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x10d00000 0x2000>;
-		clocks = <&clock CLK_PCLK_PPMU_DREX0_0>;
-		clock-names = "ppmu";
-		events {
-			ppmu_event_dmc0_0: ppmu-event3-dmc0_0 {
-				event-name = "ppmu-event3-dmc0_0";
-			};
-		};
-	};
-
-	dmc: memory-controller at 10c20000 {
-		compatible = "samsung,exynos5422-dmc";
-		reg = <0x10c20000 0x10000>, <0x10c30000 0x10000>;
-		clocks = <&clock CLK_FOUT_SPLL>,
-			 <&clock CLK_MOUT_SCLK_SPLL>,
-			 <&clock CLK_FF_DOUT_SPLL2>,
-			 <&clock CLK_FOUT_BPLL>,
-			 <&clock CLK_MOUT_BPLL>,
-			 <&clock CLK_SCLK_BPLL>,
-			 <&clock CLK_MOUT_MX_MSPLL_CCORE>,
-			 <&clock CLK_MOUT_MCLK_CDREX>;
-		clock-names = "fout_spll",
-			      "mout_sclk_spll",
-			      "ff_dout_spll2",
-			      "fout_bpll",
-			      "mout_bpll",
-			      "sclk_bpll",
-			      "mout_mx_mspll_ccore",
-			      "mout_mclk_cdrex";
-		operating-points-v2 = <&dmc_opp_table>;
-		devfreq-events = <&ppmu_event3_dmc0_0>,	<&ppmu_event3_dmc0_1>,
-				 <&ppmu_event3_dmc1_0>, <&ppmu_event3_dmc1_1>;
-		device-handle = <&samsung_K3QF2F20DB>;
-		vdd-supply = <&buck1_reg>;
-		samsung,syscon-clk = <&clock>;
-		interrupt-parent = <&combiner>;
-		interrupts = <16 0>, <16 1>;
-		interrupt-names = "drex_0", "drex_1";
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml b/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
new file mode 100644
index 000000000000..b168a9c8bfde
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
@@ -0,0 +1,137 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/samsung,exynos5422-dmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: |
+  Samsung Exynos5422 SoC frequency and voltage scaling for Dynamic Memory
+  Controller device
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Lukasz Luba <lukasz.luba at arm.com>
+
+description: |
+  The Samsung Exynos5422 SoC has DMC (Dynamic Memory Controller) to which the
+  DRAM memory chips are connected. The driver is to monitor the controller in
+  runtime and switch frequency and voltage. To monitor the usage of the
+  controller in runtime, the driver uses the PPMU (Platform Performance
+  Monitoring Unit), which is able to measure the current load of the memory.
+  When 'userspace' governor is used for the driver, an application is able to
+  switch the DMC and memory frequency.
+
+properties:
+  compatible:
+    items:
+      - const: samsung,exynos5422-dmc
+
+  clock-names:
+    items:
+      - const: fout_spll
+      - const: mout_sclk_spll
+      - const: ff_dout_spll2
+      - const: fout_bpll
+      - const: mout_bpll
+      - const: sclk_bpll
+      - const: mout_mx_mspll_ccore
+      - const: mout_mclk_cdrex
+
+  clocks:
+    minItems: 8
+    maxItems: 8
+
+  devfreq-events:
+    $ref: '/schemas/types.yaml#/definitions/phandle-array'
+    minItems: 1
+    maxItems: 16
+    description: phandles of the PPMU events used by the controller.
+
+  device-handle:
+    $ref: '/schemas/types.yaml#/definitions/phandle'
+    description: |
+      phandle of the connected DRAM memory device. For more information please
+      refer to documentation file: Documentation/devicetree/bindings/ddr/lpddr3.txt
+
+  operating-points-v2: true
+
+  interrupts:
+    items:
+      - description: DMC internal performance event counters in DREX0
+      - description: DMC internal performance event counters in DREX1
+
+  interrupt-names:
+    items:
+      - const: drex_0
+      - const: drex_1
+
+  reg:
+    items:
+      - description: registers of DREX0
+      - description: registers of DREX1
+
+  samsung,syscon-clk:
+    $ref: '/schemas/types.yaml#/definitions/phandle'
+    description: |
+      Phandle of the clock register set used by the controller, these registers
+      are used for enabling a 'pause' feature and are not exposed by clock
+      framework but they must be used in a safe way.  The register offsets are
+      in the driver code and specyfic for this SoC type.
+
+  vdd-supply: true
+
+required:
+  - compatible
+  - clock-names
+  - clocks
+  - devfreq-events
+  - device-handle
+  - reg
+  - samsung,syscon-clk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5420.h>
+    ppmu_dmc0_0: ppmu at 10d00000 {
+        compatible = "samsung,exynos-ppmu";
+        reg = <0x10d00000 0x2000>;
+        clocks = <&clock CLK_PCLK_PPMU_DREX0_0>;
+        clock-names = "ppmu";
+        events {
+            ppmu_event_dmc0_0: ppmu-event3-dmc0_0 {
+                event-name = "ppmu-event3-dmc0_0";
+            };
+        };
+    };
+
+    memory-controller at 10c20000 {
+        compatible = "samsung,exynos5422-dmc";
+        reg = <0x10c20000 0x10000>, <0x10c30000 0x10000>;
+        clocks = <&clock CLK_FOUT_SPLL>,
+                 <&clock CLK_MOUT_SCLK_SPLL>,
+                 <&clock CLK_FF_DOUT_SPLL2>,
+                 <&clock CLK_FOUT_BPLL>,
+                 <&clock CLK_MOUT_BPLL>,
+                 <&clock CLK_SCLK_BPLL>,
+                 <&clock CLK_MOUT_MX_MSPLL_CCORE>,
+                 <&clock CLK_MOUT_MCLK_CDREX>;
+        clock-names = "fout_spll",
+                      "mout_sclk_spll",
+                      "ff_dout_spll2",
+                      "fout_bpll",
+                      "mout_bpll",
+                      "sclk_bpll",
+                      "mout_mx_mspll_ccore",
+                      "mout_mclk_cdrex";
+        operating-points-v2 = <&dmc_opp_table>;
+        devfreq-events = <&ppmu_event3_dmc0_0>,	<&ppmu_event3_dmc0_1>,
+                         <&ppmu_event3_dmc1_0>, <&ppmu_event3_dmc1_1>;
+        device-handle = <&samsung_K3QF2F20DB>;
+        vdd-supply = <&buck1_reg>;
+        samsung,syscon-clk = <&clock>;
+        interrupt-parent = <&combiner>;
+        interrupts = <16 0>, <16 1>;
+        interrupt-names = "drex_0", "drex_1";
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index ebdb07a49b02..eb4ada858826 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5570,7 +5570,7 @@ M:	Lukasz Luba <lukasz.luba at arm.com>
 L:	linux-pm at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
+F:	Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
 F:	drivers/memory/samsung/exynos5422-dmc.c
 
 DME1737 HARDWARE MONITOR DRIVER
-- 
2.30.2



From robin.murphy at arm.com  Fri Aug 13 05:55:38 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 13:55:38 +0100
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference in
 probe
In-Reply-To: <20210813113338.GA30697@kili>
References: <20210813113338.GA30697@kili>
Message-ID: <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>

On 2021-08-13 12:33, Dan Carpenter wrote:
> If devm_regulator_get_optional() returns an error pointer, then we
> should return it to the user.  The current code makes an exception
> for -ENODEV that will result in an error pointer dereference on the
> next line when it calls regulator_enable().  Remove the exception.

Doesn't this break the apparent intent of the regulator being optional, 
though?

Robin.

> Fixes: e1229e884e19 ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver")
> Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
> ---
>   drivers/pci/controller/dwc/pcie-dw-rockchip.c | 5 ++---
>   1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 20cef2e06f66..2d0ffd3c4e16 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -225,9 +225,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>   	/* DON'T MOVE ME: must be enable before PHY init */
>   	rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
>   	if (IS_ERR(rockchip->vpcie3v3))
> -		if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV)
> -			return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
> -					"failed to get vpcie3v3 regulator\n");
> +		return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
> +				     "failed to get vpcie3v3 regulator\n");
>   
>   	ret = regulator_enable(rockchip->vpcie3v3);
>   	if (ret) {
> 


From daniel.lezcano at linaro.org  Fri Aug 13 05:59:56 2021
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 13 Aug 2021 14:59:56 +0200
Subject: [PATCH v3] arm64: dts: rockchip: add thermal fan control to
 rockpro64
In-Reply-To: <20210730151727.729822-1-pgwipeout@gmail.com>
References: <20210730151727.729822-1-pgwipeout@gmail.com>
Message-ID: <ad6d8025-977c-9ff2-81ff-a417df48231c@linaro.org>

On 30/07/2021 17:17, Peter Geis wrote:
> The rockpro64 had a fan node since
> commit 5882d65c1691 ("arm64: dts: rockchip: Add PWM fan for RockPro64")
> however it was never tied into the thermal driver for automatic control.
> 
> Add the links to the thermal node to permit the kernel to handle this
> automatically.
> Borrowed from the (rk3399-khadas-edge.dtsi).
> 
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
> 
> Changelog:
> v3:
> Removed the gpu nodes to prevent in-fighting (thanks Robin!)
> 
> v2:
> Adjusted fan setpoints for less noise
> 
>  .../boot/dts/rockchip/rk3399-rockpro64.dtsi   | 29 +++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> index 6bff8db7d33e..83db4ca67334 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> @@ -69,6 +69,7 @@ diy_led: led-1 {
>  
>  	fan: pwm-fan {
>  		compatible = "pwm-fan";
> +		cooling-levels = <0 100 150 200 255>;
>  		#cooling-cells = <2>;
>  		fan-supply = <&vcc12v_dcin>;
>  		pwms = <&pwm1 0 50000 0>;
> @@ -245,6 +246,34 @@ &cpu_b1 {
>  	cpu-supply = <&vdd_cpu_b>;
>  };
>  
> +&cpu_thermal {
> +	trips {
> +		cpu_warm: cpu_warm {
> +			temperature = <55000>;
> +			hysteresis = <2000>;
> +			type = "active";
> +		};
> +
> +		cpu_hot: cpu_hot {
> +			temperature = <65000>;
> +			hysteresis = <2000>;
> +			type = "active";
> +		};
> +	};
> +

Why two trip points ?

Why not one functioning temperature and no lower / upper limits for the
cooling maps ?


> +	cooling-maps {
> +		map2 {
> +			trip = <&cpu_warm>;
> +			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
> +		};
> +
> +		map3 {
> +			trip = <&cpu_hot>;
> +			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
> +		};
> +	};
> +};
> +
>  &emmc_phy {
>  	status = "okay";
>  };
> 


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From will at kernel.org  Fri Aug 13 06:03:36 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 13 Aug 2021 14:03:36 +0100
Subject: [PATCH] KVM: arm64: Make hyp_panic() more robust when protected mode
 is enabled
Message-ID: <20210813130336.8139-1-will@kernel.org>

When protected mode is enabled, the host is unable to access most parts
of the EL2 hypervisor image, including 'hyp_physvirt_offset' and the
contents of the hypervisor's '.rodata.str' section. Unfortunately,
nvhe_hyp_panic_handler() tries to read from both of these locations when
handling a BUG() triggered at EL2; the former for converting the ELR to
a physical address and the latter for displaying the name of the source
file where the BUG() occurred.

Hack the EL2 panic asm to pass both physical and virtual ELR values to
the host and utilise the newly introduced CONFIG_NVHE_EL2_DEBUG so that
we disable stage-2 protection for the host before returning to the EL1
panic handler. If the debug option is not enabled, display the address
instead of the source file:line information.

Cc: Andrew Scull <ascull at google.com>
Cc: Quentin Perret <qperret at google.com>
Signed-off-by: Will Deacon <will at kernel.org>
---

Based on kvmarm/next for CONFIG_NVHE_EL2_DEBUG although still applies
without that config option.

 arch/arm64/kvm/handle_exit.c   | 23 ++++++++++++++---------
 arch/arm64/kvm/hyp/nvhe/host.S | 21 +++++++++++++++++----
 2 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 6f48336b1d86..04ebab299aa4 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -292,11 +292,12 @@ void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index)
 		kvm_handle_guest_serror(vcpu, kvm_vcpu_get_esr(vcpu));
 }
 
-void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr,
+void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr,
+					      u64 elr_virt, u64 elr_phys,
 					      u64 par, uintptr_t vcpu,
 					      u64 far, u64 hpfar) {
-	u64 elr_in_kimg = __phys_to_kimg(__hyp_pa(elr));
-	u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr;
+	u64 elr_in_kimg = __phys_to_kimg(elr_phys);
+	u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr_virt;
 	u64 mode = spsr & PSR_MODE_MASK;
 
 	/*
@@ -309,20 +310,24 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr,
 		kvm_err("Invalid host exception to nVHE hyp!\n");
 	} else if (ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 &&
 		   (esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == BUG_BRK_IMM) {
-		struct bug_entry *bug = find_bug(elr_in_kimg);
 		const char *file = NULL;
 		unsigned int line = 0;
 
 		/* All hyp bugs, including warnings, are treated as fatal. */
-		if (bug)
-			bug_get_file_line(bug, &file, &line);
+		if (!is_protected_kvm_enabled() ||
+		    IS_ENABLED(CONFIG_NVHE_EL2_DEBUG)) {
+			struct bug_entry *bug = find_bug(elr_in_kimg);
+
+			if (bug)
+				bug_get_file_line(bug, &file, &line);
+		}
 
 		if (file)
 			kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line);
 		else
-			kvm_err("nVHE hyp BUG at: %016llx!\n", elr + hyp_offset);
+			kvm_err("nVHE hyp BUG at: %016llx!\n", elr_virt + hyp_offset);
 	} else {
-		kvm_err("nVHE hyp panic at: %016llx!\n", elr + hyp_offset);
+		kvm_err("nVHE hyp panic at: %016llx!\n", elr_virt + hyp_offset);
 	}
 
 	/*
@@ -334,5 +339,5 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr,
 	kvm_err("Hyp Offset: 0x%llx\n", hyp_offset);
 
 	panic("HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%016lx\n",
-	      spsr, elr, esr, far, hpfar, par, vcpu);
+	      spsr, elr_virt, esr, far, hpfar, par, vcpu);
 }
diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S
index 2b23400e0fb3..4b652ffb591d 100644
--- a/arch/arm64/kvm/hyp/nvhe/host.S
+++ b/arch/arm64/kvm/hyp/nvhe/host.S
@@ -7,6 +7,7 @@
 #include <linux/linkage.h>
 
 #include <asm/assembler.h>
+#include <asm/kvm_arm.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmu.h>
 
@@ -85,12 +86,24 @@ SYM_FUNC_START(__hyp_do_panic)
 
 	mov	x29, x0
 
+#ifdef CONFIG_NVHE_EL2_DEBUG
+	/* Ensure host stage-2 is disabled */
+	mrs	x0, hcr_el2
+	bic	x0, x0, #HCR_VM
+	msr	hcr_el2, x0
+	isb
+	tlbi	vmalls12e1
+	dsb	nsh
+#endif
+
 	/* Load the panic arguments into x0-7 */
 	mrs	x0, esr_el2
-	get_vcpu_ptr x4, x5
-	mrs	x5, far_el2
-	mrs	x6, hpfar_el2
-	mov	x7, xzr			// Unused argument
+	mov	x4, x3
+	mov	x3, x2
+	hyp_pa	x3, x6
+	get_vcpu_ptr x5, x6
+	mrs	x6, far_el2
+	mrs	x7, hpfar_el2
 
 	/* Enter the host, conditionally restoring the host context. */
 	cbz	x29, __host_enter_without_restoring
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From robin.murphy at arm.com  Fri Aug 13 06:08:23 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 14:08:23 +0100
Subject: [PATCH 2/5] arm64: Handle UNDEF in the EL2 stub vectors
In-Reply-To: <20210812190213.2601506-3-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-3-maz@kernel.org>
Message-ID: <2f6bf17f-d235-8311-13d5-dcb3d00e23c4@arm.com>

On 2021-08-12 20:02, Marc Zyngier wrote:
> As we want to handle the silly case where HVC has been disabled
> from EL3, augment our ability to handle exception at EL2.
> 
> Check for unknown exceptions (usually UNDEF) coming from EL2,
> and treat them as a failing HVC call into the stubs. While
> this isn't great and obviously doesn't catter for the gigantic
> range of possible exceptions, it isn't any worse than what we
> have today.
> 
> Just don't try and use it for anything else.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   arch/arm64/kernel/hyp-stub.S | 19 ++++++++++++++++++-
>   1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> index 43d212618834..026a34515b21 100644
> --- a/arch/arm64/kernel/hyp-stub.S
> +++ b/arch/arm64/kernel/hyp-stub.S
> @@ -46,7 +46,16 @@ SYM_CODE_END(__hyp_stub_vectors)
>   	.align 11
>   
>   SYM_CODE_START_LOCAL(elx_sync)
> -	cmp	x0, #HVC_SET_VECTORS
> +	mrs	x4, spsr_el2
> +	and	x4, x4, #PSR_MODE_MASK
> +	orr	x4, x4, #1
> +	cmp	x4, #PSR_MODE_EL2h
> +	b.ne	0f
> +	mrs	x4, esr_el2
> +	eor	x4, x4, #ESR_ELx_IL
> +	cbz	x4, el2_undef

Hmm, might it be neater to check ESR_EL2.ISS to see if we landed here 
for any reason *other* than a successfully-executed HVC?

Robin.

> +
> +0:	cmp	x0, #HVC_SET_VECTORS
>   	b.ne	1f
>   	msr	vbar_el2, x1
>   	b	9f
> @@ -71,6 +80,14 @@ SYM_CODE_START_LOCAL(elx_sync)
>   
>   9:	mov	x0, xzr
>   	eret
> +
> +el2_undef:
> +	// Assumes this was a HVC that went really wrong...
> +	mrs	x0, elr_el2
> +	add	x0, x0, #4
> +	msr	elr_el2, x0
> +	mov_q	x0, HVC_STUB_ERR
> +	eret
>   SYM_CODE_END(elx_sync)
>   
>   // nVHE? No way! Give me the real thing!
> 


From andrew at lunn.ch  Fri Aug 13 06:09:54 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 13 Aug 2021 15:09:54 +0200
Subject: [PATCH v1] arm64: dts: fsl: ls1028a-rdb: Add dts file to choose
 swp5 as dsa master
In-Reply-To: <20210813030155.23097-1-hongbo.wang@nxp.com>
References: <20210813030155.23097-1-hongbo.wang@nxp.com>
Message-ID: <YRZvItRlSpF2Xf+S@lunn.ch>

On Fri, Aug 13, 2021 at 11:01:55AM +0800, hongbo.wang at nxp.com wrote:
> From: hongbo wang <hongbo.wang at nxp.com>
> 
> some use cases want to use swp4-eno2 link as ordinary data path,
> so we can enable swp5 as dsa master, the data from kernel can
> be transmitted to eno3, then send to swp5 via internal link, switch will
> forward it to swp0-3.
> 
> the data to kernel will come from swp0-3, and received by kernel
> via swp5-eno3 link.
 
> new file mode 100644
> index 000000000000..a88396c137a1
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb-dsa-swp5-eno3.dts
> @@ -0,0 +1,27 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Device Tree file for NXP LS1028A RDB with dsa master swp5-eno3.
> + *
> + * Copyright 2018-2021 NXP
> + *
> + * Hongbo Wang <hongbo.wang at nxp.com>
> + *
> + */
> +
> +/dts-v1/;
> +#include "fsl-ls1028a-rdb.dts"

You will end up with two DT blobs with the same top level
compatible. This is going to cause confusion. I suggest you add an
additional top level compatible to make it clear this differs from the
compatible = "fsl,ls1028a-rdb", "fsl,ls1028a" blob.

   Andrew



From linus.walleij at linaro.org  Fri Aug 13 06:14:01 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 13 Aug 2021 15:14:01 +0200
Subject: [GIT PULL] Delete IXP4xx boardfiles replaced by device trees
Message-ID: <CACRpkdY=sPDkzmbmm+0UQnJi7BXZKH14GLmyVwKC+4cLCJpmdA@mail.gmail.com>

Hi SoC folks,

this concludes the first big chunk of IXP4xx cleanup and DT conversion
by deleting a majority of the boardfiles now supported by the device
trees.

The details of which boardfiles are deleted and the two that are kept can
be found below. The idea is that all devices except the Omicron ones
will keep being supported, but as device trees. Omicron has publicly
stated that they have no interest in keeping supporting the boards,
if someone anyway steps up and need them, scratch device trees
exist on the mailing list.

Since there were a few Kconfig fixes in this rc-phase some collisions
could occur in Kconfig. But I hope not.

Please pull it in!

Yours,
Linus Walleij


The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
tags/ixp4xx-del-boardfiles-v5.15

for you to fetch changes up to b71377b3e1e08bf1e7e3dbbe4ee7aa07971552dc:

  ARM: ixp4xx: Delete the Freecom FSG-3 boardfiles (2021-08-13 14:52:12 +0200)

----------------------------------------------------------------
This deletes the following IXP4xx boardfiles:

- NSLU2
- NAS100D
- D-Link DSM-G600
- Omicron
- Gateway WG302v2
- Arcom Vulcan
- Avila
- Intel reference designs
- Coyote and IXDPG425
- GTW5715
- Freecom FSG-3

In each case except Omicron, the board has been replaced by
a corresponding device tree and tested where someone
volunteered: Marc Zyngier has tested Arcom Vulcan and Freecom
FSG-3 and I have tested NSLU2 and Avila for example. All
that were tested boot to prompt, some devices may need some
more massage before working perfectly.

We can just as well delete these board files because we are
confident that we will fix them to a working state if people
are able to test patches.

I am holding back the following boards for now:

- Gateway 7001 - because Zoltan is working on this board and
  needs more time. He might need to test things with the board
  file so let's allow him time for that.

- Goramo MLR - the consensus is to replace this with a dry
  coded device tree, but the bindings for that tree need some
  more time to make so we keep the boardfile around until
  we can merge a complete device tree for it.

After these two (target v5.16) we can delete the remaining
board files and the old mach structure along with the old PCI
driver.

----------------------------------------------------------------
Linus Walleij (11):
      ARM: ixp4xx: Delete NSLU2 boardfiles
      ARM: ixp4xx: Delete NAS100D boardfiles
      ARM: ixp4xx: Delete the D-Link DSM-G600 boardfiles
      ARM: ixp4xx: Delete Omicron boardfiles
      ARM: ixp4xx: Delete Gateway WG302v2 boardfiles
      ARM: ixp4xx: Delete the Arcom Vulcan boardfiles
      ARM: ixp4xx: Delete Avila boardfiles
      ARM: ixp4xx: Delete Intel reference design boardfiles
      ARM: ixp4xx: Delete Coyote and IXDPG425 boardfiles
      ARM: ixp4xx: Delete GTWX5715 board files
      ARM: ixp4xx: Delete the Freecom FSG-3 boardfiles

 arch/arm/mach-ixp4xx/Kconfig          | 158 ---------------
 arch/arm/mach-ixp4xx/Makefile         |  26 ---
 arch/arm/mach-ixp4xx/avila-pci.c      |  79 --------
 arch/arm/mach-ixp4xx/avila-setup.c    | 210 --------------------
 arch/arm/mach-ixp4xx/coyote-pci.c     |  62 ------
 arch/arm/mach-ixp4xx/coyote-setup.c   | 144 --------------
 arch/arm/mach-ixp4xx/dsmg600-pci.c    |  77 --------
 arch/arm/mach-ixp4xx/dsmg600-setup.c  | 304 -----------------------------
 arch/arm/mach-ixp4xx/fsg-pci.c        |  73 -------
 arch/arm/mach-ixp4xx/fsg-setup.c      | 311 ------------------------------
 arch/arm/mach-ixp4xx/gtwx5715-pci.c   |  72 -------
 arch/arm/mach-ixp4xx/gtwx5715-setup.c | 167 ----------------
 arch/arm/mach-ixp4xx/ixdp425-pci.c    |  75 --------
 arch/arm/mach-ixp4xx/ixdp425-setup.c  | 339 --------------------------------
 arch/arm/mach-ixp4xx/ixdpg425-pci.c   |  56 ------
 arch/arm/mach-ixp4xx/miccpt-pci.c     |  75 --------
 arch/arm/mach-ixp4xx/nas100d-pci.c    |  73 -------
 arch/arm/mach-ixp4xx/nas100d-setup.c  | 353 ----------------------------------
 arch/arm/mach-ixp4xx/nslu2-pci.c      |  69 -------
 arch/arm/mach-ixp4xx/nslu2-setup.c    | 341 --------------------------------
 arch/arm/mach-ixp4xx/omixp-setup.c    | 298 ----------------------------
 arch/arm/mach-ixp4xx/vulcan-pci.c     |  70 -------
 arch/arm/mach-ixp4xx/vulcan-setup.c   | 282 ---------------------------
 arch/arm/mach-ixp4xx/wg302v2-pci.c    |  60 ------
 arch/arm/mach-ixp4xx/wg302v2-setup.c  | 114 -----------
 25 files changed, 3888 deletions(-)
 delete mode 100644 arch/arm/mach-ixp4xx/avila-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/avila-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/coyote-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/coyote-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/dsmg600-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/dsmg600-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/fsg-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/fsg-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/gtwx5715-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/gtwx5715-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/ixdp425-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/ixdp425-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/ixdpg425-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/miccpt-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/nas100d-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/nas100d-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/nslu2-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/nslu2-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/omixp-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/vulcan-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/vulcan-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/wg302v2-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/wg302v2-setup.c


From robh at kernel.org  Fri Aug 13 06:34:11 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 08:34:11 -0500
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference in
 probe
In-Reply-To: <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
Message-ID: <CAL_JsqJ4Dadf00pJxEDd14zbWyN99s1A2L4fxZSkZddeg2pV6g@mail.gmail.com>

On Fri, Aug 13, 2021 at 7:55 AM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2021-08-13 12:33, Dan Carpenter wrote:
> > If devm_regulator_get_optional() returns an error pointer, then we
> > should return it to the user.  The current code makes an exception
> > for -ENODEV that will result in an error pointer dereference on the
> > next line when it calls regulator_enable().  Remove the exception.
>
> Doesn't this break the apparent intent of the regulator being optional,
> though?

I'm pretty sure 'optional' means ENODEV is never returned. So there
wasn't any real problem, but the check was unnecessary.

>
> Robin.
>
> > Fixes: e1229e884e19 ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver")
> > Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
> > ---
> >   drivers/pci/controller/dwc/pcie-dw-rockchip.c | 5 ++---
> >   1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> > index 20cef2e06f66..2d0ffd3c4e16 100644
> > --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> > +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> > @@ -225,9 +225,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
> >       /* DON'T MOVE ME: must be enable before PHY init */
> >       rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
> >       if (IS_ERR(rockchip->vpcie3v3))
> > -             if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV)
> > -                     return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
> > -                                     "failed to get vpcie3v3 regulator\n");
> > +             return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
> > +                                  "failed to get vpcie3v3 regulator\n");
> >
> >       ret = regulator_enable(rockchip->vpcie3v3);
> >       if (ret) {
> >


From quic_qiancai at quicinc.com  Fri Aug 13 06:42:52 2021
From: quic_qiancai at quicinc.com (Qian Cai)
Date: Fri, 13 Aug 2021 09:42:52 -0400
Subject: [Internet]Re: [PATCH v5] arm pl011 serial: support multi-irq
 request
In-Reply-To: <09918b566884413898f63b92ddd037a0@tencent.com>
References: <1625103512-30182-1-git-send-email-hptsfb@gmail.com>
 <60f007b3-bb01-dd0a-b1a2-a6da62a486e5@quicinc.com>
 <3b60d054-4e22-62fa-c31b-29b146495a65@gmail.com>
 <a1843494-5c8e-1ec8-5b98-df318db40922@quicinc.com>
 <7535ae2f-6a12-8203-0498-8ac85ab0d9a7@arm.com>
 <290c01ec-173f-755f-788e-2a33a69586e8@quicinc.com>
 <e98962f3-9232-4abf-ec27-a7524a9e786d@arm.com>
 <bddf2712-72f4-2e20-da17-33b3de08f769@gmail.com>
 <0819592c-1baa-e98d-9118-5abde8b8c562@quicinc.com>
 <67cd6c830e33491e99ea4d2480f4a89d@tencent.com>
 <09918b566884413898f63b92ddd037a0@tencent.com>
Message-ID: <0206c94d-c91b-b7da-8132-d06e23c9d964@quicinc.com>



On 8/12/2021 11:32 PM, tombinfan(??) wrote:
> hello,
> 
> I have sent the modified patch to the following mailboxes. THX
> 
> gregkh at linuxfoundation.org
> linux-serial at vger.kernel.org
> linux-kernel at vger.kernel.org

Thanks for the pointer. It is good to get some reviews from Arm
people in the first place, so we don't break Arm like this.

Anyway, for anyone who might be watching, here is the new patch,

https://lore.kernel.org/linux-serial/1628825490-18937-1-git-send-email-hptsfb at gmail.com/

Unfortunately, I saw Greg mentioned that it was not based on
tty-next, so not something I can apply easily on linux-next here
as well.


From robin.murphy at arm.com  Fri Aug 13 06:47:14 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 14:47:14 +0100
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference in
 probe
In-Reply-To: <CAL_JsqJ4Dadf00pJxEDd14zbWyN99s1A2L4fxZSkZddeg2pV6g@mail.gmail.com>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
 <CAL_JsqJ4Dadf00pJxEDd14zbWyN99s1A2L4fxZSkZddeg2pV6g@mail.gmail.com>
Message-ID: <81b9a25d-f12f-90e0-0b05-b5e396f14c08@arm.com>

On 2021-08-13 14:34, Rob Herring wrote:
> On Fri, Aug 13, 2021 at 7:55 AM Robin Murphy <robin.murphy at arm.com> wrote:
>>
>> On 2021-08-13 12:33, Dan Carpenter wrote:
>>> If devm_regulator_get_optional() returns an error pointer, then we
>>> should return it to the user.  The current code makes an exception
>>> for -ENODEV that will result in an error pointer dereference on the
>>> next line when it calls regulator_enable().  Remove the exception.
>>
>> Doesn't this break the apparent intent of the regulator being optional,
>> though?
> 
> I'm pretty sure 'optional' means ENODEV is never returned. So there
> wasn't any real problem, but the check was unnecessary.

In fact it's the other way round - "optional" in this case is for when 
the supply may legitimately not exist so the driver may or may not need 
to handle it, so it can return -ENODEV if a regulator isn't described by 
firmware. A non-optional regulator is assumed to represent a necessary 
supply, so if there's nothing described by firmware you get the (valid) 
dummy regulator back.

Robin.

>>> Fixes: e1229e884e19 ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver")
>>> Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
>>> ---
>>>    drivers/pci/controller/dwc/pcie-dw-rockchip.c | 5 ++---
>>>    1 file changed, 2 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>>> index 20cef2e06f66..2d0ffd3c4e16 100644
>>> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>>> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>>> @@ -225,9 +225,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>>>        /* DON'T MOVE ME: must be enable before PHY init */
>>>        rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
>>>        if (IS_ERR(rockchip->vpcie3v3))
>>> -             if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV)
>>> -                     return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
>>> -                                     "failed to get vpcie3v3 regulator\n");
>>> +             return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
>>> +                                  "failed to get vpcie3v3 regulator\n");
>>>
>>>        ret = regulator_enable(rockchip->vpcie3v3);
>>>        if (ret) {
>>>


From robin.murphy at arm.com  Fri Aug 13 06:51:54 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 14:51:54 +0100
Subject: [PATCH v3] arm64: dts: rockchip: add thermal fan control to
 rockpro64
In-Reply-To: <ad6d8025-977c-9ff2-81ff-a417df48231c@linaro.org>
References: <20210730151727.729822-1-pgwipeout@gmail.com>
 <ad6d8025-977c-9ff2-81ff-a417df48231c@linaro.org>
Message-ID: <893701da-ea17-00ab-5e31-c745051ac9b9@arm.com>

On 2021-08-13 13:59, Daniel Lezcano wrote:
> On 30/07/2021 17:17, Peter Geis wrote:
>> The rockpro64 had a fan node since
>> commit 5882d65c1691 ("arm64: dts: rockchip: Add PWM fan for RockPro64")
>> however it was never tied into the thermal driver for automatic control.
>>
>> Add the links to the thermal node to permit the kernel to handle this
>> automatically.
>> Borrowed from the (rk3399-khadas-edge.dtsi).
>>
>> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>> ---
>>
>> Changelog:
>> v3:
>> Removed the gpu nodes to prevent in-fighting (thanks Robin!)
>>
>> v2:
>> Adjusted fan setpoints for less noise
>>
>>   .../boot/dts/rockchip/rk3399-rockpro64.dtsi   | 29 +++++++++++++++++++
>>   1 file changed, 29 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
>> index 6bff8db7d33e..83db4ca67334 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
>> @@ -69,6 +69,7 @@ diy_led: led-1 {
>>   
>>   	fan: pwm-fan {
>>   		compatible = "pwm-fan";
>> +		cooling-levels = <0 100 150 200 255>;
>>   		#cooling-cells = <2>;
>>   		fan-supply = <&vcc12v_dcin>;
>>   		pwms = <&pwm1 0 50000 0>;
>> @@ -245,6 +246,34 @@ &cpu_b1 {
>>   	cpu-supply = <&vdd_cpu_b>;
>>   };
>>   
>> +&cpu_thermal {
>> +	trips {
>> +		cpu_warm: cpu_warm {
>> +			temperature = <55000>;
>> +			hysteresis = <2000>;
>> +			type = "active";
>> +		};
>> +
>> +		cpu_hot: cpu_hot {
>> +			temperature = <65000>;
>> +			hysteresis = <2000>;
>> +			type = "active";
>> +		};
>> +	};
>> +
> 
> Why two trip points ?
> 
> Why not one functioning temperature and no lower / upper limits for the
> cooling maps ?

Certainly when I first did this for NanoPC-T4, IIRC it was to avoid the 
fan ramping up too eagerly, since level 1 for my fan is effectively 
silent but still cools enough to let a moderate load eventually settle 
to a steady state below the second trip.

Robin.

>> +	cooling-maps {
>> +		map2 {
>> +			trip = <&cpu_warm>;
>> +			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
>> +		};
>> +
>> +		map3 {
>> +			trip = <&cpu_hot>;
>> +			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
>> +		};
>> +	};
>> +};
>> +
>>   &emmc_phy {
>>   	status = "okay";
>>   };
>>
> 
> 


From dan.carpenter at oracle.com  Fri Aug 13 06:54:12 2021
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Fri, 13 Aug 2021 16:54:12 +0300
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference
 in probe
In-Reply-To: <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
Message-ID: <20210813135412.GA7722@kadam>

On Fri, Aug 13, 2021 at 01:55:38PM +0100, Robin Murphy wrote:
> On 2021-08-13 12:33, Dan Carpenter wrote:
> > If devm_regulator_get_optional() returns an error pointer, then we
> > should return it to the user.  The current code makes an exception
> > for -ENODEV that will result in an error pointer dereference on the
> > next line when it calls regulator_enable().  Remove the exception.
> 
> Doesn't this break the apparent intent of the regulator being optional,
> though?

Argh...  Crap.  My patch is wrong, but the bug is real.

This code should follow the standard kernel idiom of returning error
pointers when there are errors and returning NULL when an optional
feature is disabled.  The problem with returning a Special Error code
to mean "disabled" is that someone will use the Special Error code to
mean an error.

And that has already sort of happened, because _regulator_get() returns
-ENODEV which would will cause the Oops I described in my patch.

Ugh...  The correct thing is to convert it to NULL/error pointers.  I
have not looked at how hard that is though...

regards,
dan carpenter




From hongbo.wang at nxp.com  Fri Aug 13 06:56:53 2021
From: hongbo.wang at nxp.com (Hongbo Wang)
Date: Fri, 13 Aug 2021 13:56:53 +0000
Subject: [EXT] Re: [PATCH v1] arm64: dts: fsl: ls1028a-rdb: Add dts file
 to choose swp5 as dsa master
In-Reply-To: <YRZvItRlSpF2Xf+S@lunn.ch>
References: <20210813030155.23097-1-hongbo.wang@nxp.com>
 <YRZvItRlSpF2Xf+S@lunn.ch>
Message-ID: <VI1PR04MB56773CC01AB86A8AA1A33F9AE1FA9@VI1PR04MB5677.eurprd04.prod.outlook.com>


> On Fri, Aug 13, 2021 at 11:01:55AM +0800, hongbo.wang at nxp.com wrote:
> > From: hongbo wang <hongbo.wang at nxp.com>
> >
> > some use cases want to use swp4-eno2 link as ordinary data path, so we
> > can enable swp5 as dsa master, the data from kernel can be transmitted
> > to eno3, then send to swp5 via internal link, switch will forward it
> > to swp0-3.
> >
> > the data to kernel will come from swp0-3, and received by kernel via
> > swp5-eno3 link.
> 
> > new file mode 100644
> > index 000000000000..a88396c137a1
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb-dsa-swp5-eno3.dts
> > @@ -0,0 +1,27 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Device Tree file for NXP LS1028A RDB with dsa master swp5-eno3.
> > + *
> > + * Copyright 2018-2021 NXP
> > + *
> > + * Hongbo Wang <hongbo.wang at nxp.com>
> > + *
> > + */
> > +
> > +/dts-v1/;
> > +#include "fsl-ls1028a-rdb.dts"
> 
> You will end up with two DT blobs with the same top level compatible. This is
> going to cause confusion. I suggest you add an additional top level compatible
> to make it clear this differs from the compatible = "fsl,ls1028a-rdb",
> "fsl,ls1028a" blob.
> 
>    Andrew

hi Andrew, 

  thanks for comments.

  this "fsl-ls1028a-rdb-dsa-swp5-eno3.dts" is also for fsl-ls1028a-rdb platform,
the only difference with "fsl-ls1028a-rdb.dts" is that it use swp5 as dsa master, not swp4,
and it's based on "fsl-ls1028a-rdb.dts", so I choose this manner,
if "fsl-ls1028a-rdb.dts" has some modification for new version, this file don't need be changed.

thanks,
hongbo



From robin.murphy at arm.com  Fri Aug 13 07:01:10 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 15:01:10 +0100
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference in
 probe
In-Reply-To: <20210813135412.GA7722@kadam>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com> <20210813135412.GA7722@kadam>
Message-ID: <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>

On 2021-08-13 14:54, Dan Carpenter wrote:
> On Fri, Aug 13, 2021 at 01:55:38PM +0100, Robin Murphy wrote:
>> On 2021-08-13 12:33, Dan Carpenter wrote:
>>> If devm_regulator_get_optional() returns an error pointer, then we
>>> should return it to the user.  The current code makes an exception
>>> for -ENODEV that will result in an error pointer dereference on the
>>> next line when it calls regulator_enable().  Remove the exception.
>>
>> Doesn't this break the apparent intent of the regulator being optional,
>> though?
> 
> Argh...  Crap.  My patch is wrong, but the bug is real.

Yeah, I guess this probably wants to follow the same pattern as 
rockchip_pcie_set_vpcie() in the older driver, where it's the regulator 
API calls which get wrapped in checks.

> This code should follow the standard kernel idiom of returning error
> pointers when there are errors and returning NULL when an optional
> feature is disabled.  The problem with returning a Special Error code
> to mean "disabled" is that someone will use the Special Error code to
> mean an error.
> 
> And that has already sort of happened, because _regulator_get() returns
> -ENODEV which would will cause the Oops I described in my patch.
> 
> Ugh...  The correct thing is to convert it to NULL/error pointers.  I
> have not looked at how hard that is though...

Indeed I've thought before that it would be nice if regulators worked 
like GPIOs, where the absence of an optional one does give you NULL, and 
most of the API is also NULL-safe. Probably a pretty big job though...

Thanks,
Robin.


From vladimir.oltean at nxp.com  Fri Aug 13 07:07:46 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Fri, 13 Aug 2021 14:07:46 +0000
Subject: [EXT] Re: [PATCH v1] arm64: dts: fsl: ls1028a-rdb: Add dts file
 to choose swp5 as dsa master
In-Reply-To: <VI1PR04MB56773CC01AB86A8AA1A33F9AE1FA9@VI1PR04MB5677.eurprd04.prod.outlook.com>
References: <20210813030155.23097-1-hongbo.wang@nxp.com>
 <YRZvItRlSpF2Xf+S@lunn.ch>
 <VI1PR04MB56773CC01AB86A8AA1A33F9AE1FA9@VI1PR04MB5677.eurprd04.prod.outlook.com>
Message-ID: <20210813140745.fwjkmixzgvikvffz@skbuf>

On Fri, Aug 13, 2021 at 01:56:53PM +0000, Hongbo Wang wrote:
> > You will end up with two DT blobs with the same top level compatible. This is
> > going to cause confusion. I suggest you add an additional top level compatible
> > to make it clear this differs from the compatible = "fsl,ls1028a-rdb",
> > "fsl,ls1028a" blob.
> >
> >    Andrew
>
> hi Andrew,
>
>   thanks for comments.
>
>   this "fsl-ls1028a-rdb-dsa-swp5-eno3.dts" is also for fsl-ls1028a-rdb platform,
> the only difference with "fsl-ls1028a-rdb.dts" is that it use swp5 as dsa master, not swp4,
> and it's based on "fsl-ls1028a-rdb.dts", so I choose this manner,
> if "fsl-ls1028a-rdb.dts" has some modification for new version, this file don't need be changed.

I tend to agree with Hongbo. What confusion is it going to cause? It is
fundamentally the same board, just an Ethernet port stopped having
'status = "disabled"' and another changed role, all inside of the SoC
with no externally-visible change. If anything, I think that creating a
new top-level compatible for each small change like this would create a
bloat-fest of its own.

I was going to suggest as an alternative to define a device tree overlay
file with the changes in the CPU port assignment, instead of defining a
wholly new DTS for the LS1028A reference design board. But I am pretty
sure that it is not possible to specify a /delete-property/ inside a
device tree overlay file, so that won't actually work.

From narmstrong at baylibre.com  Fri Aug 13 07:12:59 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 13 Aug 2021 16:12:59 +0200
Subject: [GIT PULL] arm64: dts: amlogic updates for v5.15 part 2
Message-ID: <47d77095-eee7-bbd9-d3aa-1dabeea3f0b9@baylibre.com>

Hi,

Here's the second set of ARM64 DT changes for v5.15:
- add audio nodes for vega-s95 & nexbox-a1

Neil

The following changes since commit 4b5260032ec691b11a9185f7f38f5761e67fab48:

  arm64: dts: meson: improve gxm-khadas-vim2 wifi (2021-07-26 10:08:16 +0200)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git amlogic-arm64-dt-for-v5.15-v2

for you to fetch changes up to c6cf488e3bfdf92427686317d99e0342516753de:

  arm64: dts: meson: add audio playback to vega-s95 dtsi (2021-08-10 09:57:05 +0200)

----------------------------------------------------------------
Amlogic ARM64 DT changes for v5.15 part 2:
- add audio to nodes vega-s95
- add audio to nodes nexbox-a1

----------------------------------------------------------------
Christian Hewitt (2):
      arm64: dts: meson: add audio playback to nexbox-a1
      arm64: dts: meson: add audio playback to vega-s95 dtsi

 .../boot/dts/amlogic/meson-gxbb-vega-s95.dtsi      | 61 ++++++++++++++++++++++
 .../arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 61 ++++++++++++++++++++++
 2 files changed, 122 insertions(+)


From dan.carpenter at oracle.com  Fri Aug 13 07:12:57 2021
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Fri, 13 Aug 2021 17:12:57 +0300
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference
 in probe
In-Reply-To: <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
 <20210813135412.GA7722@kadam>
 <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>
Message-ID: <20210813141257.GB7722@kadam>

On Fri, Aug 13, 2021 at 03:01:10PM +0100, Robin Murphy wrote:
> Indeed I've thought before that it would be nice if regulators worked like
> GPIOs, where the absence of an optional one does give you NULL, and most of
> the API is also NULL-safe. Probably a pretty big job though...

Yeah.  You have to write a NULL-safe API with optional feature.  And,
yeah, it's a lot of work to do it in retroactively...  Too much.  I'll
just redo my patch.

regards,
dan carpenter


From andrew at lunn.ch  Fri Aug 13 07:25:37 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 13 Aug 2021 16:25:37 +0200
Subject: [EXT] Re: [PATCH v1] arm64: dts: fsl: ls1028a-rdb: Add dts file
 to choose swp5 as dsa master
In-Reply-To: <20210813140745.fwjkmixzgvikvffz@skbuf>
References: <20210813030155.23097-1-hongbo.wang@nxp.com>
 <YRZvItRlSpF2Xf+S@lunn.ch>
 <VI1PR04MB56773CC01AB86A8AA1A33F9AE1FA9@VI1PR04MB5677.eurprd04.prod.outlook.com>
 <20210813140745.fwjkmixzgvikvffz@skbuf>
Message-ID: <YRaA4VeRM0deApXu@lunn.ch>

> >   this "fsl-ls1028a-rdb-dsa-swp5-eno3.dts" is also for fsl-ls1028a-rdb platform,
> > the only difference with "fsl-ls1028a-rdb.dts" is that it use swp5 as dsa master, not swp4,
> > and it's based on "fsl-ls1028a-rdb.dts", so I choose this manner,
> > if "fsl-ls1028a-rdb.dts" has some modification for new version, this file don't need be changed.
> 
> I tend to agree with Hongbo. What confusion is it going to cause?

I don't know if Debian, or any other distribution, ever implemented
it, but it was suggested that the install media read the available DT
blobs and present the user with a list they can choose from. I've no
idea if this was based on the blob filename, or if it read the
compatible string.

The Compatible string is also printed in the kernel log at boot. If it
is not unique, you need further information to figure out the blob
sources.

We probably needs Rob input. Are there other boards with multiple
blobs? Do they use the same or different compatible strings?

       Andrew


From dan.carpenter at oracle.com  Fri Aug 13 07:26:48 2021
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Fri, 13 Aug 2021 17:26:48 +0300
Subject: [PATCH v2] PCI: rockchip-dwc: Potential error pointer dereference in
 probe
In-Reply-To: <20210813141257.GB7722@kadam>
Message-ID: <20210813142648.GA12057@kili>

If devm_regulator_get_optional() returns -ENODEV then it would lead
to an error pointer dereference on the next line and in the error
handling code.

Fixes: e1229e884e19 ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver")
Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
---
v2: The -ENODEV from devm_regulator_get_optional() has to be handled
    specially.

 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 20cef2e06f66..c9b341e55cbb 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -224,15 +224,17 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
 
 	/* DON'T MOVE ME: must be enable before PHY init */
 	rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
-	if (IS_ERR(rockchip->vpcie3v3))
+	if (IS_ERR(rockchip->vpcie3v3)) {
 		if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV)
 			return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
 					"failed to get vpcie3v3 regulator\n");
-
-	ret = regulator_enable(rockchip->vpcie3v3);
-	if (ret) {
-		dev_err(dev, "failed to enable vpcie3v3 regulator\n");
-		return ret;
+		rockchip->vpcie3v3 = NULL;
+	} else {
+		ret = regulator_enable(rockchip->vpcie3v3);
+		if (ret) {
+			dev_err(dev, "failed to enable vpcie3v3 regulator\n");
+			return ret;
+		}
 	}
 
 	ret = rockchip_pcie_phy_init(rockchip);
@@ -255,7 +257,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
 deinit_phy:
 	rockchip_pcie_phy_deinit(rockchip);
 disable_regulator:
-	regulator_disable(rockchip->vpcie3v3);
+	if (rockchip->vpcie3v3)
+		regulator_disable(rockchip->vpcie3v3);
 
 	return ret;
 }
-- 
2.20.1



From radu-nicolae.pirea at oss.nxp.com  Fri Aug 13 07:27:42 2021
From: radu-nicolae.pirea at oss.nxp.com (Radu Nicolae Pirea (NXP OSS))
Date: Fri, 13 Aug 2021 17:27:42 +0300
Subject: [PATCH 3/8] dt-bindings: serial: fsl-linflexuart: Add
 compatible for S32G2
In-Reply-To: <96c02ee6-cd3a-59df-0b3b-1632bb355019@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-4-clin@suse.com>
 <96c02ee6-cd3a-59df-0b3b-1632bb355019@suse.de>
Message-ID: <a0b5810b958eda8149ad498b76b7b05f758b8928.camel@oss.nxp.com>

On Thu, 2021-08-12 at 18:27 +0200, Andreas F?rber wrote:
> On 05.08.21 08:54, Chester Lin wrote:
> > Add a compatible string for the uart binding of NXP S32G2
> > platforms. Here
> > we use "s32v234-linflexuart" as fallback since the current
> > linflexuart
> > driver still works on S32G2.
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> > ?.../bindings/serial/fsl,s32-linflexuart.yaml? | 26
> > ++++++++++++++++---
> > ?1 file changed, 22 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-
> > linflexuart.yaml
> > b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > index acfe34706ccb..e731f3f6cea4 100644
> > --- a/Documentation/devicetree/bindings/serial/fsl,s32-
> > linflexuart.yaml
> > +++ b/Documentation/devicetree/bindings/serial/fsl,s32-
> > linflexuart.yaml
> > @@ -21,10 +21,20 @@ allOf:
> > ?
> > ?properties:
> > ?? compatible:
> > -??? description: The LINFlexD controller on S32V234 SoC, which can
> > be
> > -????? configured in UART mode.
> > -??? items:
> > -????? - const: fsl,s32v234-linflexuart
> > +??? minItems: 1
> > +??? maxItems: 2
> 
> Are these necessary for oneOf?
> 
> > +??? oneOf:
> > +????? - description: The LINFlexD controller on S32G2 SoC, which
> > can be
> > +????????? configured in UART mode.
> > +??????? items:
> > +????????? - enum:
> > +????????????? - fsl,s32g2-linflexuart
> > +????????? - const: fsl,s32v234-linflexuart
> 
> This reads inconsistent to me: Either this oneOf is for S32G2 only,
> then
> please turn the enum into a const. Or change the description to "on
> SoCs
> compatible with S32V234" if we expect the enum list to grow.
> 
> I believe the idea here was to avoid unnecessary driver compatible
> and
> earlycon compatible additions, while preparing for eventual quirks
> specific to S32G2.
> 
> @NXP: Should this be s32g2- like above or s32g274a- specifically? Do
> you
> agree this is a useful thing to prepare here, as opposed to using
> only
> s32v234- in the s32g2* DT?

s32g2- is fine, but the vendor should be nxp, not fsl.
nxp,s32g2-linflexuart

> 
> I assume the ordering is done alphabetically as S32G < S32V;
> alternatively we might order S32V234 first and then the compatible
> ones.
> 
> > +
> > +????? - description: The LINFlexD controller on S32V234 SoC, which
> > can be
> > +????????? configured in UART mode.
> > +??????? items:
> > +????????? - const: fsl,s32v234-linflexuart
> 
> To minimize this S32G2 patch, would it be valid to do oneOf for the
> single S32V in the preceding patch already? Then we would avoid the
> text
> movement and re-indentation above and more easily see the lines newly
> getting added for S32G2.
> 
> > ?
> > ?? reg:
> > ???? maxItems: 1
> > @@ -41,8 +51,16 @@ unevaluatedProperties: false
> > ?
> > ?examples:
> > ?? - |
> > +??? /* S32V234 */
> 
> Could this be:
> ? - description: S32V234
> ??? |
> ?
> 
> > ???? serial at 40053000 {
> > ???????? compatible = "fsl,s32v234-linflexuart";
> > ???????? reg = <0x40053000 0x1000>;
> > ???????? interrupts = <0 59 4>;
> > ???? };
> > +
> > +??? /* S32G2 */
> 
> This should not be part of the S32V example, but a new one:
> 
> ? - |
> 
> (or with description, as discussed above)
> 
> > +??? serial at 401c8000 {
> > +??????? compatible = "fsl,s32g2-linflexuart", "fsl,s32v234-
> > linflexuart";
> 
> Potentially affected by naming discussions above.
> 
> > +??????? reg = <0x401c8000 0x3000>;
> > +??????? interrupts = <0 82 1>;
> > +??? };
> 
> Regards,
> Andreas
> 




From broonie at kernel.org  Fri Aug 13 07:32:50 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Aug 2021 15:32:50 +0100
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference
 in probe
In-Reply-To: <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
 <20210813135412.GA7722@kadam>
 <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>
Message-ID: <20210813143250.GA5209@sirena.org.uk>

On Fri, Aug 13, 2021 at 03:01:10PM +0100, Robin Murphy wrote:

> Indeed I've thought before that it would be nice if regulators worked like
> GPIOs, where the absence of an optional one does give you NULL, and most of
> the API is also NULL-safe. Probably a pretty big job though...

It also encourages *really* bad practice with error handling, and in
general there are few use cases for optional regulators where there's
not some other actions that need to be taken in the case where the
supply isn't there (elimintating some operating points or features,
reconfiguring power internally and so on).  If we genuninely don't need
to do anything special one wonders why we're trying to turn the power on
in the first place.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/4eb2aeb2/attachment.sig>

From will at kernel.org  Fri Aug 13 07:33:48 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 13 Aug 2021 15:33:48 +0100
Subject: [PATCHv5] iommu/arm-smmu: Optimize ->tlb_flush_walk() for qcom
 implementation
In-Reply-To: <20210811160426.10312-1-saiprakash.ranjan@codeaurora.org>
References: <20210811160426.10312-1-saiprakash.ranjan@codeaurora.org>
Message-ID: <162886044327.2821414.7990736519109651727.b4-ty@kernel.org>

On Wed, 11 Aug 2021 21:34:26 +0530, Sai Prakash Ranjan wrote:
> Currently for iommu_unmap() of large scatter-gather list with page size
> elements, the majority of time is spent in flushing of partial walks in
> __arm_lpae_unmap() which is a VA based TLB invalidation invalidating
> page-by-page on iommus like arm-smmu-v2 (TLBIVA).
> 
> For example: to unmap a 32MB scatter-gather list with page size elements
> (8192 entries), there are 16->2MB buffer unmaps based on the pgsize (2MB
> for 4K granule) and each of 2MB will further result in 512 TLBIVAs (2MB/4K)
> resulting in a total of 8192 TLBIVAs (512*16) for 16->2MB causing a huge
> overhead.
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/1] iommu/arm-smmu: Optimize ->tlb_flush_walk() for qcom implementation
      https://git.kernel.org/will/c/ef75702d6d65

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Aug 13 07:33:47 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 13 Aug 2021 15:33:47 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Stop pre-zeroing batch commands
In-Reply-To: <1628696966-88386-1-git-send-email-john.garry@huawei.com>
References: <1628696966-88386-1-git-send-email-john.garry@huawei.com>
Message-ID: <162886116698.2824022.16783624022186581694.b4-ty@kernel.org>

On Wed, 11 Aug 2021 23:49:26 +0800, John Garry wrote:
> Pre-zeroing the batched commands structure is inefficient, as individual
> commands are zeroed later in arm_smmu_cmdq_build_cmd(). The size is quite
> large and commonly most commands won't even be used:
> 
> 	struct arm_smmu_cmdq_batch cmds = {};
> 345c:	52800001 	mov	w1, #0x0                   	// #0
> 3460:	d2808102 	mov	x2, #0x408                 	// #1032
> 3464:	910143a0 	add	x0, x29, #0x50
> 3468:	94000000 	bl	0 <memset>
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/1] iommu/arm-smmu-v3: Stop pre-zeroing batch commands
      https://git.kernel.org/will/c/fac956710ab0

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Aug 13 07:33:49 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 13 Aug 2021 15:33:49 +0100
Subject: [PATCH 0/4] Prepare for ECMDQ support
In-Reply-To: <20210811114852.2429-1-thunder.leizhen@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
Message-ID: <162886058252.2822076.1201372357126525246.b4-ty@kernel.org>

On Wed, 11 Aug 2021 19:48:48 +0800, Zhen Lei wrote:
> RFC --> v1
> 1. Resend the patches for ECMDQ preparation and remove the patches for ECMDQ implementation.
> 2. Patch 2 is modified. Other patches remain unchanged.
>    1) Add static helper __arm_smmu_cmdq_issue_cmd(), and make arm_smmu_cmdq_issue_cmd()
>       and arm_smmu_cmdq_issue_cmd_with_sync() implement based on it.
>    2) Remove unused arm_smmu_cmdq_issue_sync().
> 
> [...]

Applied to will (for-joerg/arm-smmu/updates), thanks!

[1/4] iommu/arm-smmu-v3: Use command queue batching helpers to improve performance
      https://git.kernel.org/arm64/c/eff19474b1bd
[2/4] iommu/arm-smmu-v3: Add and use static helper function arm_smmu_cmdq_issue_cmd_with_sync()
      https://git.kernel.org/arm64/c/4537f6f1e2d8
[3/4] iommu/arm-smmu-v3: Add and use static helper function arm_smmu_get_cmdq()
      https://git.kernel.org/arm64/c/8639cc83aac5
[4/4] iommu/arm-smmu-v3: Extract reusable function __arm_smmu_cmdq_skip_err()
      https://git.kernel.org/arm64/c/2cbeaf3f36eb

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From will at kernel.org  Fri Aug 13 07:40:27 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 13 Aug 2021 15:40:27 +0100
Subject: [PATCH v8 2/2] drivers/perf: hisi: Add driver for HiSilicon PCIe
 PMU
In-Reply-To: <a56266c4-c434-f078-6027-f30c021bd593@huawei.com>
References: <20210728080932.72515-1-liuqi115@huawei.com>
 <20210728080932.72515-3-liuqi115@huawei.com>
 <20210802100343.GA27282@willie-the-truck>
 <a56266c4-c434-f078-6027-f30c021bd593@huawei.com>
Message-ID: <20210813144026.GA8451@willie-the-truck>

On Wed, Aug 04, 2021 at 03:29:54PM +0800, liuqi (BA) wrote:
> 
> Hi Will,
> > Hmm, I was hoping that you would expose all the events as proper perf_events
> > and get rid of the subevents entirely.
> > 
> > Then userspace could do things like:
> > 
> >    // Count number of RX memory reads
> >    $ perf stat -e hisi_pcie0_0/rx_memory_read/
> > 
> >    // Count delay cycles
> >    $ perf stat -e hisi_pcie0_0/latency/
> > 
> >    // Count both of the above (events must be in the same group)
> >    $ perf stat -g -e hisi_pcie0_0/latency/ -e hisi_pcie0_0/rx_memory_read/
> > 
> > Note that in all three of these cases the hardware will be programmed in
> > the same way and both HISI_PCIE_CNT and HISI_PCIE_EXT_CNT are allocated!
> > 
> > So for example, doing this (i.e. without the '-g'):
> > 
> >    $ perf stat -e hisi_pcie0_0/latency/ -e hisi_pcie0_0/rx_memory_read/
> > 
> > would fail because the first event would allocate both of the counters.
> 
> I'm confused with this situation when getting rid of subevent:
> 
> $ perf stat -e hisi_pcie0_0/latency/ -e hisi_pcie0_0/rx_memory_read/
> 
> In this case, driver checks the relationship of "latency" and
> "rx_memory_read" in pmu->add() function and return a -EINVAL, but this seems
> lead to time division multiplexing.
> 
> 	if (event->pmu->add(event, PERF_EF_START)) {
> 		perf_event_set_state(event, PERF_EVENT_STATE_INACTIVE);
> 		event->oncpu = -1;
> 		ret = -EAGAIN;
> 		goto out;
> 	}
> 	...
> out:
> 	perf_pmu_enable(event->pmu);
> 
> This result doesn't meet our expection, do I miss something here?

This is how perf works. If you don't want multiplexing, put the events in a
group. What's the problem with that?

Will


From lorenzo.pieralisi at arm.com  Fri Aug 13 07:40:28 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 13 Aug 2021 15:40:28 +0100
Subject: [PATCH v3 0/2] PCI: xilinx-nwl: Add clock handling
In-Reply-To: <cover.1624618100.git.michal.simek@xilinx.com>
References: <cover.1624618100.git.michal.simek@xilinx.com>
Message-ID: <162886561478.21160.11916586885494837733.b4-ty@arm.com>

On Fri, 25 Jun 2021 12:48:21 +0200, Michal Simek wrote:
> this small series add support for enabling PCIe reference clock by driver.
> 
> Thanks,
> Michal
> 
> Changes in v3:
> - use PCIe instead of pcie
> - add stable cc
> - update commit message - reported by Krzysztof
> 
> [...]

Applied to pci/xilinx-nwl, thanks!

[1/2] dt-bindings: pci: xilinx-nwl: Document optional clock property
      https://git.kernel.org/lpieralisi/pci/c/4d79e36718
[2/2] PCI: xilinx-nwl: Enable the clock through CCF
      https://git.kernel.org/lpieralisi/pci/c/de0a01f529

Thanks,
Lorenzo


From andrew at lunn.ch  Fri Aug 13 07:45:58 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 13 Aug 2021 16:45:58 +0200
Subject: [PATCH v2 4/6] ARM: dts: aspeed: Add Facebook Cloudripper
 (AST2600) BMC
In-Reply-To: <20210813034016.GA21895@taoren-ubuntu-R90MNF91>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
 <20210805222818.8391-5-rentao.bupt@gmail.com>
 <CACPK8XcV5On2D4D+SXnfw1M0owwfCL4Su19jOEA7yWpq+T3jLw@mail.gmail.com>
 <20210813034016.GA21895@taoren-ubuntu-R90MNF91>
Message-ID: <YRaFpq1LvRzMYr/A@lunn.ch>

On Thu, Aug 12, 2021 at 08:40:17PM -0700, Tao Ren wrote:
> On Fri, Aug 13, 2021 at 01:29:17AM +0000, Joel Stanley wrote:
> > On Thu, 5 Aug 2021 at 22:28, <rentao.bupt at gmail.com> wrote:
> > > +&mdio1 {
> > > +       status = "okay";
> > 
> > You're enabling this but it looks like it's unused?
> 
> Thanks Joel for the careful review. The MDIO controller is not paired
> with BMC MAC; instead, it's connected to the MDC/MDIO interface of the
> on-board switch (whose ports are connected to BMC, Host and front panel
> management port).

What switch is it? Is there a DSA driver for it? drivers/net/dsa/*
Ideally you want Linux to be controlling the switch, in the standard
linux way.

     Andrew


From daniel.lezcano at linaro.org  Fri Aug 13 07:54:42 2021
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 13 Aug 2021 16:54:42 +0200
Subject: [PATCH v3] arm64: dts: rockchip: add thermal fan control to
 rockpro64
In-Reply-To: <893701da-ea17-00ab-5e31-c745051ac9b9@arm.com>
References: <20210730151727.729822-1-pgwipeout@gmail.com>
 <ad6d8025-977c-9ff2-81ff-a417df48231c@linaro.org>
 <893701da-ea17-00ab-5e31-c745051ac9b9@arm.com>
Message-ID: <2b1050f2-0311-1871-820a-f876218894bc@linaro.org>


Hi Robin,


On 13/08/2021 15:51, Robin Murphy wrote:
> On 2021-08-13 13:59, Daniel Lezcano wrote:
>> On 30/07/2021 17:17, Peter Geis wrote:
>>> The rockpro64 had a fan node since
>>> commit 5882d65c1691 ("arm64: dts: rockchip: Add PWM fan for RockPro64")
>>> however it was never tied into the thermal driver for automatic control.
>>>
>>> Add the links to the thermal node to permit the kernel to handle this
>>> automatically.
>>> Borrowed from the (rk3399-khadas-edge.dtsi).
>>>
>>> Signed-off-by: Peter Geis <pgwipeout at gmail.com>

[ ... ]

>>> ? +&cpu_thermal {
>>> +??? trips {
>>> +??????? cpu_warm: cpu_warm {
>>> +??????????? temperature = <55000>;
>>> +??????????? hysteresis = <2000>;
>>> +??????????? type = "active";
>>> +??????? };
>>> +
>>> +??????? cpu_hot: cpu_hot {
>>> +??????????? temperature = <65000>;
>>> +??????????? hysteresis = <2000>;
>>> +??????????? type = "active";
>>> +??????? };
>>> +??? };
>>> +
>>
>> Why two trip points ?
>>
>> Why not one functioning temperature and no lower / upper limits for the
>> cooling maps ?
> 
> Certainly when I first did this for NanoPC-T4, IIRC it was to avoid the
> fan ramping up too eagerly, since level 1 for my fan is effectively
> silent but still cools enough to let a moderate load eventually settle
> to a steady state below the second trip.

Thanks for your answer.

What would be the governor for this setup ?




-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From clin at suse.com  Fri Aug 13 07:58:29 2021
From: clin at suse.com (Chester Lin)
Date: Fri, 13 Aug 2021 22:58:29 +0800
Subject: [PATCH 7/8] arm64: dts: s32g2: add memory nodes for evb and rdb2
In-Reply-To: <17ab7b71-2dbe-0c66-e180-4cc2e8310441@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-8-clin@suse.com>
 <17ab7b71-2dbe-0c66-e180-4cc2e8310441@suse.de>
Message-ID: <YRaIlYiYH6P7UolW@linux-8mug>

On Thu, Aug 12, 2021 at 08:25:00PM +0200, Andreas F?rber wrote:
> Hi Chester et al.,
> 
> On 05.08.21 08:54, Chester Lin wrote:
> > Add memory nodes for S32G-VNP-EVB and S32G-VNP-RDB2 since they have fixed
> > RAM size.
> 
> You can drop "since they have fixed RAM size" - if they didn't, you
> would simply choose the lowest size and rely on the bootloader (U-Boot)
> to overwrite it with the actually detected size.
> 
> Please expand why this patch is separate - BSP based, I assume?
> 

Yes, the information of memory banks is from s32 downstream kernel, which is
listed in the board DTs of older releases [bsp27] although newer releases
[bsp28 & bsp29] have moved it into s32 downstream u-boot as runtime fdt-fixup.
I think we should still reveal this information in kernel DTs in order to have
better understanding of system memory ranges that each board can have.

@NXP: Please don't hesitate to let me know if any better idea, thanks!

> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  arch/arm64/boot/dts/freescale/s32g274a-evb.dts  | 8 ++++++++
> >  arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts | 8 ++++++++
> >  2 files changed, 16 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> > index a1ae5031730a..cd41f0af5dd8 100644
> > --- a/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> > +++ b/arch/arm64/boot/dts/freescale/s32g274a-evb.dts
> > @@ -1,6 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> >  /*
> >   * Copyright (c) 2021 SUSE LLC
> > + * Copyright 2019-2020 NXP
> 
> @NXP: Please review year, alignment. Do any Signed-off-bys apply?
> 
> >   */
> >  
> >  /dts-v1/;
> > @@ -14,6 +15,13 @@ / {
> >  	chosen {
> >  		stdout-path = "serial0:115200n8";
> >  	};
> > +
> > +	memory at 80000000 {
> > +		device_type = "memory";
> > +		/* 4GB RAM */
> 
> This looks strange to me - either put /* 4 GiB RAM */ before the node,
> three lines above, and/or append comment /* 2 GiB */ on each line below.
> Note the space, and suggest to be precise about factor 1024 vs. 1000.
> 

Thank you for the suggestion.

> > +		reg = <0 0x80000000 0 0x80000000>,
> 
> Note that this gives you the range to use for the .dtsi /soc node:
> Address 0x0 with size 0x80000000 gets mapped to 0x0 0x0, excluding the
> upper 0x80000000 for the RAM here. Or address 0x0 0x0 for two /soc cells
> if there are high-memory peripherals.
> 

I don't know if memory ranges might be changed for new boards or CPU revisions
in the future, which means the first memory range might be expanded as well
[e.g. 0~4GB]. Based this assumption, I think the size should also be changed
accordingly. Not sure if overlays can still work with this case but overwriting
all reg properties under /soc could be awful.

However if we only have to think of current hardware spec, it's good to declare
"range = <0 0 0 0x80000000>".

Please feel free to let me know if any suggestions, thanks.

> > +		      <8 0x80000000 0 0x80000000>;
> 
> Maybe use 0x8 here and 0x0 above? (second 0 stays same, so don't mind)
> 

Will fix it.

> > +	};
> >  };
> >  
> >  &uart0 {
> > diff --git a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > index b2faae306b70..8fbbf3b45eb8 100644
> > --- a/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > +++ b/arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
> > @@ -1,6 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> >  /*
> >   * Copyright (c) 2021 SUSE LLC
> > + * Copyright 2019-2020 NXP
> 
> @NXP: 2021?
> 
> >   */
> >  
> >  /dts-v1/;
> > @@ -14,6 +15,13 @@ / {
> >  	chosen {
> >  		stdout-path = "serial0:115200n8";
> >  	};
> > +
> > +	memory at 80000000 {
> > +		device_type = "memory";
> > +		/* 4GB RAM */
> > +		reg = <0 0x80000000 0 0x80000000>,
> > +		      <8 0x80000000 0 0x80000000>;
> > +	};
> 
> Same comments as for EVB.
> 
> >  };
> >  
> >  &uart0 {
> 
> Regards,
> Andreas
> 
> -- 
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 N?rnberg, Germany
> GF: Felix Imend?rffer
> HRB 36809 (AG N?rnberg)
> 



From robin.murphy at arm.com  Fri Aug 13 08:00:45 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 16:00:45 +0100
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference in
 probe
In-Reply-To: <20210813143250.GA5209@sirena.org.uk>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com> <20210813135412.GA7722@kadam>
 <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>
 <20210813143250.GA5209@sirena.org.uk>
Message-ID: <566c26bb-c488-8c86-f47e-6a748b9b6c77@arm.com>

On 2021-08-13 15:32, Mark Brown wrote:
> On Fri, Aug 13, 2021 at 03:01:10PM +0100, Robin Murphy wrote:
> 
>> Indeed I've thought before that it would be nice if regulators worked like
>> GPIOs, where the absence of an optional one does give you NULL, and most of
>> the API is also NULL-safe. Probably a pretty big job though...
> 
> It also encourages *really* bad practice with error handling, and in
> general there are few use cases for optional regulators where there's
> not some other actions that need to be taken in the case where the
> supply isn't there (elimintating some operating points or features,
> reconfiguring power internally and so on).  If we genuninely don't need
> to do anything special one wonders why we're trying to turn the power on
> in the first place.

Sure, once you get into it, regulators are arguably a rather deeper area 
than GPIOs, so in terms of the NULL-safe aspect anything beyond 
enable/disable - for the sake of keeping trivial usage simple - would be 
pretty questionable for sure.

A lot of the usage of regulator_get_optional() seems to be just making 
sure some external thing is powered between probe() and remove() if it's 
not hard-wired already, so maybe something like a 
devm_regulator_get_optional_enabled() could be an answer to that 
argument without even touching the underlying API.

Robin.


From gregkh at linuxfoundation.org  Fri Aug 13 08:01:41 2021
From: gregkh at linuxfoundation.org (gregkh)
Date: Fri, 13 Aug 2021 17:01:41 +0200
Subject: [Internet]Re: [PATCH v5] arm pl011 serial: support multi-irq
 request
In-Reply-To: <0206c94d-c91b-b7da-8132-d06e23c9d964@quicinc.com>
References: <3b60d054-4e22-62fa-c31b-29b146495a65@gmail.com>
 <a1843494-5c8e-1ec8-5b98-df318db40922@quicinc.com>
 <7535ae2f-6a12-8203-0498-8ac85ab0d9a7@arm.com>
 <290c01ec-173f-755f-788e-2a33a69586e8@quicinc.com>
 <e98962f3-9232-4abf-ec27-a7524a9e786d@arm.com>
 <bddf2712-72f4-2e20-da17-33b3de08f769@gmail.com>
 <0819592c-1baa-e98d-9118-5abde8b8c562@quicinc.com>
 <67cd6c830e33491e99ea4d2480f4a89d@tencent.com>
 <09918b566884413898f63b92ddd037a0@tencent.com>
 <0206c94d-c91b-b7da-8132-d06e23c9d964@quicinc.com>
Message-ID: <YRaJVZOJMKtAM8Sl@kroah.com>

On Fri, Aug 13, 2021 at 09:42:52AM -0400, Qian Cai wrote:
> 
> 
> On 8/12/2021 11:32 PM, tombinfan(??) wrote:
> > hello,
> > 
> > I have sent the modified patch to the following mailboxes. THX
> > 
> > gregkh at linuxfoundation.org
> > linux-serial at vger.kernel.org
> > linux-kernel at vger.kernel.org
> 
> Thanks for the pointer. It is good to get some reviews from Arm
> people in the first place, so we don't break Arm like this.
> 
> Anyway, for anyone who might be watching, here is the new patch,
> 
> https://lore.kernel.org/linux-serial/1628825490-18937-1-git-send-email-hptsfb at gmail.com/
> 
> Unfortunately, I saw Greg mentioned that it was not based on
> tty-next, so not something I can apply easily on linux-next here
> as well.

That is because the code in tty-next (and linux-next), looks to already
do exactly what you submitted, right?

So is this working now for everyone in linux-next?

thanks,

greg k-h


From robin.murphy at arm.com  Fri Aug 13 08:09:50 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 16:09:50 +0100
Subject: [Internet]Re: [PATCH v5] arm pl011 serial: support multi-irq
 request
In-Reply-To: <YRaJVZOJMKtAM8Sl@kroah.com>
References: <3b60d054-4e22-62fa-c31b-29b146495a65@gmail.com>
 <a1843494-5c8e-1ec8-5b98-df318db40922@quicinc.com>
 <7535ae2f-6a12-8203-0498-8ac85ab0d9a7@arm.com>
 <290c01ec-173f-755f-788e-2a33a69586e8@quicinc.com>
 <e98962f3-9232-4abf-ec27-a7524a9e786d@arm.com>
 <bddf2712-72f4-2e20-da17-33b3de08f769@gmail.com>
 <0819592c-1baa-e98d-9118-5abde8b8c562@quicinc.com>
 <67cd6c830e33491e99ea4d2480f4a89d@tencent.com>
 <09918b566884413898f63b92ddd037a0@tencent.com>
 <0206c94d-c91b-b7da-8132-d06e23c9d964@quicinc.com>
 <YRaJVZOJMKtAM8Sl@kroah.com>
Message-ID: <0f77be70-08fd-6fdd-227d-611c01c54788@arm.com>

On 2021-08-13 16:01, gregkh wrote:
> On Fri, Aug 13, 2021 at 09:42:52AM -0400, Qian Cai wrote:
>>
>>
>> On 8/12/2021 11:32 PM, tombinfan(??) wrote:
>>> hello,
>>>
>>> I have sent the modified patch to the following mailboxes. THX
>>>
>>> gregkh at linuxfoundation.org
>>> linux-serial at vger.kernel.org
>>> linux-kernel at vger.kernel.org
>>
>> Thanks for the pointer. It is good to get some reviews from Arm
>> people in the first place, so we don't break Arm like this.
>>
>> Anyway, for anyone who might be watching, here is the new patch,
>>
>> https://lore.kernel.org/linux-serial/1628825490-18937-1-git-send-email-hptsfb at gmail.com/
>>
>> Unfortunately, I saw Greg mentioned that it was not based on
>> tty-next, so not something I can apply easily on linux-next here
>> as well.
> 
> That is because the code in tty-next (and linux-next), looks to already
> do exactly what you submitted, right?
> 
> So is this working now for everyone in linux-next?

AFAICS commit b0819465be8b in linux-next still results in 
amba_device-specific code being called from sbsa_uart_startup() and 
sbsa_uart_shutdown(), which is what blows up.

Robin.


From pgwipeout at gmail.com  Fri Aug 13 08:10:20 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Fri, 13 Aug 2021 11:10:20 -0400
Subject: [PATCH v3] arm64: dts: rockchip: add thermal fan control to
 rockpro64
In-Reply-To: <2b1050f2-0311-1871-820a-f876218894bc@linaro.org>
References: <20210730151727.729822-1-pgwipeout@gmail.com>
 <ad6d8025-977c-9ff2-81ff-a417df48231c@linaro.org>
 <893701da-ea17-00ab-5e31-c745051ac9b9@arm.com>
 <2b1050f2-0311-1871-820a-f876218894bc@linaro.org>
Message-ID: <CAMdYzYptXpahbcdkPm1C9_aH2khNtjdZyBmckndcWLnrh259QQ@mail.gmail.com>

On Fri, Aug 13, 2021 at 10:54 AM Daniel Lezcano
<daniel.lezcano at linaro.org> wrote:
>
>
> Hi Robin,
>
>
> On 13/08/2021 15:51, Robin Murphy wrote:
> > On 2021-08-13 13:59, Daniel Lezcano wrote:
> >> On 30/07/2021 17:17, Peter Geis wrote:
> >>> The rockpro64 had a fan node since
> >>> commit 5882d65c1691 ("arm64: dts: rockchip: Add PWM fan for RockPro64")
> >>> however it was never tied into the thermal driver for automatic control.
> >>>
> >>> Add the links to the thermal node to permit the kernel to handle this
> >>> automatically.
> >>> Borrowed from the (rk3399-khadas-edge.dtsi).
> >>>
> >>> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>
> [ ... ]
>
> >>>   +&cpu_thermal {
> >>> +    trips {
> >>> +        cpu_warm: cpu_warm {
> >>> +            temperature = <55000>;
> >>> +            hysteresis = <2000>;
> >>> +            type = "active";
> >>> +        };
> >>> +
> >>> +        cpu_hot: cpu_hot {
> >>> +            temperature = <65000>;
> >>> +            hysteresis = <2000>;
> >>> +            type = "active";
> >>> +        };
> >>> +    };
> >>> +
> >>
> >> Why two trip points ?
> >>
> >> Why not one functioning temperature and no lower / upper limits for the
> >> cooling maps ?
> >
> > Certainly when I first did this for NanoPC-T4, IIRC it was to avoid the
> > fan ramping up too eagerly, since level 1 for my fan is effectively
> > silent but still cools enough to let a moderate load eventually settle
> > to a steady state below the second trip.

That's the same issue I had on the rockpro64.

>
> Thanks for your answer.
>
> What would be the governor for this setup ?
>

The default governor when using arm64_defconfig is step_wise.

>
>
>
> --
> <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs
>
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog


From gregkh at linuxfoundation.org  Fri Aug 13 08:14:08 2021
From: gregkh at linuxfoundation.org (gregkh)
Date: Fri, 13 Aug 2021 17:14:08 +0200
Subject: [Internet]Re: [PATCH v5] arm pl011 serial: support multi-irq
 request
In-Reply-To: <0f77be70-08fd-6fdd-227d-611c01c54788@arm.com>
References: <7535ae2f-6a12-8203-0498-8ac85ab0d9a7@arm.com>
 <290c01ec-173f-755f-788e-2a33a69586e8@quicinc.com>
 <e98962f3-9232-4abf-ec27-a7524a9e786d@arm.com>
 <bddf2712-72f4-2e20-da17-33b3de08f769@gmail.com>
 <0819592c-1baa-e98d-9118-5abde8b8c562@quicinc.com>
 <67cd6c830e33491e99ea4d2480f4a89d@tencent.com>
 <09918b566884413898f63b92ddd037a0@tencent.com>
 <0206c94d-c91b-b7da-8132-d06e23c9d964@quicinc.com>
 <YRaJVZOJMKtAM8Sl@kroah.com>
 <0f77be70-08fd-6fdd-227d-611c01c54788@arm.com>
Message-ID: <YRaMQL+YOaky+x9Q@kroah.com>

On Fri, Aug 13, 2021 at 04:09:50PM +0100, Robin Murphy wrote:
> On 2021-08-13 16:01, gregkh wrote:
> > On Fri, Aug 13, 2021 at 09:42:52AM -0400, Qian Cai wrote:
> > > 
> > > 
> > > On 8/12/2021 11:32 PM, tombinfan(??) wrote:
> > > > hello,
> > > > 
> > > > I have sent the modified patch to the following mailboxes. THX
> > > > 
> > > > gregkh at linuxfoundation.org
> > > > linux-serial at vger.kernel.org
> > > > linux-kernel at vger.kernel.org
> > > 
> > > Thanks for the pointer. It is good to get some reviews from Arm
> > > people in the first place, so we don't break Arm like this.
> > > 
> > > Anyway, for anyone who might be watching, here is the new patch,
> > > 
> > > https://lore.kernel.org/linux-serial/1628825490-18937-1-git-send-email-hptsfb at gmail.com/
> > > 
> > > Unfortunately, I saw Greg mentioned that it was not based on
> > > tty-next, so not something I can apply easily on linux-next here
> > > as well.
> > 
> > That is because the code in tty-next (and linux-next), looks to already
> > do exactly what you submitted, right?
> > 
> > So is this working now for everyone in linux-next?
> 
> AFAICS commit b0819465be8b in linux-next still results in
> amba_device-specific code being called from sbsa_uart_startup() and
> sbsa_uart_shutdown(), which is what blows up.

Ick,  ok, can someone send me a revert with this information in it
please?

thanks,

greg k-h


From lorenzo.pieralisi at arm.com  Fri Aug 13 08:22:40 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 13 Aug 2021 16:22:40 +0100
Subject: [PATCH v11 2/4] PCI: mediatek: Add new method to get shared
 pcie-cfg base address and parse node
In-Reply-To: <20210810194250.GA2276275@bjorn-Precision-5520>
References: <20210719073456.28666-3-chuanjia.liu@mediatek.com>
 <20210810194250.GA2276275@bjorn-Precision-5520>
Message-ID: <20210813152239.GA15515@lpieralisi>

On Tue, Aug 10, 2021 at 02:42:50PM -0500, Bjorn Helgaas wrote:
> On Mon, Jul 19, 2021 at 03:34:54PM +0800, Chuanjia Liu wrote:
> > For the new dts format, add a new method to get
> > shared pcie-cfg base address and parse node.
> 
> This commit log doesn't seem to really cover what's going on here.  It
> looks like:
> 
>   - You added a check for "mediatek,generic-pciecfg" (I guess this is
>     the "shared pcie-cfg base address" part).  Probably could have
>     been its own patch.
> 
>   - You added checks for "interrupt-names" and "pcie_irq".  Not
>     explained in commit log; probably could have been its own patch,
>     too.
> 
>   - You now look for "linux,pci-domain" (via of_get_pci_domain_nr()).
>     If present, you parse only one port instead of looking for all the
>     children of the node.
> 
>     That's sort of weird behavior -- why should the presence of
>     "linux,pci-domain" determine whether the node can have children?
>     Is that really what you intend?
> 
>     Should be explained in the commit log and could have been its own
>     patch, too.

I agree with Bjorn, this patch should be split (and commit logs
rewritten). I will drop it from my tree, waiting for a v12.

Lorenzo

> > Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> > Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> > ---
> >  drivers/pci/controller/pcie-mediatek.c | 52 +++++++++++++++++++-------
> >  1 file changed, 39 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> > index 25bee693834f..928e0983a900 100644
> > --- a/drivers/pci/controller/pcie-mediatek.c
> > +++ b/drivers/pci/controller/pcie-mediatek.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/irqchip/chained_irq.h>
> >  #include <linux/irqdomain.h>
> >  #include <linux/kernel.h>
> > +#include <linux/mfd/syscon.h>
> >  #include <linux/msi.h>
> >  #include <linux/module.h>
> >  #include <linux/of_address.h>
> > @@ -23,6 +24,7 @@
> >  #include <linux/phy/phy.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_runtime.h>
> > +#include <linux/regmap.h>
> >  #include <linux/reset.h>
> >  
> >  #include "../pci.h"
> > @@ -207,6 +209,7 @@ struct mtk_pcie_port {
> >   * struct mtk_pcie - PCIe host information
> >   * @dev: pointer to PCIe device
> >   * @base: IO mapped register base
> > + * @cfg: IO mapped register map for PCIe config
> >   * @free_ck: free-run reference clock
> >   * @mem: non-prefetchable memory resource
> >   * @ports: pointer to PCIe port information
> > @@ -215,6 +218,7 @@ struct mtk_pcie_port {
> >  struct mtk_pcie {
> >  	struct device *dev;
> >  	void __iomem *base;
> > +	struct regmap *cfg;
> >  	struct clk *free_ck;
> >  
> >  	struct list_head ports;
> > @@ -650,7 +654,11 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
> >  		return err;
> >  	}
> >  
> > -	port->irq = platform_get_irq(pdev, port->slot);
> > +	if (of_find_property(dev->of_node, "interrupt-names", NULL))
> > +		port->irq = platform_get_irq_byname(pdev, "pcie_irq");
> > +	else
> > +		port->irq = platform_get_irq(pdev, port->slot);
> > +
> >  	if (port->irq < 0)
> >  		return port->irq;
> >  
> > @@ -682,6 +690,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
> >  		val |= PCIE_CSR_LTSSM_EN(port->slot) |
> >  		       PCIE_CSR_ASPM_L1_EN(port->slot);
> >  		writel(val, pcie->base + PCIE_SYS_CFG_V2);
> > +	} else if (pcie->cfg) {
> > +		val = PCIE_CSR_LTSSM_EN(port->slot) |
> > +		      PCIE_CSR_ASPM_L1_EN(port->slot);
> > +		regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
> >  	}
> >  
> >  	/* Assert all reset signals */
> > @@ -985,6 +997,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> >  	struct device *dev = pcie->dev;
> >  	struct platform_device *pdev = to_platform_device(dev);
> >  	struct resource *regs;
> > +	struct device_node *cfg_node;
> >  	int err;
> >  
> >  	/* get shared registers, which are optional */
> > @@ -995,6 +1008,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> >  			return PTR_ERR(pcie->base);
> >  	}
> >  
> > +	cfg_node = of_find_compatible_node(NULL, NULL,
> > +					   "mediatek,generic-pciecfg");
> > +	if (cfg_node) {
> > +		pcie->cfg = syscon_node_to_regmap(cfg_node);
> > +		if (IS_ERR(pcie->cfg))
> > +			return PTR_ERR(pcie->cfg);
> > +	}
> > +
> >  	pcie->free_ck = devm_clk_get(dev, "free_ck");
> >  	if (IS_ERR(pcie->free_ck)) {
> >  		if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
> > @@ -1027,22 +1048,27 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
> >  	struct device *dev = pcie->dev;
> >  	struct device_node *node = dev->of_node, *child;
> >  	struct mtk_pcie_port *port, *tmp;
> > -	int err;
> > +	int err, slot;
> > +
> > +	slot = of_get_pci_domain_nr(dev->of_node);
> > +	if (slot < 0) {
> > +		for_each_available_child_of_node(node, child) {
> > +			err = of_pci_get_devfn(child);
> > +			if (err < 0) {
> > +				dev_err(dev, "failed to get devfn: %d\n", err);
> > +				goto error_put_node;
> > +			}
> >  
> > -	for_each_available_child_of_node(node, child) {
> > -		int slot;
> > +			slot = PCI_SLOT(err);
> >  
> > -		err = of_pci_get_devfn(child);
> > -		if (err < 0) {
> > -			dev_err(dev, "failed to parse devfn: %d\n", err);
> > -			goto error_put_node;
> > +			err = mtk_pcie_parse_port(pcie, child, slot);
> > +			if (err)
> > +				goto error_put_node;
> >  		}
> > -
> > -		slot = PCI_SLOT(err);
> > -
> > -		err = mtk_pcie_parse_port(pcie, child, slot);
> > +	} else {
> > +		err = mtk_pcie_parse_port(pcie, node, slot);
> >  		if (err)
> > -			goto error_put_node;
> > +			return err;
> >  	}
> >  
> >  	err = mtk_pcie_subsys_powerup(pcie);
> > -- 
> > 2.18.0
> > 


From quic_qiancai at quicinc.com  Fri Aug 13 08:28:32 2021
From: quic_qiancai at quicinc.com (Qian Cai)
Date: Fri, 13 Aug 2021 11:28:32 -0400
Subject: [Internet]Re: [PATCH v5] arm pl011 serial: support multi-irq
 request
In-Reply-To: <YRaMQL+YOaky+x9Q@kroah.com>
References: <7535ae2f-6a12-8203-0498-8ac85ab0d9a7@arm.com>
 <290c01ec-173f-755f-788e-2a33a69586e8@quicinc.com>
 <e98962f3-9232-4abf-ec27-a7524a9e786d@arm.com>
 <bddf2712-72f4-2e20-da17-33b3de08f769@gmail.com>
 <0819592c-1baa-e98d-9118-5abde8b8c562@quicinc.com>
 <67cd6c830e33491e99ea4d2480f4a89d@tencent.com>
 <09918b566884413898f63b92ddd037a0@tencent.com>
 <0206c94d-c91b-b7da-8132-d06e23c9d964@quicinc.com>
 <YRaJVZOJMKtAM8Sl@kroah.com> <0f77be70-08fd-6fdd-227d-611c01c54788@arm.com>
 <YRaMQL+YOaky+x9Q@kroah.com>
Message-ID: <4cc762c8-ba6f-12ba-35f0-3367be8c1fb5@quicinc.com>



On 8/13/2021 11:14 AM, gregkh wrote:
>> AFAICS commit b0819465be8b in linux-next still results in
>> amba_device-specific code being called from sbsa_uart_startup() and
>> sbsa_uart_shutdown(), which is what blows up.
> 
> Ick,  ok, can someone send me a revert with this information in it
> please?

I guess Bin won't be around to response in his timezone on Friday, so
I'll send a revert shortly.


From broonie at kernel.org  Fri Aug 13 08:30:43 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Aug 2021 16:30:43 +0100
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference
 in probe
In-Reply-To: <566c26bb-c488-8c86-f47e-6a748b9b6c77@arm.com>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
 <20210813135412.GA7722@kadam>
 <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>
 <20210813143250.GA5209@sirena.org.uk>
 <566c26bb-c488-8c86-f47e-6a748b9b6c77@arm.com>
Message-ID: <20210813153043.GB5209@sirena.org.uk>

On Fri, Aug 13, 2021 at 04:00:45PM +0100, Robin Murphy wrote:
> On 2021-08-13 15:32, Mark Brown wrote:

> > It also encourages *really* bad practice with error handling, and in
> > general there are few use cases for optional regulators where there's
> > not some other actions that need to be taken in the case where the
> > supply isn't there (elimintating some operating points or features,
> > reconfiguring power internally and so on).  If we genuninely don't need
> > to do anything special one wonders why we're trying to turn the power on
> > in the first place.

> Sure, once you get into it, regulators are arguably a rather deeper area
> than GPIOs, so in terms of the NULL-safe aspect anything beyond
> enable/disable - for the sake of keeping trivial usage simple - would be
> pretty questionable for sure.

enable and disable are among my biggest worries frankly, if the device
was supposed to have power and that didn't work then there's probably
some kind of issue.

> A lot of the usage of regulator_get_optional() seems to be just making sure
> some external thing is powered between probe() and remove() if it's not
> hard-wired already, so maybe something like a
> devm_regulator_get_optional_enabled() could be an answer to that argument
> without even touching the underlying API.

I'm fairly sure a lot of the regulator_get_optional() usage is just
abuse of the API, every so often I get fed up enough to send patches
converting users that look like you describe to normal regulator API
calls.  People really don't get the dummy regulator stuff and seem to
think that _get_optional() is what you use to avoid writing any error
handling code :(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/35476064/attachment.sig>

From dan.carpenter at oracle.com  Fri Aug 13 08:45:05 2021
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Fri, 13 Aug 2021 18:45:05 +0300
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference
 in probe
In-Reply-To: <20210813143250.GA5209@sirena.org.uk>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
 <20210813135412.GA7722@kadam>
 <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>
 <20210813143250.GA5209@sirena.org.uk>
Message-ID: <20210813154505.GC7722@kadam>

On Fri, Aug 13, 2021 at 03:32:50PM +0100, Mark Brown wrote:
> On Fri, Aug 13, 2021 at 03:01:10PM +0100, Robin Murphy wrote:
> 
> > Indeed I've thought before that it would be nice if regulators worked like
> > GPIOs, where the absence of an optional one does give you NULL, and most of
> > the API is also NULL-safe. Probably a pretty big job though...
> 
> It also encourages *really* bad practice with error handling

I'm not necessarily 100% positive what you mean by this.  I think you
mean you don't like when people pass invalid pointers to free functions?
But making regulator code NULL-safe wouldn't affect error handling
because NULL wouldn't be an error.

	p = get_optional();
	if (IS_ERR(p))
		return PTR_ERR(p);
	enable(p);
	...
	disable(p);

It all works nicely.

regards,
dan carpenter



From daniel.lezcano at linaro.org  Fri Aug 13 08:46:16 2021
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 13 Aug 2021 17:46:16 +0200
Subject: [PATCH v3] arm64: dts: rockchip: add thermal fan control to
 rockpro64
In-Reply-To: <CAMdYzYptXpahbcdkPm1C9_aH2khNtjdZyBmckndcWLnrh259QQ@mail.gmail.com>
References: <20210730151727.729822-1-pgwipeout@gmail.com>
 <ad6d8025-977c-9ff2-81ff-a417df48231c@linaro.org>
 <893701da-ea17-00ab-5e31-c745051ac9b9@arm.com>
 <2b1050f2-0311-1871-820a-f876218894bc@linaro.org>
 <CAMdYzYptXpahbcdkPm1C9_aH2khNtjdZyBmckndcWLnrh259QQ@mail.gmail.com>
Message-ID: <141e29aa-d21d-31b8-9a81-015dcd63d24d@linaro.org>

On 13/08/2021 17:10, Peter Geis wrote:
> On Fri, Aug 13, 2021 at 10:54 AM Daniel Lezcano
> <daniel.lezcano at linaro.org> wrote:
>>
>>
>> Hi Robin,
>>
>>
>> On 13/08/2021 15:51, Robin Murphy wrote:
>>> On 2021-08-13 13:59, Daniel Lezcano wrote:
>>>> On 30/07/2021 17:17, Peter Geis wrote:
>>>>> The rockpro64 had a fan node since
>>>>> commit 5882d65c1691 ("arm64: dts: rockchip: Add PWM fan for RockPro64")
>>>>> however it was never tied into the thermal driver for automatic control.
>>>>>
>>>>> Add the links to the thermal node to permit the kernel to handle this
>>>>> automatically.
>>>>> Borrowed from the (rk3399-khadas-edge.dtsi).
>>>>>
>>>>> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
>>
>> [ ... ]
>>
>>>>>   +&cpu_thermal {
>>>>> +    trips {
>>>>> +        cpu_warm: cpu_warm {
>>>>> +            temperature = <55000>;
>>>>> +            hysteresis = <2000>;
>>>>> +            type = "active";
>>>>> +        };
>>>>> +
>>>>> +        cpu_hot: cpu_hot {
>>>>> +            temperature = <65000>;
>>>>> +            hysteresis = <2000>;
>>>>> +            type = "active";
>>>>> +        };
>>>>> +    };
>>>>> +
>>>>
>>>> Why two trip points ?
>>>>
>>>> Why not one functioning temperature and no lower / upper limits for the
>>>> cooling maps ?
>>>
>>> Certainly when I first did this for NanoPC-T4, IIRC it was to avoid the
>>> fan ramping up too eagerly, since level 1 for my fan is effectively
>>> silent but still cools enough to let a moderate load eventually settle
>>> to a steady state below the second trip.
> 
> That's the same issue I had on the rockpro64.
> 
>>
>> Thanks for your answer.
>>
>> What would be the governor for this setup ?
>>
> 
> The default governor when using arm64_defconfig is step_wise.

Ok, thanks


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From lorenzo.pieralisi at arm.com  Fri Aug 13 08:46:46 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 13 Aug 2021 16:46:46 +0100
Subject: [RESEND PATCH 2/5] PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros
In-Reply-To: <20210624222621.4776-3-pali@kernel.org>
References: <20210624222621.4776-1-pali@kernel.org>
 <20210624222621.4776-3-pali@kernel.org>
Message-ID: <20210813154646.GB15515@lpieralisi>

On Fri, Jun 25, 2021 at 12:26:18AM +0200, Pali Roh?r wrote:
> Define a macro PCI_EXP_DEVCTL_PAYLOAD_* for every possible Max Payload
> Size in linux/pci_regs.h, in the same style as PCI_EXP_DEVCTL_READRQ_*.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Reviewed-by: Marek Beh?n <kabel at kernel.org>
> ---
>  include/uapi/linux/pci_regs.h | 6 ++++++
>  1 file changed, 6 insertions(+)

I'd need Bjorn's ACK to proceed with this series.

Thanks,
Lorenzo

> diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> index e709ae8235e7..ff6ccbc6efe9 100644
> --- a/include/uapi/linux/pci_regs.h
> +++ b/include/uapi/linux/pci_regs.h
> @@ -504,6 +504,12 @@
>  #define  PCI_EXP_DEVCTL_URRE	0x0008	/* Unsupported Request Reporting En. */
>  #define  PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
>  #define  PCI_EXP_DEVCTL_PAYLOAD	0x00e0	/* Max_Payload_Size */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_128B 0x0000 /* 128 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_256B 0x0020 /* 256 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_512B 0x0040 /* 512 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_1024B 0x0060 /* 1024 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_2048B 0x0080 /* 2048 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_4096B 0x00a0 /* 4096 Bytes */
>  #define  PCI_EXP_DEVCTL_EXT_TAG	0x0100	/* Extended Tag Field Enable */
>  #define  PCI_EXP_DEVCTL_PHANTOM	0x0200	/* Phantom Functions Enable */
>  #define  PCI_EXP_DEVCTL_AUX_PME	0x0400	/* Auxiliary Power PM Enable */
> -- 
> 2.20.1
> 


From lorenzo.pieralisi at arm.com  Fri Aug 13 08:53:28 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 13 Aug 2021 16:53:28 +0100
Subject: [PATCH v2 0/4] PCI: dwc: pci-dra7xx: miscellaneous improvements
In-Reply-To: <20210621144109.GC27516@lpieralisi>
References: <20210531085934.2662457-1-luca@lucaceresoli.net>
 <20210621144109.GC27516@lpieralisi>
Message-ID: <20210813155328.GC15515@lpieralisi>

On Mon, Jun 21, 2021 at 03:41:09PM +0100, Lorenzo Pieralisi wrote:
> On Mon, May 31, 2021 at 10:59:30AM +0200, Luca Ceresoli wrote:
> > This is an series of mixed improvements to the DRA7 PCI controller driver:
> > allow building as a loadabel module, allow to get and enable a clock and a
> > small cleanup.
> > 
> > Luca
> > 
> > Luca Ceresoli (4):
> >   PCI: dwc: Export more symbols to allow modular drivers
> >   PCI: dra7xx: Make it a kernel module
> >   PCI: dra7xx: Remove unused include
> >   PCI: dra7xx: Get an optional clock
> > 
> >  drivers/pci/controller/dwc/Kconfig            |  6 ++---
> >  drivers/pci/controller/dwc/pci-dra7xx.c       | 22 +++++++++++++++++--
> >  .../pci/controller/dwc/pcie-designware-ep.c   |  1 +
> >  drivers/pci/controller/dwc/pcie-designware.c  |  1 +
> >  4 files changed, 25 insertions(+), 5 deletions(-)
> 
> Hi Kishon,
> 
> I'd need your ACK to proceed with this series that looks like it
> is ready to go, please let me know.

Still need it - please let me know.

Lorenzo


From broonie at kernel.org  Fri Aug 13 08:53:50 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Aug 2021 16:53:50 +0100
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference
 in probe
In-Reply-To: <20210813154505.GC7722@kadam>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
 <20210813135412.GA7722@kadam>
 <2917a1c8-d59b-43b1-1650-228d20dfc070@arm.com>
 <20210813143250.GA5209@sirena.org.uk> <20210813154505.GC7722@kadam>
Message-ID: <20210813155350.GC5209@sirena.org.uk>

On Fri, Aug 13, 2021 at 06:45:05PM +0300, Dan Carpenter wrote:
> On Fri, Aug 13, 2021 at 03:32:50PM +0100, Mark Brown wrote:
> > On Fri, Aug 13, 2021 at 03:01:10PM +0100, Robin Murphy wrote:

> > > Indeed I've thought before that it would be nice if regulators worked like
> > > GPIOs, where the absence of an optional one does give you NULL, and most of
> > > the API is also NULL-safe. Probably a pretty big job though...

> > It also encourages *really* bad practice with error handling

> I'm not necessarily 100% positive what you mean by this.  I think you
> mean you don't like when people pass invalid pointers to free functions?

No, it's the case where people don't bother checking if they got the
regulator in the first place, don't bother checking if when they tried
to enable the regulator that actually worked, and don't do whatever
extra handling they need to do to configure the system for the fact that
one of the power supplies is missing.  It really only helps in the case
where you can just ignore the regulator completely.

> But making regulator code NULL-safe wouldn't affect error handling
> because NULL wouldn't be an error.
> 
> 	p = get_optional();
> 	if (IS_ERR(p))
> 		return PTR_ERR(p);
> 	enable(p);

Your example already misses the error handling on enable...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/4def6804/attachment.sig>

From sebastian.reichel at collabora.com  Fri Aug 13 08:54:38 2021
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 13 Aug 2021 17:54:38 +0200
Subject: [PATCH resend v6 0/3] power: supply: mt6360_charger: add MT6360
 charger support
In-Reply-To: <20210719033914.16990-1-gene.chen.richtek@gmail.com>
References: <20210719033914.16990-1-gene.chen.richtek@gmail.com>
Message-ID: <20210813155438.4ssph6deqksob2uv@earth.universe>

Hi,

On Mon, Jul 19, 2021 at 11:39:11AM +0800, Gene Chen wrote:
> This patch series add MT6360 Charger support contains driver and binding
> document

Thanks, queued.

-- Sebastian

> Gene Chen (3)
>  lib: add linear range get selector within
>  dt-bindings: power: Add bindings document for Charger support on MT6360 PMIC
>  power: supply: mt6360_charger: add MT6360 charger support
> 
>  Documentation/devicetree/bindings/power/supply/mt6360_charger.yaml |   48 
>  drivers/power/supply/Kconfig                                       |   11 
>  drivers/power/supply/Makefile                                      |    1 
>  drivers/power/supply/mt6360_charger.c                              |  867 ++++++++++
>  include/linux/linear_range.h                                       |    2 
>  lib/linear_ranges.c                                                |   31 
>  6 files changed, 960 insertions(+)
> 
> changelogs between v1 & v2
>  - Add binding property with unit and custom name prefix
>  - Remove extcon device, redundant brackets and interrupts
>  - Fix power supply prop "charger type"
> 
> changelogs between v2 & v3
>  - Add register selector to value mapping
> 
> changelogs between v3 & v4
>  - move pdata vinovp to mt6360_chg_info
>  - remove unuse sysfs attribute
>  - refactor debug log and warning
>  - add power supply prop input voltage limit
> 
> changelogs between v4 & v5
>  - add linear range selector mapping
>  - use linear range to map charger setting
> 
> changelogs between v5 & v6
>  - use REGULATOR_LINEAR_RANGE
>  - use devm_work_autocancel
>  - fix Kconfig description
> 
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/0ae73766/attachment.sig>

From robh at kernel.org  Fri Aug 13 08:57:44 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 10:57:44 -0500
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference in
 probe
In-Reply-To: <81b9a25d-f12f-90e0-0b05-b5e396f14c08@arm.com>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
 <CAL_JsqJ4Dadf00pJxEDd14zbWyN99s1A2L4fxZSkZddeg2pV6g@mail.gmail.com>
 <81b9a25d-f12f-90e0-0b05-b5e396f14c08@arm.com>
Message-ID: <CAL_JsqLWVLRDdkR62BSv69oW3QCLVebgpU1TKtxvzZmD4wuP4Q@mail.gmail.com>

On Fri, Aug 13, 2021 at 8:47 AM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2021-08-13 14:34, Rob Herring wrote:
> > On Fri, Aug 13, 2021 at 7:55 AM Robin Murphy <robin.murphy at arm.com> wrote:
> >>
> >> On 2021-08-13 12:33, Dan Carpenter wrote:
> >>> If devm_regulator_get_optional() returns an error pointer, then we
> >>> should return it to the user.  The current code makes an exception
> >>> for -ENODEV that will result in an error pointer dereference on the
> >>> next line when it calls regulator_enable().  Remove the exception.
> >>
> >> Doesn't this break the apparent intent of the regulator being optional,
> >> though?
> >
> > I'm pretty sure 'optional' means ENODEV is never returned. So there
> > wasn't any real problem, but the check was unnecessary.
>
> In fact it's the other way round - "optional" in this case is for when
> the supply may legitimately not exist so the driver may or may not need
> to handle it, so it can return -ENODEV if a regulator isn't described by
> firmware. A non-optional regulator is assumed to represent a necessary
> supply, so if there's nothing described by firmware you get the (valid)
> dummy regulator back.

Ah yes, regulators is the oddball. Surely no one else will assume the
same behavior of _optional() variants across subsystems... ;)


From broonie at kernel.org  Fri Aug 13 08:58:58 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Aug 2021 16:58:58 +0100
Subject: [PATCH resend v6 0/3] power: supply: mt6360_charger: add MT6360
 charger support
In-Reply-To: <20210813155438.4ssph6deqksob2uv@earth.universe>
References: <20210719033914.16990-1-gene.chen.richtek@gmail.com>
 <20210813155438.4ssph6deqksob2uv@earth.universe>
Message-ID: <20210813155858.GD5209@sirena.org.uk>

On Fri, Aug 13, 2021 at 05:54:38PM +0200, Sebastian Reichel wrote:
> On Mon, Jul 19, 2021 at 11:39:11AM +0800, Gene Chen wrote:
> > This patch series add MT6360 Charger support contains driver and binding
> > document

> Thanks, queued.

We're still waiting for review from Matti on the linear ranges bit -
normally that goes through the regulator tree, do you have a tag to pull
in case of merge conflicts?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/f4bfacdd/attachment-0001.sig>

From broonie at kernel.org  Fri Aug 13 09:01:16 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Aug 2021 17:01:16 +0100
Subject: [PATCH] PCI: rockchip-dwc: Potential error pointer dereference
 in probe
In-Reply-To: <CAL_JsqLWVLRDdkR62BSv69oW3QCLVebgpU1TKtxvzZmD4wuP4Q@mail.gmail.com>
References: <20210813113338.GA30697@kili>
 <01b7c3da-1c58-c1d9-6a54-0ce30ca76097@arm.com>
 <CAL_JsqJ4Dadf00pJxEDd14zbWyN99s1A2L4fxZSkZddeg2pV6g@mail.gmail.com>
 <81b9a25d-f12f-90e0-0b05-b5e396f14c08@arm.com>
 <CAL_JsqLWVLRDdkR62BSv69oW3QCLVebgpU1TKtxvzZmD4wuP4Q@mail.gmail.com>
Message-ID: <20210813160116.GE5209@sirena.org.uk>

On Fri, Aug 13, 2021 at 10:57:44AM -0500, Rob Herring wrote:
> On Fri, Aug 13, 2021 at 8:47 AM Robin Murphy <robin.murphy at arm.com> wrote:

> > In fact it's the other way round - "optional" in this case is for when
> > the supply may legitimately not exist so the driver may or may not need
> > to handle it, so it can return -ENODEV if a regulator isn't described by
> > firmware. A non-optional regulator is assumed to represent a necessary
> > supply, so if there's nothing described by firmware you get the (valid)
> > dummy regulator back.

> Ah yes, regulators is the oddball. Surely no one else will assume the
> same behavior of _optional() variants across subsystems... ;)

It would be silly to copy the *whole* pattern!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/d3ceb145/attachment.sig>

From robin.murphy at arm.com  Fri Aug 13 09:01:38 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 17:01:38 +0100
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching helpers
 to improve performance
In-Reply-To: <20210811114852.2429-2-thunder.leizhen@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
 <20210811114852.2429-2-thunder.leizhen@huawei.com>
Message-ID: <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>

On 2021-08-11 12:48, Zhen Lei wrote:
> The obvious key to the performance optimization of commit 587e6c10a7ce
> ("iommu/arm-smmu-v3: Reduce contention during command-queue insertion") is
> to allow multiple cores to insert commands in parallel after a brief mutex
> contention.
> 
> Obviously, inserting as many commands at a time as possible can reduce the
> number of times the mutex contention participates, thereby improving the
> overall performance. At least it reduces the number of calls to function
> arm_smmu_cmdq_issue_cmdlist().
> 
> Therefore, use command queue batching helpers to insert multiple commands
> at a time.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> ---
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 235f9bdaeaf223b..c81cd929047f573 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1747,15 +1747,16 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
>   {
>   	int i;
>   	struct arm_smmu_cmdq_ent cmd;
> +	struct arm_smmu_cmdq_batch cmds = {};

BTW, it looks like this has crossed over with John's patch removing these.

Robin.

>   
>   	arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
>   
>   	for (i = 0; i < master->num_streams; i++) {
>   		cmd.atc.sid = master->streams[i].id;
> -		arm_smmu_cmdq_issue_cmd(master->smmu, &cmd);
> +		arm_smmu_cmdq_batch_add(master->smmu, &cmds, &cmd);
>   	}
>   
> -	return arm_smmu_cmdq_issue_sync(master->smmu);
> +	return arm_smmu_cmdq_batch_submit(master->smmu, &cmds);
>   }
>   
>   int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
> 


From sebastian.reichel at collabora.com  Fri Aug 13 09:20:29 2021
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 13 Aug 2021 18:20:29 +0200
Subject: [PATCH resend v6 0/3] power: supply: mt6360_charger: add MT6360
 charger support
In-Reply-To: <20210813155858.GD5209@sirena.org.uk>
References: <20210719033914.16990-1-gene.chen.richtek@gmail.com>
 <20210813155438.4ssph6deqksob2uv@earth.universe>
 <20210813155858.GD5209@sirena.org.uk>
Message-ID: <20210813162029.q5slrkubelfy3mvh@earth.universe>

Hi Mark,

On Fri, Aug 13, 2021 at 04:58:58PM +0100, Mark Brown wrote:
> On Fri, Aug 13, 2021 at 05:54:38PM +0200, Sebastian Reichel wrote:
> > On Mon, Jul 19, 2021 at 11:39:11AM +0800, Gene Chen wrote:
> > > This patch series add MT6360 Charger support contains driver and binding
> > > document
> 
> > Thanks, queued.
> 
> We're still waiting for review from Matti on the linear ranges bit -
> normally that goes through the regulator tree, do you have a tag to pull
> in case of merge conflicts?

He actually already provided his Rb in v5, Gene did not carry it
over properly (I added it) and the patch looks simple enough, that
Linus will know what to do in case of a conflict. But if you insist
I can unroll my tree and create a topic branch for this.

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/cd7219db/attachment.sig>

From thierry.reding at gmail.com  Fri Aug 13 09:21:52 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 13 Aug 2021 18:21:52 +0200
Subject: [GIT PULL 1/6] dt-bindings: Changes for v5.15-rc1
Message-ID: <20210813162157.2820913-1-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-dt-bindings

for you to fetch changes up to 900a486ac73dfdf9b1629e7e4df6eacc92da7578:

  dt-bindings: tegra: Document NVIDIA Jetson TX2 NX developer kit (2021-08-12 15:06:28 +0200)

Thanks,
Thierry

----------------------------------------------------------------
dt-bindings: Changes for v5.15-rc1

This contains a single patch that adds the compatible string for the
NVIDIA Jetson TX2 NX developer kit.

----------------------------------------------------------------
Thierry Reding (1):
      dt-bindings: tegra: Document NVIDIA Jetson TX2 NX developer kit

 Documentation/devicetree/bindings/arm/tegra.yaml | 1 +
 1 file changed, 1 insertion(+)


From thierry.reding at gmail.com  Fri Aug 13 09:21:53 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 13 Aug 2021 18:21:53 +0200
Subject: [GIT PULL 2/6] firmware: tegra: Changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-1-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
Message-ID: <20210813162157.2820913-2-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-firmware

for you to fetch changes up to dd00d75007d27677158bf6e64000d2e266035294:

  firmware: tegra: Stop using seq_get_buf() (2021-08-11 12:17:18 +0200)

Thanks,
Thierry

----------------------------------------------------------------
firmware: tegra: Changes for v5.15-rc1

This contains a single fix to stop a slight abuse of the seq_buf API.

----------------------------------------------------------------
Christoph Hellwig (1):
      firmware: tegra: Stop using seq_get_buf()

 drivers/firmware/tegra/bpmp-debugfs.c | 58 ++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 11 deletions(-)


From thierry.reding at gmail.com  Fri Aug 13 09:21:54 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 13 Aug 2021 18:21:54 +0200
Subject: [GIT PULL 3/6] soc/tegra: Changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-1-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
Message-ID: <20210813162157.2820913-3-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-soc

for you to fetch changes up to 59c6fceb2ecc382c3d20508a235b539bf23af1f0:

  soc/tegra: fuse: Enable fuse clock on suspend for Tegra124 (2021-08-11 11:55:56 +0200)

Thanks,
Thierry

----------------------------------------------------------------
soc/tegra: Changes for v5.15-rc1

Implements runtime PM support for the FUSE block and prepares the driver
to work better in conjunction with the CPUIDLE driver.

----------------------------------------------------------------
Cai Huoqing (1):
      soc/tegra: bpmp: Remove unused including <linux/version.h>

Dmitry Osipenko (4):
      soc/tegra: pmc: Prevent racing with cpuilde driver
      soc/tegra: fuse: Clear fuse->clk on driver probe failure
      soc/tegra: fuse: Add runtime PM support
      soc/tegra: fuse: Enable fuse clock on suspend for Tegra124

 arch/arm/mach-tegra/pm.c              |  2 +-
 arch/arm/mach-tegra/pm.h              |  6 ----
 arch/arm/mach-tegra/tegra.c           |  2 --
 drivers/soc/tegra/fuse/fuse-tegra.c   | 60 +++++++++++++++++++++++++++++++++++
 drivers/soc/tegra/fuse/fuse-tegra20.c | 11 ++++---
 drivers/soc/tegra/fuse/fuse-tegra30.c | 16 +++++++---
 drivers/soc/tegra/fuse/fuse.h         |  2 ++
 drivers/soc/tegra/pmc.c               | 14 +++++++-
 drivers/soc/tegra/powergate-bpmp.c    |  1 -
 include/soc/tegra/pm.h                |  6 ++++
 10 files changed, 100 insertions(+), 20 deletions(-)


From thierry.reding at gmail.com  Fri Aug 13 09:21:55 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 13 Aug 2021 18:21:55 +0200
Subject: [GIT PULL 4/6] ARM: tegra: Device tree changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-1-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
Message-ID: <20210813162157.2820913-4-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-arm-dt

for you to fetch changes up to 2270ad2f4e123336af685ecedd1618701cb4ca1e:

  ARM: tegra: tamonten: Fix UART pad setting (2021-08-13 17:59:41 +0200)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Device tree changes for v5.15-rc1

The majority of this is temperature sensor additions for various devices
and fixes to the trigger type of the thermal interrupts.

Other than that there are various minor fixes across the board.

----------------------------------------------------------------
Andreas Obergschwandtner (1):
      ARM: tegra: tamonten: Fix UART pad setting

Dmitry Osipenko (15):
      ARM: tegra: Add SoC thermal sensor to Tegra30 device-trees
      ARM: tegra: ouya: Add interrupt to temperature sensor node
      ARM: tegra: paz00: Add interrupt to temperature sensor node
      ARM: tegra: nexus7: Add interrupt to temperature sensor node
      ARM: tegra: acer-a500: Add interrupt to temperature sensor node
      ARM: tegra: nyan: Correct interrupt trigger type of temperature sensor
      ARM: tegra: apalis: Correct interrupt trigger type of temperature sensor
      ARM: tegra: cardhu: Correct interrupt trigger type of temperature sensor
      ARM: tegra: dalmore: Correct interrupt trigger type of temperature sensor
      ARM: tegra: jetson-tk1: Correct interrupt trigger type of temperature sensor
      ARM: tegra: acer-a500: Remove bogus USB VBUS regulators
      ARM: tegra: acer-a500: Add power supplies to accelerometer
      ARM: tegra: acer-a500: Use verbose variant of atmel,wakeup-method value
      ARM: tegra: acer-a500: Improve thermal zones
      ARM: tegra: nexus7: Improve thermal zones

 arch/arm/boot/dts/tegra114-dalmore.dts             |  2 +-
 arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi        |  2 +-
 arch/arm/boot/dts/tegra124-apalis.dtsi             |  2 +-
 arch/arm/boot/dts/tegra124-jetson-tk1.dts          |  2 +-
 arch/arm/boot/dts/tegra124-nyan.dtsi               |  2 +-
 arch/arm/boot/dts/tegra20-acer-a500-picasso.dts    | 90 ++++++++++++++--------
 arch/arm/boot/dts/tegra20-paz00.dts                |  4 +
 arch/arm/boot/dts/tegra20-tamonten.dtsi            | 14 ++--
 .../dts/tegra30-asus-nexus7-grouper-common.dtsi    | 60 ++++++++++++++-
 arch/arm/boot/dts/tegra30-cardhu.dtsi              |  2 +-
 arch/arm/boot/dts/tegra30-ouya.dts                 | 13 ++--
 arch/arm/boot/dts/tegra30.dtsi                     | 87 ++++++++++++++++++++-
 12 files changed, 218 insertions(+), 62 deletions(-)


From thierry.reding at gmail.com  Fri Aug 13 09:21:56 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 13 Aug 2021 18:21:56 +0200
Subject: [GIT PULL 5/6] ARM: tegra: Default configuration changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-1-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
Message-ID: <20210813162157.2820913-5-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-arm-defconfig

for you to fetch changes up to 806b99206b840bcf3bfa44227dc978880d13ed1b:

  ARM: multi_v7_defconfig: Enable CONFIG_TEGRA30_TSENSOR (2021-08-11 12:15:48 +0200)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Default configuration changes for v5.15-rc1

Enables a couple of drivers by default so that the configuration is
useful on more devices. This also rebuilds the tegra_defconfig, which
hasn't been done in a long time.

----------------------------------------------------------------
Dmitry Osipenko (5):
      ARM: tegra: Enable CONFIG_TEGRA30_TSENSOR
      ARM: tegra: Enable CONFIG_FB
      ARM: tegra: Enable Acer A500 drivers
      ARM: multi_v7_defconfig: Enable Acer A500 drivers
      ARM: multi_v7_defconfig: Enable CONFIG_TEGRA30_TSENSOR

Maxim Schwalm (2):
      ARM: tegra: Enable CONFIG_CROS_EC
      ARM: tegra: Rebuild default configuration

 arch/arm/configs/multi_v7_defconfig |  4 ++++
 arch/arm/configs/tegra_defconfig    | 25 ++++++++-----------------
 2 files changed, 12 insertions(+), 17 deletions(-)


From thierry.reding at gmail.com  Fri Aug 13 09:21:57 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 13 Aug 2021 18:21:57 +0200
Subject: [GIT PULL 6/6] arm64: tegra: Device tree changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-1-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
Message-ID: <20210813162157.2820913-6-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-arm64-dt

for you to fetch changes up to f865d0292ff3c0ca09414436510eb4c815815509:

  arm64: tegra: Fix compatible string for Tegra132 CPUs (2021-08-13 18:01:01 +0200)

Thanks,
Thierry

----------------------------------------------------------------
arm64: tegra: Device tree changes for v5.15-rc1

Contains a couple of fixes across the board and adds support for the
recently released NVIDIA Jetson TX2 NX Developer Kit.

----------------------------------------------------------------
Dmitry Osipenko (1):
      arm64: tegra194: p2888: Correct interrupt trigger type of temperature sensor

Thierry Reding (4):
      arm64: tegra: Add PWM nodes on Tegra186
      arm64: tegra: Add NVIDIA Jetson TX2 NX Developer Kit support
      arm64: tegra: Add missing interconnects property for USB on Tegra186
      arm64: tegra: Fix compatible string for Tegra132 CPUs

Vidya Sagar (1):
      arm64: tegra: Fix Tegra194 PCIe EP compatible string

 arch/arm64/boot/dts/nvidia/Makefile                |   1 +
 arch/arm64/boot/dts/nvidia/tegra132.dtsi           |   4 +-
 .../dts/nvidia/tegra186-p3509-0000+p3636-0001.dts  | 718 +++++++++++++++++++++
 arch/arm64/boot/dts/nvidia/tegra186.dtsi           |  91 +++
 arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi     |   2 +-
 arch/arm64/boot/dts/nvidia/tegra194.dtsi           |   6 +-
 6 files changed, 816 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts


From james.clark at arm.com  Fri Aug 13 09:22:31 2021
From: james.clark at arm.com (James Clark)
Date: Fri, 13 Aug 2021 17:22:31 +0100
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210809112727.596876-3-leo.yan@linaro.org>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-3-leo.yan@linaro.org>
Message-ID: <2b4e0c07-a8df-cca6-6a94-328560f4b0c6@arm.com>



On 09/08/2021 12:27, Leo Yan wrote:
> +/*
> + * In the compat mode kernel runs in 64-bit and perf tool runs in 32-bit mode,
> + * 32-bit perf tool cannot access 64-bit value atomically, which might lead to
> + * the issues caused by the below sequence on multiple CPUs: when perf tool
> + * accesses either the load operation or the store operation for 64-bit value,
> + * on some architectures the operation is divided into two instructions, one
> + * is for accessing the low 32-bit value and another is for the high 32-bit;
> + * thus these two user operations can give the kernel chances to access the
> + * 64-bit value, and thus leads to the unexpected load values.
> + *
> + *   kernel (64-bit)                        user (32-bit)
> + *
> + *   if (LOAD ->aux_tail) { --,             LOAD ->aux_head_lo
> + *       STORE $aux_data      |       ,--->
> + *       FLUSH $aux_data      |       |     LOAD ->aux_head_hi
> + *       STORE ->aux_head   --|-------`     smp_rmb()
> + *   }                        |             LOAD $data
> + *                            |             smp_mb()
> + *                            |             STORE ->aux_tail_lo
> + *                            `----------->
> + *                                          STORE ->aux_tail_hi
> + *
> + * For this reason, it's impossible for the perf tool to work correctly when
> + * the AUX head or tail is bigger than 4GB (more than 32 bits length); and we
> + * can not simply limit the AUX ring buffer to less than 4GB, the reason is
> + * the pointers can be increased monotonically, whatever the buffer size it is,
> + * at the end the head and tail can be bigger than 4GB and carry out to the
> + * high 32-bit.
> + *
> + * To mitigate the issues and improve the user experience, we can allow the
> + * perf tool working in certain conditions and bail out with error if detect
> + * any overflow cannot be handled.
> + *
> + * For reading the AUX head, it reads out the values for three times, and
> + * compares the high 4 bytes of the values between the first time and the last
> + * time, if there has no change for high 4 bytes injected by the kernel during
> + * the user reading sequence, it's safe for use the second value.
> + *
> + * When update the AUX tail and detects any carrying in the high 32 bits, it
> + * means there have two store operations in user space and it cannot promise
> + * the atomicity for 64-bit write, so return '-1' in this case to tell the
> + * caller an overflow error has happened.
> + */
> +u64 __weak compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> +{
> +	struct perf_event_mmap_page *pc = mm->userpg;
> +	u64 first, second, last;
> +	u64 mask = (u64)(UINT32_MAX) << 32;
> +
> +	do {
> +		first = READ_ONCE(pc->aux_head);
> +		/* Ensure all reads are done after we read the head */
> +		smp_rmb();
> +		second = READ_ONCE(pc->aux_head);
> +		/* Ensure all reads are done after we read the head */
> +		smp_rmb();
> +		last = READ_ONCE(pc->aux_head);
> +	} while ((first & mask) != (last & mask));
> +
> +	return second;
> +}
> +

Hi Leo,

I had a couple of questions about this bit. If we're assuming that the
high bytes of 'first' and 'last' are equal, then 'second' is supposed
to be somewhere in between or equal to 'first' and 'last'.

If that's the case, wouldn't it be better to return 'last', because it's
closer to the value at the time of reading? And then in that case, if
last is returned, then why do a read for 'second' at all? Can 'second' be
skipped and just read first and last?

Also maybe it won't make a difference, but is there a missing smp_rmb()
between the read of 'last' and 'first'?

Thanks
James


From broonie at kernel.org  Fri Aug 13 09:32:54 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Aug 2021 17:32:54 +0100
Subject: [PATCH resend v6 0/3] power: supply: mt6360_charger: add MT6360
 charger support
In-Reply-To: <20210813162029.q5slrkubelfy3mvh@earth.universe>
References: <20210719033914.16990-1-gene.chen.richtek@gmail.com>
 <20210813155438.4ssph6deqksob2uv@earth.universe>
 <20210813155858.GD5209@sirena.org.uk>
 <20210813162029.q5slrkubelfy3mvh@earth.universe>
Message-ID: <20210813163254.GF5209@sirena.org.uk>

On Fri, Aug 13, 2021 at 06:20:29PM +0200, Sebastian Reichel wrote:
> On Fri, Aug 13, 2021 at 04:58:58PM +0100, Mark Brown wrote:

> > We're still waiting for review from Matti on the linear ranges bit -
> > normally that goes through the regulator tree, do you have a tag to pull
> > in case of merge conflicts?

> He actually already provided his Rb in v5, Gene did not carry it
> over properly (I added it) and the patch looks simple enough, that
> Linus will know what to do in case of a conflict. But if you insist
> I can unroll my tree and create a topic branch for this.

It would be better, the issues I'm worrying about are more general
refactorings or whatever that create actual dependencies rather than
just trivial add/add type issues - it can make doing some kinds of work
really painful if things go via a different tree.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/46f1c00a/attachment-0001.sig>

From john.garry at huawei.com  Fri Aug 13 09:45:23 2021
From: john.garry at huawei.com (John Garry)
Date: Fri, 13 Aug 2021 17:45:23 +0100
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching helpers
 to improve performance
In-Reply-To: <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
 <20210811114852.2429-2-thunder.leizhen@huawei.com>
 <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>
Message-ID: <4e741216-d6e7-c40c-f257-242cd2fea302@huawei.com>

On 13/08/2021 17:01, Robin Murphy wrote:
>>
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
>> b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index 235f9bdaeaf223b..c81cd929047f573 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -1747,15 +1747,16 @@ static int arm_smmu_atc_inv_master(struct 
>> arm_smmu_master *master)
>> ? {
>> ????? int i;
>> ????? struct arm_smmu_cmdq_ent cmd;
>> +??? struct arm_smmu_cmdq_batch cmds = {};
> 
> BTW, it looks like this has crossed over with John's patch removing these.

It is only called from arm_smmu_disable_ats(), so not hot-path by the 
look for it. Or who even has ats HW ...?

But it should be at least cleaned-up for consistency. Leizhen?

Thanks,
John


From will at kernel.org  Fri Aug 13 09:47:35 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 13 Aug 2021 17:47:35 +0100
Subject: [GIT PULL] iommu/arm-smmu: Updates for 5.15
Message-ID: <20210813164735.GA8765@willie-the-truck>

Hi Joerg,

Please pull these Arm SMMU updates for 5.15. There's not tonnes here, but
a good mixture of optimisations and cleanups -- summary in the tag.

This applies cleanly against iommu/next, but I suspect it will conflict
with Robin's series on the list. Please shout if you need anything from
me to help with that (e.g. rebase, checking a merge conflict).

Cheers,

Will

--->8

The following changes since commit ff1176468d368232b684f75e82563369208bc371:

  Linux 5.14-rc3 (2021-07-25 15:35:14 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git tags/arm-smmu-updates

for you to fetch changes up to fac956710ab0812f9e395e9f7a27da551412830f:

  iommu/arm-smmu-v3: Stop pre-zeroing batch commands (2021-08-13 14:26:06 +0100)

----------------------------------------------------------------
Arm SMMU updates for 5.15

- SMMUv3

  * Minor optimisation to avoid zeroing struct members on CMD submission

  * Increased use of batched commands to reduce submission latency

  * Refactoring in preparation for ECMDQ support

- SMMUv2

  * Fix races when probing devices with identical StreamIDs

  * Optimise walk cache flushing for Qualcomm implementations

  * Allow deep sleep states for some Qualcomm SoCs with shared clocks

----------------------------------------------------------------
Ashish Mhetre (1):
      iommu: Fix race condition during default domain allocation

John Garry (2):
      iommu/arm-smmu-v3: Remove some unneeded init in arm_smmu_cmdq_issue_cmdlist()
      iommu/arm-smmu-v3: Stop pre-zeroing batch commands

Krishna Reddy (1):
      iommu/arm-smmu: Fix race condition during iommu_group creation

Sai Prakash Ranjan (2):
      iommu/arm-smmu: Add clk_bulk_{prepare/unprepare} to system pm callbacks
      iommu/arm-smmu: Optimize ->tlb_flush_walk() for qcom implementation

Zhen Lei (4):
      iommu/arm-smmu-v3: Use command queue batching helpers to improve performance
      iommu/arm-smmu-v3: Add and use static helper function arm_smmu_cmdq_issue_cmd_with_sync()
      iommu/arm-smmu-v3: Add and use static helper function arm_smmu_get_cmdq()
      iommu/arm-smmu-v3: Extract reusable function __arm_smmu_cmdq_skip_err()

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 89 +++++++++++++++++------------
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c  | 11 ++++
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 45 ++++++++++++---
 drivers/iommu/arm/arm-smmu/arm-smmu.h       |  1 +
 drivers/iommu/iommu.c                       |  2 +
 5 files changed, 106 insertions(+), 42 deletions(-)


From robh at kernel.org  Fri Aug 13 09:49:46 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 11:49:46 -0500
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
References: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
Message-ID: <1628873386.475685.3650550.nullmailer@robh.at.kernel.org>

On Fri, 13 Aug 2021 14:54:14 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
> Dynamic Memory Controller to DT schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
>  .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
>  MAINTAINERS                                   |   2 +-
>  3 files changed, 138 insertions(+), 85 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.example.dt.yaml:0:0: /example-0/ppmu at 10d00000: failed to match any schema with compatible: ['samsung,exynos-ppmu']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1516650

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robin.murphy at arm.com  Fri Aug 13 10:03:33 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 18:03:33 +0100
Subject: [GIT PULL] iommu/arm-smmu: Updates for 5.15
In-Reply-To: <20210813164735.GA8765@willie-the-truck>
References: <20210813164735.GA8765@willie-the-truck>
Message-ID: <603960e8-e8cd-ed5c-32fd-93118401a221@arm.com>

On 2021-08-13 17:47, Will Deacon wrote:
> Hi Joerg,
> 
> Please pull these Arm SMMU updates for 5.15. There's not tonnes here, but
> a good mixture of optimisations and cleanups -- summary in the tag.
> 
> This applies cleanly against iommu/next, but I suspect it will conflict
> with Robin's series on the list. Please shout if you need anything from
> me to help with that (e.g. rebase, checking a merge conflict).

In fact it merges cleanly into my local branch, so I hope we should be 
good :)

Robin.

> Cheers,
> 
> Will
> 
> --->8
> 
> The following changes since commit ff1176468d368232b684f75e82563369208bc371:
> 
>    Linux 5.14-rc3 (2021-07-25 15:35:14 -0700)
> 
> are available in the Git repository at:
> 
>    git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git tags/arm-smmu-updates
> 
> for you to fetch changes up to fac956710ab0812f9e395e9f7a27da551412830f:
> 
>    iommu/arm-smmu-v3: Stop pre-zeroing batch commands (2021-08-13 14:26:06 +0100)
> 
> ----------------------------------------------------------------
> Arm SMMU updates for 5.15
> 
> - SMMUv3
> 
>    * Minor optimisation to avoid zeroing struct members on CMD submission
> 
>    * Increased use of batched commands to reduce submission latency
> 
>    * Refactoring in preparation for ECMDQ support
> 
> - SMMUv2
> 
>    * Fix races when probing devices with identical StreamIDs
> 
>    * Optimise walk cache flushing for Qualcomm implementations
> 
>    * Allow deep sleep states for some Qualcomm SoCs with shared clocks
> 
> ----------------------------------------------------------------
> Ashish Mhetre (1):
>        iommu: Fix race condition during default domain allocation
> 
> John Garry (2):
>        iommu/arm-smmu-v3: Remove some unneeded init in arm_smmu_cmdq_issue_cmdlist()
>        iommu/arm-smmu-v3: Stop pre-zeroing batch commands
> 
> Krishna Reddy (1):
>        iommu/arm-smmu: Fix race condition during iommu_group creation
> 
> Sai Prakash Ranjan (2):
>        iommu/arm-smmu: Add clk_bulk_{prepare/unprepare} to system pm callbacks
>        iommu/arm-smmu: Optimize ->tlb_flush_walk() for qcom implementation
> 
> Zhen Lei (4):
>        iommu/arm-smmu-v3: Use command queue batching helpers to improve performance
>        iommu/arm-smmu-v3: Add and use static helper function arm_smmu_cmdq_issue_cmd_with_sync()
>        iommu/arm-smmu-v3: Add and use static helper function arm_smmu_get_cmdq()
>        iommu/arm-smmu-v3: Extract reusable function __arm_smmu_cmdq_skip_err()
> 
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 89 +++++++++++++++++------------
>   drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c  | 11 ++++
>   drivers/iommu/arm/arm-smmu/arm-smmu.c       | 45 ++++++++++++---
>   drivers/iommu/arm/arm-smmu/arm-smmu.h       |  1 +
>   drivers/iommu/iommu.c                       |  2 +
>   5 files changed, 106 insertions(+), 42 deletions(-)
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From sebastian.reichel at collabora.com  Fri Aug 13 10:11:06 2021
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 13 Aug 2021 19:11:06 +0200
Subject: [PATCH resend v6 0/3] power: supply: mt6360_charger: add MT6360
 charger support
In-Reply-To: <20210813163254.GF5209@sirena.org.uk>
References: <20210719033914.16990-1-gene.chen.richtek@gmail.com>
 <20210813155438.4ssph6deqksob2uv@earth.universe>
 <20210813155858.GD5209@sirena.org.uk>
 <20210813162029.q5slrkubelfy3mvh@earth.universe>
 <20210813163254.GF5209@sirena.org.uk>
Message-ID: <20210813171106.entpro4b6dstho4s@earth.universe>

Hi,

On Fri, Aug 13, 2021 at 05:32:54PM +0100, Mark Brown wrote:
> On Fri, Aug 13, 2021 at 06:20:29PM +0200, Sebastian Reichel wrote:
> > On Fri, Aug 13, 2021 at 04:58:58PM +0100, Mark Brown wrote:
> 
> > > We're still waiting for review from Matti on the linear ranges bit -
> > > normally that goes through the regulator tree, do you have a tag to pull
> > > in case of merge conflicts?
> 
> > He actually already provided his Rb in v5, Gene did not carry it
> > over properly (I added it) and the patch looks simple enough, that
> > Linus will know what to do in case of a conflict. But if you insist
> > I can unroll my tree and create a topic branch for this.
> 
> It would be better, the issues I'm worrying about are more general
> refactorings or whatever that create actual dependencies rather than
> just trivial add/add type issues - it can make doing some kinds of work
> really painful if things go via a different tree.

There you go:

-- Sebastian

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  ssh://git at gitolite.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git tags/ib-mt6360-for-5.15-signed

for you to fetch changes up to 0402e8ebb8b869e375e8af7243044df21b5ff378:

  power: supply: mt6360_charger: add MT6360 charger support (2021-08-13 18:37:49 +0200)

----------------------------------------------------------------
Immutable branch between regulator and power-supply for for 5.15

This immutable branch introduces the MT6360 charger driver,
which requires a new linear range helper.

Signed-off-by: Sebastian Reichel <sre at kernel.org>

----------------------------------------------------------------
Gene Chen (3):
      lib: add linear range get selector within
      dt-bindings: power: Add bindings document for Charger support on MT6360 PMIC
      power: supply: mt6360_charger: add MT6360 charger support

 .../bindings/power/supply/mt6360_charger.yaml      |  48 ++
 drivers/power/supply/Kconfig                       |  11 +
 drivers/power/supply/Makefile                      |   1 +
 drivers/power/supply/mt6360_charger.c              | 867 +++++++++++++++++++++
 include/linux/linear_range.h                       |   2 +
 lib/linear_ranges.c                                |  31 +
 6 files changed, 960 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/mt6360_charger.yaml
 create mode 100644 drivers/power/supply/mt6360_charger.c
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/0c9f0e01/attachment-0001.sig>

From robh at kernel.org  Fri Aug 13 10:17:36 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:17:36 -0500
Subject: [PATCH v2 1/3] dt-bindings: PCI: ti,j721e: Add bindings to
 specify legacy interrupts
In-Reply-To: <20210804132912.30685-2-kishon@ti.com>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-2-kishon@ti.com>
Message-ID: <YRapMFNb63MSPJ1E@robh.at.kernel.org>

On Wed, Aug 04, 2021 at 06:59:10PM +0530, Kishon Vijay Abraham I wrote:
> Add bindings to specify interrupt controller for legacy interrupts.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  .../bindings/pci/ti,j721e-pci-host.yaml           | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
> index cc900202df29..f461d7b4c0cc 100644
> --- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
> +++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
> @@ -74,6 +74,11 @@ properties:
>  
>    msi-map: true
>  
> +patternProperties:
> +  "interrupt-controller":

Not a pattern unless you meant for foo-interrupt-controller-bar to be 
valid.

Anything is allowed in the node?

> +    type: object
> +    description: interrupt controller to handle legacy interrupts.
> +
>  required:
>    - compatible
>    - reg
> @@ -97,6 +102,8 @@ unevaluatedProperties: false
>  
>  examples:
>    - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
>      #include <dt-bindings/soc/ti,sci_pm_domain.h>
>      #include <dt-bindings/gpio/gpio.h>
>  
> @@ -131,5 +138,13 @@ examples:
>              ranges = <0x01000000 0x0 0x10001000  0x00 0x10001000  0x0 0x0010000>,
>                       <0x02000000 0x0 0x10011000  0x00 0x10011000  0x0 0x7fef000>;
>              dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
> +
> +
> +            pcie0_intc: interrupt-controller {
> +                    interrupt-controller;
> +                    #interrupt-cells = <1>;
> +                    interrupt-parent = <&gic500>;
> +                    interrupts = <GIC_SPI 312 IRQ_TYPE_EDGE_RISING>;
> +            };
>          };
>      };
> -- 
> 2.17.1
> 
> 


From robh at kernel.org  Fri Aug 13 10:22:34 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:22:34 -0500
Subject: [PATCH v2 3/6] dt-bindings: usb: dwc3: add reference clock period
In-Reply-To: <22f62c59471e128b681a731997a9416ab2e91acf.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <22f62c59471e128b681a731997a9416ab2e91acf.1628085910.git.baruch@tkos.co.il>
Message-ID: <YRaqWtSK7zNhKxSN@robh.at.kernel.org>

On Wed, Aug 04, 2021 at 05:05:07PM +0300, Baruch Siach wrote:
> Document the snps,ref-clock-period property that describes reference
> clock period when it deviates from the default set value.
> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
>  Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> index 41416fbd92aa..c8027d2852cd 100644
> --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
> @@ -252,6 +252,15 @@ properties:
>      minimum: 0
>      maximum: 0x3f
>  
> +  snps,ref-clock-period:
> +    description:
> +      Value for REFCLKPER field of GUCTL register for post-silicon reference

Why is post-silicon relevant here? Everything upstream should be for 
post-silicon. I've seen and done the hacks to make pre-silicon testing 
work and we don't need those upstream.

> +      clock period in nanoseconds, when the hardware set default does not match

If you have units, then use property unit suffix in the name.

> +      the actual clock.
> +    $ref: /schemas/types.yaml#/definitions/uint32

And then you can drop the type.

However, if the h/w block gets a ref clock why isn't it described in 
'clocks' and then you can just read why the frequency is and calculate 
the period.


From broonie at kernel.org  Fri Aug 13 10:25:24 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 13 Aug 2021 18:25:24 +0100
Subject: [PATCH resend v6 0/3] power: supply: mt6360_charger: add MT6360
 charger support
In-Reply-To: <20210813171106.entpro4b6dstho4s@earth.universe>
References: <20210719033914.16990-1-gene.chen.richtek@gmail.com>
 <20210813155438.4ssph6deqksob2uv@earth.universe>
 <20210813155858.GD5209@sirena.org.uk>
 <20210813162029.q5slrkubelfy3mvh@earth.universe>
 <20210813163254.GF5209@sirena.org.uk>
 <20210813171106.entpro4b6dstho4s@earth.universe>
Message-ID: <20210813172524.GG5209@sirena.org.uk>

On Fri, Aug 13, 2021 at 07:11:06PM +0200, Sebastian Reichel wrote:
> On Fri, Aug 13, 2021 at 05:32:54PM +0100, Mark Brown wrote:

> > It would be better, the issues I'm worrying about are more general
> > refactorings or whatever that create actual dependencies rather than
> > just trivial add/add type issues - it can make doing some kinds of work
> > really painful if things go via a different tree.

> There you go:

Thanks!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210813/cebbb358/attachment.sig>

From robh at kernel.org  Fri Aug 13 10:27:54 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:27:54 -0500
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <87v94lxpb0.fsf@tarshish>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org> <87v94lxpb0.fsf@tarshish>
Message-ID: <YRarmizUtzIunV1P@robh.at.kernel.org>

On Wed, Aug 04, 2021 at 05:22:27PM +0300, Baruch Siach wrote:
> Hi Felipe,
> 
> On Wed, Aug 04 2021, Felipe Balbi wrote:
> > Baruch Siach <baruch at tkos.co.il> writes:
> >> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
> >>  				    &dwc->hsphy_interface);
> >>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
> >>  				 &dwc->fladj);
> >> +	device_property_read_u32(dev, "snps,ref-clock-period",
> >> +				 &dwc->ref_clk_per);
> >
> > I wonder if it would make more sense to pass an actual clock reference
> > here. If valid, then reconfigure the period to the value returned by
> > clk_get_rate(). It would avoid yet another DT binding. If we make the
> > clock optional, then we won't affect any other platforms. The clock
> > itself could be a regular fixed clock node.
> 
> Thinh Nguyen asked to add a dedicated DT property. He explained that
> clk_get_rate() does not work for PCI hosted dwc3. This is the most
> complete summary of the discussion:
> 
>   https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32 at synopsys.com

PCI devices can have DT nodes with clock properties too. Or use the 
VID/PID to infer the frequency. Or use 'clock-frequency' property.

It boils down to we have lots of standard properties for clocks and 
clock configuration, so custom properties are a NAK.

Rob


From robh at kernel.org  Fri Aug 13 10:28:56 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:28:56 -0500
Subject: [PATCH v2 5/6] dt-bindings: usb: qcom,dwc3: add binding for
 IPQ6018
In-Reply-To: <24ce7c1258790b35a08e14a1e79a9447c3fed354.1628085910.git.baruch@tkos.co.il>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <24ce7c1258790b35a08e14a1e79a9447c3fed354.1628085910.git.baruch@tkos.co.il>
Message-ID: <YRar2LbE52HGr8J3@robh.at.kernel.org>

On Wed, 04 Aug 2021 17:05:09 +0300, Baruch Siach wrote:
> Add compatible string for Qualcomm IPQ6018 SoC.
> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
>  Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From maz at kernel.org  Fri Aug 13 10:33:58 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 13 Aug 2021 18:33:58 +0100
Subject: [PATCH 3/5] arm64: Detect disabled HVC early
In-Reply-To: <20210813090539.GA7536@willie-the-truck>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-4-maz@kernel.org>
 <20210813090539.GA7536@willie-the-truck>
Message-ID: <87k0kp1c6x.wl-maz@kernel.org>

On Fri, 13 Aug 2021 10:05:40 +0100,
Will Deacon <will at kernel.org> wrote:
> 
> On Thu, Aug 12, 2021 at 08:02:11PM +0100, Marc Zyngier wrote:
> > Having HVC disabled from EL3 while the kernel is entered at EL2
> > is a complete nightmare.
> > 
> > We end-up taking an UNDEF at the worse possible moment (checking
> > for VHE) and even if we didn't, having KVM enabled would signify
> > the premature end of the kernel.
> > 
> > Instead, try and detect this stupid case by issuing a HVC
> > for HVC_RESET_VECTORS, which does nothing when the stubs
> > are live. If we get HVC_STUB_ERR back, that's because the
> > UNDEF handler has kicked in.
> > 
> > In this situation, close your eyes, block your nose, and gracefully
> > pretend we have booted at EL1.
> > 
> > Reported-by: Rafa? Mi?ecki <zajec5 at gmail.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kernel/head.S | 22 ++++++++++++++++++++++
> >  1 file changed, 22 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> > index 9d5aa56a98cc..d6b2b05f5d3a 100644
> > --- a/arch/arm64/kernel/head.S
> > +++ b/arch/arm64/kernel/head.S
> > @@ -519,6 +519,28 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
> >  	msr	vbar_el2, x0
> >  	isb
> >  
> > +	// Check that HVC actually works...
> > +	mov	x0, #HVC_RESET_VECTORS
> > +	hvc	#0
> > +
> > +	mov_q	x1, HVC_STUB_ERR
> > +	cmp	x0, x1
> > +	b.ne	0f
> > +
> > +	/*
> > +	 * HVC is unusable, so pretend we actually booted at EL1.
> > +	 * Once we have left EL2, there will be no going back.
> > +	 */
> 
> This comment got me thinking...
> 
> 	.macro	host_hvc0
> 	mrs	xzr, actlr_el1
> 	.endm
> 
> then set HCR_EL2.TACR=1 while we still can and match the ISS against a
> constant in the handler. Too awful?

I had a similar idea, using an ID register instead (though ACTLR_EL1
is much neater). It would indeed allow the kernel to go back to EL2.

But for what purpose? Yes, we could enable KVM that way. However, the
guest would need to know about it as well, as even simple things like
PSCI wouldn't work. That's would be defining a new guest ABI, and I'm
not overly keen on it.

Unless you are thinking of something else?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Fri Aug 13 10:41:36 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 13 Aug 2021 18:41:36 +0100
Subject: [PATCH 2/5] arm64: Handle UNDEF in the EL2 stub vectors
In-Reply-To: <2f6bf17f-d235-8311-13d5-dcb3d00e23c4@arm.com>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-3-maz@kernel.org>
 <2f6bf17f-d235-8311-13d5-dcb3d00e23c4@arm.com>
Message-ID: <87im091bu7.wl-maz@kernel.org>

On Fri, 13 Aug 2021 14:08:23 +0100,
Robin Murphy <robin.murphy at arm.com> wrote:
> 
> On 2021-08-12 20:02, Marc Zyngier wrote:
> > As we want to handle the silly case where HVC has been disabled
> > from EL3, augment our ability to handle exception at EL2.
> > 
> > Check for unknown exceptions (usually UNDEF) coming from EL2,
> > and treat them as a failing HVC call into the stubs. While
> > this isn't great and obviously doesn't catter for the gigantic
> > range of possible exceptions, it isn't any worse than what we
> > have today.
> > 
> > Just don't try and use it for anything else.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >   arch/arm64/kernel/hyp-stub.S | 19 ++++++++++++++++++-
> >   1 file changed, 18 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> > index 43d212618834..026a34515b21 100644
> > --- a/arch/arm64/kernel/hyp-stub.S
> > +++ b/arch/arm64/kernel/hyp-stub.S
> > @@ -46,7 +46,16 @@ SYM_CODE_END(__hyp_stub_vectors)
> >   	.align 11
> >     SYM_CODE_START_LOCAL(elx_sync)
> > -	cmp	x0, #HVC_SET_VECTORS
> > +	mrs	x4, spsr_el2
> > +	and	x4, x4, #PSR_MODE_MASK
> > +	orr	x4, x4, #1
> > +	cmp	x4, #PSR_MODE_EL2h
> > +	b.ne	0f
> > +	mrs	x4, esr_el2
> > +	eor	x4, x4, #ESR_ELx_IL
> > +	cbz	x4, el2_undef
> 
> Hmm, might it be neater to check ESR_EL2.ISS to see if we landed here
> for any reason *other* than a successfully-executed HVC?

We absolutely could. However, the sixpence question (yes, that's the
Brexit effect for you) is "what do you do with exceptions that are
neither UNDEF now HVC?".

We are taking a leap of faith by assuming that the only thing that
will UNDEF at EL2 while the stubs are installed is HVC. If anything
else occurs, I have no idea what to do with it. I guess we could always
ignore it instead of treating it as a HVC (as it is done at the
moment).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From oupton at google.com  Fri Aug 13 10:46:10 2021
From: oupton at google.com (Oliver Upton)
Date: Fri, 13 Aug 2021 10:46:10 -0700
Subject: [PATCH v6 01/21] KVM: x86: Fix potential race in KVM_GET_CLOCK
In-Reply-To: <0b415872-7a67-d38b-ae01-62c38b365be0@redhat.com>
References: <20210804085819.846610-1-oupton@google.com>
 <20210804085819.846610-2-oupton@google.com>
 <78eeaf83-2bfa-8452-1301-a607fba7fa0c@redhat.com>
 <CAOQ_QsiwzKpaXUadGR6cWC2k0pg1P4QgkAxNdo0gpVAP1P3hSQ@mail.gmail.com>
 <0b415872-7a67-d38b-ae01-62c38b365be0@redhat.com>
Message-ID: <CAOQ_Qsjs7MOeh8ZGx3_CdgpedFwb9pYG_tQ4insdPwaqhAY=6g@mail.gmail.com>

On Fri, Aug 13, 2021 at 3:44 AM Paolo Bonzini <pbonzini at redhat.com> wrote:
>
> On 13/08/21 12:39, Oliver Upton wrote:
> > Might it make sense to fix this issue under the existing locking
> > scheme, then shift to what you're proposing? I say that, but the
> > locking change in 03/21 would most certainly have a short lifetime
> > until this patch supersedes it.
>
> Yes, definitely.  The seqcount change would definitely go in much later.
>   Extracting KVM_{GET,SET}_CLOCK to separate function would also be a
> patch of its own.  Give me a few more days of frantic KVM Forum
> preparation. :)

Sounds good :-) I'm probably going to send this out once more, in
three separate series:

- x86 (no changes, just rebasing)
- arm64 (address some comments, bugs)
- selftests (no changes)

--
Thanks,
Oliver

> Paolo
>


From robh at kernel.org  Fri Aug 13 10:46:49 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:46:49 -0500
Subject: [PATCH v2 1/3] dt-bindings: watchdog: sunxi: Add compatible for
 R329
In-Reply-To: <20210805045716.46141-1-samuel@sholland.org>
References: <20210805045716.46141-1-samuel@sholland.org>
Message-ID: <YRawCZ0BWEzTE4El@robh.at.kernel.org>

On Wed, Aug 04, 2021 at 11:57:14PM -0500, Samuel Holland wrote:
> On existing SoCs, the watchdog has a single clock input: HOSC (OSC24M)
> divided by 750.  However, starting with R329, LOSC (OSC32k) is added as
> an alternative clock source, with a bit to switch between them.
> 
> Since 24 MHz / 750 == 32 kHz, not 32.768 kHz, the hardware adjusts the
> cycle counts to keep the timeouts independent of the clock source. This
> keeps the programming interface backward-compatible.
> 
> R329 also adds two new registers, to allow software to immediately drive
> the SoC reset signal.
> 
> Signed-off-by: Samuel Holland <samuel at sholland.org>
> ---
> Changes v1 to v2:
>  - Switch from enum to const
>  - Add descriptions to "clocks" items
> 
>  .../watchdog/allwinner,sun4i-a10-wdt.yaml     | 32 ++++++++++++++++++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> index 9aa3c313c49f..8fa5b0d32381 100644
> --- a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> +++ b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> @@ -24,6 +24,7 @@ properties:
>                - allwinner,sun50i-a100-wdt
>                - allwinner,sun50i-h6-wdt
>                - allwinner,sun50i-h616-wdt
> +              - allwinner,sun50i-r329-wdt
>            - const: allwinner,sun6i-a31-wdt
>        - items:
>            - const: allwinner,suniv-f1c100s-wdt
> @@ -33,7 +34,18 @@ properties:
>      maxItems: 1
>  
>    clocks:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 2
> +    items:
> +      - description: High-frequency oscillator input, divided internally
> +      - description: Low-frequency oscillator input, only found on some variants
> +
> +  clock-names:
> +    minItems: 1
> +    maxItems: 2
> +    items:
> +      - const: hosc
> +      - const: losc
>  
>    interrupts:
>      maxItems: 1
> @@ -44,6 +56,24 @@ required:
>    - clocks
>    - interrupts
>  
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +        enum:
> +          - allwinner,sun50i-r329-wdt
> +
> +then:
> +  properties:
> +    clocks:
> +      minItems: 2
> +
> +    clock-names:
> +      minItems: 2
> +
> +  required:
> +    - clock-names

Needs an else clause with 'maxItems: 1' or is the 2nd clock now valid 
for all?

> +
>  unevaluatedProperties: false
>  
>  examples:
> -- 
> 2.31.1
> 
> 


From robh at kernel.org  Fri Aug 13 10:49:00 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:49:00 -0500
Subject: [PATCH 1/8] dt-bindings: arm: fsl: add NXP S32G2 boards
In-Reply-To: <bcb3ddd8-23c9-81c9-7d05-b475311068ec@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-2-clin@suse.com>
 <bcb3ddd8-23c9-81c9-7d05-b475311068ec@suse.de>
Message-ID: <YRawjOas2FixC5Kp@robh.at.kernel.org>

On Thu, Aug 12, 2021 at 05:46:16PM +0200, Andreas F?rber wrote:
> Hello Rob and NXP,
> 
> On 05.08.21 08:54, Chester Lin wrote:
> > Add bindings for S32G2's evaluation board (S32G-VNP-EVB) and reference
> > design 2 board ( S32G-VNP-RDB2).
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  Documentation/devicetree/bindings/arm/fsl.yaml | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
> > index e2097011c4b0..3914aa09e503 100644
> > --- a/Documentation/devicetree/bindings/arm/fsl.yaml
> > +++ b/Documentation/devicetree/bindings/arm/fsl.yaml
> > @@ -983,6 +983,13 @@ properties:
> >            - const: solidrun,lx2160a-cex7
> >            - const: fsl,lx2160a
> >  
> > +      - description: S32G2 based Boards
> > +        items:
> > +          - enum:
> > +              - fsl,s32g274a-evb
> > +              - fsl,s32g274a-rdb2
> 
> @Rob: Should for new boards the description: syntax be used also for
> enums? Or just at SoC level, and for board enums still traditional #
> comments?

It's up to how the platform wants to do it.

Rob


From robh at kernel.org  Fri Aug 13 10:53:59 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 12:53:59 -0500
Subject: [PATCH 1/8] dt-bindings: arm: fsl: add NXP S32G2 boards
In-Reply-To: <20210805065429.27485-2-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-2-clin@suse.com>
Message-ID: <YRaxt1LCF+hWaMJU@robh.at.kernel.org>

On Thu, Aug 05, 2021 at 02:54:22PM +0800, Chester Lin wrote:
> Add bindings for S32G2's evaluation board (S32G-VNP-EVB) and reference
> design 2 board ( S32G-VNP-RDB2).
> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  Documentation/devicetree/bindings/arm/fsl.yaml | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
> index e2097011c4b0..3914aa09e503 100644
> --- a/Documentation/devicetree/bindings/arm/fsl.yaml
> +++ b/Documentation/devicetree/bindings/arm/fsl.yaml
> @@ -983,6 +983,13 @@ properties:
>            - const: solidrun,lx2160a-cex7
>            - const: fsl,lx2160a
>  
> +      - description: S32G2 based Boards
> +        items:
> +          - enum:
> +              - fsl,s32g274a-evb
> +              - fsl,s32g274a-rdb2
> +          - const: fsl,s32g2

Given this is an entirely different family from i.MX and new?, shouldn't 
it use 'nxp' instead of 'fsl'? Either way,

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

Rob


From robh at kernel.org  Fri Aug 13 11:04:43 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:04:43 -0500
Subject: [PATCH 2/8] dt-bindings: serial: fsl-linflexuart: convert to
 json-schema format
In-Reply-To: <YRZa1ZX0gJb/yDrw@linux-8mug>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-3-clin@suse.com>
 <1ff13837-e6ca-c476-376d-b4f80450a259@suse.de>
 <YRZTSJPFLFFIR+gx@linux-8mug>
 <0b42dc7e-a7c1-fe41-e39a-89627d44cbe4@kernel.org>
 <YRZa1ZX0gJb/yDrw@linux-8mug>
Message-ID: <YRa0O9YNpHTsgi39@robh.at.kernel.org>

On Fri, Aug 13, 2021 at 07:43:17PM +0800, Chester Lin wrote:
> On Fri, Aug 13, 2021 at 01:28:40PM +0200, Krzysztof Kozlowski wrote:
> > On 13/08/2021 13:11, Chester Lin wrote:
> > > Hi Andreas,
> > > 
> > > On Thu, Aug 12, 2021 at 06:04:44PM +0200, Andreas F?rber wrote:
> > >> On 05.08.21 08:54, Chester Lin wrote:
> > >>> Convert the FSL LINFlexD UART binding to json-schema.
> > >>>
> > >>> Signed-off-by: Chester Lin <clin at suse.com>
> > >>> ---
> > >>>  .../bindings/serial/fsl,s32-linflexuart.txt   | 22 ---------
> > >>>  .../bindings/serial/fsl,s32-linflexuart.yaml  | 48 +++++++++++++++++++
> > >>>  2 files changed, 48 insertions(+), 22 deletions(-)
> > >>>  delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> > >>>  create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > >>
> > >> Thanks for your effort, Chester.
> > >>
> > >>> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> > >>> deleted file mode 100644
> > >>> index f1bbe0826be5..000000000000
> > >>> --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> > >>> +++ /dev/null
> > >>> @@ -1,22 +0,0 @@
> > >>> -* Freescale LINFlexD UART
> > >>> -
> > >>> -The LINFlexD controller implements several LIN protocol versions, as well as
> > >>> -support for full-duplex UART communication through 8-bit and 9-bit frames.
> > >>> -
> > >>> -See chapter 47 ("LINFlexD") in the reference manual[1].
> > >>> -
> > >>> -Required properties:
> > >>> -- compatible :
> > >>> -  - "fsl,s32v234-linflexuart" for LINFlexD configured in UART mode, which
> > >>> -    is compatible with the one integrated on S32V234 SoC
> > >>> -- reg : Address and length of the register set for the device
> > >>> -- interrupts : Should contain uart interrupt
> > >>> -
> > >>> -Example:
> > >>> -uart0: serial at 40053000 {
> > >>> -	compatible = "fsl,s32v234-linflexuart";
> > >>> -	reg = <0x0 0x40053000 0x0 0x1000>;
> > >>> -	interrupts = <0 59 4>;
> > >>> -};
> > >>> -
> > >>> -[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM
> > >>> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > >>> new file mode 100644
> > >>> index 000000000000..acfe34706ccb
> > >>> --- /dev/null
> > >>> +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > >>> @@ -0,0 +1,48 @@
> > >>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > >>
> > >> Since this is dual-licensed and BSD-2-Clause would seem compatible with
> > >> GPLv3, this could probably be s/GPL-2.0-only/GPL-2.0-or-later/ ? Not a
> > >> blocker.
> > > 
> > > There's no license identifier in the original file so it's not a problem to
> > > choose "GPL-2.0-or-later".
> > 
> > That is not entirely correct. If there is no explicit license in the
> > file, it's kernel's default so GPL-2.0-only. You cannot relicense
> > derivative work without getting permission from authors and copyright
> > holders.
> > 
> > However if you did not copy the text/description from original bindings,
> > your work won't be derivative so you can relicense it.
> > 
> 
> Sorry for my misunderstanding and thanks for the reminder.

TBC, please try and get permission to relicense. The single author was 
from NXP so changing the license here just needs the okay from any NXP 
employee.

But use 'GPL-2.0-only' not 'GPL-2.0-or-later' please. As gregkh says,
are you okay with GPLv4, v5, etc.?

Rob


From robh at kernel.org  Fri Aug 13 11:07:17 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:07:17 -0500
Subject: [PATCH 2/8] dt-bindings: serial: fsl-linflexuart: convert to
 json-schema format
In-Reply-To: <20210805065429.27485-3-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-3-clin@suse.com>
Message-ID: <YRa01Xj1i9bF2xbR@robh.at.kernel.org>

On Thu, Aug 05, 2021 at 02:54:23PM +0800, Chester Lin wrote:
> Convert the FSL LINFlexD UART binding to json-schema.
> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  .../bindings/serial/fsl,s32-linflexuart.txt   | 22 ---------
>  .../bindings/serial/fsl,s32-linflexuart.yaml  | 48 +++++++++++++++++++
>  2 files changed, 48 insertions(+), 22 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
>  create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> 
> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> deleted file mode 100644
> index f1bbe0826be5..000000000000
> --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -* Freescale LINFlexD UART
> -
> -The LINFlexD controller implements several LIN protocol versions, as well as
> -support for full-duplex UART communication through 8-bit and 9-bit frames.
> -
> -See chapter 47 ("LINFlexD") in the reference manual[1].
> -
> -Required properties:
> -- compatible :
> -  - "fsl,s32v234-linflexuart" for LINFlexD configured in UART mode, which
> -    is compatible with the one integrated on S32V234 SoC
> -- reg : Address and length of the register set for the device
> -- interrupts : Should contain uart interrupt
> -
> -Example:
> -uart0: serial at 40053000 {
> -	compatible = "fsl,s32v234-linflexuart";
> -	reg = <0x0 0x40053000 0x0 0x1000>;
> -	interrupts = <0 59 4>;
> -};
> -
> -[1] https://www.nxp.com/webapp/Download?colCode=S32V234RM
> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> new file mode 100644
> index 000000000000..acfe34706ccb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> @@ -0,0 +1,48 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/serial/fsl,s32-linflexuart.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale LINFlexD UART
> +
> +description: |
> +  The LINFlexD controller implements several LIN protocol versions, as well
> +  as support for full-duplex UART communication through 8-bit and 9-bit
> +  frames. See chapter 47 ("LINFlexD") in the reference manual
> +  https://www.nxp.com/webapp/Download?colCode=S32V234RM.
> +
> +maintainers:
> +  - Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> +  - Rob Herring <robh at kernel.org>

Someone that cares about this h/w, not who applies patches.

> +
> +allOf:
> +  - $ref: "serial.yaml"
> +
> +properties:
> +  compatible:
> +    description: The LINFlexD controller on S32V234 SoC, which can be
> +      configured in UART mode.

Drop 'on S32V234 SoC' so we're not editting for every new SoC.

> +    items:
> +      - const: fsl,s32v234-linflexuart
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    serial at 40053000 {
> +        compatible = "fsl,s32v234-linflexuart";
> +        reg = <0x40053000 0x1000>;
> +        interrupts = <0 59 4>;
> +    };
> -- 
> 2.30.0
> 
> 


From robh at kernel.org  Fri Aug 13 11:09:16 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:09:16 -0500
Subject: [PATCH 3/8] dt-bindings: serial: fsl-linflexuart: Add compatible
 for S32G2
In-Reply-To: <20210805065429.27485-4-clin@suse.com>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-4-clin@suse.com>
Message-ID: <YRa1THsZ/6BFkzo5@robh.at.kernel.org>

On Thu, Aug 05, 2021 at 02:54:24PM +0800, Chester Lin wrote:
> Add a compatible string for the uart binding of NXP S32G2 platforms. Here
> we use "s32v234-linflexuart" as fallback since the current linflexuart
> driver still works on S32G2.
> 
> Signed-off-by: Chester Lin <clin at suse.com>
> ---
>  .../bindings/serial/fsl,s32-linflexuart.yaml  | 26 ++++++++++++++++---
>  1 file changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> index acfe34706ccb..e731f3f6cea4 100644
> --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> @@ -21,10 +21,20 @@ allOf:
>  
>  properties:
>    compatible:
> -    description: The LINFlexD controller on S32V234 SoC, which can be
> -      configured in UART mode.
> -    items:
> -      - const: fsl,s32v234-linflexuart
> +    minItems: 1
> +    maxItems: 2

minItems/maxItems not needed here.

> +    oneOf:
> +      - description: The LINFlexD controller on S32G2 SoC, which can be
> +          configured in UART mode.
> +        items:
> +          - enum:
> +              - fsl,s32g2-linflexuart
> +          - const: fsl,s32v234-linflexuart
> +
> +      - description: The LINFlexD controller on S32V234 SoC, which can be
> +          configured in UART mode.
> +        items:
> +          - const: fsl,s32v234-linflexuart
>  
>    reg:
>      maxItems: 1
> @@ -41,8 +51,16 @@ unevaluatedProperties: false
>  
>  examples:
>    - |
> +    /* S32V234 */
>      serial at 40053000 {
>          compatible = "fsl,s32v234-linflexuart";
>          reg = <0x40053000 0x1000>;
>          interrupts = <0 59 4>;
>      };
> +
> +    /* S32G2 */
> +    serial at 401c8000 {
> +        compatible = "fsl,s32g2-linflexuart", "fsl,s32v234-linflexuart";
> +        reg = <0x401c8000 0x3000>;
> +        interrupts = <0 82 1>;
> +    };

This doesn't really warrant another example just for a new compatible 
string.


From robh at kernel.org  Fri Aug 13 11:11:13 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:11:13 -0500
Subject: [PATCH 3/8] dt-bindings: serial: fsl-linflexuart: Add compatible
 for S32G2
In-Reply-To: <96c02ee6-cd3a-59df-0b3b-1632bb355019@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-4-clin@suse.com>
 <96c02ee6-cd3a-59df-0b3b-1632bb355019@suse.de>
Message-ID: <YRa1wUW0Dp4GhZYx@robh.at.kernel.org>

On Thu, Aug 12, 2021 at 06:27:57PM +0200, Andreas F?rber wrote:
> On 05.08.21 08:54, Chester Lin wrote:
> > Add a compatible string for the uart binding of NXP S32G2 platforms. Here
> > we use "s32v234-linflexuart" as fallback since the current linflexuart
> > driver still works on S32G2.
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  .../bindings/serial/fsl,s32-linflexuart.yaml  | 26 ++++++++++++++++---
> >  1 file changed, 22 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > index acfe34706ccb..e731f3f6cea4 100644
> > --- a/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > +++ b/Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.yaml
> > @@ -21,10 +21,20 @@ allOf:
> >  
> >  properties:
> >    compatible:
> > -    description: The LINFlexD controller on S32V234 SoC, which can be
> > -      configured in UART mode.
> > -    items:
> > -      - const: fsl,s32v234-linflexuart
> > +    minItems: 1
> > +    maxItems: 2
> 
> Are these necessary for oneOf?
> 
> > +    oneOf:
> > +      - description: The LINFlexD controller on S32G2 SoC, which can be
> > +          configured in UART mode.
> > +        items:
> > +          - enum:
> > +              - fsl,s32g2-linflexuart
> > +          - const: fsl,s32v234-linflexuart
> 
> This reads inconsistent to me: Either this oneOf is for S32G2 only, then
> please turn the enum into a const. Or change the description to "on SoCs
> compatible with S32V234" if we expect the enum list to grow.
> 
> I believe the idea here was to avoid unnecessary driver compatible and
> earlycon compatible additions, while preparing for eventual quirks
> specific to S32G2.
> 
> @NXP: Should this be s32g2- like above or s32g274a- specifically? Do you
> agree this is a useful thing to prepare here, as opposed to using only
> s32v234- in the s32g2* DT?
> 
> I assume the ordering is done alphabetically as S32G < S32V;
> alternatively we might order S32V234 first and then the compatible ones.
> 
> > +
> > +      - description: The LINFlexD controller on S32V234 SoC, which can be
> > +          configured in UART mode.
> > +        items:
> > +          - const: fsl,s32v234-linflexuart
> 
> To minimize this S32G2 patch, would it be valid to do oneOf for the
> single S32V in the preceding patch already? Then we would avoid the text
> movement and re-indentation above and more easily see the lines newly
> getting added for S32G2.
> 
> >  
> >    reg:
> >      maxItems: 1
> > @@ -41,8 +51,16 @@ unevaluatedProperties: false
> >  
> >  examples:
> >    - |
> > +    /* S32V234 */
> 
> Could this be:
>   - description: S32V234
>     |
> ?

No, that would not be valid json-schema.

Rob


From robin.murphy at arm.com  Fri Aug 13 11:17:56 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 13 Aug 2021 19:17:56 +0100
Subject: [PATCH 2/5] arm64: Handle UNDEF in the EL2 stub vectors
In-Reply-To: <87im091bu7.wl-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-3-maz@kernel.org>
 <2f6bf17f-d235-8311-13d5-dcb3d00e23c4@arm.com> <87im091bu7.wl-maz@kernel.org>
Message-ID: <060ef66a-6d6f-082e-5f69-117235b8ce4e@arm.com>

On 2021-08-13 18:41, Marc Zyngier wrote:
> On Fri, 13 Aug 2021 14:08:23 +0100,
> Robin Murphy <robin.murphy at arm.com> wrote:
>>
>> On 2021-08-12 20:02, Marc Zyngier wrote:
>>> As we want to handle the silly case where HVC has been disabled
>>> from EL3, augment our ability to handle exception at EL2.
>>>
>>> Check for unknown exceptions (usually UNDEF) coming from EL2,
>>> and treat them as a failing HVC call into the stubs. While
>>> this isn't great and obviously doesn't catter for the gigantic
>>> range of possible exceptions, it isn't any worse than what we
>>> have today.
>>>
>>> Just don't try and use it for anything else.
>>>
>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>>> ---
>>>    arch/arm64/kernel/hyp-stub.S | 19 ++++++++++++++++++-
>>>    1 file changed, 18 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
>>> index 43d212618834..026a34515b21 100644
>>> --- a/arch/arm64/kernel/hyp-stub.S
>>> +++ b/arch/arm64/kernel/hyp-stub.S
>>> @@ -46,7 +46,16 @@ SYM_CODE_END(__hyp_stub_vectors)
>>>    	.align 11
>>>      SYM_CODE_START_LOCAL(elx_sync)
>>> -	cmp	x0, #HVC_SET_VECTORS
>>> +	mrs	x4, spsr_el2
>>> +	and	x4, x4, #PSR_MODE_MASK
>>> +	orr	x4, x4, #1
>>> +	cmp	x4, #PSR_MODE_EL2h
>>> +	b.ne	0f
>>> +	mrs	x4, esr_el2
>>> +	eor	x4, x4, #ESR_ELx_IL
>>> +	cbz	x4, el2_undef
>>
>> Hmm, might it be neater to check ESR_EL2.ISS to see if we landed here
>> for any reason *other* than a successfully-executed HVC?
> 
> We absolutely could. However, the sixpence question (yes, that's the
> Brexit effect for you) is "what do you do with exceptions that are
> neither UNDEF now HVC?".
> 
> We are taking a leap of faith by assuming that the only thing that
> will UNDEF at EL2 while the stubs are installed is HVC. If anything
> else occurs, I have no idea what to do with it. I guess we could always
> ignore it instead of treating it as a HVC (as it is done at the
> moment).

Right, I think that concern applies pretty much equally whichever way 
you slice it. "Any exception other than an unknown from EL2 must imply 
HVC" doesn't seem any less sketchy than "Any exception other than HVC 
implies something is horribly wrong and abandoning EL2 might be wise" to 
me, but it was primarily that the latter avoids having to faff with the 
SPSR as well. No big deal either way, just one of my "I reckon this 
could be shorter..." musings; it's been particularly Friday today :)

Robin.


From robh at kernel.org  Fri Aug 13 11:22:59 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:22:59 -0500
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <VI1PR04MB6800EE08F70CC3F0DD53C991E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
 <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <YRKOGYwx1uVdsKoF@lunn.ch>
 <VI1PR04MB6800EE08F70CC3F0DD53C991E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>
Message-ID: <YRa4g8cjGrQ979pQ@robh.at.kernel.org>

On Wed, Aug 11, 2021 at 07:57:46AM +0000, Joakim Zhang wrote:
> 
> Hi Andrew,
> 
> > -----Original Message-----
> > From: Andrew Lunn <andrew at lunn.ch>
> > Sent: 2021?8?10? 22:33
> > To: Joakim Zhang <qiangqing.zhang at nxp.com>
> > Cc: Florian Fainelli <f.fainelli at gmail.com>; davem at davemloft.net;
> > kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> > s.hauer at pengutronix.de; festevam at gmail.com; kernel at pengutronix.de;
> > dl-linux-imx <linux-imx at nxp.com>; netdev at vger.kernel.org;
> > devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> > linux-arm-kernel at lists.infradead.org
> > Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
> > wakeup-irq" property
> > 
> > > > > 1) FEC controller has up to 4 interrupt lines and all of these are
> > > > > routed to GIC
> > > > interrupt controller.
> > > > > 2) FEC has a wakeup interrupt signal and always are mixed with
> > > > > other
> > > > interrupt signals, and then output to one interrupt line.
> > > > > 3) For legacy SoCs, wakeup interrupt are mixed to int0 line, but
> > > > > for i.MX8M
> > > > serials, are mixed to int2 line.
> > 
> > So you need to know which of the interrupts listed is the wake up interrupt.

We already have a way to do this by using 'wakeup' for the 
interrupt-names entry. But I guess that ship has sailed here and that 
wouldn't work well if not just a wakeup source (though you could repeat 
an interrupt line that's the wakeup source).

> > 
> > I can see a few ways to do this:
> > 
> > The FEC driver already has quirks. Add a quirk to fec_imx8mq_info and
> > fec_imx8qm_info to indicate these should use int2.

Bingo!

Note that if the device is wakeup capable, it should have a 
'wakeup-source' property in this case.

> > 
> > or
> > 
> > Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
> > 
> >   b) two cells
> >   ------------
> >   The #interrupt-cells property is set to 2 and the first cell defines the
> >   index of the interrupt within the controller, while the second cell is used
> >   to specify any of the following flags:
> >     - bits[3:0] trigger type and level flags
> >         1 = low-to-high edge triggered
> >         2 = high-to-low edge triggered
> >         4 = active high level-sensitive
> >         8 = active low level-sensitive
> > 
> > You could add
> > 
> >        18 = wakeup source

I'd be okay with this (though it should be a power of 2 number).

> > 
> > and extend to core to either do all the work for you, or tell you this interrupt is
> > flagged as being a wakeup source. This solution has the advantage of it should
> > be usable in other drivers.

Another option is couldn't you just enable all the interrupts as wakeup 
sources? Presumably, only one of them would trigger a wakeup.

> 
> Thanks a lot for your comments first!
> 
> I just look into the irq code, if we extend bit[5] to carry wakeup info ( due to bit[4] is used for IRQ_TYPE_PROBE), 
> then configure it in the TYPE field of 'interrupts' property, so that interrupt controller would know which interrupt
> is wakeup capable. 
> I think there is no much work core would do, may just set this interrupt wakup capable. Another functionality is
> driver side get this info to identify which mixed interrupt has wakeup capability, we can export symbol from kernel/irq/irqdomain.c.
> 
> The intention is to let driver know which interrupt is wakeup capable, I would choose to provider this in specific driver,
> instead of interrupt controller, it seems to me that others may all choose this solution for wakeup mixed interrupt.
> 
> So I would prefer solution 1, it's easier and under-control. I can have a try if you strongly recommend solution 2.
> 
> Best Regards,
> Joakim Zhang
> > 	  Andrew


From mka at chromium.org  Fri Aug 13 11:33:09 2021
From: mka at chromium.org (Matthias Kaehlcke)
Date: Fri, 13 Aug 2021 11:33:09 -0700
Subject: [PATCH v15 0/6] usb: misc: Add onboard_usb_hub driver
In-Reply-To: <166449bc-4c33-b923-f53d-6df4f83dc267@kernel.org>
References: <20210727004118.2583774-1-mka@chromium.org>
 <YRFOnhJkB2vi/zwD@google.com>
 <8a8cae28-6617-76d3-1742-3f151a149069@kernel.org>
 <ddd60682-c957-2897-768e-96c9d25c148a@kernel.org>
 <YRVVjwNprk7l1jUk@google.com>
 <166449bc-4c33-b923-f53d-6df4f83dc267@kernel.org>
Message-ID: <YRa65ZWzkB5OLpPm@google.com>

On Fri, Aug 13, 2021 at 09:35:53AM +0300, Roger Quadros wrote:
> Hi Matthias,
> 
> On 12/08/2021 20:08, Matthias Kaehlcke wrote:
> > Hi Roger,
> > 
> > On Wed, Aug 11, 2021 at 03:56:15PM +0300, Roger Quadros wrote:
> >>
> >>
> >> On 11/08/2021 15:38, Roger Quadros wrote:
> >>> Hi Matthias,
> >>>
> >>> On 09/08/2021 18:49, Matthias Kaehlcke wrote:
> >>>> Hi Greg,
> >>>>
> >>>> Just wanted to check if this series is still on your radar. Is
> >>>> there anything that blocks it from landing (further ACKs, ...)?
> >>>>
> >>>> Thanks
> >>>>
> >>>> Matthias
> >>>>
> >>>> On Mon, Jul 26, 2021 at 05:41:12PM -0700, Matthias Kaehlcke wrote:
> >>>>> This series adds:
> >>>>> - the onboard_usb_hub_driver
> >>>>> - glue in the xhci-plat driver to create and destroy the
> >>>>>   onboard_usb_hub platform devices if needed
> >>>>> - a device tree binding for the Realtek RTS5411 USB hub controller
> >>>>> - device tree changes that add RTS5411 entries for the QCA SC7180
> >>>>>   based boards trogdor and lazor
> >>>>> - a couple of stubs for platform device functions to avoid
> >>>>>   unresolved symbols with certain kernel configs
> >>>>>
> >>>>> The main issue the driver addresses is that a USB hub needs to be
> >>>>> powered before it can be discovered. For discrete onboard hubs (an
> >>>>> example for such a hub is the Realtek RTS5411) this is often solved
> >>>>> by supplying the hub with an 'always-on' regulator, which is kind
> >>>>> of a hack. Some onboard hubs may require further initialization
> >>>>> steps, like changing the state of a GPIO or enabling a clock, which
> >>>>> requires even more hacks. This driver creates a platform device
> >>>>> representing the hub which performs the necessary initialization.
> >>>>> Currently it only supports switching on a single regulator, support
> >>>>> for multiple regulators or other actions can be added as needed.
> >>>>> Different initialization sequences can be supported based on the
> >>>>> compatible string.
> >>>>>
> >>>>> Besides performing the initialization the driver can be configured
> >>>>> to power the hub off during system suspend. This can help to extend
> >>>>> battery life on battery powered devices which have no requirements
> >>>>> to keep the hub powered during suspend. The driver can also be
> >>>>> configured to leave the hub powered when a wakeup capable USB device
> >>>>> is connected when suspending, and power it off otherwise.
> >>>>>
> >>>>> Changes in v15:
> >>>>> - adjusted dependencies of USB_DWC3_CORE to make sure it can only
> >>>>>   be enabled when at least one of USB_DWC3_HOST, USB_DWC3_GADGET
> >>>>>   or USB_DWC3_DUAL_ROLE is selectable
> >>>>>
> >>>>> Changes in v14:
> >>>>> - rebased on top of v5.14-rc1
> >>>>> - dropped DT binding patch which landed in v5.13
> >>>>>
> >>>>> Changes in v13:
> >>>>> - added patch "usb: Specify dependency on USB_XHCI_PLATFORM with
> >>>>>   'depends on'" to the series to avoid Kconfig conflicts
> >>>>> - added patch "arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM"
> >>>>>   to the series to keep effective defconfig unchanged
> >>>>>
> >>>>> Changes in v12:
> >>>>> - onboard_hub driver: use IS_ENABLED(CONFIG_USB_ONBOARD_HUB_MODULE)
> >>>>>   in onboard_hub.h to also check for the driver built as module
> >>>>> - onboard_hub_driver: include onboard_hub.h again to make sure there
> >>>>>   are prototype declarations for the public functions
> >>>>>
> >>>>> Changes in v11:
> >>>>> - support multiple onboard hubs connected to the same parent
> >>>>> - don't include ?onboard_hub.h? from the onboard hub driver
> >>>>>
> >>>>> Changes in v10:
> >>>>> - always use of_is_onboard_usb_hub() stub unless ONBOARD_USB_HUB=y/m
> >>>>> - keep 'regulator-boot-on' property for pp3300_hub
> >>>>>
> >>>>> Changes in v9:
> >>>>> - added dependency on ONBOARD_USB_HUB (or !!ONBOARD_USB_HUB) to
> >>>>>   USB_PLATFORM_XHCI
> >>>>>
> >>>>> Changes in v7:
> >>>>> - updated DT binding
> >>>>> - series rebased on qcom/arm64-for-5.13
> >>>>>
> >>>>> Changes in v6:
> >>>>> - updated summary
> >>>>>
> >>>>> Changes in v5:
> >>>>> - cover letter added
> >>>>>
> >>>>> Matthias Kaehlcke (6):
> >>>>>   usb: misc: Add onboard_usb_hub driver
> >>>>>   of/platform: Add stubs for of_platform_device_create/destroy()
> >>>>>   arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM
> >>>>>   usb: Specify dependencies on USB_XHCI_PLATFORM with 'depends on'
> >>>>>   usb: host: xhci-plat: Create platform device for onboard hubs in
> >>>>>     probe()
> >>>>>   arm64: dts: qcom: sc7180-trogdor: Add nodes for onboard USB hub
> >>>>>
> >>>>>  .../sysfs-bus-platform-onboard-usb-hub        |   8 +
> >>>>>  MAINTAINERS                                   |   7 +
> >>>>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r0.dts |  19 +-
> >>>>>  .../boot/dts/qcom/sc7180-trogdor-lazor-r1.dts |  12 +-
> >>>>>  .../arm64/boot/dts/qcom/sc7180-trogdor-r1.dts |  19 +-
> >>>>>  arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi  |  19 +-
> >>>>>  arch/arm64/configs/defconfig                  |   1 +
> >>>>>  drivers/usb/cdns3/Kconfig                     |   2 +-
> >>>>>  drivers/usb/dwc3/Kconfig                      |   5 +-
> >>>>>  drivers/usb/host/Kconfig                      |   5 +-
> >>>
> >>> These Kconfig changes are causing the resulting .config to be different.
> >>> For example, if I start with omap2plus_defconfig, the resulting .config
> >>> before and after your series is different as shown below
> >>>
> >>> :/work/linux$ diff /tmp/.config .config
> >>> 1902d1901
> >>> < # CONFIG_HISI_HIKEY_USB is not set
> >>> 4992c4991
> >>> < CONFIG_USB_XHCI_PLATFORM=m
> >>> ---
> >>>> # CONFIG_USB_XHCI_PLATFORM is not set
> >>> 5073,5075c5072
> >>> < # CONFIG_USB_DWC3_HOST is not set
> >>> < # CONFIG_USB_DWC3_GADGET is not set
> >>> < CONFIG_USB_DWC3_DUAL_ROLE=y
> >>> ---
> >>>> CONFIG_USB_DWC3_GADGET=y
> >>> 5173a5171
> >>>> # CONFIG_USB_ONBOARD_HUB is not set
> >>> 5285c5283
> >>> < CONFIG_USB_ROLE_SWITCH=m
> >>> ---
> >>>> # CONFIG_USB_ROLE_SWITCH is not set
> >>>
> >>> I would expect the same issues for multi_v7_defconfig and multi_v8_defconfig as well.
> >>
> >> Sorry I meant defconfig for arm64, not multi_v8_defconfig.
> >>
> >> I checked that for arm64 defconfig it is ok.
> >>
> >>> I'm ok to update the relevant defconfigs files so that the resulting .config is identical to
> >>> before your series. Thanks!
> >>
> >> With the below patch you can fix it for omap2plus_defconfig and multi_v7_defconfig.
> >>
> >> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> >> index d9abaae118dd..8c175ab37377 100644
> >> --- a/arch/arm/configs/multi_v7_defconfig
> >> +++ b/arch/arm/configs/multi_v7_defconfig
> >> @@ -787,6 +787,7 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
> >>  CONFIG_USB=y
> >>  CONFIG_USB_OTG=y
> >>  CONFIG_USB_XHCI_HCD=y
> >> +CONFIG_USB_XHCI_PLATFORM=y
> >>  CONFIG_USB_XHCI_MVEBU=y
> >>  CONFIG_USB_XHCI_TEGRA=m
> >>  CONFIG_USB_EHCI_HCD=y
> >> diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
> >> index 2ac2418084ab..a015fb04fa25 100644
> >> --- a/arch/arm/configs/omap2plus_defconfig
> >> +++ b/arch/arm/configs/omap2plus_defconfig
> >> @@ -562,6 +562,7 @@ CONFIG_USB=m
> >>  CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
> >>  CONFIG_USB_MON=m
> >>  CONFIG_USB_XHCI_HCD=m
> >> +CONFIG_USB_XHCI_PLATFORM=m
> >>  CONFIG_USB_EHCI_HCD=m
> >>  CONFIG_USB_OHCI_HCD=m
> >>  CONFIG_USB_ACM=m
> > 
> > Thanks for testing!
> > 
> > I completely forgot that arm32 has all these different defconfigs.
> > 
> > While trying to adjust qcom_defconfig I came across something that confuses
> > me. The original defconfig results in:
> > 
> > # CONFIG_USB_XHCI_HCD is not set
> > CONFIG_USB_DWC3_DUAL_ROLE=y
> 
> The original Kconfig was:
> 
> > config USB_DWC3_DUAL_ROLE
> >         bool "Dual Role mode"
> >         depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3))
> >         depends on (EXTCON=y || EXTCON=USB_DWC3)
> 
> Which means USB_DWC3_DUAL_ROLE can be enabled even without CONFIG_USB_XHCI_HCD.
> 
> All the dual role code does is add/remove the host/gadget controller platform devices.
> It doesn't care whether there is a driver for it or not.
> i.e. there is no build dependency on CONFIG_USB_XHCI_HCD.
> 
> > 
> > My assumption was that xHCI support is need for dwc3 dual mode (which is
> > made explicit by https://lore.kernel.org/patchwork/patch/1468240/), is
> > that incorrect? Maybe without xHCI support the controller can still
> > operate in USB 2.0 dual role mode?
> > 
> 
> Without xHCI support the host functionality will not work at all on dwc3 dual role.
> So I think your Kconfig changes for USB_DWC3_DUAL_ROLE to depend on USB_XHCI_PLATFORM
> are correct.

Thanks for the clarification!


From valentin.schneider at arm.com  Fri Aug 13 11:48:41 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Fri, 13 Aug 2021 19:48:41 +0100
Subject: [PATCH v3 3/4] rcu/nocb: Protect NOCB state via local_lock()
 under PREEMPT_RT
In-Reply-To: <20210813002045.GZ4126399@paulmck-ThinkPad-P17-Gen-1>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-4-valentin.schneider@arm.com>
 <20210813002045.GZ4126399@paulmck-ThinkPad-P17-Gen-1>
Message-ID: <87v9496v06.mognet@arm.com>

On 12/08/21 17:20, Paul E. McKenney wrote:
> On Wed, Aug 11, 2021 at 09:13:53PM +0100, Valentin Schneider wrote:
>> rcu_core() preemptability considerations
>> ========================================
>> 
>> As pointed out by Paul [2], keeping rcu_check_quiescent_state() preemptible
>> (which is the case under CONFIG_PREEMPT_RT) requires some consideration.
>> 
>> note_gp_changes() itself runs with irqs off, and enters
>> __note_gp_changes() with rnp->lock held (raw_spinlock), thus is safe vs
>> preemption.
>> 
>> rdp->core_needs_qs *could* change after being read by the RCU core
>> kthread if it then gets preempted. Consider, with
>> CONFIG_RCU_STRICT_GRACE_PERIOD:
>> 
>>   rcuc/x                                   task_foo
>> 
>>     rcu_check_quiescent_state()
>>     `\
>>       rdp->core_needs_qs == true
>> 			     <PREEMPT>
>> 					   rcu_read_unlock()
>> 					   `\
>> 					     rcu_preempt_deferred_qs_irqrestore()
>> 					     `\
>> 					       rcu_report_qs_rdp()
>> 					       `\
>> 						 rdp->core_needs_qs := false;
>> 
>> This would let rcuc/x's rcu_check_quiescent_state() proceed further down to
>> rcu_report_qs_rdp(), but if task_foo's earlier rcu_report_qs_rdp()
>> invocation would have cleared the rdp grpmask from the rnp mask, so
>> rcuc/x's invocation would simply bail.
>> 
>> Since rcu_report_qs_rdp() can be safely invoked, even if rdp->core_needs_qs
>> changed, it appears safe to keep rcu_check_quiescent_state() preemptible.
>
> Another concern...
>
> During the preemption of rcu_check_quiescent_state() someone might report
> a quiescent state on behalf of CPU x (perhaps due to its having recently
> been idle) and then the RCU grace-period kthread might start running on
> CPU x, where it might initialize a new grace period in rcu_gp_init().
> It can then invoke __note_gp_changes(), also on CPU x.
>

(this is me "writing out loud" to make sure I can follow)

I take it the preemption of rcuc/x itself would count as a quiescent state,
if the current grace period started before rcuc/x's rcu_read_lock()
(rcuc/x would end up in ->blkd_tasks but wouldn't affect ->gp_tasks).

Then if we get something to run rcu_report_qs_rnp() with a mask spanning
CPU x - I think the GP kthread doing quiescent state forcing might fit the
bill - we'll let the GP kthread initialize a new GP.

> If preempted as shown above just after checking >core_needs_qs, the
> ->cpu_no_qs.b.norm field will be set by the grace-period kthread, which
> will cause the rcu_check_quiescent_state() function's subsequent check
> of ->cpu_no_qs.b.norm to take an early exit.  So OK here.
>

Right

> On the other hand, if preempted just after the rcu_check_quiescent_state()
> function's check of ->cpu_no_qs.b.norm, the later invocation of
> rcu_report_qs_rdp() should take an early exit due to ->gp_seq mismatch.
> So OK here.
>

If, as described in your scenario above, the GP kthread has preempted
rcuc/x, initialized a new GP and has run __note_gp_changes() (on CPU x),
then wouldn't the rdp->gp_seq and rnp->gp_seq match when rcuc/x gets to run
again?

And because we would've then had a context switch between the GP kthread
and rcuc/x, we would've noted a quiescent state for CPU x, which would let
rcuc/x's rcu_report_qs_rdp() continue - or have I erred on the way there?

> However, this should be added to the commit log.  Might be a big commit
> log, but mass storage is cheap these days.  ;-)
>

No objections here!

> This needs a review of each and every manipulation of ->core_needs_qs
> and ->cpu_no_qs.b.norm.  For example, the preemptions will cause the
> scheduler to invoke RCU's context-switch hooks, which also mess with
> ->cpu_no_qs.b.norm.  I can get to that some time next week (or tomorrow,
> if things go better than expected), but it would be good for you (and
> others) to check as well.
>

I have some notes scribbled down regarding those that I need to go through
again, but that won't be before a week's time - I'll be away next week.

> Frederic should look this over, but I am taking a quick pass in the
> meantime.  Please see below.
>

Thanks!

>> @@ -210,6 +210,8 @@ struct rcu_data {
>>  	struct timer_list nocb_timer;	/* Enforce finite deferral. */
>>  	unsigned long nocb_gp_adv_time;	/* Last call_rcu() CB adv (jiffies). */
>>  
>> +	local_lock_t nocb_local_lock;
>
> Should this go near the beginning of the structure, given that code
> paths taking this lock tend to access ->cpu_no_qs, ->core_needs_qs,
> and so on?
>
> Given that it is used to protect core processing (not just offloaded
> callbacks), might ->core_local_lock be a better name?
>

It would still have to be in a #define CONFIG_RCU_NOCB_CPU region IMO, as
it only exists to protect access of the offloading state - hence the name,
but I'm not particularly attached to it.

> Please keep in mind that you can build kernels that offload callbacks
> but that still use softirq for RCU core processing.  And vice versa,
> that is, kernels that use rcuc kthreads but do not offload callbacks.
>

AFAICT the problem only stands if core processing becomes preemptible,
which is only the case under PREEMPT_RT (at least for now), and that implies
core processing done purely via kthreads.

>> +
>>  	/* The following fields are used by call_rcu, hence own cacheline. */
>>  	raw_spinlock_t nocb_bypass_lock ____cacheline_internodealigned_in_smp;
>>  	struct rcu_cblist nocb_bypass;	/* Lock-contention-bypass CB list. */
>> @@ -445,6 +447,8 @@ static void rcu_nocb_unlock(struct rcu_data *rdp);
>>  static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
>>  				       unsigned long flags);
>>  static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp);
>> +static void rcu_nocb_local_lock(struct rcu_data *rdp);
>> +static void rcu_nocb_local_unlock(struct rcu_data *rdp);
>>  #ifdef CONFIG_RCU_NOCB_CPU
>>  static void __init rcu_organize_nocb_kthreads(void);
>>  #define rcu_nocb_lock_irqsave(rdp, flags)				\
>> diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
>> index 0ff5e4fb933e..11c4ff00afde 100644
>> --- a/kernel/rcu/tree_plugin.h
>> +++ b/kernel/rcu/tree_plugin.h
>> @@ -21,6 +21,17 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
>>  	return lockdep_is_held(&rdp->nocb_lock);
>>  }
>>  
>> +static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
>> +{
>> +	return lockdep_is_held(
>> +#ifdef CONFIG_PREEMPT_RT
>> +		&rdp->nocb_local_lock.lock
>> +#else
>> +		&rdp->nocb_local_lock
>> +#endif
>
> It would be good if this was abstracted.  Or is this the only place
> in the kernel that needs this #ifdef?  Maybe a lockdep_is_held_rt()
> or lockdep_is_held_local(), as the case may be?
>

It does look like the first/only place that tries to access a local_lock's
dep_map regardless of CONFIG_PREEMPT_RT. Looking at it some more, I'm not
sure if it's really useful: !PREEMPT_RT local_locks disable preemption, so
the preemption check in rcu_rdp_is_offloaded() will short circuit the
lockdep check when !PREEMPT_RT...

One thing I should perhaps point out - the local lock is only really needed
for PREEMPT_RT; for !PREEMPT_RT it will just disable preemption, and it's
only used in places that *already* disabled preemption (when !PREEMPT_RT).
I initially gated the lock under CONFIG_PREEMPT_RT, but changed that as I
found it reduced the ifdeffery.

>> +	);
>> +}
>> +
>>  static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
>>  {
>>  	/* Race on early boot between thread creation and assignment */
>> @@ -38,7 +49,10 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
>>  {
>>  	return 0;
>>  }
>> -
>> +static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
>> +{
>> +	return 0;
>
> This is backwards of normal lockdep practice, which defaults to locks
> always held.  And that will be what happens once lockdep has detected
> its first deadlock, correct?  At which point, this function and its
> earlier instance will be in conflict.
>
> Or is there some subtle reason why this conflict would be OK?
>

This follows the !CONFIG_RCU_NOCB definition of rcu_lockdep_is_held_nocb(),
which looked fine to me.

Actually with the way I wrote rcu_local_offload_access_safe(), we don't
even access that function when !CONFIG_RCU_NOCB...

>> +}
>>  static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
>>  {
>>  	return false;
>> @@ -46,23 +60,44 @@ static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
>>  
>>  #endif /* #ifdef CONFIG_RCU_NOCB_CPU */
>>  
>> +/*
>> + * Is a local read of the rdp's offloaded state safe and stable?
>> + * See rcu_nocb_local_lock() & family.
>> + */
>> +static inline bool rcu_local_offload_access_safe(struct rcu_data *rdp)
>> +{
>> +	if (!preemptible())
>> +		return true;
>> +
>> +	if (!migratable()) {
>> +		if (!IS_ENABLED(CONFIG_RCU_NOCB))
>
> Do we also need to consult the use_softirq module parameter that controls
> whether or not there are rcuc kthreads?
>
> Actually, if !IS_ENABLED(CONFIG_RCU_NOCB) then rcu_rdp_is_offloaded()
> can simply return false without bothering with the RCU_LOCKDEP_WARN().
> Might be worth getting that out of the way of the RCU_LOCKDEP_WARN()
> condition.  ;-)
>

I _assumed_ the check was there even for !CONFIG_RCU_NOCB to provide a wider
test coverage of the calling conditions.

If that RCU_LOCKDEP_WARN() becomes conditionnal on CONFIG_RCU_NOCB then
yes, we could clean that up.

>> +			return true;
>> +
>> +		return rcu_lockdep_is_held_nocb_local(rdp);
>> +	}
>> +
>> +	return false;
>> +}
>> +


From robh at kernel.org  Fri Aug 13 11:54:50 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:54:50 -0500
Subject: [PATCH v3 1/7] dt-bindings: power: add rk3568-pmu-io-domain
 support
In-Reply-To: <20210805120107.27007-2-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
 <20210805120107.27007-2-michael.riesch@wolfvision.net>
Message-ID: <YRa/+rrW3ciW/tJf@robh.at.kernel.org>

On Thu, 05 Aug 2021 14:01:01 +0200, Michael Riesch wrote:
> Add binding for the RK3568 along a SoC-specific description of
> voltage supplies.
> 
> Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
> [add soc-specific section]
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
> v3:
> - add missing compatible for the rk3568 to grf.yaml
> 
>  .../bindings/power/rockchip-io-domain.yaml    | 30 +++++++++++++++++++
>  .../devicetree/bindings/soc/rockchip/grf.yaml |  1 +
>  2 files changed, 31 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Fri Aug 13 11:55:18 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:55:18 -0500
Subject: [PATCH 2/7] dt-bindings: add vendor prefix for exegin
In-Reply-To: <20210805155357.594414-3-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
 <20210805155357.594414-3-claudiu.beznea@microchip.com>
Message-ID: <YRbAFrGzKv9s0mKe@robh.at.kernel.org>

On Thu, 05 Aug 2021 18:53:52 +0300, Claudiu Beznea wrote:
> Add vendor prefix for Exegin Technologies Limited.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

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


From robh at kernel.org  Fri Aug 13 11:55:53 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:55:53 -0500
Subject: [PATCH 3/7] dt-bindings: ARM: at91: document exegin q5xr5 board
In-Reply-To: <20210805155357.594414-4-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
 <20210805155357.594414-4-claudiu.beznea@microchip.com>
Message-ID: <YRbAOYoRoMCtxuGL@robh.at.kernel.org>

On Thu, 05 Aug 2021 18:53:53 +0300, Claudiu Beznea wrote:
> Document Exegin Q5xR5 board.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

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


From robh at kernel.org  Fri Aug 13 11:56:14 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:56:14 -0500
Subject: [PATCH 5/7] dt-bindings: add vendor prefix for calamp
In-Reply-To: <20210805155357.594414-6-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
 <20210805155357.594414-6-claudiu.beznea@microchip.com>
Message-ID: <YRbAThIgS8qPi9UP@robh.at.kernel.org>

On Thu, 05 Aug 2021 18:53:55 +0300, Claudiu Beznea wrote:
> Add vendor prefix for CalAmp Corp.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

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


From lkp at intel.com  Fri Aug 13 11:57:08 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 14 Aug 2021 02:57:08 +0800
Subject: [soc:arm/drivers] BUILD SUCCESS
 1bb24be00c8c360e5e3072301d5f49eac86b384f
Message-ID: <6116c084.c36P1VdUX/5FZn3W%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/drivers
branch HEAD: 1bb24be00c8c360e5e3072301d5f49eac86b384f  Merge tag 'scmi-updates-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/drivers

elapsed time: 725m

configs tested: 131
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210813
arm                         lpc18xx_defconfig
arm                           spitz_defconfig
arm                           tegra_defconfig
arm                          badge4_defconfig
powerpc                 mpc836x_rdk_defconfig
mips                  maltasmvp_eva_defconfig
sh                            hp6xx_defconfig
arm                         shannon_defconfig
arm                        clps711x_defconfig
powerpc                      ppc64e_defconfig
sh                              ul2_defconfig
arm                         orion5x_defconfig
riscv                    nommu_k210_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                          ep93xx_defconfig
arc                              alldefconfig
powerpc                 mpc85xx_cds_defconfig
arc                     haps_hs_smp_defconfig
arm                       imx_v6_v7_defconfig
sh                           se7712_defconfig
powerpc                   microwatt_defconfig
powerpc                    amigaone_defconfig
arm                         s5pv210_defconfig
arm                           viper_defconfig
sh                          lboxre2_defconfig
sh                          urquell_defconfig
microblaze                      mmu_defconfig
arm                         nhk8815_defconfig
sh                ecovec24-romimage_defconfig
sh                   sh7770_generic_defconfig
x86_64                            allnoconfig
mips                             allyesconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a011-20210813
x86_64               randconfig-a013-20210813
x86_64               randconfig-a012-20210813
x86_64               randconfig-a016-20210813
x86_64               randconfig-a015-20210813
x86_64               randconfig-a014-20210813
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210813
x86_64               randconfig-c001-20210812
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From robh at kernel.org  Fri Aug 13 11:57:37 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:57:37 -0500
Subject: [PATCH 6/7] dt-bindings: ARM: at91: document CalAmp LMU5000 board
In-Reply-To: <20210805155357.594414-7-claudiu.beznea@microchip.com>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
 <20210805155357.594414-7-claudiu.beznea@microchip.com>
Message-ID: <YRbAocukLCTrlRVE@robh.at.kernel.org>

On Thu, Aug 05, 2021 at 06:53:56PM +0300, Claudiu Beznea wrote:
> Document CalAmp LMU5000.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> index a9ab18510fef..08efb259a947 100644
> --- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> +++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> @@ -132,6 +132,12 @@ properties:
>            - const: atmel,at91sam9g20
>            - const: atmel,at91sam9
>  
> +      - description: Exegin Q5xR5 board
> +        items:
> +          - const: exegin,q5xr5

You've got your commit msg and diff swapped.

> +          - const: atmel,at91sam9g20
> +          - const: atmel,at91sam9
> +
>        - items:
>            - enum:
>                - atmel,sama5d31
> -- 
> 2.25.1
> 
> 


From robh at kernel.org  Fri Aug 13 11:58:05 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 13:58:05 -0500
Subject: [PATCH 3/7] dt-bindings: ARM: at91: document exegin q5xr5 board
In-Reply-To: <YRbAOYoRoMCtxuGL@robh.at.kernel.org>
References: <20210805155357.594414-1-claudiu.beznea@microchip.com>
 <20210805155357.594414-4-claudiu.beznea@microchip.com>
 <YRbAOYoRoMCtxuGL@robh.at.kernel.org>
Message-ID: <YRbAvRPdU3qdwkPi@robh.at.kernel.org>

On Fri, Aug 13, 2021 at 01:55:53PM -0500, Rob Herring wrote:
> On Thu, 05 Aug 2021 18:53:53 +0300, Claudiu Beznea wrote:
> > Document Exegin Q5xR5 board.
> > 
> > Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> > ---
> >  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> 
> Acked-by: Rob Herring <robh at kernel.org>

I take that back...


From robh at kernel.org  Fri Aug 13 12:01:49 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 14:01:49 -0500
Subject: [PATCH V2 2/3] dt-bindings: gpio: zynqmp: Add binding
 documentation for modepin
In-Reply-To: <20210805174219.3000667-3-piyush.mehta@xilinx.com>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-3-piyush.mehta@xilinx.com>
Message-ID: <YRbBnRS0VosXcZWz@robh.at.kernel.org>

On Thu, Aug 05, 2021 at 11:12:18PM +0530, Piyush Mehta wrote:
> This patch adds DT binding document for zynqmp modepin GPIO controller.
> Modepin GPIO controller has four GPIO pins which can be configurable
> as input or output.
> 
> Modepin driver is a bridge between the peripheral driver and GPIO pins.
> It has set and get APIs for accessing GPIO pins, based on the device-tree
> entry of reset-gpio property in the peripheral driver, every pin can be
> configured as input/output and trigger GPIO pin.
> 
> For more information please refer zynqMp TRM link:
> Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
> Chapter 2: Signals, Interfaces, and Pins
> Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE
> 
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> ---
> Changes in v2:
> - Addressed review comments: Update commit message
> 
> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736
> ---
>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
> 
> diff --git a/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
> new file mode 100644
> index 0000000..39d78f8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
> @@ -0,0 +1,41 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: ZynqMP Mode Pin GPIO controller
> +
> +description:
> +  PS_MODE is 4-bits boot mode pins sampled on POR deassertion. Mode Pin
> +  GPIO controller with configurable from numbers of pins (from 0 to 3 per
> +  PS_MODE). Every pin can be configured as input/output.
> +
> +maintainers:
> +  - Piyush Mehta <piyush.mehta at xilinx.com>
> +
> +properties:
> +  compatible:
> +    const: xlnx,zynqmp-gpio-modepin
> +
> +  gpio-controller: true
> +
> +  "#gpio-cells":
> +    const: 2
> +
> +required:
> +  - compatible
> +  - gpio-controller
> +  - "#gpio-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    modepin_gpio: gpio {
> +        compatible = "xlnx,zynqmp-gpio-modepin";
> +        gpio-controller;
> +        #gpio-cells = <2>;

No way to interact with this h/w?

As it is part of the firmware interface, it must be a child node in the 
firmware node schema.

> +    };
> +
> +...
> -- 
> 2.7.4
> 
> 


From robh at kernel.org  Fri Aug 13 12:08:36 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 14:08:36 -0500
Subject: [PATCH] arm64: dts: synaptics: remove unused DTSI for AS370
In-Reply-To: <20210806082635.20239-1-krzysztof.kozlowski@canonical.com>
References: <20210806082635.20239-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YRbDNInfG7caSr2r@robh.at.kernel.org>

On Fri, 06 Aug 2021 10:26:35 +0200, Krzysztof Kozlowski wrote:
> The as370.dtsi for Synaptics AS370 SoC does not have a user (DTS board
> file), is uncompilable and untestable.  It was added back in 2018.  No
> user appeared since that time, so assume it won't be added.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/arm/syna.txt          |   4 -
>  arch/arm64/boot/dts/synaptics/as370.dtsi      | 173 ------------------
>  2 files changed, 177 deletions(-)
>  delete mode 100644 arch/arm64/boot/dts/synaptics/as370.dtsi
> 

I assume Arnd/Olof will take this.

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


From linux.amoon at gmail.com  Fri Aug 13 12:35:40 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Sat, 14 Aug 2021 01:05:40 +0530
Subject: [PATCHv2 1/4] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <CANAwSgS2vi7hZqX0LWxNTvk-3aN=n1fEErj4Zt0_4CCpZGyRkg@mail.gmail.com>
References: <20210716103651.1455-1-linux.amoon@gmail.com>
 <20210716103651.1455-2-linux.amoon@gmail.com>
 <CAFBinCDeqauw_V-Vn9cat9HaCXj6HEMz6G+G+VbqCNtGEFGYzg@mail.gmail.com>
 <CANAwSgQ5PDGUWMH-jxnz5wwutUVniTn7RAe=4J=8-jbmqxYRRg@mail.gmail.com>
 <CAFBinCBhg+dije+3DvV_V_kqHv9q+r4EPxXCYFti6KuA4mK7KQ@mail.gmail.com>
 <CANAwSgT9-5zGr67aGzBmW6WDBfeiAvjv_zv2UbRC+YbgAGg==A@mail.gmail.com>
 <CAFBinCCGA0b=LVjbQood+iN+DHLodY0RJ-GrSOcgdzrDFJ25pQ@mail.gmail.com>
 <CAFBinCAohjxcsY3D1rdAiYVGL+==cnjzZxg1GmYxSNVhxSTDoA@mail.gmail.com>
 <CAFBinCAP_DDvPLn4h1yQKEdU_x1ovokHUTPeq3vNV_sDF8PcWg@mail.gmail.com>
 <CANAwSgS2vi7hZqX0LWxNTvk-3aN=n1fEErj4Zt0_4CCpZGyRkg@mail.gmail.com>
Message-ID: <CANAwSgTw-aY16NOcQhgPcN+Tkz-OXdioDEAM2q0OPhvbf2TwaQ@mail.gmail.com>

Hi Martin,

On Thu, 5 Aug 2021 at 23:48, Anand Moon <linux.amoon at gmail.com> wrote:
>
> Hi Martin,
>
> On Thu, 5 Aug 2021 at 03:28, Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
> >
> > On Sun, Jul 18, 2021 at 9:09 PM Martin Blumenstingl
> > <martin.blumenstingl at googlemail.com> wrote:
> > >
> > > Hi Anand,
> > >
> > > On Sun, Jul 18, 2021 at 4:01 PM Martin Blumenstingl
> > > <martin.blumenstingl at googlemail.com> wrote:
> > > [...]
> > > > > From the schematics [1]
> > > > > https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20160226.pdf
> > > > >
> > > > > You could find references to PWREN  <--- GPIOAO.BIT5
> > > > > The second reference is USB HOST Power Switch
> > > > > The third reference is USB HOST POWER.
> > > > >
> > > > > Hope I am clean in my thought process now.
> > > > Can you please point out the page numbers for me?
> > > >
> > > > What I am seeing on page 1 is:
> > > > GPIOAO_5 (called GPIOAO.BIT5) is connected as an INPUT to the USB_OTG
> > > > PWREN signal (that's the green box with the label "USB_OTG.SchDoc"
> > > > above it).
> > > I unfortunately missed your question on IRC on this topic:
> > > <armoon> xdarklight: just want to understand the confusion on PWREN,
> > > either is INPUT / OTPUT to usb hub am I correct
> > > My understanding of the INPUT/OUTPUT direction in the Odroid-C1
> > > schematics (which you linked) above is that the arrow direction shows
> > > whether it's an input or output.
> > > For example (all on page one):
> > > - HDMI_HPD is an input to the Meson8b SoC, arrow direction is: HDMI => S805
> > > - IR_IN is an input to the Meson8b SoC, arrow direction is: S805 <=
> > > GPIOAO.BIT7 IR_IN
> > > - PWM is an output, arrow direction is: S805 => PWM.C VCCK_PWM
> > > - 3.3V/1.8V switch for the SD card is an output, arrow direction is:
> > > S805 => GPIOAO.BIT3 TF_3V3N_1V8_EN
> > >
> > > That tells me: the arrow direction shows which connections are inputs
> > > or outputs.
> > > Some pins can be input and output at the same time (HDMI_CEC). But
> > > let's keep it simple for now any only look at inputs/output.
> > >
> > > Based on this information I am looking at the arrow direction for
> > > USB_OTG: GPIOAO.BIT5 PWREN <= S805
> > > So this confirms that GPIOAO_5 is an output to the SoC.
> > > Please note though that this part is not linked with any USB host
> > > connector, it's only linked to the USB OTG path.
> > >
> > > For the next part the S805 SoC is not involved:
> > > USB1 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> > > USB2 USB_HOST_PWR_SW PWREN <= PWREN USB_HUB_GL852G
> > > This tells me that the PWREN signal for the two USB_HOST_PWR_SW (USB
> > > host power switches / current limiters) is driven by the GL852G USB
> > > hub.
> > Hardkernel team responded on the Odroid forums to the request from Anand:
> > "Power-Enable signal to the USB load switch ICs is connected to the
> > USB hub controller.
> > It is not connected the CPU GPIO."
> >
> > The regulator from Anand's patch is therefore connected to the micro USB port.
> > This means that the patch needs updating in case Anand wants to have
> > it included.
> >
>
> Yes, I will send a corrected version of the patches soon.

I have a small query regarding GPIO polarity

As per the datasheet of *MP62551DGT-LF-Z*
[0] https://www.mouser.in/datasheet/2/277/MP62550-1384050.pdf

USB power enables EN signal need to be Active High.

PIN Fucntion > Enable input. Active Low: (MP62550), Active High: (MP62551).

So the correct option in dts
+               /*
+                * signal name from schematics: PWREN - GPIOAO.BIT5
+                */
+               gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;

which gives me the below output.

$  sudo cat /sys/kernel/debug/gpio | grep USB
 gpio-1953 (USB_HUB_RST_N       |usb-hub-reset       ) out hi
 gpio-1954 (USB_OTG_PWREN       |regulator-usb-pwr-en) out hi

Please clear this small query so that I can send the update patch.

Thanks
-Anand

>
> >
> > Best regards,
> > Martin
> >
> >
> > [0] https://forum.odroid.com/viewtopic.php?p=332217#p332217
>
> Thanks
> -Anand


From Thinh.Nguyen at synopsys.com  Fri Aug 13 12:52:03 2021
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Fri, 13 Aug 2021 19:52:03 +0000
Subject: [PATCH v2 4/6] usb: dwc3: reference clock period configuration
In-Reply-To: <YRarmizUtzIunV1P@robh.at.kernel.org>
References: <3d86f45004fe2fcbae0a2cd197df81a1fd076a1e.1628085910.git.baruch@tkos.co.il>
 <0e99e3d453547ad2a8f4541090a03f3c80b80332.1628085910.git.baruch@tkos.co.il>
 <87lf5h5mc2.fsf@kernel.org> <87v94lxpb0.fsf@tarshish>
 <YRarmizUtzIunV1P@robh.at.kernel.org>
Message-ID: <53784e58-6da4-ad61-6b9e-46697fb3d695@synopsys.com>

Rob Herring wrote:
> On Wed, Aug 04, 2021 at 05:22:27PM +0300, Baruch Siach wrote:
>> Hi Felipe,
>>
>> On Wed, Aug 04 2021, Felipe Balbi wrote:
>>> Baruch Siach <baruch at tkos.co.il> writes:
>>>> @@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>>>>  				    &dwc->hsphy_interface);
>>>>  	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
>>>>  				 &dwc->fladj);
>>>> +	device_property_read_u32(dev, "snps,ref-clock-period",
>>>> +				 &dwc->ref_clk_per);
>>>
>>> I wonder if it would make more sense to pass an actual clock reference
>>> here. If valid, then reconfigure the period to the value returned by
>>> clk_get_rate(). It would avoid yet another DT binding. If we make the
>>> clock optional, then we won't affect any other platforms. The clock
>>> itself could be a regular fixed clock node.
>>
>> Thinh Nguyen asked to add a dedicated DT property. He explained that
>> clk_get_rate() does not work for PCI hosted dwc3. This is the most
>> complete summary of the discussion:
>>
>>   https://urldefense.com/v3/__https://lore.kernel.org/r/c797e9cb-cae6-c0b6-5714-169c2ad79d32 at synopsys.com__;!!A4F2R9G_pg!Nh6rqp_aOd8XIvqELvDRQe5ooZf13UZKwmn9lWcRgdbyMKpTMzL8HasrB1X2Ojvumo8g$ 
> 
> PCI devices can have DT nodes with clock properties too. Or use the 
> VID/PID to infer the frequency. Or use 'clock-frequency' property.
> 
> It boils down to we have lots of standard properties for clocks and 
> clock configuration, so custom properties are a NAK.
> 

Do we have DT node for the PCI device before discovering the device from
PCI bus enumeration? I don't think we can find the clock properties from
its configuration space. For our HAPS devices, we can't use VID/PID to
infer the frequency since our phy and ref clock may change.

Does "clock-frequency" mean ref clock? If so, let's use that?

Thanks,
Thinh

From mka at chromium.org  Fri Aug 13 12:52:25 2021
From: mka at chromium.org (Matthias Kaehlcke)
Date: Fri, 13 Aug 2021 12:52:25 -0700
Subject: [PATCH v16 4/7] arm64: defconfig: Explicitly enable USB_XHCI_PLATFORM
In-Reply-To: <20210813195228.2003500-1-mka@chromium.org>
References: <20210813195228.2003500-1-mka@chromium.org>
Message-ID: <20210813125146.v16.4.Id45138610b749ff775186ac10b3d01c504ddf4f3@changeid>

The dependency of USB_DWC3 on USB_XHCI_PLATFORM is being changed
from 'select' to 'depends on' by another patch. The defconfig selects
USB_DWC3 and implicitly USB_DWC3_DUAL_ROLE, to keep this unchanged
USB_XHCI_PLATFORM now needs to be selected explicitly.

Signed-off-by: Matthias Kaehlcke <mka at chromium.org>
Reviewed-by: Douglas Anderson <dianders at chromium.org>
---

Changes in v16:
- none

Changes in v15:
- none

Changes in v14:
- rebased on v5.14-rc1 (with the rest of the series)
- added 'Reviewed-by' tag from Doug

Changes in v13:
- patch added to the series

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f423d08b9a71..b243bd11a4ed 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -802,6 +802,7 @@ CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_PCI=m
 CONFIG_USB_XHCI_PCI_RENESAS=m
+CONFIG_USB_XHCI_PLATFORM=y
 CONFIG_USB_XHCI_TEGRA=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_EXYNOS=y
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From mka at chromium.org  Fri Aug 13 12:52:26 2021
From: mka at chromium.org (Matthias Kaehlcke)
Date: Fri, 13 Aug 2021 12:52:26 -0700
Subject: [PATCH v16 5/7] usb: Specify dependencies on USB_XHCI_PLATFORM with
 'depends on'
In-Reply-To: <20210813195228.2003500-1-mka@chromium.org>
References: <20210813195228.2003500-1-mka@chromium.org>
Message-ID: <20210813125146.v16.5.If248f05613bbb06a44eb0b0909be5d97218f417b@changeid>

Some USB controller drivers that depend on the xhci-plat driver
specify this dependency using 'select' in Kconfig. This is not
recommended for symbols that have other dependencies as it may
lead to invalid configurations. Use 'depends on' to specify the
dependency instead of 'select'.

For dwc3 specify the dependency on USB_XHCI_PLATFORM in
USB_DWC3_HOST and USB_DWC3_DUAL_ROLE. Also adjust the
dependencies of USB_DWC3_CORE to make sure that at least one
of USB_DWC3_HOST, USB_DWC3_GADGET or USB_DWC3_DUAL_ROLE can be
selected.

Signed-off-by: Matthias Kaehlcke <mka at chromium.org>
---

Changes in v16:
- none

Changes in v15:
- adjusted dependencies of USB_DWC3_CORE to make sure it can only
  be enabled when at least one of USB_DWC3_HOST, USB_DWC3_GADGET
  or USB_DWC3_DUAL_ROLE is selectable
- updated commit message

Changes in v14:
- none

Changes in v13:
- patch added to the series

 drivers/usb/cdns3/Kconfig | 2 +-
 drivers/usb/dwc3/Kconfig  | 5 +++--
 drivers/usb/host/Kconfig  | 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig
index b98ca0a1352a..07e12f786d48 100644
--- a/drivers/usb/cdns3/Kconfig
+++ b/drivers/usb/cdns3/Kconfig
@@ -1,7 +1,7 @@
 config USB_CDNS_SUPPORT
 	tristate "Cadence USB Support"
 	depends on USB_SUPPORT && (USB || USB_GADGET) && HAS_DMA
-	select USB_XHCI_PLATFORM if USB_XHCI_HCD
+	depends on !USB_XHCI_HCD || USB_XHCI_PLATFORM
 	select USB_ROLE_SWITCH
 	help
 	  Say Y here if your system has a Cadence USBSS or USBSSP
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
index 66b1454c4db2..870f2251350a 100644
--- a/drivers/usb/dwc3/Kconfig
+++ b/drivers/usb/dwc3/Kconfig
@@ -2,8 +2,7 @@
 
 config USB_DWC3
 	tristate "DesignWare USB3 DRD Core Support"
-	depends on (USB || USB_GADGET) && HAS_DMA
-	select USB_XHCI_PLATFORM if USB_XHCI_HCD
+	depends on ((USB && USB_XHCI_PLATFORM) || USB_GADGET) && HAS_DMA
 	select USB_ROLE_SWITCH if USB_DWC3_DUAL_ROLE
 	help
 	  Say Y or M here if your system has a Dual Role SuperSpeed
@@ -30,6 +29,7 @@ choice
 config USB_DWC3_HOST
 	bool "Host only mode"
 	depends on USB=y || USB=USB_DWC3
+	depends on USB_XHCI_PLATFORM
 	help
 	  Select this when you want to use DWC3 in host mode only,
 	  thereby the gadget feature will be regressed.
@@ -44,6 +44,7 @@ config USB_DWC3_GADGET
 config USB_DWC3_DUAL_ROLE
 	bool "Dual Role mode"
 	depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3))
+	depends on USB_XHCI_PLATFORM
 	depends on (EXTCON=y || EXTCON=USB_DWC3)
 	help
 	  This is the default mode of working of DWC3 controller where
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index df9428f1dc5e..518c2312ef0c 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -80,7 +80,7 @@ config USB_XHCI_MTK
 
 config USB_XHCI_MVEBU
 	tristate "xHCI support for Marvell Armada 375/38x/37xx"
-	select USB_XHCI_PLATFORM
+	depends on USB_XHCI_PLATFORM
 	depends on HAS_IOMEM
 	depends on ARCH_MVEBU || COMPILE_TEST
 	help
@@ -112,9 +112,9 @@ config USB_EHCI_BRCMSTB
 config USB_BRCMSTB
 	tristate "Broadcom STB USB support"
 	depends on (ARCH_BRCMSTB && PHY_BRCM_USB) || COMPILE_TEST
+	depends on !USB_XHCI_HCD || USB_XHCI_PLATFORM
 	select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
 	select USB_EHCI_BRCMSTB if USB_EHCI_HCD
-	select USB_XHCI_PLATFORM if USB_XHCI_HCD
 	help
 	  Enables support for XHCI, EHCI and OHCI host controllers
 	  found in Broadcom STB SoC's.
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From robh at kernel.org  Fri Aug 13 13:09:23 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 15:09:23 -0500
Subject: [PATCH v3 2/2] arm64: zynqmp: Add support for Xilinx Kria SOM
 board
In-Reply-To: <e780a2fef00e78c44c21cf3b918631bf20262688.1628244703.git.michal.simek@xilinx.com>
References: <cover.1628244703.git.michal.simek@xilinx.com>
 <e780a2fef00e78c44c21cf3b918631bf20262688.1628244703.git.michal.simek@xilinx.com>
Message-ID: <YRbRcx0b+V0vAgA4@robh.at.kernel.org>

On Fri, Aug 06, 2021 at 12:12:08PM +0200, Michal Simek wrote:
> There are couple of revisions of SOMs (k26) and associated carrier cards
> (kv260).
> SOM itself has two major versions:
> sm-k26 - SOM with EMMC
> smk-k26 - SOM without EMMC used on starter kit with preprogrammed firmware
> in QSPI.
> 
> SOMs are describing only devices available on the SOM or connections which
> are described in specification (for example UART, fwuen).
> 
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
> 
> Changes in v3:
> - Fix led node name
> - Fix compatible string for xlnx,zynqmp-sk-kv260-revA/Y/Z
> - Fix headers alignment
> - Move USB3 PHY properties from DWC3 node to USB node - reported by Manish
>   Narani
> - Change dtb names generated with dtbo
> - Fix emmc comment style
> -
> 
> Changes in v2:
> - Use sugar syntax - reported by Geert
> - Update copyright years
> - Fix SD3.0 comment alignment
> - Remove one newline from Makefile
> 
> https://www.xilinx.com/products/som/kria.html
> ---
>  .../devicetree/bindings/arm/xilinx.yaml       |  31 ++
>  arch/arm64/boot/dts/xilinx/Makefile           |  13 +
>  .../boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts  | 335 ++++++++++++++++++
>  .../boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts  | 318 +++++++++++++++++
>  .../boot/dts/xilinx/zynqmp-sm-k26-revA.dts    | 289 +++++++++++++++
>  .../boot/dts/xilinx/zynqmp-smk-k26-revA.dts   |  21 ++
>  6 files changed, 1007 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
> 
> diff --git a/Documentation/devicetree/bindings/arm/xilinx.yaml b/Documentation/devicetree/bindings/arm/xilinx.yaml
> index a0b1ae6e3e71..31b86a6363b8 100644
> --- a/Documentation/devicetree/bindings/arm/xilinx.yaml
> +++ b/Documentation/devicetree/bindings/arm/xilinx.yaml
> @@ -116,6 +116,37 @@ properties:
>            - const: xlnx,zynqmp-zcu111
>            - const: xlnx,zynqmp
>  
> +      - description: Xilinx Kria SOMs
> +        items:
> +          - const: xlnx,zynqmp-sm-k26-rev1
> +          - const: xlnx,zynqmp-sm-k26-revB
> +          - const: xlnx,zynqmp-sm-k26-revA
> +          - const: xlnx,zynqmp-sm-k26

How is having all 4 strings useful? Seems like it should be only 1 of 
the rev's at a time.

> +          - const: xlnx,zynqmp
> +
> +      - description: Xilinx Kria SOMs (starter)
> +        items:
> +          - const: xlnx,zynqmp-smk-k26-rev1
> +          - const: xlnx,zynqmp-smk-k26-revB
> +          - const: xlnx,zynqmp-smk-k26-revA
> +          - const: xlnx,zynqmp-smk-k26
> +          - const: xlnx,zynqmp
> +
> +      - description: Xilinx Kria Carrier Cards (revA/Y/Z)
> +        items:
> +          - const: xlnx,zynqmp-sk-kv260-revA
> +          - const: xlnx,zynqmp-sk-kv260-revY
> +          - const: xlnx,zynqmp-sk-kv260-revZ
> +          - const: xlnx,zynqmp-sk-k260
> +          - const: xlnx,zynqmp
> +
> +      - description: Xilinx Kria Carrier Cards (rev1/B)
> +        items:
> +          - const: xlnx,zynqmp-sk-kv260-rev1
> +          - const: xlnx,zynqmp-sk-kv260-revB
> +          - const: xlnx,zynqmp-sk-k260
> +          - const: xlnx,zynqmp
> +
>  additionalProperties: true
>  
>  ...
> diff --git a/arch/arm64/boot/dts/xilinx/Makefile b/arch/arm64/boot/dts/xilinx/Makefile
> index 083ed52337fd..4e159540d031 100644
> --- a/arch/arm64/boot/dts/xilinx/Makefile
> +++ b/arch/arm64/boot/dts/xilinx/Makefile
> @@ -17,3 +17,16 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu104-revA.dtb
>  dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu104-revC.dtb
>  dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu106-revA.dtb
>  dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-zcu111-revA.dtb
> +
> +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA.dtb
> +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA.dtb
> +
> +sm-k26-revA-sck-kv-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo
> +sm-k26-revA-sck-kv-g-revB-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo
> +smk-k26-revA-sm-k26-revA-sck-kv-g-revA-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo
> +smk-k26-revA-sm-k26-revA-sck-kv-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo
> +
> +dtb-$(CONFIG_ARCH_ZYNQMP) += sm-k26-revA-sck-kv-g-revA.dtb
> +dtb-$(CONFIG_ARCH_ZYNQMP) += sm-k26-revA-sck-kv-g-revB.dtb
> +dtb-$(CONFIG_ARCH_ZYNQMP) += smk-k26-revA-sm-k26-revA-sck-kv-g-revA.dtb
> +dtb-$(CONFIG_ARCH_ZYNQMP) += smk-k26-revA-sm-k26-revA-sck-kv-g-revB.dtb
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
> new file mode 100644
> index 000000000000..22602d8c33f8
> --- /dev/null
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
> @@ -0,0 +1,335 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * dts file for KV260 revA Carrier Card
> + *
> + * (C) Copyright 2020 - 2021, Xilinx, Inc.
> + *
> + * SD level shifter:
> + * "A" ? A01 board un-modified (NXP)
> + * "Y" ? A01 board modified with legacy interposer (Nexperia)
> + * "Z" ? A01 board modified with Diode interposer
> + *
> + * Michal Simek <michal.simek at xilinx.com>
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/net/ti-dp83867.h>
> +#include <dt-bindings/phy/phy.h>
> +#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
> +
> +/dts-v1/;
> +/plugin/;
> +
> +&{/} {
> +	compatible = "xlnx,zynqmp-sk-kv260-revA",
> +		     "xlnx,zynqmp-sk-kv260-revY",
> +		     "xlnx,zynqmp-sk-kv260-revZ",
> +		     "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp";
> +};
> +
> +&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&pinctrl_i2c1_default>;
> +	pinctrl-1 = <&pinctrl_i2c1_gpio>;
> +	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
> +	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
> +
> +	u14: ina260 at 40 { /* u14 */
> +		compatible = "ti,ina260";
> +		#io-channel-cells = <1>;
> +		label = "ina260-u14";
> +		reg = <0x40>;
> +	};
> +	/* u27 - 0xe0 - STDP4320 DP/HDMI splitter */
> +};
> +
> +&amba {
> +	ina260-u14 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&u14 0>, <&u14 1>, <&u14 2>;
> +	};
> +
> +	si5332_0: si5332_0 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <125000000>;
> +	};
> +
> +	si5332_1: si5332_1 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <25000000>;
> +	};
> +
> +	si5332_2: si5332_2 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <48000000>;
> +	};
> +
> +	si5332_3: si5332_3 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <24000000>;
> +	};
> +
> +	si5332_4: si5332_4 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <26000000>;
> +	};
> +
> +	si5332_5: si5332_5 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <27000000>;
> +	};
> +};
> +
> +/* DP/USB 3.0 and SATA */
> +&psgtr {
> +	status = "okay";
> +	/* pcie, usb3, sata */
> +	clocks = <&si5332_5>, <&si5332_4>, <&si5332_0>;
> +	clock-names = "ref0", "ref1", "ref2";
> +};
> +
> +&sata {
> +	status = "okay";
> +	/* SATA OOB timing settings */
> +	ceva,p0-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
> +	ceva,p0-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
> +	ceva,p0-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
> +	ceva,p0-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
> +	ceva,p1-cominit-params = /bits/ 8 <0x18 0x40 0x18 0x28>;
> +	ceva,p1-comwake-params = /bits/ 8 <0x06 0x14 0x08 0x0E>;
> +	ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
> +	ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
> +	phy-names = "sata-phy";
> +	phys = <&psgtr 3 PHY_TYPE_SATA 1 2>;
> +};
> +
> +&zynqmp_dpsub {
> +	status = "disabled";
> +	phy-names = "dp-phy0", "dp-phy1";
> +	phys = <&psgtr 1 PHY_TYPE_DP 0 0>, <&psgtr 0 PHY_TYPE_DP 1 0>;
> +};
> +
> +&zynqmp_dpdma {
> +	status = "okay";
> +};
> +
> +&usb0 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_usb0_default>;
> +	phy-names = "usb3-phy";
> +	phys = <&psgtr 2 PHY_TYPE_USB3 0 1>;
> +	usbhub: usb5744 { /* u43 */
> +		compatible = "microchip,usb5744";
> +		reset-gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
> +	};
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "host";
> +	snps,usb3_lpm_capable;
> +	maximum-speed = "super-speed";
> +};
> +
> +&sdhci1 { /* on CC with tuned parameters */
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sdhci1_default>;
> +	/*
> +	 * SD 3.0 requires level shifter and this property
> +	 * should be removed if the board has level shifter and
> +	 * need to work in UHS mode
> +	 */
> +	no-1-8-v;
> +	disable-wp;
> +	xlnx,mio-bank = <1>;
> +};
> +
> +&gem3 { /* required by spec */
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_gem3_default>;
> +	phy-handle = <&phy0>;
> +	phy-mode = "rgmii-id";
> +
> +	mdio: mdio {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reset-gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
> +		reset-delay-us = <2>;
> +
> +		phy0: ethernet-phy at 1 {
> +			#phy-cells = <1>;
> +			reg = <1>;
> +			ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
> +			ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
> +			ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
> +			ti,dp83867-rxctrl-strap-quirk;
> +		};
> +	};
> +};
> +
> +&pinctrl0 { /* required by spec */
> +	status = "okay";
> +
> +	pinctrl_uart1_default: uart1-default {
> +		conf {
> +			groups = "uart1_9_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +			drive-strength = <12>;
> +		};
> +
> +		conf-rx {
> +			pins = "MIO37";
> +			bias-high-impedance;
> +		};
> +
> +		conf-tx {
> +			pins = "MIO36";
> +			bias-disable;
> +		};
> +
> +		mux {
> +			groups = "uart1_9_grp";
> +			function = "uart1";
> +		};
> +	};
> +
> +	pinctrl_i2c1_default: i2c1-default {
> +		conf {
> +			groups = "i2c1_6_grp";
> +			bias-pull-up;
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		mux {
> +			groups = "i2c1_6_grp";
> +			function = "i2c1";
> +		};
> +	};
> +
> +	pinctrl_i2c1_gpio: i2c1-gpio {
> +		conf {
> +			groups = "gpio0_24_grp", "gpio0_25_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		mux {
> +			groups = "gpio0_24_grp", "gpio0_25_grp";
> +			function = "gpio0";
> +		};
> +	};
> +
> +	pinctrl_gem3_default: gem3-default {
> +		conf {
> +			groups = "ethernet3_0_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		conf-rx {
> +			pins = "MIO70", "MIO72", "MIO74";
> +			bias-high-impedance;
> +			low-power-disable;
> +		};
> +
> +		conf-bootstrap {
> +			pins = "MIO71", "MIO73", "MIO75";
> +			bias-disable;
> +			low-power-disable;
> +		};
> +
> +		conf-tx {
> +			pins = "MIO64", "MIO65", "MIO66",
> +				"MIO67", "MIO68", "MIO69";
> +			bias-disable;
> +			low-power-enable;
> +		};
> +
> +		conf-mdio {
> +			groups = "mdio3_0_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +			bias-disable;
> +		};
> +
> +		mux-mdio {
> +			function = "mdio3";
> +			groups = "mdio3_0_grp";
> +		};
> +
> +		mux {
> +			function = "ethernet3";
> +			groups = "ethernet3_0_grp";
> +		};
> +	};
> +
> +	pinctrl_usb0_default: usb0-default {
> +		conf {
> +			groups = "usb0_0_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		conf-rx {
> +			pins = "MIO52", "MIO53", "MIO55";
> +			bias-high-impedance;
> +		};
> +
> +		conf-tx {
> +			pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59",
> +			"MIO60", "MIO61", "MIO62", "MIO63";
> +			bias-disable;
> +		};
> +
> +		mux {
> +			groups = "usb0_0_grp";
> +			function = "usb0";
> +		};
> +	};
> +
> +	pinctrl_sdhci1_default: sdhci1-default {
> +		conf {
> +			groups = "sdio1_0_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +			bias-disable;
> +		};
> +
> +		conf-cd {
> +			groups = "sdio1_cd_0_grp";
> +			bias-high-impedance;
> +			bias-pull-up;
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		mux-cd {
> +			groups = "sdio1_cd_0_grp";
> +			function = "sdio1_cd";
> +		};
> +
> +		mux {
> +			groups = "sdio1_0_grp";
> +			function = "sdio1";
> +		};
> +	};
> +};
> +
> +&uart1 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_uart1_default>;
> +};
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
> new file mode 100644
> index 000000000000..df054e152a77
> --- /dev/null
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
> @@ -0,0 +1,318 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * dts file for KV260 revA Carrier Card
> + *
> + * (C) Copyright 2020 - 2021, Xilinx, Inc.
> + *
> + * Michal Simek <michal.simek at xilinx.com>
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/net/ti-dp83867.h>
> +#include <dt-bindings/phy/phy.h>
> +#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
> +
> +/dts-v1/;
> +/plugin/;
> +
> +&{/} {
> +	compatible = "xlnx,zynqmp-sk-kv260-rev1",
> +		     "xlnx,zynqmp-sk-kv260-revB",
> +		     "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp";

I don't think changing the root compatible in an overlay is a good 
policy. Do you need this all to be overlays?

> +};
> +
> +&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	pinctrl-names = "default", "gpio";
> +	pinctrl-0 = <&pinctrl_i2c1_default>;
> +	pinctrl-1 = <&pinctrl_i2c1_gpio>;
> +	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
> +	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
> +
> +	u14: ina260 at 40 { /* u14 */
> +		compatible = "ti,ina260";

Not documented. Please run 'make dtbs_check' and don't add new warnings.

> +		#io-channel-cells = <1>;
> +		label = "ina260-u14";
> +		reg = <0x40>;
> +	};
> +	usbhub: usb5744 at 2d { /* u43 */
> +		compatible = "microchip,usb5744";

Not documented.

> +		reg = <0x2d>;
> +		reset-gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
> +	};
> +	/* u27 - 0xe0 - STDP4320 DP/HDMI splitter */
> +};
> +
> +&amba {
> +	ina260-u14 {
> +		compatible = "iio-hwmon";
> +		io-channels = <&u14 0>, <&u14 1>, <&u14 2>;
> +	};
> +
> +	si5332_0: si5332_0 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <125000000>;
> +	};
> +
> +	si5332_1: si5332_1 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <25000000>;
> +	};
> +
> +	si5332_2: si5332_2 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <48000000>;
> +	};
> +
> +	si5332_3: si5332_3 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <24000000>;
> +	};
> +
> +	si5332_4: si5332_4 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <26000000>;
> +	};
> +
> +	si5332_5: si5332_5 { /* u17 */
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <27000000>;
> +	};
> +};
> +
> +/* DP/USB 3.0 */
> +&psgtr {
> +	status = "okay";
> +	/* pcie, usb3, sata */
> +	clocks = <&si5332_5>, <&si5332_4>, <&si5332_0>;
> +	clock-names = "ref0", "ref1", "ref2";
> +};
> +
> +&zynqmp_dpsub {
> +	status = "disabled";
> +	phy-names = "dp-phy0", "dp-phy1";
> +	phys = <&psgtr 1 PHY_TYPE_DP 0 0>, <&psgtr 0 PHY_TYPE_DP 1 0>;
> +};
> +
> +&zynqmp_dpdma {
> +	status = "okay";
> +};
> +
> +&usb0 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_usb0_default>;
> +	phy-names = "usb3-phy";
> +	phys = <&psgtr 2 PHY_TYPE_USB3 0 1>;
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
> +	dr_mode = "host";
> +	snps,usb3_lpm_capable;
> +	maximum-speed = "super-speed";
> +};
> +
> +&sdhci1 { /* on CC with tuned parameters */
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sdhci1_default>;
> +	/*
> +	 * SD 3.0 requires level shifter and this property
> +	 * should be removed if the board has level shifter and
> +	 * need to work in UHS mode
> +	 */
> +	no-1-8-v;
> +	disable-wp;
> +	xlnx,mio-bank = <1>;
> +	clk-phase-sd-hs = <126>, <60>;
> +	clk-phase-uhs-sdr25 = <120>, <60>;
> +	clk-phase-uhs-ddr50 = <126>, <48>;
> +};
> +
> +&gem3 { /* required by spec */
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_gem3_default>;
> +	phy-handle = <&phy0>;
> +	phy-mode = "rgmii-id";
> +
> +	mdio: mdio {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reset-gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
> +		reset-delay-us = <2>;
> +
> +		phy0: ethernet-phy at 1 {
> +			#phy-cells = <1>;
> +			reg = <1>;
> +			ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
> +			ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>;
> +			ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
> +			ti,dp83867-rxctrl-strap-quirk;
> +		};
> +	};
> +};
> +
> +&pinctrl0 { /* required by spec */
> +	status = "okay";
> +
> +	pinctrl_uart1_default: uart1-default {
> +		conf {
> +			groups = "uart1_9_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +			drive-strength = <12>;
> +		};
> +
> +		conf-rx {
> +			pins = "MIO37";
> +			bias-high-impedance;
> +		};
> +
> +		conf-tx {
> +			pins = "MIO36";
> +			bias-disable;
> +		};
> +
> +		mux {
> +			groups = "uart1_9_grp";
> +			function = "uart1";
> +		};
> +	};
> +
> +	pinctrl_i2c1_default: i2c1-default {
> +		conf {
> +			groups = "i2c1_6_grp";
> +			bias-pull-up;
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		mux {
> +			groups = "i2c1_6_grp";
> +			function = "i2c1";
> +		};
> +	};
> +
> +	pinctrl_i2c1_gpio: i2c1-gpio {
> +		conf {
> +			groups = "gpio0_24_grp", "gpio0_25_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		mux {
> +			groups = "gpio0_24_grp", "gpio0_25_grp";
> +			function = "gpio0";
> +		};
> +	};
> +
> +	pinctrl_gem3_default: gem3-default {
> +		conf {
> +			groups = "ethernet3_0_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		conf-rx {
> +			pins = "MIO70", "MIO72", "MIO74";
> +			bias-high-impedance;
> +			low-power-disable;
> +		};
> +
> +		conf-bootstrap {
> +			pins = "MIO71", "MIO73", "MIO75";
> +			bias-disable;
> +			low-power-disable;
> +		};
> +
> +		conf-tx {
> +			pins = "MIO64", "MIO65", "MIO66",
> +				"MIO67", "MIO68", "MIO69";
> +			bias-disable;
> +			low-power-enable;
> +		};
> +
> +		conf-mdio {
> +			groups = "mdio3_0_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +			bias-disable;
> +		};
> +
> +		mux-mdio {
> +			function = "mdio3";
> +			groups = "mdio3_0_grp";
> +		};
> +
> +		mux {
> +			function = "ethernet3";
> +			groups = "ethernet3_0_grp";
> +		};
> +	};
> +
> +	pinctrl_usb0_default: usb0-default {
> +		conf {
> +			groups = "usb0_0_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		conf-rx {
> +			pins = "MIO52", "MIO53", "MIO55";
> +			bias-high-impedance;
> +		};
> +
> +		conf-tx {
> +			pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59",
> +			"MIO60", "MIO61", "MIO62", "MIO63";
> +			bias-disable;
> +		};
> +
> +		mux {
> +			groups = "usb0_0_grp";
> +			function = "usb0";
> +		};
> +	};
> +
> +	pinctrl_sdhci1_default: sdhci1-default {
> +		conf {
> +			groups = "sdio1_0_grp";
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +			bias-disable;
> +		};
> +
> +		conf-cd {
> +			groups = "sdio1_cd_0_grp";
> +			bias-high-impedance;
> +			bias-pull-up;
> +			slew-rate = <SLEW_RATE_SLOW>;
> +			power-source = <IO_STANDARD_LVCMOS18>;
> +		};
> +
> +		mux-cd {
> +			groups = "sdio1_cd_0_grp";
> +			function = "sdio1_cd";
> +		};
> +
> +		mux {
> +			groups = "sdio1_0_grp";
> +			function = "sdio1";
> +		};
> +	};
> +};
> +
> +&uart1 {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_uart1_default>;
> +};
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
> new file mode 100644
> index 000000000000..550b389153e6
> --- /dev/null
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
> @@ -0,0 +1,289 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * dts file for Xilinx ZynqMP SM-K26 rev1/B/A
> + *
> + * (C) Copyright 2020 - 2021, Xilinx, Inc.
> + *
> + * Michal Simek <michal.simek at xilinx.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "zynqmp.dtsi"
> +#include "zynqmp-clk-ccf.dtsi"
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/phy/phy.h>
> +
> +/ {
> +	model = "ZynqMP SM-K26 Rev1/B/A";
> +	compatible = "xlnx,zynqmp-sm-k26-rev1", "xlnx,zynqmp-sm-k26-revB",
> +		     "xlnx,zynqmp-sm-k26-revA", "xlnx,zynqmp-sm-k26",
> +		     "xlnx,zynqmp";
> +
> +	aliases {
> +		i2c0 = &i2c0;
> +		i2c1 = &i2c1;
> +		mmc0 = &sdhci0;
> +		mmc1 = &sdhci1;
> +		nvmem0 = &eeprom;
> +		nvmem1 = &eeprom_cc;
> +		rtc0 = &rtc;
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &dcc;
> +		spi0 = &qspi;
> +		spi1 = &spi0;
> +		spi2 = &spi1;
> +		usb0 = &usb0;
> +		usb1 = &usb1;
> +	};
> +
> +	chosen {
> +		bootargs = "earlycon";
> +		stdout-path = "serial1:115200n8";
> +	};
> +
> +	memory at 0 {
> +		device_type = "memory"; /* 4GB */
> +		reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		autorepeat;
> +		fwuen {
> +			label = "fwuen";
> +			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		ds35-led {
> +			label = "heartbeat";
> +			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +
> +		ds36-led {
> +			label = "vbus_det";
> +			gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
> +			default-state = "on";
> +		};
> +	};
> +};
> +
> +&uart1 { /* MIO36/MIO37 */
> +	status = "okay";
> +};
> +
> +&qspi { /* MIO 0-5 - U143 */
> +	status = "okay";
> +	flash at 0 { /* MT25QU512A */
> +		compatible = "mt25qu512a", "jedec,spi-nor"; /* 64MB */
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		reg = <0>;
> +		spi-tx-bus-width = <1>;
> +		spi-rx-bus-width = <4>;
> +		spi-max-frequency = <40000000>; /* 40MHz */
> +		partition at 0 {
> +			label = "Image Selector";
> +			reg = <0x0 0x80000>; /* 512KB */
> +			read-only;
> +			lock;
> +		};
> +		partition at 80000 {
> +			label = "Image Selector Golden";
> +			reg = <0x80000 0x80000>; /* 512KB */
> +			read-only;
> +			lock;
> +		};
> +		partition at 100000 {
> +			label = "Persistent Register";
> +			reg = <0x100000 0x20000>; /* 128KB */
> +		};
> +		partition at 120000 {
> +			label = "Persistent Register Backup";
> +			reg = <0x120000 0x20000>; /* 128KB */
> +		};
> +		partition at 140000 {
> +			label = "Open_1";
> +			reg = <0x140000 0xC0000>; /* 768KB */
> +		};
> +		partition at 200000 {
> +			label = "Image A (FSBL, PMU, ATF, U-Boot)";
> +			reg = <0x200000 0xD00000>; /* 13MB */
> +		};
> +		partition at f00000 {
> +			label = "ImgSel Image A Catch";
> +			reg = <0xF00000 0x80000>; /* 512KB */
> +			read-only;
> +			lock;
> +		};
> +		partition at f80000 {
> +			label = "Image B (FSBL, PMU, ATF, U-Boot)";
> +			reg = <0xF80000 0xD00000>; /* 13MB */
> +		};
> +		partition at 1c80000 {
> +			label = "ImgSel Image B Catch";
> +			reg = <0x1C80000 0x80000>; /* 512KB */
> +			read-only;
> +			lock;
> +		};
> +		partition at 1d00000 {
> +			label = "Open_2";
> +			reg = <0x1D00000 0x100000>; /* 1MB */
> +		};
> +		partition at 1e00000 {
> +			label = "Recovery Image";
> +			reg = <0x1E00000 0x200000>; /* 2MB */
> +			read-only;
> +			lock;
> +		};
> +		partition at 2000000 {
> +			label = "Recovery Image Backup";
> +			reg = <0x2000000 0x200000>; /* 2MB */
> +			read-only;
> +			lock;
> +		};
> +		partition at 2200000 {
> +			label = "U-Boot storage variables";
> +			reg = <0x2200000 0x20000>; /* 128KB */
> +		};
> +		partition at 2220000 {
> +			label = "U-Boot storage variables backup";
> +			reg = <0x2220000 0x20000>; /* 128KB */
> +		};
> +		partition at 2240000 {
> +			label = "SHA256";
> +			reg = <0x2240000 0x10000>; /* 256B but 64KB sector */
> +			read-only;
> +			lock;
> +		};
> +		partition at 2250000 {
> +			label = "User";
> +			reg = <0x2250000 0x1db0000>; /* 29.5 MB */
> +		};
> +	};
> +};
> +
> +&sdhci0 { /* MIO13-23 - 16GB emmc MTFC16GAPALBH-IT - U133A */
> +	status = "okay";
> +	non-removable;
> +	disable-wp;
> +	bus-width = <8>;
> +	xlnx,mio-bank = <0>;
> +};
> +
> +&spi1 { /* MIO6, 9-11 */
> +	status = "okay";
> +	label = "TPM";
> +	num-cs = <1>;
> +	tpm at 0 { /* slm9670 - U144 */
> +		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
> +		reg = <0>;
> +		spi-max-frequency = <18500000>;
> +	};
> +};
> +
> +&i2c1 {
> +	status = "okay";
> +	clock-frequency = <400000>;
> +	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
> +	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
> +
> +	eeprom: eeprom at 50 { /* u46 - also at address 0x58 */
> +		compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
> +		reg = <0x50>;
> +		/* WP pin EE_WP_EN connected to slg7x644092 at 68 */
> +	};
> +
> +	eeprom_cc: eeprom at 51 { /* required by spec - also at address 0x59 */
> +		compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
> +		reg = <0x51>;
> +	};
> +
> +	/* da9062 at 30 - u170 - also at address 0x31 */
> +	/* da9131 at 33 - u167 */
> +	da9131: pmic at 33 {
> +		compatible = "dlg,da9131";
> +		reg = <0x33>;
> +		regulators {
> +			da9131_buck1: buck1 {
> +				regulator-name = "da9131_buck1";
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +			da9131_buck2: buck2 {
> +				regulator-name = "da9131_buck2";
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +		};
> +	};
> +
> +	/* da9130 at 32 - u166 */
> +	da9130: pmic at 32 {
> +		compatible = "dlg,da9130";
> +		reg = <0x32>;
> +		regulators {
> +			da9130_buck1: buck1 {
> +				regulator-name = "da9130_buck1";
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +		};
> +	};
> +
> +	/* slg7x644091 at 70 - u168 NOT accessible due to address conflict with stdp4320 */
> +	/*
> +	 * stdp4320 - u27 FW has below two issues to be fixed in next board revision.
> +	 * Device acknowledging to addresses 0x5C, 0x5D, 0x70, 0x72, 0x76.
> +	 * Address conflict with slg7x644091 at 70 making both the devices NOT accessible.
> +	 * With the FW fix, stdp4320 should respond to address 0x73 only.
> +	 */
> +	/* slg7x644092 at 68 - u169 */
> +	/* Also connected via JA1C as C23/C24 */
> +};
> +
> +&gpio {
> +	status = "okay";
> +	gpio-line-names = "QSPI_CLK", "QSPI_DQ1", "QSPI_DQ2", "QSPI_DQ3", "QSPI_DQ0", /* 0 - 4 */
> +			  "QSPI_CS_B", "SPI_CLK", "LED1", "LED2", "SPI_CS_B", /* 5 - 9 */
> +			  "SPI_MISO", "SPI_MOSI", "FWUEN", "EMMC_DAT0", "EMMC_DAT1", /* 10 - 14 */
> +			  "EMMC_DAT2", "EMMC_DAT3", "EMMC_DAT4", "EMMC_DAT5", "EMMC_DAT6", /* 15 - 19 */
> +			  "EMMC_DAT7", "EMMC_CMD", "EMMC_CLK", "EMMC_RST", "I2C1_SCL", /* 20 - 24 */
> +			  "I2C1_SDA", "", "", "", "", /* 25 - 29 */
> +			  "", "", "", "", "", /* 30 - 34 */
> +			  "", "", "", "", "", /* 35 - 39 */
> +			  "", "", "", "", "", /* 40 - 44 */
> +			  "", "", "", "", "", /* 45 - 49 */
> +			  "", "", "", "", "", /* 50 - 54 */
> +			  "", "", "", "", "", /* 55 - 59 */
> +			  "", "", "", "", "", /* 60 - 64 */
> +			  "", "", "", "", "", /* 65 - 69 */
> +			  "", "", "", "", "", /* 70 - 74 */
> +			  "", "", "", /* 75 - 77, MIO end and EMIO start */
> +			  "", "", /* 78 - 79 */
> +			  "", "", "", "", "", /* 80 - 84 */
> +			  "", "", "", "", "", /* 85 - 89 */
> +			  "", "", "", "", "", /* 90 - 94 */
> +			  "", "", "", "", "", /* 95 - 99 */
> +			  "", "", "", "", "", /* 100 - 104 */
> +			  "", "", "", "", "", /* 105 - 109 */
> +			  "", "", "", "", "", /* 110 - 114 */
> +			  "", "", "", "", "", /* 115 - 119 */
> +			  "", "", "", "", "", /* 120 - 124 */
> +			  "", "", "", "", "", /* 125 - 129 */
> +			  "", "", "", "", "", /* 130 - 134 */
> +			  "", "", "", "", "", /* 135 - 139 */
> +			  "", "", "", "", "", /* 140 - 144 */
> +			  "", "", "", "", "", /* 145 - 149 */
> +			  "", "", "", "", "", /* 150 - 154 */
> +			  "", "", "", "", "", /* 155 - 159 */
> +			  "", "", "", "", "", /* 160 - 164 */
> +			  "", "", "", "", "", /* 165 - 169 */
> +			  "", "", "", ""; /* 170 - 174 */
> +};
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
> new file mode 100644
> index 000000000000..c70966c1f344
> --- /dev/null
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * dts file for Xilinx ZynqMP SMK-K26 rev1/B/A
> + *
> + * (C) Copyright 2020 - 2021, Xilinx, Inc.
> + *
> + * Michal Simek <michal.simek at xilinx.com>
> + */
> +
> +#include "zynqmp-sm-k26-revA.dts"
> +
> +/ {
> +	model = "ZynqMP SMK-K26 Rev1/B/A";
> +	compatible = "xlnx,zynqmp-smk-k26-rev1", "xlnx,zynqmp-smk-k26-revB",
> +		     "xlnx,zynqmp-smk-k26-revA", "xlnx,zynqmp-smk-k26",
> +		     "xlnx,zynqmp";
> +};
> +
> +&sdhci0 {
> +	status = "disabled";
> +};
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Fri Aug 13 13:23:56 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 15:23:56 -0500
Subject: [PATCH 0/4] mmc: pwrseq: sd8787: add support for selectable
In-Reply-To: <20210806113001.821660-1-claudiu.beznea@microchip.com>
References: <20210806113001.821660-1-claudiu.beznea@microchip.com>
Message-ID: <YRbU3NtbYamh7UGH@robh.at.kernel.org>

On Fri, Aug 06, 2021 at 02:29:57PM +0300, Claudiu Beznea wrote:
> Hi,
> 
> This series adds support for selecting the delay b/w reset and power
> lines on pwrseq-sd8787. With this the driver could also be used by
> other devices (e.g. WILC1000/WILC3000 which needs a delay of 5ms). Along
> with this added the DT bindings for WILC3000 device present on
> SAMA5D27 WLSOM1 board.

A 300ms delay doesn't work? Is powering on the device so timing 
critical?

Add a new compatible for your device and imply the timing from that. 
That way we're not extending the binding a property at a time in a 
poorly designed way for each new timing quirk.

Rob


From arnd at arndb.de  Fri Aug 13 13:43:26 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 13 Aug 2021 22:43:26 +0200
Subject: [PATCH] arm64: dts: synaptics: remove unused DTSI for AS370
In-Reply-To: <YRbDNInfG7caSr2r@robh.at.kernel.org>
References: <20210806082635.20239-1-krzysztof.kozlowski@canonical.com>
 <YRbDNInfG7caSr2r@robh.at.kernel.org>
Message-ID: <CAK8P3a0QtpBq8i2_RhW=isLSNULc2z7DbjohZReMY+rhyXEbJA@mail.gmail.com>

On Fri, Aug 13, 2021 at 9:09 PM Rob Herring <robh at kernel.org> wrote:
>
> On Fri, 06 Aug 2021 10:26:35 +0200, Krzysztof Kozlowski wrote:
> > The as370.dtsi for Synaptics AS370 SoC does not have a user (DTS board
> > file), is uncompilable and untestable.  It was added back in 2018.  No
> > user appeared since that time, so assume it won't be added.
> >
> > Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > ---
> >  .../devicetree/bindings/arm/syna.txt          |   4 -
> >  arch/arm64/boot/dts/synaptics/as370.dtsi      | 173 ------------------
> >  2 files changed, 177 deletions(-)
> >  delete mode 100644 arch/arm64/boot/dts/synaptics/as370.dtsi
> >
>
> I assume Arnd/Olof will take this.
>
> Acked-by: Rob Herring <robh at kernel.org>

Sure, I can take that, but it would be nice to hear anything from Jisheng Zhang
about this.

I can see that the only two 64-bit Synaptics SoCs are as370 and bg4ct,
but both of them have apparently been replaced with newer versions that
never made it into the kernel: as371, as390, bg5ct, according to press
releases.

Jisheng, can you clarify whether you plan to complete the as370 support
or add the later SoCs?

       Arnd


From robh at kernel.org  Fri Aug 13 13:48:41 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 15:48:41 -0500
Subject: [PATCH v2 2/2] arm: dts: mt7623: add musb device nodes
In-Reply-To: <20210808123840.176738-3-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <20210808123840.176738-1-mans0n@gorani.run>
 <20210808123840.176738-3-mans0n@gorani.run>
Message-ID: <YRbaqdF0EJxNcpsX@robh.at.kernel.org>

On Sun, Aug 08, 2021 at 09:38:40PM +0900, Sungbo Eo wrote:
> MT7623 has an musb controller that is compatible with the one from MT2701.
> 
> Signed-off-by: Sungbo Eo <mans0n at gorani.run>
> ---
> v2:
> * rename usb3 label to usb0
> * move usb0 & u2phy1 nodes to the right sorted place
> * disable u2phy1 by default
> * correct u2port2 node name to match its reg address
> ---
>  arch/arm/boot/dts/mt7623.dtsi  | 34 ++++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
>  2 files changed, 38 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
> index 3c11f7cfcc40..790d74439cc6 100644
> --- a/arch/arm/boot/dts/mt7623.dtsi
> +++ b/arch/arm/boot/dts/mt7623.dtsi
> @@ -585,6 +585,40 @@ spi2: spi at 11017000 {
>  		status = "disabled";
>  	};
>  
> +	usb0: usb at 11200000 {
> +		compatible = "mediatek,mt7623-musb",
> +			     "mediatek,mtk-musb";
> +		reg = <0 0x11200000 0 0x1000>;
> +		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
> +		interrupt-names = "mc";
> +		phys = <&u2port2 PHY_TYPE_USB2>;
> +		dr_mode = "otg";
> +		clocks = <&pericfg CLK_PERI_USB0>,
> +			 <&pericfg CLK_PERI_USB0_MCU>,
> +			 <&pericfg CLK_PERI_USB_SLV>;
> +		clock-names = "main","mcu","univpll";
> +		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
> +		status = "disabled";
> +	};
> +
> +	u2phy1: t-phy at 11210000 {
> +		compatible = "mediatek,mt7623-tphy",
> +			     "mediatek,generic-tphy-v1";
> +		reg = <0 0x11210000 0 0x0800>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +		status = "disabled";
> +
> +		u2port2: usb-phy at 11210800 {
> +			reg = <0 0x11210800 0 0x0100>;
> +			clocks = <&topckgen CLK_TOP_USB_PHY48M>;
> +			clock-names = "ref";
> +			#phy-cells = <1>;
> +			status = "okay";

Enabled is the default and doesn't really make sense here given the 
parent is disabled. Drop.

> +		};
> +	};
> +
>  	audsys: clock-controller at 11220000 {
>  		compatible = "mediatek,mt7623-audsys",
>  			     "mediatek,mt2701-audsys",
> diff --git a/arch/arm/boot/dts/mt7623a.dtsi b/arch/arm/boot/dts/mt7623a.dtsi
> index 0735a1fb8ad9..d304b62d24b5 100644
> --- a/arch/arm/boot/dts/mt7623a.dtsi
> +++ b/arch/arm/boot/dts/mt7623a.dtsi
> @@ -35,6 +35,10 @@ &scpsys {
>  	clock-names = "ethif";
>  };
>  
> +&usb0 {
> +	power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>;
> +};
> +
>  &usb1 {
>  	power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>;
>  };
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Fri Aug 13 13:49:00 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 15:49:00 -0500
Subject: [PATCH v2 1/2] dt-bindings: usb: mtk-musb: add MT7623 compatible
In-Reply-To: <20210808123840.176738-2-mans0n@gorani.run>
References: <20210803151320.71531-1-mans0n@gorani.run>
 <20210808123840.176738-1-mans0n@gorani.run>
 <20210808123840.176738-2-mans0n@gorani.run>
Message-ID: <YRbavByuh2HGnVo7@robh.at.kernel.org>

On Sun, 08 Aug 2021 21:38:39 +0900, Sungbo Eo wrote:
> Document MT7623 compatible for mtk-musb.
> 
> Signed-off-by: Sungbo Eo <mans0n at gorani.run>
> Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
> ---
> v2:
> * add reviewed by Matthias
> ---
>  Documentation/devicetree/bindings/usb/mediatek,musb.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From robh at kernel.org  Fri Aug 13 13:57:00 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 15:57:00 -0500
Subject: [PATCH v6 3/6] dt-bindings: remoteproc: mediatek: Convert
 mtk,scp to json-schema
In-Reply-To: <20210809051959.31136-4-tinghan.shen@mediatek.com>
References: <20210809051959.31136-1-tinghan.shen@mediatek.com>
 <20210809051959.31136-4-tinghan.shen@mediatek.com>
Message-ID: <YRbcnKLx43UcJNSm@robh.at.kernel.org>

On Mon, 09 Aug 2021 13:19:56 +0800, Tinghan Shen wrote:
> Convert the mtk,scp binding to DT schema format using json-schema.
> 
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> ---
>  .../bindings/remoteproc/mtk,scp.txt           | 41 ---------
>  .../bindings/remoteproc/mtk,scp.yaml          | 92 +++++++++++++++++++
>  2 files changed, 92 insertions(+), 41 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
>  create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From leoyang.li at nxp.com  Fri Aug 13 14:39:14 2021
From: leoyang.li at nxp.com (Li Yang)
Date: Fri, 13 Aug 2021 16:39:14 -0500
Subject: [PATCH] soc: fsl: qe: fix static checker warning
In-Reply-To: <20210811071036.44658-1-fido_max@inbox.ru>
References: <20210811071036.44658-1-fido_max@inbox.ru>
Message-ID: <CADRPPNSP+vZ_B+myoAs9LxKQH=moKgq_McXfihxyEbc=7NnxWA@mail.gmail.com>

On Wed, Aug 11, 2021 at 2:10 AM Maxim Kochetkov <fido_max at inbox.ru> wrote:
>
> The patch be7ecbd240b2: "soc: fsl: qe: convert QE interrupt
> controller to platform_device" from Aug 3, 2021, leads to the
> following static checker warning:
>
>         drivers/soc/fsl/qe/qe_ic.c:438 qe_ic_init()
>         warn: unsigned 'qe_ic->virq_low' is never less than zero.
>
> In old variant irq_of_parse_and_map() returns zero if failed so
> unsigned int for virq_high/virq_low was ok.
> In new variant platform_get_irq() returns negative error codes
> if failed so we need to use int for virq_high/virq_low.
>
> Also simplify high_handler checking and remove the curly braces
> to make checkpatch happy.
>
> Fixes: be7ecbd240b2 ("soc: fsl: qe: convert QE interrupt controller to platform_device")
> Signed-off-by: Maxim Kochetkov <fido_max at inbox.ru>
> Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
> ---
>  drivers/soc/fsl/qe/qe_ic.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c
> index e710d554425d..bff34ee2150a 100644
> --- a/drivers/soc/fsl/qe/qe_ic.c
> +++ b/drivers/soc/fsl/qe/qe_ic.c
> @@ -54,8 +54,8 @@ struct qe_ic {
>         struct irq_chip hc_irq;
>
>         /* VIRQ numbers of QE high/low irqs */
> -       unsigned int virq_high;
> -       unsigned int virq_low;
> +       int virq_high;
> +       int virq_low;
>  };
>
>  /*
> @@ -435,9 +435,8 @@ static int qe_ic_init(struct platform_device *pdev)
>         qe_ic->virq_high = platform_get_irq(pdev, 0);
>         qe_ic->virq_low = platform_get_irq(pdev, 1);
>
> -       if (qe_ic->virq_low < 0) {
> +       if (qe_ic->virq_low < 0)

Probably should be <= 0 here.

>                 return -ENODEV;
> -       }
>
>         if (qe_ic->virq_high != qe_ic->virq_low) {

Probably we should check if qe_ic->virq_high > 0 here if we rely on
this to decide whether to set the handler later.

Applied with the above changes.  Thanks

>                 low_handler = qe_ic_cascade_low;
> @@ -459,7 +458,7 @@ static int qe_ic_init(struct platform_device *pdev)
>         irq_set_handler_data(qe_ic->virq_low, qe_ic);
>         irq_set_chained_handler(qe_ic->virq_low, low_handler);
>
> -       if (qe_ic->virq_high && qe_ic->virq_high != qe_ic->virq_low) {
> +       if (high_handler) {
>                 irq_set_handler_data(qe_ic->virq_high, qe_ic);
>                 irq_set_chained_handler(qe_ic->virq_high, high_handler);
>         }
> --
> 2.31.1
>


From robh at kernel.org  Fri Aug 13 15:18:03 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 13 Aug 2021 17:18:03 -0500
Subject: [PATCH] ARM: oxnas: Add basic support for Zyxel NSA210
In-Reply-To: <20210809104351.2050187-1-uwe@kleine-koenig.org>
References: <20210809104351.2050187-1-uwe@kleine-koenig.org>
Message-ID: <YRbvmwLGwT/ELuLM@robh.at.kernel.org>

On Mon, Aug 09, 2021 at 12:43:51PM +0200, Uwe Kleine-K?nig wrote:
> This is a one bay NAS originally shipping Linux 2.6.24.4. It features
> 
>  - 128 MiB RAM
>  - 2x eSATA (1x internal, 1x external)
>  - 2x USB 2.0
>  - 4 MiB NOR
>  - battery powered RTC on i2c (PCF8563)
>  - 1x GBit ethernet
> 
> For now only the low-hanging fruits are added to the device tree, eSATA,
> USB, i2c and networking needs more work as there are no drivers
> available.
> 
> Such a machine was offered to me by Richard Fr?hning. Thanks!
> 
> Signed-off-by: Uwe Kleine-K?nig <uwe at kleine-koenig.org>
> ---
>  .../devicetree/bindings/arm/oxnas.txt         |   1 +

Please resurrect this patch[1] before adding this.

Rob

[1] https://lore.kernel.org/linux-devicetree/20181203213223.16986-22-robh at kernel.org/


From leoyang.li at nxp.com  Fri Aug 13 15:23:05 2021
From: leoyang.li at nxp.com (Li Yang)
Date: Fri, 13 Aug 2021 17:23:05 -0500
Subject: [GIT PULL] soc/fsl drivers changes for fix(v5.14)
Message-ID: <20210813222305.13663-1-leoyang.li@nxp.com>

Hi soc maintainers,

Please merge the following fixes for soc/fsl drivers.

Regards,
Leo

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux.git tags/soc-fsl-fix-v5.14

for you to fetch changes up to c1e64c0aec8cb0499e61af7ea086b59abba97945:

  soc: fsl: qe: fix static checker warning (2021-08-13 16:56:10 -0500)

----------------------------------------------------------------
NXP/FSL SoC driver fixes for v5.14

QE interrupt controller driver
- Convert it to platform_device driver to make it work with fw_devlink
- Fix static analysis issue

----------------------------------------------------------------
Maxim Kochetkov (2):
      soc: fsl: qe: convert QE interrupt controller to platform_device
      soc: fsl: qe: fix static checker warning

 drivers/soc/fsl/qe/qe_ic.c | 84 ++++++++++++++++++++++++++--------------------
 1 file changed, 48 insertions(+), 36 deletions(-)


From changbin.du at gmail.com  Fri Aug 13 17:54:05 2021
From: changbin.du at gmail.com (Changbin Du)
Date: Sat, 14 Aug 2021 08:54:05 +0800
Subject: [PATCH] arm64: replace in_irq() with in_hardirq()
Message-ID: <20210814005405.2658-1-changbin.du@gmail.com>

Replace the obsolete and ambiguos macro in_irq() with new
macro in_hardirq().

Signed-off-by: Changbin Du <changbin.du at gmail.com>
---
 arch/arm64/include/asm/simd.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h
index 89cba2622b79..6a75d7ecdcaa 100644
--- a/arch/arm64/include/asm/simd.h
+++ b/arch/arm64/include/asm/simd.h
@@ -37,7 +37,7 @@ static __must_check inline bool may_use_simd(void)
 	 */
 	return !WARN_ON(!system_capabilities_finalized()) &&
 	       system_supports_fpsimd() &&
-	       !in_irq() && !irqs_disabled() && !in_nmi() &&
+	       !in_hardirq() && !irqs_disabled() && !in_nmi() &&
 	       !this_cpu_read(fpsimd_context_busy);
 }
 
-- 
2.30.2



From john.stultz at linaro.org  Fri Aug 13 18:06:24 2021
From: john.stultz at linaro.org (John Stultz)
Date: Fri, 13 Aug 2021 18:06:24 -0700
Subject: [PATCH 29/29] arm64: dts: qcom: Harmonize DWC USB3 DT nodes name
In-Reply-To: <20210722220918.l7j6zw3aaa27qato@mobilestation>
References: <20210721100220.ddfxwugivsndsedv@mobilestation>
 <YPf29+ewbrYgHxRP@kroah.com> <0064cb2c-5ca6-e693-2e89-8f045c8f7502@kernel.org>
 <YPf+shNM6cXb3mfe@kroah.com> <d853df77-8d36-30b0-dd26-da1bfcb068e0@kernel.org>
 <20210721112531.xvu6ni5ksaehsrjh@mobilestation>
 <CALAqxLViEqSO17P3JGRGYJh-wDoHaJiQQV48zeoRgnar4Xd5Bg@mail.gmail.com>
 <20210722181221.xh3r5kyu7zlcojjx@mobilestation> <YPnEO6NVFZDS1s//@yoga>
 <CALAqxLUT0e+mHMVo685oVTxR8y76733cN0yciQ7ePS6GRE+_dg@mail.gmail.com>
 <20210722220918.l7j6zw3aaa27qato@mobilestation>
Message-ID: <CALAqxLXrs0_Xs0JV5H-wS1q2CJ7XhW5Dj90eu=uazkRXXEMUxQ@mail.gmail.com>

On Thu, Jul 22, 2021 at 3:09 PM Serge Semin <fancer.lancer at gmail.com> wrote:
> On Thu, Jul 22, 2021 at 01:09:05PM -0700, John Stultz wrote:
> > On Thu, Jul 22, 2021 at 12:17 PM Bjorn Andersson
> > <bjorn.andersson at linaro.org> wrote:
> > > > On Jul 21, 2021, 1:45 PM +0200, Krzysztof Kozlowski wrote:
> > > > > I had impression that kernel defines interfaces which should be used and
> > > > > are stable (e.g. syscalls, sysfs and so on). This case is example of
> > > > > user-space relying on something not being marked as part of ABI. Instead
> > > > > they found something working for them and now it is being used in "we
> > > > > cannot break existing systems". Basically, AOSP unilaterally created a
> > > > > stable ABI and now kernel has to stick to it.
> > > > >
> > > > > Really, all normal systems depend on aliases or names and here we have
> > > > > dependency on device address. I proposed way how AOSP should be fixed.
> > > > > Anything happened? Nope.
> > > >
> > > > First time he sent a possible solution for the problem:
> > > > https://lore.kernel.org/lkml/20201221210423.GA2504 at kozik-lap/
> > > >
> > > > To sum up you could have used one of the more portable approaches
> > > > 1. add an udc alias to the controller and use it then to refer to the
> > > > corresponding USB controller
> > >
> > > Is there such a thing as "UDC alias"? Or are you suggesting that we
> > > should add such feature?
> > >
> > > I think it would be wonderful if we could identify the UDCs on our
> > > boards as "USB1" and "USB2", or "the one and only USB-C connector". But
> > > unless that will fall back to the existing naming it would break John's
> > > _existing_ userspace.
> >
>
> > Well, I'd not hold up the existing userspace I'm using as sacrosanct
> > (AOSP devices still usually don't have to work cross-kernel versions -
> > devboards being the main exception). I'm fine if we can rework
> > userland as proposed, so that the issues can be avoided, but I
> > honestly don't have enough context to really understand what that
> > looks like (no idea what udc aliases are).
> >
> > And whatever we do, the main constraint is that userland has to be
> > able to work with existing LTS kernels and newer kernels.
>
> As I said in my response to Bjorn even if it is added to the kernel it
> won't get to the official LTSes as it would be a new kernel feature.
> New features aren't normally backported to the older kernels.
>
> >
> > > > 2. search through DT-nodes looking for a specific compatible/reg
> > > > DT-properties.
> > > >
> > >
> > > We could define that this is the way, but again we didn't yesterday so
> > > your proposal is not backwards compatible.
> >
>
> > It may be backwards compatible, but I'm still not clear exactly how it
> > would work.
> >
> > I guess if we look through all
> > sys/bus/platform/devices/*/of_node/compatbile strings for the desired
> > "snps,dwc3", then find which of the directories have the desired
> > address in the string? (The suggestion for looking at reg seems
> > better, but I don't get a char value out of the dwc3 of_node/reg
> > file).
>
> The algorithm is simple:
> 1) You know what USB controllers you have on your platform. They are
> supposed to be compatible with snps,dwc3 string and have some pre-defined
> base address.
> 2) Find all the files in the directory /sys/class/udc/.
> 3) Walk through all the directories in /sys/bus/platform/devices/ with
> names found in 2) and stop on the device with matching compatible/base
> address defined in 1).
>
> In my case the strings could be retrieved like this:
> USB_NAME_COMPAT=$(/sys/bus/platform/devices/1f100000.usb/of_node/compatible | tr '\0' '\t' | cut -f1)
> USB_DEVICE_ADDR="$(head -c 4 /sys/bus/platform/devices/1f100000.usb/of_node/reg | hexdump -ve '/1 "%02x"' | sed -e 's/^0*//g')"


Hey Serge,
   I just wanted to follow up here.  Amit has reworked the db845c AOSP
userland so that it no longer uses the fixed node name, but instead
probes for it:
  https://android-review.googlesource.com/c/device/linaro/dragonboard/+/1774872

Admittedly, it does take a short-cut.  As your algorithm above,
digging up the devices and finding the sys/bus path to read the reg
value and pipe through hexdump (which android doesn't have) seemed
overly obtuse when the address is in the node name itself (while the
only way to be sure, one normally doesn't use spectroscopy to
determine the value of a coin when you can read what's printed on it
:).  But, should the node naming be further changed at least the
infrastructure we have can be reworked fairly easily to adapt now.

In any case, as we can handle the name change now, if you want to
resubmit your patch, we would no longer object (but can't promise no
one else might be bitten).  Sorry for the delay this caused, and we
appreciate you working with us to find a solution.

thanks
-john


From lkp at intel.com  Fri Aug 13 18:08:50 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 14 Aug 2021 09:08:50 +0800
Subject: [nomadik:ixp4xx-del-boardfiles-v5.15] BUILD SUCCESS
 b71377b3e1e08bf1e7e3dbbe4ee7aa07971552dc
Message-ID: <611717a2.HwUf8cN6408ePiIt%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-del-boardfiles-v5.15
branch HEAD: b71377b3e1e08bf1e7e3dbbe4ee7aa07971552dc  ARM: ixp4xx: Delete the Freecom FSG-3 boardfiles

elapsed time: 720m

configs tested: 123
configs skipped: 57

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210813
arm                         lpc18xx_defconfig
arm                           spitz_defconfig
arm                           tegra_defconfig
arm                          badge4_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
m68k                        mvme147_defconfig
powerpc                     stx_gp3_defconfig
arm                           viper_defconfig
sh                     magicpanelr2_defconfig
mips                          rm200_defconfig
arm                           stm32_defconfig
powerpc                       ppc64_defconfig
xtensa                  audio_kc705_defconfig
mips                      loongson3_defconfig
mips                          ath79_defconfig
sh                          urquell_defconfig
microblaze                      mmu_defconfig
arm                         nhk8815_defconfig
arm                       omap2plus_defconfig
arm                         bcm2835_defconfig
arm                            pleb_defconfig
arc                        nsim_700_defconfig
mips                 decstation_r4k_defconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a004-20210814
i386                 randconfig-a002-20210814
i386                 randconfig-a001-20210814
i386                 randconfig-a003-20210814
i386                 randconfig-a006-20210814
i386                 randconfig-a005-20210814
x86_64               randconfig-a011-20210813
x86_64               randconfig-a013-20210813
x86_64               randconfig-a012-20210813
x86_64               randconfig-a016-20210813
x86_64               randconfig-a015-20210813
x86_64               randconfig-a014-20210813
i386                 randconfig-a011-20210814
i386                 randconfig-a015-20210814
i386                 randconfig-a013-20210814
i386                 randconfig-a014-20210814
i386                 randconfig-a016-20210814
i386                 randconfig-a012-20210814
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210814
x86_64               randconfig-c001-20210813
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a013-20210814
x86_64               randconfig-a011-20210814
x86_64               randconfig-a016-20210814
x86_64               randconfig-a012-20210814
x86_64               randconfig-a014-20210814
x86_64               randconfig-a015-20210814
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From shawnguo at kernel.org  Fri Aug 13 21:47:04 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 12:47:04 +0800
Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
 LX2160A UART
In-Reply-To: <AS8PR04MB8946D0EB15D631346F4D13198FF69@AS8PR04MB8946.eurprd04.prod.outlook.com>
References: <20210615131605.616-1-thunder.leizhen@huawei.com>
 <20210615131605.616-2-thunder.leizhen@huawei.com>
 <AS8PR04MB8946D0EB15D631346F4D13198FF69@AS8PR04MB8946.eurprd04.prod.outlook.com>
Message-ID: <20210814044703.GU30984@dragon>

On Mon, Aug 09, 2021 at 10:52:04PM +0000, Leo Li wrote:
> 
> 
> > -----Original Message-----
> > From: Zhen Lei <thunder.leizhen at huawei.com>
> > Sent: Tuesday, June 15, 2021 8:16 AM
> > To: Shawn Guo <shawnguo at kernel.org>; Leo Li <leoyang.li at nxp.com>; Rob
> > Herring <robh+dt at kernel.org>; Mark Kettenis <mark.kettenis at xs4all.nl>;
> > devicetree <devicetree at vger.kernel.org>; linux-arm-kernel <linux-arm-
> > kernel at lists.infradead.org>; linux-kernel <linux-kernel at vger.kernel.org>
> > Cc: Zhen Lei <thunder.leizhen at huawei.com>
> > Subject: [PATCH v2 1/1] arm64: dts: lx2160a: Fix the compatible string of
> > LX2160A UART
> > 
> > Mark Kettenis told us that:
> > According to the NXP documentation, the LX2160A has a real PL011 UART.
> > 
> > Therefore, rewrite it to the compatible string of pl011. The property "current-
> > speed" specific to "arm,sbsa-uart" is also deleted.
> 
> Sorry that I missed the discussion on the v1.  But looks like this change breaks the LX2160 boot.  The AMBA matching doesn't seem to work.  And the console is not registered correctly.
> 
> [    0.639055] OF: amba_device_add() failed (-2) for /soc/serial at 21c0000
> [    0.645612] OF: amba_device_add() failed (-2) for /soc/serial at 21d0000

Patch dropped.

Shawn


From rentao.bupt at gmail.com  Fri Aug 13 22:22:29 2021
From: rentao.bupt at gmail.com (Tao Ren)
Date: Fri, 13 Aug 2021 22:22:29 -0700
Subject: [PATCH v2 4/6] ARM: dts: aspeed: Add Facebook Cloudripper
 (AST2600) BMC
In-Reply-To: <YRaFpq1LvRzMYr/A@lunn.ch>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
 <20210805222818.8391-5-rentao.bupt@gmail.com>
 <CACPK8XcV5On2D4D+SXnfw1M0owwfCL4Su19jOEA7yWpq+T3jLw@mail.gmail.com>
 <20210813034016.GA21895@taoren-ubuntu-R90MNF91>
 <YRaFpq1LvRzMYr/A@lunn.ch>
Message-ID: <20210814052228.GA1298@taoren-ubuntu-R90MNF91>

Hi Andrew,

On Fri, Aug 13, 2021 at 04:45:58PM +0200, Andrew Lunn wrote:
> On Thu, Aug 12, 2021 at 08:40:17PM -0700, Tao Ren wrote:
> > On Fri, Aug 13, 2021 at 01:29:17AM +0000, Joel Stanley wrote:
> > > On Thu, 5 Aug 2021 at 22:28, <rentao.bupt at gmail.com> wrote:
> > > > +&mdio1 {
> > > > +       status = "okay";
> > > 
> > > You're enabling this but it looks like it's unused?
> > 
> > Thanks Joel for the careful review. The MDIO controller is not paired
> > with BMC MAC; instead, it's connected to the MDC/MDIO interface of the
> > on-board switch (whose ports are connected to BMC, Host and front panel
> > management port).
> 
> What switch is it? Is there a DSA driver for it? drivers/net/dsa/*
> Ideally you want Linux to be controlling the switch, in the standard
> linux way.
> 
>      Andrew

Thanks for jumping in. We are using BCM5389 and the MDIO bus is used to
access BCM5389 MDC/MDIO interface in Pseudo-PHY mode.

I didn't know drivers/net/dsa, but let me check out the drivers and see
if it works in the Cloudripper environment.


Thanks,

Tao


From shawnguo at kernel.org  Fri Aug 13 22:22:53 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 13:22:53 +0800
Subject: [PATCH] arm64: dts: imx8mq-reform2: add sound support
In-Reply-To: <20210812194712.300116-1-dev@lynxeye.de>
References: <20210812194712.300116-1-dev@lynxeye.de>
Message-ID: <20210814052250.GV30984@dragon>

On Thu, Aug 12, 2021 at 09:47:12PM +0200, Lucas Stach wrote:
> This adds sound support to the Reform2.
> 
> It differs from the downstream implementation in that the codec
> is used as the BCLK and FSYNC master and the i.MX8MQ only supplies
> a fixed 25MHz MCLK from the oscillator. This allows to support
> a wider range of audio rates by using the codec PLL and to shut
> down the audio PLLs on the i.MX8MQ SoC side.
> 
> Signed-off-by: Lucas Stach <dev at lynxeye.de>

Applied, thanks!


From shawnguo at kernel.org  Fri Aug 13 22:27:15 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 13:27:15 +0800
Subject: [PATCH v34 0/3] Mainline imx6 based SKOV boards
In-Reply-To: <20210804043439.11757-1-o.rempel@pengutronix.de>
References: <20210804043439.11757-1-o.rempel@pengutronix.de>
Message-ID: <20210814052715.GW30984@dragon>

On Wed, Aug 04, 2021 at 06:34:36AM +0200, Oleksij Rempel wrote:
> changes v4:
> - add vref-supply to adc at 0
> - split gpio assignment for the mdio node
> 
> changes v3:
> - drop panel bindings patches, it is already in drm-misc-next
> - remove some new lines
> - reorder compatibles at the start of the nodes
> - use lowercase for hex value
> - add enable-active-high to the regulator-vcc-mmc-io and fix MMC voltage
>   configuration.
> 
> changes v2:
> - remove unnecessary newlines.
> - change linux,wakeup to wakeup-source
> - change switch at 3 unit-address to @0
> - sort aliases alphabetically
> 
> Mainline imx6 based DTs for SKOV A/S boards
> 
> Oleksij Rempel (2):
>   dt-bindings: vendor-prefixes: Add an entry for SKOV A/S
>   dt-bindings: arm: fsl: add SKOV imx6q and imx6dl based boards
> 
> Sam Ravnborg (1):
>   ARM: dts: add SKOV imx6q and imx6dl based boards

Applied, thanks!


From shawnguo at kernel.org  Fri Aug 13 22:40:56 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 13:40:56 +0800
Subject: [PATCH] ARM: imx_v6_v7_defconfig: enable driver of the LTC3676
 PMIC
In-Reply-To: <54505ae8-075c-bc54-e039-0badc261fa27@denx.de>
References: <20210805135035.124938-1-pzimmermann@dh-electronics.com>
 <54505ae8-075c-bc54-e039-0badc261fa27@denx.de>
Message-ID: <20210814054055.GX30984@dragon>

On Tue, Aug 10, 2021 at 07:36:24AM +0200, Marek Vasut wrote:
> On 8/5/21 3:50 PM, Pascal Zimmermann wrote:
> > The LTC3676 is a PMIC which is used on some i.MX6 based boards (like the
> > DHCOM i.MX6 Quad SoM), it was first used on the GW Ventana board, enable
> > LTC3676 driver in imx_v6_v7_defconfig.
> > 
> > Fixes: e3946fe805053 ("ARM: dts: add Gateworks Ventana support")

I don't think the Fixes tag is appropriate here.  Dropped it and applied
patch.

Shawn

> > Signed-off-by: Pascal Zimmermann <pzimmermann at dh-electronics.com>
> > Cc: Shawn Guo <shawnguo at kernel.org>
> > Cc: Sascha Hauer <s.hauer at pengutronix.de>
> > Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
> > Cc: Fabio Estevam <festevam at denx.de>
> > Cc: NXP Linux Team <linux-imx at nxp.com>
> > Cc: Marek Vasut <marex at denx.de>
> > Cc: kernel at dh-electronics.com
> > To: linux-arm-kernel at lists.infradead.org
> > ---
> >   arch/arm/configs/imx_v6_v7_defconfig | 1 +
> >   1 file changed, 1 insertion(+)
> > 
> > diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
> > index 079fcd8d1d11..f94e3d11c3e9 100644
> > --- a/arch/arm/configs/imx_v6_v7_defconfig
> > +++ b/arch/arm/configs/imx_v6_v7_defconfig
> > @@ -252,6 +252,7 @@ CONFIG_REGULATOR_DA9052=y
> >   CONFIG_REGULATOR_DA9062=y
> >   CONFIG_REGULATOR_DA9063=y
> >   CONFIG_REGULATOR_GPIO=y
> > +CONFIG_REGULATOR_LTC3676=y
> >   CONFIG_REGULATOR_MC13783=y
> >   CONFIG_REGULATOR_MC13892=y
> >   CONFIG_REGULATOR_PFUZE100=y
> 
> Reviewed-by: Marek Vasut <marex at denx.de>
> Tested-by: Marek Vasut <marex at denx.de> # On DH iMX6Q DHCOM PDK2
> 
> Neither board can work well without a PMIC driver.


From shawnguo at kernel.org  Fri Aug 13 22:43:54 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 13:43:54 +0800
Subject: [PATCH] ARM: dts: vf610-zii-dev-rev-b: Remove #address-cells and
 #size-cells property from at93c46d dt node
In-Reply-To: <20210810064420.9489-1-a-govindraju@ti.com>
References: <20210810064420.9489-1-a-govindraju@ti.com>
Message-ID: <20210814054353.GY30984@dragon>

On Tue, Aug 10, 2021 at 12:14:20PM +0530, Aswath Govindraju wrote:
> Remove #address-cells and #size-cells property from at93c46d device tree
> node as it does not have child nodes.
> 
> Fixes: 1556063fde42 ("ARM: dts: vf610-zii-dev: Add ZII development board.")
> Signed-off-by: Aswath Govindraju <a-govindraju at ti.com>

Applied, thanks!


From shawnguo at kernel.org  Fri Aug 13 22:53:29 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 13:53:29 +0800
Subject: [PATCH v1] ARM: dts: imx6qp-prtwd3: configure ENET_REF clock to
 125MHz
In-Reply-To: <20210811073835.32082-1-o.rempel@pengutronix.de>
References: <20210811073835.32082-1-o.rempel@pengutronix.de>
Message-ID: <20210814055328.GZ30984@dragon>

On Wed, Aug 11, 2021 at 09:38:35AM +0200, Oleksij Rempel wrote:
> By default ENET_REF is configured to 50MHz, which is usable for the RMII
> link. In case RGMII is used, we need 125MHz clock.
> 
> Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>

Applied, thanks!


From hch at lst.de  Sat Aug 14 00:03:16 2021
From: hch at lst.de (Christoph Hellwig)
Date: Sat, 14 Aug 2021 09:03:16 +0200
Subject: add support for the global coherent pool to the dma core
In-Reply-To: <20210712061704.4162464-1-hch@lst.de>
References: <20210712061704.4162464-1-hch@lst.de>
Message-ID: <20210814070316.GA20875@lst.de>

Any more comments?

Otherwise I'm going to pull this into the dma-mapping tree next week.


From heiko at sntech.de  Sat Aug 14 00:33:54 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 14 Aug 2021 09:33:54 +0200
Subject: [PATCH v3 0/7] arm64: dts: rockchip: rk3568-evb1-v10: add sd card
 support
In-Reply-To: <20210805120107.27007-1-michael.riesch@wolfvision.net>
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>
Message-ID: <162892642459.2674259.13856979859165200065.b4-ty@sntech.de>

On Thu, 5 Aug 2021 14:01:00 +0200, Michael Riesch wrote:
> This series enables the SD card reader on the RK3568 EVB1
> and completes the support for the on-board eMMC.
> 
> As the PMU IO domains are required, the patch series that
> introduces support for the RK3568 PMU IO domains [1] has been
> revised and integrated in this series.
> Additionally, the required voltage regulators of the RK809
> PMIC are enabled.
> 
> [...]

Applied, thanks!

[1/7] dt-bindings: power: add rk3568-pmu-io-domain support
      commit: fadbd4e7847905d61dd333a0d3d31654f4510bc6
[2/7] soc: rockchip: io-domain: add rk3568 support
      commit: 28b05a64e47cbceebb8a5f3f643033148d5c06c3
[3/7] arm64: dts: rockchip: enable io domains for rk356x
      commit: 2e9ce86bbea81022540ede98cac152df5566205e
[4/7] arm64: dts: rockchip: rk3568-evb1-v10: enable io domains
      commit: 915186bd99a55642ae77d7f9c46e295b3fd9dc1c
[5/7] arm64: dts: rockchip: rk3568-evb1-v10: add regulators of rk809 pmic
      commit: e3f6b997b6b17810583af79f458b35fc0a34d939
[6/7] arm64: dts: rockchip: rk3568-evb1-v10: add node for sd card
      commit: ef180dba76f583efc19c7d5f3d2809e0aa8856e8
[7/7] arm64: dts: rockchip: rk3568-evb1-v10: add pinctrl and alias to emmc node
      commit: eb8d07586e13fc7aa4ed68820240d36a03418193

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From marex at denx.de  Sat Aug 14 00:45:03 2021
From: marex at denx.de (Marek Vasut)
Date: Sat, 14 Aug 2021 09:45:03 +0200
Subject: [PATCH] ARM: imx_v6_v7_defconfig: enable driver of the LTC3676
 PMIC
In-Reply-To: <20210814054055.GX30984@dragon>
References: <20210805135035.124938-1-pzimmermann@dh-electronics.com>
 <54505ae8-075c-bc54-e039-0badc261fa27@denx.de>
 <20210814054055.GX30984@dragon>
Message-ID: <2a3e56b8-7fd7-44ec-4090-7fe2b5d7863c@denx.de>

On 8/14/21 7:40 AM, Shawn Guo wrote:
> On Tue, Aug 10, 2021 at 07:36:24AM +0200, Marek Vasut wrote:
>> On 8/5/21 3:50 PM, Pascal Zimmermann wrote:
>>> The LTC3676 is a PMIC which is used on some i.MX6 based boards (like the
>>> DHCOM i.MX6 Quad SoM), it was first used on the GW Ventana board, enable
>>> LTC3676 driver in imx_v6_v7_defconfig.
>>>
>>> Fixes: e3946fe805053 ("ARM: dts: add Gateworks Ventana support")
> 
> I don't think the Fixes tag is appropriate here.  Dropped it and applied
> patch.

Can you please elaborate why do you think the Fixes tag is not appropriate ?

Neither system can work properly without the PMIC driver, so I believe 
the Fixes tag is correct and this should be backported to older LTS 
kernel releases.

[...]

>>>    arch/arm/configs/imx_v6_v7_defconfig | 1 +
>>>    1 file changed, 1 insertion(+)
>>>
>>> diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
>>> index 079fcd8d1d11..f94e3d11c3e9 100644
>>> --- a/arch/arm/configs/imx_v6_v7_defconfig
>>> +++ b/arch/arm/configs/imx_v6_v7_defconfig
>>> @@ -252,6 +252,7 @@ CONFIG_REGULATOR_DA9052=y
>>>    CONFIG_REGULATOR_DA9062=y
>>>    CONFIG_REGULATOR_DA9063=y
>>>    CONFIG_REGULATOR_GPIO=y
>>> +CONFIG_REGULATOR_LTC3676=y
>>>    CONFIG_REGULATOR_MC13783=y
>>>    CONFIG_REGULATOR_MC13892=y
>>>    CONFIG_REGULATOR_PFUZE100=y
>>
>> Reviewed-by: Marek Vasut <marex at denx.de>
>> Tested-by: Marek Vasut <marex at denx.de> # On DH iMX6Q DHCOM PDK2
>>
>> Neither board can work well without a PMIC driver.

[...]


From maz at kernel.org  Sat Aug 14 02:38:30 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 14 Aug 2021 10:38:30 +0100
Subject: [PATCH 2/5] arm64: Handle UNDEF in the EL2 stub vectors
In-Reply-To: <060ef66a-6d6f-082e-5f69-117235b8ce4e@arm.com>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-3-maz@kernel.org>
 <2f6bf17f-d235-8311-13d5-dcb3d00e23c4@arm.com>
 <87im091bu7.wl-maz@kernel.org>
 <060ef66a-6d6f-082e-5f69-117235b8ce4e@arm.com>
Message-ID: <87h7fs1i3t.wl-maz@kernel.org>

On Fri, 13 Aug 2021 19:17:56 +0100,
Robin Murphy <robin.murphy at arm.com> wrote:
> 
> On 2021-08-13 18:41, Marc Zyngier wrote:
> > On Fri, 13 Aug 2021 14:08:23 +0100,
> > Robin Murphy <robin.murphy at arm.com> wrote:
> >> 
> >> On 2021-08-12 20:02, Marc Zyngier wrote:
> >>> As we want to handle the silly case where HVC has been disabled
> >>> from EL3, augment our ability to handle exception at EL2.
> >>> 
> >>> Check for unknown exceptions (usually UNDEF) coming from EL2,
> >>> and treat them as a failing HVC call into the stubs. While
> >>> this isn't great and obviously doesn't catter for the gigantic
> >>> range of possible exceptions, it isn't any worse than what we
> >>> have today.
> >>> 
> >>> Just don't try and use it for anything else.
> >>> 
> >>> Signed-off-by: Marc Zyngier <maz at kernel.org>
> >>> ---
> >>>    arch/arm64/kernel/hyp-stub.S | 19 ++++++++++++++++++-
> >>>    1 file changed, 18 insertions(+), 1 deletion(-)
> >>> 
> >>> diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> >>> index 43d212618834..026a34515b21 100644
> >>> --- a/arch/arm64/kernel/hyp-stub.S
> >>> +++ b/arch/arm64/kernel/hyp-stub.S
> >>> @@ -46,7 +46,16 @@ SYM_CODE_END(__hyp_stub_vectors)
> >>>    	.align 11
> >>>      SYM_CODE_START_LOCAL(elx_sync)
> >>> -	cmp	x0, #HVC_SET_VECTORS
> >>> +	mrs	x4, spsr_el2
> >>> +	and	x4, x4, #PSR_MODE_MASK
> >>> +	orr	x4, x4, #1
> >>> +	cmp	x4, #PSR_MODE_EL2h
> >>> +	b.ne	0f
> >>> +	mrs	x4, esr_el2
> >>> +	eor	x4, x4, #ESR_ELx_IL
> >>> +	cbz	x4, el2_undef
> >> 
> >> Hmm, might it be neater to check ESR_EL2.ISS to see if we landed here
> >> for any reason *other* than a successfully-executed HVC?
> > 
> > We absolutely could. However, the sixpence question (yes, that's the
> > Brexit effect for you) is "what do you do with exceptions that are
> > neither UNDEF now HVC?".
> > 
> > We are taking a leap of faith by assuming that the only thing that
> > will UNDEF at EL2 while the stubs are installed is HVC. If anything
> > else occurs, I have no idea what to do with it. I guess we could always
> > ignore it instead of treating it as a HVC (as it is done at the
> > moment).
> 
> Right, I think that concern applies pretty much equally whichever way
> you slice it. "Any exception other than an unknown from EL2 must imply
> HVC" doesn't seem any less sketchy than "Any exception other than HVC
> implies something is horribly wrong and abandoning EL2 might be wise"
> to me, but it was primarily that the latter avoids having to faff with
> the SPSR as well.

Actually, that's not a bad idea at all. Here's my take on the theme,
completely untested:

diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 43d212618834..5783dbab529f 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -46,6 +46,23 @@ SYM_CODE_END(__hyp_stub_vectors)
 	.align 11
 
 SYM_CODE_START_LOCAL(elx_sync)
+	// tpidr_el2 isn't used for anything while the stubs are
+	// installed, so use it to save x0 while we guess the
+	// exception type. No, we don't have a stack...
+	msr	tpidr_el2, x0
+	mrs	x0, esr_el2
+	ubfx	x0, x0, #26, #6
+	cmp	x0, #ESR_ELx_EC_HVC64
+	b.eq	elx_hvc
+	cbz	x0, elx_unknown
+
+	// For anything else, we have no reasonable way to handle
+	// the exception. Go back to the faulting instruction...
+	mrs	x0, tpidr_el2
+	eret
+
+elx_hvc:
+	mrs	x0, tpidr_el2
 	cmp	x0, #HVC_SET_VECTORS
 	b.ne	1f
 	msr	vbar_el2, x1
@@ -71,6 +88,14 @@ SYM_CODE_START_LOCAL(elx_sync)
 
 9:	mov	x0, xzr
 	eret
+
+elx_unknown:
+	// Assumes this was a HVC that went really wrong...
+	mrs	x0, elr_el2
+	add	x0, x0, #4
+	msr	elr_el2, x0
+	mov_q	x0, HVC_STUB_ERR
+	eret
 SYM_CODE_END(elx_sync)
 
 // nVHE? No way! Give me the real thing!


> No big deal either way, just one of my "I reckon this could be
> shorter..." musings; it's been particularly Friday today :)

Well, I just made it a lot longer! :D Let me know what you think.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From shawnguo at kernel.org  Sat Aug 14 04:24:25 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 19:24:25 +0800
Subject: [PATCH] ARM: imx_v6_v7_defconfig: enable driver of the LTC3676
 PMIC
In-Reply-To: <2a3e56b8-7fd7-44ec-4090-7fe2b5d7863c@denx.de>
References: <20210805135035.124938-1-pzimmermann@dh-electronics.com>
 <54505ae8-075c-bc54-e039-0badc261fa27@denx.de>
 <20210814054055.GX30984@dragon>
 <2a3e56b8-7fd7-44ec-4090-7fe2b5d7863c@denx.de>
Message-ID: <20210814112424.GA9470@dragon>

On Sat, Aug 14, 2021 at 09:45:03AM +0200, Marek Vasut wrote:
> On 8/14/21 7:40 AM, Shawn Guo wrote:
> > On Tue, Aug 10, 2021 at 07:36:24AM +0200, Marek Vasut wrote:
> > > On 8/5/21 3:50 PM, Pascal Zimmermann wrote:
> > > > The LTC3676 is a PMIC which is used on some i.MX6 based boards (like the
> > > > DHCOM i.MX6 Quad SoM), it was first used on the GW Ventana board, enable
> > > > LTC3676 driver in imx_v6_v7_defconfig.
> > > > 
> > > > Fixes: e3946fe805053 ("ARM: dts: add Gateworks Ventana support")
> > 
> > I don't think the Fixes tag is appropriate here.  Dropped it and applied
> > patch.
> 
> Can you please elaborate why do you think the Fixes tag is not appropriate ?
> 
> Neither system can work properly without the PMIC driver, so I believe the
> Fixes tag is correct and this should be backported to older LTS kernel
> releases.

It's enabling a feature (driver) rather than fixing a bug or regression.
If you want to enable it for LTS kernel, go ahead to back port it.
Do not abuse the Fixes tag.

Shawn


From lkp at intel.com  Sat Aug 14 05:15:23 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 14 Aug 2021 20:15:23 +0800
Subject: [xlnx:xlnx_rebase_v5.10 863/1761]
 drivers/crypto/xilinx/zynqmp-sha.c:116:3: error: implicit declaration of
 function '__flush_cache_user_range'
Message-ID: <202108142017.bJz6Tcvw-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   e14d4574ca81a569ee6d07e03271f2ae2dad38e4
commit: cfd28773b697fdbf45ddac80813ce6b141a21725 [863/1761] crypto: zynqmp-sha: Adopted SHA3 support for ZynqMP Soc
config: s390-randconfig-r012-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/cfd28773b697fdbf45ddac80813ce6b141a21725
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout cfd28773b697fdbf45ddac80813ce6b141a21725
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:19:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x000000ffUL) << 24) |            \
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-sha.c:9:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-sha.c:9:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-sha.c:9:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-sha.c:9:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32'
           __fswab32(x))
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-sha.c:9:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> drivers/crypto/xilinx/zynqmp-sha.c:116:3: error: implicit declaration of function '__flush_cache_user_range' [-Werror,-Wimplicit-function-declaration]
            __flush_cache_user_range((unsigned long)kbuf,
            ^
   drivers/crypto/xilinx/zynqmp-sha.c:116:3: note: did you mean 'flush_icache_user_page'?
   include/asm-generic/cacheflush.h:86:20: note: 'flush_icache_user_page' declared here
   static inline void flush_icache_user_page(struct vm_area_struct *vma,
                      ^
   20 warnings and 1 error generated.


vim +/__flush_cache_user_range +116 drivers/crypto/xilinx/zynqmp-sha.c

    98	
    99	static int zynqmp_sha_update(struct ahash_request *req)
   100	{
   101		struct zynqmp_sha_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
   102		struct zynqmp_sha_dev *dd = tctx->dd;
   103		char *kbuf;
   104		size_t dma_size = req->nbytes;
   105		dma_addr_t dma_addr;
   106		int ret;
   107	
   108		if (!req->nbytes)
   109			return 0;
   110	
   111		kbuf = dma_alloc_coherent(dd->dev, dma_size, &dma_addr, GFP_KERNEL);
   112		if (!kbuf)
   113			return -ENOMEM;
   114	
   115		scatterwalk_map_and_copy(kbuf, req->src, 0, req->nbytes, 0);
 > 116		 __flush_cache_user_range((unsigned long)kbuf,
   117					  (unsigned long)kbuf + dma_size);
   118		ret = zynqmp_pm_sha_hash(dma_addr, req->nbytes, ZYNQMP_SHA3_UPDATE); 
   119		dma_free_coherent(dd->dev, dma_size, kbuf, dma_addr);
   120	
   121		return ret;
   122	}
   123	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 32748 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210814/1c3c16c3/attachment-0001.gz>

From tangbin at cmss.chinamobile.com  Sat Aug 14 05:49:51 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Sat, 14 Aug 2021 20:49:51 +0800
Subject: [PATCH] serial: stm32: use the defined variable to simplify code
Message-ID: <20210814124951.30084-1-tangbin@cmss.chinamobile.com>

Use the defined variable 'dev' to make the code cleaner.

Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 drivers/tty/serial/stm32-usart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index d4ea86e28..8f032e77b 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -1176,7 +1176,7 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port,
 	if (uart_console(port))
 		return -ENODEV;
 
-	stm32port->rx_buf = dma_alloc_coherent(&pdev->dev, RX_BUF_L,
+	stm32port->rx_buf = dma_alloc_coherent(dev, RX_BUF_L,
 					       &stm32port->rx_dma_buf,
 					       GFP_KERNEL);
 	if (!stm32port->rx_buf)
@@ -1242,7 +1242,7 @@ static int stm32_usart_of_dma_tx_probe(struct stm32_port *stm32port,
 
 	stm32port->tx_dma_busy = false;
 
-	stm32port->tx_buf = dma_alloc_coherent(&pdev->dev, TX_BUF_L,
+	stm32port->tx_buf = dma_alloc_coherent(dev, TX_BUF_L,
 					       &stm32port->tx_dma_buf,
 					       GFP_KERNEL);
 	if (!stm32port->tx_buf)
-- 
2.20.1.windows.1





From tangbin at cmss.chinamobile.com  Sat Aug 14 06:14:18 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Sat, 14 Aug 2021 21:14:18 +0800
Subject: [PATCH] serial: stm32: use devm_platform_get_and_ioremap_resource()
Message-ID: <20210814131418.13608-1-tangbin@cmss.chinamobile.com>

Use devm_platform_get_and_ioremap_resource() to simplify code.

Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 drivers/tty/serial/stm32-usart.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 090822cd1..d4ea86e28 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -1064,8 +1064,7 @@ static int stm32_usart_init_port(struct stm32_port *stm32port,
 				      &stm32port->txftcfg);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	port->membase = devm_ioremap_resource(&pdev->dev, res);
+	port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 	port->mapbase = res->start;
-- 
2.20.1.windows.1





From festevam at gmail.com  Sat Aug 14 06:25:24 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Sat, 14 Aug 2021 10:25:24 -0300
Subject: [PATCH 1/2] arm64: dts: imx8mm-kontron-n801x-som: Fix the SPI
 chipselect polarity
In-Reply-To: <59bb828e-2a2c-ba3e-8c33-17342197f2ff@kontron.de>
References: <20210716132845.3371666-1-festevam@gmail.com>
 <59bb828e-2a2c-ba3e-8c33-17342197f2ff@kontron.de>
Message-ID: <CAOMZO5DxYSMw1siH=YBkoZ=oz+aZjgaGhfkemT=ErmxYqViN_w@mail.gmail.com>

Hi Shawn,

On Mon, Jul 19, 2021 at 7:55 AM Frieder Schrempf
<frieder.schrempf at kontron.de> wrote:

> Thanks for the fix!
>
> Reviewed-by: Frieder Schrempf <frieder.schrempf at kontron.de>
>
> Shouldn't we consider to add the following tag, as this is clearly a bug in the original implementation of the DTS and the commit that uncovers this is already in multiple stable releases?
>
> Fixes: 8668d8b2e67f ("arm64: dts: Add the Kontron i.MX8M Mini SoMs and baseboards")

Can you add the Fixes tag, or should I resend it?

Thanks


From festevam at gmail.com  Sat Aug 14 06:27:13 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Sat, 14 Aug 2021 10:27:13 -0300
Subject: [PATCH 1/4] ARM: dts: imx6dl-alti6p: Fix the SPI chipselect
 polarity
In-Reply-To: <20210717045741.shvni526xvo4bzcf@pengutronix.de>
References: <20210716133659.3372047-1-festevam@gmail.com>
 <20210717045741.shvni526xvo4bzcf@pengutronix.de>
Message-ID: <CAOMZO5Ba=M9vRZHk+tKjBCUa+mAULhiGG6Y+uefQE3RYGAnF3w@mail.gmail.com>

Hi Shawn,

On Sat, Jul 17, 2021 at 1:57 AM Oleksij Rempel <o.rempel at pengutronix.de> wrote:
>
> On Fri, Jul 16, 2021 at 10:36:56AM -0300, Fabio Estevam wrote:
> > The conversion of the spi-imx driver to use GPIO descriptors
> > in commit 8cdcd8aeee28 ("spi: imx/fsl-lpspi: Convert to GPIO descriptors")
> > helped to detect the following SPI chipselect polarity mismatch on an
> > imx6q-sabresd for example:
> >
> > [    4.854337] m25p80 at 0 enforce active low on chipselect handle
> >
> > Prior to the above commit, the chipselect polarity passed via cs-gpios
> > property was ignored and considered active-low.
> >
> > The reason for such mismatch is clearly explained in the comments inside
> > drivers/gpio/gpiolib-of.c:
> >
> > * SPI children have active low chip selects
> > * by default. This can be specified negatively
> > * by just omitting "spi-cs-high" in the
> > * device node, or actively by tagging on
> > * GPIO_ACTIVE_LOW as flag in the device
> > * tree. If the line is simultaneously
> > * tagged as active low in the device tree
> > * and has the "spi-cs-high" set, we get a
> > * conflict and the "spi-cs-high" flag will
> > * take precedence.
> >
> > To properly represent the SPI chipselect polarity, change it to active-low
> > when the "spi-cs-high" property is absent.
> >
> > Signed-off-by: Fabio Estevam <festevam at gmail.com>
>
> Reviewed-by: Oleksij Rempel <o.rempel at pengutronix.de>
> Thank you!

A gentle ping on this series.


From shawnguo at kernel.org  Sat Aug 14 06:38:50 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 21:38:50 +0800
Subject: [GIT PULL 1/4] i.MX DT bindings update for 5.15
Message-ID: <20210814133853.9981-1-shawnguo@kernel.org>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-bindings-5.15

for you to fetch changes up to 0fdedc09af18d231aa581331821c9ab6ef0903f1:

  dt-bindings: arm: fsl: Add Traverse Ten64 (LS1088A) board (2021-08-14 13:52:36 +0800)

----------------------------------------------------------------
i.MX DT bindings update for 5.15:

- Add vendor prefix for MNT Research GmbH, SKOV A/S and Traverse
  Technologies.
- Add compatible for Nitrogen8 SoM, MNT Reform2, Traverse Ten64,
  SKOV i.MX6, SolidSense and i.MX8M GW7902 boards.
- Add compatible for i.MX8QM JPEG codec.

----------------------------------------------------------------
Christoph Niedermaier (1):
      dt-bindings: arm: fsl: Add DHCOM PicoITX and DHCOM DRC02 boards

Lucas Stach (3):
      dt-bindings: arm: fsl: add Nitrogen8 SoM
      dt-bindings: vendor-prefixes: add mntre
      dt-bindings: arm: fsl: add MNT Reform2 board

Mathew McBride (2):
      dt-bindings: vendor-prefixes: add Traverse Technologies
      dt-bindings: arm: fsl: Add Traverse Ten64 (LS1088A) board

Mirela Rabulea (1):
      dt-bindings: media: imx-jpeg: Add compatible for i.MX8QM JPEG codec

Oleksij Rempel (2):
      dt-bindings: vendor-prefixes: Add an entry for SKOV A/S
      dt-bindings: arm: fsl: add SKOV imx6q and imx6dl based boards

Russell King (Oracle) (1):
      dt-bindings: arm: fsl: add SolidSense boards

Tim Harvey (1):
      dt-bindings: arm: imx: add imx8mm/imx8mn GW7902 support

 Documentation/devicetree/bindings/arm/fsl.yaml     | 29 ++++++++++++++++++++++
 .../devicetree/bindings/media/nxp,imx8-jpeg.yaml   | 19 ++++++++------
 .../devicetree/bindings/vendor-prefixes.yaml       |  6 +++++
 3 files changed, 47 insertions(+), 7 deletions(-)


From shawnguo at kernel.org  Sat Aug 14 06:38:51 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 21:38:51 +0800
Subject: [GIT PULL 2/4] i.MX arm32 device tree changes for 5.15
In-Reply-To: <20210814133853.9981-1-shawnguo@kernel.org>
References: <20210814133853.9981-1-shawnguo@kernel.org>
Message-ID: <20210814133853.9981-2-shawnguo@kernel.org>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-dt-5.15

for you to fetch changes up to 87a8c7164022d2e5c558bc0e14075c7a50af7f95:

  ARM: dts: imx6qp-prtwd3: configure ENET_REF clock to 125MHz (2021-08-14 13:45:58 +0800)

----------------------------------------------------------------
i.MX arm32 device tree changes for 5.15:

- A series from Christoph Niedermaier to clean up i.MX6 DHCOM support.
- New board support: DHCOM based PicoITX, DHSOM based DRC02, SolidRun
  SolidSense, SKOV i.MX6 boards.
- Add WiFi support for i.MX7D base reMkarkable2 device.
- Add FTM devices for i.MX7 to have Flex Timers support.
- Configure ENET_REF clock to 125MHz for imx6qp-prtwd3 to support RGMII
  PHY mode.
- Drop unneeded #address-cells and #size-cells from vf610-zii SPI EEPROM
  device node.
- Add missing USB OTG OC pinmux and Crypto device for i.MX6QDL Gateworks
  boards.

----------------------------------------------------------------
Alistair Francis (1):
      ARM: dts: imx7d-remarkable2: Add WiFi support

Aswath Govindraju (1):
      ARM: dts: vf610-zii-dev-rev-b: Remove #address-cells and #size-cells property from at93c46d dt node

Christoph Niedermaier (15):
      ARM: dts: imx6q-dhcom: Add the parallel system bus
      ARM: dts: imx6q-dhcom: Add interrupt and compatible to the ethernet PHY
      ARM: dts: imx6q-dhcom: Fill GPIO line names on DHCOM SoM
      ARM: dts: imx6q-dhcom: Adding Wake pin to the PCIe pinctrl
      ARM: dts: imx6q-dhcom: Align stdout-path with other DHCOM SoMs
      ARM: dts: imx6q-dhcom: Add keys and leds to the PDK2 board
      ARM: dts: imx6q-dhcom: Remove ddc-i2c-bus property
      ARM: dts: imx6q-dhcom: Set minimum memory size of all DHCOM i.MX6 variants
      ARM: dts: imx6q-dhcom: Use 1G ethernet on the PDK2 board
      ARM: dts: imx6q-dhcom: Rework of the DHCOM GPIO pinctrls
      ARM: dts: imx6q-dhcom: Rearrange of iomux
      ARM: dts: imx6q-dhcom: Cleanup of the devicetrees
      ARM: dts: imx6qdl-dhcom: Split SoC-independent parts of DHCOM SOM and PDK2
      ARM: dts: imx6qdl-dhcom: Add DHCOM based PicoITX board
      ARM: dts: imx6qdl-dhcom: Add DHSOM based DRC02 board

Oleksij Rempel (1):
      ARM: dts: imx6qp-prtwd3: configure ENET_REF clock to 125MHz

Russell King (1):
      ARM: dts: add SolidRun SolidSense support

Sam Ravnborg (1):
      ARM: dts: add SKOV imx6q and imx6dl based boards

Thomas Perrot (1):
      ARM: dts: imx7: add ftm nodes for Flex Timers

Tim Harvey (2):
      ARM: dts: imx6qdl-gw5xxx: add missing USB OTG OC pinmux
      ARM: dts: imx6qdl-gw5904: atecc508a support

 arch/arm/boot/dts/Makefile                         |  11 +-
 arch/arm/boot/dts/imx6dl-dhcom-picoitx.dts         |  20 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts         |  13 +
 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts         | 106 ++++
 arch/arm/boot/dts/imx6dl-solidsense.dts            |  54 ++
 arch/arm/boot/dts/imx6q-dhcom-pdk2.dts             | 270 +--------
 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts          |  36 ++
 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts          | 128 +++++
 .../boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts    | 127 +++++
 arch/arm/boot/dts/imx6q-solidsense.dts             |  54 ++
 arch/arm/boot/dts/imx6qdl-dhcom-drc02.dtsi         | 139 +++++
 arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi          | 361 ++++++++++++
 arch/arm/boot/dts/imx6qdl-dhcom-picoitx.dtsi       |  69 +++
 ...imx6q-dhcom-som.dtsi => imx6qdl-dhcom-som.dtsi} | 631 +++++++++++++++------
 arch/arm/boot/dts/imx6qdl-gw51xx.dtsi              |   1 +
 arch/arm/boot/dts/imx6qdl-gw52xx.dtsi              |   1 +
 arch/arm/boot/dts/imx6qdl-gw54xx.dtsi              |   1 +
 arch/arm/boot/dts/imx6qdl-gw553x.dtsi              |   1 +
 arch/arm/boot/dts/imx6qdl-gw5904.dtsi              |   5 +
 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi       |  54 ++
 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi            | 477 ++++++++++++++++
 arch/arm/boot/dts/imx6qdl-solidsense.dtsi          | 160 ++++++
 arch/arm/boot/dts/imx6qp-prtwd3.dts                |   2 +
 arch/arm/boot/dts/imx6s-dhcom-drc02.dts            |  30 +
 arch/arm/boot/dts/imx7d-remarkable2.dts            |  91 +++
 arch/arm/boot/dts/imx7s.dtsi                       |  28 +
 arch/arm/boot/dts/vf610-zii-dev-rev-b.dts          |   2 -
 27 files changed, 2431 insertions(+), 441 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx6dl-dhcom-picoitx.dts
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6dl-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6dl-solidsense.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt2.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-revc-lt6.dts
 create mode 100644 arch/arm/boot/dts/imx6q-skov-reve-mi1010ait-1cp1.dts
 create mode 100644 arch/arm/boot/dts/imx6q-solidsense.dts
 create mode 100644 arch/arm/boot/dts/imx6qdl-dhcom-drc02.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-dhcom-pdk2.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-dhcom-picoitx.dtsi
 rename arch/arm/boot/dts/{imx6q-dhcom-som.dtsi => imx6qdl-dhcom-som.dtsi} (57%)
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu-revc.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-skov-cpu.dtsi
 create mode 100644 arch/arm/boot/dts/imx6qdl-solidsense.dtsi
 create mode 100644 arch/arm/boot/dts/imx6s-dhcom-drc02.dts


From shawnguo at kernel.org  Sat Aug 14 06:38:52 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 21:38:52 +0800
Subject: [GIT PULL 3/4] i.MX arm64 device tree changes for 5.15
In-Reply-To: <20210814133853.9981-1-shawnguo@kernel.org>
References: <20210814133853.9981-1-shawnguo@kernel.org>
Message-ID: <20210814133853.9981-3-shawnguo@kernel.org>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-dt64-5.15

for you to fetch changes up to 418962eea35869b8e07766d8728ae660d75800a9:

  arm64: dts: add device tree for Traverse Ten64 (LS1088A) (2021-08-14 13:51:28 +0800)

----------------------------------------------------------------
i.MX arm64 device tree changes for 5.15:

- New board support: Nitrogen8 SoM and MNT Reform2, LS1088A based
  Traverse Ten64, i.MX8M based GW7902.
- A series from Ioana Ciornei to update PHY IRQ configuration for
  LayerScape SoCs.
- A series from Tim Harvey to update Gateworks imx8mm-venice devices.
- Replace deprecated `fsl,usbphy` property with phys phandle.
- Add MIPI CSI phy and bridge descriptions for i.MX8MQ SoC.
- Add JPEG encoder/decoder device nodes for i.MX8M SoCs.
- Update PMU compatible and drop interrupt-affinity for i.MX8M SoCs.
- Add Cadence HIFI4 DSP for i.MX8 MPlus SoC.
- A few small and random updates on various boards.

----------------------------------------------------------------
Daniel Baluta (1):
      arm64: dts: imx8mp: Add dsp node

Fabio Estevam (1):
      arm64: dts: imx8mm-venice-gw7901: Remove unnecessary #address-cells/#size-cells

Ioana Ciornei (3):
      arm64: dts: lx2160ardb: update PHY nodes with IRQ information
      arm64: dts: ls2088ardb: update PHY nodes with IRQ information
      arm64: dts: ls1088ardb: update PHY nodes with IRQ information

Kwon Tae-young (3):
      arm64: dts: imx8qxp-ai_ml: Fix checkpatch warnings
      arm64: dts: imx8mq-evk: add CD pinctrl for usdhc2
      arm64: dts: imx8mq-evk: Remove unnecessary blank lines

Lucas Stach (3):
      arm64: dts: imx8mq: add Nitrogen8 SoM
      arm64: dts: imx8mq: add support for MNT Reform2
      arm64: dts: imx8mq-reform2: add sound support

Marek Vasut (1):
      arm64: dts: imx8m: Replace deprecated fsl,usbphy DT props with phys

Martin Kepplinger (1):
      arm64: dts: imx8mq: add mipi csi phy and csi bridge descriptions

Mathew McBride (3):
      arm64: dts: ls1088a: add internal PCS for DPMAC1 node
      arm64: dts: ls1088a: add missing PMU node
      arm64: dts: add device tree for Traverse Ten64 (LS1088A)

Mirela Rabulea (1):
      arm64: dts: imx8: Add jpeg encoder/decoder nodes

Peng Fan (3):
      arm64: dts: imx8mm: update pmu compatible
      arm64: dts: imx8qxp: update pmu compatible
      arm64: dts: imx8m: drop interrupt-affinity for pmu

Raag Jadav (1):
      arm64: dts: ls1046a: fix eeprom entries

Tim Harvey (6):
      arm64: dts: imx: Add i.mx8mm/imx8mn Gateworks gw7902 dts support
      arm64: dts: imx8mm-venice-gw700x: fix mp5416 pmic config
      arm64: dts: imx8mm-venice-gw700x: fix invalid pmic pin config
      arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS
      arm64: dts: imx8mm-venice-gw7901: add support for USB hub subload
      arm64: dts: imx8mm-venice-gw7901: enable pull-down on gpio outputs

 arch/arm64/boot/dts/freescale/Makefile             |   4 +
 arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts |   8 +-
 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts  |   7 +-
 arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts  |   9 +
 .../arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts | 389 +++++++++
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi     |  18 +
 arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts  |   4 +
 arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts  |   4 +
 arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi     |  80 ++
 .../boot/dts/freescale/imx8mm-venice-gw700x.dtsi   |  64 +-
 .../boot/dts/freescale/imx8mm-venice-gw71xx.dtsi   |   5 +-
 .../boot/dts/freescale/imx8mm-venice-gw7901.dts    |  15 +-
 .../boot/dts/freescale/imx8mm-venice-gw7902.dts    | 911 +++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mm.dtsi          |   9 +-
 .../boot/dts/freescale/imx8mn-venice-gw7902.dts    | 884 ++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mn.dtsi          |   4 +-
 arch/arm64/boot/dts/freescale/imx8mp.dtsi          |  31 +-
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts       |  14 +-
 .../boot/dts/freescale/imx8mq-mnt-reform2.dts      | 213 +++++
 .../boot/dts/freescale/imx8mq-nitrogen-som.dtsi    | 275 +++++++
 arch/arm64/boot/dts/freescale/imx8mq.dtsi          | 105 ++-
 arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi   |  12 +
 arch/arm64/boot/dts/freescale/imx8qm.dtsi          |   2 +
 arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dts    |   2 +-
 arch/arm64/boot/dts/freescale/imx8qxp-ss-img.dtsi  |  13 +
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi         |   4 +-
 26 files changed, 3021 insertions(+), 65 deletions(-)
 create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mq-nitrogen-som.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qm-ss-img.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8qxp-ss-img.dtsi


From shawnguo at kernel.org  Sat Aug 14 06:38:53 2021
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 14 Aug 2021 21:38:53 +0800
Subject: [GIT PULL 4/4] i.MX defconfig update for 5.15
In-Reply-To: <20210814133853.9981-1-shawnguo@kernel.org>
References: <20210814133853.9981-1-shawnguo@kernel.org>
Message-ID: <20210814133853.9981-4-shawnguo@kernel.org>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-defconfig-5.15

for you to fetch changes up to 7fd19c58e48fb774de9190f27f2b06a6526f2d3c:

  ARM: imx_v6_v7_defconfig: enable driver of the LTC3676 PMIC (2021-08-14 13:38:42 +0800)

----------------------------------------------------------------
i.MX defconfig update for 5.15:

- Enable LTC3676 PMIC, SCSI_LOWLEVEL and KPROBES support in
  imx_v6_v7_defconfig.

----------------------------------------------------------------
Fabio Estevam (2):
      ARM: imx_v6_v7_defconfig: Select CONFIG_KPROBES
      ARM: imx_v6_v7_defconfig: Let CONFIG_SCSI_LOWLEVEL be selected

Pascal Zimmermann (1):
      ARM: imx_v6_v7_defconfig: enable driver of the LTC3676 PMIC

 arch/arm/configs/imx_v6_v7_defconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)


From daniel.lezcano at linaro.org  Sat Aug 14 06:42:48 2021
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Sat, 14 Aug 2021 15:42:48 +0200
Subject: [PATCH 33/54] dt-bindings: thermal: Make trips node optional
In-Reply-To: <20210721140424.725744-34-maxime@cerno.tech>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-34-maxime@cerno.tech>
Message-ID: <f0ca864a-ec20-4ad3-8876-6d73eae4a779@linaro.org>

On 21/07/2021 16:04, Maxime Ripard wrote:
> Even though the previous binding made it a required child node, the
> implementation in Linux never made it mandatory and just ignored thermal
> zones without trip points.
> 
> This was even effectively encouraged, since the thermal core wouldn't
> allow a thermal sensor to probe without a thermal zone.
> 
> In the case where you had a thermal device that had multiple sensors but
> with enough knowledge to provide trip points for only a few of them,
> this meant that the only way to make that driver probe was to provide a
> thermal zone without the trips node required by the binding.
> 
> This obviously led to a fair number of device trees doing exactly that,
> making the initial binding requirement ineffective.
> 
> Let's make it clear by dropping that requirement.
> 
> Cc: Amit Kucheria <amitk at kernel.org>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: linux-pm at vger.kernel.org
> Cc: Zhang Rui <rui.zhang at intel.com>
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>

Applied, thanks!

  -- D.


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From kjain at linux.ibm.com  Sat Aug 14 06:54:10 2021
From: kjain at linux.ibm.com (kajoljain)
Date: Sat, 14 Aug 2021 19:24:10 +0530
Subject: [PATCH 1/2] drivers: perf: Add LLC-TAD perf counter support
In-Reply-To: <20210812174209.1970-2-bbudiredla@marvell.com>
References: <20210812174209.1970-1-bbudiredla@marvell.com>
 <20210812174209.1970-2-bbudiredla@marvell.com>
Message-ID: <e006077a-a60b-2772-bdca-58d8c68550a7@linux.ibm.com>



On 8/12/21 11:12 PM, Bhaskara Budiredla wrote:
> This driver adds support for Last-level cache tag-and-data unit
> (LLC-TAD) PMU that is featured in some of the Marvell's CN10K
> infrastructure silicons.
> 
> The LLC is divided into 2N slices distributed across N Mesh tiles
> in a single-socket configuration. The driver always configures the
> same counter for all of the TADs. The user would end up effectively
> reserving one of eight counters in every TAD to look across all TADs.
> The occurrences of events are aggregated and presented to the user
> at the end of an application run. The driver does not provide a way
> for the user to partition TADs so that different TADs are used for
> different applications.
> 
> The event counters are zeroed on start event counting to avoid any
> rollover issues. TAD perf counters are 64-bit, so it's not currently
> possible to overflow event counters at current mesh and core
> frequencies.
> 
> To measure tad pmu events use perf tool stat command. For instance:
> 
> perf stat -e tad_dat_msh_in_dss,tad_req_msh_out_any <application>
> perf stat -e tad_alloc_any,tad_hit_any,tad_tag_rd <application>
> 
> Signed-off-by: Bhaskara Budiredla <bbudiredla at marvell.com>
> ---
>  drivers/perf/Kconfig                 |   7 +
>  drivers/perf/Makefile                |   1 +
>  drivers/perf/marvell_cn10k_tad_pmu.c | 429 +++++++++++++++++++++++++++
>  3 files changed, 437 insertions(+)
>  create mode 100644 drivers/perf/marvell_cn10k_tad_pmu.c
> 
> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
> index 77522e5efe11..73dca11f8080 100644
> --- a/drivers/perf/Kconfig
> +++ b/drivers/perf/Kconfig
> @@ -137,6 +137,13 @@ config ARM_DMC620_PMU
>  	  Support for PMU events monitoring on the ARM DMC-620 memory
>  	  controller.
>  
> +config MARVELL_CN10K_TAD_PMU
> +	tristate "Marvell CN10K LLC-TAD PMU"
> +	depends on ARM64
> +	help
> +	  Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
> +	  performance monitors on CN10K family silicons.
> +
>  source "drivers/perf/hisilicon/Kconfig"
>  
>  endmenu
> diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
> index 5260b116c7da..2db5418d5b0a 100644
> --- a/drivers/perf/Makefile
> +++ b/drivers/perf/Makefile
> @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
>  obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
>  obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
>  obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
> +obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
> diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
> new file mode 100644
> index 000000000000..fec8b90d52d2
> --- /dev/null
> +++ b/drivers/perf/marvell_cn10k_tad_pmu.c
> @@ -0,0 +1,429 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Marvell CN10K LLC-TAD perf driver
> + *
> + * Copyright (C) 2021 Marvell.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#define pr_fmt(fmt) "tad_pmu: " fmt
> +
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/cpuhotplug.h>
> +#include <linux/perf_event.h>
> +#include <linux/platform_device.h>
> +#include <linux/arm-smccc.h>
> +
> +#define TAD_PFC_OFFSET		0x0800
> +#define TAD_PFC(counter)	(TAD_PFC_OFFSET | (counter << 3))
> +#define TAD_PRF_OFFSET		0x0900
> +#define TAD_PRF(counter)	(TAD_PRF_OFFSET | (counter << 3))
> +#define TAD_PRF_CNTSEL_MASK	0xFF
> +#define TAD_MAX_COUNTERS	8
> +
> +#define to_tad_pmu(p) (container_of(p, struct tad_pmu, pmu))
> +
> +struct tad_region {
> +	void __iomem	*base;
> +};
> +
> +struct tad_pmu {
> +	struct pmu pmu;
> +	struct tad_region *regions;
> +	u32 region_cnt;
> +	unsigned int cpu;
> +	struct hlist_node node;
> +	struct perf_event *events[TAD_MAX_COUNTERS];
> +	DECLARE_BITMAP(counters_map, TAD_MAX_COUNTERS);
> +};
> +
> +static int tad_pmu_cpuhp_state;
> +
> +static void tad_pmu_event_counter_read(struct perf_event *event)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	u32 counter_idx = hwc->idx;
> +	u64 delta, prev, new;
> +	int i;
> +
> +	do {
> +		prev = local64_read(&hwc->prev_count);
> +		for (i = 0, new = 0; i < tad_pmu->region_cnt; i++)
> +			new += readq(tad_pmu->regions[i].base +
> +				     TAD_PFC(counter_idx));
> +	} while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev);
> +
> +	delta = (new - prev) & GENMASK_ULL(63, 0);
> +	local64_add(delta, &event->count);
> +}
> +
> +static void tad_pmu_event_counter_stop(struct perf_event *event, int flags)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	u32 counter_idx = hwc->idx;
> +	int i;
> +
> +	/* TAD()_PFC() stop counting on the write
> +	 * which sets TAD()_PRF()[CNTSEL] == 0
> +	 */
> +	for (i = 0; i < tad_pmu->region_cnt; i++)
> +		writeq_relaxed(0, tad_pmu->regions[i].base +
> +			       TAD_PRF(counter_idx));
> +
> +	tad_pmu_event_counter_read(event);
> +	hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
> +}
> +
> +static void tad_pmu_event_counter_start(struct perf_event *event, int flags)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	u32 event_idx = event->attr.config;
> +	u32 counter_idx = hwc->idx;
> +	u64 reg_val;
> +	int i;
> +
> +	hwc->state = 0;
> +
> +	/* Typically TAD_PFC() are zeroed to start counting */
> +	for (i = 0; i < tad_pmu->region_cnt; i++)
> +		writeq_relaxed(0, tad_pmu->regions[i].base +
> +			       TAD_PFC(counter_idx));
> +
> +	/* TAD()_PFC() start counting on the write
> +	 * which sets TAD()_PRF()[CNTSEL] != 0
> +	 */
> +	for (i = 0; i < tad_pmu->region_cnt; i++) {
> +		reg_val = readq_relaxed(tad_pmu->regions[i].base +
> +					TAD_PRF(counter_idx));
> +		reg_val |= (event_idx & 0xFF);
> +		writeq_relaxed(reg_val,	tad_pmu->regions[i].base +
> +			       TAD_PRF(counter_idx));
> +	}
> +}
> +
> +static void tad_pmu_event_counter_del(struct perf_event *event, int flags)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int idx = hwc->idx;
> +
> +	tad_pmu_event_counter_stop(event, flags | PERF_EF_UPDATE);
> +	tad_pmu->events[idx] = NULL;
> +	clear_bit(idx, tad_pmu->counters_map);
> +}
> +
> +static int tad_pmu_event_counter_add(struct perf_event *event, int flags)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int idx;
> +
> +	/* Get a free counter for this event */
> +	idx = find_first_zero_bit(tad_pmu->counters_map, TAD_MAX_COUNTERS);
> +	if (idx == TAD_MAX_COUNTERS)
> +		return -EAGAIN;
> +
> +	set_bit(idx, tad_pmu->counters_map);
> +
> +	hwc->idx = idx;
> +	hwc->state = PERF_HES_STOPPED;
> +	tad_pmu->events[idx] = event;
> +
> +	if (flags & PERF_EF_START)
> +		tad_pmu_event_counter_start(event, flags);
> +
> +	return 0;
> +}
> +
> +static int tad_pmu_event_init(struct perf_event *event)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
> +
> +	if (!event->attr.disabled)
> +		return -EINVAL;
> +
> +	if (event->attr.type != event->pmu->type)
> +		return -ENOENT;
> +
> +	if (event->state != PERF_EVENT_STATE_OFF)
> +		return -EINVAL;
> +
> +	event->cpu = tad_pmu->cpu;
> +	event->hw.idx = -1;
> +	event->hw.config_base = event->attr.config;
> +
> +	return 0;
> +}
> +
> +static ssize_t tad_pmu_event_show(struct device *dev,
> +				struct device_attribute *attr, char *page)
> +{
> +	struct perf_pmu_events_attr *pmu_attr;
> +
> +	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
> +	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
> +}
> +
> +#define TAD_PMU_EVENT_ATTR(name, config)			\
> +	PMU_EVENT_ATTR_ID(name, tad_pmu_event_show, config)
> +
> +static struct attribute *tad_pmu_event_attrs[] = {
> +	TAD_PMU_EVENT_ATTR(tad_none, 0x0),
> +	TAD_PMU_EVENT_ATTR(tad_req_msh_in_any, 0x1),
> +	TAD_PMU_EVENT_ATTR(tad_req_msh_in_mn, 0x2),
> +	TAD_PMU_EVENT_ATTR(tad_req_msh_in_exlmn, 0x3),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_any, 0x4),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_mn, 0x5),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_exlmn, 0x6),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_dss, 0x7),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_retry_dss, 0x8),
> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_in_any, 0x9),
> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_in_dss, 0xa),
> +	TAD_PMU_EVENT_ATTR(tad_req_msh_out_any, 0xb),
> +	TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_rd, 0xc),
> +	TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_wr, 0xd),
> +	TAD_PMU_EVENT_ATTR(tad_req_msh_out_evict, 0xe),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_any, 0xf),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_retry_exlmn, 0x10),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_retry_mn, 0x11),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_exlmn, 0x12),
> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_mn, 0x13),
> +	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_any, 0x14),
> +	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_mn, 0x15),
> +	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_exlmn, 0x16),
> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_any, 0x17),
> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_fill, 0x18),
> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_dss, 0x19),
> +	TAD_PMU_EVENT_ATTR(tad_alloc_dtg, 0x1a),
> +	TAD_PMU_EVENT_ATTR(tad_alloc_ltg, 0x1b),
> +	TAD_PMU_EVENT_ATTR(tad_alloc_any, 0x1c),
> +	TAD_PMU_EVENT_ATTR(tad_hit_dtg, 0x1d),
> +	TAD_PMU_EVENT_ATTR(tad_hit_ltg, 0x1e),
> +	TAD_PMU_EVENT_ATTR(tad_hit_any, 0x1f),
> +	TAD_PMU_EVENT_ATTR(tad_tag_rd, 0x20),
> +	TAD_PMU_EVENT_ATTR(tad_dat_rd, 0x21),
> +	TAD_PMU_EVENT_ATTR(tad_dat_rd_byp, 0x22),
> +	TAD_PMU_EVENT_ATTR(tad_ifb_occ, 0x23),
> +	TAD_PMU_EVENT_ATTR(tad_req_occ, 0x24),
> +	NULL,
> +};
> +
> +static const struct attribute_group tad_pmu_events_attr_group = {
> +	.name = "events",
> +	.attrs = tad_pmu_event_attrs,
> +};
> +
> +PMU_FORMAT_ATTR(event, "config:0-7");
> +
> +static struct attribute *tad_pmu_format_attrs[] = {
> +	&format_attr_event.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group tad_pmu_format_attr_group = {
> +	.name = "format",
> +	.attrs = tad_pmu_format_attrs,
> +};
> +
> +static ssize_t tad_pmu_cpumask_show(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	struct tad_pmu *tad_pmu = to_tad_pmu(dev_get_drvdata(dev));
> +
> +	return cpumap_print_to_pagebuf(true, buf, cpumask_of(tad_pmu->cpu));
> +}
> +
> +static DEVICE_ATTR(cpumask, 0444, tad_pmu_cpumask_show, NULL);
> +
> +static struct attribute *tad_pmu_cpumask_attrs[] = {
> +	&dev_attr_cpumask.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group tad_pmu_cpumask_attr_group = {
> +	.attrs = tad_pmu_cpumask_attrs,
> +};
> +
> +static const struct attribute_group *tad_pmu_attr_groups[] = {
> +	&tad_pmu_events_attr_group,
> +	&tad_pmu_format_attr_group,
> +	&tad_pmu_cpumask_attr_group,
> +	NULL,
> +};
> +
> +static int tad_pmu_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct tad_region *regions;
> +	struct tad_pmu *tad_pmu;
> +	struct resource *res;
> +	u32 tad_pmu_page_size;
> +	u32 tad_page_size;
> +	u32 tad_cnt;
> +	int i, ret;
> +	char *name;
> +
> +	tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu), GFP_KERNEL);
> +	if (!tad_pmu)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, tad_pmu);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "Mem resource not found\n");
> +		return -ENODEV;
> +	}
> +
> +	ret = of_property_read_u32(node, "tad-page-size", &tad_page_size);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't find tad-page-size property\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(node, "tad-pmu-page-size",
> +				   &tad_pmu_page_size);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't find tad-pmu-page-size property\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(node, "tad-cnt", &tad_cnt);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Can't find tad-cnt property\n");
> +		return ret;
> +	}
> +
> +	regions = devm_kcalloc(&pdev->dev, tad_cnt,
> +			       sizeof(*regions), GFP_KERNEL);
> +	if (!regions)
> +		return -ENOMEM;
> +
> +	/* ioremap the distributed TAD pmu regions */
> +	for (i = 0; i < tad_cnt && res->start < res->end; i++) {
> +		regions[i].base = devm_ioremap(&pdev->dev,
> +					       res->start,
> +					       tad_pmu_page_size);
> +		if (IS_ERR(regions[i].base)) {
> +			dev_err(&pdev->dev, "TAD%d ioremap fail\n", i);
> +			return -ENOMEM;
> +		}
> +		res->start += tad_page_size;
> +	}
> +
> +	tad_pmu->regions = regions;
> +	tad_pmu->region_cnt = tad_cnt;
> +
> +	tad_pmu->pmu = (struct pmu) {
> +
> +		.module		= THIS_MODULE,
> +		.attr_groups	= tad_pmu_attr_groups,
> +		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
> +				  PERF_PMU_CAP_NO_INTERRUPT,
> +		.task_ctx_nr	= perf_invalid_context,
> +
> +		.event_init	= tad_pmu_event_init,
> +		.add		= tad_pmu_event_counter_add,
> +		.del		= tad_pmu_event_counter_del,
> +		.start		= tad_pmu_event_counter_start,
> +		.stop		= tad_pmu_event_counter_stop,
> +		.read		= tad_pmu_event_counter_read,
> +	};
> +
> +	tad_pmu->cpu = raw_smp_processor_id();
> +

Hi Bhaskara, 
   I think there is some memory leaks in this function. Incase cpuotplug
code fails, don't we need to free momory allocated to `tad_pmu`?

Thanks,
Kajol Jain


> +	/* Register pmu instance for cpu hotplug */
> +	ret = cpuhp_state_add_instance_nocalls(tad_pmu_cpuhp_state,
> +					       &tad_pmu->node);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
> +		return ret;
> +	}
> +
> +	name = "tad";
> +	ret = perf_pmu_register(&tad_pmu->pmu, name, -1);
> +	if (ret)
> +		cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
> +						    &tad_pmu->node);
> +
> +	return ret;
> +}
> +
> +static int tad_pmu_remove(struct platform_device *pdev)
> +{
> +	struct tad_pmu *pmu = platform_get_drvdata(pdev);
> +
> +	cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
> +						&pmu->node);
> +	perf_pmu_unregister(&pmu->pmu);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id tad_pmu_of_match[] = {
> +	{ .compatible = "marvell,cn10k-tad-pmu", },
> +	{},
> +};
> +
> +static struct platform_driver tad_pmu_driver = {
> +	.driver         = {
> +		.name   = "cn10k_tad_pmu",
> +		.of_match_table = of_match_ptr(tad_pmu_of_match),
> +		.suppress_bind_attrs = true,
> +	},
> +	.probe          = tad_pmu_probe,
> +	.remove         = tad_pmu_remove,
> +};
> +
> +static int tad_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
> +{
> +	struct tad_pmu *pmu = hlist_entry_safe(node, struct tad_pmu, node);
> +	unsigned int target;
> +
> +	if (cpu != pmu->cpu)
> +		return 0;
> +
> +	target = cpumask_any_but(cpu_online_mask, cpu);
> +	if (target >= nr_cpu_ids)
> +		return 0;
> +
> +	perf_pmu_migrate_context(&pmu->pmu, cpu, target);
> +	pmu->cpu = target;
> +
> +	return 0;
> +}
> +
> +static int __init tad_pmu_init(void)
> +{
> +	int ret;
> +
> +	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
> +				      "perf/cn10k/tadpmu:online",
> +				      NULL,
> +				      tad_pmu_offline_cpu);

> +	if (ret < 0)
> +		return ret;
> +	tad_pmu_cpuhp_state = ret;
> +	return platform_driver_register(&tad_pmu_driver);
> +}
> +
> +static void __exit tad_pmu_exit(void)
> +{
> +	platform_driver_unregister(&tad_pmu_driver);
> +	cpuhp_remove_multi_state(tad_pmu_cpuhp_state);
> +}
> +
> +module_init(tad_pmu_init);
> +module_exit(tad_pmu_exit);
> +
> +MODULE_DESCRIPTION("Marvell CN10K LLC-TAD Perf driver");
> +MODULE_AUTHOR("Bhaskara Budiredla <bbudiredla at marvell.com>");
> +MODULE_LICENSE("GPL v2");
> 


From tangbin at cmss.chinamobile.com  Sat Aug 14 07:27:41 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Sat, 14 Aug 2021 22:27:41 +0800
Subject: [PATCH] watchdog: stm32_iwdg: drop superfluous error message
Message-ID: <20210814142741.7396-1-tangbin@cmss.chinamobile.com>

In the function stm32_iwdg_probe(), devm_platform_ioremap_resource
has already contained error message, so drop the redundant one.

Co-developed-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 drivers/watchdog/stm32_iwdg.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index a3436c296..570a71509 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -237,10 +237,8 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
 
 	/* This is the timer base. */
 	wdt->regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(wdt->regs)) {
-		dev_err(dev, "Could not get resource\n");
+	if (IS_ERR(wdt->regs))
 		return PTR_ERR(wdt->regs);
-	}
 
 	ret = stm32_iwdg_clk_init(pdev, wdt);
 	if (ret)
-- 
2.20.1.windows.1





From lkp at intel.com  Sat Aug 14 07:29:37 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 14 Aug 2021 22:29:37 +0800
Subject: [xlnx:xlnx_rebase_v5.10 1386/1761]
 drivers/crypto/xilinx/zynqmp-rsa.c:155:34: warning: unused variable
 'zynqmp_rsa_dt_ids'
Message-ID: <202108142234.DrhENwNb-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   e14d4574ca81a569ee6d07e03271f2ae2dad38e4
commit: 0dcbb157a6f9da8bad728c1e433094ba0852eba3 [1386/1761] crypto: zynqmp-rsa: switch to skcipher API
config: s390-randconfig-r012-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/0dcbb157a6f9da8bad728c1e433094ba0852eba3
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 0dcbb157a6f9da8bad728c1e433094ba0852eba3
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:19:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x000000ffUL) << 24) |            \
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-rsa.c:13:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-rsa.c:13:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-rsa.c:13:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-rsa.c:13:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32'
           __fswab32(x))
                     ^
   In file included from drivers/crypto/xilinx/zynqmp-rsa.c:13:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> drivers/crypto/xilinx/zynqmp-rsa.c:155:34: warning: unused variable 'zynqmp_rsa_dt_ids' [-Wunused-const-variable]
   static const struct of_device_id zynqmp_rsa_dt_ids[] = {
                                    ^
   21 warnings generated.


vim +/zynqmp_rsa_dt_ids +155 drivers/crypto/xilinx/zynqmp-rsa.c

766a7aab941bca5 Nava kishore Manne 2020-02-03  154  
766a7aab941bca5 Nava kishore Manne 2020-02-03 @155  static const struct of_device_id zynqmp_rsa_dt_ids[] = {
766a7aab941bca5 Nava kishore Manne 2020-02-03  156  	{ .compatible = "xlnx,zynqmp-rsa" },
766a7aab941bca5 Nava kishore Manne 2020-02-03  157  	{ /* sentinel */ }
766a7aab941bca5 Nava kishore Manne 2020-02-03  158  };
766a7aab941bca5 Nava kishore Manne 2020-02-03  159  

:::::: The code at line 155 was first introduced by commit
:::::: 766a7aab941bca5265afe0641baa5bbce6ad417a crypto: zynqmp-rsa: Adopted RSA support for ZynqMP SoC

:::::: TO: Nava kishore Manne <nava.manne at xilinx.com>
:::::: CC: Michal Simek <michal.simek at xilinx.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 32807 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210814/ca43667a/attachment-0001.gz>

From marex at denx.de  Sat Aug 14 07:31:22 2021
From: marex at denx.de (Marek Vasut)
Date: Sat, 14 Aug 2021 16:31:22 +0200
Subject: [PATCH] ARM: imx_v6_v7_defconfig: enable driver of the LTC3676
 PMIC
In-Reply-To: <20210814112424.GA9470@dragon>
References: <20210805135035.124938-1-pzimmermann@dh-electronics.com>
 <54505ae8-075c-bc54-e039-0badc261fa27@denx.de>
 <20210814054055.GX30984@dragon>
 <2a3e56b8-7fd7-44ec-4090-7fe2b5d7863c@denx.de> <20210814112424.GA9470@dragon>
Message-ID: <f8fdb350-71dc-9688-c7b5-b4da18bf4b18@denx.de>

On 8/14/21 1:24 PM, Shawn Guo wrote:
> On Sat, Aug 14, 2021 at 09:45:03AM +0200, Marek Vasut wrote:
>> On 8/14/21 7:40 AM, Shawn Guo wrote:
>>> On Tue, Aug 10, 2021 at 07:36:24AM +0200, Marek Vasut wrote:
>>>> On 8/5/21 3:50 PM, Pascal Zimmermann wrote:
>>>>> The LTC3676 is a PMIC which is used on some i.MX6 based boards (like the
>>>>> DHCOM i.MX6 Quad SoM), it was first used on the GW Ventana board, enable
>>>>> LTC3676 driver in imx_v6_v7_defconfig.
>>>>>
>>>>> Fixes: e3946fe805053 ("ARM: dts: add Gateworks Ventana support")
>>>
>>> I don't think the Fixes tag is appropriate here.  Dropped it and applied
>>> patch.
>>
>> Can you please elaborate why do you think the Fixes tag is not appropriate ?
>>
>> Neither system can work properly without the PMIC driver, so I believe the
>> Fixes tag is correct and this should be backported to older LTS kernel
>> releases.
> 
> It's enabling a feature (driver) rather than fixing a bug or regression.
> If you want to enable it for LTS kernel, go ahead to back port it.
> Do not abuse the Fixes tag.

I disagree with this. Without the PMIC driver, the system is basically 
unusable. That is because the internal regulators in the MX6 depend on 
the PMIC, so those fail to probe, and in turn all the other components 
which depend on those internal regulators also fail to probe (that is 
everything which depends on anatop regulators).

If I take linux-stable, compile it for a system that is supported in 
there, with the imx_v6_v7_defconfig which is part of it, I would expect 
the result to work properly, not just barely boot and be barely usable.

Therefore, I believe the Fixes tag here is justified.


From linux at roeck-us.net  Sat Aug 14 08:02:25 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 14 Aug 2021 08:02:25 -0700
Subject: [PATCH] watchdog: stm32_iwdg: drop superfluous error message
In-Reply-To: <20210814142741.7396-1-tangbin@cmss.chinamobile.com>
References: <20210814142741.7396-1-tangbin@cmss.chinamobile.com>
Message-ID: <500cc974-bc39-74d5-1e1c-f763e25caa8b@roeck-us.net>

On 8/14/21 7:27 AM, Tang Bin wrote:
> In the function stm32_iwdg_probe(), devm_platform_ioremap_resource
> has already contained error message, so drop the redundant one.
> 
> Co-developed-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
> Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
> Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
>   drivers/watchdog/stm32_iwdg.c | 4 +---
>   1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
> index a3436c296..570a71509 100644
> --- a/drivers/watchdog/stm32_iwdg.c
> +++ b/drivers/watchdog/stm32_iwdg.c
> @@ -237,10 +237,8 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
>   
>   	/* This is the timer base. */
>   	wdt->regs = devm_platform_ioremap_resource(pdev, 0);
> -	if (IS_ERR(wdt->regs)) {
> -		dev_err(dev, "Could not get resource\n");
> +	if (IS_ERR(wdt->regs))
>   		return PTR_ERR(wdt->regs);
> -	}
>   
>   	ret = stm32_iwdg_clk_init(pdev, wdt);
>   	if (ret)
> 



From andrew at lunn.ch  Sat Aug 14 08:26:55 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Sat, 14 Aug 2021 17:26:55 +0200
Subject: [PATCH v2 4/6] ARM: dts: aspeed: Add Facebook Cloudripper
 (AST2600) BMC
In-Reply-To: <20210814052228.GA1298@taoren-ubuntu-R90MNF91>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
 <20210805222818.8391-5-rentao.bupt@gmail.com>
 <CACPK8XcV5On2D4D+SXnfw1M0owwfCL4Su19jOEA7yWpq+T3jLw@mail.gmail.com>
 <20210813034016.GA21895@taoren-ubuntu-R90MNF91>
 <YRaFpq1LvRzMYr/A@lunn.ch>
 <20210814052228.GA1298@taoren-ubuntu-R90MNF91>
Message-ID: <YRfgv5OknMluW7jj@lunn.ch>

> Thanks for jumping in. We are using BCM5389 and the MDIO bus is used to
> access BCM5389 MDC/MDIO interface in Pseudo-PHY mode.
> 
> I didn't know drivers/net/dsa, but let me check out the drivers and see
> if it works in the Cloudripper environment.

The b53 driver knows about this switch, so please make use of that
driver. See Documentation/devicetree/bindings/net/dsa/brcm,b53.yaml
for how you describe it in DT.

    Andrew


From jic23 at kernel.org  Sat Aug 14 09:10:07 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 14 Aug 2021 17:10:07 +0100
Subject: [PATCH v1 1/2] iio: mtk-auxadc: add support IIO_CHAN_INFO_RAW case
In-Reply-To: <042625639032bffe73b60a5c6274511e58e34ef4.camel@mediatek.com>
References: <20210812054844.30575-1-hui.liu@mediatek.com>
 <20210812054844.30575-2-hui.liu@mediatek.com>
 <20210812190725.00007449@Huawei.com>
 <042625639032bffe73b60a5c6274511e58e34ef4.camel@mediatek.com>
Message-ID: <20210814171007.6892ae94@jic23-huawei>

On Fri, 13 Aug 2021 11:46:24 +0800
hui.liu <hui.liu at mediatek.com> wrote:

> On Thu, 2021-08-12 at 19:07 +0100, Jonathan Cameron wrote:
> > On Thu, 12 Aug 2021 13:48:43 +0800
> > Hui Liu <hui.liu at mediatek.com> wrote:
> >   
> > > Add support IIO_CHAN_INFO_RAW case.  
> > 
> > Why?
> > 
> > We almost never support both RAW and PROCESSED as userspace should be
> > fine to use either.  There are a few reasons we've let drivers do
> > this but I would like know why it matters to you and it definitely
> > needs to be in the patch description.
> >   
> Hi Jonathan,
> 
> 1. To support ADC consumers' different types of requirement: some
> consumers want to call iio_read_channel_raw to get raw data, the others
> use iio_read_channel_processed to get voltage.

Give an example of the consumer using the raw channel readback (without
acess to any scaling information?)

> 2. In our origin driver, if consumer call iio_read_channel_processed,
> read back value is raw data. 
> 
> Could we use SCALE instead of PROCESSED in patch for next version, or
> what's your suggestion?

That would unfortunately be a userspace ABI change.  We can add interfaces
but taking them away is normally a problem :( 

Your reasons here are fine, subject to information on what consumer cares
about having _RAW, please resend the patch with this information added
to the description.

Thanks,

Jonathan
> 
> Thanks.
> 
> > > 
> > > Signed-off-by: Hui Liu <hui.liu at mediatek.com>
> > > ---
> > >  drivers/iio/adc/mt6577_auxadc.c | 16 +++++++++++++++-
> > >  1 file changed, 15 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/iio/adc/mt6577_auxadc.c
> > > b/drivers/iio/adc/mt6577_auxadc.c
> > > index 79c1dd68b909..e995d43287b2 100644
> > > --- a/drivers/iio/adc/mt6577_auxadc.c
> > > +++ b/drivers/iio/adc/mt6577_auxadc.c
> > > @@ -60,7 +60,8 @@ static const struct mtk_auxadc_compatible
> > > mt6765_compat = {
> > >  		.type = IIO_VOLTAGE,				   
> > >  \
> > >  		.indexed = 1,					   
> > >  \
> > >  		.channel = (idx),				    \
> > > -		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
> > > +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	   
> > >  \
> > > +				      BIT(IIO_CHAN_INFO_PROCESSED), \
> > >  }
> > >  
> > >  static const struct iio_chan_spec mt6577_auxadc_iio_channels[] = {
> > > @@ -181,6 +182,19 @@ static int mt6577_auxadc_read_raw(struct
> > > iio_dev *indio_dev,
> > >  	struct mt6577_auxadc_device *adc_dev = iio_priv(indio_dev);
> > >  
> > >  	switch (info) {
> > > +	case IIO_CHAN_INFO_RAW:
> > > +		*val = mt6577_auxadc_read(indio_dev, chan);
> > > +		if (*val < 0) {
> > > +			dev_notice(indio_dev->dev.parent,
> > > +				"failed to sample data on
> > > channel[%d]\n",
> > > +				chan->channel);
> > > +			return *val;
> > > +		}
> > > +		if (adc_dev->dev_comp->sample_data_cali)
> > > +			*val = mt_auxadc_get_cali_data(*val, true);
> > > +
> > > +		return IIO_VAL_INT;
> > > +
> > >  	case IIO_CHAN_INFO_PROCESSED:
> > >  		*val = mt6577_auxadc_read(indio_dev, chan);
> > >  		if (*val < 0) {  
> > 
> >   



From alim.akhtar at gmail.com  Sat Aug 14 09:55:17 2021
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Sat, 14 Aug 2021 22:25:17 +0530
Subject: [PATCH v11] dt-bindings: ufs: Add bindings for Samsung ufs host
In-Reply-To: <20210803032539.15676-1-alim.akhtar@samsung.com>
References: <CGME20210803032734epcas5p2143008ddb212fe53fcd28b813c85c9d8@epcas5p2.samsung.com>
 <20210803032539.15676-1-alim.akhtar@samsung.com>
Message-ID: <CAGOxZ53emv4H4UqT2L7tDtTXRgDrtrqti=FtfkNWo2M3rTnZMw@mail.gmail.com>

Ping!!

On Wed, Aug 4, 2021 at 9:01 AM Alim Akhtar <alim.akhtar at samsung.com> wrote:
>
> This patch adds DT bindings for Samsung ufs hci
>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
> Changes since v10
> * Rebased on v5.14-rc2
> * removed Rob Herring earlier Reviewed-by tag
>
> This patch was part of exynos ufs driver series, somehow
> this got missed to applied on the tree, sending again as a new
> patch v11, removing Rob's earlier Reviewed-by tag.
>
>  .../bindings/ufs/samsung,exynos-ufs.yaml      | 89 +++++++++++++++++++
>  1 file changed, 89 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
>
> diff --git a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> new file mode 100644
> index 000000000000..38193975c9f1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> @@ -0,0 +1,89 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/ufs/samsung,exynos-ufs.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung SoC series UFS host controller Device Tree Bindings
> +
> +maintainers:
> +  - Alim Akhtar <alim.akhtar at samsung.com>
> +
> +description: |
> +  Each Samsung UFS host controller instance should have its own node.
> +  This binding define Samsung specific binding other then what is used
> +  in the common ufshcd bindings
> +  [1] Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
> +
> +properties:
> +
> +  compatible:
> +    enum:
> +      - samsung,exynos7-ufs
> +
> +  reg:
> +    items:
> +     - description: HCI register
> +     - description: vendor specific register
> +     - description: unipro register
> +     - description: UFS protector register
> +
> +  reg-names:
> +    items:
> +      - const: hci
> +      - const: vs_hci
> +      - const: unipro
> +      - const: ufsp
> +
> +  clocks:
> +    items:
> +      - description: ufs link core clock
> +      - description: unipro main clock
> +
> +  clock-names:
> +    items:
> +      - const: core_clk
> +      - const: sclk_unipro_main
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  phys:
> +    maxItems: 1
> +
> +  phy-names:
> +    const: ufs-phy
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - phys
> +  - phy-names
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/exynos7-clk.h>
> +
> +    ufs: ufs at 15570000 {
> +       compatible = "samsung,exynos7-ufs";
> +       reg = <0x15570000 0x100>,
> +             <0x15570100 0x100>,
> +             <0x15571000 0x200>,
> +             <0x15572000 0x300>;
> +       reg-names = "hci", "vs_hci", "unipro", "ufsp";
> +       interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
> +       clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
> +                <&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
> +       clock-names = "core_clk", "sclk_unipro_main";
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> +       phys = <&ufs_phy>;
> +       phy-names = "ufs-phy";
> +    };
> +...
>
> base-commit: 2734d6c1b1a089fb593ef6a23d4b70903526fe0c
> --
> 2.17.1
>


-- 
Regards,
Alim


From lkp at intel.com  Sat Aug 14 12:13:35 2021
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Aug 2021 03:13:35 +0800
Subject: [xlnx:xlnx_rebase_v5.10 1686/1761]
 drivers/regulator/da9121-regulator.c:1001:34: warning: unused variable
 'da9121_dt_ids'
Message-ID: <202108150327.CTXUofhE-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   e14d4574ca81a569ee6d07e03271f2ae2dad38e4
commit: 4302b1e69c7e8d751f04a08592c5e2bfa7b12d4f [1686/1761] regulator: da9121: Sync with mainline version
config: s390-randconfig-r012-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/4302b1e69c7e8d751f04a08592c5e2bfa7b12d4f
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 4302b1e69c7e8d751f04a08592c5e2bfa7b12d4f
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
                     ^
   In file included from drivers/regulator/da9121-regulator.c:17:
   In file included from include/linux/of_gpio.h:14:
   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
                     ^
   In file included from drivers/regulator/da9121-regulator.c:17:
   In file included from include/linux/of_gpio.h:14:
   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
                     ^
   In file included from drivers/regulator/da9121-regulator.c:17:
   In file included from include/linux/of_gpio.h:14:
   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32'
           __fswab32(x))
                     ^
   In file included from drivers/regulator/da9121-regulator.c:17:
   In file included from include/linux/of_gpio.h:14:
   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> drivers/regulator/da9121-regulator.c:1001:34: warning: unused variable 'da9121_dt_ids' [-Wunused-const-variable]
   static const struct of_device_id da9121_dt_ids[] = {
                                    ^
   21 warnings generated.


vim +/da9121_dt_ids +1001 drivers/regulator/da9121-regulator.c

4c466d2eb34056 Raviteja Narayanam 2020-11-09  1000  
4c466d2eb34056 Raviteja Narayanam 2020-11-09 @1001  static const struct of_device_id da9121_dt_ids[] = {
4302b1e69c7e8d Raviteja Narayanam 2021-05-10  1002  	{ .compatible = "dlg,da9121", .data = (void *) DA9121_SUBTYPE_DA9121 },
4302b1e69c7e8d Raviteja Narayanam 2021-05-10  1003  	{ .compatible = "dlg,da9130", .data = (void *) DA9121_SUBTYPE_DA9130 },
4302b1e69c7e8d Raviteja Narayanam 2021-05-10  1004  	{ .compatible = "dlg,da9217", .data = (void *) DA9121_SUBTYPE_DA9217 },
4302b1e69c7e8d Raviteja Narayanam 2021-05-10  1005  	{ .compatible = "dlg,da9122", .data = (void *) DA9121_SUBTYPE_DA9122 },
4302b1e69c7e8d Raviteja Narayanam 2021-05-10  1006  	{ .compatible = "dlg,da9131", .data = (void *) DA9121_SUBTYPE_DA9131 },
4302b1e69c7e8d Raviteja Narayanam 2021-05-10  1007  	{ .compatible = "dlg,da9220", .data = (void *) DA9121_SUBTYPE_DA9220 },
4302b1e69c7e8d Raviteja Narayanam 2021-05-10  1008  	{ .compatible = "dlg,da9132", .data = (void *) DA9121_SUBTYPE_DA9132 },
4c466d2eb34056 Raviteja Narayanam 2020-11-09  1009  	{ }
4c466d2eb34056 Raviteja Narayanam 2020-11-09  1010  };
4c466d2eb34056 Raviteja Narayanam 2020-11-09  1011  MODULE_DEVICE_TABLE(of, da9121_dt_ids);
4c466d2eb34056 Raviteja Narayanam 2020-11-09  1012  

:::::: The code at line 1001 was first introduced by commit
:::::: 4c466d2eb340560878447bfc19c68310c1a5f292 drivers: regulator: Add driver for DA9121 family of devices

:::::: TO: Raviteja Narayanam <raviteja.narayanam at xilinx.com>
:::::: CC: Michal Simek <michal.simek at xilinx.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 32806 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210815/49c790f5/attachment-0001.gz>

From lkp at intel.com  Sat Aug 14 12:44:39 2021
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Aug 2021 03:44:39 +0800
Subject: [xlnx:xlnx_rebase_v5.10 1756/1761]
 drivers/media/i2c/ap1302.c:1676:6: warning: variable 'ret' is used
 uninitialized whenever 'if' condition is true
Message-ID: <202108150332.J8KmJ4Wx-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   e14d4574ca81a569ee6d07e03271f2ae2dad38e4
commit: f6f032f82f0a13def702a0154df535db88f43391 [1756/1761] media: i2c: ap1302: Add a flag to check the streaming status
config: s390-randconfig-r012-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install s390 cross compiling tool for clang build
        # apt-get install binutils-s390x-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/f6f032f82f0a13def702a0154df535db88f43391
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout f6f032f82f0a13def702a0154df535db88f43391
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=s390 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:20:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
                     ^
   In file included from drivers/media/i2c/ap1302.c:15:
   In file included from include/linux/gpio.h:62:
   In file included from include/asm-generic/gpio.h:11:
   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:21:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
                     ^
   In file included from drivers/media/i2c/ap1302.c:15:
   In file included from include/linux/gpio.h:62:
   In file included from include/asm-generic/gpio.h:11:
   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:119:21: note: expanded from macro '__swab32'
           ___constant_swab32(x) :                 \
                              ^
   include/uapi/linux/swab.h:22:12: note: expanded from macro '___constant_swab32'
           (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
                     ^
   In file included from drivers/media/i2c/ap1302.c:15:
   In file included from include/linux/gpio.h:62:
   In file included from include/asm-generic/gpio.h:11:
   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/big_endian.h:34:59: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
                                                             ^
   include/uapi/linux/swab.h:120:12: note: expanded from macro '__swab32'
           __fswab32(x))
                     ^
   In file included from drivers/media/i2c/ap1302.c:15:
   In file included from include/linux/gpio.h:62:
   In file included from include/asm-generic/gpio.h:11:
   In file included from include/linux/gpio/driver.h:7:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/s390/include/asm/io.h:80:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:609:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsb(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:617:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsw(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:625:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           readsl(PCI_IOBASE + addr, buffer, count);
                  ~~~~~~~~~~ ^
   include/asm-generic/io.h:634:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesb(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:643:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesw(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
   include/asm-generic/io.h:652:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           writesl(PCI_IOBASE + addr, buffer, count);
                   ~~~~~~~~~~ ^
>> drivers/media/i2c/ap1302.c:1676:6: warning: variable 'ret' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
           if (enable == ap1302->streaming)
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/media/i2c/ap1302.c:1692:6: note: uninitialized use occurs here
           if (ret < 0)
               ^~~
   drivers/media/i2c/ap1302.c:1676:2: note: remove the 'if' if its condition is always false
           if (enable == ap1302->streaming)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/media/i2c/ap1302.c:1672:9: note: initialize the variable 'ret' to silence this warning
           int ret;
                  ^
                   = 0
   21 warnings generated.


vim +1676 drivers/media/i2c/ap1302.c

  1668	
  1669	static int ap1302_s_stream(struct v4l2_subdev *sd, int enable)
  1670	{
  1671		struct ap1302_device *ap1302 = to_ap1302(sd);
  1672		int ret;
  1673	
  1674		mutex_lock(&ap1302->lock);
  1675	
> 1676		if (enable == ap1302->streaming)
  1677			goto done;
  1678	
  1679		if (enable) {
  1680			ret = ap1302_configure(ap1302);
  1681			if (ret < 0)
  1682				goto done;
  1683	
  1684			ret = ap1302_stall(ap1302, false);
  1685		} else {
  1686			ret = ap1302_stall(ap1302, true);
  1687		}
  1688	
  1689	done:
  1690		mutex_unlock(&ap1302->lock);
  1691	
  1692		if (ret < 0)
  1693			dev_err(ap1302->dev, "Failed to %s stream: %d\n",
  1694				enable ? "start" : "stop", ret);
  1695	
  1696		return ret;
  1697	}
  1698	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 32810 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210815/a75a1efb/attachment-0001.gz>

From u.kleine-koenig at pengutronix.de  Sat Aug 14 13:47:10 2021
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Sat, 14 Aug 2021 22:47:10 +0200
Subject: [PATCH v5 3/3] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <20210719221322.3723009-3-sean.anderson@seco.com>
References: <20210719221322.3723009-1-sean.anderson@seco.com>
 <20210719221322.3723009-3-sean.anderson@seco.com>
Message-ID: <20210814204710.retjwn5fycwtrypp@pengutronix.de>

Hello Sean,

sorry for having you let waiting so long. Now here some more feedback:

On Mon, Jul 19, 2021 at 06:13:22PM -0400, Sean Anderson wrote:
> +static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
> +			    const struct pwm_state *state)
> +{
> +	bool enabled;
> +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
> +	u32 tlr0, tlr1, tcsr0, tcsr1;
> +	u64 period_cycles, duty_cycles;
> +	unsigned long rate;
> +
> +	if (state->polarity != PWM_POLARITY_NORMAL)
> +		return -EINVAL;
> +
> +	/*
> +	 * To be representable by TLR, cycles must be between 2 and
> +	 * priv->max + 2. To enforce this we can reduce the duty
> +	 * cycle, but we may not increase it.
> +	 */
> +	rate = clk_get_rate(priv->clk);
> +	period_cycles = mul_u64_u32_div(state->period, rate, NSEC_PER_SEC);

cool, I didn't know mul_u64_u32_div.

Hmm, we still have a problem here if

	state->period * rate > 1000000000 * U64_MAX. 

So to be entirely save, we either need:

	/*
	 * To ensure that period * rate / NSEC_PER_SEC fits into an u64
	 * we need:
	 *            U64_MAX * NSEC_PER_SEC
	 *   period < ----------------------
	 *                    rate
         *
	 * . If rate is not bigger than NSEC_PER_SEC this is true for
	 * sure as the RHS is bigger than U64_MAX. Otherwise we can
	 * calculate the RHS using mul_u64_u32_div.
	 */
	if (rate > NSEC_PER_SEC)
		period = min(state->period, mul_u64_u32_div(U64_MAX, NSEC_PER_SEC, rate);
	else
		period = state->period;

or we go a step further and check the priv->max limit in the same step:

	period = min(state->period, ((u64)priv->max + 2) * NSEC_PER_SEC / rate)

. The latter is simpler and it's safe as priv->max is an u32 and so
there is no overflow.

> +	if (period_cycles - 2 > priv->max || period_cycles < 2)

I'd check for period_cycles < 2 first, because otherwise period_cycles -
2 might underflow. Nothing bad happens in this case, but reading from
left to right my first thought was I found a bug. Also please decrease
period_cycles if it's bigger than priv->max + 2. (With the suggestion
above you don't need to check for period_cycles - 2 > priv->max any more
however.)

> +		return -ERANGE;
> +	duty_cycles = mul_u64_u32_div(state->duty_cycle, rate, NSEC_PER_SEC);
> +
> +	/*
> +	 * If we specify 100% duty cycle, we will get 0% instead, so decrease
> +	 * the duty cycle count by one.
> +	 */
> +	if (period_cycles == duty_cycles)
> +		duty_cycles--;
> +
> +	/* Round down to 0% duty cycle for unrepresentable duty cycles */
> +	if (duty_cycles < 2)
> +		duty_cycles = period_cycles;
> +
> +	regmap_read(priv->map, TCSR0, &tcsr0);
> +	regmap_read(priv->map, TCSR1, &tcsr1);
> +	tlr0 = xilinx_timer_tlr_cycles(priv, tcsr0, period_cycles);
> +	tlr1 = xilinx_timer_tlr_cycles(priv, tcsr1, duty_cycles);
> +	regmap_write(priv->map, TLR0, tlr0);
> +	regmap_write(priv->map, TLR1, tlr1);
> +
> +	enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1);
> +	if (state->enabled) {
> +		/*
> +		 * If the PWM is already running, then the counters will be
> +		 * reloaded at the end of the current cycle.
> +		 */

If state->enabled is false, $enabled isn't used, so you can move the
assignment into the if body and also limit the scope of $enabled.

> +		if (!enabled) {
> +			/* Load TLR into TCR */
> +			regmap_write(priv->map, TCSR0, tcsr0 | TCSR_LOAD);
> +			regmap_write(priv->map, TCSR1, tcsr1 | TCSR_LOAD);
> +			/* Enable timers all at once with ENALL */
> +			tcsr0 = (TCSR_PWM_SET & ~TCSR_ENT) | (tcsr0 & TCSR_UDT);
> +			tcsr1 = TCSR_PWM_SET | TCSR_ENALL | (tcsr1 & TCSR_UDT);
> +			regmap_write(priv->map, TCSR0, tcsr0);
> +			regmap_write(priv->map, TCSR1, tcsr1);
> +		}
> +	} else {
> +		regmap_write(priv->map, TCSR0, 0);
> +		regmap_write(priv->map, TCSR1, 0);
> +	}
> +
> +	return 0;
> +}
> +
> +static void xilinx_pwm_get_state(struct pwm_chip *chip,
> +				 struct pwm_device *unused,
> +				 struct pwm_state *state)
> +{
> +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
> +	u32 tlr0, tlr1, tcsr0, tcsr1;
> +
> +	regmap_read(priv->map, TLR0, &tlr0);
> +	regmap_read(priv->map, TLR1, &tlr1);
> +	regmap_read(priv->map, TCSR0, &tcsr0);
> +	regmap_read(priv->map, TCSR1, &tcsr1);
> +	state->period = xilinx_timer_get_period(priv, tlr0, tcsr0);

xilinx_timer_get_period rounds down, this is however wrong for
.get_state().

> +	state->duty_cycle = xilinx_timer_get_period(priv, tlr1, tcsr1);

ditto for duty_cycle.

> +	state->enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1);
> +	state->polarity = PWM_POLARITY_NORMAL;
> [...]
> +static int xilinx_timer_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct xilinx_timer_priv *priv;
> +	struct xilinx_pwm_device *pwm;
> +	u32 pwm_cells, one_timer;
> +	void __iomem *regs;
> +
> +	ret = of_property_read_u32(np, "#pwm-cells", &pwm_cells);
> +	if (ret == -EINVAL)
> +		return -ENODEV;
> +	else if (ret)
> +		return dev_err_probe(dev, ret, "could not read #pwm-cells\n");

Please capitalize error messages.

> [...]
> +	if (ret) {
> +		clk_rate_exclusive_put(priv->clk);
> +		clk_disable_unprepare(priv->clk);
> +		return dev_err_probe(dev, ret, "could not register pwm chip\n");

s/pwm/PWM/

> +	}
> +
> +	return 0;
> +}

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210814/18fa8317/attachment.sig>

From valentin.schneider at arm.com  Sat Aug 14 15:26:07 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sat, 14 Aug 2021 23:26:07 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <20210814194737.GA3951530@roeck-us.net>
References: <20210814194737.GA3951530@roeck-us.net>
Message-ID: <87sfzb7jeo.mognet@arm.com>

Hi,

On 14/08/21 12:47, Guenter Roeck wrote:
> On Tue, Jun 29, 2021 at 01:50:09PM +0100, Valentin Schneider wrote:
>> Now that the proper infrastructure is in place, convert the irq-gic chip to
>> use handle_strict_flow_irq() along with IRQCHIP_AUTOMASKS_FLOW.
>> 
>> For EOImode=1, the Priority Drop is moved from gic_handle_irq() into
>> chip->irq_ack(). This effectively pushes the EOI write down into
>> ->handle_irq(), but doesn't change its ordering wrt the irqaction
>> handling.
>> 
>> The EOImode=1 irqchip also gains IRQCHIP_EOI_THREADED, which allows the
>> ->irq_eoi() call to be deferred to the tail of ONESHOT IRQ threads. This
>> means a threaded ONESHOT IRQ can now be handled entirely without a single
>> chip->irq_mask() call.
>> 
>> EOImode=0 handling remains unchanged.
>> 
>> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>> Link: https://lore.kernel.org/r/20210629125010.458872-13-valentin.schneider at arm.com
>> ---
>
> This patch results in a variety of crashes in -next.
>

Thanks for testing & reporting.

> Example:
>
> [    0.025729] Unable to handle kernel NULL pointer dereference at virtual address 00000000
> [    0.025811] pgd = (ptrval)
> [    0.026029] [00000000] *pgd=00000000
> [    0.027301] Internal error: Oops: 80000005 [#1] SMP ARM
> [    0.027650] Modules linked in:
> [    0.027986] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.14.0-rc5-next-20210813 #1
> [    0.028162] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
> [    0.028311] PC is at 0x0
> [    0.028485] LR is at handle_strict_flow_irq+0xc8/0x2b8
> [    0.028538] pc : [<00000000>]    lr : [<c01a59c4>]    psr: 400001d3
> [    0.028566] sp : c1701e60  ip : c17097cc  fp : 00000050
> [    0.028594] r10: c1700000  r9 : 00000057  r8 : c2012400
> [    0.028641] r7 : 00000000  r6 : c1711268  r5 : c2083c6c  r4 : c2083c00
> [    0.028674] r3 : 00000000  r2 : 00000000  r1 : 0a728000  r0 : c2083c18
> [    0.028766] Flags: nZcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
> [    0.028821] Control: 10c5387d  Table: 8000406a  DAC: 00000051
> [    0.028881] Register r0 information: slab kmalloc-512 start c2083c00 pointer offset 24 size 512
> [    0.029482] Register r1 information: non-paged memory
> [    0.029649] Register r2 information: NULL pointer
> [    0.029672] Register r3 information: NULL pointer
> [    0.029692] Register r4 information: slab kmalloc-512 start c2083c00 pointer offset 0 size 512
> [    0.029752] Register r5 information: slab kmalloc-512 start c2083c00 pointer offset 108 size 512
> [    0.029809] Register r6 information: non-slab/vmalloc memory
> [    0.029876] Register r7 information: NULL pointer
> [    0.029897] Register r8 information: slab kmalloc-1k start c2012400 pointer offset 0 size 1024
> [    0.029958] Register r9 information: non-paged memory
> [    0.029980] Register r10 information: non-slab/vmalloc memory
> [    0.030002] Register r11 information: non-paged memory
> [    0.030023] Register r12 information: non-slab/vmalloc memory
> [    0.030064] Process swapper/0 (pid: 0, stack limit = 0x(ptrval))
> [    0.030167] Stack: (0xc1701e60 to 0xc1702000)
> [    0.030562] 1e60: c168fcd8 c1700000 c17097cc c019fa2c c1709a44 d080c00c c168fcfc c1700000
> [    0.030754] 1e80: c17097cc c1701eb8 c1700000 c076fe04 c1700000 600000d3 c0824188 80000053
> [    0.030924] 1ea0: ffffffff c1701eec 00000000 c1700000 c1700000 c0100b70 c2013400 c20a0000
> [    0.031096] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
> [    0.031267] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
> [    0.031439] 1f00: 00000051 00000000 00000000 c168f31c c17097cc c2013400 c2013708 3123ccba
> [    0.031614] 1f20: 00000001 c2013400 00000960 c20a0000 c1422958 c1709380 c16804d8 c1646020
> [    0.031790] 1f40: c14d1eec c082626c c1f6f4e0 c2013400 00000000 c1422958 c1709380 c16461d4
> [    0.031961] 1f60: 00000000 00000000 00000000 c0f7d3a4 c186fdcc c1700000 c17093cc c16804d8
> [    0.032155] 1f80: c18f8e20 c160fe80 c1903000 c1663a80 00000012 c1700000 c1709380 00000000
> [    0.032327] 1fa0: c170caf0 c1600e50 ffffffff ffffffff 00000000 c1600588 00000000 c1700000
> [    0.032500] 1fc0: 00000000 c1663a80 3126c2ba 00000000 00000000 c1600330 00000051 10c0387d
> [    0.032671] 1fe0: ffffffff 8833b000 410fc075 10c5387d 00000000 00000000 00000000 00000000
> [    0.032889] [<c01a59c4>] (handle_strict_flow_irq) from [<c019fa2c>] (handle_domain_irq+0x64/0xa4)
> [    0.033027] [<c019fa2c>] (handle_domain_irq) from [<c076fe04>] (gic_handle_irq+0x84/0xbc)
> [    0.033076] [<c076fe04>] (gic_handle_irq) from [<c0100b70>] (__irq_svc+0x70/0x98)
> [    0.033140] Exception stack(0xc1701eb8 to 0xc1701f00)
> [    0.033204] 1ea0:                                                       c2013400 c20a0000
> [    0.033377] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
> [    0.033551] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
> [    0.033596] [<c0100b70>] (__irq_svc) from [<c0824188>] (do_update_region+0x108/0x19c)
> [    0.033652] [<c0824188>] (do_update_region) from [<c082626c>] (csi_J+0xf0/0x290)
> [    0.033685] [<c082626c>] (csi_J) from [<c16461d4>] (con_init+0x1b4/0x248)
> [    0.033726] [<c16461d4>] (con_init) from [<c160fe80>] (console_init+0x21c/0x330)
> [    0.033760] [<c160fe80>] (console_init) from [<c1600e50>] (start_kernel+0x508/0x6d4)
> [    0.033797] [<c1600e50>] (start_kernel) from [<00000000>] (0x0)
> [    0.034079] Code: bad PC value
> [    0.034726] ---[ end trace c1324fc4facef313 ]---
> [    0.035004] Kernel panic - not syncing: Fatal exception in interrupt
>
> https://kerneltests.org/builders/qemu-arm-v7-next/builds/66 provides
> a more detailed log.
>
> Reverting this patch fixes the problem.
>

Passing the stacktrace through scripts/decode_stracktrace.sh would help by
giving line numbers - that said I'm pretty sure this is caused by the
flow-handler now issuing a chip->irq_ack(), and this has an irqchip that
doesn't have one.

The hardware name points me at arch/arm/mach-imx/mach-imx6ul.c, but I can't
figure out an actual devicetree/irqchip layout from this.

Ah, with some more grepping I did find arch/arm/mach-imx/gpc.c, and bingo,
no .irq_ack().

Now, the above makes me feel like this is the start of a wild goose chase
for irqchips in a similar situation. I'm tempted to apply a dumb

  .irq_ack = irq_chip_ack_parent

to all irqchips without one specified. Let's see how bad this gets, does
the below help?

---
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index ebc4339b8be4..a4e10daa3ae7 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -158,6 +158,7 @@ static void imx_gpc_irq_mask(struct irq_data *d)
 
 static struct irq_chip imx_gpc_chip = {
 	.name			= "GPC",
+	.irq_ack		= irq_chip_ack_parent,
 	.irq_eoi		= irq_chip_eoi_parent,
 	.irq_mask		= imx_gpc_irq_mask,
 	.irq_unmask		= imx_gpc_irq_unmask,
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
index 5b5a365dbd5e..e304c80cd403 100644
--- a/drivers/irqchip/irq-imx-gpcv2.c
+++ b/drivers/irqchip/irq-imx-gpcv2.c
@@ -126,6 +126,7 @@ static void imx_gpcv2_irq_mask(struct irq_data *d)
 
 static struct irq_chip gpcv2_irqchip_data_chip = {
 	.name			= "GPCv2",
+	.irq_ack                = irq_chip_ack_parent,
 	.irq_eoi		= irq_chip_eoi_parent,
 	.irq_mask		= imx_gpcv2_irq_mask,
 	.irq_unmask		= imx_gpcv2_irq_unmask,


From valentin.schneider at arm.com  Sat Aug 14 15:31:45 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sat, 14 Aug 2021 23:31:45 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87sfzb7jeo.mognet@arm.com>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
Message-ID: <87pmuf7j5a.mognet@arm.com>

On 14/08/21 23:26, Valentin Schneider wrote:
>
> Now, the above makes me feel like this is the start of a wild goose chase
> for irqchips in a similar situation.

The ones in arch/arm are easy enough to catch (I see gpc, omap-wakeupgen
and some exynos suspend thing), less so for the ones in drivers/irqchip...


From linux at roeck-us.net  Sat Aug 14 16:15:26 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 14 Aug 2021 16:15:26 -0700
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87sfzb7jeo.mognet@arm.com>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
Message-ID: <c48bd2a3-018a-9de5-d92a-7541341bbbb8@roeck-us.net>

On 8/14/21 3:26 PM, Valentin Schneider wrote:
> Hi,
> 
> On 14/08/21 12:47, Guenter Roeck wrote:
>> On Tue, Jun 29, 2021 at 01:50:09PM +0100, Valentin Schneider wrote:
>>> Now that the proper infrastructure is in place, convert the irq-gic chip to
>>> use handle_strict_flow_irq() along with IRQCHIP_AUTOMASKS_FLOW.
>>>
>>> For EOImode=1, the Priority Drop is moved from gic_handle_irq() into
>>> chip->irq_ack(). This effectively pushes the EOI write down into
>>> ->handle_irq(), but doesn't change its ordering wrt the irqaction
>>> handling.
>>>
>>> The EOImode=1 irqchip also gains IRQCHIP_EOI_THREADED, which allows the
>>> ->irq_eoi() call to be deferred to the tail of ONESHOT IRQ threads. This
>>> means a threaded ONESHOT IRQ can now be handled entirely without a single
>>> chip->irq_mask() call.
>>>
>>> EOImode=0 handling remains unchanged.
>>>
>>> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>>> Link: https://lore.kernel.org/r/20210629125010.458872-13-valentin.schneider at arm.com
>>> ---
>>
>> This patch results in a variety of crashes in -next.
>>
> 
> Thanks for testing & reporting.
> 
>> Example:
>>
>> [    0.025729] Unable to handle kernel NULL pointer dereference at virtual address 00000000
>> [    0.025811] pgd = (ptrval)
>> [    0.026029] [00000000] *pgd=00000000
>> [    0.027301] Internal error: Oops: 80000005 [#1] SMP ARM
>> [    0.027650] Modules linked in:
>> [    0.027986] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.14.0-rc5-next-20210813 #1
>> [    0.028162] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
>> [    0.028311] PC is at 0x0
>> [    0.028485] LR is at handle_strict_flow_irq+0xc8/0x2b8
>> [    0.028538] pc : [<00000000>]    lr : [<c01a59c4>]    psr: 400001d3
>> [    0.028566] sp : c1701e60  ip : c17097cc  fp : 00000050
>> [    0.028594] r10: c1700000  r9 : 00000057  r8 : c2012400
>> [    0.028641] r7 : 00000000  r6 : c1711268  r5 : c2083c6c  r4 : c2083c00
>> [    0.028674] r3 : 00000000  r2 : 00000000  r1 : 0a728000  r0 : c2083c18
>> [    0.028766] Flags: nZcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
>> [    0.028821] Control: 10c5387d  Table: 8000406a  DAC: 00000051
>> [    0.028881] Register r0 information: slab kmalloc-512 start c2083c00 pointer offset 24 size 512
>> [    0.029482] Register r1 information: non-paged memory
>> [    0.029649] Register r2 information: NULL pointer
>> [    0.029672] Register r3 information: NULL pointer
>> [    0.029692] Register r4 information: slab kmalloc-512 start c2083c00 pointer offset 0 size 512
>> [    0.029752] Register r5 information: slab kmalloc-512 start c2083c00 pointer offset 108 size 512
>> [    0.029809] Register r6 information: non-slab/vmalloc memory
>> [    0.029876] Register r7 information: NULL pointer
>> [    0.029897] Register r8 information: slab kmalloc-1k start c2012400 pointer offset 0 size 1024
>> [    0.029958] Register r9 information: non-paged memory
>> [    0.029980] Register r10 information: non-slab/vmalloc memory
>> [    0.030002] Register r11 information: non-paged memory
>> [    0.030023] Register r12 information: non-slab/vmalloc memory
>> [    0.030064] Process swapper/0 (pid: 0, stack limit = 0x(ptrval))
>> [    0.030167] Stack: (0xc1701e60 to 0xc1702000)
>> [    0.030562] 1e60: c168fcd8 c1700000 c17097cc c019fa2c c1709a44 d080c00c c168fcfc c1700000
>> [    0.030754] 1e80: c17097cc c1701eb8 c1700000 c076fe04 c1700000 600000d3 c0824188 80000053
>> [    0.030924] 1ea0: ffffffff c1701eec 00000000 c1700000 c1700000 c0100b70 c2013400 c20a0000
>> [    0.031096] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
>> [    0.031267] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
>> [    0.031439] 1f00: 00000051 00000000 00000000 c168f31c c17097cc c2013400 c2013708 3123ccba
>> [    0.031614] 1f20: 00000001 c2013400 00000960 c20a0000 c1422958 c1709380 c16804d8 c1646020
>> [    0.031790] 1f40: c14d1eec c082626c c1f6f4e0 c2013400 00000000 c1422958 c1709380 c16461d4
>> [    0.031961] 1f60: 00000000 00000000 00000000 c0f7d3a4 c186fdcc c1700000 c17093cc c16804d8
>> [    0.032155] 1f80: c18f8e20 c160fe80 c1903000 c1663a80 00000012 c1700000 c1709380 00000000
>> [    0.032327] 1fa0: c170caf0 c1600e50 ffffffff ffffffff 00000000 c1600588 00000000 c1700000
>> [    0.032500] 1fc0: 00000000 c1663a80 3126c2ba 00000000 00000000 c1600330 00000051 10c0387d
>> [    0.032671] 1fe0: ffffffff 8833b000 410fc075 10c5387d 00000000 00000000 00000000 00000000
>> [    0.032889] [<c01a59c4>] (handle_strict_flow_irq) from [<c019fa2c>] (handle_domain_irq+0x64/0xa4)
>> [    0.033027] [<c019fa2c>] (handle_domain_irq) from [<c076fe04>] (gic_handle_irq+0x84/0xbc)
>> [    0.033076] [<c076fe04>] (gic_handle_irq) from [<c0100b70>] (__irq_svc+0x70/0x98)
>> [    0.033140] Exception stack(0xc1701eb8 to 0xc1701f00)
>> [    0.033204] 1ea0:                                                       c2013400 c20a0000
>> [    0.033377] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
>> [    0.033551] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
>> [    0.033596] [<c0100b70>] (__irq_svc) from [<c0824188>] (do_update_region+0x108/0x19c)
>> [    0.033652] [<c0824188>] (do_update_region) from [<c082626c>] (csi_J+0xf0/0x290)
>> [    0.033685] [<c082626c>] (csi_J) from [<c16461d4>] (con_init+0x1b4/0x248)
>> [    0.033726] [<c16461d4>] (con_init) from [<c160fe80>] (console_init+0x21c/0x330)
>> [    0.033760] [<c160fe80>] (console_init) from [<c1600e50>] (start_kernel+0x508/0x6d4)
>> [    0.033797] [<c1600e50>] (start_kernel) from [<00000000>] (0x0)
>> [    0.034079] Code: bad PC value
>> [    0.034726] ---[ end trace c1324fc4facef313 ]---
>> [    0.035004] Kernel panic - not syncing: Fatal exception in interrupt
>>
>> https://kerneltests.org/builders/qemu-arm-v7-next/builds/66 provides
>> a more detailed log.
>>
>> Reverting this patch fixes the problem.
>>
> 
> Passing the stacktrace through scripts/decode_stracktrace.sh would help by
> giving line numbers - that said I'm pretty sure this is caused by the
> flow-handler now issuing a chip->irq_ack(), and this has an irqchip that
> doesn't have one.
> 
> The hardware name points me at arch/arm/mach-imx/mach-imx6ul.c, but I can't
> figure out an actual devicetree/irqchip layout from this.
> 

This one was imx6ul-14x14-evk, and I had seen a similar crash with mcimx7d-sabre
and imx7d-sdb.

> Ah, with some more grepping I did find arch/arm/mach-imx/gpc.c, and bingo,
> no .irq_ack().
> 
> Now, the above makes me feel like this is the start of a wild goose chase
> for irqchips in a similar situation. I'm tempted to apply a dumb
> 
>    .irq_ack = irq_chip_ack_parent
> 
> to all irqchips without one specified. Let's see how bad this gets, does
> the below help?
> 

Yes, it does, for both mcimx7d-sabre and mcimx6ul-evk bot tests with qemu.


That makes me wonder - would it make sense to (also) change the calling
code to check if irq_ack is NULL, and call irq_chip_ack_parent if it is ?

Thanks,
Guenter

> ---
> diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
> index ebc4339b8be4..a4e10daa3ae7 100644
> --- a/arch/arm/mach-imx/gpc.c
> +++ b/arch/arm/mach-imx/gpc.c
> @@ -158,6 +158,7 @@ static void imx_gpc_irq_mask(struct irq_data *d)
>   
>   static struct irq_chip imx_gpc_chip = {
>   	.name			= "GPC",
> +	.irq_ack		= irq_chip_ack_parent,
>   	.irq_eoi		= irq_chip_eoi_parent,
>   	.irq_mask		= imx_gpc_irq_mask,
>   	.irq_unmask		= imx_gpc_irq_unmask,
> diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
> index 5b5a365dbd5e..e304c80cd403 100644
> --- a/drivers/irqchip/irq-imx-gpcv2.c
> +++ b/drivers/irqchip/irq-imx-gpcv2.c
> @@ -126,6 +126,7 @@ static void imx_gpcv2_irq_mask(struct irq_data *d)
>   
>   static struct irq_chip gpcv2_irqchip_data_chip = {
>   	.name			= "GPCv2",
> +	.irq_ack                = irq_chip_ack_parent,
>   	.irq_eoi		= irq_chip_eoi_parent,
>   	.irq_mask		= imx_gpcv2_irq_mask,
>   	.irq_unmask		= imx_gpcv2_irq_unmask,
> 



From linux at roeck-us.net  Sat Aug 14 16:36:39 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 14 Aug 2021 16:36:39 -0700
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87sfzb7jeo.mognet@arm.com>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
Message-ID: <7284ea6c-14d9-ba4d-ea37-9f78533dbb51@roeck-us.net>

On 8/14/21 3:26 PM, Valentin Schneider wrote:
> Hi,
> 
> On 14/08/21 12:47, Guenter Roeck wrote:
>> On Tue, Jun 29, 2021 at 01:50:09PM +0100, Valentin Schneider wrote:
>>> Now that the proper infrastructure is in place, convert the irq-gic chip to
>>> use handle_strict_flow_irq() along with IRQCHIP_AUTOMASKS_FLOW.
>>>
>>> For EOImode=1, the Priority Drop is moved from gic_handle_irq() into
>>> chip->irq_ack(). This effectively pushes the EOI write down into
>>> ->handle_irq(), but doesn't change its ordering wrt the irqaction
>>> handling.
>>>
>>> The EOImode=1 irqchip also gains IRQCHIP_EOI_THREADED, which allows the
>>> ->irq_eoi() call to be deferred to the tail of ONESHOT IRQ threads. This
>>> means a threaded ONESHOT IRQ can now be handled entirely without a single
>>> chip->irq_mask() call.
>>>
>>> EOImode=0 handling remains unchanged.
>>>
>>> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>>> Link: https://lore.kernel.org/r/20210629125010.458872-13-valentin.schneider at arm.com
>>> ---
>>
>> This patch results in a variety of crashes in -next.
>>
> 
> Thanks for testing & reporting.
> 
>> Example:
>>
>> [    0.025729] Unable to handle kernel NULL pointer dereference at virtual address 00000000
>> [    0.025811] pgd = (ptrval)
>> [    0.026029] [00000000] *pgd=00000000
>> [    0.027301] Internal error: Oops: 80000005 [#1] SMP ARM
>> [    0.027650] Modules linked in:
>> [    0.027986] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.14.0-rc5-next-20210813 #1
>> [    0.028162] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
>> [    0.028311] PC is at 0x0
>> [    0.028485] LR is at handle_strict_flow_irq+0xc8/0x2b8
>> [    0.028538] pc : [<00000000>]    lr : [<c01a59c4>]    psr: 400001d3
>> [    0.028566] sp : c1701e60  ip : c17097cc  fp : 00000050
>> [    0.028594] r10: c1700000  r9 : 00000057  r8 : c2012400
>> [    0.028641] r7 : 00000000  r6 : c1711268  r5 : c2083c6c  r4 : c2083c00
>> [    0.028674] r3 : 00000000  r2 : 00000000  r1 : 0a728000  r0 : c2083c18
>> [    0.028766] Flags: nZcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
>> [    0.028821] Control: 10c5387d  Table: 8000406a  DAC: 00000051
>> [    0.028881] Register r0 information: slab kmalloc-512 start c2083c00 pointer offset 24 size 512
>> [    0.029482] Register r1 information: non-paged memory
>> [    0.029649] Register r2 information: NULL pointer
>> [    0.029672] Register r3 information: NULL pointer
>> [    0.029692] Register r4 information: slab kmalloc-512 start c2083c00 pointer offset 0 size 512
>> [    0.029752] Register r5 information: slab kmalloc-512 start c2083c00 pointer offset 108 size 512
>> [    0.029809] Register r6 information: non-slab/vmalloc memory
>> [    0.029876] Register r7 information: NULL pointer
>> [    0.029897] Register r8 information: slab kmalloc-1k start c2012400 pointer offset 0 size 1024
>> [    0.029958] Register r9 information: non-paged memory
>> [    0.029980] Register r10 information: non-slab/vmalloc memory
>> [    0.030002] Register r11 information: non-paged memory
>> [    0.030023] Register r12 information: non-slab/vmalloc memory
>> [    0.030064] Process swapper/0 (pid: 0, stack limit = 0x(ptrval))
>> [    0.030167] Stack: (0xc1701e60 to 0xc1702000)
>> [    0.030562] 1e60: c168fcd8 c1700000 c17097cc c019fa2c c1709a44 d080c00c c168fcfc c1700000
>> [    0.030754] 1e80: c17097cc c1701eb8 c1700000 c076fe04 c1700000 600000d3 c0824188 80000053
>> [    0.030924] 1ea0: ffffffff c1701eec 00000000 c1700000 c1700000 c0100b70 c2013400 c20a0000
>> [    0.031096] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
>> [    0.031267] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
>> [    0.031439] 1f00: 00000051 00000000 00000000 c168f31c c17097cc c2013400 c2013708 3123ccba
>> [    0.031614] 1f20: 00000001 c2013400 00000960 c20a0000 c1422958 c1709380 c16804d8 c1646020
>> [    0.031790] 1f40: c14d1eec c082626c c1f6f4e0 c2013400 00000000 c1422958 c1709380 c16461d4
>> [    0.031961] 1f60: 00000000 00000000 00000000 c0f7d3a4 c186fdcc c1700000 c17093cc c16804d8
>> [    0.032155] 1f80: c18f8e20 c160fe80 c1903000 c1663a80 00000012 c1700000 c1709380 00000000
>> [    0.032327] 1fa0: c170caf0 c1600e50 ffffffff ffffffff 00000000 c1600588 00000000 c1700000
>> [    0.032500] 1fc0: 00000000 c1663a80 3126c2ba 00000000 00000000 c1600330 00000051 10c0387d
>> [    0.032671] 1fe0: ffffffff 8833b000 410fc075 10c5387d 00000000 00000000 00000000 00000000
>> [    0.032889] [<c01a59c4>] (handle_strict_flow_irq) from [<c019fa2c>] (handle_domain_irq+0x64/0xa4)
>> [    0.033027] [<c019fa2c>] (handle_domain_irq) from [<c076fe04>] (gic_handle_irq+0x84/0xbc)
>> [    0.033076] [<c076fe04>] (gic_handle_irq) from [<c0100b70>] (__irq_svc+0x70/0x98)
>> [    0.033140] Exception stack(0xc1701eb8 to 0xc1701f00)
>> [    0.033204] 1ea0:                                                       c2013400 c20a0000
>> [    0.033377] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
>> [    0.033551] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
>> [    0.033596] [<c0100b70>] (__irq_svc) from [<c0824188>] (do_update_region+0x108/0x19c)
>> [    0.033652] [<c0824188>] (do_update_region) from [<c082626c>] (csi_J+0xf0/0x290)
>> [    0.033685] [<c082626c>] (csi_J) from [<c16461d4>] (con_init+0x1b4/0x248)
>> [    0.033726] [<c16461d4>] (con_init) from [<c160fe80>] (console_init+0x21c/0x330)
>> [    0.033760] [<c160fe80>] (console_init) from [<c1600e50>] (start_kernel+0x508/0x6d4)
>> [    0.033797] [<c1600e50>] (start_kernel) from [<00000000>] (0x0)
>> [    0.034079] Code: bad PC value
>> [    0.034726] ---[ end trace c1324fc4facef313 ]---
>> [    0.035004] Kernel panic - not syncing: Fatal exception in interrupt
>>
>> https://kerneltests.org/builders/qemu-arm-v7-next/builds/66 provides
>> a more detailed log.
>>
>> Reverting this patch fixes the problem.
>>
> 
> Passing the stacktrace through scripts/decode_stracktrace.sh would help by
> giving line numbers - that said I'm pretty sure this is caused by the
> flow-handler now issuing a chip->irq_ack(), and this has an irqchip that
> doesn't have one.
> 
> The hardware name points me at arch/arm/mach-imx/mach-imx6ul.c, but I can't
> figure out an actual devicetree/irqchip layout from this.
> 
> Ah, with some more grepping I did find arch/arm/mach-imx/gpc.c, and bingo,
> no .irq_ack().
> 
> Now, the above makes me feel like this is the start of a wild goose chase
> for irqchips in a similar situation. I'm tempted to apply a dumb
> 
>    .irq_ack = irq_chip_ack_parent
> 
> to all irqchips without one specified. Let's see how bad this gets, does
> the below help?
> 

As a follow-up, Coccinelle tells me that there are more than 300 declarations of
struct irq_chip variables without irq_ack pointer in the kernel. Does this problem
affect all of them or just a subset ? If it doesn't affect all of them, how does
one know when irq_ack is mandatory and when not ?

Thanks,
Guenter


From linux at roeck-us.net  Sat Aug 14 16:41:03 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 14 Aug 2021 16:41:03 -0700
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87pmuf7j5a.mognet@arm.com>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
 <87pmuf7j5a.mognet@arm.com>
Message-ID: <20210814234103.GA828447@roeck-us.net>

On Sat, Aug 14, 2021 at 11:31:45PM +0100, Valentin Schneider wrote:
> On 14/08/21 23:26, Valentin Schneider wrote:
> >
> > Now, the above makes me feel like this is the start of a wild goose chase
> > for irqchips in a similar situation.
> 
> The ones in arch/arm are easy enough to catch (I see gpc, omap-wakeupgen
> and some exynos suspend thing), less so for the ones in drivers/irqchip...

Try:
	make coccicheck COCCI=irq_chip.cocci MODE=report M=.
with the script below. I am sure the script could be augmented if
there is some secondary condition that makes irq_ack mandatory.

Guenter

---
irq_chip.cocci:

virtual report

@c@
identifier chip;
position p;
@@

struct irq_chip chip at p = {
...
};

@i@
identifier c.chip;
identifier f; 
@@

struct irq_chip chip = {
	.irq_ack = f,
};

@script:python depends on c && !i && report@
p << c.p;
@@

print "Found %s:%s" % (p[0].file, p[0].line)


From maz at kernel.org  Sat Aug 14 23:54:03 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 15 Aug 2021 07:54:03 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87sfzb7jeo.mognet@arm.com>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
Message-ID: <87eeav19mc.wl-maz@kernel.org>

On Sat, 14 Aug 2021 23:26:07 +0100,
Valentin Schneider <valentin.schneider at arm.com> wrote:
> 
> Hi,
> 
> On 14/08/21 12:47, Guenter Roeck wrote:
> > On Tue, Jun 29, 2021 at 01:50:09PM +0100, Valentin Schneider wrote:
> >> Now that the proper infrastructure is in place, convert the irq-gic chip to
> >> use handle_strict_flow_irq() along with IRQCHIP_AUTOMASKS_FLOW.
> >> 
> >> For EOImode=1, the Priority Drop is moved from gic_handle_irq() into
> >> chip->irq_ack(). This effectively pushes the EOI write down into
> >> ->handle_irq(), but doesn't change its ordering wrt the irqaction
> >> handling.
> >> 
> >> The EOImode=1 irqchip also gains IRQCHIP_EOI_THREADED, which allows the
> >> ->irq_eoi() call to be deferred to the tail of ONESHOT IRQ threads. This
> >> means a threaded ONESHOT IRQ can now be handled entirely without a single
> >> chip->irq_mask() call.
> >> 
> >> EOImode=0 handling remains unchanged.
> >> 
> >> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
> >> Signed-off-by: Marc Zyngier <maz at kernel.org>
> >> Link: https://lore.kernel.org/r/20210629125010.458872-13-valentin.schneider at arm.com
> >> ---
> >
> > This patch results in a variety of crashes in -next.
> >
> 
> Thanks for testing & reporting.
> 
> > Example:
> >
> > [    0.025729] Unable to handle kernel NULL pointer dereference at virtual address 00000000
> > [    0.025811] pgd = (ptrval)
> > [    0.026029] [00000000] *pgd=00000000
> > [    0.027301] Internal error: Oops: 80000005 [#1] SMP ARM
> > [    0.027650] Modules linked in:
> > [    0.027986] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.14.0-rc5-next-20210813 #1
> > [    0.028162] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
> > [    0.028311] PC is at 0x0
> > [    0.028485] LR is at handle_strict_flow_irq+0xc8/0x2b8
> > [    0.028538] pc : [<00000000>]    lr : [<c01a59c4>]    psr: 400001d3
> > [    0.028566] sp : c1701e60  ip : c17097cc  fp : 00000050
> > [    0.028594] r10: c1700000  r9 : 00000057  r8 : c2012400
> > [    0.028641] r7 : 00000000  r6 : c1711268  r5 : c2083c6c  r4 : c2083c00
> > [    0.028674] r3 : 00000000  r2 : 00000000  r1 : 0a728000  r0 : c2083c18
> > [    0.028766] Flags: nZcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
> > [    0.028821] Control: 10c5387d  Table: 8000406a  DAC: 00000051
> > [    0.028881] Register r0 information: slab kmalloc-512 start c2083c00 pointer offset 24 size 512
> > [    0.029482] Register r1 information: non-paged memory
> > [    0.029649] Register r2 information: NULL pointer
> > [    0.029672] Register r3 information: NULL pointer
> > [    0.029692] Register r4 information: slab kmalloc-512 start c2083c00 pointer offset 0 size 512
> > [    0.029752] Register r5 information: slab kmalloc-512 start c2083c00 pointer offset 108 size 512
> > [    0.029809] Register r6 information: non-slab/vmalloc memory
> > [    0.029876] Register r7 information: NULL pointer
> > [    0.029897] Register r8 information: slab kmalloc-1k start c2012400 pointer offset 0 size 1024
> > [    0.029958] Register r9 information: non-paged memory
> > [    0.029980] Register r10 information: non-slab/vmalloc memory
> > [    0.030002] Register r11 information: non-paged memory
> > [    0.030023] Register r12 information: non-slab/vmalloc memory
> > [    0.030064] Process swapper/0 (pid: 0, stack limit = 0x(ptrval))
> > [    0.030167] Stack: (0xc1701e60 to 0xc1702000)
> > [    0.030562] 1e60: c168fcd8 c1700000 c17097cc c019fa2c c1709a44 d080c00c c168fcfc c1700000
> > [    0.030754] 1e80: c17097cc c1701eb8 c1700000 c076fe04 c1700000 600000d3 c0824188 80000053
> > [    0.030924] 1ea0: ffffffff c1701eec 00000000 c1700000 c1700000 c0100b70 c2013400 c20a0000
> > [    0.031096] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
> > [    0.031267] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
> > [    0.031439] 1f00: 00000051 00000000 00000000 c168f31c c17097cc c2013400 c2013708 3123ccba
> > [    0.031614] 1f20: 00000001 c2013400 00000960 c20a0000 c1422958 c1709380 c16804d8 c1646020
> > [    0.031790] 1f40: c14d1eec c082626c c1f6f4e0 c2013400 00000000 c1422958 c1709380 c16461d4
> > [    0.031961] 1f60: 00000000 00000000 00000000 c0f7d3a4 c186fdcc c1700000 c17093cc c16804d8
> > [    0.032155] 1f80: c18f8e20 c160fe80 c1903000 c1663a80 00000012 c1700000 c1709380 00000000
> > [    0.032327] 1fa0: c170caf0 c1600e50 ffffffff ffffffff 00000000 c1600588 00000000 c1700000
> > [    0.032500] 1fc0: 00000000 c1663a80 3126c2ba 00000000 00000000 c1600330 00000051 10c0387d
> > [    0.032671] 1fe0: ffffffff 8833b000 410fc075 10c5387d 00000000 00000000 00000000 00000000
> > [    0.032889] [<c01a59c4>] (handle_strict_flow_irq) from [<c019fa2c>] (handle_domain_irq+0x64/0xa4)
> > [    0.033027] [<c019fa2c>] (handle_domain_irq) from [<c076fe04>] (gic_handle_irq+0x84/0xbc)
> > [    0.033076] [<c076fe04>] (gic_handle_irq) from [<c0100b70>] (__irq_svc+0x70/0x98)
> > [    0.033140] Exception stack(0xc1701eb8 to 0xc1701f00)
> > [    0.033204] 1ea0:                                                       c2013400 c20a0000
> > [    0.033377] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
> > [    0.033551] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
> > [    0.033596] [<c0100b70>] (__irq_svc) from [<c0824188>] (do_update_region+0x108/0x19c)
> > [    0.033652] [<c0824188>] (do_update_region) from [<c082626c>] (csi_J+0xf0/0x290)
> > [    0.033685] [<c082626c>] (csi_J) from [<c16461d4>] (con_init+0x1b4/0x248)
> > [    0.033726] [<c16461d4>] (con_init) from [<c160fe80>] (console_init+0x21c/0x330)
> > [    0.033760] [<c160fe80>] (console_init) from [<c1600e50>] (start_kernel+0x508/0x6d4)
> > [    0.033797] [<c1600e50>] (start_kernel) from [<00000000>] (0x0)
> > [    0.034079] Code: bad PC value
> > [    0.034726] ---[ end trace c1324fc4facef313 ]---
> > [    0.035004] Kernel panic - not syncing: Fatal exception in interrupt
> >
> > https://kerneltests.org/builders/qemu-arm-v7-next/builds/66 provides
> > a more detailed log.
> >
> > Reverting this patch fixes the problem.
> >
> 
> Passing the stacktrace through scripts/decode_stracktrace.sh would help by
> giving line numbers - that said I'm pretty sure this is caused by the
> flow-handler now issuing a chip->irq_ack(), and this has an irqchip that
> doesn't have one.
> 
> The hardware name points me at arch/arm/mach-imx/mach-imx6ul.c, but I can't
> figure out an actual devicetree/irqchip layout from this.
> 
> Ah, with some more grepping I did find arch/arm/mach-imx/gpc.c, and bingo,
> no .irq_ack().
> 
> Now, the above makes me feel like this is the start of a wild goose chase
> for irqchips in a similar situation. I'm tempted to apply a dumb
> 
>   .irq_ack = irq_chip_ack_parent
> 
> to all irqchips without one specified. Let's see how bad this gets, does
> the below help?

You need to be selective. A number of irqchips don't need an irq_ack
callback.

> 
> ---
> diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
> index ebc4339b8be4..a4e10daa3ae7 100644
> --- a/arch/arm/mach-imx/gpc.c
> +++ b/arch/arm/mach-imx/gpc.c
> @@ -158,6 +158,7 @@ static void imx_gpc_irq_mask(struct irq_data *d)
>  
>  static struct irq_chip imx_gpc_chip = {
>  	.name			= "GPC",
> +	.irq_ack		= irq_chip_ack_parent,
>  	.irq_eoi		= irq_chip_eoi_parent,
>  	.irq_mask		= imx_gpc_irq_mask,
>  	.irq_unmask		= imx_gpc_irq_unmask,
> diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
> index 5b5a365dbd5e..e304c80cd403 100644
> --- a/drivers/irqchip/irq-imx-gpcv2.c
> +++ b/drivers/irqchip/irq-imx-gpcv2.c
> @@ -126,6 +126,7 @@ static void imx_gpcv2_irq_mask(struct irq_data *d)
>  
>  static struct irq_chip gpcv2_irqchip_data_chip = {
>  	.name			= "GPCv2",
> +	.irq_ack                = irq_chip_ack_parent,
>  	.irq_eoi		= irq_chip_eoi_parent,
>  	.irq_mask		= imx_gpcv2_irq_mask,
>  	.irq_unmask		= imx_gpcv2_irq_unmask,
> 

This is going and-up in a wack-a-mole game. There is probably a bunch
of these all over the place. I'd rather squash it at the root,
i.e. with something like this (untested):

diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 099bc7e13d1b..601ad3fc47cd 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -410,7 +410,12 @@ void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
 
 void ack_irq(struct irq_desc *desc)
 {
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
+	struct irq_data *data = &desc->irq_data;
+
+	while (!data->chip->irq_ack)
+		data = data->parent_data;
+
+	data->chip->irq_ack(&desc->irq_data);
 
 	if (desc->irq_data.chip->flags & IRQCHIP_AUTOMASKS_FLOW)
 		irq_state_set_flow_masked(desc);

We probably need something similar for irq_eoi().

This however shows a more fundamental problem, I'm afraid. We set
IRQCHIP_AUTOMASKS_FLOW in the GIC drivers (i.e. at the root), but test
for it at the top of the hierarchy. As soon as we have more than a
single layer of irqchip, this will do the wrong thing (or at least
miss the masking optimisation).

This probably advocates for moving the flag into the descriptor. This
really makes sense, as the flow is global to the whole stack, not just
to the localised irqchip.

In order to restore -next into a working state, I'm temporarily
dropping this series. Hopefully, we can sort this out before the merge
window and reinstate it.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Sun Aug 15 00:01:12 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 15 Aug 2021 08:01:12 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <7284ea6c-14d9-ba4d-ea37-9f78533dbb51@roeck-us.net>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
 <7284ea6c-14d9-ba4d-ea37-9f78533dbb51@roeck-us.net>
Message-ID: <87czqf19af.wl-maz@kernel.org>

On Sun, 15 Aug 2021 00:36:39 +0100,
Guenter Roeck <linux at roeck-us.net> wrote:
> 
> On 8/14/21 3:26 PM, Valentin Schneider wrote:
> > Hi,
> > 
> > On 14/08/21 12:47, Guenter Roeck wrote:
> >> On Tue, Jun 29, 2021 at 01:50:09PM +0100, Valentin Schneider wrote:
> >>> Now that the proper infrastructure is in place, convert the irq-gic chip to
> >>> use handle_strict_flow_irq() along with IRQCHIP_AUTOMASKS_FLOW.
> >>> 
> >>> For EOImode=1, the Priority Drop is moved from gic_handle_irq() into
> >>> chip->irq_ack(). This effectively pushes the EOI write down into
> >>> ->handle_irq(), but doesn't change its ordering wrt the irqaction
> >>> handling.
> >>> 
> >>> The EOImode=1 irqchip also gains IRQCHIP_EOI_THREADED, which allows the
> >>> ->irq_eoi() call to be deferred to the tail of ONESHOT IRQ threads. This
> >>> means a threaded ONESHOT IRQ can now be handled entirely without a single
> >>> chip->irq_mask() call.
> >>> 
> >>> EOImode=0 handling remains unchanged.
> >>> 
> >>> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
> >>> Signed-off-by: Marc Zyngier <maz at kernel.org>
> >>> Link: https://lore.kernel.org/r/20210629125010.458872-13-valentin.schneider at arm.com
> >>> ---
> >> 
> >> This patch results in a variety of crashes in -next.
> >> 
> > 
> > Thanks for testing & reporting.
> > 
> >> Example:
> >> 
> >> [    0.025729] Unable to handle kernel NULL pointer dereference at virtual address 00000000
> >> [    0.025811] pgd = (ptrval)
> >> [    0.026029] [00000000] *pgd=00000000
> >> [    0.027301] Internal error: Oops: 80000005 [#1] SMP ARM
> >> [    0.027650] Modules linked in:
> >> [    0.027986] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.14.0-rc5-next-20210813 #1
> >> [    0.028162] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
> >> [    0.028311] PC is at 0x0
> >> [    0.028485] LR is at handle_strict_flow_irq+0xc8/0x2b8
> >> [    0.028538] pc : [<00000000>]    lr : [<c01a59c4>]    psr: 400001d3
> >> [    0.028566] sp : c1701e60  ip : c17097cc  fp : 00000050
> >> [    0.028594] r10: c1700000  r9 : 00000057  r8 : c2012400
> >> [    0.028641] r7 : 00000000  r6 : c1711268  r5 : c2083c6c  r4 : c2083c00
> >> [    0.028674] r3 : 00000000  r2 : 00000000  r1 : 0a728000  r0 : c2083c18
> >> [    0.028766] Flags: nZcv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment none
> >> [    0.028821] Control: 10c5387d  Table: 8000406a  DAC: 00000051
> >> [    0.028881] Register r0 information: slab kmalloc-512 start c2083c00 pointer offset 24 size 512
> >> [    0.029482] Register r1 information: non-paged memory
> >> [    0.029649] Register r2 information: NULL pointer
> >> [    0.029672] Register r3 information: NULL pointer
> >> [    0.029692] Register r4 information: slab kmalloc-512 start c2083c00 pointer offset 0 size 512
> >> [    0.029752] Register r5 information: slab kmalloc-512 start c2083c00 pointer offset 108 size 512
> >> [    0.029809] Register r6 information: non-slab/vmalloc memory
> >> [    0.029876] Register r7 information: NULL pointer
> >> [    0.029897] Register r8 information: slab kmalloc-1k start c2012400 pointer offset 0 size 1024
> >> [    0.029958] Register r9 information: non-paged memory
> >> [    0.029980] Register r10 information: non-slab/vmalloc memory
> >> [    0.030002] Register r11 information: non-paged memory
> >> [    0.030023] Register r12 information: non-slab/vmalloc memory
> >> [    0.030064] Process swapper/0 (pid: 0, stack limit = 0x(ptrval))
> >> [    0.030167] Stack: (0xc1701e60 to 0xc1702000)
> >> [    0.030562] 1e60: c168fcd8 c1700000 c17097cc c019fa2c c1709a44 d080c00c c168fcfc c1700000
> >> [    0.030754] 1e80: c17097cc c1701eb8 c1700000 c076fe04 c1700000 600000d3 c0824188 80000053
> >> [    0.030924] 1ea0: ffffffff c1701eec 00000000 c1700000 c1700000 c0100b70 c2013400 c20a0000
> >> [    0.031096] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
> >> [    0.031267] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
> >> [    0.031439] 1f00: 00000051 00000000 00000000 c168f31c c17097cc c2013400 c2013708 3123ccba
> >> [    0.031614] 1f20: 00000001 c2013400 00000960 c20a0000 c1422958 c1709380 c16804d8 c1646020
> >> [    0.031790] 1f40: c14d1eec c082626c c1f6f4e0 c2013400 00000000 c1422958 c1709380 c16461d4
> >> [    0.031961] 1f60: 00000000 00000000 00000000 c0f7d3a4 c186fdcc c1700000 c17093cc c16804d8
> >> [    0.032155] 1f80: c18f8e20 c160fe80 c1903000 c1663a80 00000012 c1700000 c1709380 00000000
> >> [    0.032327] 1fa0: c170caf0 c1600e50 ffffffff ffffffff 00000000 c1600588 00000000 c1700000
> >> [    0.032500] 1fc0: 00000000 c1663a80 3126c2ba 00000000 00000000 c1600330 00000051 10c0387d
> >> [    0.032671] 1fe0: ffffffff 8833b000 410fc075 10c5387d 00000000 00000000 00000000 00000000
> >> [    0.032889] [<c01a59c4>] (handle_strict_flow_irq) from [<c019fa2c>] (handle_domain_irq+0x64/0xa4)
> >> [    0.033027] [<c019fa2c>] (handle_domain_irq) from [<c076fe04>] (gic_handle_irq+0x84/0xbc)
> >> [    0.033076] [<c076fe04>] (gic_handle_irq) from [<c0100b70>] (__irq_svc+0x70/0x98)
> >> [    0.033140] Exception stack(0xc1701eb8 to 0xc1701f00)
> >> [    0.033204] 1ea0:                                                       c2013400 c20a0000
> >> [    0.033377] 1ec0: 00000050 00000000 c20a00a0 c07c0ad4 00000910 c2013400 00000000 c20a0000
> >> [    0.033551] 1ee0: c1700000 00000050 00000000 c1701f08 c0824188 c0824188 80000053 ffffffff
> >> [    0.033596] [<c0100b70>] (__irq_svc) from [<c0824188>] (do_update_region+0x108/0x19c)
> >> [    0.033652] [<c0824188>] (do_update_region) from [<c082626c>] (csi_J+0xf0/0x290)
> >> [    0.033685] [<c082626c>] (csi_J) from [<c16461d4>] (con_init+0x1b4/0x248)
> >> [    0.033726] [<c16461d4>] (con_init) from [<c160fe80>] (console_init+0x21c/0x330)
> >> [    0.033760] [<c160fe80>] (console_init) from [<c1600e50>] (start_kernel+0x508/0x6d4)
> >> [    0.033797] [<c1600e50>] (start_kernel) from [<00000000>] (0x0)
> >> [    0.034079] Code: bad PC value
> >> [    0.034726] ---[ end trace c1324fc4facef313 ]---
> >> [    0.035004] Kernel panic - not syncing: Fatal exception in interrupt
> >> 
> >> https://kerneltests.org/builders/qemu-arm-v7-next/builds/66 provides
> >> a more detailed log.
> >> 
> >> Reverting this patch fixes the problem.
> >> 
> > 
> > Passing the stacktrace through scripts/decode_stracktrace.sh would help by
> > giving line numbers - that said I'm pretty sure this is caused by the
> > flow-handler now issuing a chip->irq_ack(), and this has an irqchip that
> > doesn't have one.
> > 
> > The hardware name points me at arch/arm/mach-imx/mach-imx6ul.c, but I can't
> > figure out an actual devicetree/irqchip layout from this.
> > 
> > Ah, with some more grepping I did find arch/arm/mach-imx/gpc.c, and bingo,
> > no .irq_ack().
> > 
> > Now, the above makes me feel like this is the start of a wild goose chase
> > for irqchips in a similar situation. I'm tempted to apply a dumb
> > 
> >    .irq_ack = irq_chip_ack_parent
> > 
> > to all irqchips without one specified. Let's see how bad this gets, does
> > the below help?
> > 
> 
> As a follow-up, Coccinelle tells me that there are more than 300
> declarations of struct irq_chip variables without irq_ack pointer in
> the kernel. Does this problem affect all of them or just a subset ?
> If it doesn't affect all of them, how does one know when irq_ack is
> mandatory and when not ?

One needs to understand what flow is being used. For irqchip stacks
using fast-eoi, there was no need for an irq_ack callback until we
switched to Valentin's "strict" flow.

The problem is that although irqchip *look* like they can be composed
at will, the composition only makes sense if they all agree on the
flow that is being used.

So we can either identify the irqchips that need to be updated (not an
easy task, but not impossible: just look for anything that feeds into
a GIC through a hierarchy and not a mux). Or we can make the flow
iterate over the irqchip layers.

	M.

-- 
Without deviation from the norm, progress is not possible.


From f.fainelli at gmail.com  Sun Aug 15 00:24:24 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 15 Aug 2021 09:24:24 +0200
Subject: [PATCH v3 6/7] usb: gadget: bdc: remove unnecessary AND operation
 when get ep maxp
In-Reply-To: <1628836253-7432-6-git-send-email-chunfeng.yun@mediatek.com>
References: <1628836253-7432-1-git-send-email-chunfeng.yun@mediatek.com>
 <1628836253-7432-6-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <e191402f-69e1-2fb5-f5e1-6fd73e8b0699@gmail.com>



On 8/13/2021 8:30 AM, Chunfeng Yun wrote:
> usb_endpoint_maxp() already returns actual max packet size, no need
> to AND 0x7ff.
> 
> Acked-by: Felipe Balbi <balbi at kernel.org>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From f.fainelli at gmail.com  Sun Aug 15 00:28:47 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 15 Aug 2021 09:28:47 +0200
Subject: [PATCH 0/5] arm64: Survival kit for SCR_EL3.HCE==0 conditions
In-Reply-To: <20210812190213.2601506-1-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
Message-ID: <7ffa35bb-1f2c-19ff-fe4b-33267fba80e8@gmail.com>



On 8/12/2021 9:02 PM, Marc Zyngier wrote:
> Anyone vaguely familiar with the ARMv8 architecture would quickly
> understand that entering the kernel at EL2 without enabling the HVC
> instruction is... living dangerously. But as it turns out [0], there
> is a whole range of (*cough*) "high quality" (*cough*) Broadcom
> systems out there configured exactly like that.

Some Broadcom systems, namely the 4908 and all of those using CFE, they 
later switched to u-boot and ATF and got it right.

> 
> If you are speechless, I'm right with you.
> 
> These machines have stopped being able to boot an upstream kernel
> since 5.12, where we changed the way we switch from nVHE to VHE, as
> this relies on the HVC instruction being usable... It is also worth
> noting that these systems have never been able to use KVM. Or kexec.
> 
> This small series addresses the issue by detecting an UNDEFing HVC in
> a fairly controlled environment, and in this case pretend that we have
> booted at EL1. It also documents the requirement for SCR_EL3.HCE to be
> set to *1* if the kernel is entered at EL2. Turns out that we really
> have to state the obvious.
> 
> This has been tested on a FVP model with a hacked-up boot-wrapper.
> 
> Note that I really don't think any of this is -stable material, except
> maybe for the documentation. It isn't 5.14 material either. Best case,
> this is 5.15, or maybe even later. If ever.

While I am very appreciative of the work you have done here to try to 
get the dysfunctional systems to warn and continue to boot, I would 
rather we try to load a minimal shim at EL3 capable of fixing up any 
incorrect EL3 register setting ahead of loading the kernel provided this 
is possible at all on a commercially available system. Rafal, is this 
something that CFE allows you to do (as I could not get a straight 
answer from that team), if so have you tried it?
-- 
Florian


From oupton at google.com  Sun Aug 15 00:50:09 2021
From: oupton at google.com (Oliver Upton)
Date: Sun, 15 Aug 2021 00:50:09 -0700
Subject: [PATCH v3 0/3] KVM: arm64: Use generic guest entry infrastructure
In-Reply-To: <20210802192809.1851010-1-oupton@google.com>
References: <20210802192809.1851010-1-oupton@google.com>
Message-ID: <CAOQ_Qsj0UH=3FQNP3NTjX-rcU68s0hm6k5g7i_rwqKc4b84DZA@mail.gmail.com>

Friendly ping :)

--
Thanks,
Oliver

On Mon, Aug 2, 2021 at 12:28 PM Oliver Upton <oupton at google.com> wrote:
>
> The arm64 kernel doesn't yet support the full generic entry
> infrastructure. That being said, KVM/arm64 doesn't properly handle
> TIF_NOTIFY_RESUME and could pick this up by switching to the generic
> guest entry infrasturture.
>
> Patch 1 adds a missing vCPU stat to ARM64 to record the number of signal
> exits to userspace.
>
> Patch 2 unhitches entry-kvm from entry-generic, as ARM64 doesn't
> currently support the generic infrastructure.
>
> Patch 3 replaces the open-coded entry handling with the generic xfer
> function.
>
> This series was tested on an Ampere Mt. Jade reference system. The
> series cleanly applies to kvm/queue (note that this is deliberate as the
> generic kvm stats patches have not yet propagated to kvm-arm/queue) at
> the following commit:
>
> 8ad5e63649ff ("KVM: Don't take mmu_lock for range invalidation unless necessary")
>
> v1 -> v2:
>  - Address Jing's comment
>  - Carry Jing's r-b tag
>
> v2 -> v3:
>  - Roll all exit conditions into kvm_vcpu_exit_request() (Marc)
>  - Avoid needlessly checking for work twice (Marc)
>
> v1: http://lore.kernel.org/r/20210729195632.489978-1-oupton at google.com
> v2: http://lore.kernel.org/r/20210729220916.1672875-1-oupton at google.com
>
> Oliver Upton (3):
>   KVM: arm64: Record number of signal exits as a vCPU stat
>   entry: KVM: Allow use of generic KVM entry w/o full generic support
>   KVM: arm64: Use generic KVM xfer to guest work function
>
>  arch/arm64/include/asm/kvm_host.h |  1 +
>  arch/arm64/kvm/Kconfig            |  1 +
>  arch/arm64/kvm/arm.c              | 71 +++++++++++++++++++------------
>  arch/arm64/kvm/guest.c            |  1 +
>  include/linux/entry-kvm.h         |  6 ++-
>  5 files changed, 52 insertions(+), 28 deletions(-)
>
> --
> 2.32.0.554.ge1b32706d8-goog
>


From lkp at intel.com  Sun Aug 15 01:36:43 2021
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Aug 2021 16:36:43 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS cbfece75186d6dae6e0fe2b3492ac76eb380afdb
Message-ID: <6118d21b.QBmeKDwdFgCRj7jx%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: cbfece75186d6dae6e0fe2b3492ac76eb380afdb  ARM: ixp4xx: fix building both pci drivers

elapsed time: 3479m

configs tested: 142
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
powerpc                     pq2fads_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
mips                  cavium_octeon_defconfig
nds32                               defconfig
parisc                           alldefconfig
arm                      tct_hammer_defconfig
powerpc                      obs600_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
s390                          debug_defconfig
openrisc                  or1klitex_defconfig
arc                    vdk_hs38_smp_defconfig
csky                                defconfig
mips                           ip32_defconfig
xtensa                              defconfig
sh                          polaris_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
mips                          rm200_defconfig
arm                           stm32_defconfig
powerpc                       ppc64_defconfig
xtensa                  audio_kc705_defconfig
mips                      loongson3_defconfig
mips                          ath79_defconfig
sh                          r7780mp_defconfig
powerpc                     rainier_defconfig
arm                       cns3420vb_defconfig
mips                          ath25_defconfig
arm                          simpad_defconfig
m68k                             allyesconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                     ppa8548_defconfig
powerpc                        icon_defconfig
sh                          urquell_defconfig
microblaze                      mmu_defconfig
arm                         nhk8815_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
s390                                defconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                                  kexec
x86_64                               rhel-8.3

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sun Aug 15 01:43:10 2021
From: lkp at intel.com (kernel test robot)
Date: Sun, 15 Aug 2021 16:43:10 +0800
Subject: [soc:arm/soc] BUILD SUCCESS e694952772a7df091a6cffe828409843f53c9822
Message-ID: <6118d39e.7o52ydqP82LJTRaH%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/soc
branch HEAD: e694952772a7df091a6cffe828409843f53c9822  Merge tag 'omap-for-v5.15/soc-late-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/soc

elapsed time: 3485m

configs tested: 142
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
powerpc                     pq2fads_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
mips                  cavium_octeon_defconfig
nds32                               defconfig
parisc                           alldefconfig
arm                      tct_hammer_defconfig
powerpc                      obs600_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
s390                          debug_defconfig
openrisc                  or1klitex_defconfig
arc                    vdk_hs38_smp_defconfig
csky                                defconfig
mips                           ip32_defconfig
xtensa                              defconfig
sh                          polaris_defconfig
sh                          sdk7786_defconfig
sh                         microdev_defconfig
arm                          pxa910_defconfig
sh                           se7780_defconfig
mips                          rm200_defconfig
arm                           stm32_defconfig
powerpc                       ppc64_defconfig
xtensa                  audio_kc705_defconfig
mips                      loongson3_defconfig
mips                          ath79_defconfig
sh                          r7780mp_defconfig
powerpc                     rainier_defconfig
arm                       cns3420vb_defconfig
mips                          ath25_defconfig
arm                          simpad_defconfig
m68k                             allyesconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                     ppa8548_defconfig
powerpc                        icon_defconfig
sh                          urquell_defconfig
microblaze                      mmu_defconfig
arm                         nhk8815_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
s390                                defconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                                  kexec
x86_64                               rhel-8.3

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From maz at kernel.org  Sun Aug 15 02:21:08 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 15 Aug 2021 10:21:08 +0100
Subject: [PATCH v3 0/3] KVM: arm64: Use generic guest entry infrastructure
In-Reply-To: <CAOQ_Qsj0UH=3FQNP3NTjX-rcU68s0hm6k5g7i_rwqKc4b84DZA@mail.gmail.com>
References: <20210802192809.1851010-1-oupton@google.com>
 <CAOQ_Qsj0UH=3FQNP3NTjX-rcU68s0hm6k5g7i_rwqKc4b84DZA@mail.gmail.com>
Message-ID: <875yw712t7.wl-maz@kernel.org>

On Sun, 15 Aug 2021 08:50:09 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Friendly ping :)

Ah, thanks for reminding me of this. I'll have a look again early next
week.

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Sun Aug 15 02:27:28 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 15 Aug 2021 10:27:28 +0100
Subject: [PATCH 0/5] arm64: Survival kit for SCR_EL3.HCE==0 conditions
In-Reply-To: <7ffa35bb-1f2c-19ff-fe4b-33267fba80e8@gmail.com>
References: <20210812190213.2601506-1-maz@kernel.org>
 <7ffa35bb-1f2c-19ff-fe4b-33267fba80e8@gmail.com>
Message-ID: <874kbr12in.wl-maz@kernel.org>

On Sun, 15 Aug 2021 08:28:47 +0100,
Florian Fainelli <f.fainelli at gmail.com> wrote:
> 
> 
> 
> On 8/12/2021 9:02 PM, Marc Zyngier wrote:
> > Anyone vaguely familiar with the ARMv8 architecture would quickly
> > understand that entering the kernel at EL2 without enabling the HVC
> > instruction is... living dangerously. But as it turns out [0], there
> > is a whole range of (*cough*) "high quality" (*cough*) Broadcom
> > systems out there configured exactly like that.
> 
> Some Broadcom systems, namely the 4908 and all of those using CFE,
> they later switched to u-boot and ATF and got it right.

Do we have a list of the affected systems?

> 
> > 
> > If you are speechless, I'm right with you.
> > 
> > These machines have stopped being able to boot an upstream kernel
> > since 5.12, where we changed the way we switch from nVHE to VHE, as
> > this relies on the HVC instruction being usable... It is also worth
> > noting that these systems have never been able to use KVM. Or kexec.
> > 
> > This small series addresses the issue by detecting an UNDEFing HVC in
> > a fairly controlled environment, and in this case pretend that we have
> > booted at EL1. It also documents the requirement for SCR_EL3.HCE to be
> > set to *1* if the kernel is entered at EL2. Turns out that we really
> > have to state the obvious.
> > 
> > This has been tested on a FVP model with a hacked-up boot-wrapper.
> > 
> > Note that I really don't think any of this is -stable material, except
> > maybe for the documentation. It isn't 5.14 material either. Best case,
> > this is 5.15, or maybe even later. If ever.
> 
> While I am very appreciative of the work you have done here to try to
> get the dysfunctional systems to warn and continue to boot, I would
> rather we try to load a minimal shim at EL3 capable of fixing up any
> incorrect EL3 register setting ahead of loading the kernel provided
> this is possible at all on a commercially available system.

That would be the best thing to do, and would make the machine fully
usable. I still think we need to have something in the kernel to at
least let the user know that their system is misconfigured though.

If CFE allows a payload to be loaded at EL3 and executed on all CPUs,
that would be absolutely awesome. It would even allow switching over
to ATF...

Thanks,

	M.

> Rafal, is this something that CFE allows you to do (as I could not
> get a straight answer from that team), if so have you tried it?
> -- 
> Florian
> 

-- 
Without deviation from the norm, progress is not possible.


From jason-jh.lin at mediatek.com  Sun Aug 15 07:55:58 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:55:58 +0800
Subject: [PATCH v7 01/13] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC
 binding
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-2-jason-jh.lin@mediatek.com>

1. There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195.
   Each of them is bound to a display pipeline, so add their
   definition in mtk-mmsys documentation with 2 compatibles.

2. Add description for power-domain property.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml  | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 2d4ff0ce387b..68cb330d7595 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -30,6 +30,8 @@ properties:
               - mediatek,mt8173-mmsys
               - mediatek,mt8183-mmsys
               - mediatek,mt8365-mmsys
+              - mediatek,mt8195-vdosys0
+              - mediatek,mt8195-vdosys1
           - const: syscon
       - items:
           - const: mediatek,mt7623-mmsys
@@ -39,6 +41,12 @@ properties:
   reg:
     maxItems: 1
 
+  power-domains:
+    description:
+      A phandle and PM domain specifier as defined by bindings
+      of the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
   "#clock-cells":
     const: 1
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:05 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:05 +0800
Subject: [PATCH v7 08/13] drm/mediatek: remove unused define in
 mtk_drm_ddp_comp.c
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-9-jason-jh.lin@mediatek.com>

Remove the unsed define in mtk_drm_ddp_comp.c

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 75bc00e17fc4..aaa7450b3e2b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -21,8 +21,6 @@
 #include "mtk_drm_crtc.h"
 
 #define DISP_OD_EN				0x0000
-#define DISP_OD_INTEN				0x0008
-#define DISP_OD_INTSTA				0x000c
 #define DISP_OD_CFG				0x0020
 #define DISP_OD_SIZE				0x0030
 #define DISP_DITHER_5				0x0114
@@ -42,8 +40,6 @@
 #define DITHER_ENGINE_EN			BIT(1)
 #define DISP_DITHER_SIZE			0x0030
 
-#define LUT_10BIT_MASK				0x03ff
-
 #define OD_RELAYMODE				BIT(0)
 
 #define UFO_BYPASS				BIT(2)
@@ -52,18 +48,12 @@
 
 #define DISP_DITHERING				BIT(2)
 #define DITHER_LSB_ERR_SHIFT_R(x)		(((x) & 0x7) << 28)
-#define DITHER_OVFLW_BIT_R(x)			(((x) & 0x7) << 24)
 #define DITHER_ADD_LSHIFT_R(x)			(((x) & 0x7) << 20)
-#define DITHER_ADD_RSHIFT_R(x)			(((x) & 0x7) << 16)
 #define DITHER_NEW_BIT_MODE			BIT(0)
 #define DITHER_LSB_ERR_SHIFT_B(x)		(((x) & 0x7) << 28)
-#define DITHER_OVFLW_BIT_B(x)			(((x) & 0x7) << 24)
 #define DITHER_ADD_LSHIFT_B(x)			(((x) & 0x7) << 20)
-#define DITHER_ADD_RSHIFT_B(x)			(((x) & 0x7) << 16)
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
-#define DITHER_OVFLW_BIT_G(x)			(((x) & 0x7) << 8)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
-#define DITHER_ADD_RSHIFT_G(x)			(((x) & 0x7) << 0)
 
 struct mtk_ddp_comp_dev {
 	struct clk *clk;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:02 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:02 +0800
Subject: [PATCH v7 05/13] arm64: dts: mt8195: add display node for vdosys0
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-6-jason-jh.lin@mediatek.com>

Add display node for vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
---
This patch is based on [1][2][3]

[1]arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
[2]arm64: dts: mt8195: add IOMMU and smi nodes
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
[3]arm64: dts: mt8195: add gce node
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210705053429.4380-4-jason-jh.lin at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 111 +++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 04d3e95175fa..aa2a7849b822 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1155,9 +1155,120 @@
 			#clock-cells = <1>;
 		};
 
+		ovl0: disp_ovl at 1c000000 {
+			compatible = "mediatek,mt8195-disp-ovl",
+				     "mediatek,mt8183-disp-ovl";
+			reg = <0 0x1c000000 0 0x1000>;
+			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_OVL0_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x0000 0x1000>;
+		};
+
+		rdma0: disp_rdma at 1c002000 {
+			compatible = "mediatek,mt8195-disp-rdma";
+			reg = <0 0x1c002000 0 0x1000>;
+			interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_RDMA0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x2000 0x1000>;
+		};
+
+		color0: disp_color at 1c003000 {
+			compatible = "mediatek,mt8195-disp-color",
+				     "mediatek,mt8173-disp-color";
+			reg = <0 0x1c003000 0 0x1000>;
+			interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_COLOR0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x3000 0x1000>;
+		};
+
+		ccorr0: disp_ccorr at 1c004000 {
+			compatible = "mediatek,mt8195-disp-ccorr",
+				     "mediatek,mt8183-disp-ccorr";
+			reg = <0 0x1c004000 0 0x1000>;
+			interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_CCORR0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x4000 0x1000>;
+		};
+
+		aal0: disp_aal at 1c005000 {
+			compatible = "mediatek,mt8195-disp-aal",
+				     "mediatek,mt8173-disp-aal";
+			reg = <0 0x1c005000 0 0x1000>;
+			interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_AAL0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x5000 0x1000>;
+		};
+
+		gamma0: disp_gamma at 1c006000 {
+			compatible = "mediatek,mt8195-disp-gamma",
+				     "mediatek,mt8173-disp-gamma";
+			reg = <0 0x1c006000 0 0x1000>;
+			interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_GAMMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x6000 0x1000>;
+		};
+
+		dither0: disp_dither at 1c007000 {
+			compatible = "mediatek,mt8195-disp-dither",
+				     "mediatek,mt8183-disp-dither";
+			reg = <0 0x1c007000 0 0x1000>;
+			interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_DITHER0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x7000 0x1000>;
+		};
+
+		dsc0: disp_dsc_wrap at 1c009000 {
+			compatible = "mediatek,mt8195-disp-dsc";
+			reg = <0 0x1c009000 0 0x1000>;
+			interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+		};
+
+		merge0: disp_vpp_merge0 at 1c014000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c014000 0 0x1000>;
+			interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_VPP_MERGE0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c01XXXX 0x4000 0x1000>;
+		};
+
+		mutex: disp_mutex0 at 1c016000 {
+			compatible = "mediatek,mt8195-disp-mutex";
+			reg = <0 0x1c016000 0 0x1000>;
+			reg-names = "vdo0_mutex";
+			interrupts = <GIC_SPI 658 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_MUTEX0>;
+			clock-names = "vdo0_mutex";
+			mediatek,gce-events =
+				 <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;
+		};
+
 		vdosys0: syscon at 1c01a000 {
 			compatible = "mediatek,mt8195-vdosys0", "syscon";
 			reg = <0 0x1c01a000 0 0x1000>;
+			mboxes = <&gce1 0 CMDQ_THR_PRIO_4>;
 			#clock-cells = <1>;
 		};
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:55:57 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:55:57 +0800
Subject: [PATCH v7 00/13] Add Mediatek Soc DRM (vdosys0) support for mt8195
Message-ID: <20210815145610.2050-1-jason-jh.lin@mediatek.com>

Change in v7:
- add dt=binding of mmsys and disp path into this series
- separate th modidfication of alphabetic order, remove unused define and
  rename the define of register offset to individual patch
- add comment for MERGE ultra and preultra setting

Change in v6:
- adjust alphabetic order for mediatek-drm
- move the patch that add mt8195 support for mediatek-drm as the lastest patch
- add MERGE define for const varriable 

Change in v5:
- add power-domain property into vdosys0 and vdosys1 dts node.
- add MT8195 prifix and remove unused VDO1 define in mt8195-mmsys.h

Change in v4:
- extract dt-binding patches to another patch series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597
- squash DSC module into mtk_drm_ddp_comp.c
- add coment and simplify MERGE config function

Change in v3:
- change mmsys and display dt-bindings document from txt to yaml
- add MERGE additional description in display dt-bindings document
- fix mboxes-cells number of vdosys0 node in dts
- drop mutex eof convert define
- remove pm_runtime apis in DSC and MERGE
- change DSC and MERGE enum to alphabetic order

Change in v2:
- add DSC yaml file
- add mt8195 drm driver porting parts in to one patch
- remove useless define, variable, structure member and function
- simplify DSC and MERGE file and switch threre order

jason-jh.lin (13):
  dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
  dt-bindings: mediatek: display: split each block to individual yaml
  dt-bindings: mediatek: add mediatek,dsc.yaml for mt8195 SoC binding
  dt-bindings: mediatek: display: add mt8195 SoC binding
  arm64: dts: mt8195: add display node for vdosys0
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
  soc: mediatek: add mtk-mutex support for mt8195 vdosys0
  drm/mediatek: remove unused define in mtk_drm_ddp_comp.c
  drm/mediatek: rename the define of register offset
  drm/mediatek: adjust to the alphabetic order for mediatek-drm
  drm/mediatek: add DSC support for mediatek-drm
  drm/mediatek: add MERGE support for mediatek-drm
  drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |   8 +
 .../display/mediatek/mediatek,aal.yaml        |  76 +++++
 .../display/mediatek/mediatek,ccorr.yaml      |  74 +++++
 .../display/mediatek/mediatek,color.yaml      |  85 ++++++
 .../display/mediatek/mediatek,disp.txt        | 219 --------------
 .../display/mediatek/mediatek,dither.yaml     |  75 +++++
 .../display/mediatek/mediatek,dsc.yaml        |  69 +++++
 .../display/mediatek/mediatek,gamma.yaml      |  76 +++++
 .../display/mediatek/mediatek,merge.yaml      |  97 +++++++
 .../display/mediatek/mediatek,mutex.yaml      |  79 ++++++
 .../display/mediatek/mediatek,od.yaml         |  52 ++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  86 ++++++
 .../display/mediatek/mediatek,ovl.yaml        | 101 +++++++
 .../display/mediatek/mediatek,rdma.yaml       | 112 ++++++++
 .../display/mediatek/mediatek,split.yaml      |  56 ++++
 .../display/mediatek/mediatek,ufoe.yaml       |  59 ++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 ++++++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 111 ++++++++
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 268 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |   6 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   | 239 ++++++++++------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  24 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        | 109 ++++---
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   1 +
 drivers/soc/mediatek/mt8195-mmsys.h           | 106 +++++++
 drivers/soc/mediatek/mtk-mmsys.c              |  11 +
 drivers/soc/mediatek/mtk-mutex.c              |  93 +++++-
 include/linux/soc/mediatek/mtk-mmsys.h        |   9 +
 30 files changed, 2031 insertions(+), 365 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:00 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:00 +0800
Subject: [PATCH v7 03/13] dt-bindings: mediatek: add mediatek,
 dsc.yaml for mt8195 SoC binding
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-4-jason-jh.lin@mediatek.com>

1. Add mediatek,dsc.yaml to describe DSC module in details.
2. Add mt8195 SoC binding to mediatek,dsc.yaml.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,dsc.yaml        | 69 +++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
new file mode 100644
index 000000000000..f94a95c6a1c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display DSC controller
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The DSC standard is a specification of the algorithms used for
+  compressing and decompressing image display streams, including
+  the specification of the syntax and semantics of the compressed
+  video bit stream. DSC is designed for real-time systems with
+  real-time compression, transmission, decompression and Display.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-disp-dsc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: DSC Wrapper Clock
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  mediatek,gce-client-reg:
+      description:
+        The register of display function block to be set by gce. There are 4 arguments,
+        such as gce node, subsys id, offset and register size. The subsys id that is
+        mapping to the register of display function blocks is defined in the gce header
+        include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+      $ref: /schemas/types.yaml#/definitions/phandle-array
+      maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dsc0: disp_dsc_wrap at 1c009000 {
+        compatible = "mediatek,mt8195-disp-dsc";
+        reg = <0 0x1c009000 0 0x1000>;
+        interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+        clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+    };
+
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:03 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:03 +0800
Subject: [PATCH v7 06/13] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys0
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-7-jason-jh.lin@mediatek.com>

Add mt8195 vdosys0 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is base on [1]
[1] soc: mmsys: mediatek: add mask to mmsys routes
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210729070549.5514-1-linux at fw-web.de/

The vdosys1 impelmentation patch [2] will base on this patch
[2] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210722094551.15255-8-nancy.lin at mediatek.com/
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 106 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       |  11 +++
 include/linux/soc/mediatek/mtk-mmsys.h |   9 +++
 3 files changed, 126 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
new file mode 100644
index 000000000000..52053da8ee59
--- /dev/null
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
+#define __SOC_MEDIATEK_MT8195_MMSYS_H
+
+#define MT8195_VDO0_OVL_MOUT_EN					0xf14
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
+
+#define MT8195_VDO0_SEL_IN					0xf34
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		(0 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		(1 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		(2 << 0)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		(0 << 4)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		(1 << 4)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		(0 << 5)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		(1 << 5)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		(0 << 8)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		(1 << 8)
+#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		(0 << 9)
+#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		(0 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			(1 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		(2 << 12)
+#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			(0 << 16)
+#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			(1 << 16)
+#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			(0 << 17)
+#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			(1 << 17)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			(0 << 20)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			(1 << 20)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		(0 << 21)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		(1 << 21)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			(0 << 22)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_VPP_MERGE			(1 << 22)
+
+#define MT8195_VDO0_SEL_OUT					0xf38
+#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		(0 << 0)
+#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			(1 << 0)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		(0 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			(1 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		(2 << 1)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			(0 << 4)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			(1 << 4)
+#define MT8195_SOUT_VPP_MERGE_TO_DSI1				(0 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			(1 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			(2 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(3 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			(4 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			(0 << 11)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA0			(1 << 11)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			(0 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		(1 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			(2 << 12)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			(0 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			(1 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(3 << 16)
+
+static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
+		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
+		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT,
+		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0,
+		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT,
+		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0,
+		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN,
+		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0,
+		MT8195_SOUT_DISP_DITHER0_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
+	}
+};
+
+#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index a78e88f27b62..ce6cc2f49e7d 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -14,6 +14,7 @@
 #include "mt8167-mmsys.h"
 #include "mt8183-mmsys.h"
 #include "mt8365-mmsys.h"
+#include "mt8195-mmsys.h"
 
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.clk_driver = "clk-mt2701-mm",
@@ -59,6 +60,12 @@ static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
 	.num_routes = ARRAY_SIZE(mt8365_mmsys_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.clk_driver = "clk-mt8195-vdo0",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
@@ -171,6 +178,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8365-mmsys",
 		.data = &mt8365_mmsys_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys0",
+		.data = &mt8195_vdosys0_driver_data,
+	},
 	{ }
 };
 
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 2228bf6133da..01bedfb08094 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -39,6 +39,15 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_UFOE,
 	DDP_COMPONENT_WDMA0,
 	DDP_COMPONENT_WDMA1,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_MERGE1,
+	DDP_COMPONENT_MERGE2,
+	DDP_COMPONENT_MERGE3,
+	DDP_COMPONENT_MERGE4,
+	DDP_COMPONENT_MERGE5,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_DSC1,
+	DDP_COMPONENT_DP_INTF0,
 	DDP_COMPONENT_ID_MAX,
 };
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:07 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:07 +0800
Subject: [PATCH v7 10/13] drm/mediatek: adjust to the alphabetic order for
 mediatek-drm
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-11-jason-jh.lin@mediatek.com>

Adjust to the alphabetic order for the define, function, struct
and array in mediatek-drm driver

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 133 ++++++++++----------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  22 ++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  76 +++++------
 3 files changed, 115 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 93beb980414f..28bc42fd0b8a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -20,17 +20,9 @@
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_crtc.h"
 
-#define DISP_REG_OD_EN				0x0000
-#define DISP_REG_OD_CFG				0x0020
-#define DISP_REG_OD_SIZE			0x0030
-#define DISP_REG_DITHER_5			0x0114
-#define DISP_REG_DITHER_7			0x011c
-#define DISP_REG_DITHER_15			0x013c
-#define DISP_REG_DITHER_16			0x0140
-
-#define DISP_REG_UFO_START			0x0000
 
 #define DISP_REG_AAL_EN				0x0000
+#define AAL_EN					BIT(0)
 #define DISP_REG_AAL_SIZE			0x0030
 
 #define DISP_REG_DITHER_EN			0x0000
@@ -38,23 +30,29 @@
 #define DISP_REG_DITHER_CFG			0x0020
 #define DITHER_RELAY_MODE			BIT(0)
 #define DITHER_ENGINE_EN			BIT(1)
-#define DISP_REG_DITHER_SIZE			0x0030
-
-#define OD_RELAYMODE				BIT(0)
-
-#define UFO_BYPASS				BIT(2)
-
-#define AAL_EN					BIT(0)
 
 #define DISP_DITHERING				BIT(2)
+#define DISP_REG_DITHER_SIZE			0x0030
+#define DISP_REG_DITHER_5			0x0114
+#define DISP_REG_DITHER_7			0x011c
+#define DISP_REG_DITHER_15			0x013c
 #define DITHER_LSB_ERR_SHIFT_R(x)		(((x) & 0x7) << 28)
 #define DITHER_ADD_LSHIFT_R(x)			(((x) & 0x7) << 20)
 #define DITHER_NEW_BIT_MODE			BIT(0)
+#define DISP_REG_DITHER_16			0x0140
 #define DITHER_LSB_ERR_SHIFT_B(x)		(((x) & 0x7) << 28)
 #define DITHER_ADD_LSHIFT_B(x)			(((x) & 0x7) << 20)
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_OD_EN				0x0000
+#define DISP_REG_OD_CFG				0x0020
+#define OD_RELAYMODE				BIT(0)
+#define DISP_REG_OD_SIZE			0x0030
+
+#define DISP_REG_UFO_START			0x0000
+#define UFO_BYPASS				BIT(2)
+
 struct mtk_ddp_comp_dev {
 	struct clk *clk;
 	void __iomem *regs;
@@ -106,20 +104,6 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 #endif
 }
 
-static int mtk_ddp_clk_enable(struct device *dev)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	return clk_prepare_enable(priv->clk);
-}
-
-static void mtk_ddp_clk_disable(struct device *dev)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	clk_disable_unprepare(priv->clk);
-}
-
 void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 			   unsigned int bpc, unsigned int cfg,
 			   unsigned int dither_en, struct cmdq_pkt *cmdq_pkt)
@@ -146,38 +130,19 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 	}
 }
 
-static void mtk_dither_set(struct device *dev, unsigned int bpc,
-		    unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
-			      DISP_DITHERING, cmdq_pkt);
-}
-
-static void mtk_od_config(struct device *dev, unsigned int w,
-			  unsigned int h, unsigned int vrefresh,
-			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
-	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
-	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
-}
 
-static void mtk_od_start(struct device *dev)
+static int mtk_ddp_clk_enable(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(1, priv->regs + DISP_REG_OD_EN);
+	return clk_prepare_enable(priv->clk);
 }
 
-static void mtk_ufoe_start(struct device *dev)
+static void mtk_ddp_clk_disable(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
+	clk_disable_unprepare(priv->clk);
 }
 
 static void mtk_aal_config(struct device *dev, unsigned int w,
@@ -237,6 +202,40 @@ static void mtk_dither_stop(struct device *dev)
 	writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
 }
 
+static void mtk_dither_set(struct device *dev, unsigned int bpc,
+			   unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
+			      DISP_DITHERING, cmdq_pkt);
+}
+
+static void mtk_od_config(struct device *dev, unsigned int w,
+			  unsigned int h, unsigned int vrefresh,
+			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
+	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
+	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
+}
+
+static void mtk_od_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel(1, priv->regs + DISP_REG_OD_EN);
+}
+
+static void mtk_ufoe_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
+}
+
 static const struct mtk_ddp_comp_funcs ddp_aal = {
 	.clk_enable = mtk_ddp_clk_enable,
 	.clk_disable = mtk_ddp_clk_disable,
@@ -331,22 +330,22 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
 };
 
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
+	[MTK_DISP_AAL] = "aal",
+	[MTK_DISP_BLS] = "bls",
+	[MTK_DISP_CCORR] = "ccorr",
+	[MTK_DISP_COLOR] = "color",
+	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
 	[MTK_DISP_OVL_2L] = "ovl-2l",
+	[MTK_DISP_PWM] = "pwm",
 	[MTK_DISP_RDMA] = "rdma",
-	[MTK_DISP_WDMA] = "wdma",
-	[MTK_DISP_COLOR] = "color",
-	[MTK_DISP_CCORR] = "ccorr",
-	[MTK_DISP_AAL] = "aal",
-	[MTK_DISP_GAMMA] = "gamma",
-	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_UFOE] = "ufoe",
-	[MTK_DSI] = "dsi",
+	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
-	[MTK_DISP_PWM] = "pwm",
-	[MTK_DISP_MUTEX] = "mutex",
-	[MTK_DISP_OD] = "od",
-	[MTK_DISP_BLS] = "bls",
+	[MTK_DSI] = "dsi",
 };
 
 struct mtk_ddp_comp_match {
@@ -500,12 +499,12 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
-	    type == MTK_DPI ||
-	    type == MTK_DSI ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
-	    type == MTK_DISP_RDMA)
+	    type == MTK_DISP_RDMA ||
+	    type == MTK_DPI ||
+	    type == MTK_DSI)
 		return 0;
 
 	priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index bb914d976cf5..d317b944df66 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -18,22 +18,22 @@ struct mtk_plane_state;
 struct drm_crtc_state;
 
 enum mtk_ddp_comp_type {
-	MTK_DISP_OVL,
-	MTK_DISP_OVL_2L,
-	MTK_DISP_RDMA,
-	MTK_DISP_WDMA,
-	MTK_DISP_COLOR,
+	MTK_DISP_AAL,
+	MTK_DISP_BLS,
 	MTK_DISP_CCORR,
+	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
-	MTK_DISP_AAL,
 	MTK_DISP_GAMMA,
-	MTK_DISP_UFOE,
-	MTK_DSI,
-	MTK_DPI,
-	MTK_DISP_PWM,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-	MTK_DISP_BLS,
+	MTK_DISP_OVL,
+	MTK_DISP_OVL_2L,
+	MTK_DISP_PWM,
+	MTK_DISP_RDMA,
+	MTK_DISP_UFOE,
+	MTK_DISP_WDMA,
+	MTK_DPI,
+	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b46bdb8985da..a95dc1006b82 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -396,50 +396,20 @@ static const struct component_master_ops mtk_drm_ops = {
 };
 
 static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
-	{ .compatible = "mediatek,mt2701-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8173-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8183-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
-	  .data = (void *)MTK_DISP_OVL_2L },
-	{ .compatible = "mediatek,mt2701-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8173-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8183-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8173-disp-wdma",
-	  .data = (void *)MTK_DISP_WDMA },
+	{ .compatible = "mediatek,mt8173-disp-aal",
+	  .data = (void *)MTK_DISP_AAL},
 	{ .compatible = "mediatek,mt8183-disp-ccorr",
 	  .data = (void *)MTK_DISP_CCORR },
 	{ .compatible = "mediatek,mt2701-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8173-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
-	{ .compatible = "mediatek,mt8173-disp-aal",
-	  .data = (void *)MTK_DISP_AAL},
+	{ .compatible = "mediatek,mt8183-disp-dither",
+	  .data = (void *)MTK_DISP_DITHER },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
-	{ .compatible = "mediatek,mt8183-disp-dither",
-	  .data = (void *)MTK_DISP_DITHER },
-	{ .compatible = "mediatek,mt8173-disp-ufoe",
-	  .data = (void *)MTK_DISP_UFOE },
-	{ .compatible = "mediatek,mt2701-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt8173-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt8183-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt2701-dpi",
-	  .data = (void *)MTK_DPI },
-	{ .compatible = "mediatek,mt8173-dpi",
-	  .data = (void *)MTK_DPI },
-	{ .compatible = "mediatek,mt8183-dpi",
-	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -448,12 +418,42 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8173-disp-od",
+	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt2701-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8173-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8183-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
+	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt2701-disp-pwm",
 	  .data = (void *)MTK_DISP_BLS },
 	{ .compatible = "mediatek,mt8173-disp-pwm",
 	  .data = (void *)MTK_DISP_PWM },
-	{ .compatible = "mediatek,mt8173-disp-od",
-	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt2701-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8173-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8183-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8173-disp-ufoe",
+	  .data = (void *)MTK_DISP_UFOE },
+	{ .compatible = "mediatek,mt8173-disp-wdma",
+	  .data = (void *)MTK_DISP_WDMA },
+	{ .compatible = "mediatek,mt2701-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8173-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8183-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt2701-dsi",
+	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8173-dsi",
+	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8183-dsi",
+	  .data = (void *)MTK_DSI },
 	{ }
 };
 
@@ -542,8 +542,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
-		    comp_type == MTK_DSI ||
-		    comp_type == MTK_DPI) {
+		    comp_type == MTK_DPI ||
+		    comp_type == MTK_DSI) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, compare_of,
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:01 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:01 +0800
Subject: [PATCH v7 04/13] dt-bindings: mediatek: display: add mt8195 SoC
 binding
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-5-jason-jh.lin@mediatek.com>

1. Add mt8195 SoC binding to AAL, CCORR, COLOR, DITHER, GAMMA, MERGE,
   MUTEX, OVL and RDMA yaml schema.

2. Add MERGE additional property description for mt8195
- async clock
- fifo setting enable
- reset controller

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,aal.yaml        |  1 +
 .../display/mediatek/mediatek,ccorr.yaml      |  5 +++
 .../display/mediatek/mediatek,color.yaml      |  1 +
 .../display/mediatek/mediatek,dither.yaml     |  5 +++
 .../display/mediatek/mediatek,gamma.yaml      |  5 +++
 .../display/mediatek/mediatek,merge.yaml      | 40 +++++++++++++++++++
 .../display/mediatek/mediatek,mutex.yaml      |  2 +
 .../display/mediatek/mediatek,ovl.yaml        |  5 +++
 .../display/mediatek/mediatek,rdma.yaml       |  2 +
 9 files changed, 66 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
index 7be772d77e36..e1820238db43 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -25,6 +25,7 @@ properties:
           - enum:
               - mediatek,mt2712-disp-aal
               - mediatek,mt8183-disp-aal
+              - mediatek,mt8195-disp-aal
           - enum:
               - mediatek,mt8173-disp-aal
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
index 5a1c27d6b3e2..4c556a2bc64a 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -21,6 +21,11 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8183-disp-ccorr
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ccorr
+          - enum:
+              - mediatek,mt8183-disp-ccorr
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
index 9a3edf6f0b8e..a13096196a0c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -35,6 +35,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8183-disp-color
+              - mediatek,mt8195-disp-color
           - enum:
               - mediatek,mt8173-disp-color
   reg:
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
index 20419f876410..e89fe7393291 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -22,6 +22,11 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8183-disp-dither
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-dither
+          - enum:
+              - mediatek,mt8183-disp-dither
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
index e2a1fc218e4f..dc78d6d05dee 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -23,6 +23,11 @@ properties:
           - const: mediatek,mt8173-disp-gamma
       - items:
           - const: mediatek,mt8183-disp-gamma
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-gamma
+          - enum:
+              - mediatek,mt8183-disp-gamma
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 4cdce11d7fcd..1a27b037086b 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -21,6 +21,8 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8173-disp-merge
+      - items:
+          - const: mediatek,mt8195-disp-merge
 
   reg:
     maxItems: 1
@@ -36,6 +38,31 @@ properties:
   clocks:
     items:
       - description: MERGE Clock
+      - description: MERGE Async Clock
+          Controlling the synchronous process between MERGE and other display function
+          blocks cross clock domain.
+
+  mediatek,merge-fifo-en:
+      description:
+	    The setting of merge fifo is mainly provided for the display latency buffer.
+        to ensure that the back-end panel display data will not be underrun,
+        a little more data is needed in the fifo. According to the merge fifo settings,
+        when the water level is detected to be insufficient, it will trigger RDMA sending
+        ultra and preulra command to SMI to speed up the data rate.
+      type: boolean
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+  resets:
+    description: reset controller
+      See Documentation/devicetree/bindings/reset/reset.txt for details.
 
 required:
   - compatible
@@ -55,3 +82,16 @@ examples:
         clocks = <&mmsys CLK_MM_DISP_MERGE>;
     };
 
+    merge5: disp_vpp_merge5 at 1c110000 {
+        compatible = "mediatek,mt8195-disp-merge";
+        reg = <0 0x1c110000 0 0x1000>;
+        interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+                 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+        clock-names = "merge","merge_async";
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+        mediatek,merge-fifo-en = <1>;
+        resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
index aaba6bbfb4da..0dced7a53329 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -30,6 +30,8 @@ properties:
           - const: mediatek,mt8173-disp-mutex
       - items:
           - const: mediatek,mt8183-disp-mutex
+      - items:
+          - const: mediatek,mt8195-disp-mutex
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 833b0ca09b21..1973eee4244f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -31,6 +31,11 @@ properties:
               - mediatek,mt2712-disp-ovl
           - enum:
               - mediatek,mt2701-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ovl
+          - enum:
+              - mediatek,mt8183-disp-ovl
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
index ce3bcca30609..847bc55252ca 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -27,6 +27,8 @@ properties:
           - const: mediatek,mt8173-disp-rdma
       - items:
           - const: mediatek,mt8183-disp-rdma
+      - items:
+          - const: mediatek,mt8195-disp-rdma
       - items:
           - enum:
               - mediatek,mt7623-disp-rdma
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:09 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:09 +0800
Subject: [PATCH v7 12/13] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-13-jason-jh.lin@mediatek.com>

Add MERGE engine file:
MERGE module is used to merge two slice-per-line inputs
into one side-by-side output.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile           |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 268 ++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  16 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   4 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
 7 files changed, 298 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index dc54a7a69005..538e0087a44c 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -3,6 +3,7 @@
 mediatek-drm-y := mtk_disp_ccorr.o \
 		  mtk_disp_color.o \
 		  mtk_disp_gamma.o \
+		  mtk_disp_merge.o \
 		  mtk_disp_ovl.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index cafd9df2d63b..f407cd9d873e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -46,6 +46,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
 void mtk_gamma_start(struct device *dev);
 void mtk_gamma_stop(struct device *dev);
 
+int mtk_merge_clk_enable(struct device *dev);
+void mtk_merge_clk_disable(struct device *dev);
+void mtk_merge_config(struct device *dev, unsigned int width,
+		      unsigned int height, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start(struct device *dev);
+void mtk_merge_stop(struct device *dev);
+
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
 void mtk_ovl_bypass_shadow(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
new file mode 100644
index 000000000000..ebcb646bde9c
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_disp_drv.h"
+
+#define DISP_REG_MERGE_CTRL		0x000
+#define MERGE_EN				1
+#define DISP_REG_MERGE_CFG_0		0x010
+#define DISP_REG_MERGE_CFG_4		0x020
+#define DISP_REG_MERGE_CFG_10		0x038
+/* no swap */
+#define SWAP_MODE				0
+#define FLD_SWAP_MODE				GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_12		0x040
+#define CFG_10_10_1PI_2PO_BUF_MODE		6
+#define CFG_10_10_2PI_2PO_BUF_MODE		8
+#define FLD_CFG_MERGE_MODE			GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_24		0x070
+#define DISP_REG_MERGE_CFG_25		0x074
+#define DISP_REG_MERGE_CFG_36		0x0a0
+#define ULTRA_EN				1
+#define PREULTRA_EN				1
+#define HALT_FOR_DVFS_EN			0
+#define FLD_ULTRA_EN				GENMASK(0, 0)
+#define FLD_PREULTRA_EN				GENMASK(4, 4)
+#define FLD_HALT_FOR_DVFS_EN			GENMASK(8, 8)
+#define DISP_REG_MERGE_CFG_37		0x0a4
+/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
+#define BUFFER_MODE				3
+#define FLD_BUFFER_MODE				GENMASK(1, 0)
+#define DISP_REG_MERGE_CFG_38			0x0a8
+#define FLD_VDE_BLOCK_ULTRA			GENMASK(0, 0)
+#define FLD_VALID_TH_BLOCK_ULTRA		GENMASK(4, 4)
+#define FLD_ULTRA_FIFO_VALID_TH			GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_39		0x0ac
+#define FLD_NVDE_FORCE_PREULTRA			GENMASK(8, 8)
+#define FLD_NVALID_TH_FORCE_PREULTRA		GENMASK(12, 12)
+#define FLD_PREULTRA_FIFO_VALID_TH		GENMASK(31, 16)
+
+/*
+ * For the ultra and preultra settings, 6us ~ 9us is experience value
+ * and the maximum frequency of mmsys clock is 594MHz.
+ */
+#define DISP_REG_MERGE_CFG_40		0x0b0
+/* 6 us, 594M pixel/sec */
+#define ULTRA_TH_LOW			(6 * 594)
+/* 8 us, 594M pixel/sec */
+#define ULTRA_TH_HIGH			(8 * 594)
+#define FLD_ULTRA_TH_LOW		GENMASK(15, 0)
+#define FLD_ULTRA_TH_HIGH		GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_41		0x0b4
+/* 8 us, 594M pixel/sec */
+#define PREULTRA_TH_LOW			(8 * 594)
+/* 9 us, 594M pixel/sec */
+#define PREULTRA_TH_HIGH		(9 * 594)
+#define FLD_PREULTRA_TH_LOW		GENMASK(15, 0)
+#define FLD_PREULTRA_TH_HIGH		GENMASK(31, 16)
+
+struct mtk_disp_merge {
+	void __iomem *regs;
+	struct clk *clk;
+	struct clk *async_clk;
+	struct cmdq_client_reg		cmdq_reg;
+	bool				fifo_en;
+};
+
+void mtk_merge_start(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
+				   struct cmdq_pkt *handle)
+{
+	mtk_ddp_write_mask(handle, ULTRA_EN | PREULTRA_EN << 4 | HALT_FOR_DVFS_EN << 8,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_36,
+			   FLD_ULTRA_EN | FLD_PREULTRA_EN | FLD_HALT_FOR_DVFS_EN);
+
+	mtk_ddp_write_mask(handle, BUFFER_MODE,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_37,
+			   FLD_BUFFER_MODE);
+
+	mtk_ddp_write_mask(handle, 0,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_38,
+			   FLD_VDE_BLOCK_ULTRA | FLD_VALID_TH_BLOCK_ULTRA |
+			   FLD_ULTRA_FIFO_VALID_TH);
+
+	mtk_ddp_write_mask(handle, 0,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_39,
+			   FLD_NVDE_FORCE_PREULTRA | FLD_NVALID_TH_FORCE_PREULTRA |
+			   FLD_PREULTRA_FIFO_VALID_TH);
+
+	mtk_ddp_write_mask(handle, ULTRA_TH_LOW | ULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_40,
+			   FLD_ULTRA_TH_LOW | FLD_ULTRA_TH_HIGH);
+
+	mtk_ddp_write_mask(handle, PREULTRA_TH_LOW | PREULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_41,
+			   FLD_PREULTRA_TH_LOW | FLD_PREULTRA_TH_HIGH);
+}
+
+void mtk_merge_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *handle)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+	unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
+
+	if (!h || !w) {
+		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
+		return;
+	}
+
+	if (priv->fifo_en) {
+		mtk_merge_fifo_setting(priv, handle);
+		mode = CFG_10_10_2PI_2PO_BUF_MODE;
+	}
+
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_0);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_4);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_24);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_25);
+	mtk_ddp_write_mask(handle, SWAP_MODE, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
+	mtk_ddp_write_mask(handle, mode, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_12, FLD_CFG_MERGE_MODE);
+}
+
+int mtk_merge_clk_enable(struct device *dev)
+{
+	int ret = 0;
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		pr_err("merge clk prepare enable failed\n");
+
+	if (priv->async_clk) {
+		ret = clk_prepare_enable(priv->async_clk);
+		if (ret)
+			pr_err("async clk prepare enable failed\n");
+	}
+
+	return ret;
+}
+
+void mtk_merge_clk_disable(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	if (priv->async_clk)
+		clk_disable_unprepare(priv->async_clk);
+
+	clk_disable_unprepare(priv->clk);
+}
+
+static int mtk_disp_merge_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return 0;
+}
+
+static void mtk_disp_merge_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+}
+
+static const struct component_ops mtk_disp_merge_component_ops = {
+	.bind	= mtk_disp_merge_bind,
+	.unbind = mtk_disp_merge_unbind,
+};
+
+static int mtk_disp_merge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct mtk_disp_merge *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap merge\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get merge clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	priv->async_clk = of_clk_get(dev->of_node, 1);
+	if (IS_ERR(priv->async_clk)) {
+		ret = PTR_ERR(priv->async_clk);
+		dev_dbg(dev, "No merge async clock: %d\n", ret);
+		priv->async_clk = NULL;
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+	priv->fifo_en = of_property_read_bool(dev->of_node,
+					      "mediatek,merge-fifo-en");
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_disp_merge_component_ops);
+	if (ret != 0)
+		dev_err(dev, "Failed to add component: %d\n", ret);
+
+	return ret;
+}
+
+static int mtk_disp_merge_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_disp_merge_component_ops);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_disp_merge_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-merge", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
+
+struct platform_driver mtk_disp_merge_driver = {
+	.probe = mtk_disp_merge_probe,
+	.remove = mtk_disp_merge_remove,
+	.driver = {
+		.name = "mediatek-disp-merge",
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_disp_merge_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index beabadd206c9..c8413d5d8a84 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -331,6 +331,14 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
 	.stop = mtk_gamma_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_merge = {
+	.clk_enable = mtk_merge_clk_enable,
+	.clk_disable = mtk_merge_clk_disable,
+	.start = mtk_merge_start,
+	.stop = mtk_merge_stop,
+	.config = mtk_merge_config,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_od = {
 	.clk_enable = mtk_ddp_clk_enable,
 	.clk_disable = mtk_ddp_clk_disable,
@@ -380,6 +388,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MERGE] = "merge",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
@@ -415,6 +424,12 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DSI2]	= { MTK_DSI,		2, &ddp_dsi },
 	[DDP_COMPONENT_DSI3]	= { MTK_DSI,		3, &ddp_dsi },
 	[DDP_COMPONENT_GAMMA]	= { MTK_DISP_GAMMA,	0, &ddp_gamma },
+	[DDP_COMPONENT_MERGE0]	= { MTK_DISP_MERGE,	0, &ddp_merge },
+	[DDP_COMPONENT_MERGE1]	= { MTK_DISP_MERGE,	1, &ddp_merge },
+	[DDP_COMPONENT_MERGE2]	= { MTK_DISP_MERGE,	2, &ddp_merge },
+	[DDP_COMPONENT_MERGE3]	= { MTK_DISP_MERGE,	3, &ddp_merge },
+	[DDP_COMPONENT_MERGE4]	= { MTK_DISP_MERGE,	4, &ddp_merge },
+	[DDP_COMPONENT_MERGE5]	= { MTK_DISP_MERGE,	5, &ddp_merge },
 	[DDP_COMPONENT_OD0]	= { MTK_DISP_OD,	0, &ddp_od },
 	[DDP_COMPONENT_OD1]	= { MTK_DISP_OD,	1, &ddp_od },
 	[DDP_COMPONENT_OVL0]	= { MTK_DISP_OVL,	0, &ddp_ovl },
@@ -546,6 +561,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_DSC ||
 	    type == MTK_DISP_GAMMA ||
+	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 560be6bc9d0e..b42a47c06956 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -25,6 +25,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_DITHER,
 	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
+	MTK_DISP_MERGE,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index dae4f8e883ac..c7f369390ce6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -532,7 +532,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
-		 * Currently only the CCORR, COLOR, DSC, GAMMA, OVL, RDMA, DSI, and DPI
+		 * Currently only the CCORR, COLOR, DSC, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
 		 * blocks have separate component platform drivers and initialize their own
 		 * DDP component structure. The others are initialized here.
 		 */
@@ -540,6 +540,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_COLOR ||
 		    comp_type == MTK_DISP_DSC ||
 		    comp_type == MTK_DISP_GAMMA ||
+		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
@@ -640,6 +641,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ccorr_driver,
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
+	&mtk_disp_merge_driver,
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 637f5669e895..0fa417219a69 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -49,6 +49,7 @@ struct mtk_drm_private {
 extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
+extern struct platform_driver mtk_disp_merge_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:06 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:06 +0800
Subject: [PATCH v7 09/13] drm/mediatek: rename the define of register offset
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-10-jason-jh.lin@mediatek.com>

Add DISP_REG prefix for the define of register offset to
make the difference from the define of register value.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 57 +++++++++++----------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index aaa7450b3e2b..93beb980414f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -20,25 +20,25 @@
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_crtc.h"
 
-#define DISP_OD_EN				0x0000
-#define DISP_OD_CFG				0x0020
-#define DISP_OD_SIZE				0x0030
-#define DISP_DITHER_5				0x0114
-#define DISP_DITHER_7				0x011c
-#define DISP_DITHER_15				0x013c
-#define DISP_DITHER_16				0x0140
+#define DISP_REG_OD_EN				0x0000
+#define DISP_REG_OD_CFG				0x0020
+#define DISP_REG_OD_SIZE			0x0030
+#define DISP_REG_DITHER_5			0x0114
+#define DISP_REG_DITHER_7			0x011c
+#define DISP_REG_DITHER_15			0x013c
+#define DISP_REG_DITHER_16			0x0140
 
 #define DISP_REG_UFO_START			0x0000
 
-#define DISP_AAL_EN				0x0000
-#define DISP_AAL_SIZE				0x0030
+#define DISP_REG_AAL_EN				0x0000
+#define DISP_REG_AAL_SIZE			0x0030
 
-#define DISP_DITHER_EN				0x0000
+#define DISP_REG_DITHER_EN			0x0000
 #define DITHER_EN				BIT(0)
-#define DISP_DITHER_CFG				0x0020
+#define DISP_REG_DITHER_CFG			0x0020
 #define DITHER_RELAY_MODE			BIT(0)
 #define DITHER_ENGINE_EN			BIT(1)
-#define DISP_DITHER_SIZE			0x0030
+#define DISP_REG_DITHER_SIZE			0x0030
 
 #define OD_RELAYMODE				BIT(0)
 
@@ -129,19 +129,19 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 		return;
 
 	if (bpc >= MTK_MIN_BPC) {
-		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
-		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
+		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_5);
+		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_7);
 		mtk_ddp_write(cmdq_pkt,
 			      DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
 			      DITHER_NEW_BIT_MODE,
-			      cmdq_reg, regs, DISP_DITHER_15);
+			      cmdq_reg, regs, DISP_REG_DITHER_15);
 		mtk_ddp_write(cmdq_pkt,
 			      DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
 			      DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
-			      cmdq_reg, regs, DISP_DITHER_16);
+			      cmdq_reg, regs, DISP_REG_DITHER_16);
 		mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg);
 	}
 }
@@ -161,16 +161,16 @@ static void mtk_od_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE);
-	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG);
-	mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
+	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
+	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
 }
 
 static void mtk_od_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(1, priv->regs + DISP_OD_EN);
+	writel(1, priv->regs + DISP_REG_OD_EN);
 }
 
 static void mtk_ufoe_start(struct device *dev)
@@ -186,7 +186,7 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_AAL_SIZE);
 }
 
 static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
@@ -200,14 +200,14 @@ static void mtk_aal_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(AAL_EN, priv->regs + DISP_AAL_EN);
+	writel(AAL_EN, priv->regs + DISP_REG_AAL_EN);
 }
 
 static void mtk_aal_stop(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, priv->regs + DISP_AAL_EN);
+	writel_relaxed(0x0, priv->regs + DISP_REG_AAL_EN);
 }
 
 static void mtk_dither_config(struct device *dev, unsigned int w,
@@ -216,9 +216,10 @@ static void mtk_dither_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_DITHER_SIZE);
-	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, DISP_DITHER_CFG);
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_DITHER_CFG,
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE);
+	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_DITHER_CFG);
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
 			      DITHER_ENGINE_EN, cmdq_pkt);
 }
 
@@ -226,14 +227,14 @@ static void mtk_dither_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
+	writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
 }
 
 static void mtk_dither_stop(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
+	writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
 }
 
 static const struct mtk_ddp_comp_funcs ddp_aal = {
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:04 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:04 +0800
Subject: [PATCH v7 07/13] soc: mediatek: add mtk-mutex support for mt8195
 vdosys0
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-8-jason-jh.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 93 ++++++++++++++++++++++++++++++--
 1 file changed, 90 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2e4bcc300576..cb8bbf7f3fd8 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -17,6 +17,9 @@
 #define MT8183_MUTEX0_MOD0			0x30
 #define MT8183_MUTEX0_SOF0			0x2c
 
+#define MT8195_DISP_MUTEX0_MOD0			0x30
+#define MT8195_DISP_MUTEX0_SOF			0x2c
+
 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
@@ -67,6 +70,36 @@
 #define MT8173_MUTEX_MOD_DISP_PWM1		24
 #define MT8173_MUTEX_MOD_DISP_OD		25
 
+#define MT8195_MUTEX_MOD_DISP_OVL0		0
+#define MT8195_MUTEX_MOD_DISP_WDMA0		1
+#define MT8195_MUTEX_MOD_DISP_RDMA0		2
+#define MT8195_MUTEX_MOD_DISP_COLOR0		3
+#define MT8195_MUTEX_MOD_DISP_CCORR0		4
+#define MT8195_MUTEX_MOD_DISP_AAL0		5
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
+#define MT8195_MUTEX_MOD_DISP_DITHER0		7
+#define MT8195_MUTEX_MOD_DISP_DSI0		8
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
+#define MT8195_MUTEX_MOD_DISP_OVL1		10
+#define MT8195_MUTEX_MOD_DISP_WDMA1		11
+#define MT8195_MUTEX_MOD_DISP_RDMA1		12
+#define MT8195_MUTEX_MOD_DISP_COLOR1		13
+#define MT8195_MUTEX_MOD_DISP_CCORR1		14
+#define MT8195_MUTEX_MOD_DISP_AAL1		15
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
+#define MT8195_MUTEX_MOD_DISP_DITHER1		17
+#define MT8195_MUTEX_MOD_DISP_DSI1		18
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
+#define MT8195_MUTEX_MOD_DISP_PWM0		27
+#define MT8195_MUTEX_MOD_DISP_PWM1		28
+
 #define MT2712_MUTEX_MOD_DISP_PWM2		10
 #define MT2712_MUTEX_MOD_DISP_OVL0		11
 #define MT2712_MUTEX_MOD_DISP_OVL1		12
@@ -101,12 +134,27 @@
 #define MT2712_MUTEX_SOF_DSI3			6
 #define MT8167_MUTEX_SOF_DPI0			2
 #define MT8167_MUTEX_SOF_DPI1			3
+
 #define MT8183_MUTEX_SOF_DSI0			1
 #define MT8183_MUTEX_SOF_DPI0			2
 
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
 
+#define MT8195_MUTEX_SOF_DSI0			1
+#define MT8195_MUTEX_SOF_DSI1			2
+#define MT8195_MUTEX_SOF_DP_INTF0		3
+#define MT8195_MUTEX_SOF_DP_INTF1		4
+#define MT8195_MUTEX_SOF_DPI0			6 /* for HDMI_TX */
+#define MT8195_MUTEX_SOF_DPI1			5 /* for digital video out */
+
+#define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_SOF_DSI0 << 7)
+#define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_SOF_DSI1 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_INTF0 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_INTF1 << 7)
+#define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_SOF_DPI0 << 7)
+#define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_SOF_DPI1 << 7)
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -120,6 +168,9 @@ enum mtk_mutex_sof_id {
 	MUTEX_SOF_DPI1,
 	MUTEX_SOF_DSI2,
 	MUTEX_SOF_DSI3,
+	MUTEX_SOF_DP_INTF0,
+	MUTEX_SOF_DP_INTF1,
+	DDP_MUTEX_SOF_MAX,
 };
 
 struct mtk_mutex_data {
@@ -214,7 +265,22 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
+	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
+	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
+	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
+	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
+	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
+	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
+	[DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
+	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
+	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
+	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
+	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
+};
+
+static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
@@ -224,7 +290,7 @@ static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
 };
 
-static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
@@ -232,12 +298,24 @@ static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 };
 
 /* Add EOF setting so overlay hardware can receive frame done irq */
-static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
 };
 
+static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
+	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
+	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
+	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
+	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
+	[MUTEX_SOF_DP_INTF0] =
+		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
+	[MUTEX_SOF_DP_INTF1] =
+		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -275,6 +353,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.no_clk = true,
 };
 
+static const struct mtk_mutex_data mt8195_mutex_driver_data = {
+	.mutex_mod = mt8195_mutex_mod,
+	.mutex_sof = mt8195_mutex_sof,
+	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
+};
+
 struct mtk_mutex *mtk_mutex_get(struct device *dev)
 {
 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
@@ -507,6 +592,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
 	  .data = &mt8173_mutex_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = &mt8183_mutex_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = &mt8195_mutex_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:08 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:08 +0800
Subject: [PATCH v7 11/13] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-12-jason-jh.lin@mediatek.com>

DSC is designed for real-time systems with real-time compression,
transmission, decompression and display.
The DSC standard is a specification of the algorithms used for
compressing and decompressing image display streams, including
the specification of the syntax and semantics of the compressed
video bit stream.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 47 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  3 +-
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 28bc42fd0b8a..beabadd206c9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -45,6 +45,12 @@
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_DSC_CON			0x0000
+#define DSC_EN					BIT(0)
+#define DSC_DUAL_INOUT				BIT(2)
+#define DSC_BYPASS				BIT(4)
+#define DSC_UFOE_SEL				BIT(16)
+
 #define DISP_REG_OD_EN				0x0000
 #define DISP_REG_OD_CFG				0x0020
 #define OD_RELAYMODE				BIT(0)
@@ -211,6 +217,35 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc,
 			      DISP_DITHERING, cmdq_pkt);
 }
 
+static void mtk_dsc_config(struct device *dev, unsigned int w,
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* dsc bypass mode */
+	mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_BYPASS);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_UFOE_SEL);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_DUAL_INOUT);
+}
+
+static void mtk_dsc_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(DSC_EN, &priv->regs + DISP_REG_DSC_CON);
+}
+
+static void mtk_dsc_stop(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
+}
+
 static void mtk_od_config(struct device *dev, unsigned int w,
 			  unsigned int h, unsigned int vrefresh,
 			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -274,6 +309,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = {
 	.stop = mtk_dpi_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_dsc = {
+	.clk_enable = mtk_ddp_clk_enable,
+	.clk_disable = mtk_ddp_clk_disable,
+	.config = mtk_dsc_config,
+	.start = mtk_dsc_start,
+	.stop = mtk_dsc_stop,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_dsi = {
 	.start = mtk_dsi_ddp_start,
 	.stop = mtk_dsi_ddp_stop,
@@ -335,6 +378,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_CCORR] = "ccorr",
 	[MTK_DISP_COLOR] = "color",
 	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
@@ -364,6 +408,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DITHER]	= { MTK_DISP_DITHER,	0, &ddp_dither },
 	[DDP_COMPONENT_DPI0]	= { MTK_DPI,		0, &ddp_dpi },
 	[DDP_COMPONENT_DPI1]	= { MTK_DPI,		1, &ddp_dpi },
+	[DDP_COMPONENT_DSC0]	= { MTK_DISP_DSC,	0, &ddp_dsc },
+	[DDP_COMPONENT_DSC1]	= { MTK_DISP_DSC,	1, &ddp_dsc },
 	[DDP_COMPONENT_DSI0]	= { MTK_DSI,		0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]	= { MTK_DSI,		1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]	= { MTK_DSI,		2, &ddp_dsi },
@@ -498,6 +544,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	if (type == MTK_DISP_BLS ||
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
+	    type == MTK_DISP_DSC ||
 	    type == MTK_DISP_GAMMA ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index d317b944df66..560be6bc9d0e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_CCORR,
 	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
+	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a95dc1006b82..dae4f8e883ac 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -532,12 +532,13 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
-		 * Currently only the CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
+		 * Currently only the CCORR, COLOR, DSC, GAMMA, OVL, RDMA, DSI, and DPI
 		 * blocks have separate component platform drivers and initialize their own
 		 * DDP component structure. The others are initialized here.
 		 */
 		if (comp_type == MTK_DISP_CCORR ||
 		    comp_type == MTK_DISP_COLOR ||
+		    comp_type == MTK_DISP_DSC ||
 		    comp_type == MTK_DISP_GAMMA ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:55:59 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:55:59 +0800
Subject: [PATCH v7 02/13] dt-bindings: mediatek: display: split each block to
 individual yaml
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-3-jason-jh.lin@mediatek.com>

1. Remove mediatek,dislpay.txt
2. Split each display function block to individual yaml file

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,aal.yaml        |  75 ++++++
 .../display/mediatek/mediatek,ccorr.yaml      |  69 ++++++
 .../display/mediatek/mediatek,color.yaml      |  84 +++++++
 .../display/mediatek/mediatek,disp.txt        | 219 ------------------
 .../display/mediatek/mediatek,dither.yaml     |  70 ++++++
 .../display/mediatek/mediatek,gamma.yaml      |  71 ++++++
 .../display/mediatek/mediatek,merge.yaml      |  57 +++++
 .../display/mediatek/mediatek,mutex.yaml      |  77 ++++++
 .../display/mediatek/mediatek,od.yaml         |  52 +++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  86 +++++++
 .../display/mediatek/mediatek,ovl.yaml        |  96 ++++++++
 .../display/mediatek/mediatek,rdma.yaml       | 110 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  56 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  59 +++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
 15 files changed, 1048 insertions(+), 219 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
new file mode 100644
index 000000000000..7be772d77e36
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display adaptive ambient light processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display adaptive ambient light processor, namely AAL,
+  is responsible for backlight power saving and sunlight visibility improving.
+  AAL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-aal
+      - items:
+          - enum:
+              - mediatek,mt2712-disp-aal
+              - mediatek,mt8183-disp-aal
+          - enum:
+              - mediatek,mt8173-disp-aal
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: AAL Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    aal at 14015000 {
+        compatible = "mediatek,mt8173-disp-aal";
+        reg = <0 0x14015000 0 0x1000>;
+        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_AAL>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..5a1c27d6b3e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek Ddsplay color correction
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display color correction, namely CCORR, reproduces correct color
+  on panels with different color gamut.
+  CCORR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ccorr
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: CCORR Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ccorr0: ccorr at 1400f000 {
+        compatible = "mediatek,mt8183-disp-ccorr";
+        reg = <0 0x1400f000 0 0x1000>;
+        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+    }
+;
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
new file mode 100644
index 000000000000..9a3edf6f0b8e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display color processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek color processor, namely COLOR, provides hue, luma and
+  saturation adjustments to get better picture quality and to have one panel
+  resemble the other in their output characteristics.
+  COLOR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-color
+      - items:
+          - const: mediatek,mt8167-disp-color
+      - items:
+          - const: mediatek,mt8173-disp-color
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-color
+              - mediatek,mt2712-disp-color
+          - enum:
+              - mediatek,mt2701-disp-color
+      - items:
+          - enum:
+              - mediatek,mt8183-disp-color
+          - enum:
+              - mediatek,mt8173-disp-color
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: COLOR Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    color0: color at 14013000 {
+        compatible = "mediatek,mt8173-disp-color";
+        reg = <0 0x14013000 0 0x1000>;
+        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
deleted file mode 100644
index fbb59c9ddda6..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ /dev/null
@@ -1,219 +0,0 @@
-Mediatek display subsystem
-==========================
-
-The Mediatek display subsystem consists of various DISP function blocks in the
-MMSYS register space. The connections between them can be configured by output
-and input selectors in the MMSYS_CONFIG register space. Pixel clock and start
-of frame signal are distributed to the other function blocks by a DISP_MUTEX
-function block.
-
-All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
-For a description of the MMSYS_CONFIG binding, see
-Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt.
-
-DISP function blocks
-====================
-
-A display stream starts at a source function block that reads pixel data from
-memory and ends with a sink function block that drives pixels on a display
-interface, or writes pixels back to memory. All DISP function blocks have
-their own register space, interrupt, and clock gate. The blocks that can
-access memory additionally have to list the IOMMU and local arbiter they are
-connected to.
-
-For a description of the display interface sink function blocks, see
-Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
-Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
-
-Required properties (all function blocks):
-- compatible: "mediatek,<chip>-disp-<function>", one of
-	"mediatek,<chip>-disp-ovl"   		- overlay (4 layers, blending, csc)
-	"mediatek,<chip>-disp-ovl-2l"           - overlay (2 layers, blending, csc)
-	"mediatek,<chip>-disp-rdma"  		- read DMA / line buffer
-	"mediatek,<chip>-disp-wdma"  		- write DMA
-	"mediatek,<chip>-disp-ccorr"            - color correction
-	"mediatek,<chip>-disp-color" 		- color processor
-	"mediatek,<chip>-disp-dither"           - dither
-	"mediatek,<chip>-disp-aal"   		- adaptive ambient light controller
-	"mediatek,<chip>-disp-gamma" 		- gamma correction
-	"mediatek,<chip>-disp-merge" 		- merge streams from two RDMA sources
-	"mediatek,<chip>-disp-postmask" 	- control round corner for display frame
-	"mediatek,<chip>-disp-split" 		- split stream to two encoders
-	"mediatek,<chip>-disp-ufoe"  		- data compression engine
-	"mediatek,<chip>-dsi"        		- DSI controller, see mediatek,dsi.txt
-	"mediatek,<chip>-dpi"        		- DPI controller, see mediatek,dpi.txt
-	"mediatek,<chip>-disp-mutex" 		- display mutex
-	"mediatek,<chip>-disp-od"    		- overdrive
-  the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
-- reg: Physical base address and length of the function block register space
-- interrupts: The interrupt signal from the function block (required, except for
-  merge and split function blocks).
-- clocks: device clocks
-  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-  For most function blocks this is just a single clock input. Only the DSI and
-  DPI controller nodes have multiple clock inputs. These are documented in
-  mediatek,dsi.txt and mediatek,dpi.txt, respectively.
-  An exception is that the mt8183 mutex is always free running with no clocks property.
-
-Required properties (DMA function blocks):
-- compatible: Should be one of
-	"mediatek,<chip>-disp-ovl"
-	"mediatek,<chip>-disp-rdma"
-	"mediatek,<chip>-disp-wdma"
-  the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-- iommus: Should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-
-Optional properties (RDMA function blocks):
-- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
-  property to the corresponding rdma
-  the value is the Max value which defined in hardware data sheet.
-  mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
-  mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
-  mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
-
-Examples:
-
-mmsys: clock-controller at 14000000 {
-	compatible = "mediatek,mt8173-mmsys", "syscon";
-	reg = <0 0x14000000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	#clock-cells = <1>;
-};
-
-ovl0: ovl at 1400c000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400c000 0 0x1000>;
-	interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL0>;
-	iommus = <&iommu M4U_PORT_DISP_OVL0>;
-	mediatek,larb = <&larb0>;
-};
-
-ovl1: ovl at 1400d000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400d000 0 0x1000>;
-	interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL1>;
-	iommus = <&iommu M4U_PORT_DISP_OVL1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma0: rdma at 1400e000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400e000 0 0x1000>;
-	interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-	mediatek,larb = <&larb0>;
-	mediatek,rdma-fifosize = <8192>;
-};
-
-rdma1: rdma at 1400f000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400f000 0 0x1000>;
-	interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma2: rdma at 14010000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x14010000 0 0x1000>;
-	interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA2>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA2>;
-	mediatek,larb = <&larb4>;
-};
-
-wdma0: wdma at 14011000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14011000 0 0x1000>;
-	interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-	mediatek,larb = <&larb0>;
-};
-
-wdma1: wdma at 14012000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14012000 0 0x1000>;
-	interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-color0: color at 14013000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14013000 0 0x1000>;
-	interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR0>;
-};
-
-color1: color at 14014000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14014000 0 0x1000>;
-	interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR1>;
-};
-
-aal at 14015000 {
-	compatible = "mediatek,mt8173-disp-aal";
-	reg = <0 0x14015000 0 0x1000>;
-	interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_AAL>;
-};
-
-gamma at 14016000 {
-	compatible = "mediatek,mt8173-disp-gamma";
-	reg = <0 0x14016000 0 0x1000>;
-	interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_GAMMA>;
-};
-
-ufoe at 1401a000 {
-	compatible = "mediatek,mt8173-disp-ufoe";
-	reg = <0 0x1401a000 0 0x1000>;
-	interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_UFOE>;
-};
-
-dsi0: dsi at 1401b000 {
-	/* See mediatek,dsi.txt for details */
-};
-
-dpi0: dpi at 1401d000 {
-	/* See mediatek,dpi.txt for details */
-};
-
-mutex: mutex at 14020000 {
-	compatible = "mediatek,mt8173-disp-mutex";
-	reg = <0 0x14020000 0 0x1000>;
-	interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_MUTEX_32K>;
-};
-
-od at 14023000 {
-	compatible = "mediatek,mt8173-disp-od";
-	reg = <0 0x14023000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OD>;
-};
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
new file mode 100644
index 000000000000..20419f876410
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display dither processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display dither processor, namely DITHER, works by approximating
+  unavailable colors with available colors and by mixing and matching available
+  colors to mimic unavailable ones.
+  DITHER device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-dither
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: DITHER Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dither0: dither at 14012000 {
+        compatible = "mediatek,mt8183-disp-dither";
+        reg = <0 0x14012000 0 0x1000>;
+        interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_DITHER0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
new file mode 100644
index 000000000000..e2a1fc218e4f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,gamma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display gamma correction
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display gamma correction, namely GAMMA, provides a nonlinear operation
+  used to adjust luminance in??display system.
+  GAMMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-gamma
+      - items:
+          - const: mediatek,mt8183-disp-gamma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: GAMMA Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    gamma at 14016000 {
+        compatible = "mediatek,mt8173-disp-gamma";
+        reg = <0 0x14016000 0 0x1000>;
+        interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
new file mode 100644
index 000000000000..4cdce11d7fcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,merge.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display merge
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display merge engine is used to merge two slice-per-line inputs
+  into one side-by-side output.
+  MERGE device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-merge
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MERGE Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    merge at 14017000 {
+        compatible = "mediatek,mt8173-disp-merge";
+        reg = <0 0x14017000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_MERGE>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
new file mode 100644
index 000000000000..aaba6bbfb4da
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display mutex
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display mutex is used to send the triggers signals called
+  Start Of Frame (SOF)/ Error Of Frame (EOF) to each sub-modules on the
+  display data path.
+  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-mutex
+      - items:
+          - const: mediatek,mt2712-disp-mutex
+      - items:
+          - const: mediatek,mt8167-disp-mutex
+      - items:
+          - const: mediatek,mt8173-disp-mutex
+      - items:
+          - const: mediatek,mt8183-disp-mutex
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MUTEX Clock
+
+  mediatek,gce-events:
+    description:
+      The event id which is mapping to the specific hardware event signal to gce.
+      The event id is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    mutex: mutex at 14020000 {
+        compatible = "mediatek,mt8173-disp-mutex";
+        reg = <0 0x14020000 0 0x1000>;
+        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_MUTEX_32K>;
+        mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+                              <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
new file mode 100644
index 000000000000..bcf3fddd9231
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,od.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overdirve
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overdrive, namely OD, increases the transition values
+  of pixels between consecutive frames to make LCD rotate faster.
+  OD device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2712-disp-od
+      - items:
+          - const: mediatek,mt8173-disp-od
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    od at 14023000 {
+        compatible = "mediatek,mt8173-disp-od";
+        reg = <0 0x14023000 0 0x1000>;
+        clocks = <&mmsys CLK_MM_DISP_OD>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
new file mode 100644
index 000000000000..6255074bf415
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl-2l.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overlay 2 layer
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overlay provides 2 more layer for OVL.
+  OVL-2L device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ovl-2l
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL-2L Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl_2l0: ovl at 14009000 {
+        compatible = "mediatek,mt8183-disp-ovl-2l";
+        reg = <0 0x14009000 0 0x1000>;
+        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
+        iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
new file mode 100644
index 000000000000..833b0ca09b21
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overlay
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overlay, namely OVL, can do alpha blending from the memory.
+  OVL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-ovl
+      - items:
+          - const: mediatek,mt8173-disp-ovl
+      - items:
+          - const: mediatek,mt8183-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-ovl
+              - mediatek,mt2712-disp-ovl
+          - enum:
+              - mediatek,mt2701-disp-ovl
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommu
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl0: ovl at 1400c000 {
+        compatible = "mediatek,mt8173-disp-ovl";
+        reg = <0 0x1400c000 0 0x1000>;
+        interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0>;
+        iommus = <&iommu M4U_PORT_DISP_OVL0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
new file mode 100644
index 000000000000..ce3bcca30609
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display RDMA
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-rdma
+      - items:
+          - const: mediatek,mt8173-disp-rdma
+      - items:
+          - const: mediatek,mt8183-disp-rdma
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-rdma
+              - mediatek,mt2712-disp-rdma
+          - enum:
+              - mediatek,mt2701-disp-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,rdma-fifo-size:
+    description:
+      rdma fifo size may be different even in same SOC, add this property to the
+      corresponding rdma.
+      The value below is the Max value which defined in hardware data sheet
+      mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
+      mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
+      mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8192, 5120, 2048]
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    rdma0: rdma at 1400e000 {
+        compatible = "mediatek,mt8173-disp-rdma";
+        reg = <0 0x1400e000 0 0x1000>;
+        interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_RDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_RDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,rdma-fifosize = <8192>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
new file mode 100644
index 000000000000..d751e0a0c3a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,split.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display split
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display split engine is used to split stream to two encoders.
+  SPLIT device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-split
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: SPLIT Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    split0: split at 14018000 {
+        compatible = "mediatek,mt8173-disp-split";
+        reg = <0 0x14018000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
new file mode 100644
index 000000000000..d0249333a2bd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ufoe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display UFOe
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The Mediatek display UFOe stands for Unified Frame Optimization engine.
+  UFOe can cut the data rate for DSI port which may lead to reduce power consumption.
+  UFOe device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-ufoe
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: UFOe Clock
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ufoe at 1401a000 {
+        compatible = "mediatek,mt8173-disp-ufoe";
+        reg = <0 0x1401a000 0 0x1000>;
+        interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_UFOE>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..d7a3ba497fb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display WDMA
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display WDMA stands for Write Direct Memory Access.
+  It can write the data in display pipeline into DRAM.
+  WDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-wdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: WDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    wdma0: wdma at 14011000 {
+        compatible = "mediatek,mt8173-disp-wdma";
+        reg = <0 0x14011000 0 0x1000>;
+        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+    };
+
-- 
2.18.0

From jason-jh.lin at mediatek.com  Sun Aug 15 07:56:10 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Sun, 15 Aug 2021 22:56:10 +0800
Subject: [PATCH v7 13/13] drm/mediatek: add mediatek-drm of vdosys0 support
 for mt8195
In-Reply-To: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
References: <20210815145610.2050-1-jason-jh.lin@mediatek.com>
Message-ID: <20210815145610.2050-14-jason-jh.lin@mediatek.com>

Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  6 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 28 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 728aaadfea8c..00e9827acefe 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -355,6 +355,10 @@ static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
 	.fifo_size = 5 * SZ_1K,
 };
 
+static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
+	.fifo_size = 1920,
+};
+
 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt2701-disp-rdma",
 	  .data = &mt2701_rdma_driver_data},
@@ -362,6 +366,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	  .data = &mt8173_rdma_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = &mt8183_rdma_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = &mt8195_rdma_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index c7f369390ce6..cfe391266212 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -147,6 +147,19 @@ static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
 	DDP_COMPONENT_DPI0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
+	DDP_COMPONENT_OVL0,
+	DDP_COMPONENT_RDMA0,
+	DDP_COMPONENT_COLOR0,
+	DDP_COMPONENT_CCORR,
+	DDP_COMPONENT_AAL0,
+	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_DP_INTF0,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -186,6 +199,11 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.main_path = mt8195_mtk_ddp_main,
+	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+};
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
@@ -406,10 +424,14 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8183-disp-dither",
 	  .data = (void *)MTK_DISP_DITHER },
+	{ .compatible = "mediatek,mt8195-disp-dsc",
+	  .data = (void *)MTK_DISP_DSC },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
+	{ .compatible = "mediatek,mt8195-disp-merge",
+	  .data = (void *)MTK_DISP_MERGE },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -418,6 +440,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8173-disp-od",
 	  .data = (void *)MTK_DISP_OD },
 	{ .compatible = "mediatek,mt2701-disp-ovl",
@@ -438,6 +462,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8173-disp-ufoe",
 	  .data = (void *)MTK_DISP_UFOE },
 	{ .compatible = "mediatek,mt8173-disp-wdma",
@@ -468,6 +494,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
 	  .data = &mt8173_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8183-mmsys",
 	  .data = &mt8183_mmsys_driver_data},
+	{.compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
2.18.0

From robh at kernel.org  Sun Aug 15 08:25:03 2021
From: robh at kernel.org (Rob Herring)
Date: Sun, 15 Aug 2021 10:25:03 -0500
Subject: [PATCH v5 0/9] Add generic support for kdump DT properties
In-Reply-To: <cover.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
Message-ID: <YRkxzx/1XM3r64Ee@robh.at.kernel.org>

On Wed, Aug 11, 2021 at 10:50:58AM +0200, Geert Uytterhoeven wrote:
> 	Hi all,
> 
> This patch series adds generic support for parsing DT properties related
> to crash dump kernels ("linux,elfcorehdr" and "linux,elfcorehdr" under
> the "/chosen" node), makes use of it on arm32, and performs a few
> cleanups.  It is an evolution of the combination of [1] and [2].

The DT bits look fine to me. How do you expect this to be merged? I'm 
happy to take it if arch maintainers can ack it.

> 
> The series consists of 6 parts:
>   1. Patch 1 prepares architecture-specific code (needed for MIPS only)
>      to avoid duplicating elf core header reservation later.
>   2. Patch 2 prepares the visibility of variables used to hold
>      information retrieved from the DT properties.
>   3. Patches 3-5 add support to the FDT core for handling the
>      properties.
>      This can co-exist safely with architecture-specific handling, until
>      the latter has been removed.

Looks like patch 5 doesn't have any dependencies with the series?

>   4. Patch 6 removes the non-standard handling of "linux,elfcorehdr" on
>      riscv.

I thought this should be applied for 5.14?

>   5. Patches 7-8 convert arm64 to use the generic handling instead of
>      its own implementation.
>   6. Patch 9 adds support for kdump properties to arm32.
>      The corresponding patch for kexec-tools is "[PATCH] arm: kdump: Add
>      DT properties to crash dump kernel's DTB"[3], which is still valid.

This one can be applied on its own, right?

Rob


From jic23 at kernel.org  Sun Aug 15 09:31:50 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 15 Aug 2021 17:31:50 +0100
Subject: [PATCH v15 02/13] counter: Internalize sysfs interface code
In-Reply-To: <9844c0b2845fc001f64ebb0a4bc6d7fb7a08571a.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
 <9844c0b2845fc001f64ebb0a4bc6d7fb7a08571a.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <20210815173150.29454ed9@jic23-huawei>

On Mon,  9 Aug 2021 21:37:27 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> This is a reimplementation of the Generic Counter driver interface.
> There are no modifications to the Counter subsystem userspace interface,
> so existing userspace applications should continue to run seamlessly.
> 
> The purpose of this patch is to internalize the sysfs interface code
> among the various counter drivers into a shared module. Counter drivers
> pass and take data natively (i.e. u8, u64, etc.) and the shared counter
> module handles the translation between the sysfs interface and the
> device drivers. This guarantees a standard userspace interface for all
> counter drivers, and helps generalize the Generic Counter driver ABI in
> order to support the Generic Counter chrdev interface (introduced in a
> subsequent patch) without significant changes to the existing counter
> drivers.
> 
> Note, Counter device registration is the same as before: drivers
> populate a struct counter_device with components and callbacks, then
> pass the structure to the devm_counter_register function. However,
> what's different now is how the Counter subsystem code handles this
> registration internally.
> 
> Whereas before callbacks would interact directly with sysfs data, this
> interaction is now abstracted and instead callbacks interact with native
> C data types. The counter_comp structure forms the basis for Counter
> extensions.
> 
> The counter-sysfs.c file contains the code to parse through the
> counter_device structure and register the requested components and
> extensions. Attributes are created and populated based on type, with
> respective translation functions to handle the mapping between sysfs and
> the counter driver callbacks.
> 
> The translation performed for each attribute is straightforward: the
> attribute type and data is parsed from the counter_attribute structure,
> the respective counter driver read/write callback is called, and sysfs
> I/O is handled before or after the driver read/write function is called.
> 
> Cc: Jarkko Nikula <jarkko.nikula at linux.intel.com>
> Cc: Patrick Havelange <patrick.havelange at essensium.com>
> Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
> Cc: Fabrice Gasnier <fabrice.gasnier at st.com>
> Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> Cc: Alexandre Torgue <alexandre.torgue at st.com>
> Cc: Dan Carpenter <dan.carpenter at oracle.com>
> Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> Reviewed-by: David Lechner <david at lechnology.com>
> Tested-by: David Lechner <david at lechnology.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
Hi William,

Given we haven't had any of the reviews of the stm32 and ftm-quadec
changes I took a closer look myself.

A side effect of the warning fixes is that we now have some 'magic numbers'
for register fields.  Some of them were there already, but now there are more.

My suggestions is that you use some defines (or indeed the original enums
if appropriate) to provide text names to the register field values.
I've highlighted another driver that does it the way I'd like to see it done.

So unfortunately it looks like this this refactor is going to be in the next
kernel cycle :(  Hopefully we can get it queued up early though so you have
something to do any revisions of the latter patches against.

Jonathan



...

> -static int mchp_tc_count_action_set(struct counter_device *counter,
> -				    struct counter_count *count,
> -				    struct counter_synapse *synapse,
> -				    size_t action)
> +static int mchp_tc_count_action_write(struct counter_device *counter,
> +				      struct counter_count *count,
> +				      struct counter_synapse *synapse,
> +				      enum counter_synapse_action action)
>  {
>  	struct mchp_tc_data *const priv = counter->priv;
>  	u32 edge = ATMEL_TC_ETRGEDG_NONE;
> @@ -217,16 +205,16 @@ static int mchp_tc_count_action_set(struct counter_device *counter,
>  		return -EINVAL;
>  
>  	switch (action) {
> -	case MCHP_TC_SYNAPSE_ACTION_NONE:
> +	case COUNTER_SYNAPSE_ACTION_NONE:
>  		edge = ATMEL_TC_ETRGEDG_NONE;

This is a good example of the sort of use of defines for field values I'm suggesting
for other similar cases. Basically do it like this.


>  		break;
> -	case MCHP_TC_SYNAPSE_ACTION_RISING_EDGE:
> +	case COUNTER_SYNAPSE_ACTION_RISING_EDGE:
>  		edge = ATMEL_TC_ETRGEDG_RISING;
>  		break;
> -	case MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE:
> +	case COUNTER_SYNAPSE_ACTION_FALLING_EDGE:
>  		edge = ATMEL_TC_ETRGEDG_FALLING;
>  		break;
> -	case MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE:
> +	case COUNTER_SYNAPSE_ACTION_BOTH_EDGES:
>  		edge = ATMEL_TC_ETRGEDG_BOTH;
>  		break;
>  	default:
> @@ -240,8 +228,7 @@ static int mchp_tc_count_action_set(struct counter_device *counter,
>  }
>  

> diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
> index 13656957c45f..23d43b71f9e4 100644
> --- a/drivers/counter/stm32-lptimer-cnt.c
> +++ b/drivers/counter/stm32-lptimer-cnt.c
> @@ -17,6 +17,7 @@
>  #include <linux/module.h>
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/platform_device.h>
> +#include <linux/types.h>
>  
>  struct stm32_lptim_cnt {
>  	struct counter_device counter;
> @@ -107,11 +108,7 @@ static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
>  	return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val);
>  }
>  
> -/**
> - * enum stm32_lptim_cnt_function - enumerates LPTimer counter & encoder modes
> - * @STM32_LPTIM_COUNTER_INCREASE: up count on IN1 rising, falling or both edges
> - * @STM32_LPTIM_ENCODER_BOTH_EDGE: count on both edges (IN1 & IN2 quadrature)
> - *
> +/*
>   * In non-quadrature mode, device counts up on active edge.
>   * In quadrature mode, encoder counting scenarios are as follows:
>   * +---------+----------+--------------------+--------------------+
> @@ -129,33 +126,20 @@ static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
>   * | edges   | Low  ->  |   Up     |   Down  |   Down   |   Up    |
>   * +---------+----------+----------+---------+----------+---------+
>   */
> -enum stm32_lptim_cnt_function {
> -	STM32_LPTIM_COUNTER_INCREASE,
> -	STM32_LPTIM_ENCODER_BOTH_EDGE,
> -};
> -
>  static const enum counter_function stm32_lptim_cnt_functions[] = {
> -	[STM32_LPTIM_COUNTER_INCREASE] = COUNTER_FUNCTION_INCREASE,
> -	[STM32_LPTIM_ENCODER_BOTH_EDGE] = COUNTER_FUNCTION_QUADRATURE_X4,
> -};
> -
> -enum stm32_lptim_synapse_action {
> -	STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE,
> -	STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE,
> -	STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES,
> -	STM32_LPTIM_SYNAPSE_ACTION_NONE,
> +	COUNTER_FUNCTION_INCREASE,
> +	COUNTER_FUNCTION_QUADRATURE_X4,
>  };
>  
>  static const enum counter_synapse_action stm32_lptim_cnt_synapse_actions[] = {
> -	/* Index must match with stm32_lptim_cnt_polarity[] (priv->polarity) */
> -	[STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE,
> -	[STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE] = COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
> -	[STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
> -	[STM32_LPTIM_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
> +	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
> +	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
> +	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
> +	COUNTER_SYNAPSE_ACTION_NONE,
>  };
>  
>  static int stm32_lptim_cnt_read(struct counter_device *counter,
> -				struct counter_count *count, unsigned long *val)
> +				struct counter_count *count, u64 *val)
>  {
>  	struct stm32_lptim_cnt *const priv = counter->priv;
>  	u32 cnt;
> @@ -170,28 +154,28 @@ static int stm32_lptim_cnt_read(struct counter_device *counter,
>  	return 0;
>  }
>  
> -static int stm32_lptim_cnt_function_get(struct counter_device *counter,
> -					struct counter_count *count,
> -					size_t *function)
> +static int stm32_lptim_cnt_function_read(struct counter_device *counter,
> +					 struct counter_count *count,
> +					 enum counter_function *function)
>  {
>  	struct stm32_lptim_cnt *const priv = counter->priv;
>  
>  	if (!priv->quadrature_mode) {
> -		*function = STM32_LPTIM_COUNTER_INCREASE;
> +		*function = COUNTER_FUNCTION_INCREASE;
>  		return 0;
>  	}
>  
> -	if (priv->polarity == STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES) {
> -		*function = STM32_LPTIM_ENCODER_BOTH_EDGE;
> +	if (priv->polarity == 2) {

This wants to have some sort of define for the register field value
it corresponds to.

> +		*function = COUNTER_FUNCTION_QUADRATURE_X4;
>  		return 0;
>  	}
>  
>  	return -EINVAL;
>  }
>  
> -static int stm32_lptim_cnt_function_set(struct counter_device *counter,
> -					struct counter_count *count,
> -					size_t function)
> +static int stm32_lptim_cnt_function_write(struct counter_device *counter,
> +					  struct counter_count *count,
> +					  enum counter_function function)
>  {
>  	struct stm32_lptim_cnt *const priv = counter->priv;
>  
> @@ -199,12 +183,12 @@ static int stm32_lptim_cnt_function_set(struct counter_device *counter,
>  		return -EBUSY;
>  
>  	switch (function) {
> -	case STM32_LPTIM_COUNTER_INCREASE:
> +	case COUNTER_FUNCTION_INCREASE:
>  		priv->quadrature_mode = 0;
>  		return 0;
> -	case STM32_LPTIM_ENCODER_BOTH_EDGE:
> +	case COUNTER_FUNCTION_QUADRATURE_X4:
>  		priv->quadrature_mode = 1;
> -		priv->polarity = STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES;
> +		priv->polarity = 2;
>  		return 0;
>  	default:
>  		/* should never reach this path */
> @@ -212,9 +196,9 @@ static int stm32_lptim_cnt_function_set(struct counter_device *counter,
>  	}
>  }

...

>  
> -static int stm32_lptim_cnt_action_get(struct counter_device *counter,
> -				      struct counter_count *count,
> -				      struct counter_synapse *synapse,
> -				      size_t *action)
> +static int stm32_lptim_cnt_action_read(struct counter_device *counter,
> +				       struct counter_count *count,
> +				       struct counter_synapse *synapse,
> +				       enum counter_synapse_action *action)
>  {
>  	struct stm32_lptim_cnt *const priv = counter->priv;
> -	size_t function;
> +	enum counter_function function;
>  	int err;
>  
> -	err = stm32_lptim_cnt_function_get(counter, count, &function);
> +	err = stm32_lptim_cnt_function_read(counter, count, &function);
>  	if (err)
>  		return err;
>  
>  	switch (function) {
> -	case STM32_LPTIM_COUNTER_INCREASE:
> +	case COUNTER_FUNCTION_INCREASE:
>  		/* LP Timer acts as up-counter on input 1 */
> -		if (synapse->signal->id == count->synapses[0].signal->id)
> -			*action = priv->polarity;
> -		else
> -			*action = STM32_LPTIM_SYNAPSE_ACTION_NONE;
> -		return 0;
> -	case STM32_LPTIM_ENCODER_BOTH_EDGE:
> -		*action = priv->polarity;
> -		return 0;
> +		if (synapse->signal->id != count->synapses[0].signal->id) {
> +			*action = COUNTER_SYNAPSE_ACTION_NONE;
> +			return 0;
> +		}
> +
> +		switch (priv->polarity) {
> +		case 0:

These correspond to particular bits. As you use them elsewhere I think
you need some defines.

> +			*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
> +			return 0;
> +		case 1:
> +			*action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE;
> +			return 0;
> +		case 2:
> +			*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
> +			return 0;
> +		default:
> +			/* should never reach this path */
> +			return -EINVAL;
> +		}
> +	case COUNTER_FUNCTION_QUADRATURE_X4:
> +		switch (priv->polarity) {
> +		case 0:
> +			*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
> +			return 0;
> +		case 1:
> +			*action = COUNTER_SYNAPSE_ACTION_FALLING_EDGE;
> +			return 0;
> +		case 2:
> +			*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
> +			return 0;
> +		default:
> +			/* should never reach this path */
> +			return -EINVAL;
> +		}
>  	default:
>  		/* should never reach this path */
>  		return -EINVAL;
>  	}
>  }
>  
> -static int stm32_lptim_cnt_action_set(struct counter_device *counter,
> -				      struct counter_count *count,
> -				      struct counter_synapse *synapse,
> -				      size_t action)
> +static int stm32_lptim_cnt_action_write(struct counter_device *counter,
> +					struct counter_count *count,
> +					struct counter_synapse *synapse,
> +					enum counter_synapse_action action)
>  {
>  	struct stm32_lptim_cnt *const priv = counter->priv;
> -	size_t function;
> +	enum counter_function function;
>  	int err;
>  
>  	if (stm32_lptim_is_enabled(priv))
>  		return -EBUSY;
>  
> -	err = stm32_lptim_cnt_function_get(counter, count, &function);
> +	err = stm32_lptim_cnt_function_read(counter, count, &function);
>  	if (err)
>  		return err;
>  
>  	/* only set polarity when in counter mode (on input 1) */
> -	if (function == STM32_LPTIM_COUNTER_INCREASE
> -	    && synapse->signal->id == count->synapses[0].signal->id) {
> -		switch (action) {
> -		case STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE:
> -		case STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE:
> -		case STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES:
> -			priv->polarity = action;
> -			return 0;
> -		}
> -	}
> +	if (function != COUNTER_FUNCTION_INCREASE
> +	    || synapse->signal->id != count->synapses[0].signal->id)
> +		return -EINVAL;
>  
> -	return -EINVAL;
> +	switch (action) {
> +	case COUNTER_SYNAPSE_ACTION_RISING_EDGE:
> +		priv->polarity = 0;
> +		return 0;
> +	case COUNTER_SYNAPSE_ACTION_FALLING_EDGE:
> +		priv->polarity = 1;
> +		return 0;
> +	case COUNTER_SYNAPSE_ACTION_BOTH_EDGES:
> +		priv->polarity = 2;
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
>  }
>  
>  static const struct counter_ops stm32_lptim_cnt_ops = {
>  	.count_read = stm32_lptim_cnt_read,
> -	.function_get = stm32_lptim_cnt_function_get,
> -	.function_set = stm32_lptim_cnt_function_set,
> -	.action_get = stm32_lptim_cnt_action_get,
> -	.action_set = stm32_lptim_cnt_action_set,
> +	.function_read = stm32_lptim_cnt_function_read,
> +	.function_write = stm32_lptim_cnt_function_write,
> +	.action_read = stm32_lptim_cnt_action_read,
> +	.action_write = stm32_lptim_cnt_action_write,
>  };
>  
>  static struct counter_signal stm32_lptim_cnt_signals[] = {
> diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
> index 3fb0debd7425..8b3759096d04 100644
> --- a/drivers/counter/stm32-timer-cnt.c
> +++ b/drivers/counter/stm32-timer-cnt.c
> @@ -13,6 +13,7 @@
>  #include <linux/module.h>
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/platform_device.h>
> +#include <linux/types.h>
>  
>  #define TIM_CCMR_CCXS	(BIT(8) | BIT(0))
>  #define TIM_CCMR_MASK	(TIM_CCMR_CC1S | TIM_CCMR_CC2S | \
> @@ -36,29 +37,15 @@ struct stm32_timer_cnt {
>  	struct stm32_timer_regs bak;
>  };
>  
> -/**
> - * enum stm32_count_function - enumerates stm32 timer counter encoder modes
> - * @STM32_COUNT_SLAVE_MODE_DISABLED: counts on internal clock when CEN=1
> - * @STM32_COUNT_ENCODER_MODE_1: counts TI1FP1 edges, depending on TI2FP2 level
> - * @STM32_COUNT_ENCODER_MODE_2: counts TI2FP2 edges, depending on TI1FP1 level
> - * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges
> - */
> -enum stm32_count_function {
> -	STM32_COUNT_SLAVE_MODE_DISABLED,
> -	STM32_COUNT_ENCODER_MODE_1,
> -	STM32_COUNT_ENCODER_MODE_2,
> -	STM32_COUNT_ENCODER_MODE_3,
> -};
> -
>  static const enum counter_function stm32_count_functions[] = {
> -	[STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_FUNCTION_INCREASE,
> -	[STM32_COUNT_ENCODER_MODE_1] = COUNTER_FUNCTION_QUADRATURE_X2_A,
> -	[STM32_COUNT_ENCODER_MODE_2] = COUNTER_FUNCTION_QUADRATURE_X2_B,
> -	[STM32_COUNT_ENCODER_MODE_3] = COUNTER_FUNCTION_QUADRATURE_X4,
> +	COUNTER_FUNCTION_INCREASE,
> +	COUNTER_FUNCTION_QUADRATURE_X2_A,
> +	COUNTER_FUNCTION_QUADRATURE_X2_B,
> +	COUNTER_FUNCTION_QUADRATURE_X4,
>  };
>  
>  static int stm32_count_read(struct counter_device *counter,
> -			    struct counter_count *count, unsigned long *val)
> +			    struct counter_count *count, u64 *val)
>  {
>  	struct stm32_timer_cnt *const priv = counter->priv;
>  	u32 cnt;
> @@ -70,8 +57,7 @@ static int stm32_count_read(struct counter_device *counter,
>  }
>  
>  static int stm32_count_write(struct counter_device *counter,
> -			     struct counter_count *count,
> -			     const unsigned long val)
> +			     struct counter_count *count, const u64 val)
>  {
>  	struct stm32_timer_cnt *const priv = counter->priv;
>  	u32 ceiling;
> @@ -83,9 +69,9 @@ static int stm32_count_write(struct counter_device *counter,
>  	return regmap_write(priv->regmap, TIM_CNT, val);
>  }
>  
> -static int stm32_count_function_get(struct counter_device *counter,
> -				    struct counter_count *count,
> -				    size_t *function)
> +static int stm32_count_function_read(struct counter_device *counter,
> +				     struct counter_count *count,
> +				     enum counter_function *function)
>  {
>  	struct stm32_timer_cnt *const priv = counter->priv;
>  	u32 smcr;
> @@ -94,40 +80,40 @@ static int stm32_count_function_get(struct counter_device *counter,
>  
>  	switch (smcr & TIM_SMCR_SMS) {
>  	case 0:

As below, these case values should be named.

> -		*function = STM32_COUNT_SLAVE_MODE_DISABLED;
> +		*function = COUNTER_FUNCTION_INCREASE;
>  		return 0;
>  	case 1:
> -		*function = STM32_COUNT_ENCODER_MODE_1;
> +		*function = COUNTER_FUNCTION_QUADRATURE_X2_A;
>  		return 0;
>  	case 2:
> -		*function = STM32_COUNT_ENCODER_MODE_2;
> +		*function = COUNTER_FUNCTION_QUADRATURE_X2_B;
>  		return 0;
>  	case 3:
> -		*function = STM32_COUNT_ENCODER_MODE_3;
> +		*function = COUNTER_FUNCTION_QUADRATURE_X4;
>  		return 0;
>  	default:
>  		return -EINVAL;
>  	}
>  }
>  
> -static int stm32_count_function_set(struct counter_device *counter,
> -				    struct counter_count *count,
> -				    size_t function)
> +static int stm32_count_function_write(struct counter_device *counter,
> +				      struct counter_count *count,
> +				      enum counter_function function)
>  {
>  	struct stm32_timer_cnt *const priv = counter->priv;
>  	u32 cr1, sms;
>  
>  	switch (function) {
> -	case STM32_COUNT_SLAVE_MODE_DISABLED:
> +	case COUNTER_FUNCTION_INCREASE:
>  		sms = 0;
This code is odd in the original driver as sms is just set to the values of the 'function'
enum.  Having said that, I think with the refactored code you want some symbolic names (defines)
for the register field values.

>  		break;
> -	case STM32_COUNT_ENCODER_MODE_1:
> +	case COUNTER_FUNCTION_QUADRATURE_X2_A:
>  		sms = 1;
>  		break;
> -	case STM32_COUNT_ENCODER_MODE_2:
> +	case COUNTER_FUNCTION_QUADRATURE_X2_B:
>  		sms = 2;
>  		break;
> -	case STM32_COUNT_ENCODER_MODE_3:
> +	case COUNTER_FUNCTION_QUADRATURE_X4:
>  		sms = 3;
>  		break;
>  	default:

...




From maz at kernel.org  Sun Aug 15 09:36:02 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 15 Aug 2021 17:36:02 +0100
Subject: [PATCH v3 1/2] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <CAL_JsqLvqWiuib9s4PzX8pOQYJQ0eR7Gxz==J849eVJ5MDq4SA@mail.gmail.com>
References: <20210726083204.93196-1-mark.kettenis@xs4all.nl>
 <20210726083204.93196-2-mark.kettenis@xs4all.nl>
 <20210726231848.GA1025245@robh.at.kernel.org>
 <87sfzt1pg9.wl-maz@kernel.org>
 <CAL_JsqLvqWiuib9s4PzX8pOQYJQ0eR7Gxz==J849eVJ5MDq4SA@mail.gmail.com>
Message-ID: <8735ra1x8t.wl-maz@kernel.org>

Hi Rob,

Apologies for the delay, I somehow misplaced this email...

On Mon, 02 Aug 2021 17:10:39 +0100,
Rob Herring <robh at kernel.org> wrote:
> 
> On Sun, Aug 1, 2021 at 3:31 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Tue, 27 Jul 2021 00:18:48 +0100,
> > Rob Herring <robh at kernel.org> wrote:
> > >
> > > On Mon, Jul 26, 2021 at 10:32:00AM +0200, Mark Kettenis wrote:
> > > > From: Mark Kettenis <kettenis at openbsd.org>
> > > >
> > > > The Apple PCIe host controller is a PCIe host controller with
> > > > multiple root ports present in Apple ARM SoC platforms, including
> > > > various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > >
> > > > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > > > ---
> > > >  .../devicetree/bindings/pci/apple,pcie.yaml   | 166 ++++++++++++++++++
> > > >  MAINTAINERS                                   |   1 +
> > > >  2 files changed, 167 insertions(+)
> > > >  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > new file mode 100644
> > > > index 000000000000..bfcbdee79c64
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > @@ -0,0 +1,166 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Apple PCIe host controller
> > > > +
> > > > +maintainers:
> > > > +  - Mark Kettenis <kettenis at openbsd.org>
> > > > +
> > > > +description: |
> > > > +  The Apple PCIe host controller is a PCIe host controller with
> > > > +  multiple root ports present in Apple ARM SoC platforms, including
> > > > +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > +  The controller incorporates Synopsys DesigWare PCIe logic to
> > > > +  implements its root ports.  But the ATU found on most DesignWare
> > > > +  PCIe host bridges is absent.
> > >
> > > blank line
> > >
> > > > +  All root ports share a single ECAM space, but separate GPIOs are
> > > > +  used to take the PCI devices on those ports out of reset.  Therefore
> > > > +  the standard "reset-gpio" and "max-link-speed" properties appear on
> > >
> > > reset-gpios
> > >
> > > > +  the child nodes that represent the PCI bridges that correspond to
> > > > +  the individual root ports.
> > >
> > > blank line
> > >
> > > > +  MSIs are handled by the PCIe controller and translated into regular
> > > > +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> > > > +  distributed over the root ports as the OS sees fit by programming
> > > > +  the PCIe controller's port registers.
> > > > +
> > > > +allOf:
> > > > +  - $ref: /schemas/pci/pci-bus.yaml#
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    items:
> > > > +      - const: apple,t8103-pcie
> > > > +      - const: apple,pcie
> > > > +
> > > > +  reg:
> > > > +    minItems: 3
> > > > +    maxItems: 5
> > > > +
> > > > +  reg-names:
> > > > +    minItems: 3
> > > > +    maxItems: 5
> > > > +    items:
> > > > +      - const: config
> > > > +      - const: rc
> > > > +      - const: port0
> > > > +      - const: port1
> > > > +      - const: port2
> > > > +
> > > > +  ranges:
> > > > +    minItems: 2
> > > > +    maxItems: 2
> > > > +
> > > > +  interrupts:
> > > > +    description:
> > > > +      Interrupt specifiers, one for each root port.
> > > > +    minItems: 1
> > > > +    maxItems: 3
> > > > +
> > > > +  msi-controller: true
> > > > +  msi-parent: true
> > > > +
> > > > +  msi-ranges:
> > > > +    description:
> > > > +      A list of pairs <intid span>, where "intid" is the first
> > > > +      interrupt number that can be used as an MSI, and "span" the size
> > > > +      of that range.
> > > > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > > > +    items:
> > > > +      minItems: 2
> > > > +      maxItems: 2
> > >
> > > I still have issues I raised on v1 with this property. It's genericish
> > > looking, but not generic. 'intid' as a single cell can't specify any
> > > parent interrupt such as a GIC which uses 3 cells. You could put in all
> > > the cells, but you'd still be assuming which cell you can increment.
> >
> > The GIC bindings already use similar abstractions, see what we do for
> > both GICv2m and GICv3 MBIs. Other MSI controllers use similar
> > properties (alpine and loongson, for example).
> 
> That's the problem. Everyone making up their own crap.

And that crap gets approved:

https://lore.kernel.org/lkml/20200512205704.GA10412 at bogus/

I'm not trying to be antagonistic here, but it seems that your
position on this very subject has changed recently.

> > > I think you should just list all these under 'interrupts' using
> > > interrupt-names to make your life easier:
> > >
> > > interrupt-names:
> > >   items:
> > >     - const: port0
> > >     - const: port1
> > >     - const: port2
> > >     - const: msi0
> > >     - const: msi1
> > >     - const: msi2
> > >     - const: msi3
> > >     ...
> > >
> > > Yeah, it's kind of verbose, but if the h/w block handles N interrupts,
> > > you should list N interrupts. The worst case for the above is N entries
> > > too if not contiguous.
> >
> > And that's where I beg to differ, again.
> >
> > Specifying interrupts like this gives the false impression that these
> > interrupts are generated by the device that owns them (the RC). Which
> > for MSIs is not the case.
> 
> It's no different than an interrupt controller node having an
> interrupts property. The source is downstream and the interrupt
> controller is combining/translating the interrupts.
> 
> The physical interrupt signals are connected to and originating in
> this block.

Oh, I also object to this, for the same reasons. The only case where
it makes sense IMHO is when the interrupt controller is a multiplexer.

> That sounds like perfectly 'describing the h/w' to me.

I guess we have a different view of about these things. At the end of
the day, I don't care enough as long as we can expose a range of
interrupts one way or another.

> > This is not only verbose, this is
> > semantically dubious. And what should we do when the number of
> > possible interrupt is ridiculously large, as it is for the GICv3 ITS?
> 
> I don't disagree with the verbose part. But that's not really an issue
> in this case.
> 
> > I wish we had a standard way to express these constraints. Until we
> > do, I don't think enumerating individual interrupts is a practical
> > thing to do, nor that it actually represents the topology of the
> > system.
> 
> The only way a standard way will happen is to stop accepting the
> custom properties.
> 
> All the custom properties suffer from knowledge of what the parent
> interrupt controller is. To fix that, I think we need something like
> this:
> 
> msi-ranges = <intspec base>, <intspec step>, <intspec end>;
> 
> 'intspec' is defined by the parent interrupt-controller cells. step is
> the value to add. And end is what to match on to stop aka the last
> interrupt in the range. For example, if the GIC is the parent, we'd
> have something like this:
> 
> <GIC_SPI 123 0>, <0 1 0>, <GIC_SPI 124 0>
> 
> Does this apply to cases other than MSI? I think so as don't we have
> the same type of properties with the low power mode shadow interrupt
> controllers?  So 'interrupt-ranges'?

This would work, though the increment seems a bit over-engineered. You
also may need this property to accept multiple ranges.

> It looks to me like there's an assumption in the kernel that an MSI
> controller has a linear range of parent interrupts? Is that correct
> and something that's guaranteed? That assumption leaks into the
> existing bindings.

Depends on how the controller works. In general, the range maps to the
MultiMSI requirements where the message is an offset from the base of
the interrupt range. So you generally end-up with ranges of at least
32 contiguous MSIs. Anything under that is sub-par and probably not
worth supporting.

Of course, the controller may have some mapping facilities, which
makes things more... interesting.

> It's fine for the kernel to assume that until there's a case that's
> not linear, but a common binding needs to be able handle a
> non-linear case.

Fair enough. I can probably work with Mark to upgrade the binding and
the M1 PCIe code. Could you come up with a more formalised proposal?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From jic23 at kernel.org  Sun Aug 15 09:51:02 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 15 Aug 2021 17:51:02 +0100
Subject: [PATCH v15 07/13] docs: counter: Document character device
 interface
In-Reply-To: <a6f7be32b8ff7cc1e8e416599820a30fa9aab9f5.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
 <a6f7be32b8ff7cc1e8e416599820a30fa9aab9f5.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <20210815175102.4a10a28f@jic23-huawei>

On Mon,  9 Aug 2021 21:37:32 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> This patch adds high-level documentation about the Counter subsystem
> character device interface.
> 
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>

Hi William,

Trivial probable typo inline.

I'm struggling somewhat with these interfaces because I simply don't know
enough about how people use counters to know whether they provide everything
people will want. They feel similar to the event handling type functions you
can set up in motor drives, so they may well make sense, but ideally
we need review from someone (other than yourself!) who actually uses this
stuff on a regular basis.

If we don't get any additional review I guess we go ahead anyway
next cycle.

Jonathan

> ---

> +
> +Counter events can be configured by users to report various Counter
> +data of interest. This can be conceptualized as a list of Counter
> +component read calls to perform. For example:
> +
> +        +-------------------------------------------------+
> +        | COUNTER_EVENT_OVERFLOW | COUNTER_EVENT_INDEX    |
> +        +========================+========================+
> +        | Channel 0              | Channel 0              |
> +        +------------------------+------------------------+
> +        | * Count 0              | * Signal 0             |
> +        | * Count 1              | * Signal 0 Extension 0 |
> +        | * Signal 3             | * Extension 4          |
> +        | * Count 4 Extension 2  +------------------------+
> +        | * Signal 5 Extension 0 | Channel 1              |
> +        |                        +------------------------+
> +        |                        | * Signal 4             |
> +        |                        | * Signal 4 Extension 0 |
> +        |                        | * Count 7              |
> +        +------------------------+------------------------+
> +
> +When ``counter_push_event(counter, COUNTER_EVENT_INDEX, 1)`` is called
> +for example, it will go down the list for the ``COUNTER_EVENT_INDEX``
> +event channel 1 and execute the read callbacks for Signal 4, Signal 4
> +Extension 0, and Count 4 -- the data returned for each is pushed to a

Count 7?

> +kfifo as a ``struct counter_event``, which userspace can retrieve via a
> +standard read operation on the respective character device node.
> +

>                                                                       Block for the entire subsystem



From jic23 at kernel.org  Sun Aug 15 09:57:56 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 15 Aug 2021 17:57:56 +0100
Subject: [PATCH v15 09/13] counter: Implement
 signalZ_action_component_id sysfs attribute
In-Reply-To: <d72159ab7ebfe607d86c0ab472979e8eca6f16a0.1628511445.git.vilhelm.gray@gmail.com>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
 <d72159ab7ebfe607d86c0ab472979e8eca6f16a0.1628511445.git.vilhelm.gray@gmail.com>
Message-ID: <20210815175756.5e627c3d@jic23-huawei>

On Mon,  9 Aug 2021 21:37:34 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> The Generic Counter chrdev interface expects users to supply component
> IDs in order to select Synapses for requests. In order for users to know
> what component ID belongs to which Synapse this information must be
> exposed. The signalZ_action_component_id attribute provides a way for
> users to discover what component ID belongs to the respective Synapse.
> 
> Cc: Gwendal Grignou <gwendal at chromium.org>
> Cc: Dan Carpenter <dan.carpenter at oracle.com>
> Reviewed-by: David Lechner <david at lechnology.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
> ---

>  Contact:	linux-iio at vger.kernel.org
> diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
> index dbb507c9da11..11bef9f8190f 100644
> --- a/drivers/counter/counter-sysfs.c
> +++ b/drivers/counter/counter-sysfs.c
> @@ -393,7 +393,6 @@ static int counter_avail_attr_create(struct device *const dev,
>  	struct counter_attribute *counter_attr;
>  	struct device_attribute *dev_attr;
>  
> -	/* Allocate Counter attribute */

Trivial, but this is an unrelated change and shouldn't be in this patch (it's just noise).

>  	counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL);
>  	if (!counter_attr)
>  		return -ENOMEM;
> @@ -535,6 +534,46 @@ static int counter_name_attr_create(struct device *const dev,
>  	return 0;
>  }
>  


From jarkko.nikula at bitmer.com  Sun Aug 15 11:05:04 2021
From: jarkko.nikula at bitmer.com (Jarkko Nikula)
Date: Sun, 15 Aug 2021 21:05:04 +0300
Subject: [PATCH] bus: ti-sysc: Fix error handling for
 sysc_check_active_timer()
In-Reply-To: <20210811062231.GA16241@duo.ucw.cz>
References: <20210811061053.32081-1-tony@atomide.com>
 <20210811062231.GA16241@duo.ucw.cz>
Message-ID: <d9ebbc7f-07f1-160f-f463-7c54ed8dd6d7@bitmer.com>

Hi

On 8/11/21 9:22 AM, Pavel Machek wrote:
> On Wed 2021-08-11 09:10:53, Tony Lindgren wrote:
>> We have changed the return type for sysc_check_active_timer() from -EBUSY
>> to -ENXIO, but the gpt12 system timer fix still checks for -EBUSY. We are
>> also not returning on other errors like we did earlier as noted by
>> Pavel Machek <pavel at denx.de>.
>>
>> Commit 3ff340e24c9d ("bus: ti-sysc: Fix gpt12 system timer issue with
>> reserved status") should have been updated for commit 65fb73676112
>> ("bus: ti-sysc: suppress err msg for timers used as clockevent/source").
>>
>> Let's fix the issue by checking for -ENXIO and returning on any other
>> errors as suggested by Pavel Machek <pavel at denx.de>.
>>
>> Fixes: 3ff340e24c9d ("bus: ti-sysc: Fix gpt12 system timer issue with reserved status")
>> Depends-on: 65fb73676112 ("bus: ti-sysc: suppress err msg for timers used as clockevent/source")
>> Reported-by: Pavel Machek <pavel at denx.de>
>> Cc: Grygorii Strashko <grygorii.strashko at ti.com>
>> Cc: Jarkko Nikula <jarkko.nikula at bitmer.com>
>> Signed-off-by: Tony Lindgren <tony at atomide.com>
> 
> Reviewed-by: Pavel Machek (CIP) <pavel at denx.de>
> 
I double checked but actually both plain 0aa78d17099b ("Merge tag
'scsi-fixes' of
git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi") and with this
patch boot fine on my Beagle C2.

Anyway,

Tested-by: jarkko.nikula at bitmer.com


From lkp at intel.com  Sun Aug 15 12:05:15 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 16 Aug 2021 03:05:15 +0800
Subject: [PATCH 1/2] soc: aspeed: Add LPC mailbox support
In-Reply-To: <20210813054758.13189-2-chiawei_wang@aspeedtech.com>
References: <20210813054758.13189-2-chiawei_wang@aspeedtech.com>
Message-ID: <202108160221.59KN8jgQ-lkp@intel.com>

Hi Chia-Wei,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on joel-aspeed/for-next]
[also build test WARNING on v5.14-rc5 next-20210813]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chia-Wei-Wang/aspeed-Add-LPC-mailbox-support/20210813-134908
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git for-next
config: h8300-randconfig-s031-20210816 (attached as .config)
compiler: h8300-linux-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-348-gf0e6938b-dirty
        # https://github.com/0day-ci/linux/commit/72c5a69dc779f5b4af59eb6d47d0e1086be814af
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chia-Wei-Wang/aspeed-Add-LPC-mailbox-support/20210813-134908
        git checkout 72c5a69dc779f5b4af59eb6d47d0e1086be814af
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=h8300 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>


sparse warnings: (new ones prefixed by >>)
>> drivers/soc/aspeed/aspeed-lpc-mbox.c:240:27: sparse: sparse: incorrect type in initializer (different base types) @@     expected restricted __poll_t ( *poll )( ... ) @@     got unsigned int ( * )( ... ) @@
   drivers/soc/aspeed/aspeed-lpc-mbox.c:240:27: sparse:     expected restricted __poll_t ( *poll )( ... )
   drivers/soc/aspeed/aspeed-lpc-mbox.c:240:27: sparse:     got unsigned int ( * )( ... )

vim +240 drivers/soc/aspeed/aspeed-lpc-mbox.c

   232	
   233	static const struct file_operations aspeed_mbox_fops = {
   234		.owner		= THIS_MODULE,
   235		.llseek		= no_seek_end_llseek,
   236		.read		= aspeed_mbox_read,
   237		.write		= aspeed_mbox_write,
   238		.open		= aspeed_mbox_open,
   239		.release	= aspeed_mbox_release,
 > 240		.poll		= aspeed_mbox_poll,
   241		.unlocked_ioctl	= aspeed_mbox_ioctl,
   242	};
   243	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 36610 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210816/c93871a5/attachment-0001.gz>

From robh at kernel.org  Sun Aug 15 12:19:57 2021
From: robh at kernel.org (Rob Herring)
Date: Sun, 15 Aug 2021 14:19:57 -0500
Subject: [PATCH v3 1/2] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <8735ra1x8t.wl-maz@kernel.org>
References: <20210726083204.93196-1-mark.kettenis@xs4all.nl>
 <20210726083204.93196-2-mark.kettenis@xs4all.nl>
 <20210726231848.GA1025245@robh.at.kernel.org>
 <87sfzt1pg9.wl-maz@kernel.org>
 <CAL_JsqLvqWiuib9s4PzX8pOQYJQ0eR7Gxz==J849eVJ5MDq4SA@mail.gmail.com>
 <8735ra1x8t.wl-maz@kernel.org>
Message-ID: <CAL_JsqJ5M3soMT30ntSTbqqdrQP8TT26mHL-0xExsn10MWPofA@mail.gmail.com>

On Sun, Aug 15, 2021 at 11:36 AM Marc Zyngier <maz at kernel.org> wrote:
>
> Hi Rob,
>
> Apologies for the delay, I somehow misplaced this email...
>
> On Mon, 02 Aug 2021 17:10:39 +0100,
> Rob Herring <robh at kernel.org> wrote:
> >
> > On Sun, Aug 1, 2021 at 3:31 AM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Tue, 27 Jul 2021 00:18:48 +0100,
> > > Rob Herring <robh at kernel.org> wrote:
> > > >
> > > > On Mon, Jul 26, 2021 at 10:32:00AM +0200, Mark Kettenis wrote:
> > > > > From: Mark Kettenis <kettenis at openbsd.org>
> > > > >
> > > > > The Apple PCIe host controller is a PCIe host controller with
> > > > > multiple root ports present in Apple ARM SoC platforms, including
> > > > > various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > >
> > > > > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > > > > ---
> > > > >  .../devicetree/bindings/pci/apple,pcie.yaml   | 166 ++++++++++++++++++
> > > > >  MAINTAINERS                                   |   1 +
> > > > >  2 files changed, 167 insertions(+)
> > > > >  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > new file mode 100644
> > > > > index 000000000000..bfcbdee79c64
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > @@ -0,0 +1,166 @@
> > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > +%YAML 1.2
> > > > > +---
> > > > > +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > +
> > > > > +title: Apple PCIe host controller
> > > > > +
> > > > > +maintainers:
> > > > > +  - Mark Kettenis <kettenis at openbsd.org>
> > > > > +
> > > > > +description: |
> > > > > +  The Apple PCIe host controller is a PCIe host controller with
> > > > > +  multiple root ports present in Apple ARM SoC platforms, including
> > > > > +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > +  The controller incorporates Synopsys DesigWare PCIe logic to
> > > > > +  implements its root ports.  But the ATU found on most DesignWare
> > > > > +  PCIe host bridges is absent.
> > > >
> > > > blank line
> > > >
> > > > > +  All root ports share a single ECAM space, but separate GPIOs are
> > > > > +  used to take the PCI devices on those ports out of reset.  Therefore
> > > > > +  the standard "reset-gpio" and "max-link-speed" properties appear on
> > > >
> > > > reset-gpios
> > > >
> > > > > +  the child nodes that represent the PCI bridges that correspond to
> > > > > +  the individual root ports.
> > > >
> > > > blank line
> > > >
> > > > > +  MSIs are handled by the PCIe controller and translated into regular
> > > > > +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> > > > > +  distributed over the root ports as the OS sees fit by programming
> > > > > +  the PCIe controller's port registers.
> > > > > +
> > > > > +allOf:
> > > > > +  - $ref: /schemas/pci/pci-bus.yaml#
> > > > > +
> > > > > +properties:
> > > > > +  compatible:
> > > > > +    items:
> > > > > +      - const: apple,t8103-pcie
> > > > > +      - const: apple,pcie
> > > > > +
> > > > > +  reg:
> > > > > +    minItems: 3
> > > > > +    maxItems: 5
> > > > > +
> > > > > +  reg-names:
> > > > > +    minItems: 3
> > > > > +    maxItems: 5
> > > > > +    items:
> > > > > +      - const: config
> > > > > +      - const: rc
> > > > > +      - const: port0
> > > > > +      - const: port1
> > > > > +      - const: port2
> > > > > +
> > > > > +  ranges:
> > > > > +    minItems: 2
> > > > > +    maxItems: 2
> > > > > +
> > > > > +  interrupts:
> > > > > +    description:
> > > > > +      Interrupt specifiers, one for each root port.
> > > > > +    minItems: 1
> > > > > +    maxItems: 3
> > > > > +
> > > > > +  msi-controller: true
> > > > > +  msi-parent: true
> > > > > +
> > > > > +  msi-ranges:
> > > > > +    description:
> > > > > +      A list of pairs <intid span>, where "intid" is the first
> > > > > +      interrupt number that can be used as an MSI, and "span" the size
> > > > > +      of that range.
> > > > > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > > > > +    items:
> > > > > +      minItems: 2
> > > > > +      maxItems: 2
> > > >
> > > > I still have issues I raised on v1 with this property. It's genericish
> > > > looking, but not generic. 'intid' as a single cell can't specify any
> > > > parent interrupt such as a GIC which uses 3 cells. You could put in all
> > > > the cells, but you'd still be assuming which cell you can increment.
> > >
> > > The GIC bindings already use similar abstractions, see what we do for
> > > both GICv2m and GICv3 MBIs. Other MSI controllers use similar
> > > properties (alpine and loongson, for example).
> >
> > That's the problem. Everyone making up their own crap.
>
> And that crap gets approved:
>
> https://lore.kernel.org/lkml/20200512205704.GA10412 at bogus/
>
> I'm not trying to be antagonistic here, but it seems that your
> position on this very subject has changed recently.

Not really, I think it's not the first time we've discussed this. But
as I see things over and over, my tolerance for another instance
without solving the problem for everyone diminishes. And what other
leverage do I have?

Additionally, how long we have to support something comes into play. I
have no idea for a Loongson MSI controller. I have a better idea on an
Apple product...

> > > > I think you should just list all these under 'interrupts' using
> > > > interrupt-names to make your life easier:
> > > >
> > > > interrupt-names:
> > > >   items:
> > > >     - const: port0
> > > >     - const: port1
> > > >     - const: port2
> > > >     - const: msi0
> > > >     - const: msi1
> > > >     - const: msi2
> > > >     - const: msi3
> > > >     ...
> > > >
> > > > Yeah, it's kind of verbose, but if the h/w block handles N interrupts,
> > > > you should list N interrupts. The worst case for the above is N entries
> > > > too if not contiguous.
> > >
> > > And that's where I beg to differ, again.
> > >
> > > Specifying interrupts like this gives the false impression that these
> > > interrupts are generated by the device that owns them (the RC). Which
> > > for MSIs is not the case.
> >
> > It's no different than an interrupt controller node having an
> > interrupts property. The source is downstream and the interrupt
> > controller is combining/translating the interrupts.
> >
> > The physical interrupt signals are connected to and originating in
> > this block.
>
> Oh, I also object to this, for the same reasons. The only case where
> it makes sense IMHO is when the interrupt controller is a multiplexer.

So we've had the same kind of property for interrupt multiplexers. I'm
fine if you think an 'MSI to interrupts mapping property' should be
named something else.

> > That sounds like perfectly 'describing the h/w' to me.
>
> I guess we have a different view of about these things. At the end of
> the day, I don't care enough as long as we can expose a range of
> interrupts one way or another.

I don't really either. I just don't want 10 ways AND another...

> > > This is not only verbose, this is
> > > semantically dubious. And what should we do when the number of
> > > possible interrupt is ridiculously large, as it is for the GICv3 ITS?
> >
> > I don't disagree with the verbose part. But that's not really an issue
> > in this case.
> >
> > > I wish we had a standard way to express these constraints. Until we
> > > do, I don't think enumerating individual interrupts is a practical
> > > thing to do, nor that it actually represents the topology of the
> > > system.
> >
> > The only way a standard way will happen is to stop accepting the
> > custom properties.
> >
> > All the custom properties suffer from knowledge of what the parent
> > interrupt controller is. To fix that, I think we need something like
> > this:
> >
> > msi-ranges = <intspec base>, <intspec step>, <intspec end>;
> >
> > 'intspec' is defined by the parent interrupt-controller cells. step is
> > the value to add. And end is what to match on to stop aka the last
> > interrupt in the range. For example, if the GIC is the parent, we'd
> > have something like this:
> >
> > <GIC_SPI 123 0>, <0 1 0>, <GIC_SPI 124 0>
> >
> > Does this apply to cases other than MSI? I think so as don't we have
> > the same type of properties with the low power mode shadow interrupt
> > controllers?  So 'interrupt-ranges'?
>
> This would work, though the increment seems a bit over-engineered. You
> also may need this property to accept multiple ranges.

Yes, certainly. Worst case is a map.

> > It looks to me like there's an assumption in the kernel that an MSI
> > controller has a linear range of parent interrupts? Is that correct
> > and something that's guaranteed? That assumption leaks into the
> > existing bindings.
>
> Depends on how the controller works. In general, the range maps to the
> MultiMSI requirements where the message is an offset from the base of
> the interrupt range. So you generally end-up with ranges of at least
> 32 contiguous MSIs. Anything under that is sub-par and probably not
> worth supporting.

Maybe just this is enough:
msi-ranges = <intspec base>, <length>, <intspec base>, <length>, ...

While I say 'length' here, that's really up to the interrupt parent to
interpret the intspec cells.

> Of course, the controller may have some mapping facilities, which
> makes things more... interesting.
>
> > It's fine for the kernel to assume that until there's a case that's
> > not linear, but a common binding needs to be able handle a
> > non-linear case.
>
> Fair enough. I can probably work with Mark to upgrade the binding and
> the M1 PCIe code. Could you come up with a more formalised proposal?

Not my itch.

Rob


From fancer.lancer at gmail.com  Sun Aug 15 12:46:17 2021
From: fancer.lancer at gmail.com (Serge Semin)
Date: Sun, 15 Aug 2021 22:46:17 +0300
Subject: [PATCH 29/29] arm64: dts: qcom: Harmonize DWC USB3 DT nodes name
In-Reply-To: <CALAqxLXrs0_Xs0JV5H-wS1q2CJ7XhW5Dj90eu=uazkRXXEMUxQ@mail.gmail.com>
References: <0064cb2c-5ca6-e693-2e89-8f045c8f7502@kernel.org>
 <YPf+shNM6cXb3mfe@kroah.com>
 <d853df77-8d36-30b0-dd26-da1bfcb068e0@kernel.org>
 <20210721112531.xvu6ni5ksaehsrjh@mobilestation>
 <CALAqxLViEqSO17P3JGRGYJh-wDoHaJiQQV48zeoRgnar4Xd5Bg@mail.gmail.com>
 <20210722181221.xh3r5kyu7zlcojjx@mobilestation>
 <YPnEO6NVFZDS1s//@yoga>
 <CALAqxLUT0e+mHMVo685oVTxR8y76733cN0yciQ7ePS6GRE+_dg@mail.gmail.com>
 <20210722220918.l7j6zw3aaa27qato@mobilestation>
 <CALAqxLXrs0_Xs0JV5H-wS1q2CJ7XhW5Dj90eu=uazkRXXEMUxQ@mail.gmail.com>
Message-ID: <20210815194617.sbrkutxzldqbxfat@mobilestation>

Hello John

On Fri, Aug 13, 2021 at 06:06:24PM -0700, John Stultz wrote:
> On Thu, Jul 22, 2021 at 3:09 PM Serge Semin <fancer.lancer at gmail.com> wrote:
> > On Thu, Jul 22, 2021 at 01:09:05PM -0700, John Stultz wrote:
> > > On Thu, Jul 22, 2021 at 12:17 PM Bjorn Andersson
> > > <bjorn.andersson at linaro.org> wrote:
> > > > > On Jul 21, 2021, 1:45 PM +0200, Krzysztof Kozlowski wrote:
> > > > > > I had impression that kernel defines interfaces which should be used and
> > > > > > are stable (e.g. syscalls, sysfs and so on). This case is example of
> > > > > > user-space relying on something not being marked as part of ABI. Instead
> > > > > > they found something working for them and now it is being used in "we
> > > > > > cannot break existing systems". Basically, AOSP unilaterally created a
> > > > > > stable ABI and now kernel has to stick to it.
> > > > > >
> > > > > > Really, all normal systems depend on aliases or names and here we have
> > > > > > dependency on device address. I proposed way how AOSP should be fixed.
> > > > > > Anything happened? Nope.
> > > > >
> > > > > First time he sent a possible solution for the problem:
> > > > > https://lore.kernel.org/lkml/20201221210423.GA2504 at kozik-lap/
> > > > >
> > > > > To sum up you could have used one of the more portable approaches
> > > > > 1. add an udc alias to the controller and use it then to refer to the
> > > > > corresponding USB controller
> > > >
> > > > Is there such a thing as "UDC alias"? Or are you suggesting that we
> > > > should add such feature?
> > > >
> > > > I think it would be wonderful if we could identify the UDCs on our
> > > > boards as "USB1" and "USB2", or "the one and only USB-C connector". But
> > > > unless that will fall back to the existing naming it would break John's
> > > > _existing_ userspace.
> > >
> >
> > > Well, I'd not hold up the existing userspace I'm using as sacrosanct
> > > (AOSP devices still usually don't have to work cross-kernel versions -
> > > devboards being the main exception). I'm fine if we can rework
> > > userland as proposed, so that the issues can be avoided, but I
> > > honestly don't have enough context to really understand what that
> > > looks like (no idea what udc aliases are).
> > >
> > > And whatever we do, the main constraint is that userland has to be
> > > able to work with existing LTS kernels and newer kernels.
> >
> > As I said in my response to Bjorn even if it is added to the kernel it
> > won't get to the official LTSes as it would be a new kernel feature.
> > New features aren't normally backported to the older kernels.
> >
> > >
> > > > > 2. search through DT-nodes looking for a specific compatible/reg
> > > > > DT-properties.
> > > > >
> > > >
> > > > We could define that this is the way, but again we didn't yesterday so
> > > > your proposal is not backwards compatible.
> > >
> >
> > > It may be backwards compatible, but I'm still not clear exactly how it
> > > would work.
> > >
> > > I guess if we look through all
> > > sys/bus/platform/devices/*/of_node/compatbile strings for the desired
> > > "snps,dwc3", then find which of the directories have the desired
> > > address in the string? (The suggestion for looking at reg seems
> > > better, but I don't get a char value out of the dwc3 of_node/reg
> > > file).
> >
> > The algorithm is simple:
> > 1) You know what USB controllers you have on your platform. They are
> > supposed to be compatible with snps,dwc3 string and have some pre-defined
> > base address.
> > 2) Find all the files in the directory /sys/class/udc/.
> > 3) Walk through all the directories in /sys/bus/platform/devices/ with
> > names found in 2) and stop on the device with matching compatible/base
> > address defined in 1).
> >
> > In my case the strings could be retrieved like this:
> > USB_NAME_COMPAT=$(/sys/bus/platform/devices/1f100000.usb/of_node/compatible | tr '\0' '\t' | cut -f1)
> > USB_DEVICE_ADDR="$(head -c 4 /sys/bus/platform/devices/1f100000.usb/of_node/reg | hexdump -ve '/1 "%02x"' | sed -e 's/^0*//g')"
> 
> 

> Hey Serge,
>    I just wanted to follow up here.  Amit has reworked the db845c AOSP
> userland so that it no longer uses the fixed node name, but instead
> probes for it:
>   https://android-review.googlesource.com/c/device/linaro/dragonboard/+/1774872
> 
> Admittedly, it does take a short-cut.  As your algorithm above,
> digging up the devices and finding the sys/bus path to read the reg
> value and pipe through hexdump (which android doesn't have) seemed
> overly obtuse when the address is in the node name itself (while the
> only way to be sure, one normally doesn't use spectroscopy to
> determine the value of a coin when you can read what's printed on it
> :).  But, should the node naming be further changed at least the
> infrastructure we have can be reworked fairly easily to adapt now.
> 
> In any case, as we can handle the name change now, if you want to
> resubmit your patch, we would no longer object (but can't promise no
> one else might be bitten).  Sorry for the delay this caused, and we
> appreciate you working with us to find a solution.

Great! Thanks for sending the notification. I'll resend the patch with a
reference to your report and to the update made to AOSP, as soon as I
am done with my current task.

Regards
-Sergey

> 
> thanks
> -john


From pali at kernel.org  Sun Aug 15 13:30:45 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sun, 15 Aug 2021 22:30:45 +0200
Subject: [PATCH 2/2] arm64: dts: marvell: armada-37xx: Extend PCIe MEM
 space
In-Reply-To: <20210807113536.24ik7m7uonebwox2@pali>
References: <20210624215546.4015-1-pali@kernel.org>
 <20210624215546.4015-3-pali@kernel.org> <87pmv919bq.fsf@BL-laptop>
 <20210723141204.waiipazikhzzloj7@pali>
 <20210723155247.GB4103@lpieralisi>
 <20210723164512.vo3scpzoodff2j33@pali>
 <20210807113536.24ik7m7uonebwox2@pali>
Message-ID: <20210815203045.hiir4aqm6btrqfy5@pali>

On Saturday 07 August 2021 13:35:36 Pali Roh?r wrote:
> On Friday 23 July 2021 18:45:12 Pali Roh?r wrote:
> > On Friday 23 July 2021 16:52:47 Lorenzo Pieralisi wrote:
> > > On Fri, Jul 23, 2021 at 04:12:04PM +0200, Pali Roh?r wrote:
> > > > On Friday 23 July 2021 14:52:25 Gregory CLEMENT wrote:
> > > > > Hello Pali,
> > > > > 
> > > > > > Current PCIe MEM space of size 16 MB is not enough for some combination
> > > > > > of PCIe cards (e.g. NVMe disk together with ath11k wifi card). ARM Trusted
> > > > > > Firmware for Armada 3700 platform already assigns 128 MB for PCIe window,
> > > > > > so extend PCIe MEM space to the end of 128 MB PCIe window which allows to
> > > > > > allocate more PCIe BARs for more PCIe cards.
> > > > > >
> > > > > > Without this change some combination of PCIe cards cannot be used and
> > > > > > kernel show error messages in dmesg during initialization:
> > > > > >
> > > > > >     pci 0000:00:00.0: BAR 8: no space for [mem size 0x01800000]
> > > > > >     pci 0000:00:00.0: BAR 8: failed to assign [mem size 0x01800000]
> > > > > >     pci 0000:00:00.0: BAR 6: assigned [mem 0xe8000000-0xe80007ff pref]
> > > > > >     pci 0000:01:00.0: BAR 8: no space for [mem size 0x01800000]
> > > > > >     pci 0000:01:00.0: BAR 8: failed to assign [mem size 0x01800000]
> > > > > >     pci 0000:02:03.0: BAR 8: no space for [mem size 0x01000000]
> > > > > >     pci 0000:02:03.0: BAR 8: failed to assign [mem size 0x01000000]
> > > > > >     pci 0000:02:07.0: BAR 8: no space for [mem size 0x00100000]
> > > > > >     pci 0000:02:07.0: BAR 8: failed to assign [mem size 0x00100000]
> > > > > >     pci 0000:03:00.0: BAR 0: no space for [mem size 0x01000000 64bit]
> > > > > >     pci 0000:03:00.0: BAR 0: failed to assign [mem size 0x01000000 64bit]
> > > > > >
> > > > > > Due to bugs in U-Boot port for Turris Mox, the second range in Turris Mox
> > > > > > kernel DTS file for PCIe must start at 16 MB offset. Otherwise U-Boot
> > > > > > crashes during loading of kernel DTB file. This bug is present only in
> > > > > > U-Boot code for Turris Mox and therefore other Armada 3700 devices are not
> > > > > > affected by this bug. Bug is fixed in U-Boot version 2021.07.
> > > > > >
> > > > > > To not break booting new kernels on existing versions of U-Boot on Turris
> > > > > > Mox, use first 16 MB range for IO and second range with rest of PCIe window
> > > > > > for MEM.
> > > > > 
> > > > > Is there any depencey with the firs patch of this series ?
> > > > > 
> > > > > What happend if this patch is applied without the other ?
> > > > 
> > > > First patch is fixing reading and setting ranges configuration from DTS.
> > > > Without first patch memory windows stays as they were in bootloader or
> > > > in its default configuration. Which is that all 128 MB are transparently
> > > > mapped to PCIe MEM space.
> > > > 
> > > > Therefore this second DTS patch does not fixes issue with IO space
> > > > (kernel still crashes when accessing it). But allows to use all PCIe MEM
> > > > space (due to bootloader / default configuration) and therefore allows
> > > > to use more PCIe cards (which needs more PCIe MEM space).
> > > 
> > > So, the two patches are decoupled then ? We are not taking dts changes
> > > through the PCI tree.
> > 
> > Well, both patches are required to fix setup and use of PCIe ranges on
> > A3720 platforms. But I would say they are independent and you can apply
> > them in any order. So Gregory, feel free to take DTS change in your tree
> > and Lorenzo can review other patch.
> 
> Lorenzo, so will you take driver change via PCI tree?
> 
> And Gregory, DTS change via DTS tree?

PING?

> > I sent these two patches in one series as they are fixing one common
> > issue. It is common that for fixing one common issue it is required to
> > touch more subsystems / trees.
> > 
> > > Besides: these dts patches are a nightmare for backward compatibility,
> > > hopefully Rob can shed some light on whether what you are doing here
> > > is advisable and how to sync the changes with kernel changes.
> > 
> > As written in comment for armada-3720-turris-mox.dts file, there are
> > specific requirements what needs to be put into ranges section. And
> > version of this file without applying this patch and also version of
> > this file with applied patch matches these requirements.
> > 
> > So I would say that this DTS change is backward and also forward
> > compatible.
> > 
> > But I agree that DTS changes are lot of time nightmare...
> > 
> > > Lorenzo
> > > 
> > > > > Could you test it to see if any regression occure ?
> > > > > 
> > > > > Thanks,
> > > > > 
> > > > > Gr?gory
> > > > > 
> > > > > >
> > > > > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > > > > Fixes: 76f6386b25cc ("arm64: dts: marvell: Add Aardvark PCIe support for Armada 3700")
> > > > > > ---
> > > > > >  .../boot/dts/marvell/armada-3720-turris-mox.dts | 17 +++++++++++++++++
> > > > > >  arch/arm64/boot/dts/marvell/armada-37xx.dtsi    | 11 +++++++++--
> > > > > >  2 files changed, 26 insertions(+), 2 deletions(-)
> > > > > >
> > > > > > diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> > > > > > index 53e817c5f6f3..86b3025f174b 100644
> > > > > > --- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> > > > > > +++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> > > > > > @@ -134,6 +134,23 @@
> > > > > >  	pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>;
> > > > > >  	status = "okay";
> > > > > >  	reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
> > > > > > +	/*
> > > > > > +	 * U-Boot port for Turris Mox has a bug which always expects that "ranges" DT property
> > > > > > +	 * contains exactly 2 ranges with 3 (child) address cells, 2 (parent) address cells and
> > > > > > +	 * 2 size cells and also expects that the second range starts at 16 MB offset. If these
> > > > > > +	 * conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
> > > > > > +	 * space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
> > > > > > +	 * for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB.
> > > > > > +	 * This bug is not present in U-Boot ports for other Armada 3700 devices and is fixed in
> > > > > > +	 * U-Boot version 2021.07. See relevant U-Boot commits (the last one contains fix):
> > > > > > +	 * https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
> > > > > > +	 * https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf
> > > > > > +	 * https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33
> > > > > > +	 */
> > > > > > +	#address-cells = <3>;
> > > > > > +	#size-cells = <2>;
> > > > > > +	ranges = <0x81000000 0 0xe8000000   0 0xe8000000   0 0x01000000   /* Port 0 IO */
> > > > > > +		  0x82000000 0 0xe9000000   0 0xe9000000   0 0x07000000>; /* Port 0 MEM */
> > > > > >  
> > > > > >  	/* enabled by U-Boot if PCIe module is present */
> > > > > >  	status = "disabled";
> > > > > > diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> > > > > > index 7a2df148c6a3..dac3007f2ac1 100644
> > > > > > --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> > > > > > +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> > > > > > @@ -488,8 +488,15 @@
> > > > > >  			#interrupt-cells = <1>;
> > > > > >  			msi-parent = <&pcie0>;
> > > > > >  			msi-controller;
> > > > > > -			ranges = <0x82000000 0 0xe8000000   0 0xe8000000 0 0x1000000 /* Port 0 MEM */
> > > > > > -				  0x81000000 0 0xe9000000   0 0xe9000000 0 0x10000>; /* Port 0 IO*/
> > > > > > +			/*
> > > > > > +			 * The 128 MiB address range [0xe8000000-0xf0000000] is
> > > > > > +			 * dedicated for PCIe and can be assigned to 8 windows
> > > > > > +			 * with size a power of two. Use one 64 KiB window for
> > > > > > +			 * IO at the end and the remaining seven windows
> > > > > > +			 * (totaling 127 MiB) for MEM.
> > > > > > +			 */
> > > > > > +			ranges = <0x82000000 0 0xe8000000   0 0xe8000000   0 0x07f00000   /* Port 0 MEM */
> > > > > > +				  0x81000000 0 0xefff0000   0 0xefff0000   0 0x00010000>; /* Port 0 IO */
> > > > > >  			interrupt-map-mask = <0 0 0 7>;
> > > > > >  			interrupt-map = <0 0 0 1 &pcie_intc 0>,
> > > > > >  					<0 0 0 2 &pcie_intc 1>,
> > > > > > -- 
> > > > > > 2.20.1
> > > > > >
> > > > > 
> > > > > -- 
> > > > > Gregory Clement, Bootlin
> > > > > Embedded Linux and Kernel engineering
> > > > > http://bootlin.com


From oupton at google.com  Sun Aug 15 17:11:24 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:11:24 +0000
Subject: [PATCH v7 0/6] KVM: x86: Add idempotent controls for migrating system
 counter state
Message-ID: <20210816001130.3059564-1-oupton@google.com>

KVM's current means of saving/restoring system counters is plagued with
temporal issues. On x86, we migrate the guest's system counter by-value
through the respective guest's IA32_TSC value. Restoring system counters
by-value is brittle as the state is not idempotent: the host system
counter is still oscillating between the attempted save and restore.
Furthermore, VMMs may wish to transparently live migrate guest VMs,
meaning that they include the elapsed time due to live migration blackout
in the guest system counter view. The VMM thread could be preempted for
any number of reasons (scheduler, L0 hypervisor under nested) between the
time that it calculates the desired guest counter value and when
KVM actually sets this counter state.

Despite the value-based interface that we present to userspace, KVM
actually has idempotent guest controls by way of the TSC offset.
We can avoid all of the issues associated with a value-based interface
by abstracting these offset controls in a new device attribute. This
series introduces new vCPU device attributes to provide userspace access
to the vCPU's system counter offset.

Patch 1 addresses a possible race in KVM_GET_CLOCK where
use_master_clock is read outside of the pvclock_gtod_sync_lock.

Patch 2 is a cleanup, moving the implementation of KVM_{GET,SET}_CLOCK
into helper methods.

Patch 3 adopts Paolo's suggestion, augmenting the KVM_{GET,SET}_CLOCK
ioctls to provide userspace with a (host_tsc, realtime) instant. This is
essential for a VMM to perform precise migration of the guest's system
counters.

Patches 4-5 are some preparatory changes for exposing the TSC offset to
userspace. Patch 6 provides a vCPU attribute to provide userspace access
to the TSC offset.

This series was tested with the new KVM selftests for the KVM clock and
system counter offset controls on Haswell hardware. Note that these
tests are mailed as a separate series due to the dependencies in both
x86 and arm64.

Applies cleanly to kvm/queue.

Parent commit: a3e0b8bd99ab ("KVM: MMU: change tracepoints arguments to kvm_page_fault")

v6: https://lore.kernel.org/r/20210804085819.846610-1-oupton at google.com

v6 -> v7:
 - Separated x86, arm64, and selftests into different series
 - Rebased on top of kvm/queue

Oliver Upton (6):
  KVM: x86: Fix potential race in KVM_GET_CLOCK
  KVM: x86: Create helper methods for KVM_{GET,SET}_CLOCK ioctls
  KVM: x86: Report host tsc and realtime values in KVM_GET_CLOCK
  KVM: x86: Take the pvclock sync lock behind the tsc_write_lock
  KVM: x86: Refactor tsc synchronization code
  KVM: x86: Expose TSC offset controls to userspace

 Documentation/virt/kvm/api.rst          |  42 ++-
 Documentation/virt/kvm/devices/vcpu.rst |  57 ++++
 Documentation/virt/kvm/locking.rst      |  11 +
 arch/x86/include/asm/kvm_host.h         |   4 +
 arch/x86/include/uapi/asm/kvm.h         |   4 +
 arch/x86/kvm/x86.c                      | 362 +++++++++++++++++-------
 include/uapi/linux/kvm.h                |   7 +-
 7 files changed, 378 insertions(+), 109 deletions(-)

-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:11:25 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:11:25 +0000
Subject: [PATCH v7 1/6] KVM: x86: Fix potential race in KVM_GET_CLOCK
In-Reply-To: <20210816001130.3059564-1-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
Message-ID: <20210816001130.3059564-2-oupton@google.com>

Sean noticed that KVM_GET_CLOCK was checking kvm_arch.use_master_clock
outside of the pvclock sync lock. This is problematic, as the clock
value written to the user may or may not actually correspond to a stable
TSC.

Fix the race by populating the entire kvm_clock_data structure behind
the pvclock_gtod_sync_lock.

Suggested-by: Sean Christopherson <seanjc at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/x86/kvm/x86.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fdc0c18339fb..2f3929bd5f58 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2787,19 +2787,20 @@ static void kvm_update_masterclock(struct kvm *kvm)
 	kvm_end_pvclock_update(kvm);
 }
 
-u64 get_kvmclock_ns(struct kvm *kvm)
+static void get_kvmclock(struct kvm *kvm, struct kvm_clock_data *data)
 {
 	struct kvm_arch *ka = &kvm->arch;
 	struct pvclock_vcpu_time_info hv_clock;
 	unsigned long flags;
-	u64 ret;
 
 	spin_lock_irqsave(&ka->pvclock_gtod_sync_lock, flags);
 	if (!ka->use_master_clock) {
 		spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
-		return get_kvmclock_base_ns() + ka->kvmclock_offset;
+		data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset;
+		return;
 	}
 
+	data->flags |= KVM_CLOCK_TSC_STABLE;
 	hv_clock.tsc_timestamp = ka->master_cycle_now;
 	hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
 	spin_unlock_irqrestore(&ka->pvclock_gtod_sync_lock, flags);
@@ -2811,13 +2812,26 @@ u64 get_kvmclock_ns(struct kvm *kvm)
 		kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
 				   &hv_clock.tsc_shift,
 				   &hv_clock.tsc_to_system_mul);
-		ret = __pvclock_read_cycles(&hv_clock, rdtsc());
-	} else
-		ret = get_kvmclock_base_ns() + ka->kvmclock_offset;
+		data->clock = __pvclock_read_cycles(&hv_clock, rdtsc());
+	} else {
+		data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset;
+	}
 
 	put_cpu();
+}
 
-	return ret;
+u64 get_kvmclock_ns(struct kvm *kvm)
+{
+	struct kvm_clock_data data;
+
+	/*
+	 * Zero flags as it's accessed RMW, leave everything else uninitialized
+	 * as clock is always written and no other fields are consumed.
+	 */
+	data.flags = 0;
+
+	get_kvmclock(kvm, &data);
+	return data.clock;
 }
 
 static void kvm_setup_pvclock_page(struct kvm_vcpu *v,
@@ -6098,11 +6112,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
 	}
 	case KVM_GET_CLOCK: {
 		struct kvm_clock_data user_ns;
-		u64 now_ns;
 
-		now_ns = get_kvmclock_ns(kvm);
-		user_ns.clock = now_ns;
-		user_ns.flags = kvm->arch.use_master_clock ? KVM_CLOCK_TSC_STABLE : 0;
+		/*
+		 * Zero flags as it is accessed RMW, leave everything else
+		 * uninitialized as clock is always written and no other fields
+		 * are consumed.
+		 */
+		user_ns.flags = 0;
+		get_kvmclock(kvm, &user_ns);
 		memset(&user_ns.pad, 0, sizeof(user_ns.pad));
 
 		r = -EFAULT;
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:11:26 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:11:26 +0000
Subject: [PATCH v7 2/6] KVM: x86: Create helper methods for
 KVM_{GET,SET}_CLOCK ioctls
In-Reply-To: <20210816001130.3059564-1-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
Message-ID: <20210816001130.3059564-3-oupton@google.com>

Wrap the existing implementation of the KVM_{GET,SET}_CLOCK ioctls in
helper methods.

No functional change intended.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/x86/kvm/x86.c | 107 ++++++++++++++++++++++++---------------------
 1 file changed, 57 insertions(+), 50 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2f3929bd5f58..39eaa2fb2001 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5833,12 +5833,65 @@ int kvm_arch_pm_notifier(struct kvm *kvm, unsigned long state)
 }
 #endif /* CONFIG_HAVE_KVM_PM_NOTIFIER */
 
+static int kvm_vm_ioctl_get_clock(struct kvm *kvm, void __user *argp)
+{
+	struct kvm_clock_data data;
+
+	/*
+	 * Zero flags as it is accessed RMW, leave everything else
+	 * uninitialized as clock is always written and no other fields
+	 * are consumed.
+	 */
+	data.flags = 0;
+	get_kvmclock(kvm, &data);
+	memset(&data.pad, 0, sizeof(data.pad));
+
+	if (copy_to_user(argp, &data, sizeof(data)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int kvm_vm_ioctl_set_clock(struct kvm *kvm, void __user *argp)
+{
+	struct kvm_arch *ka = &kvm->arch;
+	struct kvm_clock_data data;
+	u64 now_ns;
+
+	if (copy_from_user(&data, argp, sizeof(data)))
+		return -EFAULT;
+
+	if (data.flags)
+		return -EINVAL;
+
+	kvm_hv_invalidate_tsc_page(kvm);
+	kvm_start_pvclock_update(kvm);
+	pvclock_update_vm_gtod_copy(kvm);
+
+	/*
+	 * This pairs with kvm_guest_time_update(): when masterclock is
+	 * in use, we use master_kernel_ns + kvmclock_offset to set
+	 * unsigned 'system_time' so if we use get_kvmclock_ns() (which
+	 * is slightly ahead) here we risk going negative on unsigned
+	 * 'system_time' when 'data.clock' is very small.
+	 */
+	if (kvm->arch.use_master_clock)
+		now_ns = ka->master_kernel_ns;
+	else
+		now_ns = get_kvmclock_base_ns();
+	ka->kvmclock_offset = data.clock - now_ns;
+	kvm_end_pvclock_update(kvm);
+
+	return 0;
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
 	struct kvm *kvm = filp->private_data;
 	void __user *argp = (void __user *)arg;
 	int r = -ENOTTY;
+
 	/*
 	 * This union makes it completely explicit to gcc-3.x
 	 * that these two variables' stack usage should be
@@ -6076,58 +6129,12 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		break;
 	}
 #endif
-	case KVM_SET_CLOCK: {
-		struct kvm_arch *ka = &kvm->arch;
-		struct kvm_clock_data user_ns;
-		u64 now_ns;
-
-		r = -EFAULT;
-		if (copy_from_user(&user_ns, argp, sizeof(user_ns)))
-			goto out;
-
-		r = -EINVAL;
-		if (user_ns.flags)
-			goto out;
-
-		r = 0;
-
-		kvm_hv_invalidate_tsc_page(kvm);
-		kvm_start_pvclock_update(kvm);
-		pvclock_update_vm_gtod_copy(kvm);
-
-		/*
-		 * This pairs with kvm_guest_time_update(): when masterclock is
-		 * in use, we use master_kernel_ns + kvmclock_offset to set
-		 * unsigned 'system_time' so if we use get_kvmclock_ns() (which
-		 * is slightly ahead) here we risk going negative on unsigned
-		 * 'system_time' when 'user_ns.clock' is very small.
-		 */
-		if (kvm->arch.use_master_clock)
-			now_ns = ka->master_kernel_ns;
-		else
-			now_ns = get_kvmclock_base_ns();
-		ka->kvmclock_offset = user_ns.clock - now_ns;
-		kvm_end_pvclock_update(kvm);
+	case KVM_SET_CLOCK:
+		r = kvm_vm_ioctl_set_clock(kvm, argp);
 		break;
-	}
-	case KVM_GET_CLOCK: {
-		struct kvm_clock_data user_ns;
-
-		/*
-		 * Zero flags as it is accessed RMW, leave everything else
-		 * uninitialized as clock is always written and no other fields
-		 * are consumed.
-		 */
-		user_ns.flags = 0;
-		get_kvmclock(kvm, &user_ns);
-		memset(&user_ns.pad, 0, sizeof(user_ns.pad));
-
-		r = -EFAULT;
-		if (copy_to_user(argp, &user_ns, sizeof(user_ns)))
-			goto out;
-		r = 0;
+	case KVM_GET_CLOCK:
+		r = kvm_vm_ioctl_get_clock(kvm, argp);
 		break;
-	}
 	case KVM_MEMORY_ENCRYPT_OP: {
 		r = -ENOTTY;
 		if (kvm_x86_ops.mem_enc_op)
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:11:27 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:11:27 +0000
Subject: [PATCH v7 3/6] KVM: x86: Report host tsc and realtime values in
 KVM_GET_CLOCK
In-Reply-To: <20210816001130.3059564-1-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
Message-ID: <20210816001130.3059564-4-oupton@google.com>

Handling the migration of TSCs correctly is difficult, in part because
Linux does not provide userspace with the ability to retrieve a (TSC,
realtime) clock pair for a single instant in time. In lieu of a more
convenient facility, KVM can report similar information in the kvm_clock
structure.

Provide userspace with a host TSC & realtime pair iff the realtime clock
is based on the TSC. If userspace provides KVM_SET_CLOCK with a valid
realtime value, advance the KVM clock by the amount of elapsed time. Do
not step the KVM clock backwards, though, as it is a monotonic
oscillator.

Suggested-by: Paolo Bonzini <pbonzini at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 Documentation/virt/kvm/api.rst  | 42 ++++++++++++++++++++++++++-------
 arch/x86/include/asm/kvm_host.h |  3 +++
 arch/x86/kvm/x86.c              | 34 ++++++++++++++++++--------
 include/uapi/linux/kvm.h        |  7 +++++-
 4 files changed, 66 insertions(+), 20 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 86d7ad3a126c..b3d12bf9fbf5 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -993,20 +993,34 @@ such as migration.
 When KVM_CAP_ADJUST_CLOCK is passed to KVM_CHECK_EXTENSION, it returns the
 set of bits that KVM can return in struct kvm_clock_data's flag member.
 
-The only flag defined now is KVM_CLOCK_TSC_STABLE.  If set, the returned
-value is the exact kvmclock value seen by all VCPUs at the instant
-when KVM_GET_CLOCK was called.  If clear, the returned value is simply
-CLOCK_MONOTONIC plus a constant offset; the offset can be modified
-with KVM_SET_CLOCK.  KVM will try to make all VCPUs follow this clock,
-but the exact value read by each VCPU could differ, because the host
-TSC is not stable.
+FLAGS:
+
+KVM_CLOCK_TSC_STABLE.  If set, the returned value is the exact kvmclock
+value seen by all VCPUs at the instant when KVM_GET_CLOCK was called.
+If clear, the returned value is simply CLOCK_MONOTONIC plus a constant
+offset; the offset can be modified with KVM_SET_CLOCK.  KVM will try
+to make all VCPUs follow this clock, but the exact value read by each
+VCPU could differ, because the host TSC is not stable.
+
+KVM_CLOCK_REALTIME.  If set, the `realtime` field in the kvm_clock_data
+structure is populated with the value of the host's real time
+clocksource at the instant when KVM_GET_CLOCK was called. If clear,
+the `realtime` field does not contain a value.
+
+KVM_CLOCK_HOST_TSC.  If set, the `host_tsc` field in the kvm_clock_data
+structure is populated with the value of the host's timestamp counter (TSC)
+at the instant when KVM_GET_CLOCK was called. If clear, the `host_tsc` field
+does not contain a value.
 
 ::
 
   struct kvm_clock_data {
 	__u64 clock;  /* kvmclock current value */
 	__u32 flags;
-	__u32 pad[9];
+	__u32 pad0;
+	__u64 realtime;
+	__u64 host_tsc;
+	__u32 pad[4];
   };
 
 
@@ -1023,12 +1037,22 @@ Sets the current timestamp of kvmclock to the value specified in its parameter.
 In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
 such as migration.
 
+FLAGS:
+
+KVM_CLOCK_REALTIME.  If set, KVM will compare the value of the `realtime` field
+with the value of the host's real time clocksource at the instant when
+KVM_SET_CLOCK was called. The difference in elapsed time is added to the final
+kvmclock value that will be provided to guests.
+
 ::
 
   struct kvm_clock_data {
 	__u64 clock;  /* kvmclock current value */
 	__u32 flags;
-	__u32 pad[9];
+	__u32 pad0;
+	__u64 realtime;
+	__u64 host_tsc;
+	__u32 pad[4];
   };
 
 
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 20daaf67a5bf..7fad2615f4a9 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1916,4 +1916,7 @@ int kvm_cpu_dirty_log_size(void);
 
 int alloc_all_memslots_rmaps(struct kvm *kvm);
 
+#define KVM_CLOCK_VALID_FLAGS						\
+	(KVM_CLOCK_TSC_STABLE | KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC)
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 39eaa2fb2001..b1e9a4885be6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2809,10 +2809,20 @@ static void get_kvmclock(struct kvm *kvm, struct kvm_clock_data *data)
 	get_cpu();
 
 	if (__this_cpu_read(cpu_tsc_khz)) {
+#ifdef CONFIG_X86_64
+		struct timespec64 ts;
+
+		if (kvm_get_walltime_and_clockread(&ts, &data->host_tsc)) {
+			data->realtime = ts.tv_nsec + NSEC_PER_SEC * ts.tv_sec;
+			data->flags |= KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC;
+		} else
+#endif
+		data->host_tsc = rdtsc();
+
 		kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
 				   &hv_clock.tsc_shift,
 				   &hv_clock.tsc_to_system_mul);
-		data->clock = __pvclock_read_cycles(&hv_clock, rdtsc());
+		data->clock = __pvclock_read_cycles(&hv_clock, data->host_tsc);
 	} else {
 		data->clock = get_kvmclock_base_ns() + ka->kvmclock_offset;
 	}
@@ -4052,7 +4062,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = KVM_SYNC_X86_VALID_FIELDS;
 		break;
 	case KVM_CAP_ADJUST_CLOCK:
-		r = KVM_CLOCK_TSC_STABLE;
+		r = KVM_CLOCK_VALID_FLAGS;
 		break;
 	case KVM_CAP_X86_DISABLE_EXITS:
 		r |=  KVM_X86_DISABLE_EXITS_HLT | KVM_X86_DISABLE_EXITS_PAUSE |
@@ -5837,14 +5847,8 @@ static int kvm_vm_ioctl_get_clock(struct kvm *kvm, void __user *argp)
 {
 	struct kvm_clock_data data;
 
-	/*
-	 * Zero flags as it is accessed RMW, leave everything else
-	 * uninitialized as clock is always written and no other fields
-	 * are consumed.
-	 */
-	data.flags = 0;
+	memset(&data, 0, sizeof(data));
 	get_kvmclock(kvm, &data);
-	memset(&data.pad, 0, sizeof(data.pad));
 
 	if (copy_to_user(argp, &data, sizeof(data)))
 		return -EFAULT;
@@ -5861,13 +5865,23 @@ static int kvm_vm_ioctl_set_clock(struct kvm *kvm, void __user *argp)
 	if (copy_from_user(&data, argp, sizeof(data)))
 		return -EFAULT;
 
-	if (data.flags)
+	if (data.flags & ~KVM_CLOCK_REALTIME)
 		return -EINVAL;
 
 	kvm_hv_invalidate_tsc_page(kvm);
 	kvm_start_pvclock_update(kvm);
 	pvclock_update_vm_gtod_copy(kvm);
 
+	if (data.flags & KVM_CLOCK_REALTIME) {
+		u64 now_real_ns = ktime_get_real_ns();
+
+		/*
+		 * Avoid stepping the kvmclock backwards.
+		 */
+		if (now_real_ns > data.realtime)
+			data.clock += now_real_ns - data.realtime;
+	}
+
 	/*
 	 * This pairs with kvm_guest_time_update(): when masterclock is
 	 * in use, we use master_kernel_ns + kvmclock_offset to set
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index a067410ebea5..d228bf394465 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1223,11 +1223,16 @@ struct kvm_irqfd {
 
 /* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags.  */
 #define KVM_CLOCK_TSC_STABLE		2
+#define KVM_CLOCK_REALTIME		(1 << 2)
+#define KVM_CLOCK_HOST_TSC		(1 << 3)
 
 struct kvm_clock_data {
 	__u64 clock;
 	__u32 flags;
-	__u32 pad[9];
+	__u32 pad0;
+	__u64 realtime;
+	__u64 host_tsc;
+	__u32 pad[4];
 };
 
 /* For KVM_CAP_SW_TLB */
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:11:28 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:11:28 +0000
Subject: [PATCH v7 4/6] KVM: x86: Take the pvclock sync lock behind the
 tsc_write_lock
In-Reply-To: <20210816001130.3059564-1-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
Message-ID: <20210816001130.3059564-5-oupton@google.com>

A later change requires that the pvclock sync lock be taken while
holding the tsc_write_lock. Change the locking in kvm_synchronize_tsc()
to align with the requirement to isolate the locking change to its own
commit.

Cc: Sean Christopherson <seanjc at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 Documentation/virt/kvm/locking.rst | 11 +++++++++++
 arch/x86/kvm/x86.c                 |  2 +-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/locking.rst
index 8138201efb09..0bf346adac2a 100644
--- a/Documentation/virt/kvm/locking.rst
+++ b/Documentation/virt/kvm/locking.rst
@@ -36,6 +36,9 @@ On x86:
   holding kvm->arch.mmu_lock (typically with ``read_lock``, otherwise
   there's no need to take kvm->arch.tdp_mmu_pages_lock at all).
 
+- kvm->arch.tsc_write_lock is taken outside
+  kvm->arch.pvclock_gtod_sync_lock
+
 Everything else is a leaf: no other lock is taken inside the critical
 sections.
 
@@ -222,6 +225,14 @@ time it will be set using the Dirty tracking mechanism described above.
 :Comment:	'raw' because hardware enabling/disabling must be atomic /wrt
 		migration.
 
+:Name:		kvm_arch::pvclock_gtod_sync_lock
+:Type:		raw_spinlock_t
+:Arch:		x86
+:Protects:	kvm_arch::{cur_tsc_generation,cur_tsc_nsec,cur_tsc_write,
+			cur_tsc_offset,nr_vcpus_matched_tsc}
+:Comment:	'raw' because updating the kvm master clock must not be
+		preempted.
+
 :Name:		kvm_arch::tsc_write_lock
 :Type:		raw_spinlock
 :Arch:		x86
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b1e9a4885be6..f1434cd388b9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2533,7 +2533,6 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
 	vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
 
 	kvm_vcpu_write_tsc_offset(vcpu, offset);
-	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
 
 	spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags);
 	if (!matched) {
@@ -2544,6 +2543,7 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
 
 	kvm_track_tsc_matching(vcpu);
 	spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags);
+	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
 }
 
 static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:11:29 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:11:29 +0000
Subject: [PATCH v7 5/6] KVM: x86: Refactor tsc synchronization code
In-Reply-To: <20210816001130.3059564-1-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
Message-ID: <20210816001130.3059564-6-oupton@google.com>

Refactor kvm_synchronize_tsc to make a new function that allows callers
to specify TSC parameters (offset, value, nanoseconds, etc.) explicitly
for the sake of participating in TSC synchronization.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/x86/kvm/x86.c | 105 ++++++++++++++++++++++++++-------------------
 1 file changed, 61 insertions(+), 44 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f1434cd388b9..9d0445527dad 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2447,13 +2447,71 @@ static inline bool kvm_check_tsc_unstable(void)
 	return check_tsc_unstable();
 }
 
+/*
+ * Infers attempts to synchronize the guest's tsc from host writes. Sets the
+ * offset for the vcpu and tracks the TSC matching generation that the vcpu
+ * participates in.
+ */
+static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc,
+				  u64 ns, bool matched)
+{
+	struct kvm *kvm = vcpu->kvm;
+	bool already_matched;
+
+	lockdep_assert_held(&kvm->arch.tsc_write_lock);
+
+	already_matched =
+	       (vcpu->arch.this_tsc_generation == kvm->arch.cur_tsc_generation);
+
+	/*
+	 * We track the most recent recorded KHZ, write and time to
+	 * allow the matching interval to be extended at each write.
+	 */
+	kvm->arch.last_tsc_nsec = ns;
+	kvm->arch.last_tsc_write = tsc;
+	kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz;
+
+	vcpu->arch.last_guest_tsc = tsc;
+
+	/* Keep track of which generation this VCPU has synchronized to */
+	vcpu->arch.this_tsc_generation = kvm->arch.cur_tsc_generation;
+	vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec;
+	vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
+
+	kvm_vcpu_write_tsc_offset(vcpu, offset);
+
+	if (!matched) {
+		/*
+		 * We split periods of matched TSC writes into generations.
+		 * For each generation, we track the original measured
+		 * nanosecond time, offset, and write, so if TSCs are in
+		 * sync, we can match exact offset, and if not, we can match
+		 * exact software computation in compute_guest_tsc()
+		 *
+		 * These values are tracked in kvm->arch.cur_xxx variables.
+		 */
+		kvm->arch.cur_tsc_generation++;
+		kvm->arch.cur_tsc_nsec = ns;
+		kvm->arch.cur_tsc_write = tsc;
+		kvm->arch.cur_tsc_offset = offset;
+
+		spin_lock(&kvm->arch.pvclock_gtod_sync_lock);
+		kvm->arch.nr_vcpus_matched_tsc = 0;
+	} else if (!already_matched) {
+		spin_lock(&kvm->arch.pvclock_gtod_sync_lock);
+		kvm->arch.nr_vcpus_matched_tsc++;
+	}
+
+	kvm_track_tsc_matching(vcpu);
+	spin_unlock(&kvm->arch.pvclock_gtod_sync_lock);
+}
+
 static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
 {
 	struct kvm *kvm = vcpu->kvm;
 	u64 offset, ns, elapsed;
 	unsigned long flags;
-	bool matched;
-	bool already_matched;
+	bool matched = false;
 	bool synchronizing = false;
 
 	raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
@@ -2499,50 +2557,9 @@ static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 data)
 			offset = kvm_compute_l1_tsc_offset(vcpu, data);
 		}
 		matched = true;
-		already_matched = (vcpu->arch.this_tsc_generation == kvm->arch.cur_tsc_generation);
-	} else {
-		/*
-		 * We split periods of matched TSC writes into generations.
-		 * For each generation, we track the original measured
-		 * nanosecond time, offset, and write, so if TSCs are in
-		 * sync, we can match exact offset, and if not, we can match
-		 * exact software computation in compute_guest_tsc()
-		 *
-		 * These values are tracked in kvm->arch.cur_xxx variables.
-		 */
-		kvm->arch.cur_tsc_generation++;
-		kvm->arch.cur_tsc_nsec = ns;
-		kvm->arch.cur_tsc_write = data;
-		kvm->arch.cur_tsc_offset = offset;
-		matched = false;
 	}
 
-	/*
-	 * We also track th most recent recorded KHZ, write and time to
-	 * allow the matching interval to be extended at each write.
-	 */
-	kvm->arch.last_tsc_nsec = ns;
-	kvm->arch.last_tsc_write = data;
-	kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz;
-
-	vcpu->arch.last_guest_tsc = data;
-
-	/* Keep track of which generation this VCPU has synchronized to */
-	vcpu->arch.this_tsc_generation = kvm->arch.cur_tsc_generation;
-	vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec;
-	vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
-
-	kvm_vcpu_write_tsc_offset(vcpu, offset);
-
-	spin_lock_irqsave(&kvm->arch.pvclock_gtod_sync_lock, flags);
-	if (!matched) {
-		kvm->arch.nr_vcpus_matched_tsc = 0;
-	} else if (!already_matched) {
-		kvm->arch.nr_vcpus_matched_tsc++;
-	}
-
-	kvm_track_tsc_matching(vcpu);
-	spin_unlock_irqrestore(&kvm->arch.pvclock_gtod_sync_lock, flags);
+	__kvm_synchronize_tsc(vcpu, offset, data, ns, matched);
 	raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
 }
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:11:30 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:11:30 +0000
Subject: [PATCH v7 6/6] KVM: x86: Expose TSC offset controls to userspace
In-Reply-To: <20210816001130.3059564-1-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
Message-ID: <20210816001130.3059564-7-oupton@google.com>

To date, VMM-directed TSC synchronization and migration has been a bit
messy. KVM has some baked-in heuristics around TSC writes to infer if
the VMM is attempting to synchronize. This is problematic, as it depends
on host userspace writing to the guest's TSC within 1 second of the last
write.

A much cleaner approach to configuring the guest's views of the TSC is to
simply migrate the TSC offset for every vCPU. Offsets are idempotent,
and thus not subject to change depending on when the VMM actually
reads/writes values from/to KVM. The VMM can then read the TSC once with
KVM_GET_CLOCK to capture a (realtime, host_tsc) pair at the instant when
the guest is paused.

Cc: David Matlack <dmatlack at google.com>
Cc: Sean Christopherson <seanjc at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 Documentation/virt/kvm/devices/vcpu.rst |  57 +++++++++++++
 arch/x86/include/asm/kvm_host.h         |   1 +
 arch/x86/include/uapi/asm/kvm.h         |   4 +
 arch/x86/kvm/x86.c                      | 109 ++++++++++++++++++++++++
 4 files changed, 171 insertions(+)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 2acec3b9ef65..3b399d727c11 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -161,3 +161,60 @@ Specifies the base address of the stolen time structure for this VCPU. The
 base address must be 64 byte aligned and exist within a valid guest memory
 region. See Documentation/virt/kvm/arm/pvtime.rst for more information
 including the layout of the stolen time structure.
+
+4. GROUP: KVM_VCPU_TSC_CTRL
+===========================
+
+:Architectures: x86
+
+4.1 ATTRIBUTE: KVM_VCPU_TSC_OFFSET
+
+:Parameters: 64-bit unsigned TSC offset
+
+Returns:
+
+	 ======= ======================================
+	 -EFAULT Error reading/writing the provided
+		 parameter address.
+	 -ENXIO  Attribute not supported
+	 ======= ======================================
+
+Specifies the guest's TSC offset relative to the host's TSC. The guest's
+TSC is then derived by the following equation:
+
+  guest_tsc = host_tsc + KVM_VCPU_TSC_OFFSET
+
+This attribute is useful for the precise migration of a guest's TSC. The
+following describes a possible algorithm to use for the migration of a
+guest's TSC:
+
+From the source VMM process:
+
+1. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (t_0),
+   kvmclock nanoseconds (k_0), and realtime nanoseconds (r_0).
+
+2. Read the KVM_VCPU_TSC_OFFSET attribute for every vCPU to record the
+   guest TSC offset (off_n).
+
+3. Invoke the KVM_GET_TSC_KHZ ioctl to record the frequency of the
+   guest's TSC (freq).
+
+From the destination VMM process:
+
+4. Invoke the KVM_SET_CLOCK ioctl, providing the kvmclock nanoseconds
+   (k_0) and realtime nanoseconds (r_0) in their respective fields.
+   Ensure that the KVM_CLOCK_REALTIME flag is set in the provided
+   structure. KVM will advance the VM's kvmclock to account for elapsed
+   time since recording the clock values.
+
+5. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (t_1) and
+   kvmclock nanoseconds (k_1).
+
+6. Adjust the guest TSC offsets for every vCPU to account for (1) time
+   elapsed since recording state and (2) difference in TSCs between the
+   source and destination machine:
+
+   new_off_n = t_0 + off_n + (k_1 - k_0) * freq - t_1
+
+7. Write the KVM_VCPU_TSC_OFFSET attribute for every vCPU with the
+   respective value derived in the previous step.
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 7fad2615f4a9..376b26a294c9 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1071,6 +1071,7 @@ struct kvm_arch {
 	u64 last_tsc_nsec;
 	u64 last_tsc_write;
 	u32 last_tsc_khz;
+	u64 last_tsc_offset;
 	u64 cur_tsc_nsec;
 	u64 cur_tsc_write;
 	u64 cur_tsc_offset;
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index a6c327f8ad9e..0b22e1e84e78 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -503,4 +503,8 @@ struct kvm_pmu_event_filter {
 #define KVM_PMU_EVENT_ALLOW 0
 #define KVM_PMU_EVENT_DENY 1
 
+/* for KVM_{GET,SET,HAS}_DEVICE_ATTR */
+#define KVM_VCPU_TSC_CTRL 0 /* control group for the timestamp counter (TSC) */
+#define   KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */
+
 #endif /* _ASM_X86_KVM_H */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9d0445527dad..0b1398d439c0 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2470,6 +2470,7 @@ static void __kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 offset, u64 tsc,
 	kvm->arch.last_tsc_nsec = ns;
 	kvm->arch.last_tsc_write = tsc;
 	kvm->arch.last_tsc_khz = vcpu->arch.virtual_tsc_khz;
+	kvm->arch.last_tsc_offset = offset;
 
 	vcpu->arch.last_guest_tsc = tsc;
 
@@ -4923,6 +4924,109 @@ static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+static int kvm_arch_tsc_has_attr(struct kvm_vcpu *vcpu,
+				 struct kvm_device_attr *attr)
+{
+	int r;
+
+	switch (attr->attr) {
+	case KVM_VCPU_TSC_OFFSET:
+		r = 0;
+		break;
+	default:
+		r = -ENXIO;
+	}
+
+	return r;
+}
+
+static int kvm_arch_tsc_get_attr(struct kvm_vcpu *vcpu,
+				 struct kvm_device_attr *attr)
+{
+	u64 __user *uaddr = (u64 __user *)attr->addr;
+	int r;
+
+	switch (attr->attr) {
+	case KVM_VCPU_TSC_OFFSET:
+		r = -EFAULT;
+		if (put_user(vcpu->arch.l1_tsc_offset, uaddr))
+			break;
+		r = 0;
+		break;
+	default:
+		r = -ENXIO;
+	}
+
+	return r;
+}
+
+static int kvm_arch_tsc_set_attr(struct kvm_vcpu *vcpu,
+				 struct kvm_device_attr *attr)
+{
+	u64 __user *uaddr = (u64 __user *)attr->addr;
+	struct kvm *kvm = vcpu->kvm;
+	int r;
+
+	switch (attr->attr) {
+	case KVM_VCPU_TSC_OFFSET: {
+		u64 offset, tsc, ns;
+		unsigned long flags;
+		bool matched;
+
+		r = -EFAULT;
+		if (get_user(offset, uaddr))
+			break;
+
+		raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
+
+		matched = (vcpu->arch.virtual_tsc_khz &&
+			   kvm->arch.last_tsc_khz == vcpu->arch.virtual_tsc_khz &&
+			   kvm->arch.last_tsc_offset == offset);
+
+		tsc = kvm_scale_tsc(vcpu, rdtsc(), vcpu->arch.l1_tsc_scaling_ratio) + offset;
+		ns = get_kvmclock_base_ns();
+
+		__kvm_synchronize_tsc(vcpu, offset, tsc, ns, matched);
+		raw_spin_unlock_irqrestore(&kvm->arch.tsc_write_lock, flags);
+
+		r = 0;
+		break;
+	}
+	default:
+		r = -ENXIO;
+	}
+
+	return r;
+}
+
+static int kvm_vcpu_ioctl_device_attr(struct kvm_vcpu *vcpu,
+				      unsigned int ioctl,
+				      void __user *argp)
+{
+	struct kvm_device_attr attr;
+	int r;
+
+	if (copy_from_user(&attr, argp, sizeof(attr)))
+		return -EFAULT;
+
+	if (attr.group != KVM_VCPU_TSC_CTRL)
+		return -ENXIO;
+
+	switch (ioctl) {
+	case KVM_HAS_DEVICE_ATTR:
+		r = kvm_arch_tsc_has_attr(vcpu, &attr);
+		break;
+	case KVM_GET_DEVICE_ATTR:
+		r = kvm_arch_tsc_get_attr(vcpu, &attr);
+		break;
+	case KVM_SET_DEVICE_ATTR:
+		r = kvm_arch_tsc_set_attr(vcpu, &attr);
+		break;
+	}
+
+	return r;
+}
+
 static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 				     struct kvm_enable_cap *cap)
 {
@@ -5377,6 +5481,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 		r = __set_sregs2(vcpu, u.sregs2);
 		break;
 	}
+	case KVM_HAS_DEVICE_ATTR:
+	case KVM_GET_DEVICE_ATTR:
+	case KVM_SET_DEVICE_ATTR:
+		r = kvm_vcpu_ioctl_device_attr(vcpu, ioctl, argp);
+		break;
 	default:
 		r = -EINVAL;
 	}
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:11 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:11 +0000
Subject: [PATCH v7 1/7] KVM: arm64: Refactor update_vtimer_cntvoff()
In-Reply-To: <20210816001217.3063400-1-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
Message-ID: <20210816001217.3063400-2-oupton@google.com>

Make the implementation of update_vtimer_cntvoff() generic w.r.t. guest
timer context and spin off into a new helper method for later use.
Require callers of this new helper method to grab the kvm lock
beforehand.

No functional change intended.

Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
---
 arch/arm64/kvm/arch_timer.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 3df67c127489..c0101db75ad4 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -747,22 +747,32 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
-/* Make the updates of cntvoff for all vtimer contexts atomic */
-static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
+/* Make offset updates for all timer contexts atomic */
+static void update_timer_offset(struct kvm_vcpu *vcpu,
+				enum kvm_arch_timers timer, u64 offset)
 {
 	int i;
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_vcpu *tmp;
 
-	mutex_lock(&kvm->lock);
+	lockdep_assert_held(&kvm->lock);
+
 	kvm_for_each_vcpu(i, tmp, kvm)
-		timer_set_offset(vcpu_vtimer(tmp), cntvoff);
+		timer_set_offset(vcpu_get_timer(tmp, timer), offset);
 
 	/*
 	 * When called from the vcpu create path, the CPU being created is not
 	 * included in the loop above, so we just set it here as well.
 	 */
-	timer_set_offset(vcpu_vtimer(vcpu), cntvoff);
+	timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
+}
+
+static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
+{
+	struct kvm *kvm = vcpu->kvm;
+
+	mutex_lock(&kvm->lock);
+	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff);
 	mutex_unlock(&kvm->lock);
 }
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:10 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:10 +0000
Subject: [PATCH v7 0/7] KVM: arm64: Add idempotent controls to migrate guest
 counter
Message-ID: <20210816001217.3063400-1-oupton@google.com>

Currently, on KVM/arm64, we only allow a VMM to migrate the guest's
virtual counter by-value. Saving and restoring the counter by value is
problematic in the fact that the recorded state is not idempotent.
Furthermore, we obfuscate from userspace the fact that the architecture
actually provides offset-based controls.

Another issue is that KVM/arm64 doesn't provide userspace with the
controls of the physical counter-timer. This series aims to address both
issues by adding offset-based controls for the virtual and physical
counters.

Patches 1-2 are refactor changes required to provide offset controls to
userspace and putting in some generic plumbing to use for both physical
and virtual offsets.

Patch 3 exposes a vCPU's virtual offset through the KVM_*_ONE_REG
ioctls. When NV support is added to KVM, CNTVOFF_EL2 will be considered
a guest system register. So, it is safe to expose it now through that
ioctl.

Patch 4 adds a cpufeature bit to detect 'full' ECV implementations,
providing EL2 with the ability to offset the physical counter-timer.

Patch 5 exposes a vCPU's physical offset as a vCPU device attribute.
This is deliberate, as the attribute is not architectural; KVM uses this
attribute to track the host<->guest offset.

Patch 6 is a prepatory change for the sake of physical offset emulation,
as counter-timer traps must be configured separately for each vCPU.

Patch 7 allows non-ECV hosts to support the physical offset vCPU device
attribute, by trapping and emulating the physical counter registers.

This series was tested on an Ampere Mt. Jade system (non-ECV, VHE and
nVHE) as well as the ARM Base RevC FVP (ECV, VHE and nVHE). Patches
apply to kvmarm/next at the following commit:

ae280335cdb5 ("Merge branch kvm-arm64/mmu/el2-tracking into kvmarm-master/next")

Selftests for these changes are being mailed as a separate series, since
there exist dependencies betwen both x86 and arm64.

v6: https://lore.kernel.org/r/20210804085819.846610-1-oupton at google.com

v6 -> v7:
 - Fixed typo in documentation (Marc)
 - Clean up some unused variables (Drew)
 - Added trap configuration for ECV+nVHE (Marc)
 - Documented dependency on SCR_EL3.ECVEn (Marc)
 - wrap up ptimer_emulation_required() for use in hyp and kernel code
   (Drew)
 - check static branch condition first (Drew)
 - s/cpus_have_const_cap/cpus_have_final_cap/ (Marc)
 - s/ARM64_ECV/ARM64_HAS_ECV2/
 - Emulate CNTPCTSS_EL2 if ECV2 not present (Marc)
 - Reordered the introduction of some functions to ensure that we don't
   have unused functions in the middle of the series.
 - Cleaned up the read side of CNTVOFF_EL2 (from userspace). Don't
   open-code the answer based on the difference of hardware offsets,
   just use the guest system register value we stashed on the write
   side.

Oliver Upton (7):
  KVM: arm64: Refactor update_vtimer_cntvoff()
  KVM: arm64: Separate guest/host counter offset values
  KVM: arm64: Allow userspace to configure a vCPU's virtual offset
  arm64: cpufeature: Enumerate support for FEAT_ECV >= 0x2
  KVM: arm64: Allow userspace to configure a guest's counter-timer
    offset
  KVM: arm64: Configure timer traps in vcpu_load() for VHE
  KVM: arm64: Emulate physical counter offsetting on non-ECV systems

 Documentation/arm64/booting.rst         |   7 +
 Documentation/virt/kvm/api.rst          |  10 ++
 Documentation/virt/kvm/devices/vcpu.rst |  28 ++++
 arch/arm64/include/asm/kvm_asm.h        |   2 +
 arch/arm64/include/asm/sysreg.h         |   5 +
 arch/arm64/include/uapi/asm/kvm.h       |   2 +
 arch/arm64/kernel/cpufeature.c          |  10 ++
 arch/arm64/kvm/arch_timer.c             | 196 +++++++++++++++++++++---
 arch/arm64/kvm/arm.c                    |   4 +-
 arch/arm64/kvm/guest.c                  |   6 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  32 ++++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |   6 +
 arch/arm64/kvm/hyp/nvhe/timer-sr.c      |  20 ++-
 arch/arm64/kvm/hyp/vhe/timer-sr.c       |   5 +
 arch/arm64/tools/cpucaps                |   1 +
 include/clocksource/arm_arch_timer.h    |   1 +
 include/kvm/arm_arch_timer.h            |   9 +-
 17 files changed, 315 insertions(+), 29 deletions(-)

-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:13 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:13 +0000
Subject: [PATCH v7 3/7] KVM: arm64: Allow userspace to configure a vCPU's
 virtual offset
In-Reply-To: <20210816001217.3063400-1-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
Message-ID: <20210816001217.3063400-4-oupton@google.com>

Allow userspace to access the guest's virtual counter-timer offset
through the ONE_REG interface. The value read or written is defined to
be an offset from the guest's physical counter-timer. Add some
documentation to clarify how a VMM should use this and the existing
CNTVCT_EL0.

Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
---
 Documentation/virt/kvm/api.rst    | 10 ++++++++++
 arch/arm64/include/uapi/asm/kvm.h |  1 +
 arch/arm64/kvm/arch_timer.c       | 23 +++++++++++++++++++++++
 arch/arm64/kvm/guest.c            |  6 +++++-
 include/kvm/arm_arch_timer.h      |  1 +
 5 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index dae68e68ca23..adb04046a752 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -2463,6 +2463,16 @@ arm64 system registers have the following id bit patterns::
      derived from the register encoding for CNTV_CVAL_EL0.  As this is
      API, it must remain this way.
 
+.. warning::
+
+     The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from
+     the guest's view of the physical counter-timer.
+
+     Userspace should use either KVM_REG_ARM_TIMER_OFFSET or
+     KVM_REG_ARM_TIMER_CNT to pause and resume a guest's virtual
+     counter-timer. Mixed use of these registers could result in an
+     unpredictable guest counter value.
+
 arm64 firmware pseudo-registers have the following bit pattern::
 
   0x6030 0000 0014 <regno:16>
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..949a31bc10f0 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_TIMER_CTL		ARM64_SYS_REG(3, 3, 14, 3, 1)
 #define KVM_REG_ARM_TIMER_CVAL		ARM64_SYS_REG(3, 3, 14, 0, 2)
 #define KVM_REG_ARM_TIMER_CNT		ARM64_SYS_REG(3, 3, 14, 3, 2)
+#define KVM_REG_ARM_TIMER_OFFSET	ARM64_SYS_REG(3, 4, 14, 0, 3)
 
 /* KVM-as-firmware specific pseudo-registers */
 #define KVM_REG_ARM_FW			(0x0014 << KVM_REG_ARM_COPROC_SHIFT)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index cf2f4a034dbe..9d9bac3ec40e 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -92,6 +92,18 @@ static u64 timer_get_offset(struct arch_timer_context *ctxt)
 	}
 }
 
+static u64 timer_get_guest_offset(struct arch_timer_context *ctxt)
+{
+	struct kvm_vcpu *vcpu = ctxt->vcpu;
+
+	switch (arch_timer_ctx_index(ctxt)) {
+	case TIMER_VTIMER:
+		return __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
+	default:
+		return 0;
+	}
+}
+
 static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
 {
 	struct kvm_vcpu *vcpu = ctxt->vcpu;
@@ -852,6 +864,10 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
 		timer = vcpu_vtimer(vcpu);
 		kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value);
 		break;
+	case KVM_REG_ARM_TIMER_OFFSET:
+		timer = vcpu_vtimer(vcpu);
+		update_vtimer_cntvoff(vcpu, value);
+		break;
 	case KVM_REG_ARM_PTIMER_CTL:
 		timer = vcpu_ptimer(vcpu);
 		kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
@@ -896,6 +912,9 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
 	case KVM_REG_ARM_TIMER_CVAL:
 		return kvm_arm_timer_read(vcpu,
 					  vcpu_vtimer(vcpu), TIMER_REG_CVAL);
+	case KVM_REG_ARM_TIMER_OFFSET:
+		return kvm_arm_timer_read(vcpu,
+					  vcpu_vtimer(vcpu), TIMER_REG_OFFSET);
 	case KVM_REG_ARM_PTIMER_CTL:
 		return kvm_arm_timer_read(vcpu,
 					  vcpu_ptimer(vcpu), TIMER_REG_CTL);
@@ -933,6 +952,10 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 		val = kvm_phys_timer_read() - timer_get_offset(timer);
 		break;
 
+	case TIMER_REG_OFFSET:
+		val = timer_get_guest_offset(timer);
+		break;
+
 	default:
 		BUG();
 	}
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 1dfb83578277..17fc06e2b422 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -591,7 +591,7 @@ static unsigned long num_core_regs(const struct kvm_vcpu *vcpu)
  * ARM64 versions of the TIMER registers, always available on arm64
  */
 
-#define NUM_TIMER_REGS 3
+#define NUM_TIMER_REGS 4
 
 static bool is_timer_reg(u64 index)
 {
@@ -599,6 +599,7 @@ static bool is_timer_reg(u64 index)
 	case KVM_REG_ARM_TIMER_CTL:
 	case KVM_REG_ARM_TIMER_CNT:
 	case KVM_REG_ARM_TIMER_CVAL:
+	case KVM_REG_ARM_TIMER_OFFSET:
 		return true;
 	}
 	return false;
@@ -614,6 +615,9 @@ static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 	uindices++;
 	if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices))
 		return -EFAULT;
+	uindices++;
+	if (put_user(KVM_REG_ARM_TIMER_OFFSET, uindices))
+		return -EFAULT;
 
 	return 0;
 }
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 9d65d4a29f81..615f9314f6a5 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -21,6 +21,7 @@ enum kvm_arch_timer_regs {
 	TIMER_REG_CVAL,
 	TIMER_REG_TVAL,
 	TIMER_REG_CTL,
+	TIMER_REG_OFFSET,
 };
 
 struct arch_timer_context {
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:12 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:12 +0000
Subject: [PATCH v7 2/7] KVM: arm64: Separate guest/host counter offset values
In-Reply-To: <20210816001217.3063400-1-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
Message-ID: <20210816001217.3063400-3-oupton@google.com>

In some instances, a VMM may want to update the guest's counter-timer
offset in a transparent manner, meaning that changes to the hardware
value do not affect the synthetic register presented to the guest or the
VMM through said guest's architectural state. Lay the groundwork to
separate guest offset register writes from the hardware values utilized
by KVM.

Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
---
 arch/arm64/kvm/arch_timer.c  | 42 +++++++++++++++++++++++++++---------
 include/kvm/arm_arch_timer.h |  3 +++
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index c0101db75ad4..cf2f4a034dbe 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -84,11 +84,9 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
 
 static u64 timer_get_offset(struct arch_timer_context *ctxt)
 {
-	struct kvm_vcpu *vcpu = ctxt->vcpu;
-
 	switch(arch_timer_ctx_index(ctxt)) {
 	case TIMER_VTIMER:
-		return __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
+		return ctxt->host_offset;
 	default:
 		return 0;
 	}
@@ -128,17 +126,33 @@ static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
 
 static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
 {
-	struct kvm_vcpu *vcpu = ctxt->vcpu;
-
 	switch(arch_timer_ctx_index(ctxt)) {
 	case TIMER_VTIMER:
-		__vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset;
+		ctxt->host_offset = offset;
 		break;
 	default:
 		WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
 	}
 }
 
+static void timer_set_guest_offset(struct arch_timer_context *ctxt, u64 offset)
+{
+	struct kvm_vcpu *vcpu = ctxt->vcpu;
+
+	switch (arch_timer_ctx_index(ctxt)) {
+	case TIMER_VTIMER: {
+		u64 host_offset = timer_get_offset(ctxt);
+
+		host_offset += offset - __vcpu_sys_reg(vcpu, CNTVOFF_EL2);
+		__vcpu_sys_reg(vcpu, CNTVOFF_EL2) = offset;
+		timer_set_offset(ctxt, host_offset);
+		break;
+	}
+	default:
+		WARN_ONCE(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
+	}
+}
+
 u64 kvm_phys_timer_read(void)
 {
 	return timecounter->cc->read(timecounter->cc);
@@ -749,7 +763,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
 
 /* Make offset updates for all timer contexts atomic */
 static void update_timer_offset(struct kvm_vcpu *vcpu,
-				enum kvm_arch_timers timer, u64 offset)
+				enum kvm_arch_timers timer, u64 offset,
+				bool guest_visible)
 {
 	int i;
 	struct kvm *kvm = vcpu->kvm;
@@ -758,13 +773,20 @@ static void update_timer_offset(struct kvm_vcpu *vcpu,
 	lockdep_assert_held(&kvm->lock);
 
 	kvm_for_each_vcpu(i, tmp, kvm)
-		timer_set_offset(vcpu_get_timer(tmp, timer), offset);
+		if (guest_visible)
+			timer_set_guest_offset(vcpu_get_timer(tmp, timer),
+					       offset);
+		else
+			timer_set_offset(vcpu_get_timer(tmp, timer), offset);
 
 	/*
 	 * When called from the vcpu create path, the CPU being created is not
 	 * included in the loop above, so we just set it here as well.
 	 */
-	timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
+	if (guest_visible)
+		timer_set_guest_offset(vcpu_get_timer(vcpu, timer), offset);
+	else
+		timer_set_offset(vcpu_get_timer(vcpu, timer), offset);
 }
 
 static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
@@ -772,7 +794,7 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
 	struct kvm *kvm = vcpu->kvm;
 
 	mutex_lock(&kvm->lock);
-	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff);
+	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, true);
 	mutex_unlock(&kvm->lock);
 }
 
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 51c19381108c..9d65d4a29f81 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -42,6 +42,9 @@ struct arch_timer_context {
 	/* Duplicated state from arch_timer.c for convenience */
 	u32				host_timer_irq;
 	u32				host_timer_irq_flags;
+
+	/* offset relative to the host's physical counter-timer */
+	u64				host_offset;
 };
 
 struct timer_map {
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:14 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:14 +0000
Subject: [PATCH v7 4/7] arm64: cpufeature: Enumerate support for FEAT_ECV >=
 0x2
In-Reply-To: <20210816001217.3063400-1-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
Message-ID: <20210816001217.3063400-5-oupton@google.com>

Introduce a new cpucap to indicate if the system supports full enhanced
counter virtualization (i.e. ID_AA64MMFR0_EL1.ECV>=0x2).

Signed-off-by: Oliver Upton <oupton at google.com>
---
 arch/arm64/include/asm/sysreg.h |  1 +
 arch/arm64/kernel/cpufeature.c  | 10 ++++++++++
 arch/arm64/tools/cpucaps        |  1 +
 3 files changed, 12 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 943d31d92b5b..c7ddf9a71134 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -847,6 +847,7 @@
 #define ID_AA64MMFR0_ASID_SHIFT		4
 #define ID_AA64MMFR0_PARANGE_SHIFT	0
 
+#define ID_AA64MMFR0_ECV_PHYS		0x2
 #define ID_AA64MMFR0_TGRAN4_NI		0xf
 #define ID_AA64MMFR0_TGRAN4_SUPPORTED	0x0
 #define ID_AA64MMFR0_TGRAN64_NI		0xf
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0ead8bfedf20..b44cef8deacc 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2301,6 +2301,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
+	{
+		.desc = "Enhanced Counter Virtualization (Physical)",
+		.capability = ARM64_HAS_ECV2,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.sys_reg = SYS_ID_AA64MMFR0_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR0_ECV_SHIFT,
+		.matches = has_cpuid_feature,
+		.min_field_value = ID_AA64MMFR0_ECV_PHYS,
+	},
 	{},
 };
 
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 49305c2e6dfd..f73a30d5fb1c 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -18,6 +18,7 @@ HAS_CRC32
 HAS_DCPODP
 HAS_DCPOP
 HAS_E0PD
+HAS_ECV2
 HAS_EPAN
 HAS_GENERIC_AUTH
 HAS_GENERIC_AUTH_ARCH
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:15 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:15 +0000
Subject: [PATCH v7 5/7] KVM: arm64: Allow userspace to configure a guest's
 counter-timer offset
In-Reply-To: <20210816001217.3063400-1-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
Message-ID: <20210816001217.3063400-6-oupton@google.com>

Presently, KVM provides no facilities for correctly migrating a guest
that depends on the physical counter-timer. While most guests (barring
NV, of course) should not depend on the physical counter-timer, an
operator may wish to provide a consistent view of the physical
counter-timer across migrations.

Provide userspace with a new vCPU attribute to modify the guest
counter-timer offset. Unlike KVM_REG_ARM_TIMER_OFFSET, this attribute is
hidden from the guest's architectural state. The value offsets *both*
the virtual and physical counter-timer views for the guest. Only support
this attribute on ECV systems as ECV is required for hardware offsetting
of the physical counter-timer.

Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
---
 Documentation/arm64/booting.rst         |  7 ++
 Documentation/virt/kvm/devices/vcpu.rst | 28 ++++++++
 arch/arm64/include/asm/kvm_asm.h        |  2 +
 arch/arm64/include/asm/sysreg.h         |  2 +
 arch/arm64/include/uapi/asm/kvm.h       |  1 +
 arch/arm64/kvm/arch_timer.c             | 96 ++++++++++++++++++++++++-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  6 ++
 arch/arm64/kvm/hyp/nvhe/timer-sr.c      |  9 +++
 arch/arm64/kvm/hyp/vhe/timer-sr.c       |  5 ++
 include/clocksource/arm_arch_timer.h    |  1 +
 10 files changed, 155 insertions(+), 2 deletions(-)

diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
index a9192e7a231b..bfdbc9df7b55 100644
--- a/Documentation/arm64/booting.rst
+++ b/Documentation/arm64/booting.rst
@@ -311,6 +311,13 @@ Before jumping into the kernel, the following conditions must be met:
     - ZCR_EL2.LEN must be initialised to the same value for all CPUs the
       kernel will execute on.
 
+  For CPUs with the Enhanced Counter Virtualization (FEAT_ECV) extension
+  present with ID_AA64MMFR0_EL1.ECV >= 0x2:
+
+  - if EL3 is present and the kernel is entered at EL2:
+
+    - SCR_EL3.ECVEn (bit 28) must be initialized to 0b1.
+
 The requirements described above for CPU mode, caches, MMUs, architected
 timers, coherency and system registers apply to all CPUs.  All CPUs must
 enter the kernel in the same exception level.  Where the values documented
diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 2acec3b9ef65..f240ecc174ef 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -139,6 +139,34 @@ configured values on other VCPUs.  Userspace should configure the interrupt
 numbers on at least one VCPU after creating all VCPUs and before running any
 VCPUs.
 
+2.2. ATTRIBUTE: KVM_ARM_VCPU_TIMER_PHYS_OFFSET
+-----------------------------------------
+
+:Parameters: in kvm_device_attr.addr the address for the timer offset is a
+             pointer to a __u64
+
+Returns:
+
+	 ======= ==================================
+	 -EFAULT Error reading/writing the provided
+		 parameter address
+	 -ENXIO  Timer offsetting not implemented
+	 ======= ==================================
+
+Specifies the guest's counter-timer offset from the host's virtual counter.
+The guest's physical counter value is then derived by the following
+equation:
+
+  guest_cntpct = host_cntvct - KVM_ARM_VCPU_TIMER_PHYS_OFFSET
+
+The guest's virtual counter value is derived by the following equation:
+
+  guest_cntvct = host_cntvct - KVM_REG_ARM_TIMER_OFFSET
+			- KVM_ARM_VCPU_TIMER_PHYS_OFFSET
+
+KVM does not allow the use of varying offset values for different vCPUs;
+the last written offset value will be broadcasted to all vCPUs in a VM.
+
 3. GROUP: KVM_ARM_VCPU_PVTIME_CTRL
 ==================================
 
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index aed2aa61766a..052a6f987095 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -64,6 +64,7 @@
 #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector		18
 #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize		19
 #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc			20
+#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntpoff		21
 
 #ifndef __ASSEMBLY__
 
@@ -199,6 +200,7 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
 extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
 
 extern void __kvm_timer_set_cntvoff(u64 cntvoff);
+extern void __kvm_timer_set_cntpoff(u64 cntpoff);
 
 extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index c7ddf9a71134..e02b7cd574e6 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -586,6 +586,8 @@
 #define SYS_ICH_LR14_EL2		__SYS__LR8_EL2(6)
 #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
 
+#define SYS_CNTPOFF_EL2			sys_reg(3, 4, 14, 0, 6)
+
 /* VHE encodings for architectural EL0/1 system registers */
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
 #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 949a31bc10f0..70e2893c1749 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -366,6 +366,7 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_ARM_VCPU_TIMER_CTRL		1
 #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
+#define   KVM_ARM_VCPU_TIMER_PHYS_OFFSET	2
 #define KVM_ARM_VCPU_PVTIME_CTRL	2
 #define   KVM_ARM_VCPU_PVTIME_IPA	0
 
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 9d9bac3ec40e..46380c389683 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -86,8 +86,11 @@ static u64 timer_get_offset(struct arch_timer_context *ctxt)
 {
 	switch(arch_timer_ctx_index(ctxt)) {
 	case TIMER_VTIMER:
+	case TIMER_PTIMER:
 		return ctxt->host_offset;
 	default:
+		WARN_ONCE(1, "unrecognized timer %ld\n",
+			  arch_timer_ctx_index(ctxt));
 		return 0;
 	}
 }
@@ -140,6 +143,7 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
 {
 	switch(arch_timer_ctx_index(ctxt)) {
 	case TIMER_VTIMER:
+	case TIMER_PTIMER:
 		ctxt->host_offset = offset;
 		break;
 	default:
@@ -568,6 +572,11 @@ static void set_cntvoff(u64 cntvoff)
 	kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff);
 }
 
+static void set_cntpoff(u64 cntpoff)
+{
+	kvm_call_hyp(__kvm_timer_set_cntpoff, cntpoff);
+}
+
 static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active)
 {
 	int r;
@@ -643,6 +652,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 	}
 
 	set_cntvoff(timer_get_offset(map.direct_vtimer));
+	if (cpus_have_final_cap(ARM64_HAS_ECV2))
+		set_cntpoff(timer_get_offset(vcpu_ptimer(vcpu)));
 
 	kvm_timer_unblocking(vcpu);
 
@@ -810,6 +821,22 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
 	mutex_unlock(&kvm->lock);
 }
 
+static void update_ptimer_cntpoff(struct kvm_vcpu *vcpu, u64 cntpoff)
+{
+	struct kvm *kvm = vcpu->kvm;
+	u64 cntvoff;
+
+	mutex_lock(&kvm->lock);
+
+	/* adjustments to the physical offset also affect vtimer */
+	cntvoff = timer_get_offset(vcpu_vtimer(vcpu));
+	cntvoff += cntpoff - timer_get_offset(vcpu_ptimer(vcpu));
+
+	update_timer_offset(vcpu, TIMER_PTIMER, cntpoff, false);
+	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, false);
+	mutex_unlock(&kvm->lock);
+}
+
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
@@ -1346,6 +1373,9 @@ void kvm_timer_init_vhe(void)
 	val = read_sysreg(cnthctl_el2);
 	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
 	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
+
+	if (cpus_have_final_cap(ARM64_HAS_ECV2))
+		val |= CNTHCTL_ECV;
 	write_sysreg(val, cnthctl_el2);
 }
 
@@ -1360,7 +1390,8 @@ static void set_timer_irqs(struct kvm *kvm, int vtimer_irq, int ptimer_irq)
 	}
 }
 
-int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+static int kvm_arm_timer_set_attr_irq(struct kvm_vcpu *vcpu,
+				      struct kvm_device_attr *attr)
 {
 	int __user *uaddr = (int __user *)(long)attr->addr;
 	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
@@ -1393,7 +1424,37 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	return 0;
 }
 
-int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
+					 struct kvm_device_attr *attr)
+{
+	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
+	u64 offset;
+
+	if (!cpus_have_final_cap(ARM64_HAS_ECV2))
+		return -ENXIO;
+
+	if (get_user(offset, uaddr))
+		return -EFAULT;
+
+	update_ptimer_cntpoff(vcpu, offset);
+	return 0;
+}
+
+int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+{
+	switch (attr->attr) {
+	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
+	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
+		return kvm_arm_timer_set_attr_irq(vcpu, attr);
+	case KVM_ARM_VCPU_TIMER_PHYS_OFFSET:
+		return kvm_arm_timer_set_attr_offset(vcpu, attr);
+	default:
+		return -ENXIO;
+	}
+}
+
+static int kvm_arm_timer_get_attr_irq(struct kvm_vcpu *vcpu,
+				      struct kvm_device_attr *attr)
 {
 	int __user *uaddr = (int __user *)(long)attr->addr;
 	struct arch_timer_context *timer;
@@ -1414,12 +1475,43 @@ int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	return put_user(irq, uaddr);
 }
 
+static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
+					 struct kvm_device_attr *attr)
+{
+	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
+	u64 offset;
+
+	if (!cpus_have_final_cap(ARM64_HAS_ECV2))
+		return -ENXIO;
+
+	offset = timer_get_offset(vcpu_ptimer(vcpu));
+	return put_user(offset, uaddr);
+}
+
+int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu,
+			   struct kvm_device_attr *attr)
+{
+	switch (attr->attr) {
+	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
+	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
+		return kvm_arm_timer_get_attr_irq(vcpu, attr);
+	case KVM_ARM_VCPU_TIMER_PHYS_OFFSET:
+		return kvm_arm_timer_get_attr_offset(vcpu, attr);
+	default:
+		return -ENXIO;
+	}
+}
+
 int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 {
 	switch (attr->attr) {
 	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
 	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
 		return 0;
+	case KVM_ARM_VCPU_TIMER_PHYS_OFFSET:
+		if (cpus_have_final_cap(ARM64_HAS_ECV2))
+			return 0;
+		break;
 	}
 
 	return -ENXIO;
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 2da6aa8da868..f1b8da4737dc 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -68,6 +68,11 @@ static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt)
 	__kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1));
 }
 
+static void handle___kvm_timer_set_cntpoff(struct kvm_cpu_context *host_ctxt)
+{
+	__kvm_timer_set_cntpoff(cpu_reg(host_ctxt, 1));
+}
+
 static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt)
 {
 	u64 tmp;
@@ -185,6 +190,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_create_private_mapping),
 	HANDLE_FUNC(__pkvm_prot_finalize),
+	HANDLE_FUNC(__kvm_timer_set_cntpoff),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index 9072e71693ba..e98a949f5227 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -15,6 +15,11 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
 	write_sysreg(cntvoff, cntvoff_el2);
 }
 
+void __kvm_timer_set_cntpoff(u64 cntpoff)
+{
+	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
+}
+
 /*
  * Should only be called on non-VHE systems.
  * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe().
@@ -26,6 +31,8 @@ void __timer_disable_traps(struct kvm_vcpu *vcpu)
 	/* Allow physical timer/counter access for the host */
 	val = read_sysreg(cnthctl_el2);
 	val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
+	if (cpus_have_final_cap(ARM64_HAS_ECV2))
+		val &= ~CNTHCTL_ECV;
 	write_sysreg(val, cnthctl_el2);
 }
 
@@ -42,6 +49,8 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
 	 * Physical counter access is allowed
 	 */
 	val = read_sysreg(cnthctl_el2);
+	if (cpus_have_final_cap(ARM64_HAS_ECV2))
+		val |= CNTHCTL_ECV;
 	val &= ~CNTHCTL_EL1PCEN;
 	val |= CNTHCTL_EL1PCTEN;
 	write_sysreg(val, cnthctl_el2);
diff --git a/arch/arm64/kvm/hyp/vhe/timer-sr.c b/arch/arm64/kvm/hyp/vhe/timer-sr.c
index 4cda674a8be6..231e16a071a5 100644
--- a/arch/arm64/kvm/hyp/vhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/timer-sr.c
@@ -10,3 +10,8 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
 {
 	write_sysreg(cntvoff, cntvoff_el2);
 }
+
+void __kvm_timer_set_cntpoff(u64 cntpoff)
+{
+	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
+}
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 73c7139c866f..7252ffa3d675 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -21,6 +21,7 @@
 #define CNTHCTL_EVNTEN			(1 << 2)
 #define CNTHCTL_EVNTDIR			(1 << 3)
 #define CNTHCTL_EVNTI			(0xF << 4)
+#define CNTHCTL_ECV			(1 << 12)
 
 enum arch_timer_reg {
 	ARCH_TIMER_REG_CTRL,
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:16 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:16 +0000
Subject: [PATCH v7 6/7] KVM: arm64: Configure timer traps in vcpu_load() for
 VHE
In-Reply-To: <20210816001217.3063400-1-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
Message-ID: <20210816001217.3063400-7-oupton@google.com>

In preparation for emulated physical counter-timer offsetting, configure
traps on every vcpu_load() for VHE systems. As before, these trap
settings do not affect host userspace, and are only active for the
guest.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
---
 arch/arm64/kvm/arch_timer.c  | 10 +++++++---
 arch/arm64/kvm/arm.c         |  4 +---
 include/kvm/arm_arch_timer.h |  2 --
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 46380c389683..1689c2e20cd3 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -51,6 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
 static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 			      struct arch_timer_context *timer,
 			      enum kvm_arch_timer_regs treg);
+static void kvm_timer_enable_traps_vhe(void);
 
 u32 timer_get_ctl(struct arch_timer_context *ctxt)
 {
@@ -663,6 +664,9 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 
 	if (map.emul_ptimer)
 		timer_emulate(map.emul_ptimer);
+
+	if (has_vhe())
+		kvm_timer_enable_traps_vhe();
 }
 
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
@@ -1355,12 +1359,12 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
 }
 
 /*
- * On VHE system, we only need to configure the EL2 timer trap register once,
- * not for every world switch.
+ * On VHE system, we only need to configure the EL2 timer trap register on
+ * vcpu_load(), but not every world switch into the guest.
  * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
  * and this makes those bits have no effect for the host kernel execution.
  */
-void kvm_timer_init_vhe(void)
+static void kvm_timer_enable_traps_vhe(void)
 {
 	/* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
 	u32 cnthctl_shift = 10;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 0de4b41c3706..f882a7fb3a1b 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1559,9 +1559,7 @@ static void cpu_hyp_reinit(void)
 
 	cpu_hyp_reset();
 
-	if (is_kernel_in_hyp_mode())
-		kvm_timer_init_vhe();
-	else
+	if (!is_kernel_in_hyp_mode())
 		cpu_init_hyp_mode();
 
 	cpu_set_hyp_vector();
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 615f9314f6a5..254653b42da0 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -87,8 +87,6 @@ u64 kvm_phys_timer_read(void);
 void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu);
 
-void kvm_timer_init_vhe(void);
-
 bool kvm_arch_timer_get_input_level(int vintid);
 
 #define vcpu_timer(v)	(&(v)->arch.timer_cpu)
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:17 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:17 +0000
Subject: [PATCH v7 7/7] KVM: arm64: Emulate physical counter offsetting on
 non-ECV systems
In-Reply-To: <20210816001217.3063400-1-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
Message-ID: <20210816001217.3063400-8-oupton@google.com>

Unfortunately, ECV hasn't yet arrived in any tangible hardware. At the
same time, controlling the guest view of the physical counter-timer is
useful. Support guest counter-timer offsetting on non-ECV systems by
trapping guest accesses to the physical counter-timer. Emulate reads of
the physical counter in the fast exit path.

Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
---
 arch/arm64/include/asm/sysreg.h         |  2 ++
 arch/arm64/kvm/arch_timer.c             | 47 +++++++++++++------------
 arch/arm64/kvm/hyp/include/hyp/switch.h | 32 +++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/timer-sr.c      | 11 ++++--
 include/kvm/arm_arch_timer.h            |  3 ++
 5 files changed, 71 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index e02b7cd574e6..b468acf7add0 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -505,6 +505,8 @@
 #define SYS_AMEVCNTR0_MEM_STALL		SYS_AMEVCNTR0_EL0(3)
 
 #define SYS_CNTFRQ_EL0			sys_reg(3, 3, 14, 0, 0)
+#define SYS_CNTPCT_EL0			sys_reg(3, 3, 14, 0, 1)
+#define SYS_CNTPCTSS_EL0		sys_reg(3, 3, 14, 0, 5)
 
 #define SYS_CNTP_TVAL_EL0		sys_reg(3, 3, 14, 2, 0)
 #define SYS_CNTP_CTL_EL0		sys_reg(3, 3, 14, 2, 1)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 1689c2e20cd3..625762c4234f 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -51,7 +51,7 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
 static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 			      struct arch_timer_context *timer,
 			      enum kvm_arch_timer_regs treg);
-static void kvm_timer_enable_traps_vhe(void);
+static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu);
 
 u32 timer_get_ctl(struct arch_timer_context *ctxt)
 {
@@ -179,8 +179,13 @@ static void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
 {
 	if (has_vhe()) {
 		map->direct_vtimer = vcpu_vtimer(vcpu);
-		map->direct_ptimer = vcpu_ptimer(vcpu);
-		map->emul_ptimer = NULL;
+		if (!ptimer_emulation_required(vcpu)) {
+			map->direct_ptimer = vcpu_ptimer(vcpu);
+			map->emul_ptimer = NULL;
+		} else {
+			map->direct_ptimer = NULL;
+			map->emul_ptimer = vcpu_ptimer(vcpu);
+		}
 	} else {
 		map->direct_vtimer = vcpu_vtimer(vcpu);
 		map->direct_ptimer = NULL;
@@ -666,7 +671,7 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 		timer_emulate(map.emul_ptimer);
 
 	if (has_vhe())
-		kvm_timer_enable_traps_vhe();
+		kvm_timer_enable_traps_vhe(vcpu);
 }
 
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
@@ -1364,22 +1369,29 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
  * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
  * and this makes those bits have no effect for the host kernel execution.
  */
-static void kvm_timer_enable_traps_vhe(void)
+static void kvm_timer_enable_traps_vhe(struct kvm_vcpu *vcpu)
 {
 	/* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
 	u32 cnthctl_shift = 10;
-	u64 val;
+	u64 val, mask;
+
+	mask = CNTHCTL_EL1PCEN << cnthctl_shift;
+	mask |= CNTHCTL_EL1PCTEN << cnthctl_shift;
 
-	/*
-	 * VHE systems allow the guest direct access to the EL1 physical
-	 * timer/counter.
-	 */
 	val = read_sysreg(cnthctl_el2);
-	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
-	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
 
 	if (cpus_have_final_cap(ARM64_HAS_ECV2))
 		val |= CNTHCTL_ECV;
+
+	/*
+	 * VHE systems allow the guest direct access to the EL1 physical
+	 * timer/counter if offsetting isn't requested on a non-ECV system.
+	 */
+	if (ptimer_emulation_required(vcpu))
+		val &= ~mask;
+	else
+		val |= mask;
+
 	write_sysreg(val, cnthctl_el2);
 }
 
@@ -1434,9 +1446,6 @@ static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
 	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
 	u64 offset;
 
-	if (!cpus_have_final_cap(ARM64_HAS_ECV2))
-		return -ENXIO;
-
 	if (get_user(offset, uaddr))
 		return -EFAULT;
 
@@ -1485,9 +1494,6 @@ static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
 	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
 	u64 offset;
 
-	if (!cpus_have_final_cap(ARM64_HAS_ECV2))
-		return -ENXIO;
-
 	offset = timer_get_offset(vcpu_ptimer(vcpu));
 	return put_user(offset, uaddr);
 }
@@ -1511,11 +1517,8 @@ int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	switch (attr->attr) {
 	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
 	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
-		return 0;
 	case KVM_ARM_VCPU_TIMER_PHYS_OFFSET:
-		if (cpus_have_final_cap(ARM64_HAS_ECV2))
-			return 0;
-		break;
+		return 0;
 	}
 
 	return -ENXIO;
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e4a2f295a394..71dd613438c2 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -15,6 +15,7 @@
 #include <linux/jump_label.h>
 #include <uapi/linux/psci.h>
 
+#include <kvm/arm_arch_timer.h>
 #include <kvm/arm_psci.h>
 
 #include <asm/barrier.h>
@@ -405,6 +406,34 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
 	return true;
 }
 
+static inline u64 __timer_read_cntpct(struct kvm_vcpu *vcpu)
+{
+	return __arch_counter_get_cntpct() - vcpu_ptimer(vcpu)->host_offset;
+}
+
+static inline bool __hyp_handle_counter(struct kvm_vcpu *vcpu)
+{
+	u32 sysreg;
+	int rt;
+	u64 rv;
+
+	if (cpus_have_final_cap(ARM64_HAS_ECV2))
+		return false;
+
+	if (kvm_vcpu_trap_get_class(vcpu) != ESR_ELx_EC_SYS64)
+		return false;
+
+	sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
+	if (sysreg != SYS_CNTPCT_EL0 && sysreg != SYS_CNTPCTSS_EL0)
+		return false;
+
+	rt = kvm_vcpu_sys_get_rt(vcpu);
+	rv = __timer_read_cntpct(vcpu);
+	vcpu_set_reg(vcpu, rt, rv);
+	__kvm_skip_instr(vcpu);
+	return true;
+}
+
 /*
  * Return true when we were able to fixup the guest exit and should return to
  * the guest, false when we should restore the host state and return to the
@@ -439,6 +468,9 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	if (*exit_code != ARM_EXCEPTION_TRAP)
 		goto exit;
 
+	if (__hyp_handle_counter(vcpu))
+		goto guest;
+
 	if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) &&
 	    kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 &&
 	    handle_tx2_tvm(vcpu))
diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
index e98a949f5227..8c19cd42d445 100644
--- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
@@ -46,12 +46,19 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
 
 	/*
 	 * Disallow physical timer access for the guest
-	 * Physical counter access is allowed
 	 */
 	val = read_sysreg(cnthctl_el2);
 	if (cpus_have_final_cap(ARM64_HAS_ECV2))
 		val |= CNTHCTL_ECV;
 	val &= ~CNTHCTL_EL1PCEN;
-	val |= CNTHCTL_EL1PCTEN;
+
+	/*
+	 * Disallow physical counter access for the guest if offsetting is
+	 * requested on a non-ECV system.
+	 */
+	if (ptimer_emulation_required(vcpu))
+		val &= ~CNTHCTL_EL1PCTEN;
+	else
+		val |= CNTHCTL_EL1PCTEN;
 	write_sysreg(val, cnthctl_el2);
 }
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 254653b42da0..13b72b5ba169 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -96,6 +96,9 @@ bool kvm_arch_timer_get_input_level(int vintid);
 
 #define arch_timer_ctx_index(ctx)	((ctx) - vcpu_timer((ctx)->vcpu)->timers)
 
+#define ptimer_emulation_required(v)	\
+	(!cpus_have_final_cap(ARM64_HAS_ECV2) && vcpu_ptimer(v)->host_offset)
+
 u64 kvm_arm_timer_read_sysreg(struct kvm_vcpu *vcpu,
 			      enum kvm_arch_timers tmr,
 			      enum kvm_arch_timer_regs treg);
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:37 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:37 +0000
Subject: [PATCH v7 0/9] selftests: KVM: Test offset-based counter controls
Message-ID: <20210816001246.3067312-1-oupton@google.com>

This series implements new tests for the x86 and arm64 counter migration
changes that I've mailed out. These are sent separately as a dependent
change since there are cross-arch dependencies here.

Patch 1 yanks the pvclock headers into the tools/ directory so we can
make use of them within a KVM selftest guest.

Patch 2 tests the new capabilities of the KVM_*_CLOCK ioctls, ensuring
that the kernel accounts for elapsed time when restoring the KVM clock.

Patches 3-4 add some device attribute helpers and clean up some mistakes
in the assertions thereof.

Patch 5 implements a test for the KVM_VCPU_TSC_OFFSET attribute,
asserting that manipulation of the offset results in correct TSC values
within the guest.

Patch 6 adds a helper to check if KVM supports a given register in the
KVM_*_REG ioctls.

Patch 7 adds basic arm64 support to the counter offset test, checking
that the virtual counter-timer offset works correctly. Patch 8 does the
same for the physical counter-timer offset.

Patch 9 adds a benchmark for physical counter offsetting, since most
implementations available right now will rely on emulation.

This series applies cleanly to kvm/queue at the following commit:

3e0b8bd99ab ("KVM: MMU: change tracepoints arguments to kvm_page_fault")

Tests were ran against the respective architecture changes on the
following systems:

 - Haswell (x86)
 - Ampere Mt. Jade (non-ECV, nVHE and VHE)
 - ARM Base RevC FVP (ECV, nVHE and VHE)

*NOTE*: Though this tests changes between both x86 and arm64, these
tests check for capabilities and skip if missing, so its OK if they're
merged in trees that lack the patches for both architectures.

v6: https://lore.kernel.org/r/20210804085819.846610-1-oupton at google.com

v6 -> v7:
 - adapted to UAPI renaming for physical counter offsetting on arm64

Oliver Upton (9):
  tools: arch: x86: pull in pvclock headers
  selftests: KVM: Add test for KVM_{GET,SET}_CLOCK
  selftests: KVM: Fix kvm device helper ioctl assertions
  selftests: KVM: Add helpers for vCPU device attributes
  selftests: KVM: Introduce system counter offset test
  selftests: KVM: Add helper to check for register presence
  selftests: KVM: Add support for aarch64 to system_counter_offset_test
  selftests: KVM: Test physical counter offsetting
  selftests: KVM: Add counter emulation benchmark

 tools/arch/x86/include/asm/pvclock-abi.h      |  48 ++++
 tools/arch/x86/include/asm/pvclock.h          | 103 +++++++++
 tools/testing/selftests/kvm/.gitignore        |   3 +
 tools/testing/selftests/kvm/Makefile          |   4 +
 .../kvm/aarch64/counter_emulation_benchmark.c | 207 +++++++++++++++++
 .../selftests/kvm/include/aarch64/processor.h |  24 ++
 .../testing/selftests/kvm/include/kvm_util.h  |  13 ++
 tools/testing/selftests/kvm/lib/kvm_util.c    |  63 +++++-
 .../kvm/system_counter_offset_test.c          | 211 ++++++++++++++++++
 .../selftests/kvm/x86_64/kvm_clock_test.c     | 204 +++++++++++++++++
 10 files changed, 877 insertions(+), 3 deletions(-)
 create mode 100644 tools/arch/x86/include/asm/pvclock-abi.h
 create mode 100644 tools/arch/x86/include/asm/pvclock.h
 create mode 100644 tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
 create mode 100644 tools/testing/selftests/kvm/system_counter_offset_test.c
 create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_clock_test.c

-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:38 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:38 +0000
Subject: [PATCH v7 1/9] tools: arch: x86: pull in pvclock headers
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-2-oupton@google.com>

Copy over approximately clean versions of the pvclock headers into
tools. Reconcile headers/symbols missing in tools that are unneeded.

Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/arch/x86/include/asm/pvclock-abi.h |  48 +++++++++++
 tools/arch/x86/include/asm/pvclock.h     | 103 +++++++++++++++++++++++
 2 files changed, 151 insertions(+)
 create mode 100644 tools/arch/x86/include/asm/pvclock-abi.h
 create mode 100644 tools/arch/x86/include/asm/pvclock.h

diff --git a/tools/arch/x86/include/asm/pvclock-abi.h b/tools/arch/x86/include/asm/pvclock-abi.h
new file mode 100644
index 000000000000..1436226efe3e
--- /dev/null
+++ b/tools/arch/x86/include/asm/pvclock-abi.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_PVCLOCK_ABI_H
+#define _ASM_X86_PVCLOCK_ABI_H
+#ifndef __ASSEMBLY__
+
+/*
+ * These structs MUST NOT be changed.
+ * They are the ABI between hypervisor and guest OS.
+ * Both Xen and KVM are using this.
+ *
+ * pvclock_vcpu_time_info holds the system time and the tsc timestamp
+ * of the last update. So the guest can use the tsc delta to get a
+ * more precise system time.  There is one per virtual cpu.
+ *
+ * pvclock_wall_clock references the point in time when the system
+ * time was zero (usually boot time), thus the guest calculates the
+ * current wall clock by adding the system time.
+ *
+ * Protocol for the "version" fields is: hypervisor raises it (making
+ * it uneven) before it starts updating the fields and raises it again
+ * (making it even) when it is done.  Thus the guest can make sure the
+ * time values it got are consistent by checking the version before
+ * and after reading them.
+ */
+
+struct pvclock_vcpu_time_info {
+	u32   version;
+	u32   pad0;
+	u64   tsc_timestamp;
+	u64   system_time;
+	u32   tsc_to_system_mul;
+	s8    tsc_shift;
+	u8    flags;
+	u8    pad[2];
+} __attribute__((__packed__)); /* 32 bytes */
+
+struct pvclock_wall_clock {
+	u32   version;
+	u32   sec;
+	u32   nsec;
+} __attribute__((__packed__));
+
+#define PVCLOCK_TSC_STABLE_BIT	(1 << 0)
+#define PVCLOCK_GUEST_STOPPED	(1 << 1)
+/* PVCLOCK_COUNTS_FROM_ZERO broke ABI and can't be used anymore. */
+#define PVCLOCK_COUNTS_FROM_ZERO (1 << 2)
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_PVCLOCK_ABI_H */
diff --git a/tools/arch/x86/include/asm/pvclock.h b/tools/arch/x86/include/asm/pvclock.h
new file mode 100644
index 000000000000..2628f9a6330b
--- /dev/null
+++ b/tools/arch/x86/include/asm/pvclock.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_PVCLOCK_H
+#define _ASM_X86_PVCLOCK_H
+
+#include <asm/barrier.h>
+#include <asm/pvclock-abi.h>
+
+/* some helper functions for xen and kvm pv clock sources */
+u64 pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
+u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src);
+void pvclock_set_flags(u8 flags);
+unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
+void pvclock_resume(void);
+
+void pvclock_touch_watchdogs(void);
+
+static __always_inline
+unsigned pvclock_read_begin(const struct pvclock_vcpu_time_info *src)
+{
+	unsigned version = src->version & ~1;
+	/* Make sure that the version is read before the data. */
+	rmb();
+	return version;
+}
+
+static __always_inline
+bool pvclock_read_retry(const struct pvclock_vcpu_time_info *src,
+			unsigned version)
+{
+	/* Make sure that the version is re-read after the data. */
+	rmb();
+	return version != src->version;
+}
+
+/*
+ * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
+ * yielding a 64-bit result.
+ */
+static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
+{
+	u64 product;
+#ifdef __i386__
+	u32 tmp1, tmp2;
+#else
+	unsigned long tmp;
+#endif
+
+	if (shift < 0)
+		delta >>= -shift;
+	else
+		delta <<= shift;
+
+#ifdef __i386__
+	__asm__ (
+		"mul  %5       ; "
+		"mov  %4,%%eax ; "
+		"mov  %%edx,%4 ; "
+		"mul  %5       ; "
+		"xor  %5,%5    ; "
+		"add  %4,%%eax ; "
+		"adc  %5,%%edx ; "
+		: "=A" (product), "=r" (tmp1), "=r" (tmp2)
+		: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
+#elif defined(__x86_64__)
+	__asm__ (
+		"mulq %[mul_frac] ; shrd $32, %[hi], %[lo]"
+		: [lo]"=a"(product),
+		  [hi]"=d"(tmp)
+		: "0"(delta),
+		  [mul_frac]"rm"((u64)mul_frac));
+#else
+#error implement me!
+#endif
+
+	return product;
+}
+
+static __always_inline
+u64 __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, u64 tsc)
+{
+	u64 delta = tsc - src->tsc_timestamp;
+	u64 offset = pvclock_scale_delta(delta, src->tsc_to_system_mul,
+					     src->tsc_shift);
+	return src->system_time + offset;
+}
+
+struct pvclock_vsyscall_time_info {
+	struct pvclock_vcpu_time_info pvti;
+} __attribute__((__aligned__(64)));
+
+#define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info)
+
+#ifdef CONFIG_PARAVIRT_CLOCK
+void pvclock_set_pvti_cpu0_va(struct pvclock_vsyscall_time_info *pvti);
+struct pvclock_vsyscall_time_info *pvclock_get_pvti_cpu0_va(void);
+#else
+static inline struct pvclock_vsyscall_time_info *pvclock_get_pvti_cpu0_va(void)
+{
+	return NULL;
+}
+#endif
+
+#endif /* _ASM_X86_PVCLOCK_H */
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:39 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:39 +0000
Subject: [PATCH v7 2/9] selftests: KVM: Add test for KVM_{GET,SET}_CLOCK
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-3-oupton@google.com>

Add a selftest for the new KVM clock UAPI that was introduced. Ensure
that the KVM clock is consistent between userspace and the guest, and
that the difference in realtime will only ever cause the KVM clock to
advance forward.

Cc: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../testing/selftests/kvm/include/kvm_util.h  |   2 +
 .../selftests/kvm/x86_64/kvm_clock_test.c     | 204 ++++++++++++++++++
 4 files changed, 208 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/x86_64/kvm_clock_test.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 0709af0144c8..06268d6b9aca 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -11,6 +11,7 @@
 /x86_64/emulator_error_test
 /x86_64/get_cpuid_test
 /x86_64/get_msr_index_features
+/x86_64/kvm_clock_test
 /x86_64/kvm_pv_test
 /x86_64/hyperv_clock
 /x86_64/hyperv_cpuid
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 5832f510a16c..3b09133e84a4 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -46,6 +46,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/get_cpuid_test
 TEST_GEN_PROGS_x86_64 += x86_64/hyperv_clock
 TEST_GEN_PROGS_x86_64 += x86_64/hyperv_cpuid
 TEST_GEN_PROGS_x86_64 += x86_64/hyperv_features
+TEST_GEN_PROGS_x86_64 += x86_64/kvm_clock_test
 TEST_GEN_PROGS_x86_64 += x86_64/kvm_pv_test
 TEST_GEN_PROGS_x86_64 += x86_64/mmio_warning_test
 TEST_GEN_PROGS_x86_64 += x86_64/mmu_role_test
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 010b59b13917..a8ac5d52e17b 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -19,6 +19,8 @@
 #define KVM_DEV_PATH "/dev/kvm"
 #define KVM_MAX_VCPUS 512
 
+#define NSEC_PER_SEC 1000000000L
+
 /*
  * Callers of kvm_util only have an incomplete/opaque description of the
  * structure kvm_util is using to maintain the state of a VM.
diff --git a/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c b/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
new file mode 100644
index 000000000000..e0dcc27ae9f1
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86_64/kvm_clock_test.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021, Google LLC.
+ *
+ * Tests for adjusting the KVM clock from userspace
+ */
+#include <asm/kvm_para.h>
+#include <asm/pvclock.h>
+#include <asm/pvclock-abi.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+
+#define VCPU_ID 0
+
+struct test_case {
+	uint64_t kvmclock_base;
+	int64_t realtime_offset;
+};
+
+static struct test_case test_cases[] = {
+	{ .kvmclock_base = 0 },
+	{ .kvmclock_base = 180 * NSEC_PER_SEC },
+	{ .kvmclock_base = 0, .realtime_offset = -180 * NSEC_PER_SEC },
+	{ .kvmclock_base = 0, .realtime_offset = 180 * NSEC_PER_SEC },
+};
+
+#define GUEST_SYNC_CLOCK(__stage, __val)			\
+		GUEST_SYNC_ARGS(__stage, __val, 0, 0, 0)
+
+static void guest_main(vm_paddr_t pvti_pa, struct pvclock_vcpu_time_info *pvti)
+{
+	int i;
+
+	wrmsr(MSR_KVM_SYSTEM_TIME_NEW, pvti_pa | KVM_MSR_ENABLED);
+	for (i = 0; i < ARRAY_SIZE(test_cases); i++)
+		GUEST_SYNC_CLOCK(i, __pvclock_read_cycles(pvti, rdtsc()));
+}
+
+#define EXPECTED_FLAGS (KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC)
+
+static inline void assert_flags(struct kvm_clock_data *data)
+{
+	TEST_ASSERT((data->flags & EXPECTED_FLAGS) == EXPECTED_FLAGS,
+		    "unexpected clock data flags: %x (want set: %x)",
+		    data->flags, EXPECTED_FLAGS);
+}
+
+static void handle_sync(struct ucall *uc, struct kvm_clock_data *start,
+			struct kvm_clock_data *end)
+{
+	uint64_t obs, exp_lo, exp_hi;
+
+	obs = uc->args[2];
+	exp_lo = start->clock;
+	exp_hi = end->clock;
+
+	assert_flags(start);
+	assert_flags(end);
+
+	TEST_ASSERT(exp_lo <= obs && obs <= exp_hi,
+		    "unexpected kvm-clock value: %"PRIu64" expected range: [%"PRIu64", %"PRIu64"]",
+		    obs, exp_lo, exp_hi);
+
+	pr_info("kvm-clock value: %"PRIu64" expected range [%"PRIu64", %"PRIu64"]\n",
+		obs, exp_lo, exp_hi);
+}
+
+static void handle_abort(struct ucall *uc)
+{
+	TEST_FAIL("%s at %s:%ld", (const char *)uc->args[0],
+		  __FILE__, uc->args[1]);
+}
+
+static void setup_clock(struct kvm_vm *vm, struct test_case *test_case)
+{
+	struct kvm_clock_data data;
+
+	memset(&data, 0, sizeof(data));
+
+	data.clock = test_case->kvmclock_base;
+	if (test_case->realtime_offset) {
+		struct timespec ts;
+		int r;
+
+		data.flags |= KVM_CLOCK_REALTIME;
+		do {
+			r = clock_gettime(CLOCK_REALTIME, &ts);
+			if (!r)
+				break;
+		} while (errno == EINTR);
+
+		TEST_ASSERT(!r, "clock_gettime() failed: %d\n", r);
+
+		data.realtime = ts.tv_sec * NSEC_PER_SEC;
+		data.realtime += ts.tv_nsec;
+		data.realtime += test_case->realtime_offset;
+	}
+
+	vm_ioctl(vm, KVM_SET_CLOCK, &data);
+}
+
+static void enter_guest(struct kvm_vm *vm)
+{
+	struct kvm_clock_data start, end;
+	struct kvm_run *run;
+	struct ucall uc;
+	int i, r;
+
+	run = vcpu_state(vm, VCPU_ID);
+
+	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
+		setup_clock(vm, &test_cases[i]);
+
+		vm_ioctl(vm, KVM_GET_CLOCK, &start);
+
+		r = _vcpu_run(vm, VCPU_ID);
+		vm_ioctl(vm, KVM_GET_CLOCK, &end);
+
+		TEST_ASSERT(!r, "vcpu_run failed: %d\n", r);
+		TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
+			    "unexpected exit reason: %u (%s)",
+			    run->exit_reason, exit_reason_str(run->exit_reason));
+
+		switch (get_ucall(vm, VCPU_ID, &uc)) {
+		case UCALL_SYNC:
+			handle_sync(&uc, &start, &end);
+			break;
+		case UCALL_ABORT:
+			handle_abort(&uc);
+			return;
+		default:
+			TEST_ASSERT(0, "unhandled ucall: %ld\n",
+				    get_ucall(vm, VCPU_ID, &uc));
+		}
+	}
+}
+
+#define CLOCKSOURCE_PATH "/sys/devices/system/clocksource/clocksource0/current_clocksource"
+
+static void check_clocksource(void)
+{
+	char *clk_name;
+	struct stat st;
+	FILE *fp;
+
+	fp = fopen(CLOCKSOURCE_PATH, "r");
+	if (!fp) {
+		pr_info("failed to open clocksource file: %d; assuming TSC.\n",
+			errno);
+		return;
+	}
+
+	if (fstat(fileno(fp), &st)) {
+		pr_info("failed to stat clocksource file: %d; assuming TSC.\n",
+			errno);
+		goto out;
+	}
+
+	clk_name = malloc(st.st_size);
+	TEST_ASSERT(clk_name, "failed to allocate buffer to read file\n");
+
+	if (!fgets(clk_name, st.st_size, fp)) {
+		pr_info("failed to read clocksource file: %d; assuming TSC.\n",
+			ferror(fp));
+		goto out;
+	}
+
+	TEST_ASSERT(!strncmp(clk_name, "tsc\n", st.st_size),
+		    "clocksource not supported: %s", clk_name);
+out:
+	fclose(fp);
+}
+
+int main(void)
+{
+	vm_vaddr_t pvti_gva;
+	vm_paddr_t pvti_gpa;
+	struct kvm_vm *vm;
+	int flags;
+
+	flags = kvm_check_cap(KVM_CAP_ADJUST_CLOCK);
+	if (!(flags & KVM_CLOCK_REALTIME)) {
+		print_skip("KVM_CLOCK_REALTIME not supported; flags: %x",
+			   flags);
+		exit(KSFT_SKIP);
+	}
+
+	check_clocksource();
+
+	vm = vm_create_default(VCPU_ID, 0, guest_main);
+
+	pvti_gva = vm_vaddr_alloc(vm, getpagesize(), 0x10000);
+	pvti_gpa = addr_gva2gpa(vm, pvti_gva);
+	vcpu_args_set(vm, VCPU_ID, 2, pvti_gpa, pvti_gva);
+
+	enter_guest(vm);
+	kvm_vm_free(vm);
+}
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:41 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:41 +0000
Subject: [PATCH v7 4/9] selftests: KVM: Add helpers for vCPU device attributes
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-5-oupton@google.com>

vCPU file descriptors are abstracted away from test code in KVM
selftests, meaning that tests cannot directly access a vCPU's device
attributes. Add helpers that tests can use to get at vCPU device
attributes.

Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 .../testing/selftests/kvm/include/kvm_util.h  |  9 +++++
 tools/testing/selftests/kvm/lib/kvm_util.c    | 38 +++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index a8ac5d52e17b..1b3ef5757819 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -240,6 +240,15 @@ int _kvm_device_access(int dev_fd, uint32_t group, uint64_t attr,
 int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr,
 		      void *val, bool write);
 
+int _vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			  uint64_t attr);
+int vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			 uint64_t attr);
+int _vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			  uint64_t attr, void *val, bool write);
+int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			 uint64_t attr, void *val, bool write);
+
 const char *exit_reason_str(unsigned int exit_reason);
 
 void virt_pgd_alloc(struct kvm_vm *vm);
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 0ffc2d39c80d..0fe66ca6139a 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -2040,6 +2040,44 @@ int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr,
 	return ret;
 }
 
+int _vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			  uint64_t attr)
+{
+	struct vcpu *vcpu = vcpu_find(vm, vcpuid);
+
+	TEST_ASSERT(vcpu, "nonexistent vcpu id: %d", vcpuid);
+
+	return _kvm_device_check_attr(vcpu->fd, group, attr);
+}
+
+int vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+				 uint64_t attr)
+{
+	int ret = _vcpu_has_device_attr(vm, vcpuid, group, attr);
+
+	TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno);
+	return ret;
+}
+
+int _vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			     uint64_t attr, void *val, bool write)
+{
+	struct vcpu *vcpu = vcpu_find(vm, vcpuid);
+
+	TEST_ASSERT(vcpu, "nonexistent vcpu id: %d", vcpuid);
+
+	return _kvm_device_access(vcpu->fd, group, attr, val, write);
+}
+
+int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group,
+			    uint64_t attr, void *val, bool write)
+{
+	int ret = _vcpu_access_device_attr(vm, vcpuid, group, attr, val, write);
+
+	TEST_ASSERT(!ret, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno);
+	return ret;
+}
+
 /*
  * VM Dump
  *
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:40 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:40 +0000
Subject: [PATCH v7 3/9] selftests: KVM: Fix kvm device helper ioctl assertions
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-4-oupton@google.com>

The KVM_CREATE_DEVICE and KVM_{GET,SET}_DEVICE_ATTR ioctls are defined
to return a value of zero on success. As such, tighten the assertions in
the helper functions to only pass if the return code is zero.

Suggested-by: Andrew Jones <drjones at redhat.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/testing/selftests/kvm/lib/kvm_util.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 10a8ed691c66..0ffc2d39c80d 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1984,7 +1984,7 @@ int kvm_device_check_attr(int dev_fd, uint32_t group, uint64_t attr)
 {
 	int ret = _kvm_device_check_attr(dev_fd, group, attr);
 
-	TEST_ASSERT(ret >= 0, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno);
+	TEST_ASSERT(!ret, "KVM_HAS_DEVICE_ATTR failed, rc: %i errno: %i", ret, errno);
 	return ret;
 }
 
@@ -2008,7 +2008,7 @@ int kvm_create_device(struct kvm_vm *vm, uint64_t type, bool test)
 	ret = _kvm_create_device(vm, type, test, &fd);
 
 	if (!test) {
-		TEST_ASSERT(ret >= 0,
+		TEST_ASSERT(!ret,
 			    "KVM_CREATE_DEVICE IOCTL failed, rc: %i errno: %i", ret, errno);
 		return fd;
 	}
@@ -2036,7 +2036,7 @@ int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr,
 {
 	int ret = _kvm_device_access(dev_fd, group, attr, val, write);
 
-	TEST_ASSERT(ret >= 0, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno);
+	TEST_ASSERT(!ret, "KVM_SET|GET_DEVICE_ATTR IOCTL failed, rc: %i errno: %i", ret, errno);
 	return ret;
 }
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:42 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:42 +0000
Subject: [PATCH v7 5/9] selftests: KVM: Introduce system counter offset test
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-6-oupton@google.com>

Introduce a KVM selftest to verify that userspace manipulation of the
TSC (via the new vCPU attribute) results in the correct behavior within
the guest.

Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/system_counter_offset_test.c          | 132 ++++++++++++++++++
 3 files changed, 134 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/system_counter_offset_test.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 06268d6b9aca..9a73befbd8d6 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -51,3 +51,4 @@
 /set_memory_region_test
 /steal_time
 /kvm_binary_stats_test
+/system_counter_offset_test
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 3b09133e84a4..2cb0a375c7db 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -84,6 +84,7 @@ TEST_GEN_PROGS_x86_64 += memslot_perf_test
 TEST_GEN_PROGS_x86_64 += set_memory_region_test
 TEST_GEN_PROGS_x86_64 += steal_time
 TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
+TEST_GEN_PROGS_x86_64 += system_counter_offset_test
 
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c
new file mode 100644
index 000000000000..b337bbbfa41f
--- /dev/null
+++ b/tools/testing/selftests/kvm/system_counter_offset_test.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021, Google LLC.
+ *
+ * Tests for adjusting the system counter from userspace
+ */
+#include <asm/kvm_para.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+
+#define VCPU_ID 0
+
+#ifdef __x86_64__
+
+struct test_case {
+	uint64_t tsc_offset;
+};
+
+static struct test_case test_cases[] = {
+	{ 0 },
+	{ 180 * NSEC_PER_SEC },
+	{ -180 * NSEC_PER_SEC },
+};
+
+static void check_preconditions(struct kvm_vm *vm)
+{
+	if (!_vcpu_has_device_attr(vm, VCPU_ID, KVM_VCPU_TSC_CTRL, KVM_VCPU_TSC_OFFSET))
+		return;
+
+	print_skip("KVM_VCPU_TSC_OFFSET not supported; skipping test");
+	exit(KSFT_SKIP);
+}
+
+static void setup_system_counter(struct kvm_vm *vm, struct test_case *test)
+{
+	vcpu_access_device_attr(vm, VCPU_ID, KVM_VCPU_TSC_CTRL,
+				KVM_VCPU_TSC_OFFSET, &test->tsc_offset, true);
+}
+
+static uint64_t guest_read_system_counter(struct test_case *test)
+{
+	return rdtsc();
+}
+
+static uint64_t host_read_guest_system_counter(struct test_case *test)
+{
+	return rdtsc() + test->tsc_offset;
+}
+
+#else /* __x86_64__ */
+
+#error test not implemented for this architecture!
+
+#endif
+
+#define GUEST_SYNC_CLOCK(__stage, __val)			\
+		GUEST_SYNC_ARGS(__stage, __val, 0, 0, 0)
+
+static void guest_main(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
+		struct test_case *test = &test_cases[i];
+
+		GUEST_SYNC_CLOCK(i, guest_read_system_counter(test));
+	}
+}
+
+static void handle_sync(struct ucall *uc, uint64_t start, uint64_t end)
+{
+	uint64_t obs = uc->args[2];
+
+	TEST_ASSERT(start <= obs && obs <= end,
+		    "unexpected system counter value: %"PRIu64" expected range: [%"PRIu64", %"PRIu64"]",
+		    obs, start, end);
+
+	pr_info("system counter value: %"PRIu64" expected range [%"PRIu64", %"PRIu64"]\n",
+		obs, start, end);
+}
+
+static void handle_abort(struct ucall *uc)
+{
+	TEST_FAIL("%s at %s:%ld", (const char *)uc->args[0],
+		  __FILE__, uc->args[1]);
+}
+
+static void enter_guest(struct kvm_vm *vm)
+{
+	uint64_t start, end;
+	struct ucall uc;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
+		struct test_case *test = &test_cases[i];
+
+		setup_system_counter(vm, test);
+		start = host_read_guest_system_counter(test);
+		vcpu_run(vm, VCPU_ID);
+		end = host_read_guest_system_counter(test);
+
+		switch (get_ucall(vm, VCPU_ID, &uc)) {
+		case UCALL_SYNC:
+			handle_sync(&uc, start, end);
+			break;
+		case UCALL_ABORT:
+			handle_abort(&uc);
+			return;
+		default:
+			TEST_ASSERT(0, "unhandled ucall %ld\n",
+				    get_ucall(vm, VCPU_ID, &uc));
+		}
+	}
+}
+
+int main(void)
+{
+	struct kvm_vm *vm;
+
+	vm = vm_create_default(VCPU_ID, 0, guest_main);
+	check_preconditions(vm);
+	ucall_init(vm, NULL);
+
+	enter_guest(vm);
+	kvm_vm_free(vm);
+}
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:43 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:43 +0000
Subject: [PATCH v7 6/9] selftests: KVM: Add helper to check for register
 presence
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-7-oupton@google.com>

The KVM_GET_REG_LIST vCPU ioctl returns a list of supported registers
for a given vCPU. Add a helper to check if a register exists in the list
of supported registers.

Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
---
 .../testing/selftests/kvm/include/kvm_util.h  |  2 ++
 tools/testing/selftests/kvm/lib/kvm_util.c    | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 1b3ef5757819..077082dd2ca7 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -215,6 +215,8 @@ void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid,
 		  struct kvm_fpu *fpu);
 void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid,
 		  struct kvm_fpu *fpu);
+
+bool vcpu_has_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t reg_id);
 void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
 void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
 #ifdef __KVM_HAVE_VCPU_EVENTS
diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
index 0fe66ca6139a..a5801d4ed37d 100644
--- a/tools/testing/selftests/kvm/lib/kvm_util.c
+++ b/tools/testing/selftests/kvm/lib/kvm_util.c
@@ -1823,6 +1823,25 @@ void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu)
 		    ret, errno, strerror(errno));
 }
 
+bool vcpu_has_reg(struct kvm_vm *vm, uint32_t vcpuid, uint64_t reg_id)
+{
+	struct kvm_reg_list *list;
+	bool ret = false;
+	uint64_t i;
+
+	list = vcpu_get_reg_list(vm, vcpuid);
+
+	for (i = 0; i < list->n; i++) {
+		if (list->reg[i] == reg_id) {
+			ret = true;
+			break;
+		}
+	}
+
+	free(list);
+	return ret;
+}
+
 void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg)
 {
 	int ret;
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:44 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:44 +0000
Subject: [PATCH v7 7/9] selftests: KVM: Add support for aarch64 to
 system_counter_offset_test
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-8-oupton@google.com>

KVM/arm64 now allows userspace to adjust the guest virtual counter-timer
via a vCPU register. Test that changes to the virtual counter-timer
offset result in the correct view being presented to the guest.

Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
---
 tools/testing/selftests/kvm/Makefile          |  1 +
 .../selftests/kvm/include/aarch64/processor.h | 12 ++++
 .../kvm/system_counter_offset_test.c          | 56 ++++++++++++++++++-
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 2cb0a375c7db..a74d4876c69c 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -97,6 +97,7 @@ TEST_GEN_PROGS_aarch64 += kvm_page_table_test
 TEST_GEN_PROGS_aarch64 += set_memory_region_test
 TEST_GEN_PROGS_aarch64 += steal_time
 TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
+TEST_GEN_PROGS_aarch64 += system_counter_offset_test
 
 TEST_GEN_PROGS_s390x = s390x/memop
 TEST_GEN_PROGS_s390x += s390x/resets
diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index 27dc5c2e56b9..3168cdbae6ee 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -129,4 +129,16 @@ void vm_install_sync_handler(struct kvm_vm *vm,
 
 #define isb()	asm volatile("isb" : : : "memory")
 
+static inline uint64_t read_cntvct_ordered(void)
+{
+	uint64_t r;
+
+	__asm__ __volatile__("isb\n\t"
+			     "mrs %0, cntvct_el0\n\t"
+			     "isb\n\t"
+			     : "=r"(r));
+
+	return r;
+}
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c
index b337bbbfa41f..ac933db83d03 100644
--- a/tools/testing/selftests/kvm/system_counter_offset_test.c
+++ b/tools/testing/selftests/kvm/system_counter_offset_test.c
@@ -53,7 +53,61 @@ static uint64_t host_read_guest_system_counter(struct test_case *test)
 	return rdtsc() + test->tsc_offset;
 }
 
-#else /* __x86_64__ */
+#elif __aarch64__ /* __x86_64__ */
+
+enum arch_counter {
+	VIRTUAL,
+};
+
+struct test_case {
+	enum arch_counter counter;
+	uint64_t offset;
+};
+
+static struct test_case test_cases[] = {
+	{ .counter = VIRTUAL, .offset = 0 },
+	{ .counter = VIRTUAL, .offset = 180 * NSEC_PER_SEC },
+	{ .counter = VIRTUAL, .offset = -180 * NSEC_PER_SEC },
+};
+
+static void check_preconditions(struct kvm_vm *vm)
+{
+	if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET))
+		return;
+
+	print_skip("KVM_REG_ARM_TIMER_OFFSET not supported; skipping test");
+	exit(KSFT_SKIP);
+}
+
+static void setup_system_counter(struct kvm_vm *vm, struct test_case *test)
+{
+	struct kvm_one_reg reg = {
+		.id = KVM_REG_ARM_TIMER_OFFSET,
+		.addr = (__u64)&test->offset,
+	};
+
+	vcpu_set_reg(vm, VCPU_ID, &reg);
+}
+
+static uint64_t guest_read_system_counter(struct test_case *test)
+{
+	switch (test->counter) {
+	case VIRTUAL:
+		return read_cntvct_ordered();
+	default:
+		GUEST_ASSERT(0);
+	}
+
+	/* unreachable */
+	return 0;
+}
+
+static uint64_t host_read_guest_system_counter(struct test_case *test)
+{
+	return read_cntvct_ordered() - test->offset;
+}
+
+#else /* __aarch64__ */
 
 #error test not implemented for this architecture!
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:45 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:45 +0000
Subject: [PATCH v7 8/9] selftests: KVM: Test physical counter offsetting
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-9-oupton@google.com>

Test that userspace adjustment of the guest physical counter-timer
results in the correct view within the guest.

Cc: Andrew Jones <drjones at redhat.com>
Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
Change-Id: I8a26e88df5c5bc03740c7f980c405b4d21b28be8
---
 .../selftests/kvm/include/aarch64/processor.h | 12 +++++++
 .../kvm/system_counter_offset_test.c          | 31 +++++++++++++++++--
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h
index 3168cdbae6ee..7f53d90e9512 100644
--- a/tools/testing/selftests/kvm/include/aarch64/processor.h
+++ b/tools/testing/selftests/kvm/include/aarch64/processor.h
@@ -141,4 +141,16 @@ static inline uint64_t read_cntvct_ordered(void)
 	return r;
 }
 
+static inline uint64_t read_cntpct_ordered(void)
+{
+	uint64_t r;
+
+	__asm__ __volatile__("isb\n\t"
+			     "mrs %0, cntpct_el0\n\t"
+			     "isb\n\t"
+			     : "=r"(r));
+
+	return r;
+}
+
 #endif /* SELFTEST_KVM_PROCESSOR_H */
diff --git a/tools/testing/selftests/kvm/system_counter_offset_test.c b/tools/testing/selftests/kvm/system_counter_offset_test.c
index ac933db83d03..2b8b4b84a273 100644
--- a/tools/testing/selftests/kvm/system_counter_offset_test.c
+++ b/tools/testing/selftests/kvm/system_counter_offset_test.c
@@ -57,6 +57,9 @@ static uint64_t host_read_guest_system_counter(struct test_case *test)
 
 enum arch_counter {
 	VIRTUAL,
+	PHYSICAL,
+	/* offset physical, read virtual */
+	PHYSICAL_READ_VIRTUAL,
 };
 
 struct test_case {
@@ -68,32 +71,54 @@ static struct test_case test_cases[] = {
 	{ .counter = VIRTUAL, .offset = 0 },
 	{ .counter = VIRTUAL, .offset = 180 * NSEC_PER_SEC },
 	{ .counter = VIRTUAL, .offset = -180 * NSEC_PER_SEC },
+	{ .counter = PHYSICAL, .offset = 0 },
+	{ .counter = PHYSICAL, .offset = 180 * NSEC_PER_SEC },
+	{ .counter = PHYSICAL, .offset = -180 * NSEC_PER_SEC },
+	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = 0 },
+	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = 180 * NSEC_PER_SEC },
+	{ .counter = PHYSICAL_READ_VIRTUAL, .offset = -180 * NSEC_PER_SEC },
 };
 
 static void check_preconditions(struct kvm_vm *vm)
 {
-	if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET))
+	if (vcpu_has_reg(vm, VCPU_ID, KVM_REG_ARM_TIMER_OFFSET) &&
+	    !_vcpu_has_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
+				   KVM_ARM_VCPU_TIMER_PHYS_OFFSET))
 		return;
 
-	print_skip("KVM_REG_ARM_TIMER_OFFSET not supported; skipping test");
+	print_skip("KVM_REG_ARM_TIMER_OFFSET|KVM_ARM_VCPU_TIMER_PHYS_OFFSET not supported; skipping test");
 	exit(KSFT_SKIP);
 }
 
 static void setup_system_counter(struct kvm_vm *vm, struct test_case *test)
 {
+	uint64_t cntvoff, cntpoff;
 	struct kvm_one_reg reg = {
 		.id = KVM_REG_ARM_TIMER_OFFSET,
-		.addr = (__u64)&test->offset,
+		.addr = (__u64)&cntvoff,
 	};
 
+	if (test->counter == VIRTUAL) {
+		cntvoff = test->offset;
+		cntpoff = 0;
+	} else {
+		cntvoff = 0;
+		cntpoff = test->offset;
+	}
+
 	vcpu_set_reg(vm, VCPU_ID, &reg);
+	vcpu_access_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
+				KVM_ARM_VCPU_TIMER_PHYS_OFFSET, &cntpoff, true);
 }
 
 static uint64_t guest_read_system_counter(struct test_case *test)
 {
 	switch (test->counter) {
 	case VIRTUAL:
+	case PHYSICAL_READ_VIRTUAL:
 		return read_cntvct_ordered();
+	case PHYSICAL:
+		return read_cntpct_ordered();
 	default:
 		GUEST_ASSERT(0);
 	}
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From oupton at google.com  Sun Aug 15 17:12:46 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 16 Aug 2021 00:12:46 +0000
Subject: [PATCH v7 9/9] selftests: KVM: Add counter emulation benchmark
In-Reply-To: <20210816001246.3067312-1-oupton@google.com>
References: <20210816001246.3067312-1-oupton@google.com>
Message-ID: <20210816001246.3067312-10-oupton@google.com>

Add a test case for counter emulation on arm64. A side effect of how KVM
handles physical counter offsetting on non-ECV systems is that the
virtual counter will always hit hardware and the physical could be
emulated. Force emulation by writing a nonzero offset to the physical
counter and compare the elapsed cycles to a direct read of the hardware
register.

Reviewed-by: Ricardo Koller <ricarkol at google.com>
Signed-off-by: Oliver Upton <oupton at google.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
Change-Id: Iec9ed89346c3f65b7f9067a7e96a9d94afbab526
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../kvm/aarch64/counter_emulation_benchmark.c | 207 ++++++++++++++++++
 3 files changed, 209 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 9a73befbd8d6..0f3d842b82d6 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+/aarch64/counter_emulation_benchmark
 /aarch64/debug-exceptions
 /aarch64/get-reg-list
 /aarch64/vgic_init
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index a74d4876c69c..3652b39e02b8 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -86,6 +86,7 @@ TEST_GEN_PROGS_x86_64 += steal_time
 TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
 TEST_GEN_PROGS_x86_64 += system_counter_offset_test
 
+TEST_GEN_PROGS_aarch64 += aarch64/counter_emulation_benchmark
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
 TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
diff --git a/tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c b/tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
new file mode 100644
index 000000000000..48dbd9459102
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/counter_emulation_benchmark.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * counter_emulation_benchmark.c -- test to measure the effects of counter
+ * emulation on guest reads of the physical counter.
+ *
+ * Copyright (c) 2021, Google LLC.
+ */
+
+#define _GNU_SOURCE
+#include <asm/kvm.h>
+#include <linux/kvm.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "kvm_util.h"
+#include "processor.h"
+#include "test_util.h"
+
+#define VCPU_ID 0
+
+static struct counter_values {
+	uint64_t cntvct_start;
+	uint64_t cntpct;
+	uint64_t cntvct_end;
+} counter_values;
+
+static uint64_t nr_iterations = 1000;
+
+static void do_test(void)
+{
+	/*
+	 * Open-coded approach instead of using helper methods to keep a tight
+	 * interval around the physical counter read.
+	 */
+	asm volatile("isb\n\t"
+		     "mrs %[cntvct_start], cntvct_el0\n\t"
+		     "isb\n\t"
+		     "mrs %[cntpct], cntpct_el0\n\t"
+		     "isb\n\t"
+		     "mrs %[cntvct_end], cntvct_el0\n\t"
+		     "isb\n\t"
+		     : [cntvct_start] "=r"(counter_values.cntvct_start),
+		     [cntpct] "=r"(counter_values.cntpct),
+		     [cntvct_end] "=r"(counter_values.cntvct_end));
+}
+
+static void guest_main(void)
+{
+	int i;
+
+	for (i = 0; i < nr_iterations; i++) {
+		do_test();
+		GUEST_SYNC(i);
+	}
+
+	for (i = 0; i < nr_iterations; i++) {
+		do_test();
+		GUEST_SYNC(i);
+	}
+}
+
+static void enter_guest(struct kvm_vm *vm)
+{
+	struct ucall uc;
+
+	vcpu_ioctl(vm, VCPU_ID, KVM_RUN, NULL);
+
+	switch (get_ucall(vm, VCPU_ID, &uc)) {
+	case UCALL_SYNC:
+		break;
+	case UCALL_ABORT:
+		TEST_ASSERT(false, "%s at %s:%ld", (const char *)uc.args[0],
+			    __FILE__, uc.args[1]);
+		break;
+	default:
+		TEST_ASSERT(false, "unexpected exit: %s",
+			    exit_reason_str(vcpu_state(vm, VCPU_ID)->exit_reason));
+		break;
+	}
+}
+
+static double counter_frequency(void)
+{
+	uint32_t freq;
+
+	asm volatile("mrs %0, cntfrq_el0"
+		     : "=r" (freq));
+
+	return freq / 1000000.0;
+}
+
+static void log_csv(FILE *csv, bool trapped)
+{
+	double freq = counter_frequency();
+
+	fprintf(csv, "%s,%.02f,%lu,%lu,%lu\n",
+		trapped ? "true" : "false", freq,
+		counter_values.cntvct_start,
+		counter_values.cntpct,
+		counter_values.cntvct_end);
+}
+
+static double run_loop(struct kvm_vm *vm, FILE *csv, bool trapped)
+{
+	double avg = 0;
+	int i;
+
+	for (i = 0; i < nr_iterations; i++) {
+		uint64_t delta;
+
+		enter_guest(vm);
+		sync_global_from_guest(vm, counter_values);
+
+		if (csv)
+			log_csv(csv, trapped);
+
+		delta = counter_values.cntvct_end - counter_values.cntvct_start;
+		avg = ((avg * i) + delta) / (i + 1);
+	}
+
+	return avg;
+}
+
+static void setup_counter(struct kvm_vm *vm, uint64_t offset)
+{
+	vcpu_access_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
+				KVM_ARM_VCPU_TIMER_PHYS_OFFSET, &offset,
+				true);
+}
+
+static void run_tests(struct kvm_vm *vm, FILE *csv)
+{
+	double avg_trapped, avg_native, freq;
+
+	freq = counter_frequency();
+
+	if (csv)
+		fputs("trapped,freq_mhz,cntvct_start,cntpct,cntvct_end\n", csv);
+
+	/* no physical offsetting; kvm allows reads of cntpct_el0 */
+	setup_counter(vm, 0);
+	avg_native = run_loop(vm, csv, false);
+
+	/* force emulation of the physical counter */
+	setup_counter(vm, 1);
+	avg_trapped = run_loop(vm, csv, true);
+
+	pr_info("%lu iterations: average cycles (@%.02fMHz) native: %.02f, trapped: %.02f\n",
+		nr_iterations, freq, avg_native, avg_trapped);
+}
+
+static void usage(const char *program_name)
+{
+	fprintf(stderr,
+		"Usage: %s [-h] [-o csv_file] [-n iterations]\n"
+		"  -h prints this message\n"
+		"  -n number of test iterations (default: %lu)\n"
+		"  -o csv file to write data\n",
+		program_name, nr_iterations);
+}
+
+int main(int argc, char **argv)
+{
+	struct kvm_vm *vm;
+	FILE *csv = NULL;
+	int opt;
+
+	while ((opt = getopt(argc, argv, "hn:o:")) != -1) {
+		switch (opt) {
+		case 'o':
+			csv = fopen(optarg, "w");
+			if (!csv) {
+				fprintf(stderr, "failed to open file '%s': %d\n",
+					optarg, errno);
+				exit(1);
+			}
+			break;
+		case 'n':
+			nr_iterations = strtoul(optarg, NULL, 0);
+			break;
+		default:
+			fprintf(stderr, "unrecognized option: '-%c'\n", opt);
+			/* fallthrough */
+		case 'h':
+			usage(argv[0]);
+			exit(1);
+		}
+	}
+
+	vm = vm_create_default(VCPU_ID, 0, guest_main);
+	sync_global_to_guest(vm, nr_iterations);
+	ucall_init(vm, NULL);
+
+	if (_vcpu_has_device_attr(vm, VCPU_ID, KVM_ARM_VCPU_TIMER_CTRL,
+				  KVM_ARM_VCPU_TIMER_PHYS_OFFSET)) {
+		print_skip("KVM_ARM_VCPU_TIMER_PHYS_OFFSET not supported.");
+		exit(KSFT_SKIP);
+	}
+
+	run_tests(vm, csv);
+	kvm_vm_free(vm);
+
+	if (csv)
+		fclose(csv);
+}
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From houlong.wei at mediatek.com  Sun Aug 15 17:46:57 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 08:46:57 +0800
Subject: [PATCH v6 1/9] mtk-mdp: propagate errors from clock_on
In-Reply-To: <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>
Message-ID: <8324f3197f20dfec3e0d7ea8f32bac75b739eea5.camel@mediatek.com>

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> Up until this change, many errors were logged but ignored when
> powering
> on clocks inside mtk_mdp_core. This change tries to do a better job
> at
> propagating errors back to the power management framework.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---

Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>

> (no changes since v1)
[...]

From houlong.wei at mediatek.com  Sun Aug 15 18:05:54 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 09:05:54 +0800
Subject: [PATCH v6 2/9] mtk-mdp: add driver to probe mdp components
In-Reply-To: <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>
Message-ID: <aef8182ffa2142f2c8ed6bda463d3c127530deae.camel@mediatek.com>

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> Broadly, this patch (1) adds a driver for various MTK MDP components
> to
> go alongside the main MTK MDP driver, and (2) hooks them all together
> using the component framework.
> 
> (1) Up until now, the MTK MDP driver controls 8 devices in the device
> tree on its own. When running tests for the hardware video decoder,
> we
> found that the iommus and LARBs were not being properly configured.
> To
> configure them, a driver for each be added to mtk_mdp_comp so that
> mtk_iommu_add_device() can (eventually) be called from
> dma_configure()
> inside really_probe().
> 
> (2) The integration into the component framework allows us to defer
> the
> registration with the v4l2 subsystem until all the MDP-related
> devices
> have been probed, so that the relevant device node does not become
> available until initialization of all the components is complete.
> 
> Some notes about how the component framework has been integrated:
> 
> - The driver for the rdma0 component serves double duty as the
> "master"
>   (aggregate) driver as well as a component driver. This is a non-
> ideal
>   compromise until a better solution is developed. This device is
>   differentiated from the rest by checking for a "mediatek,vpu"
> property
>   in the device node.
> 
> - The list of mdp components remains hard-coded as
> mtk_mdp_comp_dt_ids[]
>   in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
>   mtk_mdp_comp.c. This unfortunate duplication of information is
>   addressed in a following patch in this series.
> 
> - The component driver calls component_add() for each device that is
>   probed.
> 
> - In mtk_mdp_probe (the "master" device), we scan the device tree for
>   any matching nodes against mtk_mdp_comp_dt_ids, and add component
>   matches for them. The match criteria is a matching device node
>   pointer.
> 
> - When the set of components devices that have been probed
> corresponds
>   with the list that is generated by the "master", the callback to
>   mtk_mdp_master_bind() is made, which then calls the component bind
>   functions.
> 
> - Inside mtk_mdp_master_bind(), once all the component bind functions
>   have been called, we can then register our device to the v4l2
>   subsystem.
> 
> - The call to pm_runtime_enable() in the master device is called
> after
>   all the components have been registered by their bind() functions
>   called by mtk_mtp_master_bind(). As a result, the list of
> components
>   will not change while power management callbacks mtk_mdp_suspend()/
>   resume() are accessing the list of components.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
> 

Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>

> (no changes since v1)
> 
[...]

From houlong.wei at mediatek.com  Sun Aug 15 18:10:33 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 09:10:33 +0800
Subject: [PATCH v6 4/9] media: mtk-mdp: don't pm_run_time_get/put for
 master comp in clock_on
In-Reply-To: <20210802220943.v6.4.Ifd87681955689a08cce4c65e72ee5e8c6d09af95@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.4.Ifd87681955689a08cce4c65e72ee5e8c6d09af95@changeid>
Message-ID: <bef757c4a081bfb87aa3b429970e628641bf95a5.camel@mediatek.com>

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> The original intent of commit 86698b9505bbc ("media: mtk-mdp: convert
> mtk_mdp_dev.comp array to list") was to create a list to track all
> the
> MDP components that needed to have their clocks enabled/disabled when
> calling mtk_mdp_comp_clock_on/off. However, there was a bug inside
> mtk_mdp_register_component where the args to a call to list_add were
> swapped. The result is that only one component was added to
> mtk_mdp_dev.comp_list because comp_list was instead being
> repeatedly added to the single element lists headed by each
> mtk_mdp_comp.
> 
> The order of the args to list_add in mtk_mdp_register_component was
> fixed in https://patchwork.kernel.org/patch/11742895/ (Fix Null
> pointer
> dereference when calling list_add).
> 
> Then, as a result of https://patchwork.kernel.org/patch/11530769/
> (mtk-mdp: use pm_runtime in MDP component driver) if all the
> components
> are added to the component list, the mdp "master" / rdma0 component
> ends up having pm_runtime_get_sync() called on it twice recursively:
> 
>     rpm_resume+0x694/0x8f8
>     __pm_runtime_resume+0x7c/0xa0 ***NOTE***
>     mtk_mdp_comp_clock_on+0x48/0x104 [mtk_mdp]
>     mtk_mdp_pm_resume+0x2c/0x44 [mtk_mdp]
>     pm_generic_runtime_resume+0x34/0x48
>     __genpd_runtime_resume+0x6c/0x80
>     genpd_runtime_resume+0x104/0x1ac
>     __rpm_callback+0x120/0x238
>     rpm_callback+0x34/0x8c
>     rpm_resume+0x7a0/0x8f8
>     __pm_runtime_resume+0x7c/0xa0 ***NOTE***
>     mtk_mdp_m2m_start_streaming+0x2c/0x3c [mtk_mdp]
> 
> (The calls to pm_runtime_get_sync are inlined and correspond to the
> calls to __pm_runtime_resume). It is not correct to have
> pm_runtime_get_sync called recursively and the second call will block
> indefinitely.
> 
> As a result of all that, this change factors
> mtk_mdp_comp_clock_on/off
> into mtk_mdp_comp_power_on/off and moves the calls to
> pm_runtime_get/put into the power_on/off functions.
> 
> This change then special-cases the master/rdma0 MDP component and
> does
> these things:
> - the master/rdma0 component is not added to mtk_mdp_dev.comp_list
> - the master/rdma0 component has its clocks (*but not power*) toggled
>   by mtk_mpd_comp_clock_on/off inside mtk_mdp_clock_on/off.
> - the other components have their clocks *and* power toggled with
>   mtk_mdp_comp_power_on/off.
> 
> This change introduces the assumption that mtk_mdp_pm_resume will
> always be called though a callback from pm_runtime_get_sync made on
> the
> master / rdma0 component.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
> 

Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>

> (no changes since v1)
> 
[...]

From houlong.wei at mediatek.com  Sun Aug 15 18:07:42 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 09:07:42 +0800
Subject: [PATCH v6 3/9] mtk-mdp: use pm_runtime in MDP component driver
In-Reply-To: <20210802220943.v6.3.I909f5375d930f5d0cc877128e30e2a67078b674c@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.3.I909f5375d930f5d0cc877128e30e2a67078b674c@changeid>
Message-ID: <ab83cb2c6fd8fa89b72a1cd215e8258c2b4d2c63.camel@mediatek.com>

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> Without this change, the MDP components are not fully integrated into
> the runtime power management subsystem, and the MDP driver does not
> work.
> 
> For each of the component device drivers to be able to call
> pm_runtime_get/put_sync() a pointer to the component's device struct
> had to be added to struct mtk_mdp_comp, set by mtk_mdp_comp_init().
> 
> Note that the dev argument to mtk_mdp_comp_clock_on/off() has been
> removed. Those functions used to be called from the "master" mdp
> driver
> in mtk_mdp_core.c, but the component's device pointer no longer
> corresponds to the mdp master device pointer, which is not the right
> device to pass to pm_runtime_put/get_sync() which we had to add to
> get
> the driver to work properly.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
> 

Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>

> (no changes since v1)
> 
[...]

From houlong.wei at mediatek.com  Sun Aug 15 18:15:07 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 09:15:07 +0800
Subject: [PATCH v6 5/9] mtk-mdp: make mdp driver to be loadable by
 platform_device_register*()
In-Reply-To: <20210802220943.v6.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>
Message-ID: <4d2e4210c74f7fe14d933571df768dc58a1e9266.camel@mediatek.com>

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> Rather than hanging the MDP master component driver off of the rdma0
> device, make it possible too create a "virtual" device by registering
> it with platform_device_register_*() to be probed by the mtk_mdp_core
> driver.
> 
> Broadly, three interdependent things are done by this change:
> - Make it is possible to search for MDP devices in the device tree
>   through the grandparent device's of_node.
> - v4l-related setup is moved into from the mtk_mdp_core driver to the
>   mtk_mdp_comp driver.
> - Presence of a mediatek,vpu property in an MDP component device node
>   is used to determine what device to use when dispatching DMA ops
> from
>   the relevant ioctl, and also do V4L2 initialization in this case.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---

Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>

> Changes in v6:
> - Don't propagate errors from clock_on/off as an afterthought.
> - Split apart modifying mdp driver to be loadable from mmsys from
>   actually loading it from mmsys into two changs to make review
> easier.
> - Update devicetree bindings to reflect no longer needing the
>   mediatek,vpu property in the mdp_rdma0 device node.
> - Some stylistic cleanups.
> 
> Changes in v5:
> - rebase and test on 5.13-next @ e2f74b13dbe6
> 
> Changes in v4:
> - rebase and test on 5.13
> - don't depend on 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873
> 
> Changes in v3:
> - get mdp master from aliases instead of strcmp against of_node->name
> 
> Changes in v2:
> - rebased onto Linux 5.12
> - 100 char line length allowance was utilized in a few places
> - Removal of a redundant dev_err() print at the end of
>   mtk_mdp_comp_init()
> - Instead of printing errors and ignoring them, I've added a patch to
>   correctly propagate them.
> - Use of C style comments.
> - Three additional patches were added to eliminate dependency on the
>   mediatek,vpu property inside the mdp_rdma0 device node.

[...]

From houlong.wei at mediatek.com  Sun Aug 15 18:18:16 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 09:18:16 +0800
Subject: [PATCH v6 6/9] soc: mediatek: mmsys: instantiate mdp virtual
 device from mmsys
In-Reply-To: <20210802220943.v6.6.Ie4214d2cc73ab276dd7c41d4f63c98e011fb42d4@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.6.Ie4214d2cc73ab276dd7c41d4f63c98e011fb42d4@changeid>
Message-ID: <cba6ccf59101225150d0b9f6020753adc22221ed.camel@mediatek.com>

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> A virtual device that is probed by the mtk_mdp_core driver is
> instantiated by the mtk_mmsys driver.
> 
> This better reflects the logical organization of the hardware and
> driver: there are a number of hardware blocks that are used by the
> MDP
> that have no strict hierarchy, and the software driver is responsible
> for driving them properly.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---

Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>

> (no changes since v1)
> 
>  drivers/soc/mediatek/mtk-mmsys.c | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c
> b/drivers/soc/mediatek/mtk-mmsys.c
> index 080660ef11bf..e681029fe804 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -97,6 +97,7 @@ static int mtk_mmsys_probe(struct platform_device
> *pdev)
>  	struct platform_device *clks;
>  	struct platform_device *drm;
>  	struct mtk_mmsys *mmsys;
> +	struct platform_device *mdp;
>  	int ret;
>  
>  	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
> @@ -122,10 +123,27 @@ static int mtk_mmsys_probe(struct
> platform_device *pdev)
>  					    PLATFORM_DEVID_AUTO, NULL,
> 0);
>  	if (IS_ERR(drm)) {
>  		platform_device_unregister(clks);
> -		return PTR_ERR(drm);
> +		ret = PTR_ERR(drm);
> +		goto err_drm;
> +	}
> +
> +	mdp = platform_device_register_data(&pdev->dev, "mtk-mdp",
> +					    PLATFORM_DEVID_AUTO, NULL,
> 0);
> +	if (IS_ERR(mdp)) {
> +		ret = PTR_ERR(mdp);
> +		dev_err(dev, "Failed to register mdp: %d\n", ret);
> +		goto err_mdp;
>  	}
>  
>  	return 0;
> +
> +err_mdp:
> +	platform_device_unregister(drm);
> +
> +err_drm:
> +	platform_device_unregister(clks);
> +
> +	return ret;
>  }
>  
>  static const struct of_device_id of_match_mtk_mmsys[] = {
> -- 
> 2.32.0.554.ge1b32706d8-goog
> 

From nancy.lin at mediatek.com  Sun Aug 15 19:05:04 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 16 Aug 2021 10:05:04 +0800
Subject: [PATCH v2 07/14] soc: mediatek: add mtk-mmsys support for
 mt8195 vdosys1
In-Reply-To: <6c1891ed-178e-b589-1630-93d528276b17@gmail.com>
References: <20210722094551.15255-1-nancy.lin@mediatek.com>
 <20210722094551.15255-8-nancy.lin@mediatek.com>
 <CAFqH_53UpoChfrhXf41YRMGGPzjC9N2g3yNQQxc-J=7uPE44Cw@mail.gmail.com>
 <48be9a4ebb455737bfd640c6339f2ce05d02d4cd.camel@mediatek.com>
 <6c1891ed-178e-b589-1630-93d528276b17@gmail.com>
Message-ID: <ec0fa0d41aab77c93981dcc9553fc40596125c0e.camel@mediatek.com>

Hi Matthias,

Thanks for the review.

On Fri, 2021-08-06 at 14:20 +0200, Matthias Brugger wrote:
> 
> On 28/07/2021 07:34, Nancy.Lin wrote:
> > Hi Enric,
> > 
> > Thanks for your review.
> > 
> > On Fri, 2021-07-23 at 13:05 +0200, Enric Balletbo Serra wrote:
> > > Hi Nancy,
> > > 
> > > Thank you for your patch.
> > > 
> > > Missatge de Nancy.Lin <nancy.lin at mediatek.com> del dia dj., 22 de
> > > jul.
> > > 2021 a les 11:45:
> > > > 
> > > > Add mt8195 vdosys1 clock driver name and routing table to
> > > > the driver data of mtk-mmsys.
> > > > 
> > > > Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> > > > ---
> > > >  drivers/soc/mediatek/mt8195-mmsys.h    | 83
> > > > ++++++++++++++++++++++++--
> > > >  drivers/soc/mediatek/mtk-mmsys.c       | 10 ++++
> > > >  include/linux/soc/mediatek/mtk-mmsys.h |  2 +
> > > >  3 files changed, 90 insertions(+), 5 deletions(-)
> > > > 
> > > > diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
> > > > b/drivers/soc/mediatek/mt8195-mmsys.h
> > > > index 73e9e8286d50..104ba575f765 100644
> > > > --- a/drivers/soc/mediatek/mt8195-mmsys.h
> > > > +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> > > > @@ -64,16 +64,16 @@
> > > >  #define
> > > > SOUT_TO_VPP_MERGE0_P1_SEL                              (1
> > > > << 0)
> > > > 
> > > >  #define
> > > > MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL                      0xf40
> > > > -#define
> > > > SOUT_TO_HDR_VDO_FE0                                    (0
> > > > << 0)
> > > 
> > > This definition was introduced in this patch [1] that didn't land
> > > yet.
> > > And you're removing it now. Could you sync with Jason and only
> > > introduce the bits that are needed for your patches. Also all the
> > > comments I made to the Jason's patch apply here.
> > > 
> > > [1] 
> > > 
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210723090233.24007-3-jason-jh.lin at mediatek.com/__;!!CTRNKA9wMg0ARbw!0rDdPxfBPcZC9icK37sCxT55RMqwRngO0BF4-uDwgYZP7UwQkx7iidkINqLBb7yi$
> > >  
> > > 
> > 
> > OK, I will sync with Jason and modify it.
> > 
> > > > +#define
> > > > SOUT_TO_MIXER_IN1_SEL                                  (1
> > > > << 0)
> > > > 
> > > >  #define
> > > > MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL                      0xf44
> > > > -#define
> > > > SOUT_TO_HDR_VDO_FE1                                    (0
> > > > << 0)
> > > > +#define
> > > > SOUT_TO_MIXER_IN2_SEL                                  (1
> > > > << 0)
> > > > 
> > > >  #define
> > > > MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL                      0xf48
> > > > -#define
> > > > SOUT_TO_HDR_GFX_FE0                                    (0
> > > > << 0)
> > > > +#define
> > > > SOUT_TO_MIXER_IN3_SEL                                  (1
> > > > << 0)
> > > > 
> > > >  #define
> > > > MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL                      0xf4c
> > > > -#define
> > > > SOUT_TO_HDR_GFX_FE1                                    (0
> > > > << 0)
> > > > +#define
> > > > SOUT_TO_MIXER_IN4_SEL                                  (1
> > > > << 0)
> > > > 
> > > >  #define
> > > > MT8195_VDO1_MIXER_IN1_SOUT_SEL                         0xf58
> > > >  #define
> > > > MIXER_IN1_SOUT_TO_DISP_MIXER                           (0
> > > > << 0)
> > > > @@ -88,7 +88,7 @@
> > > >  #define
> > > > MIXER_IN4_SOUT_TO_DISP_MIXER                           (0
> > > > << 0)
> > > > 
> > > >  #define
> > > > MT8195_VDO1_MIXER_OUT_SOUT_SEL                         0xf34
> > > > -#define
> > > > MIXER_SOUT_TO_HDR_VDO_BE0                              (0
> > > > << 0)
> > > > +#define
> > > > MIXER_SOUT_TO_MERGE4_ASYNC_SEL                         (1
> > > > << 0)
> > > > 
> > > >  #define
> > > > MT8195_VDO1_MERGE4_SOUT_SEL                            0xf18
> > > >  #define
> > > > MERGE4_SOUT_TO_VDOSYS0                                 (0
> > > > << 0)
> > > > @@ -185,6 +185,79 @@ static const struct mtk_mmsys_routes
> > > > mmsys_mt8195_routing_table[] = {
> > > >         }, {
> > > >                 DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> > > >                 MT8195_VDO0_SEL_OUT,
> > > > SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_VPP_MERGE0_P0_SEL_IN,
> > > > VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_VPP_MERGE0_P1_SEL_IN,
> > > > VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_VPP_MERGE1_P0_SEL_IN,
> > > > VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL,
> > > > SOUT_TO_MIXER_IN1_SEL
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL,
> > > > SOUT_TO_MIXER_IN2_SEL
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL,
> > > > SOUT_TO_MIXER_IN3_SEL
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL,
> > > > SOUT_TO_MIXER_IN4_SEL
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MIXER_OUT_SOUT_SEL,
> > > > MIXER_SOUT_TO_MERGE4_ASYNC_SEL
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MIXER_IN1_SEL_IN,
> > > > MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MIXER_IN2_SEL_IN,
> > > > MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MIXER_IN3_SEL_IN,
> > > > MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MIXER_IN4_SEL_IN,
> > > > MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MIXER_SOUT_SEL_IN,
> > > > MIXER_SOUT_SEL_IN_FROM_DISP_MIXER
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_PSEUDO_OVL, DDP_COMPONENT_MERGE5,
> > > > +               MT8195_VDO1_MERGE4_ASYNC_SEL_IN,
> > > > MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
> > > > +               MT8195_VDO1_DISP_DPI1_SEL_IN,
> > > > DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
> > > > +               MT8195_VDO1_MERGE4_SOUT_SEL,
> > > > MERGE4_SOUT_TO_DPI1_SEL
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
> > > > +               MT8195_VDO1_DISP_DP_INTF0_SEL_IN,
> > > > +               DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT
> > > > +       },
> > > > +       {
> > > > +               DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
> > > > +               MT8195_VDO1_MERGE4_SOUT_SEL,
> > > > MERGE4_SOUT_TO_DP_INTF0_SEL
> > > >         }
> > > >  };
> > > > 
> > > > diff --git a/drivers/soc/mediatek/mtk-mmsys.c
> > > > b/drivers/soc/mediatek/mtk-mmsys.c
> > > > index 1fb241750897..9e31aad6c5c8 100644
> > > > --- a/drivers/soc/mediatek/mtk-mmsys.c
> > > > +++ b/drivers/soc/mediatek/mtk-mmsys.c
> > > > @@ -59,6 +59,12 @@ static const struct mtk_mmsys_driver_data
> > > > mt8195_vdosys0_driver_data = {
> > > >         .num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
> > > >  };
> > > > 
> > > > +static const struct mtk_mmsys_driver_data
> > > > mt8195_vdosys1_driver_data = {
> > > > +       .clk_driver = "clk-mt8195-vdo1",
> > > > +       .routes = mmsys_mt8195_routing_table,
> > > > +       .num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
> > > > +};
> > > > +
> > > >  struct mtk_mmsys {
> > > >         void __iomem *regs;
> > > >         const struct mtk_mmsys_driver_data *data;
> > > > @@ -168,6 +174,10 @@ static const struct of_device_id
> > > > of_match_mtk_mmsys[] = {
> > > >                 .compatible = "mediatek,mt8195-vdosys0",
> > > >                 .data = &mt8195_vdosys0_driver_data,
> > > >         },
> > > > +       {
> > > > +               .compatible = "mediatek,mt8195-vdosys1",
> > > 
> > > Why do you need a second compatible, isn't this the same IP
> > > block? I
> > > mean, I understand that you have 2 mmsys blocks, but both are the
> > > same
> > > IP block, right? or are they different?
> > > 
> > > Thanks,
> > >   Enric
> > > 
> > 
> > They(vdosys0 and vdosys1) are different IP block.
> > 
> 
> Please explain in what they are different. From what I see, you use
> the same
> routing table for both compatibles and only register another platform
> device for
> a second clock. Is that correct?
> 
> Regards,
> Matthias
> 
From a hardware point of view, the HW engines of vdosys0 and vdosys1
are different.
1. The components on meiatek-drm of vdosys0 are OVL0, RDMA0, COLOR0,
CCORR, AAL0, GAMMA, DITHER, DSC0, MERGE0, DP_INTF0. Its output panel is
eDP.
2. The components on meiatek-drm of vdosys1 are OVL_ADAPTOR, MERGE5,
DP_INTF1. Its output panel is DP.

In the SoC before, such as mt8173, it has 2 pipelines binding to one
mmsys with the same clock driver and the same power domain.

In mt8195, 2 pipelines are binding to different mmsys, such as vdosys0
and vdosys1. Each mmsys uses different clock drivers and different
power domains.

So I think it is more appropriate to use 2 compatibles to identify
which mmsys represents the pipeline. Another reason for using two
compatibles is that we use different driver
data in mtk-mmsys.c and mtk_drm_drv.c to identify the corresponding
mmsys is vdosys0 or vdosys1.

Their driver data in mtk_drm_drv.c is defined here:
[v7,13/13] drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

https://patchwork.kernel.org/project/linux-mediatek/patch/20210815145610.2050-14-jason-jh.lin at mediatek.com/

[v2,14/14] drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

https://patchwork.kernel.org/project/linux-mediatek/patch/20210722094551.15255-15-nancy.lin at mediatek.com/


There is another series talking about the two mmsys compatible.

https://patchwork.kernel.org/project/linux-mediatek/patch/20210722092624.14401-2-jason-jh.lin at mediatek.com/

Regards,
Nancy

> > > > +               .data = &mt8195_vdosys1_driver_data,
> > > > +       },
> > > >         { }
> > > >  };
> > > > 
> > > > diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> > > > b/include/linux/soc/mediatek/mtk-mmsys.h
> > > > index 34cb605e5df9..338c71570aeb 100644
> > > > --- a/include/linux/soc/mediatek/mtk-mmsys.h
> > > > +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> > > > @@ -49,6 +49,8 @@ enum mtk_ddp_comp_id {
> > > >         DDP_COMPONENT_DSC1,
> > > >         DDP_COMPONENT_DSC1_VIRTUAL0,
> > > >         DDP_COMPONENT_DP_INTF0,
> > > > +       DDP_COMPONENT_DP_INTF1,
> > > > +       DDP_COMPONENT_PSEUDO_OVL,
> > > >         DDP_COMPONENT_ID_MAX,
> > > >  };
> > > > 
> > > > --
> > > > 2.18.0
> > > > 

From joel at jms.id.au  Sun Aug 15 19:11:40 2021
From: joel at jms.id.au (Joel Stanley)
Date: Mon, 16 Aug 2021 02:11:40 +0000
Subject: [PATCH] ARM: dts: aspeed: minipack: Update flash partition table
In-Reply-To: <20210813062435.GA24497@taoren-ubuntu-R90MNF91>
References: <20210720002704.7390-1-rentao.bupt@gmail.com>
 <20210813062435.GA24497@taoren-ubuntu-R90MNF91>
Message-ID: <CACPK8XcAqU3KASespqS3dPterpzyqD4wYH=qOS8Ok2yUrB_F+Q@mail.gmail.com>

On Fri, 13 Aug 2021 at 06:24, Tao Ren <rentao.bupt at gmail.com> wrote:
>
> Hi Joel,
>
> Looks like the patch is not included in "dt-for-v5.15". Any comments? Or
> should I send v2 if the email was not delivered?

I had missed it. It's now applied for 5.15.

Cheers,

Joel


From thunder.leizhen at huawei.com  Sun Aug 15 19:15:37 2021
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Mon, 16 Aug 2021 10:15:37 +0800
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching helpers
 to improve performance
In-Reply-To: <4e741216-d6e7-c40c-f257-242cd2fea302@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
 <20210811114852.2429-2-thunder.leizhen@huawei.com>
 <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>
 <4e741216-d6e7-c40c-f257-242cd2fea302@huawei.com>
Message-ID: <5482d2e5-24db-6139-a8a8-74be1282e2ec@huawei.com>



On 2021/8/14 0:45, John Garry wrote:
> On 13/08/2021 17:01, Robin Murphy wrote:
>>>
>>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>> index 235f9bdaeaf223b..c81cd929047f573 100644
>>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>> @@ -1747,15 +1747,16 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
>>> ? {
>>> ????? int i;
>>> ????? struct arm_smmu_cmdq_ent cmd;
>>> +??? struct arm_smmu_cmdq_batch cmds = {};
>>
>> BTW, it looks like this has crossed over with John's patch removing these.
> 
> It is only called from arm_smmu_disable_ats(), so not hot-path by the look for it. Or who even has ats HW ...?
> 
> But it should be at least cleaned-up for consistency. Leizhen?

Okay, I'll revise it. But Will already took it. So I'm not sure whether to send v2 or a separate patch.

> 
> Thanks,
> John
> .
> 


From nancy.lin at mediatek.com  Sun Aug 15 19:59:35 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 16 Aug 2021 10:59:35 +0800
Subject: [PATCH v2 08/14] soc: mediatek: add mtk-mmsys config API for
 mt8195 vdosys1
In-Reply-To: <b71be855-b1a5-af6c-3000-59e6e42c0a79@gmail.com>
References: <20210722094551.15255-1-nancy.lin@mediatek.com>
 <20210722094551.15255-9-nancy.lin@mediatek.com>
 <b71be855-b1a5-af6c-3000-59e6e42c0a79@gmail.com>
Message-ID: <46fabd02e7990acf8409762380ee0e33c9a6edc3.camel@mediatek.com>

Hi Matthias,

Thanks for the review.

On Fri, 2021-08-06 at 17:30 +0200, Matthias Brugger wrote:
> 
> On 22/07/2021 11:45, Nancy.Lin wrote:
> > Add mmsys config API.
> 
> This patch is doing a lot of things, it adds a "config" and it adds
> cmdq
> support. Please explain better in the commit message what the config
> is for.
> Please add comments to the different values of struct
> mtk_mmsys_config.
> 
OK, I will explain in more detail in the commit message.

> I understand that cmdq is optional, so please make addition to cmdq a
> separate
> patch.

OK, I will add cmdq support in another patch.


> I'm a bit puzzled about that fact, can you please explain who you get
> the HW to
> behave the same way when you write the same value and offset to
> mmsys-regs and
> via cmdq.
> 
> Thanks,
> Matthias

The mmsys config register settings need to take effect with the other
HW settings(like OVL_ADAPTOR...) at the same vblanking time.
If we use CPU to write the mmsys reg, we can't guarantee all the
settings can be written in the same vblanking time.
Cmdq is used for this purpose. We prepare all the related HW settings
in one cmdq packet. 
The first command in the packet is "wait stream done", and then
following with all the HW settings. After the cmdq packet is flush to
GCE HW.
The GCE waits for the "stream done event" to coming and then starts
flushing all the HW settings. This can guarantee all the settings flush
in the same vblanking. 

Regards,
Nancy

> > 
> > Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> > ---
> >  drivers/soc/mediatek/mt8195-mmsys.h    | 38 ++++++++++++++++++++
> >  drivers/soc/mediatek/mtk-mmsys.c       | 50
> > ++++++++++++++++++++++++++
> >  drivers/soc/mediatek/mtk-mmsys.h       | 10 ++++++
> >  include/linux/soc/mediatek/mtk-mmsys.h | 18 ++++++++++
> >  4 files changed, 116 insertions(+)
> > 
> > diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
> > b/drivers/soc/mediatek/mt8195-mmsys.h
> > index 104ba575f765..4bdb2087250c 100644
> > --- a/drivers/soc/mediatek/mt8195-mmsys.h
> > +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> > @@ -154,6 +154,18 @@
> >  #define DISP_DP_INTF0_SEL_IN_FROM_VDO0_MERGE_DL_ASYNC_MOUT	(1 <<
> > 0)
> >  #define DISP_DP_INTF0_SEL_IN_FROM_VDO0_DSC_DL_ASYNC_MOUT	(2 <<
> > 0)
> >  
> > +#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD	0xe30
> > +#define MT8195_VDO1_MERGE1_ASYNC_CFG_WD	0xe40
> > +#define MT8195_VDO1_MERGE2_ASYNC_CFG_WD	0xe50
> > +#define MT8195_VDO1_MERGE3_ASYNC_CFG_WD	0xe60
> > +#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD	0xe70
> > +#define MT8195_VDO1_HDR_TOP_CFG		0xd00
> > +#define MT8195_VDO1_MIXER_IN1_ALPHA	0xd30
> > +#define MT8195_VDO1_MIXER_IN2_ALPHA	0xd34
> > +#define MT8195_VDO1_MIXER_IN3_ALPHA	0xd38
> > +#define MT8195_VDO1_MIXER_IN4_ALPHA	0xd3c
> > +#define MT8195_VDO1_MIXER_IN4_PAD	0xd4c
> > +
> >  static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[]
> > = {
> >  	{
> >  		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> > @@ -261,4 +273,30 @@ static const struct mtk_mmsys_routes
> > mmsys_mt8195_routing_table[] = {
> >  	}
> >  };
> >  
> > +static const struct mtk_mmsys_config mmsys_mt8195_config_table[] =
> > {
> > +	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 0,
> > MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> > +	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 0,
> > MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> > +	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 1,
> > MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> > +	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 1,
> > MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> > +	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 2,
> > MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> > +	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 2,
> > MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> > +	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 3,
> > MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> > +	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 3,
> > MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> > +	{ MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0,
> > MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(13, 0), 0},
> > +	{ MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0,
> > MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(29, 16), 16},
> > +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 1,
> > MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(8, 0), 0},
> > +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 1,
> > MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(24, 16), 16},
> > +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 2,
> > MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(8, 0), 0},
> > +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 2,
> > MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(24, 16), 16},
> > +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 3,
> > MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(8, 0), 0},
> > +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 3,
> > MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(24, 16), 16},
> > +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 4,
> > MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(8, 0), 0},
> > +	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 4,
> > MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(24, 16), 16},
> > +	{ MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, MT8195_VDO1_MIXER_IN4_PAD,
> > GENMASK(4, 4), 4},
> > +	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 1, MT8195_VDO1_HDR_TOP_CFG,
> > GENMASK(20, 20), 20},
> > +	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 2, MT8195_VDO1_HDR_TOP_CFG,
> > GENMASK(21, 21), 21},
> > +	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 3, MT8195_VDO1_HDR_TOP_CFG,
> > GENMASK(22, 22), 22},
> > +	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 4, MT8195_VDO1_HDR_TOP_CFG,
> > GENMASK(23, 23), 23},
> > +};
> > +
> >  #endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
> > diff --git a/drivers/soc/mediatek/mtk-mmsys.c
> > b/drivers/soc/mediatek/mtk-mmsys.c
> > index 9e31aad6c5c8..d0f4a407f8f8 100644
> > --- a/drivers/soc/mediatek/mtk-mmsys.c
> > +++ b/drivers/soc/mediatek/mtk-mmsys.c
> > @@ -63,10 +63,13 @@ static const struct mtk_mmsys_driver_data
> > mt8195_vdosys1_driver_data = {
> >  	.clk_driver = "clk-mt8195-vdo1",
> >  	.routes = mmsys_mt8195_routing_table,
> >  	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
> > +	.config = mmsys_mt8195_config_table,
> > +	.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
> >  };
> >  
> >  struct mtk_mmsys {
> >  	void __iomem *regs;
> > +	struct cmdq_client_reg cmdq_base;
> >  	const struct mtk_mmsys_driver_data *data;
> >  };
> >  
> > @@ -104,6 +107,47 @@ void mtk_mmsys_ddp_disconnect(struct device
> > *dev,
> >  }
> >  EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
> >  
> > +void mtk_mmsys_ddp_config(struct device *dev, enum
> > mtk_mmsys_config_type config,
> > +			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt)
> > +{
> > +	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
> > +	const struct mtk_mmsys_config *mmsys_config = mmsys->data-
> > >config;
> > +	u32 reg_val;
> > +	u32 mask;
> > +	u32 offset;
> > +	int i;
> > +
> > +	if (!mmsys->data->num_configs)
> > +		return;
> > +
> > +	for (i = 0; i < mmsys->data->num_configs; i++)
> > +		if (config == mmsys_config[i].config && id ==
> > mmsys_config[i].id)
> > +			break;
> > +
> > +	if (i == mmsys->data->num_configs)
> > +		return;
> > +
> > +	offset = mmsys_config[i].addr;
> > +	mask = mmsys_config[i].mask;
> > +	reg_val = val << mmsys_config[i].shift;
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +	if (cmdq_pkt && mmsys->cmdq_base.size) {
> > +		cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
> > +				    mmsys->cmdq_base.offset + offset,
> > reg_val,
> > +				    mask);
> > +	} else {
> > +#endif
> > +		u32 tmp = readl(mmsys->regs + offset);
> > +
> > +		tmp = (tmp & ~mask) | reg_val;
> > +		writel(tmp, mmsys->regs + offset);
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +	}
> > +#endif
> > +}
> > +EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
> > +
> >  static int mtk_mmsys_probe(struct platform_device *pdev)
> >  {
> >  	struct device *dev = &pdev->dev;
> > @@ -124,6 +168,12 @@ static int mtk_mmsys_probe(struct
> > platform_device *pdev)
> >  	}
> >  
> >  	mmsys->data = of_device_get_match_data(&pdev->dev);
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +	ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
> > +	if (ret)
> > +		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
> > +#endif
> >  	platform_set_drvdata(pdev, mmsys);
> >  
> >  	clks = platform_device_register_data(&pdev->dev, mmsys->data-
> > >clk_driver,
> > diff --git a/drivers/soc/mediatek/mtk-mmsys.h
> > b/drivers/soc/mediatek/mtk-mmsys.h
> > index a760a34e6eca..084b1f5f3c88 100644
> > --- a/drivers/soc/mediatek/mtk-mmsys.h
> > +++ b/drivers/soc/mediatek/mtk-mmsys.h
> > @@ -73,10 +73,20 @@ struct mtk_mmsys_routes {
> >  	u32 val;
> >  };
> >  
> > +struct mtk_mmsys_config {
> > +	enum mtk_mmsys_config_type config;
> > +	u32 id;
> > +	u32 addr;
> > +	u32 mask;
> > +	u32 shift;
> > +};
> > +
> >  struct mtk_mmsys_driver_data {
> >  	const char *clk_driver;
> >  	const struct mtk_mmsys_routes *routes;
> >  	const unsigned int num_routes;
> > +	const struct mtk_mmsys_config *config;
> > +	const unsigned int num_configs;
> >  };
> >  
> >  /*
> > diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> > b/include/linux/soc/mediatek/mtk-mmsys.h
> > index 338c71570aeb..ba3925661cc9 100644
> > --- a/include/linux/soc/mediatek/mtk-mmsys.h
> > +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> > @@ -6,6 +6,10 @@
> >  #ifndef __MTK_MMSYS_H
> >  #define __MTK_MMSYS_H
> >  
> > +#include <linux/mailbox_controller.h>
> > +#include <linux/mailbox/mtk-cmdq-mailbox.h>
> > +#include <linux/soc/mediatek/mtk-cmdq.h>
> > +
> >  enum mtk_ddp_comp_id;
> >  struct device;
> >  
> > @@ -54,6 +58,17 @@ enum mtk_ddp_comp_id {
> >  	DDP_COMPONENT_ID_MAX,
> >  };
> >  
> > +enum mtk_mmsys_config_type {
> > +	MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
> > +	MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
> > +	MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH,
> > +	MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT,
> > +	MMSYS_CONFIG_HDR_ALPHA_SEL,
> > +	MMSYS_CONFIG_MIXER_IN_ALPHA_ODD,
> > +	MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN,
> > +	MMSYS_CONFIG_MIXER_IN_CH_SWAP,
> > +};
> > +
> >  void mtk_mmsys_ddp_connect(struct device *dev,
> >  			   enum mtk_ddp_comp_id cur,
> >  			   enum mtk_ddp_comp_id next);
> > @@ -62,4 +77,7 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
> >  			      enum mtk_ddp_comp_id cur,
> >  			      enum mtk_ddp_comp_id next);
> >  
> > +void mtk_mmsys_ddp_config(struct device *dev, enum
> > mtk_mmsys_config_type config,
> > +			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt);
> > +
> >  #endif /* __MTK_MMSYS_H */
> > 

From houlong.wei at mediatek.com  Sun Aug 15 20:00:35 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 11:00:35 +0800
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
Message-ID: <bf98c5ee749bca755bd46832f858536dbf51a2a4.camel@mediatek.com>

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> ... Instead of depending on the presence of a mediatek,vpu property
> in
> the device node.
> 
> That property was originally added to link to the vpu node so that
> the
> mtk_mdp_core driver could pass the right device to
> vpu_wdt_reg_handler(). However in a previous patch in this series,
> the driver has been modified to search the device tree for that node
> instead.
> 
> That property was also used to indicate the primary MDP device, so
> that
> it can be passed to the V4L2 subsystem as well as register it to be
> used when setting up queues in the open() callback for the filesystem
> device node that is created. In this case, assuming that the primary
> MDP device is the one with a specific alias seems useable because the
> alternative is to add a property to the device tree which doesn't
> actually represent any facet of hardware (i.e., this being the
> primary
> MDP device is a software decision). In other words, this solution is
> equally as arbitrary, but at least it doesn't add a property to a
> device node where said property is unrelated to the hardware present.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
> 
> (no changes since v1)
> 
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++--
> ----
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
>  2 files changed, 64 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 85ef274841a3..9527649de98e 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp
> *comp)
>  		mtk_smi_larb_put(comp->larb_dev);
>  }
>  
> -static int mtk_mdp_comp_bind(struct device *dev, struct device
> *master, void *data)
> +/*
> + * The MDP master device node is identified by the device tree alias
> + * "mdp-rdma0".
> + */
> +static bool is_mdp_master(struct device *dev)
> +{
> +	struct device_node *aliases, *mdp_rdma0_node;
> +	const char *mdp_rdma0_path;
> +
> +	if (!dev->of_node)
> +		return false;
> +
> +	aliases = of_find_node_by_path("/aliases");
> +	if (!aliases) {
> +		dev_err(dev, "no aliases found for mdp-rdma0");
> +		return false;
> +	}
> +
> +	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
> +	if (!mdp_rdma0_path) {
> +		dev_err(dev, "get mdp-rdma0 property of /aliases
> failed");
> +		return false;
> +	}
> +
> +	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
> +	if (!mdp_rdma0_node) {
> +		dev_err(dev, "path resolution failed for %s",
> mdp_rdma0_path);
> +		return false;
> +	}
> +

Hi Eizan,

"mdp-rdma0" may be not the only one master device node. In fact, there
are 2 "mdp-rdma" in mt8173. You can see "mdp_rdma1" via below link.

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.13.11#n1016
If we add "mediatek,mt8173-mdp" to "mdp_rdma1" like below, we will have
one more V4L2 video devie node.

		mdp_rdma1: rdma at 14002000 {
			compatible = "mediatek,mt8173-mdp-rdma",
				     "mediatek,mt8173-mdp";
			...
		}

We should consider the case that there are more than one "MDP_RDMA"
components. 

Regards,
Houlong

> +	return dev->of_node == mdp_rdma0_node;
> +}
> +
> +static int mtk_mdp_comp_bind(struct device *dev, struct device
> *master,
> +			void *data)
>  {
>  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>  	struct mtk_mdp_dev *mdp = data;
> -	struct device_node *vpu_node;
>  
>  	mtk_mdp_register_component(mdp, comp);
>  
> -	/*
> -	 * If this component has a "mediatek-vpu" property, it is
> responsible for
> -	 * notifying the mdp master driver about it so it can be
> further initialized
> -	 * later.
> -	 */
> -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> -	if (vpu_node) {
> +	if (is_mdp_master(dev)) {
>  		int ret;
>  
> -		mdp->vpu_dev = of_find_device_by_node(vpu_node);
> -		if (WARN_ON(!mdp->vpu_dev)) {
> -			dev_err(dev, "vpu pdev failed\n");
> -			of_node_put(vpu_node);
> -		}
> -
>  		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
>  		if (ret) {
>  			dev_err(dev, "Failed to register v4l2
> device\n");
> @@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev,
> struct device *master, void *da
>  		}
>  
>  		/*
> -		 * presence of the "mediatek,vpu" property in a device
> node
> -		 * indicates that it is the primary MDP rdma device and
> MDP DMA
> -		 * ops should be handled by its DMA callbacks.
> +		 * MDP DMA ops will be handled by the DMA callbacks
> associated with this
> +		 * device;
>  		 */
>  		mdp->rdma_dev = dev;
>  	}
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index 50eafcc9993d..6a775463399c 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -150,8 +150,9 @@ static void release_of(struct device *dev, void
> *data)
>  
>  static int mtk_mdp_master_bind(struct device *dev)
>  {
> -	int status;
>  	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> +	struct device_node *vpu_node;
> +	int status;
>  
>  	status = component_bind_all(dev, mdp);
>  	if (status) {
> @@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device
> *dev)
>  		goto err_component_bind_all;
>  	}
>  
> -	if (mdp->vpu_dev) {
> -		int ret = vpu_wdt_reg_handler(mdp->vpu_dev,
> mtk_mdp_reset_handler, mdp,
> -					  VPU_RST_MDP);
> -		if (ret) {
> -			dev_err(dev, "Failed to register reset
> handler\n");
> -			goto err_wdt_reg;
> -		}
> -	} else {
> -		dev_err(dev, "no vpu_dev found\n");
> +	if (mdp->rdma_dev == NULL) {
> +		dev_err(dev, "Primary MDP device not found");
> +		status = -ENODEV;
> +		goto err_component_bind_all;
> +	}
> +
> +	vpu_node = of_find_node_by_name(NULL, "vpu");
> +	if (!vpu_node) {
> +		dev_err(dev, "unable to find vpu node");
> +		status = -ENODEV;
> +		goto err_wdt_reg;
> +	}
> +
> +	mdp->vpu_dev = of_find_device_by_node(vpu_node);
> +	if (!mdp->vpu_dev) {
> +		dev_err(dev, "unable to find vpu device");
> +		status = -ENODEV;
> +		goto err_wdt_reg;
> +	}
> +
> +	status = vpu_wdt_reg_handler(mdp->vpu_dev,
> mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
> +	if (status) {
> +		dev_err(dev, "Failed to register reset handler\n");
> +		goto err_wdt_reg;
>  	}
>  
>  	status = mtk_mdp_register_m2m_device(mdp);
> -- 
> 2.32.0.554.ge1b32706d8-goog
> 

From houlong.wei at mediatek.com  Sun Aug 15 20:37:47 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 11:37:47 +0800
Subject: [PATCH v6 5/9] mtk-mdp: make mdp driver to be loadable by
 platform_device_register*()
In-Reply-To: <20210802220943.v6.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>
Message-ID: <8ec92b60f97b7e6516a0ffd32328f428d233fa93.camel@mediatek.com>

On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> Rather than hanging the MDP master component driver off of the rdma0
> device, make it possible too create a "virtual" device by registering
> it with platform_device_register_*() to be probed by the mtk_mdp_core
> driver.
> 
> Broadly, three interdependent things are done by this change:
> - Make it is possible to search for MDP devices in the device tree
>   through the grandparent device's of_node.
> - v4l-related setup is moved into from the mtk_mdp_core driver to the
>   mtk_mdp_comp driver.
> - Presence of a mediatek,vpu property in an MDP component device node
>   is used to determine what device to use when dispatching DMA ops
> from
>   the relevant ioctl, and also do V4L2 initialization in this case.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---
> 
> Changes in v6:
> - Don't propagate errors from clock_on/off as an afterthought.
> - Split apart modifying mdp driver to be loadable from mmsys from
>   actually loading it from mmsys into two changs to make review
> easier.
> - Update devicetree bindings to reflect no longer needing the
>   mediatek,vpu property in the mdp_rdma0 device node.
> - Some stylistic cleanups.
> 
> Changes in v5:
> - rebase and test on 5.13-next @ e2f74b13dbe6
> 
> Changes in v4:
> - rebase and test on 5.13
> - don't depend on 
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873
> 
> Changes in v3:
> - get mdp master from aliases instead of strcmp against of_node->name
> 
> Changes in v2:
> - rebased onto Linux 5.12
> - 100 char line length allowance was utilized in a few places
> - Removal of a redundant dev_err() print at the end of
>   mtk_mdp_comp_init()
> - Instead of printing errors and ignoring them, I've added a patch to
>   correctly propagate them.
> - Use of C style comments.
> - Three additional patches were added to eliminate dependency on the
>   mediatek,vpu property inside the mdp_rdma0 device node.
> 
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 51 ++++++++++-----
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++-----------
> --
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.h |  2 +
>  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
>  4 files changed, 60 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 7b6c8a3f3455..85ef274841a3 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -155,8 +155,45 @@ static int mtk_mdp_comp_bind(struct device *dev,
> struct device *master, void *da
>  {
>  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>  	struct mtk_mdp_dev *mdp = data;
> +	struct device_node *vpu_node;
>  
>  	mtk_mdp_register_component(mdp, comp);
> +
> +	/*
> +	 * If this component has a "mediatek-vpu" property, it is
> responsible for
> +	 * notifying the mdp master driver about it so it can be
> further initialized
> +	 * later.
> +	 */
> +	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> +	if (vpu_node) {
> +		int ret;
> +
> +		mdp->vpu_dev = of_find_device_by_node(vpu_node);
> +		if (WARN_ON(!mdp->vpu_dev)) {
> +			dev_err(dev, "vpu pdev failed\n");
> +			of_node_put(vpu_node);
> +		}

Maybe 'of_node_put(vpu_node)' should be called when 'mdp->vpu_dev' is
valid.


> +		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> +		if (ret) {
> +			dev_err(dev, "Failed to register v4l2
> device\n");
> +			return -EINVAL;
> +		}
> +
> +		ret = vb2_dma_contig_set_max_seg_size(dev,
> DMA_BIT_MASK(32));
> +		if (ret) {
> +			dev_err(dev, "Failed to set vb2 dma mag seg
> size\n");
> +			return -EINVAL;
> +		}
> +
> +		/*
> +		 * presence of the "mediatek,vpu" property in a device
> node
> +		 * indicates that it is the primary MDP rdma device and
> MDP DMA
> +		 * ops should be handled by its DMA callbacks.
> +		 */
> +		mdp->rdma_dev = dev;
> +	}
> +
>  	pm_runtime_enable(dev);
>  
>  	return 0;
> @@ -237,23 +274,9 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp,
> struct device *dev)
>  static int mtk_mdp_comp_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> -	struct device_node *vpu_node;
>  	int status;
>  	struct mtk_mdp_comp *comp;
>  
> -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> -	if (vpu_node) {
> -		of_node_put(vpu_node);
> -		/*
> -		 * The device tree node with a mediatek,vpu property is
> deemed
> -		 * the MDP "master" device, we don't want to add a
> component
> -		 * for it in this function because the initialization
> for the
> -		 * master is done elsewhere.
> -		 */
> -		dev_info(dev, "vpu node found, not probing\n");
> -		return -ENODEV;
> -	}
> -
>  	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
>  	if (!comp)
>  		return -ENOMEM;
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index a72a9ba41ea6..50eafcc9993d 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -159,6 +159,17 @@ static int mtk_mdp_master_bind(struct device
> *dev)
>  		goto err_component_bind_all;
>  	}
>  
> +	if (mdp->vpu_dev) {
> +		int ret = vpu_wdt_reg_handler(mdp->vpu_dev,
> mtk_mdp_reset_handler, mdp,
> +					  VPU_RST_MDP);
> +		if (ret) {
> +			dev_err(dev, "Failed to register reset
> handler\n");
> +			goto err_wdt_reg;
> +		}
> +	} else {
> +		dev_err(dev, "no vpu_dev found\n");
> +	}
> +
>  	status = mtk_mdp_register_m2m_device(mdp);
>  	if (status) {
>  		dev_err(dev, "Failed to register m2m device: %d\n",
> status);
> @@ -170,6 +181,8 @@ static int mtk_mdp_master_bind(struct device
> *dev)
>  	return 0;
>  
>  err_mtk_mdp_register_m2m_device:
> +
> +err_wdt_reg:
>  	component_unbind_all(dev, mdp);
>  
>  err_component_bind_all:
> @@ -228,8 +241,13 @@ static int mtk_mdp_probe(struct platform_device
> *pdev)
>  		of_node_put(node);
>  		parent = dev->of_node;
>  		dev_warn(dev, "device tree is out of date\n");
> -	} else {
> +	} else if (dev->of_node) {
>  		parent = dev->of_node->parent;
> +	} else if (dev->parent) {
> +		/* maybe we were created from a call to
> platform_device_register_data() */
> +		parent = dev->parent->parent->of_node;
> +	} else {
> +		return -ENODEV;
>  	}
>  
>  	/* Iterate over sibling MDP function blocks */
> @@ -262,16 +280,6 @@ static int mtk_mdp_probe(struct platform_device
> *pdev)
>  		}
>  	}
>  
> -	/*
> -	 * Create a component for myself so that clocks can be toggled
> in
> -	 * clock_on().
> -	 */
> -	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
> -	if (ret) {
> -		dev_err(dev, "Failed to initialize component\n");
> -		goto err_comp;
> -	}
> -
>  	mdp->job_wq =
> create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
>  	if (!mdp->job_wq) {
>  		dev_err(&pdev->dev, "unable to alloc job workqueue\n");
> @@ -287,29 +295,8 @@ static int mtk_mdp_probe(struct platform_device
> *pdev)
>  	}
>  	INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker);
>  
> -	ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to register v4l2
> device\n");
> -		ret = -EINVAL;
> -		goto err_dev_register;
> -	}
> -
> -	mdp->vpu_dev = vpu_get_plat_device(pdev);
> -	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler,
> mdp,
> -				  VPU_RST_MDP);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to register reset
> handler\n");
> -		goto err_wdt_reg;
> -	}
> -
>  	platform_set_drvdata(pdev, mdp);
>  
> -	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev,
> DMA_BIT_MASK(32));
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg
> size\n");
> -		goto err_set_max_seg_size;
> -	}
> -
>  	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops,
> match);
>  	if (ret) {
>  		dev_err(dev, "Component master add failed\n");
> @@ -321,22 +308,12 @@ static int mtk_mdp_probe(struct platform_device
> *pdev)
>  	return 0;
>  
>  err_component_master_add:
> -	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> -
> -err_set_max_seg_size:
> -
> -err_wdt_reg:
> -	v4l2_device_unregister(&mdp->v4l2_dev);
> -
> -err_dev_register:
>  	destroy_workqueue(mdp->wdt_wq);
>  
>  err_alloc_wdt_wq:
>  	destroy_workqueue(mdp->job_wq);
>  
>  err_alloc_job_wq:
> -
> -err_comp:
>  	dev_dbg(dev, "err %d\n", ret);
>  	return ret;
>  }
> @@ -404,7 +381,6 @@ static struct platform_driver mtk_mdp_driver = {
>  	.driver = {
>  		.name	= MTK_MDP_MODULE_NAME,
>  		.pm	= &mtk_mdp_pm_ops,
> -		.of_match_table = mtk_mdp_of_ids,
>  	}
>  };
>  
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> index 8a52539b15d4..9fcd8b8e7c25 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> @@ -133,6 +133,7 @@ struct mtk_mdp_variant {
>   * struct mtk_mdp_dev - abstraction for image processor entity
>   * @lock:	the mutex protecting this data structure
>   * @vpulock:	the mutex protecting the communication with VPU
> + * @rdma_dev:  device pointer to rdma device for MDP
>   * @pdev:	pointer to the image processor platform device
>   * @variant:	the IP variant information
>   * @id:		image processor device index
> (0..MTK_MDP_MAX_DEVS)
> @@ -151,6 +152,7 @@ struct mtk_mdp_variant {
>  struct mtk_mdp_dev {
>  	struct mutex			lock;
>  	struct mutex			vpulock;
> +	struct device			*rdma_dev;
>  	struct platform_device		*pdev;
>  	struct mtk_mdp_variant		*variant;
>  	u16				id;
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> index f14779e7596e..9834d3bbe851 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> @@ -929,7 +929,7 @@ static int mtk_mdp_m2m_queue_init(void *priv,
> struct vb2_queue *src_vq,
>  	src_vq->mem_ops = &vb2_dma_contig_memops;
>  	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
>  	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> -	src_vq->dev = &ctx->mdp_dev->pdev->dev;
> +	src_vq->dev = ctx->mdp_dev->rdma_dev;
>  	src_vq->lock = &ctx->mdp_dev->lock;
>  
>  	ret = vb2_queue_init(src_vq);
> @@ -944,7 +944,7 @@ static int mtk_mdp_m2m_queue_init(void *priv,
> struct vb2_queue *src_vq,
>  	dst_vq->mem_ops = &vb2_dma_contig_memops;
>  	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
>  	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> -	dst_vq->dev = &ctx->mdp_dev->pdev->dev;
> +	dst_vq->dev = ctx->mdp_dev->rdma_dev;
>  	dst_vq->lock = &ctx->mdp_dev->lock;
>  
>  	return vb2_queue_init(dst_vq);
> -- 
> 2.32.0.554.ge1b32706d8-goog
> 

From thunder.leizhen at huawei.com  Sun Aug 15 21:05:33 2021
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Mon, 16 Aug 2021 12:05:33 +0800
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching helpers
 to improve performance
In-Reply-To: <5482d2e5-24db-6139-a8a8-74be1282e2ec@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
 <20210811114852.2429-2-thunder.leizhen@huawei.com>
 <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>
 <4e741216-d6e7-c40c-f257-242cd2fea302@huawei.com>
 <5482d2e5-24db-6139-a8a8-74be1282e2ec@huawei.com>
Message-ID: <52204403-f69a-d2b9-9365-7553e87d1298@huawei.com>



On 2021/8/16 10:15, Leizhen (ThunderTown) wrote:
> 
> 
> On 2021/8/14 0:45, John Garry wrote:
>> On 13/08/2021 17:01, Robin Murphy wrote:
>>>>
>>>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> index 235f9bdaeaf223b..c81cd929047f573 100644
>>>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>>>> @@ -1747,15 +1747,16 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
>>>> ? {
>>>> ????? int i;
>>>> ????? struct arm_smmu_cmdq_ent cmd;
>>>> +??? struct arm_smmu_cmdq_batch cmds = {};
>>>
>>> BTW, it looks like this has crossed over with John's patch removing these.
>>
>> It is only called from arm_smmu_disable_ats(), so not hot-path by the look for it. Or who even has ats HW ...?
>>
>> But it should be at least cleaned-up for consistency. Leizhen?
> 
> Okay, I'll revise it. But Will already took it. So I'm not sure whether to send v2 or a separate patch.

I think I'd better post v2, otherwise I should write the same description.

In addition, I find that function arm_smmu_cmdq_build_cmd() can also be optimized
slightly, three useless instructions can be reduced.

Case 1):
void arm_smmu_cmdq_build_cmd_tst1(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
{
        memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
        cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
}
0000000000004608 <arm_smmu_cmdq_build_cmd_tst1>:
    4608:       a9007c1f        stp     xzr, xzr, [x0]
    460c:       39400022        ldrb    w2, [x1]
    4610:       f9400001        ldr     x1, [x0]
    4614:       aa020021        orr     x1, x1, x2
    4618:       f9000001        str     x1, [x0]
    461c:       d65f03c0        ret

Case 2):
void arm_smmu_cmdq_build_cmd_tst2(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
{
        int i;

        cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
        for (i = 1; i < CMDQ_ENT_DWORDS; i++)
                cmd[i] = 0;
}
0000000000004620 <arm_smmu_cmdq_build_cmd_tst2>:
    4620:       39400021        ldrb    w1, [x1]
    4624:       a9007c01        stp     x1, xzr, [x0]
    4628:       d65f03c0        ret
    462c:       d503201f        nop

Case 3):
void arm_smmu_cmdq_build_cmd_tst3(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
{
        memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
        cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
}
0000000000004630 <arm_smmu_cmdq_build_cmd_tst3>:
    4630:       a9007c1f        stp     xzr, xzr, [x0]
    4634:       39400021        ldrb    w1, [x1]
    4638:       f9000001        str     x1, [x0]
    463c:       d65f03c0        ret

> 
>>
>> Thanks,
>> John
>> .
>>
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
> 


From houlong.wei at mediatek.com  Sun Aug 15 21:26:07 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 12:26:07 +0800
Subject: [PATCH] media: mtk-mdp: make mtk_mdp_comp_init static
In-Reply-To: <20210811171512.1.I4a34d99ace27ad2fe55e22c90244d3bba2c29bab@changeid>
References: <20210811171512.1.I4a34d99ace27ad2fe55e22c90244d3bba2c29bab@changeid>
Message-ID: <484e199d23a09d79f121ea37eb9e7d95eabfd886.camel@mediatek.com>

On Wed, 2021-08-11 at 15:15 +0800, Eizan Miyamoto wrote:
> This function isn't and doesn't need to be used outside of
> mtk_mdp_comp.c
> 
> This patch depends on and is a follow-up to
> 
https://patchwork.kernel.org/project/linux-mediatek/list/?series=524929
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> ---

Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>

>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 2 +-
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.h | 2 --
>  2 files changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 9527649de98e..2cf8f1864f8c 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -234,7 +234,7 @@ static const struct component_ops
> mtk_mdp_component_ops = {
>  	.unbind = mtk_mdp_comp_unbind,
>  };
>  
> -int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
> +static int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct
> device *dev)
>  {
>  	struct device_node *larb_node;
>  	struct platform_device *larb_pdev;
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> index e3d6aef52869..aa6442cc8c1d 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
> @@ -21,8 +21,6 @@ struct mtk_mdp_comp {
>  	struct device		*larb_dev;
>  };
>  
> -int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device
> *dev);
> -
>  int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp);
>  int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp);
>  
> -- 
> 2.32.0.605.g8dce9f2422-goog
> 

From houlong.wei at mediatek.com  Sun Aug 15 21:52:46 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Mon, 16 Aug 2021 12:52:46 +0800
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <bf98c5ee749bca755bd46832f858536dbf51a2a4.camel@mediatek.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <bf98c5ee749bca755bd46832f858536dbf51a2a4.camel@mediatek.com>
Message-ID: <9f23beea197495d017a548ef483584714a3673f9.camel@mediatek.com>

On Mon, 2021-08-16 at 11:00 +0800, houlong wei wrote:
> On Mon, 2021-08-02 at 20:12 +0800, Eizan Miyamoto wrote:
> > ... Instead of depending on the presence of a mediatek,vpu property
> > in
> > the device node.
> > 
> > That property was originally added to link to the vpu node so that
> > the
> > mtk_mdp_core driver could pass the right device to
> > vpu_wdt_reg_handler(). However in a previous patch in this series,
> > the driver has been modified to search the device tree for that
> > node
> > instead.
> > 
> > That property was also used to indicate the primary MDP device, so
> > that
> > it can be passed to the V4L2 subsystem as well as register it to be
> > used when setting up queues in the open() callback for the
> > filesystem
> > device node that is created. In this case, assuming that the
> > primary
> > MDP device is the one with a specific alias seems useable because
> > the
> > alternative is to add a property to the device tree which doesn't
> > actually represent any facet of hardware (i.e., this being the
> > primary
> > MDP device is a software decision). In other words, this solution
> > is
> > equally as arbitrary, but at least it doesn't add a property to a
> > device node where said property is unrelated to the hardware
> > present.
> > 
> > Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> > ---
> > 
> > (no changes since v1)
> > 
> >  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++--
> > ----
> >  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
> >  2 files changed, 64 insertions(+), 28 deletions(-)
> > 
> > diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> > b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> > index 85ef274841a3..9527649de98e 100644
> > --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> > +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> > @@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct
> > mtk_mdp_comp
> > *comp)
> >  		mtk_smi_larb_put(comp->larb_dev);
> >  }
> >  
> > -static int mtk_mdp_comp_bind(struct device *dev, struct device
> > *master, void *data)
> > +/*
> > + * The MDP master device node is identified by the device tree
> > alias
> > + * "mdp-rdma0".
> > + */
> > +static bool is_mdp_master(struct device *dev)
> > +{
> > +	struct device_node *aliases, *mdp_rdma0_node;
> > +	const char *mdp_rdma0_path;
> > +
> > +	if (!dev->of_node)
> > +		return false;
> > +
> > +	aliases = of_find_node_by_path("/aliases");
> > +	if (!aliases) {
> > +		dev_err(dev, "no aliases found for mdp-rdma0");
> > +		return false;
> > +	}
> > +
> > +	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
> > +	if (!mdp_rdma0_path) {
> > +		dev_err(dev, "get mdp-rdma0 property of /aliases
> > failed");
> > +		return false;
> > +	}
> > +
> > +	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
> > +	if (!mdp_rdma0_node) {
> > +		dev_err(dev, "path resolution failed for %s",
> > mdp_rdma0_path);
> > +		return false;
> > +	}
> > +
> 
> Hi Eizan,
> 
> "mdp-rdma0" may be not the only one master device node. In fact,
> there
> are 2 "mdp-rdma" in mt8173. You can see "mdp_rdma1" via below link.
> 
> 
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.13.11#n1016
> If we add "mediatek,mt8173-mdp" to "mdp_rdma1" like below, we will
> have
> one more V4L2 video devie node.
> 
> 		mdp_rdma1: rdma at 14002000 {
> 			compatible = "mediatek,mt8173-mdp-rdma",
> 				     "mediatek,mt8173-mdp";
> 			...
> 		}
> 
> We should consider the case that there are more than one "MDP_RDMA"
> components. 
> 
> Regards,
> Houlong
> 
> > +	return dev->of_node == mdp_rdma0_node;
> > +}
> > +
> > +static int mtk_mdp_comp_bind(struct device *dev, struct device
> > *master,
> > +			void *data)
> >  {
> >  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
> >  	struct mtk_mdp_dev *mdp = data;
> > -	struct device_node *vpu_node;
> >  
> >  	mtk_mdp_register_component(mdp, comp);
> >  
> > -	/*
> > -	 * If this component has a "mediatek-vpu" property, it is
> > responsible for
> > -	 * notifying the mdp master driver about it so it can be
> > further initialized
> > -	 * later.
> > -	 */
> > -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> > -	if (vpu_node) {
> > +	if (is_mdp_master(dev)) {
> >  		int ret;
> >  
> > -		mdp->vpu_dev = of_find_device_by_node(vpu_node);
> > -		if (WARN_ON(!mdp->vpu_dev)) {
> > -			dev_err(dev, "vpu pdev failed\n");
> > -			of_node_put(vpu_node);
> > -		}
> > -
> >  		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> >  		if (ret) {
> >  			dev_err(dev, "Failed to register v4l2
> > device\n");
> > @@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device
> > *dev,
> > struct device *master, void *da
> >  		}
> >  
> >  		/*
> > -		 * presence of the "mediatek,vpu" property in a device
> > node
> > -		 * indicates that it is the primary MDP rdma device and
> > MDP DMA
> > -		 * ops should be handled by its DMA callbacks.
> > +		 * MDP DMA ops will be handled by the DMA callbacks
> > associated with this
> > +		 * device;
> >  		 */
> >  		mdp->rdma_dev = dev;
> >  	}
> > diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> > b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> > index 50eafcc9993d..6a775463399c 100644
> > --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> > +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> > @@ -150,8 +150,9 @@ static void release_of(struct device *dev, void
> > *data)
> >  
> >  static int mtk_mdp_master_bind(struct device *dev)
> >  {
> > -	int status;
> >  	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> > +	struct device_node *vpu_node;
> > +	int status;
> >  
> >  	status = component_bind_all(dev, mdp);
> >  	if (status) {
> > @@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device
> > *dev)
> >  		goto err_component_bind_all;
> >  	}
> >  
> > -	if (mdp->vpu_dev) {
> > -		int ret = vpu_wdt_reg_handler(mdp->vpu_dev,
> > mtk_mdp_reset_handler, mdp,
> > -					  VPU_RST_MDP);
> > -		if (ret) {
> > -			dev_err(dev, "Failed to register reset
> > handler\n");
> > -			goto err_wdt_reg;
> > -		}
> > -	} else {
> > -		dev_err(dev, "no vpu_dev found\n");
> > +	if (mdp->rdma_dev == NULL) {
> > +		dev_err(dev, "Primary MDP device not found");
> > +		status = -ENODEV;
> > +		goto err_component_bind_all;
> > +	}
> > +
> > +	vpu_node = of_find_node_by_name(NULL, "vpu");
> > +	if (!vpu_node) {
> > +		dev_err(dev, "unable to find vpu node");
> > +		status = -ENODEV;
> > +		goto err_wdt_reg;
> > +	}

Hi Eizan,

Is your removing "mediatek,vpu" necessary for this series "Refactor MTK
MDP driver into core/components" ?

In some MediaTek projects (not upstream yet), the device-tree node name
"vpu" may be changed to something like "vpu0", "vpu1" or other name,
which depends on the implementation of "mtk-vpu" driver. We can specify
the different phandle to "mediatek,vpu" in .dtsi file. If we use
of_find_node_by_name() to get the vpu_node, we have to modify the name
string in different project.
If the answer of my previous questions is "No", I prefer to slow down
the modification of removing "mediatek,vpu".

Sorry for late reply.

Regards,
Houlong

> > +
> > +	mdp->vpu_dev = of_find_device_by_node(vpu_node);
> > +	if (!mdp->vpu_dev) {
> > +		dev_err(dev, "unable to find vpu device");
> > +		status = -ENODEV;
> > +		goto err_wdt_reg;
> > +	}
> > +
> > +	status = vpu_wdt_reg_handler(mdp->vpu_dev,
> > mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
> > +	if (status) {
> > +		dev_err(dev, "Failed to register reset handler\n");
> > +		goto err_wdt_reg;
> >  	}
> >  
> >  	status = mtk_mdp_register_m2m_device(mdp);
> > -- 
> > 2.32.0.554.ge1b32706d8-goog
> > 
> 
> 

From Matti.Vaittinen at fi.rohmeurope.com  Sun Aug 15 22:12:35 2021
From: Matti.Vaittinen at fi.rohmeurope.com (Vaittinen, Matti)
Date: Mon, 16 Aug 2021 05:12:35 +0000
Subject: [PATCH resend v6 0/3] power: supply: mt6360_charger: add MT6360
 charger support
In-Reply-To: <20210813171106.entpro4b6dstho4s@earth.universe>
References: <20210719033914.16990-1-gene.chen.richtek@gmail.com>
 <20210813155438.4ssph6deqksob2uv@earth.universe>
 <20210813155858.GD5209@sirena.org.uk>
 <20210813162029.q5slrkubelfy3mvh@earth.universe>
 <20210813163254.GF5209@sirena.org.uk>
 <20210813171106.entpro4b6dstho4s@earth.universe>
Message-ID: <8156a7d206e4c3c6392ada533f35d1309c66a8f2.camel@fi.rohmeurope.com>


On Fri, 2021-08-13 at 19:11 +0200, Sebastian Reichel wrote:
> Hi,
> 
> On Fri, Aug 13, 2021 at 05:32:54PM +0100, Mark Brown wrote:
> > On Fri, Aug 13, 2021 at 06:20:29PM +0200, Sebastian Reichel wrote:
> > > On Fri, Aug 13, 2021 at 04:58:58PM +0100, Mark Brown wrote:
> > > > We're still waiting for review from Matti on the linear ranges
> > > > bit -
> > > > normally that goes through the regulator tree, do you have a
> > > > tag to pull
> > > > in case of merge conflicts?
> > > He actually already provided his Rb in v5, Gene did not carry it
> > > over properly (I added it)

Thanks guys! I do _really_ appreciate you taking care of merging the
changes :)

Best Regards
	--Matti

From zajec5 at gmail.com  Sun Aug 15 22:14:18 2021
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Mon, 16 Aug 2021 07:14:18 +0200
Subject: [PATCH V3 RESEND] dt-bindings: mfd: add Broadcom CRU
In-Reply-To: <20210713094745.2586-1-zajec5@gmail.com>
References: <20210713094745.2586-1-zajec5@gmail.com>
Message-ID: <76a2cdb9-0d74-0dfc-7a78-a5c8022c643d@gmail.com>

Hi Lee,

On 13.07.2021 11:47, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> CRU is a block used in e.g. Northstar devices. It can be seen in the
> bcm5301x.dtsi and this binding documents its proper usage.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---
> V2: Use complete binding & change additionalProperties to false
> V3: Use clock-controller@ for clocks
> RESEND: Patch is ready for pushing now since 5.14-rc1 is out
> 
> Lee: last time I sent this patch you couldn't push it because of docs
> validation dependency on 3 following commits:
> ac5f8197d15c ("dt-bindings: pinctrl: convert Broadcom Northstar to the json-schema")
> 08e9fdfbb224 ("dt-bindings: thermal: brcm,ns-thermal: Convert to the json-schema")
> 8f711f68cffd ("dt-bindings: clock: brcm, iproc-clocks: convert to the json-schema")
> 
> All above commits made it into the 5.14-rc1.

let me kindly ask you about this patch as I don't see it in the
https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git/log/?h=for-mfd-next

Could you send it to Linus with your upcoming 5.15 pull req, please?


From rppt at kernel.org  Sun Aug 15 22:52:12 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 16 Aug 2021 08:52:12 +0300
Subject: [PATCH v5 1/9] MIPS: Avoid future duplicate elf core header
 reservation
In-Reply-To: <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>
Message-ID: <YRn9DHlB/pdNPJyP@kernel.org>

Hi Geert,

On Wed, Aug 11, 2021 at 10:50:59AM +0200, Geert Uytterhoeven wrote:
> Prepare for early_init_fdt_scan_reserved_mem() reserving the memory
> occupied by an elf core header described in the device tree.
> As arch_mem_init() calls early_init_fdt_scan_reserved_mem() before
> mips_reserve_vmcore(), the latter needs to check if the memory has
> already been reserved before.

Doing memblock_reserve() for the same region is usually fine, did you
encounter any issues without this patch?
 
> Note that mips_reserve_vmcore() cannot just be removed, as not all MIPS
> systems use DT.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> v5:
>   - New.
> ---
>  arch/mips/kernel/setup.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> index 23a140327a0bac1b..4693add05743d78b 100644
> --- a/arch/mips/kernel/setup.c
> +++ b/arch/mips/kernel/setup.c
> @@ -429,7 +429,8 @@ static void __init mips_reserve_vmcore(void)
>  	pr_info("Reserving %ldKB of memory at %ldKB for kdump\n",
>  		(unsigned long)elfcorehdr_size >> 10, (unsigned long)elfcorehdr_addr >> 10);
>  
> -	memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
> +	if (!memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)
> +		memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
>  #endif
>  }
>  
> -- 
> 2.25.1
> 

-- 
Sincerely yours,
Mike.


From wenst at chromium.org  Sun Aug 15 23:10:21 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 16 Aug 2021 14:10:21 +0800
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
Message-ID: <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>

On Thu, Aug 5, 2021 at 7:02 AM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Thu, Jul 29, 2021 at 11:43 AM Chen-Yu Tsai <wenst at chromium.org> wrote:
> > On Thu, Jul 29, 2021 at 4:23 PM zhiyong.tao <zhiyong.tao at mediatek.com> wrote:
>
> > > The rsel actual bias resistance of each setting is different in
> > > different IC. we think that the define "MTK_PULL_SET_RSEL_000" is more
> > > common for all different IC.
> >
> > I see. I personally prefer having things clearly described. I can
> > understand this might be an extra burden to support different chips
> > with different parameters, though this should be fairly straightforward
> > with lookup tables tied to the compatible strings.
> >
> > Let's see if Rob and Linus have anything to add.
>
> Not much. We have "soft pushed" for this to be described as generic
> as possible, using SI units (ohms). But we also allow vendor-specific
> numbers in this attribute. Especially when reverse engineering SoCs
> that the contributor don't really have specs on (example M1 Mac).
>
> The intent with the SI units is especially for people like you folks working
> with Chromium to be able to use different SoCs and not feel lost
> to a forest of different ways of doing things and associated
> mistakes because vendors have hopelessly idiomatic pin configs.

I'll take that as "use SI units whenever possible and reasonable".

Thanks.

ChenYu


From michal.simek at xilinx.com  Sun Aug 15 23:14:54 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 16 Aug 2021 08:14:54 +0200
Subject: [PATCH v3 2/2] arm64: zynqmp: Add support for Xilinx Kria SOM
 board
In-Reply-To: <YRbRcx0b+V0vAgA4@robh.at.kernel.org>
References: <cover.1628244703.git.michal.simek@xilinx.com>
 <e780a2fef00e78c44c21cf3b918631bf20262688.1628244703.git.michal.simek@xilinx.com>
 <YRbRcx0b+V0vAgA4@robh.at.kernel.org>
Message-ID: <390708be-f251-cb14-cd7e-7eec418a060c@xilinx.com>



On 8/13/21 10:09 PM, Rob Herring wrote:
> On Fri, Aug 06, 2021 at 12:12:08PM +0200, Michal Simek wrote:
>> There are couple of revisions of SOMs (k26) and associated carrier cards
>> (kv260).
>> SOM itself has two major versions:
>> sm-k26 - SOM with EMMC
>> smk-k26 - SOM without EMMC used on starter kit with preprogrammed firmware
>> in QSPI.
>>
>> SOMs are describing only devices available on the SOM or connections which
>> are described in specification (for example UART, fwuen).
>>
>> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
>> ---
>>
>> Changes in v3:
>> - Fix led node name
>> - Fix compatible string for xlnx,zynqmp-sk-kv260-revA/Y/Z
>> - Fix headers alignment
>> - Move USB3 PHY properties from DWC3 node to USB node - reported by Manish
>>   Narani
>> - Change dtb names generated with dtbo
>> - Fix emmc comment style
>> -
>>
>> Changes in v2:
>> - Use sugar syntax - reported by Geert
>> - Update copyright years
>> - Fix SD3.0 comment alignment
>> - Remove one newline from Makefile
>>
>> https://www.xilinx.com/products/som/kria.html
>> ---
>>  .../devicetree/bindings/arm/xilinx.yaml       |  31 ++
>>  arch/arm64/boot/dts/xilinx/Makefile           |  13 +
>>  .../boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts  | 335 ++++++++++++++++++
>>  .../boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts  | 318 +++++++++++++++++
>>  .../boot/dts/xilinx/zynqmp-sm-k26-revA.dts    | 289 +++++++++++++++
>>  .../boot/dts/xilinx/zynqmp-smk-k26-revA.dts   |  21 ++
>>  6 files changed, 1007 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dts
>>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
>>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-sm-k26-revA.dts
>>  create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-smk-k26-revA.dts
>>
>> diff --git a/Documentation/devicetree/bindings/arm/xilinx.yaml b/Documentation/devicetree/bindings/arm/xilinx.yaml
>> index a0b1ae6e3e71..31b86a6363b8 100644
>> --- a/Documentation/devicetree/bindings/arm/xilinx.yaml
>> +++ b/Documentation/devicetree/bindings/arm/xilinx.yaml
>> @@ -116,6 +116,37 @@ properties:
>>            - const: xlnx,zynqmp-zcu111
>>            - const: xlnx,zynqmp
>>  
>> +      - description: Xilinx Kria SOMs
>> +        items:
>> +          - const: xlnx,zynqmp-sm-k26-rev1
>> +          - const: xlnx,zynqmp-sm-k26-revB
>> +          - const: xlnx,zynqmp-sm-k26-revA
>> +          - const: xlnx,zynqmp-sm-k26
> 
> How is having all 4 strings useful? Seems like it should be only 1 of 
> the rev's at a time.

We have added eeprom on SOM and another one on carrier card.
And final DT is combination of them.
And I wanted to keep track which versions are compatible to each other
from software point of view.
revB is fully equal to rev1 HW and it is pretty much just change from
development version to production version.
revA compare to revB has some changes on PCB but still SW compatible.

That's why I wanted to keep track of all versions via compatible strings
and also Xilinx distribution based on this information creates symlinks
to the same DTB to pick up correct DTB based on revision written in eeprom.

Also I don't think this is going against compatible string description
written in DT spec.

"The compatible property value consists of one or more strings that
define the specific programming model for
the device. This list of strings should be used by a client program for
device driver selection. The property
value consists of a concatenated list of null terminated strings, from
most specific to most general. They
allow a device to express its compatibility with a family of similar
devices, potentially allowing a single
device driver to match against several devices."


<snip>

>> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
>> new file mode 100644
>> index 000000000000..df054e152a77
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dts
>> @@ -0,0 +1,318 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * dts file for KV260 revA Carrier Card
>> + *
>> + * (C) Copyright 2020 - 2021, Xilinx, Inc.
>> + *
>> + * Michal Simek <michal.simek at xilinx.com>
>> + */
>> +
>> +#include <dt-bindings/gpio/gpio.h>
>> +#include <dt-bindings/net/ti-dp83867.h>
>> +#include <dt-bindings/phy/phy.h>
>> +#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
>> +
>> +/dts-v1/;
>> +/plugin/;
>> +
>> +&{/} {
>> +	compatible = "xlnx,zynqmp-sk-kv260-rev1",
>> +		     "xlnx,zynqmp-sk-kv260-revB",
>> +		     "xlnx,zynqmp-sk-kv260", "xlnx,zynqmp";
> 
> I don't think changing the root compatible in an overlay is a good 
> policy. Do you need this all to be overlays?

Thanks for opening this up. DT overlay is applied in Linux now but in
near future we will have to apply it earlier in u-boot.
And the main question is if you want to see just SOM board compatible
string with k26 or carrier card compatible string (kv260).

I choose to rather see carrier card compatible string which is that
information which make difference. SOM variants are pretty much the
same. The different is only if EMMC is populated or not.
Different silicon is also recorded in eeprom but it can be detected and
sw is pretty much the same but don't need to be.

The boot works in a way that SOM is booting out of QSPI with only DT
with SOM description. Then carrier card is detected and DT overlay is
applied and never removed. And then in Linux other DT overlays are
applied and removed based on application you choose.

If you think that my thinking about carrier card compatible string is
horribly wrong I have no problem to remove them but I need to find a way
how to keep track of carrier revisions which are compatible with this
overlay.


> 
>> +};
>> +
>> +&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */
>> +	#address-cells = <1>;
>> +	#size-cells = <0>;
>> +	pinctrl-names = "default", "gpio";
>> +	pinctrl-0 = <&pinctrl_i2c1_default>;
>> +	pinctrl-1 = <&pinctrl_i2c1_gpio>;
>> +	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
>> +	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
>> +
>> +	u14: ina260 at 40 { /* u14 */
>> +		compatible = "ti,ina260";
> 
> Not documented. Please run 'make dtbs_check' and don't add new warnings.

I will remove it.
Did you get a warning? When I was looking at it it didn't come because
this is overlays. Was there any update which changed this?

> 
>> +		#io-channel-cells = <1>;
>> +		label = "ina260-u14";
>> +		reg = <0x40>;
>> +	};
>> +	usbhub: usb5744 at 2d { /* u43 */
>> +		compatible = "microchip,usb5744";
> 
> Not documented.

I will remove this one too.


Thanks,
Michal


From vijayakannan.ayyathurai at intel.com  Sun Aug 15 23:15:57 2021
From: vijayakannan.ayyathurai at intel.com (Vijayakannan Ayyathurai)
Date: Mon, 16 Aug 2021 14:15:57 +0800
Subject: [PATCH net-next v1 0/3] net: stmmac: Add ethtool per-queue statistic
Message-ID: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>

Adding generic ethtool per-queue statistic framework to display the
statistics for each rx/tx queue. In future, users can avail it to add
more per-queue specific counters. Number of rx/tx queues displayed is
depending on the available rx/tx queues in that particular MAC config
and this number is limited up to the MTL_MAX_{RX|TX}_QUEUES defined
in the driver.

Ethtool per-queue statistic display will look like below, when users
start adding more counters.

Example - 1:
 q0_tx_statA:
 q0_tx_statB:
 q0_tx_statC:
 |
 q0_tx_statX:
 .
 .
 .
 qMAX_tx_statA:
 qMAX_tx_statB:
 qMAX_tx_statC:
 |
 qMAX_tx_statX:

 q0_rx_statA:
 q0_rx_statB:
 q0_rx_statC:
 |
 q0_rx_statX:
 .
 .
 .
 qMAX_rx_statA:
 qMAX_rx_statB:
 qMAX_rx_statC:
 |
 qMAX_rx_statX:

Example - 2: Ping test using the tx queue 3.

$ tc qdisc add dev enp0s30f4 root mqprio num_tc 2 map 1 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 queues 3 at 0 1 at 3 hw 0

Statistic before ping:
---------------------
$ ethtool -S enp0s30f4

[ snip ]
     q3_tx_pkt_n: 7916
     q3_tx_irq_n: 316
[ snip ]

$ cat /proc/interrupts

[ snip ]
 143:          0          0          0        316          0          0

         0          0  IR-PCI-MSI 499719-edge      enp0s30f4:tx-3
[ snip ]

$ ping -I enp0s30f4 192.168.1.10 -i 0.01 -c 100 > /dev/null

Statistic after ping:
---------------------
$ ethtool -S enp0s30f4

[ snip ]
     q3_tx_pkt_n: 8016
     q3_tx_irq_n: 320
[ snip ]

$ cat /proc/interrupts

[ snip ]
143:          0          0          0        320          0          0

         0          0  IR-PCI-MSI 499719-edge      enp0s30f4:tx-3
[ snip ]

Vijayakannan Ayyathurai (2):
  net: stmmac: add ethtool per-queue statistic framework
  net: stmmac: add ethtool per-queue irq statistic support

Voon Weifeng (1):
  net: stmmac: fix INTR TBU status affecting irq count statistic

 drivers/net/ethernet/stmicro/stmmac/common.h  | 13 ++++
 .../net/ethernet/stmicro/stmmac/dwmac4_lib.c  |  7 +-
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 67 ++++++++++++++++++-
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  5 ++
 4 files changed, 89 insertions(+), 3 deletions(-)


base-commit: e4637f621203cb482f3ddb590cfe9f65045d92a6
-- 
2.17.1



From vijayakannan.ayyathurai at intel.com  Sun Aug 15 23:15:58 2021
From: vijayakannan.ayyathurai at intel.com (Vijayakannan Ayyathurai)
Date: Mon, 16 Aug 2021 14:15:58 +0800
Subject: [PATCH net-next v1 1/3] net: stmmac: fix INTR TBU status affecting
 irq count statistic
In-Reply-To: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
References: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
Message-ID: <f82f52076841285309a997f849e2786781548538.1629092894.git.vijayakannan.ayyathurai@intel.com>

From: Voon Weifeng <weifeng.voon at intel.com>

DMA channel status "Transmit buffer unavailable(TBU)" bit is not
considered as a successful dma tx. Hence, it should not affect
all the irq count statistic.

Fixes: 1103d3a5531c ("net: stmmac: dwmac4: Also use TBU interrupt to clean TX path")
Signed-off-by: Voon Weifeng <weifeng.voon at intel.com>
Signed-off-by: Vijayakannan Ayyathurai <vijayakannan.ayyathurai at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index e63270267578..f83db62938dd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -172,11 +172,12 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
 		x->rx_normal_irq_n++;
 		ret |= handle_rx;
 	}
-	if (likely(intr_status & (DMA_CHAN_STATUS_TI |
-		DMA_CHAN_STATUS_TBU))) {
+	if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
 		x->tx_normal_irq_n++;
 		ret |= handle_tx;
 	}
+	if (unlikely(intr_status & DMA_CHAN_STATUS_TBU))
+		ret |= handle_tx;
 	if (unlikely(intr_status & DMA_CHAN_STATUS_ERI))
 		x->rx_early_irq++;
 
-- 
2.17.1



From vijayakannan.ayyathurai at intel.com  Sun Aug 15 23:15:59 2021
From: vijayakannan.ayyathurai at intel.com (Vijayakannan Ayyathurai)
Date: Mon, 16 Aug 2021 14:15:59 +0800
Subject: [PATCH net-next v1 2/3] net: stmmac: add ethtool per-queue statistic
 framework
In-Reply-To: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
References: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
Message-ID: <b0fd3bf4e5c105e959df60d3c876297721b62ee6.1629092894.git.vijayakannan.ayyathurai@intel.com>

Adding generic ethtool per-queue statistic framework to display the
statistics for each rx/tx queue. In future, users can avail it to add
more per-queue specific counters. Number of rx/tx queues displayed is
depending on the available rx/tx queues in that particular MAC config
and this number is limited up to the MTL_MAX_{RX|TX}_QUEUES defined
in the driver.

Ethtool per-queue statistic display will look like below, when users
start adding more counters.

Example:
 q0_tx_statA:
 q0_tx_statB:
 q0_tx_statC:
 |
 q0_tx_statX:
 .
 .
 .
 qMAX_tx_statA:
 qMAX_tx_statB:
 qMAX_tx_statC:
 |
 qMAX_tx_statX:

 q0_rx_statA:
 q0_rx_statB:
 q0_rx_statC:
 |
 q0_rx_statX:
 .
 .
 .
 qMAX_rx_statA:
 qMAX_rx_statB:
 qMAX_rx_statC:
 |
 qMAX_rx_statX:

In addition, this patch has the support on displaying the number of
packets received and transmitted per queue.

Signed-off-by: Vijayakannan Ayyathurai <vijayakannan.ayyathurai at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h  | 11 ++++
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 65 ++++++++++++++++++-
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  5 ++
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 5fecc83f175b..79333deef2e2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -58,6 +58,14 @@
 #undef FRAME_FILTER_DEBUG
 /* #define FRAME_FILTER_DEBUG */
 
+struct stmmac_txq_stats {
+	unsigned long tx_pkt_n;
+};
+
+struct stmmac_rxq_stats {
+	unsigned long rx_pkt_n;
+};
+
 /* Extra statistic and debug information exposed by ethtool */
 struct stmmac_extra_stats {
 	/* Transmit errors */
@@ -189,6 +197,9 @@ struct stmmac_extra_stats {
 	unsigned long mtl_est_hlbf;
 	unsigned long mtl_est_btre;
 	unsigned long mtl_est_btrlm;
+	/* per queue statistics */
+	struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES];
+	struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES];
 };
 
 /* Safety Feature statistics exposed by ethtool */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index d0ce608b81c3..10c0895d0b43 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -261,6 +261,16 @@ static const struct stmmac_stats stmmac_mmc[] = {
 };
 #define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_mmc)
 
+static const char stmmac_qstats_tx_string[][ETH_GSTRING_LEN] = {
+	"tx_pkt_n",
+#define STMMAC_TXQ_STATS ARRAY_SIZE(stmmac_qstats_tx_string)
+};
+
+static const char stmmac_qstats_rx_string[][ETH_GSTRING_LEN] = {
+	"rx_pkt_n",
+#define STMMAC_RXQ_STATS ARRAY_SIZE(stmmac_qstats_rx_string)
+};
+
 static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
 				      struct ethtool_drvinfo *info)
 {
@@ -510,6 +520,31 @@ stmmac_set_pauseparam(struct net_device *netdev,
 	}
 }
 
+static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
+{
+	u32 tx_cnt = priv->plat->tx_queues_to_use;
+	u32 rx_cnt = priv->plat->rx_queues_to_use;
+	int q, stat;
+	char *p;
+
+	for (q = 0; q < tx_cnt; q++) {
+		p = (char *)priv + offsetof(struct stmmac_priv,
+					    xstats.txq_stats[q].tx_pkt_n);
+		for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
+			*data++ = (*(u64 *)p);
+			p += sizeof(u64 *);
+		}
+	}
+	for (q = 0; q < rx_cnt; q++) {
+		p = (char *)priv + offsetof(struct stmmac_priv,
+					    xstats.rxq_stats[q].rx_pkt_n);
+		for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
+			*data++ = (*(u64 *)p);
+			p += sizeof(u64 *);
+		}
+	}
+}
+
 static void stmmac_get_ethtool_stats(struct net_device *dev,
 				 struct ethtool_stats *dummy, u64 *data)
 {
@@ -560,16 +595,21 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
 		data[j++] = (stmmac_gstrings_stats[i].sizeof_stat ==
 			     sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
 	}
+	stmmac_get_per_qstats(priv, &data[j]);
 }
 
 static int stmmac_get_sset_count(struct net_device *netdev, int sset)
 {
 	struct stmmac_priv *priv = netdev_priv(netdev);
+	u32 tx_cnt = priv->plat->tx_queues_to_use;
+	u32 rx_cnt = priv->plat->rx_queues_to_use;
 	int i, len, safety_len = 0;
 
 	switch (sset) {
 	case ETH_SS_STATS:
-		len = STMMAC_STATS_LEN;
+		len = STMMAC_STATS_LEN +
+		      STMMAC_TXQ_STATS * tx_cnt +
+		      STMMAC_RXQ_STATS * rx_cnt;
 
 		if (priv->dma_cap.rmon)
 			len += STMMAC_MMC_STATS_LEN;
@@ -592,6 +632,28 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset)
 	}
 }
 
+static void stmmac_get_qstats_string(struct stmmac_priv *priv, u8 *data)
+{
+	u32 tx_cnt = priv->plat->tx_queues_to_use;
+	u32 rx_cnt = priv->plat->rx_queues_to_use;
+	int q, stat;
+
+	for (q = 0; q < tx_cnt; q++) {
+		for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
+			snprintf(data, ETH_GSTRING_LEN, "q%d_%s", q,
+				 stmmac_qstats_tx_string[stat]);
+			data += ETH_GSTRING_LEN;
+		}
+	}
+	for (q = 0; q < rx_cnt; q++) {
+		for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
+			snprintf(data, ETH_GSTRING_LEN, "q%d_%s", q,
+				 stmmac_qstats_rx_string[stat]);
+			data += ETH_GSTRING_LEN;
+		}
+	}
+}
+
 static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 {
 	int i;
@@ -622,6 +684,7 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 				ETH_GSTRING_LEN);
 			p += ETH_GSTRING_LEN;
 		}
+		stmmac_get_qstats_string(priv, p);
 		break;
 	case ETH_SS_TEST:
 		stmmac_selftest_get_strings(priv, p);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a2aa75cb184e..7b3fcf558603 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2500,6 +2500,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
 			} else {
 				priv->dev->stats.tx_packets++;
 				priv->xstats.tx_pkt_n++;
+				priv->xstats.txq_stats[queue].tx_pkt_n++;
 			}
 			if (skb)
 				stmmac_get_tx_hwtstamp(priv, p, skb);
@@ -5000,6 +5001,9 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
 
 	stmmac_finalize_xdp_rx(priv, xdp_status);
 
+	priv->xstats.rx_pkt_n += count;
+	priv->xstats.rxq_stats[queue].rx_pkt_n += count;
+
 	if (xsk_uses_need_wakeup(rx_q->xsk_pool)) {
 		if (failure || stmmac_rx_dirty(priv, queue) > 0)
 			xsk_set_rx_need_wakeup(rx_q->xsk_pool);
@@ -5287,6 +5291,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 	stmmac_rx_refill(priv, queue);
 
 	priv->xstats.rx_pkt_n += count;
+	priv->xstats.rxq_stats[queue].rx_pkt_n += count;
 
 	return count;
 }
-- 
2.17.1



From vijayakannan.ayyathurai at intel.com  Sun Aug 15 23:16:00 2021
From: vijayakannan.ayyathurai at intel.com (Vijayakannan Ayyathurai)
Date: Mon, 16 Aug 2021 14:16:00 +0800
Subject: [PATCH net-next v1 3/3] net: stmmac: add ethtool per-queue irq
 statistic support
In-Reply-To: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
References: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
Message-ID: <5c956016465b688a2679bd02da1f751046be189c.1629092894.git.vijayakannan.ayyathurai@intel.com>

Adding ethtool per-queue statistics support to show number of interrupts
generated at DMA tx and DMA rx. All the counters are incremented at
dwmac4_dma_interrupt function.

Signed-off-by: Vijayakannan Ayyathurai <vijayakannan.ayyathurai at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h         | 2 ++
 drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c     | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 79333deef2e2..b6d945ea903d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -60,10 +60,12 @@
 
 struct stmmac_txq_stats {
 	unsigned long tx_pkt_n;
+	unsigned long tx_normal_irq_n;
 };
 
 struct stmmac_rxq_stats {
 	unsigned long rx_pkt_n;
+	unsigned long rx_normal_irq_n;
 };
 
 /* Extra statistic and debug information exposed by ethtool */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
index f83db62938dd..9292a1fab7d3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
@@ -170,10 +170,12 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
 		x->normal_irq_n++;
 	if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
 		x->rx_normal_irq_n++;
+		x->rxq_stats[chan].rx_normal_irq_n++;
 		ret |= handle_rx;
 	}
 	if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
 		x->tx_normal_irq_n++;
+		x->txq_stats[chan].tx_normal_irq_n++;
 		ret |= handle_tx;
 	}
 	if (unlikely(intr_status & DMA_CHAN_STATUS_TBU))
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 10c0895d0b43..595c3ccdcbb7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -263,11 +263,13 @@ static const struct stmmac_stats stmmac_mmc[] = {
 
 static const char stmmac_qstats_tx_string[][ETH_GSTRING_LEN] = {
 	"tx_pkt_n",
+	"tx_irq_n",
 #define STMMAC_TXQ_STATS ARRAY_SIZE(stmmac_qstats_tx_string)
 };
 
 static const char stmmac_qstats_rx_string[][ETH_GSTRING_LEN] = {
 	"rx_pkt_n",
+	"rx_irq_n",
 #define STMMAC_RXQ_STATS ARRAY_SIZE(stmmac_qstats_rx_string)
 };
 
-- 
2.17.1



From hongbo.wang at nxp.com  Sun Aug 15 23:03:52 2021
From: hongbo.wang at nxp.com (Hongbo Wang)
Date: Mon, 16 Aug 2021 06:03:52 +0000
Subject: [EXT] Re: [PATCH v1] arm64: dts: fsl: ls1028a-rdb: Add dts file
 to choose swp5 as dsa master
In-Reply-To: <20210813140745.fwjkmixzgvikvffz@skbuf>
References: <20210813030155.23097-1-hongbo.wang@nxp.com>
 <YRZvItRlSpF2Xf+S@lunn.ch>
 <VI1PR04MB56773CC01AB86A8AA1A33F9AE1FA9@VI1PR04MB5677.eurprd04.prod.outlook.com>
 <20210813140745.fwjkmixzgvikvffz@skbuf>
Message-ID: <VI1PR04MB56777E60653203A471B9864EE1FD9@VI1PR04MB5677.eurprd04.prod.outlook.com>


> On Fri, Aug 13, 2021 at 01:56:53PM +0000, Hongbo Wang wrote:
> > > You will end up with two DT blobs with the same top level
> > > compatible. This is going to cause confusion. I suggest you add an
> > > additional top level compatible to make it clear this differs from
> > > the compatible = "fsl,ls1028a-rdb", "fsl,ls1028a" blob.
> > >
> > >    Andrew
> >
> > hi Andrew,
> >
> >   thanks for comments.
> >
> >   this "fsl-ls1028a-rdb-dsa-swp5-eno3.dts" is also for fsl-ls1028a-rdb
> > platform, the only difference with "fsl-ls1028a-rdb.dts" is that it
> > use swp5 as dsa master, not swp4, and it's based on
> > "fsl-ls1028a-rdb.dts", so I choose this manner, if "fsl-ls1028a-rdb.dts" has
> some modification for new version, this file don't need be changed.
> 
> I tend to agree with Hongbo. What confusion is it going to cause? It is
> fundamentally the same board, just an Ethernet port stopped having 'status =
> "disabled"' and another changed role, all inside of the SoC with no
> externally-visible change. If anything, I think that creating a new top-level
> compatible for each small change like this would create a bloat-fest of its own.
> 
> I was going to suggest as an alternative to define a device tree overlay file with
> the changes in the CPU port assignment, instead of defining a wholly new DTS
> for the LS1028A reference design board. But I am pretty sure that it is not
> possible to specify a /delete-property/ inside a device tree overlay file, so that
> won't actually work.

hi Vladimir,

  if don't specify "/delete-property/" in this dts file, the corresponding dtb will not work well,
so I add it to delete 'ethernet' property from mscc_felix_port4 explicitly.

thanks,
hongbo





From xinchao.zhao.kernelz at gmail.com  Sun Aug 15 23:22:26 2021
From: xinchao.zhao.kernelz at gmail.com (zhao xc)
Date: Sun, 15 Aug 2021 23:22:26 -0700
Subject: No subject
Message-ID: <CAP7CzPdXmwqp1c-7cQGoJZSLZeieWJEbt3_pcOd+t3eED85zEg@mail.gmail.com>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-arm-CONFIG_IP_NF_TARGET_LOG-not-exist-at-kernel-code.patch
Type: text/x-patch
Size: 2347 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210815/d3ec200e/attachment.bin>

From jay.xu at rock-chips.com  Sun Aug 15 23:26:28 2021
From: jay.xu at rock-chips.com (jay.xu at rock-chips.com)
Date: Mon, 16 Aug 2021 14:26:28 +0800
Subject: [PATCH v3 2/7] soc: rockchip: io-domain: add rk3568 support
References: <20210805120107.27007-1-michael.riesch@wolfvision.net>, 
 <20210805120107.27007-3-michael.riesch@wolfvision.net>, 
 <8008800c-c518-30d4-edcf-57566e7a1251@arm.com>, 
 <3206032.SvYEEZNnvj@diego>, 
 <2021080617460178513151@rock-chips.com>, 
 <41dbf032-c852-fbe4-befd-3dc89b24f4c9@arm.com>, 
 <CAMdYzYpw7RP+jbP_0HkVwAF8=b_k0oeti+h9214NtnjSfvT_ww@mail.gmail.com>
Message-ID: <202108161426279521354@rock-chips.com>

Hi?
--------------
jay.xu at rock-chips.com
>On Fri, Aug 6, 2021 at 6:28 AM Robin Murphy <robin.murphy at arm.com> wrote:
>>
>> On 2021-08-06 10:46, jay.xu at rock-chips.com wrote:
>> > Hi Heiko and Robin
>> >
>> > --------------
>> > jay.xu at rock-chips.com
>> >> Hi Robin,
>> >>
>> >> Am Donnerstag, 5. August 2021, 18:27:36 CEST schrieb Robin Murphy:
>> >>> On 2021-08-05 13:01, Michael Riesch wrote:
>> >>>> From: Jianqun Xu <jay.xu at rock-chips.com>
>> >>>>
>> >>>> The io-domain registers on RK3568 SoCs have three separated bits to
>> >>>> enable/disable the 1.8v/2.5v/3.3v power.
>> >>>>
>> >>>> This patch make the write to be a operation, allow rk3568 uses a private
>> >>>> register set function.
>> >>>>
>> >>>> Since the 2.5v is not used on RK3568, so the driver only set
>> >>>
>> >>> FWIW, this seems at odds with what the first paragraph says - can anyone
>> >>> clarify what exactly "not used" means here? Is it that the I/O domain
>> >>> controller has been redesigned to support more than two logic levels on
>> >>> the new generation of SoCs, but RK3568's I/O pads still only physically
>> >>> support 1.8v and 3.3v; or is it that it *can* support 2.5v as well but
>> >>> no currently-known RK3568-based designs use that?
>> >>>
>> >>> In the former case it's just a wording issue in the commit message, but
>> >>> in the latter it's arguably worth implementing support now for the sake
>> >>> of future compatibility.
>> >>
>> >> I hadn't looked that deeply into the rk356x io-domain config, but at least
>> >> on a register level in the TRM it seems there are separate bits for
>> >> "3.3V control", "2.5V control", "1.8V control" [0] for each io-domain.
>> >>
>> >> Of course the documentation is otherwise somewhat sparse.
>> >>
>> >> Maybe Jay or Kever [added] can explain a bit more about the 3 voltage
>> >> levels.
>> >>
>> >>
>> >> In general though, I tend to find the approach good enough for now.
>> >>
>> >> Especially as the io-domain stuff is always said to "can cause damage
>> >> to the soc if used incorrectly" and it looks like nobody (including
>> >> Rockchip) seems to have actual hardware using these 2.5V levels right now.
>> >>
>> >> So having code in there that no-one ever tested doesn't feel too good ;-)
>> >>
>> > yes
>> >
>> > about the 3bit
>> >
>> > case???? V33? V25? V18?????? result
>> > 0????????? 0????? 0?????? 0?????????? IO safe, but cannot work
>> > 1????????? 0????? 0?????? 1?????????? IO require 1.8V, should < 1.98V, otherwise IO may damage
>> > 2????????? 0????? 1?????? 0?????????? IO require 2.5V, should < 2.75V, otherwise IO may damage
>> > 3????????? 0????? 1?????? 1?????????? Invalid state, should avoid
>> > 4????????? 1????? 0?????? 0?????????? IO require 3.3V, should < 3.63V, otherwise IO may damage
>> > 5????????? 1????? 0?????? 1?????????? IO require 1.8V, should < 1.98V, otherwise IO may damage
>> > 6????????? 1????? 1?????? 0?????????? IO require 2.5V, should < 2.75V, otherwise IO may damage
>> > 7????????? 1????? 1?????? 1?????????? Invalid state, should avoid
>>
>> Thanks Jay, that's useful to know.
>>
>> Fair enough if it's the case that 2.5V mode hasn't been validated with
>> the BSP kernel either - I'd have no objection to clarifying the commit
>> message that way instead, I'm just a curious reviewer who noticed some
>> ambiguity :)
>>
>> >> Adding this later when needed should be somewhat easy, as it really only
>> >> needs adding of handling that 3rd control bit per domain.
>>
>> I'm mostly just thinking ahead a year or two when board designers have
>> ventured further away from the reference design and *are* using 2.5V
>> external components, then a user puts an older stable mainline kernel on
>> their board and starts tearing their hair out trying to figure out why
>> things are flaky. For instance I recall from my RK3328 box that if the
>> I/O domain setting for the GMAC is too high for the actual supply
>> voltage (such that it never detects MDIO responses from the external
>> phy) you end up getting an utterly nonsensical DMA error. In that case I
>> eventually figured out (by chance) that it was because I didn't have the
>> I/O domain driver enabled in my config, but it would be a whole other
>> level of frustration if the driver appeared to be working but was
>> quietly doing the wrong thing.
>
>I too have experienced the joys of io-domains breaking things.
>Perhaps the driver should warn when the voltages aren't expected,
>instead of when they are simply too high.
> 
The io-domain driver is so special, it is only rockchip soc driver, but it's so important for rockchip
system, lack of io-domain driver or wrong setting for system both breaking things

The one problem is lack of io-domain driver, since the dt node is defaultly be "disabled" in core.dtsi
If the board developer doesn't notice to enable it, the system will work without io-domain and can
hard to debug it.

So, could I summit a patch to set the dt node defaultly to be "okay" with empty property, and then
do a WARN when nothing property is found ?

>>
>> Cheers,
>> Robin.
>>
>> >>
>> >>
>> >> Heiko
>> >>
>> >>
>> >>
>> >> [0] what happens if none of the 3 is active? ;-)
>> >>
>> >>
>> >>>
>> >>> Robin.
>> >>>
>> >>>> 1.8v [enable] + 3.3v [disable] for 1.8v mode
>> >>>> 1.8v [disable] + 3.3v [enable] for 3.3v mode
>> >>>>
>> >>>> There is not register order requirement which has been cleared by our IC
>> >>>> team.
>> >>>>
>> >>>> Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
>> >>>> ---
>> >>>>???? drivers/soc/rockchip/io-domain.c | 88 +++++++++++++++++++++++++++++---
>> >>>>???? 1 file changed, 80 insertions(+), 8 deletions(-)
>> >>>>
>> >>>> diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
>> >>>> index cf8182fc3642..13c446fd33a9 100644
>> >>>> --- a/drivers/soc/rockchip/io-domain.c
>> >>>> +++ b/drivers/soc/rockchip/io-domain.c
>> >>>> @@ -51,13 +51,11 @@
>> >>>>???? #define RK3399_PMUGRF_CON0_VSEL??????? BIT(8)
>> >>>>???? #define RK3399_PMUGRF_VSEL_SUPPLY_NUM? 9
>> >>>>
>> >>>> -struct rockchip_iodomain;
>> >>>> +#define RK3568_PMU_GRF_IO_VSEL0?? (0x0140)
>> >>>> +#define RK3568_PMU_GRF_IO_VSEL1?? (0x0144)
>> >>>> +#define RK3568_PMU_GRF_IO_VSEL2?? (0x0148)
>> >>>>
>> >>>> -struct rockchip_iodomain_soc_data {
>> >>>> -? int grf_offset;
>> >>>> -? const char *supply_names[MAX_SUPPLIES];
>> >>>> -? void (*init)(struct rockchip_iodomain *iod);
>> >>>> -};
>> >>>> +struct rockchip_iodomain;
>> >>>>
>> >>>>???? struct rockchip_iodomain_supply {
>> >>>>???? struct rockchip_iodomain *iod;
>> >>>> @@ -66,13 +64,62 @@ struct rockchip_iodomain_supply {
>> >>>>???? int idx;
>> >>>>???? };
>> >>>>
>> >>>> +struct rockchip_iodomain_soc_data {
>> >>>> +? int grf_offset;
>> >>>> +? const char *supply_names[MAX_SUPPLIES];
>> >>>> +? void (*init)(struct rockchip_iodomain *iod);
>> >>>> +? int (*write)(struct rockchip_iodomain_supply *supply, int uV);
>> >>>> +};
>> >>>> +
>> >>>>???? struct rockchip_iodomain {
>> >>>>???? struct device *dev;
>> >>>>???? struct regmap *grf;
>> >>>>???? const struct rockchip_iodomain_soc_data *soc_data;
>> >>>>???? struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
>> >>>> +? int (*write)(struct rockchip_iodomain_supply *supply, int uV);
>> >>>>???? };
>> >>>>
>> >>>> +static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV)
>> >>>> +{
>> >>>> +? struct rockchip_iodomain *iod = supply->iod;
>> >>>> +? u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
>> >>>> +? u32 val0, val1;
>> >>>> +? int b;
>> >>>> +
>> >>>> +? switch (supply->idx) {
>> >>>> +? case 0: /* pmuio1 */
>> >>>> +? break;
>> >>>> +? case 1: /* pmuio2 */
>> >>>> +? b = supply->idx;
>> >>>> +? val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
>> >>>> +? b = supply->idx + 4;
>> >>>> +? val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
>> >>>> +
>> >>>> +? regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val0);
>> >>>> +? regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL2, val1);
>> >>>> +? break;
>> >>>> +? case 3: /* vccio2 */
>> >>>> +? break;
>> >>>> +? case 2: /* vccio1 */
>> >>>> +? case 4: /* vccio3 */
>> >>>> +? case 5: /* vccio4 */
>> >>>> +? case 6: /* vccio5 */
>> >>>> +? case 7: /* vccio6 */
>> >>>> +? case 8: /* vccio7 */
>> >>>> +? b = supply->idx - 1;
>> >>>> +? val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
>> >>>> +? val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);
>> >>>> +
>> >>>> +? regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL0, val0);
>> >>>> +? regmap_write(iod->grf, RK3568_PMU_GRF_IO_VSEL1, val1);
>> >>>> +? break;
>> >>>> +? default:
>> >>>> +? return -EINVAL;
>> >>>> +? };
>> >>>> +
>> >>>> +? return 0;
>> >>>> +}
>> >>>> +
>> >>>>???? static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
>> >>>>??????? int uV)
>> >>>>???? {
>> >>>> @@ -136,7 +183,7 @@ static int rockchip_iodomain_notify(struct notifier_block *nb,
>> >>>>???? return NOTIFY_BAD;
>> >>>>???? }
>> >>>>
>> >>>> -? ret = rockchip_iodomain_write(supply, uV);
>> >>>> +? ret = supply->iod->write(supply, uV);
>> >>>>???? if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
>> >>>>???? return NOTIFY_BAD;
>> >>>>
>> >>>> @@ -398,6 +445,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
>> >>>>???? .init = rk3399_pmu_iodomain_init,
>> >>>>???? };
>> >>>>
>> >>>> +static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
>> >>>> +? .grf_offset = 0x140,
>> >>>> +? .supply_names = {
>> >>>> +? "pmuio1",
>> >>>> +? "pmuio2",
>> >>>> +? "vccio1",
>> >>>> +? "vccio2",
>> >>>> +? "vccio3",
>> >>>> +? "vccio4",
>> >>>> +? "vccio5",
>> >>>> +? "vccio6",
>> >>>> +? "vccio7",
>> >>>> +? },
>> >>>> +? .write = rk3568_iodomain_write,
>> >>>> +};
>> >>>> +
>> >>>>???? static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
>> >>>>???? .grf_offset = 0x404,
>> >>>>???? .supply_names = {
>> >>>> @@ -469,6 +532,10 @@ static const struct of_device_id rockchip_iodomain_match[] = {
>> >>>>???? .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
>> >>>>???? .data = &soc_data_rk3399_pmu
>> >>>>???? },
>> >>>> +? {
>> >>>> +? .compatible = "rockchip,rk3568-pmu-io-voltage-domain",
>> >>>> +? .data = &soc_data_rk3568_pmu
>> >>>> +? },
>> >>>>???? {
>> >>>>???? .compatible = "rockchip,rv1108-io-voltage-domain",
>> >>>>???? .data = &soc_data_rv1108
>> >>>> @@ -502,6 +569,11 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>> >>>>???? match = of_match_node(rockchip_iodomain_match, np);
>> >>>>???? iod->soc_data = match->data;
>> >>>>
>> >>>> +? if (iod->soc_data->write)
>> >>>> +? iod->write = iod->soc_data->write;
>> >>>> +? else
>> >>>> +? iod->write = rockchip_iodomain_write;
>> >>>> +
>> >>>>???? parent = pdev->dev.parent;
>> >>>>???? if (parent && parent->of_node) {
>> >>>>???? iod->grf = syscon_node_to_regmap(parent->of_node);
>> >>>> @@ -562,7 +634,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
>> >>>>???? supply->reg = reg;
>> >>>>???? supply->nb.notifier_call = rockchip_iodomain_notify;
>> >>>>
>> >>>> -? ret = rockchip_iodomain_write(supply, uV);
>> >>>> +? ret = iod->write(supply, uV);
>> >>>>???? if (ret) {
>> >>>>???? supply->reg = NULL;
>> >>>>???? goto unreg_notify;
>> >>>>
>> >>>
>> >>
>> >>
>> >>
>> >>
>> >>
>> >>
>> >>
>> >
>
>
>

From michal.simek at xilinx.com  Sun Aug 15 23:27:45 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 16 Aug 2021 08:27:45 +0200
Subject: [PATCH V2 2/3] dt-bindings: gpio: zynqmp: Add binding
 documentation for modepin
In-Reply-To: <YRbBnRS0VosXcZWz@robh.at.kernel.org>
References: <20210805174219.3000667-1-piyush.mehta@xilinx.com>
 <20210805174219.3000667-3-piyush.mehta@xilinx.com>
 <YRbBnRS0VosXcZWz@robh.at.kernel.org>
Message-ID: <d71ad7f9-6972-8cc0-6dfb-b5306c9900d0@xilinx.com>



On 8/13/21 9:01 PM, Rob Herring wrote:
> On Thu, Aug 05, 2021 at 11:12:18PM +0530, Piyush Mehta wrote:
>> This patch adds DT binding document for zynqmp modepin GPIO controller.
>> Modepin GPIO controller has four GPIO pins which can be configurable
>> as input or output.
>>
>> Modepin driver is a bridge between the peripheral driver and GPIO pins.
>> It has set and get APIs for accessing GPIO pins, based on the device-tree
>> entry of reset-gpio property in the peripheral driver, every pin can be
>> configured as input/output and trigger GPIO pin.
>>
>> For more information please refer zynqMp TRM link:
>> Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
>> Chapter 2: Signals, Interfaces, and Pins
>> Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE
>>
>> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
>> ---
>> Changes in v2:
>> - Addressed review comments: Update commit message
>>
>> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
>> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736
>> ---
>>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
>>  1 file changed, 41 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>> new file mode 100644
>> index 0000000..39d78f8
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>> @@ -0,0 +1,41 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: "http://devicetree.org/schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml#"
>> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
>> +
>> +title: ZynqMP Mode Pin GPIO controller
>> +
>> +description:
>> +  PS_MODE is 4-bits boot mode pins sampled on POR deassertion. Mode Pin
>> +  GPIO controller with configurable from numbers of pins (from 0 to 3 per
>> +  PS_MODE). Every pin can be configured as input/output.
>> +
>> +maintainers:
>> +  - Piyush Mehta <piyush.mehta at xilinx.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: xlnx,zynqmp-gpio-modepin
>> +
>> +  gpio-controller: true
>> +
>> +  "#gpio-cells":
>> +    const: 2
>> +
>> +required:
>> +  - compatible
>> +  - gpio-controller
>> +  - "#gpio-cells"
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    modepin_gpio: gpio {
>> +        compatible = "xlnx,zynqmp-gpio-modepin";
>> +        gpio-controller;
>> +        #gpio-cells = <2>;
> 
> No way to interact with this h/w?
> 
> As it is part of the firmware interface, it must be a child node in the 
> firmware node schema.

Actually it is there. Only example is not showing this properly.
https://github.com/Xilinx/u-boot-xlnx/blob/master/arch/arm/dts/zynqmp.dtsi#L250

Piyush: Can you please do it as we have done with pinctrl.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml?h=v5.14-rc6#n301

like this

zynqmp_firmware: zynqmp-firmware {
    modepin_gpio: gpio {
        compatible = "xlnx,zynqmp-gpio-modepin";
        gpio-controller;
        #gpio-cells = <2>;
    };
};

That dt labels can be also removed because they are not needed in example.

Thanks,
Michal


From claudiu.beznea at microchip.com  Sun Aug 15 23:44:09 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 09:44:09 +0300
Subject: [PATCH v2 0/7] ARM: dts: at91: add Exegin Q5xR5 and CalAmp LMU5000
Message-ID: <20210816064416.1630674-1-claudiu.beznea@microchip.com>

Hi,

This series adds support for Exegin Q5xR5 and CalAmp LMU5000 boards
which were maintained up to this moment, separatelly, in OpenWrt tree.
With these patches the support for these boards will be included in
upstream kernel and there will be no need to forward port the proper
patches in OpenWrt every time the OpenWrt kernel version is changed.

Thank you,
Claudiu Beznea

Changes in v2:
- swapped commit message and diff b/w patches
  "dt-bindings: ARM: at91: document exegin q5xr5 board" and
  "dt-bindings: ARM: at91: document CalAmp LMU5000 board"
- re-ordered patches to accommodate the above swapping
- collected tags

Adam Porter (1):
  ARM: dts: at91: add CalAmp LMU5000 board

Claudiu Beznea (5):
  ARM: dts: at91: at91sam9260: add pinctrl label
  dt-bindings: add vendor prefix for calamp
  dt-bindings: ARM: at91: document CalAmp LMU5000 board
  dt-bindings: add vendor prefix for exegin
  dt-bindings: ARM: at91: document exegin q5xr5 board

Owen Kirby (1):
  ARM: dts: at91: add Exegin Q5xR5 board

 .../devicetree/bindings/arm/atmel-at91.yaml   |  12 ++
 .../devicetree/bindings/vendor-prefixes.yaml  |   4 +
 arch/arm/boot/dts/Makefile                    |   2 +
 arch/arm/boot/dts/at91-lmu5000.dts            | 148 +++++++++++++
 arch/arm/boot/dts/at91-q5xr5.dts              | 200 ++++++++++++++++++
 arch/arm/boot/dts/at91sam9260.dtsi            |   2 +-
 6 files changed, 367 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/at91-lmu5000.dts
 create mode 100644 arch/arm/boot/dts/at91-q5xr5.dts

-- 
2.25.1



From claudiu.beznea at microchip.com  Sun Aug 15 23:44:10 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 09:44:10 +0300
Subject: [PATCH v2 1/7] ARM: dts: at91: at91sam9260: add pinctrl label
In-Reply-To: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
Message-ID: <20210816064416.1630674-2-claudiu.beznea@microchip.com>

Add label for pinctrl node.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91sam9260.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index 019f1c3d4d30..7368347c9357 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -166,7 +166,7 @@ tcb1: timer at fffdc000 {
 				clock-names = "t0_clk", "t1_clk", "t2_clk", "slow_clk";
 			};
 
-			pinctrl at fffff400 {
+			pinctrl: pinctrl at fffff400 {
 				#address-cells = <1>;
 				#size-cells = <1>;
 				compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
-- 
2.25.1



From claudiu.beznea at microchip.com  Sun Aug 15 23:44:11 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 09:44:11 +0300
Subject: [PATCH v2 2/7] dt-bindings: add vendor prefix for calamp
In-Reply-To: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
Message-ID: <20210816064416.1630674-3-claudiu.beznea@microchip.com>

Add vendor prefix for CalAmp Corp.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 07fb0d25fc15..8cf2ed41537a 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -191,6 +191,8 @@ patternProperties:
     description: B&R Industrial Automation GmbH
   "^bticino,.*":
     description: Bticino International
+  "^calamp,.*":
+    description: CalAmp Corp.
   "^calaosystems,.*":
     description: CALAO Systems SAS
   "^calxeda,.*":
-- 
2.25.1



From claudiu.beznea at microchip.com  Sun Aug 15 23:44:12 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 09:44:12 +0300
Subject: [PATCH v2 3/7] dt-bindings: ARM: at91: document CalAmp LMU5000 board
In-Reply-To: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
Message-ID: <20210816064416.1630674-4-claudiu.beznea@microchip.com>

Document CalAmp LMU5000.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index fba071b9af1d..a9ab18510fef 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -126,6 +126,12 @@ properties:
           - const: atmel,sama5d3
           - const: atmel,sama5
 
+      - description: CalAmp LMU5000 board
+        items:
+          - const: calamp,lmu5000
+          - const: atmel,at91sam9g20
+          - const: atmel,at91sam9
+
       - items:
           - enum:
               - atmel,sama5d31
-- 
2.25.1



From claudiu.beznea at microchip.com  Sun Aug 15 23:44:13 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 09:44:13 +0300
Subject: [PATCH v2 4/7] ARM: dts: at91: add CalAmp LMU5000 board
In-Reply-To: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
Message-ID: <20210816064416.1630674-5-claudiu.beznea@microchip.com>

From: Adam Porter <porter.adam at gmail.com>

Add CalAmp LMU5000 board. The base device tree is from OpenWrt tree and
with the addition of this patch there will be no need to maintain it
separatelly in OpenWrt.

[porter.adam: original author of patch in OpenWrt]
Signed-off-by: Adam Porter <porter.adam at gmail.com>
[claudiu.beznea: fixed compilation warnings, use &<lable> syntax,
 sorted nodes in alphabetical order, adapted flash to new support
 in kernel 5.14, use proper compatibles according to kernel 5.14,
 use macros instead of hard coded numbers for pinctrl phandles and
 for all pinctrl references, add pinctrl-names, pinctrl-X where
 necessary]
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/Makefile         |   1 +
 arch/arm/boot/dts/at91-lmu5000.dts | 148 +++++++++++++++++++++++++++++
 2 files changed, 149 insertions(+)
 create mode 100644 arch/arm/boot/dts/at91-lmu5000.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 63b60f571035..249216d4a145 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -25,6 +25,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
 	usb_a9263.dtb \
 	at91-foxg20.dtb \
 	at91-kizbox.dtb \
+	at91-lmu5000.dtb \
 	at91sam9g20ek.dtb \
 	at91sam9g20ek_2mmc.dtb \
 	tny_a9g20.dtb \
diff --git a/arch/arm/boot/dts/at91-lmu5000.dts b/arch/arm/boot/dts/at91-lmu5000.dts
new file mode 100644
index 000000000000..6a52728cc98f
--- /dev/null
+++ b/arch/arm/boot/dts/at91-lmu5000.dts
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Device Tree file for CalAmp LMU5000 board
+ *
+ * Copyright (C) 2013 Adam Porter <porter.adam at gmail.com>
+ */
+
+/dts-v1/;
+#include "at91sam9g20.dtsi"
+
+/ {
+	model = "CalAmp LMU5000";
+	compatible = "calamp,lmu5000", "atmel,at91sam9g20", "atmel,at91sam9";
+
+	chosen {
+		bootargs = "mem=64M console=ttyS0,115200 rootfstype=jffs2";
+	};
+
+	memory {
+		reg = <0x20000000 0x4000000>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		main_clock: clock at 0 {
+			compatible = "atmel,osc", "fixed-clock";
+			clock-frequency = <18432000>;
+		};
+	};
+};
+
+&dbgu {
+	status = "okay";
+};
+
+&ebi {
+	status = "okay";
+
+	nand_controller: nand-controller {
+		pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>;
+		pinctrl-names = "default";
+		status = "okay";
+
+		nand at 3 {
+			reg = <0x3 0x0 0x800000>;
+			rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>;
+			cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>;
+			nand-bus-width = <8>;
+			nand-ecc-mode = "soft";
+			nand-on-flash-bbt;
+			label = "atmel_nand";
+			status = "okay";
+
+			partitions {
+				compatible = "fixed-partitions";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				kernel at 0 {
+					label = "kernel";
+					reg = <0x0 0x400000>;
+				};
+
+				rootfs at 400000 {
+					label = "rootfs";
+					reg = <0x400000 0x3C00000>;
+				};
+
+				user1 at 4000000 {
+					label = "user1";
+					reg = <0x4000000 0x2000000>;
+				};
+
+				user2 at 6000000 {
+					label = "user2";
+					reg = <0x6000000 0x2000000>;
+				};
+			};
+		};
+	};
+};
+
+&macb0 {
+	phy-mode = "mii";
+	status = "okay";
+};
+
+&pinctrl {
+	board {
+		pinctrl_pck0_as_mck: pck0_as_mck {
+			atmel,pins = <AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+		};
+	};
+
+	usb0 {
+		pinctrl_usb1_vbus_gpio: usb0_vbus_gpio {
+			atmel,pins = <AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+		};
+	};
+};
+
+&ssc0 {
+	status = "okay";
+	pinctrl-0 = <&pinctrl_ssc0_tx>;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&usart0 {
+	pinctrl-0 =
+		<&pinctrl_usart0
+		 &pinctrl_usart0_rts
+		 &pinctrl_usart0_cts
+		 &pinctrl_usart0_dtr_dsr
+		 &pinctrl_usart0_dcd
+		 &pinctrl_usart0_ri>;
+	status = "okay";
+};
+
+&usart2 {
+	status = "okay";
+};
+
+&usb0 {
+	num-ports = <2>;
+	status = "okay";
+};
+
+&usb1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb1_vbus_gpio>;
+	atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&watchdog {
+	status = "okay";
+};
+
-- 
2.25.1



From Claudiu.Beznea at microchip.com  Sun Aug 15 23:46:39 2021
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Mon, 16 Aug 2021 06:46:39 +0000
Subject: [PATCH 0/4] mmc: pwrseq: sd8787: add support for selectable
In-Reply-To: <YRbU3NtbYamh7UGH@robh.at.kernel.org>
References: <20210806113001.821660-1-claudiu.beznea@microchip.com>
 <YRbU3NtbYamh7UGH@robh.at.kernel.org>
Message-ID: <ce9e6c0c-6ed8-b039-f5b4-67766ecb595a@microchip.com>

On 13.08.2021 23:23, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Fri, Aug 06, 2021 at 02:29:57PM +0300, Claudiu Beznea wrote:
>> Hi,
>>
>> This series adds support for selecting the delay b/w reset and power
>> lines on pwrseq-sd8787. With this the driver could also be used by
>> other devices (e.g. WILC1000/WILC3000 which needs a delay of 5ms). Along
>> with this added the DT bindings for WILC3000 device present on
>> SAMA5D27 WLSOM1 board.
> 
> A 300ms delay doesn't work?

It should work as the datasheet specifies a minimum of 5ms is necessary.

> Is powering on the device so timing
> critical?
> 
> Add a new compatible for your device and imply the timing from that.
> That way we're not extending the binding a property at a time in a
> poorly designed way for each new timing quirk.

OK, will do it in v2.

Thank you for your review,
Claudiu Beznea

> 
> Rob
> 


From claudiu.beznea at microchip.com  Sun Aug 15 23:44:14 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 09:44:14 +0300
Subject: [PATCH v2 5/7] dt-bindings: add vendor prefix for exegin
In-Reply-To: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
Message-ID: <20210816064416.1630674-6-claudiu.beznea@microchip.com>

Add vendor prefix for Exegin Technologies Limited.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 8cf2ed41537a..61fe4778498d 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -393,6 +393,8 @@ patternProperties:
     description: Exar Corporation
   "^excito,.*":
     description: Excito
+  "^exegin,.*":
+    description: Exegin Technologies Limited
   "^ezchip,.*":
     description: EZchip Semiconductor
   "^facebook,.*":
-- 
2.25.1



From claudiu.beznea at microchip.com  Sun Aug 15 23:44:15 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 09:44:15 +0300
Subject: [PATCH v2 6/7] dt-bindings: ARM: at91: document exegin q5xr5 board
In-Reply-To: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
Message-ID: <20210816064416.1630674-7-claudiu.beznea@microchip.com>

Document Exegin Q5xR5 board.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index a9ab18510fef..08efb259a947 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -132,6 +132,12 @@ properties:
           - const: atmel,at91sam9g20
           - const: atmel,at91sam9
 
+      - description: Exegin Q5xR5 board
+        items:
+          - const: exegin,q5xr5
+          - const: atmel,at91sam9g20
+          - const: atmel,at91sam9
+
       - items:
           - enum:
               - atmel,sama5d31
-- 
2.25.1



From claudiu.beznea at microchip.com  Sun Aug 15 23:44:16 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 09:44:16 +0300
Subject: [PATCH v2 7/7] ARM: dts: at91: add Exegin Q5xR5 board
In-Reply-To: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
Message-ID: <20210816064416.1630674-8-claudiu.beznea@microchip.com>

From: Owen Kirby <osk at exegin.com>

Add Exegin Q5xR5. The base device tree is from OpenWrt tree and with
the addition of this patch there will be no need to maintain it
separatelly in OpenWrt.

[osk: original author of patch in OpenWrt]
Signed-off-by: Owen Kirby <osk at exegin.com>
[claudiu.beznea: use "&<label> {" syntax, sorted nodes in alphabetical
 order, adapted flash to new support in kernel 5.14, use proper
 compatibles according to kernel 5.14, use macros instead of
 hardcoded numbers for pinctrl phandles and for all pinctrl references,
 add pinctrl-names, pinctrl-X where necessaray]
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/Makefile       |   1 +
 arch/arm/boot/dts/at91-q5xr5.dts | 200 +++++++++++++++++++++++++++++++
 2 files changed, 201 insertions(+)
 create mode 100644 arch/arm/boot/dts/at91-q5xr5.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 249216d4a145..07be55262516 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -41,6 +41,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
 	at91-kizboxmini-base.dtb \
 	at91-kizboxmini-mb.dtb \
 	at91-kizboxmini-rd.dtb \
+	at91-q5xr5.dtb \
 	at91-smartkiz.dtb \
 	at91-wb45n.dtb \
 	at91sam9g15ek.dtb \
diff --git a/arch/arm/boot/dts/at91-q5xr5.dts b/arch/arm/boot/dts/at91-q5xr5.dts
new file mode 100644
index 000000000000..4866f1c6ccf9
--- /dev/null
+++ b/arch/arm/boot/dts/at91-q5xr5.dts
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Device Tree file for Exegin Q5xR5 board
+ *
+ * Copyright (C) 2014 Owen Kirby <osk at exegin.com>
+ */
+
+/dts-v1/;
+#include "at91sam9g20.dtsi"
+
+/ {
+	model = "Exegin Q5x (rev5)";
+	compatible = "exegin,q5xr5", "atmel,at91sam9g20", "atmel,at91sam9";
+
+	chosen {
+		bootargs = "console=ttyS0,115200 rootfstype=squashfs,jffs2";
+	};
+
+	memory {
+		reg = <0x20000000 0x0>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		main_clock: clock at 0 {
+			compatible = "atmel,osc", "fixed-clock";
+			clock-frequency = <18432000>;
+		};
+
+		slow_xtal {
+			clock-frequency = <32768>;
+		};
+
+		main_xtal {
+			clock-frequency = <18432000>;
+		};
+	};
+};
+
+&dbgu {
+	status = "okay";
+};
+
+&ebi {
+	status = "okay";
+
+	flash: flash at 0 {
+		compatible = "cfi-flash";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x0 0x1000000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			kernel at 0 {
+				label = "kernel";
+				reg = <0x0 0x200000>;
+			};
+
+			rootfs at 200000 {
+				label = "rootfs";
+				reg = <0x200000 0x600000>;
+			};
+		};
+	};
+};
+
+&macb0 {
+	phy-mode = "mii";
+	status = "okay";
+};
+
+&pinctrl {
+	board {
+		pinctrl_pck0_as_mck: pck0_as_mck {
+			atmel,pins = <AT91_PIOC 1 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+		};
+	};
+
+	spi0 {
+		pinctrl_spi0: spi0-0 {
+			atmel,pins =
+				<AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_NONE
+				 AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE
+				 AT91_PIOA 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+
+		pinctrl_spi0_npcs0: spi0_npcs0 {
+			atmel,pins = <AT91_PIOA 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+
+		pinctrl_spi0_npcs1: spi0_npcs1 {
+			atmel,pins = <AT91_PIOC 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+		};
+	};
+
+	spi1 {
+		pinctrl_spi1: spi1-0 {
+			atmel,pins =
+				<AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE
+				 AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE
+				 AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+
+		pinctrl_spi1_npcs0: spi1_npcs0 {
+			atmel,pins = <AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+		};
+
+		pinctrl_spi1_npcs1: spi1_npcs1 {
+			atmel,pins = <AT91_PIOC 5 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+		};
+	};
+};
+
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi0 &pinctrl_spi0_npcs0 &pinctrl_spi0_npcs1>;
+	cs-gpios = <&pioA 3 GPIO_ACTIVE_HIGH>, <&pioC 11 GPIO_ACTIVE_LOW>, <0>, <0>;
+	status = "okay";
+
+	m25p80 at 0 {
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <20000000>;
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		at91boot at 0 {
+			label = "at91boot";
+			reg = <0x0 0x4000>;
+		};
+
+		uenv at 4000 {
+			label = "uboot-env";
+			reg = <0x4000 0x4000>;
+		};
+
+		uboot at 8000 {
+			label = "uboot";
+			reg = <0x8000 0x3E000>;
+		};
+	};
+
+	spidev at 1 {
+		compatible = "spidev";
+		spi-max-frequency = <2000000>;
+		reg = <1>;
+	};
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi1 &pinctrl_spi1_npcs0 &pinctrl_spi1_npcs1>;
+	cs-gpios = <&pioB 3 GPIO_ACTIVE_HIGH>, <&pioC 5 GPIO_ACTIVE_LOW>, <0>, <0>;
+	status = "okay";
+
+	spidev at 0 {
+		compatible = "spidev";
+		spi-max-frequency = <2000000>;
+		reg = <0>;
+	};
+
+	spidev at 1 {
+		compatible = "spidev";
+		spi-max-frequency = <2000000>;
+		reg = <1>;
+	};
+};
+
+&usart0 {
+	pinctrl-0 =
+		<&pinctrl_usart0
+		 &pinctrl_usart0_rts
+		 &pinctrl_usart0_cts
+		 &pinctrl_usart0_dtr_dsr
+		 &pinctrl_usart0_dcd
+		 &pinctrl_usart0_ri>;
+	status = "okay";
+};
+
+&usb0 {
+	num-ports = <2>;
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
+
+&watchdog {
+	status = "okay";
+};
+
-- 
2.25.1



From qiangqing.zhang at nxp.com  Sun Aug 15 23:48:49 2021
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Mon, 16 Aug 2021 06:48:49 +0000
Subject: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
 wakeup-irq" property
In-Reply-To: <YRa4g8cjGrQ979pQ@robh.at.kernel.org>
References: <20210805074615.29096-1-qiangqing.zhang@nxp.com>
 <20210805074615.29096-2-qiangqing.zhang@nxp.com>
 <2e1a14bf-2fa8-ed39-d133-807c4e14859c@gmail.com>
 <DB8PR04MB67950F6863A8FEE6745CBC68E6F69@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <498f3cee-8f37-2ab1-93c4-5472572ecc37@gmail.com>
 <DB8PR04MB6795DC35D0387637052E64A1E6F79@DB8PR04MB6795.eurprd04.prod.outlook.com>
 <YRKOGYwx1uVdsKoF@lunn.ch>
 <VI1PR04MB6800EE08F70CC3F0DD53C991E6F89@VI1PR04MB6800.eurprd04.prod.outlook.com>
 <YRa4g8cjGrQ979pQ@robh.at.kernel.org>
Message-ID: <DB8PR04MB679595375E757DEBD569C7EFE6FD9@DB8PR04MB6795.eurprd04.prod.outlook.com>


> -----Original Message-----
> From: Rob Herring <robh at kernel.org>
> Sent: 2021?8?14? 2:23
> To: Joakim Zhang <qiangqing.zhang at nxp.com>
> Cc: Andrew Lunn <andrew at lunn.ch>; Florian Fainelli <f.fainelli at gmail.com>;
> davem at davemloft.net; kuba at kernel.org; shawnguo at kernel.org;
> s.hauer at pengutronix.de; festevam at gmail.com; kernel at pengutronix.de;
> dl-linux-imx <linux-imx at nxp.com>; netdev at vger.kernel.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add "fsl,
> wakeup-irq" property
> 
> On Wed, Aug 11, 2021 at 07:57:46AM +0000, Joakim Zhang wrote:
> >
> > Hi Andrew,
> >
> > > -----Original Message-----
> > > From: Andrew Lunn <andrew at lunn.ch>
> > > Sent: 2021?8?10? 22:33
> > > To: Joakim Zhang <qiangqing.zhang at nxp.com>
> > > Cc: Florian Fainelli <f.fainelli at gmail.com>; davem at davemloft.net;
> > > kuba at kernel.org; robh+dt at kernel.org; shawnguo at kernel.org;
> > > s.hauer at pengutronix.de; festevam at gmail.com; kernel at pengutronix.de;
> > > dl-linux-imx <linux-imx at nxp.com>; netdev at vger.kernel.org;
> > > devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> > > linux-arm-kernel at lists.infradead.org
> > > Subject: Re: [PATCH net-next 1/3] dt-bindings: net: fsl, fec: add
> > > "fsl, wakeup-irq" property
> > >
> > > > > > 1) FEC controller has up to 4 interrupt lines and all of these
> > > > > > are routed to GIC
> > > > > interrupt controller.
> > > > > > 2) FEC has a wakeup interrupt signal and always are mixed with
> > > > > > other
> > > > > interrupt signals, and then output to one interrupt line.
> > > > > > 3) For legacy SoCs, wakeup interrupt are mixed to int0 line,
> > > > > > but for i.MX8M
> > > > > serials, are mixed to int2 line.
> > >
> > > So you need to know which of the interrupts listed is the wake up interrupt.
> 
> We already have a way to do this by using 'wakeup' for the interrupt-names
> entry. But I guess that ship has sailed here and that wouldn't work well if not
> just a wakeup source (though you could repeat an interrupt line that's the
> wakeup source).

Yes, I am not sure whether it's a common solution, such as:
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
		<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
		<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
		<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
		<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
interrupt-names = "int0", "int1", "int2", "pps", "wakeup";

Where we repeat interrupt 120 for both "int2" and "wakeup", does you mean this?

> > >
> > > I can see a few ways to do this:
> > >
> > > The FEC driver already has quirks. Add a quirk to fec_imx8mq_info
> > > and fec_imx8qm_info to indicate these should use int2.
> 
> Bingo!
> 
> Note that if the device is wakeup capable, it should have a 'wakeup-source'
> property in this case.
> 
> > >
> > > or
> > >
> > > Documentation/devicetree/bindings/interrupt-controller/interrupts.tx
> > > t
> > >
> > >   b) two cells
> > >   ------------
> > >   The #interrupt-cells property is set to 2 and the first cell defines the
> > >   index of the interrupt within the controller, while the second cell is used
> > >   to specify any of the following flags:
> > >     - bits[3:0] trigger type and level flags
> > >         1 = low-to-high edge triggered
> > >         2 = high-to-low edge triggered
> > >         4 = active high level-sensitive
> > >         8 = active low level-sensitive
> > >
> > > You could add
> > >
> > >        18 = wakeup source
> 
> I'd be okay with this (though it should be a power of 2 number).
> 
> > >
> > > and extend to core to either do all the work for you, or tell you
> > > this interrupt is flagged as being a wakeup source. This solution
> > > has the advantage of it should be usable in other drivers.
> 
> Another option is couldn't you just enable all the interrupts as wakeup sources?
> Presumably, only one of them would trigger a wakeup.

Yes, another solution, I thought it but not implemented it as we had better let users know which
interrupt is wakeup capable.

Best Regards,
Joakim Zhang
> >
> > Thanks a lot for your comments first!
> >
> > I just look into the irq code, if we extend bit[5] to carry wakeup
> > info ( due to bit[4] is used for IRQ_TYPE_PROBE), then configure it in
> > the TYPE field of 'interrupts' property, so that interrupt controller would know
> which interrupt is wakeup capable.
> > I think there is no much work core would do, may just set this
> > interrupt wakup capable. Another functionality is driver side get this info to
> identify which mixed interrupt has wakeup capability, we can export symbol
> from kernel/irq/irqdomain.c.
> >
> > The intention is to let driver know which interrupt is wakeup capable,
> > I would choose to provider this in specific driver, instead of interrupt
> controller, it seems to me that others may all choose this solution for wakeup
> mixed interrupt.
> >
> > So I would prefer solution 1, it's easier and under-control. I can have a try if
> you strongly recommend solution 2.
> >
> > Best Regards,
> > Joakim Zhang
> > > 	  Andrew

From Tudor.Ambarus at microchip.com  Mon Aug 16 00:25:10 2021
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Mon, 16 Aug 2021 07:25:10 +0000
Subject: [PATCH v2 21/35] mtd: spi-nor: Introduce spi_nor_set_mtd_info()
In-Reply-To: <20210727045222.905056-22-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-22-tudor.ambarus@microchip.com>
Message-ID: <016230fa-b268-8102-b6d8-9d76ea232340@microchip.com>

On 7/27/21 7:52 AM, Tudor Ambarus wrote:
> Used to init all the mtd_info fields. Move the mtd_info init
> the last thing in the spi_nor_scan(), so that we avoid superfluous
> initialization of the mtd_info fields in case of errors.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c | 55 +++++++++++++++++++++-----------------
>  1 file changed, 31 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 5c8cffb5e6f2..26acfc9901db 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3124,6 +3124,36 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
>  	return info;
>  }
>  
> +static void spi_nor_set_mtd_info(struct spi_nor *nor)
> +{
> +	struct mtd_info *mtd = &nor->mtd;
> +	struct device *dev = nor->dev;
> +
> +	spi_nor_register_locking_ops(nor);
> +
> +	/* Configure OTP parameters and ops */
> +	spi_nor_otp_init(nor);
> +
> +	mtd->dev.parent = dev;
> +	if (!mtd->name)
> +		mtd->name = dev_name(dev);
> +	mtd->priv = nor;

Rasmus sent me a heads up that I have a leftover here, probably from a rebase.
The priv assignment is no longer needed as per previous patch. Will update in v3.

From john.garry at huawei.com  Mon Aug 16 00:24:28 2021
From: john.garry at huawei.com (John Garry)
Date: Mon, 16 Aug 2021 08:24:28 +0100
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching helpers
 to improve performance
In-Reply-To: <52204403-f69a-d2b9-9365-7553e87d1298@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
 <20210811114852.2429-2-thunder.leizhen@huawei.com>
 <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>
 <4e741216-d6e7-c40c-f257-242cd2fea302@huawei.com>
 <5482d2e5-24db-6139-a8a8-74be1282e2ec@huawei.com>
 <52204403-f69a-d2b9-9365-7553e87d1298@huawei.com>
Message-ID: <a3cdd5df-c028-5484-ce99-928a689d341a@huawei.com>

> In addition, I find that function arm_smmu_cmdq_build_cmd() can also be optimized
> slightly, three useless instructions can be reduced.

I think that you could optimise further by pre-building commonly used 
commands.

For example, CMD_SYNC without MSI polling is always the same. And then 
only different in 1 field for MSI polling.

But you need to check if the performance gain is worth the change.

> 
> Case 1):
> void arm_smmu_cmdq_build_cmd_tst1(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
> {
>          memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
>          cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
> }
> 0000000000004608 <arm_smmu_cmdq_build_cmd_tst1>:
>      4608:       a9007c1f        stp     xzr, xzr, [x0]
>      460c:       39400022        ldrb    w2, [x1]
>      4610:       f9400001        ldr     x1, [x0]
>      4614:       aa020021        orr     x1, x1, x2
>      4618:       f9000001        str     x1, [x0]
>      461c:       d65f03c0        ret
> 
> Case 2):
> void arm_smmu_cmdq_build_cmd_tst2(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
> {
>          int i;
> 
>          cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
>          for (i = 1; i < CMDQ_ENT_DWORDS; i++)
>                  cmd[i] = 0;
> }
> 0000000000004620 <arm_smmu_cmdq_build_cmd_tst2>:
>      4620:       39400021        ldrb    w1, [x1]
>      4624:       a9007c01        stp     x1, xzr, [x0]
>      4628:       d65f03c0        ret
>      462c:       d503201f        nop
> 
> Case 3):
> void arm_smmu_cmdq_build_cmd_tst3(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
> {
>          memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
>          cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
> }
> 0000000000004630 <arm_smmu_cmdq_build_cmd_tst3>:
>      4630:       a9007c1f        stp     xzr, xzr, [x0]
>      4634:       39400021        ldrb    w1, [x1]
>      4638:       f9000001        str     x1, [x0]
>      463c:       d65f03c0        ret
> 



From thunder.leizhen at huawei.com  Mon Aug 16 00:29:02 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 16 Aug 2021 15:29:02 +0800
Subject: [PATCH v2 2/4] iommu/arm-smmu-v3: Add and use static helper function
 arm_smmu_cmdq_issue_cmd_with_sync()
In-Reply-To: <20210816072904.1897-1-thunder.leizhen@huawei.com>
References: <20210816072904.1897-1-thunder.leizhen@huawei.com>
Message-ID: <20210816072904.1897-3-thunder.leizhen@huawei.com>

The obvious key to the performance optimization of commit 587e6c10a7ce
("iommu/arm-smmu-v3: Reduce contention during command-queue insertion") is
to allow multiple cores to insert commands in parallel after a brief mutex
contention.

Obviously, inserting as many commands at a time as possible can reduce the
number of times the mutex contention participates, thereby improving the
overall performance. At least it reduces the number of calls to function
arm_smmu_cmdq_issue_cmdlist().

Therefore, function arm_smmu_cmdq_issue_cmd_with_sync() is added to insert
the 'cmd+sync' commands at a time.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 35 +++++++++++----------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 5eedb46aaceece8..9be07f6915cc3c8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -845,8 +845,9 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 	return ret;
 }
 
-static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
-				   struct arm_smmu_cmdq_ent *ent)
+static int __arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
+				     struct arm_smmu_cmdq_ent *ent,
+				     bool sync)
 {
 	u64 cmd[CMDQ_ENT_DWORDS];
 
@@ -856,12 +857,19 @@ static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
 		return -EINVAL;
 	}
 
-	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
+	return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, sync);
 }
 
-static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
+static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
+				   struct arm_smmu_cmdq_ent *ent)
 {
-	return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
+	return __arm_smmu_cmdq_issue_cmd(smmu, ent, false);
+}
+
+static int arm_smmu_cmdq_issue_cmd_with_sync(struct arm_smmu_device *smmu,
+					     struct arm_smmu_cmdq_ent *ent)
+{
+	return __arm_smmu_cmdq_issue_cmd(smmu, ent, true);
 }
 
 static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu,
@@ -929,8 +937,7 @@ void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid)
 		.tlbi.asid = asid,
 	};
 
-	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-	arm_smmu_cmdq_issue_sync(smmu);
+	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 }
 
 static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
@@ -1211,8 +1218,7 @@ static void arm_smmu_sync_ste_for_sid(struct arm_smmu_device *smmu, u32 sid)
 		},
 	};
 
-	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-	arm_smmu_cmdq_issue_sync(smmu);
+	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 }
 
 static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
@@ -1825,8 +1831,7 @@ static void arm_smmu_tlb_inv_context(void *cookie)
 	} else {
 		cmd.opcode	= CMDQ_OP_TLBI_S12_VMALL;
 		cmd.tlbi.vmid	= smmu_domain->s2_cfg.vmid;
-		arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-		arm_smmu_cmdq_issue_sync(smmu);
+		arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 	}
 	arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
 }
@@ -3340,18 +3345,16 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 
 	/* Invalidate any cached configuration */
 	cmd.opcode = CMDQ_OP_CFGI_ALL;
-	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-	arm_smmu_cmdq_issue_sync(smmu);
+	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 
 	/* Invalidate any stale TLB entries */
 	if (smmu->features & ARM_SMMU_FEAT_HYP) {
 		cmd.opcode = CMDQ_OP_TLBI_EL2_ALL;
-		arm_smmu_cmdq_issue_cmd(smmu, &cmd);
+		arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 	}
 
 	cmd.opcode = CMDQ_OP_TLBI_NSNH_ALL;
-	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-	arm_smmu_cmdq_issue_sync(smmu);
+	arm_smmu_cmdq_issue_cmd_with_sync(smmu, &cmd);
 
 	/* Event queue */
 	writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE);
-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Mon Aug 16 00:29:04 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 16 Aug 2021 15:29:04 +0800
Subject: [PATCH v2 4/4] iommu/arm-smmu-v3: Extract reusable function
 __arm_smmu_cmdq_skip_err()
In-Reply-To: <20210816072904.1897-1-thunder.leizhen@huawei.com>
References: <20210816072904.1897-1-thunder.leizhen@huawei.com>
Message-ID: <20210816072904.1897-5-thunder.leizhen@huawei.com>

When SMMU_GERROR.CMDQP_ERR is different to SMMU_GERRORN.CMDQP_ERR, it
indicates that one or more errors have been encountered on a command queue
control page interface. We need to traverse all ECMDQs in that control
page to find all errors. For each ECMDQ error handling, it is much the
same as the CMDQ error handling. This common processing part is extracted
as a new function __arm_smmu_cmdq_skip_err().

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 7814366778fda35..f3824c37f1832a2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -359,7 +359,8 @@ static void arm_smmu_cmdq_build_sync_cmd(u64 *cmd, struct arm_smmu_device *smmu,
 	arm_smmu_cmdq_build_cmd(cmd, &ent);
 }
 
-static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
+static void __arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu,
+				     struct arm_smmu_queue *q)
 {
 	static const char * const cerror_str[] = {
 		[CMDQ_ERR_CERROR_NONE_IDX]	= "No error",
@@ -370,7 +371,6 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
 
 	int i;
 	u64 cmd[CMDQ_ENT_DWORDS];
-	struct arm_smmu_queue *q = &smmu->cmdq.q;
 	u32 cons = readl_relaxed(q->cons_reg);
 	u32 idx = FIELD_GET(CMDQ_CONS_ERR, cons);
 	struct arm_smmu_cmdq_ent cmd_sync = {
@@ -417,6 +417,11 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
 	queue_write(Q_ENT(q, cons), cmd, q->ent_dwords);
 }
 
+static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
+{
+	__arm_smmu_cmdq_skip_err(smmu, &smmu->cmdq.q);
+}
+
 /*
  * Command queue locking.
  * This is a form of bastardised rwlock with the following major changes:
-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Mon Aug 16 00:29:00 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 16 Aug 2021 15:29:00 +0800
Subject: [PATCH v2 0/4] Prepare for ECMDQ support
Message-ID: <20210816072904.1897-1-thunder.leizhen@huawei.com>

v1 --> v2:
1. Stop pre-zeroing batch commands. Patch 1 is modified. Other patches remain unchanged.
   Before:
   struct arm_smmu_cmdq_batch cmds = {};

   After:
   struct arm_smmu_cmdq_batch cmds;
   cmds.num = 0;

RFC --> v1
1. Resend the patches for ECMDQ preparation and remove the patches for ECMDQ implementation.
2. Patch 2 is modified. Other patches remain unchanged.
   1) Add static helper __arm_smmu_cmdq_issue_cmd(), and make arm_smmu_cmdq_issue_cmd()
      and arm_smmu_cmdq_issue_cmd_with_sync() implement based on it.
   2) Remove unused arm_smmu_cmdq_issue_sync().

RFC:
https://www.spinics.net/lists/arm-kernel/msg904879.html


Zhen Lei (4):
  iommu/arm-smmu-v3: Use command queue batching helpers to improve
    performance
  iommu/arm-smmu-v3: Add and use static helper function
    arm_smmu_cmdq_issue_cmd_with_sync()
  iommu/arm-smmu-v3: Add and use static helper function
    arm_smmu_get_cmdq()
  iommu/arm-smmu-v3: Extract reusable function
    __arm_smmu_cmdq_skip_err()

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 72 ++++++++++++---------
 1 file changed, 43 insertions(+), 29 deletions(-)

-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Mon Aug 16 00:29:01 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 16 Aug 2021 15:29:01 +0800
Subject: [PATCH v2 1/4] iommu/arm-smmu-v3: Use command queue batching helpers
 to improve performance
In-Reply-To: <20210816072904.1897-1-thunder.leizhen@huawei.com>
References: <20210816072904.1897-1-thunder.leizhen@huawei.com>
Message-ID: <20210816072904.1897-2-thunder.leizhen@huawei.com>

The obvious key to the performance optimization of commit 587e6c10a7ce
("iommu/arm-smmu-v3: Reduce contention during command-queue insertion") is
to allow multiple cores to insert commands in parallel after a brief mutex
contention.

Obviously, inserting as many commands at a time as possible can reduce the
number of times the mutex contention participates, thereby improving the
overall performance. At least it reduces the number of calls to function
arm_smmu_cmdq_issue_cmdlist().

Therefore, use command queue batching helpers to insert multiple commands
at a time.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 235f9bdaeaf223b..5eedb46aaceece8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1747,15 +1747,17 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
 {
 	int i;
 	struct arm_smmu_cmdq_ent cmd;
+	struct arm_smmu_cmdq_batch cmds;
 
 	arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
 
+	cmds.num = 0;
 	for (i = 0; i < master->num_streams; i++) {
 		cmd.atc.sid = master->streams[i].id;
-		arm_smmu_cmdq_issue_cmd(master->smmu, &cmd);
+		arm_smmu_cmdq_batch_add(master->smmu, &cmds, &cmd);
 	}
 
-	return arm_smmu_cmdq_issue_sync(master->smmu);
+	return arm_smmu_cmdq_batch_submit(master->smmu, &cmds);
 }
 
 int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Mon Aug 16 00:29:03 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 16 Aug 2021 15:29:03 +0800
Subject: [PATCH v2 3/4] iommu/arm-smmu-v3: Add and use static helper function
 arm_smmu_get_cmdq()
In-Reply-To: <20210816072904.1897-1-thunder.leizhen@huawei.com>
References: <20210816072904.1897-1-thunder.leizhen@huawei.com>
Message-ID: <20210816072904.1897-4-thunder.leizhen@huawei.com>

One SMMU has only one normal CMDQ. Therefore, this CMDQ is used regardless
of the core on which the command is inserted. It can be referenced
directly through "smmu->cmdq". However, one SMMU has multiple ECMDQs, and
the ECMDQ used by the core on which the command insertion is executed may
be different. So the helper function arm_smmu_get_cmdq() is added, which
returns the CMDQ/ECMDQ that the current core should use. Currently, the
code that supports ECMDQ is not added. just simply returns "&smmu->cmdq".

Many subfunctions of arm_smmu_cmdq_issue_cmdlist() use "&smmu->cmdq" or
"&smmu->cmdq.q" directly. To support ECMDQ, they need to call the newly
added function arm_smmu_get_cmdq() instead.

Note that normal CMDQ is still required until ECMDQ is available.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 22 ++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 9be07f6915cc3c8..7814366778fda35 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -335,10 +335,14 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 	return 0;
 }
 
+static struct arm_smmu_cmdq *arm_smmu_get_cmdq(struct arm_smmu_device *smmu)
+{
+	return &smmu->cmdq;
+}
+
 static void arm_smmu_cmdq_build_sync_cmd(u64 *cmd, struct arm_smmu_device *smmu,
-					 u32 prod)
+					 struct arm_smmu_queue *q, u32 prod)
 {
-	struct arm_smmu_queue *q = &smmu->cmdq.q;
 	struct arm_smmu_cmdq_ent ent = {
 		.opcode = CMDQ_OP_CMD_SYNC,
 	};
@@ -579,7 +583,7 @@ static int arm_smmu_cmdq_poll_until_not_full(struct arm_smmu_device *smmu,
 {
 	unsigned long flags;
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	int ret = 0;
 
 	/*
@@ -595,7 +599,7 @@ static int arm_smmu_cmdq_poll_until_not_full(struct arm_smmu_device *smmu,
 
 	queue_poll_init(smmu, &qp);
 	do {
-		llq->val = READ_ONCE(smmu->cmdq.q.llq.val);
+		llq->val = READ_ONCE(cmdq->q.llq.val);
 		if (!queue_full(llq))
 			break;
 
@@ -614,7 +618,7 @@ static int __arm_smmu_cmdq_poll_until_msi(struct arm_smmu_device *smmu,
 {
 	int ret = 0;
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	u32 *cmd = (u32 *)(Q_ENT(&cmdq->q, llq->prod));
 
 	queue_poll_init(smmu, &qp);
@@ -637,12 +641,12 @@ static int __arm_smmu_cmdq_poll_until_consumed(struct arm_smmu_device *smmu,
 					       struct arm_smmu_ll_queue *llq)
 {
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	u32 prod = llq->prod;
 	int ret = 0;
 
 	queue_poll_init(smmu, &qp);
-	llq->val = READ_ONCE(smmu->cmdq.q.llq.val);
+	llq->val = READ_ONCE(cmdq->q.llq.val);
 	do {
 		if (queue_consumed(llq, prod))
 			break;
@@ -732,7 +736,7 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 	u32 prod;
 	unsigned long flags;
 	bool owner;
-	struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	struct arm_smmu_ll_queue llq = {
 		.max_n_shift = cmdq->q.llq.max_n_shift,
 	}, head = llq;
@@ -772,7 +776,7 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 	arm_smmu_cmdq_write_entries(cmdq, cmds, llq.prod, n);
 	if (sync) {
 		prod = queue_inc_prod_n(&llq, n);
-		arm_smmu_cmdq_build_sync_cmd(cmd_sync, smmu, prod);
+		arm_smmu_cmdq_build_sync_cmd(cmd_sync, smmu, &cmdq->q, prod);
 		queue_write(Q_ENT(&cmdq->q, prod), cmd_sync, CMDQ_ENT_DWORDS);
 
 		/*
-- 
2.26.0.106.g9fadedd



From wangkefeng.wang at huawei.com  Mon Aug 16 00:46:18 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 16 Aug 2021 15:46:18 +0800
Subject: [PATCH 2/3] Revert "ARM: amba: make use of -1 IRQs warn"
In-Reply-To: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
Message-ID: <20210816074619.177383-3-wangkefeng.wang@huawei.com>

After commit 77a7300abad7 ("of/irq: Get rid of NO_IRQ usage"),
no irq case has been removed, irq_of_parse_and_map() will return
0 in all cases when get error from parse and map an interrupt into
linux virq space.

amba_device_register() is only used on no-DT initialization, see
  s3c64xx_pl080_init()		arch/arm/mach-s3c/pl080.c
  ep93xx_init_devices()		arch/arm/mach-ep93xx/core.c

They won't set -1 to irq[0], so no need the warn.

This reverts commit 2eac58d5026e4ec8b17ff8b62877fea9e1d2f1b3.

Cc: Russell King <linux at armlinux.org.uk>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 drivers/amba/bus.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 2f2137518be0..36f2f42c8014 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -377,9 +377,6 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
 	void __iomem *tmp;
 	int i, ret;
 
-	WARN_ON(dev->irq[0] == (unsigned int)-1);
-	WARN_ON(dev->irq[1] == (unsigned int)-1);
-
 	ret = request_resource(parent, &dev->res);
 	if (ret)
 		goto err_out;
-- 
2.26.2



From wangkefeng.wang at huawei.com  Mon Aug 16 00:46:16 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 16 Aug 2021 15:46:16 +0800
Subject: [PATCH 0/3] amba: Properly handle device probe without IRQ domain
Message-ID: <20210816074619.177383-1-wangkefeng.wang@huawei.com>

Patch 1 and 2 make some cleanup, and patch 3 use of_irq_get() instead of 
irq_of_parse_and_map() to get irq number, return -EPROBE_DEFER if the irq
domain is not yet created, amba_device_add() will properly to handle the
no IRQ domain issue via deferred probe.

Kefeng Wang (3):
  amba: Drop unused functions about APB/AHB devices add
  Revert "ARM: amba: make use of -1 IRQs warn"
  amba: Properly handle device probe without IRQ domain

 drivers/amba/bus.c       | 100 ++++++++++-----------------------------
 drivers/of/platform.c    |   6 +--
 include/linux/amba/bus.h |  18 -------
 3 files changed, 27 insertions(+), 97 deletions(-)

-- 
2.26.2



From wangkefeng.wang at huawei.com  Mon Aug 16 00:46:19 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 16 Aug 2021 15:46:19 +0800
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
Message-ID: <20210816074619.177383-4-wangkefeng.wang@huawei.com>

of_amba_device_create() uses irq_of_parse_and_map() to translate
a DT interrupt specification into a Linux virtual interrupt number.

But it doesn't properly handle the case where the interrupt controller
is not yet available, eg, when pl011 interrupt is connected to MBIGEN
interrupt controller, because the mbigen initialization is too late,
which will lead to no IRQ due to no IRQ domain found, log is shown below,
  "irq: no irq domain found for uart0 !"

use of_irq_get() to return -EPROBE_DEFER as above, and in the function
amba_device_try_add()/amba_device_add(), it will properly handle in such
case, also return 0 in other fail cases to be consistent as before.

Cc: Russell King <linux at armlinux.org.uk>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
Reported-by: Ruizhe Lin <linruizhe at huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
 drivers/of/platform.c |  6 +-----
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 36f2f42c8014..720aa6cdd402 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -19,6 +19,7 @@
 #include <linux/clk/clk-conf.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
+#include <linux/of_irq.h>
 
 #include <asm/irq.h>
 
@@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
 	kfree(d);
 }
 
+static int of_amba_device_decode_irq(struct amba_device *dev)
+{
+	struct device_node *node = dev->dev.of_node;
+	int i, irq = 0;
+
+	if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
+		/* Decode the IRQs and address ranges */
+		for (i = 0; i < AMBA_NR_IRQS; i++) {
+			irq = of_irq_get(node, i);
+			if (irq < 0) {
+				if (irq == -EPROBE_DEFER)
+					return irq;
+				irq = 0;
+			}
+
+			dev->irq[i] = irq;
+		}
+	}
+
+	return 0;
+}
+
 static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
 {
 	u32 size;
 	void __iomem *tmp;
 	int i, ret;
 
+	ret = of_amba_device_decode_irq(dev);
+	if (ret)
+		goto err_out;
+
 	ret = request_resource(parent, &dev->res);
 	if (ret)
 		goto err_out;
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 74afbb7a4f5e..32d5ff8df747 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -222,7 +222,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 {
 	struct amba_device *dev;
 	const void *prop;
-	int i, ret;
+	int ret;
 
 	pr_debug("Creating amba device %pOF\n", node);
 
@@ -253,10 +253,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 	if (prop)
 		dev->periphid = of_read_ulong(prop, 1);
 
-	/* Decode the IRQs and address ranges */
-	for (i = 0; i < AMBA_NR_IRQS; i++)
-		dev->irq[i] = irq_of_parse_and_map(node, i);
-
 	ret = of_address_to_resource(node, 0, &dev->res);
 	if (ret) {
 		pr_err("amba: of_address_to_resource() failed (%d) for %pOF\n",
-- 
2.26.2



From wangkefeng.wang at huawei.com  Mon Aug 16 00:46:17 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 16 Aug 2021 15:46:17 +0800
Subject: [PATCH 1/3] amba: Drop unused functions about APB/AHB devices add
In-Reply-To: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
Message-ID: <20210816074619.177383-2-wangkefeng.wang@huawei.com>

No one use the following functions, kill them.

  amba_aphb_device_add()
  amba_apb_device_add()
  amba_apb_device_add_res()
  amba_ahb_device_add()
  amba_ahb_device_add_res()

Cc: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 drivers/amba/bus.c       | 72 ----------------------------------------
 include/linux/amba/bus.h | 18 ----------
 2 files changed, 90 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 962041148482..2f2137518be0 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -579,78 +579,6 @@ int amba_device_add(struct amba_device *dev, struct resource *parent)
 }
 EXPORT_SYMBOL_GPL(amba_device_add);
 
-static struct amba_device *
-amba_aphb_device_add(struct device *parent, const char *name,
-		     resource_size_t base, size_t size, int irq1, int irq2,
-		     void *pdata, unsigned int periphid, u64 dma_mask,
-		     struct resource *resbase)
-{
-	struct amba_device *dev;
-	int ret;
-
-	dev = amba_device_alloc(name, base, size);
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	dev->dev.coherent_dma_mask = dma_mask;
-	dev->irq[0] = irq1;
-	dev->irq[1] = irq2;
-	dev->periphid = periphid;
-	dev->dev.platform_data = pdata;
-	dev->dev.parent = parent;
-
-	ret = amba_device_add(dev, resbase);
-	if (ret) {
-		amba_device_put(dev);
-		return ERR_PTR(ret);
-	}
-
-	return dev;
-}
-
-struct amba_device *
-amba_apb_device_add(struct device *parent, const char *name,
-		    resource_size_t base, size_t size, int irq1, int irq2,
-		    void *pdata, unsigned int periphid)
-{
-	return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
-				    periphid, 0, &iomem_resource);
-}
-EXPORT_SYMBOL_GPL(amba_apb_device_add);
-
-struct amba_device *
-amba_ahb_device_add(struct device *parent, const char *name,
-		    resource_size_t base, size_t size, int irq1, int irq2,
-		    void *pdata, unsigned int periphid)
-{
-	return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
-				    periphid, ~0ULL, &iomem_resource);
-}
-EXPORT_SYMBOL_GPL(amba_ahb_device_add);
-
-struct amba_device *
-amba_apb_device_add_res(struct device *parent, const char *name,
-			resource_size_t base, size_t size, int irq1,
-			int irq2, void *pdata, unsigned int periphid,
-			struct resource *resbase)
-{
-	return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
-				    periphid, 0, resbase);
-}
-EXPORT_SYMBOL_GPL(amba_apb_device_add_res);
-
-struct amba_device *
-amba_ahb_device_add_res(struct device *parent, const char *name,
-			resource_size_t base, size_t size, int irq1,
-			int irq2, void *pdata, unsigned int periphid,
-			struct resource *resbase)
-{
-	return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
-				    periphid, ~0ULL, resbase);
-}
-EXPORT_SYMBOL_GPL(amba_ahb_device_add_res);
-
-
 static void amba_device_initialize(struct amba_device *dev, const char *name)
 {
 	device_initialize(&dev->dev);
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index c68d87b87283..edfcf7a14dcd 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -122,24 +122,6 @@ struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t);
 void amba_device_put(struct amba_device *);
 int amba_device_add(struct amba_device *, struct resource *);
 int amba_device_register(struct amba_device *, struct resource *);
-struct amba_device *amba_apb_device_add(struct device *parent, const char *name,
-					resource_size_t base, size_t size,
-					int irq1, int irq2, void *pdata,
-					unsigned int periphid);
-struct amba_device *amba_ahb_device_add(struct device *parent, const char *name,
-					resource_size_t base, size_t size,
-					int irq1, int irq2, void *pdata,
-					unsigned int periphid);
-struct amba_device *
-amba_apb_device_add_res(struct device *parent, const char *name,
-			resource_size_t base, size_t size, int irq1,
-			int irq2, void *pdata, unsigned int periphid,
-			struct resource *resbase);
-struct amba_device *
-amba_ahb_device_add_res(struct device *parent, const char *name,
-			resource_size_t base, size_t size, int irq1,
-			int irq2, void *pdata, unsigned int periphid,
-			struct resource *resbase);
 void amba_device_unregister(struct amba_device *);
 struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int);
 int amba_request_regions(struct amba_device *, const char *);
-- 
2.26.2



From lee.jones at linaro.org  Mon Aug 16 00:43:53 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 16 Aug 2021 08:43:53 +0100
Subject: [PATCH 1/1] genirq/cpuhotplug: Bump debugging information print
 down to KERN_DEBUG
In-Reply-To: <87fsvgp4jd.ffs@tglx>
References: <20210617073136.315723-1-lee.jones@linaro.org>
 <8735rhs7n6.ffs@tglx> <YROC5avuGQyBIpmD@google.com>
 <87fsvgp4jd.ffs@tglx>
Message-ID: <YRoXOTRstjKEojuA@google.com>

On Wed, 11 Aug 2021, Thomas Gleixner wrote:

> On Wed, Aug 11 2021 at 08:57, Lee Jones wrote:
> > On Tue, 10 Aug 2021, Thomas Gleixner wrote:
> >> > @@ -42,7 +42,7 @@ static inline bool irq_needs_fixup(struct irq_data *d)
> >> >  		 * If this happens then there was a missed IRQ fixup at some
> >> >  		 * point. Warn about it and enforce fixup.
> >> >  		 */
> >> > -		pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",
> >> 
> >> This one is clearly a warning as this should not happen. See the
> >> comments around that.
> >> 
> >> > +		pr_debug("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n",
> >> >  			cpumask_pr_args(m), d->irq, cpu);
> >> >  		return true;
> >> >  	}
> >> > @@ -166,7 +166,7 @@ void irq_migrate_all_off_this_cpu(void)
> >> >  		raw_spin_unlock(&desc->lock);
> >> >  
> >> >  		if (affinity_broken) {
> >> > -			pr_warn_ratelimited("IRQ %u: no longer affine to CPU%u\n",
> >> > +			pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n",
> >> >  					    irq, smp_processor_id());
> >> 
> >> Maybe, but distro people might have opinions on that.
> >
> > The trouble is, even if these are real warnings, they have an affect
> > on performance on real products.  To the point where so much logging
> > builds up during pre-release testing, that it sets off the watchdog(s)
> > on some high profile consumer devices.
> 
> I'm fine with making the second one debug, but the first one really
> should not trigger at all.

Understood.  I'll follow-up with a subsequent patch and report back
with your advice.  Thanks Thomas.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From thunder.leizhen at huawei.com  Mon Aug 16 00:47:58 2021
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Mon, 16 Aug 2021 15:47:58 +0800
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching helpers
 to improve performance
In-Reply-To: <a3cdd5df-c028-5484-ce99-928a689d341a@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
 <20210811114852.2429-2-thunder.leizhen@huawei.com>
 <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>
 <4e741216-d6e7-c40c-f257-242cd2fea302@huawei.com>
 <5482d2e5-24db-6139-a8a8-74be1282e2ec@huawei.com>
 <52204403-f69a-d2b9-9365-7553e87d1298@huawei.com>
 <a3cdd5df-c028-5484-ce99-928a689d341a@huawei.com>
Message-ID: <e8b71423-e827-f141-1203-00aca2e70834@huawei.com>



On 2021/8/16 15:24, John Garry wrote:
>> In addition, I find that function arm_smmu_cmdq_build_cmd() can also be optimized
>> slightly, three useless instructions can be reduced.
> 
> I think that you could optimise further by pre-building commonly used commands.
> 
> For example, CMD_SYNC without MSI polling is always the same. And then only different in 1 field for MSI polling.
> 
> But you need to check if the performance gain is worth the change.

Good advice. I can give it a try.

> 
>>
>> Case 1):
>> void arm_smmu_cmdq_build_cmd_tst1(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
>> {
>> ???????? memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
>> ???????? cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
>> }
>> 0000000000004608 <arm_smmu_cmdq_build_cmd_tst1>:
>> ???? 4608:?????? a9007c1f??????? stp???? xzr, xzr, [x0]
>> ???? 460c:?????? 39400022??????? ldrb??? w2, [x1]
>> ???? 4610:?????? f9400001??????? ldr???? x1, [x0]
>> ???? 4614:?????? aa020021??????? orr???? x1, x1, x2
>> ???? 4618:?????? f9000001??????? str???? x1, [x0]
>> ???? 461c:?????? d65f03c0??????? ret
>>
>> Case 2):
>> void arm_smmu_cmdq_build_cmd_tst2(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
>> {
>> ???????? int i;
>>
>> ???????? cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
>> ???????? for (i = 1; i < CMDQ_ENT_DWORDS; i++)
>> ???????????????? cmd[i] = 0;
>> }
>> 0000000000004620 <arm_smmu_cmdq_build_cmd_tst2>:
>> ???? 4620:?????? 39400021??????? ldrb??? w1, [x1]
>> ???? 4624:?????? a9007c01??????? stp???? x1, xzr, [x0]
>> ???? 4628:?????? d65f03c0??????? ret
>> ???? 462c:?????? d503201f??????? nop
>>
>> Case 3):
>> void arm_smmu_cmdq_build_cmd_tst3(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
>> {
>> ???????? memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
>> ???????? cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
>> }
>> 0000000000004630 <arm_smmu_cmdq_build_cmd_tst3>:
>> ???? 4630:?????? a9007c1f??????? stp???? xzr, xzr, [x0]
>> ???? 4634:?????? 39400021??????? ldrb??? w1, [x1]
>> ???? 4638:?????? f9000001??????? str???? x1, [x0]
>> ???? 463c:?????? d65f03c0??????? ret
>>
> 
> .
> 


From Mason.Zhang at mediatek.com  Mon Aug 16 00:38:14 2021
From: Mason.Zhang at mediatek.com (Mason Zhang)
Date: Mon, 16 Aug 2021 15:38:14 +0800
Subject: [PATCH 1/1] mmc: mediatek: fixed clk contrl flow
Message-ID: <20210816073813.11715-1-Mason.Zhang@mediatek.com>

this patch fixed clk contrl flow in set clk rate, no need close clk src,
gate cg is enough, so no need call clk prepare/unprepare.

Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 4dfc246c5f95..d9835b272c1f 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -895,9 +895,9 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 	 * So if want to only gate src_clk, need gate its parent(mux).
 	 */
 	if (host->src_clk_cg)
-		clk_disable_unprepare(host->src_clk_cg);
+		clk_disable(host->src_clk_cg);
 	else
-		clk_disable_unprepare(clk_get_parent(host->src_clk));
+		clk_disable(clk_get_parent(host->src_clk));
 	if (host->dev_comp->clk_div_bits == 8)
 		sdr_set_field(host->base + MSDC_CFG,
 			      MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
@@ -907,9 +907,9 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 			      MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA,
 			      (mode << 12) | div);
 	if (host->src_clk_cg)
-		clk_prepare_enable(host->src_clk_cg);
+		clk_enable(host->src_clk_cg);
 	else
-		clk_prepare_enable(clk_get_parent(host->src_clk));
+		clk_enable(clk_get_parent(host->src_clk));
 
 	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
 		cpu_relax();
-- 
2.18.0

From lukasz.luba at arm.com  Mon Aug 16 00:53:13 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Mon, 16 Aug 2021 08:53:13 +0100
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
References: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
Message-ID: <73eebe7b-46da-137b-1938-09a5b453320a@arm.com>

Hi Krzysztof,

On 8/13/21 1:54 PM, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
> Dynamic Memory Controller to DT schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>   .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
>   .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
>   MAINTAINERS                                   |   2 +-

I'm not an expert in this DT scripts and why it complains. Maybe it
complains because the "samsung,exynos-ppmu" is defined in the .txt
file... (?)
Although, in general looks OK.

Acked-by: Lukasz Luba <lukasz.luba at arm.com>

Regards,
Lukasz


From miquel.raynal at bootlin.com  Mon Aug 16 01:11:43 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 16 Aug 2021 10:11:43 +0200
Subject: [PATCH v3] mtd: spinand: add support for Foresee FS35ND0*G parts
In-Reply-To: <20210811084924.52293-1-daniel@0x0f.com>
References: <20210811084924.52293-1-daniel@0x0f.com>
Message-ID: <20210816101143.2a64d7b9@xps13>

Hi Daniel,

Daniel Palmer <daniel at 0x0f.com> wrote on Wed, 11 Aug 2021 17:49:24
+0900:

> Add support for the various Foresee FS35ND0*G parts manufactured by Longsys.
> 
> Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
> 
> Link: https://datasheet.lcsc.com/szlcsc/2008121142_FORESEE-FS35ND01G-S1Y2QWFI000_C719495.pdf
> ---
>  Changes since v2:
>  - Originally I only had the 1Gbit version of this chip, now I have the 2Gbit and 4Gbit
>    variations so I've added support for those too. There is no datasheet for the bigger
>    chips but they are documented in a flashing tool from an SoC vendor so I took the parameters
>    from there.
>  - Previous versions of this patch only had single io read cache variants. My SPI flash driver
>    now supports dual and quad io for reading so I added and tested those modes too.
>    My driver/hardware only supports single io for writing so those are still left out.
>  - Implemented proper logic for checking the ECC status.
>  - Combined with the previous patch for 1-filling the OOB in the page buffer before writing
>    I have been using this for a few months now without anything getting broken.
>  
>  drivers/mtd/nand/spi/Makefile  |   2 +-
>  drivers/mtd/nand/spi/core.c    |   1 +
>  drivers/mtd/nand/spi/longsys.c | 134 +++++++++++++++++++++++++++++++++
>  include/linux/mtd/spinand.h    |   1 +
>  4 files changed, 137 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/mtd/nand/spi/longsys.c
> 
> diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
> index 9662b9c1d5a9..1d6819022e43 100644
> --- a/drivers/mtd/nand/spi/Makefile
> +++ b/drivers/mtd/nand/spi/Makefile
> @@ -1,3 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0
> -spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
> +spinand-objs := core.o gigadevice.o longsys.o macronix.o micron.o paragon.o toshiba.o winbond.o
>  obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index 446ba8d43fbc..48f635d5c1ff 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -895,6 +895,7 @@ static const struct nand_ops spinand_ops = {
>  
>  static const struct spinand_manufacturer *spinand_manufacturers[] = {
>  	&gigadevice_spinand_manufacturer,
> +	&longsys_spinand_manufacturer,
>  	&macronix_spinand_manufacturer,
>  	&micron_spinand_manufacturer,
>  	&paragon_spinand_manufacturer,
> diff --git a/drivers/mtd/nand/spi/longsys.c b/drivers/mtd/nand/spi/longsys.c
> new file mode 100644
> index 000000000000..ee38f8728262
> --- /dev/null
> +++ b/drivers/mtd/nand/spi/longsys.c
> @@ -0,0 +1,134 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 Daniel Palmer <daniel at thingy.jp>
> + *
> + */
> +
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/mtd/spinand.h>
> +
> +#define SPINAND_MFR_LONGSYS			0xCD
> +#define FS35ND01G_S1Y2_STATUS_ECC_0_3_BITFLIPS	(0 << 4)
> +#define FS35ND01G_S1Y2_STATUS_ECC_4_BITFLIPS	(1 << 4)
> +#define FS35ND01G_S1Y2_STATUS_ECC_UNCORRECTABLE	(2 << 4)
> +
> +static SPINAND_OP_VARIANTS(read_cache_variants,
> +		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(write_cache_variants,
> +		SPINAND_PROG_LOAD(true, 0, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(update_cache_variants,
> +		SPINAND_PROG_LOAD(false, 0, NULL, 0));
> +
> +static int fs35nd01g_s1y2_ooblayout_ecc(struct mtd_info *mtd, int section,
> +					struct mtd_oob_region *region)
> +{
> +	if (section > 3)
> +		return -ERANGE;
> +
> +	/* ECC is not user accessible */
> +	region->offset = 0;
> +	region->length = 0;

Can't you just return -ERANGE directly? (maybe not).
If you can't then just return -ERANGE on if (section), no need for two
additional calls.

> +
> +	return 0;
> +}
> +
> +static int fs35nd01g_s1y2_ooblayout_free(struct mtd_info *mtd, int section,
> +				    struct mtd_oob_region *region)
> +{
> +	if (section > 3)
> +		return -ERANGE;
> +
> +	/*
> +	 * No ECC data is stored in the accessible OOB so the full 16 bytes
> +	 * of each spare region is available to the user. Apparently also
> +	 * covered by the internal ECC.
> +	 */
> +	if (section) {
> +		region->offset = 16 * section;
> +		region->length = 16;
> +	} else {
> +		/* First byte in spare0 area is used for bad block marker */
> +		region->offset = 1;

So far we reserved two bytes for BBM while we know for now we only use
one.

> +		region->length = 15;
> +	}

You can just return

	if (section)
		return -ERANGE;

	offset = 2;
	length = (4 * 16) - offset;

	return 0;


> +
> +	return 0;
> +}
> +
> +static const struct mtd_ooblayout_ops fs35nd01g_s1y2_ooblayout = {
> +	.ecc = fs35nd01g_s1y2_ooblayout_ecc,
> +	.free = fs35nd01g_s1y2_ooblayout_free,
> +};
> +
> +static int fs35nd01g_s1y2_ecc_get_status(struct spinand_device *spinand,
> +					u8 status)
> +{
> +	switch (status & STATUS_ECC_MASK) {
> +	case FS35ND01G_S1Y2_STATUS_ECC_0_3_BITFLIPS:
> +		return 3;
> +	/*
> +	 * The datasheet says *successful* with 4 bits flipped.
> +	 * nandbiterrs always complains that the read reported
> +	 * successful but the data is incorrect.
> +	 */
> +	case FS35ND01G_S1Y2_STATUS_ECC_4_BITFLIPS:
> +		return 4;

This is a real issue. Can you use the nandflipbits tool from the
mtd-utils package (you should take a recent version of the package) and
try to observe what happens when you insert a 4th bitflip in a section?

I generally believe the tool more than the datasheet :)

> +	case FS35ND01G_S1Y2_STATUS_ECC_UNCORRECTABLE:
> +		return -EBADMSG;
> +	default:
> +		break;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct spinand_info longsys_spinand_table[] = {
> +	SPINAND_INFO("FS35ND01G-S1Y2",
> +		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEA, 0x11),
> +		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
> +		     NAND_ECCREQ(4, 512),
> +		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
> +					      &write_cache_variants,
> +					      &update_cache_variants),
> +		     SPINAND_HAS_QE_BIT,
> +		     SPINAND_ECCINFO(&fs35nd01g_s1y2_ooblayout,
> +				     fs35nd01g_s1y2_ecc_get_status)),
> +	SPINAND_INFO("FS35ND02G-S3Y2",
> +		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB, 0x11),
> +		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
> +		     NAND_ECCREQ(4, 512),
> +		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
> +					      &write_cache_variants,
> +					      &update_cache_variants),
> +		     SPINAND_HAS_QE_BIT,
> +		     SPINAND_ECCINFO(&fs35nd01g_s1y2_ooblayout,
> +				     fs35nd01g_s1y2_ecc_get_status)),
> +	SPINAND_INFO("FS35ND04G-S2Y2",
> +		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEC, 0x11),
> +		     NAND_MEMORG(1, 2048, 64, 64, 4096, 40, 1, 1, 1),
> +		     NAND_ECCREQ(4, 512),
> +		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
> +					      &write_cache_variants,
> +					      &update_cache_variants),
> +		     SPINAND_HAS_QE_BIT,
> +		     SPINAND_ECCINFO(&fs35nd01g_s1y2_ooblayout,
> +				     fs35nd01g_s1y2_ecc_get_status)),
> +};
> +
> +static const struct spinand_manufacturer_ops longsys_spinand_manuf_ops = {
> +};
> +
> +const struct spinand_manufacturer longsys_spinand_manufacturer = {
> +	.id = SPINAND_MFR_LONGSYS,
> +	.name = "Longsys",
> +	.chips = longsys_spinand_table,
> +	.nchips = ARRAY_SIZE(longsys_spinand_table),
> +	.ops = &longsys_spinand_manuf_ops,
> +};
> diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
> index 6988956b8492..f6c38528bb03 100644
> --- a/include/linux/mtd/spinand.h
> +++ b/include/linux/mtd/spinand.h
> @@ -261,6 +261,7 @@ struct spinand_manufacturer {
>  
>  /* SPI NAND manufacturers */
>  extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
> +extern const struct spinand_manufacturer longsys_spinand_manufacturer;
>  extern const struct spinand_manufacturer macronix_spinand_manufacturer;
>  extern const struct spinand_manufacturer micron_spinand_manufacturer;
>  extern const struct spinand_manufacturer paragon_spinand_manufacturer;

Otherwise LGTM.

Thanks,
Miqu?l


From will at kernel.org  Mon Aug 16 01:21:27 2021
From: will at kernel.org (Will Deacon)
Date: Mon, 16 Aug 2021 09:21:27 +0100
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching
 helpers to improve performance
In-Reply-To: <e8b71423-e827-f141-1203-00aca2e70834@huawei.com>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
 <20210811114852.2429-2-thunder.leizhen@huawei.com>
 <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>
 <4e741216-d6e7-c40c-f257-242cd2fea302@huawei.com>
 <5482d2e5-24db-6139-a8a8-74be1282e2ec@huawei.com>
 <52204403-f69a-d2b9-9365-7553e87d1298@huawei.com>
 <a3cdd5df-c028-5484-ce99-928a689d341a@huawei.com>
 <e8b71423-e827-f141-1203-00aca2e70834@huawei.com>
Message-ID: <20210816082126.GA11011@willie-the-truck>

On Mon, Aug 16, 2021 at 03:47:58PM +0800, Leizhen (ThunderTown) wrote:
> 
> 
> On 2021/8/16 15:24, John Garry wrote:
> >> In addition, I find that function arm_smmu_cmdq_build_cmd() can also be optimized
> >> slightly, three useless instructions can be reduced.
> > 
> > I think that you could optimise further by pre-building commonly used commands.
> > 
> > For example, CMD_SYNC without MSI polling is always the same. And then only different in 1 field for MSI polling.
> > 
> > But you need to check if the performance gain is worth the change.
> 
> Good advice. I can give it a try.

Please send it as a new patch on top. I've queued the old one and sent
it to Joerg. Since this is just further cleanup, it can be done separately.

Will


From krzysztof.kozlowski at canonical.com  Mon Aug 16 01:32:20 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 16 Aug 2021 10:32:20 +0200
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <73eebe7b-46da-137b-1938-09a5b453320a@arm.com>
References: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
 <73eebe7b-46da-137b-1938-09a5b453320a@arm.com>
Message-ID: <0ec05a0b-9499-3bf4-a231-ea53b1cf99ed@canonical.com>

On 16/08/2021 09:53, Lukasz Luba wrote:
> Hi Krzysztof,
> 
> On 8/13/21 1:54 PM, Krzysztof Kozlowski wrote:
>> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
>> Dynamic Memory Controller to DT schema format using json-schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>   .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
>>   .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
>>   MAINTAINERS                                   |   2 +-
> 
> I'm not an expert in this DT scripts and why it complains. Maybe it
> complains because the "samsung,exynos-ppmu" is defined in the .txt
> file... (?)
> Although, in general looks OK.
> 
> Acked-by: Lukasz Luba <lukasz.luba at arm.com>

I think the warning (triggered by DT_CHECKER_FLAGS=-m) can be ignored
because it complains about compatible in example which is not present in
the bindings. Usually it means someone wrote example not matching the
bindings (e.g. a typo in compatible) but here it is on purpose.


Best regards,
Krzysztof


From lukasz.luba at arm.com  Mon Aug 16 01:35:59 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Mon, 16 Aug 2021 09:35:59 +0100
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <0ec05a0b-9499-3bf4-a231-ea53b1cf99ed@canonical.com>
References: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
 <73eebe7b-46da-137b-1938-09a5b453320a@arm.com>
 <0ec05a0b-9499-3bf4-a231-ea53b1cf99ed@canonical.com>
Message-ID: <626d539a-ff39-ba98-0e92-4563d4e21681@arm.com>



On 8/16/21 9:32 AM, Krzysztof Kozlowski wrote:
> On 16/08/2021 09:53, Lukasz Luba wrote:
>> Hi Krzysztof,
>>
>> On 8/13/21 1:54 PM, Krzysztof Kozlowski wrote:
>>> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
>>> Dynamic Memory Controller to DT schema format using json-schema.
>>>
>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>> ---
>>>    .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
>>>    .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
>>>    MAINTAINERS                                   |   2 +-
>>
>> I'm not an expert in this DT scripts and why it complains. Maybe it
>> complains because the "samsung,exynos-ppmu" is defined in the .txt
>> file... (?)
>> Although, in general looks OK.
>>
>> Acked-by: Lukasz Luba <lukasz.luba at arm.com>
> 
> I think the warning (triggered by DT_CHECKER_FLAGS=-m) can be ignored
> because it complains about compatible in example which is not present in
> the bindings. Usually it means someone wrote example not matching the
> bindings (e.g. a typo in compatible) but here it is on purpose.

Fair enough. Thanks for working on it!


From thunder.leizhen at huawei.com  Mon Aug 16 01:41:47 2021
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Mon, 16 Aug 2021 16:41:47 +0800
Subject: [PATCH 1/4] iommu/arm-smmu-v3: Use command queue batching helpers
 to improve performance
In-Reply-To: <20210816082126.GA11011@willie-the-truck>
References: <20210811114852.2429-1-thunder.leizhen@huawei.com>
 <20210811114852.2429-2-thunder.leizhen@huawei.com>
 <81258eb7-eb73-8a32-0983-3487daba1167@arm.com>
 <4e741216-d6e7-c40c-f257-242cd2fea302@huawei.com>
 <5482d2e5-24db-6139-a8a8-74be1282e2ec@huawei.com>
 <52204403-f69a-d2b9-9365-7553e87d1298@huawei.com>
 <a3cdd5df-c028-5484-ce99-928a689d341a@huawei.com>
 <e8b71423-e827-f141-1203-00aca2e70834@huawei.com>
 <20210816082126.GA11011@willie-the-truck>
Message-ID: <60343dae-5e67-f7e1-478f-f3aab32dd8c2@huawei.com>



On 2021/8/16 16:21, Will Deacon wrote:
> On Mon, Aug 16, 2021 at 03:47:58PM +0800, Leizhen (ThunderTown) wrote:
>>
>>
>> On 2021/8/16 15:24, John Garry wrote:
>>>> In addition, I find that function arm_smmu_cmdq_build_cmd() can also be optimized
>>>> slightly, three useless instructions can be reduced.
>>>
>>> I think that you could optimise further by pre-building commonly used commands.
>>>
>>> For example, CMD_SYNC without MSI polling is always the same. And then only different in 1 field for MSI polling.
>>>
>>> But you need to check if the performance gain is worth the change.
>>
>> Good advice. I can give it a try.
> 
> Please send it as a new patch on top. I've queued the old one and sent
> it to Joerg. Since this is just further cleanup, it can be done separately.

OK, I'll post a separate patch later.

> 
> Will
> .
> 


From claudiu.beznea at microchip.com  Mon Aug 16 01:55:26 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 11:55:26 +0300
Subject: [PATCH v2 0/4] mmc: pwrseq: sd8787: add support wilc1000 devices
Message-ID: <20210816085530.1723402-1-claudiu.beznea@microchip.com>

Hi,

This series adds support for WILC1000 devices on pwrseq-sd8787 driver.
WILC1000 devices needs a minimum delay of 5ms b/w reset and power lines.
Adapt the sd8787 driver for this by adding a new compatible for WILC1000
devices and specify the delay on .data field of struct of_device_id.

Thank you,
Claudiu Beznea

Changes in v2:
- changed cover letter title (it was: mmc: pwrseq: sd8787: add support
  for selectable)
- use new compatible in pwrseq-sd8787 driver instead of adding a new
  binding for specifying the delay; with this, the patch 1/1 from v1 is
  not necessary
- adapt patch 3/3 from this version with the new compatible

Claudiu Beznea (3):
  dt-bindings: pwrseq-sd8787: add binding for wilc1000
  mmc: pwrseq: sd8787: add support for wilc1000
  mmc: pwrseq: add wilc1000_sdio dependency for pwrseq_sd8787

Eugen Hristev (1):
  ARM: dts: at91: sama5d27_wlsom1: add wifi device

 .../bindings/mmc/mmc-pwrseq-sd8787.yaml       |  4 +-
 arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi   | 71 +++++++++++++++++++
 drivers/mmc/core/Kconfig                      |  2 +-
 drivers/mmc/core/pwrseq_sd8787.c              | 11 ++-
 4 files changed, 84 insertions(+), 4 deletions(-)

-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 16 01:55:27 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 11:55:27 +0300
Subject: [PATCH v2 1/4] dt-bindings: pwrseq-sd8787: add binding for wilc1000
In-Reply-To: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
References: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
Message-ID: <20210816085530.1723402-2-claudiu.beznea@microchip.com>

Add binding for wilc1000 devices.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
index e0169a285aa2..e1a51ef70e77 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
@@ -11,7 +11,9 @@ maintainers:
 
 properties:
   compatible:
-    const: mmc-pwrseq-sd8787
+    oneOf:
+      const: mmc-pwrseq-sd8787
+      const: mmc-pwrseq-wilc1000
 
   powerdown-gpios:
     minItems: 1
-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 16 01:55:28 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 11:55:28 +0300
Subject: [PATCH v2 2/4] mmc: pwrseq: sd8787: add support for wilc1000
In-Reply-To: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
References: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
Message-ID: <20210816085530.1723402-3-claudiu.beznea@microchip.com>

Add new compatible for wilc1000 devices and specify the delay in .data
member of struct of_device_id. WILC1000, WILC3000 devices needs a minimum
of 5ms delay b/w reset and power lines.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 drivers/mmc/core/pwrseq_sd8787.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
index 68a826f1c0a1..264e48067af2 100644
--- a/drivers/mmc/core/pwrseq_sd8787.c
+++ b/drivers/mmc/core/pwrseq_sd8787.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -27,6 +28,7 @@ struct mmc_pwrseq_sd8787 {
 	struct mmc_pwrseq pwrseq;
 	struct gpio_desc *reset_gpio;
 	struct gpio_desc *pwrdn_gpio;
+	u32 reset_pwrdwn_delay_ms;
 };
 
 #define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
@@ -37,7 +39,7 @@ static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
 
 	gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
 
-	msleep(300);
+	msleep(pwrseq->reset_pwrdwn_delay_ms);
 	gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
 }
 
@@ -55,7 +57,8 @@ static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
 };
 
 static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
-	{ .compatible = "mmc-pwrseq-sd8787",},
+	{ .compatible = "mmc-pwrseq-sd8787", .data = (void *)300 },
+	{ .compatible = "mmc-pwrseq-wilc1000", .data = (void *)5 },
 	{/* sentinel */},
 };
 MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
@@ -64,11 +67,15 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
 {
 	struct mmc_pwrseq_sd8787 *pwrseq;
 	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
 
 	pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
 	if (!pwrseq)
 		return -ENOMEM;
 
+	match = of_match_node(mmc_pwrseq_sd8787_of_match, pdev->dev.of_node);
+	pwrseq->reset_pwrdwn_delay_ms = (u32)match->data;
+
 	pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW);
 	if (IS_ERR(pwrseq->pwrdn_gpio))
 		return PTR_ERR(pwrseq->pwrdn_gpio);
-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 16 01:55:29 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 11:55:29 +0300
Subject: [PATCH v2 3/4] mmc: pwrseq: add wilc1000_sdio dependency for
 pwrseq_sd8787
In-Reply-To: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
References: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
Message-ID: <20210816085530.1723402-4-claudiu.beznea@microchip.com>

pwseq_sd8787 could also be used with wilc1000_sdio driver. Add
a dependency for this.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 drivers/mmc/core/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index ae8b69aee619..6f25c34e4fec 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -15,7 +15,7 @@ config PWRSEQ_EMMC
 
 config PWRSEQ_SD8787
 	tristate "HW reset support for SD8787 BT + Wifi module"
-	depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO)
+	depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO || WILC1000_SDIO)
 	help
 	  This selects hardware reset support for the SD8787 BT + Wifi
 	  module. By default this option is set to n.
-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 16 01:55:30 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 16 Aug 2021 11:55:30 +0300
Subject: [PATCH v2 4/4] ARM: dts: at91: sama5d27_wlsom1: add wifi device
In-Reply-To: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
References: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
Message-ID: <20210816085530.1723402-5-claudiu.beznea@microchip.com>

From: Eugen Hristev <eugen.hristev at microchip.com>

SAMA5D27 WLSOM1 boards has a WILC3000 device soldered. Add proper
device tree nodes for this.

[eugen.hristev: original author of this code]
Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
[nicolas.ferre: original author of this code]
Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi | 71 +++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
index 025a78310e3a..c7bcfd3ce91d 100644
--- a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
+++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
@@ -30,6 +30,15 @@ main_xtal {
 			clock-frequency = <24000000>;
 		};
 	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-wilc1000";
+		reset-gpios = <&pioA PIN_PA27 GPIO_ACTIVE_HIGH>;
+		powerdown-gpios = <&pioA PIN_PA29 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&pinctrl_wilc_pwrseq>;
+		pinctrl-names = "default";
+		status = "okay";
+	};
 };
 
 &flx1 {
@@ -310,5 +319,67 @@ pinctrl_qspi1_default: qspi1_default {
 			 <PIN_PB10__QSPI1_IO3>;
 		bias-pull-up;
 	};
+
+	pinctrl_sdmmc1_default: sdmmc1_default {
+		cmd-data {
+			pinmux = <PIN_PA28__SDMMC1_CMD>,
+				 <PIN_PA18__SDMMC1_DAT0>,
+				 <PIN_PA19__SDMMC1_DAT1>,
+				 <PIN_PA20__SDMMC1_DAT2>,
+				 <PIN_PA21__SDMMC1_DAT3>;
+			bias-disable;
+		};
+
+		conf-ck {
+			pinmux = <PIN_PA22__SDMMC1_CK>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_wilc_default: wilc_default {
+		conf-irq {
+			pinmux = <PIN_PB25__GPIO>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_wilc_pwrseq: wilc_pwrseq {
+		conf-ce-nrst {
+			pinmux = <PIN_PA27__GPIO>,
+				 <PIN_PA29__GPIO>;
+			bias-disable;
+		};
+
+		conf-rtcclk {
+			pinmux = <PIN_PB13__PCK1>;
+			bias-disable;
+		};
+	};
+};
+
+&sdmmc1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	no-1-8-v;
+	non-removable;
+	status = "okay";
+
+	wilc: wilc at 0 {
+		reg = <0>;
+		bus-width = <4>;
+		compatible = "microchip,wilc3000", "microchip,wilc1000";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_wilc_default>;
+		irq-gpios = <&pioA PIN_PB25 GPIO_ACTIVE_LOW>;
+		clocks = <&pmc PMC_TYPE_SYSTEM 9>;
+		clock-names = "rtc";
+		assigned-clocks = <&pmc PMC_TYPE_SYSTEM 9>;
+		assigned-clock-rates = <32768>;
+		status = "okay";
+	};
 };
 
-- 
2.25.1



From michal.simek at xilinx.com  Mon Aug 16 02:08:06 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 16 Aug 2021 11:08:06 +0200
Subject: [PATCH 4/4] arm: dts: zynq: Replace 'io-standard' with
 'power-source' property
In-Reply-To: <fd759de0-d74f-3aa1-ad46-e3ee7f7f7e3f@xilinx.com>
References: <1626868353-96475-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <1626868353-96475-5-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <YQMIhBPwcNw1YqMq@robh.at.kernel.org>
 <bc5185eb-8051-89ca-4a5f-c4e5fc90a7f2@xilinx.com>
 <CAL_Jsq+281knebcN--jQgYWtDQO4OV6ZO5CvnYpaYqrAaiGmPQ@mail.gmail.com>
 <fd759de0-d74f-3aa1-ad46-e3ee7f7f7e3f@xilinx.com>
Message-ID: <c49c9633-4bc6-0cdd-cb3d-8b9ffc92b671@xilinx.com>

Hi Rob,

On 8/5/21 9:52 AM, Michal Simek wrote:
> 
> 
> On 8/2/21 7:29 PM, Rob Herring wrote:
>> On Thu, Jul 29, 2021 at 10:59 PM Michal Simek <michal.simek at xilinx.com> wrote:
>>>
>>>
>>>
>>> On 7/29/21 9:59 PM, Rob Herring wrote:
>>>> On Wed, Jul 21, 2021 at 05:22:33PM +0530, Sai Krishna Potthuri wrote:
>>>>> Replace 'io-standard' property with 'power-source' property in all zynq dts
>>>>> files to be in sync with Zynq pinctrl driver.
>>>>>
>>>>> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
>>>>> ---
>>>>>  arch/arm/boot/dts/zynq-ebaz4205.dts |  8 ++++----
>>>>>  arch/arm/boot/dts/zynq-microzed.dts |  2 +-
>>>>>  arch/arm/boot/dts/zynq-zc702.dts    | 20 ++++++++++----------
>>>>>  arch/arm/boot/dts/zynq-zc706.dts    | 18 +++++++++---------
>>>>>  4 files changed, 24 insertions(+), 24 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm/boot/dts/zynq-ebaz4205.dts b/arch/arm/boot/dts/zynq-ebaz4205.dts
>>>>> index b0b836aedd76..be7eae611fb7 100644
>>>>> --- a/arch/arm/boot/dts/zynq-ebaz4205.dts
>>>>> +++ b/arch/arm/boot/dts/zynq-ebaz4205.dts
>>>>> @@ -57,7 +57,7 @@
>>>>>
>>>>>              conf {
>>>>>                      groups = "gpio0_20_grp", "gpio0_32_grp";
>>>>> -                    io-standard = <3>;
>>>>> +                    power-source = <3>;
>>>>
>>>> This will break using a new DT with a kernel without patch 3.
>>>>
>>>
>>> What do you suggest? Not to update any old DT?
>>
>> Your options are don't change the dts files, patch 3 needs to go to
>> stable kernels, or you document the breakage (if you don't care).
> 
> There is no intention to go to stable kernel and I don't think this is
> stable material. Linus has applied 3 patches and this one should go via
> my tree. It means I will make sure that this DT change will be in the
> tree when pinctrl changes are applied.

Any issue with this patch? Or can I apply it to my tree?

Thanks,
Michal



From zhaoxiao at uniontech.com  Mon Aug 16 02:23:03 2021
From: zhaoxiao at uniontech.com (zhaoxiao)
Date: Mon, 16 Aug 2021 17:23:03 +0800
Subject: [PATCH] Media: meson: vdec: Use
 devm_platform_ioremap_resource_byname()
Message-ID: <20210816092303.10162-1-zhaoxiao@uniontech.com>

Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately.

Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
---
 drivers/staging/media/meson/vdec/vdec.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
index e51d69c4729d..8549d95be0f2 100644
--- a/drivers/staging/media/meson/vdec/vdec.c
+++ b/drivers/staging/media/meson/vdec/vdec.c
@@ -994,7 +994,6 @@ static int vdec_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct video_device *vdev;
 	struct amvdec_core *core;
-	struct resource *r;
 	const struct of_device_id *of_id;
 	int irq;
 	int ret;
@@ -1006,13 +1005,11 @@ static int vdec_probe(struct platform_device *pdev)
 	core->dev = dev;
 	platform_set_drvdata(pdev, core);
 
-	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dos");
-	core->dos_base = devm_ioremap_resource(dev, r);
+	core->dos_base = devm_platform_ioremap_resource_byname(pdev, "dos");
 	if (IS_ERR(core->dos_base))
 		return PTR_ERR(core->dos_base);
 
-	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "esparser");
-	core->esparser_base = devm_ioremap_resource(dev, r);
+	core->esparser_base = devm_platform_ioremap_resource_byname(pdev, "esparser");
 	if (IS_ERR(core->esparser_base))
 		return PTR_ERR(core->esparser_base);
 
-- 
2.20.1





From dan.carpenter at oracle.com  Mon Aug 16 02:40:55 2021
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Mon, 16 Aug 2021 12:40:55 +0300
Subject: [PATCH 1/2] soc: aspeed: Add LPC mailbox support
In-Reply-To: <20210813054758.13189-2-chiawei_wang@aspeedtech.com>
Message-ID: <202108160813.GOZ1P4Y8-lkp@intel.com>

Hi Chia-Wei,

url:    https://github.com/0day-ci/linux/commits/Chia-Wei-Wang/aspeed-Add-LPC-mailbox-support/20210813-134908
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git for-next
config: openrisc-randconfig-m031-20210816 (attached as .config)
compiler: or1k-linux-gcc (GCC) 11.2.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>
Reported-by: Dan Carpenter <dan.carpenter at oracle.com>

smatch warnings:
drivers/soc/aspeed/aspeed-lpc-mbox.c:230 aspeed_mbox_ioctl() warn: maybe return -EFAULT instead of the bytes remaining?

vim +230 drivers/soc/aspeed/aspeed-lpc-mbox.c

72c5a69dc779f5 Chia-Wei Wang 2021-08-13  214  static long aspeed_mbox_ioctl(struct file *file, unsigned int cmd,
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  215  				 unsigned long param)
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  216  {
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  217  	struct aspeed_mbox *mbox = file_mbox(file);
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  218  	const struct aspeed_mbox_model *model = mbox->model;
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  219  	struct aspeed_mbox_ioctl_data data;
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  220  	long ret;
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  221  
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  222  	switch (cmd) {
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  223  	case ASPEED_MBOX_IOCTL_GET_SIZE:
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  224  		data.data = model->dr_num;
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  225  		ret = copy_to_user((void __user *)param, &data, sizeof(data));

This should be:

	if (copy_to_user((void __user *)param, &data, sizeof(data)))
		return -EFAULT;

72c5a69dc779f5 Chia-Wei Wang 2021-08-13  226  		break;
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  227  	default:
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  228  		ret = -ENOTTY;
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  229  	}
72c5a69dc779f5 Chia-Wei Wang 2021-08-13 @230  	return ret;
72c5a69dc779f5 Chia-Wei Wang 2021-08-13  231  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org



From krzysztof.kozlowski at canonical.com  Mon Aug 16 02:45:24 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 16 Aug 2021 11:45:24 +0200
Subject: [PATCH v3 7/7] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <CAPLW+4=2msw44EjujeTUvcYJ701iZTPwkVoO3UzZyakspev20A@mail.gmail.com>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
 <20210811114827.27322-8-semen.protsenko@linaro.org>
 <f0e892ce-acd0-7acc-4881-dd67dda6fb38@canonical.com>
 <CAPLW+4=2msw44EjujeTUvcYJ701iZTPwkVoO3UzZyakspev20A@mail.gmail.com>
Message-ID: <40dd9a0a-eccc-1b0c-70ec-06edc8b91177@canonical.com>

On 12/08/2021 19:42, Sam Protsenko wrote:
> On Thu, 12 Aug 2021 at 11:17, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 11/08/2021 13:48, Sam Protsenko wrote:
>>> Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
>>>
>>> This patch adds minimal SoC support by including next Device Tree nodes:
>>>
>>> 1. Octa cores (Cortex-A55), supporting PSCI v1.0
>>> 2. ARM architecture timer (armv8-timer)
>>> 3. Interrupt controller (GIC-400)
>>> 4. Pinctrl nodes for GPIO
>>> 5. Serial node
>>>
>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>> ---
>>> Changes in v3:
>>>  - Used generic fixed clock for serial
>>>
>>> Changes in v2:
>>>  * Commit message:
>>>    - Documented added dts features instead of CPU features
>>>
>>>  * exynos850-usi.dtsi:
>>>    - Removed, moved everything to exynos850.dtsi
>>>
>>>  * exynos850.dtsi:
>>>    - Root node:
>>>      - Added comment about engineering name (Exynos3830)
>>>      - Renamed pinctrl nodes, adding domain names
>>>      - Used hard coded IRQ numbers instead of named constants everywhere
>>>      - Added soc node, moved next nodes there: gic, clock, pinctrls and
>>>        serial
>>>      - Used address-cells=1 for soc node and removed unneeded 0x0 from
>>>        reg properties
>>>      - Moved exynos850-pinctrl.dtsi include line to the end of
>>>        exynos850.dtsi
>>>      - Coding style fixes
>>>    - cpus:
>>>      - Used address-cells=1 for cpus node
>>>      - Renamed cpu at 0001 to cpu at 1, and so on
>>>      - Left only "arm,cortex-a55" for cpus compatible
>>>      - Renamed reg = <0x0001> to <0x1> for cpus
>>>    - armv8 timer:
>>>      - Add comment about missing HV timer IRQ to armv8 timer node
>>>      - Removed not existing properties from armv8 timer node
>>>      - Fixed cpu number in CPU_MASK()
>>>      - Removed obsolete clock-frequency property
>>>    - GIC:
>>>      - Fixed GIC type to be GIC-400
>>>      - Fixed size of GIC's 2nd region to be 0x2000
>>>    - serial node:
>>>      - Hard coded clock number for serial_0 for now; will replace with
>>>        named const once proper clock driver is implemented
>>>      - Removed gate_uart_clk0 clock from serial_0, as that clock is not
>>>        supported in serial driver anyway (yet)
>>>    - clock node:
>>>      - Fixed clock controller node name (@0x12.. -> @12..)
>>>
>>>  * exynos850-pinctrl.dtsi:
>>>    - Referenced pinctrl nodes instead of defining those again in root node
>>>    - Fixed interrupt-cells (3 -> 2)
>>>    - Fixed USI related comments for pin config nodes
>>>    - Removed decon_f_te_* and fm_lna_en nodes (won't be used)
>>>    - Reordered pin config nodes by pin numbers
>>>    - Improved all comments
>>>    - Used existing named constants for pin-function and pin-pud
>>>    - Fixed node names (used hyphens instead of underscore)
>>>    - Fixed warnings found in W=1 build
>>>
>>>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
>>>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 261 ++++++
>>>  2 files changed, 1009 insertions(+)
>>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
>>>
>>> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>> new file mode 100644
>>> index 000000000000..ba5d5f33e2f6
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>>> @@ -0,0 +1,748 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
>>> + *
>>> + * Copyright (C) 2017 Samsung Electronics Co., Ltd.
>>> + * Copyright (C) 2021 Linaro Ltd.
>>> + *
>>> + * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
>>> + * tree nodes in this file.
>>> + */
>>> +
>>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>>> +#include <dt-bindings/pinctrl/samsung.h>
>>> +
>>> +&pinctrl_alive {
>>> +     gpa0: gpa0 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpa1: gpa1 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpa2: gpa2 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpa3: gpa3 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpa4: gpa4 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
>>> +                          <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpq0: gpq0 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +     };
>>> +
>>> +     /* I2C5 (also called CAM_PMIC_I2C in TRM) */
>>> +     i2c5_bus: i2c5-bus {
>>> +             samsung,pins = "gpa3-5", "gpa3-6";
>>> +             samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
>>> +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>>> +             samsung,pin-drv = <0>;
>>> +     };
>>> +
>>> +     /* I2C6 (also called MOTOR_I2C in TRM) */
>>> +     i2c6_bus: i2c6-bus {
>>> +             samsung,pins = "gpa3-7", "gpa4-0";
>>> +             samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
>>> +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>>> +             samsung,pin-drv = <0>;
>>> +     };
>>> +
>>> +     /* USI: UART */
>>> +     uart0_bus: uart0-bus {
>>> +             samsung,pins = "gpq0-0", "gpq0-1";
>>> +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>>> +             samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>>> +     };
>>> +};
>>> +
>>> +&pinctrl_cmgp {
>>> +     gpm0: gpm0 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpm1: gpm1 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpm2: gpm2 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpm3: gpm3 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpm4: gpm4 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     gpm5: gpm5 {
>>> +             gpio-controller;
>>> +             #gpio-cells = <2>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <2>;
>>> +             interrupt-parent = <&gic>;
>>> +             interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
>>> +     };
>>> +
>>> +     /* USI_CMGP0: HSI2C function */
>>> +     hsi2c3_bus: hsi2c3-bus {
>>> +             samsung,pins = "gpm0-0", "gpm1-0";
>>> +             samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>>> +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>>> +             samsung,pin-drv = <0>;
>>
>> There are also macros for DRV.
>>
> 
> Unfortunately, existing DRV macros won't work for Exynos850. DRV
> constants have different meaning for different GPIO domains in
> Exynos850, so I thought introducing several groups of DRV constants
> might be confusing. But please let me know if you still want me do
> that.
> 

Oh, damn, raw values are ok then.


Best regards,
Krzysztof


From lorenzo.pieralisi at arm.com  Mon Aug 16 02:58:54 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 16 Aug 2021 10:58:54 +0100
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <20210811145508.GA3650@lpieralisi>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
 <YRKtEDycefrZLB3X@infradead.org>
 <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
 <YRPZ2Kqb/MFggHzQ@infradead.org> <20210811145508.GA3650@lpieralisi>
Message-ID: <20210816095854.GA2599@lpieralisi>

On Wed, Aug 11, 2021 at 03:55:08PM +0100, Lorenzo Pieralisi wrote:
> On Wed, Aug 11, 2021 at 03:08:24PM +0100, Christoph Hellwig wrote:
> > On Wed, Aug 11, 2021 at 12:40:28PM +0200, Ard Biesheuvel wrote:
> > > The whole problem we are solving here is that ACPI, being based on
> > > x86, conflates MMIO mappings with memory mappings, and has been using
> > > the same underlying infrastructure for either.
> > 
> > So let's fix that problem instead of papering over it.
> 
> Patch (3) in this series is a fix - I would ask whether it makes
> sense to merge patches (2-3) now and think about reworking the current
> ACPI IO/MEM mapping API later, it can be an invasive change for a fix,
> assuming we agree on how to rework the ACPI IO/MEM mapping API.

What should we do then with this series ?

Thanks,
Lorenzo


From mkorpershoek at baylibre.com  Mon Aug 16 03:00:09 2021
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Mon, 16 Aug 2021 12:00:09 +0200
Subject: [PATCH RESEND v3 0/4] input: MT6358 PMIC button support
Message-ID: <20210816100013.100412-1-mkorpershoek@baylibre.com>

The MediaTek MT6358 PMIC has support for two buttons: PWR and HOME.

The interrupt logic is a little different than other PMICs from the
same family:
for MT6323 and MT6397, we have one interrupt source per button
* for MT6358, we have two interrupts lines per button: the press and
* release interrupts are distinct sources.

Changes since original v2 at [1]:
* added 4th patch with device tree enable
* cover letter title prefixed with 'input'

This has been tested with evtest on mt8183-pumpkin on 5.14-rc6

Mattijs Korpershoek (4):
  Input: mtk-pmic-keys - use get_irq_byname() instead of index
  dt-bindings: input: mtk-pmic-keys: add MT6358 binding definition
  Input: mtk-pmic-keys - add support for MT6358
  arm64: dts: mt6358: add mt6358-keys node

 .../bindings/input/mtk-pmic-keys.txt          |  5 +-
 arch/arm64/boot/dts/mediatek/mt6358.dtsi      | 12 ++++
 drivers/input/keyboard/mtk-pmic-keys.c        | 56 +++++++++++++++++--
 3 files changed, 68 insertions(+), 5 deletions(-)

-- 
2.30.2



From mkorpershoek at baylibre.com  Mon Aug 16 03:00:11 2021
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Mon, 16 Aug 2021 12:00:11 +0200
Subject: [PATCH RESEND v3 2/4] dt-bindings: input: mtk-pmic-keys: add MT6358
 binding definition
In-Reply-To: <20210816100013.100412-1-mkorpershoek@baylibre.com>
References: <20210816100013.100412-1-mkorpershoek@baylibre.com>
Message-ID: <20210816100013.100412-3-mkorpershoek@baylibre.com>

Add the binding documentation of the mtk-pmic-keys for the MT6358 PMICs.

MT6358 is a little different since it used separate IRQs for the
release key (_r) event

Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/input/mtk-pmic-keys.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
index 535d92885372..9d00f2a8e13a 100644
--- a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
+++ b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
@@ -9,7 +9,10 @@ For MT6397/MT6323 MFD bindings see:
 Documentation/devicetree/bindings/mfd/mt6397.txt
 
 Required properties:
-- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
+- compatible: Should be one of:
+	- "mediatek,mt6397-keys"
+	- "mediatek,mt6323-keys"
+	- "mediatek,mt6358-keys"
 - linux,keycodes: See Documentation/devicetree/bindings/input/input.yaml
 
 Optional Properties:
-- 
2.30.2



From mkorpershoek at baylibre.com  Mon Aug 16 03:00:10 2021
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Mon, 16 Aug 2021 12:00:10 +0200
Subject: [PATCH RESEND v3 1/4] Input: mtk-pmic-keys - use get_irq_byname()
 instead of index
In-Reply-To: <20210816100013.100412-1-mkorpershoek@baylibre.com>
References: <20210816100013.100412-1-mkorpershoek@baylibre.com>
Message-ID: <20210816100013.100412-2-mkorpershoek@baylibre.com>

Some pmics of the mt6397 family (such as MT6358), have two IRQs per
physical key: one for press event, another for release event.

The mtk-pmic-keys driver assumes that each key only has one
IRQ. The key index and the RES_IRQ resource index have a 1/1 mapping.

This won't work for MT6358, as we have multiple resources (2) for one key.

To prepare mtk-pmic-keys to support MT6358, retrieve IRQs by name
instead of by index.

Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 drivers/input/keyboard/mtk-pmic-keys.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
index 62391d6c7da6..d1abf95d5701 100644
--- a/drivers/input/keyboard/mtk-pmic-keys.c
+++ b/drivers/input/keyboard/mtk-pmic-keys.c
@@ -241,6 +241,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	unsigned int keycount;
 	struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
 	struct device_node *node = pdev->dev.of_node, *child;
+	static const char *const irqnames[] = { "powerkey", "homekey" };
 	struct mtk_pmic_keys *keys;
 	const struct mtk_pmic_regs *mtk_pmic_regs;
 	struct input_dev *input_dev;
@@ -268,7 +269,8 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	input_dev->id.version = 0x0001;
 
 	keycount = of_get_available_child_count(node);
-	if (keycount > MTK_PMIC_MAX_KEY_COUNT) {
+	if (keycount > MTK_PMIC_MAX_KEY_COUNT ||
+	    keycount > ARRAY_SIZE(irqnames)) {
 		dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
 		return -EINVAL;
 	}
@@ -276,7 +278,8 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	for_each_child_of_node(node, child) {
 		keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
 
-		keys->keys[index].irq = platform_get_irq(pdev, index);
+		keys->keys[index].irq =
+			platform_get_irq_byname(pdev, irqnames[index]);
 		if (keys->keys[index].irq < 0) {
 			of_node_put(child);
 			return keys->keys[index].irq;
-- 
2.30.2



From mkorpershoek at baylibre.com  Mon Aug 16 03:00:13 2021
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Mon, 16 Aug 2021 12:00:13 +0200
Subject: [PATCH RESEND v3 4/4] arm64: dts: mt6358: add mt6358-keys node
In-Reply-To: <20210816100013.100412-1-mkorpershoek@baylibre.com>
References: <20210816100013.100412-1-mkorpershoek@baylibre.com>
Message-ID: <20210816100013.100412-5-mkorpershoek@baylibre.com>

This enables the power,home keys on MediaTek boards with a mt6358 pmic.

Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 arch/arm64/boot/dts/mediatek/mt6358.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
index fa159b20379e..a1b017a6a751 100644
--- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
@@ -2,6 +2,7 @@
 /*
  * Copyright (c) 2020 MediaTek Inc.
  */
+#include <dt-bindings/input/input.h>
 
 &pwrap {
 	pmic: mt6358 {
@@ -356,5 +357,16 @@ mt6358_vsim2_reg: ldo_vsim2 {
 		mt6358rtc: mt6358rtc {
 			compatible = "mediatek,mt6358-rtc";
 		};
+
+		mt6358keys: mt6358keys {
+			compatible = "mediatek,mt6358-keys";
+			power {
+				linux,keycodes = <KEY_POWER>;
+				wakeup-source;
+			};
+			home {
+				linux,keycodes = <KEY_HOME>;
+			};
+		};
 	};
 };
-- 
2.30.2



From mkorpershoek at baylibre.com  Mon Aug 16 03:00:12 2021
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Mon, 16 Aug 2021 12:00:12 +0200
Subject: [PATCH RESEND v3 3/4] Input: mtk-pmic-keys - add support for MT6358
In-Reply-To: <20210816100013.100412-1-mkorpershoek@baylibre.com>
References: <20210816100013.100412-1-mkorpershoek@baylibre.com>
Message-ID: <20210816100013.100412-4-mkorpershoek@baylibre.com>

MT6358 pmic keys behave differently than mt6397 and mt6323: there are
two interrupts per key: one for press, the other one for release (_r)

Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 drivers/input/keyboard/mtk-pmic-keys.c | 49 ++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
index d1abf95d5701..5496a7020104 100644
--- a/drivers/input/keyboard/mtk-pmic-keys.c
+++ b/drivers/input/keyboard/mtk-pmic-keys.c
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mfd/mt6323/registers.h>
+#include <linux/mfd/mt6358/registers.h>
 #include <linux/mfd/mt6397/core.h>
 #include <linux/mfd/mt6397/registers.h>
 #include <linux/module.h>
@@ -74,11 +75,22 @@ static const struct mtk_pmic_regs mt6323_regs = {
 	.pmic_rst_reg = MT6323_TOP_RST_MISC,
 };
 
+static const struct mtk_pmic_regs mt6358_regs = {
+	.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
+		MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS,
+		0x2, MT6358_PSC_TOP_INT_CON0, 0x5),
+	.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
+		MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS,
+		0x8, MT6358_PSC_TOP_INT_CON0, 0xa),
+	.pmic_rst_reg = MT6358_TOP_RST_MISC,
+};
+
 struct mtk_pmic_keys_info {
 	struct mtk_pmic_keys *keys;
 	const struct mtk_pmic_keys_regs *regs;
 	unsigned int keycode;
 	int irq;
+	int irq_r; /* optional: release irq if different */
 	bool wakeup:1;
 };
 
@@ -188,6 +200,19 @@ static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys,
 		return ret;
 	}
 
+	if (info->irq_r > 0) {
+		ret = devm_request_threaded_irq(
+			keys->dev, info->irq_r, NULL,
+			mtk_pmic_keys_irq_handler_thread,
+			IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mtk-pmic-keys",
+			info);
+		if (ret) {
+			dev_err(keys->dev, "Failed to request IRQ_r: %d: %d\n",
+				info->irq, ret);
+			return ret;
+		}
+	}
+
 	input_set_capability(keys->input_dev, EV_KEY, info->keycode);
 
 	return 0;
@@ -199,8 +224,11 @@ static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev)
 	int index;
 
 	for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
-		if (keys->keys[index].wakeup)
+		if (keys->keys[index].wakeup) {
 			enable_irq_wake(keys->keys[index].irq);
+			if (keys->keys[index].irq_r > 0)
+				enable_irq_wake(keys->keys[index].irq_r);
+		}
 	}
 
 	return 0;
@@ -212,8 +240,11 @@ static int __maybe_unused mtk_pmic_keys_resume(struct device *dev)
 	int index;
 
 	for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
-		if (keys->keys[index].wakeup)
+		if (keys->keys[index].wakeup) {
 			disable_irq_wake(keys->keys[index].irq);
+			if (keys->keys[index].irq_r > 0)
+				disable_irq_wake(keys->keys[index].irq_r);
+		}
 	}
 
 	return 0;
@@ -229,6 +260,9 @@ static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = {
 	}, {
 		.compatible = "mediatek,mt6323-keys",
 		.data = &mt6323_regs,
+	}, {
+		.compatible = "mediatek,mt6358-keys",
+		.data = &mt6358_regs,
 	}, {
 		/* sentinel */
 	}
@@ -242,6 +276,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
 	struct device_node *node = pdev->dev.of_node, *child;
 	static const char *const irqnames[] = { "powerkey", "homekey" };
+	static const char *const irqnames_r[] = { "powerkey_r", "homekey_r" };
 	struct mtk_pmic_keys *keys;
 	const struct mtk_pmic_regs *mtk_pmic_regs;
 	struct input_dev *input_dev;
@@ -285,6 +320,16 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 			return keys->keys[index].irq;
 		}
 
+		if (of_device_is_compatible(node, "mediatek,mt6358-keys")) {
+			keys->keys[index].irq_r = platform_get_irq_byname(
+				pdev, irqnames_r[index]);
+
+			if (keys->keys[index].irq_r < 0) {
+				of_node_put(child);
+				return keys->keys[index].irq_r;
+			}
+		}
+
 		error = of_property_read_u32(child,
 			"linux,keycodes", &keys->keys[index].keycode);
 		if (error) {
-- 
2.30.2



From ardb at kernel.org  Mon Aug 16 03:21:37 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 16 Aug 2021 12:21:37 +0200
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <20210816095854.GA2599@lpieralisi>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
 <YRKtEDycefrZLB3X@infradead.org>
 <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
 <YRPZ2Kqb/MFggHzQ@infradead.org> <20210811145508.GA3650@lpieralisi>
 <20210816095854.GA2599@lpieralisi>
Message-ID: <CAMj1kXHM8tG2f-i6u8Ohb0RV9XTqq2N1Oooz_Q2kvLpdfTMxqw@mail.gmail.com>

On Mon, 16 Aug 2021 at 11:59, Lorenzo Pieralisi
<lorenzo.pieralisi at arm.com> wrote:
>
> On Wed, Aug 11, 2021 at 03:55:08PM +0100, Lorenzo Pieralisi wrote:
> > On Wed, Aug 11, 2021 at 03:08:24PM +0100, Christoph Hellwig wrote:
> > > On Wed, Aug 11, 2021 at 12:40:28PM +0200, Ard Biesheuvel wrote:
> > > > The whole problem we are solving here is that ACPI, being based on
> > > > x86, conflates MMIO mappings with memory mappings, and has been using
> > > > the same underlying infrastructure for either.
> > >
> > > So let's fix that problem instead of papering over it.
> >
> > Patch (3) in this series is a fix - I would ask whether it makes
> > sense to merge patches (2-3) now and think about reworking the current
> > ACPI IO/MEM mapping API later, it can be an invasive change for a fix,
> > assuming we agree on how to rework the ACPI IO/MEM mapping API.
>
> What should we do then with this series ?
>

It is not even clear that reworking the ACPI core is feasible to begin
with, OTOH, fixing a sparse warning is arguably not a critical bug fix
either, so I'd suggest we just drop that bit.


From ulf.hansson at linaro.org  Mon Aug 16 03:27:04 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 16 Aug 2021 12:27:04 +0200
Subject: [PATCH v2] mmc: mediatek: add wait dma stop done flow
In-Reply-To: <20210809072315.1127-1-derong.liu@mediatek.com>
References: <20210809072315.1127-1-derong.liu@mediatek.com>
Message-ID: <CAPDyKFq3_eia7cvo-1Ajj5wcrfEHtp_EsMp27uL4dC_n+vPWZQ@mail.gmail.com>

On Mon, 9 Aug 2021 at 09:25, Derong Liu <derong.liu at mediatek.com> wrote:
>
> We found this issue on a 5G platform, during CMDQ error handling, if DMA status is active when it call msdc_reset_hw, it means mmc host hw reset and DMA transfer will be parallel, mmc host may access sram region unexpectedly.
>
> According to the programming guide of mtk mmc host,it needs to wait for dma stop done after set dma stop.
> This change should be applied to all SoCs.
>
> Signed-off-by: Derong Liu <derong.liu at mediatek.com>
> ---
>  drivers/mmc/host/mtk-sd.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 4dfc246c5f95..1dfd2842471b 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -2339,6 +2339,8 @@ static void msdc_cqe_disable(struct mmc_host *mmc, bool recovery)
>         if (recovery) {
>                 sdr_set_field(host->base + MSDC_DMA_CTRL,
>                               MSDC_DMA_CTRL_STOP, 1);
> +               while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS)
> +                       cpu_relax();

I suggest you look into using readl_poll_timeout() - as we don't want
to hang indefinitely, no matter what.

>                 msdc_reset_hw(host);
>         }
>  }
> --
> 2.18.0

Kind regards
Uffe


From vee.khee.wong at linux.intel.com  Mon Aug 16 03:47:46 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Mon, 16 Aug 2021 18:47:46 +0800
Subject: [PATCH net-next v1 1/3] net: stmmac: fix INTR TBU status
 affecting irq count statistic
In-Reply-To: <f82f52076841285309a997f849e2786781548538.1629092894.git.vijayakannan.ayyathurai@intel.com>
References: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
 <f82f52076841285309a997f849e2786781548538.1629092894.git.vijayakannan.ayyathurai@intel.com>
Message-ID: <20210816104746.GA9014@linux.intel.com>

On Mon, Aug 16, 2021 at 02:15:58PM +0800, Vijayakannan Ayyathurai wrote:
> From: Voon Weifeng <weifeng.voon at intel.com>
> 
> DMA channel status "Transmit buffer unavailable(TBU)" bit is not
> considered as a successful dma tx. Hence, it should not affect
> all the irq count statistic.
>

Acked-by: Wong Vee Khee <vee.khee.wong at linux.intel.com>
 
> Fixes: 1103d3a5531c ("net: stmmac: dwmac4: Also use TBU interrupt to clean TX path")
> Signed-off-by: Voon Weifeng <weifeng.voon at intel.com>
> Signed-off-by: Vijayakannan Ayyathurai <vijayakannan.ayyathurai at intel.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> index e63270267578..f83db62938dd 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> @@ -172,11 +172,12 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
>  		x->rx_normal_irq_n++;
>  		ret |= handle_rx;
>  	}
> -	if (likely(intr_status & (DMA_CHAN_STATUS_TI |
> -		DMA_CHAN_STATUS_TBU))) {
> +	if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
>  		x->tx_normal_irq_n++;
>  		ret |= handle_tx;
>  	}
> +	if (unlikely(intr_status & DMA_CHAN_STATUS_TBU))
> +		ret |= handle_tx;
>  	if (unlikely(intr_status & DMA_CHAN_STATUS_ERI))
>  		x->rx_early_irq++;
>  


From zhiyong.tao at mediatek.com  Mon Aug 16 03:48:05 2021
From: zhiyong.tao at mediatek.com (zhiyong.tao)
Date: Mon, 16 Aug 2021 18:48:05 +0800
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
Message-ID: <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>

On Mon, 2021-08-16 at 14:10 +0800, Chen-Yu Tsai wrote:
> On Thu, Aug 5, 2021 at 7:02 AM Linus Walleij <
> linus.walleij at linaro.org> wrote:
> > 
> > On Thu, Jul 29, 2021 at 11:43 AM Chen-Yu Tsai <wenst at chromium.org>
> > wrote:
> > > On Thu, Jul 29, 2021 at 4:23 PM zhiyong.tao <
> > > zhiyong.tao at mediatek.com> wrote:
> > > > The rsel actual bias resistance of each setting is different in
> > > > different IC. we think that the define "MTK_PULL_SET_RSEL_000"
> > > > is more
> > > > common for all different IC.
> > > 
> > > I see. I personally prefer having things clearly described. I can
> > > understand this might be an extra burden to support different
> > > chips
> > > with different parameters, though this should be fairly
> > > straightforward
> > > with lookup tables tied to the compatible strings.
> > > 
> > > Let's see if Rob and Linus have anything to add.
> > 
> > Not much. We have "soft pushed" for this to be described as generic
> > as possible, using SI units (ohms). But we also allow vendor-
> > specific
> > numbers in this attribute. Especially when reverse engineering SoCs
> > that the contributor don't really have specs on (example M1 Mac).
> > 
> > The intent with the SI units is especially for people like you
> > folks working
> > with Chromium to be able to use different SoCs and not feel lost
> > to a forest of different ways of doing things and associated
> > mistakes because vendors have hopelessly idiomatic pin configs.
> 
> I'll take that as "use SI units whenever possible and reasonable".

==> so It doesn't need to change the define, is it right? 
we will keep the common define.

Thanks.
> 
> Thanks.
> 
> ChenYu

From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:34 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:34 +0800
Subject: [v3 03/15] iio: adc: aspeed: set driver data when adc probe.
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-4-billy_tsai@aspeedtech.com>

Fix the issue when adc remove will get the null driver data.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 7010d56ac3b9..20462cf659e4 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -201,6 +201,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	platform_set_drvdata(pdev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->base))
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:33 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:33 +0800
Subject: [v3 02/15] iio: adc: aspeed: completes the bitfield declare.
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-3-billy_tsai@aspeedtech.com>

This patch completes the declare of adc register bitfields and uses the
same prefix ASPEED_ADC_* for these bitfields.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 56 +++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 19efaa41bc34..7010d56ac3b9 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -3,6 +3,7 @@
  * Aspeed AST2400/2500 ADC
  *
  * Copyright (C) 2017 Google, Inc.
+ * Copyright (C) 2021 Aspeed Technology Inc.
  */
 
 #include <linux/clk.h>
@@ -16,6 +17,7 @@
 #include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/bitfield.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
@@ -28,15 +30,31 @@
 #define ASPEED_REG_INTERRUPT_CONTROL	0x04
 #define ASPEED_REG_VGA_DETECT_CONTROL	0x08
 #define ASPEED_REG_CLOCK_CONTROL	0x0C
-#define ASPEED_REG_MAX			0xC0
-
-#define ASPEED_OPERATION_MODE_POWER_DOWN	(0x0 << 1)
-#define ASPEED_OPERATION_MODE_STANDBY		(0x1 << 1)
-#define ASPEED_OPERATION_MODE_NORMAL		(0x7 << 1)
-
-#define ASPEED_ENGINE_ENABLE		BIT(0)
-
-#define ASPEED_ADC_CTRL_INIT_RDY	BIT(8)
+#define ASPEED_REG_COMPENSATION_TRIM	0xC4
+#define ASPEED_REG_MAX			0xCC
+
+#define ASPEED_ADC_ENGINE_ENABLE		BIT(0)
+#define ASPEED_ADC_OP_MODE			GENMASK(3, 1)
+#define ASPEED_ADC_OP_MODE_PWR_DOWN		0
+#define ASPEED_ADC_OP_MODE_STANDBY		1
+#define ASPEED_ADC_OP_MODE_NORMAL		7
+#define ASPEED_ADC_CTRL_COMPENSATION		BIT(4)
+#define ASPEED_ADC_AUTO_COMPENSATION		BIT(5)
+#define ASPEED_ADC_REF_VOLTAGE			GENMASK(7, 6)
+#define ASPEED_ADC_REF_VOLTAGE_2500mV		0
+#define ASPEED_ADC_REF_VOLTAGE_1200mV		1
+#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH		2
+#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW		3
+#define ASPEED_ADC_BAT_SENSING_DIV		BIT(6)
+#define ASPEED_ADC_BAT_SENSING_DIV_2_3		0
+#define ASPEED_ADC_BAT_SENSING_DIV_1_3		1
+#define ASPEED_ADC_CTRL_INIT_RDY		BIT(8)
+#define ASPEED_ADC_CH7_MODE			BIT(12)
+#define ASPEED_ADC_CH7_NORMAL			0
+#define ASPEED_ADC_CH7_BAT			1
+#define ASPEED_ADC_BAT_SENSING_ENABLE		BIT(13)
+#define ASPEED_ADC_CTRL_CHANNEL			GENMASK(31, 16)
+#define ASPEED_ADC_CTRL_CHANNEL_ENABLE(ch)	FIELD_PREP(ASPEED_ADC_CTRL_CHANNEL, BIT(ch))
 
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
@@ -226,7 +244,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	if (model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
-		writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
+		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+				  ASPEED_ADC_OP_MODE_NORMAL) |
+			       ASPEED_ADC_ENGINE_ENABLE,
 		       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 		/* Wait for initial sequence complete. */
@@ -245,10 +265,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		goto clk_enable_error;
 
-	adc_engine_control_reg_val = GENMASK(31, 16) |
-		ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE;
+	adc_engine_control_reg_val =
+		ASPEED_ADC_CTRL_CHANNEL |
+		FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
+		ASPEED_ADC_ENGINE_ENABLE;
 	writel(adc_engine_control_reg_val,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 	model_data = of_device_get_match_data(&pdev->dev);
 	indio_dev->name = model_data->model_name;
@@ -264,8 +286,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	return 0;
 
 iio_register_error:
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
 poll_timeout_error:
@@ -283,8 +305,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
 	clk_hw_unregister_divider(data->clk_scaler);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:31 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:31 +0800
Subject: [v3 00/15] Add support for ast2600 ADC
Message-ID: <20210816104846.13155-1-billy_tsai@aspeedtech.com>

This patch serials make aspeed_adc.c can support ast2600 and backward
compatible.

Change since v2:
dt-bindings:
  - Create a new dt-bindings for ast2600 adc
aspeed_adc.c:
  - Splits the patch for more details
  - Remove version enum and use the flags in model data to distinguish
  hardware feature
  - Support trimming data get and set.
  - Use devm_add_action_or_reset to simplify probe error handling.

Changes since v1:
dt-bindings:
  - Fix the aspeed,adc.yaml check error.
  - Add battery-sensing property.
aspeed_adc.c:
  - Change the init flow:
    Clock and reference voltage setting should be completed before adc
    engine enable.
  - Change the default sampling rate to meet most user case.
  - Add patch #8 to suppoert battery sensing mode.

Billy Tsai (15):
  dt-bindings: iio: adc: Add ast2600-adc bindings
  iio: adc: aspeed: completes the bitfield declare.
  iio: adc: aspeed: set driver data when adc probe.
  iio: adc: aspeed: Keep model data to driver data.
  iio: adc: aspeed: Refactory model data structure
  iio: adc: aspeed: Add vref config function
  iio: adc: aspeed: Set num_channels with model data
  iio: adc: aspeed: Use model_data to set clk scaler.
  iio: adc: aspeed: Use devm_add_action_or_reset.
  iio: adc: aspeed: Support ast2600 adc.
  iio: adc: aspeed: Fix the calculate error of clock.
  iio: adc: aspeed: Add func to set sampling rate.
  iio: adc: aspeed: Add compensation phase.
  iio: adc: aspeed: Support battery sensing.
  iio: adc: aspeed: Get and set trimming data.

 .../bindings/iio/adc/aspeed,ast2600-adc.yaml  |  98 +++
 drivers/iio/adc/aspeed_adc.c                  | 562 +++++++++++++++---
 2 files changed, 570 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml

-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:32 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:32 +0800
Subject: [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-2-billy_tsai@aspeedtech.com>

Add device tree bindings document for the aspeed ast2600 adc device
driver.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 .../bindings/iio/adc/aspeed,ast2600-adc.yaml  | 98 +++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml

diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
new file mode 100644
index 000000000000..28bff89e0d75
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ADC that forms part of an ASPEED server management processor.
+
+maintainers:
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+description: |
+  ? 10-bits resolution for 16 voltage channels.
+  ? The device split into two individual engine and each contains 8 voltage
+  channels.
+  ? Channel scanning can be non-continuous.
+  ? Programmable ADC clock frequency.
+  ? Programmable upper and lower threshold for each channels.
+  ? Interrupt when larger or less than threshold for each channels.
+  ? Support hysteresis for each channels.
+  ? Built-in a compensating method.
+  ? Built-in a register to trim internal reference voltage.
+  ? Internal or External reference voltage.
+  ? Support 2 Internal reference voltage 1.2v or 2.5v.
+  ? Integrate dividing circuit for battery sensing.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2600-adc0
+      - aspeed,ast2600-adc1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    description:
+      Input clock used to derive the sample clock. Expected to be the
+      SoC's APB clock.
+
+  resets:
+    maxItems: 1
+
+  "#io-channel-cells":
+    const: 1
+
+  vref-supply:
+    description:
+      The external regulator supply ADC reference voltage.
+
+  aspeed,int_vref_mv:
+    enum:
+      - 1200
+      - 2500
+    description:
+      ADC internal reference voltage in millivolts.
+
+  aspeed,battery-sensing:
+    type: boolean
+    description:
+      Inform the driver that last channel will be used to sensor battery.
+
+  aspeed,trim-data-valid:
+    type: boolean
+    description: |
+      The ADC reference voltage can be calibrated to obtain the trimming
+      data which will be stored in otp. This property informs the driver that
+      the data store in the otp is valid.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+  - "#io-channel-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/ast2600-clock.h>
+    adc0: adc at 1e6e9000 {
+        compatible = "aspeed,ast2600-adc0";
+        reg = <0x1e6e9000 0x100>;
+        clocks = <&syscon ASPEED_CLK_APB2>;
+        resets = <&syscon ASPEED_RESET_ADC>;
+        #io-channel-cells = <1>;
+        aspeed,int_vref_mv = <2500>;
+    };
+    adc1: adc at 1e6e9100 {
+        compatible = "aspeed,ast2600-adc1";
+        reg = <0x1e6e9100 0x100>;
+        clocks = <&syscon ASPEED_CLK_APB2>;
+        resets = <&syscon ASPEED_RESET_ADC>;
+        #io-channel-cells = <1>;
+        aspeed,int_vref_mv = <2500>;
+    };
+...
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:38 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:38 +0800
Subject: [v3 07/15] iio: adc: aspeed: Set num_channels with model data
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-8-billy_tsai@aspeedtech.com>

Use the model_data member num_channels to set the num_channels of iio
device.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f260e40ab9b2..2d6215a91f99 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -291,7 +291,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-	indio_dev->num_channels = ARRAY_SIZE(aspeed_adc_iio_channels);
+	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
 	if (ret)
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:35 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:35 +0800
Subject: [v3 04/15] iio: adc: aspeed: Keep model data to driver data.
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-5-billy_tsai@aspeedtech.com>

Keep the model data pointer to driver data for reducing the usage of
of_device_get_match_data().

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 20462cf659e4..d85aa31ee3b1 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -69,6 +69,7 @@ struct aspeed_adc_model_data {
 
 struct aspeed_adc_data {
 	struct device		*dev;
+	const struct aspeed_adc_model_data *model_data;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
 	struct clk_hw		*clk_prescaler;
@@ -110,8 +111,6 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       int *val, int *val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -119,7 +118,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = model_data->vref_voltage;
+		*val = data->model_data->vref_voltage;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -138,13 +137,11 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,
 				int val, int val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val < model_data->min_sampling_rate ||
-			val > model_data->max_sampling_rate)
+		if (val < data->model_data->min_sampling_rate ||
+			val > data->model_data->max_sampling_rate)
 			return -EINVAL;
 
 		clk_set_rate(data->clk_scaler->clk,
@@ -190,7 +187,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
 	struct aspeed_adc_data *data;
-	const struct aspeed_adc_model_data *model_data;
 	const char *clk_parent_name;
 	int ret;
 	u32 adc_engine_control_reg_val;
@@ -201,6 +197,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	data->model_data = of_device_get_match_data(&pdev->dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
@@ -241,9 +238,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-
-	if (model_data->wait_init_sequence) {
+	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
 				  ASPEED_ADC_OP_MODE_NORMAL) |
@@ -273,8 +268,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	writel(adc_engine_control_reg_val,
 	       data->base + ASPEED_REG_ENGINE_CONTROL);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-	indio_dev->name = model_data->model_name;
+	indio_dev->name = data->model_data->model_name;
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:36 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:36 +0800
Subject: [v3 05/15] iio: adc: aspeed: Refactory model data structure
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-6-billy_tsai@aspeedtech.com>

This patch refactory the model data structure to distinguish the
function form differnet version of aspeed adc.
- Rename the vref_voltag to vref_fixed and add vref driver data
When driver probe will check vref_fixed value and store it
to vref which isn't const value.
- Add num_channels
Make num_channles of iio device can be changed by differnet model_data
- Add need_prescaler flag and scaler_bit_width
The need_prescaler flag used to tell the driver the clock divider needs
another prescaler and the scaler_bit_width to set the clock divider
bitfiled width.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index d85aa31ee3b1..f03c7921d534 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -63,8 +63,11 @@ struct aspeed_adc_model_data {
 	const char *model_name;
 	unsigned int min_sampling_rate;	// Hz
 	unsigned int max_sampling_rate;	// Hz
-	unsigned int vref_voltage;	// mV
+	unsigned int vref_fixed;	// mV
 	bool wait_init_sequence;
+	bool need_prescaler;
+	u8 scaler_bit_width;
+	unsigned int num_channels;
 };
 
 struct aspeed_adc_data {
@@ -75,6 +78,7 @@ struct aspeed_adc_data {
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
+	int			vref;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -118,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = data->model_data->vref_voltage;
+		*val = data->model_data->vref_fixed;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -312,17 +316,23 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 
 static const struct aspeed_adc_model_data ast2400_model_data = {
 	.model_name = "ast2400-adc",
-	.vref_voltage = 2500, // mV
+	.vref_fixed = 2500, // mV
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
+	.need_prescaler = true,
+	.scaler_bit_width = 10,
+	.num_channels = 16,
 };
 
 static const struct aspeed_adc_model_data ast2500_model_data = {
 	.model_name = "ast2500-adc",
-	.vref_voltage = 1800, // mV
+	.vref_fixed = 1800, // mV
 	.min_sampling_rate = 1,
 	.max_sampling_rate = 1000000,
 	.wait_init_sequence = true,
+	.need_prescaler = true,
+	.scaler_bit_width = 10,
+	.num_channels = 16,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:37 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:37 +0800
Subject: [v3 06/15] iio: adc: aspeed: Add vref config function
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-7-billy_tsai@aspeedtech.com>

Add the function to check the vref_fixed and set the value to driver
data.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f03c7921d534..f260e40ab9b2 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -122,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = data->model_data->vref_fixed;
+		*val = data->vref;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -187,6 +187,17 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	if (data->model_data->vref_fixed) {
+		data->vref = data->model_data->vref_fixed;
+		return 0;
+	}
+	return 0;
+}
+
 static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
@@ -242,6 +253,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
+	ret = aspeed_adc_vref_config(indio_dev);
+	if (ret)
+		goto vref_config_error;
+
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
@@ -290,6 +305,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
 poll_timeout_error:
+vref_config_error:
 	reset_control_assert(data->rst);
 reset_error:
 	clk_hw_unregister_divider(data->clk_scaler);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:40 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:40 +0800
Subject: [v3 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-10-billy_tsai@aspeedtech.com>

This patch use devm_add_action_or_reset to handle the error in probe
phase.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 92 +++++++++++++++++++++---------------
 1 file changed, 55 insertions(+), 37 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 52db38be9699..1c87e12a0cab 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -187,6 +187,27 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static void aspeed_adc_unregister_divider(void *data)
+{
+	struct clk_hw *clk = data;
+
+	clk_hw_unregister_divider(clk);
+}
+
+static void aspeed_adc_reset_assert(void *data)
+{
+	struct reset_control *rst = data;
+
+	reset_control_assert(rst);
+}
+
+static void aspeed_adc_clk_disable_unprepare(void *data)
+{
+	struct clk *clk = data;
+
+	clk_disable_unprepare(clk);
+}
+
 static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			&data->clk_lock);
 		if (IS_ERR(data->clk_prescaler))
 			return PTR_ERR(data->clk_prescaler);
+
+		ret = devm_add_action_or_reset(data->dev,
+					       aspeed_adc_unregister_divider,
+					       data->clk_prescaler);
+		if (ret)
+			return ret;
 		snprintf(clk_parent_name, 32, clk_name);
 		scaler_flags = CLK_SET_RATE_PARENT;
 	}
@@ -244,23 +271,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
 		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
 		data->model_data->scaler_bit_width, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_scaler)) {
-		ret = PTR_ERR(data->clk_scaler);
-		goto scaler_error;
-	}
+	if (IS_ERR(data->clk_scaler))
+		return PTR_ERR(data->clk_scaler);
+
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
+				       data->clk_scaler);
+	if (ret)
+		return ret;
 
 	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(data->rst)) {
 		dev_err(&pdev->dev,
 			"invalid or missing reset controller device tree entry");
-		ret = PTR_ERR(data->rst);
-		goto reset_error;
+		return PTR_ERR(data->rst);
 	}
 	reset_control_deassert(data->rst);
 
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
+				       data->rst);
+	if (ret)
+		return ret;
+
 	ret = aspeed_adc_vref_config(indio_dev);
 	if (ret)
-		goto vref_config_error;
+		return ret;
 
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
@@ -277,13 +311,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 					 ASPEED_ADC_INIT_POLLING_TIME,
 					 ASPEED_ADC_INIT_TIMEOUT);
 		if (ret)
-			goto poll_timeout_error;
+			return ret;
 	}
 
 	/* Start all channels in normal mode. */
 	ret = clk_prepare_enable(data->clk_scaler->clk);
 	if (ret)
-		goto clk_enable_error;
+		return ret;
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_clk_disable_unprepare,
+				       data->clk_scaler->clk);
+	if (ret)
+		return ret;
 
 	adc_engine_control_reg_val =
 		ASPEED_ADC_CTRL_CHANNEL |
@@ -299,41 +339,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto iio_register_error;
-
+	if (ret) {
+		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+				  ASPEED_ADC_OP_MODE_PWR_DOWN),
+		       data->base + ASPEED_REG_ENGINE_CONTROL);
+		return ret;
+	}
 	return 0;
-
-iio_register_error:
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-clk_enable_error:
-poll_timeout_error:
-vref_config_error:
-	reset_control_assert(data->rst);
-reset_error:
-	clk_hw_unregister_divider(data->clk_scaler);
-scaler_error:
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-	return ret;
 }
 
 static int aspeed_adc_remove(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-	struct aspeed_adc_data *data = iio_priv(indio_dev);
-
 	iio_device_unregister(indio_dev);
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-	reset_control_assert(data->rst);
-	clk_hw_unregister_divider(data->clk_scaler);
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-
 	return 0;
 }
 
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 16 03:48:42 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 16 Aug 2021 18:48:42 +0800
Subject: [v3 11/15] iio: adc: aspeed: Fix the calculate error of clock.
In-Reply-To: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
Message-ID: <20210816104846.13155-12-billy_tsai@aspeedtech.com>

The adc clcok formula is
ast2400/2500:
ADC clock period = PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
ast2600:
ADC clock period = PCLK * 2 * (ADC0C[15:0] + 1)
They all have one fixed divided 2 and the legacy driver didn't handle it.
This patch register the fixed factory clock device as the parent of adc
clock scaler to fix this issue.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index ea3e9a52fcc9..8fe7da1a651f 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -4,6 +4,12 @@
  *
  * Copyright (C) 2017 Google, Inc.
  * Copyright (C) 2021 Aspeed Technology Inc.
+ *
+ * ADC clock formula:
+ * Ast2400/Ast2500:
+ * clock period = period of PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
+ * Ast2600:
+ * clock period = period of PCLK * 2 * (ADC0C[15:0] + 1)
  */
 
 #include <linux/clk.h>
@@ -77,6 +83,7 @@ struct aspeed_adc_data {
 	struct regulator	*regulator;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
+	struct clk_hw		*fixed_div_clk;
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
@@ -196,6 +203,13 @@ static void aspeed_adc_unregister_divider(void *data)
 	clk_hw_unregister_divider(clk);
 }
 
+static void aspeed_adc_unregister_fixed_divider(void *data)
+{
+	struct clk_hw *clk = data;
+
+	clk_hw_unregister_fixed_factor(clk);
+}
+
 static void aspeed_adc_reset_assert(void *data)
 {
 	struct reset_control *rst = data;
@@ -312,6 +326,18 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	/* Register ADC clock prescaler with source specified by device tree. */
 	spin_lock_init(&data->clk_lock);
 	snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));
+	snprintf(clk_name, 32, "%s-fixed-div", data->model_data->model_name);
+	data->fixed_div_clk = clk_hw_register_fixed_factor(
+		&pdev->dev, clk_name, clk_parent_name, 0, 1, 2);
+	if (IS_ERR(data->fixed_div_clk))
+		return PTR_ERR(data->fixed_div_clk);
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_unregister_fixed_divider,
+				       data->clk_prescaler);
+	if (ret)
+		return ret;
+	snprintf(clk_parent_name, 32, clk_name);
 	if (data->model_data->need_prescaler) {
 		snprintf(clk_name, 32, "%s-prescaler",
 			 data->model_data->model_name);
-- 
2.25.1



From vee.khee.wong at linux.intel.com  Mon Aug 16 03:50:37 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Mon, 16 Aug 2021 18:50:37 +0800
Subject: [PATCH net-next v1 2/3] net: stmmac: add ethtool per-queue
 statistic framework
In-Reply-To: <b0fd3bf4e5c105e959df60d3c876297721b62ee6.1629092894.git.vijayakannan.ayyathurai@intel.com>
References: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
 <b0fd3bf4e5c105e959df60d3c876297721b62ee6.1629092894.git.vijayakannan.ayyathurai@intel.com>
Message-ID: <20210816105037.GA11930@linux.intel.com>

On Mon, Aug 16, 2021 at 02:15:59PM +0800, Vijayakannan Ayyathurai wrote:
> Adding generic ethtool per-queue statistic framework to display the
> statistics for each rx/tx queue. In future, users can avail it to add
> more per-queue specific counters. Number of rx/tx queues displayed is
> depending on the available rx/tx queues in that particular MAC config
> and this number is limited up to the MTL_MAX_{RX|TX}_QUEUES defined
> in the driver.
> 
> Ethtool per-queue statistic display will look like below, when users
> start adding more counters.
> 
> Example:
>  q0_tx_statA:
>  q0_tx_statB:
>  q0_tx_statC:
>  |
>  q0_tx_statX:
>  .
>  .
>  .
>  qMAX_tx_statA:
>  qMAX_tx_statB:
>  qMAX_tx_statC:
>  |
>  qMAX_tx_statX:
> 
>  q0_rx_statA:
>  q0_rx_statB:
>  q0_rx_statC:
>  |
>  q0_rx_statX:
>  .
>  .
>  .
>  qMAX_rx_statA:
>  qMAX_rx_statB:
>  qMAX_rx_statC:
>  |
>  qMAX_rx_statX:
> 
> In addition, this patch has the support on displaying the number of
> packets received and transmitted per queue.
>

Acked-by: Wong Vee Khee <vee.khee.wong at linux.intel.com>

> Signed-off-by: Vijayakannan Ayyathurai <vijayakannan.ayyathurai at intel.com>
> ---


From vee.khee.wong at linux.intel.com  Mon Aug 16 03:53:23 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Mon, 16 Aug 2021 18:53:23 +0800
Subject: [PATCH net-next v1 3/3] net: stmmac: add ethtool per-queue irq
 statistic support
In-Reply-To: <5c956016465b688a2679bd02da1f751046be189c.1629092894.git.vijayakannan.ayyathurai@intel.com>
References: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
 <5c956016465b688a2679bd02da1f751046be189c.1629092894.git.vijayakannan.ayyathurai@intel.com>
Message-ID: <20210816105323.GA13779@linux.intel.com>

On Mon, Aug 16, 2021 at 02:16:00PM +0800, Vijayakannan Ayyathurai wrote:
> Adding ethtool per-queue statistics support to show number of interrupts
> generated at DMA tx and DMA rx. All the counters are incremented at
> dwmac4_dma_interrupt function.
>

Acked-by: Wong Vee Khee <vee.khee.wong at linux.intel.com>
 
> Signed-off-by: Vijayakannan Ayyathurai <vijayakannan.ayyathurai at intel.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/common.h         | 2 ++
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c     | 2 ++
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 ++
>  3 files changed, 6 insertions(+)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 79333deef2e2..b6d945ea903d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -60,10 +60,12 @@
>  
>  struct stmmac_txq_stats {
>  	unsigned long tx_pkt_n;
> +	unsigned long tx_normal_irq_n;
>  };
>  
>  struct stmmac_rxq_stats {
>  	unsigned long rx_pkt_n;
> +	unsigned long rx_normal_irq_n;
>  };
>  
>  /* Extra statistic and debug information exposed by ethtool */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> index f83db62938dd..9292a1fab7d3 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
> @@ -170,10 +170,12 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
>  		x->normal_irq_n++;
>  	if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
>  		x->rx_normal_irq_n++;
> +		x->rxq_stats[chan].rx_normal_irq_n++;
>  		ret |= handle_rx;
>  	}
>  	if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
>  		x->tx_normal_irq_n++;
> +		x->txq_stats[chan].tx_normal_irq_n++;
>  		ret |= handle_tx;
>  	}
>  	if (unlikely(intr_status & DMA_CHAN_STATUS_TBU))
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> index 10c0895d0b43..595c3ccdcbb7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> @@ -263,11 +263,13 @@ static const struct stmmac_stats stmmac_mmc[] = {
>  
>  static const char stmmac_qstats_tx_string[][ETH_GSTRING_LEN] = {
>  	"tx_pkt_n",
> +	"tx_irq_n",
>  #define STMMAC_TXQ_STATS ARRAY_SIZE(stmmac_qstats_tx_string)
>  };
>  
>  static const char stmmac_qstats_rx_string[][ETH_GSTRING_LEN] = {
>  	"rx_pkt_n",
> +	"rx_irq_n",
>  #define STMMAC_RXQ_STATS ARRAY_SIZE(stmmac_qstats_rx_string)
>  };
>  


From robin.murphy at arm.com  Mon Aug 16 03:59:24 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 16 Aug 2021 11:59:24 +0100
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <CAMj1kXHM8tG2f-i6u8Ohb0RV9XTqq2N1Oooz_Q2kvLpdfTMxqw@mail.gmail.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
 <YRKtEDycefrZLB3X@infradead.org>
 <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
 <YRPZ2Kqb/MFggHzQ@infradead.org> <20210811145508.GA3650@lpieralisi>
 <20210816095854.GA2599@lpieralisi>
 <CAMj1kXHM8tG2f-i6u8Ohb0RV9XTqq2N1Oooz_Q2kvLpdfTMxqw@mail.gmail.com>
Message-ID: <381418c8-5302-6991-b3aa-df6378dd1c64@arm.com>

On 2021-08-16 11:21, Ard Biesheuvel wrote:
> On Mon, 16 Aug 2021 at 11:59, Lorenzo Pieralisi
> <lorenzo.pieralisi at arm.com> wrote:
>>
>> On Wed, Aug 11, 2021 at 03:55:08PM +0100, Lorenzo Pieralisi wrote:
>>> On Wed, Aug 11, 2021 at 03:08:24PM +0100, Christoph Hellwig wrote:
>>>> On Wed, Aug 11, 2021 at 12:40:28PM +0200, Ard Biesheuvel wrote:
>>>>> The whole problem we are solving here is that ACPI, being based on
>>>>> x86, conflates MMIO mappings with memory mappings, and has been using
>>>>> the same underlying infrastructure for either.
>>>>
>>>> So let's fix that problem instead of papering over it.
>>>
>>> Patch (3) in this series is a fix - I would ask whether it makes
>>> sense to merge patches (2-3) now and think about reworking the current
>>> ACPI IO/MEM mapping API later, it can be an invasive change for a fix,
>>> assuming we agree on how to rework the ACPI IO/MEM mapping API.
>>
>> What should we do then with this series ?
>>
> 
> It is not even clear that reworking the ACPI core is feasible to begin
> with, OTOH, fixing a sparse warning is arguably not a critical bug fix
> either, so I'd suggest we just drop that bit.

Indeed, the only way to truly fix the issue is to fire up the time 
machine and rewrite the ACPI and EFI specs to not define that tables and 
data may or may not be required to be mapped as Device memory depending 
on the whims of the firmware. Otherwise we're basically always going to 
have one or more casts *somewhere*, even if we were to play it safe and 
return everything as iomem instead.

I guess for read-only access to tables, the core code might be able to 
maintain a shadow copy of anything device-memory-mapped in normal memory 
and expose that instead, but if anything has to be writeable I'm not 
sure how we could abstract that "properly".

Robin.


From irui.wang at mediatek.com  Mon Aug 16 03:59:26 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:26 +0800
Subject: [PATCH 1/9] dt-bindings: media: mtk-vcodec: Add binding for MT8195
 two venc cores
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-2-irui.wang@mediatek.com>

Enable MT8195 two H.264 venc cores, updates vcodec binding document.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
index de961699ba0a..eb2e24c32426 100644
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
@@ -11,6 +11,8 @@ Required properties:
   "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
   "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
   "mediatek,mt8195-vcodec-enc" for MT8195 encoder.
+  "mediatek,mtk-venc-core0" for MT8195 avc core0 device.
+  "mediatek,mtk-venc-core1" for MT8195 avc core1 device.
 - reg : Physical base address of the video codec registers and length of
   memory mapped region.
 - interrupts : interrupt number to the cpu.
-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:31 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:31 +0800
Subject: [PATCH 6/9] media: mtk-vcodec: Add new venc drv interface for
 frame_racing mode
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-7-irui.wang@mediatek.com>

Frame-racing mode encoding need more venc working buffers, it
will break the compatibility if we just add venc_vsi in AP-Kernel
but not in firmware, so add a new venc driver interface to
distinguish the sigle_core_mode and frame_racing mode.

The new driver interface can be used for different codecs in
the future.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  19 +
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   4 +
 .../platform/mtk-vcodec/venc/venc_common_if.c | 629 ++++++++++++++++++
 .../media/platform/mtk-vcodec/venc_drv_if.c   |   5 +-
 .../media/platform/mtk-vcodec/venc_drv_if.h   |   1 +
 7 files changed, 659 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/venc/venc_common_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 661d4afeb628..a42ce704bf04 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -15,6 +15,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 
 mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		venc/venc_h264_if.o \
+		venc/venc_common_if.o \
 		mtk_vcodec_enc.o \
 		mtk_vcodec_enc_drv.o \
 		mtk_vcodec_enc_pm.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index c160b9e505eb..1c6c1eca649f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -352,6 +352,7 @@ struct mtk_vcodec_enc_pdata {
 };
 
 #define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
+#define MTK_ENC_HW_MODE(ctx) ((ctx)->dev->venc_pdata->hw_mode)
 
 /**
  * struct mtk_vcodec_dev - driver data
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index ac5973b6735f..5057e2cba627 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -9,6 +9,7 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
+#include "mtk_vcodec_enc_hw.h"
 
 /* For encoder, this will enable logs in venc/*/
 bool mtk_vcodec_dbg;
@@ -33,6 +34,24 @@ void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
 }
 EXPORT_SYMBOL(mtk_vcodec_get_reg_addr);
 
+void __iomem *mtk_get_venc_comp_reg_addr(struct mtk_vcodec_ctx *data,
+					 unsigned int hw_id)
+{
+	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data;
+	struct mtk_venc_comp_dev *venc;
+
+	if (!data || hw_id >= MTK_VENC_HW_MAX) {
+		mtk_v4l2_err("Invalid arguments, hw_id=%d", hw_id);
+		return NULL;
+	}
+	venc = (struct mtk_venc_comp_dev *)ctx->dev->enc_comp_dev[hw_id];
+	if (!venc)
+		return NULL;
+
+	return venc->reg_base;
+}
+EXPORT_SYMBOL(mtk_get_venc_comp_reg_addr);
+
 int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 			struct mtk_vcodec_mem *mem)
 {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index b999d7b84ed1..0027747c0a27 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -75,6 +75,10 @@ extern bool mtk_vcodec_dbg;
 
 void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
 				unsigned int reg_idx);
+
+void __iomem *mtk_get_venc_comp_reg_addr(struct mtk_vcodec_ctx *data,
+					 unsigned int hw_id);
+
 int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
 void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
new file mode 100644
index 000000000000..01b7d93241af
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
@@ -0,0 +1,629 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include "../venc_vpu_if.h"
+#include "../venc_drv_base.h"
+#include "../mtk_vcodec_intr.h"
+#include "../mtk_vcodec_enc.h"
+#include "../mtk_vcodec_drv.h"
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_enc_hw.h"
+
+static const char h264_filler_marker[] = {0x0, 0x0, 0x0, 0x1, 0xc};
+
+#define H264_FILLER_MARKER_SIZE ARRAY_SIZE(h264_filler_marker)
+#define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
+
+enum venc_vpu_work_buf {
+	VENC_VPU_WORK_BUF_RC_INFO_CORE0,
+	VENC_VPU_WORK_BUF_RC_INFO_CORE1,
+	VENC_VPU_WORK_BUF_FR_RC_INFO,
+	VENC_VPU_WORK_BUF_RC_CODE,
+	VENC_VPU_WORK_BUF_REC_LUMA,
+	VENC_VPU_WORK_BUF_REC_CHROMA,
+	VENC_VPU_WORK_BUF_REF_LUMA,
+	VENC_VPU_WORK_BUF_REF_CHROMA,
+	VENC_VPU_WORK_BUF_MV_INFO_1,
+	VENC_VPU_WORK_BUF_MV_INFO_2,
+	VENC_VPU_WORK_BUF_SKIP_FRAME,
+	VENC_VPU_WORK_BUF_MAX,
+};
+
+enum venc_frame_type {
+	VENC_IDR_FRM,
+	VENC_I_FRM,
+	VENC_P_FRM,
+	VENC_B_FRM,
+};
+
+enum venc_bs_mode {
+	VENC_BS_MODE_SPS,
+	VENC_BS_MODE_PPS,
+	VENC_BS_MODE_FRAME,
+};
+
+struct venc_vpu_buf {
+	u32 iova;
+	u32 vpua;
+	u32 size;
+};
+
+struct venc_vpu_config {
+	u32 input_fourcc;
+	u32 bitrate;
+	u32 pic_w;
+	u32 pic_h;
+	u32 buf_w;
+	u32 buf_h;
+	u32 gop_size;
+	u32 intra_period;
+	u32 framerate;
+	u32 profile;
+	u32 level;
+	u32 wfd;
+	u32 max_qp;
+	u32 min_qp;
+	u32 reserved[8];
+};
+
+struct venc_vsi {
+	struct venc_vpu_config config;
+	struct venc_vpu_buf work_bufs[VENC_VPU_WORK_BUF_MAX];
+};
+
+struct venc_common_inst {
+	void __iomem *hw_base[MTK_VENC_HW_MAX];
+	struct mtk_vcodec_mem work_bufs[VENC_VPU_WORK_BUF_MAX];
+	struct mtk_vcodec_mem pps_buf;
+	bool work_buf_allocated;
+	unsigned int frm_cnt;
+	unsigned int skip_frm_cnt;
+	unsigned int prepend_hdr;
+	struct venc_vpu_inst vpu_inst;
+	struct venc_vsi *vsi;
+	struct mtk_vcodec_ctx *ctx;
+};
+
+static inline u32 venc_read_reg(struct venc_common_inst *inst,
+				u32 addr, int hw_id)
+{
+	return readl(inst->hw_base[hw_id] + addr);
+}
+
+static unsigned int h264_get_profile(struct venc_common_inst *inst,
+				     unsigned int profile)
+{
+	switch (profile) {
+	case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+		return 66;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+		return 77;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+		return 100;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
+		mtk_vcodec_err(inst, "unsupported CONSTRAINED_BASELINE");
+		return 0;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
+		mtk_vcodec_err(inst, "unsupported EXTENDED");
+		return 0;
+	default:
+		mtk_vcodec_debug(inst, "unsupported profile %d", profile);
+		return 100;
+	}
+}
+
+static unsigned int h264_get_level(struct venc_common_inst *inst,
+				   unsigned int level)
+{
+	switch (level) {
+	case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
+		mtk_vcodec_err(inst, "unsupported 1B");
+		return 0;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
+		return 10;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
+		return 11;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
+		return 12;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
+		return 13;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
+		return 20;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
+		return 21;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
+		return 22;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
+		return 30;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
+		return 31;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
+		return 32;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
+		return 40;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
+		return 41;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
+		return 42;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
+		return 50;
+	case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
+		return 51;
+	default:
+		mtk_vcodec_debug(inst, "unsupported level %d", level);
+		return 31;
+	}
+}
+
+static void venc_free_work_buf(struct venc_common_inst *inst)
+{
+	int i;
+
+	mtk_vcodec_debug_enter(inst);
+
+	for (i = 0; i < VENC_VPU_WORK_BUF_MAX; i++) {
+		if (i != VENC_VPU_WORK_BUF_SKIP_FRAME)
+			mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
+	}
+
+	mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
+
+	mtk_vcodec_debug_leave(inst);
+}
+
+static int venc_alloc_work_buf(struct venc_common_inst *inst)
+{
+	int i;
+	int ret = 0;
+	struct venc_vpu_buf *wb = inst->vsi->work_bufs;
+
+	mtk_vcodec_debug_enter(inst);
+
+	for (i = 0; i < VENC_VPU_WORK_BUF_MAX; i++) {
+		/*
+		 * This 'wb' structure is set by VPU side and shared to AP for
+		 * buffer allocation and IO virtual addr mapping. For most of
+		 * the buffers, AP will allocate the buffer according to 'size'
+		 * field and store the IO virtual addr in 'iova' field. There
+		 * are two exceptions:
+		 * (1) RC_CODE buffer, it's pre-allocated in the VPU side, and
+		 * save the VPU addr in the 'vpua' field. The AP will translate
+		 * the VPU addr to the corresponding IO virtual addr and store
+		 * in 'iova' field for reg setting in VPU side.
+		 * (2) SKIP_FRAME buffer, it's pre-allocated in the VPU side,
+		 * and save the VPU addr in the 'vpua' field. The AP will
+		 * translate the VPU addr to the corresponding AP side virtual
+		 * address and do some memcpy access to move to bitstream buffer
+		 * assigned by v4l2 layer.
+		 */
+		inst->work_bufs[i].size = wb[i].size;
+		if (i == VENC_VPU_WORK_BUF_SKIP_FRAME) {
+			struct mtk_vcodec_fw *handler;
+
+			handler = inst->vpu_inst.ctx->dev->fw_handler;
+			inst->work_bufs[i].va =
+				mtk_vcodec_fw_map_dm_addr(handler, wb[i].vpua);
+			inst->work_bufs[i].dma_addr = 0;
+		} else {
+			ret = mtk_vcodec_mem_alloc(inst->ctx,
+						   &inst->work_bufs[i]);
+			if (ret) {
+				mtk_vcodec_err(inst,
+					       "cannot allocate buf %d", i);
+				goto err_alloc;
+			}
+			/*
+			 * This RC_CODE is pre-allocated by VPU and saved in VPU
+			 * addr. So we need use memcpy to copy RC_CODE from VPU
+			 * addr into IO virtual addr in 'iova' field for reg
+			 * setting in VPU side.
+			 */
+			if (i == VENC_VPU_WORK_BUF_RC_CODE) {
+				struct mtk_vcodec_fw *handler;
+				void *tmp_va;
+
+				handler = inst->vpu_inst.ctx->dev->fw_handler;
+				tmp_va = mtk_vcodec_fw_map_dm_addr(handler,
+								   wb[i].vpua);
+				memcpy(inst->work_bufs[i].va, tmp_va,
+				       wb[i].size);
+			}
+		}
+		wb[i].iova = inst->work_bufs[i].dma_addr;
+
+		mtk_vcodec_debug(inst,
+				 "work_buf[%d] va=0x%p iova=%pad size=%zu",
+				 i, inst->work_bufs[i].va,
+				 &inst->work_bufs[i].dma_addr,
+				 inst->work_bufs[i].size);
+	}
+
+	/* the pps_buf is used by AP side only */
+	inst->pps_buf.size = 128;
+	ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->pps_buf);
+	if (ret) {
+		mtk_vcodec_err(inst, "cannot allocate pps_buf");
+		goto err_alloc;
+	}
+
+	mtk_vcodec_debug_leave(inst);
+
+	return ret;
+
+err_alloc:
+	venc_free_work_buf(inst);
+
+	return ret;
+}
+
+static unsigned int venc_wait_comp_done(struct venc_common_inst *inst,
+					unsigned int hw_id)
+{
+	unsigned int irq_status = 0;
+	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
+
+	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
+					  WAIT_INTR_TIMEOUT_MS)) {
+		irq_status = ctx->irq_status;
+		mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
+	}
+	return irq_status;
+}
+
+static int venc_frame_type(struct venc_common_inst *inst)
+{
+	if ((inst->vsi->config.gop_size != 0 &&
+	     (inst->frm_cnt % inst->vsi->config.gop_size) == 0) ||
+	    (inst->frm_cnt == 0 && inst->vsi->config.gop_size == 0)) {
+		/* IDR frame */
+		return VENC_IDR_FRM;
+	} else if ((inst->vsi->config.intra_period != 0 &&
+		    (inst->frm_cnt % inst->vsi->config.intra_period) == 0) ||
+		   (inst->frm_cnt == 0 &&
+		    inst->vsi->config.intra_period == 0)) {
+		/* I frame */
+		return VENC_I_FRM;
+	} else {
+		return VENC_P_FRM;  /* Note: B frames are not supported */
+	}
+}
+
+static int venc_encode_sps(struct venc_common_inst *inst,
+			   struct mtk_vcodec_mem *bs_buf,
+			   unsigned int *bs_size)
+{
+	int ret = 0;
+	unsigned int irq_status;
+
+	mtk_vcodec_debug_enter(inst);
+
+	ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_SPS, NULL,
+			     bs_buf, bs_size, NULL);
+	if (ret)
+		return ret;
+
+	irq_status = venc_wait_comp_done(inst, MTK_VENC_CORE0);
+	if (irq_status != MTK_VENC_IRQ_STATUS_SPS) {
+		mtk_vcodec_err(inst, "expect irq status %d",
+			       MTK_VENC_IRQ_STATUS_SPS);
+		return -EINVAL;
+	}
+
+	*bs_size = venc_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT,
+				 MTK_VENC_CORE0);
+	mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
+
+	return ret;
+}
+
+static int venc_encode_pps(struct venc_common_inst *inst,
+			   struct mtk_vcodec_mem *bs_buf,
+			   unsigned int *bs_size)
+{
+	int ret = 0;
+	unsigned int irq_status;
+
+	mtk_vcodec_debug_enter(inst);
+
+	ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_PPS, NULL,
+			     bs_buf, bs_size, NULL);
+	if (ret)
+		return ret;
+
+	irq_status = venc_wait_comp_done(inst, MTK_VENC_CORE0);
+	if (irq_status != MTK_VENC_IRQ_STATUS_PPS) {
+		mtk_vcodec_err(inst, "expect irq status %d",
+			       MTK_VENC_IRQ_STATUS_PPS);
+		return -EINVAL;
+	}
+
+	*bs_size = venc_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT,
+				 MTK_VENC_CORE0);
+	mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
+
+	return ret;
+}
+
+static int venc_encode_header(struct venc_common_inst *inst,
+			      struct mtk_vcodec_mem *bs_buf,
+			      unsigned int *bs_size)
+{
+	int ret = 0;
+	unsigned int bs_size_sps;
+	unsigned int bs_size_pps;
+
+	ret = venc_encode_sps(inst, bs_buf, &bs_size_sps);
+	if (ret)
+		return ret;
+
+	ret = venc_encode_pps(inst, &inst->pps_buf, &bs_size_pps);
+	if (ret)
+		return ret;
+
+	memcpy(bs_buf->va + bs_size_sps, inst->pps_buf.va, bs_size_pps);
+	*bs_size = bs_size_sps + bs_size_pps;
+
+	return ret;
+}
+
+static int venc_encode_frame(struct venc_common_inst *inst,
+			     struct venc_frm_buf *frm_buf,
+			     struct mtk_vcodec_mem *bs_buf,
+			     unsigned int *bs_size,
+			     int hw_id)
+{
+	int ret = 0;
+	struct venc_frame_info frame_info;
+
+	mtk_vcodec_debug_enter(inst);
+	mtk_vcodec_debug(inst, "frm_cnt = %d\n ", inst->frm_cnt);
+	frame_info.frm_count = inst->frm_cnt;
+	frame_info.skip_frm_count = inst->skip_frm_cnt;
+	frame_info.frm_type = venc_frame_type(inst);
+	mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n",
+			 frame_info.frm_count, frame_info.skip_frm_count,
+			 frame_info.frm_type);
+	ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_FRAME, frm_buf,
+			     bs_buf, bs_size, &frame_info);
+	if (ret)
+		return ret;
+
+	++inst->frm_cnt;
+	mtk_vcodec_debug(inst, "frm %d bs_size %d key_frm %d <-",
+			 inst->frm_cnt, *bs_size, inst->vpu_inst.is_key_frm);
+
+	return ret;
+}
+
+static void h264_encode_filler(struct venc_common_inst *inst, void *buf,
+			       int size)
+{
+	unsigned char *p = buf;
+
+	if (size < H264_FILLER_MARKER_SIZE) {
+		mtk_vcodec_err(inst, "filler size too small %d", size);
+		return;
+	}
+
+	memcpy(p, h264_filler_marker, ARRAY_SIZE(h264_filler_marker));
+	size -= H264_FILLER_MARKER_SIZE;
+	p += H264_FILLER_MARKER_SIZE;
+	memset(p, 0xff, size);
+}
+
+static int venc_init(struct mtk_vcodec_ctx *ctx)
+{
+	int i;
+	int ret = 0;
+	struct venc_common_inst *inst;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+	inst->vpu_inst.ctx = ctx;
+	inst->vpu_inst.id = SCP_IPI_VENC_H264;
+
+	mtk_vcodec_debug_enter(inst);
+
+	ret = vpu_enc_init(&inst->vpu_inst);
+
+	inst->vsi = (struct venc_vsi *)inst->vpu_inst.vsi;
+
+	for (i = 0; i < MTK_VENC_HW_MAX; i++)
+		inst->hw_base[i] = mtk_get_venc_comp_reg_addr(ctx, i);
+
+	mtk_vcodec_debug_leave(inst);
+
+	if (ret)
+		kfree(inst);
+	else
+		ctx->drv_handle = inst;
+
+	return ret;
+}
+
+static int venc_encode(void *handle,
+		       enum venc_start_opt opt,
+		       struct venc_frm_buf *frm_buf,
+		       struct mtk_vcodec_mem *bs_buf,
+		       struct venc_done_result *result)
+{
+	int ret;
+	struct venc_common_inst *inst = (struct venc_common_inst *)handle;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+
+	switch (opt) {
+	case VENC_START_OPT_ENCODE_SEQUENCE_HEADER: {
+		unsigned int bs_size_hdr;
+
+		ret = venc_encode_header(inst, bs_buf, &bs_size_hdr);
+		if (ret) {
+			mtk_vcodec_err(inst, "encode header failed: %d", ret);
+			return ret;
+		}
+
+		result->bs_size = bs_size_hdr;
+		result->is_key_frm = false;
+
+		break;
+	}
+
+	case VENC_START_OPT_ENCODE_FRAME: {
+		int hdr_sz;
+		int hdr_sz_ext;
+		int filler_sz = 0;
+		const int bs_align = 128;
+		struct mtk_vcodec_mem tmp_bs_buf;
+		unsigned int bs_size_hdr;
+		unsigned int bs_size_frm;
+
+		if (!inst->prepend_hdr) {
+			ret = venc_encode_frame(inst, frm_buf, bs_buf,
+						&result->bs_size, ctx->hw_id);
+			if (ret) {
+				mtk_vcodec_err(inst, "encode frame failed: %d",
+					       ret);
+				return ret;
+			}
+
+			result->is_key_frm = inst->vpu_inst.is_key_frm;
+			break;
+		}
+
+		mtk_vcodec_debug(inst, "venc_encode_frame prepend SPS/PPS");
+
+		ret = venc_encode_header(inst, bs_buf, &bs_size_hdr);
+		if (ret) {
+			mtk_vcodec_err(inst, "encode prepend hdr failed: %d",
+				       ret);
+			return ret;
+		}
+
+		hdr_sz = bs_size_hdr;
+		hdr_sz_ext = (hdr_sz & (bs_align - 1));
+		if (hdr_sz_ext) {
+			filler_sz = bs_align - hdr_sz_ext;
+			if (hdr_sz_ext + H264_FILLER_MARKER_SIZE > bs_align)
+				filler_sz += bs_align;
+			h264_encode_filler(inst, bs_buf->va + hdr_sz,
+					   filler_sz);
+		}
+
+		tmp_bs_buf.va = bs_buf->va + hdr_sz + filler_sz;
+		tmp_bs_buf.dma_addr = bs_buf->dma_addr + hdr_sz + filler_sz;
+		tmp_bs_buf.size = bs_buf->size - (hdr_sz + filler_sz);
+
+		ret = venc_encode_frame(inst, frm_buf, &tmp_bs_buf,
+					&bs_size_frm, ctx->hw_id);
+
+		if (ret) {
+			mtk_vcodec_err(inst, "encode hdr frame failed: %d",
+				       ret);
+			return ret;
+		}
+
+		result->bs_size = hdr_sz + filler_sz + bs_size_frm;
+
+		mtk_vcodec_debug(inst, "hdr %d filler %d frame %d bs %d",
+				 hdr_sz, filler_sz, bs_size_frm,
+				 result->bs_size);
+
+		inst->prepend_hdr = 0;
+		result->is_key_frm = inst->vpu_inst.is_key_frm;
+		break;
+	}
+
+	default:
+		mtk_vcodec_err(inst, "venc_start_opt %d not supported", opt);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int venc_set_param(void *handle,
+			  enum venc_set_param_type type,
+			  struct venc_enc_param *enc_prm)
+{
+	int ret = 0;
+	struct venc_common_inst *inst = (struct venc_common_inst *)handle;
+
+	mtk_vcodec_debug(inst, "->type=%d", type);
+
+	switch (type) {
+	case VENC_SET_PARAM_ENC:
+		inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
+		inst->vsi->config.bitrate = enc_prm->bitrate;
+		inst->vsi->config.pic_w = enc_prm->width;
+		inst->vsi->config.pic_h = enc_prm->height;
+		inst->vsi->config.buf_w = enc_prm->buf_width;
+		inst->vsi->config.buf_h = enc_prm->buf_height;
+		inst->vsi->config.gop_size = enc_prm->gop_size;
+		inst->vsi->config.framerate = enc_prm->frm_rate;
+		inst->vsi->config.intra_period = enc_prm->intra_period;
+		inst->vsi->config.profile =
+			h264_get_profile(inst, enc_prm->h264_profile);
+		inst->vsi->config.level =
+			h264_get_level(inst, enc_prm->h264_level);
+		inst->vsi->config.wfd = 0;
+
+		ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
+		if (ret)
+			break;
+		if (inst->work_buf_allocated) {
+			venc_free_work_buf(inst);
+			inst->work_buf_allocated = false;
+		}
+		ret = venc_alloc_work_buf(inst);
+		if (ret)
+			break;
+		inst->work_buf_allocated = true;
+		break;
+
+	case VENC_SET_PARAM_PREPEND_HEADER:
+		inst->prepend_hdr = 1;
+		mtk_vcodec_debug(inst, "set prepend header mode");
+		break;
+	case VENC_SET_PARAM_FORCE_INTRA:
+	case VENC_SET_PARAM_GOP_SIZE:
+	case VENC_SET_PARAM_INTRA_PERIOD:
+		inst->frm_cnt = 0;
+		inst->skip_frm_cnt = 0;
+		fallthrough;
+	default:
+		ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
+		break;
+	}
+
+	mtk_vcodec_debug_leave(inst);
+	return ret;
+}
+
+static int venc_deinit(void *handle)
+{
+	int ret = 0;
+	struct venc_common_inst *inst = (struct venc_common_inst *)handle;
+
+	mtk_vcodec_debug_enter(inst);
+
+	ret = vpu_enc_deinit(&inst->vpu_inst);
+
+	if (inst->work_buf_allocated)
+		venc_free_work_buf(inst);
+
+	mtk_vcodec_debug_leave(inst);
+	kfree(inst);
+
+	return ret;
+}
+
+const struct venc_common_if venc_if = {
+	.init = venc_init,
+	.encode = venc_encode,
+	.set_param = venc_set_param,
+	.deinit = venc_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.c b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
index 6cbdb7e30bb3..93936d002bed 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
@@ -25,7 +25,10 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		ctx->enc_if = &venc_vp8_if;
 		break;
 	case V4L2_PIX_FMT_H264:
-		ctx->enc_if = &venc_h264_if;
+		if (MTK_ENC_HW_MODE(ctx) == VENC_FRAME_RACING_MODE)
+			ctx->enc_if = &venc_if;
+		else
+			ctx->enc_if = &venc_h264_if;
 		break;
 	default:
 		return -EINVAL;
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.h b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
index 0b04a1020873..8f384ba24ddf 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
@@ -125,6 +125,7 @@ struct venc_done_result {
 
 extern const struct venc_common_if venc_h264_if;
 extern const struct venc_common_if venc_vp8_if;
+extern const struct venc_common_if venc_if;
 
 /*
  * venc_if_init - Create the driver handle
-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:32 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:32 +0800
Subject: [PATCH 7/9] media: mtk-vcodec: Add frame racing mode encode process
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-8-irui.wang@mediatek.com>

The frame_racing mode encoding is try to use the two venc cores:
frame#0 use core#0, frame#1 use core#1, frame#2 use core#0...,

Lock the device and enabe the clock by used core, for sequence
header encoding, it always used core#0.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  5 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 35 ++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |  4 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  6 +-
 .../platform/mtk-vcodec/venc/venc_common_if.c |  6 +-
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |  6 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  2 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   | 85 ++++++++++++++-----
 .../media/platform/mtk-vcodec/venc_drv_if.h   |  4 +
 .../media/platform/mtk-vcodec/venc_vpu_if.c   | 11 ++-
 .../media/platform/mtk-vcodec/venc_vpu_if.h   |  3 +-
 11 files changed, 118 insertions(+), 49 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 1c6c1eca649f..7a9c2dd52b91 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -273,6 +273,7 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ * @enc_idx: used to record encoded frame count
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -313,6 +314,8 @@ struct mtk_vcodec_ctx {
 	int decoded_frame_cnt;
 	struct mutex lock;
 
+	int hw_id;
+	int enc_idx;
 };
 
 enum mtk_chip {
@@ -422,7 +425,7 @@ struct mtk_vcodec_dev {
 	int enc_irq;
 
 	struct mutex dec_mutex;
-	struct mutex enc_mutex;
+	struct mutex enc_mutex[MTK_VENC_HW_MAX];
 
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index d22f9c8fd063..6b37bd092fdf 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -1090,21 +1090,26 @@ static void mtk_venc_worker(struct work_struct *work)
 	if (enc_result.is_key_frm)
 		dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
 
-	if (ret) {
-		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
-		dst_buf->vb2_buf.planes[0].bytesused = 0;
-		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
-		mtk_v4l2_err("venc_if_encode failed=%d", ret);
-	} else {
-		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
-		dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size;
-		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
-		mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
-				 enc_result.bs_size);
+	if (ctx->dev->venc_pdata->hw_mode == VENC_SINGLE_CORE_MODE) {
+		if (ret) {
+			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+			dst_buf->vb2_buf.planes[0].bytesused = 0;
+			v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
+			mtk_v4l2_err("venc_if_encode failed=%d", ret);
+		} else {
+			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+			dst_buf->vb2_buf.planes[0].bytesused =
+					enc_result.bs_size;
+			v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+			mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
+				       enc_result.bs_size);
+		}
 	}
 
 	v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
 
+	ctx->enc_idx++;
+
 	mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>",
 			src_buf->vb2_buf.index, dst_buf->vb2_buf.index, ret,
 			enc_result.bs_size);
@@ -1305,19 +1310,19 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 	return vb2_queue_init(dst_vq);
 }
 
-int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
+int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
 
-	mutex_unlock(&dev->enc_mutex);
+	mutex_unlock(&dev->enc_mutex[core_id]);
 	return 0;
 }
 
-int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
+int mtk_venc_lock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
 
-	mutex_lock(&dev->enc_mutex);
+	mutex_lock(&dev->enc_mutex[core_id]);
 	return 0;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
index 30b6d7f22ed7..8d486f532025 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
@@ -41,8 +41,8 @@ struct mtk_video_enc_buf {
 extern const struct v4l2_ioctl_ops mtk_venc_ioctl_ops;
 extern const struct v4l2_m2m_ops mtk_venc_m2m_ops;
 
-int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx);
-int mtk_venc_lock(struct mtk_vcodec_ctx *ctx);
+int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id);
+int mtk_venc_lock(struct mtk_vcodec_ctx *ctx, int core_id);
 int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 			      struct vb2_queue *dst_vq);
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index b78435e8223a..ff1f05a5ca28 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -320,7 +320,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret;
+	int ret, i;
 	struct component_match *match = NULL;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -384,7 +384,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
-	mutex_init(&dev->enc_mutex);
+	for (i = 0; i < MTK_VENC_HW_MAX; i++)
+		mutex_init(&dev->enc_mutex[i]);
+
 	mutex_init(&dev->dev_mutex);
 	spin_lock_init(&dev->irqlock);
 
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
index 01b7d93241af..1580bd1beaac 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
@@ -300,7 +300,7 @@ static int venc_encode_sps(struct venc_common_inst *inst,
 	mtk_vcodec_debug_enter(inst);
 
 	ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_SPS, NULL,
-			     bs_buf, bs_size, NULL);
+			     bs_buf, bs_size, NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
@@ -328,7 +328,7 @@ static int venc_encode_pps(struct venc_common_inst *inst,
 	mtk_vcodec_debug_enter(inst);
 
 	ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_PPS, NULL,
-			     bs_buf, bs_size, NULL);
+			     bs_buf, bs_size, NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
@@ -386,7 +386,7 @@ static int venc_encode_frame(struct venc_common_inst *inst,
 			 frame_info.frm_count, frame_info.skip_frm_count,
 			 frame_info.frm_type);
 	ret = vpu_enc_encode(&inst->vpu_inst, VENC_BS_MODE_FRAME, frm_buf,
-			     bs_buf, bs_size, &frame_info);
+			     bs_buf, bs_size, &frame_info, hw_id);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index b6a4f2074fa5..a90b06a3fe5a 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -368,7 +368,7 @@ static int h264_encode_sps(struct venc_h264_inst *inst,
 	mtk_vcodec_debug_enter(inst);
 
 	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL,
-			     bs_buf, bs_size, NULL);
+			     bs_buf, bs_size, NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
@@ -395,7 +395,7 @@ static int h264_encode_pps(struct venc_h264_inst *inst,
 	mtk_vcodec_debug_enter(inst);
 
 	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL,
-			     bs_buf, bs_size, NULL);
+			     bs_buf, bs_size, NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
@@ -452,7 +452,7 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
 			 frame_info.frm_count, frame_info.skip_frm_count,
 			 frame_info.frm_type);
 	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf,
-			     bs_buf, bs_size, &frame_info);
+			     bs_buf, bs_size, &frame_info, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index 8267a9c4fd25..a68bf53d7d81 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -303,7 +303,7 @@ static int vp8_enc_encode_frame(struct venc_vp8_inst *inst,
 	mtk_vcodec_debug(inst, "->frm_cnt=%d", inst->frm_cnt);
 
 	ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf, bs_size,
-			     NULL);
+			     NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.c b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
index 93936d002bed..09fcec05a655 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
@@ -15,6 +15,7 @@
 
 #include "mtk_vcodec_enc.h"
 #include "mtk_vcodec_enc_pm.h"
+#include "mtk_vcodec_enc_hw.h"
 
 int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 {
@@ -34,9 +35,9 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		return -EINVAL;
 	}
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, 0);
 	ret = ctx->enc_if->init(ctx);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, 0);
 
 	return ret;
 }
@@ -46,9 +47,9 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
 {
 	int ret = 0;
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, 0);
 	ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, 0);
 
 	return ret;
 }
@@ -59,24 +60,12 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 		   struct venc_done_result *result)
 {
 	int ret = 0;
-	unsigned long flags;
-
-	mtk_venc_lock(ctx);
 
-	spin_lock_irqsave(&ctx->dev->irqlock, flags);
-	ctx->dev->curr_ctx = ctx;
-	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
-
-	mtk_vcodec_enc_clock_on(ctx->dev, 0);
+	venc_encode_prepare(ctx, opt);
 	ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
 				  bs_buf, result);
-	mtk_vcodec_enc_clock_off(ctx->dev, 0);
-
-	spin_lock_irqsave(&ctx->dev->irqlock, flags);
-	ctx->dev->curr_ctx = NULL;
-	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+	venc_encode_unprepare(ctx, opt);
 
-	mtk_venc_unlock(ctx);
 	return ret;
 }
 
@@ -87,11 +76,67 @@ int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
 	if (!ctx->drv_handle)
 		return 0;
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, 0);
 	ret = ctx->enc_if->deinit(ctx->drv_handle);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, 0);
 
 	ctx->drv_handle = NULL;
 
 	return ret;
 }
+
+void venc_encode_prepare(struct mtk_vcodec_ctx *ctx,
+			 enum venc_start_opt opt)
+{
+	unsigned long flags;
+	struct mtk_venc_comp_dev *venc;
+
+	if (ctx->dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
+		if (ctx->enc_idx & 0x01)
+			ctx->hw_id = MTK_VENC_CORE1;
+		else
+			ctx->hw_id = MTK_VENC_CORE0;
+	} else {
+		ctx->hw_id = MTK_VENC_CORE0;
+	}
+	mtk_venc_lock(ctx, ctx->hw_id);
+
+	spin_lock_irqsave(&ctx->dev->irqlock, flags);
+
+	if (ctx->dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
+		venc = ctx->dev->enc_comp_dev[ctx->hw_id];
+
+		venc->curr_ctx = ctx;
+	} else {
+		ctx->dev->curr_ctx = ctx;
+	}
+
+	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+
+	mtk_vcodec_enc_clock_on(ctx->dev, ctx->hw_id);
+}
+
+void venc_encode_unprepare(struct mtk_vcodec_ctx *ctx,
+			   enum venc_start_opt opt)
+{
+	unsigned long flags;
+	struct mtk_venc_comp_dev *venc;
+
+	/*clock off and unlock after irq done*/
+	if (ctx->dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
+		if (opt == VENC_START_OPT_ENCODE_SEQUENCE_HEADER) {
+			mtk_vcodec_enc_clock_off(ctx->dev, ctx->hw_id);
+			spin_lock_irqsave(&ctx->dev->irqlock, flags);
+			venc = ctx->dev->enc_comp_dev[ctx->hw_id];
+			venc->curr_ctx = NULL;
+			spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+			mtk_venc_unlock(ctx, ctx->hw_id);
+		}
+	} else {
+		mtk_vcodec_enc_clock_off(ctx->dev, ctx->hw_id);
+		spin_lock_irqsave(&ctx->dev->irqlock, flags);
+		ctx->dev->curr_ctx = NULL;
+		spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+		mtk_venc_unlock(ctx, ctx->hw_id);
+	}
+}
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.h b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
index 8f384ba24ddf..7bd1f437d8e3 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
@@ -168,4 +168,8 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 		   struct mtk_vcodec_mem *bs_buf,
 		   struct venc_done_result *result);
 
+void venc_encode_prepare(struct mtk_vcodec_ctx *ctx,
+			 enum venc_start_opt opt);
+void venc_encode_unprepare(struct mtk_vcodec_ctx *ctx,
+			   enum venc_start_opt opt);
 #endif /* _VENC_DRV_IF_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
index be6d8790a41e..5bee5f1828f1 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
@@ -226,9 +226,12 @@ int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		   struct venc_frm_buf *frm_buf,
 		   struct mtk_vcodec_mem *bs_buf,
 		   unsigned int *bs_size,
-		   struct venc_frame_info *frame_info)
+		   struct venc_frame_info *frame_info,
+		   int hw_id)
 {
 	const bool is_ext = MTK_ENC_CTX_IS_EXT(vpu->ctx);
+	const int hw_mode = MTK_ENC_HW_MODE(vpu->ctx);
+
 	size_t msg_size = is_ext ?
 		sizeof(struct venc_ap_ipi_msg_enc_ext) :
 		sizeof(struct venc_ap_ipi_msg_enc);
@@ -262,6 +265,12 @@ int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		out.data[1] = frame_info->skip_frm_count;
 		out.data[2] = frame_info->frm_type;
 	}
+
+	if (hw_mode == VENC_FRAME_RACING_MODE) {
+		out.data_item = 4;
+		out.data[3] = hw_id;
+	}
+
 	if (vpu_enc_send_msg(vpu, &out, msg_size)) {
 		mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_ENCODE %d fail",
 			       bs_mode);
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
index f9be9cab7ff7..e55656781f6e 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
@@ -46,7 +46,8 @@ int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		   struct venc_frm_buf *frm_buf,
 		   struct mtk_vcodec_mem *bs_buf,
 		   unsigned int *bs_size,
-		   struct venc_frame_info *frame_info);
+		   struct venc_frame_info *frame_info,
+		   int hw_id);
 int vpu_enc_deinit(struct venc_vpu_inst *vpu);
 
 #endif
-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:25 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:25 +0800
Subject: [PATCH 0/9] Enable two H264 encoder cores on MT8195
Message-ID: <20210816105934.28265-1-irui.wang@mediatek.com>

MT8195 has two H264 encoder cores, they have their own power-domains,
clocks, interrupts, register base. The two H264 encoder cores can work
together to achieve higher performance.

This series of patches is to use enable two h264 encoder cores.
path[1..2]: use linux component framework to manage encoder hardware,
user call "mt8195-vcodec-enc" driver can get the encoder master device,
the encoding work is done by the two encoder core device. The hw_mode
variable is added to distinguish from old platform, two encoder cores
called "FRAME_RACING_MODE".

The hardware mode of two encoder cores work together(overlap, another
word called) on MT8195 called "frame_racing_mode", the two encoder
power-domains should be power on together while encoding, the encoding
process look like this:

    VENC Core0 frm#0....frm#2....frm#4
    VENC Core1  .frm#1....frm#3....frm#5

patch[3..5]: due to the component device, the master device has no
power-domains/clocks properties in dtsi, so the power/clock init function
can't use for "frame_racing_mode" device in master device probe process,
it should be called in component device probe process. Power on the
hardware power and clock on demand.

patch[6]: "frame_racing_mode" encoding need a new set of memory buffer
for two encoder cores. For compatibility, we should new a encoder driver
interface.

patch[7..9]: add "frame_racing_mode" encoding process:
As-Is: Synchronous
VIDIOC_QBUF#0 --> device_run(triger encoder) --> wait encoder IRQ -->
encode done with result --> job_finish

VIDIOC_QBUF#1 --> device_run(triger encoder) --> wait encoder IRQ -->
encode done with result --> job_finish
...

To-Be: Asynchronous
VIDIOC_QBUF#0 --> device_run(triger encoder core0) --> job_finish
..VIDIOC_QBUF#1 --> device_run(triger encoder core1) --> job_finish
(core0 may encode done here, return encode result to client)
VIDIOC_QBUF#2 --> device_run(triger encoder core0) --> job_finish

Thers is no "wait encoder IRQ" synchronous call during "frame_racing_mode"
encoding process, which can full use the two encoder cores to achieve
higher performance.

Irui Wang (9):
  dt-bindings: media: mtk-vcodec: Add binding for MT8195 two venc cores
  media: mtk-vcodec: Use component framework to manage encoder hardware
  media: mtk-vcodec: Rewrite venc power manage interface
  media: mtk-vcodec: Add venc power on/off interface
  media: mtk-vcodec: Rewrite venc clock interface
  media: mtk-vcodec: Add new venc drv interface for frame_racing mode
  media: mtk-vcodec: Add frame racing mode encode process
  media: mtk-vcodec: Return encode result to client
  media: mtk-vcodec: Add delayed worker for encode timeout

 .../bindings/media/mediatek-vcodec.txt        |   2 +
 drivers/media/platform/mtk-vcodec/Makefile    |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  34 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 120 +++-
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |  10 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  | 204 +++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc_hw.c   | 253 +++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_hw.h   |  38 +
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 213 ++++--
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  13 +-
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  19 +
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   5 +
 .../platform/mtk-vcodec/venc/venc_common_if.c | 675 ++++++++++++++++++
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |   6 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |   2 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   |  96 ++-
 .../media/platform/mtk-vcodec/venc_drv_if.h   |   7 +
 .../media/platform/mtk-vcodec/venc_vpu_if.c   |  11 +-
 .../media/platform/mtk-vcodec/venc_vpu_if.h   |   3 +-
 19 files changed, 1564 insertions(+), 149 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h
 create mode 100644 drivers/media/platform/mtk-vcodec/venc/venc_common_if.c

-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:29 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:29 +0800
Subject: [PATCH 4/9] media: mtk-vcodec: Add venc power on/off interface
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-5-irui.wang@mediatek.com>

Frame-racing mode need power on/off all venc available power,
pm_runtime_xx helper is not appropriate called directly, add new
power on/off interface for it.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 18 +---
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  9 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 82 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  4 +
 4 files changed, 96 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 416f356af363..d22f9c8fd063 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -16,6 +16,7 @@
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 #include "venc_drv_if.h"
+#include "mtk_vcodec_enc_pm.h"
 
 #define MTK_VENC_MIN_W	160U
 #define MTK_VENC_MIN_H	128U
@@ -801,7 +802,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 	  */
 	if ((ctx->state == MTK_STATE_ABORT) || (ctx->state == MTK_STATE_FREE)) {
 		ret = -EIO;
-		goto err_start_stream;
+		goto err_set_param;
 	}
 
 	/* Do the initialization when both start_streaming have been called */
@@ -813,12 +814,6 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 			return 0;
 	}
 
-	ret = pm_runtime_resume_and_get(&ctx->dev->plat_dev->dev);
-	if (ret < 0) {
-		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
-		goto err_start_stream;
-	}
-
 	mtk_venc_set_param(ctx, &param);
 	ret = venc_if_set_param(ctx, VENC_SET_PARAM_ENC, &param);
 	if (ret) {
@@ -845,11 +840,6 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 	return 0;
 
 err_set_param:
-	ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
-	if (ret < 0)
-		mtk_v4l2_err("pm_runtime_put fail %d", ret);
-
-err_start_stream:
 	for (i = 0; i < q->num_buffers; ++i) {
 		struct vb2_buffer *buf = vb2_get_buffer(q, i);
 
@@ -903,10 +893,6 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
 	if (ret)
 		mtk_v4l2_err("venc_if_deinit failed=%d", ret);
 
-	ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
-	if (ret < 0)
-		mtk_v4l2_err("pm_runtime_put fail %d", ret);
-
 	ctx->state = MTK_STATE_FREE;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 9c2224b199d0..b78435e8223a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -253,6 +253,12 @@ static int fops_vcodec_open(struct file *file)
 		mtk_v4l2_debug(0, "encoder capability %x", dev->enc_capability);
 	}
 
+	ret = mtk_vcodec_enc_power_on(ctx);
+	if (ret < 0) {
+		mtk_v4l2_err("encoder power on failed %d", ret);
+		goto err_load_fw;
+	}
+
 	mtk_v4l2_debug(2, "Create instance [%d]@%p m2m_ctx=%p ",
 			ctx->id, ctx, ctx->m2m_ctx);
 
@@ -285,11 +291,12 @@ static int fops_vcodec_release(struct file *file)
 	mtk_v4l2_debug(1, "[%d] encoder", ctx->id);
 	mutex_lock(&dev->dev_mutex);
 
+	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	mtk_vcodec_enc_release(ctx);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
-	v4l2_m2m_ctx_release(ctx->m2m_ctx);
+	mtk_vcodec_enc_power_off(ctx);
 
 	list_del_init(&ctx->list);
 	kfree(ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 5edeb93fca84..d9df0e3701f1 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -12,6 +12,7 @@
 
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
+#include "mtk_vcodec_enc_hw.h"
 
 int mtk_vcodec_init_enc_pm(struct platform_device *pdev,
 			   struct mtk_vcodec_pm *pm)
@@ -120,3 +121,84 @@ void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 	for (i = enc_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
+
+int mtk_venc_enable_comp_hw(struct mtk_vcodec_dev *dev)
+{
+	int i, ret;
+	struct mtk_venc_comp_dev *venc_comp;
+
+	/*
+	 * frame_racing mode needs power on all available component devices.
+	 */
+	for (i = 0; i < MTK_VENC_HW_MAX; i++) {
+		venc_comp = (struct mtk_venc_comp_dev *)dev->enc_comp_dev[i];
+		if (!venc_comp)
+			return 0;
+
+		ret = mtk_smi_larb_get(venc_comp->pm.larbvenc);
+		if (ret < 0) {
+			mtk_v4l2_err("power on core[%d] fail %d", i, ret);
+				goto pw_err;
+		}
+	}
+	return 0;
+
+pw_err:
+	for (i -= 1; i >= 0; i--) {
+		venc_comp = (struct mtk_venc_comp_dev *)dev->enc_comp_dev[i];
+
+		mtk_smi_larb_put(venc_comp->pm.larbvenc);
+	}
+
+	return ret;
+}
+
+int mtk_venc_disable_comp_hw(struct mtk_vcodec_dev *dev)
+{
+	int i;
+	struct mtk_venc_comp_dev *venc_comp;
+
+	/*power off all available component device*/
+	for (i = 0; i < MTK_VENC_HW_MAX; i++) {
+		venc_comp = (struct mtk_venc_comp_dev *)dev->enc_comp_dev[i];
+		if (!venc_comp)
+			return 0;
+
+		mtk_smi_larb_put(venc_comp->pm.larbvenc);
+	}
+
+	return 0;
+}
+
+int mtk_vcodec_enc_power_on(struct mtk_vcodec_ctx *ctx)
+{
+	int ret;
+	struct mtk_vcodec_dev *dev = ctx->dev;
+
+	if (dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
+		ret = mtk_venc_enable_comp_hw(dev);
+		if (ret < 0) {
+			mtk_v4l2_err("enable venc comp hw fail :%d", ret);
+			return ret;
+		}
+	} else {
+		ret = mtk_smi_larb_get(dev->pm.larbvenc);
+		if (ret < 0) {
+			mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+int mtk_vcodec_enc_power_off(struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_vcodec_dev *dev = ctx->dev;
+
+	if (dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE)
+		mtk_venc_disable_comp_hw(dev);
+	else
+		mtk_smi_larb_put(dev->pm.larbvenc);
+
+	return 0;
+}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index f4a4aa441185..2e76b858fed1 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -16,4 +16,8 @@ void mtk_vcodec_release_enc_pm(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
 
+int mtk_venc_enable_comp_hw(struct mtk_vcodec_dev *dev);
+int mtk_venc_disable_comp_hw(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_enc_power_on(struct mtk_vcodec_ctx *ctx);
+int mtk_vcodec_enc_power_off(struct mtk_vcodec_ctx *ctx);
 #endif /* _MTK_VCODEC_ENC_PM_H_ */
-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:34 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:34 +0800
Subject: [PATCH 9/9] media: mtk-vcodec: Add delayed worker for encode timeout
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-10-irui.wang@mediatek.com>

When encoding timeout, a delayed timeout worker is needed because
of asynchronous encoding process, restore encoding process in
timeout worker.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 12 ++++--
 .../platform/mtk-vcodec/mtk_vcodec_enc_hw.c   | 26 +++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_hw.h   |  2 +
 .../platform/mtk-vcodec/venc/venc_common_if.c | 43 +++++++++++++++++--
 4 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index de8e012f1b0e..bc635436aa90 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -1340,9 +1340,15 @@ void mtk_venc_buf_done(struct mtk_vcodec_ctx *ctx, int core_id,
 		if (key_frame)
 			dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME;
 
-		v4l2_m2m_buf_done(src_vb2_v4l2, VB2_BUF_STATE_DONE);
-		dst_vb2_v4l2->vb2_buf.planes[0].bytesused = bs_size;
-		v4l2_m2m_buf_done(dst_vb2_v4l2, VB2_BUF_STATE_DONE);
+		if (time_out) {
+			v4l2_m2m_buf_done(src_vb2_v4l2, VB2_BUF_STATE_ERROR);
+			dst_vb2_v4l2->vb2_buf.planes[0].bytesused = 0;
+			v4l2_m2m_buf_done(dst_vb2_v4l2, VB2_BUF_STATE_ERROR);
+		} else {
+			v4l2_m2m_buf_done(src_vb2_v4l2, VB2_BUF_STATE_DONE);
+			dst_vb2_v4l2->vb2_buf.planes[0].bytesused = bs_size;
+			v4l2_m2m_buf_done(dst_vb2_v4l2, VB2_BUF_STATE_DONE);
+		}
 	}
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
index 687b255c58e8..f6a5dfa6929f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
@@ -16,6 +16,28 @@
 #define VENC_PIC_FRM_TYPE	0x0010
 #define VENC_PIC_KEY_FRM	0x2
 
+static void mtk_venc_timeout_worker(struct work_struct *work)
+{
+	struct mtk_venc_comp_dev *dev = container_of(work,
+						     struct mtk_venc_comp_dev,
+						     enc_timeout_worker.work);
+
+	struct mtk_vcodec_ctx *ctx;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->master_dev->irqlock, flags);
+	ctx = dev->curr_ctx;
+
+	dev_err(&dev->plat_dev->dev, "core: %d timeout\n", dev->core_id);
+
+	mtk_venc_buf_done(ctx, dev->core_id, 0, 1, 0);
+
+	mtk_vcodec_enc_clock_off(dev->master_dev, dev->core_id);
+	dev->curr_ctx = NULL;
+	spin_unlock_irqrestore(&dev->master_dev->irqlock, flags);
+
+	mtk_venc_unlock(ctx, dev->core_id);
+}
 /* Wake up core context wait_queue */
 static void mtk_venc_comp_wake_up_ctx(struct mtk_vcodec_ctx *ctx,
 				      unsigned int hw_id)
@@ -67,6 +89,7 @@ static irqreturn_t mtk_enc_comp_irq_handler(int irq, void *priv)
 	frm_type = readl(dev->reg_base + VENC_PIC_FRM_TYPE);
 	clean_irq_status(ctx->irq_status, addr);
 	if (ctx->irq_status & MTK_VENC_IRQ_STATUS_FRM) {
+		cancel_delayed_work(&dev->enc_timeout_worker);
 		if (ctx->hdr_size != 0) {
 			bs_size += ctx->hdr_size;
 			ctx->hdr_size = 0;
@@ -182,6 +205,9 @@ static int mtk_venc_comp_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, comp_dev);
 
+	INIT_DELAYED_WORK(&comp_dev->enc_timeout_worker,
+			  mtk_venc_timeout_worker);
+
 	ret = component_add(&pdev->dev, &mtk_venc_component_ops);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to add component: %d\n", ret);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h
index f9ae97e252dc..e69344e38ca6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h
@@ -19,6 +19,7 @@
  * @irq_status: venc hw irq status
  * @enc_irq: venc device irq
  * @core id: for venc core id: core#0, core#1...
+ * @enc_timeout_worker: venc timeout worker
  */
 struct mtk_venc_comp_dev {
 	struct platform_device *plat_dev;
@@ -31,6 +32,7 @@ struct mtk_venc_comp_dev {
 	unsigned int irq_status;
 	int enc_irq;
 	int core_id;
+	struct delayed_work enc_timeout_worker;
 };
 
 #endif /* _MTK_VCODEC_ENC_HW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
index 75b4e90232ae..1aab84faadf0 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
@@ -10,11 +10,13 @@
 #include "../mtk_vcodec_drv.h"
 #include "../mtk_vcodec_util.h"
 #include "../mtk_vcodec_enc_hw.h"
+#include "../mtk_vcodec_enc_pm.h"
 
 static const char h264_filler_marker[] = {0x0, 0x0, 0x0, 0x1, 0xc};
 
 #define H264_FILLER_MARKER_SIZE ARRAY_SIZE(h264_filler_marker)
 #define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
+#define MTK_VENC_HW_TIMEOUT_MSEC 2000
 
 enum venc_vpu_work_buf {
 	VENC_VPU_WORK_BUF_RC_INFO_CORE0,
@@ -413,6 +415,34 @@ static void h264_encode_filler(struct venc_common_inst *inst, void *buf,
 	memset(p, 0xff, size);
 }
 
+static void init_schedule_work(struct mtk_vcodec_ctx *ctx)
+{
+	unsigned long timeout;
+	struct mtk_venc_comp_dev *venc;
+
+	venc = ctx->dev->enc_comp_dev[ctx->hw_id];
+	timeout = msecs_to_jiffies(MTK_VENC_HW_TIMEOUT_MSEC);
+	schedule_delayed_work(&venc->enc_timeout_worker, timeout);
+}
+
+static void cancel_schedule_work(struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_venc_comp_dev *venc;
+	unsigned long flags;
+
+	venc = ctx->dev->enc_comp_dev[ctx->hw_id];
+	cancel_delayed_work(&venc->enc_timeout_worker);
+
+	mtk_venc_buf_done(ctx, ctx->hw_id, 0, 1, 0);
+	mtk_vcodec_enc_clock_off(ctx->dev, ctx->hw_id);
+
+	spin_lock_irqsave(&ctx->dev->irqlock, flags);
+	venc->curr_ctx = NULL;
+	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+
+	mtk_venc_unlock(ctx, ctx->hw_id);
+}
+
 static int venc_init(struct mtk_vcodec_ctx *ctx)
 {
 	int i;
@@ -489,12 +519,13 @@ static int venc_encode(void *handle,
 		ctx->pbs_buf[ctx->hw_id] = bs_buf->buf;
 
 		if (!inst->prepend_hdr) {
+			init_schedule_work(ctx);
 			ret = venc_encode_frame(inst, frm_buf, bs_buf,
 						&result->bs_size, ctx->hw_id);
 			if (ret) {
 				mtk_vcodec_err(inst, "encode frame failed: %d",
 					       ret);
-				return ret;
+				goto encode_err;
 			}
 
 			result->is_key_frm = inst->vpu_inst.is_key_frm;
@@ -503,11 +534,13 @@ static int venc_encode(void *handle,
 
 		mtk_vcodec_debug(inst, "venc_encode_frame prepend SPS/PPS");
 
+		init_schedule_work(ctx);
+
 		ret = venc_encode_header(inst, bs_buf, &bs_size_hdr);
 		if (ret) {
 			mtk_vcodec_err(inst, "encode prepend hdr failed: %d",
 				       ret);
-			return ret;
+			goto encode_err;
 		}
 
 		hdr_sz = bs_size_hdr;
@@ -530,7 +563,7 @@ static int venc_encode(void *handle,
 		if (ret) {
 			mtk_vcodec_err(inst, "encode hdr frame failed: %d",
 				       ret);
-			return ret;
+			goto encode_err;
 		}
 
 		result->bs_size = hdr_sz + filler_sz + bs_size_frm;
@@ -552,6 +585,10 @@ static int venc_encode(void *handle,
 	}
 
 	return ret;
+
+encode_err:
+	cancel_schedule_work(ctx);
+	return ret;
 }
 
 static int venc_set_param(void *handle,
-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:28 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:28 +0800
Subject: [PATCH 3/9] media: mtk-vcodec: Rewrite venc power manage interface
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-4-irui.wang@mediatek.com>

The args "struct mtk_vcodec_dev *" doesn't appropriate for
init/release_enc_pm functions because of component devices. For
master device, it has no "pm/clk" properties in dtsi, component
devices will init their own "pm/clk" instead. So rewrite the pm
interface with args "platform_device *" and "mtk_vcodec_pm*".

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  6 ++--
 .../platform/mtk-vcodec/mtk_vcodec_enc_hw.c   | 13 ++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 31 +++++++------------
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  5 +--
 4 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index f7538d4b5cbb..9c2224b199d0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -341,7 +341,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 
 	dev->venc_pdata = of_device_get_match_data(&pdev->dev);
 	if (dev->venc_pdata->hw_mode == VENC_SINGLE_CORE_MODE) {
-		ret = mtk_vcodec_init_enc_pm(dev);
+		ret = mtk_vcodec_init_enc_pm(dev->plat_dev, &dev->pm);
 		if (ret < 0) {
 			dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!");
 			goto err_enc_pm;
@@ -471,7 +471,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
 	if (dev->venc_pdata->hw_mode == VENC_SINGLE_CORE_MODE)
-		mtk_vcodec_release_enc_pm(dev);
+		mtk_vcodec_release_enc_pm(&dev->pm);
 err_enc_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -568,7 +568,7 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
 	v4l2_device_unregister(&dev->v4l2_dev);
 
 	if (dev->venc_pdata->hw_mode == VENC_SINGLE_CORE_MODE)
-		mtk_vcodec_release_enc_pm(dev);
+		mtk_vcodec_release_enc_pm(&dev->pm);
 
 	mtk_vcodec_fw_release(dev->fw_handler);
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
index 4e6a8a81ff67..2a9112b0561d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 
 #include "mtk_vcodec_enc_hw.h"
+#include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_enc.h"
 
 static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
@@ -105,6 +106,14 @@ static int mtk_venc_comp_probe(struct platform_device *pdev)
 
 	comp_dev->plat_dev = pdev;
 
+	ret = mtk_vcodec_init_enc_pm(pdev, &comp_dev->pm);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to get venc component clock source!");
+		return ret;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
 	comp_dev->core_id =
 		(enum mtk_venc_hw_id)of_device_get_match_data(&pdev->dev);
 
@@ -146,11 +155,15 @@ static int mtk_venc_comp_probe(struct platform_device *pdev)
 
 	return 0;
 err:
+	mtk_vcodec_release_enc_pm(&comp_dev->pm);
 	return ret;
 }
 
 static int mtk_venc_comp_remove(struct platform_device *pdev)
 {
+	struct mtk_venc_comp_dev *comp_dev = platform_get_drvdata(pdev);
+
+	mtk_vcodec_release_enc_pm(&comp_dev->pm);
 	component_del(&pdev->dev, &mtk_venc_component_ops);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 1b2e4930ed27..5edeb93fca84 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -13,38 +13,29 @@
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_enc_pm(struct platform_device *pdev,
+			   struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
-	struct platform_device *pdev;
-	struct mtk_vcodec_pm *pm;
+	struct platform_device *larb_pdev;
 	struct mtk_vcodec_clk *enc_clk;
 	struct mtk_vcodec_clk_info *clk_info;
 	int ret = 0, i = 0;
-	struct device *dev;
 
-	pdev = mtkdev->plat_dev;
-	pm = &mtkdev->pm;
-	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
-	pm->mtkdev = mtkdev;
-	pm->dev = &pdev->dev;
-	dev = &pdev->dev;
-	enc_clk = &pm->venc_clk;
-
-	node = of_parse_phandle(dev->of_node, "mediatek,larb", 0);
+	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
 	if (!node) {
 		mtk_v4l2_err("no mediatek,larb found");
 		return -ENODEV;
 	}
-	pdev = of_find_device_by_node(node);
+	larb_pdev = of_find_device_by_node(node);
 	of_node_put(node);
-	if (!pdev) {
+	if (!larb_pdev) {
 		mtk_v4l2_err("no mediatek,larb device found");
 		return -ENODEV;
 	}
-	pm->larbvenc = &pdev->dev;
-	pdev = mtkdev->plat_dev;
+	pm->larbvenc = &larb_pdev->dev;
 	pm->dev = &pdev->dev;
+	enc_clk = &pm->venc_clk;
 
 	enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
 		"clock-names");
@@ -87,10 +78,10 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
 	return ret;
 }
 
-void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev)
+void mtk_vcodec_release_enc_pm(struct mtk_vcodec_pm *pm)
 {
-	pm_runtime_disable(mtkdev->pm.dev);
-	put_device(mtkdev->pm.larbvenc);
+	pm_runtime_disable(pm->dev);
+	put_device(pm->larbvenc);
 }
 
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index b7ecdfd74823..f4a4aa441185 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -9,8 +9,9 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *dev);
-void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_enc_pm(struct platform_device *pdev,
+			   struct mtk_vcodec_pm *pm);
+void mtk_vcodec_release_enc_pm(struct mtk_vcodec_pm *pm);
 
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:30 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:30 +0800
Subject: [PATCH 5/9] media: mtk-vcodec: Rewrite venc clock interface
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-6-irui.wang@mediatek.com>

Frame-racing mode need enable the specific core's clk, add an
another param for clock_on/clock_off interface.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 104 ++++++++++++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |   4 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   |  10 +-
 3 files changed, 86 insertions(+), 32 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index d9df0e3701f1..bfb9e21bfd26 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -86,25 +86,50 @@ void mtk_vcodec_release_enc_pm(struct mtk_vcodec_pm *pm)
 }
 
 
-void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_enc_clock_on(struct mtk_vcodec_dev *dev, int core_id)
 {
-	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
-	int ret, i = 0;
+	struct mtk_venc_comp_dev *venc;
+	struct mtk_vcodec_pm *enc_pm;
+	struct mtk_vcodec_clk *enc_clk;
+	struct clk		*clk;
+	int ret, i;
 
-	for (i = 0; i < enc_clk->clk_num; i++) {
-		ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk);
-		if (ret) {
-			mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i,
-				enc_clk->clk_info[i].clk_name, ret);
-			goto clkerr;
+	if (dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
+		venc = (struct mtk_venc_comp_dev *)dev->enc_comp_dev[core_id];
+		enc_pm = &venc->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = 0; i < enc_clk->clk_num; i++) {
+			clk = enc_clk->clk_info[i].vcodec_clk;
+			ret = clk_enable(clk);
+			if (ret) {
+				mtk_v4l2_err("clk_enable %d %s fail %d", i,
+					     enc_clk->clk_info[i].clk_name,
+					     ret);
+				goto comp_clk_err;
+			}
 		}
-	}
+	} else {
+		enc_pm = &dev->pm;
+		enc_clk = &enc_pm->venc_clk;
 
-	ret = mtk_smi_larb_get(pm->larbvenc);
-	if (ret) {
-		mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret);
-		goto clkerr;
+		for (i = 0; i < enc_clk->clk_num; i++) {
+			clk = enc_clk->clk_info[i].vcodec_clk;
+			ret = clk_prepare_enable(clk);
+			if (ret) {
+				mtk_v4l2_err("clk_prepare_enable %d %s fail %d",
+					     i, enc_clk->clk_info[i].clk_name,
+					     ret);
+				goto clkerr;
+			}
+		}
 	}
+
+	return;
+
+comp_clk_err:
+	for (i -= 1; i >= 0; i--)
+		clk_disable(enc_clk->clk_info[i].vcodec_clk);
 	return;
 
 clkerr:
@@ -112,20 +137,35 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
 
-void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_enc_clock_off(struct mtk_vcodec_dev *dev, int core_id)
 {
-	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
-	int i = 0;
+	struct mtk_venc_comp_dev *venc;
+	struct mtk_vcodec_pm *enc_pm;
+	struct mtk_vcodec_clk *enc_clk;
+	int i;
 
-	mtk_smi_larb_put(pm->larbvenc);
-	for (i = enc_clk->clk_num - 1; i >= 0; i--)
-		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
+	if (dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
+		venc = (struct mtk_venc_comp_dev *)dev->enc_comp_dev[core_id];
+		enc_pm = &venc->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = enc_clk->clk_num - 1; i >= 0; i--)
+			clk_disable(enc_clk->clk_info[i].vcodec_clk);
+	} else {
+		enc_pm = &dev->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = enc_clk->clk_num - 1; i >= 0; i--)
+			clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
+	}
 }
 
 int mtk_venc_enable_comp_hw(struct mtk_vcodec_dev *dev)
 {
 	int i, ret;
 	struct mtk_venc_comp_dev *venc_comp;
+	struct mtk_vcodec_clk *enc_clk;
+	int j = 0;
 
 	/*
 	 * frame_racing mode needs power on all available component devices.
@@ -140,23 +180,38 @@ int mtk_venc_enable_comp_hw(struct mtk_vcodec_dev *dev)
 			mtk_v4l2_err("power on core[%d] fail %d", i, ret);
 				goto pw_err;
 		}
+
+		enc_clk = &venc_comp->pm.venc_clk;
+		for (j = 0; j < enc_clk->clk_num; j++) {
+			ret = clk_prepare(enc_clk->clk_info[j].vcodec_clk);
+			if (ret) {
+				mtk_v4l2_err("prepare clk [%s] fail %d",
+					     enc_clk->clk_info[j].clk_name,
+					     ret);
+				goto pw_err;
+			}
+		}
 	}
 	return 0;
 
 pw_err:
 	for (i -= 1; i >= 0; i--) {
 		venc_comp = (struct mtk_venc_comp_dev *)dev->enc_comp_dev[i];
+		enc_clk = &venc_comp->pm.venc_clk;
+
+		for (j -= 1; j >= 0; j--)
+			clk_unprepare(enc_clk->clk_info[j].vcodec_clk);
 
 		mtk_smi_larb_put(venc_comp->pm.larbvenc);
 	}
-
 	return ret;
 }
 
 int mtk_venc_disable_comp_hw(struct mtk_vcodec_dev *dev)
 {
-	int i;
+	int i, j;
 	struct mtk_venc_comp_dev *venc_comp;
+	struct mtk_vcodec_clk *enc_clk;
 
 	/*power off all available component device*/
 	for (i = 0; i < MTK_VENC_HW_MAX; i++) {
@@ -164,6 +219,11 @@ int mtk_venc_disable_comp_hw(struct mtk_vcodec_dev *dev)
 		if (!venc_comp)
 			return 0;
 
+		enc_clk = &venc_comp->pm.venc_clk;
+
+		for (j = enc_clk->clk_num - 1; j >= 0; j--)
+			clk_unprepare(enc_clk->clk_info[j].vcodec_clk);
+
 		mtk_smi_larb_put(venc_comp->pm.larbvenc);
 	}
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index 2e76b858fed1..f3a819cc0e56 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -13,8 +13,8 @@ int mtk_vcodec_init_enc_pm(struct platform_device *pdev,
 			   struct mtk_vcodec_pm *pm);
 void mtk_vcodec_release_enc_pm(struct mtk_vcodec_pm *pm);
 
-void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
+void mtk_vcodec_enc_clock_on(struct mtk_vcodec_dev *dev, int core_id);
+void mtk_vcodec_enc_clock_off(struct mtk_vcodec_dev *dev, int core_id);
 
 int mtk_venc_enable_comp_hw(struct mtk_vcodec_dev *dev);
 int mtk_venc_disable_comp_hw(struct mtk_vcodec_dev *dev);
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.c b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
index ce0bce811615..6cbdb7e30bb3 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
@@ -32,9 +32,7 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 	}
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->init(ctx);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	return ret;
@@ -46,9 +44,7 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
 	int ret = 0;
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	return ret;
@@ -68,10 +64,10 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 	ctx->dev->curr_ctx = ctx;
 	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
 
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
+	mtk_vcodec_enc_clock_on(ctx->dev, 0);
 	ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
 				  bs_buf, result);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
+	mtk_vcodec_enc_clock_off(ctx->dev, 0);
 
 	spin_lock_irqsave(&ctx->dev->irqlock, flags);
 	ctx->dev->curr_ctx = NULL;
@@ -89,9 +85,7 @@ int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
 		return 0;
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->deinit(ctx->drv_handle);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	ctx->drv_handle = NULL;
-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:27 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:27 +0800
Subject: [PATCH 2/9] media: mtk-vcodec: Use component framework to manage
 encoder hardware
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-3-irui.wang@mediatek.com>

There are two venc cores for H264 inside MT8195, uses component
framework to manage each hardware so that the two cores can be
used through one venc driver.

Adds new encoder hardware mode to indicate different hardware
modes:
VENC_SINGLE_CORE_MODE means only one core, the device has its
own power/clk/irq, init_pm/request_irq helper can be used.

VENC_FRAME_RACING_MODE means more than one core inside, the core
device driver can use the init_pm/request_irq helper to
initialize their own power/clk/irq. And the master device doesn't
need use these helper anymore.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  22 ++
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  | 189 +++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_enc_hw.c   | 179 +++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_hw.h   |  36 ++++
 6 files changed, 397 insertions(+), 32 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 4618d43dbbc8..661d4afeb628 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -20,6 +20,7 @@ mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		mtk_vcodec_enc_pm.o \
 		venc_drv_if.o \
 		venc_vpu_if.o \
+		mtk_vcodec_enc_hw.o \
 
 
 mtk-vcodec-common-y := mtk_vcodec_intr.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 3f83710b4fa5..c160b9e505eb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -8,6 +8,7 @@
 #ifndef _MTK_VCODEC_DRV_H_
 #define _MTK_VCODEC_DRV_H_
 
+#include <linux/component.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-ctrls.h>
@@ -92,6 +93,20 @@ enum mtk_fmt_type {
 	MTK_FMT_FRAME = 2,
 };
 
+enum mtk_venc_hw_id {
+	MTK_VENC_CORE0 = 0,
+	MTK_VENC_CORE1 = 1,
+	MTK_VENC_HW_MAX,
+};
+
+/**
+ * enmu mtk_venc_hw_mode - Used to indicate different encode mode
+ */
+enum mtk_venc_hw_mode {
+	VENC_SINGLE_CORE_MODE = 0,
+	VENC_FRAME_RACING_MODE = 1,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -320,6 +335,7 @@ enum mtk_chip {
  * @output_formats: array of supported output formats
  * @num_output_formats: number of entries in output_formats
  * @core_id: stand for h264 or vp8 encode index
+ * @hw_mode: indicate encode mode
  */
 struct mtk_vcodec_enc_pdata {
 	enum mtk_chip chip;
@@ -332,6 +348,7 @@ struct mtk_vcodec_enc_pdata {
 	const struct mtk_video_fmt *output_formats;
 	size_t num_output_formats;
 	int core_id;
+	enum mtk_venc_hw_mode hw_mode;
 };
 
 #define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
@@ -372,6 +389,8 @@ struct mtk_vcodec_enc_pdata {
  * @pm: power management control
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
+ * @enc_comp_node: used to store venc component node
+ * @enc_comp_dev: used to store venc component device
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -407,6 +426,9 @@ struct mtk_vcodec_dev {
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
 	unsigned int enc_capability;
+
+	struct device_node *enc_comp_node[MTK_VENC_HW_MAX];
+	void *enc_comp_dev[MTK_VENC_HW_MAX];
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
index 513ee7993e34..30b6d7f22ed7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
@@ -21,6 +21,8 @@
 #define MTK_VENC_IRQ_STATUS_OFFSET	0x05C
 #define MTK_VENC_IRQ_ACK_OFFSET	0x060
 
+extern struct platform_driver mtk_venc_comp_driver;
+
 /**
  * struct mtk_video_enc_buf - Private data related to each VB2 buffer.
  * @m2m_buf:	M2M buffer
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 7b3e0ea4c410..f7538d4b5cbb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -26,6 +26,81 @@
 module_param(mtk_v4l2_dbg_level, int, S_IRUGO | S_IWUSR);
 module_param(mtk_vcodec_dbg, bool, S_IRUGO | S_IWUSR);
 
+static const struct of_device_id mtk_venc_comp_ids[] = {
+	{
+		.compatible = "mediatek,mtk-venc-core0",
+		.data = (void *)MTK_VENC_CORE0,
+	},
+	{
+		.compatible = "mediatek,mtk-venc-core1",
+		.data = (void *)MTK_VENC_CORE1,
+	},
+	{},
+};
+
+static inline int mtk_venc_compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static inline void mtk_venc_release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
+static inline int mtk_venc_bind(struct device *dev)
+{
+	struct mtk_vcodec_dev *data = dev_get_drvdata(dev);
+
+	return component_bind_all(dev, data);
+}
+
+static inline void mtk_venc_unbind(struct device *dev)
+{
+	struct mtk_vcodec_dev *data = dev_get_drvdata(dev);
+
+	component_unbind_all(dev, data);
+}
+
+static const struct component_master_ops mtk_venc_ops = {
+	.bind = mtk_venc_bind,
+	.unbind = mtk_venc_unbind,
+};
+
+static struct component_match *mtk_venc_match_add(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	struct component_match *match = NULL;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_venc_comp_ids); i++) {
+		enum mtk_venc_hw_id comp_idx;
+		struct device_node *comp_node;
+		const struct of_device_id *of_id;
+
+		comp_node = of_find_compatible_node(NULL, NULL,
+			mtk_venc_comp_ids[i].compatible);
+		if (!comp_node)
+			continue;
+
+		of_id = of_match_node(mtk_venc_comp_ids, comp_node);
+		if (!of_id) {
+			dev_err(&pdev->dev, "Failed to get match node\n");
+			return ERR_PTR(-EINVAL);
+		}
+
+		comp_idx = (enum mtk_venc_hw_id)of_id->data;
+		dev->enc_comp_node[comp_idx] = comp_node;
+
+		component_match_add_release(&pdev->dev, &match,
+					    mtk_venc_release_of,
+					    mtk_venc_compare_of,
+					    comp_node);
+	}
+
+	return match;
+}
+
 static const struct mtk_video_fmt mtk_video_formats_output[] = {
 	{
 		.fourcc = V4L2_PIX_FMT_NV12M,
@@ -239,6 +314,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
 	int ret;
+	struct component_match *match = NULL;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -264,39 +340,41 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		return PTR_ERR(dev->fw_handler);
 
 	dev->venc_pdata = of_device_get_match_data(&pdev->dev);
-	ret = mtk_vcodec_init_enc_pm(dev);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!");
-		goto err_enc_pm;
-	}
+	if (dev->venc_pdata->hw_mode == VENC_SINGLE_CORE_MODE) {
+		ret = mtk_vcodec_init_enc_pm(dev);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!");
+			goto err_enc_pm;
+		}
 
-	pm_runtime_enable(&pdev->dev);
+		pm_runtime_enable(&pdev->dev);
 
-	dev->reg_base[dev->venc_pdata->core_id] =
-		devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(dev->reg_base[dev->venc_pdata->core_id])) {
-		ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_id]);
-		goto err_res;
-	}
+		dev->reg_base[dev->venc_pdata->core_id] =
+			devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(dev->reg_base[dev->venc_pdata->core_id])) {
+			ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_id]);
+			goto err_res;
+		}
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
-		goto err_res;
-	}
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+		if (!res) {
+			dev_err(&pdev->dev, "failed to get irq resource");
+			ret = -ENOENT;
+			goto err_res;
+		}
 
-	dev->enc_irq = platform_get_irq(pdev, 0);
-	irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, dev->enc_irq,
-			       mtk_vcodec_enc_irq_handler,
-			       0, pdev->name, dev);
-	if (ret) {
-		dev_err(&pdev->dev,
-			"Failed to install dev->enc_irq %d (%d) core_id (%d)",
-			dev->enc_irq, ret, dev->venc_pdata->core_id);
-		ret = -EINVAL;
-		goto err_res;
+		dev->enc_irq = platform_get_irq(pdev, 0);
+		irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
+		ret = devm_request_irq(&pdev->dev, dev->enc_irq,
+				       mtk_vcodec_enc_irq_handler,
+				       0, pdev->name, dev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Failed to install dev->enc_irq %d (%d) core_id (%d)",
+				dev->enc_irq, ret, dev->venc_pdata->core_id);
+			ret = -EINVAL;
+			goto err_res;
+		}
 	}
 
 	mutex_init(&dev->enc_mutex);
@@ -362,6 +440,22 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_enc_reg;
 	}
 
+	if (dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
+		match = mtk_venc_match_add(dev);
+		if (IS_ERR_OR_NULL(match)) {
+			mtk_v4l2_err("match venc component failed\n");
+			ret = -EINVAL;
+			goto err_enc_reg;
+		}
+		ret = component_master_add_with_match(&pdev->dev,
+						      &mtk_venc_ops, match);
+		if (ret) {
+			mtk_v4l2_err("Failed to bring up master");
+			ret = -EINVAL;
+			goto err_enc_reg;
+		}
+	}
+
 	mtk_v4l2_debug(0, "encoder %d registered as /dev/video%d",
 		       dev->venc_pdata->core_id, vfd_enc->num);
 
@@ -376,7 +470,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_enc_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	mtk_vcodec_release_enc_pm(dev);
+	if (dev->venc_pdata->hw_mode == VENC_SINGLE_CORE_MODE)
+		mtk_vcodec_release_enc_pm(dev);
 err_enc_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -391,6 +486,7 @@ static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
 	.min_bitrate = 1,
 	.max_bitrate = 4000000,
 	.core_id = VENC_SYS,
+	.hw_mode = VENC_SINGLE_CORE_MODE,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
@@ -402,6 +498,7 @@ static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 4000000,
 	.core_id = VENC_LT_SYS,
+	.hw_mode = VENC_SINGLE_CORE_MODE,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
@@ -414,6 +511,7 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 40000000,
 	.core_id = VENC_SYS,
+	.hw_mode = VENC_SINGLE_CORE_MODE,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
@@ -426,6 +524,7 @@ static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 100000000,
 	.core_id = VENC_SYS,
+	.hw_mode = VENC_SINGLE_CORE_MODE,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
@@ -438,6 +537,7 @@ static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 100000000,
 	.core_id = VENC_SYS,
+	.hw_mode = VENC_FRAME_RACING_MODE,
 };
 
 static const struct of_device_id mtk_vcodec_enc_match[] = {
@@ -466,8 +566,15 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_enc);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_enc_pm(dev);
+
+	if (dev->venc_pdata->hw_mode == VENC_SINGLE_CORE_MODE)
+		mtk_vcodec_release_enc_pm(dev);
+
 	mtk_vcodec_fw_release(dev->fw_handler);
+
+	if (dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE)
+		component_master_del(&pdev->dev, &mtk_venc_ops);
+
 	return 0;
 }
 
@@ -480,7 +587,25 @@ static struct platform_driver mtk_vcodec_enc_driver = {
 	},
 };
 
-module_platform_driver(mtk_vcodec_enc_driver);
+static struct platform_driver * const mtk_venc_drivers[] = {
+	&mtk_venc_comp_driver,
+	&mtk_vcodec_enc_driver,
+};
+
+static int __init mtk_venc_init(void)
+{
+	return platform_register_drivers(mtk_venc_drivers,
+					 ARRAY_SIZE(mtk_venc_drivers));
+}
+
+static void __exit mtk_venc_exit(void)
+{
+	platform_unregister_drivers(mtk_venc_drivers,
+				    ARRAY_SIZE(mtk_venc_drivers));
+}
+
+module_init(mtk_venc_init);
+module_exit(mtk_venc_exit);
 
 
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
new file mode 100644
index 000000000000..4e6a8a81ff67
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/pm_runtime.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of_platform.h>
+#include <linux/module.h>
+
+#include "mtk_vcodec_enc_hw.h"
+#include "mtk_vcodec_enc.h"
+
+static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
+{
+	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
+		writel(MTK_VENC_IRQ_STATUS_PAUSE, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_SWITCH)
+		writel(MTK_VENC_IRQ_STATUS_SWITCH, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_DRAM)
+		writel(MTK_VENC_IRQ_STATUS_DRAM, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_SPS)
+		writel(MTK_VENC_IRQ_STATUS_SPS, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_PPS)
+		writel(MTK_VENC_IRQ_STATUS_PPS, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_FRM)
+		writel(MTK_VENC_IRQ_STATUS_FRM, addr);
+}
+
+static irqreturn_t mtk_enc_comp_irq_handler(int irq, void *priv)
+{
+	struct mtk_venc_comp_dev *dev = priv;
+	struct mtk_vcodec_ctx *ctx;
+	unsigned long flags;
+	void __iomem *addr;
+
+	spin_lock_irqsave(&dev->master_dev->irqlock, flags);
+	ctx = dev->curr_ctx;
+	spin_unlock_irqrestore(&dev->master_dev->irqlock, flags);
+	if (!ctx)
+		return IRQ_HANDLED;
+
+	addr = dev->reg_base + MTK_VENC_IRQ_ACK_OFFSET;
+	ctx->irq_status = readl(dev->reg_base + MTK_VENC_IRQ_STATUS_OFFSET);
+	clean_irq_status(ctx->irq_status, addr);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_venc_comp_bind(struct device *dev,
+			      struct device *master, void *data)
+{
+	struct mtk_venc_comp_dev *comp_dev = dev_get_drvdata(dev);
+	struct mtk_vcodec_dev *master_dev = data;
+	int i;
+
+	for (i = 0; i < MTK_VENC_HW_MAX; i++) {
+		if (dev->of_node != master_dev->enc_comp_node[i])
+			continue;
+
+		/*add component device by order*/
+		if (comp_dev->core_id == MTK_VENC_CORE0)
+			master_dev->enc_comp_dev[MTK_VENC_CORE0] = comp_dev;
+		else if (comp_dev->core_id == MTK_VENC_CORE1)
+			master_dev->enc_comp_dev[MTK_VENC_CORE1] = comp_dev;
+		else
+			return -EINVAL;
+
+		comp_dev->master_dev = master_dev;
+		break;
+	}
+
+	if (i == MTK_VENC_HW_MAX) {
+		dev_err(dev, "Failed to get component node\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void mtk_venc_comp_unbind(struct device *dev,
+				 struct device *master, void *data)
+{
+}
+
+static const struct component_ops mtk_venc_component_ops = {
+	.bind = mtk_venc_comp_bind,
+	.unbind = mtk_venc_comp_unbind,
+};
+
+static int mtk_venc_comp_probe(struct platform_device *pdev)
+{
+	struct mtk_venc_comp_dev *comp_dev;
+	int ret;
+
+	comp_dev = devm_kzalloc(&pdev->dev, sizeof(*comp_dev), GFP_KERNEL);
+	if (!comp_dev)
+		return -ENOMEM;
+
+	comp_dev->plat_dev = pdev;
+
+	comp_dev->core_id =
+		(enum mtk_venc_hw_id)of_device_get_match_data(&pdev->dev);
+
+	comp_dev->reg_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(comp_dev->reg_base)) {
+		dev_err(&pdev->dev, "Failed to get reg base");
+		ret = PTR_ERR(comp_dev->reg_base);
+		goto err;
+	}
+
+	comp_dev->enc_irq = platform_get_irq(pdev, 0);
+	if (comp_dev->enc_irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource");
+		ret = comp_dev->enc_irq;
+		goto err;
+	}
+
+	ret = devm_request_irq(&pdev->dev, comp_dev->enc_irq,
+			       mtk_enc_comp_irq_handler, 0,
+			       pdev->name, comp_dev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to install comp_dev->enc_irq %d (%d)",
+			comp_dev->enc_irq, ret);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+
+	platform_set_drvdata(pdev, comp_dev);
+
+	ret = component_add(&pdev->dev, &mtk_venc_component_ops);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add component: %d\n", ret);
+		goto err;
+	}
+
+	return 0;
+err:
+	return ret;
+}
+
+static int mtk_venc_comp_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_venc_component_ops);
+	return 0;
+}
+
+static const struct of_device_id mtk_venc_comp_ids[] = {
+	{
+		.compatible = "mediatek,mtk-venc-core0",
+		.data = (void *)MTK_VENC_CORE0,
+	},
+	{
+		.compatible = "mediatek,mtk-venc-core1",
+		.data = (void *)MTK_VENC_CORE1,
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_venc_comp_ids);
+
+struct platform_driver mtk_venc_comp_driver = {
+	.probe  = mtk_venc_comp_probe,
+	.remove = mtk_venc_comp_remove,
+	.driver = {
+		.name	 = "mtk-venc-comp",
+		.of_match_table = mtk_venc_comp_ids,
+	},
+};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h
new file mode 100644
index 000000000000..f9ae97e252dc
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef _MTK_VCODEC_ENC_HW_H_
+#define _MTK_VCODEC_ENC_HW_H_
+
+#include <linux/platform_device.h>
+#include "mtk_vcodec_drv.h"
+
+/*
+ * struct mtk_venc_comp_dev - driver data
+ * @plat_dev: platform_device
+ * @master_dev: master device
+ * @pm: power management data
+ * @curr_ctx: the context that is waiting for venc hardware
+ * @reg_base: mapped address of venc registers
+ * @irq_status: venc hw irq status
+ * @enc_irq: venc device irq
+ * @core id: for venc core id: core#0, core#1...
+ */
+struct mtk_venc_comp_dev {
+	struct platform_device *plat_dev;
+	struct mtk_vcodec_dev *master_dev;
+
+	struct mtk_vcodec_pm pm;
+	struct mtk_vcodec_ctx *curr_ctx;
+
+	void __iomem *reg_base;
+	unsigned int irq_status;
+	int enc_irq;
+	int core_id;
+};
+
+#endif /* _MTK_VCODEC_ENC_HW_H_ */
-- 
2.25.1

From irui.wang at mediatek.com  Mon Aug 16 03:59:33 2021
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 16 Aug 2021 18:59:33 +0800
Subject: [PATCH 8/9] media: mtk-vcodec: Return encode result to client
In-Reply-To: <20210816105934.28265-1-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
Message-ID: <20210816105934.28265-9-irui.wang@mediatek.com>

For frame-racing mode encoding, there will no sync wait IRQ done
function, so the encode result can't return to client in
device_run. After device_run called to trigger encoding process,
finish it, so another scheduled job can be ran. When encoding
done, return the encode result to client in IRQ handler.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  6 ++
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 61 ++++++++++++++++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |  4 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_hw.c   | 35 +++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |  1 +
 .../platform/mtk-vcodec/venc/venc_common_if.c |  9 +++
 .../media/platform/mtk-vcodec/venc_drv_if.h   |  2 +
 7 files changed, 115 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 7a9c2dd52b91..c43321362896 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -274,6 +274,9 @@ struct vdec_pic_info {
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
  * @enc_idx: used to record encoded frame count
+ * @pfrm_buf: used to store current ctx's frame buffer information
+ * @pbs_buf: used to store current ctx's bitstream buffer information
+ * @hdr_size: used to store prepend header size
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -316,6 +319,9 @@ struct mtk_vcodec_ctx {
 
 	int hw_id;
 	int enc_idx;
+	struct vb2_v4l2_buffer *pfrm_buf[MTK_VENC_HW_MAX];
+	struct vb2_v4l2_buffer *pbs_buf[MTK_VENC_HW_MAX];
+	unsigned int hdr_size;
 };
 
 enum mtk_chip {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 6b37bd092fdf..de8e012f1b0e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -867,6 +867,8 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
 
 	mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type);
 
+	mtk_venc_lock_all(ctx);
+
 	if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
 			dst_buf->vb2_buf.planes[0].bytesused = 0;
@@ -1014,10 +1016,13 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
 				ctx->id,
 				vb2_v4l2->vb2_buf.index,
 				mtk_buf->enc_params.force_intra);
-		if (mtk_buf->enc_params.force_intra)
+		if (mtk_buf->enc_params.force_intra) {
 			ret |= venc_if_set_param(ctx,
 						 VENC_SET_PARAM_FORCE_INTRA,
 						 NULL);
+
+			ctx->enc_idx = 0;
+		}
 	}
 
 	mtk_buf->param_change = MTK_ENCODE_PARAM_NONE;
@@ -1068,9 +1073,12 @@ static void mtk_venc_worker(struct work_struct *work)
 		frm_buf.fb_addr[i].size =
 				(size_t)src_buf->vb2_buf.planes[i].length;
 	}
+	frm_buf.src_addr = src_buf;
+
 	bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
 	bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
 	bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length;
+	bs_buf.buf = dst_buf;
 
 	mtk_v4l2_debug(2,
 			"Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu",
@@ -1119,6 +1127,8 @@ static void m2mops_venc_device_run(void *priv)
 {
 	struct mtk_vcodec_ctx *ctx = priv;
 
+	mtk_venc_param_change(ctx);
+
 	if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) &&
 	    (ctx->state != MTK_STATE_HEADER)) {
 		/* encode h264 sps/pps header */
@@ -1127,7 +1137,6 @@ static void m2mops_venc_device_run(void *priv)
 		return;
 	}
 
-	mtk_venc_param_change(ctx);
 	queue_work(ctx->dev->encode_workqueue, &ctx->encode_work);
 }
 
@@ -1310,6 +1319,33 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 	return vb2_queue_init(dst_vq);
 }
 
+void mtk_venc_buf_done(struct mtk_vcodec_ctx *ctx, int core_id,
+		       unsigned int bs_size, bool time_out, bool key_frame)
+{
+	struct vb2_v4l2_buffer *src_vb2_v4l2 = NULL;
+	struct vb2_v4l2_buffer *dst_vb2_v4l2 = NULL;
+
+	/*
+	 * the frm_buf(src_buf) and bs_buf(dst_buf) can be obtained from ctx,
+	 * then put them to done list, user can get them by dqbuf call
+	 */
+	src_vb2_v4l2 = ctx->pfrm_buf[core_id];
+	dst_vb2_v4l2 = ctx->pbs_buf[core_id];
+
+	if (src_vb2_v4l2 && dst_vb2_v4l2) {
+		dst_vb2_v4l2->vb2_buf.timestamp =
+			src_vb2_v4l2->vb2_buf.timestamp;
+		dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode;
+
+		if (key_frame)
+			dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME;
+
+		v4l2_m2m_buf_done(src_vb2_v4l2, VB2_BUF_STATE_DONE);
+		dst_vb2_v4l2->vb2_buf.planes[0].bytesused = bs_size;
+		v4l2_m2m_buf_done(dst_vb2_v4l2, VB2_BUF_STATE_DONE);
+	}
+}
+
 int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
@@ -1335,3 +1371,24 @@ void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
 
 	ctx->state = MTK_STATE_FREE;
 }
+
+void mtk_venc_lock_all(struct mtk_vcodec_ctx *ctx)
+{
+	unsigned int i;
+	struct mtk_vcodec_dev *dev = ctx->dev;
+
+	/*
+	 * For frame-racing mode encoding, there are may be bufs being encoded
+	 * when get the empty flush buffer or stop streaming, for example, the
+	 * buffer with LAST flag will return to client before the encoding
+	 * buffers, which will cause frame lost.
+	 * The encoder device mutex will be locked during encoding process,
+	 * when encode done, the mutex unlocked. So if all encoder device mutex
+	 * can be locked, which means there are no bufs being encoded at this
+	 * time, then the buffer with LAST flag can return to client properly.
+	 */
+	for (i = 0; i < MTK_VENC_HW_MAX; i++) {
+		mutex_lock(&dev->enc_mutex[i]);
+		mutex_unlock(&dev->enc_mutex[i]);
+	}
+}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
index 8d486f532025..1d603ccb2f3d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
@@ -48,5 +48,7 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx);
 int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx);
 void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx);
-
+void mtk_venc_buf_done(struct mtk_vcodec_ctx *ctx, int core_id,
+		       unsigned int bs_size, bool time_out, bool key_frame);
+void mtk_venc_lock_all(struct mtk_vcodec_ctx *ctx);
 #endif /* _MTK_VCODEC_ENC_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
index 2a9112b0561d..687b255c58e8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
@@ -12,6 +12,17 @@
 #include "mtk_vcodec_enc_hw.h"
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_enc.h"
+#define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
+#define VENC_PIC_FRM_TYPE	0x0010
+#define VENC_PIC_KEY_FRM	0x2
+
+/* Wake up core context wait_queue */
+static void mtk_venc_comp_wake_up_ctx(struct mtk_vcodec_ctx *ctx,
+				      unsigned int hw_id)
+{
+	ctx->int_cond = 1;
+	wake_up_interruptible(&ctx->queue);
+}
 
 static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
 {
@@ -40,6 +51,9 @@ static irqreturn_t mtk_enc_comp_irq_handler(int irq, void *priv)
 	struct mtk_vcodec_ctx *ctx;
 	unsigned long flags;
 	void __iomem *addr;
+	unsigned int bs_size;
+	unsigned int frm_type;
+	bool is_key_frame = 0;
 
 	spin_lock_irqsave(&dev->master_dev->irqlock, flags);
 	ctx = dev->curr_ctx;
@@ -49,7 +63,28 @@ static irqreturn_t mtk_enc_comp_irq_handler(int irq, void *priv)
 
 	addr = dev->reg_base + MTK_VENC_IRQ_ACK_OFFSET;
 	ctx->irq_status = readl(dev->reg_base + MTK_VENC_IRQ_STATUS_OFFSET);
+	bs_size = readl(dev->reg_base + VENC_PIC_BITSTREAM_BYTE_CNT);
+	frm_type = readl(dev->reg_base + VENC_PIC_FRM_TYPE);
 	clean_irq_status(ctx->irq_status, addr);
+	if (ctx->irq_status & MTK_VENC_IRQ_STATUS_FRM) {
+		if (ctx->hdr_size != 0) {
+			bs_size += ctx->hdr_size;
+			ctx->hdr_size = 0;
+		}
+		if (frm_type & VENC_PIC_KEY_FRM)
+			is_key_frame = 1;
+
+		mtk_venc_buf_done(ctx, dev->core_id, bs_size, 0, is_key_frame);
+		mtk_vcodec_enc_clock_off(dev->master_dev, dev->core_id);
+
+		spin_lock_irqsave(&dev->master_dev->irqlock, flags);
+		dev->curr_ctx = NULL;
+		spin_unlock_irqrestore(&dev->master_dev->irqlock, flags);
+
+		mtk_venc_unlock(ctx, dev->core_id);
+	} else {
+		mtk_venc_comp_wake_up_ctx(ctx, dev->core_id);
+	}
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index 0027747c0a27..7321b7537f20 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -15,6 +15,7 @@ struct mtk_vcodec_mem {
 	size_t size;
 	void *va;
 	dma_addr_t dma_addr;
+	void *buf;
 };
 
 struct mtk_vcodec_fb {
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
index 1580bd1beaac..75b4e90232ae 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_common_if.c
@@ -481,6 +481,13 @@ static int venc_encode(void *handle,
 		unsigned int bs_size_hdr;
 		unsigned int bs_size_frm;
 
+		/*
+		 * the frm_buf and bs_buf need to be recorded into ctx,
+		 * when encoding done, the target buffer can be obtained
+		 */
+		ctx->pfrm_buf[ctx->hw_id] = frm_buf->src_addr;
+		ctx->pbs_buf[ctx->hw_id] = bs_buf->buf;
+
 		if (!inst->prepend_hdr) {
 			ret = venc_encode_frame(inst, frm_buf, bs_buf,
 						&result->bs_size, ctx->hw_id);
@@ -528,6 +535,8 @@ static int venc_encode(void *handle,
 
 		result->bs_size = hdr_sz + filler_sz + bs_size_frm;
 
+		ctx->hdr_size = hdr_sz + filler_sz;
+
 		mtk_vcodec_debug(inst, "hdr %d filler %d frame %d bs %d",
 				 hdr_sz, filler_sz, bs_size_frm,
 				 result->bs_size);
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.h b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
index 7bd1f437d8e3..50824e718c91 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
@@ -108,9 +108,11 @@ struct venc_frame_info {
 /*
  * struct venc_frm_buf - frame buffer information used in venc_if_encode()
  * @fb_addr: plane frame buffer addresses
+ * @src_addr: vb2_v4l2_buffer src buffer address
  */
 struct venc_frm_buf {
 	struct mtk_vcodec_fb fb_addr[MTK_VCODEC_MAX_PLANES];
+	void *src_addr;
 };
 
 /*
-- 
2.25.1

From cgel.zte at gmail.com  Mon Aug 16 04:29:16 2021
From: cgel.zte at gmail.com (cgel.zte at gmail.com)
Date: Mon, 16 Aug 2021 04:29:16 -0700
Subject: [PATCH linux-next] module: remove duplicate include in interrupt.c
Message-ID: <20210816112917.126675-1-lv.ruyi@zte.com.cn>

From: Lv Ruyi <lv.ruyi at zte.com.cn>

'asm/interrupt.h' included in 'interrupt.c' is duplicated.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Lv Ruyi <lv.ruyi at zte.com.cn>
---
 arch/arm/mach-sa1100/hackkit.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 3085f1c2e586..3fe34ee7c0ab 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -18,7 +18,6 @@
 #include <linux/serial_core.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <linux/tty.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
-- 
2.25.1



From hsin-hsiung.wang at mediatek.com  Mon Aug 16 05:11:38 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-hsiung Wang)
Date: Mon, 16 Aug 2021 20:11:38 +0800
Subject: [PATCH v10 3/5] spmi: mediatek: Add support for MT6873/8192
In-Reply-To: <162853170949.1975443.12492156194100139076@swboyd.mtv.corp.google.com>
References: <1627972461-2627-1-git-send-email-hsin-hsiung.wang@mediatek.com>
 <1627972461-2627-4-git-send-email-hsin-hsiung.wang@mediatek.com>
 <162853170949.1975443.12492156194100139076@swboyd.mtv.corp.google.com>
Message-ID: <1629115898.29907.3.camel@mtksdaap41>

Hi,

On Mon, 2021-08-09 at 10:55 -0700, Stephen Boyd wrote:
> Quoting Hsin-Hsiung Wang (2021-08-02 23:34:19)
> > diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
> > new file mode 100644
> > index 000000000000..94c45d46ab0c
> > --- /dev/null
> > +++ b/drivers/spmi/spmi-mtk-pmif.c
> > @@ -0,0 +1,465 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// Copyright (c) 2021 MediaTek Inc.
> > +
> > +#include <linux/clk.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> 
> include platform_device.h for the platform device driver that this is.
> 
Thanks for the commit, I will update it in the next patch.

> > +#include <linux/spmi.h>
> > +
> > +#define SWINF_IDLE     0x00
> > +#define SWINF_WFVLDCLR 0x06
> > +
> > +#define GET_SWINF(x)   (((x) >> 1) & 0x7)
> > +
> > +#define PMIF_CMD_REG_0         0
> > +#define PMIF_CMD_REG           1
> > +#define PMIF_CMD_EXT_REG       2
> > +#define PMIF_CMD_EXT_REG_LONG  3
> > +
> > +#define PMIF_DELAY_US   10
> > +#define PMIF_TIMEOUT_US (10 * 1000)
> > +
> > +#define PMIF_CHAN_OFFSET 0x5
> > +
> > +#define PMIF_MAX_CLKS  3
> > +
> > +#define SPMI_OP_ST_BUSY 1
> > +
> > +struct ch_reg {
> > +       u32 ch_sta;
> > +       u32 wdata;
> > +       u32 rdata;
> > +       u32 ch_send;
> > +       u32 ch_rdy;
> > +};
> > +
> > +struct pmif_data {
> > +       const u32       *regs;
> > +       const u32       *spmimst_regs;
> > +       u32     soc_chan;
> > +};
> > +
> > +struct pmif {
> > +       void __iomem    *base;
> > +       void __iomem    *spmimst_base;
> > +       struct ch_reg   chan;
> > +       struct clk_bulk_data clks[PMIF_MAX_CLKS];
> > +       u32 nclks;
> 
> size_t? Surely 32-bits isn't important.
> 

Thanks. I will use size_t in the next patch.

> > +       const struct pmif_data *data;
> > +};
> > +
> > +static const char * const pmif_clock_names[] = {
> > +       "pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux",
> > +};
> [...]
> > +
> > +static bool pmif_is_fsm_vldclr(struct pmif *arb)
> > +{
> > +       u32 reg_rdata;
> > +
> > +       reg_rdata = pmif_readl(arb, arb->chan.ch_sta);
> 
> Newline here please.
> 

Thanks, I will update it in the next patch.

> > +       return GET_SWINF(reg_rdata) == SWINF_WFVLDCLR;
> > +}
> > +
> > +static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
> > +{
> > +       struct pmif *arb = spmi_controller_get_drvdata(ctrl);
> > +       u32 rdata, cmd;
> > +       int ret;
> > +
> > +       /* Check the opcode */
> > +       if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
> > +               return -EINVAL;
> > +
> > +       cmd = opc - SPMI_CMD_RESET;
> > +
> > +       mtk_spmi_writel(arb, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL);
> > +       ret = readl_poll_timeout_atomic(arb->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA],
> > +                                       rdata, (rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY,
> > +                                       PMIF_DELAY_US, PMIF_TIMEOUT_US);
> > +       if (ret < 0)
> > +               dev_err(&ctrl->dev, "timeout, err = %d\n", ret);
> > +
> > +       return ret;
> > +}
> > +
> > +static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
> > +                             u16 addr, u8 *buf, size_t len)
> > +{
> > +       struct pmif *arb = spmi_controller_get_drvdata(ctrl);
> > +       struct ch_reg *inf_reg;
> > +       int ret;
> > +       u32 data, cmd;
> > +
> > +       /* Check for argument validation. */
> > +       if (sid & ~0xf) {
> > +               dev_err(&ctrl->dev, "exceed the max slv id\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       if (len > 4) {
> > +               dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
> 
> Missing newline
> 

Thanks, I will update it in the next patch.

> > +               return -EINVAL;
> > +       }
> > +
> > +       if (opc >= 0x60 && opc <= 0x7f)
> > +               opc = PMIF_CMD_REG;
> > +       else if ((opc >= 0x20 && opc <= 0x2f) || (opc >= 0x38 && opc <= 0x3f))
> > +               opc = PMIF_CMD_EXT_REG_LONG;
> > +       else
> > +               return -EINVAL;
> > +
> > +       /* Wait for Software Interface FSM state to be IDLE. */
> > +       inf_reg = &arb->chan;
> > +       ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
> > +                                       data, GET_SWINF(data) == SWINF_IDLE,
> > +                                       PMIF_DELAY_US, PMIF_TIMEOUT_US);
> > +       if (ret < 0) {
> > +               /* set channel ready if the data has transferred */
> > +               if (pmif_is_fsm_vldclr(arb))
> > +                       pmif_writel(arb, 1, inf_reg->ch_rdy);
> > +               dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
> > +               goto out;
> > +       }
> > +
> > +       /* Send the command. */
> > +       cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr;
> > +       pmif_writel(arb, cmd, inf_reg->ch_send);
> > +
> > +       /*
> > +        * Wait for Software Interface FSM state to be WFVLDCLR,
> > +        * read the data and clear the valid flag.
> > +        */
> > +       ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
> > +                                       data, GET_SWINF(data) == SWINF_WFVLDCLR,
> > +                                       PMIF_DELAY_US, PMIF_TIMEOUT_US);
> > +       if (ret < 0) {
> > +               dev_err(&ctrl->dev, "failed to wait for SWINF_WFVLDCLR\n");
> > +               goto out;
> > +       }
> > +
> > +       data = pmif_readl(arb, inf_reg->rdata);
> > +       memcpy(buf, &data, len);
> > +       pmif_writel(arb, 1, inf_reg->ch_rdy);
> > +
> > +out:
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       return 0;
> > +}
> > +
> > +static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
> > +                              u16 addr, const u8 *buf, size_t len)
> > +{
> > +       struct pmif *arb = spmi_controller_get_drvdata(ctrl);
> > +       struct ch_reg *inf_reg;
> > +       int ret;
> > +       u32 data, cmd;
> > +
> > +       if (len > 4) {
> > +               dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
> 
> Missing newline
> 

Thanks, I will update it in the next patch.

> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Check the opcode */
> > +       if (opc >= 0x40 && opc <= 0x5F)
> > +               opc = PMIF_CMD_REG;
> > +       else if ((opc <= 0xF) || (opc >= 0x30 && opc <= 0x37))
> > +               opc = PMIF_CMD_EXT_REG_LONG;
> > +       else if (opc >= 0x80)
> > +               opc = PMIF_CMD_REG_0;
> > +       else
> > +               return -EINVAL;
> > +
> > +       /* Wait for Software Interface FSM state to be IDLE. */
> > +       inf_reg = &arb->chan;
> > +       ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
> > +                                       data, GET_SWINF(data) == SWINF_IDLE,
> > +                                       PMIF_DELAY_US, PMIF_TIMEOUT_US);
> > +       if (ret < 0) {
> > +               /* set channel ready if the data has transferred */
> > +               if (pmif_is_fsm_vldclr(arb))
> > +                       pmif_writel(arb, 1, inf_reg->ch_rdy);
> > +               dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
> > +               goto out;
> > +       }
> > +
> > +       /* Set the write data. */
> > +       memcpy(&data, buf, len);
> > +       pmif_writel(arb, data, inf_reg->wdata);
> > +
> > +       /* Send the command. */
> > +       cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr;
> > +       pmif_writel(arb, cmd, inf_reg->ch_send);
> > +
> > +out:
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       return 0;
> 
> Simplify to 
> 
> 	out:
> 		return ret;
> 

Thanks, I will update it in the next patch.

> > +}
> > +
> > +static const struct pmif_data mt6873_pmif_arb = {
> > +       .regs = mt6873_regs,
> > +       .spmimst_regs = mt6873_spmi_regs,
> > +       .soc_chan = 2,
> > +};
> > +
> > +static int mtk_spmi_probe(struct platform_device *pdev)
> > +{
> > +       struct pmif *arb;
> > +       struct spmi_controller *ctrl;
> > +       int err, i;
> > +       u32 chan_offset;
> > +
> > +       ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*arb));
> > +       if (!ctrl)
> > +               return -ENOMEM;
> > +
> > +       arb = spmi_controller_get_drvdata(ctrl);
> > +       arb->data = of_device_get_match_data(&pdev->dev);
> 
> Use device_get_match_data() instead please.
> 

Thanks, I will change to use device_get_match_data in the next patch.

> > +       if (!arb->data) {
> > +               err = -EINVAL;
> > +               dev_err(&pdev->dev, "Cannot get drv_data\n");
> > +               goto err_put_ctrl;
> > +       }
> > +
> > +       arb->base = devm_platform_ioremap_resource_byname(pdev, "pmif");
> > +       if (IS_ERR(arb->base)) {
> > +               err = PTR_ERR(arb->base);
> > +               dev_err(&pdev->dev, "pmif failed to get the remappped memory\n");
> 
> Please drop print as the API already prints errors for every problem.
> 

Thanks, I will update it in the next patch.

> > +               goto err_put_ctrl;
> > +       }
> > +
> > +       arb->spmimst_base = devm_platform_ioremap_resource_byname(pdev, "spmimst");
> > +       if (IS_ERR(arb->spmimst_base)) {
> > +               err = PTR_ERR(arb->spmimst_base);
> > +               dev_err(&pdev->dev, "spmimst failed to get the remappped memory\n");
> 
> Please drop print as the API already prints errors for every problem.
> 

Thanks, I will update it in the next patch.

> > +               goto err_put_ctrl;
> > +       }
> > +
> > +       arb->nclks = ARRAY_SIZE(pmif_clock_names);
> > +       if (arb->nclks > PMIF_MAX_CLKS) {
> > +               err = -EINVAL;
> > +               dev_err(&pdev->dev, "exceed the max clock numbers\n");
> 
> Do we really care? The dt schema should be checking this instead of the
> driver.
> 

Thanks, I will remove the check in the next patch.

> > +               goto err_put_ctrl;
> > +       }
> > +
> > +       for (i = 0; i < arb->nclks; i++)
> > +               arb->clks[i].id = pmif_clock_names[i];
> > +


From rppt at kernel.org  Mon Aug 16 05:26:22 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 16 Aug 2021 15:26:22 +0300
Subject: [PATCH v5] memblock: make memblock_find_in_range method private
Message-ID: <20210816122622.30279-1-rppt@kernel.org>

From: Mike Rapoport <rppt at linux.ibm.com>

There are a lot of uses of memblock_find_in_range() along with
memblock_reserve() from the times memblock allocation APIs did not exist.

memblock_find_in_range() is the very core of memblock allocations, so any
future changes to its internal behaviour would mandate updates of all the
users outside memblock.

Replace the calls to memblock_find_in_range() with an equivalent calls to
memblock_phys_alloc() and memblock_phys_alloc_range() and make
memblock_find_in_range() private method of memblock.

This simplifies the callers, ensures that (unlikely) errors in
memblock_reserve() are handled and improves maintainability of
memblock_find_in_range().

Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
Acked-by: Kirill A. Shutemov <kirill.shtuemov at linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>	# ACPI
Acked-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Acked-by: Nick Kossifidis <mick at ics.forth.gr>			# riscv
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>		# arm64
---
v5:
* restore the original behaviour on x86 with addition of more elaborate
  comment; I will address the issue in memory_map_top_down() in a separate
  series.

v4: https://lore.kernel.org/lkml/20210812065907.20046-1-rppt at kernel.org
* Add patch that prevents the crashes reported by Guenter Roeck on x86/i386
  on QEMU with 256M or 512M of memory and EFI boot enabled.
* Add Acked-by and Reviewed-by, thanks everybidy!

v3: https://lore.kernel.org/lkml/20210803064218.6611-1-rppt at kernel.org
* simplify check for exact crash kerenl allocation on arm, per Rob
* make crash_max unsigned long long on arm64, per Rob

v2: https://lore.kernel.org/lkml/20210802063737.22733-1-rppt at kernel.org
* don't change error message in arm::reserve_crashkernel(), per Russell

v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org


 arch/arm/kernel/setup.c           | 20 +++++---------
 arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
 arch/arm64/mm/init.c              | 36 ++++++++-----------------
 arch/mips/kernel/setup.c          | 14 +++++-----
 arch/riscv/mm/init.c              | 44 ++++++++++---------------------
 arch/s390/kernel/setup.c          | 10 ++++---
 arch/x86/kernel/aperture_64.c     |  5 ++--
 arch/x86/mm/init.c                | 23 ++++++++++------
 arch/x86/mm/numa.c                |  5 ++--
 arch/x86/mm/numa_emulation.c      |  5 ++--
 arch/x86/realmode/init.c          |  2 +-
 drivers/acpi/tables.c             |  5 ++--
 drivers/base/arch_numa.c          |  5 +---
 drivers/of/of_reserved_mem.c      | 12 ++++++---
 include/linux/memblock.h          |  2 --
 mm/memblock.c                     |  2 +-
 16 files changed, 81 insertions(+), 118 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index f97eb2371672..284a80c0b6e1 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
 		unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
 		if (crash_max > lowmem_max)
 			crash_max = lowmem_max;
-		crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
-						    crash_size, CRASH_ALIGN);
+
+		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+						       CRASH_ALIGN, crash_max);
 		if (!crash_base) {
 			pr_err("crashkernel reservation failed - No suitable area found.\n");
 			return;
 		}
 	} else {
+		unsigned long long crash_max = crash_base + crash_size;
 		unsigned long long start;
 
-		start = memblock_find_in_range(crash_base,
-					       crash_base + crash_size,
-					       crash_size, SECTION_SIZE);
-		if (start != crash_base) {
+		start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
+						  crash_base, crash_max);
+		if (!start) {
 			pr_err("crashkernel reservation failed - memory is in use.\n");
 			return;
 		}
 	}
 
-	ret = memblock_reserve(crash_base, crash_size);
-	if (ret < 0) {
-		pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
-			(unsigned long)crash_base);
-		return;
-	}
-
 	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
 		(unsigned long)(crash_size >> 20),
 		(unsigned long)(crash_base >> 20),
diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c
index d654921dd09b..578670e3f608 100644
--- a/arch/arm64/kvm/hyp/reserved_mem.c
+++ b/arch/arm64/kvm/hyp/reserved_mem.c
@@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
 	 * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
 	 */
 	hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
-	hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
-					      ALIGN(hyp_mem_size, PMD_SIZE),
-					      PMD_SIZE);
+	hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
+					   PMD_SIZE);
 	if (!hyp_mem_base)
-		hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
-						      hyp_mem_size, PAGE_SIZE);
+		hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
 	else
 		hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
 
@@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
 		kvm_err("Failed to reserve hyp memory\n");
 		return;
 	}
-	memblock_reserve(hyp_mem_base, hyp_mem_size);
 
 	kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
 		 hyp_mem_base);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2917ff..0bffd2d1854f 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
 	unsigned long long crash_base, crash_size;
+	unsigned long long crash_max = arm64_dma_phys_limit;
 	int ret;
 
 	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
@@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
 
 	crash_size = PAGE_ALIGN(crash_size);
 
-	if (crash_base == 0) {
-		/* Current arm64 boot protocol requires 2MB alignment */
-		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
-				crash_size, SZ_2M);
-		if (crash_base == 0) {
-			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
-				crash_size);
-			return;
-		}
-	} else {
-		/* User specifies base address explicitly. */
-		if (!memblock_is_region_memory(crash_base, crash_size)) {
-			pr_warn("cannot reserve crashkernel: region is not memory\n");
-			return;
-		}
+	/* User specifies base address explicitly. */
+	if (crash_base)
+		crash_max = crash_base + crash_size;
 
-		if (memblock_is_region_reserved(crash_base, crash_size)) {
-			pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
-			return;
-		}
-
-		if (!IS_ALIGNED(crash_base, SZ_2M)) {
-			pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
-			return;
-		}
+	/* Current arm64 boot protocol requires 2MB alignment */
+	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
+					       crash_base, crash_max);
+	if (!crash_base) {
+		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
+			crash_size);
+		return;
 	}
-	memblock_reserve(crash_base, crash_size);
 
 	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 23a140327a0b..f979adfd4fc2 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -452,8 +452,9 @@ static void __init mips_parse_crashkernel(void)
 		return;
 
 	if (crash_base <= 0) {
-		crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX,
-							crash_size, CRASH_ALIGN);
+		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
+						       CRASH_ALIGN,
+						       CRASH_ADDR_MAX);
 		if (!crash_base) {
 			pr_warn("crashkernel reservation failed - No suitable area found.\n");
 			return;
@@ -461,8 +462,9 @@ static void __init mips_parse_crashkernel(void)
 	} else {
 		unsigned long long start;
 
-		start = memblock_find_in_range(crash_base, crash_base + crash_size,
-						crash_size, 1);
+		start = memblock_phys_alloc_range(crash_size, 1,
+						  crash_base,
+						  crash_base + crash_size);
 		if (start != crash_base) {
 			pr_warn("Invalid memory region reserved for crash kernel\n");
 			return;
@@ -656,10 +658,6 @@ static void __init arch_mem_init(char **cmdline_p)
 	mips_reserve_vmcore();
 
 	mips_parse_crashkernel();
-#ifdef CONFIG_KEXEC
-	if (crashk_res.start != crashk_res.end)
-		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
-#endif
 	device_tree_init();
 
 	/*
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index a14bf3910eec..88649337c568 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -812,38 +812,22 @@ static void __init reserve_crashkernel(void)
 
 	crash_size = PAGE_ALIGN(crash_size);
 
-	if (crash_base == 0) {
-		/*
-		 * Current riscv boot protocol requires 2MB alignment for
-		 * RV64 and 4MB alignment for RV32 (hugepage size)
-		 */
-		crash_base = memblock_find_in_range(search_start, search_end,
-						    crash_size, PMD_SIZE);
-
-		if (crash_base == 0) {
-			pr_warn("crashkernel: couldn't allocate %lldKB\n",
-				crash_size >> 10);
-			return;
-		}
-	} else {
-		/* User specifies base address explicitly. */
-		if (!memblock_is_region_memory(crash_base, crash_size)) {
-			pr_warn("crashkernel: requested region is not memory\n");
-			return;
-		}
-
-		if (memblock_is_region_reserved(crash_base, crash_size)) {
-			pr_warn("crashkernel: requested region is reserved\n");
-			return;
-		}
-
+	if (crash_base) {
+		search_start = crash_base;
+		search_end = crash_base + crash_size;
+	}
 
-		if (!IS_ALIGNED(crash_base, PMD_SIZE)) {
-			pr_warn("crashkernel: requested region is misaligned\n");
-			return;
-		}
+	/*
+	 * Current riscv boot protocol requires 2MB alignment for
+	 * RV64 and 4MB alignment for RV32 (hugepage size)
+	 */
+	crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
+					       search_start, search_end);
+	if (crash_base == 0) {
+		pr_warn("crashkernel: couldn't allocate %lldKB\n",
+			crash_size >> 10);
+		return;
 	}
-	memblock_reserve(crash_base, crash_size);
 
 	pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index ff0f9e838916..3d9efee0f43c 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -626,8 +626,9 @@ static void __init reserve_crashkernel(void)
 			return;
 		}
 		low = crash_base ?: low;
-		crash_base = memblock_find_in_range(low, high, crash_size,
-						    KEXEC_CRASH_MEM_ALIGN);
+		crash_base = memblock_phys_alloc_range(crash_size,
+						       KEXEC_CRASH_MEM_ALIGN,
+						       low, high);
 	}
 
 	if (!crash_base) {
@@ -636,14 +637,15 @@ static void __init reserve_crashkernel(void)
 		return;
 	}
 
-	if (register_memory_notifier(&kdump_mem_nb))
+	if (register_memory_notifier(&kdump_mem_nb)) {
+		memblock_free(crash_base, crash_size);
 		return;
+	}
 
 	if (!OLDMEM_BASE && MACHINE_IS_VM)
 		diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
 	crashk_res.start = crash_base;
 	crashk_res.end = crash_base + crash_size - 1;
-	memblock_remove(crash_base, crash_size);
 	pr_info("Reserving %lluMB of memory at %lluMB "
 		"for crashkernel (System RAM: %luMB)\n",
 		crash_size >> 20, crash_base >> 20,
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 294ed4392a0e..10562885f5fc 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -109,14 +109,13 @@ static u32 __init allocate_aperture(void)
 	 * memory. Unfortunately we cannot move it up because that would
 	 * make the IOMMU useless.
 	 */
-	addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR,
-				      aper_size, aper_size);
+	addr = memblock_phys_alloc_range(aper_size, aper_size,
+					 GART_MIN_ADDR, GART_MAX_ADDR);
 	if (!addr) {
 		pr_err("Cannot allocate aperture memory hole [mem %#010lx-%#010lx] (%uKB)\n",
 		       addr, addr + aper_size - 1, aper_size >> 10);
 		return 0;
 	}
-	memblock_reserve(addr, aper_size);
 	pr_info("Mapping aperture over RAM [mem %#010lx-%#010lx] (%uKB)\n",
 		addr, addr + aper_size - 1, aper_size >> 10);
 	register_nosave_region(addr >> PAGE_SHIFT,
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 75ef19aa8903..23a14d82e783 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -127,14 +127,12 @@ __ref void *alloc_low_pages(unsigned int num)
 		unsigned long ret = 0;
 
 		if (min_pfn_mapped < max_pfn_mapped) {
-			ret = memblock_find_in_range(
+			ret = memblock_phys_alloc_range(
+					PAGE_SIZE * num, PAGE_SIZE,
 					min_pfn_mapped << PAGE_SHIFT,
-					max_pfn_mapped << PAGE_SHIFT,
-					PAGE_SIZE * num , PAGE_SIZE);
+					max_pfn_mapped << PAGE_SHIFT);
 		}
-		if (ret)
-			memblock_reserve(ret, PAGE_SIZE * num);
-		else if (can_use_brk_pgt)
+		if (!ret && can_use_brk_pgt)
 			ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE));
 
 		if (!ret)
@@ -610,8 +608,17 @@ static void __init memory_map_top_down(unsigned long map_start,
 	unsigned long addr;
 	unsigned long mapped_ram_size = 0;
 
-	/* xen has big range in reserved near end of ram, skip it at first.*/
-	addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE);
+	/*
+	 * Systems that have many reserved areas near top of the memory,
+	 * e.g. QEMU with less than 1G RAM and EFI enabled, or Xen, will
+	 * require lots of 4K mappings which may exhaust pgt_buf.
+	 * Start with top-most PMD_SIZE range aligned at PMD_SIZE to ensure
+	 * there is enough mapped memory that can be allocated from
+	 * memblock.
+	 */
+	addr = memblock_phys_alloc_range(PMD_SIZE, PMD_SIZE, map_start,
+					 map_end);
+	memblock_free(addr, PMD_SIZE);
 	real_end = addr + PMD_SIZE;
 
 	/* step_size need to be small so pgt_buf from BRK could cover it */
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index e94da744386f..a1b5c71099e6 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -376,15 +376,14 @@ static int __init numa_alloc_distance(void)
 	cnt++;
 	size = cnt * cnt * sizeof(numa_distance[0]);
 
-	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
-				      size, PAGE_SIZE);
+	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0,
+					 PFN_PHYS(max_pfn_mapped));
 	if (!phys) {
 		pr_warn("Warning: can't allocate distance table!\n");
 		/* don't retry until explicitly reset */
 		numa_distance = (void *)1LU;
 		return -ENOMEM;
 	}
-	memblock_reserve(phys, size);
 
 	numa_distance = __va(phys);
 	numa_distance_cnt = cnt;
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
index 87d77cc52f86..737491b13728 100644
--- a/arch/x86/mm/numa_emulation.c
+++ b/arch/x86/mm/numa_emulation.c
@@ -447,13 +447,12 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
 	if (numa_dist_cnt) {
 		u64 phys;
 
-		phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
-					      phys_size, PAGE_SIZE);
+		phys = memblock_phys_alloc_range(phys_size, PAGE_SIZE, 0,
+						 PFN_PHYS(max_pfn_mapped));
 		if (!phys) {
 			pr_warn("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
 			goto no_emu;
 		}
-		memblock_reserve(phys, phys_size);
 		phys_dist = __va(phys);
 
 		for (i = 0; i < numa_dist_cnt; i++)
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 6534c92d0f83..31b5856010cb 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -28,7 +28,7 @@ void __init reserve_real_mode(void)
 	WARN_ON(slab_is_available());
 
 	/* Has to be under 1M so we can execute real-mode AP code. */
-	mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
+	mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
 	if (!mem)
 		pr_info("No sub-1M memory is available for the trampoline\n");
 	else
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index a37a1532a575..f9383736fa0f 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -583,8 +583,8 @@ void __init acpi_table_upgrade(void)
 	}
 
 	acpi_tables_addr =
-		memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
-				       all_tables_size, PAGE_SIZE);
+		memblock_phys_alloc_range(all_tables_size, PAGE_SIZE,
+					  0, ACPI_TABLE_UPGRADE_MAX_PHYS);
 	if (!acpi_tables_addr) {
 		WARN_ON(1);
 		return;
@@ -599,7 +599,6 @@ void __init acpi_table_upgrade(void)
 	 * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
 	 * works fine.
 	 */
-	memblock_reserve(acpi_tables_addr, all_tables_size);
 	arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
 
 	/*
diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index 4cc4e117727d..46c503486e96 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -279,13 +279,10 @@ static int __init numa_alloc_distance(void)
 	int i, j;
 
 	size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
-	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
-				      size, PAGE_SIZE);
+	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, PFN_PHYS(max_pfn));
 	if (WARN_ON(!phys))
 		return -ENOMEM;
 
-	memblock_reserve(phys, size);
-
 	numa_distance = __va(phys);
 	numa_distance_cnt = nr_node_ids;
 
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index fd3964d24224..59c1390cdf42 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -33,18 +33,22 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
 	phys_addr_t *res_base)
 {
 	phys_addr_t base;
+	int err = 0;
 
 	end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
 	align = !align ? SMP_CACHE_BYTES : align;
-	base = memblock_find_in_range(start, end, size, align);
+	base = memblock_phys_alloc_range(size, align, start, end);
 	if (!base)
 		return -ENOMEM;
 
 	*res_base = base;
-	if (nomap)
-		return memblock_mark_nomap(base, size);
+	if (nomap) {
+		err = memblock_mark_nomap(base, size);
+		if (err)
+			memblock_free(base, size);
+	}
 
-	return memblock_reserve(base, size);
+	return err;
 }
 
 /*
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 4a53c3ca86bd..b066024c62e3 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -99,8 +99,6 @@ void memblock_discard(void);
 static inline void memblock_discard(void) {}
 #endif
 
-phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
-				   phys_addr_t size, phys_addr_t align);
 void memblock_allow_resize(void);
 int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
 int memblock_add(phys_addr_t base, phys_addr_t size);
diff --git a/mm/memblock.c b/mm/memblock.c
index de7b553baa50..28a813d9e955 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -315,7 +315,7 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
  * Return:
  * Found address on success, 0 on failure.
  */
-phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
+static phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
 					phys_addr_t end, phys_addr_t size,
 					phys_addr_t align)
 {

base-commit: ff1176468d368232b684f75e82563369208bc371
-- 
2.28.0



From lee.jones at linaro.org  Mon Aug 16 05:39:10 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 16 Aug 2021 13:39:10 +0100
Subject: [PATCH v8 01/11] dt-bindings: mfd: axp20x: Add AXP305 compatible
 (plus optional IRQ)
In-Reply-To: <20210723153838.6785-2-andre.przywara@arm.com>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210723153838.6785-2-andre.przywara@arm.com>
Message-ID: <YRpcboGSk+WyLLy8@google.com>

On Fri, 23 Jul 2021, Andre Przywara wrote:

> The AXP305 PMIC used on many boards with the H616 SoC seems to be fully
> compatible to the AXP805 PMIC, so add the proper chain of compatible
> strings.
> 
> Also at least on one board (Orangepi Zero2) there is no interrupt line
> connected to the CPU, so make the "interrupts" property optional.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/mfd/axp20x.txt | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Applied, thanks.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Mon Aug 16 05:47:16 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 16 Aug 2021 13:47:16 +0100
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build
 as a module
In-Reply-To: <YQuZ2cKVE+3Os25Z@google.com>
References: <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <YQuZ2cKVE+3Os25Z@google.com>
Message-ID: <YRpeVLf18Z+1R7WE@google.com>

On Thu, 05 Aug 2021, Lee Jones wrote:

> On Wed, 04 Aug 2021, Saravana Kannan wrote:
> 
> > On Wed, Aug 4, 2021 at 11:20 AM Saravana Kannan <saravanak at google.com> wrote:
> > >
> > > On Wed, Aug 4, 2021 at 1:50 AM Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > On Wed, 04 Aug 2021 02:36:45 +0100,
> > > > Saravana Kannan <saravanak at google.com> wrote:
> > > >
> > > > Hi Saravana,
> > > >
> > > > Thanks for looking into this.
> > >
> > > You are welcome. I just don't want people to think fw_devlink is broken :)
> > >
> > > >
> > > > [...]
> > > >
> > > > > > Saravana, could you please have a look from a fw_devlink perspective?
> > > > >
> > > > > Sigh... I spent several hours looking at this and wrote up an analysis
> > > > > and then realized I might be looking at the wrong DT files.
> > > > >
> > > > > Marc, can you point me to the board file in upstream that corresponds
> > > > > to the platform in which you see this issue? I'm not asking for [1],
> > > > > but the actual final .dts (not .dtsi) file that corresponds to the
> > > > > platform/board/system.
> > > >
> > > > The platform I can reproduce this on is described in
> > > > arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts. It is an
> > > > intricate maze of inclusion, node merge and other DT subtleties. I
> > > > suggest you look at the decompiled version to get a view of the
> > > > result.
> > >
> > > Thanks. After decompiling it, it looks something like (stripped a
> > > bunch of reg and address properties and added the labels back):
> > >
> > > eth_phy: mdio-multiplexer at 4c000 {
> > >         compatible = "amlogic,g12a-mdio-mux";
> > >         clocks = <0x02 0x13 0x1e 0x02 0xb1>;
> > >         clock-names = "pclk\0clkin0\0clkin1";
> > >         mdio-parent-bus = <0x22>;
> > >
> > >         ext_mdio: mdio at 0 {
> > >                 reg = <0x00>;
> > >
> > >                 ethernet-phy at 0 {
> > >                         max-speed = <0x3e8>;
> > >                         interrupt-parent = <0x23>;
> > >                         interrupts = <0x1a 0x08>;
> > >                         phandle = <0x16>;
> > >                 };
> > >         };
> > >
> > >         int_mdio: mdio at 1 {
> > >                 ...
> > >         }
> > > }
> > >
> > > And phandle 0x23 refers to the gpio_intc interrupt controller with the
> > > modular driver.
> > >
> > > > > Based on your error messages, it's failing for mdio at 0 which
> > > > > corresponds to ext_mdio. But none of the board dts files in upstream
> > > > > have a compatible property for "ext_mdio". Which means fw_devlink
> > > > > _should_ propagate the gpio_intc IRQ dependency all the way up to
> > > > > eth_phy.
> > > > >
> > > > > Also, in the failing case, can you run:
> > > > > ls -ld supplier:*
> > > > >
> > > > > in the /sys/devices/....<something>/ folder that corresponds to the
> > > > > "eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?
> > > >
> > > > Here you go:
> > > >
> > > > root at tiger-roach:~# find /sys/devices/ -name 'supplier*'|grep -i mdio | xargs ls -ld
> > > > lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/platform/soc/ff600000.bus/ff64c000.mdio-multiplexer/supplier:platform:ff63c000.system-controller:clock-controller -> ../../../../virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer
> > >
> > > As we discussed over chat, this was taken after the mdio-multiplexer
> > > driver "successfully" probes this device. This will cause
> > > SYNC_STATE_ONLY device links created by fw_devlink to be deleted
> > > (because they are useless after a device probes). So, this doesn't
> > > show the info I was hoping to demonstrate.
> > >
> > > In any case, one can see that fw_devlink properly created the device
> > > link for the clocks dependency. So fw_devlink is parsing this node
> > > properly. But it doesn't create a similar probe order enforcing device
> > > link between the mdio-multiplexer and the gpio_intc because the
> > > dependency is only present in a grand child DT node (ethernet-phy at 0
> > > under ext_mdio). So fw_devlink is working as intended.
> > >
> > > I spent several hours squinting at the code/DT yesterday. Here's what
> > > is going on and causing the problem:
> > >
> > > The failing driver in this case is
> > > drivers/net/mdio/mdio-mux-meson-g12a.c. And the only DT node it's
> > > handling is what I pasted above in this email. In the failure case,
> > > the call flow is something like this:
> > >
> > > g12a_mdio_mux_probe()
> > > -> mdio_mux_init()
> > > -> of_mdiobus_register(ext_mdio DT node)
> > > -> of_mdiobus_register_phy(ext_mdio DT node)
> > > -> several calls deep fwnode_mdiobus_phy_device_register(ethernet_phy DT node)
> > > -> Tried to get the IRQ listed in ethernet_phy and fails with
> > > -EPROBE_DEFER because the IRQ driver isn't loaded yet.
> > >
> > > The error is propagated correctly all the way up to of_mdiobus_register(), but
> > > mdio_mux_init() ignores the -EPROBE_DEFER from of_mdiobus_register() and just
> > > continues on with the rest of the stuff and returns success as long as
> > > one of the child nodes (in this case int_mdio) succeeds.
> > >
> > > Since the probe returns 0 without really succeeding, networking stuff
> > > just fails badly after this. So, IMO, the real problem is with
> > > mdio_mux_init() not propagating up the -EPROBE_DEFER. I gave Marc a
> > > quick hack (pasted at the end of this email) to test my theory and he
> > > confirmed that it fixes the issue (a few deferred probes later, things
> > > work properly).
> > >
> > > Andrew, I don't see any good reason for mdio_mux_init() not
> > > propagating the errors up correctly (at least for EPROBE_DEFER). I'll
> > > send a patch to fix this. Please let me know if there's a reason it
> > > has to stay as-is.
> > 
> > I sent out the proper fix as a series:
> > https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
> > 
> > Marc, can you give it a shot please?
> > 
> > -Saravana
> 
> Superstar!  Thanks for taking the time to rectify this for all of us.

Just to clarify:

  Are we waiting on a subsequent patch submission at this point?

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From patchwork-bot+netdevbpf at kernel.org  Mon Aug 16 05:50:06 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Mon, 16 Aug 2021 12:50:06 +0000
Subject: [PATCH net-next v1 0/3] net: stmmac: Add ethtool per-queue
 statistic
In-Reply-To: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
References: <cover.1629092894.git.vijayakannan.ayyathurai@intel.com>
Message-ID: <162911820628.2793.5855796807565496042.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (refs/heads/master):

On Mon, 16 Aug 2021 14:15:57 +0800 you wrote:
> Adding generic ethtool per-queue statistic framework to display the
> statistics for each rx/tx queue. In future, users can avail it to add
> more per-queue specific counters. Number of rx/tx queues displayed is
> depending on the available rx/tx queues in that particular MAC config
> and this number is limited up to the MTL_MAX_{RX|TX}_QUEUES defined
> in the driver.
> 
> [...]

Here is the summary with links:
  - [net-next,v1,1/3] net: stmmac: fix INTR TBU status affecting irq count statistic
    https://git.kernel.org/netdev/net-next/c/1975df880b95
  - [net-next,v1,2/3] net: stmmac: add ethtool per-queue statistic framework
    https://git.kernel.org/netdev/net-next/c/68e9c5dee1cf
  - [net-next,v1,3/3] net: stmmac: add ethtool per-queue irq statistic support
    https://git.kernel.org/netdev/net-next/c/af9bf70154eb

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From broonie at kernel.org  Mon Aug 16 05:50:23 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 16 Aug 2021 13:50:23 +0100
Subject: [PATCH] arm64/sve: Add a comment documenting the binutils needed for
 SVE asm
Message-ID: <20210816125024.8112-1-broonie@kernel.org>

At some point it would be nice to avoid the need to manually encode SVE
instructions, add a note of the binutils version required to save looking
it up.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimdmacros.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index 059204477ce6..00a2c0b69c2b 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -94,6 +94,7 @@
 .endm
 
 /* SVE instruction encodings for non-SVE-capable assemblers */
+/* (pre binutils 2.28, all kernel capable clang versions support SVE) */
 
 /* STR (vector): STR Z\nz, [X\nxbase, #\offset, MUL VL] */
 .macro _sve_str_v nz, nxbase, offset=0
-- 
2.20.1



From zajec5 at gmail.com  Mon Aug 16 05:50:29 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 16 Aug 2021 14:50:29 +0200
Subject: [PATCH] PCI: brcmstb: implement BCM4908 support
Message-ID: <20210816125029.16879-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

BCM4908 is Broadcom's 64-bit platform with Broadcom's own Brahma-B53
CPU(s). It uses the same PCIe hardware block as STB (Set-Top-Box) family
but in a slightly different revision & setup.

Registers in BCM4908 variant are mostly the same but controller setup
differs a bit. It requires setting few extra registers and takes
slightly different bars setup.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 drivers/pci/controller/pcie-brcmstb.c | 137 +++++++++++++++++++++++---
 1 file changed, 123 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index cc30215f5a43..24bc7efcfdd5 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -51,15 +51,20 @@
 #define PCIE_RC_DL_MDIO_RD_DATA				0x1108
 
 #define PCIE_MISC_MISC_CTRL				0x4008
+#define  PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE		0x00000080
+#define  PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE		0x00000400
+#define  PCIE_MISC_MISC_CTRL_PCIE_IN_WR_COMBINE		0x00000800
 #define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK		0x1000
 #define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK	0x2000
 #define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK	0x300000
+#define  PCIE_MISC_MISC_CTRL_BURST_ALIGN_MASK		0x00080000
 
 #define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK		0xf8000000
 #define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK		0x07c00000
 #define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK		0x0000001f
 #define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
 
+
 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
 #define PCIE_MEM_WIN0_LO(win)	\
 		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
@@ -115,6 +120,9 @@
 #define PCIE_MEM_WIN0_LIMIT_HI(win)	\
 		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
 
+#define PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_OFFSET		0x40ac
+#define  PCIE_MISC_UBUS_BAR_CONFIG_ACCESS_EN		0x00000001
+
 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG					0x4204
 #define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
 #define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
@@ -131,6 +139,13 @@
 #define PCIE_EXT_CFG_DATA				0x8000
 #define PCIE_EXT_CFG_INDEX				0x9000
 
+#define PCIE_CPU_INTR1_INTR_MASK_CLEAR_OFFSET		0x940c
+#define  PCIE_CPU_INTR1_PCIE_INTA_CPU_INTR		0x00000002
+#define  PCIE_CPU_INTR1_PCIE_INTB_CPU_INTR		0x00000004
+#define  PCIE_CPU_INTR1_PCIE_INTC_CPU_INTR		0x00000008
+#define  PCIE_CPU_INTR1_PCIE_INTD_CPU_INTR		0x00000010
+#define  PCIE_CPU_INTR1_PCIE_INTR_CPU_INTR		0x00000020
+
 #define  PCIE_RGR1_SW_INIT_1_PERST_MASK			0x1
 #define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT		0x0
 
@@ -746,13 +761,19 @@ static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32
 
 static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
 {
-	if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
-		return;
+	if (pcie->hw_rev >= BRCM_PCIE_HW_REV_3_20) {
+		brcm_pcie_perst_set_7278(pcie, val);
+	} else {
+		if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
+			return;
 
-	if (val)
-		reset_control_assert(pcie->perst_reset);
-	else
-		reset_control_deassert(pcie->perst_reset);
+		if (val)
+			reset_control_assert(pcie->perst_reset);
+		else
+			reset_control_deassert(pcie->perst_reset);
+	}
+
+	usleep_range(10000, 20000);
 }
 
 static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
@@ -861,6 +882,86 @@ static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
 	return 0;
 }
 
+static int brcm_pcie_setup_bcm4908(struct brcm_pcie *pcie)
+{
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
+	void __iomem *base = pcie->base;
+	struct device *dev = pcie->dev;
+	struct resource_entry *entry;
+	u32 burst_align;
+	u32 burst;
+	u32 tmp;
+	int win;
+
+	pcie->perst_set(pcie, 0);
+
+	msleep(500);
+
+	if (!brcm_pcie_link_up(pcie)) {
+		dev_err(dev, "link down\n");
+		return -ENODEV;
+	}
+
+	/* setup lgacy outband interrupts */
+	tmp = PCIE_CPU_INTR1_PCIE_INTA_CPU_INTR |
+	      PCIE_CPU_INTR1_PCIE_INTB_CPU_INTR |
+	      PCIE_CPU_INTR1_PCIE_INTC_CPU_INTR |
+	      PCIE_CPU_INTR1_PCIE_INTD_CPU_INTR;
+	writel(tmp, base + PCIE_CPU_INTR1_INTR_MASK_CLEAR_OFFSET);
+
+	win = 0;
+	resource_list_for_each_entry(entry, &bridge->windows) {
+		struct resource *res = entry->res;
+		u64 pcie_addr;
+
+		if (resource_type(res) != IORESOURCE_MEM)
+			continue;
+
+		if (win >= BRCM_NUM_PCIE_OUT_WINS) {
+			dev_err(pcie->dev, "too many outbound wins\n");
+			return -EINVAL;
+		}
+
+		tmp = 0;
+		u32p_replace_bits(&tmp, res->start / SZ_1M,
+				  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK);
+		u32p_replace_bits(&tmp, res->end / SZ_1M,
+				  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK);
+		writel(tmp, base + PCIE_MEM_WIN0_BASE_LIMIT(win));
+
+		pcie_addr = res->start - entry->offset;
+		writel(lower_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_LO(win));
+		writel(upper_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_HI(win));
+
+		win++;
+	}
+
+	writel(0xf, base + PCIE_MISC_RC_BAR1_CONFIG_LO);
+
+	tmp = PCIE_MISC_UBUS_BAR_CONFIG_ACCESS_EN;
+	writel(tmp, base + PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_OFFSET);
+
+	tmp = readl(base + PCIE_RC_CFG_PRIV1_ID_VAL3);
+	u32p_replace_bits(&tmp, PCI_CLASS_BRIDGE_PCI << 8,
+			  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK);
+	writel(tmp, base + PCIE_RC_CFG_PRIV1_ID_VAL3);
+
+	/* Burst */
+	burst = 0x1; /* 128 B */
+	burst_align = 1;
+
+	tmp = readl(base + PCIE_MISC_MISC_CTRL);
+	u32p_replace_bits(&tmp, burst_align, PCIE_MISC_MISC_CTRL_BURST_ALIGN_MASK);
+	u32p_replace_bits(&tmp, burst, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK);
+	u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK);
+	u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_IN_WR_COMBINE);
+	u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE);
+	u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE);
+	writel(tmp, base + PCIE_MISC_MISC_CTRL);
+
+	return 0;
+}
+
 static int brcm_pcie_setup(struct brcm_pcie *pcie)
 {
 	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
@@ -1284,6 +1385,13 @@ static int brcm_pcie_probe(struct platform_device *pdev)
 		return PTR_ERR(pcie->perst_reset);
 	}
 
+	if (pcie->type == BCM4908) {
+		/* On BCM4908 we can read rev early and perst_set needs it */
+		pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION);
+
+		pcie->perst_set(pcie, 1);
+	}
+
 	ret = reset_control_reset(pcie->rescal);
 	if (ret)
 		dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
@@ -1295,16 +1403,17 @@ static int brcm_pcie_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = brcm_pcie_setup(pcie);
-	if (ret)
-		goto fail;
+	if (pcie->type == BCM4908) {
+		ret = brcm_pcie_setup_bcm4908(pcie);
+		if (ret)
+			goto fail;
+	} else {
+		ret = brcm_pcie_setup(pcie);
+		if (ret)
+			goto fail;
+	}
 
 	pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION);
-	if (pcie->type == BCM4908 && pcie->hw_rev >= BRCM_PCIE_HW_REV_3_20) {
-		dev_err(pcie->dev, "hardware revision with unsupported PERST# setup\n");
-		ret = -ENODEV;
-		goto fail;
-	}
 
 	msi_np = of_parse_phandle(pcie->np, "msi-parent", 0);
 	if (pci_msi_enabled() && msi_np == pcie->np) {
-- 
2.26.2



From haibo.chen at nxp.com  Mon Aug 16 05:38:24 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Mon, 16 Aug 2021 20:38:24 +0800
Subject: [PATCH 2/6] mmc: sdhci-eadhc-imx: select the correct mode for auto
 tuning
In-Reply-To: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629117508-4886-2-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

USDHC hardware auto tuning circuit support check 1/4/8 data lines
and cmd line. Out of reset uSDHC, it default select check 4 data
lines and do not check cmd line. This is incorrect if we use 8 data
lines. So need to config the auto tuning mode according to current
bus width.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 33 ++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index a49fac719fca..f18d169bc8ff 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -94,6 +94,11 @@
 
 #define ESDHC_VEND_SPEC2		0xc8
 #define ESDHC_VEND_SPEC2_EN_BUSY_IRQ	(1 << 8)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN	(1 << 4)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN	(0 << 4)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN	(2 << 4)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN	(1 << 6)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK	(7 << 4)
 
 #define ESDHC_TUNING_CTRL		0xcc
 #define ESDHC_STD_TUNING_EN		(1 << 24)
@@ -114,6 +119,7 @@
 #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
 #define ESDHC_CTRL_8BITBUS		(0x2 << 1)
 #define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
+#define USDHC_GET_BUSWIDTH(c) (c & ESDHC_CTRL_BUSWIDTH_MASK)
 
 /*
  * There is an INT DMA ERR mismatch between eSDHC and STD SDHC SPEC:
@@ -407,6 +413,30 @@ static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
 		dev_warn(mmc_dev(host->mmc), "%s: card clock still not gate off in 100us!.\n", __func__);
 }
 
+/* Enable the auto tuning circuit to check the CMD line and BUS line */
+static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
+{
+	u32 buswidth, auto_tune_buswidth;
+
+	buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL));
+
+	switch (buswidth) {
+	case ESDHC_CTRL_8BITBUS:
+		auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN;
+		break;
+	case ESDHC_CTRL_4BITBUS:
+		auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN;
+		break;
+	default:	/* 1BITBUS */
+		auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;
+		break;
+	}
+
+	esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
+			auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
+			ESDHC_VEND_SPEC2);
+}
+
 static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -643,6 +673,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 				v |= ESDHC_MIX_CTRL_EXE_TUNE;
 				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
 				m |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
+				usdhc_auto_tuning_mode_sel(host);
 			} else {
 				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
 			}
@@ -1012,6 +1043,8 @@ static void esdhc_post_tuning(struct sdhci_host *host)
 {
 	u32 reg;
 
+	usdhc_auto_tuning_mode_sel(host);
+
 	reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
 	reg &= ~ESDHC_MIX_CTRL_EXE_TUNE;
 	reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
-- 
2.17.1



From haibo.chen at nxp.com  Mon Aug 16 05:38:23 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Mon, 16 Aug 2021 20:38:23 +0800
Subject: [PATCH 1/6] mmc: sdhci-esdhc-imx: remove redundant code for manual
 tuning
Message-ID: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

For manual tuning method, already call esdhc_prepare_tuning()
config the necessary registers, so remove the redundant code
in esdhc_writew_le() for SDHCI_HOST_CONTROL2.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 57b19ca1ad6d..a49fac719fca 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -628,17 +628,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 		else
 			new_val &= ~ESDHC_VENDOR_SPEC_VSELECT;
 		writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
-		if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
-			new_val = readl(host->ioaddr + ESDHC_MIX_CTRL);
-			if (val & SDHCI_CTRL_TUNED_CLK) {
-				new_val |= ESDHC_MIX_CTRL_SMPCLK_SEL;
-				new_val |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
-			} else {
-				new_val &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
-				new_val &= ~ESDHC_MIX_CTRL_AUTO_TUNE_EN;
-			}
-			writel(new_val , host->ioaddr + ESDHC_MIX_CTRL);
-		} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
+		if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
 			u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
 			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
 			if (val & SDHCI_CTRL_TUNED_CLK) {
-- 
2.17.1



From haibo.chen at nxp.com  Mon Aug 16 05:38:25 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Mon, 16 Aug 2021 20:38:25 +0800
Subject: [PATCH 3/6] dt-bindings: mmc: fsl-imx-esdhc: add fsl,
 sdio-async-interrupt-enabled binding
In-Reply-To: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629117508-4886-3-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add a new fsl,sdio-async-interrupt-enabled binding for sdio devices
which enable the async interrupt function. When get this property,
driver will avoid to use DAT[1] for hardware auto tuning check.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml         | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
index b5baf439fbac..8a9f1775b0e2 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
@@ -122,6 +122,16 @@ properties:
       - const: state_200mhz
       - const: sleep
 
+  fsl,sdio-async-interrupt-enabled:
+    description: |
+      Recommend for SDIO cards that enables SDIO async interrupt for SDR104 and SDR50
+      operating modes. SDIO async interrupt uses DAT[1] to signal the card's interrupt.
+      uSDHC tuning mechanism must use DAT[0] and CMD signals to avoid a possible
+      conflict and incorrect delay line calculated by the uSDHC auto tuning mechanism.
+      Enabling this device tree property is only recommended for layouts that are
+      matching the SD interface length.
+    type: boolean
+
 required:
   - compatible
   - reg
-- 
2.17.1



From haibo.chen at nxp.com  Mon Aug 16 05:38:27 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Mon, 16 Aug 2021 20:38:27 +0800
Subject: [PATCH 5/6] arm64: dts: imx8mm-evk: add sdio wifi support
In-Reply-To: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629117508-4886-5-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add the sdio wifi support on imx8mm-evk board.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mm-evk.dts  | 20 ++++++++++
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 39 +++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
index 4e2820d19244..41f9453c5a3f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
@@ -15,6 +15,13 @@
 	aliases {
 		spi0 = &flexspi;
 	};
+
+	usdhc1_pwrseq: usdhc1_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usdhc1_gpio>;
+		reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+	};
 };
 
 &ddrc {
@@ -53,6 +60,19 @@
 	};
 };
 
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	bus-width = <4>;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&usdhc1_pwrseq>;
+	fsl,sdio-async-interrupt-enabled;
+	non-removable;
+	status = "okay";
+};
+
 &usdhc3 {
 	assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
 	assigned-clock-rates = <400000000>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index e033d0257b5a..ca623078d937 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -440,6 +440,45 @@
 		>;
 	};
 
+	pinctrl_usdhc1_gpio: usdhc1grpgpiogrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10	0x41
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x190
+			MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d0
+			MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d0
+			MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d0
+			MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d0
+			MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d0
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+		fsl,pins = <
+			MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x194
+			MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d4
+			MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d4
+			MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d4
+			MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d4
+			MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d4
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+		fsl,pins = <
+			MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x196
+			MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d6
+			MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d6
+			MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d6
+			MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d6
+			MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d6
+		>;
+	};
+
 	pinctrl_usdhc2_gpio: usdhc2grpgpiogrp {
 		fsl,pins = <
 			MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15	0x1c4
-- 
2.17.1



From haibo.chen at nxp.com  Mon Aug 16 05:38:28 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Mon, 16 Aug 2021 20:38:28 +0800
Subject: [PATCH 6/6] arm64: dts: imx8mn-evk: add sdio wifi support
In-Reply-To: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629117508-4886-6-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add sdio wifi support on imx8mn-evk board.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index 85e65f8719ea..00064f198423 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -28,6 +28,13 @@
 		reg = <0x0 0x40000000 0 0x80000000>;
 	};
 
+	usdhc1_pwrseq: usdhc1_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usdhc1_gpio>;
+		reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+	};
+
 	reg_usdhc2_vmmc: regulator-usdhc2 {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
@@ -205,6 +212,19 @@
 	};
 };
 
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	bus-width = <4>;
+	keep-power-in-suspend;
+	non-removable;
+	mmc-pwrseq = <&usdhc1_pwrseq>;
+	fsl,sdio-async-interrupt-enabled;
+	status = "okay";
+};
+
 &usdhc2 {
 	assigned-clocks = <&clk IMX8MN_CLK_USDHC2>;
 	assigned-clock-rates = <200000000>;
@@ -303,6 +323,45 @@
 		>;
 	};
 
+	pinctrl_usdhc1_gpio: usdhc1grpgpio {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD1_RESET_B_GPIO2_IO10	0x41
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK		0x190
+			MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d0
+			MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d0
+			MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d0
+			MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d0
+			MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d0
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK		0x194
+			MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d4
+			MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d4
+			MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d4
+			MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d4
+			MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d4
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK		0x196
+			MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d6
+			MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d6
+			MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d6
+			MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d6
+			MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d6
+		>;
+	};
+
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
 		fsl,pins = <
 			MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19	0x41
-- 
2.17.1



From haibo.chen at nxp.com  Mon Aug 16 05:38:26 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Mon, 16 Aug 2021 20:38:26 +0800
Subject: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the auto-tuning
 setting for sdio device
In-Reply-To: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629117508-4886-4-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

USDHC contain auto tuning circuit, this circuit will work automatically after
the tuning procedurae, it can increase/decrease the delay cell according to
the outside environment change (like temperature).

Unfortunately, this auto tuning circuit can not handle the async sdio device
interrupt correctly. When sdio device use 4 data line, async sdio interrupt
will use DAT[1], if we enable auto tuning circuit check 4 data lines, include
the DAT[1], this circuit will detect this interrupt, take this as a data on
DAT[1], and adjust the delay cell wrongly.

This is the hardware design limitation, to avoid this, when sdio device enable
async interrupt, auto tuning circuit only check DAT[0] and CMD lines.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index f18d169bc8ff..ab84c29777e5 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -226,6 +226,7 @@ struct esdhc_platform_data {
 	unsigned int tuning_step;       /* The delay cell steps in tuning procedure */
 	unsigned int tuning_start_tap;	/* The start delay cell point in tuning procedure */
 	unsigned int strobe_dll_delay_target;	/* The delay cell for strobe pad (read clock) */
+	bool sdio_async_interrupt_enabled;	/* sdio device enable the async interrupt */
 };
 
 struct esdhc_soc_data {
@@ -416,6 +417,8 @@ static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
 /* Enable the auto tuning circuit to check the CMD line and BUS line */
 static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
 {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
 	u32 buswidth, auto_tune_buswidth;
 
 	buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL));
@@ -432,6 +435,18 @@ static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
 		break;
 	}
 
+	/*
+	 * If sdio device use async interrupt, it will use DAT[1] to signal
+	 * the device's interrupt asynchronous when use 4 data lines.
+	 * Then hardware auto tuning circuit MUST NOT check the DAT[1] line,
+	 * otherwise auto tuning will be impacted by this async interrupt,
+	 * and change the delay cell incorrectly, which then cause data/cmd
+	 * errors.
+	 * This is the hardware auto tuning circuit limitation.
+	 */
+	if (imx_data->boarddata.sdio_async_interrupt_enabled)
+		auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;
+
 	esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
 			auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
 			ESDHC_VEND_SPEC2);
@@ -1531,6 +1546,9 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
 	if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line))
 		boarddata->delay_line = 0;
 
+	if (of_property_read_bool(np, "fsl,sdio-async-interrupt-enabled"))
+		boarddata->sdio_async_interrupt_enabled = true;
+
 	mmc_of_parse_voltage(host->mmc, &host->ocr_mask);
 
 	if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) {
-- 
2.17.1



From hector.yuan at mediatek.com  Mon Aug 16 05:56:34 2021
From: hector.yuan at mediatek.com (Hector Yuan)
Date: Mon, 16 Aug 2021 20:56:34 +0800
Subject: [PATCH v13 2/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW
In-Reply-To: <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7>
References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com>
 <1627574891-26514-3-git-send-email-hector.yuan@mediatek.com>
 <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7>
Message-ID: <1629118594.3246.13.camel@mtkswgap22>

On Tue, 2021-08-03 at 12:43 +0530, Viresh Kumar wrote:
> On 30-07-21, 00:08, Hector Yuan wrote:
> > From: "Hector.Yuan" <hector.yuan at mediatek.com>
> > 
> > Add cpufreq HW support
> 
> Please write a proper commit log, what you are adding and which SoCs
> it will apply to. Also add a full stop (.) at the end.
> 
OK, I will write down more details
> > Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
> > ---
> >  drivers/cpufreq/Kconfig.arm           |   12 ++
> >  drivers/cpufreq/Makefile              |    1 +
> >  drivers/cpufreq/mediatek-cpufreq-hw.c |  357 +++++++++++++++++++++++++++++++++
> >  include/linux/cpufreq.h               |   39 ++++
> 
> The changes to cpufreq.h should be done in a separate patch.
> 
OK, will separate .h to another patch
> > diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > new file mode 100644
> > index 0000000..ca50a3a
> > --- /dev/null
> > +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
> > @@ -0,0 +1,357 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2020 MediaTek Inc.
> > + */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/cpufreq.h>
> > +#include <linux/energy_model.h>
> > +#include <linux/init.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/pm_qos.h>
> > +#include <linux/slab.h>
> > +
> > +#define LUT_MAX_ENTRIES			32U
> > +#define LUT_FREQ			GENMASK(11, 0)
> > +#define LUT_ROW_SIZE			0x4
> > +#define CPUFREQ_HW_STATUS		BIT(0)
> > +#define SVS_HW_STATUS			BIT(1)
> > +#define POLL_USEC			1000
> > +#define TIMEOUT_USEC			300000
> > +
> > +enum {
> > +	REG_FREQ_LUT_TABLE,
> > +	REG_FREQ_ENABLE,
> > +	REG_FREQ_PERF_STATE,
> > +	REG_FREQ_HW_STATE,
> > +	REG_EM_POWER_TBL,
> > +	REG_FREQ_LATENCY,
> > +
> > +	REG_ARRAY_SIZE,
> > +};
> > +
> > +struct cpufreq_mtk {
> > +	struct cpufreq_frequency_table *table;
> > +	void __iomem *reg_bases[REG_ARRAY_SIZE];
> > +	int nr_opp;
> > +	cpumask_t related_cpus;
> > +};
> > +
> > +static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
> > +	[REG_FREQ_LUT_TABLE]	= 0x0,
> > +	[REG_FREQ_ENABLE]	= 0x84,
> > +	[REG_FREQ_PERF_STATE]	= 0x88,
> > +	[REG_FREQ_HW_STATE]	= 0x8c,
> > +	[REG_EM_POWER_TBL]	= 0x90,
> > +	[REG_FREQ_LATENCY]	= 0x110,
> > +};
> > +
> > +static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS];
> > +
> > +static int __maybe_unused
> > +mtk_cpufreq_get_cpu_power(unsigned long *mW,
> > +			  unsigned long *KHz, struct device *cpu_dev)
> > +{
> > +	struct cpufreq_mtk *c;
> > +	struct cpufreq_policy *policy;
> > +	int i;
> > +
> > +	policy = cpufreq_cpu_get_raw(cpu_dev->id);
> > +	if (!policy)
> > +		return 0;
> > +
> > +	c = mtk_freq_domain_map[policy->cpu];
> > +
> > +	for (i = 0; i < c->nr_opp; i++) {
> > +		if (c->table[i].frequency < *KHz)
> > +			break;
> > +	}
> > +	i--;
> > +
> > +	*KHz = c->table[i].frequency;
> > +	*mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] +
> > +			    i * LUT_ROW_SIZE) / 1000;
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
> > +				       unsigned int index)
> > +{
> > +	struct cpufreq_mtk *c = policy->driver_data;
> > +
> > +	writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
> > +
> > +	return 0;
> > +}
> > +
> > +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
> > +{
> > +	struct cpufreq_mtk *c;
> > +	struct cpufreq_policy *policy;
> > +	unsigned int index;
> > +
> > +	policy = cpufreq_cpu_get_raw(cpu);
> > +	if (!policy)
> > +		return 0;
> > +
> > +	c = mtk_freq_domain_map[policy->cpu];
> > +
> > +	index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]);
> > +	index = min(index, LUT_MAX_ENTRIES - 1);
> > +
> > +	return c->table[index].frequency;
> > +}
> > +
> > +static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
> > +					       unsigned int target_freq)
> > +{
> > +	struct cpufreq_mtk *c = policy->driver_data;
> > +	unsigned int index;
> > +
> > +	index = cpufreq_table_find_index_dl(policy, target_freq);
> > +
> > +	writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]);
> > +
> > +	return policy->freq_table[index].frequency;
> > +}
> > +
> > +static int mtk_cpu_create_freq_table(struct platform_device *pdev,
> > +				     struct cpufreq_mtk *c)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	void __iomem *base_table;
> > +	u32 data, i, freq, prev_freq = 0;
> > +
> > +	c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
> > +				sizeof(*c->table), GFP_KERNEL);
> > +	if (!c->table)
> > +		return -ENOMEM;
> > +
> > +	base_table = c->reg_bases[REG_FREQ_LUT_TABLE];
> > +
> > +	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
> > +		data = readl_relaxed(base_table + (i * LUT_ROW_SIZE));
> > +		freq = FIELD_GET(LUT_FREQ, data) * 1000;
> > +
> > +		if (freq == prev_freq)
> > +			break;
> > +
> > +		c->table[i].frequency = freq;
> > +
> > +		dev_dbg(dev, "index=%d freq=%d\n",
> > +			i, c->table[i].frequency);
> 
> Won't this fit in a single line ?
> 
OK, will modify to single line
> > +
> > +		prev_freq = freq;
> > +	}
> > +
> > +	c->table[i].frequency = CPUFREQ_TABLE_END;
> > +	c->nr_opp = i;
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_cpu_resources_init(struct platform_device *pdev,
> > +				  unsigned int cpu, int index,
> > +				  const u16 *offsets)
> > +{
> > +	struct cpufreq_mtk *c;
> > +	struct device *dev = &pdev->dev;
> > +	int ret, i;
> > +	void __iomem *base;
> > +
> > +	if (mtk_freq_domain_map[cpu])
> 
> This should not happen anymore, isn't it ?
> 
Will remove cpu map.
> > +		return 0;
> > +
> > +	c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
> > +	if (!c)
> > +		return -ENOMEM;
> > +
> > +	base = devm_platform_ioremap_resource(pdev, index);
> > +	if (IS_ERR(base))
> > +		return PTR_ERR(base);
> > +
> > +	for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
> > +		c->reg_bases[i] = base + offsets[i];
> > +
> > +	ret = of_perf_domain_get_sharing_cpumask(index, "performance-domains",
> 
> Instead of parsing parsing "performance-domains" twice, I would rather
> pass a CPU number here instead of index.
> 
Sorry, could you give me more details? For now, will use index to parse
per-cpu to related cpus.You mean pass policy->cpu or? Thanks.
> > +						 "#performance-domain-cells",
> > +						 &c->related_cpus);
> 
> You could have directly passed policy->cpus here instead.
> 
will replace it.
> > +	if (ret) {
> > +		dev_info(dev, "Domain-%d failed to get related CPUs\n", index);
> > +		return ret;
> > +	}
> > +
> > +	ret = mtk_cpu_create_freq_table(pdev, c);
> > +	if (ret) {
> > +		dev_info(dev, "Domain-%d failed to create freq table\n", index);
> > +		return ret;
> > +	}
> > +
> > +	mtk_freq_domain_map[cpu] = c;
> 
> I will rather use policy->driver_data to store this now.
> 
OK
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
> > +{
> > +	struct platform_device *pdev = cpufreq_get_driver_data();
> > +	struct cpufreq_mtk *c;
> > +	struct device *cpu_dev;
> > +	struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
> > +	struct pm_qos_request *qos_request;
> > +	struct device_node *cpu_np;
> > +	struct of_phandle_args args;
> > +	const u16 *offsets;
> > +	unsigned int latency;
> > +	int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;
> > +	int ret;
> 
> It looks much more organized when the variable definitions are in
> decreasing order of their length, instead of the random order as it is
> right now.
> 
OK, will sort it.
> > +
> > +	offsets = of_device_get_match_data(&pdev->dev);
> > +	if (!offsets)
> > +		return -EINVAL;
> > +
> > +	cpu_np = of_cpu_device_node_get(policy->cpu);
> > +	if (!cpu_np) {
> > +		dev_info(&pdev->dev, "Failed to get cpu %d device\n",
> > +			 policy->cpu);
> > +		return -ENODEV;
> > +	}
> > +
> > +	ret = of_parse_phandle_with_args(cpu_np, "performance-domains",
> > +					 "#performance-domain-cells", 0,
> > +					 &args);
> > +	if (ret < 0)
> 
> What about dropping cpu_np and same later in the code as well ?
> 
OK, Will add it.
> > +		return ret;
> > +
> > +	/* Get the bases of cpufreq for domains */
> > +	ret = mtk_cpu_resources_init(pdev, policy->cpu, args.args[0], offsets);
> > +	if (ret) {
> > +		dev_info(&pdev->dev, "CPUFreq resource init failed\n");
> > +		return ret;
> > +	}
> > +
> > +	cpu_dev = get_cpu_device(policy->cpu);
> > +	if (!cpu_dev) {
> > +		pr_err("failed to get cpu%d device\n", policy->cpu);
> > +		return -ENODEV;
> > +	}
> > +
> > +	c = mtk_freq_domain_map[policy->cpu];
> > +	if (!c) {
> > +		pr_err("No scaling support for CPU%d\n", policy->cpu);
> > +		return -ENODEV;
> > +	}
> > +
> > +	cpumask_copy(policy->cpus, &c->related_cpus);
> > +
> > +	policy->freq_table = c->table;
> > +	policy->driver_data = c;
> 
> Oh you already do this, you can remove mtk_freq_domain_map array now.
> 
OK, will remove map.
> > +
> > +	latency = readl_relaxed(c->reg_bases[REG_FREQ_LATENCY]);
> > +	if (!latency)
> > +		latency = CPUFREQ_ETERNAL;
> > +
> > +	/* us convert to ns */
> > +	policy->cpuinfo.transition_latency = latency * 1000;
> 
> You want to multiple CPUFREQ_ETERNAL too ?
> 
Yes, may be different power domain with different transition latency.
> > +
> > +	policy->fast_switch_possible = true;
> > +
> > +	qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL);
> 
> This is a small structure, why not allocate it on stack instead ?
> 
For qos part, we'd like to take more time to re-consider the SW flow and
put this to another patch set.Is this okay to you?
> > +	if (!qos_request)
> > +		return -ENOMEM;
> > +
> > +	/* Let CPUs leave idle-off state for SVS CPU initializing */
> > +	cpu_latency_qos_add_request(qos_request, 0);
> > +
> > +	/* HW should be in enabled state to proceed now */
> > +	writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]);
> > +
> > +	if (readl_poll_timeout(c->reg_bases[REG_FREQ_HW_STATE], sig,
> > +			       (sig & pwr_hw) == pwr_hw, POLL_USEC,
> > +			       TIMEOUT_USEC)) {
> > +		if (!(sig & CPUFREQ_HW_STATUS)) {
> > +			pr_info("cpufreq hardware of CPU%d is not enabled\n",
> > +				policy->cpu);
> > +			return -ENODEV;
> > +		}
> > +
> > +		pr_info("SVS of CPU%d is not enabled\n", policy->cpu);
> > +	}
> > +
> > +	cpu_latency_qos_remove_request(qos_request);
> > +
> > +	em_dev_register_perf_domain(cpu_dev, c->nr_opp, &em_cb, policy->cpus, true);
> > +
> > +	kfree(qos_request);
> 
> Why free after registering for em ? And also move the entire qos thing
> into a separate routine instead of adding it to ->init().
> 
If you agree, we'll consider to put it in another patch set.
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
> > +{
> > +	struct cpufreq_mtk *c;
> > +
> > +	c = mtk_freq_domain_map[policy->cpu];
> > +
> > +	/* HW should be in paused state now */
> > +	writel_relaxed(0x0, c->reg_bases[REG_FREQ_ENABLE]);
> 
> Please make sure each and every resource is freed here and in probe on
> failures.
> 
OK, will free all resources as probe.
> > +
> > +	return 0;
> > +}
> > +
> > +static struct cpufreq_driver cpufreq_mtk_hw_driver = {
> > +	.flags		= CPUFREQ_NEED_INITIAL_FREQ_CHECK |
> > +			  CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
> > +			  CPUFREQ_IS_COOLING_DEV,
> > +	.verify		= cpufreq_generic_frequency_table_verify,
> > +	.target_index	= mtk_cpufreq_hw_target_index,
> > +	.get		= mtk_cpufreq_hw_get,
> > +	.init		= mtk_cpufreq_hw_cpu_init,
> > +	.exit		= mtk_cpufreq_hw_cpu_exit,
> > +	.fast_switch	= mtk_cpufreq_hw_fast_switch,
> > +	.name		= "mtk-cpufreq-hw",
> > +	.attr		= cpufreq_generic_attr,
> > +};
> > +
> > +static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
> > +{
> > +	int ret;
> > +
> > +	cpufreq_mtk_hw_driver.driver_data = pdev;
> > +
> > +	ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> 
> You can do return ret here and drop the earlier return and its {}.
> 
okay.
> > +}
> > +
> > +static int mtk_cpufreq_hw_driver_remove(struct platform_device *pdev)
> > +{
> > +	return cpufreq_unregister_driver(&cpufreq_mtk_hw_driver);
> > +}
> > +
> > +static const struct of_device_id mtk_cpufreq_hw_match[] = {
> > +	{ .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_offsets },
> > +	{}
> > +};
> > +
> > +static struct platform_driver mtk_cpufreq_hw_driver = {
> > +	.probe = mtk_cpufreq_hw_driver_probe,
> > +	.remove = mtk_cpufreq_hw_driver_remove,
> > +	.driver = {
> > +		.name = "mtk-cpufreq-hw",
> > +		.of_match_table = mtk_cpufreq_hw_match,
> > +	},
> > +};
> > +module_platform_driver(mtk_cpufreq_hw_driver);
> > +
> > +MODULE_DESCRIPTION("Mediatek cpufreq-hw driver");
> > +MODULE_LICENSE("GPL v2");
> 
> You can add Module-author as well here if you want.
> 
OK.
> > diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> > index 9fd7194..4916d70 100644
> > --- a/include/linux/cpufreq.h
> > +++ b/include/linux/cpufreq.h
> > @@ -13,6 +13,8 @@
> >  #include <linux/completion.h>
> >  #include <linux/kobject.h>
> >  #include <linux/notifier.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/pm_qos.h>
> >  #include <linux/spinlock.h>
> >  #include <linux/sysfs.h>
> > @@ -1036,6 +1038,43 @@ void arch_set_freq_scale(const struct cpumask *cpus,
> >  }
> >  #endif
> >  
> > +#ifdef CONFIG_CPU_FREQ
> 
> There is another CONFIG_CPU_FREQ a few lines above, please use the
> same block for this routine as well.
> 
OK, will move it to the above.
> > +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name,
> > +						     const char *cell_name,
> > +						     struct cpumask *cpumask)
> > +{
> > +	struct device_node *cpu_np;
> > +	struct of_phandle_args args;
> > +	int cpu, ret;
> > +
> > +	for_each_possible_cpu(cpu) {
> > +		cpu_np = of_cpu_device_node_get(cpu);
> > +		if (!cpu_np)
> > +			continue;
> > +
> > +		ret = of_parse_phandle_with_args(cpu_np, list_name,
> > +						 cell_name, 0,
> > +						 &args);
> > +
> > +		of_node_put(cpu_np);
> > +		if (ret < 0)
> > +			continue;
> > +
> > +		if (index == args.args[0])
> > +			cpumask_set_cpu(cpu, cpumask);
> > +	}
> > +
> > +	return 0;
> > +}
> > +#else
> > +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name,
> > +						     const char *cell_name,
> > +						     struct cpumask *cpumask)
> > +{
> > +	return 0;
> 
> 	return -EOPNOTSUPP;
> 
> > +}
> > +#endif
> 


From lee.jones at linaro.org  Mon Aug 16 06:12:04 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 16 Aug 2021 14:12:04 +0100
Subject: [PATCH V3 RESEND] dt-bindings: mfd: add Broadcom CRU
In-Reply-To: <20210713094745.2586-1-zajec5@gmail.com>
References: <20210713094745.2586-1-zajec5@gmail.com>
Message-ID: <YRpkJOXa2sXJkAK2@google.com>

On Tue, 13 Jul 2021, Rafa? Mi?ecki wrote:

> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> CRU is a block used in e.g. Northstar devices. It can be seen in the
> bcm5301x.dtsi and this binding documents its proper usage.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---
> V2: Use complete binding & change additionalProperties to false
> V3: Use clock-controller@ for clocks
> RESEND: Patch is ready for pushing now since 5.14-rc1 is out
> 
> Lee: last time I sent this patch you couldn't push it because of docs
> validation dependency on 3 following commits:
> ac5f8197d15c ("dt-bindings: pinctrl: convert Broadcom Northstar to the json-schema")
> 08e9fdfbb224 ("dt-bindings: thermal: brcm,ns-thermal: Convert to the json-schema")
> 8f711f68cffd ("dt-bindings: clock: brcm, iproc-clocks: convert to the json-schema")
> 
> All above commits made it into the 5.14-rc1.
> ---
>  .../devicetree/bindings/mfd/brcm,cru.yaml     | 86 +++++++++++++++++++
>  1 file changed, 86 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/brcm,cru.yaml

Applied, thanks.

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From mudongliangabcd at gmail.com  Mon Aug 16 06:21:45 2021
From: mudongliangabcd at gmail.com (Dongliang Mu)
Date: Mon, 16 Aug 2021 21:21:45 +0800
Subject: [PATCH v2] crypto: sun8i-ce: fix multiple memory leaks in
 sun8i_ce_hash_run
In-Reply-To: <20210812104318.GA5780@gondor.apana.org.au>
References: <20210803063149.2821093-1-mudongliangabcd@gmail.com>
 <20210812100437.GA5055@gondor.apana.org.au>
 <CAD-N9QWGgBBddi5kwTNANKVVdWaQRwagMHvaH592B5GDALpBrg@mail.gmail.com>
 <20210812102954.GA5569@gondor.apana.org.au>
 <CAD-N9QU6r-yLBvJUpV+xy4pgOFnrtquBymthG7k5ddHt20APzg@mail.gmail.com>
 <20210812104318.GA5780@gondor.apana.org.au>
Message-ID: <CAD-N9QVz3W1E0D4i9iVTpkHVaB_Y9u1_HK2VW+FoQKJ9H8krrA@mail.gmail.com>

On Thu, Aug 12, 2021 at 6:43 PM Herbert Xu <herbert at gondor.apana.org.au> wrote:
>
> On Thu, Aug 12, 2021 at 06:40:20PM +0800, Dongliang Mu wrote:
> >
> > I agree with you and would like to modify "return 0" to "return err"
> > in the next version.  Even if the parent function does not care about
> > the return value, it is still necessary to keep the right return
> > value.
>
> Well if the parent is ignoring the error then returning the error
> there obviously isn't going to help.

If so, do I still need to change my current patch?

Dongliang Mu

>
> Cheers,
> --
> Email: Herbert Xu <herbert at gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From ulf.hansson at linaro.org  Mon Aug 16 06:43:01 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 16 Aug 2021 15:43:01 +0200
Subject: [PATCH 3/6] dt-bindings: mmc: fsl-imx-esdhc: add
 fsl,sdio-async-interrupt-enabled binding
In-Reply-To: <1629117508-4886-3-git-send-email-haibo.chen@nxp.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <1629117508-4886-3-git-send-email-haibo.chen@nxp.com>
Message-ID: <CAPDyKFqagBkbnxxh+KWbV2=sjkj3mGrKXUweOL5TrMJ1-Hmnww@mail.gmail.com>

On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
>
> From: Haibo Chen <haibo.chen at nxp.com>
>
> Add a new fsl,sdio-async-interrupt-enabled binding for sdio devices
> which enable the async interrupt function. When get this property,
> driver will avoid to use DAT[1] for hardware auto tuning check.
>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> ---
>  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml         | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> index b5baf439fbac..8a9f1775b0e2 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> @@ -122,6 +122,16 @@ properties:
>        - const: state_200mhz
>        - const: sleep
>
> +  fsl,sdio-async-interrupt-enabled:
> +    description: |
> +      Recommend for SDIO cards that enables SDIO async interrupt for SDR104 and SDR50
> +      operating modes. SDIO async interrupt uses DAT[1] to signal the card's interrupt.
> +      uSDHC tuning mechanism must use DAT[0] and CMD signals to avoid a possible
> +      conflict and incorrect delay line calculated by the uSDHC auto tuning mechanism.
> +      Enabling this device tree property is only recommended for layouts that are
> +      matching the SD interface length.
> +    type: boolean

We already have a common mmc property, "cap-sdio-irq", that tells
whether the controller supports SDIO irqs (which is delivered on
DAT1).

Can't you use this instead?

> +
>  required:
>    - compatible
>    - reg
> --
> 2.17.1
>

Kind regards
Uffe


From lee.jones at linaro.org  Mon Aug 16 06:48:17 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 16 Aug 2021 14:48:17 +0100
Subject: [PATCH v2 1/1] genirq/cpuhotplug: Bump debugging information print
 down to KERN_DEBUG
Message-ID: <20210816134817.1503661-1-lee.jones@linaro.org>

This sort of information is only generally useful when debugging.

No need to have these sprinkled through the kernel log otherwise.

Real world problem:

  During pre-release testing these have an affect on performance on
  real products.  To the point where so much logging builds up, that
  it sets off the watchdog(s) on some high profile consumer devices.

Cc: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
Change-Id: I1ad66f05c33431e2a2b0765733c5536e835108e1
---
 kernel/irq/cpuhotplug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c
index 02236b13b3599..39a41c56ad4fe 100644
--- a/kernel/irq/cpuhotplug.c
+++ b/kernel/irq/cpuhotplug.c
@@ -166,7 +166,7 @@ void irq_migrate_all_off_this_cpu(void)
 		raw_spin_unlock(&desc->lock);
 
 		if (affinity_broken) {
-			pr_warn_ratelimited("IRQ %u: no longer affine to CPU%u\n",
+			pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n",
 					    irq, smp_processor_id());
 		}
 	}
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From ulf.hansson at linaro.org  Mon Aug 16 06:53:11 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 16 Aug 2021 15:53:11 +0200
Subject: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the auto-tuning
 setting for sdio device
In-Reply-To: <1629117508-4886-4-git-send-email-haibo.chen@nxp.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <1629117508-4886-4-git-send-email-haibo.chen@nxp.com>
Message-ID: <CAPDyKFpqTdKxFytQWo+TLJf+D=JYJo6B2aZDqOQc4+9_mbH40Q@mail.gmail.com>

On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
>
> From: Haibo Chen <haibo.chen at nxp.com>
>
> USDHC contain auto tuning circuit, this circuit will work automatically after
> the tuning procedurae, it can increase/decrease the delay cell according to
> the outside environment change (like temperature).
>
> Unfortunately, this auto tuning circuit can not handle the async sdio device
> interrupt correctly. When sdio device use 4 data line, async sdio interrupt
> will use DAT[1], if we enable auto tuning circuit check 4 data lines, include
> the DAT[1], this circuit will detect this interrupt, take this as a data on
> DAT[1], and adjust the delay cell wrongly.
>
> This is the hardware design limitation, to avoid this, when sdio device enable
> async interrupt, auto tuning circuit only check DAT[0] and CMD lines.

SDIO irqs are being enabled/disabled dynamically in runtime by the mmc
core via the host ops ->enable_sdio_irq().

Rather than forcing the autotuning circuit to stay unused statically,
perhaps an option would be to disable it when the SDIO irqs becomes
enabled? Or maybe that becomes too complicated?

>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index f18d169bc8ff..ab84c29777e5 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -226,6 +226,7 @@ struct esdhc_platform_data {
>         unsigned int tuning_step;       /* The delay cell steps in tuning procedure */
>         unsigned int tuning_start_tap;  /* The start delay cell point in tuning procedure */
>         unsigned int strobe_dll_delay_target;   /* The delay cell for strobe pad (read clock) */
> +       bool sdio_async_interrupt_enabled;      /* sdio device enable the async interrupt */
>  };
>
>  struct esdhc_soc_data {
> @@ -416,6 +417,8 @@ static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
>  /* Enable the auto tuning circuit to check the CMD line and BUS line */
>  static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
>  {
> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +       struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
>         u32 buswidth, auto_tune_buswidth;
>
>         buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL));
> @@ -432,6 +435,18 @@ static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
>                 break;
>         }
>
> +       /*
> +        * If sdio device use async interrupt, it will use DAT[1] to signal
> +        * the device's interrupt asynchronous when use 4 data lines.
> +        * Then hardware auto tuning circuit MUST NOT check the DAT[1] line,
> +        * otherwise auto tuning will be impacted by this async interrupt,
> +        * and change the delay cell incorrectly, which then cause data/cmd
> +        * errors.
> +        * This is the hardware auto tuning circuit limitation.
> +        */
> +       if (imx_data->boarddata.sdio_async_interrupt_enabled)
> +               auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;
> +
>         esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
>                         auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
>                         ESDHC_VEND_SPEC2);
> @@ -1531,6 +1546,9 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
>         if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line))
>                 boarddata->delay_line = 0;
>
> +       if (of_property_read_bool(np, "fsl,sdio-async-interrupt-enabled"))

As stated on the DT patch, I think you can use the "cap-sdio-irq" instead.

> +               boarddata->sdio_async_interrupt_enabled = true;
> +
>         mmc_of_parse_voltage(host->mmc, &host->ocr_mask);
>
>         if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) {
> --
> 2.17.1
>

Kind regards
Uffe


From rafael at kernel.org  Mon Aug 16 06:57:54 2021
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Mon, 16 Aug 2021 15:57:54 +0200
Subject: [PATCH v2 1/3] ACPI: osl: Add __force attribute in
 acpi_os_map_iomem() cast
In-Reply-To: <CAMj1kXHM8tG2f-i6u8Ohb0RV9XTqq2N1Oooz_Q2kvLpdfTMxqw@mail.gmail.com>
References: <20210726100026.12538-1-lorenzo.pieralisi@arm.com>
 <20210802152359.12623-2-lorenzo.pieralisi@arm.com>
 <YRKtEDycefrZLB3X@infradead.org>
 <CAMj1kXEB1CFj1svCWu7yOoUi_OkEqYEUQnB_XWOd3gD+ejO_6w@mail.gmail.com>
 <YRPZ2Kqb/MFggHzQ@infradead.org> <20210811145508.GA3650@lpieralisi>
 <20210816095854.GA2599@lpieralisi>
 <CAMj1kXHM8tG2f-i6u8Ohb0RV9XTqq2N1Oooz_Q2kvLpdfTMxqw@mail.gmail.com>
Message-ID: <CAJZ5v0jp_cQ4gvd6TGO6dSgGtCuuEEpkmArxMMe0tcgoZAbSdg@mail.gmail.com>

On Mon, Aug 16, 2021 at 12:22 PM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Mon, 16 Aug 2021 at 11:59, Lorenzo Pieralisi
> <lorenzo.pieralisi at arm.com> wrote:
> >
> > On Wed, Aug 11, 2021 at 03:55:08PM +0100, Lorenzo Pieralisi wrote:
> > > On Wed, Aug 11, 2021 at 03:08:24PM +0100, Christoph Hellwig wrote:
> > > > On Wed, Aug 11, 2021 at 12:40:28PM +0200, Ard Biesheuvel wrote:
> > > > > The whole problem we are solving here is that ACPI, being based on
> > > > > x86, conflates MMIO mappings with memory mappings, and has been using
> > > > > the same underlying infrastructure for either.
> > > >
> > > > So let's fix that problem instead of papering over it.
> > >
> > > Patch (3) in this series is a fix - I would ask whether it makes
> > > sense to merge patches (2-3) now and think about reworking the current
> > > ACPI IO/MEM mapping API later, it can be an invasive change for a fix,
> > > assuming we agree on how to rework the ACPI IO/MEM mapping API.
> >
> > What should we do then with this series ?
> >
>
> It is not even clear that reworking the ACPI core is feasible to begin
> with, OTOH, fixing a sparse warning is arguably not a critical bug fix
> either, so I'd suggest we just drop that bit.

So I'm assuming that one more iteration of this series will be posted.


From ulf.hansson at linaro.org  Mon Aug 16 06:59:05 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 16 Aug 2021 15:59:05 +0200
Subject: [PATCH V2 04/10] mmc: sdhci-iproc: Cap min clock frequency on
 BCM2711
In-Reply-To: <1628334401-6577-5-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
 <1628334401-6577-5-git-send-email-stefan.wahren@i2se.com>
Message-ID: <CAPDyKFoAGx-1nQh81P3OPiAkR5cq1wGaioQ8Mxo4JCZsZC6NVQ@mail.gmail.com>

On Sat, 7 Aug 2021 at 13:07, Stefan Wahren <stefan.wahren at i2se.com> wrote:
>
> From: Nicolas Saenz Julienne <nsaenz at kernel.org>
>
> There is a known bug on BCM2711's SDHCI core integration where the
> controller will hang when the difference between the core clock and the
> bus clock is too great. Specifically this can be reproduced under the
> following conditions:
>
> - No SD card plugged in, polling thread is running, probing cards at
>   100 kHz.
> - BCM2711's core clock configured at 500MHz or more.
>
> So set 200 kHz as the minimum clock frequency available for that board.
>
> For more information on the issue see this:
> https://lore.kernel.org/linux-mmc/20210322185816.27582-1-nsaenz at kernel.org/T/#m11f2783a09b581da6b8a15f302625b43a6ecdeca
>
> Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
> Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>

Applied for fixes and by adding a stable tag, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/sdhci-iproc.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
> index cce390f..032bf85 100644
> --- a/drivers/mmc/host/sdhci-iproc.c
> +++ b/drivers/mmc/host/sdhci-iproc.c
> @@ -173,6 +173,23 @@ static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host)
>                 return pltfm_host->clock;
>  }
>
> +/*
> + * There is a known bug on BCM2711's SDHCI core integration where the
> + * controller will hang when the difference between the core clock and the bus
> + * clock is too great. Specifically this can be reproduced under the following
> + * conditions:
> + *
> + *  - No SD card plugged in, polling thread is running, probing cards at
> + *    100 kHz.
> + *  - BCM2711's core clock configured at 500MHz or more
> + *
> + * So we set 200kHz as the minimum clock frequency available for that SoC.
> + */
> +static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
> +{
> +       return 200000;
> +}
> +
>  static const struct sdhci_ops sdhci_iproc_ops = {
>         .set_clock = sdhci_set_clock,
>         .get_max_clock = sdhci_iproc_get_max_clock,
> @@ -271,6 +288,7 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
>         .set_clock = sdhci_set_clock,
>         .set_power = sdhci_set_power_and_bus_voltage,
>         .get_max_clock = sdhci_iproc_get_max_clock,
> +       .get_min_clock = sdhci_iproc_bcm2711_get_min_clock,
>         .set_bus_width = sdhci_set_bus_width,
>         .reset = sdhci_reset,
>         .set_uhs_signaling = sdhci_set_uhs_signaling,
> --
> 2.7.4
>


From ulf.hansson at linaro.org  Mon Aug 16 06:59:09 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 16 Aug 2021 15:59:09 +0200
Subject: [PATCH V2 05/10] mmc: sdhci-iproc: Set
 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711
In-Reply-To: <1628334401-6577-6-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
 <1628334401-6577-6-git-send-email-stefan.wahren@i2se.com>
Message-ID: <CAPDyKFr9UEO4TdieTYoR+UXgp70d4Axy7F2nYJc_qNb1dPho7A@mail.gmail.com>

On Sat, 7 Aug 2021 at 13:07, Stefan Wahren <stefan.wahren at i2se.com> wrote:
>
> From: Nicolas Saenz Julienne <nsaenz at kernel.org>
>
> The controller doesn't seem to pick-up on clock changes, so set the
> SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN flag to query the clock frequency
> directly from the clock.
>
> Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
> Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>

Applied for fixes and by adding a stable tag, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/sdhci-iproc.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
> index 032bf85..e7565c6 100644
> --- a/drivers/mmc/host/sdhci-iproc.c
> +++ b/drivers/mmc/host/sdhci-iproc.c
> @@ -295,7 +295,8 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
>  };
>
>  static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
> -       .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
> +       .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
> +                 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
>         .ops = &sdhci_iproc_bcm2711_ops,
>  };
>
> --
> 2.7.4
>


From tabba at google.com  Mon Aug 16 07:39:53 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Aug 2021 16:39:53 +0200
Subject: [PATCH v3 11/15] KVM: arm64: Add trap handlers for protected VMs
In-Reply-To: <20210812094554.GH5912@willie-the-truck>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-12-tabba@google.com>
 <20210812094554.GH5912@willie-the-truck>
Message-ID: <CA+EHjTz2warTOJLYfdOMjybg65WiUZ+v9UT7rvSPDEMR35Gy8Q@mail.gmail.com>

Hi Will,

On Thu, Aug 12, 2021 at 11:46 AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Jul 19, 2021 at 05:03:42PM +0100, Fuad Tabba wrote:
> > Add trap handlers for protected VMs. These are mainly for Sys64
> > and debug traps.
> >
> > No functional change intended as these are not hooked in yet to
> > the guest exit handlers introduced earlier. So even when trapping
> > is triggered, the exit handlers would let the host handle it, as
> > before.
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_fixed_config.h | 178 +++++++++
> >  arch/arm64/include/asm/kvm_host.h         |   2 +
> >  arch/arm64/include/asm/kvm_hyp.h          |   3 +
> >  arch/arm64/kvm/Makefile                   |   2 +-
> >  arch/arm64/kvm/arm.c                      |  11 +
> >  arch/arm64/kvm/hyp/nvhe/Makefile          |   2 +-
> >  arch/arm64/kvm/hyp/nvhe/sys_regs.c        | 443 ++++++++++++++++++++++
> >  arch/arm64/kvm/pkvm.c                     | 183 +++++++++
> >  8 files changed, 822 insertions(+), 2 deletions(-)
> >  create mode 100644 arch/arm64/include/asm/kvm_fixed_config.h
> >  create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c
> >  create mode 100644 arch/arm64/kvm/pkvm.c
> >
> > diff --git a/arch/arm64/include/asm/kvm_fixed_config.h b/arch/arm64/include/asm/kvm_fixed_config.h
> > new file mode 100644
> > index 000000000000..b39a5de2c4b9
> > --- /dev/null
> > +++ b/arch/arm64/include/asm/kvm_fixed_config.h
> > @@ -0,0 +1,178 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (C) 2021 Google LLC
> > + * Author: Fuad Tabba <tabba at google.com>
> > + */
> > +
> > +#ifndef __ARM64_KVM_FIXED_CONFIG_H__
> > +#define __ARM64_KVM_FIXED_CONFIG_H__
> > +
> > +#include <asm/sysreg.h>
> > +
> > +/*
> > + * This file contains definitions for features to be allowed or restricted for
> > + * guest virtual machines as a baseline, depending on what mode KVM is running
> > + * in and on the type of guest is running.
>
> s/is running/that is running/

Ack.

> > + *
> > + * The features are represented as the highest allowed value for a feature in
> > + * the feature id registers. If the field is set to all ones (i.e., 0b1111),
> > + * then it's only restricted by what the system allows. If the feature is set to
> > + * another value, then that value would be the maximum value allowed and
> > + * supported in pKVM, even if the system supports a higher value.
>
> Given that some fields are signed whereas others are unsigned, I think the
> wording could be a bit tighter here when it refers to "maximum".
>
> > + *
> > + * Some features are forced to a certain value, in which case a SET bitmap is
> > + * used to force these values.
> > + */
> > +
> > +
> > +/*
> > + * Allowed features for protected guests (Protected KVM)
> > + *
> > + * The approach taken here is to allow features that are:
> > + * - needed by common Linux distributions (e.g., flooating point)
>
> s/flooating/floating
Ack.

> > + * - are trivial, e.g., supporting the feature doesn't introduce or require the
> > + * tracking of additional state
> ... in KVM.

Ack.

> > + * - not trapable
>
> s/not trapable/cannot be trapped/
Ack

> > + */
> > +
> > +/*
> > + * - Floating-point and Advanced SIMD:
> > + *   Don't require much support other than maintaining the context, which KVM
> > + *   already has.
>
> I'd rework this sentence. We have to support fpsimd because Linux guests
> rely on it.

Ack

> > + * - AArch64 guests only (no support for AArch32 guests):
> > + *   Simplify support in case of asymmetric AArch32 systems.
>
> I don't think asymmetric systems come into this really; AArch32 on its
> own adds lots of complexity in trap handling, emulation, condition codes
> etc. Restricting guests to AArch64 means we don't have to worry about the
> AArch32 exception model or emulation of 32-bit instructions.

Ack

> > + * - RAS (v1)
> > + *   v1 doesn't require much additional support, but later versions do.
>
> Be more specific?

Ack

> > + * - Data Independent Timing
> > + *   Trivial
> > + * Remaining features are not supported either because they require too much
> > + * support from KVM, or risk leaking guest data.
>
> I think we should drop this sentence -- it makes it sounds like we can't
> be arsed :)

Ack.

> > + */
> > +#define PVM_ID_AA64PFR0_ALLOW (\
> > +     FEATURE(ID_AA64PFR0_FP) | \
> > +     FIELD_PREP(FEATURE(ID_AA64PFR0_EL0), ID_AA64PFR0_ELx_64BIT_ONLY) | \
> > +     FIELD_PREP(FEATURE(ID_AA64PFR0_EL1), ID_AA64PFR0_ELx_64BIT_ONLY) | \
> > +     FIELD_PREP(FEATURE(ID_AA64PFR0_EL2), ID_AA64PFR0_ELx_64BIT_ONLY) | \
> > +     FIELD_PREP(FEATURE(ID_AA64PFR0_EL3), ID_AA64PFR0_ELx_64BIT_ONLY) | \
> > +     FIELD_PREP(FEATURE(ID_AA64PFR0_RAS), ID_AA64PFR0_RAS_V1) | \
>
> I think having the FIELD_PREP entries in the ALLOW mask is quite confusing
> here -- naively you would expect to be able to bitwise-and the host register
> value with the ALLOW mask and get the sanitised version back, but with these
> here you have to go field-by-field to compute the common value.
>
> So perhaps move those into a PVM_ID_AA64PFR0_RESTRICT mask or something?
> Then pvm_access_id_aa64pfr0() will become a little easier to read, I think.

I agree. I've reworked it, and it simplifies the code and makes it
easier to read.

> > +     FEATURE(ID_AA64PFR0_ASIMD) | \
> > +     FEATURE(ID_AA64PFR0_DIT) \
> > +     )
> > +
> > +/*
> > + * - Branch Target Identification
> > + * - Speculative Store Bypassing
> > + *   These features are trivial to support
> > + */
> > +#define PVM_ID_AA64PFR1_ALLOW (\
> > +     FEATURE(ID_AA64PFR1_BT) | \
> > +     FEATURE(ID_AA64PFR1_SSBS) \
> > +     )
> > +
> > +/*
> > + * No support for Scalable Vectors:
> > + *   Requires additional support from KVM
>
> Perhaps expand on "support" here? E.g. "context-switching and trapping
> support at EL2".

Ack.

> > + */
> > +#define PVM_ID_AA64ZFR0_ALLOW (0ULL)
> > +
> > +/*
> > + * No support for debug, including breakpoints, and watchpoints:
> > + *   Reduce complexity and avoid exposing/leaking guest data
> > + *
> > + * NOTE: The Arm architecture mandates support for at least the Armv8 debug
> > + * architecture, which would include at least 2 hardware breakpoints and
> > + * watchpoints. Providing that support to protected guests adds considerable
> > + * state and complexity, and risks leaking guest data. Therefore, the reserved
> > + * value of 0 is used for debug-related fields.
> > + */
>
> I think the complexity of the debug architecture is a good reason to avoid
> exposing it here, but I don't understand how providing breakpoints or
> watchpoints to a guest could risk leaking guest data. What is the specific
> threat here?

I mixed up the various debug and trace features here. Will fix the comment.

> > +#define PVM_ID_AA64DFR0_ALLOW (0ULL)
> > +
> > +/*
> > + * These features are chosen because they are supported by KVM and to limit the
> > + * confiruation state space and make it more deterministic.
>
> s/confiruation/configuration/
>
> However, I don't agree that this provides determinism since we're not
> forcing any particular values, but rather filtering the values from the
> host.

Ack

> > + * - 40-bit IPA
>
> This seems more about not supporting KVM_CAP_ARM_VM_IPA_SIZE for now.
>
> > + * - 16-bit ASID
> > + * - Mixed-endian
> > + * - Distinction between Secure and Non-secure Memory
> > + * - Mixed-endian at EL0 only
> > + * - Non-context synchronizing exception entry and exit
>
> These all seem to fall into the "cannot trap" category, so we just advertise
> whatever we've got.

Ack.


>
> > + */
> > +#define PVM_ID_AA64MMFR0_ALLOW (\
> > +     FIELD_PREP(FEATURE(ID_AA64MMFR0_PARANGE), ID_AA64MMFR0_PARANGE_40) | \
> > +     FIELD_PREP(FEATURE(ID_AA64MMFR0_ASID), ID_AA64MMFR0_ASID_16) | \
> > +     FEATURE(ID_AA64MMFR0_BIGENDEL) | \
> > +     FEATURE(ID_AA64MMFR0_SNSMEM) | \
> > +     FEATURE(ID_AA64MMFR0_BIGENDEL0) | \
> > +     FEATURE(ID_AA64MMFR0_EXS) \
> > +     )
> > +
> > +/*
> > + * - 64KB granule not supported
> > + */
> > +#define PVM_ID_AA64MMFR0_SET (\
> > +     FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN64), ID_AA64MMFR0_TGRAN64_NI) \
> > +     )
>
> Why not, and can we actually prevent the guest from doing that?

We cannot prevent the guest from doing it. Initial reasoning was that
there isn't a clear use case for it, but since we cannot prevent the
guest from doing that, I'll unhide it.

> > +/*
> > + * These features are chosen because they are supported by KVM and to limit the
> > + * confiruation state space and make it more deterministic.
>
> It's that typo again ;) But my comment from before still applies -- I don't
> think an ALLOW mask adds hugely to the determinism.

Ack

> > + * - Hardware translation table updates to Access flag and Dirty state
> > + * - Number of VMID bits from CPU
> > + * - Hierarchical Permission Disables
> > + * - Privileged Access Never
> > + * - SError interrupt exceptions from speculative reads
> > + * - Enhanced Translation Synchronization
>
> As before, I think this is a mixture of "trivial" and "cannot trap"
> features.

Ack

> > + */
> > +#define PVM_ID_AA64MMFR1_ALLOW (\
> > +     FEATURE(ID_AA64MMFR1_HADBS) | \
> > +     FEATURE(ID_AA64MMFR1_VMIDBITS) | \
> > +     FEATURE(ID_AA64MMFR1_HPD) | \
> > +     FEATURE(ID_AA64MMFR1_PAN) | \
> > +     FEATURE(ID_AA64MMFR1_SPECSEI) | \
> > +     FEATURE(ID_AA64MMFR1_ETS) \
> > +     )
> > +
> > +/*
> > + * These features are chosen because they are supported by KVM and to limit the
> > + * confiruation state space and make it more deterministic.
>
> <same comment>

Ack
> > + * - Common not Private translations
> > + * - User Access Override
> > + * - IESB bit in the SCTLR_ELx registers
> > + * - Unaligned single-copy atomicity and atomic functions
> > + * - ESR_ELx.EC value on an exception by read access to feature ID space
> > + * - TTL field in address operations.
> > + * - Break-before-make sequences when changing translation block size
> > + * - E0PDx mechanism
> > + */
> > +#define PVM_ID_AA64MMFR2_ALLOW (\
> > +     FEATURE(ID_AA64MMFR2_CNP) | \
> > +     FEATURE(ID_AA64MMFR2_UAO) | \
> > +     FEATURE(ID_AA64MMFR2_IESB) | \
> > +     FEATURE(ID_AA64MMFR2_AT) | \
> > +     FEATURE(ID_AA64MMFR2_IDS) | \
> > +     FEATURE(ID_AA64MMFR2_TTL) | \
> > +     FEATURE(ID_AA64MMFR2_BBM) | \
> > +     FEATURE(ID_AA64MMFR2_E0PD) \
> > +     )
> > +
> > +/*
> > + * Allow all features in this register because they are trivial to support, or
> > + * are already supported by KVM:
> > + * - LS64
> > + * - XS
> > + * - I8MM
> > + * - DGB
> > + * - BF16
> > + * - SPECRES
> > + * - SB
> > + * - FRINTTS
> > + * - PAuth
> > + * - FPAC
> > + * - LRCPC
> > + * - FCMA
> > + * - JSCVT
> > + * - DPB
> > + */
> > +#define PVM_ID_AA64ISAR1_ALLOW (~0ULL)
> > +
> > +#endif /* __ARM64_KVM_FIXED_CONFIG_H__ */
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index ac67d5699c68..e1ceadd69575 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -780,6 +780,8 @@ static inline bool kvm_vm_is_protected(struct kvm *kvm)
> >       return false;
> >  }
> >
> > +void kvm_init_protected_traps(struct kvm_vcpu *vcpu);
> > +
> >  int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
> >  bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
> >
> > diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
> > index 657d0c94cf82..3f4866322f85 100644
> > --- a/arch/arm64/include/asm/kvm_hyp.h
> > +++ b/arch/arm64/include/asm/kvm_hyp.h
> > @@ -115,7 +115,10 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
> >  void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
> >  #endif
> >
> > +extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
> > +extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
> >  extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
> >  extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
> > +extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
> >
> >  #endif /* __ARM64_KVM_HYP_H__ */
> > diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> > index 989bb5dad2c8..0be63f5c495f 100644
> > --- a/arch/arm64/kvm/Makefile
> > +++ b/arch/arm64/kvm/Makefile
> > @@ -14,7 +14,7 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
> >        $(KVM)/vfio.o $(KVM)/irqchip.o $(KVM)/binary_stats.o \
> >        arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \
> >        inject_fault.o va_layout.o handle_exit.o \
> > -      guest.o debug.o reset.o sys_regs.o \
> > +      guest.o debug.o pkvm.o reset.o sys_regs.o \
> >        vgic-sys-reg-v3.o fpsimd.o pmu.o \
> >        arch_timer.o trng.o\
> >        vgic/vgic.o vgic/vgic-init.o \
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 14b12f2c08c0..3f28549aff0d 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -618,6 +618,14 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
> >
> >       ret = kvm_arm_pmu_v3_enable(vcpu);
> >
> > +     /*
> > +      * Initialize traps for protected VMs.
> > +      * NOTE: Move  trap initialization to EL2 once the code is in place for
> > +      * maintaining protected VM state at EL2 instead of the host.
> > +      */
> > +     if (kvm_vm_is_protected(kvm))
> > +             kvm_init_protected_traps(vcpu);
> > +
> >       return ret;
> >  }
> >
> > @@ -1781,8 +1789,11 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
> >       void *addr = phys_to_virt(hyp_mem_base);
> >       int ret;
> >
> > +     kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> > +     kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
> >       kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
> >       kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
> > +     kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
> >
> >       ret = create_hyp_mappings(addr, addr + hyp_mem_size, PAGE_HYP);
> >       if (ret)
> > diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
> > index 5df6193fc430..a23f417a0c20 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/Makefile
> > +++ b/arch/arm64/kvm/hyp/nvhe/Makefile
> > @@ -14,7 +14,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
> >
> >  obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
> >        hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
> > -      cache.o setup.o mm.o mem_protect.o
> > +      cache.o setup.o mm.o mem_protect.o sys_regs.o
> >  obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
> >        ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
> >  obj-y += $(lib-objs)
> > diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> > new file mode 100644
> > index 000000000000..6c7230aa70e9
> > --- /dev/null
> > +++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
> > @@ -0,0 +1,443 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (C) 2021 Google LLC
> > + * Author: Fuad Tabba <tabba at google.com>
> > + */
> > +
> > +#include <linux/kvm_host.h>
> > +
> > +#include <asm/kvm_asm.h>
> > +#include <asm/kvm_emulate.h>
> > +#include <asm/kvm_fixed_config.h>
> > +#include <asm/kvm_mmu.h>
> > +
> > +#include <hyp/adjust_pc.h>
> > +
> > +#include "../../sys_regs.h"
> > +
> > +/*
> > + * Copies of the host's CPU features registers holding sanitized values.
> > + */
> > +u64 id_aa64pfr0_el1_sys_val;
> > +u64 id_aa64pfr1_el1_sys_val;
> > +u64 id_aa64mmfr2_el1_sys_val;
> > +
> > +/*
> > + * Inject an unknown/undefined exception to the guest.
> > + */
> > +static void inject_undef(struct kvm_vcpu *vcpu)
> > +{
> > +     u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
> > +
> > +     vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 |
> > +                          KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
> > +                          KVM_ARM64_PENDING_EXCEPTION);
> > +
> > +     __kvm_adjust_pc(vcpu);
> > +
> > +     write_sysreg_el1(esr, SYS_ESR);
> > +     write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
> > +}
> > +
> > +/*
> > + * Accessor for undefined accesses.
> > + */
> > +static bool undef_access(struct kvm_vcpu *vcpu,
> > +                      struct sys_reg_params *p,
> > +                      const struct sys_reg_desc *r)
> > +{
> > +     inject_undef(vcpu);
> > +     return false;
> > +}
> > +
> > +/*
> > + * Accessors for feature registers.
> > + *
> > + * If access is allowed, set the regval to the protected VM's view of the
> > + * register and return true.
> > + * Otherwise, inject an undefined exception and return false.
> > + */
> > +
> > +/*
> > + * Returns the minimum feature supported and allowed.
> > + */
> > +static u64 get_min_feature(u64 feature, u64 allowed_features,
> > +                        u64 supported_features)
"> > +{
> > +     const u64 allowed_feature = FIELD_GET(feature, allowed_features);
> > +     const u64 supported_feature = FIELD_GET(feature, supported_features);
> > +
> > +     return min(allowed_feature, supported_feature);
>
> Careful here: this is an unsigned comparison, yet some fields are signed.
> cpufeature.c uses the S_ARM64_FTR_BITS and ARM64_FTR_BITS to declare signed
> and unsigned fields respectively.

I completely missed that! It's described in "D13.1.3 Principles of the
ID scheme for fields in ID registers" or the Arm Architecture
Reference Manual. Fortunately, all of the features I'm working with
are unsigned. However, I will fix it in v4 to ensure that should we
add a signed feature we can clearly see that it needs to be handled
differently.

Thanks!

/fuad

> Will
>
> --
> To unsubscribe from this group and stop receiving emails from it, send an email to kernel-team+unsubscribe at android.com.
>


From tabba at google.com  Mon Aug 16 07:40:15 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 16 Aug 2021 16:40:15 +0200
Subject: [PATCH v3 15/15] KVM: arm64: Restrict protected VM capabilities
In-Reply-To: <20210812095938.GM5912@willie-the-truck>
References: <20210719160346.609914-1-tabba@google.com>
 <20210719160346.609914-16-tabba@google.com>
 <20210812095938.GM5912@willie-the-truck>
Message-ID: <CA+EHjTz8ct68cZEHU_x_oTNGJw=sffy9HcgQiNPVbwFy5M7dGA@mail.gmail.com>

Hi Will,

On Thu, Aug 12, 2021 at 11:59 AM Will Deacon <will at kernel.org> wrote:
>
> On Mon, Jul 19, 2021 at 05:03:46PM +0100, Fuad Tabba wrote:
> > Restrict protected VM capabilities based on the
> > fixed-configuration for protected VMs.
> >
> > No functional change intended in current KVM-supported modes
> > (nVHE, VHE).
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_fixed_config.h | 10 ++++
> >  arch/arm64/kvm/arm.c                      | 63 ++++++++++++++++++++++-
> >  arch/arm64/kvm/pkvm.c                     | 30 +++++++++++
> >  3 files changed, 102 insertions(+), 1 deletion(-)
>
> This patch looks good to me, but I'd be inclined to add this to the user-ABI
> series given that it's really all user-facing and, without a functional
> kvm_vm_is_protected(), isn't serving much purpose.

Sure.
/fuad

> Cheers,
>
> Will


From lukas.bulwahn at gmail.com  Mon Aug 16 08:01:15 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Mon, 16 Aug 2021 17:01:15 +0200
Subject: [PATCH] pcmcia: clean up dead drivers for CompuLab CM-X255/CM-X270
 boards
Message-ID: <20210816150115.12889-1-lukas.bulwahn@gmail.com>

Commit 9d3239147d6d ("ARM: pxa: remove Compulab pxa2xx boards") removes
the config MACH_ARMCORE in ./arch/arm/mach-pxa/Kconfig.

Hence, ./scripts/checkkconfigsymbols.py warns on non-existing configs:

MACH_ARMCORE
Referencing files: drivers/pcmcia/Kconfig, drivers/pcmcia/Makefile

Clean up the dead remains of pcmcia drivers for Compulab pxa2xx boards.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/pcmcia/Kconfig          |   2 +-
 drivers/pcmcia/Makefile         |   2 -
 drivers/pcmcia/pxa2xx_cm_x255.c | 124 --------------------------------
 drivers/pcmcia/pxa2xx_cm_x270.c | 103 --------------------------
 drivers/pcmcia/pxa2xx_cm_x2xx.c |  44 ------------
 5 files changed, 1 insertion(+), 274 deletions(-)
 delete mode 100644 drivers/pcmcia/pxa2xx_cm_x255.c
 delete mode 100644 drivers/pcmcia/pxa2xx_cm_x270.c
 delete mode 100644 drivers/pcmcia/pxa2xx_cm_x2xx.c

diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index d13b8d1a780a..ab53eab635f6 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -209,7 +209,7 @@ config PCMCIA_PXA2XX
 	tristate "PXA2xx support"
 	depends on ARM && ARCH_PXA && PCMCIA
 	depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
-		    || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
+		    || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
 		    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
 		    || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
 		    || MACH_COLIBRI320 || MACH_H4700)
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index d82c07c4806b..2d5657cfc49c 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -48,10 +48,8 @@ sa1100_cs-$(CONFIG_SA1100_H3100)		+= sa1100_h3600.o
 sa1100_cs-$(CONFIG_SA1100_H3600)		+= sa1100_h3600.o
 sa1100_cs-$(CONFIG_SA1100_SIMPAD)		+= sa1100_simpad.o
 
-pxa2xx_cm_x2xx_cs-y				+= pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
 pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o
 pxa2xx-obj-$(CONFIG_PXA_SHARPSL)		+= pxa2xx_sharpsl.o
-pxa2xx-obj-$(CONFIG_MACH_ARMCORE)		+= pxa2xx_cm_x2xx_cs.o
 pxa2xx-obj-$(CONFIG_ARCOM_PCMCIA)		+= pxa2xx_viper.o
 pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA)		+= pxa2xx_trizeps4.o
 pxa2xx-obj-$(CONFIG_MACH_PALMTX)		+= pxa2xx_palmtx.o
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
deleted file mode 100644
index c0b6b846fbaa..000000000000
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ /dev/null
@@ -1,124 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/pcmcia/pxa/pxa_cm_x255.c
- *
- * Compulab Ltd., 2003, 2007, 2008
- * Mike Rapoport <mike at compulab.co.il>
- */
-
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/export.h>
-
-#include "soc_common.h"
-
-#define GPIO_PCMCIA_SKTSEL	(54)
-#define GPIO_PCMCIA_S0_CD_VALID	(16)
-#define GPIO_PCMCIA_S1_CD_VALID	(17)
-#define GPIO_PCMCIA_S0_RDYINT	(6)
-#define GPIO_PCMCIA_S1_RDYINT	(8)
-#define GPIO_PCMCIA_RESET	(9)
-
-static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
-	if (ret)
-		return ret;
-	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
-
-	if (skt->nr == 0) {
-		skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
-		skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
-	} else {
-		skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S1_CD_VALID;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
-		skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S1_RDYINT;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA1 RDY";
-	}
-
-	return 0;
-}
-
-static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
-{
-	gpio_free(GPIO_PCMCIA_RESET);
-}
-
-
-static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
-				       struct pcmcia_state *state)
-{
-	state->vs_3v  = 0;
-	state->vs_Xv  = 0;
-}
-
-
-static int cmx255_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
-					  const socket_state_t *state)
-{
-	switch (skt->nr) {
-	case 0:
-		if (state->flags & SS_RESET) {
-			gpio_set_value(GPIO_PCMCIA_SKTSEL, 0);
-			udelay(1);
-			gpio_set_value(GPIO_PCMCIA_RESET, 1);
-			udelay(10);
-			gpio_set_value(GPIO_PCMCIA_RESET, 0);
-		}
-		break;
-	case 1:
-		if (state->flags & SS_RESET) {
-			gpio_set_value(GPIO_PCMCIA_SKTSEL, 1);
-			udelay(1);
-			gpio_set_value(GPIO_PCMCIA_RESET, 1);
-			udelay(10);
-			gpio_set_value(GPIO_PCMCIA_RESET, 0);
-		}
-		break;
-	}
-
-	return 0;
-}
-
-static struct pcmcia_low_level cmx255_pcmcia_ops __initdata = {
-	.owner			= THIS_MODULE,
-	.hw_init		= cmx255_pcmcia_hw_init,
-	.hw_shutdown		= cmx255_pcmcia_shutdown,
-	.socket_state		= cmx255_pcmcia_socket_state,
-	.configure_socket	= cmx255_pcmcia_configure_socket,
-	.nr			= 1,
-};
-
-static struct platform_device *cmx255_pcmcia_device;
-
-int __init cmx255_pcmcia_init(void)
-{
-	int ret;
-
-	cmx255_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
-
-	if (!cmx255_pcmcia_device)
-		return -ENOMEM;
-
-	ret = platform_device_add_data(cmx255_pcmcia_device, &cmx255_pcmcia_ops,
-				       sizeof(cmx255_pcmcia_ops));
-
-	if (ret == 0) {
-		printk(KERN_INFO "Registering cm-x255 PCMCIA interface.\n");
-		ret = platform_device_add(cmx255_pcmcia_device);
-	}
-
-	if (ret)
-		platform_device_put(cmx255_pcmcia_device);
-
-	return ret;
-}
-
-void __exit cmx255_pcmcia_exit(void)
-{
-	platform_device_unregister(cmx255_pcmcia_device);
-}
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
deleted file mode 100644
index 36e35da5f887..000000000000
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ /dev/null
@@ -1,103 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/pcmcia/pxa/pxa_cm_x270.c
- *
- * Compulab Ltd., 2003, 2007, 2008
- * Mike Rapoport <mike at compulab.co.il>
- */
-
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/export.h>
-
-#include "soc_common.h"
-
-#define GPIO_PCMCIA_S0_CD_VALID	(84)
-#define GPIO_PCMCIA_S0_RDYINT	(82)
-#define GPIO_PCMCIA_RESET	(53)
-
-static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
-	if (ret)
-		return ret;
-	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
-
-	skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
-	skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
-	skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
-	skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
-
-	return ret;
-}
-
-static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
-{
-	gpio_free(GPIO_PCMCIA_RESET);
-}
-
-
-static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
-				       struct pcmcia_state *state)
-{
-	state->vs_3v  = 0;
-	state->vs_Xv  = 0;
-}
-
-
-static int cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
-					  const socket_state_t *state)
-{
-	switch (skt->nr) {
-	case 0:
-		if (state->flags & SS_RESET) {
-			gpio_set_value(GPIO_PCMCIA_RESET, 1);
-			udelay(10);
-			gpio_set_value(GPIO_PCMCIA_RESET, 0);
-		}
-		break;
-	}
-
-	return 0;
-}
-
-static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
-	.owner			= THIS_MODULE,
-	.hw_init		= cmx270_pcmcia_hw_init,
-	.hw_shutdown		= cmx270_pcmcia_shutdown,
-	.socket_state		= cmx270_pcmcia_socket_state,
-	.configure_socket	= cmx270_pcmcia_configure_socket,
-	.nr			= 1,
-};
-
-static struct platform_device *cmx270_pcmcia_device;
-
-int __init cmx270_pcmcia_init(void)
-{
-	int ret;
-
-	cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
-
-	if (!cmx270_pcmcia_device)
-		return -ENOMEM;
-
-	ret = platform_device_add_data(cmx270_pcmcia_device, &cmx270_pcmcia_ops,
-				       sizeof(cmx270_pcmcia_ops));
-
-	if (ret == 0) {
-		printk(KERN_INFO "Registering cm-x270 PCMCIA interface.\n");
-		ret = platform_device_add(cmx270_pcmcia_device);
-	}
-
-	if (ret)
-		platform_device_put(cmx270_pcmcia_device);
-
-	return ret;
-}
-
-void __exit cmx270_pcmcia_exit(void)
-{
-	platform_device_unregister(cmx270_pcmcia_device);
-}
diff --git a/drivers/pcmcia/pxa2xx_cm_x2xx.c b/drivers/pcmcia/pxa2xx_cm_x2xx.c
deleted file mode 100644
index 14eae238131d..000000000000
--- a/drivers/pcmcia/pxa2xx_cm_x2xx.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/drivers/pcmcia/pxa/pxa_cm_x2xx.c
- *
- * Compulab Ltd., 2003, 2007, 2008
- * Mike Rapoport <mike at compulab.co.il>
- */
-
-#include <linux/module.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-int cmx255_pcmcia_init(void);
-int cmx270_pcmcia_init(void);
-void cmx255_pcmcia_exit(void);
-void cmx270_pcmcia_exit(void);
-
-static int __init cmx2xx_pcmcia_init(void)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_armcore() && cpu_is_pxa25x())
-		ret = cmx255_pcmcia_init();
-	else if (machine_is_armcore() && cpu_is_pxa27x())
-		ret = cmx270_pcmcia_init();
-
-	return ret;
-}
-
-static void __exit cmx2xx_pcmcia_exit(void)
-{
-	if (machine_is_armcore() && cpu_is_pxa25x())
-		cmx255_pcmcia_exit();
-	else if (machine_is_armcore() && cpu_is_pxa27x())
-		cmx270_pcmcia_exit();
-}
-
-module_init(cmx2xx_pcmcia_init);
-module_exit(cmx2xx_pcmcia_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mike Rapoport <mike at compulab.co.il>");
-MODULE_DESCRIPTION("CM-x2xx PCMCIA driver");
-- 
2.26.2



From wenst at chromium.org  Mon Aug 16 08:11:50 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 16 Aug 2021 23:11:50 +0800
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
In-Reply-To: <87fsvfal4n.wl-maz@kernel.org>
References: <20210811171505.1502090-1-wenst@chromium.org>
 <87fsvfal4n.wl-maz@kernel.org>
Message-ID: <CAGXv+5GjVZ582u29_bbSKoLjb00vtvPo_ACn4WKDEfFiPULxPQ@mail.gmail.com>

Hi,

On Thu, Aug 12, 2021 at 2:31 AM Marc Zyngier <maz at kernel.org> wrote:
>
> + Alex, who introduced this.
>
> On Wed, 11 Aug 2021 18:15:05 +0100,
> Chen-Yu Tsai <wenst at chromium.org> wrote:
> >
> > When non-secure priorities are used, compared to the raw priority set,
> > the value read back from RPR is also right-shifted by one and the
> > highest bit set.
> >
> > Add a macro to do the modifications to the raw priority when doing the
> > comparison against the RPR value. This corrects the pseudo-NMI behavior
> > when non-secure priorities in the GIC are used. Tested on 5.10 with
> > the "IPI as pseudo-NMI" series [1] applied on MT8195.
> >
> > [1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg at linaro.org/
> >
> > Fixes: 336780590990 ("irqchip/gic-v3: Support pseudo-NMIs when SCR_EL3.FIQ == 0")
> > Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> > ---
> >  drivers/irqchip/irq-gic-v3.c | 11 ++++++++++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > index e0f4debe64e1..e7a0b55413db 100644
> > --- a/drivers/irqchip/irq-gic-v3.c
> > +++ b/drivers/irqchip/irq-gic-v3.c
> > @@ -100,6 +100,15 @@ EXPORT_SYMBOL(gic_pmr_sync);
> >  DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities);
> >  EXPORT_SYMBOL(gic_nonsecure_priorities);
> >
> > +#define GICD_INT_RPR_PRI(priority)                                   \
> > +     ({                                                              \
> > +             u32 __priority = (priority);                            \
> > +             if (static_branch_unlikely(&gic_nonsecure_priorities))  \
> > +                     __priority = 0x80 | (__priority >> 1);          \
> > +                                                                     \
> > +             __priority;                                             \
>
> This doesn't reflect what the pseudocode says of a read of ICC_RPR_EL1
> AFAICS. When the priority is activated, it is indeed shifted. But a
> read of RPR does appear to shift things back (and you loose the lowest
> bit in the process). Please see 'aarch64/support/ICC_RPR_EL1' in the
> architecture spec.
>
> Can you confirm that SCR_EL3.FIQ is set on your system?

I gave this a test with mainline on an ROC-RK3399-PC. I figure this is
more available and stable than the MT8195 [1].

My board is running:

- ATF v2.4-561-g465af20ce (based on git commit 8078b5c5a) with console and
  some erratas enabled, but otherwise standard rk3399 config
  "-dirty" was due to the SCR_EL3 line.

NOTICE:  BL31: v2.4(debug):v2.4-561-g465af20ce-dirty
NOTICE:  BL31: Built : 22:59:42, Aug 16 2021
INFO:    GICv3 with legacy support detected.
INFO:    ARM GICv3 driver initialized in EL3
INFO:    Maximum SPI INTID supported: 287
INFO:    plat_rockchip_pmu_init(1628): pd status 3e
INFO:    BL31: Initializing runtime services
INFO:    BL31: cortex_a53: CPU workaround for 855873 was applied
INFO:    BL31: cortex_a53: CPU workaround for 1530924 was applied
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    BL31: SCR_EL3=0x238, FIQ not set
INFO:    Entry point address = 0x200000
INFO:    SPSR = 0x3c9

- kernel next-20210813 + "NMI as IPI" series + debug printks scattered
  in the GICv3 driver

GICv3: GIC: Using split EOI/Deactivate mode
GICv3: 256 SPIs implemented
GICv3: 0 Extended SPIs implemented
GICv3: Distributor has no Range Selector support
Root IRQ handler: gic_handle_irq
GICv3: 16 PPIs implemented
GICv3: CPU0: found redistributor 0 region 0:0x00000000fef00000
GICv3: Pseudo-NMIs enabled using relaxed ICC_PMR_EL1 synchronisation
GICv3: Priority bits (gic_get_pribits()): 5
GICv3: Group0 available (gic_has_group0())
GICv3: Distributor security enabled (gic_dist_security_disabled()
GICv3: non-secure priorities used (gic_nonsecure_priorities)
GICv3: gic_irq_nmi_setup start: irq 7
GICv3: interrupt 7 priority a0
GICv3: interrupt 7 priority 20

So the RK3399 actually works correctly _without_ my fix. The NMI backtrace
triggers going through `gic_handle_nmi()`. If my fix is applied, it goes
through `gic_handle_irq()` instead.


However the MT8195 needs this to work correctly.

 === ATF ===
NOTICE:  MT8195 bl31_setup
NOTICE:  BL31: v2.5(debug):
NOTICE:  BL31: Built : Wed Jul  7 11:17:50 UTC 2021
INFO:    GICv3 without legacy support detected.
INFO:    ARM GICv3 driver initialized in EL3
INFO:    Maximum SPI INTID supported: 895
NOTICE:  MT8195 spm_boot_init
INFO:    BL31: Initializing runtime services
INFO:    BL31: cortex_a55: CPU workaround for 1530923 was applied
INFO:    SPM: enable CPC mode
INFO:    mcdi ready for mcusys-off-idle and system suspend
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x80000000
INFO:    SPSR = 0x8

 === kernel GICv3 ===
GICv3: GIC: Using split EOI/Deactivate mode
GICv3: 864 SPIs implemented
GICv3: 0 Extended SPIs implemented
GICv3: Distributor has no Range Selector support
GICv3: 16 PPIs implemented
GICv3: CPU0: found redistributor 0 region 0:0x000000000c040000
GICv3: Pseudo-NMIs enabled using relaxed ICC_PMR_EL1 synchronisation
GICv3: Priority bits: 5
GICv3: Group0 available
GICv3: Distributor security enabled
GICv3: non-secure priorities used
GICv3: gic_irq_nmi_setup start: irq 7
GICv3: interrupt 7 priority a0
GICv3: interrupt 7 priority 20

I will dig through our ATF code base and try to see what's different.


ChenYu


[1] On a side note, the latest Chrome OS kernel 5.10 for the MT8195 gives
    a spinlock recursion during boot and hangs if pseudo-NMIs are enabled.
    I had to dig through my reflog to find the early version I developed
    on.


> Thanks,
>
>         M.
>
> > +     })
> > +
> >  /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
> >  static refcount_t *ppi_nmi_refs;
> >
> > @@ -687,7 +696,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
> >               return;
> >
> >       if (gic_supports_nmi() &&
> > -         unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) {
> > +         unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) {
> >               gic_handle_nmi(irqnr, regs);
> >               return;
> >       }
>
>
> --
> Without deviation from the norm, progress is not possible.


From wenst at chromium.org  Mon Aug 16 08:37:51 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 16 Aug 2021 23:37:51 +0800
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
 <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
Message-ID: <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>

On Mon, Aug 16, 2021 at 6:48 PM zhiyong.tao <zhiyong.tao at mediatek.com> wrote:
>
> On Mon, 2021-08-16 at 14:10 +0800, Chen-Yu Tsai wrote:
> > On Thu, Aug 5, 2021 at 7:02 AM Linus Walleij <
> > linus.walleij at linaro.org> wrote:
> > >
> > > On Thu, Jul 29, 2021 at 11:43 AM Chen-Yu Tsai <wenst at chromium.org>
> > > wrote:
> > > > On Thu, Jul 29, 2021 at 4:23 PM zhiyong.tao <
> > > > zhiyong.tao at mediatek.com> wrote:
> > > > > The rsel actual bias resistance of each setting is different in
> > > > > different IC. we think that the define "MTK_PULL_SET_RSEL_000"
> > > > > is more
> > > > > common for all different IC.
> > > >
> > > > I see. I personally prefer having things clearly described. I can
> > > > understand this might be an extra burden to support different
> > > > chips
> > > > with different parameters, though this should be fairly
> > > > straightforward
> > > > with lookup tables tied to the compatible strings.
> > > >
> > > > Let's see if Rob and Linus have anything to add.
> > >
> > > Not much. We have "soft pushed" for this to be described as generic
> > > as possible, using SI units (ohms). But we also allow vendor-
> > > specific
> > > numbers in this attribute. Especially when reverse engineering SoCs
> > > that the contributor don't really have specs on (example M1 Mac).
> > >
> > > The intent with the SI units is especially for people like you
> > > folks working
> > > with Chromium to be able to use different SoCs and not feel lost
> > > to a forest of different ways of doing things and associated
> > > mistakes because vendors have hopelessly idiomatic pin configs.
> >
> > I'll take that as "use SI units whenever possible and reasonable".
>
> ==> so It doesn't need to change the define, is it right?
> we will keep the common define.

Actually I think it would be possible and reasonable to use SI units
in this case, since you are the vendor and have the resistor values
to implement the support. Having different sets of values for different
chips is nothing out of the ordinary. We already have to account for
different number of pins and different pin functions. That is what
compatible strings are for.

Now if you have _many_ different sets of values within the same chip,
that could make things more difficult. However the clearness of having
the real values visible in the device tree would likely benefit both
software and hardware engineers outside of Mediatek. That is what we
should be aiming for.


Regards
ChenYu


From tharvey at gateworks.com  Mon Aug 16 08:39:57 2021
From: tharvey at gateworks.com (Tim Harvey)
Date: Mon, 16 Aug 2021 08:39:57 -0700
Subject: [PATCH 0/6] Add IMX8M Mini PCI support
In-Reply-To: <VI1PR04MB58533AF76EA4DFD8AD6CDA158CEC9@VI1PR04MB5853.eurprd04.prod.outlook.com>
References: <20210723204958.7186-1-tharvey@gateworks.com>
 <36070609-9f1f-00c8-ccf5-8ed7877b29da@pengutronix.de>
 <VI1PR04MB58533AF76EA4DFD8AD6CDA158CEC9@VI1PR04MB5853.eurprd04.prod.outlook.com>
Message-ID: <CAJ+vNU1tgVsQWtxa0E8SArO=hA2K8OkqiSPrRSpx0Q5XS4gUWA@mail.gmail.com>

On Thu, Jul 29, 2021 at 6:28 PM Richard Zhu <hongxing.zhu at nxp.com> wrote:
>
> Hi Tim:
> Just as Ahmad mentioned, Lucas had issue one patch-set to support i.MX8MM PCIe.
> Some comments in the review cycle.
> - One separate PHY driver should be used for i.MX8MM PCIe driver.
> - Schema file should be used I think, otherwise the .txt file in the dt-binding.
>
> I'm preparing one patch-set, but it's relied on the yaml file exchanges and power-domain changes(block control and so on).
> Up to now, I only walking on the first step, trying to exchange the dt-binding files to schema yaml file.
>
> Best Regards
> Richard Zhu

Richard / Ahmad,

Thanks for your response - I did not see the series from Lucas. I will
drop this and wait for him to complete his work.

Thanks,

Tim


From marcel at holtmann.org  Mon Aug 16 08:45:44 2021
From: marcel at holtmann.org (Marcel Holtmann)
Date: Mon, 16 Aug 2021 17:45:44 +0200
Subject: [PATCH v2] Bluetooth: btusb: Remove WAKEUP_DISABLE and add
 WAKEUP_AUTOSUSPEND for Realtek devices
In-Reply-To: <20210810020147.14276-1-max.chou@realtek.com>
References: <20210810020147.14276-1-max.chou@realtek.com>
Message-ID: <08B718ED-F885-4870-BB80-AB547FEC52B1@holtmann.org>

Hi Max,

> For the commit of 9e45524a011107a73bc2cdde8370c61e82e93a4d, wakeup is
> always disabled for Realtek devices. However, there's the capability
> for Realtek devices to apply USB wake-up.
> 
> In this commit, remove WAKEUP_DISABLE feature for Realtek devices.
> If users would switch wake-up, they should access
> "/sys/bus/usb/.../power/wakeup"
> 
> In this commit, it also adds the feature as WAKEUP_AUTOSUSPEND
> for Realtek devices because it should set do_remote_wakeup on autosuspend.
> 
> Signed-off-by: Max Chou <max.chou at realtek.com>
> Tested-by: Hilda Wu <hildawu at realtek.com>
> Reviewed-by: Archie Pusaka <apusaka at chromium.org>
> Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit at chromium.org>
> ---
> Changes in v2:
> -fix the compiling error due to the incorrect patch file submited
> ---
> drivers/bluetooth/btusb.c | 28 +++++++++-------------------
> 1 file changed, 9 insertions(+), 19 deletions(-)

this does not apply cleanly to bluetooth-next tree.

Regards

Marcel



From cki-project at redhat.com  Mon Aug 16 09:02:15 2021
From: cki-project at redhat.com (CKI Project)
Date: Mon, 16 Aug 2021 16:02:15 -0000
Subject: =?utf-8?b?4pyF?= PASS: Test report for kernel 5.14.0-rc6 (arm-next,
 09bfde80)
Message-ID: <cki.4C0103C5E4.ZY0VD99XNJ@redhat.com>


Hello,

We ran automated tests on a recent commit from this kernel tree:

       Kernel repo: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
            Commit: 09bfde80e8e2 - Merge branch 'for-next/fixes' into for-kernelci

The results of these automated tests are provided below.

    Overall result: PASSED
             Merge: OK
           Compile: OK
             Tests: OK

All kernel binaries, config files, and logs are available for download here:

  https://arr-cki-prod-datawarehouse-public.s3.amazonaws.com/index.html?prefix=datawarehouse-public/2021/08/16/353738695

Please reply to this email if you have any questions about the tests that we
ran or if you have any suggestions on how to make future tests more effective.

        ,-.   ,-.
       ( C ) ( K )  Continuous
        `-',-.`-'   Kernel
          ( I )     Integration
           `-'
______________________________________________________________________________

Compile testing
---------------

We compiled the kernel for 1 architecture:

    aarch64:
      make options: make -j24 INSTALL_MOD_STRIP=1 targz-pkg



Hardware testing
----------------
We booted each kernel and ran the following tests:

  aarch64:
    Host 1:
       ? Boot test
       ? Reboot test
       ? ACPI table test
       ? ACPI enabled test
       ? LTP
       ? CIFS Connectathon
       ? POSIX pjd-fstest suites
       ? Loopdev Sanity
       ? jvm - jcstress tests
       ? Memory: fork_mem
       ? Memory function: memfd_create
       ? AMTU (Abstract Machine Test Utility)
       ? Networking bridge: sanity
       ? Ethernet drivers sanity
       ? Networking socket: fuzz
       ? Networking: igmp conformance test
       ? Networking route: pmtu
       ? Networking route_func - local
       ? Networking route_func - forward
       ? Networking TCP: keepalive test
       ? Networking UDP: socket
       ? Networking cki netfilter test
       ? Networking tunnel: geneve basic test
       ? Networking tunnel: gre basic
       ? L2TP basic test
       ? Networking tunnel: vxlan basic
       ? Networking ipsec: basic netns - transport
       ? Networking ipsec: basic netns - tunnel
       ? Libkcapi AF_ALG test
       ? pciutils: update pci ids test
       ? ALSA PCM loopback test
       ? ALSA Control (mixer) Userspace Element test
       ? storage: SCSI VPD
       ? trace: ftrace/tracer
       ? ? xarray-idr-radixtree-test
       ? ? i2c: i2cdetect sanity
       ? ? NFS Connectathon
       ? ? Firmware test suite
       ? ? Memory function: kaslr
       ? ? audit: audit testsuite test
       ? ? lvm cache test
       ? ? lvm snapper test

    Host 2:
       ? Boot test
       ? Reboot test
       ? xfstests - ext4
       ? xfstests - xfs
       ? selinux-policy: serge-testsuite
       ? storage: software RAID testing
       ? Storage: swraid mdadm raid_module test
       ? ? Podman system integration test - as root
       ? ? Podman system integration test - as user
       ? ? xfstests - btrfs
       ? ? IPMI driver test
       ? ? IPMItool loop stress test
       ? ? Storage blktests
       ? ? Storage block - filesystem fio test
       ? ? Storage block - queue scheduler test
       ? ? Storage nvme - tcp
       ? ? stress: stress-ng

  Test sources: https://gitlab.com/cki-project/kernel-tests
    ? Pull requests are welcome for new tests or improvements to existing tests!

Aborted tests
-------------
Tests that didn't complete running successfully are marked with ???.
If this was caused by an infrastructure issue, we try to mark that
explicitly in the report.

Waived tests
------------
If the test run included waived tests, they are marked with ?. Such tests are
executed but their results are not taken into account. Tests are waived when
their results are not reliable enough, e.g. when they're just introduced or are
being fixed.

Testing timeout
---------------
We aim to provide a report within reasonable timeframe. Tests that haven't
finished running yet are marked with ?.



From abailon at baylibre.com  Mon Aug 16 09:43:04 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Mon, 16 Aug 2021 18:43:04 +0200
Subject: [PATCH 0/3] Add support of thermal for mt8195
Message-ID: <20210816164307.557315-1-abailon@baylibre.com>

This adds thermal support for mt8195.
Depends on https://patchwork.kernel.org/project/linux-mediatek/list/?series=502403

The changes required to support the mt8195 look very similar to those for
the mt6873 but the differences make code factorisation difficult.

Alexandre Bailon (1):
  dt-bindings: thermal: Add binding document for mt8195 thermal
    controller

Michael Kao (1):
  thermal: mediatek: Add thermal zone settings for mt8195

Tinghan Shen (1):
  arm64: dts: mt8195: Add thermal zone and thermal policy

 .../thermal/mediatek-thermal-lvts.yaml        |   6 +-
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 164 ++++++++++++++
 drivers/thermal/mediatek/soc_temp_lvts.c      | 209 ++++++++++++++++--
 3 files changed, 361 insertions(+), 18 deletions(-)

-- 
2.31.1



From abailon at baylibre.com  Mon Aug 16 09:43:05 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Mon, 16 Aug 2021 18:43:05 +0200
Subject: [PATCH 1/3] dt-bindings: thermal: Add binding document for mt8195
 thermal controller
In-Reply-To: <20210816164307.557315-1-abailon@baylibre.com>
References: <20210816164307.557315-1-abailon@baylibre.com>
Message-ID: <20210816164307.557315-2-abailon@baylibre.com>

This patch adds binding document for mt8195 thermal controller.

Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
---
 .../devicetree/bindings/thermal/mediatek-thermal-lvts.yaml  | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal-lvts.yaml b/Documentation/devicetree/bindings/thermal/mediatek-thermal-lvts.yaml
index 69ffe7b14c212..2e1ae00d4fd18 100644
--- a/Documentation/devicetree/bindings/thermal/mediatek-thermal-lvts.yaml
+++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal-lvts.yaml
@@ -12,7 +12,11 @@ maintainers:
 
 properties:
   compatible:
-    const: mediatek,mt6873-lvts
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt6873-lvts
+              - mediatek,mt8195-lvts
 
   reg:
     maxItems: 1
-- 
2.31.1



From abailon at baylibre.com  Mon Aug 16 09:43:06 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Mon, 16 Aug 2021 18:43:06 +0200
Subject: [PATCH 2/3] thermal: mediatek: Add thermal zone settings for mt8195
In-Reply-To: <20210816164307.557315-1-abailon@baylibre.com>
References: <20210816164307.557315-1-abailon@baylibre.com>
Message-ID: <20210816164307.557315-3-abailon@baylibre.com>

From: Michael Kao <michael.kao at mediatek.com>

Add thermal zone settings for mt8195

Signed-off-by: Michael Kao <michael.kao at mediatek.com>
Signed-off-by: Ben Tseng <ben.tseng at mediatek.com>
Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
---
 drivers/thermal/mediatek/soc_temp_lvts.c | 206 +++++++++++++++++++++--
 1 file changed, 192 insertions(+), 14 deletions(-)

diff --git a/drivers/thermal/mediatek/soc_temp_lvts.c b/drivers/thermal/mediatek/soc_temp_lvts.c
index 8153edaaf8150..ddcedcedbbc16 100644
--- a/drivers/thermal/mediatek/soc_temp_lvts.c
+++ b/drivers/thermal/mediatek/soc_temp_lvts.c
@@ -53,6 +53,7 @@
 
 #define CLOCK_26MHZ_CYCLE_NS	(38)
 #define BUS_ACCESS_US		(2)
+#define GOLDEN_TEMP_MAX		(62)
 
 #define FEATURE_DEVICE_AUTO_RCK	(BIT(0))
 #define FEATURE_CK26M_ACTIVE	(BIT(1))
@@ -577,21 +578,10 @@ static int prepare_calibration_data(struct lvts_data *lvts_data)
 	if (!cal_data->count_rc)
 		return -ENOMEM;
 
-	if (ops->efuse_to_cal_data)
+	if (ops->efuse_to_cal_data && !cal_data->use_fake_efuse)
 		ops->efuse_to_cal_data(lvts_data);
-
-	cal_data->use_fake_efuse = 1;
-	if (cal_data->golden_temp != 0) {
-		cal_data->use_fake_efuse = 0;
-	} else {
-		for (i = 0; i < lvts_data->num_sensor; i++) {
-			if (cal_data->count_r[i] != 0 ||
-			    cal_data->count_rc[i] != 0) {
-				cal_data->use_fake_efuse = 0;
-				break;
-			}
-		}
-	}
+	if (cal_data->golden_temp == 0 || cal_data->golden_temp > GOLDEN_TEMP_MAX)
+		cal_data->use_fake_efuse = 1;
 
 	if (cal_data->use_fake_efuse) {
 		/* It means all efuse data are equal to 0 */
@@ -1254,6 +1244,190 @@ static struct lvts_data mt6873_lvts_data = {
 	},
 };
 
+/*==================================================
+ * LVTS MT8195
+ *==================================================
+ */
+
+#define MT8195_NUM_LVTS (ARRAY_SIZE(mt8195_tc_settings))
+
+enum mt8195_lvts_domain {
+	MT8195_AP_DOMAIN,
+	MT8195_MCU_DOMAIN,
+	MT8195_NUM_DOMAIN
+};
+
+enum mt8195_lvts_sensor_enum {
+	MT8195_TS1_0,
+	MT8195_TS1_1,
+	MT8195_TS2_0,
+	MT8195_TS2_1,
+	MT8195_TS3_0,
+	MT8195_TS3_1,
+	MT8195_TS3_2,
+	MT8195_TS3_3,
+	MT8195_TS4_0,
+	MT8195_TS4_1,
+	MT8195_TS5_0,
+	MT8195_TS5_1,
+	MT8195_TS6_0,
+	MT8195_TS6_1,
+	MT8195_TS6_2,
+	MT8195_TS7_0,
+	MT8195_TS7_1,
+	MT8195_NUM_TS
+};
+
+static void mt8195_efuse_to_cal_data(struct lvts_data *lvts_data)
+{
+	struct sensor_cal_data *cal_data = &lvts_data->cal_data;
+
+	cal_data->golden_temp = GET_CAL_DATA_BITMASK(0, 31, 24);
+	cal_data->count_r[MT8195_TS1_0] = GET_CAL_DATA_BITMASK(1, 23, 0);
+	cal_data->count_r[MT8195_TS1_1] = (GET_CAL_DATA_BITMASK(2, 15, 0) << 8) +
+					   GET_CAL_DATA_BITMASK(1, 31, 24);
+	cal_data->count_r[MT8195_TS2_0] = GET_CAL_DATA_BITMASK(3, 31, 8);
+	cal_data->count_r[MT8195_TS2_1] = GET_CAL_DATA_BITMASK(4, 23, 0);
+	cal_data->count_r[MT8195_TS3_0] = (GET_CAL_DATA_BITMASK(6, 7, 0) << 16) +
+					   GET_CAL_DATA_BITMASK(5, 31, 16);
+	cal_data->count_r[MT8195_TS3_1] = GET_CAL_DATA_BITMASK(6, 31, 8);
+	cal_data->count_r[MT8195_TS3_2] = GET_CAL_DATA_BITMASK(7, 23, 0);
+	cal_data->count_r[MT8195_TS3_3] = (GET_CAL_DATA_BITMASK(8, 15, 0) << 8) +
+					   GET_CAL_DATA_BITMASK(7, 31, 24);
+	cal_data->count_r[MT8195_TS4_0] = GET_CAL_DATA_BITMASK(9, 31, 8);
+	cal_data->count_r[MT8195_TS4_1] = GET_CAL_DATA_BITMASK(10, 23, 0);
+	cal_data->count_r[MT8195_TS5_0] = (GET_CAL_DATA_BITMASK(12, 7, 0) << 16) +
+					   GET_CAL_DATA_BITMASK(11, 31, 16);
+	cal_data->count_r[MT8195_TS5_1] = GET_CAL_DATA_BITMASK(12, 31, 8);
+	cal_data->count_r[MT8195_TS6_0] = (GET_CAL_DATA_BITMASK(14, 15, 0) << 8) +
+					   GET_CAL_DATA_BITMASK(13, 31, 24);
+	cal_data->count_r[MT8195_TS6_1] = (GET_CAL_DATA_BITMASK(15, 7, 0) << 16) +
+					   GET_CAL_DATA_BITMASK(14, 31, 16);
+	cal_data->count_r[MT8195_TS6_2] = GET_CAL_DATA_BITMASK(15, 31, 8);
+	cal_data->count_r[MT8195_TS7_0] = (GET_CAL_DATA_BITMASK(17, 15, 0) << 8) +
+					   GET_CAL_DATA_BITMASK(16, 31, 24);
+	cal_data->count_r[MT8195_TS7_1] = (GET_CAL_DATA_BITMASK(18, 7, 0) << 16) +
+					   GET_CAL_DATA_BITMASK(17, 31, 16);
+	cal_data->count_rc[MT8195_TS1_0] = (GET_CAL_DATA_BITMASK(3, 7, 0) << 16) +
+					    GET_CAL_DATA_BITMASK(2, 31, 16);
+	cal_data->count_rc[MT8195_TS2_0] = (GET_CAL_DATA_BITMASK(5, 15, 0) << 8) +
+					    GET_CAL_DATA_BITMASK(4, 31, 24);
+	cal_data->count_rc[MT8195_TS3_0] = (GET_CAL_DATA_BITMASK(9, 7, 0) << 16) +
+					    GET_CAL_DATA_BITMASK(8, 31, 16);
+	cal_data->count_rc[MT8195_TS4_0] = (GET_CAL_DATA_BITMASK(11, 15, 0) << 8) +
+					    GET_CAL_DATA_BITMASK(10, 31, 24);
+	cal_data->count_rc[MT8195_TS5_0] = GET_CAL_DATA_BITMASK(13, 23, 0);
+	cal_data->count_rc[MT8195_TS6_0] = GET_CAL_DATA_BITMASK(16, 23, 0);
+	cal_data->count_rc[MT8195_TS7_0] = GET_CAL_DATA_BITMASK(18, 31, 8);
+}
+
+static struct tc_settings mt8195_tc_settings[] = {
+	[0] = {
+		.domain_index = MT8195_MCU_DOMAIN,
+		.addr_offset = 0x0,
+		.num_sensor = 2,
+		.sensor_map = {MT8195_TS1_0, MT8195_TS1_1},
+		.tc_speed = SET_TC_SPEED_IN_US(118, 118, 118, 118),
+		.hw_filter = LVTS_FILTER_2_OF_4,
+		.dominator_sensing_point = SENSING_POINT1,
+		.hw_reboot_trip_point = 117000,
+		.irq_bit = BIT(3),
+	},
+	[1] = {
+		.domain_index = MT8195_MCU_DOMAIN,
+		.addr_offset = 0x100,
+		.num_sensor = 2,
+		.sensor_map = {MT8195_TS2_0, MT8195_TS2_1},
+		.tc_speed = SET_TC_SPEED_IN_US(118, 118, 118, 118),
+		.hw_filter = LVTS_FILTER_2_OF_4,
+		.dominator_sensing_point = SENSING_POINT0,
+		.hw_reboot_trip_point = 117000,
+		.irq_bit = BIT(4),
+	},
+	[2] = {
+		.domain_index = MT8195_MCU_DOMAIN,
+		.addr_offset = 0x200,
+		.num_sensor = 4,
+		.sensor_map = {MT8195_TS3_0, MT8195_TS3_1, MT8195_TS3_2, MT8195_TS3_3},
+		.tc_speed = SET_TC_SPEED_IN_US(118, 118, 118, 118),
+		.hw_filter = LVTS_FILTER_2_OF_4,
+		.dominator_sensing_point = SENSING_POINT0,
+		.hw_reboot_trip_point = 117000,
+		.irq_bit = BIT(5),
+	},
+	[3] = {
+		.domain_index = MT8195_AP_DOMAIN,
+		.addr_offset = 0x0,
+		.num_sensor = 2,
+		.sensor_map = {MT8195_TS4_0, MT8195_TS4_1},
+		.tc_speed = SET_TC_SPEED_IN_US(118, 118, 118, 118),
+		.hw_filter = LVTS_FILTER_2_OF_4,
+		.dominator_sensing_point = SENSING_POINT0,
+		.hw_reboot_trip_point = 117000,
+		.irq_bit = BIT(3),
+	},
+	[4] = {
+		.domain_index = MT8195_AP_DOMAIN,
+		.addr_offset = 0x100,
+		.num_sensor = 2,
+		.sensor_map = {MT8195_TS5_0, MT8195_TS5_1},
+		.tc_speed = SET_TC_SPEED_IN_US(118, 118, 118, 118),
+		.hw_filter = LVTS_FILTER_2_OF_4,
+		.dominator_sensing_point = SENSING_POINT1,
+		.hw_reboot_trip_point = 117000,
+		.irq_bit = BIT(4),
+	},
+	[5] = {
+		.domain_index = MT8195_AP_DOMAIN,
+		.addr_offset = 0x200,
+		.num_sensor = 3,
+		.sensor_map = {MT8195_TS6_0, MT8195_TS6_1, MT8195_TS6_2},
+		.tc_speed = SET_TC_SPEED_IN_US(118, 118, 118, 118),
+		.hw_filter = LVTS_FILTER_2_OF_4,
+		.dominator_sensing_point = SENSING_POINT1,
+		.hw_reboot_trip_point = 117000,
+		.irq_bit = BIT(5),
+	},
+	[6] = {
+		.domain_index = MT8195_AP_DOMAIN,
+		.addr_offset = 0x300,
+		.num_sensor = 2,
+		.sensor_map = {MT8195_TS7_0, MT8195_TS7_1},
+		.tc_speed = SET_TC_SPEED_IN_US(118, 118, 118, 118),
+		.hw_filter = LVTS_FILTER_2_OF_4,
+		.dominator_sensing_point = SENSING_POINT0,
+		.hw_reboot_trip_point = 117000,
+		.irq_bit = BIT(6),
+	}
+};
+
+static struct lvts_data mt8195_lvts_data = {
+	.num_domain = MT8195_NUM_DOMAIN,
+	.num_tc = MT8195_NUM_LVTS,
+	.tc = mt8195_tc_settings,
+	.num_sensor = MT8195_NUM_TS,
+	.ops = {
+		.efuse_to_cal_data = mt8195_efuse_to_cal_data,
+		.device_enable_and_init = device_enable_and_init_v4,
+		.device_enable_auto_rck = device_enable_auto_rck_v4,
+		.device_read_count_rc_n = device_read_count_rc_n_v4,
+		.set_cal_data = set_calibration_data_v4,
+		.init_controller = init_controller_v4,
+	},
+	.feature_bitmap = FEATURE_DEVICE_AUTO_RCK,
+	.num_efuse_addr = 22,
+	.num_efuse_block = 2,
+	.cal_data = {
+		.default_golden_temp = 50,
+		.default_count_r = 35000,
+		.default_count_rc = 2750,
+	},
+	.coeff = {
+		.a = -250460,
+		.b = 250460,
+	},
+};
+
 /*==================================================
  *==================================================
  * Support chips
@@ -1264,6 +1438,10 @@ static const struct of_device_id lvts_of_match[] = {
 		.compatible = "mediatek,mt6873-lvts",
 		.data = (void *)&mt6873_lvts_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-lvts",
+		.data = (void *)&mt8195_lvts_data,
+	},
 	{
 	},
 };
-- 
2.31.1



From abailon at baylibre.com  Mon Aug 16 09:43:07 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Mon, 16 Aug 2021 18:43:07 +0200
Subject: [PATCH 3/3] arm64: dts: mt8195: Add thermal zone and thermal policy
In-Reply-To: <20210816164307.557315-1-abailon@baylibre.com>
References: <20210816164307.557315-1-abailon@baylibre.com>
Message-ID: <20210816164307.557315-4-abailon@baylibre.com>

From: Tinghan Shen <tinghan.shen at mediatek.com>

1. Add SoC and board thermal zones.
2. Add thermal throttle policy

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Signed-off-by: Ben Tseng <ben.tseng at mediatek.com>
Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 164 +++++++++++++++++++++++
 1 file changed, 164 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index d05492ff8f190..62d0944dea4db 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -11,6 +11,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/mt8195-pinfunc.h>
 #include <dt-bindings/reset/ti-syscon.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	compatible = "mediatek,mt8195";
@@ -475,6 +476,21 @@ spi0: spi at 1100a000 {
 			status = "disabled";
 		};
 
+		lvts: lvts at 1100b000 {
+			compatible = "mediatek,mt8195-lvts";
+			#thermal-sensor-cells = <1>;
+			reg = <0 0x1100b000 0 0x1000>,
+				<0 0x11278000 0 0x1000>;
+			interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>,
+					<GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_THERM>;
+			clock-names = "lvts_clk";
+			resets = <&infracfg_rst 1>,
+					<&infracfg_rst 2>;
+			nvmem-cells = <&lvts_e_data1 &lvts_e_data2>;
+			nvmem-cell-names = "e_data1","e_data2";
+		};
+
 		spi1: spi at 11010000 {
 			compatible = "mediatek,mt8195-spi", "mediatek,mt6765-spi";
 			reg = <0 0x11010000 0 0x100>;
@@ -830,4 +846,152 @@ vdosys1: syscon at 1c100000 {
 			#clock-cells = <1>;
 		};
 	};
+
+	thermal_zones: thermal-zones {
+		soc_max {
+			polling-delay = <1000>; /* milliseconds */
+			polling-delay-passive = <1000>; /* milliseconds */
+			thermal-sensors = <&lvts 0>;
+			sustainable-power = <1500>;
+
+			trips {
+				threshold: trip-point at 0 {
+					temperature = <68000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				target: target at 1 {
+					temperature = <85000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				soc_max_crit: soc_max_crit at 0 {
+					temperature = <115000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+			cooling-maps {
+				map0 {
+					trip = <&target>;
+					cooling-device = <&cpu0
+						THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>,
+								<&cpu1
+						THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>,
+								<&cpu2
+						THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>,
+								<&cpu3
+						THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+					contribution = <3072>;
+				};
+				map1 {
+					trip = <&target>;
+					cooling-device = <&cpu4
+						THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>,
+								<&cpu5
+						THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>,
+								<&cpu6
+						THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>,
+								<&cpu7
+						THERMAL_NO_LIMIT
+						THERMAL_NO_LIMIT>;
+					contribution = <1024>;
+				};
+			};
+		};
+		cpu_big1 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 1>;
+		};
+		cpu_big2 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 2>;
+		};
+		cpu_big3 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 3>;
+		};
+		cpu_big4 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 4>;
+		};
+		cpu_little1{
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 5>;
+		};
+		cpu_little2 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 6>;
+		};
+		cpu_little3 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 7>;
+		};
+		cpu_little4 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 8>;
+		};
+		vpu1 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 9>;
+		};
+		vpu2 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 10>;
+		};
+		gpu1 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 11>;
+		};
+		gpu2 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 12>;
+		};
+		vdec {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 13>;
+		};
+		img {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 14>;
+		};
+		infra {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 15>;
+		};
+		cam1 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 16>;
+		};
+		cam2 {
+			polling-delay = <0>; /* milliseconds */
+			polling-delay-passive = <0>; /* milliseconds */
+			thermal-sensors = <&lvts 17>;
+		};
+	};
 };
-- 
2.31.1



From lorenzo.pieralisi at arm.com  Mon Aug 16 10:01:08 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 16 Aug 2021 18:01:08 +0100
Subject: [PATCH v8 0/8] Add SR-IOV support in PCIe Endpoint Core
In-Reply-To: <20210811064656.15399-1-kishon@ti.com>
References: <20210811064656.15399-1-kishon@ti.com>
Message-ID: <162913323780.3691.9972292377170327162.b4-ty@arm.com>

On Wed, 11 Aug 2021 12:16:48 +0530, Kishon Vijay Abraham I wrote:
> Patch series
> *) Adds support to add virtual functions to enable endpoint controller
>    which supports SR-IOV capability
> *) Add support in Cadence endpoint driver to configure virtual functions
> *) Enable pci_endpoint_test driver to create pci_device for virtual
>    functions
> 
> [...]

Applied to pci/endpoint, thanks!

[1/8] dt-bindings: PCI: pci-ep: Add binding to specify virtual function
      https://git.kernel.org/lpieralisi/pci/c/ea96be4a7b
[2/8] PCI: endpoint: Add support to add virtual function in endpoint core
      https://git.kernel.org/lpieralisi/pci/c/b64215ff2b
[3/8] PCI: endpoint: Add support to link a physical function to a virtual function
      https://git.kernel.org/lpieralisi/pci/c/555d7c5f83
[4/8] PCI: endpoint: Add virtual function number in pci_epc ops
      https://git.kernel.org/lpieralisi/pci/c/22a8013ade
[5/8] PCI: cadence: Simplify code to get register base address for configuring BAR
      https://git.kernel.org/lpieralisi/pci/c/9d26fd710f
[6/8] PCI: cadence: Add support to configure virtual functions
      https://git.kernel.org/lpieralisi/pci/c/f52e1cf18d
[7/8] misc: pci_endpoint_test: Populate sriov_configure ops to configure SR-IOV device
      https://git.kernel.org/lpieralisi/pci/c/681883d1d1
[8/8] Documentation: PCI: endpoint/pci-endpoint-cfs: Guide to use SR-IOV
      https://git.kernel.org/lpieralisi/pci/c/805ff686a1

Thanks,
Lorenzo


From vladimir.oltean at nxp.com  Mon Aug 16 10:48:03 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Mon, 16 Aug 2021 17:48:03 +0000
Subject: [EXT] Re: [PATCH v1] arm64: dts: fsl: ls1028a-rdb: Add dts file
 to choose swp5 as dsa master
In-Reply-To: <VI1PR04MB56777E60653203A471B9864EE1FD9@VI1PR04MB5677.eurprd04.prod.outlook.com>
References: <20210813030155.23097-1-hongbo.wang@nxp.com>
 <YRZvItRlSpF2Xf+S@lunn.ch>
 <VI1PR04MB56773CC01AB86A8AA1A33F9AE1FA9@VI1PR04MB5677.eurprd04.prod.outlook.com>
 <20210813140745.fwjkmixzgvikvffz@skbuf>
 <VI1PR04MB56777E60653203A471B9864EE1FD9@VI1PR04MB5677.eurprd04.prod.outlook.com>
Message-ID: <20210816174803.k53gqgw45hda7zh2@skbuf>

On Mon, Aug 16, 2021 at 06:03:52AM +0000, Hongbo Wang wrote:
> > I was going to suggest as an alternative to define a device tree overlay file with
> > the changes in the CPU port assignment, instead of defining a wholly new DTS
> > for the LS1028A reference design board. But I am pretty sure that it is not
> > possible to specify a /delete-property/ inside a device tree overlay file, so that
> > won't actually work.
>
> hi Vladimir,
>
>   if don't specify "/delete-property/" in this dts file, the corresponding dtb will not work well,
> so I add it to delete 'ethernet' property from mscc_felix_port4 explicitly.

Judging by the reply, I am not actually sure you've understood what has been said.

I said:

There is an option to create a device tree overlay:

https://www.kernel.org/doc/html/latest/devicetree/overlay-notes.html

We use these for the riser cards on the LS1028A-QDS boards.

https://source.codeaurora.org/external/qoriq/qoriq-components/linux/tree/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts?h=LSDK-20.12-V5.4

They are included as usual in a U-Boot ITB file:

/ {
	images {
		/* Base DTB */
		ls1028aqds-dtb {
			description = "ls1028aqds-dtb";
			data = /incbin/("arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dtb");
			type = "flat_dt";
			arch = "arm64";
			os = "linux";
			compression = "none";
			load = <0x90000000>;
			hash at 1 {
				algo = "crc32";
			};
		};
		/* Overlay */
		fdt at ls1028aqds-13bb {
			description = "ls1028aqds-13bb";
			data = /incbin/("arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dtb");
			type = "flat_dt";
			arch = "arm64";
			load = <0x90010000>;
		};
	};
};

In U-Boot, you apply the overlay as following:

tftp $kernel_addr_r boot.itb && bootm $kernel_addr_r#ls1028aqds#ls1028aqds-13bb

It would have been nice to have a similar device tree overlay that
changes the DSA master from eno2 to eno3, and for that overlay to be
able to be applied (or not) from U-Boot.

But it's _not_ possible, because you cannot put the /delete-property/
(that you need to have) in the .dtbo file. Or if you put it, it will not
delete the property from the base dtb.

That's all I said.

From linux at roeck-us.net  Mon Aug 16 10:53:26 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 16 Aug 2021 10:53:26 -0700
Subject: [PATCH v5] memblock: make memblock_find_in_range method private
In-Reply-To: <20210816122622.30279-1-rppt@kernel.org>
References: <20210816122622.30279-1-rppt@kernel.org>
Message-ID: <33933841-7c27-5cf4-0241-031b221b926d@roeck-us.net>

On 8/16/21 5:26 AM, Mike Rapoport wrote:
> From: Mike Rapoport <rppt at linux.ibm.com>
> 
> There are a lot of uses of memblock_find_in_range() along with
> memblock_reserve() from the times memblock allocation APIs did not exist.
> 
> memblock_find_in_range() is the very core of memblock allocations, so any
> future changes to its internal behaviour would mandate updates of all the
> users outside memblock.
> 
> Replace the calls to memblock_find_in_range() with an equivalent calls to
> memblock_phys_alloc() and memblock_phys_alloc_range() and make
> memblock_find_in_range() private method of memblock.
> 
> This simplifies the callers, ensures that (unlikely) errors in
> memblock_reserve() are handled and improves maintainability of
> memblock_find_in_range().
> 
> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
> Acked-by: Kirill A. Shutemov <kirill.shtuemov at linux.intel.com>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>	# ACPI
> Acked-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Acked-by: Nick Kossifidis <mick at ics.forth.gr>			# riscv
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>		# arm64

This version passes all my x86/x86_64 boot tests.

Tested-by: Guenter Roeck <linux at roeck-us.net>

Guenter

> ---
> v5:
> * restore the original behaviour on x86 with addition of more elaborate
>    comment; I will address the issue in memory_map_top_down() in a separate
>    series.
> 
> v4: https://lore.kernel.org/lkml/20210812065907.20046-1-rppt at kernel.org
> * Add patch that prevents the crashes reported by Guenter Roeck on x86/i386
>    on QEMU with 256M or 512M of memory and EFI boot enabled.
> * Add Acked-by and Reviewed-by, thanks everybidy!
> 
> v3: https://lore.kernel.org/lkml/20210803064218.6611-1-rppt at kernel.org
> * simplify check for exact crash kerenl allocation on arm, per Rob
> * make crash_max unsigned long long on arm64, per Rob
> 
> v2: https://lore.kernel.org/lkml/20210802063737.22733-1-rppt at kernel.org
> * don't change error message in arm::reserve_crashkernel(), per Russell
> 
> v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org
> 
> 
>   arch/arm/kernel/setup.c           | 20 +++++---------
>   arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
>   arch/arm64/mm/init.c              | 36 ++++++++-----------------
>   arch/mips/kernel/setup.c          | 14 +++++-----
>   arch/riscv/mm/init.c              | 44 ++++++++++---------------------
>   arch/s390/kernel/setup.c          | 10 ++++---
>   arch/x86/kernel/aperture_64.c     |  5 ++--
>   arch/x86/mm/init.c                | 23 ++++++++++------
>   arch/x86/mm/numa.c                |  5 ++--
>   arch/x86/mm/numa_emulation.c      |  5 ++--
>   arch/x86/realmode/init.c          |  2 +-
>   drivers/acpi/tables.c             |  5 ++--
>   drivers/base/arch_numa.c          |  5 +---
>   drivers/of/of_reserved_mem.c      | 12 ++++++---
>   include/linux/memblock.h          |  2 --
>   mm/memblock.c                     |  2 +-
>   16 files changed, 81 insertions(+), 118 deletions(-)
> 
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index f97eb2371672..284a80c0b6e1 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -1012,31 +1012,25 @@ static void __init reserve_crashkernel(void)
>   		unsigned long long lowmem_max = __pa(high_memory - 1) + 1;
>   		if (crash_max > lowmem_max)
>   			crash_max = lowmem_max;
> -		crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
> -						    crash_size, CRASH_ALIGN);
> +
> +		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> +						       CRASH_ALIGN, crash_max);
>   		if (!crash_base) {
>   			pr_err("crashkernel reservation failed - No suitable area found.\n");
>   			return;
>   		}
>   	} else {
> +		unsigned long long crash_max = crash_base + crash_size;
>   		unsigned long long start;
>   
> -		start = memblock_find_in_range(crash_base,
> -					       crash_base + crash_size,
> -					       crash_size, SECTION_SIZE);
> -		if (start != crash_base) {
> +		start = memblock_phys_alloc_range(crash_size, SECTION_SIZE,
> +						  crash_base, crash_max);
> +		if (!start) {
>   			pr_err("crashkernel reservation failed - memory is in use.\n");
>   			return;
>   		}
>   	}
>   
> -	ret = memblock_reserve(crash_base, crash_size);
> -	if (ret < 0) {
> -		pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
> -			(unsigned long)crash_base);
> -		return;
> -	}
> -
>   	pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
>   		(unsigned long)(crash_size >> 20),
>   		(unsigned long)(crash_base >> 20),
> diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c
> index d654921dd09b..578670e3f608 100644
> --- a/arch/arm64/kvm/hyp/reserved_mem.c
> +++ b/arch/arm64/kvm/hyp/reserved_mem.c
> @@ -92,12 +92,10 @@ void __init kvm_hyp_reserve(void)
>   	 * this is unmapped from the host stage-2, and fallback to PAGE_SIZE.
>   	 */
>   	hyp_mem_size = hyp_mem_pages << PAGE_SHIFT;
> -	hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> -					      ALIGN(hyp_mem_size, PMD_SIZE),
> -					      PMD_SIZE);
> +	hyp_mem_base = memblock_phys_alloc(ALIGN(hyp_mem_size, PMD_SIZE),
> +					   PMD_SIZE);
>   	if (!hyp_mem_base)
> -		hyp_mem_base = memblock_find_in_range(0, memblock_end_of_DRAM(),
> -						      hyp_mem_size, PAGE_SIZE);
> +		hyp_mem_base = memblock_phys_alloc(hyp_mem_size, PAGE_SIZE);
>   	else
>   		hyp_mem_size = ALIGN(hyp_mem_size, PMD_SIZE);
>   
> @@ -105,7 +103,6 @@ void __init kvm_hyp_reserve(void)
>   		kvm_err("Failed to reserve hyp memory\n");
>   		return;
>   	}
> -	memblock_reserve(hyp_mem_base, hyp_mem_size);
>   
>   	kvm_info("Reserved %lld MiB at 0x%llx\n", hyp_mem_size >> 20,
>   		 hyp_mem_base);
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 8490ed2917ff..0bffd2d1854f 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -74,6 +74,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>   static void __init reserve_crashkernel(void)
>   {
>   	unsigned long long crash_base, crash_size;
> +	unsigned long long crash_max = arm64_dma_phys_limit;
>   	int ret;
>   
>   	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> @@ -84,33 +85,18 @@ static void __init reserve_crashkernel(void)
>   
>   	crash_size = PAGE_ALIGN(crash_size);
>   
> -	if (crash_base == 0) {
> -		/* Current arm64 boot protocol requires 2MB alignment */
> -		crash_base = memblock_find_in_range(0, arm64_dma_phys_limit,
> -				crash_size, SZ_2M);
> -		if (crash_base == 0) {
> -			pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> -				crash_size);
> -			return;
> -		}
> -	} else {
> -		/* User specifies base address explicitly. */
> -		if (!memblock_is_region_memory(crash_base, crash_size)) {
> -			pr_warn("cannot reserve crashkernel: region is not memory\n");
> -			return;
> -		}
> +	/* User specifies base address explicitly. */
> +	if (crash_base)
> +		crash_max = crash_base + crash_size;
>   
> -		if (memblock_is_region_reserved(crash_base, crash_size)) {
> -			pr_warn("cannot reserve crashkernel: region overlaps reserved memory\n");
> -			return;
> -		}
> -
> -		if (!IS_ALIGNED(crash_base, SZ_2M)) {
> -			pr_warn("cannot reserve crashkernel: base address is not 2MB aligned\n");
> -			return;
> -		}
> +	/* Current arm64 boot protocol requires 2MB alignment */
> +	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> +					       crash_base, crash_max);
> +	if (!crash_base) {
> +		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> +			crash_size);
> +		return;
>   	}
> -	memblock_reserve(crash_base, crash_size);
>   
>   	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>   		crash_base, crash_base + crash_size, crash_size >> 20);
> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> index 23a140327a0b..f979adfd4fc2 100644
> --- a/arch/mips/kernel/setup.c
> +++ b/arch/mips/kernel/setup.c
> @@ -452,8 +452,9 @@ static void __init mips_parse_crashkernel(void)
>   		return;
>   
>   	if (crash_base <= 0) {
> -		crash_base = memblock_find_in_range(CRASH_ALIGN, CRASH_ADDR_MAX,
> -							crash_size, CRASH_ALIGN);
> +		crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> +						       CRASH_ALIGN,
> +						       CRASH_ADDR_MAX);
>   		if (!crash_base) {
>   			pr_warn("crashkernel reservation failed - No suitable area found.\n");
>   			return;
> @@ -461,8 +462,9 @@ static void __init mips_parse_crashkernel(void)
>   	} else {
>   		unsigned long long start;
>   
> -		start = memblock_find_in_range(crash_base, crash_base + crash_size,
> -						crash_size, 1);
> +		start = memblock_phys_alloc_range(crash_size, 1,
> +						  crash_base,
> +						  crash_base + crash_size);
>   		if (start != crash_base) {
>   			pr_warn("Invalid memory region reserved for crash kernel\n");
>   			return;
> @@ -656,10 +658,6 @@ static void __init arch_mem_init(char **cmdline_p)
>   	mips_reserve_vmcore();
>   
>   	mips_parse_crashkernel();
> -#ifdef CONFIG_KEXEC
> -	if (crashk_res.start != crashk_res.end)
> -		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
> -#endif
>   	device_tree_init();
>   
>   	/*
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index a14bf3910eec..88649337c568 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -812,38 +812,22 @@ static void __init reserve_crashkernel(void)
>   
>   	crash_size = PAGE_ALIGN(crash_size);
>   
> -	if (crash_base == 0) {
> -		/*
> -		 * Current riscv boot protocol requires 2MB alignment for
> -		 * RV64 and 4MB alignment for RV32 (hugepage size)
> -		 */
> -		crash_base = memblock_find_in_range(search_start, search_end,
> -						    crash_size, PMD_SIZE);
> -
> -		if (crash_base == 0) {
> -			pr_warn("crashkernel: couldn't allocate %lldKB\n",
> -				crash_size >> 10);
> -			return;
> -		}
> -	} else {
> -		/* User specifies base address explicitly. */
> -		if (!memblock_is_region_memory(crash_base, crash_size)) {
> -			pr_warn("crashkernel: requested region is not memory\n");
> -			return;
> -		}
> -
> -		if (memblock_is_region_reserved(crash_base, crash_size)) {
> -			pr_warn("crashkernel: requested region is reserved\n");
> -			return;
> -		}
> -
> +	if (crash_base) {
> +		search_start = crash_base;
> +		search_end = crash_base + crash_size;
> +	}
>   
> -		if (!IS_ALIGNED(crash_base, PMD_SIZE)) {
> -			pr_warn("crashkernel: requested region is misaligned\n");
> -			return;
> -		}
> +	/*
> +	 * Current riscv boot protocol requires 2MB alignment for
> +	 * RV64 and 4MB alignment for RV32 (hugepage size)
> +	 */
> +	crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE,
> +					       search_start, search_end);
> +	if (crash_base == 0) {
> +		pr_warn("crashkernel: couldn't allocate %lldKB\n",
> +			crash_size >> 10);
> +		return;
>   	}
> -	memblock_reserve(crash_base, crash_size);
>   
>   	pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n",
>   		crash_base, crash_base + crash_size, crash_size >> 20);
> diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
> index ff0f9e838916..3d9efee0f43c 100644
> --- a/arch/s390/kernel/setup.c
> +++ b/arch/s390/kernel/setup.c
> @@ -626,8 +626,9 @@ static void __init reserve_crashkernel(void)
>   			return;
>   		}
>   		low = crash_base ?: low;
> -		crash_base = memblock_find_in_range(low, high, crash_size,
> -						    KEXEC_CRASH_MEM_ALIGN);
> +		crash_base = memblock_phys_alloc_range(crash_size,
> +						       KEXEC_CRASH_MEM_ALIGN,
> +						       low, high);
>   	}
>   
>   	if (!crash_base) {
> @@ -636,14 +637,15 @@ static void __init reserve_crashkernel(void)
>   		return;
>   	}
>   
> -	if (register_memory_notifier(&kdump_mem_nb))
> +	if (register_memory_notifier(&kdump_mem_nb)) {
> +		memblock_free(crash_base, crash_size);
>   		return;
> +	}
>   
>   	if (!OLDMEM_BASE && MACHINE_IS_VM)
>   		diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
>   	crashk_res.start = crash_base;
>   	crashk_res.end = crash_base + crash_size - 1;
> -	memblock_remove(crash_base, crash_size);
>   	pr_info("Reserving %lluMB of memory at %lluMB "
>   		"for crashkernel (System RAM: %luMB)\n",
>   		crash_size >> 20, crash_base >> 20,
> diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
> index 294ed4392a0e..10562885f5fc 100644
> --- a/arch/x86/kernel/aperture_64.c
> +++ b/arch/x86/kernel/aperture_64.c
> @@ -109,14 +109,13 @@ static u32 __init allocate_aperture(void)
>   	 * memory. Unfortunately we cannot move it up because that would
>   	 * make the IOMMU useless.
>   	 */
> -	addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR,
> -				      aper_size, aper_size);
> +	addr = memblock_phys_alloc_range(aper_size, aper_size,
> +					 GART_MIN_ADDR, GART_MAX_ADDR);
>   	if (!addr) {
>   		pr_err("Cannot allocate aperture memory hole [mem %#010lx-%#010lx] (%uKB)\n",
>   		       addr, addr + aper_size - 1, aper_size >> 10);
>   		return 0;
>   	}
> -	memblock_reserve(addr, aper_size);
>   	pr_info("Mapping aperture over RAM [mem %#010lx-%#010lx] (%uKB)\n",
>   		addr, addr + aper_size - 1, aper_size >> 10);
>   	register_nosave_region(addr >> PAGE_SHIFT,
> diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
> index 75ef19aa8903..23a14d82e783 100644
> --- a/arch/x86/mm/init.c
> +++ b/arch/x86/mm/init.c
> @@ -127,14 +127,12 @@ __ref void *alloc_low_pages(unsigned int num)
>   		unsigned long ret = 0;
>   
>   		if (min_pfn_mapped < max_pfn_mapped) {
> -			ret = memblock_find_in_range(
> +			ret = memblock_phys_alloc_range(
> +					PAGE_SIZE * num, PAGE_SIZE,
>   					min_pfn_mapped << PAGE_SHIFT,
> -					max_pfn_mapped << PAGE_SHIFT,
> -					PAGE_SIZE * num , PAGE_SIZE);
> +					max_pfn_mapped << PAGE_SHIFT);
>   		}
> -		if (ret)
> -			memblock_reserve(ret, PAGE_SIZE * num);
> -		else if (can_use_brk_pgt)
> +		if (!ret && can_use_brk_pgt)
>   			ret = __pa(extend_brk(PAGE_SIZE * num, PAGE_SIZE));
>   
>   		if (!ret)
> @@ -610,8 +608,17 @@ static void __init memory_map_top_down(unsigned long map_start,
>   	unsigned long addr;
>   	unsigned long mapped_ram_size = 0;
>   
> -	/* xen has big range in reserved near end of ram, skip it at first.*/
> -	addr = memblock_find_in_range(map_start, map_end, PMD_SIZE, PMD_SIZE);
> +	/*
> +	 * Systems that have many reserved areas near top of the memory,
> +	 * e.g. QEMU with less than 1G RAM and EFI enabled, or Xen, will
> +	 * require lots of 4K mappings which may exhaust pgt_buf.
> +	 * Start with top-most PMD_SIZE range aligned at PMD_SIZE to ensure
> +	 * there is enough mapped memory that can be allocated from
> +	 * memblock.
> +	 */
> +	addr = memblock_phys_alloc_range(PMD_SIZE, PMD_SIZE, map_start,
> +					 map_end);
> +	memblock_free(addr, PMD_SIZE);
>   	real_end = addr + PMD_SIZE;
>   
>   	/* step_size need to be small so pgt_buf from BRK could cover it */
> diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
> index e94da744386f..a1b5c71099e6 100644
> --- a/arch/x86/mm/numa.c
> +++ b/arch/x86/mm/numa.c
> @@ -376,15 +376,14 @@ static int __init numa_alloc_distance(void)
>   	cnt++;
>   	size = cnt * cnt * sizeof(numa_distance[0]);
>   
> -	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
> -				      size, PAGE_SIZE);
> +	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0,
> +					 PFN_PHYS(max_pfn_mapped));
>   	if (!phys) {
>   		pr_warn("Warning: can't allocate distance table!\n");
>   		/* don't retry until explicitly reset */
>   		numa_distance = (void *)1LU;
>   		return -ENOMEM;
>   	}
> -	memblock_reserve(phys, size);
>   
>   	numa_distance = __va(phys);
>   	numa_distance_cnt = cnt;
> diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
> index 87d77cc52f86..737491b13728 100644
> --- a/arch/x86/mm/numa_emulation.c
> +++ b/arch/x86/mm/numa_emulation.c
> @@ -447,13 +447,12 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
>   	if (numa_dist_cnt) {
>   		u64 phys;
>   
> -		phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
> -					      phys_size, PAGE_SIZE);
> +		phys = memblock_phys_alloc_range(phys_size, PAGE_SIZE, 0,
> +						 PFN_PHYS(max_pfn_mapped));
>   		if (!phys) {
>   			pr_warn("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
>   			goto no_emu;
>   		}
> -		memblock_reserve(phys, phys_size);
>   		phys_dist = __va(phys);
>   
>   		for (i = 0; i < numa_dist_cnt; i++)
> diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
> index 6534c92d0f83..31b5856010cb 100644
> --- a/arch/x86/realmode/init.c
> +++ b/arch/x86/realmode/init.c
> @@ -28,7 +28,7 @@ void __init reserve_real_mode(void)
>   	WARN_ON(slab_is_available());
>   
>   	/* Has to be under 1M so we can execute real-mode AP code. */
> -	mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
> +	mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
>   	if (!mem)
>   		pr_info("No sub-1M memory is available for the trampoline\n");
>   	else
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index a37a1532a575..f9383736fa0f 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -583,8 +583,8 @@ void __init acpi_table_upgrade(void)
>   	}
>   
>   	acpi_tables_addr =
> -		memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
> -				       all_tables_size, PAGE_SIZE);
> +		memblock_phys_alloc_range(all_tables_size, PAGE_SIZE,
> +					  0, ACPI_TABLE_UPGRADE_MAX_PHYS);
>   	if (!acpi_tables_addr) {
>   		WARN_ON(1);
>   		return;
> @@ -599,7 +599,6 @@ void __init acpi_table_upgrade(void)
>   	 * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
>   	 * works fine.
>   	 */
> -	memblock_reserve(acpi_tables_addr, all_tables_size);
>   	arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
>   
>   	/*
> diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
> index 4cc4e117727d..46c503486e96 100644
> --- a/drivers/base/arch_numa.c
> +++ b/drivers/base/arch_numa.c
> @@ -279,13 +279,10 @@ static int __init numa_alloc_distance(void)
>   	int i, j;
>   
>   	size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
> -	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
> -				      size, PAGE_SIZE);
> +	phys = memblock_phys_alloc_range(size, PAGE_SIZE, 0, PFN_PHYS(max_pfn));
>   	if (WARN_ON(!phys))
>   		return -ENOMEM;
>   
> -	memblock_reserve(phys, size);
> -
>   	numa_distance = __va(phys);
>   	numa_distance_cnt = nr_node_ids;
>   
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> index fd3964d24224..59c1390cdf42 100644
> --- a/drivers/of/of_reserved_mem.c
> +++ b/drivers/of/of_reserved_mem.c
> @@ -33,18 +33,22 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
>   	phys_addr_t *res_base)
>   {
>   	phys_addr_t base;
> +	int err = 0;
>   
>   	end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end;
>   	align = !align ? SMP_CACHE_BYTES : align;
> -	base = memblock_find_in_range(start, end, size, align);
> +	base = memblock_phys_alloc_range(size, align, start, end);
>   	if (!base)
>   		return -ENOMEM;
>   
>   	*res_base = base;
> -	if (nomap)
> -		return memblock_mark_nomap(base, size);
> +	if (nomap) {
> +		err = memblock_mark_nomap(base, size);
> +		if (err)
> +			memblock_free(base, size);
> +	}
>   
> -	return memblock_reserve(base, size);
> +	return err;
>   }
>   
>   /*
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index 4a53c3ca86bd..b066024c62e3 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -99,8 +99,6 @@ void memblock_discard(void);
>   static inline void memblock_discard(void) {}
>   #endif
>   
> -phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
> -				   phys_addr_t size, phys_addr_t align);
>   void memblock_allow_resize(void);
>   int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
>   int memblock_add(phys_addr_t base, phys_addr_t size);
> diff --git a/mm/memblock.c b/mm/memblock.c
> index de7b553baa50..28a813d9e955 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -315,7 +315,7 @@ static phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
>    * Return:
>    * Found address on success, 0 on failure.
>    */
> -phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
> +static phys_addr_t __init_memblock memblock_find_in_range(phys_addr_t start,
>   					phys_addr_t end, phys_addr_t size,
>   					phys_addr_t align)
>   {
> 
> base-commit: ff1176468d368232b684f75e82563369208bc371
> 



From robh at kernel.org  Mon Aug 16 11:26:49 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 16 Aug 2021 13:26:49 -0500
Subject: [PATCH v7 08/10] arm64: dts: HiSilicon: Add support for HiKey 970
 PCIe controller hardware
In-Reply-To: <e483ba44ed3d70e1f4ca899bb287fa38ee8a2876.1626855713.git.mchehab+huawei@kernel.org>
References: <cover.1626855713.git.mchehab+huawei@kernel.org>
 <e483ba44ed3d70e1f4ca899bb287fa38ee8a2876.1626855713.git.mchehab+huawei@kernel.org>
Message-ID: <CAL_JsqLJkqr_UhDGa9duPxx5mXxcp2Ju4Xv2gH6vdru6zQY9OQ@mail.gmail.com>

On Wed, Jul 21, 2021 at 3:39 AM Mauro Carvalho Chehab
<mchehab+huawei at kernel.org> wrote:
>
> From: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
>
> Add DTS bindings for the HiKey 970 board's PCIe hardware.
>
> Co-developed-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
> ---
>  arch/arm64/boot/dts/hisilicon/hi3670.dtsi     | 71 +++++++++++++++++++
>  .../boot/dts/hisilicon/hikey970-pmic.dtsi     |  1 -
>  drivers/pci/controller/dwc/pcie-kirin.c       | 12 ----
>  3 files changed, 71 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/hisilicon/hi3670.dtsi b/arch/arm64/boot/dts/hisilicon/hi3670.dtsi
> index 1f228612192c..6dfcfcfeedae 100644
> --- a/arch/arm64/boot/dts/hisilicon/hi3670.dtsi
> +++ b/arch/arm64/boot/dts/hisilicon/hi3670.dtsi
> @@ -177,6 +177,12 @@ sctrl: sctrl at fff0a000 {
>                         #clock-cells = <1>;
>                 };
>
> +               pmctrl: pmctrl at fff31000 {
> +                       compatible = "hisilicon,hi3670-pmctrl", "syscon";
> +                       reg = <0x0 0xfff31000 0x0 0x1000>;
> +                       #clock-cells = <1>;
> +               };
> +
>                 iomcu: iomcu at ffd7e000 {
>                         compatible = "hisilicon,hi3670-iomcu", "syscon";
>                         reg = <0x0 0xffd7e000 0x0 0x1000>;
> @@ -660,6 +666,71 @@ gpio28: gpio at fff1d000 {
>                         clock-names = "apb_pclk";
>                 };
>
> +               its_pcie: interrupt-controller at f4000000 {
> +                       compatible = "arm,gic-v3-its";
> +                       msi-controller;
> +                       reg = <0x0 0xf5100000 0x0 0x100000>;

How does this h/w have a GIC-400 (which is GICv2) and then a GIC v3 ITS?

> +               };
> +
> +               pcie_phy: pcie-phy at fc000000 {
> +                       compatible = "hisilicon,hi970-pcie-phy";
> +                       reg = <0x0 0xfc000000 0x0 0x80000>;
> +
> +                       phy-supply = <&ldo33>;
> +
> +                       clocks = <&crg_ctrl HI3670_CLK_GATE_PCIEPHY_REF>,
> +                                <&crg_ctrl HI3670_CLK_GATE_PCIEAUX>,
> +                                <&crg_ctrl HI3670_PCLK_GATE_PCIE_PHY>,
> +                                <&crg_ctrl HI3670_PCLK_GATE_PCIE_SYS>,
> +                                <&crg_ctrl HI3670_ACLK_GATE_PCIE>;
> +                       clock-names = "phy_ref", "aux",
> +                                     "apb_phy", "apb_sys",
> +                                     "aclk";
> +
> +                       reset-gpios = <&gpio7 0 0 >, <&gpio25 2 0 >,
> +                                     <&gpio3 1 0 >, <&gpio27 4 0 >;
> +
> +                       clkreq-gpios = <&gpio20 6 0 >, <&gpio27 3 0 >,
> +                                      <&gpio17 0 0 >;
> +
> +                       /* vboost iboost pre post main */
> +                       hisilicon,eye-diagram-param = <0xFFFFFFFF 0xFFFFFFFF
> +                                                      0xFFFFFFFF 0xFFFFFFFF
> +                                                      0xFFFFFFFF>;
> +
> +                       #phy-cells = <0>;
> +               };
> +
> +               pcie at f4000000 {
> +                       compatible = "hisilicon,kirin970-pcie";
> +                       reg = <0x0 0xf4000000 0x0 0x1000000>,
> +                             <0x0 0xfc180000 0x0 0x1000>,
> +                             <0x0 0xf5000000 0x0 0x2000>;
> +                       reg-names = "dbi", "apb", "config";
> +                       bus-range = <0x0  0x1>;
> +                       msi-parent = <&its_pcie>;

This means the PCI host doesn't have a MSI controller...

> +                       #address-cells = <3>;
> +                       #size-cells = <2>;
> +                       device_type = "pci";
> +                       phys = <&pcie_phy>;
> +                       ranges = <0x02000000 0x0 0x00000000
> +                                 0x0 0xf6000000
> +                                 0x0 0x02000000>;
> +                       num-lanes = <1>;
> +                       #interrupt-cells = <1>;
> +                       interrupts = <0 283 4>;
> +                       interrupt-names = "msi";

But then this says it does...


From p.yadav at ti.com  Mon Aug 16 11:28:38 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Mon, 16 Aug 2021 23:58:38 +0530
Subject: [PATCH v2 05/35] mtd: spi-nor: Introduce Manufacturer ID
 collisions driver
In-Reply-To: <20210727045222.905056-6-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-6-tudor.ambarus@microchip.com>
Message-ID: <20210816182836.oidwlrgoomb2f5kd@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> Some manufacturers completely ignore the manufacturer's identification code
> standard (JEP106) and do not define the manufacturer ID continuation
> scheme. This will result in manufacturer ID collisions.
> 
> An an example, JEP106BA requires Boya that it's manufacturer ID to be
> preceded by 8 continuation codes. Boya's identification code must be:
> 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x68. But Boya ignores the
> continuation scheme and its ID collides with the manufacturer defined in
> bank one: Convex Computer.
> 
> Introduce the manuf-id-collisions driver in order to address ID collisions
> between manufacturers. flash_info entries will be added in a first come,
> first served manner. Differentiation between flashes will be done at
> runtime if possible. Where runtime differentiation is not possible, new
> compatibles will be introduced, but this will be done as a last resort.
> Every new flash addition that define the SFDP tables, should dump its SFDP
> tables in the patch's comment section below the --- line, so that we can
> reference it in case of collisions.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 11:43:50 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:13:50 +0530
Subject: [PATCH v2 06/35] mtd: spi-nor: manuf-id-collisions: Add support
 for xt25f128b
In-Reply-To: <20210727045222.905056-7-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-7-tudor.ambarus@microchip.com>
Message-ID: <20210816184348.sabnihh7b2sf34s4@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> Flash does not support continuation codes and may collide with a flash
> of other manufacturer, Intersil being an example .
Nitpick:                                          ^ drop the extra space

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
> 0000000 4653 5044 0100 ff01 0000 0901 0030 ff00
> 0000010 000b 0301 0060 ff00 ffff ffff ffff ffff
> 0000020 ffff ffff ffff ffff ffff ffff ffff ffff
> 0000030 20e5 fff1 ffff 07ff eb44 6b08 3b08 bb42
> 0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
> 0000050 d810 ff00 ffff ffff ffff ffff ffff ffff
> 0000060 3600 2700 f99f 6477 e8d9 ffff

I think you should list all the other sysfs parameters as well. See 
Michael's comments on patch 35.

> 
>  drivers/mtd/spi-nor/manuf-id-collisions.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
> index bf7dba34f018..db31470ebf6a 100644
> --- a/drivers/mtd/spi-nor/manuf-id-collisions.c
> +++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
> @@ -13,6 +13,10 @@ static const struct flash_info id_collision_parts[] = {
>  	{ "by25q128as", INFO(0x684018, 0, 64 * 1024, 256, SPI_NOR_SKIP_SFDP |
>  			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
> +
> +	/* XTX (XTX Technology Limited) */
> +	{ "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
> +			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },

I have not went and checked, but I assume these two flags can't be 
discovered via SFDP?

>  };
>  
>  const struct spi_nor_manufacturer spi_nor_manuf_id_collisions = {
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 11:45:10 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:15:10 +0530
Subject: [PATCH v2 07/35] mtd: spi-nor: manuf-id-collisions: Add support
 for xm25qh64c
In-Reply-To: <20210727045222.905056-8-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-8-tudor.ambarus@microchip.com>
Message-ID: <20210816184508.jbgix66frh6m3dqs@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> Flash ignores the manufacturer continuation codes and is likely to
> collide with other manufacturers flashes.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
> Do not apply without the SFDP tables hexdump.

... and all the other sysfs params that we usually ask for. See 
Michael's replies on patch 35.

> 
>  drivers/mtd/spi-nor/manuf-id-collisions.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
> index db31470ebf6a..f3ba00d17c68 100644
> --- a/drivers/mtd/spi-nor/manuf-id-collisions.c
> +++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
> @@ -14,6 +14,9 @@ static const struct flash_info id_collision_parts[] = {
>  			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
>  
> +	/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */
> +	{ "xm25qh64c", INFO(0x204017, 0, 64 * 1024, 128, SPI_NOR_PARSE_SFDP) },
> +
>  	/* XTX (XTX Technology Limited) */
>  	{ "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
>  			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 11:54:48 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:24:48 +0530
Subject: [PATCH v2 08/35] mtd: spi-nor: core: Introduce the ate_init() hook
In-Reply-To: <20210727045222.905056-9-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-9-tudor.ambarus@microchip.com>
Message-ID: <20210816185446.topxrgwmvpt6n4ct@ti.com>

Hi Tudor,

> Subject: [PATCH v2 08/35] mtd: spi-nor: core: Introduce the ate_init() hook
                                                              ^^^^^^^^
You ate the 'l' ;-)

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> The goal is to get rid of the spaghetti way of initializing the flash
> parameters and settings. late_init() hook will be used to tweak various
> parameters that are not defined by the SFDP standard. Can be used by
> non SFDP compliant flashes in order to tweak flash parameters that
> are not/shouldn't be handled by the flash_info flags. Will replace the
> default_init() hook.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c | 15 +++++++++++----
>  drivers/mtd/spi-nor/core.h |  8 ++++++++
>  2 files changed, 19 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index d30c8f350dc1..15ccc9994215 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -2667,11 +2667,18 @@ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
>   * spi_nor_late_init_params() - Late initialization of default flash parameters.
>   * @nor:	pointer to a 'struct spi_nor'
>   *
> - * Used to set default flash parameters and settings when the ->default_init()
> - * hook or the SFDP parser let voids.
> + * Used to tweak various flash parameters that are not defined by the SFDP
> + * standard. Can be used by non SFDP compliant flashes in order to tweek flash
> + * parameters that are not handled by the flash_info flags.

What about flashes that do have the SFDP table, but not all of them? For 
example, the Micron MT35XU512ABA flash currently uses the post_sfdp() 
hook to populate 8D-8D-8D fast read settings, command extension type, 
etc. These are supposed to be obtained from the xSPI Profile 1.0 table 
(like we do for Spansion/Cypress S28HS512T). But the flash does not 
populate this table. Should these go into the late_init() hook or the 
post_sfdp() hook?

FWIW, I think it should go into late_init(). post_sfdp() should only be 
used for correcting info obtained from the SFDP table. For populating 
the info not present in SFDP at all, late_init() should be used.

Thoughts?

>   */
>  static void spi_nor_late_init_params(struct spi_nor *nor)
>  {
> +	if (nor->manufacturer && nor->manufacturer->late_init)
> +		nor->manufacturer->late_init(nor);
> +
> +	if (nor->info->late_init)
> +		nor->info->late_init(nor);

Manufacturer late_init goes before flash late_init. Makes sense.

> +
>  	/*
>  	 * NOR protection support. When locking_ops are not provided, we pick
>  	 * the default ones.
> @@ -2713,8 +2720,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
>   *    wrong).
>   *		spi_nor_post_sfdp_fixups()
>   *
> - * 5/ Late default flash parameters initialization, used when the
> - * ->default_init() hook or the SFDP parser do not set specific params.
> + * 5/ Late flash parameters initialization, used to initialize flash
> + * parameters that are not declared in the JESD216 SFDP standard.
>   *		spi_nor_late_init_params()
>   */
>  static int spi_nor_init_params(struct spi_nor *nor)
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index e9896cd60695..13d5c5edfd27 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -391,6 +391,11 @@ struct flash_info {
>  
>  	/* Part specific fixup hooks. */
>  	const struct spi_nor_fixups *fixups;
> +	/*
> +	 * Init flash parameters that are not declared in the JESD216 SFDP
> +	 * standard.
> +	 */
> +	void (* const late_init)(struct spi_nor *nor);
>  };
>  
>  /* Used when the "_ext_id" is two bytes at most */
> @@ -457,12 +462,15 @@ struct flash_info {
>   * @parts: array of parts supported by this manufacturer
>   * @nparts: number of entries in the parts array
>   * @fixups: hooks called at various points in time during spi_nor_scan()
> + * @late_init: used to init flash parameters that are not declared in the
> + *             JESD216 SFDP standard.
>   */
>  struct spi_nor_manufacturer {
>  	const char *name;
>  	const struct flash_info *parts;
>  	unsigned int nparts;
>  	const struct spi_nor_fixups *fixups;
> +	void (* const late_init)(struct spi_nor *nor);

The patch looks good to me other than the comments above.

>  };
>  
>  /**
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From daniel.lezcano at linaro.org  Mon Aug 16 11:56:54 2021
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 16 Aug 2021 20:56:54 +0200
Subject: [PATCH v5 2/3] thermal: mediatek: Add LVTS drivers for SoC
 theraml zones
In-Reply-To: <1f92b245537d6390b7b2bde62ce8b99a3df9d445.camel@mediatek.com>
References: <20210617114707.10618-1-ben.tseng@mediatek.com>
 <20210617114707.10618-3-ben.tseng@mediatek.com>
 <06b1804c-4675-2997-8c5c-bcdffbcfc4a1@linaro.org>
 <1f92b245537d6390b7b2bde62ce8b99a3df9d445.camel@mediatek.com>
Message-ID: <8a38b9fe-0448-3ddc-9ffc-c43137b5ecaa@linaro.org>


Hi Ben,

On 23/07/2021 08:17, Ben Tseng wrote:
> On Mon, 2021-06-21 at 13:26 +0200, Daniel Lezcano wrote:
>> On 17/06/2021 13:47, Ben Tseng wrote:
>>> From: Michael Kao <michael.kao at mediatek.com>
>>>
>>> Add a LVTS (Low voltage thermal sensor) driver to report junction
>>> temperatures in Mediatek SoC and register the maximum temperature
>>> of sensors and each sensor as a thermal zone.
>>
>> I think we already talked about that. We don't want a thermal sensor
>> driver to aggregate the temperatures but create some kindof virtual
>> sensor with a property (min, max, avg, ...) which is usable by
>> anyone.
>>
>> [ ... ]
>>
>>
>>
> 
> Dear Daniel,
> 
> Sorry for the late reply.

sorry too, missed to answer. Another thread pointed to this one and I
figured out I forgot to answer.

> After survey ,I'm not sure whether the patch[1] is the architecture of
> virtual thermal sensor which you commented.

Ah, yes that is kind of what it would be requested but really generic so
anyone can use it.

> Or, is there any existing framework on mainline already support virtual
> sensor?

No unfortunately, it is not done [yet].

> Could you help to provide reference to us?

Ok, we had this discussion several times on the mailing list and at the
different events like the Linux Plumbers conference. But I was not able
to find out a pointer.

Basically the idea is simple, we don't want drivers doing weird things
in their get_temp callback. This callback must return the temperature
associated to a physical sensor in a 1:1 manner.

However, some people want to define a thermal zone but with an
aggregation of different sensors.

At this point, we are unsure how to do that.

Having a virtual sensor would be more adequate as it won't impact
anything except the DT for a configuration. And we can make it to evolve
without having to change all the thermal framework internals.

>From a DT point of view, a virtual sensor device cuold have phandles to
the different sensors and let's say a property telling what do to (avg,
min, max, ...). The thermal zone will point to the virtual device.

In the driver itself, the get_temp will just call get_temp of all the
sensors and do the operation specified in the property.

With that, the drivers stay consistent and we have the flexibility to do
whatever we want.

Does it make sense ?



-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From p.yadav at ti.com  Mon Aug 16 12:06:31 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:36:31 +0530
Subject: [PATCH v2 09/35] mtd: spi-nor: atmel: Use flash late_init() for
 locking
In-Reply-To: <20210727045222.905056-10-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-10-tudor.ambarus@microchip.com>
Message-ID: <20210816190629.3kg4cbf5d7h7gyk5@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> Locking is not described in JESD216 SFDP standard, place the locking
> init in late_init().

You are chaning the order of setting the locking ops here. Earlier, they 
were set before we parsed SFDP. Now they are set after we parse SFDP. 
Though I don't see it making much of a difference.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/atmel.c | 30 +++++++++++-------------------
>  1 file changed, 11 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c
> index 1fea5cab492c..b937ef734e55 100644
> --- a/drivers/mtd/spi-nor/atmel.c
> +++ b/drivers/mtd/spi-nor/atmel.c
> @@ -48,15 +48,11 @@ static const struct spi_nor_locking_ops atmel_at25fs_locking_ops = {
>  	.is_locked = atmel_at25fs_is_locked,
>  };
>  
> -static void atmel_at25fs_default_init(struct spi_nor *nor)
> +static void atmel_at25fs_late_init(struct spi_nor *nor)
>  {
>  	nor->params->locking_ops = &atmel_at25fs_locking_ops;
>  }
>  
> -static const struct spi_nor_fixups atmel_at25fs_fixups = {
> -	.default_init = atmel_at25fs_default_init,
> -};
> -
>  /**
>   * atmel_set_global_protection - Do a Global Protect or Unprotect command
>   * @nor:	pointer to 'struct spi_nor'
> @@ -146,34 +142,30 @@ static const struct spi_nor_locking_ops atmel_global_protection_ops = {
>  	.is_locked = atmel_is_global_protected,
>  };
>  
> -static void atmel_global_protection_default_init(struct spi_nor *nor)
> +static void atmel_global_protection_late_init(struct spi_nor *nor)
>  {
>  	nor->params->locking_ops = &atmel_global_protection_ops;
>  }
>  
> -static const struct spi_nor_fixups atmel_global_protection_fixups = {
> -	.default_init = atmel_global_protection_default_init,
> -};
> -
>  static const struct flash_info atmel_parts[] = {
>  	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
>  	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K | SPI_NOR_HAS_LOCK)
> -		.fixups = &atmel_at25fs_fixups },
> +		.late_init = atmel_at25fs_late_init },
>  	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K | SPI_NOR_HAS_LOCK)
> -		.fixups = &atmel_at25fs_fixups },
> +		.late_init = atmel_at25fs_late_init },
>  
>  	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8,
>  			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
> -			.fixups = &atmel_global_protection_fixups },
> +		.late_init = atmel_global_protection_late_init },

Won't you be better off setting this in the manufacturer late_init()? It 
seems common for most atmel flashes.

Of course, this would cause a problem for atmel flashes that don't have 
this at all, since we would set locking for those as well. But I think 
we can avoid that by checking for SNOR_F_HAS_LOCK in 
spi_nor_register_locking_ops().

>  	{ "at25df321",  INFO(0x1f4700, 0, 64 * 1024,  64,
>  			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
> -			.fixups = &atmel_global_protection_fixups },
> +		.late_init = atmel_global_protection_late_init },
>  	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64,
>  			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
> -			.fixups = &atmel_global_protection_fixups },
> +		.late_init = atmel_global_protection_late_init },
>  	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128,
>  			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
> -			.fixups = &atmel_global_protection_fixups },
> +		.late_init = atmel_global_protection_late_init },
>  
>  	{ "at25sl321",	INFO(0x1f4216, 0, 64 * 1024, 64,
>  			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> @@ -181,13 +173,13 @@ static const struct flash_info atmel_parts[] = {
>  	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
>  	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16,
>  			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
> -			.fixups = &atmel_global_protection_fixups },
> +		.late_init = atmel_global_protection_late_init },
>  	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32,
>  			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
> -			.fixups = &atmel_global_protection_fixups },
> +		.late_init = atmel_global_protection_late_init },
>  	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64,
>  			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
> -			.fixups = &atmel_global_protection_fixups },
> +		.late_init = atmel_global_protection_late_init },
>  
>  	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
>  };
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 12:09:30 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:39:30 +0530
Subject: [PATCH v2 10/35] mtd: spi-nor: sst: Use flash late_init() for
 locking
In-Reply-To: <20210727045222.905056-11-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-11-tudor.ambarus@microchip.com>
Message-ID: <20210816190928.kvzex5r6ml77uigs@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> Locking ops are not discoverable via SFDP, use late_init() call.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

One question though. Have you tested these flashes (this one and the 
ones in the previous patch) to make sure you are not causing any 
regressions? While I don't see anything wrong with the patches, it would 
be good to have some test reports.

> ---
>  drivers/mtd/spi-nor/sst.c | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
> index 980f4c09c91d..29d100febdbf 100644
> --- a/drivers/mtd/spi-nor/sst.c
> +++ b/drivers/mtd/spi-nor/sst.c
> @@ -46,15 +46,11 @@ static const struct spi_nor_locking_ops sst26vf_locking_ops = {
>  	.is_locked = sst26vf_is_locked,
>  };
>  
> -static void sst26vf_default_init(struct spi_nor *nor)
> +static void sst26vf_late_init(struct spi_nor *nor)
>  {
>  	nor->params->locking_ops = &sst26vf_locking_ops;
>  }
>  
> -static const struct spi_nor_fixups sst26vf_fixups = {
> -	.default_init = sst26vf_default_init,
> -};
> -
>  static const struct flash_info sst_parts[] = {
>  	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
>  	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8,
> @@ -88,7 +84,7 @@ static const struct flash_info sst_parts[] = {
>  	{ "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128,
>  			      SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			      SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
> -		.fixups = &sst26vf_fixups },
> +		.late_init = sst26vf_late_init},
>  };
>  
>  static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 12:17:46 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:47:46 +0530
Subject: [PATCH v2 11/35] mtd: spi-nor: winbond: Use manufacturer
 late_init() for OTP ops
In-Reply-To: <20210727045222.905056-12-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-12-tudor.ambarus@microchip.com>
Message-ID: <20210816191744.k6ufbgrrwh6whhnc@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> OTP info is not yet discoverable via SFDP, use late_init() to init
> the OTP ops.

What do you mean by the "yet"? Does it mean that OTP info is planned to 
be added to the next SFDP version? Or does it mean that it is possible 
to discover it via SFDP but we just don't support it yet?

If it is neither and it just means "SFDP does not mention OTP at all", 
like it is for locking, then you should just drop the "yet". I know this 
is very nitpicky but it just caught my eye.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/winbond.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
> index 96573f61caf5..6be45d2291c6 100644
> --- a/drivers/mtd/spi-nor/winbond.c
> +++ b/drivers/mtd/spi-nor/winbond.c
> @@ -147,17 +147,22 @@ static const struct spi_nor_otp_ops winbond_otp_ops = {
>  static void winbond_default_init(struct spi_nor *nor)
>  {
>  	nor->params->set_4byte_addr_mode = winbond_set_4byte_addr_mode;

Why not move this to late_init() as well?

> -	if (nor->params->otp.org->n_regions)
> -		nor->params->otp.ops = &winbond_otp_ops;
>  }
>  
>  static const struct spi_nor_fixups winbond_fixups = {
>  	.default_init = winbond_default_init,
>  };
>  
> +static void winbond_late_init(struct spi_nor *nor)
> +{
> +	if (nor->params->otp.org->n_regions)
> +		nor->params->otp.ops = &winbond_otp_ops;
> +}
> +
>  const struct spi_nor_manufacturer spi_nor_winbond = {
>  	.name = "winbond",
>  	.parts = winbond_parts,
>  	.nparts = ARRAY_SIZE(winbond_parts),
>  	.fixups = &winbond_fixups,
> +	.late_init = winbond_late_init,
>  };
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 12:19:10 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:49:10 +0530
Subject: [PATCH v2 12/35] mtd: spi-nor: xilinx: Use manufacturer
 late_init() to set setup method
In-Reply-To: <20210727045222.905056-13-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-13-tudor.ambarus@microchip.com>
Message-ID: <20210816191908.bglwztlx7xm2rmdu@ti.com>

On 27/07/21 07:51AM, Tudor Ambarus wrote:
> post_sfdp was misleading in this case, as SFDP is not supported by
> xilinx. Plus, there's no fixup here, just setting the correct
> setup method, as required by xilinx parts.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

> ---
>  drivers/mtd/spi-nor/xilinx.c | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c
> index 1138bdbf4199..a573c3cde414 100644
> --- a/drivers/mtd/spi-nor/xilinx.c
> +++ b/drivers/mtd/spi-nor/xilinx.c
> @@ -77,18 +77,14 @@ static int xilinx_nor_setup(struct spi_nor *nor,
>  	return 0;
>  }
>  
> -static void xilinx_post_sfdp_fixups(struct spi_nor *nor)
> +static void xilinx_late_init(struct spi_nor *nor)
>  {
>  	nor->params->setup = xilinx_nor_setup;
>  }
>  
> -static const struct spi_nor_fixups xilinx_fixups = {
> -	.post_sfdp = xilinx_post_sfdp_fixups,
> -};
> -
>  const struct spi_nor_manufacturer spi_nor_xilinx = {
>  	.name = "xilinx",
>  	.parts = xilinx_parts,
>  	.nparts = ARRAY_SIZE(xilinx_parts),
> -	.fixups = &xilinx_fixups,
> +	.late_init = xilinx_late_init,
>  };
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 12:20:26 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:50:26 +0530
Subject: [PATCH v2 13/35] mtd: spi-nor: sst: Use manufacturer late_init()
 to set _write()
In-Reply-To: <20210727045222.905056-14-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-14-tudor.ambarus@microchip.com>
Message-ID: <20210816192024.by7vo4ox6ewn4qnf@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Setting the correct nor->mtd._write in a fixup hook was misleading,
> since this is not a fixup, just a specific setting for SST, that differs
> from the SPI NOR core default init.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

> ---
>  drivers/mtd/spi-nor/sst.c | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
> index 29d100febdbf..eeb10766b70e 100644
> --- a/drivers/mtd/spi-nor/sst.c
> +++ b/drivers/mtd/spi-nor/sst.c
> @@ -173,19 +173,15 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
>  	return ret;
>  }
>  
> -static void sst_post_sfdp_fixups(struct spi_nor *nor)
> +static void sst_late_init(struct spi_nor *nor)
>  {
>  	if (nor->info->flags & SST_WRITE)
>  		nor->mtd._write = sst_write;
>  }
>  
> -static const struct spi_nor_fixups sst_fixups = {
> -	.post_sfdp = sst_post_sfdp_fixups,
> -};
> -
>  const struct spi_nor_manufacturer spi_nor_sst = {
>  	.name = "sst",
>  	.parts = sst_parts,
>  	.nparts = ARRAY_SIZE(sst_parts),
> -	.fixups = &sst_fixups,
> +	.late_init = sst_late_init,
>  };
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 12:22:20 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 00:52:20 +0530
Subject: [PATCH v2 14/35] mtd: spi-nor: spansion: Use manufacturer
 late_init()
In-Reply-To: <20210727045222.905056-15-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-15-tudor.ambarus@microchip.com>
Message-ID: <20210816192218.lv367at2tjeu2rpj@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> spansion_post_sfdp_fixups() was called regardless if the flash defined
> SFDP tables or not. A better place for this kind of parameters init is
> in manufacturer's late_init() hook. post_sfdp() should be called only
> when SFDP is defined. No functional change in this patch.
> 
> Instead of doing the 4b opcodes settings at manufacturer level, thus
> also for every flash that will be introduced, this should be done
> just where it is needed, per flash. I'll let this for other patch.

Yes, agreed.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

> ---
>  drivers/mtd/spi-nor/spansion.c | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
> index ee82dcd75310..aad7170768b4 100644
> --- a/drivers/mtd/spi-nor/spansion.c
> +++ b/drivers/mtd/spi-nor/spansion.c
> @@ -276,7 +276,7 @@ static const struct flash_info spansion_parts[] = {
>  	},
>  };
>  
> -static void spansion_post_sfdp_fixups(struct spi_nor *nor)
> +static void spansion_late_init(struct spi_nor *nor)
>  {
>  	if (nor->params->size <= SZ_16M)
>  		return;
> @@ -287,13 +287,9 @@ static void spansion_post_sfdp_fixups(struct spi_nor *nor)
>  	nor->mtd.erasesize = nor->info->sector_size;
>  }
>  
> -static const struct spi_nor_fixups spansion_fixups = {
> -	.post_sfdp = spansion_post_sfdp_fixups,
> -};
> -
>  const struct spi_nor_manufacturer spi_nor_spansion = {
>  	.name = "spansion",
>  	.parts = spansion_parts,
>  	.nparts = ARRAY_SIZE(spansion_parts),
> -	.fixups = &spansion_fixups,
> +	.late_init = spansion_late_init,
>  };
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From msp at baylibre.com  Mon Aug 16 12:25:18 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Mon, 16 Aug 2021 21:25:18 +0200
Subject: [RFC PATCH 0/5] drm/mediatek: Add mt8195 DisplayPort driver
Message-ID: <20210816192523.1739365-1-msp@baylibre.com>

Hi everyone,

this series is built around the DisplayPort driver. The dpi/dpintf driver and
the added helper functions are required for the DisplayPort.

Note that this is an RFC. I would like to have your opinion on the driver and
what needs to change. The driver itself has its rough edges that I am currently
still working on, especially the training and powerup/down need some work in
my opinion. Also the code compiles without an issue but is not fully tested
yet.

However I already wanted to reach out for some feedback to see what can and
should be improved. I am happy about every comment, thanks for taking the
time.

The series is currently based on v5.14-rc5 but it requires other patches to
actually work on mt8195 (clock, etc.). A binding documentation is not included
yet.

Thanks,
Markus

Markus Schneider-Pargmann (5):
  dt-bindings: mediatek,dpi: Add mt8195 dpintf
  drm/mediatek: dpi: Add dpintf support
  drm/edid: Add cea_sad helpers for freq/length
  video/hdmi: Add audio_infoframe packing for DP
  drm/mediatek: Add mt8195 DisplayPort driver

 .../display/mediatek/mediatek,dpi.yaml        |   48 +-
 drivers/gpu/drm/drm_edid.c                    |   57 +
 drivers/gpu/drm/mediatek/Kconfig              |    7 +
 drivers/gpu/drm/mediatek/Makefile             |    2 +
 drivers/gpu/drm/mediatek/mtk_dp.c             | 3025 ++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dp_reg.h         | 3095 +++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_dpi.c            |  282 +-
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |   12 +
 drivers/video/hdmi.c                          |   87 +-
 include/drm/drm_edid.h                        |   18 +-
 include/linux/hdmi.h                          |    4 +
 11 files changed, 6564 insertions(+), 73 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h

-- 
2.32.0



From msp at baylibre.com  Mon Aug 16 12:25:19 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Mon, 16 Aug 2021 21:25:19 +0200
Subject: [RFC PATCH 1/5] dt-bindings: mediatek,dpi: Add mt8195 dpintf
In-Reply-To: <20210816192523.1739365-1-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
Message-ID: <20210816192523.1739365-2-msp@baylibre.com>

DP_INTF is similar to the actual dpi. They differ in some points
regarding registers and what needs to be set but the function blocks
itself are similar in design.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 .../display/mediatek/mediatek,dpi.yaml        | 48 ++++++++++++++++---
 1 file changed, 42 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
index dd2896a40ff0..de4bdacd83ac 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: mediatek DPI Controller Device Tree Bindings
+title: mediatek DPI/DP_INTF Controller Device Tree Bindings
 
 maintainers:
   - CK Hu <ck.hu at mediatek.com>
@@ -13,7 +13,8 @@ maintainers:
 description: |
   The Mediatek DPI function block is a sink of the display subsystem and
   provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
-  output bus.
+  output bus. The Mediatek DP_INTF is a similar function block that is
+  connected to the (embedded) display port function block.
 
 properties:
   compatible:
@@ -23,6 +24,7 @@ properties:
       - mediatek,mt8173-dpi
       - mediatek,mt8183-dpi
       - mediatek,mt8192-dpi
+      - mediatek,mt8195-dpintf
 
   reg:
     maxItems: 1
@@ -37,10 +39,11 @@ properties:
       - description: DPI PLL
 
   clock-names:
-    items:
-      - const: pixel
-      - const: engine
-      - const: pll
+    description:
+      For dpi clocks pixel, engine and pll are required. For dpintf pixel, pll,
+      pll_d2, pll_d4, pll_d8, pll_d16, hf_fmm, hf_fdp are required.
+    minItems: 3
+    maxItems: 8
 
   pinctrl-0: true
   pinctrl-1: true
@@ -64,6 +67,39 @@ required:
   - clock-names
   - port
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8195-dpintf
+    then:
+      properties:
+        clocks:
+          minItems: 8
+          maxItems: 8
+        clock-names:
+          items:
+            - const: pixel
+            - const: pll
+            - const: pll_d2
+            - const: pll_d4
+            - const: pll_d8
+            - const: pll_d16
+            - const: hf_fmm
+            - const: hf_fdp
+    else:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: pixel
+            - const: engine
+            - const: pll
+
 additionalProperties: false
 
 examples:
-- 
2.32.0



From msp at baylibre.com  Mon Aug 16 12:25:22 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Mon, 16 Aug 2021 21:25:22 +0200
Subject: [RFC PATCH 4/5] video/hdmi: Add audio_infoframe packing for DP
In-Reply-To: <20210816192523.1739365-1-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
Message-ID: <20210816192523.1739365-5-msp@baylibre.com>

Similar to HDMI, DP uses audio infoframes as well which are structured
very similar to the HDMI ones.

This patch adds a helper function to pack the HDMI audio infoframe for
DP, called hdmi_audio_infoframe_pack_for_dp().
hdmi_audio_infoframe_pack_only() is split into two parts. One of them
packs the payload only and can be used for HDMI and DP.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/video/hdmi.c | 87 +++++++++++++++++++++++++++++++++++---------
 include/linux/hdmi.h |  4 ++
 2 files changed, 73 insertions(+), 18 deletions(-)

diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index 947be761dfa4..59c4341549e4 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -387,6 +387,28 @@ int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame)
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 
+static void
+hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
+				  u8 *buffer)
+{
+	u8 channels;
+
+	if (frame->channels >= 2)
+		channels = frame->channels - 1;
+	else
+		channels = 0;
+
+	buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
+	buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
+		 (frame->sample_size & 0x3);
+	buffer[2] = frame->coding_type_ext & 0x1f;
+	buffer[3] = frame->channel_allocation;
+	buffer[4] = (frame->level_shift_value & 0xf) << 3;
+
+	if (frame->downmix_inhibit)
+		buffer[4] |= BIT(7);
+}
+
 /**
  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary buffer
  * @frame: HDMI audio infoframe
@@ -404,7 +426,6 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_check);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size)
 {
-	unsigned char channels;
 	u8 *ptr = buffer;
 	size_t length;
 	int ret;
@@ -420,28 +441,13 @@ ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 
 	memset(buffer, 0, size);
 
-	if (frame->channels >= 2)
-		channels = frame->channels - 1;
-	else
-		channels = 0;
-
 	ptr[0] = frame->type;
 	ptr[1] = frame->version;
 	ptr[2] = frame->length;
 	ptr[3] = 0; /* checksum */
 
-	/* start infoframe payload */
-	ptr += HDMI_INFOFRAME_HEADER_SIZE;
-
-	ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
-	ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
-		 (frame->sample_size & 0x3);
-	ptr[2] = frame->coding_type_ext & 0x1f;
-	ptr[3] = frame->channel_allocation;
-	ptr[4] = (frame->level_shift_value & 0xf) << 3;
-
-	if (frame->downmix_inhibit)
-		ptr[4] |= BIT(7);
+	hdmi_audio_infoframe_pack_payload(frame,
+					  ptr + HDMI_INFOFRAME_HEADER_SIZE);
 
 	hdmi_infoframe_set_checksum(buffer, length);
 
@@ -479,6 +485,51 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 }
 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
 
+/**
+ * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for
+ *                                    displayport
+ *
+ * @frame HDMI Audio infoframe
+ * @header Header buffer to be used
+ * @header_size Size of header buffer
+ * @data Data buffer to be used
+ * @data_size Size of data buffer
+ * @dp_version Display Port version to be encoded in the header
+ *
+ * Packs a HDMI Audio Infoframe to be sent over Display Port. This function
+ * fills both header and data buffer with the required data.
+ *
+ * Return: Number of total written bytes or a negative errno on failure.
+ */
+ssize_t hdmi_audio_infoframe_pack_for_dp(struct hdmi_audio_infoframe *frame,
+					 void *header, size_t header_size,
+					 void *data, size_t data_size,
+					 u8 dp_version)
+{
+	int ret;
+	u8 *hdr_ptr = header;
+
+	ret = hdmi_audio_infoframe_check(frame);
+	if (ret)
+		return ret;
+
+	if (header_size < 4 || data_size < frame->length)
+		return -ENOSPC;
+
+	memset(header, 0, header_size);
+	memset(data, 0, data_size);
+
+	// Secondary-data packet header
+	hdr_ptr[1] = frame->type;
+	hdr_ptr[2] = 0x1B;  // As documented by DP spec for Secondary-data Packets
+	hdr_ptr[3] = (dp_version & 0x3f) << 2;
+
+	hdmi_audio_infoframe_pack_payload(frame, data);
+
+	return frame->length + 4;
+}
+EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
+
 /**
  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
  * @frame: HDMI vendor infoframe
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index c8ec982ff498..f576a0b08c85 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -334,6 +334,10 @@ struct hdmi_audio_infoframe {
 int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
 ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
 				  void *buffer, size_t size);
+ssize_t hdmi_audio_infoframe_pack_for_dp(struct hdmi_audio_infoframe *frame,
+					 void *header, size_t header_size,
+					 void *data, size_t data_size,
+					 u8 dp_version);
 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
 				       void *buffer, size_t size);
 int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame);
-- 
2.32.0



From msp at baylibre.com  Mon Aug 16 12:25:20 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Mon, 16 Aug 2021 21:25:20 +0200
Subject: [RFC PATCH 2/5] drm/mediatek: dpi: Add dpintf support
In-Reply-To: <20210816192523.1739365-1-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
Message-ID: <20210816192523.1739365-3-msp@baylibre.com>

dpintf is the displayport interface hardware unit. This unit is similar
to dpi and can reuse most of the code.

This patch adds support for mt8195-dpintf to this dpi driver. Main
differences are:
 - Some features/functional components are not available for dpintf
   which are now excluded from code execution once is_dpintf is set
 - dpintf can and needs to choose between different clockdividers based
   on the clockspeed. This is done by choosing a different clock parent.
 - There are two additional clocks that need to be managed. These are
   only set for dpintf and will be set to NULL if not supplied. The
   clk_* calls handle these as normal clocks then.
 - Some register contents differ slightly between the two components. To
   work around this I added register bits/masks with a DPINTF_ prefix
   and use them where different.

Based on a separate driver for dpintf created by
Jason-JH.Lin <jason-jh.lin at mediatek.com>.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 282 ++++++++++++++++++++----
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
 2 files changed, 247 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index bced555648b0..4ad6d1fc6bde 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -63,6 +63,14 @@ enum mtk_dpi_out_color_format {
 	MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
 };
 
+enum mtk_dpi_tvdpll_clk {
+	MTK_DPI_TVDPLL_D2 = 0,
+	MTK_DPI_TVDPLL_D4 = 1,
+	MTK_DPI_TVDPLL_D8 = 2,
+	MTK_DPI_TVDPLL_D16 = 3,
+	MTK_DPI_TVDPLL_NUM_CLKS = 4
+};
+
 struct mtk_dpi {
 	struct drm_encoder encoder;
 	struct drm_bridge bridge;
@@ -71,8 +79,11 @@ struct mtk_dpi {
 	void __iomem *regs;
 	struct device *dev;
 	struct clk *engine_clk;
+	struct clk *hf_fmm_clk;
+	struct clk *hf_fdp_clk;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
+	struct clk_bulk_data tvd_clks[MTK_DPI_TVDPLL_NUM_CLKS];
 	int irq;
 	struct drm_display_mode mode;
 	const struct mtk_dpi_conf *conf;
@@ -125,6 +136,7 @@ struct mtk_dpi_conf {
 	bool edge_sel_en;
 	const u32 *output_fmts;
 	u32 num_output_fmts;
+	bool is_dpintf;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -153,30 +165,52 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 				 struct mtk_dpi_sync_param *sync)
 {
-	mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
-		     sync->sync_width << HPW, HPW_MASK);
-	mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
-		     sync->back_porch << HBP, HBP_MASK);
-	mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
-		     HFP_MASK);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+			     sync->sync_width << HPW, DPINTF_HPW_MASK);
+		mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+			     sync->back_porch << HBP, DPINTF_HBP_MASK);
+		mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+			     DPINTF_HFP_MASK);
+	} else {
+		mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH,
+			     sync->sync_width << HPW, HPW_MASK);
+		mtk_dpi_mask(dpi, DPI_TGEN_HPORCH,
+			     sync->back_porch << HBP, HBP_MASK);
+		mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
+			     HFP_MASK);
+	}
 }
 
 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
 				 struct mtk_dpi_sync_param *sync,
 				 u32 width_addr, u32 porch_addr)
 {
-	mtk_dpi_mask(dpi, width_addr,
-		     sync->sync_width << VSYNC_WIDTH_SHIFT,
-		     VSYNC_WIDTH_MASK);
 	mtk_dpi_mask(dpi, width_addr,
 		     sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
 		     VSYNC_HALF_LINE_MASK);
-	mtk_dpi_mask(dpi, porch_addr,
-		     sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
-		     VSYNC_BACK_PORCH_MASK);
-	mtk_dpi_mask(dpi, porch_addr,
-		     sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
-		     VSYNC_FRONT_PORCH_MASK);
+
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, width_addr,
+			     sync->sync_width << VSYNC_WIDTH_SHIFT,
+			     DPINTF_VSYNC_WIDTH_MASK);
+		mtk_dpi_mask(dpi, porch_addr,
+			     sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+			     DPINTF_VSYNC_BACK_PORCH_MASK);
+		mtk_dpi_mask(dpi, porch_addr,
+			     sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
+			     DPINTF_VSYNC_FRONT_PORCH_MASK);
+	} else {
+		mtk_dpi_mask(dpi, width_addr,
+			     sync->sync_width << VSYNC_WIDTH_SHIFT,
+			     VSYNC_WIDTH_MASK);
+		mtk_dpi_mask(dpi, porch_addr,
+			     sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
+			     VSYNC_BACK_PORCH_MASK);
+		mtk_dpi_mask(dpi, porch_addr,
+			     sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
+			     VSYNC_FRONT_PORCH_MASK);
+	}
 }
 
 static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
@@ -210,13 +244,20 @@ static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
 			       struct mtk_dpi_polarities *dpi_pol)
 {
 	unsigned int pol;
+	unsigned int mask;
 
-	pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) |
-	      (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) |
-	      (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
+	mask = HSYNC_POL | VSYNC_POL;
+	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
 	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol,
-		     CK_POL | DE_POL | HSYNC_POL | VSYNC_POL);
+	if (!dpi->conf->is_dpintf) {
+		mask |= CK_POL | DE_POL;
+		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
+			0 : CK_POL) |
+		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
+			0 : DE_POL);
+	}
+
+	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
 }
 
 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
@@ -270,8 +311,12 @@ static void mtk_dpi_config_bit_num(struct mtk_dpi *dpi,
 		val = OUT_BIT_8;
 		break;
 	}
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << OUT_BIT,
-		     OUT_BIT_MASK);
+	if (dpi->conf->is_dpintf)
+		mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << DPINTF_OUT_BIT,
+			     DPINTF_OUT_BIT_MASK);
+	else
+		mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << OUT_BIT,
+			     OUT_BIT_MASK);
 }
 
 static void mtk_dpi_config_yc_map(struct mtk_dpi *dpi,
@@ -332,12 +377,21 @@ static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
 		break;
 	}
 
-	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK);
+	if (dpi->conf->is_dpintf)
+		mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << DPINTF_CH_SWAP,
+			     DPINTF_CH_SWAP_MASK);
+	else
+		mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP,
+			     CH_SWAP_MASK);
 }
 
 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
 {
-	mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
+	if (dpi->conf->is_dpintf)
+		mtk_dpi_mask(dpi, DPI_CON, enable ? DPINTF_YUV422_EN : 0,
+			     DPINTF_YUV422_EN);
+	else
+		mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN);
 }
 
 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
@@ -367,19 +421,25 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
 	if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) ||
 	    (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, false);
-		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (!dpi->conf->is_dpintf) {
+			mtk_dpi_config_csc_enable(dpi, true);
+			mtk_dpi_config_swap_input(dpi, false);
+		}
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR);
 	} else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) ||
 		   (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) {
 		mtk_dpi_config_yuv422_enable(dpi, true);
-		mtk_dpi_config_csc_enable(dpi, true);
-		mtk_dpi_config_swap_input(dpi, true);
+		if (!dpi->conf->is_dpintf) {
+			mtk_dpi_config_csc_enable(dpi, true);
+			mtk_dpi_config_swap_input(dpi, true);
+		}
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	} else {
 		mtk_dpi_config_yuv422_enable(dpi, false);
-		mtk_dpi_config_csc_enable(dpi, false);
-		mtk_dpi_config_swap_input(dpi, false);
+		if (!dpi->conf->is_dpintf) {
+			mtk_dpi_config_csc_enable(dpi, false);
+			mtk_dpi_config_swap_input(dpi, false);
+		}
 		mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
 	}
 }
@@ -410,8 +470,10 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
 
 	mtk_dpi_disable(dpi);
-	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->engine_clk);
+	clk_disable_unprepare(dpi->hf_fdp_clk);
+	clk_disable_unprepare(dpi->hf_fmm_clk);
+	clk_disable_unprepare(dpi->pixel_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -433,12 +495,28 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 		goto err_pixel;
 	}
 
+	ret = clk_prepare_enable(dpi->hf_fmm_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable hf_fmm clock: %d\n", ret);
+		goto err_hf_fmm;
+	}
+
+	ret = clk_prepare_enable(dpi->hf_fdp_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable hf_fdp clock: %d\n", ret);
+		goto err_hf_fdp;
+	}
+
 	if (dpi->pinctrl && dpi->pins_dpi)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
 
 	mtk_dpi_enable(dpi);
 	return 0;
 
+err_hf_fdp:
+	clk_disable_unprepare(dpi->hf_fmm_clk);
+err_hf_fmm:
+	clk_disable_unprepare(dpi->pixel_clk);
 err_pixel:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
@@ -446,6 +524,31 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 	return ret;
 }
 
+static void mtk_dpi_set_pixel_clk_parent(struct mtk_dpi *dpi,
+					 unsigned int factor)
+{
+	struct clk *new_parent;
+
+	switch (factor) {
+	case 16:
+		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D16].clk;
+		break;
+	case 8:
+		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D8].clk;
+		break;
+	case 4:
+		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D4].clk;
+		break;
+	case 2:
+		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D2].clk;
+		break;
+	default:
+		new_parent = NULL;
+	}
+	if (new_parent)
+		clk_set_parent(dpi->pixel_clk, new_parent);
+}
+
 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 				    struct drm_display_mode *mode)
 {
@@ -465,6 +568,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	drm_display_mode_to_videomode(mode, &vm);
 	pll_rate = vm.pixelclock * factor;
 
+	mtk_dpi_set_pixel_clk_parent(dpi, factor);
+
 	dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
 		pll_rate, vm.pixelclock);
 
@@ -484,10 +589,17 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
 		pll_rate, vm.pixelclock);
 
-	limit.c_bottom = 0x0010;
-	limit.c_top = 0x0FE0;
-	limit.y_bottom = 0x0010;
-	limit.y_top = 0x0FE0;
+	if (dpi->conf->is_dpintf) {
+		limit.c_bottom = 0x0000;
+		limit.c_top = 0xFFF;
+		limit.y_bottom = 0x0000;
+		limit.y_top = 0xFFF;
+	} else {
+		limit.c_bottom = 0x0010;
+		limit.c_top = 0x0FE0;
+		limit.y_bottom = 0x0010;
+		limit.y_top = 0x0FE0;
+	}
 
 	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
 	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
@@ -495,6 +607,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
 	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
+	// TODO(scosu): dpintf divides these 3 values by 4
 	hsync.sync_width = vm.hsync_len;
 	hsync.back_porch = vm.hback_porch;
 	hsync.front_porch = vm.hfront_porch;
@@ -539,12 +652,17 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	mtk_dpi_config_channel_limit(dpi, &limit);
 	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
 	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
-	mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 	mtk_dpi_config_color_format(dpi, dpi->color_format);
-	mtk_dpi_config_2n_h_fre(dpi);
-	mtk_dpi_dual_edge(dpi);
-	mtk_dpi_config_disable_edge(dpi);
-	mtk_dpi_sw_reset(dpi, false);
+	if (dpi->conf->is_dpintf) {
+		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
+			     DPINTF_INPUT_2P_EN);
+	} else {
+		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
+		mtk_dpi_config_2n_h_fre(dpi);
+		mtk_dpi_dual_edge(dpi);
+		mtk_dpi_config_disable_edge(dpi);
+		mtk_dpi_sw_reset(dpi, false);
+	}
 
 	return 0;
 }
@@ -683,6 +801,14 @@ static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
 	.atomic_reset = drm_atomic_helper_bridge_reset,
 };
 
+static const struct drm_bridge_funcs mtk_dpintf_bridge_funcs = {
+	.attach = mtk_dpi_bridge_attach,
+	.mode_set = mtk_dpi_bridge_mode_set,
+	.disable = mtk_dpi_bridge_disable,
+	.enable = mtk_dpi_bridge_enable,
+	.atomic_check = mtk_dpi_bridge_atomic_check,
+};
+
 void mtk_dpi_start(struct device *dev)
 {
 	struct mtk_dpi *dpi = dev_get_drvdata(dev);
@@ -779,6 +905,16 @@ static unsigned int mt8183_calculate_factor(int clock)
 		return 2;
 }
 
+static unsigned int mt8195_dpintf_calculate_factor(int clock)
+{
+	if (clock < 70000)
+		return 16;
+	else if (clock < 200000)
+		return 8;
+	else
+		return 4;
+}
+
 static const u32 mt8173_output_fmts[] = {
 	MEDIA_BUS_FMT_RGB888_1X24,
 };
@@ -794,6 +930,7 @@ static const struct mtk_dpi_conf mt8173_conf = {
 	.max_clock_khz = 300000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_dpintf = false,
 };
 
 static const struct mtk_dpi_conf mt2701_conf = {
@@ -803,6 +940,7 @@ static const struct mtk_dpi_conf mt2701_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_dpintf = false,
 };
 
 static const struct mtk_dpi_conf mt8183_conf = {
@@ -811,6 +949,7 @@ static const struct mtk_dpi_conf mt8183_conf = {
 	.max_clock_khz = 100000,
 	.output_fmts = mt8183_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.is_dpintf = false,
 };
 
 static const struct mtk_dpi_conf mt8192_conf = {
@@ -819,6 +958,12 @@ static const struct mtk_dpi_conf mt8192_conf = {
 	.max_clock_khz = 150000,
 	.output_fmts = mt8173_output_fmts,
 	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
+	.is_dpintf = false,
+};
+
+static const struct mtk_dpi_conf mt8195_dpintf_conf = {
+	.cal_factor = mt8195_dpintf_calculate_factor,
+	.is_dpintf = true,
 };
 
 static int mtk_dpi_probe(struct platform_device *pdev)
@@ -864,13 +1009,16 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dpi->engine_clk = devm_clk_get(dev, "engine");
-	if (IS_ERR(dpi->engine_clk)) {
-		ret = PTR_ERR(dpi->engine_clk);
-		if (ret != -EPROBE_DEFER)
-			dev_err(dev, "Failed to get engine clock: %d\n", ret);
+	if (!dpi->conf->is_dpintf) {
+		dpi->engine_clk = devm_clk_get(dev, "engine");
+		if (IS_ERR(dpi->engine_clk)) {
+			ret = PTR_ERR(dpi->engine_clk);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to get engine clock: %d\n",
+					ret);
 
-		return ret;
+			return ret;
+		}
 	}
 
 	dpi->pixel_clk = devm_clk_get(dev, "pixel");
@@ -891,6 +1039,40 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	dpi->hf_fmm_clk = devm_clk_get_optional(dev, "hf_fmm");
+	if (IS_ERR(dpi->hf_fmm_clk)) {
+		ret = PTR_ERR(dpi->hf_fmm_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get hf_fmm clock: %d\n", ret);
+
+		return ret;
+	}
+
+	dpi->hf_fdp_clk = devm_clk_get_optional(dev, "hf_fdp");
+	if (IS_ERR(dpi->hf_fdp_clk)) {
+		ret = PTR_ERR(dpi->hf_fdp_clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get hf_fdp clock: %d\n", ret);
+
+		return ret;
+	}
+
+	if (dpi->conf->is_dpintf) {
+		dpi->tvd_clks[MTK_DPI_TVDPLL_D2].id = "pll_d2";
+		dpi->tvd_clks[MTK_DPI_TVDPLL_D4].id = "pll_d4";
+		dpi->tvd_clks[MTK_DPI_TVDPLL_D8].id = "pll_d8";
+		dpi->tvd_clks[MTK_DPI_TVDPLL_D16].id = "pll_d16";
+		ret = devm_clk_bulk_get_optional(dev, MTK_DPI_TVDPLL_NUM_CLKS,
+						 dpi->tvd_clks);
+		if (ret) {
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev,
+					"Failed to get optional tvdpll divider clock: %d\n",
+					ret);
+			return ret;
+		}
+	}
+
 	dpi->irq = platform_get_irq(pdev, 0);
 	if (dpi->irq <= 0)
 		return -EINVAL;
@@ -904,7 +1086,10 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, dpi);
 
-	dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
+	if (dpi->conf->is_dpintf)
+		dpi->bridge.funcs = &mtk_dpintf_bridge_funcs;
+	else
+		dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
 	dpi->bridge.of_node = dev->of_node;
 	dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
 
@@ -943,6 +1128,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8192-dpi",
 	  .data = &mt8192_conf,
 	},
+	{ .compatible = "mediatek,mt8195-dpintf",
+	  .data = &mt8195_dpintf_conf,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 3a02fabe1662..c7489be5c713 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -40,10 +40,14 @@
 #define FAKE_DE_LEVEN			BIT(21)
 #define FAKE_DE_RODD			BIT(22)
 #define FAKE_DE_REVEN			BIT(23)
+#define DPINTF_YUV422_EN		BIT(24)
+#define DPINTF_INPUT_2P_EN		BIT(29)
 
 #define DPI_OUTPUT_SETTING	0x14
 #define CH_SWAP				0
+#define DPINTF_CH_SWAP			BIT(1)
 #define CH_SWAP_MASK			(0x7 << 0)
+#define DPINTF_CH_SWAP_MASK		(0x7 << 1)
 #define SWAP_RGB			0x00
 #define SWAP_GBR			0x01
 #define SWAP_BRG			0x02
@@ -64,7 +68,9 @@
 #define OEN_OFF				BIT(16)
 #define EDGE_SEL			BIT(17)
 #define OUT_BIT				18
+#define DPINTF_OUT_BIT			16
 #define OUT_BIT_MASK			(0x3 << 18)
+#define DPINTF_OUT_BIT_MASK		(0x3 << 16)
 #define OUT_BIT_8			0x00
 #define OUT_BIT_10			0x01
 #define OUT_BIT_12			0x02
@@ -93,24 +99,30 @@
 #define DPI_TGEN_HWIDTH		0x20
 #define HPW				0
 #define HPW_MASK			(0xFFF << 0)
+#define DPINTF_HPW_MASK			(0xFFFF << 0)
 
 #define DPI_TGEN_HPORCH		0x24
 #define HBP				0
 #define HBP_MASK			(0xFFF << 0)
+#define DPINTF_HBP_MASK			(0xFFFF << 0)
 #define HFP				16
 #define HFP_MASK			(0xFFF << 16)
+#define DPINTF_HFP_MASK			(0xFFFF << 16)
 
 #define DPI_TGEN_VWIDTH		0x28
 #define DPI_TGEN_VPORCH		0x2C
 
 #define VSYNC_WIDTH_SHIFT		0
 #define VSYNC_WIDTH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_WIDTH_MASK		(0xFFFF << 0)
 #define VSYNC_HALF_LINE_SHIFT		16
 #define VSYNC_HALF_LINE_MASK		BIT(16)
 #define VSYNC_BACK_PORCH_SHIFT		0
 #define VSYNC_BACK_PORCH_MASK		(0xFFF << 0)
+#define DPINTF_VSYNC_BACK_PORCH_MASK	(0xFFFF << 0)
 #define VSYNC_FRONT_PORCH_SHIFT		16
 #define VSYNC_FRONT_PORCH_MASK		(0xFFF << 16)
+#define DPINTF_VSYNC_FRONT_PORCH_MASK	(0xFFFF << 16)
 
 #define DPI_BG_HCNTL		0x30
 #define BG_RIGHT			(0x1FFF << 0)
-- 
2.32.0



From msp at baylibre.com  Mon Aug 16 12:25:21 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Mon, 16 Aug 2021 21:25:21 +0200
Subject: [RFC PATCH 3/5] drm/edid: Add cea_sad helpers for freq/length
In-Reply-To: <20210816192523.1739365-1-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
Message-ID: <20210816192523.1739365-4-msp@baylibre.com>

This patch adds two helper functions that extract the frequency and word
length from a struct cea_sad.

For these helper functions new defines are added that help translate the
'freq' and 'byte2' fields into real numbers.

Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
---
 drivers/gpu/drm/drm_edid.c | 57 ++++++++++++++++++++++++++++++++++++++
 include/drm/drm_edid.h     | 18 ++++++++++--
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 81d5f2524246..2389d34ce10e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4666,6 +4666,63 @@ int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb)
 }
 EXPORT_SYMBOL(drm_edid_to_speaker_allocation);
 
+/**
+ * drm_cea_sad_get_sample_rate - Extract the sample rate from cea_sad
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad frequency field and returns the sample rate in Hz.
+ *
+ * Return: Sample rate in Hz or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_sample_rate(struct cea_sad *sad)
+{
+	switch (sad->freq) {
+	case CEA_SAD_FREQ_32KHZ:
+		return 32000;
+	case CEA_SAD_FREQ_44KHZ:
+		return 44100;
+	case CEA_SAD_FREQ_48KHZ:
+		return 48000;
+	case CEA_SAD_FREQ_88KHZ:
+		return 88200;
+	case CEA_SAD_FREQ_96KHZ:
+		return 96000;
+	case CEA_SAD_FREQ_176KHZ:
+		return 176400;
+	case CEA_SAD_FREQ_192KHZ:
+		return 192000;
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL(drm_cea_sad_get_sample_rate);
+
+/**
+ * drm_cea_sad_get_uncompressed_word_length - Extract word length
+ * @sad: Pointer to the cea_sad struct
+ *
+ * Extracts the cea_sad byte2 field and returns the word length for an
+ * uncompressed stream.
+ *
+ * Note: This function may only be called for uncompressed audio.
+ *
+ * Return: Word length in bits or a negative errno if parsing failed.
+ */
+int drm_cea_sad_get_uncompressed_word_length(struct cea_sad *sad)
+{
+	switch (sad->byte2) {
+	case CEA_SAD_UNCOMPRESSED_WORD_16BIT:
+		return 16;
+	case CEA_SAD_UNCOMPRESSED_WORD_20BIT:
+		return 20;
+	case CEA_SAD_UNCOMPRESSED_WORD_24BIT:
+		return 24;
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL(drm_cea_sad_get_uncompressed_word_length);
+
 /**
  * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
  * @connector: connector associated with the HDMI/DP sink
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 759328a5eeb2..bed091a749ef 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -361,12 +361,24 @@ struct edid {
 
 /* Short Audio Descriptor */
 struct cea_sad {
-	u8 format;
+	u8 format; /* See HDMI_AUDIO_CODING_TYPE_* */
 	u8 channels; /* max number of channels - 1 */
-	u8 freq;
+	u8 freq; /* See CEA_SAD_FREQ_* */
 	u8 byte2; /* meaning depends on format */
 };
 
+#define CEA_SAD_FREQ_32KHZ  BIT(0)
+#define CEA_SAD_FREQ_44KHZ  BIT(1)
+#define CEA_SAD_FREQ_48KHZ  BIT(2)
+#define CEA_SAD_FREQ_88KHZ  BIT(3)
+#define CEA_SAD_FREQ_96KHZ  BIT(4)
+#define CEA_SAD_FREQ_176KHZ BIT(5)
+#define CEA_SAD_FREQ_192KHZ BIT(6)
+
+#define CEA_SAD_UNCOMPRESSED_WORD_16BIT BIT(0)
+#define CEA_SAD_UNCOMPRESSED_WORD_20BIT BIT(1)
+#define CEA_SAD_UNCOMPRESSED_WORD_24BIT BIT(2)
+
 struct drm_encoder;
 struct drm_connector;
 struct drm_connector_state;
@@ -374,6 +386,8 @@ struct drm_display_mode;
 
 int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads);
 int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb);
+int drm_cea_sad_get_sample_rate(struct cea_sad *sad);
+int drm_cea_sad_get_uncompressed_word_length(struct cea_sad *sad);
 int drm_av_sync_delay(struct drm_connector *connector,
 		      const struct drm_display_mode *mode);
 
-- 
2.32.0



From p.yadav at ti.com  Mon Aug 16 12:31:39 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 01:01:39 +0530
Subject: [PATCH v2 15/35] mtd: spi-nor: core: Call
 spi_nor_post_sfdp_fixups() only when SFDP is defined
In-Reply-To: <20210727045222.905056-16-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-16-tudor.ambarus@microchip.com>
Message-ID: <20210816193137.xyb4v4edgyge3k54@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> spi_nor_post_sfdp_fixups() was called even when there were no SFDP
> tables defined and the function name was misleading.
> 
> We introduced the late_init() hook which is used to tweak various
> parameters that could not be extracted by other means, i.e. when
> parameters are not defined in the JESD216 SFDP standard, or when
> the flash_info flags are incomplete.
> 
> Use spi_nor_post_sfdp_fixups() just to fix SFDP data. post_sfdp()
> hook is as of now used just by s28hs512t, mt35xu512aba, and both
> support SFDP, there's no functional change with this patch.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c | 66 +++++++++++++++++---------------------
>  1 file changed, 29 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 15ccc9994215..1f38fa8ab2fa 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -2509,6 +2509,25 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
>  		nor->info->fixups->default_init(nor);
>  }
>  
> +/**
> + * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
> + * after SFDP has been parsed.
> + * @nor:	pointer to a 'struct spi_nor'
> + *
> + * Typically used to tweak various parameters that could not be extracted by
> + * other means (i.e. when information provided by the SFDP tables are
> + * incomplete or wrong).

Do we want to keep the "incomplete" here? Wouldn't incomplete 
information (like missing parameter tables) be more suited for 
late_init()?

> + */
> +static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
> +{
> +	if (nor->manufacturer && nor->manufacturer->fixups &&
> +	    nor->manufacturer->fixups->post_sfdp)
> +		nor->manufacturer->fixups->post_sfdp(nor);
> +
> +	if (nor->info->fixups && nor->info->fixups->post_sfdp)
> +		nor->info->fixups->post_sfdp(nor);
> +}
> +
>  /**
>   * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
>   * based on JESD216 SFDP standard.
> @@ -2523,11 +2542,12 @@ static void spi_nor_sfdp_init_params(struct spi_nor *nor)
>  
>  	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
>  
> -	if (spi_nor_parse_sfdp(nor)) {
> -		memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
> -		nor->addr_width = 0;
> -		nor->flags &= ~SNOR_F_4B_OPCODES;
> -	}
> +	if (!spi_nor_parse_sfdp(nor))
> +		return spi_nor_post_sfdp_fixups(nor);

Huh. I didn't know you could do return foo() in a void function if foo() 
is also void. Dunno how I feel about this though. It definitely confused 
me for a bit.

> +
> +	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
> +	nor->addr_width = 0;
> +	nor->flags &= ~SNOR_F_4B_OPCODES;

I feel like the new flow makes these 3 lines more confusing. Earlier, 
these were called under if (spi_nor_parse_sfdp()) so it was a bit easier 
to make the connection that these are undoing the changes performed by 
that function. Now it is a little harder to spot. I think a comment is 
in order.

>  }
>  
>  /**
> @@ -2643,26 +2663,6 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
>  	spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
>  }
>  
> -/**
> - * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
> - * after SFDP has been parsed (is also called for SPI NORs that do not
> - * support RDSFDP).
> - * @nor:	pointer to a 'struct spi_nor'
> - *
> - * Typically used to tweak various parameters that could not be extracted by
> - * other means (i.e. when information provided by the SFDP/flash_info tables
> - * are incomplete or wrong).
> - */
> -static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
> -{
> -	if (nor->manufacturer && nor->manufacturer->fixups &&
> -	    nor->manufacturer->fixups->post_sfdp)
> -		nor->manufacturer->fixups->post_sfdp(nor);
> -
> -	if (nor->info->fixups && nor->info->fixups->post_sfdp)
> -		nor->info->fixups->post_sfdp(nor);
> -}
> -
>  /**
>   * spi_nor_late_init_params() - Late initialization of default flash parameters.
>   * @nor:	pointer to a 'struct spi_nor'
> @@ -2709,18 +2709,12 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
>   *    should be more accurate that the above.
>   *		spi_nor_sfdp_init_params()
>   *
> - *    Please note that there is a ->post_bfpt() fixup hook that can overwrite
> - *    the flash parameters and settings immediately after parsing the Basic
> - *    Flash Parameter Table.
> + *    Please note that there are ->post_{bfpt, sfdp}() fixup hooks that can
> + *    overwrite the flash parameters and settings immediately after table
> + *    parsing.
>   *
>   * which can be overwritten by:
> - * 4/ Post SFDP flash parameters initialization. Used to tweak various
> - *    parameters that could not be extracted by other means (i.e. when
> - *    information provided by the SFDP/flash_info tables are incomplete or
> - *    wrong).
> - *		spi_nor_post_sfdp_fixups()
> - *
> - * 5/ Late flash parameters initialization, used to initialize flash
> + * 4/ Late flash parameters initialization, used to initialize flash
>   * parameters that are not declared in the JESD216 SFDP standard.
>   *		spi_nor_late_init_params()
>   */
> @@ -2740,8 +2734,6 @@ static int spi_nor_init_params(struct spi_nor *nor)
>  	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
>  		spi_nor_sfdp_init_params(nor);
>  
> -	spi_nor_post_sfdp_fixups(nor);
> -
>  	spi_nor_late_init_params(nor);
>  
>  	return 0;
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Mon Aug 16 12:36:04 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 01:06:04 +0530
Subject: [PATCH v2 16/35] mtd: spi-nor: core: Mark default_init() as
 deprecated
In-Reply-To: <20210727045222.905056-17-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-17-tudor.ambarus@microchip.com>
Message-ID: <20210816193602.ze2w6qczvtgpwwdi@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> The goal is to remove the spagetti init of params. The flash should
> be initialized by the SFDP data, and when SFDP tables are not defined,
> by the flash_info flags. SFDP data can be corrected by the
> post_{bfpt, sfdp} when wrong, and in case of flash_info flags init,
> we'll use the late_init() hook, where checking for the
> SPI_NOR_SKIP_SFDP flag.

Why depreciate it? It is not like we have external callers that we need 
to notify. We know and control all the users of this function. Just move 
all users to late_init() and delete this. You have already done a large 
part of that work in the previous patches. Why not convert all other 
callers as well? Is there some complicated piece of code that stops you 
from touching it for now?

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.h | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 13d5c5edfd27..625f4eed75f1 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -289,9 +289,8 @@ struct spi_nor_flash_parameter {
>  
>  /**
>   * struct spi_nor_fixups - SPI NOR fixup hooks
> - * @default_init: called after default flash parameters init. Used to tweak
> - *                flash parameters when information provided by the flash_info
> - *                table is incomplete or wrong.
> + * @default_init: Deprecated. Use the post_{bfpt, sfdp}, or the late_init()
> + *                hooks instead.
>   * @post_bfpt: called after the BFPT table has been parsed
>   * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs
>   *             that do not support RDSFDP). Typically used to tweak various
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From robh at kernel.org  Mon Aug 16 13:07:03 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 16 Aug 2021 15:07:03 -0500
Subject: [PATCH v2 1/4] dt-bindings: pwrseq-sd8787: add binding for
 wilc1000
In-Reply-To: <20210816085530.1723402-2-claudiu.beznea@microchip.com>
References: <20210816085530.1723402-1-claudiu.beznea@microchip.com>
 <20210816085530.1723402-2-claudiu.beznea@microchip.com>
Message-ID: <1629144423.378578.2563331.nullmailer@robh.at.kernel.org>

On Mon, 16 Aug 2021 11:55:27 +0300, Claudiu Beznea wrote:
> Add binding for wilc1000 devices.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
make[1]: *** Deleting file 'Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.example.dts'
Traceback (most recent call last):
  File "/usr/local/bin/dt-extract-example", line 45, in <module>
    binding = yaml.load(open(args.yamlfile, encoding='utf-8').read())
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/main.py", line 434, in load
    return constructor.get_single_data()
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 122, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 132, in construct_document
    for _dummy in generator:
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 722, in construct_yaml_map
    value = self.construct_mapping(node)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 446, in construct_mapping
    return BaseConstructor.construct_mapping(self, node, deep=deep)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 264, in construct_mapping
    if self.check_mapping_key(node, key_node, mapping, key, value):
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 295, in check_mapping_key
    raise DuplicateKeyError(*args)
ruamel.yaml.constructor.DuplicateKeyError: while constructing a mapping
  in "<unicode string>", line 15, column 7
found duplicate key "const" with value "mmc-pwrseq-wilc1000" (original value: "mmc-pwrseq-sd8787")
  in "<unicode string>", line 16, column 7

To suppress this check see:
    http://yaml.readthedocs.io/en/latest/api.html#duplicate-keys

Duplicate keys will become an error in future releases, and are errors
by default when using the new API.

make[1]: *** [Documentation/devicetree/bindings/Makefile:20: Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.example.dts] Error 1
make[1]: *** Waiting for unfinished jobs....
Traceback (most recent call last):
  File "/usr/local/bin/dt-doc-validate", line 67, in <module>
    ret = check_doc(f)
  File "/usr/local/bin/dt-doc-validate", line 25, in check_doc
    testtree = dtschema.load(filename, line_number=line_number)
  File "/usr/local/lib/python3.8/dist-packages/dtschema/lib.py", line 623, in load
    return yaml.load(f.read())
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/main.py", line 434, in load
    return constructor.get_single_data()
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 122, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 132, in construct_document
    for _dummy in generator:
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 722, in construct_yaml_map
    value = self.construct_mapping(node)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 446, in construct_mapping
    return BaseConstructor.construct_mapping(self, node, deep=deep)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 264, in construct_mapping
    if self.check_mapping_key(node, key_node, mapping, key, value):
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 295, in check_mapping_key
    raise DuplicateKeyError(*args)
ruamel.yaml.constructor.DuplicateKeyError: while constructing a mapping
  in "<unicode string>", line 15, column 7
found duplicate key "const" with value "mmc-pwrseq-wilc1000" (original value: "mmc-pwrseq-sd8787")
  in "<unicode string>", line 16, column 7

To suppress this check see:
    http://yaml.readthedocs.io/en/latest/api.html#duplicate-keys

Duplicate keys will become an error in future releases, and are errors
by default when using the new API.

make[1]: *** Deleting file 'Documentation/devicetree/bindings/processed-schema-examples.json'
Traceback (most recent call last):
  File "/usr/local/bin/dt-mk-schema", line 38, in <module>
    schemas = dtschema.process_schemas(args.schemas, core_schema=(not args.useronly))
  File "/usr/local/lib/python3.8/dist-packages/dtschema/lib.py", line 585, in process_schemas
    sch = process_schema(os.path.abspath(filename))
  File "/usr/local/lib/python3.8/dist-packages/dtschema/lib.py", line 558, in process_schema
    schema = load_schema(filename)
  File "/usr/local/lib/python3.8/dist-packages/dtschema/lib.py", line 125, in load_schema
    return do_load(os.path.join(schema_basedir, schema))
  File "/usr/local/lib/python3.8/dist-packages/dtschema/lib.py", line 111, in do_load
    return yaml.load(f.read())
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/main.py", line 434, in load
    return constructor.get_single_data()
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 122, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 132, in construct_document
    for _dummy in generator:
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 722, in construct_yaml_map
    value = self.construct_mapping(node)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 446, in construct_mapping
    return BaseConstructor.construct_mapping(self, node, deep=deep)
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 264, in construct_mapping
    if self.check_mapping_key(node, key_node, mapping, key, value):
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 295, in check_mapping_key
    raise DuplicateKeyError(*args)
ruamel.yaml.constructor.DuplicateKeyError: while constructing a mapping
  in "<unicode string>", line 15, column 7
found duplicate key "const" with value "mmc-pwrseq-wilc1000" (original value: "mmc-pwrseq-sd8787")
  in "<unicode string>", line 16, column 7

To suppress this check see:
    http://yaml.readthedocs.io/en/latest/api.html#duplicate-keys

Duplicate keys will become an error in future releases, and are errors
by default when using the new API.

make[1]: *** [Documentation/devicetree/bindings/Makefile:62: Documentation/devicetree/bindings/processed-schema-examples.json] Error 1
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1517069

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Mon Aug 16 13:07:03 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 16 Aug 2021 15:07:03 -0500
Subject: [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <20210816104846.13155-2-billy_tsai@aspeedtech.com>
References: <20210816104846.13155-1-billy_tsai@aspeedtech.com>
 <20210816104846.13155-2-billy_tsai@aspeedtech.com>
Message-ID: <1629144423.392245.2563334.nullmailer@robh.at.kernel.org>

On Mon, 16 Aug 2021 18:48:32 +0800, Billy Tsai wrote:
> Add device tree bindings document for the aspeed ast2600 adc device
> driver.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  .../bindings/iio/adc/aspeed,ast2600-adc.yaml  | 98 +++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml: properties:aspeed,int_vref_mv: 'oneOf' conditional failed, one must be fixed:
	'type' is a required property
		hint: A vendor boolean property can use "type: boolean"
	Additional properties are not allowed ('enum' was unexpected)
		hint: A vendor boolean property can use "type: boolean"
	/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml: properties:aspeed,int_vref_mv: 'oneOf' conditional failed, one must be fixed:
		'$ref' is a required property
		'allOf' is a required property
		hint: A vendor property needs a $ref to types.yaml
		from schema $id: http://devicetree.org/meta-schemas/vendor-props.yaml#
	1200 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	2500 is not of type 'string'
		hint: A vendor string property with exact values has an implicit type
	hint: Vendor specific properties must have a type and description unless they have a defined, common suffix.
	from schema $id: http://devicetree.org/meta-schemas/vendor-props.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml: ignoring, error in schema: properties: aspeed,int_vref_mv
warning: no schema found in file: ./Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.example.dt.yaml:0:0: /example-0/adc at 1e6e9000: failed to match any schema with compatible: ['aspeed,ast2600-adc0']
Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.example.dt.yaml:0:0: /example-0/adc at 1e6e9100: failed to match any schema with compatible: ['aspeed,ast2600-adc1']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1517123

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From saravanak at google.com  Mon Aug 16 13:27:07 2021
From: saravanak at google.com (Saravana Kannan)
Date: Mon, 16 Aug 2021 13:27:07 -0700
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <YRpeVLf18Z+1R7WE@google.com>
References: <7hsga8kb8z.fsf@baylibre.com>
 <CAF2Aj3g6c8FEZb3e1by6sd8LpKLaeN5hsKrrQkZUvh8hosiW9A@mail.gmail.com>
 <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <YQuZ2cKVE+3Os25Z@google.com> <YRpeVLf18Z+1R7WE@google.com>
Message-ID: <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>

On Mon, Aug 16, 2021 at 5:47 AM Lee Jones <lee.jones at linaro.org> wrote:
>
> On Thu, 05 Aug 2021, Lee Jones wrote:
>
> > On Wed, 04 Aug 2021, Saravana Kannan wrote:
> >
> > > On Wed, Aug 4, 2021 at 11:20 AM Saravana Kannan <saravanak at google.com> wrote:
> > > >
> > > > On Wed, Aug 4, 2021 at 1:50 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > >
> > > > > On Wed, 04 Aug 2021 02:36:45 +0100,
> > > > > Saravana Kannan <saravanak at google.com> wrote:
> > > > >
> > > > > Hi Saravana,
> > > > >
> > > > > Thanks for looking into this.
> > > >
> > > > You are welcome. I just don't want people to think fw_devlink is broken :)
> > > >
> > > > >
> > > > > [...]
> > > > >
> > > > > > > Saravana, could you please have a look from a fw_devlink perspective?
> > > > > >
> > > > > > Sigh... I spent several hours looking at this and wrote up an analysis
> > > > > > and then realized I might be looking at the wrong DT files.
> > > > > >
> > > > > > Marc, can you point me to the board file in upstream that corresponds
> > > > > > to the platform in which you see this issue? I'm not asking for [1],
> > > > > > but the actual final .dts (not .dtsi) file that corresponds to the
> > > > > > platform/board/system.
> > > > >
> > > > > The platform I can reproduce this on is described in
> > > > > arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts. It is an
> > > > > intricate maze of inclusion, node merge and other DT subtleties. I
> > > > > suggest you look at the decompiled version to get a view of the
> > > > > result.
> > > >
> > > > Thanks. After decompiling it, it looks something like (stripped a
> > > > bunch of reg and address properties and added the labels back):
> > > >
> > > > eth_phy: mdio-multiplexer at 4c000 {
> > > >         compatible = "amlogic,g12a-mdio-mux";
> > > >         clocks = <0x02 0x13 0x1e 0x02 0xb1>;
> > > >         clock-names = "pclk\0clkin0\0clkin1";
> > > >         mdio-parent-bus = <0x22>;
> > > >
> > > >         ext_mdio: mdio at 0 {
> > > >                 reg = <0x00>;
> > > >
> > > >                 ethernet-phy at 0 {
> > > >                         max-speed = <0x3e8>;
> > > >                         interrupt-parent = <0x23>;
> > > >                         interrupts = <0x1a 0x08>;
> > > >                         phandle = <0x16>;
> > > >                 };
> > > >         };
> > > >
> > > >         int_mdio: mdio at 1 {
> > > >                 ...
> > > >         }
> > > > }
> > > >
> > > > And phandle 0x23 refers to the gpio_intc interrupt controller with the
> > > > modular driver.
> > > >
> > > > > > Based on your error messages, it's failing for mdio at 0 which
> > > > > > corresponds to ext_mdio. But none of the board dts files in upstream
> > > > > > have a compatible property for "ext_mdio". Which means fw_devlink
> > > > > > _should_ propagate the gpio_intc IRQ dependency all the way up to
> > > > > > eth_phy.
> > > > > >
> > > > > > Also, in the failing case, can you run:
> > > > > > ls -ld supplier:*
> > > > > >
> > > > > > in the /sys/devices/....<something>/ folder that corresponds to the
> > > > > > "eth_phy: mdio-multiplexer at 4c000" DT node and tell me what it shows?
> > > > >
> > > > > Here you go:
> > > > >
> > > > > root at tiger-roach:~# find /sys/devices/ -name 'supplier*'|grep -i mdio | xargs ls -ld
> > > > > lrwxrwxrwx 1 root root 0 Aug  4 09:47 /sys/devices/platform/soc/ff600000.bus/ff64c000.mdio-multiplexer/supplier:platform:ff63c000.system-controller:clock-controller -> ../../../../virtual/devlink/platform:ff63c000.system-controller:clock-controller--platform:ff64c000.mdio-multiplexer
> > > >
> > > > As we discussed over chat, this was taken after the mdio-multiplexer
> > > > driver "successfully" probes this device. This will cause
> > > > SYNC_STATE_ONLY device links created by fw_devlink to be deleted
> > > > (because they are useless after a device probes). So, this doesn't
> > > > show the info I was hoping to demonstrate.
> > > >
> > > > In any case, one can see that fw_devlink properly created the device
> > > > link for the clocks dependency. So fw_devlink is parsing this node
> > > > properly. But it doesn't create a similar probe order enforcing device
> > > > link between the mdio-multiplexer and the gpio_intc because the
> > > > dependency is only present in a grand child DT node (ethernet-phy at 0
> > > > under ext_mdio). So fw_devlink is working as intended.
> > > >
> > > > I spent several hours squinting at the code/DT yesterday. Here's what
> > > > is going on and causing the problem:
> > > >
> > > > The failing driver in this case is
> > > > drivers/net/mdio/mdio-mux-meson-g12a.c. And the only DT node it's
> > > > handling is what I pasted above in this email. In the failure case,
> > > > the call flow is something like this:
> > > >
> > > > g12a_mdio_mux_probe()
> > > > -> mdio_mux_init()
> > > > -> of_mdiobus_register(ext_mdio DT node)
> > > > -> of_mdiobus_register_phy(ext_mdio DT node)
> > > > -> several calls deep fwnode_mdiobus_phy_device_register(ethernet_phy DT node)
> > > > -> Tried to get the IRQ listed in ethernet_phy and fails with
> > > > -EPROBE_DEFER because the IRQ driver isn't loaded yet.
> > > >
> > > > The error is propagated correctly all the way up to of_mdiobus_register(), but
> > > > mdio_mux_init() ignores the -EPROBE_DEFER from of_mdiobus_register() and just
> > > > continues on with the rest of the stuff and returns success as long as
> > > > one of the child nodes (in this case int_mdio) succeeds.
> > > >
> > > > Since the probe returns 0 without really succeeding, networking stuff
> > > > just fails badly after this. So, IMO, the real problem is with
> > > > mdio_mux_init() not propagating up the -EPROBE_DEFER. I gave Marc a
> > > > quick hack (pasted at the end of this email) to test my theory and he
> > > > confirmed that it fixes the issue (a few deferred probes later, things
> > > > work properly).
> > > >
> > > > Andrew, I don't see any good reason for mdio_mux_init() not
> > > > propagating the errors up correctly (at least for EPROBE_DEFER). I'll
> > > > send a patch to fix this. Please let me know if there's a reason it
> > > > has to stay as-is.
> > >
> > > I sent out the proper fix as a series:
> > > https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
> > >
> > > Marc, can you give it a shot please?
> > >
> > > -Saravana
> >
> > Superstar!  Thanks for taking the time to rectify this for all of us.
>
> Just to clarify:
>
>   Are we waiting on a subsequent patch submission at this point?

Not that I'm aware of. Andrew added a "Reviewed-by" to all 3 of my
proper fix patches. I didn't think I needed to send any newer patches.
Is there some reason you that I needed to?
https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t

-Saravana


>
> --
> Lee Jones [???]
> Senior Technical Lead - Developer Services
> Linaro.org ? Open source software for Arm SoCs
> Follow Linaro: Facebook | Twitter | Blog


From andrew at lunn.ch  Mon Aug 16 13:46:52 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 16 Aug 2021 22:46:52 +0200
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build
 as a module
In-Reply-To: <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>
References: <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <YQuZ2cKVE+3Os25Z@google.com> <YRpeVLf18Z+1R7WE@google.com>
 <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>
Message-ID: <YRrOvJBLp3WreEUf@lunn.ch>

> Not that I'm aware of. Andrew added a "Reviewed-by" to all 3 of my
> proper fix patches. I didn't think I needed to send any newer patches.
> Is there some reason you that I needed to?
> https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t

https://patchwork.kernel.org/project/netdevbpf/list/?series=&submitter=&state=*&q=net%3A+mdio-mux%3A+Delete+unnecessary+devm_kfree&archive=both&delegate=

State Changes Requested. I guess because you got the subject wrong.

With netdev, if it has not been merged within three days, you probably
need to resubmit.

     Andrew


From bjorn.andersson at linaro.org  Mon Aug 16 13:50:30 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Mon, 16 Aug 2021 15:50:30 -0500
Subject: [GIT PULL] Qualcomm ARM64 fixes for v5.14
Message-ID: <20210816205030.576348-1-bjorn.andersson@linaro.org>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-fixes-for-5.14

for you to fetch changes up to d77c95bf9a64d8620662151b2b10efd8221f4bcc:

  arm64: dts: qcom: sdm845-oneplus: fix reserved-mem (2021-08-05 10:36:04 -0500)

----------------------------------------------------------------
Qualcomm ARM64 fixes for v5.14

This fixes three regressions across Angler and Bullhead, introduced by
advancements in the platform definition. It then corrects the powerdown
GPIOs for the speaker amps on C630 and lastly fixes a typo that assigned
CPU7 in SC7280 to the wrong CPUfreq domain.

----------------------------------------------------------------
Caleb Connolly (1):
      arm64: dts: qcom: sdm845-oneplus: fix reserved-mem

Petr Vorel (3):
      arm64: dts: qcom: msm8992-bullhead: Remove PSCI
      arm64: dts: qcom: msm8992-bullhead: Fix cont_splash_mem mapping
      arm64: dts: qcom: msm8994-angler: Disable cont_splash_mem

Sibi Sankar (1):
      arm64: dts: qcom: sc7280: Fixup cpufreq domain info for cpu7

Srinivas Kandagatla (1):
      arm64: dts: qcom: c630: fix correct powerdown pin for WSA881x

 arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts | 12 ++++++++++++
 arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts   |  4 ++++
 arch/arm64/boot/dts/qcom/sc7280.dtsi                  |  2 +-
 arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi   |  4 ++--
 arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts  |  4 ++--
 5 files changed, 21 insertions(+), 5 deletions(-)


From bjorn.andersson at linaro.org  Mon Aug 16 14:00:14 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Mon, 16 Aug 2021 16:00:14 -0500
Subject: [GIT PULL] Qualcomm ARM64 defconfig updates for v5.15
Message-ID: <20210816210014.577699-1-bjorn.andersson@linaro.org>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-defconfig-for-5.15

for you to fetch changes up to 20d7a9fb00ebc53e73d49df0048afb02ef92a635:

  arm64: defconfig: Enable Qualcomm MSM8996 CPU clock driver (2021-08-04 15:02:54 -0500)

----------------------------------------------------------------
Qualcomm ARM64 defconfig updates for v5.15

This enabled the MSM8996 CPU clock driver, enabling CPUfreq on the
platform.

----------------------------------------------------------------
Bjorn Andersson (1):
      arm64: defconfig: Enable Qualcomm MSM8996 CPU clock driver

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)


From saravanak at google.com  Mon Aug 16 14:02:12 2021
From: saravanak at google.com (Saravana Kannan)
Date: Mon, 16 Aug 2021 14:02:12 -0700
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <YRrOvJBLp3WreEUf@lunn.ch>
References: <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <YQuZ2cKVE+3Os25Z@google.com> <YRpeVLf18Z+1R7WE@google.com>
 <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>
 <YRrOvJBLp3WreEUf@lunn.ch>
Message-ID: <CAGETcx_Q2-7B5RpHSfDu1KB0n+pT8nkCwGsthN20QBvgePcUtQ@mail.gmail.com>

On Mon, Aug 16, 2021 at 1:46 PM Andrew Lunn <andrew at lunn.ch> wrote:
>
> > Not that I'm aware of. Andrew added a "Reviewed-by" to all 3 of my
> > proper fix patches. I didn't think I needed to send any newer patches.
> > Is there some reason you that I needed to?
> > https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
>
> https://patchwork.kernel.org/project/netdevbpf/list/?series=&submitter=&state=*&q=net%3A+mdio-mux%3A+Delete+unnecessary+devm_kfree&archive=both&delegate=
>
> State Changes Requested. I guess because you got the subject wrong.

I'm assuming the prefix is wrong? What should it be? I went by looking
at the latest commit in:
$ git log --oneline  drivers/net/mdio/
ac53c26433b5 net: mdiobus: withdraw fwnode_mdbiobus_register

What prefix do I need to use to be considered correct?
net: mdio:?

>
> With netdev, if it has not been merged within three days, you probably
> need to resubmit.

Ah, thanks for the info. Since you didn't say anything, I assumed it'd
get in eventually and didn't really check the patchwork status.

-Saravana


From arnd at kernel.org  Mon Aug 16 14:14:33 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:14:33 +0200
Subject: [GIT PULL] soc/fsl drivers changes for fix(v5.14)
In-Reply-To: <20210813222305.13663-1-leoyang.li@nxp.com>
References: <20210813222305.13663-1-leoyang.li@nxp.com>
Message-ID: <162914846696.237742.13028145809209351673.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 17:23:05 -0500, Li Yang wrote:
> Please merge the following fixes for soc/fsl drivers.
> 
> Regards,
> Leo
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> [...]

Merged into arm/fixes, thanks!

merge commit: df97e5f3b21c3ed41385fa61cfb6e191044957ce

       Arnd


From arnd at kernel.org  Mon Aug 16 14:14:34 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:14:34 +0200
Subject: [PATCH] ARM: configs: Update the nhk8815_defconfig
In-Reply-To: <20210807225518.3607126-1-linus.walleij@linaro.org>
References: <20210807225518.3607126-1-linus.walleij@linaro.org>
Message-ID: <162914846686.237742.12685570963154533210.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sun, 8 Aug 2021 00:55:18 +0200, Linus Walleij wrote:
> The platform lost the framebuffer due to a commit solving a
> circular dependency in v5.14-rc1, so add it back in by explicitly
> selecting the framebuffer.
> 
> Also fix up some Kconfig options that got dropped or moved around
> while we're at it.

Applied to arm/fixes, thanks!

[1/1] ARM: configs: Update the nhk8815_defconfig
      commit: 813bacf4109802926d86f2d7c6583c6c0a0fddb5

       Arnd


From andrew at lunn.ch  Mon Aug 16 14:18:00 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 16 Aug 2021 23:18:00 +0200
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build
 as a module
In-Reply-To: <CAGETcx_Q2-7B5RpHSfDu1KB0n+pT8nkCwGsthN20QBvgePcUtQ@mail.gmail.com>
References: <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <YQuZ2cKVE+3Os25Z@google.com> <YRpeVLf18Z+1R7WE@google.com>
 <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>
 <YRrOvJBLp3WreEUf@lunn.ch>
 <CAGETcx_Q2-7B5RpHSfDu1KB0n+pT8nkCwGsthN20QBvgePcUtQ@mail.gmail.com>
Message-ID: <YRrWCC1E1nKDsx4N@lunn.ch>

On Mon, Aug 16, 2021 at 02:02:12PM -0700, Saravana Kannan wrote:
> On Mon, Aug 16, 2021 at 1:46 PM Andrew Lunn <andrew at lunn.ch> wrote:
> >
> > > Not that I'm aware of. Andrew added a "Reviewed-by" to all 3 of my
> > > proper fix patches. I didn't think I needed to send any newer patches.
> > > Is there some reason you that I needed to?
> > > https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
> >
> > https://patchwork.kernel.org/project/netdevbpf/list/?series=&submitter=&state=*&q=net%3A+mdio-mux%3A+Delete+unnecessary+devm_kfree&archive=both&delegate=
> >
> > State Changes Requested. I guess because you got the subject wrong.
> 
> I'm assuming the prefix is wrong? What should it be? I went by looking
> at the latest commit in:
> $ git log --oneline  drivers/net/mdio/
> ac53c26433b5 net: mdiobus: withdraw fwnode_mdbiobus_register
> 
> What prefix do I need to use to be considered correct?
> net: mdio:?

https://www.kernel.org/doc/html/latest/networking/netdev-FAQ.html

and in particular:

https://www.kernel.org/doc/html/latest/networking/netdev-FAQ.html#how-do-i-indicate-which-tree-net-vs-net-next-my-patch-should-be-in

	Andrew


From bjorn.andersson at linaro.org  Mon Aug 16 14:19:57 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Mon, 16 Aug 2021 16:19:57 -0500
Subject: [GIT PULL] Qualcomm dts updates for v5.15
Message-ID: <20210816211957.579365-1-bjorn.andersson@linaro.org>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-dts-for-5.15

for you to fetch changes up to f95c4c56d65225a537a2d88735fde7ec4d37641d:

  ARM: dts: qcom: add ahb reset to ipq806x-gmac (2021-08-05 09:24:37 -0500)

----------------------------------------------------------------
Qualcomm dts updates for v5.15

This introduces the MSM8226 platform and an initial dts for the Samsung
Galaxy S III Neo phone.

MSM8974 gains another UART and this is used to enable Bluetooth on the
Sony Xperia Z2 Tablet. Samsung Galaxy S5 gains regulator definitions for
audio and modem remoteprocs, effectively enabling these.

DSI clocks on APQ8064 are updates as the old legacy clock names are no
longer supported by the driver. And IPQ806x GMAC nodes gains AHB resets
wired up.

Lastly APQ8060 is converted to a SPDX header and the ethernet node is
updates in accordance with the binding.

----------------------------------------------------------------
Alexey Minnekhanov (1):
      ARM: dts: qcom: msm8974-klte: Enable remote processors

Bartosz Dudziak (3):
      ARM: dts: qcom: Add support for MSM8226 SoC
      dt-bindings: arm: qcom: Document MSM8226 SoC binding
      ARM: dts: qcom: Add initial DTS file for Samsung Galaxy S III Neo phone

Bjorn Andersson (1):
      ARM: dts: qcom: msm8974: castor: Add Bluetooth-related nodes

Craig Tatlor (1):
      ARM: dts: qcom: msm8974: Add blsp2_uart7 for bluetooth on sirius

David Heidelberg (1):
      ARM: dts: qcom: apq8064: correct clock names

Geert Uytterhoeven (1):
      ARM: dts: qcom: apq8060: Correct Ethernet node name and drop bogus irq property

Linus Walleij (1):
      ARM: dts: qcom: Fix up APQ8060 DragonBoard license

Matthew Hagan (1):
      ARM: dts: qcom: add ahb reset to ipq806x-gmac

 Documentation/devicetree/bindings/arm/qcom.yaml    |   6 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/qcom-apq8060-dragonboard.dts     |  27 +---
 arch/arm/boot/dts/qcom-apq8064.dtsi                |   6 +-
 arch/arm/boot/dts/qcom-ipq8064.dtsi                |  20 +--
 arch/arm/boot/dts/qcom-msm8226-samsung-s3ve3g.dts  |  25 ++++
 arch/arm/boot/dts/qcom-msm8226.dtsi                | 147 +++++++++++++++++++++
 arch/arm/boot/dts/qcom-msm8974-samsung-klte.dts    |  11 ++
 .../boot/dts/qcom-msm8974-sony-xperia-castor.dts   |  81 ++++++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi                |   9 ++
 10 files changed, 297 insertions(+), 36 deletions(-)
 create mode 100644 arch/arm/boot/dts/qcom-msm8226-samsung-s3ve3g.dts
 create mode 100644 arch/arm/boot/dts/qcom-msm8226.dtsi


From arnd at kernel.org  Mon Aug 16 14:20:48 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:20:48 +0200
Subject: [GIT PULL 1/2] Renesas ARM DT updates for v5.15 (take two)
In-Reply-To: <cover.1628849623.git.geert+renesas@glider.be>
References: <cover.1628849621.git.geert+renesas@glider.be>
 <cover.1628849623.git.geert+renesas@glider.be>
Message-ID: <162914852219.237905.10683958407915595103.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 12:22:35 +0200, Geert Uytterhoeven wrote:
> The following changes since commit 651f8cffade8615bb4fce1ecb3a929892c5e60d7:
> 
>   arm64: dts: renesas: r8a77961: Add iommus to ipmmu_ds[01] related nodes (2021-07-30 15:07:25 +0200)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-arm-dt-for-v5.15-tag2
> 
> [...]

Merged into arm/dt, thanks!

merge commit: d5aa0245860732268b94d9989e2ade382770fd13

       Arnd


From arnd at kernel.org  Mon Aug 16 14:20:49 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:20:49 +0200
Subject: [GIT PULL] arm64: dts: amlogic updates for v5.15 part 2
In-Reply-To: <47d77095-eee7-bbd9-d3aa-1dabeea3f0b9@baylibre.com>
References: <47d77095-eee7-bbd9-d3aa-1dabeea3f0b9@baylibre.com>
Message-ID: <162914852228.237905.17625199363925328243.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 16:12:59 +0200, Neil Armstrong wrote:
> Here's the second set of ARM64 DT changes for v5.15:
> - add audio nodes for vega-s95 & nexbox-a1
> 
> Neil
> 
> The following changes since commit 4b5260032ec691b11a9185f7f38f5761e67fab48:
> 
>   arm64: dts: meson: improve gxm-khadas-vim2 wifi (2021-07-26 10:08:16 +0200)
> 
> [...]

Merged into arm/dt, thanks!

merge commit: fba65f104ea83d188ef470a3f32c519a7f4b5796

       Arnd


From arnd at kernel.org  Mon Aug 16 14:20:50 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:20:50 +0200
Subject: [GIT PULL 1/4] i.MX DT bindings update for 5.15
In-Reply-To: <20210814133853.9981-1-shawnguo@kernel.org>
References: <20210814133853.9981-1-shawnguo@kernel.org>
Message-ID: <162914852265.237905.13250400572485864130.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sat, 14 Aug 2021 21:38:50 +0800, Shawn Guo wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-bindings-5.15
> 
> [...]

Merged into arm/dt, thanks!

merge commit: fe3be9941e3c5cebd59d3ad02477db86af85e2da

       Arnd


From arnd at kernel.org  Mon Aug 16 14:20:52 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:20:52 +0200
Subject: [GIT PULL 1/6] dt-bindings: Changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-1-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
Message-ID: <162914852238.237905.17270063246440695138.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 18:21:52 +0200, Thierry Reding wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-dt-bindings
> 
> [...]

Merged into arm/dt, thanks!

merge commit: b05cff9f4d38cd4a9ccc387a8054f9efe8e8414f

       Arnd


From arnd at kernel.org  Mon Aug 16 14:20:51 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:20:51 +0200
Subject: [GIT PULL 3/4] i.MX arm64 device tree changes for 5.15
In-Reply-To: <20210814133853.9981-3-shawnguo@kernel.org>
References: <20210814133853.9981-1-shawnguo@kernel.org>
 <20210814133853.9981-3-shawnguo@kernel.org>
Message-ID: <162914852275.237905.12467380733542319999.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sat, 14 Aug 2021 21:38:52 +0800, Shawn Guo wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-dt64-5.15
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 6d640913126db109f2e3389173f0fe42413a8183

       Arnd


From arnd at kernel.org  Mon Aug 16 14:20:53 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:20:53 +0200
Subject: [GIT PULL 4/6] ARM: tegra: Device tree changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-4-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
 <20210813162157.2820913-4-thierry.reding@gmail.com>
Message-ID: <162914852247.237905.11712885319102863319.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 18:21:55 +0200, Thierry Reding wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-arm-dt
> 
> [...]

Merged into arm/dt, thanks!

merge commit: aadf2b3857ad1d09fb28f08058a746f04698f81b

       Arnd


From arnd at kernel.org  Mon Aug 16 14:20:54 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:20:54 +0200
Subject: [GIT PULL 6/6] arm64: tegra: Device tree changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-6-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
 <20210813162157.2820913-6-thierry.reding@gmail.com>
Message-ID: <162914852256.237905.7021775229797910596.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 18:21:57 +0200, Thierry Reding wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-arm64-dt
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 1de48932389887f83f0f560c741dd57cc69a40b2

       Arnd


From arnd at kernel.org  Mon Aug 16 14:21:24 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:21:24 +0200
Subject: [GIT PULL 2/4] i.MX arm32 device tree changes for 5.15
In-Reply-To: <20210814133853.9981-2-shawnguo@kernel.org>
References: <20210814133853.9981-1-shawnguo@kernel.org>
 <20210814133853.9981-2-shawnguo@kernel.org>
Message-ID: <162914887787.238436.2285917910205643269.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sat, 14 Aug 2021 21:38:51 +0800, Shawn Guo wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-dt-5.15
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 9b35ab1e314c3f563f8d6982c0a8f2c8964e4a36

       Arnd


From arnd at kernel.org  Mon Aug 16 14:22:47 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:22:47 +0200
Subject: [GIT PULL] Qualcomm ARM64 fixes for v5.14
In-Reply-To: <20210816205030.576348-1-bjorn.andersson@linaro.org>
References: <20210816205030.576348-1-bjorn.andersson@linaro.org>
Message-ID: <162914895749.238791.1673033166208068515.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 16 Aug 2021 15:50:30 -0500, Bjorn Andersson wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-fixes-for-5.14
> 
> [...]

Merged into arm/fixes, thanks!

merge commit: d0dc706ab1924e2f41677741cfa26f1c9ed6ce93

       Arnd


From arnd at kernel.org  Mon Aug 16 14:33:54 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:33:54 +0200
Subject: [GIT PULL] Qualcomm ARM64 defconfig updates for v5.15
In-Reply-To: <20210816210014.577699-1-bjorn.andersson@linaro.org>
References: <20210816210014.577699-1-bjorn.andersson@linaro.org>
Message-ID: <162914958933.240013.2336454374694008313.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 16 Aug 2021 16:00:14 -0500, Bjorn Andersson wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-defconfig-for-5.15
> 
> [...]

Merged into arm/defconfig, thanks!

merge commit: ecdbda1746b5bf771cd86dfeb84c20d62f5bfc51

       Arnd


From arnd at kernel.org  Mon Aug 16 14:33:55 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:33:55 +0200
Subject: [GIT PULL 4/4] i.MX defconfig update for 5.15
In-Reply-To: <20210814133853.9981-4-shawnguo@kernel.org>
References: <20210814133853.9981-1-shawnguo@kernel.org>
 <20210814133853.9981-4-shawnguo@kernel.org>
Message-ID: <162914958924.240013.14798086285090389269.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sat, 14 Aug 2021 21:38:53 +0800, Shawn Guo wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-defconfig-5.15
> 
> [...]

Merged into arm/defconfig, thanks!

merge commit: 1f69aabe1ac06cd5005352fb9314e7409b712487

       Arnd


From arnd at kernel.org  Mon Aug 16 14:33:56 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 16 Aug 2021 23:33:56 +0200
Subject: [GIT PULL 5/6] ARM: tegra: Default configuration changes for
 v5.15-rc1
In-Reply-To: <20210813162157.2820913-5-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
 <20210813162157.2820913-5-thierry.reding@gmail.com>
Message-ID: <162914958916.240013.16079818037354285640.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 18:21:56 +0200, Thierry Reding wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-arm-defconfig
> 
> [...]

Merged into arm/defconfig, thanks!

merge commit: 03bc43c09d0cd7f4a7813b10433d653ec5a02b09

       Arnd


From sam at ravnborg.org  Mon Aug 16 14:36:13 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Mon, 16 Aug 2021 23:36:13 +0200
Subject: [RFC PATCH 5/5] drm/mediatek: Add mt8195 DisplayPort driver
In-Reply-To: <20210816192523.1739365-6-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-6-msp@baylibre.com>
Message-ID: <YRraTWcY4yVuJANQ@ravnborg.org>

Hi Markus,

A few general things in the following. This is what I look for first in
a bridge driver - and I had no time today to review the driver in full.
Please address these, then cc: me on next revision where I hopefully
have more time.

	Sam

> +static int mtk_dp_bridge_attach(struct drm_bridge *bridge,
> +                               enum drm_bridge_attach_flags flags)
> +{
> +       struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
> +       int ret;
> +
> +       mtk_dp_poweron(mtk_dp);
> +
> +       if (mtk_dp->next_bridge) {
> +               ret = drm_bridge_attach(bridge->encoder, mtk_dp->next_bridge,
> +                                       &mtk_dp->bridge, flags);
> +               if (ret) {
> +                       drm_warn(mtk_dp->drm_dev,
> +                                "Failed to attach external bridge: %d\n", ret);
> +                       return ret;
> +               }
> +       }
> +
> +       if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
> +               drm_err(mtk_dp->drm_dev,
> +                       "Fix bridge driver to make connector optional!");
> +               return 0;
> +       }

This driver is only used by mediatek, and I thought all of mediatek is
converted so the display driver creates the connector.

It would be better to migrate mediatek over to always let the display
driver create the connector and drop the connector support in this
driver.


> + struct drm_bridge_funcs mtk_dp_bridge_funcs = {
> +	.attach = mtk_dp_bridge_attach,
> +	.mode_fixup = mtk_dp_bridge_mode_fixup,
> +	.disable = mtk_dp_bridge_disable,
> +	.post_disable = mtk_dp_bridge_post_disable,
> +	.mode_set = mtk_dp_bridge_mode_set,
> +	.pre_enable = mtk_dp_bridge_pre_enable,
> +	.enable = mtk_dp_bridge_enable,
> +	.get_edid = mtk_get_edid,
> +	.detect = mtk_dp_bdg_detect,
> +};


For new drivers please avoid the recently deprecated functions.

- Use the atomic versions of pre_enable, enable, disable and post_disable.

- Merge mode_set with atomic_enable - as there is no need for the mode_Set
  operation.

- Use atomic_check in favour of mode_fixup, albeit the rules for
  atomic_check is at best vauge at the moment.
 



From bjorn.andersson at linaro.org  Mon Aug 16 14:48:40 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Mon, 16 Aug 2021 16:48:40 -0500
Subject: [GIT PULL] Qualcomm driver updates for v5.15
Message-ID: <20210816214840.581244-1-bjorn.andersson@linaro.org>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-drivers-for-5.15

for you to fetch changes up to e3d4571955050736bbf3eda0a9538a09d9fcfce8:

  soc: qcom: smsm: Fix missed interrupts if state changes while masked (2021-08-04 22:20:09 -0500)

----------------------------------------------------------------
Qualcomm driver updates for v5.15

This fixes the "shared memory state machine" (SMSM) interrupt logic to
avoid missing transitions happening while the interrupts are masked.

SM6115 support is added to smd-rpm and rpmpd.

The Qualcomm SCM firmware driver is once again made possible to compile
and load as a kernel module.

An out-of-bounds error related to the cooling devices of the AOSS driver
is corrected. The binding is converted to YAML and a generic compatible
is introduced to reduce the driver churn.

The GENI wrapper gains a helper function used in I2C and SPI for
switching the serial engine hardware to use the wrapper's DMA-engine.

Lastly it contains a number of cleanups and smaller fixes for rpmhpd,
socinfo, CPR, mdt_loader and the GENI DT binding.

----------------------------------------------------------------
Alex Elder (1):
      soc: qcom: mdt_loader: be more informative on errors

Bjorn Andersson (4):
      dt-bindings: soc: qcom: aoss: Add SC8180X and generic compatible
      dt-bindings: soc: qcom: aoss: Convert to YAML
      soc: qcom: aoss: Add generic compatible
      soc: qcom: rpmhpd: Use corner in power_off

Caleb Connolly (1):
      dt-bindings: qcom: geni-se: document iommus

Douglas Anderson (1):
      PM: AVS: qcom-cpr: Use nvmem_cell_read_variable_le_u32()

Iskren Chernev (4):
      dt-bindings: soc: qcom: smd-rpm: Add SM6115 compatible
      dt-bindings: power: rpmpd: Add SM6115 to rpmpd binding
      drivers: soc: qcom: rpmpd: Add SM6115 RPM Power Domains
      soc: qcom: smd-rpm: Add SM6115 compatible

John Stultz (1):
      firmware: qcom_scm: Allow qcom_scm driver to be loadable as a permenent module

Junlin Yang (1):
      firmware: qcom_scm: remove a duplicative condition

Manivannan Sadhasivam (1):
      soc: qcom: aoss: Fix the out of bound usage of cooling_devs

Stephan Gerhold (2):
      soc: qcom: smsm: Implement support for get_irqchip_state
      soc: qcom: smsm: Fix missed interrupts if state changes while masked

Stephen Boyd (2):
      firmware: qcom_scm: Mark string array const
      soc: qcom: socinfo: Don't print anything if nothing found

Vinod Koul (2):
      soc: qcom: geni: move GENI_IF_DISABLE_RO to common header
      soc: qcom: geni: Add support for gpi dma

 .../devicetree/bindings/power/qcom,rpmpd.yaml      |   1 +
 .../devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt |  87 ----------------
 .../bindings/soc/qcom/qcom,aoss-qmp.yaml           | 114 +++++++++++++++++++++
 .../devicetree/bindings/soc/qcom/qcom,geni-se.yaml |   3 +
 .../devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml |   1 +
 drivers/firmware/Kconfig                           |   2 +-
 drivers/firmware/Makefile                          |   3 +-
 drivers/firmware/qcom_scm.c                        |   8 +-
 drivers/iommu/Kconfig                              |   2 +
 drivers/net/wireless/ath/ath10k/Kconfig            |   1 +
 drivers/soc/qcom/cpr.c                             |  43 +-------
 drivers/soc/qcom/mdt_loader.c                      |  18 ++--
 drivers/soc/qcom/qcom-geni-se.c                    |  30 +++++-
 drivers/soc/qcom/qcom_aoss.c                       |   9 +-
 drivers/soc/qcom/rpmhpd.c                          |   5 +-
 drivers/soc/qcom/rpmpd.c                           |  28 +++++
 drivers/soc/qcom/smd-rpm.c                         |   1 +
 drivers/soc/qcom/smsm.c                            |  28 ++++-
 drivers/soc/qcom/socinfo.c                         |   4 +-
 include/dt-bindings/power/qcom-rpmpd.h             |  10 ++
 include/linux/qcom-geni-se.h                       |  19 +++-
 21 files changed, 269 insertions(+), 148 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml


From jacek.anaszewski at gmail.com  Mon Aug 16 15:03:49 2021
From: jacek.anaszewski at gmail.com (Jacek Anaszewski)
Date: Tue, 17 Aug 2021 00:03:49 +0200
Subject: [PATCH v3 2/5] leds: Add driver for QCOM SPMI Flash LEDs
In-Reply-To: <20210803162641.1525980-3-nfraprado@collabora.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
 <20210803162641.1525980-3-nfraprado@collabora.com>
Message-ID: <b1060e9a-f78e-fbe9-bde3-2b4d89cbc73e@gmail.com>

Hi Nicolas,

Thanks for the update. See my comments below.

On 8/3/21 6:26 PM, N?colas F. R. A. Prado wrote:
> Add driver for Qualcomm's SPMI Flash LEDs. These are controlled
> through an SPMI bus and are part of the PM8941 PMIC. There are two LEDs
> present on the chip, which can be used independently as camera flash or,
> when in torch mode, as a lantern.
> 
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> ---
> 
> Changes in v3:
> - The two LEDs can now be operated independently even when in torch mode
> - The flashes can now strobe consecutive times without needing to manually
>    disable them between strobes
> - Implemented strobe_get()
> - Moved dt parsing to a separate function
> - Split multiplexed torch/flash on/off and torch/flash regulator on/off
>    functions
> - Set current on brightness callback and timeout on timeout callback, instead of
>    setting everything every time when strobing/turning torch on
> - And a whole lot of other minor changes
> 
> Changes in v2:
> - Thanks to Jacek:
>    - Implemented flash LED class framework
> - Thanks to Bjorn:
>    - Renamed driver to "qcom spmi flash"
> - Refactored code
> - Added missing copyright
> 
>   drivers/leds/flash/Kconfig                |    8 +
>   drivers/leds/flash/Makefile               |    1 +
>   drivers/leds/flash/leds-qcom-spmi-flash.c | 1251 +++++++++++++++++++++
>   3 files changed, 1260 insertions(+)
>   create mode 100644 drivers/leds/flash/leds-qcom-spmi-flash.c
> 
> diff --git a/drivers/leds/flash/Kconfig b/drivers/leds/flash/Kconfig
> index 3f49f3edbffb..72f61323cd2a 100644
> --- a/drivers/leds/flash/Kconfig
> +++ b/drivers/leds/flash/Kconfig
> @@ -24,4 +24,12 @@ config LEDS_RT8515
>   	  To compile this driver as a module, choose M here: the module
>   	  will be called leds-rt8515.
>   
> +config LEDS_QCOM_SPMI_FLASH
> +	tristate "Support for QCOM SPMI Flash LEDs"
> +	depends on REGMAP_SPMI
> +	depends on OF
> +	help
> +	  This option enables support for the flash/torch LEDs present in
> +	  Qualcomm's PM8941 PMIC.
> +
>   endif # LEDS_CLASS_FLASH
> diff --git a/drivers/leds/flash/Makefile b/drivers/leds/flash/Makefile
> index 09aee561f769..c141d277e9b6 100644
> --- a/drivers/leds/flash/Makefile
> +++ b/drivers/leds/flash/Makefile
> @@ -2,3 +2,4 @@
>   
>   obj-$(CONFIG_LEDS_RT4505)	+= leds-rt4505.o
>   obj-$(CONFIG_LEDS_RT8515)	+= leds-rt8515.o
> +obj-$(CONFIG_LEDS_QCOM_SPMI_FLASH)	+= leds-qcom-spmi-flash.o
> diff --git a/drivers/leds/flash/leds-qcom-spmi-flash.c b/drivers/leds/flash/leds-qcom-spmi-flash.c
> new file mode 100644
> index 000000000000..9763707bb986
> --- /dev/null
> +++ b/drivers/leds/flash/leds-qcom-spmi-flash.c
> @@ -0,0 +1,1251 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Qualcomm SPMI Flash LEDs Driver
> + *
> + * Copyright (c) 2020-2021, N?colas F. R. A. Prado <n at nfraprado.net>
> + * Copyright (c) 2021, Collabora Ltd.
> + *
> + * Based on QPNP LEDs driver from downstream MSM kernel sources.
> + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/led-class-flash.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/spmi.h>
> +#include <linux/string.h>
> +#include <linux/sysfs.h>
> +#include <linux/types.h>
> +
> +#define QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE	0x05
> +#define QCOM_FLASH_ADDR_STATUS			0x10
> +#define QCOM_FLASH_ADDR_SAFETY_TIMER		0x40
> +#define QCOM_FLASH_ADDR_MAX_CURR		0x41
> +#define QCOM_FLASH_ADDR_CURR_LED0		0x42
> +#define QCOM_FLASH_ADDR_CURR_LED1		0x43
> +#define QCOM_FLASH_ADDR_CLAMP_CURR		0x44
> +#define QCOM_FLASH_ADDR_ENABLE_CONTROL		0x46
> +#define QCOM_FLASH_ADDR_LED_STROBE_CTRL		0x47
> +#define QCOM_FLASH_ADDR_LED_TMR_CTRL		0x48
> +#define QCOM_FLASH_ADDR_HEADROOM		0x4A
> +#define QCOM_FLASH_ADDR_STARTUP_DELAY		0x4B
> +#define QCOM_FLASH_ADDR_MASK_ENABLE		0x4C
> +#define QCOM_FLASH_ADDR_VREG_OK_FORCE		0x4F
> +#define QCOM_FLASH_ADDR_LED_UNLOCK_SECURE	0xD0
> +#define QCOM_FLASH_ADDR_LED_TORCH		0xE4
> +#define QCOM_FLASH_ADDR_FAULT_DETECT		0x51
> +#define QCOM_FLASH_ADDR_RAMP_RATE		0x54
> +#define QCOM_FLASH_ADDR_VPH_PWR_DROOP		0x5A
> +
> +#define QCOM_FLASH_MAX_LEVEL		0x4F
> +#define QCOM_FLASH_TORCH_MAX_LEVEL	0x0F
> +#define	QCOM_FLASH_NO_MASK		0x00
> +
> +#define QCOM_FLASH_MASK_1		0x20
> +#define QCOM_FLASH_MASK_REG_MASK	0xE0
> +#define QCOM_FLASH_HEADROOM_MASK	0x03
> +#define QCOM_FLASH_SAFETY_TIMER_MASK	0x7F
> +#define QCOM_FLASH_CURRENT_MASK		0xFF
> +#define QCOM_FLASH_MAX_CURRENT_MASK	0x7F
> +#define QCOM_FLASH_TMR_MASK		0x03
> +#define QCOM_FLASH_TMR_WATCHDOG		0x03
> +#define QCOM_FLASH_TMR_SAFETY		0x00
> +#define QCOM_FLASH_FAULT_DETECT_MASK	0x80
> +#define QCOM_FLASH_HW_VREG_OK		0x40
> +#define QCOM_FLASH_VREG_MASK		0xC0
> +#define QCOM_FLASH_STARTUP_DLY_MASK	0x02
> +#define QCOM_FLASH_RAMP_RATE_MASK	0xBF
> +#define QCOM_FLASH_VPH_PWR_DROOP_MASK	0xF3
> +
> +#define QCOM_FLASH_ENABLE_ALL		0xE0
> +#define QCOM_FLASH_ENABLE_MODULE	0x80
> +#define QCOM_FLASH_ENABLE_MODULE_MASK	0x80
> +#define QCOM_FLASH_DISABLE_ALL		0x00
> +#define QCOM_FLASH_ENABLE_MASK		0xE0
> +#define QCOM_FLASH_ENABLE_LED0		0xC0
> +#define QCOM_FLASH_ENABLE_LED1		0xA0
> +#define QCOM_FLASH_INIT_MASK		0xE0
> +#define QCOM_FLASH_SELFCHECK_ENABLE	0x80
> +#define QCOM_FLASH_SELFCHECK_DISABLE	0x00
> +
> +#define QCOM_FLASH_STROBE_SW		0xC0
> +#define QCOM_FLASH_STROBE_HW		0x04
> +#define QCOM_FLASH_STROBE_MASK		0xC7
> +#define QCOM_FLASH_STROBE_LED0		0x80
> +#define QCOM_FLASH_STROBE_LED1		0x40
> +
> +#define QCOM_FLASH_TORCH_MASK		0x03
> +#define QCOM_FLASH_LED_TORCH_ENABLE	0x00
> +#define QCOM_FLASH_LED_TORCH_DISABLE	0x03
> +#define QCOM_FLASH_UNLOCK_SECURE	0xA5
> +#define QCOM_FLASH_SECURE_MASK		0xFF
> +
> +#define QCOM_FLASH_SUBTYPE_DUAL		0x01
> +#define QCOM_FLASH_SUBTYPE_SINGLE	0x02
> +
> +#define QCOM_FLASH_DURATION_STEP	10000
> +#define QCOM_FLASH_DURATION_MIN		10000
> +#define QCOM_FLASH_DURATION_DEFAULT	200000
> +
> +#define QCOM_FLASH_CURRENT_STEP		12500
> +#define QCOM_FLASH_CURRENT_MIN		12500
> +
> +#define QCOM_FLASH_DEFAULT_CLAMP	200000
> +
> +#define QCOM_FLASH_MASK_ON_LED0		0x8
> +#define QCOM_FLASH_MASK_ON_LED1		0x2
> +#define QCOM_FLASH_MASK_STATUS_TIMEDOUT	0x5
> +
> +enum qcom_flash_headroom {
> +	QCOM_FLASH_HEADROOM_250MV,
> +	QCOM_FLASH_HEADROOM_300MV,
> +	QCOM_FLASH_HEADROOM_400MV,
> +	QCOM_FLASH_HEADROOM_500MV,
> +};
> +
> +enum qcom_flash_startup_dly {
> +	QCOM_FLASH_STARTUP_DLY_10US,
> +	QCOM_FLASH_STARTUP_DLY_32US,
> +	QCOM_FLASH_STARTUP_DLY_64US,
> +	QCOM_FLASH_STARTUP_DLY_128US,
> +};
> +
> +enum qcom_flash_ids {
> +	QCOM_FLASH_ID_LED0,
> +	QCOM_FLASH_ID_LED1,
> +};
> +
> +/**
> + * struct qcom_flash_led - Represents each individual flash LED
> + * @fled_cdev: flash LED classdev
> + * @id: LED ID as given by enum qcom_flash_ids
> + * @default_on: default state for the LED
> + * @flash_enable_cmd: enable command for particular flash
> + * @flash_strobe_cmd: strobe command for particular flash
> + * @current_addr: address to write for current
> + * @mask_led_on: bitmask for STATUS register that shows if LED is on
> + * @flash_current_invalidated: whether the flash current in the current register
> + *	was invalidated by torch usage
> + */
> +struct qcom_flash_led {
> +	struct led_classdev_flash fled_cdev;
> +	enum qcom_flash_ids id;
> +	bool default_on;
> +	u8 flash_enable_cmd;
> +	u8 flash_strobe_cmd;
> +	u16 current_addr;
> +	u8 mask_led_on;
> +	bool flash_current_invalidated;
> +};
> +
> +/**
> + * struct qcom_flash_device - QCOM SPMI Flash device, contains 2 flash LEDs
> + * @regmap: regmap used to access LED registers over SPMI
> + * @base: base register given in device tree
> + * @dev: device from devicetree
> + * @flash_supply: voltage regulator to supply the flashes
> + * @torch_supply: voltage regulator to supply torch mode
> + * @leds: flash LEDs
> + * @num_leds: number of LEDs registered (between 0 and 2)
> + * @lock: lock to protect SPMI transactions
> + * @torch_enable_cmd: enable flash LED torch mode
> + * @peripheral_subtype: module peripheral subtype
> + * @flash_regulator_on: flash regulator status
> + * @torch_regulator_on: torch regulator status
> + * @torch_enabled: whether torch mode is enabled
> + */
> +struct qcom_flash_device {
> +	struct regmap *regmap;
> +	unsigned int base;
> +	struct device *dev;
> +	struct regulator *flash_supply;
> +	struct regulator *torch_supply;
> +	struct qcom_flash_led leds[2];
> +	u8 num_leds;
> +	struct mutex lock;
> +	u8 torch_enable_cmd;
> +	unsigned int peripheral_subtype;
> +	bool flash_regulator_on;
> +	bool torch_regulator_on;
> +	bool torch_enabled;
> +};
> +
> +struct qcom_flash_config {
> +	unsigned int base;
> +	struct regulator *flash_supply;
> +	struct regulator *torch_supply;
> +	unsigned int num_leds;
> +
> +	enum qcom_flash_ids id[2];
> +	bool default_on[2];
> +	u32 led_max_brightness[2];
> +	u32 flash_max_brightness[2];
> +	u32 flash_max_timeout[2];
> +};
> +
> +static inline struct qcom_flash_led *flcdev_to_led(struct led_classdev_flash *fled_cdev)
> +{
> +	return container_of(fled_cdev, struct qcom_flash_led, fled_cdev);
> +}
> +
> +static inline struct qcom_flash_device *led_to_leds_dev(struct qcom_flash_led *led)
> +{
> +	return container_of(led, struct qcom_flash_device, leds[led->id]);
> +}
> +
> +static inline int qcom_flash_read_reg(struct qcom_flash_device *leds_dev,
> +				      unsigned int reg, unsigned int *val)
> +{
> +	return regmap_read(leds_dev->regmap, leds_dev->base + reg, val);
> +}
> +
> +static inline int qcom_flash_masked_write(struct qcom_flash_device *leds_dev,
> +					  unsigned int reg, unsigned int mask,
> +					  unsigned int val)
> +{
> +	return regmap_update_bits(leds_dev->regmap, leds_dev->base + reg, mask,
> +				  val);
> +}
> +
> +static u8 qcom_flash_duration_to_reg(u32 us)
> +{
> +	if (us < QCOM_FLASH_DURATION_MIN)
> +		us = QCOM_FLASH_DURATION_MIN;
> +	return (us - QCOM_FLASH_DURATION_MIN) / QCOM_FLASH_DURATION_STEP;
> +}
> +
> +static u8 qcom_flash_current_to_reg(u32 ua)
> +{
> +	if (ua < QCOM_FLASH_CURRENT_MIN)
> +		ua = QCOM_FLASH_CURRENT_MIN;
> +	return (ua - QCOM_FLASH_CURRENT_MIN) / QCOM_FLASH_CURRENT_STEP;
> +}
> +
> +static void clamp_align(u32 *v, u32 min, u32 max, u32 step)
> +{
> +	*v = clamp_val(*v, min, max);
> +	if (step > 1)
> +		*v = (*v - min) / step * step + min;
> +}
> +
> +static int qcom_flash_status_get(struct qcom_flash_led *led)
> +{
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	unsigned int status;
> +	int rc;
> +
> +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_STATUS, &status);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Failure reading status, rc =  %d\n",
> +			rc);
> +		return rc;
> +	}
> +
> +	return status & led->mask_led_on;
> +}
> +
> +static int qcom_flash_status_clear(struct qcom_flash_device *leds_dev)
> +{
> +	unsigned int enable_val;
> +	int rc;
> +
> +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +				 &enable_val);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Enable reg read failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +				     QCOM_FLASH_ENABLE_MASK, QCOM_FLASH_DISABLE_ALL);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +				     QCOM_FLASH_ENABLE_MASK, enable_val);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);

It would be good to have different error messages to discern between
the two above calls' failures.

> +		return rc;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_check_timedout(struct qcom_flash_device *leds_dev)
> +{
> +	unsigned int status;
> +	int rc;
> +
> +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_STATUS, &status);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Failure reading status, rc =  %d\n",
> +			rc);
> +		return rc;
> +	}
> +
> +	return status & QCOM_FLASH_MASK_STATUS_TIMEDOUT;
> +}
> +
> +static int qcom_flash_torch_reg_enable(struct qcom_flash_device *leds_dev,
> +				       bool state)
> +{
> +	int rc;
> +
> +	if (leds_dev->torch_enabled == state)
> +		return 0;
> +
> +	/*
> +	 * For the TORCH register (0xE4) to become writable, the UNLOCK_SECURE
> +	 * register (0xD0) needs to be written with the UNLOCK_SECURE value
> +	 * (0xA5) first.
> +	 * It gets re-locked after any register write.
> +	 */
> +	rc = qcom_flash_masked_write(leds_dev,
> +				     QCOM_FLASH_ADDR_LED_UNLOCK_SECURE,
> +				     QCOM_FLASH_SECURE_MASK,
> +				     QCOM_FLASH_UNLOCK_SECURE);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Secure reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_TORCH,
> +				     QCOM_FLASH_TORCH_MASK,
> +				     state ? QCOM_FLASH_LED_TORCH_ENABLE :
> +					     QCOM_FLASH_LED_TORCH_DISABLE);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Torch reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_max_brightness_set(struct qcom_flash_led *led,
> +					 unsigned int brightness)
> +{
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	struct device *dev = leds_dev->dev;
> +	int rc;
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_MAX_CURR,
> +				     QCOM_FLASH_CURRENT_MASK, brightness);
> +	if (rc) {
> +		dev_err(dev, "Max current reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_brightness_set(struct qcom_flash_led *led,
> +				     unsigned int brightness)
> +{
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	struct device *dev = leds_dev->dev;
> +	int rc;
> +
> +	rc = qcom_flash_masked_write(leds_dev, led->current_addr,
> +				     QCOM_FLASH_CURRENT_MASK, brightness);
> +	if (rc) {
> +		dev_err(dev, "Current reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_fled_regulator_on(struct qcom_flash_device *leds_dev)
> +{
> +	int rc;
> +
> +	if (leds_dev->flash_regulator_on)
> +		return 0;
> +
> +	rc = regulator_enable(leds_dev->flash_supply);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Regulator enable failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	leds_dev->flash_regulator_on = true;
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_fled_regulator_off(struct qcom_flash_device *leds_dev)
> +{
> +	unsigned int i;
> +	u8 enable = 0;
> +	int rc;
> +
> +	if (!leds_dev->flash_regulator_on)
> +		return 0;
> +
> +	for (i = 0; i < leds_dev->num_leds; i++) {
> +		rc = qcom_flash_status_get(&leds_dev->leds[i]);
> +		if (rc < 0)
> +			return rc;
> +
> +		if (!rc)
> +			continue;
> +
> +		enable |= leds_dev->leds[i].flash_enable_cmd;
> +	}
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +				     QCOM_FLASH_ENABLE_MASK, enable);
> +	if (rc)
> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> +
> +	if (enable)
> +		return 0;
> +
> +	rc = regulator_disable(leds_dev->flash_supply);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Regulator disable failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	leds_dev->flash_regulator_on = false;
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_torch_regulator_on(struct qcom_flash_device *leds_dev)
> +{
> +	int rc;
> +
> +	if (leds_dev->torch_regulator_on)
> +		return 0;
> +
> +	rc = regulator_enable(leds_dev->torch_supply);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Regulator enable failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	leds_dev->torch_regulator_on = true;
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_torch_regulator_off(struct qcom_flash_device *leds_dev)
> +{
> +	int rc;
> +
> +	if (!leds_dev->torch_regulator_on)
> +		return 0;
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +				     QCOM_FLASH_ENABLE_MODULE_MASK,
> +				     QCOM_FLASH_DISABLE_ALL);
> +	if (rc)
> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> +
> +	rc = regulator_disable(leds_dev->torch_supply);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Regulator disable failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	leds_dev->torch_regulator_on = false;
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_fled_on(struct qcom_flash_led *led)
> +{
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	struct device *dev = leds_dev->dev;
> +	int rc, error;
> +
> +	rc = qcom_flash_fled_regulator_on(leds_dev);
> +	if (rc)
> +		goto error_flash_set;
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +				     led->flash_enable_cmd,
> +				     led->flash_enable_cmd);
> +	if (rc) {
> +		dev_err(dev, "Enable reg write failed(%d)\n", rc);
> +		goto error_flash_set;
> +	}
> +
> +	/*
> +	 * TODO The downstream driver also allowed HW strobe. Add support for it
> +	 * after v4l2 support is added and ISP can be used
> +	 */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> +				     led->flash_strobe_cmd,
> +				     led->flash_strobe_cmd);
> +	if (rc) {
> +		dev_err(dev, "LED %d strobe reg write failed(%d)\n", led->id,
> +			rc);
> +		goto error_flash_set;
> +	}
> +
> +	return 0;
> +
> +error_flash_set:
> +	error = qcom_flash_fled_regulator_off(leds_dev);
> +	if (error)
> +		return error;
> +	return rc;
> +}
> +
> +static int qcom_flash_fled_off(struct qcom_flash_led *led)
> +{
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	struct device *dev = leds_dev->dev;
> +	int rc, error;
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> +				     led->flash_strobe_cmd,
> +				     QCOM_FLASH_DISABLE_ALL);
> +	if (rc)
> +		dev_err(dev, "LED %d flash write failed(%d)\n", led->id, rc);
> +
> +	error = qcom_flash_fled_regulator_off(leds_dev);
> +	if (error)
> +		return error;
> +	return rc;
> +}
> +
> +static int qcom_flash_torch_on(struct qcom_flash_led *led)
> +{
> +	int rc, error;
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	struct device *dev = leds_dev->dev;
> +
> +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
> +		rc = qcom_flash_torch_regulator_on(leds_dev);
> +		if (rc)
> +			goto error_reg_write;
> +	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
> +		rc = qcom_flash_fled_regulator_on(leds_dev);

Why for torch mode you need to enable fled regulator?

> +		if (rc)
> +			goto error_flash_set;
> +
> +		/*
> +		 * Write 0x80 to MODULE_ENABLE before writing
> +		 * 0xE0 in order to avoid a hardware bug caused
> +		 * by register value going from 0x00 to 0xE0.
> +		 */
> +		rc = qcom_flash_masked_write(leds_dev,
> +					     QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +					     QCOM_FLASH_ENABLE_MODULE_MASK,
> +					     QCOM_FLASH_ENABLE_MODULE);
> +		if (rc) {
> +			dev_err(dev, "Enable reg write failed(%d)\n", rc);
> +			goto error_flash_set;
> +		}
> +	}
> +
> +	rc = qcom_flash_torch_reg_enable(leds_dev, true);
> +	if (rc)
> +		goto error_reg_write;
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +				     QCOM_FLASH_ENABLE_MASK,
> +				     leds_dev->torch_enable_cmd);
> +	if (rc) {
> +		dev_err(dev, "Enable reg write failed(%d)\n", rc);
> +		goto error_reg_write;
> +	}
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> +				     led->flash_strobe_cmd,
> +				     led->flash_strobe_cmd);

Just to make sure - the hardware requires strobe cmd to enable torch?

> +	if (rc) {
> +		dev_err(dev, "LED %d strobe reg write failed(%d)\n", led->id,
> +			rc);
> +		goto error_reg_write;
> +	}
> +
> +	leds_dev->torch_enabled = true;
> +
> +	return 0;
> +
> +error_reg_write:
> +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE)
> +		goto error_flash_set;
> +
> +	error = qcom_flash_torch_regulator_off(leds_dev);
> +	if (error)
> +		return error;
> +	return rc;
> +
> +error_flash_set:
> +	error = qcom_flash_fled_regulator_off(leds_dev);
> +	if (error)
> +		return error;
> +	return rc;
> +}
> +
> +static int qcom_flash_torch_off(struct qcom_flash_led *led)
> +{
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	struct device *dev = leds_dev->dev;
> +	int rc, error;
> +	unsigned int i;
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> +				     led->flash_strobe_cmd, QCOM_FLASH_DISABLE_ALL);
> +	if (rc) {
> +		dev_err(dev, "LED %d flash write failed(%d)\n", led->id, rc);
> +		goto error_torch_set;
> +	}
> +
> +	/* Keep torch on if the other LED is still on */
> +	for (i = 0; i < leds_dev->num_leds; i++)
> +		if (leds_dev->leds[i].fled_cdev.led_cdev.brightness)
> +			return 0;
> +
> +	rc = qcom_flash_torch_reg_enable(leds_dev, false);
> +	if (rc)
> +		goto error_torch_set;
> +
> +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
> +		rc = qcom_flash_torch_regulator_off(leds_dev);
> +		if (rc)
> +			return rc;
> +	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
> +		rc = qcom_flash_fled_regulator_off(leds_dev);
> +		if (rc)
> +			return rc;
> +	}
> +
> +	leds_dev->torch_enabled = false;
> +
> +	return 0;
> +
> +error_torch_set:
> +	error = qcom_flash_torch_regulator_off(leds_dev);
> +	if (error)
> +		return error;
> +	return rc;
> +}
> +
> +static int qcom_flash_ledcdev_brightness_set(struct led_classdev *led_cdev,
> +					     enum led_brightness value)
> +{
> +	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	unsigned int max_brightness;
> +	int rc;
> +
> +	if (value > led_cdev->max_brightness) {

LED framework takes care of it. You can skip this.

> +		dev_err(leds_dev->dev, "Invalid brightness value\n");
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&leds_dev->lock);
> +	if (!value) {
> +		rc = qcom_flash_torch_off(led);
> +	} else {
> +		/*
> +		 * The minimum on value for the brightness register is 0, but for
> +		 * led_classdev is 1, as 0 there means off.
> +		 */
> +		rc = qcom_flash_brightness_set(led, led_cdev->brightness - 1);
> +		if (rc)
> +			goto unlock;
> +
> +		led->flash_current_invalidated = true;
> +
> +		if (leds_dev->torch_enabled) {
> +			/* Clear status to update brightness */
> +			rc = qcom_flash_status_clear(leds_dev);
> +			if (rc)
> +				goto unlock;
> +		} else {
> +			/*
> +			 * Clear status from previous flash strobe so the LED
> +			 * can turn on
> +			 */
> +			rc = qcom_flash_check_timedout(leds_dev);
> +			if (rc > 0)
> +				rc = qcom_flash_status_clear(leds_dev);
> +			else if (rc < 0)
> +				goto unlock;
> +
> +			max_brightness = led_cdev->max_brightness - 1;
> +			rc = qcom_flash_max_brightness_set(led, max_brightness);
> +			if (rc)
> +				goto unlock;
> +		}
> +		rc = qcom_flash_torch_on(led);
> +	}
> +
> +unlock:
> +	mutex_unlock(&leds_dev->lock);
> +	return rc;
> +}
> +
> +static int qcom_flash_flcdev_brightness_set(struct led_classdev_flash *fled_cdev,
> +					    u32 brightness)
> +{
> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	unsigned int bright;
> +	int rc;
> +
> +	/* Can't operate on flash if torch is on */
> +	if (leds_dev->torch_enabled)
> +		return -EBUSY;
> +
> +	clamp_align(&brightness, QCOM_FLASH_CURRENT_MIN,
> +		    fled_cdev->brightness.max, QCOM_FLASH_CURRENT_STEP);
> +	fled_cdev->brightness.val = brightness;
> +
> +	bright = qcom_flash_current_to_reg(brightness);
> +
> +	mutex_lock(&leds_dev->lock);
> +	rc = qcom_flash_brightness_set(led, bright);
> +	if (rc)
> +		goto unlock;
> +
> +	if (led->flash_current_invalidated) {
> +		bright = qcom_flash_current_to_reg(fled_cdev->brightness.max);
> +		rc = qcom_flash_max_brightness_set(led, bright);
> +		if (rc)
> +			goto unlock;
> +	}
> +
> +	led->flash_current_invalidated = false;
> +
> +unlock:
> +	mutex_unlock(&leds_dev->lock);
> +	return rc;
> +}
> +
> +static int qcom_flash_flcdev_strobe_set(struct led_classdev_flash *fled_cdev,
> +					bool state)
> +{
> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	unsigned int bright;
> +	unsigned int i;
> +	int rc;
> +
> +	/* Can't operate on flash if torch is on */
> +	if (leds_dev->torch_enabled)
> +		return -EBUSY;
> +
> +	mutex_lock(&leds_dev->lock);
> +	if (!state) {
> +		rc = qcom_flash_fled_off(led);
> +	} else {
> +		/*
> +		 * Turn off flash LEDs from previous strobe
> +		 */
> +		rc = qcom_flash_check_timedout(leds_dev);
> +		if (rc > 0) {
> +			for (i = 0; i < leds_dev->num_leds; i++) {
> +				rc = qcom_flash_fled_off(&leds_dev->leds[i]);
> +				if (rc)
> +					goto unlock;
> +			}
> +		} else if (rc < 0) {
> +			goto unlock;
> +		}

What if flash gets timed out after this check here? Why do you need to
call qcom_flash_fled_off() if it has already timed out?

> +		if (led->flash_current_invalidated) {
> +			bright = qcom_flash_current_to_reg(fled_cdev->brightness.val);
> +			rc = qcom_flash_brightness_set(led, bright);
> +			if (rc)
> +				goto unlock;
> +
> +			bright = qcom_flash_current_to_reg(fled_cdev->brightness.max);
> +			rc = qcom_flash_max_brightness_set(led, bright);
> +			if (rc)
> +				goto unlock;
> +
> +			led->flash_current_invalidated = false;
> +		}
> +
> +		rc = qcom_flash_fled_on(led);
> +	}
> +
> +unlock:
> +	mutex_unlock(&leds_dev->lock);
> +	return rc;
> +}
> +
> +static int qcom_flash_flcdev_strobe_get(struct led_classdev_flash *fled_cdev,
> +					bool *state)
> +{
> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	int status;
> +
> +	mutex_lock(&leds_dev->lock);
> +	status = qcom_flash_status_get(led);
> +	mutex_unlock(&leds_dev->lock);
> +	if (status < 0)
> +		return status;
> +
> +	*state = status && !leds_dev->torch_enabled;
> +	return 0;
> +}
> +
> +static int qcom_flash_flcdev_timeout_set(struct led_classdev_flash *fled_cdev,
> +					 u32 timeout)
> +{
> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	unsigned int time, i;
> +	int rc;
> +
> +	clamp_align(&timeout, QCOM_FLASH_DURATION_MIN, fled_cdev->timeout.max,
> +		    QCOM_FLASH_DURATION_STEP);
> +
> +	/* Since the timeout register is shared between LEDs, update for all */
> +	for (i = 0; i < leds_dev->num_leds; i++)
> +		leds_dev->leds[i].fled_cdev.timeout.val = timeout;
> +
> +	time = qcom_flash_duration_to_reg(fled_cdev->timeout.val);
> +
> +	mutex_lock(&leds_dev->lock);
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_SAFETY_TIMER,
> +				     QCOM_FLASH_SAFETY_TIMER_MASK, time);
> +	if (rc)
> +		dev_err(leds_dev->dev, "Safety timer reg write failed(%d)\n",
> +			rc);
> +	mutex_unlock(&leds_dev->lock);
> +
> +	return rc;
> +}
> +
> +static int qcom_flash_flcdev_fault_get(struct led_classdev_flash *fled_cdev,
> +				       u32 *fault)
> +{
> +	/*
> +	 * TODO Add fault detection when we find out how to. No clue from
> +	 * inspecting the SPMI registers
> +	 */
> +	*fault = 0;
> +	return 0;
> +}
> +
> +static const struct led_flash_ops flash_ops = {
> +	.flash_brightness_set	= qcom_flash_flcdev_brightness_set,
> +	.strobe_set		= qcom_flash_flcdev_strobe_set,
> +	.strobe_get		= qcom_flash_flcdev_strobe_get,
> +	.timeout_set		= qcom_flash_flcdev_timeout_set,
> +	.fault_get		= qcom_flash_flcdev_fault_get,
> +};
> +
> +static int qcom_flash_setup_flcdev(struct qcom_flash_config *cfg,
> +				   struct qcom_flash_led *led,
> +				   struct device_node *node)
> +{
> +	int rc;
> +	struct device *dev = led_to_leds_dev(led)->dev;
> +	struct led_classdev_flash *fled_cdev = &led->fled_cdev;
> +	struct led_classdev *led_cdev = &fled_cdev->led_cdev;
> +	struct led_init_data init_data = {};
> +	struct led_flash_setting *setting;
> +
> +	init_data.fwnode = of_fwnode_handle(node);
> +
> +	led_cdev->brightness_set_blocking = qcom_flash_ledcdev_brightness_set;
> +
> +	led_cdev->max_brightness = cfg->led_max_brightness[led->id];
> +	led_cdev->max_brightness /= QCOM_FLASH_CURRENT_STEP;

Just assign the result of division:

led_cdev->max_brightness = cfg->led_max_brightness[led->id] /
                            QCOM_FLASH_CURRENT_STEP;

Two consecutive assignments look a bit convoluted.

> +
> +	setting = &fled_cdev->brightness;
> +	setting->max = cfg->flash_max_brightness[led->id];
> +	setting->min = QCOM_FLASH_CURRENT_MIN;
> +	setting->step = QCOM_FLASH_CURRENT_STEP;
> +	setting->val = setting->min;
> +
> +	setting = &fled_cdev->timeout;
> +	setting->max = cfg->flash_max_timeout[led->id];
> +	setting->min = QCOM_FLASH_DURATION_MIN;
> +	setting->step = QCOM_FLASH_DURATION_STEP;
> +	setting->val = QCOM_FLASH_DURATION_DEFAULT;
> +
> +	fled_cdev->ops = &flash_ops;
> +	led_cdev->flags |= LED_DEV_CAP_FLASH;
> +
> +	rc = devm_led_classdev_flash_register_ext(dev, fled_cdev, &init_data);
> +	if (rc)
> +		dev_err(dev, "unable to register led %d,rc=%d\n", led->id, rc);
> +
> +	return rc;
> +}
> +
> +static int qcom_flash_setup_fled(struct qcom_flash_config *cfg,
> +				 struct qcom_flash_led *led,
> +				 enum qcom_flash_ids id)
> +{
> +	led->id = cfg->id[id];
> +	led->default_on = cfg->default_on[id];
> +	led->flash_current_invalidated = true;
> +
> +	if (led->id == QCOM_FLASH_ID_LED0) {
> +		led->flash_enable_cmd = QCOM_FLASH_ENABLE_LED0;
> +		led->flash_strobe_cmd = QCOM_FLASH_STROBE_LED0;
> +		led->current_addr = QCOM_FLASH_ADDR_CURR_LED0;
> +		led->mask_led_on = QCOM_FLASH_MASK_ON_LED0;
> +	} else {
> +		led->flash_enable_cmd = QCOM_FLASH_ENABLE_LED1;
> +		led->flash_strobe_cmd = QCOM_FLASH_STROBE_LED1;
> +		led->current_addr = QCOM_FLASH_ADDR_CURR_LED1;
> +		led->mask_led_on = QCOM_FLASH_MASK_ON_LED1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_setup_regs(struct qcom_flash_device *leds_dev)
> +{
> +	int rc;
> +
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> +				     QCOM_FLASH_STROBE_MASK,
> +				     QCOM_FLASH_DISABLE_ALL);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "LED flash write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	/* Disable flash LED module */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> +				     QCOM_FLASH_ENABLE_MASK,
> +				     QCOM_FLASH_DISABLE_ALL);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	/* Set Vreg force */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_VREG_OK_FORCE,
> +				     QCOM_FLASH_VREG_MASK,
> +				     QCOM_FLASH_HW_VREG_OK);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Vreg OK reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	/* Set self fault check */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_FAULT_DETECT,
> +				     QCOM_FLASH_FAULT_DETECT_MASK,
> +				     QCOM_FLASH_SELFCHECK_DISABLE);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Fault detect reg write failed(%d)\n",
> +			rc);
> +		return rc;
> +	}
> +
> +	/* Set mask enable */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_MASK_ENABLE,
> +				     QCOM_FLASH_MASK_REG_MASK,
> +				     QCOM_FLASH_MASK_1);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Mask enable reg write failed(%d)\n",
> +			rc);
> +		return rc;
> +	}
> +
> +	/* Set ramp rate */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_RAMP_RATE,
> +				     QCOM_FLASH_RAMP_RATE_MASK, 0xBF);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Ramp rate reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	/* Enable VPH_PWR_DROOP and set threshold to 2.9V */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_VPH_PWR_DROOP,
> +				     QCOM_FLASH_VPH_PWR_DROOP_MASK, 0xC2);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "VPH_PWR_DROOP reg write failed(%d)\n",
> +			rc);
> +		return rc;
> +	}
> +
> +	/* Set headroom */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_HEADROOM,
> +				     QCOM_FLASH_HEADROOM_MASK,
> +				     QCOM_FLASH_HEADROOM_500MV);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Headroom reg write failed(%d)\n", rc);
> +		return rc;
> +	}
> +
> +	/* Set startup delay */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_STARTUP_DELAY,
> +				     QCOM_FLASH_STARTUP_DLY_MASK,
> +				     QCOM_FLASH_STARTUP_DLY_10US);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "Startup delay reg write failed(%d)\n",
> +			rc);
> +		return rc;
> +	}
> +
> +	/*
> +	 * TODO The downstream driver also supported watchdog mode. Not sure
> +	 * about the difference, so only support safety timer for now
> +	 */
> +	/* Set timer control */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_TMR_CTRL,
> +				     QCOM_FLASH_TMR_MASK,
> +				     QCOM_FLASH_TMR_SAFETY);
> +	if (rc) {
> +		dev_err(leds_dev->dev, "LED timer ctrl reg write failed(%d)\n",
> +			rc);
> +		return rc;
> +	}
> +
> +	/* Set clamp current */
> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_CLAMP_CURR,
> +				     QCOM_FLASH_CURRENT_MASK,
> +				     qcom_flash_current_to_reg(QCOM_FLASH_DEFAULT_CLAMP));
> +	if (rc)
> +		dev_err(leds_dev->dev, "Clamp current reg write failed(%d)\n",
> +			rc);
> +
> +	return rc;
> +}
> +
> +static int qcom_flash_setup_led(struct qcom_flash_config *cfg,
> +				struct qcom_flash_led *led,
> +				enum qcom_flash_ids id,
> +				struct device_node *node)
> +{
> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> +	struct led_classdev *led_cdev = &led->fled_cdev.led_cdev;
> +	int rc;
> +
> +	rc = qcom_flash_setup_fled(cfg, led, id);
> +	if (rc)
> +		return rc;
> +
> +	rc = qcom_flash_setup_flcdev(cfg, led, node);
> +	if (rc)
> +		return rc;
> +
> +	/* configure default state */
> +	if (!led->default_on) {
> +		led_cdev->brightness = LED_OFF;
> +	} else {
> +		led_cdev->brightness = led_cdev->max_brightness;
> +		mutex_lock(&leds_dev->lock);
> +		rc = qcom_flash_torch_on(led);
> +		mutex_unlock(&leds_dev->lock);
> +		if (rc)
> +			return rc;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_setup_leds_device(struct qcom_flash_device *leds_dev,
> +					struct qcom_flash_config *cfg,
> +					struct device *dev)
> +{
> +	int rc;
> +
> +	leds_dev->dev = dev;
> +
> +	leds_dev->base = cfg->base;
> +	leds_dev->num_leds = cfg->num_leds;
> +
> +	leds_dev->regmap = dev_get_regmap(dev->parent, NULL);
> +	if (!leds_dev->regmap) {
> +		dev_err(dev, "Failure getting regmap\n");
> +		return -ENODEV;
> +	}
> +
> +	rc = qcom_flash_setup_regs(leds_dev);
> +	if (rc)
> +		return rc;
> +
> +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE,
> +				 &leds_dev->peripheral_subtype);
> +	if (rc) {
> +		dev_err(dev, "Unable to read from addr=%x, rc(%d)\n",
> +			QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE, rc);
> +		return rc;
> +	}
> +
> +	leds_dev->flash_supply = cfg->flash_supply;
> +
> +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
> +		leds_dev->torch_supply = cfg->torch_supply;
> +		leds_dev->torch_enable_cmd = QCOM_FLASH_ENABLE_MODULE;
> +	} else {
> +		leds_dev->torch_enable_cmd = QCOM_FLASH_ENABLE_ALL;
> +	}
> +
> +	mutex_init(&leds_dev->lock);
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_parse_dt(struct device *dev,
> +			       struct qcom_flash_config *cfg,
> +			       struct device_node *sub_nodes[])
> +{
> +	struct device_node *node = dev->of_node;
> +	struct device_node *child_node;
> +	const char *temp_string;
> +	int rc, parsed_leds = 0;
> +	u32 val;
> +
> +	rc = of_property_read_u32(node, "reg", &val);
> +	if (rc < 0) {
> +		dev_err(dev, "Failure reading reg, rc = %d\n", rc);
> +		return rc;
> +	}
> +	cfg->base = val;
> +
> +	cfg->flash_supply = devm_regulator_get(dev, "flash-boost");
> +	cfg->torch_supply = devm_regulator_get(dev, "torch-boost");
> +
> +	for_each_available_child_of_node(node, child_node) {
> +		/* LED properties */
> +
> +		rc = of_property_read_u32(child_node, "reg",
> +					  &cfg->id[parsed_leds]);
> +		if (rc) {
> +			dev_err(dev, "Failure reading led id, rc =  %d\n", rc);
> +			of_node_put(child_node);
> +			return rc;
> +		}
> +
> +		/* Assume LED IDs are ordered in DT for simplicity */

You need to mention this requirement in DT bindings, but I am not sure
if DT child nodes parsing order is guaranteed to be top-down.

> +		if (cfg->id[parsed_leds] != parsed_leds) {
> +			dev_err(dev, "Unordered LED nodes in DT\n");
> +			of_node_put(child_node);
> +			return -EINVAL;
> +		}
> +
> +		sub_nodes[parsed_leds] = child_node;
> +
> +		rc = of_property_read_string(child_node, "default-state",
> +					     &temp_string);
> +		if (!rc) {
> +			if (strncmp(temp_string, "on", sizeof("on")) == 0)
> +				cfg->default_on[parsed_leds] = true;
> +		} else if (rc != -EINVAL) {
> +			dev_err(dev,
> +				"Failure reading default-state, rc =  %d\n",
> +				rc);
> +			of_node_put(child_node);
> +			return rc;
> +		}
> +
> +		/* FLED properties */
> +
> +		rc = of_property_read_u32(child_node, "led-max-microamp",
> +					  &cfg->led_max_brightness[parsed_leds]);
> +		if (rc < 0) {
> +			dev_err(dev, "Failure reading max_current, rc =  %d\n",
> +				rc);
> +			of_node_put(child_node);
> +			return rc;
> +		}
> +
> +		rc = of_property_read_u32(child_node, "flash-max-microamp",
> +					  &cfg->flash_max_brightness[parsed_leds]);
> +		if (rc < 0) {
> +			dev_err(dev, "Failure reading max_current, rc =  %d\n",
> +				rc);
> +			of_node_put(child_node);
> +			return rc;
> +		}
> +
> +		rc = of_property_read_u32(child_node, "flash-max-timeout-us",
> +					  &cfg->flash_max_timeout[parsed_leds]);
> +		if (rc < 0) {
> +			dev_err(dev, "Failure reading max_timeout, rc =  %d\n",
> +				rc);
> +			of_node_put(child_node);
> +			return rc;
> +		}
> +
> +		parsed_leds++;
> +		if (parsed_leds >= 2) {
> +			of_node_put(child_node);
> +			break;
> +		}
> +	}
> +	cfg->num_leds = parsed_leds;
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct qcom_flash_device *leds_dev;
> +	struct qcom_flash_config cfg = { 0 };
> +	struct device_node *sub_nodes[2];
> +	unsigned int i;
> +	int rc;
> +
> +	leds_dev = devm_kzalloc(dev, sizeof(*leds_dev), GFP_KERNEL);
> +	if (!leds_dev)
> +		return -ENOMEM;
> +
> +	rc = qcom_flash_parse_dt(dev, &cfg, sub_nodes);
> +	if (rc)
> +		return rc;
> +
> +	rc = qcom_flash_setup_leds_device(leds_dev, &cfg, dev);
> +	if (rc)
> +		return rc;
> +
> +	for (i = 0; i < leds_dev->num_leds; i++) {
> +		rc = qcom_flash_setup_led(&cfg, &leds_dev->leds[i], i,
> +					  sub_nodes[i]);
> +		if (rc)
> +			return rc;
> +	}
> +
> +	platform_set_drvdata(pdev, leds_dev);
> +
> +	return 0;
> +}
> +
> +static int qcom_flash_remove(struct platform_device *pdev)
> +{
> +	struct qcom_flash_device *leds_dev = platform_get_drvdata(pdev);
> +
> +	mutex_destroy(&leds_dev->lock);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id qcom_flash_spmi_of_match[] = {
> +	{ .compatible = "qcom,spmi-flash-leds" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, qcom_flash_spmi_of_match);
> +
> +static struct platform_driver qcom_flash_driver = {
> +	.driver		= {
> +		.name	= "qcom,spmi-flash-leds",
> +		.of_match_table = qcom_flash_spmi_of_match,
> +	},
> +	.probe		= qcom_flash_probe,
> +	.remove		= qcom_flash_remove,
> +};
> +module_platform_driver(qcom_flash_driver);
> +
> +MODULE_DESCRIPTION("Qualcomm SPMI Flash LED driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("N?colas F. R. A. Prado <n at nfraprado.net>");
> 

-- 
Best regards,
Jacek Anaszewski


From linus.walleij at linaro.org  Mon Aug 16 16:00:25 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Aug 2021 01:00:25 +0200
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
 <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
 <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>
Message-ID: <CACRpkdbZKh8cqqiDRUik6Ooo33e+feGwYsLjcLRvBQnT3x5M3A@mail.gmail.com>

On Mon, Aug 16, 2021 at 5:38 PM Chen-Yu Tsai <wenst at chromium.org> wrote:
> On Mon, Aug 16, 2021 at 6:48 PM zhiyong.tao <zhiyong.tao at mediatek.com> wrote:

> > > I'll take that as "use SI units whenever possible and reasonable".
> >
> > ==> so It doesn't need to change the define, is it right?
> > we will keep the common define.
>
> Actually I think it would be possible and reasonable to use SI units
> in this case, since you are the vendor and have the resistor values
> to implement the support. Having different sets of values for different
> chips is nothing out of the ordinary. We already have to account for
> different number of pins and different pin functions. That is what
> compatible strings are for.

I fully agree with Chen-Yu's analysis here.

Zhiyong can you make an attempt to use SI units (Ohms) and see
what it will look like? I think it will look better for users and it will
be less risk to make mistakes.

Yours,
Linus Walleij


From bjorn.andersson at linaro.org  Mon Aug 16 16:12:23 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Mon, 16 Aug 2021 18:12:23 -0500
Subject: [GIT PULL] Qualcomm ARM64 updates for v5.15
Message-ID: <20210816231223.586597-1-bjorn.andersson@linaro.org>

The following changes since commit ff1176468d368232b684f75e82563369208bc371:

  Linux 5.14-rc3 (2021-07-25 15:35:14 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-for-5.15

for you to fetch changes up to 198b8c8ede36d2135df73fee19506276059a0f8e:

  Merge tag 'v5.14-rc3' into arm64-for-5.15 (2021-08-16 18:02:26 -0500)

----------------------------------------------------------------
Qualcomm ARM64 updates for v5.15

SDM660 and SDM630 was concluded to be similar enough that they should be
merged, and the derivative SDM636 was added to the bunch. The combined
platform gained support for GPU, DMA, I2C, IMEM, display, power-domains,
SDHCI, thermal, USB, interconnects, VADC, WLED and audio remoteproc. The
Sony Xperia "Ganges" platform was similarly merged with "Nile", got
cleaned up and gained touchscreen, USB, volume keys and uSD support.

IPQ6018 gains USB2 and PCIe support and a few minor fixes. IPQ8074
gains SCM, PRNG and Crypto support and a DT style update of the PCIe
nodes.

MSM8916 gains Coresight STM support. The Xiaomi Redmi 2 is introduced,
with touchscreen, notification LED and IMU support. MSM8996 gains
support for GPU cooling and v3.0 of the SoC, which is used to introduce
support for the Sony Xperia X Performance, XZ and XZs phones.

SC7180 finally gains DisplayPort support and LPASS is updated
accordingly. A number of fixes are introduced and with the newly
introduced DRM aux bus in place Trogdor's panel is moved under the eDP
bridge. SC7280 gained USB, eMMC, SD-card, QFPROM and IPA support, the
new IDP2 board was added.

SM6126 (aka Snapdragon 665) was introduced, together with the Sony
Xperia 10II phone with support for framebuffer, USB, eMMC and volume
keys.

SM8150 gained inline crypto support for UFS enabled, CPU opp-tables was
introduced to scale DDR and L3 frequencies and SPI nodes where added, in
addition to a number of smaller fixes.

SM8250 gained a number of minor fixes and had its serial engines wired
up to use the GENI wrappers' DMA engines.

SM8350 had wakeup-parent defined for the TLMM gpio node and I2C13 was
introduced.

SDM845 display clocks was corrected and Lenovo Yoga C630 got IPA enabled
and now has working LTE connectivity.

Additionally a number of minor fixes throughout to correct DT validation
warnings.

Lastly v5.14-rc3 is merge in to resolve the merge conflicts caused by
the USB maintainer deciding to fix a regression in his tree.

----------------------------------------------------------------
Alex Elder (4):
      arm64: dts: qcom: sc7280: add IPA information
      arm64: dts: qcom: sc7280: enable IPA for sc7280-idp
      arm64: dts: qcom: sc7180: define ipa_fw_mem node
      arm64: dts: qcom: sm8350: fix IPA interconnects

AngeloGioacchino Del Regno (14):
      arm64: dts: qcom: Add support for SONY Xperia X Performance / XZ / XZs (msm8996, Tone platform)
      arm64: dts: qcom: sdm630: Rewrite memory map
      arm64: dts: qcom: sdm630: Add qfprom subnodes
      arm64: dts: qcom: sdm630: Fix TLMM node and pinctrl configuration
      arm64: dts: qcom: sdm630: Add SDHCI2 node
      arm64: dts: qcom: sdm630: Add interconnect and opp table to sdhc_1
      arm64: dts: qcom: sdm630: Add GPU Clock Controller node
      arm64: dts: qcom: sdm630: Add clocks and power domains to SMMU nodes
      arm64: dts: qcom: sdm630: Add qcom,adreno-smmu compatible
      arm64: dts: qcom: sdm630: Add Adreno 508 GPU configuration
      arm64: dts: qcom: pm660: Support SPMI regulators on PMIC sid 1
      arm64: dts: qcom: pm660l: Support SPMI regulators on PMIC sid 3
      arm64: dts: qcom: sdm630: Configure the camera subsystem
      arm64: dts: qcom: sdm630-xperia-nile: Add all RPM and fixed regulators

Baruch Siach (1):
      arm64: dts: qcom: ipq6018: correct TCSR block area

Bhupesh Sharma (4):
      arm64: dts: qcom: sm8150: Add UFS ICE capability
      arm64: dts: qcom: Use correct naming for dwc3 usb nodes in dts files
      arm64: dts: qcom: sm8150: Sort dc_noc and gem_noc nodes
      arm64: dts: qcom: Fix usb entries for SA8155p adp board

Bjorn Andersson (3):
      arm64: dts: qcom: sdm850-yoga: Enable IPA
      arm64: dts: qcom: sm8350: Add wakeup-parent to tlmm
      Merge tag 'v5.14-rc3' into arm64-for-5.15

Caleb Connolly (2):
      arm64: dts: qcom: sdm845-oneplus-common: enable debug UART
      arm64: dts: qcom: sdm845-oneplus: add ipa firmware names

Dmitry Baryshkov (7):
      arm64: dts: qcom: sm8250: fix usb2 qmp phy node
      arm64: dts: qcom: sdm845: move bus clock to mdp node for sdm845 target
      arm64: dts: qcom: sm8250: remove bus clock from the mdss node for sm8250 target
      arm64: dts: qcom: sc7180: assign DSI clock source parents
      arm64: dts: qcom: sdm845: assign DSI clock source parents
      arm64: dts: qcom: sdm845-mtp: assign DSI clock source parents
      arm64: dts: qcom: sm8250: assign DSI clock source parents

Douglas Anderson (1):
      arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip

Felipe Balbi (1):
      arm64: dts: qcom: sm8150: add SPI nodes

Georgi Djakov (2):
      arm64: dts: qcom: sm8250: Fix epss_l3 unit address
      arm64: dts: qcom: msm8916: Enable CoreSight STM component

Gokul Sriram Palanisamy (2):
      arm64: dts: qcom: ipq6018: Update WCSS PIL driver compatible
      arm64: dts: qcom: ipq8074: Add scm on IPQ8074 SoCs

Jonathan Marek (1):
      arm64: dts: qcom: sm8350: add qupv3_id_1/i2c13 nodes

Judy Hsiao (2):
      arm64: dts: qcom: sc7180: Set adau wakeup delay to 80 ms
      arm64: dts: qcom: sc7180: trogdor: Update audio codec to Max98360A

Kathiravan T (1):
      arm64: dts: qcom: ipq6018: enable USB2 support

Konrad Dybcio (31):
      arm64: dts: qcom: Add PMI8996 DTSI file
      arm64: dts: qcom: Add MSM8996v3.0 DTSI file
      arm64: dts: qcom: msm8996-*: Disable HDMI by default
      arm64: dts: qcom: sdm630: Add RPMPD nodes
      arm64: dts: qcom: sdm630: Add MMCC node
      arm64: dts: qcom: sdm630: Add interconnect provider nodes
      arm64: dts: qcom: sdm630: Add MDSS nodes
      arm64: dts: qcom: sdm630: Add USB configuration
      arm64: dts: qcom: sdm630: Add TSENS node
      arm64: dts: qcom: sdm630: Add modem/ADSP SMP2P nodes
      arm64: dts: qcom: sdm630: Add thermal-zones configuration
      arm64: dts: qcom: sdm630: Add ADSP remoteproc configuration
      arm64: dts: qcom: sdm630: Raise tcsr_mutex_regs size
      arm64: dts: qcom: pm660l: Add WLED support
      arm64: dts: qcom: pm660(l): Add VADC and temp alarm nodes
      arm64: dts: qcom: sdm660: Make the DTS an overlay on top of 630
      arm64: dts: qcom: Add device tree for SDM636
      arm64: dts: qcom: sdm630: Add IMEM node
      arm64: dts: qcom: sdm660: Add required nodes for DSI1
      arm64: dts: qcom: sdm630-nile: Use &labels
      arm64: dts: qcom: sdm630-nile: Add USB
      arm64: dts: qcom: sdm630-nile: Add Volume up key
      arm64: dts: qcom: sdm630-xperia: Retire sdm630-sony-xperia-ganges.dtsi
      arm64: dts: qcom: sdm630-nile: Add Synaptics touchscreen.
      arm64: dts: qcom: sdm630-nile: Specify ADSP firmware name
      arm64: dts: qcom: sdm630-nile: Enable uSD card slot
      arm64: dts: qcom: sdm630-nile: Remove gpio-keys autorepeat
      arm64: dts: qcom: sdm630: Add I2C functions to I2C pins
      arm64: dts: qcom: sdm630: Add DMA to I2C hosts
      arm64: dts: qcom: sm8250: Add DMA to I2C/SPI
      arm64: dts: qcom: pm8004: Enable the PMIC peripherals by default

Kuogee Hsieh (1):
      arm64: dts: qcom: sc7180: Add DisplayPort node

Martin Botka (2):
      arm64: dts: qcom: Add support for SM6125
      arm64: dts: qcom: sm6125: Add support for Sony Xperia 10II

Rajendra Nayak (3):
      arm64: dts: qcom: sc7280: Add qfprom node
      dt-bindings: arm: qcom: Document qcom,sc7280-idp2 board
      arm64: dts: qcom: sc7280-idp: Add device tree files for IDP2

Ravi Kumar Bokka (1):
      arm64: dts: qcom: sc7180:: modified qfprom CORR size as per RAW size

Robert Foss (1):
      arm64: dts: qcom: sm8350: Rename GENI serial engine DT node

Robert Marko (2):
      arm64: dts: qcom: ipq8074: add crypto nodes
      arm64: dts: qcom: ipq8074: add PRNG node

Sandeep Maheswaram (3):
      arm64: dts: qcom: sc7280: Add USB related nodes
      arm64: dts: qcom: sc7280: Add USB nodes for IDP board
      arm64: dts: qcom: sc7280: Add interconnect properties for USB

Selvam Sathappan Periakaruppan (1):
      arm64: dts: qcom: ipq6018: Add pcie support

Shaik Sajida Bhanu (1):
      arm64: dts: qcom: sc7280: Add nodes for eMMC and SD card

Sibi Sankar (1):
      arm64: dts: qcom: sc7280: Fixup the cpufreq node

Stephan Gerhold (4):
      arm64: dts: qcom: Add device tree for Xiaomi Redmi 2 (wingtech-wt88047)
      arm64: dts: qcom: msm8916-wingtech-wt88047: Add touchscreen
      arm64: dts: qcom: msm8916-wingtech-wt88047: Add notification LED
      arm64: dts: qcom: msm8916-wingtech-wt88047: Add IMU

Thara Gopinath (3):
      arm64: dts: qcom: sm8150: Add CPU opp tables
      arm64: dts: qcom: sm8150-mtp: Add 8150 compatible string
      arm64: dts: qcom: sm8150: Fix incorrect cpu opp table entry

V Sujith Kumar Reddy (2):
      arm64: dts: qcom: sc7180: Update lpass cpu node for audio over dp
      arm64: dts: qcom: sc7180-trogdor: Add lpass dai link for HDMI

Vinod Koul (11):
      arm64: dts: qcom: msm8996: don't use empty memory node
      arm64: dts: qcom: msm8998: don't use empty memory node
      arm64: dts: qcom: sdm630: don't use empty memory node
      arm64: dts: qcom: ipq8074: fix pci node reg property
      arm64: dts: qcom: sdm660: use reg value for memory node
      arm64: dts: qcom: ipq6018: drop '0x' from unit address
      arm64: dts: qcom: sdm630: don't use underscore in node name
      arm64: dts: qcom: msm8994: don't use underscore in node name
      arm64: dts: qcom: msm8996: don't use underscore in node name
      dt-bindings: arm: qcom: Document alcatel,idol347 board
      dt-bindings: arm: qcom: Drop qcom,mtp

Wesley Cheng (1):
      arm64: dts: qcom: pm8150b: Add DTS node for PMIC VBUS booster

Yassine Oudjana (1):
      arm64: dts: qcom: msm8996: Add gpu cooling support

satya priya (1):
      arm64: dts: qcom: sc7280: Remove pm8350 and pmr735b for sc7280-idp

 Documentation/devicetree/bindings/arm/qcom.yaml    |    4 +
 .../devicetree/bindings/thermal/qcom-tsens.yaml    |    1 +
 arch/arm64/boot/dts/qcom/Makefile                  |    9 +
 arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi          |    1 +
 arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts       |    8 +
 arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts       |    8 +
 arch/arm64/boot/dts/qcom/ipq6018.dtsi              |  157 ++-
 arch/arm64/boot/dts/qcom/ipq8074-hk01.dts          |    2 +-
 arch/arm64/boot/dts/qcom/ipq8074.dtsi              |   54 +-
 arch/arm64/boot/dts/qcom/msm8916-mtp.dts           |    3 +-
 .../boot/dts/qcom/msm8916-wingtech-wt88047.dts     |  313 +++++
 arch/arm64/boot/dts/qcom/msm8916.dtsi              |   27 +
 arch/arm64/boot/dts/qcom/msm8994.dtsi              |    8 +-
 arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi          |    8 +
 .../qcom/msm8996-pmi8996-sony-xperia-tone-dora.dts |   11 +
 .../msm8996-pmi8996-sony-xperia-tone-kagura.dts    |   11 +
 .../msm8996-pmi8996-sony-xperia-tone-keyaki.dts    |   11 +
 .../dts/qcom/msm8996-sony-xperia-tone-dora.dts     |   27 +
 .../dts/qcom/msm8996-sony-xperia-tone-kagura.dts   |   15 +
 .../dts/qcom/msm8996-sony-xperia-tone-keyaki.dts   |   26 +
 .../boot/dts/qcom/msm8996-sony-xperia-tone.dtsi    |  956 +++++++++++++
 arch/arm64/boot/dts/qcom/msm8996-v3.0.dtsi         |   63 +
 arch/arm64/boot/dts/qcom/msm8996.dtsi              |   44 +-
 arch/arm64/boot/dts/qcom/msm8998.dtsi              |    4 +-
 arch/arm64/boot/dts/qcom/pm660.dtsi                |  133 ++
 arch/arm64/boot/dts/qcom/pm660l.dtsi               |   54 +
 arch/arm64/boot/dts/qcom/pm8004.dtsi               |    2 -
 arch/arm64/boot/dts/qcom/pm8150b.dtsi              |    6 +
 arch/arm64/boot/dts/qcom/pmi8996.dtsi              |   15 +
 arch/arm64/boot/dts/qcom/sa8155p-adp.dts           |   60 +-
 .../arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi |    2 +-
 arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi       |   62 +-
 arch/arm64/boot/dts/qcom/sc7180.dtsi               |  102 +-
 arch/arm64/boot/dts/qcom/sc7280-idp.dts            |  241 +---
 arch/arm64/boot/dts/qcom/sc7280-idp.dtsi           |  341 +++++
 arch/arm64/boot/dts/qcom/sc7280-idp2.dts           |   23 +
 arch/arm64/boot/dts/qcom/sc7280.dtsi               |  419 +++++-
 .../dts/qcom/sdm630-sony-xperia-ganges-kirin.dts   |   14 +-
 .../boot/dts/qcom/sdm630-sony-xperia-ganges.dtsi   |   40 -
 .../dts/qcom/sdm630-sony-xperia-nile-discovery.dts |    1 +
 .../dts/qcom/sdm630-sony-xperia-nile-pioneer.dts   |    1 +
 .../dts/qcom/sdm630-sony-xperia-nile-voyager.dts   |    1 +
 .../boot/dts/qcom/sdm630-sony-xperia-nile.dtsi     |  527 ++++++-
 arch/arm64/boot/dts/qcom/sdm630.dtsi               | 1441 ++++++++++++++++++--
 .../dts/qcom/sdm636-sony-xperia-ganges-mermaid.dts |   14 +-
 arch/arm64/boot/dts/qcom/sdm636.dtsi               |   23 +
 .../arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts |    2 -
 arch/arm64/boot/dts/qcom/sdm660.dtsi               |  519 +++----
 arch/arm64/boot/dts/qcom/sdm845-mtp.dts            |    3 +
 .../arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi |   11 +
 arch/arm64/boot/dts/qcom/sdm845.dtsi               |   35 +-
 .../boot/dts/qcom/sdm850-lenovo-yoga-c630.dts      |    5 +
 .../dts/qcom/sm6125-sony-xperia-seine-pdx201.dts   |  139 ++
 arch/arm64/boot/dts/qcom/sm6125.dtsi               |  566 ++++++++
 arch/arm64/boot/dts/qcom/sm8150-mtp.dts            |    2 +-
 arch/arm64/boot/dts/qcom/sm8150.dtsi               |  797 ++++++++++-
 arch/arm64/boot/dts/qcom/sm8250.dtsi               |  217 ++-
 arch/arm64/boot/dts/qcom/sm8350-hdk.dts            |    2 +-
 arch/arm64/boot/dts/qcom/sm8350-mtp.dts            |    2 +-
 arch/arm64/boot/dts/qcom/sm8350.dtsi               |   53 +-
 60 files changed, 6754 insertions(+), 892 deletions(-)
 create mode 100644 arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-pmi8996-sony-xperia-tone-dora.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-pmi8996-sony-xperia-tone-kagura.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-pmi8996-sony-xperia-tone-keyaki.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-sony-xperia-tone-dora.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-sony-xperia-tone-kagura.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-sony-xperia-tone-keyaki.dts
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-sony-xperia-tone.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/msm8996-v3.0.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/pmi8996.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sc7280-idp2.dts
 delete mode 100644 arch/arm64/boot/dts/qcom/sdm630-sony-xperia-ganges.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sdm636.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts
 create mode 100644 arch/arm64/boot/dts/qcom/sm6125.dtsi


From dianders at chromium.org  Mon Aug 16 16:41:46 2021
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 16 Aug 2021 16:41:46 -0700
Subject: [GIT PULL] Qualcomm ARM64 updates for v5.15
In-Reply-To: <20210816231223.586597-1-bjorn.andersson@linaro.org>
References: <20210816231223.586597-1-bjorn.andersson@linaro.org>
Message-ID: <CAD=FV=XHOOjVgoQsS7vMDzeov0p6groC6Qnxz_TWpFj7dh7XLQ@mail.gmail.com>

Hi,

On Mon, Aug 16, 2021 at 4:12 PM Bjorn Andersson
<bjorn.andersson at linaro.org> wrote:
>
> Douglas Anderson (1):
>       arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip

I hope the above patch doesn't cause problems. I had landed it in the
drm-misc-next tree as per:

https://lore.kernel.org/linux-arm-msm/YMDdyEzCpdttQyNu at builder.lan/

Presumably git will magically do the right thing here since nothing
else on nearby lines is changing, but I at least wanted to point this
out in case there are any issues. Right now in linuxnext I see both
changes:

ab428819ee3f arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip
ab6f24b404c9 arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip


-Doug


From sean.anderson at seco.com  Mon Aug 16 16:51:17 2021
From: sean.anderson at seco.com (Sean Anderson)
Date: Mon, 16 Aug 2021 19:51:17 -0400
Subject: [PATCH v5 3/3] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <20210814204710.retjwn5fycwtrypp@pengutronix.de>
References: <20210719221322.3723009-1-sean.anderson@seco.com>
 <20210719221322.3723009-3-sean.anderson@seco.com>
 <20210814204710.retjwn5fycwtrypp@pengutronix.de>
Message-ID: <e8d39f18-3aa9-e617-6439-2c0b071f62b3@seco.com>



On 8/14/21 4:47 PM, Uwe Kleine-K?nig wrote:
> Hello Sean,
>
> sorry for having you let waiting so long. Now here some more feedback:
>
> On Mon, Jul 19, 2021 at 06:13:22PM -0400, Sean Anderson wrote:
>> +static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
>> +			    const struct pwm_state *state)
>> +{
>> +	bool enabled;
>> +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
>> +	u32 tlr0, tlr1, tcsr0, tcsr1;
>> +	u64 period_cycles, duty_cycles;
>> +	unsigned long rate;
>> +
>> +	if (state->polarity != PWM_POLARITY_NORMAL)
>> +		return -EINVAL;
>> +
>> +	/*
>> +	 * To be representable by TLR, cycles must be between 2 and
>> +	 * priv->max + 2. To enforce this we can reduce the duty
>> +	 * cycle, but we may not increase it.
>> +	 */
>> +	rate = clk_get_rate(priv->clk);
>> +	period_cycles = mul_u64_u32_div(state->period, rate, NSEC_PER_SEC);
>
> cool, I didn't know mul_u64_u32_div.

I didn't either. Alas, many useful functions like these have no
documentation...

>
> Hmm, we still have a problem here if
>
> 	state->period * rate > 1000000000 * U64_MAX.

Note that this can only occur with rate > 1GHz (and period = U64_MAX).
The highest fmax in the datasheet is 300 MHz (on a very expensive FPGA).

Maybe it is more prudent to do

	period = min(state->period, ULONG_MAX * NSEC_PER_SEC)

I think a period of 136 years is adequate :) This comparison also has
the advantage of being against const values.

> So to be entirely save, we either need:
>
> 	/*
> 	 * To ensure that period * rate / NSEC_PER_SEC fits into an u64
> 	 * we need:
> 	 *            U64_MAX * NSEC_PER_SEC
> 	 *   period < ----------------------
> 	 *                    rate
>           *
> 	 * . If rate is not bigger than NSEC_PER_SEC this is true for
> 	 * sure as the RHS is bigger than U64_MAX. Otherwise we can
> 	 * calculate the RHS using mul_u64_u32_div.
> 	 */
> 	if (rate > NSEC_PER_SEC)
> 		period = min(state->period, mul_u64_u32_div(U64_MAX, NSEC_PER_SEC, rate);
> 	else
> 		period = state->period;
>
> or we go a step further and check the priv->max limit in the same step:
>
> 	period = min(state->period, ((u64)priv->max + 2) * NSEC_PER_SEC / rate)
>
> . The latter is simpler and it's safe as priv->max is an u32 and so
> there is no overflow.
>
>> +	if (period_cycles - 2 > priv->max || period_cycles < 2)
>
> I'd check for period_cycles < 2 first, because otherwise period_cycles -
> 2 might underflow. Nothing bad happens in this case, but reading from
> left to right my first thought was I found a bug. Also please decrease
> period_cycles if it's bigger than priv->max + 2. (With the suggestion
> above you don't need to check for period_cycles - 2 > priv->max any more
> however.)

Ok, will swap.

>> +		return -ERANGE;
>> +	duty_cycles = mul_u64_u32_div(state->duty_cycle, rate, NSEC_PER_SEC);
>> +
>> +	/*
>> +	 * If we specify 100% duty cycle, we will get 0% instead, so decrease
>> +	 * the duty cycle count by one.
>> +	 */
>> +	if (period_cycles == duty_cycles)
>> +		duty_cycles--;
>> +
>> +	/* Round down to 0% duty cycle for unrepresentable duty cycles */
>> +	if (duty_cycles < 2)
>> +		duty_cycles = period_cycles;
>> +
>> +	regmap_read(priv->map, TCSR0, &tcsr0);
>> +	regmap_read(priv->map, TCSR1, &tcsr1);
>> +	tlr0 = xilinx_timer_tlr_cycles(priv, tcsr0, period_cycles);
>> +	tlr1 = xilinx_timer_tlr_cycles(priv, tcsr1, duty_cycles);
>> +	regmap_write(priv->map, TLR0, tlr0);
>> +	regmap_write(priv->map, TLR1, tlr1);
>> +
>> +	enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1);
>> +	if (state->enabled) {
>> +		/*
>> +		 * If the PWM is already running, then the counters will be
>> +		 * reloaded at the end of the current cycle.
>> +		 */
>
> If state->enabled is false, $enabled isn't used, so you can move the
> assignment into the if body and also limit the scope of $enabled.

Ok.

>> +		if (!enabled) {
>> +			/* Load TLR into TCR */
>> +			regmap_write(priv->map, TCSR0, tcsr0 | TCSR_LOAD);
>> +			regmap_write(priv->map, TCSR1, tcsr1 | TCSR_LOAD);
>> +			/* Enable timers all at once with ENALL */
>> +			tcsr0 = (TCSR_PWM_SET & ~TCSR_ENT) | (tcsr0 & TCSR_UDT);
>> +			tcsr1 = TCSR_PWM_SET | TCSR_ENALL | (tcsr1 & TCSR_UDT);
>> +			regmap_write(priv->map, TCSR0, tcsr0);
>> +			regmap_write(priv->map, TCSR1, tcsr1);
>> +		}
>> +	} else {
>> +		regmap_write(priv->map, TCSR0, 0);
>> +		regmap_write(priv->map, TCSR1, 0);
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void xilinx_pwm_get_state(struct pwm_chip *chip,
>> +				 struct pwm_device *unused,
>> +				 struct pwm_state *state)
>> +{
>> +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
>> +	u32 tlr0, tlr1, tcsr0, tcsr1;
>> +
>> +	regmap_read(priv->map, TLR0, &tlr0);
>> +	regmap_read(priv->map, TLR1, &tlr1);
>> +	regmap_read(priv->map, TCSR0, &tcsr0);
>> +	regmap_read(priv->map, TCSR1, &tcsr1);
>> +	state->period = xilinx_timer_get_period(priv, tlr0, tcsr0);
>
> xilinx_timer_get_period rounds down, this is however wrong for
> .get_state().

Why is this wrong? I thought get_state should return values which would
not be rounded if passed to apply_state.

>> +	state->duty_cycle = xilinx_timer_get_period(priv, tlr1, tcsr1);
>
> ditto for duty_cycle.
>
>> +	state->enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1);
>> +	state->polarity = PWM_POLARITY_NORMAL;
>> [...]
>> +static int xilinx_timer_probe(struct platform_device *pdev)
>> +{
>> +	int ret;
>> +	struct device *dev = &pdev->dev;
>> +	struct device_node *np = dev->of_node;
>> +	struct xilinx_timer_priv *priv;
>> +	struct xilinx_pwm_device *pwm;
>> +	u32 pwm_cells, one_timer;
>> +	void __iomem *regs;
>> +
>> +	ret = of_property_read_u32(np, "#pwm-cells", &pwm_cells);
>> +	if (ret == -EINVAL)
>> +		return -ENODEV;
>> +	else if (ret)
>> +		return dev_err_probe(dev, ret, "could not read #pwm-cells\n");
>
> Please capitalize error messages.

Ok.

>> [...]
>> +	if (ret) {
>> +		clk_rate_exclusive_put(priv->clk);
>> +		clk_disable_unprepare(priv->clk);
>> +		return dev_err_probe(dev, ret, "could not register pwm chip\n");
>
> s/pwm/PWM/

Ok.

Thanks for the review.

--Sean


From bjorn.andersson at linaro.org  Mon Aug 16 16:54:20 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Mon, 16 Aug 2021 18:54:20 -0500
Subject: [GIT PULL] Qualcomm ARM64 updates for v5.15
In-Reply-To: <CAD=FV=XHOOjVgoQsS7vMDzeov0p6groC6Qnxz_TWpFj7dh7XLQ@mail.gmail.com>
References: <20210816231223.586597-1-bjorn.andersson@linaro.org>
 <CAD=FV=XHOOjVgoQsS7vMDzeov0p6groC6Qnxz_TWpFj7dh7XLQ@mail.gmail.com>
Message-ID: <YRr6rLXRn0m4KUMx@builder.lan>

On Mon 16 Aug 18:41 CDT 2021, Doug Anderson wrote:

> Hi,
> 
> On Mon, Aug 16, 2021 at 4:12 PM Bjorn Andersson
> <bjorn.andersson at linaro.org> wrote:
> >
> > Douglas Anderson (1):
> >       arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip
> 
> I hope the above patch doesn't cause problems. I had landed it in the
> drm-misc-next tree as per:
> 
> https://lore.kernel.org/linux-arm-msm/YMDdyEzCpdttQyNu at builder.lan/
> 
> Presumably git will magically do the right thing here since nothing
> else on nearby lines is changing, but I at least wanted to point this
> out in case there are any issues. Right now in linuxnext I see both
> changes:
> 
> ab428819ee3f arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip
> ab6f24b404c9 arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip
> 

Yes, we agreed that you should take it through drm-misc and I must have
forgotten about that as I drained the patchwork queue.

This has been sitting in linux-next for a while now and I've not seen
any reports from Stephen, so I think we're good.

Regards,
Bjorn


From rentao.bupt at gmail.com  Mon Aug 16 17:01:49 2021
From: rentao.bupt at gmail.com (Tao Ren)
Date: Mon, 16 Aug 2021 17:01:49 -0700
Subject: [PATCH v2 4/6] ARM: dts: aspeed: Add Facebook Cloudripper
 (AST2600) BMC
In-Reply-To: <YRfgv5OknMluW7jj@lunn.ch>
References: <20210805222818.8391-1-rentao.bupt@gmail.com>
 <20210805222818.8391-5-rentao.bupt@gmail.com>
 <CACPK8XcV5On2D4D+SXnfw1M0owwfCL4Su19jOEA7yWpq+T3jLw@mail.gmail.com>
 <20210813034016.GA21895@taoren-ubuntu-R90MNF91>
 <YRaFpq1LvRzMYr/A@lunn.ch>
 <20210814052228.GA1298@taoren-ubuntu-R90MNF91>
 <YRfgv5OknMluW7jj@lunn.ch>
Message-ID: <20210817000148.GA7547@taoren-ubuntu-R90MNF91>

On Sat, Aug 14, 2021 at 05:26:55PM +0200, Andrew Lunn wrote:
> > Thanks for jumping in. We are using BCM5389 and the MDIO bus is used to
> > access BCM5389 MDC/MDIO interface in Pseudo-PHY mode.
> > 
> > I didn't know drivers/net/dsa, but let me check out the drivers and see
> > if it works in the Cloudripper environment.
> 
> The b53 driver knows about this switch, so please make use of that
> driver. See Documentation/devicetree/bindings/net/dsa/brcm,b53.yaml
> for how you describe it in DT.
> 
>     Andrew

Thank you Andrew for looking into it. I will update dts and send out
followup patch after validation (perhaps after v5.15 merge window).


Thanks,

Tao


From rentao.bupt at gmail.com  Mon Aug 16 17:04:04 2021
From: rentao.bupt at gmail.com (Tao Ren)
Date: Mon, 16 Aug 2021 17:04:04 -0700
Subject: [PATCH] ARM: dts: aspeed: minipack: Update flash partition table
In-Reply-To: <CACPK8XcAqU3KASespqS3dPterpzyqD4wYH=qOS8Ok2yUrB_F+Q@mail.gmail.com>
References: <20210720002704.7390-1-rentao.bupt@gmail.com>
 <20210813062435.GA24497@taoren-ubuntu-R90MNF91>
 <CACPK8XcAqU3KASespqS3dPterpzyqD4wYH=qOS8Ok2yUrB_F+Q@mail.gmail.com>
Message-ID: <20210817000403.GB7547@taoren-ubuntu-R90MNF91>

On Mon, Aug 16, 2021 at 02:11:40AM +0000, Joel Stanley wrote:
> On Fri, 13 Aug 2021 at 06:24, Tao Ren <rentao.bupt at gmail.com> wrote:
> >
> > Hi Joel,
> >
> > Looks like the patch is not included in "dt-for-v5.15". Any comments? Or
> > should I send v2 if the email was not delivered?
> 
> I had missed it. It's now applied for 5.15.
> 
> Cheers,
> 
> Joel

Thank you Joel.

Cheers,

Tao


From valentin.schneider at arm.com  Mon Aug 16 17:30:43 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Tue, 17 Aug 2021 01:30:43 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87eeav19mc.wl-maz@kernel.org>
References: <20210814194737.GA3951530@roeck-us.net>
 <87sfzb7jeo.mognet@arm.com> <87eeav19mc.wl-maz@kernel.org>
Message-ID: <87k0kk7w0c.mognet@arm.com>

On 15/08/21 07:54, Marc Zyngier wrote:
> This is going and-up in a wack-a-mole game. There is probably a bunch
> of these all over the place. I'd rather squash it at the root,
> i.e. with something like this (untested):
>
> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> index 099bc7e13d1b..601ad3fc47cd 100644
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -410,7 +410,12 @@ void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
>
>  void ack_irq(struct irq_desc *desc)
>  {
> -	desc->irq_data.chip->irq_ack(&desc->irq_data);
> +	struct irq_data *data = &desc->irq_data;
> +
> +	while (!data->chip->irq_ack)
> +		data = data->parent_data;
> +
> +	data->chip->irq_ack(&desc->irq_data);
>
>       if (desc->irq_data.chip->flags & IRQCHIP_AUTOMASKS_FLOW)
>               irq_state_set_flow_masked(desc);
>
> We probably need something similar for irq_eoi().
>
> This however shows a more fundamental problem, I'm afraid. We set
> IRQCHIP_AUTOMASKS_FLOW in the GIC drivers (i.e. at the root), but test
> for it at the top of the hierarchy. As soon as we have more than a
> single layer of irqchip, this will do the wrong thing (or at least
> miss the masking optimisation).
>

Yup.

> This probably advocates for moving the flag into the descriptor. This
> really makes sense, as the flow is global to the whole stack, not just
> to the localised irqchip.
>

Are we guaranteed to have

  .irq_ack \in {NULL, irq_chip_ack_parent}

for all intermediate (!root) irqchips? I don't see why that wouldn't be the
case, and with that in mind what you described makes sense to me.

> In order to restore -next into a working state, I'm temporarily
> dropping this series. Hopefully, we can sort this out before the merge
> window and reinstate it.
>

I'm away from any keyboard for most of this week, but I'll get to it by the
weekend.

> Thanks,
>
>       M.
>
> --
> Without deviation from the norm, progress is not possible.


From pgwipeout at gmail.com  Mon Aug 16 17:52:07 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Mon, 16 Aug 2021 20:52:07 -0400
Subject: [PATCH v13 0/6] Add Rockchip SFC(serial flash controller) support
In-Reply-To: <20210812134546.31340-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
Message-ID: <CAMdYzYobqhLAHhDU9E-iu-HMKSaGCDBMU-2OacGEZOQnF2ZyMw@mail.gmail.com>

On Thu, Aug 12, 2021 at 9:49 AM Jon Lin <jon.lin at rock-chips.com> wrote:
>

Good Evening,

Tested successfully on the rk3566 based Quartz64 Model A.
Tested-by: Peter Geis <pgwipeout at gmail.com>

Very Respectfully,
Peter Geis

>
>
> Changes in v13:
> - Provide independent interfaces to obtain RX TX FIFO status respectively
> - Add more debug information
> - Depress DMA limitation
>
> Changes in v12:
> - Remove useless oneOf lable
> - Add sfc controller discription
> - Remove the limitation of SFC_MIN_SPEED_HZ
> - Add IRQ_NONE method for irq handler
> - Add SPI_MASTER_HALF_DUPLEX flags
> - Add sfc interrupt mask bits and status register initial progress
>
> Changes in v11:
> - The tx is set to 1 for Odroid Go Advance device
>
> Changes in v10:
> - Fix dma transfer logic
>
> Changes in v9:
> - Separate DMA IRQ setting and wait_completion from DMA fifo transfer
>   function to make dma_status_poll be possible(Which I will implement
>   in u-boot)
> - Add SFC Kconfig detail comment
>
> Changes in v8:
> - Fix indent 4 to 2 in yaml
>
> Changes in v7:
> - Fix up the sclk_sfc parent error in rk3036
> - Unify to "rockchip,sfc" compatible id because all the feature update
>   will have a new IP version, so the driver is used for the SFC IP in
>   all SoCs
> - Change to use node "sfc" to name the SFC pinctrl group
> - Add subnode reg property check
> - Add rockchip_sfc_adjust_op_size to workaround in CMD + DUMMY case
> - Limit max_iosize to 32KB
>
> Changes in v6:
> - Add support in device trees for rv1126(Declared in series 5 but not
>   submitted)
> - Change to use "clk_sfc" "hclk_sfc" as clock lable, since it does not
>   affect interpretation and has been widely used
> - Support sfc tx_dual, tx_quad(Declared in series 5 but not submitted)
> - Simplify the code, such as remove "rockchip_sfc_register_all"(Declared
>   in series 5 but not submitted)
> - Support SFC ver4 ver5(Declared in series 5 but not submitted)
> - Add author Chris Morgan and Jon Lin to spi-rockchip-sfc.c
> - Change to use devm_spi_alloc_master and spi_unregister_master
>
> Changes in v5:
> - Add support in device trees for rv1126
> - Support sfc tx_dual, tx_quad
> - Simplify the code, such as remove "rockchip_sfc_register_all"
> - Support SFC ver4 ver5
>
> Changes in v4:
> - Changing patch back to an "RFC". An engineer from Rockchip
>   reached out to me to let me know they are working on this patch for
>   upstream, I am submitting this v4 for the community to see however
>   I expect Jon Lin (jon.lin at rock-chips.com) will submit new patches
>   soon and these are the ones we should pursue for mainlining. Jon's
>   patch series should include support for more hardware than this
>   series.
> - Clean up documentation more and ensure it is correct per
>   make dt_binding_check.
> - Add support in device trees for rk3036, rk3308, and rv1108.
> - Add ahb clock (hclk_sfc) support for rk3036.
> - Change rockchip_sfc_wait_fifo_ready() to use a switch statement.
> - Change IRQ code to only mark IRQ as handled if it handles the
>   specific IRQ (DMA transfer finish) it is supposed to handle.
>
> Changes in v3:
> - Changed the name of the clocks to sfc/ahb (from clk-sfc/clk-hsfc).
> - Changed the compatible string from rockchip,sfc to
>   rockchip,rk3036-sfc. A quick glance at the datasheets suggests this
>   driver should work for the PX30, RK180x, RK3036, RK312x, RK3308 and
>   RV1108 SoCs, and possibly more. However, I am currently only able
>   to test this on a PX30 (an RK3326). The technical reference manuals
>   appear to list the same registers for each device.
> - Corrected devicetree documentation for formatting and to note these
>   changes.
> - Replaced the maintainer with Heiko Stuebner and myself, as we will
>   take ownership of this going forward.
> - Noted that the device (per the reference manual) supports 4 CS, but
>   I am only able to test a single CS (CS 0).
> - Reordered patches to comply with upstream rules.
>
> Changes in v2:
> - Reimplemented driver using spi-mem subsystem.
> - Removed power management code as I couldn't get it working properly.
> - Added device tree bindings for Odroid Go Advance.
>
> Changes in v1:
> hanges made in this new series versus the v8 of the old series:
> - Added function to read spi-rx-bus-width from device tree, in the
>   event that the SPI chip supports 4x mode but only has 2 pins
>   wired (such as the Odroid Go Advance).
> - Changed device tree documentation from txt to yaml format.
> - Made "reset" message a dev_dbg from a dev_info.
> - Changed read and write fifo functions to remove redundant checks.
> - Changed the write and read from relaxed to non-relaxed when
>   starting the DMA transfer or reading the DMA IRQ.
> - Changed from dma_coerce_mask_and_coherent to just
>   dma_set_mask_and_coherent.
> - Changed name of get_if_type to rockchip_sfc_get_if_type.
>
> Chris Morgan (6):
>   dt-bindings: rockchip-sfc: Bindings for Rockchip serial flash
>     controller
>   spi: rockchip-sfc: add rockchip serial flash controller
>   arm64: dts: rockchip: Add SFC to PX30
>   arm: dts: rockchip: Add SFC to RV1108
>   arm64: dts: rockchip: Add SFC to RK3308
>   arm64: dts: rockchip: Enable SFC for Odroid Go Advance
>
>  .../devicetree/bindings/spi/rockchip-sfc.yaml |  91 +++
>  arch/arm/boot/dts/rv1108.dtsi                 |  37 +
>  arch/arm64/boot/dts/rockchip/px30.dtsi        |  38 +
>  arch/arm64/boot/dts/rockchip/rk3308.dtsi      |  37 +
>  .../boot/dts/rockchip/rk3326-odroid-go2.dts   |  16 +
>  drivers/spi/Kconfig                           |  12 +
>  drivers/spi/Makefile                          |   1 +
>  drivers/spi/spi-rockchip-sfc.c                | 694 ++++++++++++++++++
>  8 files changed, 926 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/spi/rockchip-sfc.yaml
>  create mode 100644 drivers/spi/spi-rockchip-sfc.c
>
> --
> 2.17.1
>
>
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From chun-jie.chen at mediatek.com  Mon Aug 16 17:56:46 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Tue, 17 Aug 2021 08:56:46 +0800
Subject: [PATCH 08/22] clk: mediatek: Add MT8195 ccusys clock support
In-Reply-To: <CAGXv+5ETXT-pxuP1NFEUrV+m3RR25zD9RZmDjHxVOLOy7gGj8w@mail.gmail.com>
References: <20210616224743.5109-1-chun-jie.chen@mediatek.com>
 <20210616224743.5109-9-chun-jie.chen@mediatek.com>
 <CAGXv+5ETXT-pxuP1NFEUrV+m3RR25zD9RZmDjHxVOLOy7gGj8w@mail.gmail.com>
Message-ID: <326b8ef66a70b526d11b0e2fad4f94b22241e9c1.camel@mediatek.com>

On Tue, 2021-07-06 at 17:00 +0800, Chen-Yu Tsai wrote:
> On Thu, Jun 17, 2021 at 6:59 AM Chun-Jie Chen
> <chun-jie.chen at mediatek.com> wrote:
> > 
> > Add MT8195 ccusys clock provider
> > 
> > Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> 
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> 
> Also, I noticed that Mediatek drivers don't support the reset
> controls found
> in these clock controllers. Are there plans to add support for them?

At present, we have no plan to support reset control in clock
controllers because no request from sub system, but we have reset
controller in MT8195 from TOPRGU [1].

[1] 
https://patchwork.kernel.org/project/linux-mediatek/list/?series=521219

Best Regards,
Chun-Jie

From chun-jie.chen at mediatek.com  Mon Aug 16 18:07:08 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Tue, 17 Aug 2021 09:07:08 +0800
Subject: [v3 3/5] soc: mediatek: pm-domains: Add support for mt8195
In-Reply-To: <CAGXv+5FNhykEvuO9RNr=ShuU+z1x7dxyGOGbf1K-9a==cnQQeA@mail.gmail.com>
References: <20210705054111.4473-1-chun-jie.chen@mediatek.com>
 <20210705054111.4473-4-chun-jie.chen@mediatek.com>
 <CAGXv+5EG00P4EzNjm=7nRNwYwEF9aXorhELsmbxtrYM20SW0KQ@mail.gmail.com>
 <526dc9077c696015d1f1065cb6e7f2c7c446ad61.camel@mediatek.com>
 <CAGXv+5FNhykEvuO9RNr=ShuU+z1x7dxyGOGbf1K-9a==cnQQeA@mail.gmail.com>
Message-ID: <c53f54178fdb6ddde2881901c3a6422b5f8b746d.camel@mediatek.com>

On Fri, 2021-07-30 at 12:20 +0800, Chen-Yu Tsai wrote:
> On Fri, Jul 30, 2021 at 11:13 AM Chun-Jie Chen
> <chun-jie.chen at mediatek.com> wrote:
> > 
> > On Tue, 2021-07-20 at 16:51 +0800, Chen-Yu Tsai wrote:
> > > Hi,
> > > On Mon, Jul 5, 2021 at 1:42 PM Chun-Jie Chen <
> > > chun-jie.chen at mediatek.com> wrote:
> > > > 
> > > > Add domain control data including bus protection data size
> > > > change due to more protection steps in mt8195.
> > > > 
> > > > Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > > > ---
> > > >  drivers/soc/mediatek/mt8195-pm-domains.h | 738
> > > > +++++++++++++++++++++++
> > > >  drivers/soc/mediatek/mtk-pm-domains.c    |   5 +
> > > >  drivers/soc/mediatek/mtk-pm-domains.h    |   2 +-
> > > >  include/linux/soc/mediatek/infracfg.h    | 103 ++++
> > > >  4 files changed, 847 insertions(+), 1 deletion(-)
> > > >  create mode 100644 drivers/soc/mediatek/mt8195-pm-domains.h
> > > > 
> > > > diff --git a/drivers/soc/mediatek/mt8195-pm-domains.h
> > > > b/drivers/soc/mediatek/mt8195-pm-domains.h
> > > > new file mode 100644
> > > > index 000000000000..54bb7af8e9a3
> > > > --- /dev/null
> > > > +++ b/drivers/soc/mediatek/mt8195-pm-domains.h
> > > > @@ -0,0 +1,738 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > > +/*
> > > > + * Copyright (c) 2021 MediaTek Inc.
> > > > + * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > > > + */
> > > > +
> > > > +#ifndef __SOC_MEDIATEK_MT8195_PM_DOMAINS_H
> > > > +#define __SOC_MEDIATEK_MT8195_PM_DOMAINS_H
> > > > +
> > > > +#include "mtk-pm-domains.h"
> > > > +#include <dt-bindings/power/mt8195-power.h>
> > > > +
> > > > +/*
> > > > + * MT8195 power domain support
> > > > + */
> > > > +
> > > > +static const struct scpsys_domain_data
> > > > scpsys_domain_data_mt8195[]
> > > > = {
> > > 
> > > The SCPSYS block is not documented in the datasheets available.
> > > However
> > > I did look at all the register and bit offsets and confirmed
> > > nothing
> > > overlapped.
> > > 
> > > > diff --git a/drivers/soc/mediatek/mtk-pm-domains.c
> > > > b/drivers/soc/mediatek/mtk-pm-domains.c
> > > > index 2689f02d7a41..12552c9996ac 100644
> > > > --- a/drivers/soc/mediatek/mtk-pm-domains.c
> > > > +++ b/drivers/soc/mediatek/mtk-pm-domains.c
> > > > @@ -20,6 +20,7 @@
> > > >  #include "mt8173-pm-domains.h"
> > > >  #include "mt8183-pm-domains.h"
> > > >  #include "mt8192-pm-domains.h"
> > > > +#include "mt8195-pm-domains.h"
> > > > 
> > > >  #define MTK_POLL_DELAY_US              10
> > > >  #define MTK_POLL_TIMEOUT               USEC_PER_SEC
> > > > @@ -576,6 +577,10 @@ static const struct of_device_id
> > > > scpsys_of_match[] = {
> > > >                 .compatible = "mediatek,mt8192-power-
> > > > controller",
> > > >                 .data = &mt8192_scpsys_data,
> > > >         },
> > > > +       {
> > > > +               .compatible = "mediatek,mt8195-power-
> > > > controller",
> > > > +               .data = &mt8195_scpsys_data,
> > > > +       },
> > > >         { }
> > > >  };
> > > > 
> > > > diff --git a/drivers/soc/mediatek/mtk-pm-domains.h
> > > > b/drivers/soc/mediatek/mtk-pm-domains.h
> > > > index 8b86ed22ca56..caaa38100093 100644
> > > > --- a/drivers/soc/mediatek/mtk-pm-domains.h
> > > > +++ b/drivers/soc/mediatek/mtk-pm-domains.h
> > > > @@ -37,7 +37,7 @@
> > > >  #define PWR_STATUS_AUDIO               BIT(24)
> > > >  #define PWR_STATUS_USB                 BIT(25)
> > > > 
> > > > -#define SPM_MAX_BUS_PROT_DATA          5
> > > > +#define SPM_MAX_BUS_PROT_DATA          6
> > > > 
> > > >  #define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) {
> > > > \
> > > >                 .bus_prot_mask =
> > > > (_mask),                       \
> > > > diff --git a/include/linux/soc/mediatek/infracfg.h
> > > > b/include/linux/soc/mediatek/infracfg.h
> > > > index 4615a228da51..3e90fb9b926a 100644
> > > > --- a/include/linux/soc/mediatek/infracfg.h
> > > > +++ b/include/linux/soc/mediatek/infracfg.h
> > > > @@ -2,6 +2,109 @@
> > > >  #ifndef __SOC_MEDIATEK_INFRACFG_H
> > > >  #define __SOC_MEDIATEK_INFRACFG_H
> > > > 
> > > > +#define MT8195_TOP_AXI_PROT_EN_STA1                     0x228
> > > > +#define MT8195_TOP_AXI_PROT_EN_1_STA1                   0x258
> > > > +#define MT8195_TOP_AXI_PROT_EN_SET                     0x2a0
> > > > +#define MT8195_TOP_AXI_PROT_EN_CLR                      0x2a4
> > > > +#define MT8195_TOP_AXI_PROT_EN_1_SET                    0x2a8
> > > > +#define MT8195_TOP_AXI_PROT_EN_1_CLR                    0x2ac
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_SET                   0x2d4
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_CLR                   0x2d8
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_STA1                  0x2ec
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_SET                    0x714
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_CLR                    0x718
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_STA1                   0x724
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_SET                 0xb84
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_CLR                 0xb88
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_STA1                0xb90
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_1_SET               0xba4
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR               0xba8
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1              0xbb0
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_2_SET               0xbb8
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_2_CLR               0xbbc
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_2_STA1              0xbc4
> > > > +#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET       0xbcc
> > > > +#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR       0xbd0
> > > > +#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1      0xbd8
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_SET                 0xdcc
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_CLR                 0xdd0
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_STA1                0xdd8
> > > 
> > > These all look correct.
> > > 
> > > > +#define MT8195_TOP_AXI_PROT_EN_NNA0                    BIT(1)
> > > > +#define MT8195_TOP_AXI_PROT_EN_NNA1                    BIT(2)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_NNA                     GENMASK(2,
> > > > 1)
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDOSYS0                 BIT(6)
> > > > +#define MT8195_TOP_AXI_PROT_EN_VPPSYS0                 BIT(10)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MFG1                    BIT(11)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MFG1_2ND                        GENMASK(
> > > > 22,
> > > > 21)
> > > > +#define MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND             BIT(23)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_1_MFG1                  GENMASK(20,
> > > > 19)
> > > > +#define MT8195_TOP_AXI_PROT_EN_1_CAM                   BIT(22)
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_CAM                   BIT(0)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND              GENMASK(6,
> > > > 5)
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_MFG1                  BIT(7)
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_AUDIO_ASRC            (BIT(8)
> > > > |
> > > > BIT(17))
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_AUDIO                 (BIT(9)
> > > > |
> > > > BIT(11))
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_2_ADSP                  (BIT(12) |
> > > > GENMASK(16, 14))
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_NNA0_2ND              BIT(19)
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_NNA1_2ND              BIT(20)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_2_NNA_2ND               GENMASK(20,
> > > > 19)
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_NNA0                  BIT(21)
> > > > +#define MT8195_TOP_AXI_PROT_EN_2_NNA1                  BIT(22)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_2_NNA                   GENMASK(22,
> > > > 21)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_CAM                  (BIT(0)
> > > > |
> > > > BIT(2) | BIT(4))
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_IPE                  BIT(1)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_IMG                  (BIT(1)
> > > > |
> > > > BIT(3))
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_VPPSYS0              (GENMASK(2,
> > > > 0) | GENMASK(8, 6) |        \
> > > > +                                                       GENMASK
> > > > (12,
> > > > 10) | GENMASK(21, 19) |     \
> > > > +                                                       BIT(31)
> > > > )
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0              (GENMASK(5,
> > > > 3) | BIT(9) |       \
> > > > +                                                       GENMASK
> > > > (14,
> > > > 13) | GENMASK(21, 17) |     \
> > > > +                                                       BIT(30)
> > > > )
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1              GENMASK(8,
> > > > 5)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_VENC                 (BIT(9)
> > > > |
> > > > BIT(11))
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1           (BIT(10) |
> > > > BIT(12))
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_VDEC0                        BIT(13)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_VDEC1                        BIT(14)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND          BIT(22)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND          BIT(23)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND              BIT(24)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND              BIT(25)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND             BIT(26)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_WPESYS               BIT(27)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND            BIT(28)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND            BIT(29)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0_2ND          GENMASK(29,
> > > > 22)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1              GENMASK(31,
> > > > 30)
> > > 
> > > There's significant overlap within this block. This means when
> > > the
> > > base
> > > VDOSYS0 power domain is on, all the overlapped protection bits
> > > get
> > > turned
> > > off. I'm not sure that's correct.
> > > 
> > > Same goes for IMG, which overlaps with IPE.
> > > 
> > 
> > Because the timing of enable & disable protection are different, we
> > duplicate some control bit in different power domain.
> > 
> > For example: IMG & IPE are parent and child relation, so IMG must
> > power
> > on before IPE, IPE must power off before IMG.
> > We want to clear some bits (protection disable) when power on IMG
> > and
> > set some bits (protection enable) when power off IPE.
> 
> Could you add that as a comment? Otherwise it just looks weird.
> And if some change related to the power sequencing order resulted
> in the system hanging, we might not spot it so easily.
> 
> Thanks
> ChenYu
> 

Some protection steps are redundant in parent power domain, I will
remove these duplicate steps if these can be handled in child power
domain. Thanks for your kindly reminder.

Best Regards,
Chun-Jie


> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND                (GENMASK
> > > > (7,
> > > > 0) | GENMASK(18, 11))
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_VENC               BIT(2)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1         (BIT(3)
> > > > |
> > > > BIT(15))
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_2_CAM                        (BIT(5)
> > > > |
> > > > BIT(17))
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1            (GENMASK(7,
> > > > 6) | BIT(18))
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0            (GENMASK(9,
> > > > 8) | GENMASK(22, 21) | BIT(24))
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1            BIT(10)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND          BIT(12)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND          BIT(13)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND         BIT(14)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_2_IMG                        BIT(16)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_2_IPE                        BIT(16)
> > > 
> > > And here, IMG and IPE are the same.
> > > 
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2              BIT(21)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0              BIT(22)
> > > > +#define MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS0            BIT(23)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS             GENMASK(24,
> > > > 23)
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX           BIT(1)
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX            BIT(2)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0                (BIT(11)
> > > > |
> > > > BIT(28))
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1                (BIT(12)
> > > > |
> > > > BIT(29))
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0      BIT(13)
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1      BIT(14)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1     (BIT(17) |
> > > > BIT(19))
> > > > +#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0  BIT(20)
> > > > +#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0  BIT(21)
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_2_NNA0             BIT(25)
> > > > +#define MT8195_TOP_AXI_PROT_EN_VDNR_2_NNA1             BIT(26)
> > > > +#define
> > > > MT8195_TOP_AXI_PROT_EN_VDNR_2_NNA              GENMASK(26,
> > > > 25)
> > > > +
> > > 
> > > All these MT8195_TOP_AXI_PROT_EN_* bit offsets aren't documented.
> > > Besides
> > > the huge overlap above, it seems NNA also includes NNA0 and NNA1.
> > > 
> > > 
> > > Regards
> > > ChenYu
> > > 
> > 
> > The detail of MT8195_TOP_AXI_PROT_EN_* bit is related to the bus
> > design, so we don't descript the detail in datasheet.
> > 
> > I will remove the unused power domain and data (like NNA) because
> > these
> > are not used in 8195 chrome project.
> > 
> > Best Regards,
> > Chun-Jie
> > 
> > > 
> > > >  #define MT8192_TOP_AXI_PROT_EN_STA1                    0x228
> > > >  #define MT8192_TOP_AXI_PROT_EN_1_STA1                  0x258
> > > >  #define MT8192_TOP_AXI_PROT_EN_SET                     0x2a0
> > > > --
> > > > 2.18.0
> > > > _______________________________________________
> > > > Linux-mediatek mailing list
> > > > Linux-mediatek at lists.infradead.org
> > > > 
> > 
> > 
https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!3jALcSgob2IQknQnQlIPVKd79QdKmXI1Y9X7kaQ2KR8AYdyP0V8Km3u_Cfq8VPMJ4-zn$
> > > > 

From zhiyong.tao at mediatek.com  Mon Aug 16 19:21:16 2021
From: zhiyong.tao at mediatek.com (zhiyong.tao)
Date: Tue, 17 Aug 2021 10:21:16 +0800
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <CACRpkdbZKh8cqqiDRUik6Ooo33e+feGwYsLjcLRvBQnT3x5M3A@mail.gmail.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
 <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
 <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>
 <CACRpkdbZKh8cqqiDRUik6Ooo33e+feGwYsLjcLRvBQnT3x5M3A@mail.gmail.com>
Message-ID: <a7c8ab68ac3513865698cde27e665bdd554f459e.camel@mediatek.com>

On Tue, 2021-08-17 at 01:00 +0200, Linus Walleij wrote:
> On Mon, Aug 16, 2021 at 5:38 PM Chen-Yu Tsai <wenst at chromium.org>
> wrote:
> > On Mon, Aug 16, 2021 at 6:48 PM zhiyong.tao <
> > zhiyong.tao at mediatek.com> wrote:
> > > > I'll take that as "use SI units whenever possible and
> > > > reasonable".
> > > 
> > > ==> so It doesn't need to change the define, is it right?
> > > we will keep the common define.
> > 
> > Actually I think it would be possible and reasonable to use SI
> > units
> > in this case, since you are the vendor and have the resistor values
> > to implement the support. Having different sets of values for
> > different
> > chips is nothing out of the ordinary. We already have to account
> > for
> > different number of pins and different pin functions. That is what
> > compatible strings are for.
> 
> I fully agree with Chen-Yu's analysis here.
> 
> Zhiyong can you make an attempt to use SI units (Ohms) and see
> what it will look like? I think it will look better for users and it
> will
> be less risk to make mistakes.
> 
> Yours,
> Linus Walleij

Hi Linus & chen-yu,

The rsel actual bias resistance of each setting is different in
different IC. For example, in mt8195, the rsel actual bias resistance
setting like as:
MTK_PULL_SET_RSEL_000:75K in PU, 75k in PD;
MTK_PULL_SET
_RSEL_001:10k in PU, 5k in PD;
MTK_PULL_SET_RSEL_010:5k in PU, 75k in
PD;
MTK_PULL_SET_RSEL_011:4k in PU, 5K in PD;
MTK_PULL_SET_RSEL_100:3k in
PU, 75k in PD;
MTK_PULL_SET_RSEL_101:2k in PU, 5K in PD;
MTK_PULL_SET_RSE
L_110:1.5k in PU, 75k in PD;
MTK_PULL_SET_RSEL_111:1k in PU, 5k in PD.

but in mt8192, the rsel actual bias resistance setting like as:
MTK_PULL_SET_RSEL_000:75K in PU, 75k in PD;
MTK_PULL_SET_RSEL_001:3k in PU, 5k in PD;
MTK_PULL_SET_RSEL_010:10k in PU, 75k in PD;
MTK_PULL_SET_RSEL_011:1k in PU, 5K in PD;

Can you help me to provide a suggestion common define for the all
different IC?
It seems that we should add a new define, if we upstream a new IC
pinctrl driver in the future.

Thanks.


From chiawei_wang at aspeedtech.com  Mon Aug 16 19:58:48 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Tue, 17 Aug 2021 10:58:48 +0800
Subject: [PATCH v2 2/2] ARM: dts: aspeed: Add mailbox to device tree
In-Reply-To: <20210817025848.19914-1-chiawei_wang@aspeedtech.com>
References: <20210817025848.19914-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210817025848.19914-3-chiawei_wang@aspeedtech.com>

Add mailbox to the device tree for Aspeed AST24xx/AST25xx/AST26xx SoCs.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 arch/arm/boot/dts/aspeed-g4.dtsi | 7 +++++++
 arch/arm/boot/dts/aspeed-g5.dtsi | 8 +++++++-
 arch/arm/boot/dts/aspeed-g6.dtsi | 7 +++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index c5aeb3cf3a09..6298d69df415 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -383,6 +383,13 @@
 					interrupts = <8>;
 					status = "disabled";
 				};
+
+				mbox: mbox at 200 {
+					compatible = "aspeed,ast2500-mbox";
+					reg = <0x200 0x30>;
+					interrupts = <46>;
+					status = "disabled";
+				};
 			};
 
 			uart2: serial at 1e78d000 {
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 329eaeef66fb..ab9453d7803c 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -497,13 +497,19 @@
 					reg = <0xa0 0x24 0xc8 0x8>;
 				};
 
-
 				ibt: ibt at 140 {
 					compatible = "aspeed,ast2500-ibt-bmc";
 					reg = <0x140 0x18>;
 					interrupts = <8>;
 					status = "disabled";
 				};
+
+				mbox: mbox at 200 {
+					compatible = "aspeed,ast2500-mbox";
+					reg = <0x200 0x30>;
+					interrupts = <46>;
+					status = "disabled";
+				};
 			};
 
 			uart2: serial at 1e78d000 {
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index f96607b7b4e2..09b286f2ece2 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -529,6 +529,13 @@
 					interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
 					status = "disabled";
 				};
+
+				mbox: mbox at 200 {
+					compatible = "aspeed,ast2600-mbox";
+					reg = <0x200 0xc0>;
+					interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+					status = "disabled";
+				};
 			};
 
 			sdc: sdc at 1e740000 {
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Mon Aug 16 19:58:46 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Tue, 17 Aug 2021 10:58:46 +0800
Subject: [PATCH v2 0/2] aspeed: Add LPC mailbox support
Message-ID: <20210817025848.19914-1-chiawei_wang@aspeedtech.com>

Add driver support for the LPC mailbox controller of ASPEED SoCs.

v2:
 - Fix error handling for copy_to_user
 - Fix incorrect type in the .poll initializer

Chia-Wei Wang (2):
  soc: aspeed: Add LPC mailbox support
  ARM: dts: aspeed: Add mailbox to device tree

 arch/arm/boot/dts/aspeed-g4.dtsi     |   7 +
 arch/arm/boot/dts/aspeed-g5.dtsi     |   8 +-
 arch/arm/boot/dts/aspeed-g6.dtsi     |   7 +
 drivers/soc/aspeed/Kconfig           |  10 +
 drivers/soc/aspeed/Makefile          |   9 +-
 drivers/soc/aspeed/aspeed-lpc-mbox.c | 418 +++++++++++++++++++++++++++
 6 files changed, 454 insertions(+), 5 deletions(-)
 create mode 100644 drivers/soc/aspeed/aspeed-lpc-mbox.c

-- 
2.17.1



From chiawei_wang at aspeedtech.com  Mon Aug 16 19:58:47 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Tue, 17 Aug 2021 10:58:47 +0800
Subject: [PATCH v2 1/2] soc: aspeed: Add LPC mailbox support
In-Reply-To: <20210817025848.19914-1-chiawei_wang@aspeedtech.com>
References: <20210817025848.19914-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210817025848.19914-2-chiawei_wang@aspeedtech.com>

The LPC mailbox controller consists of multiple general
registers for the communication between the Host and the BMC.
The interrupts for data update signaling are also introduced.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
Reported-by: kernel test robot <lkp at intel.com>
Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
---
 drivers/soc/aspeed/Kconfig           |  10 +
 drivers/soc/aspeed/Makefile          |   9 +-
 drivers/soc/aspeed/aspeed-lpc-mbox.c | 418 +++++++++++++++++++++++++++
 3 files changed, 433 insertions(+), 4 deletions(-)
 create mode 100644 drivers/soc/aspeed/aspeed-lpc-mbox.c

diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
index 243ca196e6ad..5b31a6e2620c 100644
--- a/drivers/soc/aspeed/Kconfig
+++ b/drivers/soc/aspeed/Kconfig
@@ -24,6 +24,16 @@ config ASPEED_LPC_SNOOP
 	  allows the BMC to listen on and save the data written by
 	  the host to an arbitrary LPC I/O port.
 
+config ASPEED_LPC_MAILBOX
+	tristate "ASPEED LPC mailbox support"
+	select REGMAP
+	select MFD_SYSCON
+	default ARCH_ASPEED
+	help
+	  Provides a driver to control the LPC mailbox which possesses
+	  up to 32 data registers for the communication between the Host
+	  and the BMC over LPC.
+
 config ASPEED_P2A_CTRL
 	tristate "ASPEED P2A (VGA MMIO to BMC) bridge control"
 	select REGMAP
diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
index fcab7192e1a4..cde6b4514c97 100644
--- a/drivers/soc/aspeed/Makefile
+++ b/drivers/soc/aspeed/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_ASPEED_LPC_CTRL)	+= aspeed-lpc-ctrl.o
-obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
-obj-$(CONFIG_ASPEED_P2A_CTRL)	+= aspeed-p2a-ctrl.o
-obj-$(CONFIG_ASPEED_SOCINFO)	+= aspeed-socinfo.o
+obj-$(CONFIG_ASPEED_LPC_CTRL)		+= aspeed-lpc-ctrl.o
+obj-$(CONFIG_ASPEED_LPC_SNOOP)		+= aspeed-lpc-snoop.o
+obj-$(CONFIG_ASPEED_LPC_MAILBOX)	+= aspeed-lpc-mbox.o
+obj-$(CONFIG_ASPEED_P2A_CTRL)		+= aspeed-p2a-ctrl.o
+obj-$(CONFIG_ASPEED_SOCINFO)		+= aspeed-socinfo.o
diff --git a/drivers/soc/aspeed/aspeed-lpc-mbox.c b/drivers/soc/aspeed/aspeed-lpc-mbox.c
new file mode 100644
index 000000000000..a09ca6a175f7
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-lpc-mbox.c
@@ -0,0 +1,418 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2017 IBM Corporation
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define DEVICE_NAME	"aspeed-mbox"
+
+#define ASPEED_MBOX_DR(dr, n)	(dr + (n * 4))
+#define ASPEED_MBOX_STR(str, n)	(str + (n / 8) * 4)
+#define ASPEED_MBOX_BIE(bie, n)	(bie + (n / 8) * 4)
+#define ASPEED_MBOX_HIE(hie, n) (hie + (n / 8) * 4)
+
+#define ASPEED_MBOX_BCR_RECV	BIT(7)
+#define ASPEED_MBOX_BCR_MASK	BIT(1)
+#define ASPEED_MBOX_BCR_SEND	BIT(0)
+
+/* ioctl code */
+#define ASPEED_MBOX_IOCTL		0xA3
+#define ASPEED_MBOX_IOCTL_GET_SIZE	\
+	_IOR(ASPEED_MBOX_IOCTL, 0, struct aspeed_mbox_ioctl_data)
+
+struct aspeed_mbox_ioctl_data {
+	unsigned int data;
+};
+
+struct aspeed_mbox_model {
+	unsigned int dr_num;
+
+	/* offsets to the MBOX registers */
+	unsigned int dr;
+	unsigned int str;
+	unsigned int bcr;
+	unsigned int hcr;
+	unsigned int bie;
+	unsigned int hie;
+};
+
+struct aspeed_mbox {
+	struct miscdevice miscdev;
+	struct regmap *map;
+	unsigned int base;
+	wait_queue_head_t queue;
+	struct mutex mutex;
+	const struct aspeed_mbox_model *model;
+};
+
+static atomic_t aspeed_mbox_open_count = ATOMIC_INIT(0);
+
+static u8 aspeed_mbox_inb(struct aspeed_mbox *mbox, int reg)
+{
+	/*
+	 * The mbox registers are actually only one byte but are addressed
+	 * four bytes apart. The other three bytes are marked 'reserved',
+	 * they *should* be zero but lets not rely on it.
+	 * I am going to rely on the fact we can casually read/write to them...
+	 */
+	unsigned int val = 0xff; /* If regmap throws an error return 0xff */
+	int rc = regmap_read(mbox->map, mbox->base + reg, &val);
+
+	if (rc)
+		dev_err(mbox->miscdev.parent, "regmap_read() failed with "
+			"%d (reg: 0x%08x)\n", rc, reg);
+
+	return val & 0xff;
+}
+
+static void aspeed_mbox_outb(struct aspeed_mbox *mbox, u8 data, int reg)
+{
+	int rc = regmap_write(mbox->map, mbox->base + reg, data);
+
+	if (rc)
+		dev_err(mbox->miscdev.parent, "regmap_write() failed with "
+			"%d (data: %u reg: 0x%08x)\n", rc, data, reg);
+}
+
+static struct aspeed_mbox *file_mbox(struct file *file)
+{
+	return container_of(file->private_data, struct aspeed_mbox, miscdev);
+}
+
+static int aspeed_mbox_open(struct inode *inode, struct file *file)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+
+	if (atomic_inc_return(&aspeed_mbox_open_count) == 1) {
+		/*
+		 * Clear the interrupt status bit if it was left on and unmask
+		 * interrupts.
+		 * ASPEED_MBOX_BCR_RECV bit is W1C, this also unmasks in 1 step
+		 */
+		aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_RECV, model->bcr);
+		return 0;
+	}
+
+	atomic_dec(&aspeed_mbox_open_count);
+	return -EBUSY;
+}
+
+static ssize_t aspeed_mbox_read(struct file *file, char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+	char __user *p = buf;
+	ssize_t ret;
+	int i;
+
+	if (!access_ok(buf, count))
+		return -EFAULT;
+
+	if (count + *ppos > model->dr_num)
+		return -EINVAL;
+
+	if (file->f_flags & O_NONBLOCK) {
+		if (!(aspeed_mbox_inb(mbox, model->bcr) &
+				ASPEED_MBOX_BCR_RECV))
+			return -EAGAIN;
+	} else if (wait_event_interruptible(mbox->queue,
+				aspeed_mbox_inb(mbox, model->bcr) &
+				ASPEED_MBOX_BCR_RECV)) {
+		return -ERESTARTSYS;
+	}
+
+	mutex_lock(&mbox->mutex);
+
+	for (i = *ppos; count > 0 && i < model->dr_num; i++) {
+		uint8_t reg = aspeed_mbox_inb(mbox, ASPEED_MBOX_DR(model->dr, i));
+
+		ret = __put_user(reg, p);
+		if (ret)
+			goto out_unlock;
+
+		p++;
+		count--;
+	}
+
+	/* ASPEED_MBOX_BCR_RECV bit is write to clear, this also unmasks in 1 step */
+	aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_RECV, model->bcr);
+	ret = p - buf;
+
+out_unlock:
+	mutex_unlock(&mbox->mutex);
+	return ret;
+}
+
+static ssize_t aspeed_mbox_write(struct file *file, const char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+	const char __user *p = buf;
+	ssize_t ret;
+	char c;
+	int i;
+
+	if (!access_ok(buf, count))
+		return -EFAULT;
+
+	if (count + *ppos > model->dr_num)
+		return -EINVAL;
+
+	mutex_lock(&mbox->mutex);
+
+	for (i = *ppos; count > 0 && i < model->dr_num; i++) {
+		ret = __get_user(c, p);
+		if (ret)
+			goto out_unlock;
+
+		aspeed_mbox_outb(mbox, c, ASPEED_MBOX_DR(model->dr, i));
+		p++;
+		count--;
+	}
+
+	aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_SEND, model->bcr);
+	ret = p - buf;
+
+out_unlock:
+	mutex_unlock(&mbox->mutex);
+	return ret;
+}
+
+static __poll_t aspeed_mbox_poll(struct file *file, poll_table *wait)
+{
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+	__poll_t mask = 0;
+
+	poll_wait(file, &mbox->queue, wait);
+
+	if (aspeed_mbox_inb(mbox, model->bcr) & ASPEED_MBOX_BCR_RECV)
+		mask |= POLLIN;
+
+	return mask;
+}
+
+static int aspeed_mbox_release(struct inode *inode, struct file *file)
+{
+	atomic_dec(&aspeed_mbox_open_count);
+	return 0;
+}
+
+static long aspeed_mbox_ioctl(struct file *file, unsigned int cmd,
+				 unsigned long param)
+{
+	long ret = 0;
+	struct aspeed_mbox *mbox = file_mbox(file);
+	const struct aspeed_mbox_model *model = mbox->model;
+	struct aspeed_mbox_ioctl_data data;
+
+	switch (cmd) {
+	case ASPEED_MBOX_IOCTL_GET_SIZE:
+		data.data = model->dr_num;
+		if (copy_to_user((void __user *)param, &data, sizeof(data)))
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -ENOTTY;
+		break;
+	}
+
+	return ret;
+}
+
+static const struct file_operations aspeed_mbox_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_seek_end_llseek,
+	.read		= aspeed_mbox_read,
+	.write		= aspeed_mbox_write,
+	.open		= aspeed_mbox_open,
+	.release	= aspeed_mbox_release,
+	.poll		= aspeed_mbox_poll,
+	.unlocked_ioctl	= aspeed_mbox_ioctl,
+};
+
+static irqreturn_t aspeed_mbox_irq(int irq, void *arg)
+{
+	struct aspeed_mbox *mbox = arg;
+	const struct aspeed_mbox_model *model = mbox->model;
+
+	if (!(aspeed_mbox_inb(mbox, model->bcr) & ASPEED_MBOX_BCR_RECV))
+		return IRQ_NONE;
+
+	/*
+	 * Leave the status bit set so that we know the data is for us,
+	 * clear it once it has been read.
+	 */
+
+	/* Mask it off, we'll clear it when we the data gets read */
+	aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_MASK, model->bcr);
+
+	wake_up(&mbox->queue);
+	return IRQ_HANDLED;
+}
+
+static int aspeed_mbox_config_irq(struct aspeed_mbox *mbox,
+		struct platform_device *pdev)
+{
+	const struct aspeed_mbox_model *model = mbox->model;
+	struct device *dev = &pdev->dev;
+	int i, rc, irq;
+
+	irq = irq_of_parse_and_map(dev->of_node, 0);
+	if (!irq)
+		return -ENODEV;
+
+	rc = devm_request_irq(dev, irq, aspeed_mbox_irq,
+			IRQF_SHARED, DEVICE_NAME, mbox);
+	if (rc < 0) {
+		dev_err(dev, "Unable to request IRQ %d\n", irq);
+		return rc;
+	}
+
+	/*
+	 * Disable all register based interrupts.
+	 */
+	for (i = 0; i < model->dr_num / 8; ++i)
+		aspeed_mbox_outb(mbox, 0x00, ASPEED_MBOX_BIE(model->bie, i));
+
+	/* These registers are write one to clear. Clear them. */
+	for (i = 0; i < model->dr_num / 8; ++i)
+		aspeed_mbox_outb(mbox, 0xff, ASPEED_MBOX_STR(model->str, i));
+
+	aspeed_mbox_outb(mbox, ASPEED_MBOX_BCR_RECV, model->bcr);
+	return 0;
+}
+
+static int aspeed_mbox_probe(struct platform_device *pdev)
+{
+	struct aspeed_mbox *mbox;
+	struct device *dev;
+	int rc;
+
+	dev = &pdev->dev;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	dev_set_drvdata(&pdev->dev, mbox);
+
+	rc = of_property_read_u32(dev->of_node, "reg", &mbox->base);
+	if (rc) {
+		dev_err(dev, "Couldn't read reg device tree property\n");
+		return rc;
+	}
+
+	mbox->model = of_device_get_match_data(dev);
+	if (IS_ERR(mbox->model)) {
+		dev_err(dev, "Couldn't get model data\n");
+		return -ENODEV;
+	}
+
+	mbox->map = syscon_node_to_regmap(
+			pdev->dev.parent->of_node);
+	if (IS_ERR(mbox->map)) {
+		dev_err(dev, "Couldn't get regmap\n");
+		return -ENODEV;
+	}
+
+	mutex_init(&mbox->mutex);
+	init_waitqueue_head(&mbox->queue);
+
+	mbox->miscdev.minor = MISC_DYNAMIC_MINOR;
+	mbox->miscdev.name = DEVICE_NAME;
+	mbox->miscdev.fops = &aspeed_mbox_fops;
+	mbox->miscdev.parent = dev;
+	rc = misc_register(&mbox->miscdev);
+	if (rc) {
+		dev_err(dev, "Unable to register device\n");
+		return rc;
+	}
+
+	rc = aspeed_mbox_config_irq(mbox, pdev);
+	if (rc) {
+		dev_err(dev, "Failed to configure IRQ\n");
+		misc_deregister(&mbox->miscdev);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int aspeed_mbox_remove(struct platform_device *pdev)
+{
+	struct aspeed_mbox *mbox = dev_get_drvdata(&pdev->dev);
+
+	misc_deregister(&mbox->miscdev);
+
+	return 0;
+}
+
+static const struct aspeed_mbox_model ast2400_model = {
+	.dr_num = 16,
+	.dr	= 0x0,
+	.str = 0x40,
+	.bcr = 0x48,
+	.hcr = 0x4c,
+	.bie = 0x50,
+	.hie = 0x58,
+};
+
+static const struct aspeed_mbox_model ast2500_model = {
+	.dr_num = 16,
+	.dr	= 0x0,
+	.str = 0x40,
+	.bcr = 0x48,
+	.hcr = 0x4c,
+	.bie = 0x50,
+	.hie = 0x58,
+};
+
+static const struct aspeed_mbox_model ast2600_model = {
+	.dr_num = 32,
+	.dr	= 0x0,
+	.str = 0x80,
+	.bcr = 0x90,
+	.hcr = 0x94,
+	.bie = 0xa0,
+	.hie = 0xb0,
+};
+
+static const struct of_device_id aspeed_mbox_match[] = {
+	{ .compatible = "aspeed,ast2400-mbox",
+	  .data = &ast2400_model },
+	{ .compatible = "aspeed,ast2500-mbox",
+	  .data = &ast2500_model },
+	{ .compatible = "aspeed,ast2600-mbox",
+	  .data = &ast2600_model },
+	{ },
+};
+
+static struct platform_driver aspeed_mbox_driver = {
+	.driver = {
+		.name		= DEVICE_NAME,
+		.of_match_table = aspeed_mbox_match,
+	},
+	.probe = aspeed_mbox_probe,
+	.remove = aspeed_mbox_remove,
+};
+
+module_platform_driver(aspeed_mbox_driver);
+MODULE_DEVICE_TABLE(of, aspeed_mbox_match);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cyril Bur <cyrilbur at gmail.com>");
+MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang at aspeedtech.com");
+MODULE_DESCRIPTION("Aspeed mailbox device driver");
-- 
2.17.1



From hongbo.wang at nxp.com  Mon Aug 16 19:59:07 2021
From: hongbo.wang at nxp.com (Hongbo Wang)
Date: Tue, 17 Aug 2021 02:59:07 +0000
Subject: [EXT] Re: [PATCH v1] arm64: dts: fsl: ls1028a-rdb: Add dts file
 to choose swp5 as dsa master
In-Reply-To: <20210816174803.k53gqgw45hda7zh2@skbuf>
References: <20210813030155.23097-1-hongbo.wang@nxp.com>
 <YRZvItRlSpF2Xf+S@lunn.ch>
 <VI1PR04MB56773CC01AB86A8AA1A33F9AE1FA9@VI1PR04MB5677.eurprd04.prod.outlook.com>
 <20210813140745.fwjkmixzgvikvffz@skbuf>
 <VI1PR04MB56777E60653203A471B9864EE1FD9@VI1PR04MB5677.eurprd04.prod.outlook.com>
 <20210816174803.k53gqgw45hda7zh2@skbuf>
Message-ID: <VI1PR04MB5677BA91547DC2228F615CEFE1FE9@VI1PR04MB5677.eurprd04.prod.outlook.com>


> On Mon, Aug 16, 2021 at 06:03:52AM +0000, Hongbo Wang wrote:
> > > I was going to suggest as an alternative to define a device tree
> > > overlay file with the changes in the CPU port assignment, instead of
> > > defining a wholly new DTS for the LS1028A reference design board.
> > > But I am pretty sure that it is not possible to specify a
> > > /delete-property/ inside a device tree overlay file, so that won't actually
> work.
> >
> > hi Vladimir,
> >
> >   if don't specify "/delete-property/" in this dts file, the
> > corresponding dtb will not work well, so I add it to delete 'ethernet' property
> from mscc_felix_port4 explicitly.
> 
> Judging by the reply, I am not actually sure you've understood what has been
> said.
> 
> I said:
> 
> There is an option to create a device tree overlay:
> 
> https://www.kernel.org/doc/html/latest/devicetree/overlay-notes.html
> 
> We use these for the riser cards on the LS1028A-QDS boards.
> 
> https://source.codeaurora.org/external/qoriq/qoriq-components/linux/tree/ar
> ch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts?h=LSDK-20.12-V5.4
> 
> They are included as usual in a U-Boot ITB file:
> 
> / {
> 	images {
> 		/* Base DTB */
> 		ls1028aqds-dtb {
> 			description = "ls1028aqds-dtb";
> 			data =
> /incbin/("arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dtb");
> 			type = "flat_dt";
> 			arch = "arm64";
> 			os = "linux";
> 			compression = "none";
> 			load = <0x90000000>;
> 			hash at 1 {
> 				algo = "crc32";
> 			};
> 		};
> 		/* Overlay */
> 		fdt at ls1028aqds-13bb {
> 			description = "ls1028aqds-13bb";
> 			data =
> /incbin/("arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dtb");
> 			type = "flat_dt";
> 			arch = "arm64";
> 			load = <0x90010000>;
> 		};
> 	};
> };
> 
> In U-Boot, you apply the overlay as following:
> 
> tftp $kernel_addr_r boot.itb && bootm
> $kernel_addr_r#ls1028aqds#ls1028aqds-13bb
> 
> It would have been nice to have a similar device tree overlay that changes the
> DSA master from eno2 to eno3, and for that overlay to be able to be applied
> (or not) from U-Boot.
> 
> But it's _not_ possible, because you cannot put the /delete-property/ (that you
> need to have) in the .dtbo file. Or if you put it, it will not delete the property
> from the base dtb.
> 
> That's all I said.

thanks for the detailed explanation,
I have got your point.

thanks,
hongbo



From max.chou at realtek.com  Mon Aug 16 20:03:12 2021
From: max.chou at realtek.com (max.chou at realtek.com)
Date: Tue, 17 Aug 2021 11:03:12 +0800
Subject: [PATCH v3] Bluetooth: btusb: Remove WAKEUP_DISABLE and add
 WAKEUP_AUTOSUSPEND for Realtek devices
Message-ID: <20210817030312.27755-1-max.chou@realtek.com>

From: Max Chou <max.chou at realtek.com>

For the commit of 9e45524a011107a73bc2cdde8370c61e82e93a4d, wakeup is
always disabled for Realtek devices. However, there's the capability
for Realtek devices to apply USB wakeup.

In this commit, remove WAKEUP_DISABLE feature for Realtek devices.
If users would switch wakeup, they should access
"/sys/bus/usb/.../power/wakeup"

In this commit, it also adds the feature as WAKEUP_AUTOSUSPEND
for Realtek devices because it should set do_remote_wakeup on autosuspend.

Signed-off-by: Max Chou <max.chou at realtek.com>
Tested-by: Hilda Wu <hildawu at realtek.com>
Reviewed-by: Archie Pusaka <apusaka at chromium.org>
Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit at chromium.org>
---
Changes in v2:
-fix the compiling error due to the incorrect patch file submited

Changes in v3:
-do rebase and make the patch on the latest revision
---
 drivers/bluetooth/btusb.c | 28 +++++++++-------------------
 1 file changed, 9 insertions(+), 19 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 2336f731dbc7..60d2fce59a71 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -527,7 +527,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
 #define BTUSB_OOB_WAKE_ENABLED	11
 #define BTUSB_HW_RESET_ACTIVE	12
 #define BTUSB_TX_WAIT_VND_EVT	13
-#define BTUSB_WAKEUP_DISABLE	14
+#define BTUSB_WAKEUP_AUTOSUSPEND	14
 #define BTUSB_USE_ALT3_FOR_WBS	15
 
 struct btusb_data {
@@ -1350,13 +1350,6 @@ static int btusb_open(struct hci_dev *hdev)
 
 	data->intf->needs_remote_wakeup = 1;
 
-	/* Disable device remote wakeup when host is suspended
-	 * For Realtek chips, global suspend without
-	 * SET_FEATURE (DEVICE_REMOTE_WAKEUP) can save more power in device.
-	 */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
-		device_wakeup_disable(&data->udev->dev);
-
 	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
 		goto done;
 
@@ -1423,7 +1416,7 @@ static int btusb_close(struct hci_dev *hdev)
 	data->intf->needs_remote_wakeup = 0;
 
 	/* Enable remote wake up for auto-suspend */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
+	if (test_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags))
 		data->intf->needs_remote_wakeup = 1;
 
 	usb_autopm_put_interface(data->intf);
@@ -3602,9 +3595,6 @@ static bool btusb_prevent_wake(struct hci_dev *hdev)
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
 
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags))
-		return true;
-
 	return !device_may_wakeup(&data->udev->dev);
 }
 
@@ -3882,11 +3872,8 @@ static int btusb_probe(struct usb_interface *intf,
 		hdev->shutdown = btrtl_shutdown_realtek;
 		hdev->cmd_timeout = btusb_rtl_cmd_timeout;
 
-		/* Realtek devices lose their updated firmware over global
-		 * suspend that means host doesn't send SET_FEATURE
-		 * (DEVICE_REMOTE_WAKEUP)
-		 */
-		set_bit(BTUSB_WAKEUP_DISABLE, &data->flags);
+		/* Realtek devices need to set remote wakeup on auto-suspend */
+		set_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags);
 		set_bit(BTUSB_USE_ALT3_FOR_WBS, &data->flags);
 	}
 
@@ -4062,12 +4049,15 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
 	 * Actually, it depends on whether the usb host sends
 	 * set feature (enable wakeup) or not.
 	 */
-	if (test_bit(BTUSB_WAKEUP_DISABLE, &data->flags)) {
+	if (test_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags)) {
 		if (PMSG_IS_AUTO(message) &&
 		    device_can_wakeup(&data->udev->dev))
 			data->udev->do_remote_wakeup = 1;
-		else if (!PMSG_IS_AUTO(message))
+		else if (!PMSG_IS_AUTO(message) &&
+			 !device_may_wakeup(&data->udev->dev)) {
+			data->udev->do_remote_wakeup = 0;
 			data->udev->reset_resume = 1;
+		}
 	}
 
 	return 0;
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Mon Aug 16 19:37:13 2021
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Tue, 17 Aug 2021 02:37:13 +0000
Subject: [PATCH 1/2] soc: aspeed: Add LPC mailbox support
In-Reply-To: <202108160813.GOZ1P4Y8-lkp@intel.com>
References: <20210813054758.13189-2-chiawei_wang@aspeedtech.com>
 <202108160813.GOZ1P4Y8-lkp@intel.com>
Message-ID: <HK0PR06MB3779008AC59C277899C95D1291FE9@HK0PR06MB3779.apcprd06.prod.outlook.com>

Hi Dan,

> -----Original Message-----
> From: Dan Carpenter <dan.carpenter at oracle.com>
> Sent: Monday, August 16, 2021 5:41 PM
> 
> Hi Chia-Wei,
> 
> url:
> https://github.com/0day-ci/linux/commits/Chia-Wei-Wang/aspeed-Add-LPC-m
> ailbox-support/20210813-134908
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/joel/aspeed.git
> for-next
> config: openrisc-randconfig-m031-20210816 (attached as .config)
> compiler: or1k-linux-gcc (GCC) 11.2.0
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp at intel.com>
> Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
> 
> smatch warnings:
> drivers/soc/aspeed/aspeed-lpc-mbox.c:230 aspeed_mbox_ioctl() warn: maybe
> return -EFAULT instead of the bytes remaining?
> 
> vim +230 drivers/soc/aspeed/aspeed-lpc-mbox.c
> 
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  214  static long
> aspeed_mbox_ioctl(struct file *file, unsigned int cmd,
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  215
> unsigned long param)
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  216  {
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  217  	struct aspeed_mbox
> *mbox = file_mbox(file);
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  218  	const struct
> aspeed_mbox_model *model = mbox->model;
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  219  	struct
> aspeed_mbox_ioctl_data data;
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  220  	long ret;
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  221
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  222  	switch (cmd) {
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  223  	case
> ASPEED_MBOX_IOCTL_GET_SIZE:
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  224  		data.data =
> model->dr_num;
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  225  		ret =
> copy_to_user((void __user *)param, &data, sizeof(data));
> 
> This should be:
> 
> 	if (copy_to_user((void __user *)param, &data, sizeof(data)))
> 		return -EFAULT;

Will be fixed in v2 patch. Thanks for the review.

Regards,
Chiawei

> 
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  226  		break;
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  227  	default:
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  228  		ret = -ENOTTY;
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  229  	}
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13 @230  	return ret;
> 72c5a69dc779f5 Chia-Wei Wang 2021-08-13  231  }
> 
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org



From yunfei.dong at mediatek.com  Mon Aug 16 20:38:58 2021
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Tue, 17 Aug 2021 11:38:58 +0800
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <1628702693.304754.3975941.nullmailer@robh.at.kernel.org>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
 <1628702693.304754.3975941.nullmailer@robh.at.kernel.org>
Message-ID: <2f680f94ef4d41f7a916ba0c920ec1c9121fe583.camel@mediatek.com>

Hi Rob,

Thanks for your detail suggestion.

For the header file(dt-bindings/clock/mt8192-clk.h) is included in:
https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175

Need to depend on this patch, do you have any suggestion about how to
add it?

Thanks.

On Wed, 2021-08-11 at 11:24 -0600, Rob Herring wrote:
> On Wed, 11 Aug 2021 10:57:59 +0800, Yunfei Dong wrote:
> > Adds decoder dt-bindings for mt8192.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> > ---
> > v5: no changes
> > 
> > This patch depends on "Mediatek MT8192 clock support"[1].
> > 
> > The definition of decoder clocks are in mt8192-clk.h, need to
> > include them in case of build fail [1].
> > 
> > [1]
> > https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> > ---
> >  .../media/mediatek,vcodec-comp-decoder.yaml   | 172
> > ++++++++++++++++++
> >  1 file changed, 172 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > decoder.yaml
> > 
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m
> dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> ./Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> decoder.yaml: $id: relative path/filename doesn't match actual path
> or filename
> 	expected: 
> http://devicetree.org/schemas/media/mediatek,vcodec-comp-decoder.yaml#
> Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> decoder.example.dts:22:18: fatal error: dt-bindings/clock/mt8192-
> clk.h: No such file or directory
>    22 |         #include <dt-bindings/clock/mt8192-clk.h>
>       |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> compilation terminated.
> make[1]: *** [scripts/Makefile.lib:380:
> Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> decoder.example.dt.yaml] Error 1
> make[1]: *** Waiting for unfinished jobs....
> make: *** [Makefile:1419: dt_binding_check] Error 2
> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/patch/1515556
> 
> This check can fail if there are any dependencies. The base for a
> patch
> series is generally the most recent rc1.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up
> to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 

From viresh.kumar at linaro.org  Mon Aug 16 20:42:06 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 17 Aug 2021 09:12:06 +0530
Subject: [PATCH v13 2/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW
In-Reply-To: <1629118594.3246.13.camel@mtkswgap22>
References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com>
 <1627574891-26514-3-git-send-email-hector.yuan@mediatek.com>
 <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7>
 <1629118594.3246.13.camel@mtkswgap22>
Message-ID: <20210817034206.hmpjdz4bqvwxfn3c@vireshk-i7>

On 16-08-21, 20:56, Hector Yuan wrote:
> On Tue, 2021-08-03 at 12:43 +0530, Viresh Kumar wrote:
> > On 30-07-21, 00:08, Hector Yuan wrote:
> > > +	for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
> > > +		c->reg_bases[i] = base + offsets[i];
> > > +
> > > +	ret = of_perf_domain_get_sharing_cpumask(index, "performance-domains",
> > 
> > Instead of parsing parsing "performance-domains" twice, I would rather
> > pass a CPU number here instead of index.
> > 
> Sorry, could you give me more details? For now, will use index to parse
> per-cpu to related cpus.You mean pass policy->cpu or? Thanks.

Yes, pass the cpu number from policy->cpu instead.

> > > +	latency = readl_relaxed(c->reg_bases[REG_FREQ_LATENCY]);
> > > +	if (!latency)
> > > +		latency = CPUFREQ_ETERNAL;
> > > +
> > > +	/* us convert to ns */
> > > +	policy->cpuinfo.transition_latency = latency * 1000;
> > 
> > You want to multiple CPUFREQ_ETERNAL too ?

s/multiple/multiply/

Sorry about this.

> Yes, may be different power domain with different transition latency.
> > > +
> > > +	policy->fast_switch_possible = true;
> > > +
> > > +	qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL);
> > 
> > This is a small structure, why not allocate it on stack instead ?
> > 
> For qos part, we'd like to take more time to re-consider the SW flow and
> put this to another patch set.Is this okay to you?

So you will drop entire qos stuff ? Fine by me.

-- 
viresh


From yunfei.dong at mediatek.com  Mon Aug 16 20:50:52 2021
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Tue, 17 Aug 2021 11:50:52 +0800
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
 <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>
Message-ID: <952c219de7595f7f814d3006fbe25b8089a35212.camel@mediatek.com>

Hi Laurent,

Thanks for your detail suggestion.

On Wed, 2021-08-11 at 20:59 +0300, Laurent Pinchart wrote:
> Hi Yunfei,
> 
> Thank you for the patch.
> 
> On Wed, Aug 11, 2021 at 10:57:59AM +0800, Yunfei Dong wrote:
> > Adds decoder dt-bindings for mt8192.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> > ---
> > v5: no changes
> > 
> > This patch depends on "Mediatek MT8192 clock support"[1].
> > 
> > The definition of decoder clocks are in mt8192-clk.h, need to
> > include them in case of build fail [1].
> > 
> > [1]
> > https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> > ---
> >  .../media/mediatek,vcodec-comp-decoder.yaml   | 172
> > ++++++++++++++++++
> >  1 file changed, 172 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > decoder.yaml
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > decoder.yaml
> > b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > decoder.yaml
> > new file mode 100644
> > index 000000000000..083c89933917
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > decoder.yaml
> > @@ -0,0 +1,172 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: 
> > http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Mediatek Video Decode Accelerator With Component
> > +
> > +maintainers:
> > +  - Yunfei Dong <yunfei.dong at mediatek.com>
> > +
> > +description: |+
> > +  Mediatek Video Decode is the video decode hardware present in
> > Mediatek
> > +  SoCs which supports high resolution decoding functionalities.
> > Required
> > +  master and component node.
> 
> This should explain how the three IP cores relate to each other.
> 
I will explain it in next patch.
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - enum:
> > +          - mediatek,mt8192-vcodec-dec  # for lat hardware
> > +          - mediatek,mtk-vcodec-lat     # for core hardware
> > +          - mediatek,mtk-vcodec-core
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 5
> > +
> > +  clock-names:
> > +    items:
> > +      - const: vdec-sel
> > +      - const: vdec-soc-vdec
> > +      - const: vdec-soc-lat
> > +      - const: vdec-vdec
> > +      - const: vdec-top
> > +
> > +  assigned-clocks: true
> > +
> > +  assigned-clock-parents: true
> > +
> > +  power-domains:
> > +    maxItems: 1
> > +
> > +  iommus:
> > +    minItems: 1
> > +    maxItems: 32
> > +    description: |
> > +      List of the hardware port in respective IOMMU block for
> > current Socs.
> > +      Refer to bindings/iommu/mediatek,iommu.yaml.
> > +
> > +  dma-ranges:
> > +    maxItems: 1
> > +    description: |
> > +      Describes the physical address space of IOMMU maps to
> > memory.
> > +
> > +  mediatek,scp:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    maxItems: 1
> > +    description:
> > +      Describes point to scp.
> > +
> > +required:
> > +      - compatible
> > +      - reg
> > +      - iommus
> > +      - dma-ranges
> > +
> > +allOf:
> > +  - if: #master node
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - mediatek,mt8192-vcodec-dec  # for lat hardware
> > +
> > +    then:
> > +      required:
> > +        - mediatek,scp
> > +
> > +  - if: #component node
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - mediatek,mtk-vcodec-lat     # for core hardware
> > +              - mediatek,mtk-vcodec-core
> > +
> > +    then:
> > +      required:
> > +        - interrupts
> > +        - clocks
> > +        - clock-names
> > +        - assigned-clocks
> > +        - assigned-clock-parents
> > +        - power-domains
> > +
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/memory/mt8192-larb-port.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/clock/mt8192-clk.h>
> > +    #include <dt-bindings/power/mt8192-power.h>
> > +
> > +    vcodec_dec: vcodec_dec at 16000000 {
> > +        compatible = "mediatek,mt8192-vcodec-dec";
> > +        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
> > +        mediatek,scp = <&scp>;
> > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
> > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > +    };
> > +
> > +    vcodec_lat: vcodec_lat at 0x16010000 {
> > +        compatible = "mediatek,mtk-vcodec-lat";
> > +        reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
> > +        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
> > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > +             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
> > +             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
> > +             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
> > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> > +              "vdec-vdec", "vdec-top";
> > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
> > +    };
> > +
> > +    vcodec_core: vcodec_core at 0x16025000 {
> > +        compatible = "mediatek,mtk-vcodec-core";
> > +        reg = <0 0x16025000 0 0x1000>;		/*
> > VDEC_CORE_MISC */
> > +        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
> > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > +             <&vdecsys CLK_VDEC_VDEC>,
> > +             <&vdecsys CLK_VDEC_LAT>,
> > +             <&vdecsys CLK_VDEC_LARB1>,
> > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> > +              "vdec-vdec", "vdec-top";
> > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
> > +    };
> 
> I'm a bit late in the game, reviewing v5 only, but I'm wondering if
> those IP cores need to be modelled in separate nodes. It would be
> much
> easier, from a software point of view, to have a single node, with
> multiple register ranges.
> 
> Are some of those IP cores used in different SoCs, combined in
> different
> ways, that make a modular design better ?
> 
Different platform has different hardware, for mt8192 only has three
nodes. but mt8195 will has five nodes. and the clk/power/irq/iommu are
different. It is not easy to manage all hardware at the same time in
one node, need to enable different hardware at the same time, the logic
will be very complex.
It is much easier to handle different hardware using component, enable
different hardware when we need it.



From linux.amoon at gmail.com  Mon Aug 16 21:15:34 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:34 +0530
Subject: [PATCHv3 0/6] Meson-8b and Meson-gxbb Fix some missing code
Message-ID: <20210817041548.1276-1-linux.amoon@gmail.com>

On Odroid C1+ and Odroid C2 USB feature is broken

It's being observed the after initiation of USB phy
the USB port goes in to suspend state, If we pass usbcore.autosuspend=-1
via command line USB hotplug seen to be working.

Another issue I observed is increase of USB interrupts event
even if there is not much activity on USB ports.

$ cat /proc/interrupts | grep usb
 35:   26462800          0          0          0     GIC-0  63 Level
			c90c0000.usb, dwc2_hsotg:usb1
8
Changes added power node to usb phy and small code cleanup
in usb phy.


Previous version RFC.
[0] https://patchwork.kernel.org/project/linux-amlogic/cover/20210617194154.2397-1-linux.amoon at gmail.com/
Dopped the reorder of code changes as of now.

V1 > changes Fixed the GPIO input signal on Odroid C1+/C2
     New patch added to fix Odroid C2.

[1] https://lore.kernel.org/linux-devicetree/20210716103651.1455-1-linux.amoon at gmail.com/

V2 > changes Fixed the GPIO polarity for Odroid C1
     fix the power source from phy-supply to vbus-supply 
     added new patches to fix resolve some issues.

Thanks
-Anand

Anand Moon (6):
  ARM: dts: meson8b: odroidc1: Add usb phy power node
  ARM: dts: meson8b: odroidc1: Set usb power source to always on
  arm64: dts: amlogic: odroidc2: Fix the chip enable signal for usb
    power
  arm64: dts: amlogic: odroidc2: use vbus-supply for power source for
    usb nodes
  phy: amlogic: meson8b-usb2: Power off the PHY by putting it into reset
    mode
  phy: amlogic: meson8b-usb2: don't log an error on -EPROBE_DEFER

 arch/arm/boot/dts/meson8b-odroidc1.dts        | 21 ++++++++++++++++++-
 .../boot/dts/amlogic/meson-gxbb-odroidc2.dts  | 10 ++++-----
 drivers/phy/amlogic/phy-meson8b-usb2.c        |  8 +++++--
 3 files changed, 30 insertions(+), 9 deletions(-)

-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:35 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:35 +0530
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-2-linux.amoon@gmail.com>

Add missing usb phy power node for usb node fix below warning.
P5V0 regulator supply input voltage range to USB host controller.
As described in the C1+ schematics, GPIO GPIOAO_5 is used to
enable input power to USB ports, set it to Active Low.

[    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
[    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
		mode /soc/usb at c90c0000 failed

Fixes: 2eb79a4d15ff (ARM: dts: meson: enabling the USB Host
		controller on Odroid-C1/C1+ board)

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
V2 > changes gpio polarity ACTIVE_HIGH to ACTIVE_LOW.
     Fix the source power from phy-supply to vbus-supply.

[1] https://lore.kernel.org/linux-devicetree/20210716103651.1455-2-linux.amoon at gmail.com/

V1 > Fix the Input GPIO polarity from HIGH to LOW.

previous version
[0] https://patchwork.kernel.org/project/linux-amlogic/patch/20190113181808.5768-1-linux.amoon at gmail.com

changes fix the vbus-suppy to phy-supply, drop enable usb0

    USB_PWR                       2    1      0 unknown  5000mV     0mA  5000mV  5000mV
       phy-c1108820.phy.0-phy     2                                 0mA     0mV     0mV
---
 arch/arm/boot/dts/meson8b-odroidc1.dts | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts
index c440ef94e082..30ec6a7f20c7 100644
--- a/arch/arm/boot/dts/meson8b-odroidc1.dts
+++ b/arch/arm/boot/dts/meson8b-odroidc1.dts
@@ -32,6 +32,23 @@ emmc_pwrseq: emmc-pwrseq {
 		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
 	};
 
+	usb_pwr_en: regulator-usb-pwr-en {
+		compatible = "regulator-fixed";
+
+		regulator-name = "USB_OTG_PWR";
+
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		/*
+		 * signal name from schematics: USB_POWER - P5V0
+		 */
+		vin-supply = <&p5v0>;
+		/*
+		 * signal name from schematics: PWREN - GPIOAO.BIT5
+		 */
+		gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_LOW>;
+	};
+
 	leds {
 		compatible = "gpio-leds";
 		blue {
@@ -119,7 +136,6 @@ vcc_3v3: regulator-vcc-3v3 {
 		regulator-name = "VCC3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
-
 		vin-supply = <&p5v0>;
 	};
 
@@ -382,4 +398,5 @@ &usb1_phy {
 
 &usb1 {
 	status = "okay";
+	vbus-supply = <&usb_pwr_en>;
 };
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:36 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:36 +0530
Subject: [PATCHv3 2/6] ARM: dts: meson8b: odroidc1: Set usb power source to
 always on
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-3-linux.amoon@gmail.com>

Set P5V0 and vcc_3v3 power source to USB to always on
so that regulator should not enter in suspend state.

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
New patch in this series.
---
 arch/arm/boot/dts/meson8b-odroidc1.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts
index 30ec6a7f20c7..5e5953152452 100644
--- a/arch/arm/boot/dts/meson8b-odroidc1.dts
+++ b/arch/arm/boot/dts/meson8b-odroidc1.dts
@@ -65,6 +65,7 @@ p5v0: regulator-p5v0 {
 		regulator-name = "P5V0";
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
 	};
 
 	tflash_vdd: regulator-tflash_vdd {
@@ -136,6 +137,7 @@ vcc_3v3: regulator-vcc-3v3 {
 		regulator-name = "VCC3V3";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
 		vin-supply = <&p5v0>;
 	};
 
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:37 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:37 +0530
Subject: [PATCHv3 3/6] arm64: dts: amlogic: odroidc2: Fix the chip enable
 signal for usb power
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-4-linux.amoon@gmail.com>

Fix the chip enable signal changing from Active High to Active Low
to enable input power to USB power. Also updated signal name as per
the schematics.

Fixes: 5a0803bd5ae2 ("ARM64: dts: meson-gxbb-odroidc2: Enable USB Nodes")

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
v2:
Fix the typo: shematics -> schematics
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index 201596247fd9..3f4f16a5dedd 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -38,12 +38,11 @@ usb_otg_pwr: regulator-usb-pwrs {
 		regulator-max-microvolt = <5000000>;
 
 		/*
-		 * signal name from schematics: PWREN
+		 * signal name from schematics: PWREN - GPIOAO.BIT5
 		 */
-		gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
+		gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_LOW>;
 		/*
-		 * signal name from schematics: USB_POWER
+		 * signal name from schematics: USB_POWER - P5V0
 		 */
 		vin-supply = <&p5v0>;
 	};
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:38 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:38 +0530
Subject: [PATCHv3 4/6] arm64: dts: amlogic: odroidc2: use vbus-supply for
 power source for usb nodes
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-5-linux.amoon@gmail.com>

Use vbus-supply instead of phy-supply as power source for dwc2
nodes. Drop vbus-supply for usb0 node, as it will handle later.

Fixes: e841ec956e53 ("ARM64: dts: meson-gxbb-odroidc2:
       fix usb1 power supply")

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
New patch in this series.
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index 3f4f16a5dedd..01bbfc4c091e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -400,12 +400,10 @@ &uart_AO {
 
 &usb0_phy {
 	status = "disabled";
-	phy-supply = <&usb_otg_pwr>;
 };
 
 &usb1_phy {
 	status = "okay";
-	phy-supply = <&usb_otg_pwr>;
 };
 
 &usb0 {
@@ -414,4 +412,5 @@ &usb0 {
 
 &usb1 {
 	status = "okay";
+	vbus-supply = <&usb_otg_pwr>;
 };
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:39 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:39 +0530
Subject: [PATCHv3 5/6] phy: amlogic: meson8b-usb2: Power off the PHY by
 putting it into reset mode
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-6-linux.amoon@gmail.com>

Power off the PHY by putting it into reset mode.

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
v2 - None
---
 drivers/phy/amlogic/phy-meson8b-usb2.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
index 03c061dd5f0d..2aad45c55494 100644
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
@@ -219,6 +219,10 @@ static int phy_meson8b_usb2_power_off(struct phy *phy)
 	clk_disable_unprepare(priv->clk_usb);
 	clk_disable_unprepare(priv->clk_usb_general);
 
+	/* power off the PHY by putting it into reset mode */
+	regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET,
+			   REG_CTRL_POWER_ON_RESET);
+
 	return 0;
 }
 
-- 
2.32.0



From linux.amoon at gmail.com  Mon Aug 16 21:15:40 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 17 Aug 2021 09:45:40 +0530
Subject: [PATCHv3 6/6] phy: amlogic: meson8b-usb2: don't log an error on
 -EPROBE_DEFER
In-Reply-To: <20210817041548.1276-1-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
Message-ID: <20210817041548.1276-7-linux.amoon@gmail.com>

devm_phy_create can return -EPROBE_DEFER if the vbus-supply is not ready
yet. Silence this warning as the driver framework will re-attempt
registering the PHY. Use dev_err_probe() for phy resources to indicate
the deferral reason when waiting for the resource to come up.

Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
None.
---
 drivers/phy/amlogic/phy-meson8b-usb2.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/amlogic/phy-meson8b-usb2.c b/drivers/phy/amlogic/phy-meson8b-usb2.c
index 2aad45c55494..cf10bed40528 100644
--- a/drivers/phy/amlogic/phy-meson8b-usb2.c
+++ b/drivers/phy/amlogic/phy-meson8b-usb2.c
@@ -277,8 +277,8 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
 
 	phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops);
 	if (IS_ERR(phy)) {
-		dev_err(&pdev->dev, "failed to create PHY\n");
-		return PTR_ERR(phy);
+		return dev_err_probe(&pdev->dev, PTR_ERR(phy),
+				     "failed to create PHY\n");
 	}
 
 	phy_set_drvdata(phy, priv);
-- 
2.32.0



From pawell at cadence.com  Mon Aug 16 22:05:26 2021
From: pawell at cadence.com (Pawel Laszczak)
Date: Tue, 17 Aug 2021 05:05:26 +0000
Subject: [PATCH 3/6] usb: cdnsp: fix the wrong mult value for HS isoc or
 intr
In-Reply-To: <87mtpnyx3g.fsf@kernel.org>
References: <1628739182-30089-1-git-send-email-chunfeng.yun@mediatek.com>
 <1628739182-30089-3-git-send-email-chunfeng.yun@mediatek.com>
 <87mtpnyx3g.fsf@kernel.org>
Message-ID: <BYAPR07MB53815317736C694887D51BE8DDFE9@BYAPR07MB5381.namprd07.prod.outlook.com>

>
>Chunfeng Yun <chunfeng.yun at mediatek.com> writes:
>
>> usb_endpoint_maxp() only returns the bit[10:0] of wMaxPacketSize
>> of endpoint descriptor, not include bit[12:11] anymore, so use
>> usb_endpoint_maxp_mult() instead.
>>
>> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
>> ---
>>  drivers/usb/cdns3/cdnsp-mem.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c
>> index a47948a1623f..ad9aee3f1e39 100644
>> --- a/drivers/usb/cdns3/cdnsp-mem.c
>> +++ b/drivers/usb/cdns3/cdnsp-mem.c
>> @@ -882,7 +882,7 @@ static u32 cdnsp_get_endpoint_max_burst(struct usb_gadget *g,
>>  	if (g->speed == USB_SPEED_HIGH &&
>>  	    (usb_endpoint_xfer_isoc(pep->endpoint.desc) ||
>>  	     usb_endpoint_xfer_int(pep->endpoint.desc)))
>> -		return (usb_endpoint_maxp(pep->endpoint.desc) & 0x1800) >> 11;
>> +		return usb_endpoint_maxp_mult(pep->endpoint.desc) - 1;
>
>this looks like a bugfix. Do we need to Cc stable here?
>
>In any case:
>
>Acked-by: Felipe Balbi <balbi at kernel.org>
>

It's not a bugfix. The result is the same.

Acked-by: Pawel Laszczak <pawell at cadence.com>

--

Thanks 
Pawel Laszczak


From ck.hu at mediatek.com  Mon Aug 16 22:36:45 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Tue, 17 Aug 2021 13:36:45 +0800
Subject: [RFC PATCH 5/5] drm/mediatek: Add mt8195 DisplayPort driver
In-Reply-To: <20210816192523.1739365-6-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-6-msp@baylibre.com>
Message-ID: <1629178605.7579.3.camel@mtksdaap41>

Hi, Markus:

On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports both functional units on the mt8195, the embedded
> DisplayPort as well as the external DisplayPort units. It offers
> hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> to 4 lanes.
> 
> This driver is based on an initial version by
> Jason-JH.Lin <jason-jh.lin at mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---

[snip]

> +
> +static const struct of_device_id mtk_dp_of_match[] = {
> +	{
> +		.compatible = "mediatek,mt8195-dp_tx",

Where is the binding document of "mediatek,mt8195-dp_tx"?

> +		.data = &mt8195_dp_driver_data,
> +	},
> +	{
> +		.compatible = "mediatek,mt8195-edp_tx",

Where is the binding document of "mediatek,mt8195-edp_tx"?

> +		.data = &mt8195_edp_driver_data,
> +	},
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
> +
> +struct platform_driver mtk_dp_driver = {
> +	.probe = mtk_dp_probe,
> +	.remove = mtk_dp_remove,
> +	.driver = {
> +		.name = "mediatek-drm-dp",
> +		.of_match_table = mtk_dp_of_match,
> +		.pm = &mtk_dp_pm_ops,
> +	},
> +};
> +
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp_reg.h b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> new file mode 100644
> index 000000000000..83afc79d98ff
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> @@ -0,0 +1,3095 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019 MediaTek Inc.
> + * Copyright (c) 2021 BayLibre
> + */
> +#ifndef _MTK_DP_REG_H_
> +#define _MTK_DP_REG_H_
> +
> +#define MTK_DP_SIP_CONTROL_AARCH32 0x82000523
> +# define MTK_DP_SIP_ATF_VIDEO_UNMUTE 0x20
> +# define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE 0x21
> +# define MTK_DP_SIP_ATF_REG_WRITE 0x22
> +# define MTK_DP_SIP_ATF_REG_READ 0x23
> +# define MTK_DP_SIP_ATF_CMD_COUNT 0x24
> +
> +#define TOP_OFFSET		0x2000
> +#define ENC0_OFFSET		0x3000
> +#define ENC1_OFFSET		0x3200
> +#define TRANS_OFFSET		0x3400
> +#define AUX_OFFSET		0x3600
> +#define SEC_OFFSET		0x4000
> +
> +#define MTK_DP_HPD_DISCONNECT	BIT(1)
> +#define MTK_DP_HPD_CONNECT	BIT(2)
> +#define MTK_DP_HPD_INTERRUPT	BIT(3)
> +
> +#define MTK_DP_ENC0_P0_3000              (ENC0_OFFSET + 0x000)
> +# define LANE_NUM_DP_ENC0_P0_MASK                                      0x3
> +# define LANE_NUM_DP_ENC0_P0_SHIFT                                     0
> +# define VIDEO_MUTE_SW_DP_ENC0_P0_MASK                                 0x4
> +# define VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT                                2
> +# define VIDEO_MUTE_SEL_DP_ENC0_P0_MASK                                0x8
> +# define VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT                               3
> +# define ENHANCED_FRAME_EN_DP_ENC0_P0_MASK                             0x10
> +# define ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT                            4
> +# define HDCP_FRAME_EN_DP_ENC0_P0_MASK                                 0x20
> +# define HDCP_FRAME_EN_DP_ENC0_P0_SHIFT                                5
> +# define IDP_EN_DP_ENC0_P0_MASK                                        0x40

Remove useless definition.

Regards,
CK.

> +# define IDP_EN_DP_ENC0_P0_SHIFT                                       6
> +# define BS_SYMBOL_CNT_RESET_DP_ENC0_P0_MASK                           0x80
> +# define BS_SYMBOL_CNT_RESET_DP_ENC0_P0_SHIFT                          7
> +# define MIXER_DUMMY_DATA_DP_ENC0_P0_MASK                              0xff00
> +# define MIXER_DUMMY_DATA_DP_ENC0_P0_SHIFT                             8
> +

> +
> +#endif /*_MTK_DP_REG_H_*/


From wenst at chromium.org  Mon Aug 16 22:44:13 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 17 Aug 2021 13:44:13 +0800
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <a7c8ab68ac3513865698cde27e665bdd554f459e.camel@mediatek.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
 <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
 <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>
 <CACRpkdbZKh8cqqiDRUik6Ooo33e+feGwYsLjcLRvBQnT3x5M3A@mail.gmail.com>
 <a7c8ab68ac3513865698cde27e665bdd554f459e.camel@mediatek.com>
Message-ID: <CAGXv+5FtL2zaSWx4tUymx6mpCSb5dXG4XNWM9AJL+b6Ok3dxMg@mail.gmail.com>

On Tue, Aug 17, 2021 at 10:21 AM zhiyong.tao <zhiyong.tao at mediatek.com> wrote:
>
> On Tue, 2021-08-17 at 01:00 +0200, Linus Walleij wrote:
> > On Mon, Aug 16, 2021 at 5:38 PM Chen-Yu Tsai <wenst at chromium.org>
> > wrote:
> > > On Mon, Aug 16, 2021 at 6:48 PM zhiyong.tao <
> > > zhiyong.tao at mediatek.com> wrote:
> > > > > I'll take that as "use SI units whenever possible and
> > > > > reasonable".
> > > >
> > > > ==> so It doesn't need to change the define, is it right?
> > > > we will keep the common define.
> > >
> > > Actually I think it would be possible and reasonable to use SI
> > > units
> > > in this case, since you are the vendor and have the resistor values
> > > to implement the support. Having different sets of values for
> > > different
> > > chips is nothing out of the ordinary. We already have to account
> > > for
> > > different number of pins and different pin functions. That is what
> > > compatible strings are for.
> >
> > I fully agree with Chen-Yu's analysis here.
> >
> > Zhiyong can you make an attempt to use SI units (Ohms) and see
> > what it will look like? I think it will look better for users and it
> > will
> > be less risk to make mistakes.
> >
> > Yours,
> > Linus Walleij
>
> Hi Linus & chen-yu,
>
> The rsel actual bias resistance of each setting is different in
> different IC. For example, in mt8195, the rsel actual bias resistance
> setting like as:
> MTK_PULL_SET_RSEL_000:75K in PU, 75k in PD;
> MTK_PULL_SET
> _RSEL_001:10k in PU, 5k in PD;
> MTK_PULL_SET_RSEL_010:5k in PU, 75k in
> PD;
> MTK_PULL_SET_RSEL_011:4k in PU, 5K in PD;
> MTK_PULL_SET_RSEL_100:3k in
> PU, 75k in PD;
> MTK_PULL_SET_RSEL_101:2k in PU, 5K in PD;
> MTK_PULL_SET_RSE
> L_110:1.5k in PU, 75k in PD;
> MTK_PULL_SET_RSEL_111:1k in PU, 5k in PD.
>
> but in mt8192, the rsel actual bias resistance setting like as:
> MTK_PULL_SET_RSEL_000:75K in PU, 75k in PD;
> MTK_PULL_SET_RSEL_001:3k in PU, 5k in PD;
> MTK_PULL_SET_RSEL_010:10k in PU, 75k in PD;
> MTK_PULL_SET_RSEL_011:1k in PU, 5K in PD;
>
> Can you help me to provide a suggestion common define for the all
> different IC?
> It seems that we should add a new define, if we upstream a new IC
> pinctrl driver in the future.

I assume you mean the macros used in the device tree?

The point of using SI units is to get rid of the macros. Instead of:

    bias-pull-up = <MTK_PULL_SET_RSEL_000>;

and

    bias-pull-down = <MTK_PULL_SET_RSEL_011>;

We want:

    bias-pull-up = <75000>;

and

    bias-pull-down = <5000>;

And the pinctrl driver then converts the real values in the device tree
into register values using some lookup table.

The DT schema could then enumerate all the valid resistor values,
and get proper validity checking.

Now if you really wanted to keep some symbols for mapping hardware
register values to resistor values, you could have

    #define MT8192_PULL_UP_RSEL_001      75000
    #define MT8192_PULL_DOWN_RSEL_001     5000

or have them all named MTK_PULL_{UP,DOWN}_RSEL_NNN, but split into
different header files, one per SoC.

Personally I think having the macros is a bad idea if proper values
are available. It just adds another layer of indirection, and another
area where errors can creep in.


Regards
ChenYu


From haibo.chen at nxp.com  Mon Aug 16 23:41:39 2021
From: haibo.chen at nxp.com (Bough Chen)
Date: Tue, 17 Aug 2021 06:41:39 +0000
Subject: [PATCH 3/6] dt-bindings: mmc: fsl-imx-esdhc: add
 fsl,sdio-async-interrupt-enabled binding
In-Reply-To: <CAPDyKFqagBkbnxxh+KWbV2=sjkj3mGrKXUweOL5TrMJ1-Hmnww@mail.gmail.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <1629117508-4886-3-git-send-email-haibo.chen@nxp.com>
 <CAPDyKFqagBkbnxxh+KWbV2=sjkj3mGrKXUweOL5TrMJ1-Hmnww@mail.gmail.com>
Message-ID: <VI1PR04MB529432136DB9F5FEB5F5E98090FE9@VI1PR04MB5294.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> Sent: 2021?8?16? 21:43
> To: Bough Chen <haibo.chen at nxp.com>
> Cc: Adrian Hunter <adrian.hunter at intel.com>; Shawn Guo
> <shawnguo at kernel.org>; Rob Herring <robh+dt at kernel.org>; Sascha Hauer
> <s.hauer at pengutronix.de>; Sascha Hauer <kernel at pengutronix.de>; Fabio
> Estevam <festevam at gmail.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> dl-linux-imx <linux-imx at nxp.com>; DTML <devicetree at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>
> Subject: Re: [PATCH 3/6] dt-bindings: mmc: fsl-imx-esdhc: add
> fsl,sdio-async-interrupt-enabled binding
> 
> On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
> >
> > From: Haibo Chen <haibo.chen at nxp.com>
> >
> > Add a new fsl,sdio-async-interrupt-enabled binding for sdio devices
> > which enable the async interrupt function. When get this property,
> > driver will avoid to use DAT[1] for hardware auto tuning check.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> > ---
> >  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml         | 10
> ++++++++++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > index b5baf439fbac..8a9f1775b0e2 100644
> > --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > @@ -122,6 +122,16 @@ properties:
> >        - const: state_200mhz
> >        - const: sleep
> >
> > +  fsl,sdio-async-interrupt-enabled:
> > +    description: |
> > +      Recommend for SDIO cards that enables SDIO async interrupt for
> SDR104 and SDR50
> > +      operating modes. SDIO async interrupt uses DAT[1] to signal the
> card's interrupt.
> > +      uSDHC tuning mechanism must use DAT[0] and CMD signals to avoid
> a possible
> > +      conflict and incorrect delay line calculated by the uSDHC auto tuning
> mechanism.
> > +      Enabling this device tree property is only recommended for layouts
> that are
> > +      matching the SD interface length.
> > +    type: boolean
> 
> We already have a common mmc property, "cap-sdio-irq", that tells whether
> the controller supports SDIO irqs (which is delivered on DAT1).
> 
> Can't you use this instead?
> 
Hi Ulf,

Thanks for your quick reply!

According to our WiFi team reply, the sdio-irq has two types. Sync interrupt and Async interrupt.
When WiFi send out the interrupt signal during the interrupt period, if it sync with clock pad(just as
when send out data), then this is sync interrupt. When this interrupt not sync with clock, it is async
interrupt. Async interrupt has a better overall performance than sync interrupt.

Logically, auto tuning circuit should only take care of the data and cmd line, and ignore interrupt signal.
But unfortunately current i.mx-usdhc IP do not ignore interrupt signal. So it detect the interrupt signal,
and take this signal as a data signal, and adjust the delay cell accordingly. For sync interrupt, due to it
sync with clock, so no affect, but for async interrupt, it will involve wrong delay cell change randomly.

I involve a new property here, because in sdhci.c, we default use this "cap-sdio-irq" for all sdio/sd/mmc.
I need one property which can use only for sdio device, and only when sdio device enable async-interrupt.

Best Regards
Haibo Chen

> > +
> >  required:
> >    - compatible
> >    - reg
> > --
> > 2.17.1
> >
> 
> Kind regards
> Uffe

From haibo.chen at nxp.com  Mon Aug 16 23:57:56 2021
From: haibo.chen at nxp.com (Bough Chen)
Date: Tue, 17 Aug 2021 06:57:56 +0000
Subject: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the auto-tuning
 setting for sdio device
In-Reply-To: <CAPDyKFpqTdKxFytQWo+TLJf+D=JYJo6B2aZDqOQc4+9_mbH40Q@mail.gmail.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <1629117508-4886-4-git-send-email-haibo.chen@nxp.com>
 <CAPDyKFpqTdKxFytQWo+TLJf+D=JYJo6B2aZDqOQc4+9_mbH40Q@mail.gmail.com>
Message-ID: <VI1PR04MB52948F36F428AA3476A1F9D590FE9@VI1PR04MB5294.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> Sent: 2021?8?16? 21:53
> To: Bough Chen <haibo.chen at nxp.com>
> Cc: Adrian Hunter <adrian.hunter at intel.com>; Shawn Guo
> <shawnguo at kernel.org>; Rob Herring <robh+dt at kernel.org>; Sascha Hauer
> <s.hauer at pengutronix.de>; Sascha Hauer <kernel at pengutronix.de>; Fabio
> Estevam <festevam at gmail.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> dl-linux-imx <linux-imx at nxp.com>; DTML <devicetree at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>
> Subject: Re: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the auto-tuning
> setting for sdio device
> 
> On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
> >
> > From: Haibo Chen <haibo.chen at nxp.com>
> >
> > USDHC contain auto tuning circuit, this circuit will work
> > automatically after the tuning procedurae, it can increase/decrease
> > the delay cell according to the outside environment change (like
> temperature).
> >
> > Unfortunately, this auto tuning circuit can not handle the async sdio
> > device interrupt correctly. When sdio device use 4 data line, async
> > sdio interrupt will use DAT[1], if we enable auto tuning circuit check
> > 4 data lines, include the DAT[1], this circuit will detect this
> > interrupt, take this as a data on DAT[1], and adjust the delay cell wrongly.
> >
> > This is the hardware design limitation, to avoid this, when sdio
> > device enable async interrupt, auto tuning circuit only check DAT[0] and CMD
> lines.
> 
> SDIO irqs are being enabled/disabled dynamically in runtime by the mmc core
> via the host ops ->enable_sdio_irq().
> 
> Rather than forcing the autotuning circuit to stay unused statically, perhaps an
> option would be to disable it when the SDIO irqs becomes enabled? Or maybe
> that becomes too complicated?

For interrupt in 4-bit mode, there is a definition of interrupt period, only in this period can the interrupt be
detect and recognize. The interrupt period can exist during data transfer.

So to fix this issue, one method is to disable auto tuning circuit. Another is my current method, just detect CMD
and DAT0, but at least auto tuning still can work (this method need board design keep align all data lines).
 

Best Regards
Haibo chen

> 
> >
> > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> > ---
> >  drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++++
> >  1 file changed, 18 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > index f18d169bc8ff..ab84c29777e5 100644
> > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > @@ -226,6 +226,7 @@ struct esdhc_platform_data {
> >         unsigned int tuning_step;       /* The delay cell steps in tuning
> procedure */
> >         unsigned int tuning_start_tap;  /* The start delay cell point in
> tuning procedure */
> >         unsigned int strobe_dll_delay_target;   /* The delay cell for
> strobe pad (read clock) */
> > +       bool sdio_async_interrupt_enabled;      /* sdio device enable
> the async interrupt */
> >  };
> >
> >  struct esdhc_soc_data {
> > @@ -416,6 +417,8 @@ static inline void
> > esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
> >  /* Enable the auto tuning circuit to check the CMD line and BUS line
> > */  static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host
> > *host)  {
> > +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > +       struct pltfm_imx_data *imx_data =
> > + sdhci_pltfm_priv(pltfm_host);
> >         u32 buswidth, auto_tune_buswidth;
> >
> >         buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr +
> > SDHCI_HOST_CONTROL)); @@ -432,6 +435,18 @@ static inline void
> usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
> >                 break;
> >         }
> >
> > +       /*
> > +        * If sdio device use async interrupt, it will use DAT[1] to signal
> > +        * the device's interrupt asynchronous when use 4 data lines.
> > +        * Then hardware auto tuning circuit MUST NOT check the DAT[1]
> line,
> > +        * otherwise auto tuning will be impacted by this async interrupt,
> > +        * and change the delay cell incorrectly, which then cause
> data/cmd
> > +        * errors.
> > +        * This is the hardware auto tuning circuit limitation.
> > +        */
> > +       if (imx_data->boarddata.sdio_async_interrupt_enabled)
> > +               auto_tune_buswidth =
> > + ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;
> > +
> >         esdhc_clrset_le(host,
> ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
> >                         auto_tune_buswidth |
> ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
> >                         ESDHC_VEND_SPEC2); @@ -1531,6 +1546,9
> @@
> > sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
> >         if (of_property_read_u32(np, "fsl,delay-line",
> &boarddata->delay_line))
> >                 boarddata->delay_line = 0;
> >
> > +       if (of_property_read_bool(np,
> > + "fsl,sdio-async-interrupt-enabled"))
> 
> As stated on the DT patch, I think you can use the "cap-sdio-irq" instead.
> 
> > +               boarddata->sdio_async_interrupt_enabled = true;
> > +
> >         mmc_of_parse_voltage(host->mmc, &host->ocr_mask);
> >
> >         if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) {
> > --
> > 2.17.1
> >
> 
> Kind regards
> Uffe

From krzysztof.kozlowski at canonical.com  Tue Aug 17 00:09:13 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 17 Aug 2021 09:09:13 +0200
Subject: [GIT PULL] pinctrl: samsung: pull for v5.15
Message-ID: <20210817070913.6387-1-krzysztof.kozlowski@canonical.com>

Hi Linus,

Just few commits for v5.15.

Best regards,
Krzysztof


The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git tags/samsung-pinctrl-5.15

for you to fetch changes up to cdd3d945dcec0d0dab845175dc9400ab54512aa6:

  pinctrl: samsung: Add Exynos850 SoC specific data (2021-08-13 09:39:42 +0200)

----------------------------------------------------------------
Samsung pinctrl drivers changes for v5.15

1. Fix number of pins in one GPIO pin bank.
2. Add support for Exynos850 SoC (Exynos3830).

----------------------------------------------------------------
Jaehyoung Choi (1):
      pinctrl: samsung: Fix pinctrl bank pin count

Sam Protsenko (2):
      dt-bindings: pinctrl: samsung: Add Exynos850 doc
      pinctrl: samsung: Add Exynos850 SoC specific data

 .../bindings/pinctrl/samsung-pinctrl.txt           |   1 +
 drivers/pinctrl/samsung/pinctrl-exynos-arm64.c     | 116 +++++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-exynos.h           |  29 ++++++
 drivers/pinctrl/samsung/pinctrl-samsung.c          |   4 +-
 drivers/pinctrl/samsung/pinctrl-samsung.h          |   1 +
 5 files changed, 150 insertions(+), 1 deletion(-)


From maxime at cerno.tech  Tue Aug 17 00:12:20 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Tue, 17 Aug 2021 09:12:20 +0200
Subject: [PATCH v6 1/2] ASoC: sunxi: Add Allwinner H6 Digital MIC driver
In-Reply-To: <CAE=m61_=XfhtG9Q1r34McWWCUXt1KP67cjZ0ER62+YaGrG+b4w@mail.gmail.com>
References: <20210711122055.4529-1-fengzheng923@gmail.com>
 <20210715074750.ewbggulc5kast6ez@gilmour>
 <CAE=m61_=XfhtG9Q1r34McWWCUXt1KP67cjZ0ER62+YaGrG+b4w@mail.gmail.com>
Message-ID: <20210817071220.idoxpwzbpemdjqdz@gilmour>

Hi,

On Sun, Aug 01, 2021 at 05:47:46PM +0800, ?? wrote:
> > > +     /* DMIC num is N+1 */
> > > +     regmap_update_bits(host->regmap, SUN50I_DMIC_CH_NUM,
> > > +                        SUN50I_DMIC_CH_NUM_N_MASK,
> > > +                        SUN50I_DMIC_CH_NUM_N(channels - 1));
> > > +     host->chan_en = (1 << channels) - 1;
> > > +     regmap_write(host->regmap, SUN50I_DMIC_HPF_CTRL, host->chan_en);
> >
> > Do we need to store the channels bitmask in the main structure? It looks
> > fairly easy to generate, so I guess we could just use a macro
> 
> I need to store channels bitmask and use it in sun50i_dmic_trigger function.

But you don't need it outside of hw_params. The channel setup is
typically done in hw_params, not in the trigger hook.

[...]

> > > +     /* Clocks */
> > > +     host->bus_clk = devm_clk_get(&pdev->dev, "bus");
> > > +     if (IS_ERR(host->bus_clk))
> > > +             return dev_err_probe(&pdev->dev, PTR_ERR(host->bus_clk),
> > > +                                  "failed to get bus clock.\n");
> > > +
> > > +     host->dmic_clk = devm_clk_get(&pdev->dev, "mod");
> > > +     if (IS_ERR(host->dmic_clk))
> > > +             return dev_err_probe(&pdev->dev, PTR_ERR(host->dmic_clk),
> > > +                                  "failed to get dmic clock.\n");
> > > +
> > > +     host->dma_params_rx.addr = res->start + SUN50I_DMIC_DATA;
> > > +     host->dma_params_rx.maxburst = 8;
> > > +
> > > +     platform_set_drvdata(pdev, host);
> > > +
> > > +     host->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
> > > +     if (IS_ERR(host->rst))
> > > +             return dev_err_probe(&pdev->dev, PTR_ERR(host->rst),
> > > +                                  "Failed to get reset.\n");
> >
> > Your binding states that the reset is mandatory so you don't need the
> > optional variant.
> >
> > > +     reset_control_deassert(host->rst);
> >
> > Can't this be moved to the runtime_pm hooks?
> 
> Is this necessary? I see that most of the driver files execute
> reset_control_deassert in the probe function, and reset_control_assert
> in the remove function.

Your driver seems to not rely on the fact that the device remains
powered between each run anyway, so yeah, that way you will completely
power it down.

> >
> > > +     ret = devm_snd_soc_register_component(&pdev->dev,
> > > +                             &sun50i_dmic_component, &sun50i_dmic_dai, 1);
> >
> > Your second line should be aligned on the opening parenthesis
> >
> > > +     if (ret)
> > > +             return dev_err_probe(&pdev->dev, ret,
> > > +                                  "failed to register component.\n");
> > > +
> > > +     pm_runtime_enable(&pdev->dev);
> > > +     if (!pm_runtime_enabled(&pdev->dev)) {
> > > +             ret = sun50i_dmic_runtime_resume(&pdev->dev);
> > > +             if (ret)
> > > +                     goto err_unregister;
> > > +     }
> >
> > We have a depends on PM on some drivers already, so I guess it would
> > just make sense to add one more here instead of dealing with whether
> > runtime_pm is compiled in or not.
> 
> I don't understand. I am referring to the sun4i-spdif.c file. Which
> driver files should I refer to?

That whole logic is there to enable the device is CONFIG_PM is not
enabled (and thus the calls to pm_runtime_* won't do anything).

Just add a depends on PM to your Kconfig entry, and call
pm_runtime_enable there.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/c4a01e05/attachment.sig>

From lee.jones at linaro.org  Tue Aug 17 00:24:03 2021
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 17 Aug 2021 08:24:03 +0100
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build
 as a module
In-Reply-To: <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>
References: <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <YQuZ2cKVE+3Os25Z@google.com> <YRpeVLf18Z+1R7WE@google.com>
 <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>
Message-ID: <YRtkE62O+4EiyzF9@google.com>

On Mon, 16 Aug 2021, Saravana Kannan wrote:
> > > > I sent out the proper fix as a series:
> > > > https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
> > > >
> > > > Marc, can you give it a shot please?
> > > >
> > > > -Saravana
> > >
> > > Superstar!  Thanks for taking the time to rectify this for all of us.
> >
> > Just to clarify:
> >
> >   Are we waiting on a subsequent patch submission at this point?
> 
> Not that I'm aware of. Andrew added a "Reviewed-by" to all 3 of my
> proper fix patches. I didn't think I needed to send any newer patches.
> Is there some reason you that I needed to?

Actually, I meant *this* patch.

But happy to have unlocked your patches also. :)

-- 
Lee Jones [???]
Senior Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From rocco.yue at mediatek.com  Tue Aug 17 00:26:09 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Tue, 17 Aug 2021 15:26:09 +0800
Subject: [PATCH net-next v4] ipv6: add IFLA_INET6_RA_MTU to expose mtu value
 in the RA message
Message-ID: <20210817072609.2110-1-rocco.yue@mediatek.com>

The kernel provides a "/proc/sys/net/ipv6/conf/<iface>/mtu"
file, which can temporarily record the mtu value of the last
received RA message when the RA mtu value is lower than the
interface mtu, but this proc has following limitations:

(1) when the interface mtu (/sys/class/net/<iface>/mtu) is
updeated, mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) will
be updated to the value of interface mtu;
(2) mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) only affect
ipv6 connection, and not affect ipv4.

Therefore, when the mtu option is carried in the RA message,
there will be a problem that the user sometimes cannot obtain
RA mtu value correctly by reading mtu6.

After this patch set, if a RA message carries the mtu option,
you can send a netlink msg which nlmsg_type is RTM_GETLINK,
and then by parsing the attribute of IFLA_INET6_RA_MTU to
get the mtu value carried in the RA message received on the
inet6 device. In addition, you can also get a link notification
when ra_mtu is updated so it doesn't have to poll.

In this way, if the MTU values that the device receives from
the network in the PCO IPv4 and the RA IPv6 procedures are
different, the user can obtain the correct ipv6 ra_mtu value
and compare the value of ra_mtu and ipv4 mtu, then the device
can use the lower MTU value for both IPv4 and IPv6.

Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
---
 include/net/if_inet6.h             |  2 ++
 include/uapi/linux/if_link.h       |  1 +
 net/ipv6/addrconf.c                |  8 ++++++++
 net/ipv6/ndisc.c                   | 17 +++++++++++------
 tools/include/uapi/linux/if_link.h |  1 +
 5 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 42235c178b06..653e7d0f65cb 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -210,6 +210,8 @@ struct inet6_dev {
 
 	unsigned long		tstamp; /* ipv6InterfaceTable update timestamp */
 	struct rcu_head		rcu;
+
+	unsigned int		ra_mtu;
 };
 
 static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 5310003523ce..957ec9873e70 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -417,6 +417,7 @@ enum {
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
 	IFLA_INET6_TOKEN,	/* device token			*/
 	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	IFLA_INET6_RA_MTU,	/* mtu carried in the RA message */
 	__IFLA_INET6_MAX
 };
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8381288a0d6e..3eb957777b31 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -394,6 +394,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
 		ndev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
 
 	ndev->cnf.mtu6 = dev->mtu;
+	ndev->ra_mtu = U32_MIN;
 	ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
 	if (!ndev->nd_parms) {
 		kfree(ndev);
@@ -5543,6 +5544,7 @@ static inline size_t inet6_ifla6_size(void)
 	     + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
 	     + nla_total_size(sizeof(struct in6_addr)) /* IFLA_INET6_TOKEN */
 	     + nla_total_size(1) /* IFLA_INET6_ADDR_GEN_MODE */
+	     + nla_total_size(4) /* IFLA_INET6_RA_MTU */
 	     + 0;
 }
 
@@ -5651,6 +5653,9 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
 	if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
 		goto nla_put_failure;
 
+	if (nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))
+		goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
@@ -5767,6 +5772,9 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token,
 static const struct nla_policy inet6_af_policy[IFLA_INET6_MAX + 1] = {
 	[IFLA_INET6_ADDR_GEN_MODE]	= { .type = NLA_U8 },
 	[IFLA_INET6_TOKEN]		= { .len = sizeof(struct in6_addr) },
+	[IFLA_INET6_RA_MTU]		= { .type = NLA_REJECT,
+					    .reject_message =
+						"IFLA_INET6_RA_MTU can't be set" },
 };
 
 static int check_addr_gen_mode(int mode)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c467c6419893..23e690769857 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1391,12 +1391,6 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		}
 	}
 
-	/*
-	 *	Send a notify if RA changed managed/otherconf flags or timer settings
-	 */
-	if (send_ifinfo_notify)
-		inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
-
 skip_linkparms:
 
 	/*
@@ -1496,6 +1490,11 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
 		mtu = ntohl(n);
 
+		if (in6_dev->ra_mtu != mtu) {
+			in6_dev->ra_mtu = mtu;
+			send_ifinfo_notify = true;
+		}
+
 		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
 			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
 		} else if (in6_dev->cnf.mtu6 != mtu) {
@@ -1519,6 +1518,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		ND_PRINTK(2, warn, "RA: invalid RA options\n");
 	}
 out:
+	/* Send a notify if RA changed managed/otherconf flags or timer
+	 * settings or ra_mtu value
+	 */
+	if (send_ifinfo_notify)
+		inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
+
 	fib6_info_release(rt);
 	if (neigh)
 		neigh_release(neigh);
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index eb15f319aa57..b3610fdd1fee 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -230,6 +230,7 @@ enum {
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
 	IFLA_INET6_TOKEN,	/* device token			*/
 	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	IFLA_INET6_RA_MTU,	/* mtu carried in the RA message */
 	__IFLA_INET6_MAX
 };
 
-- 
2.18.0

From maxime at cerno.tech  Tue Aug 17 00:30:30 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Tue, 17 Aug 2021 09:30:30 +0200
Subject: [PATCH v8 00/11] arm64: sunxi: Initial Allwinner H616 SoC support
In-Reply-To: <20210802013851.13375f0f@slackpad.fritz.box>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210726145230.uevhinsrvo7gtuty@gilmour>
 <20210802013851.13375f0f@slackpad.fritz.box>
Message-ID: <20210817073030.jcvpfipsikllursv@gilmour>

Hi Andre,

On Mon, Aug 02, 2021 at 01:38:51AM +0100, Andre Przywara wrote:
> On Mon, 26 Jul 2021 16:52:30 +0200
> Maxime Ripard <maxime at cerno.tech> wrote:
> > On Fri, Jul 23, 2021 at 04:38:27PM +0100, Andre Przywara wrote:
> > > Hi,
> > > 
> > > another try on the basic Allwinner H616 support, now on top of 5.14-rc1.
> > > 
> > > This time I dropped the USB support from the basic series, to split off
> > > the discussion, and simplify the core SoC support. I will post the USB
> > > series soon, to be applied on top.
> > > I kept the RTC support in, even though this is still under discussion,
> > > because this is important to keep future DT files compatible with this
> > > kernel.  
> > 
> > Honestly, I don't want to support something we don't guarantee if it's
> > at the expense of making something we do guarantee more complicated.
> 
> I don't ask for or provide guarantees, but I think we can at least *try*
> to keep this compatible. This version works at the moment, and should
> also work with future DTs - within the limits of the current driver, so
> only using the RC clock. It allows to later improve the accuracy by
> adding better input clocks - and later DT/driver combinations can make
> use of this.

Again, at the expense of having to deal with more bindings combinations
in the driver. This driver is already a nightmare to get all the one we
have to support already. You asked to keep the same driver, fair enough,
but then let's do our best to not make the situation worse there.

> > Delaying the clock tree description to sometime in the future will only
> > further complicate the probe part of the driver, and there's far too
> > many special cases already.
> 
> I don't see how this would complicate probing beyond what Allwinner
> brought upon us already anyway: no LOSC crystal input in this package
> version, but having this pin in some other SoC sharing this die
> (according to some BSP) sources. We can't expect a super clean driver
> with those HW design choices.
> 
> If we really cannot keep the DT compatible, fair enough: that's what
> it is (there is no guarantee!), but at least we have tried.

I mean, we didn't really try though? The whole clock tree has basically
a big TODO all over it.

I know that it can be hard to figure out. It's why I suggested to rely
on fixed clock for the moment as placeholders to get the rest of the
series in. But for some reason you don't want to do that either.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/9018f709/attachment.sig>

From msp at baylibre.com  Tue Aug 17 00:31:20 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue, 17 Aug 2021 09:31:20 +0200
Subject: [RFC PATCH 5/5] drm/mediatek: Add mt8195 DisplayPort driver
In-Reply-To: <YRraTWcY4yVuJANQ@ravnborg.org>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-6-msp@baylibre.com>
 <YRraTWcY4yVuJANQ@ravnborg.org>
Message-ID: <20210817073120.fqa2wybvdgbn55a4@blmsp>

Hi Sam,

On Mon, Aug 16, 2021 at 11:36:13PM +0200, Sam Ravnborg wrote:
> Hi Markus,
> 
> A few general things in the following. This is what I look for first in
> a bridge driver - and I had no time today to review the driver in full.
> Please address these, then cc: me on next revision where I hopefully
> have more time.

Thanks for taking the time and giving me the tips, will fix it and send
a new version.

Best,
Markus

> 
> 	Sam
> 
> > +static int mtk_dp_bridge_attach(struct drm_bridge *bridge,
> > +                               enum drm_bridge_attach_flags flags)
> > +{
> > +       struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
> > +       int ret;
> > +
> > +       mtk_dp_poweron(mtk_dp);
> > +
> > +       if (mtk_dp->next_bridge) {
> > +               ret = drm_bridge_attach(bridge->encoder, mtk_dp->next_bridge,
> > +                                       &mtk_dp->bridge, flags);
> > +               if (ret) {
> > +                       drm_warn(mtk_dp->drm_dev,
> > +                                "Failed to attach external bridge: %d\n", ret);
> > +                       return ret;
> > +               }
> > +       }
> > +
> > +       if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
> > +               drm_err(mtk_dp->drm_dev,
> > +                       "Fix bridge driver to make connector optional!");
> > +               return 0;
> > +       }
> 
> This driver is only used by mediatek, and I thought all of mediatek is
> converted so the display driver creates the connector.
> 
> It would be better to migrate mediatek over to always let the display
> driver create the connector and drop the connector support in this
> driver.
> 
> 
> > + struct drm_bridge_funcs mtk_dp_bridge_funcs = {
> > +	.attach = mtk_dp_bridge_attach,
> > +	.mode_fixup = mtk_dp_bridge_mode_fixup,
> > +	.disable = mtk_dp_bridge_disable,
> > +	.post_disable = mtk_dp_bridge_post_disable,
> > +	.mode_set = mtk_dp_bridge_mode_set,
> > +	.pre_enable = mtk_dp_bridge_pre_enable,
> > +	.enable = mtk_dp_bridge_enable,
> > +	.get_edid = mtk_get_edid,
> > +	.detect = mtk_dp_bdg_detect,
> > +};
> 
> 
> For new drivers please avoid the recently deprecated functions.
> 
> - Use the atomic versions of pre_enable, enable, disable and post_disable.
> 
> - Merge mode_set with atomic_enable - as there is no need for the mode_Set
>   operation.
> 
> - Use atomic_check in favour of mode_fixup, albeit the rules for
>   atomic_check is at best vauge at the moment.
>  
> 


From msp at baylibre.com  Tue Aug 17 00:35:30 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Tue, 17 Aug 2021 09:35:30 +0200
Subject: [RFC PATCH 5/5] drm/mediatek: Add mt8195 DisplayPort driver
In-Reply-To: <1629178605.7579.3.camel@mtksdaap41>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-6-msp@baylibre.com>
 <1629178605.7579.3.camel@mtksdaap41>
Message-ID: <20210817073530.uocllhlkyg767uok@blmsp>

Hi,

On Tue, Aug 17, 2021 at 01:36:45PM +0800, CK Hu wrote:
> Hi, Markus:
> 
> On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> > This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> > 
> > It supports both functional units on the mt8195, the embedded
> > DisplayPort as well as the external DisplayPort units. It offers
> > hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> > to 4 lanes.
> > 
> > This driver is based on an initial version by
> > Jason-JH.Lin <jason-jh.lin at mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> > ---
> 
> [snip]
> 
> > +
> > +static const struct of_device_id mtk_dp_of_match[] = {
> > +	{
> > +		.compatible = "mediatek,mt8195-dp_tx",
> 
> Where is the binding document of "mediatek,mt8195-dp_tx"?
> 
> > +		.data = &mt8195_dp_driver_data,
> > +	},
> > +	{
> > +		.compatible = "mediatek,mt8195-edp_tx",
> 
> Where is the binding document of "mediatek,mt8195-edp_tx"?

I didn't include the bindings in this RFC, but will include them in the
next version.

> 
> > +		.data = &mt8195_edp_driver_data,
> > +	},
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
> > +
> > +struct platform_driver mtk_dp_driver = {
> > +	.probe = mtk_dp_probe,
> > +	.remove = mtk_dp_remove,
> > +	.driver = {
> > +		.name = "mediatek-drm-dp",
> > +		.of_match_table = mtk_dp_of_match,
> > +		.pm = &mtk_dp_pm_ops,
> > +	},
> > +};
> > +
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dp_reg.h b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> > new file mode 100644
> > index 000000000000..83afc79d98ff
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
> > @@ -0,0 +1,3095 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2019 MediaTek Inc.
> > + * Copyright (c) 2021 BayLibre
> > + */
> > +#ifndef _MTK_DP_REG_H_
> > +#define _MTK_DP_REG_H_
> > +
> > +#define MTK_DP_SIP_CONTROL_AARCH32 0x82000523
> > +# define MTK_DP_SIP_ATF_VIDEO_UNMUTE 0x20
> > +# define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE 0x21
> > +# define MTK_DP_SIP_ATF_REG_WRITE 0x22
> > +# define MTK_DP_SIP_ATF_REG_READ 0x23
> > +# define MTK_DP_SIP_ATF_CMD_COUNT 0x24
> > +
> > +#define TOP_OFFSET		0x2000
> > +#define ENC0_OFFSET		0x3000
> > +#define ENC1_OFFSET		0x3200
> > +#define TRANS_OFFSET		0x3400
> > +#define AUX_OFFSET		0x3600
> > +#define SEC_OFFSET		0x4000
> > +
> > +#define MTK_DP_HPD_DISCONNECT	BIT(1)
> > +#define MTK_DP_HPD_CONNECT	BIT(2)
> > +#define MTK_DP_HPD_INTERRUPT	BIT(3)
> > +
> > +#define MTK_DP_ENC0_P0_3000              (ENC0_OFFSET + 0x000)
> > +# define LANE_NUM_DP_ENC0_P0_MASK                                      0x3
> > +# define LANE_NUM_DP_ENC0_P0_SHIFT                                     0
> > +# define VIDEO_MUTE_SW_DP_ENC0_P0_MASK                                 0x4
> > +# define VIDEO_MUTE_SW_DP_ENC0_P0_SHIFT                                2
> > +# define VIDEO_MUTE_SEL_DP_ENC0_P0_MASK                                0x8
> > +# define VIDEO_MUTE_SEL_DP_ENC0_P0_SHIFT                               3
> > +# define ENHANCED_FRAME_EN_DP_ENC0_P0_MASK                             0x10
> > +# define ENHANCED_FRAME_EN_DP_ENC0_P0_SHIFT                            4
> > +# define HDCP_FRAME_EN_DP_ENC0_P0_MASK                                 0x20
> > +# define HDCP_FRAME_EN_DP_ENC0_P0_SHIFT                                5
> > +# define IDP_EN_DP_ENC0_P0_MASK                                        0x40
> 
> Remove useless definition.

Ok, will do. Thanks for the feedback.

Best,
Markus

> 
> Regards,
> CK.
> 
> > +# define IDP_EN_DP_ENC0_P0_SHIFT                                       6
> > +# define BS_SYMBOL_CNT_RESET_DP_ENC0_P0_MASK                           0x80
> > +# define BS_SYMBOL_CNT_RESET_DP_ENC0_P0_SHIFT                          7
> > +# define MIXER_DUMMY_DATA_DP_ENC0_P0_MASK                              0xff00
> > +# define MIXER_DUMMY_DATA_DP_ENC0_P0_SHIFT                             8
> > +
> 
> > +
> > +#endif /*_MTK_DP_REG_H_*/
> 


From ulf.hansson at linaro.org  Tue Aug 17 00:37:00 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 17 Aug 2021 09:37:00 +0200
Subject: [PATCH 3/6] dt-bindings: mmc: fsl-imx-esdhc: add
 fsl,sdio-async-interrupt-enabled binding
In-Reply-To: <VI1PR04MB529432136DB9F5FEB5F5E98090FE9@VI1PR04MB5294.eurprd04.prod.outlook.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <1629117508-4886-3-git-send-email-haibo.chen@nxp.com>
 <CAPDyKFqagBkbnxxh+KWbV2=sjkj3mGrKXUweOL5TrMJ1-Hmnww@mail.gmail.com>
 <VI1PR04MB529432136DB9F5FEB5F5E98090FE9@VI1PR04MB5294.eurprd04.prod.outlook.com>
Message-ID: <CAPDyKFqv9R4R8u9vQLkDMFQy3C-+=B-_g4drktq9ncHhzX3pSw@mail.gmail.com>

On Tue, 17 Aug 2021 at 08:41, Bough Chen <haibo.chen at nxp.com> wrote:
>
> > -----Original Message-----
> > From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> > Sent: 2021?8?16? 21:43
> > To: Bough Chen <haibo.chen at nxp.com>
> > Cc: Adrian Hunter <adrian.hunter at intel.com>; Shawn Guo
> > <shawnguo at kernel.org>; Rob Herring <robh+dt at kernel.org>; Sascha Hauer
> > <s.hauer at pengutronix.de>; Sascha Hauer <kernel at pengutronix.de>; Fabio
> > Estevam <festevam at gmail.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> > dl-linux-imx <linux-imx at nxp.com>; DTML <devicetree at vger.kernel.org>; Linux
> > ARM <linux-arm-kernel at lists.infradead.org>
> > Subject: Re: [PATCH 3/6] dt-bindings: mmc: fsl-imx-esdhc: add
> > fsl,sdio-async-interrupt-enabled binding
> >
> > On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
> > >
> > > From: Haibo Chen <haibo.chen at nxp.com>
> > >
> > > Add a new fsl,sdio-async-interrupt-enabled binding for sdio devices
> > > which enable the async interrupt function. When get this property,
> > > driver will avoid to use DAT[1] for hardware auto tuning check.
> > >
> > > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> > > ---
> > >  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml         | 10
> > ++++++++++
> > >  1 file changed, 10 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > > b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > > index b5baf439fbac..8a9f1775b0e2 100644
> > > --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > > +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > > @@ -122,6 +122,16 @@ properties:
> > >        - const: state_200mhz
> > >        - const: sleep
> > >
> > > +  fsl,sdio-async-interrupt-enabled:
> > > +    description: |
> > > +      Recommend for SDIO cards that enables SDIO async interrupt for
> > SDR104 and SDR50
> > > +      operating modes. SDIO async interrupt uses DAT[1] to signal the
> > card's interrupt.
> > > +      uSDHC tuning mechanism must use DAT[0] and CMD signals to avoid
> > a possible
> > > +      conflict and incorrect delay line calculated by the uSDHC auto tuning
> > mechanism.
> > > +      Enabling this device tree property is only recommended for layouts
> > that are
> > > +      matching the SD interface length.
> > > +    type: boolean
> >
> > We already have a common mmc property, "cap-sdio-irq", that tells whether
> > the controller supports SDIO irqs (which is delivered on DAT1).
> >
> > Can't you use this instead?
> >
> Hi Ulf,
>
> Thanks for your quick reply!
>
> According to our WiFi team reply, the sdio-irq has two types. Sync interrupt and Async interrupt.
> When WiFi send out the interrupt signal during the interrupt period, if it sync with clock pad(just as
> when send out data), then this is sync interrupt. When this interrupt not sync with clock, it is async
> interrupt. Async interrupt has a better overall performance than sync interrupt.

The async interrupt is what we refer to as SDIO irqs, which is being
delivered on DAT1.

>
> Logically, auto tuning circuit should only take care of the data and cmd line, and ignore interrupt signal.
> But unfortunately current i.mx-usdhc IP do not ignore interrupt signal. So it detect the interrupt signal,
> and take this signal as a data signal, and adjust the delay cell accordingly. For sync interrupt, due to it
> sync with clock, so no affect, but for async interrupt, it will involve wrong delay cell change randomly.

Okay.

>
> I involve a new property here, because in sdhci.c, we default use this "cap-sdio-irq" for all sdio/sd/mmc.

I guess it's the similar variant of the controller for all slots then.

It can be debated whether the proper thing is to set "cap-sdio-irq"
only for the SDIO card slot. I think so, (and it's already being used
like that) if there is an embedded SDIO card attached, because
cap-sdio-irq would not make sense otherwise.

> I need one property which can use only for sdio device, and only when sdio device enable async-interrupt.

If you really need a new DT property (let's discuss that more in patch
4/6), I suggest you add something along the lines of a
"broken-auto-tuning" DT property instead, because that is in principle
what this should be about, isn't it?

Kind regards
Uffe


From maxime at cerno.tech  Tue Aug 17 00:38:10 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Tue, 17 Aug 2021 09:38:10 +0200
Subject: [PATCH v8 02/11] dt-bindings: rtc: sun6i: Add H616 compatible
 string
In-Reply-To: <20210802013938.29fa18ed@slackpad.fritz.box>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210723153838.6785-3-andre.przywara@arm.com>
 <20210726144137.6dauuxdssu7yszox@gilmour>
 <20210802013938.29fa18ed@slackpad.fritz.box>
Message-ID: <20210817073810.7stuzrppyjf4spab@gilmour>

Hi,

On Mon, Aug 02, 2021 at 01:39:38AM +0100, Andre Przywara wrote:
> On Mon, 26 Jul 2021 16:41:37 +0200
> Maxime Ripard <maxime at cerno.tech> wrote:
> 
> > Hi,
> > 
> > On Fri, Jul 23, 2021 at 04:38:29PM +0100, Andre Przywara wrote:
> > > Add the obvious compatible name to the existing RTC binding.
> > > The actual RTC part of the device uses a different day/month/year
> > > storage scheme, so it's not compatible with the previous devices.
> > > Also the clock part is quite different, as there is no external 32K LOSC
> > > oscillator input.
> > > 
> > > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > >
> > > ---
> > >  .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml      | 14 ++++++++++++++
> > >  1 file changed, 14 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > > index beeb90e55727..d8a6500e5840 100644
> > > --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > > +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > > @@ -26,6 +26,7 @@ properties:
> > >            - const: allwinner,sun50i-a64-rtc
> > >            - const: allwinner,sun8i-h3-rtc
> > >        - const: allwinner,sun50i-h6-rtc
> > > +      - const: allwinner,sun50i-h616-rtc
> > >  
> > >    reg:
> > >      maxItems: 1
> > > @@ -104,6 +105,19 @@ allOf:
> > >            minItems: 3
> > >            maxItems: 3
> > >  
> > > +  - if:
> > > +      properties:
> > > +        compatible:
> > > +          contains:
> > > +            const: allwinner,sun50i-h616-rtc
> > > +
> > > +    then:
> > > +      properties:
> > > +        clock-output-names:
> > > +          minItems: 3
> > > +          maxItems: 3  
> > 
> > You don't need both of them when they are equal
> > 
> > > +        clocks: false
> > > +  
> > 
> > It's not entirely clear to me what those clocks are about though. If we
> > look at the clock output in the user manual, it looks like there's only
> > two clocks that are actually being output: the 32k "fanout" clock and
> > the losc. What are the 3 you're talking about?]
> 
> I see three: the raw SYSTEM "CLK32K_LOSC", the RTC input + debounce
> clock (/32), and the multiplexed PAD.

But the input and debounce clock is only for the RTC itself right? So it
should be local to the driver and doesn't need to be made available to
the other drivers

Either way, what this list is must be documented.

> > Also, it looks like the 32k fanout clock needs at least the hosc or
> > pll-periph in input, so we probably don't want to ask for no parent
> > clock?
> 
> Well, we never seem to reference the HOSC this way, this was always
> somewhat explicit. And yes, there is PLL-PERIPH as an input, but we
> don't support this yet. So I went with 0 input clocks *for now*: the
> driver can then ignore all clocks, so any clock referenced in the DT
> later won't cause any harm. This will all be addressed by Samuel's RTC
> clock patch, which will also touch the H6, IIRC. And it looks like we
> will need to touch the binding anyway then, but can then just *extend*
> this.

You mentioned that series several times already and never provided an
explanation for what it was supposed to be doing except fixing
everything. What's the general plan for that series?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/5157d749/attachment.sig>

From sam.shih at mediatek.com  Tue Aug 17 00:45:45 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:45 +0800
Subject: [v2,00/12] Add basic SoC support for mediatek mt7986
Message-ID: <20210817074557.30953-1-sam.shih@mediatek.com>

This patch adds basic SoC support for Mediatek's new 4-core SoC,
MT7986, which is mainly for wifi-router application.

---
v2: updated mt7986 clock releated IDs, dt-binding, and driver
    updated mt7986 clock releated dt-binding and driver
    updated device tree of mt7986a and mt7986b

Sam Shih (12):
  dt-bindings: clock: mediatek: document clk bindings for mediatek
    mt7986 SoC
  clk: mediatek: add mt7986 clock IDs
  clk: mediatek: add mt7986 clock support
  pinctrl: mediatek: moore: check if pin_desc is valid before use
  dt-bindings: pinctrl: update bindings for MT7986 SoC
  pinctrl: mediatek: add support for MT7986 SoC
  dt-bindings: arm64: dts: mediatek: Add mt7986 series
  dt-bindings: rng: mediatek: add mt7986 to mtk rng binding
  dt-bindings: serial: Add compatible for Mediatek MT7986
  dt-bindings: watchdog: Add compatible for Mediatek MT7986
  arm64: dts: mediatek: add mt7986a support
  arm64: dts: mediatek: add mt7986b support

 .../devicetree/bindings/arm/mediatek.yaml     |    8 +
 .../arm/mediatek/mediatek,apmixedsys.txt      |    1 +
 .../bindings/arm/mediatek/mediatek,ethsys.txt |    1 +
 .../arm/mediatek/mediatek,infracfg.txt        |    1 +
 .../arm/mediatek/mediatek,sgmiisys.txt        |    2 +
 .../arm/mediatek/mediatek,topckgen.txt        |    1 +
 .../bindings/pinctrl/pinctrl-mt7622.txt       |  170 +++
 .../devicetree/bindings/rng/mtk-rng.yaml      |    1 +
 .../devicetree/bindings/serial/mtk-uart.txt   |    1 +
 .../devicetree/bindings/watchdog/mtk-wdt.txt  |    1 +
 arch/arm64/boot/dts/mediatek/Makefile         |    2 +
 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts  |   49 +
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi     |  227 +++
 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts  |   21 +
 arch/arm64/boot/dts/mediatek/mt7986b.dtsi     |  236 ++++
 drivers/clk/mediatek/Kconfig                  |   17 +
 drivers/clk/mediatek/Makefile                 |    4 +
 drivers/clk/mediatek/clk-mt7986-apmixed.c     |   78 ++
 drivers/clk/mediatek/clk-mt7986-eth.c         |  132 ++
 drivers/clk/mediatek/clk-mt7986-infracfg.c    |  198 +++
 drivers/clk/mediatek/clk-mt7986-topckgen.c    |  319 +++++
 drivers/pinctrl/mediatek/Kconfig              |    7 +
 drivers/pinctrl/mediatek/Makefile             |    1 +
 drivers/pinctrl/mediatek/pinctrl-moore.c      |   18 +
 drivers/pinctrl/mediatek/pinctrl-mt7986.c     | 1217 +++++++++++++++++
 include/dt-bindings/clock/mt7986-clk.h        |  169 +++
 26 files changed, 2882 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a.dtsi
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986b.dtsi
 create mode 100644 drivers/clk/mediatek/clk-mt7986-apmixed.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-eth.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-infracfg.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-topckgen.c
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c
 create mode 100644 include/dt-bindings/clock/mt7986-clk.h

-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:46 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:46 +0800
Subject: [v2, 01/12] dt-bindings: clock: mediatek: document clk bindings for
 mediatek mt7986 SoC
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-2-sam.shih@mediatek.com>

This patch adds the binding documentation for topckgen, apmixedsys,
infracfg, and ethernet subsystem clocks.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
---
v2: remove compatiable string 'mt7986-sgmiisys'

---
 .../devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt    | 1 +
 .../devicetree/bindings/arm/mediatek/mediatek,ethsys.txt        | 1 +
 .../devicetree/bindings/arm/mediatek/mediatek,infracfg.txt      | 1 +
 .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt      | 2 ++
 .../devicetree/bindings/arm/mediatek/mediatek,topckgen.txt      | 1 +
 5 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
index ea827e8763de..3fa755866528 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -14,6 +14,7 @@ Required Properties:
 	- "mediatek,mt7622-apmixedsys"
 	- "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys"
 	- "mediatek,mt7629-apmixedsys"
+	- "mediatek,mt7986-apmixedsys"
 	- "mediatek,mt8135-apmixedsys"
 	- "mediatek,mt8167-apmixedsys", "syscon"
 	- "mediatek,mt8173-apmixedsys"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
index 6b7e8067e7aa..0502db73686b 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
@@ -10,6 +10,7 @@ Required Properties:
 	- "mediatek,mt7622-ethsys", "syscon"
 	- "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
 	- "mediatek,mt7629-ethsys", "syscon"
+	- "mediatek,mt7986-ethsys", "syscon"
 - #clock-cells: Must be 1
 - #reset-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
index eb3523c7a7be..f66bd720571d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -15,6 +15,7 @@ Required Properties:
 	- "mediatek,mt7622-infracfg", "syscon"
 	- "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon"
 	- "mediatek,mt7629-infracfg", "syscon"
+	- "mediatek,mt7986-infracfg", "syscon"
 	- "mediatek,mt8135-infracfg", "syscon"
 	- "mediatek,mt8167-infracfg", "syscon"
 	- "mediatek,mt8173-infracfg", "syscon"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
index 30cb645c0e54..29ca7a10b315 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
@@ -8,6 +8,8 @@ Required Properties:
 - compatible: Should be:
 	- "mediatek,mt7622-sgmiisys", "syscon"
 	- "mediatek,mt7629-sgmiisys", "syscon"
+	- "mediatek,mt7986-sgmiisys_0", "syscon"
+	- "mediatek,mt7986-sgmiisys_1", "syscon"
 - #clock-cells: Must be 1
 
 The SGMIISYS controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
index 5ce7578cf274..b82422bb717f 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -14,6 +14,7 @@ Required Properties:
 	- "mediatek,mt7622-topckgen"
 	- "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen"
 	- "mediatek,mt7629-topckgen"
+	- "mediatek,mt7986-topckgen", "syscon"
 	- "mediatek,mt8135-topckgen"
 	- "mediatek,mt8167-topckgen", "syscon"
 	- "mediatek,mt8173-topckgen"
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:47 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:47 +0800
Subject: [v2,02/12] clk: mediatek: add mt7986 clock IDs
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-3-sam.shih@mediatek.com>

Add MT7986 clock dt-bindings, include topckgen, apmixedsys,
infracfg, and ethernet subsystem clocks.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
v2: changed to dual licience
    applied the comment suggested by reviewers:
    - removed 1:1 factor clock
    - renamed factor clock for easier to understand

---
 include/dt-bindings/clock/mt7986-clk.h | 169 +++++++++++++++++++++++++
 1 file changed, 169 insertions(+)
 create mode 100644 include/dt-bindings/clock/mt7986-clk.h

diff --git a/include/dt-bindings/clock/mt7986-clk.h b/include/dt-bindings/clock/mt7986-clk.h
new file mode 100644
index 000000000000..4799007c4755
--- /dev/null
+++ b/include/dt-bindings/clock/mt7986-clk.h
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7986_H
+#define _DT_BINDINGS_CLK_MT7986_H
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_ARMPLL		0
+#define CLK_APMIXED_NET2PLL		1
+#define CLK_APMIXED_MMPLL		2
+#define CLK_APMIXED_SGMPLL		3
+#define CLK_APMIXED_WEDMCUPLL		4
+#define CLK_APMIXED_NET1PLL		5
+#define CLK_APMIXED_MPLL		6
+#define CLK_APMIXED_APLL2		7
+
+/* TOPCKGEN */
+
+#define CLK_TOP_XTAL			0
+#define CLK_TOP_XTAL_D2			1
+#define CLK_TOP_RTC_32K			2
+#define CLK_TOP_RTC_32P7K		3
+#define CLK_TOP_MPLL_D2			4
+#define CLK_TOP_MPLL_D4			5
+#define CLK_TOP_MPLL_D8			6
+#define CLK_TOP_MPLL_D8_D2		7
+#define CLK_TOP_MPLL_D3_D2		8
+#define CLK_TOP_MMPLL_D2		9
+#define CLK_TOP_MMPLL_D4		10
+#define CLK_TOP_MMPLL_D8		11
+#define CLK_TOP_MMPLL_D8_D2		12
+#define CLK_TOP_MMPLL_D3_D8		13
+#define CLK_TOP_MMPLL_U2PHY		14
+#define CLK_TOP_APLL2_D4		15
+#define CLK_TOP_NET1PLL_D4		16
+#define CLK_TOP_NET1PLL_D5		17
+#define CLK_TOP_NET1PLL_D5_D2		18
+#define CLK_TOP_NET1PLL_D5_D4		19
+#define CLK_TOP_NET1PLL_D8_D2		20
+#define CLK_TOP_NET1PLL_D8_D4		21
+#define CLK_TOP_NET2PLL_D4		22
+#define CLK_TOP_NET2PLL_D4_D2		23
+#define CLK_TOP_NET2PLL_D3_D2		24
+#define CLK_TOP_WEDMCUPLL_D5_D2		25
+#define CLK_TOP_NFI1X_SEL		26
+#define CLK_TOP_SPINFI_SEL		27
+#define CLK_TOP_SPI_SEL			28
+#define CLK_TOP_SPIM_MST_SEL		29
+#define CLK_TOP_UART_SEL		30
+#define CLK_TOP_PWM_SEL			31
+#define CLK_TOP_I2C_SEL			32
+#define CLK_TOP_PEXTP_TL_SEL		33
+#define CLK_TOP_EMMC_250M_SEL		34
+#define CLK_TOP_EMMC_416M_SEL		35
+#define CLK_TOP_F_26M_ADC_SEL		36
+#define CLK_TOP_DRAMC_SEL		37
+#define CLK_TOP_DRAMC_MD32_SEL		38
+#define CLK_TOP_SYSAXI_SEL		39
+#define CLK_TOP_SYSAPB_SEL		40
+#define CLK_TOP_ARM_DB_MAIN_SEL		41
+#define CLK_TOP_ARM_DB_JTSEL		42
+#define CLK_TOP_NETSYS_SEL		43
+#define CLK_TOP_NETSYS_500M_SEL		44
+#define CLK_TOP_NETSYS_MCU_SEL		45
+#define CLK_TOP_NETSYS_2X_SEL		46
+#define CLK_TOP_SGM_325M_SEL		47
+#define CLK_TOP_SGM_REG_SEL		48
+#define CLK_TOP_A1SYS_SEL		49
+#define CLK_TOP_CONN_MCUSYS_SEL		50
+#define CLK_TOP_EIP_B_SEL		51
+#define CLK_TOP_PCIE_PHY_SEL		52
+#define CLK_TOP_USB3_PHY_SEL		53
+#define CLK_TOP_F26M_SEL		54
+#define CLK_TOP_AUD_L_SEL		55
+#define CLK_TOP_A_TUNER_SEL		56
+#define CLK_TOP_U2U3_SEL		57
+#define CLK_TOP_U2U3_SYS_SEL		58
+#define CLK_TOP_U2U3_XHCI_SEL		59
+#define CLK_TOP_DA_U2_REFSEL		60
+#define CLK_TOP_DA_U2_CK_1P_SEL		61
+#define CLK_TOP_AP2CNN_HOST_SEL		62
+#define CLK_TOP_JTAG			63
+
+/* INFRACFG */
+
+#define CLK_INFRA_SYSAXI_D2		0
+#define CLK_INFRA_UART0_SEL		1
+#define CLK_INFRA_UART1_SEL		2
+#define CLK_INFRA_UART2_SEL		3
+#define CLK_INFRA_SPI0_SEL		4
+#define CLK_INFRA_SPI1_SEL		5
+#define CLK_INFRA_PWM1_SEL		6
+#define CLK_INFRA_PWM2_SEL		7
+#define CLK_INFRA_PWM_BSEL		8
+#define CLK_INFRA_PCIE_SEL		9
+#define CLK_INFRA_GPT_STA		10
+#define CLK_INFRA_PWM_HCK		11
+#define CLK_INFRA_PWM_STA		12
+#define CLK_INFRA_PWM1_CK		13
+#define CLK_INFRA_PWM2_CK		14
+#define CLK_INFRA_CQ_DMA_CK		15
+#define CLK_INFRA_EIP97_CK		16
+#define CLK_INFRA_AUD_BUS_CK		17
+#define CLK_INFRA_AUD_26M_CK		18
+#define CLK_INFRA_AUD_L_CK		19
+#define CLK_INFRA_AUD_AUD_CK		20
+#define CLK_INFRA_AUD_EG2_CK		21
+#define CLK_INFRA_DRAMC_26M_CK		22
+#define CLK_INFRA_DBG_CK		23
+#define CLK_INFRA_AP_DMA_CK		24
+#define CLK_INFRA_SEJ_CK		25
+#define CLK_INFRA_SEJ_13M_CK		26
+#define CLK_INFRA_THERM_CK		27
+#define CLK_INFRA_I2C0_CK		28
+#define CLK_INFRA_UART0_CK		29
+#define CLK_INFRA_UART1_CK		30
+#define CLK_INFRA_UART2_CK		31
+#define CLK_INFRA_NFI1_CK		32
+#define CLK_INFRA_SPINFI1_CK		33
+#define CLK_INFRA_NFI_HCK_CK		34
+#define CLK_INFRA_SPI0_CK		35
+#define CLK_INFRA_SPI1_CK		36
+#define CLK_INFRA_SPI0_HCK_CK		37
+#define CLK_INFRA_SPI1_HCK_CK		38
+#define CLK_INFRA_FRTC_CK		39
+#define CLK_INFRA_MSDC_CK		40
+#define CLK_INFRA_MSDC_HCK_CK		41
+#define CLK_INFRA_MSDC_133M_CK		42
+#define CLK_INFRA_MSDC_66M_CK		43
+#define CLK_INFRA_ADC_26M_CK		44
+#define CLK_INFRA_ADC_FRC_CK		45
+#define CLK_INFRA_FBIST2FPC_CK		46
+#define CLK_INFRA_IUSB_133_CK		47
+#define CLK_INFRA_IUSB_66M_CK		48
+#define CLK_INFRA_IUSB_SYS_CK		49
+#define CLK_INFRA_IUSB_CK		50
+#define CLK_INFRA_IPCIE_CK		51
+#define CLK_INFRA_IPCIE_PIPE_CK		52
+#define CLK_INFRA_IPCIER_CK		53
+#define CLK_INFRA_IPCIEB_CK		54
+#define CLK_INFRA_TRNG_CK		55
+
+/* SGMIISYS_0 */
+
+#define CLK_SGMII0_TX250M_EN		0
+#define CLK_SGMII0_RX250M_EN		1
+#define CLK_SGMII0_CDR_REF		2
+#define CLK_SGMII0_CDR_FB		2
+
+/* SGMIISYS_1 */
+
+#define CLK_SGMII1_TX250M_EN		0
+#define CLK_SGMII1_RX250M_EN		1
+#define CLK_SGMII1_CDR_REF		2
+#define CLK_SGMII1_CDR_FB		2
+
+/* ETHSYS */
+
+#define CLK_ETH_FE_EN			0
+#define CLK_ETH_GP2_EN			1
+#define CLK_ETH_GP1_EN			2
+#define CLK_ETH_WOCPU1_EN		3
+#define CLK_ETH_WOCPU0_EN		4
+
+#endif /* _DT_BINDINGS_CLK_MT7986_H */
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:48 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:48 +0800
Subject: [v2,03/12] clk: mediatek: add mt7986 clock support
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-4-sam.shih@mediatek.com>

Add MT7986 clock support, include topckgen, apmixedsys,
infracfg, and ethernet subsystem clocks.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
---
v2: applied the comment suggested by reviewers:
    - splited basic clock driver to apmixed, topckgen, and infracfg
    - removed 1:1 factor clock
    - renamed factor clock for easier to understand

---
 drivers/clk/mediatek/Kconfig               |  17 ++
 drivers/clk/mediatek/Makefile              |   4 +
 drivers/clk/mediatek/clk-mt7986-apmixed.c  |  78 +++++
 drivers/clk/mediatek/clk-mt7986-eth.c      | 132 +++++++++
 drivers/clk/mediatek/clk-mt7986-infracfg.c | 198 +++++++++++++
 drivers/clk/mediatek/clk-mt7986-topckgen.c | 319 +++++++++++++++++++++
 6 files changed, 748 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt7986-apmixed.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-eth.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-infracfg.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-topckgen.c

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 886e2d9fced5..28d8a07d5139 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -344,6 +344,23 @@ config COMMON_CLK_MT7629_HIFSYS
 	  This driver supports MediaTek MT7629 HIFSYS clocks providing
 	  to PCI-E and USB.
 
+config COMMON_CLK_MT7986
+	bool "Clock driver for MediaTek MT7986"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	select COMMON_CLK_MEDIATEK
+	default ARCH_MEDIATEK
+	help
+	  This driver supports MediaTek MT7986 basic clocks and clocks
+	  required for various periperals found on MediaTek.
+
+config COMMON_CLK_MT7986_ETHSYS
+	bool "Clock driver for MediaTek MT7986 ETHSYS"
+	depends on COMMON_CLK_MT7986
+	default COMMON_CLK_MT7986
+	help
+	  This driver add support for clocks for Ethernet and SGMII
+	  required on MediaTek MT7986 SoC.
+
 config COMMON_CLK_MT8135
 	bool "Clock driver for MediaTek MT8135"
 	depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 3b0c2be73824..cab2b8764500 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -46,6 +46,10 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o
 obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
 obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
 obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
+obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
 obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
 obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
 obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
diff --git a/drivers/clk/mediatek/clk-mt7986-apmixed.c b/drivers/clk/mediatek/clk-mt7986-apmixed.c
new file mode 100644
index 000000000000..0925d61b55f2
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu at mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+#define MT7986_PLL_FMAX (2500UL * MHZ)
+#define CON0_MT7986_RST_BAR BIT(27)
+
+#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
+		 _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift,         \
+		 _div_table, _parent_name)                                     \
+	{                                                                      \
+		.id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg,    \
+		.en_mask = _en_mask, .flags = _flags,                          \
+		.rst_bar_mask = CON0_MT7986_RST_BAR, .fmax = MT7986_PLL_FMAX,  \
+		.pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \
+		.tuner_reg = _tuner_reg, .pcw_reg = _pcw_reg,                  \
+		.pcw_shift = _pcw_shift, .div_table = _div_table,              \
+		.parent_name = _parent_name,                                   \
+	}
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg,   \
+	    _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift)                       \
+	PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
+		 _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, NULL,   \
+		 "clkxtal")
+
+static const struct mtk_pll_data plls[] = {
+	PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, 0, 32,
+	    0x0200, 4, 0, 0x0204, 0),
+	PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x00000001, 0, 32,
+	    0x0210, 4, 0, 0x0214, 0),
+	PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0220, 0x022C, 0x00000001, 0, 32,
+	    0x0220, 4, 0, 0x0224, 0),
+	PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0230, 0x023c, 0x00000001, 0, 32,
+	    0x0230, 4, 0, 0x0234, 0),
+	PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0240, 0x024c, 0x00000001, 0,
+	    32, 0x0240, 4, 0, 0x0244, 0),
+	PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0250, 0x025c, 0x00000001, 0, 32,
+	    0x0250, 4, 0, 0x0254, 0),
+	PLL(CLK_APMIXED_MPLL, "mpll", 0x0260, 0x0270, 0x00000001, 0, 32, 0x0260,
+	    4, 0, 0x0264, 0),
+	PLL(CLK_APMIXED_APLL2, "apll2", 0x0278, 0x0288, 0x00000001, 0, 32,
+	    0x0278, 4, 0, 0x027c, 0),
+};
+
+static void __init mtk_apmixedsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
+
+	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+	clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt7986-apmixedsys",
+	       mtk_apmixedsys_init);
diff --git a/drivers/clk/mediatek/clk-mt7986-eth.c b/drivers/clk/mediatek/clk-mt7986-eth.c
new file mode 100644
index 000000000000..495d023ccad7
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986-eth.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu at mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+
+static const struct mtk_gate_regs sgmii0_cg_regs = {
+	.set_ofs = 0xe4,
+	.clr_ofs = 0xe4,
+	.sta_ofs = 0xe4,
+};
+
+#define GATE_SGMII0(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &sgmii0_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+	}
+
+static const struct mtk_gate sgmii0_clks[] __initconst = {
+	GATE_SGMII0(CLK_SGMII0_TX250M_EN, "sgmii0_tx250m_en", "top_xtal", 2),
+	GATE_SGMII0(CLK_SGMII0_RX250M_EN, "sgmii0_rx250m_en", "top_xtal", 3),
+	GATE_SGMII0(CLK_SGMII0_CDR_REF, "sgmii0_cdr_ref", "top_xtal", 4),
+	GATE_SGMII0(CLK_SGMII0_CDR_FB, "sgmii0_cdr_fb", "top_xtal", 5),
+};
+
+static const struct mtk_gate_regs sgmii1_cg_regs = {
+	.set_ofs = 0xe4,
+	.clr_ofs = 0xe4,
+	.sta_ofs = 0xe4,
+};
+
+#define GATE_SGMII1(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &sgmii1_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+	}
+
+static const struct mtk_gate sgmii1_clks[] __initconst = {
+	GATE_SGMII1(CLK_SGMII1_TX250M_EN, "sgmii1_tx250m_en", "top_xtal", 2),
+	GATE_SGMII1(CLK_SGMII1_RX250M_EN, "sgmii1_rx250m_en", "top_xtal", 3),
+	GATE_SGMII1(CLK_SGMII1_CDR_REF, "sgmii1_cdr_ref", "top_xtal", 4),
+	GATE_SGMII1(CLK_SGMII1_CDR_FB, "sgmii1_cdr_fb", "top_xtal", 5),
+};
+
+static const struct mtk_gate_regs eth_cg_regs = {
+	.set_ofs = 0x30,
+	.clr_ofs = 0x30,
+	.sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _name, _parent, _shift)                                  \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &eth_cg_regs, .shift = _shift,                         \
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+	}
+
+static const struct mtk_gate eth_clks[] __initconst = {
+	GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x_sel", 6),
+	GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m_sel", 7),
+	GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m_sel", 8),
+	GATE_ETH(CLK_ETH_WOCPU1_EN, "eth_wocpu1_en", "netsys_mcu_sel", 14),
+	GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", "netsys_mcu_sel", 15),
+};
+
+static void __init mtk_sgmiisys_0_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
+
+	mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_sgmiisys_0, "mediatek,mt7986-sgmiisys_0",
+	       mtk_sgmiisys_0_init);
+
+static void __init mtk_sgmiisys_1_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
+
+	mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_sgmiisys_1, "mediatek,mt7986-sgmiisys_1",
+	       mtk_sgmiisys_1_init);
+
+static void __init mtk_ethsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(eth_clks));
+
+	mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt7986-ethsys_ck", mtk_ethsys_init);
diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c
new file mode 100644
index 000000000000..35e16c28966a
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu at mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+static DEFINE_SPINLOCK(mt7986_clk_lock);
+
+static const struct mtk_fixed_factor infra_divs[] __initconst = {
+	FACTOR(CLK_INFRA_SYSAXI_D2, "infra_sysaxi_d2", "sysaxi_sel", 1, 2),
+};
+
+static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel",
+							     "uart_sel" };
+
+static const char *const infra_spi_parents[] __initconst = { "i2c_sel",
+							     "spi_sel" };
+
+static const char *const infra_pwm_bsel_parents[] __initconst = {
+	"top_rtc_32p7k", "csw_f26m_sel", "infra_sysaxi_d2", "pwm_sel"
+};
+
+static const char *const infra_pcie_parents[] __initconst = {
+	"top_rtc_32p7k", "csw_f26m_sel", "top_xtal", "pextp_tl_ck_sel"
+};
+
+static const struct mtk_mux infra_muxes[] = {
+	/* MODULE_CLK_SEL_0 */
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel",
+			     infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel",
+			     infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel",
+			     infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel",
+			     infra_spi_parents, 0x0018, 0x0010, 0x0014, 4, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel",
+			     infra_spi_parents, 0x0018, 0x0010, 0x0014, 5, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel",
+			     infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 9,
+			     2, -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel",
+			     infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 11,
+			     2, -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel",
+			     infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13,
+			     2, -1, -1, -1),
+	/* MODULE_CLK_SEL_1 */
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel",
+			     infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2,
+			     -1, -1, -1),
+};
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+	.set_ofs = 0x40,
+	.clr_ofs = 0x44,
+	.sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+	.set_ofs = 0x50,
+	.clr_ofs = 0x54,
+	.sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+	.set_ofs = 0x60,
+	.clr_ofs = 0x64,
+	.sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &infra0_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_setclr,                               \
+	}
+
+#define GATE_INFRA1(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &infra1_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_setclr,                               \
+	}
+
+#define GATE_INFRA2(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &infra2_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_setclr,                               \
+	}
+
+static const struct mtk_gate infra_clks[] __initconst = {
+	/* INFRA0 */
+	GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta", "infra_sysaxi_d2", 0),
+	GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck", "infra_sysaxi_d2", 1),
+	GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta", "infra_pwm_bsel", 2),
+	GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1", "infra_pwm1_sel", 3),
+	GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2", "infra_pwm2_sel", 4),
+	GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma", "sysaxi_sel", 6),
+	GATE_INFRA0(CLK_INFRA_EIP97_CK, "infra_eip97", "eip_b_sel", 7),
+	GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus", "sysaxi_sel", 8),
+	GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m", "csw_f26m_sel", 9),
+	GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l", "aud_l_sel", 10),
+	GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud", "a1sys_sel", 11),
+	GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2", "a_tuner_sel", 13),
+	GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", "csw_f26m_sel",
+		    14),
+	GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg", "infra_sysaxi_d2", 15),
+	GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma", "infra_sysaxi_d2", 16),
+	GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej", "infra_sysaxi_d2", 24),
+	GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m", "csw_f26m_sel", 25),
+	GATE_INFRA0(CLK_INFRA_TRNG_CK, "infra_trng", "sysaxi_sel", 26),
+	/* INFRA1 */
+	GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm", "csw_f26m_sel", 0),
+	GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0", "i2c_sel", 1),
+	GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0", "infra_uart0_sel", 2),
+	GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1", "infra_uart1_sel", 3),
+	GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2", "infra_uart2_sel", 4),
+	GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1", "nfi1x_sel", 8),
+	GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1", "spinfi_sel", 9),
+	GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck", "infra_sysaxi_d2",
+		    10),
+	GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0", "infra_spi0_sel", 11),
+	GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1", "infra_spi1_sel", 12),
+	GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", "infra_sysaxi_d2",
+		    13),
+	GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", "infra_sysaxi_d2",
+		    14),
+	GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc", "top_rtc_32k", 15),
+	GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc", "emmc_416m_sel", 16),
+	GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", "emmc_250m_sel",
+		    17),
+	GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m", "sysaxi_sel",
+		    18),
+	GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "infra_sysaxi_d2",
+		    19),
+	GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "csw_f26m_sel", 20),
+	GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m_sel", 21),
+	GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x_sel", 23),
+	/* INFRA2 */
+	GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133", "sysaxi_sel", 0),
+	GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m", "infra_sysaxi_d2",
+		    1),
+	GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", "u2u3_sys_sel", 2),
+	GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb", "u2u3_sel", 3),
+	GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie", "pextp_tl_ck_sel", 12),
+	GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe", "top_xtal",
+		    13),
+	GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier", "csw_f26m_sel", 14),
+	GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb", "sysaxi_sel", 15),
+};
+
+static void __init mtk_infracfg_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	void __iomem *base;
+	int nr = ARRAY_SIZE(infra_divs) + ARRAY_SIZE(infra_muxes) +
+		 ARRAY_SIZE(infra_clks);
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return;
+	}
+
+	clk_data = mtk_alloc_clk_data(nr);
+	mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+	mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
+			       &mt7986_clk_lock, clk_data);
+	mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_infracfg, "mediatek,mt7986-infracfg", mtk_infracfg_init);
diff --git a/drivers/clk/mediatek/clk-mt7986-topckgen.c b/drivers/clk/mediatek/clk-mt7986-topckgen.c
new file mode 100644
index 000000000000..0a376044d290
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu at mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+static DEFINE_SPINLOCK(mt7986_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+	FIXED_CLK(CLK_TOP_XTAL, "top_xtal", "clkxtal", 40000000),
+	FIXED_CLK(CLK_TOP_JTAG, "top_jtag", "clkxtal", 50000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] __initconst = {
+	/* XTAL */
+	FACTOR(CLK_TOP_XTAL_D2, "top_xtal_d2", "top_xtal", 1, 2),
+	FACTOR(CLK_TOP_RTC_32K, "top_rtc_32k", "top_xtal", 1, 1250),
+	FACTOR(CLK_TOP_RTC_32P7K, "top_rtc_32p7k", "top_xtal", 1, 1220),
+	/* MPLL */
+	FACTOR(CLK_TOP_MPLL_D2, "top_mpll_d2", "mpll", 1, 2),
+	FACTOR(CLK_TOP_MPLL_D4, "top_mpll_d4", "mpll", 1, 4),
+	FACTOR(CLK_TOP_MPLL_D8, "top_mpll_d8", "mpll", 1, 8),
+	FACTOR(CLK_TOP_MPLL_D8_D2, "top_mpll_d8_d2", "mpll", 1, 16),
+	FACTOR(CLK_TOP_MPLL_D3_D2, "top_mpll_d3_d2", "mpll", 1, 6),
+	/* MMPLL */
+	FACTOR(CLK_TOP_MMPLL_D2, "top_mmpll_d2", "mmpll", 1, 2),
+	FACTOR(CLK_TOP_MMPLL_D4, "top_mmpll_d4", "mmpll", 1, 4),
+	FACTOR(CLK_TOP_MMPLL_D8, "top_mmpll_d8", "mmpll", 1, 8),
+	FACTOR(CLK_TOP_MMPLL_D8_D2, "top_mmpll_d8_d2", "mmpll", 1, 16),
+	FACTOR(CLK_TOP_MMPLL_D3_D8, "top_mmpll_d3_d8", "mmpll", 1, 24),
+	FACTOR(CLK_TOP_MMPLL_U2PHY, "top_mmpll_u2phy", "mmpll", 1, 30),
+	/* APLL2 */
+	FACTOR(CLK_TOP_APLL2_D4, "top_apll2_d4", "apll2", 1, 4),
+	/* NET1PLL */
+	FACTOR(CLK_TOP_NET1PLL_D4, "top_net1pll_d4", "net1pll", 1, 4),
+	FACTOR(CLK_TOP_NET1PLL_D5, "top_net1pll_d5", "net1pll", 1, 5),
+	FACTOR(CLK_TOP_NET1PLL_D5_D2, "top_net1pll_d5_d2", "net1pll", 1, 10),
+	FACTOR(CLK_TOP_NET1PLL_D5_D4, "top_net1pll_d5_d4", "net1pll", 1, 20),
+	FACTOR(CLK_TOP_NET1PLL_D8_D2, "top_net1pll_d8_d2", "net1pll", 1, 16),
+	FACTOR(CLK_TOP_NET1PLL_D8_D4, "top_net1pll_d8_d4", "net1pll", 1, 32),
+	/* NET2PLL */
+	FACTOR(CLK_TOP_NET2PLL_D4, "top_net2pll_d4", "net2pll", 1, 4),
+	FACTOR(CLK_TOP_NET2PLL_D4_D2, "top_net2pll_d4_d2", "net2pll", 1, 8),
+	FACTOR(CLK_TOP_NET2PLL_D3_D2, "top_net2pll_d3_d2", "net2pll", 1, 2),
+	/* WEDMCUPLL */
+	FACTOR(CLK_TOP_WEDMCUPLL_D5_D2, "top_wedmcupll_d5_d2", "wedmcupll", 1,
+	       10),
+};
+
+static const char *const nfi1x_parents[] __initconst = { "top_xtal",
+							 "top_mmpll_d8",
+							 "top_net1pll_d8_d2",
+							 "top_net2pll_d3_d2",
+							 "top_mpll_d4",
+							 "top_mmpll_d8_d2",
+							 "top_wedmcupll_d5_d2",
+							 "top_mpll_d8" };
+
+static const char *const spinfi_parents[] __initconst = {
+	"top_xtal_d2",     "top_xtal",	"top_net1pll_d5_d4",
+	"top_mpll_d4",     "top_mmpll_d8_d2", "top_wedmcupll_d5_d2",
+	"top_mmpll_d3_d8", "top_mpll_d8"
+};
+
+static const char *const spi_parents[] __initconst = {
+	"top_xtal",	  "top_mpll_d2",	"top_mmpll_d8",
+	"top_net1pll_d8_d2", "top_net2pll_d3_d2",  "top_net1pll_d5_d4",
+	"top_mpll_d4",       "top_wedmcupll_d5_d2"
+};
+
+static const char *const uart_parents[] __initconst = { "top_xtal",
+							"top_mpll_d8",
+							"top_mpll_d8_d2" };
+
+static const char *const pwm_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d8_d2", "top_net1pll_d5_d4", "top_mpll_d4"
+};
+
+static const char *const i2c_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5_d4", "top_mpll_d4", "top_net1pll_d8_d4"
+};
+
+static const char *const pextp_tl_ck_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5_d4", "top_net2pll_d4_d2", "top_rtc_32k"
+};
+
+static const char *const emmc_250m_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5_d2"
+};
+
+static const char *const emmc_416m_parents[] __initconst = { "top_xtal",
+							     "mpll" };
+
+static const char *const f_26m_adc_parents[] __initconst = { "top_xtal",
+							     "top_mpll_d8_d2" };
+
+static const char *const dramc_md32_parents[] __initconst = { "top_xtal",
+							      "top_mpll_d2" };
+
+static const char *const sysaxi_parents[] __initconst = { "top_xtal",
+							  "top_net1pll_d8_d2",
+							  "top_net2pll_d4" };
+
+static const char *const sysapb_parents[] __initconst = { "top_xtal",
+							  "top_mpll_d3_d2",
+							  "top_net2pll_d4_d2" };
+
+static const char *const arm_db_main_parents[] __initconst = {
+	"top_xtal", "top_net2pll_d3_d2"
+};
+
+static const char *const arm_db_jtsel_parents[] __initconst = { "top_jtag",
+								"top_xtal" };
+
+static const char *const netsys_parents[] __initconst = { "top_xtal",
+							  "top_mmpll_d4" };
+
+static const char *const netsys_500m_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5"
+};
+
+static const char *const netsys_mcu_parents[] __initconst = {
+	"top_xtal", "wedmcupll", "top_mmpll_d2", "top_net1pll_d4",
+	"top_net1pll_d5"
+};
+
+static const char *const netsys_2x_parents[] __initconst = {
+	"top_xtal", "net2pll", "wedmcupll", "top_mmpll_d2"
+};
+
+static const char *const sgm_325m_parents[] __initconst = { "top_xtal",
+							    "sgmpll" };
+
+static const char *const sgm_reg_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d8_d4"
+};
+
+static const char *const a1sys_parents[] __initconst = { "top_xtal",
+							 "top_apll2_d4" };
+
+static const char *const conn_mcusys_parents[] __initconst = { "top_xtal",
+							       "top_mmpll_d2" };
+
+static const char *const eip_b_parents[] __initconst = { "top_xtal",
+							 "net2pll" };
+
+static const char *const aud_l_parents[] __initconst = { "top_xtal", "apll2",
+							 "top_mpll_d8_d2" };
+
+static const char *const a_tuner_parents[] __initconst = { "top_xtal",
+							   "top_apll2_d4",
+							   "top_mpll_d8_d2" };
+
+static const char *const u2u3_sys_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5_d4"
+};
+
+static const char *const da_u2_refsel_parents[] __initconst = {
+	"top_xtal", "top_mmpll_u2phy"
+};
+
+static const struct mtk_mux top_muxes[] = {
+	/* CLK_CFG_0 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents,
+			     0x000, 0x004, 0x008, 0, 3, 7, 0x1C0, 0),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
+			     0x000, 0x004, 0x008, 8, 3, 15, 0x1C0, 1),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000,
+			     0x004, 0x008, 16, 3, 23, 0x1C0, 2),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
+			     0x000, 0x004, 0x008, 24, 3, 31, 0x1C0, 3),
+	/* CLK_CFG_1 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010,
+			     0x014, 0x018, 0, 2, 7, 0x1C0, 4),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010,
+			     0x014, 0x018, 8, 2, 15, 0x1C0, 5),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010,
+			     0x014, 0x018, 16, 2, 23, 0x1C0, 6),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
+			     pextp_tl_ck_parents, 0x010, 0x014, 0x018, 24, 2,
+			     31, 0x1C0, 7),
+	/* CLK_CFG_2 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel",
+			     emmc_250m_parents, 0x020, 0x024, 0x028, 0, 1, 7,
+			     0x1C0, 8),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_416M_SEL, "emmc_416m_sel",
+			     emmc_416m_parents, 0x020, 0x024, 0x028, 8, 1, 15,
+			     0x1C0, 9),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel",
+			     f_26m_adc_parents, 0x020, 0x024, 0x028, 16, 1, 23,
+			     0x1C0, 10),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents,
+			     0x020, 0x024, 0x028, 24, 1, 31, 0x1C0, 11),
+	/* CLK_CFG_3 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
+			     dramc_md32_parents, 0x030, 0x034, 0x038, 0, 1, 7,
+			     0x1C0, 12),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents,
+			     0x030, 0x034, 0x038, 8, 2, 15, 0x1C0, 13),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents,
+			     0x030, 0x034, 0x038, 16, 2, 23, 0x1C0, 14),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
+			     arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1,
+			     31, 0x1C0, 15),
+	/* CLK_CFG_4 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_JTSEL, "arm_db_jtsel",
+			     arm_db_jtsel_parents, 0x040, 0x044, 0x048, 0, 1, 7,
+			     0x1C0, 16),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
+			     0x040, 0x044, 0x048, 8, 1, 15, 0x1C0, 17),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
+			     netsys_500m_parents, 0x040, 0x044, 0x048, 16, 1,
+			     23, 0x1C0, 18),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
+			     netsys_mcu_parents, 0x040, 0x044, 0x048, 24, 3, 31,
+			     0x1C0, 19),
+	/* CLK_CFG_5 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
+			     netsys_2x_parents, 0x050, 0x054, 0x058, 0, 2, 7,
+			     0x1C0, 20),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
+			     sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
+			     0x1C0, 21),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel",
+			     sgm_reg_parents, 0x050, 0x054, 0x058, 16, 1, 23,
+			     0x1C0, 22),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
+			     0x050, 0x054, 0x058, 24, 1, 31, 0x1C0, 23),
+	/* CLK_CFG_6 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel",
+			     conn_mcusys_parents, 0x060, 0x064, 0x068, 0, 1, 7,
+			     0x1C0, 24),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents,
+			     0x060, 0x064, 0x068, 8, 1, 15, 0x1C0, 25),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PCIE_PHY_SEL, "pcie_phy_sel",
+			     f_26m_adc_parents, 0x060, 0x064, 0x068, 16, 1, 23,
+			     0x1C0, 26),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_USB3_PHY_SEL, "usb3_phy_sel",
+			     f_26m_adc_parents, 0x060, 0x064, 0x068, 24, 1, 31,
+			     0x1C0, 27),
+	/* CLK_CFG_7 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_F26M_SEL, "csw_f26m_sel",
+			     f_26m_adc_parents, 0x070, 0x074, 0x078, 0, 1, 7,
+			     0x1C0, 28),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
+			     0x070, 0x074, 0x078, 8, 2, 15, 0x1C0, 29),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
+			     a_tuner_parents, 0x070, 0x074, 0x078, 16, 2, 23,
+			     0x1C0, 30),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents,
+			     0x070, 0x074, 0x078, 24, 1, 31, 0x1C4, 0),
+	/* CLK_CFG_8 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel",
+			     u2u3_sys_parents, 0x080, 0x084, 0x088, 0, 1, 7,
+			     0x1C4, 1),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel",
+			     u2u3_sys_parents, 0x080, 0x084, 0x088, 8, 1, 15,
+			     0x1C4, 2),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_U2_REFSEL, "da_u2_refsel",
+			     da_u2_refsel_parents, 0x080, 0x084, 0x088, 16, 1,
+			     23, 0x1C4, 3),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel",
+			     da_u2_refsel_parents, 0x080, 0x084, 0x088, 24, 1,
+			     31, 0x1C4, 4),
+	/* CLK_CFG_9 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel",
+			     sgm_reg_parents, 0x090, 0x094, 0x098, 0, 1, 7,
+			     0x1C4, 5),
+};
+
+static void __init mtk_topckgen_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+	void __iomem *base;
+	int nr = ARRAY_SIZE(top_fixed_clks) + ARRAY_SIZE(top_divs) +
+		 ARRAY_SIZE(top_muxes);
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return;
+	}
+
+	clk_data = mtk_alloc_clk_data(nr);
+
+	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+				    clk_data);
+	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+	mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
+			       &mt7986_clk_lock, clk_data);
+
+	clk_prepare_enable(clk_data->clks[CLK_TOP_SYSAXI_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_SYSAPB_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_DRAMC_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_DRAMC_MD32_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_F26M_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_SGM_REG_SEL]);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt7986-topckgen", mtk_topckgen_init);
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:49 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:49 +0800
Subject: [v2,
 04/12] pinctrl: mediatek: moore: check if pin_desc is valid before use
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-5-sam.shih@mediatek.com>

Certain SoC are missing the middle part gpios in consecutive pins,
it's better to check if mtk_pin_desc is a valid pin for the extensibility

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
v2: applied the comment suggested by reviewers:
    - for the pins not ballout, we can fill .name in struct mtk_pin_desc
      as NULL and return -ENOTSUPP in gpio/pinconf ops.

---
 drivers/pinctrl/mediatek/pinctrl-moore.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c
index 3a4a23c40a71..ad3b67163973 100644
--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
+++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
@@ -60,6 +60,8 @@ static int mtk_pinmux_set_mux(struct pinctrl_dev *pctldev,
 		int pin = grp->pins[i];
 
 		desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+		if (!desc->name)
+			return -ENOTSUPP;
 
 		mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
 				 pin_modes[i]);
@@ -76,6 +78,8 @@ static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	const struct mtk_pin_desc *desc;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
 				hw->soc->gpio_m);
@@ -89,6 +93,8 @@ static int mtk_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 	const struct mtk_pin_desc *desc;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	/* hardware would take 0 as input direction */
 	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !input);
@@ -103,6 +109,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 	const struct mtk_pin_desc *desc;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	switch (param) {
 	case PIN_CONFIG_BIAS_DISABLE:
@@ -218,6 +226,8 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 	int cfg, err = 0;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	for (cfg = 0; cfg < num_configs; cfg++) {
 		param = pinconf_to_config_param(configs[cfg]);
@@ -435,6 +445,8 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
 	int value, err;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
 	if (err)
@@ -449,6 +461,10 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
 	const struct mtk_pin_desc *desc;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+	if (!desc->name) {
+		dev_err(hw->dev, "Failed to set gpio %d\n", gpio);
+		return;
+	}
 
 	mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
 }
@@ -490,6 +506,8 @@ static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
 	u32 debounce;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	if (!hw->eint ||
 	    pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE ||
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:50 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:50 +0800
Subject: [v2,05/12] dt-bindings: pinctrl: update bindings for MT7986 SoC
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-6-sam.shih@mediatek.com>

This updates bindings for MT7986 pinctrl driver.
The difference of pinctrl between mt7986a and mt7986b
is that pin-41 to pin-65 do not exist on mt7986b

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
v2 : deleted the redundant description of mt7986a/mt7986b

---
 .../bindings/pinctrl/pinctrl-mt7622.txt       | 170 ++++++++++++++++++
 1 file changed, 170 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
index 7a7aca1ed705..4711dfb2ea77 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
@@ -4,6 +4,8 @@ Required properties for the root node:
  - compatible: Should be one of the following
 	       "mediatek,mt7622-pinctrl" for MT7622 SoC
 	       "mediatek,mt7629-pinctrl" for MT7629 SoC
+	       "mediatek,mt7986a-pinctrl" for MT7986a SoC
+	       "mediatek,mt7986b-pinctrl" for MT7986b SoC
  - reg: offset and length of the pinctrl space
 
  - gpio-controller: Marks the device node as a GPIO controller.
@@ -455,6 +457,174 @@ Valid values for groups are:
 	"wf0_5g"			"wifi"		0, 1, 2, 3, 4, 5, 6,
 							7, 8, 9, 10
 
+== Valid values for pins, function and groups on MT7986a and MT7986b  ==
+
+Valid values for pins are:
+pins can be referenced via the pin names as the below table shown and the
+related physical number is also put ahead of those names which helps cross
+references to pins between groups to know whether pins assignment conflict
+happens among devices try to acquire those available pins.
+
+	Pin #:  Valid values for pins
+	-----------------------------
+	PIN 0: "SYS_WATCHDOG"
+	PIN 1: "WF2G_LED"
+	PIN 2: "WF5G_LED"
+	PIN 3: "I2C_SCL"
+	PIN 4: "I2C_SDA"
+	PIN 5: "GPIO_0"
+	PIN 6: "GPIO_1"
+	PIN 7: "GPIO_2"
+	PIN 8: "GPIO_3"
+	PIN 9: "GPIO_4"
+	PIN 10: "GPIO_5"
+	PIN 11: "GPIO_6"
+	PIN 12: "GPIO_7"
+	PIN 13: "GPIO_8"
+	PIN 14: "GPIO_9"
+	PIN 15: "GPIO_10"
+	PIN 16: "GPIO_11"
+	PIN 17: "GPIO_12"
+	PIN 18: "GPIO_13"
+	PIN 19: "GPIO_14"
+	PIN 20: "GPIO_15"
+	PIN 21: "PWM0"
+	PIN 22: "PWM1"
+	PIN 23: "SPI0_CLK"
+	PIN 24: "SPI0_MOSI"
+	PIN 25: "SPI0_MISO"
+	PIN 26: "SPI0_CS"
+	PIN 27: "SPI0_HOLD"
+	PIN 28: "SPI0_WP"
+	PIN 29: "SPI1_CLK"
+	PIN 30: "SPI1_MOSI"
+	PIN 31: "SPI1_MISO"
+	PIN 32: "SPI1_CS"
+	PIN 33: "SPI2_CLK"
+	PIN 34: "SPI2_MOSI"
+	PIN 35: "SPI2_MISO"
+	PIN 36: "SPI2_CS"
+	PIN 37: "SPI2_HOLD"
+	PIN 38: "SPI2_WP"
+	PIN 39: "UART0_RXD"
+	PIN 40: "UART0_TXD"
+	PIN 41: "PCIE_PERESET_N"
+	PIN 42: "UART1_RXD"
+	PIN 43: "UART1_TXD"
+	PIN 44: "UART1_CTS"
+	PIN 45: "UART1_RTS"
+	PIN 46: "UART2_RXD"
+	PIN 47: "UART2_TXD"
+	PIN 48: "UART2_CTS"
+	PIN 49: "UART2_RTS"
+	PIN 50: "EMMC_DATA_0"
+	PIN 51: "EMMC_DATA_1"
+	PIN 52: "EMMC_DATA_2"
+	PIN 53: "EMMC_DATA_3"
+	PIN 54: "EMMC_DATA_4"
+	PIN 55: "EMMC_DATA_5"
+	PIN 56: "EMMC_DATA_6"
+	PIN 57: "EMMC_DATA_7"
+	PIN 58: "EMMC_CMD"
+	PIN 59: "EMMC_CK"
+	PIN 60: "EMMC_DSL"
+	PIN 61: "EMMC_RSTB"
+	PIN 62: "PCM_DTX"
+	PIN 63: "PCM_DRX"
+	PIN 64: "PCM_CLK"
+	PIN 65: "PCM_FS"
+	PIN 66: "MT7531_INT"
+	PIN 67: "SMI_MDC"
+	PIN 68: "SMI_MDIO"
+	PIN 69: "WF0_DIG_RESETB"
+	PIN 70: "WF0_CBA_RESETB"
+	PIN 71: "WF0_XO_REQ"
+	PIN 72: "WF0_TOP_CLK"
+	PIN 73: "WF0_TOP_DATA"
+	PIN 74: "WF0_HB1"
+	PIN 75: "WF0_HB2"
+	PIN 76: "WF0_HB3"
+	PIN 77: "WF0_HB4"
+	PIN 78: "WF0_HB0"
+	PIN 79: "WF0_HB0_B"
+	PIN 80: "WF0_HB5"
+	PIN 81: "WF0_HB6"
+	PIN 82: "WF0_HB7"
+	PIN 83: "WF0_HB8"
+	PIN 84: "WF0_HB9"
+	PIN 85: "WF0_HB10"
+	PIN 86: "WF1_DIG_RESETB"
+	PIN 87: "WF1_CBA_RESETB"
+	PIN 88: "WF1_XO_REQ"
+	PIN 89: "WF1_TOP_CLK"
+	PIN 90: "WF1_TOP_DATA"
+	PIN 91: "WF1_HB1"
+	PIN 92: "WF1_HB2"
+	PIN 93: "WF1_HB3"
+	PIN 94: "WF1_HB4"
+	PIN 95: "WF1_HB0"
+	PIN 96: "WF1_HB0_B"
+	PIN 97: "WF1_HB5"
+	PIN 98: "WF1_HB6"
+	PIN 99: "WF1_HB7"
+	PIN 100: "WF1_HB8"
+
+There is no PIN 41 to PIN 65 above on mt7686b, you can only use those
+pins on mt7986a.
+
+Valid values for function are:
+	"audio, "emmc", "eth", "i2c", "wifi", "led", "flash", "pcie",
+	"pwm", "spi", "uart", "watchdog"
+
+There is no "audio", "pcie" functions above on mt7986b, you can only
+use those functions on mt7986a.
+
+Valid values for groups are:
+additional data is put followingly with valid value allowing us to know which
+applicable function and which relevant pins (in pin#) are able applied for that
+group.
+
+	Valid value			function	pins (in pin#)
+	-------------------------------------------------------------------------
+	"watchdog"			"watchdog"	0
+	"wifi_led"			"led"		1, 2
+	"i2c"				"i2c"		3, 4
+	"uart1_0"			"uart"		7, 8, 9, 10
+	"pcie_clk"			"pcie"		9
+	"pcie_wake"			"pcie"		10
+	"spi1_0"			"spi"		11, 12, 13, 14
+	"pwm1_1"			"pwm"		20,
+	"pwm0"				"pwm"		21,
+	"pwm1_0"			"pwm"		22,
+	"snfi"				"flash"		23, 24, 25, 26, 27, 28
+	"spi1_2"			"spi"		29, 30, 31, 32
+	"emmc_45"			"emmc"		22, 23, 24, 25, 26, 27,
+							28, 29, 30, 31, 32
+	"spi1_1"			"spi"		23, 24, 25, 26
+	"uart1_2"			"uart"		29, 30, 31, 32
+	"uart1_1"			"uart"		23, 24, 25, 26
+	"uart2_0"			"uart"		29, 30, 31, 32
+	"spi0"				"spi"		33, 34, 35, 36
+	"spi0_wp_hold"			"spi"		37, 38
+	"uart1_3_rx_tx"			"uart"		35, 36
+	"uart1_3_cts_rts"		"uart"		37, 38
+	"uart2_1"			"uart"		33, 34, 35, 36
+	"spi1_3"			"spi"		33, 34, 35, 36
+	"uart0"				"uart"		39, 40
+	"pcie_pereset"			"pcie"		41
+	"uart1"				"uart"		42, 43, 44, 45
+	"uart2"				"uart"		46, 47, 48, 49
+	"emmc_51"			"emmc"		50, 51, 52, 53, 54, 55,
+							56, 57, 57, 59, 60, 61
+	"pcm"				"audio"		62, 63, 64, 65
+	"i2s"				"audio"		62, 63, 64, 65
+	"switch_int"			"eth"		66
+	"mdc_mdio"			"eth"		67
+
+There is no "pcie_pereset", "uart1", "uart2" "emmc_51", "pcm", and "i2s" groups
+above on mt7986b, you can only use those groups on mt7986a.
+
+
 Example:
 
 	pio: pinctrl at 10211000 {
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:52 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:52 +0800
Subject: [v2,07/12] dt-bindings: arm64: dts: mediatek: Add mt7986 series
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-8-sam.shih@mediatek.com>

MT7986 is Mediatek's new 4-core SoC, which is mainly for wifi-router
application. The difference between mt7986a and mt7986b is that some
pins do not exist on mt7986b.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>

---
v2: added an Acked-by tag

---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 80a05f6fee85..a9a778269684 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -76,6 +76,14 @@ properties:
           - enum:
               - mediatek,mt7629-rfb
           - const: mediatek,mt7629
+      - items:
+          - enum:
+              - mediatek,mt7986a-rfb
+          - const: mediatek,mt7986a
+      - items:
+          - enum:
+              - mediatek,mt7986b-rfb
+          - const: mediatek,mt7986b
       - items:
           - enum:
               - mediatek,mt8127-moose
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:51 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:51 +0800
Subject: [v2,06/12] pinctrl: mediatek: add support for MT7986 SoC
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-7-sam.shih@mediatek.com>

This commit includes pinctrl driver for Mediatek MT7986

The difference of pinctrl between mt7986a and mt7986b
is that pin-41 to pin-65 do not exist on mt7986b

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
v2: applied the comment suggested by reviewers:
    - for the pins not ballout, we can fill .name in struct mtk_pin_desc
      as NULL and return -ENOTSUPP in gpio/pinconf ops.

---
 drivers/pinctrl/mediatek/Kconfig          |    7 +
 drivers/pinctrl/mediatek/Makefile         |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt7986.c | 1217 +++++++++++++++++++++
 3 files changed, 1225 insertions(+)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c

diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 7040a7a7bd5d..66db4ac5d169 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -119,6 +119,13 @@ config PINCTRL_MT7622
 	default ARM64 && ARCH_MEDIATEK
 	select PINCTRL_MTK_MOORE
 
+config PINCTRL_MT7986
+	bool "Mediatek MT7986 pin control"
+	depends on OF
+	depends on ARM64 || COMPILE_TEST
+	default ARM64 && ARCH_MEDIATEK
+	select PINCTRL_MTK_MOORE
+
 config PINCTRL_MT8167
 	bool "Mediatek MT8167 pin control"
 	depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 1bb7f9c65bc2..1e3931d924e7 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_MT6797)	+= pinctrl-mt6797.o
 obj-$(CONFIG_PINCTRL_MT7622)	+= pinctrl-mt7622.o
 obj-$(CONFIG_PINCTRL_MT7623)	+= pinctrl-mt7623.o
 obj-$(CONFIG_PINCTRL_MT7629)	+= pinctrl-mt7629.o
+obj-$(CONFIG_PINCTRL_MT7986)	+= pinctrl-mt7986.o
 obj-$(CONFIG_PINCTRL_MT8167)	+= pinctrl-mt8167.o
 obj-$(CONFIG_PINCTRL_MT8173)	+= pinctrl-mt8173.o
 obj-$(CONFIG_PINCTRL_MT8183)	+= pinctrl-mt8183.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
new file mode 100644
index 000000000000..808ae4e03eb2
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
@@ -0,0 +1,1217 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7986 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ */
+
+#include "pinctrl-moore.h"
+
+#define MT7986_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
+#define MT7986_NOT_BALLOUT_PIN(_number) { .number = _number }
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,	\
+			   _x_bits)														\
+	PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,		\
+			   _x_bits, 32, 0)
+
+/**
+ * enum - Locking variants of the iocfg bases
+ *
+ * MT7986 have multiple bases to program pin configuration listed as the below:
+ * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000,
+ * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000,
+ * _i_based could be used to indicate what base the pin should be mapped into.
+ *
+ * Each iocfg register base control different group of pads on the SoC
+ *
+ *
+ *  chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 | o  o  o  o  o  o  o  o |
+ *  7 | o  o  o  o  o  o  o  o |
+ *  6 | o  o  o  o  o  o  o  o |
+ *  5 | o  o  o  o  o  o  o  o |
+ *  4 | o  o  o  o  o  o  o  o |
+ *  3 | o  o  o  o  o  o  o  o |
+ *  2 | o  o  o  o  o  o  o  o |
+ *  1 | o  o  o  o  o  o  o  o |
+ *    +------------------------+
+ *
+ *  inside Chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 |                        |
+ *  7 |        TL  TR          |
+ *  6 |      +---------+       |
+ *  5 |   LT |         | RT    |
+ *  4 |      |         |       |
+ *  3 |   LB |         | RB    |
+ *  2 |      +---------+       |
+ *  1 |                        |
+ *    +------------------------+
+ *
+ */
+
+enum {
+	GPIO_BASE,
+	IOCFG_RT_BASE,
+	IOCFG_RB_BASE,
+	IOCFG_LT_BASE,
+	IOCFG_LB_BASE,
+	IOCFG_TR_BASE,
+	IOCFG_TL_BASE,
+};
+
+static const char *const mt7986_pinctrl_register_base_names[] = {
+	"gpio_base", "iocfg_rt_base", "iocfg_rb_base", "iocfg_lt_base",
+	"iocfg_lb_base", "iocfg_tr_base", "iocfg_tl_base",
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = {
+	PIN_FIELD(0, 40, 0x300, 0x10, 0, 4),
+	PIN_FIELD(41, 65, 0x350, 0x10, 4, 4),
+	PIN_FIELD(66, 68, 0x380, 0x10, 8, 4),
+	PIN_FIELD(69, 100, 0x380, 0x10, 20, 4),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = {
+	PIN_FIELD(0, 40, 0x0, 0x10, 0, 1),
+	PIN_FIELD(41, 65, 0x10, 0x10, 9, 1),
+	PIN_FIELD(66, 68, 0x20, 0x10, 2, 1),
+	PIN_FIELD(69, 100, 0x20, 0x10, 5, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_di_range[] = {
+	PIN_FIELD(0, 40, 0x200, 0x10, 0, 1),
+	PIN_FIELD(41, 65, 0x210, 0x10, 9, 1),
+	PIN_FIELD(66, 68, 0x220, 0x10, 2, 1),
+	PIN_FIELD(69, 100, 0x220, 0x10, 5, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_do_range[] = {
+	PIN_FIELD(0, 40, 0x100, 0x10, 0, 1),
+	PIN_FIELD(41, 65, 0x110, 0x10, 9, 1),
+	PIN_FIELD(66, 68, 0x120, 0x10, 2, 1),
+	PIN_FIELD(69, 100, 0x120, 0x10, 5, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 1, IOCFG_LT_BASE, 0x20, 0x10, 10, 1),
+	PIN_FIELD_BASE(2, 2, IOCFG_LT_BASE, 0x20, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, IOCFG_LB_BASE, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(4, 4, IOCFG_LB_BASE, 0x20, 0x10, 1, 1),
+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(7, 7, IOCFG_LT_BASE, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, IOCFG_LT_BASE, 0x20, 0x10, 1, 1),
+	PIN_FIELD_BASE(9, 9, IOCFG_LT_BASE, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(10, 10, IOCFG_LT_BASE, 0x20, 0x10, 3, 1),
+	PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(13, 13, IOCFG_RB_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(14, 14, IOCFG_RB_BASE, 0x40, 0x10, 11, 1),
+	PIN_FIELD_BASE(15, 15, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(16, 16, IOCFG_RB_BASE, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(17, 17, IOCFG_RB_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(18, 18, IOCFG_RB_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(19, 19, IOCFG_RB_BASE, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(20, 20, IOCFG_RB_BASE, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(21, 21, IOCFG_RT_BASE, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(22, 22, IOCFG_RT_BASE, 0x30, 0x10, 13, 1),
+	PIN_FIELD_BASE(23, 23, IOCFG_RT_BASE, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 26, IOCFG_RT_BASE, 0x30, 0x10, 15, 1),
+	PIN_FIELD_BASE(27, 27, IOCFG_RT_BASE, 0x30, 0x10, 16, 1),
+	PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x30, 0x10, 19, 1),
+	PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x30, 0x10, 20, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x30, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x30, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x30, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x20, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x20, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x20, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 36, IOCFG_LT_BASE, 0x20, 0x10, 5, 1),
+	PIN_FIELD_BASE(37, 37, IOCFG_LT_BASE, 0x20, 0x10, 6, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x20, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x40, 0x10, 19, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 42, IOCFG_RB_BASE, 0x40, 0x10, 22, 1),
+	PIN_FIELD_BASE(43, 43, IOCFG_RB_BASE, 0x40, 0x10, 23, 1),
+	PIN_FIELD_BASE(44, 44, IOCFG_RB_BASE, 0x40, 0x10, 20, 1),
+	PIN_FIELD_BASE(45, 45, IOCFG_RB_BASE, 0x40, 0x10, 21, 1),
+	PIN_FIELD_BASE(46, 46, IOCFG_RB_BASE, 0x40, 0x10, 26, 1),
+	PIN_FIELD_BASE(47, 47, IOCFG_RB_BASE, 0x40, 0x10, 27, 1),
+	PIN_FIELD_BASE(48, 48, IOCFG_RB_BASE, 0x40, 0x10, 24, 1),
+	PIN_FIELD_BASE(49, 49, IOCFG_RB_BASE, 0x40, 0x10, 25, 1),
+	PIN_FIELD_BASE(50, 50, IOCFG_RT_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(51, 51, IOCFG_RT_BASE, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(52, 52, IOCFG_RT_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(53, 53, IOCFG_RT_BASE, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(54, 54, IOCFG_RT_BASE, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(55, 55, IOCFG_RT_BASE, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(56, 56, IOCFG_RT_BASE, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(57, 57, IOCFG_RT_BASE, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 60, IOCFG_RT_BASE, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(61, 61, IOCFG_RT_BASE, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 66, IOCFG_LB_BASE, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(67, 67, IOCFG_LB_BASE, 0x20, 0x10, 3, 1),
+	PIN_FIELD_BASE(68, 68, IOCFG_LB_BASE, 0x20, 0x10, 4, 1),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x30, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 72, IOCFG_TR_BASE, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(73, 73, IOCFG_TR_BASE, 0x30, 0x10, 15, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 75, IOCFG_TR_BASE, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(76, 76, IOCFG_TR_BASE, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(77, 77, IOCFG_TR_BASE, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(78, 78, IOCFG_TR_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(79, 79, IOCFG_TR_BASE, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(81, 81, IOCFG_TR_BASE, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(82, 82, IOCFG_TR_BASE, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(83, 83, IOCFG_TR_BASE, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(84, 84, IOCFG_TR_BASE, 0x30, 0x10, 13, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 89, IOCFG_TL_BASE, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(90, 90, IOCFG_TL_BASE, 0x30, 0x10, 13, 1),
+	PIN_FIELD_BASE(91, 91, IOCFG_TL_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(92, 92, IOCFG_TL_BASE, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(93, 93, IOCFG_TL_BASE, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(94, 94, IOCFG_TL_BASE, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(95, 95, IOCFG_TL_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(96, 96, IOCFG_TL_BASE, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(97, 97, IOCFG_TL_BASE, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(98, 98, IOCFG_TL_BASE, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(99, 99, IOCFG_TL_BASE, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(100, 100, IOCFG_TL_BASE, 0x30, 0x10, 11, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_smt_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0xf0, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 1, IOCFG_LT_BASE, 0x90, 0x10, 10, 1),
+	PIN_FIELD_BASE(2, 2, IOCFG_LT_BASE, 0x90, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, IOCFG_LB_BASE, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(4, 4, IOCFG_LB_BASE, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0xf0, 0x10, 0, 1),
+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0xf0, 0x10, 1, 1),
+	PIN_FIELD_BASE(7, 7, IOCFG_LT_BASE, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, IOCFG_LT_BASE, 0x90, 0x10, 1, 1),
+	PIN_FIELD_BASE(9, 9, IOCFG_LT_BASE, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(10, 10, IOCFG_LT_BASE, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0xf0, 0x10, 8, 1),
+	PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0xf0, 0x10, 9, 1),
+	PIN_FIELD_BASE(13, 13, IOCFG_RB_BASE, 0xf0, 0x10, 10, 1),
+	PIN_FIELD_BASE(14, 14, IOCFG_RB_BASE, 0xf0, 0x10, 11, 1),
+	PIN_FIELD_BASE(15, 15, IOCFG_RB_BASE, 0xf0, 0x10, 2, 1),
+	PIN_FIELD_BASE(16, 16, IOCFG_RB_BASE, 0xf0, 0x10, 3, 1),
+	PIN_FIELD_BASE(17, 17, IOCFG_RB_BASE, 0xf0, 0x10, 4, 1),
+	PIN_FIELD_BASE(18, 18, IOCFG_RB_BASE, 0xf0, 0x10, 5, 1),
+	PIN_FIELD_BASE(19, 19, IOCFG_RB_BASE, 0xf0, 0x10, 6, 1),
+	PIN_FIELD_BASE(20, 20, IOCFG_RB_BASE, 0xf0, 0x10, 7, 1),
+	PIN_FIELD_BASE(21, 21, IOCFG_RT_BASE, 0xc0, 0x10, 12, 1),
+	PIN_FIELD_BASE(22, 22, IOCFG_RT_BASE, 0xc0, 0x10, 13, 1),
+	PIN_FIELD_BASE(23, 23, IOCFG_RT_BASE, 0xc0, 0x10, 14, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0xc0, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0xc0, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 26, IOCFG_RT_BASE, 0xc0, 0x10, 15, 1),
+	PIN_FIELD_BASE(27, 27, IOCFG_RT_BASE, 0xc0, 0x10, 16, 1),
+	PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0xc0, 0x10, 19, 1),
+	PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0xc0, 0x10, 20, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0xc0, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0xc0, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0xc0, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 36, IOCFG_LT_BASE, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(37, 37, IOCFG_LT_BASE, 0x90, 0x10, 6, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0xf0, 0x10, 18, 1),
+	PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0xf0, 0x10, 19, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0xf0, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 42, IOCFG_RB_BASE, 0xf0, 0x10, 22, 1),
+	PIN_FIELD_BASE(43, 43, IOCFG_RB_BASE, 0xf0, 0x10, 23, 1),
+	PIN_FIELD_BASE(44, 44, IOCFG_RB_BASE, 0xf0, 0x10, 20, 1),
+	PIN_FIELD_BASE(45, 45, IOCFG_RB_BASE, 0xf0, 0x10, 21, 1),
+	PIN_FIELD_BASE(46, 46, IOCFG_RB_BASE, 0xf0, 0x10, 26, 1),
+	PIN_FIELD_BASE(47, 47, IOCFG_RB_BASE, 0xf0, 0x10, 27, 1),
+	PIN_FIELD_BASE(48, 48, IOCFG_RB_BASE, 0xf0, 0x10, 24, 1),
+	PIN_FIELD_BASE(49, 49, IOCFG_RB_BASE, 0xf0, 0x10, 25, 1),
+	PIN_FIELD_BASE(50, 50, IOCFG_RT_BASE, 0xc0, 0x10, 2, 1),
+	PIN_FIELD_BASE(51, 51, IOCFG_RT_BASE, 0xc0, 0x10, 3, 1),
+	PIN_FIELD_BASE(52, 52, IOCFG_RT_BASE, 0xc0, 0x10, 4, 1),
+	PIN_FIELD_BASE(53, 53, IOCFG_RT_BASE, 0xc0, 0x10, 5, 1),
+	PIN_FIELD_BASE(54, 54, IOCFG_RT_BASE, 0xc0, 0x10, 6, 1),
+	PIN_FIELD_BASE(55, 55, IOCFG_RT_BASE, 0xc0, 0x10, 7, 1),
+	PIN_FIELD_BASE(56, 56, IOCFG_RT_BASE, 0xc0, 0x10, 8, 1),
+	PIN_FIELD_BASE(57, 57, IOCFG_RT_BASE, 0xc0, 0x10, 9, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 60, IOCFG_RT_BASE, 0xc0, 0x10, 10, 1),
+	PIN_FIELD_BASE(61, 61, IOCFG_RT_BASE, 0xc0, 0x10, 11, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0xf0, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0xf0, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0xf0, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0xf0, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 66, IOCFG_LB_BASE, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(67, 67, IOCFG_LB_BASE, 0x90, 0x10, 3, 1),
+	PIN_FIELD_BASE(68, 68, IOCFG_LB_BASE, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 72, IOCFG_TR_BASE, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(73, 73, IOCFG_TR_BASE, 0x80, 0x10, 15, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x80, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 75, IOCFG_TR_BASE, 0x80, 0x10, 6, 1),
+	PIN_FIELD_BASE(76, 76, IOCFG_TR_BASE, 0x80, 0x10, 7, 1),
+	PIN_FIELD_BASE(77, 77, IOCFG_TR_BASE, 0x80, 0x10, 8, 1),
+	PIN_FIELD_BASE(78, 78, IOCFG_TR_BASE, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(79, 79, IOCFG_TR_BASE, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x80, 0x10, 9, 1),
+	PIN_FIELD_BASE(81, 81, IOCFG_TR_BASE, 0x80, 0x10, 10, 1),
+	PIN_FIELD_BASE(82, 82, IOCFG_TR_BASE, 0x80, 0x10, 11, 1),
+	PIN_FIELD_BASE(83, 83, IOCFG_TR_BASE, 0x80, 0x10, 12, 1),
+	PIN_FIELD_BASE(84, 84, IOCFG_TR_BASE, 0x80, 0x10, 13, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x80, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 89, IOCFG_TL_BASE, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(90, 90, IOCFG_TL_BASE, 0x70, 0x10, 13, 1),
+	PIN_FIELD_BASE(91, 91, IOCFG_TL_BASE, 0x70, 0x10, 4, 1),
+	PIN_FIELD_BASE(92, 92, IOCFG_TL_BASE, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(93, 93, IOCFG_TL_BASE, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(94, 94, IOCFG_TL_BASE, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(95, 95, IOCFG_TL_BASE, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(96, 96, IOCFG_TL_BASE, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(97, 97, IOCFG_TL_BASE, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(98, 98, IOCFG_TL_BASE, 0x70, 0x10, 9, 1),
+	PIN_FIELD_BASE(99, 99, IOCFG_TL_BASE, 0x70, 0x10, 10, 1),
+	PIN_FIELD_BASE(100, 100, IOCFG_TL_BASE, 0x70, 0x10, 11, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pu_range[] = {
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x50, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 72, IOCFG_TR_BASE, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(73, 73, IOCFG_TR_BASE, 0x50, 0x10, 15, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 75, IOCFG_TR_BASE, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(76, 76, IOCFG_TR_BASE, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(77, 77, IOCFG_TR_BASE, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(78, 78, IOCFG_TR_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(79, 79, IOCFG_TR_BASE, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(81, 81, IOCFG_TR_BASE, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(82, 82, IOCFG_TR_BASE, 0x50, 0x10, 11, 1),
+	PIN_FIELD_BASE(83, 83, IOCFG_TR_BASE, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(84, 84, IOCFG_TR_BASE, 0x50, 0x10, 13, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 89, IOCFG_TL_BASE, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(90, 90, IOCFG_TL_BASE, 0x50, 0x10, 13, 1),
+	PIN_FIELD_BASE(91, 91, IOCFG_TL_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(92, 92, IOCFG_TL_BASE, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(93, 93, IOCFG_TL_BASE, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(94, 94, IOCFG_TL_BASE, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(95, 95, IOCFG_TL_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(96, 96, IOCFG_TL_BASE, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(97, 97, IOCFG_TL_BASE, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(98, 98, IOCFG_TL_BASE, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(99, 99, IOCFG_TL_BASE, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(100, 100, IOCFG_TL_BASE, 0x50, 0x10, 11, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pd_range[] = {
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 72, IOCFG_TR_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(73, 73, IOCFG_TR_BASE, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 75, IOCFG_TR_BASE, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(76, 76, IOCFG_TR_BASE, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(77, 77, IOCFG_TR_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(78, 78, IOCFG_TR_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(79, 79, IOCFG_TR_BASE, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(81, 81, IOCFG_TR_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(82, 82, IOCFG_TR_BASE, 0x40, 0x10, 11, 1),
+	PIN_FIELD_BASE(83, 83, IOCFG_TR_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(84, 84, IOCFG_TR_BASE, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 89, IOCFG_TL_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(90, 90, IOCFG_TL_BASE, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(91, 91, IOCFG_TL_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(92, 92, IOCFG_TL_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(93, 93, IOCFG_TL_BASE, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(94, 94, IOCFG_TL_BASE, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(95, 95, IOCFG_TL_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(96, 96, IOCFG_TL_BASE, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(97, 97, IOCFG_TL_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(98, 98, IOCFG_TL_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(99, 99, IOCFG_TL_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(100, 100, IOCFG_TL_BASE, 0x40, 0x10, 11, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_drv_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(1, 1, IOCFG_LT_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(2, 2, IOCFG_LT_BASE, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(3, 3, IOCFG_LB_BASE, 0x00, 0x10, 0, 1),
+	PIN_FIELD_BASE(4, 4, IOCFG_LB_BASE, 0x00, 0x10, 1, 1),
+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(7, 7, IOCFG_LT_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(8, 8, IOCFG_LT_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(9, 9, IOCFG_LT_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(10, 10, IOCFG_LT_BASE, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(13, 13, IOCFG_RB_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(14, 14, IOCFG_RB_BASE, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(15, 15, IOCFG_RB_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(16, 16, IOCFG_RB_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(17, 17, IOCFG_RB_BASE, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(18, 18, IOCFG_RB_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(19, 19, IOCFG_RB_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(20, 20, IOCFG_RB_BASE, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(21, 21, IOCFG_RT_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(22, 22, IOCFG_RT_BASE, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(23, 23, IOCFG_RT_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(26, 26, IOCFG_RT_BASE, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(27, 27, IOCFG_RT_BASE, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x20, 0x10, 6, 3),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(36, 36, IOCFG_LT_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(37, 37, IOCFG_LT_BASE, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(42, 42, IOCFG_RB_BASE, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(43, 43, IOCFG_RB_BASE, 0x20, 0x10, 12, 3),
+	PIN_FIELD_BASE(44, 44, IOCFG_RB_BASE, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(45, 45, IOCFG_RB_BASE, 0x20, 0x10, 6, 3),
+	PIN_FIELD_BASE(46, 46, IOCFG_RB_BASE, 0x20, 0x10, 21, 3),
+	PIN_FIELD_BASE(47, 47, IOCFG_RB_BASE, 0x20, 0x10, 24, 3),
+	PIN_FIELD_BASE(48, 48, IOCFG_RB_BASE, 0x20, 0x10, 15, 3),
+	PIN_FIELD_BASE(49, 49, IOCFG_RB_BASE, 0x20, 0x10, 18, 3),
+	PIN_FIELD_BASE(50, 50, IOCFG_RT_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(51, 51, IOCFG_RT_BASE, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(52, 52, IOCFG_RT_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(53, 53, IOCFG_RT_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(54, 54, IOCFG_RT_BASE, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(55, 55, IOCFG_RT_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(56, 56, IOCFG_RT_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(57, 57, IOCFG_RT_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(60, 60, IOCFG_RT_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(61, 61, IOCFG_RT_BASE, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(66, 66, IOCFG_LB_BASE, 0x00, 0x10, 2, 3),
+	PIN_FIELD_BASE(67, 67, IOCFG_LB_BASE, 0x00, 0x10, 5, 3),
+	PIN_FIELD_BASE(68, 68, IOCFG_LB_BASE, 0x00, 0x10, 8, 3),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(72, 72, IOCFG_TR_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(73, 73, IOCFG_TR_BASE, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(75, 75, IOCFG_TR_BASE, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(76, 76, IOCFG_TR_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(77, 77, IOCFG_TR_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(78, 78, IOCFG_TR_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(79, 79, IOCFG_TR_BASE, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(81, 81, IOCFG_TR_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(82, 82, IOCFG_TR_BASE, 0x10, 0x10, 3, 3),
+	PIN_FIELD_BASE(83, 83, IOCFG_TR_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(84, 84, IOCFG_TR_BASE, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(89, 89, IOCFG_TL_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(90, 90, IOCFG_TL_BASE, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(91, 91, IOCFG_TL_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(92, 92, IOCFG_TL_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(93, 93, IOCFG_TL_BASE, 0x00, 0x10, 18, 3),
+	PIN_FIELD_BASE(94, 94, IOCFG_TL_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(95, 95, IOCFG_TL_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(96, 96, IOCFG_TL_BASE, 0x00, 0x10, 9, 3),
+	PIN_FIELD_BASE(97, 97, IOCFG_TL_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(98, 98, IOCFG_TL_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(99, 99, IOCFG_TL_BASE, 0x10, 0x10, 2, 3),
+	PIN_FIELD_BASE(100, 100, IOCFG_TL_BASE, 0x10, 0x10, 5, 3),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 1, IOCFG_LT_BASE, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(2, 2, IOCFG_LT_BASE, 0x30, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, IOCFG_LB_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(4, 4, IOCFG_LB_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(7, 7, IOCFG_LT_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, IOCFG_LT_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(9, 9, IOCFG_LT_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(10, 10, IOCFG_LT_BASE, 0x30, 0x10, 3, 1),
+	PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x60, 0x10, 9, 1),
+	PIN_FIELD_BASE(13, 13, IOCFG_RB_BASE, 0x60, 0x10, 10, 1),
+	PIN_FIELD_BASE(14, 14, IOCFG_RB_BASE, 0x60, 0x10, 11, 1),
+	PIN_FIELD_BASE(15, 15, IOCFG_RB_BASE, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(16, 16, IOCFG_RB_BASE, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(17, 17, IOCFG_RB_BASE, 0x60, 0x10, 4, 1),
+	PIN_FIELD_BASE(18, 18, IOCFG_RB_BASE, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(19, 19, IOCFG_RB_BASE, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(20, 20, IOCFG_RB_BASE, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(21, 21, IOCFG_RT_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(22, 22, IOCFG_RT_BASE, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(23, 23, IOCFG_RT_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x40, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 26, IOCFG_RT_BASE, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(27, 27, IOCFG_RT_BASE, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x40, 0x10, 19, 1),
+	PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x40, 0x10, 20, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x40, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x40, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x40, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 36, IOCFG_LT_BASE, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(37, 37, IOCFG_LT_BASE, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x60, 0x10, 18, 1),
+	PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x60, 0x10, 19, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 42, IOCFG_RB_BASE, 0x60, 0x10, 22, 1),
+	PIN_FIELD_BASE(43, 43, IOCFG_RB_BASE, 0x60, 0x10, 23, 1),
+	PIN_FIELD_BASE(44, 44, IOCFG_RB_BASE, 0x60, 0x10, 20, 1),
+	PIN_FIELD_BASE(45, 45, IOCFG_RB_BASE, 0x60, 0x10, 21, 1),
+	PIN_FIELD_BASE(46, 46, IOCFG_RB_BASE, 0x60, 0x10, 26, 1),
+	PIN_FIELD_BASE(47, 47, IOCFG_RB_BASE, 0x60, 0x10, 27, 1),
+	PIN_FIELD_BASE(48, 48, IOCFG_RB_BASE, 0x60, 0x10, 24, 1),
+	PIN_FIELD_BASE(49, 49, IOCFG_RB_BASE, 0x60, 0x10, 25, 1),
+	PIN_FIELD_BASE(50, 50, IOCFG_RT_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(51, 51, IOCFG_RT_BASE, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(52, 52, IOCFG_RT_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(53, 53, IOCFG_RT_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(54, 54, IOCFG_RT_BASE, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(55, 55, IOCFG_RT_BASE, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(56, 56, IOCFG_RT_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(57, 57, IOCFG_RT_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 60, IOCFG_RT_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(61, 61, IOCFG_RT_BASE, 0x40, 0x10, 11, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x60, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x60, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x60, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x60, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 66, IOCFG_LB_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(67, 67, IOCFG_LB_BASE, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(68, 68, IOCFG_LB_BASE, 0x40, 0x10, 4, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x70, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 1, IOCFG_LT_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(2, 2, IOCFG_LT_BASE, 0x40, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, IOCFG_LB_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(4, 4, IOCFG_LB_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(7, 7, IOCFG_LT_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, IOCFG_LT_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(9, 9, IOCFG_LT_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(10, 10, IOCFG_LT_BASE, 0x40, 0x10, 3, 1),
+	PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x70, 0x10, 9, 1),
+	PIN_FIELD_BASE(13, 13, IOCFG_RB_BASE, 0x70, 0x10, 10, 1),
+	PIN_FIELD_BASE(14, 14, IOCFG_RB_BASE, 0x70, 0x10, 11, 1),
+	PIN_FIELD_BASE(15, 15, IOCFG_RB_BASE, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(16, 16, IOCFG_RB_BASE, 0x70, 0x10, 3, 1),
+	PIN_FIELD_BASE(17, 17, IOCFG_RB_BASE, 0x70, 0x10, 4, 1),
+	PIN_FIELD_BASE(18, 18, IOCFG_RB_BASE, 0x70, 0x10, 5, 1),
+	PIN_FIELD_BASE(19, 19, IOCFG_RB_BASE, 0x70, 0x10, 6, 1),
+	PIN_FIELD_BASE(20, 20, IOCFG_RB_BASE, 0x70, 0x10, 7, 1),
+	PIN_FIELD_BASE(21, 21, IOCFG_RT_BASE, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(22, 22, IOCFG_RT_BASE, 0x50, 0x10, 13, 1),
+	PIN_FIELD_BASE(23, 23, IOCFG_RT_BASE, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x50, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x50, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 26, IOCFG_RT_BASE, 0x50, 0x10, 15, 1),
+	PIN_FIELD_BASE(27, 27, IOCFG_RT_BASE, 0x50, 0x10, 16, 1),
+	PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x50, 0x10, 19, 1),
+	PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x50, 0x10, 20, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x50, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x50, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x50, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 36, IOCFG_LT_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(37, 37, IOCFG_LT_BASE, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x70, 0x10, 18, 1),
+	PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x70, 0x10, 19, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 42, IOCFG_RB_BASE, 0x70, 0x10, 22, 1),
+	PIN_FIELD_BASE(43, 43, IOCFG_RB_BASE, 0x70, 0x10, 23, 1),
+	PIN_FIELD_BASE(44, 44, IOCFG_RB_BASE, 0x70, 0x10, 20, 1),
+	PIN_FIELD_BASE(45, 45, IOCFG_RB_BASE, 0x70, 0x10, 21, 1),
+	PIN_FIELD_BASE(46, 46, IOCFG_RB_BASE, 0x70, 0x10, 26, 1),
+	PIN_FIELD_BASE(47, 47, IOCFG_RB_BASE, 0x70, 0x10, 27, 1),
+	PIN_FIELD_BASE(48, 48, IOCFG_RB_BASE, 0x70, 0x10, 24, 1),
+	PIN_FIELD_BASE(49, 49, IOCFG_RB_BASE, 0x70, 0x10, 25, 1),
+	PIN_FIELD_BASE(50, 50, IOCFG_RT_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(51, 51, IOCFG_RT_BASE, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(52, 52, IOCFG_RT_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(53, 53, IOCFG_RT_BASE, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(54, 54, IOCFG_RT_BASE, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(55, 55, IOCFG_RT_BASE, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(56, 56, IOCFG_RT_BASE, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(57, 57, IOCFG_RT_BASE, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 60, IOCFG_RT_BASE, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(61, 61, IOCFG_RT_BASE, 0x50, 0x10, 11, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x70, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x70, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x70, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 66, IOCFG_LB_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(67, 67, IOCFG_LB_BASE, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(68, 68, IOCFG_LB_BASE, 0x50, 0x10, 4, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x80, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 1, IOCFG_LT_BASE, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(2, 2, IOCFG_LT_BASE, 0x50, 0x10, 11, 1),
+	PIN_FIELD_BASE(3, 3, IOCFG_LB_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(4, 4, IOCFG_LB_BASE, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(7, 7, IOCFG_LT_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(8, 8, IOCFG_LT_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(9, 9, IOCFG_LT_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(10, 10, IOCFG_LT_BASE, 0x50, 0x10, 3, 1),
+	PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x80, 0x10, 8, 1),
+	PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x80, 0x10, 9, 1),
+	PIN_FIELD_BASE(13, 13, IOCFG_RB_BASE, 0x80, 0x10, 10, 1),
+	PIN_FIELD_BASE(14, 14, IOCFG_RB_BASE, 0x80, 0x10, 11, 1),
+	PIN_FIELD_BASE(15, 15, IOCFG_RB_BASE, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(16, 16, IOCFG_RB_BASE, 0x80, 0x10, 3, 1),
+	PIN_FIELD_BASE(17, 17, IOCFG_RB_BASE, 0x80, 0x10, 4, 1),
+	PIN_FIELD_BASE(18, 18, IOCFG_RB_BASE, 0x80, 0x10, 5, 1),
+	PIN_FIELD_BASE(19, 19, IOCFG_RB_BASE, 0x80, 0x10, 6, 1),
+	PIN_FIELD_BASE(20, 20, IOCFG_RB_BASE, 0x80, 0x10, 7, 1),
+	PIN_FIELD_BASE(21, 21, IOCFG_RT_BASE, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(22, 22, IOCFG_RT_BASE, 0x60, 0x10, 13, 1),
+	PIN_FIELD_BASE(23, 23, IOCFG_RT_BASE, 0x60, 0x10, 14, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x60, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 26, IOCFG_RT_BASE, 0x60, 0x10, 15, 1),
+	PIN_FIELD_BASE(27, 27, IOCFG_RT_BASE, 0x60, 0x10, 16, 1),
+	PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x60, 0x10, 19, 1),
+	PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x60, 0x10, 20, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x60, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x60, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x60, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 36, IOCFG_LT_BASE, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(37, 37, IOCFG_LT_BASE, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x80, 0x10, 18, 1),
+	PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x80, 0x10, 19, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 42, IOCFG_RB_BASE, 0x80, 0x10, 22, 1),
+	PIN_FIELD_BASE(43, 43, IOCFG_RB_BASE, 0x80, 0x10, 23, 1),
+	PIN_FIELD_BASE(44, 44, IOCFG_RB_BASE, 0x80, 0x10, 20, 1),
+	PIN_FIELD_BASE(45, 45, IOCFG_RB_BASE, 0x80, 0x10, 21, 1),
+	PIN_FIELD_BASE(46, 46, IOCFG_RB_BASE, 0x80, 0x10, 26, 1),
+	PIN_FIELD_BASE(47, 47, IOCFG_RB_BASE, 0x80, 0x10, 27, 1),
+	PIN_FIELD_BASE(48, 48, IOCFG_RB_BASE, 0x80, 0x10, 24, 1),
+	PIN_FIELD_BASE(49, 49, IOCFG_RB_BASE, 0x80, 0x10, 25, 1),
+	PIN_FIELD_BASE(50, 50, IOCFG_RT_BASE, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(51, 51, IOCFG_RT_BASE, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(52, 52, IOCFG_RT_BASE, 0x60, 0x10, 4, 1),
+	PIN_FIELD_BASE(53, 53, IOCFG_RT_BASE, 0x60, 0x10, 5, 1),
+	PIN_FIELD_BASE(54, 54, IOCFG_RT_BASE, 0x60, 0x10, 6, 1),
+	PIN_FIELD_BASE(55, 55, IOCFG_RT_BASE, 0x60, 0x10, 7, 1),
+	PIN_FIELD_BASE(56, 56, IOCFG_RT_BASE, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(57, 57, IOCFG_RT_BASE, 0x60, 0x10, 9, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 60, IOCFG_RT_BASE, 0x60, 0x10, 10, 1),
+	PIN_FIELD_BASE(61, 61, IOCFG_RT_BASE, 0x60, 0x10, 11, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x80, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x80, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 66, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(67, 67, IOCFG_LB_BASE, 0x60, 0x10, 3, 1),
+	PIN_FIELD_BASE(68, 68, IOCFG_LB_BASE, 0x60, 0x10, 4, 1),
+};
+
+static const struct mtk_pin_reg_calc mt7986_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7986_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7986_pin_do_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7986_pin_smt_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7986_pin_ies_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7986_pin_drv_range),
+	[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7986_pin_pu_range),
+	[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7986_pin_pd_range),
+	[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7986_pin_pupd_range),
+	[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7986_pin_r0_range),
+	[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7986_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7986a_pins[] = {
+	MT7986_PIN(0, "SYS_WATCHDOG"),
+	MT7986_PIN(1, "WF2G_LED"),
+	MT7986_PIN(2, "WF5G_LED"),
+	MT7986_PIN(3, "I2C_SCL"),
+	MT7986_PIN(4, "I2C_SDA"),
+	MT7986_PIN(5, "GPIO_0"),
+	MT7986_PIN(6, "GPIO_1"),
+	MT7986_PIN(7, "GPIO_2"),
+	MT7986_PIN(8, "GPIO_3"),
+	MT7986_PIN(9, "GPIO_4"),
+	MT7986_PIN(10, "GPIO_5"),
+	MT7986_PIN(11, "GPIO_6"),
+	MT7986_PIN(12, "GPIO_7"),
+	MT7986_PIN(13, "GPIO_8"),
+	MT7986_PIN(14, "GPIO_9"),
+	MT7986_PIN(15, "GPIO_10"),
+	MT7986_PIN(16, "GPIO_11"),
+	MT7986_PIN(17, "GPIO_12"),
+	MT7986_PIN(18, "GPIO_13"),
+	MT7986_PIN(19, "GPIO_14"),
+	MT7986_PIN(20, "GPIO_15"),
+	MT7986_PIN(21, "PWM0"),
+	MT7986_PIN(22, "PWM1"),
+	MT7986_PIN(23, "SPI0_CLK"),
+	MT7986_PIN(24, "SPI0_MOSI"),
+	MT7986_PIN(25, "SPI0_MISO"),
+	MT7986_PIN(26, "SPI0_CS"),
+	MT7986_PIN(27, "SPI0_HOLD"),
+	MT7986_PIN(28, "SPI0_WP"),
+	MT7986_PIN(29, "SPI1_CLK"),
+	MT7986_PIN(30, "SPI1_MOSI"),
+	MT7986_PIN(31, "SPI1_MISO"),
+	MT7986_PIN(32, "SPI1_CS"),
+	MT7986_PIN(33, "SPI2_CLK"),
+	MT7986_PIN(34, "SPI2_MOSI"),
+	MT7986_PIN(35, "SPI2_MISO"),
+	MT7986_PIN(36, "SPI2_CS"),
+	MT7986_PIN(37, "SPI2_HOLD"),
+	MT7986_PIN(38, "SPI2_WP"),
+	MT7986_PIN(39, "UART0_RXD"),
+	MT7986_PIN(40, "UART0_TXD"),
+	MT7986_PIN(41, "PCIE_PERESET_N"),
+	MT7986_PIN(42, "UART1_RXD"),
+	MT7986_PIN(43, "UART1_TXD"),
+	MT7986_PIN(44, "UART1_CTS"),
+	MT7986_PIN(45, "UART1_RTS"),
+	MT7986_PIN(46, "UART2_RXD"),
+	MT7986_PIN(47, "UART2_TXD"),
+	MT7986_PIN(48, "UART2_CTS"),
+	MT7986_PIN(49, "UART2_RTS"),
+	MT7986_PIN(50, "EMMC_DATA_0"),
+	MT7986_PIN(51, "EMMC_DATA_1"),
+	MT7986_PIN(52, "EMMC_DATA_2"),
+	MT7986_PIN(53, "EMMC_DATA_3"),
+	MT7986_PIN(54, "EMMC_DATA_4"),
+	MT7986_PIN(55, "EMMC_DATA_5"),
+	MT7986_PIN(56, "EMMC_DATA_6"),
+	MT7986_PIN(57, "EMMC_DATA_7"),
+	MT7986_PIN(58, "EMMC_CMD"),
+	MT7986_PIN(59, "EMMC_CK"),
+	MT7986_PIN(60, "EMMC_DSL"),
+	MT7986_PIN(61, "EMMC_RSTB"),
+	MT7986_PIN(62, "PCM_DTX"),
+	MT7986_PIN(63, "PCM_DRX"),
+	MT7986_PIN(64, "PCM_CLK"),
+	MT7986_PIN(65, "PCM_FS"),
+	MT7986_PIN(66, "MT7531_INT"),
+	MT7986_PIN(67, "SMI_MDC"),
+	MT7986_PIN(68, "SMI_MDIO"),
+	MT7986_PIN(69, "WF0_DIG_RESETB"),
+	MT7986_PIN(70, "WF0_CBA_RESETB"),
+	MT7986_PIN(71, "WF0_XO_REQ"),
+	MT7986_PIN(72, "WF0_TOP_CLK"),
+	MT7986_PIN(73, "WF0_TOP_DATA"),
+	MT7986_PIN(74, "WF0_HB1"),
+	MT7986_PIN(75, "WF0_HB2"),
+	MT7986_PIN(76, "WF0_HB3"),
+	MT7986_PIN(77, "WF0_HB4"),
+	MT7986_PIN(78, "WF0_HB0"),
+	MT7986_PIN(79, "WF0_HB0_B"),
+	MT7986_PIN(80, "WF0_HB5"),
+	MT7986_PIN(81, "WF0_HB6"),
+	MT7986_PIN(82, "WF0_HB7"),
+	MT7986_PIN(83, "WF0_HB8"),
+	MT7986_PIN(84, "WF0_HB9"),
+	MT7986_PIN(85, "WF0_HB10"),
+	MT7986_PIN(86, "WF1_DIG_RESETB"),
+	MT7986_PIN(87, "WF1_CBA_RESETB"),
+	MT7986_PIN(88, "WF1_XO_REQ"),
+	MT7986_PIN(89, "WF1_TOP_CLK"),
+	MT7986_PIN(90, "WF1_TOP_DATA"),
+	MT7986_PIN(91, "WF1_HB1"),
+	MT7986_PIN(92, "WF1_HB2"),
+	MT7986_PIN(93, "WF1_HB3"),
+	MT7986_PIN(94, "WF1_HB4"),
+	MT7986_PIN(95, "WF1_HB0"),
+	MT7986_PIN(96, "WF1_HB0_B"),
+	MT7986_PIN(97, "WF1_HB5"),
+	MT7986_PIN(98, "WF1_HB6"),
+	MT7986_PIN(99, "WF1_HB7"),
+	MT7986_PIN(100, "WF1_HB8"),
+};
+
+static const struct mtk_pin_desc mt7986b_pins[] = {
+	MT7986_PIN(0, "SYS_WATCHDOG"),
+	MT7986_PIN(1, "WF2G_LED"),
+	MT7986_PIN(2, "WF5G_LED"),
+	MT7986_PIN(3, "I2C_SCL"),
+	MT7986_PIN(4, "I2C_SDA"),
+	MT7986_PIN(5, "GPIO_0"),
+	MT7986_PIN(6, "GPIO_1"),
+	MT7986_PIN(7, "GPIO_2"),
+	MT7986_PIN(8, "GPIO_3"),
+	MT7986_PIN(9, "GPIO_4"),
+	MT7986_PIN(10, "GPIO_5"),
+	MT7986_PIN(11, "GPIO_6"),
+	MT7986_PIN(12, "GPIO_7"),
+	MT7986_PIN(13, "GPIO_8"),
+	MT7986_PIN(14, "GPIO_9"),
+	MT7986_PIN(15, "GPIO_10"),
+	MT7986_PIN(16, "GPIO_11"),
+	MT7986_PIN(17, "GPIO_12"),
+	MT7986_PIN(18, "GPIO_13"),
+	MT7986_PIN(19, "GPIO_14"),
+	MT7986_PIN(20, "GPIO_15"),
+	MT7986_PIN(21, "PWM0"),
+	MT7986_PIN(22, "PWM1"),
+	MT7986_PIN(23, "SPI0_CLK"),
+	MT7986_PIN(24, "SPI0_MOSI"),
+	MT7986_PIN(25, "SPI0_MISO"),
+	MT7986_PIN(26, "SPI0_CS"),
+	MT7986_PIN(27, "SPI0_HOLD"),
+	MT7986_PIN(28, "SPI0_WP"),
+	MT7986_PIN(29, "SPI1_CLK"),
+	MT7986_PIN(30, "SPI1_MOSI"),
+	MT7986_PIN(31, "SPI1_MISO"),
+	MT7986_PIN(32, "SPI1_CS"),
+	MT7986_PIN(33, "SPI2_CLK"),
+	MT7986_PIN(34, "SPI2_MOSI"),
+	MT7986_PIN(35, "SPI2_MISO"),
+	MT7986_PIN(36, "SPI2_CS"),
+	MT7986_PIN(37, "SPI2_HOLD"),
+	MT7986_PIN(38, "SPI2_WP"),
+	MT7986_PIN(39, "UART0_RXD"),
+	MT7986_PIN(40, "UART0_TXD"),
+	MT7986_NOT_BALLOUT_PIN(41),
+	MT7986_NOT_BALLOUT_PIN(42),
+	MT7986_NOT_BALLOUT_PIN(43),
+	MT7986_NOT_BALLOUT_PIN(44),
+	MT7986_NOT_BALLOUT_PIN(45),
+	MT7986_NOT_BALLOUT_PIN(46),
+	MT7986_NOT_BALLOUT_PIN(47),
+	MT7986_NOT_BALLOUT_PIN(48),
+	MT7986_NOT_BALLOUT_PIN(49),
+	MT7986_NOT_BALLOUT_PIN(50),
+	MT7986_NOT_BALLOUT_PIN(51),
+	MT7986_NOT_BALLOUT_PIN(52),
+	MT7986_NOT_BALLOUT_PIN(53),
+	MT7986_NOT_BALLOUT_PIN(54),
+	MT7986_NOT_BALLOUT_PIN(55),
+	MT7986_NOT_BALLOUT_PIN(56),
+	MT7986_NOT_BALLOUT_PIN(57),
+	MT7986_NOT_BALLOUT_PIN(58),
+	MT7986_NOT_BALLOUT_PIN(59),
+	MT7986_NOT_BALLOUT_PIN(60),
+	MT7986_NOT_BALLOUT_PIN(61),
+	MT7986_NOT_BALLOUT_PIN(62),
+	MT7986_NOT_BALLOUT_PIN(63),
+	MT7986_NOT_BALLOUT_PIN(64),
+	MT7986_NOT_BALLOUT_PIN(65),
+	MT7986_PIN(66, "MT7531_INT"),
+	MT7986_PIN(67, "SMI_MDC"),
+	MT7986_PIN(68, "SMI_MDIO"),
+	MT7986_PIN(69, "WF0_DIG_RESETB"),
+	MT7986_PIN(70, "WF0_CBA_RESETB"),
+	MT7986_PIN(71, "WF0_XO_REQ"),
+	MT7986_PIN(72, "WF0_TOP_CLK"),
+	MT7986_PIN(73, "WF0_TOP_DATA"),
+	MT7986_PIN(74, "WF0_HB1"),
+	MT7986_PIN(75, "WF0_HB2"),
+	MT7986_PIN(76, "WF0_HB3"),
+	MT7986_PIN(77, "WF0_HB4"),
+	MT7986_PIN(78, "WF0_HB0"),
+	MT7986_PIN(79, "WF0_HB0_B"),
+	MT7986_PIN(80, "WF0_HB5"),
+	MT7986_PIN(81, "WF0_HB6"),
+	MT7986_PIN(82, "WF0_HB7"),
+	MT7986_PIN(83, "WF0_HB8"),
+	MT7986_PIN(84, "WF0_HB9"),
+	MT7986_PIN(85, "WF0_HB10"),
+	MT7986_PIN(86, "WF1_DIG_RESETB"),
+	MT7986_PIN(87, "WF1_CBA_RESETB"),
+	MT7986_PIN(88, "WF1_XO_REQ"),
+	MT7986_PIN(89, "WF1_TOP_CLK"),
+	MT7986_PIN(90, "WF1_TOP_DATA"),
+	MT7986_PIN(91, "WF1_HB1"),
+	MT7986_PIN(92, "WF1_HB2"),
+	MT7986_PIN(93, "WF1_HB3"),
+	MT7986_PIN(94, "WF1_HB4"),
+	MT7986_PIN(95, "WF1_HB0"),
+	MT7986_PIN(96, "WF1_HB0_B"),
+	MT7986_PIN(97, "WF1_HB5"),
+	MT7986_PIN(98, "WF1_HB6"),
+	MT7986_PIN(99, "WF1_HB7"),
+	MT7986_PIN(100, "WF1_HB8"),
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+static int mt7986_watchdog_pins[] = { 0, };
+static int mt7986_watchdog_funcs[] = { 1, };
+
+static int mt7986_wifi_led_pins[] = { 1, 2, };
+static int mt7986_wifi_led_funcs[] = { 1, 1, };
+
+static int mt7986_i2c_pins[] = { 3, 4, };
+static int mt7986_i2c_funcs[] = { 1, 1, };
+
+static int mt7986_uart1_0_pins[] = { 7, 8, 9, 10, };
+static int mt7986_uart1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_spi1_0_pins[] = { 11, 12, 13, 14, };
+static int mt7986_spi1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_pwm1_1_pins[] = { 20, };
+static int mt7986_pwm1_1_funcs[] = { 2, };
+
+static int mt7986_pwm0_pins[] = { 21, };
+static int mt7986_pwm0_funcs[] = { 1, };
+
+static int mt7986_pwm1_0_pins[] = { 22, };
+static int mt7986_pwm1_0_funcs[] = { 1, };
+
+static int mt7986_emmc_45_pins[] = {
+	22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, };
+static int mt7986_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_snfi_pins[] = { 23, 24, 25, 26, 27, 28, };
+static int mt7986_snfi_funcs[] = { 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_spi1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_spi1_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_uart1_1_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi0_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_spi0_wp_hold_pins[] = { 37, 38, };
+static int mt7986_spi0_wp_hold_funcs[] = { 1, 1, };
+
+static int mt7986_uart2_1_pins[] = { 33, 34, 35, 36, };
+static int mt7986_uart2_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_3_rx_tx_pins[] = { 35, 36, };
+static int mt7986_uart1_3_rx_tx_funcs[] = { 2, 2, };
+
+static int mt7986_uart1_3_cts_rts_pins[] = { 37, 38, };
+static int mt7986_uart1_3_cts_rts_funcs[] = { 2, 2, };
+
+static int mt7986_spi1_3_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi1_3_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_uart0_pins[] = { 39, 40, };
+static int mt7986_uart0_funcs[] = { 1, 1, };
+
+static int mt7986_pcie_reset_pins[] = { 41, };
+static int mt7986_pcie_reset_funcs[] = { 1, };
+
+static int mt7986_uart1_pins[] = { 42, 43, 44, 45, };
+static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart2_pins[] = { 46, 47, 48, 49, };
+static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_emmc_51_pins[] = {
+	50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, };
+static int mt7986_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_pcm_pins[] = { 62, 63, 64, 65, };
+static int mt7986_pcm_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_i2s_pins[] = { 62, 63, 64, 65, };
+static int mt7986_i2s_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_switch_int_pins[] = { 66, };
+static int mt7986_switch_int_funcs[] = { 1, };
+
+static int mt7986_mdc_mdio_pins[] = { 67, 68, };
+static int mt7986_mdc_mdio_funcs[] = { 1, 1, };
+
+static int mt7986_wf_2g_pins[] = {74, 75, 76, 77, 78, 79, 80, 81, 82, 83, };
+static int mt7986_wf_2g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_5g_pins[] = {91, 92, 93, 94, 95, 96, 97, 98, 99, 100, };
+static int mt7986_wf_5g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_dbdc_pins[] = {
+	74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, };
+static int mt7986_wf_dbdc_funcs[] = {
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_pcie_clk_pins[] = { 9, };
+static int mt7986_pcie_clk_funcs[] = { 1, };
+
+static int mt7986_pcie_wake_pins[] = { 10, };
+static int mt7986_pcie_wake_funcs[] = { 1, };
+
+static const struct group_desc mt7986_groups[] = {
+	PINCTRL_PIN_GROUP("watchdog", mt7986_watchdog),
+	PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led),
+	PINCTRL_PIN_GROUP("i2c", mt7986_i2c),
+	PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0),
+	PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk),
+	PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake),
+	PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0),
+	PINCTRL_PIN_GROUP("pwm1_1", mt7986_pwm1_1),
+	PINCTRL_PIN_GROUP("pwm0", mt7986_pwm0),
+	PINCTRL_PIN_GROUP("pwm1_0", mt7986_pwm1_0),
+	PINCTRL_PIN_GROUP("emmc_45", mt7986_emmc_45),
+	PINCTRL_PIN_GROUP("snfi", mt7986_snfi),
+	PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1),
+	PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1),
+	PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2),
+	PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2),
+	PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0),
+	PINCTRL_PIN_GROUP("spi0", mt7986_spi0),
+	PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold),
+	PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1),
+	PINCTRL_PIN_GROUP("uart1_3_rx_tx", mt7986_uart1_3_rx_tx),
+	PINCTRL_PIN_GROUP("uart1_3_cts_rts", mt7986_uart1_3_cts_rts),
+	PINCTRL_PIN_GROUP("spi1_3", mt7986_spi1_3),
+	PINCTRL_PIN_GROUP("uart0", mt7986_uart0),
+	PINCTRL_PIN_GROUP("switch_int", mt7986_switch_int),
+	PINCTRL_PIN_GROUP("mdc_mdio", mt7986_mdc_mdio),
+	PINCTRL_PIN_GROUP("pcie_pereset", mt7986_pcie_reset),
+	PINCTRL_PIN_GROUP("uart1", mt7986_uart1),
+	PINCTRL_PIN_GROUP("uart2", mt7986_uart2),
+	PINCTRL_PIN_GROUP("emmc_51", mt7986_emmc_51),
+	PINCTRL_PIN_GROUP("pcm", mt7986_pcm),
+	PINCTRL_PIN_GROUP("i2s", mt7986_i2s),
+	PINCTRL_PIN_GROUP("wf_2g", mt7986_wf_2g),
+	PINCTRL_PIN_GROUP("wf_5g", mt7986_wf_5g),
+	PINCTRL_PIN_GROUP("wf_dbdc", mt7986_wf_dbdc),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+
+static const char *mt7986_audio_groups[] = { "pcm", "i2s" };
+static const char *mt7986_emmc_groups[] = { "emmc_45", "emmc_51", };
+static const char *mt7986_ethernet_groups[] = { "switch_int", "mdc_mdio", };
+static const char *mt7986_i2c_groups[] = { "i2c", };
+static const char *mt7986_led_groups[] = { "wifi_led", };
+static const char *mt7986_flash_groups[] = { "snfi", };
+static const char *mt7986_pcie_groups[] = {
+	"pcie_clk", "pcie_wake", "pcie_pereset" };
+static const char *mt7986_pwm_groups[] = { "pwm0", "pwm1_0", "pwm1_1", };
+static const char *mt7986_spi_groups[] = {
+	"spi0", "spi0_wp_hold", "spi1_0", "spi1_1", "spi1_2", "spi1_3", };
+
+static const char *mt7986_uart_groups[] = {
+	"uart1_0", "uart1_1", "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts",
+	"uart2_0", "uart2_1", "uart0", "uart1", "uart2",
+};
+static const char *mt7986_wdt_groups[] = { "watchdog", };
+static const char *mt7986_wf_groups[] = { "wf_2g", "wf_5g", "wf_dbdc", };
+
+static const struct function_desc mt7986_functions[] = {
+	{"audio", mt7986_audio_groups, ARRAY_SIZE(mt7986_audio_groups)},
+	{"emmc", mt7986_emmc_groups, ARRAY_SIZE(mt7986_emmc_groups)},
+	{"eth", mt7986_ethernet_groups, ARRAY_SIZE(mt7986_ethernet_groups)},
+	{"i2c", mt7986_i2c_groups, ARRAY_SIZE(mt7986_i2c_groups)},
+	{"led", mt7986_led_groups, ARRAY_SIZE(mt7986_led_groups)},
+	{"flash", mt7986_flash_groups, ARRAY_SIZE(mt7986_flash_groups)},
+	{"pcie", mt7986_pcie_groups, ARRAY_SIZE(mt7986_pcie_groups)},
+	{"pwm", mt7986_pwm_groups, ARRAY_SIZE(mt7986_pwm_groups)},
+	{"spi", mt7986_spi_groups, ARRAY_SIZE(mt7986_spi_groups)},
+	{"uart", mt7986_uart_groups, ARRAY_SIZE(mt7986_uart_groups)},
+	{"watchdog", mt7986_wdt_groups, ARRAY_SIZE(mt7986_wdt_groups)},
+	{"wifi", mt7986_wf_groups, ARRAY_SIZE(mt7986_wf_groups)},
+};
+
+static const struct mtk_eint_hw mt7986a_eint_hw = {
+	.port_mask = 7,
+	.ports = 7,
+	.ap_num = ARRAY_SIZE(mt7986a_pins),
+	.db_cnt = 16,
+};
+
+static const struct mtk_eint_hw mt7986b_eint_hw = {
+	.port_mask = 7,
+	.ports = 7,
+	.ap_num = ARRAY_SIZE(mt7986b_pins),
+	.db_cnt = 16,
+};
+
+static struct mtk_pin_soc mt7986a_data = {
+	.reg_cal = mt7986_reg_cals,
+	.pins = mt7986a_pins,
+	.npins = ARRAY_SIZE(mt7986a_pins),
+	.grps = mt7986_groups,
+	.ngrps = ARRAY_SIZE(mt7986_groups),
+	.funcs = mt7986_functions,
+	.nfuncs = ARRAY_SIZE(mt7986_functions),
+	.eint_hw = &mt7986a_eint_hw,
+	.gpio_m = 0,
+	.ies_present = false,
+	.base_names = mt7986_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+	.bias_set_combo = mtk_pinconf_bias_set_combo,
+	.bias_get_combo = mtk_pinconf_bias_get_combo,
+	.drive_set = mtk_pinconf_drive_set_rev1,
+	.drive_get = mtk_pinconf_drive_get_rev1,
+	.adv_pull_get = mtk_pinconf_adv_pull_get,
+	.adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static struct mtk_pin_soc mt7986b_data = {
+	.reg_cal = mt7986_reg_cals,
+	.pins = mt7986b_pins,
+	.npins = ARRAY_SIZE(mt7986b_pins),
+	.grps = mt7986_groups,
+	.ngrps = ARRAY_SIZE(mt7986_groups),
+	.funcs = mt7986_functions,
+	.nfuncs = ARRAY_SIZE(mt7986_functions),
+	.eint_hw = &mt7986b_eint_hw,
+	.gpio_m = 0,
+	.ies_present = false,
+	.base_names = mt7986_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+	.bias_set_combo = mtk_pinconf_bias_set_combo,
+	.bias_get_combo = mtk_pinconf_bias_get_combo,
+	.drive_set = mtk_pinconf_drive_set_rev1,
+	.drive_get = mtk_pinconf_drive_get_rev1,
+	.adv_pull_get = mtk_pinconf_adv_pull_get,
+	.adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static const struct of_device_id mt7986a_pinctrl_of_match[] = {
+	{.compatible = "mediatek,mt7986a-pinctrl",},
+	{}
+};
+
+static const struct of_device_id mt7986b_pinctrl_of_match[] = {
+	{.compatible = "mediatek,mt7986b-pinctrl",},
+	{}
+};
+
+static int mt7986a_pinctrl_probe(struct platform_device *pdev)
+{
+	return mtk_moore_pinctrl_probe(pdev, &mt7986a_data);
+}
+
+static int mt7986b_pinctrl_probe(struct platform_device *pdev)
+{
+	return mtk_moore_pinctrl_probe(pdev, &mt7986b_data);
+}
+
+static struct platform_driver mt7986a_pinctrl_driver = {
+	.driver = {
+		.name = "mt7986a-pinctrl",
+		.of_match_table = mt7986a_pinctrl_of_match,
+	},
+	.probe = mt7986a_pinctrl_probe,
+};
+
+static struct platform_driver mt7986b_pinctrl_driver = {
+	.driver = {
+		.name = "mt7986b-pinctrl",
+		.of_match_table = mt7986b_pinctrl_of_match,
+	},
+	.probe = mt7986b_pinctrl_probe,
+};
+
+static int __init mt7986a_pinctrl_init(void)
+{
+	return platform_driver_register(&mt7986a_pinctrl_driver);
+}
+
+static int __init mt7986b_pinctrl_init(void)
+{
+	return platform_driver_register(&mt7986b_pinctrl_driver);
+}
+
+arch_initcall(mt7986a_pinctrl_init);
+arch_initcall(mt7986b_pinctrl_init);
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:55 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:55 +0800
Subject: [v2,10/12] dt-bindings: watchdog: Add compatible for Mediatek MT7986
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-11-sam.shih@mediatek.com>

This commit adds dt-binding documentation of watchdog for Mediatek MT7986
SoC Platform.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>

---
v2: added an Acked-by tag and a Reviewed-by tag

---
 Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
index 416d716403f6..a4e31ce96e0e 100644
--- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
@@ -13,6 +13,7 @@ Required properties:
 	"mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
 	"mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
 	"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
+	"mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986
 	"mediatek,mt8183-wdt": for MT8183
 	"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
 	"mediatek,mt8192-wdt": for MT8192
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:54 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:54 +0800
Subject: [v2,09/12] dt-bindings: serial: Add compatible for Mediatek MT7986
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-10-sam.shih@mediatek.com>

This commit adds dt-binding documentation of uart for Mediatek MT7986 SoC
Platform.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
 Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
index 64c4fb59acd1..b3a0bfef0d54 100644
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
@@ -15,6 +15,7 @@ Required properties:
   * "mediatek,mt7622-uart" for MT7622 compatible UARTS
   * "mediatek,mt7623-uart" for MT7623 compatible UARTS
   * "mediatek,mt7629-uart" for MT7629 compatible UARTS
+  * "mediatek,mt7986-uart", "mediatek,mt6577-uart" for MT7986 compatible UARTS
   * "mediatek,mt8127-uart" for MT8127 compatible UARTS
   * "mediatek,mt8135-uart" for MT8135 compatible UARTS
   * "mediatek,mt8173-uart" for MT8173 compatible UARTS
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:56 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:56 +0800
Subject: [v2,11/12] arm64: dts: mediatek: add mt7986a support
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-12-sam.shih@mediatek.com>

Add basic chip support for Mediatek mt7986a, include
uart nodes with correct clocks, rng node with correct clock,
and watchdog node and mt7986a pinctrl node.

Add cpu node, timer node, gic node, psci and reserved-memory node
for ARM Trusted Firmware,

Add clock controller nodes, include 40M clock source, topckgen, infracfg,
apmixedsys and ethernet subsystem.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
v2: modified clock and uart node due to clock driver updated

---
 arch/arm64/boot/dts/mediatek/Makefile        |   1 +
 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts |  49 ++++
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi    | 227 +++++++++++++++++++
 3 files changed, 277 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986a.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 4f68ebed2e31..e6c3a73b9e4a 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -7,6 +7,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
new file mode 100644
index 000000000000..a58347c09ab2
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih at mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986a.dtsi"
+
+/ {
+	model = "MediaTek MT7986a RFB";
+	compatible = "mediatek,mt7986a-rfb";
+	chosen {
+		bootargs = "console=ttyS0,115200n1 loglevel=8  \
+				earlycon=uart8250,mmio32,0x11002000";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2_pins>;
+	status = "okay";
+};
+
+&pio {
+	uart1_pins: uart1-pins-42-to-45 {
+		mux {
+			function = "uart";
+			groups = "uart1";
+		};
+	};
+
+	uart2_pins: uart1-pins-46-to-49 {
+		mux {
+			function = "uart";
+			groups = "uart2";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
new file mode 100644
index 000000000000..dfe3e7101031
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih at mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt7986-clk.h>
+
+/ {
+	compatible = "mediatek,mt7986a";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clk40m: oscillator at 0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <40000000>;
+		clock-output-names = "clkxtal";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x2>;
+			#cooling-cells = <2>;
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			enable-method = "psci";
+			compatible = "arm,cortex-a53";
+			reg = <0x3>;
+			#cooling-cells = <2>;
+		};
+	};
+
+	psci {
+		compatible  = "arm,psci-0.2";
+		method      = "smc";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+		secmon_reserved: secmon at 43000000 {
+			reg = <0 0x43000000 0 0x30000>;
+			no-map;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		clock-frequency = <13000000>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		ranges;
+
+		gic: interrupt-controller at c000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
+			interrupt-controller;
+			reg = <0 0x0c000000 0 0x40000>,
+			      <0 0x0c080000 0 0x200000>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		infracfg: infracfg at 10001000 {
+			compatible = "mediatek,mt7986-infracfg", "syscon";
+			reg = <0 0x10001000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		topckgen: topckgen at 1001b000 {
+			compatible = "mediatek,mt7986-topckgen", "syscon";
+			reg = <0 0x1001B000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		watchdog: watchdog at 1001c000 {
+			compatible = "mediatek,mt7986-wdt",
+				     "mediatek,mt6589-wdt";
+			reg = <0 0x1001c000 0 0x1000>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			#reset-cells = <1>;
+			status = "disabled";
+		};
+
+		apmixedsys: apmixedsys at 1001e000 {
+			compatible = "mediatek,mt7986-apmixedsys";
+			reg = <0 0x1001E000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		pio: pinctrl at 1001f000 {
+			compatible = "mediatek,mt7986a-pinctrl";
+			reg = <0 0x1001f000 0 0x1000>,
+			      <0 0x11c30000 0 0x1000>,
+			      <0 0x11c40000 0 0x1000>,
+			      <0 0x11e20000 0 0x1000>,
+			      <0 0x11e30000 0 0x1000>,
+			      <0 0x11f00000 0 0x1000>,
+			      <0 0x11f10000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rb_base",
+				    "iocfg_lt_base", "iocfg_lb_base", "iocfg_tr_base",
+				    "iocfg_tl_base", "eint";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pio 0 0 100>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&gic>;
+			#interrupt-cells = <2>;
+		};
+
+		sgmiisys0: syscon at 10060000 {
+			compatible = "mediatek,mt7986-sgmiisys_0",
+				     "syscon";
+			reg = <0 0x10060000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		sgmiisys1: syscon at 10070000 {
+			compatible = "mediatek,mt7986-sgmiisys_1",
+				     "syscon";
+			reg = <0 0x10070000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		trng: trng at 1020f000 {
+			compatible = "mediatek,mt7986-rng",
+				     "mediatek,mt7623-rng";
+			reg = <0 0x1020f000 0 0x100>;
+			clocks = <&infracfg CLK_INFRA_TRNG_CK>;
+			clock-names = "rng";
+			status = "disabled";
+		};
+
+		uart0: serial at 11002000 {
+			compatible = "mediatek,mt7986-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11002000 0 0x400>;
+			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_UART0_SEL>,
+				 <&infracfg CLK_INFRA_UART0_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
+					  <&infracfg CLK_INFRA_UART0_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
+						 <&topckgen CLK_TOP_UART_SEL>;
+			status = "disabled";
+		};
+
+		uart1: serial at 11003000 {
+			compatible = "mediatek,mt7986-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11003000 0 0x400>;
+			interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_UART1_SEL>,
+				 <&infracfg CLK_INFRA_UART1_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&infracfg CLK_INFRA_UART1_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
+			status = "disabled";
+		};
+
+		uart2: serial at 11004000 {
+			compatible = "mediatek,mt7986-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11004000 0 0x400>;
+			interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_UART2_SEL>,
+				 <&infracfg CLK_INFRA_UART2_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&infracfg CLK_INFRA_UART2_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
+			status = "disabled";
+		};
+
+		ethsys: syscon at 15000000 {
+			 #address-cells = <1>;
+			 #size-cells = <1>;
+			 compatible = "mediatek,mt7986-ethsys",
+				      "syscon";
+			 reg = <0 0x15000000 0 0x1000>;
+			 #clock-cells = <1>;
+			 #reset-cells = <1>;
+		};
+
+	};
+
+};
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:53 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:53 +0800
Subject: [v2,08/12] dt-bindings: rng: mediatek: add mt7986 to mtk rng binding
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-9-sam.shih@mediatek.com>

Add RNG binding for MT7986 SoC.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
v2: patch v1 has been applied

---
 Documentation/devicetree/bindings/rng/mtk-rng.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/rng/mtk-rng.yaml b/Documentation/devicetree/bindings/rng/mtk-rng.yaml
index 61888e07bda0..bb32491ee8ae 100644
--- a/Documentation/devicetree/bindings/rng/mtk-rng.yaml
+++ b/Documentation/devicetree/bindings/rng/mtk-rng.yaml
@@ -21,6 +21,7 @@ properties:
           - enum:
               - mediatek,mt7622-rng
               - mediatek,mt7629-rng
+              - mediatek,mt7986-rng
               - mediatek,mt8365-rng
               - mediatek,mt8516-rng
           - const: mediatek,mt7623-rng
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 17 00:45:57 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 17 Aug 2021 15:45:57 +0800
Subject: [v2,12/12] arm64: dts: mediatek: add mt7986b support
In-Reply-To: <20210817074557.30953-1-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
Message-ID: <20210817074557.30953-13-sam.shih@mediatek.com>

Add basic chip support for Mediatek mt7986b, include
uart nodes with correct clocks, rng node with correct clock,
and watchdog node and mt7986b pinctrl node.

Add cpu node, timer node, gic node, psci and reserved-memory node
for ARM Trusted Firmware,

Add clock controller nodes, include 40M clock source, topckgen, infracfg,
apmixedsys and ethernet subsystem.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
v2: modified clock and uart node due to clock driver updated

---
 arch/arm64/boot/dts/mediatek/Makefile        |   1 +
 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts |  21 ++
 arch/arm64/boot/dts/mediatek/mt7986b.dtsi    | 227 +++++++++++++++++++
 3 files changed, 249 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt7986b.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index e6c3a73b9e4a..d555e43d1ccc 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-x20-dev.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-bananapi-bpi-r64.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
new file mode 100644
index 000000000000..8296f1d27e77
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih at mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986b.dtsi"
+
+/ {
+	model = "MediaTek MT7986b RFB";
+	compatible = "mediatek,mt7986b-rfb";
+	chosen {
+		bootargs = "console=ttyS0,115200n1 loglevel=8  \
+				earlycon=uart8250,mmio32,0x11002000";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
new file mode 100644
index 000000000000..1fd98fb7ba84
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih at mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt7986-clk.h>
+
+/ {
+	compatible = "mediatek,mt7986b";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clk40m: oscillator at 0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <40000000>;
+		clock-output-names = "clkxtal";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			enable-method = "psci";
+			reg = <0x2>;
+			#cooling-cells = <2>;
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			enable-method = "psci";
+			compatible = "arm,cortex-a53";
+			reg = <0x3>;
+			#cooling-cells = <2>;
+		};
+	};
+
+	psci {
+		compatible  = "arm,psci-0.2";
+		method      = "smc";
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+		secmon_reserved: secmon at 43000000 {
+			reg = <0 0x43000000 0 0x30000>;
+			no-map;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		clock-frequency = <13000000>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		ranges;
+
+		gic: interrupt-controller at c000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			interrupt-parent = <&gic>;
+			interrupt-controller;
+			reg = <0 0x0c000000 0 0x40000>,
+			      <0 0x0c080000 0 0x200000>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		infracfg: infracfg at 10001000 {
+			compatible = "mediatek,mt7986-infracfg", "syscon";
+			reg = <0 0x10001000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		topckgen: topckgen at 1001b000 {
+			compatible = "mediatek,mt7986-topckgen", "syscon";
+			reg = <0 0x1001B000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		watchdog: watchdog at 1001c000 {
+			compatible = "mediatek,mt7986-wdt",
+				     "mediatek,mt6589-wdt";
+			reg = <0 0x1001c000 0 0x1000>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+			#reset-cells = <1>;
+			status = "disabled";
+		};
+
+		apmixedsys: apmixedsys at 1001e000 {
+			compatible = "mediatek,mt7986-apmixedsys";
+			reg = <0 0x1001E000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		pio: pinctrl at 1001f000 {
+			compatible = "mediatek,mt7986b-pinctrl";
+			reg = <0 0x1001f000 0 0x1000>,
+			      <0 0x11c30000 0 0x1000>,
+			      <0 0x11c40000 0 0x1000>,
+			      <0 0x11e20000 0 0x1000>,
+			      <0 0x11e30000 0 0x1000>,
+			      <0 0x11f00000 0 0x1000>,
+			      <0 0x11f10000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rb_base",
+				    "iocfg_lt_base", "iocfg_lb_base", "iocfg_tr_base",
+				    "iocfg_tl_base", "eint";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pio 0 0 41>, <&pio 66 66 35>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&gic>;
+			#interrupt-cells = <2>;
+		};
+
+		sgmiisys0: syscon at 10060000 {
+			compatible = "mediatek,mt7986-sgmiisys_0",
+				     "syscon";
+			reg = <0 0x10060000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		sgmiisys1: syscon at 10070000 {
+			compatible = "mediatek,mt7986-sgmiisys_1",
+				     "syscon";
+			reg = <0 0x10070000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		trng: trng at 1020f000 {
+			compatible = "mediatek,mt7986-rng",
+				     "mediatek,mt7623-rng";
+			reg = <0 0x1020f000 0 0x100>;
+			clocks = <&infracfg CLK_INFRA_TRNG_CK>;
+			clock-names = "rng";
+			status = "disabled";
+		};
+
+		uart0: serial at 11002000 {
+			compatible = "mediatek,mt7986-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11002000 0 0x400>;
+			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_UART0_SEL>,
+				 <&infracfg CLK_INFRA_UART0_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
+					  <&infracfg CLK_INFRA_UART0_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
+						 <&topckgen CLK_TOP_UART_SEL>;
+			status = "disabled";
+		};
+
+		uart1: serial at 11003000 {
+			compatible = "mediatek,mt7986-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11003000 0 0x400>;
+			interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_UART1_SEL>,
+				 <&infracfg CLK_INFRA_UART1_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&infracfg CLK_INFRA_UART1_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
+			status = "disabled";
+		};
+
+		uart2: serial at 11004000 {
+			compatible = "mediatek,mt7986-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11004000 0 0x400>;
+			interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_UART2_SEL>,
+				 <&infracfg CLK_INFRA_UART2_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&infracfg CLK_INFRA_UART2_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
+			status = "disabled";
+		};
+
+		ethsys: syscon at 15000000 {
+			 #address-cells = <1>;
+			 #size-cells = <1>;
+			 compatible = "mediatek,mt7986-ethsys",
+				      "syscon";
+			 reg = <0 0x15000000 0 0x1000>;
+			 #clock-cells = <1>;
+			 #reset-cells = <1>;
+		};
+
+	};
+
+};
-- 
2.29.2

From zhiyong.tao at mediatek.com  Tue Aug 17 00:51:54 2021
From: zhiyong.tao at mediatek.com (zhiyong.tao)
Date: Tue, 17 Aug 2021 15:51:54 +0800
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <CAGXv+5FtL2zaSWx4tUymx6mpCSb5dXG4XNWM9AJL+b6Ok3dxMg@mail.gmail.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
 <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
 <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>
 <CACRpkdbZKh8cqqiDRUik6Ooo33e+feGwYsLjcLRvBQnT3x5M3A@mail.gmail.com>
 <a7c8ab68ac3513865698cde27e665bdd554f459e.camel@mediatek.com>
 <CAGXv+5FtL2zaSWx4tUymx6mpCSb5dXG4XNWM9AJL+b6Ok3dxMg@mail.gmail.com>
Message-ID: <d40f6d5fd26aedb13e7a393202e5794b1893ecf8.camel@mediatek.com>

On Tue, 2021-08-17 at 13:44 +0800, Chen-Yu Tsai wrote:
> On Tue, Aug 17, 2021 at 10:21 AM zhiyong.tao <
> zhiyong.tao at mediatek.com> wrote:
> > 
> > On Tue, 2021-08-17 at 01:00 +0200, Linus Walleij wrote:
> > > On Mon, Aug 16, 2021 at 5:38 PM Chen-Yu Tsai <wenst at chromium.org>
> > > wrote:
> > > > On Mon, Aug 16, 2021 at 6:48 PM zhiyong.tao <
> > > > zhiyong.tao at mediatek.com> wrote:
> > > > > > I'll take that as "use SI units whenever possible and
> > > > > > reasonable".
> > > > > 
> > > > > ==> so It doesn't need to change the define, is it right?
> > > > > we will keep the common define.
> > > > 
> > > > Actually I think it would be possible and reasonable to use SI
> > > > units
> > > > in this case, since you are the vendor and have the resistor
> > > > values
> > > > to implement the support. Having different sets of values for
> > > > different
> > > > chips is nothing out of the ordinary. We already have to
> > > > account
> > > > for
> > > > different number of pins and different pin functions. That is
> > > > what
> > > > compatible strings are for.
> > > 
> > > I fully agree with Chen-Yu's analysis here.
> > > 
> > > Zhiyong can you make an attempt to use SI units (Ohms) and see
> > > what it will look like? I think it will look better for users and
> > > it
> > > will
> > > be less risk to make mistakes.
> > > 
> > > Yours,
> > > Linus Walleij
> > 
> > Hi Linus & chen-yu,
> > 
> > The rsel actual bias resistance of each setting is different in
> > different IC. For example, in mt8195, the rsel actual bias
> > resistance
> > setting like as:
> > MTK_PULL_SET_RSEL_000:75K in PU, 75k in PD;
> > MTK_PULL_SET
> > _RSEL_001:10k in PU, 5k in PD;
> > MTK_PULL_SET_RSEL_010:5k in PU, 75k in
> > PD;
> > MTK_PULL_SET_RSEL_011:4k in PU, 5K in PD;
> > MTK_PULL_SET_RSEL_100:3k in
> > PU, 75k in PD;
> > MTK_PULL_SET_RSEL_101:2k in PU, 5K in PD;
> > MTK_PULL_SET_RSE
> > L_110:1.5k in PU, 75k in PD;
> > MTK_PULL_SET_RSEL_111:1k in PU, 5k in PD.
> > 
> > but in mt8192, the rsel actual bias resistance setting like as:
> > MTK_PULL_SET_RSEL_000:75K in PU, 75k in PD;
> > MTK_PULL_SET_RSEL_001:3k in PU, 5k in PD;
> > MTK_PULL_SET_RSEL_010:10k in PU, 75k in PD;
> > MTK_PULL_SET_RSEL_011:1k in PU, 5K in PD;
> > 
> > Can you help me to provide a suggestion common define for the all
> > different IC?
> > It seems that we should add a new define, if we upstream a new IC
> > pinctrl driver in the future.
> 
> I assume you mean the macros used in the device tree?
> 
> The point of using SI units is to get rid of the macros. Instead of:
> 
>     bias-pull-up = <MTK_PULL_SET_RSEL_000>;
> 
> and
> 
>     bias-pull-down = <MTK_PULL_SET_RSEL_011>;
> 
> We want:
> 
>     bias-pull-up = <75000>;
> 
> and
> 
>     bias-pull-down = <5000>;
> 
> And the pinctrl driver then converts the real values in the device
> tree
> into register values using some lookup table.
> 
> The DT schema could then enumerate all the valid resistor values,
> and get proper validity checking.
> 
> Now if you really wanted to keep some symbols for mapping hardware
> register values to resistor values, you could have
> 
>     #define MT8192_PULL_UP_RSEL_001      75000
>     #define MT8192_PULL_DOWN_RSEL_001     5000
> 
> or have them all named MTK_PULL_{UP,DOWN}_RSEL_NNN, but split into
> different header files, one per SoC.
> 
> Personally I think having the macros is a bad idea if proper values
> are available. It just adds another layer of indirection, and another
> area where errors can creep in.
> 
> 
> Regards
> ChenYu

Hi Chenyu,

In one chip, If GPIO is different, the MTXXXX_PULL_UP_RSEL_001 may
means different actual bias resistance setting.

For example,

KPROW IO                                        
Paramters       Descriptions                   Min      Typ     Max    
 UNIT
Rpd     Input pull-down resistance      40      75      190     Kohm
Rpu     Input pull-up resistance        40      75      190     Kohm
Rpd     Input pull-down resistance      0.8     1.6     2       Kohm
Rpu     Input pull-up resistance        0.8     1.6     2       Kohm
                                        
                                        
KPCOL IO                                        
Paramters       Descriptions                   Min      Typ     Max    
 UNIT
Rpd     Input pull-down resistance      40      75      190     Kohm
Rpu     Input pull-up resistance        40      75      190     Kohm
Rpd     Input pull-down resistance      200     260     400     Kohm
Rpu     Input pull-up resistance        200     260     400     Kohm
                                        
                                        
MSDC1 IO                                        
Paramters       Descriptions                    Min     Typ     Max    
 UNIT
Rpd     Input pull-down resistance      5       7.5     10      Kohm
Rpu     Input pull-up resistance        5       7.5     10      Kohm
Rpd     Input pull-down resistance      10      50      100     Kohm
Rpu     Input pull-up resistance        10      50      100     Kohm

we think that we can't define like this.

Thanks.

From joel at jms.id.au  Tue Aug 17 00:51:54 2021
From: joel at jms.id.au (Joel Stanley)
Date: Tue, 17 Aug 2021 07:51:54 +0000
Subject: [GIT PULL] ARM: aspeed: devicetree changes for 5.15
Message-ID: <CACPK8XdWRBb9cuDWGQPfK8R8TsZuydJQHsL4_e2w=HvCKAMogg@mail.gmail.com>

Hello Soc maintainers,

Here are the aspeed changes for 5.15.

The following changes since commit 2734d6c1b1a089fb593ef6a23d4b70903526fe0c:

  Linux 5.14-rc2 (2021-07-18 14:13:49 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/joel/bmc.git
tags/aspeed-5.15-devicetree

for you to fetch changes up to 6b8b31269898b8891f1f3a95578ceeb109393e23:

  ARM: dts: aspeed: p10bmc: Add power control pins (2021-08-17 13:52:46 +0930)

----------------------------------------------------------------
ASPEED device tree updates for 5.15

 - New machines

  * Facebook's Cloudripper
  * Facebook's Elbert
  * Facebook's Fuji

  All three carry the description of "Facebook's next generation switch
  platform with an AST2600 BMC integrated for health monitoring
  purpose."

  They share a 128 MB SPI NOR flash layout that is also used by some
  older platforms.

  * Inspur's NF5280M6, an x86 platform server with an AST2500-based BMC

 - SGPIO updates including AST2600 support

 - GPIO descriptions for the IBM AST2600 machines

 - Pinctrl fix

 - Updates to Facebook's AST2500 based machines

----------------------------------------------------------------
Andrew Jeffery (1):
      ARM: dts: everest: Add phase corrections for eMMC

Dylan Hung (1):
      ARM: dts: aspeed-g6: Fix HVI3C function-group in pinctrl dtsi

Jim Wright (1):
      ARM: dts: aspeed: p10bmc: Add power control pins

Joel Stanley (3):
      ARM: dts: rainier, everest: Add TPM reset GPIO
      ARM: dts: aspeed: tacoma: Add TPM reset GPIO
      ARM: dts: aspeed: ast2500evb: Enable built in RTC

Ping Guo (1):
      ARM: dts: aspeed: Add Inspur NF5280M6 BMC machine

Steven Lee (4):
      dt-bindings: aspeed-sgpio: Convert txt bindings to yaml.
      dt-bindings: aspeed-sgpio: Add ast2600 sgpio
      ARM: dts: aspeed-g6: Add SGPIO node.
      ARM: dts: aspeed-g5: Remove ngpios from sgpio node.

Tao Ren (12):
      ARM: dts: aspeed: Enable ADC in Facebook AST2400 common dtsi
      ARM: dts: aspeed: wedge40: Remove redundant ADC device
      ARM: dts: aspeed: galaxy100: Remove redundant ADC device
      ARM: dts: aspeed: wedge100: Enable ADC channels
      ARM: dts: Add Facebook BMC 128MB flash layout
      ARM: dts: aspeed: wedge400: Use common flash layout
      ARM: dts: aspeed: Common dtsi for Facebook AST2600 Network BMCs
      ARM: dts: aspeed: Add Facebook Cloudripper (AST2600) BMC
      ARM: dts: aspeed: Add Facebook Elbert (AST2600) BMC
      ARM: dts: aspeed: Add Facebook Fuji (AST2600) BMC
      ARM: dts: aspeed: minipack: Update flash partition table
      ARM: dts: aspeed: cloudripper: Add comments for "mdio1"

 .../devicetree/bindings/gpio/aspeed,sgpio.yaml     |   77 ++
 .../devicetree/bindings/gpio/sgpio-aspeed.txt      |   46 -
 arch/arm/boot/dts/Makefile                         |    4 +
 arch/arm/boot/dts/aspeed-ast2500-evb.dts           |    4 +
 .../boot/dts/aspeed-bmc-facebook-cloudripper.dts   |  544 +++++++++
 arch/arm/boot/dts/aspeed-bmc-facebook-elbert.dts   |  185 +++
 arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts     | 1251 ++++++++++++++++++++
 .../arm/boot/dts/aspeed-bmc-facebook-galaxy100.dts |    4 -
 arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts |    8 +-
 arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts |    5 +
 arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts  |    4 -
 arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts |   48 +-
 arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts       |    4 +-
 arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts       |    2 +-
 arch/arm/boot/dts/aspeed-bmc-inspur-nf5280m6.dts   |  691 +++++++++++
 arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts        |    2 +-
 arch/arm/boot/dts/aspeed-g5.dtsi                   |    1 -
 arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi           |    4 +-
 arch/arm/boot/dts/aspeed-g6.dtsi                   |   28 +
 .../boot/dts/ast2400-facebook-netbmc-common.dtsi   |    4 +
 .../boot/dts/ast2600-facebook-netbmc-common.dtsi   |  169 +++
 .../boot/dts/facebook-bmc-flash-layout-128.dtsi    |   60 +
 22 files changed, 3033 insertions(+), 112 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/aspeed,sgpio.yaml
 delete mode 100644 Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-elbert.dts
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-facebook-fuji.dts
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-inspur-nf5280m6.dts
 create mode 100644 arch/arm/boot/dts/ast2600-facebook-netbmc-common.dtsi
 create mode 100644 arch/arm/boot/dts/facebook-bmc-flash-layout-128.dtsilin


From ulf.hansson at linaro.org  Tue Aug 17 01:00:56 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 17 Aug 2021 10:00:56 +0200
Subject: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the auto-tuning
 setting for sdio device
In-Reply-To: <VI1PR04MB52948F36F428AA3476A1F9D590FE9@VI1PR04MB5294.eurprd04.prod.outlook.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <1629117508-4886-4-git-send-email-haibo.chen@nxp.com>
 <CAPDyKFpqTdKxFytQWo+TLJf+D=JYJo6B2aZDqOQc4+9_mbH40Q@mail.gmail.com>
 <VI1PR04MB52948F36F428AA3476A1F9D590FE9@VI1PR04MB5294.eurprd04.prod.outlook.com>
Message-ID: <CAPDyKFpr9E6xxe2egiRGGWhUSY5aVr29rj1Hb_TwCzrY5bcvpg@mail.gmail.com>

On Tue, 17 Aug 2021 at 08:57, Bough Chen <haibo.chen at nxp.com> wrote:
>
> > -----Original Message-----
> > From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> > Sent: 2021?8?16? 21:53
> > To: Bough Chen <haibo.chen at nxp.com>
> > Cc: Adrian Hunter <adrian.hunter at intel.com>; Shawn Guo
> > <shawnguo at kernel.org>; Rob Herring <robh+dt at kernel.org>; Sascha Hauer
> > <s.hauer at pengutronix.de>; Sascha Hauer <kernel at pengutronix.de>; Fabio
> > Estevam <festevam at gmail.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> > dl-linux-imx <linux-imx at nxp.com>; DTML <devicetree at vger.kernel.org>; Linux
> > ARM <linux-arm-kernel at lists.infradead.org>
> > Subject: Re: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the auto-tuning
> > setting for sdio device
> >
> > On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
> > >
> > > From: Haibo Chen <haibo.chen at nxp.com>
> > >
> > > USDHC contain auto tuning circuit, this circuit will work
> > > automatically after the tuning procedurae, it can increase/decrease
> > > the delay cell according to the outside environment change (like
> > temperature).
> > >
> > > Unfortunately, this auto tuning circuit can not handle the async sdio
> > > device interrupt correctly. When sdio device use 4 data line, async
> > > sdio interrupt will use DAT[1], if we enable auto tuning circuit check
> > > 4 data lines, include the DAT[1], this circuit will detect this
> > > interrupt, take this as a data on DAT[1], and adjust the delay cell wrongly.
> > >
> > > This is the hardware design limitation, to avoid this, when sdio
> > > device enable async interrupt, auto tuning circuit only check DAT[0] and CMD
> > lines.
> >
> > SDIO irqs are being enabled/disabled dynamically in runtime by the mmc core
> > via the host ops ->enable_sdio_irq().
> >
> > Rather than forcing the autotuning circuit to stay unused statically, perhaps an
> > option would be to disable it when the SDIO irqs becomes enabled? Or maybe
> > that becomes too complicated?
>
> For interrupt in 4-bit mode, there is a definition of interrupt period, only in this period can the interrupt be
> detect and recognize. The interrupt period can exist during data transfer.
>
> So to fix this issue, one method is to disable auto tuning circuit. Another is my current method, just detect CMD
> and DAT0, but at least auto tuning still can work (this method need board design keep align all data lines).

To allow DAT1 being used for SDIO irqs (async or not), the irqs needs
to be enabled internally in the SDIO card first. This is done by
writing to the CCCR register, which happens in sdio_claim_irq(). At
this point in sdio_claim_irq() the core also invokes the
->enable_sdio_irq() host ops, to allow the host to prepare itself to
accept SDIO irqs.

It sounds to me that you should be able to use the ->enable_sdio_irq
ops, as a way of understanding that the auto-tuning feature also needs
to be turned off, because it's not compatible with SDIO irqs.

Kind regards
Uffe

>
>
> Best Regards
> Haibo chen
>
> >
> > >
> > > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> > > ---
> > >  drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++++
> > >  1 file changed, 18 insertions(+)
> > >
> > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > index f18d169bc8ff..ab84c29777e5 100644
> > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > @@ -226,6 +226,7 @@ struct esdhc_platform_data {
> > >         unsigned int tuning_step;       /* The delay cell steps in tuning
> > procedure */
> > >         unsigned int tuning_start_tap;  /* The start delay cell point in
> > tuning procedure */
> > >         unsigned int strobe_dll_delay_target;   /* The delay cell for
> > strobe pad (read clock) */
> > > +       bool sdio_async_interrupt_enabled;      /* sdio device enable
> > the async interrupt */
> > >  };
> > >
> > >  struct esdhc_soc_data {
> > > @@ -416,6 +417,8 @@ static inline void
> > > esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
> > >  /* Enable the auto tuning circuit to check the CMD line and BUS line
> > > */  static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host
> > > *host)  {
> > > +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > > +       struct pltfm_imx_data *imx_data =
> > > + sdhci_pltfm_priv(pltfm_host);
> > >         u32 buswidth, auto_tune_buswidth;
> > >
> > >         buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr +
> > > SDHCI_HOST_CONTROL)); @@ -432,6 +435,18 @@ static inline void
> > usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
> > >                 break;
> > >         }
> > >
> > > +       /*
> > > +        * If sdio device use async interrupt, it will use DAT[1] to signal
> > > +        * the device's interrupt asynchronous when use 4 data lines.
> > > +        * Then hardware auto tuning circuit MUST NOT check the DAT[1]
> > line,
> > > +        * otherwise auto tuning will be impacted by this async interrupt,
> > > +        * and change the delay cell incorrectly, which then cause
> > data/cmd
> > > +        * errors.
> > > +        * This is the hardware auto tuning circuit limitation.
> > > +        */
> > > +       if (imx_data->boarddata.sdio_async_interrupt_enabled)
> > > +               auto_tune_buswidth =
> > > + ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;
> > > +
> > >         esdhc_clrset_le(host,
> > ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
> > >                         auto_tune_buswidth |
> > ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
> > >                         ESDHC_VEND_SPEC2); @@ -1531,6 +1546,9
> > @@
> > > sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
> > >         if (of_property_read_u32(np, "fsl,delay-line",
> > &boarddata->delay_line))
> > >                 boarddata->delay_line = 0;
> > >
> > > +       if (of_property_read_bool(np,
> > > + "fsl,sdio-async-interrupt-enabled"))
> >
> > As stated on the DT patch, I think you can use the "cap-sdio-irq" instead.
> >
> > > +               boarddata->sdio_async_interrupt_enabled = true;
> > > +
> > >         mmc_of_parse_voltage(host->mmc, &host->ocr_mask);
> > >
> > >         if (esdhc_is_usdhc(imx_data) && !IS_ERR(imx_data->pinctrl)) {
> > > --
> > > 2.17.1
> > >
> >
> > Kind regards
> > Uffe


From krzysztof.kozlowski at canonical.com  Tue Aug 17 01:06:17 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 17 Aug 2021 10:06:17 +0200
Subject: [PATCH] dt-bindings: memory: convert Broadcom DPFE to dtschema
Message-ID: <20210817080617.14503-1-krzysztof.kozlowski@canonical.com>

Convert Broadcom DDR PHY Front End (DPFE) bindings to DT schema format
using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../memory-controllers/brcm,dpfe-cpu.txt      | 27 -----------
 .../memory-controllers/brcm,dpfe-cpu.yaml     | 48 +++++++++++++++++++
 MAINTAINERS                                   |  2 +-
 3 files changed, 49 insertions(+), 28 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.txt b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.txt
deleted file mode 100644
index 82d923ef413f..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-DDR PHY Front End (DPFE) for Broadcom STB
-=========================================
-
-DPFE and the DPFE firmware provide an interface for the host CPU to
-communicate with the DCPU, which resides inside the DDR PHY.
-
-There are three memory regions for interacting with the DCPU. These are
-specified in a single reg property.
-
-Required properties:
-  - compatible: must be "brcm,bcm7271-dpfe-cpu", "brcm,bcm7268-dpfe-cpu"
-    or "brcm,dpfe-cpu"
-  - reg: must reference three register ranges
-      - start address and length of the DCPU register space
-      - start address and length of the DCPU data memory space
-      - start address and length of the DCPU instruction memory space
-  - reg-names: must contain "dpfe-cpu", "dpfe-dmem", and "dpfe-imem";
-        they must be in the same order as the register declarations
-
-Example:
-	dpfe_cpu0: dpfe-cpu at f1132000 {
-		compatible = "brcm,bcm7271-dpfe-cpu", "brcm,dpfe-cpu";
-		reg =  <0xf1132000 0x180
-			0xf1134000 0x1000
-			0xf1138000 0x4000>;
-		reg-names = "dpfe-cpu", "dpfe-dmem", "dpfe-imem";
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
new file mode 100644
index 000000000000..769f13250047
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/brcm,dpfe-cpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DDR PHY Front End (DPFE) for Broadcom STB
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Markus Mayer <mmayer at broadcom.com>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - brcm,bcm7271-dpfe-cpu
+          - brcm,bcm7268-dpfe-cpu
+      - const: brcm,dpfe-cpu
+
+  reg:
+    items:
+      - description: DCPU register space
+      - description: DCPU data memory space
+      - description: DCPU instruction memory space
+
+  reg-names:
+    items:
+      - const: dpfe-cpu
+      - const: dpfe-dmem
+      - const: dpfe-imem
+
+required:
+  - compatible
+  - reg
+  - reg-names
+
+additionalProperties: false
+
+examples:
+  - |
+    dpfe-cpu at f1132000 {
+        compatible = "brcm,bcm7271-dpfe-cpu", "brcm,dpfe-cpu";
+        reg = <0xf1132000 0x180>,
+              <0xf1134000 0x1000>,
+              <0xf1138000 0x4000>;
+        reg-names = "dpfe-cpu", "dpfe-dmem", "dpfe-imem";
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 36aee8517ab0..be8e4af8ed64 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3855,7 +3855,7 @@ M:	Markus Mayer <mmayer at broadcom.com>
 M:	bcm-kernel-feedback-list at broadcom.com
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
-F:	Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.txt
+F:	Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
 F:	drivers/memory/brcmstb_dpfe.c
 
 BROADCOM STB NAND FLASH DRIVER
-- 
2.30.2



From tabba at google.com  Tue Aug 17 01:11:20 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:20 +0100
Subject: [PATCH v4 01/15] KVM: arm64: placeholder to check if VM is protected
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-2-tabba@google.com>

Add a function to check whether a VM is protected (under pKVM).
Since the creation of protected VMs isn't enabled yet, this is a
placeholder that always returns false. The intention is for this
to become a check for protected VMs in the future (see Will's RFC).

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>

Link: https://lore.kernel.org/kvmarm/20210603183347.1695-1-will at kernel.org/
---
 arch/arm64/include/asm/kvm_host.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 41911585ae0c..347781f99b6a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -771,6 +771,11 @@ void kvm_arch_free_vm(struct kvm *kvm);
 
 int kvm_arm_setup_stage2(struct kvm *kvm, unsigned long type);
 
+static inline bool kvm_vm_is_protected(struct kvm *kvm)
+{
+	return false;
+}
+
 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
 bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:19 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:19 +0100
Subject: [PATCH v4 00/15] KVM: arm64: Fixed features for protected VMs
Message-ID: <20210817081134.2918285-1-tabba@google.com>

Hi,

Changes since v3 [1]:
- Redid calculating restricted values of feature register fields, ensuring that
  the code distinguishes between unsigned and (potentially in the future)
  signed fields (Will)
- Refactoring and fixes (Drew, Will)
- More documentation and comments (Oliver, Will)
- Dropped patch "Restrict protected VM capabilities", since it should come with
  or after the user ABI series for pKVM (Will)
- Carried Will's acks

Changes since v2 [2]:
- Both trapping and setting of feature id registers are toggled by an allowed
  features bitmap of the feature id registers (Will)
- Documentation explaining the rationale behind allowed/blocked features (Drew)
- Restrict protected VM features by checking and restricting VM capabilities
- Misc small fixes and tidying up (mostly Will)
- Remove dependency on Will's protected VM user ABI series [3]
- Rebase on 5.14-rc2
- Carried Will's acks

Changes since v1 [4]:
- Restrict protected VM features based on an allowed features rather than
  rejected ones (Drew)
- Add more background describing protected KVM to the cover letter (Alex)

This patch series adds support for restricting CPU features for protected VMs
in KVM (pKVM) [5].

Various VM feature configurations are allowed in KVM/arm64, each requiring
specific handling logic to deal with traps, context-switching and potentially
emulation. Achieving feature parity in pKVM therefore requires either elevating
this logic to EL2 (and substantially increasing the TCB) or continuing to trust
the host handlers at EL1. Since neither of these options are especially
appealing, pKVM instead limits the CPU features exposed to a guest to a fixed
configuration based on the underlying hardware and which can mostly be provided
straightforwardly by EL2.

This series approaches that by restricting CPU features exposed to protected
guests. Features advertised through feature registers are limited, which pKVM
enforces by trapping register accesses and instructions associated with these
features.

This series is based on 5.14-rc2. You can find the applied series here [6].

Cheers,
/fuad

[1] https://lore.kernel.org/kvmarm/20210719160346.609914-1-tabba at google.com/

[2] https://lore.kernel.org/kvmarm/20210615133950.693489-1-tabba at google.com/

[3] https://lore.kernel.org/kvmarm/20210603183347.1695-1-will at kernel.org/

[4] https://lore.kernel.org/kvmarm/20210608141141.997398-1-tabba at google.com/

[5] Once complete, protected KVM adds the ability to create protected VMs.
These protected VMs are protected from the host Linux kernel (and from other
VMs), where the host does not have access to guest memory,even if compromised.
Normal (nVHE) guests can still be created and run in parallel with protected
VMs. Their functionality should not be affected.

For protected VMs, the host should not even have access to a protected guest's
state or anything that would enable it to manipulate it (e.g., vcpu register
context and el2 system registers); only hyp would have that access. If the host
could access that state, then it might be able to get around the protection
provided.  Therefore, anything that is sensitive and that would require such
access needs to happen at hyp, hence the code in nvhe running only at hyp.

For more details about pKVM, please refer to Will's talk at KVM Forum 2020:
https://mirrors.edge.kernel.org/pub/linux/kernel/people/will/slides/kvmforum-2020-edited.pdf
https://www.youtube.com/watch?v=edqJSzsDRxk

[6] https://android-kvm.googlesource.com/linux/+/refs/heads/tabba/el2_fixed_feature_v4

Fuad Tabba (15):
  KVM: arm64: placeholder to check if VM is protected
  KVM: arm64: Remove trailing whitespace in comment
  KVM: arm64: MDCR_EL2 is a 64-bit register
  KVM: arm64: Fix names of config register fields
  KVM: arm64: Refactor sys_regs.h,c for nVHE reuse
  KVM: arm64: Restore mdcr_el2 from vcpu
  KVM: arm64: Keep mdcr_el2's value as set by __init_el2_debug
  KVM: arm64: Track value of cptr_el2 in struct kvm_vcpu_arch
  KVM: arm64: Add feature register flag definitions
  KVM: arm64: Add config register bit definitions
  KVM: arm64: Guest exit handlers for nVHE hyp
  KVM: arm64: Add trap handlers for protected VMs
  KVM: arm64: Move sanitized copies of CPU features
  KVM: arm64: Trap access to pVM restricted features
  KVM: arm64: Handle protected guests at 32 bits

 arch/arm64/include/asm/cpufeature.h       |   4 +-
 arch/arm64/include/asm/kvm_arm.h          |  54 ++-
 arch/arm64/include/asm/kvm_asm.h          |   2 +-
 arch/arm64/include/asm/kvm_fixed_config.h | 170 +++++++++
 arch/arm64/include/asm/kvm_host.h         |  15 +-
 arch/arm64/include/asm/kvm_hyp.h          |   5 +-
 arch/arm64/include/asm/sysreg.h           |  17 +-
 arch/arm64/kernel/cpufeature.c            |   8 +-
 arch/arm64/kvm/Makefile                   |   2 +-
 arch/arm64/kvm/arm.c                      |  12 +
 arch/arm64/kvm/debug.c                    |   2 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h   |  52 ++-
 arch/arm64/kvm/hyp/nvhe/Makefile          |   2 +-
 arch/arm64/kvm/hyp/nvhe/debug-sr.c        |   2 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c     |   6 -
 arch/arm64/kvm/hyp/nvhe/switch.c          |  87 ++++-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c        | 432 ++++++++++++++++++++++
 arch/arm64/kvm/hyp/vhe/debug-sr.c         |   2 +-
 arch/arm64/kvm/hyp/vhe/switch.c           |  12 +-
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c        |   2 +-
 arch/arm64/kvm/pkvm.c                     | 185 +++++++++
 arch/arm64/kvm/sys_regs.c                 |  64 +---
 arch/arm64/kvm/sys_regs.h                 |  31 ++
 23 files changed, 1059 insertions(+), 109 deletions(-)
 create mode 100644 arch/arm64/include/asm/kvm_fixed_config.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c
 create mode 100644 arch/arm64/kvm/pkvm.c


base-commit: c500bee1c5b2f1d59b1081ac879d73268ab0ff17
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:21 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:21 +0100
Subject: [PATCH v4 02/15] KVM: arm64: Remove trailing whitespace in comment
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-3-tabba@google.com>

Remove trailing whitespace from comment in trap_dbgauthstatus_el1().

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/sys_regs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f6f126eb6ac1..80a6e41cadad 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -318,14 +318,14 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
 /*
  * We want to avoid world-switching all the DBG registers all the
  * time:
- * 
+ *
  * - If we've touched any debug register, it is likely that we're
  *   going to touch more of them. It then makes sense to disable the
  *   traps and start doing the save/restore dance
  * - If debug is active (DBG_MDSCR_KDE or DBG_MDSCR_MDE set), it is
  *   then mandatory to save/restore the registers, as the guest
  *   depends on them.
- * 
+ *
  * For this, we use a DIRTY bit, indicating the guest has modified the
  * debug registers, used as follow:
  *
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:22 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:22 +0100
Subject: [PATCH v4 03/15] KVM: arm64: MDCR_EL2 is a 64-bit register
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-4-tabba@google.com>

Fix the places in KVM that treat MDCR_EL2 as a 32-bit register.
More recent features (e.g., FEAT_SPEv1p2) use bits above 31.

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_arm.h   | 20 ++++++++++----------
 arch/arm64/include/asm/kvm_asm.h   |  2 +-
 arch/arm64/include/asm/kvm_host.h  |  2 +-
 arch/arm64/kvm/debug.c             |  2 +-
 arch/arm64/kvm/hyp/nvhe/debug-sr.c |  2 +-
 arch/arm64/kvm/hyp/vhe/debug-sr.c  |  2 +-
 6 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index d436831dd706..6a523ec83415 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -281,18 +281,18 @@
 /* Hyp Debug Configuration Register bits */
 #define MDCR_EL2_E2TB_MASK	(UL(0x3))
 #define MDCR_EL2_E2TB_SHIFT	(UL(24))
-#define MDCR_EL2_TTRF		(1 << 19)
-#define MDCR_EL2_TPMS		(1 << 14)
+#define MDCR_EL2_TTRF		(UL(1) << 19)
+#define MDCR_EL2_TPMS		(UL(1) << 14)
 #define MDCR_EL2_E2PB_MASK	(UL(0x3))
 #define MDCR_EL2_E2PB_SHIFT	(UL(12))
-#define MDCR_EL2_TDRA		(1 << 11)
-#define MDCR_EL2_TDOSA		(1 << 10)
-#define MDCR_EL2_TDA		(1 << 9)
-#define MDCR_EL2_TDE		(1 << 8)
-#define MDCR_EL2_HPME		(1 << 7)
-#define MDCR_EL2_TPM		(1 << 6)
-#define MDCR_EL2_TPMCR		(1 << 5)
-#define MDCR_EL2_HPMN_MASK	(0x1F)
+#define MDCR_EL2_TDRA		(UL(1) << 11)
+#define MDCR_EL2_TDOSA		(UL(1) << 10)
+#define MDCR_EL2_TDA		(UL(1) << 9)
+#define MDCR_EL2_TDE		(UL(1) << 8)
+#define MDCR_EL2_HPME		(UL(1) << 7)
+#define MDCR_EL2_TPM		(UL(1) << 6)
+#define MDCR_EL2_TPMCR		(UL(1) << 5)
+#define MDCR_EL2_HPMN_MASK	(UL(0x1F))
 
 /* For compatibility with fault code shared with 32-bit */
 #define FSC_FAULT	ESR_ELx_FSC_FAULT
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 9f0bf2109be7..63ead9060ab5 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -210,7 +210,7 @@ extern u64 __vgic_v3_read_vmcr(void);
 extern void __vgic_v3_write_vmcr(u32 vmcr);
 extern void __vgic_v3_init_lrs(void);
 
-extern u32 __kvm_get_mdcr_el2(void);
+extern u64 __kvm_get_mdcr_el2(void);
 
 #define __KVM_EXTABLE(from, to)						\
 	"	.pushsection	__kvm_ex_table, \"a\"\n"		\
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 347781f99b6a..4d2d974c1522 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -289,7 +289,7 @@ struct kvm_vcpu_arch {
 
 	/* HYP configuration */
 	u64 hcr_el2;
-	u32 mdcr_el2;
+	u64 mdcr_el2;
 
 	/* Exception Information */
 	struct kvm_vcpu_fault_info fault;
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index d5e79d7ee6e9..db9361338b2a 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -21,7 +21,7 @@
 				DBG_MDSCR_KDE | \
 				DBG_MDSCR_MDE)
 
-static DEFINE_PER_CPU(u32, mdcr_el2);
+static DEFINE_PER_CPU(u64, mdcr_el2);
 
 /**
  * save/restore_guest_debug_regs
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 7d3f25868cae..df361d839902 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -109,7 +109,7 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu)
 	__debug_switch_to_host_common(vcpu);
 }
 
-u32 __kvm_get_mdcr_el2(void)
+u64 __kvm_get_mdcr_el2(void)
 {
 	return read_sysreg(mdcr_el2);
 }
diff --git a/arch/arm64/kvm/hyp/vhe/debug-sr.c b/arch/arm64/kvm/hyp/vhe/debug-sr.c
index f1e2e5a00933..289689b2682d 100644
--- a/arch/arm64/kvm/hyp/vhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/debug-sr.c
@@ -20,7 +20,7 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu)
 	__debug_switch_to_host_common(vcpu);
 }
 
-u32 __kvm_get_mdcr_el2(void)
+u64 __kvm_get_mdcr_el2(void)
 {
 	return read_sysreg(mdcr_el2);
 }
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:23 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:23 +0100
Subject: [PATCH v4 04/15] KVM: arm64: Fix names of config register fields
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-5-tabba@google.com>

Change the names of hcr_el2 register fields to match the Arm
Architecture Reference Manual. Easier for cross-referencing and
for grepping.

Also, change the name of CPTR_EL2_RES1 to CPTR_NVHE_EL2_RES1,
because res1 bits are different for VHE.

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_arm.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 6a523ec83415..a928b2dc0b0f 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -32,9 +32,9 @@
 #define HCR_TVM		(UL(1) << 26)
 #define HCR_TTLB	(UL(1) << 25)
 #define HCR_TPU		(UL(1) << 24)
-#define HCR_TPC		(UL(1) << 23)
+#define HCR_TPC		(UL(1) << 23) /* HCR_TPCP if FEAT_DPB */
 #define HCR_TSW		(UL(1) << 22)
-#define HCR_TAC		(UL(1) << 21)
+#define HCR_TACR	(UL(1) << 21)
 #define HCR_TIDCP	(UL(1) << 20)
 #define HCR_TSC		(UL(1) << 19)
 #define HCR_TID3	(UL(1) << 18)
@@ -61,7 +61,7 @@
  * The bits we set in HCR:
  * TLOR:	Trap LORegion register accesses
  * RW:		64bit by default, can be overridden for 32bit VMs
- * TAC:		Trap ACTLR
+ * TACR:	Trap ACTLR
  * TSC:		Trap SMC
  * TSW:		Trap cache operations by set/way
  * TWE:		Trap WFE
@@ -76,7 +76,7 @@
  * PTW:		Take a stage2 fault if a stage1 walk steps in device memory
  */
 #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
-			 HCR_BSU_IS | HCR_FB | HCR_TAC | \
+			 HCR_BSU_IS | HCR_FB | HCR_TACR | \
 			 HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
 			 HCR_FMO | HCR_IMO | HCR_PTW )
 #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
@@ -275,8 +275,8 @@
 #define CPTR_EL2_TTA	(1 << 20)
 #define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
 #define CPTR_EL2_TZ	(1 << 8)
-#define CPTR_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 */
-#define CPTR_EL2_DEFAULT	CPTR_EL2_RES1
+#define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
+#define CPTR_EL2_DEFAULT	CPTR_NVHE_EL2_RES1
 
 /* Hyp Debug Configuration Register bits */
 #define MDCR_EL2_E2TB_MASK	(UL(0x3))
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:24 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:24 +0100
Subject: [PATCH v4 05/15] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-6-tabba@google.com>

Refactor sys_regs.h and sys_regs.c to make it easier to reuse
common code. It will be used in nVHE in a later patch.

Note that the refactored code uses __inline_bsearch for find_reg
instead of bsearch to avoid copying the bsearch code for nVHE.

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/sysreg.h |  5 +++
 arch/arm64/kvm/sys_regs.c       | 60 +++++++++------------------------
 arch/arm64/kvm/sys_regs.h       | 31 +++++++++++++++++
 3 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7b9c3acba684..53a93a9c5253 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1153,6 +1153,11 @@
 #define ICH_VTR_A3V_SHIFT	21
 #define ICH_VTR_A3V_MASK	(1 << ICH_VTR_A3V_SHIFT)
 
+#define ARM64_FEATURE_FIELD_BITS	4
+
+/* Create a mask for the feature bits of the specified feature. */
+#define ARM64_FEATURE_MASK(x)	(GENMASK_ULL(x##_SHIFT + ARM64_FEATURE_FIELD_BITS - 1, x##_SHIFT))
+
 #ifdef __ASSEMBLY__
 
 	.irp	num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 80a6e41cadad..b6a2f8e890db 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -44,10 +44,6 @@
  * 64bit interface.
  */
 
-#define reg_to_encoding(x)						\
-	sys_reg((u32)(x)->Op0, (u32)(x)->Op1,				\
-		(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
-
 static bool read_from_write_only(struct kvm_vcpu *vcpu,
 				 struct sys_reg_params *params,
 				 const struct sys_reg_desc *r)
@@ -1026,8 +1022,6 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 	return true;
 }
 
-#define FEATURE(x)	(GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT))
-
 /* Read a sanitised cpufeature ID register by sys_reg_desc */
 static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 		struct sys_reg_desc const *r, bool raz)
@@ -1038,40 +1032,40 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 	switch (id) {
 	case SYS_ID_AA64PFR0_EL1:
 		if (!vcpu_has_sve(vcpu))
-			val &= ~FEATURE(ID_AA64PFR0_SVE);
-		val &= ~FEATURE(ID_AA64PFR0_AMU);
-		val &= ~FEATURE(ID_AA64PFR0_CSV2);
-		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2);
-		val &= ~FEATURE(ID_AA64PFR0_CSV3);
-		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3);
+			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2);
+		val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3);
+		val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3);
 		break;
 	case SYS_ID_AA64PFR1_EL1:
-		val &= ~FEATURE(ID_AA64PFR1_MTE);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
 		if (kvm_has_mte(vcpu->kvm)) {
 			u64 pfr, mte;
 
 			pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
 			mte = cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR1_MTE_SHIFT);
-			val |= FIELD_PREP(FEATURE(ID_AA64PFR1_MTE), mte);
+			val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR1_MTE), mte);
 		}
 		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
-			val &= ~(FEATURE(ID_AA64ISAR1_APA) |
-				 FEATURE(ID_AA64ISAR1_API) |
-				 FEATURE(ID_AA64ISAR1_GPA) |
-				 FEATURE(ID_AA64ISAR1_GPI));
+			val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) |
+				 ARM64_FEATURE_MASK(ID_AA64ISAR1_API) |
+				 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) |
+				 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI));
 		break;
 	case SYS_ID_AA64DFR0_EL1:
 		/* Limit debug to ARMv8.0 */
-		val &= ~FEATURE(ID_AA64DFR0_DEBUGVER);
-		val |= FIELD_PREP(FEATURE(ID_AA64DFR0_DEBUGVER), 6);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER);
+		val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), 6);
 		/* Limit guests to PMUv3 for ARMv8.4 */
 		val = cpuid_feature_cap_perfmon_field(val,
 						      ID_AA64DFR0_PMUVER_SHIFT,
 						      kvm_vcpu_has_pmu(vcpu) ? ID_AA64DFR0_PMUVER_8_4 : 0);
 		/* Hide SPE from guests */
-		val &= ~FEATURE(ID_AA64DFR0_PMSVER);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER);
 		break;
 	case SYS_ID_DFR0_EL1:
 		/* Limit guests to PMUv3 for ARMv8.4 */
@@ -2106,23 +2100,6 @@ static int check_sysreg_table(const struct sys_reg_desc *table, unsigned int n,
 	return 0;
 }
 
-static int match_sys_reg(const void *key, const void *elt)
-{
-	const unsigned long pval = (unsigned long)key;
-	const struct sys_reg_desc *r = elt;
-
-	return pval - reg_to_encoding(r);
-}
-
-static const struct sys_reg_desc *find_reg(const struct sys_reg_params *params,
-					 const struct sys_reg_desc table[],
-					 unsigned int num)
-{
-	unsigned long pval = reg_to_encoding(params);
-
-	return bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg);
-}
-
 int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu)
 {
 	kvm_inject_undefined(vcpu);
@@ -2365,13 +2342,8 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 
 	trace_kvm_handle_sys_reg(esr);
 
-	params.Op0 = (esr >> 20) & 3;
-	params.Op1 = (esr >> 14) & 0x7;
-	params.CRn = (esr >> 10) & 0xf;
-	params.CRm = (esr >> 1) & 0xf;
-	params.Op2 = (esr >> 17) & 0x7;
+	params = esr_sys64_to_params(esr);
 	params.regval = vcpu_get_reg(vcpu, Rt);
-	params.is_write = !(esr & 1);
 
 	ret = emulate_sys_reg(vcpu, &params);
 
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index 9d0621417c2a..cc0cc95a0280 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -11,6 +11,12 @@
 #ifndef __ARM64_KVM_SYS_REGS_LOCAL_H__
 #define __ARM64_KVM_SYS_REGS_LOCAL_H__
 
+#include <linux/bsearch.h>
+
+#define reg_to_encoding(x)						\
+	sys_reg((u32)(x)->Op0, (u32)(x)->Op1,				\
+		(u32)(x)->CRn, (u32)(x)->CRm, (u32)(x)->Op2)
+
 struct sys_reg_params {
 	u8	Op0;
 	u8	Op1;
@@ -21,6 +27,14 @@ struct sys_reg_params {
 	bool	is_write;
 };
 
+#define esr_sys64_to_params(esr)                                               \
+	((struct sys_reg_params){ .Op0 = ((esr) >> 20) & 3,                    \
+				  .Op1 = ((esr) >> 14) & 0x7,                  \
+				  .CRn = ((esr) >> 10) & 0xf,                  \
+				  .CRm = ((esr) >> 1) & 0xf,                   \
+				  .Op2 = ((esr) >> 17) & 0x7,                  \
+				  .is_write = !((esr) & 1) })
+
 struct sys_reg_desc {
 	/* Sysreg string for debug */
 	const char *name;
@@ -152,6 +166,23 @@ static inline int cmp_sys_reg(const struct sys_reg_desc *i1,
 	return i1->Op2 - i2->Op2;
 }
 
+static inline int match_sys_reg(const void *key, const void *elt)
+{
+	const unsigned long pval = (unsigned long)key;
+	const struct sys_reg_desc *r = elt;
+
+	return pval - reg_to_encoding(r);
+}
+
+static inline const struct sys_reg_desc *
+find_reg(const struct sys_reg_params *params, const struct sys_reg_desc table[],
+	 unsigned int num)
+{
+	unsigned long pval = reg_to_encoding(params);
+
+	return __inline_bsearch((void *)pval, table, num, sizeof(table[0]), match_sys_reg);
+}
+
 const struct sys_reg_desc *find_reg_by_id(u64 id,
 					  struct sys_reg_params *params,
 					  const struct sys_reg_desc table[],
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:26 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:26 +0100
Subject: [PATCH v4 07/15] KVM: arm64: Keep mdcr_el2's value as set by
 __init_el2_debug
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-8-tabba@google.com>

__init_el2_debug configures mdcr_el2 at initialization based on,
among other things, available hardware support. Trap deactivation
doesn't check that, so keep the initial value.

No functional change intended. However, the value of mdcr_el2
might be different after deactivating traps than it was before
this patch.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 4 ----
 arch/arm64/kvm/hyp/vhe/switch.c  | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 2ea764a48958..1778593a08a9 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -90,10 +90,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 		isb();
 	}
 
-	vcpu->arch.mdcr_el2_host &= MDCR_EL2_HPMN_MASK |
-				    MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT |
-				    MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
-
 	__deactivate_traps_common(vcpu);
 
 	write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index ec158fa41ae6..0d0c9550fb08 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -93,10 +93,6 @@ void activate_traps_vhe_load(struct kvm_vcpu *vcpu)
 
 void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu)
 {
-	vcpu->arch.mdcr_el2_host &= MDCR_EL2_HPMN_MASK |
-				    MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT |
-				    MDCR_EL2_TPMS;
-
 	__deactivate_traps_common(vcpu);
 }
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:25 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:25 +0100
Subject: [PATCH v4 06/15] KVM: arm64: Restore mdcr_el2 from vcpu
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-7-tabba@google.com>

On deactivating traps, restore the value of mdcr_el2 from the
newly created and preserved host value vcpu context, rather than
directly reading the hardware register.

Up until and including this patch the two values are the same,
i.e., the hardware register and the vcpu one. A future patch will
be changing the value of mdcr_el2 on activating traps, and this
ensures that its value will be restored.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_host.h       |  5 ++++-
 arch/arm64/include/asm/kvm_hyp.h        |  2 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h |  6 +++++-
 arch/arm64/kvm/hyp/nvhe/switch.c        | 13 +++++--------
 arch/arm64/kvm/hyp/vhe/switch.c         | 14 +++++---------
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c      |  2 +-
 6 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 4d2d974c1522..76462c6a91ee 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -287,10 +287,13 @@ struct kvm_vcpu_arch {
 	/* Stage 2 paging state used by the hardware on next switch */
 	struct kvm_s2_mmu *hw_mmu;
 
-	/* HYP configuration */
+	/* Values of trap registers for the guest. */
 	u64 hcr_el2;
 	u64 mdcr_el2;
 
+	/* Values of trap registers for the host before guest entry. */
+	u64 mdcr_el2_host;
+
 	/* Exception Information */
 	struct kvm_vcpu_fault_info fault;
 
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 9d60b3006efc..657d0c94cf82 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -95,7 +95,7 @@ void __sve_restore_state(void *sve_pffr, u32 *fpsr);
 
 #ifndef __KVM_NVHE_HYPERVISOR__
 void activate_traps_vhe_load(struct kvm_vcpu *vcpu);
-void deactivate_traps_vhe_put(void);
+void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu);
 #endif
 
 u64 __guest_enter(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e4a2f295a394..a0e78a6027be 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -92,11 +92,15 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
 		write_sysreg(0, pmselr_el0);
 		write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
 	}
+
+	vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2);
 	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
 }
 
-static inline void __deactivate_traps_common(void)
+static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
 {
+	write_sysreg(vcpu->arch.mdcr_el2_host, mdcr_el2);
+
 	write_sysreg(0, hstr_el2);
 	if (kvm_arm_support_pmu_v3())
 		write_sysreg(0, pmuserenr_el0);
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index f7af9688c1f7..2ea764a48958 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -69,12 +69,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 static void __deactivate_traps(struct kvm_vcpu *vcpu)
 {
 	extern char __kvm_hyp_host_vector[];
-	u64 mdcr_el2, cptr;
+	u64 cptr;
 
 	___deactivate_traps(vcpu);
 
-	mdcr_el2 = read_sysreg(mdcr_el2);
-
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
 		u64 val;
 
@@ -92,13 +90,12 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 		isb();
 	}
 
-	__deactivate_traps_common();
+	vcpu->arch.mdcr_el2_host &= MDCR_EL2_HPMN_MASK |
+				    MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT |
+				    MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
 
-	mdcr_el2 &= MDCR_EL2_HPMN_MASK;
-	mdcr_el2 |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT;
-	mdcr_el2 |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
+	__deactivate_traps_common(vcpu);
 
-	write_sysreg(mdcr_el2, mdcr_el2);
 	write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
 
 	cptr = CPTR_EL2_DEFAULT;
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index b3229924d243..ec158fa41ae6 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -91,17 +91,13 @@ void activate_traps_vhe_load(struct kvm_vcpu *vcpu)
 	__activate_traps_common(vcpu);
 }
 
-void deactivate_traps_vhe_put(void)
+void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu)
 {
-	u64 mdcr_el2 = read_sysreg(mdcr_el2);
+	vcpu->arch.mdcr_el2_host &= MDCR_EL2_HPMN_MASK |
+				    MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT |
+				    MDCR_EL2_TPMS;
 
-	mdcr_el2 &= MDCR_EL2_HPMN_MASK |
-		    MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT |
-		    MDCR_EL2_TPMS;
-
-	write_sysreg(mdcr_el2, mdcr_el2);
-
-	__deactivate_traps_common();
+	__deactivate_traps_common(vcpu);
 }
 
 /* Switch to the guest for VHE systems running in EL2 */
diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index 2a0b8c88d74f..007a12dd4351 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -101,7 +101,7 @@ void kvm_vcpu_put_sysregs_vhe(struct kvm_vcpu *vcpu)
 	struct kvm_cpu_context *host_ctxt;
 
 	host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
-	deactivate_traps_vhe_put();
+	deactivate_traps_vhe_put(vcpu);
 
 	__sysreg_save_el1_state(guest_ctxt);
 	__sysreg_save_user_state(guest_ctxt);
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:27 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:27 +0100
Subject: [PATCH v4 08/15] KVM: arm64: Track value of cptr_el2 in struct
 kvm_vcpu_arch
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-9-tabba@google.com>

Track the baseline guest value for cptr_el2 in struct
kvm_vcpu_arch, similar to the other registers that control traps.
Use this value when setting cptr_el2 for the guest.

Currently this value is unchanged (CPTR_EL2_DEFAULT), but future
patches will set trapping bits based on features supported for
the guest.

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_host.h | 1 +
 arch/arm64/kvm/arm.c              | 1 +
 arch/arm64/kvm/hyp/nvhe/switch.c  | 2 +-
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 76462c6a91ee..ac67d5699c68 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -290,6 +290,7 @@ struct kvm_vcpu_arch {
 	/* Values of trap registers for the guest. */
 	u64 hcr_el2;
 	u64 mdcr_el2;
+	u64 cptr_el2;
 
 	/* Values of trap registers for the host before guest entry. */
 	u64 mdcr_el2_host;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..14b12f2c08c0 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1104,6 +1104,7 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
 	}
 
 	vcpu_reset_hcr(vcpu);
+	vcpu->arch.cptr_el2 = CPTR_EL2_DEFAULT;
 
 	/*
 	 * Handle the "start in power-off" case.
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 1778593a08a9..86f3d6482935 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -41,7 +41,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 	___activate_traps(vcpu);
 	__activate_traps_common(vcpu);
 
-	val = CPTR_EL2_DEFAULT;
+	val = vcpu->arch.cptr_el2;
 	val |= CPTR_EL2_TTA | CPTR_EL2_TAM;
 	if (!update_fp_enabled(vcpu)) {
 		val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:28 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:28 +0100
Subject: [PATCH v4 09/15] KVM: arm64: Add feature register flag definitions
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-10-tabba@google.com>

Add feature register flag definitions to clarify which features
might be supported.

Consolidate the various ID_AA64PFR0_ELx flags for all ELs.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/cpufeature.h |  4 ++--
 arch/arm64/include/asm/sysreg.h     | 12 ++++++++----
 arch/arm64/kernel/cpufeature.c      |  8 ++++----
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 9bb9d11750d7..b7d9bb17908d 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -602,14 +602,14 @@ static inline bool id_aa64pfr0_32bit_el1(u64 pfr0)
 {
 	u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_SHIFT);
 
-	return val == ID_AA64PFR0_EL1_32BIT_64BIT;
+	return val == ID_AA64PFR0_ELx_32BIT_64BIT;
 }
 
 static inline bool id_aa64pfr0_32bit_el0(u64 pfr0)
 {
 	u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL0_SHIFT);
 
-	return val == ID_AA64PFR0_EL0_32BIT_64BIT;
+	return val == ID_AA64PFR0_ELx_32BIT_64BIT;
 }
 
 static inline bool id_aa64pfr0_sve(u64 pfr0)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 53a93a9c5253..f84a00f5874d 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -784,14 +784,13 @@
 #define ID_AA64PFR0_AMU			0x1
 #define ID_AA64PFR0_SVE			0x1
 #define ID_AA64PFR0_RAS_V1		0x1
+#define ID_AA64PFR0_RAS_V1P1		0x2
 #define ID_AA64PFR0_FP_NI		0xf
 #define ID_AA64PFR0_FP_SUPPORTED	0x0
 #define ID_AA64PFR0_ASIMD_NI		0xf
 #define ID_AA64PFR0_ASIMD_SUPPORTED	0x0
-#define ID_AA64PFR0_EL1_64BIT_ONLY	0x1
-#define ID_AA64PFR0_EL1_32BIT_64BIT	0x2
-#define ID_AA64PFR0_EL0_64BIT_ONLY	0x1
-#define ID_AA64PFR0_EL0_32BIT_64BIT	0x2
+#define ID_AA64PFR0_ELx_64BIT_ONLY	0x1
+#define ID_AA64PFR0_ELx_32BIT_64BIT	0x2
 
 /* id_aa64pfr1 */
 #define ID_AA64PFR1_MPAMFRAC_SHIFT	16
@@ -847,12 +846,16 @@
 #define ID_AA64MMFR0_ASID_SHIFT		4
 #define ID_AA64MMFR0_PARANGE_SHIFT	0
 
+#define ID_AA64MMFR0_ASID_8		0x0
+#define ID_AA64MMFR0_ASID_16		0x2
+
 #define ID_AA64MMFR0_TGRAN4_NI		0xf
 #define ID_AA64MMFR0_TGRAN4_SUPPORTED	0x0
 #define ID_AA64MMFR0_TGRAN64_NI		0xf
 #define ID_AA64MMFR0_TGRAN64_SUPPORTED	0x0
 #define ID_AA64MMFR0_TGRAN16_NI		0x0
 #define ID_AA64MMFR0_TGRAN16_SUPPORTED	0x1
+#define ID_AA64MMFR0_PARANGE_40		0x2
 #define ID_AA64MMFR0_PARANGE_48		0x5
 #define ID_AA64MMFR0_PARANGE_52		0x6
 
@@ -900,6 +903,7 @@
 #define ID_AA64MMFR2_CNP_SHIFT		0
 
 /* id_aa64dfr0 */
+#define ID_AA64DFR0_MTPMU_SHIFT		48
 #define ID_AA64DFR0_TRBE_SHIFT		44
 #define ID_AA64DFR0_TRACE_FILT_SHIFT	40
 #define ID_AA64DFR0_DOUBLELOCK_SHIFT	36
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0ead8bfedf20..5b59fe5e26e4 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -239,8 +239,8 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
 	S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL3_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL2_SHIFT, 4, 0),
-	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_SHIFT, 4, ID_AA64PFR0_EL1_64BIT_ONLY),
-	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_EL0_64BIT_ONLY),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_SHIFT, 4, ID_AA64PFR0_ELx_64BIT_ONLY),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_ELx_64BIT_ONLY),
 	ARM64_FTR_END,
 };
 
@@ -1956,7 +1956,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_EL0_SHIFT,
-		.min_field_value = ID_AA64PFR0_EL0_32BIT_64BIT,
+		.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
 	},
 #ifdef CONFIG_KVM
 	{
@@ -1967,7 +1967,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_EL1_SHIFT,
-		.min_field_value = ID_AA64PFR0_EL1_32BIT_64BIT,
+		.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
 	},
 	{
 		.desc = "Protected KVM",
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:29 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:29 +0100
Subject: [PATCH v4 10/15] KVM: arm64: Add config register bit definitions
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-11-tabba@google.com>

Add hardware configuration register bit definitions for HCR_EL2
and MDCR_EL2. Future patches toggle these hyp configuration
register bits to trap on certain accesses.

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_arm.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index a928b2dc0b0f..327120c0089f 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -12,8 +12,13 @@
 #include <asm/types.h>
 
 /* Hyp Configuration Register (HCR) bits */
+
+#define HCR_TID5	(UL(1) << 58)
+#define HCR_DCT		(UL(1) << 57)
 #define HCR_ATA_SHIFT	56
 #define HCR_ATA		(UL(1) << HCR_ATA_SHIFT)
+#define HCR_AMVOFFEN	(UL(1) << 51)
+#define HCR_FIEN	(UL(1) << 47)
 #define HCR_FWB		(UL(1) << 46)
 #define HCR_API		(UL(1) << 41)
 #define HCR_APK		(UL(1) << 40)
@@ -56,6 +61,7 @@
 #define HCR_PTW		(UL(1) << 2)
 #define HCR_SWIO	(UL(1) << 1)
 #define HCR_VM		(UL(1) << 0)
+#define HCR_RES0	((UL(1) << 48) | (UL(1) << 39))
 
 /*
  * The bits we set in HCR:
@@ -277,11 +283,21 @@
 #define CPTR_EL2_TZ	(1 << 8)
 #define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
 #define CPTR_EL2_DEFAULT	CPTR_NVHE_EL2_RES1
+#define CPTR_NVHE_EL2_RES0	(GENMASK(63, 32) |	\
+				 GENMASK(29, 21) |	\
+				 GENMASK(19, 14) |	\
+				 BIT(11))
 
 /* Hyp Debug Configuration Register bits */
 #define MDCR_EL2_E2TB_MASK	(UL(0x3))
 #define MDCR_EL2_E2TB_SHIFT	(UL(24))
+#define MDCR_EL2_HPMFZS		(UL(1) << 36)
+#define MDCR_EL2_HPMFZO		(UL(1) << 29)
+#define MDCR_EL2_MTPME		(UL(1) << 28)
+#define MDCR_EL2_TDCC		(UL(1) << 27)
+#define MDCR_EL2_HCCD		(UL(1) << 23)
 #define MDCR_EL2_TTRF		(UL(1) << 19)
+#define MDCR_EL2_HPMD		(UL(1) << 17)
 #define MDCR_EL2_TPMS		(UL(1) << 14)
 #define MDCR_EL2_E2PB_MASK	(UL(0x3))
 #define MDCR_EL2_E2PB_SHIFT	(UL(12))
@@ -293,6 +309,12 @@
 #define MDCR_EL2_TPM		(UL(1) << 6)
 #define MDCR_EL2_TPMCR		(UL(1) << 5)
 #define MDCR_EL2_HPMN_MASK	(UL(0x1F))
+#define MDCR_EL2_RES0		(GENMASK(63, 37) |	\
+				 GENMASK(35, 30) |	\
+				 GENMASK(25, 24) |	\
+				 GENMASK(22, 20) |	\
+				 BIT(18) |		\
+				 GENMASK(16, 15))
 
 /* For compatibility with fault code shared with 32-bit */
 #define FSC_FAULT	ESR_ELx_FSC_FAULT
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:30 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:30 +0100
Subject: [PATCH v4 11/15] KVM: arm64: Guest exit handlers for nVHE hyp
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-12-tabba@google.com>

Add an array of pointers to handlers for various trap reasons in
nVHE code.

The current code selects how to fixup a guest on exit based on a
series of if/else statements. Future patches will also require
different handling for guest exists. Create an array of handlers
to consolidate them.

No functional change intended as the array isn't populated yet.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 43 +++++++++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/switch.c        | 33 +++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index a0e78a6027be..5a2b89b96c67 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -409,6 +409,46 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
 	return true;
 }
 
+typedef int (*exit_handle_fn)(struct kvm_vcpu *);
+
+exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu);
+
+static exit_handle_fn kvm_get_hyp_exit_handler(struct kvm_vcpu *vcpu)
+{
+	return is_nvhe_hyp_code() ? kvm_get_nvhe_exit_handler(vcpu) : NULL;
+}
+
+/*
+ * Allow the hypervisor to handle the exit with an exit handler if it has one.
+ *
+ * Returns true if the hypervisor handled the exit, and control should go back
+ * to the guest, or false if it hasn't.
+ */
+static bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu)
+{
+	bool is_handled = false;
+	exit_handle_fn exit_handler = kvm_get_hyp_exit_handler(vcpu);
+
+	if (exit_handler) {
+		/*
+		 * There's limited vcpu context here since it's not synced yet.
+		 * Ensure that relevant vcpu context that might be used by the
+		 * exit_handler is in sync before it's called and if handled.
+		 */
+		*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
+		*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
+
+		is_handled = exit_handler(vcpu);
+
+		if (is_handled) {
+			write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
+			write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
+		}
+	}
+
+	return is_handled;
+}
+
 /*
  * Return true when we were able to fixup the guest exit and should return to
  * the guest, false when we should restore the host state and return to the
@@ -496,6 +536,9 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 			goto guest;
 	}
 
+	/* Check if there's an exit handler and allow it to handle the exit. */
+	if (kvm_hyp_handle_exit(vcpu))
+		goto guest;
 exit:
 	/* Return to the host kernel and handle the exit */
 	return false;
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 86f3d6482935..b7f25307a7b9 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -158,6 +158,39 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
 		write_sysreg(pmu->events_host, pmcntenset_el0);
 }
 
+static exit_handle_fn hyp_exit_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_WFx]		= NULL,
+	[ESR_ELx_EC_CP15_32]		= NULL,
+	[ESR_ELx_EC_CP15_64]		= NULL,
+	[ESR_ELx_EC_CP14_MR]		= NULL,
+	[ESR_ELx_EC_CP14_LS]		= NULL,
+	[ESR_ELx_EC_CP14_64]		= NULL,
+	[ESR_ELx_EC_HVC32]		= NULL,
+	[ESR_ELx_EC_SMC32]		= NULL,
+	[ESR_ELx_EC_HVC64]		= NULL,
+	[ESR_ELx_EC_SMC64]		= NULL,
+	[ESR_ELx_EC_SYS64]		= NULL,
+	[ESR_ELx_EC_SVE]		= NULL,
+	[ESR_ELx_EC_IABT_LOW]		= NULL,
+	[ESR_ELx_EC_DABT_LOW]		= NULL,
+	[ESR_ELx_EC_SOFTSTP_LOW]	= NULL,
+	[ESR_ELx_EC_WATCHPT_LOW]	= NULL,
+	[ESR_ELx_EC_BREAKPT_LOW]	= NULL,
+	[ESR_ELx_EC_BKPT32]		= NULL,
+	[ESR_ELx_EC_BRK64]		= NULL,
+	[ESR_ELx_EC_FP_ASIMD]		= NULL,
+	[ESR_ELx_EC_PAC]		= NULL,
+};
+
+exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
+{
+	u32 esr = kvm_vcpu_get_esr(vcpu);
+	u8 esr_ec = ESR_ELx_EC(esr);
+
+	return hyp_exit_handlers[esr_ec];
+}
+
 /* Switch to the guest for legacy non-VHE systems */
 int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 {
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:31 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:31 +0100
Subject: [PATCH v4 12/15] KVM: arm64: Add trap handlers for protected VMs
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-13-tabba@google.com>

Add trap handlers for protected VMs. These are mainly for Sys64
and debug traps.

No functional change intended as these are not hooked in yet to
the guest exit handlers introduced earlier. So even when trapping
is triggered, the exit handlers would let the host handle it, as
before.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_fixed_config.h | 170 +++++++++
 arch/arm64/include/asm/kvm_host.h         |   2 +
 arch/arm64/include/asm/kvm_hyp.h          |   3 +
 arch/arm64/kvm/Makefile                   |   2 +-
 arch/arm64/kvm/arm.c                      |  11 +
 arch/arm64/kvm/hyp/nvhe/Makefile          |   2 +-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c        | 430 ++++++++++++++++++++++
 arch/arm64/kvm/pkvm.c                     | 185 ++++++++++
 8 files changed, 803 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/include/asm/kvm_fixed_config.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c
 create mode 100644 arch/arm64/kvm/pkvm.c

diff --git a/arch/arm64/include/asm/kvm_fixed_config.h b/arch/arm64/include/asm/kvm_fixed_config.h
new file mode 100644
index 000000000000..40c18380156d
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_fixed_config.h
@@ -0,0 +1,170 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba at google.com>
+ */
+
+#ifndef __ARM64_KVM_FIXED_CONFIG_H__
+#define __ARM64_KVM_FIXED_CONFIG_H__
+
+#include <asm/sysreg.h>
+
+/*
+ * This file contains definitions for features to be allowed or restricted for
+ * guest virtual machines, depending on the mode KVM is running in and on the
+ * type of guest that is running.
+ *
+ * The ALLOW masks represent a bitmask of feature fields that are allowed
+ * without any restrictions as long as they are supported by the system.
+ *
+ * The RESTRICT_UNSIGNED masks, if present, represent unsigned fields for
+ * features that are restricted to support at most the specified feature.
+ *
+ * If a feature field is not present in either, than it is not supported.
+ *
+ * The approach taken for protected VMs is to allow features that are:
+ * - Needed by common Linux distributions (e.g., floating point)
+ * - Trivial to support, e.g., supporting the feature does not introduce or
+ * require tracking of additional state in KVM
+ * - Cannot be trapped or prevent the guest from using anyway
+ */
+
+/*
+ * Allow for protected VMs:
+ * - Floating-point and Advanced SIMD
+ * - Data Independent Timing
+ */
+#define PVM_ID_AA64PFR0_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64PFR0_FP) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_ASIMD) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_DIT) \
+	)
+
+/*
+ * Restrict to the following *unsigned* features for protected VMs:
+ * - AArch64 guests only (no support for AArch32 guests):
+ *	AArch32 adds complexity in trap handling, emulation, condition codes,
+ *	etc...
+ * - RAS (v1)
+ *	Supported by KVM
+ */
+#define PVM_ID_AA64PFR0_RESTRICT_UNSIGNED (\
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0), ID_AA64PFR0_ELx_64BIT_ONLY) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1), ID_AA64PFR0_ELx_64BIT_ONLY) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL2), ID_AA64PFR0_ELx_64BIT_ONLY) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL3), ID_AA64PFR0_ELx_64BIT_ONLY) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_RAS), ID_AA64PFR0_RAS_V1) \
+	)
+
+/*
+ * Allow for protected VMs:
+ * - Branch Target Identification
+ * - Speculative Store Bypassing
+ */
+#define PVM_ID_AA64PFR1_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64PFR1_BT) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR1_SSBS) \
+	)
+
+/*
+ * No support for Scalable Vectors for protected VMs:
+ *	Requires additional support from KVM, e.g., context-switching and
+ *	trapping at EL2
+ */
+#define PVM_ID_AA64ZFR0_ALLOW (0ULL)
+
+/*
+ * No support for debug, including breakpoints, and watchpoints for protected
+ * VMs:
+ *	The Arm architecture mandates support for at least the Armv8 debug
+ *	architecture, which would include at least 2 hardware breakpoints and
+ *	watchpoints. Providing that support to protected guests adds
+ *	considerable state and complexity. Therefore, the reserved value of 0 is
+ *	used for debug-related fields.
+ */
+#define PVM_ID_AA64DFR0_ALLOW (0ULL)
+
+/*
+ * Allow for protected VMs:
+ * - Mixed-endian
+ * - Distinction between Secure and Non-secure Memory
+ * - Mixed-endian at EL0 only
+ * - Non-context synchronizing exception entry and exit
+ */
+#define PVM_ID_AA64MMFR0_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_BIGENDEL) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_SNSMEM) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_BIGENDEL0) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_EXS) \
+	)
+
+/*
+ * Restrict to the following *unsigned* features for protected VMs:
+ * - 40-bit IPA
+ * - 16-bit ASID
+ */
+#define PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED (\
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_PARANGE), ID_AA64MMFR0_PARANGE_40) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_ASID), ID_AA64MMFR0_ASID_16) \
+	)
+
+/*
+ * Allow for protected VMs:
+ * - Hardware translation table updates to Access flag and Dirty state
+ * - Number of VMID bits from CPU
+ * - Hierarchical Permission Disables
+ * - Privileged Access Never
+ * - SError interrupt exceptions from speculative reads
+ * - Enhanced Translation Synchronization
+ */
+#define PVM_ID_AA64MMFR1_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_HADBS) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_VMIDBITS) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_HPD) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_PAN) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_SPECSEI) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_ETS) \
+	)
+
+/*
+ * Allow for protected VMs:
+ * - Common not Private translations
+ * - User Access Override
+ * - IESB bit in the SCTLR_ELx registers
+ * - Unaligned single-copy atomicity and atomic functions
+ * - ESR_ELx.EC value on an exception by read access to feature ID space
+ * - TTL field in address operations.
+ * - Break-before-make sequences when changing translation block size
+ * - E0PDx mechanism
+ */
+#define PVM_ID_AA64MMFR2_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_CNP) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_UAO) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_IESB) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_AT) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_IDS) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_TTL) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_BBM) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_E0PD) \
+	)
+
+/*
+ * Allow for protected VMs all features in this register:
+ * - LS64
+ * - XS
+ * - I8MM
+ * - DGB
+ * - BF16
+ * - SPECRES
+ * - SB
+ * - FRINTTS
+ * - PAuth
+ * - FPAC
+ * - LRCPC
+ * - FCMA
+ * - JSCVT
+ * - DPB
+ */
+#define PVM_ID_AA64ISAR1_ALLOW (~0ULL)
+
+#endif /* __ARM64_KVM_FIXED_CONFIG_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ac67d5699c68..e1ceadd69575 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -780,6 +780,8 @@ static inline bool kvm_vm_is_protected(struct kvm *kvm)
 	return false;
 }
 
+void kvm_init_protected_traps(struct kvm_vcpu *vcpu);
+
 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
 bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 657d0c94cf82..3f4866322f85 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -115,7 +115,10 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
 void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
 #endif
 
+extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
 
 #endif /* __ARM64_KVM_HYP_H__ */
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 989bb5dad2c8..0be63f5c495f 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -14,7 +14,7 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
 	 $(KVM)/vfio.o $(KVM)/irqchip.o $(KVM)/binary_stats.o \
 	 arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \
 	 inject_fault.o va_layout.o handle_exit.o \
-	 guest.o debug.o reset.o sys_regs.o \
+	 guest.o debug.o pkvm.o reset.o sys_regs.o \
 	 vgic-sys-reg-v3.o fpsimd.o pmu.o \
 	 arch_timer.o trng.o\
 	 vgic/vgic.o vgic/vgic-init.o \
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 14b12f2c08c0..75fff5cd6a6c 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -618,6 +618,14 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 
 	ret = kvm_arm_pmu_v3_enable(vcpu);
 
+	/*
+	 * Initialize traps for protected VMs.
+	 * NOTE: Move trap initialization to EL2 once the code is in place for
+	 * maintaining protected VM state at EL2 instead of the host.
+	 */
+	if (kvm_vm_is_protected(kvm))
+		kvm_init_protected_traps(vcpu);
+
 	return ret;
 }
 
@@ -1781,8 +1789,11 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
 	void *addr = phys_to_virt(hyp_mem_base);
 	int ret;
 
+	kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+	kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
 	kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 	kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+	kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
 
 	ret = create_hyp_mappings(addr, addr + hyp_mem_size, PAGE_HYP);
 	if (ret)
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 5df6193fc430..a23f417a0c20 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -14,7 +14,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
 
 obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
 	 hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
-	 cache.o setup.o mm.o mem_protect.o
+	 cache.o setup.o mm.o mem_protect.o sys_regs.o
 obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
 obj-y += $(lib-objs)
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
new file mode 100644
index 000000000000..cd126d45cbcc
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba at google.com>
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_fixed_config.h>
+#include <asm/kvm_mmu.h>
+
+#include <hyp/adjust_pc.h>
+
+#include "../../sys_regs.h"
+
+/*
+ * Copies of the host's CPU features registers holding sanitized values.
+ */
+u64 id_aa64pfr0_el1_sys_val;
+u64 id_aa64pfr1_el1_sys_val;
+u64 id_aa64mmfr2_el1_sys_val;
+
+/*
+ * Inject an unknown/undefined exception to the guest.
+ */
+static void inject_undef(struct kvm_vcpu *vcpu)
+{
+	u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+
+	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 |
+			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+			     KVM_ARM64_PENDING_EXCEPTION);
+
+	__kvm_adjust_pc(vcpu);
+
+	write_sysreg_el1(esr, SYS_ESR);
+	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
+}
+
+/*
+ * Accessor for undefined accesses.
+ */
+static bool undef_access(struct kvm_vcpu *vcpu,
+			 struct sys_reg_params *p,
+			 const struct sys_reg_desc *r)
+{
+	inject_undef(vcpu);
+	return false;
+}
+
+/*
+ * Accessors for feature registers.
+ *
+ * If access is allowed, set the regval to the protected VM's view of the
+ * register and return true.
+ * Otherwise, inject an undefined exception and return false.
+ */
+
+/*
+ * Returns the restricted features values of the feature register based on the
+ * limitations in restrict_fields.
+ * Note: Use only for unsigned feature field values.
+ */
+static u64 get_restricted_features_unsigned(u64 sys_reg_val,
+					    u64 restrict_fields)
+{
+	u64 value = 0UL;
+	u64 mask = GENMASK_ULL(ARM64_FEATURE_FIELD_BITS - 1, 0);
+
+	/*
+	 * According to the Arm Architecture Reference Manual, feature fields
+	 * use increasing values to indicate increases in functionality.
+	 * Iterate over the restricted feature fields and calculate the minimum
+	 * unsigned value between the one supported by the system, and what the
+	 * value is being restricted to.
+	 */
+	while (sys_reg_val && restrict_fields) {
+		value |= min(sys_reg_val & mask, restrict_fields & mask);
+		sys_reg_val &= ~mask;
+		restrict_fields &= ~mask;
+		mask <<= ARM64_FEATURE_FIELD_BITS;
+	}
+
+	return value;
+}
+
+/* Accessor for ID_AA64PFR0_EL1. */
+static bool pvm_access_id_aa64pfr0(struct kvm_vcpu *vcpu,
+				   struct sys_reg_params *p,
+				   const struct sys_reg_desc *r)
+{
+	const struct kvm *kvm = (const struct kvm *) kern_hyp_va(vcpu->kvm);
+	u64 set_mask = 0;
+
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
+		PVM_ID_AA64PFR0_RESTRICT_UNSIGNED);
+
+	/* Spectre and Meltdown mitigation in KVM */
+	set_mask |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2),
+			       (u64)kvm->arch.pfr0_csv2);
+	set_mask |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3),
+			       (u64)kvm->arch.pfr0_csv3);
+
+	p->regval = (id_aa64pfr0_el1_sys_val & PVM_ID_AA64PFR0_ALLOW) |
+		    set_mask;
+	return true;
+}
+
+/* Accessor for ID_AA64PFR1_EL1. */
+static bool pvm_access_id_aa64pfr1(struct kvm_vcpu *vcpu,
+				   struct sys_reg_params *p,
+				   const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	p->regval = id_aa64pfr1_el1_sys_val & PVM_ID_AA64PFR1_ALLOW;
+	return true;
+}
+
+/* Accessor for ID_AA64ZFR0_EL1. */
+static bool pvm_access_id_aa64zfr0(struct kvm_vcpu *vcpu,
+				   struct sys_reg_params *p,
+				   const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * No support for Scalable Vectors, therefore, pKVM has no sanitized
+	 * copy of the feature id register.
+	 */
+	BUILD_BUG_ON(PVM_ID_AA64ZFR0_ALLOW != 0ULL);
+
+	p->regval = 0;
+	return true;
+}
+
+/* Accessor for ID_AA64DFR0_EL1. */
+static bool pvm_access_id_aa64dfr0(struct kvm_vcpu *vcpu,
+				   struct sys_reg_params *p,
+				   const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * No support for debug, including breakpoints, and watchpoints,
+	 * therefore, pKVM has no sanitized copy of the feature id register.
+	 */
+	BUILD_BUG_ON(PVM_ID_AA64DFR0_ALLOW != 0ULL);
+
+	p->regval = 0;
+	return true;
+}
+
+/*
+ * No restrictions on ID_AA64ISAR1_EL1 features, therefore, pKVM has no
+ * sanitized copy of the feature id register and it is handled by the host.
+ */
+static_assert(PVM_ID_AA64ISAR1_ALLOW == ~0ULL);
+
+/* Accessor for ID_AA64MMFR0_EL1. */
+static bool pvm_access_id_aa64mmfr0(struct kvm_vcpu *vcpu,
+				    struct sys_reg_params *p,
+				    const struct sys_reg_desc *r)
+{
+	u64 set_mask = 0;
+
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	set_mask |= get_restricted_features_unsigned(id_aa64mmfr0_el1_sys_val,
+		PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED);
+
+	p->regval = (id_aa64mmfr0_el1_sys_val & PVM_ID_AA64MMFR0_ALLOW) |
+		     set_mask;
+	return true;
+}
+
+/* Accessor for ID_AA64MMFR1_EL1. */
+static bool pvm_access_id_aa64mmfr1(struct kvm_vcpu *vcpu,
+				    struct sys_reg_params *p,
+				    const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	p->regval = id_aa64mmfr1_el1_sys_val & PVM_ID_AA64MMFR1_ALLOW;
+	return true;
+}
+
+/* Accessor for ID_AA64MMFR2_EL1. */
+static bool pvm_access_id_aa64mmfr2(struct kvm_vcpu *vcpu,
+				    struct sys_reg_params *p,
+				    const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	p->regval = id_aa64mmfr2_el1_sys_val & PVM_ID_AA64MMFR2_ALLOW;
+	return true;
+}
+
+/*
+ * Accessor for AArch32 Processor Feature Registers.
+ *
+ * The value of these registers is "unknown" according to the spec if AArch32
+ * isn't supported.
+ */
+static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
+				  struct sys_reg_params *p,
+				  const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * No support for AArch32 guests, therefore, pKVM has no sanitized copy
+	 * of AArch32 feature id registers.
+	 */
+	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1),
+		     PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) >
+			ID_AA64PFR0_ELx_64BIT_ONLY);
+
+	/* Use 0 for architecturally "unknown" values. */
+	p->regval = 0;
+	return true;
+}
+
+/* Mark the specified system register as an AArch32 feature register. */
+#define AARCH32(REG) { SYS_DESC(REG), .access = pvm_access_id_aarch32 }
+
+/* Mark the specified system register as not being handled in hyp. */
+#define HOST_HANDLED(REG) { SYS_DESC(REG), .access = NULL }
+
+/*
+ * Architected system registers.
+ * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
+ *
+ * NOTE: Anything not explicitly listed here will be *restricted by default*,
+ * i.e., it will lead to injecting an exception into the guest.
+ */
+static const struct sys_reg_desc pvm_sys_reg_descs[] = {
+	/* Cache maintenance by set/way operations are restricted. */
+
+	/* Debug and Trace Registers are all restricted */
+
+	/* AArch64 mappings of the AArch32 ID registers */
+	/* CRm=1 */
+	AARCH32(SYS_ID_PFR0_EL1),
+	AARCH32(SYS_ID_PFR1_EL1),
+	AARCH32(SYS_ID_DFR0_EL1),
+	AARCH32(SYS_ID_AFR0_EL1),
+	AARCH32(SYS_ID_MMFR0_EL1),
+	AARCH32(SYS_ID_MMFR1_EL1),
+	AARCH32(SYS_ID_MMFR2_EL1),
+	AARCH32(SYS_ID_MMFR3_EL1),
+
+	/* CRm=2 */
+	AARCH32(SYS_ID_ISAR0_EL1),
+	AARCH32(SYS_ID_ISAR1_EL1),
+	AARCH32(SYS_ID_ISAR2_EL1),
+	AARCH32(SYS_ID_ISAR3_EL1),
+	AARCH32(SYS_ID_ISAR4_EL1),
+	AARCH32(SYS_ID_ISAR5_EL1),
+	AARCH32(SYS_ID_MMFR4_EL1),
+	AARCH32(SYS_ID_ISAR6_EL1),
+
+	/* CRm=3 */
+	AARCH32(SYS_MVFR0_EL1),
+	AARCH32(SYS_MVFR1_EL1),
+	AARCH32(SYS_MVFR2_EL1),
+	AARCH32(SYS_ID_PFR2_EL1),
+	AARCH32(SYS_ID_DFR1_EL1),
+	AARCH32(SYS_ID_MMFR5_EL1),
+
+	/* AArch64 ID registers */
+	/* CRm=4 */
+	{ SYS_DESC(SYS_ID_AA64PFR0_EL1), .access = pvm_access_id_aa64pfr0 },
+	{ SYS_DESC(SYS_ID_AA64PFR1_EL1), .access = pvm_access_id_aa64pfr1 },
+	{ SYS_DESC(SYS_ID_AA64ZFR0_EL1), .access = pvm_access_id_aa64zfr0 },
+	{ SYS_DESC(SYS_ID_AA64DFR0_EL1), .access = pvm_access_id_aa64dfr0 },
+	HOST_HANDLED(SYS_ID_AA64DFR1_EL1),
+	HOST_HANDLED(SYS_ID_AA64AFR0_EL1),
+	HOST_HANDLED(SYS_ID_AA64AFR1_EL1),
+	HOST_HANDLED(SYS_ID_AA64ISAR0_EL1),
+	HOST_HANDLED(SYS_ID_AA64ISAR1_EL1),
+	{ SYS_DESC(SYS_ID_AA64MMFR0_EL1), .access = pvm_access_id_aa64mmfr0 },
+	{ SYS_DESC(SYS_ID_AA64MMFR1_EL1), .access = pvm_access_id_aa64mmfr1 },
+	{ SYS_DESC(SYS_ID_AA64MMFR2_EL1), .access = pvm_access_id_aa64mmfr2 },
+
+	HOST_HANDLED(SYS_SCTLR_EL1),
+	HOST_HANDLED(SYS_ACTLR_EL1),
+	HOST_HANDLED(SYS_CPACR_EL1),
+
+	HOST_HANDLED(SYS_RGSR_EL1),
+	HOST_HANDLED(SYS_GCR_EL1),
+
+	/* Scalable Vector Registers are restricted. */
+
+	HOST_HANDLED(SYS_TTBR0_EL1),
+	HOST_HANDLED(SYS_TTBR1_EL1),
+	HOST_HANDLED(SYS_TCR_EL1),
+
+	HOST_HANDLED(SYS_APIAKEYLO_EL1),
+	HOST_HANDLED(SYS_APIAKEYHI_EL1),
+	HOST_HANDLED(SYS_APIBKEYLO_EL1),
+	HOST_HANDLED(SYS_APIBKEYHI_EL1),
+	HOST_HANDLED(SYS_APDAKEYLO_EL1),
+	HOST_HANDLED(SYS_APDAKEYHI_EL1),
+	HOST_HANDLED(SYS_APDBKEYLO_EL1),
+	HOST_HANDLED(SYS_APDBKEYHI_EL1),
+	HOST_HANDLED(SYS_APGAKEYLO_EL1),
+	HOST_HANDLED(SYS_APGAKEYHI_EL1),
+
+	HOST_HANDLED(SYS_AFSR0_EL1),
+	HOST_HANDLED(SYS_AFSR1_EL1),
+	HOST_HANDLED(SYS_ESR_EL1),
+
+	HOST_HANDLED(SYS_ERRIDR_EL1),
+	HOST_HANDLED(SYS_ERRSELR_EL1),
+	HOST_HANDLED(SYS_ERXFR_EL1),
+	HOST_HANDLED(SYS_ERXCTLR_EL1),
+	HOST_HANDLED(SYS_ERXSTATUS_EL1),
+	HOST_HANDLED(SYS_ERXADDR_EL1),
+	HOST_HANDLED(SYS_ERXMISC0_EL1),
+	HOST_HANDLED(SYS_ERXMISC1_EL1),
+
+	HOST_HANDLED(SYS_TFSR_EL1),
+	HOST_HANDLED(SYS_TFSRE0_EL1),
+
+	HOST_HANDLED(SYS_FAR_EL1),
+	HOST_HANDLED(SYS_PAR_EL1),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_MAIR_EL1),
+	HOST_HANDLED(SYS_AMAIR_EL1),
+
+	/* Limited Ordering Regions Registers are restricted. */
+
+	HOST_HANDLED(SYS_VBAR_EL1),
+	HOST_HANDLED(SYS_DISR_EL1),
+
+	/* GIC CPU Interface registers are restricted. */
+
+	HOST_HANDLED(SYS_CONTEXTIDR_EL1),
+	HOST_HANDLED(SYS_TPIDR_EL1),
+
+	HOST_HANDLED(SYS_SCXTNUM_EL1),
+
+	HOST_HANDLED(SYS_CNTKCTL_EL1),
+
+	HOST_HANDLED(SYS_CCSIDR_EL1),
+	HOST_HANDLED(SYS_CLIDR_EL1),
+	HOST_HANDLED(SYS_CSSELR_EL1),
+	HOST_HANDLED(SYS_CTR_EL0),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_TPIDR_EL0),
+	HOST_HANDLED(SYS_TPIDRRO_EL0),
+
+	HOST_HANDLED(SYS_SCXTNUM_EL0),
+
+	/* Activity Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_CNTP_TVAL_EL0),
+	HOST_HANDLED(SYS_CNTP_CTL_EL0),
+	HOST_HANDLED(SYS_CNTP_CVAL_EL0),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_DACR32_EL2),
+	HOST_HANDLED(SYS_IFSR32_EL2),
+	HOST_HANDLED(SYS_FPEXC32_EL2),
+};
+
+/*
+ * Handler for protected VM MSR, MRS or System instruction execution in AArch64.
+ *
+ * Return 1 if handled, or 0 if not.
+ */
+int kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu)
+{
+	const struct sys_reg_desc *r;
+	struct sys_reg_params params;
+	unsigned long esr = kvm_vcpu_get_esr(vcpu);
+	int Rt = kvm_vcpu_sys_get_rt(vcpu);
+
+	params = esr_sys64_to_params(esr);
+	params.regval = vcpu_get_reg(vcpu, Rt);
+
+	r = find_reg(&params, pvm_sys_reg_descs, ARRAY_SIZE(pvm_sys_reg_descs));
+
+	/* Undefined access (RESTRICTED). */
+	if (r == NULL) {
+		inject_undef(vcpu);
+		return 1;
+	}
+
+	/* Handled by the host (HOST_HANDLED) */
+	if (r->access == NULL)
+		return 0;
+
+	/* Handled by hyp: skip instruction if instructed to do so. */
+	if (r->access(vcpu, &params, r))
+		__kvm_skip_instr(vcpu);
+
+	vcpu_set_reg(vcpu, Rt, params.regval);
+	return 1;
+}
+
+/*
+ * Handler for protected VM restricted exceptions.
+ *
+ * Inject an undefined exception into the guest and return 1 to indicate that
+ * it was handled.
+ */
+int kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu)
+{
+	inject_undef(vcpu);
+	return 1;
+}
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
new file mode 100644
index 000000000000..a66a74e65989
--- /dev/null
+++ b/arch/arm64/kvm/pkvm.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * KVM host (EL1) interface to Protected KVM (pkvm) code at EL2.
+ *
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba at google.com>
+ */
+
+#include <linux/kvm_host.h>
+#include <linux/mm.h>
+
+#include <asm/kvm_fixed_config.h>
+
+/*
+ * Set trap register values for features not allowed in ID_AA64PFR0.
+ */
+static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = PVM_ID_AA64PFR0_ALLOW |
+				PVM_ID_AA64PFR0_RESTRICT_UNSIGNED;
+	u64 hcr_set = 0;
+	u64 hcr_clear = 0;
+	u64 cptr_set = 0;
+
+	/* Trap AArch32 guests */
+	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0), feature_ids) <
+		    ID_AA64PFR0_ELx_32BIT_64BIT ||
+	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1), feature_ids) <
+		    ID_AA64PFR0_ELx_32BIT_64BIT)
+		hcr_set |= HCR_RW | HCR_TID0;
+
+	/* Trap RAS unless all current versions are supported */
+	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_RAS), feature_ids) <
+	    ID_AA64PFR0_RAS_V1P1) {
+		hcr_set |= HCR_TERR | HCR_TEA;
+		hcr_clear |= HCR_FIEN;
+	}
+
+	/* Trap AMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_AMU), feature_ids)) {
+		hcr_clear |= HCR_AMVOFFEN;
+		cptr_set |= CPTR_EL2_TAM;
+	}
+
+	/* Trap ASIMD */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_ASIMD), feature_ids))
+		cptr_set |= CPTR_EL2_TFP;
+
+	/* Trap SVE */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_SVE), feature_ids))
+		cptr_set |= CPTR_EL2_TZ;
+
+	vcpu->arch.hcr_el2 |= hcr_set;
+	vcpu->arch.hcr_el2 &= ~hcr_clear;
+	vcpu->arch.cptr_el2 |= cptr_set;
+}
+
+/*
+ * Set trap register values for features not allowed in ID_AA64PFR1.
+ */
+static void pvm_init_traps_aa64pfr1(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = PVM_ID_AA64PFR1_ALLOW;
+	u64 hcr_set = 0;
+	u64 hcr_clear = 0;
+
+	/* Memory Tagging: Trap and Treat as Untagged if not allowed. */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_MTE), feature_ids)) {
+		hcr_set |= HCR_TID5;
+		hcr_clear |= HCR_DCT | HCR_ATA;
+	}
+
+	vcpu->arch.hcr_el2 |= hcr_set;
+	vcpu->arch.hcr_el2 &= ~hcr_clear;
+}
+
+/*
+ * Set trap register values for features not allowed in ID_AA64DFR0.
+ */
+static void pvm_init_traps_aa64dfr0(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = PVM_ID_AA64DFR0_ALLOW;
+	u64 mdcr_set = 0;
+	u64 mdcr_clear = 0;
+	u64 cptr_set = 0;
+
+	/* Trap/constrain PMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_PMUVER), feature_ids)) {
+		mdcr_set |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
+		mdcr_clear |= MDCR_EL2_HPME | MDCR_EL2_MTPME |
+			      MDCR_EL2_HPMN_MASK;
+	}
+
+	/* Trap Debug */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), feature_ids))
+		mdcr_set |= MDCR_EL2_TDRA | MDCR_EL2_TDA | MDCR_EL2_TDE;
+
+	/* Trap OS Double Lock */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_DOUBLELOCK), feature_ids))
+		mdcr_set |= MDCR_EL2_TDOSA;
+
+	/* Trap SPE */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER), feature_ids)) {
+		mdcr_set |= MDCR_EL2_TPMS;
+		mdcr_clear |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT;
+	}
+
+	/* Trap Trace Filter */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_TRACE_FILT), feature_ids))
+		mdcr_set |= MDCR_EL2_TTRF;
+
+	/* Trap Trace */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_TRACEVER), feature_ids))
+		cptr_set |= CPTR_EL2_TTA;
+
+	vcpu->arch.mdcr_el2 |= mdcr_set;
+	vcpu->arch.mdcr_el2 &= ~mdcr_clear;
+	vcpu->arch.cptr_el2 |= cptr_set;
+}
+
+/*
+ * Set trap register values for features not allowed in ID_AA64MMFR0.
+ */
+static void pvm_init_traps_aa64mmfr0(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = PVM_ID_AA64MMFR0_ALLOW |
+				PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED;
+	u64 mdcr_set = 0;
+
+	/* Trap Debug Communications Channel registers */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_FGT), feature_ids))
+		mdcr_set |= MDCR_EL2_TDCC;
+
+	vcpu->arch.mdcr_el2 |= mdcr_set;
+}
+
+/*
+ * Set trap register values for features not allowed in ID_AA64MMFR1.
+ */
+static void pvm_init_traps_aa64mmfr1(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = PVM_ID_AA64MMFR1_ALLOW;
+	u64 hcr_set = 0;
+
+	/* Trap LOR */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_LOR), feature_ids))
+		hcr_set |= HCR_TLOR;
+
+	vcpu->arch.hcr_el2 |= hcr_set;
+}
+
+/*
+ * Set baseline trap register values.
+ */
+static void pvm_init_trap_regs(struct kvm_vcpu *vcpu)
+{
+	const u64 hcr_trap_feat_regs = HCR_TID3;
+	const u64 hcr_trap_impdef = HCR_TACR | HCR_TIDCP | HCR_TID1;
+
+	/*
+	 * Always trap:
+	 * - Feature id registers: to control features exposed to guests
+	 * - Implementation-defined features
+	 */
+	vcpu->arch.hcr_el2 |= hcr_trap_feat_regs | hcr_trap_impdef;
+
+	/* Clear res0 and set res1 bits to trap potential new features. */
+	vcpu->arch.hcr_el2 &= ~(HCR_RES0);
+	vcpu->arch.mdcr_el2 &= ~(MDCR_EL2_RES0);
+	vcpu->arch.cptr_el2 |= CPTR_NVHE_EL2_RES1;
+	vcpu->arch.cptr_el2 &= ~(CPTR_NVHE_EL2_RES0);
+}
+
+/*
+ * Initialize trap register values for protected VMs.
+ */
+void kvm_init_protected_traps(struct kvm_vcpu *vcpu)
+{
+	pvm_init_trap_regs(vcpu);
+	pvm_init_traps_aa64pfr0(vcpu);
+	pvm_init_traps_aa64pfr1(vcpu);
+	pvm_init_traps_aa64dfr0(vcpu);
+	pvm_init_traps_aa64mmfr0(vcpu);
+	pvm_init_traps_aa64mmfr1(vcpu);
+}
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:32 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:32 +0100
Subject: [PATCH v4 13/15] KVM: arm64: Move sanitized copies of CPU features
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-14-tabba@google.com>

Move the sanitized copies of the CPU feature registers to the
recently created sys_regs.c. This consolidates all copies in a
more relevant file.

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/mem_protect.c | 6 ------
 arch/arm64/kvm/hyp/nvhe/sys_regs.c    | 2 ++
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index d938ce95d3bd..925c7db7fa34 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -25,12 +25,6 @@ struct host_kvm host_kvm;
 
 static struct hyp_pool host_s2_pool;
 
-/*
- * Copies of the host's CPU features registers holding sanitized values.
- */
-u64 id_aa64mmfr0_el1_sys_val;
-u64 id_aa64mmfr1_el1_sys_val;
-
 static const u8 pkvm_hyp_id = 1;
 
 static void *host_s2_zalloc_pages_exact(size_t size)
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index cd126d45cbcc..d641bae0467d 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -20,6 +20,8 @@
  */
 u64 id_aa64pfr0_el1_sys_val;
 u64 id_aa64pfr1_el1_sys_val;
+u64 id_aa64mmfr0_el1_sys_val;
+u64 id_aa64mmfr1_el1_sys_val;
 u64 id_aa64mmfr2_el1_sys_val;
 
 /*
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:33 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:33 +0100
Subject: [PATCH v4 14/15] KVM: arm64: Trap access to pVM restricted features
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-15-tabba@google.com>

Trap accesses to restricted features for VMs running in protected
mode.

Access to feature registers are emulated, and only supported
features are exposed to protected VMs.

Accesses to restricted registers as well as restricted
instructions are trapped, and an undefined exception is injected
into the protected guests, i.e., with EC = 0x0 (unknown reason).
This EC is the one used, according to the Arm Architecture
Reference Manual, for unallocated or undefined system registers
or instructions.

Only affects the functionality of protected VMs. Otherwise,
should not affect non-protected VMs when KVM is running in
protected mode.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h |  3 +++
 arch/arm64/kvm/hyp/nvhe/switch.c        | 34 ++++++++++++++-----------
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 5a2b89b96c67..8431f1514280 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -33,6 +33,9 @@
 extern struct exception_table_entry __start___kvm_ex_table;
 extern struct exception_table_entry __stop___kvm_ex_table;
 
+int kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu);
+int kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu);
+
 /* Check whether the FP regs were dirtied while in the host-side run loop: */
 static inline bool update_fp_enabled(struct kvm_vcpu *vcpu)
 {
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index b7f25307a7b9..398e62098898 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -159,27 +159,27 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
 }
 
 static exit_handle_fn hyp_exit_handlers[] = {
-	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[0 ... ESR_ELx_EC_MAX]		= kvm_handle_pvm_restricted,
 	[ESR_ELx_EC_WFx]		= NULL,
-	[ESR_ELx_EC_CP15_32]		= NULL,
-	[ESR_ELx_EC_CP15_64]		= NULL,
-	[ESR_ELx_EC_CP14_MR]		= NULL,
-	[ESR_ELx_EC_CP14_LS]		= NULL,
-	[ESR_ELx_EC_CP14_64]		= NULL,
+	[ESR_ELx_EC_CP15_32]		= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_CP15_64]		= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_CP14_MR]		= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_CP14_LS]		= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_CP14_64]		= kvm_handle_pvm_restricted,
 	[ESR_ELx_EC_HVC32]		= NULL,
 	[ESR_ELx_EC_SMC32]		= NULL,
 	[ESR_ELx_EC_HVC64]		= NULL,
 	[ESR_ELx_EC_SMC64]		= NULL,
-	[ESR_ELx_EC_SYS64]		= NULL,
-	[ESR_ELx_EC_SVE]		= NULL,
+	[ESR_ELx_EC_SYS64]		= kvm_handle_pvm_sys64,
+	[ESR_ELx_EC_SVE]		= kvm_handle_pvm_restricted,
 	[ESR_ELx_EC_IABT_LOW]		= NULL,
 	[ESR_ELx_EC_DABT_LOW]		= NULL,
-	[ESR_ELx_EC_SOFTSTP_LOW]	= NULL,
-	[ESR_ELx_EC_WATCHPT_LOW]	= NULL,
-	[ESR_ELx_EC_BREAKPT_LOW]	= NULL,
-	[ESR_ELx_EC_BKPT32]		= NULL,
-	[ESR_ELx_EC_BRK64]		= NULL,
-	[ESR_ELx_EC_FP_ASIMD]		= NULL,
+	[ESR_ELx_EC_SOFTSTP_LOW]	= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_WATCHPT_LOW]	= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_BREAKPT_LOW]	= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_BKPT32]		= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_BRK64]		= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_FP_ASIMD]		= kvm_handle_pvm_restricted,
 	[ESR_ELx_EC_PAC]		= NULL,
 };
 
@@ -188,7 +188,11 @@ exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
 	u32 esr = kvm_vcpu_get_esr(vcpu);
 	u8 esr_ec = ESR_ELx_EC(esr);
 
-	return hyp_exit_handlers[esr_ec];
+	/* For now, only protected VMs have exit handlers. */
+	if (unlikely(kvm_vm_is_protected(kern_hyp_va(vcpu->kvm))))
+		return hyp_exit_handlers[esr_ec];
+	else
+		return NULL;
 }
 
 /* Switch to the guest for legacy non-VHE systems */
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From tabba at google.com  Tue Aug 17 01:11:34 2021
From: tabba at google.com (Fuad Tabba)
Date: Tue, 17 Aug 2021 09:11:34 +0100
Subject: [PATCH v4 15/15] KVM: arm64: Handle protected guests at 32 bits
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <20210817081134.2918285-16-tabba@google.com>

Protected KVM does not support protected AArch32 guests. However,
it is possible for the guest to force run AArch32, potentially
causing problems. Add an extra check so that if the hypervisor
catches the guest doing that, it can prevent the guest from
running again by resetting vcpu->arch.target and returning
ARM_EXCEPTION_IL.

If this were to happen, The VMM can try and fix it by re-
initializing the vcpu with KVM_ARM_VCPU_INIT, however, this is
likely not possible for protected VMs.

Adapted from commit 22f553842b14 ("KVM: arm64: Handle Asymmetric
AArch32 systems")

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 37 ++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 398e62098898..0c24b7f473bf 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -20,6 +20,7 @@
 #include <asm/kprobes.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_fixed_config.h>
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
 #include <asm/fpsimd.h>
@@ -195,6 +196,39 @@ exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
 		return NULL;
 }
 
+/*
+ * Some guests (e.g., protected VMs) might not be allowed to run in AArch32. The
+ * check below is based on the one in kvm_arch_vcpu_ioctl_run().
+ * The ARMv8 architecture does not give the hypervisor a mechanism to prevent a
+ * guest from dropping to AArch32 EL0 if implemented by the CPU. If the
+ * hypervisor spots a guest in such a state ensure it is handled, and don't
+ * trust the host to spot or fix it.
+ *
+ * Returns true if the check passed and the guest run loop can continue, or
+ * false if the guest should exit to the host.
+ */
+static bool check_aarch32_guest(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	if (kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)) &&
+	    vcpu_mode_is_32bit(vcpu) &&
+	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0),
+					 PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) <
+		ID_AA64PFR0_ELx_32BIT_64BIT) {
+		/*
+		 * As we have caught the guest red-handed, decide that it isn't
+		 * fit for purpose anymore by making the vcpu invalid. The VMM
+		 * can try and fix it by re-initializing the vcpu with
+		 * KVM_ARM_VCPU_INIT, however, this is likely not possible for
+		 * protected VMs.
+		 */
+		vcpu->arch.target = -1;
+		*exit_code = ARM_EXCEPTION_IL;
+		return false;
+	}
+
+	return true;
+}
+
 /* Switch to the guest for legacy non-VHE systems */
 int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 {
@@ -255,6 +289,9 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 		/* Jump in the fire! */
 		exit_code = __guest_enter(vcpu);
 
+		if (unlikely(!check_aarch32_guest(vcpu, &exit_code)))
+			break;
+
 		/* And we're baaack! */
 	} while (fixup_guest_exit(vcpu, &exit_code));
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From alexandre.belloni at bootlin.com  Tue Aug 17 01:13:11 2021
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Tue, 17 Aug 2021 10:13:11 +0200
Subject: [PATCH v8 02/11] dt-bindings: rtc: sun6i: Add H616 compatible
 string
In-Reply-To: <20210817073810.7stuzrppyjf4spab@gilmour>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210723153838.6785-3-andre.przywara@arm.com>
 <20210726144137.6dauuxdssu7yszox@gilmour>
 <20210802013938.29fa18ed@slackpad.fritz.box>
 <20210817073810.7stuzrppyjf4spab@gilmour>
Message-ID: <YRtvl2FWKqAw4b3l@piout.net>

On 17/08/2021 09:38:10+0200, Maxime Ripard wrote:
> > > It's not entirely clear to me what those clocks are about though. If we
> > > look at the clock output in the user manual, it looks like there's only
> > > two clocks that are actually being output: the 32k "fanout" clock and
> > > the losc. What are the 3 you're talking about?]
> > 
> > I see three: the raw SYSTEM "CLK32K_LOSC", the RTC input + debounce
> > clock (/32), and the multiplexed PAD.
> 
> But the input and debounce clock is only for the RTC itself right? So it
> should be local to the driver and doesn't need to be made available to
> the other drivers
> 

Shouldn't they be exposed to be able to use assigned-clock?


-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From arnd at arndb.de  Tue Aug 17 01:15:52 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 17 Aug 2021 10:15:52 +0200
Subject: [GIT PULL] Qualcomm ARM64 updates for v5.15
In-Reply-To: <YRr6rLXRn0m4KUMx@builder.lan>
References: <20210816231223.586597-1-bjorn.andersson@linaro.org>
 <CAD=FV=XHOOjVgoQsS7vMDzeov0p6groC6Qnxz_TWpFj7dh7XLQ@mail.gmail.com>
 <YRr6rLXRn0m4KUMx@builder.lan>
Message-ID: <CAK8P3a0_dS_wvWSLx4RmnGc5dwYFyrsPrVNBAGs1DTXnWWoX-g@mail.gmail.com>

On Tue, Aug 17, 2021 at 1:54 AM Bjorn Andersson
<bjorn.andersson at linaro.org> wrote:
> On Mon 16 Aug 18:41 CDT 2021, Doug Anderson wrote:
> > On Mon, Aug 16, 2021 at 4:12 PM Bjorn Andersson
> > <bjorn.andersson at linaro.org> wrote:
> > >
> > > Douglas Anderson (1):
> > >       arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip
> >
> > I hope the above patch doesn't cause problems. I had landed it in the
> > drm-misc-next tree as per:
> >
> > https://lore.kernel.org/linux-arm-msm/YMDdyEzCpdttQyNu at builder.lan/
> >
> > Presumably git will magically do the right thing here since nothing
> > else on nearby lines is changing, but I at least wanted to point this
> > out in case there are any issues. Right now in linuxnext I see both
> > changes:
> >
> > ab428819ee3f arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip
> > ab6f24b404c9 arm64: dts: qcom: sc7180-trogdor: Move panel under the bridge chip
> >
>
> Yes, we agreed that you should take it through drm-misc and I must have
> forgotten about that as I drained the patchwork queue.
>
> This has been sitting in linux-next for a while now and I've not seen
> any reports from Stephen, so I think we're good.

I just double-checked that the merge went in properly, sometimes
this kind of patch causes entries, but in this case it's fine.

        Arnd


From joel at jms.id.au  Tue Aug 17 01:21:04 2021
From: joel at jms.id.au (Joel Stanley)
Date: Tue, 17 Aug 2021 08:21:04 +0000
Subject: [PATCH] ARM: dts: aspeed: cloudripper: Add comments for "mdio1"
In-Reply-To: <20210813061900.24539-1-rentao.bupt@gmail.com>
References: <20210813061900.24539-1-rentao.bupt@gmail.com>
Message-ID: <CACPK8Xei0K2vcEGc3Qr5zcb1SHMgNbJ+4_fVd6u-FiOHt4PxSg@mail.gmail.com>

On Fri, 13 Aug 2021 at 06:19, <rentao.bupt at gmail.com> wrote:
>
> From: Tao Ren <rentao.bupt at gmail.com>
>
> Add some comments to explain the purpose of "mdio1" controller: it's
> connected to the MDC/MDIO interface of the on-board management switch.
>
> Signed-off-by: Tao Ren <rentao.bupt at gmail.com>

Thanks, applied.

> ---
>  arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
> index 01ec3ce0a29d..9c6271a17ae8 100644
> --- a/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
> +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-cloudripper.dts
> @@ -96,6 +96,11 @@
>         status = "okay";
>  };
>
> +/*
> + * "mdio1" is connected to the MDC/MDIO interface of the on-board
> + * management switch (whose ports are connected to BMC, Host and front
> + * panel ethernet port).
> + */
>  &mdio1 {
>         status = "okay";
>  };
> --
> 2.17.1
>


From pavlica.nikola at gmail.com  Tue Aug 17 01:32:01 2021
From: pavlica.nikola at gmail.com (Nikola Pavlica)
Date: Tue, 17 Aug 2021 10:32:01 +0200
Subject: [PATCH] drm/panel-simple: Add Vivax TPC-9150 panel
Message-ID: <20210817083201.675133-1-pavlica.nikola@gmail.com>

The model and make of the LCD panel of the Vivax TPC-9150 is unknown,
hence the panel settings that were retrieved with a FEX dump are named
after the device NOT the actual panel.

The LCD in question is a 50 pin MISO TFT LCD panel of the resolution
1024x600 used by the aforementioned device.

Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 4e2dad314c79..97fc3c5740bb 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -4090,6 +4090,29 @@ static const struct panel_desc arm_rtsm = {
 	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
 };
 
+static const struct drm_display_mode vivax_tpc9150_panel_mode = {
+	.clock = 60000,
+	.hdisplay = 1024,
+	.hsync_start = 1024 + 160,
+	.hsync_end = 1024 + 160 + 100,
+	.htotal = 1024 + 160 + 100 + 60,
+	.vdisplay = 600,
+	.vsync_start = 600 + 12,
+	.vsync_end = 600 + 12 + 10,
+	.vtotal = 600 + 12 + 10 + 13,
+};
+
+static const struct panel_desc vivax_tpc9150_panel = {
+	.modes = &vivax_tpc9150_panel_mode,
+	.num_modes = 1,
+	.size = {
+		.width = 223,
+		.height = 125,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
+};
+
 static const struct of_device_id platform_of_match[] = {
 	{
 		.compatible = "ampire,am-1280800n3tzqw-t00h",
@@ -4103,6 +4126,9 @@ static const struct of_device_id platform_of_match[] = {
 	}, {
 		.compatible = "arm,rtsm-display",
 		.data = &arm_rtsm,
+	}, {
+		.compatible = "vivax,tpc9150-panel",
+		.data = &vivax_tpc9150_panel,
 	}, {
 		.compatible = "armadeus,st0700-adapt",
 		.data = &armadeus_st0700_adapt,
-- 
2.32.0



From mripard at kernel.org  Tue Aug 17 01:35:04 2021
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 17 Aug 2021 10:35:04 +0200
Subject: [GIT PULL] Allwinner Device Tree Changes for 5.15
Message-ID: <39cd7be5-a9a7-42b6-bc29-f895b9a3448a.lettre@localhost>

Hi,

It's been a fairly quiet merge window for us, but please pull the
following changes for the next release.

Thanks!
Maxime

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git refs/tags/sunxi-dt-for-5.15-1

for you to fetch changes up to 9d3ef21dca2c80fd9567869e28fa2a992a5e2c4b:

  arm64: dts: allwinner: h6: tanix-tx6: enable emmc (2021-07-26 09:11:49 +0200)

----------------------------------------------------------------
Our usual round of DT patches for the 5.15 merge window, with some
Tanix TX6 improvements this time.

----------------------------------------------------------------
Jernej Skrabec (3):
      arm64: dts: allwinner: h6: tanix-tx6: Fix regulator node names
      arm64: dts: allwinner: h6: tanix-tx6: Add PIO power supplies
      arm64: dts: allwinner: h6: tanix-tx6: enable emmc


 arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts | 27 ++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/ffb7df1d/attachment.sig>

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:22 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:22 +0800
Subject: [PATCH RESEND 2/9] dt-bindings: usb: mtk-xhci: add compatible for
 mt8195
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629189389-18779-2-git-send-email-chunfeng.yun@mediatek.com>

There are 4 USB controllers on MT8195, the controllers (IP1~IP3,
exclude IP0) have a wrong default SOF/ITP interval which is
calculated from the frame counter clock 24Mhz by default, but
in fact, the frame counter clock is 48Mhz, so we should set
the accurate interval according to 48Mhz. Here add a new compatible
for MT8195, it's also supported in driver. But the first controller
(IP0) has no such issue, we prefer to use generic compatible,
e.g. mt8192's compatible.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
index 61a0e550b5d6..753e043e5327 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
@@ -31,6 +31,7 @@ properties:
           - mediatek,mt8173-xhci
           - mediatek,mt8183-xhci
           - mediatek,mt8192-xhci
+          - mediatek,mt8195-xhci
       - const: mediatek,mtk-xhci
 
   reg:
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:21 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:21 +0800
Subject: [PATCH RESEND 1/9] dt-bindings: usb: mtk-xhci: add optional property
 to disable usb2 ports
Message-ID: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>

Add support to disable specific usb2 host ports, it's useful when
a usb2 port is disabled on some platforms, but enabled on others for
the same SoC, another case is that the different package may support
different number of ports.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
index 49729aab6d1a..61a0e550b5d6 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
@@ -154,6 +154,11 @@ properties:
     description: The mask to disable u3ports, bit0 for u3port0,
       bit1 for u3port1, ... etc
 
+  mediatek,u2p-dis-msk:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: The mask to disable u2ports, bit0 for u2port0,
+      bit1 for u2port1, ... etc
+
   "#address-cells":
     const: 1
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:27 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:27 +0800
Subject: [PATCH RESEND 7/9] usb: xhci-mtk: check boundary before check tt
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629189389-18779-7-git-send-email-chunfeng.yun@mediatek.com>

check_sch_tt() will access fs_bus_bw[] array, check boundary
firstly to avoid out-of-bounds issue.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk-sch.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 10c0f0f6461f..c2f13d69c607 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -600,13 +600,14 @@ static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
 	 * and find a microframe where its worst bandwidth is minimum.
 	 */
 	for (offset = 0; offset < sch_ep->esit; offset++) {
-		ret = check_sch_tt(sch_ep, offset);
-		if (ret)
-			continue;
 
 		if ((offset + sch_ep->num_budget_microframes) > esit_boundary)
 			break;
 
+		ret = check_sch_tt(sch_ep, offset);
+		if (ret)
+			continue;
+
 		worst_bw = get_max_bw(sch_bw, sch_ep, offset);
 		if (worst_bw > bw_boundary)
 			continue;
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:26 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:26 +0800
Subject: [PATCH RESEND 6/9] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629189389-18779-6-git-send-email-chunfeng.yun@mediatek.com>

Use @bw_budget_table[] to update fs bus bandwidth due to
not all microframes consume @bw_cost_per_microframe, see
setup_sch_info().

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 0bb1a6295d64..10c0f0f6461f 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 		 * Compared with hs bus, no matter what ep type,
 		 * the hub will always delay one uframe to send data
 		 */
-		for (j = 0; j < sch_ep->cs_count; j++) {
-			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
+		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j];
 			if (tmp > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
 		}
@@ -534,21 +534,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
 	u32 base, num_esit;
-	int bw_updated;
 	int i, j;
 
 	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
 
-	if (used)
-		bw_updated = sch_ep->bw_cost_per_microframe;
-	else
-		bw_updated = -sch_ep->bw_cost_per_microframe;
-
 	for (i = 0; i < num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 
-		for (j = 0; j < sch_ep->cs_count; j++)
-			tt->fs_bus_bw[base + j] += bw_updated;
+		for (j = 0; j < sch_ep->num_budget_microframes; j++)
+			if (used)
+				tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j];
+			else
+				tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j];
 	}
 
 	if (used)
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:23 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:23 +0800
Subject: [PATCH RESEND 3/9] usb: xhci-mtk: fix use-after-free of mtk->hcd
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629189389-18779-3-git-send-email-chunfeng.yun@mediatek.com>

 BUG: KASAN: use-after-free in usb_hcd_is_primary_hcd+0x38/0x60
 Call trace:
  dump_backtrace+0x0/0x3dc
  show_stack+0x20/0x2c
  dump_stack+0x15c/0x1d4
  print_address_description+0x7c/0x510
  kasan_report+0x164/0x1ac
  __asan_report_load8_noabort+0x44/0x50
  usb_hcd_is_primary_hcd+0x38/0x60
  xhci_mtk_runtime_suspend+0x68/0x148
  pm_generic_runtime_suspend+0x90/0xac
  __rpm_callback+0xb8/0x1f4
  rpm_callback+0x54/0x1d0
  rpm_suspend+0x4e0/0xc84
  __pm_runtime_suspend+0xc4/0x114
  xhci_mtk_probe+0xa58/0xd00

This may happen when probe fails, needn't suspend it synchronously,
fix it by using pm_runtime_put_noidle().

Reported-by: Pi Hsun <pihsun at google.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index d66b6a8b59ba..f6d161670c4e 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -573,7 +573,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
 	xhci_mtk_ldos_disable(mtk);
 
 disable_pm:
-	pm_runtime_put_sync_autosuspend(dev);
+	pm_runtime_put_noidle(dev);
 	pm_runtime_disable(dev);
 	return ret;
 }
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:25 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:25 +0800
Subject: [PATCH RESEND 5/9] usb: xhci-mtk: fix issue of out-of-bounds array
 access
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629189389-18779-5-git-send-email-chunfeng.yun@mediatek.com>

Bus bandwidth array access is based on esit, increase one
will cause out-of-bounds issue; for example, when esit is
XHCI_MTK_MAX_ESIT, will overstep boundary.

Fixes: 7c986fbc16ae ("usb: xhci-mtk: get the microframe boundary for ESIT")
Cc: <stable at vger.kernel.org>
Reported-by: Stan Lu <stan.lu at mediatek.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk-sch.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index cffcaf4dfa9f..0bb1a6295d64 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -575,10 +575,12 @@ static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
 	u32 boundary = sch_ep->esit;
 
 	if (sch_ep->sch_tt) { /* LS/FS with TT */
-		/* tune for CS */
-		if (sch_ep->ep_type != ISOC_OUT_EP)
-			boundary++;
-		else if (boundary > 1) /* normally esit >= 8 for FS/LS */
+		/*
+		 * tune for CS, normally esit >= 8 for FS/LS,
+		 * not add one for other types to avoid access array
+		 * out of boundary
+		 */
+		if (sch_ep->ep_type == ISOC_OUT_EP && boundary > 1)
 			boundary--;
 	}
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:24 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:24 +0800
Subject: [PATCH RESEND 4/9] usb: xhci-mtk: support option to disable usb2 ports
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629189389-18779-4-git-send-email-chunfeng.yun@mediatek.com>

Add support to disable specific usb2 host ports, it's useful when
a usb2 port is disabled on some platforms, but enabled on others
for the same SoC.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk.c | 12 ++++++++++--
 drivers/usb/host/xhci-mtk.h |  1 +
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index f6d161670c4e..12b691547438 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -116,8 +116,11 @@ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
 		writel(value, &ippc->u3_ctrl_p[i]);
 	}
 
-	/* power on and enable all u2 ports */
+	/* power on and enable all u2 ports except skipped ones */
 	for (i = 0; i < mtk->num_u2_ports; i++) {
+		if (BIT(i) & mtk->u2p_dis_msk)
+			continue;
+
 		value = readl(&ippc->u2_ctrl_p[i]);
 		value &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS);
 		value |= CTRL_U2_PORT_HOST_SEL;
@@ -164,8 +167,11 @@ static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk)
 		writel(value, &ippc->u3_ctrl_p[i]);
 	}
 
-	/* power down all u2 ports */
+	/* power down all u2 ports except skipped ones */
 	for (i = 0; i < mtk->num_u2_ports; i++) {
+		if (BIT(i) & mtk->u2p_dis_msk)
+			continue;
+
 		value = readl(&ippc->u2_ctrl_p[i]);
 		value |= CTRL_U2_PORT_PDN;
 		writel(value, &ippc->u2_ctrl_p[i]);
@@ -445,6 +451,8 @@ static int xhci_mtk_probe(struct platform_device *pdev)
 	/* optional property, ignore the error if it does not exist */
 	of_property_read_u32(node, "mediatek,u3p-dis-msk",
 			     &mtk->u3p_dis_msk);
+	of_property_read_u32(node, "mediatek,u2p-dis-msk",
+			     &mtk->u2p_dis_msk);
 
 	ret = usb_wakeup_of_property_parse(mtk, node);
 	if (ret) {
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index ace432356c41..0466bc8f7500 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -138,6 +138,7 @@ struct xhci_hcd_mtk {
 	struct mu3c_ippc_regs __iomem *ippc_regs;
 	int num_u2_ports;
 	int num_u3_ports;
+	int u2p_dis_msk;
 	int u3p_dis_msk;
 	struct regulator *vusb33;
 	struct regulator *vbus;
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:29 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:29 +0800
Subject: [PATCH RESEND 9/9] usb: xhci-mtk: modify the SOF/ITP interval for
 mt8195
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629189389-18779-9-git-send-email-chunfeng.yun@mediatek.com>

There are 4 USB controllers on MT8195, the controllers (IP1~IP3,
exclude IP0) have a wrong default SOF/ITP interval which is
calculated from the frame counter clock 24Mhz by default, but
in fact, the frame counter clock is 48Mhz, so we should set
the accurate interval according to 48Mhz for those controllers.
Note: the first controller no need set it.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk.c | 65 +++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 12b691547438..7ff0cd707ba1 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -57,6 +57,27 @@
 /* u2_phy_pll register */
 #define CTRL_U2_FORCE_PLL_STB	BIT(28)
 
+/* xHCI CSR */
+#define LS_EOF_CFG		0x930
+#define LSEOF_OFFSET		0x89
+
+#define FS_EOF_CFG		0x934
+#define FSEOF_OFFSET		0x2e
+
+#define SS_GEN1_EOF_CFG		0x93c
+#define SSG1EOF_OFFSET		0x78
+
+#define HFCNTR_CFG		0x944
+#define ITP_DELTA_CLK		(0xa << 1)
+#define ITP_DELTA_CLK_MASK	GENMASK(5, 1)
+#define FRMCNT_LEV1_RANG	(0x12b << 8)
+#define FRMCNT_LEV1_RANG_MASK	GENMASK(19, 8)
+
+#define SS_GEN2_EOF_CFG		0x990
+#define SSG2EOF_OFFSET		0x3c
+
+#define XSEOF_OFFSET_MASK	GENMASK(11, 0)
+
 /* usb remote wakeup registers in syscon */
 
 /* mt8173 etc */
@@ -87,6 +108,46 @@ enum ssusb_uwk_vers {
 	SSUSB_UWK_V1_2,		/* specific revision 1.2 */
 };
 
+/*
+ * MT8195 has 4 controllers, the controller1~3's default SOF/ITP interval
+ * is calculated from the frame counter clock 24M, but in fact, the clock
+ * is 48M, add workaround for it.
+ */
+static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk)
+{
+	struct device *dev = mtk->dev;
+	struct usb_hcd *hcd = mtk->hcd;
+	u32 value;
+
+	if (!of_device_is_compatible(dev->of_node, "mediatek,mt8195-xhci"))
+		return;
+
+	value = readl(hcd->regs + HFCNTR_CFG);
+	value &= ~(ITP_DELTA_CLK_MASK | FRMCNT_LEV1_RANG_MASK);
+	value |= (ITP_DELTA_CLK | FRMCNT_LEV1_RANG);
+	writel(value, hcd->regs + HFCNTR_CFG);
+
+	value = readl(hcd->regs + LS_EOF_CFG);
+	value &= ~XSEOF_OFFSET_MASK;
+	value |= LSEOF_OFFSET;
+	writel(value, hcd->regs + LS_EOF_CFG);
+
+	value = readl(hcd->regs + FS_EOF_CFG);
+	value &= ~XSEOF_OFFSET_MASK;
+	value |= FSEOF_OFFSET;
+	writel(value, hcd->regs + FS_EOF_CFG);
+
+	value = readl(hcd->regs + SS_GEN1_EOF_CFG);
+	value &= ~XSEOF_OFFSET_MASK;
+	value |= SSG1EOF_OFFSET;
+	writel(value, hcd->regs + SS_GEN1_EOF_CFG);
+
+	value = readl(hcd->regs + SS_GEN2_EOF_CFG);
+	value &= ~XSEOF_OFFSET_MASK;
+	value |= SSG2EOF_OFFSET;
+	writel(value, hcd->regs + SS_GEN2_EOF_CFG);
+}
+
 static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
 {
 	struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
@@ -368,6 +429,9 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
 		ret = xhci_mtk_ssusb_config(mtk);
 		if (ret)
 			return ret;
+
+		/* workaround only for mt8195 */
+		xhci_mtk_set_frame_interval(mtk);
 	}
 
 	ret = xhci_gen_setup(hcd, xhci_mtk_quirks);
@@ -716,6 +780,7 @@ static const struct dev_pm_ops xhci_mtk_pm_ops = {
 
 static const struct of_device_id mtk_xhci_of_match[] = {
 	{ .compatible = "mediatek,mt8173-xhci"},
+	{ .compatible = "mediatek,mt8195-xhci"},
 	{ .compatible = "mediatek,mtk-xhci"},
 	{ },
 };
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 01:36:28 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 16:36:28 +0800
Subject: [PATCH RESEND 8/9] usb: xhci-mtk: add a member of num_esit
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629189389-18779-8-git-send-email-chunfeng.yun@mediatek.com>

Add a member num_esit to save the number of esit, then no need
caculate it in some functions.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk-sch.c | 20 +++++++-------------
 drivers/usb/host/xhci-mtk.h     |  2 ++
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index c2f13d69c607..a9fcf7e30c41 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -297,6 +297,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 		 CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info));
 
 	sch_ep->esit = get_esit(ep_ctx);
+	sch_ep->num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
 	sch_ep->ep_type = ep_type;
 	sch_ep->maxpkt = maxpkt;
 	sch_ep->offset = 0;
@@ -401,14 +402,12 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, u32 offset)
 {
-	u32 num_esit;
 	u32 max_bw = 0;
 	u32 bw;
 	int i;
 	int j;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-	for (i = 0; i < num_esit; i++) {
+	for (i = 0; i < sch_ep->num_esit; i++) {
 		u32 base = offset + i * sch_ep->esit;
 
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
@@ -424,13 +423,11 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, bool used)
 {
-	u32 num_esit;
 	u32 base;
 	int i;
 	int j;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-	for (i = 0; i < num_esit; i++) {
+	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
 			if (used)
@@ -446,12 +443,11 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
-	u32 num_esit, tmp;
+	u32 tmp;
 	int base;
 	int i, j;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-	for (i = 0; i < num_esit; i++) {
+	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = offset + i * sch_ep->esit;
 
 		/*
@@ -533,12 +529,10 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
 static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
-	u32 base, num_esit;
+	u32 base;
 	int i, j;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-
-	for (i = 0; i < num_esit; i++) {
+	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 
 		for (j = 0; j < sch_ep->num_budget_microframes; j++)
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index 0466bc8f7500..56dc348349af 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -50,6 +50,7 @@ struct mu3h_sch_bw_info {
  * struct mu3h_sch_ep_info: schedule information for endpoint
  *
  * @esit: unit is 125us, equal to 2 << Interval field in ep-context
+ * @num_esit: number of @esit in a period
  * @num_budget_microframes: number of continuous uframes
  *		(@repeat==1) scheduled within the interval
  * @bw_cost_per_microframe: bandwidth cost per microframe
@@ -79,6 +80,7 @@ struct mu3h_sch_bw_info {
  */
 struct mu3h_sch_ep_info {
 	u32 esit;
+	u32 num_esit;
 	u32 num_budget_microframes;
 	u32 bw_cost_per_microframe;
 	struct list_head endpoint;
-- 
2.18.0

From bbudiredla at marvell.com  Tue Aug 17 02:11:34 2021
From: bbudiredla at marvell.com (Bhaskara Budiredla)
Date: Tue, 17 Aug 2021 09:11:34 +0000
Subject: [EXT] Re: [PATCH 2/2] dt-bindings: perf: Add YAML schemas for
 Marvell CN10K LLC-TAD pmu bindings
In-Reply-To: <1628856667.648308.3179071.nullmailer@robh.at.kernel.org>
References: <20210812174209.1970-1-bbudiredla@marvell.com>
 <20210812174209.1970-3-bbudiredla@marvell.com>
 <1628856667.648308.3179071.nullmailer@robh.at.kernel.org>
Message-ID: <CY4PR1801MB207047A1D761C136C9B18E76DEFE9@CY4PR1801MB2070.namprd18.prod.outlook.com>

Hi Rob,

Thanks for the steps. I seeing minimum version error, though the dtschema is latest.

$ make dt_binding_check
sort: -:2: disorder: 0
ERROR: dtschema minimum version is v2021.2.1
Documentation/devicetree/bindings/Makefile:12: recipe for target 'check_dtschema_version' failed
make[1]: *** [check_dtschema_version] Error 1
Makefile:1418: recipe for target 'dt_binding_check' failed
make: *** [dt_binding_check] Error 2

$ pip3 show dtschema
Name: dtschema
Version: 2021.7
Summary: DeviceTree validation schema and tools
Home-page: https://github.com/devicetree-org/dt-schema
Author: Rob Herring
Author-email: robh at kernel.org
License: BSD

Thanks,
Bhaskara

>-----Original Message-----
>From: Rob Herring <robh at kernel.org>
>Sent: Friday, August 13, 2021 5:41 PM
>To: Bhaskara Budiredla <bbudiredla at marvell.com>
>Cc: will at kernel.org; linux-arm-kernel at lists.infradead.org;
>mark.rutland at arm.com; Sunil Kovvuri Goutham <sgoutham at marvell.com>;
>devicetree at vger.kernel.org; robh+dt at kernel.org; linux-
>kernel at vger.kernel.org
>Subject: [EXT] Re: [PATCH 2/2] dt-bindings: perf: Add YAML schemas for
>Marvell CN10K LLC-TAD pmu bindings
>
>External Email
>
>----------------------------------------------------------------------
>On Thu, 12 Aug 2021 23:12:09 +0530, Bhaskara Budiredla wrote:
>> Add device tree bindings for Last-level-cache Tag-and-data
>> (LLC-TAD) unit PMU for Marvell CN10K SoCs.
>>
>> Signed-off-by: Bhaskara Budiredla <bbudiredla at marvell.com>
>> ---
>>  .../bindings/perf/marvell-cn10k-tad.yaml      | 45 +++++++++++++++++++
>>  1 file changed, 45 insertions(+)
>>  create mode 100644
>> Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml
>>
>
>My bot found errors running 'make DT_CHECKER_FLAGS=-m
>dt_binding_check'
>on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
>yamllint warnings/errors:
>
>dtschema/dtc warnings/errors:
>Documentation/devicetree/bindings/perf/marvell-cn10k-
>tad.example.dts:19.32-25.11: Warning (unit_address_format): /example-
>0/tad_pmu at 0x87e280000000: unit name should not have leading "0x"
>/builds/robherring/linux-dt-
>review/Documentation/devicetree/bindings/perf/marvell-cn10k-
>tad.example.dt.yaml: example-0: tad_pmu at 0x87e280000000:reg:0: [34786,
>2147483648, 0, 4096] is too long
>	From schema: /usr/local/lib/python3.8/dist-
>packages/dtschema/schemas/reg.yaml
>/builds/robherring/linux-dt-
>review/Documentation/devicetree/bindings/perf/marvell-cn10k-
>tad.example.dt.yaml: example-0: 'tad_pmu at 0x87e280000000' does not
>match any of the regexes: '.*-names$', '.*-supply$', '^#.*-cells$', '^#[a-zA-Z0-
>9,+\\-._]{0,63}$', '^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}$', '^[a-zA-Z][a-zA-Z0-9,+\\-
>._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$', '^__.*__$', 'pinctrl-[0-9]+'
>	From schema: /usr/local/lib/python3.8/dist-
>packages/dtschema/schemas/dt-core.yaml
>/builds/robherring/linux-dt-
>review/Documentation/devicetree/bindings/perf/marvell-cn10k-
>tad.example.dt.yaml: tad_pmu at 0x87e280000000: 'tad-cnt', 'tad-page-size',
>'tad-pmu-page-size' do not match any of the regexes: 'pinctrl-[0-9]+'
>	From schema: /builds/robherring/linux-dt-
>review/Documentation/devicetree/bindings/perf/marvell-cn10k-tad.yaml
>
>doc reference errors (make refcheckdocs):
>
>See https://urldefense.proofpoint.com/v2/url?u=https-
>3A__patchwork.ozlabs.org_patch_1516395&d=DwIBAg&c=nKjWec2b6R0mOy
>Paz7xtfQ&r=9P_lSljSO7KnQNkCGsgu9x_Op4mstSdqWN3Olr4bUv0&m=Kqfvr5E
>wn5St-
>WmEqTDaMI6uM6H5x0uiuOxZTYd15Gc&s=NYt8Ae1pxJhBgLN5asKagq1BUQi_
>gqK_RBkBSmcCvAU&e=
>
>This check can fail if there are any dependencies. The base for a patch series is
>generally the most recent rc1.
>
>If you already ran 'make dt_binding_check' and didn't see the above error(s),
>then make sure 'yamllint' is installed and dt-schema is up to
>date:
>
>pip3 install dtschema --upgrade
>
>Please check and re-submit.



From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:39 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:39 +0800
Subject: [PATCH v3 1/9] dt-bindings: phy: mediatek: tphy: support type switch
 by pericfg
Message-ID: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>

Add support type switch by pericfg register between USB3, PCIe,
SATA, SGMII, this is used to replace the way through efuse or
jumper.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: no changes
v2: add reviewed-by Rob
---
 .../devicetree/bindings/phy/mediatek,tphy.yaml   | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 838852cb8527..9e6c0f43f1c6 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -201,6 +201,22 @@ patternProperties:
           Specify the flag to enable BC1.2 if support it
         type: boolean
 
+      mediatek,syscon-type:
+        $ref: /schemas/types.yaml#/definitions/phandle-array
+        maxItems: 1
+        description:
+          A phandle to syscon used to access the register of type switch,
+          the field should always be 3 cells long.
+        items:
+          items:
+            - description:
+                The first cell represents a phandle to syscon
+            - description:
+                The second cell represents the register offset
+            - description:
+                The third cell represents the index of config segment
+              enum: [0, 1, 2, 3]
+
     required:
       - reg
       - "#phy-cells"
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:40 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:40 +0800
Subject: [PATCH v3 2/9] phy: phy-mtk-tphy: use clock bulk to get clocks
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-2-git-send-email-chunfeng.yun@mediatek.com>

Use clock bulk helpers to get/enable/disable clocks

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2~3: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 43 +++++++++--------------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 33000b38fd1b..3259210f08a1 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -280,6 +280,8 @@
 #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
 
+#define TPHY_CLKS_CNT	2
+
 enum mtk_phy_version {
 	MTK_PHY_V1 = 1,
 	MTK_PHY_V2,
@@ -318,8 +320,7 @@ struct mtk_phy_instance {
 		struct u2phy_banks u2_banks;
 		struct u3phy_banks u3_banks;
 	};
-	struct clk *ref_clk;	/* reference clock of (digital) phy */
-	struct clk *da_ref_clk;	/* reference clock of analog phy */
+	struct clk_bulk_data clks[TPHY_CLKS_CNT];
 	u32 index;
 	u8 type;
 	int eye_src;
@@ -974,18 +975,9 @@ static int mtk_phy_init(struct phy *phy)
 	struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent);
 	int ret;
 
-	ret = clk_prepare_enable(instance->ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable ref_clk\n");
+	ret = clk_bulk_prepare_enable(TPHY_CLKS_CNT, instance->clks);
+	if (ret)
 		return ret;
-	}
-
-	ret = clk_prepare_enable(instance->da_ref_clk);
-	if (ret) {
-		dev_err(tphy->dev, "failed to enable da_ref\n");
-		clk_disable_unprepare(instance->ref_clk);
-		return ret;
-	}
 
 	switch (instance->type) {
 	case PHY_TYPE_USB2:
@@ -1003,8 +995,7 @@ static int mtk_phy_init(struct phy *phy)
 		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
-		clk_disable_unprepare(instance->ref_clk);
-		clk_disable_unprepare(instance->da_ref_clk);
+		clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
 		return -EINVAL;
 	}
 
@@ -1047,8 +1038,7 @@ static int mtk_phy_exit(struct phy *phy)
 	if (instance->type == PHY_TYPE_USB2)
 		u2_phy_instance_exit(tphy, instance);
 
-	clk_disable_unprepare(instance->ref_clk);
-	clk_disable_unprepare(instance->da_ref_clk);
+	clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
 	return 0;
 }
 
@@ -1211,6 +1201,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 	port = 0;
 	for_each_child_of_node(np, child_np) {
 		struct mtk_phy_instance *instance;
+		struct clk_bulk_data *clks;
 		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1247,20 +1238,12 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		phy_set_drvdata(phy, instance);
 		port++;
 
-		instance->ref_clk = devm_clk_get_optional(&phy->dev, "ref");
-		if (IS_ERR(instance->ref_clk)) {
-			dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->ref_clk);
+		clks = instance->clks;
+		clks[0].id = "ref";     /* digital (& analog) clock */
+		clks[1].id = "da_ref";  /* analog clock */
+		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
+		if (retval)
 			goto put_child;
-		}
-
-		instance->da_ref_clk =
-			devm_clk_get_optional(&phy->dev, "da_ref");
-		if (IS_ERR(instance->da_ref_clk)) {
-			dev_err(dev, "failed to get da_ref_clk(id-%d)\n", port);
-			retval = PTR_ERR(instance->da_ref_clk);
-			goto put_child;
-		}
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:42 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:42 +0800
Subject: [PATCH v3 4/9] phy: phy-mtk-tphy: print error log using child device
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-4-git-send-email-chunfeng.yun@mediatek.com>

Print error log using child devices instead of parent device.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2~3: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index a6502058a1a5..9d4b34298137 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1278,6 +1278,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 	for_each_child_of_node(np, child_np) {
 		struct mtk_phy_instance *instance;
 		struct clk_bulk_data *clks;
+		struct device *subdev;
 		struct phy *phy;
 
 		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
@@ -1295,16 +1296,17 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 			goto put_child;
 		}
 
+		subdev = &phy->dev;
 		retval = of_address_to_resource(child_np, 0, &res);
 		if (retval) {
-			dev_err(dev, "failed to get address resource(id-%d)\n",
+			dev_err(subdev, "failed to get address resource(id-%d)\n",
 				port);
 			goto put_child;
 		}
 
-		instance->port_base = devm_ioremap_resource(&phy->dev, &res);
+		instance->port_base = devm_ioremap_resource(subdev, &res);
 		if (IS_ERR(instance->port_base)) {
-			dev_err(dev, "failed to remap phy regs\n");
+			dev_err(subdev, "failed to remap phy regs\n");
 			retval = PTR_ERR(instance->port_base);
 			goto put_child;
 		}
@@ -1317,7 +1319,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		clks = instance->clks;
 		clks[0].id = "ref";     /* digital (& analog) clock */
 		clks[1].id = "da_ref";  /* analog clock */
-		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
+		retval = devm_clk_bulk_get_optional(subdev, TPHY_CLKS_CNT, clks);
 		if (retval)
 			goto put_child;
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:41 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:41 +0800
Subject: [PATCH v3 3/9] phy: phy-mtk-tphy: support type switch by pericfg
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-3-git-send-email-chunfeng.yun@mediatek.com>

Add support type switch between USB3, PCIe, SATA and SGMII by
pericfg register, this is used to take the place of efuse or
jumper.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2~3: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 84 ++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 3259210f08a1..a6502058a1a5 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -10,11 +10,13 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 
 /* version V1 sub-banks offset base address */
 /* banks shared by multiple phys */
@@ -280,6 +282,14 @@
 #define RG_CDR_BIRLTD0_GEN3_MSK		GENMASK(4, 0)
 #define RG_CDR_BIRLTD0_GEN3_VAL(x)	(0x1f & (x))
 
+/* PHY switch between pcie/usb3/sgmii/sata */
+#define USB_PHY_SWITCH_CTRL	0x0
+#define RG_PHY_SW_TYPE		GENMASK(3, 0)
+#define RG_PHY_SW_PCIE		0x0
+#define RG_PHY_SW_USB3		0x1
+#define RG_PHY_SW_SGMII		0x2
+#define RG_PHY_SW_SATA		0x3
+
 #define TPHY_CLKS_CNT	2
 
 enum mtk_phy_version {
@@ -322,7 +332,10 @@ struct mtk_phy_instance {
 	};
 	struct clk_bulk_data clks[TPHY_CLKS_CNT];
 	u32 index;
-	u8 type;
+	u32 type;
+	struct regmap *type_sw;
+	u32 type_sw_reg;
+	u32 type_sw_index;
 	int eye_src;
 	int eye_vrt;
 	int eye_term;
@@ -969,6 +982,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
 	}
 }
 
+/* type switch for usb3/pcie/sgmii/sata */
+static int phy_type_syscon_get(struct mtk_phy_instance *instance,
+			       struct device_node *dn)
+{
+	struct of_phandle_args args;
+	int ret;
+
+	/* type switch function is optional */
+	if (!of_property_read_bool(dn, "mediatek,syscon-type"))
+		return 0;
+
+	ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type",
+					       2, 0, &args);
+	if (ret)
+		return ret;
+
+	instance->type_sw_reg = args.args[0];
+	instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
+	instance->type_sw = syscon_node_to_regmap(args.np);
+	of_node_put(args.np);
+	dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n",
+		 instance->type_sw_reg, instance->type_sw_index);
+
+	return PTR_ERR_OR_ZERO(instance->type_sw);
+}
+
+static int phy_type_set(struct mtk_phy_instance *instance)
+{
+	int type;
+	u32 mask;
+
+	if (!instance->type_sw)
+		return 0;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB3:
+		type = RG_PHY_SW_USB3;
+		break;
+	case PHY_TYPE_PCIE:
+		type = RG_PHY_SW_PCIE;
+		break;
+	case PHY_TYPE_SGMII:
+		type = RG_PHY_SW_SGMII;
+		break;
+	case PHY_TYPE_SATA:
+		type = RG_PHY_SW_SATA;
+		break;
+	case PHY_TYPE_USB2:
+	default:
+		return 0;
+	}
+
+	mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE);
+	regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type);
+
+	return 0;
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -993,6 +1064,9 @@ static int mtk_phy_init(struct phy *phy)
 	case PHY_TYPE_SATA:
 		sata_phy_instance_init(tphy, instance);
 		break;
+	case PHY_TYPE_SGMII:
+		/* nothing to do, only used to set type */
+		break;
 	default:
 		dev_err(tphy->dev, "incompatible PHY type\n");
 		clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks);
@@ -1081,7 +1155,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	if (!(instance->type == PHY_TYPE_USB2 ||
 	      instance->type == PHY_TYPE_USB3 ||
 	      instance->type == PHY_TYPE_PCIE ||
-	      instance->type == PHY_TYPE_SATA)) {
+	      instance->type == PHY_TYPE_SATA ||
+	      instance->type == PHY_TYPE_SGMII)) {
 		dev_err(dev, "unsupported device type: %d\n", instance->type);
 		return ERR_PTR(-EINVAL);
 	}
@@ -1100,6 +1175,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	}
 
 	phy_parse_property(tphy, instance);
+	phy_type_set(instance);
 
 	return instance->phy;
 }
@@ -1244,6 +1320,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 		retval = devm_clk_bulk_get_optional(&phy->dev, TPHY_CLKS_CNT, clks);
 		if (retval)
 			goto put_child;
+
+		retval = phy_type_syscon_get(instance, child_np);
+		if (retval)
+			goto put_child;
 	}
 
 	provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:46 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:46 +0800
Subject: [PATCH v3 8/9] phy: phy-mtk-mipi-dsi: remove dummy assignment of
 error number
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-8-git-send-email-chunfeng.yun@mediatek.com>

Return the error number directly without assignment

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: no changes
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 01cf31633019..61c942fbf4a1 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -203,10 +203,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 	phy_set_drvdata(phy, mipi_tx);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-	if (IS_ERR(phy_provider)) {
-		ret = PTR_ERR(phy_provider);
-		return ret;
-	}
+	if (IS_ERR(phy_provider))
+		return PTR_ERR(phy_provider);
 
 	mipi_tx->dev = dev;
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:47 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:47 +0800
Subject: [PATCH v3 9/9] phy: phy-mtk-mipi-dsi: convert to
 devm_platform_ioremap_resource
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-9-git-send-email-chunfeng.yun@mediatek.com>

Use devm_platform_ioremap_resource to simplify code

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: no changes
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 61c942fbf4a1..28ad9403c441 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -130,7 +130,6 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_mipi_tx *mipi_tx;
-	struct resource *mem;
 	const char *ref_clk_name;
 	struct clk *ref_clk;
 	struct clk_init_data clk_init = {
@@ -148,11 +147,9 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mipi_tx->regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(mipi_tx->regs)) {
+	mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(mipi_tx->regs))
 		return PTR_ERR(mipi_tx->regs);
-	}
 
 	ref_clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(ref_clk)) {
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:45 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:45 +0800
Subject: [PATCH v3 7/9] phy: phy-mtk-hdmi: convert to
 devm_platform_ioremap_resource
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-7-git-send-email-chunfeng.yun@mediatek.com>

Use devm_platform_ioremap_resource to simplify code

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: no changes
v2: add acked-by CK
---
 drivers/phy/mediatek/phy-mtk-hdmi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index 8ad8f717ef43..5fb4217fb8e0 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -100,7 +100,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_hdmi_phy *hdmi_phy;
-	struct resource *mem;
 	struct clk *ref_clk;
 	const char *ref_clk_name;
 	struct clk_init_data clk_init = {
@@ -116,11 +115,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 	if (!hdmi_phy)
 		return -ENOMEM;
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi_phy->regs = devm_ioremap_resource(dev, mem);
-	if (IS_ERR(hdmi_phy->regs)) {
+	hdmi_phy->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(hdmi_phy->regs))
 		return PTR_ERR(hdmi_phy->regs);
-	}
 
 	ref_clk = devm_clk_get(dev, "pll_ref");
 	if (IS_ERR(ref_clk)) {
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:44 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:44 +0800
Subject: [PATCH v3 6/9] phy: phy-mtk-ufs: use clock bulk to get clocks
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-6-git-send-email-chunfeng.yun@mediatek.com>

Use clock bulk helpers to get/enable/disable clocks

Reviewed-by: Stanley Chu <stanley.chu at mediatek.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: add reviewed-by Stanley
v2: no changes
---
 drivers/phy/mediatek/phy-mtk-ufs.c | 44 ++++++++----------------------
 1 file changed, 11 insertions(+), 33 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-ufs.c b/drivers/phy/mediatek/phy-mtk-ufs.c
index 769b00b038d8..a6af06941203 100644
--- a/drivers/phy/mediatek/phy-mtk-ufs.c
+++ b/drivers/phy/mediatek/phy-mtk-ufs.c
@@ -31,11 +31,12 @@
 #define FRC_CDR_ISO_EN              BIT(19)
 #define CDR_ISO_EN                  BIT(20)
 
+#define UFSPHY_CLKS_CNT    2
+
 struct ufs_mtk_phy {
 	struct device *dev;
 	void __iomem *mmio;
-	struct clk *mp_clk;
-	struct clk *unipro_clk;
+	struct clk_bulk_data clks[UFSPHY_CLKS_CNT];
 };
 
 static inline u32 mphy_readl(struct ufs_mtk_phy *phy, u32 reg)
@@ -74,20 +75,11 @@ static struct ufs_mtk_phy *get_ufs_mtk_phy(struct phy *generic_phy)
 static int ufs_mtk_phy_clk_init(struct ufs_mtk_phy *phy)
 {
 	struct device *dev = phy->dev;
+	struct clk_bulk_data *clks = phy->clks;
 
-	phy->unipro_clk = devm_clk_get(dev, "unipro");
-	if (IS_ERR(phy->unipro_clk)) {
-		dev_err(dev, "failed to get clock: unipro");
-		return PTR_ERR(phy->unipro_clk);
-	}
-
-	phy->mp_clk = devm_clk_get(dev, "mp");
-	if (IS_ERR(phy->mp_clk)) {
-		dev_err(dev, "failed to get clock: mp");
-		return PTR_ERR(phy->mp_clk);
-	}
-
-	return 0;
+	clks[0].id = "unipro";
+	clks[1].id = "mp";
+	return devm_clk_bulk_get(dev, UFSPHY_CLKS_CNT, clks);
 }
 
 static void ufs_mtk_phy_set_active(struct ufs_mtk_phy *phy)
@@ -150,26 +142,13 @@ static int ufs_mtk_phy_power_on(struct phy *generic_phy)
 	struct ufs_mtk_phy *phy = get_ufs_mtk_phy(generic_phy);
 	int ret;
 
-	ret = clk_prepare_enable(phy->unipro_clk);
-	if (ret) {
-		dev_err(phy->dev, "unipro_clk enable failed %d\n", ret);
-		goto out;
-	}
-
-	ret = clk_prepare_enable(phy->mp_clk);
-	if (ret) {
-		dev_err(phy->dev, "mp_clk enable failed %d\n", ret);
-		goto out_unprepare_unipro_clk;
-	}
+	ret = clk_bulk_prepare_enable(UFSPHY_CLKS_CNT, phy->clks);
+	if (ret)
+		return ret;
 
 	ufs_mtk_phy_set_active(phy);
 
 	return 0;
-
-out_unprepare_unipro_clk:
-	clk_disable_unprepare(phy->unipro_clk);
-out:
-	return ret;
 }
 
 static int ufs_mtk_phy_power_off(struct phy *generic_phy)
@@ -178,8 +157,7 @@ static int ufs_mtk_phy_power_off(struct phy *generic_phy)
 
 	ufs_mtk_phy_set_deep_hibern(phy);
 
-	clk_disable_unprepare(phy->unipro_clk);
-	clk_disable_unprepare(phy->mp_clk);
+	clk_bulk_disable_unprepare(UFSPHY_CLKS_CNT, phy->clks);
 
 	return 0;
 }
-- 
2.18.0

From chunfeng.yun at mediatek.com  Tue Aug 17 02:19:43 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Tue, 17 Aug 2021 17:19:43 +0800
Subject: [PATCH v3 5/9] phy: phy-mtk-tphy: remove error log of ioremap failure
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629191987-20774-5-git-send-email-chunfeng.yun@mediatek.com>

devm_ioremap_resource() will print log if error happens.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2~3: no changes
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 9d4b34298137..cdcef865fe9e 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -1306,7 +1306,6 @@ static int mtk_tphy_probe(struct platform_device *pdev)
 
 		instance->port_base = devm_ioremap_resource(subdev, &res);
 		if (IS_ERR(instance->port_base)) {
-			dev_err(subdev, "failed to remap phy regs\n");
 			retval = PTR_ERR(instance->port_base);
 			goto put_child;
 		}
-- 
2.18.0

From lkp at intel.com  Tue Aug 17 02:39:28 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:28 +0800
Subject: [soc:tegra/defconfig] BUILD SUCCESS
 806b99206b840bcf3bfa44227dc978880d13ed1b
Message-ID: <611b83d0.oyGYfonSaMXNYMep%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tegra/defconfig
branch HEAD: 806b99206b840bcf3bfa44227dc978880d13ed1b  ARM: multi_v7_defconfig: Enable CONFIG_TEGRA30_TSENSOR

elapsed time: 6938m

configs tested: 224
configs skipped: 115

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210813
powerpc                     mpc5200_defconfig
parisc                              defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
sh                          polaris_defconfig
powerpc                      bamboo_defconfig
powerpc                       holly_defconfig
powerpc                mpc7448_hpc2_defconfig
powerpc                        cell_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
powerpc                      ep88xc_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                       aspeed_g5_defconfig
mips                        omega2p_defconfig
powerpc                        warp_defconfig
powerpc                     stx_gp3_defconfig
xtensa                  nommu_kc705_defconfig
m68k                             alldefconfig
sh                          rsk7264_defconfig
sh                            titan_defconfig
powerpc                     asp8347_defconfig
arc                          axs103_defconfig
powerpc                        icon_defconfig
powerpc                      tqm8xx_defconfig
arm                         lpc18xx_defconfig
sh                        edosk7760_defconfig
x86_64                            allnoconfig
sh                             shx3_defconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lubbock_defconfig
nios2                         3c120_defconfig
ia64                        generic_defconfig
powerpc                     tqm8555_defconfig
powerpc                      acadia_defconfig
arm                          simpad_defconfig
mips                  cavium_octeon_defconfig
nds32                               defconfig
parisc                           alldefconfig
arm                      tct_hammer_defconfig
powerpc                      obs600_defconfig
m68k                       m5208evb_defconfig
x86_64                           alldefconfig
mips                            gpr_defconfig
mips                      maltaaprp_defconfig
riscv                    nommu_k210_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                       omap2plus_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
m68k                        mvme147_defconfig
mips                  decstation_64_defconfig
mips                        bcm63xx_defconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
sh                          landisk_defconfig
arm                             mxs_defconfig
mips                           ci20_defconfig
mips                           ip22_defconfig
mips                        workpad_defconfig
mips                     decstation_defconfig
mips                          ath25_defconfig
powerpc                     ppa8548_defconfig
arc                        nsimosci_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
sh                          urquell_defconfig
microblaze                      mmu_defconfig
arm                         nhk8815_defconfig
sh                           se7705_defconfig
arc                    vdk_hs38_smp_defconfig
arm                            xcep_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
powerpc                  iss476-smp_defconfig
sh                         ap325rxa_defconfig
arm                          gemini_defconfig
sh                               alldefconfig
sh                         apsh4a3a_defconfig
powerpc                      cm5200_defconfig
powerpc                           allnoconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
powerpc                       ebony_defconfig
mips                            ar7_defconfig
mips                         tb0226_defconfig
arm                        oxnas_v6_defconfig
arm                            zeus_defconfig
sh                             sh03_defconfig
mips                        maltaup_defconfig
arc                     nsimosci_hs_defconfig
arm                            pleb_defconfig
powerpc                        fsp2_defconfig
arm                       multi_v4t_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
um                             i386_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 02:39:31 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:31 +0800
Subject: [soc:tegra/dt] BUILD SUCCESS 2270ad2f4e123336af685ecedd1618701cb4ca1e
Message-ID: <611b83d3.E7v/p4a8ugzZVgY0%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tegra/dt
branch HEAD: 2270ad2f4e123336af685ecedd1618701cb4ca1e  ARM: tegra: tamonten: Fix UART pad setting

elapsed time: 5340m

configs tested: 223
configs skipped: 136

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210813
i386                 randconfig-c001-20210816
openrisc                  or1klitex_defconfig
m68k                        m5407c3_defconfig
powerpc                    klondike_defconfig
mips                     loongson1c_defconfig
arm                          ep93xx_defconfig
arm                          iop32x_defconfig
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                        clps711x_defconfig
nios2                            alldefconfig
xtensa                    xip_kc705_defconfig
powerpc                 mpc837x_mds_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
powerpc                     pq2fads_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lpc18xx_defconfig
arm                         lubbock_defconfig
arm                       imx_v4_v5_defconfig
powerpc                     rainier_defconfig
sh                            shmin_defconfig
h8300                               defconfig
sh                          rsk7269_defconfig
ia64                          tiger_defconfig
arm                             rpc_defconfig
powerpc                      ppc40x_defconfig
sh                           se7750_defconfig
powerpc                    socrates_defconfig
riscv                             allnoconfig
powerpc                     ksi8560_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
h8300                            allyesconfig
sh                           se7206_defconfig
sh                                  defconfig
arm                           corgi_defconfig
xtensa                  audio_kc705_defconfig
parisc                           alldefconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
sh                 kfr2r09-romimage_defconfig
sh                        edosk7760_defconfig
parisc                generic-64bit_defconfig
arm                           h5000_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
powerpc                    amigaone_defconfig
mips                  decstation_64_defconfig
arm                          pxa3xx_defconfig
mips                           rs90_defconfig
mips                         cobalt_defconfig
openrisc                    or1ksim_defconfig
mips                        nlm_xlp_defconfig
sh                           se7705_defconfig
arc                    vdk_hs38_smp_defconfig
arm                            xcep_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
powerpc                  iss476-smp_defconfig
sh                   sh7724_generic_defconfig
sh                          sdk7780_defconfig
arm                             mxs_defconfig
powerpc                        warp_defconfig
m68k                        stmark2_defconfig
sh                          kfr2r09_defconfig
powerpc                     ep8248e_defconfig
arm                       spear13xx_defconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
powerpc                     ppa8548_defconfig
arm                         nhk8815_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                     decstation_defconfig
um                             i386_defconfig
arm                      jornada720_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                                defconfig
m68k                             allmodconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
csky                                defconfig
alpha                               defconfig
nios2                            allyesconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
i386                 randconfig-a004-20210814
i386                 randconfig-a001-20210814
i386                 randconfig-a006-20210814
i386                 randconfig-a005-20210814
i386                 randconfig-a002-20210814
i386                 randconfig-a003-20210814
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a011-20210813
x86_64               randconfig-a013-20210813
x86_64               randconfig-a012-20210813
x86_64               randconfig-a016-20210813
x86_64               randconfig-a015-20210813
x86_64               randconfig-a014-20210813
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
i386                 randconfig-a011-20210814
i386                 randconfig-a015-20210814
i386                 randconfig-a013-20210814
i386                 randconfig-a014-20210814
i386                 randconfig-a016-20210814
i386                 randconfig-a012-20210814
riscv                    nommu_k210_defconfig
riscv                    nommu_virt_defconfig
riscv                          rv32_defconfig
riscv                            allyesconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210814
x86_64               randconfig-c001-20210813
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a013-20210814
x86_64               randconfig-a011-20210814
x86_64               randconfig-a016-20210814
x86_64               randconfig-a012-20210814
x86_64               randconfig-a014-20210814
x86_64               randconfig-a015-20210814
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 02:39:23 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:23 +0800
Subject: [soc:imx/dt-2] BUILD SUCCESS 87a8c7164022d2e5c558bc0e14075c7a50af7f95
Message-ID: <611b83cb.MavTS2lE1iArUcp1%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git imx/dt-2
branch HEAD: 87a8c7164022d2e5c558bc0e14075c7a50af7f95  ARM: dts: imx6qp-prtwd3: configure ENET_REF clock to 125MHz

elapsed time: 4528m

configs tested: 213
configs skipped: 110

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210814
i386                 randconfig-c001-20210816
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
mips                            ar7_defconfig
arm64                            alldefconfig
arm                            pleb_defconfig
powerpc                       ppc64_defconfig
sh                   sh7770_generic_defconfig
openrisc                  or1klitex_defconfig
m68k                        m5407c3_defconfig
powerpc                    klondike_defconfig
mips                     loongson1c_defconfig
arm                          ep93xx_defconfig
arm                          iop32x_defconfig
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                            zeus_defconfig
arm                        clps711x_defconfig
nios2                            alldefconfig
xtensa                    xip_kc705_defconfig
powerpc                 mpc837x_mds_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
powerpc                     pq2fads_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lpc18xx_defconfig
arm                         lubbock_defconfig
powerpc                     tqm5200_defconfig
powerpc                      walnut_defconfig
mips                      bmips_stb_defconfig
sh                           se7619_defconfig
arm                         orion5x_defconfig
powerpc                    mvme5100_defconfig
powerpc                     rainier_defconfig
mips                        nlm_xlr_defconfig
sh                             shx3_defconfig
sh                          rsk7269_defconfig
ia64                          tiger_defconfig
arm                             rpc_defconfig
powerpc                      ppc40x_defconfig
arm                          simpad_defconfig
powerpc                       maple_defconfig
powerpc                         wii_defconfig
powerpc                     ksi8560_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
h8300                            allyesconfig
sh                           se7206_defconfig
sh                                  defconfig
arm                           corgi_defconfig
xtensa                  audio_kc705_defconfig
h8300                       h8s-sim_defconfig
arm                       aspeed_g4_defconfig
sh                  sh7785lcr_32bit_defconfig
mips                       lemote2f_defconfig
parisc                           alldefconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
sh                 kfr2r09-romimage_defconfig
sh                        edosk7760_defconfig
parisc                generic-64bit_defconfig
arm                           h5000_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
mips                     cu1830-neo_defconfig
powerpc                     asp8347_defconfig
powerpc                 canyonlands_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                  decstation_64_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
sh                           se7705_defconfig
arc                    vdk_hs38_smp_defconfig
arm                            xcep_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
powerpc                     ppa8548_defconfig
arm                         nhk8815_defconfig
mips                     decstation_defconfig
arm                            lart_defconfig
mips                          rm200_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
um                             i386_defconfig
arm                      jornada720_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
x86_64               randconfig-a004-20210814
x86_64               randconfig-a006-20210814
x86_64               randconfig-a003-20210814
x86_64               randconfig-a001-20210814
x86_64               randconfig-a005-20210814
x86_64               randconfig-a002-20210814
i386                 randconfig-a004-20210814
i386                 randconfig-a002-20210814
i386                 randconfig-a001-20210814
i386                 randconfig-a003-20210814
i386                 randconfig-a006-20210814
i386                 randconfig-a005-20210814
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
i386                 randconfig-a011-20210814
i386                 randconfig-a015-20210814
i386                 randconfig-a013-20210814
i386                 randconfig-a014-20210814
i386                 randconfig-a016-20210814
i386                 randconfig-a012-20210814
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210814
x86_64               randconfig-a013-20210814
x86_64               randconfig-a011-20210814
x86_64               randconfig-a016-20210814
x86_64               randconfig-a012-20210814
x86_64               randconfig-a014-20210814
x86_64               randconfig-a015-20210814
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 02:39:25 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:25 +0800
Subject: [soc:tegra/dt-bindings] BUILD SUCCESS
 900a486ac73dfdf9b1629e7e4df6eacc92da7578
Message-ID: <611b83cd.9HsWicy/oXBUrNt3%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tegra/dt-bindings
branch HEAD: 900a486ac73dfdf9b1629e7e4df6eacc92da7578  dt-bindings: tegra: Document NVIDIA Jetson TX2 NX developer kit

elapsed time: 6938m

configs tested: 271
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210813
powerpc                     mpc5200_defconfig
parisc                              defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
sh                          polaris_defconfig
powerpc                      bamboo_defconfig
powerpc                       holly_defconfig
powerpc                mpc7448_hpc2_defconfig
powerpc                        cell_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
powerpc                      ep88xc_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                       aspeed_g5_defconfig
mips                        omega2p_defconfig
powerpc                        warp_defconfig
powerpc                     stx_gp3_defconfig
xtensa                  nommu_kc705_defconfig
m68k                             alldefconfig
sh                          rsk7264_defconfig
sh                            titan_defconfig
powerpc                     asp8347_defconfig
arc                          axs103_defconfig
powerpc                        icon_defconfig
powerpc                      tqm8xx_defconfig
arm                         lpc18xx_defconfig
sh                        edosk7760_defconfig
x86_64                            allnoconfig
sh                             shx3_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
powerpc                     pq2fads_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lubbock_defconfig
i386                             alldefconfig
mips                      fuloong2e_defconfig
mips                           mtx1_defconfig
arm                           u8500_defconfig
nios2                         3c120_defconfig
ia64                        generic_defconfig
powerpc                     tqm8555_defconfig
powerpc                      acadia_defconfig
arm                          simpad_defconfig
mips                  cavium_octeon_defconfig
nds32                               defconfig
parisc                           alldefconfig
arm                      tct_hammer_defconfig
powerpc                      obs600_defconfig
powerpc                    mvme5100_defconfig
powerpc                     rainier_defconfig
mips                        nlm_xlr_defconfig
arm                     eseries_pxa_defconfig
arm                         vf610m4_defconfig
powerpc                      ppc40x_defconfig
powerpc                      ppc44x_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
m68k                       m5208evb_defconfig
x86_64                           alldefconfig
mips                            gpr_defconfig
mips                      maltaaprp_defconfig
riscv                    nommu_k210_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
m68k                        mvme147_defconfig
mips                  decstation_64_defconfig
mips                        bcm63xx_defconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
mips                          rm200_defconfig
powerpc                       ppc64_defconfig
xtensa                  audio_kc705_defconfig
mips                      loongson3_defconfig
mips                          ath79_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
sh                          r7780mp_defconfig
mips                          ath25_defconfig
m68k                             allyesconfig
sh                          landisk_defconfig
arm                             mxs_defconfig
mips                           ci20_defconfig
mips                     decstation_defconfig
powerpc                     ppa8548_defconfig
arc                        nsimosci_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
riscv                             allnoconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
sh                          urquell_defconfig
microblaze                      mmu_defconfig
arm                         nhk8815_defconfig
sh                           se7705_defconfig
arc                    vdk_hs38_smp_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
sh                         ap325rxa_defconfig
sh                               alldefconfig
sh                         apsh4a3a_defconfig
powerpc                      cm5200_defconfig
powerpc                           allnoconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
alpha                            alldefconfig
powerpc                       ebony_defconfig
mips                            ar7_defconfig
mips                         tb0226_defconfig
arm                        oxnas_v6_defconfig
arm                            zeus_defconfig
sh                             sh03_defconfig
arc                     nsimosci_hs_defconfig
arm                            pleb_defconfig
powerpc                        fsp2_defconfig
arm                       multi_v4t_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
um                             i386_defconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 02:39:20 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:20 +0800
Subject: [soc:amlogic/dt-2] BUILD SUCCESS
 c6cf488e3bfdf92427686317d99e0342516753de
Message-ID: <611b83c8.ZiYN3U7havdVNOSs%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git amlogic/dt-2
branch HEAD: c6cf488e3bfdf92427686317d99e0342516753de  arm64: dts: meson: add audio playback to vega-s95 dtsi

elapsed time: 10177m

configs tested: 185
configs skipped: 143

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
powerpc                     pq2fads_defconfig
arc                         haps_hs_defconfig
arc                    vdk_hs38_smp_defconfig
arm                         vf610m4_defconfig
m68k                          multi_defconfig
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lpc18xx_defconfig
arm                         lubbock_defconfig
mips                        workpad_defconfig
powerpc                    mvme5100_defconfig
powerpc                     rainier_defconfig
mips                        nlm_xlr_defconfig
sh                             shx3_defconfig
sh                          rsk7264_defconfig
ia64                        generic_defconfig
sh                        sh7785lcr_defconfig
xtensa                  nommu_kc705_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                       omap2plus_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
parisc                           alldefconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
nds32                            alldefconfig
sh                                  defconfig
mips                         bigsur_defconfig
ia64                          tiger_defconfig
powerpc                      bamboo_defconfig
mips                        bcm47xx_defconfig
sh                           se7721_defconfig
mips                   sb1250_swarm_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                  decstation_64_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
sh                           se7705_defconfig
arm                            xcep_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
sh                          sdk7786_defconfig
arm                            pleb_defconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
powerpc                     ppa8548_defconfig
arm                         nhk8815_defconfig
s390                       zfcpdump_defconfig
arc                        vdk_hs38_defconfig
powerpc                 mpc8540_ads_defconfig
arm                         palmz72_defconfig
m68k                        m5272c3_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                     decstation_defconfig
um                             i386_defconfig
arm                      jornada720_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a004-20210810
x86_64               randconfig-a006-20210810
x86_64               randconfig-a003-20210810
x86_64               randconfig-a005-20210810
x86_64               randconfig-a002-20210810
x86_64               randconfig-a001-20210810
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210809
i386                 randconfig-a005-20210809
i386                 randconfig-a006-20210809
i386                 randconfig-a002-20210809
i386                 randconfig-a001-20210809
i386                 randconfig-a003-20210809
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
i386                 randconfig-a004-20210808
i386                 randconfig-a005-20210808
i386                 randconfig-a006-20210808
i386                 randconfig-a002-20210808
i386                 randconfig-a001-20210808
i386                 randconfig-a003-20210808
i386                 randconfig-a011-20210810
i386                 randconfig-a015-20210810
i386                 randconfig-a013-20210810
i386                 randconfig-a014-20210810
i386                 randconfig-a016-20210810
i386                 randconfig-a012-20210810
riscv                    nommu_k210_defconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                            allyesconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210810
x86_64               randconfig-a013-20210810
x86_64               randconfig-a011-20210810
x86_64               randconfig-a012-20210810
x86_64               randconfig-a016-20210810
x86_64               randconfig-a014-20210810
x86_64               randconfig-a015-20210810
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
x86_64               randconfig-a016-20210809
x86_64               randconfig-a012-20210809
x86_64               randconfig-a013-20210809
x86_64               randconfig-a011-20210809
x86_64               randconfig-a014-20210809
x86_64               randconfig-a015-20210809
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 02:39:52 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:52 +0800
Subject: [soc:imx/dt64] BUILD SUCCESS 418962eea35869b8e07766d8728ae660d75800a9
Message-ID: <611b83e8.86FcSSS+jmsPyQNL%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git imx/dt64
branch HEAD: 418962eea35869b8e07766d8728ae660d75800a9  arm64: dts: add device tree for Traverse Ten64 (LS1088A)

elapsed time: 4528m

configs tested: 207
configs skipped: 143

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210814
i386                 randconfig-c001-20210816
mips                            ar7_defconfig
arm64                            alldefconfig
arm                            pleb_defconfig
powerpc                       ppc64_defconfig
sh                   sh7770_generic_defconfig
openrisc                  or1klitex_defconfig
m68k                        m5407c3_defconfig
powerpc                    klondike_defconfig
mips                     loongson1c_defconfig
arm                          ep93xx_defconfig
arm                          iop32x_defconfig
h8300                       h8s-sim_defconfig
riscv                    nommu_k210_defconfig
arm                        clps711x_defconfig
mips                malta_qemu_32r6_defconfig
powerpc                 mpc834x_mds_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
m68k                          hp300_defconfig
arm                         at91_dt_defconfig
powerpc                      mgcoge_defconfig
m68k                          sun3x_defconfig
arm                      jornada720_defconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lpc18xx_defconfig
arm                         lubbock_defconfig
powerpc                     tqm5200_defconfig
powerpc                      walnut_defconfig
mips                      bmips_stb_defconfig
sh                           se7619_defconfig
arm                         orion5x_defconfig
mips                        workpad_defconfig
powerpc                    mvme5100_defconfig
powerpc                     rainier_defconfig
mips                        nlm_xlr_defconfig
sh                             shx3_defconfig
sh                          rsk7269_defconfig
ia64                          tiger_defconfig
arm                             rpc_defconfig
powerpc                      ppc40x_defconfig
arm                          simpad_defconfig
powerpc                       maple_defconfig
mips                           rs90_defconfig
powerpc                         wii_defconfig
powerpc                     ksi8560_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                       omap2plus_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
h8300                            allyesconfig
arm                     davinci_all_defconfig
sh                           se7206_defconfig
sh                                  defconfig
arm                           corgi_defconfig
xtensa                  audio_kc705_defconfig
parisc                           alldefconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
riscv                    nommu_virt_defconfig
powerpc                        cell_defconfig
sh                        sh7785lcr_defconfig
mips                     cu1830-neo_defconfig
powerpc                     asp8347_defconfig
powerpc                 canyonlands_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                  decstation_64_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
sh                           se7705_defconfig
arc                    vdk_hs38_smp_defconfig
arm                            xcep_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
powerpc                     ppa8548_defconfig
arm                         nhk8815_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                     decstation_defconfig
um                             i386_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
x86_64               randconfig-a004-20210814
x86_64               randconfig-a006-20210814
x86_64               randconfig-a003-20210814
x86_64               randconfig-a001-20210814
x86_64               randconfig-a005-20210814
x86_64               randconfig-a002-20210814
i386                 randconfig-a004-20210814
i386                 randconfig-a002-20210814
i386                 randconfig-a001-20210814
i386                 randconfig-a003-20210814
i386                 randconfig-a006-20210814
i386                 randconfig-a005-20210814
i386                 randconfig-a004-20210815
i386                 randconfig-a001-20210815
i386                 randconfig-a002-20210815
i386                 randconfig-a003-20210815
i386                 randconfig-a006-20210815
i386                 randconfig-a005-20210815
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
x86_64               randconfig-a013-20210815
x86_64               randconfig-a011-20210815
x86_64               randconfig-a016-20210815
x86_64               randconfig-a012-20210815
x86_64               randconfig-a014-20210815
x86_64               randconfig-a015-20210815
i386                 randconfig-a011-20210814
i386                 randconfig-a015-20210814
i386                 randconfig-a013-20210814
i386                 randconfig-a014-20210814
i386                 randconfig-a016-20210814
i386                 randconfig-a012-20210814
riscv                            allyesconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210814
x86_64               randconfig-a013-20210814
x86_64               randconfig-a011-20210814
x86_64               randconfig-a016-20210814
x86_64               randconfig-a012-20210814
x86_64               randconfig-a014-20210814
x86_64               randconfig-a015-20210814
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 02:39:47 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:47 +0800
Subject: [soc:imx/dt] BUILD SUCCESS
 0fdedc09af18d231aa581331821c9ab6ef0903f1
Message-ID: <611b83e3.heluZssTfN2xusdD%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git imx/dt
branch HEAD: 0fdedc09af18d231aa581331821c9ab6ef0903f1  dt-bindings: arm: fsl: Add Traverse Ten64 (LS1088A) board

elapsed time: 4528m

configs tested: 241
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210814
i386                 randconfig-c001-20210816
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
mips                            ar7_defconfig
arm64                            alldefconfig
arm                            pleb_defconfig
powerpc                       ppc64_defconfig
sh                   sh7770_generic_defconfig
openrisc                  or1klitex_defconfig
m68k                        m5407c3_defconfig
powerpc                    klondike_defconfig
mips                     loongson1c_defconfig
arm                          ep93xx_defconfig
arm                          iop32x_defconfig
h8300                       h8s-sim_defconfig
riscv                    nommu_k210_defconfig
arm                        clps711x_defconfig
mips                malta_qemu_32r6_defconfig
powerpc                 mpc834x_mds_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                            zeus_defconfig
nios2                            alldefconfig
xtensa                    xip_kc705_defconfig
powerpc                 mpc837x_mds_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
powerpc                     pq2fads_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lpc18xx_defconfig
arm                         lubbock_defconfig
powerpc                     tqm5200_defconfig
powerpc                      walnut_defconfig
mips                      bmips_stb_defconfig
sh                           se7619_defconfig
arm                         orion5x_defconfig
sh                          rsk7269_defconfig
ia64                          tiger_defconfig
arm                             rpc_defconfig
powerpc                      ppc40x_defconfig
arm                          simpad_defconfig
sh                           se7750_defconfig
powerpc                    socrates_defconfig
riscv                             allnoconfig
powerpc                     ksi8560_defconfig
powerpc                       maple_defconfig
powerpc                         wii_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
h8300                            allyesconfig
sh                           se7206_defconfig
sh                                  defconfig
arm                           corgi_defconfig
xtensa                  audio_kc705_defconfig
arm                       aspeed_g4_defconfig
sh                  sh7785lcr_32bit_defconfig
mips                       lemote2f_defconfig
parisc                           alldefconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
riscv                    nommu_virt_defconfig
powerpc                        cell_defconfig
sh                        sh7785lcr_defconfig
sh                 kfr2r09-romimage_defconfig
sh                        edosk7760_defconfig
parisc                generic-64bit_defconfig
arm                           h5000_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
mips                     cu1830-neo_defconfig
powerpc                     asp8347_defconfig
powerpc                 canyonlands_defconfig
powerpc                     powernv_defconfig
arm                        magician_defconfig
powerpc                       eiger_defconfig
ia64                         bigsur_defconfig
powerpc64                        alldefconfig
arm                      jornada720_defconfig
sh                           se7705_defconfig
arc                    vdk_hs38_smp_defconfig
arm                            xcep_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
powerpc                  iss476-smp_defconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
powerpc                     ppa8548_defconfig
arm                         nhk8815_defconfig
mips                     decstation_defconfig
arm                            lart_defconfig
mips                          rm200_defconfig
mips                        nlm_xlr_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
um                             i386_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
x86_64               randconfig-a004-20210814
x86_64               randconfig-a006-20210814
x86_64               randconfig-a003-20210814
x86_64               randconfig-a001-20210814
x86_64               randconfig-a005-20210814
x86_64               randconfig-a002-20210814
i386                 randconfig-a004-20210814
i386                 randconfig-a002-20210814
i386                 randconfig-a001-20210814
i386                 randconfig-a003-20210814
i386                 randconfig-a006-20210814
i386                 randconfig-a005-20210814
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
i386                 randconfig-a004-20210815
i386                 randconfig-a001-20210815
i386                 randconfig-a002-20210815
i386                 randconfig-a003-20210815
i386                 randconfig-a006-20210815
i386                 randconfig-a005-20210815
x86_64               randconfig-a013-20210815
x86_64               randconfig-a011-20210815
x86_64               randconfig-a016-20210815
x86_64               randconfig-a012-20210815
x86_64               randconfig-a014-20210815
x86_64               randconfig-a015-20210815
i386                 randconfig-a011-20210814
i386                 randconfig-a015-20210814
i386                 randconfig-a013-20210814
i386                 randconfig-a014-20210814
i386                 randconfig-a016-20210814
i386                 randconfig-a012-20210814
i386                 randconfig-a011-20210815
i386                 randconfig-a015-20210815
i386                 randconfig-a014-20210815
i386                 randconfig-a013-20210815
i386                 randconfig-a016-20210815
i386                 randconfig-a012-20210815
riscv                            allyesconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210814
x86_64               randconfig-a013-20210814
x86_64               randconfig-a011-20210814
x86_64               randconfig-a016-20210814
x86_64               randconfig-a012-20210814
x86_64               randconfig-a014-20210814
x86_64               randconfig-a015-20210814
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816
x86_64               randconfig-a004-20210815
x86_64               randconfig-a006-20210815
x86_64               randconfig-a003-20210815
x86_64               randconfig-a001-20210815
x86_64               randconfig-a002-20210815
x86_64               randconfig-a005-20210815

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 02:39:50 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:50 +0800
Subject: [soc:imx/defconfig] BUILD SUCCESS
 7fd19c58e48fb774de9190f27f2b06a6526f2d3c
Message-ID: <611b83e6.UWfhDSFHZC901rfb%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git imx/defconfig
branch HEAD: 7fd19c58e48fb774de9190f27f2b06a6526f2d3c  ARM: imx_v6_v7_defconfig: enable driver of the LTC3676 PMIC

elapsed time: 4528m

configs tested: 210
configs skipped: 110

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210814
i386                 randconfig-c001-20210816
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
mips                            ar7_defconfig
arm64                            alldefconfig
arm                            pleb_defconfig
powerpc                       ppc64_defconfig
sh                   sh7770_generic_defconfig
openrisc                  or1klitex_defconfig
m68k                        m5407c3_defconfig
powerpc                    klondike_defconfig
mips                     loongson1c_defconfig
arm                          ep93xx_defconfig
arm                          iop32x_defconfig
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                            zeus_defconfig
arm                        clps711x_defconfig
nios2                            alldefconfig
xtensa                    xip_kc705_defconfig
powerpc                 mpc837x_mds_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
powerpc                     pq2fads_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lpc18xx_defconfig
arm                         lubbock_defconfig
powerpc                     tqm5200_defconfig
powerpc                      walnut_defconfig
mips                      bmips_stb_defconfig
sh                           se7619_defconfig
arm                         orion5x_defconfig
sh                          rsk7269_defconfig
ia64                          tiger_defconfig
arm                             rpc_defconfig
powerpc                      ppc40x_defconfig
arm                          simpad_defconfig
powerpc                       maple_defconfig
powerpc                         wii_defconfig
powerpc                     ksi8560_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
h8300                            allyesconfig
sh                           se7206_defconfig
sh                                  defconfig
arm                           corgi_defconfig
xtensa                  audio_kc705_defconfig
h8300                       h8s-sim_defconfig
arm                       aspeed_g4_defconfig
sh                  sh7785lcr_32bit_defconfig
mips                       lemote2f_defconfig
parisc                           alldefconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
sh                 kfr2r09-romimage_defconfig
sh                        edosk7760_defconfig
parisc                generic-64bit_defconfig
arm                           h5000_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
mips                     cu1830-neo_defconfig
powerpc                     asp8347_defconfig
powerpc                 canyonlands_defconfig
powerpc                     powernv_defconfig
arm                        magician_defconfig
powerpc                       eiger_defconfig
ia64                         bigsur_defconfig
powerpc64                        alldefconfig
arm                      jornada720_defconfig
sh                           se7705_defconfig
arc                    vdk_hs38_smp_defconfig
arm                            xcep_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
powerpc                  iss476-smp_defconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
powerpc                     ppa8548_defconfig
arm                         nhk8815_defconfig
mips                     decstation_defconfig
arm                            lart_defconfig
mips                          rm200_defconfig
mips                        nlm_xlr_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
um                             i386_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
x86_64               randconfig-a004-20210814
x86_64               randconfig-a006-20210814
x86_64               randconfig-a003-20210814
x86_64               randconfig-a001-20210814
x86_64               randconfig-a005-20210814
x86_64               randconfig-a002-20210814
i386                 randconfig-a004-20210814
i386                 randconfig-a002-20210814
i386                 randconfig-a001-20210814
i386                 randconfig-a003-20210814
i386                 randconfig-a006-20210814
i386                 randconfig-a005-20210814
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
i386                 randconfig-a011-20210814
i386                 randconfig-a015-20210814
i386                 randconfig-a013-20210814
i386                 randconfig-a014-20210814
i386                 randconfig-a016-20210814
i386                 randconfig-a012-20210814
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210814
x86_64               randconfig-a013-20210814
x86_64               randconfig-a011-20210814
x86_64               randconfig-a016-20210814
x86_64               randconfig-a012-20210814
x86_64               randconfig-a014-20210814
x86_64               randconfig-a015-20210814
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 02:39:40 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 17:39:40 +0800
Subject: [soc:tegra/dt64] BUILD SUCCESS
 f865d0292ff3c0ca09414436510eb4c815815509
Message-ID: <611b83dc./CBE7GVrZQkw/vH5%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tegra/dt64
branch HEAD: f865d0292ff3c0ca09414436510eb4c815815509  arm64: tegra: Fix compatible string for Tegra132 CPUs

elapsed time: 5340m

configs tested: 215
configs skipped: 168

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210813
i386                 randconfig-c001-20210816
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                        clps711x_defconfig
nios2                            alldefconfig
xtensa                    xip_kc705_defconfig
powerpc                 mpc837x_mds_defconfig
mips                  maltasmvp_eva_defconfig
mips                         bigsur_defconfig
powerpc64                           defconfig
powerpc                        cell_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
powerpc                     pq2fads_defconfig
h8300                            alldefconfig
powerpc                         ps3_defconfig
powerpc                  mpc866_ads_defconfig
arm                         lpc18xx_defconfig
arm                         lubbock_defconfig
arm                       imx_v4_v5_defconfig
powerpc                     rainier_defconfig
sh                            shmin_defconfig
h8300                               defconfig
powerpc                    mvme5100_defconfig
mips                        nlm_xlr_defconfig
sh                             shx3_defconfig
sh                          rsk7269_defconfig
ia64                          tiger_defconfig
arm                             rpc_defconfig
powerpc                      ppc40x_defconfig
sh                           se7750_defconfig
powerpc                    socrates_defconfig
riscv                             allnoconfig
powerpc                     ksi8560_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                       maple_defconfig
mips                           rs90_defconfig
powerpc                         wii_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
parisc                           alldefconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
powerpc                    amigaone_defconfig
mips                  decstation_64_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
arm                          pxa3xx_defconfig
arm                          iop32x_defconfig
mips                         cobalt_defconfig
openrisc                    or1ksim_defconfig
mips                        nlm_xlp_defconfig
sh                           se7705_defconfig
arc                    vdk_hs38_smp_defconfig
arm                            xcep_defconfig
xtensa                       common_defconfig
powerpc                      pmac32_defconfig
arc                     haps_hs_smp_defconfig
m68k                        m5407c3_defconfig
m68k                       m5249evb_defconfig
mips                     loongson1c_defconfig
m68k                             allmodconfig
powerpc                 mpc834x_mds_defconfig
sh                          kfr2r09_defconfig
powerpc                     ep8248e_defconfig
arm                       spear13xx_defconfig
powerpc                 mpc8560_ads_defconfig
riscv                               defconfig
powerpc                     ppa8548_defconfig
arm                         nhk8815_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                     decstation_defconfig
um                             i386_defconfig
arm                      jornada720_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
csky                                defconfig
alpha                               defconfig
nios2                            allyesconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210814
i386                 randconfig-a001-20210814
i386                 randconfig-a006-20210814
i386                 randconfig-a005-20210814
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
i386                 randconfig-a002-20210814
i386                 randconfig-a003-20210814
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a011-20210813
x86_64               randconfig-a013-20210813
x86_64               randconfig-a012-20210813
x86_64               randconfig-a016-20210813
x86_64               randconfig-a015-20210813
x86_64               randconfig-a014-20210813
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
i386                 randconfig-a011-20210814
i386                 randconfig-a015-20210814
i386                 randconfig-a013-20210814
i386                 randconfig-a014-20210814
i386                 randconfig-a016-20210814
i386                 randconfig-a012-20210814
riscv                    nommu_k210_defconfig
riscv                    nommu_virt_defconfig
riscv                          rv32_defconfig
riscv                            allyesconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210814
x86_64               randconfig-c001-20210813
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a013-20210814
x86_64               randconfig-a011-20210814
x86_64               randconfig-a016-20210814
x86_64               randconfig-a012-20210814
x86_64               randconfig-a014-20210814
x86_64               randconfig-a015-20210814
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From raphael.gallais-pou at foss.st.com  Tue Aug 17 02:43:13 2021
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Tue, 17 Aug 2021 11:43:13 +0200
Subject: [PATCH] drm/stm: ltdc: improve pm_runtime to stop clocks
In-Reply-To: <5d65ca80-4f94-49e1-5de1-cf29e8231a6a@denx.de>
References: <20210629115709.16145-1-raphael.gallais-pou@foss.st.com>
 <420e243d-7541-a07e-177b-d2db11c26aef@denx.de>
 <3bb823e4-4724-7072-fe9f-7b8a355c8e50@foss.st.com>
 <5d65ca80-4f94-49e1-5de1-cf29e8231a6a@denx.de>
Message-ID: <629b6666-74b3-91f0-5c6c-e26d55ea62d8@foss.st.com>


On 7/2/21 8:07 PM, Marek Vasut wrote:
> On 7/2/21 11:23 AM, Raphael Gallais-Pou wrote:
>> Hello Marek,
>
> Hi,
>
>> Sorry for the late answer.
>
> No worries, take your time
>
>> On 6/30/21 2:35 AM, Marek Vasut wrote:
>>> On 6/29/21 1:58 PM, Raphael GALLAIS-POU - foss wrote:
>>>
>>> [...]
>>>
>>>> +++ b/drivers/gpu/drm/stm/ltdc.c
>>>> @@ -425,10 +425,17 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
>>>> ? {
>>>> ????? struct ltdc_device *ldev = crtc_to_ltdc(crtc);
>>>> ????? struct drm_device *ddev = crtc->dev;
>>>> +??? int ret;
>>>> ? ????? DRM_DEBUG_DRIVER("\n");
>>>> ? -??? pm_runtime_get_sync(ddev->dev);
>>>> +??? if (!pm_runtime_active(ddev->dev)) {
>>>> +??????? ret = pm_runtime_get_sync(ddev->dev);
>>>
>>> All these if (!pm_runtime_active()) then pm_runtime_get_sync() calls look like workaround for some larger issue. Shouldn't the pm_runtime do some refcounting on its own , so this shouldn't be needed ?
>>
>>
>> This problem purely comes from the driver internals, so I don't think it is a workaround.
>>
>> Because of the "ltdc_crtc_mode_set_nofb" function which does not have any "symmetrical" call, such as enable/disable functions, there was two calls to pm_runtime_get_sync against one call to pm_runtime_put_sync.
>>
>> This instability resulted in the LTDC clocks being always enabled, even when the peripheral was disabled. This could be seen in the clk_summary as explained in the patch summary among other things.
>>
>> By doing so, we first check if the clocks are not already activated, and in that case we call pm_runtime_get_sync.
>
> I just have to wonder, how come other drivers don't need these if (!pm_runtime_active()) pm_runtime_get_sync() conditions. I think they just get/put the runtime PM within a call itself, not across function calls. Maybe that could be the right fix here too ?


Hello Marek,


I've run a deeper analysis over this implementation.

If I may take rockchip's "rockchip_drm_vop.c" driver, there is an boolean "is_enabled" set to true when crtc_atomic_enable is called.

The above implementation could save us from adding such field in the ltdc_dev structure.

Another solution could be in order to simply call pm_runtime_get_sync() in ltdc_crtc_mode_set_nofb() and by removing this condition in ltdc_atomic_crtc_disable() the driver behaves just like the first version of this patch.

In this way, it avoids such conditions and seems more to get along with the current implementation.


Regards,

Rapha?l



From hsin-hsiung.wang at mediatek.com  Tue Aug 17 02:47:06 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 17 Aug 2021 17:47:06 +0800
Subject: [PATCH v11 1/5] dt-bindings: spmi: modify the constraint 'maxItems'
 to 'minItems'
In-Reply-To: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1629193630-19994-2-git-send-email-hsin-hsiung.wang@mediatek.com>

The constraint of 'maxItem: 1' might be larger than 1, so we modify it
to 'minItem: 1'.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
changes since v10:
- No change.
---
 Documentation/devicetree/bindings/spmi/spmi.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/spmi/spmi.yaml b/Documentation/devicetree/bindings/spmi/spmi.yaml
index 1d243faef2f8..5938d807674f 100644
--- a/Documentation/devicetree/bindings/spmi/spmi.yaml
+++ b/Documentation/devicetree/bindings/spmi/spmi.yaml
@@ -25,7 +25,7 @@ properties:
     pattern: "^spmi at .*"
 
   reg:
-    maxItems: 1
+    minItems: 1
 
   "#address-cells":
     const: 2
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Tue Aug 17 02:47:07 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 17 Aug 2021 17:47:07 +0800
Subject: [PATCH v11 2/5] dt-bindings: spmi: document binding for the Mediatek
 SPMI controller
In-Reply-To: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1629193630-19994-3-git-send-email-hsin-hsiung.wang@mediatek.com>

This adds documentation for the SPMI controller found on Mediatek SoCs.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
changes since v10:
- No change.
---
 .../bindings/spmi/mtk,spmi-mtk-pmif.yaml      | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml

diff --git a/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml b/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml
new file mode 100644
index 000000000000..a221cc1ac6c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spmi/mtk,spmi-mtk-pmif.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek SPMI Controller Device Tree Bindings
+
+maintainers:
+  - Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
+
+description: |+
+  On MediaTek SoCs the PMIC is connected via SPMI and the controller allows
+  for multiple SoCs to control a single SPMI master.
+
+allOf:
+  - $ref: "spmi.yaml"
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt6873-spmi
+      - mediatek,mt8195-spmi
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pmif
+      - const: spmimst
+
+  clocks:
+    minItems: 3
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: pmif_sys_ck
+      - const: pmif_tmr_ck
+      - const: spmimst_clk_mux
+
+  assigned-clocks:
+    maxItems: 1
+
+  assigned-clock-parents:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8192-clk.h>
+
+    spmi: spmi at 10027000 {
+        compatible = "mediatek,mt6873-spmi";
+        reg = <0 0x10027000 0 0x000e00>,
+              <0 0x10029000 0 0x000100>;
+        reg-names = "pmif", "spmimst";
+        clocks = <&infracfg CLK_INFRA_PMIC_AP>,
+                 <&infracfg CLK_INFRA_PMIC_TMR>,
+                 <&topckgen CLK_TOP_SPMI_MST_SEL>;
+        clock-names = "pmif_sys_ck",
+                      "pmif_tmr_ck",
+                      "spmimst_clk_mux";
+        assigned-clocks = <&topckgen CLK_TOP_PWRAP_ULPOSC_SEL>;
+        assigned-clock-parents = <&topckgen CLK_TOP_OSC_D10>;
+    };
+...
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Tue Aug 17 02:47:10 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 17 Aug 2021 17:47:10 +0800
Subject: [PATCH v11 5/5] arm64: dts: mt8192: add spmi node
In-Reply-To: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1629193630-19994-6-git-send-email-hsin-hsiung.wang@mediatek.com>

Add spmi node to SOC MT8192.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
---
changes since v10:
- No change.
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 9810f1d441da..1237e3624e44 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -316,6 +316,23 @@
 			clock-names = "clk13m";
 		};
 
+		spmi: spmi at 10027000 {
+			compatible = "mediatek,mt6873-spmi";
+			reg = <0 0x10027000 0 0x000e00>,
+			      <0 0x10029000 0 0x000100>;
+			reg-names = "pmif", "spmimst";
+			clocks = <&infracfg CLK_INFRA_PMIC_AP>,
+				 <&infracfg CLK_INFRA_PMIC_TMR>,
+				 <&topckgen CLK_TOP_SPMI_MST_SEL>;
+			clock-names = "pmif_sys_ck",
+				      "pmif_tmr_ck",
+				      "spmimst_clk_mux";
+			assigned-clocks = <&topckgen CLK_TOP_PWRAP_ULPOSC_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_OSC_D10>;
+			#address-cells = <2>;
+			#size-cells = <0>;
+		};
+
 		scp_adsp: clock-controller at 10720000 {
 			compatible = "mediatek,mt8192-scp_adsp";
 			reg = <0 0x10720000 0 0x1000>;
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Tue Aug 17 02:47:09 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 17 Aug 2021 17:47:09 +0800
Subject: [PATCH v11 4/5] spmi: mediatek: Add support for MT8195
In-Reply-To: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1629193630-19994-5-git-send-email-hsin-hsiung.wang@mediatek.com>

From: Henry Chen <henryc.chen at mediatek.com>

Add spmi support for MT8195.

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
---
changes since v10:
- add sign-off.
- correct mt8195 driver.
---
 drivers/spmi/spmi-mtk-pmif.c | 88 ++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
index 35d338a19d76..5b9665031a6e 100644
--- a/drivers/spmi/spmi-mtk-pmif.c
+++ b/drivers/spmi/spmi-mtk-pmif.c
@@ -152,6 +152,54 @@ static const u32 mt6873_regs[] = {
 	[PMIF_SWINF_3_STA] =	0x0CE8,
 };
 
+static const u32 mt8195_regs[] = {
+	[PMIF_INIT_DONE] =			0x0000,
+	[PMIF_INF_EN] =				0x0024,
+	[PMIF_ARB_EN] =				0x0150,
+	[PMIF_CMDISSUE_EN] =			0x03B8,
+	[PMIF_TIMER_CTRL] =			0x03E4,
+	[PMIF_SPI_MODE_CTRL] =			0x0408,
+	[PMIF_IRQ_EVENT_EN_0] =			0x0420,
+	[PMIF_IRQ_FLAG_0] =			0x0428,
+	[PMIF_IRQ_CLR_0] =			0x042C,
+	[PMIF_IRQ_EVENT_EN_1] =			0x0430,
+	[PMIF_IRQ_FLAG_1] =			0x0438,
+	[PMIF_IRQ_CLR_1] =			0x043C,
+	[PMIF_IRQ_EVENT_EN_2] =			0x0440,
+	[PMIF_IRQ_FLAG_2] =			0x0448,
+	[PMIF_IRQ_CLR_2] =			0x044C,
+	[PMIF_IRQ_EVENT_EN_3] =			0x0450,
+	[PMIF_IRQ_FLAG_3] =			0x0458,
+	[PMIF_IRQ_CLR_3] =			0x045C,
+	[PMIF_IRQ_EVENT_EN_4] =			0x0460,
+	[PMIF_IRQ_FLAG_4] =			0x0468,
+	[PMIF_IRQ_CLR_4] =			0x046C,
+	[PMIF_WDT_EVENT_EN_0] =			0x0474,
+	[PMIF_WDT_FLAG_0] =			0x0478,
+	[PMIF_WDT_EVENT_EN_1] =			0x047C,
+	[PMIF_WDT_FLAG_1] =			0x0480,
+	[PMIF_SWINF_0_ACC] =			0x0800,
+	[PMIF_SWINF_0_WDATA_31_0] =		0x0804,
+	[PMIF_SWINF_0_RDATA_31_0] =		0x0814,
+	[PMIF_SWINF_0_VLD_CLR] =		0x0824,
+	[PMIF_SWINF_0_STA] =			0x0828,
+	[PMIF_SWINF_1_ACC] =			0x0840,
+	[PMIF_SWINF_1_WDATA_31_0] =		0x0844,
+	[PMIF_SWINF_1_RDATA_31_0] =		0x0854,
+	[PMIF_SWINF_1_VLD_CLR] =		0x0864,
+	[PMIF_SWINF_1_STA] =			0x0868,
+	[PMIF_SWINF_2_ACC] =			0x0880,
+	[PMIF_SWINF_2_WDATA_31_0] =		0x0884,
+	[PMIF_SWINF_2_RDATA_31_0] =		0x0894,
+	[PMIF_SWINF_2_VLD_CLR] =		0x08A4,
+	[PMIF_SWINF_2_STA] =			0x08A8,
+	[PMIF_SWINF_3_ACC] =			0x08C0,
+	[PMIF_SWINF_3_WDATA_31_0] =		0x08C4,
+	[PMIF_SWINF_3_RDATA_31_0] =		0x08D4,
+	[PMIF_SWINF_3_VLD_CLR] =		0x08E4,
+	[PMIF_SWINF_3_STA] =			0x08E8,
+};
+
 enum spmi_regs {
 	SPMI_OP_ST_CTRL,
 	SPMI_GRP_ID_EN,
@@ -165,6 +213,15 @@ enum spmi_regs {
 	SPMI_REC3,
 	SPMI_REC4,
 	SPMI_MST_DBG,
+
+	/* MT8195 spmi regs */
+	SPMI_MST_RCS_CTRL,
+	SPMI_SLV_3_0_EINT,
+	SPMI_SLV_7_4_EINT,
+	SPMI_SLV_B_8_EINT,
+	SPMI_SLV_F_C_EINT,
+	SPMI_REC_CMD_DEC,
+	SPMI_DEC_DBG,
 };
 
 static const u32 mt6873_spmi_regs[] = {
@@ -182,6 +239,28 @@ static const u32 mt6873_spmi_regs[] = {
 	[SPMI_MST_DBG] =	0x00fc,
 };
 
+static const u32 mt8195_spmi_regs[] = {
+	[SPMI_OP_ST_CTRL] =	0x0000,
+	[SPMI_GRP_ID_EN] =	0x0004,
+	[SPMI_OP_ST_STA] =	0x0008,
+	[SPMI_MST_SAMPL] =	0x000C,
+	[SPMI_MST_REQ_EN] =	0x0010,
+	[SPMI_MST_RCS_CTRL] =	0x0014,
+	[SPMI_SLV_3_0_EINT] =	0x0020,
+	[SPMI_SLV_7_4_EINT] =	0x0024,
+	[SPMI_SLV_B_8_EINT] =	0x0028,
+	[SPMI_SLV_F_C_EINT] =	0x002C,
+	[SPMI_REC_CTRL] =	0x0040,
+	[SPMI_REC0] =		0x0044,
+	[SPMI_REC1] =		0x0048,
+	[SPMI_REC2] =		0x004C,
+	[SPMI_REC3] =		0x0050,
+	[SPMI_REC4] =		0x0054,
+	[SPMI_REC_CMD_DEC] =	0x005C,
+	[SPMI_DEC_DBG] =	0x00F8,
+	[SPMI_MST_DBG] =	0x00FC,
+};
+
 static u32 pmif_readl(struct pmif *arb, enum pmif_regs reg)
 {
 	return readl(arb->base + arb->data->regs[reg]);
@@ -350,6 +429,12 @@ static const struct pmif_data mt6873_pmif_arb = {
 	.soc_chan = 2,
 };
 
+static const struct pmif_data mt8195_pmif_arb = {
+	.regs = mt8195_regs,
+	.spmimst_regs = mt8195_spmi_regs,
+	.soc_chan = 2,
+};
+
 static int mtk_spmi_probe(struct platform_device *pdev)
 {
 	struct pmif *arb;
@@ -438,6 +523,9 @@ static const struct of_device_id mtk_spmi_match_table[] = {
 	{
 		.compatible = "mediatek,mt6873-spmi",
 		.data = &mt6873_pmif_arb,
+	}, {
+		.compatible = "mediatek,mt8195-spmi",
+		.data = &mt8195_pmif_arb,
 	}, {
 		/* sentinel */
 	},
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Tue Aug 17 02:47:05 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 17 Aug 2021 17:47:05 +0800
Subject: [PATCH v11 0/5] Add SPMI support for Mediatek SoC IC
Message-ID: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>

This series adds support for new SoC MT6873/MT8192/MT8195 to the spmi driver.
This series is based on Chun-Jie's patches[1][2].

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127
[2] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521655

changes since v10:
- rebase to v5.14-rc6.
- remove the unnecessary check for clk and drop debug log.
- update correct mt8195 spmi driver.

Henry Chen (1):
  spmi: mediatek: Add support for MT8195

Hsin-Hsiung Wang (4):
  dt-bindings: spmi: modify the constraint 'maxItems' to 'minItems'
  dt-bindings: spmi: document binding for the Mediatek SPMI controller
  spmi: mediatek: Add support for MT6873/8192
  arm64: dts: mt8192: add spmi node

 .../bindings/spmi/mtk,spmi-mtk-pmif.yaml      |  76 +++
 .../devicetree/bindings/spmi/spmi.yaml        |   2 +-
 arch/arm64/boot/dts/mediatek/mt8192.dtsi      |  17 +
 drivers/spmi/Kconfig                          |  10 +
 drivers/spmi/Makefile                         |   2 +
 drivers/spmi/spmi-mtk-pmif.c                  | 547 ++++++++++++++++++
 6 files changed, 653 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml
 create mode 100644 drivers/spmi/spmi-mtk-pmif.c


base-commit: 794c7931a2428a656551f2179e6a093233a6e0aa
prerequisite-patch-id: 8e70d378642e084a14296dbaa2aa4e07c1d30563
prerequisite-patch-id: 82ced16215cdd31201c6146ddb5c30bc17525996
prerequisite-patch-id: 7f2137e77cfc439c2e4b4e4369a6d6b48fec1ece
prerequisite-patch-id: 15f52bb664f0f0436627d056a53afefb0b99f67a
prerequisite-patch-id: 479b44dfdc6d7b367c0d441d8635d2dc02466057
prerequisite-patch-id: 5df1858972e343d3750cdda1063655fc232eb831
prerequisite-patch-id: 7e63a29430f65c2a0d56d7353df884645d70ed8c
prerequisite-patch-id: 2a6200e8a05329d51aaa4fd63aacfbba66d16177
prerequisite-patch-id: 604d2702c4217b77de3dc305ff08f630ba38fdb4
prerequisite-patch-id: d3ece2688dbd45eee248a8c6ba3206c0c673c904
prerequisite-patch-id: 1bebe1cd9b267c974cae50c3df8c0f8f4f0b0b3d
prerequisite-patch-id: 3b34fe85667da5287bde9fd2378359be4a126266
prerequisite-patch-id: 5d3d139212ab304739b75f7638251703b95948d5
prerequisite-patch-id: 621291b21be177a63eaf6769aa6d2ee8ddb2ea2b
prerequisite-patch-id: 024f786586b409420782d24218b15f05f6476667
prerequisite-patch-id: 946aae93303bde26226289dc389c94de96a9dacd
prerequisite-patch-id: b3ddf6f2079c3c269bd24091243030a971c43cbc
prerequisite-patch-id: 5c0e0308aa8eb06ca6df6f5467bc925f2cc106ad
prerequisite-patch-id: d4e481acd8b970f08d3e4da9c8fc0ad6e1fff551
prerequisite-patch-id: 99db7309fbe1b9f73a07e25d5174db8976c77a2c
prerequisite-patch-id: cffbc99e9e60f6db43cf7879f17e05c5b041d312
prerequisite-patch-id: 69871b871ab339881b50a2d6988173050b6c7a4f
prerequisite-patch-id: 4f5900b98a0c7cbe62694f2477a6cb410187714b
-- 
2.18.0

From hsin-hsiung.wang at mediatek.com  Tue Aug 17 02:47:08 2021
From: hsin-hsiung.wang at mediatek.com (Hsin-Hsiung Wang)
Date: Tue, 17 Aug 2021 17:47:08 +0800
Subject: [PATCH v11 3/5] spmi: mediatek: Add support for MT6873/8192
In-Reply-To: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1629193630-19994-4-git-send-email-hsin-hsiung.wang@mediatek.com>

Add spmi support for MT6873/8192.

Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
---
changes since v10:
- remove the unnecessary check for clk and drop debug log.
- include platform_device.h for platform driver.
- add a new blank line before function returns.
- refactor the driver for better code quality.
---
 drivers/spmi/Kconfig         |  10 +
 drivers/spmi/Makefile        |   2 +
 drivers/spmi/spmi-mtk-pmif.c | 459 +++++++++++++++++++++++++++++++++++
 3 files changed, 471 insertions(+)
 create mode 100644 drivers/spmi/spmi-mtk-pmif.c

diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index 2874b6c26028..ea5703f6e544 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -34,4 +34,14 @@ config SPMI_MSM_PMIC_ARB
 	  This is required for communicating with Qualcomm PMICs and
 	  other devices that have the SPMI interface.
 
+config SPMI_MTK_PMIF
+	tristate "Mediatek SPMI Controller (PMIC Arbiter)"
+	help
+	  If you say yes to this option, support will be included for the
+	  built-in SPMI PMIC Arbiter interface on Mediatek family
+	  processors.
+
+	  This is required for communicating with Mediatek PMICs and
+	  other devices that have the SPMI interface.
+
 endif
diff --git a/drivers/spmi/Makefile b/drivers/spmi/Makefile
index 6e092e6f290c..0b21aaffcbb9 100644
--- a/drivers/spmi/Makefile
+++ b/drivers/spmi/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_SPMI)	+= spmi.o
 
 obj-$(CONFIG_SPMI_HISI3670)	+= hisi-spmi-controller.o
 obj-$(CONFIG_SPMI_MSM_PMIC_ARB)	+= spmi-pmic-arb.o
+obj-$(CONFIG_SPMI_MTK_PMIF)	+= spmi-mtk-pmif.o
+
diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
new file mode 100644
index 000000000000..35d338a19d76
--- /dev/null
+++ b/drivers/spmi/spmi-mtk-pmif.c
@@ -0,0 +1,459 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2021 MediaTek Inc.
+
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/spmi.h>
+
+#define SWINF_IDLE	0x00
+#define SWINF_WFVLDCLR	0x06
+
+#define GET_SWINF(x)	(((x) >> 1) & 0x7)
+
+#define PMIF_CMD_REG_0		0
+#define PMIF_CMD_REG		1
+#define PMIF_CMD_EXT_REG	2
+#define PMIF_CMD_EXT_REG_LONG	3
+
+#define PMIF_DELAY_US   10
+#define PMIF_TIMEOUT_US (10 * 1000)
+
+#define PMIF_CHAN_OFFSET 0x5
+
+#define PMIF_MAX_CLKS	3
+
+#define SPMI_OP_ST_BUSY 1
+
+struct ch_reg {
+	u32 ch_sta;
+	u32 wdata;
+	u32 rdata;
+	u32 ch_send;
+	u32 ch_rdy;
+};
+
+struct pmif_data {
+	const u32	*regs;
+	const u32	*spmimst_regs;
+	u32	soc_chan;
+};
+
+struct pmif {
+	void __iomem	*base;
+	void __iomem	*spmimst_base;
+	struct ch_reg	chan;
+	struct clk_bulk_data clks[PMIF_MAX_CLKS];
+	size_t nclks;
+	const struct pmif_data *data;
+};
+
+static const char * const pmif_clock_names[] = {
+	"pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux",
+};
+
+enum pmif_regs {
+	PMIF_INIT_DONE,
+	PMIF_INF_EN,
+	PMIF_ARB_EN,
+	PMIF_CMDISSUE_EN,
+	PMIF_TIMER_CTRL,
+	PMIF_SPI_MODE_CTRL,
+	PMIF_IRQ_EVENT_EN_0,
+	PMIF_IRQ_FLAG_0,
+	PMIF_IRQ_CLR_0,
+	PMIF_IRQ_EVENT_EN_1,
+	PMIF_IRQ_FLAG_1,
+	PMIF_IRQ_CLR_1,
+	PMIF_IRQ_EVENT_EN_2,
+	PMIF_IRQ_FLAG_2,
+	PMIF_IRQ_CLR_2,
+	PMIF_IRQ_EVENT_EN_3,
+	PMIF_IRQ_FLAG_3,
+	PMIF_IRQ_CLR_3,
+	PMIF_IRQ_EVENT_EN_4,
+	PMIF_IRQ_FLAG_4,
+	PMIF_IRQ_CLR_4,
+	PMIF_WDT_EVENT_EN_0,
+	PMIF_WDT_FLAG_0,
+	PMIF_WDT_EVENT_EN_1,
+	PMIF_WDT_FLAG_1,
+	PMIF_SWINF_0_STA,
+	PMIF_SWINF_0_WDATA_31_0,
+	PMIF_SWINF_0_RDATA_31_0,
+	PMIF_SWINF_0_ACC,
+	PMIF_SWINF_0_VLD_CLR,
+	PMIF_SWINF_1_STA,
+	PMIF_SWINF_1_WDATA_31_0,
+	PMIF_SWINF_1_RDATA_31_0,
+	PMIF_SWINF_1_ACC,
+	PMIF_SWINF_1_VLD_CLR,
+	PMIF_SWINF_2_STA,
+	PMIF_SWINF_2_WDATA_31_0,
+	PMIF_SWINF_2_RDATA_31_0,
+	PMIF_SWINF_2_ACC,
+	PMIF_SWINF_2_VLD_CLR,
+	PMIF_SWINF_3_STA,
+	PMIF_SWINF_3_WDATA_31_0,
+	PMIF_SWINF_3_RDATA_31_0,
+	PMIF_SWINF_3_ACC,
+	PMIF_SWINF_3_VLD_CLR,
+};
+
+static const u32 mt6873_regs[] = {
+	[PMIF_INIT_DONE] =	0x0000,
+	[PMIF_INF_EN] =		0x0024,
+	[PMIF_ARB_EN] =		0x0150,
+	[PMIF_CMDISSUE_EN] =	0x03B4,
+	[PMIF_TIMER_CTRL] =	0x03E0,
+	[PMIF_SPI_MODE_CTRL] =	0x0400,
+	[PMIF_IRQ_EVENT_EN_0] =	0x0418,
+	[PMIF_IRQ_FLAG_0] =	0x0420,
+	[PMIF_IRQ_CLR_0] =	0x0424,
+	[PMIF_IRQ_EVENT_EN_1] =	0x0428,
+	[PMIF_IRQ_FLAG_1] =	0x0430,
+	[PMIF_IRQ_CLR_1] =	0x0434,
+	[PMIF_IRQ_EVENT_EN_2] =	0x0438,
+	[PMIF_IRQ_FLAG_2] =	0x0440,
+	[PMIF_IRQ_CLR_2] =	0x0444,
+	[PMIF_IRQ_EVENT_EN_3] =	0x0448,
+	[PMIF_IRQ_FLAG_3] =	0x0450,
+	[PMIF_IRQ_CLR_3] =	0x0454,
+	[PMIF_IRQ_EVENT_EN_4] =	0x0458,
+	[PMIF_IRQ_FLAG_4] =	0x0460,
+	[PMIF_IRQ_CLR_4] =	0x0464,
+	[PMIF_WDT_EVENT_EN_0] =	0x046C,
+	[PMIF_WDT_FLAG_0] =	0x0470,
+	[PMIF_WDT_EVENT_EN_1] =	0x0474,
+	[PMIF_WDT_FLAG_1] =	0x0478,
+	[PMIF_SWINF_0_ACC] =	0x0C00,
+	[PMIF_SWINF_0_WDATA_31_0] =	0x0C04,
+	[PMIF_SWINF_0_RDATA_31_0] =	0x0C14,
+	[PMIF_SWINF_0_VLD_CLR] =	0x0C24,
+	[PMIF_SWINF_0_STA] =	0x0C28,
+	[PMIF_SWINF_1_ACC] =	0x0C40,
+	[PMIF_SWINF_1_WDATA_31_0] =	0x0C44,
+	[PMIF_SWINF_1_RDATA_31_0] =	0x0C54,
+	[PMIF_SWINF_1_VLD_CLR] =	0x0C64,
+	[PMIF_SWINF_1_STA] =	0x0C68,
+	[PMIF_SWINF_2_ACC] =	0x0C80,
+	[PMIF_SWINF_2_WDATA_31_0] =	0x0C84,
+	[PMIF_SWINF_2_RDATA_31_0] =	0x0C94,
+	[PMIF_SWINF_2_VLD_CLR] =	0x0CA4,
+	[PMIF_SWINF_2_STA] =	0x0CA8,
+	[PMIF_SWINF_3_ACC] =	0x0CC0,
+	[PMIF_SWINF_3_WDATA_31_0] =	0x0CC4,
+	[PMIF_SWINF_3_RDATA_31_0] =	0x0CD4,
+	[PMIF_SWINF_3_VLD_CLR] =	0x0CE4,
+	[PMIF_SWINF_3_STA] =	0x0CE8,
+};
+
+enum spmi_regs {
+	SPMI_OP_ST_CTRL,
+	SPMI_GRP_ID_EN,
+	SPMI_OP_ST_STA,
+	SPMI_MST_SAMPL,
+	SPMI_MST_REQ_EN,
+	SPMI_REC_CTRL,
+	SPMI_REC0,
+	SPMI_REC1,
+	SPMI_REC2,
+	SPMI_REC3,
+	SPMI_REC4,
+	SPMI_MST_DBG,
+};
+
+static const u32 mt6873_spmi_regs[] = {
+	[SPMI_OP_ST_CTRL] =	0x0000,
+	[SPMI_GRP_ID_EN] =	0x0004,
+	[SPMI_OP_ST_STA] =	0x0008,
+	[SPMI_MST_SAMPL] =	0x000c,
+	[SPMI_MST_REQ_EN] =	0x0010,
+	[SPMI_REC_CTRL] =	0x0040,
+	[SPMI_REC0] =		0x0044,
+	[SPMI_REC1] =		0x0048,
+	[SPMI_REC2] =		0x004c,
+	[SPMI_REC3] =		0x0050,
+	[SPMI_REC4] =		0x0054,
+	[SPMI_MST_DBG] =	0x00fc,
+};
+
+static u32 pmif_readl(struct pmif *arb, enum pmif_regs reg)
+{
+	return readl(arb->base + arb->data->regs[reg]);
+}
+
+static void pmif_writel(struct pmif *arb, u32 val, enum pmif_regs reg)
+{
+	writel(val, arb->base + arb->data->regs[reg]);
+}
+
+static void mtk_spmi_writel(struct pmif *arb, u32 val, enum spmi_regs reg)
+{
+	writel(val, arb->spmimst_base + arb->data->spmimst_regs[reg]);
+}
+
+static bool pmif_is_fsm_vldclr(struct pmif *arb)
+{
+	u32 reg_rdata;
+
+	reg_rdata = pmif_readl(arb, arb->chan.ch_sta);
+
+	return GET_SWINF(reg_rdata) == SWINF_WFVLDCLR;
+}
+
+static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
+{
+	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+	u32 rdata, cmd;
+	int ret;
+
+	/* Check the opcode */
+	if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
+		return -EINVAL;
+
+	cmd = opc - SPMI_CMD_RESET;
+
+	mtk_spmi_writel(arb, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL);
+	ret = readl_poll_timeout_atomic(arb->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA],
+					rdata, (rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY,
+					PMIF_DELAY_US, PMIF_TIMEOUT_US);
+	if (ret < 0)
+		dev_err(&ctrl->dev, "timeout, err = %d\n", ret);
+
+	return ret;
+}
+
+static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+			      u16 addr, u8 *buf, size_t len)
+{
+	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+	struct ch_reg *inf_reg;
+	int ret;
+	u32 data, cmd;
+
+	/* Check for argument validation. */
+	if (sid & ~0xf) {
+		dev_err(&ctrl->dev, "exceed the max slv id\n");
+		return -EINVAL;
+	}
+
+	if (len > 4) {
+		dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
+
+		return -EINVAL;
+	}
+
+	if (opc >= 0x60 && opc <= 0x7f)
+		opc = PMIF_CMD_REG;
+	else if ((opc >= 0x20 && opc <= 0x2f) || (opc >= 0x38 && opc <= 0x3f))
+		opc = PMIF_CMD_EXT_REG_LONG;
+	else
+		return -EINVAL;
+
+	/* Wait for Software Interface FSM state to be IDLE. */
+	inf_reg = &arb->chan;
+	ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
+					data, GET_SWINF(data) == SWINF_IDLE,
+					PMIF_DELAY_US, PMIF_TIMEOUT_US);
+	if (ret < 0) {
+		/* set channel ready if the data has transferred */
+		if (pmif_is_fsm_vldclr(arb))
+			pmif_writel(arb, 1, inf_reg->ch_rdy);
+		dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
+		goto out;
+	}
+
+	/* Send the command. */
+	cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr;
+	pmif_writel(arb, cmd, inf_reg->ch_send);
+
+	/*
+	 * Wait for Software Interface FSM state to be WFVLDCLR,
+	 * read the data and clear the valid flag.
+	 */
+	ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
+					data, GET_SWINF(data) == SWINF_WFVLDCLR,
+					PMIF_DELAY_US, PMIF_TIMEOUT_US);
+	if (ret < 0) {
+		dev_err(&ctrl->dev, "failed to wait for SWINF_WFVLDCLR\n");
+		goto out;
+	}
+
+	data = pmif_readl(arb, inf_reg->rdata);
+	memcpy(buf, &data, len);
+	pmif_writel(arb, 1, inf_reg->ch_rdy);
+
+out:
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+			       u16 addr, const u8 *buf, size_t len)
+{
+	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+	struct ch_reg *inf_reg;
+	int ret;
+	u32 data, cmd;
+
+	if (len > 4) {
+		dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
+
+		return -EINVAL;
+	}
+
+	/* Check the opcode */
+	if (opc >= 0x40 && opc <= 0x5F)
+		opc = PMIF_CMD_REG;
+	else if ((opc <= 0xF) || (opc >= 0x30 && opc <= 0x37))
+		opc = PMIF_CMD_EXT_REG_LONG;
+	else if (opc >= 0x80)
+		opc = PMIF_CMD_REG_0;
+	else
+		return -EINVAL;
+
+	/* Wait for Software Interface FSM state to be IDLE. */
+	inf_reg = &arb->chan;
+	ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
+					data, GET_SWINF(data) == SWINF_IDLE,
+					PMIF_DELAY_US, PMIF_TIMEOUT_US);
+	if (ret < 0) {
+		/* set channel ready if the data has transferred */
+		if (pmif_is_fsm_vldclr(arb))
+			pmif_writel(arb, 1, inf_reg->ch_rdy);
+		dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
+		goto out;
+	}
+
+	/* Set the write data. */
+	memcpy(&data, buf, len);
+	pmif_writel(arb, data, inf_reg->wdata);
+
+	/* Send the command. */
+	cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr;
+	pmif_writel(arb, cmd, inf_reg->ch_send);
+
+out:
+	return ret;
+}
+
+static const struct pmif_data mt6873_pmif_arb = {
+	.regs = mt6873_regs,
+	.spmimst_regs = mt6873_spmi_regs,
+	.soc_chan = 2,
+};
+
+static int mtk_spmi_probe(struct platform_device *pdev)
+{
+	struct pmif *arb;
+	struct spmi_controller *ctrl;
+	int err, i;
+	u32 chan_offset;
+
+	ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*arb));
+	if (!ctrl)
+		return -ENOMEM;
+
+	arb = spmi_controller_get_drvdata(ctrl);
+	arb->data = device_get_match_data(&pdev->dev);
+	if (!arb->data) {
+		err = -EINVAL;
+		dev_err(&pdev->dev, "Cannot get drv_data\n");
+		goto err_put_ctrl;
+	}
+
+	arb->base = devm_platform_ioremap_resource_byname(pdev, "pmif");
+	if (IS_ERR(arb->base)) {
+		err = PTR_ERR(arb->base);
+		goto err_put_ctrl;
+	}
+
+	arb->spmimst_base = devm_platform_ioremap_resource_byname(pdev, "spmimst");
+	if (IS_ERR(arb->spmimst_base)) {
+		err = PTR_ERR(arb->spmimst_base);
+		goto err_put_ctrl;
+	}
+
+	arb->nclks = ARRAY_SIZE(pmif_clock_names);
+	for (i = 0; i < arb->nclks; i++)
+		arb->clks[i].id = pmif_clock_names[i];
+
+	err = devm_clk_bulk_get(&pdev->dev, arb->nclks, arb->clks);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to get clocks: %d\n", err);
+		goto err_put_ctrl;
+	}
+
+	err = clk_bulk_prepare_enable(arb->nclks, arb->clks);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to enable clocks: %d\n", err);
+		goto err_put_ctrl;
+	}
+
+	ctrl->cmd = pmif_arb_cmd;
+	ctrl->read_cmd = pmif_spmi_read_cmd;
+	ctrl->write_cmd = pmif_spmi_write_cmd;
+
+	chan_offset = PMIF_CHAN_OFFSET * arb->data->soc_chan;
+	arb->chan.ch_sta = PMIF_SWINF_0_STA + chan_offset;
+	arb->chan.wdata = PMIF_SWINF_0_WDATA_31_0 + chan_offset;
+	arb->chan.rdata = PMIF_SWINF_0_RDATA_31_0 + chan_offset;
+	arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset;
+	arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset;
+
+	platform_set_drvdata(pdev, ctrl);
+
+	err = spmi_controller_add(ctrl);
+	if (err)
+		goto err_domain_remove;
+
+	return 0;
+
+err_domain_remove:
+	clk_bulk_disable_unprepare(arb->nclks, arb->clks);
+err_put_ctrl:
+	spmi_controller_put(ctrl);
+	return err;
+}
+
+static int mtk_spmi_remove(struct platform_device *pdev)
+{
+	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
+	struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+
+	clk_bulk_disable_unprepare(arb->nclks, arb->clks);
+	spmi_controller_remove(ctrl);
+	spmi_controller_put(ctrl);
+	return 0;
+}
+
+static const struct of_device_id mtk_spmi_match_table[] = {
+	{
+		.compatible = "mediatek,mt6873-spmi",
+		.data = &mt6873_pmif_arb,
+	}, {
+		/* sentinel */
+	},
+};
+MODULE_DEVICE_TABLE(of, mtk_spmi_match_table);
+
+static struct platform_driver mtk_spmi_driver = {
+	.driver		= {
+		.name	= "spmi-mtk",
+		.of_match_table = of_match_ptr(mtk_spmi_match_table),
+	},
+	.probe		= mtk_spmi_probe,
+	.remove		= mtk_spmi_remove,
+};
+module_platform_driver(mtk_spmi_driver);
+
+MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>");
+MODULE_DESCRIPTION("MediaTek SPMI Driver");
+MODULE_LICENSE("GPL");
-- 
2.18.0

From ck.hu at mediatek.com  Tue Aug 17 02:50:44 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Tue, 17 Aug 2021 17:50:44 +0800
Subject: [RFC PATCH 2/5] drm/mediatek: dpi: Add dpintf support
In-Reply-To: <20210816192523.1739365-3-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-3-msp@baylibre.com>
Message-ID: <1629193844.19746.2.camel@mtksdaap41>

Hi, Markus:

On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> dpintf is the displayport interface hardware unit. This unit is similar
> to dpi and can reuse most of the code.
> 
> This patch adds support for mt8195-dpintf to this dpi driver. Main
> differences are:
>  - Some features/functional components are not available for dpintf
>    which are now excluded from code execution once is_dpintf is set
>  - dpintf can and needs to choose between different clockdividers based
>    on the clockspeed. This is done by choosing a different clock parent.
>  - There are two additional clocks that need to be managed. These are
>    only set for dpintf and will be set to NULL if not supplied. The
>    clk_* calls handle these as normal clocks then.
>  - Some register contents differ slightly between the two components. To
>    work around this I added register bits/masks with a DPINTF_ prefix
>    and use them where different.
> 
> Based on a separate driver for dpintf created by
> Jason-JH.Lin <jason-jh.lin at mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c      | 282 ++++++++++++++++++++----
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
>  2 files changed, 247 insertions(+), 47 deletions(-)
> 

[snip]

>  
> +static void mtk_dpi_set_pixel_clk_parent(struct mtk_dpi *dpi,
> +					 unsigned int factor)
> +{
> +	struct clk *new_parent;
> +
> +	switch (factor) {
> +	case 16:
> +		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D16].clk;
> +		break;
> +	case 8:
> +		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D8].clk;
> +		break;
> +	case 4:
> +		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D4].clk;
> +		break;
> +	case 2:
> +		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D2].clk;
> +		break;
> +	default:
> +		new_parent = NULL;
> +	}
> +	if (new_parent)
> +		clk_set_parent(dpi->pixel_clk, new_parent);

I prefer that dpi->pixel_clk provide set_rate() interface, and let clock
driver to control the parent of dpi->pixel_clk.

Regards,
CK

> +}
> +
>  static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>  				    struct drm_display_mode *mode)
>  {
> @@ -465,6 +568,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>  	drm_display_mode_to_videomode(mode, &vm);
>  	pll_rate = vm.pixelclock * factor;
>  
> +	mtk_dpi_set_pixel_clk_parent(dpi, factor);
> +
>  	dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
>  		pll_rate, vm.pixelclock);
>  



From l.stelmach at samsung.com  Tue Aug 17 02:55:44 2021
From: l.stelmach at samsung.com (Lukasz Stelmach)
Date: Tue, 17 Aug 2021 11:55:44 +0200
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to
 dtschema
In-Reply-To: <20210811084306.28740-2-krzysztof.kozlowski@canonical.com>
 (Krzysztof Kozlowski's message of "Wed, 11 Aug 2021 10:43:06 +0200")
References: <20210811084306.28740-2-krzysztof.kozlowski@canonical.com>
 <CGME20210817095553eucas1p174e68fc6d7cfad9c2fd34f729272b01a@eucas1p1.samsung.com>
Message-ID: <dleftjeeasfl9b.fsf%l.stelmach@samsung.com>

It was <2021-08-11 ?ro 10:43>, when Krzysztof Kozlowski wrote:
> Convert Samsung Exynos SoC True Random Number Generator bindings to DT
> schema format using json-schema.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
>  .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
>  MAINTAINERS                                   |  2 +-
>  3 files changed, 45 insertions(+), 18 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>  create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>
> diff --git
> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
> deleted file mode 100644
> index 5a613a4ec780..000000000000
> --- a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -Exynos True Random Number Generator
> -
> -Required properties:
> -
> -- compatible  : Should be "samsung,exynos5250-trng".
> -- reg         : Specifies base physical address and size of the registers map.
> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
> -- clock-names : "secss" as a clock name.
> -
> -Example:
> -
> -	rng at 10830600 {
> -		compatible = "samsung,exynos5250-trng";
> -		reg = <0x10830600 0x100>;
> -		clocks = <&clock CLK_SSS>;
> -		clock-names = "secss";
> -	};
> diff --git
> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
> new file mode 100644
> index 000000000000..a50c34d5d199
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
> @@ -0,0 +1,44 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id:
> https://protect2.fireeye.com/v1/url?k=f38ca35b-ac179a0d-f38d2814-0cc47a31ce52-1faa1ecb65482b8a&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Frng%2Fsamsung%2Cexynos5250-trng.yaml%23
> +$schema:
> https://protect2.fireeye.com/v1/url?k=9409519d-cb9268cb-9408dad2-0cc47a31ce52-12394c4409905980&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
> +
> +title: Samsung Exynos SoC True Random Number Generator
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - ?ukasz Stelmach <l.stelmach at samsung.com>
> +
> +properties:
> +  compatible:
> +    const: samsung,exynos5250-trng
> +
> +  clocks:
> +    maxItems: 1

How about copying description from above into the description: property?

> +
> +  clock-names:
> +    items:
> +      - const: secss
> +
> +  reg:
> +    maxItems: 1

ditto.

> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/exynos5250.h>
> +
> +    rng at 10830600 {
> +        compatible = "samsung,exynos5250-trng";
> +        reg = <0x10830600 0x100>;
> +        clocks = <&clock CLK_SSS>;
> +        clock-names = "secss";
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4477215ef649..ebdb07a49b02 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16398,7 +16398,7 @@ SAMSUNG EXYNOS TRUE RANDOM NUMBER GENERATOR (TRNG) DRIVER
>  M:	?ukasz Stelmach <l.stelmach at samsung.com>
>  L:	linux-samsung-soc at vger.kernel.org
>  S:	Maintained
> -F:	Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
> +F:	Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>  F:	drivers/char/hw_random/exynos-trng.c
>  
>  SAMSUNG FRAMEBUFFER DRIVER

-- 
?ukasz Stelmach
Samsung R&D Institute Poland
Samsung Electronics
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 487 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/87a0c9e2/attachment.sig>

From bbudiredla at marvell.com  Tue Aug 17 03:04:23 2021
From: bbudiredla at marvell.com (Bhaskara Budiredla)
Date: Tue, 17 Aug 2021 10:04:23 +0000
Subject: [EXT] Re: [PATCH 1/2] drivers: perf: Add LLC-TAD perf counter
 support
In-Reply-To: <e006077a-a60b-2772-bdca-58d8c68550a7@linux.ibm.com>
References: <20210812174209.1970-1-bbudiredla@marvell.com>
 <20210812174209.1970-2-bbudiredla@marvell.com>
 <e006077a-a60b-2772-bdca-58d8c68550a7@linux.ibm.com>
Message-ID: <CY4PR1801MB20704E4BD24834EA010E5EAEDEFE9@CY4PR1801MB2070.namprd18.prod.outlook.com>

Thanks Kajol for pointing to memory leak.
I will fix it in the next version.

Thanks,
Bhaskara

>-----Original Message-----
>From: kajoljain <kjain at linux.ibm.com>
>Sent: Saturday, August 14, 2021 7:24 PM
>To: Bhaskara Budiredla <bbudiredla at marvell.com>; will at kernel.org;
>mark.rutland at arm.com; robh+dt at kernel.org; Sunil Kovvuri Goutham
><sgoutham at marvell.com>
>Cc: linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; linux-
>kernel at vger.kernel.org
>Subject: [EXT] Re: [PATCH 1/2] drivers: perf: Add LLC-TAD perf counter support
>
>External Email
>
>----------------------------------------------------------------------
>
>
>On 8/12/21 11:12 PM, Bhaskara Budiredla wrote:
>> This driver adds support for Last-level cache tag-and-data unit
>> (LLC-TAD) PMU that is featured in some of the Marvell's CN10K
>> infrastructure silicons.
>>
>> The LLC is divided into 2N slices distributed across N Mesh tiles in a
>> single-socket configuration. The driver always configures the same
>> counter for all of the TADs. The user would end up effectively
>> reserving one of eight counters in every TAD to look across all TADs.
>> The occurrences of events are aggregated and presented to the user at
>> the end of an application run. The driver does not provide a way for
>> the user to partition TADs so that different TADs are used for
>> different applications.
>>
>> The event counters are zeroed on start event counting to avoid any
>> rollover issues. TAD perf counters are 64-bit, so it's not currently
>> possible to overflow event counters at current mesh and core
>> frequencies.
>>
>> To measure tad pmu events use perf tool stat command. For instance:
>>
>> perf stat -e tad_dat_msh_in_dss,tad_req_msh_out_any <application> perf
>> stat -e tad_alloc_any,tad_hit_any,tad_tag_rd <application>
>>
>> Signed-off-by: Bhaskara Budiredla <bbudiredla at marvell.com>
>> ---
>>  drivers/perf/Kconfig                 |   7 +
>>  drivers/perf/Makefile                |   1 +
>>  drivers/perf/marvell_cn10k_tad_pmu.c | 429
>> +++++++++++++++++++++++++++
>>  3 files changed, 437 insertions(+)
>>  create mode 100644 drivers/perf/marvell_cn10k_tad_pmu.c
>>
>> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig index
>> 77522e5efe11..73dca11f8080 100644
>> --- a/drivers/perf/Kconfig
>> +++ b/drivers/perf/Kconfig
>> @@ -137,6 +137,13 @@ config ARM_DMC620_PMU
>>  	  Support for PMU events monitoring on the ARM DMC-620 memory
>>  	  controller.
>>
>> +config MARVELL_CN10K_TAD_PMU
>> +	tristate "Marvell CN10K LLC-TAD PMU"
>> +	depends on ARM64
>> +	help
>> +	  Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
>> +	  performance monitors on CN10K family silicons.
>> +
>>  source "drivers/perf/hisilicon/Kconfig"
>>
>>  endmenu
>> diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile index
>> 5260b116c7da..2db5418d5b0a 100644
>> --- a/drivers/perf/Makefile
>> +++ b/drivers/perf/Makefile
>> @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) +=
>thunderx2_pmu.o
>>  obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
>>  obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
>>  obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
>> +obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
>> diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c
>> b/drivers/perf/marvell_cn10k_tad_pmu.c
>> new file mode 100644
>> index 000000000000..fec8b90d52d2
>> --- /dev/null
>> +++ b/drivers/perf/marvell_cn10k_tad_pmu.c
>> @@ -0,0 +1,429 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/* Marvell CN10K LLC-TAD perf driver
>> + *
>> + * Copyright (C) 2021 Marvell.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> +modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#define pr_fmt(fmt) "tad_pmu: " fmt
>> +
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/cpuhotplug.h>
>> +#include <linux/perf_event.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/arm-smccc.h>
>> +
>> +#define TAD_PFC_OFFSET		0x0800
>> +#define TAD_PFC(counter)	(TAD_PFC_OFFSET | (counter << 3))
>> +#define TAD_PRF_OFFSET		0x0900
>> +#define TAD_PRF(counter)	(TAD_PRF_OFFSET | (counter << 3))
>> +#define TAD_PRF_CNTSEL_MASK	0xFF
>> +#define TAD_MAX_COUNTERS	8
>> +
>> +#define to_tad_pmu(p) (container_of(p, struct tad_pmu, pmu))
>> +
>> +struct tad_region {
>> +	void __iomem	*base;
>> +};
>> +
>> +struct tad_pmu {
>> +	struct pmu pmu;
>> +	struct tad_region *regions;
>> +	u32 region_cnt;
>> +	unsigned int cpu;
>> +	struct hlist_node node;
>> +	struct perf_event *events[TAD_MAX_COUNTERS];
>> +	DECLARE_BITMAP(counters_map, TAD_MAX_COUNTERS); };
>> +
>> +static int tad_pmu_cpuhp_state;
>> +
>> +static void tad_pmu_event_counter_read(struct perf_event *event) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>> +	struct hw_perf_event *hwc = &event->hw;
>> +	u32 counter_idx = hwc->idx;
>> +	u64 delta, prev, new;
>> +	int i;
>> +
>> +	do {
>> +		prev = local64_read(&hwc->prev_count);
>> +		for (i = 0, new = 0; i < tad_pmu->region_cnt; i++)
>> +			new += readq(tad_pmu->regions[i].base +
>> +				     TAD_PFC(counter_idx));
>> +	} while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev);
>> +
>> +	delta = (new - prev) & GENMASK_ULL(63, 0);
>> +	local64_add(delta, &event->count);
>> +}
>> +
>> +static void tad_pmu_event_counter_stop(struct perf_event *event, int
>> +flags) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>> +	struct hw_perf_event *hwc = &event->hw;
>> +	u32 counter_idx = hwc->idx;
>> +	int i;
>> +
>> +	/* TAD()_PFC() stop counting on the write
>> +	 * which sets TAD()_PRF()[CNTSEL] == 0
>> +	 */
>> +	for (i = 0; i < tad_pmu->region_cnt; i++)
>> +		writeq_relaxed(0, tad_pmu->regions[i].base +
>> +			       TAD_PRF(counter_idx));
>> +
>> +	tad_pmu_event_counter_read(event);
>> +	hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; }
>> +
>> +static void tad_pmu_event_counter_start(struct perf_event *event, int
>> +flags) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>> +	struct hw_perf_event *hwc = &event->hw;
>> +	u32 event_idx = event->attr.config;
>> +	u32 counter_idx = hwc->idx;
>> +	u64 reg_val;
>> +	int i;
>> +
>> +	hwc->state = 0;
>> +
>> +	/* Typically TAD_PFC() are zeroed to start counting */
>> +	for (i = 0; i < tad_pmu->region_cnt; i++)
>> +		writeq_relaxed(0, tad_pmu->regions[i].base +
>> +			       TAD_PFC(counter_idx));
>> +
>> +	/* TAD()_PFC() start counting on the write
>> +	 * which sets TAD()_PRF()[CNTSEL] != 0
>> +	 */
>> +	for (i = 0; i < tad_pmu->region_cnt; i++) {
>> +		reg_val = readq_relaxed(tad_pmu->regions[i].base +
>> +					TAD_PRF(counter_idx));
>> +		reg_val |= (event_idx & 0xFF);
>> +		writeq_relaxed(reg_val,	tad_pmu->regions[i].base +
>> +			       TAD_PRF(counter_idx));
>> +	}
>> +}
>> +
>> +static void tad_pmu_event_counter_del(struct perf_event *event, int
>> +flags) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>> +	struct hw_perf_event *hwc = &event->hw;
>> +	int idx = hwc->idx;
>> +
>> +	tad_pmu_event_counter_stop(event, flags | PERF_EF_UPDATE);
>> +	tad_pmu->events[idx] = NULL;
>> +	clear_bit(idx, tad_pmu->counters_map); }
>> +
>> +static int tad_pmu_event_counter_add(struct perf_event *event, int
>> +flags) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>> +	struct hw_perf_event *hwc = &event->hw;
>> +	int idx;
>> +
>> +	/* Get a free counter for this event */
>> +	idx = find_first_zero_bit(tad_pmu->counters_map,
>TAD_MAX_COUNTERS);
>> +	if (idx == TAD_MAX_COUNTERS)
>> +		return -EAGAIN;
>> +
>> +	set_bit(idx, tad_pmu->counters_map);
>> +
>> +	hwc->idx = idx;
>> +	hwc->state = PERF_HES_STOPPED;
>> +	tad_pmu->events[idx] = event;
>> +
>> +	if (flags & PERF_EF_START)
>> +		tad_pmu_event_counter_start(event, flags);
>> +
>> +	return 0;
>> +}
>> +
>> +static int tad_pmu_event_init(struct perf_event *event) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>> +
>> +	if (!event->attr.disabled)
>> +		return -EINVAL;
>> +
>> +	if (event->attr.type != event->pmu->type)
>> +		return -ENOENT;
>> +
>> +	if (event->state != PERF_EVENT_STATE_OFF)
>> +		return -EINVAL;
>> +
>> +	event->cpu = tad_pmu->cpu;
>> +	event->hw.idx = -1;
>> +	event->hw.config_base = event->attr.config;
>> +
>> +	return 0;
>> +}
>> +
>> +static ssize_t tad_pmu_event_show(struct device *dev,
>> +				struct device_attribute *attr, char *page) {
>> +	struct perf_pmu_events_attr *pmu_attr;
>> +
>> +	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
>> +	return sprintf(page, "event=0x%02llx\n", pmu_attr->id); }
>> +
>> +#define TAD_PMU_EVENT_ATTR(name, config)			\
>> +	PMU_EVENT_ATTR_ID(name, tad_pmu_event_show, config)
>> +
>> +static struct attribute *tad_pmu_event_attrs[] = {
>> +	TAD_PMU_EVENT_ATTR(tad_none, 0x0),
>> +	TAD_PMU_EVENT_ATTR(tad_req_msh_in_any, 0x1),
>> +	TAD_PMU_EVENT_ATTR(tad_req_msh_in_mn, 0x2),
>> +	TAD_PMU_EVENT_ATTR(tad_req_msh_in_exlmn, 0x3),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_any, 0x4),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_mn, 0x5),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_exlmn, 0x6),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_dss, 0x7),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_in_retry_dss, 0x8),
>> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_in_any, 0x9),
>> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_in_dss, 0xa),
>> +	TAD_PMU_EVENT_ATTR(tad_req_msh_out_any, 0xb),
>> +	TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_rd, 0xc),
>> +	TAD_PMU_EVENT_ATTR(tad_req_msh_out_dss_wr, 0xd),
>> +	TAD_PMU_EVENT_ATTR(tad_req_msh_out_evict, 0xe),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_any, 0xf),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_retry_exlmn, 0x10),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_retry_mn, 0x11),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_exlmn, 0x12),
>> +	TAD_PMU_EVENT_ATTR(tad_rsp_msh_out_mn, 0x13),
>> +	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_any, 0x14),
>> +	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_mn, 0x15),
>> +	TAD_PMU_EVENT_ATTR(tad_snp_msh_out_exlmn, 0x16),
>> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_any, 0x17),
>> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_fill, 0x18),
>> +	TAD_PMU_EVENT_ATTR(tad_dat_msh_out_dss, 0x19),
>> +	TAD_PMU_EVENT_ATTR(tad_alloc_dtg, 0x1a),
>> +	TAD_PMU_EVENT_ATTR(tad_alloc_ltg, 0x1b),
>> +	TAD_PMU_EVENT_ATTR(tad_alloc_any, 0x1c),
>> +	TAD_PMU_EVENT_ATTR(tad_hit_dtg, 0x1d),
>> +	TAD_PMU_EVENT_ATTR(tad_hit_ltg, 0x1e),
>> +	TAD_PMU_EVENT_ATTR(tad_hit_any, 0x1f),
>> +	TAD_PMU_EVENT_ATTR(tad_tag_rd, 0x20),
>> +	TAD_PMU_EVENT_ATTR(tad_dat_rd, 0x21),
>> +	TAD_PMU_EVENT_ATTR(tad_dat_rd_byp, 0x22),
>> +	TAD_PMU_EVENT_ATTR(tad_ifb_occ, 0x23),
>> +	TAD_PMU_EVENT_ATTR(tad_req_occ, 0x24),
>> +	NULL,
>> +};
>> +
>> +static const struct attribute_group tad_pmu_events_attr_group = {
>> +	.name = "events",
>> +	.attrs = tad_pmu_event_attrs,
>> +};
>> +
>> +PMU_FORMAT_ATTR(event, "config:0-7");
>> +
>> +static struct attribute *tad_pmu_format_attrs[] = {
>> +	&format_attr_event.attr,
>> +	NULL,
>> +};
>> +
>> +static struct attribute_group tad_pmu_format_attr_group = {
>> +	.name = "format",
>> +	.attrs = tad_pmu_format_attrs,
>> +};
>> +
>> +static ssize_t tad_pmu_cpumask_show(struct device *dev,
>> +				struct device_attribute *attr, char *buf) {
>> +	struct tad_pmu *tad_pmu = to_tad_pmu(dev_get_drvdata(dev));
>> +
>> +	return cpumap_print_to_pagebuf(true, buf, cpumask_of(tad_pmu-
>>cpu));
>> +}
>> +
>> +static DEVICE_ATTR(cpumask, 0444, tad_pmu_cpumask_show, NULL);
>> +
>> +static struct attribute *tad_pmu_cpumask_attrs[] = {
>> +	&dev_attr_cpumask.attr,
>> +	NULL,
>> +};
>> +
>> +static struct attribute_group tad_pmu_cpumask_attr_group = {
>> +	.attrs = tad_pmu_cpumask_attrs,
>> +};
>> +
>> +static const struct attribute_group *tad_pmu_attr_groups[] = {
>> +	&tad_pmu_events_attr_group,
>> +	&tad_pmu_format_attr_group,
>> +	&tad_pmu_cpumask_attr_group,
>> +	NULL,
>> +};
>> +
>> +static int tad_pmu_probe(struct platform_device *pdev) {
>> +	struct device_node *node = pdev->dev.of_node;
>> +	struct tad_region *regions;
>> +	struct tad_pmu *tad_pmu;
>> +	struct resource *res;
>> +	u32 tad_pmu_page_size;
>> +	u32 tad_page_size;
>> +	u32 tad_cnt;
>> +	int i, ret;
>> +	char *name;
>> +
>> +	tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu),
>GFP_KERNEL);
>> +	if (!tad_pmu)
>> +		return -ENOMEM;
>> +
>> +	platform_set_drvdata(pdev, tad_pmu);
>> +
>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +	if (!res) {
>> +		dev_err(&pdev->dev, "Mem resource not found\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	ret = of_property_read_u32(node, "tad-page-size", &tad_page_size);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "Can't find tad-page-size property\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = of_property_read_u32(node, "tad-pmu-page-size",
>> +				   &tad_pmu_page_size);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "Can't find tad-pmu-page-size
>property\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = of_property_read_u32(node, "tad-cnt", &tad_cnt);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "Can't find tad-cnt property\n");
>> +		return ret;
>> +	}
>> +
>> +	regions = devm_kcalloc(&pdev->dev, tad_cnt,
>> +			       sizeof(*regions), GFP_KERNEL);
>> +	if (!regions)
>> +		return -ENOMEM;
>> +
>> +	/* ioremap the distributed TAD pmu regions */
>> +	for (i = 0; i < tad_cnt && res->start < res->end; i++) {
>> +		regions[i].base = devm_ioremap(&pdev->dev,
>> +					       res->start,
>> +					       tad_pmu_page_size);
>> +		if (IS_ERR(regions[i].base)) {
>> +			dev_err(&pdev->dev, "TAD%d ioremap fail\n", i);
>> +			return -ENOMEM;
>> +		}
>> +		res->start += tad_page_size;
>> +	}
>> +
>> +	tad_pmu->regions = regions;
>> +	tad_pmu->region_cnt = tad_cnt;
>> +
>> +	tad_pmu->pmu = (struct pmu) {
>> +
>> +		.module		= THIS_MODULE,
>> +		.attr_groups	= tad_pmu_attr_groups,
>> +		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
>> +				  PERF_PMU_CAP_NO_INTERRUPT,
>> +		.task_ctx_nr	= perf_invalid_context,
>> +
>> +		.event_init	= tad_pmu_event_init,
>> +		.add		= tad_pmu_event_counter_add,
>> +		.del		= tad_pmu_event_counter_del,
>> +		.start		= tad_pmu_event_counter_start,
>> +		.stop		= tad_pmu_event_counter_stop,
>> +		.read		= tad_pmu_event_counter_read,
>> +	};
>> +
>> +	tad_pmu->cpu = raw_smp_processor_id();
>> +
>
>Hi Bhaskara,
>   I think there is some memory leaks in this function. Incase cpuotplug code
>fails, don't we need to free momory allocated to `tad_pmu`?
>
>Thanks,
>Kajol Jain
>
>
>> +	/* Register pmu instance for cpu hotplug */
>> +	ret = cpuhp_state_add_instance_nocalls(tad_pmu_cpuhp_state,
>> +					       &tad_pmu->node);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	name = "tad";
>> +	ret = perf_pmu_register(&tad_pmu->pmu, name, -1);
>> +	if (ret)
>> +
>	cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
>> +						    &tad_pmu->node);
>> +
>> +	return ret;
>> +}
>> +
>> +static int tad_pmu_remove(struct platform_device *pdev) {
>> +	struct tad_pmu *pmu = platform_get_drvdata(pdev);
>> +
>> +	cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
>> +						&pmu->node);
>> +	perf_pmu_unregister(&pmu->pmu);
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct of_device_id tad_pmu_of_match[] = {
>> +	{ .compatible = "marvell,cn10k-tad-pmu", },
>> +	{},
>> +};
>> +
>> +static struct platform_driver tad_pmu_driver = {
>> +	.driver         = {
>> +		.name   = "cn10k_tad_pmu",
>> +		.of_match_table = of_match_ptr(tad_pmu_of_match),
>> +		.suppress_bind_attrs = true,
>> +	},
>> +	.probe          = tad_pmu_probe,
>> +	.remove         = tad_pmu_remove,
>> +};
>> +
>> +static int tad_pmu_offline_cpu(unsigned int cpu, struct hlist_node
>> +*node) {
>> +	struct tad_pmu *pmu = hlist_entry_safe(node, struct tad_pmu, node);
>> +	unsigned int target;
>> +
>> +	if (cpu != pmu->cpu)
>> +		return 0;
>> +
>> +	target = cpumask_any_but(cpu_online_mask, cpu);
>> +	if (target >= nr_cpu_ids)
>> +		return 0;
>> +
>> +	perf_pmu_migrate_context(&pmu->pmu, cpu, target);
>> +	pmu->cpu = target;
>> +
>> +	return 0;
>> +}
>> +
>> +static int __init tad_pmu_init(void)
>> +{
>> +	int ret;
>> +
>> +	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
>> +				      "perf/cn10k/tadpmu:online",
>> +				      NULL,
>> +				      tad_pmu_offline_cpu);
>
>> +	if (ret < 0)
>> +		return ret;
>> +	tad_pmu_cpuhp_state = ret;
>> +	return platform_driver_register(&tad_pmu_driver);
>> +}
>> +
>> +static void __exit tad_pmu_exit(void) {
>> +	platform_driver_unregister(&tad_pmu_driver);
>> +	cpuhp_remove_multi_state(tad_pmu_cpuhp_state);
>> +}
>> +
>> +module_init(tad_pmu_init);
>> +module_exit(tad_pmu_exit);
>> +
>> +MODULE_DESCRIPTION("Marvell CN10K LLC-TAD Perf driver");
>> +MODULE_AUTHOR("Bhaskara Budiredla <bbudiredla at marvell.com>");
>> +MODULE_LICENSE("GPL v2");
>>

From krzysztof.kozlowski at canonical.com  Tue Aug 17 03:05:20 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 17 Aug 2021 12:05:20 +0200
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to
 dtschema
In-Reply-To: <dleftjeeasfl9b.fsf%l.stelmach@samsung.com>
References: <20210811084306.28740-2-krzysztof.kozlowski@canonical.com>
 <CGME20210817095553eucas1p174e68fc6d7cfad9c2fd34f729272b01a@eucas1p1.samsung.com>
 <dleftjeeasfl9b.fsf%l.stelmach@samsung.com>
Message-ID: <c3a1d7d2-7b32-b7eb-4647-f86e22f5e5ff@canonical.com>

On 17/08/2021 11:55, Lukasz Stelmach wrote:
> It was <2021-08-11 ?ro 10:43>, when Krzysztof Kozlowski wrote:
>> Convert Samsung Exynos SoC True Random Number Generator bindings to DT
>> schema format using json-schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
>>  .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
>>  MAINTAINERS                                   |  2 +-
>>  3 files changed, 45 insertions(+), 18 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>  create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>
>> diff --git
>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>> deleted file mode 100644
>> index 5a613a4ec780..000000000000
>> --- a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>> +++ /dev/null
>> @@ -1,17 +0,0 @@
>> -Exynos True Random Number Generator
>> -
>> -Required properties:
>> -
>> -- compatible  : Should be "samsung,exynos5250-trng".
>> -- reg         : Specifies base physical address and size of the registers map.
>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
>> -- clock-names : "secss" as a clock name.
>> -
>> -Example:
>> -
>> -	rng at 10830600 {
>> -		compatible = "samsung,exynos5250-trng";
>> -		reg = <0x10830600 0x100>;
>> -		clocks = <&clock CLK_SSS>;
>> -		clock-names = "secss";
>> -	};
>> diff --git
>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>> new file mode 100644
>> index 000000000000..a50c34d5d199
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>> @@ -0,0 +1,44 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id:
>> https://protect2.fireeye.com/v1/url?k=f38ca35b-ac179a0d-f38d2814-0cc47a31ce52-1faa1ecb65482b8a&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Frng%2Fsamsung%2Cexynos5250-trng.yaml%23
>> +$schema:
>> https://protect2.fireeye.com/v1/url?k=9409519d-cb9268cb-9408dad2-0cc47a31ce52-12394c4409905980&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>> +
>> +title: Samsung Exynos SoC True Random Number Generator
>> +
>> +maintainers:
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +  - ?ukasz Stelmach <l.stelmach at samsung.com>
>> +
>> +properties:
>> +  compatible:
>> +    const: samsung,exynos5250-trng
>> +
>> +  clocks:
>> +    maxItems: 1
> 
> How about copying description from above into the description: property?

But what to copy? There is no description except generic clock bindings.

> 
>> +
>> +  clock-names:
>> +    items:
>> +      - const: secss
>> +
>> +  reg:
>> +    maxItems: 1
> 
> ditto.

The same, I have no clue what to copy. It's obvious that reg contains
"physical address and size of the registers map".


Best regards,
Krzysztof


From frattaroli.nicolas at gmail.com  Tue Aug 17 03:11:15 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Tue, 17 Aug 2021 12:11:15 +0200
Subject: [PATCH 0/4] Rockchip I2S/TDM controller
Message-ID: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>

Hello,

I come bearing four patches for your consideration.

The first of these four patches adds a driver for the Rockchip
I2S/TDM controller, used in interfacing between the AHB bus and the
I2S bus on some Rockchip SoCs. This allows for audio playback with
a matching codec.

The controller has three different modes: I2S, I2S/TDM and PCM.
It is distinct from the earlier Rockchip I2S controller, and
therefore not just an extension of that driver.

The driver is based on the downstream version, though various
changes have been made to hopefully make it more palatable to
upstream. Some needless code duplication has been refactored, and
the probe function will no longer let wrong device tree values
write nonsense to hardware registers. Properties have been renamed
and had their semantics changed. I won't bore you with the details
of what downstream did, since that's not what I'm submitting, but
the changes are significant enough that I've added myself to the
list of authors.

The second patch adds the YAML device tree bindings for this, which
have been written from scratch by yours truly. Since I didn't like
having random integers mean things, I defined them as constants in
a header file for the bindings.

The third patch adds the i2s1 controller to the rk356x device tree.
I didn't add any of the other i2s controllers on that SoC for now as
I have no way of testing them; in particular, i2s0 is tied to HDMI,
so needs a functioning VOP2 driver to even have a chance of working.

The fourth patch makes use of the i2s1 controller to enable analog
audio output on the Quartz64 Model A through its RK817 codec. I've
tested this to work properly at both 44.1 kHz and 96 kHz, so both
mclk_root0 and mclk_root1 are definitely functioning.

This is my first kernel contribution, so I most likely did
something horribly wrong. That's why I'm more than happy to receive
any criticisms and concerns over how the driver is implemented,
because I've run out of ideas on how to make it clearly better
myself.

I'd also like to extend my thanks to Peter Geis, who has been
acting as somewhat of a mentor and gave me occasional feedback
and ideas during the writing of this patch series.

Regards,
Nicolas Frattaroli

Nicolas Frattaroli (4):
  ASoC: rockchip: add support for i2s-tdm controller
  dt-bindings: sound: add rockchip i2s-tdm binding
  arm64: dts: rockchip: add i2s1 on rk356x
  arm64: dts: rockchip: add analog audio on Quartz64

 .../bindings/sound/rockchip,i2s-tdm.yaml      |  221 ++
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   |   36 +-
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |   26 +
 include/dt-bindings/sound/rockchip,i2s-tdm.h  |    9 +
 sound/soc/rockchip/Kconfig                    |   11 +
 sound/soc/rockchip/Makefile                   |    2 +
 sound/soc/rockchip/rockchip_i2s_tdm.c         | 1804 +++++++++++++++++
 sound/soc/rockchip/rockchip_i2s_tdm.h         |  400 ++++
 8 files changed, 2508 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
 create mode 100644 include/dt-bindings/sound/rockchip,i2s-tdm.h
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.c
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.h

-- 
2.32.0



From frattaroli.nicolas at gmail.com  Tue Aug 17 03:11:16 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Tue, 17 Aug 2021 12:11:16 +0200
Subject: [PATCH 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210817101119.423853-2-frattaroli.nicolas@gmail.com>

This commit adds support for the rockchip i2s-tdm controller,
which enables audio output on the following rockchip SoCs:
- px30
- rk1808
- rk3308
- rk3566
- rk3568
- rv1126

This is a cleaned up version of the downstream vendor kernel's
driver. It can be enabled through the SND_SOC_ROCKCHIP_I2S_TDM
configuration option.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 sound/soc/rockchip/Kconfig            |   11 +
 sound/soc/rockchip/Makefile           |    2 +
 sound/soc/rockchip/rockchip_i2s_tdm.c | 1804 +++++++++++++++++++++++++
 sound/soc/rockchip/rockchip_i2s_tdm.h |  400 ++++++
 4 files changed, 2217 insertions(+)
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.c
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.h

diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index 053097b73e28..42f76bc0fb02 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -16,6 +16,17 @@ config SND_SOC_ROCKCHIP_I2S
 	  Rockchip I2S device. The device supports upto maximum of
 	  8 channels each for play and record.
 
+config SND_SOC_ROCKCHIP_I2S_TDM
+	tristate "Rockchip I2S/TDM Device Driver"
+	depends on HAVE_CLK && SND_SOC_ROCKCHIP
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	help
+	  Say Y or M if you want to add support for the I2S/TDM driver for
+	  Rockchip I2S/TDM devices, found in Rockchip SoCs. These devices
+	  interface between the AHB bus and the I2S bus, and support up to a
+	  maximum of 8 channels each for playback and recording.
+
+
 config SND_SOC_ROCKCHIP_PDM
 	tristate "Rockchip PDM Controller Driver"
 	depends on HAVE_CLK && SND_SOC_ROCKCHIP
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 65e814d46006..b10f5e7b136d 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -1,11 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0
 # ROCKCHIP Platform Support
 snd-soc-rockchip-i2s-objs := rockchip_i2s.o
+snd-soc-rockchip-i2s-tdm-objs := rockchip_i2s_tdm.o
 snd-soc-rockchip-pcm-objs := rockchip_pcm.o
 snd-soc-rockchip-pdm-objs := rockchip_pdm.o
 snd-soc-rockchip-spdif-objs := rockchip_spdif.o
 
 obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o snd-soc-rockchip-pcm.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S_TDM) += snd-soc-rockchip-i2s-tdm.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_PDM) += snd-soc-rockchip-pdm.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
 
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
new file mode 100644
index 000000000000..3204bc54c267
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
@@ -0,0 +1,1804 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* sound/soc/rockchip/rockchip_i2s_tdm.c
+ *
+ * ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
+ *
+ * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
+ * Author: Sugar Zhang <sugar.zhang at rock-chips.com>
+ * Author: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/delay.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+#include <dt-bindings/sound/rockchip,i2s-tdm.h>
+
+#include "rockchip_i2s_tdm.h"
+
+#define DRV_NAME "rockchip-i2s-tdm"
+
+#define DEFAULT_MCLK_FS				256
+#define CH_GRP_MAX				4  /* The max channel 8 / 2 */
+#define MULTIPLEX_CH_MAX			10
+#define CLK_PPM_MIN				(-1000)
+#define CLK_PPM_MAX				(1000)
+
+struct txrx_config {
+	u32 addr;
+	u32 reg;
+	u32 txonly;
+	u32 rxonly;
+};
+
+struct rk_i2s_soc_data {
+	u32 softrst_offset;
+	u32 grf_reg_offset;
+	u32 grf_shift;
+	int config_count;
+	const struct txrx_config *configs;
+	int (*init)(struct device *dev, u32 addr);
+};
+
+struct rk_i2s_tdm_dev {
+	struct device *dev;
+	struct clk *hclk;
+	struct clk *mclk_tx;
+	struct clk *mclk_rx;
+	/* The mclk_tx_src is parent of mclk_tx */
+	struct clk *mclk_tx_src;
+	/* The mclk_rx_src is parent of mclk_rx */
+	struct clk *mclk_rx_src;
+	/*
+	 * The mclk_root0 and mclk_root1 are root parent and supplies for
+	 * the different FS.
+	 *
+	 * e.g:
+	 * mclk_root0 is VPLL0, used for FS=48000Hz
+	 * mclk_root1 is VPLL1, used for FS=44100Hz
+	 */
+	struct clk *mclk_root0;
+	struct clk *mclk_root1;
+	struct regmap *regmap;
+	struct regmap *grf;
+	struct snd_dmaengine_dai_dma_data capture_dma_data;
+	struct snd_dmaengine_dai_dma_data playback_dma_data;
+	struct reset_control *tx_reset;
+	struct reset_control *rx_reset;
+	struct rk_i2s_soc_data *soc_data;
+	void __iomem *cru_base;
+	bool is_master_mode;
+	bool io_multiplex;
+	bool mclk_calibrate;
+	bool tdm_mode;
+	bool tdm_fsync_half_frame;
+	unsigned int mclk_rx_freq;
+	unsigned int mclk_tx_freq;
+	unsigned int mclk_root0_freq;
+	unsigned int mclk_root1_freq;
+	unsigned int mclk_root0_initial_freq;
+	unsigned int mclk_root1_initial_freq;
+	unsigned int frame_width;
+	unsigned int clk_trcm;
+	unsigned int i2s_sdis[CH_GRP_MAX];
+	unsigned int i2s_sdos[CH_GRP_MAX];
+	int clk_ppm;
+	int tx_reset_id;
+	int rx_reset_id;
+	atomic_t refcount;
+	spinlock_t lock; /* xfer lock */
+};
+
+static int to_ch_num(unsigned int val)
+{
+	switch (val) {
+	case I2S_CHN_4:
+		return 4;
+	case I2S_CHN_6:
+		return 6;
+	case I2S_CHN_8:
+		return 8;
+	default:
+		return 2;
+	}
+}
+
+static int i2s_tdm_runtime_suspend(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+
+	regcache_cache_only(i2s_tdm->regmap, true);
+	if (!IS_ERR(i2s_tdm->mclk_tx))
+		clk_disable_unprepare(i2s_tdm->mclk_tx);
+	if (!IS_ERR(i2s_tdm->mclk_rx))
+		clk_disable_unprepare(i2s_tdm->mclk_rx);
+
+	return 0;
+}
+
+static int i2s_tdm_runtime_resume(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	int ret;
+
+	if (!IS_ERR(i2s_tdm->mclk_tx))
+		clk_prepare_enable(i2s_tdm->mclk_tx);
+	if (!IS_ERR(i2s_tdm->mclk_rx))
+		clk_prepare_enable(i2s_tdm->mclk_rx);
+
+	regcache_cache_only(i2s_tdm->regmap, false);
+	regcache_mark_dirty(i2s_tdm->regmap);
+
+	ret = regcache_sync(i2s_tdm->regmap);
+	if (ret) {
+		if (!IS_ERR(i2s_tdm->mclk_tx))
+			clk_disable_unprepare(i2s_tdm->mclk_tx);
+		if (!IS_ERR(i2s_tdm->mclk_rx))
+			clk_disable_unprepare(i2s_tdm->mclk_rx);
+	}
+
+	return ret;
+}
+
+static inline struct rk_i2s_tdm_dev *to_info(struct snd_soc_dai *dai)
+{
+	return snd_soc_dai_get_drvdata(dai);
+}
+
+#if defined(CONFIG_ARM) && !defined(writeq)
+static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
+{
+	asm volatile("strd %0, %H0, [%1]" : : "r" (val), "r" (addr));
+}
+#define writeq(v, c) ({ __iowmb(); \
+			__raw_writeq((__force u64) cpu_to_le64(v), c); })
+#endif
+
+static void rockchip_snd_xfer_reset_assert(struct rk_i2s_tdm_dev *i2s_tdm,
+					   int tx_bank, int tx_offset,
+					   int rx_bank, int rx_offset)
+{
+	void __iomem *cru_reset, *addr;
+	unsigned long flags;
+	u64 val;
+
+	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
+
+	switch (abs(tx_bank - rx_bank)) {
+	case 0:
+		writel(BIT(tx_offset) | BIT(rx_offset) |
+		       (BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+		break;
+	case 1:
+		if (tx_bank < rx_bank) {
+			val = BIT(rx_offset) | (BIT(rx_offset) << 16);
+			val <<= 32;
+			val |= BIT(tx_offset) | (BIT(tx_offset) << 16);
+			addr = cru_reset + (tx_bank * 4);
+		} else {
+			val = BIT(tx_offset) | (BIT(tx_offset) << 16);
+			val <<= 32;
+			val |= BIT(rx_offset) | (BIT(rx_offset) << 16);
+			addr = cru_reset + (rx_bank * 4);
+		}
+
+		if (IS_ALIGNED((uintptr_t)addr, 8)) {
+			writeq(val, addr);
+			break;
+		}
+		fallthrough;
+	default:
+		local_irq_save(flags);
+		writel(BIT(tx_offset) | (BIT(tx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+		writel(BIT(rx_offset) | (BIT(rx_offset) << 16),
+		       cru_reset + (rx_bank * 4));
+		local_irq_restore(flags);
+		break;
+	}
+}
+
+static void rockchip_snd_xfer_reset_deassert(struct rk_i2s_tdm_dev *i2s_tdm,
+					     int tx_bank, int tx_offset,
+					     int rx_bank, int rx_offset)
+{
+	void __iomem *cru_reset, *addr;
+	unsigned long flags;
+	u64 val;
+
+	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
+
+	switch (abs(tx_bank - rx_bank)) {
+	case 0:
+		writel((BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+		break;
+	case 1:
+		if (tx_bank < rx_bank) {
+			val = (BIT(rx_offset) << 16);
+			val <<= 32;
+			val |= (BIT(tx_offset) << 16);
+			addr = cru_reset + (tx_bank * 4);
+		} else {
+			val = (BIT(tx_offset) << 16);
+			val <<= 32;
+			val |= (BIT(rx_offset) << 16);
+			addr = cru_reset + (rx_bank * 4);
+		}
+
+		if (IS_ALIGNED((uintptr_t)addr, 8)) {
+			writeq(val, addr);
+			break;
+		}
+		fallthrough;
+	default:
+		local_irq_save(flags);
+		writel((BIT(tx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+		writel((BIT(rx_offset) << 16),
+		       cru_reset + (rx_bank * 4));
+		local_irq_restore(flags);
+		break;
+	}
+}
+
+/*
+ * Makes sure that both tx and rx are reset at the same time to sync lrck
+ * when clk_trcm > 0.
+ */
+static void rockchip_snd_xfer_sync_reset(struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int tx_id, rx_id;
+	int tx_bank, rx_bank, tx_offset, rx_offset;
+
+	if (!i2s_tdm->cru_base || !i2s_tdm->soc_data)
+		return;
+
+	tx_id = i2s_tdm->tx_reset_id;
+	rx_id = i2s_tdm->rx_reset_id;
+	if (tx_id < 0 || rx_id < 0)
+		return;
+
+	tx_bank = tx_id / 16;
+	tx_offset = tx_id % 16;
+	rx_bank = rx_id / 16;
+	rx_offset = rx_id % 16;
+	dev_dbg(i2s_tdm->dev,
+		"tx_bank: %d, rx_bank: %d, tx_offset: %d, rx_offset: %d\n",
+		tx_bank, rx_bank, tx_offset, rx_offset);
+
+	rockchip_snd_xfer_reset_assert(i2s_tdm, tx_bank, tx_offset,
+				       rx_bank, rx_offset);
+
+	udelay(150);
+
+	rockchip_snd_xfer_reset_deassert(i2s_tdm, tx_bank, tx_offset,
+					 rx_bank, rx_offset);
+}
+
+static void rockchip_snd_reset(struct reset_control *rc)
+{
+	if (IS_ERR(rc))
+		return;
+
+	reset_control_assert(rc);
+	udelay(1);
+	reset_control_deassert(rc);
+}
+
+static void rockchip_snd_xfer_clear(struct rk_i2s_tdm_dev *i2s_tdm,
+				    unsigned int clr)
+{
+	unsigned int xfer_mask;
+	unsigned int xfer_val;
+	unsigned int val;
+	int retry = 10;
+	bool tx = clr & I2S_CLR_TXC;
+	bool rx = clr & I2S_CLR_RXC;
+
+	if (!(rx || tx))
+		return;
+
+	xfer_mask = (tx ? I2S_XFER_TXS_START : 0) |
+		    (rx ? I2S_XFER_RXS_START : 0);
+	xfer_val = (tx ? I2S_XFER_TXS_STOP : 0) |
+		   (rx ? I2S_XFER_RXS_STOP : 0);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_XFER, xfer_mask, xfer_val);
+	udelay(150);
+	regmap_update_bits(i2s_tdm->regmap, I2S_CLR, clr, clr);
+
+	regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
+	/* Wait on the clear operation to finish */
+	while (val) {
+		regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
+		retry--;
+		if (!retry) {
+			dev_warn(i2s_tdm->dev, "clear failed, reset %s%s\n",
+				 tx ? "tx" : "", rx ? "rx" : "");
+			if (rx && tx)
+				rockchip_snd_xfer_sync_reset(i2s_tdm);
+			else if (tx)
+				rockchip_snd_reset(i2s_tdm->tx_reset);
+			else if (rx)
+				rockchip_snd_reset(i2s_tdm->rx_reset);
+			break;
+		}
+	}
+}
+
+/* only used when clk_trcm > 0 */
+static void rockchip_snd_txrxctrl(struct snd_pcm_substream *substream,
+				  struct snd_soc_dai *dai, int on)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	spin_lock(&i2s_tdm->lock);
+	if (on) {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_TDE_ENABLE,
+					   I2S_DMACR_TDE_ENABLE);
+		else
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_RDE_ENABLE,
+					   I2S_DMACR_RDE_ENABLE);
+
+		if (atomic_inc_return(&i2s_tdm->refcount) == 1) {
+			rockchip_snd_xfer_sync_reset(i2s_tdm);
+			regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+					   I2S_XFER_TXS_START |
+					   I2S_XFER_RXS_START,
+					   I2S_XFER_TXS_START |
+					   I2S_XFER_RXS_START);
+		}
+	} else {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_TDE_ENABLE,
+					   I2S_DMACR_TDE_DISABLE);
+		else
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_RDE_ENABLE,
+					   I2S_DMACR_RDE_DISABLE);
+
+		if (atomic_dec_and_test(&i2s_tdm->refcount)) {
+			rockchip_snd_xfer_clear(i2s_tdm,
+						I2S_CLR_TXC | I2S_CLR_RXC);
+
+		}
+	}
+	spin_unlock(&i2s_tdm->lock);
+}
+
+static void rockchip_snd_txctrl(struct rk_i2s_tdm_dev *i2s_tdm, int on)
+{
+
+	if (on) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
+
+		regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+				   I2S_XFER_TXS_START,
+				   I2S_XFER_TXS_START);
+	} else {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
+
+		rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_TXC);
+	}
+}
+
+static void rockchip_snd_rxctrl(struct rk_i2s_tdm_dev *i2s_tdm, int on)
+{
+	if (on) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
+
+		regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+				   I2S_XFER_RXS_START,
+				   I2S_XFER_RXS_START);
+	} else {
+		rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_RXC);
+	}
+}
+
+static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
+				    unsigned int fmt)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
+	unsigned int mask = 0, val = 0, tdm_val = 0, txcr_val = 0, rxcr_val = 0;
+	int ret = 0;
+	bool is_tdm = i2s_tdm->tdm_mode;
+
+	pm_runtime_get_sync(cpu_dai->dev);
+	mask = I2S_CKR_MSS_MASK;
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		val = I2S_CKR_MSS_MASTER;
+		i2s_tdm->is_master_mode = true;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		val = I2S_CKR_MSS_SLAVE;
+		i2s_tdm->is_master_mode = false;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val);
+
+	mask = I2S_CKR_CKP_MASK | I2S_CKR_TLP_MASK | I2S_CKR_RLP_MASK;
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		val = I2S_CKR_CKP_NORMAL |
+		      I2S_CKR_TLP_NORMAL |
+		      I2S_CKR_RLP_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		val = I2S_CKR_CKP_NORMAL |
+		      I2S_CKR_TLP_INVERTED |
+		      I2S_CKR_RLP_INVERTED;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		val = I2S_CKR_CKP_INVERTED |
+		      I2S_CKR_TLP_NORMAL |
+		      I2S_CKR_RLP_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		val = I2S_CKR_CKP_INVERTED |
+		      I2S_CKR_TLP_INVERTED |
+		      I2S_CKR_RLP_INVERTED;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_RIGHT_J:
+		txcr_val = I2S_TXCR_IBM_RSJM;
+		rxcr_val = I2S_RXCR_IBM_RSJM;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		txcr_val = I2S_TXCR_IBM_LSJM;
+		rxcr_val = I2S_RXCR_IBM_LSJM;
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		txcr_val = I2S_TXCR_IBM_NORMAL;
+		rxcr_val = I2S_RXCR_IBM_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */
+		txcr_val = I2S_TXCR_TFS_PCM;
+		rxcr_val = I2S_RXCR_TFS_PCM;
+		break;
+	case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */
+		txcr_val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);
+		rxcr_val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	mask = I2S_TXCR_IBM_MASK | I2S_TXCR_TFS_MASK | I2S_TXCR_PBM_MASK;
+	regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, txcr_val);
+
+	mask = I2S_RXCR_IBM_MASK | I2S_RXCR_TFS_MASK | I2S_RXCR_PBM_MASK;
+	regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, rxcr_val);
+
+	if (is_tdm) {
+		switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+		case SND_SOC_DAIFMT_RIGHT_J:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(2);
+			break;
+		case SND_SOC_DAIFMT_LEFT_J:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(1);
+			break;
+		case SND_SOC_DAIFMT_I2S:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(0);
+			break;
+		case SND_SOC_DAIFMT_DSP_A:
+			val = I2S_TXCR_TFS_TDM_PCM;
+			tdm_val = TDM_SHIFT_CTRL(0);
+			break;
+		case SND_SOC_DAIFMT_DSP_B:
+			val = I2S_TXCR_TFS_TDM_PCM;
+			tdm_val = TDM_SHIFT_CTRL(2);
+			break;
+		default:
+			ret = -EINVAL;
+			goto err_pm_put;
+		}
+
+		tdm_val |= TDM_FSYNC_WIDTH_SEL1(1);
+		if (i2s_tdm->tdm_fsync_half_frame)
+			tdm_val |= TDM_FSYNC_WIDTH_HALF_FRAME;
+		else
+			tdm_val |= TDM_FSYNC_WIDTH_ONE_FRAME;
+
+		mask = I2S_TXCR_TFS_MASK;
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, val);
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, val);
+
+		mask = TDM_FSYNC_WIDTH_SEL1_MSK | TDM_FSYNC_WIDTH_SEL0_MSK |
+		       TDM_SHIFT_CTRL_MSK;
+		regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR,
+				   mask, tdm_val);
+		regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR,
+				   mask, tdm_val);
+	}
+
+err_pm_put:
+	pm_runtime_put(cpu_dai->dev);
+
+	return ret;
+}
+
+static void rockchip_i2s_tdm_xfer_pause(struct snd_pcm_substream *substream,
+					struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int stream;
+
+	stream = SNDRV_PCM_STREAM_LAST - substream->stream;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE,
+				   I2S_DMACR_TDE_DISABLE);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE,
+				   I2S_DMACR_RDE_DISABLE);
+
+	rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_TXC | I2S_CLR_RXC);
+}
+
+static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream *substream,
+					 struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int stream;
+
+	stream = SNDRV_PCM_STREAM_LAST - substream->stream;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE,
+				   I2S_DMACR_TDE_ENABLE);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE,
+				   I2S_DMACR_RDE_ENABLE);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+			   I2S_XFER_TXS_START |
+			   I2S_XFER_RXS_START,
+			   I2S_XFER_TXS_START |
+			   I2S_XFER_RXS_START);
+}
+
+static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm,
+					 struct clk *clk, unsigned long rate,
+					 int ppm)
+{
+	unsigned long rate_target;
+	int delta, ret;
+
+	if (ppm == i2s_tdm->clk_ppm)
+		return 0;
+
+	delta = (ppm < 0) ? -1 : 1;
+	delta *= (int) div64_u64((uint64_t) rate * (uint64_t) abs(ppm) + 500000,
+				 1000000);
+
+	rate_target = rate + delta;
+
+	if (!rate_target)
+		return -EINVAL;
+
+	ret = clk_set_rate(clk, rate_target);
+	if (ret)
+		return ret;
+
+	i2s_tdm->clk_ppm = ppm;
+
+	return ret;
+}
+
+static int rockchip_i2s_tdm_calibrate_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
+					   struct snd_pcm_substream *substream,
+					   unsigned int lrck_freq)
+{
+	struct clk *mclk_root;
+	struct clk *mclk_parent;
+	unsigned int mclk_root_freq;
+	unsigned int mclk_root_initial_freq;
+	unsigned int mclk_parent_freq;
+	unsigned int div, delta;
+	uint64_t ppm;
+	int ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		mclk_parent = i2s_tdm->mclk_tx_src;
+	else
+		mclk_parent = i2s_tdm->mclk_rx_src;
+
+	switch (lrck_freq) {
+	case 8000:
+	case 16000:
+	case 24000:
+	case 32000:
+	case 48000:
+	case 64000:
+	case 96000:
+	case 192000:
+		mclk_root = i2s_tdm->mclk_root0;
+		mclk_root_freq = i2s_tdm->mclk_root0_freq;
+		mclk_root_initial_freq = i2s_tdm->mclk_root0_initial_freq;
+		mclk_parent_freq = DEFAULT_MCLK_FS * 192000;
+		break;
+	case 11025:
+	case 22050:
+	case 44100:
+	case 88200:
+	case 176400:
+		mclk_root = i2s_tdm->mclk_root1;
+		mclk_root_freq = i2s_tdm->mclk_root1_freq;
+		mclk_root_initial_freq = i2s_tdm->mclk_root1_initial_freq;
+		mclk_parent_freq = DEFAULT_MCLK_FS * 176400;
+		break;
+	default:
+		dev_err(i2s_tdm->dev, "Invalid LRCK freq: %u Hz\n",
+			lrck_freq);
+		return -EINVAL;
+	}
+
+	ret = clk_set_parent(mclk_parent, mclk_root);
+	if (ret)
+		return ret;
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, mclk_root,
+					    mclk_root_freq, 0);
+	if (ret)
+		return ret;
+
+	delta = abs(mclk_root_freq % mclk_parent_freq - mclk_parent_freq);
+	ppm = div64_u64((uint64_t)delta * 1000000, (uint64_t)mclk_root_freq);
+
+	if (ppm) {
+		div = DIV_ROUND_CLOSEST(mclk_root_initial_freq, mclk_parent_freq);
+		if (!div)
+			return -EINVAL;
+
+		mclk_root_freq = mclk_parent_freq * round_up(div, 2);
+
+		ret = clk_set_rate(mclk_root, mclk_root_freq);
+		if (ret)
+			return ret;
+
+		i2s_tdm->mclk_root0_freq = clk_get_rate(i2s_tdm->mclk_root0);
+		i2s_tdm->mclk_root1_freq = clk_get_rate(i2s_tdm->mclk_root1);
+	}
+
+	ret = clk_set_rate(mclk_parent, mclk_parent_freq);
+
+	return ret;
+}
+
+static int rockchip_i2s_tdm_set_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
+				     struct snd_pcm_substream *substream,
+				     struct clk **mclk)
+{
+	unsigned int mclk_freq;
+	int ret;
+
+	if (i2s_tdm->clk_trcm) {
+		if (i2s_tdm->mclk_tx_freq != i2s_tdm->mclk_rx_freq) {
+			dev_err(i2s_tdm->dev,
+				"clk_trcm, tx: %d and rx: %d should be same\n",
+				i2s_tdm->mclk_tx_freq,
+				i2s_tdm->mclk_rx_freq);
+			ret = -EINVAL;
+			return ret;
+		}
+
+		ret = clk_set_rate(i2s_tdm->mclk_tx, i2s_tdm->mclk_tx_freq);
+		if (ret)
+			return ret;
+
+		ret = clk_set_rate(i2s_tdm->mclk_rx, i2s_tdm->mclk_rx_freq);
+		if (ret)
+			return ret;
+
+		/* mclk_rx is also ok. */
+		*mclk = i2s_tdm->mclk_tx;
+	} else {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			*mclk = i2s_tdm->mclk_tx;
+			mclk_freq = i2s_tdm->mclk_tx_freq;
+		} else {
+			*mclk = i2s_tdm->mclk_rx;
+			mclk_freq = i2s_tdm->mclk_rx_freq;
+		}
+
+		ret = clk_set_rate(*mclk, mclk_freq);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_i2s_io_multiplex(struct snd_pcm_substream *substream,
+				     struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+	int usable_chs = MULTIPLEX_CH_MAX;
+	unsigned int val = 0;
+
+	if (!i2s_tdm->io_multiplex)
+		return 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		struct snd_pcm_str *playback_str =
+			&substream->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
+
+		if (playback_str->substream_opened) {
+			regmap_read(i2s_tdm->regmap, I2S_TXCR, &val);
+			val &= I2S_TXCR_CSR_MASK;
+			usable_chs = MULTIPLEX_CH_MAX - to_ch_num(val);
+		}
+
+		regmap_read(i2s_tdm->regmap, I2S_RXCR, &val);
+		val &= I2S_RXCR_CSR_MASK;
+
+		if (to_ch_num(val) > usable_chs) {
+			dev_err(i2s_tdm->dev,
+				"Capture chs(%d) > usable chs(%d)\n",
+				to_ch_num(val), usable_chs);
+			return -EINVAL;
+		}
+
+		switch (val) {
+		case I2S_CHN_4:
+			val = I2S_IO_6CH_OUT_4CH_IN;
+			break;
+		case I2S_CHN_6:
+			val = I2S_IO_4CH_OUT_6CH_IN;
+			break;
+		case I2S_CHN_8:
+			val = I2S_IO_2CH_OUT_8CH_IN;
+			break;
+		default:
+			val = I2S_IO_8CH_OUT_2CH_IN;
+			break;
+		}
+	} else {
+		struct snd_pcm_str *capture_str =
+			&substream->pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
+
+		if (capture_str->substream_opened) {
+			regmap_read(i2s_tdm->regmap, I2S_RXCR, &val);
+			val &= I2S_RXCR_CSR_MASK;
+			usable_chs = MULTIPLEX_CH_MAX - to_ch_num(val);
+		}
+
+		regmap_read(i2s_tdm->regmap, I2S_TXCR, &val);
+		val &= I2S_TXCR_CSR_MASK;
+
+		if (to_ch_num(val) > usable_chs) {
+			dev_err(i2s_tdm->dev,
+				"Playback chs(%d) > usable chs(%d)\n",
+				to_ch_num(val), usable_chs);
+			return -EINVAL;
+		}
+
+		switch (val) {
+		case I2S_CHN_4:
+			val = I2S_IO_4CH_OUT_6CH_IN;
+			break;
+		case I2S_CHN_6:
+			val = I2S_IO_6CH_OUT_4CH_IN;
+			break;
+		case I2S_CHN_8:
+			val = I2S_IO_8CH_OUT_2CH_IN;
+			break;
+		default:
+			val = I2S_IO_2CH_OUT_8CH_IN;
+			break;
+		}
+	}
+
+	val <<= i2s_tdm->soc_data->grf_shift;
+	val |= (I2S_IO_DIRECTION_MASK << i2s_tdm->soc_data->grf_shift) << 16;
+	regmap_write(i2s_tdm->grf, i2s_tdm->soc_data->grf_reg_offset, val);
+
+	return 0;
+}
+
+static int rockchip_i2s_trcm_mode(struct snd_pcm_substream *substream,
+				  struct snd_soc_dai *dai,
+				  unsigned int div_bclk,
+				  unsigned int div_lrck,
+				  unsigned int fmt)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	if (!i2s_tdm->clk_trcm)
+		return 0;
+
+	spin_lock(&i2s_tdm->lock);
+	if (atomic_read(&i2s_tdm->refcount))
+		rockchip_i2s_tdm_xfer_pause(substream, i2s_tdm);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+			   I2S_CLKDIV_TXM_MASK | I2S_CLKDIV_RXM_MASK,
+			   I2S_CLKDIV_TXM(div_bclk) | I2S_CLKDIV_RXM(div_bclk));
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+			   I2S_CKR_TSD_MASK | I2S_CKR_RSD_MASK,
+			   I2S_CKR_TSD(div_lrck) | I2S_CKR_RSD(div_lrck));
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
+				   fmt);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
+				   fmt);
+
+	if (atomic_read(&i2s_tdm->refcount))
+		rockchip_i2s_tdm_xfer_resume(substream, i2s_tdm);
+	spin_unlock(&i2s_tdm->lock);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params,
+				      struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+	struct clk *mclk;
+	int ret = 0;
+	unsigned int val = 0;
+	unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64;
+
+	if (i2s_tdm->is_master_mode) {
+		if (i2s_tdm->mclk_calibrate)
+			rockchip_i2s_tdm_calibrate_mclk(i2s_tdm, substream,
+							params_rate(params));
+
+		ret = rockchip_i2s_tdm_set_mclk(i2s_tdm, substream, &mclk);
+		if (ret)
+			return ret;
+
+		mclk_rate = clk_get_rate(mclk);
+		bclk_rate = i2s_tdm->frame_width * params_rate(params);
+		if (!bclk_rate)
+			return -EINVAL;
+
+		div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
+		div_lrck = bclk_rate / params_rate(params);
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S8:
+		val |= I2S_TXCR_VDW(8);
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+		val |= I2S_TXCR_VDW(16);
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		val |= I2S_TXCR_VDW(20);
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		val |= I2S_TXCR_VDW(24);
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		val |= I2S_TXCR_VDW(32);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (params_channels(params)) {
+	case 8:
+		val |= I2S_CHN_8;
+		break;
+	case 6:
+		val |= I2S_CHN_6;
+		break;
+	case 4:
+		val |= I2S_CHN_4;
+		break;
+	case 2:
+		val |= I2S_CHN_2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (i2s_tdm->clk_trcm) {
+		rockchip_i2s_trcm_mode(substream, dai, div_bclk, div_lrck, val);
+	} else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+				   I2S_CLKDIV_TXM_MASK,
+				   I2S_CLKDIV_TXM(div_bclk));
+		regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+				   I2S_CKR_TSD_MASK,
+				   I2S_CKR_TSD(div_lrck));
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
+				   val);
+	} else {
+		regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+				   I2S_CLKDIV_RXM_MASK,
+				   I2S_CLKDIV_RXM(div_bclk));
+		regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+				   I2S_CKR_RSD_MASK,
+				   I2S_CKR_RSD(div_lrck));
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
+				   val);
+	}
+
+	return rockchip_i2s_io_multiplex(substream, dai);
+}
+
+static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream,
+				    int cmd, struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (i2s_tdm->clk_trcm)
+			rockchip_snd_txrxctrl(substream, dai, 1);
+		else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			rockchip_snd_rxctrl(i2s_tdm, 1);
+		else
+			rockchip_snd_txctrl(i2s_tdm, 1);
+		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (i2s_tdm->clk_trcm)
+			rockchip_snd_txrxctrl(substream, dai, 0);
+		else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			rockchip_snd_rxctrl(i2s_tdm, 0);
+		else
+			rockchip_snd_txctrl(i2s_tdm, 0);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream,
+				       unsigned int freq, int dir)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
+
+	/* Put set mclk rate into rockchip_i2s_tdm_set_mclk() */
+	if (i2s_tdm->clk_trcm) {
+		i2s_tdm->mclk_tx_freq = freq;
+		i2s_tdm->mclk_rx_freq = freq;
+	} else {
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			i2s_tdm->mclk_tx_freq = freq;
+		else
+			i2s_tdm->mclk_rx_freq = freq;
+	}
+
+	dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n",
+		stream ? "rx" : "tx", freq);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
+						  struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = CLK_PPM_MIN;
+	uinfo->value.integer.max = CLK_PPM_MAX;
+	uinfo->value.integer.step = 1;
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
+						 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+
+	ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm;
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
+						 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+	int ret = 0, ppm = 0;
+
+	if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
+	    (ucontrol->value.integer.value[0] > CLK_PPM_MAX))
+		return -EINVAL;
+
+	ppm = ucontrol->value.integer.value[0];
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root0,
+					    i2s_tdm->mclk_root0_freq, ppm);
+	if (ret)
+		return ret;
+
+	if (clk_is_match(i2s_tdm->mclk_root0, i2s_tdm->mclk_root1))
+		return 0;
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root1,
+					    i2s_tdm->mclk_root1_freq, ppm);
+
+	return ret;
+}
+
+static struct snd_kcontrol_new rockchip_i2s_tdm_compensation_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+	.name = "PCM Clk Compensation In PPM",
+	.info = rockchip_i2s_tdm_clk_compensation_info,
+	.get = rockchip_i2s_tdm_clk_compensation_get,
+	.put = rockchip_i2s_tdm_clk_compensation_put,
+};
+
+static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+
+	dai->capture_dma_data = &i2s_tdm->capture_dma_data;
+	dai->playback_dma_data = &i2s_tdm->playback_dma_data;
+
+	if (i2s_tdm->mclk_calibrate)
+		snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1);
+
+	return 0;
+}
+
+static int rockchip_dai_tdm_slot(struct snd_soc_dai *dai,
+				 unsigned int tx_mask, unsigned int rx_mask,
+				 int slots, int slot_width)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+	unsigned int mask, val;
+
+	i2s_tdm->tdm_mode = true;
+	i2s_tdm->frame_width = slots * slot_width;
+	mask = TDM_SLOT_BIT_WIDTH_MSK | TDM_FRAME_WIDTH_MSK;
+	val = TDM_SLOT_BIT_WIDTH(slot_width) |
+	      TDM_FRAME_WIDTH(slots * slot_width);
+	regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR,
+			   mask, val);
+	regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR,
+			   mask, val);
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = {
+	.hw_params = rockchip_i2s_tdm_hw_params,
+	.set_sysclk = rockchip_i2s_tdm_set_sysclk,
+	.set_fmt = rockchip_i2s_tdm_set_fmt,
+	.set_tdm_slot = rockchip_dai_tdm_slot,
+	.trigger = rockchip_i2s_tdm_trigger,
+};
+
+static const struct snd_soc_component_driver rockchip_i2s_tdm_component = {
+	.name = DRV_NAME,
+};
+
+static bool rockchip_i2s_tdm_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXCR:
+	case I2S_RXCR:
+	case I2S_CKR:
+	case I2S_DMACR:
+	case I2S_INTCR:
+	case I2S_XFER:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_TDM_TXCR:
+	case I2S_TDM_RXCR:
+	case I2S_CLKDIV:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXCR:
+	case I2S_RXCR:
+	case I2S_CKR:
+	case I2S_DMACR:
+	case I2S_INTCR:
+	case I2S_XFER:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_RXDR:
+	case I2S_TXFIFOLR:
+	case I2S_INTSR:
+	case I2S_RXFIFOLR:
+	case I2S_TDM_TXCR:
+	case I2S_TDM_RXCR:
+	case I2S_CLKDIV:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXFIFOLR:
+	case I2S_INTSR:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_RXDR:
+	case I2S_RXFIFOLR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_precious_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_RXDR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct reg_default rockchip_i2s_tdm_reg_defaults[] = {
+	{0x00, 0x7200000f},
+	{0x04, 0x01c8000f},
+	{0x08, 0x00001f1f},
+	{0x10, 0x001f0000},
+	{0x14, 0x01f00000},
+	{0x30, 0x00003eff},
+	{0x34, 0x00003eff},
+	{0x38, 0x00000707},
+};
+
+static const struct regmap_config rockchip_i2s_tdm_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = I2S_CLKDIV,
+	.reg_defaults = rockchip_i2s_tdm_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(rockchip_i2s_tdm_reg_defaults),
+	.writeable_reg = rockchip_i2s_tdm_wr_reg,
+	.readable_reg = rockchip_i2s_tdm_rd_reg,
+	.volatile_reg = rockchip_i2s_tdm_volatile_reg,
+	.precious_reg = rockchip_i2s_tdm_precious_reg,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static int common_soc_init(struct device *dev, u32 addr)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	const struct txrx_config *configs = i2s_tdm->soc_data->configs;
+	u32 reg = 0, val = 0, trcm = i2s_tdm->clk_trcm;
+	int i;
+
+	if (trcm == RK_TRCM_TXRX)
+		return 0;
+
+	for (i = 0; i < i2s_tdm->soc_data->config_count; i++) {
+		if (addr != configs[i].addr)
+			continue;
+		reg = configs[i].reg;
+		if (trcm == RK_TRCM_TX)
+			val = configs[i].txonly;
+		else
+			val = configs[i].rxonly;
+
+		if (reg)
+			regmap_write(i2s_tdm->grf, reg, val);
+	}
+
+	return 0;
+}
+
+static const struct txrx_config px30_txrx_config[] = {
+	{ 0xff060000, 0x184, PX30_I2S0_CLK_TXONLY, PX30_I2S0_CLK_RXONLY },
+};
+
+static const struct txrx_config rk1808_txrx_config[] = {
+	{ 0xff7e0000, 0x190, RK1808_I2S0_CLK_TXONLY, RK1808_I2S0_CLK_RXONLY },
+};
+
+static const struct txrx_config rk3308_txrx_config[] = {
+	{ 0xff300000, 0x308, RK3308_I2S0_CLK_TXONLY, RK3308_I2S0_CLK_RXONLY },
+	{ 0xff310000, 0x308, RK3308_I2S1_CLK_TXONLY, RK3308_I2S1_CLK_RXONLY },
+};
+
+static const struct txrx_config rk3568_txrx_config[] = {
+	{ 0xfe410000, 0x504, RK3568_I2S1_CLK_TXONLY, RK3568_I2S1_CLK_RXONLY },
+	{ 0xfe410000, 0x508, RK3568_I2S1_MCLK_TX_OE, RK3568_I2S1_MCLK_RX_OE },
+	{ 0xfe420000, 0x508, RK3568_I2S2_MCLK_OE, RK3568_I2S2_MCLK_OE },
+	{ 0xfe430000, 0x504, RK3568_I2S3_CLK_TXONLY, RK3568_I2S3_CLK_RXONLY },
+	{ 0xfe430000, 0x508, RK3568_I2S3_MCLK_TXONLY, RK3568_I2S3_MCLK_RXONLY },
+	{ 0xfe430000, 0x508, RK3568_I2S3_MCLK_OE, RK3568_I2S3_MCLK_OE },
+};
+
+static const struct txrx_config rv1126_txrx_config[] = {
+	{ 0xff800000, 0x10260, RV1126_I2S0_CLK_TXONLY, RV1126_I2S0_CLK_RXONLY },
+};
+
+static struct rk_i2s_soc_data px30_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = px30_txrx_config,
+	.config_count = ARRAY_SIZE(px30_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk1808_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = rk1808_txrx_config,
+	.config_count = ARRAY_SIZE(rk1808_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk3308_i2s_soc_data = {
+	.softrst_offset = 0x0400,
+	.grf_reg_offset = 0x0308,
+	.grf_shift = 5,
+	.configs = rk3308_txrx_config,
+	.config_count = ARRAY_SIZE(rk3308_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk3568_i2s_soc_data = {
+	.softrst_offset = 0x0400,
+	.configs = rk3568_txrx_config,
+	.config_count = ARRAY_SIZE(rk3568_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rv1126_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = rv1126_txrx_config,
+	.config_count = ARRAY_SIZE(rv1126_txrx_config),
+	.init = common_soc_init,
+};
+
+static const struct of_device_id rockchip_i2s_tdm_match[] = {
+	{ .compatible = "rockchip,px30-i2s-tdm", .data = &px30_i2s_soc_data },
+	{ .compatible = "rockchip,rk1808-i2s-tdm", .data = &rk1808_i2s_soc_data },
+	{ .compatible = "rockchip,rk3308-i2s-tdm", .data = &rk3308_i2s_soc_data },
+	{ .compatible = "rockchip,rk3568-i2s-tdm", .data = &rk3568_i2s_soc_data },
+	{ .compatible = "rockchip,rv1126-i2s-tdm", .data = &rv1126_i2s_soc_data },
+	{},
+};
+
+static int of_i2s_resetid_get(struct device_node *node,
+			      const char *id)
+{
+	struct of_phandle_args args;
+	int index = 0;
+	int ret;
+
+	if (id)
+		index = of_property_match_string(node,
+						 "reset-names", id);
+	ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
+					 index, &args);
+	if (ret)
+		return ret;
+
+	return args.args[0];
+}
+
+static struct snd_soc_dai_driver i2s_tdm_dai = {
+	.probe = rockchip_i2s_tdm_dai_probe,
+	.playback = {
+		.stream_name  = "Playback",
+		.channels_min = 2,
+		.channels_max = 8,
+		.rates        = SNDRV_PCM_RATE_8000_192000,
+		.formats      = (SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S20_3LE |
+				SNDRV_PCM_FMTBIT_S24_LE |
+				SNDRV_PCM_FMTBIT_S32_LE),
+	},
+	.capture = {
+		.stream_name  = "Capture",
+		.channels_min = 2,
+		.channels_max = 8,
+		.rates        = SNDRV_PCM_RATE_8000_192000,
+		.formats      = (SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S20_3LE |
+				SNDRV_PCM_FMTBIT_S24_LE |
+				SNDRV_PCM_FMTBIT_S32_LE),
+	},
+	.ops = &rockchip_i2s_tdm_dai_ops,
+};
+
+static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev *i2s_tdm,
+				       int num,
+				       bool is_rx_path)
+{
+	unsigned int *i2s_data;
+	int i, j;
+
+	if (is_rx_path)
+		i2s_data = i2s_tdm->i2s_sdis;
+	else
+		i2s_data = i2s_tdm->i2s_sdos;
+
+	for (i = 0; i < num; i++) {
+		if (i2s_data[i] > CH_GRP_MAX - 1) {
+			dev_err(i2s_tdm->dev,
+				"%s path i2s_data[%d]: %d is overflow, max is: %d\n",
+				is_rx_path ? "RX" : "TX",
+				i, i2s_data[i], CH_GRP_MAX);
+			return -EINVAL;
+		}
+
+		for (j = 0; j < num; j++) {
+			if (i == j)
+				continue;
+
+			if (i2s_data[i] == i2s_data[j]) {
+				dev_err(i2s_tdm->dev,
+					"%s path invalid routed i2s_data: [%d]%d == [%d]%d\n",
+					is_rx_path ? "RX" : "TX",
+					i, i2s_data[i],
+					j, i2s_data[j]);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void rockchip_i2s_tdm_tx_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					    int num)
+{
+	int idx;
+
+	for (idx = 0; idx < num; idx++) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_PATH_MASK(idx),
+				   I2S_TXCR_PATH(idx, i2s_tdm->i2s_sdos[idx]));
+	}
+}
+
+static void rockchip_i2s_tdm_rx_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					    int num)
+{
+	int idx;
+
+	for (idx = 0; idx < num; idx++) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_PATH_MASK(idx),
+				   I2S_RXCR_PATH(idx, i2s_tdm->i2s_sdis[idx]));
+	}
+}
+
+static void rockchip_i2s_tdm_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					 int num, bool is_rx_path)
+{
+	if (is_rx_path)
+		rockchip_i2s_tdm_rx_path_config(i2s_tdm, num);
+	else
+		rockchip_i2s_tdm_tx_path_config(i2s_tdm, num);
+}
+
+static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					 struct device_node *np,
+					 bool is_rx_path)
+{
+	char *i2s_tx_path_prop = "rockchip,i2s-tx-route";
+	char *i2s_rx_path_prop = "rockchip,i2s-rx-route";
+	char *i2s_path_prop;
+	unsigned int *i2s_data;
+	int num, ret = 0;
+
+	if (is_rx_path) {
+		i2s_path_prop = i2s_rx_path_prop;
+		i2s_data = i2s_tdm->i2s_sdis;
+	} else {
+		i2s_path_prop = i2s_tx_path_prop;
+		i2s_data = i2s_tdm->i2s_sdos;
+	}
+
+	num = of_count_phandle_with_args(np, i2s_path_prop, NULL);
+	if (num < 0) {
+		if (num != -ENOENT) {
+			dev_err(i2s_tdm->dev,
+				"Failed to read '%s' num: %d\n",
+				i2s_path_prop, num);
+			ret = num;
+		}
+		return ret;
+	} else if (num != CH_GRP_MAX) {
+		dev_err(i2s_tdm->dev,
+			"The num: %d should be: %d\n", num, CH_GRP_MAX);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_array(np, i2s_path_prop,
+					 i2s_data, num);
+	if (ret < 0) {
+		dev_err(i2s_tdm->dev,
+			"Failed to read '%s': %d\n",
+			i2s_path_prop, ret);
+		return ret;
+	}
+
+	ret = rockchip_i2s_tdm_path_check(i2s_tdm, num, is_rx_path);
+	if (ret < 0) {
+		dev_err(i2s_tdm->dev,
+			"Failed to check i2s data bus: %d\n", ret);
+		return ret;
+	}
+
+	rockchip_i2s_tdm_path_config(i2s_tdm, num, is_rx_path);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_tx_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					    struct device_node *np)
+{
+	return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 0);
+}
+
+static int rockchip_i2s_tdm_rx_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					    struct device_node *np)
+{
+	return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 1);
+}
+
+static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *cru_node;
+	const struct of_device_id *of_id;
+	struct rk_i2s_tdm_dev *i2s_tdm;
+	struct resource *res;
+	void __iomem *regs;
+	int ret;
+	int val;
+
+	i2s_tdm = devm_kzalloc(&pdev->dev, sizeof(*i2s_tdm), GFP_KERNEL);
+	if (!i2s_tdm)
+		return -ENOMEM;
+
+	i2s_tdm->dev = &pdev->dev;
+
+	of_id = of_match_device(rockchip_i2s_tdm_match, &pdev->dev);
+	if (!of_id || !of_id->data)
+		return -EINVAL;
+
+	spin_lock_init(&i2s_tdm->lock);
+	i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data;
+
+	i2s_tdm->frame_width = 64;
+	if (!of_property_read_u32(node, "rockchip,frame-width", &val)) {
+		if ((val >= 32) && (val % 2 == 0) && (val <= 512)) {
+			i2s_tdm->frame_width = val;
+		} else {
+			dev_err(i2s_tdm->dev, "unsupported frame width: '%d'\n",
+				val);
+			return -EINVAL;
+		}
+	}
+
+	if (!of_property_read_u32(node, "rockchip,trcm-sync", &val)) {
+		switch (val) {
+		case RK_TRCM_TX:
+		case RK_TRCM_RX:
+			i2s_tdm_dai.symmetric_rate = 1;
+			fallthrough;
+		case RK_TRCM_TXRX:
+			i2s_tdm->clk_trcm = val;
+			break;
+		default:
+			dev_err(i2s_tdm->dev,
+				"unsupported trcm-sync mode: '%d'\n", val);
+			return -EINVAL;
+		}
+	} else {
+		dev_err(i2s_tdm->dev,
+			"Missing required property rockchip,trcm-sync\n");
+		return -ENOENT;
+	}
+
+	i2s_tdm->tdm_fsync_half_frame =
+		of_property_read_bool(node, "rockchip,tdm-fsync-half-frame");
+
+	if (of_property_read_bool(node, "rockchip,playback-only"))
+		i2s_tdm_dai.capture.channels_min = 0;
+	else if (of_property_read_bool(node, "rockchip,capture-only"))
+		i2s_tdm_dai.playback.channels_min = 0;
+
+	i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
+	if (IS_ERR(i2s_tdm->grf))
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->grf),
+				     "Error in rockchip,grf\n");
+
+	if (i2s_tdm->clk_trcm != RK_TRCM_TXRX) {
+		cru_node = of_parse_phandle(node, "rockchip,cru", 0);
+		i2s_tdm->cru_base = of_iomap(cru_node, 0);
+		of_node_put(cru_node);
+		if (!i2s_tdm->cru_base) {
+			dev_err(i2s_tdm->dev,
+				"Missing or unsupported rockchip,cru node\n");
+			return -ENOENT;
+		}
+
+		i2s_tdm->tx_reset_id = of_i2s_resetid_get(node, "tx-m");
+		i2s_tdm->rx_reset_id = of_i2s_resetid_get(node, "rx-m");
+	}
+
+	i2s_tdm->tx_reset = devm_reset_control_get(&pdev->dev, "tx-m");
+	if (IS_ERR(i2s_tdm->tx_reset)) {
+		ret = PTR_ERR(i2s_tdm->tx_reset);
+		if (ret != -ENOENT)
+			return dev_err_probe(i2s_tdm->dev, ret,
+					     "Error in tx-m reset control\n");
+	}
+
+	i2s_tdm->rx_reset = devm_reset_control_get(&pdev->dev, "rx-m");
+	if (IS_ERR(i2s_tdm->rx_reset)) {
+		ret = PTR_ERR(i2s_tdm->rx_reset);
+		if (ret != -ENOENT)
+			return dev_err_probe(i2s_tdm->dev, ret,
+					     "Error in rx-m reset control\n");
+	}
+
+	i2s_tdm->hclk = devm_clk_get(&pdev->dev, "hclk");
+	if (IS_ERR(i2s_tdm->hclk)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->hclk),
+				     "Failed to get clock hclk\n");
+	}
+
+	ret = clk_prepare_enable(i2s_tdm->hclk);
+	if (ret) {
+		return dev_err_probe(i2s_tdm->dev, ret,
+				     "Failed to enable clock hclk\n");
+	}
+
+	i2s_tdm->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx");
+	if (IS_ERR(i2s_tdm->mclk_tx)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->mclk_tx),
+				     "Failed to get clock mclk_tx\n");
+	}
+
+	i2s_tdm->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx");
+	if (IS_ERR(i2s_tdm->mclk_rx)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->mclk_rx),
+				     "Failed to get clock mclk_rx\n");
+	}
+
+	i2s_tdm->io_multiplex =
+		of_property_read_bool(node, "rockchip,io-multiplex");
+
+	i2s_tdm->mclk_calibrate =
+		of_property_read_bool(node, "rockchip,mclk-calibrate");
+	if (i2s_tdm->mclk_calibrate) {
+		i2s_tdm->mclk_tx_src = devm_clk_get(&pdev->dev, "mclk_tx_src");
+		if (IS_ERR(i2s_tdm->mclk_tx_src)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_tx_src),
+					     "Failed to get clock mclk_tx_src\n");
+		}
+		i2s_tdm->mclk_rx_src = devm_clk_get(&pdev->dev, "mclk_rx_src");
+		if (IS_ERR(i2s_tdm->mclk_rx_src)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_rx_src),
+					     "Failed to get clock mclk_rx_src\n");
+		}
+		i2s_tdm->mclk_root0 = devm_clk_get(&pdev->dev, "mclk_root0");
+		if (IS_ERR(i2s_tdm->mclk_root0)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_root0),
+					     "Failed to get clock mclk_root0\n");
+		}
+		i2s_tdm->mclk_root1 = devm_clk_get(&pdev->dev, "mclk_root1");
+		if (IS_ERR(i2s_tdm->mclk_root1)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_root1),
+					     "Failed to get clock mclk_root1\n");
+		}
+
+		i2s_tdm->mclk_root0_initial_freq = clk_get_rate(i2s_tdm->mclk_root0);
+		i2s_tdm->mclk_root1_initial_freq = clk_get_rate(i2s_tdm->mclk_root1);
+		i2s_tdm->mclk_root0_freq = i2s_tdm->mclk_root0_initial_freq;
+		i2s_tdm->mclk_root1_freq = i2s_tdm->mclk_root1_initial_freq;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(regs),
+				     "Failed to get resource IORESOURCE_MEM\n");
+	}
+
+	i2s_tdm->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+					    &rockchip_i2s_tdm_regmap_config);
+	if (IS_ERR(i2s_tdm->regmap)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->regmap),
+				     "Failed to initialise regmap\n");
+	}
+
+	i2s_tdm->playback_dma_data.addr = res->start + I2S_TXDR;
+	i2s_tdm->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	i2s_tdm->playback_dma_data.maxburst = 8;
+
+	i2s_tdm->capture_dma_data.addr = res->start + I2S_RXDR;
+	i2s_tdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	i2s_tdm->capture_dma_data.maxburst = 8;
+
+	ret = rockchip_i2s_tdm_tx_path_prepare(i2s_tdm, node);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "I2S TX path prepare failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_i2s_tdm_rx_path_prepare(i2s_tdm, node);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "I2S RX path prepare failed: %d\n", ret);
+		return ret;
+	}
+
+	atomic_set(&i2s_tdm->refcount, 0);
+	dev_set_drvdata(&pdev->dev, i2s_tdm);
+
+	pm_runtime_enable(&pdev->dev);
+	if (!pm_runtime_enabled(&pdev->dev)) {
+		ret = i2s_tdm_runtime_resume(&pdev->dev);
+		if (ret)
+			goto err_pm_disable;
+	}
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
+			   I2S_DMACR_TDL(16));
+	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
+			   I2S_DMACR_RDL(16));
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, I2S_CKR_TRCM_MASK,
+			   i2s_tdm->clk_trcm << I2S_CKR_TRCM_SHIFT);
+
+	if (i2s_tdm->soc_data && i2s_tdm->soc_data->init)
+		i2s_tdm->soc_data->init(&pdev->dev, res->start);
+
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &rockchip_i2s_tdm_component,
+					      &i2s_tdm_dai, 1);
+
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register DAI\n");
+		goto err_suspend;
+	}
+
+	if (of_property_read_bool(node, "rockchip,no-dmaengine"))
+		return ret;
+	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register PCM\n");
+		return ret;
+	}
+
+	return 0;
+
+err_suspend:
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		i2s_tdm_runtime_suspend(&pdev->dev);
+err_pm_disable:
+	pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int rockchip_i2s_tdm_remove(struct platform_device *pdev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		i2s_tdm_runtime_suspend(&pdev->dev);
+
+	if (!IS_ERR(i2s_tdm->mclk_tx))
+		clk_prepare_enable(i2s_tdm->mclk_tx);
+	if (!IS_ERR(i2s_tdm->mclk_rx))
+		clk_prepare_enable(i2s_tdm->mclk_rx);
+	if (!IS_ERR(i2s_tdm->hclk))
+		clk_disable_unprepare(i2s_tdm->hclk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_i2s_tdm_suspend(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+
+	regcache_mark_dirty(i2s_tdm->regmap);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_resume(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0)
+		return ret;
+	ret = regcache_sync(i2s_tdm->regmap);
+	pm_runtime_put(dev);
+
+	return ret;
+}
+#endif
+
+static const struct dev_pm_ops rockchip_i2s_tdm_pm_ops = {
+	SET_RUNTIME_PM_OPS(i2s_tdm_runtime_suspend, i2s_tdm_runtime_resume,
+			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend,
+				rockchip_i2s_tdm_resume)
+};
+
+static struct platform_driver rockchip_i2s_tdm_driver = {
+	.probe = rockchip_i2s_tdm_probe,
+	.remove = rockchip_i2s_tdm_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table = of_match_ptr(rockchip_i2s_tdm_match),
+		.pm = &rockchip_i2s_tdm_pm_ops,
+	},
+};
+module_platform_driver(rockchip_i2s_tdm_driver);
+
+MODULE_DESCRIPTION("ROCKCHIP I2S/TDM ASoC Interface");
+MODULE_AUTHOR("Sugar Zhang <sugar.zhang at rock-chips.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, rockchip_i2s_tdm_match);
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.h b/sound/soc/rockchip/rockchip_i2s_tdm.h
new file mode 100644
index 000000000000..fdc2bfc78c53
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.h
@@ -0,0 +1,400 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * sound/soc/rockchip/rockchip_i2s_tdm.h
+ *
+ * ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
+ *
+ * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
+ * Author: Sugar Zhang <sugar.zhang at rock-chips.com>
+ *
+ */
+
+#ifndef _ROCKCHIP_I2S_TDM_H
+#define _ROCKCHIP_I2S_TDM_H
+
+/*
+ * TXCR
+ * transmit operation control register
+ */
+#define I2S_TXCR_PATH_SHIFT(x)	(23 + (x) * 2)
+#define I2S_TXCR_PATH_MASK(x)	(0x3 << I2S_TXCR_PATH_SHIFT(x))
+#define I2S_TXCR_PATH(x, v)	((v) << I2S_TXCR_PATH_SHIFT(x))
+#define I2S_TXCR_RCNT_SHIFT	17
+#define I2S_TXCR_RCNT_MASK	(0x3f << I2S_TXCR_RCNT_SHIFT)
+#define I2S_TXCR_CSR_SHIFT	15
+#define I2S_TXCR_CSR(x)		(x << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_CSR_MASK	(3 << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_HWT		BIT(14)
+#define I2S_TXCR_SJM_SHIFT	12
+#define I2S_TXCR_SJM_R		(0 << I2S_TXCR_SJM_SHIFT)
+#define I2S_TXCR_SJM_L		(1 << I2S_TXCR_SJM_SHIFT)
+#define I2S_TXCR_FBM_SHIFT	11
+#define I2S_TXCR_FBM_MSB	(0 << I2S_TXCR_FBM_SHIFT)
+#define I2S_TXCR_FBM_LSB	(1 << I2S_TXCR_FBM_SHIFT)
+#define I2S_TXCR_IBM_SHIFT	9
+#define I2S_TXCR_IBM_NORMAL	(0 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_LSJM	(1 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_RSJM	(2 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_MASK	(3 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_PBM_SHIFT	7
+#define I2S_TXCR_PBM_MODE(x)	(x << I2S_TXCR_PBM_SHIFT)
+#define I2S_TXCR_PBM_MASK	(3 << I2S_TXCR_PBM_SHIFT)
+#define I2S_TXCR_TFS_SHIFT	5
+#define I2S_TXCR_TFS_I2S	(0 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_PCM	(1 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_TDM_PCM	(2 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_TDM_I2S	(3 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_MASK	(3 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_VDW_SHIFT	0
+#define I2S_TXCR_VDW(x)		((x - 1) << I2S_TXCR_VDW_SHIFT)
+#define I2S_TXCR_VDW_MASK	(0x1f << I2S_TXCR_VDW_SHIFT)
+
+/*
+ * RXCR
+ * receive operation control register
+ */
+#define I2S_RXCR_PATH_SHIFT(x)	(17 + (x) * 2)
+#define I2S_RXCR_PATH_MASK(x)	(0x3 << I2S_RXCR_PATH_SHIFT(x))
+#define I2S_RXCR_PATH(x, v)	((v) << I2S_RXCR_PATH_SHIFT(x))
+#define I2S_RXCR_CSR_SHIFT	15
+#define I2S_RXCR_CSR(x)		(x << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_CSR_MASK	(3 << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_HWT		BIT(14)
+#define I2S_RXCR_SJM_SHIFT	12
+#define I2S_RXCR_SJM_R		(0 << I2S_RXCR_SJM_SHIFT)
+#define I2S_RXCR_SJM_L		(1 << I2S_RXCR_SJM_SHIFT)
+#define I2S_RXCR_FBM_SHIFT	11
+#define I2S_RXCR_FBM_MSB	(0 << I2S_RXCR_FBM_SHIFT)
+#define I2S_RXCR_FBM_LSB	(1 << I2S_RXCR_FBM_SHIFT)
+#define I2S_RXCR_IBM_SHIFT	9
+#define I2S_RXCR_IBM_NORMAL	(0 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_LSJM	(1 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_RSJM	(2 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_MASK	(3 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_PBM_SHIFT	7
+#define I2S_RXCR_PBM_MODE(x)	(x << I2S_RXCR_PBM_SHIFT)
+#define I2S_RXCR_PBM_MASK	(3 << I2S_RXCR_PBM_SHIFT)
+#define I2S_RXCR_TFS_SHIFT	5
+#define I2S_RXCR_TFS_I2S	(0 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_PCM	(1 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_TDM_PCM	(2 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_TDM_I2S	(3 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_MASK	(3 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_VDW_SHIFT	0
+#define I2S_RXCR_VDW(x)		((x - 1) << I2S_RXCR_VDW_SHIFT)
+#define I2S_RXCR_VDW_MASK	(0x1f << I2S_RXCR_VDW_SHIFT)
+
+/*
+ * CKR
+ * clock generation register
+ */
+#define I2S_CKR_TRCM_SHIFT	28
+#define I2S_CKR_TRCM(x)	(x << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_TXRX	(0 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_TXONLY	(1 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_RXONLY	(2 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_MASK	(3 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_MSS_SHIFT	27
+#define I2S_CKR_MSS_MASTER	(0 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_MSS_SLAVE	(1 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_MSS_MASK	(1 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_CKP_SHIFT	26
+#define I2S_CKR_CKP_NORMAL	(0 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_CKP_INVERTED	(1 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_CKP_MASK	(1 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_RLP_SHIFT	25
+#define I2S_CKR_RLP_NORMAL	(0 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_RLP_INVERTED	(1 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_RLP_MASK	(1 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_TLP_SHIFT	24
+#define I2S_CKR_TLP_NORMAL	(0 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_TLP_INVERTED	(1 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_TLP_MASK	(1 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_MDIV_SHIFT	16
+#define I2S_CKR_MDIV(x)		((x - 1) << I2S_CKR_MDIV_SHIFT)
+#define I2S_CKR_MDIV_MASK	(0xff << I2S_CKR_MDIV_SHIFT)
+#define I2S_CKR_RSD_SHIFT	8
+#define I2S_CKR_RSD(x)		((x - 1) << I2S_CKR_RSD_SHIFT)
+#define I2S_CKR_RSD_MASK	(0xff << I2S_CKR_RSD_SHIFT)
+#define I2S_CKR_TSD_SHIFT	0
+#define I2S_CKR_TSD(x)		((x - 1) << I2S_CKR_TSD_SHIFT)
+#define I2S_CKR_TSD_MASK	(0xff << I2S_CKR_TSD_SHIFT)
+
+/*
+ * FIFOLR
+ * FIFO level register
+ */
+#define I2S_FIFOLR_RFL_SHIFT	24
+#define I2S_FIFOLR_RFL_MASK	(0x3f << I2S_FIFOLR_RFL_SHIFT)
+#define I2S_FIFOLR_TFL3_SHIFT	18
+#define I2S_FIFOLR_TFL3_MASK	(0x3f << I2S_FIFOLR_TFL3_SHIFT)
+#define I2S_FIFOLR_TFL2_SHIFT	12
+#define I2S_FIFOLR_TFL2_MASK	(0x3f << I2S_FIFOLR_TFL2_SHIFT)
+#define I2S_FIFOLR_TFL1_SHIFT	6
+#define I2S_FIFOLR_TFL1_MASK	(0x3f << I2S_FIFOLR_TFL1_SHIFT)
+#define I2S_FIFOLR_TFL0_SHIFT	0
+#define I2S_FIFOLR_TFL0_MASK	(0x3f << I2S_FIFOLR_TFL0_SHIFT)
+
+/*
+ * DMACR
+ * DMA control register
+ */
+#define I2S_DMACR_RDE_SHIFT	24
+#define I2S_DMACR_RDE_DISABLE	(0 << I2S_DMACR_RDE_SHIFT)
+#define I2S_DMACR_RDE_ENABLE	(1 << I2S_DMACR_RDE_SHIFT)
+#define I2S_DMACR_RDL_SHIFT	16
+#define I2S_DMACR_RDL(x)	((x - 1) << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_RDL_MASK	(0x1f << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_TDE_SHIFT	8
+#define I2S_DMACR_TDE_DISABLE	(0 << I2S_DMACR_TDE_SHIFT)
+#define I2S_DMACR_TDE_ENABLE	(1 << I2S_DMACR_TDE_SHIFT)
+#define I2S_DMACR_TDL_SHIFT	0
+#define I2S_DMACR_TDL(x)	((x) << I2S_DMACR_TDL_SHIFT)
+#define I2S_DMACR_TDL_MASK	(0x1f << I2S_DMACR_TDL_SHIFT)
+
+/*
+ * INTCR
+ * interrupt control register
+ */
+#define I2S_INTCR_RFT_SHIFT	20
+#define I2S_INTCR_RFT(x)	((x - 1) << I2S_INTCR_RFT_SHIFT)
+#define I2S_INTCR_RXOIC		BIT(18)
+#define I2S_INTCR_RXOIE_SHIFT	17
+#define I2S_INTCR_RXOIE_DISABLE	(0 << I2S_INTCR_RXOIE_SHIFT)
+#define I2S_INTCR_RXOIE_ENABLE	(1 << I2S_INTCR_RXOIE_SHIFT)
+#define I2S_INTCR_RXFIE_SHIFT	16
+#define I2S_INTCR_RXFIE_DISABLE	(0 << I2S_INTCR_RXFIE_SHIFT)
+#define I2S_INTCR_RXFIE_ENABLE	(1 << I2S_INTCR_RXFIE_SHIFT)
+#define I2S_INTCR_TFT_SHIFT	4
+#define I2S_INTCR_TFT(x)	((x - 1) << I2S_INTCR_TFT_SHIFT)
+#define I2S_INTCR_TFT_MASK	(0x1f << I2S_INTCR_TFT_SHIFT)
+#define I2S_INTCR_TXUIC		BIT(2)
+#define I2S_INTCR_TXUIE_SHIFT	1
+#define I2S_INTCR_TXUIE_DISABLE	(0 << I2S_INTCR_TXUIE_SHIFT)
+#define I2S_INTCR_TXUIE_ENABLE	(1 << I2S_INTCR_TXUIE_SHIFT)
+
+/*
+ * INTSR
+ * interrupt status register
+ */
+#define I2S_INTSR_TXEIE_SHIFT	0
+#define I2S_INTSR_TXEIE_DISABLE	(0 << I2S_INTSR_TXEIE_SHIFT)
+#define I2S_INTSR_TXEIE_ENABLE	(1 << I2S_INTSR_TXEIE_SHIFT)
+#define I2S_INTSR_RXOI_SHIFT	17
+#define I2S_INTSR_RXOI_INA	(0 << I2S_INTSR_RXOI_SHIFT)
+#define I2S_INTSR_RXOI_ACT	(1 << I2S_INTSR_RXOI_SHIFT)
+#define I2S_INTSR_RXFI_SHIFT	16
+#define I2S_INTSR_RXFI_INA	(0 << I2S_INTSR_RXFI_SHIFT)
+#define I2S_INTSR_RXFI_ACT	(1 << I2S_INTSR_RXFI_SHIFT)
+#define I2S_INTSR_TXUI_SHIFT	1
+#define I2S_INTSR_TXUI_INA	(0 << I2S_INTSR_TXUI_SHIFT)
+#define I2S_INTSR_TXUI_ACT	(1 << I2S_INTSR_TXUI_SHIFT)
+#define I2S_INTSR_TXEI_SHIFT	0
+#define I2S_INTSR_TXEI_INA	(0 << I2S_INTSR_TXEI_SHIFT)
+#define I2S_INTSR_TXEI_ACT	(1 << I2S_INTSR_TXEI_SHIFT)
+
+/*
+ * XFER
+ * Transfer start register
+ */
+#define I2S_XFER_RXS_SHIFT	1
+#define I2S_XFER_RXS_STOP	(0 << I2S_XFER_RXS_SHIFT)
+#define I2S_XFER_RXS_START	(1 << I2S_XFER_RXS_SHIFT)
+#define I2S_XFER_TXS_SHIFT	0
+#define I2S_XFER_TXS_STOP	(0 << I2S_XFER_TXS_SHIFT)
+#define I2S_XFER_TXS_START	(1 << I2S_XFER_TXS_SHIFT)
+
+/*
+ * CLR
+ * clear SCLK domain logic register
+ */
+#define I2S_CLR_RXC	BIT(1)
+#define I2S_CLR_TXC	BIT(0)
+
+/*
+ * TXDR
+ * Transimt FIFO data register, write only.
+ */
+#define I2S_TXDR_MASK	(0xff)
+
+/*
+ * RXDR
+ * Receive FIFO data register, write only.
+ */
+#define I2S_RXDR_MASK	(0xff)
+
+/*
+ * TDM_CTRL
+ * TDM ctrl register
+ */
+#define TDM_FSYNC_WIDTH_SEL1_MSK	GENMASK(20, 18)
+#define TDM_FSYNC_WIDTH_SEL1(x)		((x - 1) << 18)
+#define TDM_FSYNC_WIDTH_SEL0_MSK	BIT(17)
+#define TDM_FSYNC_WIDTH_HALF_FRAME	0
+#define TDM_FSYNC_WIDTH_ONE_FRAME	BIT(17)
+#define TDM_SHIFT_CTRL_MSK		GENMASK(16, 14)
+#define TDM_SHIFT_CTRL(x)		((x) << 14)
+#define TDM_SLOT_BIT_WIDTH_MSK		GENMASK(13, 9)
+#define TDM_SLOT_BIT_WIDTH(x)		((x - 1) << 9)
+#define TDM_FRAME_WIDTH_MSK		GENMASK(8, 0)
+#define TDM_FRAME_WIDTH(x)		((x - 1) << 0)
+
+/*
+ * CLKDIV
+ * Mclk div register
+ */
+#define I2S_CLKDIV_TXM_SHIFT	0
+#define I2S_CLKDIV_TXM(x)		((x - 1) << I2S_CLKDIV_TXM_SHIFT)
+#define I2S_CLKDIV_TXM_MASK	(0xff << I2S_CLKDIV_TXM_SHIFT)
+#define I2S_CLKDIV_RXM_SHIFT	8
+#define I2S_CLKDIV_RXM(x)		((x - 1) << I2S_CLKDIV_RXM_SHIFT)
+#define I2S_CLKDIV_RXM_MASK	(0xff << I2S_CLKDIV_RXM_SHIFT)
+
+/* Clock divider id */
+enum {
+	ROCKCHIP_DIV_MCLK = 0,
+	ROCKCHIP_DIV_BCLK,
+};
+
+/* channel select */
+#define I2S_CSR_SHIFT	15
+#define I2S_CHN_2	(0 << I2S_CSR_SHIFT)
+#define I2S_CHN_4	(1 << I2S_CSR_SHIFT)
+#define I2S_CHN_6	(2 << I2S_CSR_SHIFT)
+#define I2S_CHN_8	(3 << I2S_CSR_SHIFT)
+
+/* io direction cfg register */
+#define I2S_IO_DIRECTION_MASK	(7)
+#define I2S_IO_8CH_OUT_2CH_IN	(7)
+#define I2S_IO_6CH_OUT_4CH_IN	(3)
+#define I2S_IO_4CH_OUT_6CH_IN	(1)
+#define I2S_IO_2CH_OUT_8CH_IN	(0)
+
+/* I2S REGS */
+#define I2S_TXCR	(0x0000)
+#define I2S_RXCR	(0x0004)
+#define I2S_CKR		(0x0008)
+#define I2S_TXFIFOLR	(0x000c)
+#define I2S_DMACR	(0x0010)
+#define I2S_INTCR	(0x0014)
+#define I2S_INTSR	(0x0018)
+#define I2S_XFER	(0x001c)
+#define I2S_CLR		(0x0020)
+#define I2S_TXDR	(0x0024)
+#define I2S_RXDR	(0x0028)
+#define I2S_RXFIFOLR	(0x002c)
+#define I2S_TDM_TXCR	(0x0030)
+#define I2S_TDM_RXCR	(0x0034)
+#define I2S_CLKDIV	(0x0038)
+
+#define HIWORD_UPDATE(v, h, l)	(((v) << (l)) | (GENMASK((h), (l)) << 16))
+
+/* PX30 GRF CONFIGS */
+#define PX30_I2S0_CLK_IN_SRC_FROM_TX		HIWORD_UPDATE(1, 13, 12)
+#define PX30_I2S0_CLK_IN_SRC_FROM_RX		HIWORD_UPDATE(2, 13, 12)
+#define PX30_I2S0_MCLK_OUT_SRC_FROM_TX		HIWORD_UPDATE(1, 5, 5)
+#define PX30_I2S0_MCLK_OUT_SRC_FROM_RX		HIWORD_UPDATE(0, 5, 5)
+
+#define PX30_I2S0_CLK_TXONLY \
+	(PX30_I2S0_MCLK_OUT_SRC_FROM_TX | PX30_I2S0_CLK_IN_SRC_FROM_TX)
+
+#define PX30_I2S0_CLK_RXONLY \
+	(PX30_I2S0_MCLK_OUT_SRC_FROM_RX | PX30_I2S0_CLK_IN_SRC_FROM_RX)
+
+/* RK1808 GRF CONFIGS */
+#define RK1808_I2S0_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 2, 2)
+#define RK1808_I2S0_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 2, 2)
+#define RK1808_I2S0_CLK_IN_SRC_FROM_TX		HIWORD_UPDATE(1, 1, 0)
+#define RK1808_I2S0_CLK_IN_SRC_FROM_RX		HIWORD_UPDATE(2, 1, 0)
+
+#define RK1808_I2S0_CLK_TXONLY \
+	(RK1808_I2S0_MCLK_OUT_SRC_FROM_TX | RK1808_I2S0_CLK_IN_SRC_FROM_TX)
+
+#define RK1808_I2S0_CLK_RXONLY \
+	(RK1808_I2S0_MCLK_OUT_SRC_FROM_RX | RK1808_I2S0_CLK_IN_SRC_FROM_RX)
+
+/* RK3308 GRF CONFIGS */
+#define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 10, 10)
+#define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 10, 10)
+#define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX	HIWORD_UPDATE(1, 9, 9)
+#define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_RX	HIWORD_UPDATE(0, 9, 9)
+#define RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_RX	HIWORD_UPDATE(1, 8, 8)
+#define RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_TX	HIWORD_UPDATE(0, 8, 8)
+#define RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 2, 2)
+#define RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 2, 2)
+#define RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_TX	HIWORD_UPDATE(1, 1, 1)
+#define RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_RX	HIWORD_UPDATE(0, 1, 1)
+#define RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_RX	HIWORD_UPDATE(1, 0, 0)
+#define RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_TX	HIWORD_UPDATE(0, 0, 0)
+
+#define RK3308_I2S0_CLK_TXONLY \
+	(RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX | \
+	RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX | \
+	RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_TX)
+
+#define RK3308_I2S0_CLK_RXONLY \
+	(RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX | \
+	RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_RX | \
+	RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_RX)
+
+#define RK3308_I2S1_CLK_TXONLY \
+	(RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_TX | \
+	RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_TX | \
+	RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_TX)
+
+#define RK3308_I2S1_CLK_RXONLY \
+	(RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_RX | \
+	RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_RX | \
+	RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_RX)
+
+/* RK3568 GRF CONFIGS */
+#define RK3568_I2S1_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(1, 5, 5)
+#define RK3568_I2S1_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(0, 5, 5)
+
+#define RK3568_I2S1_CLK_TXONLY \
+	RK3568_I2S1_MCLK_OUT_SRC_FROM_TX
+
+#define RK3568_I2S1_CLK_RXONLY \
+	RK3568_I2S1_MCLK_OUT_SRC_FROM_RX
+
+#define RK3568_I2S3_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(1, 15, 15)
+#define RK3568_I2S3_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(0, 15, 15)
+#define RK3568_I2S3_SCLK_SRC_FROM_TX		HIWORD_UPDATE(1, 7, 7)
+#define RK3568_I2S3_SCLK_SRC_FROM_RX		HIWORD_UPDATE(0, 7, 7)
+#define RK3568_I2S3_LRCK_SRC_FROM_TX		HIWORD_UPDATE(1, 6, 6)
+#define RK3568_I2S3_LRCK_SRC_FROM_RX		HIWORD_UPDATE(0, 6, 6)
+
+#define RK3568_I2S3_MCLK_TXONLY \
+	RK3568_I2S3_MCLK_OUT_SRC_FROM_TX
+
+#define RK3568_I2S3_CLK_TXONLY \
+	(RK3568_I2S3_SCLK_SRC_FROM_TX | \
+	RK3568_I2S3_LRCK_SRC_FROM_TX)
+
+#define RK3568_I2S3_MCLK_RXONLY \
+	RK3568_I2S3_MCLK_OUT_SRC_FROM_RX
+
+#define RK3568_I2S3_CLK_RXONLY \
+	(RK3568_I2S3_SCLK_SRC_FROM_RX | \
+	RK3568_I2S3_LRCK_SRC_FROM_RX)
+
+#define RK3568_I2S3_MCLK_IE			HIWORD_UPDATE(0, 3, 3)
+#define RK3568_I2S3_MCLK_OE			HIWORD_UPDATE(1, 3, 3)
+#define RK3568_I2S2_MCLK_IE			HIWORD_UPDATE(0, 2, 2)
+#define RK3568_I2S2_MCLK_OE			HIWORD_UPDATE(1, 2, 2)
+#define RK3568_I2S1_MCLK_TX_IE			HIWORD_UPDATE(0, 1, 1)
+#define RK3568_I2S1_MCLK_TX_OE			HIWORD_UPDATE(1, 1, 1)
+#define RK3568_I2S1_MCLK_RX_IE			HIWORD_UPDATE(0, 0, 0)
+#define RK3568_I2S1_MCLK_RX_OE			HIWORD_UPDATE(1, 0, 0)
+
+/* RV1126 GRF CONFIGS */
+#define RV1126_I2S0_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 9, 9)
+#define RV1126_I2S0_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 9, 9)
+
+#define RV1126_I2S0_CLK_TXONLY \
+	RV1126_I2S0_MCLK_OUT_SRC_FROM_TX
+
+#define RV1126_I2S0_CLK_RXONLY \
+	RV1126_I2S0_MCLK_OUT_SRC_FROM_RX
+
+#endif /* _ROCKCHIP_I2S_TDM_H */
-- 
2.32.0



From frattaroli.nicolas at gmail.com  Tue Aug 17 03:11:17 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Tue, 17 Aug 2021 12:11:17 +0200
Subject: [PATCH 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210817101119.423853-3-frattaroli.nicolas@gmail.com>

This adds the YAML bindings for the Rockchip I2S/TDM audio driver.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 .../bindings/sound/rockchip,i2s-tdm.yaml      | 221 ++++++++++++++++++
 include/dt-bindings/sound/rockchip,i2s-tdm.h  |   9 +
 2 files changed, 230 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
 create mode 100644 include/dt-bindings/sound/rockchip,i2s-tdm.h

diff --git a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
new file mode 100644
index 000000000000..c3022620b47f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
@@ -0,0 +1,221 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip I2S/TDM Controller
+
+description:
+  The Rockchip I2S/TDM Controller is a Time Division Multiplexed
+  audio interface found in various Rockchip SoCs, allowing up
+  to 8 channels of audio over a serial interface.
+
+maintainers:
+  - Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,px30-i2s-tdm
+      - rockchip,rk1808-i2s-tdm
+      - rockchip,rk3308-i2s-tdm
+      - rockchip,rk3568-i2s-tdm
+      - rockchip,rv1126-i2s-tdm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  dmas:
+    minItems: 1
+    maxItems: 2
+
+  dma-names:
+    oneOf:
+      - const: rx
+      - items:
+          - const: tx
+          - const: rx
+
+  clocks:
+    items:
+      - description: clock for TX
+      - description: clock for RX
+      - description: clock for I2S bus
+
+  clock-names:
+    items:
+      - const: mclk_tx
+      - const: mclk_rx
+      - const: hclk
+
+  rockchip,frame-width:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 64
+    minimum: 32
+    maximum: 512
+    description:
+      Width of a frame, usually slot width multiplied by number of slots.
+      Must be even.
+
+  resets:
+    items:
+      - description: reset for TX
+      - description: reset for RX
+
+  reset-names:
+    items:
+      - const: tx-m
+      - const: rx-m
+
+  rockchip,cru:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the cru.
+      Required if both playback and capture are used, i.e. if rockchip,clk-trcm
+      is 0.
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the GRF register.
+
+  rockchip,mclk-calibrate:
+    description:
+      Enable mclk source calibration.
+    type: boolean
+
+  rockchip,trcm-sync:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Which lrck/bclk clocks each direction will sync to. You should use the
+      constants in <dt-bindings/sound/rockchip,i2s-tdm.h>
+    oneOf:
+      - const: 0
+        description:
+          RK_TRCM_TXRX. Use both the TX and the RX clock for TX and RX.
+      - const: 1
+        description:
+          RK_TRCM_TX. Use only the TX clock for TX and RX.
+      - const: 2
+        description:
+          RK_TRCM_RX. Use only the RX clock for TX and RX.
+
+  "#sound-dai-cells":
+    const: 0
+
+  rockchip,no-dmaengine:
+    description:
+      If present, driver will not register a pcm dmaengine, only the dai.
+      If the dai is part of multi-dais, the property should be present.
+    type: boolean
+
+  rockchip,playback-only:
+    description: Specify that the controller only has playback capability.
+    type: boolean
+
+  rockchip,capture-only:
+    description: Specify that the controller only has capture capability.
+    type: boolean
+
+  rockchip,i2s-rx-route:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the mapping of I2S RX sdis to I2S data bus lines.
+      By default, they are mapped one-to-one.
+    items:
+      - description: which sdi to connect to data line 0
+      - description: which sdi to connect to data line 1
+      - description: which sdi to connect to data line 2
+      - description: which sdi to connect to data line 3
+
+  rockchip,i2s-tx-route:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the mapping of I2S TX sdos to I2S data bus lines.
+      By default, they are mapped one-to-one.
+    items:
+      - description: which sdo to connect to data line 0
+      - description: which sdo to connect to data line 1
+      - description: which sdo to connect to data line 2
+      - description: which sdo to connect to data line 3
+
+  rockchip,tdm-fsync-half-frame:
+    description: Whether to use half frame fsync.
+    type: boolean
+
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - dmas
+  - dma-names
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - rockchip,grf
+  - "#sound-dai-cells"
+  - rockchip,trcm-sync
+
+allOf:
+  - if:
+      properties:
+        rockchip,clk-trcm:
+          contains:
+            enum: [0]
+    then:
+      required:
+        - rockchip,cru
+
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3568-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/pinctrl/rockchip.h>
+    #include <dt-bindings/sound/rockchip,i2s-tdm.h>
+
+
+    foo {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        i2s at fe410000 {
+            compatible = "rockchip,rk3568-i2s-tdm";
+            reg = <0x0 0xfe410000 0x0 0x1000>;
+            interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
+                     <&cru HCLK_I2S1_8CH>;
+            clock-names = "mclk_tx", "mclk_rx", "hclk";
+            dmas = <&dmac1 2>, <&dmac1 3>;
+            dma-names = "tx", "rx";
+            resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+            reset-names = "tx-m", "rx-m";
+            rockchip,trcm-sync = <RK_TRCM_TX>;
+            rockchip,cru = <&cru>;
+            rockchip,grf = <&grf>;
+            #sound-dai-cells = <0>;
+            pinctrl-names = "default";
+            pinctrl-0 =
+                <&i2s1m0_sclktx
+                &i2s1m0_sclkrx
+                &i2s1m0_lrcktx
+                &i2s1m0_lrckrx
+                &i2s1m0_sdi0
+                &i2s1m0_sdi1
+                &i2s1m0_sdi2
+                &i2s1m0_sdi3
+                &i2s1m0_sdo0
+                &i2s1m0_sdo1
+                &i2s1m0_sdo2
+                &i2s1m0_sdo3>;
+            status = "disabled";
+        };
+    };
diff --git a/include/dt-bindings/sound/rockchip,i2s-tdm.h b/include/dt-bindings/sound/rockchip,i2s-tdm.h
new file mode 100644
index 000000000000..32494d64cf33
--- /dev/null
+++ b/include/dt-bindings/sound/rockchip,i2s-tdm.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _DT_BINDINGS_ROCKCHIP_I2S_TDM_H
+#define _DT_BINDINGS_ROCKCHIP_I2S_TDM_H
+
+#define RK_TRCM_TXRX 0
+#define RK_TRCM_TX 1
+#define RK_TRCM_RX 2
+
+#endif /* _DT_BINDINGS_ROCKCHIP_I2S_TDM_H */
-- 
2.32.0



From frattaroli.nicolas at gmail.com  Tue Aug 17 03:11:18 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Tue, 17 Aug 2021 12:11:18 +0200
Subject: [PATCH 3/4] arm64: dts: rockchip: add i2s1 on rk356x
In-Reply-To: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210817101119.423853-4-frattaroli.nicolas@gmail.com>

This adds the necessary device tree node on rk3566 and rk3568
to enable the I2S1 TDM audio controller.

I2S0 has not been added, as it is connected to HDMI and there is
no way to test that it's working without a functioning video
clock (read: VOP2 driver).

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 26 ++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index bef747fb1fe2..2cdb13f29bed 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -554,6 +554,32 @@ sdhci: mmc at fe310000 {
 		status = "disabled";
 	};
 
+	i2s1_8ch: i2s at fe410000 {
+		compatible = "rockchip,rk3568-i2s-tdm";
+		reg = <0x0 0xfe410000 0x0 0x1000>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+		assigned-clocks = <&cru CLK_I2S1_8CH_TX_SRC>, <&cru CLK_I2S1_8CH_RX_SRC>;
+		assigned-clock-rates = <1188000000>, <1188000000>;
+		clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
+		<&cru HCLK_I2S1_8CH>;
+		clock-names = "mclk_tx", "mclk_rx", "hclk";
+		dmas = <&dmac1 2>, <&dmac1 3>;
+		dma-names = "tx", "rx";
+		resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+		reset-names = "tx-m", "rx-m";
+		rockchip,cru = <&cru>;
+		rockchip,grf = <&grf>;
+		#sound-dai-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_sclkrx
+			     &i2s1m0_lrcktx &i2s1m0_lrckrx
+			     &i2s1m0_sdi0   &i2s1m0_sdi1
+			     &i2s1m0_sdi2   &i2s1m0_sdi3
+			     &i2s1m0_sdo0   &i2s1m0_sdo1
+			     &i2s1m0_sdo2   &i2s1m0_sdo3>;
+		status = "disabled";
+	};
+
 	dmac0: dmac at fe530000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xfe530000 0x0 0x4000>;
-- 
2.32.0



From frattaroli.nicolas at gmail.com  Tue Aug 17 03:11:19 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Tue, 17 Aug 2021 12:11:19 +0200
Subject: [PATCH 4/4] arm64: dts: rockchip: add analog audio on Quartz64
In-Reply-To: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210817101119.423853-5-frattaroli.nicolas@gmail.com>

On the Quartz64 Model A, the I2S1 TDM controller is connected
to the rk817 codec in I2S mode. Enabling it and adding the
necessary simple-sound-card and codec nodes allows for analog
audio output on the PINE64 Quartz64 Model A SBC.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 36 ++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index b239f314b38a..8da4d1f600c3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -4,6 +4,7 @@
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/sound/rockchip,i2s-tdm.h>
 #include "rk3566.dtsi"
 
 / {
@@ -50,6 +51,20 @@ led-diy {
 		};
 	};
 
+	rk817-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,name = "Analog RK817";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s1_8ch>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&rk817>;
+		};
+	};
+
 	vcc12v_dcin: vcc12v_dcin {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc12v_dcin";
@@ -174,8 +189,13 @@ rk817: pmic at 20 {
 		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
 		clock-output-names = "rk808-clkout1", "rk808-clkout2";
 
+		#sound-dai-cells = <0>;
+		clock-names = "mclk";
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&pmic_int_l>;
+		pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
 		rockchip,system-power-controller;
 		wakeup-source;
 		#clock-cells = <1>;
@@ -364,9 +384,23 @@ regulator-state-mem {
 				};
 			};
 		};
+
+		rk817_codec: codec {
+		};
+
 	};
 };
 
+&i2s1_8ch {
+	status = "okay";
+	rockchip,trcm-sync = <RK_TRCM_TX>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s1m0_sclktx
+		     &i2s1m0_lrcktx
+		     &i2s1m0_sdi0
+		     &i2s1m0_sdo0>;
+};
+
 &mdio1 {
 	rgmii_phy1: ethernet-phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
-- 
2.32.0



From harinik at xilinx.com  Tue Aug 17 03:16:49 2021
From: harinik at xilinx.com (Harini Katakam)
Date: Tue, 17 Aug 2021 15:46:49 +0530
Subject: [PATCH 2/3] dt-bindings: mscc: Add RGMII RX and TX delay tuning
In-Reply-To: <20210714210803.GA3522064@robh.at.kernel.org>
References: <20210629094038.18610-1-harini.katakam@xilinx.com>
 <20210629094038.18610-3-harini.katakam@xilinx.com>
 <20210714210803.GA3522064@robh.at.kernel.org>
Message-ID: <CAFcVECJXhjQLZdfQm8n_0cLsuh6CFPJbSA4A5XXQL+6+okb+CQ@mail.gmail.com>

Hi Rob,

Thanks for the review and sorry I din't reply earlier.
<snip>
> > +- vsc8531,rx-delay   : RGMII RX delay. Allowed values are defined in
>
> 'vsc8531' is not a vendor. The form is <vendor>,<propname>.

I was just aligning it with existing optional property names in this document.
Could you please let me know if mscc,rx-delay is more appropriate?

Regards,
Harini


From vkoul at kernel.org  Tue Aug 17 03:22:18 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 15:52:18 +0530
Subject: [PATCH v3 1/9] dt-bindings: phy: mediatek: tphy: support type
 switch by pericfg
In-Reply-To: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629191987-20774-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YRuN2tvQtO294+sE@matsya>

On 17-08-21, 17:19, Chunfeng Yun wrote:
> Add support type switch by pericfg register between USB3, PCIe,
> SATA, SGMII, this is used to replace the way through efuse or
> jumper.

Applied all, thanks

-- 
~Vinod


From p.yadav at ti.com  Tue Aug 17 03:24:31 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 15:54:31 +0530
Subject: [PATCH v2 17/35] mtd: spi-nor: Introduce
 spi_nor_nonsfdp_flags_init()
In-Reply-To: <20210727045222.905056-18-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-18-tudor.ambarus@microchip.com>
Message-ID: <20210817102429.kmhuef5hxumllxjj@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Used to initialize the NOR flags for settings that are not defined
> in the JESD216 SFDP standard, thus can not be retrieved when parsing
> SFDP. No functional change.

I am worried if the order in which these flags are set can cause some 
subtle bugs.

I can see one instance of it with SNOR_F_HAS_LOCK. 
spi_nor_late_init_params() checks for SNOR_F_HAS_LOCK and if there are 
no locking ops specified, it sets the default locking ops. This works 
fine before this patch because the flag is set before the function is 
called. But now, the flag will be set _after_ the function is called, 
and so you will never be able to set the default flags.

This is one bug I can spot but I fear some others might be hiding 
somewhere as well. SPI NOR has accumulated a lot of spaghetti code over 
the years and I certainly felt it when working on my Octal DTR series. 
It caused an address width selection bug that was not obvious at all, 
and was not even caught during the rc cycles.

I think this series does clean up that spaghetti a lot. But you need to 
be careful of such bugs. I think you should definitely let this series 
cook in next for some time so it gets some exposure and hopefully some 
testing.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c | 88 ++++++++++++++++++++++----------------
>  1 file changed, 52 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 1f38fa8ab2fa..6a8617346764 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -2687,6 +2687,56 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
>  		spi_nor_init_default_locking_ops(nor);
>  }
>  
> +/**
> + * spi_nor_nonsfdp_flags_init() - Initialize NOR flags for settings that are not
> + * defined in the JESD216 SFDP standard, thus can not be retrieved when parsing
> + * SFDP.
> + * @nor:	pointer to a 'struct spi_nor'
> + */
> +static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
> +{
> +	const struct flash_info *info = nor->info;
> +	struct device_node *np = spi_nor_get_flash_node(nor);
> +
> +	if (of_property_read_bool(np, "broken-flash-reset"))
> +		nor->flags |= SNOR_F_BROKEN_RESET;
> +
> +	if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
> +		nor->flags |= SNOR_F_SWP_IS_VOLATILE;
> +
> +	if (info->flags & SPI_NOR_HAS_LOCK)
> +		nor->flags |= SNOR_F_HAS_LOCK;

As mentioned above, this would cause a bug.

> +
> +	if (info->flags & SPI_NOR_HAS_TB) {
> +		nor->flags |= SNOR_F_HAS_SR_TB;
> +		if (info->flags & SPI_NOR_TB_SR_BIT6)
> +			nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
> +	}
> +
> +	if (info->flags & SPI_NOR_4BIT_BP) {
> +		nor->flags |= SNOR_F_HAS_4BIT_BP;
> +		if (info->flags & SPI_NOR_BP3_SR_BIT6)
> +			nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
> +	}
> +
> +	if (info->flags & NO_CHIP_ERASE)
> +		nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
> +
> +	if (info->flags & USE_FSR)
> +		nor->flags |= SNOR_F_USE_FSR;
> +
> +	if (info->flags & USE_CLSR)
> +		nor->flags |= SNOR_F_USE_CLSR;
> +
> +	/*
> +	 * Make sure the XSR_RDY flag is set before calling
> +	 * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
> +	 * with Atmel SPI NOR.
> +	 */
> +	if (info->flags & SPI_NOR_XSR_RDY)
> +		nor->flags |=  SNOR_F_READY_XSR_RDY;
> +}
> +
>  /**
>   * spi_nor_init_params() - Initialize the flash's parameters and settings.
>   * @nor:	pointer to a 'struct spi_nor'.
> @@ -2736,6 +2786,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
>  
>  	spi_nor_late_init_params(nor);
>  
> +	spi_nor_nonsfdp_flags_init(nor);
> +
>  	return 0;
>  }
>  
> @@ -3078,7 +3130,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	const struct flash_info *info;
>  	struct device *dev = nor->dev;
>  	struct mtd_info *mtd = &nor->mtd;
> -	struct device_node *np = spi_nor_get_flash_node(nor);
>  	int ret;
>  	int i;
>  
> @@ -3115,17 +3166,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  
>  	mutex_init(&nor->lock);
>  
> -	/*
> -	 * Make sure the XSR_RDY flag is set before calling
> -	 * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
> -	 * with Atmel SPI NOR.
> -	 */
> -	if (info->flags & SPI_NOR_XSR_RDY)
> -		nor->flags |=  SNOR_F_READY_XSR_RDY;
> -
> -	if (info->flags & SPI_NOR_HAS_LOCK)
> -		nor->flags |= SNOR_F_HAS_LOCK;
> -
>  	mtd->_write = spi_nor_write;
>  
>  	/* Init flash parameters based on flash_info struct and SFDP */
> @@ -3147,27 +3187,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	mtd->_get_device = spi_nor_get_device;
>  	mtd->_put_device = spi_nor_put_device;
>  
> -	if (info->flags & USE_FSR)
> -		nor->flags |= SNOR_F_USE_FSR;
> -	if (info->flags & SPI_NOR_HAS_TB) {
> -		nor->flags |= SNOR_F_HAS_SR_TB;
> -		if (info->flags & SPI_NOR_TB_SR_BIT6)
> -			nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
> -	}
> -
> -	if (info->flags & NO_CHIP_ERASE)
> -		nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
> -	if (info->flags & USE_CLSR)
> -		nor->flags |= SNOR_F_USE_CLSR;
> -	if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
> -		nor->flags |= SNOR_F_SWP_IS_VOLATILE;
> -
> -	if (info->flags & SPI_NOR_4BIT_BP) {
> -		nor->flags |= SNOR_F_HAS_4BIT_BP;
> -		if (info->flags & SPI_NOR_BP3_SR_BIT6)
> -			nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
> -	}
> -
>  	if (info->flags & SPI_NOR_NO_ERASE)
>  		mtd->flags |= MTD_NO_ERASE;
>  
> @@ -3175,9 +3194,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	nor->page_size = nor->params->page_size;
>  	mtd->writebufsize = nor->page_size;
>  
> -	if (of_property_read_bool(np, "broken-flash-reset"))
> -		nor->flags |= SNOR_F_BROKEN_RESET;
> -

As I pointed out above, I think this patch is certainly going in the 
right direction. We just need to be careful of the bugs that slip 
through.

>  	/*
>  	 * Configure the SPI memory:
>  	 * - select op codes for (Fast) Read, Page Program and Sector Erase.
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From vkoul at kernel.org  Tue Aug 17 03:30:52 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 16:00:52 +0530
Subject: [PATCHv3 5/6] phy: amlogic: meson8b-usb2: Power off the PHY by
 putting it into reset mode
In-Reply-To: <20210817041548.1276-6-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-6-linux.amoon@gmail.com>
Message-ID: <YRuP3D6EMlaKJOx7@matsya>

On 17-08-21, 09:45, Anand Moon wrote:
> Power off the PHY by putting it into reset mode.

Applied, thanks

-- 
~Vinod


From vkoul at kernel.org  Tue Aug 17 03:31:04 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Tue, 17 Aug 2021 16:01:04 +0530
Subject: [PATCHv3 6/6] phy: amlogic: meson8b-usb2: don't log an error on
 -EPROBE_DEFER
In-Reply-To: <20210817041548.1276-7-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-7-linux.amoon@gmail.com>
Message-ID: <YRuP6JfdEZNL8tXt@matsya>

On 17-08-21, 09:45, Anand Moon wrote:
> devm_phy_create can return -EPROBE_DEFER if the vbus-supply is not ready
> yet. Silence this warning as the driver framework will re-attempt
> registering the PHY. Use dev_err_probe() for phy resources to indicate
> the deferral reason when waiting for the resource to come up.

Applied, thanks

-- 
~Vinod


From lkp at intel.com  Tue Aug 17 04:17:59 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 19:17:59 +0800
Subject: [soc:arm/dt] BUILD SUCCESS
 9b35ab1e314c3f563f8d6982c0a8f2c8964e4a36
Message-ID: <611b9ae7.ChN2kqANvYDjuvY+%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/dt
branch HEAD: 9b35ab1e314c3f563f8d6982c0a8f2c8964e4a36  Merge tag 'imx-dt-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/dt

elapsed time: 729m

configs tested: 114
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                        shmobile_defconfig
powerpc                       ebony_defconfig
powerpc                      walnut_defconfig
arm                            mmp2_defconfig
xtensa                  audio_kc705_defconfig
arm                         vf610m4_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                       omap2plus_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                  decstation_64_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
h8300                            allyesconfig
arc                            hsdk_defconfig
powerpc                     skiroot_defconfig
mips                 decstation_r4k_defconfig
arm                        multi_v7_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                     decstation_defconfig
um                             i386_defconfig
arm                      jornada720_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 04:18:03 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 19:18:03 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS d0dc706ab1924e2f41677741cfa26f1c9ed6ce93
Message-ID: <611b9aeb.Sw6eum5KCfJ0q4qt%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: d0dc706ab1924e2f41677741cfa26f1c9ed6ce93  Merge tag 'qcom-arm64-fixes-for-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/fixes

elapsed time: 729m

configs tested: 114
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                        shmobile_defconfig
powerpc                       ebony_defconfig
powerpc                      walnut_defconfig
arm                            mmp2_defconfig
xtensa                  audio_kc705_defconfig
arm                         vf610m4_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                       omap2plus_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                  decstation_64_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
h8300                            allyesconfig
arc                            hsdk_defconfig
powerpc                     skiroot_defconfig
mips                 decstation_r4k_defconfig
arm                        multi_v7_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                     decstation_defconfig
um                             i386_defconfig
arm                      jornada720_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 04:18:08 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 19:18:08 +0800
Subject: [soc:arm/defconfig] BUILD SUCCESS
 ecdbda1746b5bf771cd86dfeb84c20d62f5bfc51
Message-ID: <611b9af0.44d+pB00l7x9F8GW%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/defconfig
branch HEAD: ecdbda1746b5bf771cd86dfeb84c20d62f5bfc51  Merge tag 'qcom-arm64-defconfig-for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/defconfig

elapsed time: 729m

configs tested: 114
configs skipped: 80

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                        shmobile_defconfig
powerpc                       ebony_defconfig
powerpc                      walnut_defconfig
arm                            mmp2_defconfig
xtensa                  audio_kc705_defconfig
arm                         vf610m4_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                       omap2plus_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                  decstation_64_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
h8300                            allyesconfig
arc                            hsdk_defconfig
powerpc                     skiroot_defconfig
mips                 decstation_r4k_defconfig
arm                        multi_v7_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                     decstation_defconfig
um                             i386_defconfig
arm                      jornada720_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 17 04:18:11 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 19:18:11 +0800
Subject: [soc:for-next] BUILD SUCCESS 4060df1d7c279715f6b9780a682ceeb0a2708201
Message-ID: <611b9af3.vebJ+I/QB3dKTSVL%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: 4060df1d7c279715f6b9780a682ceeb0a2708201  soc: document merges

elapsed time: 729m

configs tested: 114
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
powerpc                      ep88xc_defconfig
sh                   secureedge5410_defconfig
arm                        vexpress_defconfig
xtensa                          iss_defconfig
arm                        shmobile_defconfig
powerpc                       ebony_defconfig
powerpc                      walnut_defconfig
arm                            mmp2_defconfig
xtensa                  audio_kc705_defconfig
arm                         vf610m4_defconfig
arm                         cm_x300_defconfig
arm                             pxa_defconfig
arm                       omap2plus_defconfig
arm                         axm55xx_defconfig
arm                        spear6xx_defconfig
nios2                               defconfig
alpha                            alldefconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arc                          axs101_defconfig
mips                     loongson2k_defconfig
arm                        cerfcube_defconfig
powerpc                  mpc885_ads_defconfig
arm                          gemini_defconfig
arm                            hisi_defconfig
mips                  decstation_64_defconfig
mips                        vocore2_defconfig
powerpc                  iss476-smp_defconfig
h8300                            allyesconfig
arc                            hsdk_defconfig
powerpc                     skiroot_defconfig
mips                 decstation_r4k_defconfig
arm                        multi_v7_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                       imx_v4_v5_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                     decstation_defconfig
um                             i386_defconfig
arm                      jornada720_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From xuwei5 at hisilicon.com  Tue Aug 17 04:22:17 2021
From: xuwei5 at hisilicon.com (Wei Xu)
Date: Tue, 17 Aug 2021 19:22:17 +0800
Subject: [GIT PULL] arm64: dts: hisilicon dts updates for v5.15
Message-ID: <611B9BE9.8050904@hisilicon.com>

Hi ARM-SoC team,

Please consider to pull the following changes.
Thanks!

Best Regards,
Wei

---

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://github.com/hisilicon/linux-hisi.git tags/hisi-arm64-dt-for-5.15

for you to fetch changes up to 2dc30eb9241c21cbeaf5b668f4eb276278149d97:

  arm64: dts: HiSilicon: hi3660: address a PCI warning (2021-08-13 08:26:49 +0000)

----------------------------------------------------------------
ARM64: DT: HiSilicon ARM64 DT updates for 5.15

- Address a PCI bus range warning of the hi3660 SoC

----------------------------------------------------------------
Mauro Carvalho Chehab (1):
      arm64: dts: HiSilicon: hi3660: address a PCI warning

 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


From wangborong at cdjrlc.com  Tue Aug 17 04:31:12 2021
From: wangborong at cdjrlc.com (Jason Wang)
Date: Tue, 17 Aug 2021 19:31:12 +0800
Subject: [PATCH] ARM: davinci: dm355-evm: Fix typo in a comment
Message-ID: <20210817113112.17936-1-wangborong@cdjrlc.com>

The double `the' in the comment `Keep the the order same as that of
encoders.' is repeated. Consequently, one 'the' should be removed
from the comment.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
---
 arch/arm/mach-davinci/board-dm355-evm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 3c5a9e3c128a..4aeda9bd8029 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -296,7 +296,7 @@ static struct vpbe_enc_mode_info dm355evm_enc_preset_timing[] = {
 
 /*
  * The outputs available from VPBE + ecnoders. Keep the
- * the order same as that of encoders. First those from venc followed by that
+ * order same as that of encoders. First those from venc followed by that
  * from encoders. Index in the output refers to index on a particular encoder.
  * Driver uses this index to pass it to encoder when it supports more than
  * one output. Application uses index of the array to set an output.
-- 
2.32.0



From thunder.leizhen at huawei.com  Tue Aug 17 04:34:11 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Tue, 17 Aug 2021 19:34:11 +0800
Subject: [PATCH] iommu/arm-smmu-v3: Stop pre-zeroing batch commands in
 arm_smmu_atc_inv_master()
Message-ID: <20210817113411.1962-1-thunder.leizhen@huawei.com>

Pre-zeroing the batched commands structure is inefficient, as individual
commands are zeroed later in arm_smmu_cmdq_build_cmd(). Therefore, only
the member 'num' needs to be initialized to 0.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 50a9db5bac466c7..e6882ae81fd08f6 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -1776,10 +1776,11 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
 {
 	int i;
 	struct arm_smmu_cmdq_ent cmd;
-	struct arm_smmu_cmdq_batch cmds = {};
+	struct arm_smmu_cmdq_batch cmds;
 
 	arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
 
+	cmds.num = 0;
 	for (i = 0; i < master->num_streams; i++) {
 		cmd.atc.sid = master->streams[i].id;
 		arm_smmu_cmdq_batch_add(master->smmu, &cmds, &cmd);
-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Tue Aug 17 04:34:50 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Tue, 17 Aug 2021 19:34:50 +0800
Subject: [PATCH] iommu/arm-smmu-v3: Simplify useless instructions in
 arm_smmu_cmdq_build_cmd()
Message-ID: <20210817113450.2026-1-thunder.leizhen@huawei.com>

Although the parameter 'cmd' is always passed by a local array variable,
and only this function modifies it, the compiler does not know this. The
compiler almost always reads the value of cmd[i] from memory rather than
directly using the value cached in the register. This generates many
useless instruction operations and affects the performance to some extent.

To guide the compiler for proper optimization, 'cmd' is defined as a local
array variable, marked as register, and copied to the output parameter at
a time when the function is returned.

The optimization effect can be viewed by running the "size arm-smmu-v3.o"
command.

Before:
   text    data     bss     dec     hex
  27602    1348      56   29006    714e

After:
   text    data     bss     dec     hex
  27402    1348      56   28806    7086

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index d76bbbde558b776..50a9db5bac466c7 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -233,11 +233,19 @@ static int queue_remove_raw(struct arm_smmu_queue *q, u64 *ent)
 	return 0;
 }
 
+#define arm_smmu_cmdq_copy_cmd(dst, src)	\
+	do {					\
+		dst[0] = src[0];		\
+		dst[1] = src[1];		\
+	} while (0)
+
 /* High-level queue accessors */
-static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
+static int arm_smmu_cmdq_build_cmd(u64 *out_cmd, struct arm_smmu_cmdq_ent *ent)
 {
-	memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
-	cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
+	register u64 cmd[CMDQ_ENT_DWORDS];
+
+	cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
+	cmd[1] = 0;
 
 	switch (ent->opcode) {
 	case CMDQ_OP_TLBI_EL2_ALL:
@@ -309,6 +317,7 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 		case PRI_RESP_SUCC:
 			break;
 		default:
+			arm_smmu_cmdq_copy_cmd(out_cmd, cmd);
 			return -EINVAL;
 		}
 		cmd[1] |= FIELD_PREP(CMDQ_PRI_1_RESP, ent->pri.resp);
@@ -329,9 +338,12 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 		cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIATTR, ARM_SMMU_MEMATTR_OIWB);
 		break;
 	default:
+		arm_smmu_cmdq_copy_cmd(out_cmd, cmd);
 		return -ENOENT;
 	}
 
+	arm_smmu_cmdq_copy_cmd(out_cmd, cmd);
+
 	return 0;
 }
 
-- 
2.26.0.106.g9fadedd



From john.garry at huawei.com  Tue Aug 17 04:53:52 2021
From: john.garry at huawei.com (John Garry)
Date: Tue, 17 Aug 2021 12:53:52 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Stop pre-zeroing batch commands in
 arm_smmu_atc_inv_master()
In-Reply-To: <20210817113411.1962-1-thunder.leizhen@huawei.com>
References: <20210817113411.1962-1-thunder.leizhen@huawei.com>
Message-ID: <23f1cc66-2172-9534-53ef-3d9b2db26bda@huawei.com>

On 17/08/2021 12:34, Zhen Lei wrote:
> Pre-zeroing the batched commands structure is inefficient, as individual
> commands are zeroed later in arm_smmu_cmdq_build_cmd(). Therefore, only
> the member 'num' needs to be initialized to 0.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>

Reviewed-by: John Garry <john.garry at huawei.com>

> ---
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index 50a9db5bac466c7..e6882ae81fd08f6 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1776,10 +1776,11 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master)
>   {
>   	int i;
>   	struct arm_smmu_cmdq_ent cmd;
> -	struct arm_smmu_cmdq_batch cmds = {};
> +	struct arm_smmu_cmdq_batch cmds;
>   
>   	arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
>   
> +	cmds.num = 0;

We prob should have added a comment why we do this (and at the other 
sites). I think Robin said something similar in another patch.

>   	for (i = 0; i < master->num_streams; i++) {
>   		cmd.atc.sid = master->streams[i].id;
>   		arm_smmu_cmdq_batch_add(master->smmu, &cmds, &cmd);
> 



From yuzenghui at huawei.com  Tue Aug 17 04:56:33 2021
From: yuzenghui at huawei.com (Zenghui Yu)
Date: Tue, 17 Aug 2021 19:56:33 +0800
Subject: [PATCH linux-next] module: remove duplicate include in interrupt.c
In-Reply-To: <20210816112917.126675-1-lv.ruyi@zte.com.cn>
References: <20210816112917.126675-1-lv.ruyi@zte.com.cn>
Message-ID: <c01bbfdc-c586-93b7-a282-b859f2ebdb89@huawei.com>

On 2021/8/16 19:29, cgel.zte at gmail.com wrote:
> From: Lv Ruyi <lv.ruyi at zte.com.cn>
> 
> 'asm/interrupt.h' included in 'interrupt.c' is duplicated.

Sorry but this obviously doesn't match with the change you've made.

> 
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: Lv Ruyi <lv.ruyi at zte.com.cn>
> ---
>  arch/arm/mach-sa1100/hackkit.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
> index 3085f1c2e586..3fe34ee7c0ab 100644
> --- a/arch/arm/mach-sa1100/hackkit.c
> +++ b/arch/arm/mach-sa1100/hackkit.c
> @@ -18,7 +18,6 @@
>  #include <linux/serial_core.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/partitions.h>
> -#include <linux/tty.h>
>  #include <linux/gpio.h>
>  #include <linux/leds.h>
>  #include <linux/platform_device.h>
> 


From o.rempel at pengutronix.de  Tue Aug 17 05:08:32 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Tue, 17 Aug 2021 14:08:32 +0200
Subject: [PATCH v1] ARM: imx6: mask all interrupts before calling
 stby-poweroff sequence
Message-ID: <20210817120832.5746-1-o.rempel@pengutronix.de>

Any pending interrupt can prevent entering standby based power off state.
To avoid it, mask all interrupts.

Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 arch/arm/mach-imx/pm-imx6.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 9244437cb1b9..63887ade411a 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -59,8 +59,11 @@
 #define MX6Q_SUSPEND_OCRAM_SIZE		0x1000
 #define MX6_MAX_MMDC_IO_NUM		33
 
+#define GIC_DIST_ENABLE_CLEAR		0x180
+
 static void __iomem *ccm_base;
 static void __iomem *suspend_ocram_base;
+static void __iomem *gic_raw_dist_base;
 static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
 
 /*
@@ -592,6 +595,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
 static void __init imx6_pm_common_init(const struct imx6_pm_socdata
 					*socdata)
 {
+	struct device_node *np;
 	struct regmap *gpr;
 	int ret;
 
@@ -615,10 +619,29 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
 	if (!IS_ERR(gpr))
 		regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
 				   IMX6Q_GPR1_GINT);
+
+	np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
+	gic_raw_dist_base = of_iomap(np, 0);
+}
+
+static void imx_gic_mask_all(void)
+{
+	int i;
+
+	if (WARN_ON(!gic_raw_dist_base))
+		return;
+
+	for (i = 0; i < 4; i++)
+		writel_relaxed(~0, gic_raw_dist_base + GIC_DIST_ENABLE_CLEAR + 4 * i);
 }
 
 static void imx6_pm_stby_poweroff(void)
 {
+	/*
+	 * A pending interrupt can prevent power off signal to be activated.
+	 * So, mask all interrupts to avoid it.
+	 */
+	imx_gic_mask_all();
 	imx6_set_lpm(STOP_POWER_OFF);
 	imx6q_suspend_finish(0);
 
-- 
2.30.2



From bigeasy at linutronix.de  Tue Aug 17 05:13:45 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Tue, 17 Aug 2021 14:13:45 +0200
Subject: [PATCH v3 1/4] rcutorture: Don't disable softirqs with
 preemption disabled when PREEMPT_RT
In-Reply-To: <20210811201354.1976839-2-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
Message-ID: <20210817121345.5iyj5epemczn3a52@linutronix.de>

On 2021-08-11 21:13:51 [+0100], Valentin Schneider wrote:
> Running RCU torture with CONFIG_PREEMPT_RT under v5.14-rc4-rt6 triggers:
> 
> [    8.755472] DEBUG_LOCKS_WARN_ON(this_cpu_read(softirq_ctrl.cnt))
> [    8.755482] WARNING: CPU: 1 PID: 137 at kernel/softirq.c:172 __local_bh_disable_ip (kernel/softirq.c:172 (discriminator 31))
> [    8.755500] Modules linked in:
> [    8.755506] CPU: 1 PID: 137 Comm: rcu_torture_rea Not tainted 5.14.0-rc4-rt6 #171
> [    8.755514] Hardware name: ARM Juno development board (r0) (DT)
> [    8.755518] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
> [    8.755622] Call trace:
> [    8.755624] __local_bh_disable_ip (kernel/softirq.c:172 (discriminator 31))
> [    8.755633] rcutorture_one_extend (kernel/rcu/rcutorture.c:1453)
> [    8.755640] rcu_torture_one_read (kernel/rcu/rcutorture.c:1601 kernel/rcu/rcutorture.c:1645)
> [    8.755645] rcu_torture_reader (kernel/rcu/rcutorture.c:1737)
> [    8.755650] kthread (kernel/kthread.c:327)
> [    8.755656] ret_from_fork (arch/arm64/kernel/entry.S:783)
> [    8.755663] irq event stamp: 11959
> [    8.755666] hardirqs last enabled at (11959): __rcu_read_unlock (kernel/rcu/tree_plugin.h:695 kernel/rcu/tree_plugin.h:451)
> [    8.755675] hardirqs last disabled at (11958): __rcu_read_unlock (kernel/rcu/tree_plugin.h:661 kernel/rcu/tree_plugin.h:451)
> [    8.755683] softirqs last enabled at (11950): __local_bh_enable_ip (./arch/arm64/include/asm/irqflags.h:85 kernel/softirq.c:261)
> [    8.755692] softirqs last disabled at (11942): rcutorture_one_extend (./include/linux/bottom_half.h:19 kernel/rcu/rcutorture.c:1441)
> 
> Per this warning, softirqs cannot be disabled in a non-preemptible region
> under CONFIG_PREEMPT_RT. Adjust RCU torture accordingly.
> 
> Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
> ---
>  kernel/rcu/rcutorture.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index eecd1caef71d..4f3db1d3170d 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -1548,6 +1548,8 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
>  	 * them on non-RT.
>  	 */
>  	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> +		/* Can't disable bh in atomic context under PREEMPT_RT */
> +		mask &= ~(RCUTORTURE_RDR_ATOM_BH | RCUTORTURE_RDR_ATOM_RBH);

Let me stare at this?

>  		/*
>  		 * Can't release the outermost rcu lock in an irq disabled
>  		 * section without preemption also being disabled, if irqs
> -- 
> 2.25.1

Sebastian


From Tudor.Ambarus at microchip.com  Tue Aug 17 05:15:57 2021
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Tue, 17 Aug 2021 12:15:57 +0000
Subject: [PATCH v2 17/35] mtd: spi-nor: Introduce
 spi_nor_nonsfdp_flags_init()
In-Reply-To: <20210817102429.kmhuef5hxumllxjj@ti.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-18-tudor.ambarus@microchip.com>
 <20210817102429.kmhuef5hxumllxjj@ti.com>
Message-ID: <93dc6aa7-fd6d-0659-2484-16bfd4bff402@microchip.com>

On 8/17/21 1:24 PM, Pratyush Yadav wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 27/07/21 07:52AM, Tudor Ambarus wrote:
>> Used to initialize the NOR flags for settings that are not defined
>> in the JESD216 SFDP standard, thus can not be retrieved when parsing
>> SFDP. No functional change.
> 
> I am worried if the order in which these flags are set can cause some
> subtle bugs.
> 
> I can see one instance of it with SNOR_F_HAS_LOCK.
> spi_nor_late_init_params() checks for SNOR_F_HAS_LOCK and if there are
> no locking ops specified, it sets the default locking ops. This works
> fine before this patch because the flag is set before the function is
> called. But now, the flag will be set _after_ the function is called,
> and so you will never be able to set the default flags.
> 
> This is one bug I can spot but I fear some others might be hiding
> somewhere as well. SPI NOR has accumulated a lot of spaghetti code over
> the years and I certainly felt it when working on my Octal DTR series.
> It caused an address width selection bug that was not obvious at all,
> and was not even caught during the rc cycles.
> 
> I think this series does clean up that spaghetti a lot. But you need to
> be careful of such bugs. I think you should definitely let this series
> cook in next for some time so it gets some exposure and hopefully some
> testing.
> 
>>
>> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
>> ---
>>  drivers/mtd/spi-nor/core.c | 88 ++++++++++++++++++++++----------------
>>  1 file changed, 52 insertions(+), 36 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
>> index 1f38fa8ab2fa..6a8617346764 100644
>> --- a/drivers/mtd/spi-nor/core.c
>> +++ b/drivers/mtd/spi-nor/core.c
>> @@ -2687,6 +2687,56 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
>>               spi_nor_init_default_locking_ops(nor);
>>  }
>>
>> +/**
>> + * spi_nor_nonsfdp_flags_init() - Initialize NOR flags for settings that are not
>> + * defined in the JESD216 SFDP standard, thus can not be retrieved when parsing
>> + * SFDP.
>> + * @nor:     pointer to a 'struct spi_nor'
>> + */
>> +static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
>> +{
>> +     const struct flash_info *info = nor->info;
>> +     struct device_node *np = spi_nor_get_flash_node(nor);
>> +
>> +     if (of_property_read_bool(np, "broken-flash-reset"))
>> +             nor->flags |= SNOR_F_BROKEN_RESET;
>> +
>> +     if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
>> +             nor->flags |= SNOR_F_SWP_IS_VOLATILE;
>> +
>> +     if (info->flags & SPI_NOR_HAS_LOCK)
>> +             nor->flags |= SNOR_F_HAS_LOCK;
> 
> As mentioned above, this would cause a bug.

Good catch!

> 
>> +
>> +     if (info->flags & SPI_NOR_HAS_TB) {
>> +             nor->flags |= SNOR_F_HAS_SR_TB;
>> +             if (info->flags & SPI_NOR_TB_SR_BIT6)
>> +                     nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
>> +     }
>> +
>> +     if (info->flags & SPI_NOR_4BIT_BP) {
>> +             nor->flags |= SNOR_F_HAS_4BIT_BP;
>> +             if (info->flags & SPI_NOR_BP3_SR_BIT6)
>> +                     nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
>> +     }
>> +
>> +     if (info->flags & NO_CHIP_ERASE)
>> +             nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
>> +
>> +     if (info->flags & USE_FSR)
>> +             nor->flags |= SNOR_F_USE_FSR;
>> +
>> +     if (info->flags & USE_CLSR)
>> +             nor->flags |= SNOR_F_USE_CLSR;
>> +
>> +     /*
>> +      * Make sure the XSR_RDY flag is set before calling
>> +      * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
>> +      * with Atmel SPI NOR.
>> +      */
>> +     if (info->flags & SPI_NOR_XSR_RDY)
>> +             nor->flags |=  SNOR_F_READY_XSR_RDY;
>> +}
>> +
>>  /**
>>   * spi_nor_init_params() - Initialize the flash's parameters and settings.
>>   * @nor:     pointer to a 'struct spi_nor'.
>> @@ -2736,6 +2786,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
>>
>>       spi_nor_late_init_params(nor);
>>
>> +     spi_nor_nonsfdp_flags_init(nor);
>> +
>>       return 0;
>>  }
>>
>> @@ -3078,7 +3130,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>>       const struct flash_info *info;
>>       struct device *dev = nor->dev;
>>       struct mtd_info *mtd = &nor->mtd;
>> -     struct device_node *np = spi_nor_get_flash_node(nor);
>>       int ret;
>>       int i;
>>
>> @@ -3115,17 +3166,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>>
>>       mutex_init(&nor->lock);
>>
>> -     /*
>> -      * Make sure the XSR_RDY flag is set before calling
>> -      * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
>> -      * with Atmel SPI NOR.
>> -      */
>> -     if (info->flags & SPI_NOR_XSR_RDY)
>> -             nor->flags |=  SNOR_F_READY_XSR_RDY;
>> -
>> -     if (info->flags & SPI_NOR_HAS_LOCK)
>> -             nor->flags |= SNOR_F_HAS_LOCK;
>> -
>>       mtd->_write = spi_nor_write;
>>
>>       /* Init flash parameters based on flash_info struct and SFDP */
>> @@ -3147,27 +3187,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>>       mtd->_get_device = spi_nor_get_device;
>>       mtd->_put_device = spi_nor_put_device;
>>
>> -     if (info->flags & USE_FSR)
>> -             nor->flags |= SNOR_F_USE_FSR;
>> -     if (info->flags & SPI_NOR_HAS_TB) {
>> -             nor->flags |= SNOR_F_HAS_SR_TB;
>> -             if (info->flags & SPI_NOR_TB_SR_BIT6)
>> -                     nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
>> -     }
>> -
>> -     if (info->flags & NO_CHIP_ERASE)
>> -             nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
>> -     if (info->flags & USE_CLSR)
>> -             nor->flags |= SNOR_F_USE_CLSR;
>> -     if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
>> -             nor->flags |= SNOR_F_SWP_IS_VOLATILE;
>> -
>> -     if (info->flags & SPI_NOR_4BIT_BP) {
>> -             nor->flags |= SNOR_F_HAS_4BIT_BP;
>> -             if (info->flags & SPI_NOR_BP3_SR_BIT6)
>> -                     nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
>> -     }
>> -
>>       if (info->flags & SPI_NOR_NO_ERASE)
>>               mtd->flags |= MTD_NO_ERASE;
>>
>> @@ -3175,9 +3194,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>>       nor->page_size = nor->params->page_size;
>>       mtd->writebufsize = nor->page_size;
>>
>> -     if (of_property_read_bool(np, "broken-flash-reset"))
>> -             nor->flags |= SNOR_F_BROKEN_RESET;
>> -
> 
> As I pointed out above, I think this patch is certainly going in the
> right direction. We just need to be careful of the bugs that slip
> through.

Right, I'll self review all once I'll prepare v3. And I'll redo the testing,
this time trying to cover all the flash info flags. Would be great if Michael,
Vignesh and others can have a look on the series too. With 2 or 3 persons reviewing
and better test coverage, we should be fine. Would be great if we can have
these cleaning patches without introducing regressions, but if we introduce it's not
a tragedy, we will fix all once reported.

Cheers,
ta


From p.yadav at ti.com  Tue Aug 17 05:16:28 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 17:46:28 +0530
Subject: [PATCH v2 18/35] mtd: spi-nor: Get rid of SPI_NOR_4B_OPCODES flag
In-Reply-To: <20210727045222.905056-19-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-19-tudor.ambarus@microchip.com>
Message-ID: <20210817121626.5vcwuluheqfqrqc3@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Get rid of flash_info flags that indicate settings which can be
> discovered when parsing SFDP. It will be clearer who sets what,
> and we'll restrict the flash settings that a developer can choose to
> only settings that are not SFDP discoverable.
> 
> Whether a flash supports 4byte opcodes or not, is discoverable when
> parsing the optional 4-byte address instruction table. Flashes that
> do not support the 4bait SFDP table should set the SNOR_F_4B_OPCODES
> flag in the late_init() call. Flashes that define the 4bait SFDP table
> but gets it wrong, should set the flag in a post_sfdp fixup hook.

I like the idea, not so much the execution. More on this below.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c       |  3 ---
>  drivers/mtd/spi-nor/core.h       | 32 ++++++++++++++++----------------
>  drivers/mtd/spi-nor/gigadevice.c |  7 ++++---
>  drivers/mtd/spi-nor/issi.c       | 12 ++++++------
>  drivers/mtd/spi-nor/macronix.c   | 18 ++++++++++--------
>  drivers/mtd/spi-nor/micron-st.c  | 22 +++++++++++++---------
>  drivers/mtd/spi-nor/spansion.c   | 12 ++++++------
>  7 files changed, 55 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 6a8617346764..240d5c31af88 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3204,9 +3204,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	if (ret)
>  		return ret;
>  
> -	if (info->flags & SPI_NOR_4B_OPCODES)
> -		nor->flags |= SNOR_F_4B_OPCODES;
> -
>  	if (info->flags & SPI_NOR_IO_MODE_EN_VOLATILE)
>  		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
>  
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 625f4eed75f1..dfdc51a26cad 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -348,40 +348,36 @@ struct flash_info {
>  					 * S3AN flashes have specific opcode to
>  					 * read the status register.
>  					 */
> -#define SPI_NOR_4B_OPCODES	BIT(11)	/*
> -					 * Use dedicated 4byte address op codes
> -					 * to support memory size above 128Mib.
> -					 */
> -#define NO_CHIP_ERASE		BIT(12) /* Chip does not support chip erase */
> -#define SPI_NOR_SKIP_SFDP	BIT(13)	/* Skip parsing of SFDP tables */
> -#define USE_CLSR		BIT(14)	/* use CLSR command */
> -#define SPI_NOR_OCTAL_READ	BIT(15)	/* Flash supports Octal Read */
> -#define SPI_NOR_TB_SR_BIT6	BIT(16)	/*
> +#define NO_CHIP_ERASE		BIT(11) /* Chip does not support chip erase */
> +#define SPI_NOR_SKIP_SFDP	BIT(12)	/* Skip parsing of SFDP tables */
> +#define USE_CLSR		BIT(13)	/* use CLSR command */
> +#define SPI_NOR_OCTAL_READ	BIT(14)	/* Flash supports Octal Read */
> +#define SPI_NOR_TB_SR_BIT6	BIT(15)	/*
>  					 * Top/Bottom (TB) is bit 6 of
>  					 * status register. Must be used with
>  					 * SPI_NOR_HAS_TB.
>  					 */
> -#define SPI_NOR_4BIT_BP		BIT(17) /*
> +#define SPI_NOR_4BIT_BP		BIT(16) /*
>  					 * Flash SR has 4 bit fields (BP0-3)
>  					 * for block protection.
>  					 */
> -#define SPI_NOR_BP3_SR_BIT6	BIT(18) /*
> +#define SPI_NOR_BP3_SR_BIT6	BIT(17) /*
>  					 * BP3 is bit 6 of status register.
>  					 * Must be used with SPI_NOR_4BIT_BP.
>  					 */
> -#define SPI_NOR_OCTAL_DTR_READ	BIT(19) /* Flash supports octal DTR Read. */
> -#define SPI_NOR_OCTAL_DTR_PP	BIT(20) /* Flash supports Octal DTR Page Program */
> -#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(21) /*
> +#define SPI_NOR_OCTAL_DTR_READ	BIT(18) /* Flash supports octal DTR Read. */
> +#define SPI_NOR_OCTAL_DTR_PP	BIT(19) /* Flash supports Octal DTR Page Program */
> +#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(20) /*
>  						 * Flash enables the best
>  						 * available I/O mode via a
>  						 * volatile bit.
>  						 */
> -#define SPI_NOR_SWP_IS_VOLATILE	BIT(22)	/*
> +#define SPI_NOR_SWP_IS_VOLATILE	BIT(21)	/*
>  					 * Flash has volatile software write
>  					 * protection bits. Usually these will
>  					 * power-up in a write-protected state.
>  					 */
> -#define SPI_NOR_PARSE_SFDP	BIT(23) /*
> +#define SPI_NOR_PARSE_SFDP	BIT(22) /*
>  					 * Flash initialized based on the SFDP
>  					 * tables.
>  					 */
> @@ -569,4 +565,8 @@ static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
>  	return mtd->priv;
>  }
>  
> +static inline void snor_f_4b_opcodes(struct spi_nor *nor)

Maybe snor_set_f_4b_opcodes()?

> +{
> +	nor->flags |= SNOR_F_4B_OPCODES;
> +}
>  #endif /* __LINUX_MTD_SPI_NOR_INTERNAL_H */
> diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c
> index 447d84bb2128..ff523fe734ef 100644
> --- a/drivers/mtd/spi-nor/gigadevice.c
> +++ b/drivers/mtd/spi-nor/gigadevice.c
> @@ -47,9 +47,10 @@ static const struct flash_info gigadevice_parts[] = {
>  			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
>  	{ "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,
>  			   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -			   SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK |
> -			   SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
> -		.fixups = &gd25q256_fixups },
> +			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
> +			   SPI_NOR_TB_SR_BIT6)
> +		.fixups = &gd25q256_fixups,
> +		.late_init = snor_f_4b_opcodes,	},
>  };
>  
>  const struct spi_nor_manufacturer spi_nor_gigadevice = {
> diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c
> index 1e5bb5408b68..aeff8f60cbae 100644
> --- a/drivers/mtd/spi-nor/issi.c
> +++ b/drivers/mtd/spi-nor/issi.c
> @@ -45,9 +45,9 @@ static const struct flash_info issi_parts[] = {
>  	{ "is25lp128",  INFO(0x9d6018, 0, 64 * 1024, 256,
>  			     SECT_4K | SPI_NOR_DUAL_READ) },
>  	{ "is25lp256",  INFO(0x9d6019, 0, 64 * 1024, 512,
> -			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -			     SPI_NOR_4B_OPCODES)
> -		.fixups = &is25lp256_fixups },
> +			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> +		.fixups = &is25lp256_fixups,
> +		.late_init = snor_f_4b_opcodes, },
>  	{ "is25wp032",  INFO(0x9d7016, 0, 64 * 1024,  64,
>  			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>  	{ "is25wp064",  INFO(0x9d7017, 0, 64 * 1024, 128,
> @@ -55,9 +55,9 @@ static const struct flash_info issi_parts[] = {
>  	{ "is25wp128",  INFO(0x9d7018, 0, 64 * 1024, 256,
>  			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>  	{ "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512,
> -			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -			    SPI_NOR_4B_OPCODES)
> -		.fixups = &is25lp256_fixups },
> +			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> +		.fixups = &is25lp256_fixups,
> +		.late_init = snor_f_4b_opcodes, },
>  
>  	/* PMC */
>  	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
> diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
> index fba85efafb47..9709eb68b613 100644
> --- a/drivers/mtd/spi-nor/macronix.c
> +++ b/drivers/mtd/spi-nor/macronix.c
> @@ -105,29 +105,31 @@ static const struct flash_info macronix_parts[] = {
>  	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512,
>  			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
>  		.fixups = &mx25l25635_fixups },
> -	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512,
> -			      SECT_4K | SPI_NOR_4B_OPCODES) },
> +	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K)
> +		.late_init = snor_f_4b_opcodes, },
>  	{ "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024,
>  			      SECT_4K | SPI_NOR_DUAL_READ |
> -			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> +			      SPI_NOR_QUAD_READ)
> +		.late_init = snor_f_4b_opcodes, },
>  	{ "mx25v8035f",  INFO(0xc22314, 0, 64 * 1024,  16,
>  			      SECT_4K | SPI_NOR_DUAL_READ |
>  			      SPI_NOR_QUAD_READ) },
>  	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
>  	{ "mx66l51235f", INFO(0xc2201a, 0, 64 * 1024, 1024,
> -			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -			      SPI_NOR_4B_OPCODES) },
> +			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> +		.late_init = snor_f_4b_opcodes, },
>  	{ "mx66u51235f", INFO(0xc2253a, 0, 64 * 1024, 1024,
>  			      SECT_4K | SPI_NOR_DUAL_READ |
> -			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> +			      SPI_NOR_QUAD_READ)
> +		.late_init = snor_f_4b_opcodes, },
>  	{ "mx66l1g45g",  INFO(0xc2201b, 0, 64 * 1024, 2048,
>  			      SECT_4K | SPI_NOR_DUAL_READ |
>  			      SPI_NOR_QUAD_READ) },
>  	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048,
>  			      SPI_NOR_QUAD_READ) },
>  	{ "mx66u2g45g",	 INFO(0xc2253c, 0, 64 * 1024, 4096,
> -			      SECT_4K | SPI_NOR_DUAL_READ |
> -			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> +			      SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> +		.late_init = snor_f_4b_opcodes, },
>  };
>  
>  static void macronix_default_init(struct spi_nor *nor)
> diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
> index c224e59820a1..72cc4673bf88 100644
> --- a/drivers/mtd/spi-nor/micron-st.c
> +++ b/drivers/mtd/spi-nor/micron-st.c
> @@ -121,13 +121,13 @@ static struct spi_nor_fixups mt35xu512aba_fixups = {
>  static const struct flash_info micron_parts[] = {
>  	{ "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512,
>  			       SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
> -			       SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ |
> -			       SPI_NOR_OCTAL_DTR_PP |
> +			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP |
>  			       SPI_NOR_IO_MODE_EN_VOLATILE)
> -	  .fixups = &mt35xu512aba_fixups},
> +	  .fixups = &mt35xu512aba_fixups,
> +	  .late_init = snor_f_4b_opcodes, },

This flash populated the 4BAIT table, so you can simply drop the flag. 
No need for the late_init().

This makes me think that many other flashes might also have the 4BAIT 
table but the developers chose to add this flag here since at that time 
the norm was to populate all flash capabilities. I think we could be 
able to drop many more .late_init like this. But unfortunately someone 
needs to do the hard work of checking each flash, and most flash 
datasheets don't even list the SFDP contents.

So while I think in the ideal world we would go check each flash, I 
think this is an acceptable compromise. Let's not let perfection be the 
enemy of good.

While we are on this topic, I find this a bit "ugly". Having to set 
late_init() for setting these flags for each flash is not exactly very 
clean or readable. I don't know how the future will look like, but if 
each flash/family needs its own late_init() to set some flags, it won't 
be very readable. We seem to be trading one type of complexity for 
another. I dunno which is the lesser evil though...

>  	{ "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048,
> -			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
> -			    SPI_NOR_4B_OPCODES) },
> +			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ)
> +	  .late_init = snor_f_4b_opcodes, },
>  };
>  
>  static const struct flash_info st_parts[] = {
> @@ -149,25 +149,29 @@ static const struct flash_info st_parts[] = {
>  			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>  	{ "mt25ql256a",  INFO6(0x20ba19, 0x104400, 64 * 1024,  512,
>  			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
> -			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> +			       SPI_NOR_QUAD_READ)
> +	  .late_init = snor_f_4b_opcodes, },
>  	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K |
>  			      USE_FSR | SPI_NOR_DUAL_READ |
>  			      SPI_NOR_QUAD_READ) },
>  	{ "mt25qu256a",  INFO6(0x20bb19, 0x104400, 64 * 1024,  512,
>  			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
> -			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> +			       SPI_NOR_QUAD_READ)
> +	  .late_init = snor_f_4b_opcodes, },
>  	{ "n25q256ax1",  INFO(0x20bb19, 0, 64 * 1024,  512,
>  			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>  	{ "mt25ql512a",  INFO6(0x20ba20, 0x104400, 64 * 1024, 1024,
>  			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
> -			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> +			       SPI_NOR_QUAD_READ)
> +	  .late_init = snor_f_4b_opcodes, },
>  	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024,
>  			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
>  			      SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
>  			      SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
>  	{ "mt25qu512a",  INFO6(0x20bb20, 0x104400, 64 * 1024, 1024,
>  			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
> -			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
> +			       SPI_NOR_QUAD_READ)
> +	  .late_init = snor_f_4b_opcodes, },
>  	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024,
>  			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
>  			      SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
> diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
> index aad7170768b4..af10833f56d8 100644
> --- a/drivers/mtd/spi-nor/spansion.c
> +++ b/drivers/mtd/spi-nor/spansion.c
> @@ -259,14 +259,14 @@ static const struct flash_info spansion_parts[] = {
>  	{ "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16,
>  			     SECT_4K | SPI_NOR_DUAL_READ) },
>  	{ "s25fl064l",  INFO(0x016017,      0,  64 * 1024, 128,
> -			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -			     SPI_NOR_4B_OPCODES) },
> +			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> +		.late_init = snor_f_4b_opcodes, },
>  	{ "s25fl128l",  INFO(0x016018,      0,  64 * 1024, 256,
> -			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -			     SPI_NOR_4B_OPCODES) },
> +			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> +		.late_init = snor_f_4b_opcodes, },
>  	{ "s25fl256l",  INFO(0x016019,      0,  64 * 1024, 512,
> -			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -			     SPI_NOR_4B_OPCODES) },
> +			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
> +		.late_init = snor_f_4b_opcodes, },
>  	{ "cy15x104q",  INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1,
>  			      SPI_NOR_NO_ERASE) },
>  	{ "s28hs512t",   INFO(0x345b1a,      0, 256 * 1024, 256,
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Tue Aug 17 05:21:11 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 17:51:11 +0530
Subject: [PATCH v2 19/35] mtd: spi-nor: Get rid of
 SPI_NOR_IO_MODE_EN_VOLATILE flag
In-Reply-To: <20210727045222.905056-20-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-20-tudor.ambarus@microchip.com>
Message-ID: <20210817122108.nr2elnkiyatdp2hz@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Get rid of flash_info flags that indicate settings which can be
> discovered when parsing SFDP. It will be clearer who sets what,
> and we'll restrict the flash settings that a developer can choose to
> only settings that are not SFDP discoverable.
> 
> SNOR_F_IO_MODE_EN_VOLATILE is discoverable when parsing the optional
> SCCR Map SFDP table. Flashes that do not define this table should set
> the flag in the late_init() call. Flashes that define the SFDP optional
> table but get the value wrong, should fix it in a post_sfdp fixup hook.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c      |  3 ---
>  drivers/mtd/spi-nor/core.h      |  9 ++-------
>  drivers/mtd/spi-nor/micron-st.c | 11 ++++++++---
>  3 files changed, 10 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 240d5c31af88..9885d434ea83 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3204,9 +3204,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	if (ret)
>  		return ret;
>  
> -	if (info->flags & SPI_NOR_IO_MODE_EN_VOLATILE)
> -		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
> -
>  	ret = spi_nor_set_addr_width(nor);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index dfdc51a26cad..987797a789c8 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -367,17 +367,12 @@ struct flash_info {
>  					 */
>  #define SPI_NOR_OCTAL_DTR_READ	BIT(18) /* Flash supports octal DTR Read. */
>  #define SPI_NOR_OCTAL_DTR_PP	BIT(19) /* Flash supports Octal DTR Page Program */
> -#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(20) /*
> -						 * Flash enables the best
> -						 * available I/O mode via a
> -						 * volatile bit.

We are losing the information contained in the comment. I think you 
should move it to SNOR_F_IO_MODE_EN_VOLATILE's declaration.

> -						 */
> -#define SPI_NOR_SWP_IS_VOLATILE	BIT(21)	/*
> +#define SPI_NOR_SWP_IS_VOLATILE	BIT(20)	/*
>  					 * Flash has volatile software write
>  					 * protection bits. Usually these will
>  					 * power-up in a write-protected state.
>  					 */
> -#define SPI_NOR_PARSE_SFDP	BIT(22) /*
> +#define SPI_NOR_PARSE_SFDP	BIT(21) /*
>  					 * Flash initialized based on the SFDP
>  					 * tables.
>  					 */
> diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
> index 72cc4673bf88..31ebd4c9b431 100644
> --- a/drivers/mtd/spi-nor/micron-st.c
> +++ b/drivers/mtd/spi-nor/micron-st.c
> @@ -118,13 +118,18 @@ static struct spi_nor_fixups mt35xu512aba_fixups = {
>  	.post_sfdp = mt35xu512aba_post_sfdp_fixup,
>  };
>  
> +static void mt35xu512aba_late_init(struct spi_nor *nor)
> +{
> +	nor->flags |= SNOR_F_4B_OPCODES;

Like I mentioned in the previous email, you can drop this since the 
flash populates the 4BAIT table.

> +	nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
> +}
> +
>  static const struct flash_info micron_parts[] = {
>  	{ "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512,
>  			       SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
> -			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP |
> -			       SPI_NOR_IO_MODE_EN_VOLATILE)
> +			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP)
>  	  .fixups = &mt35xu512aba_fixups,
> -	  .late_init = snor_f_4b_opcodes, },
> +	  .late_init = mt35xu512aba_late_init, },
>  	{ "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048,
>  			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ)
>  	  .late_init = snor_f_4b_opcodes, },

I forgot to say this in the previous email, but since this flash is the 
same family as the one above, it should also have the 4BAIT table, and 
should not need this late_init. But I don't have access to this part so 
I can't say with 100% certainty.

> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Tue Aug 17 05:23:37 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 17:53:37 +0530
Subject: [PATCH v2 20/35] mtd: spi-nor: core: Use container_of to get the
 pointer to struct spi_nor
In-Reply-To: <20210727045222.905056-21-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-21-tudor.ambarus@microchip.com>
Message-ID: <20210817122335.ci6ntkhmx4b6my46@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Get the pointer to the containing struct spi_nor by using container_of.

Please add an explanation on _why_ you are doing this. I suspect it 
would be something boring like "because mtd is embedded in nor, no need 
to use mtd->priv", but good to have it here regardless.

> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c | 1 -
>  drivers/mtd/spi-nor/core.h | 2 +-
>  2 files changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 9885d434ea83..5c8cffb5e6f2 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3175,7 +3175,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  
>  	if (!mtd->name)
>  		mtd->name = dev_name(dev);
> -	mtd->priv = nor;
>  	mtd->type = MTD_NORFLASH;
>  	mtd->writesize = nor->params->writesize;
>  	mtd->flags = MTD_CAP_NORFLASH;
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 987797a789c8..8fddc685d2d3 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -557,7 +557,7 @@ void spi_nor_otp_init(struct spi_nor *nor);
>  
>  static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
>  {
> -	return mtd->priv;
> +	return container_of(mtd, struct spi_nor, mtd);
>  }
>  
>  static inline void snor_f_4b_opcodes(struct spi_nor *nor)
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From o.rempel at pengutronix.de  Tue Aug 17 05:25:00 2021
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Tue, 17 Aug 2021 14:25:00 +0200
Subject: [PATCH v2] ARM: imx6: mask all interrupts before calling
 stby-poweroff sequence
Message-ID: <20210817122500.31953-1-o.rempel@pengutronix.de>

Any pending interrupt can prevent entering standby based power off state.
To avoid it, mask all interrupts.

Fixes: 8148d2136002 ("ARM: imx6: register pm_power_off handler if "fsl,pmic-stby-poweroff" is set")
Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 arch/arm/mach-imx/pm-imx6.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 9244437cb1b9..63887ade411a 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -59,8 +59,11 @@
 #define MX6Q_SUSPEND_OCRAM_SIZE		0x1000
 #define MX6_MAX_MMDC_IO_NUM		33
 
+#define GIC_DIST_ENABLE_CLEAR		0x180
+
 static void __iomem *ccm_base;
 static void __iomem *suspend_ocram_base;
+static void __iomem *gic_raw_dist_base;
 static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
 
 /*
@@ -592,6 +595,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
 static void __init imx6_pm_common_init(const struct imx6_pm_socdata
 					*socdata)
 {
+	struct device_node *np;
 	struct regmap *gpr;
 	int ret;
 
@@ -615,10 +619,29 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
 	if (!IS_ERR(gpr))
 		regmap_update_bits(gpr, IOMUXC_GPR1, IMX6Q_GPR1_GINT,
 				   IMX6Q_GPR1_GINT);
+
+	np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
+	gic_raw_dist_base = of_iomap(np, 0);
+}
+
+static void imx_gic_mask_all(void)
+{
+	int i;
+
+	if (WARN_ON(!gic_raw_dist_base))
+		return;
+
+	for (i = 0; i < 4; i++)
+		writel_relaxed(~0, gic_raw_dist_base + GIC_DIST_ENABLE_CLEAR + 4 * i);
 }
 
 static void imx6_pm_stby_poweroff(void)
 {
+	/*
+	 * A pending interrupt can prevent power off signal to be activated.
+	 * So, mask all interrupts to avoid it.
+	 */
+	imx_gic_mask_all();
 	imx6_set_lpm(STOP_POWER_OFF);
 	imx6q_suspend_finish(0);
 
-- 
2.30.2



From haibo.chen at nxp.com  Tue Aug 17 05:29:23 2021
From: haibo.chen at nxp.com (Bough Chen)
Date: Tue, 17 Aug 2021 12:29:23 +0000
Subject: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the auto-tuning
 setting for sdio device
In-Reply-To: <CAPDyKFpr9E6xxe2egiRGGWhUSY5aVr29rj1Hb_TwCzrY5bcvpg@mail.gmail.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <1629117508-4886-4-git-send-email-haibo.chen@nxp.com>
 <CAPDyKFpqTdKxFytQWo+TLJf+D=JYJo6B2aZDqOQc4+9_mbH40Q@mail.gmail.com>
 <VI1PR04MB52948F36F428AA3476A1F9D590FE9@VI1PR04MB5294.eurprd04.prod.outlook.com>
 <CAPDyKFpr9E6xxe2egiRGGWhUSY5aVr29rj1Hb_TwCzrY5bcvpg@mail.gmail.com>
Message-ID: <VI1PR04MB5294E39FDC07CD642315481A90FE9@VI1PR04MB5294.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> Sent: 2021?8?17? 16:01
> To: Bough Chen <haibo.chen at nxp.com>
> Cc: Adrian Hunter <adrian.hunter at intel.com>; Shawn Guo
> <shawnguo at kernel.org>; Rob Herring <robh+dt at kernel.org>; Sascha Hauer
> <s.hauer at pengutronix.de>; Sascha Hauer <kernel at pengutronix.de>; Fabio
> Estevam <festevam at gmail.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> dl-linux-imx <linux-imx at nxp.com>; DTML <devicetree at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>
> Subject: Re: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the auto-tuning
> setting for sdio device
> 
> On Tue, 17 Aug 2021 at 08:57, Bough Chen <haibo.chen at nxp.com> wrote:
> >
> > > -----Original Message-----
> > > From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> > > Sent: 2021?8?16? 21:53
> > > To: Bough Chen <haibo.chen at nxp.com>
> > > Cc: Adrian Hunter <adrian.hunter at intel.com>; Shawn Guo
> > > <shawnguo at kernel.org>; Rob Herring <robh+dt at kernel.org>; Sascha
> > > Hauer <s.hauer at pengutronix.de>; Sascha Hauer
> > > <kernel at pengutronix.de>; Fabio Estevam <festevam at gmail.com>;
> > > linux-mmc <linux-mmc at vger.kernel.org>; dl-linux-imx
> > > <linux-imx at nxp.com>; DTML <devicetree at vger.kernel.org>; Linux ARM
> > > <linux-arm-kernel at lists.infradead.org>
> > > Subject: Re: [PATCH 4/6] mmc: host: sdhci-esdhc-imx.c: correct the
> > > auto-tuning setting for sdio device
> > >
> > > On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
> > > >
> > > > From: Haibo Chen <haibo.chen at nxp.com>
> > > >
> > > > USDHC contain auto tuning circuit, this circuit will work
> > > > automatically after the tuning procedurae, it can
> > > > increase/decrease the delay cell according to the outside
> > > > environment change (like
> > > temperature).
> > > >
> > > > Unfortunately, this auto tuning circuit can not handle the async
> > > > sdio device interrupt correctly. When sdio device use 4 data line,
> > > > async sdio interrupt will use DAT[1], if we enable auto tuning
> > > > circuit check
> > > > 4 data lines, include the DAT[1], this circuit will detect this
> > > > interrupt, take this as a data on DAT[1], and adjust the delay cell wrongly.
> > > >
> > > > This is the hardware design limitation, to avoid this, when sdio
> > > > device enable async interrupt, auto tuning circuit only check
> > > > DAT[0] and CMD
> > > lines.
> > >
> > > SDIO irqs are being enabled/disabled dynamically in runtime by the
> > > mmc core via the host ops ->enable_sdio_irq().
> > >
> > > Rather than forcing the autotuning circuit to stay unused
> > > statically, perhaps an option would be to disable it when the SDIO
> > > irqs becomes enabled? Or maybe that becomes too complicated?
> >
> > For interrupt in 4-bit mode, there is a definition of interrupt
> > period, only in this period can the interrupt be detect and recognize. The
> interrupt period can exist during data transfer.
> >
> > So to fix this issue, one method is to disable auto tuning circuit.
> > Another is my current method, just detect CMD and DAT0, but at least auto
> tuning still can work (this method need board design keep align all data lines).
> 
> To allow DAT1 being used for SDIO irqs (async or not), the irqs needs to be
> enabled internally in the SDIO card first. This is done by writing to the CCCR
> register, which happens in sdio_claim_irq(). At this point in sdio_claim_irq() the
> core also invokes the
> ->enable_sdio_irq() host ops, to allow the host to prepare itself to
> accept SDIO irqs.
> 
> It sounds to me that you should be able to use the ->enable_sdio_irq ops, as a
> way of understanding that the auto-tuning feature also needs to be turned off,
> because it's not compatible with SDIO irqs.
> 

Yes, for current auto-tuning design, it need to be turned off for sdio interrupt.

I'm just a bit greedy, want to find a method to support auto-tuning for sdio interrupt. ?
I will use a new property like "fsl,broken-auto-tuning" for this WiFI device in V2 patch.

Best Regards
Haibo Chen.

> Kind regards
> Uffe
> 
> >
> >
> > Best Regards
> > Haibo chen
> >
> > >
> > > >
> > > > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> > > > ---
> > > >  drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++++++++++
> > > >  1 file changed, 18 insertions(+)
> > > >
> > > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > index f18d169bc8ff..ab84c29777e5 100644
> > > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > @@ -226,6 +226,7 @@ struct esdhc_platform_data {
> > > >         unsigned int tuning_step;       /* The delay cell steps in
> tuning
> > > procedure */
> > > >         unsigned int tuning_start_tap;  /* The start delay cell
> > > > point in
> > > tuning procedure */
> > > >         unsigned int strobe_dll_delay_target;   /* The delay cell for
> > > strobe pad (read clock) */
> > > > +       bool sdio_async_interrupt_enabled;      /* sdio device enable
> > > the async interrupt */
> > > >  };
> > > >
> > > >  struct esdhc_soc_data {
> > > > @@ -416,6 +417,8 @@ static inline void
> > > > esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
> > > >  /* Enable the auto tuning circuit to check the CMD line and BUS
> > > > line */  static inline void usdhc_auto_tuning_mode_sel(struct
> > > > sdhci_host
> > > > *host)  {
> > > > +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > > > +       struct pltfm_imx_data *imx_data =
> > > > + sdhci_pltfm_priv(pltfm_host);
> > > >         u32 buswidth, auto_tune_buswidth;
> > > >
> > > >         buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr +
> > > > SDHCI_HOST_CONTROL)); @@ -432,6 +435,18 @@ static inline void
> > > usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
> > > >                 break;
> > > >         }
> > > >
> > > > +       /*
> > > > +        * If sdio device use async interrupt, it will use DAT[1] to signal
> > > > +        * the device's interrupt asynchronous when use 4 data lines.
> > > > +        * Then hardware auto tuning circuit MUST NOT check the
> > > > + DAT[1]
> > > line,
> > > > +        * otherwise auto tuning will be impacted by this async
> interrupt,
> > > > +        * and change the delay cell incorrectly, which then cause
> > > data/cmd
> > > > +        * errors.
> > > > +        * This is the hardware auto tuning circuit limitation.
> > > > +        */
> > > > +       if (imx_data->boarddata.sdio_async_interrupt_enabled)
> > > > +               auto_tune_buswidth =
> > > > + ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;
> > > > +
> > > >         esdhc_clrset_le(host,
> > > ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
> > > >                         auto_tune_buswidth |
> > > ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
> > > >                         ESDHC_VEND_SPEC2); @@ -1531,6
> +1546,9
> > > @@
> > > > sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
> > > >         if (of_property_read_u32(np, "fsl,delay-line",
> > > &boarddata->delay_line))
> > > >                 boarddata->delay_line = 0;
> > > >
> > > > +       if (of_property_read_bool(np,
> > > > + "fsl,sdio-async-interrupt-enabled"))
> > >
> > > As stated on the DT patch, I think you can use the "cap-sdio-irq" instead.
> > >
> > > > +               boarddata->sdio_async_interrupt_enabled = true;
> > > > +
> > > >         mmc_of_parse_voltage(host->mmc, &host->ocr_mask);
> > > >
> > > >         if (esdhc_is_usdhc(imx_data) &&
> > > > !IS_ERR(imx_data->pinctrl)) {
> > > > --
> > > > 2.17.1
> > > >
> > >
> > > Kind regards
> > > Uffe

From l.stelmach at samsung.com  Tue Aug 17 05:34:56 2021
From: l.stelmach at samsung.com (Lukasz Stelmach)
Date: Tue, 17 Aug 2021 14:34:56 +0200
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to
 dtschema
In-Reply-To: <c3a1d7d2-7b32-b7eb-4647-f86e22f5e5ff@canonical.com> (Krzysztof
 Kozlowski's message of "Tue, 17 Aug 2021 12:05:20 +0200")
References: <c3a1d7d2-7b32-b7eb-4647-f86e22f5e5ff@canonical.com>
 <CGME20210817123507eucas1p120be1e5cc942e20bed39b6d810ccdbd1@eucas1p1.samsung.com>
Message-ID: <dleftj8s10fdvz.fsf%l.stelmach@samsung.com>

It was <2021-08-17 wto 12:05>, when Krzysztof Kozlowski wrote:
> On 17/08/2021 11:55, Lukasz Stelmach wrote:
>> It was <2021-08-11 ?ro 10:43>, when Krzysztof Kozlowski wrote:
>>> Convert Samsung Exynos SoC True Random Number Generator bindings to DT
>>> schema format using json-schema.
>>>
>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>> ---
>>>  .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
>>>  .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
>>>  MAINTAINERS                                   |  2 +-
>>>  3 files changed, 45 insertions(+), 18 deletions(-)
>>>  delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>  create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>> deleted file mode 100644
>>> index 5a613a4ec780..000000000000
>>> --- a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>> +++ /dev/null
>>> @@ -1,17 +0,0 @@
>>> -Exynos True Random Number Generator
>>> -
>>> -Required properties:
>>> -
>>> -- compatible  : Should be "samsung,exynos5250-trng".
>>> -- reg         : Specifies base physical address and size of the registers map.
>>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
>>> -- clock-names : "secss" as a clock name.
>>> -
>>> -Example:
>>> -
>>> -	rng at 10830600 {
>>> -		compatible = "samsung,exynos5250-trng";
>>> -		reg = <0x10830600 0x100>;
>>> -		clocks = <&clock CLK_SSS>;
>>> -		clock-names = "secss";
>>> -	};
>>> diff --git
>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>> new file mode 100644
>>> index 000000000000..a50c34d5d199
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>> @@ -0,0 +1,44 @@
>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id:
>>> https://protect2.fireeye.com/v1/url?k=f38ca35b-ac179a0d-f38d2814-0cc47a31ce52-1faa1ecb65482b8a&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Frng%2Fsamsung%2Cexynos5250-trng.yaml%23
>>> +$schema:
>>> https://protect2.fireeye.com/v1/url?k=9409519d-cb9268cb-9408dad2-0cc47a31ce52-12394c4409905980&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>>> +
>>> +title: Samsung Exynos SoC True Random Number Generator
>>> +
>>> +maintainers:
>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>> +  - ?ukasz Stelmach <l.stelmach at samsung.com>
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: samsung,exynos5250-trng
>>> +
>>> +  clocks:
>>> +    maxItems: 1
>> 
>> How about copying description from above into the description: property?
>
> But what to copy? There is no description except generic clock bindings.
>

The description that "was" in the txt file.

>> 
>>> +
>>> +  clock-names:
>>> +    items:
>>> +      - const: secss
>>> +
>>> +  reg:
>>> +    maxItems: 1
>> 
>> ditto.
>
> The same, I have no clue what to copy. It's obvious that reg contains
> "physical address and size of the registers map".
>
>
> Best regards,
> Krzysztof
>
>

-- 
?ukasz Stelmach
Samsung R&D Institute Poland
Samsung Electronics
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 487 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/213df834/attachment.sig>

From andriy.shevchenko at linux.intel.com  Tue Aug 17 05:45:13 2021
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Tue, 17 Aug 2021 15:45:13 +0300
Subject: [PATCH v4 1/4] clk: fractional-divider: Export approximation
 algorithm to the CCF users
In-Reply-To: <YRY+uoTrBjkdh4Zj@smile.fi.intel.com>
References: <20210812170025.67074-1-andriy.shevchenko@linux.intel.com>
 <162879819529.19113.6409882476721828944@swboyd.mtv.corp.google.com>
 <YRY+uoTrBjkdh4Zj@smile.fi.intel.com>
Message-ID: <YRuvWdI+M7JuKCPC@smile.fi.intel.com>

On Fri, Aug 13, 2021 at 12:43:22PM +0300, Andy Shevchenko wrote:
> On Thu, Aug 12, 2021 at 12:56:35PM -0700, Stephen Boyd wrote:
> > Quoting Andy Shevchenko (2021-08-12 10:00:22)
> > > At least one user currently duplicates some functions that are provided
> > > by fractional divider module. Let's export approximation algorithm and
> > > replace the open-coded variant.
> > > 
> > > As a bonus the exported function will get better documentation in place.
> > Applied to clk-next
> 
> Thank you, Stephen!

When they are expected to be visible in Linux Next?

-- 
With Best Regards,
Andy Shevchenko




From ronak.jain at xilinx.com  Tue Aug 17 06:05:50 2021
From: ronak.jain at xilinx.com (Ronak Jain)
Date: Tue, 17 Aug 2021 06:05:50 -0700
Subject: [PATCH 0/3] Add support for runtime features
Message-ID: <20210817130553.20219-1-ronak.jain@xilinx.com>

Adds support for runtime feature configuration by using the IOCTL
 calls. The user can enable or disable as well as can configure the
 runtime features. The support is added for the over temperature and
 external watchdog. The user can configure the over temperature limit
 and external watchdog timer interval at runtime by using PM_IOCTL
 calls.

Also, added support for sysfs interface for runtime feature
configuration for the over temperature and external watchdog features.

Ronak Jain (3):
  firmware: xilinx: Add support for runtime features
  firmware: zynqmp: Add sysfs entry for runtime features
  firmware: xilinx: Add sysfs support for feature config

 .../ABI/stable/sysfs-driver-firmware-zynqmp   | 84 ++++++++++++++++
 drivers/firmware/xilinx/zynqmp.c              | 98 +++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h          | 25 +++++
 3 files changed, 207 insertions(+)

--
2.32.0.93.g670b81a

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From ronak.jain at xilinx.com  Tue Aug 17 06:05:53 2021
From: ronak.jain at xilinx.com (Ronak Jain)
Date: Tue, 17 Aug 2021 06:05:53 -0700
Subject: [PATCH 3/3] firmware: xilinx: Add sysfs support for feature config
In-Reply-To: <20210817130553.20219-1-ronak.jain@xilinx.com>
References: <20210817130553.20219-1-ronak.jain@xilinx.com>
Message-ID: <20210817130553.20219-4-ronak.jain@xilinx.com>

This patch adds support for sysfs interface for runtime features
 configuration. The user can configure the features at runtime. First
 the user need to select the config id of the supported features and
 then the user can configure the parameters of the feature based on
 the config id. So far the support is added for the over temperature
 and external watchdog features.

Signed-off-by: Ronak Jain <ronak.jain at xilinx.com>
---
 drivers/firmware/xilinx/zynqmp.c | 71 ++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index e2b0a8fb6f44..4c5010899837 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1344,6 +1344,75 @@ static DEVICE_ATTR_RW(pggs1);
 static DEVICE_ATTR_RW(pggs2);
 static DEVICE_ATTR_RW(pggs3);

+static atomic_t feature_conf_id;
+
+static ssize_t feature_config_id_show(struct device *device,
+                                     struct device_attribute *attr,
+                                     char *buf)
+{
+       return sysfs_emit(buf, "%d\n", atomic_read(&feature_conf_id));
+}
+
+static ssize_t feature_config_id_store(struct device *device,
+                                      struct device_attribute *attr,
+                                      const char *buf, size_t count)
+{
+       u32 config_id;
+       int ret;
+
+       if (!buf)
+               return -EINVAL;
+
+       ret = kstrtou32(buf, 10, &config_id);
+       if (ret)
+               return ret;
+
+       atomic_set(&feature_conf_id, config_id);
+
+       return count;
+}
+
+static DEVICE_ATTR_RW(feature_config_id);
+
+static ssize_t feature_config_value_show(struct device *device,
+                                        struct device_attribute *attr,
+                                        char *buf)
+{
+       int ret;
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+
+       ret = zynqmp_pm_get_feature_config(atomic_read(&feature_conf_id),
+                                          ret_payload);
+       if (ret)
+               return ret;
+
+       return sysfs_emit(buf, "%d\n", ret_payload[1]);
+}
+
+static ssize_t feature_config_value_store(struct device *device,
+                                         struct device_attribute *attr,
+                                         const char *buf, size_t count)
+{
+       u32 value;
+       int ret;
+
+       if (!buf)
+               return -EINVAL;
+
+       ret = kstrtou32(buf, 10, &value);
+       if (ret)
+               return ret;
+
+       ret = zynqmp_pm_set_feature_config(atomic_read(&feature_conf_id),
+                                          value);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
+static DEVICE_ATTR_RW(feature_config_value);
+
 static struct attribute *zynqmp_firmware_attrs[] = {
        &dev_attr_ggs0.attr,
        &dev_attr_ggs1.attr,
@@ -1355,6 +1424,8 @@ static struct attribute *zynqmp_firmware_attrs[] = {
        &dev_attr_pggs3.attr,
        &dev_attr_shutdown_scope.attr,
        &dev_attr_health_status.attr,
+       &dev_attr_feature_config_id.attr,
+       &dev_attr_feature_config_value.attr,
        NULL,
 };

--
2.32.0.93.g670b81a

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From ronak.jain at xilinx.com  Tue Aug 17 06:05:51 2021
From: ronak.jain at xilinx.com (Ronak Jain)
Date: Tue, 17 Aug 2021 06:05:51 -0700
Subject: [PATCH 1/3] firmware: xilinx: Add support for runtime features
In-Reply-To: <20210817130553.20219-1-ronak.jain@xilinx.com>
References: <20210817130553.20219-1-ronak.jain@xilinx.com>
Message-ID: <20210817130553.20219-2-ronak.jain@xilinx.com>

Add support for runtime features by using an IOCTL call. The features
 can be enabled or disabled on the firmware as well as the features
 can configure at runtime by querying IOCTL_SET_FEATURE_CONFIG id.
 Similarly, the user can get the configured values of features by
 querying IOCTL_GET_FEATURE_CONFIG id. Here, we have added support for
 the over temperature and external watchdog features only.

Signed-off-by: Ronak Jain <ronak.jain at xilinx.com>
---
 drivers/firmware/xilinx/zynqmp.c     | 27 +++++++++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h | 25 +++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 15b138326ecc..e2b0a8fb6f44 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1049,6 +1049,33 @@ int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype)
                                   0, 0, NULL);
 }

+/**
+ * zynqmp_pm_set_feature_config - PM call to request IOCTL for feature config
+ * @id:         The config ID of the feature to be configured
+ * @value:      The config value of the feature to be configured
+ *
+ * Return:      Returns 0 on success or error value on failure.
+ */
+int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value)
+{
+       return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_FEATURE_CONFIG,
+                                  id, value, NULL);
+}
+
+/**
+ * zynqmp_pm_get_feature_config - PM call to get value of configured feature
+ * @id:         The config id of the feature to be queried
+ * @payload:    Returned value array
+ *
+ * Return:      Returns 0 on success or error value on failure.
+ */
+int zynqmp_pm_get_feature_config(enum pm_feature_config_id id,
+                                u32 *payload)
+{
+       return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_FEATURE_CONFIG,
+                                  id, 0, payload);
+}
+
 /**
  * struct zynqmp_pm_shutdown_scope - Struct for shutdown scope
  * @subtype:   Shutdown subtype
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 9d1a5c175065..06d82e334d2b 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -119,6 +119,9 @@ enum pm_ioctl_id {
        IOCTL_READ_PGGS = 15,
        /* Set healthy bit value */
        IOCTL_SET_BOOT_HEALTH_STATUS = 17,
+       /* Runtime feature configuration */
+       IOCTL_SET_FEATURE_CONFIG = 26,
+       IOCTL_GET_FEATURE_CONFIG = 27,
 };

 enum pm_query_id {
@@ -347,6 +350,14 @@ enum zynqmp_pm_shutdown_subtype {
        ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM = 2,
 };

+enum pm_feature_config_id {
+       PM_FEATURE_INVALID = 0,
+       PM_FEATURE_OVERTEMP_STATUS = 1,
+       PM_FEATURE_OVERTEMP_VALUE = 2,
+       PM_FEATURE_EXTWDT_STATUS = 3,
+       PM_FEATURE_EXTWDT_VALUE = 4,
+};
+
 /**
  * struct zynqmp_pm_query_data - PM query data
  * @qid:       query ID
@@ -411,6 +422,8 @@ int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param,
                                 u32 *value);
 int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
                                 u32 value);
+int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value);
+int zynqmp_pm_get_feature_config(enum pm_feature_config_id id, u32 *payload);
 #else
 static inline int zynqmp_pm_get_api_version(u32 *version)
 {
@@ -622,6 +635,18 @@ static inline int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
 {
        return -ENODEV;
 }
+
+static inline int zynqmp_pm_set_feature_config(enum pm_feature_config_id id,
+                                              u32 value)
+{
+       return -ENODEV;
+}
+
+static inline int zynqmp_pm_get_feature_config(enum pm_feature_config_id id,
+                                              u32 *payload)
+{
+       return -ENODEV;
+}
 #endif

 #endif /* __FIRMWARE_ZYNQMP_H__ */
--
2.32.0.93.g670b81a

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From ronak.jain at xilinx.com  Tue Aug 17 06:05:52 2021
From: ronak.jain at xilinx.com (Ronak Jain)
Date: Tue, 17 Aug 2021 06:05:52 -0700
Subject: [PATCH 2/3] firmware: zynqmp: Add sysfs entry for runtime features
In-Reply-To: <20210817130553.20219-1-ronak.jain@xilinx.com>
References: <20210817130553.20219-1-ronak.jain@xilinx.com>
Message-ID: <20210817130553.20219-3-ronak.jain@xilinx.com>

Create sysfs entry for runtime feature configuration. Here the support
 is added for an over temperature and external watchdog feature.

The below listed path is used for runtime features configuration:
/sys/devices/platform/firmware\:zynqmp-firmware/*

Here there are two files to configure features at runtime.
1. feature_config_id
2. feature_config_value

In order to configure an over temperature or external watchdog
 features, first the user need to select the valid config id and then
 the user can configure the value for selected feature config id.

Signed-off-by: Ronak Jain <ronak.jain at xilinx.com>
---
 .../ABI/stable/sysfs-driver-firmware-zynqmp   | 84 +++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-driver-firmware-zynqmp b/Documentation/ABI/stable/sysfs-driver-firmware-zynqmp
index f5724bb5b462..2fde354715a5 100644
--- a/Documentation/ABI/stable/sysfs-driver-firmware-zynqmp
+++ b/Documentation/ABI/stable/sysfs-driver-firmware-zynqmp
@@ -113,3 +113,87 @@ Description:
                    # echo 0 > /sys/devices/platform/firmware\:zynqmp-firmware/health_status

 Users:         Xilinx
+
+What:          /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_*
+Date:          Aug 2021
+KernelVersion: 5.14
+Contact:       "Ronak Jain" <ronak.jain at xilinx.com>
+Description:
+               This sysfs interface allows to configure features at runtime.
+               The user can enable or disable features running at firmware.
+               Also, the user can configure the parameters of the features
+               at runtime. The supported features are over temperature and
+               external watchdog. Here, the external watchdog is completely
+               different than the /dev/watchdog as the external watchdog is
+               running on the firmware and it is used to monitor the health
+               of firmware not APU(Linux). Also, the external watchdog is
+               interfaced outside of the zynqmp soc.
+
+               By default the features are disabled in the firmware. The user
+               can enable features by querying appropriate config id of the
+               features.
+
+               The default limit for the over temperature is 90 Degree Celsius.
+               The default timer interval for the external watchdog is 570ms.
+
+               The supported config ids are for the feature configuration is,
+               1. PM_FEATURE_OVERTEMP_STATUS = 1, the user can enable or
+               disable the over temperature feature.
+               2. PM_FEATURE_OVERTEMP_VALUE = 2, the user can configure the
+               over temperature limit in Degree Celsius.
+               3. PM_FEATURE_EXTWDT_STATUS = 3, the user can enable or disable
+               the external watchdog feature.
+               4. PM_FEATURE_EXTWDT_VALUE = 4, the user can configure the
+               external watchdog feature.
+
+               Usage:
+
+               Enable over temperature feature
+               # echo 1 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_id
+               # echo 1 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+
+               Check whether the over temperature feature is enabled or not
+               # cat /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+               The expected result is 1.
+
+               Disable over temperature feature
+               # echo 1 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_id
+               # echo 0 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+
+               Check whether the over temperature feature is disabled or not
+               # cat /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+               The expected result is 0.
+
+               Configure over temperature limit to 50 Degree Celsius
+               # echo 2 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_id
+               # echo 50 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+
+               Check whether the over temperature limit is configured or not
+               # cat /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+               The expected result is 50.
+
+               Enable external watchdog feature
+               # echo 3 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_id
+               # echo 1 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+
+               Check whether the external watchdog feature is enabled or not
+               # cat /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+               The expected result is 1.
+
+               Disable external watchdog feature
+               # echo 3 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_id
+               # echo 0 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+
+               Check whether the external watchdog feature is disabled or not
+               # cat /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+               The expected result is 0.
+
+               Configure external watchdog timer interval to 500ms
+               # echo 4 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_id
+               # echo 500 > /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+
+               Check whether the external watchdog timer interval is configured or not
+               # cat /sys/devices/platform/firmware\:zynqmp-firmware/feature_config_value
+               The expected result is 500.
+
+Users:         Xilinx
--
2.32.0.93.g670b81a

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From bigeasy at linutronix.de  Tue Aug 17 06:17:41 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Tue, 17 Aug 2021 15:17:41 +0200
Subject: [PATCH v3 1/4] rcutorture: Don't disable softirqs with
 preemption disabled when PREEMPT_RT
In-Reply-To: <20210817121345.5iyj5epemczn3a52@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
Message-ID: <20210817131741.evduh4fw7vyv2dzt@linutronix.de>

On 2021-08-17 14:13:47 [+0200], To Valentin Schneider wrote:
> > index eecd1caef71d..4f3db1d3170d 100644
> > --- a/kernel/rcu/rcutorture.c
> > +++ b/kernel/rcu/rcutorture.c
> > @@ -1548,6 +1548,8 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
> >  	 * them on non-RT.
> >  	 */
> >  	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> > +		/* Can't disable bh in atomic context under PREEMPT_RT */
> > +		mask &= ~(RCUTORTURE_RDR_ATOM_BH | RCUTORTURE_RDR_ATOM_RBH);
> 
> Let me stare at this?

I would fold this

--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1549,6 +1549,13 @@ rcutorture_extend_mask(int oldmask, stru
 	 */
 	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
 		/*
+		 * Can't disable bh in atomic context if bh was already
+		 * disabled by another task on the same CPU. Instead of
+		 * attempting to track this, just avoid disabling bh in atomic
+		 * context.
+		 */
+		mask &= ~atomic_bhs;
+		/*
 		 * Can't release the outermost rcu lock in an irq disabled
 		 * section without preemption also being disabled, if irqs
 		 * had ever been enabled during this RCU critical section
@@ -1559,16 +1566,6 @@ rcutorture_extend_mask(int oldmask, stru
 		    !(mask & preempts))
 			mask |= RCUTORTURE_RDR_RCU;
 
-		/* Can't modify atomic bh in non-atomic context */
-		if ((oldmask & atomic_bhs) && (mask & atomic_bhs) &&
-		    !(mask & preempts_irq)) {
-			mask |= oldmask & preempts_irq;
-			if (mask & RCUTORTURE_RDR_IRQ)
-				mask |= oldmask & tmp;
-		}
-		if ((mask & atomic_bhs) && !(mask & preempts_irq))
-			mask |= RCUTORTURE_RDR_PREEMPT;
-
 		/* Can't modify non-atomic bh in atomic context */
 		tmp = nonatomic_bhs;
 		if (oldmask & preempts_irq)

into the original patch and forward it upstream?

Sebastian


From robin.murphy at arm.com  Tue Aug 17 06:23:53 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 17 Aug 2021 14:23:53 +0100
Subject: [PATCH] iommu/arm-smmu-v3: Simplify useless instructions in
 arm_smmu_cmdq_build_cmd()
In-Reply-To: <20210817113450.2026-1-thunder.leizhen@huawei.com>
References: <20210817113450.2026-1-thunder.leizhen@huawei.com>
Message-ID: <6fea9ce0-7b8d-bd46-6b85-f3f9ba3ddd48@arm.com>

On 2021-08-17 12:34, Zhen Lei wrote:
> Although the parameter 'cmd' is always passed by a local array variable,
> and only this function modifies it, the compiler does not know this. The
> compiler almost always reads the value of cmd[i] from memory rather than
> directly using the value cached in the register. This generates many
> useless instruction operations and affects the performance to some extent.

Which compiler? GCC 4.9 does not make the same codegen decisions that 
GCC 10 does; Clang is different again. There are also various config 
options which affect a compiler's inlining/optimisation choices either 
directly or indirectly.

If it's something that newer compilers can get right anyway, then 
micro-optimising just for older ones might warrant a bit more justification.

> To guide the compiler for proper optimization, 'cmd' is defined as a local
> array variable, marked as register, and copied to the output parameter at
> a time when the function is returned.
> 
> The optimization effect can be viewed by running the "size arm-smmu-v3.o"
> command.
> 
> Before:
>     text    data     bss     dec     hex
>    27602    1348      56   29006    714e
> 
> After:
>     text    data     bss     dec     hex
>    27402    1348      56   28806    7086
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> ---
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++++---
>   1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index d76bbbde558b776..50a9db5bac466c7 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -233,11 +233,19 @@ static int queue_remove_raw(struct arm_smmu_queue *q, u64 *ent)
>   	return 0;
>   }
>   
> +#define arm_smmu_cmdq_copy_cmd(dst, src)	\
> +	do {					\
> +		dst[0] = src[0];		\
> +		dst[1] = src[1];		\
> +	} while (0)
> +
>   /* High-level queue accessors */
> -static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
> +static int arm_smmu_cmdq_build_cmd(u64 *out_cmd, struct arm_smmu_cmdq_ent *ent)
>   {
> -	memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
> -	cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
> +	register u64 cmd[CMDQ_ENT_DWORDS];
> +
> +	cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
> +	cmd[1] = 0;
>   
>   	switch (ent->opcode) {
>   	case CMDQ_OP_TLBI_EL2_ALL:
> @@ -309,6 +317,7 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
>   		case PRI_RESP_SUCC:
>   			break;
>   		default:
> +			arm_smmu_cmdq_copy_cmd(out_cmd, cmd);

Why bother writing back a partial command when we're telling the caller 
it's invalid anyway?

>   			return -EINVAL;
>   		}
>   		cmd[1] |= FIELD_PREP(CMDQ_PRI_1_RESP, ent->pri.resp);
> @@ -329,9 +338,12 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
>   		cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIATTR, ARM_SMMU_MEMATTR_OIWB);
>   		break;
>   	default:
> +		arm_smmu_cmdq_copy_cmd(out_cmd, cmd);

Ditto.

>   		return -ENOENT;
>   	}
>   
> +	arm_smmu_cmdq_copy_cmd(out_cmd, cmd);

...and then it would be simpler to open-code the assignment here.

I guess if you're really concerned with avoiding temporary commands 
being written back to the stack and reloaded, it might be worth 
experimenting with wrapping them in a struct which can be passed around 
by value - AAPCS64 allows passing a 16-byte composite type purely in 
registers.

Robin.

> +
>   	return 0;
>   }
>   
> 


From lkp at intel.com  Tue Aug 17 06:39:34 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 17 Aug 2021 21:39:34 +0800
Subject: [PATCH 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
References: <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
Message-ID: <202108172131.wJduPew3-lkp@intel.com>

Hi Nicolas,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on rockchip/for-next]
[also build test ERROR on asoc/for-next sound/for-next v5.14-rc6 next-20210816]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Nicolas-Frattaroli/Rockchip-I2S-TDM-controller/20210817-181921
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next
config: m68k-allmodconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/3b075f992be5028cbbe3ab1fbdf95bb63bbdac0c
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Nicolas-Frattaroli/Rockchip-I2S-TDM-controller/20210817-181921
        git checkout 3b075f992be5028cbbe3ab1fbdf95bb63bbdac0c
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   sound/soc/rockchip/rockchip_i2s_tdm.c: In function 'rockchip_snd_xfer_reset_assert':
>> sound/soc/rockchip/rockchip_i2s_tdm.c:198:25: error: implicit declaration of function 'writeq'; did you mean 'writel'? [-Werror=implicit-function-declaration]
     198 |                         writeq(val, addr);
         |                         ^~~~~~
         |                         writel
   cc1: some warnings being treated as errors


vim +198 sound/soc/rockchip/rockchip_i2s_tdm.c

2a497b883a8aaf Nicolas Frattaroli 2021-08-17  167  
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  168  static void rockchip_snd_xfer_reset_assert(struct rk_i2s_tdm_dev *i2s_tdm,
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  169  					   int tx_bank, int tx_offset,
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  170  					   int rx_bank, int rx_offset)
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  171  {
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  172  	void __iomem *cru_reset, *addr;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  173  	unsigned long flags;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  174  	u64 val;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  175  
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  176  	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  177  
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  178  	switch (abs(tx_bank - rx_bank)) {
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  179  	case 0:
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  180  		writel(BIT(tx_offset) | BIT(rx_offset) |
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  181  		       (BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  182  		       cru_reset + (tx_bank * 4));
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  183  		break;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  184  	case 1:
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  185  		if (tx_bank < rx_bank) {
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  186  			val = BIT(rx_offset) | (BIT(rx_offset) << 16);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  187  			val <<= 32;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  188  			val |= BIT(tx_offset) | (BIT(tx_offset) << 16);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  189  			addr = cru_reset + (tx_bank * 4);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  190  		} else {
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  191  			val = BIT(tx_offset) | (BIT(tx_offset) << 16);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  192  			val <<= 32;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  193  			val |= BIT(rx_offset) | (BIT(rx_offset) << 16);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  194  			addr = cru_reset + (rx_bank * 4);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  195  		}
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  196  
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  197  		if (IS_ALIGNED((uintptr_t)addr, 8)) {
2a497b883a8aaf Nicolas Frattaroli 2021-08-17 @198  			writeq(val, addr);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  199  			break;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  200  		}
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  201  		fallthrough;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  202  	default:
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  203  		local_irq_save(flags);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  204  		writel(BIT(tx_offset) | (BIT(tx_offset) << 16),
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  205  		       cru_reset + (tx_bank * 4));
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  206  		writel(BIT(rx_offset) | (BIT(rx_offset) << 16),
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  207  		       cru_reset + (rx_bank * 4));
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  208  		local_irq_restore(flags);
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  209  		break;
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  210  	}
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  211  }
2a497b883a8aaf Nicolas Frattaroli 2021-08-17  212  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 60695 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/ddade1d3/attachment-0001.gz>

From qwandor at google.com  Tue Aug 17 06:53:11 2021
From: qwandor at google.com (Andrew Walbran)
Date: Tue, 17 Aug 2021 14:53:11 +0100
Subject: [PATCH v4 04/21] KVM: arm64: Introduce helper to retrieve a PTE
 and its level
In-Reply-To: <20210809152448.1810400-5-qperret@google.com>
References: <20210809152448.1810400-1-qperret@google.com>
 <20210809152448.1810400-5-qperret@google.com>
Message-ID: <CA+_y_2EsStP+zNOfykjrmJBx6a1pxaewC2X9TnXnj3kNpixsWg@mail.gmail.com>

On Mon, 9 Aug 2021 at 16:25, Quentin Perret <qperret at google.com> wrote:
>
> From: Marc Zyngier <maz at kernel.org>
>
> It is becoming a common need to fetch the PTE for a given address
> together with its level. Add such a helper.
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Signed-off-by: Quentin Perret <qperret at google.com>
> ---
>  arch/arm64/include/asm/kvm_pgtable.h | 19 ++++++++++++++
>  arch/arm64/kvm/hyp/pgtable.c         | 39 ++++++++++++++++++++++++++++
>  2 files changed, 58 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
> index f004c0115d89..082b9d65f40b 100644
> --- a/arch/arm64/include/asm/kvm_pgtable.h
> +++ b/arch/arm64/include/asm/kvm_pgtable.h
> @@ -432,6 +432,25 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size);
>  int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
>                      struct kvm_pgtable_walker *walker);
>
> +/**
> + * kvm_pgtable_get_leaf() - Walk a page-table and retrieve the leaf entry
> + *                         with its level.
> + * @pgt:       Page-table structure initialised by kvm_pgtable_*_init().
> + * @addr:      Input address for the start of the walk.
> + * @ptep:      Pointer to storage for the retrieved PTE.
> + * @level:     Pointer to storage for the level of the retrieved PTE.
> + *
> + * The offset of @addr within a page is ignored.
> + *
> + * The walker will walk the page-table entries corresponding to the input
> + * address specified, retrieving the leaf corresponding to this address.
> + * Invalid entries are treated as leaf entries.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
> +                        kvm_pte_t *ptep, u32 *level);
> +
>  /**
>   * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical
>   *                                  Addresses with compatible permission
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 05321f4165e3..78f36bd5df6c 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -326,6 +326,45 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
>         return _kvm_pgtable_walk(&walk_data);
>  }
>
> +struct leaf_walk_data {
> +       kvm_pte_t       pte;
> +       u32             level;
> +};
> +
> +static int leaf_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
> +                      enum kvm_pgtable_walk_flags flag, void * const arg)
> +{
> +       struct leaf_walk_data *data = arg;
> +
> +       data->pte   = *ptep;
> +       data->level = level;
> +
> +       return 0;
> +}
> +
> +int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr,
> +                        kvm_pte_t *ptep, u32 *level)
> +{
> +       struct leaf_walk_data data;
> +       struct kvm_pgtable_walker walker = {
> +               .cb     = leaf_walker,
> +               .flags  = KVM_PGTABLE_WALK_LEAF,
> +               .arg    = &data,
> +       };
> +       int ret;
> +
> +       ret = kvm_pgtable_walk(pgt, ALIGN_DOWN(addr, PAGE_SIZE),
> +                              PAGE_SIZE, &walker);
> +       if (!ret) {
> +               if (ptep)
> +                       *ptep  = data.pte;
> +               if (level)
> +                       *level = data.level;
> +       }
> +
> +       return ret;
> +}
> +
>  struct hyp_map_data {
>         u64                             phys;
>         kvm_pte_t                       attr;
> --
> 2.32.0.605.g8dce9f2422-goog
>

Reviewed-by: Andrew Walbran <qwandor at google.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3998 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/2e213543/attachment.p7s>

From krzysztof.kozlowski at canonical.com  Tue Aug 17 07:07:20 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 17 Aug 2021 16:07:20 +0200
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to
 dtschema
In-Reply-To: <dleftj8s10fdvz.fsf%l.stelmach@samsung.com>
References: <c3a1d7d2-7b32-b7eb-4647-f86e22f5e5ff@canonical.com>
 <CGME20210817123507eucas1p120be1e5cc942e20bed39b6d810ccdbd1@eucas1p1.samsung.com>
 <dleftj8s10fdvz.fsf%l.stelmach@samsung.com>
Message-ID: <da43d243-35b0-2cc6-f8a0-a5d02c997301@canonical.com>

On 17/08/2021 14:34, Lukasz Stelmach wrote:
> It was <2021-08-17 wto 12:05>, when Krzysztof Kozlowski wrote:
>> On 17/08/2021 11:55, Lukasz Stelmach wrote:
>>> It was <2021-08-11 ?ro 10:43>, when Krzysztof Kozlowski wrote:
>>>> Convert Samsung Exynos SoC True Random Number Generator bindings to DT
>>>> schema format using json-schema.
>>>>
>>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>> ---
>>>>  .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
>>>>  .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
>>>>  MAINTAINERS                                   |  2 +-
>>>>  3 files changed, 45 insertions(+), 18 deletions(-)
>>>>  delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>  create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>
>>>> diff --git
>>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>> deleted file mode 100644
>>>> index 5a613a4ec780..000000000000
>>>> --- a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>> +++ /dev/null
>>>> @@ -1,17 +0,0 @@
>>>> -Exynos True Random Number Generator
>>>> -
>>>> -Required properties:
>>>> -
>>>> -- compatible  : Should be "samsung,exynos5250-trng".
>>>> -- reg         : Specifies base physical address and size of the registers map.
>>>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
>>>> -- clock-names : "secss" as a clock name.
>>>> -
>>>> -Example:
>>>> -
>>>> -	rng at 10830600 {
>>>> -		compatible = "samsung,exynos5250-trng";
>>>> -		reg = <0x10830600 0x100>;
>>>> -		clocks = <&clock CLK_SSS>;
>>>> -		clock-names = "secss";
>>>> -	};
>>>> diff --git
>>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>> new file mode 100644
>>>> index 000000000000..a50c34d5d199
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>> @@ -0,0 +1,44 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id:
>>>> https://protect2.fireeye.com/v1/url?k=f38ca35b-ac179a0d-f38d2814-0cc47a31ce52-1faa1ecb65482b8a&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Frng%2Fsamsung%2Cexynos5250-trng.yaml%23
>>>> +$schema:
>>>> https://protect2.fireeye.com/v1/url?k=9409519d-cb9268cb-9408dad2-0cc47a31ce52-12394c4409905980&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>>>> +
>>>> +title: Samsung Exynos SoC True Random Number Generator
>>>> +
>>>> +maintainers:
>>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>> +  - ?ukasz Stelmach <l.stelmach at samsung.com>
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    const: samsung,exynos5250-trng
>>>> +
>>>> +  clocks:
>>>> +    maxItems: 1
>>>
>>> How about copying description from above into the description: property?
>>
>> But what to copy? There is no description except generic clock bindings.
>>
> 
> The description that "was" in the txt file.

But there was no description of fields except copy&paste of the core
schema. Do you describe C code like:

...
/* unsigned int is a integer number greater or equal 0 */
unsigned int i;
...


Best regards,
Krzysztof


From nicolas at ndufresne.ca  Tue Aug 17 07:22:20 2021
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Tue, 17 Aug 2021 10:22:20 -0400
Subject: [PATCH v13 2/9] media: hevc: Add decode params control
In-Reply-To: <h8e2hgh73r8lqgr8lgmuobubj2jcdg6mv5@4ax.com>
References: <20210603115004.915294-1-benjamin.gaignard@collabora.com>
 <20210603115004.915294-3-benjamin.gaignard@collabora.com>
 <h8e2hgh73r8lqgr8lgmuobubj2jcdg6mv5@4ax.com>
Message-ID: <8aa297e9c71ea74804824214e9d3c8a8d2b015e2.camel@ndufresne.ca>

Le lundi 09 ao?t 2021 ? 15:29 +0100, John Cox a ?crit?:
> Hi
> 
> > Add decode params control and the associated structure to group
> > all the information that are needed to decode a reference frame as
> > is described in ITU-T Rec. H.265 section "8.3.2 Decoding process
> > for reference picture set".
> 
> I'm sorry I'm commenting late but I've only just got round to
> implementing code based on this.
> 
> > Adapt Cedrus driver to these changes.
> > 
> > Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
> > Reviewed-by: Ezequiel Garcia <ezequiel at collabora.com>
> > ---
> > version 11:
> > - Split what was done in v4l2-ctrls.c in v4l2-ctrls-core.c and v4l2-ctrls-defs.c
> > 
> > .../media/v4l/ext-ctrls-codec.rst             | 94 +++++++++++++++----
> > .../media/v4l/vidioc-queryctrl.rst            |  6 ++
> > drivers/media/v4l2-core/v4l2-ctrls-core.c     | 21 +++--
> > drivers/media/v4l2-core/v4l2-ctrls-defs.c     |  4 +
> > drivers/staging/media/sunxi/cedrus/cedrus.c   |  6 ++
> > drivers/staging/media/sunxi/cedrus/cedrus.h   |  1 +
> > .../staging/media/sunxi/cedrus/cedrus_dec.c   |  2 +
> > .../staging/media/sunxi/cedrus/cedrus_h265.c  | 12 ++-
> > include/media/hevc-ctrls.h                    | 29 ++++--
> > 9 files changed, 136 insertions(+), 39 deletions(-)
> > 
> > diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> > index 9cfb471fc6be..9120c5bcaf90 100644
> > --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> > +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> > @@ -2997,9 +2997,6 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
> >     * - __u8
> >       - ``pic_struct``
> >       -
> > -    * - __u8
> > -      - ``num_active_dpb_entries``
> > -      - The number of entries in ``dpb``.
> >     * - __u8
> >       - ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
> >       - The list of L0 reference elements as indices in the DPB.
> > @@ -3007,22 +3004,8 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
> >       - ``ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
> >       - The list of L1 reference elements as indices in the DPB.
> >     * - __u8
> > -      - ``num_rps_poc_st_curr_before``
> > -      - The number of reference pictures in the short-term set that come before
> > -        the current frame.
> > -    * - __u8
> > -      - ``num_rps_poc_st_curr_after``
> > -      - The number of reference pictures in the short-term set that come after
> > -        the current frame.
> > -    * - __u8
> > -      - ``num_rps_poc_lt_curr``
> > -      - The number of reference pictures in the long-term set.
> > -    * - __u8
> > -      - ``padding[7]``
> > +      - ``padding``
> >       - Applications and drivers must set this to zero.
> > -    * - struct :c:type:`v4l2_hevc_dpb_entry`
> > -      - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
> > -      - The decoded picture buffer, for meta-data about reference frames.
> >     * - struct :c:type:`v4l2_hevc_pred_weight_table`
> >       - ``pred_weight_table``
> >       - The prediction weight coefficients for inter-picture prediction.
> > @@ -3278,3 +3261,78 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
> >     encoding the next frame queued after setting this control.
> >     This provides a bitmask which consists of bits [0, LTR_COUNT-1].
> >     This is applicable to the H264 and HEVC encoders.
> > +
> > +``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (struct)``
> > +    Specifies various decode parameters, especially the references picture order
> > +    count (POC) for all the lists (short, long, before, current, after) and the
> > +    number of entries for each of them.
> > +    These parameters are defined according to :ref:`hevc`.
> > +    They are described in section 8.3 "Slice decoding process" of the
> > +    specification.
> > +
> > +.. c:type:: v4l2_ctrl_hevc_decode_params
> > +
> > +.. cssclass:: longtable
> > +
> > +.. flat-table:: struct v4l2_ctrl_hevc_decode_params
> > +    :header-rows:  0
> > +    :stub-columns: 0
> > +    :widths:       1 1 2
> > +
> > +    * - __s32
> > +      - ``pic_order_cnt_val``
> > +      - PicOrderCntVal as described in section 8.3.1 "Decoding process
> > +        for picture order count" of the specification.
> > +    * - __u8
> > +      - ``num_active_dpb_entries``
> > +      - The number of entries in ``dpb``.
> > +    * - struct :c:type:`v4l2_hevc_dpb_entry`
> > +      - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
> > +      - The decoded picture buffer, for meta-data about reference frames.
> > +    * - __u8
> > +      - ``num_poc_st_curr_before``
> > +      - The number of reference pictures in the short-term set that come before
> > +        the current frame.
> > +    * - __u8
> > +      - ``num_poc_st_curr_after``
> > +      - The number of reference pictures in the short-term set that come after
> > +        the current frame.
> > +    * - __u8
> > +      - ``num_poc_lt_curr``
> > +      - The number of reference pictures in the long-term set.
> > +    * - __u8
> > +      - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
> > +      - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
> > +        picture set.
> > +    * - __u8
> > +      - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
> > +      - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
> > +        picture set.
> > +    * - __u8
> > +      - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
> > +      - PocLtCurr as described in section 8.3.2 "Decoding process for reference
> > +        picture set.
> 
> Two things here
> 
> 1) By my understanding poc_st_curr_before/after & poc_lt_curr attempt to
> hold a POC (as per 8.3.2). That is a 32bit signed value not U8.  You can
> get away with U16 if you mask & sign extend your comparisions but U8 I'm
> pretty sure is too small.
> 
> 2) I think you can calculate these list from the info in the DPB
> structure. Certainly v4l2_hevc_dpb_entry.rps contains which list every
> entry is in.

Putting my userspace guy hat, we calculate these lists separately in userspace,
because we need them, we do some extra effort to mark them into the DPB entry
flags. I believe there is a redundancy issue in the uAPI too with this version.
But it would be nice if we didn't have to translate twice.

> 
> Regards
> 
> John Cox
> 
> 
> > +    * - __u64
> > +      - ``flags``
> > +      - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
> > +
> > +.. _hevc_decode_params_flags:
> > +
> > +``Decode Parameters Flags``
> > +
> > +.. cssclass:: longtable
> > +
> > +.. flat-table::
> > +    :header-rows:  0
> > +    :stub-columns: 0
> > +    :widths:       1 1 2
> > +
> > +    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC``
> > +      - 0x00000001
> > +      -
> > +    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC``
> > +      - 0x00000002
> > +      -
> > +    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR``
> > +      - 0x00000004
> > +      -
> > diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> > index 07e54029e1e9..f9ecf6276129 100644
> > --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> > +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> > @@ -501,6 +501,12 @@ See also the examples in :ref:`control`.
> >       - n/a
> >       - A struct :c:type:`v4l2_ctrl_vp8_frame`, containing VP8
> > 	frame parameters for stateless video decoders.
> > +    * - ``V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS``
> > +      - n/a
> > +      - n/a
> > +      - n/a
> > +      - A struct :c:type:`v4l2_ctrl_hevc_decode_params`, containing HEVC
> > +	decoding parameters for stateless video decoders.
> > 
> > .. raw:: latex
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > index 081439224357..c4b5082849b6 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > @@ -337,6 +337,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
> > 	struct v4l2_ctrl_hevc_pps *p_hevc_pps;
> > 	struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
> > 	struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
> > +	struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params;
> > 	struct v4l2_area *area;
> > 	void *p = ptr.p + idx * ctrl->elem_size;
> > 	unsigned int i;
> > @@ -616,23 +617,26 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
> > 		zero_padding(*p_hevc_pps);
> > 		break;
> > 
> > -	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> > -		p_hevc_slice_params = p;
> > +	case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
> > +		p_hevc_decode_params = p;
> > 
> > -		if (p_hevc_slice_params->num_active_dpb_entries >
> > +		if (p_hevc_decode_params->num_active_dpb_entries >
> > 		    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
> > 			return -EINVAL;
> > 
> > -		zero_padding(p_hevc_slice_params->pred_weight_table);
> > -
> > -		for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries;
> > +		for (i = 0; i < p_hevc_decode_params->num_active_dpb_entries;
> > 		     i++) {
> > 			struct v4l2_hevc_dpb_entry *dpb_entry =
> > -				&p_hevc_slice_params->dpb[i];
> > +				&p_hevc_decode_params->dpb[i];
> > 
> > 			zero_padding(*dpb_entry);
> > 		}
> > +		break;
> > 
> > +	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> > +		p_hevc_slice_params = p;
> > +
> > +		zero_padding(p_hevc_slice_params->pred_weight_table);
> > 		zero_padding(*p_hevc_slice_params);
> > 		break;
> > 
> > @@ -1236,6 +1240,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
> > 	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> > 		elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
> > 		break;
> > +	case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
> > +		elem_size = sizeof(struct v4l2_ctrl_hevc_decode_params);
> > +		break;
> > 	case V4L2_CTRL_TYPE_HDR10_CLL_INFO:
> > 		elem_size = sizeof(struct v4l2_ctrl_hdr10_cll_info);
> > 		break;
> > diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> > index 7963c7b43450..b6344bbf1e00 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> > @@ -996,6 +996,7 @@ const char *v4l2_ctrl_get_name(u32 id)
> > 	case V4L2_CID_MPEG_VIDEO_HEVC_SPS:			return "HEVC Sequence Parameter Set";
> > 	case V4L2_CID_MPEG_VIDEO_HEVC_PPS:			return "HEVC Picture Parameter Set";
> > 	case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:		return "HEVC Slice Parameters";
> > +	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:		return "HEVC Decode Parameters";
> > 	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:		return "HEVC Decode Mode";
> > 	case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:		return "HEVC Start Code";
> > 
> > @@ -1487,6 +1488,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
> > 	case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
> > 		*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
> > 		break;
> > +	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:
> > +		*type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS;
> > +		break;
> > 	case V4L2_CID_UNIT_CELL_SIZE:
> > 		*type = V4L2_CTRL_TYPE_AREA;
> > 		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
> > index fa348c09f844..c0d005dafc6c 100644
> > --- a/drivers/staging/media/sunxi/cedrus/cedrus.c
> > +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
> > @@ -157,6 +157,12 @@ static const struct cedrus_control cedrus_controls[] = {
> > 		},
> > 		.codec		= CEDRUS_CODEC_VP8,
> > 	},
> > +	{
> > +		.cfg = {
> > +			.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS,
> > +		},
> > +		.codec		= CEDRUS_CODEC_H265,
> > +	},
> > };
> > 
> > #define CEDRUS_CONTROLS_COUNT	ARRAY_SIZE(cedrus_controls)
> > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
> > index bbcdcd0787cf..88afba17b78b 100644
> > --- a/drivers/staging/media/sunxi/cedrus/cedrus.h
> > +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
> > @@ -77,6 +77,7 @@ struct cedrus_h265_run {
> > 	const struct v4l2_ctrl_hevc_sps			*sps;
> > 	const struct v4l2_ctrl_hevc_pps			*pps;
> > 	const struct v4l2_ctrl_hevc_slice_params	*slice_params;
> > +	const struct v4l2_ctrl_hevc_decode_params	*decode_params;
> > };
> > 
> > struct cedrus_vp8_run {
> > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> > index 97e410d92506..40e8c4123f76 100644
> > --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> > @@ -70,6 +70,8 @@ void cedrus_device_run(void *priv)
> > 			V4L2_CID_MPEG_VIDEO_HEVC_PPS);
> > 		run.h265.slice_params = cedrus_find_control_data(ctx,
> > 			V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
> > +		run.h265.decode_params = cedrus_find_control_data(ctx,
> > +			V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS);
> > 		break;
> > 
> > 	case V4L2_PIX_FMT_VP8_FRAME:
> > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
> > index 10744fab7cea..6821e3d05d34 100644
> > --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
> > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
> > @@ -245,6 +245,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> > 	const struct v4l2_ctrl_hevc_sps *sps;
> > 	const struct v4l2_ctrl_hevc_pps *pps;
> > 	const struct v4l2_ctrl_hevc_slice_params *slice_params;
> > +	const struct v4l2_ctrl_hevc_decode_params *decode_params;
> > 	const struct v4l2_hevc_pred_weight_table *pred_weight_table;
> > 	dma_addr_t src_buf_addr;
> > 	dma_addr_t src_buf_end_addr;
> > @@ -256,6 +257,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> > 	sps = run->h265.sps;
> > 	pps = run->h265.pps;
> > 	slice_params = run->h265.slice_params;
> > +	decode_params = run->h265.decode_params;
> > 	pred_weight_table = &slice_params->pred_weight_table;
> > 
> > 	/* MV column buffer size and allocation. */
> > @@ -487,7 +489,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> > 
> > 	reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) |
> > 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) |
> > -	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(slice_params->num_rps_poc_st_curr_after == 0) |
> > +	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(decode_params->num_poc_st_curr_after == 0) |
> > 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) |
> > 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) |
> > 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta);
> > @@ -527,8 +529,8 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> > 	cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg);
> > 
> > 	/* Write decoded picture buffer in pic list. */
> > -	cedrus_h265_frame_info_write_dpb(ctx, slice_params->dpb,
> > -					 slice_params->num_active_dpb_entries);
> > +	cedrus_h265_frame_info_write_dpb(ctx, decode_params->dpb,
> > +					 decode_params->num_active_dpb_entries);
> > 
> > 	/* Output frame. */
> > 
> > @@ -545,7 +547,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> > 
> > 	/* Reference picture list 0 (for P/B frames). */
> > 	if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) {
> > -		cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
> > +		cedrus_h265_ref_pic_list_write(dev, decode_params->dpb,
> > 					       slice_params->ref_idx_l0,
> > 					       slice_params->num_ref_idx_l0_active_minus1 + 1,
> > 					       VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
> > @@ -564,7 +566,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
> > 
> > 	/* Reference picture list 1 (for B frames). */
> > 	if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) {
> > -		cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
> > +		cedrus_h265_ref_pic_list_write(dev, decode_params->dpb,
> > 					       slice_params->ref_idx_l1,
> > 					       slice_params->num_ref_idx_l1_active_minus1 + 1,
> > 					       VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
> > diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
> > index 245052c15864..e53666a1127f 100644
> > --- a/include/media/hevc-ctrls.h
> > +++ b/include/media/hevc-ctrls.h
> > @@ -19,6 +19,7 @@
> > #define V4L2_CID_MPEG_VIDEO_HEVC_SPS		(V4L2_CID_CODEC_BASE + 1008)
> > #define V4L2_CID_MPEG_VIDEO_HEVC_PPS		(V4L2_CID_CODEC_BASE + 1009)
> > #define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS	(V4L2_CID_CODEC_BASE + 1010)
> > +#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS	(V4L2_CID_CODEC_BASE + 1012)
> > #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE	(V4L2_CID_CODEC_BASE + 1015)
> > #define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE	(V4L2_CID_CODEC_BASE + 1016)
> > 
> > @@ -26,6 +27,7 @@
> > #define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
> > #define V4L2_CTRL_TYPE_HEVC_PPS 0x0121
> > #define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122
> > +#define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124
> > 
> > enum v4l2_mpeg_video_hevc_decode_mode {
> > 	V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
> > @@ -195,18 +197,10 @@ struct v4l2_ctrl_hevc_slice_params {
> > 	__u8	pic_struct;
> > 
> > 	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
> > -	__u8	num_active_dpb_entries;
> > 	__u8	ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> > 	__u8	ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> > 
> > -	__u8	num_rps_poc_st_curr_before;
> > -	__u8	num_rps_poc_st_curr_after;
> > -	__u8	num_rps_poc_lt_curr;
> > -
> > -	__u8	padding;
> > -
> > -	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
> > -	struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> > +	__u8	padding[5];
> > 
> > 	/* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
> > 	struct v4l2_hevc_pred_weight_table pred_weight_table;
> > @@ -214,4 +208,21 @@ struct v4l2_ctrl_hevc_slice_params {
> > 	__u64	flags;
> > };
> > 
> > +#define V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC		0x1
> > +#define V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC		0x2
> > +#define V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR  0x4
> > +
> > +struct v4l2_ctrl_hevc_decode_params {
> > +	__s32	pic_order_cnt_val;
> > +	__u8	num_active_dpb_entries;
> > +	struct	v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> > +	__u8	num_poc_st_curr_before;
> > +	__u8	num_poc_st_curr_after;
> > +	__u8	num_poc_lt_curr;
> > +	__u8	poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> > +	__u8	poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> > +	__u8	poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
> > +	__u64	flags;
> > +};
> > +
> > #endif




From broonie at kernel.org  Tue Aug 17 07:22:32 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Aug 2021 15:22:32 +0100
Subject: (subset) [PATCH v13 0/6] Add Rockchip SFC(serial flash
 controller) support
In-Reply-To: <20210812134546.31340-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
Message-ID: <162921014496.3711.7793277648760166515.b4-ty@kernel.org>

On Thu, 12 Aug 2021 21:45:40 +0800, Jon Lin wrote:
> Changes in v13:
> - Provide independent interfaces to obtain RX TX FIFO status respectively
> - Add more debug information
> - Depress DMA limitation
> 
> Changes in v12:
> - Remove useless oneOf lable
> - Add sfc controller discription
> - Remove the limitation of SFC_MIN_SPEED_HZ
> - Add IRQ_NONE method for irq handler
> - Add SPI_MASTER_HALF_DUPLEX flags
> - Add sfc interrupt mask bits and status register initial progress
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/6] dt-bindings: rockchip-sfc: Bindings for Rockchip serial flash controller
      commit: 538d7c2ed73098850fe80be14eed2739d37e419b
[2/6] spi: rockchip-sfc: add rockchip serial flash controller
      commit: 0b89fc0a367edab09065af722894d186bd0ccb0d

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From thierry.reding at gmail.com  Tue Aug 17 07:36:08 2021
From: thierry.reding at gmail.com (Thierry Reding)
Date: Tue, 17 Aug 2021 16:36:08 +0200
Subject: [PATCH] drm/panel-simple: Add Vivax TPC-9150 panel
In-Reply-To: <20210817083201.675133-1-pavlica.nikola@gmail.com>
References: <20210817083201.675133-1-pavlica.nikola@gmail.com>
Message-ID: <YRvJWKwfCWLSdroy@orome.fritz.box>

On Tue, Aug 17, 2021 at 10:32:01AM +0200, Nikola Pavlica wrote:
> The model and make of the LCD panel of the Vivax TPC-9150 is unknown,
> hence the panel settings that were retrieved with a FEX dump are named
> after the device NOT the actual panel.
> 
> The LCD in question is a 50 pin MISO TFT LCD panel of the resolution
> 1024x600 used by the aforementioned device.
> 
> Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
> ---
>  drivers/gpu/drm/panel/panel-simple.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 4e2dad314c79..97fc3c5740bb 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -4090,6 +4090,29 @@ static const struct panel_desc arm_rtsm = {
>  	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
>  };
>  
> +static const struct drm_display_mode vivax_tpc9150_panel_mode = {
> +	.clock = 60000,
> +	.hdisplay = 1024,
> +	.hsync_start = 1024 + 160,
> +	.hsync_end = 1024 + 160 + 100,
> +	.htotal = 1024 + 160 + 100 + 60,
> +	.vdisplay = 600,
> +	.vsync_start = 600 + 12,
> +	.vsync_end = 600 + 12 + 10,
> +	.vtotal = 600 + 12 + 10 + 13,
> +};
> +
> +static const struct panel_desc vivax_tpc9150_panel = {
> +	.modes = &vivax_tpc9150_panel_mode,
> +	.num_modes = 1,
> +	.size = {
> +		.width = 223,
> +		.height = 125,
> +	},
> +	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
> +	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
> +};
> +

These were originally supposed to be alphabetically ordered by
compatible string, though it looks like at least the data structures for
ARM RTSM weren't properly ordered.

Perhaps you can prepend a patch correcting that order and then make sure
your patch keeps the alphabetical ordering, too?

>  static const struct of_device_id platform_of_match[] = {
>  	{
>  		.compatible = "ampire,am-1280800n3tzqw-t00h",
> @@ -4103,6 +4126,9 @@ static const struct of_device_id platform_of_match[] = {
>  	}, {
>  		.compatible = "arm,rtsm-display",
>  		.data = &arm_rtsm,
> +	}, {
> +		.compatible = "vivax,tpc9150-panel",
> +		.data = &vivax_tpc9150_panel,

Also make sure to keep the alphabetical order here.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/9c607206/attachment.sig>

From bigeasy at linutronix.de  Tue Aug 17 07:40:18 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Tue, 17 Aug 2021 16:40:18 +0200
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting on RT
In-Reply-To: <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
Message-ID: <20210817144018.nqssoq475vitrqlv@linutronix.de>

From: Scott Wood <swood at redhat.com>

rcutorture was generating some nesting scenarios that are not
reasonable.  Constrain the state selection to avoid them.

Example:

1. rcu_read_lock()
2. local_irq_disable()
3. rcu_read_unlock()
4. local_irq_enable()

If the thread is preempted between steps 1 and 2,
rcu_read_unlock_special.b.blocked will be set, but it won't be
acted on in step 3 because IRQs are disabled.  Thus, reporting of the
quiescent state will be delayed beyond the local_irq_enable().

For now, these scenarios will continue to be tested on non-PREEMPT_RT
kernels, until debug checks are added to ensure that they are not
happening elsewhere.

Signed-off-by: Scott Wood <swood at redhat.com>
[valentin.schneider at arm.com: Don't disable BH in atomic context]
[bigeasy: remove 'preempt_disable(); local_bh_disable(); preempt_enable();
 local_bh_enable();' from the examples because this works on RT now. ]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
---
I folded Valentin's bits.
I removed the unbalanced preempt_disable()/migrate_disable() part from
the description because it is supported now by the migrate disable
implementation. I didn't find it explicit in code/ patch except as part
of local_bh_disable().


 kernel/rcu/rcutorture.c |   94 ++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 80 insertions(+), 14 deletions(-)
---
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -61,10 +61,13 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck
 #define RCUTORTURE_RDR_RBH	 0x08	/*  ... rcu_read_lock_bh(). */
 #define RCUTORTURE_RDR_SCHED	 0x10	/*  ... rcu_read_lock_sched(). */
 #define RCUTORTURE_RDR_RCU	 0x20	/*  ... entering another RCU reader. */
-#define RCUTORTURE_RDR_NBITS	 6	/* Number of bits defined above. */
+#define RCUTORTURE_RDR_ATOM_BH	 0x40	/*  ... disabling bh while atomic */
+#define RCUTORTURE_RDR_ATOM_RBH	 0x80	/*  ... RBH while atomic */
+#define RCUTORTURE_RDR_NBITS	 8	/* Number of bits defined above. */
 #define RCUTORTURE_MAX_EXTEND	 \
 	(RCUTORTURE_RDR_BH | RCUTORTURE_RDR_IRQ | RCUTORTURE_RDR_PREEMPT | \
-	 RCUTORTURE_RDR_RBH | RCUTORTURE_RDR_SCHED)
+	 RCUTORTURE_RDR_RBH | RCUTORTURE_RDR_SCHED | \
+	 RCUTORTURE_RDR_ATOM_BH | RCUTORTURE_RDR_ATOM_RBH)
 #define RCUTORTURE_RDR_MAX_LOOPS 0x7	/* Maximum reader extensions. */
 					/* Must be power of two minus one. */
 #define RCUTORTURE_RDR_MAX_SEGS (RCUTORTURE_RDR_MAX_LOOPS + 3)
@@ -1429,31 +1432,53 @@ static void rcutorture_one_extend(int *r
 	WARN_ON_ONCE((idxold >> RCUTORTURE_RDR_SHIFT) > 1);
 	rtrsp->rt_readstate = newstate;
 
-	/* First, put new protection in place to avoid critical-section gap. */
+	/*
+	 * First, put new protection in place to avoid critical-section gap.
+	 * Disable preemption around the ATOM disables to ensure that
+	 * in_atomic() is true.
+	 */
 	if (statesnew & RCUTORTURE_RDR_BH)
 		local_bh_disable();
+	if (statesnew & RCUTORTURE_RDR_RBH)
+		rcu_read_lock_bh();
 	if (statesnew & RCUTORTURE_RDR_IRQ)
 		local_irq_disable();
 	if (statesnew & RCUTORTURE_RDR_PREEMPT)
 		preempt_disable();
-	if (statesnew & RCUTORTURE_RDR_RBH)
-		rcu_read_lock_bh();
 	if (statesnew & RCUTORTURE_RDR_SCHED)
 		rcu_read_lock_sched();
+	preempt_disable();
+	if (statesnew & RCUTORTURE_RDR_ATOM_BH)
+		local_bh_disable();
+	if (statesnew & RCUTORTURE_RDR_ATOM_RBH)
+		rcu_read_lock_bh();
+	preempt_enable();
 	if (statesnew & RCUTORTURE_RDR_RCU)
 		idxnew = cur_ops->readlock() << RCUTORTURE_RDR_SHIFT;
 
-	/* Next, remove old protection, irq first due to bh conflict. */
+	/*
+	 * Next, remove old protection, in decreasing order of strength
+	 * to avoid unlock paths that aren't safe in the stronger
+	 * context.  Disable preemption around the ATOM enables in
+	 * case the context was only atomic due to IRQ disabling.
+	 */
+	preempt_disable();
 	if (statesold & RCUTORTURE_RDR_IRQ)
 		local_irq_enable();
-	if (statesold & RCUTORTURE_RDR_BH)
+	if (statesold & RCUTORTURE_RDR_ATOM_BH)
 		local_bh_enable();
+	if (statesold & RCUTORTURE_RDR_ATOM_RBH)
+		rcu_read_unlock_bh();
+	preempt_enable();
 	if (statesold & RCUTORTURE_RDR_PREEMPT)
 		preempt_enable();
-	if (statesold & RCUTORTURE_RDR_RBH)
-		rcu_read_unlock_bh();
 	if (statesold & RCUTORTURE_RDR_SCHED)
 		rcu_read_unlock_sched();
+	if (statesold & RCUTORTURE_RDR_BH)
+		local_bh_enable();
+	if (statesold & RCUTORTURE_RDR_RBH)
+		rcu_read_unlock_bh();
+
 	if (statesold & RCUTORTURE_RDR_RCU) {
 		bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);
 
@@ -1496,6 +1521,12 @@ rcutorture_extend_mask(int oldmask, stru
 	int mask = rcutorture_extend_mask_max();
 	unsigned long randmask1 = torture_random(trsp) >> 8;
 	unsigned long randmask2 = randmask1 >> 3;
+	unsigned long preempts = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;
+	unsigned long preempts_irq = preempts | RCUTORTURE_RDR_IRQ;
+	unsigned long nonatomic_bhs = RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
+	unsigned long atomic_bhs = RCUTORTURE_RDR_ATOM_BH |
+				   RCUTORTURE_RDR_ATOM_RBH;
+	unsigned long tmp;
 
 	WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT);
 	/* Mostly only one bit (need preemption!), sometimes lots of bits. */
@@ -1503,11 +1534,46 @@ rcutorture_extend_mask(int oldmask, stru
 		mask = mask & randmask2;
 	else
 		mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS));
-	/* Can't enable bh w/irq disabled. */
-	if ((mask & RCUTORTURE_RDR_IRQ) &&
-	    ((!(mask & RCUTORTURE_RDR_BH) && (oldmask & RCUTORTURE_RDR_BH)) ||
-	     (!(mask & RCUTORTURE_RDR_RBH) && (oldmask & RCUTORTURE_RDR_RBH))))
-		mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
+
+	/*
+	 * Can't enable bh w/irq disabled.
+	 */
+	tmp = atomic_bhs | nonatomic_bhs;
+	if (mask & RCUTORTURE_RDR_IRQ)
+		mask |= oldmask & tmp;
+
+	/*
+	 * Ideally these sequences would be detected in debug builds
+	 * (regardless of RT), but until then don't stop testing
+	 * them on non-RT.
+	 */
+	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
+		/*
+		 * Can't disable bh in atomic context if bh was already
+		 * disabled by another task on the same CPU. Instead of
+		 * attempting to track this, just avoid disabling bh in atomic
+		 * context.
+		 */
+		mask &= ~atomic_bhs;
+		/*
+		 * Can't release the outermost rcu lock in an irq disabled
+		 * section without preemption also being disabled, if irqs
+		 * had ever been enabled during this RCU critical section
+		 * (could leak a special flag and delay reporting the qs).
+		 */
+		if ((oldmask & RCUTORTURE_RDR_RCU) &&
+		    (mask & RCUTORTURE_RDR_IRQ) &&
+		    !(mask & preempts))
+			mask |= RCUTORTURE_RDR_RCU;
+
+		/* Can't modify non-atomic bh in atomic context */
+		tmp = nonatomic_bhs;
+		if (oldmask & preempts_irq)
+			mask &= ~tmp;
+		if ((oldmask | mask) & preempts_irq)
+			mask |= oldmask & tmp;
+	}
+
 	return mask ?: RCUTORTURE_RDR_RCU;
 }
 


From bigeasy at linutronix.de  Tue Aug 17 07:43:48 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Tue, 17 Aug 2021 16:43:48 +0200
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <20210811201354.1976839-3-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
Message-ID: <20210817144348.kkgoytuz3766jeoz@linutronix.de>

On 2021-08-11 21:13:52 [+0100], Valentin Schneider wrote:
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index debc960f41e3..8ba7b4a7ee69 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
>  #endif
>  }
>  
> +/* Is the current task guaranteed to stay on its current CPU? */
> +static inline bool migratable(void)
> +{
> +#ifdef CONFIG_SMP
> +	return preemptible() && !current->migration_disabled;
> +#else
> +	return true;

shouldn't this be false in the UP case?

> +#endif
> +}
> +
>  /* Per-process atomic flags. */
>  #define PFA_NO_NEW_PRIVS		0	/* May not gain new privileges. */
>  #define PFA_SPREAD_PAGE			1	/* Spread page cache over cpuset */

Sebastian


From mmayer at broadcom.com  Tue Aug 17 07:59:08 2021
From: mmayer at broadcom.com (Markus Mayer)
Date: Tue, 17 Aug 2021 07:59:08 -0700
Subject: [PATCH] dt-bindings: memory: convert Broadcom DPFE to dtschema
In-Reply-To: <20210817080617.14503-1-krzysztof.kozlowski@canonical.com>
References: <20210817080617.14503-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGt4E5t8oGcjw=q1UeKZcGk=XuYyw-=8LCMjxHDKgKLedd31hw@mail.gmail.com>

Thanks for updating this.

> +++ b/Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> @@ -0,0 +1,48 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/brcm,dpfe-cpu.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: DDR PHY Front End (DPFE) for Broadcom STB
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Markus Mayer <mmayer at broadcom.com>
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - brcm,bcm7271-dpfe-cpu
> +          - brcm,bcm7268-dpfe-cpu
> +      - const: brcm,dpfe-cpu
> +
> +  reg:
> +    items:
> +      - description: DCPU register space
> +      - description: DCPU data memory space
> +      - description: DCPU instruction memory space
> +
> +  reg-names:
> +    items:
> +      - const: dpfe-cpu
> +      - const: dpfe-dmem
> +      - const: dpfe-imem
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    dpfe-cpu at f1132000 {
> +        compatible = "brcm,bcm7271-dpfe-cpu", "brcm,dpfe-cpu";
> +        reg = <0xf1132000 0x180>,
> +              <0xf1134000 0x1000>,
> +              <0xf1138000 0x4000>;
> +        reg-names = "dpfe-cpu", "dpfe-dmem", "dpfe-imem";
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 36aee8517ab0..be8e4af8ed64 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3855,7 +3855,7 @@ M:        Markus Mayer <mmayer at broadcom.com>
>  M:     bcm-kernel-feedback-list at broadcom.com
>  L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  S:     Maintained
> -F:     Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.txt
> +F:     Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
>  F:     drivers/memory/brcmstb_dpfe.c
>
>  BROADCOM STB NAND FLASH DRIVER
> --
> 2.30.2
>

Acked-by: Markus Mayer <mmayer at broadcom.com>

Regards,
-Markus


From dsahern at gmail.com  Tue Aug 17 08:05:36 2021
From: dsahern at gmail.com (David Ahern)
Date: Tue, 17 Aug 2021 09:05:36 -0600
Subject: [PATCH net-next v4] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <20210817072609.2110-1-rocco.yue@mediatek.com>
References: <20210817072609.2110-1-rocco.yue@mediatek.com>
Message-ID: <ad32c931-3056-cdef-4b9b-aab654c61cb9@gmail.com>

On 8/17/21 1:26 AM, Rocco Yue wrote:
> @@ -1496,6 +1490,11 @@ static void ndisc_router_discovery(struct sk_buff *skb)
>  		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
>  		mtu = ntohl(n);
>  
> +		if (in6_dev->ra_mtu != mtu) {
> +			in6_dev->ra_mtu = mtu;
> +			send_ifinfo_notify = true;
> +		}
> +
>  		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
>  			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
>  		} else if (in6_dev->cnf.mtu6 != mtu) {


If an RA no longer carries an MTU or if accept_ra_mtu is reset, then
in6_dev->ra_mtu should be reset to 0 right?

rest of the change looks good to me.


From peterz at infradead.org  Tue Aug 17 08:10:53 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Tue, 17 Aug 2021 17:10:53 +0200
Subject: [PATCH v11 08/16] sched: Allow task CPU affinity to be
 restricted on asymmetric systems
In-Reply-To: <20210730112443.23245-9-will@kernel.org>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-9-will@kernel.org>
Message-ID: <YRvRfZ/NnuNyIu3s@hirez.programming.kicks-ass.net>

On Fri, Jul 30, 2021 at 12:24:35PM +0100, Will Deacon wrote:
> @@ -2783,20 +2778,173 @@ static int __set_cpus_allowed_ptr(struct task_struct *p,
>  
>  	__do_set_cpus_allowed(p, new_mask, flags);
>  
> -	return affine_move_task(rq, p, &rf, dest_cpu, flags);
> +	if (flags & SCA_USER)
> +		release_user_cpus_ptr(p);
> +
> +	return affine_move_task(rq, p, rf, dest_cpu, flags);
>  
>  out:
> -	task_rq_unlock(rq, p, &rf);
> +	task_rq_unlock(rq, p, rf);
>  
>  	return ret;
>  }

> +void relax_compatible_cpus_allowed_ptr(struct task_struct *p)
> +{
> +	unsigned long flags;
> +	struct cpumask *mask = p->user_cpus_ptr;
> +
> +	/*
> +	 * Try to restore the old affinity mask. If this fails, then
> +	 * we free the mask explicitly to avoid it being inherited across
> +	 * a subsequent fork().
> +	 */
> +	if (!mask || !__sched_setaffinity(p, mask))
> +		return;
> +
> +	raw_spin_lock_irqsave(&p->pi_lock, flags);
> +	release_user_cpus_ptr(p);
> +	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
> +}

Both these are a problem on RT.

The easiest recourse is simply never freeing the CPU mask (except on
exit). The alternative is something like the below I suppose..

I'm leaning towards the former option, wdyt?

--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2733,6 +2733,7 @@ static int __set_cpus_allowed_ptr_locked
 	const struct cpumask *cpu_allowed_mask = task_cpu_possible_mask(p);
 	const struct cpumask *cpu_valid_mask = cpu_active_mask;
 	bool kthread = p->flags & PF_KTHREAD;
+	struct cpumask *user_mask = NULL;
 	unsigned int dest_cpu;
 	int ret = 0;
 
@@ -2792,9 +2793,13 @@ static int __set_cpus_allowed_ptr_locked
 	__do_set_cpus_allowed(p, new_mask, flags);
 
 	if (flags & SCA_USER)
-		release_user_cpus_ptr(p);
+		swap(user_mask, p->user_cpus_ptr);
+
+	ret = affine_move_task(rq, p, rf, dest_cpu, flags);
+
+	kfree(user_mask);
 
-	return affine_move_task(rq, p, rf, dest_cpu, flags);
+	return ret;
 
 out:
 	task_rq_unlock(rq, p, rf);
@@ -2954,8 +2959,10 @@ void relax_compatible_cpus_allowed_ptr(s
 		return;
 
 	raw_spin_lock_irqsave(&p->pi_lock, flags);
-	release_user_cpus_ptr(p);
+	p->user_cpus_ptr = NULL;
 	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
+
+	kfree(mask);
 }
 
 void set_task_cpu(struct task_struct *p, unsigned int new_cpu)


From helgaas at kernel.org  Tue Aug 17 08:24:12 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 17 Aug 2021 10:24:12 -0500
Subject: [PATCH v8 5/8] PCI: cadence: Simplify code to get register base
 address for configuring BAR
In-Reply-To: <20210811064656.15399-6-kishon@ti.com>
Message-ID: <20210817152412.GA3016169@bjorn-Precision-5520>

On Wed, Aug 11, 2021 at 12:16:53PM +0530, Kishon Vijay Abraham I wrote:
> No functional change. Simplify code to get register base address for
> configuring PCI BAR.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  .../pci/controller/cadence/pcie-cadence-ep.c   | 18 ++++--------------
>  drivers/pci/controller/cadence/pcie-cadence.h  |  2 ++
>  2 files changed, 6 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> index 912a15be8bfd..f337f0842400 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
> +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
> @@ -97,13 +97,8 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>  	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
>  			 addr1);
>  
> -	if (bar < BAR_4) {
> -		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
> -		b = bar;
> -	} else {
> -		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
> -		b = bar - BAR_4;
> -	}
> +	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
> +	b = (bar < BAR_4) ? bar : bar - BAR_4;
>  
>  	cfg = cdns_pcie_readl(pcie, reg);
>  	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> @@ -126,13 +121,8 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>  	enum pci_barno bar = epf_bar->barno;
>  	u32 reg, cfg, b, ctrl;
>  
> -	if (bar < BAR_4) {
> -		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
> -		b = bar;
> -	} else {
> -		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
> -		b = bar - BAR_4;
> -	}
> +	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
> +	b = (bar < BAR_4) ? bar : bar - BAR_4;
>  
>  	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
>  	cfg = cdns_pcie_readl(pcie, reg);
> diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
> index 30db2d68c17a..d5b1fcf2c39d 100644
> --- a/drivers/pci/controller/cadence/pcie-cadence.h
> +++ b/drivers/pci/controller/cadence/pcie-cadence.h
> @@ -46,6 +46,8 @@
>  #define  CDNS_PCIE_LM_EP_ID_BUS_SHIFT	8
>  
>  /* Endpoint Function f BAR b Configuration Registers */
> +#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn) \
> +	(((bar) < 4) ? CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn))

Why do we use "BAR_4" above and "4" here?  Shouldn't they look the
same?

>  #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \
>  	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
>  #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
> -- 
> 2.17.1
> 


From bigeasy at linutronix.de  Tue Aug 17 08:36:13 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Tue, 17 Aug 2021 17:36:13 +0200
Subject: [PATCH v3 3/4] rcu/nocb: Protect NOCB state via local_lock()
 under PREEMPT_RT
In-Reply-To: <20210811201354.1976839-4-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-4-valentin.schneider@arm.com>
Message-ID: <20210817153613.l5f66czar6pajexo@linutronix.de>

On 2021-08-11 21:13:53 [+0100], Valentin Schneider wrote:
> diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
> index 0ff5e4fb933e..11c4ff00afde 100644
> --- a/kernel/rcu/tree_plugin.h
> +++ b/kernel/rcu/tree_plugin.h
> @@ -21,6 +21,17 @@ static inline int rcu_lockdep_is_held_nocb(struct rcu_data *rdp)
>  	return lockdep_is_held(&rdp->nocb_lock);
>  }
>  
> +static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
> +{
> +	return lockdep_is_held(
> +#ifdef CONFIG_PREEMPT_RT
> +		&rdp->nocb_local_lock.lock
> +#else
> +		&rdp->nocb_local_lock
> +#endif
> +	);
> +}

Now that I see it and Paul asked for it, please just use !RT version.
	return lockdep_is_held(&rdp->nocb_local_lock);

and RT will work, too.

>  static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
>  {
>  	/* Race on early boot between thread creation and assignment */
> @@ -1629,6 +1664,22 @@ static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
>  	}
>  }
>  
> +/*
> + * The invocation of rcu_core() within the RCU core kthreads remains preemptible
> + * under PREEMPT_RT, thus the offload state of a CPU could change while
> + * said kthreads are preempted. Prevent this from happening by protecting the
> + * offload state with a local_lock().
> + */
> +static void rcu_nocb_local_lock(struct rcu_data *rdp)
> +{
> +	local_lock(&rcu_data.nocb_local_lock);
> +}
> +
> +static void rcu_nocb_local_unlock(struct rcu_data *rdp)
> +{
> +	local_unlock(&rcu_data.nocb_local_lock);
> +}
> +
Do you need to pass rdp given that it is not used?

>  /* Lockdep check that ->cblist may be safely accessed. */
>  static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp)
>  {

Sebastian


From helgaas at kernel.org  Tue Aug 17 08:38:52 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 17 Aug 2021 10:38:52 -0500
Subject: [PATCH v8 6/8] PCI: cadence: Add support to configure virtual
 functions
In-Reply-To: <20210811064656.15399-7-kishon@ti.com>
Message-ID: <20210817153852.GA3016660@bjorn-Precision-5520>

On Wed, Aug 11, 2021 at 12:16:54PM +0530, Kishon Vijay Abraham I wrote:
> Now that support for SR-IOV is added in PCIe endpoint core, add support
> to configure virtual functions in the Cadence PCIe EP driver.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  .../pci/controller/cadence/pcie-cadence-ep.c  | 136 +++++++++++++++---
>  drivers/pci/controller/cadence/pcie-cadence.h |   9 ++
>  2 files changed, 125 insertions(+), 20 deletions(-)

> @@ -92,21 +118,29 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>  
>  	addr0 = lower_32_bits(bar_phys);
>  	addr1 = upper_32_bits(bar_phys);
> -	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
> -			 addr0);
> -	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
> -			 addr1);
>  
>  	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
> +	if (vfn == 1)
> +		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);

Seems sort of weird to compute "reg", then sometimes overwrite it, as
opposed to:

  if (vfn == 1)
    reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
  else
    reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);

Also slightly weird that "vfn" is basically used as a boolean, but
it's actually a u8 virtual function number.  I guess VF 1 is special
and not like the other VFs?

>  	b = (bar < BAR_4) ? bar : bar - BAR_4;
>  
> -	cfg = cdns_pcie_readl(pcie, reg);
> -	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> -		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
> -	cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
> -		CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
> -	cdns_pcie_writel(pcie, reg, cfg);
> +	if (vfn == 0 || vfn == 1) {
> +		cfg = cdns_pcie_readl(pcie, reg);
> +		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> +			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
> +		cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
> +			CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
> +		cdns_pcie_writel(pcie, reg, cfg);
> +	}
>  
> +	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
> +	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
> +			 addr0);
> +	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
> +			 addr1);
> +
> +	if (vfn > 0)
> +		epf = &epf->epf[vfn - 1];
>  	epf->epf_bar[bar] = epf_bar;
>  
>  	return 0;
> @@ -122,18 +156,25 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>  	u32 reg, cfg, b, ctrl;
>  
>  	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
> +	if (vfn == 1)
> +		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);

Similar recomputation of "reg".

>  	b = (bar < BAR_4) ? bar : bar - BAR_4;
>  
> -	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
> -	cfg = cdns_pcie_readl(pcie, reg);
> -	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> -		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
> -	cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
> -	cdns_pcie_writel(pcie, reg, cfg);
> +	if (vfn == 0 || vfn == 1) {
> +		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
> +		cfg = cdns_pcie_readl(pcie, reg);
> +		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
> +			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
> +		cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
> +		cdns_pcie_writel(pcie, reg, cfg);
> +	}


From frieder.schrempf at kontron.de  Tue Aug 17 08:39:30 2021
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Tue, 17 Aug 2021 17:39:30 +0200
Subject: [PATCH v4 4/5] ARM: dts: imx6ull: add rng
In-Reply-To: <20200715152604.10407-5-horia.geanta@nxp.com>
References: <20200715152604.10407-1-horia.geanta@nxp.com>
 <20200715152604.10407-5-horia.geanta@nxp.com>
Message-ID: <4f30d822-9db7-4a54-c082-fa9f54982b42@kontron.de>

Hi,

On 15.07.20 17:26, Horia Geant? wrote:
> Add node for the RNGB block.
> 
> Signed-off-by: Horia Geant? <horia.geanta at nxp.com>
> Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
> ---
>  arch/arm/boot/dts/imx6ull.dtsi | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
> index fcde7f77ae42..9bf67490ac49 100644
> --- a/arch/arm/boot/dts/imx6ull.dtsi
> +++ b/arch/arm/boot/dts/imx6ull.dtsi
> @@ -68,6 +68,13 @@
>  				clock-names = "dcp";
>  			};
>  
> +			rngb: rng at 2284000 {
> +				compatible = "fsl,imx6ull-rngb", "fsl,imx25-rngb";
> +				reg = <0x02284000 0x4000>;
> +				interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
> +				clocks = <&clks IMX6UL_CLK_DUMMY>;
> +			};
> +

My board (imx6ull-kontron-n6411-s.dts) fails to boot since this was added in v5.10-rc1. There is a crash in the RNG probe. Can anyone help?
Below is the interesting part of the boot log from v5.14-rc6.

Thanks
Frieder


[...]
Asymmetric key parser 'x509' registered
io scheduler mq-deadline registered
io scheduler kyber registered
imx_soc_device_init: failed to find fsl,imx6ul-ocotp regmap!
2020000.serial: ttymxc0 at MMIO 0x2020000 (irq = 30, base_baud = 5000000) is a IMX
21e8000.serial: ttymxc1 at MMIO 0x21e8000 (irq = 69, base_baud = 5000000) is a IMX
21ec000.serial: ttymxc2 at MMIO 0x21ec000 (irq = 70, base_baud = 5000000) is a IMX
21f0000.serial: ttymxc3 at MMIO 0x21f0000 (irq = 71, base_baud = 5000000) is a IMX
imx-uart 21f0000.serial: Console IMX rounded baud rate from 114943 to 114900
printk: console [ttymxc3] enabled
8<--- cut here ---
Unhandled fault: external abort on non-linefetch (0x008) at 0xe08d8000
pgd = (ptrval)
[e08d8000] *pgd=81c89811, *pte=02284653, *ppte=02284453
Internal error: : 8 [#1] SMP ARM
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.14.0-rc6-ktn+g807a88195d76 #1
Hardware name: Freescale i.MX6 Ultralite (Device Tree)
PC is at imx_rngc_probe+0xa4/0x30c
LR is at _raw_spin_unlock_irqrestore+0x4c/0x50
pc : [<c06922b4>]    lr : [<c0c7ccd4>]    psr: 60000053
sp : c1ccfe00  ip : 00000001  fp : 00000000
r10: c1cb6240  r9 : c1fdeb40  r8 : 00000000
r7 : c1d98410  r6 : c1d98400  r5 : c1e07b40  r4 : 0000004c
r3 : e08d8000  r2 : 00000000  r1 : e591bac3  r0 : 00000000
Flags: nZCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment none
Control: 10c5387d  Table: 8000406a  DAC: 00000051
Register r0 information: NULL pointer
Register r1 information: non-paged memory
Register r2 information: NULL pointer
Register r3 information: 0-page vmalloc region starting at 0xe08d8000 allocated at __devm_ioremap+0xa4/0xbc
Register r4 information: non-paged memory
Register r5 information: slab kmalloc-256 start c1e07b00 pointer offset 64 size 256
Register r6 information: slab kmalloc-1k start c1d98400 pointer offset 0 size 1024
Register r7 information: slab kmalloc-1k start c1d98400 pointer offset 16 size 1024
Register r8 information: NULL pointer
Register r9 information: slab kmalloc-64 start c1fdeb40 pointer offset 0 size 64
Register r10 information: slab kmalloc-192 start c1cb6240 pointer offset 0 size 192
Register r11 information: NULL pointer
Register r12 information: non-paged memory
Process swapper/0 (pid: 1, stack limit = 0x(ptrval))
Stack: (0xc1ccfe00 to 0xc1cd0000)
fe00: 00000000 00000000 00000000 9cd54eeb 00000000 c1d98410 c145a4d4 00000000
fe20: c1d98410 c1244854 c1cb6240 c0710fb4 c1d98410 00000000 c145a4d4 00000000
fe40: c1d98410 c070e86c c1d98410 c145a4d4 c145a4d4 c070eadc c1b3b0fc c1b3b100
fe60: c145a4d4 c070eb70 00000000 c1d98410 c145a4d4 c1cce000 00000000 c070ef24
fe80: 00000000 c145a4d4 c070eeb4 c070cb9c c1fdd900 c1cb32b0 c1de0a14 9cd54eeb
fea0: c1cb32e4 c145a4d4 c1fdd900 00000000 c145cdf0 c070db70 c1024488 c122e530
fec0: c145a4d4 c145a4d4 c122e530 c145a4d4 c1308fcc c070fc7c c145a4c0 c122e530
fee0: c145a4d4 c0711470 c1cce000 c122e530 c14c6b80 c0102220 00000000 00000000
ff00: c1cb62e1 c1106d00 000000fc c014cd08 000000a2 c11059b8 c1051d10 c12003e8
ff20: c1cce000 c14c6b80 c1308fcc c11059b8 c14d1000 c1244854 000000fc c01aa110
ff40: 00000000 9cd54eeb c1254540 00000007 c1244874 c11059b8 c14d1000 c1244854
ff60: c1cb6240 c1201200 00000006 00000006 00000000 c12003e8 00000000 000000fc
ff80: 00000000 00000000 c0c71b20 00000000 00000000 00000000 00000000 00000000
ffa0: 00000000 c0c71b30 00000000 c010013c 00000000 00000000 00000000 00000000
ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[<c06922b4>] (imx_rngc_probe) from [<c0710fb4>] (platform_probe+0x58/0xb8)
[<c0710fb4>] (platform_probe) from [<c070e86c>] (really_probe+0x14c/0x33c)
[<c070e86c>] (really_probe) from [<c070eadc>] (__driver_probe_device+0x80/0xe4)
[<c070eadc>] (__driver_probe_device) from [<c070eb70>] (driver_probe_device+0x30/0xd4)
[<c070eb70>] (driver_probe_device) from [<c070ef24>] (__driver_attach+0x70/0xf4)
[<c070ef24>] (__driver_attach) from [<c070cb9c>] (bus_for_each_dev+0x78/0xb8)
[<c070cb9c>] (bus_for_each_dev) from [<c070db70>] (bus_add_driver+0x150/0x1dc)
[<c070db70>] (bus_add_driver) from [<c070fc7c>] (driver_register+0x74/0x108)
[<c070fc7c>] (driver_register) from [<c0711470>] (__platform_driver_probe+0x44/0xdc)
[<c0711470>] (__platform_driver_probe) from [<c0102220>] (do_one_initcall+0x80/0x3a8)
[<c0102220>] (do_one_initcall) from [<c1201200>] (kernel_init_freeable+0x1a0/0x234)
[<c1201200>] (kernel_init_freeable) from [<c0c71b30>] (kernel_init+0x10/0x124)
[<c0c71b30>] (kernel_init) from [<c010013c>] (ret_from_fork+0x14/0x38)
Exception stack(0xc1ccffb0 to 0xc1ccfff8)
ffa0:                                     00000000 00000000 00000000 00000000
ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
Code: ebfe93da e2508000 1a00000f e5953008 (e5939000)
---[ end trace 27e536094eba35b6 ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---






From peterz at infradead.org  Tue Aug 17 08:40:24 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Tue, 17 Aug 2021 17:40:24 +0200
Subject: [PATCH v11 07/16] sched: Split the guts of sched_setaffinity()
 into a helper function
In-Reply-To: <20210730112443.23245-8-will@kernel.org>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-8-will@kernel.org>
Message-ID: <YRvYaGa4QnhV2q51@hirez.programming.kicks-ass.net>

On Fri, Jul 30, 2021 at 12:24:34PM +0100, Will Deacon wrote:
> In preparation for replaying user affinity requests using a saved mask,
> split sched_setaffinity() up so that the initial task lookup and
> security checks are only performed when the request is coming directly
> from userspace.
> 
> Reviewed-by: Valentin Schneider <Valentin.Schneider at arm.com>
> Signed-off-by: Will Deacon <will at kernel.org>

Should not sched_setaffinity() update user_cpus_ptr when it isn't NULL,
such that the upcoming relax_compatible_cpus_allowed_ptr() preserve the
full user mask?


From peterz at infradead.org  Tue Aug 17 08:41:42 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Tue, 17 Aug 2021 17:41:42 +0200
Subject: [PATCH v11 08/16] sched: Allow task CPU affinity to be
 restricted on asymmetric systems
In-Reply-To: <20210730112443.23245-9-will@kernel.org>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-9-will@kernel.org>
Message-ID: <YRvYtlyhuRpFi/Th@hirez.programming.kicks-ass.net>

On Fri, Jul 30, 2021 at 12:24:35PM +0100, Will Deacon wrote:
> +	struct rq_flags rf;
> +	struct rq *rq;
> +	int err;
> +	struct cpumask *user_mask = NULL;

> +	cpumask_var_t new_mask;
> +	const struct cpumask *override_mask = task_cpu_possible_mask(p);

> +	unsigned long flags;
> +	struct cpumask *mask = p->user_cpus_ptr;

I've fixed all that up to be proper reverse x-mas trees; similar for
other patches.


From sam at ravnborg.org  Tue Aug 17 08:45:16 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Tue, 17 Aug 2021 17:45:16 +0200
Subject: [PATCH] drm/panel-simple: Add Vivax TPC-9150 panel
In-Reply-To: <20210817083201.675133-1-pavlica.nikola@gmail.com>
References: <20210817083201.675133-1-pavlica.nikola@gmail.com>
Message-ID: <YRvZjDfSxMC5q8ac@ravnborg.org>

Hi Nikola,

see a few comments in the following.

On Tue, Aug 17, 2021 at 10:32:01AM +0200, Nikola Pavlica wrote:
> The model and make of the LCD panel of the Vivax TPC-9150 is unknown,
> hence the panel settings that were retrieved with a FEX dump are named
> after the device NOT the actual panel.
> 
> The LCD in question is a 50 pin MISO TFT LCD panel of the resolution
> 1024x600 used by the aforementioned device.
> 
> Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
> ---
>  drivers/gpu/drm/panel/panel-simple.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 4e2dad314c79..97fc3c5740bb 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -4090,6 +4090,29 @@ static const struct panel_desc arm_rtsm = {
>  	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
>  };
>  
> +static const struct drm_display_mode vivax_tpc9150_panel_mode = {
> +	.clock = 60000,
> +	.hdisplay = 1024,
> +	.hsync_start = 1024 + 160,
> +	.hsync_end = 1024 + 160 + 100,
> +	.htotal = 1024 + 160 + 100 + 60,
> +	.vdisplay = 600,
> +	.vsync_start = 600 + 12,
> +	.vsync_end = 600 + 12 + 10,
> +	.vtotal = 600 + 12 + 10 + 13,
> +};
.flags?

> +
> +static const struct panel_desc vivax_tpc9150_panel = {
> +	.modes = &vivax_tpc9150_panel_mode,
> +	.num_modes = 1,
> +	.size = {
> +		.width = 223,
> +		.height = 125,
> +	},
> +	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
> +	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
> +};

Specifying .connector_type is mandatory today.
Please specify .bpc too.

Consider if .bus_flags cover it all, they can be a little tricky to add
them all. And many many displays have failed to do so.

I hope to see a new version soon with these comments and also the
comments from Thierry fixed.

	Sam

> +
>  static const struct of_device_id platform_of_match[] = {
>  	{
>  		.compatible = "ampire,am-1280800n3tzqw-t00h",
> @@ -4103,6 +4126,9 @@ static const struct of_device_id platform_of_match[] = {
>  	}, {
>  		.compatible = "arm,rtsm-display",
>  		.data = &arm_rtsm,
> +	}, {
> +		.compatible = "vivax,tpc9150-panel",
> +		.data = &vivax_tpc9150_panel,
>  	}, {
>  		.compatible = "armadeus,st0700-adapt",
>  		.data = &armadeus_st0700_adapt,
> -- 
> 2.32.0


From jic23 at kernel.org  Tue Aug 17 08:54:18 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Tue, 17 Aug 2021 16:54:18 +0100
Subject: [PATCH v1 1/2] iio: mtk-auxadc: add support IIO_CHAN_INFO_RAW case
In-Reply-To: <470d4a7fbbcbcaa35aa9dcbaab6a2b77f98dc528.camel@mediatek.com>
References: <20210812054844.30575-1-hui.liu@mediatek.com>
 <20210812054844.30575-2-hui.liu@mediatek.com>
 <20210812190725.00007449@Huawei.com>
 <042625639032bffe73b60a5c6274511e58e34ef4.camel@mediatek.com>
 <20210814171007.6892ae94@jic23-huawei>
 <470d4a7fbbcbcaa35aa9dcbaab6a2b77f98dc528.camel@mediatek.com>
Message-ID: <20210817165418.4b1cfdce@jic23-huawei>

On Tue, 17 Aug 2021 16:37:52 +0800
hui.liu <hui.liu at mediatek.com> wrote:

> On Sat, 2021-08-14 at 17:10 +0100, Jonathan Cameron wrote:
> > On Fri, 13 Aug 2021 11:46:24 +0800
> > hui.liu <hui.liu at mediatek.com> wrote:
> >   
> > > On Thu, 2021-08-12 at 19:07 +0100, Jonathan Cameron wrote:  
> > > > On Thu, 12 Aug 2021 13:48:43 +0800
> > > > Hui Liu <hui.liu at mediatek.com> wrote:
> > > >     
> > > > > Add support IIO_CHAN_INFO_RAW case.    
> > > > 
> > > > Why?
> > > > 
> > > > We almost never support both RAW and PROCESSED as userspace
> > > > should be
> > > > fine to use either.  There are a few reasons we've let drivers do
> > > > this but I would like know why it matters to you and it
> > > > definitely
> > > > needs to be in the patch description.
> > > >     
> > > 
> > > Hi Jonathan,
> > > 
> > > 1. To support ADC consumers' different types of requirement: some
> > > consumers want to call iio_read_channel_raw to get raw data, the
> > > others
> > > use iio_read_channel_processed to get voltage.  
> > 
> > Give an example of the consumer using the raw channel readback
> > (without
> > acess to any scaling information?)
> >   
> 
> > > 2. In our origin driver, if consumer call
> > > iio_read_channel_processed,
> > > read back value is raw data. 
> > > 
> > > Could we use SCALE instead of PROCESSED in patch for next version,
> > > or
> > > what's your suggestion?  
> > 
> > That would unfortunately be a userspace ABI change.  We can add
> > interfaces
> > but taking them away is normally a problem :( 
> > 
> > Your reasons here are fine, subject to information on what consumer
> > cares
> > about having _RAW, please resend the patch with this information
> > added
> > to the description.
> > 
> > Thanks,
> > 
> > Jonathan  
> 
> 1. We found afe/iio-rescale.c, dac/dpot-dac.c and multiplexer/iio-mux.c 
> call iio_read_channel_raw to get raw data. If they use our ADC driver,
> I think we should support _RAW case. 
> If we support _RAW case, we will add more information in v2
> description.

iio-rescale has recently gained support for processed.
https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/commit/drivers/iio/afe/iio-rescale.c?h=testing&id=53ebee9499805add3eef630d998c40812e6a1c39
dpot-dac is a rather obscure special case, so I doubt you actually have one of those.
If iio-mux is relevant then we should add processed support to that driver as well.

I would rather see those users of the interface fixed than us
having to tweak lots of drivers to provide _raw when it isn't appropriate for
that piece of hardware.

Jonathan

> 
> 2. Since we change _PROCESSED readback value from raw data to voltage,
> our consumer will make the changes synchronously. 
> 
> > > 
> > > Thanks.
> > >   
> > > > > 
> > > > > Signed-off-by: Hui Liu <hui.liu at mediatek.com>
> > > > > ---
> > > > >  drivers/iio/adc/mt6577_auxadc.c | 16 +++++++++++++++-
> > > > >  1 file changed, 15 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/iio/adc/mt6577_auxadc.c
> > > > > b/drivers/iio/adc/mt6577_auxadc.c
> > > > > index 79c1dd68b909..e995d43287b2 100644
> > > > > --- a/drivers/iio/adc/mt6577_auxadc.c
> > > > > +++ b/drivers/iio/adc/mt6577_auxadc.c
> > > > > @@ -60,7 +60,8 @@ static const struct mtk_auxadc_compatible
> > > > > mt6765_compat = {
> > > > >  		.type = IIO_VOLTAGE,				
> > > > >    
> > > > >  \
> > > > >  		.indexed = 1,					
> > > > >    
> > > > >  \
> > > > >  		.channel = (idx),				
> > > > >     \
> > > > > -		.info_mask_separate =
> > > > > BIT(IIO_CHAN_INFO_PROCESSED), \
> > > > > +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	
> > > > >    
> > > > >  \
> > > > > +				      BIT(IIO_CHAN_INFO_PROCESS
> > > > > ED), \
> > > > >  }
> > > > >  
> > > > >  static const struct iio_chan_spec mt6577_auxadc_iio_channels[]
> > > > > = {
> > > > > @@ -181,6 +182,19 @@ static int mt6577_auxadc_read_raw(struct
> > > > > iio_dev *indio_dev,
> > > > >  	struct mt6577_auxadc_device *adc_dev =
> > > > > iio_priv(indio_dev);
> > > > >  
> > > > >  	switch (info) {
> > > > > +	case IIO_CHAN_INFO_RAW:
> > > > > +		*val = mt6577_auxadc_read(indio_dev, chan);
> > > > > +		if (*val < 0) {
> > > > > +			dev_notice(indio_dev->dev.parent,
> > > > > +				"failed to sample data on
> > > > > channel[%d]\n",
> > > > > +				chan->channel);
> > > > > +			return *val;
> > > > > +		}
> > > > > +		if (adc_dev->dev_comp->sample_data_cali)
> > > > > +			*val = mt_auxadc_get_cali_data(*val,
> > > > > true);
> > > > > +
> > > > > +		return IIO_VAL_INT;
> > > > > +
> > > > >  	case IIO_CHAN_INFO_PROCESSED:
> > > > >  		*val = mt6577_auxadc_read(indio_dev, chan);
> > > > >  		if (*val < 0) {    
> > > > 
> > > >     
> > 
> >   



From pavlica.nikola at gmail.com  Tue Aug 17 08:53:43 2021
From: pavlica.nikola at gmail.com (Nikola Pavlica)
Date: Tue, 17 Aug 2021 17:53:43 +0200
Subject: [PATCH] drm/panel-simple: Add Vivax TPC-9150 panel v2
Message-ID: <20210817155343.1063402-1-pavlica.nikola@gmail.com>

The model and make of the LCD panel of the Vivax TPC-9150 is unknown,
hence the panel settings that were retrieved with a FEX dump are named
after the device NOT the actual panel.

The LCD in question is a 50 pin MISO TFT LCD panel of the resolution
1024x600 used by the aforementioned device.

Version 2, as Thierry kindly suggested that I fix the order in which the
panel was ordered compared to others.

Thanks,
Nikola

Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 4e2dad314c79..9f6080e57771 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3989,6 +3989,30 @@ static const struct panel_desc urt_umsh_8596md_parallel = {
 	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 };
 
+static const struct drm_display_mode vivax_tpc9150_panel_mode = {
+	.clock = 60000,
+	.hdisplay = 1024,
+	.hsync_start = 1024 + 160,
+	.hsync_end = 1024 + 160 + 100,
+	.htotal = 1024 + 160 + 100 + 60,
+	.vdisplay = 600,
+	.vsync_start = 600 + 12,
+	.vsync_end = 600 + 12 + 10,
+	.vtotal = 600 + 12 + 10 + 13,
+};
+
+static const struct panel_desc vivax_tpc9150_panel = {
+	.modes = &vivax_tpc9150_panel_mode,
+	.num_modes = 1,
+	.size = {
+		.width = 223,
+		.height = 125,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
+};
+
+
 static const struct drm_display_mode vl050_8048nt_c01_mode = {
 	.clock = 33333,
 	.hdisplay = 800,
@@ -4490,6 +4514,9 @@ static const struct of_device_id platform_of_match[] = {
 	}, {
 		.compatible = "urt,umsh-8596md-20t",
 		.data = &urt_umsh_8596md_parallel,
+	}, {
+		.compatible = "vivax,tpc9150-panel",
+		.data = &vivax_tpc9150_panel,
 	}, {
 		.compatible = "vxt,vl050-8048nt-c01",
 		.data = &vl050_8048nt_c01,
-- 
2.32.0



From len.baker at gmx.com  Tue Aug 17 09:18:21 2021
From: len.baker at gmx.com (Len Baker)
Date: Tue, 17 Aug 2021 18:18:21 +0200
Subject: [PATCH] input/serio: Prefer strscpy over strlcpy
Message-ID: <20210817161821.4601-1-len.baker@gmx.com>

strlcpy() reads the entire source buffer first. This read may exceed the
destination size limit. This is both inefficient and can lead to linear
read overflows if a source string is not NUL-terminated. The safe
replacement is strscpy().

This is a previous step in the path to remove the strlcpy() function
entirely from the kernel [1].

In the case where a constant string is copied, the strscpy() is not
very useful (we know that a read overflow can not happen, and if the
dst is big enough that the string will not be truncated). However,
the change is made to avoid the use of strlcpy().

[1] https://github.com/KSPP/linux/issues/89

Signed-off-by: Len Baker <len.baker at gmx.com>
---
Hi Dmitry,

If you disagree with the constant string copy changes I can use
strcpy or memcpy instead. In this discussion [2] the patch was
rejected since it not fixed any real issue. However, if we want
to cleanup the proliferation of str*cpy() functions in the kernel
this can be a good start point.

[2] https://lore.kernel.org/linux-hardening/YQbXiwie4YPzPWKK at google.com/

Regards,
Len

 drivers/input/serio/altera_ps2.c      |  4 ++--
 drivers/input/serio/ams_delta_serio.c |  4 ++--
 drivers/input/serio/apbps2.c          |  2 +-
 drivers/input/serio/ct82c710.c        |  2 +-
 drivers/input/serio/i8042.c           | 14 +++++++-------
 drivers/input/serio/olpc_apsp.c       |  8 ++++----
 drivers/input/serio/parkbd.c          |  2 +-
 drivers/input/serio/pcips2.c          |  4 ++--
 drivers/input/serio/ps2-gpio.c        |  4 ++--
 drivers/input/serio/ps2mult.c         |  2 +-
 drivers/input/serio/q40kbd.c          |  4 ++--
 drivers/input/serio/rpckbd.c          |  4 ++--
 drivers/input/serio/sa1111ps2.c       |  4 ++--
 drivers/input/serio/serport.c         |  2 +-
 drivers/input/serio/sun4i-ps2.c       |  4 ++--
 15 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
index 379e9240c2b3..3a92304f64fb 100644
--- a/drivers/input/serio/altera_ps2.c
+++ b/drivers/input/serio/altera_ps2.c
@@ -110,8 +110,8 @@ static int altera_ps2_probe(struct platform_device *pdev)
 	serio->write		= altera_ps2_write;
 	serio->open		= altera_ps2_open;
 	serio->close		= altera_ps2_close;
-	strlcpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name));
-	strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
+	strscpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name));
+	strscpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
 	serio->port_data	= ps2if;
 	serio->dev.parent	= &pdev->dev;
 	ps2if->io		= serio;
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c
index 1c0be299f179..ec93cb4573c3 100644
--- a/drivers/input/serio/ams_delta_serio.c
+++ b/drivers/input/serio/ams_delta_serio.c
@@ -159,8 +159,8 @@ static int ams_delta_serio_init(struct platform_device *pdev)
 	serio->id.type = SERIO_8042;
 	serio->open = ams_delta_serio_open;
 	serio->close = ams_delta_serio_close;
-	strlcpy(serio->name, "AMS DELTA keyboard adapter", sizeof(serio->name));
-	strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
+	strscpy(serio->name, "AMS DELTA keyboard adapter", sizeof(serio->name));
+	strscpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
 	serio->dev.parent = &pdev->dev;
 	serio->port_data = priv;

diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c
index 974d7bfae0a0..9c9ce097f8bf 100644
--- a/drivers/input/serio/apbps2.c
+++ b/drivers/input/serio/apbps2.c
@@ -176,7 +176,7 @@ static int apbps2_of_probe(struct platform_device *ofdev)
 	priv->io->close = apbps2_close;
 	priv->io->write = apbps2_write;
 	priv->io->port_data = priv;
-	strlcpy(priv->io->name, "APBPS2 PS/2", sizeof(priv->io->name));
+	strscpy(priv->io->name, "APBPS2 PS/2", sizeof(priv->io->name));
 	snprintf(priv->io->phys, sizeof(priv->io->phys),
 		 "apbps2_%d", apbps2_idx++);

diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index d45009d654bf..752ce60e2211 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -170,7 +170,7 @@ static int ct82c710_probe(struct platform_device *dev)
 	ct82c710_port->open = ct82c710_open;
 	ct82c710_port->close = ct82c710_close;
 	ct82c710_port->write = ct82c710_write;
-	strlcpy(ct82c710_port->name, "C&T 82c710 mouse port",
+	strscpy(ct82c710_port->name, "C&T 82c710 mouse port",
 		sizeof(ct82c710_port->name));
 	snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys),
 		 "isa%16llx/serio0", (unsigned long long)CT82C710_DATA);
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 0b9f1d0a8f8b..681b1f9678a7 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -1337,9 +1337,9 @@ static int __init i8042_create_kbd_port(void)
 	serio->ps2_cmd_mutex	= &i8042_mutex;
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
-	strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
-	strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
-	strlcpy(serio->firmware_id, i8042_kbd_firmware_id,
+	strscpy(serio->name, "i8042 KBD port", sizeof(serio->name));
+	strscpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
+	strscpy(serio->firmware_id, i8042_kbd_firmware_id,
 		sizeof(serio->firmware_id));
 	set_primary_fwnode(&serio->dev, i8042_kbd_fwnode);

@@ -1367,15 +1367,15 @@ static int __init i8042_create_aux_port(int idx)
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
 	if (idx < 0) {
-		strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name));
-		strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
-		strlcpy(serio->firmware_id, i8042_aux_firmware_id,
+		strscpy(serio->name, "i8042 AUX port", sizeof(serio->name));
+		strscpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+		strscpy(serio->firmware_id, i8042_aux_firmware_id,
 			sizeof(serio->firmware_id));
 		serio->close = i8042_port_close;
 	} else {
 		snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx);
 		snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1);
-		strlcpy(serio->firmware_id, i8042_aux_firmware_id,
+		strscpy(serio->firmware_id, i8042_aux_firmware_id,
 			sizeof(serio->firmware_id));
 	}

diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c
index 59de8d9b6710..04d2db982fb8 100644
--- a/drivers/input/serio/olpc_apsp.c
+++ b/drivers/input/serio/olpc_apsp.c
@@ -199,8 +199,8 @@ static int olpc_apsp_probe(struct platform_device *pdev)
 	kb_serio->close		= olpc_apsp_close;
 	kb_serio->port_data	= priv;
 	kb_serio->dev.parent	= &pdev->dev;
-	strlcpy(kb_serio->name, "sp keyboard", sizeof(kb_serio->name));
-	strlcpy(kb_serio->phys, "sp/serio0", sizeof(kb_serio->phys));
+	strscpy(kb_serio->name, "sp keyboard", sizeof(kb_serio->name));
+	strscpy(kb_serio->phys, "sp/serio0", sizeof(kb_serio->phys));
 	priv->kbio		= kb_serio;
 	serio_register_port(kb_serio);

@@ -216,8 +216,8 @@ static int olpc_apsp_probe(struct platform_device *pdev)
 	pad_serio->close	= olpc_apsp_close;
 	pad_serio->port_data	= priv;
 	pad_serio->dev.parent	= &pdev->dev;
-	strlcpy(pad_serio->name, "sp touchpad", sizeof(pad_serio->name));
-	strlcpy(pad_serio->phys, "sp/serio1", sizeof(pad_serio->phys));
+	strscpy(pad_serio->name, "sp touchpad", sizeof(pad_serio->name));
+	strscpy(pad_serio->phys, "sp/serio1", sizeof(pad_serio->phys));
 	priv->padio		= pad_serio;
 	serio_register_port(pad_serio);

diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
index 3ac57a91ede4..6bee653d1965 100644
--- a/drivers/input/serio/parkbd.c
+++ b/drivers/input/serio/parkbd.c
@@ -169,7 +169,7 @@ static struct serio *parkbd_allocate_serio(void)
 	if (serio) {
 		serio->id.type = parkbd_mode;
 		serio->write = parkbd_write;
-		strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name));
+		strscpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name));
 		snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", parkbd_dev->port->name);
 	}

diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
index bedf75de0a2c..05878750f2c2 100644
--- a/drivers/input/serio/pcips2.c
+++ b/drivers/input/serio/pcips2.c
@@ -149,8 +149,8 @@ static int pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	serio->write		= pcips2_write;
 	serio->open		= pcips2_open;
 	serio->close		= pcips2_close;
-	strlcpy(serio->name, pci_name(dev), sizeof(serio->name));
-	strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
+	strscpy(serio->name, pci_name(dev), sizeof(serio->name));
+	strscpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
 	serio->port_data	= ps2if;
 	serio->dev.parent	= &dev->dev;
 	ps2if->io		= serio;
diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c
index 8970b49ea09a..1e5e8d94220a 100644
--- a/drivers/input/serio/ps2-gpio.c
+++ b/drivers/input/serio/ps2-gpio.c
@@ -393,8 +393,8 @@ static int ps2_gpio_probe(struct platform_device *pdev)
 	serio->write = drvdata->write_enable ? ps2_gpio_write : NULL;
 	serio->port_data = drvdata;
 	serio->dev.parent = dev;
-	strlcpy(serio->name, dev_name(dev), sizeof(serio->name));
-	strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys));
+	strscpy(serio->name, dev_name(dev), sizeof(serio->name));
+	strscpy(serio->phys, dev_name(dev), sizeof(serio->phys));

 	drvdata->serio = serio;
 	drvdata->dev = dev;
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c
index 0071dd5ebcc2..902e81826fbf 100644
--- a/drivers/input/serio/ps2mult.c
+++ b/drivers/input/serio/ps2mult.c
@@ -131,7 +131,7 @@ static int ps2mult_create_port(struct ps2mult *psm, int i)
 	if (!serio)
 		return -ENOMEM;

-	strlcpy(serio->name, "TQC PS/2 Multiplexer", sizeof(serio->name));
+	strscpy(serio->name, "TQC PS/2 Multiplexer", sizeof(serio->name));
 	snprintf(serio->phys, sizeof(serio->phys),
 		 "%s/port%d", mx_serio->phys, i);
 	serio->id.type = SERIO_8042;
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index bd248398556a..a1c61f5de047 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -126,8 +126,8 @@ static int q40kbd_probe(struct platform_device *pdev)
 	port->close = q40kbd_close;
 	port->port_data = q40kbd;
 	port->dev.parent = &pdev->dev;
-	strlcpy(port->name, "Q40 Kbd Port", sizeof(port->name));
-	strlcpy(port->phys, "Q40", sizeof(port->phys));
+	strscpy(port->name, "Q40 Kbd Port", sizeof(port->name));
+	strscpy(port->phys, "Q40", sizeof(port->phys));

 	q40kbd_stop();

diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index 37fe6a5711ea..7008bc101415 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -128,8 +128,8 @@ static int rpckbd_probe(struct platform_device *dev)
 	serio->close		= rpckbd_close;
 	serio->dev.parent	= &dev->dev;
 	serio->port_data	= rpckbd;
-	strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
-	strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
+	strscpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
+	strscpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));

 	platform_set_drvdata(dev, serio);
 	serio_register_port(serio);
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 68fac4801e2e..2724c3aa512c 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -267,8 +267,8 @@ static int ps2_probe(struct sa1111_dev *dev)
 	serio->write		= ps2_write;
 	serio->open		= ps2_open;
 	serio->close		= ps2_close;
-	strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name));
-	strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
+	strscpy(serio->name, dev_name(&dev->dev), sizeof(serio->name));
+	strscpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
 	serio->port_data	= ps2if;
 	serio->dev.parent	= &dev->dev;
 	ps2if->io		= serio;
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 7fbbe00e3553..50295b17cca4 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -171,7 +171,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file,
 	if (!serio)
 		return -ENOMEM;

-	strlcpy(serio->name, "Serial port", sizeof(serio->name));
+	strscpy(serio->name, "Serial port", sizeof(serio->name));
 	snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty));
 	serio->id = serport->id;
 	serio->id.type = SERIO_RS232;
diff --git a/drivers/input/serio/sun4i-ps2.c b/drivers/input/serio/sun4i-ps2.c
index f15ed3dcdb9b..eb262640192e 100644
--- a/drivers/input/serio/sun4i-ps2.c
+++ b/drivers/input/serio/sun4i-ps2.c
@@ -256,8 +256,8 @@ static int sun4i_ps2_probe(struct platform_device *pdev)
 	serio->close = sun4i_ps2_close;
 	serio->port_data = drvdata;
 	serio->dev.parent = dev;
-	strlcpy(serio->name, dev_name(dev), sizeof(serio->name));
-	strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys));
+	strscpy(serio->name, dev_name(dev), sizeof(serio->name));
+	strscpy(serio->phys, dev_name(dev), sizeof(serio->phys));

 	/* shutoff interrupt */
 	writel(0, drvdata->reg_base + PS2_REG_GCTL);
--
2.25.1



From p.yadav at ti.com  Tue Aug 17 09:23:48 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 21:53:48 +0530
Subject: [PATCH v2 21/35] mtd: spi-nor: Introduce spi_nor_set_mtd_info()
In-Reply-To: <20210727045222.905056-22-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-22-tudor.ambarus@microchip.com>
Message-ID: <20210817162346.bsxdbf7we5sg5qfp@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Used to init all the mtd_info fields. Move the mtd_info init
> the last thing in the spi_nor_scan(), so that we avoid superfluous
> initialization of the mtd_info fields in case of errors.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c | 55 +++++++++++++++++++++-----------------
>  1 file changed, 31 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 5c8cffb5e6f2..26acfc9901db 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3124,6 +3124,36 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
>  	return info;
>  }
>  
> +static void spi_nor_set_mtd_info(struct spi_nor *nor)
> +{
> +	struct mtd_info *mtd = &nor->mtd;
> +	struct device *dev = nor->dev;
> +
> +	spi_nor_register_locking_ops(nor);
> +
> +	/* Configure OTP parameters and ops */
> +	spi_nor_otp_init(nor);
> +
> +	mtd->dev.parent = dev;
> +	if (!mtd->name)
> +		mtd->name = dev_name(dev);
> +	mtd->priv = nor;

You remove the lines setting mtd->priv in the previous patch. Why add it 
back?

Other than this,

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

> +	mtd->type = MTD_NORFLASH;
> +	mtd->flags = MTD_CAP_NORFLASH;
> +	if (nor->info->flags & SPI_NOR_NO_ERASE)
> +		mtd->flags |= MTD_NO_ERASE;
> +	mtd->writesize = nor->params->writesize;
> +	mtd->writebufsize = nor->page_size;
> +	mtd->size = nor->params->size;
> +	mtd->_erase = spi_nor_erase;
> +	mtd->_read = spi_nor_read;
> +	mtd->_write = spi_nor_write;
> +	mtd->_suspend = spi_nor_suspend;
> +	mtd->_resume = spi_nor_resume;
> +	mtd->_get_device = spi_nor_get_device;
> +	mtd->_put_device = spi_nor_put_device;
> +}
> +
>  int spi_nor_scan(struct spi_nor *nor, const char *name,
>  		 const struct spi_nor_hwcaps *hwcaps)
>  {
> @@ -3166,32 +3196,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  
>  	mutex_init(&nor->lock);
>  
> -	mtd->_write = spi_nor_write;
> -
>  	/* Init flash parameters based on flash_info struct and SFDP */
>  	ret = spi_nor_init_params(nor);
>  	if (ret)
>  		return ret;
>  
> -	if (!mtd->name)
> -		mtd->name = dev_name(dev);
> -	mtd->type = MTD_NORFLASH;
> -	mtd->writesize = nor->params->writesize;
> -	mtd->flags = MTD_CAP_NORFLASH;
> -	mtd->size = nor->params->size;
> -	mtd->_erase = spi_nor_erase;
> -	mtd->_read = spi_nor_read;
> -	mtd->_suspend = spi_nor_suspend;
> -	mtd->_resume = spi_nor_resume;
> -	mtd->_get_device = spi_nor_get_device;
> -	mtd->_put_device = spi_nor_put_device;
> -
> -	if (info->flags & SPI_NOR_NO_ERASE)
> -		mtd->flags |= MTD_NO_ERASE;
> -
> -	mtd->dev.parent = dev;
>  	nor->page_size = nor->params->page_size;
> -	mtd->writebufsize = nor->page_size;
>  
>  	/*
>  	 * Configure the SPI memory:
> @@ -3207,15 +3217,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	if (ret)
>  		return ret;
>  
> -	spi_nor_register_locking_ops(nor);
> -
>  	/* Send all the required SPI flash commands to initialize device */
>  	ret = spi_nor_init(nor);
>  	if (ret)
>  		return ret;
>  
> -	/* Configure OTP parameters and ops */
> -	spi_nor_otp_init(nor);
> +	spi_nor_set_mtd_info(nor);
>  
>  	if (!nor->name)
>  		nor->name = info->name;
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Tue Aug 17 09:26:02 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 21:56:02 +0530
Subject: [PATCH v2 22/35] mtd: spi-nor: core: Use common naming scheme
 for setting mtd_info fields
In-Reply-To: <20210727045222.905056-23-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-23-tudor.ambarus@microchip.com>
Message-ID: <20210817162600.zzkfs3nv7iwucljq@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> The functions names are self explanatory, get rid of the comment
> for the OTP function.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

> ---
>  drivers/mtd/spi-nor/core.c | 6 ++----
>  drivers/mtd/spi-nor/core.h | 4 ++--
>  drivers/mtd/spi-nor/otp.c  | 2 +-
>  drivers/mtd/spi-nor/swp.c  | 2 +-
>  4 files changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 26acfc9901db..72dfe6274041 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3129,10 +3129,8 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
>  	struct mtd_info *mtd = &nor->mtd;
>  	struct device *dev = nor->dev;
>  
> -	spi_nor_register_locking_ops(nor);
> -
> -	/* Configure OTP parameters and ops */
> -	spi_nor_otp_init(nor);
> +	spi_nor_set_mtd_locking_ops(nor);
> +	spi_nor_set_mtd_otp_ops(nor);
>  
>  	mtd->dev.parent = dev;
>  	if (!mtd->name)
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 8fddc685d2d3..7fb0cfabe85a 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -552,8 +552,8 @@ int spi_nor_post_bfpt_fixups(struct spi_nor *nor,
>  
>  void spi_nor_init_default_locking_ops(struct spi_nor *nor);
>  void spi_nor_try_unlock_all(struct spi_nor *nor);
> -void spi_nor_register_locking_ops(struct spi_nor *nor);
> -void spi_nor_otp_init(struct spi_nor *nor);
> +void spi_nor_set_mtd_locking_ops(struct spi_nor *nor);
> +void spi_nor_set_mtd_otp_ops(struct spi_nor *nor);
>  
>  static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
>  {
> diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c
> index 983e40b19134..fa63d8571218 100644
> --- a/drivers/mtd/spi-nor/otp.c
> +++ b/drivers/mtd/spi-nor/otp.c
> @@ -480,7 +480,7 @@ static int spi_nor_mtd_otp_lock(struct mtd_info *mtd, loff_t from, size_t len)
>  	return ret;
>  }
>  
> -void spi_nor_otp_init(struct spi_nor *nor)
> +void spi_nor_set_mtd_otp_ops(struct spi_nor *nor)
>  {
>  	struct mtd_info *mtd = &nor->mtd;
>  
> diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
> index 8594bcbb7dbe..1f178313ba8f 100644
> --- a/drivers/mtd/spi-nor/swp.c
> +++ b/drivers/mtd/spi-nor/swp.c
> @@ -414,7 +414,7 @@ void spi_nor_try_unlock_all(struct spi_nor *nor)
>  		dev_dbg(nor->dev, "Failed to unlock the entire flash memory array\n");
>  }
>  
> -void spi_nor_register_locking_ops(struct spi_nor *nor)
> +void spi_nor_set_mtd_locking_ops(struct spi_nor *nor)
>  {
>  	struct mtd_info *mtd = &nor->mtd;
>  
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From alexandru.elisei at arm.com  Tue Aug 17 09:34:20 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 17 Aug 2021 17:34:20 +0100
Subject: [boot-wrapper PATCH] aarch64: Do not trap PMSNEVFR_EL1
Message-ID: <20210817163420.813631-1-alexandru.elisei@arm.com>

FEAT_PMUv1p2 adds a new register, PMSNEVFR_EL1, and a new MDCR_EL3 trap bit
for it, EnPMSN. Set the bit to 1 to allow lower exception levels direct
access to the register.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/aarch64/boot.S | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 2215f7ed3a1f..8951f1e4676a 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -88,8 +88,12 @@ ASM_FUNC(_start)
 	cbz	x1, 1f
 
 	// Enable SPE for the non-secure world.
-	ldr	x1, =(0x3 << 12)
-	orr	x0, x0, x1
+	ldr	x2, =(0x3 << 12)
+	orr	x0, x0, x2
+	cmp	x1, #3
+	b.lt	1
+	// Do not trap PMSNEVFR_EL1.
+	orr	x0, x0, #(1 << 36)
 
 1:	mrs	x1, id_aa64dfr0_el1
 	ubfx	x1, x1, #44, #4
-- 
2.32.0



From p.yadav at ti.com  Tue Aug 17 09:33:25 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 22:03:25 +0530
Subject: [PATCH v2 23/35] mtd: spi-nor: Get rid of nor->page_size
In-Reply-To: <20210727045222.905056-24-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-24-tudor.ambarus@microchip.com>
Message-ID: <20210817163323.zohq7fblo4hn37qk@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> nor->page_size duplicated what nor->params->page_size indicates
> for no good reason. page_size is a flash parameter of fixed value
> and it is better suited to be found in nor->params->page_size.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From pavlica.nikola at gmail.com  Tue Aug 17 09:36:05 2021
From: pavlica.nikola at gmail.com (Nikola Pavlica)
Date: Tue, 17 Aug 2021 18:36:05 +0200
Subject: [PATCH] drm/panel-simple: Add Vivax TPC-9150 panel v3
Message-ID: <20210817163605.1077257-1-pavlica.nikola@gmail.com>

The model and make of the LCD panel of the Vivax TPC-9150 is unknown,
hence the panel settings that were retrieved with a FEX dump are named
after the device NOT the actual panel.

The LCD in question is a 50 pin MISO TFT LCD panel of the resolution
1024x600 used by the aforementioned device.

Version 2, as Thierry kindly suggested that I fix the order in which the
panel was ordered compared to others.

Version 3, filling in the required info suggested by Sam. Plus some
factual issues that I've corrected myself (tested working)

Thanks,
Nikola

Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 29 ++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 4e2dad314c79..f6b3e58c162b 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3989,6 +3989,32 @@ static const struct panel_desc urt_umsh_8596md_parallel = {
 	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 };
 
+static const struct drm_display_mode vivax_tpc9150_panel_mode = {
+	.clock = 60000,
+	.hdisplay = 1024,
+	.hsync_start = 1024 + 160,
+	.hsync_end = 1024 + 160 + 100,
+	.htotal = 1024 + 160 + 100 + 60,
+	.vdisplay = 600,
+	.vsync_start = 600 + 12,
+	.vsync_end = 600 + 12 + 10,
+	.vtotal = 600 + 12 + 10 + 13,
+};
+
+static const struct panel_desc vivax_tpc9150_panel = {
+	.modes = &vivax_tpc9150_panel_mode,
+	.num_modes = 1,
+	.size = {
+		.width = 200,
+		.height = 115,
+	},
+	.bpc = 6,
+	.bus_format = MEDIA_BUS_FMT_RGB666_1X24,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
+
 static const struct drm_display_mode vl050_8048nt_c01_mode = {
 	.clock = 33333,
 	.hdisplay = 800,
@@ -4490,6 +4516,9 @@ static const struct of_device_id platform_of_match[] = {
 	}, {
 		.compatible = "urt,umsh-8596md-20t",
 		.data = &urt_umsh_8596md_parallel,
+	}, {
+		.compatible = "vivax,tpc9150-panel",
+		.data = &vivax_tpc9150_panel,
 	}, {
 		.compatible = "vxt,vl050-8048nt-c01",
 		.data = &vl050_8048nt_c01,
-- 
2.32.0



From gregory.clement at bootlin.com  Tue Aug 17 09:39:50 2021
From: gregory.clement at bootlin.com (Gregory CLEMENT)
Date: Tue, 17 Aug 2021 18:39:50 +0200
Subject: [PATCH 2/2] arm64: dts: marvell: armada-37xx: Extend PCIe MEM
 space
In-Reply-To: <20210624215546.4015-3-pali@kernel.org>
References: <20210624215546.4015-1-pali@kernel.org>
 <20210624215546.4015-3-pali@kernel.org>
Message-ID: <87bl5wyqi1.fsf@BL-laptop>

Pali Roh?r <pali at kernel.org> writes:

> Current PCIe MEM space of size 16 MB is not enough for some combination
> of PCIe cards (e.g. NVMe disk together with ath11k wifi card). ARM Trusted
> Firmware for Armada 3700 platform already assigns 128 MB for PCIe window,
> so extend PCIe MEM space to the end of 128 MB PCIe window which allows to
> allocate more PCIe BARs for more PCIe cards.
>
> Without this change some combination of PCIe cards cannot be used and
> kernel show error messages in dmesg during initialization:
>
>     pci 0000:00:00.0: BAR 8: no space for [mem size 0x01800000]
>     pci 0000:00:00.0: BAR 8: failed to assign [mem size 0x01800000]
>     pci 0000:00:00.0: BAR 6: assigned [mem 0xe8000000-0xe80007ff pref]
>     pci 0000:01:00.0: BAR 8: no space for [mem size 0x01800000]
>     pci 0000:01:00.0: BAR 8: failed to assign [mem size 0x01800000]
>     pci 0000:02:03.0: BAR 8: no space for [mem size 0x01000000]
>     pci 0000:02:03.0: BAR 8: failed to assign [mem size 0x01000000]
>     pci 0000:02:07.0: BAR 8: no space for [mem size 0x00100000]
>     pci 0000:02:07.0: BAR 8: failed to assign [mem size 0x00100000]
>     pci 0000:03:00.0: BAR 0: no space for [mem size 0x01000000 64bit]
>     pci 0000:03:00.0: BAR 0: failed to assign [mem size 0x01000000 64bit]
>
> Due to bugs in U-Boot port for Turris Mox, the second range in Turris Mox
> kernel DTS file for PCIe must start at 16 MB offset. Otherwise U-Boot
> crashes during loading of kernel DTB file. This bug is present only in
> U-Boot code for Turris Mox and therefore other Armada 3700 devices are not
> affected by this bug. Bug is fixed in U-Boot version 2021.07.
>
> To not break booting new kernels on existing versions of U-Boot on Turris
> Mox, use first 16 MB range for IO and second range with rest of PCIe window
> for MEM.
>
> Signed-off-by: Pali Roh?r <pali at kernel.org>

Applied on mvebu/dt64

Thanks,

Gregory

> Fixes: 76f6386b25cc ("arm64: dts: marvell: Add Aardvark PCIe support for Armada 3700")
> ---
>  .../boot/dts/marvell/armada-3720-turris-mox.dts | 17 +++++++++++++++++
>  arch/arm64/boot/dts/marvell/armada-37xx.dtsi    | 11 +++++++++--
>  2 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> index 53e817c5f6f3..86b3025f174b 100644
> --- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> +++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> @@ -134,6 +134,23 @@
>  	pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>;
>  	status = "okay";
>  	reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
> +	/*
> +	 * U-Boot port for Turris Mox has a bug which always expects that "ranges" DT property
> +	 * contains exactly 2 ranges with 3 (child) address cells, 2 (parent) address cells and
> +	 * 2 size cells and also expects that the second range starts at 16 MB offset. If these
> +	 * conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
> +	 * space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
> +	 * for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB.
> +	 * This bug is not present in U-Boot ports for other Armada 3700 devices and is fixed in
> +	 * U-Boot version 2021.07. See relevant U-Boot commits (the last one contains fix):
> +	 * https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
> +	 * https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf
> +	 * https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33
> +	 */
> +	#address-cells = <3>;
> +	#size-cells = <2>;
> +	ranges = <0x81000000 0 0xe8000000   0 0xe8000000   0 0x01000000   /* Port 0 IO */
> +		  0x82000000 0 0xe9000000   0 0xe9000000   0 0x07000000>; /* Port 0 MEM */
>  
>  	/* enabled by U-Boot if PCIe module is present */
>  	status = "disabled";
> diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> index 7a2df148c6a3..dac3007f2ac1 100644
> --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> @@ -488,8 +488,15 @@
>  			#interrupt-cells = <1>;
>  			msi-parent = <&pcie0>;
>  			msi-controller;
> -			ranges = <0x82000000 0 0xe8000000   0 0xe8000000 0 0x1000000 /* Port 0 MEM */
> -				  0x81000000 0 0xe9000000   0 0xe9000000 0 0x10000>; /* Port 0 IO*/
> +			/*
> +			 * The 128 MiB address range [0xe8000000-0xf0000000] is
> +			 * dedicated for PCIe and can be assigned to 8 windows
> +			 * with size a power of two. Use one 64 KiB window for
> +			 * IO at the end and the remaining seven windows
> +			 * (totaling 127 MiB) for MEM.
> +			 */
> +			ranges = <0x82000000 0 0xe8000000   0 0xe8000000   0 0x07f00000   /* Port 0 MEM */
> +				  0x81000000 0 0xefff0000   0 0xefff0000   0 0x00010000>; /* Port 0 IO */
>  			interrupt-map-mask = <0 0 0 7>;
>  			interrupt-map = <0 0 0 1 &pcie_intc 0>,
>  					<0 0 0 2 &pcie_intc 1>,
> -- 
> 2.20.1
>

-- 
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com


From p.yadav at ti.com  Tue Aug 17 09:47:51 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 22:17:51 +0530
Subject: [PATCH v2 24/35] mtd: spi-nor: core: Fix spi_nor_flash_parameter
 otp description
In-Reply-To: <20210727045222.905056-25-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-25-tudor.ambarus@microchip.com>
Message-ID: <20210817164749.fzihdqop3mtddpbu@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Update the description of the otp member of the
> struct spi_nor_flash_parameter.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

> ---
>  drivers/mtd/spi-nor/core.h | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 7fb0cfabe85a..501d9212ba9b 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -250,7 +250,7 @@ struct spi_nor_otp {
>   *                      higher index in the array, the higher priority.
>   * @erase_map:		the erase map parsed from the SFDP Sector Map Parameter
>   *                      Table.
> - * @otp_info:		describes the OTP regions.
> + * @otp:		SPI NOR OTP info.
>   * @octal_dtr_enable:	enables SPI NOR octal DTR mode.
>   * @quad_enable:	enables SPI NOR quad mode.
>   * @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
> @@ -262,7 +262,6 @@ struct spi_nor_otp {
>   *                      e.g. different opcodes, specific address calculation,
>   *                      page size, etc.
>   * @locking_ops:	SPI NOR locking methods.
> - * @otp:		SPI NOR OTP methods.
>   */
>  struct spi_nor_flash_parameter {
>  	u64				size;
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From jbx6244 at gmail.com  Tue Aug 17 09:52:15 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Tue, 17 Aug 2021 18:52:15 +0200
Subject: [PATCH v2 2/8] dt-bindings: phy: phy-rockchip-inno-usb2: add
 rk3568 documentation
In-Reply-To: <20210812204116.2303617-3-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
 <20210812204116.2303617-3-pgwipeout@gmail.com>
Message-ID: <c7ff9234-cc3b-3679-bc63-73c5eb825269@gmail.com>

Hi Peter,

Some comments. Have a look if it's useful.

On 8/12/21 10:41 PM, Peter Geis wrote:
> The rk3568 usb2phy node is a standalone node with a single muxed
> interrupt.
> Add documentation for it to phy-rockchip-inno-usb2.
> 
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
>  .../bindings/phy/phy-rockchip-inno-usb2.yaml  | 31 ++++++++++++++++---
>  1 file changed, 27 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> index 5bebd86bf8b6..d2a749c3f9a3 100644
> --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> @@ -18,6 +18,7 @@ properties:
>        - rockchip,rk3328-usb2phy
>        - rockchip,rk3366-usb2phy
>        - rockchip,rk3399-usb2phy
> +      - rockchip,rk3568-usb2phy
>        - rockchip,rv1108-usb2phy
>  
>    reg:
> @@ -50,6 +51,9 @@ properties:
>      description:
>        Phandle to the extcon device providing the cable state for the otg phy.
>  

> +  interrupts:
> +    description: Muxed interrupt for both ports
> +

This allows every Rockchip SoC dtsi to add an interrupt here.
You have only restricted the requirements.
The goal is to restrict things and filter bogus properties.
If it was done because it doesn't compile, maybe could you try/test/use
something like the rockchip-io-domain.yaml $defs format.

===

unevaluatedProperties: false

allOf:
  - $ref: "#/$defs/rk3568"

$defs:
  rk3568:
    if:
      properties:
        compatible:
          contains:
            const: rockchip,rk3568-usb2phy

    then:
      properties:
        interrupts:
          maxItems: 1

      required:
        - interrupts

    else:
      properties:
        host-port:
          properties:
            interrupts:
              description: host linestate interrupt

            interrupt-names:
              const: linestate

          required:
            - interrupts
            - interrupt-names

        otg-port:
          properties:

           interrupts:
             minItems: 1
             maxItems: 3

           interrupt-names:
             oneOf:
               - const: linestate
               - const: otg-mux
               - items:
                   - const: otg-bvalid
                   - const: otg-id
                   - const: linestate

          required:
            - interrupts
            - interrupt-names

>    rockchip,usbgrf:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description:
> @@ -78,8 +82,6 @@ properties:
>  
>      required:
>        - "#phy-cells"

> -      - interrupts
> -      - interrupt-names

Also remove them as properties in this part when a separate $defs is used.

>  
>    otg-port:
>      type: object
> @@ -109,8 +111,6 @@ properties:
>  
>      required:
>        - "#phy-cells"

> -      - interrupts
> -      - interrupt-names

dito

>  
>  required:
>    - compatible
> @@ -120,6 +120,29 @@ required:
>    - host-port
>    - otg-port
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: rockchip,rk3568-usb2phy

> +      then:

Test "if then else" alignment with yamllint

> +        properties:
> +          interrupts:
> +            maxItems: 1
> +        required:
> +          - interrupts

> +      else:

alignment

> +        properties:
> +          host-port:
> +            required:
> +              - interrupts
> +              - interrupt-names
> +          otg-port:
> +            required:
> +              - interrupts
> +              - interrupt-names
> +

>  additionalProperties: false

additionalProperties does workn't with allOf: - $ref. Use
unevaluatedProperties.

>  
>  examples:
> 


From gregory.clement at bootlin.com  Tue Aug 17 09:52:13 2021
From: gregory.clement at bootlin.com (Gregory CLEMENT)
Date: Tue, 17 Aug 2021 18:52:13 +0200
Subject: [GIT PULL] ARM: mvebu: dt64 for v5.15 (#1)
Message-ID: <878s10ypxe.fsf@BL-laptop>

Hi,

Here is the first pull request for dt64 for mvebu for v5.15.

Gregory

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu.git tags/mvebu-dt64-5.15-1

for you to fetch changes up to 514ef1e62d6521c2199d192b1c71b79d2aa21d5a:

  arm64: dts: marvell: armada-37xx: Extend PCIe MEM space (2021-08-17 18:30:14 +0200)

----------------------------------------------------------------
mvebu dt64 for 5.15 (part 1)

 - DTS updates for Marvell Armada CN913x platforms

   + Add support for Armada CN913x Development Board topology "B"
   + Add support for Armada CN913x Reference Design boards (CRB)
   + Fixes the NAND partitioning scheme in DTS eliminating gap between
     consecutive partitions
   + Fix 10Gb ports PHY mode names

 - Extend PCIe MEM space on Armada 37xx: useful for some combination
    of PCIe cards where the initial 16MB was not enough

----------------------------------------------------------------
Konstantin Porotchkin (3):
      arm64: dts: cn913x: add device trees for topology B boards
      arm64: dts: add support for Marvell cn9130-crb platform
      arch/arm64: dts: change 10gbase-kr to 10gbase-r in Armada

Pali Roh?r (1):
      arm64: dts: marvell: armada-37xx: Extend PCIe MEM space

Stefan Chulski (1):
      dts: marvell: Enable 10G interfaces on 9130-DB and 9131-DB boards

 arch/arm64/boot/dts/marvell/Makefile               |   5 +
 .../boot/dts/marvell/armada-3720-turris-mox.dts    |  17 +
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi       |  11 +-
 arch/arm64/boot/dts/marvell/armada-7040-db.dts     |   2 +-
 arch/arm64/boot/dts/marvell/armada-8040-db.dts     |   4 +-
 arch/arm64/boot/dts/marvell/cn9130-crb-A.dts       |  38 ++
 arch/arm64/boot/dts/marvell/cn9130-crb-B.dts       |  46 +++
 arch/arm64/boot/dts/marvell/cn9130-crb.dtsi        | 222 +++++++++++
 arch/arm64/boot/dts/marvell/cn9130-db-B.dts        |  22 ++
 arch/arm64/boot/dts/marvell/cn9130-db.dts          | 403 +-------------------
 arch/arm64/boot/dts/marvell/cn9130-db.dtsi         | 410 +++++++++++++++++++++
 arch/arm64/boot/dts/marvell/cn9131-db-B.dts        |  22 ++
 arch/arm64/boot/dts/marvell/cn9131-db.dts          | 197 +---------
 arch/arm64/boot/dts/marvell/cn9131-db.dtsi         | 206 +++++++++++
 arch/arm64/boot/dts/marvell/cn9132-db-B.dts        |  22 ++
 arch/arm64/boot/dts/marvell/cn9132-db.dts          | 218 +----------
 arch/arm64/boot/dts/marvell/cn9132-db.dtsi         | 227 ++++++++++++
 17 files changed, 1267 insertions(+), 805 deletions(-)
 create mode 100644 arch/arm64/boot/dts/marvell/cn9130-crb-A.dts
 create mode 100644 arch/arm64/boot/dts/marvell/cn9130-crb-B.dts
 create mode 100644 arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
 create mode 100644 arch/arm64/boot/dts/marvell/cn9130-db-B.dts
 create mode 100644 arch/arm64/boot/dts/marvell/cn9130-db.dtsi
 create mode 100644 arch/arm64/boot/dts/marvell/cn9131-db-B.dts
 create mode 100644 arch/arm64/boot/dts/marvell/cn9131-db.dtsi
 create mode 100644 arch/arm64/boot/dts/marvell/cn9132-db-B.dts
 create mode 100644 arch/arm64/boot/dts/marvell/cn9132-db.dtsi
-- 
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com


From p.yadav at ti.com  Tue Aug 17 09:52:57 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 17 Aug 2021 22:22:57 +0530
Subject: [PATCH v2 25/35] mtd: spi-nor: core: Move
 spi_nor_set_addr_width() in spi_nor_setup()
In-Reply-To: <20210727045222.905056-26-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-26-tudor.ambarus@microchip.com>
Message-ID: <20210817165255.kuhp7tzfuk54a3cg@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> spi_nor_setup() configures the SPI NOR memory. Setting the addr width
> is too a configuration, hence we can move the spi_nor_set_addr_width()
> in spi_nor_setup().
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav at ti.com>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From len.baker at gmx.com  Tue Aug 17 09:58:59 2021
From: len.baker at gmx.com (Len Baker)
Date: Tue, 17 Aug 2021 18:58:59 +0200
Subject: [PATCH] i2c: sun6i-pw2i: Prefer strscpy over strlcpy
Message-ID: <20210817165859.5429-1-len.baker@gmx.com>

strlcpy() reads the entire source buffer first. This read may exceed the
destination size limit. This is both inefficient and can lead to linear
read overflows if a source string is not NUL-terminated. The safe
replacement is strscpy().

This is a previous step in the path to remove the strlcpy() function
entirely from the kernel [1].

[1] https://github.com/KSPP/linux/issues/89

Signed-off-by: Len Baker <len.baker at gmx.com>
---
 drivers/i2c/busses/i2c-sun6i-p2wi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
index 2f6f6468214d..9e3483f507ff 100644
--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
@@ -234,7 +234,7 @@ static int p2wi_probe(struct platform_device *pdev)
 	if (IS_ERR(p2wi->regs))
 		return PTR_ERR(p2wi->regs);

-	strlcpy(p2wi->adapter.name, pdev->name, sizeof(p2wi->adapter.name));
+	strscpy(p2wi->adapter.name, pdev->name, sizeof(p2wi->adapter.name));
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return irq;
--
2.25.1



From bigeasy at linutronix.de  Tue Aug 17 10:09:25 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Tue, 17 Aug 2021 19:09:25 +0200
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <20210811201354.1976839-3-valentin.schneider@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
Message-ID: <20210817170925.2jwqvgvmqab2glwu@linutronix.de>

On 2021-08-11 21:13:52 [+0100], Valentin Schneider wrote:
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index debc960f41e3..8ba7b4a7ee69 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
>  #endif
>  }
>  
> +/* Is the current task guaranteed to stay on its current CPU? */
> +static inline bool migratable(void)

I'm going to rename this in my tree to `is_migratable' because of
|security/keys/trusted-keys/trusted_core.c:45:22: error: ?migratable? redeclared as different kind of symbol
|   45 | static unsigned char migratable;
|      |                      ^~~~~~~~~~
|In file included from arch/arm64/include/asm/compat.h:16,
|                 from arch/arm64/include/asm/stat.h:13,
|                 from include/linux/stat.h:6,
|                 from include/linux/sysfs.h:22,
|                 from include/linux/kobject.h:20,
|                 from include/linux/of.h:17,
|                 from include/linux/irqdomain.h:35,
|                 from include/linux/acpi.h:13,
|                 from include/linux/tpm.h:21,
|                 from include/keys/trusted-type.h:12,
|                 from security/keys/trusted-keys/trusted_core.c:10:
|include/linux/sched.h:1719:20: note: previous definition of ?migratable? was here
| 1719 | static inline bool migratable(void)
|      |                    ^~~~~~~~~~

Sebastian


From broonie at kernel.org  Tue Aug 17 10:13:30 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 17 Aug 2021 18:13:30 +0100
Subject: [PATCH] arm64/sve: Better handle failure to allocate SVE register
 storage
Message-ID: <20210817171330.25847-1-broonie@kernel.org>

Currently we "handle" failure to allocate the SVE register storage by
doing a BUG_ON() and hoping for the best. This is obviously not great and
the memory allocation failure will already be loud enough without the
BUG_ON(). As the comment says it is a corner case but let's try to do a bit
better, remove the BUG_ON() and add code to handle the failure in the
callers.

For the ptrace and signal code we can return -ENOMEM gracefully however
we have no real error reporting path available to us for the SVE access
trap so instead generate a SIGKILL if the allocation fails there. This
at least means that we won't try to soldier on and end up trying to
access the nonexistant state and while it's obviously not ideal for
userspace SIGKILL doesn't allow any handling so minimises the ABI
impact, making it easier to improve the interface later if we come up
with a better idea.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 10 ++++------
 arch/arm64/kernel/ptrace.c |  4 ++++
 arch/arm64/kernel/signal.c |  3 +++
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index eb8d972ad3d2..5a294f20e9de 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -520,12 +520,6 @@ void sve_alloc(struct task_struct *task)
 	/* This is a small allocation (maximum ~8KB) and Should Not Fail. */
 	task->thread.sve_state =
 		kzalloc(sve_state_size(task), GFP_KERNEL);
-
-	/*
-	 * If future SVE revisions can have larger vectors though,
-	 * this may cease to be true:
-	 */
-	BUG_ON(!task->thread.sve_state);
 }
 
 
@@ -945,6 +939,10 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
 	}
 
 	sve_alloc(current);
+	if (!current->thread.sve_state) {
+		force_sig(SIGKILL);
+		return;
+	}
 
 	get_cpu_fpsimd_context();
 
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index b381a1ee9ea7..8bb3376b53fe 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -845,6 +845,10 @@ static int sve_set(struct task_struct *target,
 	}
 
 	sve_alloc(target);
+	if (!target->thread.sve_state) {
+		ret = -ENOMEM;
+		goto out;
+	}
 
 	/*
 	 * Ensure target->thread.sve_state is up to date with target's
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index aa46168bff32..34ea71ea6126 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -290,6 +290,9 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
 
 	sve_alloc(current);
+	if (!current->thread.sve_state)
+		return -ENOMEM;
+
 	err = __copy_from_user(current->thread.sve_state,
 			       (char __user const *)user->sve +
 					SVE_SIG_REGS_OFFSET,
-- 
2.20.1



From frieder.schrempf at kontron.de  Tue Aug 17 10:38:42 2021
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Tue, 17 Aug 2021 19:38:42 +0200
Subject: [PATCH v4 4/5] ARM: dts: imx6ull: add rng
In-Reply-To: <4f30d822-9db7-4a54-c082-fa9f54982b42@kontron.de>
References: <20200715152604.10407-1-horia.geanta@nxp.com>
 <20200715152604.10407-5-horia.geanta@nxp.com>
 <4f30d822-9db7-4a54-c082-fa9f54982b42@kontron.de>
Message-ID: <1246c765-0bbe-9143-6214-94b7ebcb6151@kontron.de>

On 17.08.21 17:39, Frieder Schrempf wrote:
> Hi,
> 
> On 15.07.20 17:26, Horia Geant? wrote:
>> Add node for the RNGB block.
>>
>> Signed-off-by: Horia Geant? <horia.geanta at nxp.com>
>> Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
>> ---
>>  arch/arm/boot/dts/imx6ull.dtsi | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
>> index fcde7f77ae42..9bf67490ac49 100644
>> --- a/arch/arm/boot/dts/imx6ull.dtsi
>> +++ b/arch/arm/boot/dts/imx6ull.dtsi
>> @@ -68,6 +68,13 @@
>>  				clock-names = "dcp";
>>  			};
>>  
>> +			rngb: rng at 2284000 {
>> +				compatible = "fsl,imx6ull-rngb", "fsl,imx25-rngb";
>> +				reg = <0x02284000 0x4000>;
>> +				interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
>> +				clocks = <&clks IMX6UL_CLK_DUMMY>;
>> +			};
>> +
> 
> My board (imx6ull-kontron-n6411-s.dts) fails to boot since this was added in v5.10-rc1. There is a crash in the RNG probe. Can anyone help?
> Below is the interesting part of the boot log from v5.14-rc6.

I just found out, that I was trying to boot on an i.MX6UL when I was assuming the board had an i.MX6ULL. That won't work of course. Sorry for the noise!


From sam at ravnborg.org  Tue Aug 17 10:41:57 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Tue, 17 Aug 2021 19:41:57 +0200
Subject: [PATCH] drm/panel-simple: Add Vivax TPC-9150 panel v3
In-Reply-To: <20210817163605.1077257-1-pavlica.nikola@gmail.com>
References: <20210817163605.1077257-1-pavlica.nikola@gmail.com>
Message-ID: <YRv05QbPz4lBQG8E@ravnborg.org>

Hi Nikola,

thanks for the quick re-spin. There is still a few things that needs to
be addressed though. Sorry for not catching these the first time.

On Tue, Aug 17, 2021 at 06:36:05PM +0200, Nikola Pavlica wrote:
> The model and make of the LCD panel of the Vivax TPC-9150 is unknown,
> hence the panel settings that were retrieved with a FEX dump are named
HEX dump?

> after the device NOT the actual panel.
> 
> The LCD in question is a 50 pin MISO TFT LCD panel of the resolution
> 1024x600 used by the aforementioned device.
> 
> Version 2, as Thierry kindly suggested that I fix the order in which the
> panel was ordered compared to others.
> 
> Version 3, filling in the required info suggested by Sam. Plus some
> factual issues that I've corrected myself (tested working)
> 
> Thanks,
> Nikola
> 
> Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
> ---
>  drivers/gpu/drm/panel/panel-simple.c | 29 ++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 4e2dad314c79..f6b3e58c162b 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -3989,6 +3989,32 @@ static const struct panel_desc urt_umsh_8596md_parallel = {
>  	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
>  };
>  
> +static const struct drm_display_mode vivax_tpc9150_panel_mode = {
> +	.clock = 60000,
> +	.hdisplay = 1024,
> +	.hsync_start = 1024 + 160,
> +	.hsync_end = 1024 + 160 + 100,
> +	.htotal = 1024 + 160 + 100 + 60,
> +	.vdisplay = 600,
> +	.vsync_start = 600 + 12,
> +	.vsync_end = 600 + 12 + 10,
> +	.vtotal = 600 + 12 + 10 + 13,
> +};
> +
> +static const struct panel_desc vivax_tpc9150_panel = {
> +	.modes = &vivax_tpc9150_panel_mode,
> +	.num_modes = 1,
Most panels put .bpc right above .size, so they follow the order in the
struct. This is bikeshedding but my OCD triggered here.

> +	.size = {
> +		.width = 200,
> +		.height = 115,
> +	},
> +	.bpc = 6,
> +	.bus_format = MEDIA_BUS_FMT_RGB666_1X24,
This does not build - I have no MEDIA_BUS_FMT_RGB666_1X24 in my kernel
(drm-misc-next).

With an LVDS connector and bpc equals 6 my bet is on: MEDIA_BUS_FMT_RGB666_1X7X3_SPWG
This is from looking at similar panels.


> +	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
> +	.connector_type = DRM_MODE_CONNECTOR_LVDS,
> +};
> +
> +
>  static const struct drm_display_mode vl050_8048nt_c01_mode = {
>  	.clock = 33333,
>  	.hdisplay = 800,
> @@ -4490,6 +4516,9 @@ static const struct of_device_id platform_of_match[] = {
>  	}, {
>  		.compatible = "urt,umsh-8596md-20t",
>  		.data = &urt_umsh_8596md_parallel,
> +	}, {
> +		.compatible = "vivax,tpc9150-panel",
vivax is an unknown vendor, needs to be added to
Documentation/devicetree/bindings/vendor-prefixes.yaml in a separate
patch.

tpc9150-panel should be added to
Documentation/devicetree/bindings/display/panel/panel-simple.yaml
or at least I assume this is the file to add it to.
Again as a separate patch.

For the two binding related patches see
Documentation/devicetree/bindings/submitting-patches.rst

Sorry for making this difficult, but we need it done right.

	Sam


From nicolas.dufresne at collabora.com  Tue Aug 17 10:49:48 2021
From: nicolas.dufresne at collabora.com (Nicolas Dufresne)
Date: Tue, 17 Aug 2021 13:49:48 -0400
Subject: [PATCH v3 05/10] media: uapi: Add VP9 stateless decoder controls
In-Reply-To: <20210805144246.11998-6-andrzej.p@collabora.com>
References: <20210805144246.11998-1-andrzej.p@collabora.com>
 <20210805144246.11998-6-andrzej.p@collabora.com>
Message-ID: <0fd8f0cfd231be2e11da218b0401e1b0e0a15cca.camel@collabora.com>

Le jeudi 05 ao?t 2021 ? 16:42 +0200, Andrzej Pietrasiewicz a ?crit?:
> Add the VP9 stateless decoder controls plus the documentation that goes
> with it.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
> Co-developed-by: Ezequiel Garcia <ezequiel at collabora.com>
> Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
> Signed-off-by: Adrian Ratiu <adrian.ratiu at collabora.com>
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at collabora.com>
> Co-developed-by: Daniel Almeida <daniel.almeida at collabora.com>
> Signed-off-by: Daniel Almeida <daniel.almeida at collabora.com>
> ---
>  .../userspace-api/media/v4l/biblio.rst        |  10 +
>  .../media/v4l/ext-ctrls-codec-stateless.rst   | 545 ++++++++++++++++++
>  .../media/v4l/pixfmt-compressed.rst           |  15 +
>  .../media/v4l/vidioc-g-ext-ctrls.rst          |   8 +
>  .../media/v4l/vidioc-queryctrl.rst            |  12 +
>  .../media/videodev2.h.rst.exceptions          |   2 +
>  drivers/media/v4l2-core/v4l2-ctrls-core.c     | 174 ++++++
>  drivers/media/v4l2-core/v4l2-ctrls-defs.c     |   8 +
>  drivers/media/v4l2-core/v4l2-ioctl.c          |   1 +
>  include/media/v4l2-ctrls.h                    |   4 +
>  include/uapi/linux/v4l2-controls.h            | 433 ++++++++++++++
>  include/uapi/linux/videodev2.h                |   6 +
>  12 files changed, 1218 insertions(+)
> 
> diff --git a/Documentation/userspace-api/media/v4l/biblio.rst b/Documentation/userspace-api/media/v4l/biblio.rst
> index 7b8e6738ff9e..9cd18c153d19 100644
> --- a/Documentation/userspace-api/media/v4l/biblio.rst
> +++ b/Documentation/userspace-api/media/v4l/biblio.rst
> @@ -417,3 +417,13 @@ VP8
>  :title:     RFC 6386: "VP8 Data Format and Decoding Guide"
>  
>  :author:    J. Bankoski et al.
> +
> +.. _vp9:
> +
> +VP9
> +===
> +
> +
> +:title:     VP9 Bitstream & Decoding Process Specification
> +
> +:author:    Adrian Grange (Google), Peter de Rivaz (Argon Design), Jonathan Hunt (Argon Design)
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
> index 72f5e85b4f34..af06d46e5993 100644
> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
> @@ -1458,3 +1458,548 @@ FWHT Flags
>  .. raw:: latex
>  
>      \normalsize
> +
> +.. _v4l2-codec-stateless-vp9:
> +
> +``V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS (struct)``
> +    Stores VP9 probabilities updates as parsed from the current compressed frame
> +    header. A value of zero in an array element means no update of the relevant
> +    probability. Motion vector-related updates contain a new value or zero. All
> +    other updates contain values translated with inv_map_table[] (see 6.3.5 in
> +    :ref:`vp9`).

As we discuss, widewine and other crypto may encrypt the compressed headers, so
passing this information is not always possible from userspace. Newer VP9
decoders (notably newer Rockchip decoder) are being being extended with full HW
support for compressed header handling including probability updates. Regardless
if we like drm or not, we should at least make sure the spec allow to optimize
and skip this control.

Documenting this will reassure driver writers that don't need it and will let
userspace devs know that they should check the control presence and can then
skip the associate entropy decoding if not needed.

> +
> +.. c:type:: v4l2_ctrl_vp9_compressed_hdr_probs
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}|
> +
> +.. flat-table:: struct v4l2_ctrl_vp9_compressed_hdr_probs
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 1 2
> +
> +    * - __u8
> +      - ``tx8[2][1]``
> +      - TX 8x8 probabilities delta.
> +    * - __u8
> +      - ``tx16[2][2]``
> +      - TX 16x16 probabilities delta.
> +    * - __u8
> +      - ``tx32[2][3]``
> +      - TX 32x32 probabilities delta.
> +    * - __u8
> +      - ``coef[4][2][2][6][6][3]``
> +      - Coefficient probabilities delta.
> +    * - __u8
> +      - ``skip[3]``
> +      - Skip probabilities delta.
> +    * - __u8
> +      - ``inter_mode[7][3]``
> +      - Inter prediction mode probabilities delta.
> +    * - __u8
> +      - ``interp_filter[4][2]``
> +      - Interpolation filter probabilities delta.
> +    * - __u8
> +      - ``is_inter[4]``
> +      - Is inter-block probabilities delta.
> +    * - __u8
> +      - ``comp_mode[5]``
> +      - Compound prediction mode probabilities delta.
> +    * - __u8
> +      - ``single_ref[5][2]``
> +      - Single reference probabilities delta.
> +    * - __u8
> +      - ``comp_ref[5]``
> +      - Compound reference probabilities delta.
> +    * - __u8
> +      - ``y_mode[4][9]``
> +      - Y prediction mode probabilities delta.
> +    * - __u8
> +      - ``uv_mode[10][9]``
> +      - UV prediction mode probabilities delta.
> +    * - __u8
> +      - ``partition[16][3]``
> +      - Partition probabilities delta.
> +    * - __u8
> +      - ``mv.joint[3]``
> +      - Motion vector joint probabilities delta.
> +    * - __u8
> +      - ``mv.sign[2]``
> +      - Motion vector sign probabilities delta.
> +    * - __u8
> +      - ``mv.classes[2][10]``
> +      - Motion vector class probabilities delta.
> +    * - __u8
> +      - ``mv.class0_bit[2]``
> +      - Motion vector class0 bit probabilities delta.
> +    * - __u8
> +      - ``mv.bits[2][10]``
> +      - Motion vector bits probabilities delta.
> +    * - __u8
> +      - ``mv.class0_fr[2][2][3]``
> +      - Motion vector class0 fractional bit probabilities delta.
> +    * - __u8
> +      - ``mv.fr[2][3]``
> +      - Motion vector fractional bit probabilities delta.
> +    * - __u8
> +      - ``mv.class0_hp[2]``
> +      - Motion vector class0 high precision fractional bit probabilities delta.
> +    * - __u8
> +      - ``mv.hp[2]``
> +      - Motion vector high precision fractional bit probabilities delta.
> +
> +``V4L2_CID_STATELESS_VP9_FRAME (struct)``
> +    Specifies the frame parameters for the associated VP9 frame decode request.
> +    This includes the necessary parameters for configuring a stateless hardware
> +    decoding pipeline for VP9. The bitstream parameters are defined according
> +    to :ref:`vp9`.
> +
> +.. c:type:: v4l2_ctrl_vp9_frame
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: struct v4l2_ctrl_vp9_frame
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 1 2
> +
> +    * - struct :c:type:`v4l2_vp9_loop_filter`
> +      - ``lf``
> +      - Loop filter parameters. See struct :c:type:`v4l2_vp9_loop_filter` for more details.
> +    * - struct :c:type:`v4l2_vp9_quantization`
> +      - ``quant``
> +      - Quantization parameters. See :c:type:`v4l2_vp9_quantization` for more details.
> +    * - struct :c:type:`v4l2_vp9_segmentation`
> +      - ``seg``
> +      - Segmentation parameters. See :c:type:`v4l2_vp9_segmentation` for more details.
> +    * - __u32
> +      - ``flags``
> +      - Combination of V4L2_VP9_FRAME_FLAG_* flags. See :c:type:`v4l2_vp9_frame_flags`.
> +    * - __u16
> +      - ``compressed_header_size``
> +      - Compressed header size in bytes.
> +    * - __u16
> +      - ``uncompressed_header_size``
> +      - Uncompressed header size in bytes.
> +    * - __u16
> +      - ``frame_width_minus_1``
> +      - Add 1 to get the frame width expressed in pixels. See section 7.2.3 in :ref:`vp9`.
> +    * - __u16
> +      - ``frame_height_minus_1``
> +      - Add 1 to get the frame height expressed in pixels. See section 7.2.3 in :ref:`vp9`.
> +    * - __u16
> +      - ``render_width_minus_1``
> +      - Add 1 to get the expected render width expressed in pixels. This is
> +        not used during the decoding process but might be used by HW scalers to
> +        prepare a frame that's ready for scanout. See section 7.2.4 in :ref:`vp9`.
> +    * - __u16
> +      - render_height_minus_1
> +      - Add 1 to get the expected render height expressed in pixels. This is
> +        not used during the decoding process but might be used by HW scalers to
> +        prepare a frame that's ready for scanout. See section 7.2.4 in :ref:`vp9`.
> +    * - __u64
> +      - ``last_frame_ts``
> +      - "last" reference buffer timestamp.
> +	The timestamp refers to the ``timestamp`` field in
> +        struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
> +        function to convert the struct :c:type:`timeval` in struct
> +        :c:type:`v4l2_buffer` to a __u64.
> +    * - __u64
> +      - ``golden_frame_ts``
> +      - "golden" reference buffer timestamp.
> +	The timestamp refers to the ``timestamp`` field in
> +        struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
> +        function to convert the struct :c:type:`timeval` in struct
> +        :c:type:`v4l2_buffer` to a __u64.
> +    * - __u64
> +      - ``alt_frame_ts``
> +      - "alt" reference buffer timestamp.
> +	The timestamp refers to the ``timestamp`` field in
> +        struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
> +        function to convert the struct :c:type:`timeval` in struct
> +        :c:type:`v4l2_buffer` to a __u64.
> +    * - __u8
> +      - ``ref_frame_sign_bias``
> +      - a bitfield specifying whether the sign bias is set for a given
> +        reference frame. See :c:type:`v4l2_vp9_ref_frame_sign_bias` for more details.
> +    * - __u8
> +      - ``reset_frame_context``
> +      - specifies whether the frame context should be reset to default values. See
> +        :c:type:`v4l2_vp9_reset_frame_context` for more details.
> +    * - __u8
> +      - ``frame_context_idx``
> +      - Frame context that should be used/updated.
> +    * - __u8
> +      - ``profile``
> +      - VP9 profile. Can be 0, 1, 2 or 3.
> +    * - __u8
> +      - ``bit_depth``
> +      - Component depth in bits. Can be 8, 10 or 12. Note that not all profiles
> +        support 10 and/or 12 bits depths.
> +    * - __u8
> +      - ``interpolation_filter``
> +      - Specifies the filter selection used for performing inter prediction. See
> +        :c:type:`v4l2_vp9_interpolation_filter` for more details.
> +    * - __u8
> +      - ``tile_cols_log2``
> +      - Specifies the base 2 logarithm of the width of each tile (where the
> +        width is measured in units of 8x8 blocks). Shall be less than or equal
> +        to 6.
> +    * - __u8
> +      - ``tile_rows_log2``
> +      - Specifies the base 2 logarithm of the height of each tile (where the
> +        height is measured in units of 8x8 blocks).
> +    * - __u8
> +      - ``tx_mode``
> +      - Specifies the TX mode. See :c:type:`v4l2_vp9_tx_mode` for more details.
> +    * - __u8
> +      - ``reference_mode``
> +      - Specifies the type of inter prediction to be used. See
> +        :c:type:`v4l2_vp9_reference_mode` for more details.
> +    * - __u8
> +      - ``reserved[6]``
> +      - Applications and drivers must set this to zero.
> +
> +.. c:type:: v4l2_vp9_frame_flags
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_frame_flags
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_FRAME_FLAG_KEY_FRAME``
> +      - The frame is a key frame.
> +    * - ``V4L2_VP9_FRAME_FLAG_SHOW_FRAME``
> +      - The frame should be displayed.
> +    * - ``V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT``
> +      - The decoding should be error resilient.
> +    * - ``V4L2_VP9_FRAME_FLAG_INTRA_ONLY``
> +      - The frame does not reference other frames.
> +    * - ``V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV``
> +      - The frame can use high precision motion vectors.
> +    * - ``V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX``
> +      - Frame context should be updated after decoding.
> +    * - ``V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE``
> +      - Parallel decoding is used.
> +    * - ``V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING``
> +      - Vertical subsampling is enabled.
> +    * - ``V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING``
> +      - Horizontal subsampling is enabled.
> +    * - ``V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING``
> +      - The full UV range is used.
> +
> +.. c:type:: v4l2_vp9_tx_mode
> +
> +See section '7.3.1 Tx mode semantics' of the VP9 specification for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_tx_mode
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_TX_MODE_ONLY_4X4``
> +      - Transform size is 4x4.
> +    * - ``V4L2_VP9_TX_MODE_ALLOW_8X8``
> +      - Transform size can be up to 8x8.
> +    * - ``V4L2_VP9_TX_MODE_ALLOW_16X16``
> +      - Transform size can be up to 16x16.
> +    * - ``V4L2_VP9_TX_MODE_ALLOW_32X32``
> +      - transform size can be up to 32x32.
> +    * - ``V4L2_VP9_TX_MODE_SELECT``
> +      - Bitstream contains the transform size for each block.
> +
> +.. c:type:: v4l2_vp9_reference_mode
> +
> +See section '7.3.6 Frame reference mode semantics' of the VP9 specification for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_reference_mode
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE``
> +      - Indicates that all the inter blocks use only a single reference frame
> +        to generate motion compensated prediction.
> +    * - ``V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE``
> +      - Requires all the inter blocks to use compound mode. Single reference
> +        frame prediction is not allowed.
> +    * - ``V4L2_VP9_REFERENCE_MODE_SELECT``
> +      - Allows each individual inter block to select between single and
> +        compound prediction modes.
> +
> +.. c:type:: v4l2_vp9_interpolation_filter
> +
> +See section '7.2.7 Interpolation filter semantics' of the VP9 specification
> +for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_interpolation_filter
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP``
> +      - Eight tap filter.
> +    * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH``
> +      - Eight tap smooth filter.
> +    * - ``V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP``
> +      - Eeight tap sharp filter.
> +    * - ``V4L2_VP9_INTERP_FILTER_BILINEAR``
> +      - Bilinear filter.
> +    * - ``V4L2_VP9_INTERP_FILTER_SWITCHABLE``
> +      - Filter selection is signaled at the block level.
> +
> +.. c:type:: v4l2_vp9_reset_frame_context
> +
> +See section '7.2 Uncompressed header semantics' of the VP9 specification
> +for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_reset_frame_context
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_RESET_FRAME_CTX_NONE``
> +      - Do not reset any frame context.
> +    * - ``V4L2_VP9_RESET_FRAME_CTX_SPEC``
> +      - Reset the frame context pointed to by
> +        :c:type:`v4l2_ctrl_vp9_frame`.frame_context_idx.
> +    * - ``V4L2_VP9_RESET_FRAME_CTX_ALL``
> +      - Reset all frame contexts.
> +
> +.. c:type:: v4l2_vp9_intra_prediction_mode
> +
> +See section '7.4.5 Intra frame mode info semantics' for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_intra_prediction_mode
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_DC_PRED``
> +      - DC intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_V_PRED``
> +      - Vertical intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_H_PRED``
> +      - Horizontal intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_D45_PRED``
> +      - D45 intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_D135_PRED``
> +      - D135 intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_D117_PRED``
> +      - D117 intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_D153_PRED``
> +      - D153 intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_D207_PRED``
> +      - D207 intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_D63_PRED``
> +      - D63 intra prediction.
> +    * - ``V4L2_VP9_INTRA_PRED_MODE_TM_PRED``
> +      - True motion intra prediction.
> +
> +.. c:type:: v4l2_vp9_segmentation
> +
> +Encodes the quantization parameters. See section '7.2.10 Segmentation
> +params syntax' of the VP9 specification for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: struct v4l2_vp9_segmentation
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 1 2
> +
> +    * - __u8
> +      - ``feature_data[8][4]``
> +      - Data attached to each feature. Data entry is only valid if the feature
> +        is enabled.
> +    * - __u8
> +      - ``feature_enabled[8]``
> +      - Bitmask defining which features are enabled in each segment.
> +    * - __u8
> +      - ``tree_probs[7]``
> +      - Specifies the probability values to be used when decoding a Segment-ID.
> +        See '5.15. Segmentation map' section of :ref:`vp9` for more details.
> +    * - __u8
> +      - ``pred_probs[3]``
> +      - Specifies the probability values to be used when decoding a
> +        Predicted-Segment-ID. See '6.4.14. Get segment id syntax'
> +        section of :ref:`vp9` for more details.
> +    * - __u8
> +      - ``flags``
> +      - Combination of V4L2_VP9_SEGMENTATION_FLAG_* flags. See
> +        :c:type:`v4l2_vp9_segmentation_flags`.
> +    * - __u8
> +      - ``reserved[5]``
> +      - Applications and drivers must set this to zero.
> +
> +.. c:type:: v4l2_vp9_segment_feature
> +
> +Segment feature IDs. See section '7.2.10 Segmentation params syntax' of the
> +VP9 specification for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_segment_feature
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_SEG_LVL_ALT_Q``
> +      - Quantizer segment feature.
> +    * - ``V4L2_VP9_SEG_LVL_ALT_L``
> +      - Loop filter segment feature.
> +    * - ``V4L2_VP9_SEG_LVL_REF_FRAME``
> +      - Reference frame segment feature.
> +    * - ``V4L2_VP9_SEG_LVL_SKIP``
> +      - Skip segment feature.
> +    * - ``V4L2_VP9_SEG_LVL_MAX``
> +      - Number of segment features.
> +
> +.. c:type:: v4l2_vp9_segmentation_flags
> +
> +Those are the flags that may be passed to &v4l2_vp9_segmentation.flags. See
> +section '7.2.10 Segmentation params syntax' of the VP9 specification for
> +more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_segmentation_flags
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_SEGMENTATION_FLAG_ENABLED``
> +      - Indicates that this frame makes use of the segmentation tool.
> +    * - ``V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP``
> +      - Indicates that the segmentation map should be updated during the
> +        decoding of this frame.
> +    * - ``V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE``
> +      - Indicates that the updates to the segmentation map are coded
> +        relative to the existing segmentation map.
> +    * - ``V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA``
> +      - Indicates that new parameters are about to be specified for each
> +        segment.
> +    * - ``V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE``
> +      - Indicates that the segmentation parameters represent the actual values
> +        to be used.
> +
> +.. c:type:: v4l2_vp9_quantization
> +
> +Encodes the quantization parameters. See section '7.2.9 Quantization params
> +syntax' of the VP9 specification for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: struct v4l2_vp9_quantization
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 1 2
> +
> +    * - __u8
> +      - ``base_q_idx``
> +      - Indicates the base frame qindex.
> +    * - __s8
> +      - ``delta_q_y_dc``
> +      - Indicates the Y DC quantizer relative to base_q_idx.
> +    * - __s8
> +      - ``delta_q_uv_dc``
> +      - Indicates the UV DC quantizer relative to base_q_idx.
> +    * - __s8
> +      - ``delta_q_uv_ac``
> +      - Indicates the UV AC quantizer relative to base_q_idx.
> +    * - __u8
> +      - ``reserved[4]``
> +      - Applications and drivers must set this to zero.
> +
> +.. c:type:: v4l2_vp9_loop_filter
> +
> +This structure contains all loop filter related parameters. See sections
> +'7.2.8 Loop filter semantics' of the VP9 specification for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: struct v4l2_vp9_loop_filter
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 1 2
> +
> +    * - __s8
> +      - ``ref_deltas[4]``
> +      - Contains the adjustment needed for the filter level based on the chosen
> +        reference frame.
> +    * - __s8
> +      - ``mode_deltas[2]``
> +      - Contains the adjustment needed for the filter level based on the chosen
> +        mode.
> +    * - __u8
> +      - ``level``
> +      - Indicates the loop filter strength.
> +    * - __u8
> +      - ``sharpness``
> +      - Indicates the sharpness level.
> +    * - __u8
> +      - ``flags``
> +      - Combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags.
> +        See :c:type:`v4l2_vp9_loop_filter_flags`.
> +    * - __u8
> +      - ``reserved[7]``
> +      - Applications and drivers must set this to zero.
> +
> +
> +.. c:type:: v4l2_vp9_loop_filter_flags
> +
> +Those are the flags that may be passed. See section '7.2.8 Loop filter
> +semantics' of the VP9 specification for more details.
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
> +
> +.. flat-table:: enum v4l2_vp9_loop_filter_flags
> +    :header-rows:  0
> +    :stub-columns: 0
> +    :widths:       1 2
> +
> +    * - ``V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED``
> +      - When set, the filter level depends on the mode and reference frame used
> +        to predict a block.
> +    * - ``V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE``
> +      - When set, the bitstream contains additional syntax elements that
> +        specify which mode and reference frame deltas are to be updated.
> diff --git a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
> index 0ede39907ee2..1b20f48a24b9 100644
> --- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
> +++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst
> @@ -172,6 +172,21 @@ Compressed Formats
>        - VP9 compressed video frame. The encoder generates one
>  	compressed frame per buffer, and the decoder requires one
>  	compressed frame per buffer.
> +    * .. _V4L2-PIX-FMT-VP9-FRAME:
> +
> +      - ``V4L2_PIX_FMT_VP9_FRAME``
> +      - 'VP9F'
> +      - VP9 parsed frame, including the frame header, as extracted from the container.
> +	This format is adapted for stateless video decoders that implement a
> +	VP9 pipeline with the :ref:`stateless_decoder`.
> +	Metadata associated with the frame to decode is required to be passed
> +	through the ``V4L2_CID_STATELESS_VP9_FRAME`` and
> +	the ``V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS`` controls.
> +	See the :ref:`associated Codec Control IDs <v4l2-codec-stateless-vp9>`.
> +	Exactly one output and one capture buffer must be provided for use with
> +	this pixel format. The output buffer must contain the appropriate number
> +	of macroblocks to decode a full corresponding frame to the matching
> +	capture buffer.
>      * .. _V4L2-PIX-FMT-HEVC:
>  
>        - ``V4L2_PIX_FMT_HEVC``
> diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
> index 2d6bc8d94380..258895ff0c71 100644
> --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
> +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
> @@ -233,6 +233,14 @@ still cause this situation.
>        - ``p_mpeg2_quantisation``
>        - A pointer to a struct :c:type:`v4l2_ctrl_mpeg2_quantisation`. Valid if this control is
>          of type ``V4L2_CTRL_TYPE_MPEG2_QUANTISATION``.
> +    * - struct :c:type:`v4l2_ctrl_vp9_compressed_hdr_probs` *
> +      - ``p_vp9_compressed_hdr_probs``
> +      - A pointer to a struct :c:type:`v4l2_ctrl_vp9_compressed_hdr_probs`. Valid if this
> +        control is of type ``V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS``.
> +    * - struct :c:type:`v4l2_ctrl_vp9_frame` *
> +      - ``p_vp9_frame``
> +      - A pointer to a struct :c:type:`v4l2_ctrl_vp9_frame`. Valid if this
> +        control is of type ``V4L2_CTRL_TYPE_VP9_FRAME``.
>      * - struct :c:type:`v4l2_ctrl_hdr10_cll_info` *
>        - ``p_hdr10_cll``
>        - A pointer to a struct :c:type:`v4l2_ctrl_hdr10_cll_info`. Valid if this control is
> diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> index f9ecf6276129..e0c6a5d9ff6b 100644
> --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> @@ -507,6 +507,18 @@ See also the examples in :ref:`control`.
>        - n/a
>        - A struct :c:type:`v4l2_ctrl_hevc_decode_params`, containing HEVC
>  	decoding parameters for stateless video decoders.
> +    * - ``V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS``
> +      - n/a
> +      - n/a
> +      - n/a
> +      - A struct :c:type:`v4l2_ctrl_vp9_compressed_hdr_probs`, containing VP9
> +	probabilities updates for stateless video decoders.
> +    * - ``V4L2_CTRL_TYPE_VP9_FRAME``
> +      - n/a
> +      - n/a
> +      - n/a
> +      - A struct :c:type:`v4l2_ctrl_vp9_frame`, containing VP9
> +	frame decode parameters for stateless video decoders.
>  
>  .. raw:: latex
>  
> diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> index eb0b1cd37abd..129ef3edfa73 100644
> --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> @@ -149,6 +149,8 @@ replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_FWHT_PARAMS :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_VP8_FRAME :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_VP9_FRAME :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_HDR10_CLL_INFO :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY :c:type:`v4l2_ctrl_type`
>  
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> index c4b5082849b6..ed9cf298a83a 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> @@ -283,6 +283,12 @@ static void std_log(const struct v4l2_ctrl *ctrl)
>  	case V4L2_CTRL_TYPE_MPEG2_PICTURE:
>  		pr_cont("MPEG2_PICTURE");
>  		break;
> +	case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS:
> +		pr_cont("VP9_COMPRESSED_HDR_PROBS");
> +		break;
> +	case V4L2_CTRL_TYPE_VP9_FRAME:
> +		pr_cont("VP9_FRAME");
> +		break;
>  	default:
>  		pr_cont("unknown type %d", ctrl->type);
>  		break;
> @@ -317,6 +323,162 @@ static void std_log(const struct v4l2_ctrl *ctrl)
>  #define zero_reserved(s) \
>  	memset(&(s).reserved, 0, sizeof((s).reserved))
>  
> +static int
> +validate_vp9_lf_params(struct v4l2_vp9_loop_filter *lf)
> +{
> +	unsigned int i;
> +
> +	if (lf->flags & ~(V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED |
> +			  V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE))
> +		return -EINVAL;
> +
> +	/* That all values are in the accepted range. */
> +	if (lf->level > GENMASK(5, 0))
> +		return -EINVAL;
> +
> +	if (lf->sharpness > GENMASK(2, 0))
> +		return -EINVAL;
> +
> +	for (i = 0; i < ARRAY_SIZE(lf->ref_deltas); i++)
> +		if (lf->ref_deltas[i] < -63 || lf->ref_deltas[i] > 63)
> +			return -EINVAL;
> +
> +	for (i = 0; i < ARRAY_SIZE(lf->mode_deltas); i++)
> +		if (lf->mode_deltas[i] < -63 || lf->mode_deltas[i] > 63)
> +			return -EINVAL;
> +
> +	zero_reserved(*lf);
> +	return 0;
> +}
> +
> +static int
> +validate_vp9_quant_params(struct v4l2_vp9_quantization *quant)
> +{
> +	if (quant->delta_q_y_dc < -15 || quant->delta_q_y_dc > 15 ||
> +	    quant->delta_q_uv_dc < -15 || quant->delta_q_uv_dc > 15 ||
> +	    quant->delta_q_uv_ac < -15 || quant->delta_q_uv_ac > 15)
> +		return -EINVAL;
> +
> +	zero_reserved(*quant);
> +	return 0;
> +}
> +
> +static int
> +validate_vp9_seg_params(struct v4l2_vp9_segmentation *seg)
> +{
> +	unsigned int i, j;
> +
> +	if (seg->flags & ~(V4L2_VP9_SEGMENTATION_FLAG_ENABLED |
> +			   V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP |
> +			   V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE |
> +			   V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA |
> +			   V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE))
> +		return -EINVAL;
> +
> +	for (i = 0; i < ARRAY_SIZE(seg->feature_enabled); i++) {
> +		if (seg->feature_enabled[i] &
> +		    ~V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK)
> +			return -EINVAL;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(seg->feature_data); i++) {
> +		const int range[] = { 255, 63, 3, 0 };
> +
> +		for (j = 0; j < ARRAY_SIZE(seg->feature_data[j]); j++) {
> +			if (seg->feature_data[i][j] < -range[j] ||
> +			    seg->feature_data[i][j] > range[j])
> +				return -EINVAL;
> +		}
> +	}
> +
> +	zero_reserved(*seg);
> +	return 0;
> +}
> +
> +static int
> +validate_vp9_frame(struct v4l2_ctrl_vp9_frame *frame)
> +{
> +	int ret;
> +
> +	/* Make sure we're not passed invalid flags. */
> +	if (frame->flags & ~(V4L2_VP9_FRAME_FLAG_KEY_FRAME |
> +		  V4L2_VP9_FRAME_FLAG_SHOW_FRAME |
> +		  V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT |
> +		  V4L2_VP9_FRAME_FLAG_INTRA_ONLY |
> +		  V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV |
> +		  V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX |
> +		  V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE |
> +		  V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
> +		  V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING |
> +		  V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING))
> +		return -EINVAL;
> +
> +	if (frame->flags & V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT &&
> +	    frame->flags & V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX)
> +		return -EINVAL;
> +
> +	if (frame->profile > V4L2_VP9_PROFILE_MAX)
> +		return -EINVAL;
> +
> +	if (frame->reset_frame_context > V4L2_VP9_RESET_FRAME_CTX_ALL)
> +		return -EINVAL;
> +
> +	if (frame->frame_context_idx >= V4L2_VP9_NUM_FRAME_CTX)
> +		return -EINVAL;
> +
> +	/*
> +	 * Profiles 0 and 1 only support 8-bit depth, profiles 2 and 3 only 10
> +	 * and 12 bit depths.
> +	 */
> +	if ((frame->profile < 2 && frame->bit_depth != 8) ||
> +	    (frame->profile >= 2 &&
> +	     (frame->bit_depth != 10 && frame->bit_depth != 12)))
> +		return -EINVAL;
> +
> +	/* Profile 0 and 2 only accept YUV 4:2:0. */
> +	if ((frame->profile == 0 || frame->profile == 2) &&
> +	    (!(frame->flags & V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING) ||
> +	     !(frame->flags & V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING)))
> +		return -EINVAL;
> +
> +	/* Profile 1 and 3 only accept YUV 4:2:2, 4:4:0 and 4:4:4. */
> +	if ((frame->profile == 1 || frame->profile == 3) &&
> +	    ((frame->flags & V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING) &&
> +	     (frame->flags & V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING)))
> +		return -EINVAL;
> +
> +	if (frame->interpolation_filter > V4L2_VP9_INTERP_FILTER_SWITCHABLE)
> +		return -EINVAL;
> +
> +	/*
> +	 * According to the spec, tile_cols_log2 shall be less than or equal
> +	 * to 6.
> +	 */
> +	if (frame->tile_cols_log2 > 6)
> +		return -EINVAL;
> +
> +	if (frame->tx_mode > V4L2_VP9_TX_MODE_SELECT)
> +		return -EINVAL;
> +
> +	if (frame->reference_mode > V4L2_VP9_REFERENCE_MODE_SELECT)
> +		return -EINVAL;
> +
> +	ret = validate_vp9_lf_params(&frame->lf);
> +	if (ret)
> +		return ret;
> +
> +	ret = validate_vp9_quant_params(&frame->quant);
> +	if (ret)
> +		return ret;
> +
> +	ret = validate_vp9_seg_params(&frame->seg);
> +	if (ret)
> +		return ret;
> +
> +	zero_reserved(*frame);
> +	return 0;
> +}
> +
>  /*
>   * Compound controls validation requires setting unused fields/flags to zero
>   * in order to properly detect unchanged controls with std_equal's memcmp.
> @@ -687,6 +849,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>  
>  		break;
>  
> +	case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS:
> +		break;
> +
> +	case V4L2_CTRL_TYPE_VP9_FRAME:
> +		return validate_vp9_frame(p);
> +
>  	case V4L2_CTRL_TYPE_AREA:
>  		area = p;
>  		if (!area->width || !area->height)
> @@ -1249,6 +1417,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
>  	case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY:
>  		elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display);
>  		break;
> +	case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS:
> +		elem_size = sizeof(struct v4l2_ctrl_vp9_compressed_hdr_probs);
> +		break;
> +	case V4L2_CTRL_TYPE_VP9_FRAME:
> +		elem_size = sizeof(struct v4l2_ctrl_vp9_frame);
> +		break;
>  	case V4L2_CTRL_TYPE_AREA:
>  		elem_size = sizeof(struct v4l2_area);
>  		break;
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> index 421300e13a41..d383c438156f 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> @@ -1175,6 +1175,8 @@ const char *v4l2_ctrl_get_name(u32 id)
>  	case V4L2_CID_STATELESS_MPEG2_SEQUENCE:			return "MPEG-2 Sequence Header";
>  	case V4L2_CID_STATELESS_MPEG2_PICTURE:			return "MPEG-2 Picture Header";
>  	case V4L2_CID_STATELESS_MPEG2_QUANTISATION:		return "MPEG-2 Quantisation Matrices";
> +	case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS:	return "VP9 Probabilities Updates";
> +	case V4L2_CID_STATELESS_VP9_FRAME:			return "VP9 Frame Decode Parameters";
>  
>  	/* Colorimetry controls */
>  	/* Keep the order of the 'case's the same as in v4l2-controls.h! */
> @@ -1493,6 +1495,12 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
>  	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:
>  		*type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS;
>  		break;
> +	case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS:
> +		*type = V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS;
> +		break;
> +	case V4L2_CID_STATELESS_VP9_FRAME:
> +		*type = V4L2_CTRL_TYPE_VP9_FRAME;
> +		break;
>  	case V4L2_CID_UNIT_CELL_SIZE:
>  		*type = V4L2_CTRL_TYPE_AREA;
>  		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index ec6fc1ef291e..7a5e8120d733 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1394,6 +1394,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
>  		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
>  		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;
>  		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
> +		case V4L2_PIX_FMT_VP9_FRAME:    descr = "VP9 Frame"; break;
>  		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
>  		case V4L2_PIX_FMT_HEVC_SLICE:	descr = "HEVC Parsed Slice Data"; break;
>  		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
> index 575b59fbac77..3ea4386ebd91 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -50,6 +50,8 @@ struct video_device;
>   * @p_h264_decode_params:	Pointer to a struct v4l2_ctrl_h264_decode_params.
>   * @p_h264_pred_weights:	Pointer to a struct v4l2_ctrl_h264_pred_weights.
>   * @p_vp8_frame:		Pointer to a VP8 frame params structure.
> + * @p_vp9_compressed_hdr_probs:	Pointer to a VP9 frame compressed header probs structure.
> + * @p_vp9_frame:		Pointer to a VP9 frame params structure.
>   * @p_hevc_sps:			Pointer to an HEVC sequence parameter set structure.
>   * @p_hevc_pps:			Pointer to an HEVC picture parameter set structure.
>   * @p_hevc_slice_params:	Pointer to an HEVC slice parameters structure.
> @@ -80,6 +82,8 @@ union v4l2_ctrl_ptr {
>  	struct v4l2_ctrl_hevc_sps *p_hevc_sps;
>  	struct v4l2_ctrl_hevc_pps *p_hevc_pps;
>  	struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
> +	struct v4l2_ctrl_vp9_compressed_hdr_probs *p_vp9_compressed_hdr_probs;
> +	struct v4l2_ctrl_vp9_frame *p_vp9_frame;
>  	struct v4l2_ctrl_hdr10_cll_info *p_hdr10_cll;
>  	struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
>  	struct v4l2_area *p_area;
> diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
> index 5532b5f68493..8f8c3c1ad885 100644
> --- a/include/uapi/linux/v4l2-controls.h
> +++ b/include/uapi/linux/v4l2-controls.h
> @@ -2010,6 +2010,439 @@ struct v4l2_ctrl_hdr10_mastering_display {
>  	__u32 min_display_mastering_luminance;
>  };
>  
> +/* Stateless VP9 controls */
> +
> +/**
> + * enum v4l2_vp9_loop_filter_flags - VP9 loop filter flags
> + *
> + * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED: the filter level depends on
> + *	the mode and reference frame used to predict a block
> + * @V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE: the bitstream contains additional
> + *	syntax elements that specify which mode and reference frame deltas are to be updated
> + *
> + * Those are the flags that may be passed to &v4l2_vp9_loop_filter.flags. See
> + * section '7.2.8 Loop filter semantics' of the VP9 specification for more
> + * details.
> + */
> +enum v4l2_vp9_loop_filter_flags {
> +	V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED = 1 << 0,
> +	V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE = 1 << 1,
> +};
> +
> +/**
> + * struct v4l2_vp9_loop_filter - VP9 loop filter parameters
> + *
> + * @ref_deltas: contains the adjustment needed for the filter level based on the chosen
> + *	reference frame. If this syntax element is not present in the bitstream, users
> + *	should pass its last value.
> + * @mode_deltas: contains the adjustment needed for the filter level based on the chosen mode.
> + *	If this syntax element is not present in the bitstream, users
> + *	should pass its last value.
> + * @level: indicates the loop filter strength
> + * @sharpness: indicates the sharpness level
> + * @flags: combination of V4L2_VP9_LOOP_FILTER_FLAG_* flags
> + * @reserved: padding field. Should be zeroed by applications.
> + *
> + * This structure contains all loop filter related parameters. See sections
> + * '7.2.8 Loop filter semantics' of the VP9 specification for more details.
> + */
> +struct v4l2_vp9_loop_filter {
> +	__s8 ref_deltas[4];
> +	__s8 mode_deltas[2];
> +	__u8 level;
> +	__u8 sharpness;
> +	__u8 flags;
> +	__u8 reserved[7];
> +};
> +
> +/**
> + * struct v4l2_vp9_quantization - VP9 quantization parameters
> + *
> + * @base_q_idx: indicates the base frame qindex
> + * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx
> + * @delta_q_uv_dc: indicates the UV DC quantizer relative to base_q_idx
> + * @delta_q_uv_ac: indicates the UV AC quantizer relative to base_q_idx
> + * @reserved: padding field. Should be zeroed by applications.
> + *
> + * Encodes the quantization parameters. See section '7.2.9 Quantization params
> + * syntax' of the VP9 specification for more details.
> + */
> +struct v4l2_vp9_quantization {
> +	__u8 base_q_idx;
> +	__s8 delta_q_y_dc;
> +	__s8 delta_q_uv_dc;
> +	__s8 delta_q_uv_ac;
> +	__u8 reserved[4];
> +};
> +
> +/**
> + * enum v4l2_vp9_segmentation_flags - VP9 segmentation flags
> + *
> + * @V4L2_VP9_SEGMENTATION_FLAG_ENABLED: indicates that this frame makes use of
> + *	the segmentation tool
> + * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP: indicates that the segmentation map
> + *	should be updated during the decoding of this frame
> + * @V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE: indicates that the updates to
> + *	the segmentation map are coded relative to the existing segmentation map
> + * @V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA: indicates that new parameters are
> + *	about to be specified for each segment
> + * @V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE: indicates that the
> + *	segmentation parameters represent the actual values to be used
> + *
> + * Those are the flags that may be passed to &v4l2_vp9_segmentation.flags. See
> + * section '7.2.10 Segmentation params syntax' of the VP9 specification for
> + * more details.
> + */
> +enum v4l2_vp9_segmentation_flags {
> +	V4L2_VP9_SEGMENTATION_FLAG_ENABLED = 1 << 0,
> +	V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP = 1 << 1,
> +	V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE = 1 << 2,
> +	V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA = 1 << 3,
> +	V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE = 1 << 4,
> +};
> +
> +#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id)	(1 << (id))
> +#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK	0xf
> +
> +/**
> + * enum v4l2_vp9_segment_feature - VP9 segment feature IDs
> + *
> + * @V4L2_VP9_SEG_LVL_ALT_Q: quantizer segment feature
> + * @V4L2_VP9_SEG_LVL_ALT_L: loop filter segment feature
> + * @V4L2_VP9_SEG_LVL_REF_FRAME reference frame segment feature
> + * @V4L2_VP9_SEG_LVL_SKIP: skip segment feature
> + * @V4L2_VP9_SEG_LVV_MAX: number of segment features
> + *
> + * Segment feature IDs. See section '7.2.10 Segmentation params syntax' of the
> + * VP9 specification for more details.
> + */
> +enum v4l2_vp9_segment_feature {
> +	V4L2_VP9_SEG_LVL_ALT_Q,
> +	V4L2_VP9_SEG_LVL_ALT_L,
> +	V4L2_VP9_SEG_LVL_REF_FRAME,
> +	V4L2_VP9_SEG_LVL_SKIP,
> +	V4L2_VP9_SEG_LVL_MAX,
> +};
> +
> +/**
> + * struct v4l2_vp9_segmentation - VP9 segmentation parameters
> + *
> + * @feature_data: data attached to each feature. Data entry is only valid if the feature is enabled
> + * @feature_enabled: bitmask defining which features are enabled in each segment
> + * @tree_probs: specifies the probability values to be used when
> + *	decoding a Segment-ID. See '5.15. Segmentation map' section of the VP9 specification
> + *	for more details.
> + * @pred_probs: specifies the probability values to be used when decoding a
> + *	Predicted-Segment-ID. See '6.4.14. Get segment id syntax' section of :ref:`vp9`
> + *	for more details.
> + * @flags: combination of V4L2_VP9_SEGMENTATION_FLAG_* flags
> + * @reserved: padding field. Should be zeroed by applications.
> + *
> + * Encodes the quantization parameters. See section '7.2.10 Segmentation params syntax' of
> + * the VP9 specification for more details.
> + */
> +struct v4l2_vp9_segmentation {
> +	__s16 feature_data[8][4];
> +	__u8 feature_enabled[8];
> +	__u8 tree_probs[7];
> +	__u8 pred_probs[3];
> +	__u8 flags;
> +	__u8 reserved[5];
> +};
> +
> +/**
> + * enum v4l2_vp9_intra_prediction_mode - VP9 Intra prediction modes
> + *
> + * @V4L2_VP9_INTRA_PRED_MODE_DC_PRED: DC intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_V_PRED: vertical intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_H_PRED: horizontal intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D45_PRED: D45 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D135_PRED: D135 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D117_PRED: D117 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D153_PRED: D153 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D207_PRED: D207 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_D63_PRED: D63 intra prediction
> + * @V4L2_VP9_INTRA_PRED_MODE_TM_PRED: True Motion intra prediction
> + *
> + * See section '7.4.5 Intra frame mode info semantics' for more details.
> + */
> +enum v4l2_vp9_intra_prediction_mode {
> +	V4L2_VP9_INTRA_PRED_MODE_DC_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_V_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_H_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D45_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D135_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D117_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D153_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D207_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_D63_PRED,
> +	V4L2_VP9_INTRA_PRED_MODE_TM_PRED,
> +};
> +
> +/**
> + * enum v4l2_vp9_reset_frame_context - Valid values for
> + *			&v4l2_ctrl_vp9_frame->reset_frame_context
> + *
> + * @V4L2_VP9_RESET_FRAME_CTX_NONE: don't reset any frame context
> + * @V4L2_VP9_RESET_FRAME_CTX_SPEC: reset the frame context pointed by
> + *	&v4l2_ctrl_vp9_frame.frame_context_idx
> + * @V4L2_VP9_RESET_FRAME_CTX_ALL: reset all frame contexts
> + *
> + * See section '7.2 Uncompressed header semantics' of the VP9 specification for more details.
> + */
> +enum v4l2_vp9_reset_frame_context {
> +	V4L2_VP9_RESET_FRAME_CTX_NONE,
> +	V4L2_VP9_RESET_FRAME_CTX_SPEC,
> +	V4L2_VP9_RESET_FRAME_CTX_ALL,
> +};
> +
> +/**
> + * enum v4l2_vp9_interpolation_filter - VP9 interpolation filter types
> + *
> + * @V4L2_VP9_INTERP_FILTER_EIGHTTAP: eight tap filter
> + * @V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH: eight tap smooth filter
> + * @V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP: eight tap sharp filter
> + * @V4L2_VP9_INTERP_FILTER_BILINEAR: bilinear filter
> + * @V4L2_VP9_INTERP_FILTER_SWITCHABLE: filter selection is signaled at the block level
> + *
> + * See section '7.2.7 Interpolation filter semantics' of the VP9 specification
> + * for more details.
> + */
> +enum v4l2_vp9_interpolation_filter {
> +	V4L2_VP9_INTERP_FILTER_EIGHTTAP,
> +	V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH,
> +	V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP,
> +	V4L2_VP9_INTERP_FILTER_BILINEAR,
> +	V4L2_VP9_INTERP_FILTER_SWITCHABLE,
> +};
> +
> +/**
> + * enum v4l2_vp9_reference_mode - VP9 reference modes
> + *
> + * @V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE: indicates that all the inter blocks use only a
> + *	single reference frame to generate motion compensated prediction
> + * @V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE: requires all the inter blocks to use compound mode.
> + *	Single reference frame prediction is not allowed
> + * @V4L2_VP9_REFERENCE_MODE_SELECT: allows each individual inter block to select between single
> + *	and compound prediction modes
> + *
> + * See section '7.3.6 Frame reference mode semantics' of the VP9 specification
> + * for more details.
> + */
> +enum v4l2_vp9_reference_mode {
> +	V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE,
> +	V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE,
> +	V4L2_VP9_REFERENCE_MODE_SELECT,
> +};
> +
> +/**
> + * enum v4l2_vp9_tx_mode - VP9 TX modes
> + *
> + * @V4L2_VP9_TX_MODE_ONLY_4X4: transform size is 4x4
> + * @V4L2_VP9_TX_MODE_ALLOW_8X8: transform size can be up to 8x8
> + * @V4L2_VP9_TX_MODE_ALLOW_16X16: transform size can be up to 16x16
> + * @V4L2_VP9_TX_MODE_ALLOW_32X32: transform size can be up to 32x32
> + * @V4L2_VP9_TX_MODE_SELECT: bitstream contains the transform size for each block
> + *
> + * See section '7.3.1 Tx mode semantics' of the VP9 specification for more details.
> + */
> +enum v4l2_vp9_tx_mode {
> +	V4L2_VP9_TX_MODE_ONLY_4X4,
> +	V4L2_VP9_TX_MODE_ALLOW_8X8,
> +	V4L2_VP9_TX_MODE_ALLOW_16X16,
> +	V4L2_VP9_TX_MODE_ALLOW_32X32,
> +	V4L2_VP9_TX_MODE_SELECT,
> +};
> +
> +/**
> + * enum v4l2_vp9_frame_flags - VP9 frame flags
> + * @V4L2_VP9_FRAME_FLAG_KEY_FRAME: the frame is a key frame
> + * @V4L2_VP9_FRAME_FLAG_SHOW_FRAME: the frame should be displayed
> + * @V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT: the decoding should be error resilient
> + * @V4L2_VP9_FRAME_FLAG_INTRA_ONLY: the frame does not reference other frames
> + * @V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV: the frame can use high precision motion vectors
> + * @V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX: frame context should be updated after decoding
> + * @V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE: parallel decoding is used
> + * @V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING: vertical subsampling is enabled
> + * @V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING: horizontal subsampling is enabled
> + * @V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING: full UV range is used
> + *
> + * Check the VP9 specification for more details.
> + */
> +enum v4l2_vp9_frame_flags {
> +	V4L2_VP9_FRAME_FLAG_KEY_FRAME = 1 << 0,
> +	V4L2_VP9_FRAME_FLAG_SHOW_FRAME = 1 << 1,
> +	V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT = 1 << 2,
> +	V4L2_VP9_FRAME_FLAG_INTRA_ONLY = 1 << 3,
> +	V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV = 1 << 4,
> +	V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX = 1 << 5,
> +	V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE = 1 << 6,
> +	V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING = 1 << 7,
> +	V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING = 1 << 8,
> +	V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING = 1 << 9,
> +};
> +
> +/**
> + * enum v4l2_vp9_ref_frame_sign_bias - Whether ref_frame_sign_bias is 1 for a given reference frame
> + * @V4L2_VP9_SIGN_BIAS_LAST: ref_frame_sign_bias is 1 for the "last" reference frame
> + * @V4L2_VP9_SIGN_BIAS_GOLDEN: ref_frame_sign_bias is 1 for the "golden" reference frame
> + * @V4L2_VP9_SIGN_BIAS_ALT: ref_frame_sign_bias is 1 for the "alt" reference frame
> + */
> +
> +enum v4l2_vp9_ref_frame_sign_bias {
> +	V4L2_VP9_SIGN_BIAS_LAST,
> +	V4L2_VP9_SIGN_BIAS_GOLDEN,
> +	V4L2_VP9_SIGN_BIAS_ALT,
> +};
> +
> +#define V4L2_VP9_PROFILE_MAX		3
> +
> +#define V4L2_CID_STATELESS_VP9_FRAME	(V4L2_CID_CODEC_STATELESS_BASE + 300)
> +/**
> + * struct v4l2_ctrl_vp9_frame - VP9 frame decoding control
> + *
> + * @lf: loop filter parameters. See &v4l2_vp9_loop_filter for more details
> + * @quant: quantization parameters. See &v4l2_vp9_quantization for more details
> + * @seg: segmentation parameters. See &v4l2_vp9_segmentation for more details
> + * @flags: combination of V4L2_VP9_FRAME_FLAG_* flags
> + * @compressed_header_size: compressed header size in bytes
> + * @uncompressed_header_size: uncompressed header size in bytes
> + * @frame_width_minus_1: add 1 to it and you'll get the frame width expressed in pixels
> + * @frame_height_minus_1: add 1 to it and you'll get the frame height expressed in pixels
> + * @render_width_minus_1: add 1 to it and you'll get the expected render width expressed in
> + *	pixels. This is not used during the decoding process but might be used by HW scalers
> + *	to prepare a frame that's ready for scanout
> + * @render_height_minus_1: add 1 to it and you'll get the expected render height expressed in
> + *	pixels. This is not used during the decoding process but might be used by HW scalers
> + *	to prepare a frame that's ready for scanout
> + * @last_frame_ts: "last" reference buffer timestamp.
> + * The timestamp refers to the timestamp field in struct v4l2_buffer.
> + * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
> + * @golden_frame_ts: "golden" reference buffer timestamp.
> + * The timestamp refers to the timestamp field in struct v4l2_buffer.
> + * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
> + * @alt_frame_ts: "alt" reference buffer timestamp.
> + * The timestamp refers to the timestamp field in struct v4l2_buffer.
> + * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
> + * @ref_frame_sign_bias: a bitfield specifying whether the sign bias is set for a given
> + *	reference frame. See &v4l2_vp9_ref_frame_sign_bias for more details.
> + * @reset_frame_context: specifies whether the frame context should be reset to default values.
> + *	See &v4l2_vp9_reset_frame_context for more details
> + * @frame_context_idx: frame context that should be used/updated
> + * @profile: VP9 profile. Can be 0, 1, 2 or 3
> + * @bit_depth: bits per components. Can be 8, 10 or 12. Note that not all profiles support
> + *	10 and/or 12 bits depths
> + * @interpolation_filter: specifies the filter selection used for performing inter prediction.
> + *	See &v4l2_vp9_interpolation_filter for more details
> + * @tile_cols_log2: specifies the base 2 logarithm of the width of each tile (where the width
> + *	is measured in units of 8x8 blocks). Shall be less than or equal to 6
> + * @tile_rows_log2: specifies the base 2 logarithm of the height of each tile (where the height
> + *	is measured in units of 8x8 blocks)
> + * @tx_mode: specifies the TX mode. See &v4l2_vp9_tx_mode for more details
> + * @reference_mode: specifies the type of inter prediction to be used. See
> + *	&v4l2_vp9_reference_mode for more details
> + * @reserved: padding field. Should be zeroed by applications.
> + */
> +struct v4l2_ctrl_vp9_frame {
> +	struct v4l2_vp9_loop_filter lf;
> +	struct v4l2_vp9_quantization quant;
> +	struct v4l2_vp9_segmentation seg;
> +	__u32 flags;
> +	__u16 compressed_header_size;
> +	__u16 uncompressed_header_size;
> +	__u16 frame_width_minus_1;
> +	__u16 frame_height_minus_1;
> +	__u16 render_width_minus_1;
> +	__u16 render_height_minus_1;
> +	__u64 last_frame_ts;
> +	__u64 golden_frame_ts;
> +	__u64 alt_frame_ts;
> +	__u8 ref_frame_sign_bias;
> +	__u8 reset_frame_context;
> +	__u8 frame_context_idx;
> +	__u8 profile;
> +	__u8 bit_depth;
> +	__u8 interpolation_filter;
> +	__u8 tile_cols_log2;
> +	__u8 tile_rows_log2;
> +	__u8 tx_mode;
> +	__u8 reference_mode;
> +	__u8 reserved[6];
> +};
> +
> +#define V4L2_VP9_NUM_FRAME_CTX	4
> +
> +/**
> + * struct v4l2_vp9_mv_compressed_hdr_probs - VP9 Motion vector probability updates
> + * @joint: motion vector joint probability updates
> + * @sign: motion vector sign probability updates
> + * @classes: motion vector class probability updates
> + * @class0_bit: motion vector class0 bit probability updates
> + * @bits: motion vector bits probability updates
> + * @class0_fr: motion vector class0 fractional bit probability updates
> + * @fr: motion vector fractional bit probability updates
> + * @class0_hp: motion vector class0 high precision fractional bit probability updates
> + * @hp: motion vector high precision fractional bit probability updates
> + *
> + * This structure contains new values of motion vector probabilities.
> + * A value of zero in an array element means there is no update of the relevant probability.
> + * See `struct v4l2_vp9_prob_updates` for details.
> + */
> +struct v4l2_vp9_mv_compressed_hdr_probs {
> +	__u8 joint[3];
> +	__u8 sign[2];
> +	__u8 classes[2][10];
> +	__u8 class0_bit[2];
> +	__u8 bits[2][10];
> +	__u8 class0_fr[2][2][3];
> +	__u8 fr[2][3];
> +	__u8 class0_hp[2];
> +	__u8 hp[2];
> +};
> +
> +#define V4L2_CID_STATELESS_VP9_COMPRESSED_HDR_PROBS	(V4L2_CID_CODEC_STATELESS_BASE + 301)
> +/**
> + * struct v4l2_ctrl_vp9_compressed_hdr_probs - VP9 probability updates control
> + * @tx8: TX 8x8 probability updates
> + * @tx16: TX 16x16 probability updates
> + * @tx32: TX 32x32 probability updates
> + * @coef: coefficient probability updates
> + * @skip: skip probability updates
> + * @inter_mode: inter mode probability updates
> + * @interp_filter: interpolation filter probability updates
> + * @is_inter: is inter-block probability updates
> + * @comp_mode: compound prediction mode probability updates
> + * @single_ref: single ref probability updates
> + * @comp_ref: compound ref probability updates
> + * @y_mode: Y prediction mode probability updates
> + * @uv_mode: UV prediction mode probability updates
> + * @partition: partition probability updates
> + * @mv: motion vector probability updates
> + *
> + * This structure holds the probabilities update as parsed in the compressed
> + * header (Spec 6.3). These values represent the value of probability update after
> + * being translated with inv_map_table[] (see 6.3.5). A value of zero in an array element
> + * means that there is no update of the relevant probability.
> + */
> +struct v4l2_ctrl_vp9_compressed_hdr_probs {
> +	__u8 tx8[2][1];
> +	__u8 tx16[2][2];
> +	__u8 tx32[2][3];
> +	__u8 coef[4][2][2][6][6][3];
> +	__u8 skip[3];
> +	__u8 inter_mode[7][3];
> +	__u8 interp_filter[4][2];
> +	__u8 is_inter[4];
> +	__u8 comp_mode[5];
> +	__u8 single_ref[5][2];
> +	__u8 comp_ref[5];
> +	__u8 y_mode[4][9];
> +	__u8 uv_mode[10][9];
> +	__u8 partition[16][3];
> +
> +	struct v4l2_vp9_mv_compressed_hdr_probs mv;
> +};
> +
>  /* MPEG-compression definitions kept for backwards compatibility */
>  #ifndef __KERNEL__
>  #define V4L2_CTRL_CLASS_MPEG            V4L2_CTRL_CLASS_CODEC
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 58392dcd3bf5..4abe4362519e 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -703,6 +703,7 @@ struct v4l2_pix_format {
>  #define V4L2_PIX_FMT_VP8      v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
>  #define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') /* VP8 parsed frame */
>  #define V4L2_PIX_FMT_VP9      v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
> +#define V4L2_PIX_FMT_VP9_FRAME v4l2_fourcc('V', 'P', '9', 'F') /* VP9 parsed frame */
>  #define V4L2_PIX_FMT_HEVC     v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */
>  #define V4L2_PIX_FMT_FWHT     v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */
>  #define V4L2_PIX_FMT_FWHT_STATELESS     v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */
> @@ -1755,6 +1756,8 @@ struct v4l2_ext_control {
>  		struct v4l2_ctrl_mpeg2_sequence __user *p_mpeg2_sequence;
>  		struct v4l2_ctrl_mpeg2_picture __user *p_mpeg2_picture;
>  		struct v4l2_ctrl_mpeg2_quantisation __user *p_mpeg2_quantisation;
> +		struct v4l2_ctrl_vp9_compressed_hdr_probs __user *p_vp9_compressed_hdr_probs;
> +		struct v4l2_ctrl_vp9_frame __user *p_vp9_frame;
>  		void __user *ptr;
>  	};
>  } __attribute__ ((packed));
> @@ -1819,6 +1822,9 @@ enum v4l2_ctrl_type {
>  	V4L2_CTRL_TYPE_MPEG2_QUANTISATION   = 0x0250,
>  	V4L2_CTRL_TYPE_MPEG2_SEQUENCE       = 0x0251,
>  	V4L2_CTRL_TYPE_MPEG2_PICTURE        = 0x0252,
> +
> +	V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR_PROBS	= 0x0260,
> +	V4L2_CTRL_TYPE_VP9_FRAME		= 0x0261,
>  };
>  
>  /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */




From u.kleine-koenig at pengutronix.de  Tue Aug 17 11:04:07 2021
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 17 Aug 2021 20:04:07 +0200
Subject: [PATCH v5 3/3] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <e8d39f18-3aa9-e617-6439-2c0b071f62b3@seco.com>
References: <20210719221322.3723009-1-sean.anderson@seco.com>
 <20210719221322.3723009-3-sean.anderson@seco.com>
 <20210814204710.retjwn5fycwtrypp@pengutronix.de>
 <e8d39f18-3aa9-e617-6439-2c0b071f62b3@seco.com>
Message-ID: <20210817180407.ru4prwu344dxpynu@pengutronix.de>

On Mon, Aug 16, 2021 at 07:51:17PM -0400, Sean Anderson wrote:
> 
> 
> On 8/14/21 4:47 PM, Uwe Kleine-K?nig wrote:
> > Hello Sean,
> > 
> > sorry for having you let waiting so long. Now here some more feedback:
> > 
> > On Mon, Jul 19, 2021 at 06:13:22PM -0400, Sean Anderson wrote:
> > > +static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
> > > +			    const struct pwm_state *state)
> > > +{
> > > +	bool enabled;
> > > +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
> > > +	u32 tlr0, tlr1, tcsr0, tcsr1;
> > > +	u64 period_cycles, duty_cycles;
> > > +	unsigned long rate;
> > > +
> > > +	if (state->polarity != PWM_POLARITY_NORMAL)
> > > +		return -EINVAL;
> > > +
> > > +	/*
> > > +	 * To be representable by TLR, cycles must be between 2 and
> > > +	 * priv->max + 2. To enforce this we can reduce the duty
> > > +	 * cycle, but we may not increase it.
> > > +	 */
> > > +	rate = clk_get_rate(priv->clk);
> > > +	period_cycles = mul_u64_u32_div(state->period, rate, NSEC_PER_SEC);
> > 
> > cool, I didn't know mul_u64_u32_div.
> 
> I didn't either. Alas, many useful functions like these have no
> documentation...
> 
> > 
> > Hmm, we still have a problem here if
> > 
> > 	state->period * rate > 1000000000 * U64_MAX.
> 
> Note that this can only occur with rate > 1GHz (and period = U64_MAX).
> The highest fmax in the datasheet is 300 MHz (on a very expensive FPGA).
> 
> Maybe it is more prudent to do
> 
> 	period = min(state->period, ULONG_MAX * NSEC_PER_SEC)

Together with a check for rate being <= 300 MHz to be safe that's fine.

> I think a period of 136 years is adequate :) This comparison also has
> the advantage of being against const values.

*nod*

> > > +static void xilinx_pwm_get_state(struct pwm_chip *chip,
> > > +				 struct pwm_device *unused,
> > > +				 struct pwm_state *state)
> > > +{
> > > +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
> > > +	u32 tlr0, tlr1, tcsr0, tcsr1;
> > > +
> > > +	regmap_read(priv->map, TLR0, &tlr0);
> > > +	regmap_read(priv->map, TLR1, &tlr1);
> > > +	regmap_read(priv->map, TCSR0, &tcsr0);
> > > +	regmap_read(priv->map, TCSR1, &tcsr1);
> > > +	state->period = xilinx_timer_get_period(priv, tlr0, tcsr0);
> > 
> > xilinx_timer_get_period rounds down, this is however wrong for
> > .get_state().
> 
> Why is this wrong? I thought get_state should return values which would
> not be rounded if passed to apply_state.

Consider a PWM that yields a period of ? * $regval ns when a certain
register is programmed with the value $regval.

Consider the HW is programmed with regval = 317. The exact period is
995.8848711879644. If now .get_state() rounds down and returns 995 ns and
you feed that value back into .apply the new regval (assuming round down
in .apply(), too) this yields regval = 316. If however .get_state()
rounds up and returns 996, putting this value back into .apply() you get
the desired 317.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/3b36c65c/attachment.sig>

From saravanak at google.com  Tue Aug 17 11:12:34 2021
From: saravanak at google.com (Saravana Kannan)
Date: Tue, 17 Aug 2021 11:12:34 -0700
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <YRtkE62O+4EiyzF9@google.com>
References: <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <YQuZ2cKVE+3Os25Z@google.com> <YRpeVLf18Z+1R7WE@google.com>
 <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>
 <YRtkE62O+4EiyzF9@google.com>
Message-ID: <CAGETcx-FS_88nQuF=xN4iJJ-nGnaeTnO-iiGpZuNELqE42FtoA@mail.gmail.com>

On Tue, Aug 17, 2021 at 12:24 AM Lee Jones <lee.jones at linaro.org> wrote:
>
> On Mon, 16 Aug 2021, Saravana Kannan wrote:
> > > > > I sent out the proper fix as a series:
> > > > > https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
> > > > >
> > > > > Marc, can you give it a shot please?
> > > > >
> > > > > -Saravana
> > > >
> > > > Superstar!  Thanks for taking the time to rectify this for all of us.
> > >
> > > Just to clarify:
> > >
> > >   Are we waiting on a subsequent patch submission at this point?
> >
> > Not that I'm aware of. Andrew added a "Reviewed-by" to all 3 of my
> > proper fix patches. I didn't think I needed to send any newer patches.
> > Is there some reason you that I needed to?
>
> Actually, I meant *this* patch.

I think it'll be nice if Neil addresses the stuff Marc mentioned
(ideally) using the macros I suggested. Not sure if Marc is waiting on
that though. Marc also probably wants my mdio-mux series to merge
first before he takes this patch. So that it doesn't break networking
in his device.

-Saravana

>
> But happy to have unlocked your patches also. :)
>
> --
> Lee Jones [???]
> Senior Technical Lead - Developer Services
> Linaro.org ? Open source software for Arm SoCs
> Follow Linaro: Facebook | Twitter | Blog


From robh at kernel.org  Tue Aug 17 11:17:50 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 13:17:50 -0500
Subject: [PATCH v11 2/5] dt-bindings: spmi: document binding for the
 Mediatek SPMI controller
In-Reply-To: <1629193630-19994-3-git-send-email-hsin-hsiung.wang@mediatek.com>
References: <1629193630-19994-1-git-send-email-hsin-hsiung.wang@mediatek.com>
 <1629193630-19994-3-git-send-email-hsin-hsiung.wang@mediatek.com>
Message-ID: <1629224270.762546.589511.nullmailer@robh.at.kernel.org>

On Tue, 17 Aug 2021 17:47:07 +0800, Hsin-Hsiung Wang wrote:
> This adds documentation for the SPMI controller found on Mediatek SoCs.
> 
> Signed-off-by: Hsin-Hsiung Wang <hsin-hsiung.wang at mediatek.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---
> changes since v10:
> - No change.
> ---
>  .../bindings/spmi/mtk,spmi-mtk-pmif.yaml      | 76 +++++++++++++++++++
>  1 file changed, 76 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.example.dts:19:18: fatal error: dt-bindings/clock/mt8192-clk.h: No such file or directory
   19 |         #include <dt-bindings/clock/mt8192-clk.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1517677

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Tue Aug 17 11:35:12 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 13:35:12 -0500
Subject: [v2,08/12] dt-bindings: rng: mediatek: add mt7986 to mtk rng
 binding
In-Reply-To: <20210817074557.30953-9-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
 <20210817074557.30953-9-sam.shih@mediatek.com>
Message-ID: <YRwBYJmfAQ/3hGuI@robh.at.kernel.org>

On Tue, Aug 17, 2021 at 03:45:53PM +0800, Sam Shih wrote:
> Add RNG binding for MT7986 SoC.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> 
> ---
> v2: patch v1 has been applied

Then don't send the patch again.

Rob


From robh at kernel.org  Tue Aug 17 11:42:25 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 13:42:25 -0500
Subject: [PATCH v3 7/7] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <20210811114827.27322-8-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
 <20210811114827.27322-8-semen.protsenko@linaro.org>
Message-ID: <YRwDETpe019RFU/q@robh.at.kernel.org>

On Wed, Aug 11, 2021 at 02:48:27PM +0300, Sam Protsenko wrote:
> Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
> 
> This patch adds minimal SoC support by including next Device Tree nodes:
> 
> 1. Octa cores (Cortex-A55), supporting PSCI v1.0
> 2. ARM architecture timer (armv8-timer)
> 3. Interrupt controller (GIC-400)
> 4. Pinctrl nodes for GPIO
> 5. Serial node
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v3:
>  - Used generic fixed clock for serial
> 
> Changes in v2:
>  * Commit message:
>    - Documented added dts features instead of CPU features
> 
>  * exynos850-usi.dtsi:
>    - Removed, moved everything to exynos850.dtsi
> 
>  * exynos850.dtsi:
>    - Root node:
>      - Added comment about engineering name (Exynos3830)
>      - Renamed pinctrl nodes, adding domain names
>      - Used hard coded IRQ numbers instead of named constants everywhere
>      - Added soc node, moved next nodes there: gic, clock, pinctrls and
>        serial
>      - Used address-cells=1 for soc node and removed unneeded 0x0 from
>        reg properties
>      - Moved exynos850-pinctrl.dtsi include line to the end of
>        exynos850.dtsi
>      - Coding style fixes
>    - cpus:
>      - Used address-cells=1 for cpus node
>      - Renamed cpu at 0001 to cpu at 1, and so on
>      - Left only "arm,cortex-a55" for cpus compatible
>      - Renamed reg = <0x0001> to <0x1> for cpus
>    - armv8 timer:
>      - Add comment about missing HV timer IRQ to armv8 timer node
>      - Removed not existing properties from armv8 timer node
>      - Fixed cpu number in CPU_MASK()
>      - Removed obsolete clock-frequency property
>    - GIC:
>      - Fixed GIC type to be GIC-400
>      - Fixed size of GIC's 2nd region to be 0x2000
>    - serial node:
>      - Hard coded clock number for serial_0 for now; will replace with
>        named const once proper clock driver is implemented
>      - Removed gate_uart_clk0 clock from serial_0, as that clock is not
>        supported in serial driver anyway (yet)
>    - clock node:
>      - Fixed clock controller node name (@0x12.. -> @12..)
> 
>  * exynos850-pinctrl.dtsi:
>    - Referenced pinctrl nodes instead of defining those again in root node
>    - Fixed interrupt-cells (3 -> 2)
>    - Fixed USI related comments for pin config nodes
>    - Removed decon_f_te_* and fm_lna_en nodes (won't be used)
>    - Reordered pin config nodes by pin numbers
>    - Improved all comments
>    - Used existing named constants for pin-function and pin-pud
>    - Fixed node names (used hyphens instead of underscore)
>    - Fixed warnings found in W=1 build
> 
>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
>  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 261 ++++++
>  2 files changed, 1009 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> new file mode 100644
> index 000000000000..ba5d5f33e2f6
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> @@ -0,0 +1,748 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
> + *
> + * Copyright (C) 2017 Samsung Electronics Co., Ltd.
> + * Copyright (C) 2021 Linaro Ltd.
> + *
> + * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
> + * tree nodes in this file.
> + */
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/pinctrl/samsung.h>
> +
> +&pinctrl_alive {
> +	gpa0: gpa0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpa1: gpa1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpa2: gpa2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpa3: gpa3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpa4: gpa4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpq0: gpq0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	/* I2C5 (also called CAM_PMIC_I2C in TRM) */
> +	i2c5_bus: i2c5-bus {

Please name all the pinctrl nodes with some pattern you can match on 
once there is a schema. '-pins$' is my suggestion.

> +		samsung,pins = "gpa3-5", "gpa3-6";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};
> +
> +	/* I2C6 (also called MOTOR_I2C in TRM) */
> +	i2c6_bus: i2c6-bus {
> +		samsung,pins = "gpa3-7", "gpa4-0";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <0>;
> +	};


From robh at kernel.org  Tue Aug 17 11:46:41 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 13:46:41 -0500
Subject: [PATCH v2 6/7] dt-bindings: ARM: at91: document exegin q5xr5 board
In-Reply-To: <20210816064416.1630674-7-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
 <20210816064416.1630674-7-claudiu.beznea@microchip.com>
Message-ID: <YRwEEQ0SgQRDnd7t@robh.at.kernel.org>

On Mon, 16 Aug 2021 09:44:15 +0300, Claudiu Beznea wrote:
> Document Exegin Q5xR5 board.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.



From lkp at intel.com  Tue Aug 17 12:01:09 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 18 Aug 2021 03:01:09 +0800
Subject: [PATCH] drm/panel-simple: Add Vivax TPC-9150 panel v3
In-Reply-To: <20210817163605.1077257-1-pavlica.nikola@gmail.com>
References: <20210817163605.1077257-1-pavlica.nikola@gmail.com>
Message-ID: <202108180209.tYk3gPLL-lkp@intel.com>

Hi Nikola,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-intel/for-linux-next]
[also build test ERROR on drm-tip/drm-tip drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next linus/master v5.14-rc6 next-20210817]
[cannot apply to drm/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Nikola-Pavlica/drm-panel-simple-Add-Vivax-TPC-9150-panel-v3/20210818-003804
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: arm-randconfig-r023-20210816 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/b3b8de24d73c21a6e689abb123326d84425c877b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Nikola-Pavlica/drm-panel-simple-Add-Vivax-TPC-9150-panel-v3/20210818-003804
        git checkout b3b8de24d73c21a6e689abb123326d84425c877b
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/gpu/drm/panel/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/panel/panel-simple.c:4386:23: error: 'MEDIA_BUS_FMT_RGB666_1X24' undeclared here (not in a function); did you mean 'MEDIA_BUS_FMT_RGB666_1X18'?
    4386 |         .bus_format = MEDIA_BUS_FMT_RGB666_1X24,
         |                       ^~~~~~~~~~~~~~~~~~~~~~~~~
         |                       MEDIA_BUS_FMT_RGB666_1X18

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for QCOM_SCM
   Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
   Selected by
   - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU


vim +4386 drivers/gpu/drm/panel/panel-simple.c

  4377	
  4378	static const struct panel_desc vivax_tpc9150_panel = {
  4379		.modes = &vivax_tpc9150_panel_mode,
  4380		.num_modes = 1,
  4381		.size = {
  4382			.width = 200,
  4383			.height = 115,
  4384		},
  4385		.bpc = 6,
> 4386		.bus_format = MEDIA_BUS_FMT_RGB666_1X24,
  4387		.bus_flags = DRM_BUS_FLAG_DE_HIGH,
  4388		.connector_type = DRM_MODE_CONNECTOR_LVDS,
  4389	};
  4390	
  4391	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 37172 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/bb6cfff5/attachment-0001.gz>

From lkp at intel.com  Tue Aug 17 12:13:57 2021
From: lkp at intel.com (kernel test robot)
Date: Wed, 18 Aug 2021 03:13:57 +0800
Subject: [PATCH] drm/panel-simple: Add Vivax TPC-9150 panel v3
In-Reply-To: <20210817163605.1077257-1-pavlica.nikola@gmail.com>
References: <20210817163605.1077257-1-pavlica.nikola@gmail.com>
Message-ID: <202108180327.NESNKQYK-lkp@intel.com>

Hi Nikola,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-intel/for-linux-next]
[also build test ERROR on drm-tip/drm-tip drm-exynos/exynos-drm-next tegra-drm/drm/tegra/for-next linus/master v5.14-rc6 next-20210817]
[cannot apply to drm/drm-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Nikola-Pavlica/drm-panel-simple-Add-Vivax-TPC-9150-panel-v3/20210818-003804
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: arm64-randconfig-r025-20210816 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 2c6448cdc2f68f8c28fd0bd9404182b81306e6e6)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/b3b8de24d73c21a6e689abb123326d84425c877b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Nikola-Pavlica/drm-panel-simple-Add-Vivax-TPC-9150-panel-v3/20210818-003804
        git checkout b3b8de24d73c21a6e689abb123326d84425c877b
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/gpu/drm/panel/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/panel/panel-simple.c:4386:16: error: use of undeclared identifier 'MEDIA_BUS_FMT_RGB666_1X24'
           .bus_format = MEDIA_BUS_FMT_RGB666_1X24,
                         ^
   1 error generated.


vim +/MEDIA_BUS_FMT_RGB666_1X24 +4386 drivers/gpu/drm/panel/panel-simple.c

  4377	
  4378	static const struct panel_desc vivax_tpc9150_panel = {
  4379		.modes = &vivax_tpc9150_panel_mode,
  4380		.num_modes = 1,
  4381		.size = {
  4382			.width = 200,
  4383			.height = 115,
  4384		},
  4385		.bpc = 6,
> 4386		.bus_format = MEDIA_BUS_FMT_RGB666_1X24,
  4387		.bus_flags = DRM_BUS_FLAG_DE_HIGH,
  4388		.connector_type = DRM_MODE_CONNECTOR_LVDS,
  4389	};
  4390	
  4391	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 39490 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/4872afa2/attachment-0001.gz>

From pauld at redhat.com  Tue Aug 17 12:30:10 2021
From: pauld at redhat.com (Phil Auld)
Date: Tue, 17 Aug 2021 15:30:10 -0400
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <20210817170925.2jwqvgvmqab2glwu@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
 <20210817170925.2jwqvgvmqab2glwu@linutronix.de>
Message-ID: <YRwOQtvOW02QFVow@lorien.usersys.redhat.com>

On Tue, Aug 17, 2021 at 07:09:25PM +0200 Sebastian Andrzej Siewior wrote:
> On 2021-08-11 21:13:52 [+0100], Valentin Schneider wrote:
> > diff --git a/include/linux/sched.h b/include/linux/sched.h
> > index debc960f41e3..8ba7b4a7ee69 100644
> > --- a/include/linux/sched.h
> > +++ b/include/linux/sched.h
> > @@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
> >  #endif
> >  }
> >  
> > +/* Is the current task guaranteed to stay on its current CPU? */
> > +static inline bool migratable(void)
> 
> I'm going to rename this in my tree to `is_migratable' because of

It's better anyway. See is_percpu_thread() 5 lines above :)


> |security/keys/trusted-keys/trusted_core.c:45:22: error: ?migratable? redeclared as different kind of symbol
> |   45 | static unsigned char migratable;
> |      |                      ^~~~~~~~~~
> |In file included from arch/arm64/include/asm/compat.h:16,
> |                 from arch/arm64/include/asm/stat.h:13,
> |                 from include/linux/stat.h:6,
> |                 from include/linux/sysfs.h:22,
> |                 from include/linux/kobject.h:20,
> |                 from include/linux/of.h:17,
> |                 from include/linux/irqdomain.h:35,
> |                 from include/linux/acpi.h:13,
> |                 from include/linux/tpm.h:21,
> |                 from include/keys/trusted-type.h:12,
> |                 from security/keys/trusted-keys/trusted_core.c:10:
> |include/linux/sched.h:1719:20: note: previous definition of ?migratable? was here
> | 1719 | static inline bool migratable(void)
> |      |                    ^~~~~~~~~~
> 
> Sebastian
> 

-- 



From wsa at kernel.org  Tue Aug 17 12:36:28 2021
From: wsa at kernel.org (Wolfram Sang)
Date: Tue, 17 Aug 2021 21:36:28 +0200
Subject: [PATCH] i2c: sun6i-pw2i: Prefer strscpy over strlcpy
In-Reply-To: <20210817165859.5429-1-len.baker@gmx.com>
References: <20210817165859.5429-1-len.baker@gmx.com>
Message-ID: <YRwPvKZm8i47xFXP@kunai>

On Tue, Aug 17, 2021 at 06:58:59PM +0200, Len Baker wrote:
> strlcpy() reads the entire source buffer first. This read may exceed the
> destination size limit. This is both inefficient and can lead to linear
> read overflows if a source string is not NUL-terminated. The safe
> replacement is strscpy().
> 
> This is a previous step in the path to remove the strlcpy() function
> entirely from the kernel [1].
> 
> [1] https://github.com/KSPP/linux/issues/89
> 
> Signed-off-by: Len Baker <len.baker at gmx.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/cfb4cd36/attachment.sig>

From linus.walleij at linaro.org  Tue Aug 17 13:00:03 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Aug 2021 22:00:03 +0200
Subject: [GIT PULL] pinctrl: samsung: pull for v5.15
In-Reply-To: <20210817070913.6387-1-krzysztof.kozlowski@canonical.com>
References: <20210817070913.6387-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CACRpkdYpFYZsJ_WZ9UMBfZ83=5uFG8CGv38PBX+xg01UntdSNQ@mail.gmail.com>

On Tue, Aug 17, 2021 at 9:11 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:

> Just few commits for v5.15.

Ah Sam's 850 support, nice! Pulled in for v5.15.

Yours,
Linus Walleij


From wsa at kernel.org  Tue Aug 17 13:08:27 2021
From: wsa at kernel.org (Wolfram Sang)
Date: Tue, 17 Aug 2021 22:08:27 +0200
Subject: [PATCH v2 4/5] i2c: s3c2410: fix IRQ check
In-Reply-To: <771d94cf-5e82-0cb7-fb1f-5af2f0b10dd4@omp.ru>
References: <3712e871-bf2f-32c5-f9c2-2968c42087f8@omp.ru>
 <771d94cf-5e82-0cb7-fb1f-5af2f0b10dd4@omp.ru>
Message-ID: <YRwXOzam9prm9/o/@kunai>

On Sun, Jul 04, 2021 at 05:45:25PM +0300, Sergey Shtylyov wrote:
> Iff platform_get_irq() returns 0, the driver's probe() method will return 0
> early (as if the method's call was successful).  Let's consider IRQ0 valid
> for simplicity -- devm_request_irq() can always override that decision...
> 
> Fixes: 2bbd681ba2b ("i2c-s3c2410: Change IRQ to be plain integer.")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>
> 

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/d5c72e0d/attachment.sig>

From wsa at kernel.org  Tue Aug 17 13:09:09 2021
From: wsa at kernel.org (Wolfram Sang)
Date: Tue, 17 Aug 2021 22:09:09 +0200
Subject: [PATCH v2 2/5] i2c: mt65xx: fix IRQ check
In-Reply-To: <bab29007-8d74-0a68-2378-9db6ba0bc576@omp.ru>
References: <3712e871-bf2f-32c5-f9c2-2968c42087f8@omp.ru>
 <bab29007-8d74-0a68-2378-9db6ba0bc576@omp.ru>
Message-ID: <YRwXZVxORTpddj2k@kunai>

On Sun, Jul 04, 2021 at 05:38:45PM +0300, Sergey Shtylyov wrote:
> Iff platform_get_irq() returns 0, the driver's probe() method will return 0
> early (as if the method's call was successful).  Let's consider IRQ0 valid
> for simplicity -- devm_request_irq() can always override that decision...
> 
> Fixes: ce38815d39ea ("I2C: mediatek: Add driver for MediaTek I2C controller")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omprussia.ru>

Qii Wang, do you like this patch?

> 
> ---
>  drivers/i2c/busses/i2c-mt65xx.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> Index: linux/drivers/i2c/busses/i2c-mt65xx.c
> ===================================================================
> --- linux.orig/drivers/i2c/busses/i2c-mt65xx.c
> +++ linux/drivers/i2c/busses/i2c-mt65xx.c
> @@ -1211,7 +1211,7 @@ static int mtk_i2c_probe(struct platform
>  		return PTR_ERR(i2c->pdmabase);
>  
>  	irq = platform_get_irq(pdev, 0);
> -	if (irq <= 0)
> +	if (irq < 0)
>  		return irq;
>  
>  	init_completion(&i2c->msg_complete);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210817/06d62c2c/attachment.sig>

From linus.walleij at linaro.org  Tue Aug 17 13:09:21 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 17 Aug 2021 22:09:21 +0200
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <d40f6d5fd26aedb13e7a393202e5794b1893ecf8.camel@mediatek.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
 <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
 <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>
 <CACRpkdbZKh8cqqiDRUik6Ooo33e+feGwYsLjcLRvBQnT3x5M3A@mail.gmail.com>
 <a7c8ab68ac3513865698cde27e665bdd554f459e.camel@mediatek.com>
 <CAGXv+5FtL2zaSWx4tUymx6mpCSb5dXG4XNWM9AJL+b6Ok3dxMg@mail.gmail.com>
 <d40f6d5fd26aedb13e7a393202e5794b1893ecf8.camel@mediatek.com>
Message-ID: <CACRpkdYkwXr76Kq5WYdz=1KkLTpaByAL1vJFo8V+2mncqs8-3Q@mail.gmail.com>

On Tue, Aug 17, 2021 at 9:51 AM zhiyong.tao <zhiyong.tao at mediatek.com> wrote:

> In one chip, If GPIO is different, the MTXXXX_PULL_UP_RSEL_001 may
> means different actual bias resistance setting.
>
> For example,
>
> KPROW IO
> Paramters       Descriptions                   Min      Typ     Max
>  UNIT
> Rpd     Input pull-down resistance      40      75      190     Kohm
> Rpu     Input pull-up resistance        40      75      190     Kohm
> Rpd     Input pull-down resistance      0.8     1.6     2       Kohm
> Rpu     Input pull-up resistance        0.8     1.6     2       Kohm

This is exactly why we should try to use SI units in the device tree.
I assume that the software can eventually configure which resistance
it gets?

The electronics people will say make sure it is pulled down by around
80 kOhm, they can put that on the device tree and your code can
say, "hm 40 < 80 < 190 this is OK" and let the value pass.

We do not define these exact semantics, it is up to the driver code
to decide what to do with the Ohm value 80000 in this case, but
it makes perfect sent for me to let it pass and fail if someone
for example requests 20 kOhm, or at least print a helpful warning:

dev_warn(dev, "the requested resistance %d is out of range, supported
range %d to %d kOhm\n",
                 val, low, high);

This is what makes the SI units really helpful for people writing device
trees: solve real integration tasks and make it easy to do the right thing.

Yours,
Linus Walleij


From robh at kernel.org  Tue Aug 17 13:12:06 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:12:06 -0500
Subject: [PATCH v3 02/13] dt-bindings: memory: mediatek: Add mt8195 smi
 sub common
In-Reply-To: <20210810080859.29511-3-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
 <20210810080859.29511-3-yong.wu@mediatek.com>
Message-ID: <YRwYFtVlNjxyRwX+@robh.at.kernel.org>

On Tue, Aug 10, 2021 at 04:08:48PM +0800, Yong Wu wrote:
> Add the binding for smi-sub-common. The SMI block diagram like this:
> 
>         IOMMU
>          |  |
>       smi-common
>   ------------------
>   |      ....      |
>  larb0           larb7   <-max is 8
> 
> The smi-common connects with smi-larb and IOMMU. The maximum larbs number
> that connects with a smi-common is 8. If the engines number is over 8,
> sometimes we use a smi-sub-common which is nearly same with smi-common.
> It supports up to 8 input and 1 output(smi-common has 2 output)
> 
> Something like:
> 
>         IOMMU
>          |  |
>       smi-common
>   ---------------------
>   |      |          ...
> larb0  sub-common   ...   <-max is 8
>       -----------
>        |    |    ...   <-max is 8 too.
>      larb2 larb5
> 
> We don't need extra SW setting for smi-sub-common, only the sub-common has
> special clocks need to enable when the engines access dram.
> 
> If it is sub-common, it should have a "mediatek,smi" phandle to point to
> its smi-common. meanwhile the sub-common only has one gals clock.
> 
> Additionally, add a new property "mediatek,smi_sub_common" for this
> sub-common, this is needed in the IOMMU driver in which we create a device
> link between smi-common and the IOMMU device. If we add the smi-sub-common
> here, the IOMMU driver still need to find the smi-common device. thus,
> add this bool property to indicate if it is sub-common.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
> change note:
> a. change mediatek, smi type from phandle-array to phandle from Rob.
> b. Add a new bool property (mediatek,smi_sub_common) to indicate this is
>    smi-sub-common. the reason is as above.
> ---
>  .../mediatek,smi-common.yaml                  | 30 +++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
> index 602592b6c3f5..26bb9903864b 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
> @@ -38,6 +38,7 @@ properties:
>            - mediatek,mt8192-smi-common
>            - mediatek,mt8195-smi-common-vdo
>            - mediatek,mt8195-smi-common-vpp
> +          - mediatek,mt8195-smi-sub-common
>  
>        - description: for mt7623
>          items:
> @@ -67,6 +68,14 @@ properties:
>      minItems: 2
>      maxItems: 4
>  
> +  mediatek,smi:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: a phandle to the smi-common node above. Only for sub-common.
> +
> +  mediatek,smi_sub_common:

s/_/-/

> +    type: boolean
> +    description: Indicate if this is smi-sub-common.
> +
>  required:
>    - compatible
>    - reg
> @@ -93,6 +102,27 @@ allOf:
>              - const: smi
>              - const: async
>  
> +  - if:  # only for sub common
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - mediatek,mt8195-smi-sub-common
> +    then:
> +      required:
> +        - mediatek,smi
> +        - mediatek,smi_sub_common
> +      properties:
> +        clock:
> +          items:
> +            minItems: 3
> +            maxItems: 3
> +        clock-names:
> +          items:
> +            - const: apb
> +            - const: smi
> +            - const: gals0

If not allowed for other compatibles, you need:

else:
  properties:
    mediatek,sni: false
    mediatek,smi_sub_common: false


> +
>    - if:  # for gen2 HW that have gals
>        properties:
>          compatible:
> -- 
> 2.18.0
> 
> 


From robh at kernel.org  Tue Aug 17 13:16:27 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:16:27 -0500
Subject: [PATCH v2 1/8] dt-bindings: clock: samsung: convert Exynos5250
 to dtschema
In-Reply-To: <20210810093145.26153-2-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-2-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwZG1uerWt+NAQH@robh.at.kernel.org>

On Tue, Aug 10, 2021 at 11:31:38AM +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos5250 clock controller bindings to DT schema format
> using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos5250-clock.txt       | 41 ----------------
>  .../bindings/clock/samsung,exynos-clock.yaml  | 48 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  3 files changed, 49 insertions(+), 41 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> 
> diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
> deleted file mode 100644
> index aff266a12eeb..000000000000
> --- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
> +++ /dev/null
> @@ -1,41 +0,0 @@
> -* Samsung Exynos5250 Clock Controller
> -
> -The Exynos5250 clock controller generates and supplies clock to various
> -controllers within the Exynos5250 SoC.
> -
> -Required Properties:
> -
> -- compatible: should be one of the following.
> -  - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
> -
> -- reg: physical base address of the controller and length of memory mapped
> -  region.
> -
> -- #clock-cells: should be 1.
> -
> -Each clock is assigned an identifier and client nodes can use this identifier
> -to specify the clock which they consume.
> -
> -All available clocks are defined as preprocessor macros in
> -dt-bindings/clock/exynos5250.h header and can be used in device
> -tree sources.
> -
> -Example 1: An example of a clock controller node is listed below.
> -
> -	clock: clock-controller at 10010000 {
> -		compatible = "samsung,exynos5250-clock";
> -		reg = <0x10010000 0x30000>;
> -		#clock-cells = <1>;
> -	};
> -
> -Example 2: UART controller node that consumes the clock generated by the clock
> -	   controller. Refer to the standard clock bindings for information
> -	   about 'clocks' and 'clock-names' property.
> -
> -	serial at 13820000 {
> -		compatible = "samsung,exynos4210-uart";
> -		reg = <0x13820000 0x100>;
> -		interrupts = <0 54 0>;
> -		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
> -		clock-names = "uart", "clk_uart_baud0";
> -	};
> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> new file mode 100644
> index 000000000000..cd6567bd8cc7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> @@ -0,0 +1,48 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/samsung,exynos-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung Exynos SoC clock controller
> +
> +maintainers:
> +  - Chanwoo Choi <cw00.choi at samsung.com>
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  All available clocks are defined as preprocessor macros in
> +  dt-bindings/clock/ headers.
> +
> +properties:
> +  compatible:
> +    const: samsung,exynos5250-clock
> +
> +  assigned-clocks: true
> +  assigned-clock-parents: true
> +  assigned-clock-rates: true

These can be dropped. They are always allowed if 'clocks' is present.

> +  clocks: true

This needs to define how many.

> +
> +  "#clock-cells":
> +    const: 1
> +
> +  reg:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - "#clock-cells"
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/exynos5250.h>
> +    clock: clock-controller at 10010000 {
> +        compatible = "samsung,exynos5250-clock";
> +        reg = <0x10010000 0x30000>;
> +        #clock-cells = <1>;
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 36aee8517ab0..2dbacacac3f5 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16491,6 +16491,7 @@ L:	linux-samsung-soc at vger.kernel.org
>  S:	Supported
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
>  F:	Documentation/devicetree/bindings/clock/exynos*.txt
> +F:	Documentation/devicetree/bindings/clock/samsung,*.yaml
>  F:	Documentation/devicetree/bindings/clock/samsung,s3c*
>  F:	Documentation/devicetree/bindings/clock/samsung,s5p*
>  F:	drivers/clk/samsung/
> -- 
> 2.30.2
> 
> 


From robh at kernel.org  Tue Aug 17 13:17:48 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:17:48 -0500
Subject: [PATCH v2 2/8] dt-bindings: clock: samsung: add bindings for
 Exynos external clock
In-Reply-To: <20210810093145.26153-3-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-3-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwZbBEbbO/bL7gl@robh.at.kernel.org>

On Tue, 10 Aug 2021 11:31:39 +0200, Krzysztof Kozlowski wrote:
> Document the bindings for Samsung Exynos external to SoC
> (oscclk/XXTI/XusbXTI) clock provided on boards.  The bindings are
> already implemented in most of the Exynos clock drivers and DTS files.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../clock/samsung,exynos-ext-clock.yaml       | 46 +++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Aug 17 13:21:05 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:21:05 -0500
Subject: [PATCH v2 3/8] dt-bindings: clock: samsung: convert Exynos542x
 to dtschema
In-Reply-To: <20210810093145.26153-4-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-4-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwaMWChKoasAFYh@robh.at.kernel.org>

On Tue, Aug 10, 2021 at 11:31:40AM +0200, Krzysztof Kozlowski wrote:
> Merge Exynos542x clock controller bindings to existing DT schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos5420-clock.txt       | 42 -------------------
>  .../bindings/clock/samsung,exynos-clock.yaml  | 11 ++++-
>  2 files changed, 10 insertions(+), 43 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
> deleted file mode 100644
> index 717a7b1531c7..000000000000
> --- a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
> +++ /dev/null
> @@ -1,42 +0,0 @@
> -* Samsung Exynos5420 Clock Controller
> -
> -The Exynos5420 clock controller generates and supplies clock to various
> -controllers within the Exynos5420 SoC and for the Exynos5800 SoC.
> -
> -Required Properties:
> -
> -- compatible: should be one of the following.
> -  - "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
> -  - "samsung,exynos5800-clock" - controller compatible with Exynos5800 SoC.
> -
> -- reg: physical base address of the controller and length of memory mapped
> -  region.
> -
> -- #clock-cells: should be 1.
> -
> -Each clock is assigned an identifier and client nodes can use this identifier
> -to specify the clock which they consume.
> -
> -All available clocks are defined as preprocessor macros in
> -dt-bindings/clock/exynos5420.h header and can be used in device
> -tree sources.
> -
> -Example 1: An example of a clock controller node is listed below.
> -
> -	clock: clock-controller at 10010000 {
> -		compatible = "samsung,exynos5420-clock";
> -		reg = <0x10010000 0x30000>;
> -		#clock-cells = <1>;
> -	};
> -
> -Example 2: UART controller node that consumes the clock generated by the clock
> -	   controller. Refer to the standard clock bindings for information
> -	   about 'clocks' and 'clock-names' property.
> -
> -	serial at 13820000 {
> -		compatible = "samsung,exynos4210-uart";
> -		reg = <0x13820000 0x100>;
> -		interrupts = <0 54 0>;
> -		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
> -		clock-names = "uart", "clk_uart_baud0";
> -	};
> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> index cd6567bd8cc7..b0f58a1cf6cb 100644
> --- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> @@ -18,7 +18,16 @@ description: |
>  
>  properties:
>    compatible:
> -    const: samsung,exynos5250-clock
> +    oneOf:
> +      - enum:
> +          - samsung,exynos5250-clock
> +          - samsung,exynos5420-clock
> +          - samsung,exynos5800-clock
> +      - items:
> +          - enum:
> +              - samsung,exynos5420-clock
> +              - samsung,exynos5800-clock

Is there a reason these are supported with or without 'syscon'?

> +          - const: syscon
>  
>    assigned-clocks: true
>    assigned-clock-parents: true
> -- 
> 2.30.2
> 
> 


From robh at kernel.org  Tue Aug 17 13:21:37 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:21:37 -0500
Subject: [PATCH v2 4/8] dt-bindings: clock: samsung: convert Exynos3250
 to dtschema
In-Reply-To: <20210810093145.26153-5-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-5-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwaUVPHIIlxOjkx@robh.at.kernel.org>

On Tue, 10 Aug 2021 11:31:41 +0200, Krzysztof Kozlowski wrote:
> Merge Exynos3250 clock controller bindings to existing DT schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos3250-clock.txt       | 57 -------------------
>  .../bindings/clock/samsung,exynos-clock.yaml  |  3 +
>  2 files changed, 3 insertions(+), 57 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos3250-clock.txt
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Aug 17 13:24:01 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:24:01 -0500
Subject: [PATCH v2 5/8] dt-bindings: clock: samsung: convert Exynos4 to
 dtschema
In-Reply-To: <20210810093145.26153-6-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-6-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwa4ehkBUNwJi+I@robh.at.kernel.org>

On Tue, Aug 10, 2021 at 11:31:42AM +0200, Krzysztof Kozlowski wrote:
> Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
> schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos4-clock.txt          | 86 -------------------
>  .../bindings/clock/samsung,exynos-clock.yaml  | 29 ++++++-
>  2 files changed, 28 insertions(+), 87 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
> deleted file mode 100644
> index 17bb11365354..000000000000
> --- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
> +++ /dev/null
> @@ -1,86 +0,0 @@
> -* Samsung Exynos4 Clock Controller
> -
> -The Exynos4 clock controller generates and supplies clock to various controllers
> -within the Exynos4 SoC. The clock binding described here is applicable to all
> -SoC's in the Exynos4 family.
> -
> -Required Properties:
> -
> -- compatible: should be one of the following.
> -  - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
> -  - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
> -
> -- reg: physical base address of the controller and length of memory mapped
> -  region.
> -
> -- #clock-cells: should be 1.
> -
> -Each clock is assigned an identifier and client nodes can use this identifier
> -to specify the clock which they consume.
> -
> -All available clocks are defined as preprocessor macros in
> -dt-bindings/clock/exynos4.h header and can be used in device
> -tree sources.
> -
> -Example 1: An example of a clock controller node is listed below.
> -
> -	clock: clock-controller at 10030000 {
> -		compatible = "samsung,exynos4210-clock";
> -		reg = <0x10030000 0x20000>;
> -		#clock-cells = <1>;
> -	};
> -
> -Example 2: UART controller node that consumes the clock generated by the clock
> -	   controller. Refer to the standard clock bindings for information
> -	   about 'clocks' and 'clock-names' property.
> -
> -	serial at 13820000 {
> -		compatible = "samsung,exynos4210-uart";
> -		reg = <0x13820000 0x100>;
> -		interrupts = <0 54 0>;
> -		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
> -		clock-names = "uart", "clk_uart_baud0";
> -	};
> -
> -Exynos4412 SoC contains some additional clocks for FIMC-ISP (Camera ISP)
> -subsystem. Registers for those clocks are located in the ISP power domain.
> -Because those registers are also located in a different memory region than
> -the main clock controller, a separate clock controller has to be defined for
> -handling them.
> -
> -Required Properties:
> -
> -- compatible: should be "samsung,exynos4412-isp-clock".
> -
> -- reg: physical base address of the ISP clock controller and length of memory
> -  mapped region.
> -
> -- #clock-cells: should be 1.
> -
> -- clocks: list of the clock controller input clock identifiers,
> -  from common clock bindings, should point to CLK_ACLK200 and
> -  CLK_ACLK400_MCUISP clocks from the main clock controller.
> -
> -- clock-names: list of the clock controller input clock names,
> -  as described in clock-bindings.txt, should be "aclk200" and
> -  "aclk400_mcuisp".
> -
> -- power-domains: a phandle to ISP power domain node as described by
> -  generic PM domain bindings.
> -
> -Example 3: The clock controllers bindings for Exynos4412 SoCs.
> -
> -	clock: clock-controller at 10030000 {
> -		compatible = "samsung,exynos4412-clock";
> -		reg = <0x10030000 0x18000>;
> -		#clock-cells = <1>;
> -	};
> -
> -	isp_clock: clock-controller at 10048000 {
> -		compatible = "samsung,exynos4412-isp-clock";
> -		reg = <0x10048000 0x1000>;
> -		#clock-cells = <1>;
> -		power-domains = <&pd_isp>;
> -		clocks = <&clock CLK_ACLK200>, <&clock CLK_ACLK400_MCUISP>;
> -		clock-names = "aclk200", "aclk400_mcuisp";
> -	};
> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> index c7b07fcd3fa1..ea73201f259b 100644
> --- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> @@ -23,6 +23,9 @@ properties:
>            - samsung,exynos3250-cmu
>            - samsung,exynos3250-cmu-dmc
>            - samsung,exynos3250-cmu-isp
> +          - samsung,exynos4210-clock
> +          - samsung,exynos4412-clock
> +          - samsung,exynos4412-isp-clock
>            - samsung,exynos5250-clock
>            - samsung,exynos5420-clock
>            - samsung,exynos5800-clock
> @@ -35,11 +38,18 @@ properties:
>    assigned-clocks: true
>    assigned-clock-parents: true
>    assigned-clock-rates: true
> -  clocks: true
> +  clocks:
> +    description: |
> +      For samsung,exynos4412-isp-clock, the input clocks should be CLK_ACLK200
> +      and CLK_ACLK400_MCUISP from the main clock controller.
> +
> +  clock-names: true
>  
>    "#clock-cells":
>      const: 1
>  
> +  power-domains: true
> +

How many?

Now all the flavors can have a power domain? Maybe this should be a 
separate binding given this and the if/then below.

>    reg:
>      maxItems: 1
>  
> @@ -50,6 +60,23 @@ required:
>  
>  additionalProperties: false
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: samsung,exynos4412-isp-clock
> +    then:
> +      properties:
> +        clock-names:
> +          items:
> +            - const: aclk200
> +            - const: aclk400_mcuisp
> +      required:
> +        - clocks
> +        - clock-names
> +        - power-domains
> +
>  examples:
>    - |
>      #include <dt-bindings/clock/exynos5250.h>
> -- 
> 2.30.2
> 
> 


From robh at kernel.org  Tue Aug 17 13:25:22 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:25:22 -0500
Subject: [PATCH v2 6/8] dt-bindings: clock: samsung: convert Exynos AudSS
 to dtschema
In-Reply-To: <2f8ff138-4d34-619c-e137-099dc9251e25@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-7-krzysztof.kozlowski@canonical.com>
 <CAPLW+4=tOpaNGs6vxwyVy7xaeX+w_jhtY2P2U8sZGvm6mdqh1Q@mail.gmail.com>
 <2f8ff138-4d34-619c-e137-099dc9251e25@canonical.com>
Message-ID: <YRwbMjZwnX5ix0O0@robh.at.kernel.org>

On Wed, Aug 11, 2021 at 08:46:46AM +0200, Krzysztof Kozlowski wrote:
> On 10/08/2021 19:46, Sam Protsenko wrote:
> > On Tue, 10 Aug 2021 at 12:32, Krzysztof Kozlowski
> > <krzysztof.kozlowski at canonical.com> wrote:
> >>
> >> Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
> >> schema format using json-schema.
> >>
> >> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >> ---
> >>  .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
> >>  .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
> >>  2 files changed, 79 insertions(+), 103 deletions(-)
> >>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
> >>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
> >>
> >> diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
> >> deleted file mode 100644
> >> index 6030afb10b5c..000000000000
> >> --- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
> >> +++ /dev/null
> >> @@ -1,103 +0,0 @@
> >> -* Samsung Audio Subsystem Clock Controller
> >> -
> >> -The Samsung Audio Subsystem clock controller generates and supplies clocks
> >> -to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
> >> -binding described here is applicable to all SoCs in Exynos family.
> >> -
> >> -Required Properties:
> >> -
> >> -- compatible: should be one of the following:
> >> -  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
> >> -  - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
> >> -    SoCs.
> >> -  - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
> >> -    SoCs.
> >> -  - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
> >> -    SoCs.
> >> -- reg: physical base address and length of the controller's register set.
> >> -
> >> -- #clock-cells: should be 1.
> >> -
> >> -- clocks:
> >> -  - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
> >> -    is used if not specified.
> >> -  - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
> >> -    is used if not specified.
> >> -  - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
> >> -    specified.
> >> -  - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
> >> -    not specified.
> >> -  - sclk_pcm_in: PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not
> >> -    specified.
> >> -
> >> -- clock-names: Aliases for the above clocks. They should be "pll_ref",
> >> -  "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
> >> -
> >> -Optional Properties:
> >> -
> >> -  - power-domains: a phandle to respective power domain node as described by
> >> -    generic PM domain bindings (see power/power_domain.txt for more
> >> -    information).
> >> -
> >> -The following is the list of clocks generated by the controller. Each clock is
> >> -assigned an identifier and client nodes use this identifier to specify the
> >> -clock which they consume. Some of the clocks are available only on a particular
> >> -Exynos4 SoC and this is specified where applicable.
> >> -
> >> -Provided clocks:
> >> -
> >> -Clock           ID      SoC (if specific)
> >> ------------------------------------------------
> >> -
> >> -mout_audss      0
> >> -mout_i2s        1
> >> -dout_srp        2
> >> -dout_aud_bus    3
> >> -dout_i2s        4
> >> -srp_clk         5
> >> -i2s_bus         6
> >> -sclk_i2s        7
> >> -pcm_bus         8
> >> -sclk_pcm        9
> >> -adma            10      Exynos5420
> >> -
> >> -Example 1: An example of a clock controller node using the default input
> >> -          clock names is listed below.
> >> -
> >> -clock_audss: audss-clock-controller at 3810000 {
> >> -       compatible = "samsung,exynos5250-audss-clock";
> >> -       reg = <0x03810000 0x0C>;
> >> -       #clock-cells = <1>;
> >> -};
> >> -
> >> -Example 2: An example of a clock controller node with the input clocks
> >> -           specified.
> >> -
> >> -clock_audss: audss-clock-controller at 3810000 {
> >> -       compatible = "samsung,exynos5250-audss-clock";
> >> -       reg = <0x03810000 0x0C>;
> >> -       #clock-cells = <1>;
> >> -       clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
> >> -               <&ext_i2s_clk>;
> >> -       clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
> >> -};
> >> -
> >> -Example 3: I2S controller node that consumes the clock generated by the clock
> >> -           controller. Refer to the standard clock bindings for information
> >> -           about 'clocks' and 'clock-names' property.
> >> -
> >> -i2s0: i2s at 3830000 {
> >> -       compatible = "samsung,i2s-v5";
> >> -       reg = <0x03830000 0x100>;
> >> -       dmas = <&pdma0 10
> >> -               &pdma0 9
> >> -               &pdma0 8>;
> >> -       dma-names = "tx", "rx", "tx-sec";
> >> -       clocks = <&clock_audss EXYNOS_I2S_BUS>,
> >> -               <&clock_audss EXYNOS_I2S_BUS>,
> >> -               <&clock_audss EXYNOS_SCLK_I2S>,
> >> -               <&clock_audss EXYNOS_MOUT_AUDSS>,
> >> -               <&clock_audss EXYNOS_MOUT_I2S>;
> >> -       clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
> >> -                     "mout_audss", "mout_i2s";
> >> -};
> > 
> > Seems like some examples and "Provided clocks" table were dropped in
> > in yaml binding. Also there is no description for example present in
> > yaml file. Is that some redundant info and was dropped intentionally?
> > I'm just worrying about losing some useful info during the conversion.
> 
> I don't see any point of having a clock consumer example in a clock
> provider binding.

+1

Just another one to get wrong...


From robh at kernel.org  Tue Aug 17 13:26:10 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:26:10 -0500
Subject: [PATCH v2 6/8] dt-bindings: clock: samsung: convert Exynos AudSS
 to dtschema
In-Reply-To: <20210810093145.26153-7-krzysztof.kozlowski@canonical.com>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-7-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwbYiS7VTd/NdS5@robh.at.kernel.org>

On Tue, Aug 10, 2021 at 11:31:43AM +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
> schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
>  .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
>  2 files changed, 79 insertions(+), 103 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
> 
> diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
> deleted file mode 100644
> index 6030afb10b5c..000000000000
> --- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
> +++ /dev/null
> @@ -1,103 +0,0 @@
> -* Samsung Audio Subsystem Clock Controller
> -
> -The Samsung Audio Subsystem clock controller generates and supplies clocks
> -to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
> -binding described here is applicable to all SoCs in Exynos family.
> -
> -Required Properties:
> -
> -- compatible: should be one of the following:
> -  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
> -  - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
> -    SoCs.
> -  - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
> -    SoCs.
> -  - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
> -    SoCs.
> -- reg: physical base address and length of the controller's register set.
> -
> -- #clock-cells: should be 1.
> -
> -- clocks:
> -  - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
> -    is used if not specified.
> -  - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
> -    is used if not specified.
> -  - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
> -    specified.
> -  - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
> -    not specified.
> -  - sclk_pcm_in: PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not
> -    specified.
> -
> -- clock-names: Aliases for the above clocks. They should be "pll_ref",
> -  "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
> -
> -Optional Properties:
> -
> -  - power-domains: a phandle to respective power domain node as described by
> -    generic PM domain bindings (see power/power_domain.txt for more
> -    information).
> -
> -The following is the list of clocks generated by the controller. Each clock is
> -assigned an identifier and client nodes use this identifier to specify the
> -clock which they consume. Some of the clocks are available only on a particular
> -Exynos4 SoC and this is specified where applicable.
> -
> -Provided clocks:
> -
> -Clock           ID      SoC (if specific)
> ------------------------------------------------
> -
> -mout_audss      0
> -mout_i2s        1
> -dout_srp        2
> -dout_aud_bus    3
> -dout_i2s        4
> -srp_clk         5
> -i2s_bus         6
> -sclk_i2s        7
> -pcm_bus         8
> -sclk_pcm        9
> -adma            10      Exynos5420
> -
> -Example 1: An example of a clock controller node using the default input
> -	   clock names is listed below.
> -
> -clock_audss: audss-clock-controller at 3810000 {
> -	compatible = "samsung,exynos5250-audss-clock";
> -	reg = <0x03810000 0x0C>;
> -	#clock-cells = <1>;
> -};
> -
> -Example 2: An example of a clock controller node with the input clocks
> -           specified.
> -
> -clock_audss: audss-clock-controller at 3810000 {
> -	compatible = "samsung,exynos5250-audss-clock";
> -	reg = <0x03810000 0x0C>;
> -	#clock-cells = <1>;
> -	clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
> -		<&ext_i2s_clk>;
> -	clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
> -};
> -
> -Example 3: I2S controller node that consumes the clock generated by the clock
> -           controller. Refer to the standard clock bindings for information
> -           about 'clocks' and 'clock-names' property.
> -
> -i2s0: i2s at 3830000 {
> -	compatible = "samsung,i2s-v5";
> -	reg = <0x03830000 0x100>;
> -	dmas = <&pdma0 10
> -		&pdma0 9
> -		&pdma0 8>;
> -	dma-names = "tx", "rx", "tx-sec";
> -	clocks = <&clock_audss EXYNOS_I2S_BUS>,
> -		<&clock_audss EXYNOS_I2S_BUS>,
> -		<&clock_audss EXYNOS_SCLK_I2S>,
> -		<&clock_audss EXYNOS_MOUT_AUDSS>,
> -		<&clock_audss EXYNOS_MOUT_I2S>;
> -	clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
> -		      "mout_audss", "mout_i2s";
> -};
> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
> new file mode 100644
> index 000000000000..d60b29fa22e7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
> @@ -0,0 +1,79 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/samsung,exynos-audss-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung Exynos SoC Audio SubSystem clock controller
> +
> +maintainers:
> +  - Chanwoo Choi <cw00.choi at samsung.com>
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  All available clocks are defined as preprocessor macros in
> +  include/dt-bindings/clock/exynos-audss-clk.h header.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - samsung,exynos4210-audss-clock
> +      - samsung,exynos5250-audss-clock
> +      - samsung,exynos5410-audss-clock
> +      - samsung,exynos5420-audss-clock
> +
> +  clocks:
> +    minItems: 2
> +    items:
> +      - description:
> +          Fixed rate PLL reference clock, parent of mout_audss. "fin_pll" is
> +          used if not specified.
> +      - description:
> +          Input PLL to the AudioSS block, parent of mout_audss. "fout_epll" is
> +          used if not specified.
> +      - description:
> +          Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if not
> +          specified.
> +      - description:
> +          PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not specified.
> +      - description:
> +          External i2s clock, parent of mout_i2s. "cdclk0" is used if not
> +          specified.
> +
> +  clock-names:
> +    minItems: 2
> +    items:
> +      - const: pll_ref
> +      - const: pll_in
> +      - const: sclk_audio
> +      - const: sclk_pcm_in
> +      - const: cdclk
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  power-domains: true

How many?

> +
> +  reg:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - "#clock-cells"
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    clock-controller at 3810000 {
> +        compatible = "samsung,exynos5250-audss-clock";
> +        reg = <0x03810000 0x0c>;
> +        #clock-cells = <1>;
> +        clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>, <&ext_i2s_clk>;
> +        clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
> +    };
> -- 
> 2.30.2
> 
> 


From robh at kernel.org  Tue Aug 17 13:27:41 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:27:41 -0500
Subject: [PATCH v2 1/4] dt-bindings: perf: marvell: cn10k ddr performance
 monitor
In-Reply-To: <20210810094307.29595-2-bbhushan2@marvell.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
 <20210810094307.29595-2-bbhushan2@marvell.com>
Message-ID: <YRwbvfCYl94UDseY@robh.at.kernel.org>

On Tue, Aug 10, 2021 at 03:13:04PM +0530, Bharat Bhushan wrote:
> Add binding documentation for the Marvell CN10k DDR
> performance monitor unit.
> 
> Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
> ---
> v1->v2:
>  - DT binding changed to new DT Schema
> 
>  .../bindings/perf/marvell-cn10k-ddr.yaml      | 37 +++++++++++++++++++
>  1 file changed, 37 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
> 
> diff --git a/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
> new file mode 100644
> index 000000000000..2a335444cf53
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
> @@ -0,0 +1,37 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/perf/marvell-cn10k-ddr.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Marvell CN10K DDR performance monitor
> +
> +maintainers:
> +  - Bharat Bhushan <bbhushan2 at marvell.com>
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - marvell,cn10k-ddr-pmu
> +
> +  reg:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    bus {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        ddrcpmu at 1 {

pmu at 87e1c0000000

> +            compatible = "marvell,cn10k-ddr-pmu";
> +            reg = <0x87e1 0xc0000000 0x0 0x10000>;
> +        };
> +    };
> -- 
> 2.17.1
> 
> 


From robh at kernel.org  Tue Aug 17 13:27:58 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:27:58 -0500
Subject: [PATCH v2 1/2] dt-bindings: arm: amlogic: add support for Radxa
 Zero
In-Reply-To: <20210810102613.25149-2-christianshewitt@gmail.com>
References: <20210810102613.25149-1-christianshewitt@gmail.com>
 <20210810102613.25149-2-christianshewitt@gmail.com>
Message-ID: <YRwbzripmlsoG3Fp@robh.at.kernel.org>

On Tue, 10 Aug 2021 10:26:12 +0000, Christian Hewitt wrote:
> Radxa Zero is a small form-factor SBC with an Amlogic S905Y2 chip.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From robh at kernel.org  Tue Aug 17 13:33:39 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 15:33:39 -0500
Subject: [PATCH v5, 05/15] dt-bindings: media: mtk-vcodec: Separate video
 encoder and decoder dt-bindings
In-Reply-To: <20210811025801.21597-6-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-6-yunfei.dong@mediatek.com>
Message-ID: <YRwdI7GcPofoSube@robh.at.kernel.org>

On Wed, 11 Aug 2021 10:57:51 +0800, Yunfei Dong wrote:
> Decoder will use component framework to manage hardware, it is big
> difference with encoder.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
> v5: no changes
> ---
>  .../media/mediatek,vcodec-decoder.yaml        | 175 +++++++++++++++++
>  .../media/mediatek,vcodec-encoder.yaml        | 185 ++++++++++++++++++
>  .../bindings/media/mediatek-vcodec.txt        | 130 ------------
>  3 files changed, 360 insertions(+), 130 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
>  delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Aug 17 14:11:39 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:11:39 -0500
Subject: [PATCH 1/2] dt-bindings: ata: drop unused Exynos SATA bindings
In-Reply-To: <20210811083859.28234-1-krzysztof.kozlowski@canonical.com>
References: <20210811083859.28234-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwmCyppx3InBR+1@robh.at.kernel.org>

On Wed, 11 Aug 2021 10:38:58 +0200, Krzysztof Kozlowski wrote:
> The Samsung Exynos SoC SATA bindings are not implemented in the kernel,
> not used and superseded by generic
> Documentation/devicetree/bindings/ata/ahci-platform.txt bindings.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/ata/exynos-sata.txt   | 30 -------------------
>  1 file changed, 30 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/ata/exynos-sata.txt
> 

Applied, thanks!


From robh at kernel.org  Tue Aug 17 14:13:01 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:13:01 -0500
Subject: [PATCH 1/2] dt-bindings: irqchip: convert Samsung Exynos IRQ
 combiner to dtschema
In-Reply-To: <20210811084306.28740-1-krzysztof.kozlowski@canonical.com>
References: <20210811084306.28740-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwmXWUzF2AbEhcQ@robh.at.kernel.org>

On Wed, 11 Aug 2021 10:43:05 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos SoC Interrupt Combiner Controller bindings to DT
> schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../samsung,exynos4210-combiner.txt           | 50 ----------
>  .../samsung,exynos4210-combiner.yaml          | 96 +++++++++++++++++++
>  2 files changed, 96 insertions(+), 50 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.txt
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/samsung,exynos4210-combiner.yaml
> 

Applied, thanks!


From robh at kernel.org  Tue Aug 17 14:15:07 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:15:07 -0500
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to
 dtschema
In-Reply-To: <20210811084306.28740-2-krzysztof.kozlowski@canonical.com>
References: <20210811084306.28740-1-krzysztof.kozlowski@canonical.com>
 <20210811084306.28740-2-krzysztof.kozlowski@canonical.com>
Message-ID: <YRwm27L+PQx0TydS@robh.at.kernel.org>

On Wed, 11 Aug 2021 10:43:06 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos SoC True Random Number Generator bindings to DT
> schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
>  .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
>  MAINTAINERS                                   |  2 +-
>  3 files changed, 45 insertions(+), 18 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>  create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
> 

Applied, thanks!


From robh at kernel.org  Tue Aug 17 14:21:58 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:21:58 -0500
Subject: [PATCH v3 3/7] dt-bindings: serial: samsung: Add Exynos850 doc
In-Reply-To: <20210811114827.27322-4-semen.protsenko@linaro.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
 <20210811114827.27322-4-semen.protsenko@linaro.org>
Message-ID: <YRwodjUxlZmvrvSC@robh.at.kernel.org>

On Wed, 11 Aug 2021 14:48:23 +0300, Sam Protsenko wrote:
> Add compatible string for Exynos850 SoC.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> Changes in v3:
>   - None
> 
> Changes in v2:
>   - None
> 
>  Documentation/devicetree/bindings/serial/samsung_uart.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From robh at kernel.org  Tue Aug 17 14:23:59 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:23:59 -0500
Subject: [V11,PATCH 02/19] dt-bindings: mediatek: add compatible for
 MT8195 dvfsrc
In-Reply-To: <20210812085846.2628-3-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
 <20210812085846.2628-3-dawei.chien@mediatek.com>
Message-ID: <YRwo72vWlsY1cPw+@robh.at.kernel.org>

On Thu, 12 Aug 2021 16:58:29 +0800, Dawei Chien wrote:
> This adds dt-binding documentation of dvfsrc for Mediatek MT8195
> SoCs Platform.
> 
> Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
> ---
>  Documentation/devicetree/bindings/soc/mediatek/dvfsrc.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From robh at kernel.org  Tue Aug 17 14:24:21 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:24:21 -0500
Subject: [V11,PATCH 11/19] dt-bindings: interconnect: add MT8195
 interconnect dt-bindings
In-Reply-To: <20210812085846.2628-12-dawei.chien@mediatek.com>
References: <20210812085846.2628-1-dawei.chien@mediatek.com>
 <20210812085846.2628-12-dawei.chien@mediatek.com>
Message-ID: <YRwpBQu+rXPiUe3i@robh.at.kernel.org>

On Thu, 12 Aug 2021 16:58:38 +0800, Dawei Chien wrote:
> Add interconnect provider dt-bindings for MT8195
> 
> Signed-off-by: Dawei Chien <dawei.chien at mediatek.com>
> ---
>  include/dt-bindings/interconnect/mtk,mt8195-emi.h | 42 +++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
>  create mode 100644 include/dt-bindings/interconnect/mtk,mt8195-emi.h
> 

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


From robh at kernel.org  Tue Aug 17 14:28:39 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:28:39 -0500
Subject: [PATCH 2/3] dt-bindings: msm: Add QTI download mode support
 binding
In-Reply-To: <217c22d40e0a9db713e2a55623408eca88166897.1628757036.git.saiprakash.ranjan@codeaurora.org>
References: <cover.1628757036.git.saiprakash.ranjan@codeaurora.org>
 <217c22d40e0a9db713e2a55623408eca88166897.1628757036.git.saiprakash.ranjan@codeaurora.org>
Message-ID: <YRwqBx4hNsbsPYY0@robh.at.kernel.org>

On Thu, Aug 12, 2021 at 02:47:41PM +0530, Sai Prakash Ranjan wrote:
> Add device tree binding for QTI download mode cookies
> region found in IMEM.
> 
> Signed-off-by: Sai Prakash Ranjan <saiprakash.ranjan at codeaurora.org>
> ---
>  .../bindings/arm/msm/qcom,dload-mode.yaml     | 53 +++++++++++++++++++
>  1 file changed, 53 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,dload-mode.yaml
> 
> diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,dload-mode.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,dload-mode.yaml
> new file mode 100644
> index 000000000000..90b9b6a9b75e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/msm/qcom,dload-mode.yaml
> @@ -0,0 +1,53 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/arm/msm/qcom,dload-mode.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm Download Mode binding
> +
> +maintainers:
> +  - Sai Prakash Ranjan <saiprakash.ranjan at codeaurora.org>
> +
> +description:
> +  Qualcomm download mode cookies memory region in IMEM is used by SDI
> +  (System Debug Image) firmware to determine whether to enter download
> +  mode or not to collect ramdump for post mortem debug.
> +
> +properties:
> +  compatible:
> +    const: qcom,dload-mode
> +
> +  reg:
> +    maxItems: 1
> +
> +  qcom,sdi-disable-regs:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description:
> +      Phandle reference to a syscon representing TCSR followed by the
> +      offset and length for SDI disable register.
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    imem at 146aa000 {
> +      compatible = "simple-mfd";

If this is just internal RAM, then we already have a binding for it and 
'simple-mfd' is not it.

> +      reg = <0x146aa000 0x2000>;
> +
> +      #address-cells = <1>;
> +      #size-cells = <1>;
> +
> +      ranges = <0 0x146aa000 0x2000>;
> +
> +      dload-mode at 1c00 {
> +        compatible = "qcom,dload-mode";
> +        reg = <0x1c00 0x1000>;

0x1c00 + 0x1000 > 0x2000


> +        qcom,sdi-disable-regs = <&tcsr_regs 0x3a000 0x4>;
> +      };
> +    };
> +...
> -- 
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
> 
> 


From robh at kernel.org  Tue Aug 17 14:30:48 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:30:48 -0500
Subject: [PATCH v2 01/29] dt-bindings: arm: renesas: Document more R-Car
 Gen3e Socs and boards
In-Reply-To: <55271d405112f327753945072cde5d158ab815b1.1628766192.git.geert+renesas@glider.be>
References: <cover.1628766192.git.geert+renesas@glider.be>
 <55271d405112f327753945072cde5d158ab815b1.1628766192.git.geert+renesas@glider.be>
Message-ID: <YRwqiIHa/avcyvQp@robh.at.kernel.org>

On Thu, 12 Aug 2021 13:23:51 +0200, Geert Uytterhoeven wrote:
> Document the compatible values for the remaining R-Car Gen3e SoCs: R-Car
> H3e (R8A779M0), M3e (R8A779M2), M3Ne (R8A779M4), M3Ne-2G (R8A779M5), E3e
> (R8A779M6), D3e (R8A779M7), and H3Ne (R8A779M8).  These are different
> gradings of R-Car Gen3 SoCs.
> 
> All R-Car Gen3e on-SoC devices are identical to the devices on the
> corresponding R-Car Gen3 SoCs, and thus just use the compatible values
> for the latter.  The root compatible properties do gain an additional
> value, to sort out integration issues if they ever arise.
> 
> Document the use of these SoCs on the Salvator-XS, ULCB (with and
> without Kingfisher extension), Ebisu, and Draak development boards.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> v2:
>   - Typo s/R8A779M/R8A779M0/,
>   - Add Reviewed-by.
> ---
>  .../devicetree/bindings/arm/renesas.yaml      | 61 +++++++++++++++++++
>  1 file changed, 61 insertions(+)
> 

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


From robh at kernel.org  Tue Aug 17 14:31:53 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:31:53 -0500
Subject: [PATCH v2 1/8] dt-bindings: soc: rockchip: add rk3568-usb2phy-grf
In-Reply-To: <20210812204116.2303617-2-pgwipeout@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
 <20210812204116.2303617-2-pgwipeout@gmail.com>
Message-ID: <YRwqyZEF6FRpkdHQ@robh.at.kernel.org>

On Thu, 12 Aug 2021 16:41:09 -0400, Peter Geis wrote:
> Add the documentation for the rk3568-usb2phy-grf node, which is separate
> from the usb2phy node on this chip.
> 
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
>  Documentation/devicetree/bindings/soc/rockchip/grf.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From robh at kernel.org  Tue Aug 17 14:43:59 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:43:59 -0500
Subject: [PATCH v2 2/8] dt-bindings: phy: phy-rockchip-inno-usb2: add
 rk3568 documentation
In-Reply-To: <c7ff9234-cc3b-3679-bc63-73c5eb825269@gmail.com>
References: <20210812204116.2303617-1-pgwipeout@gmail.com>
 <20210812204116.2303617-3-pgwipeout@gmail.com>
 <c7ff9234-cc3b-3679-bc63-73c5eb825269@gmail.com>
Message-ID: <YRwtnxucxIeq+ayx@robh.at.kernel.org>

On Tue, Aug 17, 2021 at 06:52:15PM +0200, Johan Jonker wrote:
> Hi Peter,
> 
> Some comments. Have a look if it's useful.
> 
> On 8/12/21 10:41 PM, Peter Geis wrote:
> > The rk3568 usb2phy node is a standalone node with a single muxed
> > interrupt.
> > Add documentation for it to phy-rockchip-inno-usb2.
> > 
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >  .../bindings/phy/phy-rockchip-inno-usb2.yaml  | 31 ++++++++++++++++---
> >  1 file changed, 27 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> > index 5bebd86bf8b6..d2a749c3f9a3 100644
> > --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> > +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
> > @@ -18,6 +18,7 @@ properties:
> >        - rockchip,rk3328-usb2phy
> >        - rockchip,rk3366-usb2phy
> >        - rockchip,rk3399-usb2phy
> > +      - rockchip,rk3568-usb2phy
> >        - rockchip,rv1108-usb2phy
> >  
> >    reg:
> > @@ -50,6 +51,9 @@ properties:
> >      description:
> >        Phandle to the extcon device providing the cable state for the otg phy.
> >  
> 
> > +  interrupts:
> > +    description: Muxed interrupt for both ports
> > +
> 
> This allows every Rockchip SoC dtsi to add an interrupt here.
> You have only restricted the requirements.
> The goal is to restrict things and filter bogus properties.
> If it was done because it doesn't compile, maybe could you try/test/use
> something like the rockchip-io-domain.yaml $defs format.

Don't use $defs unless there's more than 1 copy needed of something. If 
it happens to bypass some checks, it's only a matter of time til I fix 
that.

This may be better solved with another schema file rather than a long 
if/then schema. It's a judgement call.

> 
> ===
> 
> unevaluatedProperties: false
> 
> allOf:
>   - $ref: "#/$defs/rk3568"
> 
> $defs:
>   rk3568:
>     if:
>       properties:
>         compatible:
>           contains:
>             const: rockchip,rk3568-usb2phy
> 
>     then:
>       properties:
>         interrupts:
>           maxItems: 1
> 
>       required:
>         - interrupts
> 
>     else:
>       properties:
>         host-port:
>           properties:
>             interrupts:
>               description: host linestate interrupt
> 
>             interrupt-names:
>               const: linestate
> 
>           required:
>             - interrupts
>             - interrupt-names
> 
>         otg-port:
>           properties:
> 
>            interrupts:
>              minItems: 1
>              maxItems: 3
> 
>            interrupt-names:
>              oneOf:
>                - const: linestate
>                - const: otg-mux
>                - items:
>                    - const: otg-bvalid
>                    - const: otg-id
>                    - const: linestate
> 
>           required:
>             - interrupts
>             - interrupt-names
> 
> >    rockchip,usbgrf:
> >      $ref: /schemas/types.yaml#/definitions/phandle
> >      description:
> > @@ -78,8 +82,6 @@ properties:
> >  
> >      required:
> >        - "#phy-cells"
> 
> > -      - interrupts
> > -      - interrupt-names
> 
> Also remove them as properties in this part when a separate $defs is used.
> 
> >  
> >    otg-port:
> >      type: object
> > @@ -109,8 +111,6 @@ properties:
> >  
> >      required:
> >        - "#phy-cells"
> 
> > -      - interrupts
> > -      - interrupt-names
> 
> dito
> 
> >  
> >  required:
> >    - compatible
> > @@ -120,6 +120,29 @@ required:
> >    - host-port
> >    - otg-port
> >  
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: rockchip,rk3568-usb2phy
> 
> > +      then:
> 
> Test "if then else" alignment with yamllint

yamllint is not going to help there. What's needed is a meta-schema that 
adds the dependencies.

> 
> > +        properties:
> > +          interrupts:
> > +            maxItems: 1
> > +        required:
> > +          - interrupts
> 
> > +      else:
> 
> alignment
> 
> > +        properties:
> > +          host-port:
> > +            required:
> > +              - interrupts
> > +              - interrupt-names
> > +          otg-port:
> > +            required:
> > +              - interrupts
> > +              - interrupt-names
> > +
> 
> >  additionalProperties: false
> 
> additionalProperties does workn't with allOf: - $ref. Use
> unevaluatedProperties.
> 
> >  
> >  examples:
> > 
> 


From robh at kernel.org  Tue Aug 17 14:44:53 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 16:44:53 -0500
Subject: [PATCH v2 02/29] dt-bindings: mediatek: mt8195: Add binding for
 infra IOMMU
In-Reply-To: <20210813065324.29220-3-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
 <20210813065324.29220-3-yong.wu@mediatek.com>
Message-ID: <YRwt1f6UBL0zoxF4@robh.at.kernel.org>

On Fri, 13 Aug 2021 14:52:57 +0800, Yong Wu wrote:
> In mt8195, we have a new IOMMU that is for INFRA IOMMU. its masters
> mainly are PCIe and USB. Different with MM IOMMU, all these masters
> connect with IOMMU directly, there is no mediatek,larbs property for
> infra IOMMU.
> 
> Another thing is about PCIe ports. currently the function
> "of_iommu_configure_dev_id" only support the id number is 1, But our
> PCIe have two ports, one is for reading and the other is for writing.
> see more about the PCIe patch in this patchset. Thus, I only list
> the reading id here and add the other id in our driver.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
> Change note: use "contains" commented from Rob.
> ---
>  .../bindings/iommu/mediatek,iommu.yaml         | 13 ++++++++++++-
>  .../dt-bindings/memory/mt8195-memory-port.h    | 18 ++++++++++++++++++
>  include/dt-bindings/memory/mtk-memory-port.h   |  2 ++
>  3 files changed, 32 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From pcc at google.com  Tue Aug 17 14:58:27 2021
From: pcc at google.com (Peter Collingbourne)
Date: Tue, 17 Aug 2021 14:58:27 -0700
Subject: [PATCH] arm64: symbolize user-space stack on SIGSEGV
Message-ID: <20210817215827.2763811-1-pcc@google.com>

On arm64, dump the userspace stack to the console when a SIGSEGV
occurs. Print filename+offset to allow symbolization.

This is a patch that I frequently need to apply locally in order to
debug segfaults that occur in environments where attaching a debugger
is infeasible.

Although I don't expect this patch to be applied to the mainline
kernel, I am posting it in case anyone else would find it useful
(and because I almost lost track of it recently, and I don't want to
have to write it again).

Signed-off-by: Peter Collingbourne <pcc at google.com>
---
 arch/arm64/mm/fault.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 349c488765ca..8db82788e80b 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -526,6 +526,38 @@ static bool is_write_abort(unsigned int esr)
 	return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM);
 }
 
+static void symbolize_addr(const char *prefix, unsigned long addr)
+{
+	struct vm_area_struct *vma = find_vma(current->mm, addr);
+	if (vma && vma->vm_file) {
+		char buf[1024];
+		char *c = d_path(&vma->vm_file->f_path, buf, 1024);
+		printk(KERN_ERR "%s = 0x%lx (%s + 0x%lx)\n", prefix, addr, c,
+		       addr - vma->vm_start + vma->vm_pgoff * PAGE_SIZE);
+	} else {
+		printk(KERN_ERR "%s = 0x%lx", prefix, addr);
+	}
+}
+
+static void symbolize_stack(void)
+{
+	int i;
+	unsigned long frame = current_pt_regs()->regs[29];
+
+	symbolize_addr("pc", current_pt_regs()->pc);
+	symbolize_addr("lr", current_pt_regs()->regs[30]);
+
+	for (i = 0; i != 64; ++i) {
+		unsigned long ret_addr;
+		unsafe_get_user(ret_addr, (unsigned long __user *)(frame + 8),
+				end);
+		symbolize_addr("ret_addr", ptrauth_clear_pac(ret_addr));
+
+		unsafe_get_user(frame, (unsigned long __user *)frame, end);
+	}
+end:;
+}
+
 static int __kprobes do_page_fault(unsigned long far, unsigned int esr,
 				   struct pt_regs *regs)
 {
@@ -671,6 +703,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned int esr,
 		 * Something tried to access memory that isn't in our memory
 		 * map.
 		 */
+		symbolize_stack();
 		arm64_force_sig_fault(SIGSEGV,
 				      fault == VM_FAULT_BADACCESS ? SEGV_ACCERR : SEGV_MAPERR,
 				      far, inf->name);
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From l.stelmach at samsung.com  Tue Aug 17 15:17:24 2021
From: l.stelmach at samsung.com (Lukasz Stelmach)
Date: Wed, 18 Aug 2021 00:17:24 +0200
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to
 dtschema
In-Reply-To: <da43d243-35b0-2cc6-f8a0-a5d02c997301@canonical.com> (Krzysztof
 Kozlowski's message of "Tue, 17 Aug 2021 16:07:20 +0200")
References: <da43d243-35b0-2cc6-f8a0-a5d02c997301@canonical.com>
 <CGME20210817221734eucas1p2e4a0aa41406137b90e49230371b92ac6@eucas1p2.samsung.com>
Message-ID: <dleftjtujnemx7.fsf%l.stelmach@samsung.com>

It was <2021-08-17 wto 16:07>, when Krzysztof Kozlowski wrote:
> On 17/08/2021 14:34, Lukasz Stelmach wrote:
>> It was <2021-08-17 wto 12:05>, when Krzysztof Kozlowski wrote:
>>> On 17/08/2021 11:55, Lukasz Stelmach wrote:
>>>> It was <2021-08-11 ?ro 10:43>, when Krzysztof Kozlowski wrote:
>>>>> Convert Samsung Exynos SoC True Random Number Generator bindings to DT
>>>>> schema format using json-schema.
>>>>>
>>>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>>> ---
>>>>>  .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
>>>>>  .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
>>>>>  MAINTAINERS                                   |  2 +-
>>>>>  3 files changed, 45 insertions(+), 18 deletions(-)
>>>>>  delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>>  create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>>
>>>>> diff --git
>>>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>> deleted file mode 100644
>>>>> index 5a613a4ec780..000000000000
>>>>> --- a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>> +++ /dev/null
>>>>> @@ -1,17 +0,0 @@
>>>>> -Exynos True Random Number Generator
>>>>> -
>>>>> -Required properties:
>>>>> -
>>>>> -- compatible  : Should be "samsung,exynos5250-trng".
>>>>> -- reg         : Specifies base physical address and size of the registers map.
>>>>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
>>>>> -- clock-names : "secss" as a clock name.
>>>>> -
>>>>> -Example:
>>>>> -
>>>>> -	rng at 10830600 {
>>>>> -		compatible = "samsung,exynos5250-trng";
>>>>> -		reg = <0x10830600 0x100>;
>>>>> -		clocks = <&clock CLK_SSS>;
>>>>> -		clock-names = "secss";
>>>>> -	};
>>>>> diff --git
>>>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>> new file mode 100644
>>>>> index 000000000000..a50c34d5d199
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>> @@ -0,0 +1,44 @@
>>>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>>>>> +%YAML 1.2
>>>>> +---
>>>>> +$id:
>>>>> https://protect2.fireeye.com/v1/url?k=f38ca35b-ac179a0d-f38d2814-0cc47a31ce52-1faa1ecb65482b8a&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Frng%2Fsamsung%2Cexynos5250-trng.yaml%23
>>>>> +$schema:
>>>>> https://protect2.fireeye.com/v1/url?k=9409519d-cb9268cb-9408dad2-0cc47a31ce52-12394c4409905980&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>>>>> +
>>>>> +title: Samsung Exynos SoC True Random Number Generator
>>>>> +
>>>>> +maintainers:
>>>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>>> +  - ?ukasz Stelmach <l.stelmach at samsung.com>
>>>>> +
>>>>> +properties:
>>>>> +  compatible:
>>>>> +    const: samsung,exynos5250-trng
>>>>> +
>>>>> +  clocks:
>>>>> +    maxItems: 1
>>>>
>>>> How about copying description from above into the description: property?
>>>
>>> But what to copy? There is no description except generic clock bindings.
>>>
>> 
>> The description that "was" in the txt file.
>
> But there was no description of fields except copy&paste of the core
> schema. Do you describe C code like:
>
> ...
> /* unsigned int is a integer number greater or equal 0 */
> unsigned int i;
> ...

I believe having descriptions for reg and clocks

>>>>> -- reg         : Specifies base physical address and size of the registers map.
>>>>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.

right next to properties' formal definitions is beneficial for anyone
browsing the YAML file. If you think otherwise, oh well, I am fine with
that.

-- 
?ukasz Stelmach
Samsung R&D Institute Poland
Samsung Electronics
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 487 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/b923a0a4/attachment-0001.sig>

From robh at kernel.org  Tue Aug 17 15:18:36 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 17:18:36 -0500
Subject: [PATCH v2 3/7] dt-bindings: ARM: at91: document CalAmp LMU5000
 board
In-Reply-To: <20210816064416.1630674-4-claudiu.beznea@microchip.com>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
 <20210816064416.1630674-4-claudiu.beznea@microchip.com>
Message-ID: <YRw1vN9KHSY1hCmR@robh.at.kernel.org>

On Mon, 16 Aug 2021 09:44:12 +0300, Claudiu Beznea wrote:
> Document CalAmp LMU5000.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

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


From robh at kernel.org  Tue Aug 17 15:27:37 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 17:27:37 -0500
Subject: [PATCH 0/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
Message-ID: <YRw32YE4cnNnWSvl@robh.at.kernel.org>

On Mon, Aug 16, 2021 at 03:46:16PM +0800, Kefeng Wang wrote:
> Patch 1 and 2 make some cleanup, and patch 3 use of_irq_get() instead of 
> irq_of_parse_and_map() to get irq number, return -EPROBE_DEFER if the irq
> domain is not yet created, amba_device_add() will properly to handle the
> no IRQ domain issue via deferred probe.
> 
> Kefeng Wang (3):
>   amba: Drop unused functions about APB/AHB devices add
>   Revert "ARM: amba: make use of -1 IRQs warn"
>   amba: Properly handle device probe without IRQ domain
> 
>  drivers/amba/bus.c       | 100 ++++++++++-----------------------------
>  drivers/of/platform.c    |   6 +--
>  include/linux/amba/bus.h |  18 -------
>  3 files changed, 27 insertions(+), 97 deletions(-)

Reviewed-by: Rob Herring <robh at kernel.org>


From sean.anderson at seco.com  Tue Aug 17 15:56:28 2021
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 17 Aug 2021 18:56:28 -0400
Subject: [PATCH v5 3/3] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <20210817180407.ru4prwu344dxpynu@pengutronix.de>
References: <20210719221322.3723009-1-sean.anderson@seco.com>
 <20210719221322.3723009-3-sean.anderson@seco.com>
 <20210814204710.retjwn5fycwtrypp@pengutronix.de>
 <e8d39f18-3aa9-e617-6439-2c0b071f62b3@seco.com>
 <20210817180407.ru4prwu344dxpynu@pengutronix.de>
Message-ID: <082d39cd-1ce5-344f-3229-3beb7cea0a15@seco.com>



On 8/17/21 2:04 PM, Uwe Kleine-K?nig wrote:
> On Mon, Aug 16, 2021 at 07:51:17PM -0400, Sean Anderson wrote:
>>
>>
>> On 8/14/21 4:47 PM, Uwe Kleine-K?nig wrote:
>> > Hello Sean,
>> >
>> > sorry for having you let waiting so long. Now here some more feedback:
>> >
>> > On Mon, Jul 19, 2021 at 06:13:22PM -0400, Sean Anderson wrote:
>> > > +static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
>> > > +			    const struct pwm_state *state)
>> > > +{
>> > > +	bool enabled;
>> > > +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
>> > > +	u32 tlr0, tlr1, tcsr0, tcsr1;
>> > > +	u64 period_cycles, duty_cycles;
>> > > +	unsigned long rate;
>> > > +
>> > > +	if (state->polarity != PWM_POLARITY_NORMAL)
>> > > +		return -EINVAL;
>> > > +
>> > > +	/*
>> > > +	 * To be representable by TLR, cycles must be between 2 and
>> > > +	 * priv->max + 2. To enforce this we can reduce the duty
>> > > +	 * cycle, but we may not increase it.
>> > > +	 */
>> > > +	rate = clk_get_rate(priv->clk);
>> > > +	period_cycles = mul_u64_u32_div(state->period, rate, NSEC_PER_SEC);
>> >
>> > cool, I didn't know mul_u64_u32_div.
>>
>> I didn't either. Alas, many useful functions like these have no
>> documentation...
>>
>> >
>> > Hmm, we still have a problem here if
>> >
>> > 	state->period * rate > 1000000000 * U64_MAX.
>>
>> Note that this can only occur with rate > 1GHz (and period = U64_MAX).
>> The highest fmax in the datasheet is 300 MHz (on a very expensive FPGA).
>>
>> Maybe it is more prudent to do
>>
>> 	period = min(state->period, ULONG_MAX * NSEC_PER_SEC)
>
> Together with a check for rate being <= 300 MHz to be safe that's fine.

That's what the ULONG_MAX is for; whatever we get back from
clk_get_rate, it has to fit in a ulong.

>
>> I think a period of 136 years is adequate :) This comparison also has
>> the advantage of being against const values.
>
> *nod*
>
>> > > +static void xilinx_pwm_get_state(struct pwm_chip *chip,
>> > > +				 struct pwm_device *unused,
>> > > +				 struct pwm_state *state)
>> > > +{
>> > > +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
>> > > +	u32 tlr0, tlr1, tcsr0, tcsr1;
>> > > +
>> > > +	regmap_read(priv->map, TLR0, &tlr0);
>> > > +	regmap_read(priv->map, TLR1, &tlr1);
>> > > +	regmap_read(priv->map, TCSR0, &tcsr0);
>> > > +	regmap_read(priv->map, TCSR1, &tcsr1);
>> > > +	state->period = xilinx_timer_get_period(priv, tlr0, tcsr0);
>> >
>> > xilinx_timer_get_period rounds down, this is however wrong for
>> > .get_state().
>>
>> Why is this wrong? I thought get_state should return values which would
>> not be rounded if passed to apply_state.
>
> Consider a PWM that yields a period of ? * $regval ns when a certain
> register is programmed with the value $regval.
>
> Consider the HW is programmed with regval = 317. The exact period is
> 995.8848711879644. If now .get_state() rounds down and returns 995 ns and
> you feed that value back into .apply the new regval (assuming round down
> in .apply(), too) this yields regval = 316. If however .get_state()
> rounds up and returns 996, putting this value back into .apply() you get
> the desired 317.

Will fix for v6, but please document this somewhere :)

--Sean


From sfr at canb.auug.org.au  Tue Aug 17 17:08:19 2021
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Wed, 18 Aug 2021 10:08:19 +1000
Subject: linux-next: manual merge of the i2c tree with the arm-soc tree
Message-ID: <20210818100819.10927d37@canb.auug.org.au>

Hi all,

Today's linux-next merge of the i2c tree got a conflict in:

  include/uapi/linux/virtio_ids.h

between commit:

  46abe13b5e3d ("firmware: arm_scmi: Add virtio transport")

from the arm-soc tree and commit:

  8fb12751ac78 ("i2c: virtio: add a virtio i2c frontend driver")

from the i2c tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc include/uapi/linux/virtio_ids.h
index f74155f6882d,99aa27b100bc..000000000000
--- a/include/uapi/linux/virtio_ids.h
+++ b/include/uapi/linux/virtio_ids.h
@@@ -55,7 -55,7 +55,8 @@@
  #define VIRTIO_ID_FS			26 /* virtio filesystem */
  #define VIRTIO_ID_PMEM			27 /* virtio pmem */
  #define VIRTIO_ID_MAC80211_HWSIM	29 /* virtio mac80211-hwsim */
 +#define VIRTIO_ID_SCMI			32 /* virtio SCMI */
+ #define VIRTIO_ID_I2C_ADAPTER		34 /* virtio i2c adapter */
  #define VIRTIO_ID_BT			40 /* virtio bluetooth */
  
  /*
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/b884f105/attachment-0001.sig>

From robh at kernel.org  Tue Aug 17 17:09:03 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 19:09:03 -0500
Subject: [PATCH 1/9] dt-bindings: media: mtk-vcodec: Add binding for
 MT8195 two venc cores
In-Reply-To: <20210816105934.28265-2-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-2-irui.wang@mediatek.com>
Message-ID: <YRxPn1agQMdJtcpI@robh.at.kernel.org>

On Mon, 16 Aug 2021 18:59:26 +0800, Irui Wang wrote:
> Enable MT8195 two H.264 venc cores, updates vcodec binding document.
> 
> Signed-off-by: Irui Wang <irui.wang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 

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


From seanjc at google.com  Tue Aug 17 17:12:05 2021
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 17 Aug 2021 17:12:05 -0700
Subject: [PATCH 0/5] KVM: rseq: Fix and a test for a KVM+rseq bug
Message-ID: <20210818001210.4073390-1-seanjc@google.com>

Patch 1 fixes a KVM+rseq bug where KVM's handling of TIF_NOTIFY_RESUME,
e.g. for task migration, clears the flag without informing rseq and leads
to stale data in userspace's rseq struct.

Patch 2 is a cleanup to try and make future bugs less likely.  It's also
a baby step towards moving and renaming tracehook_notify_resume() since
it has nothing to do with tracing.  It kills me to not do the move/rename
as part of this series, but having a dedicated series/discussion seems
more appropriate given the sheer number of architectures that call
tracehook_notify_resume() and the lack of an obvious home for the code.

Patch 3 is a fix/cleanup to stop overriding x86's unistd_{32,64}.h when
the include path (intentionally) omits tools' uapi headers.  KVM's
selftests do exactly that so that they can pick up the uapi headers from
the installed kernel headers, and still use various tools/ headers that
mirror kernel code, e.g. linux/types.h.  This allows the new test in
patch 4 to reference __NR_rseq without having to manually define it.

Patch 4 is a regression test for the KVM+rseq bug.

Patch 5 is a cleanup made possible by patch 3.


Sean Christopherson (5):
  KVM: rseq: Update rseq when processing NOTIFY_RESUME on xfer to KVM
    guest
  entry: rseq: Call rseq_handle_notify_resume() in
    tracehook_notify_resume()
  tools: Move x86 syscall number fallbacks to .../uapi/
  KVM: selftests: Add a test for KVM_RUN+rseq to detect task migration
    bugs
  KVM: selftests: Remove __NR_userfaultfd syscall fallback

 arch/arm/kernel/signal.c                      |   1 -
 arch/arm64/kernel/signal.c                    |   1 -
 arch/csky/kernel/signal.c                     |   4 +-
 arch/mips/kernel/signal.c                     |   4 +-
 arch/powerpc/kernel/signal.c                  |   4 +-
 arch/s390/kernel/signal.c                     |   1 -
 include/linux/tracehook.h                     |   2 +
 kernel/entry/common.c                         |   4 +-
 kernel/rseq.c                                 |   4 +-
 .../x86/include/{ => uapi}/asm/unistd_32.h    |   0
 .../x86/include/{ => uapi}/asm/unistd_64.h    |   3 -
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   3 +
 tools/testing/selftests/kvm/rseq_test.c       | 131 ++++++++++++++++++
 14 files changed, 143 insertions(+), 20 deletions(-)
 rename tools/arch/x86/include/{ => uapi}/asm/unistd_32.h (100%)
 rename tools/arch/x86/include/{ => uapi}/asm/unistd_64.h (83%)
 create mode 100644 tools/testing/selftests/kvm/rseq_test.c

-- 
2.33.0.rc1.237.g0d66db33f3-goog



From seanjc at google.com  Tue Aug 17 17:12:06 2021
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 17 Aug 2021 17:12:06 -0700
Subject: [PATCH 1/5] KVM: rseq: Update rseq when processing NOTIFY_RESUME on
 xfer to KVM guest
In-Reply-To: <20210818001210.4073390-1-seanjc@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
Message-ID: <20210818001210.4073390-2-seanjc@google.com>

Invoke rseq's NOTIFY_RESUME handler when processing the flag prior to
transferring to a KVM guest, which is roughly equivalent to an exit to
userspace and processes many of the same pending actions.  While the task
cannot be in an rseq critical section as the KVM path is reachable only
via ioctl(KVM_RUN), the side effects that apply to rseq outside of a
critical section still apply, e.g. the CPU ID needs to be updated if the
task is migrated.

Clearing TIF_NOTIFY_RESUME without informing rseq can lead to segfaults
and other badness in userspace VMMs that use rseq in combination with KVM,
e.g. due to the CPU ID being stale after task migration.

Fixes: 72c3c0fe54a3 ("x86/kvm: Use generic xfer to guest work function")
Reported-by: Peter Foley <pefoley at google.com>
Bisected-by: Doug Evans <dje at google.com>
Cc: Shakeel Butt <shakeelb at google.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: stable at vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 kernel/entry/kvm.c | 4 +++-
 kernel/rseq.c      | 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
index 49972ee99aff..049fd06b4c3d 100644
--- a/kernel/entry/kvm.c
+++ b/kernel/entry/kvm.c
@@ -19,8 +19,10 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
 		if (ti_work & _TIF_NEED_RESCHED)
 			schedule();
 
-		if (ti_work & _TIF_NOTIFY_RESUME)
+		if (ti_work & _TIF_NOTIFY_RESUME) {
 			tracehook_notify_resume(NULL);
+			rseq_handle_notify_resume(NULL, NULL);
+		}
 
 		ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
 		if (ret)
diff --git a/kernel/rseq.c b/kernel/rseq.c
index 35f7bd0fced0..58c79a7918cd 100644
--- a/kernel/rseq.c
+++ b/kernel/rseq.c
@@ -236,7 +236,7 @@ static bool in_rseq_cs(unsigned long ip, struct rseq_cs *rseq_cs)
 
 static int rseq_ip_fixup(struct pt_regs *regs)
 {
-	unsigned long ip = instruction_pointer(regs);
+	unsigned long ip = regs ? instruction_pointer(regs) : 0;
 	struct task_struct *t = current;
 	struct rseq_cs rseq_cs;
 	int ret;
@@ -250,7 +250,7 @@ static int rseq_ip_fixup(struct pt_regs *regs)
 	 * If not nested over a rseq critical section, restart is useless.
 	 * Clear the rseq_cs pointer and return.
 	 */
-	if (!in_rseq_cs(ip, &rseq_cs))
+	if (!regs || !in_rseq_cs(ip, &rseq_cs))
 		return clear_rseq_cs(t);
 	ret = rseq_need_restart(t, rseq_cs.flags);
 	if (ret <= 0)
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From seanjc at google.com  Tue Aug 17 17:12:07 2021
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 17 Aug 2021 17:12:07 -0700
Subject: [PATCH 2/5] entry: rseq: Call rseq_handle_notify_resume() in
 tracehook_notify_resume()
In-Reply-To: <20210818001210.4073390-1-seanjc@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
Message-ID: <20210818001210.4073390-3-seanjc@google.com>

Invoke rseq_handle_notify_resume() from tracehook_notify_resume() now
that the two function are always called back-to-back by architectures
that have rseq.  The rseq helper is stubbed out for architectures that
don't support rseq, i.e. this is a nop across the board.

Note, tracehook_notify_resume() is horribly named and arguably does not
belong in tracehook.h as literally every line of code in it has nothing
to do with tracing.  But, that's been true since commit a42c6ded827d
("move key_repace_session_keyring() into tracehook_notify_resume()")
first usurped tracehook_notify_resume() back in 2012.  Punt cleaning that
mess up to future patches.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm/kernel/signal.c     | 1 -
 arch/arm64/kernel/signal.c   | 1 -
 arch/csky/kernel/signal.c    | 4 +---
 arch/mips/kernel/signal.c    | 4 +---
 arch/powerpc/kernel/signal.c | 4 +---
 arch/s390/kernel/signal.c    | 1 -
 include/linux/tracehook.h    | 2 ++
 kernel/entry/common.c        | 4 +---
 kernel/entry/kvm.c           | 4 +---
 9 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index a3a38d0a4c85..9df68d139965 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -670,7 +670,6 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 				uprobe_notify_resume(regs);
 			} else {
 				tracehook_notify_resume(regs);
-				rseq_handle_notify_resume(NULL, regs);
 			}
 		}
 		local_irq_disable();
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 23036334f4dc..22b55db13da6 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -951,7 +951,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 
 			if (thread_flags & _TIF_NOTIFY_RESUME) {
 				tracehook_notify_resume(regs);
-				rseq_handle_notify_resume(NULL, regs);
 
 				/*
 				 * If we reschedule after checking the affinity
diff --git a/arch/csky/kernel/signal.c b/arch/csky/kernel/signal.c
index 312f046d452d..bc4238b9f709 100644
--- a/arch/csky/kernel/signal.c
+++ b/arch/csky/kernel/signal.c
@@ -260,8 +260,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
 		do_signal(regs);
 
-	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+	if (thread_info_flags & _TIF_NOTIFY_RESUME)
 		tracehook_notify_resume(regs);
-		rseq_handle_notify_resume(NULL, regs);
-	}
 }
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index f1e985109da0..c9b2a75563e1 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -906,10 +906,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
 		do_signal(regs);
 
-	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+	if (thread_info_flags & _TIF_NOTIFY_RESUME)
 		tracehook_notify_resume(regs);
-		rseq_handle_notify_resume(NULL, regs);
-	}
 
 	user_enter();
 }
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index e600764a926c..b93b87df499d 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -293,10 +293,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
 		do_signal(current);
 	}
 
-	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+	if (thread_info_flags & _TIF_NOTIFY_RESUME)
 		tracehook_notify_resume(regs);
-		rseq_handle_notify_resume(NULL, regs);
-	}
 }
 
 static unsigned long get_tm_stackpointer(struct task_struct *tsk)
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 78ef53b29958..b307db26bf2d 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -537,5 +537,4 @@ void arch_do_signal_or_restart(struct pt_regs *regs, bool has_signal)
 void do_notify_resume(struct pt_regs *regs)
 {
 	tracehook_notify_resume(regs);
-	rseq_handle_notify_resume(NULL, regs);
 }
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index 3e80c4bc66f7..2564b7434b4d 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -197,6 +197,8 @@ static inline void tracehook_notify_resume(struct pt_regs *regs)
 
 	mem_cgroup_handle_over_high();
 	blkcg_maybe_throttle_current();
+
+	rseq_handle_notify_resume(NULL, regs);
 }
 
 /*
diff --git a/kernel/entry/common.c b/kernel/entry/common.c
index bf16395b9e13..d5a61d565ad5 100644
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -171,10 +171,8 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 		if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
 			handle_signal_work(regs, ti_work);
 
-		if (ti_work & _TIF_NOTIFY_RESUME) {
+		if (ti_work & _TIF_NOTIFY_RESUME)
 			tracehook_notify_resume(regs);
-			rseq_handle_notify_resume(NULL, regs);
-		}
 
 		/* Architecture specific TIF work */
 		arch_exit_to_user_mode_work(regs, ti_work);
diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
index 049fd06b4c3d..49972ee99aff 100644
--- a/kernel/entry/kvm.c
+++ b/kernel/entry/kvm.c
@@ -19,10 +19,8 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
 		if (ti_work & _TIF_NEED_RESCHED)
 			schedule();
 
-		if (ti_work & _TIF_NOTIFY_RESUME) {
+		if (ti_work & _TIF_NOTIFY_RESUME)
 			tracehook_notify_resume(NULL);
-			rseq_handle_notify_resume(NULL, NULL);
-		}
 
 		ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
 		if (ret)
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From seanjc at google.com  Tue Aug 17 17:12:08 2021
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 17 Aug 2021 17:12:08 -0700
Subject: [PATCH 3/5] tools: Move x86 syscall number fallbacks to .../uapi/
In-Reply-To: <20210818001210.4073390-1-seanjc@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
Message-ID: <20210818001210.4073390-4-seanjc@google.com>

Move unistd_{32,64}.h from x86/include/asm to x86/include/uapi/asm so
that tools/selftests that install kernel headers, e.g. KVM selftests, can
include non-uapi tools headers, e.g. to get 'struct list_head', without
effectively overriding the installed non-tool uapi headers.

Swapping KVM's search order, e.g. to search the kernel headers before
tool headers, is not a viable option as doing results in linux/type.h and
other core headers getting pulled from the kernel headers, which do not
have the kernel-internal typedefs that are used through tools, including
many files outside of selftests/kvm's control.

Prior to commit cec07f53c398 ("perf tools: Move syscall number fallbacks
from perf-sys.h to tools/arch/x86/include/asm/"), the handcoded numbers
were actual fallbacks, i.e. overriding unistd_{32,64}.h from the kernel
headers was unintentional.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/arch/x86/include/{ => uapi}/asm/unistd_32.h | 0
 tools/arch/x86/include/{ => uapi}/asm/unistd_64.h | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename tools/arch/x86/include/{ => uapi}/asm/unistd_32.h (100%)
 rename tools/arch/x86/include/{ => uapi}/asm/unistd_64.h (100%)

diff --git a/tools/arch/x86/include/asm/unistd_32.h b/tools/arch/x86/include/uapi/asm/unistd_32.h
similarity index 100%
rename from tools/arch/x86/include/asm/unistd_32.h
rename to tools/arch/x86/include/uapi/asm/unistd_32.h
diff --git a/tools/arch/x86/include/asm/unistd_64.h b/tools/arch/x86/include/uapi/asm/unistd_64.h
similarity index 100%
rename from tools/arch/x86/include/asm/unistd_64.h
rename to tools/arch/x86/include/uapi/asm/unistd_64.h
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From seanjc at google.com  Tue Aug 17 17:12:09 2021
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 17 Aug 2021 17:12:09 -0700
Subject: [PATCH 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to detect
 task migration bugs
In-Reply-To: <20210818001210.4073390-1-seanjc@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
Message-ID: <20210818001210.4073390-5-seanjc@google.com>

Add a test to verify an rseq's CPU ID is updated correctly if the task is
migrated while the kernel is handling KVM_RUN.  This is a regression test
for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
without updating rseq, leading to a stale CPU ID and other badness.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/.gitignore  |   1 +
 tools/testing/selftests/kvm/Makefile    |   3 +
 tools/testing/selftests/kvm/rseq_test.c | 131 ++++++++++++++++++++++++
 3 files changed, 135 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/rseq_test.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 0709af0144c8..6d031ff6b68e 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -47,6 +47,7 @@
 /kvm_page_table_test
 /memslot_modification_stress_test
 /memslot_perf_test
+/rseq_test
 /set_memory_region_test
 /steal_time
 /kvm_binary_stats_test
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 5832f510a16c..0756e79cb513 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -80,6 +80,7 @@ TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
 TEST_GEN_PROGS_x86_64 += kvm_page_table_test
 TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
 TEST_GEN_PROGS_x86_64 += memslot_perf_test
+TEST_GEN_PROGS_x86_64 += rseq_test
 TEST_GEN_PROGS_x86_64 += set_memory_region_test
 TEST_GEN_PROGS_x86_64 += steal_time
 TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
@@ -92,6 +93,7 @@ TEST_GEN_PROGS_aarch64 += dirty_log_test
 TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
 TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
 TEST_GEN_PROGS_aarch64 += kvm_page_table_test
+TEST_GEN_PROGS_aarch64 += rseq_test
 TEST_GEN_PROGS_aarch64 += set_memory_region_test
 TEST_GEN_PROGS_aarch64 += steal_time
 TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
@@ -103,6 +105,7 @@ TEST_GEN_PROGS_s390x += demand_paging_test
 TEST_GEN_PROGS_s390x += dirty_log_test
 TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
 TEST_GEN_PROGS_s390x += kvm_page_table_test
+TEST_GEN_PROGS_s390x += rseq_test
 TEST_GEN_PROGS_s390x += set_memory_region_test
 TEST_GEN_PROGS_s390x += kvm_binary_stats_test
 
diff --git a/tools/testing/selftests/kvm/rseq_test.c b/tools/testing/selftests/kvm/rseq_test.c
new file mode 100644
index 000000000000..90ed535eded7
--- /dev/null
+++ b/tools/testing/selftests/kvm/rseq_test.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#define _GNU_SOURCE /* for program_invocation_short_name */
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <syscall.h>
+#include <sys/ioctl.h>
+#include <linux/rseq.h>
+#include <linux/unistd.h>
+
+#include "kvm_util.h"
+#include "processor.h"
+#include "test_util.h"
+
+#define VCPU_ID 0
+
+static __thread volatile struct rseq __rseq = {
+	.cpu_id = RSEQ_CPU_ID_UNINITIALIZED,
+};
+
+#define RSEQ_SIG 0xdeadbeef
+
+static pthread_t migration_thread;
+static cpu_set_t possible_mask;
+static bool done;
+
+static void guest_code(void)
+{
+	for (;;)
+		GUEST_SYNC(0);
+}
+
+static void sys_rseq(int flags)
+{
+	int r;
+
+	r = syscall(__NR_rseq, &__rseq, sizeof(__rseq), flags, RSEQ_SIG);
+	TEST_ASSERT(!r, "rseq failed, errno = %d (%s)", errno, strerror(errno));
+}
+
+static void *migration_worker(void *ign)
+{
+	cpu_set_t allowed_mask;
+	int r, i, nr_cpus, cpu;
+
+	CPU_ZERO(&allowed_mask);
+
+	nr_cpus = CPU_COUNT(&possible_mask);
+
+	for (i = 0; i < 20000; i++) {
+		cpu = i % nr_cpus;
+		if (!CPU_ISSET(cpu, &possible_mask))
+			continue;
+
+		CPU_SET(cpu, &allowed_mask);
+
+		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
+		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)", errno,
+			    strerror(errno));
+
+		CPU_CLR(cpu, &allowed_mask);
+
+		usleep(10);
+	}
+	done = true;
+	return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+	struct kvm_vm *vm;
+	u32 cpu, rseq_cpu;
+	int r;
+
+	/* Tell stdout not to buffer its content */
+	setbuf(stdout, NULL);
+
+	r = sched_getaffinity(0, sizeof(possible_mask), &possible_mask);
+	TEST_ASSERT(!r, "sched_getaffinity failed, errno = %d (%s)", errno,
+		    strerror(errno));
+
+	if (CPU_COUNT(&possible_mask) < 2) {
+		print_skip("Only one CPU, task migration not possible\n");
+		exit(KSFT_SKIP);
+	}
+
+	sys_rseq(0);
+
+	/*
+	 * Create and run a dummy VM that immediately exits to userspace via
+	 * GUEST_SYNC, while concurrently migrating the process by setting its
+	 * CPU affinity.
+	 */
+	vm = vm_create_default(VCPU_ID, 0, guest_code);
+
+	pthread_create(&migration_thread, NULL, migration_worker, 0);
+
+	while (!done) {
+		vcpu_run(vm, VCPU_ID);
+		TEST_ASSERT(get_ucall(vm, VCPU_ID, NULL) == UCALL_SYNC,
+			    "Guest failed?");
+
+		cpu = sched_getcpu();
+		rseq_cpu = READ_ONCE(__rseq.cpu_id);
+
+		/*
+		 * Verify rseq's CPU matches sched's CPU, and that sched's CPU
+		 * is stable.  This doesn't handle the case where the task is
+		 * migrated between sched_getcpu() and reading rseq, and again
+		 * between reading rseq and sched_getcpu(), but in practice no
+		 * false positives have been observed, while on the other hand
+		 * blocking migration while this thread reads CPUs messes with
+		 * the timing and prevents hitting failures on a buggy kernel.
+		 */
+		TEST_ASSERT(rseq_cpu == cpu || cpu != sched_getcpu(),
+			    "rseq CPU = %d, sched CPU = %d\n", rseq_cpu, cpu);
+	}
+
+	pthread_join(migration_thread, NULL);
+
+	kvm_vm_free(vm);
+
+	sys_rseq(RSEQ_FLAG_UNREGISTER);
+
+	return 0;
+}
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From seanjc at google.com  Tue Aug 17 17:12:10 2021
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 17 Aug 2021 17:12:10 -0700
Subject: [PATCH 5/5] KVM: selftests: Remove __NR_userfaultfd syscall fallback
In-Reply-To: <20210818001210.4073390-1-seanjc@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
Message-ID: <20210818001210.4073390-6-seanjc@google.com>

Revert the __NR_userfaultfd syscall fallback added for KVM selftests now
that x86's unistd_{32,63}.h overrides are under uapi/ and thus not in
KVM sefltests' search path, i.e. now that KVM gets x86 syscall numbers
from the installed kernel headers.

No functional change intended.

Cc: Ben Gardon <bgardon at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/arch/x86/include/uapi/asm/unistd_64.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/arch/x86/include/uapi/asm/unistd_64.h b/tools/arch/x86/include/uapi/asm/unistd_64.h
index 4205ed4158bf..cb52a3a8b8fc 100644
--- a/tools/arch/x86/include/uapi/asm/unistd_64.h
+++ b/tools/arch/x86/include/uapi/asm/unistd_64.h
@@ -1,7 +1,4 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __NR_userfaultfd
-#define __NR_userfaultfd 282
-#endif
 #ifndef __NR_perf_event_open
 # define __NR_perf_event_open 298
 #endif
-- 
2.33.0.rc1.237.g0d66db33f3-goog



From robh at kernel.org  Tue Aug 17 17:13:07 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 19:13:07 -0500
Subject: [PATCH v5] memblock: make memblock_find_in_range method private
In-Reply-To: <20210816122622.30279-1-rppt@kernel.org>
References: <20210816122622.30279-1-rppt@kernel.org>
Message-ID: <YRxQk0Cjj5yzmvBA@robh.at.kernel.org>

On Mon, 16 Aug 2021 15:26:22 +0300, Mike Rapoport wrote:
> From: Mike Rapoport <rppt at linux.ibm.com>
> 
> There are a lot of uses of memblock_find_in_range() along with
> memblock_reserve() from the times memblock allocation APIs did not exist.
> 
> memblock_find_in_range() is the very core of memblock allocations, so any
> future changes to its internal behaviour would mandate updates of all the
> users outside memblock.
> 
> Replace the calls to memblock_find_in_range() with an equivalent calls to
> memblock_phys_alloc() and memblock_phys_alloc_range() and make
> memblock_find_in_range() private method of memblock.
> 
> This simplifies the callers, ensures that (unlikely) errors in
> memblock_reserve() are handled and improves maintainability of
> memblock_find_in_range().
> 
> Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
> Acked-by: Kirill A. Shutemov <kirill.shtuemov at linux.intel.com>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>	# ACPI
> Acked-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Acked-by: Nick Kossifidis <mick at ics.forth.gr>			# riscv
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>		# arm64
> ---
> v5:
> * restore the original behaviour on x86 with addition of more elaborate
>   comment; I will address the issue in memory_map_top_down() in a separate
>   series.
> 
> v4: https://lore.kernel.org/lkml/20210812065907.20046-1-rppt at kernel.org
> * Add patch that prevents the crashes reported by Guenter Roeck on x86/i386
>   on QEMU with 256M or 512M of memory and EFI boot enabled.
> * Add Acked-by and Reviewed-by, thanks everybidy!
> 
> v3: https://lore.kernel.org/lkml/20210803064218.6611-1-rppt at kernel.org
> * simplify check for exact crash kerenl allocation on arm, per Rob
> * make crash_max unsigned long long on arm64, per Rob
> 
> v2: https://lore.kernel.org/lkml/20210802063737.22733-1-rppt at kernel.org
> * don't change error message in arm::reserve_crashkernel(), per Russell
> 
> v1: https://lore.kernel.org/lkml/20210730104039.7047-1-rppt at kernel.org
> 
> 
>  arch/arm/kernel/setup.c           | 20 +++++---------
>  arch/arm64/kvm/hyp/reserved_mem.c |  9 +++----
>  arch/arm64/mm/init.c              | 36 ++++++++-----------------
>  arch/mips/kernel/setup.c          | 14 +++++-----
>  arch/riscv/mm/init.c              | 44 ++++++++++---------------------
>  arch/s390/kernel/setup.c          | 10 ++++---
>  arch/x86/kernel/aperture_64.c     |  5 ++--
>  arch/x86/mm/init.c                | 23 ++++++++++------
>  arch/x86/mm/numa.c                |  5 ++--
>  arch/x86/mm/numa_emulation.c      |  5 ++--
>  arch/x86/realmode/init.c          |  2 +-
>  drivers/acpi/tables.c             |  5 ++--
>  drivers/base/arch_numa.c          |  5 +---
>  drivers/of/of_reserved_mem.c      | 12 ++++++---
>  include/linux/memblock.h          |  2 --
>  mm/memblock.c                     |  2 +-
>  16 files changed, 81 insertions(+), 118 deletions(-)
> 

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


From joel at jms.id.au  Tue Aug 17 18:05:34 2021
From: joel at jms.id.au (Joel Stanley)
Date: Wed, 18 Aug 2021 10:35:34 +0930
Subject: [PATCH] soc: aspeed: socinfo: Add AST2625 variant
Message-ID: <20210818010534.2508122-1-joel@jms.id.au>

Add AST26XX series AST2625-A3 SOC ID, taken from the vendor u-boot SDK:

 arch/arm/mach-aspeed/ast2600/scu_info.c
 +       SOC_ID("AST2625-A3", 0x0503040305030403),

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
Dylan, can you please review this for me?

 drivers/soc/aspeed/aspeed-socinfo.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/aspeed/aspeed-socinfo.c b/drivers/soc/aspeed/aspeed-socinfo.c
index e3215f826d17..1ca140356a08 100644
--- a/drivers/soc/aspeed/aspeed-socinfo.c
+++ b/drivers/soc/aspeed/aspeed-socinfo.c
@@ -26,6 +26,7 @@ static struct {
 	{ "AST2600", 0x05000303 },
 	{ "AST2620", 0x05010203 },
 	{ "AST2605", 0x05030103 },
+	{ "AST2625", 0x05030403 },
 };
 
 static const char *siliconid_to_name(u32 siliconid)
-- 
2.32.0



From robh at kernel.org  Tue Aug 17 18:07:07 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 20:07:07 -0500
Subject: [PATCH 1/3] dt-bindings: thermal: Add binding document for
 mt8195 thermal controller
In-Reply-To: <20210816164307.557315-2-abailon@baylibre.com>
References: <20210816164307.557315-1-abailon@baylibre.com>
 <20210816164307.557315-2-abailon@baylibre.com>
Message-ID: <YRxdO9upQxib5Tcb@robh.at.kernel.org>

On Mon, Aug 16, 2021 at 06:43:05PM +0200, Alexandre Bailon wrote:
> This patch adds binding document for mt8195 thermal controller.
> 
> Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
> ---
>  .../devicetree/bindings/thermal/mediatek-thermal-lvts.yaml  | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal-lvts.yaml b/Documentation/devicetree/bindings/thermal/mediatek-thermal-lvts.yaml
> index 69ffe7b14c212..2e1ae00d4fd18 100644
> --- a/Documentation/devicetree/bindings/thermal/mediatek-thermal-lvts.yaml
> +++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal-lvts.yaml
> @@ -12,7 +12,11 @@ maintainers:
>  
>  properties:
>    compatible:
> -    const: mediatek,mt6873-lvts
> +    oneOf:
> +      - items:
> +          - enum:
> +              - mediatek,mt6873-lvts
> +              - mediatek,mt8195-lvts

You don't need 'oneOf' when only one clause. Just changing the const to 
enum is enough. 

Rob


From robh at kernel.org  Tue Aug 17 18:20:05 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 20:20:05 -0500
Subject: [v2,01/12] dt-bindings: clock: mediatek: document clk bindings
 for mediatek mt7986 SoC
In-Reply-To: <20210817074557.30953-2-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
 <20210817074557.30953-2-sam.shih@mediatek.com>
Message-ID: <YRxgRZ5VyXSPqY42@robh.at.kernel.org>

On Tue, 17 Aug 2021 15:45:46 +0800, Sam Shih wrote:
> This patch adds the binding documentation for topckgen, apmixedsys,
> infracfg, and ethernet subsystem clocks.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> ---
> v2: remove compatiable string 'mt7986-sgmiisys'
> 
> ---
>  .../devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt    | 1 +
>  .../devicetree/bindings/arm/mediatek/mediatek,ethsys.txt        | 1 +
>  .../devicetree/bindings/arm/mediatek/mediatek,infracfg.txt      | 1 +
>  .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt      | 2 ++
>  .../devicetree/bindings/arm/mediatek/mediatek,topckgen.txt      | 1 +
>  5 files changed, 6 insertions(+)
> 

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


From robh at kernel.org  Tue Aug 17 18:20:30 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 17 Aug 2021 20:20:30 -0500
Subject: [v2,02/12] clk: mediatek: add mt7986 clock IDs
In-Reply-To: <20210817074557.30953-3-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
 <20210817074557.30953-3-sam.shih@mediatek.com>
Message-ID: <YRxgXso7qQcAqg6+@robh.at.kernel.org>

On Tue, 17 Aug 2021 15:45:47 +0800, Sam Shih wrote:
> Add MT7986 clock dt-bindings, include topckgen, apmixedsys,
> infracfg, and ethernet subsystem clocks.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> 
> ---
> v2: changed to dual licience
>     applied the comment suggested by reviewers:
>     - removed 1:1 factor clock
>     - renamed factor clock for easier to understand
> 
> ---
>  include/dt-bindings/clock/mt7986-clk.h | 169 +++++++++++++++++++++++++
>  1 file changed, 169 insertions(+)
>  create mode 100644 include/dt-bindings/clock/mt7986-clk.h
> 

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


From thunder.leizhen at huawei.com  Tue Aug 17 19:28:09 2021
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Wed, 18 Aug 2021 10:28:09 +0800
Subject: [PATCH] iommu/arm-smmu-v3: Simplify useless instructions in
 arm_smmu_cmdq_build_cmd()
In-Reply-To: <6fea9ce0-7b8d-bd46-6b85-f3f9ba3ddd48@arm.com>
References: <20210817113450.2026-1-thunder.leizhen@huawei.com>
 <6fea9ce0-7b8d-bd46-6b85-f3f9ba3ddd48@arm.com>
Message-ID: <54b94259-628a-1763-0f1e-e2e7c2b2a297@huawei.com>



On 2021/8/17 21:23, Robin Murphy wrote:
> On 2021-08-17 12:34, Zhen Lei wrote:
>> Although the parameter 'cmd' is always passed by a local array variable,
>> and only this function modifies it, the compiler does not know this. The
>> compiler almost always reads the value of cmd[i] from memory rather than
>> directly using the value cached in the register. This generates many
>> useless instruction operations and affects the performance to some extent.
> 
> Which compiler? GCC 4.9 does not make the same codegen decisions that GCC 10 does; Clang is different again. There are also various config options which affect a compiler's inlining/optimisation choices either directly or indirectly.

gcc version 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05)

In addition, yesterday morning I also purposely compiled a compiler with the latest
GCC source code. The result is the same.

gcc version 11.2.0 (GCC)

> 
> If it's something that newer compilers can get right anyway, then micro-optimising just for older ones might warrant a bit more justification.
> 
>> To guide the compiler for proper optimization, 'cmd' is defined as a local
>> array variable, marked as register, and copied to the output parameter at
>> a time when the function is returned.
>>
>> The optimization effect can be viewed by running the "size arm-smmu-v3.o"
>> command.
>>
>> Before:
>> ??? text??? data???? bss???? dec???? hex
>> ?? 27602??? 1348????? 56?? 29006??? 714e
>>
>> After:
>> ??? text??? data???? bss???? dec???? hex
>> ?? 27402??? 1348????? 56?? 28806??? 7086
>>
>> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
>> ---
>> ? drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 +++++++++++++++---
>> ? 1 file changed, 15 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index d76bbbde558b776..50a9db5bac466c7 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -233,11 +233,19 @@ static int queue_remove_raw(struct arm_smmu_queue *q, u64 *ent)
>> ????? return 0;
>> ? }
>> ? +#define arm_smmu_cmdq_copy_cmd(dst, src)??? \
>> +??? do {??????????????????? \
>> +??????? dst[0] = src[0];??????? \
>> +??????? dst[1] = src[1];??????? \
>> +??? } while (0)
>> +
>> ? /* High-level queue accessors */
>> -static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
>> +static int arm_smmu_cmdq_build_cmd(u64 *out_cmd, struct arm_smmu_cmdq_ent *ent)
>> ? {
>> -??? memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
>> -??? cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
>> +??? register u64 cmd[CMDQ_ENT_DWORDS];
>> +
>> +??? cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
>> +??? cmd[1] = 0;
>> ? ????? switch (ent->opcode) {
>> ????? case CMDQ_OP_TLBI_EL2_ALL:
>> @@ -309,6 +317,7 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
>> ????????? case PRI_RESP_SUCC:
>> ????????????? break;
>> ????????? default:
>> +??????????? arm_smmu_cmdq_copy_cmd(out_cmd, cmd);
> 
> Why bother writing back a partial command when we're telling the caller it's invalid anyway?

Some callers do not check the return value of arm_smmu_cmdq_build_cmd().
In particular, the arm_smmu_cmdq_batch_add has no judgment. Yes, I should
add judgment there.

> 
>> ????????????? return -EINVAL;
>> ????????? }
>> ????????? cmd[1] |= FIELD_PREP(CMDQ_PRI_1_RESP, ent->pri.resp);
>> @@ -329,9 +338,12 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
>> ????????? cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIATTR, ARM_SMMU_MEMATTR_OIWB);
>> ????????? break;
>> ????? default:
>> +??????? arm_smmu_cmdq_copy_cmd(out_cmd, cmd);
> 
> Ditto.
> 
>> ????????? return -ENOENT;
>> ????? }
>> ? +??? arm_smmu_cmdq_copy_cmd(out_cmd, cmd);
> 
> ...and then it would be simpler to open-code the assignment here.

Right, I'll modify it in v2. I also don't like the addition of arm_smmu_cmdq_copy_cmd().

> 
> I guess if you're really concerned with avoiding temporary commands being written back to the stack and reloaded, it might be worth experimenting with wrapping them in a struct which can be passed around by value - AAPCS64 allows passing a 16-byte composite type purely in registers.

'out_cmd' is an output parameter. Use 16-byte composite type need to modify
many functions, this may not be good..

> 
> Robin.
> 
>> +
>> ????? return 0;
>> ? }
>> ?
> .
> 


From jason-jh.lin at mediatek.com  Tue Aug 17 19:40:33 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 18 Aug 2021 10:40:33 +0800
Subject: [PATCH v5 1/5] dt-bindings: mailbox: add definition for mt8195
In-Reply-To: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
References: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
Message-ID: <20210818024037.11396-2-jason-jh.lin@mediatek.com>

Add definition of compatible and dt-binding header for mt8195.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 Documentation/devicetree/bindings/mailbox/mtk-gce.txt | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 7771ecaac586..a036fb5407bb 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,8 +9,8 @@ CMDQ driver uses mailbox framework for communication. Please refer to
 mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
-- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce" or
-  "mediatek,mt6779-gce".
+- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce",
+  "mediatek,mt6779-gce" or "mediatek,mt8195-gce".
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -36,8 +36,9 @@ Optional properties for a client device:
   size: the total size of register address that GCE can access.
 
 Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h',
-'dt-binding/gce/mt8183-gce.h' or 'dt-bindings/gce/mt6779-gce.h'. Such as
-sub-system ids, thread priority, event ids.
+'dt-binding/gce/mt8183-gce.h', 'dt-bindings/gce/mt6779-gce.h' or
+'dt-binding/gce/mt8195-gce.h'. Such as sub-system ids, thread priority,
+event ids.
 
 Example:
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 17 19:40:37 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 18 Aug 2021 10:40:37 +0800
Subject: [PATCH v5 5/5] mailbox: cmdq: add multi-gce clocks support for mt8195
In-Reply-To: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
References: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
Message-ID: <20210818024037.11396-6-jason-jh.lin@mediatek.com>

For the design of GCE hardware event signal transportation,
evnet rx will send the event signal to all GCE event merges
after receiving the event signal from the other hardware.

Because GCE event merges need to response to event rx, their
clocks must be enabled at that time.

To make sure all the gce clock is enabled while receiving the
hardware event, each cmdq mailbox should enable or disable
the others gce clk at the same time.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 90 +++++++++++++++++++++++-------
 1 file changed, 70 insertions(+), 20 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 205bde4ed6e6..3839faab68ca 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -19,6 +19,7 @@
 
 #define CMDQ_OP_CODE_MASK		(0xff << CMDQ_OP_CODE_SHIFT)
 #define CMDQ_NUM_CMD(t)			(t->cmd_buf_size / CMDQ_INST_SIZE)
+#define CMDQ_GCE_NUM_MAX		(2)
 
 #define CMDQ_CURR_IRQ_STATUS		0x10
 #define CMDQ_SYNC_TOKEN_UPDATE		0x68
@@ -73,14 +74,16 @@ struct cmdq {
 	u32			thread_nr;
 	u32			irq_mask;
 	struct cmdq_thread	*thread;
-	struct clk		*clock;
+	struct clk_bulk_data	clocks[CMDQ_GCE_NUM_MAX];
 	bool			suspended;
 	u8			shift_pa;
+	u32			gce_num;
 };
 
 struct gce_plat {
 	u32 thread_nr;
 	u8 shift;
+	u32 gce_num;
 };
 
 u8 cmdq_get_shift_pa(struct mbox_chan *chan)
@@ -120,11 +123,13 @@ static void cmdq_init(struct cmdq *cmdq)
 {
 	int i;
 
-	WARN_ON(clk_enable(cmdq->clock) < 0);
+	WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
+
 	writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
 	for (i = 0; i <= CMDQ_MAX_EVENT; i++)
 		writel(i, cmdq->base + CMDQ_SYNC_TOKEN_UPDATE);
-	clk_disable(cmdq->clock);
+
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 }
 
 static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
@@ -262,7 +267,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
 
 	if (list_empty(&thread->task_busy_list)) {
 		cmdq_thread_disable(cmdq, thread);
-		clk_disable(cmdq->clock);
+		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 	}
 }
 
@@ -307,7 +312,7 @@ static int cmdq_suspend(struct device *dev)
 	if (task_running)
 		dev_warn(dev, "exist running task(s) in suspend\n");
 
-	clk_unprepare(cmdq->clock);
+	clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
 
 	return 0;
 }
@@ -316,7 +321,7 @@ static int cmdq_resume(struct device *dev)
 {
 	struct cmdq *cmdq = dev_get_drvdata(dev);
 
-	WARN_ON(clk_prepare(cmdq->clock) < 0);
+	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
 	cmdq->suspended = false;
 	return 0;
 }
@@ -325,8 +330,7 @@ static int cmdq_remove(struct platform_device *pdev)
 {
 	struct cmdq *cmdq = platform_get_drvdata(pdev);
 
-	clk_unprepare(cmdq->clock);
-
+	clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
 	return 0;
 }
 
@@ -352,7 +356,8 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 	task->pkt = pkt;
 
 	if (list_empty(&thread->task_busy_list)) {
-		WARN_ON(clk_enable(cmdq->clock) < 0);
+		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
+
 		/*
 		 * The thread reset will clear thread related register to 0,
 		 * including pc, end, priority, irq, suspend and enable. Thus
@@ -424,7 +429,8 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 	}
 
 	cmdq_thread_disable(cmdq, thread);
-	clk_disable(cmdq->clock);
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+
 done:
 	/*
 	 * The thread->task_busy_list empty means thread already disable. The
@@ -469,7 +475,7 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
 
 	cmdq_thread_resume(thread);
 	cmdq_thread_disable(cmdq, thread);
-	clk_disable(cmdq->clock);
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 
 out:
 	spin_unlock_irqrestore(&thread->chan->lock, flags);
@@ -518,6 +524,10 @@ static int cmdq_probe(struct platform_device *pdev)
 	struct cmdq *cmdq;
 	int err, i;
 	struct gce_plat *plat_data;
+	struct device_node *phandle = dev->of_node;
+	struct device_node *node;
+	int alias_id = 0;
+	char clk_name[4] = "gce";
 
 	cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
 	if (!cmdq)
@@ -540,6 +550,7 @@ static int cmdq_probe(struct platform_device *pdev)
 
 	cmdq->thread_nr = plat_data->thread_nr;
 	cmdq->shift_pa = plat_data->shift;
+	cmdq->gce_num = plat_data->gce_num;
 	cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0);
 	err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
 			       "mtk_cmdq", cmdq);
@@ -551,10 +562,28 @@ static int cmdq_probe(struct platform_device *pdev)
 	dev_dbg(dev, "cmdq device: addr:0x%p, va:0x%p, irq:%d\n",
 		dev, cmdq->base, cmdq->irq);
 
-	cmdq->clock = devm_clk_get(dev, "gce");
-	if (IS_ERR(cmdq->clock)) {
-		dev_err(dev, "failed to get gce clk\n");
-		return PTR_ERR(cmdq->clock);
+	if (cmdq->gce_num > 1) {
+		for_each_child_of_node(phandle->parent, node) {
+			char clk_id[8];
+
+			alias_id = of_alias_get_id(node, clk_name);
+			if (alias_id < cmdq->gce_num) {
+				snprintf(clk_id, sizeof(clk_id), "%s%d", clk_name, alias_id);
+				cmdq->clocks[alias_id].id = clk_id;
+				cmdq->clocks[alias_id].clk = of_clk_get(node, 0);
+				if (IS_ERR(cmdq->clocks[alias_id].clk)) {
+					dev_err(dev, "failed to get gce clk: %d\n", alias_id);
+					return PTR_ERR(cmdq->clocks[alias_id].clk);
+				}
+			}
+		}
+	} else {
+		cmdq->clocks[alias_id].id = clk_name;
+		cmdq->clocks[alias_id].clk = devm_clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(cmdq->clocks[alias_id].clk)) {
+			dev_err(dev, "failed to get gce clk\n");
+			return PTR_ERR(cmdq->clocks[alias_id].clk);
+		}
 	}
 
 	cmdq->mbox.dev = dev;
@@ -590,7 +619,8 @@ static int cmdq_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, cmdq);
-	WARN_ON(clk_prepare(cmdq->clock) < 0);
+
+	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
 
 	cmdq_init(cmdq);
 
@@ -602,15 +632,35 @@ static const struct dev_pm_ops cmdq_pm_ops = {
 	.resume = cmdq_resume,
 };
 
-static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
-static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
-static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
+static const struct gce_plat gce_plat_v2 = {
+	.thread_nr = 16,
+	.shift = 0,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v3 = {
+	.thread_nr = 24,
+	.shift = 0,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v4 = {
+	.thread_nr = 24,
+	.shift = 3,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v5 = {
+	.thread_nr = 24,
+	.shift = 3,
+	.gce_num = 2
+};
 
 static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
 	{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
 	{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
-	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v4},
+	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v5},
 	{}
 };
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 17 19:40:36 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 18 Aug 2021 10:40:36 +0800
Subject: [PATCH v5 4/5] mailbox: cmdq: add mediatek mailbox support for mt8195
In-Reply-To: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
References: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
Message-ID: <20210818024037.11396-5-jason-jh.lin@mediatek.com>

Add mt8195 compatible name in the driver data of cmdq mailbox driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 67a42b514429..205bde4ed6e6 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -610,6 +610,7 @@ static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
 	{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
 	{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
+	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v4},
 	{}
 };
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 17 19:40:32 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 18 Aug 2021 10:40:32 +0800
Subject: [PATCH v5 0/5] 
Message-ID: <20210818024037.11396-1-jason-jh.lin@mediatek.com>

Change in v5:
- rebase on kernel-5.14-rc1
- remove unused varriable in mtk-cmdq-mailbox.c

Change in v4:
- change clk array to bulk_clk_data array

Change in v3:
- fix #mbox-cless number in dts

Change in v2:
- remove the second clock in dts and add alias id for gce node
- find the other gce node and get it's clock

jason-jh.lin (5):
  dt-bindings: mailbox: add definition for mt8195
  dt-bindings: gce: add gce header file for mt8195
  arm64: dts: mt8195: add gce node
  mailbox: cmdq: add mediatek mailbox support for mt8195
  mailbox: cmdq: add multi-gce clocks support for mt8195

 .../devicetree/bindings/mailbox/mtk-gce.txt   |   9 +-
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      |  22 +
 drivers/mailbox/mtk-cmdq-mailbox.c            |  89 +-
 include/dt-bindings/gce/mt8195-gce.h          | 920 ++++++++++++++++++
 4 files changed, 1017 insertions(+), 23 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt8195-gce.h

-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 17 19:40:35 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 18 Aug 2021 10:40:35 +0800
Subject: [PATCH v5 3/5] arm64: dts: mt8195: add gce node
In-Reply-To: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
References: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
Message-ID: <20210818024037.11396-4-jason-jh.lin@mediatek.com>

Add gce node and gce alias on mt8195 dts file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is based on [1]
[1] Add Mediatek SoC MT8195 and evaluation board dts and Makefile
    - https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index c146a91c6272..47c44cb77da0 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include <dt-bindings/clock/mt8195-clk.h>
+#include <dt-bindings/gce/mt8195-gce.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/power/mt8195-power.h>
@@ -16,6 +17,11 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		gce0 = &gce0;
+		gce1 = &gce1;
+	};
+
 	clocks {
 		clk26m: oscillator0 {
 			compatible = "fixed-clock";
@@ -699,6 +705,22 @@
 			#clock-cells = <1>;
 		};
 
+		gce0: mdp_mailbox at 10320000 {
+			compatible = "mediatek,mt8195-gce";
+			reg = <0 0x10320000 0 0x4000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_GCE>;
+		};
+
+		gce1: disp_mailbox at 10330000 {
+			compatible = "mediatek,mt8195-gce";
+			reg = <0 0x10330000 0 0x4000>;
+			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_GCE2>;
+		};
+
 		scp_adsp: syscon at 10720000 {
 			compatible = "mediatek,mt8195-scp_adsp", "syscon";
 			reg = <0 0x10720000 0 0x1000>;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 17 19:40:34 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 18 Aug 2021 10:40:34 +0800
Subject: [PATCH v5 2/5] dt-bindings: gce: add gce header file for mt8195
In-Reply-To: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
References: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
Message-ID: <20210818024037.11396-3-jason-jh.lin@mediatek.com>

To define the subsys id and event id, add gce header file for mt8195.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 include/dt-bindings/gce/mt8195-gce.h | 920 +++++++++++++++++++++++++++
 1 file changed, 920 insertions(+)
 create mode 100644 include/dt-bindings/gce/mt8195-gce.h

diff --git a/include/dt-bindings/gce/mt8195-gce.h b/include/dt-bindings/gce/mt8195-gce.h
new file mode 100644
index 000000000000..8c309e59491d
--- /dev/null
+++ b/include/dt-bindings/gce/mt8195-gce.h
@@ -0,0 +1,920 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8195_H
+#define _DT_BINDINGS_GCE_MT8195_H
+
+/* assign timeout 0 also means default */
+#define CMDQ_NO_TIMEOUT		0xffffffff
+#define CMDQ_TIMEOUT_DEFAULT	1000
+
+/* GCE thread priority */
+#define CMDQ_THR_PRIO_LOWEST	0
+#define CMDQ_THR_PRIO_1		1
+#define CMDQ_THR_PRIO_2		2
+#define CMDQ_THR_PRIO_3		3
+#define CMDQ_THR_PRIO_4		4
+#define CMDQ_THR_PRIO_5		5
+#define CMDQ_THR_PRIO_6		6
+#define CMDQ_THR_PRIO_HIGHEST	7
+
+/* CPR count in 32bit register */
+#define GCE_CPR_COUNT		1312
+
+/* GCE subsys table */
+#define SUBSYS_1400XXXX		0
+#define SUBSYS_1401XXXX		1
+#define SUBSYS_1402XXXX		2
+#define SUBSYS_1c00XXXX		3
+#define SUBSYS_1c01XXXX		4
+#define SUBSYS_1c02XXXX		5
+#define SUBSYS_1c10XXXX		6
+#define SUBSYS_1c11XXXX		7
+#define SUBSYS_1c12XXXX		8
+#define SUBSYS_14f0XXXX		9
+#define SUBSYS_14f1XXXX		10
+#define SUBSYS_14f2XXXX		11
+#define SUBSYS_1800XXXX		12
+#define SUBSYS_1801XXXX		13
+#define SUBSYS_1802XXXX		14
+#define SUBSYS_1803XXXX		15
+#define SUBSYS_1032XXXX		16
+#define SUBSYS_1033XXXX		17
+#define SUBSYS_1600XXXX		18
+#define SUBSYS_1601XXXX		19
+#define SUBSYS_14e0XXXX		20
+#define SUBSYS_1c20XXXX		21
+#define SUBSYS_1c30XXXX		22
+#define SUBSYS_1c40XXXX		23
+#define SUBSYS_1c50XXXX		24
+#define SUBSYS_1c60XXXX		25
+#define SUBSYS_NO_SUPPORT	99
+
+/* GCE General Purpose Register (GPR) support
+ * Leave note for scenario usage here
+ */
+/* GCE: write mask */
+#define GCE_GPR_R00		0x00
+#define GCE_GPR_R01		0x01
+/* MDP: P1: JPEG dest */
+#define GCE_GPR_R02		0x02
+#define GCE_GPR_R03		0x03
+/* MDP: PQ color */
+#define GCE_GPR_R04		0x04
+/* MDP: 2D sharpness */
+#define GCE_GPR_R05		0x05
+/* DISP: poll esd */
+#define GCE_GPR_R06		0x06
+#define GCE_GPR_R07		0x07
+/* MDP: P4: 2D sharpness dst */
+#define GCE_GPR_R08		0x08
+#define GCE_GPR_R09		0x09
+/* VCU: poll with timeout for GPR timer */
+#define GCE_GPR_R10		0x0A
+#define GCE_GPR_R11		0x0B
+/* CMDQ: debug */
+#define GCE_GPR_R12		0x0C
+#define GCE_GPR_R13		0x0D
+/* CMDQ: P7: debug */
+#define GCE_GPR_R14		0x0E
+#define GCE_GPR_R15		0x0F
+
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_0	1
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_1	2
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_2	3
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_3	4
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_4	5
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_5	6
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_6	7
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_7	8
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_8	9
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_9	10
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_10	11
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_11	12
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_12	13
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_13	14
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_14	15
+#define CMDQ_EVENT_TRAW0_DMA_ERROR_INT	16
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_0	17
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_1	18
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_2	19
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_3	20
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_4	21
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_5	22
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_6	23
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_7	24
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_8	25
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_9	26
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_10	27
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_11	28
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_12	29
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_13	30
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_14	31
+#define CMDQ_EVENT_TRAW1_DMA_ERROR_INT	32
+
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_0	65
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_1	66
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_2	67
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_3	68
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_4	69
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_5	70
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_6	71
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_7	72
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_8	73
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_9	74
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_10	75
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_11	76
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_12	77
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_13	78
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_14	79
+#define CMDQ_EVENT_DIP0_DMA_ERR	80
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_0	81
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_1	82
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_2	83
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_3	84
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_4	85
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_5	86
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_6	87
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_7	88
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_8	89
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_9	90
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_10	91
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_11	92
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_12	93
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_13	94
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_14	95
+#define CMDQ_EVENT_PQA0_DMA_ERR	96
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_0	97
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_1	98
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_2	99
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_3	100
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_4	101
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_5	102
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_6	103
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_7	104
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_8	105
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_9	106
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_10	107
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_11	108
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_12	109
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_13	110
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_14	111
+#define CMDQ_EVENT_PQB0_DMA_ERR	112
+#define CMDQ_EVENT_DIP0_DUMMY_0	113
+#define CMDQ_EVENT_DIP0_DUMMY_1	114
+#define CMDQ_EVENT_DIP0_DUMMY_2	115
+#define CMDQ_EVENT_DIP0_DUMMY_3	116
+#define CMDQ_EVENT_WPE0_EIS_GCE_FRAME_DONE	117
+#define CMDQ_EVENT_WPE0_EIS_DONE_SYNC_OUT	118
+#define CMDQ_EVENT_WPE0_TNR_GCE_FRAME_DONE	119
+#define CMDQ_EVENT_WPE0_TNR_DONE_SYNC_OUT	120
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_0	121
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_1	122
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_2	123
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_3	124
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_4	125
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_5	126
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_6	127
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_7	128
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_8	129
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_9	130
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_10	131
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_11	132
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_12	133
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_13	134
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_14	135
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_0	136
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_1	137
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_2	138
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_3	139
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_4	140
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_5	141
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_6	142
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_7	143
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_8	144
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_9	145
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_10	146
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_11	147
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_12	148
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_13	149
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_14	150
+#define CMDQ_EVENT_WPE0_DUMMY_0	151
+#define CMDQ_EVENT_IMGSYS_IPE_DUMMY	152
+#define CMDQ_EVENT_IMGSYS_IPE_FDVT_DONE	153
+#define CMDQ_EVENT_IMGSYS_IPE_ME_DONE	154
+#define CMDQ_EVENT_IMGSYS_IPE_DVS_DONE	155
+#define CMDQ_EVENT_IMGSYS_IPE_DVP_DONE	156
+
+#define CMDQ_EVENT_TPR_0	194
+#define CMDQ_EVENT_TPR_1	195
+#define CMDQ_EVENT_TPR_2	196
+#define CMDQ_EVENT_TPR_3	197
+#define CMDQ_EVENT_TPR_4	198
+#define CMDQ_EVENT_TPR_5	199
+#define CMDQ_EVENT_TPR_6	200
+#define CMDQ_EVENT_TPR_7	201
+#define CMDQ_EVENT_TPR_8	202
+#define CMDQ_EVENT_TPR_9	203
+#define CMDQ_EVENT_TPR_10	204
+#define CMDQ_EVENT_TPR_11	205
+#define CMDQ_EVENT_TPR_12	206
+#define CMDQ_EVENT_TPR_13	207
+#define CMDQ_EVENT_TPR_14	208
+#define CMDQ_EVENT_TPR_15	209
+#define CMDQ_EVENT_TPR_16	210
+#define CMDQ_EVENT_TPR_17	211
+#define CMDQ_EVENT_TPR_18	212
+#define CMDQ_EVENT_TPR_19	213
+#define CMDQ_EVENT_TPR_20	214
+#define CMDQ_EVENT_TPR_21	215
+#define CMDQ_EVENT_TPR_22	216
+#define CMDQ_EVENT_TPR_23	217
+#define CMDQ_EVENT_TPR_24	218
+#define CMDQ_EVENT_TPR_25	219
+#define CMDQ_EVENT_TPR_26	220
+#define CMDQ_EVENT_TPR_27	221
+#define CMDQ_EVENT_TPR_28	222
+#define CMDQ_EVENT_TPR_29	223
+#define CMDQ_EVENT_TPR_30	224
+#define CMDQ_EVENT_TPR_31	225
+#define CMDQ_EVENT_TPR_TIMEOUT_0	226
+#define CMDQ_EVENT_TPR_TIMEOUT_1	227
+#define CMDQ_EVENT_TPR_TIMEOUT_2	228
+#define CMDQ_EVENT_TPR_TIMEOUT_3	229
+#define CMDQ_EVENT_TPR_TIMEOUT_4	230
+#define CMDQ_EVENT_TPR_TIMEOUT_5	231
+#define CMDQ_EVENT_TPR_TIMEOUT_6	232
+#define CMDQ_EVENT_TPR_TIMEOUT_7	233
+#define CMDQ_EVENT_TPR_TIMEOUT_8	234
+#define CMDQ_EVENT_TPR_TIMEOUT_9	235
+#define CMDQ_EVENT_TPR_TIMEOUT_10	236
+#define CMDQ_EVENT_TPR_TIMEOUT_11	237
+#define CMDQ_EVENT_TPR_TIMEOUT_12	238
+#define CMDQ_EVENT_TPR_TIMEOUT_13	239
+#define CMDQ_EVENT_TPR_TIMEOUT_14	240
+#define CMDQ_EVENT_TPR_TIMEOUT_15	241
+
+#define CMDQ_EVENT_VPP0_MDP_RDMA_SOF	256
+#define CMDQ_EVENT_VPP0_MDP_FG_SOF	257
+#define CMDQ_EVENT_VPP0_STITCH_SOF	258
+#define CMDQ_EVENT_VPP0_MDP_HDR_SOF	259
+#define CMDQ_EVENT_VPP0_MDP_AAL_SOF	260
+#define CMDQ_EVENT_VPP0_MDP_RSZ_IN_RSZ_SOF	261
+#define CMDQ_EVENT_VPP0_MDP_TDSHP_SOF	262
+#define CMDQ_EVENT_VPP0_DISP_COLOR_SOF	263
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_SOF	264
+#define CMDQ_EVENT_VPP0_VPP_PADDING_IN_PADDING_SOF	265
+#define CMDQ_EVENT_VPP0_MDP_TCC_IN_SOF	266
+#define CMDQ_EVENT_VPP0_MDP_WROT_SOF	267
+
+#define CMDQ_EVENT_VPP0_WARP0_MMSYS_TOP_RELAY_SOF_PRE	269
+#define CMDQ_EVENT_VPP0_WARP1_MMSYS_TOP_RELAY_SOF_PRE	270
+#define CMDQ_EVENT_VPP0_VPP1_MMSYS_TOP_RELAY_SOF	271
+#define CMDQ_EVENT_VPP0_VPP1_IN_MMSYS_TOP_RELAY_SOF_PRE	272
+
+#define CMDQ_EVENT_VPP0_MDP_RDMA_FRAME_DONE	288
+#define CMDQ_EVENT_VPP0_MDP_FG_TILE_DONE	289
+#define CMDQ_EVENT_VPP0_STITCH_FRAME_DONE	290
+#define CMDQ_EVENT_VPP0_MDP_HDR_FRAME_DONE	291
+#define CMDQ_EVENT_VPP0_MDP_AAL_FRAME_DONE	292
+#define CMDQ_EVENT_VPP0_MDP_RSZ_FRAME_DONE	293
+#define CMDQ_EVENT_VPP0_MDP_TDSHP_FRAME_DONE	294
+#define CMDQ_EVENT_VPP0_DISP_COLOR_FRAME_DONE	295
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_FRAME_DONE	296
+#define CMDQ_EVENT_VPP0_VPP_PADDING_IN_PADDING_FRAME_DONE	297
+#define CMDQ_EVENT_VPP0_MDP_TCC_TCC_FRAME_DONE	298
+#define CMDQ_EVENT_VPP0_MDP_WROT_VIDO_WDONE	299
+
+#define CMDQ_EVENT_VPP0_STREAM_DONE_0	320
+#define CMDQ_EVENT_VPP0_STREAM_DONE_1	321
+#define CMDQ_EVENT_VPP0_STREAM_DONE_2	322
+#define CMDQ_EVENT_VPP0_STREAM_DONE_3	323
+#define CMDQ_EVENT_VPP0_STREAM_DONE_4	324
+#define CMDQ_EVENT_VPP0_STREAM_DONE_5	325
+#define CMDQ_EVENT_VPP0_STREAM_DONE_6	326
+#define CMDQ_EVENT_VPP0_STREAM_DONE_7	327
+#define CMDQ_EVENT_VPP0_STREAM_DONE_8	328
+#define CMDQ_EVENT_VPP0_STREAM_DONE_9	329
+#define CMDQ_EVENT_VPP0_STREAM_DONE_10	330
+#define CMDQ_EVENT_VPP0_STREAM_DONE_11	331
+#define CMDQ_EVENT_VPP0_STREAM_DONE_12	332
+#define CMDQ_EVENT_VPP0_STREAM_DONE_13	333
+#define CMDQ_EVENT_VPP0_STREAM_DONE_14	334
+#define CMDQ_EVENT_VPP0_STREAM_DONE_15	335
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_0	336
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_1	337
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_2	338
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_3	339
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_4	340
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_5	341
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_6	342
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_7	343
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_8	344
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_9	345
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_10	346
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_11	347
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_12	348
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_13	349
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_14	350
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_15	351
+#define CMDQ_EVENT_VPP0_MDP_RDMA_SW_RST_DONE	352
+#define CMDQ_EVENT_VPP0_MDP_RDMA_PM_VALID	353
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_FRAME_RESET_DONE_PULSE	354
+#define CMDQ_EVENT_VPP0_MDP_WROT_SW_RST_DONE	355
+
+#define CMDQ_EVENT_VPP1_HDMI_META_SOF		384
+#define CMDQ_EVENT_VPP1_DGI_SOF			385
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_SOF		386
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_TCC_SOF	387
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RDMA_SOF	388
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_SOF	389
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_SOF	390
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_FG_SOF	391
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_FG_SOF	392
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_FG_SOF	393
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_HDR_SOF	394
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_HDR_SOF	395
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_HDR_SOF	396
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_AAL_SOF	397
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_AAL_SOF	398
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_AAL_SOF	399
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RSZ_SOF	400
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RSZ_SOF	401
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RSZ_SOF	402
+#define CMDQ_EVENT_VPP1_SVPP1_TDSHP_SOF		403
+#define CMDQ_EVENT_VPP1_SVPP2_TDSHP_SOF		404
+#define CMDQ_EVENT_VPP1_SVPP3_TDSHP_SOF		405
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_MERGE_SOF	406
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_MERGE_SOF	407
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_COLOR_SOF	408
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_COLOR_SOF	409
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_COLOR_SOF	410
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_OVL_SOF	411
+#define CMDQ_EVENT_VPP1_SVPP1_VPP_PAD_SOF	412
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_PAD_SOF	413
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_PAD_SOF	414
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_SOF	415
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_SOF	416
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_SOF	417
+#define CMDQ_EVENT_VPP1_VPP0_DL_IRLY_SOF	418
+#define CMDQ_EVENT_VPP1_VPP0_DL_ORLY_SOF	419
+#define CMDQ_EVENT_VPP1_VDO0_DL_ORLY_0_SOF	420
+#define CMDQ_EVENT_VPP1_VDO0_DL_ORLY_1_SOF	421
+#define CMDQ_EVENT_VPP1_VDO1_DL_ORLY_0_SOF	422
+#define CMDQ_EVENT_VPP1_VDO1_DL_ORLY_1_SOF	423
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RDMA_FRAME_DONE	424
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_FRAME_DONE	425
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_FRAME_DONE	426
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_FRAME_DONE	427
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_FRAME_DONE	428
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_FRAME_DONE	429
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_OVL_FRAME_DONE	430
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RSZ_FRAME_DONE	431
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RSZ_FRAME_DONE	432
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RSZ_FRAME_DONE	433
+#define CMDQ_EVENT_VPP1_FRAME_DONE_10	434
+#define CMDQ_EVENT_VPP1_FRAME_DONE_11	435
+#define CMDQ_EVENT_VPP1_FRAME_DONE_12	436
+#define CMDQ_EVENT_VPP1_FRAME_DONE_13	437
+#define CMDQ_EVENT_VPP1_FRAME_DONE_14	438
+#define CMDQ_EVENT_VPP1_STREAM_DONE_0	439
+#define CMDQ_EVENT_VPP1_STREAM_DONE_1	440
+#define CMDQ_EVENT_VPP1_STREAM_DONE_2	441
+#define CMDQ_EVENT_VPP1_STREAM_DONE_3	442
+#define CMDQ_EVENT_VPP1_STREAM_DONE_4	443
+#define CMDQ_EVENT_VPP1_STREAM_DONE_5	444
+#define CMDQ_EVENT_VPP1_STREAM_DONE_6	445
+#define CMDQ_EVENT_VPP1_STREAM_DONE_7	446
+#define CMDQ_EVENT_VPP1_STREAM_DONE_8	447
+#define CMDQ_EVENT_VPP1_STREAM_DONE_9	448
+#define CMDQ_EVENT_VPP1_STREAM_DONE_10	449
+#define CMDQ_EVENT_VPP1_STREAM_DONE_11	450
+#define CMDQ_EVENT_VPP1_STREAM_DONE_12	451
+#define CMDQ_EVENT_VPP1_STREAM_DONE_13	452
+#define CMDQ_EVENT_VPP1_STREAM_DONE_14	453
+#define CMDQ_EVENT_VPP1_STREAM_DONE_15	454
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_0	455
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_1	456
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_2	457
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_3	458
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_4	459
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_5	460
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_6	461
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_7	462
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_8	463
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_9	464
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_10	465
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_11	466
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_12	467
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_13	468
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_14	469
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_15	470
+#define CMDQ_EVENT_VPP1_DGI_0	471
+#define CMDQ_EVENT_VPP1_DGI_1	472
+#define CMDQ_EVENT_VPP1_DGI_2	473
+#define CMDQ_EVENT_VPP1_DGI_3	474
+#define CMDQ_EVENT_VPP1_DGI_4	475
+#define CMDQ_EVENT_VPP1_DGI_5	476
+#define CMDQ_EVENT_VPP1_DGI_6	477
+#define CMDQ_EVENT_VPP1_DGI_7	478
+#define CMDQ_EVENT_VPP1_DGI_8	479
+#define CMDQ_EVENT_VPP1_DGI_9	480
+#define CMDQ_EVENT_VPP1_DGI_10	481
+#define CMDQ_EVENT_VPP1_DGI_11	482
+#define CMDQ_EVENT_VPP1_DGI_12	483
+#define CMDQ_EVENT_VPP1_DGI_13	484
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_MERGE	485
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_MERGE	486
+#define CMDQ_EVENT_VPP1_MDP_OVL_FRAME_RESET_DONE_PULSE	487
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_DGI	488
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_HDMI	489
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_SW_RST_DONE	490
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_SW_RST_DONE	491
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_SW_RST_DONE	492
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_FG_TILE_DONE	493
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_FG_TILE_DONE	494
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_FG_TILE_DONE	495
+
+#define CMDQ_EVENT_VDO0_DISP_OVL0_SOF	512
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_SOF	513
+#define CMDQ_EVENT_VDO0_DISP_RDMA0_SOF	514
+#define CMDQ_EVENT_VDO0_DISP_COLOR0_SOF	515
+#define CMDQ_EVENT_VDO0_DISP_CCORR0_SOF	516
+#define CMDQ_EVENT_VDO0_DISP_AAL0_SOF	517
+#define CMDQ_EVENT_VDO0_DISP_GAMMA0_SOF	518
+#define CMDQ_EVENT_VDO0_DISP_DITHER0_SOF	519
+#define CMDQ_EVENT_VDO0_DSI0_SOF	520
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C0_SOF	521
+#define CMDQ_EVENT_VDO0_DISP_OVL1_SOF	522
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_SOF	523
+#define CMDQ_EVENT_VDO0_DISP_RDMA1_SOF	524
+#define CMDQ_EVENT_VDO0_DISP_COLOR1_SOF	525
+#define CMDQ_EVENT_VDO0_DISP_CCORR1_SOF	526
+#define CMDQ_EVENT_VDO0_DISP_AAL1_SOF	527
+#define CMDQ_EVENT_VDO0_DISP_GAMMA1_SOF	528
+#define CMDQ_EVENT_VDO0_DISP_DITHER1_SOF	529
+#define CMDQ_EVENT_VDO0_DSI1_SOF	530
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C1_SOF	531
+#define CMDQ_EVENT_VDO0_VPP_MERGE0_SOF	532
+#define CMDQ_EVENT_VDO0_DP_INTF0_SOF	533
+#define CMDQ_EVENT_VDO0_VPP1_DL_RELAY0_SOF	534
+#define CMDQ_EVENT_VDO0_VPP1_DL_RELAY1_SOF	535
+#define CMDQ_EVENT_VDO0_VDO1_DL_RELAY2_SOF	536
+#define CMDQ_EVENT_VDO0_VDO0_DL_RELAY3_SOF	537
+#define CMDQ_EVENT_VDO0_VDO0_DL_RELAY4_SOF	538
+#define CMDQ_EVENT_VDO0_DISP_PWM0_SOF	539
+#define CMDQ_EVENT_VDO0_DISP_PWM1_SOF	540
+
+#define CMDQ_EVENT_VDO0_DISP_OVL0_FRAME_DONE	544
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_FRAME_DONE	545
+#define CMDQ_EVENT_VDO0_DISP_RDMA0_FRAME_DONE	546
+#define CMDQ_EVENT_VDO0_DISP_COLOR0_FRAME_DONE	547
+#define CMDQ_EVENT_VDO0_DISP_CCORR0_FRAME_DONE	548
+#define CMDQ_EVENT_VDO0_DISP_AAL0_FRAME_DONE	549
+#define CMDQ_EVENT_VDO0_DISP_GAMMA0_FRAME_DONE	550
+#define CMDQ_EVENT_VDO0_DISP_DITHER0_FRAME_DONE	551
+#define CMDQ_EVENT_VDO0_DSI0_FRAME_DONE	552
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C0_FRAME_DONE	553
+#define CMDQ_EVENT_VDO0_DISP_OVL1_FRAME_DONE	554
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_FRAME_DONE	555
+#define CMDQ_EVENT_VDO0_DISP_RDMA1_FRAME_DONE	556
+#define CMDQ_EVENT_VDO0_DISP_COLOR1_FRAME_DONE	557
+#define CMDQ_EVENT_VDO0_DISP_CCORR1_FRAME_DONE	558
+#define CMDQ_EVENT_VDO0_DISP_AAL1_FRAME_DONE	559
+#define CMDQ_EVENT_VDO0_DISP_GAMMA1_FRAME_DONE	560
+#define CMDQ_EVENT_VDO0_DISP_DITHER1_FRAME_DONE	561
+#define CMDQ_EVENT_VDO0_DSI1_FRAME_DONE	562
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C1_FRAME_DONE	563
+
+#define CMDQ_EVENT_VDO0_DP_INTF0_FRAME_DONE	565
+
+#define CMDQ_EVENT_VDO0_DISP_SMIASSERT_ENG	576
+#define CMDQ_EVENT_VDO0_DSI0_IRQ_ENG_EVENT_MM	577
+#define CMDQ_EVENT_VDO0_DSI0_TE_ENG_EVENT_MM	578
+#define CMDQ_EVENT_VDO0_DSI0_DONE_ENG_EVENT_MM	579
+#define CMDQ_EVENT_VDO0_DSI0_SOF_ENG_EVENT_MM	580
+#define CMDQ_EVENT_VDO0_DSI0_VACTL_ENG_EVENT_MM	581
+#define CMDQ_EVENT_VDO0_DSI1_IRQ_ENG_EVENT_MM	582
+#define CMDQ_EVENT_VDO0_DSI1_TE_ENG_EVENT_MM	583
+#define CMDQ_EVENT_VDO0_DSI1_DONE_ENG_EVENT_MM	584
+#define CMDQ_EVENT_VDO0_DSI1_SOF_ENG_EVENT_MM	585
+#define CMDQ_EVENT_VDO0_DSI1_VACTL_ENG_EVENT_MM	586
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_SW_RST_DONE_ENG	587
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_SW_RST_DONE_ENG	588
+#define CMDQ_EVENT_VDO0_DISP_OVL0_RST_DONE_ENG	589
+#define CMDQ_EVENT_VDO0_DISP_OVL1_RST_DONE_ENG	590
+#define CMDQ_EVENT_VDO0_DP_INTF0_VSYNC_START_ENG_EVENT_MM	591
+#define CMDQ_EVENT_VDO0_DP_INTF0_VSYNC_END_ENG_EVENT_MM	592
+#define CMDQ_EVENT_VDO0_DP_INTF0_VDE_START_ENG_EVENT_MM	593
+#define CMDQ_EVENT_VDO0_DP_INTF0_VDE_END_ENG_EVENT_MM	594
+#define CMDQ_EVENT_VDO0_DP_INTF0_TARGET_LINE_ENG_EVENT_MM	595
+#define CMDQ_EVENT_VDO0_VPP_MERGE0_ENG	596
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0	597
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_1	598
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_2	599
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_3	600
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_4	601
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_5	602
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_6	603
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_7	604
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_8	605
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_9	606
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_10	607
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_11	608
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_12	609
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_13	610
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_14	611
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_15	612
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_0	613
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_1	614
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_2	615
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_3	616
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_4	617
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_5	618
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_6	619
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_7	620
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_8	621
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_9	622
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_10	623
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_11	624
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_12	625
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_13	626
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_14	627
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_15	628
+
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_SOF	640
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_SOF	641
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_SOF	642
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_SOF	643
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_SOF	644
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_SOF	645
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_SOF	646
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_SOF	647
+#define CMDQ_EVENT_VDO1_VPP_MERGE0_SOF	648
+#define CMDQ_EVENT_VDO1_VPP_MERGE1_SOF	649
+#define CMDQ_EVENT_VDO1_VPP_MERGE2_SOF	650
+#define CMDQ_EVENT_VDO1_VPP_MERGE3_SOF	651
+#define CMDQ_EVENT_VDO1_VPP_MERGE4_SOF	652
+#define CMDQ_EVENT_VDO1_VPP2_DL_RELAY_SOF	653
+#define CMDQ_EVENT_VDO1_VPP3_DL_RELAY_SOF	654
+#define CMDQ_EVENT_VDO1_VDO0_DSC_DL_ASYNC_SOF	655
+#define CMDQ_EVENT_VDO1_VDO0_MERGE_DL_ASYNC_SOF	656
+#define CMDQ_EVENT_VDO1_OUT_DL_RELAY_SOF	657
+#define CMDQ_EVENT_VDO1_DISP_MIXER_SOF	658
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE0_SOF	659
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_SOF	660
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_SOF	661
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_SOF	662
+#define CMDQ_EVENT_VDO1_HDR_VDO_BE0_SOF	663
+#define CMDQ_EVENT_VDO1_HDR_MLOAD_SOF	664
+
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_FRAME_DONE	672
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_FRAME_DONE	673
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_FRAME_DONE	674
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_FRAME_DONE	675
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_FRAME_DONE	676
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_FRAME_DONE	677
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_FRAME_DONE	678
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_FRAME_DONE	679
+#define CMDQ_EVENT_VDO1_VPP_MERGE0_FRAME_DONE	680
+#define CMDQ_EVENT_VDO1_VPP_MERGE1_FRAME_DONE	681
+#define CMDQ_EVENT_VDO1_VPP_MERGE2_FRAME_DONE	682
+#define CMDQ_EVENT_VDO1_VPP_MERGE3_FRAME_DONE	683
+#define CMDQ_EVENT_VDO1_VPP_MERGE4_FRAME_DONE	684
+#define CMDQ_EVENT_VDO1_DPI0_FRAME_DONE	685
+#define CMDQ_EVENT_VDO1_DPI1_FRAME_DONE	686
+#define CMDQ_EVENT_VDO1_DP_INTF0_FRAME_DONE	687
+#define CMDQ_EVENT_VDO1_DISP_MIXER_FRAME_DONE_MM	688
+
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_0	704
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_1	705
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_2	706
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_3	707
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_4	708
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_5	709
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_6	710
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_7	711
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_8	712
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_9	713
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_10	714
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_11	715
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_12	716
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_13	717
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_14	718
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_15	719
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_0	720
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_1	721
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_2	722
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_3	723
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_4	724
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_5	725
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_6	726
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_7	727
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_8	728
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_9	729
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_10	730
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_11	731
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_12	732
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_13	733
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_14	734
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_15	735
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_SW_RST_DONE	736
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_SW_RST_DONE	737
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_SW_RST_DONE	738
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_SW_RST_DONE	739
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_SW_RST_DONE	740
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_SW_RST_DONE	741
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_SW_RST_DONE	742
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_SW_RST_DONE	743
+
+#define CMDQ_EVENT_VDO1_DP0_VDE_END_ENG_EVENT_MM	745
+#define CMDQ_EVENT_VDO1_DP0_VDE_START_ENG_EVENT_MM	746
+#define CMDQ_EVENT_VDO1_DP0_VSYNC_END_ENG_EVENT_MM	747
+#define CMDQ_EVENT_VDO1_DP0_VSYNC_START_ENG_EVENT_MM	748
+#define CMDQ_EVENT_VDO1_DP0_TARGET_LINE_ENG_EVENT_MM	749
+#define CMDQ_EVENT_VDO1_VPP_MERGE0	750
+#define CMDQ_EVENT_VDO1_VPP_MERGE1	751
+#define CMDQ_EVENT_VDO1_VPP_MERGE2	752
+#define CMDQ_EVENT_VDO1_VPP_MERGE3	753
+#define CMDQ_EVENT_VDO1_VPP_MERGE4	754
+#define CMDQ_EVENT_VDO1_HDMITX	755
+#define CMDQ_EVENT_VDO1_HDR_VDO_BE0_ADL_TRIG_EVENT_MM	756
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_THDR_ADL_TRIG_EVENT_MM	757
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_DM_ADL_TRIG_EVENT_MM	758
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_THDR_ADL_TRIG_EVENT_MM	759
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_DM_ADL_TRIG_EVENT_MM	760
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_ADL_TRIG_EVENT_MM	761
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_AD0_TRIG_EVENT_MM	762
+
+#define CMDQ_EVENT_CAM_A_PASS1_DONE	769
+#define CMDQ_EVENT_CAM_B_PASS1_DONE	770
+#define CMDQ_EVENT_GCAMSV_A_PASS1_DONE	771
+#define CMDQ_EVENT_GCAMSV_B_PASS1_DONE	772
+#define CMDQ_EVENT_MRAW_0_PASS1_DONE	773
+#define CMDQ_EVENT_MRAW_1_PASS1_DONE	774
+#define CMDQ_EVENT_MRAW_2_PASS1_DONE	775
+#define CMDQ_EVENT_MRAW_3_PASS1_DONE	776
+#define CMDQ_EVENT_SENINF_CAM0_FIFO_FULL_X	777
+#define CMDQ_EVENT_SENINF_CAM1_FIFO_FULL_X	778
+#define CMDQ_EVENT_SENINF_CAM2_FIFO_FULL	779
+#define CMDQ_EVENT_SENINF_CAM3_FIFO_FULL	780
+#define CMDQ_EVENT_SENINF_CAM4_FIFO_FULL	781
+#define CMDQ_EVENT_SENINF_CAM5_FIFO_FULL	782
+#define CMDQ_EVENT_SENINF_CAM6_FIFO_FULL	783
+#define CMDQ_EVENT_SENINF_CAM7_FIFO_FULL	784
+#define CMDQ_EVENT_SENINF_CAM8_FIFO_FULL	785
+#define CMDQ_EVENT_SENINF_CAM9_FIFO_FULL	786
+#define CMDQ_EVENT_SENINF_CAM10_FIFO_FULL_X	787
+#define CMDQ_EVENT_SENINF_CAM11_FIFO_FULL_X	788
+#define CMDQ_EVENT_SENINF_CAM12_FIFO_FULL_X	789
+#define CMDQ_EVENT_SENINF_CAM13_FIFO_FULL_X	790
+#define CMDQ_EVENT_TG_OVRUN_MRAW0_INT_X0	791
+#define CMDQ_EVENT_TG_OVRUN_MRAW1_INT_X0	792
+#define CMDQ_EVENT_TG_OVRUN_MRAW2_INT	793
+#define CMDQ_EVENT_TG_OVRUN_MRAW3_INT	794
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW0_INT	795
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW1_INT	796
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW2_INT	797
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW3_INT	798
+#define CMDQ_EVENT_U_CAMSYS_PDA_IRQO_EVENT_DONE_D1	799
+#define CMDQ_EVENT_SUBB_TG_INT4	800
+#define CMDQ_EVENT_SUBB_TG_INT3	801
+#define CMDQ_EVENT_SUBB_TG_INT2	802
+#define CMDQ_EVENT_SUBB_TG_INT1	803
+#define CMDQ_EVENT_SUBA_TG_INT4	804
+#define CMDQ_EVENT_SUBA_TG_INT3	805
+#define CMDQ_EVENT_SUBA_TG_INT2	806
+#define CMDQ_EVENT_SUBA_TG_INT1	807
+#define CMDQ_EVENT_SUBB_DRZS4NO_R1_LOW_LATENCY_LINE_CNT_INT	808
+#define CMDQ_EVENT_SUBB_YUVO_R3_LOW_LATENCY_LINE_CNT_INT	809
+#define CMDQ_EVENT_SUBB_YUVO_R1_LOW_LATENCY_LINE_CNT_INT	810
+#define CMDQ_EVENT_SUBB_IMGO_R1_LOW_LATENCY_LINE_CNT_INT	811
+#define CMDQ_EVENT_SUBA_DRZS4NO_R1_LOW_LATENCY_LINE_CNT_INT	812
+#define CMDQ_EVENT_SUBA_YUVO_R3_LOW_LATENCY_LINE_CNT_INT	813
+#define CMDQ_EVENT_SUBA_YUVO_R1_LOW_LATENCY_LINE_CNT_INT	814
+#define CMDQ_EVENT_SUBA_IMGO_R1_LOW_LATENCY_LINE_CNT_INT	815
+#define CMDQ_EVENT_GCE1_SOF_0	816
+#define CMDQ_EVENT_GCE1_SOF_1	817
+#define CMDQ_EVENT_GCE1_SOF_2	818
+#define CMDQ_EVENT_GCE1_SOF_3	819
+#define CMDQ_EVENT_GCE1_SOF_4	820
+#define CMDQ_EVENT_GCE1_SOF_5	821
+#define CMDQ_EVENT_GCE1_SOF_6	822
+#define CMDQ_EVENT_GCE1_SOF_7	823
+#define CMDQ_EVENT_GCE1_SOF_8	824
+#define CMDQ_EVENT_GCE1_SOF_9	825
+#define CMDQ_EVENT_GCE1_SOF_10	826
+#define CMDQ_EVENT_GCE1_SOF_11	827
+#define CMDQ_EVENT_GCE1_SOF_12	828
+#define CMDQ_EVENT_GCE1_SOF_13	829
+#define CMDQ_EVENT_GCE1_SOF_14	830
+#define CMDQ_EVENT_GCE1_SOF_15	831
+
+#define CMDQ_EVENT_VDEC_LAT_LINE_COUNT_THRESHOLD_INTERRUPT	832
+#define CMDQ_EVENT_VDEC_LAT_VDEC_INT	833
+#define CMDQ_EVENT_VDEC_LAT_VDEC_PAUSE	834
+#define CMDQ_EVENT_VDEC_LAT_VDEC_DEC_ERROR	835
+#define CMDQ_EVENT_VDEC_LAT_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	836
+#define CMDQ_EVENT_VDEC_LAT_VDEC_FRAME_DONE	837
+#define CMDQ_EVENT_VDEC_LAT_INI_FETCH_RDY	838
+#define CMDQ_EVENT_VDEC_LAT_PROCESS_FLAG	839
+#define CMDQ_EVENT_VDEC_LAT_SEARCH_START_CODE_DONE	840
+#define CMDQ_EVENT_VDEC_LAT_REF_REORDER_DONE	841
+#define CMDQ_EVENT_VDEC_LAT_WP_TBLE_DONE	842
+#define CMDQ_EVENT_VDEC_LAT_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	843
+#define CMDQ_EVENT_VDEC_LAT_GCE_CNT_OP_THRESHOLD	847
+
+#define CMDQ_EVENT_VDEC_LAT1_LINE_COUNT_THRESHOLD_INTERRUPT	848
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_INT	849
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_PAUSE	850
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_DEC_ERROR	851
+#define CMDQ_EVENT_VDEC_LAT1_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	852
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_FRAME_DONE	853
+#define CMDQ_EVENT_VDEC_LAT1_INI_FETCH_RDY	854
+#define CMDQ_EVENT_VDEC_LAT1_PROCESS_FLAG	855
+#define CMDQ_EVENT_VDEC_LAT1_SEARCH_START_CODE_DONE	856
+#define CMDQ_EVENT_VDEC_LAT1_REF_REORDER_DONE	857
+#define CMDQ_EVENT_VDEC_LAT1_WP_TBLE_DONE	858
+#define CMDQ_EVENT_VDEC_LAT1_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	859
+#define CMDQ_EVENT_VDEC_LAT1_GCE_CNT_OP_THRESHOLD	863
+
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_0	864
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_1	865
+
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_8	872
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_9	873
+
+#define CMDQ_EVENT_VDEC_CORE_LINE_COUNT_THRESHOLD_INTERRUPT	896
+#define CMDQ_EVENT_VDEC_CORE_VDEC_INT	897
+#define CMDQ_EVENT_VDEC_CORE_VDEC_PAUSE	898
+#define CMDQ_EVENT_VDEC_CORE_VDEC_DEC_ERROR	899
+#define CMDQ_EVENT_VDEC_CORE_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	900
+#define CMDQ_EVENT_VDEC_CORE_VDEC_FRAME_DONE	901
+#define CMDQ_EVENT_VDEC_CORE_INI_FETCH_RDY	902
+#define CMDQ_EVENT_VDEC_CORE_PROCESS_FLAG	903
+#define CMDQ_EVENT_VDEC_CORE_SEARCH_START_CODE_DONE	904
+#define CMDQ_EVENT_VDEC_CORE_REF_REORDER_DONE	905
+#define CMDQ_EVENT_VDEC_CORE_WP_TBLE_DONE	906
+#define CMDQ_EVENT_VDEC_CORE_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	907
+#define CMDQ_EVENT_VDEC_CORE_GCE_CNT_OP_THRESHOLD	911
+
+#define CMDQ_EVENT_VDEC_CORE1_LINE_COUNT_THRESHOLD_INTERRUPT	912
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_INT	913
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_PAUSE	914
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_DEC_ERROR	915
+#define CMDQ_EVENT_VDEC_CORE1_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	916
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_FRAME_DONE	917
+#define CMDQ_EVENT_VDEC_CORE1_INI_FETCH_RDY	918
+#define CMDQ_EVENT_VDEC_CORE1_PROCESS_FLAG	919
+#define CMDQ_EVENT_VDEC_CORE1_SEARCH_START_CODE_DONE	920
+#define CMDQ_EVENT_VDEC_CORE1_REF_REORDER_DONE	921
+#define CMDQ_EVENT_VDEC_CORE1_WP_TBLE_DONE	922
+#define CMDQ_EVENT_VDEC_CORE1_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	923
+#define CMDQ_EVENT_VDEC_CORE1_CNT_OP_THRESHOLD	927
+
+#define CMDQ_EVENT_VENC_TOP_FRAME_DONE	929
+#define CMDQ_EVENT_VENC_TOP_PAUSE_DONE	930
+#define CMDQ_EVENT_VENC_TOP_JPGENC_DONE	931
+#define CMDQ_EVENT_VENC_TOP_MB_DONE	932
+#define CMDQ_EVENT_VENC_TOP_128BYTE_DONE	933
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_DONE	934
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_C1_DONE	935
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_INSUFF_DONE	936
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_C1_INSUFF_DONE	937
+#define CMDQ_EVENT_VENC_TOP_WP_2ND_STAGE_DONE	938
+#define CMDQ_EVENT_VENC_TOP_WP_3RD_STAGE_DONE	939
+#define CMDQ_EVENT_VENC_TOP_PPS_HEADER_DONE	940
+#define CMDQ_EVENT_VENC_TOP_SPS_HEADER_DONE	941
+#define CMDQ_EVENT_VENC_TOP_VPS_HEADER_DONE	942
+
+#define CMDQ_EVENT_VENC_CORE1_TOP_FRAME_DONE	945
+#define CMDQ_EVENT_VENC_CORE1_TOP_PAUSE_DONE	946
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGENC_DONE	947
+#define CMDQ_EVENT_VENC_CORE1_TOP_MB_DONE	948
+#define CMDQ_EVENT_VENC_CORE1_TOP_128BYTE_DONE	949
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_DONE	950
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_C1_DONE	951
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_INSUFF_DONE	952
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_C1_INSUFF_DONE	953
+#define CMDQ_EVENT_VENC_CORE1_TOP_WP_2ND_STAGE_DONE	954
+#define CMDQ_EVENT_VENC_CORE1_TOP_WP_3RD_STAGE_DONE	955
+#define CMDQ_EVENT_VENC_CORE1_TOP_PPS_HEADER_DONE	956
+#define CMDQ_EVENT_VENC_CORE1_TOP_SPS_HEADER_DONE	957
+#define CMDQ_EVENT_VENC_CORE1_TOP_VPS_HEADER_DONE	958
+
+#define CMDQ_EVENT_WPE_VPP0_WPE_GCE_FRAME_DONE	962
+#define CMDQ_EVENT_WPE_VPP0_WPE_DONE_SYNC_OUT	963
+
+#define CMDQ_EVENT_WPE_VPP1_WPE_GCE_FRAME_DONE	969
+#define CMDQ_EVENT_WPE_VPP1_WPE_DONE_SYNC_OUT	970
+
+#define CMDQ_EVENT_DP_TX_VBLANK_FALLING	994 /* exception */
+#define CMDQ_EVENT_DP_TX_VSC_FINISH	995 /* exception */
+
+#define CMDQ_EVENT_OUTPIN_0	1018 /* exception */
+#define CMDQ_EVENT_OUTPIN_1	1019 /* exception */
+
+/* end of hw event */
+#define CMDQ_MAX_HW_EVENT				1019
+
+/* sw token should use the unused event id from 0 to 1023 */
+#define CMDQ_SYNC_TOKEN_INVALID				(-1)
+
+/* Event for imgsys flow control */
+#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_EIS			33
+#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_TNR			34
+#define CMDQ_SYNC_TOKEN_IMGSYS_TRAW			35
+#define CMDQ_SYNC_TOKEN_IMGSYS_LTRAW			36
+#define CMDQ_SYNC_TOKEN_IMGSYS_DIP			37
+#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_A			38
+#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_B			39
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_1			41
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_2			42
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_3			43
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_4			44
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_5			45
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_6			46
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_7			47
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_8			48
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_9			49
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_10			50
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_11			51
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_12			52
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_13			53
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_14			54
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_15			55
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_16			56
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_17			57
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_18			58
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_19			59
+#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_20			60
+/* Config thread notify trigger thread */
+#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY			971
+/* Trigger thread notify config thread */
+#define CMDQ_SYNC_TOKEN_STREAM_EOF			972
+/* Block Trigger thread until the ESD check finishes. */
+#define CMDQ_SYNC_TOKEN_ESD_EOF				973
+#define CMDQ_SYNC_TOKEN_STREAM_BLOCK			974
+/* check CABC setup finish */
+#define CMDQ_SYNC_TOKEN_CABC_EOF			975
+/* Pass-2 notifies VENC frame is ready to be encoded */
+#define CMDQ_SYNC_TOKEN_VENC_INPUT_READY		976
+/* VENC notifies Pass-2 encode done so next frame may start */
+#define CMDQ_SYNC_TOKEN_VENC_EOF			977
+
+/* Notify normal CMDQ there are some secure task done
+ * MUST NOT CHANGE, this token sync with secure world
+ */
+#define CMDQ_SYNC_SECURE_THR_EOF			980
+#define CMDQ_SYNC_SECURE_THR_EOF_DBG			995
+
+/* CMDQ use sw token */
+#define CMDQ_SYNC_TOKEN_USER_0				981
+#define CMDQ_SYNC_TOKEN_USER_1				982
+#define CMDQ_SYNC_TOKEN_POLL_MONITOR			983
+#define CMDQ_SYNC_TOKEN_TPR_LOCK			984
+
+/* ISP sw token */
+#define CMDQ_SYNC_TOKEN_MSS				985
+#define CMDQ_SYNC_TOKEN_MSF				986
+
+/* GPR access tokens (for register backup)
+ * There are 15 32-bit GPR, 3 GPR form a set
+ * (64-bit for address, 32-bit for value)
+ * MUST NOT CHANGE, these tokens sync with MDP
+ */
+#define CMDQ_SYNC_TOKEN_GPR_SET_0			987
+#define CMDQ_SYNC_TOKEN_GPR_SET_1			988
+#define CMDQ_SYNC_TOKEN_GPR_SET_2			989
+#define CMDQ_SYNC_TOKEN_GPR_SET_3			990
+#define CMDQ_SYNC_TOKEN_GPR_SET_4			991
+
+/* Resource lock event to control resource in GCE thread */
+#define CMDQ_SYNC_RESOURCE_WROT0			992
+#define CMDQ_SYNC_RESOURCE_WROT1			993
+
+/* Event for gpr timer, used in sleep and poll with timeout */
+#define CMDQ_TOKEN_GPR_TIMER_R0				996
+#define CMDQ_TOKEN_GPR_TIMER_R1				997
+#define CMDQ_TOKEN_GPR_TIMER_R2				998
+#define CMDQ_TOKEN_GPR_TIMER_R3				999
+#define CMDQ_TOKEN_GPR_TIMER_R4				1000
+#define CMDQ_TOKEN_GPR_TIMER_R5				1001
+#define CMDQ_TOKEN_GPR_TIMER_R6				1002
+#define CMDQ_TOKEN_GPR_TIMER_R7				1003
+#define CMDQ_TOKEN_GPR_TIMER_R8				1004
+#define CMDQ_TOKEN_GPR_TIMER_R9				1005
+#define CMDQ_TOKEN_GPR_TIMER_R10			1006
+#define CMDQ_TOKEN_GPR_TIMER_R11			1007
+#define CMDQ_TOKEN_GPR_TIMER_R12			1008
+#define CMDQ_TOKEN_GPR_TIMER_R13			1009
+#define CMDQ_TOKEN_GPR_TIMER_R14			1010
+#define CMDQ_TOKEN_GPR_TIMER_R15			1011
+
+/* defined in mtk-cmdq-mailbox.h */
+/* #define CMDQ_EVENT_MAX					0x3ff */
+
+#endif
-- 
2.18.0

From ikjn at chromium.org  Tue Aug 17 19:43:25 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Wed, 18 Aug 2021 10:43:25 +0800
Subject: [RFC PATCH] usb: xhci-mtk: handle bandwidth table rollover
In-Reply-To: <efcd999aaf83cf73ed2f4f4b9efa1bb93efd2523.camel@mediatek.com>
References: <20210809165904.RFC.1.I5165a4a8da5cac23c9928b1ec3c3a1a7383b7c23@changeid>
 <YRDxTodNNqtnpPpn@kroah.com>
 <CAATdQgDSCzZtiDSQk94CYHfSb9Mq28OH7-RdaTZNv3oPrW3nkQ@mail.gmail.com>
 <7b48f4c132a8b4b3819282e961fbe8b3ed753069.camel@mediatek.com>
 <CAATdQgD1paUUmWhiLVq-+zq0V6=RTJw89ggk=R6cBUZO+5dB-Q@mail.gmail.com>
 <efcd999aaf83cf73ed2f4f4b9efa1bb93efd2523.camel@mediatek.com>
Message-ID: <CAATdQgC_aukAA3-=cuiOAQGzu_Ztvo4BsMbRv2hCGZpUeOAJVg@mail.gmail.com>

Hi Chunfeng,

On Thu, Aug 12, 2021 at 7:49 PM Chunfeng Yun (???)
<Chunfeng.Yun at mediatek.com> wrote:
>
> On Thu, 2021-08-12 at 17:31 +0800, Ikjoon Jang wrote:
> > HI,
> >
> > On Wed, Aug 11, 2021 at 5:02 PM Chunfeng Yun (???)
> > <Chunfeng.Yun at mediatek.com> wrote:
> > >
> > > On Mon, 2021-08-09 at 17:42 +0800, Ikjoon Jang wrote:
> > > > On Mon, Aug 9, 2021 at 5:11 PM Greg Kroah-Hartman
> > > > <gregkh at linuxfoundation.org> wrote:
> > > > >
> > > > > On Mon, Aug 09, 2021 at 04:59:29PM +0800, Ikjoon Jang wrote:
> > > > > > xhci-mtk has 64 slots for periodic bandwidth calculations and
> > > > > > each
> > > > > > slot represents byte budgets on a microframe. When an
> > > > > > endpoint's
> > > > > > allocation sits on the boundary of the table, byte budgets'
> > > > > > slot
> > > > > > should be rolled over but the current implementation doesn't.
> > > > > >
> > > > > > This patch applies a 6 bits mask to the microframe index to
> > > > > > handle
> > > > > > its rollover 64 slots and prevent out-of-bounds array access.
> > > > > >
> > > > > > Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
> > > > > > ---
> > > > > >
> > > > > >  drivers/usb/host/xhci-mtk-sch.c | 79 +++++++++------------
> > > > > > ----
> > > > > > --------
> > > > > >  drivers/usb/host/xhci-mtk.h     |  1 +
> > > > > >  2 files changed, 23 insertions(+), 57 deletions(-)
> > > > >
> > > > > Why is this "RFC"?  What needs to be addressed in this change
> > > > > before it
> > > > > can be accepted?
> > > >
> > > > sorry, I had to mention why this is RFC:
> > > >
> > > > I simply don't know about the details of the xhci-mtk internals.
> > > > It was okay from my tests with mt8173 and I think this will be
> > > > harmless
> > > > as this is "better than before".
> > > >
> > > > But when I removed get_esit_boundary(), I really have no idea why
> > > > it was there. I'm wondering if there was another reason of that
> > > > function
> > > > other than just preventing out-of-bounds. Maybe chunfeng can
> > > > answer
> > > > this?
> > >
> > > We use @esit to prevent out-of-bounds array access. it's not a
> > > ring,
> > > can't insert out-of-bounds value into head slot.
> >
> > Thanks, so that function was only for out-of-bounds array access.
> > then I think we just can remove that function and use it as a ring.
> > Can you tell me _why_ it can't be used as a ring?
> Treat it as a period, roll over slot equals to put it into the next
> period.
>
> >
> > I think a transaction (e.g. esit_boundary = 7) can start its first
> > SSPLIT
> > from Y_7 (offset = 7). But will that allocation be matched with this?
> >
> > -               if ((offset + sch_ep->num_budget_microframes) >
> > esit_boundary)
> > -                       break;
> >
> > I mean I'm not sure why this is needed.
> Prevent out-of-bounds.

If it was for preventing drivers from out-of-bound array access,
I couldn't find any reasons why we cannot remove the above lines.
So can I know if it was just for preventing xhci-mtk drivers from
out-of-bounds array access?

If xhci-mtk HC itself can continue the transaction from Y_7 to (Y+1)_n;
including the case of Y==63, I think it's just okay to rollover to (Y+1).

If it's prohibited by xhci-mtk hw, or if you think this patch is not
allowed by any other reasons, can you please  tell me what
kinds of problems can happen with this patch?

Otherwise, please consider minimizing the bw constraints from
xhci-mtk-sch on your side. Note that we're still having other usb
audio headsets which cannot be configured with xhci-mtk
even with this patch.

Thanks.

>
> >
> > Until now, I couldn't find a way to accept the USB audio headset
> > with a configuration of { INT-IN 64 + ISOC-OUT 384 + ISOC-IN 192 }
> > without this patch.
> what is the interval value of each endpoint?
>
> >
> > >
> > > >
> > > > Thanks!
> > > >
> > > > >
> > > > > thanks,
> > > > >
> > > > > greg k-h


From bjorn.andersson at linaro.org  Tue Aug 17 20:44:23 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Tue, 17 Aug 2021 22:44:23 -0500
Subject: [PATCH 29/29] arm64: dts: qcom: Harmonize DWC USB3 DT nodes name
In-Reply-To: <20210815194617.sbrkutxzldqbxfat@mobilestation>
References: <YPf+shNM6cXb3mfe@kroah.com>
 <d853df77-8d36-30b0-dd26-da1bfcb068e0@kernel.org>
 <20210721112531.xvu6ni5ksaehsrjh@mobilestation>
 <CALAqxLViEqSO17P3JGRGYJh-wDoHaJiQQV48zeoRgnar4Xd5Bg@mail.gmail.com>
 <20210722181221.xh3r5kyu7zlcojjx@mobilestation>
 <YPnEO6NVFZDS1s//@yoga>
 <CALAqxLUT0e+mHMVo685oVTxR8y76733cN0yciQ7ePS6GRE+_dg@mail.gmail.com>
 <20210722220918.l7j6zw3aaa27qato@mobilestation>
 <CALAqxLXrs0_Xs0JV5H-wS1q2CJ7XhW5Dj90eu=uazkRXXEMUxQ@mail.gmail.com>
 <20210815194617.sbrkutxzldqbxfat@mobilestation>
Message-ID: <YRyCFx0ZOYTMhinf@builder.lan>

On Sun 15 Aug 14:46 CDT 2021, Serge Semin wrote:

> Hello John
> 
> On Fri, Aug 13, 2021 at 06:06:24PM -0700, John Stultz wrote:
> > On Thu, Jul 22, 2021 at 3:09 PM Serge Semin <fancer.lancer at gmail.com> wrote:
> > > On Thu, Jul 22, 2021 at 01:09:05PM -0700, John Stultz wrote:
> > > > On Thu, Jul 22, 2021 at 12:17 PM Bjorn Andersson
> > > > <bjorn.andersson at linaro.org> wrote:
> > > > > > On Jul 21, 2021, 1:45 PM +0200, Krzysztof Kozlowski wrote:
> > > > > > > I had impression that kernel defines interfaces which should be used and
> > > > > > > are stable (e.g. syscalls, sysfs and so on). This case is example of
> > > > > > > user-space relying on something not being marked as part of ABI. Instead
> > > > > > > they found something working for them and now it is being used in "we
> > > > > > > cannot break existing systems". Basically, AOSP unilaterally created a
> > > > > > > stable ABI and now kernel has to stick to it.
> > > > > > >
> > > > > > > Really, all normal systems depend on aliases or names and here we have
> > > > > > > dependency on device address. I proposed way how AOSP should be fixed.
> > > > > > > Anything happened? Nope.
> > > > > >
> > > > > > First time he sent a possible solution for the problem:
> > > > > > https://lore.kernel.org/lkml/20201221210423.GA2504 at kozik-lap/
> > > > > >
> > > > > > To sum up you could have used one of the more portable approaches
> > > > > > 1. add an udc alias to the controller and use it then to refer to the
> > > > > > corresponding USB controller
> > > > >
> > > > > Is there such a thing as "UDC alias"? Or are you suggesting that we
> > > > > should add such feature?
> > > > >
> > > > > I think it would be wonderful if we could identify the UDCs on our
> > > > > boards as "USB1" and "USB2", or "the one and only USB-C connector". But
> > > > > unless that will fall back to the existing naming it would break John's
> > > > > _existing_ userspace.
> > > >
> > >
> > > > Well, I'd not hold up the existing userspace I'm using as sacrosanct
> > > > (AOSP devices still usually don't have to work cross-kernel versions -
> > > > devboards being the main exception). I'm fine if we can rework
> > > > userland as proposed, so that the issues can be avoided, but I
> > > > honestly don't have enough context to really understand what that
> > > > looks like (no idea what udc aliases are).
> > > >
> > > > And whatever we do, the main constraint is that userland has to be
> > > > able to work with existing LTS kernels and newer kernels.
> > >
> > > As I said in my response to Bjorn even if it is added to the kernel it
> > > won't get to the official LTSes as it would be a new kernel feature.
> > > New features aren't normally backported to the older kernels.
> > >
> > > >
> > > > > > 2. search through DT-nodes looking for a specific compatible/reg
> > > > > > DT-properties.
> > > > > >
> > > > >
> > > > > We could define that this is the way, but again we didn't yesterday so
> > > > > your proposal is not backwards compatible.
> > > >
> > >
> > > > It may be backwards compatible, but I'm still not clear exactly how it
> > > > would work.
> > > >
> > > > I guess if we look through all
> > > > sys/bus/platform/devices/*/of_node/compatbile strings for the desired
> > > > "snps,dwc3", then find which of the directories have the desired
> > > > address in the string? (The suggestion for looking at reg seems
> > > > better, but I don't get a char value out of the dwc3 of_node/reg
> > > > file).
> > >
> > > The algorithm is simple:
> > > 1) You know what USB controllers you have on your platform. They are
> > > supposed to be compatible with snps,dwc3 string and have some pre-defined
> > > base address.
> > > 2) Find all the files in the directory /sys/class/udc/.
> > > 3) Walk through all the directories in /sys/bus/platform/devices/ with
> > > names found in 2) and stop on the device with matching compatible/base
> > > address defined in 1).
> > >
> > > In my case the strings could be retrieved like this:
> > > USB_NAME_COMPAT=$(/sys/bus/platform/devices/1f100000.usb/of_node/compatible | tr '\0' '\t' | cut -f1)
> > > USB_DEVICE_ADDR="$(head -c 4 /sys/bus/platform/devices/1f100000.usb/of_node/reg | hexdump -ve '/1 "%02x"' | sed -e 's/^0*//g')"
> > 
> > 
> 
> > Hey Serge,
> >    I just wanted to follow up here.  Amit has reworked the db845c AOSP
> > userland so that it no longer uses the fixed node name, but instead
> > probes for it:
> >   https://android-review.googlesource.com/c/device/linaro/dragonboard/+/1774872
> > 
> > Admittedly, it does take a short-cut.  As your algorithm above,
> > digging up the devices and finding the sys/bus path to read the reg
> > value and pipe through hexdump (which android doesn't have) seemed
> > overly obtuse when the address is in the node name itself (while the
> > only way to be sure, one normally doesn't use spectroscopy to
> > determine the value of a coin when you can read what's printed on it
> > :).  But, should the node naming be further changed at least the
> > infrastructure we have can be reworked fairly easily to adapt now.
> > 
> > In any case, as we can handle the name change now, if you want to
> > resubmit your patch, we would no longer object (but can't promise no
> > one else might be bitten).  Sorry for the delay this caused, and we
> > appreciate you working with us to find a solution.
> 
> Great! Thanks for sending the notification. I'll resend the patch with a
> reference to your report and to the update made to AOSP, as soon as I
> am done with my current task.
> 

Amit's change makes future versions of AOSP able to cope with changes in
the UDC name, unfortunately it doesn't change the fact that renaming the
node breaks compatibility in non-Android user space (or any existing
branches/tags of AOSP).

Regards,
Bjorn


From ck.hu at mediatek.com  Tue Aug 17 21:42:09 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Wed, 18 Aug 2021 12:42:09 +0800
Subject: [RFC PATCH 5/5] drm/mediatek: Add mt8195 DisplayPort driver
In-Reply-To: <20210816192523.1739365-6-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-6-msp@baylibre.com>
Message-ID: <1629261729.11678.2.camel@mtksdaap41>

Hi, Markus:

On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports both functional units on the mt8195, the embedded
> DisplayPort as well as the external DisplayPort units. It offers
> hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with up
> to 4 lanes.
> 
> This driver is based on an initial version by
> Jason-JH.Lin <jason-jh.lin at mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>  drivers/gpu/drm/mediatek/Kconfig      |    7 +
>  drivers/gpu/drm/mediatek/Makefile     |    2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c     | 3025 ++++++++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h | 3095 +++++++++++++++++++++++++
>  4 files changed, 6129 insertions(+)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
> 
> diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig
> index 2976d21e9a34..d81eb3521c1c 100644
> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -28,3 +28,10 @@ config DRM_MEDIATEK_HDMI
>  	select PHY_MTK_HDMI
>  	help
>  	  DRM/KMS HDMI driver for Mediatek SoCs
> +
> +config MTK_DPTX_SUPPORT
> +	tristate "DRM DPTX Support for Mediatek SoCs"
> +	depends on DRM_MEDIATEK
> +	select GENERIC_PHY

Why select GENERIC_PHY?
If this is a phy driver, place this driver in drivers/phy/mediatek/

Regards,
CK

> +	help
> +	  DRM/KMS Display Port driver for Mediatek SoCs.
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index dc54a7a69005..6b9d148ab7fe 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -20,3 +20,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
>  			  mtk_hdmi_ddc.o
>  



From ck.hu at mediatek.com  Tue Aug 17 21:45:46 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Wed, 18 Aug 2021 12:45:46 +0800
Subject: [RFC PATCH 1/5] dt-bindings: mediatek,dpi: Add mt8195 dpintf
In-Reply-To: <20210816192523.1739365-2-msp@baylibre.com>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-2-msp@baylibre.com>
Message-ID: <1629261946.11678.5.camel@mtksdaap41>

Hi, Markus:

On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> DP_INTF is similar to the actual dpi. They differ in some points
> regarding registers and what needs to be set but the function blocks
> itself are similar in design.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> ---
>  .../display/mediatek/mediatek,dpi.yaml        | 48 ++++++++++++++++---
>  1 file changed, 42 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> index dd2896a40ff0..de4bdacd83ac 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> @@ -4,7 +4,7 @@
>  $id: https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml*__;Iw!!CTRNKA9wMg0ARbw!z5TyPvbq3ZLHjRPscOHigUMlikjhtJMFrEQqemcjQZa4NaXBE9tzMnDFMa1qYg$ 
>  $schema: https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!z5TyPvbq3ZLHjRPscOHigUMlikjhtJMFrEQqemcjQZa4NaXBE9tzMnAjuBCxsg$ 
> 
> -title: mediatek DPI Controller Device Tree Bindings
> +title: mediatek DPI/DP_INTF Controller Device Tree Bindings
>  
>  maintainers:
>    - CK Hu <ck.hu at mediatek.com>
> @@ -13,7 +13,8 @@ maintainers:
>  description: |
>    The Mediatek DPI function block is a sink of the display subsystem and
>    provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
> -  output bus.
> +  output bus. The Mediatek DP_INTF is a similar function block that is
> +  connected to the (embedded) display port function block.
>  
>  properties:
>    compatible:
> @@ -23,6 +24,7 @@ properties:
>        - mediatek,mt8173-dpi
>        - mediatek,mt8183-dpi
>        - mediatek,mt8192-dpi
> +      - mediatek,mt8195-dpintf

I've reviewed the modification in driver, it seems that dpintf is almost
the same as dpi. Why use the name "dpintf"? I could accept this name
only it's defined by hardware data sheet.

Regards,
CK

>  
>    reg:
>      maxItems: 1
> @@ -37,10 +39,11 @@ properties:
>        - description: DPI PLL
>  
>    clock-names:
> -    items:
> -      - const: pixel
> -      - const: engine
> -      - const: pll
> +    description:
> +      For dpi clocks pixel, engine and pll are required. For dpintf pixel, pll,
> +      pll_d2, pll_d4, pll_d8, pll_d16, hf_fmm, hf_fdp are required.
> +    minItems: 3
> +    maxItems: 8
>  
>    pinctrl-0: true
>    pinctrl-1: true
> @@ -64,6 +67,39 @@ required:
>    - clock-names
>    - port
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - mediatek,mt8195-dpintf
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 8
> +          maxItems: 8
> +        clock-names:
> +          items:
> +            - const: pixel
> +            - const: pll
> +            - const: pll_d2
> +            - const: pll_d4
> +            - const: pll_d8
> +            - const: pll_d16
> +            - const: hf_fmm
> +            - const: hf_fdp
> +    else:
> +      properties:
> +        clocks:
> +          minItems: 3
> +          maxItems: 3
> +        clock-names:
> +          items:
> +            - const: pixel
> +            - const: engine
> +            - const: pll
> +
>  additionalProperties: false
>  
>  examples:


From Claudiu.Beznea at microchip.com  Tue Aug 17 22:12:51 2021
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Wed, 18 Aug 2021 05:12:51 +0000
Subject: [PATCH] clk/at91: remove kernel-doc warnings in sama7g5.c
In-Reply-To: <20210810005431.22007-1-rdunlap@infradead.org>
References: <20210810005431.22007-1-rdunlap@infradead.org>
Message-ID: <1670a11e-98d8-1b55-34c0-3369aaa8a615@microchip.com>

Hi Randy,

On 10.08.2021 03:54, Randy Dunlap wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Fix multiple kernel-doc warnings in sama7g5.c. There are several
> enums and structs that were not identified as such.
> There are also several anonymous structs (that scripts/kernel-doc
> has problems with), so add struct names to them.
> 
> Fixes the following warnings:
> 
> drivers/clk/at91/sama7g5.c:39: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>  * PLL clocks identifiers
> drivers/clk/at91/sama7g5.c:60: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>  * PLL type identifiers
> drivers/clk/at91/sama7g5.c:122: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>  * PLL clocks description
> drivers/clk/at91/sama7g5.c:289: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>  * Master clock (MCK[1..4]) description
> drivers/clk/at91/sama7g5.c:341: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>  * System clock description
> drivers/clk/at91/sama7g5.c:365: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>  * Peripheral clock description
> drivers/clk/at91/sama7g5.c:453: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>  * Generic clock description
> drivers/clk/at91/sama7g5.c:339: warning: Function parameter or member 'ep_chg_id' not described in 'master_clock'
> 
> Some kernel-doc warnings are still printed, but they are all due to
> problems in the kernel-doc script (if anyone is interested in playing
> with some Perl :). These warnings are:
> 
> sama7g5.c:287: warning: Function parameter or member '{' not described in 'sama7g5_plls'
> sama7g5.c:287: warning: Function parameter or member '' not described in 'sama7g5_plls'
> sama7g5.c:287: warning: Function parameter or member '}' not described in 'sama7g5_plls'
> sama7g5.c:339: warning: Function parameter or member 'sama7g5_mckx' not described in 'master_clock'
> sama7g5.c:339: warning: Function parameter or member '}' not described in 'master_clock'
> sama7g5.c:360: warning: Function parameter or member 'sama7g5_systemck' not described in 'system_clock'
> sama7g5.c:451: warning: Function parameter or member 'sama7g5_periphck' not described in 'periph_clock'
> sama7g5.c:451: warning: Function parameter or member '' not described in 'periph_clock'
> sama7g5.c:451: warning: Function parameter or member '}' not described in 'periph_clock'
> sama7g5.c:841: warning: Function parameter or member 'sama7g5_gck' not described in 'generic_clock'
> sama7g5.c:841: warning: Function parameter or member '}' not described in 'generic_clock'

What about keeping only one '*' instead of '**' where necessary as these
data structures are only local to sama7g5.c file (according to
Documentation/doc-guide/kernel-doc.rst "Functions and data structures in
header files which are intended to be used by modules should also have
kernel-doc comments."). This way all the warnings will be gone.

Thank you,
Claudiu Beznea

> 
> Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
> Reported-by: kernel test robot <lkp at intel.com>
> Cc: Claudiu Beznea <claudiu.beznea at microchip.com>
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: Eugen Hristev <eugen.hristev at microchip.com>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: Jonathan Corbet <corbet at lwn.net>
> ---
>  drivers/clk/at91/sama7g5.c |   27 ++++++++++++++-------------
>  1 file changed, 14 insertions(+), 13 deletions(-)
> 
> --- linux-next-20210809.orig/drivers/clk/at91/sama7g5.c
> +++ linux-next-20210809/drivers/clk/at91/sama7g5.c
> @@ -36,7 +36,7 @@ static DEFINE_SPINLOCK(pmc_mck0_lock);
>  static DEFINE_SPINLOCK(pmc_mckX_lock);
> 
>  /**
> - * PLL clocks identifiers
> + * enum pll_ids - PLL clocks identifiers
>   * @PLL_ID_CPU:                CPU PLL identifier
>   * @PLL_ID_SYS:                System PLL identifier
>   * @PLL_ID_DDR:                DDR PLL identifier
> @@ -44,6 +44,7 @@ static DEFINE_SPINLOCK(pmc_mckX_lock);
>   * @PLL_ID_BAUD:       Baud PLL identifier
>   * @PLL_ID_AUDIO:      Audio PLL identifier
>   * @PLL_ID_ETH:                Ethernet PLL identifier
> + * @PLL_ID_MAX:                Number of PLL_ID values (1 more than the last valid PLL_ID)
>   */
>  enum pll_ids {
>         PLL_ID_CPU,
> @@ -57,7 +58,7 @@ enum pll_ids {
>  };
> 
>  /**
> - * PLL type identifiers
> + * enum pll_type - PLL type identifiers
>   * @PLL_TYPE_FRAC:     fractional PLL identifier
>   * @PLL_TYPE_DIV:      divider PLL identifier
>   */
> @@ -119,7 +120,7 @@ static const struct clk_pll_characterist
>  };
> 
>  /**
> - * PLL clocks description
> + * struct sama7g5_plls - PLL clocks description
>   * @n:         clock name
>   * @p:         clock parent
>   * @l:         clock layout
> @@ -128,7 +129,7 @@ static const struct clk_pll_characterist
>   * @f:         clock flags
>   * @eid:       export index in sama7g5->chws[] array
>   */
> -static const struct {
> +static const struct sama7g5_plls {
>         const char *n;
>         const char *p;
>         const struct clk_pll_layout *l;
> @@ -286,17 +287,17 @@ static const struct {
>  };
> 
>  /**
> - * Master clock (MCK[1..4]) description
> + * struct master_clock - Master clock (MCK[1..4]) description
>   * @n:                 clock name
>   * @ep:                        extra parents names array
> - * @ep_chg_chg_id:     index in parents array that specifies the changeable
> + * @ep_chg_id:         index in parents array that specifies the changeable
>   *                     parent
>   * @ep_count:          extra parents count
>   * @ep_mux_table:      mux table for extra parents
>   * @id:                        clock id
>   * @c:                 true if clock is critical and cannot be disabled
>   */
> -static const struct {
> +static const struct master_clock {
>         const char *n;
>         const char *ep[4];
>         int ep_chg_id;
> @@ -338,12 +339,12 @@ static const struct {
>  };
> 
>  /**
> - * System clock description
> + * struct system_clock - System clock description
>   * @n: clock name
>   * @p: clock parent name
>   * @id: clock id
>   */
> -static const struct {
> +static const struct system_clock {
>         const char *n;
>         const char *p;
>         u8 id;
> @@ -362,14 +363,14 @@ static const struct {
>  static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, };
> 
>  /**
> - * Peripheral clock description
> + * struct periph_clock - Peripheral clock description
>   * @n:         clock name
>   * @p:         clock parent name
>   * @r:         clock range values
>   * @id:                clock id
>   * @chgp:      index in parent array of the changeable parent
>   */
> -static const struct {
> +static const struct periph_clock {
>         const char *n;
>         const char *p;
>         struct clk_range r;
> @@ -450,7 +451,7 @@ static const struct {
>  };
> 
>  /**
> - * Generic clock description
> + * struct generic_clock - Generic clock description
>   * @n:                 clock name
>   * @pp:                        PLL parents
>   * @pp_mux_table:      PLL parents mux table
> @@ -459,7 +460,7 @@ static const struct {
>   * @pp_count:          PLL parents count
>   * @id:                        clock id
>   */
> -static const struct {
> +static const struct generic_clock {
>         const char *n;
>         const char *pp[8];
>         const char pp_mux_table[8];
> 


From rdunlap at infradead.org  Tue Aug 17 22:32:37 2021
From: rdunlap at infradead.org (Randy Dunlap)
Date: Tue, 17 Aug 2021 22:32:37 -0700
Subject: [PATCH] clk/at91: remove kernel-doc warnings in sama7g5.c
In-Reply-To: <1670a11e-98d8-1b55-34c0-3369aaa8a615@microchip.com>
References: <20210810005431.22007-1-rdunlap@infradead.org>
 <1670a11e-98d8-1b55-34c0-3369aaa8a615@microchip.com>
Message-ID: <29f0b5d0-d9ab-6ef3-b280-ba3d64c8d828@infradead.org>

On 8/17/21 10:12 PM, Claudiu.Beznea at microchip.com wrote:
> Hi Randy,
> 
> On 10.08.2021 03:54, Randy Dunlap wrote:
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>
>> Fix multiple kernel-doc warnings in sama7g5.c. There are several
>> enums and structs that were not identified as such.
>> There are also several anonymous structs (that scripts/kernel-doc
>> has problems with), so add struct names to them.
>>
>> Fixes the following warnings:
>>
>> drivers/clk/at91/sama7g5.c:39: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>>   * PLL clocks identifiers
>> drivers/clk/at91/sama7g5.c:60: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>>   * PLL type identifiers
>> drivers/clk/at91/sama7g5.c:122: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>>   * PLL clocks description
>> drivers/clk/at91/sama7g5.c:289: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>>   * Master clock (MCK[1..4]) description
>> drivers/clk/at91/sama7g5.c:341: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>>   * System clock description
>> drivers/clk/at91/sama7g5.c:365: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>>   * Peripheral clock description
>> drivers/clk/at91/sama7g5.c:453: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
>>   * Generic clock description
>> drivers/clk/at91/sama7g5.c:339: warning: Function parameter or member 'ep_chg_id' not described in 'master_clock'
>>
>> Some kernel-doc warnings are still printed, but they are all due to
>> problems in the kernel-doc script (if anyone is interested in playing
>> with some Perl :). These warnings are:
>>
>> sama7g5.c:287: warning: Function parameter or member '{' not described in 'sama7g5_plls'
>> sama7g5.c:287: warning: Function parameter or member '' not described in 'sama7g5_plls'
>> sama7g5.c:287: warning: Function parameter or member '}' not described in 'sama7g5_plls'
>> sama7g5.c:339: warning: Function parameter or member 'sama7g5_mckx' not described in 'master_clock'
>> sama7g5.c:339: warning: Function parameter or member '}' not described in 'master_clock'
>> sama7g5.c:360: warning: Function parameter or member 'sama7g5_systemck' not described in 'system_clock'
>> sama7g5.c:451: warning: Function parameter or member 'sama7g5_periphck' not described in 'periph_clock'
>> sama7g5.c:451: warning: Function parameter or member '' not described in 'periph_clock'
>> sama7g5.c:451: warning: Function parameter or member '}' not described in 'periph_clock'
>> sama7g5.c:841: warning: Function parameter or member 'sama7g5_gck' not described in 'generic_clock'
>> sama7g5.c:841: warning: Function parameter or member '}' not described in 'generic_clock'
> 
> What about keeping only one '*' instead of '**' where necessary as these
> data structures are only local to sama7g5.c file (according to
> Documentation/doc-guide/kernel-doc.rst "Functions and data structures in
> header files which are intended to be used by modules should also have
> kernel-doc comments."). This way all the warnings will be gone.

Sure, that works too.
I'll send an updated patch.

thanks.
-- 
~Randy



From lakshmi.sai.krishna.potthuri at xilinx.com  Tue Aug 17 22:53:19 2021
From: lakshmi.sai.krishna.potthuri at xilinx.com (Sai Krishna Potthuri)
Date: Wed, 18 Aug 2021 11:23:19 +0530
Subject: [PATCH] pinctrl: pinctrl-zynq: Add warning for not to use
 'io-standard'
Message-ID: <1629265999-33358-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>

This patch add warning message saying 'io-standard' property is deprecated
and instead use 'power-source' property for configuring power supplies.
This gives an indication for Zynq pinctrl users to migrate to use
'power-source' property.

Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
---
 drivers/pinctrl/pinctrl-zynq.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c
index a96af8a..5b269b6 100644
--- a/drivers/pinctrl/pinctrl-zynq.c
+++ b/drivers/pinctrl/pinctrl-zynq.c
@@ -1028,6 +1028,8 @@ static int zynq_pinconf_cfg_get(struct pinctrl_dev *pctldev,
 		break;
 	}
 	case PIN_CONFIG_IOSTANDARD:
+		dev_warn(pctldev->dev, "io-standard is deprecated, please use power-source");
+		fallthrough;
 	case PIN_CONFIG_POWER_SOURCE:
 		arg = zynq_pinconf_iostd_get(reg);
 		break;
@@ -1079,6 +1081,8 @@ static int zynq_pinconf_cfg_set(struct pinctrl_dev *pctldev,
 
 			break;
 		case PIN_CONFIG_IOSTANDARD:
+			dev_warn(pctldev->dev, "io-standard is deprecated, please use power-source");
+			fallthrough;
 		case PIN_CONFIG_POWER_SOURCE:
 			if (arg <= zynq_iostd_min || arg >= zynq_iostd_max) {
 				dev_warn(pctldev->dev,
-- 
2.1.1



From inki.dae at samsung.com  Tue Aug 17 23:09:16 2021
From: inki.dae at samsung.com (Inki Dae)
Date: Wed, 18 Aug 2021 15:09:16 +0900
Subject: [RFC PATCH 06/17] drm/exynos: dsi: Handle exynos specifics via
 driver_data
In-Reply-To: <YRZioZvYrU99fQxJ@pendragon.ideasonboard.com>
References: <20210704090230.26489-1-jagan@amarulasolutions.com>
 <20210704090230.26489-7-jagan@amarulasolutions.com>
 <CGME20210725172551epcas1p31dff839439ac37757cf061405b5ac65c@epcas1p3.samsung.com>
 <YP2el40V3K4R7ner@ravnborg.org>
 <79ef7f71-b167-2368-e0fd-d4ccaee596c2@samsung.com>
 <YRZioZvYrU99fQxJ@pendragon.ideasonboard.com>
Message-ID: <9165278a-547f-cb11-9609-ecf498192db7@samsung.com>

Hi Laurent,

21. 8. 13. ?? 9:16? Laurent Pinchart ?(?) ? ?:
> Hi Inki,
> 
> On Fri, Aug 13, 2021 at 03:50:56PM +0900, Inki Dae wrote:
>> 21. 7. 26. ?? 2:25? Sam Ravnborg ?(?) ? ?:
>>> On Sun, Jul 04, 2021 at 02:32:19PM +0530, Jagan Teki wrote:
>>>> Exynos DSI driver is actually a Samsung MIPI DSIM bridge
>>>> IP which is also used in i.MX8MM platforms.
>>>>
>>>> Right now the existing driver has some exynos drm specific
>>>> code bases like te_irq, crtc and component_ops.
>>>>
>>>> In order to switch this driver into a common bridge driver
>>>> We can see 2 options to handle the exynos specific code.
>>>>
>>>> A. Drop the component_ops, and rework other specifics.
>>>>    This may lead to more foundation work as it requires
>>>>    more changes in exynos drm drivers stack.
>>>>
>>>> B. Handle the exynos specifics via driver data, and make
>>>>    the common bridge work in different platforms and plan
>>>>    for option A in future.
>>>>
>>>> So, this patch is trying to add option B) changes to handle
>>>> exynos specifics via driver_data.
>>>
>>> We really should find someone that has the time, energy, knowledge and
>>> hardware that can include device_link support once anf for all for
>>> bridges.
>>> Then we would avoid hacks like this.
>>>
>>> I see no other options at the moment, but look forward for a better
>>> solution.
>>
>> I'm not sure that it's correct to share this mipi dsi driver with
>> I.MX8MM SoC even though it's a same IP because this MIPI DSI device
>> isn't peripheral device but in SoC.
>>
>> It would mean that Exynos MIPI DSI device depends on SoC architecture,
>> and Exynos and I.MX series are totally different SoC. So if we share
>> the same driver for the MIPI DSI device then many things we didn't
>> predict may happen in the future.
> 
> Isn't that true for external components true thought ? Any driver shared
> by multiple systems will face this issue, where it will be developed
> with some use cases in mind, and regressions may happen when the driver
> is then extended to support other use cases not required for the
> original platform.
> 
> In general we don't want multiple drivers for the same IP core unless
> there are valid technical reasons for that. It's the whole point of the
> device tree, being able to describe how IP cores are integrated, so that
> code can be reused across platforms. Of course, integration differences
> between SoCs can sometimes vary wildly and require some amount of glue
> code.

Agree with you. It would be a good chance to clarify what we need to share same device driver without any regress in this time.

> 
>> I don't want to make Jagan's efforts
>> in vain for the community but clarify whether this is correct way or
>> not. If this is only the way we have to go then we could more focus on
>> actual solution not such hack. Impossible work with Jagan alone I
>> think.
> 
> I do agree that we need more correct solutions and less hacks in general
> :-) The issues faced on Exynos also exist on other platforms, so it
> would be much better to solve them well once that duplicating
> implementations with less test coverage and reviews. There have been
> efforts in the past to address some of these issues, which have resulted
> in solutions such as the component framework. However, I'd argued that

Yeah, most of ARM systems have various separate devices but DRM subsytem wanted each ARM driver to work like one device driver for all of them. And the component framework has been adopted by several ARM DRM drivers for it including Exynos.

> we've never taken it to the last step, and have always stopped with half
> solutions. The component framework, for instance, is painful to use, and
> the handling of .remove() in most drivers is completely broken because
> of that (not just because of that though, we have issues in the DRM core
> that make hot-unplug just impossible to handle safetly).

This may be one of what we have to clarify. I think ARM DRM drivers need component framework or similar thing to address probing order issue.
So would we need to enhance existing compoent framework to be suitable for DRM subsystem, or introducing an alternative solution?

Otherwise, would there be some way to address the probing order issue without the compoment framework?

> 
>> So let's get started with a question,
>> - Is MIPI-DSI bridge device or Encoder device? I think that MIPI-DSI
>> is a Encoder device managed by atomic KMS. If MIPI-DSI should be
>> handled as bridge device then does now drm bridge framework provide
>> everything to share one driver with one more SoC? I mean something
>> that drm bridge has to consider for such driver support, which is
>> shared with one more SoC.
> 
> The DRM "encoder" concept was a bit of a historical mistake that we are
> stuck with as drm_encoder is exposed to userspace. It comes from a time
> where nobody was envisioning chaining multiple encoders. DRM is moving
> to modelling every component after the CRTC as a bridge. This brings

Thanks for explanation and seems correct direction. :) However, there would be something we have to address before changing the existing modeling because any regress shouldn't be allowed.

Thanks,
Inki Dae

> much more flexibility, and in that model, the drm_encoder becomes more
> or less a stub.
> 
> The DRM bridge API has been extended in the past to support more
> features, and if anything is still missing that makes it difficult to
> move away from drm_encoder, we can of course address the issues in
> drm_bridge.
> 
>> And Display mode - VIDEO and COMMAND mode - is generic type of MIPI
>> DSI, and also componentised subsystem is a generic solution to resolve
>> probing order issue not Exynos specific feature. These are driver
>> specific ones not Exynos SoC I think. As SoC specific things should be
>> considered, I think MIPI DSI Driver - interrupt handler and probing
>> order things are really specific to device driver - should be
>> separated but we could share the control part of the device.
>>
>> I was busy with other projects so didn't care of Linux DRM world so
>> there may be my missing something.
>>
>>>> Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
>>>> ---
>>>>  drivers/gpu/drm/exynos/exynos_drm_dsi.c | 37 +++++++++++++++++++------
>>>>  1 file changed, 29 insertions(+), 8 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
>>>> index 99a1b8c22313..53d878d4d2d7 100644
>>>> --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
>>>> +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
>>>> @@ -250,6 +250,7 @@ struct exynos_dsi_driver_data {
>>>>  	unsigned int wait_for_reset;
>>>>  	unsigned int num_bits_resol;
>>>>  	const unsigned int *reg_values;
>>>> +	bool exynos_specific;
>>>>  };
>>>>  
>>>>  struct exynos_dsi {
>>>> @@ -459,6 +460,7 @@ static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
>>>>  	.wait_for_reset = 1,
>>>>  	.num_bits_resol = 11,
>>>>  	.reg_values = reg_values,
>>>> +	.exynos_specific = true,
>>>>  };
>>>>  
>>>>  static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
>>>> @@ -471,6 +473,7 @@ static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
>>>>  	.wait_for_reset = 1,
>>>>  	.num_bits_resol = 11,
>>>>  	.reg_values = reg_values,
>>>> +	.exynos_specific = true,
>>>>  };
>>>>  
>>>>  static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
>>>> @@ -481,6 +484,7 @@ static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
>>>>  	.wait_for_reset = 1,
>>>>  	.num_bits_resol = 11,
>>>>  	.reg_values = reg_values,
>>>> +	.exynos_specific = true,
>>>>  };
>>>>  
>>>>  static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
>>>> @@ -492,6 +496,7 @@ static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
>>>>  	.wait_for_reset = 0,
>>>>  	.num_bits_resol = 12,
>>>>  	.reg_values = exynos5433_reg_values,
>>>> +	.exynos_specific = true,
>>>>  };
>>>>  
>>>>  static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
>>>> @@ -503,6 +508,7 @@ static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
>>>>  	.wait_for_reset = 1,
>>>>  	.num_bits_resol = 12,
>>>>  	.reg_values = exynos5422_reg_values,
>>>> +	.exynos_specific = true,
>>>>  };
>>>>  
>>>>  static const struct of_device_id exynos_dsi_of_match[] = {
>>>> @@ -1484,7 +1490,8 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
>>>>  	 * If attached panel device is for command mode one, dsi should register
>>>>  	 * TE interrupt handler.
>>>>  	 */
>>>> -	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
>>>> +	if (dsi->driver_data->exynos_specific &&
>>>> +	    !(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
>>>>  		int ret = exynos_dsi_register_te_irq(dsi, &device->dev);
>>>>  		if (ret)
>>>>  			return ret;
>>>> @@ -1495,8 +1502,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host,
>>>>  	dsi->lanes = device->lanes;
>>>>  	dsi->format = device->format;
>>>>  	dsi->mode_flags = device->mode_flags;
>>>> -	exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
>>>> -			!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
>>>> +	if (dsi->driver_data->exynos_specific)
>>>> +		exynos_drm_crtc_get_by_type(drm, EXYNOS_DISPLAY_TYPE_LCD)->i80_mode =
>>>> +					    !(dsi->mode_flags & MIPI_DSI_MODE_VIDEO);
>>>>  
>>>>  	mutex_unlock(&drm->mode_config.mutex);
>>>>  
>>>> @@ -1515,7 +1523,8 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
>>>>  	if (drm->mode_config.poll_enabled)
>>>>  		drm_kms_helper_hotplug_event(drm);
>>>>  
>>>> -	exynos_dsi_unregister_te_irq(dsi);
>>>> +	if (dsi->driver_data->exynos_specific)
>>>> +		exynos_dsi_unregister_te_irq(dsi);
>>>>  
>>>>  	return 0;
>>>>  }
>>>> @@ -1737,6 +1746,15 @@ static int exynos_dsi_probe(struct platform_device *pdev)
>>>>  	if (ret)
>>>>  		return ret;
>>>>  
>>>> +	if (!dsi->driver_data->exynos_specific) {
>>>> +		ret = mipi_dsi_host_register(&dsi->dsi_host);
>>>> +		if (ret) {
>>>> +			dev_err(dev, "failed to register mipi dsi host: %d\n",
>>>> +				ret);
>>>> +			return ret;
>>>> +		}
>>>> +	}
>>>> +
>>>>  	platform_set_drvdata(pdev, dsi);
>>>>  
>>>>  	pm_runtime_enable(dev);
>>>> @@ -1747,9 +1765,11 @@ static int exynos_dsi_probe(struct platform_device *pdev)
>>>>  
>>>>  	drm_bridge_add(&dsi->bridge);
>>>>  
>>>> -	ret = component_add(dev, &exynos_dsi_component_ops);
>>>> -	if (ret)
>>>> -		goto err_disable_runtime;
>>>> +	if (dsi->driver_data->exynos_specific) {
>>>> +		ret = component_add(dev, &exynos_dsi_component_ops);
>>>> +		if (ret)
>>>> +			goto err_disable_runtime;
>>>> +	}
>>>>  
>>>>  	return 0;
>>>>  
>>>> @@ -1767,7 +1787,8 @@ static int exynos_dsi_remove(struct platform_device *pdev)
>>>>  
>>>>  	pm_runtime_disable(&pdev->dev);
>>>>  
>>>> -	component_del(&pdev->dev, &exynos_dsi_component_ops);
>>>> +	if (dsi->driver_data->exynos_specific)
>>>> +		component_del(&pdev->dev, &exynos_dsi_component_ops);
>>>>  
>>>>  	return 0;
>>>>  }
> 


From michal.simek at xilinx.com  Tue Aug 17 23:00:03 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Wed, 18 Aug 2021 08:00:03 +0200
Subject: [PATCH] pinctrl: pinctrl-zynq: Add warning for not to use
 'io-standard'
In-Reply-To: <1629265999-33358-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
References: <1629265999-33358-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
Message-ID: <447d7205-f562-72c2-8317-031cd733d60c@xilinx.com>



On 8/18/21 7:53 AM, Sai Krishna Potthuri wrote:
> This patch add warning message saying 'io-standard' property is deprecated
> and instead use 'power-source' property for configuring power supplies.
> This gives an indication for Zynq pinctrl users to migrate to use
> 'power-source' property.
> 
> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> ---
>  drivers/pinctrl/pinctrl-zynq.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c
> index a96af8a..5b269b6 100644
> --- a/drivers/pinctrl/pinctrl-zynq.c
> +++ b/drivers/pinctrl/pinctrl-zynq.c
> @@ -1028,6 +1028,8 @@ static int zynq_pinconf_cfg_get(struct pinctrl_dev *pctldev,
>  		break;
>  	}
>  	case PIN_CONFIG_IOSTANDARD:
> +		dev_warn(pctldev->dev, "io-standard is deprecated, please use power-source");
> +		fallthrough;
>  	case PIN_CONFIG_POWER_SOURCE:
>  		arg = zynq_pinconf_iostd_get(reg);
>  		break;
> @@ -1079,6 +1081,8 @@ static int zynq_pinconf_cfg_set(struct pinctrl_dev *pctldev,
>  
>  			break;
>  		case PIN_CONFIG_IOSTANDARD:
> +			dev_warn(pctldev->dev, "io-standard is deprecated, please use power-source");
> +			fallthrough;
>  		case PIN_CONFIG_POWER_SOURCE:
>  			if (arg <= zynq_iostd_min || arg >= zynq_iostd_max) {
>  				dev_warn(pctldev->dev,
> 


Acked-by: Michal Simek <michal.simek at xilinx.com>

Linus: would be good to know how long we should keep the support for
this deprecated dt property.

Thanks,
Michal


From wenst at chromium.org  Tue Aug 17 23:25:54 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 18 Aug 2021 14:25:54 +0800
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <CACRpkdYkwXr76Kq5WYdz=1KkLTpaByAL1vJFo8V+2mncqs8-3Q@mail.gmail.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
 <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
 <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>
 <CACRpkdbZKh8cqqiDRUik6Ooo33e+feGwYsLjcLRvBQnT3x5M3A@mail.gmail.com>
 <a7c8ab68ac3513865698cde27e665bdd554f459e.camel@mediatek.com>
 <CAGXv+5FtL2zaSWx4tUymx6mpCSb5dXG4XNWM9AJL+b6Ok3dxMg@mail.gmail.com>
 <d40f6d5fd26aedb13e7a393202e5794b1893ecf8.camel@mediatek.com>
 <CACRpkdYkwXr76Kq5WYdz=1KkLTpaByAL1vJFo8V+2mncqs8-3Q@mail.gmail.com>
Message-ID: <CAGXv+5EUAVFJd7VZsDgpOK_6fhs12ztwKHioghq5ZQHzFKY89w@mail.gmail.com>

On Wed, Aug 18, 2021 at 4:09 AM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Tue, Aug 17, 2021 at 9:51 AM zhiyong.tao <zhiyong.tao at mediatek.com> wrote:
>
> > In one chip, If GPIO is different, the MTXXXX_PULL_UP_RSEL_001 may
> > means different actual bias resistance setting.
> >
> > For example,
> >
> > KPROW IO
> > Paramters       Descriptions                   Min      Typ     Max
> >  UNIT
> > Rpd     Input pull-down resistance      40      75      190     Kohm
> > Rpu     Input pull-up resistance        40      75      190     Kohm
> > Rpd     Input pull-down resistance      0.8     1.6     2       Kohm
> > Rpu     Input pull-up resistance        0.8     1.6     2       Kohm
>
> This is exactly why we should try to use SI units in the device tree.
> I assume that the software can eventually configure which resistance
> it gets?
>
> The electronics people will say make sure it is pulled down by around
> 80 kOhm, they can put that on the device tree and your code can
> say, "hm 40 < 80 < 190 this is OK" and let the value pass.
>
> We do not define these exact semantics, it is up to the driver code
> to decide what to do with the Ohm value 80000 in this case, but
> it makes perfect sent for me to let it pass and fail if someone
> for example requests 20 kOhm, or at least print a helpful warning:
>
> dev_warn(dev, "the requested resistance %d is out of range, supported
> range %d to %d kOhm\n",
>                  val, low, high);
>
> This is what makes the SI units really helpful for people writing device
> trees: solve real integration tasks and make it easy to do the right thing.

I think this makes a lot of sense. The driver could select the closest
setting. And from what Zhiyong mentioned offline, the resistor values
aren't exact as specified in the datasheet. I suppose this is expected
with any electronics. So the hardware integration will say to pull up
or down by some value, and the driver will do its best to fulfill that
request. That precludes DT schema checking for the values used, but I
think that is a good compromise.

Zhiyong also mentioned that some of their downstream integrators might
not be able to deal with actual values, and would prefer symbols tied
to specific RSEL values. I think that would be doable together using
some _magic_ values, but I would prefer not to if it were avoidable.


Regards
ChenYu


From kewei.xu at mediatek.com  Tue Aug 17 23:37:08 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Wed, 18 Aug 2021 14:37:08 +0800
Subject: [PATCH v4 5/8] dt-bindings: i2c: add attribute
 default-timing-adjust
In-Reply-To: <20210722031016.GA3228241@robh.at.kernel.org>
References: <1626517079-9057-1-git-send-email-kewei.xu@mediatek.com>
 <1626517079-9057-6-git-send-email-kewei.xu@mediatek.com>
 <20210722031016.GA3228241@robh.at.kernel.org>
Message-ID: <d89aa91a5231219b5da9940d659d4acfff3ded66.camel@mediatek.com>

On Wed, 2021-07-21 at 21:10 -0600, Rob Herring wrote:
> On Sat, Jul 17, 2021 at 06:17:56PM +0800, Kewei Xu wrote:
> > Add attribute default-timing-adjust for DT-binding document.
> > 
> > Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust
> > support")
> > Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
> > ---
> >  Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
> > b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
> > index 7c4915bc4439..7b80a11d4d4c 100644
> > --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
> > +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
> > @@ -33,6 +33,8 @@ Optional properties:
> >    - mediatek,have-pmic: platform can control i2c form special pmic
> > side.
> >      Only mt6589 and mt8135 support this feature.
> >    - mediatek,use-push-pull: IO config use push-pull mode.
> > +  - mediatek,default-timing-adjust: use default timing
> > calculation, no timing
> > +    adjustment.
> 
> 'mediatek,use-default-timing' perhaps as it means don't adjust
> anything.
> 
> >  
> >  Example:
> >  
> > -- 
> > 2.18.0
> > 
Hi Rob,

Thanks for your suggestion. We will use "mediatek,use-default-timing"
instead of "mediatek,default-timing-adjust" in the next version of
patch.

Thanks
kewei

From krzysztof.kozlowski at canonical.com  Tue Aug 17 23:37:09 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 18 Aug 2021 08:37:09 +0200
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to
 dtschema
In-Reply-To: <dleftjtujnemx7.fsf%l.stelmach@samsung.com>
References: <da43d243-35b0-2cc6-f8a0-a5d02c997301@canonical.com>
 <CGME20210817221734eucas1p2e4a0aa41406137b90e49230371b92ac6@eucas1p2.samsung.com>
 <dleftjtujnemx7.fsf%l.stelmach@samsung.com>
Message-ID: <1960d499-1509-ad42-94d3-f668501fb30b@canonical.com>

On 18/08/2021 00:17, Lukasz Stelmach wrote:
> It was <2021-08-17 wto 16:07>, when Krzysztof Kozlowski wrote:
>> On 17/08/2021 14:34, Lukasz Stelmach wrote:
>>> It was <2021-08-17 wto 12:05>, when Krzysztof Kozlowski wrote:
>>>> On 17/08/2021 11:55, Lukasz Stelmach wrote:
>>>>> It was <2021-08-11 ?ro 10:43>, when Krzysztof Kozlowski wrote:
>>>>>> Convert Samsung Exynos SoC True Random Number Generator bindings to DT
>>>>>> schema format using json-schema.
>>>>>>
>>>>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>>>> ---
>>>>>>  .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
>>>>>>  .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
>>>>>>  MAINTAINERS                                   |  2 +-
>>>>>>  3 files changed, 45 insertions(+), 18 deletions(-)
>>>>>>  delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>>>  create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>>>
>>>>>> diff --git
>>>>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>>> deleted file mode 100644
>>>>>> index 5a613a4ec780..000000000000
>>>>>> --- a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
>>>>>> +++ /dev/null
>>>>>> @@ -1,17 +0,0 @@
>>>>>> -Exynos True Random Number Generator
>>>>>> -
>>>>>> -Required properties:
>>>>>> -
>>>>>> -- compatible  : Should be "samsung,exynos5250-trng".
>>>>>> -- reg         : Specifies base physical address and size of the registers map.
>>>>>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
>>>>>> -- clock-names : "secss" as a clock name.
>>>>>> -
>>>>>> -Example:
>>>>>> -
>>>>>> -	rng at 10830600 {
>>>>>> -		compatible = "samsung,exynos5250-trng";
>>>>>> -		reg = <0x10830600 0x100>;
>>>>>> -		clocks = <&clock CLK_SSS>;
>>>>>> -		clock-names = "secss";
>>>>>> -	};
>>>>>> diff --git
>>>>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>>> new file mode 100644
>>>>>> index 000000000000..a50c34d5d199
>>>>>> --- /dev/null
>>>>>> +++ b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
>>>>>> @@ -0,0 +1,44 @@
>>>>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>>>>>> +%YAML 1.2
>>>>>> +---
>>>>>> +$id:
>>>>>> https://protect2.fireeye.com/v1/url?k=f38ca35b-ac179a0d-f38d2814-0cc47a31ce52-1faa1ecb65482b8a&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Frng%2Fsamsung%2Cexynos5250-trng.yaml%23
>>>>>> +$schema:
>>>>>> https://protect2.fireeye.com/v1/url?k=9409519d-cb9268cb-9408dad2-0cc47a31ce52-12394c4409905980&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>>>>>> +
>>>>>> +title: Samsung Exynos SoC True Random Number Generator
>>>>>> +
>>>>>> +maintainers:
>>>>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>>>> +  - ?ukasz Stelmach <l.stelmach at samsung.com>
>>>>>> +
>>>>>> +properties:
>>>>>> +  compatible:
>>>>>> +    const: samsung,exynos5250-trng
>>>>>> +
>>>>>> +  clocks:
>>>>>> +    maxItems: 1
>>>>>
>>>>> How about copying description from above into the description: property?
>>>>
>>>> But what to copy? There is no description except generic clock bindings.
>>>>
>>>
>>> The description that "was" in the txt file.
>>
>> But there was no description of fields except copy&paste of the core
>> schema. Do you describe C code like:
>>
>> ...
>> /* unsigned int is a integer number greater or equal 0 */
>> unsigned int i;
>> ...
> 
> I believe having descriptions for reg and clocks
> 
>>>>>> -- reg         : Specifies base physical address and size of the registers map.
>>>>>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
> 
> right next to properties' formal definitions is beneficial for anyone
> browsing the YAML file. If you think otherwise, oh well, I am fine with
> that.

Useful descriptions would be beneficial. Descriptions which are copy of
schema, therefore equal to explaining unsigned int, are not beneficial.
Make the document just unnecessarily bigger, are irrelevant and hide
actual important information. One of the principles is to keep things
simple. Duplicating description from schema into specific bindings is
rather the opposite of such approach.


Best regards,
Krzysztof


From m.tretter at pengutronix.de  Tue Aug 17 23:43:42 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 18 Aug 2021 08:43:42 +0200
Subject: [PATCH 0/3] Add support for runtime features
In-Reply-To: <20210817130553.20219-1-ronak.jain@xilinx.com>
References: <20210817130553.20219-1-ronak.jain@xilinx.com>
Message-ID: <20210818064342.GB12231@pengutronix.de>

Hi Ronak,

On Tue, 17 Aug 2021 06:05:50 -0700, Ronak Jain wrote:
> Adds support for runtime feature configuration by using the IOCTL
>  calls. The user can enable or disable as well as can configure the
>  runtime features. The support is added for the over temperature and
>  external watchdog. The user can configure the over temperature limit
>  and external watchdog timer interval at runtime by using PM_IOCTL
>  calls.
> 
> Also, added support for sysfs interface for runtime feature
> configuration for the over temperature and external watchdog features.

Can we have proper kernel drivers instead of the sysfs interface?

Michael

> 
> Ronak Jain (3):
>   firmware: xilinx: Add support for runtime features
>   firmware: zynqmp: Add sysfs entry for runtime features
>   firmware: xilinx: Add sysfs support for feature config
> 
>  .../ABI/stable/sysfs-driver-firmware-zynqmp   | 84 ++++++++++++++++
>  drivers/firmware/xilinx/zynqmp.c              | 98 +++++++++++++++++++
>  include/linux/firmware/xlnx-zynqmp.h          | 25 +++++
>  3 files changed, 207 insertions(+)
> 
> --
> 2.32.0.93.g670b81a
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From krzysztof.kozlowski at canonical.com  Tue Aug 17 23:49:22 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 18 Aug 2021 08:49:22 +0200
Subject: [PATCH v2 1/8] dt-bindings: clock: samsung: convert Exynos5250 to
 dtschema
In-Reply-To: <YRwZG1uerWt+NAQH@robh.at.kernel.org>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-2-krzysztof.kozlowski@canonical.com>
 <YRwZG1uerWt+NAQH@robh.at.kernel.org>
Message-ID: <c7311cd1-7e62-91d9-bbbd-cfc3c027da35@canonical.com>

On 17/08/2021 22:16, Rob Herring wrote:
> On Tue, Aug 10, 2021 at 11:31:38AM +0200, Krzysztof Kozlowski wrote:
>> Convert Samsung Exynos5250 clock controller bindings to DT schema format
>> using json-schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/clock/exynos5250-clock.txt       | 41 ----------------
>>  .../bindings/clock/samsung,exynos-clock.yaml  | 48 +++++++++++++++++++
>>  MAINTAINERS                                   |  1 +
>>  3 files changed, 49 insertions(+), 41 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>> deleted file mode 100644
>> index aff266a12eeb..000000000000
>> --- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>> +++ /dev/null
>> @@ -1,41 +0,0 @@
>> -* Samsung Exynos5250 Clock Controller
>> -
>> -The Exynos5250 clock controller generates and supplies clock to various
>> -controllers within the Exynos5250 SoC.
>> -
>> -Required Properties:
>> -
>> -- compatible: should be one of the following.
>> -  - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
>> -
>> -- reg: physical base address of the controller and length of memory mapped
>> -  region.
>> -
>> -- #clock-cells: should be 1.
>> -
>> -Each clock is assigned an identifier and client nodes can use this identifier
>> -to specify the clock which they consume.
>> -
>> -All available clocks are defined as preprocessor macros in
>> -dt-bindings/clock/exynos5250.h header and can be used in device
>> -tree sources.
>> -
>> -Example 1: An example of a clock controller node is listed below.
>> -
>> -	clock: clock-controller at 10010000 {
>> -		compatible = "samsung,exynos5250-clock";
>> -		reg = <0x10010000 0x30000>;
>> -		#clock-cells = <1>;
>> -	};
>> -
>> -Example 2: UART controller node that consumes the clock generated by the clock
>> -	   controller. Refer to the standard clock bindings for information
>> -	   about 'clocks' and 'clock-names' property.
>> -
>> -	serial at 13820000 {
>> -		compatible = "samsung,exynos4210-uart";
>> -		reg = <0x13820000 0x100>;
>> -		interrupts = <0 54 0>;
>> -		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
>> -		clock-names = "uart", "clk_uart_baud0";
>> -	};
>> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> new file mode 100644
>> index 000000000000..cd6567bd8cc7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> @@ -0,0 +1,48 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/samsung,exynos-clock.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Samsung Exynos SoC clock controller
>> +
>> +maintainers:
>> +  - Chanwoo Choi <cw00.choi at samsung.com>
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
>> +  - Tomasz Figa <tomasz.figa at gmail.com>
>> +
>> +description: |
>> +  All available clocks are defined as preprocessor macros in
>> +  dt-bindings/clock/ headers.
>> +
>> +properties:
>> +  compatible:
>> +    const: samsung,exynos5250-clock
>> +
>> +  assigned-clocks: true
>> +  assigned-clock-parents: true
>> +  assigned-clock-rates: true
> 
> These can be dropped. They are always allowed if 'clocks' is present.
> 
>> +  clocks: true
> 
> This needs to define how many.
> 

Right, thanks.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Aug 17 23:53:07 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 18 Aug 2021 08:53:07 +0200
Subject: [PATCH v2 3/8] dt-bindings: clock: samsung: convert Exynos542x to
 dtschema
In-Reply-To: <YRwaMWChKoasAFYh@robh.at.kernel.org>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-4-krzysztof.kozlowski@canonical.com>
 <YRwaMWChKoasAFYh@robh.at.kernel.org>
Message-ID: <4ac27c04-5ee5-b15c-29bd-fce841429522@canonical.com>

On 17/08/2021 22:21, Rob Herring wrote:
> On Tue, Aug 10, 2021 at 11:31:40AM +0200, Krzysztof Kozlowski wrote:
>> Merge Exynos542x clock controller bindings to existing DT schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/clock/exynos5420-clock.txt       | 42 -------------------
>>  .../bindings/clock/samsung,exynos-clock.yaml  | 11 ++++-
>>  2 files changed, 10 insertions(+), 43 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
>> deleted file mode 100644
>> index 717a7b1531c7..000000000000
>> --- a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
>> +++ /dev/null
>> @@ -1,42 +0,0 @@
>> -* Samsung Exynos5420 Clock Controller
>> -
>> -The Exynos5420 clock controller generates and supplies clock to various
>> -controllers within the Exynos5420 SoC and for the Exynos5800 SoC.
>> -
>> -Required Properties:
>> -
>> -- compatible: should be one of the following.
>> -  - "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
>> -  - "samsung,exynos5800-clock" - controller compatible with Exynos5800 SoC.
>> -
>> -- reg: physical base address of the controller and length of memory mapped
>> -  region.
>> -
>> -- #clock-cells: should be 1.
>> -
>> -Each clock is assigned an identifier and client nodes can use this identifier
>> -to specify the clock which they consume.
>> -
>> -All available clocks are defined as preprocessor macros in
>> -dt-bindings/clock/exynos5420.h header and can be used in device
>> -tree sources.
>> -
>> -Example 1: An example of a clock controller node is listed below.
>> -
>> -	clock: clock-controller at 10010000 {
>> -		compatible = "samsung,exynos5420-clock";
>> -		reg = <0x10010000 0x30000>;
>> -		#clock-cells = <1>;
>> -	};
>> -
>> -Example 2: UART controller node that consumes the clock generated by the clock
>> -	   controller. Refer to the standard clock bindings for information
>> -	   about 'clocks' and 'clock-names' property.
>> -
>> -	serial at 13820000 {
>> -		compatible = "samsung,exynos4210-uart";
>> -		reg = <0x13820000 0x100>;
>> -		interrupts = <0 54 0>;
>> -		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
>> -		clock-names = "uart", "clk_uart_baud0";
>> -	};
>> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> index cd6567bd8cc7..b0f58a1cf6cb 100644
>> --- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> @@ -18,7 +18,16 @@ description: |
>>  
>>  properties:
>>    compatible:
>> -    const: samsung,exynos5250-clock
>> +    oneOf:
>> +      - enum:
>> +          - samsung,exynos5250-clock
>> +          - samsung,exynos5420-clock
>> +          - samsung,exynos5800-clock
>> +      - items:
>> +          - enum:
>> +              - samsung,exynos5420-clock
>> +              - samsung,exynos5800-clock
> 
> Is there a reason these are supported with or without 'syscon'?
> 

Yes, the syscon is optional and needed only by the Exynos5422 DMC driver
(exynos5422-dmc.txt/samsung,exynos5422-dmc.yaml with
samsung,exynos5422-dmc compatible). Without that driver, there is no
need for syscon.


Best regards,
Krzysztof


From pavel at ucw.cz  Wed Aug 18 00:00:01 2021
From: pavel at ucw.cz (Pavel Machek)
Date: Wed, 18 Aug 2021 09:00:01 +0200
Subject: [PATCH 1/2] leds: trigger: remove reference to obsolete
 CONFIG_IDE_GD_ATA
In-Reply-To: <20210804123426.16947-2-lukas.bulwahn@gmail.com>
References: <20210804123426.16947-1-lukas.bulwahn@gmail.com>
 <20210804123426.16947-2-lukas.bulwahn@gmail.com>
Message-ID: <20210818070001.GD22282@amd>

On Wed 2021-08-04 14:34:25, Lukas Bulwahn wrote:
> Commit b7fb14d3ac63 ("ide: remove the legacy ide driver") removes the
> definition of the config IDE_GD_ATA.
> 
> So, remove the obsolete reference in ./drivers/leds/trigger/Kconfig.
> 
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>

Thanks, applied.
								Pavel
								
-- 
http://www.livejournal.com/~pavelmachek
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/f005a211/attachment.sig>

From krzysztof.kozlowski at canonical.com  Wed Aug 18 00:05:04 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 18 Aug 2021 09:05:04 +0200
Subject: [PATCH v2 5/8] dt-bindings: clock: samsung: convert Exynos4 to
 dtschema
In-Reply-To: <YRwa4ehkBUNwJi+I@robh.at.kernel.org>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-6-krzysztof.kozlowski@canonical.com>
 <YRwa4ehkBUNwJi+I@robh.at.kernel.org>
Message-ID: <dcbe2391-b0a4-6e81-77b7-003ac0611ccc@canonical.com>

On 17/08/2021 22:24, Rob Herring wrote:
> On Tue, Aug 10, 2021 at 11:31:42AM +0200, Krzysztof Kozlowski wrote:
>> Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
>> schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/clock/exynos4-clock.txt          | 86 -------------------
>>  .../bindings/clock/samsung,exynos-clock.yaml  | 29 ++++++-
>>  2 files changed, 28 insertions(+), 87 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
>> deleted file mode 100644
>> index 17bb11365354..000000000000
>> --- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
>> +++ /dev/null
>> @@ -1,86 +0,0 @@
>> -* Samsung Exynos4 Clock Controller
>> -
>> -The Exynos4 clock controller generates and supplies clock to various controllers
>> -within the Exynos4 SoC. The clock binding described here is applicable to all
>> -SoC's in the Exynos4 family.
>> -
>> -Required Properties:
>> -
>> -- compatible: should be one of the following.
>> -  - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
>> -  - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
>> -
>> -- reg: physical base address of the controller and length of memory mapped
>> -  region.
>> -
>> -- #clock-cells: should be 1.
>> -
>> -Each clock is assigned an identifier and client nodes can use this identifier
>> -to specify the clock which they consume.
>> -
>> -All available clocks are defined as preprocessor macros in
>> -dt-bindings/clock/exynos4.h header and can be used in device
>> -tree sources.
>> -
>> -Example 1: An example of a clock controller node is listed below.
>> -
>> -	clock: clock-controller at 10030000 {
>> -		compatible = "samsung,exynos4210-clock";
>> -		reg = <0x10030000 0x20000>;
>> -		#clock-cells = <1>;
>> -	};
>> -
>> -Example 2: UART controller node that consumes the clock generated by the clock
>> -	   controller. Refer to the standard clock bindings for information
>> -	   about 'clocks' and 'clock-names' property.
>> -
>> -	serial at 13820000 {
>> -		compatible = "samsung,exynos4210-uart";
>> -		reg = <0x13820000 0x100>;
>> -		interrupts = <0 54 0>;
>> -		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
>> -		clock-names = "uart", "clk_uart_baud0";
>> -	};
>> -
>> -Exynos4412 SoC contains some additional clocks for FIMC-ISP (Camera ISP)
>> -subsystem. Registers for those clocks are located in the ISP power domain.
>> -Because those registers are also located in a different memory region than
>> -the main clock controller, a separate clock controller has to be defined for
>> -handling them.
>> -
>> -Required Properties:
>> -
>> -- compatible: should be "samsung,exynos4412-isp-clock".
>> -
>> -- reg: physical base address of the ISP clock controller and length of memory
>> -  mapped region.
>> -
>> -- #clock-cells: should be 1.
>> -
>> -- clocks: list of the clock controller input clock identifiers,
>> -  from common clock bindings, should point to CLK_ACLK200 and
>> -  CLK_ACLK400_MCUISP clocks from the main clock controller.
>> -
>> -- clock-names: list of the clock controller input clock names,
>> -  as described in clock-bindings.txt, should be "aclk200" and
>> -  "aclk400_mcuisp".
>> -
>> -- power-domains: a phandle to ISP power domain node as described by
>> -  generic PM domain bindings.
>> -
>> -Example 3: The clock controllers bindings for Exynos4412 SoCs.
>> -
>> -	clock: clock-controller at 10030000 {
>> -		compatible = "samsung,exynos4412-clock";
>> -		reg = <0x10030000 0x18000>;
>> -		#clock-cells = <1>;
>> -	};
>> -
>> -	isp_clock: clock-controller at 10048000 {
>> -		compatible = "samsung,exynos4412-isp-clock";
>> -		reg = <0x10048000 0x1000>;
>> -		#clock-cells = <1>;
>> -		power-domains = <&pd_isp>;
>> -		clocks = <&clock CLK_ACLK200>, <&clock CLK_ACLK400_MCUISP>;
>> -		clock-names = "aclk200", "aclk400_mcuisp";
>> -	};
>> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> index c7b07fcd3fa1..ea73201f259b 100644
>> --- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
>> @@ -23,6 +23,9 @@ properties:
>>            - samsung,exynos3250-cmu
>>            - samsung,exynos3250-cmu-dmc
>>            - samsung,exynos3250-cmu-isp
>> +          - samsung,exynos4210-clock
>> +          - samsung,exynos4412-clock
>> +          - samsung,exynos4412-isp-clock
>>            - samsung,exynos5250-clock
>>            - samsung,exynos5420-clock
>>            - samsung,exynos5800-clock
>> @@ -35,11 +38,18 @@ properties:
>>    assigned-clocks: true
>>    assigned-clock-parents: true
>>    assigned-clock-rates: true
>> -  clocks: true
>> +  clocks:
>> +    description: |
>> +      For samsung,exynos4412-isp-clock, the input clocks should be CLK_ACLK200
>> +      and CLK_ACLK400_MCUISP from the main clock controller.
>> +
>> +  clock-names: true
>>  
>>    "#clock-cells":
>>      const: 1
>>  
>> +  power-domains: true
>> +
> 
> How many?

I'll add it.

> 
> Now all the flavors can have a power domain? Maybe this should be a 
> separate binding given this and the if/then below.

If you ask about the hardware specifically - almost all flavors could
have a power domain.

There are actually several clock controllers in every SoC responsible
for different parts (e.g. display, GPU, audio, video encoder) and most
of them could have a power domain.

However the clock controller bindings and drivers for all ARMv7 Exynos
SoCs were designed as one device with one device node. Inside the driver
spawns sub-controllers but still there is one device node.

Therefore the answer, if you ask about bindings and hardware-driver
model, is that only some of the flavors will have a power domain.

If you think that having to separate bindings, without that "allOf: if:"
below, is simpler then I can split it.

> 
>>    reg:
>>      maxItems: 1
>>  
>> @@ -50,6 +60,23 @@ required:
>>  
>>  additionalProperties: false
>>  
>> +allOf:
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: samsung,exynos4412-isp-clock
>> +    then:
>> +      properties:
>> +        clock-names:
>> +          items:
>> +            - const: aclk200
>> +            - const: aclk400_mcuisp
>> +      required:
>> +        - clocks
>> +        - clock-names
>> +        - power-domains
>> +
>>  examples:
>>    - |
>>      #include <dt-bindings/clock/exynos5250.h>
>> -- 
>> 2.30.2
>>
>>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Wed Aug 18 00:06:44 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 18 Aug 2021 09:06:44 +0200
Subject: [PATCH v2 6/8] dt-bindings: clock: samsung: convert Exynos AudSS
 to dtschema
In-Reply-To: <YRwbYiS7VTd/NdS5@robh.at.kernel.org>
References: <20210810093145.26153-1-krzysztof.kozlowski@canonical.com>
 <20210810093145.26153-7-krzysztof.kozlowski@canonical.com>
 <YRwbYiS7VTd/NdS5@robh.at.kernel.org>
Message-ID: <098578c6-ca2c-2c4b-d5c6-657abba35c4f@canonical.com>

On 17/08/2021 22:26, Rob Herring wrote:
> On Tue, Aug 10, 2021 at 11:31:43AM +0200, Krzysztof Kozlowski wrote:
>> Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
>> schema format using json-schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
>>  .../clock/samsung,exynos-audss-clock.yaml     |  79 ++++++++++++++
>>  2 files changed, 79 insertions(+), 103 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>> deleted file mode 100644
>> index 6030afb10b5c..000000000000
>> --- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>> +++ /dev/null
>> @@ -1,103 +0,0 @@
>> -* Samsung Audio Subsystem Clock Controller
>> -
>> -The Samsung Audio Subsystem clock controller generates and supplies clocks
>> -to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
>> -binding described here is applicable to all SoCs in Exynos family.
>> -
>> -Required Properties:
>> -
>> -- compatible: should be one of the following:
>> -  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
>> -  - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
>> -    SoCs.
>> -  - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
>> -    SoCs.
>> -  - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
>> -    SoCs.
>> -- reg: physical base address and length of the controller's register set.
>> -
>> -- #clock-cells: should be 1.
>> -
>> -- clocks:
>> -  - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
>> -    is used if not specified.
>> -  - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
>> -    is used if not specified.
>> -  - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
>> -    specified.
>> -  - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
>> -    not specified.
>> -  - sclk_pcm_in: PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not
>> -    specified.
>> -
>> -- clock-names: Aliases for the above clocks. They should be "pll_ref",
>> -  "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
>> -
>> -Optional Properties:
>> -
>> -  - power-domains: a phandle to respective power domain node as described by
>> -    generic PM domain bindings (see power/power_domain.txt for more
>> -    information).
>> -
>> -The following is the list of clocks generated by the controller. Each clock is
>> -assigned an identifier and client nodes use this identifier to specify the
>> -clock which they consume. Some of the clocks are available only on a particular
>> -Exynos4 SoC and this is specified where applicable.
>> -
>> -Provided clocks:
>> -
>> -Clock           ID      SoC (if specific)
>> ------------------------------------------------
>> -
>> -mout_audss      0
>> -mout_i2s        1
>> -dout_srp        2
>> -dout_aud_bus    3
>> -dout_i2s        4
>> -srp_clk         5
>> -i2s_bus         6
>> -sclk_i2s        7
>> -pcm_bus         8
>> -sclk_pcm        9
>> -adma            10      Exynos5420
>> -
>> -Example 1: An example of a clock controller node using the default input
>> -	   clock names is listed below.
>> -
>> -clock_audss: audss-clock-controller at 3810000 {
>> -	compatible = "samsung,exynos5250-audss-clock";
>> -	reg = <0x03810000 0x0C>;
>> -	#clock-cells = <1>;
>> -};
>> -
>> -Example 2: An example of a clock controller node with the input clocks
>> -           specified.
>> -
>> -clock_audss: audss-clock-controller at 3810000 {
>> -	compatible = "samsung,exynos5250-audss-clock";
>> -	reg = <0x03810000 0x0C>;
>> -	#clock-cells = <1>;
>> -	clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
>> -		<&ext_i2s_clk>;
>> -	clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
>> -};
>> -
>> -Example 3: I2S controller node that consumes the clock generated by the clock
>> -           controller. Refer to the standard clock bindings for information
>> -           about 'clocks' and 'clock-names' property.
>> -
>> -i2s0: i2s at 3830000 {
>> -	compatible = "samsung,i2s-v5";
>> -	reg = <0x03830000 0x100>;
>> -	dmas = <&pdma0 10
>> -		&pdma0 9
>> -		&pdma0 8>;
>> -	dma-names = "tx", "rx", "tx-sec";
>> -	clocks = <&clock_audss EXYNOS_I2S_BUS>,
>> -		<&clock_audss EXYNOS_I2S_BUS>,
>> -		<&clock_audss EXYNOS_SCLK_I2S>,
>> -		<&clock_audss EXYNOS_MOUT_AUDSS>,
>> -		<&clock_audss EXYNOS_MOUT_I2S>;
>> -	clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
>> -		      "mout_audss", "mout_i2s";
>> -};
>> diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
>> new file mode 100644
>> index 000000000000..d60b29fa22e7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
>> @@ -0,0 +1,79 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/samsung,exynos-audss-clock.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Samsung Exynos SoC Audio SubSystem clock controller
>> +
>> +maintainers:
>> +  - Chanwoo Choi <cw00.choi at samsung.com>
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
>> +  - Tomasz Figa <tomasz.figa at gmail.com>
>> +
>> +description: |
>> +  All available clocks are defined as preprocessor macros in
>> +  include/dt-bindings/clock/exynos-audss-clk.h header.
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - samsung,exynos4210-audss-clock
>> +      - samsung,exynos5250-audss-clock
>> +      - samsung,exynos5410-audss-clock
>> +      - samsung,exynos5420-audss-clock
>> +
>> +  clocks:
>> +    minItems: 2
>> +    items:
>> +      - description:
>> +          Fixed rate PLL reference clock, parent of mout_audss. "fin_pll" is
>> +          used if not specified.
>> +      - description:
>> +          Input PLL to the AudioSS block, parent of mout_audss. "fout_epll" is
>> +          used if not specified.
>> +      - description:
>> +          Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if not
>> +          specified.
>> +      - description:
>> +          PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not specified.
>> +      - description:
>> +          External i2s clock, parent of mout_i2s. "cdclk0" is used if not
>> +          specified.
>> +
>> +  clock-names:
>> +    minItems: 2
>> +    items:
>> +      - const: pll_ref
>> +      - const: pll_in
>> +      - const: sclk_audio
>> +      - const: sclk_pcm_in
>> +      - const: cdclk
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +
>> +  power-domains: true
> 
> How many?
> 

I'll fix it, thanks for review.

Best regards,
Krzysztof


From Claudiu.Beznea at microchip.com  Wed Aug 18 00:17:25 2021
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Wed, 18 Aug 2021 07:17:25 +0000
Subject: [PATCH v2 6/7] dt-bindings: ARM: at91: document exegin q5xr5 board
In-Reply-To: <YRwEEQ0SgQRDnd7t@robh.at.kernel.org>
References: <20210816064416.1630674-1-claudiu.beznea@microchip.com>
 <20210816064416.1630674-7-claudiu.beznea@microchip.com>
 <YRwEEQ0SgQRDnd7t@robh.at.kernel.org>
Message-ID: <c9814716-b662-8e44-fc27-32b0c2692415@microchip.com>

On 17.08.2021 21:46, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Mon, 16 Aug 2021 09:44:15 +0300, Claudiu Beznea wrote:
>> Document Exegin Q5xR5 board.
>>
>> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
>> ---
>>  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
> 
> 
> Please add Acked-by/Reviewed-by tags when posting new versions. However,
> there's no need to repost patches *only* to add the tags. The upstream
> maintainer will do that for acks received on the version they apply.
> 
> If a tag was not added on purpose, please state why and what changed.
> 

On this patch I haven't received a tag on v1 as I swapped the commit msg
and diff b/w this one and patch 3/7. On patch 3/7 I got a tag from you but
you had taken it back when (probably) you realized I did the swapping.

From Claudiu.Beznea at microchip.com  Wed Aug 18 00:20:30 2021
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Wed, 18 Aug 2021 07:20:30 +0000
Subject: [PATCH] clk/at91: remove kernel-doc warnings in sama7g5.c
In-Reply-To: <29f0b5d0-d9ab-6ef3-b280-ba3d64c8d828@infradead.org>
References: <20210810005431.22007-1-rdunlap@infradead.org>
 <1670a11e-98d8-1b55-34c0-3369aaa8a615@microchip.com>
 <29f0b5d0-d9ab-6ef3-b280-ba3d64c8d828@infradead.org>
Message-ID: <1918428f-a808-2a90-5c6d-991e5f5d469c@microchip.com>

On 18.08.2021 08:32, Randy Dunlap wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> content is safe
> 
> On 8/17/21 10:12 PM, Claudiu.Beznea at microchip.com wrote:
>> Hi Randy,
>>
>> On 10.08.2021 03:54, Randy Dunlap wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know
>>> the content is safe
>>>
>>> Fix multiple kernel-doc warnings in sama7g5.c. There are several
>>> enums and structs that were not identified as such.
>>> There are also several anonymous structs (that scripts/kernel-doc
>>> has problems with), so add struct names to them.
>>>
>>> Fixes the following warnings:
>>>
>>> drivers/clk/at91/sama7g5.c:39: warning: This comment starts with '/**',
>>> but isn't a kernel-doc comment. Refer
>>> Documentation/doc-guide/kernel-doc.rst
>>> ? * PLL clocks identifiers
>>> drivers/clk/at91/sama7g5.c:60: warning: This comment starts with '/**',
>>> but isn't a kernel-doc comment. Refer
>>> Documentation/doc-guide/kernel-doc.rst
>>> ? * PLL type identifiers
>>> drivers/clk/at91/sama7g5.c:122: warning: This comment starts with '/**',
>>> but isn't a kernel-doc comment. Refer
>>> Documentation/doc-guide/kernel-doc.rst
>>> ? * PLL clocks description
>>> drivers/clk/at91/sama7g5.c:289: warning: This comment starts with '/**',
>>> but isn't a kernel-doc comment. Refer
>>> Documentation/doc-guide/kernel-doc.rst
>>> ? * Master clock (MCK[1..4]) description
>>> drivers/clk/at91/sama7g5.c:341: warning: This comment starts with '/**',
>>> but isn't a kernel-doc comment. Refer
>>> Documentation/doc-guide/kernel-doc.rst
>>> ? * System clock description
>>> drivers/clk/at91/sama7g5.c:365: warning: This comment starts with '/**',
>>> but isn't a kernel-doc comment. Refer
>>> Documentation/doc-guide/kernel-doc.rst
>>> ? * Peripheral clock description
>>> drivers/clk/at91/sama7g5.c:453: warning: This comment starts with '/**',
>>> but isn't a kernel-doc comment. Refer
>>> Documentation/doc-guide/kernel-doc.rst
>>> ? * Generic clock description
>>> drivers/clk/at91/sama7g5.c:339: warning: Function parameter or member
>>> 'ep_chg_id' not described in 'master_clock'
>>>
>>> Some kernel-doc warnings are still printed, but they are all due to
>>> problems in the kernel-doc script (if anyone is interested in playing
>>> with some Perl :). These warnings are:
>>>
>>> sama7g5.c:287: warning: Function parameter or member '{' not described
>>> in 'sama7g5_plls'
>>> sama7g5.c:287: warning: Function parameter or member '' not described in
>>> 'sama7g5_plls'
>>> sama7g5.c:287: warning: Function parameter or member '}' not described
>>> in 'sama7g5_plls'
>>> sama7g5.c:339: warning: Function parameter or member 'sama7g5_mckx' not
>>> described in 'master_clock'
>>> sama7g5.c:339: warning: Function parameter or member '}' not described
>>> in 'master_clock'
>>> sama7g5.c:360: warning: Function parameter or member 'sama7g5_systemck'
>>> not described in 'system_clock'
>>> sama7g5.c:451: warning: Function parameter or member 'sama7g5_periphck'
>>> not described in 'periph_clock'
>>> sama7g5.c:451: warning: Function parameter or member '' not described in
>>> 'periph_clock'
>>> sama7g5.c:451: warning: Function parameter or member '}' not described
>>> in 'periph_clock'
>>> sama7g5.c:841: warning: Function parameter or member 'sama7g5_gck' not
>>> described in 'generic_clock'
>>> sama7g5.c:841: warning: Function parameter or member '}' not described
>>> in 'generic_clock'
>>
>> What about keeping only one '*' instead of '**' where necessary as these
>> data structures are only local to sama7g5.c file (according to
>> Documentation/doc-guide/kernel-doc.rst "Functions and data structures in
>> header files which are intended to be used by modules should also have
>> kernel-doc comments."). This way all the warnings will be gone.
> 
> Sure, that works too.
> I'll send an updated patch.

Also, the title should be something like
"clk: at91: sama7g5: <your message>"

> 
> thanks.
> -- 
> ~Randy
> 


From msp at baylibre.com  Wed Aug 18 00:26:50 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Wed, 18 Aug 2021 09:26:50 +0200
Subject: [RFC PATCH 2/5] drm/mediatek: dpi: Add dpintf support
In-Reply-To: <1629193844.19746.2.camel@mtksdaap41>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-3-msp@baylibre.com>
 <1629193844.19746.2.camel@mtksdaap41>
Message-ID: <20210818072650.wtarykc4rihtio4k@blmsp>

Hi,

On Tue, Aug 17, 2021 at 05:50:44PM +0800, CK Hu wrote:
> Hi, Markus:
> 
> On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> > dpintf is the displayport interface hardware unit. This unit is similar
> > to dpi and can reuse most of the code.
> > 
> > This patch adds support for mt8195-dpintf to this dpi driver. Main
> > differences are:
> >  - Some features/functional components are not available for dpintf
> >    which are now excluded from code execution once is_dpintf is set
> >  - dpintf can and needs to choose between different clockdividers based
> >    on the clockspeed. This is done by choosing a different clock parent.
> >  - There are two additional clocks that need to be managed. These are
> >    only set for dpintf and will be set to NULL if not supplied. The
> >    clk_* calls handle these as normal clocks then.
> >  - Some register contents differ slightly between the two components. To
> >    work around this I added register bits/masks with a DPINTF_ prefix
> >    and use them where different.
> > 
> > Based on a separate driver for dpintf created by
> > Jason-JH.Lin <jason-jh.lin at mediatek.com>.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dpi.c      | 282 ++++++++++++++++++++----
> >  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  12 +
> >  2 files changed, 247 insertions(+), 47 deletions(-)
> > 
> 
> [snip]
> 
> >  
> > +static void mtk_dpi_set_pixel_clk_parent(struct mtk_dpi *dpi,
> > +					 unsigned int factor)
> > +{
> > +	struct clk *new_parent;
> > +
> > +	switch (factor) {
> > +	case 16:
> > +		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D16].clk;
> > +		break;
> > +	case 8:
> > +		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D8].clk;
> > +		break;
> > +	case 4:
> > +		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D4].clk;
> > +		break;
> > +	case 2:
> > +		new_parent = dpi->tvd_clks[MTK_DPI_TVDPLL_D2].clk;
> > +		break;
> > +	default:
> > +		new_parent = NULL;
> > +	}
> > +	if (new_parent)
> > +		clk_set_parent(dpi->pixel_clk, new_parent);
> 
> I prefer that dpi->pixel_clk provide set_rate() interface, and let clock
> driver to control the parent of dpi->pixel_clk.

Good point, will do that, thanks.

Best,
Markus

> 
> Regards,
> CK
> 
> > +}
> > +
> >  static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> >  				    struct drm_display_mode *mode)
> >  {
> > @@ -465,6 +568,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
> >  	drm_display_mode_to_videomode(mode, &vm);
> >  	pll_rate = vm.pixelclock * factor;
> >  
> > +	mtk_dpi_set_pixel_clk_parent(dpi, factor);
> > +
> >  	dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
> >  		pll_rate, vm.pixelclock);
> >  
> 
> 


From msp at baylibre.com  Wed Aug 18 00:30:37 2021
From: msp at baylibre.com (Markus Schneider-Pargmann)
Date: Wed, 18 Aug 2021 09:30:37 +0200
Subject: [RFC PATCH 1/5] dt-bindings: mediatek,dpi: Add mt8195 dpintf
In-Reply-To: <1629261946.11678.5.camel@mtksdaap41>
References: <20210816192523.1739365-1-msp@baylibre.com>
 <20210816192523.1739365-2-msp@baylibre.com>
 <1629261946.11678.5.camel@mtksdaap41>
Message-ID: <20210818073037.apmh2cf5hxhya6vo@blmsp>

Hi,

On Wed, Aug 18, 2021 at 12:45:46PM +0800, CK Hu wrote:
> Hi, Markus:
> 
> On Mon, 2021-08-16 at 21:25 +0200, Markus Schneider-Pargmann wrote:
> > DP_INTF is similar to the actual dpi. They differ in some points
> > regarding registers and what needs to be set but the function blocks
> > itself are similar in design.
> > 
> > Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> > ---
> >  .../display/mediatek/mediatek,dpi.yaml        | 48 ++++++++++++++++---
> >  1 file changed, 42 insertions(+), 6 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > index dd2896a40ff0..de4bdacd83ac 100644
> > --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> > @@ -4,7 +4,7 @@
> >  $id: https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,dpi.yaml*__;Iw!!CTRNKA9wMg0ARbw!z5TyPvbq3ZLHjRPscOHigUMlikjhtJMFrEQqemcjQZa4NaXBE9tzMnDFMa1qYg$ 
> >  $schema: https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!z5TyPvbq3ZLHjRPscOHigUMlikjhtJMFrEQqemcjQZa4NaXBE9tzMnAjuBCxsg$ 
> > 
> > -title: mediatek DPI Controller Device Tree Bindings
> > +title: mediatek DPI/DP_INTF Controller Device Tree Bindings
> >  
> >  maintainers:
> >    - CK Hu <ck.hu at mediatek.com>
> > @@ -13,7 +13,8 @@ maintainers:
> >  description: |
> >    The Mediatek DPI function block is a sink of the display subsystem and
> >    provides 8-bit RGB/YUV444 or 8/10/10-bit YUV422 pixel data on a parallel
> > -  output bus.
> > +  output bus. The Mediatek DP_INTF is a similar function block that is
> > +  connected to the (embedded) display port function block.
> >  
> >  properties:
> >    compatible:
> > @@ -23,6 +24,7 @@ properties:
> >        - mediatek,mt8173-dpi
> >        - mediatek,mt8183-dpi
> >        - mediatek,mt8192-dpi
> > +      - mediatek,mt8195-dpintf
> 
> I've reviewed the modification in driver, it seems that dpintf is almost
> the same as dpi. Why use the name "dpintf"? I could accept this name
> only it's defined by hardware data sheet.

Yes the data sheet makes a distinction between DPI and DP_INTF. mt8195
has a DPI unit as well. DP_INTF has a slightly different feature set and
also uses slightly different register bits.

Best,
Markus

> 
> Regards,
> CK
> 
> >  
> >    reg:
> >      maxItems: 1
> > @@ -37,10 +39,11 @@ properties:
> >        - description: DPI PLL
> >  
> >    clock-names:
> > -    items:
> > -      - const: pixel
> > -      - const: engine
> > -      - const: pll
> > +    description:
> > +      For dpi clocks pixel, engine and pll are required. For dpintf pixel, pll,
> > +      pll_d2, pll_d4, pll_d8, pll_d16, hf_fmm, hf_fdp are required.
> > +    minItems: 3
> > +    maxItems: 8
> >  
> >    pinctrl-0: true
> >    pinctrl-1: true
> > @@ -64,6 +67,39 @@ required:
> >    - clock-names
> >    - port
> >  
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - mediatek,mt8195-dpintf
> > +    then:
> > +      properties:
> > +        clocks:
> > +          minItems: 8
> > +          maxItems: 8
> > +        clock-names:
> > +          items:
> > +            - const: pixel
> > +            - const: pll
> > +            - const: pll_d2
> > +            - const: pll_d4
> > +            - const: pll_d8
> > +            - const: pll_d16
> > +            - const: hf_fmm
> > +            - const: hf_fdp
> > +    else:
> > +      properties:
> > +        clocks:
> > +          minItems: 3
> > +          maxItems: 3
> > +        clock-names:
> > +          items:
> > +            - const: pixel
> > +            - const: engine
> > +            - const: pll
> > +
> >  additionalProperties: false
> >  
> >  examples:
> 


From eizan at chromium.org  Wed Aug 18 00:43:33 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 18 Aug 2021 17:43:33 +1000
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <bf98c5ee749bca755bd46832f858536dbf51a2a4.camel@mediatek.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <bf98c5ee749bca755bd46832f858536dbf51a2a4.camel@mediatek.com>
Message-ID: <CAOak1e-oyzxbvHimMReQpZCAPyCtAsaGixjwmoa0EzMjqaUxVg@mail.gmail.com>

Hi Houlong,

On Mon, Aug 16, 2021 at 1:00 PM houlong wei <houlong.wei at mediatek.com> wrote:
> Hi Eizan,
>
> "mdp-rdma0" may be not the only one master device node. In fact, there
> are 2 "mdp-rdma" in mt8173. You can see "mdp_rdma1" via below link.
>
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.13.11#n1016
> If we add "mediatek,mt8173-mdp" to "mdp_rdma1" like below, we will have
> one more V4L2 video devie node.
>
>                 mdp_rdma1: rdma at 14002000 {
>                         compatible = "mediatek,mt8173-mdp-rdma",
>                                      "mediatek,mt8173-mdp";
>                         ...
>                 }
>
> We should consider the case that there are more than one "MDP_RDMA"
> components.

Would it be okay with you if we added support for multiple MDP master
device nodes in follow-up changes? My rationale is this:
- As far as I can tell, the mediatek integration with V4L2 currently
only handles a single MDP master device node. It's not clear to me the
scope of changes that will be needed to make things work properly with
multiple nodes.
- The patch series makes video decode work (admittedly, in light of
your comments not optimally) upstream, which is better than not
landing these changes at all.

I'd like to say that I'm very open to (and excited about) discussing
further work to support multiple MDP master nodes, perhaps we can
work together on this so I can understand what needs to be done.

Please let me know your thoughts,

Eizan


From maninder1.s at samsung.com  Wed Aug 18 00:15:43 2021
From: maninder1.s at samsung.com (Maninder Singh)
Date: Wed, 18 Aug 2021 12:45:43 +0530
Subject: [PATCH 1/1] exception/stackdepot: add irqentry section in case of
 STACKDEPOT
References: <CGME20210818071602epcas5p4fecf459638312c95c5d5aaa29e7e983a@epcas5p4.samsung.com>
Message-ID: <1629270943-9304-1-git-send-email-maninder1.s@samsung.com>

As of now if CONFIG_FUNCTION_GRAPH_TRACER is disabled some functions
like gic_handle_irq will not be added in irqentry text section.

which leads to adding more stacks in stackdepot as frames below IRQ
will not be filtered with filter_irq_stack() function.

checked with debug interface for satckdepot:
https://lkml.org/lkml/2017/11/22/242

e.g. (ARM)
stack count 23188 backtrace
 prep_new_page+0x14c/0x160
 get_page_from_freelist+0x1258/0x1350
...
 __handle_domain_irq+0x1ac/0x4ac
 gic_handle_irq+0x44/0x80
 __irq_svc+0x5c/0x98
 __slab_alloc.constprop.0+0x84/0xac
 __kmalloc+0x31c/0x340
 sf_malloc+0x14/0x18

and for same _irq_svc there were 25000 calls which was causing
memory pressure of 2MB more on satckdepot, which will keep increasing.

Before patch memory consumption on ARM target after 2 hours:
Memory consumed by Stackdepot:3600 KB

After change:
============
Memory consumed by Stackdepot:1744 KB

 prep_new_page+0x14c/0x160
 get_page_from_freelist+0x2e4/0x1350
...
 __handle_domain_irq+0x1ac/0x4ac
 gic_handle_irq+0x44/0x80

^^^^^ no frames below this.

Signed-off-by: Maninder Singh <maninder1.s at samsung.com>
Signed-off-by: Vaneet Narang <v.narang at samsung.com>
---
 arch/arm/include/asm/exception.h   | 2 +-
 arch/arm64/include/asm/exception.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h
index 58e039a851af..3f4534cccc0f 100644
--- a/arch/arm/include/asm/exception.h
+++ b/arch/arm/include/asm/exception.h
@@ -10,7 +10,7 @@
 
 #include <linux/interrupt.h>
 
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_STACKDEPOT)
 #define __exception_irq_entry	__irq_entry
 #else
 #define __exception_irq_entry
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 339477dca551..ef2581b63405 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -13,7 +13,7 @@
 
 #include <linux/interrupt.h>
 
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_STACKDEPOT)
 #define __exception_irq_entry	__irq_entry
 #else
 #define __exception_irq_entry	__kprobes
-- 
2.17.1



From eizan at chromium.org  Wed Aug 18 00:50:39 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 18 Aug 2021 17:50:39 +1000
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <9f23beea197495d017a548ef483584714a3673f9.camel@mediatek.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <bf98c5ee749bca755bd46832f858536dbf51a2a4.camel@mediatek.com>
 <9f23beea197495d017a548ef483584714a3673f9.camel@mediatek.com>
Message-ID: <CAOak1e924x8E+kM2WJ3oGPxxt_R=b79BtbxPAdENamvjVamnEw@mail.gmail.com>

Hi Houlong,

Thank you for your review on this series, it is much appreciated.

On Mon, Aug 16, 2021 at 2:53 PM houlong wei <houlong.wei at mediatek.com> wrote:
> Is your removing "mediatek,vpu" necessary for this series "Refactor MTK
> MDP driver into core/components" ?

Removing it is not strictly necessary for the series to function, I
will re-upload the series and omit the following changes:
- [PATCH v6 8/9] dts: mtk-mdp: remove mediatek,vpu property from
primary MDP device
- [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from mtk-mdp

Do please let me know if you meant something different.

Thanks,

Eizan




>
> In some MediaTek projects (not upstream yet), the device-tree node name
> "vpu" may be changed to something like "vpu0", "vpu1" or other name,
> which depends on the implementation of "mtk-vpu" driver. We can specify
> the different phandle to "mediatek,vpu" in .dtsi file. If we use
> of_find_node_by_name() to get the vpu_node, we have to modify the name
> string in different project.
> If the answer of my previous questions is "No", I prefer to slow down
> the modification of removing "mediatek,vpu".
>
> Sorry for late reply.
>
> Regards,
> Houlong


From thunder.leizhen at huawei.com  Wed Aug 18 01:04:50 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Wed, 18 Aug 2021 16:04:50 +0800
Subject: [PATCH v2 0/2] iommu/arm-smmu-v3: Perform some simple optimizations
 for arm_smmu_cmdq_build_cmd()
Message-ID: <20210818080452.2079-1-thunder.leizhen@huawei.com>

v1 --> v2:
1. Add patch 1, Properly handle the return value of arm_smmu_cmdq_build_cmd()
2. Remove arm_smmu_cmdq_copy_cmd(). In addition, when build command fails, out_cmd is not filled.


Zhen Lei (2):
  iommu/arm-smmu-v3: Properly handle the return value of
    arm_smmu_cmdq_build_cmd()
  iommu/arm-smmu-v3: Simplify useless instructions in
    arm_smmu_cmdq_build_cmd()

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 29 ++++++++++++++-------
 1 file changed, 20 insertions(+), 9 deletions(-)

-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Wed Aug 18 01:04:51 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Wed, 18 Aug 2021 16:04:51 +0800
Subject: [PATCH v2 1/2] iommu/arm-smmu-v3: Properly handle the return value of
 arm_smmu_cmdq_build_cmd()
In-Reply-To: <20210818080452.2079-1-thunder.leizhen@huawei.com>
References: <20210818080452.2079-1-thunder.leizhen@huawei.com>
Message-ID: <20210818080452.2079-2-thunder.leizhen@huawei.com>

1. Build command CMD_SYNC cannot fail. So the return value can be ignored.
2. The arm_smmu_cmdq_build_cmd() almost never fails, the addition of
   "unlikely()" can optimize the instruction pipeline.
3. Check the return value in arm_smmu_cmdq_batch_add().

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 3646bf8f021cd4c..01e95b56ffa07d1 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -409,10 +409,7 @@ static void __arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu,
 		dev_err(smmu->dev, "\t0x%016llx\n", (unsigned long long)cmd[i]);
 
 	/* Convert the erroneous command into a CMD_SYNC */
-	if (arm_smmu_cmdq_build_cmd(cmd, &cmd_sync)) {
-		dev_err(smmu->dev, "failed to convert to CMD_SYNC\n");
-		return;
-	}
+	arm_smmu_cmdq_build_cmd(cmd, &cmd_sync);
 
 	queue_write(Q_ENT(q, cons), cmd, q->ent_dwords);
 }
@@ -860,7 +857,7 @@ static int __arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
 {
 	u64 cmd[CMDQ_ENT_DWORDS];
 
-	if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
+	if (unlikely(arm_smmu_cmdq_build_cmd(cmd, ent))) {
 		dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
 			 ent->opcode);
 		return -EINVAL;
@@ -885,11 +882,20 @@ static void arm_smmu_cmdq_batch_add(struct arm_smmu_device *smmu,
 				    struct arm_smmu_cmdq_batch *cmds,
 				    struct arm_smmu_cmdq_ent *cmd)
 {
+	int index;
+
 	if (cmds->num == CMDQ_BATCH_ENTRIES) {
 		arm_smmu_cmdq_issue_cmdlist(smmu, cmds->cmds, cmds->num, false);
 		cmds->num = 0;
 	}
-	arm_smmu_cmdq_build_cmd(&cmds->cmds[cmds->num * CMDQ_ENT_DWORDS], cmd);
+
+	index = cmds->num * CMDQ_ENT_DWORDS;
+	if (unlikely(arm_smmu_cmdq_build_cmd(&cmds->cmds[index], cmd))) {
+		dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
+			 cmd->opcode);
+		return;
+	}
+
 	cmds->num++;
 }
 
-- 
2.26.0.106.g9fadedd



From thunder.leizhen at huawei.com  Wed Aug 18 01:04:52 2021
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Wed, 18 Aug 2021 16:04:52 +0800
Subject: [PATCH v2 2/2] iommu/arm-smmu-v3: Simplify useless instructions in
 arm_smmu_cmdq_build_cmd()
In-Reply-To: <20210818080452.2079-1-thunder.leizhen@huawei.com>
References: <20210818080452.2079-1-thunder.leizhen@huawei.com>
Message-ID: <20210818080452.2079-3-thunder.leizhen@huawei.com>

Although the parameter 'cmd' is always passed by a local array variable,
and only this function modifies it, the compiler does not know this. The
compiler almost always reads the value of cmd[i] from memory rather than
directly using the value cached in the register. This generates many
useless instruction operations and affects the performance to some extent.

To guide the compiler for proper optimization, 'cmd' is defined as a local
array variable, marked as register, and copied to the output parameter at
a time when the function is returned.

The optimization effect can be viewed by running the "size arm-smmu-v3.o"
command.

Before:
   text    data     bss     dec     hex
  26954    1348      56   28358    6ec6

After:
   text    data     bss     dec     hex
  26762    1348      56   28166    6e06

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 01e95b56ffa07d1..7cec0c967f71d86 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -234,10 +234,12 @@ static int queue_remove_raw(struct arm_smmu_queue *q, u64 *ent)
 }
 
 /* High-level queue accessors */
-static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
+static int arm_smmu_cmdq_build_cmd(u64 *out_cmd, struct arm_smmu_cmdq_ent *ent)
 {
-	memset(cmd, 0, 1 << CMDQ_ENT_SZ_SHIFT);
-	cmd[0] |= FIELD_PREP(CMDQ_0_OP, ent->opcode);
+	register u64 cmd[CMDQ_ENT_DWORDS];
+
+	cmd[0] = FIELD_PREP(CMDQ_0_OP, ent->opcode);
+	cmd[1] = 0;
 
 	switch (ent->opcode) {
 	case CMDQ_OP_TLBI_EL2_ALL:
@@ -332,6 +334,9 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 		return -ENOENT;
 	}
 
+	out_cmd[0] = cmd[0];
+	out_cmd[1] = cmd[1];
+
 	return 0;
 }
 
-- 
2.26.0.106.g9fadedd



From haibo.chen at nxp.com  Wed Aug 18 00:44:35 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 15:44:35 +0800
Subject: [PATCH] arm64: dts: imx8qm: minor fix for schema dts check
Message-ID: <1629272675-7142-1-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add minor fix to pass schema dts check.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 .../arm64/boot/dts/freescale/imx8-ss-conn.dtsi | 18 +++++++++---------
 .../boot/dts/freescale/imx8qm-ss-conn.dtsi     |  4 ++--
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
index a79f42a9618e..639220dbff00 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
@@ -38,9 +38,9 @@ conn_subsys: bus at 5b000000 {
 		interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0x5b010000 0x10000>;
 		clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>,
-			 <&sdhc0_lpcg IMX_LPCG_CLK_5>,
-			 <&sdhc0_lpcg IMX_LPCG_CLK_0>;
-		clock-names = "ipg", "per", "ahb";
+			 <&sdhc0_lpcg IMX_LPCG_CLK_0>,
+			 <&sdhc0_lpcg IMX_LPCG_CLK_5>;
+		clock-names = "ipg", "ahb", "per";
 		power-domains = <&pd IMX_SC_R_SDHC_0>;
 		status = "disabled";
 	};
@@ -49,9 +49,9 @@ conn_subsys: bus at 5b000000 {
 		interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0x5b020000 0x10000>;
 		clocks = <&sdhc1_lpcg IMX_LPCG_CLK_4>,
-			 <&sdhc1_lpcg IMX_LPCG_CLK_5>,
-			 <&sdhc1_lpcg IMX_LPCG_CLK_0>;
-		clock-names = "ipg", "per", "ahb";
+			 <&sdhc1_lpcg IMX_LPCG_CLK_0>,
+			 <&sdhc1_lpcg IMX_LPCG_CLK_5>;
+		clock-names = "ipg", "ahb", "per";
 		power-domains = <&pd IMX_SC_R_SDHC_1>;
 		fsl,tuning-start-tap = <20>;
 		fsl,tuning-step= <2>;
@@ -62,9 +62,9 @@ conn_subsys: bus at 5b000000 {
 		interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0x5b030000 0x10000>;
 		clocks = <&sdhc2_lpcg IMX_LPCG_CLK_4>,
-			 <&sdhc2_lpcg IMX_LPCG_CLK_5>,
-			 <&sdhc2_lpcg IMX_LPCG_CLK_0>;
-		clock-names = "ipg", "per", "ahb";
+			 <&sdhc2_lpcg IMX_LPCG_CLK_0>,
+			 <&sdhc2_lpcg IMX_LPCG_CLK_5>;
+		clock-names = "ipg", "ahb", "per";
 		power-domains = <&pd IMX_SC_R_SDHC_2>;
 		status = "disabled";
 	};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
index 42637a45701c..17bbe2e16126 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
@@ -13,9 +13,9 @@
 };
 
 &usdhc1 {
-	compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+	compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
 };
 
 &usdhc2 {
-	compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+	compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
 };
-- 
2.17.1



From gregkh at linuxfoundation.org  Wed Aug 18 01:08:25 2021
From: gregkh at linuxfoundation.org (Greg KH)
Date: Wed, 18 Aug 2021 10:08:25 +0200
Subject: [PATCH 0/3] Add support for runtime features
In-Reply-To: <20210817130553.20219-1-ronak.jain@xilinx.com>
References: <20210817130553.20219-1-ronak.jain@xilinx.com>
Message-ID: <YRy/+epfpiRq2fLr@kroah.com>

On Tue, Aug 17, 2021 at 06:05:50AM -0700, Ronak Jain wrote:
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

This footer means that this has to be ignored and can not be used for
kernel development at all.


From piyush.mehta at xilinx.com  Wed Aug 18 01:10:15 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Wed, 18 Aug 2021 13:40:15 +0530
Subject: [PATCH V3 0/3] gpio: modepin: Add driver support for modepin GPIO
 controller
Message-ID: <20210818081018.2620544-1-piyush.mehta@xilinx.com>

This patch adds support for the zynqmp modepin GPIO controller and
documented for the same. GPIO modepin driver set and get the value and
status of the PS_MODE pin, based on device-tree pin configuration.
These four-bits boot-mode pins are dedicated configurable as input/output.
After the stabilization of the system,these mode pins are sampled.

To access GPIO pins, added Xilinx ZynqMP firmware MDIO API support to
set and get PS_MODE pins value and status. These APIs are interface
APIs, between the mode pin controller driver and low-level API.

---
Changes in v2:
- Added Xilinx ZynqMP firmware MMIO API support to set and get pin
  value and status.
- DT Documentation- Addressed review comments: Update commit message
- Modepin driver- Addressed review comments:
  - Update APIs
  - Removed unwanted variables
  - Handle return path for probe function

Review Comments:
https://lore.kernel.org/linux-arm-kernel/20210624205055.GA1961487 at robh.at.kernel.org/T/#u

Changes in v3:
- Update example in dt-bindings documentation
- Update probe function return value
- Remove unnecessary print and header file

Review Comments:
https://lore.kernel.org/linux-arm-kernel/20210805174219.3000667-1-piyush.mehta at xilinx.com/#t
---

Piyush Mehta (3):
  firmware: zynqmp: Add MMIO read and write support for PS_MODE pin
  dt-bindings: gpio: zynqmp: Add binding documentation for modepin
  gpio: modepin: Add driver support for modepin GPIO controller

 .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    |  43 ++++++
 drivers/firmware/xilinx/zynqmp.c                   |  46 +++++++
 drivers/gpio/Kconfig                               |  12 ++
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-zynqmp-modepin.c                 | 153 +++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h               |  14 ++
 6 files changed, 269 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
 create mode 100644 drivers/gpio/gpio-zynqmp-modepin.c

-- 
2.7.4



From piyush.mehta at xilinx.com  Wed Aug 18 01:10:17 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Wed, 18 Aug 2021 13:40:17 +0530
Subject: [PATCH V3 2/3] dt-bindings: gpio: zynqmp: Add binding documentation
 for modepin
In-Reply-To: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
Message-ID: <20210818081018.2620544-3-piyush.mehta@xilinx.com>

This patch adds DT binding document for zynqmp modepin GPIO controller.
Modepin GPIO controller has four GPIO pins which can be configurable
as input or output.

Modepin driver is a bridge between the peripheral driver and GPIO pins.
It has set and get APIs for accessing GPIO pins, based on the device-tree
entry of reset-gpio property in the peripheral driver, every pin can be
configured as input/output and trigger GPIO pin.

For more information please refer zynqMp TRM link:
Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
Chapter 2: Signals, Interfaces, and Pins
Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE

Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
Acked-by: Michal Simek <michal.simek at xilinx.com>
---
Changes in v2:
- Addressed review comments: Update commit message

Review Comments:
https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736

Changes in v3:
- Addressed Rob and Michal review comments:
  - Update DT example. 

Review Comments:
https://lore.kernel.org/linux-arm-kernel/YRbBnRS0VosXcZWz at robh.at.kernel.org/
https://lore.kernel.org/linux-arm-kernel/d71ad7f9-6972-8cc0-6dfb-b5306c9900d0 at xilinx.com/
---
 .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
 .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml

diff --git a/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
new file mode 100644
index 0000000..1442815
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: ZynqMP Mode Pin GPIO controller
+
+description:
+  PS_MODE is 4-bits boot mode pins sampled on POR deassertion. Mode Pin
+  GPIO controller with configurable from numbers of pins (from 0 to 3 per
+  PS_MODE). Every pin can be configured as input/output.
+
+maintainers:
+  - Piyush Mehta <piyush.mehta at xilinx.com>
+
+properties:
+  compatible:
+    const: xlnx,zynqmp-gpio-modepin
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+
+required:
+  - compatible
+  - gpio-controller
+  - "#gpio-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    zynqmp-firmware {
+        gpio {
+            compatible = "xlnx,zynqmp-gpio-modepin";
+            gpio-controller;
+            #gpio-cells = <2>;
+        };
+    };
+
+...
-- 
2.7.4



From piyush.mehta at xilinx.com  Wed Aug 18 01:10:16 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Wed, 18 Aug 2021 13:40:16 +0530
Subject: [PATCH V3 1/3] firmware: zynqmp: Add MMIO read and write support for
 PS_MODE pin
In-Reply-To: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
Message-ID: <20210818081018.2620544-2-piyush.mehta@xilinx.com>

Add Xilinx ZynqMP firmware MMIO APIs support to set and get PS_MODE
pins value and status. These APIs create an interface path between
mode pin controller driver and low-level API to access GPIO pins.

Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
Acked-by: Michal Simek <michal.simek at xilinx.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
---
Changes in v2:
- Added Xilinx ZynqMP firmware MMIO API support to set and get pin
  value and status.
---
 drivers/firmware/xilinx/zynqmp.c     | 46 ++++++++++++++++++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h | 14 +++++++++++
 2 files changed, 60 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 15b13832..0234423 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -28,6 +28,13 @@
 /* Max HashMap Order for PM API feature check (1<<7 = 128) */
 #define PM_API_FEATURE_CHECK_MAX_ORDER  7
 
+/* CRL registers and bitfields */
+#define CRL_APB_BASE			0xFF5E0000U
+/* BOOT_PIN_CTRL- Used to control the mode pins after boot */
+#define CRL_APB_BOOT_PIN_CTRL		(CRL_APB_BASE + (0x250U))
+/* BOOT_PIN_CTRL_MASK- out_val[11:8], out_en[3:0] */
+#define CRL_APB_BOOTPIN_CTRL_MASK	0xF0FU
+
 static bool feature_check_enabled;
 static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER);
 
@@ -926,6 +933,45 @@ int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
 EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_config);
 
 /**
+ * zynqmp_pm_bootmode_read() - PM Config API for read bootpin status
+ * @ps_mode: Returned output value of ps_mode
+ *
+ * This API function is to be used for notify the power management controller
+ * to read bootpin status.
+ *
+ * Return: status, either success or error+reason
+ */
+unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode)
+{
+	unsigned int ret;
+	u32 ret_payload[PAYLOAD_ARG_CNT];
+
+	ret = zynqmp_pm_invoke_fn(PM_MMIO_READ, CRL_APB_BOOT_PIN_CTRL, 0,
+				  0, 0, ret_payload);
+
+	*ps_mode = ret_payload[1];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_read);
+
+/**
+ * zynqmp_pm_bootmode_write() - PM Config API for Configure bootpin
+ * @ps_mode: Value to be written to the bootpin ctrl register
+ *
+ * This API function is to be used for notify the power management controller
+ * to configure bootpin.
+ *
+ * Return: Returns status, either success or error+reason
+ */
+int zynqmp_pm_bootmode_write(u32 ps_mode)
+{
+	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, CRL_APB_BOOT_PIN_CTRL,
+				   CRL_APB_BOOTPIN_CTRL_MASK, ps_mode, 0, NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write);
+
+/**
  * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
  *			       master has initialized its own power management
  *
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 9d1a5c1..dc6f39f 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -68,6 +68,8 @@ enum pm_api_id {
 	PM_SET_REQUIREMENT = 15,
 	PM_RESET_ASSERT = 17,
 	PM_RESET_GET_STATUS = 18,
+	PM_MMIO_WRITE = 19,
+	PM_MMIO_READ = 20,
 	PM_PM_INIT_FINALIZE = 21,
 	PM_FPGA_LOAD = 22,
 	PM_FPGA_GET_STATUS = 23,
@@ -386,6 +388,8 @@ int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type);
 int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
 			   const enum zynqmp_pm_reset_action assert_flag);
 int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status);
+unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode);
+int zynqmp_pm_bootmode_write(u32 ps_mode);
 int zynqmp_pm_init_finalize(void);
 int zynqmp_pm_set_suspend_mode(u32 mode);
 int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
@@ -515,6 +519,16 @@ static inline int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset,
 	return -ENODEV;
 }
 
+static inline unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode)
+{
+	return -ENODEV;
+}
+
+static inline int zynqmp_pm_bootmode_write(u32 ps_mode)
+{
+	return -ENODEV;
+}
+
 static inline int zynqmp_pm_init_finalize(void)
 {
 	return -ENODEV;
-- 
2.7.4



From piyush.mehta at xilinx.com  Wed Aug 18 01:10:18 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Wed, 18 Aug 2021 13:40:18 +0530
Subject: [PATCH V3 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
Message-ID: <20210818081018.2620544-4-piyush.mehta@xilinx.com>

This patch adds driver support for the zynqmp modepin GPIO controller.
GPIO modepin driver set and get the value and status of the PS_MODE pin,
based on device-tree pin configuration. These four mode pins are
configurable as input/output. The mode pin has a control register, which
have lower four-bits [0:3] are configurable as input/output, next four-bits
can be used for reading the data  as input[4:7], and next setting the
output pin state output[8:11].

Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
Acked-by: Michal Simek <michal.simek at xilinx.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
---
Changes in v2:
- Modepin driver- Addressed review comments:
  - Update APIs
  - Removed unwanted variables
  - Handle return path for probe function

Review Comments:
https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#m276c8a5c52f8dc1ed1cd91a2d660f78d498e4ae5

Changes in v3:
- Addressed Linus and Arnd review comments:
  - Update probe function return value
  - Remove unnecessary print and header file
  - Update error message for set value method

Review Comments:
https://lore.kernel.org/linux-arm-kernel/20210805174219.3000667-4-piyush.mehta at xilinx.com/T/#m70acd39653033e32458633e21a2e6d21afdd16e6
---
 drivers/gpio/Kconfig               |  12 +++
 drivers/gpio/Makefile              |   1 +
 drivers/gpio/gpio-zynqmp-modepin.c | 153 +++++++++++++++++++++++++++++++++++++
 3 files changed, 166 insertions(+)
 create mode 100644 drivers/gpio/gpio-zynqmp-modepin.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index fab5710..90a3a3d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -755,6 +755,18 @@ config GPIO_ZYNQ
 	help
 	  Say yes here to support Xilinx Zynq GPIO controller.
 
+config GPIO_ZYNQMP_MODEPIN
+	tristate "ZynqMP ps-mode pin gpio configuration driver"
+	depends on ZYNQMP_FIRMWARE
+	default ZYNQMP_FIRMWARE
+	help
+	  Say yes here to support the ZynqMP ps-mode pin gpio configuration
+	  driver.
+
+	  This ps-mode pin gpio driver is based on GPIO framework, PS_MODE
+	  is 4-bits boot mode pins. It sets and gets the status of
+	  the ps-mode pin. Every pin can be configured as input/output.
+
 config GPIO_LOONGSON1
 	tristate "Loongson1 GPIO support"
 	depends on MACH_LOONGSON32
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 32a3265..978dc4595 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -183,3 +183,4 @@ obj-$(CONFIG_GPIO_XRA1403)		+= gpio-xra1403.o
 obj-$(CONFIG_GPIO_XTENSA)		+= gpio-xtensa.o
 obj-$(CONFIG_GPIO_ZEVIO)		+= gpio-zevio.o
 obj-$(CONFIG_GPIO_ZYNQ)			+= gpio-zynq.o
+obj-$(CONFIG_GPIO_ZYNQMP_MODEPIN)	+= gpio-zynqmp-modepin.o
diff --git a/drivers/gpio/gpio-zynqmp-modepin.c b/drivers/gpio/gpio-zynqmp-modepin.c
new file mode 100644
index 0000000..d52e391
--- /dev/null
+++ b/drivers/gpio/gpio-zynqmp-modepin.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for the ps-mode pin configuration.
+ *
+ * Copyright (c) 2021 Xilinx, Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/firmware/xlnx-zynqmp.h>
+
+/* 4-bit boot mode pins */
+#define MODE_PINS			4
+
+/**
+ * modepin_gpio_get_value - Get the state of the specified pin of GPIO device
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ *
+ * This function reads the state of the specified pin of the GPIO device.
+ *
+ * Return: 0 if the pin is low, 1 if pin is high, -EINVAL wrong pin configured
+ *         or error value.
+ */
+static int modepin_gpio_get_value(struct gpio_chip *chip, unsigned int pin)
+{
+	u32 regval = 0;
+	int ret;
+
+	ret = zynqmp_pm_bootmode_read(&regval);
+	if (ret)
+		return ret;
+
+	return !!(regval & BIT(pin + 8));
+}
+
+/**
+ * modepin_gpio_set_value - Modify the state of the pin with specified value
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ * @state:	value used to modify the state of the specified pin
+ *
+ * This function reads the state of the specified pin of the GPIO device, mask
+ * with the capture state of GPIO pin, and update pin of GPIO device.
+ *
+ * Return:	None.
+ */
+static void modepin_gpio_set_value(struct gpio_chip *chip, unsigned int pin,
+				   int state)
+{
+	u32 bootpin_val = 0;
+	int ret;
+
+	zynqmp_pm_bootmode_read(&bootpin_val);
+
+	if (state)
+		bootpin_val |= BIT(pin + 8);
+	else
+		bootpin_val &= ~BIT(pin + 8);
+
+	/* Configure bootpin value */
+	ret = zynqmp_pm_bootmode_write(bootpin_val);
+	if (ret)
+		pr_err("modepin: set value error %d for pin %d\n", ret, pin);
+}
+
+/**
+ * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ *
+ * Return: 0 always
+ */
+static int modepin_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
+{
+	return 0;
+}
+
+/**
+ * modepin_gpio_dir_out - Set the direction of the specified GPIO pin as output
+ * @chip:	gpio_chip instance to be worked on
+ * @pin:	gpio pin number within the device
+ * @state:	value to be written to specified pin
+ *
+ * Return: 0 always
+ */
+static int modepin_gpio_dir_out(struct gpio_chip *chip, unsigned int pin,
+				int state)
+{
+	return 0;
+}
+
+/**
+ * modepin_gpio_probe - Initialization method for modepin_gpio
+ * @pdev:		platform device instance
+ *
+ * Return: 0 on success, negative error otherwise.
+ */
+static int modepin_gpio_probe(struct platform_device *pdev)
+{
+	struct gpio_chip *chip;
+	int status;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, chip);
+
+	/* configure the gpio chip */
+	chip->base = -1;
+	chip->ngpio = MODE_PINS;
+	chip->owner = THIS_MODULE;
+	chip->parent = &pdev->dev;
+	chip->get = modepin_gpio_get_value;
+	chip->set = modepin_gpio_set_value;
+	chip->direction_input = modepin_gpio_dir_in;
+	chip->direction_output = modepin_gpio_dir_out;
+	chip->label = dev_name(&pdev->dev);
+
+	/* modepin gpio registration */
+	status = devm_gpiochip_add_data(&pdev->dev, chip, chip);
+	if (status)
+		return dev_err_probe(&pdev->dev, status,
+			      "Failed to add GPIO chip\n");
+
+	return status;
+}
+
+static const struct of_device_id modepin_platform_id[] = {
+	{ .compatible = "xlnx,zynqmp-gpio-modepin", },
+	{ }
+};
+
+static struct platform_driver modepin_platform_driver = {
+	.driver = {
+		.name = "modepin-gpio",
+		.of_match_table = modepin_platform_id,
+	},
+	.probe = modepin_gpio_probe,
+};
+
+module_platform_driver(modepin_platform_driver);
+
+MODULE_AUTHOR("Piyush Mehta <piyush.mehta at xilinx.com>");
+MODULE_DESCRIPTION("ZynqMP Boot PS_MODE Configuration");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4



From maxime at cerno.tech  Wed Aug 18 01:15:26 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 10:15:26 +0200
Subject: [PATCH v9 02/11] dt-bindings: rtc: sun6i: Add H616 compatible
 string
In-Reply-To: <20210802003952.19942-3-andre.przywara@arm.com>
References: <20210802003952.19942-1-andre.przywara@arm.com>
 <20210802003952.19942-3-andre.przywara@arm.com>
Message-ID: <20210818081526.ejzqyz4tqvf2mmdj@gilmour>

On Mon, Aug 02, 2021 at 01:39:43AM +0100, Andre Przywara wrote:
> Add the obvious compatible name to the existing RTC binding.
> The actual RTC part of the device uses a different day/month/year
> storage scheme, so it's not compatible with the previous devices.
> Also the clock part is quite different, as there is no external 32K LOSC
> oscillator input.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---
>  .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml      | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> index beeb90e55727..d8a6500e5840 100644
> --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> @@ -26,6 +26,7 @@ properties:
>            - const: allwinner,sun50i-a64-rtc
>            - const: allwinner,sun8i-h3-rtc
>        - const: allwinner,sun50i-h6-rtc
> +      - const: allwinner,sun50i-h616-rtc
>  
>    reg:
>      maxItems: 1
> @@ -104,6 +105,19 @@ allOf:
>            minItems: 3
>            maxItems: 3
>  
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: allwinner,sun50i-h616-rtc
> +
> +    then:
> +      properties:
> +        clock-output-names:
> +          minItems: 3
> +          maxItems: 3

The comments I made here on the v7 are still relevant: you only need one
of these two, and the list of clocks should be documented.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/06bf0b88/attachment.sig>

From liuqi115 at huawei.com  Tue Aug 17 22:12:45 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Wed, 18 Aug 2021 13:12:45 +0800
Subject: [PATCH v9 1/2] docs: perf: Add description for HiSilicon PCIe PMU
 driver
In-Reply-To: <20210818051246.29545-1-liuqi115@huawei.com>
References: <20210818051246.29545-1-liuqi115@huawei.com>
Message-ID: <20210818051246.29545-2-liuqi115@huawei.com>

PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported on
HiSilicon HIP09 platform. Document it to provide guidance on how to
use it.

Reviewed-by: John Garry <john.garry at huawei.com>
Signed-off-by: Qi Liu <liuqi115 at huawei.com>
---
 .../admin-guide/perf/hisi-pcie-pmu.rst        | 106 ++++++++++++++++++
 Documentation/admin-guide/perf/index.rst      |   1 +
 2 files changed, 107 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst

diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
new file mode 100644
index 000000000000..bbe66480ff85
--- /dev/null
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
@@ -0,0 +1,106 @@
+================================================
+HiSilicon PCIe Performance Monitoring Unit (PMU)
+================================================
+
+On Hip09, HiSilicon PCIe Performance Monitoring Unit (PMU) could monitor
+bandwidth, latency, bus utilization and buffer occupancy data of PCIe.
+
+Each PCIe Core has a PMU to monitor multi Root Ports of this PCIe Core and
+all Endpoints downstream these Root Ports.
+
+
+HiSilicon PCIe PMU driver
+=========================
+
+The PCIe PMU driver registers a perf PMU with the name of its sicl-id and PCIe
+Core id.::
+
+  /sys/bus/event_source/hisi_pcie<sicl>_core<core>
+
+PMU driver provides description of available events and filter options in sysfs,
+see /sys/bus/event_source/devices/hisi_pcie<sicl>_core<core>.
+
+The "format" directory describes all formats of the config (events) and config1
+(filter options) fields of the perf_event_attr structure. The "events" directory
+describes all documented events shown in perf list.
+
+The "identifier" sysfs file allows users to identify the version of the
+PMU hardware device.
+
+The "bus" sysfs file allows users to get the bus number of Root Ports
+monitored by PMU.
+
+Example usage of perf::
+
+  $# perf list
+  hisi_pcie0_core0/rx_mwr_latency/ [kernel PMU event]
+  hisi_pcie0_core0/rx_mwr_cnt/ [kernel PMU event]
+  ------------------------------------------
+
+  $# perf stat -e hisi_pcie0_core0/rx_mwr_latency/
+  $# perf stat -e hisi_pcie0_core0/rx_mwr_cnt/
+  $# perf stat -g -e hisi_pcie0_core0/rx_mwr_latency/ -e hisi_pcie0_core0/rx_mwr_cnt/
+
+The current driver does not support sampling. So "perf record" is unsupported.
+Also attach to a task is unsupported for PCIe PMU.
+
+Filter options
+--------------
+
+1. Target filter
+PMU could only monitor the performance of traffic downstream target Root Ports
+or downstream target Endpoint. PCIe PMU driver support "port" and "bdf"
+interfaces for users, and these two interfaces aren't supported at the same
+time.
+
+-port
+"port" filter can be used in all PCIe PMU events, target Root Port can be
+selected by configuring the 16-bits-bitmap "port". Multi ports can be selected
+for AP-layer-events, and only one port can be selected for TL/DL-layer-events.
+
+For example, if target Root Port is 0000:00:00.0 (x8 lanes), bit0 of bitmap
+should be set, port=0x1; if target Root Port is 0000:00:04.0 (x4 lanes),
+bit8 is set, port=0x100; if these two Root Ports are both monitored, port=0x101.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_core0/rx_mwr_latency,port=0x1/ sleep 5
+
+-bdf
+
+"bdf" filter can only be used in bandwidth events, target Endpoint is selected
+by configuring BDF to "bdf". Counter only counts the bandwidth of message
+requested by target Endpoint.
+
+For example, "bdf=0x3900" means BDF of target Endpoint is 0000:39:00.0.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,bdf=0x3900/ sleep 5
+
+2. Trigger filter
+Event statistics start when the first time TLP length is greater/smaller
+than trigger condition. You can set the trigger condition by writing "trig_len",
+and set the trigger mode by writing "trig_mode". This filter can only be used
+in bandwidth events.
+
+For example, "trig_len=4" means trigger condition is 2^4 DW, "trig_mode=0"
+means statistics start when TLP length > trigger condition, "trig_mode=1"
+means start when TLP length < condition.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,trig_len=0x4,trig_mode=1/ sleep 5
+
+3. Threshold filter
+Counter counts when TLP length within the specified range. You can set the
+threshold by writing "thr_len", and set the threshold mode by writing
+"thr_mode". This filter can only be used in bandwidth events.
+
+For example, "thr_len=4" means threshold is 2^4 DW, "thr_mode=0" means
+counter counts when TLP length >= threshold, and "thr_mode=1" means counts
+when TLP length < threshold.
+
+Example usage of perf::
+
+  $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,thr_len=0x4,thr_mode=1/ sleep 5
diff --git a/Documentation/admin-guide/perf/index.rst b/Documentation/admin-guide/perf/index.rst
index 5a8f2529a033..9d1e5e90277b 100644
--- a/Documentation/admin-guide/perf/index.rst
+++ b/Documentation/admin-guide/perf/index.rst
@@ -7,6 +7,7 @@ Performance monitor support
 .. toctree::
    :maxdepth: 1
 
+   hisi-pcie-pmu
    hisi-pmu
    imx-ddr
    qcom_l2_pmu
-- 
2.17.1



From liuqi115 at huawei.com  Tue Aug 17 22:12:44 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Wed, 18 Aug 2021 13:12:44 +0800
Subject: [PATCH v9 0/2] drivers/perf: hisi: Add support for PCIe PMU
Message-ID: <20210818051246.29545-1-liuqi115@huawei.com>

This patchset adds support for HiSilicon PCIe Performance Monitoring
Unit(PMU). It is a PCIe Root Complex integrated End Point(RCiEP) device
added on Hip09. Each PCIe Core has a PMU RCiEP to monitor multi root
ports and all Endpoints downstream these root ports.

HiSilicon PCIe PMU is supported to collect performance data of PCIe bus,
such as: bandwidth, latency etc.

Example usage of counting PCIe rx memory write latency::

  $# perf stat -e hisi_pcie0_core0/rx_mwr_latency/
  $# perf stat -e hisi_pcie0_core0/rx_mwr_cnt/
  $# perf stat -g -e hisi_pcie0_core0/rx_mwr_latency/ -e hisi_pcie0_core0/rx_mwr_cnt/

average rx memory write latency can be calculated like this:
  latency = rx_mwr_latency / rx_mwr_cnt.

Common PMU events and metrics will be described in JSON file, and will be add
in userspace perf tool latter.

Changes since v8:
- Remove subevent parameter in attr->config.
- Check the counter scheduling constraints when accepting an event group.
- Link: https://lore.kernel.org/linux-arm-kernel/20210728080932.72515-1-liuqi115 at huawei.com/

Changes since v7:
- Drop headerfile cpumask.h and cpuhotplug.h.
- Rename events in perf list: bw->flux, lat->delay, as driver doesn't
  process bandwidth and average latency data.
- Link: https://lore.kernel.org/linux-arm-kernel/1624532384-43002-1-git-send-email-liuqi115 at huawei.com/

Changes since v6:
- Move the driver to drivers/perf/hisilicon.
- Treat content in PMU counter and ext_counter as different PMU events, and
  export them separately.
- Address the comments from Will and Krzysztof.
- Link: https://lore.kernel.org/linux-arm-kernel/1622467951-32114-1-git-send-email-liuqi115 at huawei.com/

Changes since v5:
- Fix some errors when build under ARCH=xtensa.
- Link: https://lore.kernel.org/linux-arm-kernel/1621946795-14046-1-git-send-email-liuqi115 at huawei.com/

Changes since v4:
- Replace irq_set_affinity_hint() with irq_set_affinity().
- Link: https://lore.kernel.org/linux-arm-kernel/1621417741-5229-1-git-send-email-liuqi115 at huawei.com/

Changes since v3:
- Fix some warnings when build under 32bits architecture.
- Address the comments from John.
- Link: https://lore.kernel.org/linux-arm-kernel/1618490885-44612-1-git-send-email-liuqi115 at huawei.com/

Changes since v2:
- Address the comments from John.
- Link: https://lore.kernel.org/linux-arm-kernel/1617959157-22956-1-git-send-email-liuqi115 at huawei.com/

Changes since v1:
- Drop the internal Reviewed-by tag.
- Fix some build warnings when W=1.
- Link: https://lore.kernel.org/linux-arm-kernel/1617788943-52722-1-git-send-email-liuqi115 at huawei.com/

Qi Liu (2):
  docs: perf: Add description for HiSilicon PCIe PMU driver
  drivers/perf: hisi: Add driver for HiSilicon PCIe PMU

 .../admin-guide/perf/hisi-pcie-pmu.rst        | 106 ++
 Documentation/admin-guide/perf/index.rst      |   1 +
 MAINTAINERS                                   |   2 +
 drivers/perf/hisilicon/Kconfig                |   9 +
 drivers/perf/hisilicon/Makefile               |   2 +
 drivers/perf/hisilicon/hisi_pcie_pmu.c        | 972 ++++++++++++++++++
 include/linux/cpuhotplug.h                    |   1 +
 7 files changed, 1093 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst
 create mode 100644 drivers/perf/hisilicon/hisi_pcie_pmu.c

-- 
2.17.1



From liuqi115 at huawei.com  Tue Aug 17 22:12:46 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Wed, 18 Aug 2021 13:12:46 +0800
Subject: [PATCH v9 2/2] drivers/perf: hisi: Add driver for HiSilicon PCIe PMU
In-Reply-To: <20210818051246.29545-1-liuqi115@huawei.com>
References: <20210818051246.29545-1-liuqi115@huawei.com>
Message-ID: <20210818051246.29545-3-liuqi115@huawei.com>

PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported
to sample bandwidth, latency, buffer occupation etc.

Each PMU RCiEP device monitors multiple Root Ports, and each RCiEP is
registered as a PMU in /sys/bus/event_source/devices, so users can
select target PMU, and use filter to do further sets.

Filtering options contains:
event     - select the event.
port      - select target Root Ports. Information of Root Ports are
            shown under sysfs.
bdf       - select requester_id of target EP device.
trig_len  - set trigger condition for starting event statistics.
trig_mode - set trigger mode. 0 means starting to statistic when bigger
            than trigger condition, and 1 means smaller.
thr_len   - set threshold for statistics.
thr_mode  - set threshold mode. 0 means count when bigger than threshold,
            and 1 means smaller.

Reviewed-by: John Garry <john.garry at huawei.com>
Signed-off-by: Qi Liu <liuqi115 at huawei.com>
---
 MAINTAINERS                            |   2 +
 drivers/perf/hisilicon/Kconfig         |   9 +
 drivers/perf/hisilicon/Makefile        |   2 +
 drivers/perf/hisilicon/hisi_pcie_pmu.c | 972 +++++++++++++++++++++++++
 include/linux/cpuhotplug.h             |   1 +
 5 files changed, 986 insertions(+)
 create mode 100644 drivers/perf/hisilicon/hisi_pcie_pmu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fd25e4ecf0b9..8af543ac0ddc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8379,8 +8379,10 @@ F:	Documentation/devicetree/bindings/misc/hisilicon-hikey-usb.yaml
 
 HISILICON PMU DRIVER
 M:	Shaokun Zhang <zhangshaokun at hisilicon.com>
+M:	Qi Liu <liuqi115 at huawei.com>
 S:	Supported
 W:	http://www.hisilicon.com
+F:	Documentation/admin-guide/perf/hisi-pcie-pmu.rst
 F:	Documentation/admin-guide/perf/hisi-pmu.rst
 F:	drivers/perf/hisilicon
 
diff --git a/drivers/perf/hisilicon/Kconfig b/drivers/perf/hisilicon/Kconfig
index c5d1b7019fff..5546218b5598 100644
--- a/drivers/perf/hisilicon/Kconfig
+++ b/drivers/perf/hisilicon/Kconfig
@@ -5,3 +5,12 @@ config HISI_PMU
 	  help
 	  Support for HiSilicon SoC L3 Cache performance monitor, Hydra Home
 	  Agent performance monitor and DDR Controller performance monitor.
+
+config HISI_PCIE_PMU
+	tristate "HiSilicon PCIE PERF PMU"
+	depends on PCI && ARM64
+	help
+	  Provide support for HiSilicon PCIe performance monitoring unit (PMU)
+	  RCiEP devices.
+	  Adds the PCIe PMU into perf events system for monitoring latency,
+	  bandwidth etc.
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
index 7643c9f93e36..506ed39e3266 100644
--- a/drivers/perf/hisilicon/Makefile
+++ b/drivers/perf/hisilicon/Makefile
@@ -2,3 +2,5 @@
 obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
 			  hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
 			  hisi_uncore_pa_pmu.o
+
+obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
new file mode 100644
index 000000000000..7a8613b049f5
--- /dev/null
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
@@ -0,0 +1,972 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This driver adds support for PCIe PMU RCiEP device. Related
+ * perf events are bandwidth, bandwidth utilization, latency
+ * etc.
+ *
+ * Copyright (C) 2021 HiSilicon Limited
+ * Author: Qi Liu <liuqi115 at huawei.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/bitmap.h>
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/perf_event.h>
+
+#define DRV_NAME "hisi_pcie_pmu"
+/* Define registers */
+#define HISI_PCIE_GLOBAL_CTRL		0x00
+#define HISI_PCIE_EVENT_CTRL		0x010
+#define HISI_PCIE_CNT			0x090
+#define HISI_PCIE_EXT_CNT		0x110
+#define HISI_PCIE_INT_STAT		0x150
+#define HISI_PCIE_INT_MASK		0x154
+#define HISI_PCIE_REG_BDF		0xfe0
+#define HISI_PCIE_REG_VERSION		0xfe4
+#define HISI_PCIE_REG_INFO		0xfe8
+
+/* Define command in HISI_PCIE_GLOBAL_CTRL */
+#define HISI_PCIE_GLOBAL_EN		0x01
+#define HISI_PCIE_GLOBAL_NONE		0
+
+/* Define command in HISI_PCIE_EVENT_CTRL */
+#define HISI_PCIE_EVENT_EN		BIT_ULL(20)
+#define HISI_PCIE_RESET_CNT		BIT_ULL(22)
+#define HISI_PCIE_INIT_SET		BIT_ULL(34)
+#define HISI_PCIE_THR_EN		BIT_ULL(26)
+#define HISI_PCIE_TARGET_EN		BIT_ULL(32)
+#define HISI_PCIE_TRIG_EN		BIT_ULL(52)
+
+/* Define offsets in HISI_PCIE_EVENT_CTRL */
+#define HISI_PCIE_EVENT_M		GENMASK_ULL(15, 0)
+#define HISI_PCIE_THR_MODE_M		GENMASK_ULL(27, 27)
+#define HISI_PCIE_THR_M			GENMASK_ULL(31, 28)
+#define HISI_PCIE_TARGET_M		GENMASK_ULL(52, 36)
+#define HISI_PCIE_TRIG_MODE_M		GENMASK_ULL(53, 53)
+#define HISI_PCIE_TRIG_M		GENMASK_ULL(59, 56)
+
+#define HISI_PCIE_MAX_COUNTERS		8
+#define HISI_PCIE_REG_STEP		8
+#define HISI_PCIE_THR_MAX_VAL		10
+#define HISI_PCIE_TRIG_MAX_VAL		10
+#define HISI_PCIE_MAX_PERIOD		(GENMASK_ULL(63, 0))
+#define HISI_PCIE_INIT_VAL		BIT_ULL(63)
+
+struct hisi_pcie_pmu {
+	struct perf_event *hw_events[HISI_PCIE_MAX_COUNTERS];
+	struct hlist_node node;
+	struct pci_dev *pdev;
+	struct pmu pmu;
+	void __iomem *base;
+	int irq;
+	u32 identifier;
+	/* Minimum and maximum bdf of root ports monitored by PMU */
+	u16 bdf_min;
+	u16 bdf_max;
+	int on_cpu;
+};
+
+struct hisi_pcie_reg_pair {
+	u16 lo;
+	u16 hi;
+};
+
+#define to_pcie_pmu(p)  (container_of((p), struct hisi_pcie_pmu, pmu))
+#define GET_PCI_DEVFN(bdf)  ((bdf) & 0xff)
+
+#define HISI_PCIE_PMU_FILTER_ATTR(_name, _config, _hi, _lo)		  \
+	static u64 hisi_pcie_get_##_name(struct perf_event *event)	  \
+	{								  \
+		return FIELD_GET(GENMASK(_hi, _lo), event->attr._config); \
+	}								  \
+
+HISI_PCIE_PMU_FILTER_ATTR(event, config, 16, 0);
+HISI_PCIE_PMU_FILTER_ATTR(thr_len, config1, 3, 0);
+HISI_PCIE_PMU_FILTER_ATTR(thr_mode, config1, 4, 4);
+HISI_PCIE_PMU_FILTER_ATTR(trig_len, config1, 8, 5);
+HISI_PCIE_PMU_FILTER_ATTR(trig_mode, config1, 9, 9);
+HISI_PCIE_PMU_FILTER_ATTR(port, config2, 15, 0);
+HISI_PCIE_PMU_FILTER_ATTR(bdf, config2, 31, 16);
+
+static ssize_t hisi_pcie_format_sysfs_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct dev_ext_attribute *eattr;
+
+	eattr = container_of(attr, struct dev_ext_attribute, attr);
+
+	return sysfs_emit(buf, "%s\n", (char *)eattr->var);
+}
+
+static ssize_t hisi_pcie_event_sysfs_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct perf_pmu_events_attr *pmu_attr =
+		container_of(attr, struct perf_pmu_events_attr, attr);
+
+	return sysfs_emit(buf, "config=0x%llx\n", pmu_attr->id);
+}
+
+#define HISI_PCIE_PMU_FORMAT_ATTR(_name, _format)                              \
+	(&((struct dev_ext_attribute[]){                                       \
+		{ .attr = __ATTR(_name, 0444, hisi_pcie_format_sysfs_show,     \
+				 NULL),                                        \
+		  .var = (void *)_format }                                     \
+	})[0].attr.attr)
+
+#define HISI_PCIE_PMU_EVENT_ATTR(_name, _id)			\
+	PMU_EVENT_ATTR_ID(_name, hisi_pcie_event_sysfs_show, _id)
+
+static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
+
+	return cpumap_print_to_pagebuf(true, buf, cpumask_of(pcie_pmu->on_cpu));
+}
+static DEVICE_ATTR_RO(cpumask);
+
+static ssize_t identifier_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
+
+	return sysfs_emit(buf, "%#x\n", pcie_pmu->identifier);
+}
+static DEVICE_ATTR_RO(identifier);
+
+static ssize_t bus_show(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev));
+
+	return sysfs_emit(buf, "%#04x\n", PCI_BUS_NUM(pcie_pmu->bdf_min));
+}
+static DEVICE_ATTR_RO(bus);
+
+static struct hisi_pcie_reg_pair
+hisi_pcie_parse_reg_value(struct hisi_pcie_pmu *pcie_pmu, u32 reg_off)
+{
+	u32 val = readl_relaxed(pcie_pmu->base + reg_off);
+	struct hisi_pcie_reg_pair regs = {
+		.lo = val,
+		.hi = val >> 16,
+	};
+
+	return regs;
+}
+
+/*
+ * Hardware counter and ext_counter work together for bandwidth, latency, bus
+ * utilization and buffer occupancy events. For example, RX memory write latency
+ * events(index = 0x0010), counter counts total delay cycles and ext_counter
+ * counts RX memory write PCIe packets number.
+ *
+ * As we don't want PMU driver to process these two data, "delay cycles" can
+ * be treated as an independent event(index = 0x0010), "RX memory write packets
+ * number" as another(index = 0x10010). BIT 16 is used to distinguish and 0-15
+ * bits are "real" event index, which can be used to set HISI_PCIE_EVENT_CTRL.
+ */
+#define EXT_COUNTER_IS_USED(idx)		((idx) & BIT(16))
+
+static u32 hisi_pcie_get_real_event(struct perf_event *event)
+{
+	return hisi_pcie_get_event(event) & GENMASK(15, 0);
+}
+
+static u32 hisi_pcie_pmu_get_offset(u32 offset, u32 idx)
+{
+	return offset + HISI_PCIE_REG_STEP * idx;
+}
+
+static u32 hisi_pcie_pmu_readl(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
+			       u32 idx)
+{
+	u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
+
+	return readl_relaxed(pcie_pmu->base + offset);
+}
+
+static void hisi_pcie_pmu_writel(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
+				 u32 idx, u32 val)
+{
+	u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
+
+	writel_relaxed(val, pcie_pmu->base + offset);
+}
+
+static u64 hisi_pcie_pmu_readq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
+			       u32 idx)
+{
+	u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
+
+	return readq_relaxed(pcie_pmu->base + offset);
+}
+
+static void hisi_pcie_pmu_writeq(struct hisi_pcie_pmu *pcie_pmu, u32 reg_offset,
+				 u32 idx, u64 val)
+{
+	u32 offset = hisi_pcie_pmu_get_offset(reg_offset, idx);
+
+	writeq_relaxed(val, pcie_pmu->base + offset);
+}
+
+static void hisi_pcie_pmu_config_filter(struct perf_event *event)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 reg = HISI_PCIE_INIT_SET;
+	u64 port, trig_len, thr_len;
+
+	/* Config HISI_PCIE_EVENT_CTRL according to event. */
+	reg |= FIELD_PREP(HISI_PCIE_EVENT_M, hisi_pcie_get_real_event(event));
+
+	/* Config HISI_PCIE_EVENT_CTRL according to ROOT PORT or EP device. */
+	port = hisi_pcie_get_port(event);
+	if (port)
+		reg |= FIELD_PREP(HISI_PCIE_TARGET_M, port);
+	else
+		reg |= HISI_PCIE_TARGET_EN |
+		       FIELD_PREP(HISI_PCIE_TARGET_M, hisi_pcie_get_bdf(event));
+
+	/* Config HISI_PCIE_EVENT_CTRL according to trigger condition. */
+	trig_len = hisi_pcie_get_trig_len(event);
+	if (trig_len) {
+		reg |= FIELD_PREP(HISI_PCIE_TRIG_M, trig_len);
+		reg |= FIELD_PREP(HISI_PCIE_TRIG_MODE_M,
+				  hisi_pcie_get_trig_mode(event));
+		reg |= HISI_PCIE_TRIG_EN;
+	}
+
+	/* Config HISI_PCIE_EVENT_CTRL according to threshold condition. */
+	thr_len = hisi_pcie_get_thr_len(event);
+	if (thr_len) {
+		reg |= FIELD_PREP(HISI_PCIE_THR_M, thr_len);
+		reg |= FIELD_PREP(HISI_PCIE_THR_MODE_M,
+		       hisi_pcie_get_thr_mode(event));
+		reg |= HISI_PCIE_THR_EN;
+	}
+
+	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
+}
+
+static void hisi_pcie_pmu_clear_filter(struct perf_event *event)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx,
+			     HISI_PCIE_INIT_SET);
+}
+
+static bool hisi_pcie_pmu_valid_requester_id(struct hisi_pcie_pmu *pcie_pmu,
+					     u32 bdf)
+{
+	struct pci_dev *root_port, *pdev;
+	u16 rp_bdf;
+
+	pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pcie_pmu->pdev->bus),
+					   PCI_BUS_NUM(bdf),
+					   GET_PCI_DEVFN(bdf));
+	if (!pdev)
+		return false;
+
+	root_port = pcie_find_root_port(pdev);
+	if (!root_port) {
+		pci_dev_put(pdev);
+		return false;
+	}
+
+	pci_dev_put(pdev);
+	rp_bdf = pci_dev_id(root_port);
+	return rp_bdf >= pcie_pmu->bdf_min && rp_bdf <= pcie_pmu->bdf_max;
+}
+
+static bool hisi_pcie_pmu_valid_filter(struct perf_event *event,
+				       struct hisi_pcie_pmu *pcie_pmu)
+{
+	u32 requester_id = hisi_pcie_get_bdf(event);
+
+	if (hisi_pcie_get_thr_len(event) > HISI_PCIE_THR_MAX_VAL)
+		return false;
+
+	if (hisi_pcie_get_trig_len(event) > HISI_PCIE_TRIG_MAX_VAL)
+		return false;
+
+	if (requester_id) {
+		if (!hisi_pcie_pmu_valid_requester_id(pcie_pmu, requester_id))
+			return false;
+	}
+
+	return true;
+}
+
+static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)
+{
+	struct perf_event *sibling, *leader = event->group_leader;
+	int counters = 1;
+
+	if (!is_software_event(leader)) {
+		if (leader->pmu != event->pmu)
+			return false;
+
+		if (leader != event)
+			counters++;
+	}
+
+	for_each_sibling_event(sibling, event->group_leader) {
+		if (is_software_event(sibling))
+			continue;
+
+		if (sibling->pmu != event->pmu)
+			return false;
+
+		counters++;
+	}
+
+	return counters <= HISI_PCIE_MAX_COUNTERS;
+}
+
+static int hisi_pcie_pmu_event_init(struct perf_event *event)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	event->cpu = pcie_pmu->on_cpu;
+
+	if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event)))
+		hwc->event_base = HISI_PCIE_EXT_CNT;
+	else
+		hwc->event_base = HISI_PCIE_CNT;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/* Sampling is not supported. */
+	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+		return -EOPNOTSUPP;
+
+	if (!hisi_pcie_pmu_valid_filter(event, pcie_pmu)) {
+		pci_err(pcie_pmu->pdev, "Invalid filter!\n");
+		return -EINVAL;
+	}
+
+	if (!hisi_pcie_pmu_validate_event_group(event))
+		return -EINVAL;
+
+	return 0;
+}
+
+static u64 hisi_pcie_pmu_read_counter(struct perf_event *event)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	u32 idx = event->hw.idx;
+
+	return hisi_pcie_pmu_readq(pcie_pmu, event->hw.event_base, idx);
+}
+
+static int hisi_pcie_pmu_find_related_event(struct hisi_pcie_pmu *pcie_pmu,
+					    struct perf_event *event)
+{
+	struct perf_event *sibling;
+	int idx;
+
+	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
+		sibling = pcie_pmu->hw_events[idx];
+		if (!sibling)
+			continue;
+
+		if (hisi_pcie_get_real_event(sibling) !=
+		    hisi_pcie_get_real_event(event))
+			continue;
+
+		/* Related events must be used in group */
+		if (sibling->group_leader == event->group_leader)
+			return idx;
+		else
+			return -EINVAL;
+	}
+
+	return idx;
+}
+
+static int hisi_pcie_pmu_get_event_idx(struct hisi_pcie_pmu *pcie_pmu)
+{
+	int idx;
+
+	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
+		if (!pcie_pmu->hw_events[idx])
+			return idx;
+	}
+
+	return -EINVAL;
+}
+
+static void hisi_pcie_pmu_event_update(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 new_cnt, prev_cnt, delta;
+
+	do {
+		prev_cnt = local64_read(&hwc->prev_count);
+		new_cnt = hisi_pcie_pmu_read_counter(event);
+	} while (local64_cmpxchg(&hwc->prev_count, prev_cnt,
+				 new_cnt) != prev_cnt);
+
+	delta = (new_cnt - prev_cnt) & HISI_PCIE_MAX_PERIOD;
+	local64_add(delta, &event->count);
+}
+
+static void hisi_pcie_pmu_read(struct perf_event *event)
+{
+	hisi_pcie_pmu_event_update(event);
+}
+
+static void hisi_pcie_pmu_set_period(struct perf_event *event)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	local64_set(&hwc->prev_count, HISI_PCIE_INIT_VAL);
+	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_CNT, idx, HISI_PCIE_INIT_VAL);
+	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EXT_CNT, idx,
+			     HISI_PCIE_INIT_VAL);
+}
+
+static void hisi_pcie_pmu_enable_counter(struct hisi_pcie_pmu *pcie_pmu,
+					 struct hw_perf_event *hwc)
+{
+	u32 idx = hwc->idx;
+	u64 val;
+
+	val = hisi_pcie_pmu_readq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx);
+	val |= HISI_PCIE_EVENT_EN;
+	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, val);
+}
+
+static void hisi_pcie_pmu_disable_counter(struct hisi_pcie_pmu *pcie_pmu,
+					  struct hw_perf_event *hwc)
+{
+	u32 idx = hwc->idx;
+	u64 val;
+
+	val = hisi_pcie_pmu_readq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx);
+	val &= ~HISI_PCIE_EVENT_EN;
+	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx, val);
+}
+
+static void hisi_pcie_pmu_enable_int(struct hisi_pcie_pmu *pcie_pmu,
+				     struct hw_perf_event *hwc)
+{
+	u32 idx = hwc->idx;
+
+	hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_MASK, idx, 0);
+}
+
+static void hisi_pcie_pmu_disable_int(struct hisi_pcie_pmu *pcie_pmu,
+				      struct hw_perf_event *hwc)
+{
+	u32 idx = hwc->idx;
+
+	hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_MASK, idx, 1);
+}
+
+static void hisi_pcie_pmu_reset_counter(struct hisi_pcie_pmu *pcie_pmu,
+					int idx)
+{
+	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx,
+			     HISI_PCIE_RESET_CNT);
+	hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, idx,
+			     HISI_PCIE_INIT_SET);
+}
+
+static void hisi_pcie_pmu_start(struct perf_event *event, int flags)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+	u64 prev_cnt;
+
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+	hwc->state = 0;
+
+	hisi_pcie_pmu_config_filter(event);
+	hisi_pcie_pmu_enable_counter(pcie_pmu, hwc);
+	hisi_pcie_pmu_enable_int(pcie_pmu, hwc);
+	hisi_pcie_pmu_set_period(event);
+
+	if (flags & PERF_EF_RELOAD) {
+		prev_cnt = local64_read(&hwc->prev_count);
+		hisi_pcie_pmu_writeq(pcie_pmu, hwc->event_base, idx, prev_cnt);
+	}
+
+	perf_event_update_userpage(event);
+}
+
+static void hisi_pcie_pmu_stop(struct perf_event *event, int flags)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	hisi_pcie_pmu_event_update(event);
+	hisi_pcie_pmu_disable_int(pcie_pmu, hwc);
+	hisi_pcie_pmu_disable_counter(pcie_pmu, hwc);
+	hisi_pcie_pmu_clear_filter(event);
+	WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+	hwc->state |= PERF_HES_STOPPED;
+
+	if (hwc->state & PERF_HES_UPTODATE)
+		return;
+
+	hwc->state |= PERF_HES_UPTODATE;
+}
+
+static int hisi_pcie_pmu_add(struct perf_event *event, int flags)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+
+	/* Check all working events to find a related event. */
+	idx = hisi_pcie_pmu_find_related_event(pcie_pmu, event);
+	if (idx < 0)
+		return idx;
+
+	/* Current event shares an enabled counter with the related event */
+	if (idx < HISI_PCIE_MAX_COUNTERS) {
+		hwc->idx = idx;
+		goto start_count;
+	}
+
+	idx = hisi_pcie_pmu_get_event_idx(pcie_pmu);
+	if (idx < 0)
+		return idx;
+
+	hwc->idx = idx;
+	pcie_pmu->hw_events[idx] = event;
+	/* Reset Counter to avoid previous statistic interference. */
+	hisi_pcie_pmu_reset_counter(pcie_pmu, idx);
+
+start_count:
+	if (flags & PERF_EF_START)
+		hisi_pcie_pmu_start(event, PERF_EF_RELOAD);
+
+	return 0;
+}
+
+static void hisi_pcie_pmu_del(struct perf_event *event, int flags)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	hisi_pcie_pmu_stop(event, PERF_EF_UPDATE);
+	pcie_pmu->hw_events[hwc->idx] = NULL;
+	perf_event_update_userpage(event);
+}
+
+static void hisi_pcie_pmu_enable(struct pmu *pmu)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(pmu);
+	int num;
+
+	for (num = 0; num < HISI_PCIE_MAX_COUNTERS; num++) {
+		if (pcie_pmu->hw_events[num])
+			break;
+	}
+
+	if (num == HISI_PCIE_MAX_COUNTERS)
+		return;
+
+	writel(HISI_PCIE_GLOBAL_EN, pcie_pmu->base + HISI_PCIE_GLOBAL_CTRL);
+}
+
+static void hisi_pcie_pmu_disable(struct pmu *pmu)
+{
+	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(pmu);
+
+	writel(HISI_PCIE_GLOBAL_NONE, pcie_pmu->base + HISI_PCIE_GLOBAL_CTRL);
+}
+
+static irqreturn_t hisi_pcie_pmu_irq(int irq, void *data)
+{
+	struct hisi_pcie_pmu *pcie_pmu = data;
+	irqreturn_t ret = IRQ_NONE;
+	struct perf_event *event;
+	u32 overflown;
+	int idx;
+
+	for (idx = 0; idx < HISI_PCIE_MAX_COUNTERS; idx++) {
+		overflown = hisi_pcie_pmu_readl(pcie_pmu, HISI_PCIE_INT_STAT,
+						idx);
+		if (!overflown)
+			continue;
+
+		/* Clear status of interrupt. */
+		hisi_pcie_pmu_writel(pcie_pmu, HISI_PCIE_INT_STAT, idx, 1);
+		event = pcie_pmu->hw_events[idx];
+		if (!event)
+			continue;
+
+		hisi_pcie_pmu_event_update(event);
+		hisi_pcie_pmu_set_period(event);
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+static int hisi_pcie_pmu_irq_register(struct pci_dev *pdev,
+				      struct hisi_pcie_pmu *pcie_pmu)
+{
+	int irq, ret;
+
+	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
+	if (ret < 0) {
+		pci_err(pdev, "Failed to enable MSI vectors: %d!\n", ret);
+		return ret;
+	}
+
+	irq = pci_irq_vector(pdev, 0);
+	ret = request_irq(irq, hisi_pcie_pmu_irq,
+			  IRQF_NOBALANCING | IRQF_NO_THREAD, DRV_NAME,
+			  pcie_pmu);
+	if (ret) {
+		pci_err(pdev, "Failed to register IRQ: %d!\n", ret);
+		pci_free_irq_vectors(pdev);
+		return ret;
+	}
+
+	pcie_pmu->irq = irq;
+
+	return 0;
+}
+
+static void hisi_pcie_pmu_irq_unregister(struct pci_dev *pdev,
+					 struct hisi_pcie_pmu *pcie_pmu)
+{
+	free_irq(pcie_pmu->irq, pcie_pmu);
+	pci_free_irq_vectors(pdev);
+}
+
+static int hisi_pcie_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct hisi_pcie_pmu *pcie_pmu = hlist_entry_safe(node,
+					 struct hisi_pcie_pmu, node);
+
+	if (pcie_pmu->on_cpu == -1) {
+		pcie_pmu->on_cpu = cpu;
+		WARN_ON(irq_set_affinity(pcie_pmu->irq, cpumask_of(cpu)));
+	}
+
+	return 0;
+}
+
+static int hisi_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct hisi_pcie_pmu *pcie_pmu = hlist_entry_safe(node,
+					 struct hisi_pcie_pmu, node);
+	unsigned int target;
+
+	/* Nothing to do if this CPU doesn't own the PMU */
+	if (pcie_pmu->on_cpu != cpu)
+		return 0;
+
+	pcie_pmu->on_cpu = -1;
+	/* Choose a new CPU from all online cpus. */
+	target = cpumask_first(cpu_online_mask);
+	if (target >= nr_cpu_ids) {
+		pci_err(pcie_pmu->pdev, "There is no CPU to set!\n");
+		return 0;
+	}
+
+	perf_pmu_migrate_context(&pcie_pmu->pmu, cpu, target);
+	/* Use this CPU for event counting */
+	pcie_pmu->on_cpu = target;
+	WARN_ON(irq_set_affinity(pcie_pmu->irq, cpumask_of(target)));
+
+	return 0;
+}
+
+/*
+ * Events with the "dl" suffix in their names count performance in DL layer,
+ * otherswise, events count performance in TL layer.
+ */
+static struct attribute *hisi_pcie_pmu_events_attr[] = {
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_latency, 0x0010),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mwr_cnt, 0x10010),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_latency, 0x0210),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x1005),
+	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x11005),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x2004),
+	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x12004),
+	NULL
+};
+
+static struct attribute_group hisi_pcie_pmu_events_group = {
+	.name = "events",
+	.attrs = hisi_pcie_pmu_events_attr,
+};
+
+static struct attribute *hisi_pcie_pmu_format_attr[] = {
+	HISI_PCIE_PMU_FORMAT_ATTR(event, "config:0-16"),
+	HISI_PCIE_PMU_FORMAT_ATTR(thr_len, "config1:0-3"),
+	HISI_PCIE_PMU_FORMAT_ATTR(thr_mode, "config1:4"),
+	HISI_PCIE_PMU_FORMAT_ATTR(trig_len, "config1:5-8"),
+	HISI_PCIE_PMU_FORMAT_ATTR(trig_mode, "config1:9"),
+	HISI_PCIE_PMU_FORMAT_ATTR(port, "config2:0-15"),
+	HISI_PCIE_PMU_FORMAT_ATTR(bdf, "config2:16-31"),
+	NULL
+};
+
+static const struct attribute_group hisi_pcie_pmu_format_group = {
+	.name = "format",
+	.attrs = hisi_pcie_pmu_format_attr,
+};
+
+static struct attribute *hisi_pcie_pmu_bus_attrs[] = {
+	&dev_attr_bus.attr,
+	NULL
+};
+
+static const struct attribute_group hisi_pcie_pmu_bus_attr_group = {
+	.attrs = hisi_pcie_pmu_bus_attrs,
+};
+
+static struct attribute *hisi_pcie_pmu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL
+};
+
+static const struct attribute_group hisi_pcie_pmu_cpumask_attr_group = {
+	.attrs = hisi_pcie_pmu_cpumask_attrs,
+};
+
+static struct attribute *hisi_pcie_pmu_identifier_attrs[] = {
+	&dev_attr_identifier.attr,
+	NULL
+};
+
+static const struct attribute_group hisi_pcie_pmu_identifier_attr_group = {
+	.attrs = hisi_pcie_pmu_identifier_attrs,
+};
+
+static const struct attribute_group *hisi_pcie_pmu_attr_groups[] = {
+	&hisi_pcie_pmu_events_group,
+	&hisi_pcie_pmu_format_group,
+	&hisi_pcie_pmu_bus_attr_group,
+	&hisi_pcie_pmu_cpumask_attr_group,
+	&hisi_pcie_pmu_identifier_attr_group,
+	NULL
+};
+
+static int hisi_pcie_alloc_pmu(struct pci_dev *pdev,
+			       struct hisi_pcie_pmu *pcie_pmu)
+{
+	struct hisi_pcie_reg_pair regs;
+	u16 sicl_id, core_id;
+	char *name;
+
+	regs = hisi_pcie_parse_reg_value(pcie_pmu, HISI_PCIE_REG_BDF);
+	pcie_pmu->bdf_min = regs.lo;
+	pcie_pmu->bdf_max = regs.hi;
+
+	regs = hisi_pcie_parse_reg_value(pcie_pmu, HISI_PCIE_REG_INFO);
+	sicl_id = regs.hi;
+	core_id = regs.lo;
+
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+			      "hisi_pcie%u_core%u", sicl_id, core_id);
+	if (!name)
+		return -ENOMEM;
+
+	pcie_pmu->pdev = pdev;
+	pcie_pmu->on_cpu = -1;
+	pcie_pmu->identifier = readl(pcie_pmu->base + HISI_PCIE_REG_VERSION);
+	pcie_pmu->pmu = (struct pmu) {
+		.name		= name,
+		.module		= THIS_MODULE,
+		.event_init	= hisi_pcie_pmu_event_init,
+		.pmu_enable	= hisi_pcie_pmu_enable,
+		.pmu_disable	= hisi_pcie_pmu_disable,
+		.add		= hisi_pcie_pmu_add,
+		.del		= hisi_pcie_pmu_del,
+		.start		= hisi_pcie_pmu_start,
+		.stop		= hisi_pcie_pmu_stop,
+		.read		= hisi_pcie_pmu_read,
+		.task_ctx_nr	= perf_invalid_context,
+		.attr_groups	= hisi_pcie_pmu_attr_groups,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+	};
+
+	return 0;
+}
+
+static int hisi_pcie_init_pmu(struct pci_dev *pdev,
+			      struct hisi_pcie_pmu *pcie_pmu)
+{
+	int ret;
+
+	pcie_pmu->base = pci_ioremap_bar(pdev, 2);
+	if (!pcie_pmu->base) {
+		pci_err(pdev, "Ioremap failed for pcie_pmu resource.\n");
+		return -ENOMEM;
+	}
+
+	ret = hisi_pcie_alloc_pmu(pdev, pcie_pmu);
+	if (ret)
+		goto err_ioremap_fail;
+
+	ret = hisi_pcie_pmu_irq_register(pdev, pcie_pmu);
+	if (ret)
+		goto err_ioremap_fail;
+
+	ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
+				       &pcie_pmu->node);
+	if (ret) {
+		pci_err(pdev, "Failed to register hotplug: %d.\n", ret);
+		goto err_irq_unregister;
+	}
+
+	ret = perf_pmu_register(&pcie_pmu->pmu, pcie_pmu->pmu.name, -1);
+	if (ret) {
+		pci_err(pdev, "Failed to register PCIe PMU: %d.\n", ret);
+		goto err_hotplug_unregister;
+	}
+
+	return ret;
+
+err_hotplug_unregister:
+	cpuhp_state_remove_instance_nocalls(
+		CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
+
+err_irq_unregister:
+	hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
+
+err_ioremap_fail:
+	iounmap(pcie_pmu->base);
+
+	return ret;
+}
+
+static void hisi_pcie_uninit_pmu(struct pci_dev *pdev)
+{
+	struct hisi_pcie_pmu *pcie_pmu = pci_get_drvdata(pdev);
+
+	perf_pmu_unregister(&pcie_pmu->pmu);
+	cpuhp_state_remove_instance_nocalls(
+		CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
+	hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
+	iounmap(pcie_pmu->base);
+}
+
+static int hisi_pcie_init_dev(struct pci_dev *pdev)
+{
+	int ret;
+
+	ret = pcim_enable_device(pdev);
+	if (ret) {
+		pci_err(pdev, "Failed to enable PCI device: %d.\n", ret);
+		return ret;
+	}
+
+	ret = pcim_iomap_regions(pdev, BIT(2), DRV_NAME);
+	if (ret < 0) {
+		pci_err(pdev, "Failed to request PCI mem regions: %d.\n", ret);
+		return ret;
+	}
+
+	pci_set_master(pdev);
+
+	return 0;
+}
+
+static int hisi_pcie_pmu_probe(struct pci_dev *pdev,
+			       const struct pci_device_id *id)
+{
+	struct hisi_pcie_pmu *pcie_pmu;
+	int ret;
+
+	pcie_pmu = devm_kzalloc(&pdev->dev, sizeof(*pcie_pmu), GFP_KERNEL);
+	if (!pcie_pmu)
+		return -ENOMEM;
+
+	ret = hisi_pcie_init_dev(pdev);
+	if (ret)
+		return ret;
+
+	ret = hisi_pcie_init_pmu(pdev, pcie_pmu);
+	if (ret)
+		return ret;
+
+	pci_set_drvdata(pdev, pcie_pmu);
+
+	return ret;
+}
+
+static void hisi_pcie_pmu_remove(struct pci_dev *pdev)
+{
+	hisi_pcie_uninit_pmu(pdev);
+	pci_set_drvdata(pdev, NULL);
+}
+
+static const struct pci_device_id hisi_pcie_pmu_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, 0xa12d) },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, hisi_pcie_pmu_ids);
+
+static struct pci_driver hisi_pcie_pmu_driver = {
+	.name = DRV_NAME,
+	.id_table = hisi_pcie_pmu_ids,
+	.probe = hisi_pcie_pmu_probe,
+	.remove = hisi_pcie_pmu_remove,
+};
+
+static int __init hisi_pcie_module_init(void)
+{
+	int ret;
+
+	ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
+				      "AP_PERF_ARM_HISI_PCIE_PMU_ONLINE",
+				      hisi_pcie_pmu_online_cpu,
+				      hisi_pcie_pmu_offline_cpu);
+	if (ret) {
+		pr_err("Failed to setup PCIe PMU hotplug, ret = %d.\n", ret);
+		return ret;
+	}
+
+	ret = pci_register_driver(&hisi_pcie_pmu_driver);
+	if (ret)
+		cpuhp_remove_multi_state(
+				CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
+
+	return ret;
+}
+module_init(hisi_pcie_module_init);
+
+static void __exit hisi_pcie_module_exit(void)
+{
+	pci_unregister_driver(&hisi_pcie_pmu_driver);
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
+}
+module_exit(hisi_pcie_module_exit);
+
+MODULE_DESCRIPTION("HiSilicon PCIe PMU driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Qi Liu <liuqi115 at huawei.com>");
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index f39b34b13871..4008560e7b8c 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -179,6 +179,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
 	CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
 	CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
+	CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
 	CPUHP_AP_PERF_ARM_L2X0_ONLINE,
 	CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
 	CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
-- 
2.17.1



From piyush.mehta at xilinx.com  Wed Aug 18 01:43:11 2021
From: piyush.mehta at xilinx.com (Piyush Mehta)
Date: Wed, 18 Aug 2021 14:13:11 +0530
Subject: [PATCH] phy: xilinx: zynqmp: skip PHY initialization and PLL lock for
 USB
Message-ID: <20210818084311.2643986-1-piyush.mehta@xilinx.com>

PHY initialization for USB is required on linux boot or when
gt lane is changed from the current one and it is applicable
on PLL lock too.

Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
---
 drivers/phy/xilinx/phy-zynqmp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c
index 35652152ce5d..f478d8a17115 100644
--- a/drivers/phy/xilinx/phy-zynqmp.c
+++ b/drivers/phy/xilinx/phy-zynqmp.c
@@ -626,6 +626,9 @@ static int xpsgtr_phy_power_on(struct phy *phy)
 	struct xpsgtr_phy *gtr_phy = phy_get_drvdata(phy);
 	int ret = 0;
 
+	/* Skip initialization if not required. */
+	if (!xpsgtr_phy_init_required(gtr_phy))
+		return ret;
 	/*
 	 * Wait for the PLL to lock. For DP, only wait on DP0 to avoid
 	 * cumulating waits for both lanes. The user is expected to initialize
-- 
2.25.1



From maxime at cerno.tech  Wed Aug 18 01:45:39 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 10:45:39 +0200
Subject: [PATCH 27/54] dt-bindings: net: wireless: Convert ESP ESP8089
 binding to a schema
In-Reply-To: <20210806084709.0C279C4338A@smtp.codeaurora.org>
References: <20210721140424.725744-28-maxime@cerno.tech>
 <20210806084709.0C279C4338A@smtp.codeaurora.org>
Message-ID: <20210818084539.kw267o4dc5nqk2qt@gilmour>

Hi Kalle,

On Fri, Aug 06, 2021 at 08:47:09AM +0000, Kalle Valo wrote:
> Maxime Ripard <maxime at cerno.tech> wrote:
> 
> > The ESP8089 Wireless Chip is supported by Linux (through an out-of-tree
> > driver) thanks to its device tree binding.
> > 
> > Now that we have the DT validation in place, let's convert the device
> > tree bindings for that driver over to a YAML schema.
> > 
> > Cc: "David S. Miller" <davem at davemloft.net>
> > Cc: de Goede <hdegoede at redhat.com>
> > Cc: Jakub Kicinski <kuba at kernel.org>
> > Cc: Kalle Valo <kvalo at codeaurora.org>
> > Cc: linux-wireless at vger.kernel.org
> > Cc: netdev at vger.kernel.org
> > Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> > Reviewed-by: Rob Herring <robh at kernel.org>
> 
> We support out-of-tree drivers in DT?

Yeah, as long as the binding is stable we can merge it. This controller
is one of these examples, but we supported multiple GPU that way too.

> Via which tree is this supposed to go? I guess not via
> wireless-drivers-next as this is an out-of-tree driver.

It's up to you I guess. It was already part of the dt-bindings wireless
directory, so either your tree or the DT maintainers if you'd prefer not
to.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/d6963387/attachment.sig>

From maxime at cerno.tech  Wed Aug 18 01:47:13 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 10:47:13 +0200
Subject: [PATCH 12/17] dt-bindings: mmc: sunxi-mmc: add R329 MMC
 compatible string
In-Reply-To: <20210802062212.73220-13-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-13-icenowy@sipeed.com>
Message-ID: <20210818084713.klz3ijd4tskhorzm@gilmour>

On Mon, Aug 02, 2021 at 02:22:07PM +0800, Icenowy Zheng wrote:
> R329 SoC has two MMC controllers similar to ones in the previous
> Allwinner SoCs. However, as R329 has no eMMC controller, the two MMC
> controllers look like a mixture of previous SoCs' ordinary MMC
> controller and eMMC controller.
> 
> Add a compatible string for R329 MMC controllers.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/4e06c82f/attachment.sig>

From maxime at cerno.tech  Wed Aug 18 01:47:42 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 10:47:42 +0200
Subject: [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers
In-Reply-To: <20210802062212.73220-14-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-14-icenowy@sipeed.com>
Message-ID: <20210818084742.mi4mipyrjochvbat@gilmour>

On Mon, Aug 02, 2021 at 02:22:08PM +0800, Icenowy Zheng wrote:
> The two MMC controllers in Allwinner R329 have a mixed feature set
> comparing to the previous SoCs' ordinary MMC and eMMC controllers.
> 
> Add support for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/2f711405/attachment-0001.sig>

From maxime at cerno.tech  Wed Aug 18 01:48:15 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 10:48:15 +0200
Subject: [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO
 and R-PIO
In-Reply-To: <20210802062212.73220-7-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-7-icenowy@sipeed.com>
Message-ID: <20210818084815.o4gnstf2jjxhfq7n@gilmour>

On Mon, Aug 02, 2021 at 02:22:01PM +0800, Icenowy Zheng wrote:
> Allwinner R329 have two pin controllers similar to previous Allwinner
> SoCs, PIO and R-PIO.
> 
> Add compatible strings for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/c068f8b8/attachment.sig>

From maxime at cerno.tech  Wed Aug 18 01:48:54 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 10:48:54 +0200
Subject: [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin
 controller
In-Reply-To: <20210802062212.73220-8-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-8-icenowy@sipeed.com>
Message-ID: <20210818084854.4zo6u5heeamdg7kw@gilmour>

On Mon, Aug 02, 2021 at 02:22:02PM +0800, Icenowy Zheng wrote:
> Allwinner R329 SoC has two pin controllers similar to ones on previous
> SoCs, one in CPUX power domain and another in CPUS.
> 
> This patch adds support for the CPUX domain pin controller.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/8080df93/attachment.sig>

From maxime at cerno.tech  Wed Aug 18 01:50:41 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 10:50:41 +0200
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <20210802062212.73220-11-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-11-icenowy@sipeed.com>
Message-ID: <20210818085041.ge57t5xxw7wnepyd@gilmour>

On Mon, Aug 02, 2021 at 02:22:05PM +0800, Icenowy Zheng wrote:
> Allwinner R329 has clock controls in PRCM, like other new Allwinner
> SoCs.
> 
> Add support for them.
> 
> This driver is added before the main CCU because PLLs are controlled by
> R-CCU on R329.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>

The driver looks good, the title has a typo though (sunxi=ng vs sunxi-ng)

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/f7fcfe75/attachment.sig>

From a.fatoum at pengutronix.de  Wed Aug 18 01:52:02 2021
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Wed, 18 Aug 2021 10:52:02 +0200
Subject: [PATCH V3 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <20210818081018.2620544-4-piyush.mehta@xilinx.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-4-piyush.mehta@xilinx.com>
Message-ID: <b3d718af-6eb7-a212-f599-d0d91273afdc@pengutronix.de>

On 18.08.21 10:10, Piyush Mehta wrote:
> This patch adds driver support for the zynqmp modepin GPIO controller.
> GPIO modepin driver set and get the value and status of the PS_MODE pin,
> based on device-tree pin configuration. These four mode pins are
> configurable as input/output. The mode pin has a control register, which
> have lower four-bits [0:3] are configurable as input/output, next four-bits
> can be used for reading the data  as input[4:7], and next setting the
> output pin state output[8:11].
> 
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> Acked-by: Michal Simek <michal.simek at xilinx.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> ---

> +/**
> + * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input
> + * @chip:	gpio_chip instance to be worked on
> + * @pin:	gpio pin number within the device
> + *
> + * Return: 0 always
> + */
> +static int modepin_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
> +{
> +	return 0;
> +}

You say the gpio controller can configure pins as inputs or outputs.
Yet, .direction_input is doing nothing. So it's not clear to me,
how this sequence could work:

 - set gpio output high (writes bootmode)
 - set gpio to input (no-op, pin will remain high, not high impedance)

I didn't check the previous discussions, but if this indeed works as intended,
the how should be written here into the driver. That is a more useful comment
than kernel doc for a stub function.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From maxime at cerno.tech  Wed Aug 18 01:52:56 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 10:52:56 +0200
Subject: [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO pin
 controller
In-Reply-To: <20210802062212.73220-9-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-9-icenowy@sipeed.com>
Message-ID: <20210818085256.p5m5zwri6jfkgihy@gilmour>

On Mon, Aug 02, 2021 at 02:22:03PM +0800, Icenowy Zheng wrote:
> Allwinner R320 SoC has a pin controller in the CPUS power domain.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/fe8d04b5/attachment-0001.sig>

From maz at kernel.org  Wed Aug 18 01:57:37 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 09:57:37 +0100
Subject: [PATCH V2 0/5] KVM: arm64: General cleanups
In-Reply-To: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
References: <1628744994-16623-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <162927703840.2372.14610953148314715293.b4-ty@kernel.org>

On Thu, 12 Aug 2021 10:39:49 +0530, Anshuman Khandual wrote:
> This series contains mostly unrelated general cleanups. This series applies
> on v5.14-rc5 and has been boot tested with different page sized guests.
> 
> Changes in V2:
> 
> - Dropped the first patch regarding PAGE_[SHIFT|SIZE] per Marc
> - Added remaining ID_AA64MMFR0_PARANGE_ macros and ARM64_MIN_PARANGE_BITS per Marc
> - Dropped memory and cycle reference from commit message in [PATCH 3/5]
> - Changed return value as u32 in kvm_target_cpu() per Will
> 
> [...]

Applied to next, thanks!

[1/5] arm64/mm: Add remaining ID_AA64MMFR0_PARANGE_ macros
      commit: 504c6295b998effa682089747a96d7bb5933d4db
[2/5] KVM: arm64: Use ARM64_MIN_PARANGE_BITS as the minimum supported IPA
      commit: 9788c14060f3c179c376b2a87af1a430d4d84973
[3/5] KVM: arm64: Drop init_common_resources()
      commit: bf249d9e362f1011a839d57e771b4b1a7eed9656
[4/5] KVM: arm64: Drop check_kvm_target_cpu() based percpu probe
      commit: 6b7982fefc1fdcaa31b712f5fbc2e993cc99ad23
[5/5] KVM: arm64: Drop unused REQUIRES_VIRT
      commit: 9329752bc8659e3934e2b13434b2fddb0df0bb13

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From a.fatoum at pengutronix.de  Wed Aug 18 02:00:05 2021
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Wed, 18 Aug 2021 11:00:05 +0200
Subject: [PATCH V3 2/3] dt-bindings: gpio: zynqmp: Add binding
 documentation for modepin
In-Reply-To: <20210818081018.2620544-3-piyush.mehta@xilinx.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-3-piyush.mehta@xilinx.com>
Message-ID: <5e44ee87-f727-99fd-9860-d3d58a035dc4@pengutronix.de>

On 18.08.21 10:10, Piyush Mehta wrote:
> This patch adds DT binding document for zynqmp modepin GPIO controller.
> Modepin GPIO controller has four GPIO pins which can be configurable
> as input or output.
> 
> Modepin driver is a bridge between the peripheral driver and GPIO pins.
> It has set and get APIs for accessing GPIO pins, based on the device-tree
> entry of reset-gpio property in the peripheral driver, every pin can be
> configured as input/output and trigger GPIO pin.
> 
> For more information please refer zynqMp TRM link:
> Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
> Chapter 2: Signals, Interfaces, and Pins
> Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE
> 
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> Acked-by: Michal Simek <michal.simek at xilinx.com>
> ---
> Changes in v2:
> - Addressed review comments: Update commit message
> 
> Review Comments:
> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736
> 
> Changes in v3:
> - Addressed Rob and Michal review comments:
>   - Update DT example. 
> 
> Review Comments:
> https://lore.kernel.org/linux-arm-kernel/YRbBnRS0VosXcZWz at robh.at.kernel.org/
> https://lore.kernel.org/linux-arm-kernel/d71ad7f9-6972-8cc0-6dfb-b5306c9900d0 at xilinx.com/
> ---
>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 43 ++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
> 
> diff --git a/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
> new file mode 100644
> index 0000000..1442815
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
> @@ -0,0 +1,43 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: ZynqMP Mode Pin GPIO controller
> +
> +description:
> +  PS_MODE is 4-bits boot mode pins sampled on POR deassertion. Mode Pin
> +  GPIO controller with configurable from numbers of pins (from 0 to 3 per
> +  PS_MODE). Every pin can be configured as input/output.
So, at Linux runtime, someone decides to boot the system into e.g. a USB
recovery mode and then toggles the appropriate GPIOs and does a system
reset?

If so, are you aware of the reboot mode[1] infrastructure?

A reboot-mode-gpio driver on top of this GPIO controller would allow you
to describe the supported reboot modes in the device tree and instead of
exporting GPIOs to userspace, users can then just do

	systemctl restart recovery

to toggle the appropriate bits.

Also to be sure: PS_MODE are actual GPIO pins that you could toggle
board level components with, right? i.e. it's not just a register that
overrides the values read from the boot mode pins? (In the latter case
a syscon-reboot-mode without GPIO controller would be the correct
abstraction).

[1]: drivers/power/reset/reboot-mode.c

Cheers,
Ahmad

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From maxime at cerno.tech  Wed Aug 18 02:01:39 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 11:01:39 +0200
Subject: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
In-Reply-To: <20210802062212.73220-16-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-16-icenowy@sipeed.com>
Message-ID: <20210818090139.rllz4fvvq3pzdkls@gilmour>

On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
> Allwinner R329 is a new SoC focused on smart audio devices.
> 
> Add a DTSI file for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
>  1 file changed, 244 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> new file mode 100644
> index 000000000000..bfefa2b734b0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> @@ -0,0 +1,244 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +// Copyright (c) 2021 Sipeed
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu at 0 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <0>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu1: cpu at 1 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <1>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	osc24M: osc24M_clk {
> +		#clock-cells = <0>;
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "osc24M";
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		arm,no-tick-in-suspend;
> +		interrupts = <GIC_PPI 13
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 11
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 10
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		pio: pinctrl at 2000400 {
> +			compatible = "allwinner,sun50i-r329-pinctrl";
> +			reg = <0x02000400 0x400>;
> +			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
> +			clock-names = "apb", "hosc", "losc";
> +			gpio-controller;
> +			#gpio-cells = <3>;
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
> +
> +			uart0_pb_pins: uart0-pb-pins {
> +				pins = "PB4", "PB5";
> +				function = "uart0";
> +			};
> +
> +			mmc0_pf_pins: mmc0-pf-pins {
> +				pins = "PF0", "PF1", "PF2",
> +				       "PF3", "PF4", "PF5";
> +				function = "mmc0";
> +			};
> +
> +			mmc1_clk_pg0: mmc1-clk-pg0 {
> +				pins = "PG0";
> +				function = "mmc1_clk";
> +			};

Argh, of course it was bound to happen :)

Make sure your DT pass validation though, all your mmc1 node names will report errors.

> +
> +			mmc1_cmd_pg1: mmc1-clk-pg1 {

s/clk/cmd/ ?

> +				pins = "PG1";
> +				function = "mmc1_cmd";
> +			};
> +
> +			mmc1_d0_pg2: mmc1-clk-pg2 {

s/clk/d0/

> +				pins = "PG2";
> +				function = "mmc1_d0";
> +			};
> +
> +			mmc1_d1_pg3: mmc1-clk-pg3 {

s/clk/d1/

> +				pins = "PG3";
> +				function = "mmc1_d1";
> +			};
> +
> +			mmc1_d2_pg4: mmc1-clk-pg4 {

s/clk/d2/

> +				pins = "PG4";
> +				function = "mmc1_d2";
> +			};
> +
> +			mmc1_d3_pg5: mmc1-clk-pg5 {

s/clk/d3/

> +				pins = "PG5";
> +				function = "mmc1_d3";
> +			};
> +		};
> +
> +		ccu: clock at 2001000 {
> +			compatible = "allwinner,sun50i-r329-ccu";
> +			reg = <0x02001000 0x1000>;
> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
> +			clock-names = "hosc", "losc", "iosc";

Do we have a clock tree for the RTC? Is it the same than the H616?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/de2398f0/attachment.sig>

From maxime at cerno.tech  Wed Aug 18 02:03:17 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 11:03:17 +0200
Subject: [PATCH 14/17] dt-bindings: arm: sunxi: add compatible strings
 for Sipeed MaixSense
In-Reply-To: <20210802062212.73220-15-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-15-icenowy@sipeed.com>
Message-ID: <20210818090317.xqo62oy23jbc27ti@gilmour>

On Mon, Aug 02, 2021 at 02:22:09PM +0800, Icenowy Zheng wrote:
> Sipeed MaixSense is an Allwinner R329 development kit based on Maix IIA
> SoM.
> 
> Add compatible strings for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  Documentation/devicetree/bindings/arm/sunxi.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
> index 889128acf49a..bce306908eff 100644
> --- a/Documentation/devicetree/bindings/arm/sunxi.yaml
> +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
> @@ -444,6 +444,12 @@ properties:
>            - const: haoyu,a10-marsboard
>            - const: allwinner,sun4i-a10
>  
> +      - description: Sipeed MaixSense
> +        items:
> +          - const: sipeed,maixsense
> +          - const: sipeed,maix-iia
> +          - const: allwinner,sun50i-r329
> +

This should be ordered

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/a441e86c/attachment-0001.sig>

From andre.przywara at arm.com  Wed Aug 18 02:04:07 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 18 Aug 2021 10:04:07 +0100
Subject: [PATCH v8 02/11] dt-bindings: rtc: sun6i: Add H616 compatible
 string
In-Reply-To: <20210817073810.7stuzrppyjf4spab@gilmour>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210723153838.6785-3-andre.przywara@arm.com>
 <20210726144137.6dauuxdssu7yszox@gilmour>
 <20210802013938.29fa18ed@slackpad.fritz.box>
 <20210817073810.7stuzrppyjf4spab@gilmour>
Message-ID: <20210818100407.7cf7cfb7@slackpad.fritz.box>

On Tue, 17 Aug 2021 09:38:10 +0200
Maxime Ripard <maxime at cerno.tech> wrote:

Hi Maxime,

> On Mon, Aug 02, 2021 at 01:39:38AM +0100, Andre Przywara wrote:
> > On Mon, 26 Jul 2021 16:41:37 +0200
> > Maxime Ripard <maxime at cerno.tech> wrote:
> >   
> > > Hi,
> > > 
> > > On Fri, Jul 23, 2021 at 04:38:29PM +0100, Andre Przywara wrote:  
> > > > Add the obvious compatible name to the existing RTC binding.
> > > > The actual RTC part of the device uses a different day/month/year
> > > > storage scheme, so it's not compatible with the previous devices.
> > > > Also the clock part is quite different, as there is no external 32K LOSC
> > > > oscillator input.
> > > > 
> > > > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > > >
> > > > ---
> > > >  .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml      | 14 ++++++++++++++
> > > >  1 file changed, 14 insertions(+)
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > > > index beeb90e55727..d8a6500e5840 100644
> > > > --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > > > +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
> > > > @@ -26,6 +26,7 @@ properties:
> > > >            - const: allwinner,sun50i-a64-rtc
> > > >            - const: allwinner,sun8i-h3-rtc
> > > >        - const: allwinner,sun50i-h6-rtc
> > > > +      - const: allwinner,sun50i-h616-rtc
> > > >  
> > > >    reg:
> > > >      maxItems: 1
> > > > @@ -104,6 +105,19 @@ allOf:
> > > >            minItems: 3
> > > >            maxItems: 3
> > > >  
> > > > +  - if:
> > > > +      properties:
> > > > +        compatible:
> > > > +          contains:
> > > > +            const: allwinner,sun50i-h616-rtc
> > > > +
> > > > +    then:
> > > > +      properties:
> > > > +        clock-output-names:
> > > > +          minItems: 3
> > > > +          maxItems: 3    
> > > 
> > > You don't need both of them when they are equal
> > >   
> > > > +        clocks: false
> > > > +    
> > > 
> > > It's not entirely clear to me what those clocks are about though. If we
> > > look at the clock output in the user manual, it looks like there's only
> > > two clocks that are actually being output: the 32k "fanout" clock and
> > > the losc. What are the 3 you're talking about?]  
> > 
> > I see three: the raw SYSTEM "CLK32K_LOSC", the RTC input + debounce
> > clock (/32), and the multiplexed PAD.  
> 
> But the input and debounce clock is only for the RTC itself right? So it
> should be local to the driver and doesn't need to be made available to
> the other drivers

I understood "debounce" as being the clock used for the pinctrl
debouncer. What would it debounce otherwise? Do you think that this
"debounce circuit" is something internal to the RTC and is totally
irrelevant for us?

But in general I looked at how many *different* clocks this diagram
describes, and I count: one unaltered ("SYSTEM"), one "div by
32" (RTC/debounce), and one multiplexed. My aim was to avoid
DT binding changes when we later discover we do need one of them for
something (as happened in the past). So three seemed to be the safe
choice here, to avoid surprises. In the worst case we just will never
reference one of them.

> Either way, what this list is must be documented.

You mean to overwrite the "description" stanza for clock-output-names?
And can this be done in the per-SoC parts in the later part of the
binding, keeping the existing description?

Cheers,
Andre

> 
> > > Also, it looks like the 32k fanout clock needs at least the hosc or
> > > pll-periph in input, so we probably don't want to ask for no parent
> > > clock?  
> > 
> > Well, we never seem to reference the HOSC this way, this was always
> > somewhat explicit. And yes, there is PLL-PERIPH as an input, but we
> > don't support this yet. So I went with 0 input clocks *for now*: the
> > driver can then ignore all clocks, so any clock referenced in the DT
> > later won't cause any harm. This will all be addressed by Samuel's RTC
> > clock patch, which will also touch the H6, IIRC. And it looks like we
> > will need to touch the binding anyway then, but can then just *extend*
> > this.  
> 
> You mentioned that series several times already and never provided an
> explanation for what it was supposed to be doing except fixing
> everything. What's the general plan for that series?
> 
> Maxime



From maxime at cerno.tech  Wed Aug 18 02:07:32 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 11:07:32 +0200
Subject: [PATCH v2 1/3] dt-bindings: watchdog: sunxi: Add compatible for
 R329
In-Reply-To: <20210805045716.46141-1-samuel@sholland.org>
References: <20210805045716.46141-1-samuel@sholland.org>
Message-ID: <20210818090732.wdickyw67oc4zqpt@gilmour>

Hi,

On Wed, Aug 04, 2021 at 11:57:14PM -0500, Samuel Holland wrote:
> On existing SoCs, the watchdog has a single clock input: HOSC (OSC24M)
> divided by 750.  However, starting with R329, LOSC (OSC32k) is added as
> an alternative clock source, with a bit to switch between them.
> 
> Since 24 MHz / 750 == 32 kHz, not 32.768 kHz, the hardware adjusts the
> cycle counts to keep the timeouts independent of the clock source. This
> keeps the programming interface backward-compatible.
> 
> R329 also adds two new registers, to allow software to immediately drive
> the SoC reset signal.
> 
> Signed-off-by: Samuel Holland <samuel at sholland.org>
> ---
> Changes v1 to v2:
>  - Switch from enum to const
>  - Add descriptions to "clocks" items
> 
>  .../watchdog/allwinner,sun4i-a10-wdt.yaml     | 32 ++++++++++++++++++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> index 9aa3c313c49f..8fa5b0d32381 100644
> --- a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> +++ b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> @@ -24,6 +24,7 @@ properties:
>                - allwinner,sun50i-a100-wdt
>                - allwinner,sun50i-h6-wdt
>                - allwinner,sun50i-h616-wdt
> +              - allwinner,sun50i-r329-wdt
>            - const: allwinner,sun6i-a31-wdt
>        - items:
>            - const: allwinner,suniv-f1c100s-wdt
> @@ -33,7 +34,18 @@ properties:
>      maxItems: 1
>  
>    clocks:
> -    maxItems: 1
> +    minItems: 1
> +    maxItems: 2
> +    items:
> +      - description: High-frequency oscillator input, divided internally
> +      - description: Low-frequency oscillator input, only found on some variants
> +
> +  clock-names:
> +    minItems: 1
> +    maxItems: 2
> +    items:
> +      - const: hosc
> +      - const: losc
>  
>    interrupts:
>      maxItems: 1
> @@ -44,6 +56,24 @@ required:
>    - clocks
>    - interrupts
>  
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +        enum:
> +          - allwinner,sun50i-r329-wdt
> +
> +then:
> +  properties:
> +    clocks:
> +      minItems: 2
> +
> +    clock-names:
> +      minItems: 2
> +
> +  required:
> +    - clock-names
> +

We should also make sure through an else clause that all the other SoCs
have a length of one for both clocks and clock-names

Also, it looks like you forgot the patch to enable the compatible in the
driver?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/f6c7ebdf/attachment.sig>

From maxime at cerno.tech  Wed Aug 18 02:07:59 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 11:07:59 +0200
Subject: [PATCH v2 2/3] dt-bindings: watchdog: sunxi: Add compatible for D1
In-Reply-To: <20210805045716.46141-2-samuel@sholland.org>
References: <20210805045716.46141-1-samuel@sholland.org>
 <20210805045716.46141-2-samuel@sholland.org>
Message-ID: <20210818090759.defewtmx3l3ku3rd@gilmour>

On Wed, Aug 04, 2021 at 11:57:15PM -0500, Samuel Holland wrote:
> D1 keeps the same register layout and clock sources as the R329, but it
> adds a key field which must be set to update the watchdog's "CFG" and
> "MODE" registers. Therefore it is not backward-compatible.
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Samuel Holland <samuel at sholland.org>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/510bf0c1/attachment.sig>

From maxime at cerno.tech  Wed Aug 18 02:08:11 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 11:08:11 +0200
Subject: [PATCH v2 3/3] watchdog: sunxi_wdt: Add support for D1
In-Reply-To: <20210805045716.46141-3-samuel@sholland.org>
References: <20210805045716.46141-1-samuel@sholland.org>
 <20210805045716.46141-3-samuel@sholland.org>
Message-ID: <20210818090811.fl7u4jtxh4ko7j3c@gilmour>

On Wed, Aug 04, 2021 at 11:57:16PM -0500, Samuel Holland wrote:
> D1 adds a key field to the "CFG" and "MODE" registers, that must be set
> to change the other bits. Add logic to set the key when updating those
> registers.
> 
> Reviewed-by: Guenter Roeck <linux at roeck-us.net>
> Signed-off-by: Samuel Holland <samuel at sholland.org>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/896620e6/attachment-0001.sig>

From maz at kernel.org  Wed Aug 18 02:10:40 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 10:10:40 +0100
Subject: [PATCH] KVM: arm64: Make hyp_panic() more robust when protected
 mode is enabled
In-Reply-To: <20210813130336.8139-1-will@kernel.org>
References: <20210813130336.8139-1-will@kernel.org>
Message-ID: <162927783509.2863.13074937375734887703.b4-ty@kernel.org>

On Fri, 13 Aug 2021 14:03:36 +0100, Will Deacon wrote:
> When protected mode is enabled, the host is unable to access most parts
> of the EL2 hypervisor image, including 'hyp_physvirt_offset' and the
> contents of the hypervisor's '.rodata.str' section. Unfortunately,
> nvhe_hyp_panic_handler() tries to read from both of these locations when
> handling a BUG() triggered at EL2; the former for converting the ELR to
> a physical address and the latter for displaying the name of the source
> file where the BUG() occurred.
> 
> [...]

Applied to kvm-arm64/mmu/el2-tracking, thanks!

[1/1] KVM: arm64: Make hyp_panic() more robust when protected mode is enabled
      commit: ccac96977243d7916053550f62e6489760ad0adc

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From icenowy at sipeed.com  Wed Aug 18 02:15:05 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Wed, 18 Aug 2021 17:15:05 +0800
Subject: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
In-Reply-To: <20210818090139.rllz4fvvq3pzdkls@gilmour>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-16-icenowy@sipeed.com>
 <20210818090139.rllz4fvvq3pzdkls@gilmour>
Message-ID: <74F51516-2470-4A49-972B-E19D8EDD9A3D@sipeed.com>+2C0AB55E581E37B6



? 2021?8?18? GMT+08:00 ??5:01:39, Maxime Ripard <maxime at cerno.tech> ??:
>On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
>> Allwinner R329 is a new SoC focused on smart audio devices.
>> 
>> Add a DTSI file for it.
>> 
>> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
>> ---
>>  .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
>>  1 file changed, 244 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
>> 
>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
>> new file mode 100644
>> index 000000000000..bfefa2b734b0
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
>> @@ -0,0 +1,244 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +// Copyright (c) 2021 Sipeed
>> +
>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
>> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
>> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
>> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
>> +
>> +/ {
>> +	interrupt-parent = <&gic>;
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +
>> +	cpus {
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		cpu0: cpu at 0 {
>> +			compatible = "arm,cortex-a53";
>> +			device_type = "cpu";
>> +			reg = <0>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu1: cpu at 1 {
>> +			compatible = "arm,cortex-a53";
>> +			device_type = "cpu";
>> +			reg = <1>;
>> +			enable-method = "psci";
>> +		};
>> +	};
>> +
>> +	osc24M: osc24M_clk {
>> +		#clock-cells = <0>;
>> +		compatible = "fixed-clock";
>> +		clock-frequency = <24000000>;
>> +		clock-output-names = "osc24M";
>> +	};
>> +
>> +	psci {
>> +		compatible = "arm,psci-0.2";
>> +		method = "smc";
>> +	};
>> +
>> +	timer {
>> +		compatible = "arm,armv8-timer";
>> +		arm,no-tick-in-suspend;
>> +		interrupts = <GIC_PPI 13
>> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
>> +			     <GIC_PPI 14
>> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
>> +			     <GIC_PPI 11
>> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
>> +			     <GIC_PPI 10
>> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
>> +	};
>> +
>> +	soc {
>> +		compatible = "simple-bus";
>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +		ranges;
>> +
>> +		pio: pinctrl at 2000400 {
>> +			compatible = "allwinner,sun50i-r329-pinctrl";
>> +			reg = <0x02000400 0x400>;
>> +			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
>> +				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
>> +			clock-names = "apb", "hosc", "losc";
>> +			gpio-controller;
>> +			#gpio-cells = <3>;
>> +			interrupt-controller;
>> +			#interrupt-cells = <3>;
>> +
>> +			uart0_pb_pins: uart0-pb-pins {
>> +				pins = "PB4", "PB5";
>> +				function = "uart0";
>> +			};
>> +
>> +			mmc0_pf_pins: mmc0-pf-pins {
>> +				pins = "PF0", "PF1", "PF2",
>> +				       "PF3", "PF4", "PF5";
>> +				function = "mmc0";
>> +			};
>> +
>> +			mmc1_clk_pg0: mmc1-clk-pg0 {
>> +				pins = "PG0";
>> +				function = "mmc1_clk";
>> +			};
>
>Argh, of course it was bound to happen :)
>
>Make sure your DT pass validation though, all your mmc1 node names will report errors.
>
>> +
>> +			mmc1_cmd_pg1: mmc1-clk-pg1 {
>
>s/clk/cmd/ ?
>
>> +				pins = "PG1";
>> +				function = "mmc1_cmd";
>> +			};
>> +
>> +			mmc1_d0_pg2: mmc1-clk-pg2 {
>
>s/clk/d0/
>
>> +				pins = "PG2";
>> +				function = "mmc1_d0";
>> +			};
>> +
>> +			mmc1_d1_pg3: mmc1-clk-pg3 {
>
>s/clk/d1/
>
>> +				pins = "PG3";
>> +				function = "mmc1_d1";
>> +			};
>> +
>> +			mmc1_d2_pg4: mmc1-clk-pg4 {
>
>s/clk/d2/
>
>> +				pins = "PG4";
>> +				function = "mmc1_d2";
>> +			};
>> +
>> +			mmc1_d3_pg5: mmc1-clk-pg5 {
>
>s/clk/d3/
>
>> +				pins = "PG5";
>> +				function = "mmc1_d3";
>> +			};
>> +		};
>> +
>> +		ccu: clock at 2001000 {
>> +			compatible = "allwinner,sun50i-r329-ccu";
>> +			reg = <0x02001000 0x1000>;
>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
>> +			clock-names = "hosc", "losc", "iosc";
>
>Do we have a clock tree for the RTC? Is it the same than the H616?

Nope, it's the same with H6 because of external LOSC crystal is
possible. (Although production M2A SoMs has it NC for cost control.)

What's the same between H616 and R329 is linear day storage of the timekeeping
part, not the clock part.

>
>Maxime

-- 
?? K-9 Mail ?????Android???


From nancy.lin at mediatek.com  Wed Aug 18 02:18:41 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:41 +0800
Subject: [PATCH v3 09/15] soc: mediatek: add cmdq support of mtk-mmsys config
 API for mt8195 vdosys1
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-10-nancy.lin@mediatek.com>

Add cmdq support for mtk-mmsys config API.
The mmsys config register settings need to take effect with the other
HW settings(like OVL_ADAPTOR...) at the same vblanking time.

If we use CPU to write the mmsys reg, we can't guarantee all the
settings can be written in the same vblanking time.
Cmdq is used for this purpose. We prepare all the related HW settings
in one cmdq packet. The first command in the packet is "wait stream done",
and then following with all the HW settings. After the cmdq packet is
flush to GCE HW. The GCE waits for the "stream done event" to coming
and then starts flushing all the HW settings. This can guarantee all
the settings flush in the same vblanking.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mmsys.c       | 28 +++++++++++++++++++++-----
 include/linux/soc/mediatek/mtk-mmsys.h |  6 +++++-
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index cd59a4157731..e2bcd701ceb0 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -77,6 +77,7 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
+	struct cmdq_client_reg cmdq_base;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -117,7 +118,7 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
-			  u32 id, u32 val)
+			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
 	const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
@@ -140,10 +141,20 @@ void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
 	mask = mmsys_config[i].mask;
 	reg_val = val << mmsys_config[i].shift;
 
-	u32 tmp = readl(mmsys->regs + offset);
-
-	tmp = (tmp & ~mask) | reg_val;
-	writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	if (cmdq_pkt && mmsys->cmdq_base.size) {
+		cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+				    mmsys->cmdq_base.offset + offset, reg_val,
+				    mask);
+	} else {
+#endif
+		u32 tmp = readl(mmsys->regs + offset);
+
+		tmp = (tmp & ~mask) | reg_val;
+		writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	}
+#endif
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
@@ -167,6 +178,13 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 	}
 
 	mmsys->data = of_device_get_match_data(&pdev->dev);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
+	if (ret)
+		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
+#endif
+
 	platform_set_drvdata(pdev, mmsys);
 
 	clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index ef2a6d9a834b..9705d242849a 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -6,6 +6,10 @@
 #ifndef __MTK_MMSYS_H
 #define __MTK_MMSYS_H
 
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox/mtk-cmdq-mailbox.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
 enum mtk_ddp_comp_id;
 struct device;
 
@@ -75,6 +79,6 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id next);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
-			  u32 id, u32 val);
+			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt);
 
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:35 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:35 +0800
Subject: [PATCH v3 03/15] dt-bindings: mediatek: add ethdr definition for
 mt8195
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-4-nancy.lin@mediatek.com>

Add vdosys1 ETHDR definition.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../display/mediatek/mediatek,ethdr.yaml      | 144 ++++++++++++++++++
 1 file changed, 144 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
new file mode 100644
index 000000000000..64d5349cdf8f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
@@ -0,0 +1,144 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek ethdr Device Tree Bindings
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+  - Nancy.Lin <nancy.lin at mediatek.com>
+
+description: |
+  ETHDR is designed for HDR video and graphics conversion in the external display path.
+  It handles multiple HDR input types and performs tone mapping, color space/color
+  format conversion, and then combine different layers, output the required HDR or
+  SDR signal to the subsequent display path. This engine is composed of two video
+  frontends, two graphic frontends, one video backend and a mixer.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-disp-ethdr
+  reg:
+    maxItems: 7
+  reg-names:
+    items:
+      - const: mixer
+      - const: vdo_fe0
+      - const: vdo_fe1
+      - const: gfx_fe0
+      - const: gfx_fe1
+      - const: vdo_be
+      - const: adl_ds
+  interrupts:
+    minItems: 1
+  iommus:
+    description: The compatible property is DMA function blocks.
+      Should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for
+      details.
+    minItems: 1
+    maxItems: 2
+  clocks:
+    items:
+      - description: mixer clock
+      - description: video frontend 0 clock
+      - description: video frontend 1 clock
+      - description: graphic frontend 0 clock
+      - description: graphic frontend 1 clock
+      - description: video backend clock
+      - description: autodownload and menuload clock
+      - description: video frontend 0 async clock
+      - description: video frontend 1 async clock
+      - description: graphic frontend 0 async clock
+      - description: graphic frontend 1 async clock
+      - description: video backend async clock
+      - description: ethdr top clock
+  clock-names:
+    items:
+      - const: mixer
+      - const: vdo_fe0
+      - const: vdo_fe1
+      - const: gfx_fe0
+      - const: gfx_fe1
+      - const: vdo_be
+      - const: adl_ds
+      - const: vdo_fe0_async
+      - const: vdo_fe1_async
+      - const: gfx_fe0_async
+      - const: gfx_fe1_async
+      - const: vdo_be_async
+      - const: ethdr_top
+  power-domains:
+    maxItems: 1
+  resets:
+    maxItems: 5
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: The register of display function block to be set by gce.
+      There are 4 arguments in this property, gce node, subsys id, offset and
+      register size. The subsys id is defined in the gce header of each chips
+      include/include/dt-bindings/gce/<chip>-gce.h, mapping to the register of
+      display function block.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+
+    disp_ethdr at 1c114000 {
+            compatible = "mediatek,mt8195-disp-ethdr";
+            reg = <0 0x1c114000 0 0x1000>,
+                  <0 0x1c115000 0 0x1000>,
+                  <0 0x1c117000 0 0x1000>,
+                  <0 0x1c119000 0 0x1000>,
+                  <0 0x1c11A000 0 0x1000>,
+                  <0 0x1c11B000 0 0x1000>,
+                  <0 0x1c11C000 0 0x1000>;
+            reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+                        "vdo_be", "adl_ds";
+            mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x4000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0x5000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0x7000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0x9000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0xA000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0xB000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0xC000 0x1000>;
+            clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_BE>,
+                     <&vdosys1 CLK_VDO1_26M_SLOW>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE0_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE1_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE0_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE1_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_BE_DL_ASYNC>,
+                     <&topckgen CLK_TOP_ETHDR_SEL>;
+            clock-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+                          "vdo_be", "adl_ds", "vdo_fe0_async", "vdo_fe1_async",
+                          "gfx_fe0_async", "gfx_fe1_async","vdo_be_async",
+                          "ethdr_top";
+            power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+            iommus = <&iommu_vpp M4U_PORT_L3_HDR_DS>,
+                     <&iommu_vpp M4U_PORT_L3_HDR_ADL>;
+            interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>; /* disp mixer */
+            resets = <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC>;
+    };
+
+...
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:34 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:34 +0800
Subject: [PATCH v3 02/15] dt-bindings: mediatek: add vdosys1 MERGE definition
 for mt8195
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-3-nancy.lin@mediatek.com>

Add vdosys1 MERGE definition.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../devicetree/bindings/display/mediatek/mediatek,merge.yaml    | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 1a27b037086b..ba1e0c837988 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -23,6 +23,8 @@ properties:
           - const: mediatek,mt8173-disp-merge
       - items:
           - const: mediatek,mt8195-disp-merge
+      - items:
+          - const: mediatek,mt8195-vdo1-merge
 
   reg:
     maxItems: 1
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:36 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:36 +0800
Subject: [PATCH v3 04/15] dt-bindings: mediatek: Add #reset-cells to mmsys
 system controller
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-5-nancy.lin@mediatek.com>

The mmsys system controller exposes a set of memory client resets and
needs to specify the #reset-cells property in order to advertise the
number of cells needed to describe each of the resets

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml       | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 68cb330d7595..5678d55b032a 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -50,6 +50,9 @@ properties:
   "#clock-cells":
     const: 1
 
+  "#reset-cells":
+    const: 1
+
 required:
   - compatible
   - reg
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:42 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:42 +0800
Subject: [PATCH v3 10/15] soc: mediatek: mmsys: Add reset controller support
 for MT8195 vdosys1
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-11-nancy.lin@mediatek.com>

Among other features the mmsys driver should implement a reset
controller to be able to reset different bits from their space.

For MT8195 vdosys1, many async modules need to reset after
the display pipe stops and restart.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h |  1 +
 drivers/soc/mediatek/mtk-mmsys.c    | 76 +++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h    |  1 +
 3 files changed, 78 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index 0b079cba443f..0b08ac0cf2bf 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -123,6 +123,7 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER		(0 << 0)
 
+#define MT8195_VDO1_SW0_RST_B           0x1d0
 #define MT8195_VDO1_MERGE0_ASYNC_CFG_WD	0xe30
 #define MT8195_VDO1_MERGE1_ASYNC_CFG_WD	0xe40
 #define MT8195_VDO1_MERGE2_ASYNC_CFG_WD	0xe50
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index e2bcd701ceb0..5e6c116e589a 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -4,10 +4,12 @@
  * Author: James Liao <jamesjj.liao at mediatek.com>
  */
 
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/reset-controller.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 
 #include "mtk-mmsys.h"
@@ -16,6 +18,8 @@
 #include "mt8365-mmsys.h"
 #include "mt8195-mmsys.h"
 
+#define MMSYS_SW_RESET_PER_REG 32
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.clk_driver = "clk-mt2701-mm",
 	.routes = mmsys_default_routing_table,
@@ -72,12 +76,15 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
 	.config = mmsys_mt8195_config_table,
 	.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
+	.sw_reset_start = MT8195_VDO1_SW0_RST_B,
 };
 
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
 	struct cmdq_client_reg cmdq_base;
+	spinlock_t lock; /* protects mmsys_sw_rst_b reg */
+	struct reset_controller_dev rcdev;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -158,6 +165,63 @@ void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
+static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
+				  bool assert)
+{
+	struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
+	unsigned long flags;
+	u32 reg;
+	int i;
+	u32 offset;
+
+	offset = (id / MMSYS_SW_RESET_PER_REG) * sizeof(u32);
+	id = id % MMSYS_SW_RESET_PER_REG;
+
+	spin_lock_irqsave(&mmsys->lock, flags);
+
+	reg = readl_relaxed(mmsys->regs + mmsys->data->sw_reset_start + offset);
+
+	if (assert)
+		reg &= ~BIT(id);
+	else
+		reg |= BIT(id);
+
+	writel_relaxed(reg, mmsys->regs + mmsys->data->sw_reset_start + offset);
+
+	spin_unlock_irqrestore(&mmsys->lock, flags);
+
+	return 0;
+}
+
+static int mtk_mmsys_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return mtk_mmsys_reset_update(rcdev, id, true);
+}
+
+static int mtk_mmsys_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return mtk_mmsys_reset_update(rcdev, id, false);
+}
+
+static int mtk_mmsys_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	int ret;
+
+	ret = mtk_mmsys_reset_assert(rcdev, id);
+	if (ret)
+		return ret;
+
+	usleep_range(1000, 1100);
+
+	return mtk_mmsys_reset_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops mtk_mmsys_reset_ops = {
+	.assert = mtk_mmsys_reset_assert,
+	.deassert = mtk_mmsys_reset_deassert,
+	.reset = mtk_mmsys_reset,
+};
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -185,6 +249,18 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
 #endif
 
+	spin_lock_init(&mmsys->lock);
+
+	mmsys->rcdev.owner = THIS_MODULE;
+	mmsys->rcdev.nr_resets = 64;
+	mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
+	mmsys->rcdev.of_node = pdev->dev.of_node;
+	ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Couldn't register mmsys reset controller: %d\n", ret);
+		return ret;
+	}
+
 	platform_set_drvdata(pdev, mmsys);
 
 	clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver,
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 825857d8d7f4..d84f5cb78f8c 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -100,6 +100,7 @@ struct mtk_mmsys_driver_data {
 	const unsigned int num_routes;
 	const struct mtk_mmsys_config *config;
 	const unsigned int num_configs;
+	u32 sw_reset_start;
 };
 
 /*
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:33 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:33 +0800
Subject: [PATCH v3 01/15] dt-bindings: mediatek: add vdosys1 RDMA definition
 for mt8195
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-2-nancy.lin@mediatek.com>

Add vdosys1 RDMA definition.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../display/mediatek/mediatek,mdp-rdma.yaml   | 77 +++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
new file mode 100644
index 000000000000..3610093848e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mdp-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display MDP RDMA
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display MDP RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-vdo1-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    vdo1_rdma0: vdo1_rdma at 1c104000 {
+        compatible = "mediatek,mt8195-vdo1-rdma";
+        reg = <0 0x1c104000 0 0x1000>;
+        interrupts = <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x4000 0x1000>;
+    };
+
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:37 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:37 +0800
Subject: [PATCH v3 05/15] dt-bindings: reset: mt8195: add vdosys1 reset
 control bit
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-6-nancy.lin@mediatek.com>

Add vdosys1 reset control bit for MT8195 platform.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 include/dt-bindings/reset/mt8195-resets.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/dt-bindings/reset/mt8195-resets.h b/include/dt-bindings/reset/mt8195-resets.h
index a26bccc8b957..eaaa882c09bd 100644
--- a/include/dt-bindings/reset/mt8195-resets.h
+++ b/include/dt-bindings/reset/mt8195-resets.h
@@ -26,4 +26,16 @@
 
 #define MT8195_TOPRGU_SW_RST_NUM               16
 
+/* VDOSYS1 */
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC 25
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC 26
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC 27
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC 28
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC 29
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC 51
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC 52
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC 53
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC 54
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC 55
+
 #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:40 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:40 +0800
Subject: [PATCH v3 08/15] soc: mediatek: add mtk-mmsys config API for mt8195
 vdosys1
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-9-nancy.lin@mediatek.com>

Add mmsys config API. The config API is used for config mmsys reg.
Some mmsys regs need to be setting according to the HW engine binding
to the mmsys simultaneously.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 62 ++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 33 ++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       | 10 +++++
 include/linux/soc/mediatek/mtk-mmsys.h | 16 +++++++
 4 files changed, 121 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index 3c2b1d43dcc4..0b079cba443f 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -123,6 +123,21 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER		(0 << 0)
 
+#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD	0xe30
+#define MT8195_VDO1_MERGE1_ASYNC_CFG_WD	0xe40
+#define MT8195_VDO1_MERGE2_ASYNC_CFG_WD	0xe50
+#define MT8195_VDO1_MERGE3_ASYNC_CFG_WD	0xe60
+#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD	0xe70
+#define MT8195_VDO1_HDR_TOP_CFG		0xd00
+#define MT8195_VDO1_MIXER_IN1_ALPHA	0xd30
+#define MT8195_VDO1_MIXER_IN2_ALPHA	0xd34
+#define MT8195_VDO1_MIXER_IN3_ALPHA	0xd38
+#define MT8195_VDO1_MIXER_IN4_ALPHA	0xd3c
+#define MT8195_VDO1_MIXER_IN1_PAD	0xd40
+#define MT8195_VDO1_MIXER_IN2_PAD	0xd44
+#define MT8195_VDO1_MIXER_IN3_PAD	0xd48
+#define MT8195_VDO1_MIXER_IN4_PAD	0xd4c
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	{
 		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -247,4 +262,51 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	}
 };
 
+/*
+ * mtk_mmsys_config table is used for config mmsys reg in runtime.
+ * MMSYS_CONFIG_MERGE_ASYNC_WIDTH: config merge async width
+ * MMSYS_CONFIG_MERGE_ASYNC_HEIGHT: config merge async height
+ * MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH: config hdr_be async width
+ * MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT: config hdr_be async height
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_ODD: config mixer odd channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN: config mixer even channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_CH_SWAP: config mixer input RGB channel swap
+ * MMSYS_CONFIG_HDR_ALPHA_SEL: config alpha source
+ * MMSYS_CONFIG_MIXER_IN_MODE: config mixer pad mode(bypass/even extend mode)
+ * MMSYS_CONFIG_MIXER_IN_BIWIDTH: config mixer pad width. formula: width / 2 - 1
+ */
+static const struct mtk_mmsys_config mmsys_mt8195_config_table[] = {
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(4, 4), 4},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 1, MT8195_VDO1_HDR_TOP_CFG, GENMASK(20, 20), 20},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 2, MT8195_VDO1_HDR_TOP_CFG, GENMASK(21, 21), 21},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 3, MT8195_VDO1_HDR_TOP_CFG, GENMASK(22, 22), 22},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 4, MT8195_VDO1_HDR_TOP_CFG, GENMASK(23, 23), 23},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 2, MT8195_VDO1_MIXER_IN2_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 3, MT8195_VDO1_MIXER_IN3_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 2, MT8195_VDO1_MIXER_IN2_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 3, MT8195_VDO1_MIXER_IN3_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(31, 16), 16},
+};
+
 #endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 7365731c9fd7..cd59a4157731 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -70,6 +70,8 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 	.clk_driver = "clk-mt8195-vdo1",
 	.routes = mmsys_mt8195_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+	.config = mmsys_mt8195_config_table,
+	.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
 };
 
 struct mtk_mmsys {
@@ -114,6 +116,37 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
+void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
+			  u32 id, u32 val)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
+	u32 reg_val;
+	u32 mask;
+	u32 offset;
+	int i;
+
+	if (!mmsys->data->num_configs)
+		return;
+
+	for (i = 0; i < mmsys->data->num_configs; i++)
+		if (config == mmsys_config[i].config && id == mmsys_config[i].id)
+			break;
+
+	if (i == mmsys->data->num_configs)
+		return;
+
+	offset = mmsys_config[i].addr;
+	mask = mmsys_config[i].mask;
+	reg_val = val << mmsys_config[i].shift;
+
+	u32 tmp = readl(mmsys->regs + offset);
+
+	tmp = (tmp & ~mask) | reg_val;
+	writel(tmp, mmsys->regs + offset);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 5f3e2bf0c40b..825857d8d7f4 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -86,10 +86,20 @@ struct mtk_mmsys_routes {
 	u32 val;
 };
 
+struct mtk_mmsys_config {
+	enum mtk_mmsys_config_type config;
+	u32 id;
+	u32 addr;
+	u32 mask;
+	u32 shift;
+};
+
 struct mtk_mmsys_driver_data {
 	const char *clk_driver;
 	const struct mtk_mmsys_routes *routes;
 	const unsigned int num_routes;
+	const struct mtk_mmsys_config *config;
+	const unsigned int num_configs;
 };
 
 /*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 619392221a52..ef2a6d9a834b 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -53,6 +53,19 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_ID_MAX,
 };
 
+enum mtk_mmsys_config_type {
+	MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
+	MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
+	MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH,
+	MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT,
+	MMSYS_CONFIG_HDR_ALPHA_SEL,
+	MMSYS_CONFIG_MIXER_IN_ALPHA_ODD,
+	MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN,
+	MMSYS_CONFIG_MIXER_IN_CH_SWAP,
+	MMSYS_CONFIG_MIXER_IN_MODE,
+	MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+};
+
 void mtk_mmsys_ddp_connect(struct device *dev,
 			   enum mtk_ddp_comp_id cur,
 			   enum mtk_ddp_comp_id next);
@@ -61,4 +74,7 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id cur,
 			      enum mtk_ddp_comp_id next);
 
+void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
+			  u32 id, u32 val);
+
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:38 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:38 +0800
Subject: [PATCH v3 06/15] arm64: dts: mt8195: add display node for vdosys1
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-7-nancy.lin@mediatek.com>

Add display node for vdosys1.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 217 +++++++++++++++++++++++
 1 file changed, 217 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index aa2a7849b822..b2e377515a52 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -10,6 +10,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/power/mt8195-power.h>
+#include <dt-bindings/reset/mt8195-resets.h>
 
 / {
 	compatible = "mediatek,mt8195";
@@ -20,6 +21,21 @@
 	aliases {
 		gce0 = &gce0;
 		gce1 = &gce1;
+		mutex0 = &mutex;
+		mutex1 = &mutex1;
+		merge1 = &merge1;
+		merge2 = &merge2;
+		merge3 = &merge3;
+		merge4 = &merge4;
+		merge5 = &merge5;
+		vdo1_rdma0 = &vdo1_rdma0;
+		vdo1_rdma1 = &vdo1_rdma1;
+		vdo1_rdma2 = &vdo1_rdma2;
+		vdo1_rdma3 = &vdo1_rdma3;
+		vdo1_rdma4 = &vdo1_rdma4;
+		vdo1_rdma5 = &vdo1_rdma5;
+		vdo1_rdma6 = &vdo1_rdma6;
+		vdo1_rdma7 = &vdo1_rdma7;
 	};
 
 	clocks {
@@ -1275,7 +1291,208 @@
 		vdosys1: syscon at 1c100000 {
 			compatible = "mediatek,mt8195-vdosys1", "syscon";
 			reg = <0 0x1c100000 0 0x1000>;
+			mboxes = <&gce1 1 CMDQ_THR_PRIO_4>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x0000 0x1000>;
 			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		mutex1: disp_mutex0 at 1c101000 {
+			compatible = "mediatek,mt8195-disp-mutex";
+			reg = <0 0x1c101000 0 0x1000>;
+			reg-names = "vdo1_mutex";
+			interrupts = <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>;
+			clock-names = "vdo1_mutex";
+			mediatek,gce-events = <CMDQ_EVENT_VDO1_STREAM_DONE_ENG_0>;
+		};
+
+		vdo1_rdma0: vdo1_rdma at 1c104000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c104000 0 0x1000>;
+			interrupts = <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x4000 0x1000>;
+		};
+
+		vdo1_rdma1: vdo1_rdma at 1c105000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c105000 0 0x1000>;
+			interrupts = <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA1>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x5000 0x1000>;
+		};
+
+		vdo1_rdma2: vdo1_rdma at 1c106000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c106000 0 0x1000>;
+			interrupts = <GIC_SPI 497 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA2>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x6000 0x1000>;
+		};
+
+		vdo1_rdma3: vdo1_rdma at 1c107000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c107000 0 0x1000>;
+			interrupts = <GIC_SPI 498 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA3>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x7000 0x1000>;
+		};
+
+		vdo1_rdma4: vdo1_rdma at 1c108000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c108000 0 0x1000>;
+			interrupts = <GIC_SPI 499 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA4>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA4>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x8000 0x1000>;
+		};
+
+		vdo1_rdma5: vdo1_rdma at 1c109000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c109000 0 0x1000>;
+			interrupts = <GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA5>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA5>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x9000 0x1000>;
+		};
+
+		vdo1_rdma6: vdo1_rdma at 1c10a000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c10a000 0 0x1000>;
+			interrupts = <GIC_SPI 501 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA6>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA6>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xa000 0x1000>;
+		};
+
+		vdo1_rdma7: vdo1_rdma at 1c10b000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c10b000 0 0x1000>;
+			interrupts = <GIC_SPI 502 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA7>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA7>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xb000 0x1000>;
+		};
+
+		merge1: disp_vpp_merge at 1c10c000 {
+			compatible = "mediatek,mt8195-vdo1-merge";
+			reg = <0 0x1c10c000 0 0x1000>;
+			interrupts = <GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE0>,
+				 <&vdosys1 CLK_VDO1_MERGE0_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xc000 0x1000>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC>;
+		};
+
+		merge2: disp_vpp_merge at 1c10d000 {
+			compatible = "mediatek,mt8195-vdo1-merge";
+			reg = <0 0x1c10d000 0 0x1000>;
+			interrupts = <GIC_SPI 504 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE1>,
+				 <&vdosys1 CLK_VDO1_MERGE1_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xd000 0x1000>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC>;
+		};
+
+		merge3: disp_vpp_merge at 1c10e000 {
+			compatible = "mediatek,mt8195-vdo1-merge";
+			reg = <0 0x1c10e000 0 0x1000>;
+			interrupts = <GIC_SPI 505 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE2>,
+				 <&vdosys1 CLK_VDO1_MERGE2_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xe000 0x1000>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC>;
+		};
+
+		merge4: disp_vpp_merge at 1c10f000 {
+			compatible = "mediatek,mt8195-vdo1-merge";
+			reg = <0 0x1c10f000 0 0x1000>;
+			interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE3>,
+				 <&vdosys1 CLK_VDO1_MERGE3_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xf000 0x1000>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC>;
+		};
+
+		merge5: disp_vpp_merge5 at 1c110000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c110000 0 0x1000>;
+			interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+				 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+			mediatek,merge-fifo-en = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+		};
+
+		disp_ethdr at 1c114000 {
+			compatible = "mediatek,mt8195-disp-ethdr";
+			reg = <0 0x1c114000 0 0x1000>,
+			      <0 0x1c115000 0 0x1000>,
+			      <0 0x1c117000 0 0x1000>,
+			      <0 0x1c119000 0 0x1000>,
+			      <0 0x1c11A000 0 0x1000>,
+			      <0 0x1c11B000 0 0x1000>,
+			      <0 0x1c11C000 0 0x1000>;
+			reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+				    "vdo_be", "adl_ds";
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x4000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0x5000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0x7000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0x9000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0xA000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0xB000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0xC000 0x1000>;
+			clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_BE>,
+				 <&vdosys1 CLK_VDO1_26M_SLOW>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE0_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE1_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE0_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE1_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_BE_DL_ASYNC>,
+				 <&topckgen CLK_TOP_ETHDR_SEL>;
+			clock-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+				      "vdo_be", "adl_ds", "vdo_fe0_async", "vdo_fe1_async",
+				      "gfx_fe0_async", "gfx_fe1_async","vdo_be_async",
+				      "ethdr_top";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_HDR_DS>,
+				 <&iommu_vpp M4U_PORT_L3_HDR_ADL>;
+			interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>; /* disp mixer */
+			resets = <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC>;
 		};
 	};
 
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:45 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:45 +0800
Subject: [PATCH v3 13/15] drm/mediatek: add ovl_adaptor support for MT8195
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-14-nancy.lin@mediatek.com>

Add ovl_adaptor driver for MT8195.
Ovl_adaptor is an encapsulated module and designed for simplified
DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and
an ETHDR. Two RDMAs merge into one layer, so this module support 4
layers.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile             |   3 +-
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 528 ++++++++++++++++++
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.h   |  19 +
 3 files changed, 549 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 38ec2354a894..f04ac86c9593 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \
 		  mtk_drm_plane.o \
 		  mtk_dsi.o \
 		  mtk_dpi.o \
-		  mtk_mdp_rdma.o
+		  mtk_mdp_rdma.o \
+		  mtk_disp_ovl_adaptor.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
new file mode 100644
index 000000000000..8222ec5ff799
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_disp_drv.h"
+#include "mtk_disp_ovl_adaptor.h"
+
+#define DISP_MERGE_ENABLE	0x0
+	#define MERGE_ENABLE BIT(0)
+#define DISP_MERGE_CFG_0	0x10
+#define DISP_MERGE_CFG_1	0x14
+#define DISP_MERGE_CFG_4	0x20
+#define DISP_MERGE_CFG_5	0x24
+#define DISP_MERGE_CFG_10	0x38
+	#define CFG_10_NO_SWAP 0
+#define DISP_MERGE_CFG_12	0x40
+	#define CFG12_10_10_1PI_2PO_BUF_MODE 6
+	#define CFG12_11_10_1PI_2PO_MERGE 18
+#define DISP_MERGE_CFG_24	0x70
+#define DISP_MERGE_CFG_25	0x74
+#define DISP_MERGE_CFG_26	0x78
+#define DISP_MERGE_CFG_27	0x7c
+#define DISP_MERGE_MUTE_0	0xf00
+
+#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
+#define MTK_OVL_ADAPTOR_LAYER_NUM 4
+
+enum mtk_ovl_adaptor_comp_type {
+	OVL_ADAPTOR_TYPE_RDMA = 0,
+	OVL_ADAPTOR_TYPE_MERGE,
+	OVL_ADAPTOR_TYPE_NUM,
+};
+
+enum mtk_ovl_adaptor_comp_id {
+	OVL_ADAPTOR_MDP_RDMA0,
+	OVL_ADAPTOR_MDP_RDMA1,
+	OVL_ADAPTOR_MDP_RDMA2,
+	OVL_ADAPTOR_MDP_RDMA3,
+	OVL_ADAPTOR_MDP_RDMA4,
+	OVL_ADAPTOR_MDP_RDMA5,
+	OVL_ADAPTOR_MDP_RDMA6,
+	OVL_ADAPTOR_MDP_RDMA7,
+	OVL_ADAPTOR_MERGE0,
+	OVL_ADAPTOR_MERGE1,
+	OVL_ADAPTOR_MERGE2,
+	OVL_ADAPTOR_MERGE3,
+	OVL_ADAPTOR_ID_MAX
+};
+
+struct ovl_adaptor_comp_match {
+	enum mtk_ovl_adaptor_comp_type type;
+	int alias_id;
+};
+
+struct ovl_adaptor_merge_config {
+	unsigned int fmt;
+	unsigned int merge_mode;
+	unsigned int in_w[2];
+	unsigned int out_w[2];
+	unsigned int in_h;
+};
+
+struct mtk_ovl_adaptor_comp {
+	struct device *dev;
+	struct clk *clks[2];
+	struct cmdq_client_reg cmdq_base;
+	void __iomem *regs;
+};
+
+struct mtk_disp_ovl_adaptor {
+	struct mtk_ovl_adaptor_comp ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
+	struct device *mmsys_dev;
+};
+
+static const char * const ovl_adaptor_comp_str[] = {
+	"OVL_ADAPTOR_MDP_RDMA0",
+	"OVL_ADAPTOR_MDP_RDMA1",
+	"OVL_ADAPTOR_MDP_RDMA2",
+	"OVL_ADAPTOR_MDP_RDMA3",
+	"OVL_ADAPTOR_MDP_RDMA4",
+	"OVL_ADAPTOR_MDP_RDMA5",
+	"OVL_ADAPTOR_MDP_RDMA6",
+	"OVL_ADAPTOR_MDP_RDMA7",
+	"OVL_ADAPTOR_MERGE0",
+	"OVL_ADAPTOR_MERGE1",
+	"OVL_ADAPTOR_MERGE2",
+	"OVL_ADAPTOR_MERGE3",
+	"OVL_ADAPTOR_ID_MAX"
+};
+
+static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
+	[OVL_ADAPTOR_TYPE_RDMA] = "vdo1_rdma",
+	[OVL_ADAPTOR_TYPE_MERGE] = "merge",
+};
+
+static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
+	[OVL_ADAPTOR_MDP_RDMA0] =	{ OVL_ADAPTOR_TYPE_RDMA, 0 },
+	[OVL_ADAPTOR_MDP_RDMA1] =	{ OVL_ADAPTOR_TYPE_RDMA, 1 },
+	[OVL_ADAPTOR_MDP_RDMA2] =	{ OVL_ADAPTOR_TYPE_RDMA, 2 },
+	[OVL_ADAPTOR_MDP_RDMA3] =	{ OVL_ADAPTOR_TYPE_RDMA, 3 },
+	[OVL_ADAPTOR_MDP_RDMA4] =	{ OVL_ADAPTOR_TYPE_RDMA, 4 },
+	[OVL_ADAPTOR_MDP_RDMA5] =	{ OVL_ADAPTOR_TYPE_RDMA, 5 },
+	[OVL_ADAPTOR_MDP_RDMA6] =	{ OVL_ADAPTOR_TYPE_RDMA, 6 },
+	[OVL_ADAPTOR_MDP_RDMA7] =	{ OVL_ADAPTOR_TYPE_RDMA, 7 },
+	[OVL_ADAPTOR_MERGE0] =	{ OVL_ADAPTOR_TYPE_MERGE, 1 },
+	[OVL_ADAPTOR_MERGE1] =	{ OVL_ADAPTOR_TYPE_MERGE, 2 },
+	[OVL_ADAPTOR_MERGE2] =	{ OVL_ADAPTOR_TYPE_MERGE, 3 },
+	[OVL_ADAPTOR_MERGE3] =	{ OVL_ADAPTOR_TYPE_MERGE, 4 },
+};
+
+static void mtk_ovl_adaptor_merge_config(struct mtk_ovl_adaptor_comp *comp,
+					 struct ovl_adaptor_merge_config *merge_cfg,
+					 struct cmdq_pkt *cmdq_pkt)
+{
+	switch (merge_cfg->merge_mode) {
+	case 6:
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_0);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->out_w[0]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_4);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_24);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_25);
+		break;
+	case 18:
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_0);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[1]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_1);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->out_w[0]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_4);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_24);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[1]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_25);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_26);
+		mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[1]),
+			      &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_27);
+		break;
+	default:
+		break;
+	}
+
+	mtk_ddp_write(cmdq_pkt, merge_cfg->merge_mode, &comp->cmdq_base,
+		      comp->regs, DISP_MERGE_CFG_12);
+	mtk_ddp_write(cmdq_pkt, CFG_10_NO_SWAP, &comp->cmdq_base,
+		      comp->regs, DISP_MERGE_CFG_10);
+	mtk_ddp_write_mask(cmdq_pkt, 1, &comp->cmdq_base, comp->regs,
+			   DISP_MERGE_ENABLE, MERGE_ENABLE);
+}
+
+void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
+				  struct mtk_plane_state *state,
+				  struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+	struct mtk_plane_pending_state *pending = &state->pending;
+	struct ovl_adaptor_merge_config merge_cfg = {0};
+	struct mtk_mdp_rdma_cfg rdma_config = {0};
+	struct mtk_ovl_adaptor_comp *rdma_l;
+	struct mtk_ovl_adaptor_comp *rdma_r;
+	struct mtk_ovl_adaptor_comp *merge;
+	const struct drm_format_info *fmt_info = drm_format_info(pending->format);
+	bool use_dual_pipe = false;
+
+	dev_dbg(dev, "%s+ idx:%d, enable:%d, fmt:0x%x\n", __func__, idx,
+		pending->enable, pending->format);
+	dev_dbg(dev, "addr 0x%lx, fb w:%d, {%d,%d,%d,%d}\n",
+		pending->addr, (pending->pitch / fmt_info->cpp[0]),
+		pending->x, pending->y, pending->width, pending->height);
+
+	rdma_l = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx];
+	rdma_r = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx + 1];
+	merge = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
+
+	if (!pending->enable) {
+		mtk_ddp_write_mask(cmdq_pkt, 0x0, &merge->cmdq_base, merge->regs,
+				   DISP_MERGE_ENABLE, MERGE_ENABLE);
+		mtk_mdp_rdma_stop(rdma_l->regs, cmdq_pkt, &rdma_l->cmdq_base);
+		mtk_mdp_rdma_stop(rdma_r->regs, cmdq_pkt, &rdma_r->cmdq_base);
+		return;
+	}
+
+	if (pending->width > MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH)
+		use_dual_pipe = true;
+
+	merge_cfg.out_w[0] = pending->width;
+	merge_cfg.in_h = pending->height;
+	merge_cfg.fmt = pending->format;
+	if (use_dual_pipe) {
+		merge_cfg.merge_mode = CFG12_11_10_1PI_2PO_MERGE;
+		merge_cfg.in_w[0] = (pending->width / 2) + ((pending->width / 2) % 2);
+		merge_cfg.in_w[1] = (pending->width / 2) - ((pending->width / 2) % 2);
+	} else {
+		merge_cfg.merge_mode = CFG12_10_10_1PI_2PO_BUF_MODE;
+		merge_cfg.in_w[0] = pending->width;
+	}
+	mtk_ovl_adaptor_merge_config(merge, &merge_cfg, cmdq_pkt);
+
+	mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev, MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
+			     idx, pending->width / 2, cmdq_pkt);
+	mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev, MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
+			     idx, pending->height, cmdq_pkt);
+
+	rdma_config.source_width = pending->pitch / fmt_info->cpp[0];
+	rdma_config.csc_enable = fmt_info->is_yuv ? true : false;
+	rdma_config.profile = RDMA_CSC_FULL709_TO_RGB;
+	rdma_config.width = merge_cfg.in_w[0];
+	rdma_config.height = pending->height;
+	rdma_config.addr0 = pending->addr;
+	rdma_config.pitch = pending->pitch;
+	rdma_config.fmt = pending->format;
+	mtk_mdp_rdma_config(rdma_l->regs, &rdma_config, cmdq_pkt, &rdma_l->cmdq_base);
+
+	rdma_config.x_left = merge_cfg.in_w[0];
+	rdma_config.width = merge_cfg.in_w[1];
+	mtk_mdp_rdma_config(rdma_r->regs, &rdma_config, cmdq_pkt, &rdma_r->cmdq_base);
+
+	mtk_ddp_write_mask(cmdq_pkt, 0x1, &merge->cmdq_base, merge->regs,
+			   DISP_MERGE_ENABLE, MERGE_ENABLE);
+	mtk_ddp_write_mask(cmdq_pkt, 0x0, &merge->cmdq_base, merge->regs,
+			   DISP_MERGE_MUTE_0, 0x1);
+
+	mtk_mdp_rdma_start(rdma_l->regs, cmdq_pkt, &rdma_l->cmdq_base);
+	if (use_dual_pipe)
+		mtk_mdp_rdma_start(rdma_r->regs, cmdq_pkt, &rdma_r->cmdq_base);
+	else
+		mtk_mdp_rdma_stop(rdma_r->regs, cmdq_pkt, &rdma_r->cmdq_base);
+}
+
+void mtk_ovl_adaptor_stop(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+	struct mtk_ovl_adaptor_comp *rdma_l;
+	struct mtk_ovl_adaptor_comp *rdma_r;
+	struct mtk_ovl_adaptor_comp *merge;
+	unsigned int reg;
+	u32 i;
+
+	for (i = 0; i < MTK_OVL_ADAPTOR_LAYER_NUM; i++) {
+		rdma_l = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * i];
+		rdma_r = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * i + 1];
+		merge = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + i];
+
+		mtk_mdp_rdma_stop(rdma_l->regs, NULL, &rdma_l->cmdq_base);
+		mtk_mdp_rdma_stop(rdma_r->regs, NULL, &rdma_r->cmdq_base);
+
+		reg = readl(merge->regs + DISP_MERGE_ENABLE);
+		reg = reg & ~MERGE_ENABLE;
+		writel_relaxed(reg, merge->regs + DISP_MERGE_ENABLE);
+
+		device_reset_optional(merge->dev);
+	}
+}
+
+int mtk_ovl_adaptor_clk_enable(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+	struct mtk_ovl_adaptor_comp *comp;
+	int ret;
+	int i;
+	int j;
+
+	for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_ID_MAX; i++) {
+		comp = &ovl_adaptor->ovl_adaptor_comp[i];
+		if (!comp->dev)
+			continue;
+
+		/* Need to power on for private rdma devices */
+		if (i < OVL_ADAPTOR_MERGE0) {
+			ret = pm_runtime_get_sync(comp->dev);
+			if (ret < 0)
+				dev_err(dev,
+					"Failed to power on, err %d-%s\n",
+					ret, ovl_adaptor_comp_str[i]);
+		}
+
+		for (j = 0; j < ARRAY_SIZE(comp->clks); j++) {
+			if (IS_ERR(comp->clks[j]))
+				break;
+
+			ret = clk_prepare_enable(comp->clks[j]);
+			if (ret)
+				dev_err(dev,
+					"Failed to enable clock %d, err %d-%s\n",
+					i, ret, ovl_adaptor_comp_str[i]);
+		}
+	}
+
+	return ret;
+}
+
+void mtk_ovl_adaptor_clk_disable(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+	struct mtk_ovl_adaptor_comp *comp;
+	int ret;
+	int i;
+	int j;
+
+	for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_ID_MAX; i++) {
+		comp = &ovl_adaptor->ovl_adaptor_comp[i];
+		if (!comp->dev)
+			continue;
+
+		for (j = 0; i < ARRAY_SIZE(comp->clks); j++) {
+			if (IS_ERR(comp->clks[j]))
+				break;
+			clk_disable_unprepare(comp->clks[j]);
+		}
+
+		/* Need to power off for private rdma devices */
+		if (i < OVL_ADAPTOR_MERGE0) {
+			ret = pm_runtime_put(comp->dev);
+			if (ret < 0)
+				dev_err(dev,
+					"Failed to power off, err-%s\n",
+					ret, ovl_adaptor_comp_str[i]);
+		}
+	}
+}
+
+static int ovl_adaptor_comp_get_id(struct device *dev, struct device_node *node,
+				   enum mtk_ovl_adaptor_comp_type type)
+{
+	int alias_id = of_alias_get_id(node, private_comp_stem[type]);
+	int ret;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
+		if (comp_matches[i].type == type &&
+		    comp_matches[i].alias_id == alias_id)
+			return i;
+
+	dev_err(dev, "Failed to get id. type: %d, alias: %d\n", type, alias_id);
+	return -EINVAL;
+}
+
+static int private_comp_init(struct device *dev, struct device_node *node,
+			     struct mtk_ovl_adaptor_comp *comp,
+			     enum mtk_ovl_adaptor_comp_id id)
+{
+	struct platform_device *comp_pdev;
+	int ret;
+	int i;
+
+	if (id < 0 || id >= OVL_ADAPTOR_ID_MAX) {
+		dev_err(dev, "Invalid component id %d\n", id);
+		return -EINVAL;
+	}
+
+	comp_pdev = of_find_device_by_node(node);
+	if (!comp_pdev) {
+		dev_warn(dev, "can't find platform device of node:%s\n",
+			 node->name);
+		return -ENODEV;
+	}
+	comp->dev = &comp_pdev->dev;
+	comp->regs = of_iomap(node, 0);
+
+	for (i = 0; i < ARRAY_SIZE(comp->clks); i++) {
+		comp->clks[i] = of_clk_get(node, i);
+		if (IS_ERR(comp->clks[i]))
+			break;
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(comp->dev, &comp->cmdq_base, 0);
+	if (ret)
+		dev_info(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+	if (id < OVL_ADAPTOR_MERGE0)
+		pm_runtime_enable(comp->dev);
+
+	dev_info(dev, "[DRM]regs:0x%p, node:%s\n", comp->regs, ovl_adaptor_comp_str[id]);
+
+	return 0;
+}
+
+static int mtk_disp_ovl_adaptor_comp_probe(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int mtk_disp_ovl_adaptor_comp_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = {
+	{
+		.compatible = "mediatek,mt8195-vdo1-rdma",
+		.data = (void *)OVL_ADAPTOR_TYPE_RDMA,
+	}, {
+		.compatible = "mediatek,mt8195-vdo1-merge",
+		.data = (void *)OVL_ADAPTOR_TYPE_MERGE,
+	},
+	{},
+};
+
+static struct platform_driver mtk_disp_ovl_adaptor_comp_driver = {
+	.probe		= mtk_disp_ovl_adaptor_comp_probe,
+	.remove		= mtk_disp_ovl_adaptor_comp_remove,
+	.driver = {
+		.name	= "mediatek-disp-ovl-adaptor-comp",
+		.owner	= THIS_MODULE,
+		.of_match_table = mtk_ovl_adaptor_comp_dt_ids,
+	},
+};
+module_platform_driver(mtk_disp_ovl_adaptor_comp_driver);
+
+static int ovl_adaptor_comp_init(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
+	struct device_node *node, *parent;
+	int i, ret;
+
+	parent = dev->parent->of_node->parent;
+
+	for_each_child_of_node(parent, node) {
+		const struct of_device_id *of_id;
+		enum mtk_ovl_adaptor_comp_type type;
+		struct mtk_ovl_adaptor_comp *comp;
+		int id;
+
+		of_id = of_match_node(mtk_ovl_adaptor_comp_dt_ids, node);
+		if (!of_id)
+			continue;
+
+		if (!of_device_is_available(node)) {
+			dev_info(dev, "Skipping disabled component %pOF\n",
+				 node);
+			continue;
+		}
+
+		type = (enum mtk_ovl_adaptor_comp_type)of_id->data;
+		id = ovl_adaptor_comp_get_id(dev, node, type);
+		if (id < 0) {
+			dev_warn(dev, "Skipping unknown component %pOF\n",
+				 node);
+			continue;
+		}
+
+		ret = private_comp_init(dev, node, &priv->ovl_adaptor_comp[id], id);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id ovl_adaptor_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-ethdr"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_disp_ovl_adaptor_driver_dt_match);
+
+static int mtk_disp_ovl_adaptor_probe(struct platform_device *pdev)
+{
+	struct mtk_disp_ovl_adaptor *priv;
+	struct device *dev = &pdev->dev;
+	struct device_node *phandle = dev->parent->of_node;
+	const struct of_device_id *of_id;
+	int ret;
+	int i;
+
+	dev_info(dev, "%s+\n", __func__);
+
+	of_id = of_match_node(ovl_adaptor_driver_dt_match, phandle);
+	if (!of_id)
+		return -ENODEV;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mmsys_dev = pdev->dev.platform_data;
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = ovl_adaptor_comp_init(dev);
+	if (ret) {
+		dev_notice(dev, "ovl_adaptor comp init fail\n");
+		return ret;
+	}
+
+	dev_info(dev, "%s-\n", __func__);
+	return ret;
+}
+
+static int mtk_disp_ovl_adaptor_remove(struct platform_device *pdev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(&pdev->dev);
+	int i;
+
+	for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_MERGE0; i++)
+		pm_runtime_disable(ovl_adaptor->ovl_adaptor_comp[i].dev);
+
+	return 0;
+}
+
+struct platform_driver mtk_disp_ovl_adaptor_driver = {
+	.probe = mtk_disp_ovl_adaptor_probe,
+	.remove = mtk_disp_ovl_adaptor_remove,
+	.driver = {
+			.name = "mediatek-disp-ovl-adaptor",
+			.owner = THIS_MODULE,
+		},
+};
+module_platform_driver(mtk_disp_ovl_adaptor_driver);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
new file mode 100644
index 000000000000..7d757be1f491
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MTK_DISP_OVL_ADAPTOR_H__
+#define __MTK_DISP_OVL_ADAPTOR_H__
+
+#include <drm/mediatek_drm.h>
+
+void mtk_ovl_adaptor_stop(struct device *dev);
+int mtk_ovl_adaptor_clk_enable(struct device *dev);
+void mtk_ovl_adaptor_clk_disable(struct device *dev);
+void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
+				  struct mtk_plane_state *state,
+				  struct cmdq_pkt *cmdq_pkt);
+
+#endif
+
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:32 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:32 +0800
Subject: [PATCH v3 00/15] Add MediaTek SoC DRM (vdosys1) support for mt8195
Message-ID: <20210818091847.8060-1-nancy.lin@mediatek.com>

The hardware path of vdosys1 with DPTx output need to go through by several modules, such as, OVL_ADAPTOR and MERGE.

Add DRM and these modules support by the patches below:

Changes in v3:
- modify for reviewer's comment in v2.
- add vdosys1 2 pixels align limit.
- add mixer odd offset support.

Changes in v2:
- Merge PSEUDO_OVL and ETHDR into one DRM component.
- Add mmsys config API for vdosys1 hardware setting.
- Add mmsys reset control using linux reset framework.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

This series are based on the following patch:
[1] arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
[2] arm64: dts: mt8195: add IOMMU and smi nodes
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
[3] [01/24] dt-bindings: mediatek: mt8195: Add binding for MM IOMMU
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210630023504.18177-2-yong.wu at mediatek.com/
[4] Add gce support for mt8195
    https://patchwork.kernel.org/project/linux-mediatek/list/?series=515599
[5] Add MediaTek SoC DRM (vdosys0) support for mt8195
    https://patchwork.kernel.org/project/linux-mediatek/list/?series=531695
[6] [v8,1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header file
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210806023606.16867-2-Christine.Zhu at mediatek.com/

Nancy.Lin (15):
  dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
  dt-bindings: mediatek: add vdosys1 MERGE definition for mt8195
  dt-bindings: mediatek: add ethdr definition for mt8195
  dt-bindings: mediatek: Add #reset-cells to mmsys system controller
  dt-bindings: reset: mt8195: add vdosys1 reset control bit
  arm64: dts: mt8195: add display node for vdosys1
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
  soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1
  soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195
    vdosys1
  soc: mediatek: mmsys: Add reset controller support for MT8195 vdosys1
  soc: mediatek: add mtk-mutex support for mt8195 vdosys1
  drm/mediatek: add display MDP RDMA support for MT8195
  drm/mediatek: add ovl_adaptor support for MT8195
  drm/mediatek: add ETHDR support for MT8195
  drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |   3 +
 .../display/mediatek/mediatek,ethdr.yaml      | 144 +++++
 .../display/mediatek/mediatek,mdp-rdma.yaml   |  77 +++
 .../display/mediatek/mediatek,merge.yaml      |   2 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 217 +++++++
 drivers/gpu/drm/mediatek/Makefile             |   5 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  28 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     |   4 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 528 ++++++++++++++++++
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.h   |  19 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       |  25 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h       |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  15 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        | 375 +++++++++++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   9 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c          | 440 +++++++++++++++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c       | 275 +++++++++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h       |  39 ++
 drivers/soc/mediatek/mt8195-mmsys.h           | 199 +++++++
 drivers/soc/mediatek/mtk-mmsys.c              | 137 +++++
 drivers/soc/mediatek/mtk-mmsys.h              |  11 +
 drivers/soc/mediatek/mtk-mutex.c              | 270 +++++----
 include/dt-bindings/reset/mt8195-resets.h     |  12 +
 include/linux/soc/mediatek/mtk-mmsys.h        |  22 +
 25 files changed, 2677 insertions(+), 183 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:39 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:39 +0800
Subject: [PATCH v3 07/15] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys1
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-8-nancy.lin@mediatek.com>

Add mt8195 vdosys1 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 136 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       |  10 ++
 include/linux/soc/mediatek/mtk-mmsys.h |   2 +
 3 files changed, 148 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index 39a2b125494d..3c2b1d43dcc4 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -59,6 +59,70 @@
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 << 16)
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(3 << 16)
 
+#define MT8195_VDO1_VPP_MERGE0_P0_SEL_IN			0xf04
+#define MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0		(1 << 0)
+
+#define MT8195_VDO1_VPP_MERGE0_P1_SEL_IN			0xf08
+#define MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1		(1 << 0)
+
+#define MT8195_VDO1_DISP_DPI1_SEL_IN				0xf10
+#define MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT		(0 << 0)
+
+#define MT8195_VDO1_DISP_DP_INTF0_SEL_IN			0xf14
+#define MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT	(0 << 0)
+
+#define MT8195_VDO1_MERGE4_SOUT_SEL				0xf18
+#define MT8195_MERGE4_SOUT_TO_DPI1_SEL				(2 << 0)
+#define MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL			(3 << 0)
+
+#define MT8195_VDO1_MIXER_IN1_SEL_IN				0xf24
+#define MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_IN2_SEL_IN				0xf28
+#define MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_IN3_SEL_IN				0xf2c
+#define MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_IN4_SEL_IN				0xf30
+#define MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_OUT_SOUT_SEL				0xf34
+#define MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL			(1 << 0)
+
+#define MT8195_VDO1_VPP_MERGE1_P0_SEL_IN			0xf3c
+#define MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2		(1 << 0)
+
+#define MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL			0xf40
+#define MT8195_SOUT_TO_MIXER_IN1_SEL				(1 << 0)
+
+#define MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL			0xf44
+#define MT8195_SOUT_TO_MIXER_IN2_SEL				(1 << 0)
+
+#define MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL			0xf48
+#define MT8195_SOUT_TO_MIXER_IN3_SEL				(1 << 0)
+
+#define MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL			0xf4c
+#define MT8195_SOUT_TO_MIXER_IN4_SEL				(1 << 0)
+
+#define MT8195_VDO1_MERGE4_ASYNC_SEL_IN				0xf50
+#define MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_IN1_SOUT_SEL				0xf58
+#define MT8195_MIXER_IN1_SOUT_TO_DISP_MIXER			(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN2_SOUT_SEL				0xf5c
+#define MT8195_MIXER_IN2_SOUT_TO_DISP_MIXER			(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN3_SOUT_SEL				0xf60
+#define MT8195_MIXER_IN3_SOUT_TO_DISP_MIXER			(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN4_SOUT_SEL				0xf64
+#define MT8195_MIXER_IN4_SOUT_TO_DISP_MIXER			(0 << 0)
+
+#define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
+#define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER		(0 << 0)
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	{
 		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -108,6 +172,78 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 		DDP_COMPONENT_MERGE0 , DDP_COMPONENT_DP_INTF0,
 		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
 		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE0_P0_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE0_P1_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE1_P0_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN1_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN2_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN3_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN4_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_OUT_SOUT_SEL, GENMASK(0, 0),
+		MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN1_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN2_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN3_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN4_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_SOUT_SEL_IN, GENMASK(2, 0),
+		MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE4_ASYNC_SEL_IN, GENMASK(2, 0),
+		MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
+		MT8195_VDO1_DISP_DPI1_SEL_IN, GENMASK(1, 0),
+		MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
+		MT8195_VDO1_MERGE4_SOUT_SEL, GENMASK(1, 0),
+		MT8195_MERGE4_SOUT_TO_DPI1_SEL
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
+		MT8195_VDO1_DISP_DP_INTF0_SEL_IN, GENMASK(1, 0),
+		MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
+		MT8195_VDO1_MERGE4_SOUT_SEL, GENMASK(1, 0),
+		MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL
 	}
 };
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index ce6cc2f49e7d..7365731c9fd7 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -66,6 +66,12 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
+	.clk_driver = "clk-mt8195-vdo1",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
@@ -182,6 +188,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8195-vdosys0",
 		.data = &mt8195_vdosys0_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys1",
+		.data = &mt8195_vdosys1_driver_data,
+	},
 	{ }
 };
 
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 6d6ece48b61e..619392221a52 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -18,6 +18,7 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
 	DDP_COMPONENT_DP_INTF0,
+	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
 	DDP_COMPONENT_DSC0,
@@ -38,6 +39,7 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_OVL0,
 	DDP_COMPONENT_OVL_2L0,
 	DDP_COMPONENT_OVL_2L1,
+	DDP_COMPONENT_OVL_ADAPTOR,
 	DDP_COMPONENT_OVL1,
 	DDP_COMPONENT_PWM0,
 	DDP_COMPONENT_PWM1,
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:47 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:47 +0800
Subject: [PATCH v3 15/15] drm/mediatek: add mediatek-drm of vdosys1 support
 for MT8195
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-16-nancy.lin@mediatek.com>

Add driver data of mt8195 vdosys1 to mediatek-drm and modify drm for
multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring
up two drm drivers, only one drm driver register as the drm device.
Each drm driver binds its own component. The first bind drm driver
will allocate the drm device, and the last bind drm driver registers
the drm device to drm core. Each crtc path is created with the
corresponding drm driver data.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   |   4 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |  25 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  15 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 372 ++++++++++++++++----
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   8 +-
 7 files changed, 354 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index ebcb646bde9c..c61f5bafd22c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/reset.h>
 #include <linux/component.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
@@ -87,6 +88,9 @@ void mtk_merge_stop(struct device *dev)
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
 	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+
+	if (priv->async_clk)
+		device_reset_optional(dev);
 }
 
 static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 40df2c823187..0da78adf3b4f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -737,21 +737,28 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 }
 
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
-			const enum mtk_ddp_comp_id *path, unsigned int path_len)
+			const enum mtk_ddp_comp_id *path, unsigned int path_len,
+			int priv_data_index)
 {
 	struct mtk_drm_private *priv = drm_dev->dev_private;
 	struct device *dev = drm_dev->dev;
 	struct mtk_drm_crtc *mtk_crtc;
 	unsigned int num_comp_planes = 0;
-	int pipe = priv->num_pipes;
 	int ret;
 	int i;
 	bool has_ctm = false;
 	uint gamma_lut_size = 0;
+	struct drm_crtc *tmp;
+	int crtc_i = 0;
 
 	if (!path)
 		return 0;
 
+	priv = priv->all_drm_private[priv_data_index];
+
+	drm_for_each_crtc(tmp, drm_dev)
+		crtc_i++;
+
 	for (i = 0; i < path_len; i++) {
 		enum mtk_ddp_comp_id comp_id = path[i];
 		struct device_node *node;
@@ -760,7 +767,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 		if (!node) {
 			dev_info(dev,
 				 "Not creating crtc %d because component %d is disabled or missing\n",
-				 pipe, comp_id);
+				 crtc_i, comp_id);
 			return 0;
 		}
 	}
@@ -816,25 +823,25 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 		ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
-						    pipe);
+						    crtc_i);
 		if (ret)
 			return ret;
 	}
 
-	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
+	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
 	if (ret < 0)
 		return ret;
 
 	if (gamma_lut_size)
 		drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
 	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
-	priv->num_pipes++;
 	mutex_init(&mtk_crtc->hw_lock);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	i = (priv->data->mmsys_dev_num > 1) ? 0 : drm_crtc_index(&mtk_crtc->base);
+
 	mtk_crtc->cmdq_client =
-			cmdq_mbox_create(mtk_crtc->mmsys_dev,
-					 drm_crtc_index(&mtk_crtc->base));
+			cmdq_mbox_create(mtk_crtc->mmsys_dev, i);
 	if (IS_ERR(mtk_crtc->cmdq_client)) {
 		dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
 			drm_crtc_index(&mtk_crtc->base));
@@ -844,7 +851,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 	if (mtk_crtc->cmdq_client) {
 		ret = of_property_read_u32_index(priv->mutex_node,
 						 "mediatek,gce-events",
-						 drm_crtc_index(&mtk_crtc->base),
+						 i,
 						 &mtk_crtc->cmdq_event);
 		if (ret) {
 			dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index cb9a36c48d4f..a57eb12d7c05 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -17,7 +17,8 @@
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
 			const enum mtk_ddp_comp_id *path,
-			unsigned int path_len);
+			unsigned int path_len,
+			int priv_data_index);
 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 			     struct mtk_plane_state *state);
 void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index ee8efc13eaea..9623adbc2277 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -380,6 +380,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
 	.start = mtk_ufoe_start,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
+	.clk_enable = mtk_ethdr_clk_enable,
+	.clk_disable = mtk_ethdr_clk_disable,
+	.config = mtk_ethdr_config,
+	.start = mtk_ethdr_start,
+	.stop = mtk_ethdr_stop,
+	.layer_nr = mtk_ethdr_layer_nr,
+	.layer_config = mtk_ethdr_layer_config,
+	.enable_vblank = mtk_ethdr_enable_vblank,
+	.disable_vblank = mtk_ethdr_disable_vblank,
+};
+
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_AAL] = "aal",
 	[MTK_DISP_BLS] = "bls",
@@ -393,6 +405,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
 	[MTK_DISP_OVL_2L] = "ovl-2l",
+	[MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor",
 	[MTK_DISP_PWM] = "pwm",
 	[MTK_DISP_RDMA] = "rdma",
 	[MTK_DISP_UFOE] = "ufoe",
@@ -436,6 +449,7 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_OVL1]	= { MTK_DISP_OVL,	1, &ddp_ovl },
 	[DDP_COMPONENT_OVL_2L0]	= { MTK_DISP_OVL_2L,	0, &ddp_ovl },
 	[DDP_COMPONENT_OVL_2L1]	= { MTK_DISP_OVL_2L,	1, &ddp_ovl },
+	[DDP_COMPONENT_OVL_ADAPTOR] = { MTK_DISP_OVL_ADAPTOR,	0, &ddp_ovl_adaptor },
 	[DDP_COMPONENT_PWM0]	= { MTK_DISP_PWM,	0, NULL },
 	[DDP_COMPONENT_PWM1]	= { MTK_DISP_PWM,	1, NULL },
 	[DDP_COMPONENT_PWM2]	= { MTK_DISP_PWM,	2, NULL },
@@ -563,6 +577,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
+	    type == MTK_DISP_OVL_ADAPTOR ||
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index b42a47c06956..a8e5e770ce2f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -30,6 +30,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
 	MTK_DISP_OVL_2L,
+	MTK_DISP_OVL_ADAPTOR,
 	MTK_DISP_PWM,
 	MTK_DISP_RDMA,
 	MTK_DISP_UFOE,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 6a18c12fe04e..c233069b4cc2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -11,6 +11,7 @@
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
 #include <linux/dma-mapping.h>
+#include <linux/reset-controller.h>
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -160,12 +161,20 @@ static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
 	DDP_COMPONENT_DP_INTF0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_ext[] = {
+	DDP_COMPONENT_OVL_ADAPTOR,
+	DDP_COMPONENT_MERGE5,
+	DDP_COMPONENT_DP_INTF1,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
 	.ext_path = mt2701_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
 	.shadow_register = true,
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
@@ -174,6 +183,8 @@ static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
 	.ext_path = mt7623_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
 	.shadow_register = true,
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
@@ -183,6 +194,8 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
 	.third_path = mt2712_mtk_ddp_third,
 	.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
@@ -190,6 +203,8 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
 	.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
 	.ext_path = mt8173_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
@@ -197,32 +212,226 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
 	.ext_path = mt8183_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
 	.main_path = mt8195_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+	.mmsys_id = 0,
+	.mmsys_dev_num = 2,
+};
+
+static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
+	.ext_path = mt8195_mtk_ddp_ext,
+	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
+	.mmsys_id = 1,
+	.mmsys_dev_num = 2,
+};
+
+static const struct of_device_id mtk_drm_of_ids[] = {
+	{ .compatible = "mediatek,mt2701-mmsys",
+	  .data = &mt2701_mmsys_driver_data},
+	{ .compatible = "mediatek,mt7623-mmsys",
+	  .data = &mt7623_mmsys_driver_data},
+	{ .compatible = "mediatek,mt2712-mmsys",
+	  .data = &mt2712_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8173-mmsys",
+	  .data = &mt8173_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8183-mmsys",
+	  .data = &mt8183_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
+	{ .compatible = "mediatek,mt8195-vdosys1",
+	  .data = &mt8195_vdosys1_driver_data},
+	{ }
 };
+MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
+
+static int mtk_drm_match(struct device *dev, void *data)
+{
+	if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
+		return true;
+	return false;
+}
+
+static int mtk_drm_get_drm_priv(struct device *dev,
+				struct mtk_drm_private **all_drm_priv,
+				int num)
+{
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct device_node *phandle = dev->parent->of_node;
+	const struct of_device_id *of_id;
+	struct device_node *node;
+	int cnt = 0;
+	struct device *drm_dev;
+
+	for_each_child_of_node(phandle->parent, node) {
+		struct platform_device *pdev;
+
+		of_id = of_match_node(mtk_drm_of_ids, node);
+		if (!of_id)
+			continue;
+
+		pdev = of_find_device_by_node(node);
+		if (!pdev)
+			continue;
+
+		drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
+		if (!drm_dev || !dev_get_drvdata(drm_dev))
+			continue;
+
+		all_drm_priv[cnt++] = dev_get_drvdata(drm_dev);
+		if (cnt == num)
+			break;
+	}
+
+	return 0;
+}
+
+static bool mtk_drm_check_last_drm_bind(struct device *dev)
+{
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
+	int cnt = 0;
+	int i;
+
+	mtk_drm_get_drm_priv(dev, all_drm_priv, drm_priv->data->mmsys_dev_num);
+
+	for (i = 0; i < MAX_CRTC; i++)
+		if (all_drm_priv[i] && all_drm_priv[i]->mtk_drm_bound)
+			cnt++;
+
+	return (drm_priv->data->mmsys_dev_num == cnt);
+}
+
+static bool mtk_drm_find_drm_dev(struct device *dev, struct drm_device **drm)
+{
+	struct device_node *phandle = dev->parent->of_node;
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
+	int i;
+
+	if (!drm_priv->data->mmsys_dev_num)
+		return false;
+
+	mtk_drm_get_drm_priv(dev, all_drm_priv, drm_priv->data->mmsys_dev_num);
+
+	for (i = 0; i < MAX_CRTC; i++) {
+		if (all_drm_priv[i] && all_drm_priv[i]->mtk_drm_bound) {
+			*drm = all_drm_priv[i]->drm;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int mtk_drm_setup_all_drm_private(struct device *dev)
+{
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
+	int mmsys_dev_num = drm_priv->data->mmsys_dev_num;
+	int i;
+	int j;
+
+	mtk_drm_get_drm_priv(dev, all_drm_priv, mmsys_dev_num);
+
+	for (i = 0; i < mmsys_dev_num; i++)
+		for (j = 0; j < mmsys_dev_num; j++)
+			all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
+
+	return 0;
+}
+
+static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
+{
+	const struct mtk_mmsys_driver_data *drv_data = private->data;
+	int ret = false;
+	int i;
+
+	if (drv_data->mmsys_dev_num == 1)
+		return true;
+
+	if (drv_data->main_path) {
+		for (i = 0; i < drv_data->main_len; i++)
+			if (drv_data->main_path[i] == comp_id)
+				ret |= true;
+
+		if (i == drv_data->main_len)
+			ret |= false;
+	}
+
+	if (drv_data->ext_path) {
+		for (i = 0; i < drv_data->ext_len; i++)
+			if (drv_data->ext_path[i] == comp_id)
+				ret |= true;
+
+		if (i == drv_data->ext_len)
+			ret |= false;
+	}
+
+	if (drv_data->third_path) {
+		for (i = 0; i < drv_data->third_len; i++)
+			if (drv_data->third_path[i] == comp_id)
+				ret |= true;
+
+		if (i == drv_data->third_len)
+			ret |= false;
+	}
+
+	return ret;
+}
+
+static int mtk_drm_check_mutex_dev(struct mtk_drm_private *private)
+{
+	struct platform_device *pdev;
+	struct mtk_drm_private *priv_i;
+	int ret;
+	int i;
+
+	for (i = 0; i < private->data->mmsys_dev_num; i++) {
+		priv_i = private->all_drm_private[i];
+
+		pdev = of_find_device_by_node(priv_i->mutex_node);
+		if (!pdev) {
+			dev_err(priv_i->dev, "Waiting for disp-mutex device %pOF\n",
+				priv_i->mutex_node);
+			ret = -EPROBE_DEFER;
+			goto err_put_mutex;
+		}
+		priv_i->mutex_dev = &pdev->dev;
+	}
+
+	return 0;
+
+err_put_mutex:
+	for (i = 0; i < private->data->mmsys_dev_num; i++) {
+		priv_i = private->all_drm_private[i];
+		of_node_put(priv_i->mutex_node);
+	}
+
+	return ret;
+}
 
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
+	struct mtk_drm_private *priv_n;
 	struct platform_device *pdev;
-	struct device_node *np;
+	struct device_node *np = NULL;
 	struct device *dma_dev;
 	int ret;
+	int i;
+	int j;
 
 	if (!iommu_present(&platform_bus_type))
 		return -EPROBE_DEFER;
 
-	pdev = of_find_device_by_node(private->mutex_node);
-	if (!pdev) {
-		dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
-			private->mutex_node);
-		of_node_put(private->mutex_node);
-		return -EPROBE_DEFER;
-	}
-	private->mutex_dev = &pdev->dev;
+	ret = mtk_drm_check_mutex_dev(private);
+	if (ret)
+		return ret;
 
 	ret = drmm_mode_config_init(drm);
 	if (ret)
@@ -241,33 +450,57 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
 	drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
 
-	ret = component_bind_all(drm->dev, drm);
+	for (i = 0; i < private->data->mmsys_dev_num; i++) {
+		drm->dev_private = private->all_drm_private[i];
+		ret = component_bind_all(private->all_drm_private[i]->dev, drm);
 	if (ret)
 		goto put_mutex_dev;
+	}
 
 	/*
 	 * We currently support two fixed data streams, each optional,
 	 * and each statically assigned to a crtc:
 	 * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
 	 */
-	ret = mtk_drm_crtc_create(drm, private->data->main_path,
-				  private->data->main_len);
-	if (ret < 0)
-		goto err_component_unbind;
-	/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
-	ret = mtk_drm_crtc_create(drm, private->data->ext_path,
-				  private->data->ext_len);
-	if (ret < 0)
-		goto err_component_unbind;
-
-	ret = mtk_drm_crtc_create(drm, private->data->third_path,
-				  private->data->third_len);
-	if (ret < 0)
-		goto err_component_unbind;
+	for (i = 0; i < MAX_CRTC; i++) {
+		for (j = 0; j < private->data->mmsys_dev_num; j++) {
+			priv_n = private->all_drm_private[j];
+
+			if (i == 0 && priv_n->data->main_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
+							  priv_n->data->main_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->main_path[0]];
+
+				continue;
+			} else if (i == 1 && priv_n->data->ext_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->ext_path,
+							  priv_n->data->ext_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->ext_path[0]];
+
+				continue;
+			} else if (i == 2 && priv_n->data->third_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->third_path,
+							  priv_n->data->third_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->third_path[0]];
+
+				continue;
+			}
+		}
+	}
 
 	/* Use OVL device for all DMA memory allocations */
-	np = private->comp_node[private->data->main_path[0]] ?:
-	     private->comp_node[private->data->ext_path[0]];
 	pdev = of_find_device_by_node(np);
 	if (!pdev) {
 		ret = -ENODEV;
@@ -276,13 +509,15 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	}
 
 	dma_dev = &pdev->dev;
-	private->dma_dev = dma_dev;
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		private->all_drm_private[i]->dma_dev = dma_dev;
 
 	/*
 	 * Configure the DMA segment size to make sure we get contiguous IOVA
 	 * when importing PRIME buffers.
 	 */
 	ret = dma_set_max_seg_size(dma_dev, UINT_MAX);
+
 	if (ret) {
 		dev_err(dma_dev, "Failed to set DMA segment size\n");
 		goto err_component_unbind;
@@ -304,9 +539,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	return 0;
 
 err_component_unbind:
-	component_unbind_all(drm->dev, drm);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		component_unbind_all(private->all_drm_private[i]->dev, drm);
 put_mutex_dev:
-	put_device(private->mutex_dev);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		put_device(private->all_drm_private[i]->mutex_dev);
+
 	return ret;
 }
 
@@ -371,12 +609,21 @@ static int mtk_drm_bind(struct device *dev)
 	struct drm_device *drm;
 	int ret;
 
-	drm = drm_dev_alloc(&mtk_drm_driver, dev);
-	if (IS_ERR(drm))
-		return PTR_ERR(drm);
+	if (!mtk_drm_find_drm_dev(dev, &drm)) {
+		drm = drm_dev_alloc(&mtk_drm_driver, dev);
+		if (IS_ERR(drm))
+			return PTR_ERR(drm);
+		drm->dev_private = private;
+	}
 
-	drm->dev_private = private;
+	private->dev = dev;
 	private->drm = drm;
+	private->mtk_drm_bound = true;
+
+	if (!mtk_drm_check_last_drm_bind(dev))
+		return 0;
+
+	mtk_drm_setup_all_drm_private(dev);
 
 	ret = mtk_drm_kms_init(drm);
 	if (ret < 0)
@@ -401,10 +648,13 @@ static void mtk_drm_unbind(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
 
-	drm_dev_unregister(private->drm);
-	mtk_drm_kms_deinit(private->drm);
-	drm_dev_put(private->drm);
-	private->num_pipes = 0;
+	/* for multi mmsys dev, unregister drm dev in mmsys master */
+	if (private->data->mmsys_id == 0) {
+		drm_dev_unregister(private->drm);
+		mtk_drm_kms_deinit(private->drm);
+		drm_dev_put(private->drm);
+	}
+	private->mtk_drm_bound = false;
 	private->drm = NULL;
 }
 
@@ -485,50 +735,40 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	{ }
 };
 
-static const struct of_device_id mtk_drm_of_ids[] = {
-	{ .compatible = "mediatek,mt2701-mmsys",
-	  .data = &mt2701_mmsys_driver_data},
-	{ .compatible = "mediatek,mt7623-mmsys",
-	  .data = &mt7623_mmsys_driver_data},
-	{ .compatible = "mediatek,mt2712-mmsys",
-	  .data = &mt2712_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8173-mmsys",
-	  .data = &mt8173_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8183-mmsys",
-	  .data = &mt8183_mmsys_driver_data},
-	{.compatible = "mediatek,mt8195-vdosys0",
-	  .data = &mt8195_vdosys0_driver_data},
-	{ }
-};
-MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-
 static int mtk_drm_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *phandle = dev->parent->of_node;
 	const struct of_device_id *of_id;
+	const struct mtk_mmsys_driver_data *drv_data;
 	struct mtk_drm_private *private;
 	struct device_node *node;
 	struct component_match *match = NULL;
 	int ret;
 	int i;
 
+	of_id = of_match_node(mtk_drm_of_ids, phandle);
+	if (!of_id)
+		return -ENODEV;
+
+	drv_data = of_id->data;
 	private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
 	if (!private)
 		return -ENOMEM;
 
+	private->all_drm_private = devm_kmalloc_array(dev, drv_data->mmsys_dev_num,
+						      sizeof(*private->all_drm_private),
+						      GFP_KERNEL);
+	if (!private->all_drm_private)
+		return -ENOMEM;
+
+	private->data = drv_data;
 	private->mmsys_dev = dev->parent;
 	if (!private->mmsys_dev) {
 		dev_err(dev, "Failed to get MMSYS device\n");
 		return -ENODEV;
 	}
 
-	of_id = of_match_node(mtk_drm_of_ids, phandle);
-	if (!of_id)
-		return -ENODEV;
-
-	private->data = of_id->data;
-
 	/* Iterate over sibling DISP function blocks */
 	for_each_child_of_node(phandle->parent, node) {
 		const struct of_device_id *of_id;
@@ -548,7 +788,13 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		comp_type = (enum mtk_ddp_comp_type)of_id->data;
 
 		if (comp_type == MTK_DISP_MUTEX) {
-			private->mutex_node = of_node_get(node);
+			int id;
+
+			id = of_alias_get_id(node, "mutex");
+			if (id < 0 || id == drv_data->mmsys_id) {
+				private->mutex_node = of_node_get(node);
+				dev_dbg(dev, "get mutex for mmsys %d", drv_data->mmsys_id);
+			}
 			continue;
 		}
 
@@ -559,6 +805,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
 			continue;
 		}
 
+		if (!mtk_drm_find_mmsys_comp(private, comp_id))
+			continue;
+
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
@@ -572,6 +821,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
+		    comp_type == MTK_DISP_OVL_ADAPTOR ||
 		    comp_type == MTK_DISP_RDMA ||
 		    comp_type == MTK_DPI ||
 		    comp_type == MTK_DSI) {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 7b09fe6db067..867d7b8e788f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -29,14 +29,15 @@ struct mtk_mmsys_driver_data {
 	unsigned int third_len;
 
 	bool shadow_register;
+	unsigned int mmsys_id;
+	unsigned int mmsys_dev_num;
 };
 
 struct mtk_drm_private {
 	struct drm_device *drm;
 	struct device *dma_dev;
-
-	unsigned int num_pipes;
-
+	bool mtk_drm_bound;
+	struct device *dev;
 	struct device_node *mutex_node;
 	struct device *mutex_dev;
 	struct device *mmsys_dev;
@@ -44,6 +45,7 @@ struct mtk_drm_private {
 	struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_ID_MAX];
 	const struct mtk_mmsys_driver_data *data;
 	struct drm_atomic_state *suspend_state;
+	struct mtk_drm_private **all_drm_private;
 };
 
 extern struct platform_driver mtk_disp_ccorr_driver;
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:43 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:43 +0800
Subject: [PATCH v3 11/15] soc: mediatek: add mtk-mutex support for mt8195
 vdosys1
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-12-nancy.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys1.
The vdosys1 path component contains ovl_adaptor, merge5,
and dp_intf1. Ovl_adaptor is composed of several sub-elements,
so change it to support multi-bit control.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 270 ++++++++++++++++++-------------
 1 file changed, 162 insertions(+), 108 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index c177156ee2fa..588e378d1855 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -29,101 +29,130 @@
 
 #define INT_MUTEX				BIT(1)
 
-#define MT8167_MUTEX_MOD_DISP_PWM		1
-#define MT8167_MUTEX_MOD_DISP_OVL0		6
-#define MT8167_MUTEX_MOD_DISP_OVL1		7
-#define MT8167_MUTEX_MOD_DISP_RDMA0		8
-#define MT8167_MUTEX_MOD_DISP_RDMA1		9
-#define MT8167_MUTEX_MOD_DISP_WDMA0		10
-#define MT8167_MUTEX_MOD_DISP_CCORR		11
-#define MT8167_MUTEX_MOD_DISP_COLOR		12
-#define MT8167_MUTEX_MOD_DISP_AAL		13
-#define MT8167_MUTEX_MOD_DISP_GAMMA		14
-#define MT8167_MUTEX_MOD_DISP_DITHER		15
-#define MT8167_MUTEX_MOD_DISP_UFOE		16
-
-#define MT8183_MUTEX_MOD_DISP_RDMA0		0
-#define MT8183_MUTEX_MOD_DISP_RDMA1		1
-#define MT8183_MUTEX_MOD_DISP_OVL0		9
-#define MT8183_MUTEX_MOD_DISP_OVL0_2L		10
-#define MT8183_MUTEX_MOD_DISP_OVL1_2L		11
-#define MT8183_MUTEX_MOD_DISP_WDMA0		12
-#define MT8183_MUTEX_MOD_DISP_COLOR0		13
-#define MT8183_MUTEX_MOD_DISP_CCORR0		14
-#define MT8183_MUTEX_MOD_DISP_AAL0		15
-#define MT8183_MUTEX_MOD_DISP_GAMMA0		16
-#define MT8183_MUTEX_MOD_DISP_DITHER0		17
-
-#define MT8173_MUTEX_MOD_DISP_OVL0		11
-#define MT8173_MUTEX_MOD_DISP_OVL1		12
-#define MT8173_MUTEX_MOD_DISP_RDMA0		13
-#define MT8173_MUTEX_MOD_DISP_RDMA1		14
-#define MT8173_MUTEX_MOD_DISP_RDMA2		15
-#define MT8173_MUTEX_MOD_DISP_WDMA0		16
-#define MT8173_MUTEX_MOD_DISP_WDMA1		17
-#define MT8173_MUTEX_MOD_DISP_COLOR0		18
-#define MT8173_MUTEX_MOD_DISP_COLOR1		19
-#define MT8173_MUTEX_MOD_DISP_AAL		20
-#define MT8173_MUTEX_MOD_DISP_GAMMA		21
-#define MT8173_MUTEX_MOD_DISP_UFOE		22
-#define MT8173_MUTEX_MOD_DISP_PWM0		23
-#define MT8173_MUTEX_MOD_DISP_PWM1		24
-#define MT8173_MUTEX_MOD_DISP_OD		25
-
-#define MT8195_MUTEX_MOD_DISP_OVL0		0
-#define MT8195_MUTEX_MOD_DISP_WDMA0		1
-#define MT8195_MUTEX_MOD_DISP_RDMA0		2
-#define MT8195_MUTEX_MOD_DISP_COLOR0		3
-#define MT8195_MUTEX_MOD_DISP_CCORR0		4
-#define MT8195_MUTEX_MOD_DISP_AAL0		5
-#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
-#define MT8195_MUTEX_MOD_DISP_DITHER0		7
-#define MT8195_MUTEX_MOD_DISP_DSI0		8
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
-#define MT8195_MUTEX_MOD_DISP_OVL1		10
-#define MT8195_MUTEX_MOD_DISP_WDMA1		11
-#define MT8195_MUTEX_MOD_DISP_RDMA1		12
-#define MT8195_MUTEX_MOD_DISP_COLOR1		13
-#define MT8195_MUTEX_MOD_DISP_CCORR1		14
-#define MT8195_MUTEX_MOD_DISP_AAL1		15
-#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
-#define MT8195_MUTEX_MOD_DISP_DITHER1		17
-#define MT8195_MUTEX_MOD_DISP_DSI1		18
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
-#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
-#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
-#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
-#define MT8195_MUTEX_MOD_DISP_PWM0		27
-#define MT8195_MUTEX_MOD_DISP_PWM1		28
-
-#define MT2712_MUTEX_MOD_DISP_PWM2		10
-#define MT2712_MUTEX_MOD_DISP_OVL0		11
-#define MT2712_MUTEX_MOD_DISP_OVL1		12
-#define MT2712_MUTEX_MOD_DISP_RDMA0		13
-#define MT2712_MUTEX_MOD_DISP_RDMA1		14
-#define MT2712_MUTEX_MOD_DISP_RDMA2		15
-#define MT2712_MUTEX_MOD_DISP_WDMA0		16
-#define MT2712_MUTEX_MOD_DISP_WDMA1		17
-#define MT2712_MUTEX_MOD_DISP_COLOR0		18
-#define MT2712_MUTEX_MOD_DISP_COLOR1		19
-#define MT2712_MUTEX_MOD_DISP_AAL0		20
-#define MT2712_MUTEX_MOD_DISP_UFOE		22
-#define MT2712_MUTEX_MOD_DISP_PWM0		23
-#define MT2712_MUTEX_MOD_DISP_PWM1		24
-#define MT2712_MUTEX_MOD_DISP_OD0		25
-#define MT2712_MUTEX_MOD2_DISP_AAL1		33
-#define MT2712_MUTEX_MOD2_DISP_OD1		34
-
-#define MT2701_MUTEX_MOD_DISP_OVL		3
-#define MT2701_MUTEX_MOD_DISP_WDMA		6
-#define MT2701_MUTEX_MOD_DISP_COLOR		7
-#define MT2701_MUTEX_MOD_DISP_BLS		9
-#define MT2701_MUTEX_MOD_DISP_RDMA0		10
-#define MT2701_MUTEX_MOD_DISP_RDMA1		12
+#define MT8167_MUTEX_MOD_DISP_PWM		BIT(1)
+#define MT8167_MUTEX_MOD_DISP_OVL0		BIT(6)
+#define MT8167_MUTEX_MOD_DISP_OVL1		BIT(7)
+#define MT8167_MUTEX_MOD_DISP_RDMA0		BIT(8)
+#define MT8167_MUTEX_MOD_DISP_RDMA1		BIT(9)
+#define MT8167_MUTEX_MOD_DISP_WDMA0		BIT(10)
+#define MT8167_MUTEX_MOD_DISP_CCORR		BIT(11)
+#define MT8167_MUTEX_MOD_DISP_COLOR		BIT(12)
+#define MT8167_MUTEX_MOD_DISP_AAL		BIT(13)
+#define MT8167_MUTEX_MOD_DISP_GAMMA		BIT(14)
+#define MT8167_MUTEX_MOD_DISP_DITHER		BIT(15)
+#define MT8167_MUTEX_MOD_DISP_UFOE		BIT(16)
+
+#define MT8183_MUTEX_MOD_DISP_RDMA0		BIT(0)
+#define MT8183_MUTEX_MOD_DISP_RDMA1		BIT(1)
+#define MT8183_MUTEX_MOD_DISP_OVL0		BIT(9)
+#define MT8183_MUTEX_MOD_DISP_OVL0_2L		BIT(10)
+#define MT8183_MUTEX_MOD_DISP_OVL1_2L		BIT(11)
+#define MT8183_MUTEX_MOD_DISP_WDMA0		BIT(12)
+#define MT8183_MUTEX_MOD_DISP_COLOR0		BIT(13)
+#define MT8183_MUTEX_MOD_DISP_CCORR0		BIT(14)
+#define MT8183_MUTEX_MOD_DISP_AAL0		BIT(15)
+#define MT8183_MUTEX_MOD_DISP_GAMMA0		BIT(16)
+#define MT8183_MUTEX_MOD_DISP_DITHER0		BIT(17)
+
+#define MT8173_MUTEX_MOD_DISP_OVL0		BIT(11)
+#define MT8173_MUTEX_MOD_DISP_OVL1		BIT(12)
+#define MT8173_MUTEX_MOD_DISP_RDMA0		BIT(13)
+#define MT8173_MUTEX_MOD_DISP_RDMA1		BIT(14)
+#define MT8173_MUTEX_MOD_DISP_RDMA2		BIT(15)
+#define MT8173_MUTEX_MOD_DISP_WDMA0		BIT(16)
+#define MT8173_MUTEX_MOD_DISP_WDMA1		BIT(17)
+#define MT8173_MUTEX_MOD_DISP_COLOR0		BIT(18)
+#define MT8173_MUTEX_MOD_DISP_COLOR1		BIT(19)
+#define MT8173_MUTEX_MOD_DISP_AAL		BIT(20)
+#define MT8173_MUTEX_MOD_DISP_GAMMA		BIT(21)
+#define MT8173_MUTEX_MOD_DISP_UFOE		BIT(22)
+#define MT8173_MUTEX_MOD_DISP_PWM0		BIT(23)
+#define MT8173_MUTEX_MOD_DISP_PWM1		BIT(24)
+#define MT8173_MUTEX_MOD_DISP_OD		BIT(25)
+
+#define MT8195_MUTEX_MOD_DISP_OVL0		BIT(0)
+#define MT8195_MUTEX_MOD_DISP_WDMA0		BIT(1)
+#define MT8195_MUTEX_MOD_DISP_RDMA0		BIT(2)
+#define MT8195_MUTEX_MOD_DISP_COLOR0		BIT(3)
+#define MT8195_MUTEX_MOD_DISP_CCORR0		BIT(4)
+#define MT8195_MUTEX_MOD_DISP_AAL0		BIT(5)
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		BIT(6)
+#define MT8195_MUTEX_MOD_DISP_DITHER0		BIT(7)
+#define MT8195_MUTEX_MOD_DISP_DSI0		BIT(8)
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	BIT(9)
+#define MT8195_MUTEX_MOD_DISP_OVL1		BIT(10)
+#define MT8195_MUTEX_MOD_DISP_WDMA1		BIT(11)
+#define MT8195_MUTEX_MOD_DISP_RDMA1		BIT(12)
+#define MT8195_MUTEX_MOD_DISP_COLOR1		BIT(13)
+#define MT8195_MUTEX_MOD_DISP_CCORR1		BIT(14)
+#define MT8195_MUTEX_MOD_DISP_AAL1		BIT(15)
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		BIT(16)
+#define MT8195_MUTEX_MOD_DISP_DITHER1		BIT(17)
+#define MT8195_MUTEX_MOD_DISP_DSI1		BIT(18)
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	BIT(19)
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		BIT(20)
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		BIT(21)
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	BIT(22)
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	BIT(23)
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	BIT(24)
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	BIT(25)
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	BIT(26)
+#define MT8195_MUTEX_MOD_DISP_PWM0		BIT(27)
+#define MT8195_MUTEX_MOD_DISP_PWM1		BIT(28)
+
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA0 BIT(0)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA1 BIT(1)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA2 BIT(2)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA3 BIT(3)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA4 BIT(4)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA5 BIT(5)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA6 BIT(6)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA7 BIT(7)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE0 BIT(8)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE1 BIT(9)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE2 BIT(10)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE3 BIT(11)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE4 BIT(12)
+#define MT8195_MUTEX_MOD_DISP1_VPP2_DL_RELAY BIT(13)
+#define MT8195_MUTEX_MOD_DISP1_VPP3_DL_RELAY BIT(14)
+#define MT8195_MUTEX_MOD_DISP1_VDO0_DSC_DL_ASYNC BIT(15)
+#define MT8195_MUTEX_MOD_DISP1_VDO0_MERGE_DL_ASYNC BIT(16)
+#define MT8195_MUTEX_MOD_DISP1_VDO1_OUT_DL_RELAY BIT(17)
+#define MT8195_MUTEX_MOD_DISP1_DISP_MIXER BIT(18)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 BIT(19)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 BIT(20)
+#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 BIT(21)
+#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 BIT(22)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 BIT(23)
+#define MT8195_MUTEX_MOD_DISP1_HDR_MLOAD BIT(24)
+#define MT8195_MUTEX_MOD_DISP1_DPI0 BIT(25)
+#define MT8195_MUTEX_MOD_DISP1_DPI1 BIT(26)
+#define MT8195_MUTEX_MOD_DISP1_DP_INTF0 BIT(27)
+
+#define MT2712_MUTEX_MOD_DISP_PWM2		BIT(10)
+#define MT2712_MUTEX_MOD_DISP_OVL0		BIT(11)
+#define MT2712_MUTEX_MOD_DISP_OVL1		BIT(12)
+#define MT2712_MUTEX_MOD_DISP_RDMA0		BIT(13)
+#define MT2712_MUTEX_MOD_DISP_RDMA1		BIT(14)
+#define MT2712_MUTEX_MOD_DISP_RDMA2		BIT(15)
+#define MT2712_MUTEX_MOD_DISP_WDMA0		BIT(16)
+#define MT2712_MUTEX_MOD_DISP_WDMA1		BIT(17)
+#define MT2712_MUTEX_MOD_DISP_COLOR0		BIT(18)
+#define MT2712_MUTEX_MOD_DISP_COLOR1		BIT(19)
+#define MT2712_MUTEX_MOD_DISP_AAL0		BIT(20)
+#define MT2712_MUTEX_MOD_DISP_UFOE		BIT(22)
+#define MT2712_MUTEX_MOD_DISP_PWM0		BIT(23)
+#define MT2712_MUTEX_MOD_DISP_PWM1		BIT(24)
+#define MT2712_MUTEX_MOD_DISP_OD0		BIT(25)
+#define MT2712_MUTEX_MOD2_DISP_AAL1		BIT(33)
+#define MT2712_MUTEX_MOD2_DISP_OD1		BIT(34)
+
+#define MT2701_MUTEX_MOD_DISP_OVL		BIT(3)
+#define MT2701_MUTEX_MOD_DISP_WDMA		BIT(6)
+#define MT2701_MUTEX_MOD_DISP_COLOR		BIT(7)
+#define MT2701_MUTEX_MOD_DISP_BLS		BIT(9)
+#define MT2701_MUTEX_MOD_DISP_RDMA0		BIT(10)
+#define MT2701_MUTEX_MOD_DISP_RDMA1		BIT(12)
 
 #define MT2712_MUTEX_SOF_SINGLE_MODE		0
 #define MT2712_MUTEX_SOF_DSI0			1
@@ -174,7 +203,7 @@ enum mtk_mutex_sof_id {
 };
 
 struct mtk_mutex_data {
-	const unsigned int *mutex_mod;
+	const unsigned long *mutex_mod;
 	const unsigned int *mutex_sof;
 	const unsigned int mutex_mod_reg;
 	const unsigned int mutex_sof_reg;
@@ -189,7 +218,7 @@ struct mtk_mutex_ctx {
 	const struct mtk_mutex_data	*data;
 };
 
-static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
 	[DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
 	[DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
@@ -198,7 +227,7 @@ static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
 };
 
-static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
 	[DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
@@ -218,7 +247,7 @@ static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1,
 };
 
-static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL,
 	[DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR,
 	[DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR,
@@ -233,7 +262,7 @@ static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL,
 	[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
 	[DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
@@ -251,7 +280,7 @@ static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
 };
 
-static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0,
 	[DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0,
@@ -265,7 +294,7 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
 	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
 	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
@@ -279,6 +308,27 @@ static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
 	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
 	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
+	[DDP_COMPONENT_OVL_ADAPTOR] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA0 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA1 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA2 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA3 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA4 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA5 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA6 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA7 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE0 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE1 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE2 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE3 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_MLOAD |
+				      MT8195_MUTEX_MOD_DISP1_DISP_MIXER,
+	[DDP_COMPONENT_MERGE5] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE4,
+	[DDP_COMPONENT_DP_INTF1] = MT8195_MUTEX_MOD_DISP1_DP_INTF0,
 };
 
 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
@@ -436,17 +486,20 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DP_INTF0:
 		sof_id = MUTEX_SOF_DP_INTF0;
 		break;
+	case DDP_COMPONENT_DP_INTF1:
+		sof_id = MUTEX_SOF_DP_INTF1;
+		break;
 	default:
-		if (mtx->data->mutex_mod[id] < 32) {
+		if (mtx->data->mutex_mod[id] <= BIT(31)) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
 						    mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg |= 1 << mtx->data->mutex_mod[id];
+			reg |= mtx->data->mutex_mod[id];
 			writel_relaxed(reg, mtx->regs + offset);
 		} else {
 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg |= 1 << (mtx->data->mutex_mod[id] - 32);
+			reg |= (mtx->data->mutex_mod[id] >> 32);
 			writel_relaxed(reg, mtx->regs + offset);
 		}
 		return;
@@ -476,22 +529,23 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DPI0:
 	case DDP_COMPONENT_DPI1:
 	case DDP_COMPONENT_DP_INTF0:
+	case DDP_COMPONENT_DP_INTF1:
 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
 			       mtx->regs +
 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
 						  mutex->id));
 		break;
 	default:
-		if (mtx->data->mutex_mod[id] < 32) {
+		if (mtx->data->mutex_mod[id] <= BIT(31)) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
 						    mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg &= ~(1 << mtx->data->mutex_mod[id]);
+			reg &= ~(mtx->data->mutex_mod[id]);
 			writel_relaxed(reg, mtx->regs + offset);
 		} else {
 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg &= ~(1 << (mtx->data->mutex_mod[id] - 32));
+			reg &= ~(mtx->data->mutex_mod[id] >> 32);
 			writel_relaxed(reg, mtx->regs + offset);
 		}
 		break;
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:44 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:44 +0800
Subject: [PATCH v3 12/15] drm/mediatek: add display MDP RDMA support for MT8195
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-13-nancy.lin@mediatek.com>

Add MDP_RDMA driver for MT8195. MDP_RDMA is the DMA engine of
the ovl_adaptor component.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile       |   3 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  12 ++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 275 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h |  39 ++++
 4 files changed, 328 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 538e0087a44c..38ec2354a894 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -12,7 +12,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \
 		  mtk_drm_gem.o \
 		  mtk_drm_plane.o \
 		  mtk_dsi.o \
-		  mtk_dpi.o
+		  mtk_dpi.o \
+		  mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index f407cd9d873e..7129ba061ecb 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -8,6 +8,7 @@
 
 #include <linux/soc/mediatek/mtk-cmdq.h>
 #include "mtk_drm_plane.h"
+#include "mtk_mdp_rdma.h"
 
 void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state);
 int mtk_ccorr_clk_enable(struct device *dev);
@@ -97,4 +98,15 @@ void mtk_rdma_enable_vblank(struct device *dev,
 			    void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+void mtk_mdp_rdma_start(void __iomem *base,
+			struct cmdq_pkt *cmdq_pkt,
+			struct cmdq_client_reg *cmdq_base);
+void mtk_mdp_rdma_stop(void __iomem *base,
+		       struct cmdq_pkt *cmdq_pkt,
+		       struct cmdq_client_reg *cmdq_base);
+void mtk_mdp_rdma_config(void __iomem *base,
+			 struct mtk_mdp_rdma_cfg *cfg,
+			 struct cmdq_pkt *cmdq_pkt,
+			 struct cmdq_client_reg *cmdq_base);
+
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
new file mode 100644
index 000000000000..95e762eda4a8
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include "mtk_drm_drv.h"
+#include "mtk_mdp_rdma.h"
+
+#define REG_FLD(width, shift) \
+	((unsigned int)((((width) & 0xff) << 16) | ((shift) & 0xff)))
+
+#define REG_FLD_WIDTH(field) ((unsigned int)(((field) >> 16) & 0xff))
+
+#define REG_FLD_SHIFT(field) ((unsigned int)((field) & 0xff))
+
+#define REG_FLD_MASK(field) \
+	((unsigned int)((1ULL << REG_FLD_WIDTH(field)) - 1) \
+	 << REG_FLD_SHIFT(field))
+
+#define REG_FLD_VAL(field, val) \
+	(((val) << REG_FLD_SHIFT(field)) & REG_FLD_MASK(field))
+
+#define MDP_RDMA_EN                                            0x000
+#define FLD_ROT_ENABLE                            REG_FLD(1, 0)
+
+#define MDP_RDMA_RESET                                         0x008
+
+#define MDP_RDMA_CON                                           0x020
+#define FLD_OUTPUT_10B                            REG_FLD(1, 5)
+#define FLD_SIMPLE_MODE                           REG_FLD(1, 4)
+
+#define MDP_RDMA_GMCIF_CON                                     0x028
+#define FLD_EXT_ULTRA_EN                          REG_FLD(1, 18)
+#define FLD_PRE_ULTRA_EN                          REG_FLD(2, 16)
+#define FLD_ULTRA_EN                              REG_FLD(2, 12)
+#define FLD_RD_REQ_TYPE                           REG_FLD(4, 4)
+#define VAL_RD_REQ_TYPE_BURST_8_ACCESS       7
+#define FLD_EXT_PREULTRA_EN                       REG_FLD(1, 3)
+#define FLD_COMMAND_DIV                           REG_FLD(1, 0)
+
+#define MDP_RDMA_SRC_CON                                       0x030
+#define FLD_OUTPUT_ARGB                           REG_FLD(1, 25)
+#define FLD_BIT_NUMBER                            REG_FLD(2, 18)
+#define FLD_UNIFORM_CONFIG                        REG_FLD(1, 17)
+#define FLD_SWAP                                  REG_FLD(1, 14)
+#define FLD_SRC_FORMAT                            REG_FLD(4, 0)
+
+#define MDP_RDMA_COMP_CON                                      0x038
+#define FLD_AFBC_EN                               REG_FLD(1, 22)
+#define FLD_AFBC_YUV_TRANSFORM                    REG_FLD(1, 21)
+#define FLD_UFBDC_EN                              REG_FLD(1, 12)
+
+#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE                          0x060
+#define FLD_MF_BKGD_WB                            REG_FLD(23, 0)
+
+#define MDP_RDMA_MF_BKGD_SIZE_IN_PIXEL                         0x068
+#define FLD_MF_BKGD_WP                            REG_FLD(23, 0)
+
+#define MDP_RDMA_MF_SRC_SIZE                                   0x070
+#define FLD_MF_SRC_H                              REG_FLD(15, 16)
+#define FLD_MF_SRC_W                              REG_FLD(15, 0)
+
+#define MDP_RDMA_MF_CLIP_SIZE                                  0x078
+#define FLD_MF_CLIP_H                             REG_FLD(15, 16)
+#define FLD_MF_CLIP_W                             REG_FLD(15, 0)
+
+#define MDP_RDMA_TARGET_LINE                                   0x0a0
+#define FLD_LINE_THRESHOLD                        REG_FLD(15, 17)
+#define FLD_TARGET_LINE_EN                        REG_FLD(1, 16)
+
+#define MDP_RDMA_SRC_OFFSET_0                                  0x118
+#define FLD_SRC_OFFSET_0                          REG_FLD(32, 0)
+
+#define MDP_RDMA_TRANSFORM_0                                   0x200
+#define FLD_INT_MATRIX_SEL                        REG_FLD(5, 23)
+#define FLD_TRANS_EN                              REG_FLD(1, 16)
+
+#define MDP_RDMA_UTRA_H_CON_0                                  0x248
+#define FLD_PREUTRA_H_OFS_0                       REG_FLD(10, 10)
+
+#define MDP_RDMA_UTRA_L_CON_0                                  0x250
+#define FLD_PREUTRA_L_OFS_0                       REG_FLD(10, 10)
+
+#define MDP_RDMA_SRC_BASE_0                                    0xf00
+#define FLD_SRC_BASE_0                            REG_FLD(32, 0)
+
+#define RDMA_INPUT_SWAP		BIT(14)
+#define RDMA_INPUT_10BIT	BIT(18)
+
+enum rdma_format {
+	RDMA_INPUT_FORMAT_RGB565 = 0,
+	RDMA_INPUT_FORMAT_RGB888 = 1,
+	RDMA_INPUT_FORMAT_RGBA8888 = 2,
+	RDMA_INPUT_FORMAT_ARGB8888 = 3,
+	RDMA_INPUT_FORMAT_UYVY = 4,
+	RDMA_INPUT_FORMAT_YUY2 = 5,
+	RDMA_INPUT_FORMAT_Y8 = 7,
+	RDMA_INPUT_FORMAT_YV12 = 8,
+	RDMA_INPUT_FORMAT_UYVY_3PL = 9,
+	RDMA_INPUT_FORMAT_NV12 = 12,
+	RDMA_INPUT_FORMAT_UYVY_2PL = 13,
+	RDMA_INPUT_FORMAT_Y410 = 14
+};
+
+static unsigned int rdma_fmt_convert(unsigned int fmt)
+{
+	switch (fmt) {
+	default:
+	case DRM_FORMAT_RGB565:
+		return RDMA_INPUT_FORMAT_RGB565;
+	case DRM_FORMAT_BGR565:
+		return RDMA_INPUT_FORMAT_RGB565 | RDMA_INPUT_SWAP;
+	case DRM_FORMAT_RGB888:
+		return RDMA_INPUT_FORMAT_RGB888;
+	case DRM_FORMAT_BGR888:
+		return RDMA_INPUT_FORMAT_RGB888 | RDMA_INPUT_SWAP;
+	case DRM_FORMAT_RGBX8888:
+	case DRM_FORMAT_RGBA8888:
+		return RDMA_INPUT_FORMAT_ARGB8888;
+	case DRM_FORMAT_BGRX8888:
+	case DRM_FORMAT_BGRA8888:
+		return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_SWAP;
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ARGB8888:
+		return RDMA_INPUT_FORMAT_RGBA8888;
+	case DRM_FORMAT_XBGR8888:
+	case DRM_FORMAT_ABGR8888:
+		return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_SWAP;
+	case DRM_FORMAT_ABGR2101010:
+		return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_SWAP |
+				RDMA_INPUT_10BIT;
+	case DRM_FORMAT_ARGB2101010:
+		return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_10BIT;
+	case DRM_FORMAT_RGBA1010102:
+		return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_SWAP |
+				RDMA_INPUT_10BIT;
+	case DRM_FORMAT_BGRA1010102:
+		return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_10BIT;
+	case DRM_FORMAT_UYVY:
+		return RDMA_INPUT_FORMAT_UYVY;
+	case DRM_FORMAT_YUYV:
+		return RDMA_INPUT_FORMAT_YUY2;
+	}
+}
+
+static void mtk_mdp_rdma_fifo_config(void __iomem *base, struct cmdq_pkt *cmdq_pkt,
+				     struct cmdq_client_reg *cmdq_base)
+{
+	unsigned int pre_ultra_h = 156;
+	unsigned int pre_ultra_l = 104;
+	unsigned int reg_mask;
+	unsigned int reg_val;
+	unsigned int reg;
+
+	reg = MDP_RDMA_GMCIF_CON;
+	reg_val = REG_FLD_VAL(FLD_RD_REQ_TYPE, VAL_RD_REQ_TYPE_BURST_8_ACCESS) |
+		  REG_FLD_VAL(FLD_COMMAND_DIV, 1) |
+		  REG_FLD_VAL(FLD_EXT_PREULTRA_EN, 1) |
+		  REG_FLD_VAL(FLD_ULTRA_EN, 0) |
+		  REG_FLD_VAL(FLD_PRE_ULTRA_EN, 1) |
+		  REG_FLD_VAL(FLD_EXT_ULTRA_EN, 1);
+	reg_mask = REG_FLD_MASK(FLD_RD_REQ_TYPE) |
+		   REG_FLD_MASK(FLD_COMMAND_DIV) |
+		   REG_FLD_MASK(FLD_EXT_PREULTRA_EN) |
+		   REG_FLD_MASK(FLD_ULTRA_EN) |
+		   REG_FLD_MASK(FLD_PRE_ULTRA_EN) |
+		   REG_FLD_MASK(FLD_EXT_ULTRA_EN);
+	mtk_ddp_write_mask(cmdq_pkt, reg_val, cmdq_base, base, reg, reg_mask);
+
+	reg = MDP_RDMA_UTRA_H_CON_0;
+	reg_val = REG_FLD_VAL(FLD_PREUTRA_H_OFS_0, pre_ultra_h);
+	reg_mask = REG_FLD_MASK(FLD_PREUTRA_H_OFS_0);
+	mtk_ddp_write_mask(cmdq_pkt, reg_val, cmdq_base, base, reg, reg_mask);
+
+	reg = MDP_RDMA_UTRA_L_CON_0;
+	reg_val = REG_FLD_VAL(FLD_PREUTRA_L_OFS_0, pre_ultra_l);
+	reg_mask = REG_FLD_MASK(FLD_PREUTRA_L_OFS_0);
+	mtk_ddp_write_mask(cmdq_pkt, reg_val, cmdq_base, base, reg, reg_mask);
+}
+
+void mtk_mdp_rdma_start(void __iomem *base, struct cmdq_pkt *cmdq_pkt,
+			struct cmdq_client_reg *cmdq_base)
+{
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_ROT_ENABLE, 1), cmdq_base,
+			   base, MDP_RDMA_EN, REG_FLD_MASK(FLD_ROT_ENABLE));
+}
+
+void mtk_mdp_rdma_stop(void __iomem *base, struct cmdq_pkt *cmdq_pkt,
+		       struct cmdq_client_reg *cmdq_base)
+{
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_ROT_ENABLE, 0), cmdq_base,
+			   base, MDP_RDMA_EN, REG_FLD_MASK(FLD_ROT_ENABLE));
+	mtk_ddp_write(cmdq_pkt, 1, cmdq_base, base, MDP_RDMA_RESET);
+	mtk_ddp_write(cmdq_pkt, 0, cmdq_base, base, MDP_RDMA_RESET);
+}
+
+void mtk_mdp_rdma_config(void __iomem *base, struct mtk_mdp_rdma_cfg *cfg,
+			 struct cmdq_pkt *cmdq_pkt,
+			 struct cmdq_client_reg *cmdq_base)
+{
+	const struct drm_format_info *fmt_info = drm_format_info(cfg->fmt);
+	unsigned int src_pitch_y = cfg->pitch;
+	unsigned int bpp_y = fmt_info->cpp[0] * 8;
+	unsigned int offset_y = 0;
+
+	mtk_mdp_rdma_fifo_config(base, cmdq_pkt, cmdq_base);
+
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_UNIFORM_CONFIG, 1),
+			   cmdq_base, base, MDP_RDMA_SRC_CON,
+			   REG_FLD_MASK(FLD_UNIFORM_CONFIG));
+	mtk_ddp_write_mask(cmdq_pkt, rdma_fmt_convert(cfg->fmt), cmdq_base,
+			   base, MDP_RDMA_SRC_CON, REG_FLD_MASK(FLD_SWAP) |
+			   REG_FLD_MASK(FLD_SRC_FORMAT) |
+			   REG_FLD_MASK(FLD_BIT_NUMBER));
+
+	if (!cfg->csc_enable && fmt_info->has_alpha)
+		mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_OUTPUT_ARGB, 1),
+				   cmdq_base, base, MDP_RDMA_SRC_CON,
+				   REG_FLD_MASK(FLD_OUTPUT_ARGB));
+	else
+		mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_OUTPUT_ARGB, 0),
+				   cmdq_base, base, MDP_RDMA_SRC_CON,
+				   REG_FLD_MASK(FLD_OUTPUT_ARGB));
+
+	mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, cmdq_base, base,
+			   MDP_RDMA_SRC_BASE_0, REG_FLD_MASK(FLD_SRC_BASE_0));
+
+	mtk_ddp_write_mask(cmdq_pkt, src_pitch_y, cmdq_base, base,
+			   MDP_RDMA_MF_BKGD_SIZE_IN_BYTE,
+			   REG_FLD_MASK(FLD_MF_BKGD_WB));
+
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_AFBC_YUV_TRANSFORM, 0),
+			   cmdq_base, base, MDP_RDMA_COMP_CON,
+			   REG_FLD_MASK(FLD_AFBC_YUV_TRANSFORM));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_UFBDC_EN, 0), cmdq_base,
+			   base, MDP_RDMA_COMP_CON, REG_FLD_MASK(FLD_UFBDC_EN));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_AFBC_EN, 0), cmdq_base,
+			   base, MDP_RDMA_COMP_CON, REG_FLD_MASK(FLD_AFBC_EN));
+
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_OUTPUT_10B, 1), cmdq_base,
+			   base, MDP_RDMA_CON, REG_FLD_MASK(FLD_OUTPUT_10B));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_SIMPLE_MODE, 1), cmdq_base,
+			   base, MDP_RDMA_CON, REG_FLD_MASK(FLD_SIMPLE_MODE));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_TRANS_EN, cfg->csc_enable),
+			   cmdq_base, base, MDP_RDMA_TRANSFORM_0,
+			   REG_FLD_MASK(FLD_TRANS_EN));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_INT_MATRIX_SEL, cfg->profile),
+			   cmdq_base, base, MDP_RDMA_TRANSFORM_0,
+			   REG_FLD_MASK(FLD_INT_MATRIX_SEL));
+
+	offset_y  = (cfg->x_left * bpp_y >> 3) + cfg->y_top * src_pitch_y;
+
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_SRC_OFFSET_0, offset_y),
+			   cmdq_base, base, MDP_RDMA_SRC_OFFSET_0,
+			   REG_FLD_MASK(FLD_SRC_OFFSET_0));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_MF_SRC_W, cfg->width),
+			   cmdq_base, base, MDP_RDMA_MF_SRC_SIZE,
+			   REG_FLD_MASK(FLD_MF_SRC_W));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_MF_SRC_H, cfg->height),
+			   cmdq_base, base, MDP_RDMA_MF_SRC_SIZE,
+			   REG_FLD_MASK(FLD_MF_SRC_H));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_MF_CLIP_W, cfg->width),
+			   cmdq_base, base, MDP_RDMA_MF_CLIP_SIZE,
+			   REG_FLD_MASK(FLD_MF_CLIP_W));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_MF_CLIP_H, cfg->height),
+			   cmdq_base, base, MDP_RDMA_MF_CLIP_SIZE,
+			   REG_FLD_MASK(FLD_MF_CLIP_H));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_LINE_THRESHOLD, cfg->height),
+			   cmdq_base, base, MDP_RDMA_TARGET_LINE,
+			   REG_FLD_MASK(FLD_LINE_THRESHOLD));
+	mtk_ddp_write_mask(cmdq_pkt, REG_FLD_VAL(FLD_TARGET_LINE_EN, 1),
+			   cmdq_base, base, MDP_RDMA_TARGET_LINE,
+			   REG_FLD_MASK(FLD_TARGET_LINE_EN));
+}
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
new file mode 100644
index 000000000000..50fa6e18d244
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MTK_MDP_RDMA_H__
+#define __MTK_MDP_RDMA_H__
+
+enum mtk_mdp_rdma_profile {
+	RDMA_CSC_RGB_TO_JPEG = 0,
+	RDMA_CSC_RGB_TO_FULL709 = 1,
+	RDMA_CSC_RGB_TO_BT601 = 2,
+	RDMA_CSC_RGB_TO_BT709 = 3,
+	RDMA_CSC_JPEG_TO_RGB = 4,
+	RDMA_CSC_FULL709_TO_RGB = 5,
+	RDMA_CSC_BT601_TO_RGB = 6,
+	RDMA_CSC_BT709_TO_RGB = 7,
+	RDMA_CSC_JPEG_TO_BT601 = 8,
+	RDMA_CSC_JPEG_TO_BT709 = 9,
+	RDMA_CSC_BT601_TO_JPEG = 10,
+	RDMA_CSC_BT709_TO_BT601 = 11,
+	RDMA_CSC_BT601_TO_BT709 = 12
+};
+
+struct mtk_mdp_rdma_cfg {
+	enum mtk_mdp_rdma_profile profile;
+	unsigned int source_width;
+	unsigned int pitch;
+	unsigned int addr0;
+	unsigned int width;
+	unsigned int height;
+	unsigned int x_left;
+	unsigned int y_top;
+	bool csc_enable;
+	int fmt;
+};
+
+#endif // __MTK_MDP_RDMA_H__
+
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 18 02:18:46 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 18 Aug 2021 17:18:46 +0800
Subject: [PATCH v3 14/15] drm/mediatek: add ETHDR support for MT8195
In-Reply-To: <20210818091847.8060-1-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
Message-ID: <20210818091847.8060-15-nancy.lin@mediatek.com>

ETHDR is a part of ovl_adaptor.
ETHDR is designed for HDR video and graphics conversion in the external
display path. It handles multiple HDR input types and performs tone
mapping, color space/color format conversion, and then combine
different layers, output the required HDR or SDR signal to the
subsequent display path.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile       |   3 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  16 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   3 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   1 +
 drivers/gpu/drm/mediatek/mtk_ethdr.c    | 440 ++++++++++++++++++++++++
 5 files changed, 462 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index f04ac86c9593..c42d0623e629 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -14,7 +14,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \
 		  mtk_dsi.o \
 		  mtk_dpi.o \
 		  mtk_mdp_rdma.o \
-		  mtk_disp_ovl_adaptor.o
+		  mtk_disp_ovl_adaptor.o \
+		  mtk_ethdr.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 7129ba061ecb..964d0ad2b81d 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -98,6 +98,22 @@ void mtk_rdma_enable_vblank(struct device *dev,
 			    void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_ethdr_clk_enable(struct device *dev);
+void mtk_ethdr_clk_disable(struct device *dev);
+void mtk_ethdr_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
+			    struct mtk_plane_state *state,
+			    struct cmdq_pkt *cmdq_pkt);
+void mtk_ethdr_enable_vblank(struct device *dev,
+			     void (*vblank_cb)(void *),
+			     void *vblank_cb_data);
+void mtk_ethdr_disable_vblank(struct device *dev);
+void mtk_ethdr_start(struct device *dev);
+void mtk_ethdr_stop(struct device *dev);
+unsigned int mtk_ethdr_layer_nr(struct device *dev);
+
 void mtk_mdp_rdma_start(void __iomem *base,
 			struct cmdq_pkt *cmdq_pkt,
 			struct cmdq_client_reg *cmdq_base);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 9aebf73144c6..6a18c12fe04e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -452,6 +452,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
+	{ .compatible = "mediatek,mt8195-disp-ethdr",
+	  .data = (void *)MTK_DISP_OVL_ADAPTOR },
 	{ .compatible = "mediatek,mt2701-disp-pwm",
 	  .data = (void *)MTK_DISP_BLS },
 	{ .compatible = "mediatek,mt8173-disp-pwm",
@@ -674,6 +676,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_dpi_driver,
 	&mtk_drm_platform_driver,
 	&mtk_dsi_driver,
+	&mtk_ethdr_driver,
 };
 
 static int __init mtk_drm_init(void)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 0fa417219a69..7b09fe6db067 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -54,5 +54,6 @@ extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
+extern struct platform_driver mtk_ethdr_driver;
 
 #endif /* MTK_DRM_DRV_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
new file mode 100644
index 000000000000..05035b6015d8
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -0,0 +1,440 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_disp_ovl_adaptor.h"
+
+#define MIX_INTEN		0x4
+	#define MIX_FME_CPL_INTEN	BIT(1)
+#define MIX_INTSTA		0x8
+#define MIX_EN			0xc
+#define MIX_RST			0x14
+#define MIX_ROI_SIZE		0x18
+#define MIX_DATAPATH_CON	0x1c
+	#define OUTPUT_NO_RND	BIT(3)
+	#define SOURCE_RGB_SEL	BIT(7)
+	#define BACKGROUND_RELAY	(4 << 9)
+#define MIX_ROI_BGCLR		0x20
+	#define BGCLR_BLACK	0xff000000
+#define MIX_SRC_CON		0x24
+	#define MIX_SRC_L0_EN	BIT(0)
+#define MIX_L_SRC_CON(n)	(0x28 + 0x18 * (n))
+	#define NON_PREMULTI_SOURCE (2 << 12)
+#define MIX_L_SRC_SIZE(n)	(0x30 + 0x18 * (n))
+#define MIX_L_SRC_OFFSET(n)	(0x34 + 0x18 * (n))
+#define MIX_FUNC_DCM0		0x120
+#define MIX_FUNC_DCM1		0x124
+	#define MIX_FUNC_DCM_ENABLE 0xffffffff
+
+#define HDR_VDO_FE_0804_HDR_DM_FE	0x804
+	#define HDR_VDO_FE_0804_BYPASS_ALL	0xfd
+#define HDR_GFX_FE_0204_GFX_HDR_FE	0x204
+	#define HDR_GFX_FE_0204_BYPASS_ALL	0xfd
+#define HDR_VDO_BE_0204_VDO_DM_BE	0x204
+	#define HDR_VDO_BE_0204_BYPASS_ALL	0x7e
+
+#define MIXER_INx_MODE_BYPASS 0
+#define MIXER_INx_MODE_EVEN_EXTEND 1
+#define MIXER_INx_MODE_ODD_EXTEND 2
+#define DEFAULT_9BIT_ALPHA	0x100
+#define	MIXER_ALPHA_AEN		BIT(8)
+#define	MIXER_ALPHA		0xff
+#define ETHDR_CLK_NUM		13
+
+enum mtk_ethdr_comp_id {
+	ETHDR_MIXER,
+	ETHDR_VDO_FE0,
+	ETHDR_VDO_FE1,
+	ETHDR_GFX_FE0,
+	ETHDR_GFX_FE1,
+	ETHDR_VDO_BE,
+	ETHDR_ADL_DS,
+	ETHDR_ID_MAX
+};
+
+struct mtk_ethdr_comp {
+	struct device *dev;
+	void __iomem *regs;
+	struct cmdq_client_reg cmdq_base;
+};
+
+struct mtk_ethdr {
+	struct mtk_ethdr_comp ethdr_comp[ETHDR_ID_MAX];
+	struct clk_bulk_data ethdr_clk[ETHDR_CLK_NUM];
+	struct device *ovl_adaptor_dev;
+	struct device *mmsys_dev;
+	spinlock_t lock; /* protects vblank_cb and vblank_cb_data */
+	void (*vblank_cb)(void *data);
+	void *vblank_cb_data;
+	int irq;
+};
+
+static const char * const ethdr_comp_str[] = {
+	"ETHDR_MIXER",
+	"ETHDR_VDO_FE0",
+	"ETHDR_VDO_FE1",
+	"ETHDR_GFX_FE0",
+	"ETHDR_GFX_FE1",
+	"ETHDR_VDO_BE",
+	"ETHDR_ADL_DS",
+	"ETHDR_ID_MAX"
+};
+
+static const char * const ethdr_clk_str[] = {
+	"ethdr_top",
+	"mixer",
+	"vdo_fe0",
+	"vdo_fe1",
+	"gfx_fe0",
+	"gfx_fe1",
+	"vdo_be",
+	"adl_ds",
+	"vdo_fe0_async",
+	"vdo_fe1_async",
+	"gfx_fe0_async",
+	"gfx_fe1_async",
+	"vdo_be_async",
+};
+
+void mtk_ethdr_enable_vblank(struct device *dev,
+			     void (*vblank_cb)(void *),
+			     void *vblank_cb_data)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->vblank_cb = vblank_cb;
+	priv->vblank_cb_data = vblank_cb_data;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	writel(MIX_FME_CPL_INTEN, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
+}
+
+void mtk_ethdr_disable_vblank(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->vblank_cb = NULL;
+	priv->vblank_cb_data = NULL;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
+}
+
+static irqreturn_t mtk_ethdr_irq_handler(int irq, void *dev_id)
+{
+	struct mtk_ethdr *priv = dev_id;
+	unsigned long flags;
+
+	writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTSTA);
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->vblank_cb) {
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return IRQ_NONE;
+	}
+
+	priv->vblank_cb(priv->vblank_cb_data);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
+			    struct mtk_plane_state *state,
+			    struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+	struct mtk_plane_pending_state *pending = &state->pending;
+	unsigned int offset = (pending->y << 16) | pending->x;
+	unsigned int mixer_pad_mode = MIXER_INx_MODE_BYPASS;
+	unsigned int alpha_con = 0;
+	unsigned int fmt = 0;
+	unsigned int src_size;
+	bool x_offset_odd = false;
+
+	dev_dbg(dev, "%s+ idx:%d", __func__, idx);
+
+	if (idx >= 4)
+		return;
+
+	/* ETHDR is in 1T2P domain, width needs to be 2 pixels align */
+	pending->width = ALIGN_DOWN(pending->width, 2);
+	src_size = (pending->height << 16) | pending->width;
+
+	mtk_ovl_adaptor_layer_config(priv->ovl_adaptor_dev, idx, state, cmdq_pkt);
+
+	if (!pending->enable) {
+		mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_MODE,
+				     idx + 1, MIXER_INx_MODE_BYPASS, cmdq_pkt);
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+				     idx + 1, 0, cmdq_pkt);
+		return;
+	}
+
+	if (pending->x % 2) {
+		x_offset_odd = true;
+		mixer_pad_mode = MIXER_INx_MODE_EVEN_EXTEND;
+	}
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_MODE,
+			     idx + 1, mixer_pad_mode, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+			     idx + 1, pending->width / 2 - 1, cmdq_pkt);
+
+	if (state->base.fb && state->base.fb->format->has_alpha) {
+		alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_ALPHA_SEL,
+				     idx + 1, 0, cmdq_pkt);
+	} else {
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_ALPHA_SEL,
+				     idx + 1, 1, cmdq_pkt);
+	}
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, idx + 1,
+			     DEFAULT_9BIT_ALPHA, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, idx + 1,
+			     DEFAULT_9BIT_ALPHA, cmdq_pkt);
+
+	mtk_ddp_write(cmdq_pkt, src_size, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
+	mtk_ddp_write(cmdq_pkt, (x_offset_odd << 31) | offset, &mixer->cmdq_base,
+		      mixer->regs, MIX_L_SRC_OFFSET(idx));
+	mtk_ddp_write_mask(cmdq_pkt, alpha_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx),
+			   0x1ff);
+	mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs, MIX_SRC_CON,
+			   BIT(idx));
+}
+
+void mtk_ethdr_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *vdo_fe0 = &priv->ethdr_comp[ETHDR_VDO_FE0];
+	struct mtk_ethdr_comp *vdo_fe1 = &priv->ethdr_comp[ETHDR_VDO_FE1];
+	struct mtk_ethdr_comp *gfx_fe0 = &priv->ethdr_comp[ETHDR_GFX_FE0];
+	struct mtk_ethdr_comp *gfx_fe1 = &priv->ethdr_comp[ETHDR_GFX_FE1];
+	struct mtk_ethdr_comp *vdo_be = &priv->ethdr_comp[ETHDR_VDO_BE];
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	dev_dbg(dev, "%s-w:%d, h:%d\n", __func__, w, h);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_FE_0804_BYPASS_ALL, &vdo_fe0->cmdq_base,
+		      vdo_fe0->regs, HDR_VDO_FE_0804_HDR_DM_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_FE_0804_BYPASS_ALL, &vdo_fe1->cmdq_base,
+		      vdo_fe1->regs, HDR_VDO_FE_0804_HDR_DM_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_GFX_FE_0204_BYPASS_ALL, &gfx_fe0->cmdq_base,
+		      gfx_fe0->regs, HDR_GFX_FE_0204_GFX_HDR_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_GFX_FE_0204_BYPASS_ALL, &gfx_fe1->cmdq_base,
+		      gfx_fe1->regs, HDR_GFX_FE_0204_GFX_HDR_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_BE_0204_BYPASS_ALL, &vdo_be->cmdq_base,
+		      vdo_be->regs, HDR_VDO_BE_0204_VDO_DM_BE);
+
+	mtk_ddp_write(cmdq_pkt, MIX_FUNC_DCM_ENABLE, &mixer->cmdq_base, mixer->regs, MIX_FUNC_DCM0);
+	mtk_ddp_write(cmdq_pkt, MIX_FUNC_DCM_ENABLE, &mixer->cmdq_base, mixer->regs, MIX_FUNC_DCM1);
+	mtk_ddp_write(cmdq_pkt, (h << 16 | w), &mixer->cmdq_base, mixer->regs, MIX_ROI_SIZE);
+	mtk_ddp_write(cmdq_pkt, BGCLR_BLACK, &mixer->cmdq_base, mixer->regs, MIX_ROI_BGCLR);
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(0));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(1));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(2));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(3));
+	mtk_ddp_write(cmdq_pkt, 0x0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(0));
+	mtk_ddp_write(cmdq_pkt, OUTPUT_NO_RND | SOURCE_RGB_SEL | BACKGROUND_RELAY,
+		      &mixer->cmdq_base, mixer->regs, MIX_DATAPATH_CON);
+	mtk_ddp_write_mask(cmdq_pkt, MIX_SRC_L0_EN, &mixer->cmdq_base, mixer->regs,
+			   MIX_SRC_CON, MIX_SRC_L0_EN);
+
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0,
+			     w / 2, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0,
+			     h, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, 0, cmdq_pkt);
+}
+
+void mtk_ethdr_start(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	writel(1, mixer->regs + MIX_EN);
+}
+
+void mtk_ethdr_stop(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	mtk_ovl_adaptor_stop(priv->ovl_adaptor_dev);
+
+	writel(0, mixer->regs + MIX_EN);
+	writel(1, mixer->regs + MIX_RST);
+	reset_control_reset(devm_reset_control_array_get(dev, true, true));
+	writel(0, mixer->regs + MIX_RST);
+}
+
+int mtk_ethdr_clk_enable(struct device *dev)
+{
+	int ret;
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	mtk_ovl_adaptor_clk_enable(priv->ovl_adaptor_dev);
+
+	ret = clk_bulk_prepare_enable(ETHDR_CLK_NUM, priv->ethdr_clk);
+	if (ret)
+		dev_err(dev,
+			"ethdr_clk prepare enable failed\n");
+	return ret;
+}
+
+void mtk_ethdr_clk_disable(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	mtk_ovl_adaptor_clk_disable(priv->ovl_adaptor_dev);
+
+	clk_bulk_disable_unprepare(ETHDR_CLK_NUM, priv->ethdr_clk);
+}
+
+unsigned int mtk_ethdr_layer_nr(struct device *dev)
+{
+	return 4;
+}
+
+static int mtk_ethdr_bind(struct device *dev, struct device *master,
+			  void *data)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct platform_device *ovl_adaptor;
+	struct drm_device *drm_dev = data;
+	struct mtk_drm_private *drm_private = drm_dev->dev_private;
+
+	priv->mmsys_dev = drm_private->mmsys_dev;
+
+	/* Bring up ovl adaptor rdma and merge */
+	ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovl-adaptor",
+						    PLATFORM_DEVID_AUTO, (void *)priv->mmsys_dev,
+						    sizeof(*priv->mmsys_dev));
+	if (IS_ERR(ovl_adaptor))
+		return PTR_ERR(ovl_adaptor);
+
+	priv->ovl_adaptor_dev = &ovl_adaptor->dev;
+
+	return 0;
+}
+
+static void mtk_ethdr_unbind(struct device *dev, struct device *master, void *data)
+{
+}
+
+static const struct component_ops mtk_ethdr_component_ops = {
+	.bind	= mtk_ethdr_bind,
+	.unbind = mtk_ethdr_unbind,
+};
+
+static int mtk_ethdr_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_ethdr *priv;
+	int ret;
+	int i;
+
+	dev_info(dev, "%s+\n", __func__);
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	for (i = 0; i < ETHDR_ID_MAX; i++) {
+		priv->ethdr_comp[i].dev = dev;
+		priv->ethdr_comp[i].regs = of_iomap(dev->of_node, i);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+		ret = cmdq_dev_get_client_reg(dev,
+					      &priv->ethdr_comp[i].cmdq_base, i);
+		if (ret)
+			dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+		dev_info(dev, "[DRM]regs:0x%x, node:%s\n",
+			 priv->ethdr_comp[i].regs, ethdr_comp_str[i]);
+	}
+
+	for (i = 0; i < ETHDR_CLK_NUM; i++)
+		priv->ethdr_clk[i].id = ethdr_clk_str[i];
+	ret = devm_clk_bulk_get_optional(dev, ETHDR_CLK_NUM, priv->ethdr_clk);
+	if (ret)
+		return ret;
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (priv->irq < 0)
+		priv->irq = 0;
+
+	if (priv->irq) {
+		ret = devm_request_irq(dev, priv->irq, mtk_ethdr_irq_handler,
+				       IRQF_TRIGGER_NONE, dev_name(dev), priv);
+		if (ret < 0) {
+			dev_err(dev, "Failed to request irq %d: %d\n", priv->irq, ret);
+			return ret;
+		}
+	}
+
+	spin_lock_init(&priv->lock);
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_ethdr_component_ops);
+	if (ret)
+		dev_notice(dev, "Failed to add component: %d\n", ret);
+
+	dev_info(dev, "%s-\n", __func__);
+	pm_runtime_enable(dev);
+
+	return ret;
+}
+
+static int mtk_ethdr_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_ethdr_component_ops);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id mtk_ethdr_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-ethdr"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_ethdr_driver_dt_match);
+
+struct platform_driver mtk_ethdr_driver = {
+	.probe = mtk_ethdr_probe,
+	.remove = mtk_ethdr_remove,
+	.driver = {
+			.name = "mediatek-disp-ethdr",
+			.owner = THIS_MODULE,
+			.of_match_table = mtk_ethdr_driver_dt_match,
+		},
+};
-- 
2.18.0

From haibo.chen at nxp.com  Wed Aug 18 02:12:30 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 17:12:30 +0800
Subject: [PATCH] ARM: dts: imx: add minor fix to pass schema dtb check
Message-ID: <1629277950-7230-1-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add some fix to pass schema dtb check for fsl-imx-esdhc.yaml

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 arch/arm/boot/dts/imx50.dtsi   | 8 ++++----
 arch/arm/boot/dts/imx6sl.dtsi  | 8 ++++----
 arch/arm/boot/dts/imx6sll.dtsi | 6 +++---
 arch/arm/boot/dts/imx6sx.dtsi  | 8 ++++----
 arch/arm/boot/dts/imx6ul.dtsi  | 4 ++--
 arch/arm/boot/dts/imx6ull.dtsi | 4 ++--
 arch/arm/boot/dts/imx7s.dtsi   | 6 +++---
 arch/arm/boot/dts/imx7ulp.dtsi | 4 ++--
 arch/arm/boot/dts/vfxxx.dtsi   | 4 ++--
 9 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
index a969f335b240..a1814f10f7f0 100644
--- a/arch/arm/boot/dts/imx50.dtsi
+++ b/arch/arm/boot/dts/imx50.dtsi
@@ -116,7 +116,7 @@
 				ranges;
 
 				esdhc1: mmc at 50004000 {
-					compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc";
+					compatible = "fsl,imx53-esdhc";
 					reg = <0x50004000 0x4000>;
 					interrupts = <1>;
 					clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
@@ -128,7 +128,7 @@
 				};
 
 				esdhc2: mmc at 50008000 {
-					compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc";
+					compatible = "fsl,imx53-esdhc";
 					reg = <0x50008000 0x4000>;
 					interrupts = <2>;
 					clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
@@ -177,7 +177,7 @@
 				};
 
 				esdhc3: mmc at 50020000 {
-					compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc";
+					compatible = "fsl,imx53-esdhc";
 					reg = <0x50020000 0x4000>;
 					interrupts = <3>;
 					clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
@@ -189,7 +189,7 @@
 				};
 
 				esdhc4: mmc at 50024000 {
-					compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc";
+					compatible = "fsl,imx53-esdhc";
 					reg = <0x50024000 0x4000>;
 					interrupts = <4>;
 					clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 997b96c1c47b..e40e017b6f38 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -858,7 +858,7 @@
 			};
 
 			usdhc1: mmc at 2190000 {
-				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+				compatible = "fsl,imx6sl-usdhc";
 				reg = <0x02190000 0x4000>;
 				interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SL_CLK_USDHC1>,
@@ -870,7 +870,7 @@
 			};
 
 			usdhc2: mmc at 2194000 {
-				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+				compatible = "fsl,imx6sl-usdhc";
 				reg = <0x02194000 0x4000>;
 				interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SL_CLK_USDHC2>,
@@ -882,7 +882,7 @@
 			};
 
 			usdhc3: mmc at 2198000 {
-				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+				compatible = "fsl,imx6sl-usdhc";
 				reg = <0x02198000 0x4000>;
 				interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SL_CLK_USDHC3>,
@@ -894,7 +894,7 @@
 			};
 
 			usdhc4: mmc at 219c000 {
-				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
+				compatible = "fsl,imx6sl-usdhc";
 				reg = <0x0219c000 0x4000>;
 				interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SL_CLK_USDHC4>,
diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
index 04f8d637a501..82b248353386 100644
--- a/arch/arm/boot/dts/imx6sll.dtsi
+++ b/arch/arm/boot/dts/imx6sll.dtsi
@@ -711,7 +711,7 @@
 			};
 
 			usdhc1: mmc at 2190000 {
-				compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
+				compatible = "fsl,imx6sll-usdhc";
 				reg = <0x02190000 0x4000>;
 				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SLL_CLK_USDHC1>,
@@ -725,7 +725,7 @@
 			};
 
 			usdhc2: mmc at 2194000 {
-				compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
+				compatible = "fsl,imx6sll-usdhc";
 				reg = <0x02194000 0x4000>;
 				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SLL_CLK_USDHC2>,
@@ -739,7 +739,7 @@
 			};
 
 			usdhc3: mmc at 2198000 {
-				compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
+				compatible = "fsl,imx6sll-usdhc";
 				reg = <0x02198000 0x4000>;
 				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SLL_CLK_USDHC3>,
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 8516730778df..acab73c932c1 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -967,7 +967,7 @@
 			};
 
 			usdhc1: mmc at 2190000 {
-				compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
+				compatible = "fsl,imx6sx-usdhc";
 				reg = <0x02190000 0x4000>;
 				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SX_CLK_USDHC1>,
@@ -979,7 +979,7 @@
 			};
 
 			usdhc2: mmc at 2194000 {
-				compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
+				compatible = "fsl,imx6sx-usdhc";
 				reg = <0x02194000 0x4000>;
 				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SX_CLK_USDHC2>,
@@ -991,7 +991,7 @@
 			};
 
 			usdhc3: mmc at 2198000 {
-				compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
+				compatible = "fsl,imx6sx-usdhc";
 				reg = <0x02198000 0x4000>;
 				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SX_CLK_USDHC3>,
@@ -1003,7 +1003,7 @@
 			};
 
 			usdhc4: mmc at 219c000 {
-				compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
+				compatible = "fsl,imx6sx-usdhc";
 				reg = <0x0219c000 0x4000>;
 				interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6SX_CLK_USDHC4>,
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index afeec01f6522..c066d85b2c0a 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -891,7 +891,7 @@
 			};
 
 			usdhc1: mmc at 2190000 {
-				compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc";
+				compatible = "fsl,imx6sx-usdhc";
 				reg = <0x02190000 0x4000>;
 				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6UL_CLK_USDHC1>,
@@ -905,7 +905,7 @@
 			};
 
 			usdhc2: mmc at 2194000 {
-				compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc";
+				compatible = "fsl,imx6sx-usdhc";
 				reg = <0x02194000 0x4000>;
 				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6UL_CLK_USDHC2>,
diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
index 9bf67490ac49..8b1ed3bc7393 100644
--- a/arch/arm/boot/dts/imx6ull.dtsi
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -42,11 +42,11 @@
 };
 
 &usdhc1 {
-	compatible = "fsl,imx6ull-usdhc", "fsl,imx6sx-usdhc";
+	compatible = "fsl,imx6ull-usdhc";
 };
 
 &usdhc2 {
-	compatible = "fsl,imx6ull-usdhc", "fsl,imx6sx-usdhc";
+	compatible = "fsl,imx6ull-usdhc";
 };
 
 / {
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 1843fc053870..075f8e5c0579 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -1158,7 +1158,7 @@
 			};
 
 			usdhc1: mmc at 30b40000 {
-				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
+				compatible = "fsl,imx7d-usdhc";
 				reg = <0x30b40000 0x10000>;
 				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
@@ -1170,7 +1170,7 @@
 			};
 
 			usdhc2: mmc at 30b50000 {
-				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
+				compatible = "fsl,imx7d-usdhc";
 				reg = <0x30b50000 0x10000>;
 				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
@@ -1182,7 +1182,7 @@
 			};
 
 			usdhc3: mmc at 30b60000 {
-				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
+				compatible = "fsl,imx7d-usdhc";
 				reg = <0x30b60000 0x10000>;
 				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi
index b7ea37ad4e55..456c3f5f393c 100644
--- a/arch/arm/boot/dts/imx7ulp.dtsi
+++ b/arch/arm/boot/dts/imx7ulp.dtsi
@@ -216,7 +216,7 @@
 		};
 
 		usdhc0: mmc at 40370000 {
-			compatible = "fsl,imx7ulp-usdhc", "fsl,imx6sx-usdhc";
+			compatible = "fsl,imx7ulp-usdhc";
 			reg = <0x40370000 0x10000>;
 			interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>,
@@ -230,7 +230,7 @@
 		};
 
 		usdhc1: mmc at 40380000 {
-			compatible = "fsl,imx7ulp-usdhc", "fsl,imx6sx-usdhc";
+			compatible = "fsl,imx7ulp-usdhc";
 			reg = <0x40380000 0x10000>;
 			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>,
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index d53f9c9db8bf..c5651f23b3fd 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -574,7 +574,7 @@
 							<20000000>;
 			};
 
-			esdhc0: esdhc at 400b1000 {
+			esdhc0: mmc at 400b1000 {
 				compatible = "fsl,imx53-esdhc";
 				reg = <0x400b1000 0x1000>;
 				interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
@@ -585,7 +585,7 @@
 				status = "disabled";
 			};
 
-			esdhc1: esdhc at 400b2000 {
+			esdhc1: mmc at 400b2000 {
 				compatible = "fsl,imx53-esdhc";
 				reg = <0x400b2000 0x1000>;
 				interrupts = <28 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.17.1



From michal.simek at xilinx.com  Wed Aug 18 02:38:38 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Wed, 18 Aug 2021 11:38:38 +0200
Subject: [PATCH V3 2/3] dt-bindings: gpio: zynqmp: Add binding
 documentation for modepin
In-Reply-To: <5e44ee87-f727-99fd-9860-d3d58a035dc4@pengutronix.de>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-3-piyush.mehta@xilinx.com>
 <5e44ee87-f727-99fd-9860-d3d58a035dc4@pengutronix.de>
Message-ID: <50e468b1-9a32-0017-bd6a-8d47c3fa1a9c@xilinx.com>

Hi Ahmad,

On 8/18/21 11:00 AM, Ahmad Fatoum wrote:
> On 18.08.21 10:10, Piyush Mehta wrote:
>> This patch adds DT binding document for zynqmp modepin GPIO controller.
>> Modepin GPIO controller has four GPIO pins which can be configurable
>> as input or output.
>>
>> Modepin driver is a bridge between the peripheral driver and GPIO pins.
>> It has set and get APIs for accessing GPIO pins, based on the device-tree
>> entry of reset-gpio property in the peripheral driver, every pin can be
>> configured as input/output and trigger GPIO pin.
>>
>> For more information please refer zynqMp TRM link:
>> Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
>> Chapter 2: Signals, Interfaces, and Pins
>> Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE
>>
>> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
>> Acked-by: Michal Simek <michal.simek at xilinx.com>
>> ---
>> Changes in v2:
>> - Addressed review comments: Update commit message
>>
>> Review Comments:
>> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
>> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736
>>
>> Changes in v3:
>> - Addressed Rob and Michal review comments:
>>   - Update DT example. 
>>
>> Review Comments:
>> https://lore.kernel.org/linux-arm-kernel/YRbBnRS0VosXcZWz at robh.at.kernel.org/
>> https://lore.kernel.org/linux-arm-kernel/d71ad7f9-6972-8cc0-6dfb-b5306c9900d0 at xilinx.com/
>> ---
>>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
>>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 43 ++++++++++++++++++++++
>>  1 file changed, 43 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>> new file mode 100644
>> index 0000000..1442815
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>> @@ -0,0 +1,43 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: "http://devicetree.org/schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml#"
>> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
>> +
>> +title: ZynqMP Mode Pin GPIO controller
>> +
>> +description:
>> +  PS_MODE is 4-bits boot mode pins sampled on POR deassertion. Mode Pin
>> +  GPIO controller with configurable from numbers of pins (from 0 to 3 per
>> +  PS_MODE). Every pin can be configured as input/output.
> So, at Linux runtime, someone decides to boot the system into e.g. a USB
> recovery mode and then toggles the appropriate GPIOs and does a system
> reset?
> 
> If so, are you aware of the reboot mode[1] infrastructure?
> 
> A reboot-mode-gpio driver on top of this GPIO controller would allow you
> to describe the supported reboot modes in the device tree and instead of
> exporting GPIOs to userspace, users can then just do
> 
> 	systemctl restart recovery
> 
> to toggle the appropriate bits.
> 
> Also to be sure: PS_MODE are actual GPIO pins that you could toggle
> board level components with, right? i.e. it's not just a register that
> overrides the values read from the boot mode pins? (In the latter case
> a syscon-reboot-mode without GPIO controller would be the correct
> abstraction).
> 
> [1]: drivers/power/reset/reboot-mode.c

Thanks for these links. I wasn't aware about it.
But this device/IP is not working like this. Changing gpios to certain
state won't ensure that on reboot/reset (done in whatever way) won't
stay on values you chose.

modepin gpio driver is at BOOT_PIN_CTRL 	0xFF5E0250

(To be fair if you add additional external chip it could work like this
but I have never seen it).


But when you bring this up. Xilinx ZynqMP is providing a way how to
setup alternative boot mode which is done via
BOOT_MODE_USER 	0xFF5E0200
Bit 8 and 15-12.
Then you can setup any bootmode.

ZynqMP supports couple of modes listed here
https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/mach-zynqmp/include/mach/hardware.h#L73

but again routing to this register needs to be done via firmware
interface but it should be done via separate driver.
Is there an option to setup whatever modes you like?

I mean to simply cover all modes like this?

mode-jtag = <0>;
mode-sd = <3>;
mode-sd1 = <5>;
etc

And then users/customers can say what normal/recovery/test modes are.

Thanks,
Michal


From haibo.chen at nxp.com  Wed Aug 18 02:17:57 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 17:17:57 +0800
Subject: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: add a new compatible string
Message-ID: <1629278277-7313-1-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Lack a compatible string "fsl,imx6sll-usdhc", so add it here.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
index 8a9f1775b0e2..1457eb21473e 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
@@ -29,6 +29,7 @@ properties:
           - fsl,imx53-esdhc
           - fsl,imx6q-usdhc
           - fsl,imx6sl-usdhc
+          - fsl,imx6sll-usdhc
           - fsl,imx6sx-usdhc
           - fsl,imx6ull-usdhc
           - fsl,imx7d-usdhc
-- 
2.17.1



From a.fatoum at pengutronix.de  Wed Aug 18 02:55:01 2021
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Wed, 18 Aug 2021 11:55:01 +0200
Subject: [PATCH V3 2/3] dt-bindings: gpio: zynqmp: Add binding
 documentation for modepin
In-Reply-To: <50e468b1-9a32-0017-bd6a-8d47c3fa1a9c@xilinx.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-3-piyush.mehta@xilinx.com>
 <5e44ee87-f727-99fd-9860-d3d58a035dc4@pengutronix.de>
 <50e468b1-9a32-0017-bd6a-8d47c3fa1a9c@xilinx.com>
Message-ID: <4a724736-8bb9-a21d-974c-d9598c3d7b37@pengutronix.de>

On 18.08.21 11:38, Michal Simek wrote:
> Hi Ahmad,
> 
> On 8/18/21 11:00 AM, Ahmad Fatoum wrote:
>> On 18.08.21 10:10, Piyush Mehta wrote:
>>> This patch adds DT binding document for zynqmp modepin GPIO controller.
>>> Modepin GPIO controller has four GPIO pins which can be configurable
>>> as input or output.
>>>
>>> Modepin driver is a bridge between the peripheral driver and GPIO pins.
>>> It has set and get APIs for accessing GPIO pins, based on the device-tree
>>> entry of reset-gpio property in the peripheral driver, every pin can be
>>> configured as input/output and trigger GPIO pin.
>>>
>>> For more information please refer zynqMp TRM link:
>>> Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
>>> Chapter 2: Signals, Interfaces, and Pins
>>> Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE
>>>
>>> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
>>> Acked-by: Michal Simek <michal.simek at xilinx.com>
>>> ---
>>> Changes in v2:
>>> - Addressed review comments: Update commit message
>>>
>>> Review Comments:
>>> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
>>> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736
>>>
>>> Changes in v3:
>>> - Addressed Rob and Michal review comments:
>>>   - Update DT example. 
>>>
>>> Review Comments:
>>> https://lore.kernel.org/linux-arm-kernel/YRbBnRS0VosXcZWz at robh.at.kernel.org/
>>> https://lore.kernel.org/linux-arm-kernel/d71ad7f9-6972-8cc0-6dfb-b5306c9900d0 at xilinx.com/
>>> ---
>>>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
>>>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 43 ++++++++++++++++++++++
>>>  1 file changed, 43 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>>> new file mode 100644
>>> index 0000000..1442815
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>>> @@ -0,0 +1,43 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: "http://devicetree.org/schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml#"
>>> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
>>> +
>>> +title: ZynqMP Mode Pin GPIO controller
>>> +
>>> +description:
>>> +  PS_MODE is 4-bits boot mode pins sampled on POR deassertion. Mode Pin
>>> +  GPIO controller with configurable from numbers of pins (from 0 to 3 per
>>> +  PS_MODE). Every pin can be configured as input/output.
>> So, at Linux runtime, someone decides to boot the system into e.g. a USB
>> recovery mode and then toggles the appropriate GPIOs and does a system
>> reset?
>>
>> If so, are you aware of the reboot mode[1] infrastructure?
>>
>> A reboot-mode-gpio driver on top of this GPIO controller would allow you
>> to describe the supported reboot modes in the device tree and instead of
>> exporting GPIOs to userspace, users can then just do
>>
>> 	systemctl restart recovery
>>
>> to toggle the appropriate bits.
>>
>> Also to be sure: PS_MODE are actual GPIO pins that you could toggle
>> board level components with, right? i.e. it's not just a register that
>> overrides the values read from the boot mode pins? (In the latter case
>> a syscon-reboot-mode without GPIO controller would be the correct
>> abstraction).
>>
>> [1]: drivers/power/reset/reboot-mode.c
> 
> Thanks for these links. I wasn't aware about it.
> But this device/IP is not working like this. Changing gpios to certain
> state won't ensure that on reboot/reset (done in whatever way) won't
> stay on values you chose.

Ah, the "PS_MODE is 4-bits boot mode pins sampled on POR deassertion" part
misled me. These pins are sampled on startup, but can afterwards be reused 
via talking to firmware. Thanks for clearing this up.
> modepin gpio driver is at BOOT_PIN_CTRL 	0xFF5E0250
> 
> (To be fair if you add additional external chip it could work like this
> but I have never seen it).

Ye, that would've been strange, that's why I asked. :)

> But when you bring this up. Xilinx ZynqMP is providing a way how to
> setup alternative boot mode which is done via
> BOOT_MODE_USER 	0xFF5E0200
> Bit 8 and 15-12.
> Then you can setup any bootmode.
> 
> ZynqMP supports couple of modes listed here
> https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/mach-zynqmp/include/mach/hardware.h#L73
> 
> but again routing to this register needs to be done via firmware
> interface but it should be done via separate driver.

Yes.

> Is there an option to setup whatever modes you like?
> 
> I mean to simply cover all modes like this?
> 
> mode-jtag = <0>;
> mode-sd = <3>;
> mode-sd1 = <5>;

Yes, you can define the supported modes in the SoC dtsi
and boards inherit that and can extend it as necessary.

> And then users/customers can say what normal/recovery/test modes are.

Yes, that would be nice. But after your clarification, I see that it's
unrelated to this patch series. Binding is fine. Question on driver
is still applicable.

Cheers,
Ahmad

> 
> Thanks,
> Michal
> 


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From maxime at cerno.tech  Wed Aug 18 03:00:21 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 12:00:21 +0200
Subject: [PATCH 05/54] dt-bindings: Convert Reserved Memory binding to a
 schema
In-Reply-To: <CAL_JsqKAZLBK2UDDUNrO4aaYr886oODB_N_yF70X44gPXs=k5Q@mail.gmail.com>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-6-maxime@cerno.tech>
 <CAL_JsqKAZLBK2UDDUNrO4aaYr886oODB_N_yF70X44gPXs=k5Q@mail.gmail.com>
Message-ID: <20210818100021.yzzcuadkowy4tfv4@gilmour>

Hi Rob,

On Wed, Jul 21, 2021 at 08:30:43AM -0600, Rob Herring wrote:
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/reserved-memory/reserved-memory.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: /reserved-memory Node
> > +
> > +maintainers:
> > +  - Devicetree Specification Mailing List <devicetree-spec at vger.kernel.org>
> > +
> > +description: >
> > +  Reserved memory is specified as a node under the /reserved-memory node. The
> > +  operating system shall exclude reserved memory from normal usage one can
> > +  create child nodes describing particular reserved (excluded from normal use)
> > +  memory regions. Such memory regions are usually designed for the special
> > +  usage by various device drivers.
> > +
> > +properties:
> > +  $nodename:
> > +    const: reserved-memory
> > +
> > +  "#address-cells": true
> > +  "#size-cells": true
> > +  ranges: true
> > +
> > +patternProperties:
> > +  "^(?!(ranges))[a-z,-]*(@[0-9]+)?$":
> 
> Note that you could drop this and put under 'additionalProperties'.
> You would lose some node name checking, but there's really little
> standard on these nodes.

I didn't realise it could be used that way too, I'll change it.

> > +    type: object
> > +
> > +    description: >
> > +      Each child of the reserved-memory node specifies one or more regions of
> > +      reserved memory. Each child node may either use a 'reg' property to
> > +      specify a specific range of reserved memory, or a 'size' property with
> > +      optional constraints to request a dynamically allocated block of memory.
> > +
> > +      Following the generic-names recommended practice, node names should
> > +      reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
> > +      address (@<address>) should be appended to the name if the node is a
> > +      static allocation.
> > +
> > +    properties:
> > +      reg: true
> > +
> > +      size:
> > +        $ref: /schemas/types.yaml#/definitions/uint32-array
> > +        description: >
> > +          Length based on parent's \#size-cells. Size in bytes of memory to
> > +          reserve.
> > +
> > +      alignment:
> > +        $ref: /schemas/types.yaml#/definitions/uint32-array
> > +        description: >
> > +          Length based on parent's \#size-cells. Address boundary for
> > +          alignment of allocation.
> > +
> > +      alloc-ranges:
> > +        $ref: /schemas/types.yaml#/definitions/uint32-array
> > +        description: >
> > +          Address and Length pairs. Specifies regions of memory that are
> > +          acceptable to allocate from.
> > +
> > +      compatible:
> > +        oneOf:
> > +          - const: shared-dma-pool
> > +            description: >
> > +              This indicates a region of memory meant to be used as a shared
> > +              pool of DMA buffers for a set of devices. It can be used by an
> > +              operating system to instantiate the necessary pool management
> > +              subsystem if necessary.
> > +
> > +          # Vendor-specific compatibles in the form <vendor>,[<device>-]<usage>
> > +          - const: mediatek,trustzone-bootinfo
> 
> I think these should be separate schema files. At least, we're going
> to need to support separate files because I don't think we want ones
> adding custom properties here. This would fail unless we add every
> compatible here. We could also be a bit more exact as to which
> properties below apply (e.g. linux,.*-default is only valid for
> shared-dma-pool).

I'm not entirely sure how we can just ignore the vendor compatibles
without raising a warning. Do you have any suggestion?

Thanks!
Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/56cab1b7/attachment-0001.sig>

From michal.simek at xilinx.com  Wed Aug 18 03:01:19 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Wed, 18 Aug 2021 12:01:19 +0200
Subject: [PATCH V3 2/3] dt-bindings: gpio: zynqmp: Add binding
 documentation for modepin
In-Reply-To: <4a724736-8bb9-a21d-974c-d9598c3d7b37@pengutronix.de>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-3-piyush.mehta@xilinx.com>
 <5e44ee87-f727-99fd-9860-d3d58a035dc4@pengutronix.de>
 <50e468b1-9a32-0017-bd6a-8d47c3fa1a9c@xilinx.com>
 <4a724736-8bb9-a21d-974c-d9598c3d7b37@pengutronix.de>
Message-ID: <c53d7b06-e619-45c5-8b93-d1688792f270@xilinx.com>



On 8/18/21 11:55 AM, Ahmad Fatoum wrote:
> On 18.08.21 11:38, Michal Simek wrote:
>> Hi Ahmad,
>>
>> On 8/18/21 11:00 AM, Ahmad Fatoum wrote:
>>> On 18.08.21 10:10, Piyush Mehta wrote:
>>>> This patch adds DT binding document for zynqmp modepin GPIO controller.
>>>> Modepin GPIO controller has four GPIO pins which can be configurable
>>>> as input or output.
>>>>
>>>> Modepin driver is a bridge between the peripheral driver and GPIO pins.
>>>> It has set and get APIs for accessing GPIO pins, based on the device-tree
>>>> entry of reset-gpio property in the peripheral driver, every pin can be
>>>> configured as input/output and trigger GPIO pin.
>>>>
>>>> For more information please refer zynqMp TRM link:
>>>> Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
>>>> Chapter 2: Signals, Interfaces, and Pins
>>>> Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE
>>>>
>>>> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
>>>> Acked-by: Michal Simek <michal.simek at xilinx.com>
>>>> ---
>>>> Changes in v2:
>>>> - Addressed review comments: Update commit message
>>>>
>>>> Review Comments:
>>>> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
>>>> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736
>>>>
>>>> Changes in v3:
>>>> - Addressed Rob and Michal review comments:
>>>>   - Update DT example. 
>>>>
>>>> Review Comments:
>>>> https://lore.kernel.org/linux-arm-kernel/YRbBnRS0VosXcZWz at robh.at.kernel.org/
>>>> https://lore.kernel.org/linux-arm-kernel/d71ad7f9-6972-8cc0-6dfb-b5306c9900d0 at xilinx.com/
>>>> ---
>>>>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
>>>>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 43 ++++++++++++++++++++++
>>>>  1 file changed, 43 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>>>> new file mode 100644
>>>> index 0000000..1442815
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
>>>> @@ -0,0 +1,43 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: "http://devicetree.org/schemas/gpio/xlnx,zynqmp-gpio-modepin.yaml#"
>>>> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
>>>> +
>>>> +title: ZynqMP Mode Pin GPIO controller
>>>> +
>>>> +description:
>>>> +  PS_MODE is 4-bits boot mode pins sampled on POR deassertion. Mode Pin
>>>> +  GPIO controller with configurable from numbers of pins (from 0 to 3 per
>>>> +  PS_MODE). Every pin can be configured as input/output.
>>> So, at Linux runtime, someone decides to boot the system into e.g. a USB
>>> recovery mode and then toggles the appropriate GPIOs and does a system
>>> reset?
>>>
>>> If so, are you aware of the reboot mode[1] infrastructure?
>>>
>>> A reboot-mode-gpio driver on top of this GPIO controller would allow you
>>> to describe the supported reboot modes in the device tree and instead of
>>> exporting GPIOs to userspace, users can then just do
>>>
>>> 	systemctl restart recovery
>>>
>>> to toggle the appropriate bits.
>>>
>>> Also to be sure: PS_MODE are actual GPIO pins that you could toggle
>>> board level components with, right? i.e. it's not just a register that
>>> overrides the values read from the boot mode pins? (In the latter case
>>> a syscon-reboot-mode without GPIO controller would be the correct
>>> abstraction).
>>>
>>> [1]: drivers/power/reset/reboot-mode.c
>>
>> Thanks for these links. I wasn't aware about it.
>> But this device/IP is not working like this. Changing gpios to certain
>> state won't ensure that on reboot/reset (done in whatever way) won't
>> stay on values you chose.
> 
> Ah, the "PS_MODE is 4-bits boot mode pins sampled on POR deassertion" part
> misled me. These pins are sampled on startup, but can afterwards be reused 
> via talking to firmware. Thanks for clearing this up.

yes

>> modepin gpio driver is at BOOT_PIN_CTRL 	0xFF5E0250
>>
>> (To be fair if you add additional external chip it could work like this
>> but I have never seen it).
> 
> Ye, that would've been strange, that's why I asked. :)

No issue at all.

> 
>> But when you bring this up. Xilinx ZynqMP is providing a way how to
>> setup alternative boot mode which is done via
>> BOOT_MODE_USER 	0xFF5E0200
>> Bit 8 and 15-12.
>> Then you can setup any bootmode.
>>
>> ZynqMP supports couple of modes listed here
>> https://source.denx.de/u-boot/u-boot/-/blob/master/arch/arm/mach-zynqmp/include/mach/hardware.h#L73
>>
>> but again routing to this register needs to be done via firmware
>> interface but it should be done via separate driver.
> 
> Yes.
> 
>> Is there an option to setup whatever modes you like?
>>
>> I mean to simply cover all modes like this?
>>
>> mode-jtag = <0>;
>> mode-sd = <3>;
>> mode-sd1 = <5>;
> 
> Yes, you can define the supported modes in the SoC dtsi
> and boards inherit that and can extend it as necessary.

ok.

> 
>> And then users/customers can say what normal/recovery/test modes are.
> 
> Yes, that would be nice. But after your clarification, I see that it's
> unrelated to this patch series. Binding is fine. Question on driver
> is still applicable.

I remember any discussion about it between Piyush and Linus and I will
let Piyush to handle it.

Thanks,
Michal


From haibo.chen at nxp.com  Wed Aug 18 02:46:24 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 17:46:24 +0800
Subject: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: change the pinctrl-names rule
Message-ID: <1629279984-7397-1-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Change the pinctrl-names rule to cover all cases.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 .../bindings/mmc/fsl-imx-esdhc.yaml           | 21 +++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
index 17086f60f8a3..d324606a4f0a 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
@@ -116,12 +116,21 @@ properties:
       - const: per
 
   pinctrl-names:
-    minItems: 1
-    items:
-      - const: default
-      - const: state_100mhz
-      - const: state_200mhz
-      - const: sleep
+    oneOf:
+      - items:
+          - const: default
+          - const: state_100mhz
+          - const: state_200mhz
+          - const: sleep
+      - items:
+          - const: default
+          - const: state_100mhz
+          - const: state_200mhz
+      - items:
+          - const: default
+          - const: sleep
+      - items:
+          - const: default
 
 required:
   - compatible
-- 
2.17.1



From piyushm at xilinx.com  Wed Aug 18 03:09:17 2021
From: piyushm at xilinx.com (Piyush Mehta)
Date: Wed, 18 Aug 2021 10:09:17 +0000
Subject: [PATCH V3 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <b3d718af-6eb7-a212-f599-d0d91273afdc@pengutronix.de>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-4-piyush.mehta@xilinx.com>
 <b3d718af-6eb7-a212-f599-d0d91273afdc@pengutronix.de>
Message-ID: <SJ0PR02MB86443029095BF5949E51808AD4FF9@SJ0PR02MB8644.namprd02.prod.outlook.com>

Hi Ahmad,

-----Original Message-----
From: Ahmad Fatoum <a.fatoum at pengutronix.de> 
Sent: Wednesday, August 18, 2021 2:22 PM
To: Piyush Mehta <piyushm at xilinx.com>; arnd at arndb.de; zou_wei at huawei.com; gregkh at linuxfoundation.org; linus.walleij at linaro.org; Michal Simek <michals at xilinx.com>; Jiaying Liang <jliang at xilinx.com>; iwamatsu at nigauri.org; bgolaszewski at baylibre.com; robh+dt at kernel.org; Rajan Vaja <RAJANV at xilinx.com>
Cc: linux-gpio at vger.kernel.org; devicetree at vger.kernel.org; git <git at xilinx.com>; Srinivas Goud <sgoud at xilinx.com>; linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Pengutronix Kernel Team <kernel at pengutronix.de>
Subject: Re: [PATCH V3 3/3] gpio: modepin: Add driver support for modepin GPIO controller

On 18.08.21 10:10, Piyush Mehta wrote:
> This patch adds driver support for the zynqmp modepin GPIO controller.
> GPIO modepin driver set and get the value and status of the PS_MODE 
> pin, based on device-tree pin configuration. These four mode pins are 
> configurable as input/output. The mode pin has a control register, 
> which have lower four-bits [0:3] are configurable as input/output, 
> next four-bits can be used for reading the data  as input[4:7], and 
> next setting the output pin state output[8:11].
> 
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> Acked-by: Michal Simek <michal.simek at xilinx.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> ---

> +/**
> + * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input
> + * @chip:	gpio_chip instance to be worked on
> + * @pin:	gpio pin number within the device
> + *
> + * Return: 0 always
> + */
> +static int modepin_gpio_dir_in(struct gpio_chip *chip, unsigned int 
> +pin) {
> +	return 0;
> +}

You say the gpio controller can configure pins as inputs or outputs.
These pins are controller via firmware driver. We are updating BOOT_PIN_CTRL 	0xFF5E0250 register.
[0:3]  = When 0, the pins will be inputs from the board to the PS. When 1, the PS will drive these pins
[4:7] = Value captured from the mode pins
[8:11] = Value driven onto the mode pins, when control register bit set out = 1

The lower four-bits [0:3] we can set either input and output, based on configuration we read pin as for input [4:7]
and write on pin [8:11].
Example:
If we want to configure pin 1 as output, then we will configure as [0:3]=[0100], for access pin will trigger upper bit [8:11]=[0100].

Based on
https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf

page 46

PS_MODE Input/Output Dedicated 4-bit boot mode pins sampled on POR deassertion

Xilinx is using this pin for usb phy resets.

Yet, .direction_input is doing nothing. So, it's not clear to me, how this sequence could work:

 - set gpio output high (writes bootmode)
 - set gpio to input (no-op, pin will remain high, not high impedance)






I didn't check the previous discussions, but if this indeed works as intended, the how should be written here into the driver. That is a more useful comment than kernel doc for a stub function.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

Regards,
Piyush Mehta

From vkoul at kernel.org  Wed Aug 18 03:14:22 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 18 Aug 2021 15:44:22 +0530
Subject: [PATCH] phy: xilinx: zynqmp: skip PHY initialization and PLL
 lock for USB
In-Reply-To: <20210818084311.2643986-1-piyush.mehta@xilinx.com>
References: <20210818084311.2643986-1-piyush.mehta@xilinx.com>
Message-ID: <YRzdfsnntGf9ebU/@matsya>

On 18-08-21, 14:13, Piyush Mehta wrote:
> PHY initialization for USB is required on linux boot or when
> gt lane is changed from the current one and it is applicable
> on PLL lock too.

Applied, thanks

-- 
~Vinod


From jens.wiklander at linaro.org  Wed Aug 18 03:18:43 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 18 Aug 2021 12:18:43 +0200
Subject: [PATCH v4 0/6] Asynchronous notifications from secure world
Message-ID: <20210818101849.602257-1-jens.wiklander@linaro.org>

Hi all,

This adds support for asynchronous notifications from OP-TEE in secure
world to the OP-TEE driver. This allows a design with a top half and bottom
half type of driver where the top half runs in secure interrupt context and
a notifications tells normal world to schedule a yielding call to do the
bottom half processing.

An edge-triggered interrupt is used to notify the driver that there are
asynchronous notifications pending.

v3->v4:
* Clarfied the expected type of interrypt is edge-triggered, both in
  the normal documentation and in the DT bindings as requested.

v2->v3:
* Rebased on v5.14-rc2 which made the patch "dt-bindings: arm: Convert
  optee binding to json-schema" from the V2 patch set obsolete.
* Applied Ard's Acked-by on "optee: add asynchronous notifications"

v1->v2:
* Added documentation
* Converted optee bindings to json-schema and added interrupt property
* Configure notification interrupt from DT instead of getting it
  from secure world, suggested by Ard Biesheuvel <ardb at kernel.org>.

Thanks,
Jens

Jens Wiklander (6):
  docs: staging/tee.rst: add a section on OP-TEE notifications
  dt-bindings: arm: optee: add interrupt property
  tee: fix put order in teedev_close_context()
  tee: add tee_dev_open_helper() primitive
  optee: separate notification functions
  optee: add asynchronous notifications

 .../arm/firmware/linaro,optee-tz.yaml         |   7 +
 Documentation/staging/tee.rst                 |  29 +++
 drivers/tee/optee/Makefile                    |   1 +
 drivers/tee/optee/call.c                      |  27 +++
 drivers/tee/optee/core.c                      |  87 +++++--
 drivers/tee/optee/notif.c                     | 226 ++++++++++++++++++
 drivers/tee/optee/optee_msg.h                 |   9 +
 drivers/tee/optee/optee_private.h             |  23 +-
 drivers/tee/optee/optee_rpc_cmd.h             |  31 +--
 drivers/tee/optee/optee_smc.h                 |  75 +++++-
 drivers/tee/optee/rpc.c                       |  73 +-----
 drivers/tee/tee_core.c                        |  37 ++-
 include/linux/tee_drv.h                       |  27 +++
 13 files changed, 528 insertions(+), 124 deletions(-)
 create mode 100644 drivers/tee/optee/notif.c

-- 
2.31.1



From jens.wiklander at linaro.org  Wed Aug 18 03:18:46 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 18 Aug 2021 12:18:46 +0200
Subject: [PATCH v4 3/6] tee: fix put order in teedev_close_context()
In-Reply-To: <20210818101849.602257-1-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
Message-ID: <20210818101849.602257-4-jens.wiklander@linaro.org>

Prior to this patch was teedev_close_context() calling tee_device_put()
before teedev_ctx_put() leading to teedev_ctx_release() accessing
ctx->teedev just after the reference counter was decreased on the
teedev. Fix this by calling teedev_ctx_put() before tee_device_put().

Fixes: 217e0250cccb ("tee: use reference counting for tee_context")
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/tee_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index 2b37bc408fc3..85102d12d716 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -98,8 +98,10 @@ void teedev_ctx_put(struct tee_context *ctx)
 
 static void teedev_close_context(struct tee_context *ctx)
 {
-	tee_device_put(ctx->teedev);
+	struct tee_device *teedev = ctx->teedev;
+
 	teedev_ctx_put(ctx);
+	tee_device_put(teedev);
 }
 
 static int tee_open(struct inode *inode, struct file *filp)
-- 
2.31.1



From jens.wiklander at linaro.org  Wed Aug 18 03:18:44 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 18 Aug 2021 12:18:44 +0200
Subject: [PATCH v4 1/6] docs: staging/tee.rst: add a section on OP-TEE
 notifications
In-Reply-To: <20210818101849.602257-1-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
Message-ID: <20210818101849.602257-2-jens.wiklander@linaro.org>

Adds a section on notifications used by OP-TEE, synchronous and
asynchronous.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 Documentation/staging/tee.rst | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/Documentation/staging/tee.rst b/Documentation/staging/tee.rst
index 4d4b5f889603..951f07dd026b 100644
--- a/Documentation/staging/tee.rst
+++ b/Documentation/staging/tee.rst
@@ -184,6 +184,35 @@ order to support device enumeration. In other words, OP-TEE driver invokes this
 application to retrieve a list of Trusted Applications which can be registered
 as devices on the TEE bus.
 
+OP-TEE notifications
+--------------------
+
+There are two kinds of notifications that secure world can use to make
+normal world aware of some event.
+
+1. Synchronous notifications delivered with ``OPTEE_RPC_CMD_NOTIFICATION``
+   using the ``OPTEE_RPC_NOTIFICATION_SEND`` parameter.
+2. Asynchronous notifications delivered with a combination of a non-secure
+   edge-triggered interrupt and a fast call from the non-secure interrupt
+   handler.
+
+Synchronous notifications are limited by depending on RPC for delivery,
+this is only usable when secure world is entered with a yielding call via
+``OPTEE_SMC_CALL_WITH_ARG``. This excludes such notifications from secure
+world interrupt handlers.
+
+An asynchronous notification is delivered via a non-secure edge-triggered
+interrupt to an interrupt handler registered in the OP-TEE driver. The
+actual notification value are retrieved with the fast call
+``OPTEE_SMC_GET_ASYNC_NOTIF_VALUE``.
+
+One notification value ``OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF`` has a
+special meaning. When this value is received it means that normal world is
+supposed to make a yielding call ``OPTEE_MSG_CMD_DO_BOTTOM_HALF``. This
+call is done from the thread assisting the interrupt handler. This is a
+building block for OP-TEE OS in secure world to implement the top half and
+bottom half style of device drivers.
+
 AMD-TEE driver
 ==============
 
-- 
2.31.1



From jens.wiklander at linaro.org  Wed Aug 18 03:18:47 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 18 Aug 2021 12:18:47 +0200
Subject: [PATCH v4 4/6] tee: add tee_dev_open_helper() primitive
In-Reply-To: <20210818101849.602257-1-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
Message-ID: <20210818101849.602257-5-jens.wiklander@linaro.org>

Adds tee_dev_open_helper() and tee_dev_ctx_put() to make it easier to
create a driver internal struct tee_context without the usual
tee_device_get() on the struct tee_device as that adds a circular
reference counter dependency and would prevent the struct tee_device
from ever being released again.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/tee_core.c  | 33 ++++++++++++++++++++++++---------
 include/linux/tee_drv.h | 27 +++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index 85102d12d716..3beb682684a8 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -43,14 +43,11 @@ static DEFINE_SPINLOCK(driver_lock);
 static struct class *tee_class;
 static dev_t tee_devt;
 
-static struct tee_context *teedev_open(struct tee_device *teedev)
+struct tee_context *tee_dev_open_helper(struct tee_device *teedev)
 {
 	int rc;
 	struct tee_context *ctx;
 
-	if (!tee_device_get(teedev))
-		return ERR_PTR(-EINVAL);
-
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx) {
 		rc = -ENOMEM;
@@ -66,10 +63,30 @@ static struct tee_context *teedev_open(struct tee_device *teedev)
 	return ctx;
 err:
 	kfree(ctx);
-	tee_device_put(teedev);
 	return ERR_PTR(rc);
 
 }
+EXPORT_SYMBOL_GPL(tee_dev_open_helper);
+
+void tee_dev_ctx_put(struct tee_context *ctx)
+{
+	teedev_ctx_put(ctx);
+}
+EXPORT_SYMBOL_GPL(tee_dev_ctx_put);
+
+static struct tee_context *teedev_open(struct tee_device *teedev)
+{
+	struct tee_context *ctx;
+
+	if (!tee_device_get(teedev))
+		return ERR_PTR(-EINVAL);
+
+	ctx = tee_dev_open_helper(teedev);
+	if (IS_ERR(ctx))
+		tee_device_put(teedev);
+
+	return ctx;
+}
 
 void teedev_ctx_get(struct tee_context *ctx)
 {
@@ -90,10 +107,8 @@ static void teedev_ctx_release(struct kref *ref)
 
 void teedev_ctx_put(struct tee_context *ctx)
 {
-	if (ctx->releasing)
-		return;
-
-	kref_put(&ctx->refcount, teedev_ctx_release);
+	if (ctx && !ctx->releasing)
+		kref_put(&ctx->refcount, teedev_ctx_release);
 }
 
 static void teedev_close_context(struct tee_context *ctx)
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index 54269e47ac9a..f592ba4e9561 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -456,6 +456,33 @@ static inline int tee_shm_get_id(struct tee_shm *shm)
  */
 struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
 
+/**
+ * tee_dev_open_helper() - helper function to make a struct tee_context
+ * @teedev:	Device to open
+ *
+ * Creates the struct tee_context without increasing the reference counter
+ * on @teedev. This is needed for instance when a driver need an internal
+ * struct tee_context to operate on. By skipping the reference counter
+ * the circular dependency is broken.
+ *
+ * Note that this struct tee_context need special care when freeing in
+ * order to avoid the normal put on the struct tee_device.
+ * tee_dev_ctx_put() is the best choice for this.
+ *
+ * @returns a pointer 'struct tee_context' on success or an ERR_PTR on failure
+ */
+struct tee_context *tee_dev_open_helper(struct tee_device *teedev);
+
+/**
+ * tee_dev_ctx_put() - helper function to release a struct tee_context
+ * @ctx:	The struct tee_context to release
+ *
+ * Note that this function doesn't do a tee_device_put() on the internal
+ * struct tee_device so this function should normal only be used when
+ * releasing a struct tee_context obtained with tee_dev_open_helper().
+ */
+void tee_dev_ctx_put(struct tee_context *ctx);
+
 /**
  * tee_client_open_context() - Open a TEE context
  * @start:	if not NULL, continue search after this context
-- 
2.31.1



From jens.wiklander at linaro.org  Wed Aug 18 03:18:45 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 18 Aug 2021 12:18:45 +0200
Subject: [PATCH v4 2/6] dt-bindings: arm: optee: add interrupt property
In-Reply-To: <20210818101849.602257-1-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
Message-ID: <20210818101849.602257-3-jens.wiklander@linaro.org>

Adds an optional interrupt property to the optee binding.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 .../devicetree/bindings/arm/firmware/linaro,optee-tz.yaml  | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
index c24047c1fdd5..40c9f1901e3f 100644
--- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
+++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
@@ -24,6 +24,12 @@ properties:
   compatible:
     const: linaro,optee-tz
 
+  interrupts:
+    maxItems: 1
+    description: |
+      This interrupt which is used to signal an event by the secure world
+      software is expected to be edge-triggered.
+
   method:
     enum: [smc, hvc]
     description: |
@@ -46,6 +52,7 @@ examples:
         optee  {
             compatible = "linaro,optee-tz";
             method = "smc";
+            interrupts = <0 187 1>;
         };
     };
 
-- 
2.31.1



From jens.wiklander at linaro.org  Wed Aug 18 03:18:48 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 18 Aug 2021 12:18:48 +0200
Subject: [PATCH v4 5/6] optee: separate notification functions
In-Reply-To: <20210818101849.602257-1-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
Message-ID: <20210818101849.602257-6-jens.wiklander@linaro.org>

Renames struct optee_wait_queue to struct optee_notif and all related
functions to optee_notif_*().

The implementation is changed to allow sending a notification from an
atomic state, that is from the top half of an interrupt handler.

Waiting for keys is currently only used when secure world is waiting for
a mutex or condition variable. The old implementation could handle any
32-bit key while this new implementation is restricted to only 8 bits or
the maximum value 255. A upper value is needed since a bitmap is
allocated to allow an interrupt handler to only set a bit in case the
waiter hasn't had the time yet to allocate and register a completion.

The keys are currently only representing secure world threads which
number usually are never even close to 255 so it should be safe for now.
In future ABI updates the maximum value of the key will be communicated
while the driver is initializing.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/Makefile        |   1 +
 drivers/tee/optee/core.c          |  13 +++-
 drivers/tee/optee/notif.c         | 125 ++++++++++++++++++++++++++++++
 drivers/tee/optee/optee_private.h |  19 +++--
 drivers/tee/optee/optee_rpc_cmd.h |  31 ++++----
 drivers/tee/optee/rpc.c           |  73 ++---------------
 6 files changed, 171 insertions(+), 91 deletions(-)
 create mode 100644 drivers/tee/optee/notif.c

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 3aa33ea9e6a6..df55e4ad5370 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_OPTEE) += optee.o
 optee-objs += core.o
 optee-objs += call.o
+optee-objs += notif.o
 optee-objs += rpc.o
 optee-objs += supp.o
 optee-objs += shm_pool.o
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index ddb8f9ecf307..2272696ac986 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -583,6 +583,7 @@ static int optee_remove(struct platform_device *pdev)
 	 */
 	optee_disable_shm_cache(optee);
 
+	optee_notif_uninit(optee);
 	/*
 	 * The two devices have to be unregistered before we can free the
 	 * other resources.
@@ -593,7 +594,6 @@ static int optee_remove(struct platform_device *pdev)
 	tee_shm_pool_free(optee->pool);
 	if (optee->memremaped_shm)
 		memunmap(optee->memremaped_shm);
-	optee_wait_queue_exit(&optee->wait_queue);
 	optee_supp_uninit(&optee->supp);
 	mutex_destroy(&optee->call_queue.mutex);
 
@@ -681,18 +681,23 @@ static int optee_probe(struct platform_device *pdev)
 
 	mutex_init(&optee->call_queue.mutex);
 	INIT_LIST_HEAD(&optee->call_queue.waiters);
-	optee_wait_queue_init(&optee->wait_queue);
 	optee_supp_init(&optee->supp);
 	optee->memremaped_shm = memremaped_shm;
 	optee->pool = pool;
 
+	platform_set_drvdata(pdev, optee);
+
+	rc = optee_notif_init(optee, 255);
+	if (rc) {
+		optee_remove(pdev);
+		return rc;
+	}
+
 	optee_enable_shm_cache(optee);
 
 	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
 		pr_info("dynamic shared memory is enabled\n");
 
-	platform_set_drvdata(pdev, optee);
-
 	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
 	if (rc) {
 		optee_remove(pdev);
diff --git a/drivers/tee/optee/notif.c b/drivers/tee/optee/notif.c
new file mode 100644
index 000000000000..a28fa03dcd0e
--- /dev/null
+++ b/drivers/tee/optee/notif.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015-2021, Linaro Limited
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/arm-smccc.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/tee_drv.h>
+#include "optee_private.h"
+
+struct notif_entry {
+	struct list_head link;
+	struct completion c;
+	u_int key;
+};
+
+static bool have_key(struct optee *optee, u_int key)
+{
+	struct notif_entry *entry;
+
+	list_for_each_entry(entry, &optee->notif.db, link)
+		if (entry->key == key)
+			return true;
+
+	return false;
+}
+
+int optee_notif_wait(struct optee *optee, u_int key)
+{
+	unsigned long flags;
+	struct notif_entry *entry;
+	int rc = 0;
+
+	if (key > optee->notif.max_key)
+		return -EINVAL;
+
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+	init_completion(&entry->c);
+	entry->key = key;
+
+	spin_lock_irqsave(&optee->notif.lock, flags);
+
+	/*
+	 * If the bit is already set it means that the key has already
+	 * been posted and we must not wait.
+	 */
+	if (test_bit(key, optee->notif.bitmap)) {
+		clear_bit(key, optee->notif.bitmap);
+		goto out;
+	}
+
+	/*
+	 * Check if someone is already waiting for this key. If there is
+	 * it's a programming error.
+	 */
+	if (have_key(optee, key)) {
+		rc = -EBUSY;
+		goto out;
+	}
+
+	list_add_tail(&entry->link, &optee->notif.db);
+
+	/*
+	 * Unlock temporarily and wait for completion.
+	 */
+	spin_unlock_irqrestore(&optee->notif.lock, flags);
+	wait_for_completion(&entry->c);
+	spin_lock_irqsave(&optee->notif.lock, flags);
+
+	list_del(&entry->link);
+out:
+	spin_unlock_irqrestore(&optee->notif.lock, flags);
+
+	kfree(entry);
+
+	return rc;
+}
+
+int optee_notif_send(struct optee *optee, u_int key)
+{
+	unsigned long flags;
+	struct notif_entry *entry;
+
+	if (key > optee->notif.max_key)
+		return -EINVAL;
+
+	spin_lock_irqsave(&optee->notif.lock, flags);
+
+	list_for_each_entry(entry, &optee->notif.db, link)
+		if (entry->key == key) {
+			complete(&entry->c);
+			goto out;
+		}
+
+	/* Only set the bit in case there where nobody waiting */
+	set_bit(key, optee->notif.bitmap);
+out:
+	spin_unlock_irqrestore(&optee->notif.lock, flags);
+
+	return 0;
+}
+
+int optee_notif_init(struct optee *optee, u_int max_key)
+{
+	spin_lock_init(&optee->notif.lock);
+	INIT_LIST_HEAD(&optee->notif.db);
+	optee->notif.bitmap = bitmap_zalloc(max_key, GFP_KERNEL);
+	if (!optee->notif.bitmap)
+		return -ENOMEM;
+
+	optee->notif.max_key = max_key;
+
+	return 0;
+}
+
+void optee_notif_uninit(struct optee *optee)
+{
+	kfree(optee->notif.bitmap);
+}
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index e25b216a14ef..7dc058d008b2 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -35,10 +35,12 @@ struct optee_call_queue {
 	struct list_head waiters;
 };
 
-struct optee_wait_queue {
-	/* Serializes access to this struct */
-	struct mutex mu;
+struct optee_notif {
+	u_int max_key;
+	/* Serializes access to the elements below in this struct */
+	spinlock_t lock;
 	struct list_head db;
+	u_long *bitmap;
 };
 
 /**
@@ -72,8 +74,7 @@ struct optee_supp {
  * @teedev:		client device
  * @invoke_fn:		function to issue smc or hvc
  * @call_queue:		queue of threads waiting to call @invoke_fn
- * @wait_queue:		queue of threads from secure world waiting for a
- *			secure world sync object
+ * @notif:		notification synchronization struct
  * @supp:		supplicant synchronization struct for RPC to supplicant
  * @pool:		shared memory pool
  * @memremaped_shm	virtual address of memory in shared memory pool
@@ -88,7 +89,7 @@ struct optee {
 	struct tee_device *teedev;
 	optee_invoke_fn *invoke_fn;
 	struct optee_call_queue call_queue;
-	struct optee_wait_queue wait_queue;
+	struct optee_notif notif;
 	struct optee_supp supp;
 	struct tee_shm_pool *pool;
 	void *memremaped_shm;
@@ -131,8 +132,10 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
 		      struct optee_call_ctx *call_ctx);
 void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx);
 
-void optee_wait_queue_init(struct optee_wait_queue *wq);
-void optee_wait_queue_exit(struct optee_wait_queue *wq);
+int optee_notif_init(struct optee *optee, u_int max_key);
+void optee_notif_uninit(struct optee *optee);
+int optee_notif_wait(struct optee *optee, u_int key);
+int optee_notif_send(struct optee *optee, u_int key);
 
 u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
 			struct tee_param *param);
diff --git a/drivers/tee/optee/optee_rpc_cmd.h b/drivers/tee/optee/optee_rpc_cmd.h
index b8275140cef8..f3f06e0994a7 100644
--- a/drivers/tee/optee/optee_rpc_cmd.h
+++ b/drivers/tee/optee/optee_rpc_cmd.h
@@ -28,24 +28,27 @@
 #define OPTEE_RPC_CMD_GET_TIME		3
 
 /*
- * Wait queue primitive, helper for secure world to implement a wait queue.
+ * Notification from/to secure world.
  *
- * If secure world needs to wait for a secure world mutex it issues a sleep
- * request instead of spinning in secure world. Conversely is a wakeup
- * request issued when a secure world mutex with a thread waiting thread is
- * unlocked.
+ * If secure world needs to wait for something, for instance a mutex, it
+ * does a notification wait request instead of spinning in secure world.
+ * Conversely can a synchronous notification can be sent when a secure
+ * world mutex with a thread waiting thread is unlocked.
  *
- * Waiting on a key
- * [in]    value[0].a	    OPTEE_RPC_WAIT_QUEUE_SLEEP
- * [in]    value[0].b	    Wait key
+ * This interface can also be used to wait for a asynchronous notification
+ * which instead is sent via a non-secure interrupt.
  *
- * Waking up a key
- * [in]    value[0].a	    OPTEE_RPC_WAIT_QUEUE_WAKEUP
- * [in]    value[0].b	    Wakeup key
+ * Waiting on notification
+ * [in]    value[0].a	    OPTEE_RPC_NOTIFICATION_WAIT
+ * [in]    value[0].b	    notification value
+ *
+ * Sending a synchronous notification
+ * [in]    value[0].a	    OPTEE_RPC_NOTIFICATION_SEND
+ * [in]    value[0].b	    notification value
  */
-#define OPTEE_RPC_CMD_WAIT_QUEUE	4
-#define OPTEE_RPC_WAIT_QUEUE_SLEEP	0
-#define OPTEE_RPC_WAIT_QUEUE_WAKEUP	1
+#define OPTEE_RPC_CMD_NOTIFICATION	4
+#define OPTEE_RPC_NOTIFICATION_WAIT	0
+#define OPTEE_RPC_NOTIFICATION_SEND	1
 
 /*
  * Suspend execution
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index 1849180b0278..e5b931f50db2 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2016, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -14,23 +14,6 @@
 #include "optee_smc.h"
 #include "optee_rpc_cmd.h"
 
-struct wq_entry {
-	struct list_head link;
-	struct completion c;
-	u32 key;
-};
-
-void optee_wait_queue_init(struct optee_wait_queue *priv)
-{
-	mutex_init(&priv->mu);
-	INIT_LIST_HEAD(&priv->db);
-}
-
-void optee_wait_queue_exit(struct optee_wait_queue *priv)
-{
-	mutex_destroy(&priv->mu);
-}
-
 static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
 {
 	struct timespec64 ts;
@@ -143,48 +126,6 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 }
 #endif
 
-static struct wq_entry *wq_entry_get(struct optee_wait_queue *wq, u32 key)
-{
-	struct wq_entry *w;
-
-	mutex_lock(&wq->mu);
-
-	list_for_each_entry(w, &wq->db, link)
-		if (w->key == key)
-			goto out;
-
-	w = kmalloc(sizeof(*w), GFP_KERNEL);
-	if (w) {
-		init_completion(&w->c);
-		w->key = key;
-		list_add_tail(&w->link, &wq->db);
-	}
-out:
-	mutex_unlock(&wq->mu);
-	return w;
-}
-
-static void wq_sleep(struct optee_wait_queue *wq, u32 key)
-{
-	struct wq_entry *w = wq_entry_get(wq, key);
-
-	if (w) {
-		wait_for_completion(&w->c);
-		mutex_lock(&wq->mu);
-		list_del(&w->link);
-		mutex_unlock(&wq->mu);
-		kfree(w);
-	}
-}
-
-static void wq_wakeup(struct optee_wait_queue *wq, u32 key)
-{
-	struct wq_entry *w = wq_entry_get(wq, key);
-
-	if (w)
-		complete(&w->c);
-}
-
 static void handle_rpc_func_cmd_wq(struct optee *optee,
 				   struct optee_msg_arg *arg)
 {
@@ -196,11 +137,13 @@ static void handle_rpc_func_cmd_wq(struct optee *optee,
 		goto bad;
 
 	switch (arg->params[0].u.value.a) {
-	case OPTEE_RPC_WAIT_QUEUE_SLEEP:
-		wq_sleep(&optee->wait_queue, arg->params[0].u.value.b);
+	case OPTEE_RPC_NOTIFICATION_WAIT:
+		if (optee_notif_wait(optee, arg->params[0].u.value.b))
+			goto bad;
 		break;
-	case OPTEE_RPC_WAIT_QUEUE_WAKEUP:
-		wq_wakeup(&optee->wait_queue, arg->params[0].u.value.b);
+	case OPTEE_RPC_NOTIFICATION_SEND:
+		if (optee_notif_send(optee, arg->params[0].u.value.b))
+			goto bad;
 		break;
 	default:
 		goto bad;
@@ -463,7 +406,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
 	case OPTEE_RPC_CMD_GET_TIME:
 		handle_rpc_func_cmd_get_time(arg);
 		break;
-	case OPTEE_RPC_CMD_WAIT_QUEUE:
+	case OPTEE_RPC_CMD_NOTIFICATION:
 		handle_rpc_func_cmd_wq(optee, arg);
 		break;
 	case OPTEE_RPC_CMD_SUSPEND:
-- 
2.31.1



From jens.wiklander at linaro.org  Wed Aug 18 03:18:49 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 18 Aug 2021 12:18:49 +0200
Subject: [PATCH v4 6/6] optee: add asynchronous notifications
In-Reply-To: <20210818101849.602257-1-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
Message-ID: <20210818101849.602257-7-jens.wiklander@linaro.org>

Adds support for asynchronous notifications from secure world to normal
world. This allows a design with a top half and bottom half type of
driver where the top half runs in secure interrupt context and a
notifications tells normal world to schedule a yielding call to do the
bottom half processing.

The protocol is defined in optee_msg.h optee_rpc_cmd.h and optee_smc.h.

A notification consists of a 32-bit value which normal world can
retrieve using a fastcall into secure world. The value
OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF (0) has a special meaning.
When this value is sent it means that normal world is supposed to make a
yielding call OPTEE_MSG_CMD_DO_BOTTOM_HALF.

Notification capability is negotiated while the driver is initialized.
If both sides supports these notifications then they are enabled.

An interrupt is used to notify the driver that there are asynchronous
notifications pending.  The maximum needed notification value is
communicated at this stage. This allows scaling up when needed.

Acked-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/call.c          |  27 ++++++++
 drivers/tee/optee/core.c          |  82 +++++++++++++++-------
 drivers/tee/optee/notif.c         | 109 ++++++++++++++++++++++++++++--
 drivers/tee/optee/optee_msg.h     |   9 +++
 drivers/tee/optee/optee_private.h |   6 +-
 drivers/tee/optee/optee_smc.h     |  75 +++++++++++++++++++-
 6 files changed, 276 insertions(+), 32 deletions(-)

diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 6e6eb836e9b6..3afd43b598f9 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -392,6 +392,33 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 	return 0;
 }
 
+static int simple_call_with_arg(struct tee_context *ctx, u32 cmd)
+{
+	struct optee_msg_arg *msg_arg;
+	phys_addr_t msg_parg;
+	struct tee_shm *shm;
+
+	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+
+	msg_arg->cmd = cmd;
+	optee_do_call_with_arg(ctx, msg_parg);
+
+	tee_shm_free(shm);
+	return 0;
+}
+
+int optee_do_bottom_half(struct tee_context *ctx)
+{
+	return simple_call_with_arg(ctx, OPTEE_MSG_CMD_DO_BOTTOM_HALF);
+}
+
+int optee_stop_async_notif(struct tee_context *ctx)
+{
+	return simple_call_with_arg(ctx, OPTEE_MSG_CMD_STOP_ASYNC_NOTIF);
+}
+
 /**
  * optee_enable_shm_cache() - Enables caching of some shared memory allocation
  *			      in OP-TEE
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 2272696ac986..e3c80505cc88 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -7,9 +7,12 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/errno.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -353,6 +356,17 @@ static const struct tee_desc optee_supp_desc = {
 	.flags = TEE_DESC_PRIVILEGED,
 };
 
+static int enable_async_notif(optee_invoke_fn *invoke_fn)
+{
+	struct arm_smccc_res res;
+
+	invoke_fn(OPTEE_SMC_ENABLE_ASYNC_NOTIF, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0)
+		return -EINVAL;
+	return 0;
+}
+
 static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
 {
 	struct arm_smccc_res res;
@@ -402,7 +416,7 @@ static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
 }
 
 static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
-					    u32 *sec_caps)
+					    u32 *sec_caps, u32 *max_notif_value)
 {
 	union {
 		struct arm_smccc_res smccc;
@@ -425,6 +439,7 @@ static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
 		return false;
 
 	*sec_caps = res.result.capabilities;
+	*max_notif_value = res.result.max_notif_value;
 	return true;
 }
 
@@ -609,6 +624,7 @@ static int optee_probe(struct platform_device *pdev)
 	struct optee *optee = NULL;
 	void *memremaped_shm = NULL;
 	struct tee_device *teedev;
+	u32 max_notif_value;
 	u32 sec_caps;
 	int rc;
 
@@ -628,7 +644,8 @@ static int optee_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
+	if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps,
+					     &max_notif_value)) {
 		pr_warn("capabilities mismatch\n");
 		return -EINVAL;
 	}
@@ -651,7 +668,7 @@ static int optee_probe(struct platform_device *pdev)
 	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
 	if (!optee) {
 		rc = -ENOMEM;
-		goto err;
+		goto err_free_pool;
 	}
 
 	optee->invoke_fn = invoke_fn;
@@ -660,24 +677,24 @@ static int optee_probe(struct platform_device *pdev)
 	teedev = tee_device_alloc(&optee_desc, NULL, pool, optee);
 	if (IS_ERR(teedev)) {
 		rc = PTR_ERR(teedev);
-		goto err;
+		goto err_free_optee;
 	}
 	optee->teedev = teedev;
 
 	teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee);
 	if (IS_ERR(teedev)) {
 		rc = PTR_ERR(teedev);
-		goto err;
+		goto err_unreg_teedev;
 	}
 	optee->supp_teedev = teedev;
 
 	rc = tee_device_register(optee->teedev);
 	if (rc)
-		goto err;
+		goto err_unreg_supp_teedev;
 
 	rc = tee_device_register(optee->supp_teedev);
 	if (rc)
-		goto err;
+		goto err_unreg_supp_teedev;
 
 	mutex_init(&optee->call_queue.mutex);
 	INIT_LIST_HEAD(&optee->call_queue.waiters);
@@ -687,10 +704,30 @@ static int optee_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, optee);
 
-	rc = optee_notif_init(optee, 255);
-	if (rc) {
-		optee_remove(pdev);
-		return rc;
+	if (sec_caps & OPTEE_SMC_SEC_CAP_ASYNC_NOTIF) {
+		unsigned int irq;
+
+		rc = platform_get_irq(pdev, 0);
+		if (rc < 0) {
+			pr_err("platform_get_irq: ret %d\n", rc);
+			goto err_unreg_supp_teedev;
+		}
+		irq = rc;
+
+		rc = optee_notif_init(optee, max_notif_value, irq);
+		if (rc) {
+			irq_dispose_mapping(irq);
+			optee_remove(pdev);
+			return rc;
+		}
+		enable_async_notif(optee->invoke_fn);
+		pr_info("Asynchronous notifications enabled\n");
+	} else {
+		rc = optee_notif_init(optee, 255, 0);
+		if (rc) {
+			optee_remove(pdev);
+			return rc;
+		}
 	}
 
 	optee_enable_shm_cache(optee);
@@ -706,20 +743,15 @@ static int optee_probe(struct platform_device *pdev)
 
 	pr_info("initialized driver\n");
 	return 0;
-err:
-	if (optee) {
-		/*
-		 * tee_device_unregister() is safe to call even if the
-		 * devices hasn't been registered with
-		 * tee_device_register() yet.
-		 */
-		tee_device_unregister(optee->supp_teedev);
-		tee_device_unregister(optee->teedev);
-		kfree(optee);
-	}
-	if (pool)
-		tee_shm_pool_free(pool);
-	if (memremaped_shm)
+err_unreg_supp_teedev:
+	tee_device_unregister(optee->supp_teedev);
+err_unreg_teedev:
+	tee_device_unregister(optee->teedev);
+err_free_optee:
+	kfree(optee);
+err_free_pool:
+	tee_shm_pool_free(pool);
+	if (optee->memremaped_shm)
 		memunmap(memremaped_shm);
 	return rc;
 }
diff --git a/drivers/tee/optee/notif.c b/drivers/tee/optee/notif.c
index a28fa03dcd0e..ecfa82797695 100644
--- a/drivers/tee/optee/notif.c
+++ b/drivers/tee/optee/notif.c
@@ -7,10 +7,14 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/tee_drv.h>
 #include "optee_private.h"
+#include "optee_smc.h"
+#include "optee_rpc_cmd.h"
 
 struct notif_entry {
 	struct list_head link;
@@ -18,6 +22,54 @@ struct notif_entry {
 	u_int key;
 };
 
+static u32 get_async_notif_value(optee_invoke_fn *invoke_fn, bool *value_valid,
+				 bool *value_pending)
+{
+	struct arm_smccc_res res;
+
+	invoke_fn(OPTEE_SMC_GET_ASYNC_NOTIF_VALUE, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0)
+		return 0;
+	*value_valid = (res.a2 & OPTEE_SMC_ASYNC_NOTIF_VALUE_VALID);
+	*value_pending = (res.a2 & OPTEE_SMC_ASYNC_NOTIF_VALUE_PENDING);
+	return res.a1;
+}
+
+static irqreturn_t notif_irq_handler(int irq, void *dev_id)
+{
+	struct optee *optee = dev_id;
+	bool do_bottom_half = false;
+	bool value_valid;
+	bool value_pending;
+	u32 value;
+
+	do {
+		value = get_async_notif_value(optee->invoke_fn, &value_valid,
+					      &value_pending);
+		if (!value_valid)
+			break;
+
+		if (value == OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF)
+			do_bottom_half = true;
+		else
+			optee_notif_send(optee, value);
+	} while (value_pending);
+
+	if (do_bottom_half)
+		return IRQ_WAKE_THREAD;
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t notif_irq_thread_fn(int irq, void *dev_id)
+{
+	struct optee *optee = dev_id;
+
+	optee_do_bottom_half(optee->notif.ctx);
+
+	return IRQ_HANDLED;
+}
+
 static bool have_key(struct optee *optee, u_int key)
 {
 	struct notif_entry *entry;
@@ -106,20 +158,69 @@ int optee_notif_send(struct optee *optee, u_int key)
 	return 0;
 }
 
-int optee_notif_init(struct optee *optee, u_int max_key)
+int optee_notif_init(struct optee *optee, u_int max_key, u_int irq)
 {
+	struct tee_context *ctx;
+	int rc;
+
+	if (irq) {
+		ctx = tee_dev_open_helper(optee->teedev);
+		if (IS_ERR(ctx))
+			return PTR_ERR(ctx);
+
+		optee->notif.ctx = ctx;
+	}
+
 	spin_lock_init(&optee->notif.lock);
 	INIT_LIST_HEAD(&optee->notif.db);
 	optee->notif.bitmap = bitmap_zalloc(max_key, GFP_KERNEL);
-	if (!optee->notif.bitmap)
-		return -ENOMEM;
-
+	if (!optee->notif.bitmap) {
+		rc = -ENOMEM;
+		goto err_put_ctx;
+	}
 	optee->notif.max_key = max_key;
 
+	if (irq) {
+		rc = request_threaded_irq(irq, notif_irq_handler,
+					  notif_irq_thread_fn,
+					  0, "optee_notification", optee);
+		if (rc)
+			goto err_free_bitmap;
+
+		optee->notif.irq = irq;
+	}
+
 	return 0;
+
+err_free_bitmap:
+	kfree(optee->notif.bitmap);
+err_put_ctx:
+	tee_dev_ctx_put(optee->notif.ctx);
+	optee->notif.ctx = NULL;
+
+	return rc;
 }
 
 void optee_notif_uninit(struct optee *optee)
 {
+	if (optee->notif.ctx) {
+		optee_stop_async_notif(optee->notif.ctx);
+		if (optee->notif.irq) {
+			free_irq(optee->notif.irq, optee);
+			irq_dispose_mapping(optee->notif.irq);
+		}
+
+		/*
+		 * The thread normally working with optee->notif.ctx was
+		 * stopped with free_irq() above.
+		 *
+		 * Note we're not using teedev_close_context() or
+		 * tee_client_close_context() since we have already called
+		 * tee_device_put() while initializing to avoid a circular
+		 * reference counting.
+		 */
+		tee_dev_ctx_put(optee->notif.ctx);
+	}
+
 	kfree(optee->notif.bitmap);
 }
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index e3d72d09c484..3e09c8386e46 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -293,6 +293,13 @@ struct optee_msg_arg {
  * [in] param[0].u.rmem.shm_ref		holds shared memory reference
  * [in] param[0].u.rmem.offs		0
  * [in] param[0].u.rmem.size		0
+ *
+ * OPTEE_MSG_CMD_DO_BOTTOM_HALF does the scheduled bottom half processing
+ * of a driver.
+ *
+ * OPTEE_MSG_CMD_STOP_ASYNC_NOTIF informs secure world that from now is
+ * normal world unable to process asynchronous notifications. Typically
+ * used when the driver is shut down.
  */
 #define OPTEE_MSG_CMD_OPEN_SESSION	0
 #define OPTEE_MSG_CMD_INVOKE_COMMAND	1
@@ -300,6 +307,8 @@ struct optee_msg_arg {
 #define OPTEE_MSG_CMD_CANCEL		3
 #define OPTEE_MSG_CMD_REGISTER_SHM	4
 #define OPTEE_MSG_CMD_UNREGISTER_SHM	5
+#define OPTEE_MSG_CMD_DO_BOTTOM_HALF	6
+#define OPTEE_MSG_CMD_STOP_ASYNC_NOTIF	7
 #define OPTEE_MSG_FUNCID_CALL_WITH_ARG	0x0004
 
 #endif /* _OPTEE_MSG_H */
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 7dc058d008b2..62365912a70b 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -37,6 +37,8 @@ struct optee_call_queue {
 
 struct optee_notif {
 	u_int max_key;
+	unsigned int irq;
+	struct tee_context *ctx;
 	/* Serializes access to the elements below in this struct */
 	spinlock_t lock;
 	struct list_head db;
@@ -132,7 +134,7 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
 		      struct optee_call_ctx *call_ctx);
 void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx);
 
-int optee_notif_init(struct optee *optee, u_int max_key);
+int optee_notif_init(struct optee *optee, u_int max_key, u_int irq);
 void optee_notif_uninit(struct optee *optee);
 int optee_notif_wait(struct optee *optee, u_int key);
 int optee_notif_send(struct optee *optee, u_int key);
@@ -159,6 +161,8 @@ int optee_close_session(struct tee_context *ctx, u32 session);
 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 		      struct tee_param *param);
 int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
+int optee_do_bottom_half(struct tee_context *ctx);
+int optee_stop_async_notif(struct tee_context *ctx);
 
 void optee_enable_shm_cache(struct optee *optee);
 void optee_disable_shm_cache(struct optee *optee);
diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h
index 80eb763a8a80..c6eec6b6febf 100644
--- a/drivers/tee/optee/optee_smc.h
+++ b/drivers/tee/optee/optee_smc.h
@@ -107,6 +107,12 @@ struct optee_smc_call_get_os_revision_result {
 /*
  * Call with struct optee_msg_arg as argument
  *
+ * When calling this function normal world has a few responsibilities:
+ * 1. It must be able to handle eventual RPCs
+ * 2. Non-secure interrupts should not be masked
+ * 3. If asynchronous notifications has be negotiated successfully, then
+ *    asynchronous notifications should be unmasked during this call.
+ *
  * Call register usage:
  * a0	SMC Function ID, OPTEE_SMC*CALL_WITH_ARG
  * a1	Upper 32 bits of a 64-bit physical pointer to a struct optee_msg_arg
@@ -195,7 +201,8 @@ struct optee_smc_get_shm_config_result {
  * Normal return register usage:
  * a0	OPTEE_SMC_RETURN_OK
  * a1	bitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*
- * a2-7	Preserved
+ * a2	The maximum secure world notification number
+ * a3-7	Preserved
  *
  * Error return register usage:
  * a0	OPTEE_SMC_RETURN_ENOTAVAIL, can't use the capabilities from normal world
@@ -218,6 +225,8 @@ struct optee_smc_get_shm_config_result {
 #define OPTEE_SMC_SEC_CAP_VIRTUALIZATION	BIT(3)
 /* Secure world supports Shared Memory with a NULL reference */
 #define OPTEE_SMC_SEC_CAP_MEMREF_NULL		BIT(4)
+/* Secure world supports asynchronous notification of normal world */
+#define OPTEE_SMC_SEC_CAP_ASYNC_NOTIF		BIT(5)
 
 #define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES	9
 #define OPTEE_SMC_EXCHANGE_CAPABILITIES \
@@ -226,8 +235,8 @@ struct optee_smc_get_shm_config_result {
 struct optee_smc_exchange_capabilities_result {
 	unsigned long status;
 	unsigned long capabilities;
+	unsigned long max_notif_value;
 	unsigned long reserved0;
-	unsigned long reserved1;
 };
 
 /*
@@ -319,6 +328,68 @@ struct optee_smc_disable_shm_cache_result {
 #define OPTEE_SMC_GET_THREAD_COUNT \
 	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_THREAD_COUNT)
 
+/*
+ * Inform OP-TEE that normal world is able to receive asynchronous
+ * notifications.
+ *
+ * Call requests usage:
+ * a0	SMC Function ID, OPTEE_SMC_ENABLE_ASYNC_NOTIF
+ * a1-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Normal return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1-7	Preserved
+ *
+ * Not supported return register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL
+ * a1-7	Preserved
+ */
+#define OPTEE_SMC_FUNCID_ENABLE_ASYNC_NOTIF	16
+#define OPTEE_SMC_ENABLE_ASYNC_NOTIF \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_ASYNC_NOTIF)
+
+/*
+ * Retrieve a value of notifications pended since the last call of this
+ * function.
+ *
+ * OP-TEE keeps a records of all posted values. When an interrupts is
+ * received which indicates that there are posed values this function
+ * should be called until all pended values has been retrieved. When a
+ * value is retrieved it's cleared from the record in secure world.
+ *
+ * Call requests usage:
+ * a0	SMC Function ID, OPTEE_SMC_GET_ASYNC_NOTIF_VALUE
+ * a1-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Normal return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1	value
+ * a2	Bit[0]: OPTEE_SMC_ASYNC_NOTIF_VALUE_VALID if the value in a1 is
+ *		valid, else 0 if no values where pending
+ * a2	Bit[1]: OPTEE_SMC_ASYNC_NOTIF_VALUE_PENDING if another value is
+ *		pending, else 0.
+ *	Bit[31:2]: MBZ
+ * a3-7	Preserved
+ *
+ * Not supported return register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL
+ * a1-7	Preserved
+ */
+#define OPTEE_SMC_ASYNC_NOTIF_VALUE_VALID	BIT(0)
+#define OPTEE_SMC_ASYNC_NOTIF_VALUE_PENDING	BIT(1)
+
+/*
+ * Notification that OP-TEE expects a yielding call to do some bottom half
+ * work in a driver.
+ */
+#define OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF	0
+
+#define OPTEE_SMC_FUNCID_GET_ASYNC_NOTIF_VALUE	17
+#define OPTEE_SMC_GET_ASYNC_NOTIF_VALUE \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_ASYNC_NOTIF_VALUE)
+
 /*
  * Resume from RPC (for example after processing a foreign interrupt)
  *
-- 
2.31.1



From trevor.wu at mediatek.com  Wed Aug 18 03:32:04 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:04 +0800
Subject: [PATCH v4 00/11] ASoC: mediatek: Add support for MT8195 SoC
Message-ID: <20210818103215.9186-1-trevor.wu@mediatek.com>

This series of patches adds support for Mediatek AFE of MT8195 SoC.
Patches are based on broonie tree "for-next" branch.

Changes since v3:
  - fixed warnings found by kernel test robot
  - removed unused critical section
  - corrected the lock protected sections on etdm driver
  - added DPTX and HDMITX audio support

Changes since v2:
  - added audio clock gate control
  - added 'mediatek' prefix to private dts properties
  - added consumed clocks to dt-bindins and adopted suggestions from Rob
  - refined clock usage and remove unused clock and control code
  - fixed typos

Changes since v1:
  - fixed some problems related to dt-bindings
  - added some missing properties to dt-bindings
  - added depency declaration on dt-bindings
  - fixed some warnings found by kernel test robot

Trevor Wu (11):
  ASoC: mediatek: mt8195: update mediatek common driver
  ASoC: mediatek: mt8195: support audsys clock control
  ASoC: mediatek: mt8195: support etdm in platform driver
  ASoC: mediatek: mt8195: support adda in platform driver
  ASoC: mediatek: mt8195: support pcm in platform driver
  ASoC: mediatek: mt8195: add platform driver
  dt-bindings: mediatek: mt8195: add audio afe document
  ASoC: mediatek: mt8195: add machine driver with mt6359, rt1019 and
    rt5682
  ASoC: mediatek: mt8195: add DPTX audio support
  ASoC: mediatek: mt8195: add HDMITX audio support
  dt-bindings: mediatek: mt8195: add mt8195-mt6359-rt1019-rt5682
    document

 .../bindings/sound/mt8195-afe-pcm.yaml        |  184 +
 .../sound/mt8195-mt6359-rt1019-rt5682.yaml    |   47 +
 sound/soc/mediatek/Kconfig                    |   24 +
 sound/soc/mediatek/Makefile                   |    1 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.c    |   22 +-
 sound/soc/mediatek/common/mtk-base-afe.h      |   10 +-
 sound/soc/mediatek/mt8195/Makefile            |   15 +
 sound/soc/mediatek/mt8195/mt8195-afe-clk.c    |  441 +++
 sound/soc/mediatek/mt8195/mt8195-afe-clk.h    |  109 +
 sound/soc/mediatek/mt8195/mt8195-afe-common.h |  158 +
 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c    | 3281 +++++++++++++++++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c |  214 ++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h |   15 +
 .../soc/mediatek/mt8195/mt8195-audsys-clkid.h |   93 +
 sound/soc/mediatek/mt8195/mt8195-dai-adda.c   |  830 +++++
 sound/soc/mediatek/mt8195/mt8195-dai-etdm.c   | 2639 +++++++++++++
 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c    |  389 ++
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 1093 ++++++
 sound/soc/mediatek/mt8195/mt8195-reg.h        | 2796 ++++++++++++++
 19 files changed, 12356 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
 create mode 100644 sound/soc/mediatek/mt8195/Makefile
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-common.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-adda.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-reg.h

-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:05 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:05 +0800
Subject: [PATCH v4 01/11] ASoC: mediatek: mt8195: update mediatek common driver
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-2-trevor.wu@mediatek.com>

Update mediatek common driver to support MT8195

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 sound/soc/mediatek/common/mtk-afe-fe-dai.c | 22 +++++++++++++++++++---
 sound/soc/mediatek/common/mtk-base-afe.h   | 10 ++++++++--
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
index 3cb2adf420bb..baaa5881b1d4 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -139,7 +139,7 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
 		substream->runtime->dma_area,
 		substream->runtime->dma_bytes);
 
-	memset_io(substream->runtime->dma_area, 0,
+	memset_io((void __force __iomem *)substream->runtime->dma_area, 0,
 		  substream->runtime->dma_bytes);
 
 	/* set addr */
@@ -433,11 +433,20 @@ int mtk_memif_set_addr(struct mtk_base_afe *afe, int id,
 				 phys_buf_addr_upper_32);
 	}
 
-	/* set MSB to 33-bit */
-	if (memif->data->msb_reg >= 0)
+	/*
+	 * set MSB to 33-bit, for memif address
+	 * only for memif base address, if msb_end_reg exists
+	 */
+	if (memif->data->msb_reg)
 		mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg,
 				       1, msb_at_bit33, memif->data->msb_shift);
 
+	/* set MSB to 33-bit, for memif end address */
+	if (memif->data->msb_end_reg)
+		mtk_regmap_update_bits(afe->regmap, memif->data->msb_end_reg,
+				       1, msb_at_bit33,
+				       memif->data->msb_end_shift);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_memif_set_addr);
@@ -464,6 +473,13 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe,
 	else
 		mono = (channel == 1) ? 1 : 0;
 
+	/* for specific configuration of memif mono mode */
+	if (memif->data->int_odd_flag_reg)
+		mtk_regmap_update_bits(afe->regmap,
+				       memif->data->int_odd_flag_reg,
+				       1, mono,
+				       memif->data->int_odd_flag_shift);
+
 	return mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg,
 				      1, mono, memif->data->mono_shift);
 }
diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h
index a6f68c68581c..ef83e78c22a8 100644
--- a/sound/soc/mediatek/common/mtk-base-afe.h
+++ b/sound/soc/mediatek/common/mtk-base-afe.h
@@ -29,6 +29,8 @@ struct mtk_base_memif_data {
 	int quad_ch_reg;
 	int quad_ch_mask;
 	int quad_ch_shift;
+	int int_odd_flag_reg;
+	int int_odd_flag_shift;
 	int enable_reg;
 	int enable_shift;
 	int hd_reg;
@@ -37,10 +39,13 @@ struct mtk_base_memif_data {
 	int hd_align_mshift;
 	int msb_reg;
 	int msb_shift;
-	int msb2_reg;
-	int msb2_shift;
+	int msb_end_reg;
+	int msb_end_shift;
 	int agent_disable_reg;
 	int agent_disable_shift;
+	int ch_num_reg;
+	int ch_num_shift;
+	int ch_num_maskbit;
 	/* playback memif only */
 	int pbuf_reg;
 	int pbuf_mask;
@@ -62,6 +67,7 @@ struct mtk_base_irq_data {
 	int irq_en_shift;
 	int irq_clr_reg;
 	int irq_clr_shift;
+	int irq_status_shift;
 };
 
 struct device;
-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:06 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:06 +0800
Subject: [PATCH v4 02/11] ASoC: mediatek: mt8195: support audsys clock control
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-3-trevor.wu@mediatek.com>

This patch adds mt8195 audio cg control.
Audio clock gates are registered to CCF for reference count and
clock parent management.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c | 214 ++++++++++++++++++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h |  15 ++
 .../soc/mediatek/mt8195/mt8195-audsys-clkid.h |  93 ++++++++
 3 files changed, 322 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h

diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
new file mode 100644
index 000000000000..740aa6ddda0e
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt8195-audsys-clk.h  --  Mediatek 8195 audsys clock control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include "mt8195-afe-common.h"
+#include "mt8195-audsys-clk.h"
+#include "mt8195-audsys-clkid.h"
+#include "mt8195-reg.h"
+
+struct afe_gate {
+	int id;
+	const char *name;
+	const char *parent_name;
+	int reg;
+	u8 bit;
+	const struct clk_ops *ops;
+	unsigned long flags;
+	u8 cg_flags;
+};
+
+#define GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, _flags, _cgflags) {\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.reg = _reg,					\
+		.bit = _bit,					\
+		.flags = _flags,				\
+		.cg_flags = _cgflags,				\
+	}
+
+#define GATE_AFE(_id, _name, _parent, _reg, _bit)		\
+	GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit,		\
+		       CLK_SET_RATE_PARENT, CLK_GATE_SET_TO_DISABLE)
+
+#define GATE_AUD0(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON0, _bit)
+
+#define GATE_AUD1(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON1, _bit)
+
+#define GATE_AUD3(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON3, _bit)
+
+#define GATE_AUD4(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON4, _bit)
+
+#define GATE_AUD5(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON5, _bit)
+
+#define GATE_AUD6(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON6, _bit)
+
+static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
+	/* AUD0 */
+	GATE_AUD0(CLK_AUD_AFE, "aud_afe", "a1sys_hp_sel", 2),
+	GATE_AUD0(CLK_AUD_LRCK_CNT, "aud_lrck_cnt", "a1sys_hp_sel", 4),
+	GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_APLL, "aud_spdifin_tuner_apll", "apll4_sel", 10),
+	GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_DBG, "aud_spdifin_tuner_dbg", "apll4_sel", 11),
+	GATE_AUD0(CLK_AUD_UL_TML, "aud_ul_tml", "a1sys_hp_sel", 18),
+	GATE_AUD0(CLK_AUD_APLL1_TUNER, "aud_apll1_tuner", "apll1_sel", 19),
+	GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "apll2_sel", 20),
+	GATE_AUD0(CLK_AUD_TOP0_SPDF, "aud_top0_spdf", "aud_iec_sel", 21),
+	GATE_AUD0(CLK_AUD_APLL, "aud_apll", "apll1_sel", 23),
+	GATE_AUD0(CLK_AUD_APLL2, "aud_apll2", "apll2_sel", 24),
+	GATE_AUD0(CLK_AUD_DAC, "aud_dac", "a1sys_hp_sel", 25),
+	GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "a1sys_hp_sel", 26),
+	GATE_AUD0(CLK_AUD_TML, "aud_tml", "a1sys_hp_sel", 27),
+	GATE_AUD0(CLK_AUD_ADC, "aud_adc", "a1sys_hp_sel", 28),
+	GATE_AUD0(CLK_AUD_DAC_HIRES, "aud_dac_hires", "audio_h_sel", 31),
+
+	/* AUD1 */
+	GATE_AUD1(CLK_AUD_A1SYS_HP, "aud_a1sys_hp", "a1sys_hp_sel", 2),
+	GATE_AUD1(CLK_AUD_AFE_DMIC1, "aud_afe_dmic1", "a1sys_hp_sel", 10),
+	GATE_AUD1(CLK_AUD_AFE_DMIC2, "aud_afe_dmic2", "a1sys_hp_sel", 11),
+	GATE_AUD1(CLK_AUD_AFE_DMIC3, "aud_afe_dmic3", "a1sys_hp_sel", 12),
+	GATE_AUD1(CLK_AUD_AFE_DMIC4, "aud_afe_dmic4", "a1sys_hp_sel", 13),
+	GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "a1sys_hp_sel", 14),
+	GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "audio_h_sel", 16),
+	GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "audio_h_sel", 17),
+	GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "a1sys_hp_sel", 18),
+	GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "audio_h_sel", 19),
+
+	/* AUD3 */
+	GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "apll5_sel", 5),
+	GATE_AUD3(CLK_AUD_EARC_TUNER, "aud_earc_tuner", "apll3_sel", 7),
+
+	/* AUD4 */
+	GATE_AUD4(CLK_AUD_I2SIN, "aud_i2sin", "a1sys_hp_sel", 0),
+	GATE_AUD4(CLK_AUD_TDM_IN, "aud_tdm_in", "a1sys_hp_sel", 1),
+	GATE_AUD4(CLK_AUD_I2S_OUT, "aud_i2s_out", "a1sys_hp_sel", 6),
+	GATE_AUD4(CLK_AUD_TDM_OUT, "aud_tdm_out", "a1sys_hp_sel", 7),
+	GATE_AUD4(CLK_AUD_HDMI_OUT, "aud_hdmi_out", "a1sys_hp_sel", 8),
+	GATE_AUD4(CLK_AUD_ASRC11, "aud_asrc11", "a1sys_hp_sel", 16),
+	GATE_AUD4(CLK_AUD_ASRC12, "aud_asrc12", "a1sys_hp_sel", 17),
+	GATE_AUD4(CLK_AUD_MULTI_IN, "aud_multi_in", "mphone_slave_b", 19),
+	GATE_AUD4(CLK_AUD_INTDIR, "aud_intdir", "intdir_sel", 20),
+	GATE_AUD4(CLK_AUD_A1SYS, "aud_a1sys", "a1sys_hp_sel", 21),
+	GATE_AUD4(CLK_AUD_A2SYS, "aud_a2sys", "a2sys_sel", 22),
+	GATE_AUD4(CLK_AUD_PCMIF, "aud_pcmif", "a1sys_hp_sel", 24),
+	GATE_AUD4(CLK_AUD_A3SYS, "aud_a3sys", "a3sys_sel", 30),
+	GATE_AUD4(CLK_AUD_A4SYS, "aud_a4sys", "a4sys_sel", 31),
+
+	/* AUD5 */
+	GATE_AUD5(CLK_AUD_MEMIF_UL1, "aud_memif_ul1", "a1sys_hp_sel", 0),
+	GATE_AUD5(CLK_AUD_MEMIF_UL2, "aud_memif_ul2", "a1sys_hp_sel", 1),
+	GATE_AUD5(CLK_AUD_MEMIF_UL3, "aud_memif_ul3", "a1sys_hp_sel", 2),
+	GATE_AUD5(CLK_AUD_MEMIF_UL4, "aud_memif_ul4", "a1sys_hp_sel", 3),
+	GATE_AUD5(CLK_AUD_MEMIF_UL5, "aud_memif_ul5", "a1sys_hp_sel", 4),
+	GATE_AUD5(CLK_AUD_MEMIF_UL6, "aud_memif_ul6", "a1sys_hp_sel", 5),
+	GATE_AUD5(CLK_AUD_MEMIF_UL8, "aud_memif_ul8", "a1sys_hp_sel", 7),
+	GATE_AUD5(CLK_AUD_MEMIF_UL9, "aud_memif_ul9", "a1sys_hp_sel", 8),
+	GATE_AUD5(CLK_AUD_MEMIF_UL10, "aud_memif_ul10", "a1sys_hp_sel", 9),
+	GATE_AUD5(CLK_AUD_MEMIF_DL2, "aud_memif_dl2", "a1sys_hp_sel", 18),
+	GATE_AUD5(CLK_AUD_MEMIF_DL3, "aud_memif_dl3", "a1sys_hp_sel", 19),
+	GATE_AUD5(CLK_AUD_MEMIF_DL6, "aud_memif_dl6", "a1sys_hp_sel", 22),
+	GATE_AUD5(CLK_AUD_MEMIF_DL7, "aud_memif_dl7", "a1sys_hp_sel", 23),
+	GATE_AUD5(CLK_AUD_MEMIF_DL8, "aud_memif_dl8", "a1sys_hp_sel", 24),
+	GATE_AUD5(CLK_AUD_MEMIF_DL10, "aud_memif_dl10", "a1sys_hp_sel", 26),
+	GATE_AUD5(CLK_AUD_MEMIF_DL11, "aud_memif_dl11", "a1sys_hp_sel", 27),
+
+	/* AUD6 */
+	GATE_AUD6(CLK_AUD_GASRC0, "aud_gasrc0", "asm_h_sel", 0),
+	GATE_AUD6(CLK_AUD_GASRC1, "aud_gasrc1", "asm_h_sel", 1),
+	GATE_AUD6(CLK_AUD_GASRC2, "aud_gasrc2", "asm_h_sel", 2),
+	GATE_AUD6(CLK_AUD_GASRC3, "aud_gasrc3", "asm_h_sel", 3),
+	GATE_AUD6(CLK_AUD_GASRC4, "aud_gasrc4", "asm_h_sel", 4),
+	GATE_AUD6(CLK_AUD_GASRC5, "aud_gasrc5", "asm_h_sel", 5),
+	GATE_AUD6(CLK_AUD_GASRC6, "aud_gasrc6", "asm_h_sel", 6),
+	GATE_AUD6(CLK_AUD_GASRC7, "aud_gasrc7", "asm_h_sel", 7),
+	GATE_AUD6(CLK_AUD_GASRC8, "aud_gasrc8", "asm_h_sel", 8),
+	GATE_AUD6(CLK_AUD_GASRC9, "aud_gasrc9", "asm_h_sel", 9),
+	GATE_AUD6(CLK_AUD_GASRC10, "aud_gasrc10", "asm_h_sel", 10),
+	GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "asm_h_sel", 11),
+	GATE_AUD6(CLK_AUD_GASRC12, "aud_gasrc12", "asm_h_sel", 12),
+	GATE_AUD6(CLK_AUD_GASRC13, "aud_gasrc13", "asm_h_sel", 13),
+	GATE_AUD6(CLK_AUD_GASRC14, "aud_gasrc14", "asm_h_sel", 14),
+	GATE_AUD6(CLK_AUD_GASRC15, "aud_gasrc15", "asm_h_sel", 15),
+	GATE_AUD6(CLK_AUD_GASRC16, "aud_gasrc16", "asm_h_sel", 16),
+	GATE_AUD6(CLK_AUD_GASRC17, "aud_gasrc17", "asm_h_sel", 17),
+	GATE_AUD6(CLK_AUD_GASRC18, "aud_gasrc18", "asm_h_sel", 18),
+	GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "asm_h_sel", 19),
+};
+
+int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk *clk;
+	struct clk_lookup *cl;
+	int i;
+
+	afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK,
+					sizeof(*afe_priv->lookup),
+					GFP_KERNEL);
+
+	if (!afe_priv->lookup)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
+		const struct afe_gate *gate = &aud_clks[i];
+
+		clk = clk_register_gate(afe->dev, gate->name, gate->parent_name,
+					gate->flags, afe->base_addr + gate->reg,
+					gate->bit, gate->cg_flags, NULL);
+
+		if (IS_ERR(clk)) {
+			dev_err(afe->dev, "Failed to register clk %s: %ld\n",
+				gate->name, PTR_ERR(clk));
+			continue;
+		}
+
+		/* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */
+		cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+		if (!cl)
+			return -ENOMEM;
+
+		cl->clk = clk;
+		cl->con_id = gate->name;
+		cl->dev_id = dev_name(afe->dev);
+		clkdev_add(cl);
+
+		afe_priv->lookup[i] = cl;
+	}
+
+	return 0;
+}
+
+void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk *clk;
+	struct clk_lookup *cl;
+	int i;
+
+	if (!afe_priv)
+		return;
+
+	for (i = 0; i < CLK_AUD_NR_CLK; i++) {
+		cl = afe_priv->lookup[i];
+		if (!cl)
+			continue;
+
+		clk = cl->clk;
+		clk_unregister_gate(clk);
+
+		clkdev_drop(cl);
+	}
+}
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
new file mode 100644
index 000000000000..239d31016ba7
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-audsys-clk.h  --  Mediatek 8195 audsys clock definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#ifndef _MT8195_AUDSYS_CLK_H_
+#define _MT8195_AUDSYS_CLK_H_
+
+int mt8195_audsys_clk_register(struct mtk_base_afe *afe);
+void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe);
+
+#endif
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
new file mode 100644
index 000000000000..4dd0a5c8b8fa
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-audsys-clkid.h  --  Mediatek 8195 audsys clock id definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#ifndef _MT8195_AUDSYS_CLKID_H_
+#define _MT8195_AUDSYS_CLKID_H_
+
+enum{
+	CLK_AUD_AFE,
+	CLK_AUD_LRCK_CNT,
+	CLK_AUD_SPDIFIN_TUNER_APLL,
+	CLK_AUD_SPDIFIN_TUNER_DBG,
+	CLK_AUD_UL_TML,
+	CLK_AUD_APLL1_TUNER,
+	CLK_AUD_APLL2_TUNER,
+	CLK_AUD_TOP0_SPDF,
+	CLK_AUD_APLL,
+	CLK_AUD_APLL2,
+	CLK_AUD_DAC,
+	CLK_AUD_DAC_PREDIS,
+	CLK_AUD_TML,
+	CLK_AUD_ADC,
+	CLK_AUD_DAC_HIRES,
+	CLK_AUD_A1SYS_HP,
+	CLK_AUD_AFE_DMIC1,
+	CLK_AUD_AFE_DMIC2,
+	CLK_AUD_AFE_DMIC3,
+	CLK_AUD_AFE_DMIC4,
+	CLK_AUD_AFE_26M_DMIC_TM,
+	CLK_AUD_UL_TML_HIRES,
+	CLK_AUD_ADC_HIRES,
+	CLK_AUD_ADDA6_ADC,
+	CLK_AUD_ADDA6_ADC_HIRES,
+	CLK_AUD_LINEIN_TUNER,
+	CLK_AUD_EARC_TUNER,
+	CLK_AUD_I2SIN,
+	CLK_AUD_TDM_IN,
+	CLK_AUD_I2S_OUT,
+	CLK_AUD_TDM_OUT,
+	CLK_AUD_HDMI_OUT,
+	CLK_AUD_ASRC11,
+	CLK_AUD_ASRC12,
+	CLK_AUD_MULTI_IN,
+	CLK_AUD_INTDIR,
+	CLK_AUD_A1SYS,
+	CLK_AUD_A2SYS,
+	CLK_AUD_PCMIF,
+	CLK_AUD_A3SYS,
+	CLK_AUD_A4SYS,
+	CLK_AUD_MEMIF_UL1,
+	CLK_AUD_MEMIF_UL2,
+	CLK_AUD_MEMIF_UL3,
+	CLK_AUD_MEMIF_UL4,
+	CLK_AUD_MEMIF_UL5,
+	CLK_AUD_MEMIF_UL6,
+	CLK_AUD_MEMIF_UL8,
+	CLK_AUD_MEMIF_UL9,
+	CLK_AUD_MEMIF_UL10,
+	CLK_AUD_MEMIF_DL2,
+	CLK_AUD_MEMIF_DL3,
+	CLK_AUD_MEMIF_DL6,
+	CLK_AUD_MEMIF_DL7,
+	CLK_AUD_MEMIF_DL8,
+	CLK_AUD_MEMIF_DL10,
+	CLK_AUD_MEMIF_DL11,
+	CLK_AUD_GASRC0,
+	CLK_AUD_GASRC1,
+	CLK_AUD_GASRC2,
+	CLK_AUD_GASRC3,
+	CLK_AUD_GASRC4,
+	CLK_AUD_GASRC5,
+	CLK_AUD_GASRC6,
+	CLK_AUD_GASRC7,
+	CLK_AUD_GASRC8,
+	CLK_AUD_GASRC9,
+	CLK_AUD_GASRC10,
+	CLK_AUD_GASRC11,
+	CLK_AUD_GASRC12,
+	CLK_AUD_GASRC13,
+	CLK_AUD_GASRC14,
+	CLK_AUD_GASRC15,
+	CLK_AUD_GASRC16,
+	CLK_AUD_GASRC17,
+	CLK_AUD_GASRC18,
+	CLK_AUD_GASRC19,
+	CLK_AUD_NR_CLK,
+};
+
+#endif
-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:11 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:11 +0800
Subject: [PATCH v4 07/11] dt-bindings: mediatek: mt8195: add audio afe document
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-8-trevor.wu@mediatek.com>

This patch adds mt8195 audio afe document.

In order to support dynamic clock reparenting for ADDA and ETDM, PLL
and MUX clocks are requested even though they are not consumed by afe
directly.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
This patch depends on the following series that have not been accepted.

[1] Mediatek MT8195 clock support
https://patchwork.kernel.org/project/linux-mediatek/list/?series=501923
(dt-bindings/clock/mt8195-clk.h is included)

[2] Mediatek MT8195 power domain support
https://patchwork.kernel.org/project/linux-mediatek/list/?series=500709
(dt-bindings/power/mt8195-power.h is included)
---
---
 .../bindings/sound/mt8195-afe-pcm.yaml        | 184 ++++++++++++++++++
 1 file changed, 184 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml

diff --git a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
new file mode 100644
index 000000000000..53e9434a6d9d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt8195-afe-pcm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek AFE PCM controller for mt8195
+
+maintainers:
+  - Trevor Wu <trevor.wu at mediatek.com>
+
+properties:
+  compatible:
+    const: mediatek,mt8195-audio
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  mediatek,topckgen:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of the mediatek topckgen controller
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: 26M clock
+      - description: audio pll1 clock
+      - description: audio pll2 clock
+      - description: clock divider for i2si1_mck
+      - description: clock divider for i2si2_mck
+      - description: clock divider for i2so1_mck
+      - description: clock divider for i2so2_mck
+      - description: clock divider for dptx_mck
+      - description: a1sys hoping clock
+      - description: audio intbus clock
+      - description: audio hires clock
+      - description: audio local bus clock
+      - description: mux for dptx_mck
+      - description: mux for i2so1_mck
+      - description: mux for i2so2_mck
+      - description: mux for i2si1_mck
+      - description: mux for i2si2_mck
+      - description: audio infra 26M clock
+      - description: infra bus clock
+
+  clock-names:
+    items:
+      - const: clk26m
+      - const: apll1_ck
+      - const: apll2_ck
+      - const: apll12_div0
+      - const: apll12_div1
+      - const: apll12_div2
+      - const: apll12_div3
+      - const: apll12_div9
+      - const: a1sys_hp_sel
+      - const: aud_intbus_sel
+      - const: audio_h_sel
+      - const: audio_local_bus_sel
+      - const: dptx_m_sel
+      - const: i2so1_m_sel
+      - const: i2so2_m_sel
+      - const: i2si1_m_sel
+      - const: i2si2_m_sel
+      - const: infra_ao_audio_26m_b
+      - const: scp_adsp_audiodsp
+
+  mediatek,etdm-in1-chn-disabled:
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    maxItems: 24
+    description: Specify which input channel should be disabled.
+
+  mediatek,etdm-in2-chn-disabled:
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    maxItems: 16
+    description: Specify which input channel should be disabled.
+
+patternProperties:
+  "^mediatek,etdm-in[1-2]-mclk-always-on-rate-hz$":
+    description: Specify etdm in mclk output rate for always on case.
+
+  "^mediatek,etdm-out[1-3]-mclk-always-on-rate-hz$":
+    description: Specify etdm out mclk output rate for always on case.
+
+  "^mediatek,etdm-in[1-2]-multi-pin-mode$":
+    type: boolean
+    description: if present, the etdm data mode is I2S.
+
+  "^mediatek,etdm-out[1-3]-multi-pin-mode$":
+    type: boolean
+    description: if present, the etdm data mode is I2S.
+
+  "^mediatek,etdm-in[1-2]-cowork-source$":
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      etdm modules can share the same external clock pin. Specify
+      which etdm clock source is required by this etdm in moudule.
+    enum:
+      - 0 # etdm1_in
+      - 1 # etdm2_in
+      - 2 # etdm1_out
+      - 3 # etdm2_out
+
+  "^mediatek,etdm-out[1-2]-cowork-source$":
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      etdm modules can share the same external clock pin. Specify
+      which etdm clock source is required by this etdm out moudule.
+    enum:
+      - 0 # etdm1_in
+      - 1 # etdm2_in
+      - 2 # etdm1_out
+      - 3 # etdm2_out
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - mediatek,topckgen
+  - power-domains
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt8195-power.h>
+
+    afe: mt8195-afe-pcm at 10890000 {
+        compatible = "mediatek,mt8195-audio";
+        reg = <0x10890000 0x10000>;
+        interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
+        mediatek,topckgen = <&topckgen>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_AUDIO>;
+        clocks = <&clk26m>,
+                 <&topckgen CLK_TOP_APLL1>,
+                 <&topckgen CLK_TOP_APLL2>,
+                 <&topckgen CLK_TOP_APLL12_DIV0>,
+                 <&topckgen CLK_TOP_APLL12_DIV1>,
+                 <&topckgen CLK_TOP_APLL12_DIV2>,
+                 <&topckgen CLK_TOP_APLL12_DIV3>,
+                 <&topckgen CLK_TOP_APLL12_DIV9>,
+                 <&topckgen CLK_TOP_A1SYS_HP_SEL>,
+                 <&topckgen CLK_TOP_AUD_INTBUS_SEL>,
+                 <&topckgen CLK_TOP_AUDIO_H_SEL>,
+                 <&topckgen CLK_TOP_AUDIO_LOCAL_BUS_SEL>,
+                 <&topckgen CLK_TOP_DPTX_M_SEL>,
+                 <&topckgen CLK_TOP_I2SO1_M_SEL>,
+                 <&topckgen CLK_TOP_I2SO2_M_SEL>,
+                 <&topckgen CLK_TOP_I2SI1_M_SEL>,
+                 <&topckgen CLK_TOP_I2SI2_M_SEL>,
+                 <&infracfg_ao CLK_INFRA_AO_AUDIO_26M_B>,
+                 <&scp_adsp CLK_SCP_ADSP_AUDIODSP>;
+        clock-names = "clk26m",
+                      "apll1_ck",
+                      "apll2_ck",
+                      "apll12_div0",
+                      "apll12_div1",
+                      "apll12_div2",
+                      "apll12_div3",
+                      "apll12_div9",
+                      "a1sys_hp_sel",
+                      "aud_intbus_sel",
+                      "audio_h_sel",
+                      "audio_local_bus_sel",
+                      "dptx_m_sel",
+                      "i2so1_m_sel",
+                      "i2so2_m_sel",
+                      "i2si1_m_sel",
+                      "i2si2_m_sel",
+                      "infra_ao_audio_26m_b",
+                      "scp_adsp_audiodsp";
+    };
+
+...
-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:09 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:09 +0800
Subject: [PATCH v4 05/11] ASoC: mediatek: mt8195: support pcm in platform
 driver
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-6-trevor.wu@mediatek.com>

This patch adds mt8195 pcm dai driver.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c | 389 +++++++++++++++++++++
 1 file changed, 389 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c

diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
new file mode 100644
index 000000000000..5d10d2c4c991
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
@@ -0,0 +1,389 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI PCM I/F Control
+ *
+ * Copyright (c) 2020 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai at mediatek.com>
+ *         Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+enum {
+	MTK_DAI_PCM_FMT_I2S,
+	MTK_DAI_PCM_FMT_EIAJ,
+	MTK_DAI_PCM_FMT_MODEA,
+	MTK_DAI_PCM_FMT_MODEB,
+};
+
+enum {
+	MTK_DAI_PCM_CLK_A1SYS,
+	MTK_DAI_PCM_CLK_A2SYS,
+	MTK_DAI_PCM_CLK_26M_48K,
+	MTK_DAI_PCM_CLK_26M_441K,
+};
+
+struct mtk_dai_pcm_rate {
+	unsigned int rate;
+	unsigned int reg_value;
+};
+
+struct mtk_dai_pcmif_priv {
+	unsigned int slave_mode;
+	unsigned int lrck_inv;
+	unsigned int bck_inv;
+	unsigned int format;
+};
+
+static const struct mtk_dai_pcm_rate mtk_dai_pcm_rates[] = {
+	{ .rate = 8000, .reg_value = 0, },
+	{ .rate = 16000, .reg_value = 1, },
+	{ .rate = 32000, .reg_value = 2, },
+	{ .rate = 48000, .reg_value = 3, },
+	{ .rate = 11025, .reg_value = 1, },
+	{ .rate = 22050, .reg_value = 2, },
+	{ .rate = 44100, .reg_value = 3, },
+};
+
+static int mtk_dai_pcm_mode(unsigned int rate)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_dai_pcm_rates); i++)
+		if (mtk_dai_pcm_rates[i].rate == rate)
+			return mtk_dai_pcm_rates[i].reg_value;
+
+	return -EINVAL;
+}
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o000_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN0, 0, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN0_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o001_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN1, 1, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN1_2, 7, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
+	SND_SOC_DAPM_MIXER("I002", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I003", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("O000", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_pcm_o000_mix,
+			   ARRAY_SIZE(mtk_dai_pcm_o000_mix)),
+	SND_SOC_DAPM_MIXER("O001", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_pcm_o001_mix,
+			   ARRAY_SIZE(mtk_dai_pcm_o001_mix)),
+
+	SND_SOC_DAPM_INPUT("PCM1_INPUT"),
+	SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
+	{"I002", NULL, "PCM1 Capture"},
+	{"I003", NULL, "PCM1 Capture"},
+
+	{"O000", "I000 Switch", "I000"},
+	{"O001", "I001 Switch", "I001"},
+
+	{"O000", "I070 Switch", "I070"},
+	{"O001", "I071 Switch", "I071"},
+
+	{"PCM1 Playback", NULL, "O000"},
+	{"PCM1 Playback", NULL, "O001"},
+
+	{"PCM1_OUTPUT", NULL, "PCM1 Playback"},
+	{"PCM1 Capture", NULL, "PCM1_INPUT"},
+};
+
+static void mtk_dai_pcm_enable(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_PCM_EN, PCM_INTF_CON1_PCM_EN);
+}
+
+static void mtk_dai_pcm_disable(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_PCM_EN, 0x0);
+}
+
+static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_pcm_runtime * const runtime = substream->runtime;
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
+	unsigned int slave_mode = pcmif_priv->slave_mode;
+	unsigned int lrck_inv = pcmif_priv->lrck_inv;
+	unsigned int bck_inv = pcmif_priv->bck_inv;
+	unsigned int fmt = pcmif_priv->format;
+	unsigned int bit_width = dai->sample_bits;
+	unsigned int val = 0;
+	unsigned int mask = 0;
+	int fs = 0;
+	int mode = 0;
+
+	/* sync freq mode */
+	fs = mt8195_afe_fs_timing(runtime->rate);
+	if (fs < 0)
+		return -EINVAL;
+	val |= PCM_INTF_CON2_SYNC_FREQ_MODE(fs);
+	mask |= PCM_INTF_CON2_SYNC_FREQ_MODE_MASK;
+
+	/* clk domain sel */
+	if (runtime->rate % 8000)
+		val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_441K);
+	else
+		val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_48K);
+	mask |= PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK;
+
+	regmap_update_bits(afe->regmap, PCM_INTF_CON2, mask, val);
+
+	val = 0;
+	mask = 0;
+
+	/* pcm mode */
+	mode = mtk_dai_pcm_mode(runtime->rate);
+	if (mode < 0)
+		return -EINVAL;
+	val |= PCM_INTF_CON1_PCM_MODE(mode);
+	mask |= PCM_INTF_CON1_PCM_MODE_MASK;
+
+	/* pcm format */
+	val |= PCM_INTF_CON1_PCM_FMT(fmt);
+	mask |= PCM_INTF_CON1_PCM_FMT_MASK;
+
+	/* pcm sync length */
+	if (fmt == MTK_DAI_PCM_FMT_MODEA ||
+	    fmt == MTK_DAI_PCM_FMT_MODEB)
+		val |= PCM_INTF_CON1_SYNC_LENGTH(1);
+	else
+		val |= PCM_INTF_CON1_SYNC_LENGTH(bit_width);
+	mask |= PCM_INTF_CON1_SYNC_LENGTH_MASK;
+
+	/* pcm bits, word length */
+	if (bit_width > 16) {
+		val |= PCM_INTF_CON1_PCM_24BIT;
+		val |= PCM_INTF_CON1_PCM_WLEN_64BCK;
+	} else {
+		val |= PCM_INTF_CON1_PCM_16BIT;
+		val |= PCM_INTF_CON1_PCM_WLEN_32BCK;
+	}
+	mask |= PCM_INTF_CON1_PCM_BIT_MASK;
+	mask |= PCM_INTF_CON1_PCM_WLEN_MASK;
+
+	/* master/slave */
+	if (!slave_mode) {
+		val |= PCM_INTF_CON1_PCM_MASTER;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_OUT_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_OUT_INV;
+		mask |= PCM_INTF_CON1_CLK_OUT_INV_MASK;
+	} else {
+		val |= PCM_INTF_CON1_PCM_SLAVE;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_IN_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_IN_INV;
+		mask |= PCM_INTF_CON1_CLK_IN_INV_MASK;
+
+		/* TODO: add asrc setting for slave mode */
+	}
+	mask |= PCM_INTF_CON1_PCM_M_S_MASK;
+
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1, mask, val);
+
+	return 0;
+}
+
+/* dai ops */
+static int mtk_dai_pcm_startup(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+	if (dai->component->active)
+		return 0;
+
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]);
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]);
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]);
+
+	return 0;
+}
+
+static void mtk_dai_pcm_shutdown(struct snd_pcm_substream *substream,
+				 struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+	if (dai->component->active)
+		return;
+
+	mtk_dai_pcm_disable(afe);
+
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]);
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]);
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]);
+}
+
+static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	int ret = 0;
+
+	if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) &&
+	    snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE))
+		return 0;
+
+	ret = mtk_dai_pcm_configure(substream, dai);
+	if (ret)
+		return ret;
+
+	mtk_dai_pcm_enable(afe);
+
+	return 0;
+}
+
+static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
+
+	dev_dbg(dai->dev, "%s fmt 0x%x\n", __func__, fmt);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_I2S;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_MODEA;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_MODEB;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		pcmif_priv->bck_inv = 0;
+		pcmif_priv->lrck_inv = 0;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		pcmif_priv->bck_inv = 0;
+		pcmif_priv->lrck_inv = 1;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		pcmif_priv->bck_inv = 1;
+		pcmif_priv->lrck_inv = 0;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		pcmif_priv->bck_inv = 1;
+		pcmif_priv->lrck_inv = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		pcmif_priv->slave_mode = 1;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		pcmif_priv->slave_mode = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_pcm_ops = {
+	.startup	= mtk_dai_pcm_startup,
+	.shutdown	= mtk_dai_pcm_shutdown,
+	.prepare	= mtk_dai_pcm_prepare,
+	.set_fmt	= mtk_dai_pcm_set_fmt,
+};
+
+/* dai driver */
+#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000)
+
+#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+			 SNDRV_PCM_FMTBIT_S24_LE |\
+			 SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
+	{
+		.name = "PCM1",
+		.id = MT8195_AFE_IO_PCM,
+		.playback = {
+			.stream_name = "PCM1 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_PCM_RATES,
+			.formats = MTK_PCM_FORMATS,
+		},
+		.capture = {
+			.stream_name = "PCM1 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_PCM_RATES,
+			.formats = MTK_PCM_FORMATS,
+		},
+		.ops = &mtk_dai_pcm_ops,
+		.symmetric_rate = 1,
+		.symmetric_sample_bits = 1,
+	},
+};
+
+static int init_pcmif_priv_data(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv;
+
+	pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_pcmif_priv),
+				  GFP_KERNEL);
+	if (!pcmif_priv)
+		return -ENOMEM;
+
+	afe_priv->dai_priv[MT8195_AFE_IO_PCM] = pcmif_priv;
+	return 0;
+}
+
+int mt8195_dai_pcm_register(struct mtk_base_afe *afe)
+{
+	struct mtk_base_afe_dai *dai;
+
+	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+
+	list_add(&dai->list, &afe->sub_dais);
+
+	dai->dai_drivers = mtk_dai_pcm_driver;
+	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
+
+	dai->dapm_widgets = mtk_dai_pcm_widgets;
+	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
+	dai->dapm_routes = mtk_dai_pcm_routes;
+	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
+
+	return init_pcmif_priv_data(afe);
+}
-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:15 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:15 +0800
Subject: [PATCH v4 11/11] dt-bindings: mediatek: mt8195: add
 mt8195-mt6359-rt1019-rt5682 document
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-12-trevor.wu@mediatek.com>

This patch adds document for mt8195 board with mt6359, rt1019 and rt5682

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 .../sound/mt8195-mt6359-rt1019-rt5682.yaml    | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml

diff --git a/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
new file mode 100644
index 000000000000..20bc0ffd0e34
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1019-rt5682.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT8195 with MT6359, RT1019 and RT5682 ASoC sound card driver
+
+maintainers:
+  - Trevor Wu <trevor.wu at mediatek.com>
+
+description:
+  This binding describes the MT8195 sound card.
+
+properties:
+  compatible:
+    const: mediatek,mt8195_mt6359_rt1019_rt5682
+
+  mediatek,platform:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of MT8195 ASoC platform.
+
+  mediatek,dptx-codec:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of MT8195 Display Port Tx codec node.
+
+  mediatek,hdmi-codec:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of MT8195 HDMI codec node.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - mediatek,platform
+
+examples:
+  - |
+
+    sound: mt8195-sound {
+        compatible = "mediatek,mt8195_mt6359_rt1019_rt5682";
+        mediatek,platform = <&afe>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&aud_pins_default>;
+    };
+
+...
-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:08 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:08 +0800
Subject: [PATCH v4 04/11] ASoC: mediatek: mt8195: support adda in platform
 driver
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-5-trevor.wu@mediatek.com>

This patch adds mt8195 adda dai driver.

audio_h clock is used by ADSP bus and ADDA module.
When ADDA requires audio_h clock, it is switched to APLL1, otherwise
it is switched to Xtal_26m so that APLL1 can be turned off when audio
feature is not used.
ADSP bus only requires that the clock is on, so dynamic reparenting
is used for the purpose of lowering power consumption.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-dai-adda.c | 830 ++++++++++++++++++++
 1 file changed, 830 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-adda.c

diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-adda.c b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
new file mode 100644
index 000000000000..878dec0b69ed
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI ADDA Control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai at mediatek.com>
+ *         Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+#define ADDA_DL_GAIN_LOOPBACK 0x1800
+#define ADDA_HIRES_THRES 48000
+
+enum {
+	SUPPLY_SEQ_CLOCK_SEL,
+	SUPPLY_SEQ_CLOCK_ON,
+	SUPPLY_SEQ_ADDA_DL_ON,
+	SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+	SUPPLY_SEQ_ADDA_UL_ON,
+	SUPPLY_SEQ_ADDA_AFE_ON,
+};
+
+enum {
+	MTK_AFE_ADDA_DL_RATE_8K = 0,
+	MTK_AFE_ADDA_DL_RATE_11K = 1,
+	MTK_AFE_ADDA_DL_RATE_12K = 2,
+	MTK_AFE_ADDA_DL_RATE_16K = 3,
+	MTK_AFE_ADDA_DL_RATE_22K = 4,
+	MTK_AFE_ADDA_DL_RATE_24K = 5,
+	MTK_AFE_ADDA_DL_RATE_32K = 6,
+	MTK_AFE_ADDA_DL_RATE_44K = 7,
+	MTK_AFE_ADDA_DL_RATE_48K = 8,
+	MTK_AFE_ADDA_DL_RATE_96K = 9,
+	MTK_AFE_ADDA_DL_RATE_192K = 10,
+};
+
+enum {
+	MTK_AFE_ADDA_UL_RATE_8K = 0,
+	MTK_AFE_ADDA_UL_RATE_16K = 1,
+	MTK_AFE_ADDA_UL_RATE_32K = 2,
+	MTK_AFE_ADDA_UL_RATE_48K = 3,
+	MTK_AFE_ADDA_UL_RATE_96K = 4,
+	MTK_AFE_ADDA_UL_RATE_192K = 5,
+};
+
+enum {
+	DELAY_DATA_MISO1 = 0,
+	DELAY_DATA_MISO0 = 1,
+	DELAY_DATA_MISO2 = 1,
+};
+
+enum {
+	MTK_AFE_ADDA,
+	MTK_AFE_ADDA6,
+};
+
+struct mtk_dai_adda_priv {
+	bool hires_required;
+};
+
+static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
+					       unsigned int rate)
+{
+	switch (rate) {
+	case 8000:
+		return MTK_AFE_ADDA_DL_RATE_8K;
+	case 11025:
+		return MTK_AFE_ADDA_DL_RATE_11K;
+	case 12000:
+		return MTK_AFE_ADDA_DL_RATE_12K;
+	case 16000:
+		return MTK_AFE_ADDA_DL_RATE_16K;
+	case 22050:
+		return MTK_AFE_ADDA_DL_RATE_22K;
+	case 24000:
+		return MTK_AFE_ADDA_DL_RATE_24K;
+	case 32000:
+		return MTK_AFE_ADDA_DL_RATE_32K;
+	case 44100:
+		return MTK_AFE_ADDA_DL_RATE_44K;
+	case 48000:
+		return MTK_AFE_ADDA_DL_RATE_48K;
+	case 96000:
+		return MTK_AFE_ADDA_DL_RATE_96K;
+	case 192000:
+		return MTK_AFE_ADDA_DL_RATE_192K;
+	default:
+		dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+			 __func__, rate);
+		return MTK_AFE_ADDA_DL_RATE_48K;
+	}
+}
+
+static unsigned int afe_adda_ul_rate_transform(struct mtk_base_afe *afe,
+					       unsigned int rate)
+{
+	switch (rate) {
+	case 8000:
+		return MTK_AFE_ADDA_UL_RATE_8K;
+	case 16000:
+		return MTK_AFE_ADDA_UL_RATE_16K;
+	case 32000:
+		return MTK_AFE_ADDA_UL_RATE_32K;
+	case 48000:
+		return MTK_AFE_ADDA_UL_RATE_48K;
+	case 96000:
+		return MTK_AFE_ADDA_UL_RATE_96K;
+	case 192000:
+		return MTK_AFE_ADDA_UL_RATE_192K;
+	default:
+		dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+			 __func__, rate);
+		return MTK_AFE_ADDA_UL_RATE_48K;
+	}
+}
+
+static int mt8195_adda_mtkaif_init(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int delay_data;
+	int delay_cycle;
+	unsigned int mask = 0;
+	unsigned int val = 0;
+
+	/* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
+	mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+	val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+
+	regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask, val);
+	regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, mask, val);
+
+	mask = RG_RX_PROTOCOL2;
+	val = RG_RX_PROTOCOL2;
+	regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val);
+
+	if (!param->mtkaif_calibration_ok) {
+		dev_info(afe->dev, "%s(), calibration fail\n",  __func__);
+		return 0;
+	}
+
+	/* set delay for ch1, ch2 */
+	if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] >=
+	    param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {
+		delay_data = DELAY_DATA_MISO1;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];
+	} else {
+		delay_data = DELAY_DATA_MISO0;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0];
+	}
+
+	val = 0;
+	mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+	val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+	       MTKAIF_RXIF_DELAY_CYCLE_MASK;
+	val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+	regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
+
+	/* set delay between ch3 and ch2 */
+	if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] >=
+	    param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {
+		delay_data = DELAY_DATA_MISO1;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];
+	} else {
+		delay_data = DELAY_DATA_MISO2;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2];
+	}
+
+	val = 0;
+	mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+	val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+	       MTKAIF_RXIF_DELAY_CYCLE_MASK;
+	val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+	regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG2, mask, val);
+
+	return 0;
+}
+
+static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
+				     struct snd_kcontrol *kcontrol,
+				     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8195_adda_mtkaif_init(afe);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, int adda, bool dmic)
+{
+	unsigned int reg = 0;
+	unsigned int mask = 0;
+	unsigned int val = 0;
+
+	switch (adda) {
+	case MTK_AFE_ADDA:
+		reg = AFE_ADDA_UL_SRC_CON0;
+		break;
+	case MTK_AFE_ADDA6:
+		reg = AFE_ADDA6_UL_SRC_CON0;
+		break;
+	default:
+		dev_info(afe->dev, "%s(), wrong parameter\n",  __func__);
+		return;
+	}
+
+	mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
+		UL_MODE_3P25M_CH2_CTL);
+
+	/* turn on dmic, ch1, ch2 */
+	if (dmic)
+		val = mask;
+
+	regmap_update_bits(afe->regmap, reg, mask, val);
+}
+
+static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_adda_ul_mictype(afe, MTK_AFE_ADDA, param->mtkaif_dmic_on);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_adda6_ul_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol,
+			      int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	unsigned int val;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_adda_ul_mictype(afe, MTK_AFE_ADDA6, param->mtkaif_dmic_on);
+
+		val = (param->mtkaif_adda6_only ?
+			ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE : 0);
+
+		regmap_update_bits(afe->regmap,
+				   AFE_ADDA_MTKAIF_SYNCWORD_CFG,
+				   ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE,
+				   val);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk *clk = afe_priv->clk[MT8195_CLK_TOP_AUDIO_H_SEL];
+	struct clk *clk_parent;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		clk_parent = afe_priv->clk[MT8195_CLK_TOP_APLL1];
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		clk_parent = afe_priv->clk[MT8195_CLK_XTAL_26M];
+		break;
+	default:
+		return 0;
+	}
+	mt8195_afe_set_clk_parent(afe, clk, clk_parent);
+
+	return 0;
+}
+
+static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
+						       const char *name)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	int dai_id;
+
+	if (strstr(name, "aud_adc_hires"))
+		dai_id = MT8195_AFE_IO_UL_SRC1;
+	else if (strstr(name, "aud_adda6_adc_hires"))
+		dai_id = MT8195_AFE_IO_UL_SRC2;
+	else if (strstr(name, "aud_dac_hires"))
+		dai_id = MT8195_AFE_IO_DL_SRC;
+	else
+		return NULL;
+
+	return afe_priv->dai_priv[dai_id];
+}
+
+static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
+				      struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = source;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_adda_priv *adda_priv;
+
+	adda_priv = get_adda_priv_by_name(afe, w->name);
+
+	if (!adda_priv) {
+		dev_info(afe->dev, "adda_priv == NULL");
+		return 0;
+	}
+
+	return (adda_priv->hires_required) ? 1 : 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),
+};
+
+static const char * const adda_dlgain_mux_map[] = {
+	"Bypass", "Connect",
+};
+
+static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,
+			    SND_SOC_NOPM, 0,
+			    adda_dlgain_mux_map);
+
+static const struct snd_kcontrol_new adda_dlgain_mux_control =
+	SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);
+
+static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
+	SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I170", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I171", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_adda_o176_mix,
+			   ARRAY_SIZE(mtk_dai_adda_o176_mix)),
+	SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_adda_o177_mix,
+			   ARRAY_SIZE(mtk_dai_adda_o177_mix)),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
+			      AFE_ADDA_UL_DL_CON0,
+			      ADDA_AFE_ON_SHIFT, 0,
+			      NULL,
+			      0),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
+			      AFE_ADDA_DL_SRC2_CON0,
+			      DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,
+			      mtk_adda_dl_event,
+			      SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+			      AFE_ADDA_UL_SRC_CON0,
+			      UL_SRC_ON_TMP_CTL_SHIFT, 0,
+			      mtk_adda_ul_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA6 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+			      AFE_ADDA6_UL_SRC_CON0,
+			      UL_SRC_ON_TMP_CTL_SHIFT, 0,
+			      mtk_adda6_ul_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,
+			      SND_SOC_NOPM,
+			      0, 0,
+			      mtk_audio_hires_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+			      SND_SOC_NOPM,
+			      0, 0,
+			      mtk_adda_mtkaif_cfg_event,
+			      SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,
+			 &adda_dlgain_mux_control),
+
+	SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,
+			 DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),
+
+	SND_SOC_DAPM_INPUT("ADDA_INPUT"),
+	SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),
+
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc_hires"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
+	{"ADDA Capture", NULL, "ADDA Enable"},
+	{"ADDA Capture", NULL, "ADDA Capture Enable"},
+	{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
+	{"ADDA Capture", NULL, "aud_adc"},
+	{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
+	{"aud_adc_hires", NULL, "AUDIO_HIRES"},
+
+	{"ADDA6 Capture", NULL, "ADDA Enable"},
+	{"ADDA6 Capture", NULL, "ADDA6 Capture Enable"},
+	{"ADDA6 Capture", NULL, "ADDA_MTKAIF_CFG"},
+	{"ADDA6 Capture", NULL, "aud_adda6_adc"},
+	{"ADDA6 Capture", NULL, "aud_adda6_adc_hires",
+	mtk_afe_adda_hires_connect},
+	{"aud_adda6_adc_hires", NULL, "AUDIO_HIRES"},
+
+	{"I168", NULL, "ADDA Capture"},
+	{"I169", NULL, "ADDA Capture"},
+	{"I170", NULL, "ADDA6 Capture"},
+	{"I171", NULL, "ADDA6 Capture"},
+
+	{"ADDA Playback", NULL, "ADDA Enable"},
+	{"ADDA Playback", NULL, "ADDA Playback Enable"},
+	{"ADDA Playback", NULL, "aud_dac"},
+	{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
+	{"aud_dac_hires", NULL, "AUDIO_HIRES"},
+
+	{"DL_GAIN", NULL, "O176"},
+	{"DL_GAIN", NULL, "O177"},
+
+	{"DL_GAIN_MUX", "Bypass", "O176"},
+	{"DL_GAIN_MUX", "Bypass", "O177"},
+	{"DL_GAIN_MUX", "Connect", "DL_GAIN"},
+
+	{"ADDA Playback", NULL, "DL_GAIN_MUX"},
+
+	{"O176", "I000 Switch", "I000"},
+	{"O177", "I001 Switch", "I001"},
+
+	{"O176", "I002 Switch", "I002"},
+	{"O177", "I003 Switch", "I003"},
+
+	{"O176", "I020 Switch", "I020"},
+	{"O177", "I021 Switch", "I021"},
+
+	{"O176", "I022 Switch", "I022"},
+	{"O177", "I023 Switch", "I023"},
+
+	{"O176", "I070 Switch", "I070"},
+	{"O177", "I071 Switch", "I071"},
+
+	{"ADDA Capture", NULL, "ADDA_INPUT"},
+	{"ADDA6 Capture", NULL, "ADDA_INPUT"},
+	{"ADDA_OUTPUT", NULL, "ADDA Playback"},
+};
+
+static int mt8195_adda_dl_gain_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+	unsigned int reg = AFE_ADDA_DL_SRC2_CON1;
+	unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;
+	unsigned int value = (unsigned int)(ucontrol->value.integer.value[0]);
+
+	regmap_update_bits(afe->regmap, reg, mask, DL_2_GAIN_CTL_PRE(value));
+	return 0;
+}
+
+static int mt8195_adda_dl_gain_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+	unsigned int reg = AFE_ADDA_DL_SRC2_CON1;
+	unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;
+	unsigned int value = 0;
+
+	regmap_read(afe->regmap, reg, &value);
+
+	ucontrol->value.integer.value[0] = ((value & mask) >>
+					    DL_2_GAIN_CTL_PRE_SHIFT);
+	return 0;
+}
+
+static int mt8195_adda6_only_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	ucontrol->value.integer.value[0] = param->mtkaif_adda6_only;
+	return 0;
+}
+
+static int mt8195_adda6_only_set(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int mtkaif_adda6_only;
+
+	mtkaif_adda6_only = ucontrol->value.integer.value[0];
+
+	dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n",
+		 __func__, kcontrol->id.name, mtkaif_adda6_only);
+
+	param->mtkaif_adda6_only = mtkaif_adda6_only;
+
+	return 0;
+}
+
+static int mt8195_adda_dmic_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;
+	return 0;
+}
+
+static int mt8195_adda_dmic_set(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int dmic_on;
+
+	dmic_on = ucontrol->value.integer.value[0];
+
+	dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
+		__func__, kcontrol->id.name, dmic_on);
+
+	param->mtkaif_dmic_on = dmic_on;
+	return 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_controls[] = {
+	SOC_SINGLE_EXT("ADDA_DL_Gain", SND_SOC_NOPM, 0, 65535, 0,
+		       mt8195_adda_dl_gain_get, mt8195_adda_dl_gain_put),
+	SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC", 0,
+			    mt8195_adda_dmic_get, mt8195_adda_dmic_set),
+	SOC_SINGLE_BOOL_EXT("MTKAIF_ADDA6_ONLY", 0,
+			    mt8195_adda6_only_get,
+			    mt8195_adda6_only_set),
+};
+
+static int mtk_dai_da_configure(struct mtk_base_afe *afe,
+				unsigned int rate, int id)
+{
+	unsigned int val = 0;
+	unsigned int mask = 0;
+
+	/* set sampling rate */
+	mask |= DL_2_INPUT_MODE_CTL_MASK;
+	val |= DL_2_INPUT_MODE_CTL(afe_adda_dl_rate_transform(afe, rate));
+
+	/* turn off saturation */
+	mask |= DL_2_CH1_SATURATION_EN_CTL;
+	mask |= DL_2_CH2_SATURATION_EN_CTL;
+
+	/* turn off mute function */
+	mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+	mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+	val |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+	val |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+
+	/* set voice input data if input sample rate is 8k or 16k */
+	mask |= DL_2_VOICE_MODE_CTL_PRE;
+	if (rate == 8000 || rate == 16000)
+		val |= DL_2_VOICE_MODE_CTL_PRE;
+
+	regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);
+
+	mask = 0;
+	val = 0;
+
+	/* new 2nd sdm */
+	mask |= DL_USE_NEW_2ND_SDM;
+	val |= DL_USE_NEW_2ND_SDM;
+	regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, mask, val);
+
+	return 0;
+}
+
+static int mtk_dai_ad_configure(struct mtk_base_afe *afe,
+				unsigned int rate, int id)
+{
+	unsigned int val = 0;
+	unsigned int mask = 0;
+
+	mask |= UL_VOICE_MODE_CTL_MASK;
+	val |= UL_VOICE_MODE_CTL(afe_adda_ul_rate_transform(afe, rate));
+
+	switch (id) {
+	case MT8195_AFE_IO_UL_SRC1:
+		regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
+				   mask, val);
+		break;
+	case MT8195_AFE_IO_UL_SRC2:
+		regmap_update_bits(afe->regmap, AFE_ADDA6_UL_SRC_CON0,
+				   mask, val);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id];
+	unsigned int rate = params_rate(params);
+	int id = dai->id;
+	int ret = 0;
+
+	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
+		__func__, id, substream->stream, rate);
+
+	if (rate > ADDA_HIRES_THRES)
+		adda_priv->hires_required = 1;
+	else
+		adda_priv->hires_required = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ret = mtk_dai_da_configure(afe, rate, id);
+	else
+		ret = mtk_dai_ad_configure(afe, rate, id);
+
+	return ret;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
+	.hw_params = mtk_dai_adda_hw_params,
+};
+
+/* dai driver */
+#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
+				 SNDRV_PCM_RATE_96000 |\
+				 SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
+				SNDRV_PCM_RATE_16000 |\
+				SNDRV_PCM_RATE_32000 |\
+				SNDRV_PCM_RATE_48000 |\
+				SNDRV_PCM_RATE_96000 |\
+				SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+			  SNDRV_PCM_FMTBIT_S24_LE |\
+			  SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
+	{
+		.name = "DL_SRC",
+		.id = MT8195_AFE_IO_DL_SRC,
+		.playback = {
+			.stream_name = "ADDA Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_PLAYBACK_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+	{
+		.name = "UL_SRC1",
+		.id = MT8195_AFE_IO_UL_SRC1,
+		.capture = {
+			.stream_name = "ADDA Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_CAPTURE_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+	{
+		.name = "UL_SRC2",
+		.id = MT8195_AFE_IO_UL_SRC2,
+		.capture = {
+			.stream_name = "ADDA6 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_CAPTURE_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+};
+
+static int init_adda_priv_data(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_adda_priv *adda_priv;
+	int adda_dai_list[] = { MT8195_AFE_IO_DL_SRC,
+				MT8195_AFE_IO_UL_SRC1,
+				MT8195_AFE_IO_UL_SRC2};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
+		adda_priv = devm_kzalloc(afe->dev,
+					 sizeof(struct mtk_dai_adda_priv),
+					 GFP_KERNEL);
+		if (!adda_priv)
+			return -ENOMEM;
+
+		afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
+	}
+
+	return 0;
+}
+
+int mt8195_dai_adda_register(struct mtk_base_afe *afe)
+{
+	struct mtk_base_afe_dai *dai;
+
+	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+
+	list_add(&dai->list, &afe->sub_dais);
+
+	dai->dai_drivers = mtk_dai_adda_driver;
+	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
+
+	dai->dapm_widgets = mtk_dai_adda_widgets;
+	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
+	dai->dapm_routes = mtk_dai_adda_routes;
+	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
+	dai->controls = mtk_dai_adda_controls;
+	dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);
+
+	return init_adda_priv_data(afe);
+}
-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:14 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:14 +0800
Subject: [PATCH v4 10/11] ASoC: mediatek: mt8195: add HDMITX audio support
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-11-trevor.wu@mediatek.com>

This patch adds HDMITX audio support on mt8195-mt6359-rt1019-rt5682 board.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
index d853bc445753..e4472bbc9f01 100644
--- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
@@ -28,6 +28,7 @@
 struct mt8195_mt6359_rt1019_rt5682_priv {
 	struct snd_soc_jack headset_jack;
 	struct snd_soc_jack dp_jack;
+	struct snd_soc_jack hdmi_jack;
 };
 
 static const struct snd_soc_dapm_widget
@@ -407,6 +408,22 @@ static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
 	return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL);
 }
 
+static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+		snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	int ret = 0;
+
+	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
+				    &priv->hdmi_jack, NULL, 0);
+	if (ret)
+		return ret;
+
+	return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
+}
+
 static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 					      struct snd_pcm_hw_params *params)
 
@@ -936,6 +953,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
 			SND_SOC_DAIFMT_NB_NF |
 			SND_SOC_DAIFMT_CBS_CFS,
 		.dpcm_playback = 1,
+		.be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup,
 		SND_SOC_DAILINK_REG(ETDM3_OUT_BE),
 	},
 	[DAI_LINK_PCM1_BE] = {
@@ -1008,6 +1026,26 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
 			dai_link->codecs->dai_name = "i2s-hifi";
 			dai_link->init = mt8195_dptx_codec_init;
 		}
+
+		if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
+			dai_link->codecs->of_node =
+				of_parse_phandle(machine_node,
+						 "mediatek,hdmi-codec", 0);
+#else
+			dai_link->codecs->of_node =
+				of_parse_phandle(pdev->dev.of_node,
+						 "mediatek,hdmi-codec", 0);
+#endif
+			if (!dai_link->codecs->of_node) {
+				dev_err(&pdev->dev, "Property 'hdmi-codec' missing or invalid\n");
+				return -EINVAL;
+			}
+
+			dai_link->codecs->name = NULL;
+			dai_link->codecs->dai_name = "i2s-hifi";
+			dai_link->init = mt8195_hdmi_codec_init;
+		}
 	}
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:13 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:13 +0800
Subject: [PATCH v4 09/11] ASoC: mediatek: mt8195: add DPTX audio support
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-10-trevor.wu@mediatek.com>

This patch adds DPTX audio support on mt8195-mt6359-rt1019-rt5682 board.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/Kconfig                    |  1 +
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 88 +++++++++++++++++--
 2 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index bfee954d0c7c..cf567a89f421 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -202,6 +202,7 @@ config SND_SOC_MT8195_MT6359_RT1019_RT5682
 	select SND_SOC_RT1015P
 	select SND_SOC_RT5682_I2C
 	select SND_SOC_DMIC
+	select SND_SOC_HDMI_CODEC
 	help
 	  This adds ASoC driver for Mediatek MT8195 boards
 	  with the MT6359 RT1019 RT5682 audio codec.
diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
index 39b33aecc1e9..d853bc445753 100644
--- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
@@ -27,6 +27,7 @@
 
 struct mt8195_mt6359_rt1019_rt5682_priv {
 	struct snd_soc_jack headset_jack;
+	struct snd_soc_jack dp_jack;
 };
 
 static const struct snd_soc_dapm_widget
@@ -327,6 +328,52 @@ static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 	return 0;
 }
 
+static int mt8195_hdmitx_dptx_startup(struct snd_pcm_substream *substream)
+{
+	static const unsigned int rates[] = {
+		48000
+	};
+	static const unsigned int channels[] = {
+		2, 4, 6, 8
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list  = rates,
+		.mask = 0,
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list  = channels,
+		.mask = 0,
+	};
+
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_rates);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+		return ret;
+	}
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_CHANNELS,
+					 &constraints_channels);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops mt8195_hdmitx_dptx_playback_ops = {
+	.startup = mt8195_hdmitx_dptx_startup,
+};
+
 static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params)
 {
@@ -344,8 +391,25 @@ static struct snd_soc_ops mt8195_dptx_ops = {
 	.hw_params = mt8195_dptx_hw_params,
 };
 
-static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
-				       struct snd_pcm_hw_params *params)
+static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+		snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	int ret = 0;
+
+	ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT,
+				    &priv->dp_jack, NULL, 0);
+	if (ret)
+		return ret;
+
+	return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL);
+}
+
+static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					      struct snd_pcm_hw_params *params)
+
 {
 	/* fix BE i2s format to 32bit, clean param mask first */
 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
@@ -687,6 +751,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
 		},
 		.dynamic = 1,
 		.dpcm_playback = 1,
+		.ops = &mt8195_hdmitx_dptx_playback_ops,
 		SND_SOC_DAILINK_REG(DL10_FE),
 	},
 	[DAI_LINK_DL11_FE] = {
@@ -820,7 +885,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
 		.no_pcm = 1,
 		.dpcm_playback = 1,
 		.ops = &mt8195_dptx_ops,
-		.be_hw_params_fixup = mt8195_dptx_hw_params_fixup,
+		.be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup,
 		SND_SOC_DAILINK_REG(DPTX_BE),
 	},
 	[DAI_LINK_ETDM1_IN_BE] = {
@@ -915,7 +980,6 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
 	struct device_node *platform_node;
 	struct snd_soc_dai_link *dai_link;
 	struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL;
-
 	int ret, i;
 
 	card->dev = &pdev->dev;
@@ -930,6 +994,20 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
 	for_each_card_prelinks(card, i, dai_link) {
 		if (!dai_link->platforms->name)
 			dai_link->platforms->of_node = platform_node;
+
+		if (strcmp(dai_link->name, "DPTX_BE") == 0) {
+			dai_link->codecs->of_node =
+				of_parse_phandle(pdev->dev.of_node,
+						 "mediatek,dptx-codec", 0);
+			if (!dai_link->codecs->of_node) {
+				dev_err(&pdev->dev, "Property 'dptx-codec' missing or invalid\n");
+				return -EINVAL;
+			}
+
+			dai_link->codecs->name = NULL;
+			dai_link->codecs->dai_name = "i2s-hifi";
+			dai_link->init = mt8195_dptx_codec_init;
+		}
 	}
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -940,7 +1018,7 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
 
 	ret = devm_snd_soc_register_card(&pdev->dev, card);
 	if (ret)
-		dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
 	return ret;
 }
-- 
2.18.0

From trevor.wu at mediatek.com  Wed Aug 18 03:32:12 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 18 Aug 2021 18:32:12 +0800
Subject: [PATCH v4 08/11] ASoC: mediatek: mt8195: add machine driver with
 mt6359, rt1019 and rt5682
In-Reply-To: <20210818103215.9186-1-trevor.wu@mediatek.com>
References: <20210818103215.9186-1-trevor.wu@mediatek.com>
Message-ID: <20210818103215.9186-9-trevor.wu@mediatek.com>

This patch adds support for mt8195 board with mt6359, rt1019 and rt5682.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 sound/soc/mediatek/Kconfig                    |  14 +
 sound/soc/mediatek/mt8195/Makefile            |   3 +
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 977 ++++++++++++++++++
 3 files changed, 994 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 3389f382be06..bfee954d0c7c 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -193,3 +193,17 @@ config SND_SOC_MT8195
 	  that can be used with other codecs.
 	  Select Y if you have such device.
 	  If unsure select "N".
+
+config SND_SOC_MT8195_MT6359_RT1019_RT5682
+	tristate "ASoC Audio driver for MT8195 with MT6359 RT1019 RT5682 codec"
+	depends on I2C
+	depends on SND_SOC_MT8195
+	select SND_SOC_MT6359
+	select SND_SOC_RT1015P
+	select SND_SOC_RT5682_I2C
+	select SND_SOC_DMIC
+	help
+	  This adds ASoC driver for Mediatek MT8195 boards
+	  with the MT6359 RT1019 RT5682 audio codec.
+	  Select Y if you have such device.
+	  If unsure select "N".
diff --git a/sound/soc/mediatek/mt8195/Makefile b/sound/soc/mediatek/mt8195/Makefile
index 6529dd5beb2b..44775f400b40 100644
--- a/sound/soc/mediatek/mt8195/Makefile
+++ b/sound/soc/mediatek/mt8195/Makefile
@@ -10,3 +10,6 @@ snd-soc-mt8195-afe-objs := \
 	mt8195-dai-pcm.o
 
 obj-$(CONFIG_SND_SOC_MT8195) += snd-soc-mt8195-afe.o
+
+# machine driver
+obj-$(CONFIG_SND_SOC_MT8195_MT6359_RT1019_RT5682) += mt8195-mt6359-rt1019-rt5682.o
diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
new file mode 100644
index 000000000000..39b33aecc1e9
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
@@ -0,0 +1,977 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// mt8195-mt6359-rt1019-rt5682.c  --
+//	MT8195-MT6359-RT1019-RT6358 ALSA SoC machine driver
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Trevor Wu <trevor.wu at mediatek.com>
+//
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/rt5682.h>
+#include <sound/soc.h>
+#include "../../codecs/mt6359.h"
+#include "../../codecs/rt5682.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "mt8195-afe-common.h"
+
+#define RT1019_CODEC_DAI	"HiFi"
+#define RT1019_DEV0_NAME	"rt1019p"
+
+#define RT5682_CODEC_DAI	"rt5682-aif1"
+#define RT5682_DEV0_NAME	"rt5682.2-001a"
+
+struct mt8195_mt6359_rt1019_rt5682_priv {
+	struct snd_soc_jack headset_jack;
+};
+
+static const struct snd_soc_dapm_widget
+	mt8195_mt6359_rt1019_rt5682_widgets[] = {
+	SND_SOC_DAPM_SPK("Speakers", NULL),
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = {
+	/* speaker */
+	{ "Speakers", NULL, "Speaker" },
+	/* headset */
+	{ "Headphone Jack", NULL, "HPOL" },
+	{ "Headphone Jack", NULL, "HPOR" },
+	{ "IN1P", NULL, "Headset Mic" },
+};
+
+static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Speakers"),
+	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+	unsigned int rate = params_rate(params);
+	unsigned int mclk_fs_ratio = 128;
+	unsigned int mclk_fs = rate * mclk_fs_ratio;
+	int bitwidth;
+	int ret;
+
+	bitwidth = snd_pcm_format_width(params_format(params));
+	if (bitwidth < 0) {
+		dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
+		return bitwidth;
+	}
+
+	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
+	if (ret) {
+		dev_err(card->dev, "failed to set tdm slot\n");
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
+				  RT5682_PLL1_S_BCLK1,
+				  params_rate(params) * 64,
+				  params_rate(params) * 512);
+	if (ret) {
+		dev_err(card->dev, "failed to set pll\n");
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(codec_dai,
+				     RT5682_SCLK_S_PLL1,
+				     params_rate(params) * 512,
+				     SND_SOC_CLOCK_IN);
+	if (ret) {
+		dev_err(card->dev, "failed to set sysclk\n");
+		return ret;
+	}
+
+	return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
+}
+
+static const struct snd_soc_ops mt8195_rt5682_etdm_ops = {
+	.hw_params = mt8195_rt5682_etdm_hw_params,
+};
+
+#define CKSYS_AUD_TOP_CFG 0x032c
+#define CKSYS_AUD_TOP_MON 0x0330
+
+static int mt8195_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_afe =
+		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int phase;
+	unsigned int monitor;
+	int mtkaif_calibration_num_phase;
+	int test_done_1, test_done_2, test_done_3;
+	int cycle_1, cycle_2, cycle_3;
+	int prev_cycle_1, prev_cycle_2, prev_cycle_3;
+	int chosen_phase_1, chosen_phase_2, chosen_phase_3;
+	int counter;
+	bool mtkaif_calibration_ok;
+	int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM];
+	int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM];
+	int i;
+
+	dev_info(afe->dev, "%s(), start\n", __func__);
+
+	param->mtkaif_calibration_ok = false;
+	for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) {
+		param->mtkaif_chosen_phase[i] = -1;
+		param->mtkaif_phase_cycle[i] = 0;
+		mtkaif_chosen_phase[i] = -1;
+		mtkaif_phase_cycle[i] = 0;
+	}
+
+	if (IS_ERR(afe_priv->topckgen)) {
+		dev_info(afe->dev, "%s() Cannot find topckgen controller\n",
+			 __func__);
+		return 0;
+	}
+
+	pm_runtime_get_sync(afe->dev);
+	mt6359_mtkaif_calibration_enable(cmpnt_codec);
+
+	/* set test type to synchronizer pulse */
+	regmap_update_bits(afe_priv->topckgen,
+			   CKSYS_AUD_TOP_CFG, 0xffff, 0x4);
+	mtkaif_calibration_num_phase = 42;	/* mt6359: 0 ~ 42 */
+	mtkaif_calibration_ok = true;
+
+	for (phase = 0;
+	     phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok;
+	     phase++) {
+		mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+						    phase, phase, phase);
+
+		regmap_update_bits(afe_priv->topckgen,
+				   CKSYS_AUD_TOP_CFG, 0x1, 0x1);
+
+		test_done_1 = 0;
+		test_done_2 = 0;
+		test_done_3 = 0;
+		cycle_1 = -1;
+		cycle_2 = -1;
+		cycle_3 = -1;
+		counter = 0;
+		while (!(test_done_1 & test_done_2 & test_done_3)) {
+			regmap_read(afe_priv->topckgen,
+				    CKSYS_AUD_TOP_MON, &monitor);
+			test_done_1 = (monitor >> 28) & 0x1;
+			test_done_2 = (monitor >> 29) & 0x1;
+			test_done_3 = (monitor >> 30) & 0x1;
+			if (test_done_1 == 1)
+				cycle_1 = monitor & 0xf;
+
+			if (test_done_2 == 1)
+				cycle_2 = (monitor >> 4) & 0xf;
+
+			if (test_done_3 == 1)
+				cycle_3 = (monitor >> 8) & 0xf;
+
+			/* handle if never test done */
+			if (++counter > 10000) {
+				dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n",
+					 __func__,
+					 cycle_1, cycle_2, cycle_3, monitor);
+				mtkaif_calibration_ok = false;
+				break;
+			}
+		}
+
+		if (phase == 0) {
+			prev_cycle_1 = cycle_1;
+			prev_cycle_2 = cycle_2;
+			prev_cycle_3 = cycle_3;
+		}
+
+		if (cycle_1 != prev_cycle_1 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1;
+		}
+
+		if (cycle_2 != prev_cycle_2 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2;
+		}
+
+		if (cycle_3 != prev_cycle_3 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3;
+		}
+
+		regmap_update_bits(afe_priv->topckgen,
+				   CKSYS_AUD_TOP_CFG, 0x1, 0x0);
+
+		if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0)
+			break;
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_1 = 0;
+	} else {
+		chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0];
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_2 = 0;
+	} else {
+		chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1];
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_3 = 0;
+	} else {
+		chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2];
+	}
+
+	mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+					    chosen_phase_1,
+					    chosen_phase_2,
+					    chosen_phase_3);
+
+	mt6359_mtkaif_calibration_disable(cmpnt_codec);
+	pm_runtime_put(afe->dev);
+
+	param->mtkaif_calibration_ok = mtkaif_calibration_ok;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3;
+	for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++)
+		param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];
+
+	dev_info(afe->dev, "%s(), end, calibration ok %d\n",
+		 __func__, param->mtkaif_calibration_ok);
+
+	return 0;
+}
+
+static int mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+
+	/* set mtkaif protocol */
+	mt6359_set_mtkaif_protocol(cmpnt_codec,
+				   MT6359_MTKAIF_PROTOCOL_2_CLK_P2);
+
+	/* mtkaif calibration */
+	mt8195_mt6359_mtkaif_calibration(rtd);
+
+	return 0;
+}
+
+static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+		snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_jack *jack = &priv->headset_jack;
+	int ret;
+
+	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
+				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
+				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
+				    SND_JACK_BTN_3,
+				    jack, NULL, 0);
+	if (ret) {
+		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+		return ret;
+	}
+
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+	ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
+	if (ret) {
+		dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+};
+
+static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				       struct snd_pcm_hw_params *params)
+{
+	/* fix BE i2s format to 32bit, clean param mask first */
+	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
+
+	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+	return 0;
+}
+
+static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+	unsigned int rate = params_rate(params);
+	unsigned int mclk_fs_ratio = 256;
+	unsigned int mclk_fs = rate * mclk_fs_ratio;
+
+	return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs,
+				      SND_SOC_CLOCK_OUT);
+}
+
+static struct snd_soc_ops mt8195_dptx_ops = {
+	.hw_params = mt8195_dptx_hw_params,
+};
+
+static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				       struct snd_pcm_hw_params *params)
+{
+	/* fix BE i2s format to 32bit, clean param mask first */
+	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
+
+	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+	return 0;
+}
+
+static int mt8195_playback_startup(struct snd_pcm_substream *substream)
+{
+	static const unsigned int rates[] = {
+		48000
+	};
+	static const unsigned int channels[] = {
+		2
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list  = rates,
+		.mask = 0,
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list  = channels,
+		.mask = 0,
+	};
+
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_rates);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+		return ret;
+	}
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_CHANNELS,
+					 &constraints_channels);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops mt8195_playback_ops = {
+	.startup = mt8195_playback_startup,
+};
+
+static int mt8195_capture_startup(struct snd_pcm_substream *substream)
+{
+	static const unsigned int rates[] = {
+		48000
+	};
+	static const unsigned int channels[] = {
+		1, 2
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list  = rates,
+		.mask = 0,
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list  = channels,
+		.mask = 0,
+	};
+
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_rates);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+		return ret;
+	}
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_CHANNELS,
+					 &constraints_channels);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops mt8195_capture_ops = {
+	.startup = mt8195_capture_startup,
+};
+
+enum {
+	DAI_LINK_DL2_FE,
+	DAI_LINK_DL3_FE,
+	DAI_LINK_DL6_FE,
+	DAI_LINK_DL7_FE,
+	DAI_LINK_DL8_FE,
+	DAI_LINK_DL10_FE,
+	DAI_LINK_DL11_FE,
+	DAI_LINK_UL1_FE,
+	DAI_LINK_UL2_FE,
+	DAI_LINK_UL3_FE,
+	DAI_LINK_UL4_FE,
+	DAI_LINK_UL5_FE,
+	DAI_LINK_UL6_FE,
+	DAI_LINK_UL8_FE,
+	DAI_LINK_UL9_FE,
+	DAI_LINK_UL10_FE,
+	DAI_LINK_DL_SRC_BE,
+	DAI_LINK_DPTX_BE,
+	DAI_LINK_ETDM1_IN_BE,
+	DAI_LINK_ETDM2_IN_BE,
+	DAI_LINK_ETDM1_OUT_BE,
+	DAI_LINK_ETDM2_OUT_BE,
+	DAI_LINK_ETDM3_OUT_BE,
+	DAI_LINK_PCM1_BE,
+	DAI_LINK_UL_SRC1_BE,
+	DAI_LINK_UL_SRC2_BE,
+};
+
+/* FE */
+SND_SOC_DAILINK_DEFS(DL2_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL3_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL6_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL7_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL8_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL10_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL10")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL11_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL11")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL1_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL2_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL3_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL4_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL5_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL6_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL8_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL8")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL9_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL9")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL10_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL10")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+/* BE */
+SND_SOC_DAILINK_DEFS(DL_SRC_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif1")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DPTX_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM1_IN_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM2_IN_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME,
+						   RT5682_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME,
+						   RT5682_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME,
+						   RT1019_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(PCM1_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL_SRC1_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif1"),
+					COMP_CODEC("dmic-codec",
+						   "dmic-hifi")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL_SRC2_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif2")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
+	/* FE */
+	[DAI_LINK_DL2_FE] = {
+		.name = "DL2_FE",
+		.stream_name = "DL2 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL2_FE),
+	},
+	[DAI_LINK_DL3_FE] = {
+		.name = "DL3_FE",
+		.stream_name = "DL3 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL3_FE),
+	},
+	[DAI_LINK_DL6_FE] = {
+		.name = "DL6_FE",
+		.stream_name = "DL6 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL6_FE),
+	},
+	[DAI_LINK_DL7_FE] = {
+		.name = "DL7_FE",
+		.stream_name = "DL7 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL7_FE),
+	},
+	[DAI_LINK_DL8_FE] = {
+		.name = "DL8_FE",
+		.stream_name = "DL8 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL8_FE),
+	},
+	[DAI_LINK_DL10_FE] = {
+		.name = "DL10_FE",
+		.stream_name = "DL10 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL10_FE),
+	},
+	[DAI_LINK_DL11_FE] = {
+		.name = "DL11_FE",
+		.stream_name = "DL11 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL11_FE),
+	},
+	[DAI_LINK_UL1_FE] = {
+		.name = "UL1_FE",
+		.stream_name = "UL1 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL1_FE),
+	},
+	[DAI_LINK_UL2_FE] = {
+		.name = "UL2_FE",
+		.stream_name = "UL2 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL2_FE),
+	},
+	[DAI_LINK_UL3_FE] = {
+		.name = "UL3_FE",
+		.stream_name = "UL3 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL3_FE),
+	},
+	[DAI_LINK_UL4_FE] = {
+		.name = "UL4_FE",
+		.stream_name = "UL4 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL4_FE),
+	},
+	[DAI_LINK_UL5_FE] = {
+		.name = "UL5_FE",
+		.stream_name = "UL5 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL5_FE),
+	},
+	[DAI_LINK_UL6_FE] = {
+		.name = "UL6_FE",
+		.stream_name = "UL6 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL6_FE),
+	},
+	[DAI_LINK_UL8_FE] = {
+		.name = "UL8_FE",
+		.stream_name = "UL8 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL8_FE),
+	},
+	[DAI_LINK_UL9_FE] = {
+		.name = "UL9_FE",
+		.stream_name = "UL9 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL9_FE),
+	},
+	[DAI_LINK_UL10_FE] = {
+		.name = "UL10_FE",
+		.stream_name = "UL10 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL10_FE),
+	},
+	/* BE */
+	[DAI_LINK_DL_SRC_BE] = {
+		.name = "DL_SRC_BE",
+		.init = mt8195_mt6359_init,
+		.no_pcm = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL_SRC_BE),
+	},
+	[DAI_LINK_DPTX_BE] = {
+		.name = "DPTX_BE",
+		.no_pcm = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_dptx_ops,
+		.be_hw_params_fixup = mt8195_dptx_hw_params_fixup,
+		SND_SOC_DAILINK_REG(DPTX_BE),
+	},
+	[DAI_LINK_ETDM1_IN_BE] = {
+		.name = "ETDM1_IN_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(ETDM1_IN_BE),
+	},
+	[DAI_LINK_ETDM2_IN_BE] = {
+		.name = "ETDM2_IN_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		.init = mt8195_rt5682_init,
+		.ops = &mt8195_rt5682_etdm_ops,
+		.be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
+		SND_SOC_DAILINK_REG(ETDM2_IN_BE),
+	},
+	[DAI_LINK_ETDM1_OUT_BE] = {
+		.name = "ETDM1_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		.ops = &mt8195_rt5682_etdm_ops,
+		.be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
+		SND_SOC_DAILINK_REG(ETDM1_OUT_BE),
+	},
+	[DAI_LINK_ETDM2_OUT_BE] = {
+		.name = "ETDM2_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(ETDM2_OUT_BE),
+	},
+	[DAI_LINK_ETDM3_OUT_BE] = {
+		.name = "ETDM3_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(ETDM3_OUT_BE),
+	},
+	[DAI_LINK_PCM1_BE] = {
+		.name = "PCM1_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(PCM1_BE),
+	},
+	[DAI_LINK_UL_SRC1_BE] = {
+		.name = "UL_SRC1_BE",
+		.no_pcm = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL_SRC1_BE),
+	},
+	[DAI_LINK_UL_SRC2_BE] = {
+		.name = "UL_SRC2_BE",
+		.no_pcm = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL_SRC2_BE),
+	},
+};
+
+static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = {
+	.name = "mt8195_r1019_5682",
+	.owner = THIS_MODULE,
+	.dai_link = mt8195_mt6359_rt1019_rt5682_dai_links,
+	.num_links = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links),
+	.controls = mt8195_mt6359_rt1019_rt5682_controls,
+	.num_controls = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_controls),
+	.dapm_widgets = mt8195_mt6359_rt1019_rt5682_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets),
+	.dapm_routes = mt8195_mt6359_rt1019_rt5682_routes,
+	.num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes),
+};
+
+static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = &mt8195_mt6359_rt1019_rt5682_soc_card;
+	struct device_node *platform_node;
+	struct snd_soc_dai_link *dai_link;
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL;
+
+	int ret, i;
+
+	card->dev = &pdev->dev;
+
+	platform_node = of_parse_phandle(pdev->dev.of_node,
+					 "mediatek,platform", 0);
+	if (!platform_node) {
+		dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n");
+		return -EINVAL;
+	}
+
+	for_each_card_prelinks(card, i, dai_link) {
+		if (!dai_link->platforms->name)
+			dai_link->platforms->of_node = platform_node;
+	}
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	snd_soc_card_set_drvdata(card, priv);
+
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+	if (ret)
+		dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+			__func__, ret);
+	return ret;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id mt8195_mt6359_rt1019_rt5682_dt_match[] = {
+	{.compatible = "mediatek,mt8195_mt6359_rt1019_rt5682",},
+	{}
+};
+#endif
+
+static const struct dev_pm_ops mt8195_mt6359_rt1019_rt5682_pm_ops = {
+	.poweroff = snd_soc_poweroff,
+	.restore = snd_soc_resume,
+};
+
+static struct platform_driver mt8195_mt6359_rt1019_rt5682_driver = {
+	.driver = {
+		.name = "mt8195_mt6359_rt1019_rt5682",
+#ifdef CONFIG_OF
+		.of_match_table = mt8195_mt6359_rt1019_rt5682_dt_match,
+#endif
+		.pm = &mt8195_mt6359_rt1019_rt5682_pm_ops,
+	},
+	.probe = mt8195_mt6359_rt1019_rt5682_dev_probe,
+};
+
+module_platform_driver(mt8195_mt6359_rt1019_rt5682_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("MT8195-MT6359-RT1019-RT5682 ALSA SoC machine driver");
+MODULE_AUTHOR("Trevor Wu <trevor.wu at mediatek.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("mt8195_mt6359_rt1019_rt5682 soc card");
-- 
2.18.0

From will at kernel.org  Wed Aug 18 03:42:28 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 11:42:28 +0100
Subject: [PATCH v11 08/16] sched: Allow task CPU affinity to be
 restricted on asymmetric systems
In-Reply-To: <YRvRfZ/NnuNyIu3s@hirez.programming.kicks-ass.net>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-9-will@kernel.org>
 <YRvRfZ/NnuNyIu3s@hirez.programming.kicks-ass.net>
Message-ID: <20210818104227.GA13828@willie-the-truck>

Hi Peter,

On Tue, Aug 17, 2021 at 05:10:53PM +0200, Peter Zijlstra wrote:
> On Fri, Jul 30, 2021 at 12:24:35PM +0100, Will Deacon wrote:
> > @@ -2783,20 +2778,173 @@ static int __set_cpus_allowed_ptr(struct task_struct *p,
> >  
> >  	__do_set_cpus_allowed(p, new_mask, flags);
> >  
> > -	return affine_move_task(rq, p, &rf, dest_cpu, flags);
> > +	if (flags & SCA_USER)
> > +		release_user_cpus_ptr(p);
> > +
> > +	return affine_move_task(rq, p, rf, dest_cpu, flags);
> >  
> >  out:
> > -	task_rq_unlock(rq, p, &rf);
> > +	task_rq_unlock(rq, p, rf);
> >  
> >  	return ret;
> >  }
> 
> > +void relax_compatible_cpus_allowed_ptr(struct task_struct *p)
> > +{
> > +	unsigned long flags;
> > +	struct cpumask *mask = p->user_cpus_ptr;
> > +
> > +	/*
> > +	 * Try to restore the old affinity mask. If this fails, then
> > +	 * we free the mask explicitly to avoid it being inherited across
> > +	 * a subsequent fork().
> > +	 */
> > +	if (!mask || !__sched_setaffinity(p, mask))
> > +		return;
> > +
> > +	raw_spin_lock_irqsave(&p->pi_lock, flags);
> > +	release_user_cpus_ptr(p);
> > +	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
> > +}
> 
> Both these are a problem on RT.

Ah, sorry. I didn't realise you couldn't _free_ with a raw lock held in RT.
Is there somewhere I can read up on that?

> The easiest recourse is simply never freeing the CPU mask (except on
> exit). The alternative is something like the below I suppose..
> 
> I'm leaning towards the former option, wdyt?

Defering the freeing until exit feels like a little fiddly, as we still
want to clear ->user_cpus_ptr on affinity changes when SCA_USER is set
so we'd have to keep track of the mask somewhere and reuse it instead
of allocating a new one if we need it later on. Do-able, but feels a bit
nasty, particular across fork().

As for your other suggestion:

> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -2733,6 +2733,7 @@ static int __set_cpus_allowed_ptr_locked
>  	const struct cpumask *cpu_allowed_mask = task_cpu_possible_mask(p);
>  	const struct cpumask *cpu_valid_mask = cpu_active_mask;
>  	bool kthread = p->flags & PF_KTHREAD;
> +	struct cpumask *user_mask = NULL;
>  	unsigned int dest_cpu;
>  	int ret = 0;
>  
> @@ -2792,9 +2793,13 @@ static int __set_cpus_allowed_ptr_locked
>  	__do_set_cpus_allowed(p, new_mask, flags);
>  
>  	if (flags & SCA_USER)
> -		release_user_cpus_ptr(p);
> +		swap(user_mask, p->user_cpus_ptr);
> +
> +	ret = affine_move_task(rq, p, rf, dest_cpu, flags);
> +
> +	kfree(user_mask);
>  
> -	return affine_move_task(rq, p, rf, dest_cpu, flags);
> +	return ret;
>  
>  out:
>  	task_rq_unlock(rq, p, rf);
> @@ -2954,8 +2959,10 @@ void relax_compatible_cpus_allowed_ptr(s
>  		return;
>  
>  	raw_spin_lock_irqsave(&p->pi_lock, flags);
> -	release_user_cpus_ptr(p);
> +	p->user_cpus_ptr = NULL;
>  	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
> +
> +	kfree(mask);

I think the idea looks good, but perhaps we could wrap things up a bit:

/* Comment about why this is useful with RT */
static cpumask_t *clear_user_cpus_ptr(struct task_struct *p)
{
	struct cpumask *user_mask = NULL;

	swap(user_mask, p->user_cpus_ptr);
	return user_mask;
}

void release_user_cpus_ptr(struct task_struct *p)
{
	kfree(clear_user_cpus_ptr(p));
}

Then just use clear_user_cpus_ptr() in sched/core.c where we know what
we're doing (well, at least one of us does!).

Will


From will at kernel.org  Wed Aug 18 03:43:11 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 11:43:11 +0100
Subject: [PATCH v11 08/16] sched: Allow task CPU affinity to be
 restricted on asymmetric systems
In-Reply-To: <YRvYtlyhuRpFi/Th@hirez.programming.kicks-ass.net>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-9-will@kernel.org>
 <YRvYtlyhuRpFi/Th@hirez.programming.kicks-ass.net>
Message-ID: <20210818104311.GB13828@willie-the-truck>

On Tue, Aug 17, 2021 at 05:41:42PM +0200, Peter Zijlstra wrote:
> On Fri, Jul 30, 2021 at 12:24:35PM +0100, Will Deacon wrote:
> > +	struct rq_flags rf;
> > +	struct rq *rq;
> > +	int err;
> > +	struct cpumask *user_mask = NULL;
> 
> > +	cpumask_var_t new_mask;
> > +	const struct cpumask *override_mask = task_cpu_possible_mask(p);
> 
> > +	unsigned long flags;
> > +	struct cpumask *mask = p->user_cpus_ptr;
> 
> I've fixed all that up to be proper reverse x-mas trees; similar for
> other patches.

Thanks.

Will


From bot at kernelci.org  Wed Aug 18 03:48:21 2021
From: bot at kernelci.org (kernelci.org bot)
Date: Wed, 18 Aug 2021 03:48:21 -0700 (PDT)
Subject: arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 2 errors,
 1 warning (v5.14-rc6-2-g09bfde80e8e2)
Message-ID: <611ce575.1c69fb81.6a988.cd47@mx.google.com>

arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 2 errors, 1 warning (v5.14-rc6-2-g09bfde80e8e2)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v5.14-rc6-2-g09bfde80e8e2/

Tree: arm64
Branch: for-kernelci
Git Describe: v5.14-rc6-2-g09bfde80e8e2
Git Commit: 09bfde80e8e285ceebddf09959f91f6be0a999ad
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Build Failure Detected:

arm64:
    allmodconfig: (gcc-8) FAIL

Errors and Warnings Detected:

arm64:
    allmodconfig (gcc-8): 2 errors, 1 warning

Errors summary:

    1    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1864? declared with attribute error: FIELD_PREP: value too large for the field
    1    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1857? declared with attribute error: FIELD_PREP: value too large for the field

Warnings summary:

    1    kernel/trace/trace_osnoise.c:1461:8: warning: ?main? is usually a function [-Wmain]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
allmodconfig (arm64, gcc-8) ? FAIL, 2 errors, 1 warning, 0 section mismatches

Errors:
    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1857? declared with attribute error: FIELD_PREP: value too large for the field
    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1864? declared with attribute error: FIELD_PREP: value too large for the field

Warnings:
    kernel/trace/trace_osnoise.c:1461:8: warning: ?main? is usually a function [-Wmain]

--------------------------------------------------------------------------------
defconfig (arm64, gcc-8) ? PASS, 0 errors, 0 warnings, 0 section mismatches

---
For more info write to <info at kernelci.org>


From will at kernel.org  Wed Aug 18 03:50:30 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 11:50:30 +0100
Subject: [PATCH v11 07/16] sched: Split the guts of sched_setaffinity()
 into a helper function
In-Reply-To: <YRvYaGa4QnhV2q51@hirez.programming.kicks-ass.net>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-8-will@kernel.org>
 <YRvYaGa4QnhV2q51@hirez.programming.kicks-ass.net>
Message-ID: <20210818105029.GC13828@willie-the-truck>

On Tue, Aug 17, 2021 at 05:40:24PM +0200, Peter Zijlstra wrote:
> On Fri, Jul 30, 2021 at 12:24:34PM +0100, Will Deacon wrote:
> > In preparation for replaying user affinity requests using a saved mask,
> > split sched_setaffinity() up so that the initial task lookup and
> > security checks are only performed when the request is coming directly
> > from userspace.
> > 
> > Reviewed-by: Valentin Schneider <Valentin.Schneider at arm.com>
> > Signed-off-by: Will Deacon <will at kernel.org>
> 
> Should not sched_setaffinity() update user_cpus_ptr when it isn't NULL,
> such that the upcoming relax_compatible_cpus_allowed_ptr() preserve the
> full user mask?

The idea is that force_compatible_cpus_allowed_ptr() and
relax_compatible_cpus_allowed_ptr() are used as a pair, with the former
setting ->user_cpus_ptr and the latter restoring it. An intervening call
to sched_setaffinity() must _clear_ the saved mask, as we discussed
before at:

https://lore.kernel.org/r/YK53kDtczHIYumDC at hirez.programming.kicks-ass.net

Will


From peterz at infradead.org  Wed Aug 18 03:56:41 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Wed, 18 Aug 2021 12:56:41 +0200
Subject: [PATCH v11 08/16] sched: Allow task CPU affinity to be
 restricted on asymmetric systems
In-Reply-To: <20210818104227.GA13828@willie-the-truck>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-9-will@kernel.org>
 <YRvRfZ/NnuNyIu3s@hirez.programming.kicks-ass.net>
 <20210818104227.GA13828@willie-the-truck>
Message-ID: <YRznaZBHXYEzCPt1@hirez.programming.kicks-ass.net>

On Wed, Aug 18, 2021 at 11:42:28AM +0100, Will Deacon wrote:
> As for your other suggestion:
> 
> > --- a/kernel/sched/core.c
> > +++ b/kernel/sched/core.c
> > @@ -2733,6 +2733,7 @@ static int __set_cpus_allowed_ptr_locked
> >  	const struct cpumask *cpu_allowed_mask = task_cpu_possible_mask(p);
> >  	const struct cpumask *cpu_valid_mask = cpu_active_mask;
> >  	bool kthread = p->flags & PF_KTHREAD;
> > +	struct cpumask *user_mask = NULL;
> >  	unsigned int dest_cpu;
> >  	int ret = 0;
> >  
> > @@ -2792,9 +2793,13 @@ static int __set_cpus_allowed_ptr_locked
> >  	__do_set_cpus_allowed(p, new_mask, flags);
> >  
> >  	if (flags & SCA_USER)
> > -		release_user_cpus_ptr(p);
> > +		swap(user_mask, p->user_cpus_ptr);
> > +
> > +	ret = affine_move_task(rq, p, rf, dest_cpu, flags);
> > +
> > +	kfree(user_mask);
> >  
> > -	return affine_move_task(rq, p, rf, dest_cpu, flags);
> > +	return ret;
> >  
> >  out:
> >  	task_rq_unlock(rq, p, rf);
> > @@ -2954,8 +2959,10 @@ void relax_compatible_cpus_allowed_ptr(s
> >  		return;
> >  
> >  	raw_spin_lock_irqsave(&p->pi_lock, flags);
> > -	release_user_cpus_ptr(p);
> > +	p->user_cpus_ptr = NULL;
> >  	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
> > +
> > +	kfree(mask);
> 
> I think the idea looks good, but perhaps we could wrap things up a bit:
> 
> /* Comment about why this is useful with RT */
> static cpumask_t *clear_user_cpus_ptr(struct task_struct *p)
> {
> 	struct cpumask *user_mask = NULL;
> 
> 	swap(user_mask, p->user_cpus_ptr);
> 	return user_mask;
> }
> 
> void release_user_cpus_ptr(struct task_struct *p)
> {
> 	kfree(clear_user_cpus_ptr(p));
> }
> 
> Then just use clear_user_cpus_ptr() in sched/core.c where we know what
> we're doing (well, at least one of us does!).

OK, I'll go make it like that.


From peterz at infradead.org  Wed Aug 18 03:56:24 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Wed, 18 Aug 2021 12:56:24 +0200
Subject: [PATCH v11 07/16] sched: Split the guts of sched_setaffinity()
 into a helper function
In-Reply-To: <20210818105029.GC13828@willie-the-truck>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-8-will@kernel.org>
 <YRvYaGa4QnhV2q51@hirez.programming.kicks-ass.net>
 <20210818105029.GC13828@willie-the-truck>
Message-ID: <YRznWDtF/doFRm0/@hirez.programming.kicks-ass.net>

On Wed, Aug 18, 2021 at 11:50:30AM +0100, Will Deacon wrote:
> On Tue, Aug 17, 2021 at 05:40:24PM +0200, Peter Zijlstra wrote:
> > On Fri, Jul 30, 2021 at 12:24:34PM +0100, Will Deacon wrote:
> > > In preparation for replaying user affinity requests using a saved mask,
> > > split sched_setaffinity() up so that the initial task lookup and
> > > security checks are only performed when the request is coming directly
> > > from userspace.
> > > 
> > > Reviewed-by: Valentin Schneider <Valentin.Schneider at arm.com>
> > > Signed-off-by: Will Deacon <will at kernel.org>
> > 
> > Should not sched_setaffinity() update user_cpus_ptr when it isn't NULL,
> > such that the upcoming relax_compatible_cpus_allowed_ptr() preserve the
> > full user mask?
> 
> The idea is that force_compatible_cpus_allowed_ptr() and
> relax_compatible_cpus_allowed_ptr() are used as a pair, with the former
> setting ->user_cpus_ptr and the latter restoring it. An intervening call
> to sched_setaffinity() must _clear_ the saved mask, as we discussed
> before at:
> 
> https://lore.kernel.org/r/YK53kDtczHIYumDC at hirez.programming.kicks-ass.net

Clearly that deserves a comment somewhere, because I keep trying to make
it more consistent than it can be :/ I'll see if I can find a spot.


From liuqi115 at huawei.com  Wed Aug 18 00:33:35 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Wed, 18 Aug 2021 15:33:35 +0800
Subject: [PATCH v4 1/2] Make save_all_base_regs and restore_all_base_regs as
 common macro
In-Reply-To: <20210818073336.59678-1-liuqi115@huawei.com>
References: <20210818073336.59678-1-liuqi115@huawei.com>
Message-ID: <20210818073336.59678-2-liuqi115@huawei.com>

Move save_all_base_regs and restore_all_base_regs to <asm/assembler.h>,
as these two macros can be reused in optprobe.
---
 arch/arm64/include/asm/assembler.h            | 52 +++++++++++++++++++
 arch/arm64/kernel/probes/kprobes_trampoline.S | 52 -------------------
 2 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 89faca0e740d..cd912810fc80 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -515,6 +515,58 @@ alternative_endif
 	.pushsection "_kprobe_blacklist", "aw";	\
 	.quad	x;				\
 	.popsection;
+
+	.macro	save_all_base_regs
+	stp x0, x1, [sp, #S_X0]
+	stp x2, x3, [sp, #S_X2]
+	stp x4, x5, [sp, #S_X4]
+	stp x6, x7, [sp, #S_X6]
+	stp x8, x9, [sp, #S_X8]
+	stp x10, x11, [sp, #S_X10]
+	stp x12, x13, [sp, #S_X12]
+	stp x14, x15, [sp, #S_X14]
+	stp x16, x17, [sp, #S_X16]
+	stp x18, x19, [sp, #S_X18]
+	stp x20, x21, [sp, #S_X20]
+	stp x22, x23, [sp, #S_X22]
+	stp x24, x25, [sp, #S_X24]
+	stp x26, x27, [sp, #S_X26]
+	stp x28, x29, [sp, #S_X28]
+	add x0, sp, #PT_REGS_SIZE
+	stp lr, x0, [sp, #S_LR]
+	/*
+	 * Construct a useful saved PSTATE
+	 */
+	mrs x0, nzcv
+	mrs x1, daif
+	orr x0, x0, x1
+	mrs x1, CurrentEL
+	orr x0, x0, x1
+	mrs x1, SPSel
+	orr x0, x0, x1
+	stp xzr, x0, [sp, #S_PC]
+	.endm
+
+	.macro	restore_all_base_regs
+	ldr x0, [sp, #S_PSTATE]
+	and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
+	msr nzcv, x0
+	ldp x0, x1, [sp, #S_X0]
+	ldp x2, x3, [sp, #S_X2]
+	ldp x4, x5, [sp, #S_X4]
+	ldp x6, x7, [sp, #S_X6]
+	ldp x8, x9, [sp, #S_X8]
+	ldp x10, x11, [sp, #S_X10]
+	ldp x12, x13, [sp, #S_X12]
+	ldp x14, x15, [sp, #S_X14]
+	ldp x16, x17, [sp, #S_X16]
+	ldp x18, x19, [sp, #S_X18]
+	ldp x20, x21, [sp, #S_X20]
+	ldp x22, x23, [sp, #S_X22]
+	ldp x24, x25, [sp, #S_X24]
+	ldp x26, x27, [sp, #S_X26]
+	ldp x28, x29, [sp, #S_X28]
+	.endm
 #else
 #define NOKPROBE(x)
 #endif
diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S
index 288a84e253cc..2463d5d0e004 100644
--- a/arch/arm64/kernel/probes/kprobes_trampoline.S
+++ b/arch/arm64/kernel/probes/kprobes_trampoline.S
@@ -9,58 +9,6 @@
 
 	.text
 
-	.macro	save_all_base_regs
-	stp x0, x1, [sp, #S_X0]
-	stp x2, x3, [sp, #S_X2]
-	stp x4, x5, [sp, #S_X4]
-	stp x6, x7, [sp, #S_X6]
-	stp x8, x9, [sp, #S_X8]
-	stp x10, x11, [sp, #S_X10]
-	stp x12, x13, [sp, #S_X12]
-	stp x14, x15, [sp, #S_X14]
-	stp x16, x17, [sp, #S_X16]
-	stp x18, x19, [sp, #S_X18]
-	stp x20, x21, [sp, #S_X20]
-	stp x22, x23, [sp, #S_X22]
-	stp x24, x25, [sp, #S_X24]
-	stp x26, x27, [sp, #S_X26]
-	stp x28, x29, [sp, #S_X28]
-	add x0, sp, #PT_REGS_SIZE
-	stp lr, x0, [sp, #S_LR]
-	/*
-	 * Construct a useful saved PSTATE
-	 */
-	mrs x0, nzcv
-	mrs x1, daif
-	orr x0, x0, x1
-	mrs x1, CurrentEL
-	orr x0, x0, x1
-	mrs x1, SPSel
-	orr x0, x0, x1
-	stp xzr, x0, [sp, #S_PC]
-	.endm
-
-	.macro	restore_all_base_regs
-	ldr x0, [sp, #S_PSTATE]
-	and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
-	msr nzcv, x0
-	ldp x0, x1, [sp, #S_X0]
-	ldp x2, x3, [sp, #S_X2]
-	ldp x4, x5, [sp, #S_X4]
-	ldp x6, x7, [sp, #S_X6]
-	ldp x8, x9, [sp, #S_X8]
-	ldp x10, x11, [sp, #S_X10]
-	ldp x12, x13, [sp, #S_X12]
-	ldp x14, x15, [sp, #S_X14]
-	ldp x16, x17, [sp, #S_X16]
-	ldp x18, x19, [sp, #S_X18]
-	ldp x20, x21, [sp, #S_X20]
-	ldp x22, x23, [sp, #S_X22]
-	ldp x24, x25, [sp, #S_X24]
-	ldp x26, x27, [sp, #S_X26]
-	ldp x28, x29, [sp, #S_X28]
-	.endm
-
 SYM_CODE_START(kretprobe_trampoline)
 	sub sp, sp, #PT_REGS_SIZE
 
-- 
2.17.1



From liuqi115 at huawei.com  Wed Aug 18 00:33:34 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Wed, 18 Aug 2021 15:33:34 +0800
Subject: [PATCH v4 0/2] arm64: Enable OPTPROBE for arm64
Message-ID: <20210818073336.59678-1-liuqi115@huawei.com>

This patch introduce optprobe for ARM64, using a branch instruction
to replace probed instruction.

The test result on Hip08 platform is shown here, and optprobe could
reduce the latency to 1/4 of normal kprobe

kprobe before optimized:
[280709.846380] do_empty returned 0 and took 1530 ns to execute
[280709.852057] do_empty returned 0 and took 550 ns to execute
[280709.857631] do_empty returned 0 and took 440 ns to execute
[280709.863215] do_empty returned 0 and took 380 ns to execute
[280709.868787] do_empty returned 0 and took 360 ns to execute
[280709.874362] do_empty returned 0 and took 340 ns to execute
[280709.879936] do_empty returned 0 and took 320 ns to execute
[280709.885505] do_empty returned 0 and took 300 ns to execute
[280709.891075] do_empty returned 0 and took 280 ns to execute
[280709.896646] do_empty returned 0 and took 290 ns to execute
[280709.902220] do_empty returned 0 and took 290 ns to execute
[280709.907807] do_empty returned 0 and took 290 ns to execute

optprobe:
[ 2965.964572] do_empty returned 0 and took 90 ns to execute
[ 2965.969952] do_empty returned 0 and took 80 ns to execute
[ 2965.975332] do_empty returned 0 and took 70 ns to execute
[ 2965.980714] do_empty returned 0 and took 60 ns to execute
[ 2965.986128] do_empty returned 0 and took 80 ns to execute
[ 2965.991507] do_empty returned 0 and took 70 ns to execute
[ 2965.996884] do_empty returned 0 and took 70 ns to execute
[ 2966.002262] do_empty returned 0 and took 80 ns to execute
[ 2966.007642] do_empty returned 0 and took 70 ns to execute
[ 2966.013020] do_empty returned 0 and took 70 ns to execute
[ 2966.018400] do_empty returned 0 and took 70 ns to execute
[ 2966.023779] do_empty returned 0 and took 70 ns to execute
[ 2966.029158] do_empty returned 0 and took 70 ns to execute

Changes since V3:
- Address the comments from Masami, reduce the number of aarch64_insn_patch_text
in arch_optimize_kprobes() and arch_unoptimize_kprobes().
- Link: https://lore.kernel.org/lkml/20210810055330.18924-1-liuqi115 at huawei.com/

Changes since V2:
- Address the comments from Masami, prepare another writable buffer in
arch_prepare_optimized_kprobe()and build the trampoline code on it.
- Address the comments from Amit, move save_all_base_regs and
restore_all_base_regs to <asm/assembler.h>, as these two macros are reused
in optprobe.
- Link: https://lore.kernel.org/lkml/20210804060209.95817-1-liuqi115 at huawei.com/

Changes since V1:
- Address the comments from Masami, checks for all branch instructions, and
use aarch64_insn_patch_text_nosync() instead of aarch64_insn_patch_text()
in each probe.
- Link: https://lore.kernel.org/lkml/20210719122417.10355-1-liuqi115 at huawei.com/

Qi Liu (2):
  Make save_all_base_regs and restore_all_base_regs as common macro
  arm64: kprobe: Enable OPTPROBE for arm64

 arch/arm64/Kconfig                            |   1 +
 arch/arm64/include/asm/assembler.h            |  52 ++++
 arch/arm64/include/asm/kprobes.h              |  24 ++
 arch/arm64/kernel/probes/Makefile             |   2 +
 arch/arm64/kernel/probes/kprobes.c            |  19 +-
 arch/arm64/kernel/probes/kprobes_trampoline.S |  52 ----
 arch/arm64/kernel/probes/opt_arm64.c          | 276 ++++++++++++++++++
 .../arm64/kernel/probes/optprobe_trampoline.S |  37 +++
 8 files changed, 408 insertions(+), 55 deletions(-)
 create mode 100644 arch/arm64/kernel/probes/opt_arm64.c
 create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S

-- 
2.17.1



From liuqi115 at huawei.com  Wed Aug 18 00:33:36 2021
From: liuqi115 at huawei.com (Qi Liu)
Date: Wed, 18 Aug 2021 15:33:36 +0800
Subject: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210818073336.59678-1-liuqi115@huawei.com>
References: <20210818073336.59678-1-liuqi115@huawei.com>
Message-ID: <20210818073336.59678-3-liuqi115@huawei.com>

This patch introduce optprobe for ARM64. In optprobe, probed
instruction is replaced by a branch instruction to detour
buffer. Detour buffer contains trampoline code and a call to
optimized_callback(). optimized_callback() calls opt_pre_handler()
to execute kprobe handler.

Performance of optprobe on Hip08 platform is test using kprobe
example module[1] to analyze the latency of a kernel function,
and here is the result:

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c

kprobe before optimized:
[280709.846380] do_empty returned 0 and took 1530 ns to execute
[280709.852057] do_empty returned 0 and took 550 ns to execute
[280709.857631] do_empty returned 0 and took 440 ns to execute
[280709.863215] do_empty returned 0 and took 380 ns to execute
[280709.868787] do_empty returned 0 and took 360 ns to execute
[280709.874362] do_empty returned 0 and took 340 ns to execute
[280709.879936] do_empty returned 0 and took 320 ns to execute
[280709.885505] do_empty returned 0 and took 300 ns to execute
[280709.891075] do_empty returned 0 and took 280 ns to execute
[280709.896646] do_empty returned 0 and took 290 ns to execute
[280709.902220] do_empty returned 0 and took 290 ns to execute
[280709.907807] do_empty returned 0 and took 290 ns to execute

optprobe:
[ 2965.964572] do_empty returned 0 and took 90 ns to execute
[ 2965.969952] do_empty returned 0 and took 80 ns to execute
[ 2965.975332] do_empty returned 0 and took 70 ns to execute
[ 2965.980714] do_empty returned 0 and took 60 ns to execute
[ 2965.986128] do_empty returned 0 and took 80 ns to execute
[ 2965.991507] do_empty returned 0 and took 70 ns to execute
[ 2965.996884] do_empty returned 0 and took 70 ns to execute
[ 2966.002262] do_empty returned 0 and took 80 ns to execute
[ 2966.007642] do_empty returned 0 and took 70 ns to execute
[ 2966.013020] do_empty returned 0 and took 70 ns to execute
[ 2966.018400] do_empty returned 0 and took 70 ns to execute
[ 2966.023779] do_empty returned 0 and took 70 ns to execute
[ 2966.029158] do_empty returned 0 and took 70 ns to execute

Signed-off-by: Qi Liu <liuqi115 at huawei.com>

Note:
To guarantee the offset between probe point and kprobe pre_handler
is smaller than 128MiB, users should set
CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
optprobe will not work and fall back to normal kprobe.
---
 arch/arm64/Kconfig                            |   1 +
 arch/arm64/include/asm/kprobes.h              |  24 ++
 arch/arm64/kernel/probes/Makefile             |   2 +
 arch/arm64/kernel/probes/kprobes.c            |  19 +-
 arch/arm64/kernel/probes/opt_arm64.c          | 276 ++++++++++++++++++
 .../arm64/kernel/probes/optprobe_trampoline.S |  37 +++
 6 files changed, 356 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/kernel/probes/opt_arm64.c
 create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5b13a932561..b05d1d275d87 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -200,6 +200,7 @@ config ARM64
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_KPROBES
+	select HAVE_OPTPROBES
 	select HAVE_KRETPROBES
 	select HAVE_GENERIC_VDSO
 	select IOMMU_DMA if IOMMU_SUPPORT
diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
index 5d38ff4a4806..6b2fdd2ad7d8 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -39,6 +39,30 @@ void arch_remove_kprobe(struct kprobe *);
 int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
 int kprobe_exceptions_notify(struct notifier_block *self,
 			     unsigned long val, void *data);
+
+#define RELATIVEJUMP_SIZE (4)
+#define MAX_COPIED_INSN	DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
+struct arch_optimized_insn {
+	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
+	/* detour code buffer */
+	kprobe_opcode_t *insn;
+};
+
+/* optinsn template addresses */
+extern __visible kprobe_opcode_t optprobe_template_entry[];
+extern __visible kprobe_opcode_t optprobe_template_val[];
+extern __visible kprobe_opcode_t optprobe_template_call[];
+extern __visible kprobe_opcode_t optprobe_template_end[];
+extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
+extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
+extern __visible kprobe_opcode_t optprobe_template_restore_end[];
+extern __visible kprobe_opcode_t optprobe_template_max_length[];
+
+#define MAX_OPTIMIZED_LENGTH	4
+#define MAX_OPTINSN_SIZE				\
+	((unsigned long)optprobe_template_end -	\
+	 (unsigned long)optprobe_template_entry)
+
 void kretprobe_trampoline(void);
 void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
 
diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
index 8e4be92e25b1..07105fd3261d 100644
--- a/arch/arm64/kernel/probes/Makefile
+++ b/arch/arm64/kernel/probes/Makefile
@@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o decode-insn.o	\
 				   simulate-insn.o
 obj-$(CONFIG_UPROBES)		+= uprobes.o decode-insn.o	\
 				   simulate-insn.o
+obj-$(CONFIG_OPTPROBES)		+= opt_arm64.o			\
+				   optprobe_trampoline.o
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index 6dbcc89f6662..83755ad62abe 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -11,6 +11,7 @@
 #include <linux/kasan.h>
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
+#include <linux/moduleloader.h>
 #include <linux/sched/debug.h>
 #include <linux/set_memory.h>
 #include <linux/slab.h>
@@ -113,9 +114,21 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 
 void *alloc_insn_page(void)
 {
-	return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
-			GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
-			NUMA_NO_NODE, __builtin_return_address(0));
+	void *page;
+
+	page = module_alloc(PAGE_SIZE);
+	if (!page)
+		return NULL;
+
+	set_vm_flush_reset_perms(page);
+	/*
+	 * First make the page read-only, and only then make it executable to
+	 * prevent it from being W+X in between.
+	 */
+	set_memory_ro((unsigned long)page, 1);
+	set_memory_x((unsigned long)page, 1);
+
+	return page;
 }
 
 /* arm kprobe: install breakpoint in text */
diff --git a/arch/arm64/kernel/probes/opt_arm64.c b/arch/arm64/kernel/probes/opt_arm64.c
new file mode 100644
index 000000000000..4de535bee534
--- /dev/null
+++ b/arch/arm64/kernel/probes/opt_arm64.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Code for Kernel probes Jump optimization.
+ *
+ * Copyright (C) 2021 Hisilicon Limited
+ */
+
+#include <linux/jump_label.h>
+#include <linux/kprobes.h>
+
+#include <asm/cacheflush.h>
+#include <asm/insn.h>
+#include <asm/kprobes.h>
+#include <asm/patching.h>
+
+#define TMPL_VAL_IDX \
+	(optprobe_template_val - optprobe_template_entry)
+#define TMPL_CALL_BACK \
+	(optprobe_template_call - optprobe_template_entry)
+#define TMPL_END_IDX \
+	(optprobe_template_end - optprobe_template_entry)
+#define TMPL_RESTORE_ORIGN_INSN \
+	(optprobe_template_restore_orig_insn - optprobe_template_entry)
+#define TMPL_RESTORE_END \
+	(optprobe_template_restore_end - optprobe_template_entry)
+#define TMPL_MAX_LENGTH \
+	(optprobe_template_max_length - optprobe_template_entry)
+#define OPTPROBE_BATCH_SIZE 64
+
+int arch_check_optimized_kprobe(struct optimized_kprobe *op)
+{
+	return 0;
+}
+
+int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
+{
+	return optinsn->insn != NULL;
+}
+
+int arch_within_optimized_kprobe(struct optimized_kprobe *op,
+				unsigned long addr)
+{
+	return ((unsigned long)op->kp.addr <= addr &&
+		(unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
+}
+
+static void
+optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
+{
+	/* This is possible if op is under delayed unoptimizing */
+	if (kprobe_disabled(&op->kp))
+		return;
+
+	preempt_disable();
+
+	if (kprobe_running()) {
+		kprobes_inc_nmissed_count(&op->kp);
+	} else {
+		__this_cpu_write(current_kprobe, &op->kp);
+		regs->pc = (unsigned long)op->kp.addr;
+		get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+		opt_pre_handler(&op->kp, regs);
+		__this_cpu_write(current_kprobe, NULL);
+	}
+
+	preempt_enable_no_resched();
+}
+NOKPROBE_SYMBOL(optimized_callback)
+
+static bool is_offset_in_range(unsigned long start, unsigned long end)
+{
+	long offset = end - start;
+
+	/*
+	 * Verify if the address gap is in 128MiB range, because this uses
+	 * a relative jump.
+	 *
+	 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
+	 * According to ARM manual, branch instruction is:
+	 *
+	 *   31  30                  25              0
+	 *  +----+---+---+---+---+---+---------------+
+	 *  |cond| 0 | 0 | 1 | 0 | 1 |     imm26     |
+	 *  +----+---+---+---+---+---+---------------+
+	 *
+	 * imm26 is a signed 26 bits integer. The real branch offset is computed
+	 * by: imm64 = SignExtend(imm26:'00', 64);
+	 *
+	 * So the maximum forward branch should be:
+	 *   (0x01ffffff << 2) = 0x07fffffc
+	 * The maximum backward branch should be:
+	 *   (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
+	 *
+	 * We can simply check (rel & 0xf8000003):
+	 *  if rel is positive, (rel & 0xf8000003) should be 0
+	 *  if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
+	 *  the last '3' is used for alignment checking.
+	 */
+	return (offset >= -0x8000000 && offset <= 0x7fffffc && !(offset & 0x3));
+}
+
+int arch_prepare_optimized_kprobe(struct optimized_kprobe *op,
+				  struct kprobe *orig)
+{
+	kprobe_opcode_t *code, *buf;
+	void **addrs;
+	u32 insn;
+	int ret, i;
+
+	addrs = kcalloc(TMPL_MAX_LENGTH, sizeof(void *), GFP_KERNEL);
+	if (!addrs)
+		return -ENOMEM;
+
+	buf = kcalloc(TMPL_MAX_LENGTH, sizeof(kprobe_opcode_t), GFP_KERNEL);
+	if (!buf) {
+		kfree(addrs);
+		return -ENOMEM;
+	}
+
+	code = get_optinsn_slot();
+	if (!code) {
+		kfree(addrs);
+		kfree(buf);
+		return -ENOMEM;
+	}
+
+	if (!is_offset_in_range((unsigned long)code,
+				(unsigned long)orig->addr + 8)) {
+		ret = -ERANGE;
+		goto error;
+	}
+
+	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
+				(unsigned long)optimized_callback)) {
+		ret = -ERANGE;
+		goto error;
+	}
+
+	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
+				(unsigned long)op->kp.addr + 4)) {
+		ret = -ERANGE;
+		goto error;
+	}
+
+	memcpy(buf, optprobe_template_entry,
+	       TMPL_END_IDX * sizeof(kprobe_opcode_t));
+
+	buf[TMPL_VAL_IDX] = FIELD_GET(GENMASK(31, 0), (unsigned long long)op);
+	buf[TMPL_VAL_IDX + 1] =
+		FIELD_GET(GENMASK(63, 32), (unsigned long long)op);
+	buf[TMPL_RESTORE_ORIGN_INSN] = orig->opcode;
+
+	insn = aarch64_insn_gen_branch_imm(
+		(unsigned long)(&code[TMPL_CALL_BACK]),
+		(unsigned long)optimized_callback, AARCH64_INSN_BRANCH_LINK);
+	buf[TMPL_CALL_BACK] = insn;
+
+	insn = aarch64_insn_gen_branch_imm(
+		(unsigned long)(&code[TMPL_RESTORE_END]),
+		(unsigned long)(op->kp.addr) + 4, AARCH64_INSN_BRANCH_NOLINK);
+	buf[TMPL_RESTORE_END] = insn;
+
+	/* Setup template */
+	for (i = 0; i < TMPL_MAX_LENGTH; i++)
+		addrs[i] = code + i;
+
+	ret = aarch64_insn_patch_text(addrs, buf, TMPL_MAX_LENGTH);
+	if (ret < 0)
+		goto error;
+
+	flush_icache_range((unsigned long)code,
+			   (unsigned long)(&code[TMPL_END_IDX]));
+
+	/* Set op->optinsn.insn means prepared. */
+	op->optinsn.insn = code;
+
+out:
+	kfree(addrs);
+	kfree(buf);
+	return ret;
+
+error:
+	free_optinsn_slot(code, 0);
+	goto out;
+}
+
+void arch_optimize_kprobes(struct list_head *oplist)
+{
+	struct optimized_kprobe *op, *tmp;
+	kprobe_opcode_t *insns;
+	void **addrs;
+	int i = 0;
+
+	addrs = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(void *), GFP_KERNEL);
+	if (!addrs)
+		return;
+
+	insns = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(kprobe_opcode_t), GFP_KERNEL);
+	if (!insns) {
+		kfree(addrs);
+		return;
+	}
+
+	list_for_each_entry_safe(op, tmp, oplist, list) {
+		WARN_ON(kprobe_disabled(&op->kp));
+
+		/*
+		 * Backup instructions which will be replaced
+		 * by jump address
+		 */
+		memcpy(op->optinsn.copied_insn, op->kp.addr,
+			RELATIVEJUMP_SIZE);
+
+		addrs[i] = (void *)op->kp.addr;
+		insns[i] = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
+				(unsigned long)op->optinsn.insn,
+				AARCH64_INSN_BRANCH_NOLINK);
+
+		list_del_init(&op->list);
+		if (++i == OPTPROBE_BATCH_SIZE)
+			break;
+	}
+
+	aarch64_insn_patch_text(addrs, insns, i);
+	kfree(addrs);
+	kfree(insns);
+}
+
+void arch_unoptimize_kprobe(struct optimized_kprobe *op)
+{
+	arch_arm_kprobe(&op->kp);
+}
+
+/*
+ * Recover original instructions and breakpoints from relative jumps.
+ * Caller must call with locking kprobe_mutex.
+ */
+void arch_unoptimize_kprobes(struct list_head *oplist,
+			    struct list_head *done_list)
+{
+	struct optimized_kprobe *op, *tmp;
+	kprobe_opcode_t *insns;
+	void **addrs;
+	int i = 0;
+
+	addrs = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(void *), GFP_KERNEL);
+	if (!addrs)
+		return;
+
+	insns = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(kprobe_opcode_t), GFP_KERNEL);
+	if (!insns) {
+		kfree(addrs);
+		return;
+	}
+
+	list_for_each_entry_safe(op, tmp, oplist, list) {
+		addrs[i] = (void *)op->kp.addr;
+		insns[i] = BRK64_OPCODE_KPROBES;
+		list_move(&op->list, done_list);
+
+		if (++i == OPTPROBE_BATCH_SIZE)
+			break;
+	}
+
+	aarch64_insn_patch_text(addrs, insns, i);
+	kfree(addrs);
+	kfree(insns);
+}
+
+void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
+{
+	if (op->optinsn.insn) {
+		free_optinsn_slot(op->optinsn.insn, 1);
+		op->optinsn.insn = NULL;
+	}
+}
diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
new file mode 100644
index 000000000000..24d713d400cd
--- /dev/null
+++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * trampoline entry and return code for optprobes.
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+
+	.global optprobe_template_entry
+optprobe_template_entry:
+	sub sp, sp, #PT_REGS_SIZE
+	save_all_base_regs
+	/* Get parameters to optimized_callback() */
+	ldr	x0, 1f
+	mov	x1, sp
+	/* Branch to optimized_callback() */
+	.global optprobe_template_call
+optprobe_template_call:
+	nop
+	restore_all_base_regs
+	ldr lr, [sp, #S_LR]
+        add sp, sp, #PT_REGS_SIZE
+	.global optprobe_template_restore_orig_insn
+optprobe_template_restore_orig_insn:
+	nop
+	.global optprobe_template_restore_end
+optprobe_template_restore_end:
+	nop
+	.global optprobe_template_end
+optprobe_template_end:
+	.global optprobe_template_val
+optprobe_template_val:
+	1:	.long 0
+		.long 0
+	.global optprobe_template_max_length
+optprobe_template_max_length:
-- 
2.17.1



From peterz at infradead.org  Wed Aug 18 04:06:08 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Wed, 18 Aug 2021 13:06:08 +0200
Subject: [PATCH v11 08/16] sched: Allow task CPU affinity to be
 restricted on asymmetric systems
In-Reply-To: <20210818104227.GA13828@willie-the-truck>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-9-will@kernel.org>
 <YRvRfZ/NnuNyIu3s@hirez.programming.kicks-ass.net>
 <20210818104227.GA13828@willie-the-truck>
Message-ID: <YRzpoFdCqHHsjFpW@hirez.programming.kicks-ass.net>

On Wed, Aug 18, 2021 at 11:42:28AM +0100, Will Deacon wrote:

> Ah, sorry. I didn't realise you couldn't _free_ with a raw lock held in RT.
> Is there somewhere I can read up on that?

It's because the allocators use spinlock_t, which cannot nest inside
raw_spinlock_t.


From will at kernel.org  Wed Aug 18 04:11:53 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 12:11:53 +0100
Subject: [PATCH v11 07/16] sched: Split the guts of sched_setaffinity()
 into a helper function
In-Reply-To: <YRznWDtF/doFRm0/@hirez.programming.kicks-ass.net>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-8-will@kernel.org>
 <YRvYaGa4QnhV2q51@hirez.programming.kicks-ass.net>
 <20210818105029.GC13828@willie-the-truck>
 <YRznWDtF/doFRm0/@hirez.programming.kicks-ass.net>
Message-ID: <20210818111153.GA13999@willie-the-truck>

On Wed, Aug 18, 2021 at 12:56:24PM +0200, Peter Zijlstra wrote:
> On Wed, Aug 18, 2021 at 11:50:30AM +0100, Will Deacon wrote:
> > On Tue, Aug 17, 2021 at 05:40:24PM +0200, Peter Zijlstra wrote:
> > > On Fri, Jul 30, 2021 at 12:24:34PM +0100, Will Deacon wrote:
> > > > In preparation for replaying user affinity requests using a saved mask,
> > > > split sched_setaffinity() up so that the initial task lookup and
> > > > security checks are only performed when the request is coming directly
> > > > from userspace.
> > > > 
> > > > Reviewed-by: Valentin Schneider <Valentin.Schneider at arm.com>
> > > > Signed-off-by: Will Deacon <will at kernel.org>
> > > 
> > > Should not sched_setaffinity() update user_cpus_ptr when it isn't NULL,
> > > such that the upcoming relax_compatible_cpus_allowed_ptr() preserve the
> > > full user mask?
> > 
> > The idea is that force_compatible_cpus_allowed_ptr() and
> > relax_compatible_cpus_allowed_ptr() are used as a pair, with the former
> > setting ->user_cpus_ptr and the latter restoring it. An intervening call
> > to sched_setaffinity() must _clear_ the saved mask, as we discussed
> > before at:
> > 
> > https://lore.kernel.org/r/YK53kDtczHIYumDC at hirez.programming.kicks-ass.net
> 
> Clearly that deserves a comment somewhere, because I keep trying to make
> it more consistent than it can be :/ I'll see if I can find a spot.

Agreed. The relax/force functions are already commented, so maybe alongside
SCA_USER?

Will


From christian.gmeiner at gmail.com  Wed Aug 18 04:17:46 2021
From: christian.gmeiner at gmail.com (Christian Gmeiner)
Date: Wed, 18 Aug 2021 13:17:46 +0200
Subject: [PATCH] arm64: dts: ti: k3-am64-mcu: Add pinctrl
Message-ID: <20210818111747.88569-1-christian.gmeiner@gmail.com>

Add the definition of the pinctrl for the MCU domain.

Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
---
 arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
index 59cc58f7d0c8..2bb5c9ff172c 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
@@ -97,4 +97,12 @@ mcu_gpio0: gpio at 4201000 {
 		clocks = <&k3_clks 79 0>;
 		clock-names = "gpio";
 	};
+
+	mcu_pmx0: pinctrl at 4084000 {
+		compatible = "pinctrl-single";
+		reg = <0x00 0x4084000 0x00 0x84>;
+		#pinctrl-cells = <1>;
+		pinctrl-single,register-width = <32>;
+		pinctrl-single,function-mask = <0xffffffff>;
+	};
 };
-- 
2.31.1



From maz at kernel.org  Wed Aug 18 04:19:23 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 12:19:23 +0100
Subject: [PATCH 1/2] irqchip: irq-meson-gpio: make it possible to build as
 a module
In-Reply-To: <CAGETcx-FS_88nQuF=xN4iJJ-nGnaeTnO-iiGpZuNELqE42FtoA@mail.gmail.com>
References: <87r1hwwier.wl-maz@kernel.org> <7h7diwgjup.fsf@baylibre.com>
 <87im0m277h.wl-maz@kernel.org>
 <CAGETcx9OukoWM_qprMse9aXdzCE=GFUgFEkfhhNjg44YYsOQLw@mail.gmail.com>
 <87sfzpwq4f.wl-maz@kernel.org>
 <CAGETcx95kHrv8wA-O+-JtfH7H9biJEGJtijuPVN0V5dUKUAB3A@mail.gmail.com>
 <CAGETcx8bpWQEnkpJ0YW9GqX8WE0ewT45zqkbWWdZ0ktJBhG4yQ@mail.gmail.com>
 <YQuZ2cKVE+3Os25Z@google.com> <YRpeVLf18Z+1R7WE@google.com>
 <CAGETcx-gSJD0Ra=U_55k3Anps11N_3Ev9gEQV6NaXOvqwP0J3g@mail.gmail.com>
 <YRtkE62O+4EiyzF9@google.com>
 <CAGETcx-FS_88nQuF=xN4iJJ-nGnaeTnO-iiGpZuNELqE42FtoA@mail.gmail.com>
Message-ID: <87o89vroec.wl-maz@kernel.org>

On Tue, 17 Aug 2021 19:12:34 +0100,
Saravana Kannan <saravanak at google.com> wrote:
> 
> On Tue, Aug 17, 2021 at 12:24 AM Lee Jones <lee.jones at linaro.org> wrote:
> >
> > On Mon, 16 Aug 2021, Saravana Kannan wrote:
> > > > > > I sent out the proper fix as a series:
> > > > > > https://lore.kernel.org/lkml/20210804214333.927985-1-saravanak at google.com/T/#t
> > > > > >
> > > > > > Marc, can you give it a shot please?
> > > > > >
> > > > > > -Saravana
> > > > >
> > > > > Superstar!  Thanks for taking the time to rectify this for all of us.
> > > >
> > > > Just to clarify:
> > > >
> > > >   Are we waiting on a subsequent patch submission at this point?
> > >
> > > Not that I'm aware of. Andrew added a "Reviewed-by" to all 3 of my
> > > proper fix patches. I didn't think I needed to send any newer patches.
> > > Is there some reason you that I needed to?
> >
> > Actually, I meant *this* patch.
> 
> I think it'll be nice if Neil addresses the stuff Marc mentioned
> (ideally) using the macros I suggested. Not sure if Marc is waiting on
> that though. Marc also probably wants my mdio-mux series to merge
> first before he takes this patch. So that it doesn't break networking
> in his device.

Yup. Two things need to happen here:

- the MDIO fixes must be merged (I think they are queued, from what I
  can see)

- the irqchip patch must be fixed so that the driver cannot be
  unloaded (Saravana did explain what needs to be done).

Once these two condition are met, I'll happily take this patch.

	M.

-- 
Without deviation from the norm, progress is not possible.


From joro at 8bytes.org  Wed Aug 18 04:29:31 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Wed, 18 Aug 2021 13:29:31 +0200
Subject: [PATCH v4 00/24] iommu: Refactor DMA domain strictness
In-Reply-To: <cover.1628682048.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
Message-ID: <YRzvGxTW8m+NUcSi@8bytes.org>

On Wed, Aug 11, 2021 at 01:21:14PM +0100, Robin Murphy wrote:
> Robin Murphy (24):
>   iommu: Pull IOVA cookie management into the core
>   iommu/amd: Drop IOVA cookie management
>   iommu/arm-smmu: Drop IOVA cookie management
>   iommu/vt-d: Drop IOVA cookie management
>   iommu/exynos: Drop IOVA cookie management
>   iommu/ipmmu-vmsa: Drop IOVA cookie management
>   iommu/mtk: Drop IOVA cookie management
>   iommu/rockchip: Drop IOVA cookie management
>   iommu/sprd: Drop IOVA cookie management
>   iommu/sun50i: Drop IOVA cookie management
>   iommu/virtio: Drop IOVA cookie management
>   iommu/dma: Unexport IOVA cookie management
>   iommu/dma: Remove redundant "!dev" checks
>   iommu: Indicate queued flushes via gather data
>   iommu/io-pgtable: Remove non-strict quirk
>   iommu: Introduce explicit type for non-strict DMA domains
>   iommu/amd: Prepare for multiple DMA domain types
>   iommu/arm-smmu: Prepare for multiple DMA domain types
>   iommu/vt-d: Prepare for multiple DMA domain types
>   iommu: Express DMA strictness via the domain type
>   iommu: Expose DMA domain strictness via sysfs
>   iommu: Only log strictness for DMA domains
>   iommu: Merge strictness and domain type configs
>   iommu: Allow enabling non-strict mode dynamically

Applied all except patch 12. Please re-submit patch 12 together with the
APPLE DART fixups after v5.15-rc1 is out.

Thanks,

	Joerg


From bot at kernelci.org  Wed Aug 18 04:32:07 2021
From: bot at kernelci.org (kernelci.org bot)
Date: Wed, 18 Aug 2021 04:32:07 -0700 (PDT)
Subject: arm64/for-kernelci baseline: 49 runs,
 4 regressions (v5.14-rc6-2-g09bfde80e8e2)
Message-ID: <611cefb7.1c69fb81.a6c31.48d7@mx.google.com>

arm64/for-kernelci baseline: 49 runs, 4 regressions (v5.14-rc6-2-g09bfde80e8e2)

Regressions Summary
-------------------

platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
bcm2837-rpi-3-b  | arm64 | lab-baylibre  | gcc-8    | defconfig | 1          
hip07-d05        | arm64 | lab-collabora | gcc-8    | defconfig | 1          
rk3399-gru-kevin | arm64 | lab-collabora | gcc-8    | defconfig | 2          

  Details:  https://kernelci.org/test/job/arm64/branch/for-kernelci/kernel/v5.14-rc6-2-g09bfde80e8e2/plan/baseline/

  Test:     baseline
  Tree:     arm64
  Branch:   for-kernelci
  Describe: v5.14-rc6-2-g09bfde80e8e2
  URL:      https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  SHA:      09bfde80e8e285ceebddf09959f91f6be0a999ad 


Test Regressions
---------------- 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
bcm2837-rpi-3-b  | arm64 | lab-baylibre  | gcc-8    | defconfig | 1          

  Details:     https://kernelci.org/test/plan/id/611ce5102b3b8ab0a1b13661

  Results:     0 PASS, 1 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-2-g09bfde80e8e2/arm64/defconfig/gcc-8/lab-baylibre/baseline-bcm2837-rpi-3-b.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-2-g09bfde80e8e2/arm64/defconfig/gcc-8/lab-baylibre/baseline-bcm2837-rpi-3-b.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.login: https://kernelci.org/test/case/id/611ce5102b3b8ab0a1b13662
        failing since 36 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1) 
 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
hip07-d05        | arm64 | lab-collabora | gcc-8    | defconfig | 1          

  Details:     https://kernelci.org/test/plan/id/611ceb61adba17ec92b136e1

  Results:     0 PASS, 1 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-2-g09bfde80e8e2/arm64/defconfig/gcc-8/lab-collabora/baseline-hip07-d05.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-2-g09bfde80e8e2/arm64/defconfig/gcc-8/lab-collabora/baseline-hip07-d05.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.login: https://kernelci.org/test/case/id/611ceb61adba17ec92b136e2
        failing since 47 days (last pass: v5.13-rc7-174-g8ab9b1a98a22, first fail: v5.13-13-g68ddb29c953a) 
 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
rk3399-gru-kevin | arm64 | lab-collabora | gcc-8    | defconfig | 2          

  Details:     https://kernelci.org/test/plan/id/611ce13a0a59993d9ab13677

  Results:     89 PASS, 2 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-2-g09bfde80e8e2/arm64/defconfig/gcc-8/lab-collabora/baseline-rk3399-gru-kevin.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-2-g09bfde80e8e2/arm64/defconfig/gcc-8/lab-collabora/baseline-rk3399-gru-kevin.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.bootrr.rockchip-usb2phy1-probed: https://kernelci.org/test/case/id/611ce13a0a59993d9ab13681
        failing since 36 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1)

    2021-08-18T10:30:04.467988  /lava-4374905/1/../bin/lava-test-case   

  * baseline.bootrr.rockchip-usb2phy0-probed: https://kernelci.org/test/case/id/611ce13a0a59993d9ab13682
        failing since 36 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1)

    2021-08-18T10:30:02.411043  <8>[   23.062350] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=rockchip-usb2phy-driver-present RESULT=pass>
    2021-08-18T10:30:03.432998  /lava-4374905/1/../bin/lava-test-case
    2021-08-18T10:30:03.444721  <8>[   24.096934] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=rockchip-usb2phy0-probed RESULT=fail>   
  


From marcan at marcan.st  Wed Aug 18 04:35:04 2021
From: marcan at marcan.st (Hector Martin)
Date: Wed, 18 Aug 2021 20:35:04 +0900
Subject: [PATCH] irqchip/apple-aic: fix irq_disable from within irq
 handlers
In-Reply-To: <20210812100942.17206-1-sven@svenpeter.dev>
References: <20210812100942.17206-1-sven@svenpeter.dev>
Message-ID: <9b2805ec-e5b4-bb1b-abee-0bff7e3dbf24@marcan.st>

*Puts on kernel maintainer hat again*

Sorry for the delay. I've been spending too much time on hardware RE 
recently...

On 12/08/2021 19.09, Sven Peter wrote:
> When disable_irq_nosync for an interrupt is called from within its
> interrupt handler, this interrupt is only marked as disabled with the
> intention to mask it when it triggers again.
> The AIC hardware however automatically masks the interrupt when it is read.
> aic_irq_eoi then unmasks it again if it's not disabled *and* not masked.
> This results in a state mismatch between the hardware state and the
> state kept in irq_data: The hardware interrupt is masked but
> IRQD_IRQ_MASKED is not set. Any further calls to unmask_irq will directly
> return and the interrupt can never be enabled again.
> 
> Fix this by keeping the hardware and irq_data state in sync by unmasking in
> aic_irq_eoi if and only if the irq_data state also assumes the interrupt to
> be unmasked.
> 
> Fixes: 76cde2639411 ("irqchip/apple-aic: Add support for the Apple Interrupt Controller")
> Signed-off-by: Sven Peter <sven at svenpeter.dev>
> ---
>   drivers/irqchip/irq-apple-aic.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
> index b8c06bd8659e..6fc145aacaf0 100644
> --- a/drivers/irqchip/irq-apple-aic.c
> +++ b/drivers/irqchip/irq-apple-aic.c
> @@ -226,7 +226,7 @@ static void aic_irq_eoi(struct irq_data *d)
>   	 * Reading the interrupt reason automatically acknowledges and masks
>   	 * the IRQ, so we just unmask it here if needed.
>   	 */
> -	if (!irqd_irq_disabled(d) && !irqd_irq_masked(d))
> +	if (!irqd_irq_masked(d))
>   		aic_irq_unmask(d);
>   }
>   
> 

Looks good to me. I can't remember exactly where this code came from, 
but looking again at the irqchip code it's clear that the mask state and 
hardware mask always have to be in sync.

Acked-by: Hector Martin <marcan at marcan.st>

-- 
Hector Martin (marcan at marcan.st)
Public Key: https://mrcn.st/pub


From haibo.chen at nxp.com  Wed Aug 18 04:16:50 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 19:16:50 +0800
Subject: [PATCH v2 1/6] mmc: sdhci-esdhc-imx: remove redundant code for manual
 tuning
Message-ID: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

For manual tuning method, already call esdhc_prepare_tuning()
config the necessary registers, so remove the redundant code
in esdhc_writew_le() for SDHCI_HOST_CONTROL2.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 57b19ca1ad6d..a49fac719fca 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -628,17 +628,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 		else
 			new_val &= ~ESDHC_VENDOR_SPEC_VSELECT;
 		writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
-		if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
-			new_val = readl(host->ioaddr + ESDHC_MIX_CTRL);
-			if (val & SDHCI_CTRL_TUNED_CLK) {
-				new_val |= ESDHC_MIX_CTRL_SMPCLK_SEL;
-				new_val |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
-			} else {
-				new_val &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
-				new_val &= ~ESDHC_MIX_CTRL_AUTO_TUNE_EN;
-			}
-			writel(new_val , host->ioaddr + ESDHC_MIX_CTRL);
-		} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
+		if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
 			u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
 			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
 			if (val & SDHCI_CTRL_TUNED_CLK) {
-- 
2.17.1



From haibo.chen at nxp.com  Wed Aug 18 04:16:51 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 19:16:51 +0800
Subject: [PATCH v2 2/6] mmc: sdhci-eadhc-imx: select the correct mode for auto
 tuning
In-Reply-To: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
References: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629285415-7495-2-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

USDHC hardware auto tuning circuit support check 1/4/8 data lines
and cmd line. Out of reset uSDHC, it default select check 4 data
lines and do not check cmd line. This is incorrect if we use 8 data
lines. So need to config the auto tuning mode according to current
bus width.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 33 ++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index a49fac719fca..f18d169bc8ff 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -94,6 +94,11 @@
 
 #define ESDHC_VEND_SPEC2		0xc8
 #define ESDHC_VEND_SPEC2_EN_BUSY_IRQ	(1 << 8)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN	(1 << 4)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN	(0 << 4)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN	(2 << 4)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN	(1 << 6)
+#define ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK	(7 << 4)
 
 #define ESDHC_TUNING_CTRL		0xcc
 #define ESDHC_STD_TUNING_EN		(1 << 24)
@@ -114,6 +119,7 @@
 #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
 #define ESDHC_CTRL_8BITBUS		(0x2 << 1)
 #define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
+#define USDHC_GET_BUSWIDTH(c) (c & ESDHC_CTRL_BUSWIDTH_MASK)
 
 /*
  * There is an INT DMA ERR mismatch between eSDHC and STD SDHC SPEC:
@@ -407,6 +413,30 @@ static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
 		dev_warn(mmc_dev(host->mmc), "%s: card clock still not gate off in 100us!.\n", __func__);
 }
 
+/* Enable the auto tuning circuit to check the CMD line and BUS line */
+static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host)
+{
+	u32 buswidth, auto_tune_buswidth;
+
+	buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL));
+
+	switch (buswidth) {
+	case ESDHC_CTRL_8BITBUS:
+		auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN;
+		break;
+	case ESDHC_CTRL_4BITBUS:
+		auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN;
+		break;
+	default:	/* 1BITBUS */
+		auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN;
+		break;
+	}
+
+	esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK,
+			auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN,
+			ESDHC_VEND_SPEC2);
+}
+
 static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -643,6 +673,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 				v |= ESDHC_MIX_CTRL_EXE_TUNE;
 				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
 				m |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
+				usdhc_auto_tuning_mode_sel(host);
 			} else {
 				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
 			}
@@ -1012,6 +1043,8 @@ static void esdhc_post_tuning(struct sdhci_host *host)
 {
 	u32 reg;
 
+	usdhc_auto_tuning_mode_sel(host);
+
 	reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
 	reg &= ~ESDHC_MIX_CTRL_EXE_TUNE;
 	reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
-- 
2.17.1



From haibo.chen at nxp.com  Wed Aug 18 04:16:52 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 19:16:52 +0800
Subject: [PATCH v2 3/6] dt-bindings: mmc: fsl-imx-esdhc: add fsl,
 broken-auto-tuning binding
In-Reply-To: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
References: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629285415-7495-3-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add a new fsl,broken-auto-tuning binding for sdio devices. When sdio
device support sdio interrupt, need to use this property to disable
auto-tuning. Auto-tuning circuit is conflict with sdio interrupt.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
index b5baf439fbac..d7c8e5880473 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
@@ -93,6 +93,15 @@ properties:
       tuning step can't find the proper delay window within limited tuning retries.
     default: 0
 
+  fsl,broken-auto-tuning:
+    description: |
+      Recommend for SDIO cards that enables SDIO interrupt for SDR104 and SDR50 mode.
+      SDIO interrupt uses DAT[1] to signal the card's interrupt. Auto-tuning circuit
+      will detect this interrupt on DAT[1] when in 4Bit bus mode, and take it just
+      as normal data, wrongly adjust the delay cell. This property is used to disable
+      the auto-tuning function.
+    type: boolean
+
   fsl,strobe-dll-delay-target:
     $ref: /schemas/types.yaml#/definitions/uint32
     description: |
-- 
2.17.1



From haibo.chen at nxp.com  Wed Aug 18 04:16:53 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 19:16:53 +0800
Subject: [PATCH v2 4/6] mmc: host: sdhci-esdhc-imx.c: disable auto-tuning when
 necessary
In-Reply-To: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
References: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629285415-7495-4-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add a method to enable/disable auto-tuning function. auto-tuning function
is conflict with sdio interrupt. For sdio device with sdio interrupt,
need to disable auto-tuning function.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index f18d169bc8ff..3af6519c561b 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -226,6 +226,7 @@ struct esdhc_platform_data {
 	unsigned int tuning_step;       /* The delay cell steps in tuning procedure */
 	unsigned int tuning_start_tap;	/* The start delay cell point in tuning procedure */
 	unsigned int strobe_dll_delay_target;	/* The delay cell for strobe pad (read clock) */
+	bool broken_auto_tuning;	/* Disable the auto tuning circuit */
 };
 
 struct esdhc_soc_data {
@@ -672,8 +673,10 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 			if (val & SDHCI_CTRL_EXEC_TUNING) {
 				v |= ESDHC_MIX_CTRL_EXE_TUNE;
 				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
-				m |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
-				usdhc_auto_tuning_mode_sel(host);
+				if (!imx_data->boarddata.broken_auto_tuning) {
+					usdhc_auto_tuning_mode_sel(host);
+					m |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
+				}
 			} else {
 				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
 			}
@@ -1041,13 +1044,16 @@ static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
 
 static void esdhc_post_tuning(struct sdhci_host *host)
 {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
 	u32 reg;
 
-	usdhc_auto_tuning_mode_sel(host);
-
 	reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
 	reg &= ~ESDHC_MIX_CTRL_EXE_TUNE;
-	reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
+	if (!imx_data->boarddata.broken_auto_tuning) {
+		usdhc_auto_tuning_mode_sel(host);
+		reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
+	}
 	writel(reg, host->ioaddr + ESDHC_MIX_CTRL);
 }
 
@@ -1522,7 +1528,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
 	of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step);
 	of_property_read_u32(np, "fsl,tuning-start-tap",
 			     &boarddata->tuning_start_tap);
-
+	if (of_property_read_bool(np, "fsl,broken-auto-tuning"))
+		boarddata->broken_auto_tuning = true;
 	of_property_read_u32(np, "fsl,strobe-dll-delay-target",
 				&boarddata->strobe_dll_delay_target);
 	if (of_find_property(np, "no-1-8-v", NULL))
-- 
2.17.1



From haibo.chen at nxp.com  Wed Aug 18 04:16:54 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 19:16:54 +0800
Subject: [PATCH v2 5/6] arm64: dts: imx8mm-evk: add sdio wifi support
In-Reply-To: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
References: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629285415-7495-5-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add the sdio wifi support on imx8mm-evk board.
Disable auto tuning for this sdio wifi since it support sdio
interrupt.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mm-evk.dts  | 20 ++++++++++
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 39 +++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
index 4e2820d19244..07a28b6e00be 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
@@ -15,6 +15,13 @@
 	aliases {
 		spi0 = &flexspi;
 	};
+
+	usdhc1_pwrseq: usdhc1_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usdhc1_gpio>;
+		reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+	};
 };
 
 &ddrc {
@@ -53,6 +60,19 @@
 	};
 };
 
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	bus-width = <4>;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&usdhc1_pwrseq>;
+	fsl,broken-auto-tuning;
+	non-removable;
+	status = "okay";
+};
+
 &usdhc3 {
 	assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
 	assigned-clock-rates = <400000000>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index e033d0257b5a..ca623078d937 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -440,6 +440,45 @@
 		>;
 	};
 
+	pinctrl_usdhc1_gpio: usdhc1grpgpiogrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10	0x41
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x190
+			MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d0
+			MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d0
+			MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d0
+			MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d0
+			MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d0
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+		fsl,pins = <
+			MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x194
+			MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d4
+			MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d4
+			MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d4
+			MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d4
+			MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d4
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+		fsl,pins = <
+			MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x196
+			MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d6
+			MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d6
+			MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d6
+			MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d6
+			MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d6
+		>;
+	};
+
 	pinctrl_usdhc2_gpio: usdhc2grpgpiogrp {
 		fsl,pins = <
 			MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15	0x1c4
-- 
2.17.1



From haibo.chen at nxp.com  Wed Aug 18 04:16:55 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Wed, 18 Aug 2021 19:16:55 +0800
Subject: [PATCH v2 6/6] arm64: dts: imx8mn-evk: add sdio wifi support
In-Reply-To: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
References: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629285415-7495-6-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Add sdio wifi support on imx8mn-evk board.
Disable auto tuning for this sdio wifi since it support sdio
interrupt.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi | 59 +++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index 85e65f8719ea..276fcfdc9033 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -28,6 +28,13 @@
 		reg = <0x0 0x40000000 0 0x80000000>;
 	};
 
+	usdhc1_pwrseq: usdhc1_pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usdhc1_gpio>;
+		reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+	};
+
 	reg_usdhc2_vmmc: regulator-usdhc2 {
 		compatible = "regulator-fixed";
 		pinctrl-names = "default";
@@ -205,6 +212,19 @@
 	};
 };
 
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	bus-width = <4>;
+	keep-power-in-suspend;
+	non-removable;
+	mmc-pwrseq = <&usdhc1_pwrseq>;
+	fsl,broken-auto-tuning;
+	status = "okay";
+};
+
 &usdhc2 {
 	assigned-clocks = <&clk IMX8MN_CLK_USDHC2>;
 	assigned-clock-rates = <200000000>;
@@ -303,6 +323,45 @@
 		>;
 	};
 
+	pinctrl_usdhc1_gpio: usdhc1grpgpio {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD1_RESET_B_GPIO2_IO10	0x41
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK		0x190
+			MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d0
+			MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d0
+			MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d0
+			MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d0
+			MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d0
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK		0x194
+			MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d4
+			MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d4
+			MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d4
+			MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d4
+			MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d4
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+		fsl,pins = <
+			MX8MN_IOMUXC_SD1_CLK_USDHC1_CLK		0x196
+			MX8MN_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d6
+			MX8MN_IOMUXC_SD1_DATA0_USDHC1_DATA0	0x1d6
+			MX8MN_IOMUXC_SD1_DATA1_USDHC1_DATA1	0x1d6
+			MX8MN_IOMUXC_SD1_DATA2_USDHC1_DATA2	0x1d6
+			MX8MN_IOMUXC_SD1_DATA3_USDHC1_DATA3	0x1d6
+		>;
+	};
+
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
 		fsl,pins = <
 			MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19	0x41
-- 
2.17.1



From peterz at infradead.org  Wed Aug 18 04:53:28 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Wed, 18 Aug 2021 13:53:28 +0200
Subject: [PATCH v11 08/16] sched: Allow task CPU affinity to be
 restricted on asymmetric systems
In-Reply-To: <YRznaZBHXYEzCPt1@hirez.programming.kicks-ass.net>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-9-will@kernel.org>
 <YRvRfZ/NnuNyIu3s@hirez.programming.kicks-ass.net>
 <20210818104227.GA13828@willie-the-truck>
 <YRznaZBHXYEzCPt1@hirez.programming.kicks-ass.net>
Message-ID: <YRz0uI6V58eGNL1C@hirez.programming.kicks-ass.net>

On Wed, Aug 18, 2021 at 12:56:41PM +0200, Peter Zijlstra wrote:
> On Wed, Aug 18, 2021 at 11:42:28AM +0100, Will Deacon wrote:

> > I think the idea looks good, but perhaps we could wrap things up a bit:
> > 
> > /* Comment about why this is useful with RT */
> > static cpumask_t *clear_user_cpus_ptr(struct task_struct *p)
> > {
> > 	struct cpumask *user_mask = NULL;
> > 
> > 	swap(user_mask, p->user_cpus_ptr);
> > 	return user_mask;
> > }
> > 
> > void release_user_cpus_ptr(struct task_struct *p)
> > {
> > 	kfree(clear_user_cpus_ptr(p));
> > }
> > 
> > Then just use clear_user_cpus_ptr() in sched/core.c where we know what
> > we're doing (well, at least one of us does!).
> 
> OK, I'll go make it like that.

Something like so then?

--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2497,10 +2497,18 @@ int dup_user_cpus_ptr(struct task_struct
 	return 0;
 }
 
+static inline struct cpumask *clear_user_cpus_ptr(struct task_struct *p)
+{
+	struct cpumask *user_mask = NULL;
+
+	swap(p->user_cpus_ptr, user_mask);
+
+	return user_mask;
+}
+
 void release_user_cpus_ptr(struct task_struct *p)
 {
-	kfree(p->user_cpus_ptr);
-	p->user_cpus_ptr = NULL;
+	kfree(clear_user_cpus_ptr(p));
 }
 
 /*
@@ -2733,6 +2741,7 @@ static int __set_cpus_allowed_ptr_locked
 	const struct cpumask *cpu_allowed_mask = task_cpu_possible_mask(p);
 	const struct cpumask *cpu_valid_mask = cpu_active_mask;
 	bool kthread = p->flags & PF_KTHREAD;
+	struct cpumask *user_mask = NULL;
 	unsigned int dest_cpu;
 	int ret = 0;
 
@@ -2792,9 +2801,13 @@ static int __set_cpus_allowed_ptr_locked
 	__do_set_cpus_allowed(p, new_mask, flags);
 
 	if (flags & SCA_USER)
-		release_user_cpus_ptr(p);
+		user_mask = clear_user_cpus_ptr(p);
 
-	return affine_move_task(rq, p, rf, dest_cpu, flags);
+	ret = affine_move_task(rq, p, rf, dest_cpu, flags);
+
+	kfree(user_mask);
+
+	return ret;
 
 out:
 	task_rq_unlock(rq, p, rf);
@@ -2941,20 +2954,22 @@ __sched_setaffinity(struct task_struct *
  */
 void relax_compatible_cpus_allowed_ptr(struct task_struct *p)
 {
+	struct cpumask *user_mask = p->user_cpus_ptr;
 	unsigned long flags;
-	struct cpumask *mask = p->user_cpus_ptr;
 
 	/*
 	 * Try to restore the old affinity mask. If this fails, then
 	 * we free the mask explicitly to avoid it being inherited across
 	 * a subsequent fork().
 	 */
-	if (!mask || !__sched_setaffinity(p, mask))
+	if (!user_mask || !__sched_setaffinity(p, user_mask))
 		return;
 
 	raw_spin_lock_irqsave(&p->pi_lock, flags);
-	release_user_cpus_ptr(p);
+	user_mask = clear_user_cpus_ptr(p);
 	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
+
+	kfree(user_mask);
 }
 
 void set_task_cpu(struct task_struct *p, unsigned int new_cpu)



From joro at 8bytes.org  Wed Aug 18 05:08:25 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Wed, 18 Aug 2021 14:08:25 +0200
Subject: [GIT PULL] iommu/arm-smmu: Updates for 5.15
In-Reply-To: <20210813164735.GA8765@willie-the-truck>
References: <20210813164735.GA8765@willie-the-truck>
Message-ID: <YRz4OemrkIcDxCC5@8bytes.org>

On Fri, Aug 13, 2021 at 05:47:35PM +0100, Will Deacon wrote:
> This applies cleanly against iommu/next, but I suspect it will conflict
> with Robin's series on the list. Please shout if you need anything from
> me to help with that (e.g. rebase, checking a merge conflict).

For now there were at least no conflicts which git couldn't resolve
automatically, but the compile tests are still running :)

> The following changes since commit ff1176468d368232b684f75e82563369208bc371:
> 
>   Linux 5.14-rc3 (2021-07-25 15:35:14 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git tags/arm-smmu-updates

So this is pulled now, thanks.



From will at kernel.org  Wed Aug 18 05:17:29 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 13:17:29 +0100
Subject: [GIT PULL] iommu/arm-smmu: Updates for 5.15
In-Reply-To: <YRz4OemrkIcDxCC5@8bytes.org>
References: <20210813164735.GA8765@willie-the-truck>
 <YRz4OemrkIcDxCC5@8bytes.org>
Message-ID: <20210818121728.GB14107@willie-the-truck>

On Wed, Aug 18, 2021 at 02:08:25PM +0200, Joerg Roedel wrote:
> On Fri, Aug 13, 2021 at 05:47:35PM +0100, Will Deacon wrote:
> > This applies cleanly against iommu/next, but I suspect it will conflict
> > with Robin's series on the list. Please shout if you need anything from
> > me to help with that (e.g. rebase, checking a merge conflict).
> 
> For now there were at least no conflicts which git couldn't resolve
> automatically, but the compile tests are still running :)

Ok, I won't hold my breath!

> > The following changes since commit ff1176468d368232b684f75e82563369208bc371:
> > 
> >   Linux 5.14-rc3 (2021-07-25 15:35:14 -0700)
> > 
> > are available in the Git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git tags/arm-smmu-updates
> 
> So this is pulled now, thanks.

Cheers,

Will


From will at kernel.org  Wed Aug 18 05:19:01 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 13:19:01 +0100
Subject: [PATCH v11 08/16] sched: Allow task CPU affinity to be
 restricted on asymmetric systems
In-Reply-To: <YRz0uI6V58eGNL1C@hirez.programming.kicks-ass.net>
References: <20210730112443.23245-1-will@kernel.org>
 <20210730112443.23245-9-will@kernel.org>
 <YRvRfZ/NnuNyIu3s@hirez.programming.kicks-ass.net>
 <20210818104227.GA13828@willie-the-truck>
 <YRznaZBHXYEzCPt1@hirez.programming.kicks-ass.net>
 <YRz0uI6V58eGNL1C@hirez.programming.kicks-ass.net>
Message-ID: <20210818121900.GC14107@willie-the-truck>

On Wed, Aug 18, 2021 at 01:53:28PM +0200, Peter Zijlstra wrote:
> On Wed, Aug 18, 2021 at 12:56:41PM +0200, Peter Zijlstra wrote:
> > On Wed, Aug 18, 2021 at 11:42:28AM +0100, Will Deacon wrote:
> 
> > > I think the idea looks good, but perhaps we could wrap things up a bit:
> > > 
> > > /* Comment about why this is useful with RT */
> > > static cpumask_t *clear_user_cpus_ptr(struct task_struct *p)
> > > {
> > > 	struct cpumask *user_mask = NULL;
> > > 
> > > 	swap(user_mask, p->user_cpus_ptr);
> > > 	return user_mask;
> > > }
> > > 
> > > void release_user_cpus_ptr(struct task_struct *p)
> > > {
> > > 	kfree(clear_user_cpus_ptr(p));
> > > }
> > > 
> > > Then just use clear_user_cpus_ptr() in sched/core.c where we know what
> > > we're doing (well, at least one of us does!).
> > 
> > OK, I'll go make it like that.
> 
> Something like so then?

Looks good to me, thanks!

Will


From kjain at linux.ibm.com  Wed Aug 18 05:27:37 2021
From: kjain at linux.ibm.com (kajoljain)
Date: Wed, 18 Aug 2021 17:57:37 +0530
Subject: [PATCH v2 2/4] perf/marvell: CN10k DDR performance monitor support
In-Reply-To: <20210810094307.29595-3-bbhushan2@marvell.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
 <20210810094307.29595-3-bbhushan2@marvell.com>
Message-ID: <329a1d8c-1b93-443c-a1d8-484083a8978f@linux.ibm.com>



On 8/10/21 3:13 PM, Bharat Bhushan wrote:
> Marvell CN10k DRAM Subsystem (DSS) supports eight
> event counters for monitoring performance and software
> can program each counter to monitor any of the defined
> performance event. Performance events are for interface
> between the DDR controller and the PHY, interface between
> the DDR Controller and the CHI interconnect, or within
> the DDR Controller. Additionally DSS also supports two
> fixed performance event counters, one for number of
> ddr reads and other for ddr writes.
> 
> This patch add basic support for these performance
> monitoring events on CN10k.
> 
> Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
> ---
> v1->v2:
>  - writeq/readq changed to respective relaxed version
>  - Using PMU_EVENT_ATTR_ID
> 
>  drivers/perf/Kconfig                 |   7 +
>  drivers/perf/Makefile                |   1 +
>  drivers/perf/marvell_cn10k_ddr_pmu.c | 606 +++++++++++++++++++++++++++
>  3 files changed, 614 insertions(+)
>  create mode 100644 drivers/perf/marvell_cn10k_ddr_pmu.c
> 
> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
> index 77522e5efe11..41a80a4b8d29 100644
> --- a/drivers/perf/Kconfig
> +++ b/drivers/perf/Kconfig
> @@ -139,4 +139,11 @@ config ARM_DMC620_PMU
>  
>  source "drivers/perf/hisilicon/Kconfig"
>  
> +config MARVELL_CN10K_DDR_PMU
> +	tristate "Enable MARVELL CN10K DRAM Subsystem(DSS) PMU Support"
> +	depends on ARM64
> +	help
> +	  Enable perf support for Marvell DDR Performance monitoring
> +	  event on CN10K platform.
> +
>  endmenu
> diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
> index 5260b116c7da..ee1126219d8d 100644
> --- a/drivers/perf/Makefile
> +++ b/drivers/perf/Makefile
> @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
>  obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
>  obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
>  obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
> +obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
> diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
> new file mode 100644
> index 000000000000..8f9e3d1fcd8d
> --- /dev/null
> +++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
> @@ -0,0 +1,606 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Marvell CN10K DRAM Subsystem (DSS) Performance Monitor Driver
> + *
> + * Copyright (C) 2021 Marvell.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/perf_event.h>
> +
> +/* Performance Counters Operating Mode Control Registers */
> +#define DDRC_PERF_CNT_OP_MODE_CTRL	0x8020
> +#define OP_MODE_CTRL_VAL_MANNUAL	0x1
> +
> +/* Performance Counters Start Operation Control Registers */
> +#define DDRC_PERF_CNT_START_OP_CTRL	0x8028
> +#define START_OP_CTRL_VAL_START		0x1ULL
> +#define START_OP_CTRL_VAL_ACTIVE	0x2
> +
> +/* Performance Counters End Operation Control Registers */
> +#define DDRC_PERF_CNT_END_OP_CTRL	0x8030
> +#define END_OP_CTRL_VAL_END		0x1ULL
> +
> +/* Performance Counters End Status Registers */
> +#define DDRC_PERF_CNT_END_STATUS		0x8038
> +#define END_STATUS_VAL_END_TIMER_MODE_END	0x1
> +
> +/* Performance Counters Configuration Registers */
> +#define DDRC_PERF_CFG_BASE		0x8040
> +
> +/* 8 Generic event counter + 2 fixed event counters */
> +#define DDRC_PERF_NUM_GEN_COUNTERS	8
> +#define DDRC_PERF_NUM_FIX_COUNTERS	2
> +#define DDRC_PERF_READ_COUNTER_IDX	DDRC_PERF_NUM_GEN_COUNTERS
> +#define DDRC_PERF_WRITE_COUNTER_IDX	(DDRC_PERF_NUM_GEN_COUNTERS + 1)
> +#define DDRC_PERF_NUM_COUNTERS		(DDRC_PERF_NUM_GEN_COUNTERS + \
> +					 DDRC_PERF_NUM_FIX_COUNTERS)
> +
> +/* Generic event counter registers */
> +#define DDRC_PERF_CFG(n)		(DDRC_PERF_CFG_BASE + 8 * (n))
> +#define EVENT_ENABLE			BIT_ULL(63)
> +
> +/* Two dedicated event counters for DDR reads and writes */
> +#define EVENT_DDR_READS			101
> +#define EVENT_DDR_WRITES		100
> +
> +/*
> + * programmable events IDs in programmable event counters.
> + * DO NOT change these event-id numbers, they are used to
> + * program event bitmap in h/w.
> + */
> +#define EVENT_OP_IS_ZQLATCH			55
> +#define EVENT_OP_IS_ZQSTART			54
> +#define EVENT_OP_IS_TCR_MRR			53
> +#define EVENT_OP_IS_DQSOSC_MRR			52
> +#define EVENT_OP_IS_DQSOSC_MPC			51
> +#define EVENT_VISIBLE_WIN_LIMIT_REACHED_WR	50
> +#define EVENT_VISIBLE_WIN_LIMIT_REACHED_RD	49
> +#define EVENT_BSM_STARVATION			48
> +#define EVENT_BSM_ALLOC				47
> +#define EVENT_LPR_REQ_WITH_NOCREDIT		46
> +#define EVENT_HPR_REQ_WITH_NOCREDIT		45
> +#define EVENT_OP_IS_ZQCS			44
> +#define EVENT_OP_IS_ZQCL			43
> +#define EVENT_OP_IS_LOAD_MODE			42
> +#define EVENT_OP_IS_SPEC_REF			41
> +#define EVENT_OP_IS_CRIT_REF			40
> +#define EVENT_OP_IS_REFRESH			39
> +#define EVENT_OP_IS_ENTER_MPSM			35
> +#define EVENT_OP_IS_ENTER_POWERDOWN		31
> +#define EVENT_OP_IS_ENTER_SELFREF		27
> +#define EVENT_WAW_HAZARD			26
> +#define EVENT_RAW_HAZARD			25
> +#define EVENT_WAR_HAZARD			24
> +#define EVENT_WRITE_COMBINE			23
> +#define EVENT_RDWR_TRANSITIONS			22
> +#define EVENT_PRECHARGE_FOR_OTHER		21
> +#define EVENT_PRECHARGE_FOR_RDWR		20
> +#define EVENT_OP_IS_PRECHARGE			19
> +#define EVENT_OP_IS_MWR				18
> +#define EVENT_OP_IS_WR				17
> +#define EVENT_OP_IS_RD				16
> +#define EVENT_OP_IS_RD_ACTIVATE			15
> +#define EVENT_OP_IS_RD_OR_WR			14
> +#define EVENT_OP_IS_ACTIVATE			13
> +#define EVENT_WR_XACT_WHEN_CRITICAL		12
> +#define EVENT_LPR_XACT_WHEN_CRITICAL		11
> +#define EVENT_HPR_XACT_WHEN_CRITICAL		10
> +#define EVENT_DFI_RD_DATA_CYCLES		9
> +#define EVENT_DFI_WR_DATA_CYCLES		8
> +#define EVENT_ACT_BYPASS			7
> +#define EVENT_READ_BYPASS			6
> +#define EVENT_HIF_HI_PRI_RD			5
> +#define EVENT_HIF_RMW				4
> +#define EVENT_HIF_RD				3
> +#define EVENT_HIF_WR				2
> +#define EVENT_HIF_RD_OR_WR			1
> +
> +/* Event counter value registers */
> +#define DDRC_PERF_CNT_VALUE_BASE		0x8080
> +#define DDRC_PERF_CNT_VALUE(n)	(DDRC_PERF_CNT_VALUE_BASE + 8 * (n))
> +
> +/* Fixed event counter enable/disable register */
> +#define DDRC_PERF_CNT_FREERUN_EN	0x80C0
> +#define DDRC_PERF_FREERUN_WRITE_EN	0x1
> +#define DDRC_PERF_FREERUN_READ_EN	0x2
> +
> +/* Fixed event counter control register */
> +#define DDRC_PERF_CNT_FREERUN_CTRL	0x80C8
> +#define DDRC_FREERUN_WRITE_CNT_CLR	0x1
> +#define DDRC_FREERUN_READ_CNT_CLR	0x2
> +
> +/* Fixed event counter value register */
> +#define DDRC_PERF_CNT_VALUE_WR_OP	0x80D0
> +#define DDRC_PERF_CNT_VALUE_RD_OP	0x80D8
> +#define DDRC_PERF_CNT_VALUE_OVERFLOW	BIT_ULL(48)
> +#define DDRC_PERF_CNT_MAX_VALUE		GENMASK_ULL(48, 0)
> +
> +struct cn10k_ddr_pmu {
> +	struct pmu pmu;
> +	int id;
> +	void __iomem *base;
> +	unsigned int cpu;
> +	struct	device *dev;
> +	int active_events;
> +	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
> +};
> +
> +#define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu, pmu)
> +
> +static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
> +					struct device_attribute *attr,
> +					char *page)
> +{
> +	struct perf_pmu_events_attr *pmu_attr;
> +
> +	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
> +	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
> +}
> +
> +#define CN10K_DDR_PMU_EVENT_ATTR(_name, _id)				     \
> +	PMU_EVENT_ATTR_ID(_name, cn10k_ddr_pmu_event_show, _id)
> +
> +static struct attribute *cn10k_ddr_perf_events_attrs[] = {
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access, EVENT_HIF_RD_OR_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access, EVENT_HIF_RMW),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess, EVENT_HIF_HI_PRI_RD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access, EVENT_READ_BYPASS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access, EVENT_ACT_BYPASS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_wr_data_access, EVENT_DFI_WR_DATA_CYCLES),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_rd_data_access, EVENT_DFI_RD_DATA_CYCLES),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
> +					EVENT_HPR_XACT_WHEN_CRITICAL),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
> +					EVENT_LPR_XACT_WHEN_CRITICAL),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
> +					EVENT_WR_XACT_WHEN_CRITICAL),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access, EVENT_OP_IS_ACTIVATE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access, EVENT_OP_IS_RD_OR_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access, EVENT_OP_IS_RD_ACTIVATE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge, EVENT_OP_IS_PRECHARGE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr, EVENT_PRECHARGE_FOR_RDWR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
> +					EVENT_PRECHARGE_FOR_OTHER),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions, EVENT_RDWR_TRANSITIONS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine, EVENT_WRITE_COMBINE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard, EVENT_WAR_HAZARD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard, EVENT_RAW_HAZARD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard, EVENT_WAW_HAZARD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref, EVENT_OP_IS_ENTER_SELFREF),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown, EVENT_OP_IS_ENTER_POWERDOWN),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_mpsm, EVENT_OP_IS_ENTER_MPSM),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode, EVENT_OP_IS_LOAD_MODE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqcl, EVENT_OP_IS_ZQCL),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_wr_access, EVENT_OP_IS_ZQCS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpr_req_with_nocredit,
> +					EVENT_HPR_REQ_WITH_NOCREDIT),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpr_req_with_nocredit,
> +					EVENT_LPR_REQ_WITH_NOCREDIT),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_alloc, EVENT_BSM_ALLOC),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_starvation, EVENT_BSM_STARVATION),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
> +					EVENT_VISIBLE_WIN_LIMIT_REACHED_RD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
> +					EVENT_VISIBLE_WIN_LIMIT_REACHED_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc, EVENT_OP_IS_DQSOSC_MPC),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr, EVENT_OP_IS_DQSOSC_MRR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_OP_IS_TCR_MRR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_OP_IS_ZQSTART),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_OP_IS_ZQLATCH),
> +	/* Free run event counters */
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
> +	NULL,
> +};
> +
> +static struct attribute_group cn10k_ddr_perf_events_attr_group = {
> +	.name = "events",
> +	.attrs = cn10k_ddr_perf_events_attrs,
> +};
> +
> +PMU_FORMAT_ATTR(event, "config:0-8");
> +
> +static struct attribute *cn10k_ddr_perf_format_attrs[] = {
> +	&format_attr_event.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group cn10k_ddr_perf_format_attr_group = {
> +	.name = "format",
> +	.attrs = cn10k_ddr_perf_format_attrs,
> +};
> +
> +static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
> +					   struct device_attribute *attr,
> +					   char *buf)
> +{
> +	struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
> +
> +	return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> +}
> +
> +static struct device_attribute cn10k_ddr_perf_cpumask_attr =
> +	__ATTR(cpumask, 0444, cn10k_ddr_perf_cpumask_show, NULL);
> +
> +static struct attribute *cn10k_ddr_perf_cpumask_attrs[] = {
> +	&cn10k_ddr_perf_cpumask_attr.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group cn10k_ddr_perf_cpumask_attr_group = {
> +	.attrs = cn10k_ddr_perf_cpumask_attrs,
> +};
> +
> +static const struct attribute_group *cn10k_attr_groups[] = {
> +	&cn10k_ddr_perf_events_attr_group,
> +	&cn10k_ddr_perf_format_attr_group,
> +	&cn10k_ddr_perf_cpumask_attr_group,
> +	NULL,
> +};
> +
> +static uint64_t ddr_perf_get_event_bitmap(int eventid)
> +{
> +	uint64_t event_bitmap = 0;
> +
> +	switch (eventid) {
> +	case EVENT_HIF_RD_OR_WR ... EVENT_WAW_HAZARD:
> +	case EVENT_OP_IS_REFRESH ... EVENT_OP_IS_ZQLATCH:
> +		event_bitmap = (1ULL << (eventid - 1));
> +		break;
> +
> +	case EVENT_OP_IS_ENTER_SELFREF:
> +	case EVENT_OP_IS_ENTER_POWERDOWN:
> +	case EVENT_OP_IS_ENTER_MPSM:
> +		event_bitmap = (0xFULL << (eventid - 1));
> +		break;
> +	default:
> +		pr_err("%s Invalid eventid %d\n", __func__, eventid);
> +		break;
> +	}
> +
> +	return event_bitmap;
> +}
> +
> +static int cn10k_ddr_perf_alloc_counter(struct cn10k_ddr_pmu *pmu,
> +					struct perf_event *event)
> +{
> +	uint8_t config = event->attr.config;
> +	int i;
> +
> +	/* DDR read free-run counter index */
> +	if (config == EVENT_DDR_READS) {
> +		pmu->events[DDRC_PERF_READ_COUNTER_IDX] = event;
> +		return DDRC_PERF_READ_COUNTER_IDX;
> +	}
> +
> +	/* DDR write free-run counter index */
> +	if (config == EVENT_DDR_WRITES) {
> +		pmu->events[DDRC_PERF_WRITE_COUNTER_IDX] = event;
> +		return DDRC_PERF_WRITE_COUNTER_IDX;
> +	}
> +
> +	/* Allocate DDR generic counters */
> +	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
> +		if (pmu->events[i] == NULL) {
> +			pmu->events[i] = event;
> +			return i;
> +		}
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +static void cn10k_ddr_perf_free_counter(struct cn10k_ddr_pmu *pmu, int counter)
> +{
> +	pmu->events[counter] = NULL;
> +}
> +
> +static int cn10k_ddr_perf_event_init(struct perf_event *event)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	if (event->attr.type != event->pmu->type)
> +		return -ENOENT;
> +
> +	if (is_sampling_event(event)) {
> +		dev_info(pmu->dev, "Sampling not supported!\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	if (event->cpu < 0) {
> +		dev_warn(pmu->dev, "Can't provide per-task data!\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	/*  We must NOT create groups containing mixed PMUs */
> +	if (event->group_leader->pmu != event->pmu &&
> +			!is_software_event(event->group_leader))
> +		return -EINVAL;
> +
> +	/* Set ownership of event to one CPU, same event can not be observed
> +	 * on multiple cpus at same time.
> +	 */
> +	event->cpu = pmu->cpu;
> +	hwc->idx = -1;
> +	return 0;
> +}
> +
> +static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
> +					  int counter, bool enable)
> +{
> +	uint32_t reg;
> +	uint64_t val;
> +
> +	if (counter > DDRC_PERF_NUM_COUNTERS) {
> +		pr_err("Error: unsupported counter %d\n", counter);
> +		return;
> +	}
> +
> +	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
> +		reg = DDRC_PERF_CFG(counter);
> +		val = readq_relaxed(pmu->base + reg);
> +
> +		if (enable)
> +			val |= EVENT_ENABLE;
> +		else
> +			val &= ~EVENT_ENABLE;
> +
> +		writeq_relaxed(val, pmu->base + reg);
> +	} else {
> +		val = readq_relaxed(pmu->base + DDRC_PERF_CNT_FREERUN_EN);
> +		if (enable) {
> +			if (counter == DDRC_PERF_READ_COUNTER_IDX)
> +				val |= DDRC_PERF_FREERUN_READ_EN;
> +			else
> +				val |= DDRC_PERF_FREERUN_WRITE_EN;
> +		} else {
> +			if (counter == DDRC_PERF_READ_COUNTER_IDX)
> +				val &= ~DDRC_PERF_FREERUN_READ_EN;
> +			else
> +				val &= ~DDRC_PERF_FREERUN_WRITE_EN;
> +		}
> +		writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_EN);
> +	}
> +}
> +
> +static uint64_t cn10k_ddr_perf_read_counter(struct cn10k_ddr_pmu *pmu,
> +					    int counter)
> +{
> +	uint64_t val;
> +
> +	if (counter == DDRC_PERF_READ_COUNTER_IDX)
> +		return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_RD_OP);
> +
> +	if (counter == DDRC_PERF_WRITE_COUNTER_IDX)
> +		return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_WR_OP);
> +
> +	val = readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE(counter));
> +	return val;
> +}
> +
> +static void cn10k_ddr_perf_event_update(struct perf_event *event)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	uint64_t prev_count, new_count, mask;
> +
> +	do {
> +		prev_count = local64_read(&hwc->prev_count);
> +		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
> +	} while (local64_xchg(&hwc->prev_count, new_count) != prev_count);
> +
> +	mask = DDRC_PERF_CNT_MAX_VALUE;
> +
> +	local64_add((new_count - prev_count) & mask, &event->count);
> +}
> +
> +static void cn10k_ddr_perf_event_start(struct perf_event *event, int flags)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int counter = hwc->idx;
> +
> +	local64_set(&hwc->prev_count, 0);
> +
> +	cn10k_ddr_perf_counter_enable(pmu, counter, true);
> +
> +	hwc->state = 0;
> +}
> +
> +static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	uint8_t config = event->attr.config;
> +	uint32_t reg_offset;
> +	uint64_t val;
> +	int counter;
> +
> +	counter = cn10k_ddr_perf_alloc_counter(pmu, event);
> +	if (counter < 0) {
> +		dev_dbg(pmu->dev, "There are not enough counters\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	pmu->active_events++;
> +	hwc->idx = counter;
> +
> +	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
> +		/* Generic counters, configure event id */
> +		reg_offset = DDRC_PERF_CFG(counter);
> +		val = ddr_perf_get_event_bitmap(config);
> +		writeq_relaxed(val, pmu->base + reg_offset);
> +	} else {
> +		/* fixed event counter, clear counter value */
> +		if (counter == DDRC_PERF_READ_COUNTER_IDX)
> +			val = DDRC_FREERUN_READ_CNT_CLR;
> +		else
> +			val = DDRC_FREERUN_WRITE_CNT_CLR;
> +
> +		writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_CTRL);
> +	}
> +
> +	hwc->state |= PERF_HES_STOPPED;
> +
> +	if (flags & PERF_EF_START)
> +		cn10k_ddr_perf_event_start(event, flags);
> +
> +	return 0;
> +}
> +
> +static void cn10k_ddr_perf_event_stop(struct perf_event *event, int flags)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int counter = hwc->idx;
> +
> +	cn10k_ddr_perf_counter_enable(pmu, counter, false);
> +
> +	if (flags & PERF_EF_UPDATE)
> +		cn10k_ddr_perf_event_update(event);
> +
> +	hwc->state |= PERF_HES_STOPPED;
> +}
> +
> +static void cn10k_ddr_perf_event_del(struct perf_event *event, int flags)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int counter = hwc->idx;
> +
> +	cn10k_ddr_perf_event_stop(event, PERF_EF_UPDATE);
> +
> +	cn10k_ddr_perf_free_counter(pmu, counter);
> +	pmu->active_events--;
> +	hwc->idx = -1;
> +}
> +
> +static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu)
> +{
> +	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
> +
> +	writeq_relaxed(START_OP_CTRL_VAL_START, ddr_pmu->base +
> +		       DDRC_PERF_CNT_START_OP_CTRL);
> +}
> +
> +static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu)
> +{
> +	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
> +
> +	writeq_relaxed(END_OP_CTRL_VAL_END, ddr_pmu->base +
> +		       DDRC_PERF_CNT_END_OP_CTRL);
> +}
> +
> +static int cn10k_ddr_perf_probe(struct platform_device *pdev)
> +{
> +	struct cn10k_ddr_pmu *ddr_pmu;
> +	struct resource *res;
> +	void __iomem *base;
> +	static int index;
> +	char *name;
> +	int ret;
> +
> +	ddr_pmu = devm_kzalloc(&pdev->dev, sizeof(*ddr_pmu), GFP_KERNEL);
> +	if (!ddr_pmu)
> +		return -ENOMEM;
> +
> +	ddr_pmu->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, ddr_pmu);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	ddr_pmu->base = base;
> +
> +	/* Setup the PMU counter to work in mannual mode */
> +	writeq_relaxed(OP_MODE_CTRL_VAL_MANNUAL, ddr_pmu->base +
> +		       DDRC_PERF_CNT_OP_MODE_CTRL);
> +
> +	ddr_pmu->pmu = (struct pmu) {
> +		.module	      = THIS_MODULE,
> +		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> +		.task_ctx_nr = perf_invalid_context,
> +		.attr_groups = cn10k_attr_groups,
> +		.event_init  = cn10k_ddr_perf_event_init,
> +		.add	     = cn10k_ddr_perf_event_add,
> +		.del	     = cn10k_ddr_perf_event_del,
> +		.start	     = cn10k_ddr_perf_event_start,
> +		.stop	     = cn10k_ddr_perf_event_stop,
> +		.read	     = cn10k_ddr_perf_event_update,
> +		.pmu_enable  = cn10k_ddr_perf_pmu_enable,
> +		.pmu_disable = cn10k_ddr_perf_pmu_disable,
> +	};
> +
> +	/* Choose this cpu to collect perf data */
> +	ddr_pmu->cpu = raw_smp_processor_id();
> +
> +	name = devm_kasprintf(ddr_pmu->dev, GFP_KERNEL, "mrvl_ddr_pmu@%llx",
> +			      res->start);
> +	if (!name)
> +		return -ENOMEM;
> +
> +	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
> +	if (ret)
> +		return ret;

Hi Bharat,
   Do we need to free memory allocated to ddr_pmu incase perf_pmu_register fails? I think right now
we might have memory leaks here.
Also you added cpu hotplug support in patch 4, but cpu variable is added in this patch. Will it be better
to move addition of cpu part also in patch 4?

Thanks,
Kajol Jain

> +
> +	ddr_pmu->id = index++;
> +	pr_info("CN10K DDR PMU Driver for ddrc@%llx - id-%d\n",
> +		res->start, ddr_pmu->id);
> +	return 0;
> +}
> +
> +static int cn10k_ddr_perf_remove(struct platform_device *pdev)
> +{
> +	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
> +
> +	perf_pmu_unregister(&ddr_pmu->pmu);
> +	return 0;
> +}
> +
> +static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
> +	{ .compatible = "marvell,cn10k-ddr-pmu", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
> +
> +static struct platform_driver cn10k_ddr_pmu_driver = {
> +	.driver	= {
> +		.name   = "cn10k-ddr-pmu",
> +		.of_match_table = cn10k_ddr_pmu_of_match,
> +		.suppress_bind_attrs = true,
> +	},
> +	.probe		= cn10k_ddr_perf_probe,
> +	.remove		= cn10k_ddr_perf_remove,
> +};
> +
> +static int __init cn10k_ddr_pmu_init(void)
> +{
> +	return platform_driver_register(&cn10k_ddr_pmu_driver);
> +}
> +
> +static void __exit cn10k_ddr_pmu_exit(void)
> +{
> +	platform_driver_unregister(&cn10k_ddr_pmu_driver);
> +}
> +
> +module_init(cn10k_ddr_pmu_init);
> +module_exit(cn10k_ddr_pmu_exit);
> +
> +MODULE_AUTHOR("Bharat Bhushan <bbhushan2 at marvell.com>");
> +MODULE_LICENSE("GPL v2");
> 


From lukas.bulwahn at gmail.com  Wed Aug 18 05:41:09 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed, 18 Aug 2021 14:41:09 +0200
Subject: [PATCH 0/5] Kconfig symbol clean-up on gpu
Message-ID: <20210818124114.28545-1-lukas.bulwahn@gmail.com>

Dear DRM maintainers,

The script ./scripts/checkkconfigsymbols.py warns on invalid references to
Kconfig symbols (often, minor typos, name confusions or outdated references).

This patch series addresses all issues reported by ./scripts/checkkconfigsymbols.py
in ./drivers/gpu/ for Kconfig and Makefile files. Issues in the Kconfig and
Makefile files indicate some shortcomings in the overall build definitions, and
often are true actionable issues to address.

These issues can be identified and filtered by:

  ./scripts/checkkconfigsymbols.py | grep -E "drivers/gpu/.*(Kconfig|Makefile)" -B 1 -A 1

After applying this patch series on linux-next (next-20210817), the command
above yields just one further issues to address:

DRM_AMD_DC_DCE11_0
Referencing files: drivers/gpu/drm/amd/display/dc/dce100/Makefile

  Conclusion: No action required.
  Rationale:
    drivers/gpu/drm/amd/display/dc/dce100/Makefile refers to
    DRM_AMD_DC_DCE11_0 in a comment, after an "ifdef 0".


Please pick this patch series into your drm-next tree.

Best regards,

Lukas

Lukas Bulwahn (5):
  drm: rockchip: remove reference to non-existing config DRM_RGB
  drm: amdgpu: remove obsolete reference to config CHASH
  drm: v3d: correct reference to config ARCH_BRCMSTB
  drm: zte: remove obsolete DRM Support for ZTE SoCs
  drm: omap: remove obsolete selection of OMAP2_DSS in config DRM_OMAP

 drivers/gpu/drm/Kconfig              |   1 -
 drivers/gpu/drm/Makefile             |   1 -
 drivers/gpu/drm/omapdrm/Kconfig      |   1 -
 drivers/gpu/drm/rockchip/Kconfig     |   1 -
 drivers/gpu/drm/v3d/Kconfig          |   2 +-
 drivers/gpu/drm/zte/Kconfig          |  10 -
 drivers/gpu/drm/zte/Makefile         |  10 -
 drivers/gpu/drm/zte/zx_common_regs.h |  28 -
 drivers/gpu/drm/zte/zx_drm_drv.c     | 184 ------
 drivers/gpu/drm/zte/zx_drm_drv.h     |  34 -
 drivers/gpu/drm/zte/zx_hdmi.c        | 760 ----------------------
 drivers/gpu/drm/zte/zx_hdmi_regs.h   |  66 --
 drivers/gpu/drm/zte/zx_plane.c       | 537 ----------------
 drivers/gpu/drm/zte/zx_plane.h       |  26 -
 drivers/gpu/drm/zte/zx_plane_regs.h  | 120 ----
 drivers/gpu/drm/zte/zx_tvenc.c       | 400 ------------
 drivers/gpu/drm/zte/zx_tvenc_regs.h  |  27 -
 drivers/gpu/drm/zte/zx_vga.c         | 527 ---------------
 drivers/gpu/drm/zte/zx_vga_regs.h    |  33 -
 drivers/gpu/drm/zte/zx_vou.c         | 921 ---------------------------
 drivers/gpu/drm/zte/zx_vou.h         |  64 --
 drivers/gpu/drm/zte/zx_vou_regs.h    | 212 ------
 22 files changed, 1 insertion(+), 3964 deletions(-)
 delete mode 100644 drivers/gpu/drm/zte/Kconfig
 delete mode 100644 drivers/gpu/drm/zte/Makefile
 delete mode 100644 drivers/gpu/drm/zte/zx_common_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.c
 delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.h
 delete mode 100644 drivers/gpu/drm/zte/zx_hdmi.c
 delete mode 100644 drivers/gpu/drm/zte/zx_hdmi_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_plane.c
 delete mode 100644 drivers/gpu/drm/zte/zx_plane.h
 delete mode 100644 drivers/gpu/drm/zte/zx_plane_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_tvenc.c
 delete mode 100644 drivers/gpu/drm/zte/zx_tvenc_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vga.c
 delete mode 100644 drivers/gpu/drm/zte/zx_vga_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vou.c
 delete mode 100644 drivers/gpu/drm/zte/zx_vou.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vou_regs.h

-- 
2.26.2



From lukas.bulwahn at gmail.com  Wed Aug 18 05:41:10 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed, 18 Aug 2021 14:41:10 +0200
Subject: [PATCH 1/5] drm: rockchip: remove reference to non-existing config
 DRM_RGB
In-Reply-To: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
References: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
Message-ID: <20210818124114.28545-2-lukas.bulwahn@gmail.com>

commit 1f0f01515172 ("drm/rockchip: Add support for Rockchip Soc RGB
output interface") accidently adds to select the non-existing config
DRM_RGB in ./drivers/gpu/drm/rockchip/Kconfig.

Luckily, ./scripts/checkkconfigsymbols.py warns on non-existing configs:

DRM_RGB
Referencing files: drivers/gpu/drm/rockchip/Kconfig

So, remove the reference to the non-existing config DRM_RGB.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/gpu/drm/rockchip/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 558f1b58bd69..9f1ecefc3933 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -9,7 +9,6 @@ config DRM_ROCKCHIP
 	select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
 	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
 	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
-	select DRM_RGB if ROCKCHIP_RGB
 	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
 	select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
 	select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
-- 
2.26.2



From lukas.bulwahn at gmail.com  Wed Aug 18 05:41:11 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed, 18 Aug 2021 14:41:11 +0200
Subject: [PATCH 2/5] drm: amdgpu: remove obsolete reference to config CHASH
In-Reply-To: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
References: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
Message-ID: <20210818124114.28545-3-lukas.bulwahn@gmail.com>

Commit 04ed8459f334 ("drm/amdgpu: remove chash") removes the chash
architecture and its corresponding config CHASH.

There is still a reference to CHASH in the config DRM_AMDGPU in
./drivers/gpu/drm/Kconfig.

Remove this obsolete reference to config CHASH.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/gpu/drm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f3bc90baca61..8fc40317f2b7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -257,7 +257,6 @@ config DRM_AMDGPU
 	select HWMON
 	select BACKLIGHT_CLASS_DEVICE
 	select INTERVAL_TREE
-	select CHASH
 	help
 	  Choose this option if you have a recent AMD Radeon graphics card.
 
-- 
2.26.2



From lukas.bulwahn at gmail.com  Wed Aug 18 05:41:12 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed, 18 Aug 2021 14:41:12 +0200
Subject: [PATCH 3/5] drm: v3d: correct reference to config ARCH_BRCMSTB
In-Reply-To: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
References: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
Message-ID: <20210818124114.28545-4-lukas.bulwahn@gmail.com>

Commit 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D
V3.x+") adds the config DRM_V3D, which depends on "ARCH_BCMSTB".

Although, a bit confusing: all Broadcom architectures in
./arch/arm/mach-bcm/Kconfig have the prefix "ARCH_BCM", except for
ARCH_BRCMSTB, i.e., the config for Broadcom BCM7XXX based boards.

So, correct the reference ARCH_BCMSTB to the intended ARCH_BRCMSTB.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/gpu/drm/v3d/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/Kconfig b/drivers/gpu/drm/v3d/Kconfig
index 9a5c44606337..e973ec487484 100644
--- a/drivers/gpu/drm/v3d/Kconfig
+++ b/drivers/gpu/drm/v3d/Kconfig
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config DRM_V3D
 	tristate "Broadcom V3D 3.x and newer"
-	depends on ARCH_BCM || ARCH_BCMSTB || COMPILE_TEST
+	depends on ARCH_BCM || ARCH_BRCMSTB || COMPILE_TEST
 	depends on DRM
 	depends on COMMON_CLK
 	depends on MMU
-- 
2.26.2



From lukas.bulwahn at gmail.com  Wed Aug 18 05:41:14 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Wed, 18 Aug 2021 14:41:14 +0200
Subject: [PATCH 5/5] drm: omap: remove obsolete selection of OMAP2_DSS in
 config DRM_OMAP
In-Reply-To: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
References: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
Message-ID: <20210818124114.28545-6-lukas.bulwahn@gmail.com>

Commit 55b68fb856b5 ("drm/omap: squash omapdrm sub-modules into one")
removes the config OMAP2_DSS in ./drivers/gpu/drm/omapdrm/dss/Kconfig,
while moving the other configs into./drivers/gpu/drm/omapdrm/Kconfig, but
misses to remove an obsolete selection of OMAP2_DSS in config DRM_OMAP.

Hence, ./scripts/checkkconfigsymbols.py warns:

OMAP2_DSS
Referencing files: drivers/gpu/drm/omapdrm/Kconfig

Remove this reference in an obsolete selection.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/gpu/drm/omapdrm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index e7281da5bc6a..d6e4df291d6f 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -3,7 +3,6 @@ config DRM_OMAP
 	tristate "OMAP DRM"
 	depends on DRM
 	depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
-	select OMAP2_DSS
 	select DRM_KMS_HELPER
 	select VIDEOMODE_HELPERS
 	select HDMI
-- 
2.26.2



From maxime at cerno.tech  Wed Aug 18 05:43:04 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 18 Aug 2021 14:43:04 +0200
Subject: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel
 compatibles
In-Reply-To: <20210722022947.GA3168293@robh.at.kernel.org>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-11-maxime@cerno.tech>
 <20210722022947.GA3168293@robh.at.kernel.org>
Message-ID: <20210818124304.2jxsf44bcbprcvbk@gilmour>

Hi Rob, Sam,

On Wed, Jul 21, 2021 at 08:29:47PM -0600, Rob Herring wrote:
> On Wed, Jul 21, 2021 at 04:03:40PM +0200, Maxime Ripard wrote:
> > The binding mentions that all the drivers using that driver must use a
> > vendor-specific compatible but never enforces it, nor documents the
> > vendor-specific compatibles.
> > 
> > Let's make we document all of them, and that the binding will create an
> > error if we add one that isn't.
> > 
> > Cc: dri-devel at lists.freedesktop.org
> > Cc: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > Cc: Sam Ravnborg <sam at ravnborg.org>
> > Cc: Thierry Reding <thierry.reding at gmail.com>
> > Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> > ---
> >  .../bindings/display/panel/lvds.yaml           | 18 ++++++++++++------
> >  1 file changed, 12 insertions(+), 6 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > index 49460c9dceea..d1513111eb48 100644
> > --- a/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > +++ b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > @@ -31,12 +31,18 @@ allOf:
> >  
> >  properties:
> >    compatible:
> > -    contains:
> > -      const: panel-lvds
> > -    description:
> > -      Shall contain "panel-lvds" in addition to a mandatory panel-specific
> > -      compatible string defined in individual panel bindings. The "panel-lvds"
> > -      value shall never be used on its own.
> > +    items:
> > +      - enum:
> > +          - advantech,idk-1110wr
> 
> At least this one is documented elsewhere.

Indeed, I missed it.

> You can add 'minItems: 2' if you want to just enforce having 2 compatibles. Or do:
> 
> items:
>   - {}
>   - const: panel-lvds
> 
> Which also enforces the order.

It's not just about the order since a missing compatible will also raise
a warning.

Some of those panels have a binding of their own, but some probably
won't (and I can't find anything specific about the one I'm most
interested in: tbs,a711-panel)

Can we have something like:

compatible:
  oneOf:
    - items:
      - enum:
	- tbs,a711-panel
      - const: panel-lvds

    - items:
      - {}
      - const: panel-lvds

That would work for both cases I guess?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210818/1e615f80/attachment.sig>

From robh+dt at kernel.org  Wed Aug 18 05:54:59 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 07:54:59 -0500
Subject: [PATCH 05/54] dt-bindings: Convert Reserved Memory binding to a
 schema
In-Reply-To: <20210818100021.yzzcuadkowy4tfv4@gilmour>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-6-maxime@cerno.tech>
 <CAL_JsqKAZLBK2UDDUNrO4aaYr886oODB_N_yF70X44gPXs=k5Q@mail.gmail.com>
 <20210818100021.yzzcuadkowy4tfv4@gilmour>
Message-ID: <CAL_JsqK8ZDy=4_KmB_5ce4Z1=XcKH7EgydAVuC5Cko6F63ACrQ@mail.gmail.com>

On Wed, Aug 18, 2021 at 5:00 AM Maxime Ripard <maxime at cerno.tech> wrote:
>
> Hi Rob,
>
> On Wed, Jul 21, 2021 at 08:30:43AM -0600, Rob Herring wrote:
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/reserved-memory/reserved-memory.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: /reserved-memory Node
> > > +
> > > +maintainers:
> > > +  - Devicetree Specification Mailing List <devicetree-spec at vger.kernel.org>
> > > +
> > > +description: >
> > > +  Reserved memory is specified as a node under the /reserved-memory node. The
> > > +  operating system shall exclude reserved memory from normal usage one can
> > > +  create child nodes describing particular reserved (excluded from normal use)
> > > +  memory regions. Such memory regions are usually designed for the special
> > > +  usage by various device drivers.
> > > +
> > > +properties:
> > > +  $nodename:
> > > +    const: reserved-memory
> > > +
> > > +  "#address-cells": true
> > > +  "#size-cells": true
> > > +  ranges: true
> > > +
> > > +patternProperties:
> > > +  "^(?!(ranges))[a-z,-]*(@[0-9]+)?$":
> >
> > Note that you could drop this and put under 'additionalProperties'.
> > You would lose some node name checking, but there's really little
> > standard on these nodes.
>
> I didn't realise it could be used that way too, I'll change it.
>
> > > +    type: object
> > > +
> > > +    description: >
> > > +      Each child of the reserved-memory node specifies one or more regions of
> > > +      reserved memory. Each child node may either use a 'reg' property to
> > > +      specify a specific range of reserved memory, or a 'size' property with
> > > +      optional constraints to request a dynamically allocated block of memory.
> > > +
> > > +      Following the generic-names recommended practice, node names should
> > > +      reflect the purpose of the node (ie. "framebuffer" or "dma-pool"). Unit
> > > +      address (@<address>) should be appended to the name if the node is a
> > > +      static allocation.
> > > +
> > > +    properties:
> > > +      reg: true
> > > +
> > > +      size:
> > > +        $ref: /schemas/types.yaml#/definitions/uint32-array
> > > +        description: >
> > > +          Length based on parent's \#size-cells. Size in bytes of memory to
> > > +          reserve.
> > > +
> > > +      alignment:
> > > +        $ref: /schemas/types.yaml#/definitions/uint32-array
> > > +        description: >
> > > +          Length based on parent's \#size-cells. Address boundary for
> > > +          alignment of allocation.
> > > +
> > > +      alloc-ranges:
> > > +        $ref: /schemas/types.yaml#/definitions/uint32-array
> > > +        description: >
> > > +          Address and Length pairs. Specifies regions of memory that are
> > > +          acceptable to allocate from.
> > > +
> > > +      compatible:
> > > +        oneOf:
> > > +          - const: shared-dma-pool
> > > +            description: >
> > > +              This indicates a region of memory meant to be used as a shared
> > > +              pool of DMA buffers for a set of devices. It can be used by an
> > > +              operating system to instantiate the necessary pool management
> > > +              subsystem if necessary.
> > > +
> > > +          # Vendor-specific compatibles in the form <vendor>,[<device>-]<usage>
> > > +          - const: mediatek,trustzone-bootinfo
> >
> > I think these should be separate schema files. At least, we're going
> > to need to support separate files because I don't think we want ones
> > adding custom properties here. This would fail unless we add every
> > compatible here. We could also be a bit more exact as to which
> > properties below apply (e.g. linux,.*-default is only valid for
> > shared-dma-pool).
>
> I'm not entirely sure how we can just ignore the vendor compatibles
> without raising a warning. Do you have any suggestion?

You need 1 schema file with all the common (child) properties and then
1 schema file for each compatible (maybe some can be grouped) that
references the common schema.

You'd lose checking that the child nodes are actually children of
/reserved-memory, but I'm not too worried about that.

Rob


From arnd at kernel.org  Wed Aug 18 05:59:22 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 14:59:22 +0200
Subject: [GIT PULL] Qualcomm ARM64 updates for v5.15
In-Reply-To: <20210816231223.586597-1-bjorn.andersson@linaro.org>
References: <20210816231223.586597-1-bjorn.andersson@linaro.org>
Message-ID: <162929137182.372162.1107207134095888693.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 16 Aug 2021 18:12:23 -0500, Bjorn Andersson wrote:
> The following changes since commit ff1176468d368232b684f75e82563369208bc371:
> 
>   Linux 5.14-rc3 (2021-07-25 15:35:14 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-arm64-for-5.15
> 
> [...]

Merged into arm/dt, thanks!

merge commit: a0f480dc6546b9d97027bf7bc8145aad48ddad00

       Arnd


From arnd at kernel.org  Wed Aug 18 05:59:23 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 14:59:23 +0200
Subject: [GIT PULL] Qualcomm dts updates for v5.15
In-Reply-To: <20210816211957.579365-1-bjorn.andersson@linaro.org>
References: <20210816211957.579365-1-bjorn.andersson@linaro.org>
Message-ID: <162929137177.372162.12275626408150474282.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 16 Aug 2021 16:19:57 -0500, Bjorn Andersson wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-dts-for-5.15
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 4d314179d62b19d0b5ac8de51b491494359c7a19

       Arnd


From arnd at kernel.org  Wed Aug 18 05:59:24 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 14:59:24 +0200
Subject: [GIT PULL] ARM: mvebu: dt64 for v5.15 (#1)
In-Reply-To: <878s10ypxe.fsf@BL-laptop>
References: <878s10ypxe.fsf@BL-laptop>
Message-ID: <162929137212.372162.12996626191507618886.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 17 Aug 2021 18:52:13 +0200, Gregory CLEMENT wrote:
> Here is the first pull request for dt64 for mvebu for v5.15.
> 
> Gregory
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> [...]

Merged into arm/dt, thanks!

merge commit: c4d3928250de919a1d324f6c8a7f26f51af40fd2

       Arnd


From arnd at kernel.org  Wed Aug 18 05:59:25 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 14:59:25 +0200
Subject: [GIT PULL] ARM: aspeed: devicetree changes for 5.15
In-Reply-To: <CACPK8XdWRBb9cuDWGQPfK8R8TsZuydJQHsL4_e2w=HvCKAMogg@mail.gmail.com>
References: <CACPK8XdWRBb9cuDWGQPfK8R8TsZuydJQHsL4_e2w=HvCKAMogg@mail.gmail.com>
Message-ID: <162929137186.372162.11203697127775599651.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 17 Aug 2021 07:51:54 +0000, Joel Stanley wrote:
> Here are the aspeed changes for 5.15.
> 
> The following changes since commit 2734d6c1b1a089fb593ef6a23d4b70903526fe0c:
> 
>   Linux 5.14-rc2 (2021-07-18 14:13:49 -0700)
> 
> are available in the Git repository at:
> 
> [...]

Merged into arm/dt, thanks!

merge commit: c872138c2c7166dc95c778f4decc165bace9cb33

       Arnd


From arnd at kernel.org  Wed Aug 18 05:59:26 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 14:59:26 +0200
Subject: [GIT PULL] Allwinner Device Tree Changes for 5.15
In-Reply-To: <39cd7be5-a9a7-42b6-bc29-f895b9a3448a.lettre@localhost>
References: <39cd7be5-a9a7-42b6-bc29-f895b9a3448a.lettre@localhost>
Message-ID: <162929137195.372162.12135615382649684003.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 17 Aug 2021 10:35:04 +0200, Maxime Ripard wrote:
> It's been a fairly quiet merge window for us, but please pull the
> following changes for the next release.
> 
> Thanks!
> Maxime
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 4b2784473108ffaac1ab78a2de928931693e47fe

       Arnd


From arnd at kernel.org  Wed Aug 18 05:59:27 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 14:59:27 +0200
Subject: [GIT PULL] arm64: dts: hisilicon dts updates for v5.15
In-Reply-To: <611B9BE9.8050904@hisilicon.com>
References: <611B9BE9.8050904@hisilicon.com>
Message-ID: <162929137204.372162.7039199681946826323.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Tue, 17 Aug 2021 19:22:17 +0800, Wei Xu wrote:
> Please consider to pull the following changes.
> Thanks!
> 
> Best Regards,
> Wei

Merged into arm/dt, thanks!

merge commit: 911f0faf485817a1e70bcaad8121201ef0f30ae2

       Arnd


From a.fatoum at pengutronix.de  Wed Aug 18 06:05:28 2021
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Wed, 18 Aug 2021 15:05:28 +0200
Subject: [PATCH V3 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <SJ0PR02MB86443029095BF5949E51808AD4FF9@SJ0PR02MB8644.namprd02.prod.outlook.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-4-piyush.mehta@xilinx.com>
 <b3d718af-6eb7-a212-f599-d0d91273afdc@pengutronix.de>
 <SJ0PR02MB86443029095BF5949E51808AD4FF9@SJ0PR02MB8644.namprd02.prod.outlook.com>
Message-ID: <a1bd7d9f-5746-2d4c-8658-beb804468846@pengutronix.de>

Hello Piyush,

On 18.08.21 12:09, Piyush Mehta wrote:
> Hi Ahmad,
> 
> -----Original Message-----
> From: Ahmad Fatoum <a.fatoum at pengutronix.de> 
> Sent: Wednesday, August 18, 2021 2:22 PM
> To: Piyush Mehta <piyushm at xilinx.com>; arnd at arndb.de; zou_wei at huawei.com; gregkh at linuxfoundation.org; linus.walleij at linaro.org; Michal Simek <michals at xilinx.com>; Jiaying Liang <jliang at xilinx.com>; iwamatsu at nigauri.org; bgolaszewski at baylibre.com; robh+dt at kernel.org; Rajan Vaja <RAJANV at xilinx.com>
> Cc: linux-gpio at vger.kernel.org; devicetree at vger.kernel.org; git <git at xilinx.com>; Srinivas Goud <sgoud at xilinx.com>; linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Pengutronix Kernel Team <kernel at pengutronix.de>
> Subject: Re: [PATCH V3 3/3] gpio: modepin: Add driver support for modepin GPIO controller
> 
> On 18.08.21 10:10, Piyush Mehta wrote:
>> This patch adds driver support for the zynqmp modepin GPIO controller.
>> GPIO modepin driver set and get the value and status of the PS_MODE 
>> pin, based on device-tree pin configuration. These four mode pins are 
>> configurable as input/output. The mode pin has a control register, 
>> which have lower four-bits [0:3] are configurable as input/output, 
>> next four-bits can be used for reading the data  as input[4:7], and 
>> next setting the output pin state output[8:11].
>>
>> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
>> Acked-by: Michal Simek <michal.simek at xilinx.com>
>> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>> ---
> 
>> +/**
>> + * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input
>> + * @chip:	gpio_chip instance to be worked on
>> + * @pin:	gpio pin number within the device
>> + *
>> + * Return: 0 always
>> + */
>> +static int modepin_gpio_dir_in(struct gpio_chip *chip, unsigned int 
>> +pin) {
>> +	return 0;
>> +}
> 
> You say the gpio controller can configure pins as inputs or outputs.
> These pins are controller via firmware driver. We are updating BOOT_PIN_CTRL 	0xFF5E0250 register.
> [0:3]  = When 0, the pins will be inputs from the board to the PS. When 1, the PS will drive these pins

Ok. So if you want to configure the pin as input, you should call zynqmp_pm_bootmode_write
to write a zero into that bit.

But there's only one zynqmp_pm_bootmode_write in the GPIO driver and it's in modepin_gpio_set_value,
which does output, not input. If I understand you right, there should be a modepin_gpio_set_value in
modepin_gpio_dir_in as well?
 
> Yet, .direction_input is doing nothing. So, it's not clear to me, how this sequence could work:
> 
>  - set gpio output high (writes bootmode)
>  - set gpio to input (no-op, pin will remain high, not high impedance)

This is a valid sequence for a GPIO consumer and I don't see how this GPIO driver could
honor it. Could you clarify?

Cheers,
Ahmad

> 
> 
> 
> 
> 
> 
> I didn't check the previous discussions, but if this indeed works as intended, the how should be written here into the driver. That is a more useful comment than kernel doc for a stub function.
> 


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From joro at 8bytes.org  Wed Aug 18 06:09:28 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Wed, 18 Aug 2021 15:09:28 +0200
Subject: [GIT PULL] iommu/arm-smmu: Updates for 5.15
In-Reply-To: <20210818121728.GB14107@willie-the-truck>
References: <20210813164735.GA8765@willie-the-truck>
 <YRz4OemrkIcDxCC5@8bytes.org>
 <20210818121728.GB14107@willie-the-truck>
Message-ID: <YR0GiO+miNkxXp76@8bytes.org>

On Wed, Aug 18, 2021 at 01:17:29PM +0100, Will Deacon wrote:
> Ok, I won't hold my breath!

Compile tests went fine and the kernel booted fine on my workstation, so
I pushed things out. Let's see whether testing in linux-next breaks
anything.

Regards,

	Joerg


From will at kernel.org  Wed Aug 18 06:13:51 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 14:13:51 +0100
Subject: [PATCH v4 06/15] KVM: arm64: Restore mdcr_el2 from vcpu
In-Reply-To: <20210817081134.2918285-7-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-7-tabba@google.com>
Message-ID: <20210818131350.GD14107@willie-the-truck>

On Tue, Aug 17, 2021 at 09:11:25AM +0100, Fuad Tabba wrote:
> On deactivating traps, restore the value of mdcr_el2 from the
> newly created and preserved host value vcpu context, rather than
> directly reading the hardware register.
> 
> Up until and including this patch the two values are the same,
> i.e., the hardware register and the vcpu one. A future patch will
> be changing the value of mdcr_el2 on activating traps, and this
> ensures that its value will be restored.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h       |  5 ++++-
>  arch/arm64/include/asm/kvm_hyp.h        |  2 +-
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  6 +++++-
>  arch/arm64/kvm/hyp/nvhe/switch.c        | 13 +++++--------
>  arch/arm64/kvm/hyp/vhe/switch.c         | 14 +++++---------
>  arch/arm64/kvm/hyp/vhe/sysreg-sr.c      |  2 +-
>  6 files changed, 21 insertions(+), 21 deletions(-)

Acked-by: Will Deacon <will at kernel.org>

Will


From will at kernel.org  Wed Aug 18 06:17:53 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 14:17:53 +0100
Subject: [PATCH v4 07/15] KVM: arm64: Keep mdcr_el2's value as set by
 __init_el2_debug
In-Reply-To: <20210817081134.2918285-8-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-8-tabba@google.com>
Message-ID: <20210818131752.GE14107@willie-the-truck>

On Tue, Aug 17, 2021 at 09:11:26AM +0100, Fuad Tabba wrote:
> __init_el2_debug configures mdcr_el2 at initialization based on,
> among other things, available hardware support. Trap deactivation
> doesn't check that, so keep the initial value.
> 
> No functional change intended. However, the value of mdcr_el2
> might be different after deactivating traps than it was before
> this patch.

I think this sentence is very confusing, so I'd remove it. I also don't
think it's correct, as the EL2 initialisation code only manipulates the
bits which are being masked here.

So with that sentence removed:

Acked-by: Will Deacon <will at kernel.org>

Will


From will at kernel.org  Wed Aug 18 06:21:57 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 18 Aug 2021 14:21:57 +0100
Subject: [PATCH v4 09/15] KVM: arm64: Add feature register flag definitions
In-Reply-To: <20210817081134.2918285-10-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-10-tabba@google.com>
Message-ID: <20210818132156.GF14107@willie-the-truck>

On Tue, Aug 17, 2021 at 09:11:28AM +0100, Fuad Tabba wrote:
> Add feature register flag definitions to clarify which features
> might be supported.
> 
> Consolidate the various ID_AA64PFR0_ELx flags for all ELs.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/cpufeature.h |  4 ++--
>  arch/arm64/include/asm/sysreg.h     | 12 ++++++++----
>  arch/arm64/kernel/cpufeature.c      |  8 ++++----
>  3 files changed, 14 insertions(+), 10 deletions(-)

Thanks, looks better now:

Acked-by: Will Deacon <will at kernel.org>

Will



From arnd at kernel.org  Wed Aug 18 06:34:36 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 15:34:36 +0200
Subject: [GIT PULL] Qualcomm driver updates for v5.15
In-Reply-To: <20210816214840.581244-1-bjorn.andersson@linaro.org>
References: <20210816214840.581244-1-bjorn.andersson@linaro.org>
Message-ID: <162929367332.377646.799358526302496478.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 16 Aug 2021 16:48:40 -0500, Bjorn Andersson wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git tags/qcom-drivers-for-5.15
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 5c785014b67fb25d8e2a36d24940dad0c416a005

       Arnd


From arnd at kernel.org  Wed Aug 18 06:34:37 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 15:34:37 +0200
Subject: [GIT PULL 2/2] Renesas driver updates for v5.15 (take two)
In-Reply-To: <cover.1628849625.git.geert+renesas@glider.be>
References: <cover.1628849621.git.geert+renesas@glider.be>
 <cover.1628849625.git.geert+renesas@glider.be>
Message-ID: <162929367324.377646.18237573210512732738.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 12:22:36 +0200, Geert Uytterhoeven wrote:
> The following changes since commit bfe6b5590ce6cab81b3ee51b4541bd1d0b18b3b2:
> 
>   soc: renesas: Identify R-Car H3e-2G and M3e-2G (2021-07-27 09:27:19 +0200)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git tags/renesas-drivers-for-v5.15-tag2
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 63db5acb4adf3a61c42b387c9c79799b86d25e7f

       Arnd


From arnd at kernel.org  Wed Aug 18 06:34:38 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 15:34:38 +0200
Subject: [GIT PULL 2/6] firmware: tegra: Changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-2-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
 <20210813162157.2820913-2-thierry.reding@gmail.com>
Message-ID: <162929367306.377646.6251992787945452705.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 18:21:53 +0200, Thierry Reding wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-firmware
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 8745d0e9155f0ef13656ab3447f71a8b53556842

       Arnd


From arnd at kernel.org  Wed Aug 18 06:34:39 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 15:34:39 +0200
Subject: [GIT PULL 3/6] soc/tegra: Changes for v5.15-rc1
In-Reply-To: <20210813162157.2820913-3-thierry.reding@gmail.com>
References: <20210813162157.2820913-1-thierry.reding@gmail.com>
 <20210813162157.2820913-3-thierry.reding@gmail.com>
Message-ID: <162929367315.377646.14938708321715472898.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 18:21:54 +0200, Thierry Reding wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-5.15-soc
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: c4361dee2e6cffa32122e06c9df0a9c2e5c4dd51

       Arnd


From arnd at kernel.org  Wed Aug 18 06:43:21 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Wed, 18 Aug 2021 15:43:21 +0200
Subject: [GIT PULL] Delete IXP4xx boardfiles replaced by device trees
In-Reply-To: <CACRpkdY=sPDkzmbmm+0UQnJi7BXZKH14GLmyVwKC+4cLCJpmdA@mail.gmail.com>
References: <CACRpkdY=sPDkzmbmm+0UQnJi7BXZKH14GLmyVwKC+4cLCJpmdA@mail.gmail.com>
Message-ID: <162929419377.379314.14504743675400378814.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Fri, 13 Aug 2021 15:14:01 +0200, Linus Walleij wrote:
> this concludes the first big chunk of IXP4xx cleanup and DT conversion
> by deleting a majority of the boardfiles now supported by the device
> trees.
> 
> The details of which boardfiles are deleted and the two that are kept can
> be found below. The idea is that all devices except the Omicron ones
> will keep being supported, but as device trees. Omicron has publicly
> stated that they have no interest in keeping supporting the boards,
> if someone anyway steps up and need them, scratch device trees
> exist on the mailing list.
> 
> [...]

Merged into arm/soc, thanks!

merge commit: 0fbd7409446a8ee76ee701ec846ede917c6c89fa

       Arnd


From robh at kernel.org  Wed Aug 18 06:48:46 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 08:48:46 -0500
Subject: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel
 compatibles
In-Reply-To: <20210818124304.2jxsf44bcbprcvbk@gilmour>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-11-maxime@cerno.tech>
 <20210722022947.GA3168293@robh.at.kernel.org>
 <20210818124304.2jxsf44bcbprcvbk@gilmour>
Message-ID: <CAL_JsqJjnGhXpfvPWU0HM8YHk5PyDup7ors3ewa17vc0bnVCmQ@mail.gmail.com>

On Wed, Aug 18, 2021 at 7:43 AM Maxime Ripard <maxime at cerno.tech> wrote:
>
> Hi Rob, Sam,
>
> On Wed, Jul 21, 2021 at 08:29:47PM -0600, Rob Herring wrote:
> > On Wed, Jul 21, 2021 at 04:03:40PM +0200, Maxime Ripard wrote:
> > > The binding mentions that all the drivers using that driver must use a
> > > vendor-specific compatible but never enforces it, nor documents the
> > > vendor-specific compatibles.
> > >
> > > Let's make we document all of them, and that the binding will create an
> > > error if we add one that isn't.
> > >
> > > Cc: dri-devel at lists.freedesktop.org
> > > Cc: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > > Cc: Sam Ravnborg <sam at ravnborg.org>
> > > Cc: Thierry Reding <thierry.reding at gmail.com>
> > > Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> > > ---
> > >  .../bindings/display/panel/lvds.yaml           | 18 ++++++++++++------
> > >  1 file changed, 12 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > index 49460c9dceea..d1513111eb48 100644
> > > --- a/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > +++ b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > @@ -31,12 +31,18 @@ allOf:
> > >
> > >  properties:
> > >    compatible:
> > > -    contains:
> > > -      const: panel-lvds
> > > -    description:
> > > -      Shall contain "panel-lvds" in addition to a mandatory panel-specific
> > > -      compatible string defined in individual panel bindings. The "panel-lvds"
> > > -      value shall never be used on its own.
> > > +    items:
> > > +      - enum:
> > > +          - advantech,idk-1110wr
> >
> > At least this one is documented elsewhere.
>
> Indeed, I missed it.
>
> > You can add 'minItems: 2' if you want to just enforce having 2 compatibles. Or do:
> >
> > items:
> >   - {}
> >   - const: panel-lvds
> >
> > Which also enforces the order.
>
> It's not just about the order since a missing compatible will also raise
> a warning.
>
> Some of those panels have a binding of their own, but some probably
> won't (and I can't find anything specific about the one I'm most
> interested in: tbs,a711-panel)
>
> Can we have something like:
>
> compatible:
>   oneOf:
>     - items:
>       - enum:
>         - tbs,a711-panel
>       - const: panel-lvds
>
>     - items:
>       - {}
>       - const: panel-lvds
>
> That would work for both cases I guess?

No, both conditions will be true. If you use 'anyOf', then we're never
really checking the specific compatible.

I think the problem here is trying to mix a common binding (aka an
incomplete collection of properties) and a specific binding. The
former is characterized with 'additionalProperties: true' as we have
here. You need to create a 'panel-simple-lvds.yaml' schema file that
references this one, defines all the 'simple' compatibles, and sets
'unevaluatedProperties: false'.

Rob


From john.garry at huawei.com  Wed Aug 18 06:49:28 2021
From: john.garry at huawei.com (John Garry)
Date: Wed, 18 Aug 2021 14:49:28 +0100
Subject: [PATCH v2 2/4] perf/marvell: CN10k DDR performance monitor support
In-Reply-To: <20210810094307.29595-3-bbhushan2@marvell.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
 <20210810094307.29595-3-bbhushan2@marvell.com>
Message-ID: <c4e9c893-9130-7024-e24e-c63e232be4be@huawei.com>

On 10/08/2021 10:43, Bharat Bhushan wrote:
> Marvell CN10k DRAM Subsystem (DSS) supports eight
> event counters for monitoring performance and software
> can program each counter to monitor any of the defined
> performance event. Performance events are for interface
> between the DDR controller and the PHY, interface between
> the DDR Controller and the CHI interconnect, or within
> the DDR Controller. Additionally DSS also supports two
> fixed performance event counters, one for number of
> ddr reads and other for ddr writes.
> 
> This patch add basic support for these performance
> monitoring events on CN10k.

please use full 75 char width

> 
> Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
> ---
> v1->v2:
>   - writeq/readq changed to respective relaxed version
>   - Using PMU_EVENT_ATTR_ID
> 
>   drivers/perf/Kconfig                 |   7 +
>   drivers/perf/Makefile                |   1 +
>   drivers/perf/marvell_cn10k_ddr_pmu.c | 606 +++++++++++++++++++++++++++
>   3 files changed, 614 insertions(+)
>   create mode 100644 drivers/perf/marvell_cn10k_ddr_pmu.c
> 
> diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
> index 77522e5efe11..41a80a4b8d29 100644
> --- a/drivers/perf/Kconfig
> +++ b/drivers/perf/Kconfig
> @@ -139,4 +139,11 @@ config ARM_DMC620_PMU
>   
>   source "drivers/perf/hisilicon/Kconfig"
>   
> +config MARVELL_CN10K_DDR_PMU
> +	tristate "Enable MARVELL CN10K DRAM Subsystem(DSS) PMU Support"
> +	depends on ARM64

Is there anything to stop using adding COMPILE_TEST as a dependency? 
This really helps build coverage testing for other archs

> +	help
> +	  Enable perf support for Marvell DDR Performance monitoring
> +	  event on CN10K platform.
> +
>   endmenu
> diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
> index 5260b116c7da..ee1126219d8d 100644
> --- a/drivers/perf/Makefile
> +++ b/drivers/perf/Makefile
> @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
>   obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
>   obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
>   obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
> +obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
> diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
> new file mode 100644
> index 000000000000..8f9e3d1fcd8d
> --- /dev/null
> +++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
> @@ -0,0 +1,606 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Marvell CN10K DRAM Subsystem (DSS) Performance Monitor Driver
> + *
> + * Copyright (C) 2021 Marvell.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/perf_event.h>
> +
> +/* Performance Counters Operating Mode Control Registers */
> +#define DDRC_PERF_CNT_OP_MODE_CTRL	0x8020
> +#define OP_MODE_CTRL_VAL_MANNUAL	0x1
> +
> +/* Performance Counters Start Operation Control Registers */
> +#define DDRC_PERF_CNT_START_OP_CTRL	0x8028
> +#define START_OP_CTRL_VAL_START		0x1ULL
> +#define START_OP_CTRL_VAL_ACTIVE	0x2
> +
> +/* Performance Counters End Operation Control Registers */
> +#define DDRC_PERF_CNT_END_OP_CTRL	0x8030
> +#define END_OP_CTRL_VAL_END		0x1ULL
> +
> +/* Performance Counters End Status Registers */
> +#define DDRC_PERF_CNT_END_STATUS		0x8038
> +#define END_STATUS_VAL_END_TIMER_MODE_END	0x1
> +
> +/* Performance Counters Configuration Registers */
> +#define DDRC_PERF_CFG_BASE		0x8040
> +
> +/* 8 Generic event counter + 2 fixed event counters */
> +#define DDRC_PERF_NUM_GEN_COUNTERS	8
> +#define DDRC_PERF_NUM_FIX_COUNTERS	2
> +#define DDRC_PERF_READ_COUNTER_IDX	DDRC_PERF_NUM_GEN_COUNTERS
> +#define DDRC_PERF_WRITE_COUNTER_IDX	(DDRC_PERF_NUM_GEN_COUNTERS + 1)
> +#define DDRC_PERF_NUM_COUNTERS		(DDRC_PERF_NUM_GEN_COUNTERS + \
> +					 DDRC_PERF_NUM_FIX_COUNTERS)
> +
> +/* Generic event counter registers */
> +#define DDRC_PERF_CFG(n)		(DDRC_PERF_CFG_BASE + 8 * (n))
> +#define EVENT_ENABLE			BIT_ULL(63)
> +
> +/* Two dedicated event counters for DDR reads and writes */
> +#define EVENT_DDR_READS			101
> +#define EVENT_DDR_WRITES		100
> +
> +/*
> + * programmable events IDs in programmable event counters.
> + * DO NOT change these event-id numbers, they are used to
> + * program event bitmap in h/w.
> + */
> +#define EVENT_OP_IS_ZQLATCH			55
> +#define EVENT_OP_IS_ZQSTART			54
> +#define EVENT_OP_IS_TCR_MRR			53
> +#define EVENT_OP_IS_DQSOSC_MRR			52
> +#define EVENT_OP_IS_DQSOSC_MPC			51
> +#define EVENT_VISIBLE_WIN_LIMIT_REACHED_WR	50
> +#define EVENT_VISIBLE_WIN_LIMIT_REACHED_RD	49
> +#define EVENT_BSM_STARVATION			48
> +#define EVENT_BSM_ALLOC				47
> +#define EVENT_LPR_REQ_WITH_NOCREDIT		46
> +#define EVENT_HPR_REQ_WITH_NOCREDIT		45
> +#define EVENT_OP_IS_ZQCS			44
> +#define EVENT_OP_IS_ZQCL			43
> +#define EVENT_OP_IS_LOAD_MODE			42
> +#define EVENT_OP_IS_SPEC_REF			41
> +#define EVENT_OP_IS_CRIT_REF			40
> +#define EVENT_OP_IS_REFRESH			39
> +#define EVENT_OP_IS_ENTER_MPSM			35
> +#define EVENT_OP_IS_ENTER_POWERDOWN		31
> +#define EVENT_OP_IS_ENTER_SELFREF		27
> +#define EVENT_WAW_HAZARD			26
> +#define EVENT_RAW_HAZARD			25
> +#define EVENT_WAR_HAZARD			24
> +#define EVENT_WRITE_COMBINE			23
> +#define EVENT_RDWR_TRANSITIONS			22
> +#define EVENT_PRECHARGE_FOR_OTHER		21
> +#define EVENT_PRECHARGE_FOR_RDWR		20
> +#define EVENT_OP_IS_PRECHARGE			19
> +#define EVENT_OP_IS_MWR				18
> +#define EVENT_OP_IS_WR				17
> +#define EVENT_OP_IS_RD				16
> +#define EVENT_OP_IS_RD_ACTIVATE			15
> +#define EVENT_OP_IS_RD_OR_WR			14
> +#define EVENT_OP_IS_ACTIVATE			13
> +#define EVENT_WR_XACT_WHEN_CRITICAL		12
> +#define EVENT_LPR_XACT_WHEN_CRITICAL		11
> +#define EVENT_HPR_XACT_WHEN_CRITICAL		10
> +#define EVENT_DFI_RD_DATA_CYCLES		9
> +#define EVENT_DFI_WR_DATA_CYCLES		8
> +#define EVENT_ACT_BYPASS			7
> +#define EVENT_READ_BYPASS			6
> +#define EVENT_HIF_HI_PRI_RD			5
> +#define EVENT_HIF_RMW				4
> +#define EVENT_HIF_RD				3
> +#define EVENT_HIF_WR				2
> +#define EVENT_HIF_RD_OR_WR			1
> +
> +/* Event counter value registers */
> +#define DDRC_PERF_CNT_VALUE_BASE		0x8080
> +#define DDRC_PERF_CNT_VALUE(n)	(DDRC_PERF_CNT_VALUE_BASE + 8 * (n))
> +
> +/* Fixed event counter enable/disable register */
> +#define DDRC_PERF_CNT_FREERUN_EN	0x80C0
> +#define DDRC_PERF_FREERUN_WRITE_EN	0x1
> +#define DDRC_PERF_FREERUN_READ_EN	0x2
> +
> +/* Fixed event counter control register */
> +#define DDRC_PERF_CNT_FREERUN_CTRL	0x80C8
> +#define DDRC_FREERUN_WRITE_CNT_CLR	0x1
> +#define DDRC_FREERUN_READ_CNT_CLR	0x2
> +
> +/* Fixed event counter value register */
> +#define DDRC_PERF_CNT_VALUE_WR_OP	0x80D0
> +#define DDRC_PERF_CNT_VALUE_RD_OP	0x80D8
> +#define DDRC_PERF_CNT_VALUE_OVERFLOW	BIT_ULL(48)
> +#define DDRC_PERF_CNT_MAX_VALUE		GENMASK_ULL(48, 0)

I assume all these macros are used...

> +
> +struct cn10k_ddr_pmu {
> +	struct pmu pmu;
> +	int id;
> +	void __iomem *base;
> +	unsigned int cpu;
> +	struct	device *dev;
> +	int active_events;
> +	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
> +};
> +
> +#define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu, pmu)
> +
> +static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
> +					struct device_attribute *attr,
> +					char *page)
> +{
> +	struct perf_pmu_events_attr *pmu_attr;
> +
> +	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
> +	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);

isn't sysfs_emit() preferred now? Need to check.

> +}
> +
> +#define CN10K_DDR_PMU_EVENT_ATTR(_name, _id)				     \
> +	PMU_EVENT_ATTR_ID(_name, cn10k_ddr_pmu_event_show, _id)
> +
> +static struct attribute *cn10k_ddr_perf_events_attrs[] = {
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access, EVENT_HIF_RD_OR_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access, EVENT_HIF_RMW),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess, EVENT_HIF_HI_PRI_RD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access, EVENT_READ_BYPASS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access, EVENT_ACT_BYPASS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_wr_data_access, EVENT_DFI_WR_DATA_CYCLES),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_rd_data_access, EVENT_DFI_RD_DATA_CYCLES),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
> +					EVENT_HPR_XACT_WHEN_CRITICAL),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
> +					EVENT_LPR_XACT_WHEN_CRITICAL),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
> +					EVENT_WR_XACT_WHEN_CRITICAL),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access, EVENT_OP_IS_ACTIVATE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access, EVENT_OP_IS_RD_OR_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access, EVENT_OP_IS_RD_ACTIVATE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge, EVENT_OP_IS_PRECHARGE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr, EVENT_PRECHARGE_FOR_RDWR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
> +					EVENT_PRECHARGE_FOR_OTHER),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions, EVENT_RDWR_TRANSITIONS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine, EVENT_WRITE_COMBINE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard, EVENT_WAR_HAZARD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard, EVENT_RAW_HAZARD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard, EVENT_WAW_HAZARD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref, EVENT_OP_IS_ENTER_SELFREF),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown, EVENT_OP_IS_ENTER_POWERDOWN),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_mpsm, EVENT_OP_IS_ENTER_MPSM),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode, EVENT_OP_IS_LOAD_MODE),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqcl, EVENT_OP_IS_ZQCL),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_wr_access, EVENT_OP_IS_ZQCS),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpr_req_with_nocredit,
> +					EVENT_HPR_REQ_WITH_NOCREDIT),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpr_req_with_nocredit,
> +					EVENT_LPR_REQ_WITH_NOCREDIT),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_alloc, EVENT_BSM_ALLOC),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_starvation, EVENT_BSM_STARVATION),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
> +					EVENT_VISIBLE_WIN_LIMIT_REACHED_RD),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
> +					EVENT_VISIBLE_WIN_LIMIT_REACHED_WR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc, EVENT_OP_IS_DQSOSC_MPC),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr, EVENT_OP_IS_DQSOSC_MRR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_OP_IS_TCR_MRR),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_OP_IS_ZQSTART),
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_OP_IS_ZQLATCH),
> +	/* Free run event counters */
> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),

if you want perf tool to support aliases / metrics for these then a hw 
identifer sysfs file is required, like the freescale imx8 ddr pmu driver 
has, as I assume that this PMU is not tightly coupled always to a 
specific CPU

> +	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
> +	NULL,

no need for ',' when the array is not going to be expanded

> +};
> +
> +static struct attribute_group cn10k_ddr_perf_events_attr_group = {
> +	.name = "events",
> +	.attrs = cn10k_ddr_perf_events_attrs,
> +};
> +
> +PMU_FORMAT_ATTR(event, "config:0-8");
> +
> +static struct attribute *cn10k_ddr_perf_format_attrs[] = {
> +	&format_attr_event.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group cn10k_ddr_perf_format_attr_group = {
> +	.name = "format",
> +	.attrs = cn10k_ddr_perf_format_attrs,
> +};
> +
> +static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
> +					   struct device_attribute *attr,
> +					   char *buf)
> +{
> +	struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
> +
> +	return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> +}
> +
> +static struct device_attribute cn10k_ddr_perf_cpumask_attr =
> +	__ATTR(cpumask, 0444, cn10k_ddr_perf_cpumask_show, NULL);
> +
> +static struct attribute *cn10k_ddr_perf_cpumask_attrs[] = {
> +	&cn10k_ddr_perf_cpumask_attr.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group cn10k_ddr_perf_cpumask_attr_group = {
> +	.attrs = cn10k_ddr_perf_cpumask_attrs,
> +};
> +
> +static const struct attribute_group *cn10k_attr_groups[] = {
> +	&cn10k_ddr_perf_events_attr_group,
> +	&cn10k_ddr_perf_format_attr_group,
> +	&cn10k_ddr_perf_cpumask_attr_group,
> +	NULL,
> +};
> +
> +static uint64_t ddr_perf_get_event_bitmap(int eventid)

Don't we use u64 in kernel land as preference?

> +{
> +	uint64_t event_bitmap = 0;
> +
> +	switch (eventid) {
> +	case EVENT_HIF_RD_OR_WR ... EVENT_WAW_HAZARD:
> +	case EVENT_OP_IS_REFRESH ... EVENT_OP_IS_ZQLATCH:
> +		event_bitmap = (1ULL << (eventid - 1));
> +		break;
> +
> +	case EVENT_OP_IS_ENTER_SELFREF:
> +	case EVENT_OP_IS_ENTER_POWERDOWN:
> +	case EVENT_OP_IS_ENTER_MPSM:
> +		event_bitmap = (0xFULL << (eventid - 1));
> +		break;
> +	default:
> +		pr_err("%s Invalid eventid %d\n", __func__, eventid);

shouldn't this generate a proper error to its only caller (which can 
actually error)?

> +		break;
> +	}
> +
> +	return event_bitmap;
> +}
> +
> +static int cn10k_ddr_perf_alloc_counter(struct cn10k_ddr_pmu *pmu,
> +					struct perf_event *event)
> +{
> +	uint8_t config = event->attr.config;
> +	int i;
> +
> +	/* DDR read free-run counter index */
> +	if (config == EVENT_DDR_READS) {
> +		pmu->events[DDRC_PERF_READ_COUNTER_IDX] = event;
> +		return DDRC_PERF_READ_COUNTER_IDX;
> +	}
> +
> +	/* DDR write free-run counter index */
> +	if (config == EVENT_DDR_WRITES) {
> +		pmu->events[DDRC_PERF_WRITE_COUNTER_IDX] = event;
> +		return DDRC_PERF_WRITE_COUNTER_IDX;
> +	}
> +
> +	/* Allocate DDR generic counters */
> +	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
> +		if (pmu->events[i] == NULL) {
> +			pmu->events[i] = event;
> +			return i;
> +		}
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +static void cn10k_ddr_perf_free_counter(struct cn10k_ddr_pmu *pmu, int counter)
> +{
> +	pmu->events[counter] = NULL;
> +}
> +
> +static int cn10k_ddr_perf_event_init(struct perf_event *event)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	if (event->attr.type != event->pmu->type)
> +		return -ENOENT;
> +
> +	if (is_sampling_event(event)) {
> +		dev_info(pmu->dev, "Sampling not supported!\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	if (event->cpu < 0) {
> +		dev_warn(pmu->dev, "Can't provide per-task data!\n");
> +		return -EOPNOTSUPP;
> +	}
> +
> +	/*  We must NOT create groups containing mixed PMUs */
> +	if (event->group_leader->pmu != event->pmu &&
> +			!is_software_event(event->group_leader))

pay attention to indentation

> +		return -EINVAL;
> +
> +	/* Set ownership of event to one CPU, same event can not be observed
> +	 * on multiple cpus at same time.
> +	 */
> +	event->cpu = pmu->cpu;
> +	hwc->idx = -1;
> +	return 0;
> +}
> +
> +static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
> +					  int counter, bool enable)
> +{
> +	uint32_t reg;
> +	uint64_t val;
> +
> +	if (counter > DDRC_PERF_NUM_COUNTERS) {

is this paranoia?

> +		pr_err("Error: unsupported counter %d\n", counter);
> +		return;
> +	}
> +
> +	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
> +		reg = DDRC_PERF_CFG(counter);
> +		val = readq_relaxed(pmu->base + reg);
> +
> +		if (enable)
> +			val |= EVENT_ENABLE;
> +		else
> +			val &= ~EVENT_ENABLE;
> +
> +		writeq_relaxed(val, pmu->base + reg);
> +	} else {
> +		val = readq_relaxed(pmu->base + DDRC_PERF_CNT_FREERUN_EN);
> +		if (enable) {
> +			if (counter == DDRC_PERF_READ_COUNTER_IDX)
> +				val |= DDRC_PERF_FREERUN_READ_EN;
> +			else
> +				val |= DDRC_PERF_FREERUN_WRITE_EN;
> +		} else {
> +			if (counter == DDRC_PERF_READ_COUNTER_IDX)
> +				val &= ~DDRC_PERF_FREERUN_READ_EN;
> +			else
> +				val &= ~DDRC_PERF_FREERUN_WRITE_EN;
> +		}
> +		writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_EN);
> +	}
> +}
> +
> +static uint64_t cn10k_ddr_perf_read_counter(struct cn10k_ddr_pmu *pmu,
> +					    int counter)
> +{
> +	uint64_t val;
> +
> +	if (counter == DDRC_PERF_READ_COUNTER_IDX)
> +		return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_RD_OP);
> +
> +	if (counter == DDRC_PERF_WRITE_COUNTER_IDX)
> +		return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_WR_OP);
> +
> +	val = readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE(counter));
> +	return val;
> +}
> +
> +static void cn10k_ddr_perf_event_update(struct perf_event *event)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	uint64_t prev_count, new_count, mask;
> +
> +	do {
> +		prev_count = local64_read(&hwc->prev_count);
> +		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
> +	} while (local64_xchg(&hwc->prev_count, new_count) != prev_count);
> +
> +	mask = DDRC_PERF_CNT_MAX_VALUE;
> +
> +	local64_add((new_count - prev_count) & mask, &event->count);
> +}
> +
> +static void cn10k_ddr_perf_event_start(struct perf_event *event, int flags)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int counter = hwc->idx;
> +
> +	local64_set(&hwc->prev_count, 0);
> +
> +	cn10k_ddr_perf_counter_enable(pmu, counter, true);
> +
> +	hwc->state = 0;
> +}
> +
> +static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	uint8_t config = event->attr.config;
> +	uint32_t reg_offset;
> +	uint64_t val;
> +	int counter;
> +
> +	counter = cn10k_ddr_perf_alloc_counter(pmu, event);
> +	if (counter < 0) {
> +		dev_dbg(pmu->dev, "There are not enough counters\n");

hmmm .. I'd be inclined to say that there are not enough available. And 
is dev_dbg() really any use?

> +		return -EOPNOTSUPP;

is that the best error code?

> +	}
> +
> +	pmu->active_events++;
> +	hwc->idx = counter;
> +
> +	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
> +		/* Generic counters, configure event id */
> +		reg_offset = DDRC_PERF_CFG(counter);
> +		val = ddr_perf_get_event_bitmap(config);
> +		writeq_relaxed(val, pmu->base + reg_offset);
> +	} else {
> +		/* fixed event counter, clear counter value */
> +		if (counter == DDRC_PERF_READ_COUNTER_IDX)
> +			val = DDRC_FREERUN_READ_CNT_CLR;
> +		else
> +			val = DDRC_FREERUN_WRITE_CNT_CLR;
> +
> +		writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_CTRL);
> +	}
> +
> +	hwc->state |= PERF_HES_STOPPED;
> +
> +	if (flags & PERF_EF_START)
> +		cn10k_ddr_perf_event_start(event, flags);
> +
> +	return 0;
> +}
> +
> +static void cn10k_ddr_perf_event_stop(struct perf_event *event, int flags)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int counter = hwc->idx;
> +
> +	cn10k_ddr_perf_counter_enable(pmu, counter, false);
> +
> +	if (flags & PERF_EF_UPDATE)
> +		cn10k_ddr_perf_event_update(event);
> +
> +	hwc->state |= PERF_HES_STOPPED;
> +}
> +
> +static void cn10k_ddr_perf_event_del(struct perf_event *event, int flags)
> +{
> +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int counter = hwc->idx;
> +
> +	cn10k_ddr_perf_event_stop(event, PERF_EF_UPDATE);
> +
> +	cn10k_ddr_perf_free_counter(pmu, counter);
> +	pmu->active_events--;
> +	hwc->idx = -1;
> +}
> +
> +static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu)
> +{
> +	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
> +
> +	writeq_relaxed(START_OP_CTRL_VAL_START, ddr_pmu->base +
> +		       DDRC_PERF_CNT_START_OP_CTRL);
> +}
> +
> +static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu)
> +{
> +	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
> +
> +	writeq_relaxed(END_OP_CTRL_VAL_END, ddr_pmu->base +
> +		       DDRC_PERF_CNT_END_OP_CTRL);
> +}
> +
> +static int cn10k_ddr_perf_probe(struct platform_device *pdev)
> +{
> +	struct cn10k_ddr_pmu *ddr_pmu;
> +	struct resource *res;
> +	void __iomem *base;
> +	static int index;
> +	char *name;
> +	int ret;
> +
> +	ddr_pmu = devm_kzalloc(&pdev->dev, sizeof(*ddr_pmu), GFP_KERNEL);
> +	if (!ddr_pmu)
> +		return -ENOMEM;
> +
> +	ddr_pmu->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, ddr_pmu);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);

can you use devm_platform_get_and_ioremap_resource()? I think that there 
is some helper that does both these steps

> +
> +	ddr_pmu->base = base;
> +
> +	/* Setup the PMU counter to work in mannual mode */

manual

> +	writeq_relaxed(OP_MODE_CTRL_VAL_MANNUAL, ddr_pmu->base +
> +		       DDRC_PERF_CNT_OP_MODE_CTRL);
> +
> +	ddr_pmu->pmu = (struct pmu) {
> +		.module	      = THIS_MODULE,
> +		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> +		.task_ctx_nr = perf_invalid_context,
> +		.attr_groups = cn10k_attr_groups,
> +		.event_init  = cn10k_ddr_perf_event_init,
> +		.add	     = cn10k_ddr_perf_event_add,
> +		.del	     = cn10k_ddr_perf_event_del,
> +		.start	     = cn10k_ddr_perf_event_start,
> +		.stop	     = cn10k_ddr_perf_event_stop,
> +		.read	     = cn10k_ddr_perf_event_update,
> +		.pmu_enable  = cn10k_ddr_perf_pmu_enable,
> +		.pmu_disable = cn10k_ddr_perf_pmu_disable,
> +	};
> +
> +	/* Choose this cpu to collect perf data */
> +	ddr_pmu->cpu = raw_smp_processor_id();
> +
> +	name = devm_kasprintf(ddr_pmu->dev, GFP_KERNEL, "mrvl_ddr_pmu@%llx",

mostly _%llx would be used elsewhere, and I am not sure how perf tool 
likes @ at all

> +			      res->start);
> +	if (!name)
> +		return -ENOMEM;
> +
> +	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
> +	if (ret)
> +		return ret;
> +
> +	ddr_pmu->id = index++;

where is this used?

> +	pr_info("CN10K DDR PMU Driver for ddrc@%llx - id-%d\n",
> +		res->start, ddr_pmu->id);
> +	return 0;
> +}
> +
> +static int cn10k_ddr_perf_remove(struct platform_device *pdev)
> +{
> +	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
> +
> +	perf_pmu_unregister(&ddr_pmu->pmu);
> +	return 0;
> +}
> +
> +static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
> +	{ .compatible = "marvell,cn10k-ddr-pmu", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
> +
> +static struct platform_driver cn10k_ddr_pmu_driver = {
> +	.driver	= {
> +		.name   = "cn10k-ddr-pmu",
> +		.of_match_table = cn10k_ddr_pmu_of_match,
> +		.suppress_bind_attrs = true,
> +	},
> +	.probe		= cn10k_ddr_perf_probe,
> +	.remove		= cn10k_ddr_perf_remove,
> +};
> +
> +static int __init cn10k_ddr_pmu_init(void)
> +{
> +	return platform_driver_register(&cn10k_ddr_pmu_driver);
> +}
> +
> +static void __exit cn10k_ddr_pmu_exit(void)
> +{
> +	platform_driver_unregister(&cn10k_ddr_pmu_driver);
> +}
> +
> +module_init(cn10k_ddr_pmu_init);
> +module_exit(cn10k_ddr_pmu_exit);
> +
> +MODULE_AUTHOR("Bharat Bhushan <bbhushan2 at marvell.com>");
> +MODULE_LICENSE("GPL v2");
> 



From kishon at ti.com  Wed Aug 18 06:55:09 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 18 Aug 2021 19:25:09 +0530
Subject: [PATCH v8 6/8] PCI: cadence: Add support to configure virtual
 functions
In-Reply-To: <20210817153852.GA3016660@bjorn-Precision-5520>
References: <20210817153852.GA3016660@bjorn-Precision-5520>
Message-ID: <ce380e6f-d10a-4db2-9bde-82615cfbe4db@ti.com>

Hi Bjorn,

On 17/08/21 9:08 pm, Bjorn Helgaas wrote:
> On Wed, Aug 11, 2021 at 12:16:54PM +0530, Kishon Vijay Abraham I wrote:
>> Now that support for SR-IOV is added in PCIe endpoint core, add support
>> to configure virtual functions in the Cadence PCIe EP driver.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>> ---
>>  .../pci/controller/cadence/pcie-cadence-ep.c  | 136 +++++++++++++++---
>>  drivers/pci/controller/cadence/pcie-cadence.h |   9 ++
>>  2 files changed, 125 insertions(+), 20 deletions(-)
> 
>> @@ -92,21 +118,29 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>>  
>>  	addr0 = lower_32_bits(bar_phys);
>>  	addr1 = upper_32_bits(bar_phys);
>> -	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
>> -			 addr0);
>> -	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
>> -			 addr1);
>>  
>>  	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
>> +	if (vfn == 1)
>> +		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
> 
> Seems sort of weird to compute "reg", then sometimes overwrite it, as
> opposed to:
> 
>   if (vfn == 1)
>     reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
>   else
>     reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);

I tried to write it without "else". But I can change it back.
> 
> Also slightly weird that "vfn" is basically used as a boolean, but
> it's actually a u8 virtual function number.  I guess VF 1 is special
> and not like the other VFs?

VF1 is special in that it's enough for configuring the SR-IOV capability
but below the "vfn" is used for configuring inbound window.

Thanks
Kishon
> 
>>  	b = (bar < BAR_4) ? bar : bar - BAR_4;
>>  
>> -	cfg = cdns_pcie_readl(pcie, reg);
>> -	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
>> -		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
>> -	cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
>> -		CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
>> -	cdns_pcie_writel(pcie, reg, cfg);
>> +	if (vfn == 0 || vfn == 1) {
>> +		cfg = cdns_pcie_readl(pcie, reg);
>> +		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
>> +			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
>> +		cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
>> +			CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
>> +		cdns_pcie_writel(pcie, reg, cfg);
>> +	}
>>  
>> +	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
>> +	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
>> +			 addr0);
>> +	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
>> +			 addr1);
>> +
>> +	if (vfn > 0)
>> +		epf = &epf->epf[vfn - 1];
>>  	epf->epf_bar[bar] = epf_bar;
>>  
>>  	return 0;
>> @@ -122,18 +156,25 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
>>  	u32 reg, cfg, b, ctrl;
>>  
>>  	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
>> +	if (vfn == 1)
>> +		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
> 
> Similar recomputation of "reg".
> 
>>  	b = (bar < BAR_4) ? bar : bar - BAR_4;
>>  
>> -	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
>> -	cfg = cdns_pcie_readl(pcie, reg);
>> -	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
>> -		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
>> -	cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
>> -	cdns_pcie_writel(pcie, reg, cfg);
>> +	if (vfn == 0 || vfn == 1) {
>> +		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
>> +		cfg = cdns_pcie_readl(pcie, reg);
>> +		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
>> +			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
>> +		cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
>> +		cdns_pcie_writel(pcie, reg, cfg);
>> +	}


From kishon at ti.com  Wed Aug 18 06:58:50 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 18 Aug 2021 19:28:50 +0530
Subject: [PATCH v2 1/3] dt-bindings: PCI: ti,j721e: Add bindings to
 specify legacy interrupts
In-Reply-To: <YRapMFNb63MSPJ1E@robh.at.kernel.org>
References: <20210804132912.30685-1-kishon@ti.com>
 <20210804132912.30685-2-kishon@ti.com> <YRapMFNb63MSPJ1E@robh.at.kernel.org>
Message-ID: <d0f83129-4c9a-d9ff-380a-cab37a86e29e@ti.com>

Hi Rob,

On 13/08/21 10:47 pm, Rob Herring wrote:
> On Wed, Aug 04, 2021 at 06:59:10PM +0530, Kishon Vijay Abraham I wrote:
>> Add bindings to specify interrupt controller for legacy interrupts.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>> ---
>>  .../bindings/pci/ti,j721e-pci-host.yaml           | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> index cc900202df29..f461d7b4c0cc 100644
>> --- a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> +++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
>> @@ -74,6 +74,11 @@ properties:
>>  
>>    msi-map: true
>>  
>> +patternProperties:
>> +  "interrupt-controller":
> 
> Not a pattern unless you meant for foo-interrupt-controller-bar to be 
> valid.
> 
> Anything is allowed in the node?

It's same as whatever is defined in schemas/interrupt-controller.yaml,
just that it should be a subnode of pcie at . Should I add whatever is
present in schemas/interrupt-controller.yaml here?

Thanks
Kishon
> 
>> +    type: object
>> +    description: interrupt controller to handle legacy interrupts.
>> +
>>  required:
>>    - compatible
>>    - reg
>> @@ -97,6 +102,8 @@ unevaluatedProperties: false
>>  
>>  examples:
>>    - |
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/interrupt-controller/irq.h>
>>      #include <dt-bindings/soc/ti,sci_pm_domain.h>
>>      #include <dt-bindings/gpio/gpio.h>
>>  
>> @@ -131,5 +138,13 @@ examples:
>>              ranges = <0x01000000 0x0 0x10001000  0x00 0x10001000  0x0 0x0010000>,
>>                       <0x02000000 0x0 0x10011000  0x00 0x10011000  0x0 0x7fef000>;
>>              dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
>> +
>> +
>> +            pcie0_intc: interrupt-controller {
>> +                    interrupt-controller;
>> +                    #interrupt-cells = <1>;
>> +                    interrupt-parent = <&gic500>;
>> +                    interrupts = <GIC_SPI 312 IRQ_TYPE_EDGE_RISING>;
>> +            };
>>          };
>>      };
>> -- 
>> 2.17.1
>>
>>


From robh at kernel.org  Wed Aug 18 07:10:42 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 09:10:42 -0500
Subject: [PATCH RESEND 1/9] dt-bindings: usb: mtk-xhci: add optional
 property to disable usb2 ports
In-Reply-To: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629189389-18779-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <YR0U4irxNbITU2R5@robh.at.kernel.org>

On Tue, 17 Aug 2021 16:36:21 +0800, Chunfeng Yun wrote:
> Add support to disable specific usb2 host ports, it's useful when
> a usb2 port is disabled on some platforms, but enabled on others for
> the same SoC, another case is that the different package may support
> different number of ports.
> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>  Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From colin.king at canonical.com  Wed Aug 18 07:10:51 2021
From: colin.king at canonical.com (Colin King)
Date: Wed, 18 Aug 2021 15:10:51 +0100
Subject: [PATCH][next] spi: rockchip-sfc: Fix assigned but never used return
 error codes
Message-ID: <20210818141051.36320-1-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

Currently there are two places where the error return variable ret is
being assigned -ETIMEDOUT on timeout errors and this value is not
being returned. Fix this by returning -ETIMEDOUT rather than redundantly
assiging it to ret.

Addresses-Coverity: ("Unused value")
Fixes: 0b89fc0a367e ("spi: rockchip-sfc: add rockchip serial flash controller")
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 drivers/spi/spi-rockchip-sfc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
index 7c4d47fe80c2..827e205c5340 100644
--- a/drivers/spi/spi-rockchip-sfc.c
+++ b/drivers/spi/spi-rockchip-sfc.c
@@ -257,7 +257,7 @@ static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_
 	if (ret) {
 		dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
 
-		ret = -ETIMEDOUT;
+		return -ETIMEDOUT;
 	}
 
 	return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
@@ -274,7 +274,7 @@ static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_
 	if (ret) {
 		dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n");
 
-		ret = -ETIMEDOUT;
+		return -ETIMEDOUT;
 	}
 
 	return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
-- 
2.32.0



From ezequiel at vanguardiasur.com.ar  Wed Aug 18 07:11:57 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 18 Aug 2021 11:11:57 -0300
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <20210811025801.21597-1-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
Message-ID: <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>

+danvet

Hi,

On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <yunfei.dong at mediatek.com> wrote:
>
> This series adds support for multi hardware decode into mtk-vcodec, by first
> adding component framework to manage each hardware information: interrupt,
> clock, register bases and power. Secondly add core thread to deal with core
> hardware message, at the same time, add msg queue for different hardware
> share messages. Lastly, the architecture of different specs are not the same,
> using specs type to separate them.
>

I don't think it's a good idea to introduce the component API in the
media subsystem. It doesn't seem to be maintained, IRC there's not even
a maintainer for it, and it has some issues that were never addressed.

It would be really important to avoid it. Is it really needed in the
first place?

Thanks,
Ezequiel


From mark.rutland at arm.com  Wed Aug 18 07:12:56 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 18 Aug 2021 15:12:56 +0100
Subject: [boot-wrapper PATCH] aarch64: Do not trap PMSNEVFR_EL1
In-Reply-To: <20210817163420.813631-1-alexandru.elisei@arm.com>
References: <20210817163420.813631-1-alexandru.elisei@arm.com>
Message-ID: <20210818141256.GB64368@C02TD0UTHF1T.local>

On Tue, Aug 17, 2021 at 05:34:20PM +0100, Alexandru Elisei wrote:
> FEAT_PMUv1p2 adds a new register, PMSNEVFR_EL1, and a new MDCR_EL3 trap bit
> for it, EnPMSN. Set the bit to 1 to allow lower exception levels direct
> access to the register.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>

Thanks for this; I have a couple of minor comments below, which I'll fix
up when applying.

> ---
>  arch/aarch64/boot.S | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 2215f7ed3a1f..8951f1e4676a 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -88,8 +88,12 @@ ASM_FUNC(_start)
>  	cbz	x1, 1f
>  
>  	// Enable SPE for the non-secure world.
> -	ldr	x1, =(0x3 << 12)
> -	orr	x0, x0, x1
> +	ldr	x2, =(0x3 << 12)
> +	orr	x0, x0, x2

Since we're touching this, I'll make it:

	orr	x0, x0, #(3 << 12)

> +	cmp	x1, #3
> +	b.lt	1

For consistency, I'll make this `b.lt 1f`

> +	// Do not trap PMSNEVFR_EL1.
> +	orr	x0, x0, #(1 << 36)

For legibility, I'll re-order this as:

	// Do not trap PMSNEVFR_EL1 if present.
	cmp	x1, #3
	b.lt	1f
	orr	x0, x0, #(1 << 36)

Thanks,
Mark.

>  
>  1:	mrs	x1, id_aa64dfr0_el1
>  	ubfx	x1, x1, #44, #4
> -- 
> 2.32.0
> 


From d-gerlach at ti.com  Wed Aug 18 07:13:32 2021
From: d-gerlach at ti.com (Dave Gerlach)
Date: Wed, 18 Aug 2021 09:13:32 -0500
Subject: [PATCH] arm64: dts: ti: k3-am64-mcu: Add pinctrl
In-Reply-To: <20210818111747.88569-1-christian.gmeiner@gmail.com>
References: <20210818111747.88569-1-christian.gmeiner@gmail.com>
Message-ID: <13974a27-a90d-639d-d050-c97570fdf369@ti.com>

Hi,

On 8/18/21 6:17 AM, Christian Gmeiner wrote:
> Add the definition of the pinctrl for the MCU domain.
> 
> Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
> ---
>  arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
> index 59cc58f7d0c8..2bb5c9ff172c 100644
> --- a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
> @@ -97,4 +97,12 @@ mcu_gpio0: gpio at 4201000 {
>  		clocks = <&k3_clks 79 0>;
>  		clock-names = "gpio";
>  	};
> +
> +	mcu_pmx0: pinctrl at 4084000 {
> +		compatible = "pinctrl-single";
> +		reg = <0x00 0x4084000 0x00 0x84>;
> +		#pinctrl-cells = <1>;
> +		pinctrl-single,register-width = <32>;
> +		pinctrl-single,function-mask = <0xffffffff>;
> +	};
>  };
> 

Reviewed-by: Dave Gerlach <d-gerlach at ti.com>

Regards,
Dave


From robh at kernel.org  Wed Aug 18 07:20:37 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 09:20:37 -0500
Subject: [PATCH 03/11] dt-bindings: usb: mtk-xhci: add compatible for
 mt8195
In-Reply-To: <cd1662f5f47fe7539d2c01bd280ad8b9d9d25b3e.camel@mediatek.com>
References: <1627635002-24521-1-git-send-email-chunfeng.yun@mediatek.com>
 <1627635002-24521-3-git-send-email-chunfeng.yun@mediatek.com>
 <YQ2e6AGFi7beqp6Q@robh.at.kernel.org>
 <cd1662f5f47fe7539d2c01bd280ad8b9d9d25b3e.camel@mediatek.com>
Message-ID: <CAL_JsqKjjPqArmhoXuYrk+1C-vXFSKNA_gxtOfLFsGTGBq20aQ@mail.gmail.com>

On Wed, Aug 11, 2021 at 3:02 AM Chunfeng Yun (???)
<Chunfeng.Yun at mediatek.com> wrote:
>
> On Fri, 2021-08-06 at 14:43 -0600, Rob Herring wrote:
> > On Fri, Jul 30, 2021 at 04:49:54PM +0800, Chunfeng Yun wrote:
> > > There are 4 USB controllers on MT8195, the controllers (IP1~IP3,
> > > exclude IP0) have a wrong default SOF/ITP interval which is
> > > calculated from the frame counter clock 24Mhz by default, but
> > > in fact, the frame counter clock is 48Mhz, so we should set
> > > the accurate interval according to 48Mhz. Here add a new compatible
> > > for MT8195, it's also supported in driver. But the first controller
> > > (IP0) has no such issue, we prefer to use generic compatible,
> > > e.g. mt8192's compatible.
> >
> > That only works until you find some 8195 bug common to all
> > instances.
> It's also OK for IP0 to use mt8195's compatible, these setting value is
> the same as IP0's default value, use mt8192's may avoid these dummy
> setting.

I still don't understand. By use mt8192's compatible, that means you
have for IP0:

compatible = "mediatek,mt8192-xhci", "mediatek,mtk-xhci";

And for the rest:
compatible = "mediatek,mt8195-xhci", "mediatek,mtk-xhci";

If there's a 8195 quirk you need to work around, then you can't on
IP0. You need to be able to address quirks in the future without
changing the DTB. That is why we require SoC specific compatibles even
when IP blocks are 'the same'.

Rob


From hch at lst.de  Wed Aug 18 07:27:15 2021
From: hch at lst.de ('Christoph Hellwig')
Date: Wed, 18 Aug 2021 16:27:15 +0200
Subject: [PATCH 7/7] hexagon: use the generic global coherent pool
In-Reply-To: <00a901d790af$b05165c0$10f43140$@codeaurora.org>
References: <20210712061704.4162464-1-hch@lst.de>
 <20210712061704.4162464-8-hch@lst.de>
 <00a901d790af$b05165c0$10f43140$@codeaurora.org>
Message-ID: <20210818142715.GA10755@lst.de>

Thanks,

I've pulled the whole series into the dma-mapping for-next tree.


From robh+dt at kernel.org  Wed Aug 18 07:31:21 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 09:31:21 -0500
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <0ec05a0b-9499-3bf4-a231-ea53b1cf99ed@canonical.com>
References: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
 <73eebe7b-46da-137b-1938-09a5b453320a@arm.com>
 <0ec05a0b-9499-3bf4-a231-ea53b1cf99ed@canonical.com>
Message-ID: <CAL_JsqLOHY0P=Y8-Ss0cYr54SWgpV0zktEg8p-Cj_F+juDQNoA@mail.gmail.com>

On Mon, Aug 16, 2021 at 3:32 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 16/08/2021 09:53, Lukasz Luba wrote:
> > Hi Krzysztof,
> >
> > On 8/13/21 1:54 PM, Krzysztof Kozlowski wrote:
> >> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
> >> Dynamic Memory Controller to DT schema format using json-schema.
> >>
> >> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >> ---
> >>   .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
> >>   .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
> >>   MAINTAINERS                                   |   2 +-
> >
> > I'm not an expert in this DT scripts and why it complains. Maybe it
> > complains because the "samsung,exynos-ppmu" is defined in the .txt
> > file... (?)
> > Although, in general looks OK.
> >
> > Acked-by: Lukasz Luba <lukasz.luba at arm.com>
>
> I think the warning (triggered by DT_CHECKER_FLAGS=-m) can be ignored
> because it complains about compatible in example which is not present in
> the bindings. Usually it means someone wrote example not matching the
> bindings (e.g. a typo in compatible) but here it is on purpose.

Ultimately, it will mean the binding is undocumented (or a typo). But
right now, it means the binding is undocumented with a schema. It's
off by default because there's still about 80 warnings. It's turned on
for the bot so we don't add more. So please don't ignore it.

Rob


From maz at kernel.org  Wed Aug 18 07:32:24 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 15:32:24 +0100
Subject: [PATCH v4 03/15] KVM: arm64: MDCR_EL2 is a 64-bit register
In-Reply-To: <20210817081134.2918285-4-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-4-tabba@google.com>
Message-ID: <87k0kisu13.wl-maz@kernel.org>

On Tue, 17 Aug 2021 09:11:22 +0100,
Fuad Tabba <tabba at google.com> wrote:
> 
> Fix the places in KVM that treat MDCR_EL2 as a 32-bit register.
> More recent features (e.g., FEAT_SPEv1p2) use bits above 31.
> 
> No functional change intended.
> 
> Acked-by: Will Deacon <will at kernel.org>
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_arm.h   | 20 ++++++++++----------
>  arch/arm64/include/asm/kvm_asm.h   |  2 +-
>  arch/arm64/include/asm/kvm_host.h  |  2 +-
>  arch/arm64/kvm/debug.c             |  2 +-
>  arch/arm64/kvm/hyp/nvhe/debug-sr.c |  2 +-
>  arch/arm64/kvm/hyp/vhe/debug-sr.c  |  2 +-
>  6 files changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index d436831dd706..6a523ec83415 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -281,18 +281,18 @@
>  /* Hyp Debug Configuration Register bits */
>  #define MDCR_EL2_E2TB_MASK	(UL(0x3))
>  #define MDCR_EL2_E2TB_SHIFT	(UL(24))
> -#define MDCR_EL2_TTRF		(1 << 19)
> -#define MDCR_EL2_TPMS		(1 << 14)
> +#define MDCR_EL2_TTRF		(UL(1) << 19)
> +#define MDCR_EL2_TPMS		(UL(1) << 14)
>  #define MDCR_EL2_E2PB_MASK	(UL(0x3))
>  #define MDCR_EL2_E2PB_SHIFT	(UL(12))
> -#define MDCR_EL2_TDRA		(1 << 11)
> -#define MDCR_EL2_TDOSA		(1 << 10)
> -#define MDCR_EL2_TDA		(1 << 9)
> -#define MDCR_EL2_TDE		(1 << 8)
> -#define MDCR_EL2_HPME		(1 << 7)
> -#define MDCR_EL2_TPM		(1 << 6)
> -#define MDCR_EL2_TPMCR		(1 << 5)
> -#define MDCR_EL2_HPMN_MASK	(0x1F)
> +#define MDCR_EL2_TDRA		(UL(1) << 11)
> +#define MDCR_EL2_TDOSA		(UL(1) << 10)
> +#define MDCR_EL2_TDA		(UL(1) << 9)
> +#define MDCR_EL2_TDE		(UL(1) << 8)
> +#define MDCR_EL2_HPME		(UL(1) << 7)
> +#define MDCR_EL2_TPM		(UL(1) << 6)
> +#define MDCR_EL2_TPMCR		(UL(1) << 5)
> +#define MDCR_EL2_HPMN_MASK	(UL(0x1F))
>  
>  /* For compatibility with fault code shared with 32-bit */
>  #define FSC_FAULT	ESR_ELx_FSC_FAULT
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 9f0bf2109be7..63ead9060ab5 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -210,7 +210,7 @@ extern u64 __vgic_v3_read_vmcr(void);
>  extern void __vgic_v3_write_vmcr(u32 vmcr);
>  extern void __vgic_v3_init_lrs(void);
>  
> -extern u32 __kvm_get_mdcr_el2(void);
> +extern u64 __kvm_get_mdcr_el2(void);
>  
>  #define __KVM_EXTABLE(from, to)						\
>  	"	.pushsection	__kvm_ex_table, \"a\"\n"		\
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 347781f99b6a..4d2d974c1522 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -289,7 +289,7 @@ struct kvm_vcpu_arch {
>  
>  	/* HYP configuration */
>  	u64 hcr_el2;
> -	u32 mdcr_el2;
> +	u64 mdcr_el2;

This breaks an existing trace in debug.c::kvm_arm_setup_mdcr_el2():

	trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);

which expects a 32bit value. I guess we could add an equivalent 64bit
version, or silently upgrade the tracepoint to take a 64bit value.
None of them are good solutions, but hey, something has to give...

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From clin at suse.com  Wed Aug 18 07:34:57 2021
From: clin at suse.com (Chester Lin)
Date: Wed, 18 Aug 2021 22:34:57 +0800
Subject: [PATCH 1/8] dt-bindings: arm: fsl: add NXP S32G2 boards
In-Reply-To: <YRaxt1LCF+hWaMJU@robh.at.kernel.org>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-2-clin@suse.com>
 <YRaxt1LCF+hWaMJU@robh.at.kernel.org>
Message-ID: <YR0akXYPYthDuvCh@linux-8mug>

On Fri, Aug 13, 2021 at 12:53:59PM -0500, Rob Herring wrote:
> On Thu, Aug 05, 2021 at 02:54:22PM +0800, Chester Lin wrote:
> > Add bindings for S32G2's evaluation board (S32G-VNP-EVB) and reference
> > design 2 board ( S32G-VNP-RDB2).
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  Documentation/devicetree/bindings/arm/fsl.yaml | 7 +++++++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
> > index e2097011c4b0..3914aa09e503 100644
> > --- a/Documentation/devicetree/bindings/arm/fsl.yaml
> > +++ b/Documentation/devicetree/bindings/arm/fsl.yaml
> > @@ -983,6 +983,13 @@ properties:
> >            - const: solidrun,lx2160a-cex7
> >            - const: fsl,lx2160a
> >  
> > +      - description: S32G2 based Boards
> > +        items:
> > +          - enum:
> > +              - fsl,s32g274a-evb
> > +              - fsl,s32g274a-rdb2
> > +          - const: fsl,s32g2
> 
> Given this is an entirely different family from i.MX and new?, shouldn't 
> it use 'nxp' instead of 'fsl'? Either way,

It sounds good and Radu from NXP has mentioned a similar idea for the
compatible string of linflexuart. To keep the naming consistency, should we
change all 'fsl' to 'nxp' as well? For example, we could rename the fsl.yaml
to nxp.yaml. However, changing all of them would cause some impacts, which will
need more verifications on new strings. Otherwise we would have to tolerate the
naming differences only used by s32g2.

Thanks,
Chester

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



From maz at kernel.org  Wed Aug 18 07:42:23 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 15:42:23 +0100
Subject: [PATCH v4 06/15] KVM: arm64: Restore mdcr_el2 from vcpu
In-Reply-To: <20210817081134.2918285-7-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-7-tabba@google.com>
Message-ID: <87im02stkg.wl-maz@kernel.org>

On Tue, 17 Aug 2021 09:11:25 +0100,
Fuad Tabba <tabba at google.com> wrote:
> 
> On deactivating traps, restore the value of mdcr_el2 from the
> newly created and preserved host value vcpu context, rather than
> directly reading the hardware register.
> 
> Up until and including this patch the two values are the same,
> i.e., the hardware register and the vcpu one. A future patch will
> be changing the value of mdcr_el2 on activating traps, and this
> ensures that its value will be restored.
> 
> No functional change intended.
> 
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h       |  5 ++++-
>  arch/arm64/include/asm/kvm_hyp.h        |  2 +-
>  arch/arm64/kvm/hyp/include/hyp/switch.h |  6 +++++-
>  arch/arm64/kvm/hyp/nvhe/switch.c        | 13 +++++--------
>  arch/arm64/kvm/hyp/vhe/switch.c         | 14 +++++---------
>  arch/arm64/kvm/hyp/vhe/sysreg-sr.c      |  2 +-
>  6 files changed, 21 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 4d2d974c1522..76462c6a91ee 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -287,10 +287,13 @@ struct kvm_vcpu_arch {
>  	/* Stage 2 paging state used by the hardware on next switch */
>  	struct kvm_s2_mmu *hw_mmu;
>  
> -	/* HYP configuration */
> +	/* Values of trap registers for the guest. */
>  	u64 hcr_el2;
>  	u64 mdcr_el2;
>  
> +	/* Values of trap registers for the host before guest entry. */
> +	u64 mdcr_el2_host;

This probably should then eventually replace the per-CPU copy of
mdcr_el2 that lives in debug.c, shouldn't it?

> +
>  	/* Exception Information */
>  	struct kvm_vcpu_fault_info fault;
>  
> diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
> index 9d60b3006efc..657d0c94cf82 100644
> --- a/arch/arm64/include/asm/kvm_hyp.h
> +++ b/arch/arm64/include/asm/kvm_hyp.h
> @@ -95,7 +95,7 @@ void __sve_restore_state(void *sve_pffr, u32 *fpsr);
>  
>  #ifndef __KVM_NVHE_HYPERVISOR__
>  void activate_traps_vhe_load(struct kvm_vcpu *vcpu);
> -void deactivate_traps_vhe_put(void);
> +void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu);
>  #endif
>  
>  u64 __guest_enter(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index e4a2f295a394..a0e78a6027be 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -92,11 +92,15 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
>  		write_sysreg(0, pmselr_el0);
>  		write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
>  	}
> +
> +	vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2);
>  	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
>  }
>  
> -static inline void __deactivate_traps_common(void)
> +static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
>  {
> +	write_sysreg(vcpu->arch.mdcr_el2_host, mdcr_el2);
> +
>  	write_sysreg(0, hstr_el2);
>  	if (kvm_arm_support_pmu_v3())
>  		write_sysreg(0, pmuserenr_el0);
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index f7af9688c1f7..2ea764a48958 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -69,12 +69,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
>  static void __deactivate_traps(struct kvm_vcpu *vcpu)
>  {
>  	extern char __kvm_hyp_host_vector[];
> -	u64 mdcr_el2, cptr;
> +	u64 cptr;
>  
>  	___deactivate_traps(vcpu);
>  
> -	mdcr_el2 = read_sysreg(mdcr_el2);
> -
>  	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
>  		u64 val;
>  
> @@ -92,13 +90,12 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
>  		isb();
>  	}
>  
> -	__deactivate_traps_common();
> +	vcpu->arch.mdcr_el2_host &= MDCR_EL2_HPMN_MASK |
> +				    MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT |
> +				    MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
>  
> -	mdcr_el2 &= MDCR_EL2_HPMN_MASK;
> -	mdcr_el2 |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT;
> -	mdcr_el2 |= MDCR_EL2_E2TB_MASK << MDCR_EL2_E2TB_SHIFT;
> +	__deactivate_traps_common(vcpu);
>  
> -	write_sysreg(mdcr_el2, mdcr_el2);

FWIW, I found this whole sequence massively confusing, and it is only
when I came to patch #7 that the various pieces did come together.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzysztof.kozlowski at canonical.com  Wed Aug 18 07:43:49 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 18 Aug 2021 16:43:49 +0200
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <CAL_JsqLOHY0P=Y8-Ss0cYr54SWgpV0zktEg8p-Cj_F+juDQNoA@mail.gmail.com>
References: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
 <73eebe7b-46da-137b-1938-09a5b453320a@arm.com>
 <0ec05a0b-9499-3bf4-a231-ea53b1cf99ed@canonical.com>
 <CAL_JsqLOHY0P=Y8-Ss0cYr54SWgpV0zktEg8p-Cj_F+juDQNoA@mail.gmail.com>
Message-ID: <aaa53a2a-c15b-8017-4e44-dd3f883b2378@canonical.com>

On 18/08/2021 16:31, Rob Herring wrote:
> On Mon, Aug 16, 2021 at 3:32 AM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 16/08/2021 09:53, Lukasz Luba wrote:
>>> Hi Krzysztof,
>>>
>>> On 8/13/21 1:54 PM, Krzysztof Kozlowski wrote:
>>>> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
>>>> Dynamic Memory Controller to DT schema format using json-schema.
>>>>
>>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>> ---
>>>>   .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
>>>>   .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
>>>>   MAINTAINERS                                   |   2 +-
>>>
>>> I'm not an expert in this DT scripts and why it complains. Maybe it
>>> complains because the "samsung,exynos-ppmu" is defined in the .txt
>>> file... (?)
>>> Although, in general looks OK.
>>>
>>> Acked-by: Lukasz Luba <lukasz.luba at arm.com>
>>
>> I think the warning (triggered by DT_CHECKER_FLAGS=-m) can be ignored
>> because it complains about compatible in example which is not present in
>> the bindings. Usually it means someone wrote example not matching the
>> bindings (e.g. a typo in compatible) but here it is on purpose.
> 
> Ultimately, it will mean the binding is undocumented (or a typo). But
> right now, it means the binding is undocumented with a schema. It's
> off by default because there's still about 80 warnings. It's turned on
> for the bot so we don't add more. So please don't ignore it.
> 

By "Ignore" I meant here that it is a false positive, so it can be
ignored. The warning is about compatible "samsung,exynos-ppmu" used in
the example. However this exynos-ppmu is not part of this bindings and
is documented elsewhere:
Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt


Best regards,
Krzysztof


From pavlica.nikola at gmail.com  Wed Aug 18 07:46:46 2021
From: pavlica.nikola at gmail.com (Nikola Pavlica)
Date: Wed, 18 Aug 2021 16:46:46 +0200
Subject: [PATCH 1/3] drm/panel-simple: Add Vivax TPC-9150 panel v4
Message-ID: <20210818144648.72665-1-pavlica.nikola@gmail.com>

The model and make of the LCD panel of the Vivax TPC-9150 is unknown,
hence the panel settings that were retrieved with a FEX dump are named
after the device NOT the actual panel.

The LCD in question is a 50 pin MISO TFT LCD panel of the resolution
1024x600 used by the aforementioned device.

Version 2, as Thierry kindly suggested that I fix the order in which the
panel was ordered compared to others.

Version 3, filling in the required info suggested by Sam. Plus some
factual issues that I've corrected myself (tested working)

Version 4, rearranged the display parameters and fix invalid bit format
issue. (Thanks Sam)

Thanks,
Nikola

Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
---
 drivers/gpu/drm/panel/panel-simple.c | 29 ++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 4e2dad314c79..9e06c375f8a0 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3989,6 +3989,32 @@ static const struct panel_desc urt_umsh_8596md_parallel = {
 	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 };

+static const struct drm_display_mode vivax_tpc9150_panel_mode = {
+	.clock = 60000,
+	.hdisplay = 1024,
+	.hsync_start = 1024 + 160,
+	.hsync_end = 1024 + 160 + 100,
+	.htotal = 1024 + 160 + 100 + 60,
+	.vdisplay = 600,
+	.vsync_start = 600 + 12,
+	.vsync_end = 600 + 12 + 10,
+	.vtotal = 600 + 12 + 10 + 13,
+};
+
+static const struct panel_desc vivax_tpc9150_panel = {
+	.modes = &vivax_tpc9150_panel_mode,
+	.num_modes = 1,
+	.bpc = 6,
+	.size = {
+		.width = 200,
+		.height = 115,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
+
 static const struct drm_display_mode vl050_8048nt_c01_mode = {
 	.clock = 33333,
 	.hdisplay = 800,
@@ -4490,6 +4516,9 @@ static const struct of_device_id platform_of_match[] = {
 	}, {
 		.compatible = "urt,umsh-8596md-20t",
 		.data = &urt_umsh_8596md_parallel,
+	}, {
+		.compatible = "vivax,tpc9150-panel",
+		.data = &vivax_tpc9150_panel,
 	}, {
 		.compatible = "vxt,vl050-8048nt-c01",
 		.data = &vl050_8048nt_c01,
--
2.32.0



From pavlica.nikola at gmail.com  Wed Aug 18 07:46:47 2021
From: pavlica.nikola at gmail.com (Nikola Pavlica)
Date: Wed, 18 Aug 2021 16:46:47 +0200
Subject: [PATCH 2/3] dt-bindings: display: simple: Add Vivax TPC-9150 panel
In-Reply-To: <20210818144648.72665-1-pavlica.nikola@gmail.com>
References: <20210818144648.72665-1-pavlica.nikola@gmail.com>
Message-ID: <20210818144648.72665-2-pavlica.nikola@gmail.com>

This tablet display is unique and hence must be added to documentation.
Unfortunately, it's real make and number is not known due to obscure and
missing documentation and lack of writing on the display assembly
itself.

So the natural alternative that came to mind is to name the panel after
the device that contained it (an Android tablet). Hopefully that isn't
an issue.

I can confirm that the parameters that I've obtained are correct since
they came from a dump of the original Android OS.

Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
---
 .../devicetree/bindings/display/panel/panel-simple.yaml         | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 62b0d54d87b7..d0efefa5a820 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -285,6 +285,8 @@ properties:
       - urt,umsh-8596md-11t
       - urt,umsh-8596md-19t
       - urt,umsh-8596md-20t
+        # Vivax TPC-9150 tablet 9.0" WSVGA TFT LCD panel
+      - vivax,tpc9150-panel
         # VXT 800x480 color TFT LCD panel
       - vxt,vl050-8048nt-c01
         # Winstar Display Corporation 3.5" QVGA (320x240) TFT LCD panel
-- 
2.32.0



From pavlica.nikola at gmail.com  Wed Aug 18 07:46:48 2021
From: pavlica.nikola at gmail.com (Nikola Pavlica)
Date: Wed, 18 Aug 2021 16:46:48 +0200
Subject: [PATCH 3/3] dt-bindings: add vendor prefix for Vivax
In-Reply-To: <20210818144648.72665-1-pavlica.nikola@gmail.com>
References: <20210818144648.72665-1-pavlica.nikola@gmail.com>
Message-ID: <20210818144648.72665-3-pavlica.nikola@gmail.com>

Add vendor prefix for the Vivax brand by M SAN Grupa d.o.o.

Source (in Croatian): https://www.vivax.com/hr/o-nama.aspx

Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index f6064d84a424..c234c392538d 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1206,6 +1206,8 @@ patternProperties:
     description: Vitesse Semiconductor Corporation
   "^vivante,.*":
     description: Vivante Corporation
+  "^vivax,.*":
+    description: Vivax brand by M SAN Grupa d.o.o.
   "^vocore,.*":
     description: VoCore Studio
   "^voipac,.*":
-- 
2.32.0



From robin.murphy at arm.com  Wed Aug 18 08:13:24 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 18 Aug 2021 16:13:24 +0100
Subject: [PATCH v4 00/24] iommu: Refactor DMA domain strictness
In-Reply-To: <YRzvGxTW8m+NUcSi@8bytes.org>
References: <cover.1628682048.git.robin.murphy@arm.com>
 <YRzvGxTW8m+NUcSi@8bytes.org>
Message-ID: <914d7243-7f9d-425e-1ff7-6be218e04913@arm.com>

On 2021-08-18 12:29, Joerg Roedel wrote:
> On Wed, Aug 11, 2021 at 01:21:14PM +0100, Robin Murphy wrote:
>> Robin Murphy (24):
>>    iommu: Pull IOVA cookie management into the core
>>    iommu/amd: Drop IOVA cookie management
>>    iommu/arm-smmu: Drop IOVA cookie management
>>    iommu/vt-d: Drop IOVA cookie management
>>    iommu/exynos: Drop IOVA cookie management
>>    iommu/ipmmu-vmsa: Drop IOVA cookie management
>>    iommu/mtk: Drop IOVA cookie management
>>    iommu/rockchip: Drop IOVA cookie management
>>    iommu/sprd: Drop IOVA cookie management
>>    iommu/sun50i: Drop IOVA cookie management
>>    iommu/virtio: Drop IOVA cookie management
>>    iommu/dma: Unexport IOVA cookie management
>>    iommu/dma: Remove redundant "!dev" checks
>>    iommu: Indicate queued flushes via gather data
>>    iommu/io-pgtable: Remove non-strict quirk
>>    iommu: Introduce explicit type for non-strict DMA domains
>>    iommu/amd: Prepare for multiple DMA domain types
>>    iommu/arm-smmu: Prepare for multiple DMA domain types
>>    iommu/vt-d: Prepare for multiple DMA domain types
>>    iommu: Express DMA strictness via the domain type
>>    iommu: Expose DMA domain strictness via sysfs
>>    iommu: Only log strictness for DMA domains
>>    iommu: Merge strictness and domain type configs
>>    iommu: Allow enabling non-strict mode dynamically
> 
> Applied all except patch 12. Please re-submit patch 12 together with the
> APPLE DART fixups after v5.15-rc1 is out.

Brilliant, thanks for fixing that up!

Sven - I've prepared the follow-up patches already[1], so consider 
yourself off the hook (I see no point in trying to fix the nominal DART 
cookie bugs between now and then) :)

Cheers,
Robin.

[1] https://gitlab.arm.com/linux-arm/linux-rm/-/commits/iommu/fq-fixes


From abel.vesa at nxp.com  Wed Aug 18 08:14:35 2021
From: abel.vesa at nxp.com (Abel Vesa)
Date: Wed, 18 Aug 2021 18:14:35 +0300
Subject: [PATCH] clk: imx8m: fix clock tree update of TF-A managed clocks
In-Reply-To: <20210810151432.9228-1-a.fatoum@pengutronix.de>
References: <20210810151432.9228-1-a.fatoum@pengutronix.de>
Message-ID: <YR0j21KspR618YLK@ryzen>

On 21-08-10 17:14:33, Ahmad Fatoum wrote:
> On the i.MX8M*, the TF-A exposes a SiP (Silicon Provider) service
> for DDR frequency scaling. The imx8m-ddrc-devfreq driver calls the
> SiP and then does clk_set_parent on the DDR muxes to synchronize
> the clock tree.
> 
> Since 936c383673b9 ("clk: imx: fix composite peripheral flags"),
> these TF-A managed muxes have SET_PARENT_GATE set, which results
> in imx8m-ddrc-devfreq's clk_set_parent after SiP failing with -EBUSY:
> 
> 	echo 25000000 > userspace/set_freq
> 	imx8m-ddrc-devfreq 3d400000.memory-controller: failed to set
> 		dram_apb parent: -16
> 
> Fix this by adding a new i.MX composite flag for firmware managed
> clocks, which clears SET_PARENT_GATE.
> 
> This is safe to do, because updating the Linux clock tree to reflect
> reality will always be glitch-free.
> 
> Fixes: 936c383673b9 ("clk: imx: fix composite peripheral flags")
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>

I'm OK with this.

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

BTW, let me know if you are interested in the interconnect+devfreq
(the replacement for NXP's internal busfreq). I have a new version of
that patchset which I intend to send soon for review.

> ---
> To: Abel Vesa <abel.vesa at nxp.com>
> To: Michael Turquette <mturquette at baylibre.com>
> To: Stephen Boyd <sboyd at kernel.org>
> To: Shawn Guo <shawnguo at kernel.org>
> To: Sascha Hauer <s.hauer at pengutronix.de>
> To: Pengutronix Kernel Team <kernel at pengutronix.de>
> To: Fabio Estevam <festevam at gmail.com>
> To: NXP Linux Team <linux-imx at nxp.com>
> To: Peng Fan <peng.fan at nxp.com>
> To: Leonard Crestez <leonard.crestez at nxp.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-clk at vger.kernel.org
> ---
>  drivers/clk/imx/clk-composite-8m.c |  3 ++-
>  drivers/clk/imx/clk-imx8mm.c       |  7 ++++---
>  drivers/clk/imx/clk-imx8mn.c       |  7 ++++---
>  drivers/clk/imx/clk-imx8mq.c       |  7 ++++---
>  drivers/clk/imx/clk.h              | 16 ++++++++++++++--
>  5 files changed, 28 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
> index 2c309e3dc8e3..04e728538cef 100644
> --- a/drivers/clk/imx/clk-composite-8m.c
> +++ b/drivers/clk/imx/clk-composite-8m.c
> @@ -216,7 +216,8 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>  		div->width = PCG_PREDIV_WIDTH;
>  		divider_ops = &imx8m_clk_composite_divider_ops;
>  		mux_ops = &clk_mux_ops;
> -		flags |= CLK_SET_PARENT_GATE;
> +		if (!(composite_flags & IMX_COMPOSITE_FW_MANAGED))
> +			flags |= CLK_SET_PARENT_GATE;
>  	}
>  
>  	div->lock = &imx_ccm_lock;
> diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
> index f1919fafb124..73cc9805ec59 100644
> --- a/drivers/clk/imx/clk-imx8mm.c
> +++ b/drivers/clk/imx/clk-imx8mm.c
> @@ -470,10 +470,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
>  
>  	/*
>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> +	 * as div value should always be read from hardware
>  	 */
> -	hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> -	hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> +	hws[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
> +	hws[IMX8MM_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
>  
>  	/* IP */
>  	hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
> diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
> index 88f6630cd472..0a76f969b28b 100644
> --- a/drivers/clk/imx/clk-imx8mn.c
> +++ b/drivers/clk/imx/clk-imx8mn.c
> @@ -453,10 +453,11 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
>  
>  	/*
>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> +	 * as div value should always be read from hardware
>  	 */
> -	hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> -	hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> +	hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
> +	hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
>  
>  	hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
>  	hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> index c491bc9c61ce..83cc2b1c3294 100644
> --- a/drivers/clk/imx/clk-imx8mq.c
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -449,11 +449,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
>  
>  	/*
>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> +	 * as div value should always be read from hardware
>  	 */
>  	hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
> -	hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> -	hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> +	hws[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
> +	hws[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
>  
>  	/* IP */
>  	hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
> index 7571603bee23..e144f983fd8c 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -530,8 +530,9 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
>  		struct clk *div, struct clk *mux, struct clk *pll,
>  		struct clk *step);
>  
> -#define IMX_COMPOSITE_CORE	BIT(0)
> -#define IMX_COMPOSITE_BUS	BIT(1)
> +#define IMX_COMPOSITE_CORE		BIT(0)
> +#define IMX_COMPOSITE_BUS		BIT(1)
> +#define IMX_COMPOSITE_FW_MANAGED	BIT(2)
>  
>  struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>  					    const char * const *parent_names,
> @@ -567,6 +568,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>  		ARRAY_SIZE(parent_names), reg, 0, \
>  		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
>  
> +#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \
> +	imx8m_clk_hw_composite_flags(name, parent_names, \
> +		ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \
> +		flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
> +
> +#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
> +	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0)
> +
> +#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
> +	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL)
> +
>  #define __imx8m_clk_composite(name, parent_names, reg, flags) \
>  	to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
>  
> -- 
> 2.30.2
> 


From maz at kernel.org  Wed Aug 18 08:16:04 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 16:16:04 +0100
Subject: [PATCH v4 10/15] KVM: arm64: Add config register bit definitions
In-Reply-To: <20210817081134.2918285-11-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-11-tabba@google.com>
Message-ID: <87h7fmss0b.wl-maz@kernel.org>

On Tue, 17 Aug 2021 09:11:29 +0100,
Fuad Tabba <tabba at google.com> wrote:
> 
> Add hardware configuration register bit definitions for HCR_EL2
> and MDCR_EL2. Future patches toggle these hyp configuration
> register bits to trap on certain accesses.
> 
> No functional change intended.
> 
> Acked-by: Will Deacon <will at kernel.org>
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/include/asm/kvm_arm.h | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index a928b2dc0b0f..327120c0089f 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -12,8 +12,13 @@
>  #include <asm/types.h>
>  
>  /* Hyp Configuration Register (HCR) bits */
> +
> +#define HCR_TID5	(UL(1) << 58)
> +#define HCR_DCT		(UL(1) << 57)
>  #define HCR_ATA_SHIFT	56
>  #define HCR_ATA		(UL(1) << HCR_ATA_SHIFT)
> +#define HCR_AMVOFFEN	(UL(1) << 51)
> +#define HCR_FIEN	(UL(1) << 47)
>  #define HCR_FWB		(UL(1) << 46)
>  #define HCR_API		(UL(1) << 41)
>  #define HCR_APK		(UL(1) << 40)
> @@ -56,6 +61,7 @@
>  #define HCR_PTW		(UL(1) << 2)
>  #define HCR_SWIO	(UL(1) << 1)
>  #define HCR_VM		(UL(1) << 0)
> +#define HCR_RES0	((UL(1) << 48) | (UL(1) << 39))
>  
>  /*
>   * The bits we set in HCR:
> @@ -277,11 +283,21 @@
>  #define CPTR_EL2_TZ	(1 << 8)
>  #define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
>  #define CPTR_EL2_DEFAULT	CPTR_NVHE_EL2_RES1
> +#define CPTR_NVHE_EL2_RES0	(GENMASK(63, 32) |	\
> +				 GENMASK(29, 21) |	\
> +				 GENMASK(19, 14) |	\
> +				 BIT(11))
>  
>  /* Hyp Debug Configuration Register bits */
>  #define MDCR_EL2_E2TB_MASK	(UL(0x3))
>  #define MDCR_EL2_E2TB_SHIFT	(UL(24))
> +#define MDCR_EL2_HPMFZS		(UL(1) << 36)
> +#define MDCR_EL2_HPMFZO		(UL(1) << 29)
> +#define MDCR_EL2_MTPME		(UL(1) << 28)
> +#define MDCR_EL2_TDCC		(UL(1) << 27)
> +#define MDCR_EL2_HCCD		(UL(1) << 23)

Nit: If you're aiming for completeness, you're missing MDCR_EL2.HLP
(bit 26).

>  #define MDCR_EL2_TTRF		(UL(1) << 19)
> +#define MDCR_EL2_HPMD		(UL(1) << 17)
>  #define MDCR_EL2_TPMS		(UL(1) << 14)
>  #define MDCR_EL2_E2PB_MASK	(UL(0x3))
>  #define MDCR_EL2_E2PB_SHIFT	(UL(12))
> @@ -293,6 +309,12 @@
>  #define MDCR_EL2_TPM		(UL(1) << 6)
>  #define MDCR_EL2_TPMCR		(UL(1) << 5)
>  #define MDCR_EL2_HPMN_MASK	(UL(0x1F))
> +#define MDCR_EL2_RES0		(GENMASK(63, 37) |	\
> +				 GENMASK(35, 30) |	\
> +				 GENMASK(25, 24) |	\
> +				 GENMASK(22, 20) |	\
> +				 BIT(18) |		\
> +				 GENMASK(16, 15))
>  
>  /* For compatibility with fault code shared with 32-bit */
>  #define FSC_FAULT	ESR_ELx_FSC_FAULT

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From colin.king at canonical.com  Wed Aug 18 08:17:46 2021
From: colin.king at canonical.com (Colin King)
Date: Wed, 18 Aug 2021 16:17:46 +0100
Subject: [PATCH] ASoC: uniphier: make arrays mul and div static const,
 makes object smaller
Message-ID: <20210818151746.38520-1-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

Don't populate the arrays mul and div on the stack but instead make them
static const. Makes the object code smaller by 4 bytes.

Before:
   text    data     bss     dec     hex filename
  16226    4984      64   21274    531a ./sound/soc/uniphier/aio-cpu.o

After:
   text    data     bss     dec     hex filename
  16062    5144      64   21270    5316 ./sound/soc/uniphier/aio-cpu.o

(gcc version 10.2.0)

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 sound/soc/uniphier/aio-cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
index cf9814130067..4e8d5f7532ba 100644
--- a/sound/soc/uniphier/aio-cpu.c
+++ b/sound/soc/uniphier/aio-cpu.c
@@ -128,8 +128,8 @@ static const struct uniphier_aio_spec *find_spec(struct uniphier_aio *aio,
 static int find_divider(struct uniphier_aio *aio, int pll_id, unsigned int freq)
 {
 	struct uniphier_aio_pll *pll;
-	int mul[] = { 1, 1, 1, 2, };
-	int div[] = { 2, 3, 1, 3, };
+	static const int mul[] = { 1, 1, 1, 2, };
+	static const int div[] = { 2, 3, 1, 3, };
 	int i;
 
 	if (!is_valid_pll(aio->chip, pll_id))
-- 
2.32.0



From a.fatoum at pengutronix.de  Wed Aug 18 08:28:42 2021
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Wed, 18 Aug 2021 17:28:42 +0200
Subject: [PATCH] clk: imx8m: fix clock tree update of TF-A managed clocks
In-Reply-To: <YR0j21KspR618YLK@ryzen>
References: <20210810151432.9228-1-a.fatoum@pengutronix.de>
 <YR0j21KspR618YLK@ryzen>
Message-ID: <93de171b-a4d3-e1da-a5e0-4c50e7a97c5d@pengutronix.de>

Hello Abel,

On 18.08.21 17:14, Abel Vesa wrote:
> On 21-08-10 17:14:33, Ahmad Fatoum wrote:
>> On the i.MX8M*, the TF-A exposes a SiP (Silicon Provider) service
>> for DDR frequency scaling. The imx8m-ddrc-devfreq driver calls the
>> SiP and then does clk_set_parent on the DDR muxes to synchronize
>> the clock tree.
>>
>> Since 936c383673b9 ("clk: imx: fix composite peripheral flags"),
>> these TF-A managed muxes have SET_PARENT_GATE set, which results
>> in imx8m-ddrc-devfreq's clk_set_parent after SiP failing with -EBUSY:
>>
>> 	echo 25000000 > userspace/set_freq
>> 	imx8m-ddrc-devfreq 3d400000.memory-controller: failed to set
>> 		dram_apb parent: -16
>>
>> Fix this by adding a new i.MX composite flag for firmware managed
>> clocks, which clears SET_PARENT_GATE.
>>
>> This is safe to do, because updating the Linux clock tree to reflect
>> reality will always be glitch-free.
>>
>> Fixes: 936c383673b9 ("clk: imx: fix composite peripheral flags")
>> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> 
> I'm OK with this.
> 
> Reviewed-by: Abel Vesa <abel.vesa at nxp.com>

Thanks for the review.

> BTW, let me know if you are interested in the interconnect+devfreq
> (the replacement for NXP's internal busfreq). I have a new version of
> that patchset which I intend to send soon for review.

Ye, add me to CC and I'll give it at least a test. It sounds like you
recently worked with devfreq? I am wondering why you didn't run into this issue.

Cheers,
Ahmad

> 
>> ---
>> To: Abel Vesa <abel.vesa at nxp.com>
>> To: Michael Turquette <mturquette at baylibre.com>
>> To: Stephen Boyd <sboyd at kernel.org>
>> To: Shawn Guo <shawnguo at kernel.org>
>> To: Sascha Hauer <s.hauer at pengutronix.de>
>> To: Pengutronix Kernel Team <kernel at pengutronix.de>
>> To: Fabio Estevam <festevam at gmail.com>
>> To: NXP Linux Team <linux-imx at nxp.com>
>> To: Peng Fan <peng.fan at nxp.com>
>> To: Leonard Crestez <leonard.crestez at nxp.com>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: linux-clk at vger.kernel.org
>> ---
>>  drivers/clk/imx/clk-composite-8m.c |  3 ++-
>>  drivers/clk/imx/clk-imx8mm.c       |  7 ++++---
>>  drivers/clk/imx/clk-imx8mn.c       |  7 ++++---
>>  drivers/clk/imx/clk-imx8mq.c       |  7 ++++---
>>  drivers/clk/imx/clk.h              | 16 ++++++++++++++--
>>  5 files changed, 28 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
>> index 2c309e3dc8e3..04e728538cef 100644
>> --- a/drivers/clk/imx/clk-composite-8m.c
>> +++ b/drivers/clk/imx/clk-composite-8m.c
>> @@ -216,7 +216,8 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>>  		div->width = PCG_PREDIV_WIDTH;
>>  		divider_ops = &imx8m_clk_composite_divider_ops;
>>  		mux_ops = &clk_mux_ops;
>> -		flags |= CLK_SET_PARENT_GATE;
>> +		if (!(composite_flags & IMX_COMPOSITE_FW_MANAGED))
>> +			flags |= CLK_SET_PARENT_GATE;
>>  	}
>>  
>>  	div->lock = &imx_ccm_lock;
>> diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
>> index f1919fafb124..73cc9805ec59 100644
>> --- a/drivers/clk/imx/clk-imx8mm.c
>> +++ b/drivers/clk/imx/clk-imx8mm.c
>> @@ -470,10 +470,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
>>  
>>  	/*
>>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
>> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
>> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
>> +	 * as div value should always be read from hardware
>>  	 */
>> -	hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
>> -	hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
>> +	hws[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
>> +	hws[IMX8MM_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
>>  
>>  	/* IP */
>>  	hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
>> diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
>> index 88f6630cd472..0a76f969b28b 100644
>> --- a/drivers/clk/imx/clk-imx8mn.c
>> +++ b/drivers/clk/imx/clk-imx8mn.c
>> @@ -453,10 +453,11 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
>>  
>>  	/*
>>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
>> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
>> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
>> +	 * as div value should always be read from hardware
>>  	 */
>> -	hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
>> -	hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
>> +	hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
>> +	hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
>>  
>>  	hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
>>  	hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
>> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
>> index c491bc9c61ce..83cc2b1c3294 100644
>> --- a/drivers/clk/imx/clk-imx8mq.c
>> +++ b/drivers/clk/imx/clk-imx8mq.c
>> @@ -449,11 +449,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
>>  
>>  	/*
>>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
>> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
>> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
>> +	 * as div value should always be read from hardware
>>  	 */
>>  	hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
>> -	hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
>> -	hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
>> +	hws[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
>> +	hws[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
>>  
>>  	/* IP */
>>  	hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
>> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
>> index 7571603bee23..e144f983fd8c 100644
>> --- a/drivers/clk/imx/clk.h
>> +++ b/drivers/clk/imx/clk.h
>> @@ -530,8 +530,9 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
>>  		struct clk *div, struct clk *mux, struct clk *pll,
>>  		struct clk *step);
>>  
>> -#define IMX_COMPOSITE_CORE	BIT(0)
>> -#define IMX_COMPOSITE_BUS	BIT(1)
>> +#define IMX_COMPOSITE_CORE		BIT(0)
>> +#define IMX_COMPOSITE_BUS		BIT(1)
>> +#define IMX_COMPOSITE_FW_MANAGED	BIT(2)
>>  
>>  struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>>  					    const char * const *parent_names,
>> @@ -567,6 +568,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>>  		ARRAY_SIZE(parent_names), reg, 0, \
>>  		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
>>  
>> +#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \
>> +	imx8m_clk_hw_composite_flags(name, parent_names, \
>> +		ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \
>> +		flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
>> +
>> +#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
>> +	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0)
>> +
>> +#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
>> +	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL)
>> +
>>  #define __imx8m_clk_composite(name, parent_names, reg, flags) \
>>  	to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
>>  
>> -- 
>> 2.30.2
>>
> 


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From houlong.wei at mediatek.com  Wed Aug 18 08:34:32 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Wed, 18 Aug 2021 23:34:32 +0800
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <CAOak1e-oyzxbvHimMReQpZCAPyCtAsaGixjwmoa0EzMjqaUxVg@mail.gmail.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <bf98c5ee749bca755bd46832f858536dbf51a2a4.camel@mediatek.com>
 <CAOak1e-oyzxbvHimMReQpZCAPyCtAsaGixjwmoa0EzMjqaUxVg@mail.gmail.com>
Message-ID: <ea8c8373fbf6a9895276f098cfa2cf3f7761a4b5.camel@mediatek.com>

Hi Eizan,

Firstly, about how to determine the master mdp driver, we also can
judge the component type. The component type can be gotten by calling
of_device_get_match_data(dev). If the component is MTK_MDP_RDMA, it is
the master driver. No matter it is mdp_rdma0 or mdp_rdma1.

Secondly, about supporting the multiple MDP master device nodes, you
can try my advice in my previous comment after the completion of this
series of patches.

Thanks a lot.

Regards,
Houlong

On Wed, 2021-08-18 at 15:43 +0800, Eizan Miyamoto wrote:
> Hi Houlong,
> 
> On Mon, Aug 16, 2021 at 1:00 PM houlong wei <houlong.wei at mediatek.com
> > wrote:
> > Hi Eizan,
> > 
> > "mdp-rdma0" may be not the only one master device node. In fact,
> > there
> > are 2 "mdp-rdma" in mt8173. You can see "mdp_rdma1" via below link.
> > 
> > 
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/boot/dts/mediatek/mt8173.dtsi?h=v5.13.11#n1016
> > If we add "mediatek,mt8173-mdp" to "mdp_rdma1" like below, we will
> > have
> > one more V4L2 video devie node.
> > 
> >                 mdp_rdma1: rdma at 14002000 {
> >                         compatible = "mediatek,mt8173-mdp-rdma",
> >                                      "mediatek,mt8173-mdp";
> >                         ...
> >                 }
> > 
> > We should consider the case that there are more than one "MDP_RDMA"
> > components.
> 
> Would it be okay with you if we added support for multiple MDP master
> device nodes in follow-up changes? My rationale is this:
> - As far as I can tell, the mediatek integration with V4L2 currently
> only handles a single MDP master device node. It's not clear to me
> the
> scope of changes that will be needed to make things work properly
> with
> multiple nodes.
> - The patch series makes video decode work (admittedly, in light of
> your comments not optimally) upstream, which is better than not
> landing these changes at all.
> 
> I'd like to say that I'm very open to (and excited about) discussing
> further work to support multiple MDP master nodes, perhaps we can
> work together on this so I can understand what needs to be done.
> 
> Please let me know your thoughts,
> 
> Eizan

From abel.vesa at nxp.com  Wed Aug 18 08:39:23 2021
From: abel.vesa at nxp.com (Abel Vesa)
Date: Wed, 18 Aug 2021 18:39:23 +0300
Subject: [PATCH] clk: imx8m: fix clock tree update of TF-A managed clocks
In-Reply-To: <93de171b-a4d3-e1da-a5e0-4c50e7a97c5d@pengutronix.de>
References: <20210810151432.9228-1-a.fatoum@pengutronix.de>
 <YR0j21KspR618YLK@ryzen>
 <93de171b-a4d3-e1da-a5e0-4c50e7a97c5d@pengutronix.de>
Message-ID: <YR0pqxqrlW+2KpmZ@ryzen>

On 21-08-18 17:28:42, Ahmad Fatoum wrote:
> Hello Abel,
> 
> On 18.08.21 17:14, Abel Vesa wrote:
> > On 21-08-10 17:14:33, Ahmad Fatoum wrote:
> >> On the i.MX8M*, the TF-A exposes a SiP (Silicon Provider) service
> >> for DDR frequency scaling. The imx8m-ddrc-devfreq driver calls the
> >> SiP and then does clk_set_parent on the DDR muxes to synchronize
> >> the clock tree.
> >>
> >> Since 936c383673b9 ("clk: imx: fix composite peripheral flags"),
> >> these TF-A managed muxes have SET_PARENT_GATE set, which results
> >> in imx8m-ddrc-devfreq's clk_set_parent after SiP failing with -EBUSY:
> >>
> >> 	echo 25000000 > userspace/set_freq
> >> 	imx8m-ddrc-devfreq 3d400000.memory-controller: failed to set
> >> 		dram_apb parent: -16
> >>
> >> Fix this by adding a new i.MX composite flag for firmware managed
> >> clocks, which clears SET_PARENT_GATE.
> >>
> >> This is safe to do, because updating the Linux clock tree to reflect
> >> reality will always be glitch-free.
> >>
> >> Fixes: 936c383673b9 ("clk: imx: fix composite peripheral flags")
> >> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> > 
> > I'm OK with this.
> > 
> > Reviewed-by: Abel Vesa <abel.vesa at nxp.com>
> 
> Thanks for the review.
> 
> > BTW, let me know if you are interested in the interconnect+devfreq
> > (the replacement for NXP's internal busfreq). I have a new version of
> > that patchset which I intend to send soon for review.
> 
> Ye, add me to CC and I'll give it at least a test. It sounds like you
> recently worked with devfreq? I am wondering why you didn't run into this issue.

I actually had a different fix for this issue actually. Have a look here:

https://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git/commit/?h=imx8mq/icc_devfreq&id=bd39ccabdfdbf128670dea56094b0da7764be05a

And my fix will still be needed when the icc+devfreq gets in, since the
parent will be changed in TF-A but the kernel clock tree can't because
the clock is marked as CLK_IS_CRITICAL.

> 
> Cheers,
> Ahmad
> 
> > 
> >> ---
> >> To: Abel Vesa <abel.vesa at nxp.com>
> >> To: Michael Turquette <mturquette at baylibre.com>
> >> To: Stephen Boyd <sboyd at kernel.org>
> >> To: Shawn Guo <shawnguo at kernel.org>
> >> To: Sascha Hauer <s.hauer at pengutronix.de>
> >> To: Pengutronix Kernel Team <kernel at pengutronix.de>
> >> To: Fabio Estevam <festevam at gmail.com>
> >> To: NXP Linux Team <linux-imx at nxp.com>
> >> To: Peng Fan <peng.fan at nxp.com>
> >> To: Leonard Crestez <leonard.crestez at nxp.com>
> >> Cc: linux-arm-kernel at lists.infradead.org
> >> Cc: linux-kernel at vger.kernel.org
> >> Cc: linux-clk at vger.kernel.org
> >> ---
> >>  drivers/clk/imx/clk-composite-8m.c |  3 ++-
> >>  drivers/clk/imx/clk-imx8mm.c       |  7 ++++---
> >>  drivers/clk/imx/clk-imx8mn.c       |  7 ++++---
> >>  drivers/clk/imx/clk-imx8mq.c       |  7 ++++---
> >>  drivers/clk/imx/clk.h              | 16 ++++++++++++++--
> >>  5 files changed, 28 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
> >> index 2c309e3dc8e3..04e728538cef 100644
> >> --- a/drivers/clk/imx/clk-composite-8m.c
> >> +++ b/drivers/clk/imx/clk-composite-8m.c
> >> @@ -216,7 +216,8 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
> >>  		div->width = PCG_PREDIV_WIDTH;
> >>  		divider_ops = &imx8m_clk_composite_divider_ops;
> >>  		mux_ops = &clk_mux_ops;
> >> -		flags |= CLK_SET_PARENT_GATE;
> >> +		if (!(composite_flags & IMX_COMPOSITE_FW_MANAGED))
> >> +			flags |= CLK_SET_PARENT_GATE;
> >>  	}
> >>  
> >>  	div->lock = &imx_ccm_lock;
> >> diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
> >> index f1919fafb124..73cc9805ec59 100644
> >> --- a/drivers/clk/imx/clk-imx8mm.c
> >> +++ b/drivers/clk/imx/clk-imx8mm.c
> >> @@ -470,10 +470,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
> >>  
> >>  	/*
> >>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> >> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> >> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> >> +	 * as div value should always be read from hardware
> >>  	 */
> >> -	hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> >> -	hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> >> +	hws[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
> >> +	hws[IMX8MM_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
> >>  
> >>  	/* IP */
> >>  	hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
> >> diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
> >> index 88f6630cd472..0a76f969b28b 100644
> >> --- a/drivers/clk/imx/clk-imx8mn.c
> >> +++ b/drivers/clk/imx/clk-imx8mn.c
> >> @@ -453,10 +453,11 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
> >>  
> >>  	/*
> >>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> >> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> >> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> >> +	 * as div value should always be read from hardware
> >>  	 */
> >> -	hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> >> -	hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> >> +	hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
> >> +	hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
> >>  
> >>  	hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
> >>  	hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
> >> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> >> index c491bc9c61ce..83cc2b1c3294 100644
> >> --- a/drivers/clk/imx/clk-imx8mq.c
> >> +++ b/drivers/clk/imx/clk-imx8mq.c
> >> @@ -449,11 +449,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
> >>  
> >>  	/*
> >>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> >> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> >> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> >> +	 * as div value should always be read from hardware
> >>  	 */
> >>  	hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
> >> -	hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> >> -	hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> >> +	hws[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
> >> +	hws[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
> >>  
> >>  	/* IP */
> >>  	hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
> >> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
> >> index 7571603bee23..e144f983fd8c 100644
> >> --- a/drivers/clk/imx/clk.h
> >> +++ b/drivers/clk/imx/clk.h
> >> @@ -530,8 +530,9 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
> >>  		struct clk *div, struct clk *mux, struct clk *pll,
> >>  		struct clk *step);
> >>  
> >> -#define IMX_COMPOSITE_CORE	BIT(0)
> >> -#define IMX_COMPOSITE_BUS	BIT(1)
> >> +#define IMX_COMPOSITE_CORE		BIT(0)
> >> +#define IMX_COMPOSITE_BUS		BIT(1)
> >> +#define IMX_COMPOSITE_FW_MANAGED	BIT(2)
> >>  
> >>  struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
> >>  					    const char * const *parent_names,
> >> @@ -567,6 +568,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
> >>  		ARRAY_SIZE(parent_names), reg, 0, \
> >>  		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
> >>  
> >> +#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \
> >> +	imx8m_clk_hw_composite_flags(name, parent_names, \
> >> +		ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \
> >> +		flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
> >> +
> >> +#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
> >> +	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0)
> >> +
> >> +#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
> >> +	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL)
> >> +
> >>  #define __imx8m_clk_composite(name, parent_names, reg, flags) \
> >>  	to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
> >>  
> >> -- 
> >> 2.30.2
> >>
> > 
> 
> 
> -- 
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pengutronix.de%2F&amp;data=04%7C01%7Cabel.vesa%40nxp.com%7Cb8c21d0576b0482b181608d9625cdf49%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637648973293620984%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=D0efPtr5bHllXtgau1QWgMrzY8p2Zckeo43pvUztDPE%3D&amp;reserved=0  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From houlong.wei at mediatek.com  Wed Aug 18 08:42:45 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Wed, 18 Aug 2021 23:42:45 +0800
Subject: [PATCH v6 7/9] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <CAOak1e924x8E+kM2WJ3oGPxxt_R=b79BtbxPAdENamvjVamnEw@mail.gmail.com>
References: <20210802121215.703023-1-eizan@chromium.org>
 <20210802220943.v6.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <bf98c5ee749bca755bd46832f858536dbf51a2a4.camel@mediatek.com>
 <9f23beea197495d017a548ef483584714a3673f9.camel@mediatek.com>
 <CAOak1e924x8E+kM2WJ3oGPxxt_R=b79BtbxPAdENamvjVamnEw@mail.gmail.com>
Message-ID: <14b9c2efb28d84712b7b4e7b67b6c87558cd9f5d.camel@mediatek.com>

On Wed, 2021-08-18 at 15:50 +0800, Eizan Miyamoto wrote:
> Hi Houlong,
> 
> Thank you for your review on this series, it is much appreciated.
> 
> On Mon, Aug 16, 2021 at 2:53 PM houlong wei <houlong.wei at mediatek.com
> > wrote:
> > Is your removing "mediatek,vpu" necessary for this series "Refactor
> > MTK
> > MDP driver into core/components" ?
> 
> Removing it is not strictly necessary for the series to function, I
> will re-upload the series and omit the following changes:
> - [PATCH v6 8/9] dts: mtk-mdp: remove mediatek,vpu property from
> primary MDP device
> - [PATCH v6 9/9] dt-bindings: mediatek: remove vpu requirement from
> mtk-mdp
> 
> Do please let me know if you meant something different.
> 
> Thanks,
> 
> Eizan
> 
> 
Hi Eizan,

Thanks for your help and effort. It's exactly what I expressed.

Regards,
Houlong
> 
> 
> > 
> > In some MediaTek projects (not upstream yet), the device-tree node
> > name
> > "vpu" may be changed to something like "vpu0", "vpu1" or other
> > name,
> > which depends on the implementation of "mtk-vpu" driver. We can
> > specify
> > the different phandle to "mediatek,vpu" in .dtsi file. If we use
> > of_find_node_by_name() to get the vpu_node, we have to modify the
> > name
> > string in different project.
> > If the answer of my previous questions is "No", I prefer to slow
> > down
> > the modification of removing "mediatek,vpu".
> > 
> > Sorry for late reply.
> > 
> > Regards,
> > Houlong

From nm at ti.com  Wed Aug 18 09:14:15 2021
From: nm at ti.com (Nishanth Menon)
Date: Wed, 18 Aug 2021 11:14:15 -0500
Subject: [PATCH] arm64: dts: ti: k3-am64-mcu: Add pinctrl
In-Reply-To: <13974a27-a90d-639d-d050-c97570fdf369@ti.com>
References: <20210818111747.88569-1-christian.gmeiner@gmail.com>
 <13974a27-a90d-639d-d050-c97570fdf369@ti.com>
Message-ID: <20210818161415.fmj5cufon3zvrvjs@dyslexic>

On 09:13-20210818, Dave Gerlach wrote:
> Hi,
> 
> On 8/18/21 6:17 AM, Christian Gmeiner wrote:
> > Add the definition of the pinctrl for the MCU domain.
> > 
> > Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
> > ---
> >  arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
> > index 59cc58f7d0c8..2bb5c9ff172c 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
> > @@ -97,4 +97,12 @@ mcu_gpio0: gpio at 4201000 {
> >  		clocks = <&k3_clks 79 0>;
> >  		clock-names = "gpio";
> >  	};
> > +
> > +	mcu_pmx0: pinctrl at 4084000 {
> > +		compatible = "pinctrl-single";
> > +		reg = <0x00 0x4084000 0x00 0x84>;
> > +		#pinctrl-cells = <1>;
> > +		pinctrl-single,register-width = <32>;
> > +		pinctrl-single,function-mask = <0xffffffff>;
> > +	};
> >  };
> > 
> 
> Reviewed-by: Dave Gerlach <d-gerlach at ti.com>


Sigh.. Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt is
still not converted to yaml .. but otherwise, it is a bit late for 5.15
window.. I can stage it for 5.16 once rc1 is tagged (and need to figure
out pinctrl-single situation..)

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From mark.rutland at arm.com  Wed Aug 18 09:15:35 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 18 Aug 2021 17:15:35 +0100
Subject: [PATCH] arm64: initialize all of CNTHCTL_EL2
Message-ID: <20210818161535.52786-1-mark.rutland@arm.com>

In __init_el2_timers we initialize CNTHCTL_EL2.{EL1PCEN,EL1PCTEN} with a
RMW sequence, leaving all other bits UNKNOWN.

In general, we should initialize all bits in a register rather than
using an RMW sequence, since most bits are UNKNOWN out of reset, and as
new bits are added to the reigster their reset value might not result in
expected behaviour.

In the case of CNTHCTL_EL2, FEAT_ECV added a number of new control bits
in previously RES0 bits, which reset to UNKNOWN values, and may cause
issues for EL1 and EL0:

* CNTHCTL_EL2.ECV enables the CNTPOFF_EL2 offset (which itself resets to
  an UNKNOWN value) at EL0 and EL1. Since the offset could reset to
  distinct values across CPUs, when the control bit resets to 1 this
  could break timekeeping generally.

* CNTHCTL_EL2.{EL1TVT,EL1TVCT} trap EL0 and EL1 accesses to the EL1
  virtual timer/counter registers to EL2. When reset to 1, this could
  cause unexpected traps to EL2.

Initializing these bits to zero avoids these problems, and all other
bits in CNPTOFF_EL2 other than EL1PCEN and EL1PCTEN can safely be reset
to zero.

This patch ensures we initialize CNTHCTL_EL2 accordingly, only setting
EL1PCEN and EL1PCTEN, and setting all other bits to zero.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oupton at google.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 21fa330f498dd..b83fb24954b77 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -33,8 +33,7 @@
  * EL2.
  */
 .macro __init_el2_timers
-	mrs	x0, cnthctl_el2
-	orr	x0, x0, #3			// Enable EL1 physical timers
+	mov	x0, #3				// Enable EL1 physical timers
 	msr	cnthctl_el2, x0
 	msr	cntvoff_el2, xzr		// Clear virtual offset
 .endm
-- 
2.11.0



From robh at kernel.org  Wed Aug 18 09:21:06 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 11:21:06 -0500
Subject: [PATCH] dt-bindings: memory: convert Broadcom DPFE to dtschema
In-Reply-To: <20210817080617.14503-1-krzysztof.kozlowski@canonical.com>
References: <20210817080617.14503-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YR0zchjUr073SoTO@robh.at.kernel.org>

On Tue, 17 Aug 2021 10:06:17 +0200, Krzysztof Kozlowski wrote:
> Convert Broadcom DDR PHY Front End (DPFE) bindings to DT schema format
> using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../memory-controllers/brcm,dpfe-cpu.txt      | 27 -----------
>  .../memory-controllers/brcm,dpfe-cpu.yaml     | 48 +++++++++++++++++++
>  MAINTAINERS                                   |  2 +-
>  3 files changed, 49 insertions(+), 28 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/brcm,dpfe-cpu.yaml
> 

Applied, thanks!


From mhiramat at kernel.org  Wed Aug 18 09:27:57 2021
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Thu, 19 Aug 2021 01:27:57 +0900
Subject: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210818073336.59678-3-liuqi115@huawei.com>
References: <20210818073336.59678-1-liuqi115@huawei.com>
 <20210818073336.59678-3-liuqi115@huawei.com>
Message-ID: <20210819012757.bf08d4c601cca4d401d5803f@kernel.org>

On Wed, 18 Aug 2021 15:33:36 +0800
Qi Liu <liuqi115 at huawei.com> wrote:

> This patch introduce optprobe for ARM64. In optprobe, probed
> instruction is replaced by a branch instruction to detour
> buffer. Detour buffer contains trampoline code and a call to
> optimized_callback(). optimized_callback() calls opt_pre_handler()
> to execute kprobe handler.
> 
> Performance of optprobe on Hip08 platform is test using kprobe
> example module[1] to analyze the latency of a kernel function,
> and here is the result:
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> 
> kprobe before optimized:
> [280709.846380] do_empty returned 0 and took 1530 ns to execute
> [280709.852057] do_empty returned 0 and took 550 ns to execute
> [280709.857631] do_empty returned 0 and took 440 ns to execute
> [280709.863215] do_empty returned 0 and took 380 ns to execute
> [280709.868787] do_empty returned 0 and took 360 ns to execute
> [280709.874362] do_empty returned 0 and took 340 ns to execute
> [280709.879936] do_empty returned 0 and took 320 ns to execute
> [280709.885505] do_empty returned 0 and took 300 ns to execute
> [280709.891075] do_empty returned 0 and took 280 ns to execute
> [280709.896646] do_empty returned 0 and took 290 ns to execute
> [280709.902220] do_empty returned 0 and took 290 ns to execute
> [280709.907807] do_empty returned 0 and took 290 ns to execute
> 
> optprobe:
> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> [ 2966.029158] do_empty returned 0 and took 70 ns to execute
> 
> Signed-off-by: Qi Liu <liuqi115 at huawei.com>

Thanks for updating. This looks good to me. :D

Acked-by: Masami Hiramatsu <mhiramat at kernel.org>

Thank you!

> 
> Note:
> To guarantee the offset between probe point and kprobe pre_handler
> is smaller than 128MiB, users should set
> CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
> optprobe will not work and fall back to normal kprobe.
> ---
>  arch/arm64/Kconfig                            |   1 +
>  arch/arm64/include/asm/kprobes.h              |  24 ++
>  arch/arm64/kernel/probes/Makefile             |   2 +
>  arch/arm64/kernel/probes/kprobes.c            |  19 +-
>  arch/arm64/kernel/probes/opt_arm64.c          | 276 ++++++++++++++++++
>  .../arm64/kernel/probes/optprobe_trampoline.S |  37 +++
>  6 files changed, 356 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm64/kernel/probes/opt_arm64.c
>  create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b5b13a932561..b05d1d275d87 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -200,6 +200,7 @@ config ARM64
>  	select HAVE_STACKPROTECTOR
>  	select HAVE_SYSCALL_TRACEPOINTS
>  	select HAVE_KPROBES
> +	select HAVE_OPTPROBES
>  	select HAVE_KRETPROBES
>  	select HAVE_GENERIC_VDSO
>  	select IOMMU_DMA if IOMMU_SUPPORT
> diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
> index 5d38ff4a4806..6b2fdd2ad7d8 100644
> --- a/arch/arm64/include/asm/kprobes.h
> +++ b/arch/arm64/include/asm/kprobes.h
> @@ -39,6 +39,30 @@ void arch_remove_kprobe(struct kprobe *);
>  int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
>  int kprobe_exceptions_notify(struct notifier_block *self,
>  			     unsigned long val, void *data);
> +
> +#define RELATIVEJUMP_SIZE (4)
> +#define MAX_COPIED_INSN	DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
> +struct arch_optimized_insn {
> +	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
> +	/* detour code buffer */
> +	kprobe_opcode_t *insn;
> +};
> +
> +/* optinsn template addresses */
> +extern __visible kprobe_opcode_t optprobe_template_entry[];
> +extern __visible kprobe_opcode_t optprobe_template_val[];
> +extern __visible kprobe_opcode_t optprobe_template_call[];
> +extern __visible kprobe_opcode_t optprobe_template_end[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_end[];
> +extern __visible kprobe_opcode_t optprobe_template_max_length[];
> +
> +#define MAX_OPTIMIZED_LENGTH	4
> +#define MAX_OPTINSN_SIZE				\
> +	((unsigned long)optprobe_template_end -	\
> +	 (unsigned long)optprobe_template_entry)
> +
>  void kretprobe_trampoline(void);
>  void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
>  
> diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
> index 8e4be92e25b1..07105fd3261d 100644
> --- a/arch/arm64/kernel/probes/Makefile
> +++ b/arch/arm64/kernel/probes/Makefile
> @@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o decode-insn.o	\
>  				   simulate-insn.o
>  obj-$(CONFIG_UPROBES)		+= uprobes.o decode-insn.o	\
>  				   simulate-insn.o
> +obj-$(CONFIG_OPTPROBES)		+= opt_arm64.o			\
> +				   optprobe_trampoline.o
> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> index 6dbcc89f6662..83755ad62abe 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> @@ -11,6 +11,7 @@
>  #include <linux/kasan.h>
>  #include <linux/kernel.h>
>  #include <linux/kprobes.h>
> +#include <linux/moduleloader.h>
>  #include <linux/sched/debug.h>
>  #include <linux/set_memory.h>
>  #include <linux/slab.h>
> @@ -113,9 +114,21 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
>  
>  void *alloc_insn_page(void)
>  {
> -	return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
> -			GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
> -			NUMA_NO_NODE, __builtin_return_address(0));
> +	void *page;
> +
> +	page = module_alloc(PAGE_SIZE);
> +	if (!page)
> +		return NULL;
> +
> +	set_vm_flush_reset_perms(page);
> +	/*
> +	 * First make the page read-only, and only then make it executable to
> +	 * prevent it from being W+X in between.
> +	 */
> +	set_memory_ro((unsigned long)page, 1);
> +	set_memory_x((unsigned long)page, 1);
> +
> +	return page;
>  }
>  
>  /* arm kprobe: install breakpoint in text */
> diff --git a/arch/arm64/kernel/probes/opt_arm64.c b/arch/arm64/kernel/probes/opt_arm64.c
> new file mode 100644
> index 000000000000..4de535bee534
> --- /dev/null
> +++ b/arch/arm64/kernel/probes/opt_arm64.c
> @@ -0,0 +1,276 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Code for Kernel probes Jump optimization.
> + *
> + * Copyright (C) 2021 Hisilicon Limited
> + */
> +
> +#include <linux/jump_label.h>
> +#include <linux/kprobes.h>
> +
> +#include <asm/cacheflush.h>
> +#include <asm/insn.h>
> +#include <asm/kprobes.h>
> +#include <asm/patching.h>
> +
> +#define TMPL_VAL_IDX \
> +	(optprobe_template_val - optprobe_template_entry)
> +#define TMPL_CALL_BACK \
> +	(optprobe_template_call - optprobe_template_entry)
> +#define TMPL_END_IDX \
> +	(optprobe_template_end - optprobe_template_entry)
> +#define TMPL_RESTORE_ORIGN_INSN \
> +	(optprobe_template_restore_orig_insn - optprobe_template_entry)
> +#define TMPL_RESTORE_END \
> +	(optprobe_template_restore_end - optprobe_template_entry)
> +#define TMPL_MAX_LENGTH \
> +	(optprobe_template_max_length - optprobe_template_entry)
> +#define OPTPROBE_BATCH_SIZE 64
> +
> +int arch_check_optimized_kprobe(struct optimized_kprobe *op)
> +{
> +	return 0;
> +}
> +
> +int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
> +{
> +	return optinsn->insn != NULL;
> +}
> +
> +int arch_within_optimized_kprobe(struct optimized_kprobe *op,
> +				unsigned long addr)
> +{
> +	return ((unsigned long)op->kp.addr <= addr &&
> +		(unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
> +}
> +
> +static void
> +optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
> +{
> +	/* This is possible if op is under delayed unoptimizing */
> +	if (kprobe_disabled(&op->kp))
> +		return;
> +
> +	preempt_disable();
> +
> +	if (kprobe_running()) {
> +		kprobes_inc_nmissed_count(&op->kp);
> +	} else {
> +		__this_cpu_write(current_kprobe, &op->kp);
> +		regs->pc = (unsigned long)op->kp.addr;
> +		get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
> +		opt_pre_handler(&op->kp, regs);
> +		__this_cpu_write(current_kprobe, NULL);
> +	}
> +
> +	preempt_enable_no_resched();
> +}
> +NOKPROBE_SYMBOL(optimized_callback)
> +
> +static bool is_offset_in_range(unsigned long start, unsigned long end)
> +{
> +	long offset = end - start;
> +
> +	/*
> +	 * Verify if the address gap is in 128MiB range, because this uses
> +	 * a relative jump.
> +	 *
> +	 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
> +	 * According to ARM manual, branch instruction is:
> +	 *
> +	 *   31  30                  25              0
> +	 *  +----+---+---+---+---+---+---------------+
> +	 *  |cond| 0 | 0 | 1 | 0 | 1 |     imm26     |
> +	 *  +----+---+---+---+---+---+---------------+
> +	 *
> +	 * imm26 is a signed 26 bits integer. The real branch offset is computed
> +	 * by: imm64 = SignExtend(imm26:'00', 64);
> +	 *
> +	 * So the maximum forward branch should be:
> +	 *   (0x01ffffff << 2) = 0x07fffffc
> +	 * The maximum backward branch should be:
> +	 *   (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
> +	 *
> +	 * We can simply check (rel & 0xf8000003):
> +	 *  if rel is positive, (rel & 0xf8000003) should be 0
> +	 *  if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
> +	 *  the last '3' is used for alignment checking.
> +	 */
> +	return (offset >= -0x8000000 && offset <= 0x7fffffc && !(offset & 0x3));
> +}
> +
> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op,
> +				  struct kprobe *orig)
> +{
> +	kprobe_opcode_t *code, *buf;
> +	void **addrs;
> +	u32 insn;
> +	int ret, i;
> +
> +	addrs = kcalloc(TMPL_MAX_LENGTH, sizeof(void *), GFP_KERNEL);
> +	if (!addrs)
> +		return -ENOMEM;
> +
> +	buf = kcalloc(TMPL_MAX_LENGTH, sizeof(kprobe_opcode_t), GFP_KERNEL);
> +	if (!buf) {
> +		kfree(addrs);
> +		return -ENOMEM;
> +	}
> +
> +	code = get_optinsn_slot();
> +	if (!code) {
> +		kfree(addrs);
> +		kfree(buf);
> +		return -ENOMEM;
> +	}
> +
> +	if (!is_offset_in_range((unsigned long)code,
> +				(unsigned long)orig->addr + 8)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
> +				(unsigned long)optimized_callback)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
> +				(unsigned long)op->kp.addr + 4)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	memcpy(buf, optprobe_template_entry,
> +	       TMPL_END_IDX * sizeof(kprobe_opcode_t));
> +
> +	buf[TMPL_VAL_IDX] = FIELD_GET(GENMASK(31, 0), (unsigned long long)op);
> +	buf[TMPL_VAL_IDX + 1] =
> +		FIELD_GET(GENMASK(63, 32), (unsigned long long)op);
> +	buf[TMPL_RESTORE_ORIGN_INSN] = orig->opcode;
> +
> +	insn = aarch64_insn_gen_branch_imm(
> +		(unsigned long)(&code[TMPL_CALL_BACK]),
> +		(unsigned long)optimized_callback, AARCH64_INSN_BRANCH_LINK);
> +	buf[TMPL_CALL_BACK] = insn;
> +
> +	insn = aarch64_insn_gen_branch_imm(
> +		(unsigned long)(&code[TMPL_RESTORE_END]),
> +		(unsigned long)(op->kp.addr) + 4, AARCH64_INSN_BRANCH_NOLINK);
> +	buf[TMPL_RESTORE_END] = insn;
> +
> +	/* Setup template */
> +	for (i = 0; i < TMPL_MAX_LENGTH; i++)
> +		addrs[i] = code + i;
> +
> +	ret = aarch64_insn_patch_text(addrs, buf, TMPL_MAX_LENGTH);
> +	if (ret < 0)
> +		goto error;
> +
> +	flush_icache_range((unsigned long)code,
> +			   (unsigned long)(&code[TMPL_END_IDX]));
> +
> +	/* Set op->optinsn.insn means prepared. */
> +	op->optinsn.insn = code;
> +
> +out:
> +	kfree(addrs);
> +	kfree(buf);
> +	return ret;
> +
> +error:
> +	free_optinsn_slot(code, 0);
> +	goto out;
> +}
> +
> +void arch_optimize_kprobes(struct list_head *oplist)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +	kprobe_opcode_t *insns;
> +	void **addrs;
> +	int i = 0;
> +
> +	addrs = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(void *), GFP_KERNEL);
> +	if (!addrs)
> +		return;
> +
> +	insns = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(kprobe_opcode_t), GFP_KERNEL);
> +	if (!insns) {
> +		kfree(addrs);
> +		return;
> +	}
> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		WARN_ON(kprobe_disabled(&op->kp));
> +
> +		/*
> +		 * Backup instructions which will be replaced
> +		 * by jump address
> +		 */
> +		memcpy(op->optinsn.copied_insn, op->kp.addr,
> +			RELATIVEJUMP_SIZE);
> +
> +		addrs[i] = (void *)op->kp.addr;
> +		insns[i] = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
> +				(unsigned long)op->optinsn.insn,
> +				AARCH64_INSN_BRANCH_NOLINK);
> +
> +		list_del_init(&op->list);
> +		if (++i == OPTPROBE_BATCH_SIZE)
> +			break;
> +	}
> +
> +	aarch64_insn_patch_text(addrs, insns, i);
> +	kfree(addrs);
> +	kfree(insns);
> +}
> +
> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
> +{
> +	arch_arm_kprobe(&op->kp);
> +}
> +
> +/*
> + * Recover original instructions and breakpoints from relative jumps.
> + * Caller must call with locking kprobe_mutex.
> + */
> +void arch_unoptimize_kprobes(struct list_head *oplist,
> +			    struct list_head *done_list)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +	kprobe_opcode_t *insns;
> +	void **addrs;
> +	int i = 0;
> +
> +	addrs = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(void *), GFP_KERNEL);
> +	if (!addrs)
> +		return;
> +
> +	insns = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(kprobe_opcode_t), GFP_KERNEL);
> +	if (!insns) {
> +		kfree(addrs);
> +		return;
> +	}
> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		addrs[i] = (void *)op->kp.addr;
> +		insns[i] = BRK64_OPCODE_KPROBES;
> +		list_move(&op->list, done_list);
> +
> +		if (++i == OPTPROBE_BATCH_SIZE)
> +			break;
> +	}
> +
> +	aarch64_insn_patch_text(addrs, insns, i);
> +	kfree(addrs);
> +	kfree(insns);
> +}
> +
> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
> +{
> +	if (op->optinsn.insn) {
> +		free_optinsn_slot(op->optinsn.insn, 1);
> +		op->optinsn.insn = NULL;
> +	}
> +}
> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
> new file mode 100644
> index 000000000000..24d713d400cd
> --- /dev/null
> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * trampoline entry and return code for optprobes.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/assembler.h>
> +
> +	.global optprobe_template_entry
> +optprobe_template_entry:
> +	sub sp, sp, #PT_REGS_SIZE
> +	save_all_base_regs
> +	/* Get parameters to optimized_callback() */
> +	ldr	x0, 1f
> +	mov	x1, sp
> +	/* Branch to optimized_callback() */
> +	.global optprobe_template_call
> +optprobe_template_call:
> +	nop
> +	restore_all_base_regs
> +	ldr lr, [sp, #S_LR]
> +        add sp, sp, #PT_REGS_SIZE
> +	.global optprobe_template_restore_orig_insn
> +optprobe_template_restore_orig_insn:
> +	nop
> +	.global optprobe_template_restore_end
> +optprobe_template_restore_end:
> +	nop
> +	.global optprobe_template_end
> +optprobe_template_end:
> +	.global optprobe_template_val
> +optprobe_template_val:
> +	1:	.long 0
> +		.long 0
> +	.global optprobe_template_max_length
> +optprobe_template_max_length:
> -- 
> 2.17.1
> 


-- 
Masami Hiramatsu <mhiramat at kernel.org>


From robh at kernel.org  Wed Aug 18 09:44:58 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 11:44:58 -0500
Subject: [PATCH 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
 <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
Message-ID: <YR05Cj5R3cH+rTMx@robh.at.kernel.org>

On Tue, Aug 17, 2021 at 12:11:17PM +0200, Nicolas Frattaroli wrote:
> This adds the YAML bindings for the Rockchip I2S/TDM audio driver.
> 
> Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> ---
>  .../bindings/sound/rockchip,i2s-tdm.yaml      | 221 ++++++++++++++++++
>  include/dt-bindings/sound/rockchip,i2s-tdm.h  |   9 +
>  2 files changed, 230 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
>  create mode 100644 include/dt-bindings/sound/rockchip,i2s-tdm.h
> 
> diff --git a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> new file mode 100644
> index 000000000000..c3022620b47f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> @@ -0,0 +1,221 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip I2S/TDM Controller
> +
> +description:
> +  The Rockchip I2S/TDM Controller is a Time Division Multiplexed
> +  audio interface found in various Rockchip SoCs, allowing up
> +  to 8 channels of audio over a serial interface.
> +
> +maintainers:
> +  - Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - rockchip,px30-i2s-tdm
> +      - rockchip,rk1808-i2s-tdm
> +      - rockchip,rk3308-i2s-tdm
> +      - rockchip,rk3568-i2s-tdm
> +      - rockchip,rv1126-i2s-tdm
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  dmas:
> +    minItems: 1
> +    maxItems: 2
> +
> +  dma-names:
> +    oneOf:
> +      - const: rx
> +      - items:
> +          - const: tx
> +          - const: rx

If 'rx' is always present, then make it first:

minItems: 1
items:
  - const: rx
  - const: tx

> +
> +  clocks:
> +    items:
> +      - description: clock for TX
> +      - description: clock for RX
> +      - description: clock for I2S bus
> +
> +  clock-names:
> +    items:
> +      - const: mclk_tx
> +      - const: mclk_rx
> +      - const: hclk
> +
> +  rockchip,frame-width:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 64
> +    minimum: 32
> +    maximum: 512
> +    description:
> +      Width of a frame, usually slot width multiplied by number of slots.
> +      Must be even.
> +
> +  resets:
> +    items:
> +      - description: reset for TX
> +      - description: reset for RX
> +
> +  reset-names:
> +    items:
> +      - const: tx-m
> +      - const: rx-m
> +
> +  rockchip,cru:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the cru.
> +      Required if both playback and capture are used, i.e. if rockchip,clk-trcm
> +      is 0.
> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the GRF register.
> +
> +  rockchip,mclk-calibrate:
> +    description:
> +      Enable mclk source calibration.
> +    type: boolean
> +
> +  rockchip,trcm-sync:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Which lrck/bclk clocks each direction will sync to. You should use the
> +      constants in <dt-bindings/sound/rockchip,i2s-tdm.h>
> +    oneOf:
> +      - const: 0
> +        description:
> +          RK_TRCM_TXRX. Use both the TX and the RX clock for TX and RX.
> +      - const: 1
> +        description:
> +          RK_TRCM_TX. Use only the TX clock for TX and RX.
> +      - const: 2
> +        description:
> +          RK_TRCM_RX. Use only the RX clock for TX and RX.
> +
> +  "#sound-dai-cells":
> +    const: 0
> +
> +  rockchip,no-dmaengine:
> +    description:
> +      If present, driver will not register a pcm dmaengine, only the dai.
> +      If the dai is part of multi-dais, the property should be present.
> +    type: boolean
> +
> +  rockchip,playback-only:
> +    description: Specify that the controller only has playback capability.
> +    type: boolean
> +
> +  rockchip,capture-only:
> +    description: Specify that the controller only has capture capability.
> +    type: boolean
> +
> +  rockchip,i2s-rx-route:
> +    $ref: /schemas/types.yaml#/definitions/uint32

A single uint32 or

> +    description:
> +      Defines the mapping of I2S RX sdis to I2S data bus lines.
> +      By default, they are mapped one-to-one.
> +    items:
> +      - description: which sdi to connect to data line 0
> +      - description: which sdi to connect to data line 1
> +      - description: which sdi to connect to data line 2
> +      - description: which sdi to connect to data line 3

An array of 4 uint32s?

> +
> +  rockchip,i2s-tx-route:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the mapping of I2S TX sdos to I2S data bus lines.
> +      By default, they are mapped one-to-one.
> +    items:
> +      - description: which sdo to connect to data line 0
> +      - description: which sdo to connect to data line 1
> +      - description: which sdo to connect to data line 2
> +      - description: which sdo to connect to data line 3
> +
> +  rockchip,tdm-fsync-half-frame:
> +    description: Whether to use half frame fsync.
> +    type: boolean
> +
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - dmas
> +  - dma-names
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - rockchip,grf
> +  - "#sound-dai-cells"
> +  - rockchip,trcm-sync
> +
> +allOf:
> +  - if:
> +      properties:
> +        rockchip,clk-trcm:

This property doesn't exist.

> +          contains:
> +            enum: [0]
> +    then:
> +      required:
> +        - rockchip,cru
> +
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/rk3568-cru.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/pinctrl/rockchip.h>
> +    #include <dt-bindings/sound/rockchip,i2s-tdm.h>
> +
> +
> +    foo {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +        i2s at fe410000 {
> +            compatible = "rockchip,rk3568-i2s-tdm";
> +            reg = <0x0 0xfe410000 0x0 0x1000>;
> +            interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
> +            clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
> +                     <&cru HCLK_I2S1_8CH>;
> +            clock-names = "mclk_tx", "mclk_rx", "hclk";
> +            dmas = <&dmac1 2>, <&dmac1 3>;
> +            dma-names = "tx", "rx";
> +            resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
> +            reset-names = "tx-m", "rx-m";
> +            rockchip,trcm-sync = <RK_TRCM_TX>;
> +            rockchip,cru = <&cru>;
> +            rockchip,grf = <&grf>;
> +            #sound-dai-cells = <0>;
> +            pinctrl-names = "default";
> +            pinctrl-0 =
> +                <&i2s1m0_sclktx
> +                &i2s1m0_sclkrx
> +                &i2s1m0_lrcktx
> +                &i2s1m0_lrckrx
> +                &i2s1m0_sdi0
> +                &i2s1m0_sdi1
> +                &i2s1m0_sdi2
> +                &i2s1m0_sdi3
> +                &i2s1m0_sdo0
> +                &i2s1m0_sdo1
> +                &i2s1m0_sdo2
> +                &i2s1m0_sdo3>;
> +            status = "disabled";

Why is the example disabled?

> +        };
> +    };
> diff --git a/include/dt-bindings/sound/rockchip,i2s-tdm.h b/include/dt-bindings/sound/rockchip,i2s-tdm.h
> new file mode 100644
> index 000000000000..32494d64cf33
> --- /dev/null
> +++ b/include/dt-bindings/sound/rockchip,i2s-tdm.h
> @@ -0,0 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _DT_BINDINGS_ROCKCHIP_I2S_TDM_H
> +#define _DT_BINDINGS_ROCKCHIP_I2S_TDM_H
> +
> +#define RK_TRCM_TXRX 0
> +#define RK_TRCM_TX 1
> +#define RK_TRCM_RX 2
> +
> +#endif /* _DT_BINDINGS_ROCKCHIP_I2S_TDM_H */
> -- 
> 2.32.0
> 
> 


From maz at kernel.org  Wed Aug 18 09:45:50 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 17:45:50 +0100
Subject: [PATCH v4 11/15] KVM: arm64: Guest exit handlers for nVHE hyp
In-Reply-To: <20210817081134.2918285-12-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-12-tabba@google.com>
Message-ID: <87fsv6snup.wl-maz@kernel.org>

On Tue, 17 Aug 2021 09:11:30 +0100,
Fuad Tabba <tabba at google.com> wrote:
> 
> Add an array of pointers to handlers for various trap reasons in
> nVHE code.
> 
> The current code selects how to fixup a guest on exit based on a
> series of if/else statements. Future patches will also require
> different handling for guest exists. Create an array of handlers
> to consolidate them.
> 
> No functional change intended as the array isn't populated yet.
> 
> Acked-by: Will Deacon <will at kernel.org>
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/kvm/hyp/include/hyp/switch.h | 43 +++++++++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/switch.c        | 33 +++++++++++++++++++
>  2 files changed, 76 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index a0e78a6027be..5a2b89b96c67 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -409,6 +409,46 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
>  	return true;
>  }
>  
> +typedef int (*exit_handle_fn)(struct kvm_vcpu *);

This returns an int...

> +
> +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu);
> +
> +static exit_handle_fn kvm_get_hyp_exit_handler(struct kvm_vcpu *vcpu)
> +{
> +	return is_nvhe_hyp_code() ? kvm_get_nvhe_exit_handler(vcpu) : NULL;
> +}
> +
> +/*
> + * Allow the hypervisor to handle the exit with an exit handler if it has one.
> + *
> + * Returns true if the hypervisor handled the exit, and control should go back
> + * to the guest, or false if it hasn't.
> + */
> +static bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu)
> +{
> +	bool is_handled = false;

... which you then implicitly cast as a bool.

> +	exit_handle_fn exit_handler = kvm_get_hyp_exit_handler(vcpu);
> +
> +	if (exit_handler) {
> +		/*
> +		 * There's limited vcpu context here since it's not synced yet.
> +		 * Ensure that relevant vcpu context that might be used by the
> +		 * exit_handler is in sync before it's called and if handled.
> +		 */
> +		*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
> +		*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
> +
> +		is_handled = exit_handler(vcpu);

What does 'is_handled' mean here? By definition, any trap *must* be
handled, one way or another. By the look of it, what you really mean
is something like "I have updated the vcpu state and you'd better
reload it". Is that what it means?

> +
> +		if (is_handled) {
> +			write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
> +			write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
> +		}
> +	}
> +
> +	return is_handled;
> +}

All these functions really should be marked inline. Have you checked
how this expands on VHE? I think some compilers could be pretty
unhappy about the undefined symbol in kvm_get_hyp_exit_handler().

It is also unfortunate that we get a bunch of tests for various
flavours of traps (FP, PAuth, page faults...), only to hit yet another
decoding tree. Is there a way we could use this infrastructure for
everything?

> +
>  /*
>   * Return true when we were able to fixup the guest exit and should return to
>   * the guest, false when we should restore the host state and return to the
> @@ -496,6 +536,9 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  			goto guest;
>  	}
>  
> +	/* Check if there's an exit handler and allow it to handle the exit. */
> +	if (kvm_hyp_handle_exit(vcpu))
> +		goto guest;
>  exit:
>  	/* Return to the host kernel and handle the exit */
>  	return false;
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index 86f3d6482935..b7f25307a7b9 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -158,6 +158,39 @@ static void __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt)
>  		write_sysreg(pmu->events_host, pmcntenset_el0);
>  }
>  
> +static exit_handle_fn hyp_exit_handlers[] = {
> +	[0 ... ESR_ELx_EC_MAX]		= NULL,
> +	[ESR_ELx_EC_WFx]		= NULL,
> +	[ESR_ELx_EC_CP15_32]		= NULL,
> +	[ESR_ELx_EC_CP15_64]		= NULL,
> +	[ESR_ELx_EC_CP14_MR]		= NULL,
> +	[ESR_ELx_EC_CP14_LS]		= NULL,
> +	[ESR_ELx_EC_CP14_64]		= NULL,
> +	[ESR_ELx_EC_HVC32]		= NULL,
> +	[ESR_ELx_EC_SMC32]		= NULL,
> +	[ESR_ELx_EC_HVC64]		= NULL,
> +	[ESR_ELx_EC_SMC64]		= NULL,
> +	[ESR_ELx_EC_SYS64]		= NULL,
> +	[ESR_ELx_EC_SVE]		= NULL,
> +	[ESR_ELx_EC_IABT_LOW]		= NULL,
> +	[ESR_ELx_EC_DABT_LOW]		= NULL,
> +	[ESR_ELx_EC_SOFTSTP_LOW]	= NULL,
> +	[ESR_ELx_EC_WATCHPT_LOW]	= NULL,
> +	[ESR_ELx_EC_BREAKPT_LOW]	= NULL,
> +	[ESR_ELx_EC_BKPT32]		= NULL,
> +	[ESR_ELx_EC_BRK64]		= NULL,
> +	[ESR_ELx_EC_FP_ASIMD]		= NULL,
> +	[ESR_ELx_EC_PAC]		= NULL,

You can safely drop all these and only keep the top one for now. This
will also keep the idiot robot at bay for until the next patch... ;-)

> +};
> +
> +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
> +{
> +	u32 esr = kvm_vcpu_get_esr(vcpu);
> +	u8 esr_ec = ESR_ELx_EC(esr);
> +
> +	return hyp_exit_handlers[esr_ec];
> +}
> +
>  /* Switch to the guest for legacy non-VHE systems */
>  int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>  {

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Wed Aug 18 09:58:21 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 17:58:21 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87k0kk7w0c.mognet@arm.com>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
 <87eeav19mc.wl-maz@kernel.org> <87k0kk7w0c.mognet@arm.com>
Message-ID: <87czqasn9u.wl-maz@kernel.org>

On Tue, 17 Aug 2021 01:30:43 +0100,
Valentin Schneider <valentin.schneider at arm.com> wrote:
> 
> On 15/08/21 07:54, Marc Zyngier wrote:
> > This is going and-up in a wack-a-mole game. There is probably a bunch
> > of these all over the place. I'd rather squash it at the root,
> > i.e. with something like this (untested):
> >
> > diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> > index 099bc7e13d1b..601ad3fc47cd 100644
> > --- a/kernel/irq/chip.c
> > +++ b/kernel/irq/chip.c
> > @@ -410,7 +410,12 @@ void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
> >
> >  void ack_irq(struct irq_desc *desc)
> >  {
> > -	desc->irq_data.chip->irq_ack(&desc->irq_data);
> > +	struct irq_data *data = &desc->irq_data;
> > +
> > +	while (!data->chip->irq_ack)
> > +		data = data->parent_data;
> > +
> > +	data->chip->irq_ack(&desc->irq_data);
> >
> >       if (desc->irq_data.chip->flags & IRQCHIP_AUTOMASKS_FLOW)
> >               irq_state_set_flow_masked(desc);
> >
> > We probably need something similar for irq_eoi().
> >
> > This however shows a more fundamental problem, I'm afraid. We set
> > IRQCHIP_AUTOMASKS_FLOW in the GIC drivers (i.e. at the root), but test
> > for it at the top of the hierarchy. As soon as we have more than a
> > single layer of irqchip, this will do the wrong thing (or at least
> > miss the masking optimisation).
> >
> 
> Yup.
> 
> > This probably advocates for moving the flag into the descriptor. This
> > really makes sense, as the flow is global to the whole stack, not just
> > to the localised irqchip.
> >
> 
> Are we guaranteed to have
> 
>   .irq_ack \in {NULL, irq_chip_ack_parent}
> 
> for all intermediate (!root) irqchips? I don't see why that wouldn't
> be the case, and with that in mind what you described makes sense to
> me.

An intermediate layer is allowed to implement its own irq_ack that is
not irq_chip_ack_parent, but it then has to call irq_chip_ack_parent
itself.

There is the bizarre case of drivers/gpio/gpio-thunderx.c that changes
the irqchip flow to use either handle_fasteoi_ack_irq or
handle_fasteoi_mask_irq, which won't play very nicely with this.
Someone said Cavium?

> 
> > In order to restore -next into a working state, I'm temporarily
> > dropping this series. Hopefully, we can sort this out before the merge
> > window and reinstate it.
> >
> 
> I'm away from any keyboard for most of this week, but I'll get to it by the
> weekend.

No worries, enjoy your break!

	M.

-- 
Without deviation from the norm, progress is not possible.


From robh at kernel.org  Wed Aug 18 10:51:58 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 12:51:58 -0500
Subject: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: add a new compatible
 string
In-Reply-To: <1629278277-7313-1-git-send-email-haibo.chen@nxp.com>
References: <1629278277-7313-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <YR1IvutH4RNxiivs@robh.at.kernel.org>

On Wed, 18 Aug 2021 17:17:57 +0800, haibo.chen at nxp.com wrote:
> From: Haibo Chen <haibo.chen at nxp.com>
> 
> Lack a compatible string "fsl,imx6sll-usdhc", so add it here.
> 
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> ---
>  Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From maz at kernel.org  Wed Aug 18 11:14:32 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 19:14:32 +0100
Subject: [PATCH] KVM: arm64: vgic: Resample HW pending state on deactivation
Message-ID: <20210818181432.432256-1-maz@kernel.org>

When a mapped level interrupt (a timer, for example) is deactivated
by the guest, the corresponding host interrupt is equally deactivated.
However, the fate of the pending state still needs to be dealt
with in SW.

This is specially true when the interrupt was in the active+pending
state in the virtual distributor at the point where the guest
was entered. On exit, the pending state is potentially stale
(the guest may have put the interrupt in a non-pending state).

If we don't do anything, the interrupt will be spuriously injected
in the guest. Although this shouldn't have any ill effect (spurious
interrupts are always possible), we can improve the emulation by
detecting the deactivation-while-pending case and resample the
interrupt.

Fixes: e40cc57bac79 ("KVM: arm/arm64: vgic: Support level-triggered mapped interrupts")
Reported-by: Raghavendra Rao Ananta <rananta at google.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org
---
 arch/arm64/kvm/vgic/vgic-v2.c | 25 ++++++++++++++++++-------
 arch/arm64/kvm/vgic/vgic-v3.c | 25 ++++++++++++++++++-------
 2 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
index 2c580204f1dc..3e52ea86a87f 100644
--- a/arch/arm64/kvm/vgic/vgic-v2.c
+++ b/arch/arm64/kvm/vgic/vgic-v2.c
@@ -60,6 +60,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 		u32 val = cpuif->vgic_lr[lr];
 		u32 cpuid, intid = val & GICH_LR_VIRTUALID;
 		struct vgic_irq *irq;
+		bool deactivated;
 
 		/* Extract the source vCPU id from the LR */
 		cpuid = val & GICH_LR_PHYSID_CPUID;
@@ -75,7 +76,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 
 		raw_spin_lock(&irq->irq_lock);
 
-		/* Always preserve the active bit */
+		/* Always preserve the active bit, note deactivation */
+		deactivated = irq->active && !(val & GICH_LR_ACTIVE_BIT);
 		irq->active = !!(val & GICH_LR_ACTIVE_BIT);
 
 		if (irq->active && vgic_irq_is_sgi(intid))
@@ -105,6 +107,12 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 		 * device state could have changed or we simply need to
 		 * process the still pending interrupt later.
 		 *
+		 * We could also have entered the guest with the interrupt
+		 * active+pending. On the next exit, we need to re-evaluate
+		 * the pending state, as it could otherwise result in a
+		 * spurious interrupt by injecting a now potentially stale
+		 * pending state.
+		 *
 		 * If this causes us to lower the level, we have to also clear
 		 * the physical active state, since we will otherwise never be
 		 * told when the interrupt becomes asserted again.
@@ -115,12 +123,15 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 		if (vgic_irq_is_mapped_level(irq)) {
 			bool resample = false;
 
-			if (val & GICH_LR_PENDING_BIT) {
-				irq->line_level = vgic_get_phys_line_level(irq);
-				resample = !irq->line_level;
-			} else if (vgic_irq_needs_resampling(irq) &&
-				   !(irq->active || irq->pending_latch)) {
-				resample = true;
+			if (unlikely(vgic_irq_needs_resampling(irq))) {
+				if (!(irq->active || irq->pending_latch))
+					resample = true;
+			} else {
+				if ((val & GICH_LR_PENDING_BIT) ||
+				    (deactivated && irq->line_level)) {
+					irq->line_level = vgic_get_phys_line_level(irq);
+					resample = !irq->line_level;
+				}
 			}
 
 			if (resample)
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 66004f61cd83..74f9aefffd5e 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -46,6 +46,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 		u32 intid, cpuid;
 		struct vgic_irq *irq;
 		bool is_v2_sgi = false;
+		bool deactivated;
 
 		cpuid = val & GICH_LR_PHYSID_CPUID;
 		cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT;
@@ -68,7 +69,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 
 		raw_spin_lock(&irq->irq_lock);
 
-		/* Always preserve the active bit */
+		/* Always preserve the active bit, note deactivation */
+		deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT);
 		irq->active = !!(val & ICH_LR_ACTIVE_BIT);
 
 		if (irq->active && is_v2_sgi)
@@ -98,6 +100,12 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 		 * device state could have changed or we simply need to
 		 * process the still pending interrupt later.
 		 *
+		 * We could also have entered the guest with the interrupt
+		 * active+pending. On the next exit, we need to re-evaluate
+		 * the pending state, as it could otherwise result in a
+		 * spurious interrupt by injecting a now potentially stale
+		 * pending state.
+		 *
 		 * If this causes us to lower the level, we have to also clear
 		 * the physical active state, since we will otherwise never be
 		 * told when the interrupt becomes asserted again.
@@ -108,12 +116,15 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 		if (vgic_irq_is_mapped_level(irq)) {
 			bool resample = false;
 
-			if (val & ICH_LR_PENDING_BIT) {
-				irq->line_level = vgic_get_phys_line_level(irq);
-				resample = !irq->line_level;
-			} else if (vgic_irq_needs_resampling(irq) &&
-				   !(irq->active || irq->pending_latch)) {
-				resample = true;
+			if (unlikely(vgic_irq_needs_resampling(irq))) {
+				if (!(irq->active || irq->pending_latch))
+					resample = true;
+			} else {
+				if ((val & ICH_LR_PENDING_BIT) ||
+				    (deactivated && irq->line_level)) {
+					irq->line_level = vgic_get_phys_line_level(irq);
+					resample = !irq->line_level;
+				}
 			}
 
 			if (resample)
-- 
2.30.2



From sam at ravnborg.org  Wed Aug 18 11:21:28 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Wed, 18 Aug 2021 20:21:28 +0200
Subject: [PATCH 1/3] drm/panel-simple: Add Vivax TPC-9150 panel v4
In-Reply-To: <20210818144648.72665-1-pavlica.nikola@gmail.com>
References: <20210818144648.72665-1-pavlica.nikola@gmail.com>
Message-ID: <YR1PqL9rnAjGT3rf@ravnborg.org>

Hi Nikola,

On Wed, Aug 18, 2021 at 04:46:46PM +0200, Nikola Pavlica wrote:
> The model and make of the LCD panel of the Vivax TPC-9150 is unknown,
> hence the panel settings that were retrieved with a FEX dump are named
> after the device NOT the actual panel.
> 
> The LCD in question is a 50 pin MISO TFT LCD panel of the resolution
> 1024x600 used by the aforementioned device.
> 
> Version 2, as Thierry kindly suggested that I fix the order in which the
> panel was ordered compared to others.
> 
> Version 3, filling in the required info suggested by Sam. Plus some
> factual issues that I've corrected myself (tested working)
> 
> Version 4, rearranged the display parameters and fix invalid bit format
> issue. (Thanks Sam)
> 
> Thanks,
> Nikola
> 
> Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
> ---
>  drivers/gpu/drm/panel/panel-simple.c | 29 ++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index 4e2dad314c79..9e06c375f8a0 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -3989,6 +3989,32 @@ static const struct panel_desc urt_umsh_8596md_parallel = {
>  	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
>  };
> 
> +static const struct drm_display_mode vivax_tpc9150_panel_mode = {
> +	.clock = 60000,
> +	.hdisplay = 1024,
> +	.hsync_start = 1024 + 160,
> +	.hsync_end = 1024 + 160 + 100,
> +	.htotal = 1024 + 160 + 100 + 60,
> +	.vdisplay = 600,
> +	.vsync_start = 600 + 12,
> +	.vsync_end = 600 + 12 + 10,
> +	.vtotal = 600 + 12 + 10 + 13,
> +};
> +
> +static const struct panel_desc vivax_tpc9150_panel = {
> +	.modes = &vivax_tpc9150_panel_mode,
> +	.num_modes = 1,
> +	.bpc = 6,
> +	.size = {
> +		.width = 200,
> +		.height = 115,
> +	},
> +	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
> +	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
> +	.connector_type = DRM_MODE_CONNECTOR_LVDS,

The bus_format is not right. If you look at your logging this panel
will result in a warning.

Look at the following code:
       case DRM_MODE_CONNECTOR_LVDS:
                WARN_ON(desc->bus_flags &
                        ~(DRM_BUS_FLAG_DE_LOW |
                          DRM_BUS_FLAG_DE_HIGH |
                          DRM_BUS_FLAG_DATA_MSB_TO_LSB |
                          DRM_BUS_FLAG_DATA_LSB_TO_MSB));
                WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG &&
                        desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG &&
                        desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA);
                WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG &&
                        desc->bpc != 6);
                WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG ||
                         desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) &&
                        desc->bpc != 8);
                break;

Here you see that for an LVDS connector we expect at least one bus_flag
- this is OK.
You can also see that for bus_format only a selected few are valid.
You need to investigate and pick the right one here.

One way to find out is to check the driver default as this is likely
selected when you specify an invalid bus_format like in the patch.

If you look for example in Documentation/devicetree/bindings/display/panel/lvds.yaml
then you can see a graphical representation of the formats. This should
help you pick the right one.

	Sam


From sam at ravnborg.org  Wed Aug 18 11:22:43 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Wed, 18 Aug 2021 20:22:43 +0200
Subject: [PATCH 3/3] dt-bindings: add vendor prefix for Vivax
In-Reply-To: <20210818144648.72665-3-pavlica.nikola@gmail.com>
References: <20210818144648.72665-1-pavlica.nikola@gmail.com>
 <20210818144648.72665-3-pavlica.nikola@gmail.com>
Message-ID: <YR1P86H+s3BuLebl@ravnborg.org>

On Wed, Aug 18, 2021 at 04:46:48PM +0200, Nikola Pavlica wrote:
> Add vendor prefix for the Vivax brand by M SAN Grupa d.o.o.
> 
> Source (in Croatian): https://www.vivax.com/hr/o-nama.aspx
> 
> Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
Reviewed-by: Sam Ravnborg <sam at ravnborg.org>

I like this as the first in the series, as we cannot apply the patch to
the panel-simple binding before the vendor prefix is present.

	Sam

> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index f6064d84a424..c234c392538d 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -1206,6 +1206,8 @@ patternProperties:
>      description: Vitesse Semiconductor Corporation
>    "^vivante,.*":
>      description: Vivante Corporation
> +  "^vivax,.*":
> +    description: Vivax brand by M SAN Grupa d.o.o.
>    "^vocore,.*":
>      description: VoCore Studio
>    "^voipac,.*":
> -- 
> 2.32.0


From maz at kernel.org  Wed Aug 18 11:24:20 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 19:24:20 +0100
Subject: [PATCH v4 2/6] dt-bindings: arm: optee: add interrupt property
In-Reply-To: <20210818101849.602257-3-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
 <20210818101849.602257-3-jens.wiklander@linaro.org>
Message-ID: <87a6lesjaj.wl-maz@kernel.org>

On Wed, 18 Aug 2021 11:18:45 +0100,
Jens Wiklander <jens.wiklander at linaro.org> wrote:
> 
> Adds an optional interrupt property to the optee binding.
> 
> Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> ---
>  .../devicetree/bindings/arm/firmware/linaro,optee-tz.yaml  | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
> index c24047c1fdd5..40c9f1901e3f 100644
> --- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
> +++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
> @@ -24,6 +24,12 @@ properties:
>    compatible:
>      const: linaro,optee-tz
>  
> +  interrupts:
> +    maxItems: 1
> +    description: |
> +      This interrupt which is used to signal an event by the secure world
> +      software is expected to be edge-triggered.
> +
>    method:
>      enum: [smc, hvc]
>      description: |
> @@ -46,6 +52,7 @@ examples:
>          optee  {
>              compatible = "linaro,optee-tz";
>              method = "smc";
> +            interrupts = <0 187 1>;
>          };
>      };
>  

Acked-by: Marc Zyngier <maz at kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


From sam at ravnborg.org  Wed Aug 18 11:24:52 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Wed, 18 Aug 2021 20:24:52 +0200
Subject: [PATCH 2/3] dt-bindings: display: simple: Add Vivax TPC-9150 panel
In-Reply-To: <20210818144648.72665-2-pavlica.nikola@gmail.com>
References: <20210818144648.72665-1-pavlica.nikola@gmail.com>
 <20210818144648.72665-2-pavlica.nikola@gmail.com>
Message-ID: <YR1QdDgB0H+8J318@ravnborg.org>

Hi Nikola,

On Wed, Aug 18, 2021 at 04:46:47PM +0200, Nikola Pavlica wrote:
> This tablet display is unique and hence must be added to documentation.
> Unfortunately, it's real make and number is not known due to obscure and
> missing documentation and lack of writing on the display assembly
> itself.
> 
> So the natural alternative that came to mind is to name the panel after
> the device that contained it (an Android tablet). Hopefully that isn't
> an issue.
> 
> I can confirm that the parameters that I've obtained are correct since
> they came from a dump of the original Android OS.
> 
> Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>
Reviewed-by: Sam Ravnborg <sam at ravnborg.org>

I like this to be *before* the patch to panel-simple.c, as we cannot
apply the panel-simple.c patch before the compatible is documented.

Or we can apply it, but checkpatch will complain and that will stop me
applying.

So in other words - reverse the order of the patches.

	Sam

> ---
>  .../devicetree/bindings/display/panel/panel-simple.yaml         | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> index 62b0d54d87b7..d0efefa5a820 100644
> --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
> @@ -285,6 +285,8 @@ properties:
>        - urt,umsh-8596md-11t
>        - urt,umsh-8596md-19t
>        - urt,umsh-8596md-20t
> +        # Vivax TPC-9150 tablet 9.0" WSVGA TFT LCD panel
> +      - vivax,tpc9150-panel
>          # VXT 800x480 color TFT LCD panel
>        - vxt,vl050-8048nt-c01
>          # Winstar Display Corporation 3.5" QVGA (320x240) TFT LCD panel
> -- 
> 2.32.0


From sam at ravnborg.org  Wed Aug 18 11:26:37 2021
From: sam at ravnborg.org (Sam Ravnborg)
Date: Wed, 18 Aug 2021 20:26:37 +0200
Subject: [PATCH 3/3] dt-bindings: add vendor prefix for Vivax
In-Reply-To: <20210818144648.72665-3-pavlica.nikola@gmail.com>
References: <20210818144648.72665-1-pavlica.nikola@gmail.com>
 <20210818144648.72665-3-pavlica.nikola@gmail.com>
Message-ID: <YR1Q3ZkrUgG+MHZR@ravnborg.org>

Hi Nikola,

On Wed, Aug 18, 2021 at 04:46:48PM +0200, Nikola Pavlica wrote:
> Add vendor prefix for the Vivax brand by M SAN Grupa d.o.o.
> 
> Source (in Croatian): https://www.vivax.com/hr/o-nama.aspx
> 
> Signed-off-by: Nikola Pavlica <pavlica.nikola at gmail.com>

One other note, bindings patches should also be copied to the devicetree
mailing list. See the submitting-patches instructions.

	Sam

> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index f6064d84a424..c234c392538d 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -1206,6 +1206,8 @@ patternProperties:
>      description: Vitesse Semiconductor Corporation
>    "^vivante,.*":
>      description: Vivante Corporation
> +  "^vivax,.*":
> +    description: Vivax brand by M SAN Grupa d.o.o.
>    "^vocore,.*":
>      description: VoCore Studio
>    "^voipac,.*":
> -- 
> 2.32.0


From maz at kernel.org  Wed Aug 18 11:27:58 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 19:27:58 +0100
Subject: [PATCH v4 1/6] docs: staging/tee.rst: add a section on OP-TEE
 notifications
In-Reply-To: <20210818101849.602257-2-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
 <20210818101849.602257-2-jens.wiklander@linaro.org>
Message-ID: <878s0ysj4h.wl-maz@kernel.org>

On Wed, 18 Aug 2021 11:18:44 +0100,
Jens Wiklander <jens.wiklander at linaro.org> wrote:
> 
> Adds a section on notifications used by OP-TEE, synchronous and
> asynchronous.
> 
> Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> ---
>  Documentation/staging/tee.rst | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/Documentation/staging/tee.rst b/Documentation/staging/tee.rst
> index 4d4b5f889603..951f07dd026b 100644
> --- a/Documentation/staging/tee.rst
> +++ b/Documentation/staging/tee.rst
> @@ -184,6 +184,35 @@ order to support device enumeration. In other words, OP-TEE driver invokes this
>  application to retrieve a list of Trusted Applications which can be registered
>  as devices on the TEE bus.
>  
> +OP-TEE notifications
> +--------------------
> +
> +There are two kinds of notifications that secure world can use to make
> +normal world aware of some event.
> +
> +1. Synchronous notifications delivered with ``OPTEE_RPC_CMD_NOTIFICATION``
> +   using the ``OPTEE_RPC_NOTIFICATION_SEND`` parameter.
> +2. Asynchronous notifications delivered with a combination of a non-secure
> +   edge-triggered interrupt and a fast call from the non-secure interrupt
> +   handler.
> +
> +Synchronous notifications are limited by depending on RPC for delivery,
> +this is only usable when secure world is entered with a yielding call via
> +``OPTEE_SMC_CALL_WITH_ARG``. This excludes such notifications from secure
> +world interrupt handlers.
> +
> +An asynchronous notification is delivered via a non-secure edge-triggered
> +interrupt to an interrupt handler registered in the OP-TEE driver. The
> +actual notification value are retrieved with the fast call
> +``OPTEE_SMC_GET_ASYNC_NOTIF_VALUE``.

One thing you may want to describe whether a single interrupt can
represent multiple notification (multiple edge interrupts will happily
be coalesced into a single one if not acknowledged before the next
notification).

Otherwise,

Acked-by: Marc Zyngier <maz at kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


From robh at kernel.org  Wed Aug 18 11:33:26 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 13:33:26 -0500
Subject: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: change the
 pinctrl-names rule
In-Reply-To: <1629279984-7397-1-git-send-email-haibo.chen@nxp.com>
References: <1629279984-7397-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <YR1SdhfM344Ii7BQ@robh.at.kernel.org>

On Wed, Aug 18, 2021 at 05:46:24PM +0800, haibo.chen at nxp.com wrote:
> From: Haibo Chen <haibo.chen at nxp.com>
> 
> Change the pinctrl-names rule to cover all cases.
> 
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> ---
>  .../bindings/mmc/fsl-imx-esdhc.yaml           | 21 +++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> index 17086f60f8a3..d324606a4f0a 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> @@ -116,12 +116,21 @@ properties:
>        - const: per
>  
>    pinctrl-names:
> -    minItems: 1
> -    items:
> -      - const: default
> -      - const: state_100mhz
> -      - const: state_200mhz
> -      - const: sleep
> +    oneOf:
> +      - items:
> +          - const: default
> +          - const: state_100mhz
> +          - const: state_200mhz
> +          - const: sleep
> +      - items:
> +          - const: default
> +          - const: state_100mhz
> +          - const: state_200mhz

You can drop this one and add 'minItems: 3' to the first case.

> +      - items:
> +          - const: default
> +          - const: sleep
> +      - items:
> +          - const: default

Similar here too with the prior case. Or use 'minItems: 1' in the first 
case. That additional allows the 2 entry case, but why isn't that valid? 
Couldn't a board only support default+state_100mhz?

Rob


From robh at kernel.org  Wed Aug 18 11:34:08 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 13:34:08 -0500
Subject: [PATCH v4 2/6] dt-bindings: arm: optee: add interrupt property
In-Reply-To: <20210818101849.602257-3-jens.wiklander@linaro.org>
References: <20210818101849.602257-1-jens.wiklander@linaro.org>
 <20210818101849.602257-3-jens.wiklander@linaro.org>
Message-ID: <YR1SoO/GRao00Ugg@robh.at.kernel.org>

On Wed, 18 Aug 2021 12:18:45 +0200, Jens Wiklander wrote:
> Adds an optional interrupt property to the optee binding.
> 
> Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> ---
>  .../devicetree/bindings/arm/firmware/linaro,optee-tz.yaml  | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Wed Aug 18 11:48:52 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 13:48:52 -0500
Subject: [PATCH v2 3/6] dt-bindings: mmc: fsl-imx-esdhc: add
 fsl,broken-auto-tuning binding
In-Reply-To: <1629285415-7495-3-git-send-email-haibo.chen@nxp.com>
References: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
 <1629285415-7495-3-git-send-email-haibo.chen@nxp.com>
Message-ID: <YR1WFGUGS3pERnOD@robh.at.kernel.org>

On Wed, Aug 18, 2021 at 07:16:52PM +0800, haibo.chen at nxp.com wrote:
> From: Haibo Chen <haibo.chen at nxp.com>
> 
> Add a new fsl,broken-auto-tuning binding for sdio devices. When sdio
> device support sdio interrupt, need to use this property to disable
> auto-tuning. Auto-tuning circuit is conflict with sdio interrupt.
> 
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> ---
>  Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> index b5baf439fbac..d7c8e5880473 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> @@ -93,6 +93,15 @@ properties:
>        tuning step can't find the proper delay window within limited tuning retries.
>      default: 0
>  
> +  fsl,broken-auto-tuning:
> +    description: |
> +      Recommend for SDIO cards that enables SDIO interrupt for SDR104 and SDR50 mode.
> +      SDIO interrupt uses DAT[1] to signal the card's interrupt. Auto-tuning circuit
> +      will detect this interrupt on DAT[1] when in 4Bit bus mode, and take it just
> +      as normal data, wrongly adjust the delay cell. This property is used to disable
> +      the auto-tuning function.
> +    type: boolean

Seems like something that could be broken on a variety of hosts and 
should be common?

If auto tuning is broken, shouldn't that speed be disabled?

Rob


From rananta at google.com  Wed Aug 18 12:05:32 2021
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Wed, 18 Aug 2021 12:05:32 -0700
Subject: [PATCH] KVM: arm64: vgic: Resample HW pending state on
 deactivation
In-Reply-To: <20210818181432.432256-1-maz@kernel.org>
References: <20210818181432.432256-1-maz@kernel.org>
Message-ID: <CAJHc60zUZS3K4q88QYwP2CkGn7ywt-_fedjk7OK_W7cdQRJvxA@mail.gmail.com>

On Wed, Aug 18, 2021 at 11:14 AM Marc Zyngier <maz at kernel.org> wrote:
>
> When a mapped level interrupt (a timer, for example) is deactivated
> by the guest, the corresponding host interrupt is equally deactivated.
> However, the fate of the pending state still needs to be dealt
> with in SW.
>
> This is specially true when the interrupt was in the active+pending
> state in the virtual distributor at the point where the guest
> was entered. On exit, the pending state is potentially stale
> (the guest may have put the interrupt in a non-pending state).
>
> If we don't do anything, the interrupt will be spuriously injected
> in the guest. Although this shouldn't have any ill effect (spurious
> interrupts are always possible), we can improve the emulation by
> detecting the deactivation-while-pending case and resample the
> interrupt.
>
> Fixes: e40cc57bac79 ("KVM: arm/arm64: vgic: Support level-triggered mapped interrupts")
> Reported-by: Raghavendra Rao Ananta <rananta at google.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Cc: stable at vger.kernel.org
> ---
>  arch/arm64/kvm/vgic/vgic-v2.c | 25 ++++++++++++++++++-------
>  arch/arm64/kvm/vgic/vgic-v3.c | 25 ++++++++++++++++++-------
>  2 files changed, 36 insertions(+), 14 deletions(-)
>
Tested-by: Raghavendra Rao Ananta <rananta at google.com>

Thanks,
Raghavendra
> diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
> index 2c580204f1dc..3e52ea86a87f 100644
> --- a/arch/arm64/kvm/vgic/vgic-v2.c
> +++ b/arch/arm64/kvm/vgic/vgic-v2.c
> @@ -60,6 +60,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
>                 u32 val = cpuif->vgic_lr[lr];
>                 u32 cpuid, intid = val & GICH_LR_VIRTUALID;
>                 struct vgic_irq *irq;
> +               bool deactivated;
>
>                 /* Extract the source vCPU id from the LR */
>                 cpuid = val & GICH_LR_PHYSID_CPUID;
> @@ -75,7 +76,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
>
>                 raw_spin_lock(&irq->irq_lock);
>
> -               /* Always preserve the active bit */
> +               /* Always preserve the active bit, note deactivation */
> +               deactivated = irq->active && !(val & GICH_LR_ACTIVE_BIT);
>                 irq->active = !!(val & GICH_LR_ACTIVE_BIT);
>
>                 if (irq->active && vgic_irq_is_sgi(intid))
> @@ -105,6 +107,12 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
>                  * device state could have changed or we simply need to
>                  * process the still pending interrupt later.
>                  *
> +                * We could also have entered the guest with the interrupt
> +                * active+pending. On the next exit, we need to re-evaluate
> +                * the pending state, as it could otherwise result in a
> +                * spurious interrupt by injecting a now potentially stale
> +                * pending state.
> +                *
>                  * If this causes us to lower the level, we have to also clear
>                  * the physical active state, since we will otherwise never be
>                  * told when the interrupt becomes asserted again.
> @@ -115,12 +123,15 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
>                 if (vgic_irq_is_mapped_level(irq)) {
>                         bool resample = false;
>
> -                       if (val & GICH_LR_PENDING_BIT) {
> -                               irq->line_level = vgic_get_phys_line_level(irq);
> -                               resample = !irq->line_level;
> -                       } else if (vgic_irq_needs_resampling(irq) &&
> -                                  !(irq->active || irq->pending_latch)) {
> -                               resample = true;
> +                       if (unlikely(vgic_irq_needs_resampling(irq))) {
> +                               if (!(irq->active || irq->pending_latch))
> +                                       resample = true;
> +                       } else {
> +                               if ((val & GICH_LR_PENDING_BIT) ||
> +                                   (deactivated && irq->line_level)) {
> +                                       irq->line_level = vgic_get_phys_line_level(irq);
> +                                       resample = !irq->line_level;
> +                               }
>                         }
>
>                         if (resample)
> diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
> index 66004f61cd83..74f9aefffd5e 100644
> --- a/arch/arm64/kvm/vgic/vgic-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-v3.c
> @@ -46,6 +46,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
>                 u32 intid, cpuid;
>                 struct vgic_irq *irq;
>                 bool is_v2_sgi = false;
> +               bool deactivated;
>
>                 cpuid = val & GICH_LR_PHYSID_CPUID;
>                 cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT;
> @@ -68,7 +69,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
>
>                 raw_spin_lock(&irq->irq_lock);
>
> -               /* Always preserve the active bit */
> +               /* Always preserve the active bit, note deactivation */
> +               deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT);
>                 irq->active = !!(val & ICH_LR_ACTIVE_BIT);
>
>                 if (irq->active && is_v2_sgi)
> @@ -98,6 +100,12 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
>                  * device state could have changed or we simply need to
>                  * process the still pending interrupt later.
>                  *
> +                * We could also have entered the guest with the interrupt
> +                * active+pending. On the next exit, we need to re-evaluate
> +                * the pending state, as it could otherwise result in a
> +                * spurious interrupt by injecting a now potentially stale
> +                * pending state.
> +                *
>                  * If this causes us to lower the level, we have to also clear
>                  * the physical active state, since we will otherwise never be
>                  * told when the interrupt becomes asserted again.
> @@ -108,12 +116,15 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
>                 if (vgic_irq_is_mapped_level(irq)) {
>                         bool resample = false;
>
> -                       if (val & ICH_LR_PENDING_BIT) {
> -                               irq->line_level = vgic_get_phys_line_level(irq);
> -                               resample = !irq->line_level;
> -                       } else if (vgic_irq_needs_resampling(irq) &&
> -                                  !(irq->active || irq->pending_latch)) {
> -                               resample = true;
> +                       if (unlikely(vgic_irq_needs_resampling(irq))) {
> +                               if (!(irq->active || irq->pending_latch))
> +                                       resample = true;
> +                       } else {
> +                               if ((val & ICH_LR_PENDING_BIT) ||
> +                                   (deactivated && irq->line_level)) {
> +                                       irq->line_level = vgic_get_phys_line_level(irq);
> +                                       resample = !irq->line_level;
> +                               }
>                         }
>
>                         if (resample)
> --
> 2.30.2
>


From oupton at google.com  Wed Aug 18 12:37:23 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 18 Aug 2021 12:37:23 -0700
Subject: [PATCH] arm64: initialize all of CNTHCTL_EL2
In-Reply-To: <20210818161535.52786-1-mark.rutland@arm.com>
References: <20210818161535.52786-1-mark.rutland@arm.com>
Message-ID: <CAOQ_QshA5ZmD-WDGC86xkBE3H3uUXfUdR-K3N8OGNgjWytT7xw@mail.gmail.com>

On Wed, Aug 18, 2021 at 9:15 AM Mark Rutland <mark.rutland at arm.com> wrote:
>
> In __init_el2_timers we initialize CNTHCTL_EL2.{EL1PCEN,EL1PCTEN} with a
> RMW sequence, leaving all other bits UNKNOWN.
>
> In general, we should initialize all bits in a register rather than
> using an RMW sequence, since most bits are UNKNOWN out of reset, and as
> new bits are added to the reigster their reset value might not result in
> expected behaviour.
>
> In the case of CNTHCTL_EL2, FEAT_ECV added a number of new control bits
> in previously RES0 bits, which reset to UNKNOWN values, and may cause
> issues for EL1 and EL0:
>
> * CNTHCTL_EL2.ECV enables the CNTPOFF_EL2 offset (which itself resets to
>   an UNKNOWN value) at EL0 and EL1. Since the offset could reset to
>   distinct values across CPUs, when the control bit resets to 1 this
>   could break timekeeping generally.
>
> * CNTHCTL_EL2.{EL1TVT,EL1TVCT} trap EL0 and EL1 accesses to the EL1
>   virtual timer/counter registers to EL2. When reset to 1, this could
>   cause unexpected traps to EL2.
>
> Initializing these bits to zero avoids these problems, and all other
> bits in CNPTOFF_EL2 other than EL1PCEN and EL1PCTEN can safely be reset
> to zero.

s/CNPTOFF_EL2/CNTHCTL_EL2

>
> This patch ensures we initialize CNTHCTL_EL2 accordingly, only setting
> EL1PCEN and EL1PCTEN, and setting all other bits to zero.
>
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oupton at google.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/el2_setup.h | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index 21fa330f498dd..b83fb24954b77 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -33,8 +33,7 @@
>   * EL2.
>   */
>  .macro __init_el2_timers
> -       mrs     x0, cnthctl_el2
> -       orr     x0, x0, #3                      // Enable EL1 physical timers
> +       mov     x0, #3                          // Enable EL1 physical timers
>         msr     cnthctl_el2, x0
>         msr     cntvoff_el2, xzr                // Clear virtual offset
>  .endm
> --
> 2.11.0
>

Besides noted above:

Reviewed-by: Oliver Upton <oupton at google.com>


From mathieu.poirier at linaro.org  Wed Aug 18 12:40:11 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:11 -0600
Subject: [PATCH 00/11] coresight: Patches for v5.15
Message-ID: <20210818194022.379573-1-mathieu.poirier@linaro.org>

Hi Greg,

This is what I picked up for the next merge window (v5.15).  Please have
a look when time permits.

Applies cleanly on your char-misc-next branch (9e1b28b77388).  

Thanks,
Mathieu

Mike Leach (10):
  coresight: syscfg: Initial coresight system configuration
  coresight: syscfg: Add registration and feature loading for cs devices
  coresight: config: Add configuration and feature generic functions
  coresight: etm-perf: Update to handle configuration selection
  coresight: syscfg: Add API to activate and enable configurations
  coresight: etm-perf: Update to activate selected configuration
  coresight: etm4x: Add complex configuration handlers to etmv4
  coresight: config: Add preloaded configurations
  coresight: syscfg: Add initial configfs support
  Documentation: coresight: Add documentation for CoreSight config

Sebastian Andrzej Siewior (1):
  coresight: Replace deprecated CPU-hotplug functions.

 .../trace/coresight/coresight-config.rst      | 244 +++++
 Documentation/trace/coresight/coresight.rst   |  15 +
 drivers/hwtracing/coresight/Kconfig           |   1 +
 drivers/hwtracing/coresight/Makefile          |   7 +-
 .../hwtracing/coresight/coresight-cfg-afdo.c  | 153 ++++
 .../coresight/coresight-cfg-preload.c         |  31 +
 .../coresight/coresight-cfg-preload.h         |  13 +
 .../hwtracing/coresight/coresight-config.c    | 272 ++++++
 .../hwtracing/coresight/coresight-config.h    | 253 ++++++
 drivers/hwtracing/coresight/coresight-core.c  |  12 +-
 .../hwtracing/coresight/coresight-cpu-debug.c |   4 +-
 .../hwtracing/coresight/coresight-etm-perf.c  | 150 +++-
 .../hwtracing/coresight/coresight-etm-perf.h  |  12 +-
 .../hwtracing/coresight/coresight-etm4x-cfg.c | 182 ++++
 .../hwtracing/coresight/coresight-etm4x-cfg.h |  30 +
 .../coresight/coresight-etm4x-core.c          |  38 +-
 .../coresight/coresight-etm4x-sysfs.c         |   3 +
 .../coresight/coresight-syscfg-configfs.c     | 396 ++++++++
 .../coresight/coresight-syscfg-configfs.h     |  45 +
 .../hwtracing/coresight/coresight-syscfg.c    | 847 ++++++++++++++++++
 .../hwtracing/coresight/coresight-syscfg.h    |  81 ++
 include/linux/coresight.h                     |   9 +
 22 files changed, 2760 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/trace/coresight/coresight-config.rst
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-afdo.c
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.c
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.h
 create mode 100644 drivers/hwtracing/coresight/coresight-config.c
 create mode 100644 drivers/hwtracing/coresight/coresight-config.h
 create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c
 create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h
 create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.c
 create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.h
 create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.c
 create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.h

-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:12 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:12 -0600
Subject: [PATCH 01/11] coresight: syscfg: Initial coresight system
 configuration
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-2-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Creates an system management API to allow complex configurations and
features to be programmed into a CoreSight infrastructure.

A feature is defined as a programming set for a device or class of
devices.

A configuration is a set of features across the system that are enabled
for a trace session.

The API will manage system wide configuration, and allow complex
programmed features to be added to individual device instances, and
provide for system wide configuration selection on trace capture
operations.

This patch creates the initial data object and the initial API for
loading configurations and features.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-2-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 drivers/hwtracing/coresight/Makefile          |   2 +-
 .../hwtracing/coresight/coresight-config.h    | 142 +++++++++++++
 drivers/hwtracing/coresight/coresight-core.c  |  12 +-
 .../hwtracing/coresight/coresight-etm-perf.c  |   2 +-
 .../hwtracing/coresight/coresight-etm-perf.h  |   2 +-
 .../hwtracing/coresight/coresight-syscfg.c    | 199 ++++++++++++++++++
 .../hwtracing/coresight/coresight-syscfg.h    |  46 ++++
 7 files changed, 401 insertions(+), 4 deletions(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-config.h
 create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.c
 create mode 100644 drivers/hwtracing/coresight/coresight-syscfg.h

diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index d60816509755..3d037f17aade 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -4,7 +4,7 @@
 #
 obj-$(CONFIG_CORESIGHT) += coresight.o
 coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
-		coresight-sysfs.o
+		coresight-sysfs.o coresight-syscfg.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
 coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
 		      coresight-tmc-etr.o
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
new file mode 100644
index 000000000000..21aa7464dcdc
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <mike.leach at linaro.org>
+ */
+
+#ifndef _CORESIGHT_CORESIGHT_CONFIG_H
+#define _CORESIGHT_CORESIGHT_CONFIG_H
+
+#include <linux/coresight.h>
+#include <linux/types.h>
+
+/* CoreSight Configuration Management - component and system wide configuration */
+
+/*
+ * Register type flags for register value descriptor:
+ * describe how the value is interpreted, and handled.
+ */
+#define CS_CFG_REG_TYPE_STD		0x80	/* reg is standard reg */
+#define CS_CFG_REG_TYPE_RESOURCE	0x40	/* reg is a resource */
+#define CS_CFG_REG_TYPE_VAL_PARAM	0x08	/* reg value uses param */
+#define CS_CFG_REG_TYPE_VAL_MASK	0x04	/* reg value bit masked */
+#define CS_CFG_REG_TYPE_VAL_64BIT	0x02	/* reg value 64 bit */
+#define CS_CFG_REG_TYPE_VAL_SAVE	0x01	/* reg value save on disable */
+
+/*
+ * flags defining what device class a feature will match to when processing a
+ * system configuration - used by config data and devices.
+ */
+#define CS_CFG_MATCH_CLASS_SRC_ALL	0x0001	/* match any source */
+#define CS_CFG_MATCH_CLASS_SRC_ETM4	0x0002	/* match any ETMv4 device */
+
+/* flags defining device instance matching - used in config match desc data. */
+#define CS_CFG_MATCH_INST_ANY		0x80000000 /* any instance of a class */
+
+/*
+ * Limit number of presets in a configuration
+ * This is related to the number of bits (4) we use to select the preset on
+ * the perf command line. Preset 0 is always none selected.
+ * See PMU_FORMAT_ATTR(preset, "config:0-3") in coresight-etm-perf.c
+ */
+#define CS_CFG_CONFIG_PRESET_MAX 15
+
+/**
+ * Parameter descriptor for a device feature.
+ *
+ * @name:  Name of parameter.
+ * @value: Initial or default value.
+ */
+struct cscfg_parameter_desc {
+	const char *name;
+	u64 value;
+};
+
+/**
+ * Representation of register value and a descriptor of register usage.
+ *
+ * Used as a descriptor in the feature descriptors.
+ * Used as a value in when in a feature loading into a csdev.
+ *
+ * Supports full 64 bit register value, or 32 bit value with optional mask
+ * value.
+ *
+ * @type:	define register usage and interpretation.
+ * @offset:	the address offset for register in the hardware device (per device specification).
+ * @hw_info:	optional hardware device type specific information. (ETM / CTI specific etc)
+ * @val64:	64 bit value.
+ * @val32:	32 bit value.
+ * @mask32:	32 bit mask when using 32 bit value to access device register - if mask type.
+ * @param_idx:	parameter index value into parameter array if param type.
+ */
+struct cscfg_regval_desc {
+	struct {
+		u32 type:8;
+		u32 offset:12;
+		u32 hw_info:12;
+	};
+	union {
+		u64 val64;
+		struct {
+			u32 val32;
+			u32 mask32;
+		};
+		u32 param_idx;
+	};
+};
+
+/**
+ * Device feature descriptor - combination of registers and parameters to
+ * program a device to implement a specific complex function.
+ *
+ * @name:	 feature name.
+ * @description: brief description of the feature.
+ * @item:	 List entry.
+ * @match_flags: matching information if loading into a device
+ * @nr_params:   number of parameters used.
+ * @params_desc: array of parameters used.
+ * @nr_regs:	 number of registers used.
+ * @regs_desc:	 array of registers used.
+ */
+struct cscfg_feature_desc {
+	const char *name;
+	const char *description;
+	struct list_head item;
+	u32 match_flags;
+	int nr_params;
+	struct cscfg_parameter_desc *params_desc;
+	int nr_regs;
+	struct cscfg_regval_desc *regs_desc;
+};
+
+/**
+ * Configuration descriptor - describes selectable system configuration.
+ *
+ * A configuration describes device features in use, and may provide preset
+ * values for the parameters in those features.
+ *
+ * A single set of presets is the sum of the parameters declared by
+ * all the features in use - this value is @nr_total_params.
+ *
+ * @name:		name of the configuration - used for selection.
+ * @description:	description of the purpose of the configuration.
+ * @item:		list entry.
+ * @nr_feat_refs:	Number of features used in this configuration.
+ * @feat_ref_names:	references to features used in this configuration.
+ * @nr_presets:		Number of sets of presets supplied by this configuration.
+ * @nr_total_params:	Sum of all parameters declared by used features
+ * @presets:		Array of preset values.
+ *
+ */
+struct cscfg_config_desc {
+	const char *name;
+	const char *description;
+	struct list_head item;
+	int nr_feat_refs;
+	const char **feat_ref_names;
+	int nr_presets;
+	int nr_total_params;
+	const u64 *presets; /* nr_presets * nr_total_params */
+};
+
+#endif /* _CORESIGHT_CORESIGHT_CONFIG_H */
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 1002605db8ba..8a18c71df37a 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -21,6 +21,7 @@
 
 #include "coresight-etm-perf.h"
 #include "coresight-priv.h"
+#include "coresight-syscfg.h"
 
 static DEFINE_MUTEX(coresight_mutex);
 static DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
@@ -1763,13 +1764,22 @@ static int __init coresight_init(void)
 
 	ret = etm_perf_init();
 	if (ret)
-		bus_unregister(&coresight_bustype);
+		goto exit_bus_unregister;
 
+	/* initialise the coresight syscfg API */
+	ret = cscfg_init();
+	if (!ret)
+		return 0;
+
+	etm_perf_exit();
+exit_bus_unregister:
+	bus_unregister(&coresight_bustype);
 	return ret;
 }
 
 static void __exit coresight_exit(void)
 {
+	cscfg_exit();
 	etm_perf_exit();
 	bus_unregister(&coresight_bustype);
 }
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 6f398377fec9..b582e92cdea4 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -748,7 +748,7 @@ int __init etm_perf_init(void)
 	return ret;
 }
 
-void __exit etm_perf_exit(void)
+void etm_perf_exit(void)
 {
 	perf_pmu_unregister(&etm_pmu);
 }
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h
index 3e4f2ad5e193..29d90dfeba31 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.h
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
@@ -83,6 +83,6 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle)
 #endif /* CONFIG_CORESIGHT */
 
 int __init etm_perf_init(void);
-void __exit etm_perf_exit(void);
+void etm_perf_exit(void);
 
 #endif
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
new file mode 100644
index 000000000000..417db3f92c2f
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <mike.leach at linaro.org>
+ */
+
+#include <linux/platform_device.h>
+
+#include "coresight-config.h"
+#include "coresight-syscfg.h"
+
+/*
+ * cscfg_ API manages configurations and features for the entire coresight
+ * infrastructure.
+ *
+ * It allows the loading of configurations and features, and loads these into
+ * coresight devices as appropriate.
+ */
+
+/* protect the cscsg_data and device */
+static DEFINE_MUTEX(cscfg_mutex);
+
+/* only one of these */
+static struct cscfg_manager *cscfg_mgr;
+
+/* load features and configuations into the lists */
+
+/* check feature list for a named feature - call with mutex locked. */
+static bool cscfg_match_list_feat(const char *name)
+{
+	struct cscfg_feature_desc *feat_desc;
+
+	list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
+		if (strcmp(feat_desc->name, name) == 0)
+			return true;
+	}
+	return false;
+}
+
+/* check all feat needed for cfg are in the list - call with mutex locked. */
+static int cscfg_check_feat_for_cfg(struct cscfg_config_desc *config_desc)
+{
+	int i;
+
+	for (i = 0; i < config_desc->nr_feat_refs; i++)
+		if (!cscfg_match_list_feat(config_desc->feat_ref_names[i]))
+			return -EINVAL;
+	return 0;
+}
+
+/*
+ * load feature - add to feature list.
+ */
+static int cscfg_load_feat(struct cscfg_feature_desc *feat_desc)
+{
+	list_add(&feat_desc->item, &cscfg_mgr->feat_desc_list);
+
+	return 0;
+}
+
+/*
+ * load config into the system - validate used features exist then add to
+ * config list.
+ */
+static int cscfg_load_config(struct cscfg_config_desc *config_desc)
+{
+	int err;
+
+	/* validate features are present */
+	err = cscfg_check_feat_for_cfg(config_desc);
+	if (err)
+		return err;
+
+	list_add(&config_desc->item, &cscfg_mgr->config_desc_list);
+	return 0;
+}
+
+/**
+ * cscfg_load_config_sets - API function to load feature and config sets.
+ *
+ * Take a 0 terminated array of feature descriptors and/or configuration
+ * descriptors and load into the system.
+ * Features are loaded first to ensure configuration dependencies can be met.
+ *
+ * @config_descs: 0 terminated array of configuration descriptors.
+ * @feat_descs:   0 terminated array of feature descriptors.
+ */
+int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
+			   struct cscfg_feature_desc **feat_descs)
+{
+	int err, i = 0;
+
+	mutex_lock(&cscfg_mutex);
+
+	/* load features first */
+	if (feat_descs) {
+		while (feat_descs[i]) {
+			err = cscfg_load_feat(feat_descs[i]);
+			if (err) {
+				pr_err("coresight-syscfg: Failed to load feature %s\n",
+				       feat_descs[i]->name);
+				goto exit_unlock;
+			}
+			i++;
+		}
+	}
+
+	/* next any configurations to check feature dependencies */
+	i = 0;
+	if (config_descs) {
+		while (config_descs[i]) {
+			err = cscfg_load_config(config_descs[i]);
+			if (err) {
+				pr_err("coresight-syscfg: Failed to load configuration %s\n",
+				       config_descs[i]->name);
+				goto exit_unlock;
+			}
+			i++;
+		}
+	}
+
+exit_unlock:
+	mutex_unlock(&cscfg_mutex);
+	return err;
+}
+EXPORT_SYMBOL_GPL(cscfg_load_config_sets);
+
+/* Initialise system configuration management device. */
+
+struct device *cscfg_device(void)
+{
+	return cscfg_mgr ? &cscfg_mgr->dev : NULL;
+}
+
+/* Must have a release function or the kernel will complain on module unload */
+static void cscfg_dev_release(struct device *dev)
+{
+	kfree(cscfg_mgr);
+	cscfg_mgr = NULL;
+}
+
+/* a device is needed to "own" some kernel elements such as sysfs entries.  */
+static int cscfg_create_device(void)
+{
+	struct device *dev;
+	int err = -ENOMEM;
+
+	mutex_lock(&cscfg_mutex);
+	if (cscfg_mgr) {
+		err = -EINVAL;
+		goto create_dev_exit_unlock;
+	}
+
+	cscfg_mgr = kzalloc(sizeof(struct cscfg_manager), GFP_KERNEL);
+	if (!cscfg_mgr)
+		goto create_dev_exit_unlock;
+
+	/* setup the device */
+	dev = cscfg_device();
+	dev->release = cscfg_dev_release;
+	dev->init_name = "cs_system_cfg";
+
+	err = device_register(dev);
+	if (err)
+		cscfg_dev_release(dev);
+
+create_dev_exit_unlock:
+	mutex_unlock(&cscfg_mutex);
+	return err;
+}
+
+static void cscfg_clear_device(void)
+{
+	mutex_lock(&cscfg_mutex);
+	device_unregister(cscfg_device());
+	mutex_unlock(&cscfg_mutex);
+}
+
+/* Initialise system config management API device  */
+int __init cscfg_init(void)
+{
+	int err = 0;
+
+	err = cscfg_create_device();
+	if (err)
+		return err;
+
+	INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
+	INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
+	INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
+
+	dev_info(cscfg_device(), "CoreSight Configuration manager initialised");
+	return 0;
+}
+
+void cscfg_exit(void)
+{
+	cscfg_clear_device();
+}
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
new file mode 100644
index 000000000000..18be9b58cd0b
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-syscfg.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Coresight system configuration driver.
+ */
+
+#ifndef CORESIGHT_SYSCFG_H
+#define CORESIGHT_SYSCFG_H
+
+#include <linux/coresight.h>
+#include <linux/device.h>
+
+#include "coresight-config.h"
+
+/**
+ * System configuration manager device.
+ *
+ * Contains lists of the loaded configurations and features, plus a list of CoreSight devices
+ * registered with the system as supporting configuration management.
+ *
+ * Need a device to 'own' some coresight system wide sysfs entries in
+ * perf events, configfs etc.
+ *
+ * @dev:		The device.
+ * @csdev_desc_list:	List of coresight devices registered with the configuration manager.
+ * @feat_desc_list:	List of feature descriptors to load into registered devices.
+ * @config_desc_list:	List of system configuration descriptors to load into registered devices.
+ */
+struct cscfg_manager {
+	struct device dev;
+	struct list_head csdev_desc_list;
+	struct list_head feat_desc_list;
+	struct list_head config_desc_list;
+};
+
+/* get reference to dev in cscfg_manager */
+struct device *cscfg_device(void);
+
+/* internal core operations for cscfg */
+int __init cscfg_init(void);
+void cscfg_exit(void);
+
+/* syscfg manager external API */
+int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
+			   struct cscfg_feature_desc **feat_descs);
+
+#endif /* CORESIGHT_SYSCFG_H */
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:13 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:13 -0600
Subject: [PATCH 02/11] coresight: syscfg: Add registration and feature loading
 for cs devices
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-3-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

API for individual devices to register with the syscfg management
system is added.

Devices register with matching information, and any features or
configurations that match will be loaded into the device.

The feature and configuration loading is extended so that on load these
are loaded into any currently registered devices. This allows
configuration loading after devices have been registered.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-3-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 .../hwtracing/coresight/coresight-config.h    |  98 +++++
 .../hwtracing/coresight/coresight-syscfg.c    | 338 +++++++++++++++++-
 .../hwtracing/coresight/coresight-syscfg.h    |  19 +
 include/linux/coresight.h                     |   7 +
 4 files changed, 461 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 21aa7464dcdc..685fb46ce893 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -139,4 +139,102 @@ struct cscfg_config_desc {
 	const u64 *presets; /* nr_presets * nr_total_params */
 };
 
+/**
+ * config register instance - part of a loaded feature.
+ *                            maps register values to csdev driver structures
+ *
+ * @reg_desc:		value to use when setting feature on device / store for
+ *			readback of volatile values.
+ * @driver_regval:	pointer to internal driver element used to set the value
+ *			in hardware.
+ */
+struct cscfg_regval_csdev {
+	struct cscfg_regval_desc reg_desc;
+	void *driver_regval;
+};
+
+/**
+ * config parameter instance - part of a loaded feature.
+ *
+ * @feat_csdev:		parent feature
+ * @reg_csdev:		register value updated by this parameter.
+ * @current_value:	current value of parameter - may be set by user via
+ *			sysfs, or modified during device operation.
+ * @val64:		true if 64 bit value
+ */
+struct cscfg_parameter_csdev {
+	struct cscfg_feature_csdev *feat_csdev;
+	struct cscfg_regval_csdev *reg_csdev;
+	u64 current_value;
+	bool val64;
+};
+
+/**
+ * Feature instance loaded into a CoreSight device.
+ *
+ * When a feature is loaded into a specific device, then this structure holds
+ * the connections between the register / parameter values used and the
+ * internal data structures that are written when the feature is enabled.
+ *
+ * Since applying a feature modifies internal data structures in the device,
+ * then we have a reference to the device spinlock to protect access to these
+ * structures (@drv_spinlock).
+ *
+ * @feat_desc:		pointer to the static descriptor for this feature.
+ * @csdev:		parent CoreSight device instance.
+ * @node:		list entry into feature list for this device.
+ * @drv_spinlock:	device spinlock for access to driver register data.
+ * @nr_params:		number of parameters.
+ * @params_csdev:	current parameter values on this device
+ * @nr_regs:		number of registers to be programmed.
+ * @regs_csdev:		Programming details for the registers
+ */
+struct cscfg_feature_csdev {
+	const struct cscfg_feature_desc *feat_desc;
+	struct coresight_device *csdev;
+	struct list_head node;
+	spinlock_t *drv_spinlock;
+	int nr_params;
+	struct cscfg_parameter_csdev *params_csdev;
+	int nr_regs;
+	struct cscfg_regval_csdev *regs_csdev;
+};
+
+/**
+ * Configuration instance when loaded into a CoreSight device.
+ *
+ * The instance contains references to loaded features on this device that are
+ * used by the configuration.
+ *
+ * @config_desc:reference to the descriptor for this configuration
+ * @csdev:	parent coresight device for this configuration instance.
+ * @enabled:	true if configuration is enabled on this device.
+ * @node:	list entry within the coresight device
+ * @nr_feat:	Number of features on this device that are used in the
+ *		configuration.
+ * @feats_csdev:references to the device features to enable.
+ */
+struct cscfg_config_csdev {
+	const struct cscfg_config_desc *config_desc;
+	struct coresight_device *csdev;
+	bool enabled;
+	struct list_head node;
+	int nr_feat;
+	struct cscfg_feature_csdev *feats_csdev[0];
+};
+
+/**
+ * Coresight device operations.
+ *
+ * Registered coresight devices provide these operations to manage feature
+ * instances compatible with the device hardware and drivers
+ *
+ * @load_feat:	Pass a feature descriptor into the device and create the
+ *		loaded feature instance (struct cscfg_feature_csdev).
+ */
+struct cscfg_csdev_feat_ops {
+	int (*load_feat)(struct coresight_device *csdev,
+			 struct cscfg_feature_csdev *feat_csdev);
+};
+
 #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 417db3f92c2f..2c0d4906e226 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -25,6 +25,198 @@ static struct cscfg_manager *cscfg_mgr;
 
 /* load features and configuations into the lists */
 
+/* get name feature instance from a coresight device list of features */
+static struct cscfg_feature_csdev *
+cscfg_get_feat_csdev(struct coresight_device *csdev, const char *name)
+{
+	struct cscfg_feature_csdev *feat_csdev = NULL;
+
+	list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node) {
+		if (strcmp(feat_csdev->feat_desc->name, name) == 0)
+			return feat_csdev;
+	}
+	return NULL;
+}
+
+/* allocate the device config instance - with max number of used features */
+static struct cscfg_config_csdev *
+cscfg_alloc_csdev_cfg(struct coresight_device *csdev, int nr_feats)
+{
+	struct cscfg_config_csdev *config_csdev = NULL;
+	struct device *dev = csdev->dev.parent;
+
+	/* this is being allocated using the devm for the coresight device */
+	config_csdev = devm_kzalloc(dev,
+				    offsetof(struct cscfg_config_csdev, feats_csdev[nr_feats]),
+				    GFP_KERNEL);
+	if (!config_csdev)
+		return NULL;
+
+	config_csdev->csdev = csdev;
+	return config_csdev;
+}
+
+/* Load a config into a device if there are any feature matches between config and device */
+static int cscfg_add_csdev_cfg(struct coresight_device *csdev,
+			       struct cscfg_config_desc *config_desc)
+{
+	struct cscfg_config_csdev *config_csdev = NULL;
+	struct cscfg_feature_csdev *feat_csdev;
+	unsigned long flags;
+	int i;
+
+	/* look at each required feature and see if it matches any feature on the device */
+	for (i = 0; i < config_desc->nr_feat_refs; i++) {
+		/* look for a matching name */
+		feat_csdev = cscfg_get_feat_csdev(csdev, config_desc->feat_ref_names[i]);
+		if (feat_csdev) {
+			/*
+			 * At least one feature on this device matches the config
+			 * add a config instance to the device and a reference to the feature.
+			 */
+			if (!config_csdev) {
+				config_csdev = cscfg_alloc_csdev_cfg(csdev,
+								     config_desc->nr_feat_refs);
+				if (!config_csdev)
+					return -ENOMEM;
+				config_csdev->config_desc = config_desc;
+			}
+			config_csdev->feats_csdev[config_csdev->nr_feat++] = feat_csdev;
+		}
+	}
+	/* if matched features, add config to device.*/
+	if (config_csdev) {
+		spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+		list_add(&config_csdev->node, &csdev->config_csdev_list);
+		spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+	}
+
+	return 0;
+}
+
+/*
+ * Add the config to the set of registered devices - call with mutex locked.
+ * Iterates through devices - any device that matches one or more of the
+ * configuration features will load it, the others will ignore it.
+ */
+static int cscfg_add_cfg_to_csdevs(struct cscfg_config_desc *config_desc)
+{
+	struct cscfg_registered_csdev *csdev_item;
+	int err;
+
+	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
+		err = cscfg_add_csdev_cfg(csdev_item->csdev, config_desc);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+/*
+ * Allocate a feature object for load into a csdev.
+ * memory allocated using the csdev->dev object using devm managed allocator.
+ */
+static struct cscfg_feature_csdev *
+cscfg_alloc_csdev_feat(struct coresight_device *csdev, struct cscfg_feature_desc *feat_desc)
+{
+	struct cscfg_feature_csdev *feat_csdev = NULL;
+	struct device *dev = csdev->dev.parent;
+	int i;
+
+	feat_csdev = devm_kzalloc(dev, sizeof(struct cscfg_feature_csdev), GFP_KERNEL);
+	if (!feat_csdev)
+		return NULL;
+
+	/* parameters are optional - could be 0 */
+	feat_csdev->nr_params = feat_desc->nr_params;
+
+	/*
+	 * if we need parameters, zero alloc the space here, the load routine in
+	 * the csdev device driver will fill out some information according to
+	 * feature descriptor.
+	 */
+	if (feat_csdev->nr_params) {
+		feat_csdev->params_csdev = devm_kcalloc(dev, feat_csdev->nr_params,
+							sizeof(struct cscfg_parameter_csdev),
+							GFP_KERNEL);
+		if (!feat_csdev->params_csdev)
+			return NULL;
+
+		/*
+		 * fill in the feature reference in the param - other fields
+		 * handled by loader in csdev.
+		 */
+		for (i = 0; i < feat_csdev->nr_params; i++)
+			feat_csdev->params_csdev[i].feat_csdev = feat_csdev;
+	}
+
+	/*
+	 * Always have registers to program - again the load routine in csdev device
+	 * will fill out according to feature descriptor and device requirements.
+	 */
+	feat_csdev->nr_regs = feat_desc->nr_regs;
+	feat_csdev->regs_csdev = devm_kcalloc(dev, feat_csdev->nr_regs,
+					      sizeof(struct cscfg_regval_csdev),
+					      GFP_KERNEL);
+	if (!feat_csdev->regs_csdev)
+		return NULL;
+
+	/* load the feature default values */
+	feat_csdev->feat_desc = feat_desc;
+	feat_csdev->csdev = csdev;
+
+	return feat_csdev;
+}
+
+/* load one feature into one coresight device */
+static int cscfg_load_feat_csdev(struct coresight_device *csdev,
+				 struct cscfg_feature_desc *feat_desc,
+				 struct cscfg_csdev_feat_ops *ops)
+{
+	struct cscfg_feature_csdev *feat_csdev;
+	unsigned long flags;
+	int err;
+
+	if (!ops->load_feat)
+		return -EINVAL;
+
+	feat_csdev = cscfg_alloc_csdev_feat(csdev, feat_desc);
+	if (!feat_csdev)
+		return -ENOMEM;
+
+	/* load the feature into the device */
+	err = ops->load_feat(csdev, feat_csdev);
+	if (err)
+		return err;
+
+	/* add to internal csdev feature list */
+	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	list_add(&feat_csdev->node, &csdev->feature_csdev_list);
+	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+
+	return 0;
+}
+
+/*
+ * Add feature to any matching devices - call with mutex locked.
+ * Iterates through devices - any device that matches the feature will be
+ * called to load it.
+ */
+static int cscfg_add_feat_to_csdevs(struct cscfg_feature_desc *feat_desc)
+{
+	struct cscfg_registered_csdev *csdev_item;
+	int err;
+
+	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
+		if (csdev_item->match_flags & feat_desc->match_flags) {
+			err = cscfg_load_feat_csdev(csdev_item->csdev, feat_desc, &csdev_item->ops);
+			if (err)
+				return err;
+		}
+	}
+	return 0;
+}
+
 /* check feature list for a named feature - call with mutex locked. */
 static bool cscfg_match_list_feat(const char *name)
 {
@@ -53,8 +245,14 @@ static int cscfg_check_feat_for_cfg(struct cscfg_config_desc *config_desc)
  */
 static int cscfg_load_feat(struct cscfg_feature_desc *feat_desc)
 {
-	list_add(&feat_desc->item, &cscfg_mgr->feat_desc_list);
+	int err;
+
+	/* add feature to any matching registered devices */
+	err = cscfg_add_feat_to_csdevs(feat_desc);
+	if (err)
+		return err;
 
+	list_add(&feat_desc->item, &cscfg_mgr->feat_desc_list);
 	return 0;
 }
 
@@ -71,6 +269,11 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc)
 	if (err)
 		return err;
 
+	/* add config to any matching registered device */
+	err = cscfg_add_cfg_to_csdevs(config_desc);
+	if (err)
+		return err;
+
 	list_add(&config_desc->item, &cscfg_mgr->config_desc_list);
 	return 0;
 }
@@ -125,6 +328,139 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
 }
 EXPORT_SYMBOL_GPL(cscfg_load_config_sets);
 
+/* Handle coresight device registration and add configs and features to devices */
+
+/* iterate through config lists and load matching configs to device */
+static int cscfg_add_cfgs_csdev(struct coresight_device *csdev)
+{
+	struct cscfg_config_desc *config_desc;
+	int err = 0;
+
+	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
+		err = cscfg_add_csdev_cfg(csdev, config_desc);
+		if (err)
+			break;
+	}
+	return err;
+}
+
+/* iterate through feature lists and load matching features to device */
+static int cscfg_add_feats_csdev(struct coresight_device *csdev,
+				 u32 match_flags,
+				 struct cscfg_csdev_feat_ops *ops)
+{
+	struct cscfg_feature_desc *feat_desc;
+	int err = 0;
+
+	if (!ops->load_feat)
+		return -EINVAL;
+
+	list_for_each_entry(feat_desc, &cscfg_mgr->feat_desc_list, item) {
+		if (feat_desc->match_flags & match_flags) {
+			err = cscfg_load_feat_csdev(csdev, feat_desc, ops);
+			if (err)
+				break;
+		}
+	}
+	return err;
+}
+
+/* Add coresight device to list and copy its matching info */
+static int cscfg_list_add_csdev(struct coresight_device *csdev,
+				u32 match_flags,
+				struct cscfg_csdev_feat_ops *ops)
+{
+	struct cscfg_registered_csdev *csdev_item;
+
+	/* allocate the list entry structure */
+	csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
+	if (!csdev_item)
+		return -ENOMEM;
+
+	csdev_item->csdev = csdev;
+	csdev_item->match_flags = match_flags;
+	csdev_item->ops.load_feat = ops->load_feat;
+	list_add(&csdev_item->item, &cscfg_mgr->csdev_desc_list);
+
+	INIT_LIST_HEAD(&csdev->feature_csdev_list);
+	INIT_LIST_HEAD(&csdev->config_csdev_list);
+	spin_lock_init(&csdev->cscfg_csdev_lock);
+
+	return 0;
+}
+
+/* remove a coresight device from the list and free data */
+static void cscfg_list_remove_csdev(struct coresight_device *csdev)
+{
+	struct cscfg_registered_csdev *csdev_item, *tmp;
+
+	list_for_each_entry_safe(csdev_item, tmp, &cscfg_mgr->csdev_desc_list, item) {
+		if (csdev_item->csdev == csdev) {
+			list_del(&csdev_item->item);
+			kfree(csdev_item);
+			break;
+		}
+	}
+}
+
+/**
+ * cscfg_register_csdev - register a coresight device with the syscfg manager.
+ *
+ * Registers the coresight device with the system. @match_flags used to check
+ * if the device is a match for registered features. Any currently registered
+ * configurations and features that match the device will be loaded onto it.
+ *
+ * @csdev:		The coresight device to register.
+ * @match_flags:	Matching information to load features.
+ * @ops:		Standard operations supported by the device.
+ */
+int cscfg_register_csdev(struct coresight_device *csdev,
+			 u32 match_flags,
+			 struct cscfg_csdev_feat_ops *ops)
+{
+	int ret = 0;
+
+	mutex_lock(&cscfg_mutex);
+
+	/* add device to list of registered devices  */
+	ret = cscfg_list_add_csdev(csdev, match_flags, ops);
+	if (ret)
+		goto reg_csdev_unlock;
+
+	/* now load any registered features and configs matching the device. */
+	ret = cscfg_add_feats_csdev(csdev, match_flags, ops);
+	if (ret) {
+		cscfg_list_remove_csdev(csdev);
+		goto reg_csdev_unlock;
+	}
+
+	ret = cscfg_add_cfgs_csdev(csdev);
+	if (ret) {
+		cscfg_list_remove_csdev(csdev);
+		goto reg_csdev_unlock;
+	}
+
+	pr_info("CSCFG registered %s", dev_name(&csdev->dev));
+
+reg_csdev_unlock:
+	mutex_unlock(&cscfg_mutex);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cscfg_register_csdev);
+
+/**
+ * cscfg_unregister_csdev - remove coresight device from syscfg manager.
+ *
+ * @csdev: Device to remove.
+ */
+void cscfg_unregister_csdev(struct coresight_device *csdev)
+{
+	mutex_lock(&cscfg_mutex);
+	cscfg_list_remove_csdev(csdev);
+	mutex_unlock(&cscfg_mutex);
+}
+EXPORT_SYMBOL_GPL(cscfg_unregister_csdev);
+
 /* Initialise system configuration management device. */
 
 struct device *cscfg_device(void)
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
index 18be9b58cd0b..5bcae3b374c6 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.h
+++ b/drivers/hwtracing/coresight/coresight-syscfg.h
@@ -35,6 +35,22 @@ struct cscfg_manager {
 /* get reference to dev in cscfg_manager */
 struct device *cscfg_device(void);
 
+/**
+ * List entry for Coresight devices that are registered as supporting complex
+ * config operations.
+ *
+ * @csdev:	 The registered device.
+ * @match_flags: The matching type information for adding features.
+ * @ops:	 Operations supported by the registered device.
+ * @item:	 list entry.
+ */
+struct cscfg_registered_csdev {
+	struct coresight_device *csdev;
+	u32 match_flags;
+	struct cscfg_csdev_feat_ops ops;
+	struct list_head item;
+};
+
 /* internal core operations for cscfg */
 int __init cscfg_init(void);
 void cscfg_exit(void);
@@ -42,5 +58,8 @@ void cscfg_exit(void);
 /* syscfg manager external API */
 int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
 			   struct cscfg_feature_desc **feat_descs);
+int cscfg_register_csdev(struct coresight_device *csdev, u32 match_flags,
+			 struct cscfg_csdev_feat_ops *ops);
+void cscfg_unregister_csdev(struct coresight_device *csdev);
 
 #endif /* CORESIGHT_SYSCFG_H */
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 85008a65e21f..16544ae2b532 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -220,6 +220,9 @@ struct coresight_sysfs_link {
  * @nr_links:   number of sysfs links created to other components from this
  *		device. These will appear in the "connections" group.
  * @has_conns_grp: Have added a "connections" group for sysfs links.
+ * @feature_csdev_list: List of complex feature programming added to the device.
+ * @config_csdev_list:  List of system configurations added to the device.
+ * @cscfg_csdev_lock:	Protect the lists of configurations and features.
  */
 struct coresight_device {
 	struct coresight_platform_data *pdata;
@@ -241,6 +244,10 @@ struct coresight_device {
 	int nr_links;
 	bool has_conns_grp;
 	bool ect_enabled; /* true only if associated ect device is enabled */
+	/* system configuration and feature lists */
+	struct list_head feature_csdev_list;
+	struct list_head config_csdev_list;
+	spinlock_t cscfg_csdev_lock;
 };
 
 /*
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:14 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:14 -0600
Subject: [PATCH 03/11] coresight: config: Add configuration and feature
 generic functions
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-4-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Adds a set of generic support functions that allow devices to set and save
features values on the device, and enable and disable configurations.

Additional functions for other common operations including feature
reset.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-4-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 drivers/hwtracing/coresight/Makefile          |   2 +-
 .../hwtracing/coresight/coresight-config.c    | 272 ++++++++++++++++++
 .../hwtracing/coresight/coresight-config.h    |   9 +
 .../hwtracing/coresight/coresight-syscfg.c    |   3 +-
 4 files changed, 284 insertions(+), 2 deletions(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-config.c

diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 3d037f17aade..63ecfc3cf66d 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -4,7 +4,7 @@
 #
 obj-$(CONFIG_CORESIGHT) += coresight.o
 coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
-		coresight-sysfs.o coresight-syscfg.o
+		coresight-sysfs.o coresight-syscfg.o coresight-config.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
 coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
 		      coresight-tmc-etr.o
diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c
new file mode 100644
index 000000000000..4723bf7402a2
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-config.c
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2020 Linaro Limited. All rights reserved.
+ * Author: Mike Leach <mike.leach at linaro.org>
+ */
+
+#include <linux/sysfs.h>
+#include "coresight-config.h"
+#include "coresight-priv.h"
+
+/*
+ * This provides a set of generic functions that operate on configurations
+ * and features to manage the handling of parameters, the programming and
+ * saving of registers used by features on devices.
+ */
+
+/*
+ * Write the value held in the register structure into the driver internal memory
+ * location.
+ */
+static void cscfg_set_reg(struct cscfg_regval_csdev *reg_csdev)
+{
+	u32 *p_val32 = (u32 *)reg_csdev->driver_regval;
+	u32 tmp32 = reg_csdev->reg_desc.val32;
+
+	if (reg_csdev->reg_desc.type & CS_CFG_REG_TYPE_VAL_64BIT) {
+		*((u64 *)reg_csdev->driver_regval) = reg_csdev->reg_desc.val64;
+		return;
+	}
+
+	if (reg_csdev->reg_desc.type & CS_CFG_REG_TYPE_VAL_MASK) {
+		tmp32 = *p_val32;
+		tmp32 &= ~reg_csdev->reg_desc.mask32;
+		tmp32 |= reg_csdev->reg_desc.val32 & reg_csdev->reg_desc.mask32;
+	}
+	*p_val32 = tmp32;
+}
+
+/*
+ * Read the driver value into the reg if this is marked as one we want to save.
+ */
+static void cscfg_save_reg(struct cscfg_regval_csdev *reg_csdev)
+{
+	if (!(reg_csdev->reg_desc.type & CS_CFG_REG_TYPE_VAL_SAVE))
+		return;
+	if (reg_csdev->reg_desc.type & CS_CFG_REG_TYPE_VAL_64BIT)
+		reg_csdev->reg_desc.val64 = *(u64 *)(reg_csdev->driver_regval);
+	else
+		reg_csdev->reg_desc.val32 = *(u32 *)(reg_csdev->driver_regval);
+}
+
+/*
+ * Some register values are set from parameters. Initialise these registers
+ * from the current parameter values.
+ */
+static void cscfg_init_reg_param(struct cscfg_feature_csdev *feat_csdev,
+				 struct cscfg_regval_desc *reg_desc,
+				 struct cscfg_regval_csdev *reg_csdev)
+{
+	struct cscfg_parameter_csdev *param_csdev;
+
+	/* for param, load routines have validated the index */
+	param_csdev = &feat_csdev->params_csdev[reg_desc->param_idx];
+	param_csdev->reg_csdev = reg_csdev;
+	param_csdev->val64 = reg_csdev->reg_desc.type & CS_CFG_REG_TYPE_VAL_64BIT;
+
+	if (param_csdev->val64)
+		reg_csdev->reg_desc.val64 = param_csdev->current_value;
+	else
+		reg_csdev->reg_desc.val32 = (u32)param_csdev->current_value;
+}
+
+/* set values into the driver locations referenced in cscfg_reg_csdev */
+static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat_csdev)
+{
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
+	for (i = 0; i < feat_csdev->nr_regs; i++)
+		cscfg_set_reg(&feat_csdev->regs_csdev[i]);
+	spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+	dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
+		feat_csdev->feat_desc->name, "set on enable");
+	return 0;
+}
+
+/* copy back values from the driver locations referenced in cscfg_reg_csdev */
+static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat_csdev)
+{
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
+	for (i = 0; i < feat_csdev->nr_regs; i++)
+		cscfg_save_reg(&feat_csdev->regs_csdev[i]);
+	spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+	dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
+		feat_csdev->feat_desc->name, "save on disable");
+}
+
+/* default reset - restore default values */
+void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev)
+{
+	struct cscfg_regval_desc *reg_desc;
+	struct cscfg_regval_csdev *reg_csdev;
+	int i;
+
+	/*
+	 * set the default values for all parameters and regs from the
+	 * relevant static descriptors.
+	 */
+	for (i = 0; i < feat_csdev->nr_params; i++)
+		feat_csdev->params_csdev[i].current_value =
+			feat_csdev->feat_desc->params_desc[i].value;
+
+	for (i = 0; i < feat_csdev->nr_regs; i++) {
+		reg_desc = &feat_csdev->feat_desc->regs_desc[i];
+		reg_csdev = &feat_csdev->regs_csdev[i];
+		reg_csdev->reg_desc.type = reg_desc->type;
+
+		/* check if reg set from a parameter otherwise desc default */
+		if (reg_desc->type & CS_CFG_REG_TYPE_VAL_PARAM)
+			cscfg_init_reg_param(feat_csdev, reg_desc, reg_csdev);
+		else
+			/*
+			 * for normal values the union between val64 & val32 + mask32
+			 * allows us to init using the 64 bit value
+			 */
+			reg_csdev->reg_desc.val64 = reg_desc->val64;
+	}
+}
+
+/*
+ * For the selected presets, we set the register associated with the parameter, to
+ * the value of the preset index associated with the parameter.
+ */
+static int cscfg_update_presets(struct cscfg_config_csdev *config_csdev, int preset)
+{
+	int i, j, val_idx = 0, nr_cfg_params;
+	struct cscfg_parameter_csdev *param_csdev;
+	struct cscfg_feature_csdev *feat_csdev;
+	const struct cscfg_config_desc *config_desc = config_csdev->config_desc;
+	const char *name;
+	const u64 *preset_base;
+	u64 val;
+
+	/* preset in range 1 to nr_presets */
+	if (preset < 1 || preset > config_desc->nr_presets)
+		return -EINVAL;
+	/*
+	 * Go through the array of features, assigning preset values to
+	 * feature parameters in the order they appear.
+	 * There should be precisely the same number of preset values as the
+	 * sum of number of parameters over all the features - but we will
+	 * ensure there is no overrun.
+	 */
+	nr_cfg_params = config_desc->nr_total_params;
+	preset_base = &config_desc->presets[(preset - 1) * nr_cfg_params];
+	for (i = 0; i < config_csdev->nr_feat; i++) {
+		feat_csdev = config_csdev->feats_csdev[i];
+		if (!feat_csdev->nr_params)
+			continue;
+
+		for (j = 0; j < feat_csdev->nr_params; j++) {
+			param_csdev = &feat_csdev->params_csdev[j];
+			name = feat_csdev->feat_desc->params_desc[j].name;
+			val = preset_base[val_idx++];
+			if (param_csdev->val64) {
+				dev_dbg(&config_csdev->csdev->dev,
+					"set param %s (%lld)", name, val);
+				param_csdev->reg_csdev->reg_desc.val64 = val;
+			} else {
+				param_csdev->reg_csdev->reg_desc.val32 = (u32)val;
+				dev_dbg(&config_csdev->csdev->dev,
+					"set param %s (%d)", name, (u32)val);
+			}
+		}
+
+		/* exit early if all params filled */
+		if (val_idx >= nr_cfg_params)
+			break;
+	}
+	return 0;
+}
+
+/*
+ * if we are not using a preset, then need to update the feature params
+ * with current values. This sets the register associated with the parameter
+ * with the current value of that parameter.
+ */
+static int cscfg_update_curr_params(struct cscfg_config_csdev *config_csdev)
+{
+	int i, j;
+	struct cscfg_feature_csdev *feat_csdev;
+	struct cscfg_parameter_csdev *param_csdev;
+	const char *name;
+	u64 val;
+
+	for (i = 0; i < config_csdev->nr_feat; i++) {
+		feat_csdev = config_csdev->feats_csdev[i];
+		if (!feat_csdev->nr_params)
+			continue;
+		for (j = 0; j < feat_csdev->nr_params; j++) {
+			param_csdev = &feat_csdev->params_csdev[j];
+			name = feat_csdev->feat_desc->params_desc[j].name;
+			val = param_csdev->current_value;
+			if (param_csdev->val64) {
+				dev_dbg(&config_csdev->csdev->dev,
+					"set param %s (%lld)", name, val);
+				param_csdev->reg_csdev->reg_desc.val64 = val;
+			} else {
+				param_csdev->reg_csdev->reg_desc.val32 = (u32)val;
+				dev_dbg(&config_csdev->csdev->dev,
+					"set param %s (%d)", name, (u32)val);
+			}
+		}
+	}
+	return 0;
+}
+
+/*
+ * Configuration values will be programmed into the driver locations if enabling, or read
+ * from relevant locations on disable.
+ */
+static int cscfg_prog_config(struct cscfg_config_csdev *config_csdev, bool enable)
+{
+	int i, err = 0;
+	struct cscfg_feature_csdev *feat_csdev;
+	struct coresight_device *csdev;
+
+	for (i = 0; i < config_csdev->nr_feat; i++) {
+		feat_csdev = config_csdev->feats_csdev[i];
+		csdev = feat_csdev->csdev;
+		dev_dbg(&csdev->dev, "cfg %s;  %s feature:%s", config_csdev->config_desc->name,
+			enable ? "enable" : "disable", feat_csdev->feat_desc->name);
+
+		if (enable)
+			err = cscfg_set_on_enable(feat_csdev);
+		else
+			cscfg_save_on_disable(feat_csdev);
+
+		if (err)
+			break;
+	}
+	return err;
+}
+
+/*
+ * Enable configuration for the device. Will result in the internal driver data
+ * being updated ready for programming into the device.
+ *
+ * @config_csdev:	config_csdev to set.
+ * @preset:		preset values to use - 0 for default.
+ */
+int cscfg_csdev_enable_config(struct cscfg_config_csdev *config_csdev, int preset)
+{
+	int err = 0;
+
+	if (preset)
+		err = cscfg_update_presets(config_csdev, preset);
+	else
+		err = cscfg_update_curr_params(config_csdev);
+	if (!err)
+		err = cscfg_prog_config(config_csdev, true);
+	return err;
+}
+
+void cscfg_csdev_disable_config(struct cscfg_config_csdev *config_csdev)
+{
+	cscfg_prog_config(config_csdev, false);
+}
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 685fb46ce893..5a39cbbc38a4 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -237,4 +237,13 @@ struct cscfg_csdev_feat_ops {
 			 struct cscfg_feature_csdev *feat_csdev);
 };
 
+/* coresight config helper functions*/
+
+/* enable / disable config on a device - called with appropriate locks set.*/
+int cscfg_csdev_enable_config(struct cscfg_config_csdev *config_csdev, int preset);
+void cscfg_csdev_disable_config(struct cscfg_config_csdev *config_csdev);
+
+/* reset a feature to default values */
+void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev);
+
 #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 2c0d4906e226..5e4bd86f369e 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -189,7 +189,8 @@ static int cscfg_load_feat_csdev(struct coresight_device *csdev,
 	if (err)
 		return err;
 
-	/* add to internal csdev feature list */
+	/* add to internal csdev feature list & initialise using reset call */
+	cscfg_reset_feat(feat_csdev);
 	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
 	list_add(&feat_csdev->node, &csdev->feature_csdev_list);
 	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:16 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:16 -0600
Subject: [PATCH 05/11] coresight: syscfg: Add API to activate and enable
 configurations
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-6-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Configurations are first activated, then when any coresight device is
enabled, the active configurations are checked and any matching
one is enabled.

This patch provides the activation / enable API.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-6-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 .../hwtracing/coresight/coresight-config.h    |   2 +
 .../hwtracing/coresight/coresight-syscfg.c    | 215 ++++++++++++++++++
 .../hwtracing/coresight/coresight-syscfg.h    |   8 +
 include/linux/coresight.h                     |   2 +
 4 files changed, 227 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 0667581822c1..25eb6c632692 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -127,6 +127,7 @@ struct cscfg_feature_desc {
  * @nr_total_params:	Sum of all parameters declared by used features
  * @presets:		Array of preset values.
  * @event_ea:		Extended attribute for perf event value
+ * @active_cnt:		ref count for activate on this configuration.
  *
  */
 struct cscfg_config_desc {
@@ -139,6 +140,7 @@ struct cscfg_config_desc {
 	int nr_total_params;
 	const u64 *presets; /* nr_presets * nr_total_params */
 	struct dev_ext_attribute *event_ea;
+	atomic_t active_cnt;
 };
 
 /**
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index b93f2b4a777e..795dba576fea 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -282,6 +282,7 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc)
 		return err;
 
 	list_add(&config_desc->item, &cscfg_mgr->config_desc_list);
+	atomic_set(&config_desc->active_cnt, 0);
 	return 0;
 }
 
@@ -468,6 +469,219 @@ void cscfg_unregister_csdev(struct coresight_device *csdev)
 }
 EXPORT_SYMBOL_GPL(cscfg_unregister_csdev);
 
+/**
+ * cscfg_csdev_reset_feats - reset features for a CoreSight device.
+ *
+ * Resets all parameters and register values for any features loaded
+ * into @csdev to their default values.
+ *
+ * @csdev: The CoreSight device.
+ */
+void cscfg_csdev_reset_feats(struct coresight_device *csdev)
+{
+	struct cscfg_feature_csdev *feat_csdev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	if (list_empty(&csdev->feature_csdev_list))
+		goto unlock_exit;
+
+	list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node)
+		cscfg_reset_feat(feat_csdev);
+
+unlock_exit:
+	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+}
+EXPORT_SYMBOL_GPL(cscfg_csdev_reset_feats);
+
+/**
+ * cscfg_activate_config -  Mark a configuration descriptor as active.
+ *
+ * This will be seen when csdev devices are enabled in the system.
+ * Only activated configurations can be enabled on individual devices.
+ * Activation protects the configuration from alteration or removal while
+ * active.
+ *
+ * Selection by hash value - generated from the configuration name when it
+ * was loaded and added to the cs_etm/configurations file system for selection
+ * by perf.
+ *
+ * Increments the configuration descriptor active count and the global active
+ * count.
+ *
+ * @cfg_hash: Hash value of the selected configuration name.
+ */
+int cscfg_activate_config(unsigned long cfg_hash)
+{
+	struct cscfg_config_desc *config_desc;
+	int err = -EINVAL;
+
+	mutex_lock(&cscfg_mutex);
+
+	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
+		if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
+			/*
+			 * increment the global active count - control changes to
+			 * active configurations
+			 */
+			atomic_inc(&cscfg_mgr->sys_active_cnt);
+
+			/*
+			 * mark the descriptor as active so enable config on a
+			 * device instance will use it
+			 */
+			atomic_inc(&config_desc->active_cnt);
+
+			err = 0;
+			dev_dbg(cscfg_device(), "Activate config %s.\n", config_desc->name);
+			break;
+		}
+	}
+	mutex_unlock(&cscfg_mutex);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(cscfg_activate_config);
+
+/**
+ * cscfg_deactivate_config -  Mark a config descriptor as inactive.
+ *
+ * Decrement the configuration and global active counts.
+ *
+ * @cfg_hash: Hash value of the selected configuration name.
+ */
+void cscfg_deactivate_config(unsigned long cfg_hash)
+{
+	struct cscfg_config_desc *config_desc;
+
+	mutex_lock(&cscfg_mutex);
+
+	list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) {
+		if ((unsigned long)config_desc->event_ea->var == cfg_hash) {
+			atomic_dec(&config_desc->active_cnt);
+			atomic_dec(&cscfg_mgr->sys_active_cnt);
+			dev_dbg(cscfg_device(), "Deactivate config %s.\n", config_desc->name);
+			break;
+		}
+	}
+	mutex_unlock(&cscfg_mutex);
+}
+EXPORT_SYMBOL_GPL(cscfg_deactivate_config);
+
+/**
+ * cscfg_csdev_enable_active_config - Enable matching active configuration for device.
+ *
+ * Enables the configuration selected by @cfg_hash if the configuration is supported
+ * on the device and has been activated.
+ *
+ * If active and supported the CoreSight device @csdev will be programmed with the
+ * configuration, using @preset parameters.
+ *
+ * Should be called before driver hardware enable for the requested device, prior to
+ * programming and enabling the physical hardware.
+ *
+ * @csdev:	CoreSight device to program.
+ * @cfg_hash:	Selector for the configuration.
+ * @preset:	Preset parameter values to use, 0 for current / default values.
+ */
+int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
+				     unsigned long cfg_hash, int preset)
+{
+	struct cscfg_config_csdev *config_csdev_active = NULL, *config_csdev_item;
+	const struct cscfg_config_desc *config_desc;
+	unsigned long flags;
+	int err = 0;
+
+	/* quickly check global count */
+	if (!atomic_read(&cscfg_mgr->sys_active_cnt))
+		return 0;
+
+	/*
+	 * Look for matching configuration - set the active configuration
+	 * context if found.
+	 */
+	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	list_for_each_entry(config_csdev_item, &csdev->config_csdev_list, node) {
+		config_desc = config_csdev_item->config_desc;
+		if ((atomic_read(&config_desc->active_cnt)) &&
+		    ((unsigned long)config_desc->event_ea->var == cfg_hash)) {
+			config_csdev_active = config_csdev_item;
+			csdev->active_cscfg_ctxt = (void *)config_csdev_active;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+
+	/*
+	 * If found, attempt to enable
+	 */
+	if (config_csdev_active) {
+		/*
+		 * Call the generic routine that will program up the internal
+		 * driver structures prior to programming up the hardware.
+		 * This routine takes the driver spinlock saved in the configs.
+		 */
+		err = cscfg_csdev_enable_config(config_csdev_active, preset);
+		if (!err) {
+			/*
+			 * Successful programming. Check the active_cscfg_ctxt
+			 * pointer to ensure no pre-emption disabled it via
+			 * cscfg_csdev_disable_active_config() before
+			 * we could start.
+			 *
+			 * Set enabled if OK, err if not.
+			 */
+			spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+			if (csdev->active_cscfg_ctxt)
+				config_csdev_active->enabled = true;
+			else
+				err = -EBUSY;
+			spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+		}
+	}
+	return err;
+}
+EXPORT_SYMBOL_GPL(cscfg_csdev_enable_active_config);
+
+/**
+ * cscfg_csdev_disable_active_config - disable an active config on the device.
+ *
+ * Disables the active configuration on the CoreSight device @csdev.
+ * Disable will save the values of any registers marked in the configurations
+ * as save on disable.
+ *
+ * Should be called after driver hardware disable for the requested device,
+ * after disabling the physical hardware and reading back registers.
+ *
+ * @csdev: The CoreSight device.
+ */
+void cscfg_csdev_disable_active_config(struct coresight_device *csdev)
+{
+	struct cscfg_config_csdev *config_csdev;
+	unsigned long flags;
+
+	/*
+	 * Check if we have an active config, and that it was successfully enabled.
+	 * If it was not enabled, we have no work to do, otherwise mark as disabled.
+	 * Clear the active config pointer.
+	 */
+	spin_lock_irqsave(&csdev->cscfg_csdev_lock, flags);
+	config_csdev = (struct cscfg_config_csdev *)csdev->active_cscfg_ctxt;
+	if (config_csdev) {
+		if (!config_csdev->enabled)
+			config_csdev = NULL;
+		else
+			config_csdev->enabled = false;
+	}
+	csdev->active_cscfg_ctxt = NULL;
+	spin_unlock_irqrestore(&csdev->cscfg_csdev_lock, flags);
+
+	/* true if there was an enabled active config */
+	if (config_csdev)
+		cscfg_csdev_disable_config(config_csdev);
+}
+EXPORT_SYMBOL_GPL(cscfg_csdev_disable_active_config);
+
 /* Initialise system configuration management device. */
 
 struct device *cscfg_device(void)
@@ -536,6 +750,7 @@ int __init cscfg_init(void)
 	INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
 	INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
 	INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
+	atomic_set(&cscfg_mgr->sys_active_cnt, 0);
 
 	dev_info(cscfg_device(), "CoreSight Configuration manager initialised");
 	return 0;
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
index 5bcae3b374c6..a52775890670 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.h
+++ b/drivers/hwtracing/coresight/coresight-syscfg.h
@@ -24,12 +24,14 @@
  * @csdev_desc_list:	List of coresight devices registered with the configuration manager.
  * @feat_desc_list:	List of feature descriptors to load into registered devices.
  * @config_desc_list:	List of system configuration descriptors to load into registered devices.
+ * @sys_active_cnt:	Total number of active config descriptor references.
  */
 struct cscfg_manager {
 	struct device dev;
 	struct list_head csdev_desc_list;
 	struct list_head feat_desc_list;
 	struct list_head config_desc_list;
+	atomic_t sys_active_cnt;
 };
 
 /* get reference to dev in cscfg_manager */
@@ -61,5 +63,11 @@ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
 int cscfg_register_csdev(struct coresight_device *csdev, u32 match_flags,
 			 struct cscfg_csdev_feat_ops *ops);
 void cscfg_unregister_csdev(struct coresight_device *csdev);
+int cscfg_activate_config(unsigned long cfg_hash);
+void cscfg_deactivate_config(unsigned long cfg_hash);
+void cscfg_csdev_reset_feats(struct coresight_device *csdev);
+int cscfg_csdev_enable_active_config(struct coresight_device *csdev,
+				     unsigned long cfg_hash, int preset);
+void cscfg_csdev_disable_active_config(struct coresight_device *csdev);
 
 #endif /* CORESIGHT_SYSCFG_H */
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 16544ae2b532..93a2922b7653 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -223,6 +223,7 @@ struct coresight_sysfs_link {
  * @feature_csdev_list: List of complex feature programming added to the device.
  * @config_csdev_list:  List of system configurations added to the device.
  * @cscfg_csdev_lock:	Protect the lists of configurations and features.
+ * @active_cscfg_ctxt:  Context information for current active system configuration.
  */
 struct coresight_device {
 	struct coresight_platform_data *pdata;
@@ -248,6 +249,7 @@ struct coresight_device {
 	struct list_head feature_csdev_list;
 	struct list_head config_csdev_list;
 	spinlock_t cscfg_csdev_lock;
+	void *active_cscfg_ctxt;
 };
 
 /*
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:15 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:15 -0600
Subject: [PATCH 04/11] coresight: etm-perf: Update to handle configuration
 selection
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-5-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Loaded coresight configurations are registered in the cs_etm\events sub
directory. This extends the etm-perf code to handle these registrations,
and the cs_syscfg driver to perform the registration on load.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-5-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 .../hwtracing/coresight/coresight-config.h    |   2 +
 .../hwtracing/coresight/coresight-etm-perf.c  | 134 ++++++++++++++----
 .../hwtracing/coresight/coresight-etm-perf.h  |   8 ++
 .../hwtracing/coresight/coresight-syscfg.c    |  11 ++
 4 files changed, 127 insertions(+), 28 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 5a39cbbc38a4..0667581822c1 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -126,6 +126,7 @@ struct cscfg_feature_desc {
  * @nr_presets:		Number of sets of presets supplied by this configuration.
  * @nr_total_params:	Sum of all parameters declared by used features
  * @presets:		Array of preset values.
+ * @event_ea:		Extended attribute for perf event value
  *
  */
 struct cscfg_config_desc {
@@ -137,6 +138,7 @@ struct cscfg_config_desc {
 	int nr_presets;
 	int nr_total_params;
 	const u64 *presets; /* nr_presets * nr_total_params */
+	struct dev_ext_attribute *event_ea;
 };
 
 /**
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index b582e92cdea4..e42ab919ddc3 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -18,8 +18,10 @@
 #include <linux/types.h>
 #include <linux/workqueue.h>
 
+#include "coresight-config.h"
 #include "coresight-etm-perf.h"
 #include "coresight-priv.h"
+#include "coresight-syscfg.h"
 
 static struct pmu etm_pmu;
 static bool etm_perf_up;
@@ -57,8 +59,13 @@ PMU_FORMAT_ATTR(contextid1,	"config:" __stringify(ETM_OPT_CTXTID));
 PMU_FORMAT_ATTR(contextid2,	"config:" __stringify(ETM_OPT_CTXTID2));
 PMU_FORMAT_ATTR(timestamp,	"config:" __stringify(ETM_OPT_TS));
 PMU_FORMAT_ATTR(retstack,	"config:" __stringify(ETM_OPT_RETSTK));
+/* preset - if sink ID is used as a configuration selector */
+PMU_FORMAT_ATTR(preset,		"config:0-3");
 /* Sink ID - same for all ETMs */
 PMU_FORMAT_ATTR(sinkid,		"config2:0-31");
+/* config ID - set if a system configuration is selected */
+PMU_FORMAT_ATTR(configid,	"config2:32-63");
+
 
 /*
  * contextid always traces the "PID".  The PID is in CONTEXTIDR_EL1
@@ -88,6 +95,8 @@ static struct attribute *etm_config_formats_attr[] = {
 	&format_attr_timestamp.attr,
 	&format_attr_retstack.attr,
 	&format_attr_sinkid.attr,
+	&format_attr_preset.attr,
+	&format_attr_configid.attr,
 	NULL,
 };
 
@@ -105,9 +114,19 @@ static const struct attribute_group etm_pmu_sinks_group = {
 	.attrs  = etm_config_sinks_attr,
 };
 
+static struct attribute *etm_config_events_attr[] = {
+	NULL,
+};
+
+static const struct attribute_group etm_pmu_events_group = {
+	.name   = "events",
+	.attrs  = etm_config_events_attr,
+};
+
 static const struct attribute_group *etm_pmu_attr_groups[] = {
 	&etm_pmu_format_group,
 	&etm_pmu_sinks_group,
+	&etm_pmu_events_group,
 	NULL,
 };
 
@@ -286,7 +305,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
 	INIT_WORK(&event_data->work, free_event_data);
 
 	/* First get the selected sink from user space. */
-	if (event->attr.config2) {
+	if (event->attr.config2 & GENMASK_ULL(31, 0)) {
 		id = (u32)event->attr.config2;
 		sink = user_sink = coresight_get_sink_by_id(id);
 	}
@@ -658,68 +677,127 @@ static ssize_t etm_perf_sink_name_show(struct device *dev,
 	return scnprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)(ea->var));
 }
 
-int etm_perf_add_symlink_sink(struct coresight_device *csdev)
+static struct dev_ext_attribute *
+etm_perf_add_symlink_group(struct device *dev, const char *name, const char *group_name)
 {
-	int ret;
+	struct dev_ext_attribute *ea;
 	unsigned long hash;
-	const char *name;
+	int ret;
 	struct device *pmu_dev = etm_pmu.dev;
-	struct device *dev = &csdev->dev;
-	struct dev_ext_attribute *ea;
-
-	if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
-	    csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
-		return -EINVAL;
-
-	if (csdev->ea != NULL)
-		return -EINVAL;
 
 	if (!etm_perf_up)
-		return -EPROBE_DEFER;
+		return ERR_PTR(-EPROBE_DEFER);
 
 	ea = devm_kzalloc(dev, sizeof(*ea), GFP_KERNEL);
 	if (!ea)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	name = dev_name(dev);
-	/* See function coresight_get_sink_by_id() to know where this is used */
+	/*
+	 * If this function is called adding a sink then the hash is used for
+	 * sink selection - see function coresight_get_sink_by_id().
+	 * If adding a configuration then the hash is used for selection in
+	 * cscfg_activate_config()
+	 */
 	hash = hashlen_hash(hashlen_string(NULL, name));
 
 	sysfs_attr_init(&ea->attr.attr);
 	ea->attr.attr.name = devm_kstrdup(dev, name, GFP_KERNEL);
 	if (!ea->attr.attr.name)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	ea->attr.attr.mode = 0444;
-	ea->attr.show = etm_perf_sink_name_show;
 	ea->var = (unsigned long *)hash;
 
 	ret = sysfs_add_file_to_group(&pmu_dev->kobj,
-				      &ea->attr.attr, "sinks");
+				      &ea->attr.attr, group_name);
 
-	if (!ret)
-		csdev->ea = ea;
+	return ret ? ERR_PTR(ret) : ea;
+}
 
-	return ret;
+int etm_perf_add_symlink_sink(struct coresight_device *csdev)
+{
+	const char *name;
+	struct device *dev = &csdev->dev;
+	int err = 0;
+
+	if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
+	    csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
+		return -EINVAL;
+
+	if (csdev->ea != NULL)
+		return -EINVAL;
+
+	name = dev_name(dev);
+	csdev->ea = etm_perf_add_symlink_group(dev, name, "sinks");
+	if (IS_ERR(csdev->ea)) {
+		err = PTR_ERR(csdev->ea);
+		csdev->ea = NULL;
+	} else
+		csdev->ea->attr.show = etm_perf_sink_name_show;
+
+	return err;
 }
 
-void etm_perf_del_symlink_sink(struct coresight_device *csdev)
+static void etm_perf_del_symlink_group(struct dev_ext_attribute *ea, const char *group_name)
 {
 	struct device *pmu_dev = etm_pmu.dev;
-	struct dev_ext_attribute *ea = csdev->ea;
 
+	sysfs_remove_file_from_group(&pmu_dev->kobj,
+				     &ea->attr.attr, group_name);
+}
+
+void etm_perf_del_symlink_sink(struct coresight_device *csdev)
+{
 	if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
 	    csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
 		return;
 
-	if (!ea)
+	if (!csdev->ea)
 		return;
 
-	sysfs_remove_file_from_group(&pmu_dev->kobj,
-				     &ea->attr.attr, "sinks");
+	etm_perf_del_symlink_group(csdev->ea, "sinks");
 	csdev->ea = NULL;
 }
 
+static ssize_t etm_perf_cscfg_event_show(struct device *dev,
+					 struct device_attribute *dattr,
+					 char *buf)
+{
+	struct dev_ext_attribute *ea;
+
+	ea = container_of(dattr, struct dev_ext_attribute, attr);
+	return scnprintf(buf, PAGE_SIZE, "configid=0x%lx\n", (unsigned long)(ea->var));
+}
+
+int etm_perf_add_symlink_cscfg(struct device *dev, struct cscfg_config_desc *config_desc)
+{
+	int err = 0;
+
+	if (config_desc->event_ea != NULL)
+		return 0;
+
+	config_desc->event_ea = etm_perf_add_symlink_group(dev, config_desc->name, "events");
+
+	/* set the show function to the custom cscfg event */
+	if (!IS_ERR(config_desc->event_ea))
+		config_desc->event_ea->attr.show = etm_perf_cscfg_event_show;
+	else {
+		err = PTR_ERR(config_desc->event_ea);
+		config_desc->event_ea = NULL;
+	}
+
+	return err;
+}
+
+void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *config_desc)
+{
+	if (!config_desc->event_ea)
+		return;
+
+	etm_perf_del_symlink_group(config_desc->event_ea, "events");
+	config_desc->event_ea = NULL;
+}
+
 int __init etm_perf_init(void)
 {
 	int ret;
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h
index 29d90dfeba31..ba617fe2217e 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.h
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
@@ -11,6 +11,7 @@
 #include "coresight-priv.h"
 
 struct coresight_device;
+struct cscfg_config_desc;
 
 /*
  * In both ETMv3 and v4 the maximum number of address comparator implentable
@@ -69,6 +70,9 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle)
 		return data->snk_config;
 	return NULL;
 }
+int etm_perf_add_symlink_cscfg(struct device *dev,
+			       struct cscfg_config_desc *config_desc);
+void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *config_desc);
 #else
 static inline int etm_perf_symlink(struct coresight_device *csdev, bool link)
 { return -EINVAL; }
@@ -79,6 +83,10 @@ static inline void *etm_perf_sink_config(struct perf_output_handle *handle)
 {
 	return NULL;
 }
+int etm_perf_add_symlink_cscfg(struct device *dev,
+			       struct cscfg_config_desc *config_desc)
+{ return -EINVAL; }
+void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *config_desc) {}
 
 #endif /* CONFIG_CORESIGHT */
 
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 5e4bd86f369e..b93f2b4a777e 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -7,6 +7,7 @@
 #include <linux/platform_device.h>
 
 #include "coresight-config.h"
+#include "coresight-etm-perf.h"
 #include "coresight-syscfg.h"
 
 /*
@@ -275,6 +276,11 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc)
 	if (err)
 		return err;
 
+	/* add config to perf fs to allow selection */
+	err = etm_perf_add_symlink_cscfg(cscfg_device(), config_desc);
+	if (err)
+		return err;
+
 	list_add(&config_desc->item, &cscfg_mgr->config_desc_list);
 	return 0;
 }
@@ -508,7 +514,12 @@ static int cscfg_create_device(void)
 
 static void cscfg_clear_device(void)
 {
+	struct cscfg_config_desc *cfg_desc;
+
 	mutex_lock(&cscfg_mutex);
+	list_for_each_entry(cfg_desc, &cscfg_mgr->config_desc_list, item) {
+		etm_perf_del_symlink_cscfg(cfg_desc);
+	}
 	device_unregister(cscfg_device());
 	mutex_unlock(&cscfg_mutex);
 }
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:17 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:17 -0600
Subject: [PATCH 06/11] coresight: etm-perf: Update to activate selected
 configuration
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-7-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Add calls to activate the selected configuration as perf starts
and stops the tracing session.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Link: https://lore.kernel.org/r/20210723165444.1048-7-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm-perf.c | 14 +++++++++++++-
 drivers/hwtracing/coresight/coresight-etm-perf.h |  2 ++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index e42ab919ddc3..8ebd728d3a80 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -215,6 +215,10 @@ static void free_event_data(struct work_struct *work)
 	/* Free the sink buffers, if there are any */
 	free_sink_buffer(event_data);
 
+	/* clear any configuration we were using */
+	if (event_data->cfg_hash)
+		cscfg_deactivate_config(event_data->cfg_hash);
+
 	for_each_cpu(cpu, mask) {
 		struct list_head **ppath;
 
@@ -292,7 +296,7 @@ static bool sinks_compatible(struct coresight_device *a,
 static void *etm_setup_aux(struct perf_event *event, void **pages,
 			   int nr_pages, bool overwrite)
 {
-	u32 id;
+	u32 id, cfg_hash;
 	int cpu = event->cpu;
 	cpumask_t *mask;
 	struct coresight_device *sink = NULL;
@@ -310,6 +314,14 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
 		sink = user_sink = coresight_get_sink_by_id(id);
 	}
 
+	/* check if user wants a coresight configuration selected */
+	cfg_hash = (u32)((event->attr.config2 & GENMASK_ULL(63, 32)) >> 32);
+	if (cfg_hash) {
+		if (cscfg_activate_config(cfg_hash))
+			goto err;
+		event_data->cfg_hash = cfg_hash;
+	}
+
 	mask = &event_data->mask;
 
 	/*
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h
index ba617fe2217e..468f7799ab4f 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.h
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
@@ -49,12 +49,14 @@ struct etm_filters {
  * @work:		Handle to free allocated memory outside IRQ context.
  * @mask:		Hold the CPU(s) this event was set for.
  * @snk_config:		The sink configuration.
+ * @cfg_hash:		The hash id of any coresight config selected.
  * @path:		An array of path, each slot for one CPU.
  */
 struct etm_event_data {
 	struct work_struct work;
 	cpumask_t mask;
 	void *snk_config;
+	u32 cfg_hash;
 	struct list_head * __percpu *path;
 };
 
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:18 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:18 -0600
Subject: [PATCH 07/11] coresight: etm4x: Add complex configuration handlers to
 etmv4
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-8-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Adds in handlers to allow the ETMv4 to use the complex configuration
support. Features and configurations can be loaded and selected in the
device.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-8-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 drivers/hwtracing/coresight/Makefile          |   3 +-
 .../hwtracing/coresight/coresight-etm4x-cfg.c | 182 ++++++++++++++++++
 .../hwtracing/coresight/coresight-etm4x-cfg.h |  15 ++
 .../coresight/coresight-etm4x-core.c          |  38 +++-
 .../coresight/coresight-etm4x-sysfs.c         |   3 +
 5 files changed, 238 insertions(+), 3 deletions(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.c
 create mode 100644 drivers/hwtracing/coresight/coresight-etm4x-cfg.h

diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 63ecfc3cf66d..9420d33b23ac 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -16,7 +16,8 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o
 coresight-etm3x-y := coresight-etm3x-core.o coresight-etm-cp14.o \
 		     coresight-etm3x-sysfs.o
 obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o
-coresight-etm4x-y := coresight-etm4x-core.o coresight-etm4x-sysfs.o
+coresight-etm4x-y := coresight-etm4x-core.o coresight-etm4x-sysfs.o \
+			coresight-etm4x-cfg.o
 obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
 obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
 obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
new file mode 100644
index 000000000000..d2ea903231b2
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2020 Linaro Limited. All rights reserved.
+ * Author: Mike Leach <mike.leach at linaro.org>
+ */
+
+#include "coresight-etm4x.h"
+#include "coresight-etm4x-cfg.h"
+#include "coresight-priv.h"
+#include "coresight-syscfg.h"
+
+/* defines to associate register IDs with driver data locations */
+#define CHECKREG(cval, elem) \
+	{ \
+		if (offset == cval) { \
+			reg_csdev->driver_regval = &drvcfg->elem; \
+			err = 0; \
+			break; \
+		} \
+	}
+
+#define CHECKREGIDX(cval, elem, off_idx, mask)	\
+	{ \
+		if (mask == cval) { \
+			reg_csdev->driver_regval = &drvcfg->elem[off_idx]; \
+			err = 0; \
+			break; \
+		} \
+	}
+
+/**
+ * etm4_cfg_map_reg_offset - validate and map the register offset into a
+ *			     location in the driver config struct.
+ *
+ * Limits the number of registers that can be accessed and programmed in
+ * features, to those which are used to control the trace capture parameters.
+ *
+ * Omits or limits access to those which the driver must use exclusively.
+ *
+ * Invalid offsets will result in fail code return and feature load failure.
+ *
+ * @drvdata:	driver data to map into.
+ * @reg:	register to map.
+ * @offset:	device offset for the register
+ */
+static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
+				   struct cscfg_regval_csdev *reg_csdev, u32 offset)
+{
+	int err = -EINVAL, idx;
+	struct etmv4_config *drvcfg = &drvdata->config;
+	u32 off_mask;
+
+	if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) ||
+	    ((offset >= TRCSEQRSTEVR) && (offset <= TRCEXTINSELR)) ||
+	    ((offset >= TRCCIDCCTLR0) && (offset <= TRCVMIDCCTLR1))) {
+		do {
+			CHECKREG(TRCEVENTCTL0R, eventctrl0);
+			CHECKREG(TRCEVENTCTL1R, eventctrl1);
+			CHECKREG(TRCSTALLCTLR, stall_ctrl);
+			CHECKREG(TRCTSCTLR, ts_ctrl);
+			CHECKREG(TRCSYNCPR, syncfreq);
+			CHECKREG(TRCCCCTLR, ccctlr);
+			CHECKREG(TRCBBCTLR, bb_ctrl);
+			CHECKREG(TRCVICTLR, vinst_ctrl);
+			CHECKREG(TRCVIIECTLR, viiectlr);
+			CHECKREG(TRCVISSCTLR, vissctlr);
+			CHECKREG(TRCVIPCSSCTLR, vipcssctlr);
+			CHECKREG(TRCSEQRSTEVR, seq_rst);
+			CHECKREG(TRCSEQSTR, seq_state);
+			CHECKREG(TRCEXTINSELR, ext_inp);
+			CHECKREG(TRCCIDCCTLR0, ctxid_mask0);
+			CHECKREG(TRCCIDCCTLR1, ctxid_mask1);
+			CHECKREG(TRCVMIDCCTLR0, vmid_mask0);
+			CHECKREG(TRCVMIDCCTLR1, vmid_mask1);
+		} while (0);
+	} else if ((offset & GENMASK(11, 4)) == TRCSEQEVRn(0)) {
+		/* sequencer state control registers */
+		idx = (offset & GENMASK(3, 0)) / 4;
+		if (idx < ETM_MAX_SEQ_STATES) {
+			reg_csdev->driver_regval = &drvcfg->seq_ctrl[idx];
+			err = 0;
+		}
+	} else if ((offset >= TRCSSCCRn(0)) && (offset <= TRCSSPCICRn(7))) {
+		/* 32 bit, 8 off indexed register sets */
+		idx = (offset & GENMASK(4, 0)) / 4;
+		off_mask =  (offset & GENMASK(11, 5));
+		do {
+			CHECKREGIDX(TRCSSCCRn(0), ss_ctrl, idx, off_mask);
+			CHECKREGIDX(TRCSSCSRn(0), ss_status, idx, off_mask);
+			CHECKREGIDX(TRCSSPCICRn(0), ss_pe_cmp, idx, off_mask);
+		} while (0);
+	} else if ((offset >= TRCCIDCVRn(0)) && (offset <= TRCVMIDCVRn(7))) {
+		/* 64 bit, 8 off indexed register sets */
+		idx = (offset & GENMASK(5, 0)) / 8;
+		off_mask = (offset & GENMASK(11, 6));
+		do {
+			CHECKREGIDX(TRCCIDCVRn(0), ctxid_pid, idx, off_mask);
+			CHECKREGIDX(TRCVMIDCVRn(0), vmid_val, idx, off_mask);
+		} while (0);
+	} else if ((offset >= TRCRSCTLRn(2)) &&
+		   (offset <= TRCRSCTLRn((ETM_MAX_RES_SEL - 1)))) {
+		/* 32 bit resource selection regs, 32 off, skip fixed 0,1 */
+		idx = (offset & GENMASK(6, 0)) / 4;
+		if (idx < ETM_MAX_RES_SEL) {
+			reg_csdev->driver_regval = &drvcfg->res_ctrl[idx];
+			err = 0;
+		}
+	} else if ((offset >= TRCACVRn(0)) &&
+		   (offset <= TRCACATRn((ETM_MAX_SINGLE_ADDR_CMP - 1)))) {
+		/* 64 bit addr cmp regs, 16 off */
+		idx = (offset & GENMASK(6, 0)) / 8;
+		off_mask = offset & GENMASK(11, 7);
+		do {
+			CHECKREGIDX(TRCACVRn(0), addr_val, idx, off_mask);
+			CHECKREGIDX(TRCACATRn(0), addr_acc, idx, off_mask);
+		} while (0);
+	} else if ((offset >= TRCCNTRLDVRn(0)) &&
+		   (offset <= TRCCNTVRn((ETMv4_MAX_CNTR - 1)))) {
+		/* 32 bit counter regs, 4 off (ETMv4_MAX_CNTR - 1) */
+		idx = (offset &  GENMASK(3, 0)) / 4;
+		off_mask = offset &  GENMASK(11, 4);
+		do {
+			CHECKREGIDX(TRCCNTRLDVRn(0), cntrldvr, idx, off_mask);
+			CHECKREGIDX(TRCCNTCTLRn(0), cntr_ctrl, idx, off_mask);
+			CHECKREGIDX(TRCCNTVRn(0), cntr_val, idx, off_mask);
+		} while (0);
+	}
+	return err;
+}
+
+/**
+ * etm4_cfg_load_feature - load a feature into a device instance.
+ *
+ * @csdev:	An ETMv4 CoreSight device.
+ * @feat:	The feature to be loaded.
+ *
+ * The function will load a feature instance into the device, checking that
+ * the register definitions are valid for the device.
+ *
+ * Parameter and register definitions will be converted into internal
+ * structures that are used to set the values in the driver when the
+ * feature is enabled for the device.
+ *
+ * The feature spinlock pointer is initialised to the same spinlock
+ * that the driver uses to protect the internal register values.
+ */
+static int etm4_cfg_load_feature(struct coresight_device *csdev,
+				 struct cscfg_feature_csdev *feat_csdev)
+{
+	struct device *dev = csdev->dev.parent;
+	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
+	const struct cscfg_feature_desc *feat_desc = feat_csdev->feat_desc;
+	u32 offset;
+	int i = 0, err = 0;
+
+	/*
+	 * essential we set the device spinlock - this is used in the generic
+	 * programming routines when copying values into the drvdata structures
+	 * via the pointers setup in etm4_cfg_map_reg_offset().
+	 */
+	feat_csdev->drv_spinlock = &drvdata->spinlock;
+
+	/* process the register descriptions */
+	for (i = 0; i < feat_csdev->nr_regs && !err; i++) {
+		offset = feat_desc->regs_desc[i].offset;
+		err = etm4_cfg_map_reg_offset(drvdata, &feat_csdev->regs_csdev[i], offset);
+	}
+	return err;
+}
+
+/* match information when loading configurations */
+#define CS_CFG_ETM4_MATCH_FLAGS	(CS_CFG_MATCH_CLASS_SRC_ALL | \
+				 CS_CFG_MATCH_CLASS_SRC_ETM4)
+
+int etm4_cscfg_register(struct coresight_device *csdev)
+{
+	struct cscfg_csdev_feat_ops ops;
+
+	ops.load_feat = &etm4_cfg_load_feature;
+
+	return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops);
+}
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.h b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h
new file mode 100644
index 000000000000..a204ad9a4792
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_ETM4X_CFG_H
+#define _CORESIGHT_ETM4X_CFG_H
+
+#include "coresight-config.h"
+#include "coresight-etm4x.h"
+
+/* ETMv4 specific config functions */
+int etm4_cscfg_register(struct coresight_device *csdev);
+
+#endif /* CORESIGHT_ETM4X_CFG_H */
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index da27cd4a3c38..e24252eaf8e4 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -39,6 +39,8 @@
 
 #include "coresight-etm4x.h"
 #include "coresight-etm-perf.h"
+#include "coresight-etm4x-cfg.h"
+#include "coresight-syscfg.h"
 
 static int boot_enable;
 module_param(boot_enable, int, 0444);
@@ -561,12 +563,15 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata)
 	return ret;
 }
 
-static int etm4_parse_event_config(struct etmv4_drvdata *drvdata,
+static int etm4_parse_event_config(struct coresight_device *csdev,
 				   struct perf_event *event)
 {
 	int ret = 0;
+	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	struct etmv4_config *config = &drvdata->config;
 	struct perf_event_attr *attr = &event->attr;
+	unsigned long cfg_hash;
+	int preset;
 
 	/* Clear configuration from previous run */
 	memset(config, 0, sizeof(struct etmv4_config));
@@ -632,6 +637,20 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata,
 		/* bit[12], Return stack enable bit */
 		config->cfg |= BIT(12);
 
+	/*
+	 * Set any selected configuration and preset.
+	 *
+	 * This extracts the values of PMU_FORMAT_ATTR(configid) and PMU_FORMAT_ATTR(preset)
+	 * in the perf attributes defined in coresight-etm-perf.c.
+	 * configid uses bits 63:32 of attr->config2, preset uses bits 3:0 of attr->config.
+	 * A zero configid means no configuration active, preset = 0 means no preset selected.
+	 */
+	if (attr->config2 & GENMASK_ULL(63, 32)) {
+		cfg_hash = (u32)(attr->config2 >> 32);
+		preset = attr->config & 0xF;
+		ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
+	}
+
 out:
 	return ret;
 }
@@ -648,7 +667,7 @@ static int etm4_enable_perf(struct coresight_device *csdev,
 	}
 
 	/* Configure the tracer based on the session's specifics */
-	ret = etm4_parse_event_config(drvdata, event);
+	ret = etm4_parse_event_config(csdev, event);
 	if (ret)
 		goto out;
 	/* And enable it */
@@ -794,11 +813,18 @@ static int etm4_disable_perf(struct coresight_device *csdev,
 	u32 control;
 	struct etm_filters *filters = event->hw.addr_filters;
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	struct perf_event_attr *attr = &event->attr;
 
 	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
 		return -EINVAL;
 
 	etm4_disable_hw(drvdata);
+	/*
+	 * The config_id occupies bits 63:32 of the config2 perf event attr
+	 * field. If this is non-zero then we will have enabled a config.
+	 */
+	if (attr->config2 & GENMASK_ULL(63, 32))
+		cscfg_csdev_disable_active_config(csdev);
 
 	/*
 	 * Check if the start/stop logic was active when the unit was stopped.
@@ -1939,6 +1965,13 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
 		return ret;
 	}
 
+	/* register with config infrastructure & load any current features */
+	ret = etm4_cscfg_register(drvdata->csdev);
+	if (ret) {
+		coresight_unregister(drvdata->csdev);
+		return ret;
+	}
+
 	etmdrvdata[drvdata->cpu] = drvdata;
 
 	dev_info(&drvdata->csdev->dev, "CPU%d: %s v%d.%d initialized\n",
@@ -2025,6 +2058,7 @@ static int __exit etm4_remove_dev(struct etmv4_drvdata *drvdata)
 
 	cpus_read_unlock();
 
+	cscfg_unregister_csdev(drvdata->csdev);
 	coresight_unregister(drvdata->csdev);
 
 	return 0;
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 007bad9e7ad8..a0640fa5c55b 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -9,6 +9,7 @@
 #include <linux/sysfs.h>
 #include "coresight-etm4x.h"
 #include "coresight-priv.h"
+#include "coresight-syscfg.h"
 
 static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude)
 {
@@ -269,6 +270,8 @@ static ssize_t reset_store(struct device *dev,
 
 	spin_unlock(&drvdata->spinlock);
 
+	cscfg_csdev_reset_feats(to_coresight_device(dev));
+
 	return size;
 }
 static DEVICE_ATTR_WO(reset);
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:19 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:19 -0600
Subject: [PATCH 08/11] coresight: config: Add preloaded configurations
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-9-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Preload set of configurations.

This patch creates a small set of preloaded configurations and features
that are available immediately after coresight has been initialised.

The current set provides a strobing feature for ETMv4, that creates a
periodic sampling of trace by switching trace generation on and off
using counters in the ETM.

A configuration called "autofdo" is also provided that uses the 'strobing'
feature and provides a couple of preset values, selectable on the perf
command line.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-9-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 drivers/hwtracing/coresight/Makefile          |   3 +-
 .../hwtracing/coresight/coresight-cfg-afdo.c  | 153 ++++++++++++++++++
 .../coresight/coresight-cfg-preload.c         |  31 ++++
 .../coresight/coresight-cfg-preload.h         |  13 ++
 .../hwtracing/coresight/coresight-etm4x-cfg.h |  15 ++
 .../hwtracing/coresight/coresight-syscfg.c    |   9 ++
 .../hwtracing/coresight/coresight-syscfg.h    |   1 +
 7 files changed, 224 insertions(+), 1 deletion(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-afdo.c
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.c
 create mode 100644 drivers/hwtracing/coresight/coresight-cfg-preload.h

diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 9420d33b23ac..ad44f0fe3069 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -4,7 +4,8 @@
 #
 obj-$(CONFIG_CORESIGHT) += coresight.o
 coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
-		coresight-sysfs.o coresight-syscfg.o coresight-config.o
+		coresight-sysfs.o coresight-syscfg.o coresight-config.o \
+		coresight-cfg-preload.o coresight-cfg-afdo.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
 coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
 		      coresight-tmc-etr.o
diff --git a/drivers/hwtracing/coresight/coresight-cfg-afdo.c b/drivers/hwtracing/coresight/coresight-cfg-afdo.c
new file mode 100644
index 000000000000..84b31184252b
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-cfg-afdo.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2020 Linaro Limited. All rights reserved.
+ * Author: Mike Leach <mike.leach at linaro.org>
+ */
+
+#include "coresight-config.h"
+
+/* ETMv4 includes and features */
+#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
+#include "coresight-etm4x-cfg.h"
+
+/* preload configurations and features */
+
+/* preload in features for ETMv4 */
+
+/* strobe feature */
+static struct cscfg_parameter_desc strobe_params[] = {
+	{
+		.name = "window",
+		.value = 5000,
+	},
+	{
+		.name = "period",
+		.value = 10000,
+	},
+};
+
+static struct cscfg_regval_desc strobe_regs[] = {
+	/* resource selectors */
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCRSCTLRn(2),
+		.hw_info = ETM4_CFG_RES_SEL,
+		.val32 = 0x20001,
+	},
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCRSCTLRn(3),
+		.hw_info = ETM4_CFG_RES_SEQ,
+		.val32 = 0x20002,
+	},
+	/* strobe window counter 0 - reload from param 0 */
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_SAVE,
+		.offset = TRCCNTVRn(0),
+		.hw_info = ETM4_CFG_RES_CTR,
+	},
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM,
+		.offset = TRCCNTRLDVRn(0),
+		.hw_info = ETM4_CFG_RES_CTR,
+		.val32 = 0,
+	},
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCCNTCTLRn(0),
+		.hw_info = ETM4_CFG_RES_CTR,
+		.val32 = 0x10001,
+	},
+	/* strobe period counter 1 - reload from param 1 */
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_SAVE,
+		.offset = TRCCNTVRn(1),
+		.hw_info = ETM4_CFG_RES_CTR,
+	},
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE | CS_CFG_REG_TYPE_VAL_PARAM,
+		.offset = TRCCNTRLDVRn(1),
+		.hw_info = ETM4_CFG_RES_CTR,
+		.val32 = 1,
+	},
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCCNTCTLRn(1),
+		.hw_info = ETM4_CFG_RES_CTR,
+		.val32 = 0x8102,
+	},
+	/* sequencer */
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCSEQEVRn(0),
+		.hw_info = ETM4_CFG_RES_SEQ,
+		.val32 = 0x0081,
+	},
+	{
+		.type = CS_CFG_REG_TYPE_RESOURCE,
+		.offset = TRCSEQEVRn(1),
+		.hw_info = ETM4_CFG_RES_SEQ,
+		.val32 = 0x0000,
+	},
+	/* view-inst */
+	{
+		.type = CS_CFG_REG_TYPE_STD | CS_CFG_REG_TYPE_VAL_MASK,
+		.offset = TRCVICTLR,
+		.val32 = 0x0003,
+		.mask32 = 0x0003,
+	},
+	/* end of regs */
+};
+
+struct cscfg_feature_desc strobe_etm4x = {
+	.name = "strobing",
+	.description = "Generate periodic trace capture windows.\n"
+		       "parameter \'window\': a number of CPU cycles (W)\n"
+		       "parameter \'period\': trace enabled for W cycles every period x W cycles\n",
+	.match_flags = CS_CFG_MATCH_CLASS_SRC_ETM4,
+	.nr_params = ARRAY_SIZE(strobe_params),
+	.params_desc = strobe_params,
+	.nr_regs = ARRAY_SIZE(strobe_regs),
+	.regs_desc = strobe_regs,
+};
+
+/* create an autofdo configuration */
+
+/* we will provide 9 sets of preset parameter values */
+#define AFDO_NR_PRESETS	9
+/* the total number of parameters in used features */
+#define AFDO_NR_PARAMS	ARRAY_SIZE(strobe_params)
+
+static const char *afdo_ref_names[] = {
+	"strobing",
+};
+
+/*
+ * set of presets leaves strobing window constant while varying period to allow
+ * experimentation with mark / space ratios for various workloads
+ */
+static u64 afdo_presets[AFDO_NR_PRESETS][AFDO_NR_PARAMS] = {
+	{ 5000, 2 },
+	{ 5000, 4 },
+	{ 5000, 8 },
+	{ 5000, 16 },
+	{ 5000, 64 },
+	{ 5000, 128 },
+	{ 5000, 512 },
+	{ 5000, 1024 },
+	{ 5000, 4096 },
+};
+
+struct cscfg_config_desc afdo_etm4x = {
+	.name = "autofdo",
+	.description = "Setup ETMs with strobing for autofdo\n"
+	"Supplied presets allow experimentation with mark-space ratio for various loads\n",
+	.nr_feat_refs = ARRAY_SIZE(afdo_ref_names),
+	.feat_ref_names = afdo_ref_names,
+	.nr_presets = AFDO_NR_PRESETS,
+	.nr_total_params = AFDO_NR_PARAMS,
+	.presets = &afdo_presets[0][0],
+};
+
+/* end of ETM4x configurations */
+#endif	/* IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) */
diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.c b/drivers/hwtracing/coresight/coresight-cfg-preload.c
new file mode 100644
index 000000000000..751af3710d56
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-cfg-preload.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(C) 2020 Linaro Limited. All rights reserved.
+ * Author: Mike Leach <mike.leach at linaro.org>
+ */
+
+#include "coresight-cfg-preload.h"
+#include "coresight-config.h"
+#include "coresight-syscfg.h"
+
+/* Basic features and configurations pre-loaded on initialisation */
+
+static struct cscfg_feature_desc *preload_feats[] = {
+#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
+	&strobe_etm4x,
+#endif
+	NULL
+};
+
+static struct cscfg_config_desc *preload_cfgs[] = {
+#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
+	&afdo_etm4x,
+#endif
+	NULL
+};
+
+/* preload called on initialisation */
+int cscfg_preload(void)
+{
+	return cscfg_load_config_sets(preload_cfgs, preload_feats);
+}
diff --git a/drivers/hwtracing/coresight/coresight-cfg-preload.h b/drivers/hwtracing/coresight/coresight-cfg-preload.h
new file mode 100644
index 000000000000..21299e175477
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-cfg-preload.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright(C) 2020 Linaro Limited. All rights reserved.
+ * Author: Mike Leach <mike.leach at linaro.org>
+ */
+
+/* declare preloaded configurations and features */
+
+/* from coresight-cfg-afdo.c - etm 4x features */
+#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
+extern struct cscfg_feature_desc strobe_etm4x;
+extern struct cscfg_config_desc afdo_etm4x;
+#endif
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.h b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h
index a204ad9a4792..32dab34c1dac 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.h
@@ -9,6 +9,21 @@
 #include "coresight-config.h"
 #include "coresight-etm4x.h"
 
+/* ETMv4 specific config defines */
+
+/* resource IDs */
+
+#define ETM4_CFG_RES_CTR	0x001
+#define ETM4_CFG_RES_CMP	0x002
+#define ETM4_CFG_RES_CMP_PAIR0	0x003
+#define ETM4_CFG_RES_CMP_PAIR1	0x004
+#define ETM4_CFG_RES_SEL	0x005
+#define ETM4_CFG_RES_SEL_PAIR0	0x006
+#define ETM4_CFG_RES_SEL_PAIR1	0x007
+#define ETM4_CFG_RES_SEQ	0x008
+#define ETM4_CFG_RES_TS		0x009
+#define ETM4_CFG_RES_MASK	0x00F
+
 /* ETMv4 specific config functions */
 int etm4_cscfg_register(struct coresight_device *csdev);
 
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 795dba576fea..c0f764d85f20 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -752,8 +752,17 @@ int __init cscfg_init(void)
 	INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
 	atomic_set(&cscfg_mgr->sys_active_cnt, 0);
 
+	/* preload built-in configurations */
+	err = cscfg_preload();
+	if (err)
+		goto exit_err;
+
 	dev_info(cscfg_device(), "CoreSight Configuration manager initialised");
 	return 0;
+
+exit_err:
+	cscfg_clear_device();
+	return err;
 }
 
 void cscfg_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
index a52775890670..7bb8c8e497ba 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.h
+++ b/drivers/hwtracing/coresight/coresight-syscfg.h
@@ -56,6 +56,7 @@ struct cscfg_registered_csdev {
 /* internal core operations for cscfg */
 int __init cscfg_init(void);
 void cscfg_exit(void);
+int cscfg_preload(void);
 
 /* syscfg manager external API */
 int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:20 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:20 -0600
Subject: [PATCH 09/11] coresight: syscfg: Add initial configfs support
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-10-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Adds configfs subsystem and attributes to the configuration manager
to enable the listing of loaded configurations and features.

The default values of feature parameters can be accessed and altered
from these attributes to affect all installed devices using the feature.

Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-10-mike.leach at linaro.org
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 drivers/hwtracing/coresight/Kconfig           |   1 +
 drivers/hwtracing/coresight/Makefile          |   3 +-
 .../coresight/coresight-syscfg-configfs.c     | 396 ++++++++++++++++++
 .../coresight/coresight-syscfg-configfs.h     |  45 ++
 .../hwtracing/coresight/coresight-syscfg.c    |  76 ++++
 .../hwtracing/coresight/coresight-syscfg.h    |   7 +
 6 files changed, 527 insertions(+), 1 deletion(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.c
 create mode 100644 drivers/hwtracing/coresight/coresight-syscfg-configfs.h

diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 84530fd80998..f026e5c0e777 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -8,6 +8,7 @@ menuconfig CORESIGHT
 	depends on OF || ACPI
 	select ARM_AMBA
 	select PERF_EVENTS
+	select CONFIGFS_FS
 	help
 	  This framework provides a kernel interface for the CoreSight debug
 	  and trace drivers to register themselves with. It's intended to build
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index ad44f0fe3069..b6c4a48140ec 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -5,7 +5,8 @@
 obj-$(CONFIG_CORESIGHT) += coresight.o
 coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
 		coresight-sysfs.o coresight-syscfg.o coresight-config.o \
-		coresight-cfg-preload.o coresight-cfg-afdo.o
+		coresight-cfg-preload.o coresight-cfg-afdo.o \
+		coresight-syscfg-configfs.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
 coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
 		      coresight-tmc-etr.o
diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
new file mode 100644
index 000000000000..c547816b9000
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
@@ -0,0 +1,396 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Linaro Limited, All rights reserved.
+ * Author: Mike Leach <mike.leach at linaro.org>
+ */
+
+#include <linux/configfs.h>
+
+#include "coresight-syscfg-configfs.h"
+
+/* create a default ci_type. */
+static inline struct config_item_type *cscfg_create_ci_type(void)
+{
+	struct config_item_type *ci_type;
+
+	ci_type = devm_kzalloc(cscfg_device(), sizeof(*ci_type), GFP_KERNEL);
+	if (ci_type)
+		ci_type->ct_owner = THIS_MODULE;
+
+	return ci_type;
+}
+
+/* configurations sub-group */
+
+/* attributes for the config view group */
+static ssize_t cscfg_cfg_description_show(struct config_item *item, char *page)
+{
+	struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
+							 struct cscfg_fs_config, group);
+
+	return scnprintf(page, PAGE_SIZE, "%s", fs_config->config_desc->description);
+}
+CONFIGFS_ATTR_RO(cscfg_cfg_, description);
+
+static ssize_t cscfg_cfg_feature_refs_show(struct config_item *item, char *page)
+{
+	struct cscfg_fs_config *fs_config = container_of(to_config_group(item),
+							 struct cscfg_fs_config, group);
+	const struct cscfg_config_desc *config_desc = fs_config->config_desc;
+	ssize_t ch_used = 0;
+	int i;
+
+	for (i = 0; i < config_desc->nr_feat_refs; i++)
+		ch_used += scnprintf(page + ch_used, PAGE_SIZE - ch_used,
+				     "%s\n", config_desc->feat_ref_names[i]);
+	return ch_used;
+}
+CONFIGFS_ATTR_RO(cscfg_cfg_, feature_refs);
+
+/* list preset values in order of features and params */
+static ssize_t cscfg_cfg_values_show(struct config_item *item, char *page)
+{
+	const struct cscfg_feature_desc *feat_desc;
+	const struct cscfg_config_desc *config_desc;
+	struct cscfg_fs_preset *fs_preset;
+	int i, j, val_idx, preset_idx;
+	ssize_t used = 0;
+
+	fs_preset = container_of(to_config_group(item), struct cscfg_fs_preset, group);
+	config_desc = fs_preset->config_desc;
+
+	if (!config_desc->nr_presets)
+		return 0;
+
+	preset_idx = fs_preset->preset_num - 1;
+
+	/* start index on the correct array line */
+	val_idx = config_desc->nr_total_params * preset_idx;
+
+	/*
+	 * A set of presets is the sum of all params in used features,
+	 * in order of declaration of features and params in the features
+	 */
+	for (i = 0; i < config_desc->nr_feat_refs; i++) {
+		feat_desc = cscfg_get_named_feat_desc(config_desc->feat_ref_names[i]);
+		for (j = 0; j < feat_desc->nr_params; j++) {
+			used += scnprintf(page + used, PAGE_SIZE - used,
+					  "%s.%s = 0x%llx ",
+					  feat_desc->name,
+					  feat_desc->params_desc[j].name,
+					  config_desc->presets[val_idx++]);
+		}
+	}
+	used += scnprintf(page + used, PAGE_SIZE - used, "\n");
+
+	return used;
+}
+CONFIGFS_ATTR_RO(cscfg_cfg_, values);
+
+static struct configfs_attribute *cscfg_config_view_attrs[] = {
+	&cscfg_cfg_attr_description,
+	&cscfg_cfg_attr_feature_refs,
+	NULL,
+};
+
+static struct config_item_type cscfg_config_view_type = {
+	.ct_owner = THIS_MODULE,
+	.ct_attrs = cscfg_config_view_attrs,
+};
+
+static struct configfs_attribute *cscfg_config_preset_attrs[] = {
+	&cscfg_cfg_attr_values,
+	NULL,
+};
+
+static struct config_item_type cscfg_config_preset_type = {
+	.ct_owner = THIS_MODULE,
+	.ct_attrs = cscfg_config_preset_attrs,
+};
+
+static int cscfg_add_preset_groups(struct cscfg_fs_config *cfg_view)
+{
+	int preset_num;
+	struct cscfg_fs_preset *cfg_fs_preset;
+	struct cscfg_config_desc *config_desc = cfg_view->config_desc;
+	char name[CONFIGFS_ITEM_NAME_LEN];
+
+	if (!config_desc->nr_presets)
+		return 0;
+
+	for (preset_num = 1; preset_num <= config_desc->nr_presets; preset_num++) {
+		cfg_fs_preset = devm_kzalloc(cscfg_device(),
+					     sizeof(struct cscfg_fs_preset), GFP_KERNEL);
+
+		if (!cfg_fs_preset)
+			return -ENOMEM;
+
+		snprintf(name, CONFIGFS_ITEM_NAME_LEN, "preset%d", preset_num);
+		cfg_fs_preset->preset_num = preset_num;
+		cfg_fs_preset->config_desc = cfg_view->config_desc;
+		config_group_init_type_name(&cfg_fs_preset->group, name,
+					    &cscfg_config_preset_type);
+		configfs_add_default_group(&cfg_fs_preset->group, &cfg_view->group);
+	}
+	return 0;
+}
+
+static struct config_group *cscfg_create_config_group(struct cscfg_config_desc *config_desc)
+{
+	struct cscfg_fs_config *cfg_view;
+	struct device *dev = cscfg_device();
+	int err;
+
+	if (!dev)
+		return ERR_PTR(-EINVAL);
+
+	cfg_view = devm_kzalloc(dev, sizeof(struct cscfg_fs_config), GFP_KERNEL);
+	if (!cfg_view)
+		return ERR_PTR(-ENOMEM);
+
+	cfg_view->config_desc = config_desc;
+	config_group_init_type_name(&cfg_view->group, config_desc->name, &cscfg_config_view_type);
+
+	/* add in a preset<n> dir for each preset */
+	err = cscfg_add_preset_groups(cfg_view);
+	if (err)
+		return ERR_PTR(err);
+
+	return &cfg_view->group;
+}
+
+/* attributes for features view */
+
+static ssize_t cscfg_feat_description_show(struct config_item *item, char *page)
+{
+	struct cscfg_fs_feature *fs_feat = container_of(to_config_group(item),
+							struct cscfg_fs_feature, group);
+
+	return scnprintf(page, PAGE_SIZE, "%s", fs_feat->feat_desc->description);
+}
+CONFIGFS_ATTR_RO(cscfg_feat_, description);
+
+static ssize_t cscfg_feat_matches_show(struct config_item *item, char *page)
+{
+	struct cscfg_fs_feature *fs_feat = container_of(to_config_group(item),
+							struct cscfg_fs_feature, group);
+	u32 match_flags = fs_feat->feat_desc->match_flags;
+	int used = 0;
+
+	if (match_flags & CS_CFG_MATCH_CLASS_SRC_ALL)
+		used = scnprintf(page, PAGE_SIZE, "SRC_ALL ");
+
+	if (match_flags & CS_CFG_MATCH_CLASS_SRC_ETM4)
+		used += scnprintf(page + used, PAGE_SIZE - used, "SRC_ETMV4 ");
+
+	used += scnprintf(page + used, PAGE_SIZE - used, "\n");
+	return used;
+}
+CONFIGFS_ATTR_RO(cscfg_feat_, matches);
+
+static ssize_t cscfg_feat_nr_params_show(struct config_item *item, char *page)
+{
+	struct cscfg_fs_feature *fs_feat = container_of(to_config_group(item),
+							struct cscfg_fs_feature, group);
+
+	return scnprintf(page, PAGE_SIZE, "%d\n", fs_feat->feat_desc->nr_params);
+}
+CONFIGFS_ATTR_RO(cscfg_feat_, nr_params);
+
+/* base feature desc attrib structures */
+static struct configfs_attribute *cscfg_feature_view_attrs[] = {
+	&cscfg_feat_attr_description,
+	&cscfg_feat_attr_matches,
+	&cscfg_feat_attr_nr_params,
+	NULL,
+};
+
+static struct config_item_type cscfg_feature_view_type = {
+	.ct_owner = THIS_MODULE,
+	.ct_attrs = cscfg_feature_view_attrs,
+};
+
+static ssize_t cscfg_param_value_show(struct config_item *item, char *page)
+{
+	struct cscfg_fs_param *param_item = container_of(to_config_group(item),
+							 struct cscfg_fs_param, group);
+	u64 value = param_item->feat_desc->params_desc[param_item->param_idx].value;
+
+	return scnprintf(page, PAGE_SIZE, "0x%llx\n", value);
+}
+
+static ssize_t cscfg_param_value_store(struct config_item *item,
+				       const char *page, size_t size)
+{
+	struct cscfg_fs_param *param_item = container_of(to_config_group(item),
+							 struct cscfg_fs_param, group);
+	struct cscfg_feature_desc *feat_desc = param_item->feat_desc;
+	int param_idx = param_item->param_idx;
+	u64 value;
+	int err;
+
+	err = kstrtoull(page, 0, &value);
+	if (!err)
+		err = cscfg_update_feat_param_val(feat_desc, param_idx, value);
+
+	return err ? err : size;
+}
+CONFIGFS_ATTR(cscfg_param_, value);
+
+static struct configfs_attribute *cscfg_param_view_attrs[] = {
+	&cscfg_param_attr_value,
+	NULL,
+};
+
+static struct config_item_type cscfg_param_view_type = {
+	.ct_owner = THIS_MODULE,
+	.ct_attrs = cscfg_param_view_attrs,
+};
+
+/*
+ * configfs has far less functionality provided to add attributes dynamically than sysfs,
+ * and the show and store fns pass the enclosing config_item so the actual attribute cannot
+ * be determined. Therefore we add each item as a group directory, with a value attribute.
+ */
+static int cscfg_create_params_group_items(struct cscfg_feature_desc *feat_desc,
+					   struct config_group *params_group)
+{
+	struct device *dev = cscfg_device();
+	struct cscfg_fs_param *param_item;
+	int i;
+
+	/* parameter items - as groups with default_value attribute */
+	for (i = 0; i < feat_desc->nr_params; i++) {
+		param_item = devm_kzalloc(dev, sizeof(struct cscfg_fs_param), GFP_KERNEL);
+		if (!param_item)
+			return -ENOMEM;
+		param_item->feat_desc = feat_desc;
+		param_item->param_idx = i;
+		config_group_init_type_name(&param_item->group,
+					    feat_desc->params_desc[i].name,
+					    &cscfg_param_view_type);
+		configfs_add_default_group(&param_item->group, params_group);
+	}
+	return 0;
+}
+
+static struct config_group *cscfg_create_feature_group(struct cscfg_feature_desc *feat_desc)
+{
+	struct cscfg_fs_feature *feat_view;
+	struct config_item_type *params_group_type;
+	struct config_group *params_group = NULL;
+	struct device *dev = cscfg_device();
+	int item_err;
+
+	if (!dev)
+		return ERR_PTR(-EINVAL);
+
+	feat_view = devm_kzalloc(dev, sizeof(struct cscfg_fs_feature), GFP_KERNEL);
+	if (!feat_view)
+		return ERR_PTR(-ENOMEM);
+
+	if (feat_desc->nr_params) {
+		params_group = devm_kzalloc(dev, sizeof(struct config_group), GFP_KERNEL);
+		if (!params_group)
+			return ERR_PTR(-ENOMEM);
+
+		params_group_type = cscfg_create_ci_type();
+		if (!params_group_type)
+			return ERR_PTR(-ENOMEM);
+	}
+
+	feat_view->feat_desc = feat_desc;
+	config_group_init_type_name(&feat_view->group,
+				    feat_desc->name,
+				    &cscfg_feature_view_type);
+	if (params_group) {
+		config_group_init_type_name(params_group, "params", params_group_type);
+		configfs_add_default_group(params_group, &feat_view->group);
+		item_err = cscfg_create_params_group_items(feat_desc, params_group);
+		if (item_err)
+			return ERR_PTR(item_err);
+	}
+	return &feat_view->group;
+}
+
+static struct config_item_type cscfg_configs_type = {
+	.ct_owner = THIS_MODULE,
+};
+
+static struct config_group cscfg_configs_grp = {
+	.cg_item = {
+		.ci_namebuf = "configurations",
+		.ci_type = &cscfg_configs_type,
+	},
+};
+
+/* add configuration to configurations group */
+int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc)
+{
+	struct config_group *new_group;
+	int err;
+
+	new_group = cscfg_create_config_group(config_desc);
+	if (IS_ERR(new_group))
+		return PTR_ERR(new_group);
+	err =  configfs_register_group(&cscfg_configs_grp, new_group);
+	return err;
+}
+
+static struct config_item_type cscfg_features_type = {
+	.ct_owner = THIS_MODULE,
+};
+
+static struct config_group cscfg_features_grp = {
+	.cg_item = {
+		.ci_namebuf = "features",
+		.ci_type = &cscfg_features_type,
+	},
+};
+
+/* add feature to features group */
+int cscfg_configfs_add_feature(struct cscfg_feature_desc *feat_desc)
+{
+	struct config_group *new_group;
+	int err;
+
+	new_group = cscfg_create_feature_group(feat_desc);
+	if (IS_ERR(new_group))
+		return PTR_ERR(new_group);
+	err =  configfs_register_group(&cscfg_features_grp, new_group);
+	return err;
+}
+
+int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr)
+{
+	struct configfs_subsystem *subsys;
+	struct config_item_type *ci_type;
+
+	if (!cscfg_mgr)
+		return -EINVAL;
+
+	ci_type = cscfg_create_ci_type();
+	if (!ci_type)
+		return -ENOMEM;
+
+	subsys = &cscfg_mgr->cfgfs_subsys;
+	config_item_set_name(&subsys->su_group.cg_item, CSCFG_FS_SUBSYS_NAME);
+	subsys->su_group.cg_item.ci_type = ci_type;
+
+	config_group_init(&subsys->su_group);
+	mutex_init(&subsys->su_mutex);
+
+	/* Add default groups to subsystem */
+	config_group_init(&cscfg_configs_grp);
+	configfs_add_default_group(&cscfg_configs_grp, &subsys->su_group);
+
+	config_group_init(&cscfg_features_grp);
+	configfs_add_default_group(&cscfg_features_grp, &subsys->su_group);
+
+	return configfs_register_subsystem(subsys);
+}
+
+void cscfg_configfs_release(struct cscfg_manager *cscfg_mgr)
+{
+	configfs_unregister_subsystem(&cscfg_mgr->cfgfs_subsys);
+}
diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h
new file mode 100644
index 000000000000..7d6ffe35ca4c
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Coresight system configuration driver - support for configfs.
+ */
+
+#ifndef CORESIGHT_SYSCFG_CONFIGFS_H
+#define CORESIGHT_SYSCFG_CONFIGFS_H
+
+#include <linux/configfs.h>
+#include "coresight-syscfg.h"
+
+#define CSCFG_FS_SUBSYS_NAME "cs-syscfg"
+
+/* container for configuration view */
+struct cscfg_fs_config {
+	struct cscfg_config_desc *config_desc;
+	struct config_group group;
+};
+
+/* container for feature view */
+struct cscfg_fs_feature {
+	struct cscfg_feature_desc *feat_desc;
+	struct config_group group;
+};
+
+/* container for parameter view */
+struct cscfg_fs_param {
+	int param_idx;
+	struct cscfg_feature_desc *feat_desc;
+	struct config_group group;
+};
+
+/* container for preset view */
+struct cscfg_fs_preset {
+	int preset_num;
+	struct cscfg_config_desc *config_desc;
+	struct config_group group;
+};
+
+int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr);
+void cscfg_configfs_release(struct cscfg_manager *cscfg_mgr);
+int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc);
+int cscfg_configfs_add_feature(struct cscfg_feature_desc *feat_desc);
+
+#endif /* CORESIGHT_SYSCFG_CONFIGFS_H */
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index c0f764d85f20..fc0760f55c53 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -9,6 +9,7 @@
 #include "coresight-config.h"
 #include "coresight-etm-perf.h"
 #include "coresight-syscfg.h"
+#include "coresight-syscfg-configfs.h"
 
 /*
  * cscfg_ API manages configurations and features for the entire coresight
@@ -286,6 +287,72 @@ static int cscfg_load_config(struct cscfg_config_desc *config_desc)
 	return 0;
 }
 
+/* get a feature descriptor by name */
+const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name)
+{
+	const struct cscfg_feature_desc *feat_desc = NULL, *feat_desc_item;
+
+	mutex_lock(&cscfg_mutex);
+
+	list_for_each_entry(feat_desc_item, &cscfg_mgr->feat_desc_list, item) {
+		if (strcmp(feat_desc_item->name, name) == 0) {
+			feat_desc = feat_desc_item;
+			break;
+		}
+	}
+
+	mutex_unlock(&cscfg_mutex);
+	return feat_desc;
+}
+
+/* called with cscfg_mutex held */
+static struct cscfg_feature_csdev *
+cscfg_csdev_get_feat_from_desc(struct coresight_device *csdev,
+			       struct cscfg_feature_desc *feat_desc)
+{
+	struct cscfg_feature_csdev *feat_csdev;
+
+	list_for_each_entry(feat_csdev, &csdev->feature_csdev_list, node) {
+		if (feat_csdev->feat_desc == feat_desc)
+			return feat_csdev;
+	}
+	return NULL;
+}
+
+int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
+				int param_idx, u64 value)
+{
+	int err = 0;
+	struct cscfg_feature_csdev *feat_csdev;
+	struct cscfg_registered_csdev *csdev_item;
+
+	mutex_lock(&cscfg_mutex);
+
+	/* check if any config active & return busy */
+	if (atomic_read(&cscfg_mgr->sys_active_cnt)) {
+		err = -EBUSY;
+		goto unlock_exit;
+	}
+
+	/* set the value */
+	if ((param_idx < 0) || (param_idx >= feat_desc->nr_params)) {
+		err = -EINVAL;
+		goto unlock_exit;
+	}
+	feat_desc->params_desc[param_idx].value = value;
+
+	/* update loaded instances.*/
+	list_for_each_entry(csdev_item, &cscfg_mgr->csdev_desc_list, item) {
+		feat_csdev = cscfg_csdev_get_feat_from_desc(csdev_item->csdev, feat_desc);
+		if (feat_csdev)
+			feat_csdev->params_csdev[param_idx].current_value = value;
+	}
+
+unlock_exit:
+	mutex_unlock(&cscfg_mutex);
+	return err;
+}
+
 /**
  * cscfg_load_config_sets - API function to load feature and config sets.
  *
@@ -307,6 +374,8 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
 	if (feat_descs) {
 		while (feat_descs[i]) {
 			err = cscfg_load_feat(feat_descs[i]);
+			if (!err)
+				err = cscfg_configfs_add_feature(feat_descs[i]);
 			if (err) {
 				pr_err("coresight-syscfg: Failed to load feature %s\n",
 				       feat_descs[i]->name);
@@ -321,6 +390,8 @@ int cscfg_load_config_sets(struct cscfg_config_desc **config_descs,
 	if (config_descs) {
 		while (config_descs[i]) {
 			err = cscfg_load_config(config_descs[i]);
+			if (!err)
+				err = cscfg_configfs_add_config(config_descs[i]);
 			if (err) {
 				pr_err("coresight-syscfg: Failed to load configuration %s\n",
 				       config_descs[i]->name);
@@ -734,6 +805,7 @@ static void cscfg_clear_device(void)
 	list_for_each_entry(cfg_desc, &cscfg_mgr->config_desc_list, item) {
 		etm_perf_del_symlink_cscfg(cfg_desc);
 	}
+	cscfg_configfs_release(cscfg_mgr);
 	device_unregister(cscfg_device());
 	mutex_unlock(&cscfg_mutex);
 }
@@ -747,6 +819,10 @@ int __init cscfg_init(void)
 	if (err)
 		return err;
 
+	err = cscfg_configfs_init(cscfg_mgr);
+	if (err)
+		goto exit_err;
+
 	INIT_LIST_HEAD(&cscfg_mgr->csdev_desc_list);
 	INIT_LIST_HEAD(&cscfg_mgr->feat_desc_list);
 	INIT_LIST_HEAD(&cscfg_mgr->config_desc_list);
diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
index 7bb8c8e497ba..8d018efd6ead 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.h
+++ b/drivers/hwtracing/coresight/coresight-syscfg.h
@@ -6,6 +6,7 @@
 #ifndef CORESIGHT_SYSCFG_H
 #define CORESIGHT_SYSCFG_H
 
+#include <linux/configfs.h>
 #include <linux/coresight.h>
 #include <linux/device.h>
 
@@ -25,6 +26,7 @@
  * @feat_desc_list:	List of feature descriptors to load into registered devices.
  * @config_desc_list:	List of system configuration descriptors to load into registered devices.
  * @sys_active_cnt:	Total number of active config descriptor references.
+ * @cfgfs_subsys:	configfs subsystem used to manage configurations.
  */
 struct cscfg_manager {
 	struct device dev;
@@ -32,6 +34,7 @@ struct cscfg_manager {
 	struct list_head feat_desc_list;
 	struct list_head config_desc_list;
 	atomic_t sys_active_cnt;
+	struct configfs_subsystem cfgfs_subsys;
 };
 
 /* get reference to dev in cscfg_manager */
@@ -57,6 +60,10 @@ struct cscfg_registered_csdev {
 int __init cscfg_init(void);
 void cscfg_exit(void);
 int cscfg_preload(void);
+const struct cscfg_feature_desc *cscfg_get_named_feat_desc(const char *name);
+int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
+				int param_idx, u64 value);
+
 
 /* syscfg manager external API */
 int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:21 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:21 -0600
Subject: [PATCH 10/11] Documentation: coresight: Add documentation for
 CoreSight config
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-11-mathieu.poirier@linaro.org>

From: Mike Leach <mike.leach at linaro.org>

Adds documentation for the CoreSight System configuration manager.

Cc: Jonathan Corbet <corbet at lwn.net>
Cc: linux-doc at vger.kernel.org
Signed-off-by: Mike Leach <mike.leach at linaro.org>
Link: https://lore.kernel.org/r/20210723165444.1048-11-mike.leach at linaro.org
[Fixed coresight-config.rst documentation link]
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 .../trace/coresight/coresight-config.rst      | 244 ++++++++++++++++++
 Documentation/trace/coresight/coresight.rst   |  15 ++
 2 files changed, 259 insertions(+)
 create mode 100644 Documentation/trace/coresight/coresight-config.rst

diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst
new file mode 100644
index 000000000000..a4e3ef295240
--- /dev/null
+++ b/Documentation/trace/coresight/coresight-config.rst
@@ -0,0 +1,244 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+======================================
+CoreSight System Configuration Manager
+======================================
+
+    :Author:   Mike Leach <mike.leach at linaro.org>
+    :Date:     October 2020
+
+Introduction
+============
+
+The CoreSight System Configuration manager is an API that allows the
+programming of the CoreSight system with pre-defined configurations that
+can then be easily enabled from sysfs or perf.
+
+Many CoreSight components can be programmed in complex ways - especially ETMs.
+In addition, components can interact across the CoreSight system, often via
+the cross trigger components such as CTI and CTM. These system settings can
+be defined and enabled as named configurations.
+
+
+Basic Concepts
+==============
+
+This section introduces the basic concepts of a CoreSight system configuration.
+
+
+Features
+--------
+
+A feature is a named set of programming for a CoreSight device. The programming
+is device dependent, and can be defined in terms of absolute register values,
+resource usage and parameter values.
+
+The feature is defined using a descriptor. This descriptor is used to load onto
+a matching device, either when the feature is loaded into the system, or when the
+CoreSight device is registered with the configuration manager.
+
+The load process involves interpreting the descriptor into a set of register
+accesses in the driver - the resource usage and parameter descriptions
+translated into appropriate register accesses. This interpretation makes it easy
+and efficient for the feature to be programmed onto the device when required.
+
+The feature will not be active on the device until the feature is enabled, and
+the device itself is enabled. When the device is enabled then enabled features
+will be programmed into the device hardware.
+
+A feature is enabled as part of a configuration being enabled on the system.
+
+
+Parameter Value
+~~~~~~~~~~~~~~~
+
+A parameter value is a named value that may be set by the user prior to the
+feature being enabled that can adjust the behaviour of the operation programmed
+by the feature.
+
+For example, this could be a count value in a programmed operation that repeats
+at a given rate. When the feature is enabled then the current value of the
+parameter is used in programming the device.
+
+The feature descriptor defines a default value for a parameter, which is used
+if the user does not supply a new value.
+
+Users can update parameter values using the configfs API for the CoreSight
+system - which is described below.
+
+The current value of the parameter is loaded into the device when the feature
+is enabled on that device.
+
+
+Configurations
+--------------
+
+A configuration defines a set of features that are to be used in a trace
+session where the configuration is selected. For any trace session only one
+configuration may be selected.
+
+The features defined may be on any type of device that is registered
+to support system configuration. A configuration may select features to be
+enabled on a class of devices - i.e. any ETMv4, or specific devices, e.g. a
+specific CTI on the system.
+
+As with the feature, a descriptor is used to define the configuration.
+This will define the features that must be enabled as part of the configuration
+as well as any preset values that can be used to override default parameter
+values.
+
+
+Preset Values
+~~~~~~~~~~~~~
+
+Preset values are easily selectable sets of parameter values for the features
+that the configuration uses. The number of values in a single preset set, equals
+the sum of parameter values in the features used by the configuration.
+
+e.g. a configuration consists of 3 features, one has 2 parameters, one has
+a single parameter, and another has no parameters. A single preset set will
+therefore have 3 values.
+
+Presets are optionally defined by the configuration, up to 15 can be defined.
+If no preset is selected, then the parameter values defined in the feature
+are used as normal.
+
+
+Operation
+~~~~~~~~~
+
+The following steps take place in the operation of a configuration.
+
+1) In this example, the configuration is 'autofdo', which has an
+   associated feature 'strobing' that works on ETMv4 CoreSight Devices.
+
+2) The configuration is enabled. For example 'perf' may select the
+   configuration as part of its command line::
+
+    perf record -e cs_etm/autofdo/ myapp
+
+   which will enable the 'autofdo' configuration.
+
+3) perf starts tracing on the system. As each ETMv4 that perf uses for
+   trace is enabled,  the configuration manager will check if the ETMv4
+   has a feature that relates to the currently active configuration.
+   In this case 'strobing' is enabled & programmed into the ETMv4.
+
+4) When the ETMv4 is disabled, any registers marked as needing to be
+   saved will be read back.
+
+5) At the end of the perf session, the configuration will be disabled.
+
+
+Viewing Configurations and Features
+===================================
+
+The set of configurations and features that are currently loaded into the
+system can be viewed using the configfs API.
+
+Mount configfs as normal and the 'cs-syscfg' subsystem will appear::
+
+    $ ls /config
+    cs-syscfg  stp-policy
+
+This has two sub-directories::
+
+    $ cd cs-syscfg/
+    $ ls
+    configurations  features
+
+The system has the configuration 'autofdo' built in. It may be examined as
+follows::
+
+    $ cd configurations/
+    $ ls
+    autofdo
+    $ cd autofdo/
+    $ ls
+    description   preset1  preset3  preset5  preset7  preset9
+    feature_refs  preset2  preset4  preset6  preset8
+    $ cat description
+    Setup ETMs with strobing for autofdo
+    $ cat feature_refs
+    strobing
+
+Each preset declared has a preset<n> subdirectory declared. The values for
+the preset can be examined::
+
+    $ cat preset1/values
+    strobing.window = 0x1388 strobing.period = 0x2
+    $ cat preset2/values
+    strobing.window = 0x1388 strobing.period = 0x4
+
+The features referenced by the configuration can be examined in the features
+directory::
+
+    $ cd ../../features/strobing/
+    $ ls
+    description  matches  nr_params  params
+    $ cat description
+    Generate periodic trace capture windows.
+    parameter 'window': a number of CPU cycles (W)
+    parameter 'period': trace enabled for W cycles every period x W cycles
+    $ cat matches
+    SRC_ETMV4
+    $ cat nr_params
+    2
+
+Move to the params directory to examine and adjust parameters::
+
+    cd params
+    $ ls
+    period  window
+    $ cd period
+    $ ls
+    value
+    $ cat value
+    0x2710
+    # echo 15000 > value
+    # cat value
+    0x3a98
+
+Parameters adjusted in this way are reflected in all device instances that have
+loaded the feature.
+
+
+Using Configurations in perf
+============================
+
+The configurations loaded into the CoreSight configuration management are
+also declared in the perf 'cs_etm' event infrastructure so that they can
+be selected when running trace under perf::
+
+    $ ls /sys/devices/cs_etm
+    configurations  format  perf_event_mux_interval_ms  sinks  type
+    events  nr_addr_filters  power
+
+Key directories here are 'configurations' - which lists the loaded
+configurations, and 'events' - a generic perf directory which allows
+selection on the perf command line.::
+
+    $ ls configurations/
+    autofdo
+    $ cat configurations/autofdo
+    0xa7c3dddd
+
+As with the sinks entries, this provides a hash of the configuration name.
+The entry in the 'events' directory uses perfs built in syntax generator
+to substitute the syntax for the name when evaluating the command::
+
+    $ ls events/
+    autofdo
+    $ cat events/autofdo
+    configid=0xa7c3dddd
+
+The 'autofdo' configuration may be selected on the perf command line::
+
+    $ perf record -e cs_etm/autofdo/u --per-thread <application>
+
+A preset to override the current parameter values can also be selected::
+
+    $ perf record -e cs_etm/autofdo,preset=1/u --per-thread <application>
+
+When configurations are selected in this way, then the trace sink used is
+automatically selected.
diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst
index 1ec8dc35b1d8..a15571d96cc8 100644
--- a/Documentation/trace/coresight/coresight.rst
+++ b/Documentation/trace/coresight/coresight.rst
@@ -620,6 +620,19 @@ channels on the CTM (Cross Trigger Matrix).
 A separate documentation file is provided to explain the use of these devices.
 (Documentation/trace/coresight/coresight-ect.rst) [#fourth]_.
 
+CoreSight System Configuration
+------------------------------
+
+CoreSight components can be complex devices with many programming options.
+Furthermore, components can be programmed to interact with each other across the
+complete system.
+
+A CoreSight System Configuration manager is provided to allow these complex programming
+configurations to be selected and used easily from perf and sysfs.
+
+See the separate document for further information.
+(Documentation/trace/coresight/coresight-config.rst) [#fifth]_.
+
 
 .. [#first] Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
 
@@ -628,3 +641,5 @@ A separate documentation file is provided to explain the use of these devices.
 .. [#third] https://github.com/Linaro/perf-opencsd
 
 .. [#fourth] Documentation/trace/coresight/coresight-ect.rst
+
+.. [#fifth] Documentation/trace/coresight/coresight-config.rst
-- 
2.25.1



From mathieu.poirier at linaro.org  Wed Aug 18 12:40:22 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 18 Aug 2021 13:40:22 -0600
Subject: [PATCH 11/11] coresight: Replace deprecated CPU-hotplug functions.
In-Reply-To: <20210818194022.379573-1-mathieu.poirier@linaro.org>
References: <20210818194022.379573-1-mathieu.poirier@linaro.org>
Message-ID: <20210818194022.379573-12-mathieu.poirier@linaro.org>

From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

The functions get_online_cpus() and put_online_cpus() have been
deprecated during the CPU hotplug rework. They map directly to
cpus_read_lock() and cpus_read_unlock().

Replace deprecated CPU-hotplug functions with the official version.
The behavior remains unchanged.

Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
Cc: Mike Leach <mike.leach at linaro.org>
Cc: Leo Yan <leo.yan at linaro.org>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: coresight at lists.linaro.org
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
Link: https://lore.kernel.org/r/20210803141621.780504-15-bigeasy at linutronix.de
Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>
---
 drivers/hwtracing/coresight/coresight-cpu-debug.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 9731d3a96073..00de46565bc4 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -588,11 +588,11 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id)
 
 	drvdata->base = base;
 
-	get_online_cpus();
+	cpus_read_lock();
 	per_cpu(debug_drvdata, drvdata->cpu) = drvdata;
 	ret = smp_call_function_single(drvdata->cpu, debug_init_arch_data,
 				       drvdata, 1);
-	put_online_cpus();
+	cpus_read_unlock();
 
 	if (ret) {
 		dev_err(dev, "CPU%d debug arch init failed\n", drvdata->cpu);
-- 
2.25.1



From oupton at google.com  Wed Aug 18 12:40:42 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 18 Aug 2021 12:40:42 -0700
Subject: [PATCH] KVM: arm64: vgic: Resample HW pending state on
 deactivation
In-Reply-To: <CAJHc60zUZS3K4q88QYwP2CkGn7ywt-_fedjk7OK_W7cdQRJvxA@mail.gmail.com>
References: <20210818181432.432256-1-maz@kernel.org>
 <CAJHc60zUZS3K4q88QYwP2CkGn7ywt-_fedjk7OK_W7cdQRJvxA@mail.gmail.com>
Message-ID: <CAOQ_QsgGiGSfEq1QGfePiRF-=spCuR6XZ2QXfUsZ1zWds0ftag@mail.gmail.com>

Hey Marc,

On Wed, Aug 18, 2021 at 12:05 PM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> On Wed, Aug 18, 2021 at 11:14 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > When a mapped level interrupt (a timer, for example) is deactivated
> > by the guest, the corresponding host interrupt is equally deactivated.
> > However, the fate of the pending state still needs to be dealt
> > with in SW.
> >
> > This is specially true when the interrupt was in the active+pending
> > state in the virtual distributor at the point where the guest
> > was entered. On exit, the pending state is potentially stale
> > (the guest may have put the interrupt in a non-pending state).
> >
> > If we don't do anything, the interrupt will be spuriously injected
> > in the guest. Although this shouldn't have any ill effect (spurious
> > interrupts are always possible), we can improve the emulation by
> > detecting the deactivation-while-pending case and resample the
> > interrupt.
> >
> > Fixes: e40cc57bac79 ("KVM: arm/arm64: vgic: Support level-triggered mapped interrupts")
> > Reported-by: Raghavendra Rao Ananta <rananta at google.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > Cc: stable at vger.kernel.org
> > ---
> >  arch/arm64/kvm/vgic/vgic-v2.c | 25 ++++++++++++++++++-------
> >  arch/arm64/kvm/vgic/vgic-v3.c | 25 ++++++++++++++++++-------
> >  2 files changed, 36 insertions(+), 14 deletions(-)
> >
> Tested-by: Raghavendra Rao Ananta <rananta at google.com>
>
> Thanks,
> Raghavendra
> > diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
> > index 2c580204f1dc..3e52ea86a87f 100644
> > --- a/arch/arm64/kvm/vgic/vgic-v2.c
> > +++ b/arch/arm64/kvm/vgic/vgic-v2.c
> > @@ -60,6 +60,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> >                 u32 val = cpuif->vgic_lr[lr];
> >                 u32 cpuid, intid = val & GICH_LR_VIRTUALID;
> >                 struct vgic_irq *irq;
> > +               bool deactivated;
> >
> >                 /* Extract the source vCPU id from the LR */
> >                 cpuid = val & GICH_LR_PHYSID_CPUID;
> > @@ -75,7 +76,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> >
> >                 raw_spin_lock(&irq->irq_lock);
> >
> > -               /* Always preserve the active bit */
> > +               /* Always preserve the active bit, note deactivation */
> > +               deactivated = irq->active && !(val & GICH_LR_ACTIVE_BIT);
> >                 irq->active = !!(val & GICH_LR_ACTIVE_BIT);
> >
> >                 if (irq->active && vgic_irq_is_sgi(intid))
> > @@ -105,6 +107,12 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> >                  * device state could have changed or we simply need to
> >                  * process the still pending interrupt later.
> >                  *
> > +                * We could also have entered the guest with the interrupt
> > +                * active+pending. On the next exit, we need to re-evaluate
> > +                * the pending state, as it could otherwise result in a
> > +                * spurious interrupt by injecting a now potentially stale
> > +                * pending state.
> > +                *
> >                  * If this causes us to lower the level, we have to also clear
> >                  * the physical active state, since we will otherwise never be
> >                  * told when the interrupt becomes asserted again.
> > @@ -115,12 +123,15 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> >                 if (vgic_irq_is_mapped_level(irq)) {
> >                         bool resample = false;
> >
> > -                       if (val & GICH_LR_PENDING_BIT) {
> > -                               irq->line_level = vgic_get_phys_line_level(irq);
> > -                               resample = !irq->line_level;
> > -                       } else if (vgic_irq_needs_resampling(irq) &&
> > -                                  !(irq->active || irq->pending_latch)) {
> > -                               resample = true;
> > +                       if (unlikely(vgic_irq_needs_resampling(irq))) {
> > +                               if (!(irq->active || irq->pending_latch))
> > +                                       resample = true;
> > +                       } else {
> > +                               if ((val & GICH_LR_PENDING_BIT) ||
> > +                                   (deactivated && irq->line_level)) {
> > +                                       irq->line_level = vgic_get_phys_line_level(irq);
> > +                                       resample = !irq->line_level;
> > +                               }
> >                         }
> >
> >                         if (resample)
> > diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
> > index 66004f61cd83..74f9aefffd5e 100644
> > --- a/arch/arm64/kvm/vgic/vgic-v3.c
> > +++ b/arch/arm64/kvm/vgic/vgic-v3.c
> > @@ -46,6 +46,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
> >                 u32 intid, cpuid;
> >                 struct vgic_irq *irq;
> >                 bool is_v2_sgi = false;
> > +               bool deactivated;
> >
> >                 cpuid = val & GICH_LR_PHYSID_CPUID;
> >                 cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT;
> > @@ -68,7 +69,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
> >
> >                 raw_spin_lock(&irq->irq_lock);
> >
> > -               /* Always preserve the active bit */
> > +               /* Always preserve the active bit, note deactivation */
> > +               deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT);
> >                 irq->active = !!(val & ICH_LR_ACTIVE_BIT);
> >
> >                 if (irq->active && is_v2_sgi)
> > @@ -98,6 +100,12 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
> >                  * device state could have changed or we simply need to
> >                  * process the still pending interrupt later.
> >                  *
> > +                * We could also have entered the guest with the interrupt
> > +                * active+pending. On the next exit, we need to re-evaluate
> > +                * the pending state, as it could otherwise result in a
> > +                * spurious interrupt by injecting a now potentially stale
> > +                * pending state.
> > +                *
> >                  * If this causes us to lower the level, we have to also clear
> >                  * the physical active state, since we will otherwise never be
> >                  * told when the interrupt becomes asserted again.
> > @@ -108,12 +116,15 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
> >                 if (vgic_irq_is_mapped_level(irq)) {
> >                         bool resample = false;
> >
> > -                       if (val & ICH_LR_PENDING_BIT) {
> > -                               irq->line_level = vgic_get_phys_line_level(irq);
> > -                               resample = !irq->line_level;
> > -                       } else if (vgic_irq_needs_resampling(irq) &&
> > -                                  !(irq->active || irq->pending_latch)) {
> > -                               resample = true;
> > +                       if (unlikely(vgic_irq_needs_resampling(irq))) {
> > +                               if (!(irq->active || irq->pending_latch))
> > +                                       resample = true;
> > +                       } else {
> > +                               if ((val & ICH_LR_PENDING_BIT) ||
> > +                                   (deactivated && irq->line_level)) {
> > +                                       irq->line_level = vgic_get_phys_line_level(irq);
> > +                                       resample = !irq->line_level;
> > +                               }

The vGICv3 and vGICv2 implementations look identical here, should we
have a helper that keeps the code common between the two?

Otherwise, the functional change LGTM, so:

Reviewed-by: Oliver Upton <oupton at google.com>

> >                         }
> >
> >                         if (resample)
> > --
> > 2.30.2
> >


From mark.kettenis at xs4all.nl  Wed Aug 18 12:56:10 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Wed, 18 Aug 2021 21:56:10 +0200 (CEST)
Subject: [PATCH v3 1/2] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <CAL_JsqJ5M3soMT30ntSTbqqdrQP8TT26mHL-0xExsn10MWPofA@mail.gmail.com>
 (message from Rob Herring on Sun, 15 Aug 2021 14:19:57 -0500)
References: <20210726083204.93196-1-mark.kettenis@xs4all.nl>
 <20210726083204.93196-2-mark.kettenis@xs4all.nl>
 <20210726231848.GA1025245@robh.at.kernel.org>
 <87sfzt1pg9.wl-maz@kernel.org>
 <CAL_JsqLvqWiuib9s4PzX8pOQYJQ0eR7Gxz==J849eVJ5MDq4SA@mail.gmail.com>
 <8735ra1x8t.wl-maz@kernel.org>
 <CAL_JsqJ5M3soMT30ntSTbqqdrQP8TT26mHL-0xExsn10MWPofA@mail.gmail.com>
Message-ID: <56140331bd735d61@bloch.sibelius.xs4all.nl>

> From: Rob Herring <robh at kernel.org>
> Date: Sun, 15 Aug 2021 14:19:57 -0500
> 
> On Sun, Aug 15, 2021 at 11:36 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > Hi Rob,
> >
> > Apologies for the delay, I somehow misplaced this email...
> >
> > On Mon, 02 Aug 2021 17:10:39 +0100,
> > Rob Herring <robh at kernel.org> wrote:
> > >
> > > On Sun, Aug 1, 2021 at 3:31 AM Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > On Tue, 27 Jul 2021 00:18:48 +0100,
> > > > Rob Herring <robh at kernel.org> wrote:
> > > > >
> > > > > On Mon, Jul 26, 2021 at 10:32:00AM +0200, Mark Kettenis wrote:
> > > > > > From: Mark Kettenis <kettenis at openbsd.org>
> > > > > >
> > > > > > The Apple PCIe host controller is a PCIe host controller with
> > > > > > multiple root ports present in Apple ARM SoC platforms, including
> > > > > > various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > >
> > > > > > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > > > > > ---
> > > > > >  .../devicetree/bindings/pci/apple,pcie.yaml   | 166 ++++++++++++++++++
> > > > > >  MAINTAINERS                                   |   1 +
> > > > > >  2 files changed, 167 insertions(+)
> > > > > >  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > >
> > > > > > diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > new file mode 100644
> > > > > > index 000000000000..bfcbdee79c64
> > > > > > --- /dev/null
> > > > > > +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > @@ -0,0 +1,166 @@
> > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > > +%YAML 1.2
> > > > > > +---
> > > > > > +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > > +
> > > > > > +title: Apple PCIe host controller
> > > > > > +
> > > > > > +maintainers:
> > > > > > +  - Mark Kettenis <kettenis at openbsd.org>
> > > > > > +
> > > > > > +description: |
> > > > > > +  The Apple PCIe host controller is a PCIe host controller with
> > > > > > +  multiple root ports present in Apple ARM SoC platforms, including
> > > > > > +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > > +  The controller incorporates Synopsys DesigWare PCIe logic to
> > > > > > +  implements its root ports.  But the ATU found on most DesignWare
> > > > > > +  PCIe host bridges is absent.
> > > > >
> > > > > blank line
> > > > >
> > > > > > +  All root ports share a single ECAM space, but separate GPIOs are
> > > > > > +  used to take the PCI devices on those ports out of reset.  Therefore
> > > > > > +  the standard "reset-gpio" and "max-link-speed" properties appear on
> > > > >
> > > > > reset-gpios
> > > > >
> > > > > > +  the child nodes that represent the PCI bridges that correspond to
> > > > > > +  the individual root ports.
> > > > >
> > > > > blank line
> > > > >
> > > > > > +  MSIs are handled by the PCIe controller and translated into regular
> > > > > > +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> > > > > > +  distributed over the root ports as the OS sees fit by programming
> > > > > > +  the PCIe controller's port registers.
> > > > > > +
> > > > > > +allOf:
> > > > > > +  - $ref: /schemas/pci/pci-bus.yaml#
> > > > > > +
> > > > > > +properties:
> > > > > > +  compatible:
> > > > > > +    items:
> > > > > > +      - const: apple,t8103-pcie
> > > > > > +      - const: apple,pcie
> > > > > > +
> > > > > > +  reg:
> > > > > > +    minItems: 3
> > > > > > +    maxItems: 5
> > > > > > +
> > > > > > +  reg-names:
> > > > > > +    minItems: 3
> > > > > > +    maxItems: 5
> > > > > > +    items:
> > > > > > +      - const: config
> > > > > > +      - const: rc
> > > > > > +      - const: port0
> > > > > > +      - const: port1
> > > > > > +      - const: port2
> > > > > > +
> > > > > > +  ranges:
> > > > > > +    minItems: 2
> > > > > > +    maxItems: 2
> > > > > > +
> > > > > > +  interrupts:
> > > > > > +    description:
> > > > > > +      Interrupt specifiers, one for each root port.
> > > > > > +    minItems: 1
> > > > > > +    maxItems: 3
> > > > > > +
> > > > > > +  msi-controller: true
> > > > > > +  msi-parent: true
> > > > > > +
> > > > > > +  msi-ranges:
> > > > > > +    description:
> > > > > > +      A list of pairs <intid span>, where "intid" is the first
> > > > > > +      interrupt number that can be used as an MSI, and "span" the size
> > > > > > +      of that range.
> > > > > > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > > > > > +    items:
> > > > > > +      minItems: 2
> > > > > > +      maxItems: 2
> > > > >
> > > > > I still have issues I raised on v1 with this property. It's genericish
> > > > > looking, but not generic. 'intid' as a single cell can't specify any
> > > > > parent interrupt such as a GIC which uses 3 cells. You could put in all
> > > > > the cells, but you'd still be assuming which cell you can increment.
> > > >
> > > > The GIC bindings already use similar abstractions, see what we do for
> > > > both GICv2m and GICv3 MBIs. Other MSI controllers use similar
> > > > properties (alpine and loongson, for example).
> > >
> > > That's the problem. Everyone making up their own crap.
> >
> > And that crap gets approved:
> >
> > https://lore.kernel.org/lkml/20200512205704.GA10412 at bogus/
> >
> > I'm not trying to be antagonistic here, but it seems that your
> > position on this very subject has changed recently.
> 
> Not really, I think it's not the first time we've discussed this. But
> as I see things over and over, my tolerance for another instance
> without solving the problem for everyone diminishes. And what other
> leverage do I have?
> 
> Additionally, how long we have to support something comes into play. I
> have no idea for a Loongson MSI controller. I have a better idea on an
> Apple product...
> 
> > > > > I think you should just list all these under 'interrupts' using
> > > > > interrupt-names to make your life easier:
> > > > >
> > > > > interrupt-names:
> > > > >   items:
> > > > >     - const: port0
> > > > >     - const: port1
> > > > >     - const: port2
> > > > >     - const: msi0
> > > > >     - const: msi1
> > > > >     - const: msi2
> > > > >     - const: msi3
> > > > >     ...
> > > > >
> > > > > Yeah, it's kind of verbose, but if the h/w block handles N interrupts,
> > > > > you should list N interrupts. The worst case for the above is N entries
> > > > > too if not contiguous.
> > > >
> > > > And that's where I beg to differ, again.
> > > >
> > > > Specifying interrupts like this gives the false impression that these
> > > > interrupts are generated by the device that owns them (the RC). Which
> > > > for MSIs is not the case.
> > >
> > > It's no different than an interrupt controller node having an
> > > interrupts property. The source is downstream and the interrupt
> > > controller is combining/translating the interrupts.
> > >
> > > The physical interrupt signals are connected to and originating in
> > > this block.
> >
> > Oh, I also object to this, for the same reasons. The only case where
> > it makes sense IMHO is when the interrupt controller is a multiplexer.
> 
> So we've had the same kind of property for interrupt multiplexers. I'm
> fine if you think an 'MSI to interrupts mapping property' should be
> named something else.
> 
> > > That sounds like perfectly 'describing the h/w' to me.
> >
> > I guess we have a different view of about these things. At the end of
> > the day, I don't care enough as long as we can expose a range of
> > interrupts one way or another.
> 
> I don't really either. I just don't want 10 ways AND another...
> 
> > > > This is not only verbose, this is
> > > > semantically dubious. And what should we do when the number of
> > > > possible interrupt is ridiculously large, as it is for the GICv3 ITS?
> > >
> > > I don't disagree with the verbose part. But that's not really an issue
> > > in this case.
> > >
> > > > I wish we had a standard way to express these constraints. Until we
> > > > do, I don't think enumerating individual interrupts is a practical
> > > > thing to do, nor that it actually represents the topology of the
> > > > system.
> > >
> > > The only way a standard way will happen is to stop accepting the
> > > custom properties.
> > >
> > > All the custom properties suffer from knowledge of what the parent
> > > interrupt controller is. To fix that, I think we need something like
> > > this:
> > >
> > > msi-ranges = <intspec base>, <intspec step>, <intspec end>;
> > >
> > > 'intspec' is defined by the parent interrupt-controller cells. step is
> > > the value to add. And end is what to match on to stop aka the last
> > > interrupt in the range. For example, if the GIC is the parent, we'd
> > > have something like this:
> > >
> > > <GIC_SPI 123 0>, <0 1 0>, <GIC_SPI 124 0>
> > >
> > > Does this apply to cases other than MSI? I think so as don't we have
> > > the same type of properties with the low power mode shadow interrupt
> > > controllers?  So 'interrupt-ranges'?
> >
> > This would work, though the increment seems a bit over-engineered. You
> > also may need this property to accept multiple ranges.
> 
> Yes, certainly. Worst case is a map.
> 
> > > It looks to me like there's an assumption in the kernel that an MSI
> > > controller has a linear range of parent interrupts? Is that correct
> > > and something that's guaranteed? That assumption leaks into the
> > > existing bindings.
> >
> > Depends on how the controller works. In general, the range maps to the
> > MultiMSI requirements where the message is an offset from the base of
> > the interrupt range. So you generally end-up with ranges of at least
> > 32 contiguous MSIs. Anything under that is sub-par and probably not
> > worth supporting.
> 
> Maybe just this is enough:
> msi-ranges = <intspec base>, <length>, <intspec base>, <length>, ...
> 
> While I say 'length' here, that's really up to the interrupt parent to
> interpret the intspec cells.

So for the Apple PCIe controller we'd have:

   msi-ranges = <AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;

That would work just fine.

Should this be documented in the apple,pcie binding, or somewhere more
generic?

> > Of course, the controller may have some mapping facilities, which
> > makes things more... interesting.
> >
> > > It's fine for the kernel to assume that until there's a case that's
> > > not linear, but a common binding needs to be able handle a
> > > non-linear case.
> >
> > Fair enough. I can probably work with Mark to upgrade the binding and
> > the M1 PCIe code. Could you come up with a more formalised proposal?
> 
> Not my itch.
> 
> Rob
> 


From krzysztof.kozlowski at canonical.com  Wed Aug 18 13:41:40 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 18 Aug 2021 22:41:40 +0200
Subject: [PATCH v3 00/13] MT8195 SMI support
In-Reply-To: <20210810080859.29511-1-yong.wu@mediatek.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
Message-ID: <1a160afd-ceeb-04a3-8213-fe781ec18e30@canonical.com>

On 10/08/2021 10:08, Yong Wu wrote:
> This patchset mainly adds SMI support for mt8195.
> 
> Comparing with the previous version, add two new functions:
> a) add smi sub common
> b) add initial setting for smi-common and smi-larb.
> 
> Change note:
> v3:1) In the dt-binding:
>        a. Change mediatek,smi type from phandle-array to phandle from Rob.
>        b. Add a new bool property (mediatek,smi_sub_common)
>           to indicate if this is smi-sub-common.
>    2) Change the clock using bulk parting.
>       keep the smi-common's has_gals flag. more strict.
>    3) More comment about larb initial setting.
>    4) Add a maintain patch

The patchset looks good to me but I saw now comments from Rob, so I
expect a resend. Therefore there is also time for additional review -
maybe continued by Ikjoon Jang?

If you sent a v4 with fixes rather soon and get ack from Rob, I could
still try to get it into next merge window. After this weekend I won't
be taking patches for this cycle and it will wait for the merge window
to finish.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Wed Aug 18 13:44:22 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 18 Aug 2021 22:44:22 +0200
Subject: [PATCH][PULL/direct] ARM: s3c: delete unneed local variable "delay"
Message-ID: <20210818204422.17919-1-krzysztof.kozlowski@canonical.com>

From: Jason Wang <wangborong at cdjrlc.com>

"delay" variable on line 79 can be deleted by returning "0" on line 88.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
Link: https://lore.kernel.org/r/20210624055627.22295-1-wangborong at cdjrlc.com
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---

Hi Arnd and Olof,

I have just one patch for Samsung ARM mach/soc, so sending this
directly.

Best regards,
Krzysztof


 arch/arm/mach-s3c/mach-gta02.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/mach-s3c/mach-gta02.c b/arch/arm/mach-s3c/mach-gta02.c
index aec8b451c016..418939ce0fc3 100644
--- a/arch/arm/mach-s3c/mach-gta02.c
+++ b/arch/arm/mach-s3c/mach-gta02.c
@@ -79,13 +79,12 @@ static struct pcf50633 *gta02_pcf;
 
 static long gta02_panic_blink(int state)
 {
-	long delay = 0;
 	char led;
 
 	led = (state) ? 1 : 0;
 	gpio_direction_output(GTA02_GPIO_AUX_LED, led);
 
-	return delay;
+	return 0;
 }
 
 
-- 
2.30.2



From robh at kernel.org  Wed Aug 18 13:51:11 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 18 Aug 2021 15:51:11 -0500
Subject: [PATCH v3 1/2] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <56140331bd735d61@bloch.sibelius.xs4all.nl>
References: <20210726083204.93196-1-mark.kettenis@xs4all.nl>
 <20210726083204.93196-2-mark.kettenis@xs4all.nl>
 <20210726231848.GA1025245@robh.at.kernel.org>
 <87sfzt1pg9.wl-maz@kernel.org>
 <CAL_JsqLvqWiuib9s4PzX8pOQYJQ0eR7Gxz==J849eVJ5MDq4SA@mail.gmail.com>
 <8735ra1x8t.wl-maz@kernel.org>
 <CAL_JsqJ5M3soMT30ntSTbqqdrQP8TT26mHL-0xExsn10MWPofA@mail.gmail.com>
 <56140331bd735d61@bloch.sibelius.xs4all.nl>
Message-ID: <CAL_JsqJ-YDNWOoo8TUupDox31YreUNQAPXHnMMtXakQs0S_BDA@mail.gmail.com>

,

On Wed, Aug 18, 2021 at 2:56 PM Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
>
> > From: Rob Herring <robh at kernel.org>
> > Date: Sun, 15 Aug 2021 14:19:57 -0500
> >
> > On Sun, Aug 15, 2021 at 11:36 AM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > Hi Rob,
> > >
> > > Apologies for the delay, I somehow misplaced this email...
> > >
> > > On Mon, 02 Aug 2021 17:10:39 +0100,
> > > Rob Herring <robh at kernel.org> wrote:
> > > >
> > > > On Sun, Aug 1, 2021 at 3:31 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > >
> > > > > On Tue, 27 Jul 2021 00:18:48 +0100,
> > > > > Rob Herring <robh at kernel.org> wrote:
> > > > > >
> > > > > > On Mon, Jul 26, 2021 at 10:32:00AM +0200, Mark Kettenis wrote:
> > > > > > > From: Mark Kettenis <kettenis at openbsd.org>
> > > > > > >
> > > > > > > The Apple PCIe host controller is a PCIe host controller with
> > > > > > > multiple root ports present in Apple ARM SoC platforms, including
> > > > > > > various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > > >
> > > > > > > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > > > > > > ---
> > > > > > >  .../devicetree/bindings/pci/apple,pcie.yaml   | 166 ++++++++++++++++++
> > > > > > >  MAINTAINERS                                   |   1 +
> > > > > > >  2 files changed, 167 insertions(+)
> > > > > > >  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > >
> > > > > > > diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > > new file mode 100644
> > > > > > > index 000000000000..bfcbdee79c64
> > > > > > > --- /dev/null
> > > > > > > +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > > @@ -0,0 +1,166 @@
> > > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > > > +%YAML 1.2
> > > > > > > +---
> > > > > > > +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> > > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > > > +
> > > > > > > +title: Apple PCIe host controller
> > > > > > > +
> > > > > > > +maintainers:
> > > > > > > +  - Mark Kettenis <kettenis at openbsd.org>
> > > > > > > +
> > > > > > > +description: |
> > > > > > > +  The Apple PCIe host controller is a PCIe host controller with
> > > > > > > +  multiple root ports present in Apple ARM SoC platforms, including
> > > > > > > +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > > > +  The controller incorporates Synopsys DesigWare PCIe logic to
> > > > > > > +  implements its root ports.  But the ATU found on most DesignWare
> > > > > > > +  PCIe host bridges is absent.
> > > > > >
> > > > > > blank line
> > > > > >
> > > > > > > +  All root ports share a single ECAM space, but separate GPIOs are
> > > > > > > +  used to take the PCI devices on those ports out of reset.  Therefore
> > > > > > > +  the standard "reset-gpio" and "max-link-speed" properties appear on
> > > > > >
> > > > > > reset-gpios
> > > > > >
> > > > > > > +  the child nodes that represent the PCI bridges that correspond to
> > > > > > > +  the individual root ports.
> > > > > >
> > > > > > blank line
> > > > > >
> > > > > > > +  MSIs are handled by the PCIe controller and translated into regular
> > > > > > > +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> > > > > > > +  distributed over the root ports as the OS sees fit by programming
> > > > > > > +  the PCIe controller's port registers.
> > > > > > > +
> > > > > > > +allOf:
> > > > > > > +  - $ref: /schemas/pci/pci-bus.yaml#
> > > > > > > +
> > > > > > > +properties:
> > > > > > > +  compatible:
> > > > > > > +    items:
> > > > > > > +      - const: apple,t8103-pcie
> > > > > > > +      - const: apple,pcie
> > > > > > > +
> > > > > > > +  reg:
> > > > > > > +    minItems: 3
> > > > > > > +    maxItems: 5
> > > > > > > +
> > > > > > > +  reg-names:
> > > > > > > +    minItems: 3
> > > > > > > +    maxItems: 5
> > > > > > > +    items:
> > > > > > > +      - const: config
> > > > > > > +      - const: rc
> > > > > > > +      - const: port0
> > > > > > > +      - const: port1
> > > > > > > +      - const: port2
> > > > > > > +
> > > > > > > +  ranges:
> > > > > > > +    minItems: 2
> > > > > > > +    maxItems: 2
> > > > > > > +
> > > > > > > +  interrupts:
> > > > > > > +    description:
> > > > > > > +      Interrupt specifiers, one for each root port.
> > > > > > > +    minItems: 1
> > > > > > > +    maxItems: 3
> > > > > > > +
> > > > > > > +  msi-controller: true
> > > > > > > +  msi-parent: true

BTW, I don't think msi-parent and msi-controller together is valid?

> > > > > > > +
> > > > > > > +  msi-ranges:
> > > > > > > +    description:
> > > > > > > +      A list of pairs <intid span>, where "intid" is the first
> > > > > > > +      interrupt number that can be used as an MSI, and "span" the size
> > > > > > > +      of that range.
> > > > > > > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > > > > > > +    items:
> > > > > > > +      minItems: 2
> > > > > > > +      maxItems: 2
> > > > > >
> > > > > > I still have issues I raised on v1 with this property. It's genericish
> > > > > > looking, but not generic. 'intid' as a single cell can't specify any
> > > > > > parent interrupt such as a GIC which uses 3 cells. You could put in all
> > > > > > the cells, but you'd still be assuming which cell you can increment.
> > > > >
> > > > > The GIC bindings already use similar abstractions, see what we do for
> > > > > both GICv2m and GICv3 MBIs. Other MSI controllers use similar
> > > > > properties (alpine and loongson, for example).
> > > >
> > > > That's the problem. Everyone making up their own crap.
> > >
> > > And that crap gets approved:
> > >
> > > https://lore.kernel.org/lkml/20200512205704.GA10412 at bogus/
> > >
> > > I'm not trying to be antagonistic here, but it seems that your
> > > position on this very subject has changed recently.
> >
> > Not really, I think it's not the first time we've discussed this. But
> > as I see things over and over, my tolerance for another instance
> > without solving the problem for everyone diminishes. And what other
> > leverage do I have?
> >
> > Additionally, how long we have to support something comes into play. I
> > have no idea for a Loongson MSI controller. I have a better idea on an
> > Apple product...
> >
> > > > > > I think you should just list all these under 'interrupts' using
> > > > > > interrupt-names to make your life easier:
> > > > > >
> > > > > > interrupt-names:
> > > > > >   items:
> > > > > >     - const: port0
> > > > > >     - const: port1
> > > > > >     - const: port2
> > > > > >     - const: msi0
> > > > > >     - const: msi1
> > > > > >     - const: msi2
> > > > > >     - const: msi3
> > > > > >     ...
> > > > > >
> > > > > > Yeah, it's kind of verbose, but if the h/w block handles N interrupts,
> > > > > > you should list N interrupts. The worst case for the above is N entries
> > > > > > too if not contiguous.
> > > > >
> > > > > And that's where I beg to differ, again.
> > > > >
> > > > > Specifying interrupts like this gives the false impression that these
> > > > > interrupts are generated by the device that owns them (the RC). Which
> > > > > for MSIs is not the case.
> > > >
> > > > It's no different than an interrupt controller node having an
> > > > interrupts property. The source is downstream and the interrupt
> > > > controller is combining/translating the interrupts.
> > > >
> > > > The physical interrupt signals are connected to and originating in
> > > > this block.
> > >
> > > Oh, I also object to this, for the same reasons. The only case where
> > > it makes sense IMHO is when the interrupt controller is a multiplexer.
> >
> > So we've had the same kind of property for interrupt multiplexers. I'm
> > fine if you think an 'MSI to interrupts mapping property' should be
> > named something else.
> >
> > > > That sounds like perfectly 'describing the h/w' to me.
> > >
> > > I guess we have a different view of about these things. At the end of
> > > the day, I don't care enough as long as we can expose a range of
> > > interrupts one way or another.
> >
> > I don't really either. I just don't want 10 ways AND another...
> >
> > > > > This is not only verbose, this is
> > > > > semantically dubious. And what should we do when the number of
> > > > > possible interrupt is ridiculously large, as it is for the GICv3 ITS?
> > > >
> > > > I don't disagree with the verbose part. But that's not really an issue
> > > > in this case.
> > > >
> > > > > I wish we had a standard way to express these constraints. Until we
> > > > > do, I don't think enumerating individual interrupts is a practical
> > > > > thing to do, nor that it actually represents the topology of the
> > > > > system.
> > > >
> > > > The only way a standard way will happen is to stop accepting the
> > > > custom properties.
> > > >
> > > > All the custom properties suffer from knowledge of what the parent
> > > > interrupt controller is. To fix that, I think we need something like
> > > > this:
> > > >
> > > > msi-ranges = <intspec base>, <intspec step>, <intspec end>;
> > > >
> > > > 'intspec' is defined by the parent interrupt-controller cells. step is
> > > > the value to add. And end is what to match on to stop aka the last
> > > > interrupt in the range. For example, if the GIC is the parent, we'd
> > > > have something like this:
> > > >
> > > > <GIC_SPI 123 0>, <0 1 0>, <GIC_SPI 124 0>
> > > >
> > > > Does this apply to cases other than MSI? I think so as don't we have
> > > > the same type of properties with the low power mode shadow interrupt
> > > > controllers?  So 'interrupt-ranges'?
> > >
> > > This would work, though the increment seems a bit over-engineered. You
> > > also may need this property to accept multiple ranges.
> >
> > Yes, certainly. Worst case is a map.
> >
> > > > It looks to me like there's an assumption in the kernel that an MSI
> > > > controller has a linear range of parent interrupts? Is that correct
> > > > and something that's guaranteed? That assumption leaks into the
> > > > existing bindings.
> > >
> > > Depends on how the controller works. In general, the range maps to the
> > > MultiMSI requirements where the message is an offset from the base of
> > > the interrupt range. So you generally end-up with ranges of at least
> > > 32 contiguous MSIs. Anything under that is sub-par and probably not
> > > worth supporting.
> >
> > Maybe just this is enough:
> > msi-ranges = <intspec base>, <length>, <intspec base>, <length>, ...
> >
> > While I say 'length' here, that's really up to the interrupt parent to
> > interpret the intspec cells.
>
> So for the Apple PCIe controller we'd have:
>
>    msi-ranges = <AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
>
> That would work just fine.
>
> Should this be documented in the apple,pcie binding, or somewhere more
> generic?

It doesn't have an 'apple,' prefix, so somewhere generic. Probably
bindings/interrupt-controller/msi.txt. Or start an msi-controller.yaml
schema as I'd rather not add things we can't validate, but I don't
want to gate this on converting all the MSI bindings. Someone that
understands MSI better than me should review too.

Another thing I thought of is the above is assuming the interrupt
parent is the same as any interrupts for the node and that all MSIs go
to 1 interrupt controller. Also, given Marc doesn't think using
'interrupts' is right, then using 'interrupt-parent' isn't either
(though many of the examples below do just that). So maybe we need the
phandle in there:

msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;

Other examples of this type of property include:
al,msi-base-spi/al,msi-base-spi
arm,msi-base-spi/arm,msi-num-spis
mbi-ranges
loongson,msi-base-vec/loongson,msi-num-vecs
marvell,spi-ranges
ti,interrupt-ranges?

We should make sure msi-ranges works for all of these cases at least
even if we can't change them.

Rob


From maz at kernel.org  Wed Aug 18 14:24:38 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 18 Aug 2021 22:24:38 +0100
Subject: [PATCH] KVM: arm64: vgic: Resample HW pending state on
 deactivation
In-Reply-To: <CAOQ_QsgGiGSfEq1QGfePiRF-=spCuR6XZ2QXfUsZ1zWds0ftag@mail.gmail.com>
References: <20210818181432.432256-1-maz@kernel.org>
 <CAJHc60zUZS3K4q88QYwP2CkGn7ywt-_fedjk7OK_W7cdQRJvxA@mail.gmail.com>
 <CAOQ_QsgGiGSfEq1QGfePiRF-=spCuR6XZ2QXfUsZ1zWds0ftag@mail.gmail.com>
Message-ID: <87o89uzbs9.wl-maz@kernel.org>

On Wed, 18 Aug 2021 20:40:42 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Hey Marc,
> 
> On Wed, Aug 18, 2021 at 12:05 PM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > On Wed, Aug 18, 2021 at 11:14 AM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > When a mapped level interrupt (a timer, for example) is deactivated
> > > by the guest, the corresponding host interrupt is equally deactivated.
> > > However, the fate of the pending state still needs to be dealt
> > > with in SW.
> > >
> > > This is specially true when the interrupt was in the active+pending
> > > state in the virtual distributor at the point where the guest
> > > was entered. On exit, the pending state is potentially stale
> > > (the guest may have put the interrupt in a non-pending state).
> > >
> > > If we don't do anything, the interrupt will be spuriously injected
> > > in the guest. Although this shouldn't have any ill effect (spurious
> > > interrupts are always possible), we can improve the emulation by
> > > detecting the deactivation-while-pending case and resample the
> > > interrupt.
> > >
> > > Fixes: e40cc57bac79 ("KVM: arm/arm64: vgic: Support level-triggered mapped interrupts")
> > > Reported-by: Raghavendra Rao Ananta <rananta at google.com>
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > Cc: stable at vger.kernel.org
> > > ---
> > >  arch/arm64/kvm/vgic/vgic-v2.c | 25 ++++++++++++++++++-------
> > >  arch/arm64/kvm/vgic/vgic-v3.c | 25 ++++++++++++++++++-------
> > >  2 files changed, 36 insertions(+), 14 deletions(-)
> > >
> > Tested-by: Raghavendra Rao Ananta <rananta at google.com>
> >
> > Thanks,
> > Raghavendra
> > > diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
> > > index 2c580204f1dc..3e52ea86a87f 100644
> > > --- a/arch/arm64/kvm/vgic/vgic-v2.c
> > > +++ b/arch/arm64/kvm/vgic/vgic-v2.c
> > > @@ -60,6 +60,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> > >                 u32 val = cpuif->vgic_lr[lr];
> > >                 u32 cpuid, intid = val & GICH_LR_VIRTUALID;
> > >                 struct vgic_irq *irq;
> > > +               bool deactivated;
> > >
> > >                 /* Extract the source vCPU id from the LR */
> > >                 cpuid = val & GICH_LR_PHYSID_CPUID;
> > > @@ -75,7 +76,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> > >
> > >                 raw_spin_lock(&irq->irq_lock);
> > >
> > > -               /* Always preserve the active bit */
> > > +               /* Always preserve the active bit, note deactivation */
> > > +               deactivated = irq->active && !(val & GICH_LR_ACTIVE_BIT);
> > >                 irq->active = !!(val & GICH_LR_ACTIVE_BIT);
> > >
> > >                 if (irq->active && vgic_irq_is_sgi(intid))
> > > @@ -105,6 +107,12 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> > >                  * device state could have changed or we simply need to
> > >                  * process the still pending interrupt later.
> > >                  *
> > > +                * We could also have entered the guest with the interrupt
> > > +                * active+pending. On the next exit, we need to re-evaluate
> > > +                * the pending state, as it could otherwise result in a
> > > +                * spurious interrupt by injecting a now potentially stale
> > > +                * pending state.
> > > +                *
> > >                  * If this causes us to lower the level, we have to also clear
> > >                  * the physical active state, since we will otherwise never be
> > >                  * told when the interrupt becomes asserted again.
> > > @@ -115,12 +123,15 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
> > >                 if (vgic_irq_is_mapped_level(irq)) {
> > >                         bool resample = false;
> > >
> > > -                       if (val & GICH_LR_PENDING_BIT) {
> > > -                               irq->line_level = vgic_get_phys_line_level(irq);
> > > -                               resample = !irq->line_level;
> > > -                       } else if (vgic_irq_needs_resampling(irq) &&
> > > -                                  !(irq->active || irq->pending_latch)) {
> > > -                               resample = true;
> > > +                       if (unlikely(vgic_irq_needs_resampling(irq))) {
> > > +                               if (!(irq->active || irq->pending_latch))
> > > +                                       resample = true;
> > > +                       } else {
> > > +                               if ((val & GICH_LR_PENDING_BIT) ||
> > > +                                   (deactivated && irq->line_level)) {
> > > +                                       irq->line_level = vgic_get_phys_line_level(irq);
> > > +                                       resample = !irq->line_level;
> > > +                               }
> > >                         }
> > >
> > >                         if (resample)
> > > diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
> > > index 66004f61cd83..74f9aefffd5e 100644
> > > --- a/arch/arm64/kvm/vgic/vgic-v3.c
> > > +++ b/arch/arm64/kvm/vgic/vgic-v3.c
> > > @@ -46,6 +46,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
> > >                 u32 intid, cpuid;
> > >                 struct vgic_irq *irq;
> > >                 bool is_v2_sgi = false;
> > > +               bool deactivated;
> > >
> > >                 cpuid = val & GICH_LR_PHYSID_CPUID;
> > >                 cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT;
> > > @@ -68,7 +69,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
> > >
> > >                 raw_spin_lock(&irq->irq_lock);
> > >
> > > -               /* Always preserve the active bit */
> > > +               /* Always preserve the active bit, note deactivation */
> > > +               deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT);
> > >                 irq->active = !!(val & ICH_LR_ACTIVE_BIT);
> > >
> > >                 if (irq->active && is_v2_sgi)
> > > @@ -98,6 +100,12 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
> > >                  * device state could have changed or we simply need to
> > >                  * process the still pending interrupt later.
> > >                  *
> > > +                * We could also have entered the guest with the interrupt
> > > +                * active+pending. On the next exit, we need to re-evaluate
> > > +                * the pending state, as it could otherwise result in a
> > > +                * spurious interrupt by injecting a now potentially stale
> > > +                * pending state.
> > > +                *
> > >                  * If this causes us to lower the level, we have to also clear
> > >                  * the physical active state, since we will otherwise never be
> > >                  * told when the interrupt becomes asserted again.
> > > @@ -108,12 +116,15 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
> > >                 if (vgic_irq_is_mapped_level(irq)) {
> > >                         bool resample = false;
> > >
> > > -                       if (val & ICH_LR_PENDING_BIT) {
> > > -                               irq->line_level = vgic_get_phys_line_level(irq);
> > > -                               resample = !irq->line_level;
> > > -                       } else if (vgic_irq_needs_resampling(irq) &&
> > > -                                  !(irq->active || irq->pending_latch)) {
> > > -                               resample = true;
> > > +                       if (unlikely(vgic_irq_needs_resampling(irq))) {
> > > +                               if (!(irq->active || irq->pending_latch))
> > > +                                       resample = true;
> > > +                       } else {
> > > +                               if ((val & ICH_LR_PENDING_BIT) ||
> > > +                                   (deactivated && irq->line_level)) {
> > > +                                       irq->line_level = vgic_get_phys_line_level(irq);
> > > +                                       resample = !irq->line_level;
> > > +                               }
> 
> The vGICv3 and vGICv2 implementations look identical here, should we
> have a helper that keeps the code common between the two?

Probably. This code used to be much simpler, but it has grown a bit
unwieldy since I added the M1 support hack. This change doesn't make
look any better so it is probably time for a minor refactor.

I've pushed out an updated patch, but I'll wait a bit more for
additional feedback before posting it again.

> 
> Otherwise, the functional change LGTM, so:
> 
> Reviewed-by: Oliver Upton <oupton at google.com>

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From heiko at sntech.de  Wed Aug 18 14:25:24 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 18 Aug 2021 23:25:24 +0200
Subject: (subset) [PATCH v2 0/8] fixes and enablement for rk356x
In-Reply-To: <20210728180034.717953-1-pgwipeout@gmail.com>
References: <20210728180034.717953-1-pgwipeout@gmail.com>
Message-ID: <162932191989.2857998.7332944656635209644.b4-ty@sntech.de>

On Wed, 28 Jul 2021 14:00:26 -0400, Peter Geis wrote:
> Good Morning,
> 
> This series aims to fix some early issues with the rk356x and enable
> nodes that are currently supported by the available drivers.
> 
> 1. fixes the mbi-alias, which points to the wrong location
> 2. fixes the rockchip clk-pll to work without a grf node
> 3. adds the gpio debounce clocks which are necessary for gpio to bind
> 4. adds the common gmac1 node
> 5. adds the tsadc nodes
> 6. adjusts the gpll and ppll clocks to better support hardware
> 7. enables the gmac1 on the Quartz64
> 8. adds thermal support to the Quartz64
> 
> [...]

Applied, thanks!

[3/8] arm64: dts: rockchip: add rk356x gpio debounce clocks
      commit: bf092ebe6e81fe7f7b710e749a3debfece193ff5

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From christophe.jaillet at wanadoo.fr  Wed Aug 18 14:21:59 2021
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Wed, 18 Aug 2021 23:21:59 +0200
Subject: [PATCH] soc: fsl: guts: Fix a resource leak in the error handling
 path of 'fsl_guts_probe()'
Message-ID: <b12e8c5c5d6ab3061d9504de8fbaefcad6bbc385.1629321668.git.christophe.jaillet@wanadoo.fr>

If an error occurs after 'of_find_node_by_path()', the reference taken for
'root' will never be released and some memory will leak.

Instead of adding an error handling path and modifying all the
'return -SOMETHING' into 'goto errorpath', use 'devm_add_action_or_reset()'
to release the reference when needed.

Simplify the remove function accordingly.

As an extra benefit, the 'root' global variable can now be removed as well.

Fixes: 3c0d64e867ed ("soc: fsl: guts: reuse machine name from device tree")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
Compile tested only
---
 drivers/soc/fsl/guts.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index d5e9a5f2c087..4d9476c7b87c 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -28,7 +28,6 @@ struct fsl_soc_die_attr {
 static struct guts *guts;
 static struct soc_device_attribute soc_dev_attr;
 static struct soc_device *soc_dev;
-static struct device_node *root;
 
 
 /* SoC die attribute definition for QorIQ platform */
@@ -136,14 +135,23 @@ static u32 fsl_guts_get_svr(void)
 	return svr;
 }
 
+static void fsl_guts_put_root(void *data)
+{
+	struct device_node *root = data;
+
+	of_node_put(root);
+}
+
 static int fsl_guts_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
+	struct device_node *root;
 	struct resource *res;
 	const struct fsl_soc_die_attr *soc_die;
 	const char *machine;
 	u32 svr;
+	int ret;
 
 	/* Initialize guts */
 	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
@@ -159,6 +167,10 @@ static int fsl_guts_probe(struct platform_device *pdev)
 
 	/* Register soc device */
 	root = of_find_node_by_path("/");
+	ret = devm_add_action_or_reset(dev, fsl_guts_put_root, root);
+	if (ret)
+		return ret;
+
 	if (of_property_read_string(root, "model", &machine))
 		of_property_read_string_index(root, "compatible", 0, &machine);
 	if (machine)
@@ -197,7 +209,7 @@ static int fsl_guts_probe(struct platform_device *pdev)
 static int fsl_guts_remove(struct platform_device *dev)
 {
 	soc_device_unregister(soc_dev);
-	of_node_put(root);
+
 	return 0;
 }
 
-- 
2.30.2



From heiko at sntech.de  Wed Aug 18 14:42:44 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 18 Aug 2021 23:42:44 +0200
Subject: (subset) [PATCH v2 0/8] fixes and enablement for rk356x
In-Reply-To: <20210728180034.717953-1-pgwipeout@gmail.com>
References: <20210728180034.717953-1-pgwipeout@gmail.com>
Message-ID: <162932289621.2860738.15310161824918921933.b4-ty@sntech.de>

On Wed, 28 Jul 2021 14:00:26 -0400, Peter Geis wrote:
> Good Morning,
> 
> This series aims to fix some early issues with the rk356x and enable
> nodes that are currently supported by the available drivers.
> 
> 1. fixes the mbi-alias, which points to the wrong location
> 2. fixes the rockchip clk-pll to work without a grf node
> 3. adds the gpio debounce clocks which are necessary for gpio to bind
> 4. adds the common gmac1 node
> 5. adds the tsadc nodes
> 6. adjusts the gpll and ppll clocks to better support hardware
> 7. enables the gmac1 on the Quartz64
> 8. adds thermal support to the Quartz64
> 
> [...]

Applied, thanks!

[5/8] arm64: dts: rockchip: add rk3568 tsadc nodes
      commit: 1a9563ba0a59b221156d80a3a77a43fdd144576c

[I've moved the tsadc-pin pin setting to the second pinctrl
 block meant to hand-crafted pin settings in rk3568-pinctrl.dtsi]


[8/8] arm64: dts: rockchip: add thermal support to Quartz64 Model A
      commit: d0e2e61b3cbaab474e2093ceb2073c4441bd36f8

Looks like we're all done with that series now.

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From alexdeucher at gmail.com  Wed Aug 18 14:51:36 2021
From: alexdeucher at gmail.com (Alex Deucher)
Date: Wed, 18 Aug 2021 17:51:36 -0400
Subject: [PATCH 2/5] drm: amdgpu: remove obsolete reference to config CHASH
In-Reply-To: <20210818124114.28545-3-lukas.bulwahn@gmail.com>
References: <20210818124114.28545-1-lukas.bulwahn@gmail.com>
 <20210818124114.28545-3-lukas.bulwahn@gmail.com>
Message-ID: <CADnq5_MiTXcAu1kK3-9m=nFoT+SxF9SBv9wYgm2-WNVt_85RQA@mail.gmail.com>

Applied.  Thanks!

Alex

On Wed, Aug 18, 2021 at 8:41 AM Lukas Bulwahn <lukas.bulwahn at gmail.com> wrote:
>
> Commit 04ed8459f334 ("drm/amdgpu: remove chash") removes the chash
> architecture and its corresponding config CHASH.
>
> There is still a reference to CHASH in the config DRM_AMDGPU in
> ./drivers/gpu/drm/Kconfig.
>
> Remove this obsolete reference to config CHASH.
>
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
> ---
>  drivers/gpu/drm/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index f3bc90baca61..8fc40317f2b7 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -257,7 +257,6 @@ config DRM_AMDGPU
>         select HWMON
>         select BACKLIGHT_CLASS_DEVICE
>         select INTERVAL_TREE
> -       select CHASH
>         help
>           Choose this option if you have a recent AMD Radeon graphics card.
>
> --
> 2.26.2
>


From heiko at sntech.de  Wed Aug 18 15:14:48 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 19 Aug 2021 00:14:48 +0200
Subject: (subset) [PATCH v13 0/6] Add Rockchip SFC(serial flash
 controller) support
In-Reply-To: <20210812134546.31340-1-jon.lin@rock-chips.com>
References: <20210812134546.31340-1-jon.lin@rock-chips.com>
Message-ID: <162932487840.2867187.12225818198624183651.b4-ty@sntech.de>

On Thu, 12 Aug 2021 21:45:40 +0800, Jon Lin wrote:
> Changes in v13:
> - Provide independent interfaces to obtain RX TX FIFO status respectively
> - Add more debug information
> - Depress DMA limitation
> 
> Changes in v12:
> - Remove useless oneOf lable
> - Add sfc controller discription
> - Remove the limitation of SFC_MIN_SPEED_HZ
> - Add IRQ_NONE method for irq handler
> - Add SPI_MASTER_HALF_DUPLEX flags
> - Add sfc interrupt mask bits and status register initial progress
> 
> [...]

Applied, thanks!

[3/6] arm64: dts: rockchip: Add SFC to PX30
      commit: c68defec1585819af54f011fa4d47892b38fb74a
[4/6] arm: dts: rockchip: Add SFC to RV1108
      commit: 9d508827c7939242e8ed6b06f66aa87d9f7ea832
[5/6] arm64: dts: rockchip: Add SFC to RK3308
      commit: ab438ba2dc6b7bd3dce8e3c8b0f131905cd133d9
[6/6] arm64: dts: rockchip: Enable SFC for Odroid Go Advance
      commit: f9576999b0aef399e7cb1065787032d42198c362

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From paulmck at kernel.org  Wed Aug 18 15:46:51 2021
From: paulmck at kernel.org (Paul E. McKenney)
Date: Wed, 18 Aug 2021 15:46:51 -0700
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20210817144018.nqssoq475vitrqlv@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
Message-ID: <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>

On Tue, Aug 17, 2021 at 04:40:18PM +0200, Sebastian Andrzej Siewior wrote:
> From: Scott Wood <swood at redhat.com>
> 
> rcutorture was generating some nesting scenarios that are not
> reasonable.  Constrain the state selection to avoid them.
> 
> Example:
> 
> 1. rcu_read_lock()
> 2. local_irq_disable()
> 3. rcu_read_unlock()
> 4. local_irq_enable()
> 
> If the thread is preempted between steps 1 and 2,
> rcu_read_unlock_special.b.blocked will be set, but it won't be
> acted on in step 3 because IRQs are disabled.  Thus, reporting of the
> quiescent state will be delayed beyond the local_irq_enable().
> 
> For now, these scenarios will continue to be tested on non-PREEMPT_RT
> kernels, until debug checks are added to ensure that they are not
> happening elsewhere.
> 
> Signed-off-by: Scott Wood <swood at redhat.com>
> [valentin.schneider at arm.com: Don't disable BH in atomic context]
> [bigeasy: remove 'preempt_disable(); local_bh_disable(); preempt_enable();
>  local_bh_enable();' from the examples because this works on RT now. ]
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

This looks close to being ready for mainline, actually.

One comment below.

							Thanx, Paul

> ---
> I folded Valentin's bits.
> I removed the unbalanced preempt_disable()/migrate_disable() part from
> the description because it is supported now by the migrate disable
> implementation. I didn't find it explicit in code/ patch except as part
> of local_bh_disable().
> 
> 
>  kernel/rcu/rcutorture.c |   94 ++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 80 insertions(+), 14 deletions(-)
> ---
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -61,10 +61,13 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck
>  #define RCUTORTURE_RDR_RBH	 0x08	/*  ... rcu_read_lock_bh(). */
>  #define RCUTORTURE_RDR_SCHED	 0x10	/*  ... rcu_read_lock_sched(). */
>  #define RCUTORTURE_RDR_RCU	 0x20	/*  ... entering another RCU reader. */
> -#define RCUTORTURE_RDR_NBITS	 6	/* Number of bits defined above. */
> +#define RCUTORTURE_RDR_ATOM_BH	 0x40	/*  ... disabling bh while atomic */
> +#define RCUTORTURE_RDR_ATOM_RBH	 0x80	/*  ... RBH while atomic */
> +#define RCUTORTURE_RDR_NBITS	 8	/* Number of bits defined above. */
>  #define RCUTORTURE_MAX_EXTEND	 \
>  	(RCUTORTURE_RDR_BH | RCUTORTURE_RDR_IRQ | RCUTORTURE_RDR_PREEMPT | \
> -	 RCUTORTURE_RDR_RBH | RCUTORTURE_RDR_SCHED)
> +	 RCUTORTURE_RDR_RBH | RCUTORTURE_RDR_SCHED | \
> +	 RCUTORTURE_RDR_ATOM_BH | RCUTORTURE_RDR_ATOM_RBH)
>  #define RCUTORTURE_RDR_MAX_LOOPS 0x7	/* Maximum reader extensions. */
>  					/* Must be power of two minus one. */
>  #define RCUTORTURE_RDR_MAX_SEGS (RCUTORTURE_RDR_MAX_LOOPS + 3)
> @@ -1429,31 +1432,53 @@ static void rcutorture_one_extend(int *r
>  	WARN_ON_ONCE((idxold >> RCUTORTURE_RDR_SHIFT) > 1);
>  	rtrsp->rt_readstate = newstate;
>  
> -	/* First, put new protection in place to avoid critical-section gap. */
> +	/*
> +	 * First, put new protection in place to avoid critical-section gap.
> +	 * Disable preemption around the ATOM disables to ensure that
> +	 * in_atomic() is true.
> +	 */
>  	if (statesnew & RCUTORTURE_RDR_BH)
>  		local_bh_disable();
> +	if (statesnew & RCUTORTURE_RDR_RBH)
> +		rcu_read_lock_bh();
>  	if (statesnew & RCUTORTURE_RDR_IRQ)
>  		local_irq_disable();
>  	if (statesnew & RCUTORTURE_RDR_PREEMPT)
>  		preempt_disable();
> -	if (statesnew & RCUTORTURE_RDR_RBH)
> -		rcu_read_lock_bh();
>  	if (statesnew & RCUTORTURE_RDR_SCHED)
>  		rcu_read_lock_sched();
> +	preempt_disable();
> +	if (statesnew & RCUTORTURE_RDR_ATOM_BH)
> +		local_bh_disable();
> +	if (statesnew & RCUTORTURE_RDR_ATOM_RBH)
> +		rcu_read_lock_bh();
> +	preempt_enable();
>  	if (statesnew & RCUTORTURE_RDR_RCU)
>  		idxnew = cur_ops->readlock() << RCUTORTURE_RDR_SHIFT;
>  
> -	/* Next, remove old protection, irq first due to bh conflict. */
> +	/*
> +	 * Next, remove old protection, in decreasing order of strength
> +	 * to avoid unlock paths that aren't safe in the stronger
> +	 * context.  Disable preemption around the ATOM enables in
> +	 * case the context was only atomic due to IRQ disabling.
> +	 */
> +	preempt_disable();
>  	if (statesold & RCUTORTURE_RDR_IRQ)
>  		local_irq_enable();
> -	if (statesold & RCUTORTURE_RDR_BH)
> +	if (statesold & RCUTORTURE_RDR_ATOM_BH)
>  		local_bh_enable();
> +	if (statesold & RCUTORTURE_RDR_ATOM_RBH)
> +		rcu_read_unlock_bh();
> +	preempt_enable();

The addition of preempt_enable() here prevents rcutorture from covering
an important part of the mainline RCU state space, namely when an RCU
read-side section ends with just local_irq_enable().  This situation
is a challenge for RCU because it must indirectly detect the end of the
critical section.

Would it work for RT if the preempt_enable() and preempt_disable()
were executed only if either RT on the one hand or statesold has the
RCUTORTURE_RDR_ATOM_BH or RCUTORTURE_RDR_ATOM_RBH bit set on the other?

>  	if (statesold & RCUTORTURE_RDR_PREEMPT)
>  		preempt_enable();
> -	if (statesold & RCUTORTURE_RDR_RBH)
> -		rcu_read_unlock_bh();
>  	if (statesold & RCUTORTURE_RDR_SCHED)
>  		rcu_read_unlock_sched();
> +	if (statesold & RCUTORTURE_RDR_BH)
> +		local_bh_enable();
> +	if (statesold & RCUTORTURE_RDR_RBH)
> +		rcu_read_unlock_bh();
> +
>  	if (statesold & RCUTORTURE_RDR_RCU) {
>  		bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);
>  
> @@ -1496,6 +1521,12 @@ rcutorture_extend_mask(int oldmask, stru
>  	int mask = rcutorture_extend_mask_max();
>  	unsigned long randmask1 = torture_random(trsp) >> 8;
>  	unsigned long randmask2 = randmask1 >> 3;
> +	unsigned long preempts = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;
> +	unsigned long preempts_irq = preempts | RCUTORTURE_RDR_IRQ;
> +	unsigned long nonatomic_bhs = RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
> +	unsigned long atomic_bhs = RCUTORTURE_RDR_ATOM_BH |
> +				   RCUTORTURE_RDR_ATOM_RBH;
> +	unsigned long tmp;
>  
>  	WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT);
>  	/* Mostly only one bit (need preemption!), sometimes lots of bits. */
> @@ -1503,11 +1534,46 @@ rcutorture_extend_mask(int oldmask, stru
>  		mask = mask & randmask2;
>  	else
>  		mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS));
> -	/* Can't enable bh w/irq disabled. */
> -	if ((mask & RCUTORTURE_RDR_IRQ) &&
> -	    ((!(mask & RCUTORTURE_RDR_BH) && (oldmask & RCUTORTURE_RDR_BH)) ||
> -	     (!(mask & RCUTORTURE_RDR_RBH) && (oldmask & RCUTORTURE_RDR_RBH))))
> -		mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
> +
> +	/*
> +	 * Can't enable bh w/irq disabled.
> +	 */
> +	tmp = atomic_bhs | nonatomic_bhs;
> +	if (mask & RCUTORTURE_RDR_IRQ)
> +		mask |= oldmask & tmp;

This is more straightforward than my original, good!

> +
> +	/*
> +	 * Ideally these sequences would be detected in debug builds
> +	 * (regardless of RT), but until then don't stop testing
> +	 * them on non-RT.
> +	 */
> +	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> +		/*
> +		 * Can't disable bh in atomic context if bh was already
> +		 * disabled by another task on the same CPU. Instead of
> +		 * attempting to track this, just avoid disabling bh in atomic
> +		 * context.
> +		 */
> +		mask &= ~atomic_bhs;

At some point, we will need to test disabling bh in atomic context,
correct?  Or am I missing something here?

> +		/*
> +		 * Can't release the outermost rcu lock in an irq disabled
> +		 * section without preemption also being disabled, if irqs
> +		 * had ever been enabled during this RCU critical section
> +		 * (could leak a special flag and delay reporting the qs).
> +		 */
> +		if ((oldmask & RCUTORTURE_RDR_RCU) &&
> +		    (mask & RCUTORTURE_RDR_IRQ) &&
> +		    !(mask & preempts))
> +			mask |= RCUTORTURE_RDR_RCU;
> +
> +		/* Can't modify non-atomic bh in atomic context */
> +		tmp = nonatomic_bhs;
> +		if (oldmask & preempts_irq)
> +			mask &= ~tmp;
> +		if ((oldmask | mask) & preempts_irq)
> +			mask |= oldmask & tmp;
> +	}
> +
>  	return mask ?: RCUTORTURE_RDR_RCU;
>  }
>  


From mhiramat at kernel.org  Wed Aug 18 16:36:44 2021
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Thu, 19 Aug 2021 08:36:44 +0900
Subject: [PATCH] ASoC: uniphier: make arrays mul and div static const,
 makes object smaller
In-Reply-To: <20210818151746.38520-1-colin.king@canonical.com>
References: <20210818151746.38520-1-colin.king@canonical.com>
Message-ID: <20210819083644.6c88a29eef5926eca76cffcb@kernel.org>

On Wed, 18 Aug 2021 16:17:46 +0100
Colin King <colin.king at canonical.com> wrote:

> From: Colin Ian King <colin.king at canonical.com>
> 
> Don't populate the arrays mul and div on the stack but instead make them
> static const. Makes the object code smaller by 4 bytes.
> 
> Before:
>    text    data     bss     dec     hex filename
>   16226    4984      64   21274    531a ./sound/soc/uniphier/aio-cpu.o
> 
> After:
>    text    data     bss     dec     hex filename
>   16062    5144      64   21270    5316 ./sound/soc/uniphier/aio-cpu.o
> 
> (gcc version 10.2.0)

This looks good to me.

Acked-by: Masami Hiramatsu <mhiramat at kernel.org>

Thank you,

> 
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>  sound/soc/uniphier/aio-cpu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
> index cf9814130067..4e8d5f7532ba 100644
> --- a/sound/soc/uniphier/aio-cpu.c
> +++ b/sound/soc/uniphier/aio-cpu.c
> @@ -128,8 +128,8 @@ static const struct uniphier_aio_spec *find_spec(struct uniphier_aio *aio,
>  static int find_divider(struct uniphier_aio *aio, int pll_id, unsigned int freq)
>  {
>  	struct uniphier_aio_pll *pll;
> -	int mul[] = { 1, 1, 1, 2, };
> -	int div[] = { 2, 3, 1, 3, };
> +	static const int mul[] = { 1, 1, 1, 2, };
> +	static const int div[] = { 2, 3, 1, 3, };
>  	int i;
>  
>  	if (!is_valid_pll(aio->chip, pll_id))
> -- 
> 2.32.0
> 


-- 
Masami Hiramatsu <mhiramat at kernel.org>


From linus.walleij at linaro.org  Wed Aug 18 16:37:33 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 19 Aug 2021 01:37:33 +0200
Subject: [PATCH] pinctrl: pinctrl-zynq: Add warning for not to use
 'io-standard'
In-Reply-To: <447d7205-f562-72c2-8317-031cd733d60c@xilinx.com>
References: <1629265999-33358-1-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com>
 <447d7205-f562-72c2-8317-031cd733d60c@xilinx.com>
Message-ID: <CACRpkdadQujzApH_XKhe5LD46S4GUseXKQ_mV4Jv7eaA5u1yUg@mail.gmail.com>

On Wed, Aug 18, 2021 at 8:00 AM Michal Simek <michal.simek at xilinx.com> wrote:

> Linus: would be good to know how long we should keep the support for
> this deprecated dt property.

We use the "noone hears the tree fall in an empty forest"-metric.
If no user suffers, we can drop it. Determining that requires some
kind of reasoning about when that happens, and then the maintainer
of the driver decides.

Yours,
Linus Walleij


From zhiyong.tao at mediatek.com  Wed Aug 18 18:49:08 2021
From: zhiyong.tao at mediatek.com (zhiyong.tao)
Date: Thu, 19 Aug 2021 09:49:08 +0800
Subject: [PATCH v10 1/2] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <CAGXv+5EUAVFJd7VZsDgpOK_6fhs12ztwKHioghq5ZQHzFKY89w@mail.gmail.com>
References: <20210710081722.1828-1-zhiyong.tao@mediatek.com>
 <20210710081722.1828-2-zhiyong.tao@mediatek.com>
 <CAGXv+5GXg0RuOQkh4vaRmcLpehZiXnEUXBvEaObiatAa1sXvaA@mail.gmail.com>
 <1626940470.29611.9.camel@mhfsdcap03>
 <CAGXv+5F_-W4aNt0WVSDBGLo_t8orNUq59GMKk_4xVr+hMb9Ctg@mail.gmail.com>
 <07388dac4e25e0f260725e8f80ba099d5aa80949.camel@mediatek.com>
 <CAGXv+5EagmhYYpri+nzo6WgGz8A=oiU3Vy+2AVjho=eo6Z+DLw@mail.gmail.com>
 <CACRpkdZ4k9Km3vBtdN6AnBM89c4355GtPMzCQ0_YHaTb4V5cKA@mail.gmail.com>
 <CAGXv+5HohMwU8jow5QXO5MK1tO+u=5YsfhArBWCP4Dgm1Q8igg@mail.gmail.com>
 <4fd12d5c53f6492e5fa3ba94a78b9a149f5b6ed9.camel@mediatek.com>
 <CAGXv+5GCuNK=-z9VAOjkpJdZLUSZFPfUsQ09m1FhfTsbCYLLRw@mail.gmail.com>
 <CACRpkdbZKh8cqqiDRUik6Ooo33e+feGwYsLjcLRvBQnT3x5M3A@mail.gmail.com>
 <a7c8ab68ac3513865698cde27e665bdd554f459e.camel@mediatek.com>
 <CAGXv+5FtL2zaSWx4tUymx6mpCSb5dXG4XNWM9AJL+b6Ok3dxMg@mail.gmail.com>
 <d40f6d5fd26aedb13e7a393202e5794b1893ecf8.camel@mediatek.com>
 <CACRpkdYkwXr76Kq5WYdz=1KkLTpaByAL1vJFo8V+2mncqs8-3Q@mail.gmail.com>
 <CAGXv+5EUAVFJd7VZsDgpOK_6fhs12ztwKHioghq5ZQHzFKY89w@mail.gmail.com>
Message-ID: <dff9c2c8358594a15fab543415bc084058d33bb7.camel@mediatek.com>

On Wed, 2021-08-18 at 14:25 +0800, Chen-Yu Tsai wrote:
> On Wed, Aug 18, 2021 at 4:09 AM Linus Walleij <
> linus.walleij at linaro.org> wrote:
> > 
> > On Tue, Aug 17, 2021 at 9:51 AM zhiyong.tao <
> > zhiyong.tao at mediatek.com> wrote:
> > 
> > > In one chip, If GPIO is different, the MTXXXX_PULL_UP_RSEL_001
> > > may
> > > means different actual bias resistance setting.
> > > 
> > > For example,
> > > 
> > > KPROW IO
> > > Paramters       Descriptions                   Min      Typ     M
> > > ax
> > >  UNIT
> > > Rpd     Input pull-down
> > > resistance      40      75      190     Kohm
> > > Rpu     Input pull-up
> > > resistance        40      75      190     Kohm
> > > Rpd     Input pull-down
> > > resistance      0.8     1.6     2       Kohm
> > > Rpu     Input pull-up
> > > resistance        0.8     1.6     2       Kohm
> > 
> > This is exactly why we should try to use SI units in the device
> > tree.
> > I assume that the software can eventually configure which
> > resistance
> > it gets?
> > 
> > The electronics people will say make sure it is pulled down by
> > around
> > 80 kOhm, they can put that on the device tree and your code can
> > say, "hm 40 < 80 < 190 this is OK" and let the value pass.
> > 
> > We do not define these exact semantics, it is up to the driver code
> > to decide what to do with the Ohm value 80000 in this case, but
> > it makes perfect sent for me to let it pass and fail if someone
> > for example requests 20 kOhm, or at least print a helpful warning:
> > 
> > dev_warn(dev, "the requested resistance %d is out of range,
> > supported
> > range %d to %d kOhm\n",
> >                  val, low, high);
> > 
> > This is what makes the SI units really helpful for people writing
> > device
> > trees: solve real integration tasks and make it easy to do the
> > right thing.
> 
> I think this makes a lot of sense. The driver could select the
> closest
> setting. And from what Zhiyong mentioned offline, the resistor values
> aren't exact as specified in the datasheet. I suppose this is
> expected
> with any electronics. So the hardware integration will say to pull up
> or down by some value, and the driver will do its best to fulfill
> that
> request. That precludes DT schema checking for the values used, but I
> think that is a good compromise.
> 
> Zhiyong also mentioned that some of their downstream integrators
> might
> not be able to deal with actual values, and would prefer symbols tied
> to specific RSEL values. I think that would be doable together using
> some _magic_ values, but I would prefer not to if it were avoidable.
> 
> 
> Regards
> ChenYu

Hi chenyu & Linus,

Thanks for your suggestion.

we will try to update a new version to use SI units in the device tree
in the rsel feature patch.

Thanks

From lkp at intel.com  Wed Aug 18 19:10:59 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Aug 2021 10:10:59 +0800
Subject: [soc:hisi/dt] BUILD SUCCESS 2dc30eb9241c21cbeaf5b668f4eb276278149d97
Message-ID: <611dbdb3.H1A9u6bdW7RHqsoY%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git hisi/dt
branch HEAD: 2dc30eb9241c21cbeaf5b668f4eb276278149d97  arm64: dts: HiSilicon: hi3660: address a PCI warning

elapsed time: 8187m

configs tested: 251
configs skipped: 148

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210813
i386                 randconfig-c001-20210818
nios2                         3c120_defconfig
powerpc                     pseries_defconfig
mips                         mpc30x_defconfig
powerpc                     kmeter1_defconfig
m68k                             allyesconfig
powerpc                     mpc5200_defconfig
m68k                          hp300_defconfig
sh                        edosk7760_defconfig
powerpc                     asp8347_defconfig
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
mips                        workpad_defconfig
powerpc                     pq2fads_defconfig
powerpc                      walnut_defconfig
powerpc                       holly_defconfig
arm                             ezx_defconfig
powerpc                     mpc512x_defconfig
xtensa                  nommu_kc705_defconfig
powerpc                      tqm8xx_defconfig
arm                         lpc18xx_defconfig
x86_64                            allnoconfig
sh                             shx3_defconfig
m68k                       m5475evb_defconfig
csky                                defconfig
powerpc                      acadia_defconfig
mips                       bmips_be_defconfig
powerpc                 mpc837x_mds_defconfig
arm                     davinci_all_defconfig
arm                       omap2plus_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
powerpc                         ps3_defconfig
arm                         hackkit_defconfig
sh                           se7724_defconfig
powerpc                      pmac32_defconfig
xtensa                           allyesconfig
arm                       imx_v4_v5_defconfig
powerpc                      ep88xc_defconfig
powerpc                     rainier_defconfig
sh                            shmin_defconfig
h8300                               defconfig
arm                        clps711x_defconfig
sh                           se7750_defconfig
powerpc                    socrates_defconfig
riscv                             allnoconfig
powerpc                     ksi8560_defconfig
powerpc                 mpc837x_rdb_defconfig
powerpc                    adder875_defconfig
arm                        spear6xx_defconfig
sh                             sh03_defconfig
powerpc                       ppc64_defconfig
mips                      maltaaprp_defconfig
mips                           ip28_defconfig
sh                          urquell_defconfig
arm                      tct_hammer_defconfig
csky                             alldefconfig
arm                           sama5_defconfig
m68k                          amiga_defconfig
powerpc                   microwatt_defconfig
mips                          ath25_defconfig
sh                          rsk7201_defconfig
m68k                       m5249evb_defconfig
arm                        mvebu_v5_defconfig
arm                          ep93xx_defconfig
arm                       aspeed_g4_defconfig
nios2                         10m50_defconfig
m68k                       bvme6000_defconfig
microblaze                          defconfig
um                                  defconfig
arc                              alldefconfig
mips                           ip22_defconfig
powerpc                 mpc85xx_cds_defconfig
mips                     decstation_defconfig
powerpc                         wii_defconfig
arm                          exynos_defconfig
powerpc                    amigaone_defconfig
arm                         s5pv210_defconfig
arm                           viper_defconfig
arm                         orion5x_defconfig
sh                          lboxre2_defconfig
arm                    vt8500_v6_v7_defconfig
sh                          r7785rp_defconfig
arm                            xcep_defconfig
h8300                    h8300h-sim_defconfig
sh                         ecovec24_defconfig
arm                         axm55xx_defconfig
mips                  decstation_64_defconfig
mips                     loongson2k_defconfig
parisc                generic-64bit_defconfig
powerpc                     sequoia_defconfig
arc                     nsimosci_hs_defconfig
arm                         bcm2835_defconfig
arm                            pleb_defconfig
arc                        nsim_700_defconfig
mips                 decstation_r4k_defconfig
arm                             rpc_defconfig
arm                        cerfcube_defconfig
sh                           sh2007_defconfig
arm                          pcm027_defconfig
mips                      loongson3_defconfig
ia64                             alldefconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
i386                 randconfig-a004-20210814
i386                 randconfig-a002-20210814
i386                 randconfig-a001-20210814
i386                 randconfig-a003-20210814
i386                 randconfig-a006-20210814
i386                 randconfig-a005-20210814
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
i386                 randconfig-a004-20210813
i386                 randconfig-a003-20210813
i386                 randconfig-a001-20210813
i386                 randconfig-a002-20210813
i386                 randconfig-a006-20210813
i386                 randconfig-a005-20210813
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
x86_64               randconfig-a011-20210813
x86_64               randconfig-a013-20210813
x86_64               randconfig-a012-20210813
x86_64               randconfig-a016-20210813
x86_64               randconfig-a015-20210813
x86_64               randconfig-a014-20210813
x86_64               randconfig-a013-20210819
x86_64               randconfig-a011-20210819
x86_64               randconfig-a012-20210819
x86_64               randconfig-a016-20210819
x86_64               randconfig-a014-20210819
x86_64               randconfig-a015-20210819
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
i386                 randconfig-a011-20210814
i386                 randconfig-a015-20210814
i386                 randconfig-a013-20210814
i386                 randconfig-a014-20210814
i386                 randconfig-a016-20210814
i386                 randconfig-a012-20210814
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
x86_64               randconfig-c001-20210814
x86_64               randconfig-c001-20210813
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
x86_64               randconfig-a013-20210814
x86_64               randconfig-a011-20210814
x86_64               randconfig-a016-20210814
x86_64               randconfig-a012-20210814
x86_64               randconfig-a014-20210814
x86_64               randconfig-a015-20210814
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug 18 19:10:47 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Aug 2021 10:10:47 +0800
Subject: [soc:tegra/firmware] BUILD SUCCESS
 dd00d75007d27677158bf6e64000d2e266035294
Message-ID: <611dbda7.1oleYLJtIY0r3DI2%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tegra/firmware
branch HEAD: dd00d75007d27677158bf6e64000d2e266035294  firmware: tegra: Stop using seq_get_buf()

elapsed time: 9370m

configs tested: 259
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210813
i386                 randconfig-c001-20210818
powerpc                     mpc5200_defconfig
parisc                              defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
m68k                             alldefconfig
sh                          rsk7264_defconfig
sh                            titan_defconfig
powerpc                     asp8347_defconfig
arc                          axs103_defconfig
powerpc                        icon_defconfig
powerpc                     pq2fads_defconfig
powerpc                      walnut_defconfig
powerpc                       holly_defconfig
arm                             ezx_defconfig
powerpc                     mpc512x_defconfig
xtensa                  nommu_kc705_defconfig
powerpc                      tqm8xx_defconfig
arm                         lpc18xx_defconfig
sh                        edosk7760_defconfig
x86_64                            allnoconfig
sh                             shx3_defconfig
powerpc                      ep88xc_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                     loongson1c_defconfig
arm                        mvebu_v5_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
i386                             alldefconfig
mips                      fuloong2e_defconfig
mips                           mtx1_defconfig
arm                           u8500_defconfig
nios2                         3c120_defconfig
ia64                        generic_defconfig
powerpc                     tqm8555_defconfig
powerpc                      acadia_defconfig
arm                          simpad_defconfig
mips                  cavium_octeon_defconfig
nds32                               defconfig
parisc                           alldefconfig
arm                      tct_hammer_defconfig
powerpc                      obs600_defconfig
arm                     eseries_pxa_defconfig
arm                         vf610m4_defconfig
powerpc                      ppc40x_defconfig
powerpc                      ppc44x_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
riscv                    nommu_k210_defconfig
m68k                       m5208evb_defconfig
x86_64                           alldefconfig
mips                            gpr_defconfig
mips                      maltaaprp_defconfig
alpha                            alldefconfig
sh                     sh7710voipgw_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
mips                           ip28_defconfig
sh                          urquell_defconfig
csky                             alldefconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
mips                          rm200_defconfig
powerpc                       ppc64_defconfig
xtensa                  audio_kc705_defconfig
mips                      loongson3_defconfig
mips                          ath79_defconfig
sh                          r7780mp_defconfig
powerpc                     rainier_defconfig
arm                       cns3420vb_defconfig
mips                          ath25_defconfig
m68k                             allyesconfig
mips                     decstation_defconfig
powerpc                        cell_defconfig
powerpc                     ppa8548_defconfig
arc                        nsimosci_defconfig
arm                  colibri_pxa300_defconfig
sh                   sh7724_generic_defconfig
sparc                            alldefconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
riscv                             allnoconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
microblaze                      mmu_defconfig
arm                         nhk8815_defconfig
mips                     loongson2k_defconfig
parisc                generic-64bit_defconfig
powerpc                     sequoia_defconfig
arc                     nsimosci_hs_defconfig
arm                       imx_v4_v5_defconfig
mips                           ip27_defconfig
mips                      pic32mzda_defconfig
sh                        apsh4ad0a_defconfig
xtensa                          iss_defconfig
sh                           se7780_defconfig
sh                         ap325rxa_defconfig
arm                          gemini_defconfig
sh                               alldefconfig
sh                         apsh4a3a_defconfig
powerpc                      cm5200_defconfig
powerpc                           allnoconfig
arm                            pleb_defconfig
powerpc                        fsp2_defconfig
arm                       multi_v4t_defconfig
arm                          pcm027_defconfig
powerpc                 mpc85xx_cds_defconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
i386                 randconfig-c001-20210818
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
i386                 randconfig-a004-20210817
i386                 randconfig-a003-20210817
i386                 randconfig-a001-20210817
i386                 randconfig-a002-20210817
i386                 randconfig-a006-20210817
i386                 randconfig-a005-20210817
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug 18 19:10:51 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Aug 2021 10:10:51 +0800
Subject: [soc:arm/soc] BUILD SUCCESS 0fbd7409446a8ee76ee701ec846ede917c6c89fa
Message-ID: <611dbdab.YYaVr3WBZeN1wK7G%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/soc
branch HEAD: 0fbd7409446a8ee76ee701ec846ede917c6c89fa  Merge tag 'ixp4xx-del-boardfiles-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik into arm/soc

elapsed time: 724m

configs tested: 131
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210818
powerpc                     pq2fads_defconfig
powerpc                      walnut_defconfig
powerpc                       holly_defconfig
arm                             ezx_defconfig
powerpc                     mpc512x_defconfig
xtensa                  nommu_kc705_defconfig
powerpc                      ep88xc_defconfig
arm                         at91_dt_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                     loongson1c_defconfig
arm                        mvebu_v5_defconfig
alpha                            alldefconfig
sh                     sh7710voipgw_defconfig
mips                           ip28_defconfig
sh                          urquell_defconfig
arm                      tct_hammer_defconfig
csky                             alldefconfig
arm                  colibri_pxa300_defconfig
sh                   sh7724_generic_defconfig
sparc                            alldefconfig
mips                     loongson2k_defconfig
parisc                generic-64bit_defconfig
powerpc                     sequoia_defconfig
arc                     nsimosci_hs_defconfig
arm                       imx_v4_v5_defconfig
mips                           ip27_defconfig
mips                      pic32mzda_defconfig
sh                        apsh4ad0a_defconfig
xtensa                          iss_defconfig
sh                           se7780_defconfig
mips                  maltasmvp_eva_defconfig
arm                          pcm027_defconfig
mips                      loongson3_defconfig
ia64                             alldefconfig
powerpc                 mpc85xx_cds_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
i386                 randconfig-a004-20210817
i386                 randconfig-a003-20210817
i386                 randconfig-a001-20210817
i386                 randconfig-a002-20210817
i386                 randconfig-a006-20210817
i386                 randconfig-a005-20210817
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug 18 19:10:56 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Aug 2021 10:10:56 +0800
Subject: [soc:tegra/drivers] BUILD SUCCESS
 59c6fceb2ecc382c3d20508a235b539bf23af1f0
Message-ID: <611dbdb0.Y6c+g6eWSqJWCJ35%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tegra/drivers
branch HEAD: 59c6fceb2ecc382c3d20508a235b539bf23af1f0  soc/tegra: fuse: Enable fuse clock on suspend for Tegra124

elapsed time: 9370m

configs tested: 271
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210812
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210813
i386                 randconfig-c001-20210818
powerpc                     mpc5200_defconfig
parisc                              defconfig
powerpc                         wii_defconfig
arm                      integrator_defconfig
arm                        trizeps4_defconfig
powerpc                 mpc8540_ads_defconfig
ia64                                defconfig
arm                       imx_v6_v7_defconfig
mips                           rs90_defconfig
parisc                generic-32bit_defconfig
arm                     am200epdkit_defconfig
powerpc                     redwood_defconfig
arm                         at91_dt_defconfig
sh                   secureedge5410_defconfig
powerpc                     pseries_defconfig
powerpc                      makalu_defconfig
arm                      jornada720_defconfig
m68k                             alldefconfig
sh                          rsk7264_defconfig
sh                            titan_defconfig
powerpc                     asp8347_defconfig
arc                          axs103_defconfig
powerpc                        icon_defconfig
powerpc                     pq2fads_defconfig
powerpc                      walnut_defconfig
powerpc                       holly_defconfig
arm                             ezx_defconfig
powerpc                     mpc512x_defconfig
xtensa                  nommu_kc705_defconfig
powerpc                      tqm8xx_defconfig
arm                         lpc18xx_defconfig
sh                        edosk7760_defconfig
x86_64                            allnoconfig
sh                             shx3_defconfig
powerpc                      ep88xc_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                     loongson1c_defconfig
arm                        mvebu_v5_defconfig
arm                     davinci_all_defconfig
mips                        workpad_defconfig
arm                       omap2plus_defconfig
mips                  maltasmvp_eva_defconfig
h8300                            alldefconfig
i386                             alldefconfig
mips                      fuloong2e_defconfig
mips                           mtx1_defconfig
arm                           u8500_defconfig
nios2                         3c120_defconfig
ia64                        generic_defconfig
powerpc                     tqm8555_defconfig
powerpc                      acadia_defconfig
arm                          simpad_defconfig
mips                  cavium_octeon_defconfig
nds32                               defconfig
parisc                           alldefconfig
arm                      tct_hammer_defconfig
powerpc                      obs600_defconfig
arm                     eseries_pxa_defconfig
arm                         vf610m4_defconfig
powerpc                      ppc40x_defconfig
powerpc                      ppc44x_defconfig
powerpc               mpc834x_itxgp_defconfig
mips                        maltaup_defconfig
mips                           ip22_defconfig
sh                           se7721_defconfig
mips                           ip27_defconfig
arm                         bcm2835_defconfig
m68k                        m5307c3_defconfig
arm                         mv78xx0_defconfig
sh                     magicpanelr2_defconfig
riscv                    nommu_k210_defconfig
m68k                       m5208evb_defconfig
x86_64                           alldefconfig
mips                            gpr_defconfig
mips                      maltaaprp_defconfig
alpha                            alldefconfig
sh                     sh7710voipgw_defconfig
arm                        clps711x_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
ia64                             alldefconfig
sh                        edosk7705_defconfig
mips                           ip28_defconfig
sh                          urquell_defconfig
csky                             alldefconfig
xtensa                generic_kc705_defconfig
arm                           stm32_defconfig
arm                           omap1_defconfig
arc                           tb10x_defconfig
arm                          exynos_defconfig
mips                          rm200_defconfig
powerpc                       ppc64_defconfig
xtensa                  audio_kc705_defconfig
mips                      loongson3_defconfig
mips                          ath79_defconfig
sh                          r7780mp_defconfig
powerpc                     rainier_defconfig
arm                       cns3420vb_defconfig
mips                          ath25_defconfig
m68k                             allyesconfig
mips                        jmr3927_defconfig
mips                   sb1250_swarm_defconfig
mips                     decstation_defconfig
powerpc                        cell_defconfig
powerpc                     ppa8548_defconfig
arc                        nsimosci_defconfig
arm                  colibri_pxa300_defconfig
sh                   sh7724_generic_defconfig
sparc                            alldefconfig
mips                           gcw0_defconfig
arm                            xcep_defconfig
riscv                             allnoconfig
powerpc64                        alldefconfig
powerpc                     ksi8560_defconfig
powerpc                      pcm030_defconfig
arm                         s5pv210_defconfig
microblaze                      mmu_defconfig
arm                         nhk8815_defconfig
mips                     loongson2k_defconfig
parisc                generic-64bit_defconfig
powerpc                     sequoia_defconfig
arc                     nsimosci_hs_defconfig
arm                       imx_v4_v5_defconfig
mips                      pic32mzda_defconfig
sh                        apsh4ad0a_defconfig
xtensa                          iss_defconfig
sh                           se7780_defconfig
sh                         ap325rxa_defconfig
arm                          gemini_defconfig
sh                               alldefconfig
sh                         apsh4a3a_defconfig
powerpc                      cm5200_defconfig
powerpc                           allnoconfig
arm                            pleb_defconfig
powerpc                        fsp2_defconfig
arm                       multi_v4t_defconfig
arm                          pcm027_defconfig
powerpc                 mpc85xx_cds_defconfig
ia64                             allmodconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a006-20210812
x86_64               randconfig-a004-20210812
x86_64               randconfig-a003-20210812
x86_64               randconfig-a005-20210812
x86_64               randconfig-a002-20210812
x86_64               randconfig-a001-20210812
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
i386                 randconfig-a004-20210812
i386                 randconfig-a003-20210812
i386                 randconfig-a002-20210812
i386                 randconfig-a001-20210812
i386                 randconfig-a006-20210812
i386                 randconfig-a005-20210812
i386                 randconfig-a011-20210812
i386                 randconfig-a015-20210812
i386                 randconfig-a013-20210812
i386                 randconfig-a014-20210812
i386                 randconfig-a016-20210812
i386                 randconfig-a012-20210812
i386                 randconfig-a011-20210813
i386                 randconfig-a015-20210813
i386                 randconfig-a014-20210813
i386                 randconfig-a013-20210813
i386                 randconfig-a016-20210813
i386                 randconfig-a012-20210813
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-c001-20210812
i386                 randconfig-c001-20210818
x86_64               randconfig-a006-20210813
x86_64               randconfig-a004-20210813
x86_64               randconfig-a003-20210813
x86_64               randconfig-a002-20210813
x86_64               randconfig-a005-20210813
x86_64               randconfig-a001-20210813
i386                 randconfig-a004-20210817
i386                 randconfig-a003-20210817
i386                 randconfig-a001-20210817
i386                 randconfig-a002-20210817
i386                 randconfig-a006-20210817
i386                 randconfig-a005-20210817
x86_64               randconfig-a011-20210812
x86_64               randconfig-a013-20210812
x86_64               randconfig-a012-20210812
x86_64               randconfig-a016-20210812
x86_64               randconfig-a015-20210812
x86_64               randconfig-a014-20210812
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug 18 19:10:43 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Aug 2021 10:10:43 +0800
Subject: [soc:qcom/arm64] BUILD SUCCESS
 198b8c8ede36d2135df73fee19506276059a0f8e
Message-ID: <611dbda3.vRlRiLeBbLq2BKxM%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git qcom/arm64
branch HEAD: 198b8c8ede36d2135df73fee19506276059a0f8e  Merge tag 'v5.14-rc3' into arm64-for-5.15

elapsed time: 723m

configs tested: 131
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210818
powerpc                     pq2fads_defconfig
powerpc                      walnut_defconfig
powerpc                       holly_defconfig
arm                             ezx_defconfig
powerpc                     mpc512x_defconfig
xtensa                  nommu_kc705_defconfig
powerpc                      ep88xc_defconfig
arm                         at91_dt_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                     loongson1c_defconfig
arm                        mvebu_v5_defconfig
alpha                            alldefconfig
sh                     sh7710voipgw_defconfig
mips                           ip28_defconfig
sh                          urquell_defconfig
arm                      tct_hammer_defconfig
csky                             alldefconfig
arm                  colibri_pxa300_defconfig
sh                   sh7724_generic_defconfig
sparc                            alldefconfig
mips                     loongson2k_defconfig
parisc                generic-64bit_defconfig
powerpc                     sequoia_defconfig
arc                     nsimosci_hs_defconfig
arm                       imx_v4_v5_defconfig
mips                           ip27_defconfig
mips                      pic32mzda_defconfig
sh                        apsh4ad0a_defconfig
xtensa                          iss_defconfig
sh                           se7780_defconfig
mips                  maltasmvp_eva_defconfig
arm                          pcm027_defconfig
mips                      loongson3_defconfig
ia64                             alldefconfig
powerpc                 mpc85xx_cds_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
i386                 randconfig-a004-20210817
i386                 randconfig-a003-20210817
i386                 randconfig-a001-20210817
i386                 randconfig-a002-20210817
i386                 randconfig-a006-20210817
i386                 randconfig-a005-20210817
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug 18 19:10:41 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Aug 2021 10:10:41 +0800
Subject: [soc:mvebu/dt] BUILD SUCCESS 514ef1e62d6521c2199d192b1c71b79d2aa21d5a
Message-ID: <611dbda1.LK1UbRlOK12s3DXg%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git mvebu/dt
branch HEAD: 514ef1e62d6521c2199d192b1c71b79d2aa21d5a  arm64: dts: marvell: armada-37xx: Extend PCIe MEM space

elapsed time: 1970m

configs tested: 159
configs skipped: 141

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210818
powerpc                     pq2fads_defconfig
powerpc                      walnut_defconfig
powerpc                       holly_defconfig
arm                             ezx_defconfig
powerpc                     mpc512x_defconfig
xtensa                  nommu_kc705_defconfig
arm                         at91_dt_defconfig
mips                     loongson1c_defconfig
mips                          rb532_defconfig
mips                       bmips_be_defconfig
arm                            dove_defconfig
sh                     magicpanelr2_defconfig
powerpc                      ep88xc_defconfig
powerpc                 mpc832x_rdb_defconfig
arm                        mvebu_v5_defconfig
i386                             alldefconfig
powerpc               mpc834x_itxgp_defconfig
arm                        magician_defconfig
arm                        multi_v5_defconfig
openrisc                    or1ksim_defconfig
powerpc                      mgcoge_defconfig
arc                         haps_hs_defconfig
arm                       aspeed_g5_defconfig
powerpc                mpc7448_hpc2_defconfig
ia64                             alldefconfig
powerpc                     redwood_defconfig
powerpc                     asp8347_defconfig
parisc                generic-32bit_defconfig
powerpc                 mpc837x_mds_defconfig
arm                            mps2_defconfig
alpha                            alldefconfig
sh                     sh7710voipgw_defconfig
mips                           ip28_defconfig
sh                          urquell_defconfig
arm                      tct_hammer_defconfig
csky                             alldefconfig
powerpc                   microwatt_defconfig
arm                  colibri_pxa270_defconfig
um                               alldefconfig
sh                           se7721_defconfig
sh                          rsk7201_defconfig
sh                           se7724_defconfig
powerpc                        cell_defconfig
openrisc                 simple_smp_defconfig
mips                        vocore2_defconfig
powerpc                        icon_defconfig
mips                     loongson2k_defconfig
parisc                generic-64bit_defconfig
powerpc                     sequoia_defconfig
arc                     nsimosci_hs_defconfig
arm                         cm_x300_defconfig
mips                  maltasmvp_eva_defconfig
powerpc                      cm5200_defconfig
arm                       spear13xx_defconfig
arm                       imx_v4_v5_defconfig
mips                           ip27_defconfig
mips                      pic32mzda_defconfig
sh                        apsh4ad0a_defconfig
xtensa                          iss_defconfig
sh                           se7780_defconfig
arm                          pcm027_defconfig
mips                      loongson3_defconfig
powerpc                 mpc85xx_cds_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
i386                 randconfig-a004-20210817
i386                 randconfig-a006-20210817
i386                 randconfig-a005-20210817
i386                 randconfig-a003-20210817
i386                 randconfig-a001-20210817
i386                 randconfig-a002-20210817
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Aug 18 19:10:38 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 19 Aug 2021 10:10:38 +0800
Subject: [soc:aspeed/dt] BUILD SUCCESS 6b8b31269898b8891f1f3a95578ceeb109393e23
Message-ID: <611dbd9e.b/RPyWcyf7gpPecF%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git aspeed/dt
branch HEAD: 6b8b31269898b8891f1f3a95578ceeb109393e23  ARM: dts: aspeed: p10bmc: Add power control pins

elapsed time: 2551m

configs tested: 157
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210818
sh                           se7206_defconfig
mips                          rm200_defconfig
xtensa                    smp_lx200_defconfig
arm                      footbridge_defconfig
arm                       multi_v4t_defconfig
arm                        shmobile_defconfig
powerpc                       ebony_defconfig
powerpc                      walnut_defconfig
arm                            mmp2_defconfig
xtensa                  audio_kc705_defconfig
arm                         vf610m4_defconfig
powerpc                      ep88xc_defconfig
arm                         at91_dt_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                     loongson1c_defconfig
arm                        mvebu_v5_defconfig
alpha                            alldefconfig
sh                     sh7710voipgw_defconfig
mips                         rt305x_defconfig
s390                          debug_defconfig
arm                        clps711x_defconfig
arc                     haps_hs_smp_defconfig
parisc                           alldefconfig
powerpc                 linkstation_defconfig
arm                       cns3420vb_defconfig
powerpc                     mpc512x_defconfig
arm                          lpd270_defconfig
sh                          lboxre2_defconfig
arm                       mainstone_defconfig
arc                      axs103_smp_defconfig
mips                      fuloong2e_defconfig
mips                           jazz_defconfig
mips                           xway_defconfig
mips                    maltaup_xpa_defconfig
arm                         s3c6400_defconfig
m68k                        mvme16x_defconfig
arm                      pxa255-idp_defconfig
arm                  colibri_pxa300_defconfig
sh                   sh7724_generic_defconfig
sparc                            alldefconfig
arm                    vt8500_v6_v7_defconfig
mips                           ip28_defconfig
arm64                            alldefconfig
riscv             nommu_k210_sdcard_defconfig
arm                       imx_v4_v5_defconfig
mips                           ip27_defconfig
mips                      pic32mzda_defconfig
sh                        apsh4ad0a_defconfig
xtensa                          iss_defconfig
sh                           se7780_defconfig
sh                           se7750_defconfig
powerpc                   bluestone_defconfig
m68k                       m5208evb_defconfig
arm                         s5pv210_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a004-20210816
i386                 randconfig-a003-20210816
i386                 randconfig-a002-20210816
i386                 randconfig-a001-20210816
i386                 randconfig-a006-20210816
i386                 randconfig-a005-20210816
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210817
i386                 randconfig-c001-20210818
i386                 randconfig-a004-20210817
i386                 randconfig-a003-20210817
i386                 randconfig-a001-20210817
i386                 randconfig-a002-20210817
i386                 randconfig-a006-20210817
i386                 randconfig-a005-20210817
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
x86_64               randconfig-a011-20210816
x86_64               randconfig-a013-20210816
x86_64               randconfig-a016-20210816
x86_64               randconfig-a012-20210816
x86_64               randconfig-a015-20210816
x86_64               randconfig-a014-20210816
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818
i386                 randconfig-a011-20210816
i386                 randconfig-a015-20210816
i386                 randconfig-a013-20210816
i386                 randconfig-a014-20210816
i386                 randconfig-a016-20210816
i386                 randconfig-a012-20210816

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From bfgithub at veryspeedy.net  Wed Aug 18 19:21:44 2021
From: bfgithub at veryspeedy.net (bfgithub at veryspeedy.net)
Date: Thu, 19 Aug 2021 12:21:44 +1000
Subject: [PATCH v1 0/1] ARM hangs on boot with CONFIG_FORTIFY_SOURCE and ATAGs
Message-ID: <20210819022144.22719-1-bfgithub@veryspeedy.net>

From: Berto Furth <bfgithub at veryspeedy.net>

ARM may hang on boot with ATAGS and CONFIG_FORTIFY_SOURCE.


An ARM 32 device may hang on boot after the

Uncompressing Linux... done, booting the kernel.

message if the bootloader passes a command line via ATAG to the
kernel and CONFIG_FORTIFY_SOURCE is enabled.

Workaround : Disable CONFIG_FORTIFY_SOURCE in kernel build options.

Details : I am trying to build v5.14.0-rc5 for an old 32 bit arm NAS
system (Cavium CNS3420 based Seagate Central).

The embedded u-boot bootloader on this system is very old and uses
ATAGs to pass parameters to the kernel.

I am confident that the hang problem is occurring because of the
fortified string functions which check the declared size of string
objects before working with them.

My tests show that when booting using kernel v4.19.195 (which does not
have fortified string functions) or with kernel v5.14.0-rc5 with
CONFIG_FORTIFY_SOURCE disabled, that the system does not hang on boot.

Berto Furth (1):
  Make cmdline ATAG work with fortified string fn

 arch/arm/include/uapi/asm/setup.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


base-commit: d6d09a6942050f21b065a134169002b4d6b701ef
-- 
2.32.0



From bfgithub at veryspeedy.net  Wed Aug 18 19:21:46 2021
From: bfgithub at veryspeedy.net (bfgithub at veryspeedy.net)
Date: Thu, 19 Aug 2021 12:21:46 +1000
Subject: [PATCH v1 1/1] Set cmdline array size to COMMAND_LINE_SIZE
In-Reply-To: <20210819022144.22719-1-bfgithub@veryspeedy.net>
References: <20210819022144.22719-1-bfgithub@veryspeedy.net>
Message-ID: <20210819022144.22719-2-bfgithub@veryspeedy.net>

From: Berto Furth <bfgithub at veryspeedy.net>

Use maximum size in declaration of ATAG cmdline string.

The declaration of the cmdline string in the ATAG type tag_cmdline
uses an array size of 1. This means that the fortified versions of
string functions (like strlcpy) will panic when they see that the
actual contents of the cmdline string are bigger than 1 byte.

Fix is to simply indicate that the string can actually be up to
COMMAND_LINE_SIZE bytes by setting the array size as such.

Signed-off-by: Berto Furth <bfgithub at veryspeedy.net>
Tested-by: Berto Furth <bfgithub at veryspeedy.net>
---
 arch/arm/include/uapi/asm/setup.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/uapi/asm/setup.h b/arch/arm/include/uapi/asm/setup.h
index 25ceda63b284..9c88c919467b 100644
--- a/arch/arm/include/uapi/asm/setup.h
+++ b/arch/arm/include/uapi/asm/setup.h
@@ -124,7 +124,7 @@ struct tag_videolfb {
 #define ATAG_CMDLINE	0x54410009
 
 struct tag_cmdline {
-	char	cmdline[1];	/* this is the minimum size */
+	char	cmdline[COMMAND_LINE_SIZE];
 };
 
 /* acorn RiscPC specific information */
-- 
2.32.0



From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:17 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:17 +0800
Subject: [PATCH v8 03/13] dt-bindings: mediatek: add mediatek,
 dsc.yaml for mt8195 SoC binding
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-4-jason-jh.lin@mediatek.com>

1. Add mediatek,dsc.yaml to describe DSC module in details.
2. Add mt8195 SoC binding to mediatek,dsc.yaml.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,dsc.yaml        | 69 +++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
new file mode 100644
index 000000000000..f94a95c6a1c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display DSC controller
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The DSC standard is a specification of the algorithms used for
+  compressing and decompressing image display streams, including
+  the specification of the syntax and semantics of the compressed
+  video bit stream. DSC is designed for real-time systems with
+  real-time compression, transmission, decompression and Display.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-disp-dsc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: DSC Wrapper Clock
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  mediatek,gce-client-reg:
+      description:
+        The register of display function block to be set by gce. There are 4 arguments,
+        such as gce node, subsys id, offset and register size. The subsys id that is
+        mapping to the register of display function blocks is defined in the gce header
+        include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+      $ref: /schemas/types.yaml#/definitions/phandle-array
+      maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dsc0: disp_dsc_wrap at 1c009000 {
+        compatible = "mediatek,mt8195-disp-dsc";
+        reg = <0 0x1c009000 0 0x1000>;
+        interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+        clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+    };
+
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:15 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:15 +0800
Subject: [PATCH v8 01/13] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC
 binding
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-2-jason-jh.lin@mediatek.com>

1. There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195.
   Each of them is bound to a display pipeline, so add their
   definition in mtk-mmsys documentation with 2 compatibles.

2. Add description for power-domain property.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
this patch is base on [1][2]

[1] dt-bindings: arm: mediatek: mmsys: convert to YAML format
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-1-fparent at baylibre.com/
[2] dt-bindings: arm: mediatek: mmsys: add MT8365 SoC binding
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-2-fparent at baylibre.com/
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml  | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 2d4ff0ce387b..68cb330d7595 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -30,6 +30,8 @@ properties:
               - mediatek,mt8173-mmsys
               - mediatek,mt8183-mmsys
               - mediatek,mt8365-mmsys
+              - mediatek,mt8195-vdosys0
+              - mediatek,mt8195-vdosys1
           - const: syscon
       - items:
           - const: mediatek,mt7623-mmsys
@@ -39,6 +41,12 @@ properties:
   reg:
     maxItems: 1
 
+  power-domains:
+    description:
+      A phandle and PM domain specifier as defined by bindings
+      of the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
   "#clock-cells":
     const: 1
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:22 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:22 +0800
Subject: [PATCH v8 08/13] drm/mediatek: remove unused define in
 mtk_drm_ddp_comp.c
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-9-jason-jh.lin@mediatek.com>

Remove the unsed define in mtk_drm_ddp_comp.c

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 75bc00e17fc4..aaa7450b3e2b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -21,8 +21,6 @@
 #include "mtk_drm_crtc.h"
 
 #define DISP_OD_EN				0x0000
-#define DISP_OD_INTEN				0x0008
-#define DISP_OD_INTSTA				0x000c
 #define DISP_OD_CFG				0x0020
 #define DISP_OD_SIZE				0x0030
 #define DISP_DITHER_5				0x0114
@@ -42,8 +40,6 @@
 #define DITHER_ENGINE_EN			BIT(1)
 #define DISP_DITHER_SIZE			0x0030
 
-#define LUT_10BIT_MASK				0x03ff
-
 #define OD_RELAYMODE				BIT(0)
 
 #define UFO_BYPASS				BIT(2)
@@ -52,18 +48,12 @@
 
 #define DISP_DITHERING				BIT(2)
 #define DITHER_LSB_ERR_SHIFT_R(x)		(((x) & 0x7) << 28)
-#define DITHER_OVFLW_BIT_R(x)			(((x) & 0x7) << 24)
 #define DITHER_ADD_LSHIFT_R(x)			(((x) & 0x7) << 20)
-#define DITHER_ADD_RSHIFT_R(x)			(((x) & 0x7) << 16)
 #define DITHER_NEW_BIT_MODE			BIT(0)
 #define DITHER_LSB_ERR_SHIFT_B(x)		(((x) & 0x7) << 28)
-#define DITHER_OVFLW_BIT_B(x)			(((x) & 0x7) << 24)
 #define DITHER_ADD_LSHIFT_B(x)			(((x) & 0x7) << 20)
-#define DITHER_ADD_RSHIFT_B(x)			(((x) & 0x7) << 16)
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
-#define DITHER_OVFLW_BIT_G(x)			(((x) & 0x7) << 8)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
-#define DITHER_ADD_RSHIFT_G(x)			(((x) & 0x7) << 0)
 
 struct mtk_ddp_comp_dev {
 	struct clk *clk;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:19 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:19 +0800
Subject: [PATCH v8 05/13] arm64: dts: mt8195: add display node for vdosys0
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-6-jason-jh.lin@mediatek.com>

Add display node for vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is based on [1][2][3]

[1]arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
[2]arm64: dts: mt8195: add IOMMU and smi nodes
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
[3]arm64: dts: mt8195: add gce node
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210705053429.4380-4-jason-jh.lin at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 111 +++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 47c44cb77da0..b4558a223b37 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1153,9 +1153,120 @@
 			#clock-cells = <1>;
 		};
 
+		ovl0: disp_ovl at 1c000000 {
+			compatible = "mediatek,mt8195-disp-ovl",
+				     "mediatek,mt8183-disp-ovl";
+			reg = <0 0x1c000000 0 0x1000>;
+			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_OVL0_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x0000 0x1000>;
+		};
+
+		rdma0: disp_rdma at 1c002000 {
+			compatible = "mediatek,mt8195-disp-rdma";
+			reg = <0 0x1c002000 0 0x1000>;
+			interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_RDMA0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x2000 0x1000>;
+		};
+
+		color0: disp_color at 1c003000 {
+			compatible = "mediatek,mt8195-disp-color",
+				     "mediatek,mt8173-disp-color";
+			reg = <0 0x1c003000 0 0x1000>;
+			interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_COLOR0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x3000 0x1000>;
+		};
+
+		ccorr0: disp_ccorr at 1c004000 {
+			compatible = "mediatek,mt8195-disp-ccorr",
+				     "mediatek,mt8183-disp-ccorr";
+			reg = <0 0x1c004000 0 0x1000>;
+			interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_CCORR0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x4000 0x1000>;
+		};
+
+		aal0: disp_aal at 1c005000 {
+			compatible = "mediatek,mt8195-disp-aal",
+				     "mediatek,mt8173-disp-aal";
+			reg = <0 0x1c005000 0 0x1000>;
+			interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_AAL0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x5000 0x1000>;
+		};
+
+		gamma0: disp_gamma at 1c006000 {
+			compatible = "mediatek,mt8195-disp-gamma",
+				     "mediatek,mt8173-disp-gamma";
+			reg = <0 0x1c006000 0 0x1000>;
+			interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_GAMMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x6000 0x1000>;
+		};
+
+		dither0: disp_dither at 1c007000 {
+			compatible = "mediatek,mt8195-disp-dither",
+				     "mediatek,mt8183-disp-dither";
+			reg = <0 0x1c007000 0 0x1000>;
+			interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_DITHER0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x7000 0x1000>;
+		};
+
+		dsc0: disp_dsc_wrap at 1c009000 {
+			compatible = "mediatek,mt8195-disp-dsc";
+			reg = <0 0x1c009000 0 0x1000>;
+			interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+		};
+
+		merge0: disp_vpp_merge0 at 1c014000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c014000 0 0x1000>;
+			interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_VPP_MERGE0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c01XXXX 0x4000 0x1000>;
+		};
+
+		mutex: disp_mutex0 at 1c016000 {
+			compatible = "mediatek,mt8195-disp-mutex";
+			reg = <0 0x1c016000 0 0x1000>;
+			reg-names = "vdo0_mutex";
+			interrupts = <GIC_SPI 658 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_MUTEX0>;
+			clock-names = "vdo0_mutex";
+			mediatek,gce-events =
+				 <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;
+		};
+
 		vdosys0: syscon at 1c01a000 {
 			compatible = "mediatek,mt8195-vdosys0", "syscon";
 			reg = <0 0x1c01a000 0 0x1000>;
+			mboxes = <&gce1 0 CMDQ_THR_PRIO_4>;
 			#clock-cells = <1>;
 		};
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:18 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:18 +0800
Subject: [PATCH v8 04/13] dt-bindings: mediatek: display: add mt8195 SoC
 binding
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-5-jason-jh.lin@mediatek.com>

1. Add mt8195 SoC binding to AAL, CCORR, COLOR, DITHER, GAMMA, MERGE,
   MUTEX, OVL and RDMA yaml schema.

2. Add MERGE additional property description for mt8195
- async clock
- fifo setting enable
- reset controller

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,aal.yaml        |  1 +
 .../display/mediatek/mediatek,ccorr.yaml      |  5 +++
 .../display/mediatek/mediatek,color.yaml      |  1 +
 .../display/mediatek/mediatek,dither.yaml     |  5 +++
 .../display/mediatek/mediatek,gamma.yaml      |  5 +++
 .../display/mediatek/mediatek,merge.yaml      | 40 +++++++++++++++++++
 .../display/mediatek/mediatek,mutex.yaml      |  2 +
 .../display/mediatek/mediatek,ovl.yaml        |  5 +++
 .../display/mediatek/mediatek,rdma.yaml       |  2 +
 9 files changed, 66 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
index 7be772d77e36..e1820238db43 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -25,6 +25,7 @@ properties:
           - enum:
               - mediatek,mt2712-disp-aal
               - mediatek,mt8183-disp-aal
+              - mediatek,mt8195-disp-aal
           - enum:
               - mediatek,mt8173-disp-aal
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
index 5a1c27d6b3e2..4c556a2bc64a 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -21,6 +21,11 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8183-disp-ccorr
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ccorr
+          - enum:
+              - mediatek,mt8183-disp-ccorr
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
index 9a3edf6f0b8e..a13096196a0c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -35,6 +35,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8183-disp-color
+              - mediatek,mt8195-disp-color
           - enum:
               - mediatek,mt8173-disp-color
   reg:
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
index 20419f876410..e89fe7393291 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -22,6 +22,11 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8183-disp-dither
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-dither
+          - enum:
+              - mediatek,mt8183-disp-dither
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
index e2a1fc218e4f..dc78d6d05dee 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -23,6 +23,11 @@ properties:
           - const: mediatek,mt8173-disp-gamma
       - items:
           - const: mediatek,mt8183-disp-gamma
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-gamma
+          - enum:
+              - mediatek,mt8183-disp-gamma
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 4cdce11d7fcd..1a27b037086b 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -21,6 +21,8 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8173-disp-merge
+      - items:
+          - const: mediatek,mt8195-disp-merge
 
   reg:
     maxItems: 1
@@ -36,6 +38,31 @@ properties:
   clocks:
     items:
       - description: MERGE Clock
+      - description: MERGE Async Clock
+          Controlling the synchronous process between MERGE and other display function
+          blocks cross clock domain.
+
+  mediatek,merge-fifo-en:
+      description:
+	    The setting of merge fifo is mainly provided for the display latency buffer.
+        to ensure that the back-end panel display data will not be underrun,
+        a little more data is needed in the fifo. According to the merge fifo settings,
+        when the water level is detected to be insufficient, it will trigger RDMA sending
+        ultra and preulra command to SMI to speed up the data rate.
+      type: boolean
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+  resets:
+    description: reset controller
+      See Documentation/devicetree/bindings/reset/reset.txt for details.
 
 required:
   - compatible
@@ -55,3 +82,16 @@ examples:
         clocks = <&mmsys CLK_MM_DISP_MERGE>;
     };
 
+    merge5: disp_vpp_merge5 at 1c110000 {
+        compatible = "mediatek,mt8195-disp-merge";
+        reg = <0 0x1c110000 0 0x1000>;
+        interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+                 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+        clock-names = "merge","merge_async";
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+        mediatek,merge-fifo-en = <1>;
+        resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
index aaba6bbfb4da..0dced7a53329 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -30,6 +30,8 @@ properties:
           - const: mediatek,mt8173-disp-mutex
       - items:
           - const: mediatek,mt8183-disp-mutex
+      - items:
+          - const: mediatek,mt8195-disp-mutex
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 833b0ca09b21..1973eee4244f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -31,6 +31,11 @@ properties:
               - mediatek,mt2712-disp-ovl
           - enum:
               - mediatek,mt2701-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ovl
+          - enum:
+              - mediatek,mt8183-disp-ovl
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
index ce3bcca30609..847bc55252ca 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -27,6 +27,8 @@ properties:
           - const: mediatek,mt8173-disp-rdma
       - items:
           - const: mediatek,mt8183-disp-rdma
+      - items:
+          - const: mediatek,mt8195-disp-rdma
       - items:
           - enum:
               - mediatek,mt7623-disp-rdma
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:21 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:21 +0800
Subject: [PATCH v8 07/13] soc: mediatek: add mtk-mutex support for mt8195
 vdosys0
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-8-jason-jh.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 98 +++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2e4bcc300576..c177156ee2fa 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -17,6 +17,9 @@
 #define MT8183_MUTEX0_MOD0			0x30
 #define MT8183_MUTEX0_SOF0			0x2c
 
+#define MT8195_DISP_MUTEX0_MOD0			0x30
+#define MT8195_DISP_MUTEX0_SOF			0x2c
+
 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
@@ -67,6 +70,36 @@
 #define MT8173_MUTEX_MOD_DISP_PWM1		24
 #define MT8173_MUTEX_MOD_DISP_OD		25
 
+#define MT8195_MUTEX_MOD_DISP_OVL0		0
+#define MT8195_MUTEX_MOD_DISP_WDMA0		1
+#define MT8195_MUTEX_MOD_DISP_RDMA0		2
+#define MT8195_MUTEX_MOD_DISP_COLOR0		3
+#define MT8195_MUTEX_MOD_DISP_CCORR0		4
+#define MT8195_MUTEX_MOD_DISP_AAL0		5
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
+#define MT8195_MUTEX_MOD_DISP_DITHER0		7
+#define MT8195_MUTEX_MOD_DISP_DSI0		8
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
+#define MT8195_MUTEX_MOD_DISP_OVL1		10
+#define MT8195_MUTEX_MOD_DISP_WDMA1		11
+#define MT8195_MUTEX_MOD_DISP_RDMA1		12
+#define MT8195_MUTEX_MOD_DISP_COLOR1		13
+#define MT8195_MUTEX_MOD_DISP_CCORR1		14
+#define MT8195_MUTEX_MOD_DISP_AAL1		15
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
+#define MT8195_MUTEX_MOD_DISP_DITHER1		17
+#define MT8195_MUTEX_MOD_DISP_DSI1		18
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
+#define MT8195_MUTEX_MOD_DISP_PWM0		27
+#define MT8195_MUTEX_MOD_DISP_PWM1		28
+
 #define MT2712_MUTEX_MOD_DISP_PWM2		10
 #define MT2712_MUTEX_MOD_DISP_OVL0		11
 #define MT2712_MUTEX_MOD_DISP_OVL1		12
@@ -101,12 +134,27 @@
 #define MT2712_MUTEX_SOF_DSI3			6
 #define MT8167_MUTEX_SOF_DPI0			2
 #define MT8167_MUTEX_SOF_DPI1			3
+
 #define MT8183_MUTEX_SOF_DSI0			1
 #define MT8183_MUTEX_SOF_DPI0			2
 
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
 
+#define MT8195_MUTEX_SOF_DSI0			1
+#define MT8195_MUTEX_SOF_DSI1			2
+#define MT8195_MUTEX_SOF_DP_INTF0		3
+#define MT8195_MUTEX_SOF_DP_INTF1		4
+#define MT8195_MUTEX_SOF_DPI0			6 /* for HDMI_TX */
+#define MT8195_MUTEX_SOF_DPI1			5 /* for digital video out */
+
+#define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_SOF_DSI0 << 7)
+#define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_SOF_DSI1 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_INTF0 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_INTF1 << 7)
+#define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_SOF_DPI0 << 7)
+#define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_SOF_DPI1 << 7)
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -120,6 +168,9 @@ enum mtk_mutex_sof_id {
 	MUTEX_SOF_DPI1,
 	MUTEX_SOF_DSI2,
 	MUTEX_SOF_DSI3,
+	MUTEX_SOF_DP_INTF0,
+	MUTEX_SOF_DP_INTF1,
+	DDP_MUTEX_SOF_MAX,
 };
 
 struct mtk_mutex_data {
@@ -214,7 +265,23 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
+	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
+	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
+	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
+	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
+	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
+	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
+	[DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
+	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
+	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
+	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
+	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
+	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
+};
+
+static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
@@ -224,7 +291,7 @@ static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
 };
 
-static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
@@ -232,12 +299,24 @@ static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 };
 
 /* Add EOF setting so overlay hardware can receive frame done irq */
-static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
 };
 
+static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
+	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
+	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
+	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
+	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
+	[MUTEX_SOF_DP_INTF0] =
+		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
+	[MUTEX_SOF_DP_INTF1] =
+		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -275,6 +354,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.no_clk = true,
 };
 
+static const struct mtk_mutex_data mt8195_mutex_driver_data = {
+	.mutex_mod = mt8195_mutex_mod,
+	.mutex_sof = mt8195_mutex_sof,
+	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
+};
+
 struct mtk_mutex *mtk_mutex_get(struct device *dev)
 {
 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
@@ -347,6 +433,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DPI1:
 		sof_id = MUTEX_SOF_DPI1;
 		break;
+	case DDP_COMPONENT_DP_INTF0:
+		sof_id = MUTEX_SOF_DP_INTF0;
+		break;
 	default:
 		if (mtx->data->mutex_mod[id] < 32) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
@@ -386,6 +475,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DSI3:
 	case DDP_COMPONENT_DPI0:
 	case DDP_COMPONENT_DPI1:
+	case DDP_COMPONENT_DP_INTF0:
 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
 			       mtx->regs +
 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
@@ -507,6 +597,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
 	  .data = &mt8173_mutex_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = &mt8183_mutex_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = &mt8195_mutex_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:14 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:14 +0800
Subject: [PATCH v8 00/13] Add Mediatek Soc DRM (vdosys0) support for mt8195
Message-ID: <20210819022327.13040-1-jason-jh.lin@mediatek.com>

Change in v8:
- add DP_INTF0 mux into mmsys routing table
- add DP_INTF0 mutex mod and enum into add/remove comp funtion
- remove bypass DSC enum in mtk_ddp_comp_init

Change in v7:
- add dt=binding of mmsys and disp path into this series
- separate th modidfication of alphabetic order, remove unused define and
  rename the define of register offset to individual patch
- add comment for MERGE ultra and preultra setting

Change in v6:
- adjust alphabetic order for mediatek-drm
- move the patch that add mt8195 support for mediatek-drm as the lastest patch
- add MERGE define for const varriable 

Change in v5:
- add power-domain property into vdosys0 and vdosys1 dts node.
- add MT8195 prifix and remove unused VDO1 define in mt8195-mmsys.h

Change in v4:
- extract dt-binding patches to another patch series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597
- squash DSC module into mtk_drm_ddp_comp.c
- add coment and simplify MERGE config function

Change in v3:
- change mmsys and display dt-bindings document from txt to yaml
- add MERGE additional description in display dt-bindings document
- fix mboxes-cells number of vdosys0 node in dts
- drop mutex eof convert define
- remove pm_runtime apis in DSC and MERGE
- change DSC and MERGE enum to alphabetic order

Change in v2:
- add DSC yaml file
- add mt8195 drm driver porting parts in to one patch
- remove useless define, variable, structure member and function
- simplify DSC and MERGE file and switch threre order

jason-jh.lin (13):
  dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
  dt-bindings: mediatek: display: split each block to individual yaml
  dt-bindings: mediatek: add mediatek,dsc.yaml for mt8195 SoC binding
  dt-bindings: mediatek: display: add mt8195 SoC binding
  arm64: dts: mt8195: add display node for vdosys0
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
  soc: mediatek: add mtk-mutex support for mt8195 vdosys0
  drm/mediatek: remove unused define in mtk_drm_ddp_comp.c
  drm/mediatek: rename the define of register offset
  drm/mediatek: adjust to the alphabetic order for mediatek-drm
  drm/mediatek: add DSC support for mediatek-drm
  drm/mediatek: add MERGE support for mediatek-drm
  drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |   8 +
 .../display/mediatek/mediatek,aal.yaml        |  76 +++++
 .../display/mediatek/mediatek,ccorr.yaml      |  74 +++++
 .../display/mediatek/mediatek,color.yaml      |  85 ++++++
 .../display/mediatek/mediatek,disp.txt        | 219 --------------
 .../display/mediatek/mediatek,dither.yaml     |  75 +++++
 .../display/mediatek/mediatek,dsc.yaml        |  69 +++++
 .../display/mediatek/mediatek,gamma.yaml      |  76 +++++
 .../display/mediatek/mediatek,merge.yaml      |  97 +++++++
 .../display/mediatek/mediatek,mutex.yaml      |  79 ++++++
 .../display/mediatek/mediatek,od.yaml         |  52 ++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  86 ++++++
 .../display/mediatek/mediatek,ovl.yaml        | 101 +++++++
 .../display/mediatek/mediatek,rdma.yaml       | 112 ++++++++
 .../display/mediatek/mediatek,split.yaml      |  56 ++++
 .../display/mediatek/mediatek,ufoe.yaml       |  59 ++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 ++++++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 111 ++++++++
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 268 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |   6 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   | 238 ++++++++++------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  24 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        | 106 ++++---
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   1 +
 drivers/soc/mediatek/mt8195-mmsys.h           | 114 ++++++++
 drivers/soc/mediatek/mtk-mmsys.c              |  11 +
 drivers/soc/mediatek/mtk-mutex.c              |  98 ++++++-
 include/linux/soc/mediatek/mtk-mmsys.h        |   9 +
 30 files changed, 2041 insertions(+), 364 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:20 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:20 +0800
Subject: [PATCH v8 06/13] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys0
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-7-jason-jh.lin@mediatek.com>

Add mt8195 vdosys0 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is base on [1][2]
[1] soc: mediatek: mmsys: add MT8365 support
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-3-fparent at baylibre.com/
[2] soc: mmsys: mediatek: add mask to mmsys routes
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210729070549.5514-1-linux at fw-web.de/

The vdosys1 impelmentation patch [3] will base on this patch
[3] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210722094551.15255-8-nancy.lin at mediatek.com/
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 114 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       |  11 +++
 include/linux/soc/mediatek/mtk-mmsys.h |   9 ++
 3 files changed, 134 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
new file mode 100644
index 000000000000..0c97a5f016c1
--- /dev/null
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
+#define __SOC_MEDIATEK_MT8195_MMSYS_H
+
+#define MT8195_VDO0_OVL_MOUT_EN					0xf14
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
+
+#define MT8195_VDO0_SEL_IN					0xf34
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		(0 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		(1 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		(2 << 0)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		(0 << 4)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		(1 << 4)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		(0 << 5)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		(1 << 5)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		(0 << 8)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		(1 << 8)
+#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		(0 << 9)
+#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		(0 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			(1 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		(2 << 12)
+#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			(0 << 16)
+#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			(1 << 16)
+#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			(0 << 17)
+#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			(1 << 17)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			(0 << 20)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			(1 << 20)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		(0 << 21)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		(1 << 21)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			(0 << 22)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_VPP_MERGE			(1 << 22)
+
+#define MT8195_VDO0_SEL_OUT					0xf38
+#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		(0 << 0)
+#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			(1 << 0)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		(0 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			(1 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		(2 << 1)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			(0 << 4)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			(1 << 4)
+#define MT8195_SOUT_VPP_MERGE_TO_DSI1				(0 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			(1 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			(2 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(3 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			(4 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			(0 << 11)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA0			(1 << 11)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			(0 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		(1 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			(2 << 12)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			(0 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			(1 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(3 << 16)
+
+static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
+		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
+		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT,
+		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE,
+		MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0,
+		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT,
+		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0,
+		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN,
+		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0,
+		MT8195_SOUT_DISP_DITHER0_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
+	}, {
+		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
+		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+	}
+};
+
+#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index a78e88f27b62..ce6cc2f49e7d 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -14,6 +14,7 @@
 #include "mt8167-mmsys.h"
 #include "mt8183-mmsys.h"
 #include "mt8365-mmsys.h"
+#include "mt8195-mmsys.h"
 
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.clk_driver = "clk-mt2701-mm",
@@ -59,6 +60,12 @@ static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
 	.num_routes = ARRAY_SIZE(mt8365_mmsys_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.clk_driver = "clk-mt8195-vdo0",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
@@ -171,6 +178,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8365-mmsys",
 		.data = &mt8365_mmsys_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys0",
+		.data = &mt8195_vdosys0_driver_data,
+	},
 	{ }
 };
 
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 2228bf6133da..6d6ece48b61e 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -17,13 +17,22 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DP_INTF0,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_DSC1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
 	DDP_COMPONENT_DSI3,
 	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_MERGE1,
+	DDP_COMPONENT_MERGE2,
+	DDP_COMPONENT_MERGE3,
+	DDP_COMPONENT_MERGE4,
+	DDP_COMPONENT_MERGE5,
 	DDP_COMPONENT_OD0,
 	DDP_COMPONENT_OD1,
 	DDP_COMPONENT_OVL0,
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:27 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:27 +0800
Subject: [PATCH v8 13/13] drm/mediatek: add mediatek-drm of vdosys0 support
 for mt8195
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-14-jason-jh.lin@mediatek.com>

Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  6 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 28 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 705f28ceb4dd..0d3d3c834e0f 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -353,6 +353,10 @@ static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
 	.fifo_size = 5 * SZ_1K,
 };
 
+static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
+	.fifo_size = 1920,
+};
+
 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt2701-disp-rdma",
 	  .data = &mt2701_rdma_driver_data},
@@ -360,6 +364,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	  .data = &mt8173_rdma_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = &mt8183_rdma_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = &mt8195_rdma_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index aba26a704d9c..18b89ab990c0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -147,6 +147,19 @@ static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
 	DDP_COMPONENT_DPI0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
+	DDP_COMPONENT_OVL0,
+	DDP_COMPONENT_RDMA0,
+	DDP_COMPONENT_COLOR0,
+	DDP_COMPONENT_CCORR,
+	DDP_COMPONENT_AAL0,
+	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_DP_INTF0,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -186,6 +199,11 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.main_path = mt8195_mtk_ddp_main,
+	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+};
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
@@ -406,10 +424,14 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8183-disp-dither",
 	  .data = (void *)MTK_DISP_DITHER },
+	{ .compatible = "mediatek,mt8195-disp-dsc",
+	  .data = (void *)MTK_DISP_DSC },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
+	{ .compatible = "mediatek,mt8195-disp-merge",
+	  .data = (void *)MTK_DISP_MERGE },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -418,6 +440,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8173-disp-od",
 	  .data = (void *)MTK_DISP_OD },
 	{ .compatible = "mediatek,mt2701-disp-ovl",
@@ -438,6 +462,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8173-disp-ufoe",
 	  .data = (void *)MTK_DISP_UFOE },
 	{ .compatible = "mediatek,mt8173-disp-wdma",
@@ -468,6 +494,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
 	  .data = &mt8173_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8183-mmsys",
 	  .data = &mt8183_mmsys_driver_data},
+	{.compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:25 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:25 +0800
Subject: [PATCH v8 11/13] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-12-jason-jh.lin@mediatek.com>

DSC is designed for real-time systems with real-time compression,
transmission, decompression and display.
The DSC standard is a specification of the algorithms used for
compressing and decompressing image display streams, including
the specification of the syntax and semantics of the compressed
video bit stream.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 46 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 2 files changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 28bc42fd0b8a..929630a6d832 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -45,6 +45,12 @@
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_DSC_CON			0x0000
+#define DSC_EN					BIT(0)
+#define DSC_DUAL_INOUT				BIT(2)
+#define DSC_BYPASS				BIT(4)
+#define DSC_UFOE_SEL				BIT(16)
+
 #define DISP_REG_OD_EN				0x0000
 #define DISP_REG_OD_CFG				0x0020
 #define OD_RELAYMODE				BIT(0)
@@ -211,6 +217,35 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc,
 			      DISP_DITHERING, cmdq_pkt);
 }
 
+static void mtk_dsc_config(struct device *dev, unsigned int w,
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* dsc bypass mode */
+	mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_BYPASS);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_UFOE_SEL);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_DUAL_INOUT);
+}
+
+static void mtk_dsc_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(DSC_EN, &priv->regs + DISP_REG_DSC_CON);
+}
+
+static void mtk_dsc_stop(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
+}
+
 static void mtk_od_config(struct device *dev, unsigned int w,
 			  unsigned int h, unsigned int vrefresh,
 			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -274,6 +309,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = {
 	.stop = mtk_dpi_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_dsc = {
+	.clk_enable = mtk_ddp_clk_enable,
+	.clk_disable = mtk_ddp_clk_disable,
+	.config = mtk_dsc_config,
+	.start = mtk_dsc_start,
+	.stop = mtk_dsc_stop,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_dsi = {
 	.start = mtk_dsi_ddp_start,
 	.stop = mtk_dsi_ddp_stop,
@@ -335,6 +378,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_CCORR] = "ccorr",
 	[MTK_DISP_COLOR] = "color",
 	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
@@ -364,6 +408,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DITHER]	= { MTK_DISP_DITHER,	0, &ddp_dither },
 	[DDP_COMPONENT_DPI0]	= { MTK_DPI,		0, &ddp_dpi },
 	[DDP_COMPONENT_DPI1]	= { MTK_DPI,		1, &ddp_dpi },
+	[DDP_COMPONENT_DSC0]	= { MTK_DISP_DSC,	0, &ddp_dsc },
+	[DDP_COMPONENT_DSC1]	= { MTK_DISP_DSC,	1, &ddp_dsc },
 	[DDP_COMPONENT_DSI0]	= { MTK_DSI,		0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]	= { MTK_DSI,		1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]	= { MTK_DSI,		2, &ddp_dsi },
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index d317b944df66..560be6bc9d0e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_CCORR,
 	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
+	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:26 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:26 +0800
Subject: [PATCH v8 12/13] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-13-jason-jh.lin@mediatek.com>

Add MERGE engine file:
MERGE module is used to merge two slice-per-line inputs
into one side-by-side output.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile           |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 268 ++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  16 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   2 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
 7 files changed, 297 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index dc54a7a69005..538e0087a44c 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -3,6 +3,7 @@
 mediatek-drm-y := mtk_disp_ccorr.o \
 		  mtk_disp_color.o \
 		  mtk_disp_gamma.o \
+		  mtk_disp_merge.o \
 		  mtk_disp_ovl.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index cafd9df2d63b..f407cd9d873e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -46,6 +46,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
 void mtk_gamma_start(struct device *dev);
 void mtk_gamma_stop(struct device *dev);
 
+int mtk_merge_clk_enable(struct device *dev);
+void mtk_merge_clk_disable(struct device *dev);
+void mtk_merge_config(struct device *dev, unsigned int width,
+		      unsigned int height, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start(struct device *dev);
+void mtk_merge_stop(struct device *dev);
+
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
 void mtk_ovl_bypass_shadow(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
new file mode 100644
index 000000000000..ebcb646bde9c
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_disp_drv.h"
+
+#define DISP_REG_MERGE_CTRL		0x000
+#define MERGE_EN				1
+#define DISP_REG_MERGE_CFG_0		0x010
+#define DISP_REG_MERGE_CFG_4		0x020
+#define DISP_REG_MERGE_CFG_10		0x038
+/* no swap */
+#define SWAP_MODE				0
+#define FLD_SWAP_MODE				GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_12		0x040
+#define CFG_10_10_1PI_2PO_BUF_MODE		6
+#define CFG_10_10_2PI_2PO_BUF_MODE		8
+#define FLD_CFG_MERGE_MODE			GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_24		0x070
+#define DISP_REG_MERGE_CFG_25		0x074
+#define DISP_REG_MERGE_CFG_36		0x0a0
+#define ULTRA_EN				1
+#define PREULTRA_EN				1
+#define HALT_FOR_DVFS_EN			0
+#define FLD_ULTRA_EN				GENMASK(0, 0)
+#define FLD_PREULTRA_EN				GENMASK(4, 4)
+#define FLD_HALT_FOR_DVFS_EN			GENMASK(8, 8)
+#define DISP_REG_MERGE_CFG_37		0x0a4
+/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
+#define BUFFER_MODE				3
+#define FLD_BUFFER_MODE				GENMASK(1, 0)
+#define DISP_REG_MERGE_CFG_38			0x0a8
+#define FLD_VDE_BLOCK_ULTRA			GENMASK(0, 0)
+#define FLD_VALID_TH_BLOCK_ULTRA		GENMASK(4, 4)
+#define FLD_ULTRA_FIFO_VALID_TH			GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_39		0x0ac
+#define FLD_NVDE_FORCE_PREULTRA			GENMASK(8, 8)
+#define FLD_NVALID_TH_FORCE_PREULTRA		GENMASK(12, 12)
+#define FLD_PREULTRA_FIFO_VALID_TH		GENMASK(31, 16)
+
+/*
+ * For the ultra and preultra settings, 6us ~ 9us is experience value
+ * and the maximum frequency of mmsys clock is 594MHz.
+ */
+#define DISP_REG_MERGE_CFG_40		0x0b0
+/* 6 us, 594M pixel/sec */
+#define ULTRA_TH_LOW			(6 * 594)
+/* 8 us, 594M pixel/sec */
+#define ULTRA_TH_HIGH			(8 * 594)
+#define FLD_ULTRA_TH_LOW		GENMASK(15, 0)
+#define FLD_ULTRA_TH_HIGH		GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_41		0x0b4
+/* 8 us, 594M pixel/sec */
+#define PREULTRA_TH_LOW			(8 * 594)
+/* 9 us, 594M pixel/sec */
+#define PREULTRA_TH_HIGH		(9 * 594)
+#define FLD_PREULTRA_TH_LOW		GENMASK(15, 0)
+#define FLD_PREULTRA_TH_HIGH		GENMASK(31, 16)
+
+struct mtk_disp_merge {
+	void __iomem *regs;
+	struct clk *clk;
+	struct clk *async_clk;
+	struct cmdq_client_reg		cmdq_reg;
+	bool				fifo_en;
+};
+
+void mtk_merge_start(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
+				   struct cmdq_pkt *handle)
+{
+	mtk_ddp_write_mask(handle, ULTRA_EN | PREULTRA_EN << 4 | HALT_FOR_DVFS_EN << 8,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_36,
+			   FLD_ULTRA_EN | FLD_PREULTRA_EN | FLD_HALT_FOR_DVFS_EN);
+
+	mtk_ddp_write_mask(handle, BUFFER_MODE,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_37,
+			   FLD_BUFFER_MODE);
+
+	mtk_ddp_write_mask(handle, 0,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_38,
+			   FLD_VDE_BLOCK_ULTRA | FLD_VALID_TH_BLOCK_ULTRA |
+			   FLD_ULTRA_FIFO_VALID_TH);
+
+	mtk_ddp_write_mask(handle, 0,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_39,
+			   FLD_NVDE_FORCE_PREULTRA | FLD_NVALID_TH_FORCE_PREULTRA |
+			   FLD_PREULTRA_FIFO_VALID_TH);
+
+	mtk_ddp_write_mask(handle, ULTRA_TH_LOW | ULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_40,
+			   FLD_ULTRA_TH_LOW | FLD_ULTRA_TH_HIGH);
+
+	mtk_ddp_write_mask(handle, PREULTRA_TH_LOW | PREULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_41,
+			   FLD_PREULTRA_TH_LOW | FLD_PREULTRA_TH_HIGH);
+}
+
+void mtk_merge_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *handle)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+	unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
+
+	if (!h || !w) {
+		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
+		return;
+	}
+
+	if (priv->fifo_en) {
+		mtk_merge_fifo_setting(priv, handle);
+		mode = CFG_10_10_2PI_2PO_BUF_MODE;
+	}
+
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_0);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_4);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_24);
+	mtk_ddp_write(handle, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_25);
+	mtk_ddp_write_mask(handle, SWAP_MODE, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
+	mtk_ddp_write_mask(handle, mode, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_12, FLD_CFG_MERGE_MODE);
+}
+
+int mtk_merge_clk_enable(struct device *dev)
+{
+	int ret = 0;
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		pr_err("merge clk prepare enable failed\n");
+
+	if (priv->async_clk) {
+		ret = clk_prepare_enable(priv->async_clk);
+		if (ret)
+			pr_err("async clk prepare enable failed\n");
+	}
+
+	return ret;
+}
+
+void mtk_merge_clk_disable(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	if (priv->async_clk)
+		clk_disable_unprepare(priv->async_clk);
+
+	clk_disable_unprepare(priv->clk);
+}
+
+static int mtk_disp_merge_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return 0;
+}
+
+static void mtk_disp_merge_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+}
+
+static const struct component_ops mtk_disp_merge_component_ops = {
+	.bind	= mtk_disp_merge_bind,
+	.unbind = mtk_disp_merge_unbind,
+};
+
+static int mtk_disp_merge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct mtk_disp_merge *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap merge\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get merge clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	priv->async_clk = of_clk_get(dev->of_node, 1);
+	if (IS_ERR(priv->async_clk)) {
+		ret = PTR_ERR(priv->async_clk);
+		dev_dbg(dev, "No merge async clock: %d\n", ret);
+		priv->async_clk = NULL;
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+	priv->fifo_en = of_property_read_bool(dev->of_node,
+					      "mediatek,merge-fifo-en");
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_disp_merge_component_ops);
+	if (ret != 0)
+		dev_err(dev, "Failed to add component: %d\n", ret);
+
+	return ret;
+}
+
+static int mtk_disp_merge_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_disp_merge_component_ops);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_disp_merge_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-merge", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
+
+struct platform_driver mtk_disp_merge_driver = {
+	.probe = mtk_disp_merge_probe,
+	.remove = mtk_disp_merge_remove,
+	.driver = {
+		.name = "mediatek-disp-merge",
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_disp_merge_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 929630a6d832..ee8efc13eaea 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -331,6 +331,14 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
 	.stop = mtk_gamma_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_merge = {
+	.clk_enable = mtk_merge_clk_enable,
+	.clk_disable = mtk_merge_clk_disable,
+	.start = mtk_merge_start,
+	.stop = mtk_merge_stop,
+	.config = mtk_merge_config,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_od = {
 	.clk_enable = mtk_ddp_clk_enable,
 	.clk_disable = mtk_ddp_clk_disable,
@@ -380,6 +388,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MERGE] = "merge",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
@@ -415,6 +424,12 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DSI2]	= { MTK_DSI,		2, &ddp_dsi },
 	[DDP_COMPONENT_DSI3]	= { MTK_DSI,		3, &ddp_dsi },
 	[DDP_COMPONENT_GAMMA]	= { MTK_DISP_GAMMA,	0, &ddp_gamma },
+	[DDP_COMPONENT_MERGE0]	= { MTK_DISP_MERGE,	0, &ddp_merge },
+	[DDP_COMPONENT_MERGE1]	= { MTK_DISP_MERGE,	1, &ddp_merge },
+	[DDP_COMPONENT_MERGE2]	= { MTK_DISP_MERGE,	2, &ddp_merge },
+	[DDP_COMPONENT_MERGE3]	= { MTK_DISP_MERGE,	3, &ddp_merge },
+	[DDP_COMPONENT_MERGE4]	= { MTK_DISP_MERGE,	4, &ddp_merge },
+	[DDP_COMPONENT_MERGE5]	= { MTK_DISP_MERGE,	5, &ddp_merge },
 	[DDP_COMPONENT_OD0]	= { MTK_DISP_OD,	0, &ddp_od },
 	[DDP_COMPONENT_OD1]	= { MTK_DISP_OD,	1, &ddp_od },
 	[DDP_COMPONENT_OVL0]	= { MTK_DISP_OVL,	0, &ddp_ovl },
@@ -545,6 +560,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
+	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 560be6bc9d0e..b42a47c06956 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -25,6 +25,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_DITHER,
 	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
+	MTK_DISP_MERGE,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a95dc1006b82..aba26a704d9c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -539,6 +539,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		if (comp_type == MTK_DISP_CCORR ||
 		    comp_type == MTK_DISP_COLOR ||
 		    comp_type == MTK_DISP_GAMMA ||
+		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
@@ -639,6 +640,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ccorr_driver,
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
+	&mtk_disp_merge_driver,
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 637f5669e895..0fa417219a69 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -49,6 +49,7 @@ struct mtk_drm_private {
 extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
+extern struct platform_driver mtk_disp_merge_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:16 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:16 +0800
Subject: [PATCH v8 02/13] dt-bindings: mediatek: display: split each block to
 individual yaml
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-3-jason-jh.lin@mediatek.com>

1. Remove mediatek,dislpay.txt
2. Split each display function block to individual yaml file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,aal.yaml        |  75 ++++++
 .../display/mediatek/mediatek,ccorr.yaml      |  69 ++++++
 .../display/mediatek/mediatek,color.yaml      |  84 +++++++
 .../display/mediatek/mediatek,disp.txt        | 219 ------------------
 .../display/mediatek/mediatek,dither.yaml     |  70 ++++++
 .../display/mediatek/mediatek,gamma.yaml      |  71 ++++++
 .../display/mediatek/mediatek,merge.yaml      |  57 +++++
 .../display/mediatek/mediatek,mutex.yaml      |  77 ++++++
 .../display/mediatek/mediatek,od.yaml         |  52 +++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  86 +++++++
 .../display/mediatek/mediatek,ovl.yaml        |  96 ++++++++
 .../display/mediatek/mediatek,rdma.yaml       | 110 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  56 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  59 +++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
 15 files changed, 1048 insertions(+), 219 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
new file mode 100644
index 000000000000..7be772d77e36
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display adaptive ambient light processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display adaptive ambient light processor, namely AAL,
+  is responsible for backlight power saving and sunlight visibility improving.
+  AAL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-aal
+      - items:
+          - enum:
+              - mediatek,mt2712-disp-aal
+              - mediatek,mt8183-disp-aal
+          - enum:
+              - mediatek,mt8173-disp-aal
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: AAL Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    aal at 14015000 {
+        compatible = "mediatek,mt8173-disp-aal";
+        reg = <0 0x14015000 0 0x1000>;
+        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_AAL>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..5a1c27d6b3e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek Ddsplay color correction
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display color correction, namely CCORR, reproduces correct color
+  on panels with different color gamut.
+  CCORR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ccorr
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: CCORR Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ccorr0: ccorr at 1400f000 {
+        compatible = "mediatek,mt8183-disp-ccorr";
+        reg = <0 0x1400f000 0 0x1000>;
+        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+    }
+;
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
new file mode 100644
index 000000000000..9a3edf6f0b8e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display color processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek color processor, namely COLOR, provides hue, luma and
+  saturation adjustments to get better picture quality and to have one panel
+  resemble the other in their output characteristics.
+  COLOR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-color
+      - items:
+          - const: mediatek,mt8167-disp-color
+      - items:
+          - const: mediatek,mt8173-disp-color
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-color
+              - mediatek,mt2712-disp-color
+          - enum:
+              - mediatek,mt2701-disp-color
+      - items:
+          - enum:
+              - mediatek,mt8183-disp-color
+          - enum:
+              - mediatek,mt8173-disp-color
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: COLOR Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    color0: color at 14013000 {
+        compatible = "mediatek,mt8173-disp-color";
+        reg = <0 0x14013000 0 0x1000>;
+        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
deleted file mode 100644
index fbb59c9ddda6..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ /dev/null
@@ -1,219 +0,0 @@
-Mediatek display subsystem
-==========================
-
-The Mediatek display subsystem consists of various DISP function blocks in the
-MMSYS register space. The connections between them can be configured by output
-and input selectors in the MMSYS_CONFIG register space. Pixel clock and start
-of frame signal are distributed to the other function blocks by a DISP_MUTEX
-function block.
-
-All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
-For a description of the MMSYS_CONFIG binding, see
-Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt.
-
-DISP function blocks
-====================
-
-A display stream starts at a source function block that reads pixel data from
-memory and ends with a sink function block that drives pixels on a display
-interface, or writes pixels back to memory. All DISP function blocks have
-their own register space, interrupt, and clock gate. The blocks that can
-access memory additionally have to list the IOMMU and local arbiter they are
-connected to.
-
-For a description of the display interface sink function blocks, see
-Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
-Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
-
-Required properties (all function blocks):
-- compatible: "mediatek,<chip>-disp-<function>", one of
-	"mediatek,<chip>-disp-ovl"   		- overlay (4 layers, blending, csc)
-	"mediatek,<chip>-disp-ovl-2l"           - overlay (2 layers, blending, csc)
-	"mediatek,<chip>-disp-rdma"  		- read DMA / line buffer
-	"mediatek,<chip>-disp-wdma"  		- write DMA
-	"mediatek,<chip>-disp-ccorr"            - color correction
-	"mediatek,<chip>-disp-color" 		- color processor
-	"mediatek,<chip>-disp-dither"           - dither
-	"mediatek,<chip>-disp-aal"   		- adaptive ambient light controller
-	"mediatek,<chip>-disp-gamma" 		- gamma correction
-	"mediatek,<chip>-disp-merge" 		- merge streams from two RDMA sources
-	"mediatek,<chip>-disp-postmask" 	- control round corner for display frame
-	"mediatek,<chip>-disp-split" 		- split stream to two encoders
-	"mediatek,<chip>-disp-ufoe"  		- data compression engine
-	"mediatek,<chip>-dsi"        		- DSI controller, see mediatek,dsi.txt
-	"mediatek,<chip>-dpi"        		- DPI controller, see mediatek,dpi.txt
-	"mediatek,<chip>-disp-mutex" 		- display mutex
-	"mediatek,<chip>-disp-od"    		- overdrive
-  the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
-- reg: Physical base address and length of the function block register space
-- interrupts: The interrupt signal from the function block (required, except for
-  merge and split function blocks).
-- clocks: device clocks
-  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-  For most function blocks this is just a single clock input. Only the DSI and
-  DPI controller nodes have multiple clock inputs. These are documented in
-  mediatek,dsi.txt and mediatek,dpi.txt, respectively.
-  An exception is that the mt8183 mutex is always free running with no clocks property.
-
-Required properties (DMA function blocks):
-- compatible: Should be one of
-	"mediatek,<chip>-disp-ovl"
-	"mediatek,<chip>-disp-rdma"
-	"mediatek,<chip>-disp-wdma"
-  the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-- iommus: Should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-
-Optional properties (RDMA function blocks):
-- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
-  property to the corresponding rdma
-  the value is the Max value which defined in hardware data sheet.
-  mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
-  mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
-  mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
-
-Examples:
-
-mmsys: clock-controller at 14000000 {
-	compatible = "mediatek,mt8173-mmsys", "syscon";
-	reg = <0 0x14000000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	#clock-cells = <1>;
-};
-
-ovl0: ovl at 1400c000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400c000 0 0x1000>;
-	interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL0>;
-	iommus = <&iommu M4U_PORT_DISP_OVL0>;
-	mediatek,larb = <&larb0>;
-};
-
-ovl1: ovl at 1400d000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400d000 0 0x1000>;
-	interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL1>;
-	iommus = <&iommu M4U_PORT_DISP_OVL1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma0: rdma at 1400e000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400e000 0 0x1000>;
-	interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-	mediatek,larb = <&larb0>;
-	mediatek,rdma-fifosize = <8192>;
-};
-
-rdma1: rdma at 1400f000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400f000 0 0x1000>;
-	interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma2: rdma at 14010000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x14010000 0 0x1000>;
-	interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA2>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA2>;
-	mediatek,larb = <&larb4>;
-};
-
-wdma0: wdma at 14011000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14011000 0 0x1000>;
-	interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-	mediatek,larb = <&larb0>;
-};
-
-wdma1: wdma at 14012000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14012000 0 0x1000>;
-	interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-color0: color at 14013000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14013000 0 0x1000>;
-	interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR0>;
-};
-
-color1: color at 14014000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14014000 0 0x1000>;
-	interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR1>;
-};
-
-aal at 14015000 {
-	compatible = "mediatek,mt8173-disp-aal";
-	reg = <0 0x14015000 0 0x1000>;
-	interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_AAL>;
-};
-
-gamma at 14016000 {
-	compatible = "mediatek,mt8173-disp-gamma";
-	reg = <0 0x14016000 0 0x1000>;
-	interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_GAMMA>;
-};
-
-ufoe at 1401a000 {
-	compatible = "mediatek,mt8173-disp-ufoe";
-	reg = <0 0x1401a000 0 0x1000>;
-	interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_UFOE>;
-};
-
-dsi0: dsi at 1401b000 {
-	/* See mediatek,dsi.txt for details */
-};
-
-dpi0: dpi at 1401d000 {
-	/* See mediatek,dpi.txt for details */
-};
-
-mutex: mutex at 14020000 {
-	compatible = "mediatek,mt8173-disp-mutex";
-	reg = <0 0x14020000 0 0x1000>;
-	interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_MUTEX_32K>;
-};
-
-od at 14023000 {
-	compatible = "mediatek,mt8173-disp-od";
-	reg = <0 0x14023000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OD>;
-};
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
new file mode 100644
index 000000000000..20419f876410
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display dither processor
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display dither processor, namely DITHER, works by approximating
+  unavailable colors with available colors and by mixing and matching available
+  colors to mimic unavailable ones.
+  DITHER device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-dither
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: DITHER Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dither0: dither at 14012000 {
+        compatible = "mediatek,mt8183-disp-dither";
+        reg = <0 0x14012000 0 0x1000>;
+        interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_DITHER0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
new file mode 100644
index 000000000000..e2a1fc218e4f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,gamma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display gamma correction
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display gamma correction, namely GAMMA, provides a nonlinear operation
+  used to adjust luminance in?display system.
+  GAMMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-gamma
+      - items:
+          - const: mediatek,mt8183-disp-gamma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: GAMMA Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    gamma at 14016000 {
+        compatible = "mediatek,mt8173-disp-gamma";
+        reg = <0 0x14016000 0 0x1000>;
+        interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
new file mode 100644
index 000000000000..4cdce11d7fcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,merge.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display merge
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display merge engine is used to merge two slice-per-line inputs
+  into one side-by-side output.
+  MERGE device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-merge
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MERGE Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    merge at 14017000 {
+        compatible = "mediatek,mt8173-disp-merge";
+        reg = <0 0x14017000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_MERGE>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
new file mode 100644
index 000000000000..aaba6bbfb4da
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display mutex
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display mutex is used to send the triggers signals called
+  Start Of Frame (SOF)/ Error Of Frame (EOF) to each sub-modules on the
+  display data path.
+  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-mutex
+      - items:
+          - const: mediatek,mt2712-disp-mutex
+      - items:
+          - const: mediatek,mt8167-disp-mutex
+      - items:
+          - const: mediatek,mt8173-disp-mutex
+      - items:
+          - const: mediatek,mt8183-disp-mutex
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MUTEX Clock
+
+  mediatek,gce-events:
+    description:
+      The event id which is mapping to the specific hardware event signal to gce.
+      The event id is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    mutex: mutex at 14020000 {
+        compatible = "mediatek,mt8173-disp-mutex";
+        reg = <0 0x14020000 0 0x1000>;
+        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_MUTEX_32K>;
+        mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+                              <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
new file mode 100644
index 000000000000..bcf3fddd9231
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,od.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overdirve
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overdrive, namely OD, increases the transition values
+  of pixels between consecutive frames to make LCD rotate faster.
+  OD device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2712-disp-od
+      - items:
+          - const: mediatek,mt8173-disp-od
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    od at 14023000 {
+        compatible = "mediatek,mt8173-disp-od";
+        reg = <0 0x14023000 0 0x1000>;
+        clocks = <&mmsys CLK_MM_DISP_OD>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
new file mode 100644
index 000000000000..6255074bf415
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl-2l.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overlay 2 layer
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overlay provides 2 more layer for OVL.
+  OVL-2L device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ovl-2l
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL-2L Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl_2l0: ovl at 14009000 {
+        compatible = "mediatek,mt8183-disp-ovl-2l";
+        reg = <0 0x14009000 0 0x1000>;
+        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
+        iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
new file mode 100644
index 000000000000..833b0ca09b21
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overlay
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display overlay, namely OVL, can do alpha blending from the memory.
+  OVL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-ovl
+      - items:
+          - const: mediatek,mt8173-disp-ovl
+      - items:
+          - const: mediatek,mt8183-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-ovl
+              - mediatek,mt2712-disp-ovl
+          - enum:
+              - mediatek,mt2701-disp-ovl
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommu
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl0: ovl at 1400c000 {
+        compatible = "mediatek,mt8173-disp-ovl";
+        reg = <0 0x1400c000 0 0x1000>;
+        interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0>;
+        iommus = <&iommu M4U_PORT_DISP_OVL0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
new file mode 100644
index 000000000000..ce3bcca30609
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display RDMA
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-rdma
+      - items:
+          - const: mediatek,mt8173-disp-rdma
+      - items:
+          - const: mediatek,mt8183-disp-rdma
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-rdma
+              - mediatek,mt2712-disp-rdma
+          - enum:
+              - mediatek,mt2701-disp-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,rdma-fifo-size:
+    description:
+      rdma fifo size may be different even in same SOC, add this property to the
+      corresponding rdma.
+      The value below is the Max value which defined in hardware data sheet
+      mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
+      mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
+      mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8192, 5120, 2048]
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    rdma0: rdma at 1400e000 {
+        compatible = "mediatek,mt8173-disp-rdma";
+        reg = <0 0x1400e000 0 0x1000>;
+        interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_RDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_RDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,rdma-fifosize = <8192>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
new file mode 100644
index 000000000000..d751e0a0c3a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,split.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display split
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display split engine is used to split stream to two encoders.
+  SPLIT device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-split
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: SPLIT Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    split0: split at 14018000 {
+        compatible = "mediatek,mt8173-disp-split";
+        reg = <0 0x14018000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
new file mode 100644
index 000000000000..d0249333a2bd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ufoe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display UFOe
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The Mediatek display UFOe stands for Unified Frame Optimization engine.
+  UFOe can cut the data rate for DSI port which may lead to reduce power consumption.
+  UFOe device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-ufoe
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: UFOe Clock
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ufoe at 1401a000 {
+        compatible = "mediatek,mt8173-disp-ufoe";
+        reg = <0 0x1401a000 0 0x1000>;
+        interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_UFOE>;
+    };
+
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..d7a3ba497fb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display WDMA
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display WDMA stands for Write Direct Memory Access.
+  It can write the data in display pipeline into DRAM.
+  WDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-wdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: WDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    wdma0: wdma at 14011000 {
+        compatible = "mediatek,mt8173-disp-wdma";
+        reg = <0 0x14011000 0 0x1000>;
+        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+    };
+
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:23 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:23 +0800
Subject: [PATCH v8 09/13] drm/mediatek: rename the define of register offset
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-10-jason-jh.lin@mediatek.com>

Add DISP_REG prefix for the define of register offset to
make the difference from the define of register value.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 57 +++++++++++----------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index aaa7450b3e2b..93beb980414f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -20,25 +20,25 @@
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_crtc.h"
 
-#define DISP_OD_EN				0x0000
-#define DISP_OD_CFG				0x0020
-#define DISP_OD_SIZE				0x0030
-#define DISP_DITHER_5				0x0114
-#define DISP_DITHER_7				0x011c
-#define DISP_DITHER_15				0x013c
-#define DISP_DITHER_16				0x0140
+#define DISP_REG_OD_EN				0x0000
+#define DISP_REG_OD_CFG				0x0020
+#define DISP_REG_OD_SIZE			0x0030
+#define DISP_REG_DITHER_5			0x0114
+#define DISP_REG_DITHER_7			0x011c
+#define DISP_REG_DITHER_15			0x013c
+#define DISP_REG_DITHER_16			0x0140
 
 #define DISP_REG_UFO_START			0x0000
 
-#define DISP_AAL_EN				0x0000
-#define DISP_AAL_SIZE				0x0030
+#define DISP_REG_AAL_EN				0x0000
+#define DISP_REG_AAL_SIZE			0x0030
 
-#define DISP_DITHER_EN				0x0000
+#define DISP_REG_DITHER_EN			0x0000
 #define DITHER_EN				BIT(0)
-#define DISP_DITHER_CFG				0x0020
+#define DISP_REG_DITHER_CFG			0x0020
 #define DITHER_RELAY_MODE			BIT(0)
 #define DITHER_ENGINE_EN			BIT(1)
-#define DISP_DITHER_SIZE			0x0030
+#define DISP_REG_DITHER_SIZE			0x0030
 
 #define OD_RELAYMODE				BIT(0)
 
@@ -129,19 +129,19 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 		return;
 
 	if (bpc >= MTK_MIN_BPC) {
-		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
-		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
+		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_5);
+		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_7);
 		mtk_ddp_write(cmdq_pkt,
 			      DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
 			      DITHER_NEW_BIT_MODE,
-			      cmdq_reg, regs, DISP_DITHER_15);
+			      cmdq_reg, regs, DISP_REG_DITHER_15);
 		mtk_ddp_write(cmdq_pkt,
 			      DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
 			      DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
-			      cmdq_reg, regs, DISP_DITHER_16);
+			      cmdq_reg, regs, DISP_REG_DITHER_16);
 		mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg);
 	}
 }
@@ -161,16 +161,16 @@ static void mtk_od_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE);
-	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG);
-	mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
+	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
+	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
 }
 
 static void mtk_od_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(1, priv->regs + DISP_OD_EN);
+	writel(1, priv->regs + DISP_REG_OD_EN);
 }
 
 static void mtk_ufoe_start(struct device *dev)
@@ -186,7 +186,7 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_AAL_SIZE);
 }
 
 static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
@@ -200,14 +200,14 @@ static void mtk_aal_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(AAL_EN, priv->regs + DISP_AAL_EN);
+	writel(AAL_EN, priv->regs + DISP_REG_AAL_EN);
 }
 
 static void mtk_aal_stop(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, priv->regs + DISP_AAL_EN);
+	writel_relaxed(0x0, priv->regs + DISP_REG_AAL_EN);
 }
 
 static void mtk_dither_config(struct device *dev, unsigned int w,
@@ -216,9 +216,10 @@ static void mtk_dither_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_DITHER_SIZE);
-	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, DISP_DITHER_CFG);
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_DITHER_CFG,
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE);
+	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_DITHER_CFG);
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
 			      DITHER_ENGINE_EN, cmdq_pkt);
 }
 
@@ -226,14 +227,14 @@ static void mtk_dither_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
+	writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
 }
 
 static void mtk_dither_stop(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
+	writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
 }
 
 static const struct mtk_ddp_comp_funcs ddp_aal = {
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 18 19:23:24 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Thu, 19 Aug 2021 10:23:24 +0800
Subject: [PATCH v8 10/13] drm/mediatek: adjust to the alphabetic order for
 mediatek-drm
In-Reply-To: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
Message-ID: <20210819022327.13040-11-jason-jh.lin@mediatek.com>

Adjust to the alphabetic order for the define, function, struct
and array in mediatek-drm driver

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 133 ++++++++++----------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  22 ++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  76 +++++------
 3 files changed, 115 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 93beb980414f..28bc42fd0b8a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -20,17 +20,9 @@
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_crtc.h"
 
-#define DISP_REG_OD_EN				0x0000
-#define DISP_REG_OD_CFG				0x0020
-#define DISP_REG_OD_SIZE			0x0030
-#define DISP_REG_DITHER_5			0x0114
-#define DISP_REG_DITHER_7			0x011c
-#define DISP_REG_DITHER_15			0x013c
-#define DISP_REG_DITHER_16			0x0140
-
-#define DISP_REG_UFO_START			0x0000
 
 #define DISP_REG_AAL_EN				0x0000
+#define AAL_EN					BIT(0)
 #define DISP_REG_AAL_SIZE			0x0030
 
 #define DISP_REG_DITHER_EN			0x0000
@@ -38,23 +30,29 @@
 #define DISP_REG_DITHER_CFG			0x0020
 #define DITHER_RELAY_MODE			BIT(0)
 #define DITHER_ENGINE_EN			BIT(1)
-#define DISP_REG_DITHER_SIZE			0x0030
-
-#define OD_RELAYMODE				BIT(0)
-
-#define UFO_BYPASS				BIT(2)
-
-#define AAL_EN					BIT(0)
 
 #define DISP_DITHERING				BIT(2)
+#define DISP_REG_DITHER_SIZE			0x0030
+#define DISP_REG_DITHER_5			0x0114
+#define DISP_REG_DITHER_7			0x011c
+#define DISP_REG_DITHER_15			0x013c
 #define DITHER_LSB_ERR_SHIFT_R(x)		(((x) & 0x7) << 28)
 #define DITHER_ADD_LSHIFT_R(x)			(((x) & 0x7) << 20)
 #define DITHER_NEW_BIT_MODE			BIT(0)
+#define DISP_REG_DITHER_16			0x0140
 #define DITHER_LSB_ERR_SHIFT_B(x)		(((x) & 0x7) << 28)
 #define DITHER_ADD_LSHIFT_B(x)			(((x) & 0x7) << 20)
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_OD_EN				0x0000
+#define DISP_REG_OD_CFG				0x0020
+#define OD_RELAYMODE				BIT(0)
+#define DISP_REG_OD_SIZE			0x0030
+
+#define DISP_REG_UFO_START			0x0000
+#define UFO_BYPASS				BIT(2)
+
 struct mtk_ddp_comp_dev {
 	struct clk *clk;
 	void __iomem *regs;
@@ -106,20 +104,6 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 #endif
 }
 
-static int mtk_ddp_clk_enable(struct device *dev)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	return clk_prepare_enable(priv->clk);
-}
-
-static void mtk_ddp_clk_disable(struct device *dev)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	clk_disable_unprepare(priv->clk);
-}
-
 void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 			   unsigned int bpc, unsigned int cfg,
 			   unsigned int dither_en, struct cmdq_pkt *cmdq_pkt)
@@ -146,38 +130,19 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 	}
 }
 
-static void mtk_dither_set(struct device *dev, unsigned int bpc,
-		    unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
-			      DISP_DITHERING, cmdq_pkt);
-}
-
-static void mtk_od_config(struct device *dev, unsigned int w,
-			  unsigned int h, unsigned int vrefresh,
-			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
-	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
-	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
-}
 
-static void mtk_od_start(struct device *dev)
+static int mtk_ddp_clk_enable(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(1, priv->regs + DISP_REG_OD_EN);
+	return clk_prepare_enable(priv->clk);
 }
 
-static void mtk_ufoe_start(struct device *dev)
+static void mtk_ddp_clk_disable(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
+	clk_disable_unprepare(priv->clk);
 }
 
 static void mtk_aal_config(struct device *dev, unsigned int w,
@@ -237,6 +202,40 @@ static void mtk_dither_stop(struct device *dev)
 	writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
 }
 
+static void mtk_dither_set(struct device *dev, unsigned int bpc,
+			   unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
+			      DISP_DITHERING, cmdq_pkt);
+}
+
+static void mtk_od_config(struct device *dev, unsigned int w,
+			  unsigned int h, unsigned int vrefresh,
+			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
+	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
+	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
+}
+
+static void mtk_od_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel(1, priv->regs + DISP_REG_OD_EN);
+}
+
+static void mtk_ufoe_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
+}
+
 static const struct mtk_ddp_comp_funcs ddp_aal = {
 	.clk_enable = mtk_ddp_clk_enable,
 	.clk_disable = mtk_ddp_clk_disable,
@@ -331,22 +330,22 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
 };
 
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
+	[MTK_DISP_AAL] = "aal",
+	[MTK_DISP_BLS] = "bls",
+	[MTK_DISP_CCORR] = "ccorr",
+	[MTK_DISP_COLOR] = "color",
+	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
 	[MTK_DISP_OVL_2L] = "ovl-2l",
+	[MTK_DISP_PWM] = "pwm",
 	[MTK_DISP_RDMA] = "rdma",
-	[MTK_DISP_WDMA] = "wdma",
-	[MTK_DISP_COLOR] = "color",
-	[MTK_DISP_CCORR] = "ccorr",
-	[MTK_DISP_AAL] = "aal",
-	[MTK_DISP_GAMMA] = "gamma",
-	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_UFOE] = "ufoe",
-	[MTK_DSI] = "dsi",
+	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
-	[MTK_DISP_PWM] = "pwm",
-	[MTK_DISP_MUTEX] = "mutex",
-	[MTK_DISP_OD] = "od",
-	[MTK_DISP_BLS] = "bls",
+	[MTK_DSI] = "dsi",
 };
 
 struct mtk_ddp_comp_match {
@@ -500,12 +499,12 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
-	    type == MTK_DPI ||
-	    type == MTK_DSI ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
-	    type == MTK_DISP_RDMA)
+	    type == MTK_DISP_RDMA ||
+	    type == MTK_DPI ||
+	    type == MTK_DSI)
 		return 0;
 
 	priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index bb914d976cf5..d317b944df66 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -18,22 +18,22 @@ struct mtk_plane_state;
 struct drm_crtc_state;
 
 enum mtk_ddp_comp_type {
-	MTK_DISP_OVL,
-	MTK_DISP_OVL_2L,
-	MTK_DISP_RDMA,
-	MTK_DISP_WDMA,
-	MTK_DISP_COLOR,
+	MTK_DISP_AAL,
+	MTK_DISP_BLS,
 	MTK_DISP_CCORR,
+	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
-	MTK_DISP_AAL,
 	MTK_DISP_GAMMA,
-	MTK_DISP_UFOE,
-	MTK_DSI,
-	MTK_DPI,
-	MTK_DISP_PWM,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-	MTK_DISP_BLS,
+	MTK_DISP_OVL,
+	MTK_DISP_OVL_2L,
+	MTK_DISP_PWM,
+	MTK_DISP_RDMA,
+	MTK_DISP_UFOE,
+	MTK_DISP_WDMA,
+	MTK_DPI,
+	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index b46bdb8985da..a95dc1006b82 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -396,50 +396,20 @@ static const struct component_master_ops mtk_drm_ops = {
 };
 
 static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
-	{ .compatible = "mediatek,mt2701-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8173-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8183-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
-	  .data = (void *)MTK_DISP_OVL_2L },
-	{ .compatible = "mediatek,mt2701-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8173-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8183-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8173-disp-wdma",
-	  .data = (void *)MTK_DISP_WDMA },
+	{ .compatible = "mediatek,mt8173-disp-aal",
+	  .data = (void *)MTK_DISP_AAL},
 	{ .compatible = "mediatek,mt8183-disp-ccorr",
 	  .data = (void *)MTK_DISP_CCORR },
 	{ .compatible = "mediatek,mt2701-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8173-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
-	{ .compatible = "mediatek,mt8173-disp-aal",
-	  .data = (void *)MTK_DISP_AAL},
+	{ .compatible = "mediatek,mt8183-disp-dither",
+	  .data = (void *)MTK_DISP_DITHER },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
-	{ .compatible = "mediatek,mt8183-disp-dither",
-	  .data = (void *)MTK_DISP_DITHER },
-	{ .compatible = "mediatek,mt8173-disp-ufoe",
-	  .data = (void *)MTK_DISP_UFOE },
-	{ .compatible = "mediatek,mt2701-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt8173-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt8183-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt2701-dpi",
-	  .data = (void *)MTK_DPI },
-	{ .compatible = "mediatek,mt8173-dpi",
-	  .data = (void *)MTK_DPI },
-	{ .compatible = "mediatek,mt8183-dpi",
-	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -448,12 +418,42 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8173-disp-od",
+	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt2701-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8173-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8183-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
+	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt2701-disp-pwm",
 	  .data = (void *)MTK_DISP_BLS },
 	{ .compatible = "mediatek,mt8173-disp-pwm",
 	  .data = (void *)MTK_DISP_PWM },
-	{ .compatible = "mediatek,mt8173-disp-od",
-	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt2701-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8173-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8183-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8173-disp-ufoe",
+	  .data = (void *)MTK_DISP_UFOE },
+	{ .compatible = "mediatek,mt8173-disp-wdma",
+	  .data = (void *)MTK_DISP_WDMA },
+	{ .compatible = "mediatek,mt2701-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8173-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8183-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt2701-dsi",
+	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8173-dsi",
+	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8183-dsi",
+	  .data = (void *)MTK_DSI },
 	{ }
 };
 
@@ -542,8 +542,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
-		    comp_type == MTK_DSI ||
-		    comp_type == MTK_DPI) {
+		    comp_type == MTK_DPI ||
+		    comp_type == MTK_DSI) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, compare_of,
-- 
2.18.0

From samuel at sholland.org  Wed Aug 18 19:32:53 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed, 18 Aug 2021 21:32:53 -0500
Subject: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
In-Reply-To: <74F51516-2470-4A49-972B-E19D8EDD9A3D@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-16-icenowy@sipeed.com>
 <20210818090139.rllz4fvvq3pzdkls@gilmour>
 <74F51516-2470-4A49-972B-E19D8EDD9A3D@sipeed.com>
Message-ID: <75ae9ef8-496b-68ca-214e-e8b270648a50@sholland.org>

On 8/18/21 4:15 AM, Icenowy Zheng wrote:
> ? 2021?8?18? GMT+08:00 ??5:01:39, Maxime Ripard <maxime at cerno.tech> ??:
>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
>>> +		ccu: clock at 2001000 {
>>> +			compatible = "allwinner,sun50i-r329-ccu";
>>> +			reg = <0x02001000 0x1000>;
>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
>>> +			clock-names = "hosc", "losc", "iosc";
>>
>> Do we have a clock tree for the RTC? Is it the same than the H616?
> 
> Nope, it's the same with H6 because of external LOSC crystal is
> possible. (Although production M2A SoMs has it NC for cost control.)

It is not the same as the H6, either. The clock tree _is_ identical to the D1,
which has three diagrams on pages 363-364 of its user manual here:

https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf

Compared to the H6, the R329/D1:
 - Loses the LOSC calibration circuit
 - Gains a third mux input for LOSC (not external 32k) to fanout
 - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
 - Gains an SPI bus clock input divided from the PRCM AHB

Compared to the H616, the R329/D1:
 - Has an external 32k crystal input
   - Gains the IOSC vs. external 32k crystal mux for LOSC
   - Switches fanout mux input #1 from pll_periph0/N to external 32k
 - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
 - Gains an SPI bus clock input divided from the PRCM AHB

So the R329/D1 RTC has three inputs:
 - SPI clock from PRCM
 - 24 MHz DCXO crystal
 - 32 kHz external crystal (optional)

and four outputs:
 - 16 MHz "IOSC" RC oscillator
 - 32 kHz "LOSC"
 - ~1 kHz for RTC timekeeping
 - 32 kHz fanout

(Arguably, since the 24 MHz DCXO can be turned on/off from the RTC registers, it
should be an "output" and not an "input".)

Regards,
Samuel


From samuel at sholland.org  Wed Aug 18 19:40:32 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed, 18 Aug 2021 21:40:32 -0500
Subject: [PATCH 06/17] dt-bindings: pinctrl: document Allwinner R329 PIO
 and R-PIO
In-Reply-To: <20210802062212.73220-7-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-7-icenowy@sipeed.com>
Message-ID: <b2e40538-77ba-6a14-508a-d99d0481278e@sholland.org>

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 have two pin controllers similar to previous Allwinner
> SoCs, PIO and R-PIO.
> 
> Add compatible strings for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  .../bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml         | 4 ++++
>  1 file changed, 4 insertions(+)

Reviewed-by: Samuel Holland <samuel at sholland.org>


From samuel at sholland.org  Wed Aug 18 20:09:56 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed, 18 Aug 2021 22:09:56 -0500
Subject: [PATCH 07/17] pinctrl: sunxi: add support for R329 CPUX pin
 controller
In-Reply-To: <20210802062212.73220-8-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-8-icenowy@sipeed.com>
Message-ID: <2f6de069-7983-efc2-3c4a-7c1355c4cbc5@sholland.org>

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 SoC has two pin controllers similar to ones on previous
> SoCs, one in CPUX power domain and another in CPUS.
> 
> This patch adds support for the CPUX domain pin controller.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  drivers/pinctrl/sunxi/Kconfig               |   5 +
>  drivers/pinctrl/sunxi/Makefile              |   1 +
>  drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c | 410 ++++++++++++++++++++
>  3 files changed, 416 insertions(+)
>  create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
> 
> diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
> index 33751a6a0757..c662e8b1b351 100644
> --- a/drivers/pinctrl/sunxi/Kconfig
> +++ b/drivers/pinctrl/sunxi/Kconfig
> @@ -129,4 +129,9 @@ config PINCTRL_SUN50I_H616_R
>  	default ARM64 && ARCH_SUNXI
>  	select PINCTRL_SUNXI
>  
> +config PINCTRL_SUN50I_R329
> +	bool "Support for the Allwinner R329 PIO"
> +	default ARM64 && ARCH_SUNXI
> +	select PINCTRL_SUNXI
> +
>  endif
> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
> index d3440c42b9d6..e33f7c5f1ff9 100644
> --- a/drivers/pinctrl/sunxi/Makefile
> +++ b/drivers/pinctrl/sunxi/Makefile
> @@ -25,5 +25,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6)		+= pinctrl-sun50i-h6.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H616)	+= pinctrl-sun50i-h616.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H616_R)	+= pinctrl-sun50i-h616-r.o
> +obj-$(CONFIG_PINCTRL_SUN50I_R329)	+= pinctrl-sun50i-r329.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
> new file mode 100644
> index 000000000000..742f437ec0b6
> --- /dev/null
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329.c
> @@ -0,0 +1,410 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Allwinner R329 SoC pinctrl driver.
> + *
> + * Copyright (C) 2021 Sipeed
> + * based on the H616 pinctrl driver
> + *   Copyright (C) 2020 Arm Ltd.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/pinctrl/pinctrl.h>
> +
> +#include "pinctrl-sunxi.h"
> +
> +static const struct sunxi_desc_pin r329_pins[] = {
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart2"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM0 */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS */
> +		  SUNXI_FUNCTION(0x5, "ledc"),		/* DO */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PB_EINT0 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart2"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM1 */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK */
> +		  SUNXI_FUNCTION(0x5, "i2s0"),		/* MCLK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PB_EINT1 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM2 */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO */
> +		  SUNXI_FUNCTION(0x5, "i2s0"),		/* LRCK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PB_EINT2 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM3 */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI */
> +		  SUNXI_FUNCTION(0x5, "i2s0"),		/* BCLK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PB_EINT3 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart0"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM4 */
> +		  SUNXI_FUNCTION(0x4, "i2s0_dout0"),
> +		  SUNXI_FUNCTION(0x5, "i2s0_din1"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PB_EINT4 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart0"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM5 */
> +		  SUNXI_FUNCTION(0x4, "i2s0_dout1"),
> +		  SUNXI_FUNCTION(0x5, "i2s0_din0"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PB_EINT5 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "ir"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM6 */
> +		  SUNXI_FUNCTION(0x4, "i2s0"),		/* DOUT2 */
> +		  SUNXI_FUNCTION(0x5, "i2c0"),		/* SCK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PB_EINT6 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "ir"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM7 */
> +		  SUNXI_FUNCTION(0x4, "i2s0"),		/* DOUT3 */
> +		  SUNXI_FUNCTION(0x5, "i2c0"),		/* SDA */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PB_EINT7 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "ir_tx"),
> +		  SUNXI_FUNCTION(0x3, "pwm"),		/* PWM8 */
> +		  SUNXI_FUNCTION(0x4, "ir_rx"),
> +		  SUNXI_FUNCTION(0x5, "ledc"),		/* DO */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PB_EINT8 */
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* RB0 */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* CLK */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* CS */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* RE */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* CMD */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* MISO */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* CE0 */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D2 */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* WP */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* CLE */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D1 */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* MOSI */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* ALE */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D0 */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* CLK */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* WE */
> +		  SUNXI_FUNCTION(0x3, "mmc0"),		/* D3 */
> +		  SUNXI_FUNCTION(0x4, "spi0")),		/* HOLD */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ0 */
> +		  SUNXI_FUNCTION(0x3, "mmc0")),		/* RST */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ1 */
> +		  SUNXI_FUNCTION(0x5, "boot_sel")),
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ7 */

Please be consistent between "nand" and "nand0". "nand0" looks like it is much
more common.

> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* VPPEN */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS */
> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D1 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),	/* PF_EINT0 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ6 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* VPPPP */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI */
> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D0 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),	/* PF_EINT1 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ5 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* PWREN */
> +		  SUNXI_FUNCTION(0x4, "uart"),		/* TX */

Should be "uart0".

> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* CLK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),	/* PF_EINT2 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ4 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* CLK */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO */
> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* CMD */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),	/* PF_EINT3 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQS */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* DATA */
> +		  SUNXI_FUNCTION(0x4, "uart"),		/* RX */

"uart0" here as well.

> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D3 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),	/* PF_EINT4 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ2 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* RST */
> +		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK */
> +		  SUNXI_FUNCTION(0x5, "mmc0"),		/* D2 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),	/* PF_EINT5 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ1 */
> +		  SUNXI_FUNCTION(0x3, "sim0"),		/* DET */
> +		  SUNXI_FUNCTION(0x4, "spdif_in"),
> +		  SUNXI_FUNCTION(0x5, "spdif_out"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 6)),	/* PF_EINT6 */
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_clk"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_d2"),
> +		  /* 0x4 is also mmc1_d2 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 0)),	/* PG_EINT0 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_cmd"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_d3"),
> +		  SUNXI_FUNCTION(0x4, "mmc1_clk"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)),	/* PG_EINT1 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_d0"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_cmd"),
> +		  SUNXI_FUNCTION(0x4, "mmc1_d3"),

Missing function 5 "pll".

> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 2)),	/* PG_EINT2 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_d1"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_clk"),
> +		  /* 0x4 is also mmc1_d1 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 3)),	/* PG_EINT3 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_d2"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_d0"),
> +		  /* 0x4 is also mmc1_d0 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 4)),	/* PG_EINT4 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "mmc1_d3"),
> +		  SUNXI_FUNCTION(0x3, "mmc1_d1"),
> +		  SUNXI_FUNCTION(0x4, "mmc1_cmd"),
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 5)),	/* PG_EINT5 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart1"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "i2c0"),		/* SCK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 6)),	/* PG_EINT6 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart1"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "i2c0"),		/* SDA */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 7)),	/* PG_EINT7 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart1"),		/* RTS */
> +		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SCK */
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* HOLD/DBI-DCX/DBI-WRX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 8)),	/* PG_EINT8 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart1"),		/* CTS */
> +		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SDA */
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* WP/DBI-TE */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 9)),	/* PG_EINT9 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x3, "i2s1"),		/* MCLK */
> +		  SUNXI_FUNCTION(0x3, "ledc"),		/* DO */

Should be function 4.

> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 10)),	/* PG_EINT10 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "i2s1"),		/* LRCK */
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* CS/DBI-CSX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)),	/* PG_EINT11 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "i2s1"),		/* BCLK */
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* CLK/DBI-SCLK */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 12)),	/* PG_EINT12 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
> +		  SUNXI_FUNCTION(0x3, "i2s1_dout0"),
> +		  SUNXI_FUNCTION(0x4, "i2s1_din1"),
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* MOSI/DBI-SDO */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 13)),	/* PG_EINT13 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 14),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
> +		  SUNXI_FUNCTION(0x3, "i2s1_dout1"),
> +		  SUNXI_FUNCTION(0x4, "i2s1_din0"),
> +		  SUNXI_FUNCTION(0x5, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 14)),	/* PG_EINT14 */
> +	/* Hole */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SCK */
> +		  SUNXI_FUNCTION(0x3, "uart0"),		/* TX */
> +		  SUNXI_FUNCTION(0x4, "spi1"),		/* CS/DBI-CSX */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM0 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 0)),	/* PH_EINT0 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SDA */
> +		  SUNXI_FUNCTION(0x3, "uart0"),		/* RX */
> +		  SUNXI_FUNCTION(0x4, "spi1"),		/* CLK/DBI-SCLK */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM1 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 1)),	/* PH_EINT1 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
> +		  SUNXI_FUNCTION(0x3, "ledc"),		/* DO */
> +		  SUNXI_FUNCTION(0x4, "spi1"),		/* MOSI/DBI-SDO */
> +		  SUNXI_FUNCTION(0x5, "ir"),		/* RX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 2)),	/* PH_EINT2 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
> +		  SUNXI_FUNCTION(0x3, "spdif"),		/* OUT */
> +		  SUNXI_FUNCTION(0x4, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
> +		  SUNXI_FUNCTION(0x5, "ir"),		/* TX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 3)),	/* PH_EINT3 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
> +		  SUNXI_FUNCTION(0x3, "spi1_cs"),	/* CS/DBI-CSX */
> +		  SUNXI_FUNCTION(0x4, "spi1_hold"),	/* HOLD/DBI-DCX/DBI-WRX */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM2 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 4)),	/* PH_EINT4 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
> +		  SUNXI_FUNCTION(0x3, "spi1_clk"),	/* CLK/DBI-SCLK */
> +		  SUNXI_FUNCTION(0x4, "spi1_wp"),	/* WP/DBI-TE */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM3 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 5)),	/* PH_EINT5 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
> +		  SUNXI_FUNCTION(0x3, "spi1"),		/* MOSI/SPI-DBO */
> +		  SUNXI_FUNCTION(0x4, "i2c0"),		/* SCK */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM4 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 6)),	/* PH_EINT6 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
> +		  SUNXI_FUNCTION(0x3, "spi1"),		/* MISO/DBI-SDI/DBI-TE/DBI-DCX */
> +		  SUNXI_FUNCTION(0x4, "i2c0"),		/* SDA */
> +		  SUNXI_FUNCTION(0x5, "pwm"),		/* PWM5 */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 7)),	/* PH_EINT7 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
> +		  SUNXI_FUNCTION(0x3, "spi1"),		/* WP/DBI-TE */
> +		  SUNXI_FUNCTION(0x4, "ledc"),		/* DO */
> +		  SUNXI_FUNCTION(0x5, "ir"),		/* TX */

You have PH8 and PH9 functions 2 through 5 swapped.

And I won't be surprised if I missed something too :)

Regards,
Samuel

> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)),	/* PH_EINT8 */
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
> +		  SUNXI_FUNCTION(0x3, "spi1"),		/* HOLD/DBI-DCX/DBI-WRX */
> +		  SUNXI_FUNCTION(0x4, "spdif"),		/* IN */
> +		  SUNXI_FUNCTION(0x5, "ir"),		/* RX */
> +		  SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)),	/* PH_EINT9 */
> +};
> +static const unsigned int r329_irq_bank_map[] = { 1, 5, 6, 7 };
> +
> +static const struct sunxi_pinctrl_desc r329_pinctrl_data = {
> +	.pins = r329_pins,
> +	.npins = ARRAY_SIZE(r329_pins),
> +	.irq_banks = ARRAY_SIZE(r329_irq_bank_map),
> +	.irq_bank_map = r329_irq_bank_map,
> +	.io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
> +};
> +
> +static int r329_pinctrl_probe(struct platform_device *pdev)
> +{
> +	return sunxi_pinctrl_init(pdev, &r329_pinctrl_data);
> +}
> +
> +static const struct of_device_id r329_pinctrl_match[] = {
> +	{ .compatible = "allwinner,sun50i-r329-pinctrl", },
> +	{}
> +};
> +
> +static struct platform_driver r329_pinctrl_driver = {
> +	.probe	= r329_pinctrl_probe,
> +	.driver	= {
> +		.name		= "sun50i-r329-pinctrl",
> +		.of_match_table	= r329_pinctrl_match,
> +	},
> +};
> +builtin_platform_driver(r329_pinctrl_driver);
> 



From samuel at sholland.org  Wed Aug 18 20:22:48 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed, 18 Aug 2021 22:22:48 -0500
Subject: [PATCH 08/17] pinctrl: sunxi: add support for R329 R-PIO pin
 controller
In-Reply-To: <20210802062212.73220-9-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-9-icenowy@sipeed.com>
Message-ID: <e9937a23-8a8a-ebec-0a44-0d15a06b7e89@sholland.org>

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R320 SoC has a pin controller in the CPUS power domain.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  drivers/pinctrl/sunxi/Kconfig                 |   5 +
>  drivers/pinctrl/sunxi/Makefile                |   1 +
>  drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c | 292 ++++++++++++++++++
>  3 files changed, 298 insertions(+)
>  create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
> 
> diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
> index c662e8b1b351..abd60ff8daec 100644
> --- a/drivers/pinctrl/sunxi/Kconfig
> +++ b/drivers/pinctrl/sunxi/Kconfig
> @@ -134,4 +134,9 @@ config PINCTRL_SUN50I_R329
>  	default ARM64 && ARCH_SUNXI
>  	select PINCTRL_SUNXI
>  
> +config PINCTRL_SUN50I_R329_R
> +	bool "Support for the Allwinner R329 R-PIO"
> +	default ARM64 && ARCH_SUNXI
> +	select PINCTRL_SUNXI
> +
>  endif
> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
> index e33f7c5f1ff9..245840a7959e 100644
> --- a/drivers/pinctrl/sunxi/Makefile
> +++ b/drivers/pinctrl/sunxi/Makefile
> @@ -26,5 +26,6 @@ obj-$(CONFIG_PINCTRL_SUN50I_H6_R)	+= pinctrl-sun50i-h6-r.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H616)	+= pinctrl-sun50i-h616.o
>  obj-$(CONFIG_PINCTRL_SUN50I_H616_R)	+= pinctrl-sun50i-h616-r.o
>  obj-$(CONFIG_PINCTRL_SUN50I_R329)	+= pinctrl-sun50i-r329.o
> +obj-$(CONFIG_PINCTRL_SUN50I_R329_R)	+= pinctrl-sun50i-r329-r.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80_R)	+= pinctrl-sun9i-a80-r.o
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
> new file mode 100644
> index 000000000000..dc4792c685ba
> --- /dev/null
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-r329-r.c
> @@ -0,0 +1,292 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Allwinner H616 R_PIO pin controller driver

This needs to be updated.

> + *
> + * Copyright (C) 2020 Arm Ltd.
> + * Based on former work, which is:
> + *   Copyright (C) 2017 Icenowy Zheng <icenowy at aosc.io>
> + */
> +
> +#include <linux/init.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/reset.h>
> +
> +#include "pinctrl-sunxi.h"
> +
> +static const struct sunxi_desc_pin sun50i_r329_r_pins[] = {
> +	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
> +		  SUNXI_FUNCTION(0x0, "gpio_in"),
> +		  SUNXI_FUNCTION(0x1, "gpio_out"),
> +		  SUNXI_FUNCTION(0x2, "s_i2s"),		/* LRCK */

"s_i2s0" for these would match existing drivers (and the manual).

Everything else matches the manual.

Regards,
Samuel


From dylan_hung at aspeedtech.com  Wed Aug 18 20:29:27 2021
From: dylan_hung at aspeedtech.com (Dylan Hung)
Date: Thu, 19 Aug 2021 03:29:27 +0000
Subject: [PATCH] soc: aspeed: socinfo: Add AST2625 variant
In-Reply-To: <20210818010534.2508122-1-joel@jms.id.au>
References: <20210818010534.2508122-1-joel@jms.id.au>
Message-ID: <HK0PR06MB28347997935D31D1F0799C8B9CC09@HK0PR06MB2834.apcprd06.prod.outlook.com>

> -----Original Message-----
> From: joel.stan at gmail.com [mailto:joel.stan at gmail.com] On Behalf Of Joel
> Stanley
> Sent: 2021?8?18? 9:06 AM
> To: Dylan Hung <dylan_hung at aspeedtech.com>; Andrew Jeffery
> <andrew at aj.id.au>
> Cc: linux-arm-kernel at lists.infradead.org; linux-aspeed at lists.ozlabs.org
> Subject: [PATCH] soc: aspeed: socinfo: Add AST2625 variant
> 
> Add AST26XX series AST2625-A3 SOC ID, taken from the vendor u-boot SDK:
> 
>  arch/arm/mach-aspeed/ast2600/scu_info.c
>  +       SOC_ID("AST2625-A3", 0x0503040305030403),
> 
> Signed-off-by: Joel Stanley <joel at jms.id.au>
> ---
> Dylan, can you please review this for me?
> 
>  drivers/soc/aspeed/aspeed-socinfo.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/soc/aspeed/aspeed-socinfo.c
> b/drivers/soc/aspeed/aspeed-socinfo.c
> index e3215f826d17..1ca140356a08 100644
> --- a/drivers/soc/aspeed/aspeed-socinfo.c
> +++ b/drivers/soc/aspeed/aspeed-socinfo.c
> @@ -26,6 +26,7 @@ static struct {
>  	{ "AST2600", 0x05000303 },
>  	{ "AST2620", 0x05010203 },
>  	{ "AST2605", 0x05030103 },
> +	{ "AST2625", 0x05030403 },
>  };
> 
>  static const char *siliconid_to_name(u32 siliconid)
> --
> 2.32.0

Reviewed-by: Dylan Hung <dylan_hung at aspeedtech.com>

From haibo.chen at nxp.com  Wed Aug 18 20:30:33 2021
From: haibo.chen at nxp.com (Bough Chen)
Date: Thu, 19 Aug 2021 03:30:33 +0000
Subject: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: change the pinctrl-names
 rule
In-Reply-To: <YR1SdhfM344Ii7BQ@robh.at.kernel.org>
References: <1629279984-7397-1-git-send-email-haibo.chen@nxp.com>
 <YR1SdhfM344Ii7BQ@robh.at.kernel.org>
Message-ID: <VI1PR04MB5294534C01DD24063937E79290C09@VI1PR04MB5294.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Rob Herring [mailto:robh at kernel.org]
> Sent: 2021?8?19? 2:33
> To: Bough Chen <haibo.chen at nxp.com>
> Cc: shawnguo at kernel.org; s.hauer at pengutronix.de; ulf.hansson at linaro.org;
> kernel at pengutronix.de; festevam at gmail.com; dl-linux-imx
> <linux-imx at nxp.com>; Aisheng Dong <aisheng.dong at nxp.com>;
> devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-mmc at vger.kernel.org
> Subject: Re: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: change the
> pinctrl-names rule
> 
> On Wed, Aug 18, 2021 at 05:46:24PM +0800, haibo.chen at nxp.com wrote:
> > From: Haibo Chen <haibo.chen at nxp.com>
> >
> > Change the pinctrl-names rule to cover all cases.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> > ---
> >  .../bindings/mmc/fsl-imx-esdhc.yaml           | 21 +++++++++++++------
> >  1 file changed, 15 insertions(+), 6 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > index 17086f60f8a3..d324606a4f0a 100644
> > --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> > @@ -116,12 +116,21 @@ properties:
> >        - const: per
> >
> >    pinctrl-names:
> > -    minItems: 1
> > -    items:
> > -      - const: default
> > -      - const: state_100mhz
> > -      - const: state_200mhz
> > -      - const: sleep
> > +    oneOf:
> > +      - items:
> > +          - const: default
> > +          - const: state_100mhz
> > +          - const: state_200mhz
> > +          - const: sleep
> > +      - items:
> > +          - const: default
> > +          - const: state_100mhz
> > +          - const: state_200mhz
> 
> You can drop this one and add 'minItems: 3' to the first case.

Okay, I will do that.

> 
> > +      - items:
> > +          - const: default
> > +          - const: sleep
> > +      - items:
> > +          - const: default
> 
> Similar here too with the prior case. Or use 'minItems: 1' in the first case. That
> additional allows the 2 entry case, but why isn't that valid?
> Couldn't a board only support default+state_100mhz?

Logically not, for board, if support SD3.0 mode, this means it support both SDR104/SDR50/DDR50/HS200/HS400
State_100mhz is used for SDR50 and DDR50, state_200mhz is used for SDR104/HS200/HS400.

So, if there is state_100mhz, there should be state_200mhz.

Rest Regards
Haibo Chen
> 
> Rob

From ronakj at xilinx.com  Wed Aug 18 20:57:00 2021
From: ronakj at xilinx.com (Ronak Jain)
Date: Thu, 19 Aug 2021 03:57:00 +0000
Subject: [PATCH 0/3] Add support for runtime features
In-Reply-To: <YRy/+epfpiRq2fLr@kroah.com>
References: <20210817130553.20219-1-ronak.jain@xilinx.com>
 <YRy/+epfpiRq2fLr@kroah.com>
Message-ID: <BYAPR02MB4488B0685113564403A17158A4C09@BYAPR02MB4488.namprd02.prod.outlook.com>

Hi Greg KH,

Thanks for reviewing.

I will fix footer and submit new version.

Thanks,
Ronak

> -----Original Message-----
> From: Greg KH <gregkh at linuxfoundation.org>
> Sent: Wednesday, August 18, 2021 1:38 PM
> To: Ronak Jain <ronakj at xilinx.com>
> Cc: Michal Simek <michals at xilinx.com>; linux-kernel at vger.kernel.org; Rajan
> Vaja <RAJANV at xilinx.com>; corbet at lwn.net; linux-arm-
> kernel at lists.infradead.org; arnd at arndb.de; Sai Krishna Potthuri
> <lakshmis at xilinx.com>
> Subject: Re: [PATCH 0/3] Add support for runtime features
> 
> On Tue, Aug 17, 2021 at 06:05:50AM -0700, Ronak Jain wrote:
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> 
> This footer means that this has to be ignored and can not be used for kernel
> development at all.


From vkoul at kernel.org  Wed Aug 18 21:37:20 2021
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 19 Aug 2021 10:07:20 +0530
Subject: [PATCH v3 06/10] arm64: dts: qcom: sc7280: Update reserved
 memory map
In-Reply-To: <1629344185-27368-7-git-send-email-sibis@codeaurora.org>
References: <1629344185-27368-1-git-send-email-sibis@codeaurora.org>
 <1629344185-27368-7-git-send-email-sibis@codeaurora.org>
Message-ID: <YR3gAD68xRtNJRhi@matsya>

Hi Sibi,

On 19-08-21, 09:06, Sibi Sankar wrote:

> diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> index 5e4f4f3b738a..894106efadfe 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> @@ -48,6 +48,16 @@
>  		#size-cells = <2>;
>  		ranges;
>  
> +		hyp_mem: memory at 80000000 {
> +			reg = <0x0 0x80000000 0x0 0x600000>;
> +			no-map;

This should conflict with the memory defined in this file:

        memory at 80000000 {
                device_type = "memory";
                /* We expect the bootloader to fill in the size */
                reg = <0 0x80000000 0 0>;
        };

I think this should be updated?

-- 
~Vinod


From zajec5 at gmail.com  Wed Aug 18 22:29:18 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 07:29:18 +0200
Subject: [PATCH] dt-bindings: clock: brcm,iproc-clocks: fix armpll properties
Message-ID: <20210819052918.6753-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

armpll clocks (available on Cygnus and Northstar Plus) are simple clocks
with no cells. Adjust binding props #clock-cells and clock-output-names
to handle them.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../bindings/clock/brcm,iproc-clocks.yaml     | 27 +++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml
index 1174c9aa9934..5ad147d265e6 100644
--- a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml
+++ b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml
@@ -61,13 +61,30 @@ properties:
     maxItems: 1
 
   '#clock-cells':
-    const: 1
+    true
 
   clock-output-names:
     minItems: 1
     maxItems: 45
 
 allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - brcm,cygnus-armpll
+              - brcm,nsp-armpll
+    then:
+      properties:
+        '#clock-cells':
+          const: 0
+    else:
+      properties:
+        '#clock-cells':
+          const: 1
+      required:
+        - clock-output-names
   - if:
       properties:
         compatible:
@@ -358,7 +375,6 @@ required:
   - reg
   - clocks
   - '#clock-cells'
-  - clock-output-names
 
 additionalProperties: false
 
@@ -392,3 +408,10 @@ examples:
         clocks = <&osc2>;
         clock-output-names = "keypad", "adc/touch", "pwm";
     };
+  - |
+    arm_clk at 0 {
+        #clock-cells = <0>;
+        compatible = "brcm,nsp-armpll";
+        clocks = <&osc>;
+        reg = <0x0 0x1000>;
+    };
-- 
2.26.2



From joel at jms.id.au  Wed Aug 18 22:31:53 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 19 Aug 2021 05:31:53 +0000
Subject: [GIT PULL] ARM: aspeed: soc changes for 5.15
Message-ID: <CACPK8XdyT0rCkoeE7x2EQyvFy1Z7ZwFNdm1SQfCG9yC_Z7UbxA@mail.gmail.com>

Hello Soc maintainers,

Here are some soc changes for 5.15.

The following changes since commit 2734d6c1b1a089fb593ef6a23d4b70903526fe0c:

  Linux 5.14-rc2 (2021-07-18 14:13:49 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/joel/bmc.git
tags/aspeed-5.15-soc

for you to fetch changes up to 2f9b25fa668218f22a85ebe8c55d1d132fc0019d:

  soc: aspeed: Re-enable FWH2AHB on AST2600 (2021-08-19 13:59:28 +0930)

----------------------------------------------------------------
ASPEED soc updates for 5.15

 * Two fixes for drivers that control the mapping of BMC memory over
   PCIe and LPC

 * Re-enable FWH2AHB on systems that have it closed off by default

 * A new id for the AST2625, an AST2600 variant

----------------------------------------------------------------
Iwona Winiarska (2):
      soc: aspeed: lpc-ctrl: Fix boundary check for mmap
      soc: aspeed: p2a-ctrl: Fix boundary check for mmap

Joel Stanley (2):
      soc: aspeed: socinfo: Add AST2625 variant
      soc: aspeed: Re-enable FWH2AHB on AST2600

 drivers/soc/aspeed/aspeed-lpc-ctrl.c | 31 ++++++++++++++++++++++++-------
 drivers/soc/aspeed/aspeed-p2a-ctrl.c |  2 +-
 drivers/soc/aspeed/aspeed-socinfo.c  |  1 +
 3 files changed, 26 insertions(+), 8 deletions(-)


From Yong.Wu at mediatek.com  Wed Aug 18 22:34:34 2021
From: Yong.Wu at mediatek.com (=?utf-8?B?WW9uZyBXdSAo5ZC05YuHKQ==?=)
Date: Thu, 19 Aug 2021 05:34:34 +0000
Subject: [PATCH v3 00/13] MT8195 SMI support
In-Reply-To: <1a160afd-ceeb-04a3-8213-fe781ec18e30@canonical.com>
References: <20210810080859.29511-1-yong.wu@mediatek.com>
 <1a160afd-ceeb-04a3-8213-fe781ec18e30@canonical.com>
Message-ID: <5f4c25b27f347a1ae0e2941ab3e3584730a9970a.camel@mediatek.com>

On Wed, 2021-08-18 at 22:41 +0200, Krzysztof Kozlowski wrote:
> On 10/08/2021 10:08, Yong Wu wrote:
> > This patchset mainly adds SMI support for mt8195.
> > 
> > Comparing with the previous version, add two new functions:
> > a) add smi sub common
> > b) add initial setting for smi-common and smi-larb.
> > 
> > Change note:
> > v3:1) In the dt-binding:
> >        a. Change mediatek,smi type from phandle-array to phandle
> > from Rob.
> >        b. Add a new bool property (mediatek,smi_sub_common)
> >           to indicate if this is smi-sub-common.
> >    2) Change the clock using bulk parting.
> >       keep the smi-common's has_gals flag. more strict.
> >    3) More comment about larb initial setting.
> >    4) Add a maintain patch
> 
> The patchset looks good to me but I saw now comments from Rob, so I
> expect a resend. Therefore there is also time for additional review -
> maybe continued by Ikjoon Jang?
> 
> If you sent a v4 with fixes rather soon and get ack from Rob, I could
> still try to get it into next merge window. After this weekend I
> won't
> be taking patches for this cycle and it will wait for the merge
> window
> to finish.

Hi Krzysztof,

Thanks very much for your information.

It looks the time is too short to get Rob's ack in this weekend. I will
wait for one or two weeks to see if there is other comments, then
resend.

> 
> 
> Best regards,
> Krzysztof

From tony at atomide.com  Wed Aug 18 23:34:36 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 19 Aug 2021 09:34:36 +0300
Subject: [GIT PULL] Fix for omap gpt12 timer error handling
Message-ID: <pull-1629354796-830948@atomide.com>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit 353b7a55dcaf5fb8758e09ebe2ddf5f3adbac7c5:

  Merge branch 'fixes-v5.14' into fixes (2021-07-27 11:25:08 +0300)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.14/gpt12-fix-signed

for you to fetch changes up to 06a089ef644934372a3062528244fca3417d3430:

  bus: ti-sysc: Fix error handling for sysc_check_active_timer() (2021-08-11 08:34:46 +0300)

----------------------------------------------------------------
Fix for omap gpt12 timer error handling

Two of the recent fixes for ti-sysc driver had bad interaction for a
function return value that caused one of the fixes to not work so we
need to change the return value handling. Otherwise early beagleboard
variants still have a boot issue.

----------------------------------------------------------------
Tony Lindgren (1):
      bus: ti-sysc: Fix error handling for sysc_check_active_timer()

 drivers/bus/ti-sysc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)


From tony at atomide.com  Wed Aug 18 23:36:07 2021
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 19 Aug 2021 09:36:07 +0300
Subject: [PATCH] bus: ti-sysc: Fix error handling for
 sysc_check_active_timer()
In-Reply-To: <d9ebbc7f-07f1-160f-f463-7c54ed8dd6d7@bitmer.com>
References: <20210811061053.32081-1-tony@atomide.com>
 <20210811062231.GA16241@duo.ucw.cz>
 <d9ebbc7f-07f1-160f-f463-7c54ed8dd6d7@bitmer.com>
Message-ID: <YR3710C+ROYblg5q@atomide.com>

* Jarkko Nikula <jarkko.nikula at bitmer.com> [210815 18:13]:
> I double checked but actually both plain 0aa78d17099b ("Merge tag
> 'scsi-fixes' of
> git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi") and with this
> patch boot fine on my Beagle C2.
> 
> Anyway,
> 
> Tested-by: jarkko.nikula at bitmer.com

OK thanks for testing. I had already pushed out my fixes branch so
I did not want to go back to add the Tested-by. Anyways, a pull
request for this has been sent now.

Regards,

Tony


From Jisheng.Zhang at synaptics.com  Wed Aug 18 23:37:35 2021
From: Jisheng.Zhang at synaptics.com (Jisheng Zhang)
Date: Thu, 19 Aug 2021 14:37:35 +0800
Subject: [PATCH] arm64: dts: synaptics: remove unused DTSI for AS370
In-Reply-To: <CAK8P3a0QtpBq8i2_RhW=isLSNULc2z7DbjohZReMY+rhyXEbJA@mail.gmail.com>
References: <20210806082635.20239-1-krzysztof.kozlowski@canonical.com>
 <YRbDNInfG7caSr2r@robh.at.kernel.org>
 <CAK8P3a0QtpBq8i2_RhW=isLSNULc2z7DbjohZReMY+rhyXEbJA@mail.gmail.com>
Message-ID: <20210819143735.5171af23@xhacker.debian>

On Fri, 13 Aug 2021 22:43:26 +0200 Arnd Bergmann wrote:


> 
> On Fri, Aug 13, 2021 at 9:09 PM Rob Herring <robh at kernel.org> wrote:
> >
> > On Fri, 06 Aug 2021 10:26:35 +0200, Krzysztof Kozlowski wrote:  
> > > The as370.dtsi for Synaptics AS370 SoC does not have a user (DTS board
> > > file), is uncompilable and untestable.  It was added back in 2018.  No
> > > user appeared since that time, so assume it won't be added.
> > >
> > > Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > > ---
> > >  .../devicetree/bindings/arm/syna.txt          |   4 -
> > >  arch/arm64/boot/dts/synaptics/as370.dtsi      | 173 ------------------
> > >  2 files changed, 177 deletions(-)
> > >  delete mode 100644 arch/arm64/boot/dts/synaptics/as370.dtsi
> > >  
> >
> > I assume Arnd/Olof will take this.
> >
> > Acked-by: Rob Herring <robh at kernel.org>  
> 
> Sure, I can take that, but it would be nice to hear anything from Jisheng Zhang
> about this.
> 
> I can see that the only two 64-bit Synaptics SoCs are as370 and bg4ct,
> but both of them have apparently been replaced with newer versions that
> never made it into the kernel: as371, as390, bg5ct, according to press
> releases.
> 
> Jisheng, can you clarify whether you plan to complete the as370 support
> or add the later SoCs?

Hi Arnd, Rob, Krzysztof

Sorry for being late. I was on vocation in the past several days.
As for this as370 removing, I think we'd better keep it. I planned
to submit the as370-rdk board dts two years ago, but latter I focused
on Synaptics SoCs related drivers support such as gpio, pcie, sdhci and
so on. I will send a basic as370 rdk board dts. I'm also considering
to mainline basic support for a new SoC.

Thanks


From joel at jms.id.au  Wed Aug 18 23:51:59 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 19 Aug 2021 16:21:59 +0930
Subject: [PATCH 0/4] ARM: config: aspeed: Defconfig updates
Message-ID: <20210819065203.2620911-1-joel@jms.id.au>

Here are some defconfig updates that we've been using in the openbmc
distro kernel tree for a while now.

Joel Stanley (4):
  ARM: config: aspeed: Enable hardened allocator feature
  ARM: config: aspeed: Enable KCS adapter for raw SerIO
  ARM: config: aspeed_g4: Enable EDAC and SPGIO
  ARM: config: aspeed: Regenerate defconfigs

 arch/arm/configs/aspeed_g4_defconfig | 16 +++++-----------
 arch/arm/configs/aspeed_g5_defconfig | 25 +++++++++----------------
 2 files changed, 14 insertions(+), 27 deletions(-)

-- 
2.32.0



From joel at jms.id.au  Wed Aug 18 23:52:00 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 19 Aug 2021 16:22:00 +0930
Subject: [PATCH 1/4] ARM: config: aspeed: Enable hardened allocator feature
In-Reply-To: <20210819065203.2620911-1-joel@jms.id.au>
References: <20210819065203.2620911-1-joel@jms.id.au>
Message-ID: <20210819065203.2620911-2-joel@jms.id.au>

SLAB_FREELIST_HARDENED can protect from freelist overwrite attacks with
really small overhead.

It works best with the SLUB allocator, so make SLUB the default by
removing SLAB=y.

      total   used           free           shared        buff/cache    available
SLAB  425596  44065.3+/-220  311099+/-3800  14864+/-3900  70432+/-3700  352767+/-3900

SLUB  425592  44225.3+/-280  313275+/-600   12132+/-3.3   68092+/-530   355295+/-280

These figures are the average memory usage from three boots of each
option in qemu, running the Romulus userspace. The output is from
free(1), reported in kilobytes.

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
 arch/arm/configs/aspeed_g4_defconfig | 2 +-
 arch/arm/configs/aspeed_g5_defconfig | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig
index a3ee647b1ebb..397c57e94743 100644
--- a/arch/arm/configs/aspeed_g4_defconfig
+++ b/arch/arm/configs/aspeed_g4_defconfig
@@ -18,8 +18,8 @@ CONFIG_BPF_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
 CONFIG_SLAB_FREELIST_RANDOM=y
+CONFIG_SLAB_FREELIST_HARDENED=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G4=y
diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig
index 2db48438c5d2..3f81146a9c0e 100644
--- a/arch/arm/configs/aspeed_g5_defconfig
+++ b/arch/arm/configs/aspeed_g5_defconfig
@@ -18,8 +18,8 @@ CONFIG_BPF_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
 CONFIG_SLAB_FREELIST_RANDOM=y
+CONFIG_SLAB_FREELIST_HARDENED=y
 CONFIG_ARCH_MULTI_V6=y
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G5=y
-- 
2.32.0



From joel at jms.id.au  Wed Aug 18 23:52:01 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 19 Aug 2021 16:22:01 +0930
Subject: [PATCH 2/4] ARM: config: aspeed: Enable KCS adapter for raw SerIO
In-Reply-To: <20210819065203.2620911-1-joel@jms.id.au>
References: <20210819065203.2620911-1-joel@jms.id.au>
Message-ID: <20210819065203.2620911-3-joel@jms.id.au>

Raw SerIO is used by the OpenBMC debug-trigger application to take
signals from the host that applications are unresponsive on the BMC.

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
 arch/arm/configs/aspeed_g5_defconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig
index 3f81146a9c0e..6ba30b212bda 100644
--- a/arch/arm/configs/aspeed_g5_defconfig
+++ b/arch/arm/configs/aspeed_g5_defconfig
@@ -130,7 +130,7 @@ CONFIG_KEYBOARD_GPIO_POLLED=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_IBM_PANEL=y
-# CONFIG_SERIO is not set
+CONFIG_SERIO_RAW=y
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
@@ -144,6 +144,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_ASPEED_KCS_IPMI_BMC=y
+CONFIG_IPMI_KCS_BMC_SERIO=y
 CONFIG_ASPEED_BT_IPMI_BMC=y
 CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
-- 
2.32.0



From joel at jms.id.au  Wed Aug 18 23:52:02 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 19 Aug 2021 16:22:02 +0930
Subject: [PATCH 3/4] ARM: config: aspeed_g4: Enable EDAC and SPGIO
In-Reply-To: <20210819065203.2620911-1-joel@jms.id.au>
References: <20210819065203.2620911-1-joel@jms.id.au>
Message-ID: <20210819065203.2620911-4-joel@jms.id.au>

These two devices are part of the AST2400 and the drivers have support
for that version of the soc.

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
 arch/arm/configs/aspeed_g4_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig
index 397c57e94743..a578865c2d96 100644
--- a/arch/arm/configs/aspeed_g4_defconfig
+++ b/arch/arm/configs/aspeed_g4_defconfig
@@ -141,6 +141,7 @@ CONFIG_SPI=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_ASPEED=y
+CONFIG_GPIO_ASPEED_SGPIO=y
 CONFIG_W1=y
 CONFIG_W1_MASTER_GPIO=y
 CONFIG_W1_SLAVE_THERM=y
@@ -205,6 +206,7 @@ CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_EDAC=y
+CONFIG_EDAC_ASPEED=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_RTC_DRV_PCF8523=y
-- 
2.32.0



From joel at jms.id.au  Wed Aug 18 23:52:03 2021
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 19 Aug 2021 16:22:03 +0930
Subject: [PATCH 4/4] ARM: config: aspeed: Regenerate defconfigs
In-Reply-To: <20210819065203.2620911-1-joel@jms.id.au>
References: <20210819065203.2620911-1-joel@jms.id.au>
Message-ID: <20210819065203.2620911-5-joel@jms.id.au>

A make defconfig && make savedefconfig was performed for each
configuration.

Most changes are due to options moving around, except for the following
which are due to changing defaults:

 - SECCOMP is enabled by default as of commit 282a181b1a0d ("seccomp:
   Move config option SECCOMP to arch/Kconfig") in v5.9

 - The soc drivers ASPEED_LPC_CTRL, ASPEED_LPC_SNOOP and ASPEED_P2A_CTRL
   are enabled by default when the aspeed platform is enabled, as of
   commit 592693a1f881 ("soc: aspeed: Improve kconfig") in v5.9

 - The ZBOOT_ROM_TEXT/BSS values fall out of the defconfig as of
   commit 39c3e304567a ("ARM: 8984/1: Kconfig: set default
   ZBOOT_ROM_TEXT/BSS value to 0x0") in v5.8

- I2C_MUX is selected by MEDIA_SUBDRV_AUTOSELECT, probably as of about
  v5.8. It was in the config as it is required bt the PCA I2C muxes that
  enabled it

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
 arch/arm/configs/aspeed_g4_defconfig | 12 ++----------
 arch/arm/configs/aspeed_g5_defconfig | 20 ++++++--------------
 2 files changed, 8 insertions(+), 24 deletions(-)

diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig
index a578865c2d96..acaafa351d08 100644
--- a/arch/arm/configs/aspeed_g4_defconfig
+++ b/arch/arm/configs/aspeed_g4_defconfig
@@ -3,6 +3,7 @@ CONFIG_KERNEL_XZ=y
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -14,7 +15,6 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSFS_SYSCALL is not set
 # CONFIG_AIO is not set
-CONFIG_BPF_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
@@ -26,10 +26,7 @@ CONFIG_MACH_ASPEED_G4=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_AEABI=y
 CONFIG_UACCESS_WITH_MEMCPY=y
-CONFIG_SECCOMP=y
 # CONFIG_ATAGS is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_KEXEC=y
@@ -76,7 +73,6 @@ CONFIG_NETCONSOLE=y
 # CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_VENDOR_AURORA is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_CADENCE is not set
 # CONFIG_NET_VENDOR_CAVIUM is not set
@@ -132,7 +128,6 @@ CONFIG_ASPEED_BT_IPMI_BMC=y
 CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA9541=y
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_ASPEED=y
@@ -214,9 +209,6 @@ CONFIG_RTC_DRV_RV8803=y
 CONFIG_RTC_DRV_ASPEED=y
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
-CONFIG_ASPEED_LPC_CTRL=y
-CONFIG_ASPEED_LPC_SNOOP=y
-CONFIG_ASPEED_P2A_CTRL=y
 CONFIG_IIO=y
 CONFIG_ASPEED_ADC=y
 CONFIG_MAX1363=y
@@ -257,6 +249,7 @@ CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_GDB_SCRIPTS=y
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_WX=y
 CONFIG_SCHED_STACK_END_CHECK=y
 CONFIG_PANIC_ON_OOPS=y
 CONFIG_PANIC_TIMEOUT=-1
@@ -265,6 +258,5 @@ CONFIG_SOFTLOCKUP_DETECTOR=y
 CONFIG_WQ_WATCHDOG=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_FUNCTION_TRACER=y
-CONFIG_DEBUG_WX=y
 CONFIG_DEBUG_USER=y
 # CONFIG_RUNTIME_TESTING_MENU is not set
diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig
index 6ba30b212bda..480dbbb4ff91 100644
--- a/arch/arm/configs/aspeed_g5_defconfig
+++ b/arch/arm/configs/aspeed_g5_defconfig
@@ -3,6 +3,7 @@ CONFIG_KERNEL_XZ=y
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
@@ -14,7 +15,6 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSFS_SYSCALL is not set
 # CONFIG_AIO is not set
-CONFIG_BPF_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
@@ -31,10 +31,7 @@ CONFIG_VMSPLIT_2G=y
 CONFIG_NR_CPUS=2
 CONFIG_HIGHMEM=y
 CONFIG_UACCESS_WITH_MEMCPY=y
-CONFIG_SECCOMP=y
 # CONFIG_ATAGS is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_KEXEC=y
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -89,7 +86,6 @@ CONFIG_NETCONSOLE=y
 # CONFIG_NET_VENDOR_AMAZON is not set
 # CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_VENDOR_AURORA is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_CADENCE is not set
 # CONFIG_NET_VENDOR_CAVIUM is not set
@@ -149,7 +145,6 @@ CONFIG_ASPEED_BT_IPMI_BMC=y
 CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_GPIO=y
 CONFIG_I2C_MUX_PCA9541=y
 CONFIG_I2C_MUX_PCA954x=y
@@ -232,9 +227,6 @@ CONFIG_RTC_DRV_RV8803=y
 CONFIG_RTC_DRV_ASPEED=y
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
-CONFIG_ASPEED_LPC_CTRL=y
-CONFIG_ASPEED_LPC_SNOOP=y
-CONFIG_ASPEED_P2A_CTRL=y
 CONFIG_IIO=y
 CONFIG_ASPEED_ADC=y
 CONFIG_MAX1363=y
@@ -279,14 +271,14 @@ CONFIG_DEBUG_INFO_DWARF4=y
 CONFIG_GDB_SCRIPTS=y
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_WX=y
+CONFIG_SCHED_STACK_END_CHECK=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_PANIC_TIMEOUT=-1
 CONFIG_SOFTLOCKUP_DETECTOR=y
 # CONFIG_DETECT_HUNG_TASK is not set
 CONFIG_WQ_WATCHDOG=y
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_PANIC_TIMEOUT=-1
 # CONFIG_SCHED_DEBUG is not set
-CONFIG_SCHED_STACK_END_CHECK=y
 CONFIG_FUNCTION_TRACER=y
-# CONFIG_RUNTIME_TESTING_MENU is not set
-CONFIG_DEBUG_WX=y
 CONFIG_DEBUG_USER=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
-- 
2.32.0



From zajec5 at gmail.com  Wed Aug 18 23:57:01 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 08:57:01 +0200
Subject: [PATCH 2/3] ARM: dts: BCM5301X: Fix MDIO mux binding
In-Reply-To: <20210819065702.15406-1-zajec5@gmail.com>
References: <20210819065702.15406-1-zajec5@gmail.com>
Message-ID: <20210819065702.15406-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This fixes following error for all BCM5301X dts files:
mdio-bus-mux at 18003000: compatible: ['mdio-mux-mmioreg'] is too short

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm/boot/dts/bcm5301x.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi
index f9d3a53065ef..d4f355015e3c 100644
--- a/arch/arm/boot/dts/bcm5301x.dtsi
+++ b/arch/arm/boot/dts/bcm5301x.dtsi
@@ -370,7 +370,7 @@ mdio: mdio at 18003000 {
 	};
 
 	mdio-mux at 18003000 {
-		compatible = "mdio-mux-mmioreg";
+		compatible = "mdio-mux-mmioreg", "mdio-mux";
 		mdio-parent-bus = <&mdio>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-- 
2.26.2



From zajec5 at gmail.com  Wed Aug 18 23:57:00 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 08:57:00 +0200
Subject: [PATCH 1/3] ARM: dts: BCM5301X: Fix nodes names
Message-ID: <20210819065702.15406-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This fixes following errors for all BCM5301X dts files:
chipcommonA at 18000000: $nodename:0: 'chipcommonA at 18000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
mpcore at 19000000: $nodename:0: 'mpcore at 19000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
mdio-bus-mux at 18003000: $nodename:0: 'mdio-bus-mux at 18003000' does not match '^mdio-mux[\\-@]?'
dmu at 1800c000: $nodename:0: 'dmu at 1800c000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm/boot/dts/bcm47094-linksys-panamera.dts | 2 +-
 arch/arm/boot/dts/bcm5301x.dtsi                 | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
index 05d4f2931772..9bef6b9bfa8d 100644
--- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
@@ -129,7 +129,7 @@ bluebar8 {
 		};
 	};
 
-	mdio-bus-mux at 18003000 {
+	mdio-mux at 18003000 {
 
 		/* BIT(9) = 1 => external mdio */
 		mdio at 200 {
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi
index f92089290ccd..f9d3a53065ef 100644
--- a/arch/arm/boot/dts/bcm5301x.dtsi
+++ b/arch/arm/boot/dts/bcm5301x.dtsi
@@ -19,7 +19,7 @@ / {
 	#size-cells = <1>;
 	interrupt-parent = <&gic>;
 
-	chipcommonA at 18000000 {
+	chipcommon-a-bus at 18000000 {
 		compatible = "simple-bus";
 		ranges = <0x00000000 0x18000000 0x00001000>;
 		#address-cells = <1>;
@@ -44,7 +44,7 @@ uart1: serial at 400 {
 		};
 	};
 
-	mpcore at 19000000 {
+	mpcore-bus at 19000000 {
 		compatible = "simple-bus";
 		ranges = <0x00000000 0x19000000 0x00023000>;
 		#address-cells = <1>;
@@ -369,7 +369,7 @@ mdio: mdio at 18003000 {
 		#address-cells = <1>;
 	};
 
-	mdio-bus-mux at 18003000 {
+	mdio-mux at 18003000 {
 		compatible = "mdio-mux-mmioreg";
 		mdio-parent-bus = <&mdio>;
 		#address-cells = <1>;
@@ -415,7 +415,7 @@ i2c0: i2c at 18009000 {
 		status = "disabled";
 	};
 
-	dmu at 1800c000 {
+	dmu-bus at 1800c000 {
 		compatible = "simple-bus";
 		ranges = <0 0x1800c000 0x1000>;
 		#address-cells = <1>;
-- 
2.26.2



From zajec5 at gmail.com  Wed Aug 18 23:57:02 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 08:57:02 +0200
Subject: [PATCH 3/3] ARM: dts: BCM5301X: Fix memory nodes names
In-Reply-To: <20210819065702.15406-1-zajec5@gmail.com>
References: <20210819065702.15406-1-zajec5@gmail.com>
Message-ID: <20210819065702.15406-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Thix fixes:
arch/arm/boot/dts/bcm4708-netgear-r6250.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 402653184]]}
arch/arm/boot/dts/bcm4709-linksys-ea9200.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
arch/arm/boot/dts/bcm4709-netgear-r7000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
arch/arm/boot/dts/bcm4709-netgear-r8000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]}
arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 402653184]]}
arch/arm/boot/dts/bcm53016-meraki-mr32.dt.yaml: /: memory: False schema does not allow {'reg': [[0, 134217728]], 'device_type': ['memory']}
arch/arm/boot/dts/bcm94708.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]}
arch/arm/boot/dts/bcm94709.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]}

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm/boot/dts/bcm4708-netgear-r6250.dts       | 2 +-
 arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts       | 2 +-
 arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 2 +-
 arch/arm/boot/dts/bcm4709-linksys-ea9200.dts      | 2 +-
 arch/arm/boot/dts/bcm4709-netgear-r7000.dts       | 2 +-
 arch/arm/boot/dts/bcm4709-netgear-r8000.dts       | 2 +-
 arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts | 2 +-
 arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts     | 2 +-
 arch/arm/boot/dts/bcm53016-meraki-mr32.dts        | 2 +-
 arch/arm/boot/dts/bcm94708.dts                    | 2 +-
 arch/arm/boot/dts/bcm94709.dts                    | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
index 61c7b137607e..7900aac4f35a 100644
--- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
@@ -20,7 +20,7 @@ chosen {
 		bootargs = "console=ttyS0,115200 earlycon";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>,
 		      <0x88000000 0x08000000>;
diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
index 6c6bb7b17d27..7546c8d07bcd 100644
--- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
@@ -19,7 +19,7 @@ chosen {
 		bootargs = "console=ttyS0,115200";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>,
 		      <0x88000000 0x08000000>;
diff --git a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
index d29e7f80ea6a..beae9eab9cb8 100644
--- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
@@ -19,7 +19,7 @@ chosen {
 		bootargs = "console=ttyS0,115200";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>,
 		      <0x88000000 0x18000000>;
diff --git a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
index 9b6887d477d8..7879f7d7d9c3 100644
--- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
@@ -16,7 +16,7 @@ chosen {
 		bootargs = "console=ttyS0,115200";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>,
 		      <0x88000000 0x08000000>;
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
index 7989a53597d4..56d309dbc6b0 100644
--- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
@@ -19,7 +19,7 @@ chosen {
 		bootargs = "console=ttyS0,115200";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>,
 		      <0x88000000 0x08000000>;
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
index 87b655be674c..184e3039aa86 100644
--- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
@@ -30,7 +30,7 @@ chosen {
 		bootargs = "console=ttyS0,115200";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>,
 		      <0x88000000 0x08000000>;
diff --git a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
index f806be5da723..c2a266a439d0 100644
--- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
@@ -15,7 +15,7 @@ chosen {
 		bootargs = "console=ttyS0,115200 earlycon";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>;
 	};
diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
index 452b8d0ab180..b0d8a688141d 100644
--- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
@@ -16,7 +16,7 @@ chosen {
 		bootargs = "earlycon";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>,
 		      <0x88000000 0x18000000>;
diff --git a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
index 3b978dc8997a..612d61852bfb 100644
--- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
@@ -20,7 +20,7 @@ chosen {
 		bootargs = " console=ttyS0,115200n8 earlycon";
 	};
 
-	memory {
+	memory at 0 {
 		reg = <0x00000000 0x08000000>;
 		device_type = "memory";
 	};
diff --git a/arch/arm/boot/dts/bcm94708.dts b/arch/arm/boot/dts/bcm94708.dts
index 3d13e46c6949..d9eb2040b963 100644
--- a/arch/arm/boot/dts/bcm94708.dts
+++ b/arch/arm/boot/dts/bcm94708.dts
@@ -38,7 +38,7 @@ / {
 	model = "NorthStar SVK (BCM94708)";
 	compatible = "brcm,bcm94708", "brcm,bcm4708";
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>;
 	};
diff --git a/arch/arm/boot/dts/bcm94709.dts b/arch/arm/boot/dts/bcm94709.dts
index 5017b7b259cb..618c812eef73 100644
--- a/arch/arm/boot/dts/bcm94709.dts
+++ b/arch/arm/boot/dts/bcm94709.dts
@@ -38,7 +38,7 @@ / {
 	model = "NorthStar SVK (BCM94709)";
 	compatible = "brcm,bcm94709", "brcm,bcm4709", "brcm,bcm4708";
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x08000000>;
 	};
-- 
2.26.2



From andrew at aj.id.au  Wed Aug 18 23:58:32 2021
From: andrew at aj.id.au (Andrew Jeffery)
Date: Thu, 19 Aug 2021 16:28:32 +0930
Subject: [PATCH 0/4] ARM: config: aspeed: Defconfig updates
In-Reply-To: <20210819065203.2620911-1-joel@jms.id.au>
References: <20210819065203.2620911-1-joel@jms.id.au>
Message-ID: <fb7380ff-55ed-41aa-a446-28f7235b4d9f@www.fastmail.com>



On Thu, 19 Aug 2021, at 16:21, Joel Stanley wrote:
> Here are some defconfig updates that we've been using in the openbmc
> distro kernel tree for a while now.
> 
> Joel Stanley (4):
>   ARM: config: aspeed: Enable hardened allocator feature
>   ARM: config: aspeed: Enable KCS adapter for raw SerIO
>   ARM: config: aspeed_g4: Enable EDAC and SPGIO
>   ARM: config: aspeed: Regenerate defconfigs
> 
>  arch/arm/configs/aspeed_g4_defconfig | 16 +++++-----------
>  arch/arm/configs/aspeed_g5_defconfig | 25 +++++++++----------------
>  2 files changed, 14 insertions(+), 27 deletions(-)

For the series:

Reviewed-by: Andrew Jeffery <andrew at aj.id.au>


From moudy.ho at mediatek.com  Thu Aug 19 00:09:51 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Thu, 19 Aug 2021 15:09:51 +0800
Subject: [PATCH v6 2/5] soc: mediatek: mutex: add support for MDP
In-Reply-To: <20210819070954.16679-1-moudy.ho@mediatek.com>
References: <20210819070954.16679-1-moudy.ho@mediatek.com>
Message-ID: <20210819070954.16679-3-moudy.ho@mediatek.com>

Add functions to support MDP:
  1. Get mutex function
  2. Enable/disable mutex
  3. Enable MDP's modules
  4. Write register via CMDQ

Add MDP related settings for 8183 SoC
  1. Register settings

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c       | 106 +++++++++++++++++++++++--
 include/linux/soc/mediatek/mtk-mutex.h |   8 ++
 2 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2e4bcc300576..935f2849a094 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -7,9 +7,11 @@
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
 
 #define MT2701_MUTEX0_MOD0			0x2c
@@ -107,6 +109,10 @@
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
 
+#define MT8183_MUTEX_MDP_START			5
+#define MT8183_MUTEX_MDP_MOD_MASK		0x07FFFFFF
+#define MT8183_MUTEX_MDP_SOF_MASK		0x00000007
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -123,11 +129,14 @@ enum mtk_mutex_sof_id {
 };
 
 struct mtk_mutex_data {
-	const unsigned int *mutex_mod;
-	const unsigned int *mutex_sof;
-	const unsigned int mutex_mod_reg;
-	const unsigned int mutex_sof_reg;
-	const bool no_clk;
+	const unsigned int	*mutex_mod;
+	const unsigned int	*mutex_sof;
+	const unsigned int	mutex_mod_reg;
+	const unsigned int	mutex_sof_reg;
+	const unsigned int	*mutex_mdp_offset;
+	const unsigned int	mutex_mdp_mod_mask;
+	const unsigned int	mutex_mdp_sof_mask;
+	const bool		no_clk;
 };
 
 struct mtk_mutex_ctx {
@@ -136,6 +145,8 @@ struct mtk_mutex_ctx {
 	void __iomem			*regs;
 	struct mtk_mutex		mutex[10];
 	const struct mtk_mutex_data	*data;
+	phys_addr_t			addr;
+	u8				subsys_id;
 };
 
 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
@@ -238,6 +249,14 @@ static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
 };
 
+/* indicate which mutex is used by each pipepline */
+static const unsigned int mt8183_mutex_mdp_offset[MDP_PIPE_MAX] = {
+	[MDP_PIPE_IMGI] = MT8183_MUTEX_MDP_START,
+	[MDP_PIPE_RDMA0] = MT8183_MUTEX_MDP_START + 1,
+	[MDP_PIPE_WPEI] = MT8183_MUTEX_MDP_START + 2,
+	[MDP_PIPE_WPEI2] = MT8183_MUTEX_MDP_START + 3
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -272,6 +291,9 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.mutex_sof = mt8183_mutex_sof,
 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
+	.mutex_mdp_offset = mt8183_mutex_mdp_offset,
+	.mutex_mdp_mod_mask = MT8183_MUTEX_MDP_MOD_MASK,
+	.mutex_mdp_sof_mask = MT8183_MUTEX_MDP_SOF_MASK,
 	.no_clk = true,
 };
 
@@ -290,6 +312,21 @@ struct mtk_mutex *mtk_mutex_get(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_get);
 
+struct mtk_mutex *mtk_mutex_mdp_get(struct device *dev,
+				    enum mtk_mdp_pipe_id id)
+{
+	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
+	int i = mtx->data->mutex_mdp_offset[id];
+
+	if (!mtx->mutex[i].claimed) {
+		mtx->mutex[i].claimed = true;
+		return &mtx->mutex[i];
+	}
+
+	return ERR_PTR(-EBUSY);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_mdp_get);
+
 void mtk_mutex_put(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -369,6 +406,25 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_add_comp);
 
+void mtk_mutex_add_mdp_mod(struct mtk_mutex *mutex, u32 mod,
+			   struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+	unsigned int offset;
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, mutex->id);
+	cmdq_pkt_write_mask(cmd->pkt, mtx->subsys_id, mtx->addr + offset,
+			    mod, mtx->data->mutex_mdp_mod_mask);
+
+	offset = DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id);
+	cmdq_pkt_write_mask(cmd->pkt, mtx->subsys_id, mtx->addr + offset,
+			    0, mtx->data->mutex_mdp_sof_mask);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_add_mdp_mod);
+
 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 			   enum mtk_ddp_comp_id id)
 {
@@ -420,6 +476,20 @@ void mtk_mutex_enable(struct mtk_mutex *mutex)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_enable);
 
+void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex,
+			      struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	cmdq_pkt_write_mask(cmd->pkt, mtx->subsys_id,
+			    mtx->addr + DISP_REG_MUTEX_EN(mutex->id),
+			    0x1, 0x00000001);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq);
+
 void mtk_mutex_disable(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -431,6 +501,20 @@ void mtk_mutex_disable(struct mtk_mutex *mutex)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_disable);
 
+void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex,
+			       struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	cmdq_pkt_write_mask(cmd->pkt, mtx->subsys_id,
+			    mtx->addr + DISP_REG_MUTEX_EN(mutex->id),
+			    0x0, 0x00000001);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_disable_by_cmdq);
+
 void mtk_mutex_acquire(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -458,7 +542,8 @@ static int mtk_mutex_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_mutex_ctx *mtx;
-	struct resource *regs;
+	struct cmdq_client_reg cmdq_reg;
+	struct resource *regs, addr;
 	int i;
 
 	mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL);
@@ -479,6 +564,15 @@ static int mtk_mutex_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (of_address_to_resource(dev->of_node, 0, &addr) < 0)
+		mtx->addr = 0L;
+	else
+		mtx->addr = addr.start;
+
+	if (cmdq_dev_get_client_reg(dev, &cmdq_reg, 0) != 0)
+		dev_info(dev, "cmdq subsys id has not been set\n");
+	mtx->subsys_id = cmdq_reg.subsys;
+
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mtx->regs = devm_ioremap_resource(dev, regs);
 	if (IS_ERR(mtx->regs)) {
diff --git a/include/linux/soc/mediatek/mtk-mutex.h b/include/linux/soc/mediatek/mtk-mutex.h
index 6fe4ffbde290..d08b98419dd9 100644
--- a/include/linux/soc/mediatek/mtk-mutex.h
+++ b/include/linux/soc/mediatek/mtk-mutex.h
@@ -11,11 +11,19 @@ struct device;
 struct mtk_mutex;
 
 struct mtk_mutex *mtk_mutex_get(struct device *dev);
+struct mtk_mutex *mtk_mutex_mdp_get(struct device *dev,
+				    enum mtk_mdp_pipe_id id);
 int mtk_mutex_prepare(struct mtk_mutex *mutex);
 void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 			enum mtk_ddp_comp_id id);
+void mtk_mutex_add_mdp_mod(struct mtk_mutex *mutex, u32 mod,
+			   struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_enable(struct mtk_mutex *mutex);
+void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex,
+			      struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_disable(struct mtk_mutex *mutex);
+void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex,
+			       struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 			   enum mtk_ddp_comp_id id);
 void mtk_mutex_unprepare(struct mtk_mutex *mutex);
-- 
2.18.0

From moudy.ho at mediatek.com  Thu Aug 19 00:09:53 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Thu, 19 Aug 2021 15:09:53 +0800
Subject: [PATCH v6 4/5] dts: arm64: mt8183: Add Mediatek MDP3 nodes
In-Reply-To: <20210819070954.16679-1-moudy.ho@mediatek.com>
References: <20210819070954.16679-1-moudy.ho@mediatek.com>
Message-ID: <20210819070954.16679-5-moudy.ho@mediatek.com>

Add device nodes for Media Data Path 3 (MDP3) modules.

Signed-off-by: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
Signed-off-by: daoyuan huang <daoyuan.huang at mediatek.com>
Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 110 +++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index f90df6439c08..7cb1fcfeefb6 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1232,6 +1232,108 @@
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
 		};
 
+		mdp3_rdma0: mdp3_rdma0 at 14001000 {
+			compatible = "mediatek,mt8183-mdp3",
+				     "mediatek,mt8183-mdp3-rdma";
+			mediatek,scp = <&scp>;
+			mediatek,mdp3-id = <0>;
+			mdp3-comps = "mediatek,mt8183-mdp3-dl1", "mediatek,mt8183-mdp3-dl2",
+				     "mediatek,mt8183-mdp3-path1", "mediatek,mt8183-mdp3-path2",
+				     "mediatek,mt8183-mdp3-imgi", "mediatek,mt8183-mdp3-exto";
+			mdp3-comp-ids = <0 1 0 1 0 1>;
+			reg = <0 0x14001000 0 0x1000>,
+			      <0 0x14000000 0 0x1000>,
+			      <0 0x14005000 0 0x1000>,
+			      <0 0x14006000 0 0x1000>,
+			      <0 0x15020000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
+						  <&gce SUBSYS_1502XXXX 0 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_RDMA0>,
+				 <&mmsys CLK_MM_MDP_RSZ1>,
+				 <&mmsys CLK_MM_MDP_DL_TXCK>,
+				 <&mmsys CLK_MM_MDP_DL_RX>,
+				 <&mmsys CLK_MM_IPU_DL_TXCK>,
+				 <&mmsys CLK_MM_IPU_DL_RX>;
+			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
+			mediatek,mmsys = <&mmsys>;
+			mediatek,mm-mutex = <&mutex>;
+			mediatek,mailbox-gce = <&gce>;
+			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
+				 <&gce 21 CMDQ_THR_PRIO_LOWEST 0>,
+				 <&gce 22 CMDQ_THR_PRIO_LOWEST 0>,
+				 <&gce 23 CMDQ_THR_PRIO_LOWEST 0>;
+			gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
+				     <&gce 0x14010000 SUBSYS_1401XXXX>,
+				     <&gce 0x14020000 SUBSYS_1402XXXX>,
+				     <&gce 0x15020000 SUBSYS_1502XXXX>;
+			mediatek,gce-events = <CMDQ_EVENT_MDP_RDMA0_SOF>,
+					      <CMDQ_EVENT_MDP_RDMA0_EOF>,
+					      <CMDQ_EVENT_MDP_RSZ0_SOF>,
+					      <CMDQ_EVENT_MDP_RSZ1_SOF>,
+					      <CMDQ_EVENT_MDP_TDSHP_SOF>,
+					      <CMDQ_EVENT_MDP_WROT0_SOF>,
+					      <CMDQ_EVENT_MDP_WROT0_EOF>,
+					      <CMDQ_EVENT_MDP_WDMA0_SOF>,
+					      <CMDQ_EVENT_MDP_WDMA0_EOF>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_0>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_1>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_2>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_3>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_4>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_5>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_6>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_7>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_8>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_9>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_10>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_11>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_12>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_13>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_14>,
+					      <CMDQ_EVENT_WPE_A_DONE>,
+					      <CMDQ_EVENT_SPE_B_DONE>;
+		};
+
+		mdp3_rsz0: mdp3_rsz0 at 14003000 {
+			compatible = "mediatek,mt8183-mdp3-rsz";
+			mediatek,mdp3-id = <0>;
+			reg = <0 0x14003000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_RSZ0>;
+		};
+
+		mdp3_rsz1: mdp3_rsz1 at 14004000 {
+			compatible = "mediatek,mt8183-mdp3-rsz";
+			mediatek,mdp3-id = <1>;
+			reg = <0 0x14004000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_RSZ1>;
+		};
+
+		mdp3_wrot0: mdp3_wrot0 at 14005000 {
+			compatible = "mediatek,mt8183-mdp3-wrot";
+			mediatek,mdp3-id = <0>;
+			reg = <0 0x14005000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_WROT0>;
+			iommus = <&iommu M4U_PORT_MDP_WROT0>;
+		};
+
+		mdp3_wdma: mdp3_wdma at 14006000 {
+			compatible = "mediatek,mt8183-mdp3-wdma";
+			mediatek,mdp3-id = <0>;
+			reg = <0 0x14006000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_WDMA0>;
+			iommus = <&iommu M4U_PORT_MDP_WDMA0>;
+		};
+
 		ovl0: ovl at 14008000 {
 			compatible = "mediatek,mt8183-disp-ovl";
 			reg = <0 0x14008000 0 0x1000>;
@@ -1378,6 +1480,14 @@
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 		};
 
+		mdp3_ccorr: mdp3_ccorr at 1401c000 {
+			compatible = "mediatek,mt8183-mdp3-ccorr";
+			mediatek,mdp3-id = <0>;
+			reg = <0 0x1401c000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_CCORR>;
+		};
+
 		imgsys: syscon at 15020000 {
 			compatible = "mediatek,mt8183-imgsys", "syscon";
 			reg = <0 0x15020000 0 0x1000>;
-- 
2.18.0

From moudy.ho at mediatek.com  Thu Aug 19 00:09:49 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Thu, 19 Aug 2021 15:09:49 +0800
Subject: [PATCH v6 0/5] media: mediatek: support mdp3 on mt8183 platform
Message-ID: <20210819070954.16679-1-moudy.ho@mediatek.com>

Changes since v5:
- Rebase on v5.14-rc6.
- Move MMSYS/Mutex settings to corresponding driver.
- Revise the software license description and copyright.
- Remove unnecessary enum. or definitions.
- Optimize platform/chip definition conditions.
- Use general printing functions instead of MDP3 private ones.
- Fix compile warning.

Changes since v4:
- Rebase on v5.13-rc1.
- Remove the CMDQ flush flow to match the CMDQ API change.
- Integrate four of MDP's direct-link subcomponents into MDP controller node
  from syscon node to avoid illegal clock usage.
- Rewrite dt-binding in a JSON compatible subset of YAML
- Fix a bit of macro argument precedence.

Changes since v3:
- Rebase on v5.9-rc1.
- modify code for review comment from Rob Herring, cancel multiple nodes using
  same register base situation.
- control IOMMU port through pm runtime get/put to DMA components' device.
- SCP(VPU) driver revision.
- stop queuing jobs(remove flush_workqueue()) after mdp_m2m_release().
- add computation of plane address with data_offset.
- fix scale ratio check issue.
- add default v4l2_format setting.

Changes since v2:
- modify code for review comment from Tomasz Figa & Alexandre Courbot
- review comment from Rob Herring will offer code revision in v4, due to
  it's related to device node modification, will need to modify code
  architecture

Changes since v1:
- modify code for CMDQ v3 API support
- EC ipi cmd migration
- fix compliance test fail item (m2m cmd with -f) due to there is two problem in runing all format(-f) cmd:
1. out of memory before test complete
        Due to capture buffer mmap (refcount + 1) after reqbuf but seems
        no corresponding munmap called before device close.
        There are total 12XX items(formats) in format test and each format
        alloc 8 capture/output buffers.
2. unceasingly captureBufs() (randomly)
        Seems the break statement didn't catch the count == 0 situation:
        In v4l2-test-buffers.cpp, function: captureBufs()
                        ...
                        count--;
                        if (!node->is_m2m && !count)
                                break;
        Log is as attachment

I will paste the test result with problem part in another e-mail

Hi,

This is the first version of RFC patch for Media Data Path 3 (MDP3),
MDP3 is used for scaling and color format conversion.
support using GCE to write register in critical time limitation.
support V4L2 m2m device control.

Moudy Ho (5):
  soc: mediatek: mmsys: Add support for MDP
  soc: mediatek: mutex: add support for MDP
  dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
  dts: arm64: mt8183: Add Mediatek MDP3 nodes
  media: platform: mtk-mdp3: Add Mediatek MDP3 driver

 .../bindings/media/mediatek,mdp3-ccorr.yaml   |   58 +
 .../bindings/media/mediatek,mdp3-rdma.yaml    |  241 +++
 .../bindings/media/mediatek,mdp3-rsz.yaml     |   66 +
 .../bindings/media/mediatek,mdp3-wdma.yaml    |   71 +
 .../bindings/media/mediatek,mdp3-wrot.yaml    |   71 +
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  110 ++
 drivers/media/platform/Kconfig                |   19 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/mtk-mdp3/Makefile      |    7 +
 drivers/media/platform/mtk-mdp3/isp_reg.h     |   27 +
 .../media/platform/mtk-mdp3/mdp_reg_ccorr.h   |   19 +
 .../media/platform/mtk-mdp3/mdp_reg_rdma.h    |   65 +
 drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h |   39 +
 .../media/platform/mtk-mdp3/mdp_reg_wdma.h    |   47 +
 .../media/platform/mtk-mdp3/mdp_reg_wrot.h    |   55 +
 drivers/media/platform/mtk-mdp3/mtk-img-ipi.h |  281 ++++
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.c   |  508 ++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.h   |   47 +
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 1357 +++++++++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.h   |  148 ++
 .../media/platform/mtk-mdp3/mtk-mdp3-core.c   |  300 ++++
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |   75 +
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    |  802 ++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.h    |   42 +
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   |  747 +++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |  373 +++++
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.c    |  314 ++++
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.h    |   79 +
 drivers/soc/mediatek/mt8183-mmsys.h           |  235 +++
 drivers/soc/mediatek/mtk-mmsys.c              |  164 ++
 drivers/soc/mediatek/mtk-mmsys.h              |    9 +-
 drivers/soc/mediatek/mtk-mutex.c              |  106 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |   81 +
 include/linux/soc/mediatek/mtk-mutex.h        |    8 +
 34 files changed, 6564 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
 create mode 100644 drivers/media/platform/mtk-mdp3/Makefile
 create mode 100644 drivers/media/platform/mtk-mdp3/isp_reg.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_ccorr.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_rdma.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_wdma.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_wrot.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-img-ipi.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h

-- 
2.18.0

From moudy.ho at mediatek.com  Thu Aug 19 00:09:50 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Thu, 19 Aug 2021 15:09:50 +0800
Subject: [PATCH v6 1/5] soc: mediatek: mmsys: Add support for MDP
In-Reply-To: <20210819070954.16679-1-moudy.ho@mediatek.com>
References: <20210819070954.16679-1-moudy.ho@mediatek.com>
Message-ID: <20210819070954.16679-2-moudy.ho@mediatek.com>

Add functions to support MDP:
  1. MDP connect/disconnect functions
  2. ISP control function
  3. Write register via CMDQ

Add MDP related settings for 8183 SoC
  1. Register settings
  2. MDP route table

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 drivers/soc/mediatek/mt8183-mmsys.h    | 235 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 164 +++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       |   9 +-
 include/linux/soc/mediatek/mtk-mmsys.h |  81 +++++++++
 4 files changed, 486 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mt8183-mmsys.h b/drivers/soc/mediatek/mt8183-mmsys.h
index 579dfc8dc8fc..2fa79e745a45 100644
--- a/drivers/soc/mediatek/mt8183-mmsys.h
+++ b/drivers/soc/mediatek/mt8183-mmsys.h
@@ -12,6 +12,32 @@
 #define MT8183_DISP_DPI0_SEL_IN			0xf30
 #define MT8183_DISP_RDMA0_SOUT_SEL_IN		0xf50
 #define MT8183_DISP_RDMA1_SOUT_SEL_IN		0xf54
+#define MT8183_MDP_ISP_MOUT_EN			0xf80
+#define MT8183_MDP_RDMA0_MOUT_EN		0xf84
+#define MT8183_MDP_PRZ0_MOUT_EN			0xf8c
+#define MT8183_MDP_PRZ1_MOUT_EN			0xf90
+#define MT8183_MDP_COLOR_MOUT_EN		0xf94
+#define MT8183_MDP_IPU_MOUT_EN			0xf98
+#define MT8183_MDP_PATH0_SOUT_SEL		0xfa8
+#define MT8183_MDP_PATH1_SOUT_SEL		0xfac
+#define MT8183_MDP_PRZ0_SEL_IN			0xfc0
+#define MT8183_MDP_PRZ1_SEL_IN			0xfc4
+#define MT8183_MDP_TDSHP_SEL_IN			0xfc8
+#define MT8183_MDP_WROT0_SEL_IN			0xfd0
+#define MT8183_MDP_WDMA_SEL_IN			0xfd4
+#define MT8183_MDP_PATH0_SEL_IN			0xfe0
+#define MT8183_MDP_PATH1_SEL_IN			0xfe4
+#define MT8183_MDP_AAL_MOUT_EN			0xfe8
+#define MT8183_MDP_AAL_SEL_IN			0xfec
+#define MT8183_MDP_CCORR_SEL_IN			0xff0
+#define MT8183_MDP_CCORR_SOUT_SEL		0xff4
+
+#define MT8183_ISP_CTRL_MMSYS_SW0_RST_B		0x140
+#define MT8183_ISP_CTRL_MMSYS_SW1_RST_B		0x144
+#define MT8183_ISP_CTRL_MDP_ASYNC_CFG_WD	0x934
+#define MT8183_ISP_CTRL_MDP_ASYNC_IPU_CFG_WD	0x93C
+#define MT8183_ISP_CTRL_ISP_RELAY_CFG_WD	0x994
+#define MT8183_ISP_CTRL_IPU_RELAY_CFG_WD	0x9a0
 
 #define MT8183_OVL0_MOUT_EN_OVL0_2L		BIT(4)
 #define MT8183_OVL0_2L_MOUT_EN_DISP_PATH0	BIT(0)
@@ -24,6 +50,55 @@
 #define MT8183_DPI0_SEL_IN_RDMA1		0x2
 #define MT8183_RDMA0_SOUT_COLOR0		0x1
 #define MT8183_RDMA1_SOUT_DSI0			0x1
+#define MT8183_MDP_ISP_MOUT_EN_CCORR0		BIT(0)
+#define MT8183_MDP_ISP_MOUT_EN_RSZ1		BIT(1)
+#define MT8183_MDP_ISP_MOUT_EN_AAL0		BIT(2)
+#define MT8183_MDP_IPU_MOUT_EN_CCORR0		BIT(0)
+#define MT8183_MDP_IPU_MOUT_EN_RSZ1		BIT(1)
+#define MT8183_MDP_IPU_MOUT_EN_AAL0		BIT(2)
+#define MT8183_MDP_RDMA0_MOUT_EN_CCORR0		BIT(0)
+#define MT8183_MDP_RDMA0_MOUT_EN_RSZ1		BIT(1)
+#define MT8183_MDP_RDMA0_MOUT_EN_PATH0_OUT	BIT(2)
+#define MT8183_MDP_RDMA0_MOUT_EN_AAL0		BIT(3)
+#define MT8183_MDP_AAL_MOUT_EN_CCORR0		BIT(0)
+#define MT8183_MDP_AAL_MOUT_EN_RSZ1		BIT(1)
+#define MT8183_MDP_AAL_MOUT_EN_RSZ0		BIT(2)
+#define MT8183_MDP_PRZ0_MOUT_EN_PATH0_OUT	BIT(0)
+#define MT8183_MDP_PRZ0_MOUT_EN_TDSHP0		BIT(1)
+#define MT8183_MDP_PRZ1_MOUT_EN_PATH0_OUT	BIT(0)
+#define MT8183_MDP_PRZ1_MOUT_EN_TDSHP0		BIT(1)
+#define MT8183_MDP_PRZ1_MOUT_EN_PATH1_OUT	BIT(2)
+#define MT8183_MDP_PRZ1_MOUT_EN_COLOR0		BIT(4)
+#define MT8183_MDP_COLOR_MOUT_EN_PATH0_OUT	BIT(0)
+#define MT8183_MDP_COLOR_MOUT_EN_PATH1_OUT	BIT(1)
+#define MT8183_MDP_AAL_SEL_IN_CAMIN		0
+#define MT8183_MDP_AAL_SEL_IN_RDMA0		1
+#define MT8183_MDP_AAL_SEL_IN_CAMIN2		2
+#define MT8183_MDP_AAL_SEL_IN_CCORR0		3
+#define MT8183_MDP_CCORR_SEL_IN_CAMIN		0
+#define MT8183_MDP_CCORR_SEL_IN_RDMA0		1
+#define MT8183_MDP_CCORR_SEL_IN_CAMIN2		3
+#define MT8183_MDP_CCORR_SEL_IN_AAL0		4
+#define MT8183_MDP_PRZ0_SEL_IN_AAL0		0
+#define MT8183_MDP_PRZ0_SEL_IN_CCORR0		1
+#define MT8183_MDP_PRZ1_SEL_IN_CAMIN		0
+#define MT8183_MDP_PRZ1_SEL_IN_RDMA0		1
+#define MT8183_MDP_PRZ1_SEL_IN_CAMIN2		4
+#define MT8183_MDP_PRZ1_SEL_IN_AAL0		5
+#define MT8183_MDP_TDSHP_SEL_IN_RSZ0		0
+#define MT8183_MDP_TDSHP_SEL_IN_RSZ1		1
+#define MT8183_MDP_PATH0_SEL_IN_RSZ0		0
+#define MT8183_MDP_PATH0_SEL_IN_RSZ1		1
+#define MT8183_MDP_PATH0_SEL_IN_COLOR0		2
+#define MT8183_MDP_PATH0_SEL_IN_RDMA0		3
+#define MT8183_MDP_PATH1_SEL_IN_RSZ1		0
+#define MT8183_MDP_PATH1_SEL_IN_COLOR0		1
+#define MT8183_MDP_WROT0_SEL_IN_PATH0_OUT	0
+#define MT8183_MDP_WDMA_SEL_IN_PATH1_OUT	0
+#define MT8183_MDP_CCORR_SOUT_SEL_AAL0		0
+#define MT8183_MDP_CCORR_SOUT_SEL_RSZ0		1
+#define MT8183_MDP_PATH0_SOUT_SEL_WROT0		0
+#define MT8183_MDP_PATH1_SOUT_SEL_WDMA		0
 
 static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
 	{
@@ -50,5 +125,165 @@ static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
 	}
 };
 
+static const struct mtk_mmsys_routes mmsys_mt8183_mdp_routing_table[] = {
+	{
+		MDP_COMP_CAMIN, MDP_COMP_CCORR0,
+		MT8183_MDP_ISP_MOUT_EN, MT8183_MDP_ISP_MOUT_EN_CCORR0
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_RSZ1,
+		MT8183_MDP_ISP_MOUT_EN, MT8183_MDP_ISP_MOUT_EN_RSZ1
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_AAL0,
+		MT8183_MDP_ISP_MOUT_EN, MT8183_MDP_ISP_MOUT_EN_AAL0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_CCORR0,
+		MT8183_MDP_IPU_MOUT_EN, MT8183_MDP_IPU_MOUT_EN_CCORR0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_RSZ1,
+		MT8183_MDP_IPU_MOUT_EN, MT8183_MDP_IPU_MOUT_EN_RSZ1
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_AAL0,
+		MT8183_MDP_IPU_MOUT_EN, MT8183_MDP_IPU_MOUT_EN_AAL0
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_CCORR0,
+		MT8183_MDP_RDMA0_MOUT_EN, MT8183_MDP_RDMA0_MOUT_EN_CCORR0
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_RSZ1,
+		MT8183_MDP_RDMA0_MOUT_EN, MT8183_MDP_RDMA0_MOUT_EN_RSZ1
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_RDMA0_MOUT_EN, MT8183_MDP_RDMA0_MOUT_EN_PATH0_OUT
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_AAL0,
+		MT8183_MDP_RDMA0_MOUT_EN, MT8183_MDP_RDMA0_MOUT_EN_AAL0
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_CCORR0,
+		MT8183_MDP_AAL_MOUT_EN, MT8183_MDP_AAL_MOUT_EN_CCORR0
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_RSZ1,
+		MT8183_MDP_AAL_MOUT_EN, MT8183_MDP_AAL_MOUT_EN_RSZ1
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_RSZ0,
+		MT8183_MDP_AAL_MOUT_EN, MT8183_MDP_AAL_MOUT_EN_RSZ0
+	}, {
+		MDP_COMP_RSZ0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PRZ0_MOUT_EN, MT8183_MDP_PRZ0_MOUT_EN_PATH0_OUT
+	}, {
+		MDP_COMP_RSZ0, MDP_COMP_TDSHP0,
+		MT8183_MDP_PRZ0_MOUT_EN, MT8183_MDP_PRZ0_MOUT_EN_TDSHP0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PRZ1_MOUT_EN, MT8183_MDP_PRZ1_MOUT_EN_PATH0_OUT
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_TDSHP0,
+		MT8183_MDP_PRZ1_MOUT_EN, MT8183_MDP_PRZ1_MOUT_EN_TDSHP0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_PATH1_SOUT,
+		MT8183_MDP_PRZ1_MOUT_EN, MT8183_MDP_PRZ1_MOUT_EN_PATH1_OUT
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_COLOR0,
+		MT8183_MDP_PRZ1_MOUT_EN, MT8183_MDP_PRZ1_MOUT_EN_COLOR0
+	}, {
+		MDP_COMP_COLOR0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_COLOR_MOUT_EN, MT8183_MDP_COLOR_MOUT_EN_PATH0_OUT
+	}, {
+		MDP_COMP_COLOR0, MDP_COMP_PATH1_SOUT,
+		MT8183_MDP_COLOR_MOUT_EN, MT8183_MDP_COLOR_MOUT_EN_PATH1_OUT
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_AAL0,
+		MT8183_MDP_AAL_SEL_IN, MT8183_MDP_AAL_SEL_IN_CAMIN
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_AAL0,
+		MT8183_MDP_AAL_SEL_IN, MT8183_MDP_AAL_SEL_IN_RDMA0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_AAL0,
+		MT8183_MDP_AAL_SEL_IN, MT8183_MDP_AAL_SEL_IN_CAMIN2
+	}, {
+		MDP_COMP_CCORR0, MDP_COMP_AAL0,
+		MT8183_MDP_AAL_SEL_IN, MT8183_MDP_AAL_SEL_IN_CCORR0
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_CCORR0,
+		MT8183_MDP_CCORR_SEL_IN, MT8183_MDP_CCORR_SEL_IN_CAMIN
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_CCORR0,
+		MT8183_MDP_CCORR_SEL_IN, MT8183_MDP_CCORR_SEL_IN_RDMA0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_CCORR0,
+		MT8183_MDP_CCORR_SEL_IN, MT8183_MDP_CCORR_SEL_IN_CAMIN2
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_CCORR0,
+		MT8183_MDP_CCORR_SEL_IN, MT8183_MDP_CCORR_SEL_IN_AAL0
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_RSZ0,
+		MT8183_MDP_PRZ0_SEL_IN, MT8183_MDP_PRZ0_SEL_IN_AAL0
+	}, {
+		MDP_COMP_CCORR0, MDP_COMP_RSZ0,
+		MT8183_MDP_PRZ0_SEL_IN, MT8183_MDP_PRZ0_SEL_IN_CCORR0
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_RSZ1,
+		MT8183_MDP_PRZ1_SEL_IN, MT8183_MDP_PRZ1_SEL_IN_CAMIN
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_RSZ1,
+		MT8183_MDP_PRZ1_SEL_IN, MT8183_MDP_PRZ1_SEL_IN_RDMA0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_RSZ1,
+		MT8183_MDP_PRZ1_SEL_IN, MT8183_MDP_PRZ1_SEL_IN_CAMIN2
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_RSZ1,
+		MT8183_MDP_PRZ1_SEL_IN, MT8183_MDP_PRZ1_SEL_IN_AAL0
+	}, {
+		MDP_COMP_RSZ0, MDP_COMP_TDSHP0,
+		MT8183_MDP_TDSHP_SEL_IN, MT8183_MDP_TDSHP_SEL_IN_RSZ0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_TDSHP0,
+		MT8183_MDP_TDSHP_SEL_IN, MT8183_MDP_TDSHP_SEL_IN_RSZ1
+	}, {
+		MDP_COMP_RSZ0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PATH0_SEL_IN, MT8183_MDP_PATH0_SEL_IN_RSZ0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PATH0_SEL_IN, MT8183_MDP_PATH0_SEL_IN_RSZ1
+	}, {
+		MDP_COMP_COLOR0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PATH0_SEL_IN, MT8183_MDP_PATH0_SEL_IN_COLOR0
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PATH0_SEL_IN, MT8183_MDP_PATH0_SEL_IN_RDMA0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_PATH1_SOUT,
+		MT8183_MDP_PATH1_SEL_IN, MT8183_MDP_PATH1_SEL_IN_RSZ1
+	}, {
+		MDP_COMP_COLOR0, MDP_COMP_PATH1_SOUT,
+		MT8183_MDP_PATH1_SEL_IN, MT8183_MDP_PATH1_SEL_IN_COLOR0
+	}, {
+		MDP_COMP_PATH0_SOUT, MDP_COMP_WROT0,
+		MT8183_MDP_WROT0_SEL_IN, MT8183_MDP_WROT0_SEL_IN_PATH0_OUT
+	}, {
+		MDP_COMP_PATH1_SOUT, MDP_COMP_WDMA,
+		MT8183_MDP_WDMA_SEL_IN, MT8183_MDP_WDMA_SEL_IN_PATH1_OUT
+	}, {
+		MDP_COMP_CCORR0, MDP_COMP_AAL0,
+		MT8183_MDP_CCORR_SOUT_SEL, MT8183_MDP_CCORR_SOUT_SEL_AAL0
+	}, {
+		MDP_COMP_CCORR0, MDP_COMP_RSZ0,
+		MT8183_MDP_CCORR_SOUT_SEL, MT8183_MDP_CCORR_SOUT_SEL_RSZ0
+	}, {
+		MDP_COMP_PATH0_SOUT, MDP_COMP_WROT0,
+		MT8183_MDP_PATH0_SOUT_SEL, MT8183_MDP_PATH0_SOUT_SEL_WROT0
+	}, {
+		MDP_COMP_PATH1_SOUT, MDP_COMP_WDMA,
+		MT8183_MDP_PATH1_SOUT_SEL, MT8183_MDP_PATH1_SOUT_SEL_WDMA
+	}
+};
+
+static const unsigned int mmsys_mt8183_mdp_isp_ctrl_table[ISP_CTRL_MAX] = {
+	[ISP_CTRL_MMSYS_SW0_RST_B] = MT8183_ISP_CTRL_MMSYS_SW0_RST_B,
+	[ISP_CTRL_MMSYS_SW1_RST_B] = MT8183_ISP_CTRL_MMSYS_SW1_RST_B,
+	[ISP_CTRL_MDP_ASYNC_CFG_WD] = MT8183_ISP_CTRL_MDP_ASYNC_CFG_WD,
+	[ISP_CTRL_MDP_ASYNC_IPU_CFG_WD] = MT8183_ISP_CTRL_MDP_ASYNC_IPU_CFG_WD,
+	[ISP_CTRL_ISP_RELAY_CFG_WD] = MT8183_ISP_CTRL_ISP_RELAY_CFG_WD,
+	[ISP_CTRL_IPU_RELAY_CFG_WD] = MT8183_ISP_CTRL_IPU_RELAY_CFG_WD,
+};
+
 #endif /* __SOC_MEDIATEK_MT8183_MMSYS_H */
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 080660ef11bf..c4b99a99ee1e 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -7,8 +7,10 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk-mmsys.h"
 #include "mt8167-mmsys.h"
@@ -50,11 +52,16 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.clk_driver = "clk-mt8183-mm",
 	.routes = mmsys_mt8183_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
+	.mdp_routes = mmsys_mt8183_mdp_routing_table,
+	.mdp_num_routes = ARRAY_SIZE(mmsys_mt8183_mdp_routing_table),
+	.mdp_isp_ctrl = mmsys_mt8183_mdp_isp_ctrl_table,
 };
 
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
+	phys_addr_t addr;
+	u8 subsys_id;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -91,12 +98,160 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
+void mtk_mmsys_mdp_connect(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			   enum mtk_mdp_comp_id cur,
+			   enum mtk_mdp_comp_id next)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const struct mtk_mmsys_routes *routes = mmsys->data->mdp_routes;
+	int i;
+
+	WARN_ON(!routes);
+	WARN_ON(mmsys->subsys_id == 0);
+	for (i = 0; i < mmsys->data->mdp_num_routes; i++)
+		if (cur == routes[i].from_comp && next == routes[i].to_comp)
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id,
+					    mmsys->addr + routes[i].addr,
+					    routes[i].val, 0xFFFFFFFF);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_connect);
+
+void mtk_mmsys_mdp_disconnect(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id cur,
+			      enum mtk_mdp_comp_id next)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const struct mtk_mmsys_routes *routes = mmsys->data->mdp_routes;
+	int i;
+
+	WARN_ON(mmsys->subsys_id == 0);
+	for (i = 0; i < mmsys->data->mdp_num_routes; i++)
+		if (cur == routes[i].from_comp && next == routes[i].to_comp)
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id,
+					    mmsys->addr + routes[i].addr,
+					    0, 0xFFFFFFFF);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_disconnect);
+
+void mtk_mmsys_mdp_isp_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			    enum mtk_mdp_comp_id id)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const unsigned int *isp_ctrl = mmsys->data->mdp_isp_ctrl;
+	u32 reg;
+
+	WARN_ON(mmsys->subsys_id == 0);
+	/* Direct link */
+	if (id == MDP_COMP_CAMIN) {
+		/* Reset MDP_DL_ASYNC_TX */
+		/* Bit  3: MDP_DL_ASYNC_TX / MDP_RELAY */
+		if (isp_ctrl[ISP_CTRL_MMSYS_SW0_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MMSYS_SW0_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0x0, 0x00000008);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    1 << 3, 0x00000008);
+		}
+
+		/* Reset MDP_DL_ASYNC_RX */
+		/* Bit  10: MDP_DL_ASYNC_RX */
+		if (isp_ctrl[ISP_CTRL_MMSYS_SW1_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MMSYS_SW1_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0x0, 0x00000400);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    1 << 10, 0x00000400);
+		}
+
+		/* Enable sof mode */
+		if (isp_ctrl[ISP_CTRL_ISP_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_ISP_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0 << 31, 0x80000000);
+		}
+	}
+
+	if (id == MDP_COMP_CAMIN2) {
+		/* Reset MDP_DL_ASYNC2_TX */
+		/* Bit  4: MDP_DL_ASYNC2_TX / MDP_RELAY2 */
+		if (isp_ctrl[ISP_CTRL_MMSYS_SW0_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MMSYS_SW0_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0x0, 0x00000010);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    1 << 4, 0x00000010);
+		}
+
+		/* Reset MDP_DL_ASYNC2_RX */
+		/* Bit  11: MDP_DL_ASYNC2_RX */
+		if (isp_ctrl[ISP_CTRL_MMSYS_SW1_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MMSYS_SW1_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0x0, 0x00000800);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    1 << 11, 0x00000800);
+		}
+
+		/* Enable sof mode */
+		if (isp_ctrl[ISP_CTRL_IPU_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_IPU_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0 << 31, 0x80000000);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_isp_ctrl);
+
+void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id id, u32 camin_w, u32 camin_h)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const unsigned int *isp_ctrl = mmsys->data->mdp_isp_ctrl;
+	u32 reg;
+
+	WARN_ON(mmsys->subsys_id == 0);
+	/* Config for direct link */
+	if (id == MDP_COMP_CAMIN) {
+		if (isp_ctrl[ISP_CTRL_MDP_ASYNC_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MDP_ASYNC_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+
+		if (isp_ctrl[ISP_CTRL_ISP_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_ISP_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+	}
+	if (id == MDP_COMP_CAMIN2) {
+		if (isp_ctrl[ISP_CTRL_MDP_ASYNC_IPU_CFG_WD]) {
+			reg = mmsys->addr +
+			      isp_ctrl[ISP_CTRL_MDP_ASYNC_IPU_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+		if (isp_ctrl[ISP_CTRL_IPU_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_IPU_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_camin_ctrl);
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct platform_device *clks;
 	struct platform_device *drm;
 	struct mtk_mmsys *mmsys;
+	struct resource res;
+	struct cmdq_client_reg cmdq_reg;
 	int ret;
 
 	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
@@ -110,6 +265,15 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	if (of_address_to_resource(dev->of_node, 0, &res) < 0)
+		mmsys->addr = 0L;
+	else
+		mmsys->addr = res.start;
+
+	if (cmdq_dev_get_client_reg(dev, &cmdq_reg, 0) != 0)
+		dev_info(dev, "cmdq subsys id has not been set\n");
+	mmsys->subsys_id = cmdq_reg.subsys;
+
 	mmsys->data = of_device_get_match_data(&pdev->dev);
 	platform_set_drvdata(pdev, mmsys);
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index a760a34e6eca..025d4bc9c8cc 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -74,9 +74,12 @@ struct mtk_mmsys_routes {
 };
 
 struct mtk_mmsys_driver_data {
-	const char *clk_driver;
-	const struct mtk_mmsys_routes *routes;
-	const unsigned int num_routes;
+	const char		*clk_driver;
+	const struct		mtk_mmsys_routes *routes;
+	const unsigned int	num_routes;
+	const struct		mtk_mmsys_routes *mdp_routes;
+	const unsigned int	mdp_num_routes;
+	const unsigned int	*mdp_isp_ctrl;
 };
 
 /*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 2228bf6133da..1234e8c0aefd 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -7,8 +7,14 @@
 #define __MTK_MMSYS_H
 
 enum mtk_ddp_comp_id;
+enum mtk_mdp_comp_id;
 struct device;
 
+struct mmsys_cmdq_cmd {
+	struct cmdq_pkt *pkt;
+	s32 *event;
+};
+
 enum mtk_ddp_comp_id {
 	DDP_COMPONENT_AAL0,
 	DDP_COMPONENT_AAL1,
@@ -42,6 +48,64 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_ID_MAX,
 };
 
+enum mtk_mdp_comp_id {
+	MDP_COMP_NONE = -1,	/* Invalid engine */
+
+	/* ISP */
+	MDP_COMP_WPEI = 0,
+	MDP_COMP_WPEO,		/* 1 */
+	MDP_COMP_WPEI2,		/* 2 */
+	MDP_COMP_WPEO2,		/* 3 */
+	MDP_COMP_ISP_IMGI,	/* 4 */
+	MDP_COMP_ISP_IMGO,	/* 5 */
+	MDP_COMP_ISP_IMG2O,	/* 6 */
+
+	/* IPU */
+	MDP_COMP_IPUI,		/* 7 */
+	MDP_COMP_IPUO,		/* 8 */
+
+	/* MDP */
+	MDP_COMP_CAMIN,		/* 9 */
+	MDP_COMP_CAMIN2,	/* 10 */
+	MDP_COMP_RDMA0,		/* 11 */
+	MDP_COMP_AAL0,		/* 12 */
+	MDP_COMP_CCORR0,	/* 13 */
+	MDP_COMP_RSZ0,		/* 14 */
+	MDP_COMP_RSZ1,		/* 15 */
+	MDP_COMP_TDSHP0,	/* 16 */
+	MDP_COMP_COLOR0,	/* 17 */
+	MDP_COMP_PATH0_SOUT,	/* 18 */
+	MDP_COMP_PATH1_SOUT,	/* 19 */
+	MDP_COMP_WROT0,		/* 20 */
+	MDP_COMP_WDMA,		/* 21 */
+
+	/* Dummy Engine */
+	MDP_COMP_RDMA1,		/* 22 */
+	MDP_COMP_RSZ2,		/* 23 */
+	MDP_COMP_TDSHP1,	/* 24 */
+	MDP_COMP_WROT1,		/* 25 */
+
+	MDP_MAX_COMP_COUNT	/* ALWAYS keep at the end */
+};
+
+enum mtk_mdp_pipe_id {
+	MDP_PIPE_IMGI,
+	MDP_PIPE_RDMA0,
+	MDP_PIPE_WPEI,
+	MDP_PIPE_WPEI2,
+	MDP_PIPE_MAX
+};
+
+enum mtk_isp_ctrl {
+	ISP_CTRL_MMSYS_SW0_RST_B,
+	ISP_CTRL_MMSYS_SW1_RST_B,
+	ISP_CTRL_MDP_ASYNC_CFG_WD,
+	ISP_CTRL_MDP_ASYNC_IPU_CFG_WD,
+	ISP_CTRL_ISP_RELAY_CFG_WD,
+	ISP_CTRL_IPU_RELAY_CFG_WD,
+	ISP_CTRL_MAX
+};
+
 void mtk_mmsys_ddp_connect(struct device *dev,
 			   enum mtk_ddp_comp_id cur,
 			   enum mtk_ddp_comp_id next);
@@ -50,4 +114,21 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id cur,
 			      enum mtk_ddp_comp_id next);
 
+void mtk_mmsys_mdp_connect(struct device *dev,
+			   struct mmsys_cmdq_cmd *cmd,
+			   enum mtk_mdp_comp_id cur,
+			   enum mtk_mdp_comp_id next);
+
+void mtk_mmsys_mdp_disconnect(struct device *dev,
+			      struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id cur,
+			      enum mtk_mdp_comp_id next);
+
+void mtk_mmsys_mdp_isp_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			    enum mtk_mdp_comp_id id);
+
+void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id id,
+			      u32 camin_w, u32 camin_h);
+
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0

From moudy.ho at mediatek.com  Thu Aug 19 00:09:52 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Thu, 19 Aug 2021 15:09:52 +0800
Subject: [PATCH v6 3/5] dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
In-Reply-To: <20210819070954.16679-1-moudy.ho@mediatek.com>
References: <20210819070954.16679-1-moudy.ho@mediatek.com>
Message-ID: <20210819070954.16679-4-moudy.ho@mediatek.com>

This patch adds DT binding document for Media Data Path 3 (MDP3)
a unit in multimedia system used for scaling and color format convert.

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 .../bindings/media/mediatek,mdp3-ccorr.yaml   |  58 +++++
 .../bindings/media/mediatek,mdp3-rdma.yaml    | 241 ++++++++++++++++++
 .../bindings/media/mediatek,mdp3-rsz.yaml     |  66 +++++
 .../bindings/media/mediatek,mdp3-wdma.yaml    |  71 ++++++
 .../bindings/media/mediatek,mdp3-wrot.yaml    |  71 ++++++
 5 files changed, 507 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
new file mode 100644
index 000000000000..205b91b55806
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 CCORR Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to do color correction with 3X3 matrix.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8183-mdp3-ccorr
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+
+    mdp3_ccorr: mdp3_ccorr at 1401c000 {
+      compatible = "mediatek,mt8183-mdp3-ccorr";
+      mediatek,mdp3-id = <0>;
+      reg = <0x1401c000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_CCORR>;
+    };
+
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
new file mode 100644
index 000000000000..9565317990a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
@@ -0,0 +1,241 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to do read DMA.
+  RDMA0 is also used to be a controller node containing MMSYS,
+  MUTEX, GCE and SCP settings.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+        - enum:
+          # controller node
+          - mediatek,mt8183-mdp3
+        - enum:
+          - mediatek,mt8183-mdp3-rdma
+
+      - items:
+        - enum:
+          # read DMA
+          - mediatek,mt8183-mdp3-rdma
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of system control processor (SCP), using
+      the remoteproc & rpmsg framework.
+      $ref: /schemas/remoteproc/mtk,scp.yaml
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      In MDP3, it can allocate multiple identical modules for
+      different data path selection or multi-pipeline execution.
+      This node is used to indicate the ID of each module.
+
+  mdp3-comps:
+    $ref: /schemas/types.yaml#/definitions/string-array
+    items:
+        - enum:
+          # MDP direct-link input path selection, create a
+          # component for path connectedness of HW pipe control
+          - mediatek,mt8183-mdp3-dl1
+        - enum:
+          - mediatek,mt8183-mdp3-dl2
+        - enum:
+          # MDP direct-link output path selection, create a
+          # component for path connectedness of HW pipe control
+          - mediatek,mt8183-mdp3-path1
+        - enum:
+          - mediatek,mt8183-mdp3-path2
+        - enum:
+          # Input DMA of ISP PASS2 (DIP) module for raw image input
+          - mediatek,mt8183-mdp3-imgi
+        - enum:
+          # Output DMA of ISP PASS2 (DIP) module for YUV image output
+          - mediatek,mt8183-mdp3-exto
+
+  mdp3-comp-ids:
+    maxItems: 1
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: |
+      Pipeline ID of MDP direct-link or DIP.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 6
+
+  iommus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Should point to the respective IOMMU block with master
+      port as argument.
+      $ref: /schemas/iommu/mediatek,iommu.yaml
+
+  mediatek,mmsys:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of mux(multiplexer) controller for HW connections.
+
+  mediatek,mm-mutex:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of sof(start of frame) signal controller.
+
+  mediatek,mailbox-gce:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      The node of global command engine (GCE), used to read/write
+      registers with critical time limitation.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  mboxes:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      $ref: /schemas/mailbox/mailbox.txt
+
+  gce-subsys:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  mediatek,gce-events:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: |
+      In use event IDs list, all IDs are defined in
+      'dt-bindings/gce/mt8183-gce.h'.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+if:
+  properties:
+    compatible:
+      items:
+        - enum:
+          - mediatek,mt8183-mdp3
+        - enum:
+          - mediatek,mt8183-mdp3-rdma
+
+then:
+  required:
+    - mediatek,scp
+    - mediatek,mmsys
+    - mediatek,mm-mutex
+    - mediatek,gce-events
+    - mediatek,mailbox-gce
+    - mboxes
+    - gce-subsys
+
+required:
+  - compatible
+  - mediatek,mdp3-id
+  - reg
+  - clocks
+  - mediatek,gce-client-reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_rdma0: mdp3_rdma0 at 14001000 {
+      compatible = "mediatek,mt8183-mdp3",
+                   "mediatek,mt8183-mdp3-rdma";
+      mediatek,scp = <&scp>;
+      mediatek,mdp3-id = <0>;
+      mdp3-comps = "mediatek,mt8183-mdp3-dl1", "mediatek,mt8183-mdp3-dl2",
+		   "mediatek,mt8183-mdp3-path1", "mediatek,mt8183-mdp3-path2",
+                   "mediatek,mt8183-mdp3-imgi", "mediatek,mt8183-mdp3-exto";
+      mdp3-comp-ids = <0 1 0 1 0 1>;
+      reg = <0x14001000 0x1000>,
+            <0x14000000 0x1000>,
+            <0x14005000 0x1000>,
+            <0x14006000 0x1000>,
+            <0x15020000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
+                                <&gce SUBSYS_1502XXXX 0 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_RDMA0>,
+               <&mmsys CLK_MM_MDP_RSZ1>,
+               <&mmsys CLK_MM_MDP_DL_TXCK>,
+               <&mmsys CLK_MM_MDP_DL_RX>,
+               <&mmsys CLK_MM_IPU_DL_TXCK>,
+               <&mmsys CLK_MM_IPU_DL_RX>;
+      iommus = <&iommu>;
+      mediatek,mmsys = <&mmsys>;
+      mediatek,mm-mutex = <&mutex>;
+      mediatek,mailbox-gce = <&gce>;
+      mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
+               <&gce 21 CMDQ_THR_PRIO_LOWEST 0>,
+               <&gce 22 CMDQ_THR_PRIO_LOWEST 0>,
+               <&gce 23 CMDQ_THR_PRIO_LOWEST 0>;
+      gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
+                   <&gce 0x14010000 SUBSYS_1401XXXX>,
+                   <&gce 0x14020000 SUBSYS_1402XXXX>,
+                   <&gce 0x15020000 SUBSYS_1502XXXX>;
+      mediatek,gce-events = <CMDQ_EVENT_MDP_RDMA0_SOF>,
+                            <CMDQ_EVENT_MDP_RDMA0_EOF>,
+                            <CMDQ_EVENT_MDP_RSZ0_SOF>,
+                            <CMDQ_EVENT_MDP_RSZ1_SOF>,
+                            <CMDQ_EVENT_MDP_TDSHP_SOF>,
+                            <CMDQ_EVENT_MDP_WROT0_SOF>,
+                            <CMDQ_EVENT_MDP_WROT0_EOF>,
+                            <CMDQ_EVENT_MDP_WDMA0_SOF>,
+                            <CMDQ_EVENT_MDP_WDMA0_EOF>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_0>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_1>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_2>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_3>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_4>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_5>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_6>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_7>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_8>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_9>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_10>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_11>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_12>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_13>,
+                            <CMDQ_EVENT_ISP_FRAME_DONE_P2_14>,
+                            <CMDQ_EVENT_WPE_A_DONE>,
+                            <CMDQ_EVENT_SPE_B_DONE>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
new file mode 100644
index 000000000000..218f035ad406
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-rsz.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 Resizer Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to do frame resizing.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8183-mdp3-rsz
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+
+    mdp3_rsz0: mdp3_rsz0 at 14003000 {
+      compatible = "mediatek,mt8183-mdp3-rsz";
+      mediatek,mdp3-id = <0>;
+      reg = <0x14003000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_RSZ0>;
+    };
+
+    mdp3_rsz1: mdp3_rsz1 at 14004000 {
+      compatible = "mediatek,mt8183-mdp3-rsz";
+      mediatek,mdp3-id = <1>;
+      reg = <0x14004000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_RSZ1>;
+    };
+
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
new file mode 100644
index 000000000000..93e6f331ada8
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to write DMA.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8183-mdp3-wdma
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+  iommus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Should point to the respective IOMMU block with master
+      port as argument.
+      $ref: /schemas/iommu/mediatek,iommu.yaml
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_wdma: mdp3_wdma at 14006000 {
+      compatible = "mediatek,mt8183-mdp3-wdma";
+      mediatek,mdp3-id = <0>;
+      reg = <0x14006000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_WDMA0>;
+      iommus = <&iommu>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
new file mode 100644
index 000000000000..2993da04c562
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-wrot.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to write DMA with frame rotation.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8183-mdp3-wrot
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+  iommus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Should point to the respective IOMMU block with master
+      port as argument.
+      $ref: /schemas/iommu/mediatek,iommu.yaml
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_wrot0: mdp3_wrot0 at 14005000 {
+      compatible = "mediatek,mt8183-mdp3-wrot";
+      mediatek,mdp3-id = <0>;
+      reg = <0x14005000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_WROT0>;
+      iommus = <&iommu>;
+    };
-- 
2.18.0

From yunfei.dong at mediatek.com  Thu Aug 19 00:13:48 2021
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Thu, 19 Aug 2021 15:13:48 +0800
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
Message-ID: <1b79a67b703d2c894bc4d9458c760e082fc42958.camel@mediatek.com>

Hi Ezequiel,

Thanks for your suggestion.

On Wed, 2021-08-18 at 11:11 -0300, Ezequiel Garcia wrote:
> +danvet
> 
> Hi,
> 
> On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <yunfei.dong at mediatek.com>
> wrote:
> > 
> > This series adds support for multi hardware decode into mtk-vcodec, 
> > by first
> > adding component framework to manage each hardware information:
> > interrupt,
> > clock, register bases and power. Secondly add core thread to deal
> > with core
> > hardware message, at the same time, add msg queue for different
> > hardware
> > share messages. Lastly, the architecture of different specs are not
> > the same,
> > using specs type to separate them.
> > 
> 
> I don't think it's a good idea to introduce the component API in the
> media subsystem. It doesn't seem to be maintained, IRC there's not
> even
> a maintainer for it, and it has some issues that were never
> addressed.
> 
> It would be really important to avoid it. Is it really needed in the
> first place?
> 
> Thanks,
> Ezequiel

For there are many hardware need to use, mt8192 is three and mt8195 is
five. Maybe need more to be used in the feature.

Each hardware has independent clk/power/iommu port/irq.
Use component interface in prob to get each component's information.
Just enable the hardware when need to use it, very convenient and
simple.

I found that there are many modules use component to manage hardware
information, such as iommu and drm etc.

Do you have any other suggestion for this architecture?

Thanks
Yunfei Dong


From hongxing.zhu at nxp.com  Thu Aug 19 00:14:05 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Thu, 19 Aug 2021 15:14:05 +0800
Subject: [PATCH v1 0/3] dt-bindings: PCI: imx6: convert the imx pcie
Message-ID: <20210819071408.3856475-1-hongxing.zhu@nxp.com>

And fix according errors on imx6qdl.dtsi, imx6qp.dtsi, imx6sx.dtsi,
imx7d.dtsi and imx8mq.dtsi found by dt_binding_check and dtbs_check.

 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt  | 100 ----------------------------------------
 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 MAINTAINERS                                               |   2 +-
 arch/arm/boot/dts/imx6qdl.dtsi                            |   6 +--
 arch/arm/boot/dts/imx6qp.dtsi                             |   2 +-
 arch/arm/boot/dts/imx6sx.dtsi                             |   7 +--
 arch/arm/boot/dts/imx7d.dtsi                              |   6 +--
 arch/arm64/boot/dts/freescale/imx8mq.dtsi                 |   8 ++--
 8 files changed, 223 insertions(+), 115 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml

[PATCH v1 1/3] dt-bindings: PCI: imx6: convert the imx pcie
[PATCH v1 2/3] arm: dts: imx: fix the schema check errors
[PATCH v1 3/3] arm64: dts: imx8mq: fix the schema check errors



From hongxing.zhu at nxp.com  Thu Aug 19 00:14:06 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Thu, 19 Aug 2021 15:14:06 +0800
Subject: [PATCH v1 1/3] dt-bindings: PCI: imx6: convert the imx pcie
 controller to dtschema
In-Reply-To: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
References: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
Message-ID: <20210819071408.3856475-2-hongxing.zhu@nxp.com>

Convert the fsl,imx6q-pcie.txt into a schema.
- the ranges should be aligned to $ref: /schemas/pci/pci-bus.yaml#
- only one propert is allowed in the compatible string, remove
  "snps,dw-pcie".

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
---
 .../bindings/pci/fsl,imx6q-pcie.txt           | 100 ---------
 .../bindings/pci/fsl,imx6q-pcie.yaml          | 207 ++++++++++++++++++
 MAINTAINERS                                   |   2 +-
 3 files changed, 208 insertions(+), 101 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
deleted file mode 100644
index d8971ab99274..000000000000
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-* Freescale i.MX6 PCIe interface
-
-This PCIe host controller is based on the Synopsys DesignWare PCIe IP
-and thus inherits all the common properties defined in designware-pcie.txt.
-
-Required properties:
-- compatible:
-	- "fsl,imx6q-pcie"
-	- "fsl,imx6sx-pcie",
-	- "fsl,imx6qp-pcie"
-	- "fsl,imx7d-pcie"
-	- "fsl,imx8mq-pcie"
-- reg: base address and length of the PCIe controller
-- interrupts: A list of interrupt outputs of the controller. Must contain an
-  entry for each entry in the interrupt-names property.
-- interrupt-names: Must include the following entries:
-	- "msi": The interrupt that is asserted when an MSI is received
-- clock-names: Must include the following additional entries:
-	- "pcie_phy"
-
-Optional properties:
-- fsl,tx-deemph-gen1: Gen1 De-emphasis value. Default: 0
-- fsl,tx-deemph-gen2-3p5db: Gen2 (3.5db) De-emphasis value. Default: 0
-- fsl,tx-deemph-gen2-6db: Gen2 (6db) De-emphasis value. Default: 20
-- fsl,tx-swing-full: Gen2 TX SWING FULL value. Default: 127
-- fsl,tx-swing-low: TX launch amplitude swing_low value. Default: 127
-- fsl,max-link-speed: Specify PCI gen for link capability. Must be '2' for
-  gen2, otherwise will default to gen1. Note that the IMX6 LVDS clock outputs
-  do not meet gen2 jitter requirements and thus for gen2 capability a gen2
-  compliant clock generator should be used and configured.
-- reset-gpio: Should specify the GPIO for controlling the PCI bus device reset
-  signal. It's not polarity aware and defaults to active-low reset sequence
-  (L=reset state, H=operation state).
-- reset-gpio-active-high: If present then the reset sequence using the GPIO
-  specified in the "reset-gpio" property is reversed (H=reset state,
-  L=operation state).
-- vpcie-supply: Should specify the regulator in charge of PCIe port power.
-  The regulator will be enabled when initializing the PCIe host and
-  disabled either as part of the init process or when shutting down the
-  host.
-- vph-supply: Should specify the regulator in charge of VPH one of the three
-  PCIe PHY powers. This regulator can be supplied by both 1.8v and 3.3v voltage
-  supplies.
-
-Additional required properties for imx6sx-pcie:
-- clock names: Must include the following additional entries:
-	- "pcie_inbound_axi"
-- power-domains: Must be set to phandles pointing to the DISPLAY and
-  PCIE_PHY power domains
-- power-domain-names: Must be "pcie", "pcie_phy"
-
-Additional required properties for imx7d-pcie and imx8mq-pcie:
-- power-domains: Must be set to a phandle pointing to PCIE_PHY power domain
-- resets: Must contain phandles to PCIe-related reset lines exposed by SRC
-  IP block
-- reset-names: Must contain the following entries:
-	       - "pciephy"
-	       - "apps"
-	       - "turnoff"
-- fsl,imx7d-pcie-phy: A phandle to an fsl,imx7d-pcie-phy node.
-
-Additional required properties for imx8mq-pcie:
-- clock-names: Must include the following additional entries:
-	- "pcie_aux"
-
-Example:
-
-	pcie at 01000000 {
-		compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
-		reg = <0x01ffc000 0x04000>,
-		      <0x01f00000 0x80000>;
-		reg-names = "dbi", "config";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000
-			  0x81000000 0 0          0x01f80000 0 0x00010000
-			  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
-		num-lanes = <1>;
-		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "msi";
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0x7>;
-		interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-		                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-		                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-		                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clks 144>, <&clks 206>, <&clks 189>;
-		clock-names = "pcie", "pcie_bus", "pcie_phy";
-	};
-
-* Freescale i.MX7d PCIe PHY
-
-This is the PHY associated with the IMX7d PCIe controller.  It's used by the
-PCI-e controller via the fsl,imx7d-pcie-phy phandle.
-
-Required properties:
-- compatible:
-	- "fsl,imx7d-pcie-phy"
-- reg: base address and length of the PCIe PHY controller
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
new file mode 100644
index 000000000000..3503ce3de05d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -0,0 +1,207 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/fsl,imx6q-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX6 PCIe host controller
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+  - Richard Zhu <hongxing.zhu at nxp.com>
+
+description: |+
+  This PCIe host controller is based on the Synopsys DesignWare PCIe IP
+  and thus inherits all the common properties defined in snps,dw-pcie.yaml.
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx6q-pcie
+      - fsl,imx6sx-pcie
+      - fsl,imx6qp-pcie
+      - fsl,imx7d-pcie
+      - fsl,imx8mq-pcie
+
+  reg:
+    items:
+      - description: Data Bus Interface (DBI) registers.
+      - description: PCIe configuration space region.
+
+  reg-names:
+    items:
+      - const: dbi
+      - const: config
+
+  interrupts:
+    minItems: 1
+    items:
+      - description: builtin MSI controller.
+
+  interrupt-names:
+    minItems: 1
+    items:
+      - const: msi
+
+  clocks:
+    minItems: 3
+    maxItems: 4
+    items:
+      - description: PCIe bridge clock.
+      - description: PCIe bus clock.
+      - description: PCIe PHY clock.
+      - description: Additional required clock entry for imx6sx-pcie,
+          imx8mq-pcie.
+
+  clock-names:
+    minItems: 3
+    maxItems: 4
+    items:
+      - const: pcie
+      - const: pcie_bus
+      - const: pcie_phy
+      - const: pcie_inbound_axi for imx6sx-pcie, pcie_aux for imx8mq-pcie
+
+  num-lanes:
+    const: 1
+
+  num-viewport:
+    const: 4
+
+  fsl,imx7d-pcie-phy:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: A phandle to an fsl,imx7d-pcie-phy node. Additional
+      required properties for imx7d-pcie and imx8mq-pcie.
+
+  power-domains:
+    maxItems: 2
+    description: The first phandle pointing to the DISPLAY domain for
+      imx6sx-pcie, to PCIE_PHY power domain for imx7d-pcie and imx8mq-pcie.
+      The second phandle pointing to the PCIE_PHY power domains for imx6sx-pcie.
+
+  power-domain-names:
+    maxItems: 2
+
+  resets:
+    maxItems: 3
+    description: Phandles to PCIe-related reset lines exposed by SRC
+      IP block. Additional required by imx7d-pcie and imx8mq-pcie.
+
+  reset-names:
+    items:
+      - const: pciephy
+      - const: apps
+      - const: turnoff
+
+  fsl,tx-deemph-gen1:
+    description: Gen1 De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  fsl,tx-deemph-gen2-3p5db:
+    description: Gen2 (3.5db) De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  fsl,tx-deemph-gen2-6db:
+    description: Gen2 (6db) De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 20
+
+  fsl,tx-swing-full:
+    description: Gen2 TX SWING FULL value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 127
+
+  fsl,tx-swing-low:
+    description: TX launch amplitude swing_low value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 127
+
+  fsl,max-link-speed:
+    description: Specify PCI Gen for link capability (optional required).
+      Note that the IMX6 LVDS clock outputs do not meet gen2 jitter
+      requirements and thus for gen2 capability a gen2 compliant clock
+      generator should be used and configured.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3, 4]
+    default: 1
+
+  reset-gpio:
+    description: Should specify the GPIO for controlling the PCI bus device
+      reset signal. It's not polarity aware and defaults to active-low reset
+      sequence (L=reset state, H=operation state) (optional required).
+
+  reset-gpio-active-high:
+    description: If present then the reset sequence using the GPIO
+      specified in the "reset-gpio" property is reversed (H=reset state,
+      L=operation state) (optional required).
+
+  vpcie-supply:
+    description: Should specify the regulator in charge of PCIe port power.
+      The regulator will be enabled when initializing the PCIe host and
+      disabled either as part of the init process or when shutting down
+      the host (optional required).
+
+  vph-supply:
+    description: Should specify the regulator in charge of VPH one of
+      the three PCIe PHY powers. This regulator can be supplied by both
+      1.8v and 3.3v voltage supplies (optional required).
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#address-cells"
+  - "#size-cells"
+  - device_type
+  - bus-range
+  - ranges
+  - num-lanes
+  - num-viewport
+  - interrupts
+  - interrupt-names
+  - "#interrupt-cells"
+  - interrupt-map-mask
+  - interrupt-map
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx6qdl-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    pcie: pcie at 1ffc000 {
+        compatible = "fsl,imx6q-pcie";
+        reg = <0x01ffc000 0x04000>,
+              <0x01f00000 0x80000>;
+        reg-names = "dbi", "config";
+        #address-cells = <3>;
+        #size-cells = <2>;
+        device_type = "pci";
+        bus-range = <0x00 0xff>;
+        ranges = <0x81000000 0 0          0x01f80000 0 0x00010000>,
+                 <0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
+        num-lanes = <1>;
+        num-viewport = <4>;
+        interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "msi";
+        #interrupt-cells = <1>;
+        interrupt-map-mask = <0 0 0 0x7>;
+        interrupt-map = <0 0 0 1 &gpc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                        <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                        <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                        <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
+                <&clks IMX6QDL_CLK_LVDS1_GATE>,
+                <&clks IMX6QDL_CLK_PCIE_REF_125M>;
+        clock-names = "pcie", "pcie_bus", "pcie_phy";
+        status = "disabled";
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index f73fef615702..a1e2cc0be9e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14187,7 +14187,7 @@ M:	Lucas Stach <l.stach at pengutronix.de>
 L:	linux-pci at vger.kernel.org
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
-F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
 F:	drivers/pci/controller/dwc/*imx6*
 
 PCI DRIVER FOR FU740
-- 
2.25.1



From hongxing.zhu at nxp.com  Thu Aug 19 00:14:08 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Thu, 19 Aug 2021 15:14:08 +0800
Subject: [PATCH v1 3/3] arm64: dts: imx8mq: fix the schema check errors
In-Reply-To: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
References: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
Message-ID: <20210819071408.3856475-4-hongxing.zhu@nxp.com>

The ranges should be aligned to $ref: /schemas/pci/pci-bus.yaml#

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 91df9c5350ae..45895dad85e1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1364,8 +1364,8 @@ pcie0: pcie at 33800000 {
 			#size-cells = <2>;
 			device_type = "pci";
 			bus-range = <0x00 0xff>;
-			ranges = <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000 /* downstream I/O 64KB */
-			          0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000>, /* downstream I/O 64KB */
+				 <0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
 			num-viewport = <4>;
 			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
@@ -1402,8 +1402,8 @@ pcie1: pcie at 33c00000 {
 			#address-cells = <3>;
 			#size-cells = <2>;
 			device_type = "pci";
-			ranges =  <0x81000000 0 0x00000000 0x27f80000 0 0x00010000 /* downstream I/O 64KB */
-				   0x82000000 0 0x20000000 0x20000000 0 0x07f00000>; /* non-prefetchable memory */
+			ranges =  <0x81000000 0 0x00000000 0x27f80000 0 0x00010000>, /* downstream I/O 64KB */
+				  <0x82000000 0 0x20000000 0x20000000 0 0x07f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
 			num-viewport = <4>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.25.1



From hongxing.zhu at nxp.com  Thu Aug 19 00:14:07 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Thu, 19 Aug 2021 15:14:07 +0800
Subject: [PATCH v1 2/3] arm: dts: imx: fix the schema check errors
In-Reply-To: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
References: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
Message-ID: <20210819071408.3856475-3-hongxing.zhu@nxp.com>

- the ranges should be aligned to $ref: /schemas/pci/pci-bus.yaml#
- num-viewport is required, add it in imx6sx.dtsi.
- only one propert is allowed in the compatible string, remove
  "snps,dw-pcie".

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 6 +++---
 arch/arm/boot/dts/imx6qp.dtsi  | 2 +-
 arch/arm/boot/dts/imx6sx.dtsi  | 7 ++++---
 arch/arm/boot/dts/imx7d.dtsi   | 6 +++---
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 82e01ce026ea..cb43c72806a1 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -264,7 +264,7 @@ L2: cache-controller at a02000 {
 		};
 
 		pcie: pcie at 1ffc000 {
-			compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
+			compatible = "fsl,imx6q-pcie";
 			reg = <0x01ffc000 0x04000>,
 			      <0x01f00000 0x80000>;
 			reg-names = "dbi", "config";
@@ -272,8 +272,8 @@ pcie: pcie at 1ffc000 {
 			#size-cells = <2>;
 			device_type = "pci";
 			bus-range = <0x00 0xff>;
-			ranges = <0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
-				  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0 0          0x01f80000 0 0x00010000>, /* downstream I/O */
+				 <0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
 			num-viewport = <4>;
 			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi
index b310f13a53f2..050365513836 100644
--- a/arch/arm/boot/dts/imx6qp.dtsi
+++ b/arch/arm/boot/dts/imx6qp.dtsi
@@ -110,5 +110,5 @@ &mmdc0 {
 };
 
 &pcie {
-	compatible = "fsl,imx6qp-pcie", "snps,dw-pcie";
+	compatible = "fsl,imx6qp-pcie";
 };
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 8516730778df..0324f9e17389 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -1395,16 +1395,17 @@ pwm8: pwm at 22b0000 {
 		};
 
 		pcie: pcie at 8ffc000 {
-			compatible = "fsl,imx6sx-pcie", "snps,dw-pcie";
+			compatible = "fsl,imx6sx-pcie";
 			reg = <0x08ffc000 0x04000>, <0x08f00000 0x80000>;
 			reg-names = "dbi", "config";
 			#address-cells = <3>;
 			#size-cells = <2>;
 			device_type = "pci";
 			bus-range = <0x00 0xff>;
-			ranges = <0x81000000 0 0          0x08f80000 0 0x00010000 /* downstream I/O */
-				  0x82000000 0 0x08000000 0x08000000 0 0x00f00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0 0          0x08f80000 0 0x00010000>, /* downstream I/O */
+				 <0x82000000 0 0x08000000 0x08000000 0 0x00f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
+			num-viewport = <4>;
 			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
 			#interrupt-cells = <1>;
diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index b0bcfa9094a3..0cb8c8df87ef 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -164,7 +164,7 @@ fec2: ethernet at 30bf0000 {
 	};
 
 	pcie: pcie at 33800000 {
-		compatible = "fsl,imx7d-pcie", "snps,dw-pcie";
+		compatible = "fsl,imx7d-pcie";
 		reg = <0x33800000 0x4000>,
 		      <0x4ff00000 0x80000>;
 		reg-names = "dbi", "config";
@@ -172,8 +172,8 @@ pcie: pcie at 33800000 {
 		#size-cells = <2>;
 		device_type = "pci";
 		bus-range = <0x00 0xff>;
-		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
+		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000>, /* downstream I/O */
+			 <0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
 		num-lanes = <1>;
 		num-viewport = <4>;
 		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.25.1



From steen.hegelund at microchip.com  Thu Aug 19 00:39:40 2021
From: steen.hegelund at microchip.com (Steen Hegelund)
Date: Thu, 19 Aug 2021 09:39:40 +0200
Subject: [PATCH net-next v2 2/2] arm64: dts: sparx5: Add the Sparx5 switch
 frame DMA support
In-Reply-To: <20210819073940.1589383-1-steen.hegelund@microchip.com>
References: <20210819073940.1589383-1-steen.hegelund@microchip.com>
Message-ID: <20210819073940.1589383-3-steen.hegelund@microchip.com>

This adds the interrupt for the Sparx5 Frame DMA.

If this configuration is present the Sparx5 SwitchDev driver will use the
Frame DMA feature, and if not it will use register based injection and
extraction for sending and receiving frames to the CPU.

Signed-off-by: Steen Hegelund <steen.hegelund at microchip.com>
---
 arch/arm64/boot/dts/microchip/sparx5.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/microchip/sparx5.dtsi b/arch/arm64/boot/dts/microchip/sparx5.dtsi
index ad07fff40544..787ebcec121d 100644
--- a/arch/arm64/boot/dts/microchip/sparx5.dtsi
+++ b/arch/arm64/boot/dts/microchip/sparx5.dtsi
@@ -471,8 +471,9 @@ switch: switch at 0x600000000 {
 				<0x6 0x10004000 0x7fc000>,
 				<0x6 0x11010000 0xaf0000>;
 			reg-names = "cpu", "dev", "gcb";
-			interrupt-names = "xtr";
-			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "xtr", "fdma";
+			interrupts =	<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
 			resets = <&reset 0>;
 			reset-names = "switch";
 		};
-- 
2.32.0



From steen.hegelund at microchip.com  Thu Aug 19 00:39:39 2021
From: steen.hegelund at microchip.com (Steen Hegelund)
Date: Thu, 19 Aug 2021 09:39:39 +0200
Subject: [PATCH net-next v2 1/2] net: sparx5: switchdev: adding frame DMA
 functionality
In-Reply-To: <20210819073940.1589383-1-steen.hegelund@microchip.com>
References: <20210819073940.1589383-1-steen.hegelund@microchip.com>
Message-ID: <20210819073940.1589383-2-steen.hegelund@microchip.com>

This add frame DMA functionality to the Sparx5 platform.

Ethernet frames can be extracted or injected autonomously to or from the
device?s DDR3/DDR3L memory and/or PCIe memory space. Linked list data
structures in memory are used for injecting or extracting Ethernet frames.
The FDMA generates interrupts when frame extraction or injection is done
and when the linked lists need updating.

The FDMA implements two extraction channels, one per switch core port
towards the VCore CPU system and a total of six injection channels.
Extraction channels are mapped one-to-one to the CPU ports, while injection
channels can be individually assigned to any CPU port.

- FDMA channel 0 through 5 corresponds to CPU port 0 injection direction
  FDMA_CH_CFG[channel].CH_INJ_PORT is set to 0.
- FDMA channel 0 through 5 corresponds to CPU port 1 injection direction when
  FDMA_CH_CFG[channel].CH_INJ_PORT is set to 1.
- FDMA channel 6 corresponds to CPU port 0 extraction direction.
- FDMA channel 7 corresponds to CPU port 1 extraction direction.

The FDMA implements a strict priority scheme among channels. Extraction
channels are prioritized over injection channels and secondarily channels
with higher channel number are prioritized over channels with lower number.
On the other hand, ports are being served on an equal-bandwidth principle
both on injection and extraction directions.  The equal-bandwidth principle
will not force an equal bandwidth. Instead, it ensures that the ports
perform at their best considering the operating conditions.

When more than one injection channel is enabled for injection on the same
CPU port, priority determines which channel can inject data. Ownership
is re-arbitrated on frame boundaries.

The FDMA processes linked lists of DMA Control Block Structures (DCBs). The
DCBs have the same basic structure for both injection and extraction. A DCB
must be placed on a 64-bit word-aligned address in memory. Each DCB has a
per-channel configurable amount of associated data blocks in memory, where
the frame data is stored.

The data blocks that are used by extraction channels must be placed on
64-bit word aligned addresses in memory, and their length must be a
multiple of 128 bytes.

A DCB carries the pointer to the next DCB of the linked list, the INFO word
which holds information for the DCB, and a pair of status word and memory
pointer for every data block that it is associated with.

Signed-off-by: Steen Hegelund <steen.hegelund at microchip.com>
---
 .../net/ethernet/microchip/sparx5/Makefile    |   2 +-
 .../ethernet/microchip/sparx5/sparx5_fdma.c   | 593 ++++++++++++++++++
 .../ethernet/microchip/sparx5/sparx5_main.c   |  23 +-
 .../ethernet/microchip/sparx5/sparx5_main.h   |  69 ++
 .../ethernet/microchip/sparx5/sparx5_packet.c |  13 +-
 .../ethernet/microchip/sparx5/sparx5_port.c   |   2 +-
 .../ethernet/microchip/sparx5/sparx5_port.h   |   1 +
 7 files changed, 693 insertions(+), 10 deletions(-)
 create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c

diff --git a/drivers/net/ethernet/microchip/sparx5/Makefile b/drivers/net/ethernet/microchip/sparx5/Makefile
index faa8f07a6b75..c271e86ee292 100644
--- a/drivers/net/ethernet/microchip/sparx5/Makefile
+++ b/drivers/net/ethernet/microchip/sparx5/Makefile
@@ -7,4 +7,4 @@ obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o
 
 sparx5-switch-objs  := sparx5_main.o sparx5_packet.o \
  sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \
- sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o
+ sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o sparx5_fdma.o
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
new file mode 100644
index 000000000000..7436f62fa152
--- /dev/null
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
@@ -0,0 +1,593 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Microchip Sparx5 Switch driver
+ *
+ * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
+ *
+ * The Sparx5 Chip Register Model can be browsed at this location:
+ * https://github.com/microchip-ung/sparx-5_reginfo
+ */
+
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/ip.h>
+#include <linux/dma-mapping.h>
+
+#include "sparx5_main_regs.h"
+#include "sparx5_main.h"
+#include "sparx5_port.h"
+
+#define FDMA_XTR_CHANNEL		6
+#define FDMA_INJ_CHANNEL		0
+
+#define FDMA_DCB_INFO_DATAL(x)		((x) & GENMASK(15, 0))
+#define FDMA_DCB_INFO_TOKEN		BIT(17)
+#define FDMA_DCB_INFO_INTR		BIT(18)
+#define FDMA_DCB_INFO_SW(x)		(((x) << 24) & GENMASK(31, 24))
+
+#define FDMA_DCB_STATUS_BLOCKL(x)	((x) & GENMASK(15, 0))
+#define FDMA_DCB_STATUS_SOF		BIT(16)
+#define FDMA_DCB_STATUS_EOF		BIT(17)
+#define FDMA_DCB_STATUS_INTR		BIT(18)
+#define FDMA_DCB_STATUS_DONE		BIT(19)
+#define FDMA_DCB_STATUS_BLOCKO(x)	(((x) << 20) & GENMASK(31, 20))
+#define FDMA_DCB_INVALID_DATA		0x1
+
+#define FDMA_XTR_BUFFER_SIZE		2048
+#define FDMA_WEIGHT			4
+
+/* Frame DMA DCB format
+ *
+ * +---------------------------+
+ * |         Next Ptr          |
+ * +---------------------------+
+ * |   Reserved  |    Info     |
+ * +---------------------------+
+ * |         Data0 Ptr         |
+ * +---------------------------+
+ * |   Reserved  |    Status0  |
+ * +---------------------------+
+ * |         Data1 Ptr         |
+ * +---------------------------+
+ * |   Reserved  |    Status1  |
+ * +---------------------------+
+ * |         Data2 Ptr         |
+ * +---------------------------+
+ * |   Reserved  |    Status2  |
+ * |-------------|-------------|
+ * |                           |
+ * |                           |
+ * |                           |
+ * |                           |
+ * |                           |
+ * |---------------------------|
+ * |         Data14 Ptr        |
+ * +-------------|-------------+
+ * |   Reserved  |    Status14 |
+ * +-------------|-------------+
+ */
+
+/* For each hardware DB there is an entry in this list and when the HW DB
+ * entry is used, this SW DB entry is moved to the back of the list
+ */
+struct sparx5_db {
+	struct list_head list;
+	void *cpu_addr;
+};
+
+static void sparx5_fdma_rx_add_dcb(struct sparx5_rx *rx,
+				   struct sparx5_rx_dcb_hw *dcb,
+				   u64 nextptr)
+{
+	int idx = 0;
+
+	/* Reset the status of the DB */
+	for (idx = 0; idx < FDMA_RX_DCB_MAX_DBS; ++idx) {
+		struct sparx5_db_hw *db = &dcb->db[idx];
+
+		db->status = FDMA_DCB_STATUS_INTR;
+	}
+	dcb->nextptr = FDMA_DCB_INVALID_DATA;
+	dcb->info = FDMA_DCB_INFO_DATAL(FDMA_XTR_BUFFER_SIZE);
+	rx->last_entry->nextptr = nextptr;
+	rx->last_entry = dcb;
+}
+
+static void sparx5_fdma_tx_add_dcb(struct sparx5_tx *tx,
+				   struct sparx5_tx_dcb_hw *dcb,
+				   u64 nextptr)
+{
+	int idx = 0;
+
+	/* Reset the status of the DB */
+	for (idx = 0; idx < FDMA_TX_DCB_MAX_DBS; ++idx) {
+		struct sparx5_db_hw *db = &dcb->db[idx];
+
+		db->status = FDMA_DCB_STATUS_DONE;
+	}
+	dcb->nextptr = FDMA_DCB_INVALID_DATA;
+	dcb->info = FDMA_DCB_INFO_DATAL(FDMA_XTR_BUFFER_SIZE);
+}
+
+static void sparx5_fdma_rx_activate(struct sparx5 *sparx5, struct sparx5_rx *rx)
+{
+	/* Write the buffer address in the LLP and LLP1 regs */
+	spx5_wr(((u64)rx->dma) & GENMASK(31, 0), sparx5,
+		FDMA_DCB_LLP(rx->channel_id));
+	spx5_wr(((u64)rx->dma) >> 32, sparx5, FDMA_DCB_LLP1(rx->channel_id));
+
+	/* Set the number of RX DBs to be used, and DB end-of-frame interrupt */
+	spx5_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_RX_DCB_MAX_DBS) |
+		FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) |
+		FDMA_CH_CFG_CH_INJ_PORT_SET(XTR_QUEUE),
+		sparx5, FDMA_CH_CFG(rx->channel_id));
+
+	/* Set the RX Watermark to max */
+	spx5_rmw(FDMA_XTR_CFG_XTR_FIFO_WM_SET(31), FDMA_XTR_CFG_XTR_FIFO_WM,
+		 sparx5,
+		 FDMA_XTR_CFG);
+
+	/* Start RX fdma */
+	spx5_rmw(FDMA_PORT_CTRL_XTR_STOP_SET(0), FDMA_PORT_CTRL_XTR_STOP,
+		 sparx5, FDMA_PORT_CTRL(0));
+
+	/* Enable RX channel DB interrupt */
+	spx5_rmw(BIT(rx->channel_id),
+		 BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
+		 sparx5, FDMA_INTR_DB_ENA);
+
+	/* Activate the RX channel */
+	spx5_wr(BIT(rx->channel_id), sparx5, FDMA_CH_ACTIVATE);
+}
+
+static void sparx5_fdma_rx_deactivate(struct sparx5 *sparx5, struct sparx5_rx *rx)
+{
+	/* Dectivate the RX channel */
+	spx5_rmw(0, BIT(rx->channel_id) & FDMA_CH_ACTIVATE_CH_ACTIVATE,
+		 sparx5, FDMA_CH_ACTIVATE);
+
+	/* Disable RX channel DB interrupt */
+	spx5_rmw(0, BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
+		 sparx5, FDMA_INTR_DB_ENA);
+
+	/* Stop RX fdma */
+	spx5_rmw(FDMA_PORT_CTRL_XTR_STOP_SET(1), FDMA_PORT_CTRL_XTR_STOP,
+		 sparx5, FDMA_PORT_CTRL(0));
+}
+
+static void sparx5_fdma_tx_activate(struct sparx5 *sparx5, struct sparx5_tx *tx)
+{
+	/* Write the buffer address in the LLP and LLP1 regs */
+	spx5_wr(((u64)tx->dma) & GENMASK(31, 0), sparx5,
+		FDMA_DCB_LLP(tx->channel_id));
+	spx5_wr(((u64)tx->dma) >> 32, sparx5, FDMA_DCB_LLP1(tx->channel_id));
+
+	/* Set the number of TX DBs to be used, and DB end-of-frame interrupt */
+	spx5_wr(FDMA_CH_CFG_CH_DCB_DB_CNT_SET(FDMA_TX_DCB_MAX_DBS) |
+		FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY_SET(1) |
+		FDMA_CH_CFG_CH_INJ_PORT_SET(INJ_QUEUE),
+		sparx5, FDMA_CH_CFG(tx->channel_id));
+
+	/* Start TX fdma */
+	spx5_rmw(FDMA_PORT_CTRL_INJ_STOP_SET(0), FDMA_PORT_CTRL_INJ_STOP,
+		 sparx5, FDMA_PORT_CTRL(0));
+
+	/* Activate the channel */
+	spx5_wr(BIT(tx->channel_id), sparx5, FDMA_CH_ACTIVATE);
+}
+
+static void sparx5_fdma_tx_deactivate(struct sparx5 *sparx5, struct sparx5_tx *tx)
+{
+	/* Disable the channel */
+	spx5_rmw(0, BIT(tx->channel_id) & FDMA_CH_ACTIVATE_CH_ACTIVATE,
+		 sparx5, FDMA_CH_ACTIVATE);
+}
+
+static void sparx5_fdma_rx_reload(struct sparx5 *sparx5, struct sparx5_rx *rx)
+{
+	/* Reload the RX channel */
+	spx5_wr(BIT(rx->channel_id), sparx5, FDMA_CH_RELOAD);
+}
+
+static void sparx5_fdma_tx_reload(struct sparx5 *sparx5, struct sparx5_tx *tx)
+{
+	/* Reload the TX channel */
+	spx5_wr(BIT(tx->channel_id), sparx5, FDMA_CH_RELOAD);
+}
+
+static struct sk_buff *sparx5_fdma_rx_alloc_skb(struct sparx5_rx *rx)
+{
+	return __netdev_alloc_skb(rx->ndev, FDMA_XTR_BUFFER_SIZE,
+				  GFP_ATOMIC);
+}
+
+static bool sparx5_fdma_rx_get_frame(struct sparx5 *sparx5, struct sparx5_rx *rx)
+{
+	struct sparx5_db_hw *db_hw;
+	unsigned int packet_size;
+	struct sparx5_port *port;
+	struct sk_buff *new_skb;
+	struct frame_info fi;
+	struct sk_buff *skb;
+	dma_addr_t dma_addr;
+
+	/* Check if the DCB is done */
+	db_hw = &rx->dcb_entries[rx->dcb_index].db[rx->db_index];
+	if (unlikely(!(db_hw->status & FDMA_DCB_STATUS_DONE)))
+		return false;
+	skb = rx->skb[rx->dcb_index][rx->db_index];
+	/* Replace the DB entry with a new SKB */
+	new_skb = sparx5_fdma_rx_alloc_skb(rx);
+	if (unlikely(!new_skb))
+		return false;
+	/* Map the new skb data and set the new skb */
+	dma_addr = virt_to_phys(new_skb->data);
+	rx->skb[rx->dcb_index][rx->db_index] = new_skb;
+	db_hw->dataptr = dma_addr;
+	packet_size = FDMA_DCB_STATUS_BLOCKL(db_hw->status);
+	skb_put(skb, packet_size);
+	/* Now do the normal processing of the skb */
+	sparx5_ifh_parse((u32 *)skb->data, &fi);
+	/* Map to port netdev */
+	port = fi.src_port < SPX5_PORTS ?  sparx5->ports[fi.src_port] : NULL;
+	if (!port || !port->ndev) {
+		dev_err(sparx5->dev, "Data on inactive port %d\n", fi.src_port);
+		sparx5_xtr_flush(sparx5, XTR_QUEUE);
+		return false;
+	}
+	skb->dev = port->ndev;
+	skb_pull(skb, IFH_LEN * sizeof(u32));
+	if (likely(!(skb->dev->features & NETIF_F_RXFCS)))
+		skb_trim(skb, skb->len - ETH_FCS_LEN);
+	skb->protocol = eth_type_trans(skb, skb->dev);
+	/* Everything we see on an interface that is in the HW bridge
+	 * has already been forwarded
+	 */
+	if (test_bit(port->portno, sparx5->bridge_mask))
+		skb->offload_fwd_mark = 1;
+	skb->dev->stats.rx_bytes += skb->len;
+	skb->dev->stats.rx_packets++;
+	rx->packets++;
+	netif_receive_skb(skb);
+	return true;
+}
+
+static int sparx5_fdma_napi_callback(struct napi_struct *napi, int weight)
+{
+	struct sparx5_rx *rx = container_of(napi, struct sparx5_rx, napi);
+	struct sparx5 *sparx5 = container_of(rx, struct sparx5, rx);
+	int counter = 0;
+
+	while (counter < weight && sparx5_fdma_rx_get_frame(sparx5, rx)) {
+		struct sparx5_rx_dcb_hw *old_dcb;
+
+		rx->db_index++;
+		counter++;
+		/* Check if the DCB can be reused */
+		if (rx->db_index != FDMA_RX_DCB_MAX_DBS)
+			continue;
+		/* As the DCB  can be reused, just advance the dcb_index
+		 * pointer and set the nextptr in the DCB
+		 */
+		rx->db_index = 0;
+		old_dcb = &rx->dcb_entries[rx->dcb_index];
+		rx->dcb_index++;
+		rx->dcb_index &= FDMA_DCB_MAX - 1;
+		sparx5_fdma_rx_add_dcb(rx, old_dcb,
+				       rx->dma +
+				       ((unsigned long)old_dcb -
+					(unsigned long)rx->dcb_entries));
+	}
+	if (counter < weight) {
+		napi_complete_done(&rx->napi, counter);
+		spx5_rmw(BIT(rx->channel_id),
+			 BIT(rx->channel_id) & FDMA_INTR_DB_ENA_INTR_DB_ENA,
+			 sparx5, FDMA_INTR_DB_ENA);
+	}
+	if (counter)
+		sparx5_fdma_rx_reload(sparx5, rx);
+	return counter;
+}
+
+static struct sparx5_tx_dcb_hw *sparx5_fdma_next_dcb(struct sparx5_tx *tx,
+						     struct sparx5_tx_dcb_hw *dcb)
+{
+	struct sparx5_tx_dcb_hw *next_dcb;
+
+	next_dcb = dcb;
+	next_dcb++;
+	/* Handle wrap-around */
+	if ((unsigned long)next_dcb >=
+	    ((unsigned long)tx->first_entry + FDMA_DCB_MAX * sizeof(*dcb)))
+		next_dcb = tx->first_entry;
+	return next_dcb;
+}
+
+int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb)
+{
+	struct sparx5_tx_dcb_hw *next_dcb_hw;
+	struct sparx5_tx *tx = &sparx5->tx;
+	static bool first_time = true;
+	struct sparx5_db_hw *db_hw;
+	struct sparx5_db *db;
+
+	next_dcb_hw = sparx5_fdma_next_dcb(tx, tx->curr_entry);
+	db_hw = &next_dcb_hw->db[0];
+	if (!(db_hw->status & FDMA_DCB_STATUS_DONE))
+		tx->dropped++;
+	db = list_first_entry(&tx->db_list, struct sparx5_db, list);
+	list_move_tail(&db->list, &tx->db_list);
+	next_dcb_hw->nextptr = FDMA_DCB_INVALID_DATA;
+	tx->curr_entry->nextptr = tx->dma +
+		((unsigned long)next_dcb_hw -
+		 (unsigned long)tx->first_entry);
+	tx->curr_entry = next_dcb_hw;
+	memset(db->cpu_addr, 0, FDMA_XTR_BUFFER_SIZE);
+	memcpy(db->cpu_addr, ifh, IFH_LEN * 4);
+	memcpy(db->cpu_addr + IFH_LEN * 4, skb->data, skb->len);
+	db_hw->status = FDMA_DCB_STATUS_SOF |
+			FDMA_DCB_STATUS_EOF |
+			FDMA_DCB_STATUS_BLOCKO(0) |
+			FDMA_DCB_STATUS_BLOCKL(skb->len + IFH_LEN * 4 + 4);
+	if (first_time) {
+		sparx5_fdma_tx_activate(sparx5, tx);
+		first_time = false;
+	} else {
+		sparx5_fdma_tx_reload(sparx5, tx);
+	}
+	return NETDEV_TX_OK;
+}
+
+static int sparx5_fdma_rx_alloc(struct sparx5 *sparx5)
+{
+	struct sparx5_rx *rx = &sparx5->rx;
+	struct sparx5_rx_dcb_hw *dcb;
+	int idx, jdx;
+	int size;
+
+	size = sizeof(struct sparx5_rx_dcb_hw) * FDMA_DCB_MAX;
+	size = ALIGN(size, PAGE_SIZE);
+	rx->dcb_entries = devm_kzalloc(sparx5->dev, size, GFP_KERNEL);
+	if (!rx->dcb_entries)
+		return -ENOMEM;
+	rx->dma = virt_to_phys(rx->dcb_entries);
+	rx->last_entry = rx->dcb_entries;
+	rx->db_index = 0;
+	rx->dcb_index = 0;
+	/* Now for each dcb allocate the db */
+	for (idx = 0; idx < FDMA_DCB_MAX; ++idx) {
+		dcb = &rx->dcb_entries[idx];
+		dcb->info = 0;
+		/* For each db allocate an skb and map skb data pointer to the DB
+		 * dataptr. In this way when the frame is received the skb->data
+		 * will contain the frame, so no memcpy is needed
+		 */
+		for (jdx = 0; jdx < FDMA_RX_DCB_MAX_DBS; ++jdx) {
+			struct sparx5_db_hw *db_hw = &dcb->db[jdx];
+			dma_addr_t dma_addr;
+			struct sk_buff *skb;
+
+			skb = sparx5_fdma_rx_alloc_skb(rx);
+			if (!skb)
+				return -ENOMEM;
+
+			dma_addr = virt_to_phys(skb->data);
+			db_hw->dataptr = dma_addr;
+			db_hw->status = 0;
+			rx->skb[idx][jdx] = skb;
+		}
+		sparx5_fdma_rx_add_dcb(rx, dcb, rx->dma + sizeof(*dcb) * idx);
+	}
+	netif_napi_add(rx->ndev, &rx->napi, sparx5_fdma_napi_callback, FDMA_WEIGHT);
+	napi_enable(&rx->napi);
+	sparx5_fdma_rx_activate(sparx5, rx);
+	return 0;
+}
+
+static int sparx5_fdma_tx_alloc(struct sparx5 *sparx5)
+{
+	struct sparx5_tx *tx = &sparx5->tx;
+	struct sparx5_tx_dcb_hw *dcb;
+	int idx, jdx;
+	int size;
+
+	size = sizeof(struct sparx5_tx_dcb_hw) * FDMA_DCB_MAX;
+	size = ALIGN(size, PAGE_SIZE);
+	tx->curr_entry = devm_kzalloc(sparx5->dev, size, GFP_KERNEL);
+	if (!tx->curr_entry)
+		return -ENOMEM;
+	tx->dma = virt_to_phys(tx->curr_entry);
+	tx->first_entry = tx->curr_entry;
+	INIT_LIST_HEAD(&tx->db_list);
+	/* Now for each dcb allocate the db */
+	for (idx = 0; idx < FDMA_DCB_MAX; ++idx) {
+		dcb = &tx->curr_entry[idx];
+		dcb->info = 0;
+		/* TX databuffers must be 16byte aligned */
+		for (jdx = 0; jdx < FDMA_TX_DCB_MAX_DBS; ++jdx) {
+			struct sparx5_db_hw *db_hw = &dcb->db[jdx];
+			struct sparx5_db *db;
+			dma_addr_t phys;
+			void *cpu_addr;
+
+			cpu_addr = devm_kzalloc(sparx5->dev,
+						FDMA_XTR_BUFFER_SIZE,
+						GFP_KERNEL);
+			if (!cpu_addr)
+				return -ENOMEM;
+			phys = virt_to_phys(cpu_addr);
+			db_hw->dataptr = phys;
+			db_hw->status = 0;
+			db = devm_kzalloc(sparx5->dev, sizeof(*db), GFP_KERNEL);
+			db->cpu_addr = cpu_addr;
+			list_add_tail(&db->list, &tx->db_list);
+		}
+		sparx5_fdma_tx_add_dcb(tx, dcb, tx->dma + sizeof(*dcb) * idx);
+		/* Let the curr_entry to point to the last allocated entry */
+		if (idx == FDMA_DCB_MAX - 1)
+			tx->curr_entry = dcb;
+	}
+	return 0;
+}
+
+static void sparx5_fdma_rx_init(struct sparx5 *sparx5,
+				struct sparx5_rx *rx, int channel)
+{
+	int idx;
+
+	rx->channel_id = channel;
+	/* Fetch a netdev for SKB and NAPI use, any will do */
+	for (idx = 0; idx < SPX5_PORTS; ++idx) {
+		struct sparx5_port *port = sparx5->ports[idx];
+
+		if (port && port->ndev) {
+			rx->ndev = port->ndev;
+			break;
+		}
+	}
+}
+
+static void sparx5_fdma_tx_init(struct sparx5 *sparx5,
+				struct sparx5_tx *tx, int channel)
+{
+	tx->channel_id = channel;
+}
+
+irqreturn_t sparx5_fdma_handler(int irq, void *args)
+{
+	struct sparx5 *sparx5 = args;
+	u32 db = 0, err = 0;
+
+	db = spx5_rd(sparx5, FDMA_INTR_DB);
+	err = spx5_rd(sparx5, FDMA_INTR_ERR);
+	/* Clear interrupt */
+	if (db) {
+		spx5_wr(0, sparx5, FDMA_INTR_DB_ENA);
+		spx5_wr(db, sparx5, FDMA_INTR_DB);
+		napi_schedule(&sparx5->rx.napi);
+	}
+	if (err) {
+		u32 err_type = spx5_rd(sparx5, FDMA_ERRORS);
+
+		dev_err_ratelimited(sparx5->dev,
+				    "ERR: int: %#x, type: %#x\n",
+				    err, err_type);
+		spx5_wr(err, sparx5, FDMA_INTR_ERR);
+		spx5_wr(err_type, sparx5, FDMA_ERRORS);
+	}
+	return IRQ_HANDLED;
+}
+
+static void sparx5_fdma_injection_mode(struct sparx5 *sparx5)
+{
+	const int byte_swap = 1;
+	int portno;
+	int urgency;
+
+	/* Change mode to fdma extraction and injection */
+	spx5_wr(QS_XTR_GRP_CFG_MODE_SET(2) |
+		QS_XTR_GRP_CFG_STATUS_WORD_POS_SET(1) |
+		QS_XTR_GRP_CFG_BYTE_SWAP_SET(byte_swap),
+		sparx5, QS_XTR_GRP_CFG(XTR_QUEUE));
+	spx5_wr(QS_INJ_GRP_CFG_MODE_SET(2) |
+		QS_INJ_GRP_CFG_BYTE_SWAP_SET(byte_swap),
+		sparx5, QS_INJ_GRP_CFG(INJ_QUEUE));
+
+	/* CPU ports capture setup */
+	for (portno = SPX5_PORT_CPU_0; portno <= SPX5_PORT_CPU_1; portno++) {
+		/* ASM CPU port: No preamble, IFH, enable padding */
+		spx5_wr(ASM_PORT_CFG_PAD_ENA_SET(1) |
+			ASM_PORT_CFG_NO_PREAMBLE_ENA_SET(1) |
+			ASM_PORT_CFG_INJ_FORMAT_CFG_SET(1), /* 1 = IFH */
+			sparx5, ASM_PORT_CFG(portno));
+
+		/* Reset WM cnt to unclog queued frames */
+		spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_CNT_CLR_SET(1),
+			 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_CNT_CLR,
+			 sparx5,
+			 DSM_DEV_TX_STOP_WM_CFG(portno));
+
+		/* Set Disassembler Stop Watermark level */
+		spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM_SET(100),
+			 DSM_DEV_TX_STOP_WM_CFG_DEV_TX_STOP_WM,
+			 sparx5,
+			 DSM_DEV_TX_STOP_WM_CFG(portno));
+
+		/* Enable port in queue system */
+		urgency = sparx5_port_fwd_urg(sparx5, SPEED_2500);
+		spx5_rmw(QFWD_SWITCH_PORT_MODE_PORT_ENA_SET(1) |
+			 QFWD_SWITCH_PORT_MODE_FWD_URGENCY_SET(urgency),
+			 QFWD_SWITCH_PORT_MODE_PORT_ENA |
+			 QFWD_SWITCH_PORT_MODE_FWD_URGENCY,
+			 sparx5,
+			 QFWD_SWITCH_PORT_MODE(portno));
+
+		/* Disable Disassembler buffer underrun watchdog
+		 * to avoid truncated packets in XTR
+		 */
+		spx5_rmw(DSM_BUF_CFG_UNDERFLOW_WATCHDOG_DIS_SET(1),
+			 DSM_BUF_CFG_UNDERFLOW_WATCHDOG_DIS,
+			 sparx5,
+			 DSM_BUF_CFG(portno));
+
+		/* Disabling frame aging */
+		spx5_rmw(HSCH_PORT_MODE_AGE_DIS_SET(1),
+			 HSCH_PORT_MODE_AGE_DIS,
+			 sparx5,
+			 HSCH_PORT_MODE(portno));
+	}
+}
+
+int sparx5_fdma_start(struct sparx5 *sparx5)
+{
+	int err;
+
+	/* Reset FDMA state */
+	spx5_wr(FDMA_CTRL_NRESET_SET(0), sparx5, FDMA_CTRL);
+	spx5_wr(FDMA_CTRL_NRESET_SET(1), sparx5, FDMA_CTRL);
+
+	/* Force ACP caching but disable read/write allocation */
+	spx5_rmw(CPU_PROC_CTRL_ACP_CACHE_FORCE_ENA_SET(1) |
+		 CPU_PROC_CTRL_ACP_AWCACHE_SET(0) |
+		 CPU_PROC_CTRL_ACP_ARCACHE_SET(0),
+		 CPU_PROC_CTRL_ACP_CACHE_FORCE_ENA |
+		 CPU_PROC_CTRL_ACP_AWCACHE |
+		 CPU_PROC_CTRL_ACP_ARCACHE,
+		 sparx5, CPU_PROC_CTRL);
+
+	sparx5_fdma_injection_mode(sparx5);
+	sparx5_fdma_rx_init(sparx5, &sparx5->rx, FDMA_XTR_CHANNEL);
+	sparx5_fdma_tx_init(sparx5, &sparx5->tx, FDMA_INJ_CHANNEL);
+	err = sparx5_fdma_rx_alloc(sparx5);
+	if (err) {
+		dev_err(sparx5->dev, "Could not allocate RX buffers: %d\n", err);
+		return err;
+	}
+	err = sparx5_fdma_tx_alloc(sparx5);
+	if (err) {
+		dev_err(sparx5->dev, "Could not allocate TX buffers: %d\n", err);
+		return err;
+	}
+	return err;
+}
+
+static u32 sparx5_fdma_port_ctrl(struct sparx5 *sparx5)
+{
+	return spx5_rd(sparx5, FDMA_PORT_CTRL(0));
+}
+
+int sparx5_fdma_stop(struct sparx5 *sparx5)
+{
+	u32 val;
+
+	napi_disable(&sparx5->rx.napi);
+	/* Stop the fdma and channel interrupts */
+	sparx5_fdma_rx_deactivate(sparx5, &sparx5->rx);
+	sparx5_fdma_tx_deactivate(sparx5, &sparx5->tx);
+	/* Wait for the RX channel to stop */
+	read_poll_timeout(sparx5_fdma_port_ctrl, val,
+			  FDMA_PORT_CTRL_XTR_BUF_IS_EMPTY_GET(val) == 0,
+			  500, 10000, 0, sparx5);
+	return 0;
+}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index f666133a15de..cbece6e9bff2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -640,8 +640,23 @@ static int sparx5_start(struct sparx5 *sparx5)
 	sparx5_board_init(sparx5);
 	err = sparx5_register_notifier_blocks(sparx5);
 
-	/* Start register based INJ/XTR */
+	/* Start Frame DMA with fallback to register based INJ/XTR */
 	err = -ENXIO;
+	if (sparx5->fdma_irq >= 0) {
+		if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0)
+			err = devm_request_threaded_irq(sparx5->dev,
+							sparx5->fdma_irq,
+							NULL,
+							sparx5_fdma_handler,
+							IRQF_ONESHOT,
+							"sparx5-fdma", sparx5);
+		if (!err)
+			err = sparx5_fdma_start(sparx5);
+		if (err)
+			sparx5->fdma_irq = -ENXIO;
+	} else {
+		sparx5->fdma_irq = -ENXIO;
+	}
 	if (err && sparx5->xtr_irq >= 0) {
 		err = devm_request_irq(sparx5->dev, sparx5->xtr_irq,
 				       sparx5_xtr_handler, IRQF_SHARED,
@@ -766,6 +781,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
 		sparx5->base_mac[5] = 0;
 	}
 
+	sparx5->fdma_irq = platform_get_irq_byname(sparx5->pdev, "fdma");
 	sparx5->xtr_irq = platform_get_irq_byname(sparx5->pdev, "xtr");
 
 	/* Read chip ID to check CPU interface */
@@ -824,6 +840,11 @@ static int mchp_sparx5_remove(struct platform_device *pdev)
 		disable_irq(sparx5->xtr_irq);
 		sparx5->xtr_irq = -ENXIO;
 	}
+	if (sparx5->fdma_irq) {
+		disable_irq(sparx5->fdma_irq);
+		sparx5->fdma_irq = -ENXIO;
+	}
+	sparx5_fdma_stop(sparx5);
 	sparx5_cleanup_ports(sparx5);
 	/* Unregister netdevs */
 	sparx5_unregister_notifier_blocks(sparx5);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 4d5f44c3a421..a1acc9b461f2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -73,8 +73,61 @@ enum sparx5_vlan_port_type {
 #define XTR_QUEUE     0
 #define INJ_QUEUE     0
 
+#define FDMA_DCB_MAX			64
+#define FDMA_RX_DCB_MAX_DBS		15
+#define FDMA_TX_DCB_MAX_DBS		1
+
 struct sparx5;
 
+struct sparx5_db_hw {
+	u64 dataptr;
+	u64 status;
+};
+
+struct sparx5_rx_dcb_hw {
+	u64 nextptr;
+	u64 info;
+	struct sparx5_db_hw db[FDMA_RX_DCB_MAX_DBS];
+};
+
+struct sparx5_tx_dcb_hw {
+	u64 nextptr;
+	u64 info;
+	struct sparx5_db_hw db[FDMA_TX_DCB_MAX_DBS];
+};
+
+/* Frame DMA receive state:
+ * For each DB, there is a SKB, and the skb data pointer is mapped in
+ * the DB. Once a frame is received the skb is given to the upper layers
+ * and a new skb is added to the dcb.
+ * When the db_index reached FDMA_RX_DCB_MAX_DBS the DB is reused.
+ */
+struct sparx5_rx {
+	struct sparx5_rx_dcb_hw *dcb_entries;
+	struct sparx5_rx_dcb_hw *last_entry;
+	struct sk_buff *skb[FDMA_DCB_MAX][FDMA_RX_DCB_MAX_DBS];
+	int db_index;
+	int dcb_index;
+	dma_addr_t dma;
+	struct napi_struct napi;
+	u32 channel_id;
+	struct net_device *ndev;
+	u64 packets;
+};
+
+/* Frame DMA transmit state:
+ * DCBs are chained using the DCBs nextptr field.
+ */
+struct sparx5_tx {
+	struct sparx5_tx_dcb_hw *curr_entry;
+	struct sparx5_tx_dcb_hw *first_entry;
+	struct list_head db_list;
+	dma_addr_t dma;
+	u32 channel_id;
+	u64 packets;
+	u64 dropped;
+};
+
 struct sparx5_port_config {
 	phy_interface_t portmode;
 	u32 bandwidth;
@@ -167,6 +220,10 @@ struct sparx5 {
 	bool sd_sgpio_remapping;
 	/* Register based inj/xtr */
 	int xtr_irq;
+	/* Frame DMA */
+	int fdma_irq;
+	struct sparx5_rx rx;
+	struct sparx5_tx tx;
 };
 
 /* sparx5_switchdev.c */
@@ -174,11 +231,23 @@ int sparx5_register_notifier_blocks(struct sparx5 *sparx5);
 void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5);
 
 /* sparx5_packet.c */
+struct frame_info {
+	int src_port;
+};
+
+void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp);
+void sparx5_ifh_parse(u32 *ifh, struct frame_info *info);
 irqreturn_t sparx5_xtr_handler(int irq, void *_priv);
 int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev);
 int sparx5_manual_injection_mode(struct sparx5 *sparx5);
 void sparx5_port_inj_timer_setup(struct sparx5_port *port);
 
+/* sparx5_fdma.c */
+int sparx5_fdma_start(struct sparx5 *sparx5);
+int sparx5_fdma_stop(struct sparx5 *sparx5);
+int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb);
+irqreturn_t sparx5_fdma_handler(int irq, void *args);
+
 /* sparx5_mactable.c */
 void sparx5_mact_pull_work(struct work_struct *work);
 int sparx5_mact_learn(struct sparx5 *sparx5, int port,
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
index 09ca7a3bafdc..dc7e5ea6ec15 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
@@ -20,11 +20,7 @@
 
 #define INJ_TIMEOUT_NS 50000
 
-struct frame_info {
-	int src_port;
-};
-
-static void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp)
+void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp)
 {
 	/* Start flush */
 	spx5_wr(QS_XTR_FLUSH_FLUSH_SET(BIT(grp)), sparx5, QS_XTR_FLUSH);
@@ -36,7 +32,7 @@ static void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp)
 	spx5_wr(0, sparx5, QS_XTR_FLUSH);
 }
 
-static void sparx5_ifh_parse(u32 *ifh, struct frame_info *info)
+void sparx5_ifh_parse(u32 *ifh, struct frame_info *info)
 {
 	u8 *xtr_hdr = (u8 *)ifh;
 
@@ -224,7 +220,10 @@ int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
 	struct sparx5 *sparx5 = port->sparx5;
 	int ret;
 
-	ret = sparx5_inject(sparx5, port->ifh, skb, dev);
+	if (sparx5->fdma_irq > 0)
+		ret = sparx5_fdma_xmit(sparx5, port->ifh, skb);
+	else
+		ret = sparx5_inject(sparx5, port->ifh, skb, dev);
 
 	if (ret == NETDEV_TX_OK) {
 		stats->tx_bytes += skb->len;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index d2e3250928bf..189a6a0a2e08 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -596,7 +596,7 @@ static int sparx5_port_max_tags_set(struct sparx5 *sparx5,
 	return 0;
 }
 
-static int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed)
+int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed)
 {
 	u32 clk_period_ps = 1600; /* 625Mhz for now */
 	u32 urg = 672000;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
index fd05ab6436d1..2f8043eac71b 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
@@ -89,5 +89,6 @@ int sparx5_get_port_status(struct sparx5 *sparx5,
 			   struct sparx5_port_status *status);
 
 void sparx5_port_enable(struct sparx5_port *port, bool enable);
+int sparx5_port_fwd_urg(struct sparx5 *sparx5, u32 speed);
 
 #endif	/* __SPARX5_PORT_H__ */
-- 
2.32.0



From steen.hegelund at microchip.com  Thu Aug 19 00:39:38 2021
From: steen.hegelund at microchip.com (Steen Hegelund)
Date: Thu, 19 Aug 2021 09:39:38 +0200
Subject: [PATCH net-next v2 0/2] Adding Frame DMA functionality to Sparx5
Message-ID: <20210819073940.1589383-1-steen.hegelund@microchip.com>

v2:
    Removed an unused variable (proc_ctrl) from sparx5_fdma_start.

This add frame DMA functionality to the Sparx5 platform.

Until now the Sparx5 SwitchDev driver has been using register based
injection and extraction when sending frames to/from the host CPU.

With this series the Frame DMA functionality now added.

The Frame DMA is only used if the Frame DMA interrupt is configured in the
device tree; otherwise the existing register based injection and extraction
is used.

The Sparx5 has two ports that can be used for sending and receiving frames,
but there are 8 channels that can be configured: 6 for injection and 2 for
extraction.

The additional channels can be used for more advanced scenarios e.g. where
virtual cores are used, but currently the driver only uses port 0 and
channel 0 and 6 respectively.

DCB (data control block) structures are passed to the Frame DMA with
suitable information about frame start/end etc, as well as pointers to DB
(data blocks) buffers.

The Frame DMA engine can use interrupts to signal back when the frames have
been injected or extracted.

There is a limitation on the DB alignment also for injection: Block must
start on 16byte boundaries, and this is why the driver currently copies the
data to into separate buffers.

The Sparx5 switch core needs a IFH (Internal Frame Header) to pass
information from the port to the switch core, and this header is added
before injection and stripped after extraction.

Steen Hegelund (2):
  net: sparx5: switchdev: adding frame DMA functionality
  arm64: dts: sparx5: Add the Sparx5 switch frame DMA support

 arch/arm64/boot/dts/microchip/sparx5.dtsi     |   5 +-
 .../net/ethernet/microchip/sparx5/Makefile    |   2 +-
 .../ethernet/microchip/sparx5/sparx5_fdma.c   | 593 ++++++++++++++++++
 .../ethernet/microchip/sparx5/sparx5_main.c   |  23 +-
 .../ethernet/microchip/sparx5/sparx5_main.h   |  69 ++
 .../ethernet/microchip/sparx5/sparx5_packet.c |  13 +-
 .../ethernet/microchip/sparx5/sparx5_port.c   |   2 +-
 .../ethernet/microchip/sparx5/sparx5_port.h   |   1 +
 8 files changed, 696 insertions(+), 12 deletions(-)
 create mode 100644 drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c

-- 
2.32.0



From maxime at cerno.tech  Thu Aug 19 00:43:58 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Thu, 19 Aug 2021 09:43:58 +0200
Subject: [PATCH] ARM: sunxi: Add a missing SPDX license header
In-Reply-To: <20210810132954.107518-1-wangborong@cdjrlc.com>
References: <20210810132954.107518-1-wangborong@cdjrlc.com>
Message-ID: <20210819074358.qkvu4ynwk7s7ssuj@gilmour>

On Tue, Aug 10, 2021 at 09:29:54PM +0800, Jason Wang wrote:
> Add the missing SPDX license header to arch/arm/mach-sunxi/sunxi.c.
> 
> Signed-off-by: Jason Wang <wangborong at cdjrlc.com>

Queued for 5.16, thanks
Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210819/2e3f30ce/attachment.sig>

From maxime at cerno.tech  Thu Aug 19 00:44:15 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Thu, 19 Aug 2021 09:44:15 +0200
Subject: [PATCH] ARM: sunxi: Add a missing SPDX license header
In-Reply-To: <20210810133138.109309-1-wangborong@cdjrlc.com>
References: <20210810133138.109309-1-wangborong@cdjrlc.com>
Message-ID: <20210819074415.2qaevcwqrnuxc3jq@gilmour>

On Tue, Aug 10, 2021 at 09:31:38PM +0800, Jason Wang wrote:
> Add the missing SPDX license header to arch/arm/mach-sunxi/platsmp.c.
> 
> Signed-off-by: Jason Wang <wangborong at cdjrlc.com>

Queued for 5.16, thanks!
Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210819/a6a7c358/attachment.sig>

From maxime at cerno.tech  Thu Aug 19 00:56:30 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Thu, 19 Aug 2021 09:56:30 +0200
Subject: [PATCH v8 02/11] dt-bindings: rtc: sun6i: Add H616 compatible
 string
In-Reply-To: <YRtvl2FWKqAw4b3l@piout.net>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210723153838.6785-3-andre.przywara@arm.com>
 <20210726144137.6dauuxdssu7yszox@gilmour>
 <20210802013938.29fa18ed@slackpad.fritz.box>
 <20210817073810.7stuzrppyjf4spab@gilmour>
 <YRtvl2FWKqAw4b3l@piout.net>
Message-ID: <20210819075630.upliivqux4dsohzd@gilmour>

Salut Alex,

On Tue, Aug 17, 2021 at 10:13:11AM +0200, Alexandre Belloni wrote:
> On 17/08/2021 09:38:10+0200, Maxime Ripard wrote:
> > > > It's not entirely clear to me what those clocks are about though. If we
> > > > look at the clock output in the user manual, it looks like there's only
> > > > two clocks that are actually being output: the 32k "fanout" clock and
> > > > the losc. What are the 3 you're talking about?]
> > > 
> > > I see three: the raw SYSTEM "CLK32K_LOSC", the RTC input + debounce
> > > clock (/32), and the multiplexed PAD.
> > 
> > But the input and debounce clock is only for the RTC itself right? So it
> > should be local to the driver and doesn't need to be made available to
> > the other drivers
> > 
> 
> Shouldn't they be exposed to be able to use assigned-clock?

I'm not sure we would even need that? If it's an internal clock to the
RTC, then we probably won't ever need to change it from the device tree?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210819/43100c65/attachment.sig>

From chiawei_wang at aspeedtech.com  Thu Aug 19 01:00:35 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 19 Aug 2021 16:00:35 +0800
Subject: [PATCH v2 0/5] arm: aspeed: Add eSPI support
Message-ID: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>

This patch series add the driver support for the eSPI controller
of Aspeed 5/6th generation SoCs. This controller is a slave device
communicating with a master over Enhanced Serial Peripheral Interface (eSPI).
It supports all of the 4 eSPI channels, namely peripheral, virtual wire,
out-of-band, and flash, and operates at max frequency of 66MHz.

v2:
 - remove irqchip implementation
 - merge per-channel drivers into single one to avoid the racing issue
   among eSPI handshake process and driver probing.

Chia-Wei Wang (5):
  dt-bindings: aspeed: Add eSPI controller
  MAINTAINER: Add ASPEED eSPI driver entry
  clk: aspeed: Add eSPI reset bit
  soc: aspeed: Add eSPI driver
  ARM: dts: aspeed: Add eSPI node

 .../devicetree/bindings/soc/aspeed/espi.yaml  | 158 +++++
 MAINTAINERS                                   |   9 +
 arch/arm/boot/dts/aspeed-g6.dtsi              |  17 +
 drivers/soc/aspeed/Kconfig                    |  11 +
 drivers/soc/aspeed/Makefile                   |   1 +
 drivers/soc/aspeed/aspeed-espi-ctrl.c         | 206 ++++++
 drivers/soc/aspeed/aspeed-espi-ctrl.h         | 304 +++++++++
 drivers/soc/aspeed/aspeed-espi-flash.h        | 380 +++++++++++
 drivers/soc/aspeed/aspeed-espi-ioc.h          | 153 +++++
 drivers/soc/aspeed/aspeed-espi-oob.h          | 611 ++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-perif.h        | 512 +++++++++++++++
 drivers/soc/aspeed/aspeed-espi-vw.h           | 142 ++++
 include/dt-bindings/clock/ast2600-clock.h     |   1 +
 13 files changed, 2505 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-flash.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ioc.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-oob.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-perif.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-vw.h

-- 
2.17.1



From chiawei_wang at aspeedtech.com  Thu Aug 19 01:00:37 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 19 Aug 2021 16:00:37 +0800
Subject: [PATCH v2 2/5] MAINTAINER: Add ASPEED eSPI driver entry
In-Reply-To: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
References: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210819080040.31242-3-chiawei_wang@aspeedtech.com>

Add Ryan Chen and myself as the maintainer of Aspeed eSPI
driver. Joel Stanley is added as the reviewer.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fd25e4ecf0b9..b21bcb46692e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1713,6 +1713,15 @@ F:	drivers/crypto/axis
 F:	drivers/mmc/host/usdhi6rol0.c
 F:	drivers/pinctrl/pinctrl-artpec*
 
+ARM/ASPEED ESPI DRIVER
+M:	Chia-Wei Wang <chiawei_wang at aspeedtech.com>
+M:	Ryan Chen <ryan_chen at aspeedtech.com>
+R:	Joel Stanley <joel at jms.id.au>
+L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/soc/aspeed/espi.yaml
+
 ARM/ASPEED I2C DRIVER
 M:	Brendan Higgins <brendanhiggins at google.com>
 R:	Benjamin Herrenschmidt <benh at kernel.crashing.org>
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Thu Aug 19 01:00:36 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 19 Aug 2021 16:00:36 +0800
Subject: [PATCH v2 1/5] dt-bindings: aspeed: Add eSPI controller
In-Reply-To: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
References: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210819080040.31242-2-chiawei_wang@aspeedtech.com>

Add dt-bindings for Aspeed eSPI controller

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 .../devicetree/bindings/soc/aspeed/espi.yaml  | 158 ++++++++++++++++++
 1 file changed, 158 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml

diff --git a/Documentation/devicetree/bindings/soc/aspeed/espi.yaml b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
new file mode 100644
index 000000000000..fec3d37f3ffd
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
@@ -0,0 +1,158 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# # Copyright (c) 2021 Aspeed Technology Inc.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/aspeed/espi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Aspeed eSPI Controller
+
+maintainers:
+  - Chia-Wei Wang <chiawei_wang at aspeedtech.com>
+  - Ryan Chen <ryan_chen at aspeedtech.com>
+
+description:
+  Aspeed eSPI controller implements a slave side eSPI endpoint device
+  supporting the four eSPI channels, namely peripheral, virtual wire,
+  out-of-band, and flash.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - aspeed,ast2500-espi
+          - aspeed,ast2600-espi
+      - const: simple-mfd
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+  espi-ctrl:
+    type: object
+
+    properties:
+      compatible:
+        items:
+          - enum:
+              - aspeed,ast2500-espi-ctrl
+              - aspeed,ast2600-espi-ctrl
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      perif,memcyc-enable:
+        type: boolean
+        description: Enable memory cycle over eSPI peripheral channel
+
+      perif,memcyc-src-addr:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description: The Host side address to be decoded into the memory cycle over eSPI peripheral channel
+
+      perif,memcyc-size:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        description: The size of the memory region allocated for the memory cycle over eSPI peripheral channel
+        minimum: 65536
+
+      perif,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI peripheral channel
+
+      oob,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI out-of-band channel
+
+      oob,dma-tx-desc-num:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        minimum: 2
+        maximum: 1023
+        description: The number of TX descriptors available for eSPI OOB DMA engine
+
+      oob,dma-rx-desc-num:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        minimum: 2
+        maximum: 1023
+        description: The number of RX descriptors available for eSPI OOB DMA engine
+
+      flash,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI flash channel
+
+      flash,safs-mode:
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+        enum: [ 0, 1, 2 ]
+        default: 0
+        description: Slave-Attached-Sharing-Flash mode, 0->Mix, 1->SW, 2->HW
+
+    dependencies:
+      perif,memcyc-src-addr: [ perif,memcyc-enable ]
+      perif,memcyc-size: [ perif,memcyc-enable ]
+      oob,dma-tx-desc-num: [ oob,dma-mode ]
+      oob,dma-rx-desc-num: [ oob,dma-mode ]
+
+    required:
+      - compatible
+      - interrupts
+      - clocks
+
+  espi-mmbi:
+    type: object
+
+    properties:
+      compatible:
+        const: aspeed, ast2600-espi-mmbi
+
+      interrupts:
+        maxItems: 1
+
+    required:
+      - compatible
+      - interrupts
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+
+    espi: espi at 1e6ee000 {
+        compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
+        reg = <0x1e6ee000 0x1000>;
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0x0 0x1e6ee000 0x1000>;
+
+        espi_ctrl: espi-ctrl at 0 {
+            compatible = "aspeed,ast2600-espi-ctrl";
+            reg = <0x0 0x800>;
+            interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
+            resets = <&syscon ASPEED_RESET_ESPI>;
+        };
+
+        espi_mmbi: espi-flash-channel at 800 {
+            compatible = "aspeed,ast2600-espi-flash";
+            reg = <0x800 0x50>;
+            interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+        };
+    };
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Thu Aug 19 01:00:38 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 19 Aug 2021 16:00:38 +0800
Subject: [PATCH v2 3/5] clk: aspeed: Add eSPI reset bit
In-Reply-To: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
References: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210819080040.31242-4-chiawei_wang@aspeedtech.com>

Add bit field definition for the eSPI reset control

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 include/dt-bindings/clock/ast2600-clock.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h
index 62b9520a00fd..964934b1caef 100644
--- a/include/dt-bindings/clock/ast2600-clock.h
+++ b/include/dt-bindings/clock/ast2600-clock.h
@@ -89,6 +89,7 @@
 #define ASPEED_CLK_MAC4RCLK		70
 
 /* Only list resets here that are not part of a gate */
+#define ASPEED_RESET_ESPI		57
 #define ASPEED_RESET_ADC		55
 #define ASPEED_RESET_JTAG_MASTER2	54
 #define ASPEED_RESET_I3C_DMA		39
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Thu Aug 19 01:00:40 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 19 Aug 2021 16:00:40 +0800
Subject: [PATCH v2 5/5] ARM: dts: aspeed: Add eSPI node
In-Reply-To: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
References: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210819080040.31242-6-chiawei_wang@aspeedtech.com>

Add eSPI to the device tree for Aspeed 5/6th generation SoCs.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 arch/arm/boot/dts/aspeed-g6.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index f96607b7b4e2..47dc0b3993d1 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -364,6 +364,23 @@
 				status = "disabled";
 			};
 
+			espi: espi at 1e6ee000 {
+				compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
+				reg = <0x1e6ee000 0x1000>;
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1e6ee000 0x1000>;
+
+				espi_ctrl: espi-ctrl at 0 {
+					compatible = "aspeed,ast2600-espi-ctrl";
+					reg = <0x0 0x800>;
+					interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
+					status = "disabled";
+				};
+			};
+
 			gpio0: gpio at 1e780000 {
 				#gpio-cells = <2>;
 				gpio-controller;
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Thu Aug 19 01:00:39 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 19 Aug 2021 16:00:39 +0800
Subject: [PATCH v2 4/5] soc: aspeed: Add eSPI driver
In-Reply-To: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
References: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210819080040.31242-5-chiawei_wang@aspeedtech.com>

The Aspeed eSPI controller is slave device to communicate with
the master through the Enhanced Serial Peripheral Interface (eSPI).
All of the four eSPI channels, namely peripheral, virtual wire,
out-of-band, and flash are supported.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 drivers/soc/aspeed/Kconfig             |  11 +
 drivers/soc/aspeed/Makefile            |   1 +
 drivers/soc/aspeed/aspeed-espi-ctrl.c  | 206 +++++++++
 drivers/soc/aspeed/aspeed-espi-ctrl.h  | 304 ++++++++++++
 drivers/soc/aspeed/aspeed-espi-flash.h | 380 +++++++++++++++
 drivers/soc/aspeed/aspeed-espi-ioc.h   | 153 +++++++
 drivers/soc/aspeed/aspeed-espi-oob.h   | 611 +++++++++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-perif.h | 512 +++++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-vw.h    | 142 ++++++
 9 files changed, 2320 insertions(+)
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-flash.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ioc.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-oob.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-perif.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-vw.h

diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
index 243ca196e6ad..7617a02df5cf 100644
--- a/drivers/soc/aspeed/Kconfig
+++ b/drivers/soc/aspeed/Kconfig
@@ -42,6 +42,17 @@ config ASPEED_SOCINFO
 	help
 	  Say yes to support decoding of ASPEED BMC information.
 
+config ASPEED_ESPI
+	bool "ASPEED eSPI slave driver"
+	select REGMAP
+	select MFD_SYSCON
+	default n
+	help
+	  Enable driver support for the Aspeed eSPI engine. The eSPI engine
+	  plays as a slave device in BMC to communicate with the Host over
+	  the eSPI interface. The four eSPI channels, namely peripheral,
+	  virtual wire, out-of-band, and flash are supported.
+
 endmenu
 
 endif
diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
index fcab7192e1a4..650d8de2875d 100644
--- a/drivers/soc/aspeed/Makefile
+++ b/drivers/soc/aspeed/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_ASPEED_LPC_CTRL)	+= aspeed-lpc-ctrl.o
 obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
 obj-$(CONFIG_ASPEED_P2A_CTRL)	+= aspeed-p2a-ctrl.o
 obj-$(CONFIG_ASPEED_SOCINFO)	+= aspeed-socinfo.o
+obj-$(CONFIG_ASPEED_ESPI)	+= aspeed-espi-ctrl.o
diff --git a/drivers/soc/aspeed/aspeed-espi-ctrl.c b/drivers/soc/aspeed/aspeed-espi-ctrl.c
new file mode 100644
index 000000000000..80a135d357f1
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ctrl.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include "aspeed-espi-ioc.h"
+#include "aspeed-espi-ctrl.h"
+
+/* include alloc/free/event/ioctl handlers of the eSPI 4 channels */
+#include "aspeed-espi-perif.h"
+#include "aspeed-espi-vw.h"
+#include "aspeed-espi-oob.h"
+#include "aspeed-espi-flash.h"
+
+#define DEVICE_NAME "aspeed-espi-ctrl"
+
+static irqreturn_t aspeed_espi_ctrl_isr(int irq, void *arg)
+{
+	uint32_t sts;
+	struct aspeed_espi_ctrl *espi_ctrl = (struct aspeed_espi_ctrl *)arg;
+
+	regmap_read(espi_ctrl->map, ESPI_INT_STS, &sts);
+
+	if (sts & ESPI_INT_STS_PERIF_BITS) {
+		aspeed_espi_perif_event(sts, espi_ctrl->perif);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_PERIF_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_VW_BITS) {
+		aspeed_espi_vw_event(sts, espi_ctrl->vw);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_VW_BITS);
+	}
+
+	if (sts & (ESPI_INT_STS_OOB_BITS)) {
+		aspeed_espi_oob_event(sts, espi_ctrl->oob);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_OOB_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_FLASH_BITS) {
+		aspeed_espi_flash_event(sts, espi_ctrl->flash);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_FLASH_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_HW_RST_DEASSERT) {
+		aspeed_espi_perif_enable(espi_ctrl->perif);
+		aspeed_espi_vw_enable(espi_ctrl->vw);
+		aspeed_espi_oob_enable(espi_ctrl->oob);
+		aspeed_espi_flash_enable(espi_ctrl->flash);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
+
+		if (espi_ctrl->version == ESPI_AST2500)
+			regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T2,
+				     ESPI_SYSEVT_INT_T2_HOST_RST_WARN |
+				     ESPI_SYSEVT_INT_T2_OOB_RST_WARN);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+				   ESPI_INT_EN_HW_RST_DEASSERT,
+				   ESPI_INT_EN_HW_RST_DEASSERT);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+				   ESPI_SYSEVT_SLV_BOOT_STS | ESPI_SYSEVT_SLV_BOOT_DONE,
+				   ESPI_SYSEVT_SLV_BOOT_STS | ESPI_SYSEVT_SLV_BOOT_DONE);
+
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, ESPI_INT_STS_HW_RST_DEASSERT);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int aspeed_espi_ctrl_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	uint32_t reg;
+	struct aspeed_espi_ctrl *espi_ctrl;
+	struct device *dev = &pdev->dev;
+	struct regmap *scu;
+
+	espi_ctrl = devm_kzalloc(dev, sizeof(*espi_ctrl), GFP_KERNEL);
+	if (!espi_ctrl)
+		return -ENOMEM;
+
+	espi_ctrl->version = (uint32_t)of_device_get_match_data(dev);
+
+	espi_ctrl->map = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(espi_ctrl->map)) {
+		dev_err(dev, "cannot get remap\n");
+		return -ENODEV;
+	}
+
+	espi_ctrl->irq = platform_get_irq(pdev, 0);
+	if (espi_ctrl->irq < 0)
+		return espi_ctrl->irq;
+
+	espi_ctrl->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(espi_ctrl->clk)) {
+		dev_err(dev, "cannot get clock\n");
+		return -ENODEV;
+	}
+
+	rc = clk_prepare_enable(espi_ctrl->clk);
+	if (rc) {
+		dev_err(dev, "cannot enable clock\n");
+		return rc;
+	}
+
+	espi_ctrl->perif = aspeed_espi_perif_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->perif)) {
+		dev_err(dev, "failed to allocate peripheral channel\n");
+		return PTR_ERR(espi_ctrl->perif);
+	}
+
+	espi_ctrl->vw = aspeed_espi_vw_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->vw)) {
+		dev_err(dev, "failed to allocate virtual wire channel\n");
+		return PTR_ERR(espi_ctrl->vw);
+	}
+
+	espi_ctrl->oob = aspeed_espi_oob_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->oob)) {
+		dev_err(dev, "failed to allocate out-of-band channel\n");
+		return PTR_ERR(espi_ctrl->oob);
+	}
+
+	espi_ctrl->flash = aspeed_espi_flash_alloc(dev, espi_ctrl);
+	if (rc) {
+		dev_err(dev, "failed to allocate flash channel\n");
+		return PTR_ERR(espi_ctrl->flash);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
+
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
+
+	rc = devm_request_irq(dev, espi_ctrl->irq,
+			      aspeed_espi_ctrl_isr,
+			      0, DEVICE_NAME, espi_ctrl);
+	if (rc) {
+		dev_err(dev, "failed to request IRQ\n");
+		return rc;
+	}
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_HW_RST_DEASSERT,
+			   ESPI_INT_EN_HW_RST_DEASSERT);
+
+	dev_set_drvdata(dev, espi_ctrl);
+
+	dev_info(dev, "module loaded\n");
+
+	return 0;
+}
+
+static int aspeed_espi_ctrl_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct aspeed_espi_ctrl *espi_ctrl = dev_get_drvdata(dev);
+
+	aspeed_espi_perif_free(dev, espi_ctrl->perif);
+	aspeed_espi_vw_free(dev, espi_ctrl->vw);
+	aspeed_espi_oob_free(dev, espi_ctrl->oob);
+	aspeed_espi_flash_free(dev, espi_ctrl->flash);
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_espi_ctrl_of_matches[] = {
+	{ .compatible = "aspeed,ast2500-espi-ctrl", .data = (void *)ESPI_AST2500 },
+	{ .compatible = "aspeed,ast2600-espi-ctrl", .data = (void *)ESPI_AST2600 },
+	{ },
+};
+
+static struct platform_driver aspeed_espi_ctrl_driver = {
+	.driver = {
+		.name = DEVICE_NAME,
+		.of_match_table = aspeed_espi_ctrl_of_matches,
+	},
+	.probe = aspeed_espi_ctrl_probe,
+	.remove = aspeed_espi_ctrl_remove,
+};
+
+module_platform_driver(aspeed_espi_ctrl_driver);
+
+MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang at aspeedtech.com>");
+MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
+MODULE_DESCRIPTION("Control of Aspeed eSPI Slave Device");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/aspeed/aspeed-espi-ctrl.h b/drivers/soc/aspeed/aspeed-espi-ctrl.h
new file mode 100644
index 000000000000..44b93698fd0f
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ctrl.h
@@ -0,0 +1,304 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_CTRL_H_
+#define _ASPEED_ESPI_CTRL_H_
+
+#include <linux/bits.h>
+
+enum aspeed_espi_version {
+	ESPI_AST2500,
+	ESPI_AST2600,
+};
+
+struct aspeed_espi_ctrl {
+	struct device *dev;
+
+	struct regmap *map;
+	struct clk *clk;
+
+	int irq;
+
+	struct aspeed_espi_perif *perif;
+	struct aspeed_espi_vw *vw;
+	struct aspeed_espi_oob *oob;
+	struct aspeed_espi_flash *flash;
+
+	uint32_t version;
+};
+
+/* eSPI register offset */
+#define ESPI_CTRL		0x000
+#define   ESPI_CTRL_OOB_RX_SW_RST		BIT(28)
+#define   ESPI_CTRL_FLASH_TX_DMA_EN		BIT(23)
+#define   ESPI_CTRL_FLASH_RX_DMA_EN		BIT(22)
+#define   ESPI_CTRL_OOB_TX_DMA_EN		BIT(21)
+#define   ESPI_CTRL_OOB_RX_DMA_EN		BIT(20)
+#define   ESPI_CTRL_PERIF_NP_TX_DMA_EN		BIT(19)
+#define   ESPI_CTRL_PERIF_PC_TX_DMA_EN		BIT(17)
+#define   ESPI_CTRL_PERIF_PC_RX_DMA_EN		BIT(16)
+#define   ESPI_CTRL_FLASH_SW_MODE_MASK		GENMASK(11, 10)
+#define   ESPI_CTRL_FLASH_SW_MODE_SHIFT		10
+#define   ESPI_CTRL_PERIF_PC_RX_DMA_EN		BIT(16)
+#define   ESPI_CTRL_FLASH_SW_RDY		BIT(7)
+#define   ESPI_CTRL_OOB_SW_RDY			BIT(4)
+#define   ESPI_CTRL_VW_SW_RDY			BIT(3)
+#define   ESPI_CTRL_PERIF_SW_RDY		BIT(1)
+#define ESPI_STS		0x004
+#define ESPI_INT_STS		0x008
+#define   ESPI_INT_STS_HW_RST_DEASSERT		BIT(31)
+#define   ESPI_INT_STS_OOB_RX_TMOUT		BIT(23)
+#define   ESPI_INT_STS_VW_SYSEVT1		BIT(22)
+#define   ESPI_INT_STS_FLASH_TX_ERR		BIT(21)
+#define   ESPI_INT_STS_OOB_TX_ERR		BIT(20)
+#define   ESPI_INT_STS_FLASH_TX_ABT		BIT(19)
+#define   ESPI_INT_STS_OOB_TX_ABT		BIT(18)
+#define   ESPI_INT_STS_PERIF_NP_TX_ABT		BIT(17)
+#define   ESPI_INT_STS_PERIF_PC_TX_ABT		BIT(16)
+#define   ESPI_INT_STS_FLASH_RX_ABT		BIT(15)
+#define   ESPI_INT_STS_OOB_RX_ABT		BIT(14)
+#define   ESPI_INT_STS_PERIF_NP_RX_ABT		BIT(13)
+#define   ESPI_INT_STS_PERIF_PC_RX_ABT		BIT(12)
+#define   ESPI_INT_STS_PERIF_NP_TX_ERR		BIT(11)
+#define   ESPI_INT_STS_PERIF_PC_TX_ERR		BIT(10)
+#define   ESPI_INT_STS_VW_GPIOEVT		BIT(9)
+#define   ESPI_INT_STS_VW_SYSEVT		BIT(8)
+#define   ESPI_INT_STS_FLASH_TX_CMPLT		BIT(7)
+#define   ESPI_INT_STS_FLASH_RX_CMPLT		BIT(6)
+#define   ESPI_INT_STS_OOB_TX_CMPLT		BIT(5)
+#define   ESPI_INT_STS_OOB_RX_CMPLT		BIT(4)
+#define   ESPI_INT_STS_PERIF_NP_TX_CMPLT	BIT(3)
+#define   ESPI_INT_STS_PERIF_PC_TX_CMPLT	BIT(1)
+#define   ESPI_INT_STS_PERIF_PC_RX_CMPLT	BIT(0)
+#define ESPI_INT_EN		0x00c
+#define   ESPI_INT_EN_HW_RST_DEASSERT		BIT(31)
+#define   ESPI_INT_EN_OOB_RX_TMOUT		BIT(23)
+#define   ESPI_INT_EN_VW_SYSEVT1		BIT(22)
+#define   ESPI_INT_EN_FLASH_TX_ERR		BIT(21)
+#define   ESPI_INT_EN_OOB_TX_ERR		BIT(20)
+#define   ESPI_INT_EN_FLASH_TX_ABT		BIT(19)
+#define   ESPI_INT_EN_OOB_TX_ABT		BIT(18)
+#define   ESPI_INT_EN_PERIF_NP_TX_ABT		BIT(17)
+#define   ESPI_INT_EN_PERIF_PC_TX_ABT		BIT(16)
+#define   ESPI_INT_EN_FLASH_RX_ABT		BIT(15)
+#define   ESPI_INT_EN_OOB_RX_ABT		BIT(14)
+#define   ESPI_INT_EN_PERIF_NP_RX_ABT		BIT(13)
+#define   ESPI_INT_EN_PERIF_PC_RX_ABT		BIT(12)
+#define   ESPI_INT_EN_PERIF_NP_TX_ERR		BIT(11)
+#define   ESPI_INT_EN_PERIF_PC_TX_ERR		BIT(10)
+#define   ESPI_INT_EN_VW_GPIOEVT		BIT(9)
+#define   ESPI_INT_EN_VW_SYSEVT			BIT(8)
+#define   ESPI_INT_EN_FLASH_TX_CMPLT		BIT(7)
+#define   ESPI_INT_EN_FLASH_RX_CMPLT		BIT(6)
+#define   ESPI_INT_EN_OOB_TX_CMPLT		BIT(5)
+#define   ESPI_INT_EN_OOB_RX_CMPLT		BIT(4)
+#define   ESPI_INT_EN_PERIF_NP_TX_CMPLT		BIT(3)
+#define   ESPI_INT_EN_PERIF_PC_TX_CMPLT		BIT(1)
+#define   ESPI_INT_EN_PERIF_PC_RX_CMPLT		BIT(0)
+#define ESPI_PERIF_PC_RX_DMA	0x010
+#define ESPI_PERIF_PC_RX_CTRL	0x014
+#define   ESPI_PERIF_PC_RX_CTRL_PEND_SERV	BIT(31)
+#define   ESPI_PERIF_PC_RX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define   ESPI_PERIF_PC_RX_CTRL_LEN_SHIFT	12
+#define   ESPI_PERIF_PC_RX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define   ESPI_PERIF_PC_RX_CTRL_TAG_SHIFT	8
+#define   ESPI_PERIF_PC_RX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define   ESPI_PERIF_PC_RX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_PC_RX_PORT	0x018
+#define ESPI_PERIF_PC_TX_DMA	0x020
+#define ESPI_PERIF_PC_TX_CTRL	0x024
+#define	  ESPI_PERIF_PC_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_PERIF_PC_TX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define	  ESPI_PERIF_PC_TX_CTRL_LEN_SHIFT	12
+#define	  ESPI_PERIF_PC_TX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define	  ESPI_PERIF_PC_TX_CTRL_TAG_SHIFT	8
+#define	  ESPI_PERIF_PC_TX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define	  ESPI_PERIF_PC_TX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_PC_TX_PORT	0x028
+#define ESPI_PERIF_NP_TX_DMA	0x030
+#define ESPI_PERIF_NP_TX_CTRL	0x034
+#define   ESPI_PERIF_NP_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_PERIF_NP_TX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define	  ESPI_PERIF_NP_TX_CTRL_LEN_SHIFT	12
+#define	  ESPI_PERIF_NP_TX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define	  ESPI_PERIF_NP_TX_CTRL_TAG_SHIFT	8
+#define	  ESPI_PERIF_NP_TX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define	  ESPI_PERIF_NP_TX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_NP_TX_PORT	0x038
+#define ESPI_OOB_RX_DMA		0x040
+#define ESPI_OOB_RX_CTRL	0x044
+#define	  ESPI_OOB_RX_CTRL_PEND_SERV		BIT(31)
+#define	  ESPI_OOB_RX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_OOB_RX_CTRL_LEN_SHIFT		12
+#define	  ESPI_OOB_RX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_OOB_RX_CTRL_TAG_SHIFT		8
+#define	  ESPI_OOB_RX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_OOB_RX_CTRL_CYC_SHIFT		0
+#define ESPI_OOB_RX_PORT	0x048
+#define ESPI_OOB_TX_DMA		0x050
+#define ESPI_OOB_TX_CTRL	0x054
+#define	  ESPI_OOB_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_OOB_TX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_OOB_TX_CTRL_LEN_SHIFT		12
+#define	  ESPI_OOB_TX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_OOB_TX_CTRL_TAG_SHIFT		8
+#define	  ESPI_OOB_TX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_OOB_TX_CTRL_CYC_SHIFT		0
+#define ESPI_OOB_TX_PORT	0x058
+#define ESPI_FLASH_RX_DMA	0x060
+#define ESPI_FLASH_RX_CTRL	0x064
+#define	  ESPI_FLASH_RX_CTRL_PEND_SERV		BIT(31)
+#define	  ESPI_FLASH_RX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_FLASH_RX_CTRL_LEN_SHIFT		12
+#define	  ESPI_FLASH_RX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_FLASH_RX_CTRL_TAG_SHIFT		8
+#define	  ESPI_FLASH_RX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_FLASH_RX_CTRL_CYC_SHIFT		0
+#define ESPI_FLASH_RX_PORT	0x068
+#define ESPI_FLASH_TX_DMA	0x070
+#define ESPI_FLASH_TX_CTRL	0x074
+#define	  ESPI_FLASH_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_FLASH_TX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_FLASH_TX_CTRL_LEN_SHIFT		12
+#define	  ESPI_FLASH_TX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_FLASH_TX_CTRL_TAG_SHIFT		8
+#define	  ESPI_FLASH_TX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_FLASH_TX_CTRL_CYC_SHIFT		0
+#define ESPI_FLASH_TX_PORT	0x078
+#define ESPI_CTRL2		0x080
+#define   ESPI_CTRL2_MEMCYC_RD_DIS		BIT(6)
+#define   ESPI_CTRL2_MEMCYC_WR_DIS		BIT(4)
+#define ESPI_PERIF_PC_RX_SADDR	0x084
+#define ESPI_PERIF_PC_RX_TADDR	0x088
+#define ESPI_PERIF_PC_RX_MASK	0x08c
+#define   ESPI_PERIF_PC_RX_MASK_CFG_WP		BIT(0)
+#define ESPI_SYSEVT_INT_EN	0x094
+#define ESPI_SYSEVT		0x098
+#define   ESPI_SYSEVT_HOST_RST_ACK		BIT(27)
+#define   ESPI_SYSEVT_RST_CPU_INIT		BIT(26)
+#define   ESPI_SYSEVT_SLV_BOOT_STS		BIT(23)
+#define   ESPI_SYSEVT_NON_FATAL_ERR		BIT(22)
+#define   ESPI_SYSEVT_FATAL_ERR			BIT(21)
+#define   ESPI_SYSEVT_SLV_BOOT_DONE		BIT(20)
+#define   ESPI_SYSEVT_OOB_RST_ACK		BIT(16)
+#define   ESPI_SYSEVT_NMI_OUT			BIT(10)
+#define   ESPI_SYSEVT_SMI_OUT			BIT(9)
+#define   ESPI_SYSEVT_HOST_RST_WARN		BIT(8)
+#define   ESPI_SYSEVT_OOB_RST_WARN		BIT(6)
+#define   ESPI_SYSEVT_PLTRSTN			BIT(5)
+#define   ESPI_SYSEVT_SUSPEND			BIT(4)
+#define   ESPI_SYSEVT_S5_SLEEP			BIT(2)
+#define   ESPI_SYSEVT_S4_SLEEP			BIT(1)
+#define   ESPI_SYSEVT_S3_SLEEP			BIT(0)
+#define ESPI_VW_GPIO_VAL	0x09c
+#define ESPI_GEN_CAP_N_CONF	0x0a0
+#define ESPI_CH0_CAP_N_CONF	0x0a4
+#define ESPI_CH1_CAP_N_CONF	0x0a8
+#define ESPI_CH2_CAP_N_CONF	0x0ac
+#define ESPI_CH3_CAP_N_CONF	0x0b0
+#define ESPI_CH3_CAP_N_CONF2	0x0b4
+#define ESPI_SYSEVT1_INT_EN	0x100
+#define ESPI_SYSEVT1		0x104
+#define   ESPI_SYSEVT1_SUSPEND_ACK		BIT(20)
+#define   ESPI_SYSEVT1_SUSPEND_WARN		BIT(0)
+#define ESPI_SYSEVT_INT_T0	0x110
+#define ESPI_SYSEVT_INT_T1	0x114
+#define ESPI_SYSEVT_INT_T2	0x118
+#define   ESPI_SYSEVT_INT_T2_HOST_RST_WARN	ESPI_SYSEVT_HOST_RST_WARN
+#define   ESPI_SYSEVT_INT_T2_OOB_RST_WARN	ESPI_SYSEVT_OOB_RST_WARN
+#define ESPI_SYSEVT_INT_STS	0x11c
+#define   ESPI_SYSEVT_INT_STS_NMI_OUT		ESPI_SYSEVT_NMI_OUT
+#define   ESPI_SYSEVT_INT_STS_SMI_OUT		ESPI_SYSEVT_SMI_OUT
+#define   ESPI_SYSEVT_INT_STS_HOST_RST_WARN	ESPI_SYSEVT_HOST_RST_WARN
+#define   ESPI_SYSEVT_INT_STS_OOB_RST_WARN	ESPI_SYSEVT_OOB_RST_WARN
+#define   ESPI_SYSEVT_INT_STS_PLTRSTN		ESPI_SYSEVT_PLTRSTN
+#define   ESPI_SYSEVT_INT_STS_SUSPEND		ESPI_SYSEVT_SUSPEND
+#define   ESPI_SYSEVT_INT_STS_S5_SLEEP		ESPI_SYSEVT_INT_S5_SLEEP
+#define   ESPI_SYSEVT_INT_STS_S4_SLEEP		ESPI_SYSEVT_INT_S4_SLEEP
+#define   ESPI_SYSEVT_INT_STS_S3_SLEEP		ESPI_SYSEVT_INT_S3_SLEEP
+#define ESPI_SYSEVT1_INT_T0	0x120
+#define ESPI_SYSEVT1_INT_T1	0x124
+#define ESPI_SYSEVT1_INT_T2	0x128
+#define ESPI_SYSEVT1_INT_STS	0x12c
+#define   ESPI_SYSEVT1_INT_STS_SUSPEND_WARN	ESPI_SYSEVT1_SUSPEND_WARN
+#define ESPI_OOB_RX_DMA_RB_SIZE	0x130
+#define ESPI_OOB_RX_DMA_RD_PTR	0x134
+#define	  ESPI_OOB_RX_DMA_RD_PTR_UPDATE		BIT(31)
+#define ESPI_OOB_RX_DMA_WS_PTR	0x138
+#define   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN	BIT(31)
+#define   ESPI_OOB_RX_DMA_WS_PTR_SP_MASK	GENMASK(27, 16)
+#define   ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT	16
+#define   ESPI_OOB_RX_DMA_WS_PTR_WP_MASK	GENMASK(11, 0)
+#define   ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT	0
+#define ESPI_OOB_TX_DMA_RB_SIZE	0x140
+#define ESPI_OOB_TX_DMA_RD_PTR	0x144
+#define	  ESPI_OOB_TX_DMA_RD_PTR_UPDATE		BIT(31)
+#define ESPI_OOB_TX_DMA_WR_PTR	0x148
+#define	  ESPI_OOB_TX_DMA_WR_PTR_SEND_EN	BIT(31)
+
+/* collect ESPI_INT_STS bits of eSPI channels for convenience */
+#define ESPI_INT_STS_PERIF_BITS			\
+	(ESPI_INT_STS_PERIF_NP_TX_ABT |		\
+	 ESPI_INT_STS_PERIF_PC_TX_ABT |		\
+	 ESPI_INT_STS_PERIF_NP_RX_ABT |		\
+	 ESPI_INT_STS_PERIF_PC_RX_ABT |		\
+	 ESPI_INT_STS_PERIF_NP_TX_ERR |		\
+	 ESPI_INT_STS_PERIF_PC_TX_ERR |		\
+	 ESPI_INT_STS_PERIF_NP_TX_CMPLT |	\
+	 ESPI_INT_STS_PERIF_PC_TX_CMPLT |	\
+	 ESPI_INT_STS_PERIF_PC_RX_CMPLT)
+
+#define ESPI_INT_STS_VW_BITS		\
+	(ESPI_INT_STS_VW_SYSEVT1 |	\
+	 ESPI_INT_STS_VW_GPIOEVT |	\
+	 ESPI_INT_STS_VW_SYSEVT)
+
+#define ESPI_INT_STS_OOB_BITS		\
+	(ESPI_INT_STS_OOB_RX_TMOUT |	\
+	 ESPI_INT_STS_OOB_TX_ERR |	\
+	 ESPI_INT_STS_OOB_TX_ABT |	\
+	 ESPI_INT_STS_OOB_RX_ABT |	\
+	 ESPI_INT_STS_OOB_TX_CMPLT |	\
+	 ESPI_INT_STS_OOB_RX_CMPLT)
+
+#define ESPI_INT_STS_FLASH_BITS		\
+	(ESPI_INT_STS_FLASH_TX_ERR |	\
+	 ESPI_INT_STS_FLASH_TX_ABT |	\
+	 ESPI_INT_STS_FLASH_RX_ABT |	\
+	 ESPI_INT_STS_FLASH_TX_CMPLT |	\
+	 ESPI_INT_STS_FLASH_RX_CMPLT)
+
+/* collect ESPI_INT_EN bits of eSPI channels for convenience */
+#define ESPI_INT_EN_PERIF_BITS			\
+	(ESPI_INT_EN_PERIF_NP_TX_ABT |		\
+	 ESPI_INT_EN_PERIF_PC_TX_ABT |		\
+	 ESPI_INT_EN_PERIF_NP_RX_ABT |		\
+	 ESPI_INT_EN_PERIF_PC_RX_ABT |		\
+	 ESPI_INT_EN_PERIF_NP_TX_ERR |		\
+	 ESPI_INT_EN_PERIF_PC_TX_ERR |		\
+	 ESPI_INT_EN_PERIF_NP_TX_CMPLT |	\
+	 ESPI_INT_EN_PERIF_PC_TX_CMPLT |	\
+	 ESPI_INT_EN_PERIF_PC_RX_CMPLT)
+
+#define ESPI_INT_EN_VW_BITS		\
+	(ESPI_INT_EN_VW_SYSEVT1 |	\
+	 ESPI_INT_EN_VW_GPIOEVT |	\
+	 ESPI_INT_EN_VW_SYSEVT)
+
+#define ESPI_INT_EN_OOB_BITS		\
+	(ESPI_INT_EN_OOB_RX_TMOUT |	\
+	 ESPI_INT_EN_OOB_TX_ERR |	\
+	 ESPI_INT_EN_OOB_TX_ABT |	\
+	 ESPI_INT_EN_OOB_RX_ABT |	\
+	 ESPI_INT_EN_OOB_TX_CMPLT |	\
+	 ESPI_INT_EN_OOB_RX_CMPLT)
+
+#define ESPI_INT_EN_FLASH_BITS		\
+	(ESPI_INT_EN_FLASH_TX_ERR |	\
+	 ESPI_INT_EN_FLASH_TX_ABT |	\
+	 ESPI_INT_EN_FLASH_RX_ABT |	\
+	 ESPI_INT_EN_FLASH_TX_CMPLT |	\
+	 ESPI_INT_EN_FLASH_RX_CMPLT)
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-flash.h b/drivers/soc/aspeed/aspeed-espi-flash.h
new file mode 100644
index 000000000000..1acb9877cb2c
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-flash.h
@@ -0,0 +1,380 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ *
+ * This header includes the data strcuture and the handler
+ * for eSPI flash channel. It is part of Aspeed eSPI slave
+ * driver implementation
+ */
+#ifndef _ASPEED_ESPI_FLASH_H_
+#define _ASPEED_ESPI_FLASH_H_
+
+#define FLASH_MDEV_NAME	"aspeed-espi-flash"
+
+enum aspeed_espi_flash_safs_mode {
+	SAFS_MODE_MIX,
+	SAFS_MODE_SW,
+	SAFS_MODE_HW,
+	SAFS_MODES,
+};
+
+struct aspeed_espi_flash_dma {
+	void *tx_virt;
+	dma_addr_t tx_addr;
+	void *rx_virt;
+	dma_addr_t rx_addr;
+};
+
+struct aspeed_espi_flash {
+	uint32_t safs_mode;
+
+	uint32_t dma_mode;
+	struct aspeed_espi_flash_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	struct mutex get_rx_mtx;
+	struct mutex put_tx_mtx;
+
+	spinlock_t lock;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+static long aspeed_espi_flash_get_rx(struct file *fp,
+				     struct aspeed_espi_ioc *ioc,
+				     struct aspeed_espi_flash *espi_flash)
+{
+	int i, rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	if (fp->f_flags & O_NONBLOCK) {
+		if (mutex_trylock(&espi_flash->get_rx_mtx))
+			return -EBUSY;
+
+		if (!espi_flash->rx_ready) {
+			rc = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+	} else {
+		mutex_lock(&espi_flash->get_rx_mtx);
+
+		if (!espi_flash->rx_ready) {
+			rc = wait_event_interruptible(espi_flash->wq,
+						      espi_flash->rx_ready);
+			if (rc == -ERESTARTSYS) {
+				rc = -EINTR;
+				goto unlock_mtx_n_out;
+			}
+		}
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_FLASH_RX_CTRL, &reg);
+	cyc = (reg & ESPI_FLASH_RX_CTRL_CYC_MASK) >> ESPI_FLASH_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_FLASH_RX_CTRL_TAG_MASK) >> ESPI_FLASH_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_FLASH_RX_CTRL_LEN_MASK) >> ESPI_FLASH_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	switch (cyc) {
+	case ESPI_FLASH_READ:
+	case ESPI_FLASH_WRITE:
+	case ESPI_FLASH_ERASE:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_flash_rwe);
+		break;
+	case ESPI_FLASH_SUC_CMPLT_D_MIDDLE:
+	case ESPI_FLASH_SUC_CMPLT_D_FIRST:
+	case ESPI_FLASH_SUC_CMPLT_D_LAST:
+	case ESPI_FLASH_SUC_CMPLT_D_ONLY:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_flash_cmplt);
+		break;
+	case ESPI_FLASH_SUC_CMPLT:
+	case ESPI_FLASH_UNSUC_CMPLT:
+		pkt_len = len + sizeof(struct espi_flash_cmplt);
+		break;
+	default:
+		rc = -EFAULT;
+		goto unlock_mtx_n_out;
+	}
+
+	if (ioc->pkt_len < pkt_len) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_flash->dma_mode) {
+		memcpy(hdr + 1, espi_flash->dma.rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_FLASH_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_flash->lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_FLASH_RX_CTRL,
+			  ESPI_FLASH_RX_CTRL_PEND_SERV,
+			  ESPI_FLASH_RX_CTRL_PEND_SERV);
+
+	espi_flash->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_flash->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_flash->get_rx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_flash_put_tx(struct file *fp,
+				     struct aspeed_espi_ioc *ioc,
+				     struct aspeed_espi_flash *espi_flash)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	if (!mutex_trylock(&espi_flash->put_tx_mtx))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_FLASH_TX_CTRL, &reg);
+	if (reg & ESPI_FLASH_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_flash->dma_mode) {
+		memcpy(espi_flash->dma.tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_FLASH_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_FLASH_TX_CTRL_CYC_SHIFT) & ESPI_FLASH_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_FLASH_TX_CTRL_TAG_SHIFT) & ESPI_FLASH_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_FLASH_TX_CTRL_LEN_SHIFT) & ESPI_FLASH_TX_CTRL_LEN_MASK)
+		| ESPI_FLASH_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_FLASH_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_flash->put_tx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_flash_ioctl(struct file *fp, unsigned int cmd,
+				    unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_flash *espi_flash = container_of(
+			fp->private_data,
+			struct aspeed_espi_flash,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_FLASH_GET_RX:
+		return aspeed_espi_flash_get_rx(fp, &ioc, espi_flash);
+	case ASPEED_ESPI_FLASH_PUT_TX:
+		return aspeed_espi_flash_put_tx(fp, &ioc, espi_flash);
+	};
+
+	return -EINVAL;
+}
+
+static const struct file_operations aspeed_espi_flash_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_flash_ioctl,
+};
+
+static void aspeed_espi_flash_event(uint32_t sts, struct aspeed_espi_flash *espi_flash)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_FLASH_RX_CMPLT) {
+		spin_lock_irqsave(&espi_flash->lock, flags);
+		espi_flash->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_flash->lock, flags);
+		wake_up_interruptible(&espi_flash->wq);
+	}
+}
+
+static void aspeed_espi_flash_enable(struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_flash_dma *dma = &espi_flash->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_FLASH_SW_MODE_MASK,
+			   (espi_flash->safs_mode << ESPI_CTRL_FLASH_SW_MODE_SHIFT));
+
+	if (espi_flash->dma_mode) {
+		regmap_write(espi_ctrl->map, ESPI_FLASH_TX_DMA, dma->tx_addr);
+		regmap_write(espi_ctrl->map, ESPI_FLASH_RX_DMA, dma->rx_addr);
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_FLASH_TX_DMA_EN | ESPI_CTRL_FLASH_RX_DMA_EN,
+				   ESPI_CTRL_FLASH_TX_DMA_EN | ESPI_CTRL_FLASH_RX_DMA_EN);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_FLASH_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_FLASH_BITS,
+			   ESPI_INT_EN_FLASH_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_FLASH_SW_RDY,
+			   ESPI_CTRL_FLASH_SW_RDY);
+}
+
+static void *aspeed_espi_flash_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc = 0;
+	struct aspeed_espi_flash *espi_flash;
+	struct aspeed_espi_flash_dma *dma;
+
+	espi_flash = devm_kzalloc(dev, sizeof(*espi_flash), GFP_KERNEL);
+	if (!espi_flash)
+		return ERR_PTR(-ENOMEM);
+
+	espi_flash->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_flash->wq);
+
+	spin_lock_init(&espi_flash->lock);
+
+	mutex_init(&espi_flash->put_tx_mtx);
+	mutex_init(&espi_flash->get_rx_mtx);
+
+	if (of_property_read_bool(dev->of_node, "flash,dma-mode"))
+		espi_flash->dma_mode = 1;
+
+	of_property_read_u32(dev->of_node, "flash,safs-mode", &espi_flash->safs_mode);
+	if (espi_flash->safs_mode >= SAFS_MODES) {
+		dev_err(dev, "invalid SAFS mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (espi_flash->dma_mode) {
+		dma = &espi_flash->dma;
+
+		dma->tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						  &dma->tx_addr, GFP_KERNEL);
+		if (!dma->tx_virt) {
+			dev_err(dev, "cannot allocate DMA TX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->rx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						  &dma->rx_addr, GFP_KERNEL);
+		if (!dma->rx_virt) {
+			dev_err(dev, "cannot allocate DMA RX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	espi_flash->mdev.parent = dev;
+	espi_flash->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_flash->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", FLASH_MDEV_NAME);
+	espi_flash->mdev.fops = &aspeed_espi_flash_fops;
+	rc = misc_register(&espi_flash->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_flash_enable(espi_flash);
+
+	return espi_flash;
+}
+
+static void aspeed_espi_flash_free(struct device *dev, struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_flash_dma *dma = &espi_flash->dma;
+
+	if (espi_flash->dma_mode) {
+		dma_free_coherent(dev, PAGE_SIZE, dma->tx_virt, dma->tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->rx_virt, dma->rx_addr);
+	}
+
+	mutex_destroy(&espi_flash->put_tx_mtx);
+	mutex_destroy(&espi_flash->get_rx_mtx);
+
+	misc_deregister(&espi_flash->mdev);
+}
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-ioc.h b/drivers/soc/aspeed/aspeed-espi-ioc.h
new file mode 100644
index 000000000000..e93739c80b5f
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ioc.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_IOC_H
+#define _ASPEED_ESPI_IOC_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * eSPI cycle type encoding
+ *
+ * Section 5.1 Cycle Types and Packet Format,
+ * Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ */
+#define ESPI_PERIF_MEMRD32		0x00
+#define ESPI_PERIF_MEMRD64		0x02
+#define ESPI_PERIF_MEMWR32		0x01
+#define ESPI_PERIF_MEMWR64		0x03
+#define ESPI_PERIF_MSG			0x10
+#define ESPI_PERIF_MSG_D		0x11
+#define ESPI_PERIF_SUC_CMPLT		0x06
+#define ESPI_PERIF_SUC_CMPLT_D_MIDDLE	0x09
+#define ESPI_PERIF_SUC_CMPLT_D_FIRST	0x0b
+#define ESPI_PERIF_SUC_CMPLT_D_LAST	0x0d
+#define ESPI_PERIF_SUC_CMPLT_D_ONLY	0x0f
+#define ESPI_PERIF_UNSUC_CMPLT		0x0c
+#define ESPI_OOB_MSG			0x21
+#define ESPI_FLASH_READ			0x00
+#define ESPI_FLASH_WRITE		0x01
+#define ESPI_FLASH_ERASE		0x02
+#define ESPI_FLASH_SUC_CMPLT		0x06
+#define ESPI_FLASH_SUC_CMPLT_D_MIDDLE	0x09
+#define ESPI_FLASH_SUC_CMPLT_D_FIRST	0x0b
+#define ESPI_FLASH_SUC_CMPLT_D_LAST	0x0d
+#define ESPI_FLASH_SUC_CMPLT_D_ONLY	0x0f
+#define ESPI_FLASH_UNSUC_CMPLT		0x0c
+
+/*
+ * eSPI packet format structure
+ *
+ * Section 5.1 Cycle Types and Packet Format,
+ * Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ */
+struct espi_comm_hdr {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+};
+
+struct espi_perif_mem32 {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_mem64 {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_msg {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t msg_code;
+	uint8_t msg_byte[4];
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_cmplt {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+} __packed;
+
+struct espi_oob_msg {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+};
+
+struct espi_flash_rwe {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_flash_cmplt {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+} __packed;
+
+struct aspeed_espi_ioc {
+	uint32_t pkt_len;
+	uint8_t *pkt;
+};
+
+/*
+ * we choose the longest header and the max payload size
+ * based on the Intel specification to define the maximum
+ * eSPI packet length
+ */
+#define ESPI_PLD_LEN_MIN	(1UL << 6)
+#define ESPI_PLD_LEN_MAX	(1UL << 12)
+#define ESPI_PKT_LEN_MAX	(sizeof(struct espi_perif_msg) + ESPI_PLD_LEN_MAX)
+
+#define __ASPEED_ESPI_IOCTL_MAGIC	0xb8
+
+/* peripheral channel (ch0) */
+#define ASPEED_ESPI_PERIF_PC_GET_RX	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x00, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_PERIF_PC_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x01, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_PERIF_NP_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x02, struct aspeed_espi_ioc)
+/* peripheral channel (ch1) */
+#define ASPEED_ESPI_VW_GET_GPIO_VAL	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x10, uint8_t)
+#define ASPEED_ESPI_VW_PUT_GPIO_VAL	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x11, uint8_t)
+/* out-of-band channel (ch2) */
+#define ASPEED_ESPI_OOB_GET_RX		_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x20, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_OOB_PUT_TX		_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x21, struct aspeed_espi_ioc)
+/* flash channel (ch3) */
+#define ASPEED_ESPI_FLASH_GET_RX	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x30, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_FLASH_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x31, struct aspeed_espi_ioc)
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-oob.h b/drivers/soc/aspeed/aspeed-espi-oob.h
new file mode 100644
index 000000000000..182a9ca1e4cc
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-oob.h
@@ -0,0 +1,611 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ *
+ * This header includes the data strcuture and the handler
+ * for eSPI out-of-band channel. It is part of Aspeed eSPI
+ * slave driver implementation
+ */
+#ifndef _ASPEED_ESPI_OOB_H_
+#define _ASPEED_ESPI_OOB_H_
+
+#define OOB_MDEV_NAME	"aspeed-espi-oob"
+
+/* DMA descriptor is supported since AST2600 */
+#define OOB_DMA_DESC_MAX_NUM	1024
+
+/* DMA TX descriptor type */
+#define OOB_DMA_TX_DESC_CUST	0x04
+
+struct oob_tx_dma_desc {
+	uint32_t data_addr;
+	uint8_t cyc;
+	uint16_t tag : 4;
+	uint16_t len : 12;
+	uint8_t msg_type : 3;
+	uint8_t raz0 : 1;
+	uint8_t pec : 1;
+	uint8_t int_en : 1;
+	uint8_t pause : 1;
+	uint8_t raz1 : 1;
+	uint32_t raz2;
+	uint32_t raz3;
+} __packed;
+
+struct oob_rx_dma_desc {
+	uint32_t data_addr;
+	uint8_t cyc;
+	uint16_t tag : 4;
+	uint16_t len : 12;
+	uint8_t raz : 7;
+	uint8_t dirty : 1;
+} __packed;
+
+struct aspeed_espi_oob_dma {
+	uint32_t tx_desc_num;
+	uint32_t rx_desc_num;
+
+	struct oob_tx_dma_desc *tx_desc;
+	dma_addr_t tx_desc_addr;
+
+	struct oob_rx_dma_desc *rx_desc;
+	dma_addr_t rx_desc_addr;
+
+	void *tx_virt;
+	dma_addr_t tx_addr;
+
+	void *rx_virt;
+	dma_addr_t rx_addr;
+};
+
+struct aspeed_espi_oob {
+	uint32_t dma_mode;
+	struct aspeed_espi_oob_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	struct mutex get_rx_mtx;
+	struct mutex put_tx_mtx;
+
+	spinlock_t lock;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+/* descriptor-based RX DMA handling */
+static long aspeed_espi_oob_dma_desc_get_rx(struct file *fp,
+					    struct aspeed_espi_ioc *ioc,
+					    struct aspeed_espi_oob *espi_oob)
+{
+	int rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t wptr, sptr;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct oob_rx_dma_desc *d;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR, &reg);
+	wptr = (reg & ESPI_OOB_RX_DMA_WS_PTR_WP_MASK) >> ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT;
+	sptr = (reg & ESPI_OOB_RX_DMA_WS_PTR_SP_MASK) >> ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT;
+
+	d = &espi_oob->dma.rx_desc[sptr];
+
+	if (!d->dirty)
+		return -EFAULT;
+
+	pkt_len = ((d->len) ? d->len : 0x1000) + sizeof(struct espi_comm_hdr);
+
+	if (ioc->pkt_len < pkt_len)
+		return -EINVAL;
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt)
+		return -ENOMEM;
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = d->cyc;
+	hdr->tag = d->tag;
+	hdr->len_h = d->len >> 8;
+	hdr->len_l = d->len & 0xff;
+	memcpy(hdr + 1, espi_oob->dma.rx_virt + (PAGE_SIZE * sptr), pkt_len - sizeof(*hdr));
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_oob->lock, flags);
+
+	/* make current descriptor available again */
+	d->dirty = 0;
+
+	sptr = (sptr + 1) % espi_oob->dma.rx_desc_num;
+	wptr = (wptr + 1) % espi_oob->dma.rx_desc_num;
+
+	reg = ((wptr << ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT) & ESPI_OOB_RX_DMA_WS_PTR_WP_MASK)
+		| ((sptr << ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT) & ESPI_OOB_RX_DMA_WS_PTR_SP_MASK)
+		| ESPI_OOB_RX_DMA_WS_PTR_RECV_EN;
+	regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR, reg);
+
+	/* set ready flag base on the next RX descriptor */
+	espi_oob->rx_ready = espi_oob->dma.rx_desc[sptr].dirty;
+
+	spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_get_rx(struct file *fp,
+				   struct aspeed_espi_ioc *ioc,
+				   struct aspeed_espi_oob *espi_oob)
+{
+	int i, rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	if (fp->f_flags & O_NONBLOCK) {
+		if (mutex_trylock(&espi_oob->get_rx_mtx))
+			return -EBUSY;
+
+		if (!espi_oob->rx_ready) {
+			rc = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+	} else {
+		mutex_lock(&espi_oob->get_rx_mtx);
+
+		if (!espi_oob->rx_ready) {
+			rc = wait_event_interruptible(espi_oob->wq,
+						      espi_oob->rx_ready);
+			if (rc == -ERESTARTSYS) {
+				rc = -EINTR;
+				goto unlock_mtx_n_out;
+			}
+		}
+	}
+
+	if (espi_oob->dma_mode && espi_ctrl->version != ESPI_AST2500) {
+		rc = aspeed_espi_oob_dma_desc_get_rx(fp, ioc, espi_oob);
+		goto unlock_mtx_n_out;
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_OOB_RX_CTRL, &reg);
+	cyc = (reg & ESPI_OOB_RX_CTRL_CYC_MASK) >> ESPI_OOB_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_OOB_RX_CTRL_TAG_MASK) >> ESPI_OOB_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_OOB_RX_CTRL_LEN_MASK) >> ESPI_OOB_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) + sizeof(struct espi_comm_hdr);
+
+	if (ioc->pkt_len < pkt_len) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_oob->dma_mode) {
+		memcpy(hdr + 1, espi_oob->dma.rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_OOB_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_oob->lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_OOB_RX_CTRL,
+			  ESPI_OOB_RX_CTRL_PEND_SERV,
+			  ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	espi_oob->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_oob->get_rx_mtx);
+
+	return rc;
+}
+
+/* descriptor-based TX DMA handling */
+static long aspeed_espi_oob_dma_desc_put_tx(struct file *fp,
+					    struct aspeed_espi_ioc *ioc,
+					    struct aspeed_espi_oob *espi_oob)
+{
+	int rc = 0;
+	uint32_t rptr, wptr;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct oob_tx_dma_desc *d;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	pkt = vzalloc(ioc->pkt_len);
+	if (!pkt)
+		return -ENOMEM;
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/* kick HW to reflect the up-to-date read/write pointer */
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_RD_PTR,
+		     ESPI_OOB_TX_DMA_RD_PTR_UPDATE);
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_DMA_RD_PTR, &rptr);
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_DMA_WR_PTR, &wptr);
+
+	if (((wptr + 1) % espi_oob->dma.tx_desc_num) == rptr)
+		return -EBUSY;
+
+	d = &espi_oob->dma.tx_desc[wptr];
+	d->cyc = hdr->cyc;
+	d->tag = hdr->tag;
+	d->len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+	d->msg_type = OOB_DMA_TX_DESC_CUST;
+
+	memcpy(espi_oob->dma.tx_virt + (PAGE_SIZE * wptr), hdr + 1,
+	       ioc->pkt_len - sizeof(*hdr));
+
+	dma_wmb();
+
+	wptr = (wptr + 1) % espi_oob->dma.tx_desc_num;
+	wptr |= ESPI_OOB_TX_DMA_WR_PTR_SEND_EN;
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_WR_PTR, wptr);
+
+free_n_out:
+	vfree(pkt);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_put_tx(struct file *fp,
+				   struct aspeed_espi_ioc *ioc,
+				   struct aspeed_espi_oob *espi_oob)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	if (!mutex_trylock(&espi_oob->put_tx_mtx))
+		return -EBUSY;
+
+	if (espi_oob->dma_mode && espi_ctrl->version != ESPI_AST2500) {
+		rc = aspeed_espi_oob_dma_desc_put_tx(fp, ioc, espi_oob);
+		goto unlock_mtx_n_out;
+	}
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_CTRL, &reg);
+	if (reg & ESPI_OOB_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_mtx_n_out;
+	}
+
+	if (ioc->pkt_len > ESPI_PKT_LEN_MAX) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_oob->dma_mode) {
+		memcpy(espi_oob->dma.tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_OOB_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_OOB_TX_CTRL_CYC_SHIFT) & ESPI_OOB_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_OOB_TX_CTRL_TAG_SHIFT) & ESPI_OOB_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_OOB_TX_CTRL_LEN_SHIFT) & ESPI_OOB_TX_CTRL_LEN_MASK)
+		| ESPI_OOB_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_oob->put_tx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_ioctl(struct file *fp, unsigned int cmd,
+				    unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_oob *espi_oob = container_of(
+			fp->private_data,
+			struct aspeed_espi_oob,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_OOB_GET_RX:
+		return aspeed_espi_oob_get_rx(fp, &ioc, espi_oob);
+	case ASPEED_ESPI_OOB_PUT_TX:
+		return aspeed_espi_oob_put_tx(fp, &ioc, espi_oob);
+	};
+
+	return -EINVAL;
+}
+
+static const struct file_operations aspeed_espi_oob_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_oob_ioctl,
+};
+
+static void aspeed_espi_oob_event(uint32_t sts, struct aspeed_espi_oob *espi_oob)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_OOB_RX_CMPLT) {
+		spin_lock_irqsave(&espi_oob->lock, flags);
+		espi_oob->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+		wake_up_interruptible(&espi_oob->wq);
+	}
+}
+
+static void aspeed_espi_oob_enable(struct aspeed_espi_oob *espi_oob)
+{
+	int i;
+	struct aspeed_espi_oob_dma *dma = &espi_oob->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_SW_RDY | ESPI_CTRL_OOB_RX_SW_RST, 0);
+
+	if (espi_oob->dma_mode)
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN, 0);
+	else
+		regmap_write(espi_ctrl->map, ESPI_OOB_RX_CTRL, ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	/*
+	 * cleanup OOB RX FIFO to get rid of the data
+	 * of OOB early init side-effect
+	 */
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_RX_SW_RST, ESPI_CTRL_OOB_RX_SW_RST);
+
+	regmap_write(espi_ctrl->map, ESPI_OOB_RX_CTRL,
+		     ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	if (espi_oob->dma_mode) {
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN);
+
+		if (espi_ctrl->version == ESPI_AST2500) {
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA, dma->tx_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA, dma->rx_addr);
+		} else {
+			for (i = 0; i < dma->tx_desc_num; ++i)
+				dma->tx_desc[i].data_addr = dma->tx_addr + (i * PAGE_SIZE);
+
+			for (i = 0; i < dma->rx_desc_num; ++i) {
+				dma->rx_desc[i].data_addr = dma->rx_addr + (i * PAGE_SIZE);
+				dma->rx_desc[i].dirty = 0;
+			}
+
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA, dma->tx_desc_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_RB_SIZE, dma->tx_desc_num);
+
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA, dma->rx_desc_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA_RB_SIZE, dma->rx_desc_num);
+			regmap_update_bits(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR,
+					   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN,
+					   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN);
+		}
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_OOB_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_OOB_BITS,
+			   ESPI_INT_EN_OOB_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_SW_RDY,
+			   ESPI_CTRL_OOB_SW_RDY);
+}
+
+static void *aspeed_espi_oob_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc = 0;
+	struct aspeed_espi_oob *espi_oob;
+	struct aspeed_espi_oob_dma *dma;
+
+	espi_oob = devm_kzalloc(dev, sizeof(*espi_oob), GFP_KERNEL);
+	if (!espi_oob)
+		return ERR_PTR(-ENOMEM);
+
+	espi_oob->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_oob->wq);
+
+	spin_lock_init(&espi_oob->lock);
+
+	mutex_init(&espi_oob->put_tx_mtx);
+	mutex_init(&espi_oob->get_rx_mtx);
+
+	if (of_property_read_bool(dev->of_node, "oob,dma-mode"))
+		espi_oob->dma_mode = 1;
+
+	if (espi_oob->dma_mode) {
+		dma = &espi_oob->dma;
+
+		/* Descriptor based OOB DMA is supported since AST2600 */
+		if (espi_ctrl->version != ESPI_AST2500) {
+			of_property_read_u32(dev->of_node, "oob,dma-tx-desc-num",
+					     &dma->tx_desc_num);
+			of_property_read_u32(dev->of_node, "oob,dma-rx-desc-num",
+					     &dma->rx_desc_num);
+
+			if (!dma->tx_desc_num || !dma->rx_desc_num) {
+				dev_err(dev, "invalid zero number of DMA channels\n");
+				return ERR_PTR(-EINVAL);
+			}
+
+			if (dma->tx_desc_num >= OOB_DMA_DESC_MAX_NUM ||
+			    dma->rx_desc_num >= OOB_DMA_DESC_MAX_NUM) {
+				dev_err(dev, "too many number of DMA channels\n");
+				return ERR_PTR(-EINVAL);
+			}
+
+			dma->tx_desc = dma_alloc_coherent(dev,
+							  sizeof(*dma->tx_desc) * dma->tx_desc_num,
+							  &dma->tx_desc_addr, GFP_KERNEL);
+			if (!dma->tx_desc) {
+				dev_err(dev, "cannot allocate DMA TX descriptor\n");
+				return ERR_PTR(-ENOMEM);
+			}
+
+			dma->rx_desc = dma_alloc_coherent(dev,
+							  sizeof(*dma->rx_desc) * dma->rx_desc_num,
+							  &dma->rx_desc_addr, GFP_KERNEL);
+			if (!dma->rx_desc) {
+				dev_err(dev, "cannot allocate DMA RX descriptor\n");
+				return ERR_PTR(-ENOMEM);
+			}
+		}
+
+		/*
+		 * DMA descriptors are consumed in the circular
+		 * queue paradigm. Therefore, one dummy slot is
+		 * reserved to detect the full condition.
+		 *
+		 * For AST2500 without DMA descriptors supported,
+		 * the number of the queue slot should be 1 here.
+		 */
+		dma->tx_desc_num += 1;
+		dma->rx_desc_num += 1;
+
+		dma->tx_virt = dma_alloc_coherent(dev, PAGE_SIZE * dma->tx_desc_num,
+						  &dma->tx_addr, GFP_KERNEL);
+		if (!dma->tx_virt) {
+			dev_err(dev, "cannot allocate DMA TX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->rx_virt = dma_alloc_coherent(dev, PAGE_SIZE * dma->rx_desc_num,
+						  &dma->rx_addr, GFP_KERNEL);
+		if (!dma->rx_virt) {
+			dev_err(dev, "cannot allocate DMA RX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	espi_oob->mdev.parent = dev;
+	espi_oob->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_oob->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", OOB_MDEV_NAME);
+	espi_oob->mdev.fops = &aspeed_espi_oob_fops;
+	rc = misc_register(&espi_oob->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_oob_enable(espi_oob);
+
+	return espi_oob;
+}
+
+static void aspeed_espi_oob_free(struct device *dev, struct aspeed_espi_oob *espi_oob)
+{
+	struct aspeed_espi_oob_dma *dma = &espi_oob->dma;
+
+	if (espi_oob->dma_mode) {
+		dma_free_coherent(dev, sizeof(*dma->tx_desc) * dma->tx_desc_num,
+				  dma->tx_desc, dma->tx_desc_addr);
+		dma_free_coherent(dev, sizeof(*dma->rx_desc) * dma->rx_desc_num,
+				  dma->rx_desc, dma->rx_desc_addr);
+		dma_free_coherent(dev, PAGE_SIZE * dma->tx_desc_num,
+				  dma->tx_virt, dma->tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE * dma->rx_desc_num,
+				  dma->rx_virt, dma->rx_addr);
+	}
+
+	mutex_destroy(&espi_oob->put_tx_mtx);
+	mutex_destroy(&espi_oob->get_rx_mtx);
+
+	misc_deregister(&espi_oob->mdev);
+}
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-perif.h b/drivers/soc/aspeed/aspeed-espi-perif.h
new file mode 100644
index 000000000000..f24818227c18
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-perif.h
@@ -0,0 +1,512 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ *
+ * This header includes the data strcuture and the handler
+ * for eSPI peripheral channel. It is part of Aspeed eSPI
+ * slave driver implementation
+ */
+#ifndef _ASPEED_ESPI_PERIF_H_
+#define _ASPEED_ESPI_PERIF_H_
+
+#define PERIF_MDEV_NAME		"aspeed-espi-peripheral"
+#define PERIF_MEMCYC_UNLOCK_KEY	0xfedc756e
+#define PERIF_MEMCYC_SIZE_MIN	0x10000
+
+struct aspeed_espi_perif_dma {
+	void *pc_tx_virt;
+	dma_addr_t pc_tx_addr;
+	void *pc_rx_virt;
+	dma_addr_t pc_rx_addr;
+	void *np_tx_virt;
+	dma_addr_t np_tx_addr;
+};
+
+struct aspeed_espi_perif {
+	uint32_t mcyc_enable;
+	void *mcyc_virt;
+	phys_addr_t mcyc_saddr;
+	phys_addr_t mcyc_taddr;
+	uint32_t mcyc_size;
+	uint32_t mcyc_mask;
+
+	uint32_t dma_mode;
+	struct aspeed_espi_perif_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	spinlock_t rx_lock;
+	struct mutex pc_tx_lock;
+	struct mutex np_tx_lock;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+static long aspeed_espi_perif_pc_get_rx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	unsigned long flags;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (!espi_perif->rx_ready) {
+		if (fp->f_flags & O_NONBLOCK)
+			return -ENODATA;
+
+		rc = wait_event_interruptible(espi_perif->wq, espi_perif->rx_ready);
+		if (rc == -ERESTARTSYS)
+			return -EINTR;
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_PERIF_PC_RX_CTRL, &reg);
+	cyc = (reg & ESPI_PERIF_PC_RX_CTRL_CYC_MASK) >> ESPI_PERIF_PC_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_PERIF_PC_RX_CTRL_TAG_MASK) >> ESPI_PERIF_PC_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_PERIF_PC_RX_CTRL_LEN_MASK) >> ESPI_PERIF_PC_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	switch (cyc) {
+	case ESPI_PERIF_MSG:
+		pkt_len = len + sizeof(struct espi_perif_msg);
+		break;
+	case ESPI_PERIF_MSG_D:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_perif_msg);
+		break;
+	case ESPI_PERIF_SUC_CMPLT_D_MIDDLE:
+	case ESPI_PERIF_SUC_CMPLT_D_FIRST:
+	case ESPI_PERIF_SUC_CMPLT_D_LAST:
+	case ESPI_PERIF_SUC_CMPLT_D_ONLY:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_perif_cmplt);
+		break;
+	case ESPI_PERIF_SUC_CMPLT:
+	case ESPI_PERIF_UNSUC_CMPLT:
+		pkt_len = len + sizeof(struct espi_perif_cmplt);
+		break;
+	default:
+		return -EFAULT;
+	}
+
+	if (ioc->pkt_len < pkt_len)
+		return -EINVAL;
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt)
+		return -ENOMEM;
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_perif->dma_mode) {
+		memcpy(hdr + 1, espi_perif->dma.pc_rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_PERIF_PC_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len))
+		return -EFAULT;
+
+	spin_lock_irqsave(&espi_perif->rx_lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_PERIF_PC_RX_CTRL,
+			  ESPI_PERIF_PC_RX_CTRL_PEND_SERV,
+			  ESPI_PERIF_PC_RX_CTRL_PEND_SERV);
+
+	espi_perif->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_perif->rx_lock, flags);
+
+	return pkt_len;
+}
+
+static long aspeed_espi_perif_pc_put_tx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (!mutex_trylock(&espi_perif->pc_tx_lock))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_PERIF_PC_TX_CTRL, &reg);
+	if (reg & ESPI_PERIF_PC_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_perif->dma_mode) {
+		memcpy(espi_perif->dma.pc_tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_PERIF_PC_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_PERIF_PC_TX_CTRL_CYC_SHIFT) & ESPI_PERIF_PC_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_PERIF_PC_TX_CTRL_TAG_SHIFT) & ESPI_PERIF_PC_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_PERIF_PC_TX_CTRL_LEN_SHIFT) & ESPI_PERIF_PC_TX_CTRL_LEN_MASK)
+		| ESPI_PERIF_PC_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_PERIF_PC_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_n_out:
+	mutex_unlock(&espi_perif->pc_tx_lock);
+
+	return rc;
+}
+
+static long aspeed_espi_perif_np_put_tx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (!mutex_trylock(&espi_perif->np_tx_lock))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_PERIF_NP_TX_CTRL, &reg);
+	if (reg & ESPI_PERIF_NP_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_perif->dma_mode) {
+		memcpy(espi_perif->dma.np_tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_PERIF_NP_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_PERIF_NP_TX_CTRL_CYC_SHIFT) & ESPI_PERIF_NP_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_PERIF_NP_TX_CTRL_TAG_SHIFT) & ESPI_PERIF_NP_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_PERIF_NP_TX_CTRL_LEN_SHIFT) & ESPI_PERIF_NP_TX_CTRL_LEN_MASK)
+		| ESPI_PERIF_NP_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_PERIF_NP_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_n_out:
+	mutex_unlock(&espi_perif->np_tx_lock);
+
+	return rc;
+
+}
+
+static long aspeed_espi_perif_ioctl(struct file *fp, unsigned int cmd,
+				    unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_perif *espi_perif = container_of(
+			fp->private_data,
+			struct aspeed_espi_perif,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_PERIF_PC_GET_RX:
+		return aspeed_espi_perif_pc_get_rx(fp, &ioc, espi_perif);
+	case ASPEED_ESPI_PERIF_PC_PUT_TX:
+		return aspeed_espi_perif_pc_put_tx(fp, &ioc, espi_perif);
+	case ASPEED_ESPI_PERIF_NP_PUT_TX:
+		return aspeed_espi_perif_np_put_tx(fp, &ioc, espi_perif);
+	};
+
+	return -EINVAL;
+}
+
+static int aspeed_espi_perif_mmap(struct file *fp, struct vm_area_struct *vma)
+{
+	struct aspeed_espi_perif *espi_perif = container_of(
+			fp->private_data,
+			struct aspeed_espi_perif,
+			mdev);
+	unsigned long vm_size = vma->vm_end - vma->vm_start;
+	pgprot_t prot = vma->vm_page_prot;
+
+	if (!espi_perif->mcyc_enable)
+		return -EPERM;
+
+	if (((vma->vm_pgoff << PAGE_SHIFT) + vm_size) > espi_perif->mcyc_size)
+		return -EINVAL;
+
+	prot = pgprot_noncached(prot);
+
+	if (remap_pfn_range(vma, vma->vm_start,
+			    (espi_perif->mcyc_taddr >> PAGE_SHIFT) + vma->vm_pgoff,
+			    vm_size, prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static const struct file_operations aspeed_espi_perif_fops = {
+	.owner = THIS_MODULE,
+	.mmap = aspeed_espi_perif_mmap,
+	.unlocked_ioctl = aspeed_espi_perif_ioctl,
+};
+
+static void aspeed_espi_perif_event(uint32_t sts, struct aspeed_espi_perif *espi_perif)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_PERIF_PC_RX_CMPLT) {
+		spin_lock_irqsave(&espi_perif->rx_lock, flags);
+		espi_perif->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_perif->rx_lock, flags);
+
+		wake_up_interruptible(&espi_perif->wq);
+	}
+}
+
+static void aspeed_espi_perif_enable(struct aspeed_espi_perif *espi_perif)
+{
+	struct aspeed_espi_perif_dma *dma = &espi_perif->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (espi_perif->mcyc_enable) {
+		if (espi_ctrl->version == ESPI_AST2500) {
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     PERIF_MEMCYC_UNLOCK_KEY);
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     espi_perif->mcyc_mask);
+		} else {
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     espi_perif->mcyc_mask | ESPI_PERIF_PC_RX_MASK_CFG_WP);
+			regmap_update_bits(espi_ctrl->map, ESPI_CTRL2,
+					   ESPI_CTRL2_MEMCYC_RD_DIS | ESPI_CTRL2_MEMCYC_WR_DIS, 0);
+		}
+
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_SADDR, espi_perif->mcyc_saddr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_TADDR, espi_perif->mcyc_taddr);
+	}
+
+	if (espi_perif->dma_mode) {
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_DMA, dma->pc_rx_addr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_TX_DMA, dma->pc_tx_addr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_NP_TX_DMA, dma->np_tx_addr);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_PERIF_NP_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_RX_DMA_EN,
+				   ESPI_CTRL_PERIF_NP_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_RX_DMA_EN);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_PERIF_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_PERIF_BITS,
+			   ESPI_INT_EN_PERIF_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_PERIF_SW_RDY,
+			   ESPI_CTRL_PERIF_SW_RDY);
+}
+
+static void *aspeed_espi_perif_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc;
+	struct aspeed_espi_perif *espi_perif;
+	struct aspeed_espi_perif_dma *dma;
+
+	espi_perif = devm_kzalloc(dev, sizeof(*espi_perif), GFP_KERNEL);
+	if (!espi_perif)
+		return ERR_PTR(-ENOMEM);
+
+	espi_perif->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_perif->wq);
+
+	spin_lock_init(&espi_perif->rx_lock);
+
+	mutex_init(&espi_perif->pc_tx_lock);
+	mutex_init(&espi_perif->np_tx_lock);
+
+	espi_perif->mcyc_enable = of_property_read_bool(dev->of_node, "perif,memcyc-enable");
+	if (espi_perif->mcyc_enable) {
+		rc = of_property_read_u32(dev->of_node, "perif,memcyc-src-addr",
+					  &espi_perif->mcyc_saddr);
+		if (rc) {
+			dev_err(dev, "cannot get Host source address for memory cycle\n");
+			return ERR_PTR(-ENODEV);
+		}
+
+		rc = of_property_read_u32(dev->of_node, "perif,memcyc-size",
+					  &espi_perif->mcyc_size);
+		if (rc) {
+			dev_err(dev, "cannot get size for memory cycle\n");
+			return ERR_PTR(-ENODEV);
+		}
+
+		if (espi_perif->mcyc_size < PERIF_MEMCYC_SIZE_MIN)
+			espi_perif->mcyc_size = PERIF_MEMCYC_SIZE_MIN;
+		else
+			espi_perif->mcyc_size = roundup_pow_of_two(espi_perif->mcyc_size);
+
+		espi_perif->mcyc_mask = ~(espi_perif->mcyc_size - 1);
+		espi_perif->mcyc_virt = dma_alloc_coherent(dev, espi_perif->mcyc_size,
+							   &espi_perif->mcyc_taddr, GFP_KERNEL);
+		if (!espi_perif->mcyc_virt) {
+			dev_err(dev, "cannot allocate memory cycle region\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	if (of_property_read_bool(dev->of_node, "perif,dma-mode")) {
+		dma = &espi_perif->dma;
+
+		dma->pc_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						     &dma->pc_tx_addr, GFP_KERNEL);
+		if (!dma->pc_tx_virt) {
+			dev_err(dev, "cannot allocate posted TX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->pc_rx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						     &dma->pc_rx_addr, GFP_KERNEL);
+		if (!dma->pc_rx_virt) {
+			dev_err(dev, "cannot allocate posted RX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->np_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+				&dma->np_tx_addr, GFP_KERNEL);
+		if (!dma->np_tx_virt) {
+			dev_err(dev, "cannot allocate non-posted TX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		espi_perif->dma_mode = 1;
+	}
+
+	espi_perif->mdev.parent = dev;
+	espi_perif->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_perif->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", PERIF_MDEV_NAME);
+	espi_perif->mdev.fops = &aspeed_espi_perif_fops;
+	rc = misc_register(&espi_perif->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_perif_enable(espi_perif);
+
+	return espi_perif;
+}
+
+static void aspeed_espi_perif_free(struct device *dev, struct aspeed_espi_perif *espi_perif)
+{
+	struct aspeed_espi_perif_dma *dma = &espi_perif->dma;
+
+	if (espi_perif->mcyc_virt)
+		dma_free_coherent(dev, espi_perif->mcyc_size,
+				  espi_perif->mcyc_virt,
+				  espi_perif->mcyc_taddr);
+
+	if (espi_perif->dma_mode) {
+		dma_free_coherent(dev, PAGE_SIZE, dma->pc_tx_virt,
+				  dma->pc_tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->pc_rx_virt,
+				  dma->pc_rx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->np_tx_virt,
+				  dma->np_tx_addr);
+	}
+
+	mutex_destroy(&espi_perif->pc_tx_lock);
+	mutex_destroy(&espi_perif->np_tx_lock);
+
+	misc_deregister(&espi_perif->mdev);
+}
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-vw.h b/drivers/soc/aspeed/aspeed-espi-vw.h
new file mode 100644
index 000000000000..3d49366c912e
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-vw.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ *
+ * This header includes the data strcuture and the handler
+ * for eSPI virtual wire channel. It is part of Aspeed eSPI
+ * slave driver implementation
+ */
+#ifndef _ASPEED_ESPI_VW_H_
+#define _ASPEED_ESPI_VW_H_
+
+#define VW_MDEV_NAME	"aspeed-espi-vw"
+
+struct aspeed_espi_vw {
+	int irq;
+	int irq_reset;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+static long aspeed_espi_vw_ioctl(struct file *fp, unsigned int cmd,
+				    unsigned long arg)
+{
+	uint32_t val;
+
+	struct aspeed_espi_vw *espi_vw = container_of(
+			fp->private_data,
+			struct aspeed_espi_vw,
+			mdev);
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	switch (cmd) {
+	case ASPEED_ESPI_VW_GET_GPIO_VAL:
+		regmap_read(espi_ctrl->map, ESPI_VW_GPIO_VAL, &val);
+		if (put_user(val, (uint32_t __user *)arg))
+			return -EFAULT;
+		break;
+
+	case ASPEED_ESPI_VW_PUT_GPIO_VAL:
+		if (get_user(val, (uint32_t __user *)arg))
+			return -EFAULT;
+		regmap_write(espi_ctrl->map, ESPI_VW_GPIO_VAL, val);
+		break;
+
+	default:
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
+static const struct file_operations aspeed_espi_vw_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_vw_ioctl,
+};
+
+static void aspeed_espi_vw_event(uint32_t sts, struct aspeed_espi_vw *espi_vw)
+{
+	uint32_t sysevt_sts;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	regmap_read(espi_ctrl->map, ESPI_INT_STS, &sts);
+
+	if (sts & ESPI_INT_STS_VW_SYSEVT) {
+		regmap_read(espi_ctrl->map, ESPI_SYSEVT_INT_STS, &sysevt_sts);
+
+		if (espi_ctrl->version == ESPI_AST2500) {
+			if (sysevt_sts & ESPI_SYSEVT_INT_STS_HOST_RST_WARN)
+				regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+						   ESPI_SYSEVT_HOST_RST_ACK,
+						   ESPI_SYSEVT_HOST_RST_ACK);
+
+			if (sysevt_sts & ESPI_SYSEVT_INT_STS_OOB_RST_WARN)
+				regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+						   ESPI_SYSEVT_OOB_RST_ACK,
+						   ESPI_SYSEVT_OOB_RST_ACK);
+		}
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_STS, sysevt_sts);
+	}
+
+	if (sts & ESPI_INT_STS_VW_SYSEVT1) {
+		regmap_read(espi_ctrl->map, ESPI_SYSEVT1_INT_STS, &sysevt_sts);
+
+		if (sysevt_sts & ESPI_SYSEVT1_INT_STS_SUSPEND_WARN)
+			regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT1,
+					   ESPI_SYSEVT1_SUSPEND_ACK,
+					   ESPI_SYSEVT1_SUSPEND_ACK);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_STS, sysevt_sts);
+	}
+}
+
+static void aspeed_espi_vw_enable(struct aspeed_espi_vw *espi_vw)
+{
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_VW_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_VW_BITS,
+			   ESPI_INT_EN_VW_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_VW_SW_RDY,
+			   ESPI_CTRL_VW_SW_RDY);
+}
+
+static void *aspeed_espi_vw_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc;
+	struct aspeed_espi_vw *espi_vw;
+
+	espi_vw = devm_kzalloc(dev, sizeof(*espi_vw), GFP_KERNEL);
+	if (!espi_vw)
+		return ERR_PTR(-ENOMEM);
+
+	espi_vw->ctrl = espi_ctrl;
+
+	espi_vw->mdev.parent = dev;
+	espi_vw->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_vw->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", VW_MDEV_NAME);
+	espi_vw->mdev.fops = &aspeed_espi_vw_fops;
+	rc = misc_register(&espi_vw->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_vw_enable(espi_vw);
+
+	return espi_vw;
+}
+
+static void aspeed_espi_vw_free(struct device *dev, struct aspeed_espi_vw *espi_vw)
+{
+	misc_deregister(&espi_vw->mdev);
+}
+
+#endif
-- 
2.17.1



From oupton at google.com  Thu Aug 19 01:10:06 2021
From: oupton at google.com (Oliver Upton)
Date: Thu, 19 Aug 2021 01:10:06 -0700
Subject: [PATCH v4 15/15] KVM: arm64: Handle protected guests at 32 bits
In-Reply-To: <20210817081134.2918285-16-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-16-tabba@google.com>
Message-ID: <CAOQ_QsgSfHVjJkSJku5DwUe0_=ds4GduPbJ7vC-t+4_=fPVFBQ@mail.gmail.com>

Hi Fuad,

On Tue, Aug 17, 2021 at 1:12 AM Fuad Tabba <tabba at google.com> wrote:
>
> Protected KVM does not support protected AArch32 guests. However,
> it is possible for the guest to force run AArch32, potentially
> causing problems. Add an extra check so that if the hypervisor
> catches the guest doing that, it can prevent the guest from
> running again by resetting vcpu->arch.target and returning
> ARM_EXCEPTION_IL.
>
> If this were to happen, The VMM can try and fix it by re-
> initializing the vcpu with KVM_ARM_VCPU_INIT, however, this is
> likely not possible for protected VMs.
>
> Adapted from commit 22f553842b14 ("KVM: arm64: Handle Asymmetric
> AArch32 systems")
>
> Signed-off-by: Fuad Tabba <tabba at google.com>
> ---
>  arch/arm64/kvm/hyp/nvhe/switch.c | 37 ++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index 398e62098898..0c24b7f473bf 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -20,6 +20,7 @@
>  #include <asm/kprobes.h>
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
> +#include <asm/kvm_fixed_config.h>
>  #include <asm/kvm_hyp.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/fpsimd.h>
> @@ -195,6 +196,39 @@ exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
>                 return NULL;
>  }
>
> +/*
> + * Some guests (e.g., protected VMs) might not be allowed to run in AArch32. The
> + * check below is based on the one in kvm_arch_vcpu_ioctl_run().
> + * The ARMv8 architecture does not give the hypervisor a mechanism to prevent a
> + * guest from dropping to AArch32 EL0 if implemented by the CPU. If the
> + * hypervisor spots a guest in such a state ensure it is handled, and don't
> + * trust the host to spot or fix it.
> + *
> + * Returns true if the check passed and the guest run loop can continue, or
> + * false if the guest should exit to the host.
> + */
> +static bool check_aarch32_guest(struct kvm_vcpu *vcpu, u64 *exit_code)

This does a bit more than just check & return, so maybe call it
handle_aarch32_guest()?

> +{
> +       if (kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)) &&

maybe initialize a local with a hyp pointer to the kvm structure.

> +           vcpu_mode_is_32bit(vcpu) &&
> +           FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0),
> +                                        PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) <
> +               ID_AA64PFR0_ELx_32BIT_64BIT) {

It may be more readable to initialize a local variable with this
feature check, i.e:

bool aarch32_allowed = FIELD_GET(...) == ID_AA64PFR0_ELx_32BIT_64BIT;

and then:

  if (kvm_vm_is_protected(kvm) && vcpu_mode_is_32bit(vcpu) &&
!aarch32_allowed) {

> +               /*
> +                * As we have caught the guest red-handed, decide that it isn't
> +                * fit for purpose anymore by making the vcpu invalid. The VMM
> +                * can try and fix it by re-initializing the vcpu with
> +                * KVM_ARM_VCPU_INIT, however, this is likely not possible for
> +                * protected VMs.
> +                */
> +               vcpu->arch.target = -1;
> +               *exit_code = ARM_EXCEPTION_IL;
> +               return false;
> +       }
> +
> +       return true;
> +}
> +
>  /* Switch to the guest for legacy non-VHE systems */
>  int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>  {
> @@ -255,6 +289,9 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
>                 /* Jump in the fire! */
>                 exit_code = __guest_enter(vcpu);
>
> +               if (unlikely(!check_aarch32_guest(vcpu, &exit_code)))
> +                       break;
> +
>                 /* And we're baaack! */
>         } while (fixup_guest_exit(vcpu, &exit_code));
>
> --
> 2.33.0.rc1.237.g0d66db33f3-goog
>


From arnd at arndb.de  Thu Aug 19 01:10:26 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 19 Aug 2021 10:10:26 +0200
Subject: [PATCH] arm64: dts: synaptics: remove unused DTSI for AS370
In-Reply-To: <20210819143735.5171af23@xhacker.debian>
References: <20210806082635.20239-1-krzysztof.kozlowski@canonical.com>
 <YRbDNInfG7caSr2r@robh.at.kernel.org>
 <CAK8P3a0QtpBq8i2_RhW=isLSNULc2z7DbjohZReMY+rhyXEbJA@mail.gmail.com>
 <20210819143735.5171af23@xhacker.debian>
Message-ID: <CAK8P3a3jk-iGC3UjB95A50hFxfJGaFxq8cjGm22aKZU7HVK-dg@mail.gmail.com>

On Thu, Aug 19, 2021 at 8:38 AM Jisheng Zhang
<Jisheng.Zhang at synaptics.com> wrote:
> On Fri, 13 Aug 2021 22:43:26 +0200 Arnd Bergmann wrote:
> > On Fri, Aug 13, 2021 at 9:09 PM Rob Herring <robh at kernel.org> wrote:
> > > On Fri, 06 Aug 2021 10:26:35 +0200, Krzysztof Kozlowski wrote:
> > > > The as370.dtsi for Synaptics AS370 SoC does not have a user (DTS board
> > > > file), is uncompilable and untestable.  It was added back in 2018.  No
> > > > user appeared since that time, so assume it won't be added.
> > > >
> > > > Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > > > ---
> > > >  .../devicetree/bindings/arm/syna.txt          |   4 -
> > > >  arch/arm64/boot/dts/synaptics/as370.dtsi      | 173 ------------------
> > > >  2 files changed, 177 deletions(-)
> > > >  delete mode 100644 arch/arm64/boot/dts/synaptics/as370.dtsi
> > > >
> > >
> > > I assume Arnd/Olof will take this.
> > >
> > > Acked-by: Rob Herring <robh at kernel.org>
> >
> > Sure, I can take that, but it would be nice to hear anything from Jisheng Zhang
> > about this.
> >
> > I can see that the only two 64-bit Synaptics SoCs are as370 and bg4ct,
> > but both of them have apparently been replaced with newer versions that
> > never made it into the kernel: as371, as390, bg5ct, according to press
> > releases.
> >
> > Jisheng, can you clarify whether you plan to complete the as370 support
> > or add the later SoCs?
>
> Hi Arnd, Rob, Krzysztof
>
> Sorry for being late. I was on vocation in the past several days.
> As for this as370 removing, I think we'd better keep it. I planned
> to submit the as370-rdk board dts two years ago, but latter I focused
> on Synaptics SoCs related drivers support such as gpio, pcie, sdhci and
> so on. I will send a basic as370 rdk board dts. I'm also considering
> to mainline basic support for a new SoC.

Ok, sounds good. Let's keep it for now then. If you have the dts file at
hand, please send the patch to soc at kernel.org directly so I can still
apply it for 5.15 to enable it for build testing, even if it's still missing
functionality.

        Arnd


From maz at kernel.org  Thu Aug 19 01:15:17 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Aug 2021 09:15:17 +0100
Subject: [PATCH] arm64: initialize all of CNTHCTL_EL2
In-Reply-To: <20210818161535.52786-1-mark.rutland@arm.com>
References: <20210818161535.52786-1-mark.rutland@arm.com>
Message-ID: <875yw1sve2.wl-maz@kernel.org>

On Wed, 18 Aug 2021 17:15:35 +0100,
Mark Rutland <mark.rutland at arm.com> wrote:
> 
> In __init_el2_timers we initialize CNTHCTL_EL2.{EL1PCEN,EL1PCTEN} with a
> RMW sequence, leaving all other bits UNKNOWN.
> 
> In general, we should initialize all bits in a register rather than
> using an RMW sequence, since most bits are UNKNOWN out of reset, and as
> new bits are added to the reigster their reset value might not result in
> expected behaviour.
> 
> In the case of CNTHCTL_EL2, FEAT_ECV added a number of new control bits
> in previously RES0 bits, which reset to UNKNOWN values, and may cause
> issues for EL1 and EL0:
> 
> * CNTHCTL_EL2.ECV enables the CNTPOFF_EL2 offset (which itself resets to
>   an UNKNOWN value) at EL0 and EL1. Since the offset could reset to
>   distinct values across CPUs, when the control bit resets to 1 this
>   could break timekeeping generally.
> 
> * CNTHCTL_EL2.{EL1TVT,EL1TVCT} trap EL0 and EL1 accesses to the EL1
>   virtual timer/counter registers to EL2. When reset to 1, this could
>   cause unexpected traps to EL2.
> 
> Initializing these bits to zero avoids these problems, and all other
> bits in CNPTOFF_EL2 other than EL1PCEN and EL1PCTEN can safely be reset
> to zero.
> 
> This patch ensures we initialize CNTHCTL_EL2 accordingly, only setting
> EL1PCEN and EL1PCTEN, and setting all other bits to zero.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Oliver Upton <oupton at google.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/el2_setup.h | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index 21fa330f498dd..b83fb24954b77 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -33,8 +33,7 @@
>   * EL2.
>   */
>  .macro __init_el2_timers
> -	mrs	x0, cnthctl_el2
> -	orr	x0, x0, #3			// Enable EL1 physical timers
> +	mov	x0, #3				// Enable EL1 physical timers
>  	msr	cnthctl_el2, x0
>  	msr	cntvoff_el2, xzr		// Clear virtual offset
>  .endm

With the typo spotted by Oliver fixed:

Acked-by: Marc Zyngier <maz at kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


From jiapeng.chong at linux.alibaba.com  Thu Aug 19 01:29:09 2021
From: jiapeng.chong at linux.alibaba.com (Jiapeng Chong)
Date: Thu, 19 Aug 2021 16:29:09 +0800
Subject: [PATCH] soc: rockchip: io-domain: Remove unneeded semicolon
Message-ID: <1629361749-97977-1-git-send-email-jiapeng.chong@linux.alibaba.com>

Fix the following coccicheck warnings:

./drivers/soc/rockchip/io-domain.c:118:2-3: Unneeded semicolon.

Reported-by: Abaci Robot <abaci at linux.alibaba.com>
Signed-off-by: Jiapeng Chong <jiapeng.chong at linux.alibaba.com>
---
 drivers/soc/rockchip/io-domain.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c
index 13c446f..9df513d1 100644
--- a/drivers/soc/rockchip/io-domain.c
+++ b/drivers/soc/rockchip/io-domain.c
@@ -115,7 +115,7 @@ static int rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uV
 		break;
 	default:
 		return -EINVAL;
-	};
+	}
 
 	return 0;
 }
-- 
1.8.3.1



From trevor.wu at mediatek.com  Thu Aug 19 01:41:34 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:34 +0800
Subject: [PATCH v5 01/11] ASoC: mediatek: mt8195: update mediatek common driver
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-2-trevor.wu@mediatek.com>

Update mediatek common driver to support MT8195

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 sound/soc/mediatek/common/mtk-afe-fe-dai.c | 22 +++++++++++++++++++---
 sound/soc/mediatek/common/mtk-base-afe.h   | 10 ++++++++--
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
index 3cb2adf420bb..baaa5881b1d4 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -139,7 +139,7 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
 		substream->runtime->dma_area,
 		substream->runtime->dma_bytes);
 
-	memset_io(substream->runtime->dma_area, 0,
+	memset_io((void __force __iomem *)substream->runtime->dma_area, 0,
 		  substream->runtime->dma_bytes);
 
 	/* set addr */
@@ -433,11 +433,20 @@ int mtk_memif_set_addr(struct mtk_base_afe *afe, int id,
 				 phys_buf_addr_upper_32);
 	}
 
-	/* set MSB to 33-bit */
-	if (memif->data->msb_reg >= 0)
+	/*
+	 * set MSB to 33-bit, for memif address
+	 * only for memif base address, if msb_end_reg exists
+	 */
+	if (memif->data->msb_reg)
 		mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg,
 				       1, msb_at_bit33, memif->data->msb_shift);
 
+	/* set MSB to 33-bit, for memif end address */
+	if (memif->data->msb_end_reg)
+		mtk_regmap_update_bits(afe->regmap, memif->data->msb_end_reg,
+				       1, msb_at_bit33,
+				       memif->data->msb_end_shift);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_memif_set_addr);
@@ -464,6 +473,13 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe,
 	else
 		mono = (channel == 1) ? 1 : 0;
 
+	/* for specific configuration of memif mono mode */
+	if (memif->data->int_odd_flag_reg)
+		mtk_regmap_update_bits(afe->regmap,
+				       memif->data->int_odd_flag_reg,
+				       1, mono,
+				       memif->data->int_odd_flag_shift);
+
 	return mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg,
 				      1, mono, memif->data->mono_shift);
 }
diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h
index a6f68c68581c..ef83e78c22a8 100644
--- a/sound/soc/mediatek/common/mtk-base-afe.h
+++ b/sound/soc/mediatek/common/mtk-base-afe.h
@@ -29,6 +29,8 @@ struct mtk_base_memif_data {
 	int quad_ch_reg;
 	int quad_ch_mask;
 	int quad_ch_shift;
+	int int_odd_flag_reg;
+	int int_odd_flag_shift;
 	int enable_reg;
 	int enable_shift;
 	int hd_reg;
@@ -37,10 +39,13 @@ struct mtk_base_memif_data {
 	int hd_align_mshift;
 	int msb_reg;
 	int msb_shift;
-	int msb2_reg;
-	int msb2_shift;
+	int msb_end_reg;
+	int msb_end_shift;
 	int agent_disable_reg;
 	int agent_disable_shift;
+	int ch_num_reg;
+	int ch_num_shift;
+	int ch_num_maskbit;
 	/* playback memif only */
 	int pbuf_reg;
 	int pbuf_mask;
@@ -62,6 +67,7 @@ struct mtk_base_irq_data {
 	int irq_en_shift;
 	int irq_clr_reg;
 	int irq_clr_shift;
+	int irq_status_shift;
 };
 
 struct device;
-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:44 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:44 +0800
Subject: [PATCH v5 11/11] dt-bindings: mediatek: mt8195: add
 mt8195-mt6359-rt1019-rt5682 document
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-12-trevor.wu@mediatek.com>

This patch adds document for mt8195 board with mt6359, rt1019 and rt5682

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 .../sound/mt8195-mt6359-rt1019-rt5682.yaml    | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml

diff --git a/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
new file mode 100644
index 000000000000..20bc0ffd0e34
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1019-rt5682.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT8195 with MT6359, RT1019 and RT5682 ASoC sound card driver
+
+maintainers:
+  - Trevor Wu <trevor.wu at mediatek.com>
+
+description:
+  This binding describes the MT8195 sound card.
+
+properties:
+  compatible:
+    const: mediatek,mt8195_mt6359_rt1019_rt5682
+
+  mediatek,platform:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of MT8195 ASoC platform.
+
+  mediatek,dptx-codec:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of MT8195 Display Port Tx codec node.
+
+  mediatek,hdmi-codec:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of MT8195 HDMI codec node.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - mediatek,platform
+
+examples:
+  - |
+
+    sound: mt8195-sound {
+        compatible = "mediatek,mt8195_mt6359_rt1019_rt5682";
+        mediatek,platform = <&afe>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&aud_pins_default>;
+    };
+
+...
-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:33 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:33 +0800
Subject: [PATCH v5 00/11] ASoC: mediatek: Add support for MT8195 SoC
Message-ID: <20210819084144.18483-1-trevor.wu@mediatek.com>

This series of patches adds support for Mediatek AFE of MT8195 SoC.
Patches are based on broonie tree "for-next" branch.

Changes since v4:
  - removed sof related code

Changes since v3:
  - fixed warnings found by kernel test robot
  - removed unused critical section
  - corrected the lock protected sections on etdm driver
  - added DPTX and HDMITX audio support

Changes since v2:
  - added audio clock gate control
  - added 'mediatek' prefix to private dts properties
  - added consumed clocks to dt-bindins and adopted suggestions from Rob
  - refined clock usage and remove unused clock and control code
  - fixed typos

Changes since v1:
  - fixed some problems related to dt-bindings
  - added some missing properties to dt-bindings
  - added depency declaration on dt-bindings
  - fixed some warnings found by kernel test robot

Trevor Wu (11):
  ASoC: mediatek: mt8195: update mediatek common driver
  ASoC: mediatek: mt8195: support audsys clock control
  ASoC: mediatek: mt8195: support etdm in platform driver
  ASoC: mediatek: mt8195: support adda in platform driver
  ASoC: mediatek: mt8195: support pcm in platform driver
  ASoC: mediatek: mt8195: add platform driver
  dt-bindings: mediatek: mt8195: add audio afe document
  ASoC: mediatek: mt8195: add machine driver with mt6359, rt1019 and
    rt5682
  ASoC: mediatek: mt8195: add DPTX audio support
  ASoC: mediatek: mt8195: add HDMITX audio support
  dt-bindings: mediatek: mt8195: add mt8195-mt6359-rt1019-rt5682
    document

 .../bindings/sound/mt8195-afe-pcm.yaml        |  184 +
 .../sound/mt8195-mt6359-rt1019-rt5682.yaml    |   47 +
 sound/soc/mediatek/Kconfig                    |   24 +
 sound/soc/mediatek/Makefile                   |    1 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.c    |   22 +-
 sound/soc/mediatek/common/mtk-base-afe.h      |   10 +-
 sound/soc/mediatek/mt8195/Makefile            |   15 +
 sound/soc/mediatek/mt8195/mt8195-afe-clk.c    |  441 +++
 sound/soc/mediatek/mt8195/mt8195-afe-clk.h    |  109 +
 sound/soc/mediatek/mt8195/mt8195-afe-common.h |  158 +
 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c    | 3281 +++++++++++++++++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c |  214 ++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h |   15 +
 .../soc/mediatek/mt8195/mt8195-audsys-clkid.h |   93 +
 sound/soc/mediatek/mt8195/mt8195-dai-adda.c   |  830 +++++
 sound/soc/mediatek/mt8195/mt8195-dai-etdm.c   | 2639 +++++++++++++
 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c    |  389 ++
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 1087 ++++++
 sound/soc/mediatek/mt8195/mt8195-reg.h        | 2796 ++++++++++++++
 19 files changed, 12350 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml
 create mode 100644 sound/soc/mediatek/mt8195/Makefile
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-common.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-adda.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-reg.h

-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:38 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:38 +0800
Subject: [PATCH v5 05/11] ASoC: mediatek: mt8195: support pcm in platform
 driver
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-6-trevor.wu@mediatek.com>

This patch adds mt8195 pcm dai driver.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c | 389 +++++++++++++++++++++
 1 file changed, 389 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c

diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
new file mode 100644
index 000000000000..5d10d2c4c991
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c
@@ -0,0 +1,389 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI PCM I/F Control
+ *
+ * Copyright (c) 2020 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai at mediatek.com>
+ *         Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+enum {
+	MTK_DAI_PCM_FMT_I2S,
+	MTK_DAI_PCM_FMT_EIAJ,
+	MTK_DAI_PCM_FMT_MODEA,
+	MTK_DAI_PCM_FMT_MODEB,
+};
+
+enum {
+	MTK_DAI_PCM_CLK_A1SYS,
+	MTK_DAI_PCM_CLK_A2SYS,
+	MTK_DAI_PCM_CLK_26M_48K,
+	MTK_DAI_PCM_CLK_26M_441K,
+};
+
+struct mtk_dai_pcm_rate {
+	unsigned int rate;
+	unsigned int reg_value;
+};
+
+struct mtk_dai_pcmif_priv {
+	unsigned int slave_mode;
+	unsigned int lrck_inv;
+	unsigned int bck_inv;
+	unsigned int format;
+};
+
+static const struct mtk_dai_pcm_rate mtk_dai_pcm_rates[] = {
+	{ .rate = 8000, .reg_value = 0, },
+	{ .rate = 16000, .reg_value = 1, },
+	{ .rate = 32000, .reg_value = 2, },
+	{ .rate = 48000, .reg_value = 3, },
+	{ .rate = 11025, .reg_value = 1, },
+	{ .rate = 22050, .reg_value = 2, },
+	{ .rate = 44100, .reg_value = 3, },
+};
+
+static int mtk_dai_pcm_mode(unsigned int rate)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_dai_pcm_rates); i++)
+		if (mtk_dai_pcm_rates[i].rate == rate)
+			return mtk_dai_pcm_rates[i].reg_value;
+
+	return -EINVAL;
+}
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o000_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN0, 0, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN0_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o001_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN1, 1, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN1_2, 7, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
+	SND_SOC_DAPM_MIXER("I002", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I003", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("O000", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_pcm_o000_mix,
+			   ARRAY_SIZE(mtk_dai_pcm_o000_mix)),
+	SND_SOC_DAPM_MIXER("O001", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_pcm_o001_mix,
+			   ARRAY_SIZE(mtk_dai_pcm_o001_mix)),
+
+	SND_SOC_DAPM_INPUT("PCM1_INPUT"),
+	SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
+	{"I002", NULL, "PCM1 Capture"},
+	{"I003", NULL, "PCM1 Capture"},
+
+	{"O000", "I000 Switch", "I000"},
+	{"O001", "I001 Switch", "I001"},
+
+	{"O000", "I070 Switch", "I070"},
+	{"O001", "I071 Switch", "I071"},
+
+	{"PCM1 Playback", NULL, "O000"},
+	{"PCM1 Playback", NULL, "O001"},
+
+	{"PCM1_OUTPUT", NULL, "PCM1 Playback"},
+	{"PCM1 Capture", NULL, "PCM1_INPUT"},
+};
+
+static void mtk_dai_pcm_enable(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_PCM_EN, PCM_INTF_CON1_PCM_EN);
+}
+
+static void mtk_dai_pcm_disable(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_PCM_EN, 0x0);
+}
+
+static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream,
+				 struct snd_soc_dai *dai)
+{
+	struct snd_pcm_runtime * const runtime = substream->runtime;
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
+	unsigned int slave_mode = pcmif_priv->slave_mode;
+	unsigned int lrck_inv = pcmif_priv->lrck_inv;
+	unsigned int bck_inv = pcmif_priv->bck_inv;
+	unsigned int fmt = pcmif_priv->format;
+	unsigned int bit_width = dai->sample_bits;
+	unsigned int val = 0;
+	unsigned int mask = 0;
+	int fs = 0;
+	int mode = 0;
+
+	/* sync freq mode */
+	fs = mt8195_afe_fs_timing(runtime->rate);
+	if (fs < 0)
+		return -EINVAL;
+	val |= PCM_INTF_CON2_SYNC_FREQ_MODE(fs);
+	mask |= PCM_INTF_CON2_SYNC_FREQ_MODE_MASK;
+
+	/* clk domain sel */
+	if (runtime->rate % 8000)
+		val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_441K);
+	else
+		val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_48K);
+	mask |= PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK;
+
+	regmap_update_bits(afe->regmap, PCM_INTF_CON2, mask, val);
+
+	val = 0;
+	mask = 0;
+
+	/* pcm mode */
+	mode = mtk_dai_pcm_mode(runtime->rate);
+	if (mode < 0)
+		return -EINVAL;
+	val |= PCM_INTF_CON1_PCM_MODE(mode);
+	mask |= PCM_INTF_CON1_PCM_MODE_MASK;
+
+	/* pcm format */
+	val |= PCM_INTF_CON1_PCM_FMT(fmt);
+	mask |= PCM_INTF_CON1_PCM_FMT_MASK;
+
+	/* pcm sync length */
+	if (fmt == MTK_DAI_PCM_FMT_MODEA ||
+	    fmt == MTK_DAI_PCM_FMT_MODEB)
+		val |= PCM_INTF_CON1_SYNC_LENGTH(1);
+	else
+		val |= PCM_INTF_CON1_SYNC_LENGTH(bit_width);
+	mask |= PCM_INTF_CON1_SYNC_LENGTH_MASK;
+
+	/* pcm bits, word length */
+	if (bit_width > 16) {
+		val |= PCM_INTF_CON1_PCM_24BIT;
+		val |= PCM_INTF_CON1_PCM_WLEN_64BCK;
+	} else {
+		val |= PCM_INTF_CON1_PCM_16BIT;
+		val |= PCM_INTF_CON1_PCM_WLEN_32BCK;
+	}
+	mask |= PCM_INTF_CON1_PCM_BIT_MASK;
+	mask |= PCM_INTF_CON1_PCM_WLEN_MASK;
+
+	/* master/slave */
+	if (!slave_mode) {
+		val |= PCM_INTF_CON1_PCM_MASTER;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_OUT_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_OUT_INV;
+		mask |= PCM_INTF_CON1_CLK_OUT_INV_MASK;
+	} else {
+		val |= PCM_INTF_CON1_PCM_SLAVE;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_IN_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_IN_INV;
+		mask |= PCM_INTF_CON1_CLK_IN_INV_MASK;
+
+		/* TODO: add asrc setting for slave mode */
+	}
+	mask |= PCM_INTF_CON1_PCM_M_S_MASK;
+
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1, mask, val);
+
+	return 0;
+}
+
+/* dai ops */
+static int mtk_dai_pcm_startup(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+	if (dai->component->active)
+		return 0;
+
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]);
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]);
+	mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]);
+
+	return 0;
+}
+
+static void mtk_dai_pcm_shutdown(struct snd_pcm_substream *substream,
+				 struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+
+	if (dai->component->active)
+		return;
+
+	mtk_dai_pcm_disable(afe);
+
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]);
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]);
+	mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]);
+}
+
+static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	int ret = 0;
+
+	if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) &&
+	    snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE))
+		return 0;
+
+	ret = mtk_dai_pcm_configure(substream, dai);
+	if (ret)
+		return ret;
+
+	mtk_dai_pcm_enable(afe);
+
+	return 0;
+}
+
+static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id];
+
+	dev_dbg(dai->dev, "%s fmt 0x%x\n", __func__, fmt);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_I2S;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_MODEA;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		pcmif_priv->format = MTK_DAI_PCM_FMT_MODEB;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		pcmif_priv->bck_inv = 0;
+		pcmif_priv->lrck_inv = 0;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		pcmif_priv->bck_inv = 0;
+		pcmif_priv->lrck_inv = 1;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		pcmif_priv->bck_inv = 1;
+		pcmif_priv->lrck_inv = 0;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		pcmif_priv->bck_inv = 1;
+		pcmif_priv->lrck_inv = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		pcmif_priv->slave_mode = 1;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		pcmif_priv->slave_mode = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_pcm_ops = {
+	.startup	= mtk_dai_pcm_startup,
+	.shutdown	= mtk_dai_pcm_shutdown,
+	.prepare	= mtk_dai_pcm_prepare,
+	.set_fmt	= mtk_dai_pcm_set_fmt,
+};
+
+/* dai driver */
+#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000)
+
+#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+			 SNDRV_PCM_FMTBIT_S24_LE |\
+			 SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
+	{
+		.name = "PCM1",
+		.id = MT8195_AFE_IO_PCM,
+		.playback = {
+			.stream_name = "PCM1 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_PCM_RATES,
+			.formats = MTK_PCM_FORMATS,
+		},
+		.capture = {
+			.stream_name = "PCM1 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_PCM_RATES,
+			.formats = MTK_PCM_FORMATS,
+		},
+		.ops = &mtk_dai_pcm_ops,
+		.symmetric_rate = 1,
+		.symmetric_sample_bits = 1,
+	},
+};
+
+static int init_pcmif_priv_data(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_pcmif_priv *pcmif_priv;
+
+	pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_pcmif_priv),
+				  GFP_KERNEL);
+	if (!pcmif_priv)
+		return -ENOMEM;
+
+	afe_priv->dai_priv[MT8195_AFE_IO_PCM] = pcmif_priv;
+	return 0;
+}
+
+int mt8195_dai_pcm_register(struct mtk_base_afe *afe)
+{
+	struct mtk_base_afe_dai *dai;
+
+	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+
+	list_add(&dai->list, &afe->sub_dais);
+
+	dai->dai_drivers = mtk_dai_pcm_driver;
+	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
+
+	dai->dapm_widgets = mtk_dai_pcm_widgets;
+	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
+	dai->dapm_routes = mtk_dai_pcm_routes;
+	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
+
+	return init_pcmif_priv_data(afe);
+}
-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:41 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:41 +0800
Subject: [PATCH v5 08/11] ASoC: mediatek: mt8195: add machine driver with
 mt6359, rt1019 and rt5682
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-9-trevor.wu@mediatek.com>

This patch adds support for mt8195 board with mt6359, rt1019 and rt5682.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 sound/soc/mediatek/Kconfig                    |  14 +
 sound/soc/mediatek/mt8195/Makefile            |   3 +
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 977 ++++++++++++++++++
 3 files changed, 994 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 3389f382be06..bfee954d0c7c 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -193,3 +193,17 @@ config SND_SOC_MT8195
 	  that can be used with other codecs.
 	  Select Y if you have such device.
 	  If unsure select "N".
+
+config SND_SOC_MT8195_MT6359_RT1019_RT5682
+	tristate "ASoC Audio driver for MT8195 with MT6359 RT1019 RT5682 codec"
+	depends on I2C
+	depends on SND_SOC_MT8195
+	select SND_SOC_MT6359
+	select SND_SOC_RT1015P
+	select SND_SOC_RT5682_I2C
+	select SND_SOC_DMIC
+	help
+	  This adds ASoC driver for Mediatek MT8195 boards
+	  with the MT6359 RT1019 RT5682 audio codec.
+	  Select Y if you have such device.
+	  If unsure select "N".
diff --git a/sound/soc/mediatek/mt8195/Makefile b/sound/soc/mediatek/mt8195/Makefile
index 6529dd5beb2b..44775f400b40 100644
--- a/sound/soc/mediatek/mt8195/Makefile
+++ b/sound/soc/mediatek/mt8195/Makefile
@@ -10,3 +10,6 @@ snd-soc-mt8195-afe-objs := \
 	mt8195-dai-pcm.o
 
 obj-$(CONFIG_SND_SOC_MT8195) += snd-soc-mt8195-afe.o
+
+# machine driver
+obj-$(CONFIG_SND_SOC_MT8195_MT6359_RT1019_RT5682) += mt8195-mt6359-rt1019-rt5682.o
diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
new file mode 100644
index 000000000000..39b33aecc1e9
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
@@ -0,0 +1,977 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// mt8195-mt6359-rt1019-rt5682.c  --
+//	MT8195-MT6359-RT1019-RT6358 ALSA SoC machine driver
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Trevor Wu <trevor.wu at mediatek.com>
+//
+
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/rt5682.h>
+#include <sound/soc.h>
+#include "../../codecs/mt6359.h"
+#include "../../codecs/rt5682.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "mt8195-afe-common.h"
+
+#define RT1019_CODEC_DAI	"HiFi"
+#define RT1019_DEV0_NAME	"rt1019p"
+
+#define RT5682_CODEC_DAI	"rt5682-aif1"
+#define RT5682_DEV0_NAME	"rt5682.2-001a"
+
+struct mt8195_mt6359_rt1019_rt5682_priv {
+	struct snd_soc_jack headset_jack;
+};
+
+static const struct snd_soc_dapm_widget
+	mt8195_mt6359_rt1019_rt5682_widgets[] = {
+	SND_SOC_DAPM_SPK("Speakers", NULL),
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = {
+	/* speaker */
+	{ "Speakers", NULL, "Speaker" },
+	/* headset */
+	{ "Headphone Jack", NULL, "HPOL" },
+	{ "Headphone Jack", NULL, "HPOR" },
+	{ "IN1P", NULL, "Headset Mic" },
+};
+
+static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = {
+	SOC_DAPM_PIN_SWITCH("Speakers"),
+	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+	SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+	unsigned int rate = params_rate(params);
+	unsigned int mclk_fs_ratio = 128;
+	unsigned int mclk_fs = rate * mclk_fs_ratio;
+	int bitwidth;
+	int ret;
+
+	bitwidth = snd_pcm_format_width(params_format(params));
+	if (bitwidth < 0) {
+		dev_err(card->dev, "invalid bit width: %d\n", bitwidth);
+		return bitwidth;
+	}
+
+	ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);
+	if (ret) {
+		dev_err(card->dev, "failed to set tdm slot\n");
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
+				  RT5682_PLL1_S_BCLK1,
+				  params_rate(params) * 64,
+				  params_rate(params) * 512);
+	if (ret) {
+		dev_err(card->dev, "failed to set pll\n");
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(codec_dai,
+				     RT5682_SCLK_S_PLL1,
+				     params_rate(params) * 512,
+				     SND_SOC_CLOCK_IN);
+	if (ret) {
+		dev_err(card->dev, "failed to set sysclk\n");
+		return ret;
+	}
+
+	return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
+}
+
+static const struct snd_soc_ops mt8195_rt5682_etdm_ops = {
+	.hw_params = mt8195_rt5682_etdm_hw_params,
+};
+
+#define CKSYS_AUD_TOP_CFG 0x032c
+#define CKSYS_AUD_TOP_MON 0x0330
+
+static int mt8195_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_afe =
+		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int phase;
+	unsigned int monitor;
+	int mtkaif_calibration_num_phase;
+	int test_done_1, test_done_2, test_done_3;
+	int cycle_1, cycle_2, cycle_3;
+	int prev_cycle_1, prev_cycle_2, prev_cycle_3;
+	int chosen_phase_1, chosen_phase_2, chosen_phase_3;
+	int counter;
+	bool mtkaif_calibration_ok;
+	int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM];
+	int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM];
+	int i;
+
+	dev_info(afe->dev, "%s(), start\n", __func__);
+
+	param->mtkaif_calibration_ok = false;
+	for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) {
+		param->mtkaif_chosen_phase[i] = -1;
+		param->mtkaif_phase_cycle[i] = 0;
+		mtkaif_chosen_phase[i] = -1;
+		mtkaif_phase_cycle[i] = 0;
+	}
+
+	if (IS_ERR(afe_priv->topckgen)) {
+		dev_info(afe->dev, "%s() Cannot find topckgen controller\n",
+			 __func__);
+		return 0;
+	}
+
+	pm_runtime_get_sync(afe->dev);
+	mt6359_mtkaif_calibration_enable(cmpnt_codec);
+
+	/* set test type to synchronizer pulse */
+	regmap_update_bits(afe_priv->topckgen,
+			   CKSYS_AUD_TOP_CFG, 0xffff, 0x4);
+	mtkaif_calibration_num_phase = 42;	/* mt6359: 0 ~ 42 */
+	mtkaif_calibration_ok = true;
+
+	for (phase = 0;
+	     phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok;
+	     phase++) {
+		mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+						    phase, phase, phase);
+
+		regmap_update_bits(afe_priv->topckgen,
+				   CKSYS_AUD_TOP_CFG, 0x1, 0x1);
+
+		test_done_1 = 0;
+		test_done_2 = 0;
+		test_done_3 = 0;
+		cycle_1 = -1;
+		cycle_2 = -1;
+		cycle_3 = -1;
+		counter = 0;
+		while (!(test_done_1 & test_done_2 & test_done_3)) {
+			regmap_read(afe_priv->topckgen,
+				    CKSYS_AUD_TOP_MON, &monitor);
+			test_done_1 = (monitor >> 28) & 0x1;
+			test_done_2 = (monitor >> 29) & 0x1;
+			test_done_3 = (monitor >> 30) & 0x1;
+			if (test_done_1 == 1)
+				cycle_1 = monitor & 0xf;
+
+			if (test_done_2 == 1)
+				cycle_2 = (monitor >> 4) & 0xf;
+
+			if (test_done_3 == 1)
+				cycle_3 = (monitor >> 8) & 0xf;
+
+			/* handle if never test done */
+			if (++counter > 10000) {
+				dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n",
+					 __func__,
+					 cycle_1, cycle_2, cycle_3, monitor);
+				mtkaif_calibration_ok = false;
+				break;
+			}
+		}
+
+		if (phase == 0) {
+			prev_cycle_1 = cycle_1;
+			prev_cycle_2 = cycle_2;
+			prev_cycle_3 = cycle_3;
+		}
+
+		if (cycle_1 != prev_cycle_1 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1;
+		}
+
+		if (cycle_2 != prev_cycle_2 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2;
+		}
+
+		if (cycle_3 != prev_cycle_3 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
+			mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1;
+			mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3;
+		}
+
+		regmap_update_bits(afe_priv->topckgen,
+				   CKSYS_AUD_TOP_CFG, 0x1, 0x0);
+
+		if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 &&
+		    mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0)
+			break;
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_1 = 0;
+	} else {
+		chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0];
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_2 = 0;
+	} else {
+		chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1];
+	}
+
+	if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) {
+		mtkaif_calibration_ok = false;
+		chosen_phase_3 = 0;
+	} else {
+		chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2];
+	}
+
+	mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+					    chosen_phase_1,
+					    chosen_phase_2,
+					    chosen_phase_3);
+
+	mt6359_mtkaif_calibration_disable(cmpnt_codec);
+	pm_runtime_put(afe->dev);
+
+	param->mtkaif_calibration_ok = mtkaif_calibration_ok;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2;
+	param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3;
+	for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++)
+		param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];
+
+	dev_info(afe->dev, "%s(), end, calibration ok %d\n",
+		 __func__, param->mtkaif_calibration_ok);
+
+	return 0;
+}
+
+static int mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+
+	/* set mtkaif protocol */
+	mt6359_set_mtkaif_protocol(cmpnt_codec,
+				   MT6359_MTKAIF_PROTOCOL_2_CLK_P2);
+
+	/* mtkaif calibration */
+	mt8195_mt6359_mtkaif_calibration(rtd);
+
+	return 0;
+}
+
+static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+		snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_jack *jack = &priv->headset_jack;
+	int ret;
+
+	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
+				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
+				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
+				    SND_JACK_BTN_3,
+				    jack, NULL, 0);
+	if (ret) {
+		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
+		return ret;
+	}
+
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+
+	ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
+	if (ret) {
+		dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+};
+
+static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				       struct snd_pcm_hw_params *params)
+{
+	/* fix BE i2s format to 32bit, clean param mask first */
+	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
+
+	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+	return 0;
+}
+
+static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+	unsigned int rate = params_rate(params);
+	unsigned int mclk_fs_ratio = 256;
+	unsigned int mclk_fs = rate * mclk_fs_ratio;
+
+	return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs,
+				      SND_SOC_CLOCK_OUT);
+}
+
+static struct snd_soc_ops mt8195_dptx_ops = {
+	.hw_params = mt8195_dptx_hw_params,
+};
+
+static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+				       struct snd_pcm_hw_params *params)
+{
+	/* fix BE i2s format to 32bit, clean param mask first */
+	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
+
+	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+
+	return 0;
+}
+
+static int mt8195_playback_startup(struct snd_pcm_substream *substream)
+{
+	static const unsigned int rates[] = {
+		48000
+	};
+	static const unsigned int channels[] = {
+		2
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list  = rates,
+		.mask = 0,
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list  = channels,
+		.mask = 0,
+	};
+
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_rates);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+		return ret;
+	}
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_CHANNELS,
+					 &constraints_channels);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops mt8195_playback_ops = {
+	.startup = mt8195_playback_startup,
+};
+
+static int mt8195_capture_startup(struct snd_pcm_substream *substream)
+{
+	static const unsigned int rates[] = {
+		48000
+	};
+	static const unsigned int channels[] = {
+		1, 2
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list  = rates,
+		.mask = 0,
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list  = channels,
+		.mask = 0,
+	};
+
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_rates);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+		return ret;
+	}
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_CHANNELS,
+					 &constraints_channels);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops mt8195_capture_ops = {
+	.startup = mt8195_capture_startup,
+};
+
+enum {
+	DAI_LINK_DL2_FE,
+	DAI_LINK_DL3_FE,
+	DAI_LINK_DL6_FE,
+	DAI_LINK_DL7_FE,
+	DAI_LINK_DL8_FE,
+	DAI_LINK_DL10_FE,
+	DAI_LINK_DL11_FE,
+	DAI_LINK_UL1_FE,
+	DAI_LINK_UL2_FE,
+	DAI_LINK_UL3_FE,
+	DAI_LINK_UL4_FE,
+	DAI_LINK_UL5_FE,
+	DAI_LINK_UL6_FE,
+	DAI_LINK_UL8_FE,
+	DAI_LINK_UL9_FE,
+	DAI_LINK_UL10_FE,
+	DAI_LINK_DL_SRC_BE,
+	DAI_LINK_DPTX_BE,
+	DAI_LINK_ETDM1_IN_BE,
+	DAI_LINK_ETDM2_IN_BE,
+	DAI_LINK_ETDM1_OUT_BE,
+	DAI_LINK_ETDM2_OUT_BE,
+	DAI_LINK_ETDM3_OUT_BE,
+	DAI_LINK_PCM1_BE,
+	DAI_LINK_UL_SRC1_BE,
+	DAI_LINK_UL_SRC2_BE,
+};
+
+/* FE */
+SND_SOC_DAILINK_DEFS(DL2_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL3_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL6_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL7_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL8_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL10_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL10")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DL11_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL11")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL1_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL2_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL3_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL4_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL5_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL6_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL8_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL8")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL9_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL9")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL10_FE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL10")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+/* BE */
+SND_SOC_DAILINK_DEFS(DL_SRC_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif1")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(DPTX_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM1_IN_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM2_IN_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME,
+						   RT5682_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME,
+						   RT5682_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME,
+						   RT1019_CODEC_DAI)),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(PCM1_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),
+		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL_SRC1_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif1"),
+					COMP_CODEC("dmic-codec",
+						   "dmic-hifi")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(UL_SRC2_BE,
+		     DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")),
+		     DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+						   "mt6359-snd-codec-aif2")),
+		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
+	/* FE */
+	[DAI_LINK_DL2_FE] = {
+		.name = "DL2_FE",
+		.stream_name = "DL2 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL2_FE),
+	},
+	[DAI_LINK_DL3_FE] = {
+		.name = "DL3_FE",
+		.stream_name = "DL3 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL3_FE),
+	},
+	[DAI_LINK_DL6_FE] = {
+		.name = "DL6_FE",
+		.stream_name = "DL6 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL6_FE),
+	},
+	[DAI_LINK_DL7_FE] = {
+		.name = "DL7_FE",
+		.stream_name = "DL7 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL7_FE),
+	},
+	[DAI_LINK_DL8_FE] = {
+		.name = "DL8_FE",
+		.stream_name = "DL8 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL8_FE),
+	},
+	[DAI_LINK_DL10_FE] = {
+		.name = "DL10_FE",
+		.stream_name = "DL10 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL10_FE),
+	},
+	[DAI_LINK_DL11_FE] = {
+		.name = "DL11_FE",
+		.stream_name = "DL11 Playback",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_playback_ops,
+		SND_SOC_DAILINK_REG(DL11_FE),
+	},
+	[DAI_LINK_UL1_FE] = {
+		.name = "UL1_FE",
+		.stream_name = "UL1 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL1_FE),
+	},
+	[DAI_LINK_UL2_FE] = {
+		.name = "UL2_FE",
+		.stream_name = "UL2 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL2_FE),
+	},
+	[DAI_LINK_UL3_FE] = {
+		.name = "UL3_FE",
+		.stream_name = "UL3 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL3_FE),
+	},
+	[DAI_LINK_UL4_FE] = {
+		.name = "UL4_FE",
+		.stream_name = "UL4 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL4_FE),
+	},
+	[DAI_LINK_UL5_FE] = {
+		.name = "UL5_FE",
+		.stream_name = "UL5 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL5_FE),
+	},
+	[DAI_LINK_UL6_FE] = {
+		.name = "UL6_FE",
+		.stream_name = "UL6 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_PRE,
+			SND_SOC_DPCM_TRIGGER_PRE,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL6_FE),
+	},
+	[DAI_LINK_UL8_FE] = {
+		.name = "UL8_FE",
+		.stream_name = "UL8 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL8_FE),
+	},
+	[DAI_LINK_UL9_FE] = {
+		.name = "UL9_FE",
+		.stream_name = "UL9 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL9_FE),
+	},
+	[DAI_LINK_UL10_FE] = {
+		.name = "UL10_FE",
+		.stream_name = "UL10 Capture",
+		.trigger = {
+			SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST,
+		},
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.ops = &mt8195_capture_ops,
+		SND_SOC_DAILINK_REG(UL10_FE),
+	},
+	/* BE */
+	[DAI_LINK_DL_SRC_BE] = {
+		.name = "DL_SRC_BE",
+		.init = mt8195_mt6359_init,
+		.no_pcm = 1,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(DL_SRC_BE),
+	},
+	[DAI_LINK_DPTX_BE] = {
+		.name = "DPTX_BE",
+		.no_pcm = 1,
+		.dpcm_playback = 1,
+		.ops = &mt8195_dptx_ops,
+		.be_hw_params_fixup = mt8195_dptx_hw_params_fixup,
+		SND_SOC_DAILINK_REG(DPTX_BE),
+	},
+	[DAI_LINK_ETDM1_IN_BE] = {
+		.name = "ETDM1_IN_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(ETDM1_IN_BE),
+	},
+	[DAI_LINK_ETDM2_IN_BE] = {
+		.name = "ETDM2_IN_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		.init = mt8195_rt5682_init,
+		.ops = &mt8195_rt5682_etdm_ops,
+		.be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
+		SND_SOC_DAILINK_REG(ETDM2_IN_BE),
+	},
+	[DAI_LINK_ETDM1_OUT_BE] = {
+		.name = "ETDM1_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		.ops = &mt8195_rt5682_etdm_ops,
+		.be_hw_params_fixup = mt8195_etdm_hw_params_fixup,
+		SND_SOC_DAILINK_REG(ETDM1_OUT_BE),
+	},
+	[DAI_LINK_ETDM2_OUT_BE] = {
+		.name = "ETDM2_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(ETDM2_OUT_BE),
+	},
+	[DAI_LINK_ETDM3_OUT_BE] = {
+		.name = "ETDM3_OUT_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_playback = 1,
+		SND_SOC_DAILINK_REG(ETDM3_OUT_BE),
+	},
+	[DAI_LINK_PCM1_BE] = {
+		.name = "PCM1_BE",
+		.no_pcm = 1,
+		.dai_fmt = SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBS_CFS,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(PCM1_BE),
+	},
+	[DAI_LINK_UL_SRC1_BE] = {
+		.name = "UL_SRC1_BE",
+		.no_pcm = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL_SRC1_BE),
+	},
+	[DAI_LINK_UL_SRC2_BE] = {
+		.name = "UL_SRC2_BE",
+		.no_pcm = 1,
+		.dpcm_capture = 1,
+		SND_SOC_DAILINK_REG(UL_SRC2_BE),
+	},
+};
+
+static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = {
+	.name = "mt8195_r1019_5682",
+	.owner = THIS_MODULE,
+	.dai_link = mt8195_mt6359_rt1019_rt5682_dai_links,
+	.num_links = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links),
+	.controls = mt8195_mt6359_rt1019_rt5682_controls,
+	.num_controls = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_controls),
+	.dapm_widgets = mt8195_mt6359_rt1019_rt5682_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets),
+	.dapm_routes = mt8195_mt6359_rt1019_rt5682_routes,
+	.num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes),
+};
+
+static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = &mt8195_mt6359_rt1019_rt5682_soc_card;
+	struct device_node *platform_node;
+	struct snd_soc_dai_link *dai_link;
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL;
+
+	int ret, i;
+
+	card->dev = &pdev->dev;
+
+	platform_node = of_parse_phandle(pdev->dev.of_node,
+					 "mediatek,platform", 0);
+	if (!platform_node) {
+		dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n");
+		return -EINVAL;
+	}
+
+	for_each_card_prelinks(card, i, dai_link) {
+		if (!dai_link->platforms->name)
+			dai_link->platforms->of_node = platform_node;
+	}
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	snd_soc_card_set_drvdata(card, priv);
+
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+	if (ret)
+		dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+			__func__, ret);
+	return ret;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id mt8195_mt6359_rt1019_rt5682_dt_match[] = {
+	{.compatible = "mediatek,mt8195_mt6359_rt1019_rt5682",},
+	{}
+};
+#endif
+
+static const struct dev_pm_ops mt8195_mt6359_rt1019_rt5682_pm_ops = {
+	.poweroff = snd_soc_poweroff,
+	.restore = snd_soc_resume,
+};
+
+static struct platform_driver mt8195_mt6359_rt1019_rt5682_driver = {
+	.driver = {
+		.name = "mt8195_mt6359_rt1019_rt5682",
+#ifdef CONFIG_OF
+		.of_match_table = mt8195_mt6359_rt1019_rt5682_dt_match,
+#endif
+		.pm = &mt8195_mt6359_rt1019_rt5682_pm_ops,
+	},
+	.probe = mt8195_mt6359_rt1019_rt5682_dev_probe,
+};
+
+module_platform_driver(mt8195_mt6359_rt1019_rt5682_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("MT8195-MT6359-RT1019-RT5682 ALSA SoC machine driver");
+MODULE_AUTHOR("Trevor Wu <trevor.wu at mediatek.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("mt8195_mt6359_rt1019_rt5682 soc card");
-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:40 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:40 +0800
Subject: [PATCH v5 07/11] dt-bindings: mediatek: mt8195: add audio afe document
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-8-trevor.wu@mediatek.com>

This patch adds mt8195 audio afe document.

In order to support dynamic clock reparenting for ADDA and ETDM, PLL
and MUX clocks are requested even though they are not consumed by afe
directly.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
This patch depends on the following series that have not been accepted.

[1] Mediatek MT8195 clock support
https://patchwork.kernel.org/project/linux-mediatek/list/?series=501923
(dt-bindings/clock/mt8195-clk.h is included)

[2] Mediatek MT8195 power domain support
https://patchwork.kernel.org/project/linux-mediatek/list/?series=500709
(dt-bindings/power/mt8195-power.h is included)
---
---
 .../bindings/sound/mt8195-afe-pcm.yaml        | 184 ++++++++++++++++++
 1 file changed, 184 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml

diff --git a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
new file mode 100644
index 000000000000..53e9434a6d9d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt8195-afe-pcm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek AFE PCM controller for mt8195
+
+maintainers:
+  - Trevor Wu <trevor.wu at mediatek.com>
+
+properties:
+  compatible:
+    const: mediatek,mt8195-audio
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  mediatek,topckgen:
+    $ref: "/schemas/types.yaml#/definitions/phandle"
+    description: The phandle of the mediatek topckgen controller
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: 26M clock
+      - description: audio pll1 clock
+      - description: audio pll2 clock
+      - description: clock divider for i2si1_mck
+      - description: clock divider for i2si2_mck
+      - description: clock divider for i2so1_mck
+      - description: clock divider for i2so2_mck
+      - description: clock divider for dptx_mck
+      - description: a1sys hoping clock
+      - description: audio intbus clock
+      - description: audio hires clock
+      - description: audio local bus clock
+      - description: mux for dptx_mck
+      - description: mux for i2so1_mck
+      - description: mux for i2so2_mck
+      - description: mux for i2si1_mck
+      - description: mux for i2si2_mck
+      - description: audio infra 26M clock
+      - description: infra bus clock
+
+  clock-names:
+    items:
+      - const: clk26m
+      - const: apll1_ck
+      - const: apll2_ck
+      - const: apll12_div0
+      - const: apll12_div1
+      - const: apll12_div2
+      - const: apll12_div3
+      - const: apll12_div9
+      - const: a1sys_hp_sel
+      - const: aud_intbus_sel
+      - const: audio_h_sel
+      - const: audio_local_bus_sel
+      - const: dptx_m_sel
+      - const: i2so1_m_sel
+      - const: i2so2_m_sel
+      - const: i2si1_m_sel
+      - const: i2si2_m_sel
+      - const: infra_ao_audio_26m_b
+      - const: scp_adsp_audiodsp
+
+  mediatek,etdm-in1-chn-disabled:
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    maxItems: 24
+    description: Specify which input channel should be disabled.
+
+  mediatek,etdm-in2-chn-disabled:
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    maxItems: 16
+    description: Specify which input channel should be disabled.
+
+patternProperties:
+  "^mediatek,etdm-in[1-2]-mclk-always-on-rate-hz$":
+    description: Specify etdm in mclk output rate for always on case.
+
+  "^mediatek,etdm-out[1-3]-mclk-always-on-rate-hz$":
+    description: Specify etdm out mclk output rate for always on case.
+
+  "^mediatek,etdm-in[1-2]-multi-pin-mode$":
+    type: boolean
+    description: if present, the etdm data mode is I2S.
+
+  "^mediatek,etdm-out[1-3]-multi-pin-mode$":
+    type: boolean
+    description: if present, the etdm data mode is I2S.
+
+  "^mediatek,etdm-in[1-2]-cowork-source$":
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      etdm modules can share the same external clock pin. Specify
+      which etdm clock source is required by this etdm in moudule.
+    enum:
+      - 0 # etdm1_in
+      - 1 # etdm2_in
+      - 2 # etdm1_out
+      - 3 # etdm2_out
+
+  "^mediatek,etdm-out[1-2]-cowork-source$":
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      etdm modules can share the same external clock pin. Specify
+      which etdm clock source is required by this etdm out moudule.
+    enum:
+      - 0 # etdm1_in
+      - 1 # etdm2_in
+      - 2 # etdm1_out
+      - 3 # etdm2_out
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - mediatek,topckgen
+  - power-domains
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt8195-power.h>
+
+    afe: mt8195-afe-pcm at 10890000 {
+        compatible = "mediatek,mt8195-audio";
+        reg = <0x10890000 0x10000>;
+        interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
+        mediatek,topckgen = <&topckgen>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_AUDIO>;
+        clocks = <&clk26m>,
+                 <&topckgen CLK_TOP_APLL1>,
+                 <&topckgen CLK_TOP_APLL2>,
+                 <&topckgen CLK_TOP_APLL12_DIV0>,
+                 <&topckgen CLK_TOP_APLL12_DIV1>,
+                 <&topckgen CLK_TOP_APLL12_DIV2>,
+                 <&topckgen CLK_TOP_APLL12_DIV3>,
+                 <&topckgen CLK_TOP_APLL12_DIV9>,
+                 <&topckgen CLK_TOP_A1SYS_HP_SEL>,
+                 <&topckgen CLK_TOP_AUD_INTBUS_SEL>,
+                 <&topckgen CLK_TOP_AUDIO_H_SEL>,
+                 <&topckgen CLK_TOP_AUDIO_LOCAL_BUS_SEL>,
+                 <&topckgen CLK_TOP_DPTX_M_SEL>,
+                 <&topckgen CLK_TOP_I2SO1_M_SEL>,
+                 <&topckgen CLK_TOP_I2SO2_M_SEL>,
+                 <&topckgen CLK_TOP_I2SI1_M_SEL>,
+                 <&topckgen CLK_TOP_I2SI2_M_SEL>,
+                 <&infracfg_ao CLK_INFRA_AO_AUDIO_26M_B>,
+                 <&scp_adsp CLK_SCP_ADSP_AUDIODSP>;
+        clock-names = "clk26m",
+                      "apll1_ck",
+                      "apll2_ck",
+                      "apll12_div0",
+                      "apll12_div1",
+                      "apll12_div2",
+                      "apll12_div3",
+                      "apll12_div9",
+                      "a1sys_hp_sel",
+                      "aud_intbus_sel",
+                      "audio_h_sel",
+                      "audio_local_bus_sel",
+                      "dptx_m_sel",
+                      "i2so1_m_sel",
+                      "i2so2_m_sel",
+                      "i2si1_m_sel",
+                      "i2si2_m_sel",
+                      "infra_ao_audio_26m_b",
+                      "scp_adsp_audiodsp";
+    };
+
+...
-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:35 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:35 +0800
Subject: [PATCH v5 02/11] ASoC: mediatek: mt8195: support audsys clock control
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-3-trevor.wu@mediatek.com>

This patch adds mt8195 audio cg control.
Audio clock gates are registered to CCF for reference count and
clock parent management.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c | 214 ++++++++++++++++++
 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h |  15 ++
 .../soc/mediatek/mt8195/mt8195-audsys-clkid.h |  93 ++++++++
 3 files changed, 322 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h

diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
new file mode 100644
index 000000000000..740aa6ddda0e
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt8195-audsys-clk.h  --  Mediatek 8195 audsys clock control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include "mt8195-afe-common.h"
+#include "mt8195-audsys-clk.h"
+#include "mt8195-audsys-clkid.h"
+#include "mt8195-reg.h"
+
+struct afe_gate {
+	int id;
+	const char *name;
+	const char *parent_name;
+	int reg;
+	u8 bit;
+	const struct clk_ops *ops;
+	unsigned long flags;
+	u8 cg_flags;
+};
+
+#define GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, _flags, _cgflags) {\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.reg = _reg,					\
+		.bit = _bit,					\
+		.flags = _flags,				\
+		.cg_flags = _cgflags,				\
+	}
+
+#define GATE_AFE(_id, _name, _parent, _reg, _bit)		\
+	GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit,		\
+		       CLK_SET_RATE_PARENT, CLK_GATE_SET_TO_DISABLE)
+
+#define GATE_AUD0(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON0, _bit)
+
+#define GATE_AUD1(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON1, _bit)
+
+#define GATE_AUD3(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON3, _bit)
+
+#define GATE_AUD4(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON4, _bit)
+
+#define GATE_AUD5(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON5, _bit)
+
+#define GATE_AUD6(_id, _name, _parent, _bit)			\
+	GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON6, _bit)
+
+static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
+	/* AUD0 */
+	GATE_AUD0(CLK_AUD_AFE, "aud_afe", "a1sys_hp_sel", 2),
+	GATE_AUD0(CLK_AUD_LRCK_CNT, "aud_lrck_cnt", "a1sys_hp_sel", 4),
+	GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_APLL, "aud_spdifin_tuner_apll", "apll4_sel", 10),
+	GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_DBG, "aud_spdifin_tuner_dbg", "apll4_sel", 11),
+	GATE_AUD0(CLK_AUD_UL_TML, "aud_ul_tml", "a1sys_hp_sel", 18),
+	GATE_AUD0(CLK_AUD_APLL1_TUNER, "aud_apll1_tuner", "apll1_sel", 19),
+	GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "apll2_sel", 20),
+	GATE_AUD0(CLK_AUD_TOP0_SPDF, "aud_top0_spdf", "aud_iec_sel", 21),
+	GATE_AUD0(CLK_AUD_APLL, "aud_apll", "apll1_sel", 23),
+	GATE_AUD0(CLK_AUD_APLL2, "aud_apll2", "apll2_sel", 24),
+	GATE_AUD0(CLK_AUD_DAC, "aud_dac", "a1sys_hp_sel", 25),
+	GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "a1sys_hp_sel", 26),
+	GATE_AUD0(CLK_AUD_TML, "aud_tml", "a1sys_hp_sel", 27),
+	GATE_AUD0(CLK_AUD_ADC, "aud_adc", "a1sys_hp_sel", 28),
+	GATE_AUD0(CLK_AUD_DAC_HIRES, "aud_dac_hires", "audio_h_sel", 31),
+
+	/* AUD1 */
+	GATE_AUD1(CLK_AUD_A1SYS_HP, "aud_a1sys_hp", "a1sys_hp_sel", 2),
+	GATE_AUD1(CLK_AUD_AFE_DMIC1, "aud_afe_dmic1", "a1sys_hp_sel", 10),
+	GATE_AUD1(CLK_AUD_AFE_DMIC2, "aud_afe_dmic2", "a1sys_hp_sel", 11),
+	GATE_AUD1(CLK_AUD_AFE_DMIC3, "aud_afe_dmic3", "a1sys_hp_sel", 12),
+	GATE_AUD1(CLK_AUD_AFE_DMIC4, "aud_afe_dmic4", "a1sys_hp_sel", 13),
+	GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "a1sys_hp_sel", 14),
+	GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "audio_h_sel", 16),
+	GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "audio_h_sel", 17),
+	GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "a1sys_hp_sel", 18),
+	GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "audio_h_sel", 19),
+
+	/* AUD3 */
+	GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "apll5_sel", 5),
+	GATE_AUD3(CLK_AUD_EARC_TUNER, "aud_earc_tuner", "apll3_sel", 7),
+
+	/* AUD4 */
+	GATE_AUD4(CLK_AUD_I2SIN, "aud_i2sin", "a1sys_hp_sel", 0),
+	GATE_AUD4(CLK_AUD_TDM_IN, "aud_tdm_in", "a1sys_hp_sel", 1),
+	GATE_AUD4(CLK_AUD_I2S_OUT, "aud_i2s_out", "a1sys_hp_sel", 6),
+	GATE_AUD4(CLK_AUD_TDM_OUT, "aud_tdm_out", "a1sys_hp_sel", 7),
+	GATE_AUD4(CLK_AUD_HDMI_OUT, "aud_hdmi_out", "a1sys_hp_sel", 8),
+	GATE_AUD4(CLK_AUD_ASRC11, "aud_asrc11", "a1sys_hp_sel", 16),
+	GATE_AUD4(CLK_AUD_ASRC12, "aud_asrc12", "a1sys_hp_sel", 17),
+	GATE_AUD4(CLK_AUD_MULTI_IN, "aud_multi_in", "mphone_slave_b", 19),
+	GATE_AUD4(CLK_AUD_INTDIR, "aud_intdir", "intdir_sel", 20),
+	GATE_AUD4(CLK_AUD_A1SYS, "aud_a1sys", "a1sys_hp_sel", 21),
+	GATE_AUD4(CLK_AUD_A2SYS, "aud_a2sys", "a2sys_sel", 22),
+	GATE_AUD4(CLK_AUD_PCMIF, "aud_pcmif", "a1sys_hp_sel", 24),
+	GATE_AUD4(CLK_AUD_A3SYS, "aud_a3sys", "a3sys_sel", 30),
+	GATE_AUD4(CLK_AUD_A4SYS, "aud_a4sys", "a4sys_sel", 31),
+
+	/* AUD5 */
+	GATE_AUD5(CLK_AUD_MEMIF_UL1, "aud_memif_ul1", "a1sys_hp_sel", 0),
+	GATE_AUD5(CLK_AUD_MEMIF_UL2, "aud_memif_ul2", "a1sys_hp_sel", 1),
+	GATE_AUD5(CLK_AUD_MEMIF_UL3, "aud_memif_ul3", "a1sys_hp_sel", 2),
+	GATE_AUD5(CLK_AUD_MEMIF_UL4, "aud_memif_ul4", "a1sys_hp_sel", 3),
+	GATE_AUD5(CLK_AUD_MEMIF_UL5, "aud_memif_ul5", "a1sys_hp_sel", 4),
+	GATE_AUD5(CLK_AUD_MEMIF_UL6, "aud_memif_ul6", "a1sys_hp_sel", 5),
+	GATE_AUD5(CLK_AUD_MEMIF_UL8, "aud_memif_ul8", "a1sys_hp_sel", 7),
+	GATE_AUD5(CLK_AUD_MEMIF_UL9, "aud_memif_ul9", "a1sys_hp_sel", 8),
+	GATE_AUD5(CLK_AUD_MEMIF_UL10, "aud_memif_ul10", "a1sys_hp_sel", 9),
+	GATE_AUD5(CLK_AUD_MEMIF_DL2, "aud_memif_dl2", "a1sys_hp_sel", 18),
+	GATE_AUD5(CLK_AUD_MEMIF_DL3, "aud_memif_dl3", "a1sys_hp_sel", 19),
+	GATE_AUD5(CLK_AUD_MEMIF_DL6, "aud_memif_dl6", "a1sys_hp_sel", 22),
+	GATE_AUD5(CLK_AUD_MEMIF_DL7, "aud_memif_dl7", "a1sys_hp_sel", 23),
+	GATE_AUD5(CLK_AUD_MEMIF_DL8, "aud_memif_dl8", "a1sys_hp_sel", 24),
+	GATE_AUD5(CLK_AUD_MEMIF_DL10, "aud_memif_dl10", "a1sys_hp_sel", 26),
+	GATE_AUD5(CLK_AUD_MEMIF_DL11, "aud_memif_dl11", "a1sys_hp_sel", 27),
+
+	/* AUD6 */
+	GATE_AUD6(CLK_AUD_GASRC0, "aud_gasrc0", "asm_h_sel", 0),
+	GATE_AUD6(CLK_AUD_GASRC1, "aud_gasrc1", "asm_h_sel", 1),
+	GATE_AUD6(CLK_AUD_GASRC2, "aud_gasrc2", "asm_h_sel", 2),
+	GATE_AUD6(CLK_AUD_GASRC3, "aud_gasrc3", "asm_h_sel", 3),
+	GATE_AUD6(CLK_AUD_GASRC4, "aud_gasrc4", "asm_h_sel", 4),
+	GATE_AUD6(CLK_AUD_GASRC5, "aud_gasrc5", "asm_h_sel", 5),
+	GATE_AUD6(CLK_AUD_GASRC6, "aud_gasrc6", "asm_h_sel", 6),
+	GATE_AUD6(CLK_AUD_GASRC7, "aud_gasrc7", "asm_h_sel", 7),
+	GATE_AUD6(CLK_AUD_GASRC8, "aud_gasrc8", "asm_h_sel", 8),
+	GATE_AUD6(CLK_AUD_GASRC9, "aud_gasrc9", "asm_h_sel", 9),
+	GATE_AUD6(CLK_AUD_GASRC10, "aud_gasrc10", "asm_h_sel", 10),
+	GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "asm_h_sel", 11),
+	GATE_AUD6(CLK_AUD_GASRC12, "aud_gasrc12", "asm_h_sel", 12),
+	GATE_AUD6(CLK_AUD_GASRC13, "aud_gasrc13", "asm_h_sel", 13),
+	GATE_AUD6(CLK_AUD_GASRC14, "aud_gasrc14", "asm_h_sel", 14),
+	GATE_AUD6(CLK_AUD_GASRC15, "aud_gasrc15", "asm_h_sel", 15),
+	GATE_AUD6(CLK_AUD_GASRC16, "aud_gasrc16", "asm_h_sel", 16),
+	GATE_AUD6(CLK_AUD_GASRC17, "aud_gasrc17", "asm_h_sel", 17),
+	GATE_AUD6(CLK_AUD_GASRC18, "aud_gasrc18", "asm_h_sel", 18),
+	GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "asm_h_sel", 19),
+};
+
+int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk *clk;
+	struct clk_lookup *cl;
+	int i;
+
+	afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK,
+					sizeof(*afe_priv->lookup),
+					GFP_KERNEL);
+
+	if (!afe_priv->lookup)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
+		const struct afe_gate *gate = &aud_clks[i];
+
+		clk = clk_register_gate(afe->dev, gate->name, gate->parent_name,
+					gate->flags, afe->base_addr + gate->reg,
+					gate->bit, gate->cg_flags, NULL);
+
+		if (IS_ERR(clk)) {
+			dev_err(afe->dev, "Failed to register clk %s: %ld\n",
+				gate->name, PTR_ERR(clk));
+			continue;
+		}
+
+		/* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */
+		cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+		if (!cl)
+			return -ENOMEM;
+
+		cl->clk = clk;
+		cl->con_id = gate->name;
+		cl->dev_id = dev_name(afe->dev);
+		clkdev_add(cl);
+
+		afe_priv->lookup[i] = cl;
+	}
+
+	return 0;
+}
+
+void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk *clk;
+	struct clk_lookup *cl;
+	int i;
+
+	if (!afe_priv)
+		return;
+
+	for (i = 0; i < CLK_AUD_NR_CLK; i++) {
+		cl = afe_priv->lookup[i];
+		if (!cl)
+			continue;
+
+		clk = cl->clk;
+		clk_unregister_gate(clk);
+
+		clkdev_drop(cl);
+	}
+}
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
new file mode 100644
index 000000000000..239d31016ba7
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-audsys-clk.h  --  Mediatek 8195 audsys clock definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#ifndef _MT8195_AUDSYS_CLK_H_
+#define _MT8195_AUDSYS_CLK_H_
+
+int mt8195_audsys_clk_register(struct mtk_base_afe *afe);
+void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe);
+
+#endif
diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
new file mode 100644
index 000000000000..4dd0a5c8b8fa
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8195-audsys-clkid.h  --  Mediatek 8195 audsys clock id definition
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#ifndef _MT8195_AUDSYS_CLKID_H_
+#define _MT8195_AUDSYS_CLKID_H_
+
+enum{
+	CLK_AUD_AFE,
+	CLK_AUD_LRCK_CNT,
+	CLK_AUD_SPDIFIN_TUNER_APLL,
+	CLK_AUD_SPDIFIN_TUNER_DBG,
+	CLK_AUD_UL_TML,
+	CLK_AUD_APLL1_TUNER,
+	CLK_AUD_APLL2_TUNER,
+	CLK_AUD_TOP0_SPDF,
+	CLK_AUD_APLL,
+	CLK_AUD_APLL2,
+	CLK_AUD_DAC,
+	CLK_AUD_DAC_PREDIS,
+	CLK_AUD_TML,
+	CLK_AUD_ADC,
+	CLK_AUD_DAC_HIRES,
+	CLK_AUD_A1SYS_HP,
+	CLK_AUD_AFE_DMIC1,
+	CLK_AUD_AFE_DMIC2,
+	CLK_AUD_AFE_DMIC3,
+	CLK_AUD_AFE_DMIC4,
+	CLK_AUD_AFE_26M_DMIC_TM,
+	CLK_AUD_UL_TML_HIRES,
+	CLK_AUD_ADC_HIRES,
+	CLK_AUD_ADDA6_ADC,
+	CLK_AUD_ADDA6_ADC_HIRES,
+	CLK_AUD_LINEIN_TUNER,
+	CLK_AUD_EARC_TUNER,
+	CLK_AUD_I2SIN,
+	CLK_AUD_TDM_IN,
+	CLK_AUD_I2S_OUT,
+	CLK_AUD_TDM_OUT,
+	CLK_AUD_HDMI_OUT,
+	CLK_AUD_ASRC11,
+	CLK_AUD_ASRC12,
+	CLK_AUD_MULTI_IN,
+	CLK_AUD_INTDIR,
+	CLK_AUD_A1SYS,
+	CLK_AUD_A2SYS,
+	CLK_AUD_PCMIF,
+	CLK_AUD_A3SYS,
+	CLK_AUD_A4SYS,
+	CLK_AUD_MEMIF_UL1,
+	CLK_AUD_MEMIF_UL2,
+	CLK_AUD_MEMIF_UL3,
+	CLK_AUD_MEMIF_UL4,
+	CLK_AUD_MEMIF_UL5,
+	CLK_AUD_MEMIF_UL6,
+	CLK_AUD_MEMIF_UL8,
+	CLK_AUD_MEMIF_UL9,
+	CLK_AUD_MEMIF_UL10,
+	CLK_AUD_MEMIF_DL2,
+	CLK_AUD_MEMIF_DL3,
+	CLK_AUD_MEMIF_DL6,
+	CLK_AUD_MEMIF_DL7,
+	CLK_AUD_MEMIF_DL8,
+	CLK_AUD_MEMIF_DL10,
+	CLK_AUD_MEMIF_DL11,
+	CLK_AUD_GASRC0,
+	CLK_AUD_GASRC1,
+	CLK_AUD_GASRC2,
+	CLK_AUD_GASRC3,
+	CLK_AUD_GASRC4,
+	CLK_AUD_GASRC5,
+	CLK_AUD_GASRC6,
+	CLK_AUD_GASRC7,
+	CLK_AUD_GASRC8,
+	CLK_AUD_GASRC9,
+	CLK_AUD_GASRC10,
+	CLK_AUD_GASRC11,
+	CLK_AUD_GASRC12,
+	CLK_AUD_GASRC13,
+	CLK_AUD_GASRC14,
+	CLK_AUD_GASRC15,
+	CLK_AUD_GASRC16,
+	CLK_AUD_GASRC17,
+	CLK_AUD_GASRC18,
+	CLK_AUD_GASRC19,
+	CLK_AUD_NR_CLK,
+};
+
+#endif
-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:43 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:43 +0800
Subject: [PATCH v5 10/11] ASoC: mediatek: mt8195: add HDMITX audio support
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-11-trevor.wu@mediatek.com>

This patch adds HDMITX audio support on mt8195-mt6359-rt1019-rt5682 board.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
index d853bc445753..5dc217f59bd6 100644
--- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
@@ -28,6 +28,7 @@
 struct mt8195_mt6359_rt1019_rt5682_priv {
 	struct snd_soc_jack headset_jack;
 	struct snd_soc_jack dp_jack;
+	struct snd_soc_jack hdmi_jack;
 };
 
 static const struct snd_soc_dapm_widget
@@ -407,6 +408,22 @@ static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
 	return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL);
 }
 
+static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+		snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	int ret = 0;
+
+	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
+				    &priv->hdmi_jack, NULL, 0);
+	if (ret)
+		return ret;
+
+	return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
+}
+
 static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 					      struct snd_pcm_hw_params *params)
 
@@ -936,6 +953,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
 			SND_SOC_DAIFMT_NB_NF |
 			SND_SOC_DAIFMT_CBS_CFS,
 		.dpcm_playback = 1,
+		.be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup,
 		SND_SOC_DAILINK_REG(ETDM3_OUT_BE),
 	},
 	[DAI_LINK_PCM1_BE] = {
@@ -1008,6 +1026,20 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
 			dai_link->codecs->dai_name = "i2s-hifi";
 			dai_link->init = mt8195_dptx_codec_init;
 		}
+
+		if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
+			dai_link->codecs->of_node =
+				of_parse_phandle(pdev->dev.of_node,
+						 "mediatek,hdmi-codec", 0);
+			if (!dai_link->codecs->of_node) {
+				dev_err(&pdev->dev, "Property 'hdmi-codec' missing or invalid\n");
+				return -EINVAL;
+			}
+
+			dai_link->codecs->name = NULL;
+			dai_link->codecs->dai_name = "i2s-hifi";
+			dai_link->init = mt8195_hdmi_codec_init;
+		}
 	}
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:37 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:37 +0800
Subject: [PATCH v5 04/11] ASoC: mediatek: mt8195: support adda in platform
 driver
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-5-trevor.wu@mediatek.com>

This patch adds mt8195 adda dai driver.

audio_h clock is used by ADSP bus and ADDA module.
When ADDA requires audio_h clock, it is switched to APLL1, otherwise
it is switched to Xtal_26m so that APLL1 can be turned off when audio
feature is not used.
ADSP bus only requires that the clock is on, so dynamic reparenting
is used for the purpose of lowering power consumption.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/mt8195/mt8195-dai-adda.c | 830 ++++++++++++++++++++
 1 file changed, 830 insertions(+)
 create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-adda.c

diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-adda.c b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
new file mode 100644
index 000000000000..878dec0b69ed
--- /dev/null
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI ADDA Control
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai at mediatek.com>
+ *         Trevor Wu <trevor.wu at mediatek.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include "mt8195-afe-clk.h"
+#include "mt8195-afe-common.h"
+#include "mt8195-reg.h"
+
+#define ADDA_DL_GAIN_LOOPBACK 0x1800
+#define ADDA_HIRES_THRES 48000
+
+enum {
+	SUPPLY_SEQ_CLOCK_SEL,
+	SUPPLY_SEQ_CLOCK_ON,
+	SUPPLY_SEQ_ADDA_DL_ON,
+	SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+	SUPPLY_SEQ_ADDA_UL_ON,
+	SUPPLY_SEQ_ADDA_AFE_ON,
+};
+
+enum {
+	MTK_AFE_ADDA_DL_RATE_8K = 0,
+	MTK_AFE_ADDA_DL_RATE_11K = 1,
+	MTK_AFE_ADDA_DL_RATE_12K = 2,
+	MTK_AFE_ADDA_DL_RATE_16K = 3,
+	MTK_AFE_ADDA_DL_RATE_22K = 4,
+	MTK_AFE_ADDA_DL_RATE_24K = 5,
+	MTK_AFE_ADDA_DL_RATE_32K = 6,
+	MTK_AFE_ADDA_DL_RATE_44K = 7,
+	MTK_AFE_ADDA_DL_RATE_48K = 8,
+	MTK_AFE_ADDA_DL_RATE_96K = 9,
+	MTK_AFE_ADDA_DL_RATE_192K = 10,
+};
+
+enum {
+	MTK_AFE_ADDA_UL_RATE_8K = 0,
+	MTK_AFE_ADDA_UL_RATE_16K = 1,
+	MTK_AFE_ADDA_UL_RATE_32K = 2,
+	MTK_AFE_ADDA_UL_RATE_48K = 3,
+	MTK_AFE_ADDA_UL_RATE_96K = 4,
+	MTK_AFE_ADDA_UL_RATE_192K = 5,
+};
+
+enum {
+	DELAY_DATA_MISO1 = 0,
+	DELAY_DATA_MISO0 = 1,
+	DELAY_DATA_MISO2 = 1,
+};
+
+enum {
+	MTK_AFE_ADDA,
+	MTK_AFE_ADDA6,
+};
+
+struct mtk_dai_adda_priv {
+	bool hires_required;
+};
+
+static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
+					       unsigned int rate)
+{
+	switch (rate) {
+	case 8000:
+		return MTK_AFE_ADDA_DL_RATE_8K;
+	case 11025:
+		return MTK_AFE_ADDA_DL_RATE_11K;
+	case 12000:
+		return MTK_AFE_ADDA_DL_RATE_12K;
+	case 16000:
+		return MTK_AFE_ADDA_DL_RATE_16K;
+	case 22050:
+		return MTK_AFE_ADDA_DL_RATE_22K;
+	case 24000:
+		return MTK_AFE_ADDA_DL_RATE_24K;
+	case 32000:
+		return MTK_AFE_ADDA_DL_RATE_32K;
+	case 44100:
+		return MTK_AFE_ADDA_DL_RATE_44K;
+	case 48000:
+		return MTK_AFE_ADDA_DL_RATE_48K;
+	case 96000:
+		return MTK_AFE_ADDA_DL_RATE_96K;
+	case 192000:
+		return MTK_AFE_ADDA_DL_RATE_192K;
+	default:
+		dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+			 __func__, rate);
+		return MTK_AFE_ADDA_DL_RATE_48K;
+	}
+}
+
+static unsigned int afe_adda_ul_rate_transform(struct mtk_base_afe *afe,
+					       unsigned int rate)
+{
+	switch (rate) {
+	case 8000:
+		return MTK_AFE_ADDA_UL_RATE_8K;
+	case 16000:
+		return MTK_AFE_ADDA_UL_RATE_16K;
+	case 32000:
+		return MTK_AFE_ADDA_UL_RATE_32K;
+	case 48000:
+		return MTK_AFE_ADDA_UL_RATE_48K;
+	case 96000:
+		return MTK_AFE_ADDA_UL_RATE_96K;
+	case 192000:
+		return MTK_AFE_ADDA_UL_RATE_192K;
+	default:
+		dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+			 __func__, rate);
+		return MTK_AFE_ADDA_UL_RATE_48K;
+	}
+}
+
+static int mt8195_adda_mtkaif_init(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int delay_data;
+	int delay_cycle;
+	unsigned int mask = 0;
+	unsigned int val = 0;
+
+	/* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
+	mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+	val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+
+	regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask, val);
+	regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, mask, val);
+
+	mask = RG_RX_PROTOCOL2;
+	val = RG_RX_PROTOCOL2;
+	regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val);
+
+	if (!param->mtkaif_calibration_ok) {
+		dev_info(afe->dev, "%s(), calibration fail\n",  __func__);
+		return 0;
+	}
+
+	/* set delay for ch1, ch2 */
+	if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] >=
+	    param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {
+		delay_data = DELAY_DATA_MISO1;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];
+	} else {
+		delay_data = DELAY_DATA_MISO0;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0];
+	}
+
+	val = 0;
+	mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+	val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+	       MTKAIF_RXIF_DELAY_CYCLE_MASK;
+	val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+	regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
+
+	/* set delay between ch3 and ch2 */
+	if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] >=
+	    param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) {
+		delay_data = DELAY_DATA_MISO1;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1];
+	} else {
+		delay_data = DELAY_DATA_MISO2;
+		delay_cycle =
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] -
+			param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2];
+	}
+
+	val = 0;
+	mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+	val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+	       MTKAIF_RXIF_DELAY_CYCLE_MASK;
+	val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+	regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG2, mask, val);
+
+	return 0;
+}
+
+static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
+				     struct snd_kcontrol *kcontrol,
+				     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8195_adda_mtkaif_init(afe);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, int adda, bool dmic)
+{
+	unsigned int reg = 0;
+	unsigned int mask = 0;
+	unsigned int val = 0;
+
+	switch (adda) {
+	case MTK_AFE_ADDA:
+		reg = AFE_ADDA_UL_SRC_CON0;
+		break;
+	case MTK_AFE_ADDA6:
+		reg = AFE_ADDA6_UL_SRC_CON0;
+		break;
+	default:
+		dev_info(afe->dev, "%s(), wrong parameter\n",  __func__);
+		return;
+	}
+
+	mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
+		UL_MODE_3P25M_CH2_CTL);
+
+	/* turn on dmic, ch1, ch2 */
+	if (dmic)
+		val = mask;
+
+	regmap_update_bits(afe->regmap, reg, mask, val);
+}
+
+static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_adda_ul_mictype(afe, MTK_AFE_ADDA, param->mtkaif_dmic_on);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_adda6_ul_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol,
+			      int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	unsigned int val;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_adda_ul_mictype(afe, MTK_AFE_ADDA6, param->mtkaif_dmic_on);
+
+		val = (param->mtkaif_adda6_only ?
+			ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE : 0);
+
+		regmap_update_bits(afe->regmap,
+				   AFE_ADDA_MTKAIF_SYNCWORD_CFG,
+				   ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE,
+				   val);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+		usleep_range(125, 135);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kcontrol,
+				 int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct clk *clk = afe_priv->clk[MT8195_CLK_TOP_AUDIO_H_SEL];
+	struct clk *clk_parent;
+
+	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		clk_parent = afe_priv->clk[MT8195_CLK_TOP_APLL1];
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		clk_parent = afe_priv->clk[MT8195_CLK_XTAL_26M];
+		break;
+	default:
+		return 0;
+	}
+	mt8195_afe_set_clk_parent(afe, clk, clk_parent);
+
+	return 0;
+}
+
+static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe,
+						       const char *name)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	int dai_id;
+
+	if (strstr(name, "aud_adc_hires"))
+		dai_id = MT8195_AFE_IO_UL_SRC1;
+	else if (strstr(name, "aud_adda6_adc_hires"))
+		dai_id = MT8195_AFE_IO_UL_SRC2;
+	else if (strstr(name, "aud_dac_hires"))
+		dai_id = MT8195_AFE_IO_DL_SRC;
+	else
+		return NULL;
+
+	return afe_priv->dai_priv[dai_id];
+}
+
+static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source,
+				      struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = source;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_adda_priv *adda_priv;
+
+	adda_priv = get_adda_priv_by_name(afe, w->name);
+
+	if (!adda_priv) {
+		dev_info(afe->dev, "adda_priv == NULL");
+		return 0;
+	}
+
+	return (adda_priv->hires_required) ? 1 : 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {
+	SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),
+	SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),
+};
+
+static const char * const adda_dlgain_mux_map[] = {
+	"Bypass", "Connect",
+};
+
+static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,
+			    SND_SOC_NOPM, 0,
+			    adda_dlgain_mux_map);
+
+static const struct snd_kcontrol_new adda_dlgain_mux_control =
+	SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);
+
+static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
+	SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I170", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("I171", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+	SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_adda_o176_mix,
+			   ARRAY_SIZE(mtk_dai_adda_o176_mix)),
+	SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,
+			   mtk_dai_adda_o177_mix,
+			   ARRAY_SIZE(mtk_dai_adda_o177_mix)),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
+			      AFE_ADDA_UL_DL_CON0,
+			      ADDA_AFE_ON_SHIFT, 0,
+			      NULL,
+			      0),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
+			      AFE_ADDA_DL_SRC2_CON0,
+			      DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,
+			      mtk_adda_dl_event,
+			      SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+			      AFE_ADDA_UL_SRC_CON0,
+			      UL_SRC_ON_TMP_CTL_SHIFT, 0,
+			      mtk_adda_ul_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA6 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+			      AFE_ADDA6_UL_SRC_CON0,
+			      UL_SRC_ON_TMP_CTL_SHIFT, 0,
+			      mtk_adda6_ul_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,
+			      SND_SOC_NOPM,
+			      0, 0,
+			      mtk_audio_hires_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+			      SND_SOC_NOPM,
+			      0, 0,
+			      mtk_adda_mtkaif_cfg_event,
+			      SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,
+			 &adda_dlgain_mux_control),
+
+	SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,
+			 DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),
+
+	SND_SOC_DAPM_INPUT("ADDA_INPUT"),
+	SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),
+
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),
+	SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc_hires"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
+	{"ADDA Capture", NULL, "ADDA Enable"},
+	{"ADDA Capture", NULL, "ADDA Capture Enable"},
+	{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
+	{"ADDA Capture", NULL, "aud_adc"},
+	{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect},
+	{"aud_adc_hires", NULL, "AUDIO_HIRES"},
+
+	{"ADDA6 Capture", NULL, "ADDA Enable"},
+	{"ADDA6 Capture", NULL, "ADDA6 Capture Enable"},
+	{"ADDA6 Capture", NULL, "ADDA_MTKAIF_CFG"},
+	{"ADDA6 Capture", NULL, "aud_adda6_adc"},
+	{"ADDA6 Capture", NULL, "aud_adda6_adc_hires",
+	mtk_afe_adda_hires_connect},
+	{"aud_adda6_adc_hires", NULL, "AUDIO_HIRES"},
+
+	{"I168", NULL, "ADDA Capture"},
+	{"I169", NULL, "ADDA Capture"},
+	{"I170", NULL, "ADDA6 Capture"},
+	{"I171", NULL, "ADDA6 Capture"},
+
+	{"ADDA Playback", NULL, "ADDA Enable"},
+	{"ADDA Playback", NULL, "ADDA Playback Enable"},
+	{"ADDA Playback", NULL, "aud_dac"},
+	{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect},
+	{"aud_dac_hires", NULL, "AUDIO_HIRES"},
+
+	{"DL_GAIN", NULL, "O176"},
+	{"DL_GAIN", NULL, "O177"},
+
+	{"DL_GAIN_MUX", "Bypass", "O176"},
+	{"DL_GAIN_MUX", "Bypass", "O177"},
+	{"DL_GAIN_MUX", "Connect", "DL_GAIN"},
+
+	{"ADDA Playback", NULL, "DL_GAIN_MUX"},
+
+	{"O176", "I000 Switch", "I000"},
+	{"O177", "I001 Switch", "I001"},
+
+	{"O176", "I002 Switch", "I002"},
+	{"O177", "I003 Switch", "I003"},
+
+	{"O176", "I020 Switch", "I020"},
+	{"O177", "I021 Switch", "I021"},
+
+	{"O176", "I022 Switch", "I022"},
+	{"O177", "I023 Switch", "I023"},
+
+	{"O176", "I070 Switch", "I070"},
+	{"O177", "I071 Switch", "I071"},
+
+	{"ADDA Capture", NULL, "ADDA_INPUT"},
+	{"ADDA6 Capture", NULL, "ADDA_INPUT"},
+	{"ADDA_OUTPUT", NULL, "ADDA Playback"},
+};
+
+static int mt8195_adda_dl_gain_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+	unsigned int reg = AFE_ADDA_DL_SRC2_CON1;
+	unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;
+	unsigned int value = (unsigned int)(ucontrol->value.integer.value[0]);
+
+	regmap_update_bits(afe->regmap, reg, mask, DL_2_GAIN_CTL_PRE(value));
+	return 0;
+}
+
+static int mt8195_adda_dl_gain_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+	unsigned int reg = AFE_ADDA_DL_SRC2_CON1;
+	unsigned int mask = DL_2_GAIN_CTL_PRE_MASK;
+	unsigned int value = 0;
+
+	regmap_read(afe->regmap, reg, &value);
+
+	ucontrol->value.integer.value[0] = ((value & mask) >>
+					    DL_2_GAIN_CTL_PRE_SHIFT);
+	return 0;
+}
+
+static int mt8195_adda6_only_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	ucontrol->value.integer.value[0] = param->mtkaif_adda6_only;
+	return 0;
+}
+
+static int mt8195_adda6_only_set(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int mtkaif_adda6_only;
+
+	mtkaif_adda6_only = ucontrol->value.integer.value[0];
+
+	dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n",
+		 __func__, kcontrol->id.name, mtkaif_adda6_only);
+
+	param->mtkaif_adda6_only = mtkaif_adda6_only;
+
+	return 0;
+}
+
+static int mt8195_adda_dmic_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+	ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;
+	return 0;
+}
+
+static int mt8195_adda_dmic_set(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtkaif_param *param = &afe_priv->mtkaif_params;
+	int dmic_on;
+
+	dmic_on = ucontrol->value.integer.value[0];
+
+	dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
+		__func__, kcontrol->id.name, dmic_on);
+
+	param->mtkaif_dmic_on = dmic_on;
+	return 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_controls[] = {
+	SOC_SINGLE_EXT("ADDA_DL_Gain", SND_SOC_NOPM, 0, 65535, 0,
+		       mt8195_adda_dl_gain_get, mt8195_adda_dl_gain_put),
+	SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC", 0,
+			    mt8195_adda_dmic_get, mt8195_adda_dmic_set),
+	SOC_SINGLE_BOOL_EXT("MTKAIF_ADDA6_ONLY", 0,
+			    mt8195_adda6_only_get,
+			    mt8195_adda6_only_set),
+};
+
+static int mtk_dai_da_configure(struct mtk_base_afe *afe,
+				unsigned int rate, int id)
+{
+	unsigned int val = 0;
+	unsigned int mask = 0;
+
+	/* set sampling rate */
+	mask |= DL_2_INPUT_MODE_CTL_MASK;
+	val |= DL_2_INPUT_MODE_CTL(afe_adda_dl_rate_transform(afe, rate));
+
+	/* turn off saturation */
+	mask |= DL_2_CH1_SATURATION_EN_CTL;
+	mask |= DL_2_CH2_SATURATION_EN_CTL;
+
+	/* turn off mute function */
+	mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+	mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+	val |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+	val |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+
+	/* set voice input data if input sample rate is 8k or 16k */
+	mask |= DL_2_VOICE_MODE_CTL_PRE;
+	if (rate == 8000 || rate == 16000)
+		val |= DL_2_VOICE_MODE_CTL_PRE;
+
+	regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);
+
+	mask = 0;
+	val = 0;
+
+	/* new 2nd sdm */
+	mask |= DL_USE_NEW_2ND_SDM;
+	val |= DL_USE_NEW_2ND_SDM;
+	regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, mask, val);
+
+	return 0;
+}
+
+static int mtk_dai_ad_configure(struct mtk_base_afe *afe,
+				unsigned int rate, int id)
+{
+	unsigned int val = 0;
+	unsigned int mask = 0;
+
+	mask |= UL_VOICE_MODE_CTL_MASK;
+	val |= UL_VOICE_MODE_CTL(afe_adda_ul_rate_transform(afe, rate));
+
+	switch (id) {
+	case MT8195_AFE_IO_UL_SRC1:
+		regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
+				   mask, val);
+		break;
+	case MT8195_AFE_IO_UL_SRC2:
+		regmap_update_bits(afe->regmap, AFE_ADDA6_UL_SRC_CON0,
+				   mask, val);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id];
+	unsigned int rate = params_rate(params);
+	int id = dai->id;
+	int ret = 0;
+
+	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
+		__func__, id, substream->stream, rate);
+
+	if (rate > ADDA_HIRES_THRES)
+		adda_priv->hires_required = 1;
+	else
+		adda_priv->hires_required = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ret = mtk_dai_da_configure(afe, rate, id);
+	else
+		ret = mtk_dai_ad_configure(afe, rate, id);
+
+	return ret;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
+	.hw_params = mtk_dai_adda_hw_params,
+};
+
+/* dai driver */
+#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
+				 SNDRV_PCM_RATE_96000 |\
+				 SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
+				SNDRV_PCM_RATE_16000 |\
+				SNDRV_PCM_RATE_32000 |\
+				SNDRV_PCM_RATE_48000 |\
+				SNDRV_PCM_RATE_96000 |\
+				SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+			  SNDRV_PCM_FMTBIT_S24_LE |\
+			  SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
+	{
+		.name = "DL_SRC",
+		.id = MT8195_AFE_IO_DL_SRC,
+		.playback = {
+			.stream_name = "ADDA Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_PLAYBACK_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+	{
+		.name = "UL_SRC1",
+		.id = MT8195_AFE_IO_UL_SRC1,
+		.capture = {
+			.stream_name = "ADDA Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_CAPTURE_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+	{
+		.name = "UL_SRC2",
+		.id = MT8195_AFE_IO_UL_SRC2,
+		.capture = {
+			.stream_name = "ADDA6 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MTK_ADDA_CAPTURE_RATES,
+			.formats = MTK_ADDA_FORMATS,
+		},
+		.ops = &mtk_dai_adda_ops,
+	},
+};
+
+static int init_adda_priv_data(struct mtk_base_afe *afe)
+{
+	struct mt8195_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_adda_priv *adda_priv;
+	int adda_dai_list[] = { MT8195_AFE_IO_DL_SRC,
+				MT8195_AFE_IO_UL_SRC1,
+				MT8195_AFE_IO_UL_SRC2};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) {
+		adda_priv = devm_kzalloc(afe->dev,
+					 sizeof(struct mtk_dai_adda_priv),
+					 GFP_KERNEL);
+		if (!adda_priv)
+			return -ENOMEM;
+
+		afe_priv->dai_priv[adda_dai_list[i]] = adda_priv;
+	}
+
+	return 0;
+}
+
+int mt8195_dai_adda_register(struct mtk_base_afe *afe)
+{
+	struct mtk_base_afe_dai *dai;
+
+	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+
+	list_add(&dai->list, &afe->sub_dais);
+
+	dai->dai_drivers = mtk_dai_adda_driver;
+	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
+
+	dai->dapm_widgets = mtk_dai_adda_widgets;
+	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
+	dai->dapm_routes = mtk_dai_adda_routes;
+	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
+	dai->controls = mtk_dai_adda_controls;
+	dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);
+
+	return init_adda_priv_data(afe);
+}
-- 
2.18.0

From trevor.wu at mediatek.com  Thu Aug 19 01:41:42 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Thu, 19 Aug 2021 16:41:42 +0800
Subject: [PATCH v5 09/11] ASoC: mediatek: mt8195: add DPTX audio support
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <20210819084144.18483-10-trevor.wu@mediatek.com>

This patch adds DPTX audio support on mt8195-mt6359-rt1019-rt5682 board.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 sound/soc/mediatek/Kconfig                    |  1 +
 .../mt8195/mt8195-mt6359-rt1019-rt5682.c      | 88 +++++++++++++++++--
 2 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index bfee954d0c7c..cf567a89f421 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -202,6 +202,7 @@ config SND_SOC_MT8195_MT6359_RT1019_RT5682
 	select SND_SOC_RT1015P
 	select SND_SOC_RT5682_I2C
 	select SND_SOC_DMIC
+	select SND_SOC_HDMI_CODEC
 	help
 	  This adds ASoC driver for Mediatek MT8195 boards
 	  with the MT6359 RT1019 RT5682 audio codec.
diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
index 39b33aecc1e9..d853bc445753 100644
--- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
+++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c
@@ -27,6 +27,7 @@
 
 struct mt8195_mt6359_rt1019_rt5682_priv {
 	struct snd_soc_jack headset_jack;
+	struct snd_soc_jack dp_jack;
 };
 
 static const struct snd_soc_dapm_widget
@@ -327,6 +328,52 @@ static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 	return 0;
 }
 
+static int mt8195_hdmitx_dptx_startup(struct snd_pcm_substream *substream)
+{
+	static const unsigned int rates[] = {
+		48000
+	};
+	static const unsigned int channels[] = {
+		2, 4, 6, 8
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list  = rates,
+		.mask = 0,
+	};
+	static const struct snd_pcm_hw_constraint_list constraints_channels = {
+		.count = ARRAY_SIZE(channels),
+		.list  = channels,
+		.mask = 0,
+	};
+
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int ret;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_RATE,
+					 &constraints_rates);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list rate failed\n");
+		return ret;
+	}
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_CHANNELS,
+					 &constraints_channels);
+	if (ret < 0) {
+		dev_err(rtd->dev, "hw_constraint_list channel failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_ops mt8195_hdmitx_dptx_playback_ops = {
+	.startup = mt8195_hdmitx_dptx_startup,
+};
+
 static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params)
 {
@@ -344,8 +391,25 @@ static struct snd_soc_ops mt8195_dptx_ops = {
 	.hw_params = mt8195_dptx_hw_params,
 };
 
-static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
-				       struct snd_pcm_hw_params *params)
+static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct mt8195_mt6359_rt1019_rt5682_priv *priv =
+		snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_component *cmpnt_codec =
+		asoc_rtd_to_codec(rtd, 0)->component;
+	int ret = 0;
+
+	ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT,
+				    &priv->dp_jack, NULL, 0);
+	if (ret)
+		return ret;
+
+	return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL);
+}
+
+static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					      struct snd_pcm_hw_params *params)
+
 {
 	/* fix BE i2s format to 32bit, clean param mask first */
 	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
@@ -687,6 +751,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
 		},
 		.dynamic = 1,
 		.dpcm_playback = 1,
+		.ops = &mt8195_hdmitx_dptx_playback_ops,
 		SND_SOC_DAILINK_REG(DL10_FE),
 	},
 	[DAI_LINK_DL11_FE] = {
@@ -820,7 +885,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
 		.no_pcm = 1,
 		.dpcm_playback = 1,
 		.ops = &mt8195_dptx_ops,
-		.be_hw_params_fixup = mt8195_dptx_hw_params_fixup,
+		.be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup,
 		SND_SOC_DAILINK_REG(DPTX_BE),
 	},
 	[DAI_LINK_ETDM1_IN_BE] = {
@@ -915,7 +980,6 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
 	struct device_node *platform_node;
 	struct snd_soc_dai_link *dai_link;
 	struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL;
-
 	int ret, i;
 
 	card->dev = &pdev->dev;
@@ -930,6 +994,20 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
 	for_each_card_prelinks(card, i, dai_link) {
 		if (!dai_link->platforms->name)
 			dai_link->platforms->of_node = platform_node;
+
+		if (strcmp(dai_link->name, "DPTX_BE") == 0) {
+			dai_link->codecs->of_node =
+				of_parse_phandle(pdev->dev.of_node,
+						 "mediatek,dptx-codec", 0);
+			if (!dai_link->codecs->of_node) {
+				dev_err(&pdev->dev, "Property 'dptx-codec' missing or invalid\n");
+				return -EINVAL;
+			}
+
+			dai_link->codecs->name = NULL;
+			dai_link->codecs->dai_name = "i2s-hifi";
+			dai_link->init = mt8195_dptx_codec_init;
+		}
 	}
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -940,7 +1018,7 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
 
 	ret = devm_snd_soc_register_card(&pdev->dev, card);
 	if (ret)
-		dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n",
+		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
 	return ret;
 }
-- 
2.18.0

From will at kernel.org  Thu Aug 19 02:04:35 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 19 Aug 2021 10:04:35 +0100
Subject: [PATCH] arm64: initialize all of CNTHCTL_EL2
In-Reply-To: <20210818161535.52786-1-mark.rutland@arm.com>
References: <20210818161535.52786-1-mark.rutland@arm.com>
Message-ID: <162936373134.1479808.3089909665812193636.b4-ty@kernel.org>

On Wed, 18 Aug 2021 17:15:35 +0100, Mark Rutland wrote:
> In __init_el2_timers we initialize CNTHCTL_EL2.{EL1PCEN,EL1PCTEN} with a
> RMW sequence, leaving all other bits UNKNOWN.
> 
> In general, we should initialize all bits in a register rather than
> using an RMW sequence, since most bits are UNKNOWN out of reset, and as
> new bits are added to the reigster their reset value might not result in
> expected behaviour.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: initialize all of CNTHCTL_EL2
      https://git.kernel.org/arm64/c/bde8fff82e4a

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From maz at kernel.org  Thu Aug 19 02:11:09 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Aug 2021 10:11:09 +0100
Subject: [PATCH v7 3/7] KVM: arm64: Allow userspace to configure a vCPU's
 virtual offset
In-Reply-To: <20210816001217.3063400-4-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
 <20210816001217.3063400-4-oupton@google.com>
Message-ID: <874kblsssy.wl-maz@kernel.org>

On Mon, 16 Aug 2021 01:12:13 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Allow userspace to access the guest's virtual counter-timer offset
> through the ONE_REG interface. The value read or written is defined to
> be an offset from the guest's physical counter-timer. Add some
> documentation to clarify how a VMM should use this and the existing
> CNTVCT_EL0.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> Reviewed-by: Andrew Jones <drjones at redhat.com>
> ---
>  Documentation/virt/kvm/api.rst    | 10 ++++++++++
>  arch/arm64/include/uapi/asm/kvm.h |  1 +
>  arch/arm64/kvm/arch_timer.c       | 23 +++++++++++++++++++++++
>  arch/arm64/kvm/guest.c            |  6 +++++-
>  include/kvm/arm_arch_timer.h      |  1 +
>  5 files changed, 40 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index dae68e68ca23..adb04046a752 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -2463,6 +2463,16 @@ arm64 system registers have the following id bit patterns::
>       derived from the register encoding for CNTV_CVAL_EL0.  As this is
>       API, it must remain this way.
>  
> +.. warning::
> +
> +     The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from
> +     the guest's view of the physical counter-timer.
> +
> +     Userspace should use either KVM_REG_ARM_TIMER_OFFSET or
> +     KVM_REG_ARM_TIMER_CNT to pause and resume a guest's virtual
> +     counter-timer. Mixed use of these registers could result in an
> +     unpredictable guest counter value.
> +
>  arm64 firmware pseudo-registers have the following bit pattern::
>  
>    0x6030 0000 0014 <regno:16>
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index b3edde68bc3e..949a31bc10f0 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags {
>  #define KVM_REG_ARM_TIMER_CTL		ARM64_SYS_REG(3, 3, 14, 3, 1)
>  #define KVM_REG_ARM_TIMER_CVAL		ARM64_SYS_REG(3, 3, 14, 0, 2)
>  #define KVM_REG_ARM_TIMER_CNT		ARM64_SYS_REG(3, 3, 14, 3, 2)
> +#define KVM_REG_ARM_TIMER_OFFSET	ARM64_SYS_REG(3, 4, 14, 0, 3)
>

Andrew, does this warrant an update to the selftest that checks for
sysreg visibility?

I am also wondering how a VMM such as QEMU is going to deal with the
above restriction, given the way it blindly saves/restores all the
registers that KVM exposes, hence hitting that mixed-use that the
documentation warns about...

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From quic_taozha at quicinc.com  Thu Aug 19 02:28:42 2021
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Thu, 19 Aug 2021 17:28:42 +0800
Subject: [PATCH 0/2] Add Coresight support for RB5 board
Message-ID: <1629365324-5891-1-git-send-email-quic_taozha@quicinc.com>

This series adds Coresight support for SM8250 Soc on RB5 board.
It is composed of two elements.
a) Add ETM PID for Kryo-5XX.
b) Add coresight support to DTS for RB5.

This series applies to coresight/next
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git

Tao Zhang (2):
  coresight: etm4x: Add ETM PID for Kryo-5XX
  arm64: dts: qcom: sm8250: Add Coresight support

 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts      | 442 +++++++++++++++++-
 .../coresight/coresight-etm4x-core.c          |   1 +
 2 files changed, 439 insertions(+), 4 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From quic_taozha at quicinc.com  Thu Aug 19 02:28:43 2021
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Thu, 19 Aug 2021 17:28:43 +0800
Subject: [PATCH 1/2] coresight: etm4x: Add ETM PID for Kryo-5XX
In-Reply-To: <1629365324-5891-1-git-send-email-quic_taozha@quicinc.com>
References: <1629365324-5891-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1629365324-5891-2-git-send-email-quic_taozha@quicinc.com>

Add ETM PID for Kryo-5XX to the list of supported ETMs.
Otherwise, Kryo-5XX ETMs will not be initialized successfully.
e.g.
This change can be verified on qrb5165-rb5 board. ETM4-ETM7 nodes
will not be visible without this change.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index da27cd4a3c38..84959c585a5f 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -2065,6 +2065,7 @@ static const struct amba_id etm4_ids[] = {
 	CS_AMBA_UCI_ID(0x000bb803, uci_id_etm4),/* Qualcomm Kryo 385 Cortex-A75 */
 	CS_AMBA_UCI_ID(0x000bb805, uci_id_etm4),/* Qualcomm Kryo 4XX Cortex-A55 */
 	CS_AMBA_UCI_ID(0x000bb804, uci_id_etm4),/* Qualcomm Kryo 4XX Cortex-A76 */
+	CS_AMBA_UCI_ID(0x000bbd0d, uci_id_etm4),/* Qualcomm Kryo 5XX */
 	CS_AMBA_UCI_ID(0x000cc0af, uci_id_etm4),/* Marvell ThunderX2 */
 	CS_AMBA_UCI_ID(0x000b6d01, uci_id_etm4),/* HiSilicon-Hip08 */
 	CS_AMBA_UCI_ID(0x000b6d02, uci_id_etm4),/* HiSilicon-Hip09 */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From quic_taozha at quicinc.com  Thu Aug 19 02:28:44 2021
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Thu, 19 Aug 2021 17:28:44 +0800
Subject: [PATCH 2/2] arm64: dts: qcom: sm8250: Add Coresight support
In-Reply-To: <1629365324-5891-1-git-send-email-quic_taozha@quicinc.com>
References: <1629365324-5891-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <1629365324-5891-3-git-send-email-quic_taozha@quicinc.com>

Add the basic coresight components found on Qualcomm SM8250 Soc. The
basic coresight components include ETF, ETMs,STM and the related
funnels.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 442 ++++++++++++++++++++++-
 1 file changed, 438 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
index 8ac96f8e79d4..9c8f87d80afc 100644
--- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
+++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
@@ -222,11 +222,445 @@
 		regulator-max-microvolt = <1800000>;
 		regulator-always-on;
 	};
-};
 
-&adsp {
-	status = "okay";
-	firmware-name = "qcom/sm8250/adsp.mbn";
+	stm at 6002000 {
+		compatible = "arm,coresight-stm", "arm,primecell";
+		reg = <0 0x06002000 0 0x1000>,
+		      <0 0x16280000 0 0x180000>;
+		reg-names = "stm-base", "stm-stimulus-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				stm_out: endpoint {
+					remote-endpoint =
+					  <&funnel0_in7>;
+				};
+			};
+		};
+	};
+
+	funnel at 6041000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0 0x06041000 0 0x1000>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				funnel0_out: endpoint {
+					remote-endpoint =
+					  <&merge_funnel_in0>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 7 {
+				reg = <7>;
+				funnel0_in7: endpoint {
+					remote-endpoint = <&stm_out>;
+				};
+			};
+		};
+	};
+
+	funnel at 6042000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0 0x06042000 0 0x1000>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				funnel2_out: endpoint {
+					remote-endpoint =
+					  <&merge_funnel_in2>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 4 {
+				reg = <4>;
+				funnel2_in5: endpoint {
+					remote-endpoint =
+					  <&apss_merge_funnel_out>;
+				};
+			};
+		};
+	};
+
+	funnel at 6b04000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		arm,primecell-periphid = <0x000bb908>;
+
+		reg = <0 0x6b04000 0 0x1000>;
+		reg-names = "funnel-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				merge_funnel_out: endpoint {
+					remote-endpoint =
+						<&etf_in>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 7 {
+				reg = <7>;
+				swao_funnel_in7: endpoint {
+					slave-mode;
+					remote-endpoint=
+						<&merg_funnel_out>;
+				};
+			};
+		};
+
+	};
+
+	funnel at 6045000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0 0x06045000 0 0x1000>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				merg_funnel_out: endpoint {
+					remote-endpoint = <&swao_funnel_in7>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+				merge_funnel_in0: endpoint {
+					remote-endpoint =
+					  <&funnel0_out>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+				merge_funnel_in2: endpoint {
+					remote-endpoint =
+					  <&funnel2_out>;
+				};
+			};
+		};
+	};
+
+	etf at 6b05000 {
+		compatible = "arm,coresight-tmc", "arm,primecell";
+		reg = <0 0x06b05000 0 0x1000>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		in-ports {
+			port {
+				etf_in: endpoint {
+					remote-endpoint =
+					  <&merge_funnel_out>;
+				};
+			};
+		};
+	};
+
+	etm at 7040000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0 0x07040000 0 0x1000>;
+
+		cpu = <&CPU0>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		arm,coresight-loses-context-with-cpu;
+
+		out-ports {
+			port {
+				etm0_out: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_in0>;
+				};
+			};
+		};
+	};
+
+	etm at 7140000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0 0x07140000 0 0x1000>;
+
+		cpu = <&CPU1>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		arm,coresight-loses-context-with-cpu;
+
+		out-ports {
+			port {
+				etm1_out: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_in1>;
+				};
+			};
+		};
+	};
+
+	etm at 7240000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0 0x07240000 0 0x1000>;
+
+		cpu = <&CPU2>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		arm,coresight-loses-context-with-cpu;
+
+		out-ports {
+			port {
+				etm2_out: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_in2>;
+				};
+			};
+		};
+	};
+
+	etm at 7340000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0 0x07340000 0 0x1000>;
+
+		cpu = <&CPU3>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		arm,coresight-loses-context-with-cpu;
+
+		out-ports {
+			port {
+				etm3_out: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_in3>;
+				};
+			};
+		};
+	};
+
+	etm at 7440000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0 0x07440000 0 0x1000>;
+
+		cpu = <&CPU4>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		arm,coresight-loses-context-with-cpu;
+
+		out-ports {
+			port {
+				etm4_out: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_in4>;
+				};
+			};
+		};
+	};
+
+	etm at 7540000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0 0x07540000 0 0x1000>;
+
+		cpu = <&CPU5>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		arm,coresight-loses-context-with-cpu;
+
+		out-ports {
+			port {
+				etm5_out: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_in5>;
+				};
+			};
+		};
+	};
+
+	etm at 7640000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0 0x07640000 0 0x1000>;
+
+		cpu = <&CPU6>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		arm,coresight-loses-context-with-cpu;
+
+		out-ports {
+			port {
+				etm6_out: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_in6>;
+				};
+			};
+		};
+	};
+
+	etm at 7740000 {
+		compatible = "arm,coresight-etm4x", "arm,primecell";
+		reg = <0 0x07740000 0 0x1000>;
+
+		cpu = <&CPU7>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		arm,coresight-loses-context-with-cpu;
+
+		out-ports {
+			port {
+				etm7_out: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_in7>;
+				};
+			};
+		};
+	};
+
+	funnel at 7800000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0 0x07800000 0 0x1000>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				apss_funnel_out: endpoint {
+					remote-endpoint =
+					  <&apss_merge_funnel_in>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+				apss_funnel_in0: endpoint {
+					remote-endpoint =
+					  <&etm0_out>;
+				};
+			};
+
+			port at 1 {
+				reg = <1>;
+				apss_funnel_in1: endpoint {
+					remote-endpoint =
+					  <&etm1_out>;
+				};
+			};
+
+			port at 2 {
+				reg = <2>;
+				apss_funnel_in2: endpoint {
+					remote-endpoint =
+					  <&etm2_out>;
+				};
+			};
+
+			port at 3 {
+				reg = <3>;
+				apss_funnel_in3: endpoint {
+					remote-endpoint =
+					  <&etm3_out>;
+				};
+			};
+
+			port at 4 {
+				reg = <4>;
+				apss_funnel_in4: endpoint {
+					remote-endpoint =
+					  <&etm4_out>;
+				};
+			};
+
+			port at 5 {
+				reg = <5>;
+				apss_funnel_in5: endpoint {
+					remote-endpoint =
+					  <&etm5_out>;
+				};
+			};
+
+			port at 6 {
+				reg = <6>;
+				apss_funnel_in6: endpoint {
+					remote-endpoint =
+					  <&etm6_out>;
+				};
+			};
+
+			port at 7 {
+				reg = <7>;
+				apss_funnel_in7: endpoint {
+					remote-endpoint =
+					  <&etm7_out>;
+				};
+			};
+		};
+	};
+
+	funnel at 7810000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		reg = <0 0x07810000 0 0x1000>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				apss_merge_funnel_out: endpoint {
+					remote-endpoint =
+					  <&funnel2_in5>;
+				};
+			};
+		};
+
+		in-ports {
+			port {
+				apss_merge_funnel_in: endpoint {
+					remote-endpoint =
+					  <&apss_funnel_out>;
+				};
+			};
+		};
+	};
 };
 
 &apps_rsc {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From quic_taozha at quicinc.com  Thu Aug 19 02:29:37 2021
From: quic_taozha at quicinc.com (Tao Zhang)
Date: Thu, 19 Aug 2021 17:29:37 +0800
Subject: [PATCH] coresight: cti: Correct the parameter for pm_runtime_put
Message-ID: <1629365377-5937-1-git-send-email-quic_taozha@quicinc.com>

The input parameter of the function pm_runtime_put should be the
same in the function cti_enable_hw and cti_disable_hw. The correct
parameter to use here should be dev->parent.

Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
---
 drivers/hwtracing/coresight/coresight-cti-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
index e2a3620..8988b2e 100644
--- a/drivers/hwtracing/coresight/coresight-cti-core.c
+++ b/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -175,7 +175,7 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
 	coresight_disclaim_device_unlocked(csdev);
 	CS_LOCK(drvdata->base);
 	spin_unlock(&drvdata->spinlock);
-	pm_runtime_put(dev);
+	pm_runtime_put(dev->parent);
 	return 0;
 
 	/* not disabled this call */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From maz at kernel.org  Thu Aug 19 02:52:54 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Aug 2021 10:52:54 +0100
Subject: [PATCH v7 5/7] KVM: arm64: Allow userspace to configure a guest's
 counter-timer offset
In-Reply-To: <20210816001217.3063400-6-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
 <20210816001217.3063400-6-oupton@google.com>
Message-ID: <8735r5sqvd.wl-maz@kernel.org>

On Mon, 16 Aug 2021 01:12:15 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Presently, KVM provides no facilities for correctly migrating a guest
> that depends on the physical counter-timer. While most guests (barring
> NV, of course) should not depend on the physical counter-timer, an
> operator may wish to provide a consistent view of the physical
> counter-timer across migrations.
> 
> Provide userspace with a new vCPU attribute to modify the guest
> counter-timer offset. Unlike KVM_REG_ARM_TIMER_OFFSET, this attribute is
> hidden from the guest's architectural state. The value offsets *both*
> the virtual and physical counter-timer views for the guest. Only support
> this attribute on ECV systems as ECV is required for hardware offsetting
> of the physical counter-timer.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> Reviewed-by: Andrew Jones <drjones at redhat.com>
> ---
>  Documentation/arm64/booting.rst         |  7 ++
>  Documentation/virt/kvm/devices/vcpu.rst | 28 ++++++++
>  arch/arm64/include/asm/kvm_asm.h        |  2 +
>  arch/arm64/include/asm/sysreg.h         |  2 +
>  arch/arm64/include/uapi/asm/kvm.h       |  1 +
>  arch/arm64/kvm/arch_timer.c             | 96 ++++++++++++++++++++++++-
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c      |  6 ++
>  arch/arm64/kvm/hyp/nvhe/timer-sr.c      |  9 +++
>  arch/arm64/kvm/hyp/vhe/timer-sr.c       |  5 ++
>  include/clocksource/arm_arch_timer.h    |  1 +
>  10 files changed, 155 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
> index a9192e7a231b..bfdbc9df7b55 100644
> --- a/Documentation/arm64/booting.rst
> +++ b/Documentation/arm64/booting.rst
> @@ -311,6 +311,13 @@ Before jumping into the kernel, the following conditions must be met:
>      - ZCR_EL2.LEN must be initialised to the same value for all CPUs the
>        kernel will execute on.
>  
> +  For CPUs with the Enhanced Counter Virtualization (FEAT_ECV) extension
> +  present with ID_AA64MMFR0_EL1.ECV >= 0x2:
> +
> +  - if EL3 is present and the kernel is entered at EL2:
> +
> +    - SCR_EL3.ECVEn (bit 28) must be initialized to 0b1.
> +
>  The requirements described above for CPU mode, caches, MMUs, architected
>  timers, coherency and system registers apply to all CPUs.  All CPUs must
>  enter the kernel in the same exception level.  Where the values documented
> diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
> index 2acec3b9ef65..f240ecc174ef 100644
> --- a/Documentation/virt/kvm/devices/vcpu.rst
> +++ b/Documentation/virt/kvm/devices/vcpu.rst
> @@ -139,6 +139,34 @@ configured values on other VCPUs.  Userspace should configure the interrupt
>  numbers on at least one VCPU after creating all VCPUs and before running any
>  VCPUs.
>  
> +2.2. ATTRIBUTE: KVM_ARM_VCPU_TIMER_PHYS_OFFSET
> +-----------------------------------------
> +
> +:Parameters: in kvm_device_attr.addr the address for the timer offset is a
> +             pointer to a __u64
> +
> +Returns:
> +
> +	 ======= ==================================
> +	 -EFAULT Error reading/writing the provided
> +		 parameter address
> +	 -ENXIO  Timer offsetting not implemented
> +	 ======= ==================================
> +
> +Specifies the guest's counter-timer offset from the host's virtual counter.
> +The guest's physical counter value is then derived by the following
> +equation:
> +
> +  guest_cntpct = host_cntvct - KVM_ARM_VCPU_TIMER_PHYS_OFFSET
> +
> +The guest's virtual counter value is derived by the following equation:
> +
> +  guest_cntvct = host_cntvct - KVM_REG_ARM_TIMER_OFFSET
> +			- KVM_ARM_VCPU_TIMER_PHYS_OFFSET
> +
> +KVM does not allow the use of varying offset values for different vCPUs;
> +the last written offset value will be broadcasted to all vCPUs in a VM.
> +
>  3. GROUP: KVM_ARM_VCPU_PVTIME_CTRL
>  ==================================
>  
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index aed2aa61766a..052a6f987095 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -64,6 +64,7 @@
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector		18
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize		19
>  #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc			20
> +#define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntpoff		21
>  
>  #ifndef __ASSEMBLY__
>  
> @@ -199,6 +200,7 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
>  extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
>  
>  extern void __kvm_timer_set_cntvoff(u64 cntvoff);
> +extern void __kvm_timer_set_cntpoff(u64 cntpoff);
>  
>  extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
>  
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index c7ddf9a71134..e02b7cd574e6 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -586,6 +586,8 @@
>  #define SYS_ICH_LR14_EL2		__SYS__LR8_EL2(6)
>  #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
>  
> +#define SYS_CNTPOFF_EL2			sys_reg(3, 4, 14, 0, 6)
> +
>  /* VHE encodings for architectural EL0/1 system registers */
>  #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
>  #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index 949a31bc10f0..70e2893c1749 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -366,6 +366,7 @@ struct kvm_arm_copy_mte_tags {
>  #define KVM_ARM_VCPU_TIMER_CTRL		1
>  #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
>  #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
> +#define   KVM_ARM_VCPU_TIMER_PHYS_OFFSET	2
>  #define KVM_ARM_VCPU_PVTIME_CTRL	2
>  #define   KVM_ARM_VCPU_PVTIME_IPA	0
>  
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index 9d9bac3ec40e..46380c389683 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -86,8 +86,11 @@ static u64 timer_get_offset(struct arch_timer_context *ctxt)
>  {
>  	switch(arch_timer_ctx_index(ctxt)) {
>  	case TIMER_VTIMER:
> +	case TIMER_PTIMER:
>  		return ctxt->host_offset;
>  	default:
> +		WARN_ONCE(1, "unrecognized timer %ld\n",
> +			  arch_timer_ctx_index(ctxt));
>  		return 0;
>  	}
>  }
> @@ -140,6 +143,7 @@ static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
>  {
>  	switch(arch_timer_ctx_index(ctxt)) {
>  	case TIMER_VTIMER:
> +	case TIMER_PTIMER:
>  		ctxt->host_offset = offset;
>  		break;
>  	default:
> @@ -568,6 +572,11 @@ static void set_cntvoff(u64 cntvoff)
>  	kvm_call_hyp(__kvm_timer_set_cntvoff, cntvoff);
>  }
>  
> +static void set_cntpoff(u64 cntpoff)
> +{
> +	kvm_call_hyp(__kvm_timer_set_cntpoff, cntpoff);
> +}
> +
>  static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active)
>  {
>  	int r;
> @@ -643,6 +652,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
>  	}
>  
>  	set_cntvoff(timer_get_offset(map.direct_vtimer));
> +	if (cpus_have_final_cap(ARM64_HAS_ECV2))
> +		set_cntpoff(timer_get_offset(vcpu_ptimer(vcpu)));

You probably want to change vcpu_ptimer(vcpu) to map.direct_ptimer.
This will work for NV, and won't impact nVHE (see below for the
details).

>  
>  	kvm_timer_unblocking(vcpu);
>  
> @@ -810,6 +821,22 @@ static void update_vtimer_cntvoff(struct kvm_vcpu *vcpu, u64 cntvoff)
>  	mutex_unlock(&kvm->lock);
>  }
>  
> +static void update_ptimer_cntpoff(struct kvm_vcpu *vcpu, u64 cntpoff)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 cntvoff;
> +
> +	mutex_lock(&kvm->lock);
> +
> +	/* adjustments to the physical offset also affect vtimer */
> +	cntvoff = timer_get_offset(vcpu_vtimer(vcpu));
> +	cntvoff += cntpoff - timer_get_offset(vcpu_ptimer(vcpu));
> +
> +	update_timer_offset(vcpu, TIMER_PTIMER, cntpoff, false);
> +	update_timer_offset(vcpu, TIMER_VTIMER, cntvoff, false);
> +	mutex_unlock(&kvm->lock);
> +}
> +
>  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
>  {
>  	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
> @@ -1346,6 +1373,9 @@ void kvm_timer_init_vhe(void)
>  	val = read_sysreg(cnthctl_el2);
>  	val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
>  	val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
> +
> +	if (cpus_have_final_cap(ARM64_HAS_ECV2))
> +		val |= CNTHCTL_ECV;
>  	write_sysreg(val, cnthctl_el2);
>  }
>  
> @@ -1360,7 +1390,8 @@ static void set_timer_irqs(struct kvm *kvm, int vtimer_irq, int ptimer_irq)
>  	}
>  }
>  
> -int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +static int kvm_arm_timer_set_attr_irq(struct kvm_vcpu *vcpu,
> +				      struct kvm_device_attr *attr)
>  {
>  	int __user *uaddr = (int __user *)(long)attr->addr;
>  	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
> @@ -1393,7 +1424,37 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  	return 0;
>  }
>  
> -int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +static int kvm_arm_timer_set_attr_offset(struct kvm_vcpu *vcpu,
> +					 struct kvm_device_attr *attr)
> +{
> +	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +	u64 offset;
> +
> +	if (!cpus_have_final_cap(ARM64_HAS_ECV2))
> +		return -ENXIO;
> +
> +	if (get_user(offset, uaddr))
> +		return -EFAULT;
> +
> +	update_ptimer_cntpoff(vcpu, offset);
> +	return 0;
> +}
> +
> +int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> +{
> +	switch (attr->attr) {
> +	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> +	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> +		return kvm_arm_timer_set_attr_irq(vcpu, attr);
> +	case KVM_ARM_VCPU_TIMER_PHYS_OFFSET:
> +		return kvm_arm_timer_set_attr_offset(vcpu, attr);
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
> +static int kvm_arm_timer_get_attr_irq(struct kvm_vcpu *vcpu,
> +				      struct kvm_device_attr *attr)
>  {
>  	int __user *uaddr = (int __user *)(long)attr->addr;
>  	struct arch_timer_context *timer;
> @@ -1414,12 +1475,43 @@ int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  	return put_user(irq, uaddr);
>  }
>  
> +static int kvm_arm_timer_get_attr_offset(struct kvm_vcpu *vcpu,
> +					 struct kvm_device_attr *attr)
> +{
> +	u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> +	u64 offset;
> +
> +	if (!cpus_have_final_cap(ARM64_HAS_ECV2))
> +		return -ENXIO;
> +
> +	offset = timer_get_offset(vcpu_ptimer(vcpu));
> +	return put_user(offset, uaddr);
> +}
> +
> +int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu,
> +			   struct kvm_device_attr *attr)
> +{
> +	switch (attr->attr) {
> +	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
> +	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
> +		return kvm_arm_timer_get_attr_irq(vcpu, attr);
> +	case KVM_ARM_VCPU_TIMER_PHYS_OFFSET:
> +		return kvm_arm_timer_get_attr_offset(vcpu, attr);
> +	default:
> +		return -ENXIO;
> +	}
> +}
> +
>  int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  {
>  	switch (attr->attr) {
>  	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
>  	case KVM_ARM_VCPU_TIMER_IRQ_PTIMER:
>  		return 0;
> +	case KVM_ARM_VCPU_TIMER_PHYS_OFFSET:
> +		if (cpus_have_final_cap(ARM64_HAS_ECV2))
> +			return 0;
> +		break;
>  	}
>  
>  	return -ENXIO;
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 2da6aa8da868..f1b8da4737dc 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -68,6 +68,11 @@ static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ctxt)
>  	__kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1));
>  }
>  
> +static void handle___kvm_timer_set_cntpoff(struct kvm_cpu_context *host_ctxt)
> +{
> +	__kvm_timer_set_cntpoff(cpu_reg(host_ctxt, 1));
> +}
> +
>  static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt)
>  {
>  	u64 tmp;
> @@ -185,6 +190,7 @@ static const hcall_t host_hcall[] = {
>  	HANDLE_FUNC(__pkvm_host_share_hyp),
>  	HANDLE_FUNC(__pkvm_create_private_mapping),
>  	HANDLE_FUNC(__pkvm_prot_finalize),
> +	HANDLE_FUNC(__kvm_timer_set_cntpoff),
>  };
>  
>  static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> diff --git a/arch/arm64/kvm/hyp/nvhe/timer-sr.c b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> index 9072e71693ba..e98a949f5227 100644
> --- a/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> +++ b/arch/arm64/kvm/hyp/nvhe/timer-sr.c
> @@ -15,6 +15,11 @@ void __kvm_timer_set_cntvoff(u64 cntvoff)
>  	write_sysreg(cntvoff, cntvoff_el2);
>  }
>  
> +void __kvm_timer_set_cntpoff(u64 cntpoff)
> +{
> +	write_sysreg_s(cntpoff, SYS_CNTPOFF_EL2);
> +}
> +
>  /*
>   * Should only be called on non-VHE systems.
>   * VHE systems use EL2 timers and configure EL1 timers in kvm_timer_init_vhe().
> @@ -26,6 +31,8 @@ void __timer_disable_traps(struct kvm_vcpu *vcpu)
>  	/* Allow physical timer/counter access for the host */
>  	val = read_sysreg(cnthctl_el2);
>  	val |= CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN;
> +	if (cpus_have_final_cap(ARM64_HAS_ECV2))
> +		val &= ~CNTHCTL_ECV;
>  	write_sysreg(val, cnthctl_el2);
>  }
>  
> @@ -42,6 +49,8 @@ void __timer_enable_traps(struct kvm_vcpu *vcpu)
>  	 * Physical counter access is allowed
>  	 */
>  	val = read_sysreg(cnthctl_el2);
> +	if (cpus_have_final_cap(ARM64_HAS_ECV2))
> +		val |= CNTHCTL_ECV;

There is something here that has been nagging me for some time, and I
just had an epiphany: ECV2 is fundamentally incompatible with the way
we use the physical timer in nVHE.

The main reason is that we never use the EL2 timer like VHE does, but
instead stick with the EL1 timer. Which is fine, since we only provide
access to the *counter* in a guest.

However, with ECV2, we allow the counter to be offset to an arbitrary
value. On the face of it, it should be OK, as only the guest can
access the counter while the offset is active. However, there is a
small nugget in the spec that says:

<quote>
The CNTPOFF_EL2 offset applies to:
* Direct reads of the physical counter from EL0 or EL1.
* Indirect reads of the physical counter by the EL1 physical timer.
</quote>

and this last point is absolutely critical. The timer itself can
observe the offset, which means that depending on how the comparator
is implemented, the offset could influence the firing of the timer
that the *host* uses. And that's clearly not acceptable.

I can see two ways to work around this:

- we stick to the tried and trusted SW emulation for the counter on
nVHE,

- we use the EL2 timer as an offload for the host EL1 timer and switch
it on entry/exit. This requires some additional setup code (the
interrupt needs to be enabled), and the overhead of the offload is
currently unknown.

My advise would be to stick to the emulation until someone shouts,
which is pretty unlikely. We can gate the detection of ECV2 on VHE for
the time being, and drop the setup code.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From drjones at redhat.com  Thu Aug 19 03:20:49 2021
From: drjones at redhat.com (Andrew Jones)
Date: Thu, 19 Aug 2021 12:20:49 +0200
Subject: [PATCH v7 3/7] KVM: arm64: Allow userspace to configure a vCPU's
 virtual offset
In-Reply-To: <874kblsssy.wl-maz@kernel.org>
References: <20210816001217.3063400-1-oupton@google.com>
 <20210816001217.3063400-4-oupton@google.com>
 <874kblsssy.wl-maz@kernel.org>
Message-ID: <20210819102049.xbpwancdrram6ujj@gator.home>

On Thu, Aug 19, 2021 at 10:11:09AM +0100, Marc Zyngier wrote:
> On Mon, 16 Aug 2021 01:12:13 +0100,
> Oliver Upton <oupton at google.com> wrote:
> > 
> > Allow userspace to access the guest's virtual counter-timer offset
> > through the ONE_REG interface. The value read or written is defined to
> > be an offset from the guest's physical counter-timer. Add some
> > documentation to clarify how a VMM should use this and the existing
> > CNTVCT_EL0.
> > 
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > Reviewed-by: Andrew Jones <drjones at redhat.com>
> > ---
> >  Documentation/virt/kvm/api.rst    | 10 ++++++++++
> >  arch/arm64/include/uapi/asm/kvm.h |  1 +
> >  arch/arm64/kvm/arch_timer.c       | 23 +++++++++++++++++++++++
> >  arch/arm64/kvm/guest.c            |  6 +++++-
> >  include/kvm/arm_arch_timer.h      |  1 +
> >  5 files changed, 40 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> > index dae68e68ca23..adb04046a752 100644
> > --- a/Documentation/virt/kvm/api.rst
> > +++ b/Documentation/virt/kvm/api.rst
> > @@ -2463,6 +2463,16 @@ arm64 system registers have the following id bit patterns::
> >       derived from the register encoding for CNTV_CVAL_EL0.  As this is
> >       API, it must remain this way.
> >  
> > +.. warning::
> > +
> > +     The value of KVM_REG_ARM_TIMER_OFFSET is defined as an offset from
> > +     the guest's view of the physical counter-timer.
> > +
> > +     Userspace should use either KVM_REG_ARM_TIMER_OFFSET or
> > +     KVM_REG_ARM_TIMER_CNT to pause and resume a guest's virtual
> > +     counter-timer. Mixed use of these registers could result in an
> > +     unpredictable guest counter value.
> > +
> >  arm64 firmware pseudo-registers have the following bit pattern::
> >  
> >    0x6030 0000 0014 <regno:16>
> > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> > index b3edde68bc3e..949a31bc10f0 100644
> > --- a/arch/arm64/include/uapi/asm/kvm.h
> > +++ b/arch/arm64/include/uapi/asm/kvm.h
> > @@ -255,6 +255,7 @@ struct kvm_arm_copy_mte_tags {
> >  #define KVM_REG_ARM_TIMER_CTL		ARM64_SYS_REG(3, 3, 14, 3, 1)
> >  #define KVM_REG_ARM_TIMER_CVAL		ARM64_SYS_REG(3, 3, 14, 0, 2)
> >  #define KVM_REG_ARM_TIMER_CNT		ARM64_SYS_REG(3, 3, 14, 3, 2)
> > +#define KVM_REG_ARM_TIMER_OFFSET	ARM64_SYS_REG(3, 4, 14, 0, 3)
> >
> 
> Andrew, does this warrant an update to the selftest that checks for
> sysreg visibility?

Yup, until we do, the test will emit a warning with a suggestion to add
the new register to the list. It won't be a test FAIL, because adding new
registers doesn't break migration from older kernels, but we might as well
update the list sooner than later.

> 
> I am also wondering how a VMM such as QEMU is going to deal with the
> above restriction, given the way it blindly saves/restores all the
> registers that KVM exposes, hence hitting that mixed-use that the
> documentation warns about...

You're right and I think it's a problem. While we can special case
registers in QEMU using a cpreg "level" so they won't get saved/restored
all the time, it doesn't help here since we won't be special casing
KVM_REG_ARM_TIMER_OFFSET in older QEMU. We need a way for the VMM to opt
in to using KVM_REG_ARM_TIMER_OFFSET, such as with a CAP we can enable.

Thanks,
drew



From maz at kernel.org  Thu Aug 19 03:28:16 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Aug 2021 11:28:16 +0100
Subject: [PATCH v3 0/3] KVM: arm64: Use generic guest entry infrastructure
In-Reply-To: <20210802192809.1851010-1-oupton@google.com>
References: <20210802192809.1851010-1-oupton@google.com>
Message-ID: <162936887458.598180.10185839299725357336.b4-ty@kernel.org>

On Mon, 2 Aug 2021 19:28:06 +0000, Oliver Upton wrote:
> The arm64 kernel doesn't yet support the full generic entry
> infrastructure. That being said, KVM/arm64 doesn't properly handle
> TIF_NOTIFY_RESUME and could pick this up by switching to the generic
> guest entry infrasturture.
> 
> Patch 1 adds a missing vCPU stat to ARM64 to record the number of signal
> exits to userspace.
> 
> [...]

Applied to next, thanks!

[1/3] KVM: arm64: Record number of signal exits as a vCPU stat
      commit: fe5161d2c39b8c2801f0e786631460c6e8a1cae4
[2/3] entry: KVM: Allow use of generic KVM entry w/o full generic support
      commit: e1c6b9e1669e44fb7f9688e34e460b759e3b9187
[3/3] KVM: arm64: Use generic KVM xfer to guest work function
      commit: 6caa5812e2d126a0aa8a17816c1ba6f0a0c2b309

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From bot at kernelci.org  Thu Aug 19 03:49:16 2021
From: bot at kernelci.org (kernelci.org bot)
Date: Thu, 19 Aug 2021 03:49:16 -0700 (PDT)
Subject: arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 2 errors,
 1 warning (v5.14-rc6-3-g4a8d882022c7)
Message-ID: <611e372c.1c69fb81.dbc2c.b388@mx.google.com>

arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 2 errors, 1 warning (v5.14-rc6-3-g4a8d882022c7)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v5.14-rc6-3-g4a8d882022c7/

Tree: arm64
Branch: for-kernelci
Git Describe: v5.14-rc6-3-g4a8d882022c7
Git Commit: 4a8d882022c79ae4d10c30f58d17cc6cf57c3079
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Build Failure Detected:

arm64:
    allmodconfig: (gcc-8) FAIL

Errors and Warnings Detected:

arm64:
    allmodconfig (gcc-8): 2 errors, 1 warning

Errors summary:

    1    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1864? declared with attribute error: FIELD_PREP: value too large for the field
    1    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1857? declared with attribute error: FIELD_PREP: value too large for the field

Warnings summary:

    1    kernel/trace/trace_osnoise.c:1461:8: warning: ?main? is usually a function [-Wmain]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
allmodconfig (arm64, gcc-8) ? FAIL, 2 errors, 1 warning, 0 section mismatches

Errors:
    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1857? declared with attribute error: FIELD_PREP: value too large for the field
    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1864? declared with attribute error: FIELD_PREP: value too large for the field

Warnings:
    kernel/trace/trace_osnoise.c:1461:8: warning: ?main? is usually a function [-Wmain]

--------------------------------------------------------------------------------
defconfig (arm64, gcc-8) ? PASS, 0 errors, 0 warnings, 0 section mismatches

---
For more info write to <info at kernelci.org>


From Hari.PrasathGE at microchip.com  Thu Aug 19 03:56:21 2021
From: Hari.PrasathGE at microchip.com (Hari.PrasathGE at microchip.com)
Date: Thu, 19 Aug 2021 10:56:21 +0000
Subject: [PATCH 2/2] ARM: at91: dts: at91-sama5d2_xplained: Add comments
 for sama5d29
In-Reply-To: <YRV13nfgpEEuOOxB@piout.net>
References: <20210812140758.28273-1-Hari.PrasathGE@microchip.com>
 <20210812140758.28273-2-Hari.PrasathGE@microchip.com>
 <YRV13nfgpEEuOOxB@piout.net>
Message-ID: <78b26b01-b66f-5779-9f67-fdd13e473dfc@microchip.com>

Hello,

On 13/08/21 12:56 am, Alexandre Belloni wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Hello,
> 
> On 12/08/2021 19:37:58+0530, Hari Prasath wrote:
>> Add comments for the end user for modifying the DTS file for
>> instantiating the sama5d29 SoC.
>>
>> Signed-off-by: Hari Prasath <Hari.PrasathGE at microchip.com>
>> ---
>>   arch/arm/boot/dts/at91-sama5d2_xplained.dts | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
>> index 627b7bf88d83..faa30063d9a9 100644
>> --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
>> +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
>> @@ -6,6 +6,11 @@
>>    *                2015 Nicolas Ferre <nicolas.ferre at atmel.com>
>>    */
>>   /dts-v1/;
>> +/*
>> + * Replace the line below with "sama5d29.dtsi" in order to instantiate the
>> + * sama5d29 SoC of the sama5d2 family.Otherwise, leave it unchanged when
>> + * using sama5d27 SoC for instance.
>> + */
> 
> I guess it would be better to have a at91-sama5d29_xplained.dts (and we
> should have had a at91-sama5d27_xplained.dts), else, you can't create an
> image that will support both variants.
> 
> 
The new SoC 'sama5d29' belongs to the same sama5d2 family. It is 
essentially a new chip revision of the existing sama5d27 with a new GMAC 
controller IP that addresses few silicon issues. There wouldn't be 
separate evaluation boards that shall be made but we will be using the 
existing sama5d2 XPlained boards itself but with the new SoC populated. 
Hence we have taken this approach of having a separate DTSI file and 
reuse the existing board specific DTS file.

We don't want to create single image that will support both variants. In 
fact, we don't want our customers to enable certain features that are 
broken at the silicon level in the existing revision of the SoC i.e 
sama5d27. Instead, they could do this change manually and use it in the 
new SoC i.e sama5d29.

Regards,
Hari

> --
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
> 

From hayashi.kunihiko at socionext.com  Thu Aug 19 03:56:06 2021
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Thu, 19 Aug 2021 19:56:06 +0900
Subject: [PATCH] PCI: uniphier: Take lock in INTX irq_{mask, unmask,
 ack} callbacks
Message-ID: <1629370566-29984-1-git-send-email-hayashi.kunihiko@socionext.com>

The same condition register PCI_RCV_INTX is used in irq_mask(),
irq_unmask() and irq_ack() callbacks. Accesses to register can occur at the
same time without lock.
This introduces a lock into the callbacks to prevent the issue.

Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
Suggested-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pci/controller/dwc/pcie-uniphier.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index ebe43e9..5075714 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -186,12 +186,17 @@ static void uniphier_pcie_irq_ack(struct irq_data *d)
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+	unsigned long flags;
 	u32 val;
 
+	raw_spin_lock_irqsave(&pp->lock, flags);
+
 	val = readl(priv->base + PCL_RCV_INTX);
 	val &= ~PCL_RCV_INTX_ALL_STATUS;
 	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
+
+	raw_spin_unlock_irqrestore(&pp->lock, flags);
 }
 
 static void uniphier_pcie_irq_mask(struct irq_data *d)
@@ -199,12 +204,17 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+	unsigned long flags;
 	u32 val;
 
+	raw_spin_lock_irqsave(&pp->lock, flags);
+
 	val = readl(priv->base + PCL_RCV_INTX);
 	val &= ~PCL_RCV_INTX_ALL_MASK;
 	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
+
+	raw_spin_unlock_irqrestore(&pp->lock, flags);
 }
 
 static void uniphier_pcie_irq_unmask(struct irq_data *d)
@@ -212,12 +222,17 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+	unsigned long flags;
 	u32 val;
 
+	raw_spin_lock_irqsave(&pp->lock, flags);
+
 	val = readl(priv->base + PCL_RCV_INTX);
 	val &= ~PCL_RCV_INTX_ALL_MASK;
 	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
+
+	raw_spin_unlock_irqrestore(&pp->lock, flags);
 }
 
 static struct irq_chip uniphier_pcie_irq_chip = {
-- 
2.7.4



From fancer.lancer at gmail.com  Thu Aug 19 04:03:20 2021
From: fancer.lancer at gmail.com (Serge Semin)
Date: Thu, 19 Aug 2021 14:03:20 +0300
Subject: [PATCH 29/29] arm64: dts: qcom: Harmonize DWC USB3 DT nodes name
In-Reply-To: <YRyCFx0ZOYTMhinf@builder.lan>
References: <d853df77-8d36-30b0-dd26-da1bfcb068e0@kernel.org>
 <20210721112531.xvu6ni5ksaehsrjh@mobilestation>
 <CALAqxLViEqSO17P3JGRGYJh-wDoHaJiQQV48zeoRgnar4Xd5Bg@mail.gmail.com>
 <20210722181221.xh3r5kyu7zlcojjx@mobilestation>
 <YPnEO6NVFZDS1s//@yoga>
 <CALAqxLUT0e+mHMVo685oVTxR8y76733cN0yciQ7ePS6GRE+_dg@mail.gmail.com>
 <20210722220918.l7j6zw3aaa27qato@mobilestation>
 <CALAqxLXrs0_Xs0JV5H-wS1q2CJ7XhW5Dj90eu=uazkRXXEMUxQ@mail.gmail.com>
 <20210815194617.sbrkutxzldqbxfat@mobilestation>
 <YRyCFx0ZOYTMhinf@builder.lan>
Message-ID: <20210819110320.ikri4yjkp3zfuvqx@mobilestation>

On Tue, Aug 17, 2021 at 10:44:23PM -0500, Bjorn Andersson wrote:
> On Sun 15 Aug 14:46 CDT 2021, Serge Semin wrote:
> 
> > Hello John
> > 
> > On Fri, Aug 13, 2021 at 06:06:24PM -0700, John Stultz wrote:
> > > On Thu, Jul 22, 2021 at 3:09 PM Serge Semin <fancer.lancer at gmail.com> wrote:
> > > > On Thu, Jul 22, 2021 at 01:09:05PM -0700, John Stultz wrote:
> > > > > On Thu, Jul 22, 2021 at 12:17 PM Bjorn Andersson
> > > > > <bjorn.andersson at linaro.org> wrote:
> > > > > > > On Jul 21, 2021, 1:45 PM +0200, Krzysztof Kozlowski wrote:
> > > > > > > > I had impression that kernel defines interfaces which should be used and
> > > > > > > > are stable (e.g. syscalls, sysfs and so on). This case is example of
> > > > > > > > user-space relying on something not being marked as part of ABI. Instead
> > > > > > > > they found something working for them and now it is being used in "we
> > > > > > > > cannot break existing systems". Basically, AOSP unilaterally created a
> > > > > > > > stable ABI and now kernel has to stick to it.
> > > > > > > >
> > > > > > > > Really, all normal systems depend on aliases or names and here we have
> > > > > > > > dependency on device address. I proposed way how AOSP should be fixed.
> > > > > > > > Anything happened? Nope.
> > > > > > >
> > > > > > > First time he sent a possible solution for the problem:
> > > > > > > https://lore.kernel.org/lkml/20201221210423.GA2504 at kozik-lap/
> > > > > > >
> > > > > > > To sum up you could have used one of the more portable approaches
> > > > > > > 1. add an udc alias to the controller and use it then to refer to the
> > > > > > > corresponding USB controller
> > > > > >
> > > > > > Is there such a thing as "UDC alias"? Or are you suggesting that we
> > > > > > should add such feature?
> > > > > >
> > > > > > I think it would be wonderful if we could identify the UDCs on our
> > > > > > boards as "USB1" and "USB2", or "the one and only USB-C connector". But
> > > > > > unless that will fall back to the existing naming it would break John's
> > > > > > _existing_ userspace.
> > > > >
> > > >
> > > > > Well, I'd not hold up the existing userspace I'm using as sacrosanct
> > > > > (AOSP devices still usually don't have to work cross-kernel versions -
> > > > > devboards being the main exception). I'm fine if we can rework
> > > > > userland as proposed, so that the issues can be avoided, but I
> > > > > honestly don't have enough context to really understand what that
> > > > > looks like (no idea what udc aliases are).
> > > > >
> > > > > And whatever we do, the main constraint is that userland has to be
> > > > > able to work with existing LTS kernels and newer kernels.
> > > >
> > > > As I said in my response to Bjorn even if it is added to the kernel it
> > > > won't get to the official LTSes as it would be a new kernel feature.
> > > > New features aren't normally backported to the older kernels.
> > > >
> > > > >
> > > > > > > 2. search through DT-nodes looking for a specific compatible/reg
> > > > > > > DT-properties.
> > > > > > >
> > > > > >
> > > > > > We could define that this is the way, but again we didn't yesterday so
> > > > > > your proposal is not backwards compatible.
> > > > >
> > > >
> > > > > It may be backwards compatible, but I'm still not clear exactly how it
> > > > > would work.
> > > > >
> > > > > I guess if we look through all
> > > > > sys/bus/platform/devices/*/of_node/compatbile strings for the desired
> > > > > "snps,dwc3", then find which of the directories have the desired
> > > > > address in the string? (The suggestion for looking at reg seems
> > > > > better, but I don't get a char value out of the dwc3 of_node/reg
> > > > > file).
> > > >
> > > > The algorithm is simple:
> > > > 1) You know what USB controllers you have on your platform. They are
> > > > supposed to be compatible with snps,dwc3 string and have some pre-defined
> > > > base address.
> > > > 2) Find all the files in the directory /sys/class/udc/.
> > > > 3) Walk through all the directories in /sys/bus/platform/devices/ with
> > > > names found in 2) and stop on the device with matching compatible/base
> > > > address defined in 1).
> > > >
> > > > In my case the strings could be retrieved like this:
> > > > USB_NAME_COMPAT=$(/sys/bus/platform/devices/1f100000.usb/of_node/compatible | tr '\0' '\t' | cut -f1)
> > > > USB_DEVICE_ADDR="$(head -c 4 /sys/bus/platform/devices/1f100000.usb/of_node/reg | hexdump -ve '/1 "%02x"' | sed -e 's/^0*//g')"
> > > 
> > > 
> > 
> > > Hey Serge,
> > >    I just wanted to follow up here.  Amit has reworked the db845c AOSP
> > > userland so that it no longer uses the fixed node name, but instead
> > > probes for it:
> > >   https://android-review.googlesource.com/c/device/linaro/dragonboard/+/1774872
> > > 
> > > Admittedly, it does take a short-cut.  As your algorithm above,
> > > digging up the devices and finding the sys/bus path to read the reg
> > > value and pipe through hexdump (which android doesn't have) seemed
> > > overly obtuse when the address is in the node name itself (while the
> > > only way to be sure, one normally doesn't use spectroscopy to
> > > determine the value of a coin when you can read what's printed on it
> > > :).  But, should the node naming be further changed at least the
> > > infrastructure we have can be reworked fairly easily to adapt now.
> > > 
> > > In any case, as we can handle the name change now, if you want to
> > > resubmit your patch, we would no longer object (but can't promise no
> > > one else might be bitten).  Sorry for the delay this caused, and we
> > > appreciate you working with us to find a solution.
> > 
> > Great! Thanks for sending the notification. I'll resend the patch with a
> > reference to your report and to the update made to AOSP, as soon as I
> > am done with my current task.
> > 
> 

> Amit's change makes future versions of AOSP able to cope with changes in
> the UDC name, unfortunately it doesn't change the fact that renaming the
> node breaks compatibility in non-Android user space (or any existing
> branches/tags of AOSP).

After looking over the whole discussion, as I see it there is no
compatibility breakage in this case. But there is an improper UDC
interface usage, which has been fixed by Amit and could be ported to
another AOSP branches/tags if needed. As [1] says user-space is
able to create a USB gadget only with controllers listed in the
directory /sys/class/udc/*. That ABI doesn't change. Note the ABI
doesn't say that if someone found a file there in some kernel
version it will be available there in the in a next version with the
same name. A developer just need to search for the UDC controllers ach
time when a UDC gadget needs to be created.

Anyway as I see it the UDC gadget creation ABI IS indeed abided by
most of the developers since we haven't heard much complains so far
except from John. In case of AOSP the problem has been fixed so we can
get back the modification and proceed with the rest of the patches
review.

[1] Documentation/usb/gadget_configfs.rst

-Sergey

> 
> Regards,
> Bjorn


From jens.wiklander at linaro.org  Thu Aug 19 04:06:51 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 19 Aug 2021 13:06:51 +0200
Subject: [PATCH v4 1/5] tee: add sec_world_id to struct tee_shm
In-Reply-To: <20210819110655.739318-1-jens.wiklander@linaro.org>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
Message-ID: <20210819110655.739318-2-jens.wiklander@linaro.org>

Adds sec_world_id to struct tee_shm which describes a shared memory
object. sec_world_id can be used by a driver to store an id assigned by
secure world.

Reviewed-by: Sumit Garg <sumit.garg at linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 include/linux/tee_drv.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index 54269e47ac9a..1a29f0e66e13 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -196,7 +196,11 @@ int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
  * @num_pages:	number of locked pages
  * @dmabuf:	dmabuf used to for exporting to user space
  * @flags:	defined by TEE_SHM_* in tee_drv.h
- * @id:		unique id of a shared memory object on this device
+ * @id:		unique id of a shared memory object on this device, shared
+ *		with user space
+ * @sec_world_id:
+ *		secure world assigned id of this shared memory object, not
+ *		used by all drivers
  *
  * This pool is only supposed to be accessed directly from the TEE
  * subsystem and from drivers that implements their own shm pool manager.
@@ -212,6 +216,7 @@ struct tee_shm {
 	struct dma_buf *dmabuf;
 	u32 flags;
 	int id;
+	u64 sec_world_id;
 };
 
 /**
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 19 04:06:50 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 19 Aug 2021 13:06:50 +0200
Subject: [PATCH v4 0/5] Add FF-A support in OP-TEE driver
Message-ID: <20210819110655.739318-1-jens.wiklander@linaro.org>

Hi all,

This adds supports for the OP-TEE driver to communicate with secure world
using FF-A [1] as transport.

There is one change to the TEE subsystem with "tee: add sec_world_id to
struct tee_shm" to add support for holding globally unique handle assigned
by the FF-A. This is a field that I believe could useful for the AMDTEE
driver too.

For communication the OP-TEE message protocol is still used, but with a new
type of memory reference, struct optee_msg_param_fmem, to carry the
information needed by FF-A. The OP-TEE driver is refactored internally with
to sets of callbacks, one for the old SMC based communication and another
set with FF-A as transport. The functions relating to the SMC based ABI
are moved to smc_abi.c while the FF-A based ABI is added in a ffa_abi.c.

There is also a difference in how the drivers are instantiated. With the
SMC based transport we have a platform driver, module_platform_driver(),
today which we're keeping as is for this configuration. In a FF-A system we
have a FF-A driver, module_ffa_driver(), instead.

The OP-TEE driver can be compiled for both targets at the same time and
it's up to runtime configuration (device tree or ACPI) to decide how it's
initialized. Note that it's only the old SMC based driver instance that
need device tree or ACPI to initialize. The FF-A based driver relies on the
FF-A bus instead.

This can be tested QEMU
The repo for SPMC at S-EL1 retrieved by
repo init -u https://github.com/jenswi-linaro/manifest.git -m
qemu_v8.xml -b ffav4_spmc
repo sync
# Then checkout the branch optee_ffa_v4 from
# git://git.linaro.org/people/jens.wiklander/linux-tee.git
# in the linux directory

To build do:
cd build
make toolchains
make all

To boot:
make run-only

Test with xtest, perhaps only with the command "xtest 1004" in case you're
not interested in too many tests.

Thanks,
Jens

[1] https://developer.arm.com/documentation/den0077/latest

v3->v4:
- Made a bit more RPC code common between the SMC and FF-A ABIs as
  requested by Sumit.
- Replaced module_platform_driver() with module_init()/module_exit() as
  described in the commit "optee: isolate smc abi".
- Applied Sumit's R-B for the commits "tee: add sec_world_id to struct
  tee_shm", "optee: simplify optee_release()", and "optee: refactor driver
  with internal callbacks"

v2->v3:
- Rebased on 5.14-rc2 which now have the FF-A patches merged
- Fixed a couple bugs in optee_shm_register() and optee_shm_unregister()
  which where introduced in "optee: refactor driver with internal callbacks"
  in previous the version.
- Separated SMC ABI specifics into smc_abi.c to keep it separated from
  the FF-A ABI functions as requested by Sumit.
- Added the FF-A specifics in ffa_abi.c
- Provided an implementation for optee_ffa_remove()

v1->v2:
- Rebased to the FF-A v7 patch
- Fixed a couple of reports from kernel test robot <lkp at intel.com>

Jens Wiklander (5):
  tee: add sec_world_id to struct tee_shm
  optee: simplify optee_release()
  optee: refactor driver with internal callbacks
  optee: isolate smc abi
  optee: add FF-A support

 drivers/tee/optee/Makefile        |    7 +-
 drivers/tee/optee/call.c          |  415 ++-------
 drivers/tee/optee/core.c          |  685 ++-------------
 drivers/tee/optee/ffa_abi.c       |  907 ++++++++++++++++++++
 drivers/tee/optee/optee_ffa.h     |  153 ++++
 drivers/tee/optee/optee_msg.h     |   27 +-
 drivers/tee/optee/optee_private.h |  162 +++-
 drivers/tee/optee/rpc.c           |  236 +-----
 drivers/tee/optee/shm_pool.c      |   89 --
 drivers/tee/optee/shm_pool.h      |   14 -
 drivers/tee/optee/smc_abi.c       | 1299 +++++++++++++++++++++++++++++
 include/linux/tee_drv.h           |    7 +-
 12 files changed, 2665 insertions(+), 1336 deletions(-)
 create mode 100644 drivers/tee/optee/ffa_abi.c
 create mode 100644 drivers/tee/optee/optee_ffa.h
 delete mode 100644 drivers/tee/optee/shm_pool.c
 delete mode 100644 drivers/tee/optee/shm_pool.h
 create mode 100644 drivers/tee/optee/smc_abi.c

-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 19 04:06:52 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 19 Aug 2021 13:06:52 +0200
Subject: [PATCH v4 2/5] optee: simplify optee_release()
In-Reply-To: <20210819110655.739318-1-jens.wiklander@linaro.org>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
Message-ID: <20210819110655.739318-3-jens.wiklander@linaro.org>

Simplifies optee_release() with a new helper function,
optee_close_session_helper() which has been factored out from
optee_close_session().

A separate optee_release_supp() is added for the supplicant device.

Reviewed-by: Sumit Garg <sumit.garg at linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/call.c          | 31 ++++++++++-------
 drivers/tee/optee/core.c          | 55 +++++++++++--------------------
 drivers/tee/optee/optee_private.h |  1 +
 3 files changed, 39 insertions(+), 48 deletions(-)

diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 6e6eb836e9b6..9d8f5a95e42f 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -288,12 +288,28 @@ int optee_open_session(struct tee_context *ctx,
 	return rc;
 }
 
-int optee_close_session(struct tee_context *ctx, u32 session)
+int optee_close_session_helper(struct tee_context *ctx, u32 session)
 {
-	struct optee_context_data *ctxdata = ctx->data;
 	struct tee_shm *shm;
 	struct optee_msg_arg *msg_arg;
 	phys_addr_t msg_parg;
+
+	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
+	msg_arg->session = session;
+	optee_do_call_with_arg(ctx, msg_parg);
+
+	tee_shm_free(shm);
+
+	return 0;
+}
+
+int optee_close_session(struct tee_context *ctx, u32 session)
+{
+	struct optee_context_data *ctxdata = ctx->data;
 	struct optee_session *sess;
 
 	/* Check that the session is valid and remove it from the list */
@@ -306,16 +322,7 @@ int optee_close_session(struct tee_context *ctx, u32 session)
 		return -EINVAL;
 	kfree(sess);
 
-	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
-	if (IS_ERR(shm))
-		return PTR_ERR(shm);
-
-	msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
-	msg_arg->session = session;
-	optee_do_call_with_arg(ctx, msg_parg);
-
-	tee_shm_free(shm);
-	return 0;
+	return optee_close_session_helper(ctx, session);
 }
 
 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index ddb8f9ecf307..949223b214c3 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -263,59 +263,42 @@ static int optee_open(struct tee_context *ctx)
 	return 0;
 }
 
-static void optee_release(struct tee_context *ctx)
+static void optee_release_helper(struct tee_context *ctx,
+				 int (*close_session)(struct tee_context *ctx,
+						      u32 session))
 {
 	struct optee_context_data *ctxdata = ctx->data;
-	struct tee_device *teedev = ctx->teedev;
-	struct optee *optee = tee_get_drvdata(teedev);
-	struct tee_shm *shm;
-	struct optee_msg_arg *arg = NULL;
-	phys_addr_t parg;
 	struct optee_session *sess;
 	struct optee_session *sess_tmp;
 
 	if (!ctxdata)
 		return;
 
-	shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg), TEE_SHM_MAPPED);
-	if (!IS_ERR(shm)) {
-		arg = tee_shm_get_va(shm, 0);
-		/*
-		 * If va2pa fails for some reason, we can't call into
-		 * secure world, only free the memory. Secure OS will leak
-		 * sessions and finally refuse more sessions, but we will
-		 * at least let normal world reclaim its memory.
-		 */
-		if (!IS_ERR(arg))
-			if (tee_shm_va2pa(shm, arg, &parg))
-				arg = NULL; /* prevent usage of parg below */
-	}
-
 	list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list,
 				 list_node) {
 		list_del(&sess->list_node);
-		if (!IS_ERR_OR_NULL(arg)) {
-			memset(arg, 0, sizeof(*arg));
-			arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
-			arg->session = sess->session_id;
-			optee_do_call_with_arg(ctx, parg);
-		}
+		close_session(ctx, sess->session_id);
 		kfree(sess);
 	}
 	kfree(ctxdata);
+	ctx->data = NULL;
+}
 
-	if (!IS_ERR(shm))
-		tee_shm_free(shm);
+static void optee_release(struct tee_context *ctx)
+{
+	optee_release_helper(ctx, optee_close_session_helper);
+}
 
-	ctx->data = NULL;
+static void optee_release_supp(struct tee_context *ctx)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 
-	if (teedev == optee->supp_teedev) {
-		if (optee->scan_bus_wq) {
-			destroy_workqueue(optee->scan_bus_wq);
-			optee->scan_bus_wq = NULL;
-		}
-		optee_supp_release(&optee->supp);
+	optee_release_helper(ctx, optee_close_session_helper);
+	if (optee->scan_bus_wq) {
+		destroy_workqueue(optee->scan_bus_wq);
+		optee->scan_bus_wq = NULL;
 	}
+	optee_supp_release(&optee->supp);
 }
 
 static const struct tee_driver_ops optee_ops = {
@@ -339,7 +322,7 @@ static const struct tee_desc optee_desc = {
 static const struct tee_driver_ops optee_supp_ops = {
 	.get_version = optee_get_version,
 	.open = optee_open,
-	.release = optee_release,
+	.release = optee_release_supp,
 	.supp_recv = optee_supp_recv,
 	.supp_send = optee_supp_send,
 	.shm_register = optee_shm_register_supp,
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index e25b216a14ef..2b63b796645e 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -152,6 +152,7 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
 int optee_open_session(struct tee_context *ctx,
 		       struct tee_ioctl_open_session_arg *arg,
 		       struct tee_param *param);
+int optee_close_session_helper(struct tee_context *ctx, u32 session);
 int optee_close_session(struct tee_context *ctx, u32 session);
 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 		      struct tee_param *param);
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 19 04:06:53 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 19 Aug 2021 13:06:53 +0200
Subject: [PATCH v4 3/5] optee: refactor driver with internal callbacks
In-Reply-To: <20210819110655.739318-1-jens.wiklander@linaro.org>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
Message-ID: <20210819110655.739318-4-jens.wiklander@linaro.org>

The OP-TEE driver is refactored with three internal callbacks replacing
direct calls to optee_from_msg_param(), optee_to_msg_param() and
optee_do_call_with_arg().

These functions a central to communicating with OP-TEE in secure world
by using the SMC Calling Convention directly.

This refactoring makes room for using other primitives to communicate
with OP-TEE in secure world while being able to reuse as much as
possible from the present driver.

Reviewed-by: Sumit Garg <sumit.garg at linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/call.c          |  86 +++++++++--------
 drivers/tee/optee/core.c          | 148 ++++++++++++++++++++----------
 drivers/tee/optee/optee_private.h |  35 +++++--
 drivers/tee/optee/rpc.c           |  19 ++--
 4 files changed, 182 insertions(+), 106 deletions(-)

diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 9d8f5a95e42f..00ecd794e59a 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 #include <linux/arm-smccc.h>
 #include <linux/device.h>
@@ -118,20 +118,25 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
 /**
  * optee_do_call_with_arg() - Do an SMC to OP-TEE in secure world
  * @ctx:	calling context
- * @parg:	physical address of message to pass to secure world
+ * @arg:	shared memory holding the message to pass to secure world
  *
  * Does and SMC to OP-TEE in secure world and handles eventual resulting
  * Remote Procedure Calls (RPC) from OP-TEE.
  *
  * Returns return code from secure world, 0 is OK
  */
-u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
+int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg)
 {
 	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_call_waiter w;
 	struct optee_rpc_param param = { };
 	struct optee_call_ctx call_ctx = { };
-	u32 ret;
+	phys_addr_t parg;
+	int rc;
+
+	rc = tee_shm_get_pa(arg, 0, &parg);
+	if (rc)
+		return rc;
 
 	param.a0 = OPTEE_SMC_CALL_WITH_ARG;
 	reg_pair_from_64(&param.a1, &param.a2, parg);
@@ -160,7 +165,7 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
 			param.a3 = res.a3;
 			optee_handle_rpc(ctx, &param, &call_ctx);
 		} else {
-			ret = res.a0;
+			rc = res.a0;
 			break;
 		}
 	}
@@ -172,14 +177,12 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
 	 */
 	optee_cq_wait_final(&optee->call_queue, &w);
 
-	return ret;
+	return rc;
 }
 
 static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
-				   struct optee_msg_arg **msg_arg,
-				   phys_addr_t *msg_parg)
+				   struct optee_msg_arg **msg_arg)
 {
-	int rc;
 	struct tee_shm *shm;
 	struct optee_msg_arg *ma;
 
@@ -190,22 +193,13 @@ static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
 
 	ma = tee_shm_get_va(shm, 0);
 	if (IS_ERR(ma)) {
-		rc = PTR_ERR(ma);
-		goto out;
+		tee_shm_free(shm);
+		return (void *)ma;
 	}
 
-	rc = tee_shm_get_pa(shm, 0, msg_parg);
-	if (rc)
-		goto out;
-
 	memset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params));
 	ma->num_params = num_params;
 	*msg_arg = ma;
-out:
-	if (rc) {
-		tee_shm_free(shm);
-		return ERR_PTR(rc);
-	}
 
 	return shm;
 }
@@ -214,16 +208,16 @@ int optee_open_session(struct tee_context *ctx,
 		       struct tee_ioctl_open_session_arg *arg,
 		       struct tee_param *param)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_context_data *ctxdata = ctx->data;
 	int rc;
 	struct tee_shm *shm;
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
 	struct optee_session *sess = NULL;
 	uuid_t client_uuid;
 
 	/* +2 for the meta parameters added below */
-	shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg, &msg_parg);
+	shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
@@ -247,7 +241,8 @@ int optee_open_session(struct tee_context *ctx,
 		goto out;
 	export_uuid(msg_arg->params[1].u.octets, &client_uuid);
 
-	rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param);
+	rc = optee->ops->to_msg_param(optee, msg_arg->params + 2,
+				      arg->num_params, param);
 	if (rc)
 		goto out;
 
@@ -257,7 +252,7 @@ int optee_open_session(struct tee_context *ctx,
 		goto out;
 	}
 
-	if (optee_do_call_with_arg(ctx, msg_parg)) {
+	if (optee->ops->do_call_with_arg(ctx, shm)) {
 		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
 		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
 	}
@@ -272,7 +267,8 @@ int optee_open_session(struct tee_context *ctx,
 		kfree(sess);
 	}
 
-	if (optee_from_msg_param(param, arg->num_params, msg_arg->params + 2)) {
+	if (optee->ops->from_msg_param(optee, param, arg->num_params,
+				       msg_arg->params + 2)) {
 		arg->ret = TEEC_ERROR_COMMUNICATION;
 		arg->ret_origin = TEEC_ORIGIN_COMMS;
 		/* Close session again to avoid leakage */
@@ -291,16 +287,16 @@ int optee_open_session(struct tee_context *ctx,
 int optee_close_session_helper(struct tee_context *ctx, u32 session)
 {
 	struct tee_shm *shm;
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
 
-	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	shm = get_msg_arg(ctx, 0, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
 	msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
 	msg_arg->session = session;
-	optee_do_call_with_arg(ctx, msg_parg);
+	optee->ops->do_call_with_arg(ctx, shm);
 
 	tee_shm_free(shm);
 
@@ -328,10 +324,10 @@ int optee_close_session(struct tee_context *ctx, u32 session)
 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 		      struct tee_param *param)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_context_data *ctxdata = ctx->data;
 	struct tee_shm *shm;
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
 	struct optee_session *sess;
 	int rc;
 
@@ -342,7 +338,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 	if (!sess)
 		return -EINVAL;
 
-	shm = get_msg_arg(ctx, arg->num_params, &msg_arg, &msg_parg);
+	shm = get_msg_arg(ctx, arg->num_params, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 	msg_arg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
@@ -350,16 +346,18 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 	msg_arg->session = arg->session;
 	msg_arg->cancel_id = arg->cancel_id;
 
-	rc = optee_to_msg_param(msg_arg->params, arg->num_params, param);
+	rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params,
+				      param);
 	if (rc)
 		goto out;
 
-	if (optee_do_call_with_arg(ctx, msg_parg)) {
+	if (optee->ops->do_call_with_arg(ctx, shm)) {
 		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
 		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
 	}
 
-	if (optee_from_msg_param(param, arg->num_params, msg_arg->params)) {
+	if (optee->ops->from_msg_param(optee, param, arg->num_params,
+				       msg_arg->params)) {
 		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
 		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
 	}
@@ -373,10 +371,10 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 
 int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_context_data *ctxdata = ctx->data;
 	struct tee_shm *shm;
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
 	struct optee_session *sess;
 
 	/* Check that the session is valid */
@@ -386,14 +384,14 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 	if (!sess)
 		return -EINVAL;
 
-	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	shm = get_msg_arg(ctx, 0, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
 	msg_arg->cmd = OPTEE_MSG_CMD_CANCEL;
 	msg_arg->session = session;
 	msg_arg->cancel_id = cancel_id;
-	optee_do_call_with_arg(ctx, msg_parg);
+	optee->ops->do_call_with_arg(ctx, shm);
 
 	tee_shm_free(shm);
 	return 0;
@@ -592,10 +590,10 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 		       struct page **pages, size_t num_pages,
 		       unsigned long start)
 {
-	struct tee_shm *shm_arg = NULL;
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm_arg;
 	u64 *pages_list;
-	phys_addr_t msg_parg;
 	int rc;
 
 	if (!num_pages)
@@ -609,7 +607,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 	if (!pages_list)
 		return -ENOMEM;
 
-	shm_arg = get_msg_arg(ctx, 1, &msg_arg, &msg_parg);
+	shm_arg = get_msg_arg(ctx, 1, &msg_arg);
 	if (IS_ERR(shm_arg)) {
 		rc = PTR_ERR(shm_arg);
 		goto out;
@@ -630,7 +628,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 	msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
 	  (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
 
-	if (optee_do_call_with_arg(ctx, msg_parg) ||
+	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
 	    msg_arg->ret != TEEC_SUCCESS)
 		rc = -EINVAL;
 
@@ -642,12 +640,12 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 
 int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
 {
-	struct tee_shm *shm_arg;
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
+	struct tee_shm *shm_arg;
 	int rc = 0;
 
-	shm_arg = get_msg_arg(ctx, 1, &msg_arg, &msg_parg);
+	shm_arg = get_msg_arg(ctx, 1, &msg_arg);
 	if (IS_ERR(shm_arg))
 		return PTR_ERR(shm_arg);
 
@@ -656,7 +654,7 @@ int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
 	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
 	msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;
 
-	if (optee_do_call_with_arg(ctx, msg_parg) ||
+	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
 	    msg_arg->ret != TEEC_SUCCESS)
 		rc = -EINVAL;
 	tee_shm_free(shm_arg);
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 949223b214c3..f689f171a794 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -26,21 +26,87 @@
 
 #define OPTEE_SHM_NUM_PRIV_PAGES	CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
 
+static void from_msg_param_value(struct tee_param *p, u32 attr,
+				 const struct optee_msg_param *mp)
+{
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+	p->u.value.a = mp->u.value.a;
+	p->u.value.b = mp->u.value.b;
+	p->u.value.c = mp->u.value.c;
+}
+
+static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
+				  const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm;
+	phys_addr_t pa;
+	int rc;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
+	p->u.memref.size = mp->u.tmem.size;
+	shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
+	if (!shm) {
+		p->u.memref.shm_offs = 0;
+		p->u.memref.shm = NULL;
+		return 0;
+	}
+
+	rc = tee_shm_get_pa(shm, 0, &pa);
+	if (rc)
+		return rc;
+
+	p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
+	p->u.memref.shm = shm;
+
+	/* Check that the memref is covered by the shm object */
+	if (p->u.memref.size) {
+		size_t o = p->u.memref.shm_offs +
+			   p->u.memref.size - 1;
+
+		rc = tee_shm_get_pa(shm, o, NULL);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
+
+static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
+				   const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
+	p->u.memref.size = mp->u.rmem.size;
+	shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
+
+	if (shm) {
+		p->u.memref.shm_offs = mp->u.rmem.offs;
+		p->u.memref.shm = shm;
+	} else {
+		p->u.memref.shm_offs = 0;
+		p->u.memref.shm = NULL;
+	}
+}
+
 /**
  * optee_from_msg_param() - convert from OPTEE_MSG parameters to
  *			    struct tee_param
+ * @optee:	main service struct
  * @params:	subsystem internal parameter representation
  * @num_params:	number of elements in the parameter arrays
  * @msg_params:	OPTEE_MSG parameters
  * Returns 0 on success or <0 on failure
  */
-int optee_from_msg_param(struct tee_param *params, size_t num_params,
-			 const struct optee_msg_param *msg_params)
+static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
+				size_t num_params,
+				const struct optee_msg_param *msg_params)
 {
 	int rc;
 	size_t n;
-	struct tee_shm *shm;
-	phys_addr_t pa;
 
 	for (n = 0; n < num_params; n++) {
 		struct tee_param *p = params + n;
@@ -55,48 +121,19 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params,
 		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
-			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
-				  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
-			p->u.value.a = mp->u.value.a;
-			p->u.value.b = mp->u.value.b;
-			p->u.value.c = mp->u.value.c;
+			from_msg_param_value(p, attr, mp);
 			break;
 		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
-			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
-				  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
-			p->u.memref.size = mp->u.tmem.size;
-			shm = (struct tee_shm *)(unsigned long)
-				mp->u.tmem.shm_ref;
-			if (!shm) {
-				p->u.memref.shm_offs = 0;
-				p->u.memref.shm = NULL;
-				break;
-			}
-			rc = tee_shm_get_pa(shm, 0, &pa);
+			rc = from_msg_param_tmp_mem(p, attr, mp);
 			if (rc)
 				return rc;
-			p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
-			p->u.memref.shm = shm;
 			break;
 		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
-			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
-				  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
-			p->u.memref.size = mp->u.rmem.size;
-			shm = (struct tee_shm *)(unsigned long)
-				mp->u.rmem.shm_ref;
-
-			if (!shm) {
-				p->u.memref.shm_offs = 0;
-				p->u.memref.shm = NULL;
-				break;
-			}
-			p->u.memref.shm_offs = mp->u.rmem.offs;
-			p->u.memref.shm = shm;
-
+			from_msg_param_reg_mem(p, attr, mp);
 			break;
 
 		default:
@@ -106,6 +143,16 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params,
 	return 0;
 }
 
+static void to_msg_param_value(struct optee_msg_param *mp,
+			       const struct tee_param *p)
+{
+	mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+	mp->u.value.a = p->u.value.a;
+	mp->u.value.b = p->u.value.b;
+	mp->u.value.c = p->u.value.c;
+}
+
 static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
 				const struct tee_param *p)
 {
@@ -148,13 +195,15 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp,
 
 /**
  * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
+ * @optee:	main service struct
  * @msg_params:	OPTEE_MSG parameters
  * @num_params:	number of elements in the parameter arrays
  * @params:	subsystem itnernal parameter representation
  * Returns 0 on success or <0 on failure
  */
-int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
-		       const struct tee_param *params)
+static int optee_to_msg_param(struct optee *optee,
+			      struct optee_msg_param *msg_params,
+			      size_t num_params, const struct tee_param *params)
 {
 	int rc;
 	size_t n;
@@ -171,11 +220,7 @@ int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
-			mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
-				   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-			mp->u.value.a = p->u.value.a;
-			mp->u.value.b = p->u.value.b;
-			mp->u.value.c = p->u.value.c;
+			to_msg_param_value(mp, p);
 			break;
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
@@ -301,7 +346,7 @@ static void optee_release_supp(struct tee_context *ctx)
 	optee_supp_release(&optee->supp);
 }
 
-static const struct tee_driver_ops optee_ops = {
+static const struct tee_driver_ops optee_clnt_ops = {
 	.get_version = optee_get_version,
 	.open = optee_open,
 	.release = optee_release,
@@ -313,9 +358,9 @@ static const struct tee_driver_ops optee_ops = {
 	.shm_unregister = optee_shm_unregister,
 };
 
-static const struct tee_desc optee_desc = {
+static const struct tee_desc optee_clnt_desc = {
 	.name = DRIVER_NAME "-clnt",
-	.ops = &optee_ops,
+	.ops = &optee_clnt_ops,
 	.owner = THIS_MODULE,
 };
 
@@ -336,6 +381,12 @@ static const struct tee_desc optee_supp_desc = {
 	.flags = TEE_DESC_PRIVILEGED,
 };
 
+static const struct optee_ops optee_ops = {
+	.do_call_with_arg = optee_do_call_with_arg,
+	.to_msg_param = optee_to_msg_param,
+	.from_msg_param = optee_from_msg_param,
+};
+
 static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
 {
 	struct arm_smccc_res res;
@@ -637,10 +688,11 @@ static int optee_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	optee->ops = &optee_ops;
 	optee->invoke_fn = invoke_fn;
 	optee->sec_caps = sec_caps;
 
-	teedev = tee_device_alloc(&optee_desc, NULL, pool, optee);
+	teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
 	if (IS_ERR(teedev)) {
 		rc = PTR_ERR(teedev);
 		goto err;
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 2b63b796645e..c5741e96e967 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 
 #ifndef OPTEE_PRIVATE_H
@@ -66,9 +66,34 @@ struct optee_supp {
 	struct completion reqs_c;
 };
 
+struct optee;
+
+/**
+ * struct optee_ops - OP-TEE driver internal operations
+ * @do_call_with_arg:	enters OP-TEE in secure world
+ * @to_msg_param:	converts from struct tee_param to OPTEE_MSG parameters
+ * @from_msg_param:	converts from OPTEE_MSG parameters to struct tee_param
+ *
+ * These OPs are only supposed to be used internally in the OP-TEE driver
+ * as a way of abstracting the different methogs of entering OP-TEE in
+ * secure world.
+ */
+struct optee_ops {
+	int (*do_call_with_arg)(struct tee_context *ctx,
+				struct tee_shm *shm_arg);
+	int (*to_msg_param)(struct optee *optee,
+			    struct optee_msg_param *msg_params,
+			    size_t num_params, const struct tee_param *params);
+	int (*from_msg_param)(struct optee *optee, struct tee_param *params,
+			      size_t num_params,
+			      const struct optee_msg_param *msg_params);
+};
+
 /**
  * struct optee - main service struct
  * @supp_teedev:	supplicant device
+ * @ops:		internal callbacks for different ways to reach secure
+ *			world
  * @teedev:		client device
  * @invoke_fn:		function to issue smc or hvc
  * @call_queue:		queue of threads waiting to call @invoke_fn
@@ -86,6 +111,7 @@ struct optee_supp {
 struct optee {
 	struct tee_device *supp_teedev;
 	struct tee_device *teedev;
+	const struct optee_ops *ops;
 	optee_invoke_fn *invoke_fn;
 	struct optee_call_queue call_queue;
 	struct optee_wait_queue wait_queue;
@@ -148,7 +174,7 @@ int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
 int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
 		    struct tee_param *param);
 
-u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
+int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg);
 int optee_open_session(struct tee_context *ctx,
 		       struct tee_ioctl_open_session_arg *arg,
 		       struct tee_param *param);
@@ -171,11 +197,6 @@ int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
 			    unsigned long start);
 int optee_shm_unregister_supp(struct tee_context *ctx, struct tee_shm *shm);
 
-int optee_from_msg_param(struct tee_param *params, size_t num_params,
-			 const struct optee_msg_param *msg_params);
-int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
-		       const struct tee_param *params);
-
 u64 *optee_allocate_pages_list(size_t num_entries);
 void optee_free_pages_list(void *array, size_t num_entries);
 void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index 1849180b0278..39562fb6841e 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2016, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -55,6 +55,7 @@ static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 					     struct optee_msg_arg *arg)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct tee_param *params;
 	struct i2c_adapter *adapter;
 	struct i2c_msg msg = { };
@@ -79,7 +80,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 		return;
 	}
 
-	if (optee_from_msg_param(params, arg->num_params, arg->params))
+	if (optee->ops->from_msg_param(optee, params, arg->num_params,
+				       arg->params))
 		goto bad;
 
 	for (i = 0; i < arg->num_params; i++) {
@@ -122,7 +124,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 		arg->ret = TEEC_ERROR_COMMUNICATION;
 	} else {
 		params[3].u.value.a = msg.len;
-		if (optee_to_msg_param(arg->params, arg->num_params, params))
+		if (optee->ops->to_msg_param(optee, arg->params,
+					     arg->num_params, params))
 			arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		else
 			arg->ret = TEEC_SUCCESS;
@@ -234,7 +237,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
 	arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 }
 
-static void handle_rpc_supp_cmd(struct tee_context *ctx,
+static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
 				struct optee_msg_arg *arg)
 {
 	struct tee_param *params;
@@ -248,14 +251,16 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx,
 		return;
 	}
 
-	if (optee_from_msg_param(params, arg->num_params, arg->params)) {
+	if (optee->ops->from_msg_param(optee, params, arg->num_params,
+				       arg->params)) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		goto out;
 	}
 
 	arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
 
-	if (optee_to_msg_param(arg->params, arg->num_params, params))
+	if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
+				     params))
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 out:
 	kfree(params);
@@ -480,7 +485,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
 		handle_rpc_func_cmd_i2c_transfer(ctx, arg);
 		break;
 	default:
-		handle_rpc_supp_cmd(ctx, arg);
+		handle_rpc_supp_cmd(ctx, optee, arg);
 	}
 }
 
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 19 04:06:55 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 19 Aug 2021 13:06:55 +0200
Subject: [PATCH v4 5/5] optee: add FF-A support
In-Reply-To: <20210819110655.739318-1-jens.wiklander@linaro.org>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
Message-ID: <20210819110655.739318-6-jens.wiklander@linaro.org>

Adds support for using FF-A [1] as transport to the OP-TEE driver.

Introduces struct optee_msg_param_fmem which carries all information
needed when OP-TEE is calling FFA_MEM_RETRIEVE_REQ to get the shared
memory reference mapped by the hypervisor in S-EL2. Register usage is
also updated to include the information needed.

The FF-A part of this driver is enabled if CONFIG_ARM_FFA_TRANSPORT is
enabled.

[1] https://developer.arm.com/documentation/den0077/latest
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/Makefile        |   3 +-
 drivers/tee/optee/call.c          |  13 +-
 drivers/tee/optee/core.c          |  16 +-
 drivers/tee/optee/ffa_abi.c       | 907 ++++++++++++++++++++++++++++++
 drivers/tee/optee/optee_ffa.h     | 153 +++++
 drivers/tee/optee/optee_msg.h     |  27 +-
 drivers/tee/optee/optee_private.h |  43 +-
 7 files changed, 1148 insertions(+), 14 deletions(-)
 create mode 100644 drivers/tee/optee/ffa_abi.c
 create mode 100644 drivers/tee/optee/optee_ffa.h

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index e92f77462f40..dbfd83d3c4ae 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -7,7 +7,8 @@ optee-objs += supp.o
 optee-objs += device.o
 
 optee-smc-abi-y = smc_abi.o
-optee-objs += $(optee-ffa-abi-y)
+optee-ffa-abi-$(CONFIG_ARM_FFA_TRANSPORT) = ffa_abi.o
+optee-objs += $(optee-smc-abi-y) $(optee-ffa-abi-y)
 
 # for tracing framework to find optee_trace.h
 CFLAGS_smc_abi.o := -I$(src)
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 3f81c168ed3f..87d739091055 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -107,11 +107,20 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
 struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params,
 				  struct optee_msg_arg **msg_arg)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	size_t sz = OPTEE_MSG_GET_ARG_SIZE(num_params);
 	struct tee_shm *shm;
 	struct optee_msg_arg *ma;
 
-	shm = tee_shm_alloc(ctx, OPTEE_MSG_GET_ARG_SIZE(num_params),
-			    TEE_SHM_MAPPED);
+	/*
+	 * rpc_arg_count is set to the number of allocated parameters in
+	 * the RPC argument struct if a second MSG arg struct is expected.
+	 * The second arg struct will then be used for RPC.
+	 */
+	if (optee->rpc_arg_count)
+		sz += OPTEE_MSG_GET_ARG_SIZE(optee->rpc_arg_count);
+
+	shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED);
 	if (IS_ERR(shm))
 		return shm;
 
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index e372ebaff5d6..c22cdf65451b 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -160,15 +160,27 @@ void optee_remove_common(struct optee *optee)
 	mutex_destroy(&optee->call_queue.mutex);
 }
 
+static int smc_abi_rc;
+static int ffa_abi_rc;
+
 static int optee_core_init(void)
 {
-	return optee_smc_abi_register();
+	smc_abi_rc = optee_smc_abi_register();
+	ffa_abi_rc = optee_ffa_abi_register();
+
+	/* If both failed there's no point with this module */
+	if (smc_abi_rc && ffa_abi_rc)
+		return smc_abi_rc;
+	return 0;
 }
 module_init(optee_core_init);
 
 static void optee_core_exit(void)
 {
-	optee_smc_abi_unregister();
+	if (!smc_abi_rc)
+		optee_smc_abi_unregister();
+	if (!ffa_abi_rc)
+		optee_ffa_abi_unregister();
 }
 module_exit(optee_core_exit);
 
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
new file mode 100644
index 000000000000..85dca49ac2ce
--- /dev/null
+++ b/drivers/tee/optee/ffa_abi.c
@@ -0,0 +1,907 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, Linaro Limited
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/arm_ffa.h>
+#include <linux/errno.h>
+#include <linux/scatterlist.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include "optee_private.h"
+#include "optee_ffa.h"
+#include "optee_rpc_cmd.h"
+
+/*
+ * This file implement the FF-A ABI used when communicating with secure world
+ * OP-TEE OS via FF-A.
+ * This file is divided into the follow sections:
+ * 1. Maintain a hash table for lookup of a global FF-A memory handle
+ * 2. Convert between struct tee_param and struct optee_msg_param
+ * 3. Low level support functions to register shared memory in secure world
+ * 4. Dynamic shared memory pool based on alloc_pages()
+ * 5. Do a normal scheduled call into secure world
+ * 6. Driver initialization.
+ */
+
+/*
+ * 1. Maintain a hash table for lookup of a global FF-A memory handle
+ *
+ * FF-A assigns a global memory handle for each piece shared memory.
+ * This handle is then used when communicating with secure world.
+ *
+ * Main functions are optee_shm_add_ffa_handle() and optee_shm_rem_ffa_handle()
+ */
+struct shm_rhash {
+	struct tee_shm *shm;
+	u64 global_id;
+	struct rhash_head linkage;
+};
+
+static void rh_free_fn(void *ptr, void *arg)
+{
+	kfree(ptr);
+}
+
+static const struct rhashtable_params shm_rhash_params = {
+	.head_offset = offsetof(struct shm_rhash, linkage),
+	.key_len     = sizeof(u64),
+	.key_offset  = offsetof(struct shm_rhash, global_id),
+	.automatic_shrinking = true,
+};
+
+static struct tee_shm *optee_shm_from_ffa_handle(struct optee *optee,
+						 u64 global_id)
+{
+	struct tee_shm *shm = NULL;
+	struct shm_rhash *r;
+
+	mutex_lock(&optee->ffa.mutex);
+	r = rhashtable_lookup_fast(&optee->ffa.global_ids, &global_id,
+				   shm_rhash_params);
+	if (r)
+		shm = r->shm;
+	mutex_unlock(&optee->ffa.mutex);
+
+	return shm;
+}
+
+static int optee_shm_add_ffa_handle(struct optee *optee, struct tee_shm *shm,
+				    u64 global_id)
+{
+	struct shm_rhash *r;
+	int rc;
+
+	r = kmalloc(sizeof(*r), GFP_KERNEL);
+	if (!r)
+		return -ENOMEM;
+	r->shm = shm;
+	r->global_id = global_id;
+
+	mutex_lock(&optee->ffa.mutex);
+	rc = rhashtable_lookup_insert_fast(&optee->ffa.global_ids, &r->linkage,
+					   shm_rhash_params);
+	mutex_unlock(&optee->ffa.mutex);
+
+	if (rc)
+		kfree(r);
+
+	return rc;
+}
+
+static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id)
+{
+	struct shm_rhash *r;
+	int rc = -ENOENT;
+
+	mutex_lock(&optee->ffa.mutex);
+	r = rhashtable_lookup_fast(&optee->ffa.global_ids, &global_id,
+				   shm_rhash_params);
+	if (r)
+		rc = rhashtable_remove_fast(&optee->ffa.global_ids,
+					    &r->linkage, shm_rhash_params);
+	mutex_unlock(&optee->ffa.mutex);
+
+	if (!rc)
+		kfree(r);
+
+	return rc;
+}
+
+/*
+ * 2. Convert between struct tee_param and struct optee_msg_param
+ *
+ * optee_ffa_from_msg_param() and optee_ffa_to_msg_param() are the main
+ * functions.
+ */
+
+static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
+				   u32 attr, const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm = NULL;
+	u64 offs_high = 0;
+	u64 offs_low = 0;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
+	p->u.memref.size = mp->u.fmem.size;
+
+	if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID)
+		shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id);
+	p->u.memref.shm = shm;
+
+	if (shm) {
+		offs_low = mp->u.fmem.offs_low;
+		offs_high = mp->u.fmem.offs_high;
+	}
+	p->u.memref.shm_offs = offs_low | offs_high << 32;
+}
+
+/**
+ * optee_ffa_from_msg_param() - convert from OPTEE_MSG parameters to
+ *				struct tee_param
+ * @optee:	main service struct
+ * @params:	subsystem internal parameter representation
+ * @num_params:	number of elements in the parameter arrays
+ * @msg_params:	OPTEE_MSG parameters
+ *
+ * Returns 0 on success or <0 on failure
+ */
+static int optee_ffa_from_msg_param(struct optee *optee,
+				    struct tee_param *params, size_t num_params,
+				    const struct optee_msg_param *msg_params)
+{
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_param *p = params + n;
+		const struct optee_msg_param *mp = msg_params + n;
+		u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
+
+		switch (attr) {
+		case OPTEE_MSG_ATTR_TYPE_NONE:
+			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
+			memset(&p->u, 0, sizeof(p->u));
+			break;
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
+			optee_from_msg_param_value(p, attr, mp);
+			break;
+		case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
+			from_msg_param_ffa_mem(optee, p, attr, mp);
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
+				const struct tee_param *p)
+{
+	struct tee_shm *shm = p->u.memref.shm;
+
+	mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
+
+	if (shm) {
+		u64 shm_offs = p->u.memref.shm_offs;
+
+		mp->u.fmem.internal_offs = shm->offset;
+
+		mp->u.fmem.offs_low = shm_offs;
+		mp->u.fmem.offs_high = shm_offs >> 32;
+		/* Check that the entire offset could be stored. */
+		if (mp->u.fmem.offs_high != shm_offs >> 32)
+			return -EINVAL;
+
+		mp->u.fmem.global_id = shm->sec_world_id;
+	} else {
+		memset(&mp->u, 0, sizeof(mp->u));
+		mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
+	}
+	mp->u.fmem.size = p->u.memref.size;
+
+	return 0;
+}
+
+/**
+ * optee_ffa_to_msg_param() - convert from struct tee_params to OPTEE_MSG
+ *			      parameters
+ * @optee:	main service struct
+ * @msg_params:	OPTEE_MSG parameters
+ * @num_params:	number of elements in the parameter arrays
+ * @params:	subsystem itnernal parameter representation
+ * Returns 0 on success or <0 on failure
+ */
+static int optee_ffa_to_msg_param(struct optee *optee,
+				  struct optee_msg_param *msg_params,
+				  size_t num_params,
+				  const struct tee_param *params)
+{
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		const struct tee_param *p = params + n;
+		struct optee_msg_param *mp = msg_params + n;
+
+		switch (p->attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
+			mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
+			memset(&mp->u, 0, sizeof(mp->u));
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			optee_to_msg_param_value(mp, p);
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			if (to_msg_param_ffa_mem(mp, p))
+				return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * 3. Low level support functions to register shared memory in secure world
+ *
+ * Functions to register and unregister shared memory both for normal
+ * clients and for tee-supplicant.
+ */
+
+static int optee_ffa_shm_register(struct tee_context *ctx, struct tee_shm *shm,
+				  struct page **pages, size_t num_pages,
+				  unsigned long start)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
+	struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
+	struct ffa_mem_region_attributes mem_attr = {
+		.receiver = ffa_dev->vm_id,
+		.attrs = FFA_MEM_RW,
+	};
+	struct ffa_mem_ops_args args = {
+		.use_txbuf = true,
+		.attrs = &mem_attr,
+		.nattrs = 1,
+	};
+	struct sg_table sgt;
+	int rc;
+
+	rc = optee_check_mem_type(start, num_pages);
+	if (rc)
+		return rc;
+
+	rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
+				       num_pages * PAGE_SIZE, GFP_KERNEL);
+	if (rc)
+		return rc;
+	args.sg = sgt.sgl;
+	rc = ffa_ops->memory_share(ffa_dev, &args);
+	sg_free_table(&sgt);
+	if (rc)
+		return rc;
+
+	rc = optee_shm_add_ffa_handle(optee, shm, args.g_handle);
+	if (rc) {
+		ffa_ops->memory_reclaim(args.g_handle, 0);
+		return rc;
+	}
+
+	shm->sec_world_id = args.g_handle;
+
+	return 0;
+}
+
+static int optee_ffa_shm_unregister(struct tee_context *ctx,
+				    struct tee_shm *shm)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
+	struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
+	u64 global_handle = shm->sec_world_id;
+	struct ffa_send_direct_data data = {
+		.data0 = OPTEE_FFA_UNREGISTER_SHM,
+		.data1 = (u32)global_handle,
+		.data2 = (u32)(global_handle >> 32)
+	};
+	int rc;
+
+	optee_shm_rem_ffa_handle(optee, global_handle);
+	shm->sec_world_id = 0;
+
+	rc = ffa_ops->sync_send_receive(ffa_dev, &data);
+	if (rc)
+		pr_err("Unregister SHM id 0x%llx rc %d\n", global_handle, rc);
+
+	rc = ffa_ops->memory_reclaim(global_handle, 0);
+	if (rc)
+		pr_err("mem_reclain: 0x%llx %d", global_handle, rc);
+
+	return rc;
+}
+
+static int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
+					 struct tee_shm *shm)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
+	u64 global_handle = shm->sec_world_id;
+	int rc;
+
+	/*
+	 * We're skipping the OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM call
+	 * since this is OP-TEE freeing via RPC so it has already retired
+	 * this ID.
+	 */
+
+	optee_shm_rem_ffa_handle(optee, global_handle);
+	rc = ffa_ops->memory_reclaim(global_handle, 0);
+	if (rc)
+		pr_err("mem_reclain: 0x%llx %d", global_handle, rc);
+
+	shm->sec_world_id = 0;
+
+	return rc;
+}
+
+/*
+ * 4. Dynamic shared memory pool based on alloc_pages()
+ *
+ * Implements an OP-TEE specific shared memory pool.
+ * The main function is optee_ffa_shm_pool_alloc_pages().
+ */
+
+static int pool_ffa_op_alloc(struct tee_shm_pool_mgr *poolm,
+			     struct tee_shm *shm, size_t size)
+{
+	return optee_pool_op_alloc_helper(poolm, shm, size,
+					  optee_ffa_shm_register);
+}
+
+static void pool_ffa_op_free(struct tee_shm_pool_mgr *poolm,
+			     struct tee_shm *shm)
+{
+	optee_ffa_shm_unregister(shm->ctx, shm);
+	free_pages((unsigned long)shm->kaddr, get_order(shm->size));
+	shm->kaddr = NULL;
+}
+
+static void pool_ffa_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
+{
+	kfree(poolm);
+}
+
+static const struct tee_shm_pool_mgr_ops pool_ffa_ops = {
+	.alloc = pool_ffa_op_alloc,
+	.free = pool_ffa_op_free,
+	.destroy_poolmgr = pool_ffa_op_destroy_poolmgr,
+};
+
+/**
+ * optee_ffa_shm_pool_alloc_pages() - create page-based allocator pool
+ *
+ * This pool is used with OP-TEE over FF-A. In this case command buffers
+ * and such are allocated from kernel's own memory.
+ */
+static struct tee_shm_pool_mgr *optee_ffa_shm_pool_alloc_pages(void)
+{
+	struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+
+	if (!mgr)
+		return ERR_PTR(-ENOMEM);
+
+	mgr->ops = &pool_ffa_ops;
+
+	return mgr;
+}
+
+/*
+ * 5. Do a normal scheduled call into secure world
+ *
+ * The function optee_ffa_do_call_with_arg() performs a normal scheduled
+ * call into secure world. During this call may normal world request help
+ * from normal world using RPCs, Remote Procedure Calls. This includes
+ * delivery of non-secure interrupts to for instance allow rescheduling of
+ * the current task.
+ */
+
+static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
+					      struct optee_msg_arg *arg)
+{
+	struct tee_shm *shm;
+
+	if (arg->num_params != 1 ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_RPC_SHM_TYPE_APPL:
+		shm = optee_rpc_cmd_alloc_suppl(ctx, arg->params[0].u.value.b);
+		break;
+	case OPTEE_RPC_SHM_TYPE_KERNEL:
+		shm = tee_shm_alloc(ctx, arg->params[0].u.value.b,
+				    TEE_SHM_MAPPED);
+		break;
+	default:
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	if (IS_ERR(shm)) {
+		arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+		return;
+	}
+
+	arg->params[0] = (struct optee_msg_param){
+		.attr = OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT,
+		.u.fmem.size = tee_shm_get_size(shm),
+		.u.fmem.global_id = shm->sec_world_id,
+		.u.fmem.internal_offs = shm->offset,
+	};
+
+	arg->ret = TEEC_SUCCESS;
+}
+
+static void handle_ffa_rpc_func_cmd_shm_free(struct tee_context *ctx,
+					     struct optee *optee,
+					     struct optee_msg_arg *arg)
+{
+	struct tee_shm *shm;
+
+	if (arg->num_params != 1 ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
+		goto err_bad_param;
+
+	shm = optee_shm_from_ffa_handle(optee, arg->params[0].u.value.b);
+	if (!shm)
+		goto err_bad_param;
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_RPC_SHM_TYPE_APPL:
+		optee_rpc_cmd_free_suppl(ctx, shm);
+		break;
+	case OPTEE_RPC_SHM_TYPE_KERNEL:
+		tee_shm_free(shm);
+		break;
+	default:
+		goto err_bad_param;
+	}
+	arg->ret = TEEC_SUCCESS;
+	return;
+
+err_bad_param:
+	arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+}
+
+static void handle_ffa_rpc_func_cmd(struct tee_context *ctx,
+				    struct optee_msg_arg *arg)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+
+	arg->ret_origin = TEEC_ORIGIN_COMMS;
+	switch (arg->cmd) {
+	case OPTEE_RPC_CMD_SHM_ALLOC:
+		handle_ffa_rpc_func_cmd_shm_alloc(ctx, arg);
+		break;
+	case OPTEE_RPC_CMD_SHM_FREE:
+		handle_ffa_rpc_func_cmd_shm_free(ctx, optee, arg);
+		break;
+	default:
+		optee_rpc_cmd(ctx, optee, arg);
+	}
+}
+
+static void optee_handle_ffa_rpc(struct tee_context *ctx, u32 cmd,
+				 struct optee_msg_arg *arg)
+{
+	switch (cmd) {
+	case OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD:
+		handle_ffa_rpc_func_cmd(ctx, arg);
+		break;
+	case OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT:
+		/* Interrupt delivered by now */
+		break;
+	default:
+		pr_warn("Unknown RPC func 0x%x\n", cmd);
+		break;
+	}
+}
+
+static int optee_ffa_yielding_call(struct tee_context *ctx,
+				   struct ffa_send_direct_data *data,
+				   struct optee_msg_arg *rpc_arg)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
+	struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
+	struct optee_call_waiter w;
+	u32 cmd = data->data0;
+	u32 w4 = data->data1;
+	u32 w5 = data->data2;
+	u32 w6 = data->data3;
+	int rc;
+
+	/* Initialize waiter */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		rc = ffa_ops->sync_send_receive(ffa_dev, data);
+		if (rc)
+			goto done;
+
+		switch ((int)data->data0) {
+		case TEEC_SUCCESS:
+			break;
+		case TEEC_ERROR_BUSY:
+			if (cmd == OPTEE_FFA_YIELDING_CALL_RESUME) {
+				rc = -EIO;
+				goto done;
+			}
+
+			/*
+			 * Out of threads in secure world, wait for a thread
+			 * become available.
+			 */
+			optee_cq_wait_for_completion(&optee->call_queue, &w);
+			data->data0 = cmd;
+			data->data1 = w4;
+			data->data2 = w5;
+			data->data3 = w6;
+			continue;
+		default:
+			rc = -EIO;
+			goto done;
+		}
+
+		if (data->data1 == OPTEE_FFA_YIELDING_CALL_RETURN_DONE)
+			goto done;
+
+		/*
+		 * OP-TEE has returned with a RPC request.
+		 *
+		 * Note that data->data4 (passed in register w7) is already
+		 * filled in by ffa_ops->sync_send_receive() returning
+		 * above.
+		 */
+		cond_resched();
+		optee_handle_ffa_rpc(ctx, data->data1, rpc_arg);
+		cmd = OPTEE_FFA_YIELDING_CALL_RESUME;
+		data->data0 = cmd;
+		data->data1 = 0;
+		data->data2 = 0;
+		data->data3 = 0;
+	}
+done:
+	/*
+	 * We're done with our thread in secure world, if there's any
+	 * thread waiters wake up one.
+	 */
+	optee_cq_wait_final(&optee->call_queue, &w);
+
+	return rc;
+}
+
+/**
+ * optee_ffa_do_call_with_arg() - Do a FF-A call to enter OP-TEE in secure world
+ * @ctx:	calling context
+ * @shm:	shared memory holding the message to pass to secure world
+ *
+ * Does a FF-A call to OP-TEE in secure world and handles eventual resulting
+ * Remote Procedure Calls (RPC) from OP-TEE.
+ *
+ * Returns return code from FF-A, 0 is OK
+ */
+
+static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
+				      struct tee_shm *shm)
+{
+	struct ffa_send_direct_data data = {
+		.data0 = OPTEE_FFA_YIELDING_CALL_WITH_ARG,
+		.data1 = (u32)shm->sec_world_id,
+		.data2 = (u32)(shm->sec_world_id >> 32),
+		.data3 = shm->offset,
+	};
+	struct optee_msg_arg *arg = tee_shm_get_va(shm, 0);
+	unsigned int rpc_arg_offs = OPTEE_MSG_GET_ARG_SIZE(arg->num_params);
+	struct optee_msg_arg *rpc_arg = tee_shm_get_va(shm, rpc_arg_offs);
+
+	return optee_ffa_yielding_call(ctx, &data, rpc_arg);
+}
+
+/*
+ * 6. Driver initialization
+ *
+ * During driver inititialization is the OP-TEE Secure Partition is probed
+ * to find out which features it supports so the driver can be initialized
+ * with a matching configuration.
+ */
+
+static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev,
+					const struct ffa_dev_ops *ops)
+{
+	struct ffa_send_direct_data data = { OPTEE_FFA_GET_API_VERSION };
+	int rc;
+
+	ops->mode_32bit_set(ffa_dev);
+
+	rc = ops->sync_send_receive(ffa_dev, &data);
+	if (rc) {
+		pr_err("Unexpected error %d\n", rc);
+		return false;
+	}
+	if (data.data0 != OPTEE_FFA_VERSION_MAJOR ||
+	    data.data1 < OPTEE_FFA_VERSION_MINOR) {
+		pr_err("Incompatible OP-TEE API version %lu.%lu",
+		       data.data0, data.data1);
+		return false;
+	}
+
+	data = (struct ffa_send_direct_data){ OPTEE_FFA_GET_OS_VERSION };
+	rc = ops->sync_send_receive(ffa_dev, &data);
+	if (rc) {
+		pr_err("Unexpected error %d\n", rc);
+		return false;
+	}
+	if (data.data2)
+		pr_info("revision %lu.%lu (%08lx)",
+			data.data0, data.data1, data.data2);
+	else
+		pr_info("revision %lu.%lu", data.data0, data.data1);
+
+	return true;
+}
+
+static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev,
+				    const struct ffa_dev_ops *ops,
+				    unsigned int *rpc_arg_count)
+{
+	struct ffa_send_direct_data data = { OPTEE_FFA_EXCHANGE_CAPABILITIES };
+	int rc;
+
+	rc = ops->sync_send_receive(ffa_dev, &data);
+	if (rc) {
+		pr_err("Unexpected error %d", rc);
+		return false;
+	}
+	if (data.data0) {
+		pr_err("Unexpected exchange error %lu", data.data0);
+		return false;
+	}
+
+	*rpc_arg_count = (u8)data.data1;
+
+	return true;
+}
+
+static struct tee_shm_pool *optee_ffa_config_dyn_shm(void)
+{
+	struct tee_shm_pool_mgr *priv_mgr;
+	struct tee_shm_pool_mgr *dmabuf_mgr;
+	void *rc;
+
+	rc = optee_ffa_shm_pool_alloc_pages();
+	if (IS_ERR(rc))
+		return rc;
+	priv_mgr = rc;
+
+	rc = optee_ffa_shm_pool_alloc_pages();
+	if (IS_ERR(rc)) {
+		tee_shm_pool_mgr_destroy(priv_mgr);
+		return rc;
+	}
+	dmabuf_mgr = rc;
+
+	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
+	if (IS_ERR(rc)) {
+		tee_shm_pool_mgr_destroy(priv_mgr);
+		tee_shm_pool_mgr_destroy(dmabuf_mgr);
+	}
+
+	return rc;
+}
+
+static void optee_ffa_get_version(struct tee_device *teedev,
+				  struct tee_ioctl_version_data *vers)
+{
+	struct tee_ioctl_version_data v = {
+		.impl_id = TEE_IMPL_ID_OPTEE,
+		.impl_caps = TEE_OPTEE_CAP_TZ,
+		.gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM |
+			    TEE_GEN_CAP_MEMREF_NULL,
+	};
+
+	*vers = v;
+}
+
+static int optee_ffa_open(struct tee_context *ctx)
+{
+	return optee_open(ctx, true);
+}
+
+static const struct tee_driver_ops optee_ffa_clnt_ops = {
+	.get_version = optee_ffa_get_version,
+	.open = optee_ffa_open,
+	.release = optee_release,
+	.open_session = optee_open_session,
+	.close_session = optee_close_session,
+	.invoke_func = optee_invoke_func,
+	.cancel_req = optee_cancel_req,
+	.shm_register = optee_ffa_shm_register,
+	.shm_unregister = optee_ffa_shm_unregister,
+};
+
+static const struct tee_desc optee_ffa_clnt_desc = {
+	.name = DRIVER_NAME "-ffa-clnt",
+	.ops = &optee_ffa_clnt_ops,
+	.owner = THIS_MODULE,
+};
+
+static const struct tee_driver_ops optee_ffa_supp_ops = {
+	.get_version = optee_ffa_get_version,
+	.open = optee_ffa_open,
+	.release = optee_release_supp,
+	.supp_recv = optee_supp_recv,
+	.supp_send = optee_supp_send,
+	.shm_register = optee_ffa_shm_register, /* same as for clnt ops */
+	.shm_unregister = optee_ffa_shm_unregister_supp,
+};
+
+static const struct tee_desc optee_ffa_supp_desc = {
+	.name = DRIVER_NAME "-ffa-supp",
+	.ops = &optee_ffa_supp_ops,
+	.owner = THIS_MODULE,
+	.flags = TEE_DESC_PRIVILEGED,
+};
+
+static const struct optee_ops optee_ffa_ops = {
+	.do_call_with_arg = optee_ffa_do_call_with_arg,
+	.to_msg_param = optee_ffa_to_msg_param,
+	.from_msg_param = optee_ffa_from_msg_param,
+};
+
+static void optee_ffa_remove(struct ffa_device *ffa_dev)
+{
+	struct optee *optee = ffa_dev->dev.driver_data;
+
+	optee_remove_common(optee);
+
+	mutex_destroy(&optee->ffa.mutex);
+	rhashtable_free_and_destroy(&optee->ffa.global_ids, rh_free_fn, NULL);
+
+	kfree(optee);
+}
+
+static int optee_ffa_probe(struct ffa_device *ffa_dev)
+{
+	const struct ffa_dev_ops *ffa_ops;
+	unsigned int rpc_arg_count;
+	struct tee_device *teedev;
+	struct optee *optee;
+	int rc;
+
+	ffa_ops = ffa_dev_ops_get(ffa_dev);
+	if (!ffa_ops) {
+		pr_warn("failed \"method\" init: ffa\n");
+		return -ENOENT;
+	}
+
+	if (!optee_ffa_api_is_compatbile(ffa_dev, ffa_ops))
+		return -EINVAL;
+
+	if (!optee_ffa_exchange_caps(ffa_dev, ffa_ops, &rpc_arg_count))
+		return -EINVAL;
+
+	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
+	if (!optee) {
+		rc = -ENOMEM;
+		goto err;
+	}
+	optee->pool = optee_ffa_config_dyn_shm();
+	if (IS_ERR(optee->pool)) {
+		rc = PTR_ERR(optee->pool);
+		optee->pool = NULL;
+		goto err;
+	}
+
+	optee->ops = &optee_ffa_ops;
+	optee->ffa.ffa_dev = ffa_dev;
+	optee->ffa.ffa_ops = ffa_ops;
+	optee->rpc_arg_count = rpc_arg_count;
+
+	teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool,
+				  optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->teedev = teedev;
+
+	teedev = tee_device_alloc(&optee_ffa_supp_desc, NULL, optee->pool,
+				  optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->supp_teedev = teedev;
+
+	rc = tee_device_register(optee->teedev);
+	if (rc)
+		goto err;
+
+	rc = tee_device_register(optee->supp_teedev);
+	if (rc)
+		goto err;
+
+	rc = rhashtable_init(&optee->ffa.global_ids, &shm_rhash_params);
+	if (rc)
+		goto err;
+	mutex_init(&optee->ffa.mutex);
+	mutex_init(&optee->call_queue.mutex);
+	INIT_LIST_HEAD(&optee->call_queue.waiters);
+	optee_wait_queue_init(&optee->wait_queue);
+	optee_supp_init(&optee->supp);
+	ffa_dev_set_drvdata(ffa_dev, optee);
+
+	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
+	if (rc) {
+		optee_ffa_remove(ffa_dev);
+		return rc;
+	}
+
+	pr_info("initialized driver\n");
+	return 0;
+err:
+	/*
+	 * tee_device_unregister() is safe to call even if the
+	 * devices hasn't been registered with
+	 * tee_device_register() yet.
+	 */
+	tee_device_unregister(optee->supp_teedev);
+	tee_device_unregister(optee->teedev);
+	if (optee->pool)
+		tee_shm_pool_free(optee->pool);
+	kfree(optee);
+	return rc;
+}
+
+static const struct ffa_device_id optee_ffa_device_id[] = {
+	/* 486178e0-e7f8-11e3-bc5e0002a5d5c51b */
+	{ UUID_INIT(0x486178e0, 0xe7f8, 0x11e3,
+		    0xbc, 0x5e, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b) },
+	{}
+};
+
+static struct ffa_driver optee_ffa_driver = {
+	.name = "optee",
+	.probe = optee_ffa_probe,
+	.remove = optee_ffa_remove,
+	.id_table = optee_ffa_device_id,
+};
+
+int optee_ffa_abi_register(void)
+{
+	return ffa_register(&optee_ffa_driver);
+}
+
+void optee_ffa_abi_unregister(void)
+{
+	ffa_unregister(&optee_ffa_driver);
+}
diff --git a/drivers/tee/optee/optee_ffa.h b/drivers/tee/optee/optee_ffa.h
new file mode 100644
index 000000000000..ee3a03fc392c
--- /dev/null
+++ b/drivers/tee/optee/optee_ffa.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2019-2021, Linaro Limited
+ */
+
+/*
+ * This file is exported by OP-TEE and is kept in sync between secure world
+ * and normal world drivers. We're using ARM FF-A 1.0 specification.
+ */
+
+#ifndef __OPTEE_FFA_H
+#define __OPTEE_FFA_H
+
+#include <linux/arm_ffa.h>
+
+/*
+ * Normal world sends requests with FFA_MSG_SEND_DIRECT_REQ and
+ * responses are returned with FFA_MSG_SEND_DIRECT_RESP for normal
+ * messages.
+ *
+ * All requests with FFA_MSG_SEND_DIRECT_REQ and FFA_MSG_SEND_DIRECT_RESP
+ * are using the AArch32 SMC calling convention with register usage as
+ * defined in FF-A specification:
+ * w0:    Function ID (0x8400006F or 0x84000070)
+ * w1:    Source/Destination IDs
+ * w2:    Reserved (MBZ)
+ * w3-w7: Implementation defined, free to be used below
+ */
+
+#define OPTEE_FFA_VERSION_MAJOR	1
+#define OPTEE_FFA_VERSION_MINOR	0
+
+#define OPTEE_FFA_BLOCKING_CALL(id)	(id)
+#define OPTEE_FFA_YIELDING_CALL_BIT	31
+#define OPTEE_FFA_YIELDING_CALL(id)	((id) | BIT(OPTEE_FFA_YIELDING_CALL_BIT))
+
+/*
+ * Returns the API version implemented, currently follows the FF-A version.
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_GET_API_VERSION
+ * w4-w7: Not used (MBZ)
+ *
+ * Return register usage:
+ * w3:    OPTEE_FFA_VERSION_MAJOR
+ * w4:    OPTEE_FFA_VERSION_MINOR
+ * w5-w7: Not used (MBZ)
+ */
+#define OPTEE_FFA_GET_API_VERSION	OPTEE_FFA_BLOCKING_CALL(0)
+
+/*
+ * Returns the revision of OP-TEE.
+ *
+ * Used by non-secure world to figure out which version of the Trusted OS
+ * is installed. Note that the returned revision is the revision of the
+ * Trusted OS, not of the API.
+ *
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_GET_OS_VERSION
+ * w4-w7: Unused (MBZ)
+ *
+ * Return register usage:
+ * w3:    CFG_OPTEE_REVISION_MAJOR
+ * w4:    CFG_OPTEE_REVISION_MINOR
+ * w5:    TEE_IMPL_GIT_SHA1 (or zero if not supported)
+ */
+#define OPTEE_FFA_GET_OS_VERSION	OPTEE_FFA_BLOCKING_CALL(1)
+
+/*
+ * Exchange capabilities between normal world and secure world.
+ *
+ * Currently there are no defined capabilities. When features are added new
+ * capabilities may be added.
+ *
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_EXCHANGE_CAPABILITIES
+ * w4-w7: Note used (MBZ)
+ *
+ * Return register usage:
+ * w3:    Error code, 0 on success
+ * w4:    Bit[7:0]:  Number of parameters needed for RPC to be supplied
+ *                   as the second MSG arg struct for
+ *                   OPTEE_FFA_YIELDING_CALL_WITH_ARG.
+ *        Bit[31:8]: Reserved (MBZ)
+ * w5-w7: Note used (MBZ)
+ */
+#define OPTEE_FFA_EXCHANGE_CAPABILITIES OPTEE_FFA_BLOCKING_CALL(2)
+
+/*
+ * Unregister shared memory
+ *
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM
+ * w4:    Shared memory handle, lower bits
+ * w5:    Shared memory handle, higher bits
+ * w6-w7: Not used (MBZ)
+ *
+ * Return register usage:
+ * w3:    Error code, 0 on success
+ * w4-w7: Note used (MBZ)
+ */
+#define OPTEE_FFA_UNREGISTER_SHM	OPTEE_FFA_BLOCKING_CALL(3)
+
+/*
+ * Call with struct optee_msg_arg as argument in the supplied shared memory
+ * with a zero internal offset and normal cached memory attributes.
+ * Register usage:
+ * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_WITH_ARG
+ * w4:    Lower 32 bits of a 64-bit Shared memory handle
+ * w5:    Upper 32 bits of a 64-bit Shared memory handle
+ * w6:    Offset into shared memory pointing to a struct optee_msg_arg
+ *	  right after the parameters of this struct (at offset
+ *	  OPTEE_MSG_GET_ARG_SIZE(num_params) follows a struct optee_msg_arg
+ *	  for RPC, this struct has reserved space for the number of RPC
+ *	  parameters as returned by OPTEE_FFA_EXCHANGE_CAPABILITIES.
+ * w7:    Not used (MBZ)
+ * Resume from RPC. Register usage:
+ * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_RESUME
+ * w4-w6: Not used (MBZ)
+ * w7:    Resume info
+ *
+ * Normal return (yielding call is completed). Register usage:
+ * w3:    Error code, 0 on success
+ * w4:    OPTEE_FFA_YIELDING_CALL_RETURN_DONE
+ * w5-w7: Not used (MBZ)
+ *
+ * RPC interrupt return (RPC from secure world). Register usage:
+ * w3:    Error code == 0
+ * w4:    Any defined RPC code but OPTEE_FFA_YIELDING_CALL_RETURN_DONE
+ * w5-w6: Not used (MBZ)
+ * w7:    Resume info
+ *
+ * Possible error codes in register w3:
+ * 0:                       Success
+ * FFA_DENIED:              w4 isn't one of OPTEE_FFA_YIELDING_CALL_START
+ *                          OPTEE_FFA_YIELDING_CALL_RESUME
+ *
+ * Possible error codes for OPTEE_FFA_YIELDING_CALL_START,
+ * FFA_BUSY:               Number of OP-TEE OS threads exceeded,
+ *                         try again later
+ * FFA_DENIED:             RPC shared memory object not found
+ * FFA_INVALID_PARAMETER:  Bad shared memory handle or offset into the memory
+ *
+ * Possible error codes for OPTEE_FFA_YIELDING_CALL_RESUME
+ * FFA_INVALID_PARAMETER:  Bad resume info
+ */
+#define OPTEE_FFA_YIELDING_CALL_WITH_ARG	OPTEE_FFA_YIELDING_CALL(0)
+#define OPTEE_FFA_YIELDING_CALL_RESUME		OPTEE_FFA_YIELDING_CALL(1)
+
+#define OPTEE_FFA_YIELDING_CALL_RETURN_DONE		0
+#define OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD		1
+#define OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT	2
+
+#endif /*__OPTEE_FFA_H*/
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index e3d72d09c484..2422e185d400 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -28,6 +28,9 @@
 #define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT		0x5
 #define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT		0x6
 #define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT		0x7
+#define OPTEE_MSG_ATTR_TYPE_FMEM_INPUT		OPTEE_MSG_ATTR_TYPE_RMEM_INPUT
+#define OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT		OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT
+#define OPTEE_MSG_ATTR_TYPE_FMEM_INOUT		OPTEE_MSG_ATTR_TYPE_RMEM_INOUT
 #define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT		0x9
 #define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT		0xa
 #define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT		0xb
@@ -96,6 +99,8 @@
  */
 #define OPTEE_MSG_NONCONTIG_PAGE_SIZE		4096
 
+#define OPTEE_MSG_FMEM_INVALID_GLOBAL_ID	0xffffffffffffffff
+
 /**
  * struct optee_msg_param_tmem - temporary memory reference parameter
  * @buf_ptr:	Address of the buffer
@@ -127,6 +132,23 @@ struct optee_msg_param_rmem {
 	u64 shm_ref;
 };
 
+/**
+ * struct optee_msg_param_fmem - ffa memory reference parameter
+ * @offs_lower:	   Lower bits of offset into shared memory reference
+ * @offs_upper:	   Upper bits of offset into shared memory reference
+ * @internal_offs: Internal offset into the first page of shared memory
+ *		   reference
+ * @size:	   Size of the buffer
+ * @global_id:	   Global identifier of Shared memory
+ */
+struct optee_msg_param_fmem {
+	u32 offs_low;
+	u16 offs_high;
+	u16 internal_offs;
+	u64 size;
+	u64 global_id;
+};
+
 /**
  * struct optee_msg_param_value - opaque value parameter
  *
@@ -143,13 +165,15 @@ struct optee_msg_param_value {
  * @attr:	attributes
  * @tmem:	parameter by temporary memory reference
  * @rmem:	parameter by registered memory reference
+ * @fmem:	parameter by ffa registered memory reference
  * @value:	parameter by opaque value
  * @octets:	parameter by octet string
  *
  * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in
  * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value or octets,
  * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and
- * OPTEE_MSG_ATTR_TYPE_RMEM_* indicates @rmem,
+ * OPTEE_MSG_ATTR_TYPE_RMEM_* or the alias PTEE_MSG_ATTR_TYPE_FMEM_* indicates
+ * @rmem or @fmem depending on the conduit.
  * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used.
  */
 struct optee_msg_param {
@@ -157,6 +181,7 @@ struct optee_msg_param {
 	union {
 		struct optee_msg_param_tmem tmem;
 		struct optee_msg_param_rmem rmem;
+		struct optee_msg_param_fmem fmem;
 		struct optee_msg_param_value value;
 		u8 octets[24];
 	} u;
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index ca0213e330b5..2593742364da 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -7,6 +7,7 @@
 #define OPTEE_PRIVATE_H
 
 #include <linux/arm-smccc.h>
+#include <linux/rhashtable.h>
 #include <linux/semaphore.h>
 #include <linux/tee_drv.h>
 #include <linux/types.h>
@@ -22,6 +23,7 @@
 #define TEEC_ERROR_NOT_SUPPORTED	0xFFFF000A
 #define TEEC_ERROR_COMMUNICATION	0xFFFF000E
 #define TEEC_ERROR_OUT_OF_MEMORY	0xFFFF000C
+#define TEEC_ERROR_BUSY			0xFFFF000D
 #define TEEC_ERROR_SHORT_BUFFER		0xFFFF0010
 
 #define TEEC_ORIGIN_COMMS		0x00000002
@@ -73,19 +75,28 @@ struct optee_supp {
 	struct completion reqs_c;
 };
 
-/**
- * struct optee_smc - SMC ABI specifics
- * @invoke_fn:		function to issue smc or hvc
- * @memremaped_shm	virtual address of memory in shared memory pool
- * @sec_caps:		secure world capabilities defined by
- *			OPTEE_SMC_SEC_CAP_* in optee_smc.h
- */
 struct optee_smc {
 	optee_invoke_fn *invoke_fn;
 	void *memremaped_shm;
 	u32 sec_caps;
 };
 
+/**
+ * struct optee_ffa_data -  FFA communication struct
+ * @ffa_dev		FFA device, contains the destination id, the id of
+ *			OP-TEE in secure world
+ * @ffa_ops		FFA operations
+ * @mutex		Serializes access to @global_ids
+ * @global_ids		FF-A shared memory global handle translation
+ */
+struct optee_ffa {
+	struct ffa_device *ffa_dev;
+	const struct ffa_dev_ops *ffa_ops;
+	/* Serializes access to @global_ids */
+	struct mutex mutex;
+	struct rhashtable global_ids;
+};
+
 struct optee;
 
 /**
@@ -116,11 +127,13 @@ struct optee_ops {
  *			world
  * @teedev:		client device
  * @smc:		specific to SMC ABI
+ * @ffa:		specific to FF-A ABI
  * @call_queue:		queue of threads waiting to call @invoke_fn
  * @wait_queue:		queue of threads from secure world waiting for a
  *			secure world sync object
  * @supp:		supplicant synchronization struct for RPC to supplicant
  * @pool:		shared memory pool
+ * @rpc_arg_count:	If > 0 number of RPC parameters to make room for
  * @scan_bus_done	flag if device registation was already done.
  * @scan_bus_wq		workqueue to scan optee bus and register optee drivers
  * @scan_bus_work	workq to scan optee bus and register optee drivers
@@ -129,11 +142,17 @@ struct optee {
 	struct tee_device *supp_teedev;
 	struct tee_device *teedev;
 	const struct optee_ops *ops;
-	struct optee_smc smc;
+	union {
+		struct optee_smc smc;
+#ifdef CONFIG_ARM_FFA_TRANSPORT
+		struct optee_ffa ffa;
+#endif
+	};
 	struct optee_call_queue call_queue;
 	struct optee_wait_queue wait_queue;
 	struct optee_supp supp;
 	struct tee_shm_pool *pool;
+	unsigned int rpc_arg_count;
 	bool   scan_bus_done;
 	struct workqueue_struct *scan_bus_wq;
 	struct work_struct scan_bus_work;
@@ -266,4 +285,12 @@ static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
 int optee_smc_abi_register(void);
 void optee_smc_abi_unregister(void);
 
+#ifdef CONFIG_ARM_FFA_TRANSPORT
+int optee_ffa_abi_register(void);
+void optee_ffa_abi_unregister(void);
+#else
+static inline int optee_ffa_abi_register(void) { return -EOPNOTSUPP; }
+static inline void optee_ffa_abi_unregister(void) {}
+#endif
+
 #endif /*OPTEE_PRIVATE_H*/
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 19 04:06:54 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 19 Aug 2021 13:06:54 +0200
Subject: [PATCH v4 4/5] optee: isolate smc abi
In-Reply-To: <20210819110655.739318-1-jens.wiklander@linaro.org>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
Message-ID: <20210819110655.739318-5-jens.wiklander@linaro.org>

Isolate the ABI based on raw SMCs. Code specific to the raw SMC ABI is
moved into smc_abi.c. This makes room for other ABIs with a clear
separation.

The driver changes to use module_init()/module_exit() instead of
module_platform_driver(). The platform_driver_register() and
platform_driver_unregister() functions called directly to keep the same
behavior. This is needed because module_platform_driver() is based on
module_driver() which can only be used once in a module.

A function optee_rpc_cmd() is factored out from the function
handle_rpc_func_cmd() to handle the ABI independent part of RPC
processing.

This patch is not supposed to change the driver behavior, it's only a
matter of reorganizing the code.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/Makefile        |    6 +-
 drivers/tee/optee/call.c          |  339 +-------
 drivers/tee/optee/core.c          |  688 +--------------
 drivers/tee/optee/optee_private.h |  103 ++-
 drivers/tee/optee/rpc.c           |  217 +----
 drivers/tee/optee/shm_pool.c      |   89 --
 drivers/tee/optee/shm_pool.h      |   14 -
 drivers/tee/optee/smc_abi.c       | 1299 +++++++++++++++++++++++++++++
 8 files changed, 1439 insertions(+), 1316 deletions(-)
 delete mode 100644 drivers/tee/optee/shm_pool.c
 delete mode 100644 drivers/tee/optee/shm_pool.h
 create mode 100644 drivers/tee/optee/smc_abi.c

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 3aa33ea9e6a6..e92f77462f40 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -4,8 +4,10 @@ optee-objs += core.o
 optee-objs += call.o
 optee-objs += rpc.o
 optee-objs += supp.o
-optee-objs += shm_pool.o
 optee-objs += device.o
 
+optee-smc-abi-y = smc_abi.o
+optee-objs += $(optee-ffa-abi-y)
+
 # for tracing framework to find optee_trace.h
-CFLAGS_call.o := -I$(src)
+CFLAGS_smc_abi.o := -I$(src)
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 00ecd794e59a..3f81c168ed3f 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -2,28 +2,17 @@
 /*
  * Copyright (c) 2015-2021, Linaro Limited
  */
-#include <linux/arm-smccc.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/tee_drv.h>
 #include <linux/types.h>
-#include <linux/uaccess.h>
 #include "optee_private.h"
-#include "optee_smc.h"
-#define CREATE_TRACE_POINTS
-#include "optee_trace.h"
 
-struct optee_call_waiter {
-	struct list_head list_node;
-	struct completion c;
-};
-
-static void optee_cq_wait_init(struct optee_call_queue *cq,
-			       struct optee_call_waiter *w)
+void optee_cq_wait_init(struct optee_call_queue *cq,
+			struct optee_call_waiter *w)
 {
 	/*
 	 * We're preparing to make a call to secure world. In case we can't
@@ -47,8 +36,8 @@ static void optee_cq_wait_init(struct optee_call_queue *cq,
 	mutex_unlock(&cq->mutex);
 }
 
-static void optee_cq_wait_for_completion(struct optee_call_queue *cq,
-					 struct optee_call_waiter *w)
+void optee_cq_wait_for_completion(struct optee_call_queue *cq,
+				  struct optee_call_waiter *w)
 {
 	wait_for_completion(&w->c);
 
@@ -74,8 +63,8 @@ static void optee_cq_complete_one(struct optee_call_queue *cq)
 	}
 }
 
-static void optee_cq_wait_final(struct optee_call_queue *cq,
-				struct optee_call_waiter *w)
+void optee_cq_wait_final(struct optee_call_queue *cq,
+			 struct optee_call_waiter *w)
 {
 	/*
 	 * We're done with the call to secure world. The thread in secure
@@ -115,73 +104,8 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
 	return NULL;
 }
 
-/**
- * optee_do_call_with_arg() - Do an SMC to OP-TEE in secure world
- * @ctx:	calling context
- * @arg:	shared memory holding the message to pass to secure world
- *
- * Does and SMC to OP-TEE in secure world and handles eventual resulting
- * Remote Procedure Calls (RPC) from OP-TEE.
- *
- * Returns return code from secure world, 0 is OK
- */
-int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg)
-{
-	struct optee *optee = tee_get_drvdata(ctx->teedev);
-	struct optee_call_waiter w;
-	struct optee_rpc_param param = { };
-	struct optee_call_ctx call_ctx = { };
-	phys_addr_t parg;
-	int rc;
-
-	rc = tee_shm_get_pa(arg, 0, &parg);
-	if (rc)
-		return rc;
-
-	param.a0 = OPTEE_SMC_CALL_WITH_ARG;
-	reg_pair_from_64(&param.a1, &param.a2, parg);
-	/* Initialize waiter */
-	optee_cq_wait_init(&optee->call_queue, &w);
-	while (true) {
-		struct arm_smccc_res res;
-
-		trace_optee_invoke_fn_begin(&param);
-		optee->invoke_fn(param.a0, param.a1, param.a2, param.a3,
-				 param.a4, param.a5, param.a6, param.a7,
-				 &res);
-		trace_optee_invoke_fn_end(&param, &res);
-
-		if (res.a0 == OPTEE_SMC_RETURN_ETHREAD_LIMIT) {
-			/*
-			 * Out of threads in secure world, wait for a thread
-			 * become available.
-			 */
-			optee_cq_wait_for_completion(&optee->call_queue, &w);
-		} else if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {
-			cond_resched();
-			param.a0 = res.a0;
-			param.a1 = res.a1;
-			param.a2 = res.a2;
-			param.a3 = res.a3;
-			optee_handle_rpc(ctx, &param, &call_ctx);
-		} else {
-			rc = res.a0;
-			break;
-		}
-	}
-
-	optee_rpc_finalize_call(&call_ctx);
-	/*
-	 * We're done with our thread in secure world, if there's any
-	 * thread waiters wake up one.
-	 */
-	optee_cq_wait_final(&optee->call_queue, &w);
-
-	return rc;
-}
-
-static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
-				   struct optee_msg_arg **msg_arg)
+struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params,
+				  struct optee_msg_arg **msg_arg)
 {
 	struct tee_shm *shm;
 	struct optee_msg_arg *ma;
@@ -217,7 +141,7 @@ int optee_open_session(struct tee_context *ctx,
 	uuid_t client_uuid;
 
 	/* +2 for the meta parameters added below */
-	shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg);
+	shm = optee_get_msg_arg(ctx, arg->num_params + 2, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
@@ -290,7 +214,7 @@ int optee_close_session_helper(struct tee_context *ctx, u32 session)
 	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_msg_arg *msg_arg;
 
-	shm = get_msg_arg(ctx, 0, &msg_arg);
+	shm = optee_get_msg_arg(ctx, 0, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
@@ -338,7 +262,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 	if (!sess)
 		return -EINVAL;
 
-	shm = get_msg_arg(ctx, arg->num_params, &msg_arg);
+	shm = optee_get_msg_arg(ctx, arg->num_params, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 	msg_arg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
@@ -384,7 +308,7 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 	if (!sess)
 		return -EINVAL;
 
-	shm = get_msg_arg(ctx, 0, &msg_arg);
+	shm = optee_get_msg_arg(ctx, 0, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
@@ -397,152 +321,6 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 	return 0;
 }
 
-/**
- * optee_enable_shm_cache() - Enables caching of some shared memory allocation
- *			      in OP-TEE
- * @optee:	main service struct
- */
-void optee_enable_shm_cache(struct optee *optee)
-{
-	struct optee_call_waiter w;
-
-	/* We need to retry until secure world isn't busy. */
-	optee_cq_wait_init(&optee->call_queue, &w);
-	while (true) {
-		struct arm_smccc_res res;
-
-		optee->invoke_fn(OPTEE_SMC_ENABLE_SHM_CACHE, 0, 0, 0, 0, 0, 0,
-				 0, &res);
-		if (res.a0 == OPTEE_SMC_RETURN_OK)
-			break;
-		optee_cq_wait_for_completion(&optee->call_queue, &w);
-	}
-	optee_cq_wait_final(&optee->call_queue, &w);
-}
-
-/**
- * optee_disable_shm_cache() - Disables caching of some shared memory allocation
- *			      in OP-TEE
- * @optee:	main service struct
- */
-void optee_disable_shm_cache(struct optee *optee)
-{
-	struct optee_call_waiter w;
-
-	/* We need to retry until secure world isn't busy. */
-	optee_cq_wait_init(&optee->call_queue, &w);
-	while (true) {
-		union {
-			struct arm_smccc_res smccc;
-			struct optee_smc_disable_shm_cache_result result;
-		} res;
-
-		optee->invoke_fn(OPTEE_SMC_DISABLE_SHM_CACHE, 0, 0, 0, 0, 0, 0,
-				 0, &res.smccc);
-		if (res.result.status == OPTEE_SMC_RETURN_ENOTAVAIL)
-			break; /* All shm's freed */
-		if (res.result.status == OPTEE_SMC_RETURN_OK) {
-			struct tee_shm *shm;
-
-			shm = reg_pair_to_ptr(res.result.shm_upper32,
-					      res.result.shm_lower32);
-			tee_shm_free(shm);
-		} else {
-			optee_cq_wait_for_completion(&optee->call_queue, &w);
-		}
-	}
-	optee_cq_wait_final(&optee->call_queue, &w);
-}
-
-#define PAGELIST_ENTRIES_PER_PAGE				\
-	((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1)
-
-/**
- * optee_fill_pages_list() - write list of user pages to given shared
- * buffer.
- *
- * @dst: page-aligned buffer where list of pages will be stored
- * @pages: array of pages that represents shared buffer
- * @num_pages: number of entries in @pages
- * @page_offset: offset of user buffer from page start
- *
- * @dst should be big enough to hold list of user page addresses and
- *	links to the next pages of buffer
- */
-void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
-			   size_t page_offset)
-{
-	int n = 0;
-	phys_addr_t optee_page;
-	/*
-	 * Refer to OPTEE_MSG_ATTR_NONCONTIG description in optee_msg.h
-	 * for details.
-	 */
-	struct {
-		u64 pages_list[PAGELIST_ENTRIES_PER_PAGE];
-		u64 next_page_data;
-	} *pages_data;
-
-	/*
-	 * Currently OP-TEE uses 4k page size and it does not looks
-	 * like this will change in the future.  On other hand, there are
-	 * no know ARM architectures with page size < 4k.
-	 * Thus the next built assert looks redundant. But the following
-	 * code heavily relies on this assumption, so it is better be
-	 * safe than sorry.
-	 */
-	BUILD_BUG_ON(PAGE_SIZE < OPTEE_MSG_NONCONTIG_PAGE_SIZE);
-
-	pages_data = (void *)dst;
-	/*
-	 * If linux page is bigger than 4k, and user buffer offset is
-	 * larger than 4k/8k/12k/etc this will skip first 4k pages,
-	 * because they bear no value data for OP-TEE.
-	 */
-	optee_page = page_to_phys(*pages) +
-		round_down(page_offset, OPTEE_MSG_NONCONTIG_PAGE_SIZE);
-
-	while (true) {
-		pages_data->pages_list[n++] = optee_page;
-
-		if (n == PAGELIST_ENTRIES_PER_PAGE) {
-			pages_data->next_page_data =
-				virt_to_phys(pages_data + 1);
-			pages_data++;
-			n = 0;
-		}
-
-		optee_page += OPTEE_MSG_NONCONTIG_PAGE_SIZE;
-		if (!(optee_page & ~PAGE_MASK)) {
-			if (!--num_pages)
-				break;
-			pages++;
-			optee_page = page_to_phys(*pages);
-		}
-	}
-}
-
-/*
- * The final entry in each pagelist page is a pointer to the next
- * pagelist page.
- */
-static size_t get_pages_list_size(size_t num_entries)
-{
-	int pages = DIV_ROUND_UP(num_entries, PAGELIST_ENTRIES_PER_PAGE);
-
-	return pages * OPTEE_MSG_NONCONTIG_PAGE_SIZE;
-}
-
-u64 *optee_allocate_pages_list(size_t num_entries)
-{
-	return alloc_pages_exact(get_pages_list_size(num_entries), GFP_KERNEL);
-}
-
-void optee_free_pages_list(void *list, size_t num_entries)
-{
-	free_pages_exact(list, get_pages_list_size(num_entries));
-}
-
 static bool is_normal_memory(pgprot_t p)
 {
 #if defined(CONFIG_ARM)
@@ -566,7 +344,7 @@ static int __check_mem_type(struct vm_area_struct *vma, unsigned long end)
 	return -EINVAL;
 }
 
-static int check_mem_type(unsigned long start, size_t num_pages)
+int optee_check_mem_type(unsigned long start, size_t num_pages)
 {
 	struct mm_struct *mm = current->mm;
 	int rc;
@@ -585,94 +363,3 @@ static int check_mem_type(unsigned long start, size_t num_pages)
 
 	return rc;
 }
-
-int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
-		       struct page **pages, size_t num_pages,
-		       unsigned long start)
-{
-	struct optee *optee = tee_get_drvdata(ctx->teedev);
-	struct optee_msg_arg *msg_arg;
-	struct tee_shm *shm_arg;
-	u64 *pages_list;
-	int rc;
-
-	if (!num_pages)
-		return -EINVAL;
-
-	rc = check_mem_type(start, num_pages);
-	if (rc)
-		return rc;
-
-	pages_list = optee_allocate_pages_list(num_pages);
-	if (!pages_list)
-		return -ENOMEM;
-
-	shm_arg = get_msg_arg(ctx, 1, &msg_arg);
-	if (IS_ERR(shm_arg)) {
-		rc = PTR_ERR(shm_arg);
-		goto out;
-	}
-
-	optee_fill_pages_list(pages_list, pages, num_pages,
-			      tee_shm_get_page_offset(shm));
-
-	msg_arg->cmd = OPTEE_MSG_CMD_REGISTER_SHM;
-	msg_arg->params->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
-				OPTEE_MSG_ATTR_NONCONTIG;
-	msg_arg->params->u.tmem.shm_ref = (unsigned long)shm;
-	msg_arg->params->u.tmem.size = tee_shm_get_size(shm);
-	/*
-	 * In the least bits of msg_arg->params->u.tmem.buf_ptr we
-	 * store buffer offset from 4k page, as described in OP-TEE ABI.
-	 */
-	msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
-	  (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
-
-	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
-	    msg_arg->ret != TEEC_SUCCESS)
-		rc = -EINVAL;
-
-	tee_shm_free(shm_arg);
-out:
-	optee_free_pages_list(pages_list, num_pages);
-	return rc;
-}
-
-int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
-{
-	struct optee *optee = tee_get_drvdata(ctx->teedev);
-	struct optee_msg_arg *msg_arg;
-	struct tee_shm *shm_arg;
-	int rc = 0;
-
-	shm_arg = get_msg_arg(ctx, 1, &msg_arg);
-	if (IS_ERR(shm_arg))
-		return PTR_ERR(shm_arg);
-
-	msg_arg->cmd = OPTEE_MSG_CMD_UNREGISTER_SHM;
-
-	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
-	msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;
-
-	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
-	    msg_arg->ret != TEEC_SUCCESS)
-		rc = -EINVAL;
-	tee_shm_free(shm_arg);
-	return rc;
-}
-
-int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
-			    struct page **pages, size_t num_pages,
-			    unsigned long start)
-{
-	/*
-	 * We don't want to register supplicant memory in OP-TEE.
-	 * Instead information about it will be passed in RPC code.
-	 */
-	return check_mem_type(start, num_pages);
-}
-
-int optee_shm_unregister_supp(struct tee_context *ctx, struct tee_shm *shm)
-{
-	return 0;
-}
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index f689f171a794..e372ebaff5d6 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -1,259 +1,62 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2015-2021, Linaro Limited
+ * Copyright (c) 2016, EPAM Systems
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/arm-smccc.h>
 #include <linux/errno.h>
 #include <linux/io.h>
+#include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/tee_drv.h>
 #include <linux/types.h>
-#include <linux/uaccess.h>
 #include <linux/workqueue.h>
 #include "optee_private.h"
-#include "optee_smc.h"
-#include "shm_pool.h"
 
-#define DRIVER_NAME "optee"
-
-#define OPTEE_SHM_NUM_PRIV_PAGES	CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
-
-static void from_msg_param_value(struct tee_param *p, u32 attr,
-				 const struct optee_msg_param *mp)
-{
-	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
-		  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
-	p->u.value.a = mp->u.value.a;
-	p->u.value.b = mp->u.value.b;
-	p->u.value.c = mp->u.value.c;
-}
-
-static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
-				  const struct optee_msg_param *mp)
-{
-	struct tee_shm *shm;
-	phys_addr_t pa;
-	int rc;
-
-	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
-		  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
-	p->u.memref.size = mp->u.tmem.size;
-	shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
-	if (!shm) {
-		p->u.memref.shm_offs = 0;
-		p->u.memref.shm = NULL;
-		return 0;
-	}
-
-	rc = tee_shm_get_pa(shm, 0, &pa);
-	if (rc)
-		return rc;
-
-	p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
-	p->u.memref.shm = shm;
-
-	/* Check that the memref is covered by the shm object */
-	if (p->u.memref.size) {
-		size_t o = p->u.memref.shm_offs +
-			   p->u.memref.size - 1;
-
-		rc = tee_shm_get_pa(shm, o, NULL);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}
-
-static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
-				   const struct optee_msg_param *mp)
+int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
+			       struct tee_shm *shm, size_t size,
+			       int (*shm_register)(struct tee_context *ctx,
+						   struct tee_shm *shm,
+						   struct page **pages,
+						   size_t num_pages,
+						   unsigned long start))
 {
-	struct tee_shm *shm;
+	unsigned int order = get_order(size);
+	struct page *page;
+	int rc = 0;
 
-	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
-		  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
-	p->u.memref.size = mp->u.rmem.size;
-	shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
-
-	if (shm) {
-		p->u.memref.shm_offs = mp->u.rmem.offs;
-		p->u.memref.shm = shm;
-	} else {
-		p->u.memref.shm_offs = 0;
-		p->u.memref.shm = NULL;
-	}
-}
+	page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+	if (!page)
+		return -ENOMEM;
 
-/**
- * optee_from_msg_param() - convert from OPTEE_MSG parameters to
- *			    struct tee_param
- * @optee:	main service struct
- * @params:	subsystem internal parameter representation
- * @num_params:	number of elements in the parameter arrays
- * @msg_params:	OPTEE_MSG parameters
- * Returns 0 on success or <0 on failure
- */
-static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
-				size_t num_params,
-				const struct optee_msg_param *msg_params)
-{
-	int rc;
-	size_t n;
+	shm->kaddr = page_address(page);
+	shm->paddr = page_to_phys(page);
+	shm->size = PAGE_SIZE << order;
 
-	for (n = 0; n < num_params; n++) {
-		struct tee_param *p = params + n;
-		const struct optee_msg_param *mp = msg_params + n;
-		u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
+	if (shm_register) {
+		unsigned int nr_pages = 1 << order, i;
+		struct page **pages;
 
-		switch (attr) {
-		case OPTEE_MSG_ATTR_TYPE_NONE:
-			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
-			memset(&p->u, 0, sizeof(p->u));
-			break;
-		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
-		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
-		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
-			from_msg_param_value(p, attr, mp);
-			break;
-		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
-		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
-		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
-			rc = from_msg_param_tmp_mem(p, attr, mp);
-			if (rc)
-				return rc;
-			break;
-		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
-		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
-		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
-			from_msg_param_reg_mem(p, attr, mp);
-			break;
+		pages = kcalloc(nr_pages, sizeof(pages), GFP_KERNEL);
+		if (!pages)
+			return -ENOMEM;
 
-		default:
-			return -EINVAL;
+		for (i = 0; i < nr_pages; i++) {
+			pages[i] = page;
+			page++;
 		}
-	}
-	return 0;
-}
-
-static void to_msg_param_value(struct optee_msg_param *mp,
-			       const struct tee_param *p)
-{
-	mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
-		   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-	mp->u.value.a = p->u.value.a;
-	mp->u.value.b = p->u.value.b;
-	mp->u.value.c = p->u.value.c;
-}
-
-static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
-				const struct tee_param *p)
-{
-	int rc;
-	phys_addr_t pa;
-
-	mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
-		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
-
-	mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
-	mp->u.tmem.size = p->u.memref.size;
-
-	if (!p->u.memref.shm) {
-		mp->u.tmem.buf_ptr = 0;
-		return 0;
-	}
-
-	rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
-	if (rc)
-		return rc;
-
-	mp->u.tmem.buf_ptr = pa;
-	mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
-		    OPTEE_MSG_ATTR_CACHE_SHIFT;
-
-	return 0;
-}
-
-static int to_msg_param_reg_mem(struct optee_msg_param *mp,
-				const struct tee_param *p)
-{
-	mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
-		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
-
-	mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
-	mp->u.rmem.size = p->u.memref.size;
-	mp->u.rmem.offs = p->u.memref.shm_offs;
-	return 0;
-}
-
-/**
- * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
- * @optee:	main service struct
- * @msg_params:	OPTEE_MSG parameters
- * @num_params:	number of elements in the parameter arrays
- * @params:	subsystem itnernal parameter representation
- * Returns 0 on success or <0 on failure
- */
-static int optee_to_msg_param(struct optee *optee,
-			      struct optee_msg_param *msg_params,
-			      size_t num_params, const struct tee_param *params)
-{
-	int rc;
-	size_t n;
-
-	for (n = 0; n < num_params; n++) {
-		const struct tee_param *p = params + n;
-		struct optee_msg_param *mp = msg_params + n;
 
-		switch (p->attr) {
-		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
-			mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
-			memset(&mp->u, 0, sizeof(mp->u));
-			break;
-		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
-		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
-		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
-			to_msg_param_value(mp, p);
-			break;
-		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
-		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
-		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
-			if (tee_shm_is_registered(p->u.memref.shm))
-				rc = to_msg_param_reg_mem(mp, p);
-			else
-				rc = to_msg_param_tmp_mem(mp, p);
-			if (rc)
-				return rc;
-			break;
-		default:
-			return -EINVAL;
-		}
+		shm->flags |= TEE_SHM_REGISTER;
+		rc = shm_register(shm->ctx, shm, pages, nr_pages,
+				  (unsigned long)shm->kaddr);
+		kfree(pages);
 	}
-	return 0;
-}
-
-static void optee_get_version(struct tee_device *teedev,
-			      struct tee_ioctl_version_data *vers)
-{
-	struct tee_ioctl_version_data v = {
-		.impl_id = TEE_IMPL_ID_OPTEE,
-		.impl_caps = TEE_OPTEE_CAP_TZ,
-		.gen_caps = TEE_GEN_CAP_GP,
-	};
-	struct optee *optee = tee_get_drvdata(teedev);
 
-	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
-		v.gen_caps |= TEE_GEN_CAP_REG_MEM;
-	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
-		v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
-	*vers = v;
+	return rc;
 }
 
 static void optee_bus_scan(struct work_struct *work)
@@ -261,7 +64,7 @@ static void optee_bus_scan(struct work_struct *work)
 	WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
 }
 
-static int optee_open(struct tee_context *ctx)
+int optee_open(struct tee_context *ctx, bool cap_memref_null)
 {
 	struct optee_context_data *ctxdata;
 	struct tee_device *teedev = ctx->teedev;
@@ -299,11 +102,7 @@ static int optee_open(struct tee_context *ctx)
 	mutex_init(&ctxdata->mutex);
 	INIT_LIST_HEAD(&ctxdata->sess_list);
 
-	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
-		ctx->cap_memref_null  = true;
-	else
-		ctx->cap_memref_null = false;
-
+	ctx->cap_memref_null = cap_memref_null;
 	ctx->data = ctxdata;
 	return 0;
 }
@@ -329,12 +128,12 @@ static void optee_release_helper(struct tee_context *ctx,
 	ctx->data = NULL;
 }
 
-static void optee_release(struct tee_context *ctx)
+void optee_release(struct tee_context *ctx)
 {
 	optee_release_helper(ctx, optee_close_session_helper);
 }
 
-static void optee_release_supp(struct tee_context *ctx)
+void optee_release_supp(struct tee_context *ctx)
 {
 	struct optee *optee = tee_get_drvdata(ctx->teedev);
 
@@ -346,277 +145,8 @@ static void optee_release_supp(struct tee_context *ctx)
 	optee_supp_release(&optee->supp);
 }
 
-static const struct tee_driver_ops optee_clnt_ops = {
-	.get_version = optee_get_version,
-	.open = optee_open,
-	.release = optee_release,
-	.open_session = optee_open_session,
-	.close_session = optee_close_session,
-	.invoke_func = optee_invoke_func,
-	.cancel_req = optee_cancel_req,
-	.shm_register = optee_shm_register,
-	.shm_unregister = optee_shm_unregister,
-};
-
-static const struct tee_desc optee_clnt_desc = {
-	.name = DRIVER_NAME "-clnt",
-	.ops = &optee_clnt_ops,
-	.owner = THIS_MODULE,
-};
-
-static const struct tee_driver_ops optee_supp_ops = {
-	.get_version = optee_get_version,
-	.open = optee_open,
-	.release = optee_release_supp,
-	.supp_recv = optee_supp_recv,
-	.supp_send = optee_supp_send,
-	.shm_register = optee_shm_register_supp,
-	.shm_unregister = optee_shm_unregister_supp,
-};
-
-static const struct tee_desc optee_supp_desc = {
-	.name = DRIVER_NAME "-supp",
-	.ops = &optee_supp_ops,
-	.owner = THIS_MODULE,
-	.flags = TEE_DESC_PRIVILEGED,
-};
-
-static const struct optee_ops optee_ops = {
-	.do_call_with_arg = optee_do_call_with_arg,
-	.to_msg_param = optee_to_msg_param,
-	.from_msg_param = optee_from_msg_param,
-};
-
-static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
-{
-	struct arm_smccc_res res;
-
-	invoke_fn(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res);
-
-	if (res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 &&
-	    res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3)
-		return true;
-	return false;
-}
-
-static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn)
-{
-	union {
-		struct arm_smccc_res smccc;
-		struct optee_smc_call_get_os_revision_result result;
-	} res = {
-		.result = {
-			.build_id = 0
-		}
-	};
-
-	invoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0,
-		  &res.smccc);
-
-	if (res.result.build_id)
-		pr_info("revision %lu.%lu (%08lx)", res.result.major,
-			res.result.minor, res.result.build_id);
-	else
-		pr_info("revision %lu.%lu", res.result.major, res.result.minor);
-}
-
-static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
-{
-	union {
-		struct arm_smccc_res smccc;
-		struct optee_smc_calls_revision_result result;
-	} res;
-
-	invoke_fn(OPTEE_SMC_CALLS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
-
-	if (res.result.major == OPTEE_MSG_REVISION_MAJOR &&
-	    (int)res.result.minor >= OPTEE_MSG_REVISION_MINOR)
-		return true;
-	return false;
-}
-
-static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
-					    u32 *sec_caps)
-{
-	union {
-		struct arm_smccc_res smccc;
-		struct optee_smc_exchange_capabilities_result result;
-	} res;
-	u32 a1 = 0;
-
-	/*
-	 * TODO This isn't enough to tell if it's UP system (from kernel
-	 * point of view) or not, is_smp() returns the the information
-	 * needed, but can't be called directly from here.
-	 */
-	if (!IS_ENABLED(CONFIG_SMP) || nr_cpu_ids == 1)
-		a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR;
-
-	invoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES, a1, 0, 0, 0, 0, 0, 0,
-		  &res.smccc);
-
-	if (res.result.status != OPTEE_SMC_RETURN_OK)
-		return false;
-
-	*sec_caps = res.result.capabilities;
-	return true;
-}
-
-static struct tee_shm_pool *optee_config_dyn_shm(void)
-{
-	struct tee_shm_pool_mgr *priv_mgr;
-	struct tee_shm_pool_mgr *dmabuf_mgr;
-	void *rc;
-
-	rc = optee_shm_pool_alloc_pages();
-	if (IS_ERR(rc))
-		return rc;
-	priv_mgr = rc;
-
-	rc = optee_shm_pool_alloc_pages();
-	if (IS_ERR(rc)) {
-		tee_shm_pool_mgr_destroy(priv_mgr);
-		return rc;
-	}
-	dmabuf_mgr = rc;
-
-	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
-	if (IS_ERR(rc)) {
-		tee_shm_pool_mgr_destroy(priv_mgr);
-		tee_shm_pool_mgr_destroy(dmabuf_mgr);
-	}
-
-	return rc;
-}
-
-static struct tee_shm_pool *
-optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
-{
-	union {
-		struct arm_smccc_res smccc;
-		struct optee_smc_get_shm_config_result result;
-	} res;
-	unsigned long vaddr;
-	phys_addr_t paddr;
-	size_t size;
-	phys_addr_t begin;
-	phys_addr_t end;
-	void *va;
-	struct tee_shm_pool_mgr *priv_mgr;
-	struct tee_shm_pool_mgr *dmabuf_mgr;
-	void *rc;
-	const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
-
-	invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
-	if (res.result.status != OPTEE_SMC_RETURN_OK) {
-		pr_err("static shm service not available\n");
-		return ERR_PTR(-ENOENT);
-	}
-
-	if (res.result.settings != OPTEE_SMC_SHM_CACHED) {
-		pr_err("only normal cached shared memory supported\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	begin = roundup(res.result.start, PAGE_SIZE);
-	end = rounddown(res.result.start + res.result.size, PAGE_SIZE);
-	paddr = begin;
-	size = end - begin;
-
-	if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
-		pr_err("too small shared memory area\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	va = memremap(paddr, size, MEMREMAP_WB);
-	if (!va) {
-		pr_err("shared memory ioremap failed\n");
-		return ERR_PTR(-EINVAL);
-	}
-	vaddr = (unsigned long)va;
-
-	rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
-					    3 /* 8 bytes aligned */);
-	if (IS_ERR(rc))
-		goto err_memunmap;
-	priv_mgr = rc;
-
-	vaddr += sz;
-	paddr += sz;
-	size -= sz;
-
-	rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT);
-	if (IS_ERR(rc))
-		goto err_free_priv_mgr;
-	dmabuf_mgr = rc;
-
-	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
-	if (IS_ERR(rc))
-		goto err_free_dmabuf_mgr;
-
-	*memremaped_shm = va;
-
-	return rc;
-
-err_free_dmabuf_mgr:
-	tee_shm_pool_mgr_destroy(dmabuf_mgr);
-err_free_priv_mgr:
-	tee_shm_pool_mgr_destroy(priv_mgr);
-err_memunmap:
-	memunmap(va);
-	return rc;
-}
-
-/* Simple wrapper functions to be able to use a function pointer */
-static void optee_smccc_smc(unsigned long a0, unsigned long a1,
-			    unsigned long a2, unsigned long a3,
-			    unsigned long a4, unsigned long a5,
-			    unsigned long a6, unsigned long a7,
-			    struct arm_smccc_res *res)
-{
-	arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
-}
-
-static void optee_smccc_hvc(unsigned long a0, unsigned long a1,
-			    unsigned long a2, unsigned long a3,
-			    unsigned long a4, unsigned long a5,
-			    unsigned long a6, unsigned long a7,
-			    struct arm_smccc_res *res)
-{
-	arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
-}
-
-static optee_invoke_fn *get_invoke_func(struct device *dev)
-{
-	const char *method;
-
-	pr_info("probing for conduit method.\n");
-
-	if (device_property_read_string(dev, "method", &method)) {
-		pr_warn("missing \"method\" property\n");
-		return ERR_PTR(-ENXIO);
-	}
-
-	if (!strcmp("hvc", method))
-		return optee_smccc_hvc;
-	else if (!strcmp("smc", method))
-		return optee_smccc_smc;
-
-	pr_warn("invalid \"method\" property: %s\n", method);
-	return ERR_PTR(-EINVAL);
-}
-
-static int optee_remove(struct platform_device *pdev)
+void optee_remove_common(struct optee *optee)
 {
-	struct optee *optee = platform_get_drvdata(pdev);
-
-	/*
-	 * Ask OP-TEE to free all cached shared memory objects to decrease
-	 * reference counters and also avoid wild pointers in secure world
-	 * into the old shared memory range.
-	 */
-	optee_disable_shm_cache(optee);
-
 	/*
 	 * The two devices have to be unregistered before we can free the
 	 * other resources.
@@ -625,150 +155,22 @@ static int optee_remove(struct platform_device *pdev)
 	tee_device_unregister(optee->teedev);
 
 	tee_shm_pool_free(optee->pool);
-	if (optee->memremaped_shm)
-		memunmap(optee->memremaped_shm);
 	optee_wait_queue_exit(&optee->wait_queue);
 	optee_supp_uninit(&optee->supp);
 	mutex_destroy(&optee->call_queue.mutex);
-
-	kfree(optee);
-
-	return 0;
 }
 
-static int optee_probe(struct platform_device *pdev)
+static int optee_core_init(void)
 {
-	optee_invoke_fn *invoke_fn;
-	struct tee_shm_pool *pool = ERR_PTR(-EINVAL);
-	struct optee *optee = NULL;
-	void *memremaped_shm = NULL;
-	struct tee_device *teedev;
-	u32 sec_caps;
-	int rc;
-
-	invoke_fn = get_invoke_func(&pdev->dev);
-	if (IS_ERR(invoke_fn))
-		return PTR_ERR(invoke_fn);
-
-	if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
-		pr_warn("api uid mismatch\n");
-		return -EINVAL;
-	}
-
-	optee_msg_get_os_revision(invoke_fn);
-
-	if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
-		pr_warn("api revision mismatch\n");
-		return -EINVAL;
-	}
-
-	if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
-		pr_warn("capabilities mismatch\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * Try to use dynamic shared memory if possible
-	 */
-	if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
-		pool = optee_config_dyn_shm();
-
-	/*
-	 * If dynamic shared memory is not available or failed - try static one
-	 */
-	if (IS_ERR(pool) && (sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
-		pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
-
-	if (IS_ERR(pool))
-		return PTR_ERR(pool);
-
-	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
-	if (!optee) {
-		rc = -ENOMEM;
-		goto err;
-	}
-
-	optee->ops = &optee_ops;
-	optee->invoke_fn = invoke_fn;
-	optee->sec_caps = sec_caps;
-
-	teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
-	if (IS_ERR(teedev)) {
-		rc = PTR_ERR(teedev);
-		goto err;
-	}
-	optee->teedev = teedev;
-
-	teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee);
-	if (IS_ERR(teedev)) {
-		rc = PTR_ERR(teedev);
-		goto err;
-	}
-	optee->supp_teedev = teedev;
-
-	rc = tee_device_register(optee->teedev);
-	if (rc)
-		goto err;
-
-	rc = tee_device_register(optee->supp_teedev);
-	if (rc)
-		goto err;
-
-	mutex_init(&optee->call_queue.mutex);
-	INIT_LIST_HEAD(&optee->call_queue.waiters);
-	optee_wait_queue_init(&optee->wait_queue);
-	optee_supp_init(&optee->supp);
-	optee->memremaped_shm = memremaped_shm;
-	optee->pool = pool;
-
-	optee_enable_shm_cache(optee);
-
-	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
-		pr_info("dynamic shared memory is enabled\n");
-
-	platform_set_drvdata(pdev, optee);
-
-	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
-	if (rc) {
-		optee_remove(pdev);
-		return rc;
-	}
-
-	pr_info("initialized driver\n");
-	return 0;
-err:
-	if (optee) {
-		/*
-		 * tee_device_unregister() is safe to call even if the
-		 * devices hasn't been registered with
-		 * tee_device_register() yet.
-		 */
-		tee_device_unregister(optee->supp_teedev);
-		tee_device_unregister(optee->teedev);
-		kfree(optee);
-	}
-	if (pool)
-		tee_shm_pool_free(pool);
-	if (memremaped_shm)
-		memunmap(memremaped_shm);
-	return rc;
+	return optee_smc_abi_register();
 }
+module_init(optee_core_init);
 
-static const struct of_device_id optee_dt_match[] = {
-	{ .compatible = "linaro,optee-tz" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, optee_dt_match);
-
-static struct platform_driver optee_driver = {
-	.probe  = optee_probe,
-	.remove = optee_remove,
-	.driver = {
-		.name = "optee",
-		.of_match_table = optee_dt_match,
-	},
-};
-module_platform_driver(optee_driver);
+static void optee_core_exit(void)
+{
+	optee_smc_abi_unregister();
+}
+module_exit(optee_core_exit);
 
 MODULE_AUTHOR("Linaro");
 MODULE_DESCRIPTION("OP-TEE driver");
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index c5741e96e967..ca0213e330b5 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -12,6 +12,8 @@
 #include <linux/types.h>
 #include "optee_msg.h"
 
+#define DRIVER_NAME "optee"
+
 #define OPTEE_MAX_ARG_SIZE	1024
 
 /* Some Global Platform error codes used in this driver */
@@ -29,6 +31,11 @@ typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long,
 				unsigned long, unsigned long,
 				struct arm_smccc_res *);
 
+struct optee_call_waiter {
+	struct list_head list_node;
+	struct completion c;
+};
+
 struct optee_call_queue {
 	/* Serializes access to this struct */
 	struct mutex mutex;
@@ -66,6 +73,19 @@ struct optee_supp {
 	struct completion reqs_c;
 };
 
+/**
+ * struct optee_smc - SMC ABI specifics
+ * @invoke_fn:		function to issue smc or hvc
+ * @memremaped_shm	virtual address of memory in shared memory pool
+ * @sec_caps:		secure world capabilities defined by
+ *			OPTEE_SMC_SEC_CAP_* in optee_smc.h
+ */
+struct optee_smc {
+	optee_invoke_fn *invoke_fn;
+	void *memremaped_shm;
+	u32 sec_caps;
+};
+
 struct optee;
 
 /**
@@ -95,15 +115,12 @@ struct optee_ops {
  * @ops:		internal callbacks for different ways to reach secure
  *			world
  * @teedev:		client device
- * @invoke_fn:		function to issue smc or hvc
+ * @smc:		specific to SMC ABI
  * @call_queue:		queue of threads waiting to call @invoke_fn
  * @wait_queue:		queue of threads from secure world waiting for a
  *			secure world sync object
  * @supp:		supplicant synchronization struct for RPC to supplicant
  * @pool:		shared memory pool
- * @memremaped_shm	virtual address of memory in shared memory pool
- * @sec_caps:		secure world capabilities defined by
- *			OPTEE_SMC_SEC_CAP_* in optee_smc.h
  * @scan_bus_done	flag if device registation was already done.
  * @scan_bus_wq		workqueue to scan optee bus and register optee drivers
  * @scan_bus_work	workq to scan optee bus and register optee drivers
@@ -112,13 +129,11 @@ struct optee {
 	struct tee_device *supp_teedev;
 	struct tee_device *teedev;
 	const struct optee_ops *ops;
-	optee_invoke_fn *invoke_fn;
+	struct optee_smc smc;
 	struct optee_call_queue call_queue;
 	struct optee_wait_queue wait_queue;
 	struct optee_supp supp;
 	struct tee_shm_pool *pool;
-	void *memremaped_shm;
-	u32 sec_caps;
 	bool   scan_bus_done;
 	struct workqueue_struct *scan_bus_wq;
 	struct work_struct scan_bus_work;
@@ -153,10 +168,6 @@ struct optee_call_ctx {
 	size_t num_entries;
 };
 
-void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
-		      struct optee_call_ctx *call_ctx);
-void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx);
-
 void optee_wait_queue_init(struct optee_wait_queue *wq);
 void optee_wait_queue_exit(struct optee_wait_queue *wq);
 
@@ -174,7 +185,6 @@ int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
 int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
 		    struct tee_param *param);
 
-int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg);
 int optee_open_session(struct tee_context *ctx,
 		       struct tee_ioctl_open_session_arg *arg,
 		       struct tee_param *param);
@@ -184,27 +194,58 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 		      struct tee_param *param);
 int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
 
-void optee_enable_shm_cache(struct optee *optee);
-void optee_disable_shm_cache(struct optee *optee);
+#define PTA_CMD_GET_DEVICES		0x0
+#define PTA_CMD_GET_DEVICES_SUPP	0x1
+int optee_enumerate_devices(u32 func);
 
-int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
-		       struct page **pages, size_t num_pages,
-		       unsigned long start);
-int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm);
+int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
+			       struct tee_shm *shm, size_t size,
+			       int (*shm_register)(struct tee_context *ctx,
+						   struct tee_shm *shm,
+						   struct page **pages,
+						   size_t num_pages,
+						   unsigned long start));
 
-int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
-			    struct page **pages, size_t num_pages,
-			    unsigned long start);
-int optee_shm_unregister_supp(struct tee_context *ctx, struct tee_shm *shm);
 
-u64 *optee_allocate_pages_list(size_t num_entries);
-void optee_free_pages_list(void *array, size_t num_entries);
-void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
-			   size_t page_offset);
+void optee_remove_common(struct optee *optee);
+int optee_open(struct tee_context *ctx, bool cap_memref_null);
+void optee_release(struct tee_context *ctx);
+void optee_release_supp(struct tee_context *ctx);
 
-#define PTA_CMD_GET_DEVICES		0x0
-#define PTA_CMD_GET_DEVICES_SUPP	0x1
-int optee_enumerate_devices(u32 func);
+static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr,
+					      const struct optee_msg_param *mp)
+{
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+	p->u.value.a = mp->u.value.a;
+	p->u.value.b = mp->u.value.b;
+	p->u.value.c = mp->u.value.c;
+}
+
+static inline void optee_to_msg_param_value(struct optee_msg_param *mp,
+					    const struct tee_param *p)
+{
+	mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+	mp->u.value.a = p->u.value.a;
+	mp->u.value.b = p->u.value.b;
+	mp->u.value.c = p->u.value.c;
+}
+
+void optee_cq_wait_init(struct optee_call_queue *cq,
+			struct optee_call_waiter *w);
+void optee_cq_wait_for_completion(struct optee_call_queue *cq,
+				  struct optee_call_waiter *w);
+void optee_cq_wait_final(struct optee_call_queue *cq,
+			 struct optee_call_waiter *w);
+int optee_check_mem_type(unsigned long start, size_t num_pages);
+struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params,
+				  struct optee_msg_arg **msg_arg);
+
+struct tee_shm *optee_rpc_cmd_alloc_suppl(struct tee_context *ctx, size_t sz);
+void optee_rpc_cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm);
+void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
+		   struct optee_msg_arg *arg);
 
 /*
  * Small helpers
@@ -221,4 +262,8 @@ static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
 	*reg1 = val;
 }
 
+/* Registration of the ABIs */
+int optee_smc_abi_register(void);
+void optee_smc_abi_unregister(void);
+
 #endif /*OPTEE_PRIVATE_H*/
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index 39562fb6841e..cd642e340eaf 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -6,12 +6,10 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/delay.h>
-#include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/tee_drv.h>
 #include "optee_private.h"
-#include "optee_smc.h"
 #include "optee_rpc_cmd.h"
 
 struct wq_entry {
@@ -266,7 +264,7 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
 	kfree(params);
 }
 
-static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
+struct tee_shm *optee_rpc_cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
 {
 	u32 ret;
 	struct tee_param param;
@@ -289,103 +287,7 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
 	return shm;
 }
 
-static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
-					  struct optee_msg_arg *arg,
-					  struct optee_call_ctx *call_ctx)
-{
-	phys_addr_t pa;
-	struct tee_shm *shm;
-	size_t sz;
-	size_t n;
-
-	arg->ret_origin = TEEC_ORIGIN_COMMS;
-
-	if (!arg->num_params ||
-	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-		return;
-	}
-
-	for (n = 1; n < arg->num_params; n++) {
-		if (arg->params[n].attr != OPTEE_MSG_ATTR_TYPE_NONE) {
-			arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-			return;
-		}
-	}
-
-	sz = arg->params[0].u.value.b;
-	switch (arg->params[0].u.value.a) {
-	case OPTEE_RPC_SHM_TYPE_APPL:
-		shm = cmd_alloc_suppl(ctx, sz);
-		break;
-	case OPTEE_RPC_SHM_TYPE_KERNEL:
-		shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED);
-		break;
-	default:
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-		return;
-	}
-
-	if (IS_ERR(shm)) {
-		arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
-		return;
-	}
-
-	if (tee_shm_get_pa(shm, 0, &pa)) {
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-		goto bad;
-	}
-
-	sz = tee_shm_get_size(shm);
-
-	if (tee_shm_is_registered(shm)) {
-		struct page **pages;
-		u64 *pages_list;
-		size_t page_num;
-
-		pages = tee_shm_get_pages(shm, &page_num);
-		if (!pages || !page_num) {
-			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
-			goto bad;
-		}
-
-		pages_list = optee_allocate_pages_list(page_num);
-		if (!pages_list) {
-			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
-			goto bad;
-		}
-
-		call_ctx->pages_list = pages_list;
-		call_ctx->num_entries = page_num;
-
-		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
-				      OPTEE_MSG_ATTR_NONCONTIG;
-		/*
-		 * In the least bits of u.tmem.buf_ptr we store buffer offset
-		 * from 4k page, as described in OP-TEE ABI.
-		 */
-		arg->params[0].u.tmem.buf_ptr = virt_to_phys(pages_list) |
-			(tee_shm_get_page_offset(shm) &
-			 (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
-		arg->params[0].u.tmem.size = tee_shm_get_size(shm);
-		arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
-
-		optee_fill_pages_list(pages_list, pages, page_num,
-				      tee_shm_get_page_offset(shm));
-	} else {
-		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT;
-		arg->params[0].u.tmem.buf_ptr = pa;
-		arg->params[0].u.tmem.size = sz;
-		arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
-	}
-
-	arg->ret = TEEC_SUCCESS;
-	return;
-bad:
-	tee_shm_free(shm);
-}
-
-static void cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
+void optee_rpc_cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
 {
 	struct tee_param param;
 
@@ -410,60 +312,9 @@ static void cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
 	optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_FREE, 1, &param);
 }
 
-static void handle_rpc_func_cmd_shm_free(struct tee_context *ctx,
-					 struct optee_msg_arg *arg)
-{
-	struct tee_shm *shm;
-
-	arg->ret_origin = TEEC_ORIGIN_COMMS;
-
-	if (arg->num_params != 1 ||
-	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-		return;
-	}
-
-	shm = (struct tee_shm *)(unsigned long)arg->params[0].u.value.b;
-	switch (arg->params[0].u.value.a) {
-	case OPTEE_RPC_SHM_TYPE_APPL:
-		cmd_free_suppl(ctx, shm);
-		break;
-	case OPTEE_RPC_SHM_TYPE_KERNEL:
-		tee_shm_free(shm);
-		break;
-	default:
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-	}
-	arg->ret = TEEC_SUCCESS;
-}
-
-static void free_pages_list(struct optee_call_ctx *call_ctx)
-{
-	if (call_ctx->pages_list) {
-		optee_free_pages_list(call_ctx->pages_list,
-				      call_ctx->num_entries);
-		call_ctx->pages_list = NULL;
-		call_ctx->num_entries = 0;
-	}
-}
-
-void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx)
-{
-	free_pages_list(call_ctx);
-}
-
-static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
-				struct tee_shm *shm,
-				struct optee_call_ctx *call_ctx)
+void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
+		   struct optee_msg_arg *arg)
 {
-	struct optee_msg_arg *arg;
-
-	arg = tee_shm_get_va(shm, 0);
-	if (IS_ERR(arg)) {
-		pr_err("%s: tee_shm_get_va %p failed\n", __func__, shm);
-		return;
-	}
-
 	switch (arg->cmd) {
 	case OPTEE_RPC_CMD_GET_TIME:
 		handle_rpc_func_cmd_get_time(arg);
@@ -474,13 +325,6 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
 	case OPTEE_RPC_CMD_SUSPEND:
 		handle_rpc_func_cmd_wait(arg);
 		break;
-	case OPTEE_RPC_CMD_SHM_ALLOC:
-		free_pages_list(call_ctx);
-		handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
-		break;
-	case OPTEE_RPC_CMD_SHM_FREE:
-		handle_rpc_func_cmd_shm_free(ctx, arg);
-		break;
 	case OPTEE_RPC_CMD_I2C_TRANSFER:
 		handle_rpc_func_cmd_i2c_transfer(ctx, arg);
 		break;
@@ -489,57 +333,4 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
 	}
 }
 
-/**
- * optee_handle_rpc() - handle RPC from secure world
- * @ctx:	context doing the RPC
- * @param:	value of registers for the RPC
- * @call_ctx:	call context. Preserved during one OP-TEE invocation
- *
- * Result of RPC is written back into @param.
- */
-void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
-		      struct optee_call_ctx *call_ctx)
-{
-	struct tee_device *teedev = ctx->teedev;
-	struct optee *optee = tee_get_drvdata(teedev);
-	struct tee_shm *shm;
-	phys_addr_t pa;
-
-	switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
-	case OPTEE_SMC_RPC_FUNC_ALLOC:
-		shm = tee_shm_alloc(ctx, param->a1, TEE_SHM_MAPPED);
-		if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
-			reg_pair_from_64(&param->a1, &param->a2, pa);
-			reg_pair_from_64(&param->a4, &param->a5,
-					 (unsigned long)shm);
-		} else {
-			param->a1 = 0;
-			param->a2 = 0;
-			param->a4 = 0;
-			param->a5 = 0;
-		}
-		break;
-	case OPTEE_SMC_RPC_FUNC_FREE:
-		shm = reg_pair_to_ptr(param->a1, param->a2);
-		tee_shm_free(shm);
-		break;
-	case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR:
-		/*
-		 * A foreign interrupt was raised while secure world was
-		 * executing, since they are handled in Linux a dummy RPC is
-		 * performed to let Linux take the interrupt through the normal
-		 * vector.
-		 */
-		break;
-	case OPTEE_SMC_RPC_FUNC_CMD:
-		shm = reg_pair_to_ptr(param->a1, param->a2);
-		handle_rpc_func_cmd(ctx, optee, shm, call_ctx);
-		break;
-	default:
-		pr_warn("Unknown RPC func 0x%x\n",
-			(u32)OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0));
-		break;
-	}
 
-	param->a0 = OPTEE_SMC_CALL_RETURN_FROM_RPC;
-}
diff --git a/drivers/tee/optee/shm_pool.c b/drivers/tee/optee/shm_pool.c
deleted file mode 100644
index d767eebf30bd..000000000000
--- a/drivers/tee/optee/shm_pool.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2015, Linaro Limited
- * Copyright (c) 2017, EPAM Systems
- */
-#include <linux/device.h>
-#include <linux/dma-buf.h>
-#include <linux/genalloc.h>
-#include <linux/slab.h>
-#include <linux/tee_drv.h>
-#include "optee_private.h"
-#include "optee_smc.h"
-#include "shm_pool.h"
-
-static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
-			 struct tee_shm *shm, size_t size)
-{
-	unsigned int order = get_order(size);
-	struct page *page;
-	int rc = 0;
-
-	page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
-	if (!page)
-		return -ENOMEM;
-
-	shm->kaddr = page_address(page);
-	shm->paddr = page_to_phys(page);
-	shm->size = PAGE_SIZE << order;
-
-	if (shm->flags & TEE_SHM_DMA_BUF) {
-		unsigned int nr_pages = 1 << order, i;
-		struct page **pages;
-
-		pages = kcalloc(nr_pages, sizeof(pages), GFP_KERNEL);
-		if (!pages)
-			return -ENOMEM;
-
-		for (i = 0; i < nr_pages; i++) {
-			pages[i] = page;
-			page++;
-		}
-
-		shm->flags |= TEE_SHM_REGISTER;
-		rc = optee_shm_register(shm->ctx, shm, pages, nr_pages,
-					(unsigned long)shm->kaddr);
-		kfree(pages);
-	}
-
-	return rc;
-}
-
-static void pool_op_free(struct tee_shm_pool_mgr *poolm,
-			 struct tee_shm *shm)
-{
-	if (shm->flags & TEE_SHM_DMA_BUF)
-		optee_shm_unregister(shm->ctx, shm);
-
-	free_pages((unsigned long)shm->kaddr, get_order(shm->size));
-	shm->kaddr = NULL;
-}
-
-static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
-{
-	kfree(poolm);
-}
-
-static const struct tee_shm_pool_mgr_ops pool_ops = {
-	.alloc = pool_op_alloc,
-	.free = pool_op_free,
-	.destroy_poolmgr = pool_op_destroy_poolmgr,
-};
-
-/**
- * optee_shm_pool_alloc_pages() - create page-based allocator pool
- *
- * This pool is used when OP-TEE supports dymanic SHM. In this case
- * command buffers and such are allocated from kernel's own memory.
- */
-struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void)
-{
-	struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
-
-	if (!mgr)
-		return ERR_PTR(-ENOMEM);
-
-	mgr->ops = &pool_ops;
-
-	return mgr;
-}
diff --git a/drivers/tee/optee/shm_pool.h b/drivers/tee/optee/shm_pool.h
deleted file mode 100644
index 28109d991c4b..000000000000
--- a/drivers/tee/optee/shm_pool.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2015, Linaro Limited
- * Copyright (c) 2016, EPAM Systems
- */
-
-#ifndef SHM_POOL_H
-#define SHM_POOL_H
-
-#include <linux/tee_drv.h>
-
-struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void);
-
-#endif
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
new file mode 100644
index 000000000000..2cbd3de74c31
--- /dev/null
+++ b/drivers/tee/optee/smc_abi.c
@@ -0,0 +1,1299 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015-2021, Linaro Limited
+ * Copyright (c) 2016, EPAM Systems
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/arm-smccc.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include "optee_private.h"
+#include "optee_smc.h"
+#include "optee_rpc_cmd.h"
+#define CREATE_TRACE_POINTS
+#include "optee_trace.h"
+
+/*
+ * This file implement the SMC ABI used when communicating with secure world
+ * OP-TEE OS via raw SMCs.
+ * This file is divided into the follow sections:
+ * 1. Convert between struct tee_param and struct optee_msg_param
+ * 2. Low level support functions to register shared memory in secure world
+ * 3. Dynamic shared memory pool based on alloc_pages()
+ * 4. Do a normal scheduled call into secure world
+ * 5. Driver initialization.
+ */
+
+#define OPTEE_SHM_NUM_PRIV_PAGES	CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
+
+/*
+ * 1. Convert between struct tee_param and struct optee_msg_param
+ *
+ * optee_from_msg_param() and optee_to_msg_param() are the main
+ * functions.
+ */
+
+static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
+				  const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm;
+	phys_addr_t pa;
+	int rc;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
+	p->u.memref.size = mp->u.tmem.size;
+	shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
+	if (!shm) {
+		p->u.memref.shm_offs = 0;
+		p->u.memref.shm = NULL;
+		return 0;
+	}
+
+	rc = tee_shm_get_pa(shm, 0, &pa);
+	if (rc)
+		return rc;
+
+	p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
+	p->u.memref.shm = shm;
+
+	/* Check that the memref is covered by the shm object */
+	if (p->u.memref.size) {
+		size_t o = p->u.memref.shm_offs +
+			   p->u.memref.size - 1;
+
+		rc = tee_shm_get_pa(shm, o, NULL);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
+
+static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
+				   const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
+	p->u.memref.size = mp->u.rmem.size;
+	shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
+
+	if (shm) {
+		p->u.memref.shm_offs = mp->u.rmem.offs;
+		p->u.memref.shm = shm;
+	} else {
+		p->u.memref.shm_offs = 0;
+		p->u.memref.shm = NULL;
+	}
+}
+
+/**
+ * optee_from_msg_param() - convert from OPTEE_MSG parameters to
+ *			    struct tee_param
+ * @optee:	main service struct
+ * @params:	subsystem internal parameter representation
+ * @num_params:	number of elements in the parameter arrays
+ * @msg_params:	OPTEE_MSG parameters
+ * Returns 0 on success or <0 on failure
+ */
+static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
+				size_t num_params,
+				const struct optee_msg_param *msg_params)
+{
+	int rc;
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_param *p = params + n;
+		const struct optee_msg_param *mp = msg_params + n;
+		u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
+
+		switch (attr) {
+		case OPTEE_MSG_ATTR_TYPE_NONE:
+			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
+			memset(&p->u, 0, sizeof(p->u));
+			break;
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
+			optee_from_msg_param_value(p, attr, mp);
+			break;
+		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
+			rc = from_msg_param_tmp_mem(p, attr, mp);
+			if (rc)
+				return rc;
+			break;
+		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
+			from_msg_param_reg_mem(p, attr, mp);
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
+				const struct tee_param *p)
+{
+	int rc;
+	phys_addr_t pa;
+
+	mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
+
+	mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
+	mp->u.tmem.size = p->u.memref.size;
+
+	if (!p->u.memref.shm) {
+		mp->u.tmem.buf_ptr = 0;
+		return 0;
+	}
+
+	rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
+	if (rc)
+		return rc;
+
+	mp->u.tmem.buf_ptr = pa;
+	mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
+		    OPTEE_MSG_ATTR_CACHE_SHIFT;
+
+	return 0;
+}
+
+static int to_msg_param_reg_mem(struct optee_msg_param *mp,
+				const struct tee_param *p)
+{
+	mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
+
+	mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
+	mp->u.rmem.size = p->u.memref.size;
+	mp->u.rmem.offs = p->u.memref.shm_offs;
+	return 0;
+}
+
+/**
+ * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
+ * @optee:	main service struct
+ * @msg_params:	OPTEE_MSG parameters
+ * @num_params:	number of elements in the parameter arrays
+ * @params:	subsystem itnernal parameter representation
+ * Returns 0 on success or <0 on failure
+ */
+static int optee_to_msg_param(struct optee *optee,
+			      struct optee_msg_param *msg_params,
+			      size_t num_params, const struct tee_param *params)
+{
+	int rc;
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		const struct tee_param *p = params + n;
+		struct optee_msg_param *mp = msg_params + n;
+
+		switch (p->attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
+			mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
+			memset(&mp->u, 0, sizeof(mp->u));
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			optee_to_msg_param_value(mp, p);
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			if (tee_shm_is_registered(p->u.memref.shm))
+				rc = to_msg_param_reg_mem(mp, p);
+			else
+				rc = to_msg_param_tmp_mem(mp, p);
+			if (rc)
+				return rc;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+/*
+ * 2. Low level support functions to register shared memory in secure world
+ *
+ * Functions to enable/disable shared memory caching in secure world, that
+ * is, lazy freeing of previously allocated shared memory. Freeing is
+ * performed when a request has been compled.
+ *
+ * Functions to register and unregister shared memory both for normal
+ * clients and for tee-supplicant.
+ */
+
+/**
+ * optee_enable_shm_cache() - Enables caching of some shared memory allocation
+ *			      in OP-TEE
+ * @optee:	main service struct
+ */
+static void optee_enable_shm_cache(struct optee *optee)
+{
+	struct optee_call_waiter w;
+
+	/* We need to retry until secure world isn't busy. */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		struct arm_smccc_res res;
+
+		optee->smc.invoke_fn(OPTEE_SMC_ENABLE_SHM_CACHE,
+				     0, 0, 0, 0, 0, 0, 0, &res);
+		if (res.a0 == OPTEE_SMC_RETURN_OK)
+			break;
+		optee_cq_wait_for_completion(&optee->call_queue, &w);
+	}
+	optee_cq_wait_final(&optee->call_queue, &w);
+}
+
+/**
+ * optee_disable_shm_cache() - Disables caching of some shared memory allocation
+ *			      in OP-TEE
+ * @optee:	main service struct
+ */
+static void optee_disable_shm_cache(struct optee *optee)
+{
+	struct optee_call_waiter w;
+
+	/* We need to retry until secure world isn't busy. */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		union {
+			struct arm_smccc_res smccc;
+			struct optee_smc_disable_shm_cache_result result;
+		} res;
+
+		optee->smc.invoke_fn(OPTEE_SMC_DISABLE_SHM_CACHE,
+				     0, 0, 0, 0, 0, 0, 0, &res.smccc);
+		if (res.result.status == OPTEE_SMC_RETURN_ENOTAVAIL)
+			break; /* All shm's freed */
+		if (res.result.status == OPTEE_SMC_RETURN_OK) {
+			struct tee_shm *shm;
+
+			shm = reg_pair_to_ptr(res.result.shm_upper32,
+					      res.result.shm_lower32);
+			tee_shm_free(shm);
+		} else {
+			optee_cq_wait_for_completion(&optee->call_queue, &w);
+		}
+	}
+	optee_cq_wait_final(&optee->call_queue, &w);
+}
+
+#define PAGELIST_ENTRIES_PER_PAGE				\
+	((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1)
+
+/*
+ * The final entry in each pagelist page is a pointer to the next
+ * pagelist page.
+ */
+static size_t get_pages_list_size(size_t num_entries)
+{
+	int pages = DIV_ROUND_UP(num_entries, PAGELIST_ENTRIES_PER_PAGE);
+
+	return pages * OPTEE_MSG_NONCONTIG_PAGE_SIZE;
+}
+
+static u64 *optee_allocate_pages_list(size_t num_entries)
+{
+	return alloc_pages_exact(get_pages_list_size(num_entries), GFP_KERNEL);
+}
+
+static void optee_free_pages_list(void *list, size_t num_entries)
+{
+	free_pages_exact(list, get_pages_list_size(num_entries));
+}
+
+/**
+ * optee_fill_pages_list() - write list of user pages to given shared
+ * buffer.
+ *
+ * @dst: page-aligned buffer where list of pages will be stored
+ * @pages: array of pages that represents shared buffer
+ * @num_pages: number of entries in @pages
+ * @page_offset: offset of user buffer from page start
+ *
+ * @dst should be big enough to hold list of user page addresses and
+ *	links to the next pages of buffer
+ */
+static void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
+				  size_t page_offset)
+{
+	int n = 0;
+	phys_addr_t optee_page;
+	/*
+	 * Refer to OPTEE_MSG_ATTR_NONCONTIG description in optee_msg.h
+	 * for details.
+	 */
+	struct {
+		u64 pages_list[PAGELIST_ENTRIES_PER_PAGE];
+		u64 next_page_data;
+	} *pages_data;
+
+	/*
+	 * Currently OP-TEE uses 4k page size and it does not looks
+	 * like this will change in the future.  On other hand, there are
+	 * no know ARM architectures with page size < 4k.
+	 * Thus the next built assert looks redundant. But the following
+	 * code heavily relies on this assumption, so it is better be
+	 * safe than sorry.
+	 */
+	BUILD_BUG_ON(PAGE_SIZE < OPTEE_MSG_NONCONTIG_PAGE_SIZE);
+
+	pages_data = (void *)dst;
+	/*
+	 * If linux page is bigger than 4k, and user buffer offset is
+	 * larger than 4k/8k/12k/etc this will skip first 4k pages,
+	 * because they bear no value data for OP-TEE.
+	 */
+	optee_page = page_to_phys(*pages) +
+		round_down(page_offset, OPTEE_MSG_NONCONTIG_PAGE_SIZE);
+
+	while (true) {
+		pages_data->pages_list[n++] = optee_page;
+
+		if (n == PAGELIST_ENTRIES_PER_PAGE) {
+			pages_data->next_page_data =
+				virt_to_phys(pages_data + 1);
+			pages_data++;
+			n = 0;
+		}
+
+		optee_page += OPTEE_MSG_NONCONTIG_PAGE_SIZE;
+		if (!(optee_page & ~PAGE_MASK)) {
+			if (!--num_pages)
+				break;
+			pages++;
+			optee_page = page_to_phys(*pages);
+		}
+	}
+}
+
+static int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
+			      struct page **pages, size_t num_pages,
+			      unsigned long start)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm_arg;
+	u64 *pages_list;
+	int rc;
+
+	if (!num_pages)
+		return -EINVAL;
+
+	rc = optee_check_mem_type(start, num_pages);
+	if (rc)
+		return rc;
+
+	pages_list = optee_allocate_pages_list(num_pages);
+	if (!pages_list)
+		return -ENOMEM;
+
+	shm_arg = optee_get_msg_arg(ctx, 1, &msg_arg);
+	if (IS_ERR(shm_arg)) {
+		rc = PTR_ERR(shm_arg);
+		goto out;
+	}
+
+	optee_fill_pages_list(pages_list, pages, num_pages,
+			      tee_shm_get_page_offset(shm));
+
+	msg_arg->cmd = OPTEE_MSG_CMD_REGISTER_SHM;
+	msg_arg->params->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
+				OPTEE_MSG_ATTR_NONCONTIG;
+	msg_arg->params->u.tmem.shm_ref = (unsigned long)shm;
+	msg_arg->params->u.tmem.size = tee_shm_get_size(shm);
+	/*
+	 * In the least bits of msg_arg->params->u.tmem.buf_ptr we
+	 * store buffer offset from 4k page, as described in OP-TEE ABI.
+	 */
+	msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
+	  (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
+
+	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
+	    msg_arg->ret != TEEC_SUCCESS)
+		rc = -EINVAL;
+
+	tee_shm_free(shm_arg);
+out:
+	optee_free_pages_list(pages_list, num_pages);
+	return rc;
+}
+
+static int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm_arg;
+	int rc = 0;
+
+	shm_arg = optee_get_msg_arg(ctx, 1, &msg_arg);
+	if (IS_ERR(shm_arg))
+		return PTR_ERR(shm_arg);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_UNREGISTER_SHM;
+
+	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
+	msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;
+
+	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
+	    msg_arg->ret != TEEC_SUCCESS)
+		rc = -EINVAL;
+	tee_shm_free(shm_arg);
+	return rc;
+}
+
+static int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
+				   struct page **pages, size_t num_pages,
+				   unsigned long start)
+{
+	/*
+	 * We don't want to register supplicant memory in OP-TEE.
+	 * Instead information about it will be passed in RPC code.
+	 */
+	return optee_check_mem_type(start, num_pages);
+}
+
+static int optee_shm_unregister_supp(struct tee_context *ctx,
+				     struct tee_shm *shm)
+{
+	return 0;
+}
+
+/*
+ * 3. Dynamic shared memory pool based on alloc_pages()
+ *
+ * Implements an OP-TEE specific shared memory pool which is used
+ * when dynamic shared memory is supported by secure world.
+ *
+ * The main function is optee_shm_pool_alloc_pages().
+ */
+
+static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
+			 struct tee_shm *shm, size_t size)
+{
+	if (!(shm->flags & TEE_SHM_DMA_BUF))
+		return optee_pool_op_alloc_helper(poolm, shm, size, NULL);
+
+	return optee_pool_op_alloc_helper(poolm, shm, size, optee_shm_register);
+}
+
+static void pool_op_free(struct tee_shm_pool_mgr *poolm,
+			 struct tee_shm *shm)
+{
+	if (shm->flags & TEE_SHM_DMA_BUF)
+		optee_shm_unregister(shm->ctx, shm);
+
+	free_pages((unsigned long)shm->kaddr, get_order(shm->size));
+	shm->kaddr = NULL;
+}
+
+static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
+{
+	kfree(poolm);
+}
+
+static const struct tee_shm_pool_mgr_ops pool_ops = {
+	.alloc = pool_op_alloc,
+	.free = pool_op_free,
+	.destroy_poolmgr = pool_op_destroy_poolmgr,
+};
+
+/**
+ * optee_shm_pool_alloc_pages() - create page-based allocator pool
+ *
+ * This pool is used when OP-TEE supports dymanic SHM. In this case
+ * command buffers and such are allocated from kernel's own memory.
+ */
+static struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void)
+{
+	struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+
+	if (!mgr)
+		return ERR_PTR(-ENOMEM);
+
+	mgr->ops = &pool_ops;
+
+	return mgr;
+}
+
+/*
+ * 4. Do a normal scheduled call into secure world
+ *
+ * The function optee_smc_do_call_with_arg() performs a normal scheduled
+ * call into secure world. During this call may normal world request help
+ * from normal world using RPCs, Remote Procedure Calls. This includes
+ * delivery of non-secure interrupts to for instance allow rescheduling of
+ * the current task.
+ */
+
+static void handle_rpc_func_cmd_shm_free(struct tee_context *ctx,
+					 struct optee_msg_arg *arg)
+{
+	struct tee_shm *shm;
+
+	arg->ret_origin = TEEC_ORIGIN_COMMS;
+
+	if (arg->num_params != 1 ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	shm = (struct tee_shm *)(unsigned long)arg->params[0].u.value.b;
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_RPC_SHM_TYPE_APPL:
+		optee_rpc_cmd_free_suppl(ctx, shm);
+		break;
+	case OPTEE_RPC_SHM_TYPE_KERNEL:
+		tee_shm_free(shm);
+		break;
+	default:
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+	}
+	arg->ret = TEEC_SUCCESS;
+}
+
+static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
+					  struct optee_msg_arg *arg,
+					  struct optee_call_ctx *call_ctx)
+{
+	phys_addr_t pa;
+	struct tee_shm *shm;
+	size_t sz;
+	size_t n;
+
+	arg->ret_origin = TEEC_ORIGIN_COMMS;
+
+	if (!arg->num_params ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	for (n = 1; n < arg->num_params; n++) {
+		if (arg->params[n].attr != OPTEE_MSG_ATTR_TYPE_NONE) {
+			arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+			return;
+		}
+	}
+
+	sz = arg->params[0].u.value.b;
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_RPC_SHM_TYPE_APPL:
+		shm = optee_rpc_cmd_alloc_suppl(ctx, sz);
+		break;
+	case OPTEE_RPC_SHM_TYPE_KERNEL:
+		shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED);
+		break;
+	default:
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	if (IS_ERR(shm)) {
+		arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+		return;
+	}
+
+	if (tee_shm_get_pa(shm, 0, &pa)) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		goto bad;
+	}
+
+	sz = tee_shm_get_size(shm);
+
+	if (tee_shm_is_registered(shm)) {
+		struct page **pages;
+		u64 *pages_list;
+		size_t page_num;
+
+		pages = tee_shm_get_pages(shm, &page_num);
+		if (!pages || !page_num) {
+			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+			goto bad;
+		}
+
+		pages_list = optee_allocate_pages_list(page_num);
+		if (!pages_list) {
+			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+			goto bad;
+		}
+
+		call_ctx->pages_list = pages_list;
+		call_ctx->num_entries = page_num;
+
+		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
+				      OPTEE_MSG_ATTR_NONCONTIG;
+		/*
+		 * In the least bits of u.tmem.buf_ptr we store buffer offset
+		 * from 4k page, as described in OP-TEE ABI.
+		 */
+		arg->params[0].u.tmem.buf_ptr = virt_to_phys(pages_list) |
+			(tee_shm_get_page_offset(shm) &
+			 (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
+		arg->params[0].u.tmem.size = tee_shm_get_size(shm);
+		arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
+
+		optee_fill_pages_list(pages_list, pages, page_num,
+				      tee_shm_get_page_offset(shm));
+	} else {
+		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT;
+		arg->params[0].u.tmem.buf_ptr = pa;
+		arg->params[0].u.tmem.size = sz;
+		arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
+	}
+
+	arg->ret = TEEC_SUCCESS;
+	return;
+bad:
+	tee_shm_free(shm);
+}
+
+static void free_pages_list(struct optee_call_ctx *call_ctx)
+{
+	if (call_ctx->pages_list) {
+		optee_free_pages_list(call_ctx->pages_list,
+				      call_ctx->num_entries);
+		call_ctx->pages_list = NULL;
+		call_ctx->num_entries = 0;
+	}
+}
+
+static void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx)
+{
+	free_pages_list(call_ctx);
+}
+
+static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
+				struct tee_shm *shm,
+				struct optee_call_ctx *call_ctx)
+{
+	struct optee_msg_arg *arg;
+
+	arg = tee_shm_get_va(shm, 0);
+	if (IS_ERR(arg)) {
+		pr_err("%s: tee_shm_get_va %p failed\n", __func__, shm);
+		return;
+	}
+
+	switch (arg->cmd) {
+	case OPTEE_RPC_CMD_SHM_ALLOC:
+		free_pages_list(call_ctx);
+		handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
+		break;
+	case OPTEE_RPC_CMD_SHM_FREE:
+		handle_rpc_func_cmd_shm_free(ctx, arg);
+		break;
+	default:
+		optee_rpc_cmd(ctx, optee, arg);
+	}
+}
+
+/**
+ * optee_handle_rpc() - handle RPC from secure world
+ * @ctx:	context doing the RPC
+ * @param:	value of registers for the RPC
+ * @call_ctx:	call context. Preserved during one OP-TEE invocation
+ *
+ * Result of RPC is written back into @param.
+ */
+static void optee_handle_rpc(struct tee_context *ctx,
+			     struct optee_rpc_param *param,
+			     struct optee_call_ctx *call_ctx)
+{
+	struct tee_device *teedev = ctx->teedev;
+	struct optee *optee = tee_get_drvdata(teedev);
+	struct tee_shm *shm;
+	phys_addr_t pa;
+
+	switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
+	case OPTEE_SMC_RPC_FUNC_ALLOC:
+		shm = tee_shm_alloc(ctx, param->a1, TEE_SHM_MAPPED);
+		if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
+			reg_pair_from_64(&param->a1, &param->a2, pa);
+			reg_pair_from_64(&param->a4, &param->a5,
+					 (unsigned long)shm);
+		} else {
+			param->a1 = 0;
+			param->a2 = 0;
+			param->a4 = 0;
+			param->a5 = 0;
+		}
+		break;
+	case OPTEE_SMC_RPC_FUNC_FREE:
+		shm = reg_pair_to_ptr(param->a1, param->a2);
+		tee_shm_free(shm);
+		break;
+	case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR:
+		/*
+		 * A foreign interrupt was raised while secure world was
+		 * executing, since they are handled in Linux a dummy RPC is
+		 * performed to let Linux take the interrupt through the normal
+		 * vector.
+		 */
+		break;
+	case OPTEE_SMC_RPC_FUNC_CMD:
+		shm = reg_pair_to_ptr(param->a1, param->a2);
+		handle_rpc_func_cmd(ctx, optee, shm, call_ctx);
+		break;
+	default:
+		pr_warn("Unknown RPC func 0x%x\n",
+			(u32)OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0));
+		break;
+	}
+
+	param->a0 = OPTEE_SMC_CALL_RETURN_FROM_RPC;
+}
+
+/**
+ * optee_smc_do_call_with_arg() - Do an SMC to OP-TEE in secure world
+ * @ctx:	calling context
+ * @arg:	shared memory holding the message to pass to secure world
+ *
+ * Does and SMC to OP-TEE in secure world and handles eventual resulting
+ * Remote Procedure Calls (RPC) from OP-TEE.
+ *
+ * Returns return code from secure world, 0 is OK
+ */
+static int optee_smc_do_call_with_arg(struct tee_context *ctx,
+				      struct tee_shm *arg)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct optee_call_waiter w;
+	struct optee_rpc_param param = { };
+	struct optee_call_ctx call_ctx = { };
+	phys_addr_t parg;
+	int rc;
+
+	rc = tee_shm_get_pa(arg, 0, &parg);
+	if (rc)
+		return rc;
+
+	param.a0 = OPTEE_SMC_CALL_WITH_ARG;
+	reg_pair_from_64(&param.a1, &param.a2, parg);
+	/* Initialize waiter */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		struct arm_smccc_res res;
+
+		trace_optee_invoke_fn_begin(&param);
+		optee->smc.invoke_fn(param.a0, param.a1, param.a2, param.a3,
+				     param.a4, param.a5, param.a6, param.a7,
+				     &res);
+		trace_optee_invoke_fn_end(&param, &res);
+
+		if (res.a0 == OPTEE_SMC_RETURN_ETHREAD_LIMIT) {
+			/*
+			 * Out of threads in secure world, wait for a thread
+			 * become available.
+			 */
+			optee_cq_wait_for_completion(&optee->call_queue, &w);
+		} else if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {
+			cond_resched();
+			param.a0 = res.a0;
+			param.a1 = res.a1;
+			param.a2 = res.a2;
+			param.a3 = res.a3;
+			optee_handle_rpc(ctx, &param, &call_ctx);
+		} else {
+			rc = res.a0;
+			break;
+		}
+	}
+
+	optee_rpc_finalize_call(&call_ctx);
+	/*
+	 * We're done with our thread in secure world, if there's any
+	 * thread waiters wake up one.
+	 */
+	optee_cq_wait_final(&optee->call_queue, &w);
+
+	return rc;
+}
+
+/*
+ * 5. Driver initialization
+ *
+ * During driver inititialization is secure world probed to find out which
+ * features it supports so the driver can be initialized with a matching
+ * configuration. This involves for instance support for dynamic shared
+ * memory instead of a static memory carvout.
+ */
+
+static void optee_get_version(struct tee_device *teedev,
+			      struct tee_ioctl_version_data *vers)
+{
+	struct tee_ioctl_version_data v = {
+		.impl_id = TEE_IMPL_ID_OPTEE,
+		.impl_caps = TEE_OPTEE_CAP_TZ,
+		.gen_caps = TEE_GEN_CAP_GP,
+	};
+	struct optee *optee = tee_get_drvdata(teedev);
+
+	if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
+		v.gen_caps |= TEE_GEN_CAP_REG_MEM;
+	if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
+		v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
+	*vers = v;
+}
+
+static int optee_smc_open(struct tee_context *ctx)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	u32 sec_caps = optee->smc.sec_caps;
+
+	return optee_open(ctx, sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL);
+}
+
+static const struct tee_driver_ops optee_clnt_ops = {
+	.get_version = optee_get_version,
+	.open = optee_smc_open,
+	.release = optee_release,
+	.open_session = optee_open_session,
+	.close_session = optee_close_session,
+	.invoke_func = optee_invoke_func,
+	.cancel_req = optee_cancel_req,
+	.shm_register = optee_shm_register,
+	.shm_unregister = optee_shm_unregister,
+};
+
+static const struct tee_desc optee_clnt_desc = {
+	.name = DRIVER_NAME "-clnt",
+	.ops = &optee_clnt_ops,
+	.owner = THIS_MODULE,
+};
+
+static const struct tee_driver_ops optee_supp_ops = {
+	.get_version = optee_get_version,
+	.open = optee_smc_open,
+	.release = optee_release_supp,
+	.supp_recv = optee_supp_recv,
+	.supp_send = optee_supp_send,
+	.shm_register = optee_shm_register_supp,
+	.shm_unregister = optee_shm_unregister_supp,
+};
+
+static const struct tee_desc optee_supp_desc = {
+	.name = DRIVER_NAME "-supp",
+	.ops = &optee_supp_ops,
+	.owner = THIS_MODULE,
+	.flags = TEE_DESC_PRIVILEGED,
+};
+
+static const struct optee_ops optee_ops = {
+	.do_call_with_arg = optee_smc_do_call_with_arg,
+	.to_msg_param = optee_to_msg_param,
+	.from_msg_param = optee_from_msg_param,
+};
+
+static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
+{
+	struct arm_smccc_res res;
+
+	invoke_fn(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 &&
+	    res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3)
+		return true;
+	return false;
+}
+
+static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_call_get_os_revision_result result;
+	} res = {
+		.result = {
+			.build_id = 0
+		}
+	};
+
+	invoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0,
+		  &res.smccc);
+
+	if (res.result.build_id)
+		pr_info("revision %lu.%lu (%08lx)", res.result.major,
+			res.result.minor, res.result.build_id);
+	else
+		pr_info("revision %lu.%lu", res.result.major, res.result.minor);
+}
+
+static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_calls_revision_result result;
+	} res;
+
+	invoke_fn(OPTEE_SMC_CALLS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
+
+	if (res.result.major == OPTEE_MSG_REVISION_MAJOR &&
+	    (int)res.result.minor >= OPTEE_MSG_REVISION_MINOR)
+		return true;
+	return false;
+}
+
+static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
+					    u32 *sec_caps)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_exchange_capabilities_result result;
+	} res;
+	u32 a1 = 0;
+
+	/*
+	 * TODO This isn't enough to tell if it's UP system (from kernel
+	 * point of view) or not, is_smp() returns the information
+	 * needed, but can't be called directly from here.
+	 */
+	if (!IS_ENABLED(CONFIG_SMP) || nr_cpu_ids == 1)
+		a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR;
+
+	invoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES, a1, 0, 0, 0, 0, 0, 0,
+		  &res.smccc);
+
+	if (res.result.status != OPTEE_SMC_RETURN_OK)
+		return false;
+
+	*sec_caps = res.result.capabilities;
+	return true;
+}
+
+static struct tee_shm_pool *optee_config_dyn_shm(void)
+{
+	struct tee_shm_pool_mgr *priv_mgr;
+	struct tee_shm_pool_mgr *dmabuf_mgr;
+	void *rc;
+
+	rc = optee_shm_pool_alloc_pages();
+	if (IS_ERR(rc))
+		return rc;
+	priv_mgr = rc;
+
+	rc = optee_shm_pool_alloc_pages();
+	if (IS_ERR(rc)) {
+		tee_shm_pool_mgr_destroy(priv_mgr);
+		return rc;
+	}
+	dmabuf_mgr = rc;
+
+	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
+	if (IS_ERR(rc)) {
+		tee_shm_pool_mgr_destroy(priv_mgr);
+		tee_shm_pool_mgr_destroy(dmabuf_mgr);
+	}
+
+	return rc;
+}
+
+static struct tee_shm_pool *
+optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_get_shm_config_result result;
+	} res;
+	unsigned long vaddr;
+	phys_addr_t paddr;
+	size_t size;
+	phys_addr_t begin;
+	phys_addr_t end;
+	void *va;
+	struct tee_shm_pool_mgr *priv_mgr;
+	struct tee_shm_pool_mgr *dmabuf_mgr;
+	void *rc;
+	const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
+
+	invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
+	if (res.result.status != OPTEE_SMC_RETURN_OK) {
+		pr_err("static shm service not available\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	if (res.result.settings != OPTEE_SMC_SHM_CACHED) {
+		pr_err("only normal cached shared memory supported\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	begin = roundup(res.result.start, PAGE_SIZE);
+	end = rounddown(res.result.start + res.result.size, PAGE_SIZE);
+	paddr = begin;
+	size = end - begin;
+
+	if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
+		pr_err("too small shared memory area\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	va = memremap(paddr, size, MEMREMAP_WB);
+	if (!va) {
+		pr_err("shared memory ioremap failed\n");
+		return ERR_PTR(-EINVAL);
+	}
+	vaddr = (unsigned long)va;
+
+	rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
+					    3 /* 8 bytes aligned */);
+	if (IS_ERR(rc))
+		goto err_memunmap;
+	priv_mgr = rc;
+
+	vaddr += sz;
+	paddr += sz;
+	size -= sz;
+
+	rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT);
+	if (IS_ERR(rc))
+		goto err_free_priv_mgr;
+	dmabuf_mgr = rc;
+
+	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
+	if (IS_ERR(rc))
+		goto err_free_dmabuf_mgr;
+
+	*memremaped_shm = va;
+
+	return rc;
+
+err_free_dmabuf_mgr:
+	tee_shm_pool_mgr_destroy(dmabuf_mgr);
+err_free_priv_mgr:
+	tee_shm_pool_mgr_destroy(priv_mgr);
+err_memunmap:
+	memunmap(va);
+	return rc;
+}
+
+/* Simple wrapper functions to be able to use a function pointer */
+static void optee_smccc_smc(unsigned long a0, unsigned long a1,
+			    unsigned long a2, unsigned long a3,
+			    unsigned long a4, unsigned long a5,
+			    unsigned long a6, unsigned long a7,
+			    struct arm_smccc_res *res)
+{
+	arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
+}
+
+static void optee_smccc_hvc(unsigned long a0, unsigned long a1,
+			    unsigned long a2, unsigned long a3,
+			    unsigned long a4, unsigned long a5,
+			    unsigned long a6, unsigned long a7,
+			    struct arm_smccc_res *res)
+{
+	arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
+}
+
+static optee_invoke_fn *get_invoke_func(struct device *dev)
+{
+	const char *method;
+
+	pr_info("probing for conduit method.\n");
+
+	if (device_property_read_string(dev, "method", &method)) {
+		pr_warn("missing \"method\" property\n");
+		return ERR_PTR(-ENXIO);
+	}
+
+	if (!strcmp("hvc", method))
+		return optee_smccc_hvc;
+	else if (!strcmp("smc", method))
+		return optee_smccc_smc;
+
+	pr_warn("invalid \"method\" property: %s\n", method);
+	return ERR_PTR(-EINVAL);
+}
+
+static int optee_smc_remove(struct platform_device *pdev)
+{
+	struct optee *optee = platform_get_drvdata(pdev);
+
+	/*
+	 * Ask OP-TEE to free all cached shared memory objects to decrease
+	 * reference counters and also avoid wild pointers in secure world
+	 * into the old shared memory range.
+	 */
+	optee_disable_shm_cache(optee);
+
+	optee_remove_common(optee);
+
+	if (optee->smc.memremaped_shm)
+		memunmap(optee->smc.memremaped_shm);
+
+	kfree(optee);
+
+	return 0;
+}
+
+static int optee_probe(struct platform_device *pdev)
+{
+	optee_invoke_fn *invoke_fn;
+	struct tee_shm_pool *pool = ERR_PTR(-EINVAL);
+	struct optee *optee = NULL;
+	void *memremaped_shm = NULL;
+	struct tee_device *teedev;
+	u32 sec_caps;
+	int rc;
+
+	invoke_fn = get_invoke_func(&pdev->dev);
+	if (IS_ERR(invoke_fn))
+		return PTR_ERR(invoke_fn);
+
+	if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
+		pr_warn("api uid mismatch\n");
+		return -EINVAL;
+	}
+
+	optee_msg_get_os_revision(invoke_fn);
+
+	if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
+		pr_warn("api revision mismatch\n");
+		return -EINVAL;
+	}
+
+	if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
+		pr_warn("capabilities mismatch\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Try to use dynamic shared memory if possible
+	 */
+	if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
+		pool = optee_config_dyn_shm();
+
+	/*
+	 * If dynamic shared memory is not available or failed - try static one
+	 */
+	if (IS_ERR(pool) && (sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
+		pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
+
+	if (IS_ERR(pool))
+		return PTR_ERR(pool);
+
+	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
+	if (!optee) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	optee->ops = &optee_ops;
+	optee->smc.invoke_fn = invoke_fn;
+	optee->smc.sec_caps = sec_caps;
+
+	teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->teedev = teedev;
+
+	teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->supp_teedev = teedev;
+
+	rc = tee_device_register(optee->teedev);
+	if (rc)
+		goto err;
+
+	rc = tee_device_register(optee->supp_teedev);
+	if (rc)
+		goto err;
+
+	mutex_init(&optee->call_queue.mutex);
+	INIT_LIST_HEAD(&optee->call_queue.waiters);
+	optee_wait_queue_init(&optee->wait_queue);
+	optee_supp_init(&optee->supp);
+	optee->smc.memremaped_shm = memremaped_shm;
+	optee->pool = pool;
+
+	optee_enable_shm_cache(optee);
+
+	if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
+		pr_info("dynamic shared memory is enabled\n");
+
+	platform_set_drvdata(pdev, optee);
+
+	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
+	if (rc) {
+		optee_smc_remove(pdev);
+		return rc;
+	}
+
+	pr_info("initialized driver\n");
+	return 0;
+err:
+	if (optee) {
+		/*
+		 * tee_device_unregister() is safe to call even if the
+		 * devices hasn't been registered with
+		 * tee_device_register() yet.
+		 */
+		tee_device_unregister(optee->supp_teedev);
+		tee_device_unregister(optee->teedev);
+		kfree(optee);
+	}
+	if (pool)
+		tee_shm_pool_free(pool);
+	if (memremaped_shm)
+		memunmap(memremaped_shm);
+	return rc;
+}
+
+static const struct of_device_id optee_dt_match[] = {
+	{ .compatible = "linaro,optee-tz" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, optee_dt_match);
+
+static struct platform_driver optee_driver = {
+	.probe  = optee_probe,
+	.remove = optee_smc_remove,
+	.driver = {
+		.name = "optee",
+		.of_match_table = optee_dt_match,
+	},
+};
+
+int optee_smc_abi_register(void)
+{
+	return platform_driver_register(&optee_driver);
+}
+
+void optee_smc_abi_unregister(void)
+{
+	platform_driver_unregister(&optee_driver);
+}
+
-- 
2.31.1



From l.stach at pengutronix.de  Thu Aug 19 04:10:39 2021
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 19 Aug 2021 13:10:39 +0200
Subject: [PATCH v1 2/3] arm: dts: imx: fix the schema check errors
In-Reply-To: <20210819071408.3856475-3-hongxing.zhu@nxp.com>
References: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
 <20210819071408.3856475-3-hongxing.zhu@nxp.com>
Message-ID: <cbd278b1828d4b8fbfd885e56731d82355d2112b.camel@pengutronix.de>

Hi Richard,

Am Donnerstag, dem 19.08.2021 um 15:14 +0800 schrieb Richard Zhu:
> - the ranges should be aligned to $ref: /schemas/pci/pci-bus.yaml#

I failed to parse this part of the commit message and expected to see
an actual change in the addresses of the ranges or something. I think
it would be better to phrase this something like: "group ranges
property by region" or something to make it clear that this is purely a
DTS representation change, with no functional change.

> - num-viewport is required, add it in imx6sx.dtsi.
> - only one propert is allowed in the compatible string, remove
>   "snps,dw-pcie".
> 
> Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>

Other than the nit above, this is:
Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

> ---
>  arch/arm/boot/dts/imx6qdl.dtsi | 6 +++---
>  arch/arm/boot/dts/imx6qp.dtsi  | 2 +-
>  arch/arm/boot/dts/imx6sx.dtsi  | 7 ++++---
>  arch/arm/boot/dts/imx7d.dtsi   | 6 +++---
>  4 files changed, 11 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> index 82e01ce026ea..cb43c72806a1 100644
> --- a/arch/arm/boot/dts/imx6qdl.dtsi
> +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> @@ -264,7 +264,7 @@ L2: cache-controller at a02000 {
>  		};
>  
>  		pcie: pcie at 1ffc000 {
> -			compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
> +			compatible = "fsl,imx6q-pcie";
>  			reg = <0x01ffc000 0x04000>,
>  			      <0x01f00000 0x80000>;
>  			reg-names = "dbi", "config";
> @@ -272,8 +272,8 @@ pcie: pcie at 1ffc000 {
>  			#size-cells = <2>;
>  			device_type = "pci";
>  			bus-range = <0x00 0xff>;
> -			ranges = <0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
> -				  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
> +			ranges = <0x81000000 0 0          0x01f80000 0 0x00010000>, /* downstream I/O */
> +				 <0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
>  			num-lanes = <1>;
>  			num-viewport = <4>;
>  			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi
> index b310f13a53f2..050365513836 100644
> --- a/arch/arm/boot/dts/imx6qp.dtsi
> +++ b/arch/arm/boot/dts/imx6qp.dtsi
> @@ -110,5 +110,5 @@ &mmdc0 {
>  };
>  
>  &pcie {
> -	compatible = "fsl,imx6qp-pcie", "snps,dw-pcie";
> +	compatible = "fsl,imx6qp-pcie";
>  };
> diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
> index 8516730778df..0324f9e17389 100644
> --- a/arch/arm/boot/dts/imx6sx.dtsi
> +++ b/arch/arm/boot/dts/imx6sx.dtsi
> @@ -1395,16 +1395,17 @@ pwm8: pwm at 22b0000 {
>  		};
>  
>  		pcie: pcie at 8ffc000 {
> -			compatible = "fsl,imx6sx-pcie", "snps,dw-pcie";
> +			compatible = "fsl,imx6sx-pcie";
>  			reg = <0x08ffc000 0x04000>, <0x08f00000 0x80000>;
>  			reg-names = "dbi", "config";
>  			#address-cells = <3>;
>  			#size-cells = <2>;
>  			device_type = "pci";
>  			bus-range = <0x00 0xff>;
> -			ranges = <0x81000000 0 0          0x08f80000 0 0x00010000 /* downstream I/O */
> -				  0x82000000 0 0x08000000 0x08000000 0 0x00f00000>; /* non-prefetchable memory */
> +			ranges = <0x81000000 0 0          0x08f80000 0 0x00010000>, /* downstream I/O */
> +				 <0x82000000 0 0x08000000 0x08000000 0 0x00f00000>; /* non-prefetchable memory */
>  			num-lanes = <1>;
> +			num-viewport = <4>;
>  			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
>  			interrupt-names = "msi";
>  			#interrupt-cells = <1>;
> diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
> index b0bcfa9094a3..0cb8c8df87ef 100644
> --- a/arch/arm/boot/dts/imx7d.dtsi
> +++ b/arch/arm/boot/dts/imx7d.dtsi
> @@ -164,7 +164,7 @@ fec2: ethernet at 30bf0000 {
>  	};
>  
>  	pcie: pcie at 33800000 {
> -		compatible = "fsl,imx7d-pcie", "snps,dw-pcie";
> +		compatible = "fsl,imx7d-pcie";
>  		reg = <0x33800000 0x4000>,
>  		      <0x4ff00000 0x80000>;
>  		reg-names = "dbi", "config";
> @@ -172,8 +172,8 @@ pcie: pcie at 33800000 {
>  		#size-cells = <2>;
>  		device_type = "pci";
>  		bus-range = <0x00 0xff>;
> -		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000   /* downstream I/O */
> -			  0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
> +		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000>, /* downstream I/O */
> +			 <0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
>  		num-lanes = <1>;
>  		num-viewport = <4>;
>  		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;




From l.stach at pengutronix.de  Thu Aug 19 04:11:25 2021
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 19 Aug 2021 13:11:25 +0200
Subject: [PATCH v1 3/3] arm64: dts: imx8mq: fix the schema check errors
In-Reply-To: <20210819071408.3856475-4-hongxing.zhu@nxp.com>
References: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
 <20210819071408.3856475-4-hongxing.zhu@nxp.com>
Message-ID: <6e179b30d360e8151ad1aba5f49540009a2076a5.camel@pengutronix.de>

Am Donnerstag, dem 19.08.2021 um 15:14 +0800 schrieb Richard Zhu:
> The ranges should be aligned to $ref: /schemas/pci/pci-bus.yaml#
> 
> Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>

Same comment as on the last patch, but still:
Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

> ---
>  arch/arm64/boot/dts/freescale/imx8mq.dtsi | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> index 91df9c5350ae..45895dad85e1 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> @@ -1364,8 +1364,8 @@ pcie0: pcie at 33800000 {
>  			#size-cells = <2>;
>  			device_type = "pci";
>  			bus-range = <0x00 0xff>;
> -			ranges = <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000 /* downstream I/O 64KB */
> -			          0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
> +			ranges = <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000>, /* downstream I/O 64KB */
> +				 <0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
>  			num-lanes = <1>;
>  			num-viewport = <4>;
>  			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
> @@ -1402,8 +1402,8 @@ pcie1: pcie at 33c00000 {
>  			#address-cells = <3>;
>  			#size-cells = <2>;
>  			device_type = "pci";
> -			ranges =  <0x81000000 0 0x00000000 0x27f80000 0 0x00010000 /* downstream I/O 64KB */
> -				   0x82000000 0 0x20000000 0x20000000 0 0x07f00000>; /* non-prefetchable memory */
> +			ranges =  <0x81000000 0 0x00000000 0x27f80000 0 0x00010000>, /* downstream I/O 64KB */
> +				  <0x82000000 0 0x20000000 0x20000000 0 0x07f00000>; /* non-prefetchable memory */
>  			num-lanes = <1>;
>  			num-viewport = <4>;
>  			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;




From alexandre.belloni at bootlin.com  Thu Aug 19 04:20:25 2021
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Thu, 19 Aug 2021 13:20:25 +0200
Subject: [PATCH 2/2] ARM: at91: dts: at91-sama5d2_xplained: Add comments
 for sama5d29
In-Reply-To: <78b26b01-b66f-5779-9f67-fdd13e473dfc@microchip.com>
References: <20210812140758.28273-1-Hari.PrasathGE@microchip.com>
 <20210812140758.28273-2-Hari.PrasathGE@microchip.com>
 <YRV13nfgpEEuOOxB@piout.net>
 <78b26b01-b66f-5779-9f67-fdd13e473dfc@microchip.com>
Message-ID: <YR4+eUWdeHRCOMo3@piout.net>

On 19/08/2021 10:56:21+0000, Hari.PrasathGE at microchip.com wrote:
> Hello,
> 
> On 13/08/21 12:56 am, Alexandre Belloni wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> > Hello,
> > 
> > On 12/08/2021 19:37:58+0530, Hari Prasath wrote:
> >> Add comments for the end user for modifying the DTS file for
> >> instantiating the sama5d29 SoC.
> >>
> >> Signed-off-by: Hari Prasath <Hari.PrasathGE at microchip.com>
> >> ---
> >>   arch/arm/boot/dts/at91-sama5d2_xplained.dts | 5 +++++
> >>   1 file changed, 5 insertions(+)
> >>
> >> diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
> >> index 627b7bf88d83..faa30063d9a9 100644
> >> --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
> >> +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
> >> @@ -6,6 +6,11 @@
> >>    *                2015 Nicolas Ferre <nicolas.ferre at atmel.com>
> >>    */
> >>   /dts-v1/;
> >> +/*
> >> + * Replace the line below with "sama5d29.dtsi" in order to instantiate the
> >> + * sama5d29 SoC of the sama5d2 family.Otherwise, leave it unchanged when
> >> + * using sama5d27 SoC for instance.
> >> + */
> > 
> > I guess it would be better to have a at91-sama5d29_xplained.dts (and we
> > should have had a at91-sama5d27_xplained.dts), else, you can't create an
> > image that will support both variants.
> > 
> > 
> The new SoC 'sama5d29' belongs to the same sama5d2 family. It is 
> essentially a new chip revision of the existing sama5d27 with a new GMAC 
> controller IP that addresses few silicon issues. There wouldn't be 
> separate evaluation boards that shall be made but we will be using the 
> existing sama5d2 XPlained boards itself but with the new SoC populated. 

That's what I understood but a board with a different SoC is a
different board.

> Hence we have taken this approach of having a separate DTSI file and 
> reuse the existing board specific DTS file.
> 
> We don't want to create single image that will support both variants. In 
> fact, we don't want our customers to enable certain features that are 
> broken at the silicon level in the existing revision of the SoC i.e 
> sama5d27. Instead, they could do this change manually and use it in the 
> new SoC i.e sama5d29.
> 

This will be confusing to your customers while you could make their
lives simpler by having the bootloader chose the proper dtb instead of
having them change that manually. They will then have to regenerate
images with that change, see how your customers struggle to do that:

https://stackoverflow.com/questions/68222619/update-custom-device-tree-on-yocto
https://stackoverflow.com/questions/37347808/how-to-use-an-own-device-tree-and-modified-kernel-config-in-yocto
https://stackoverflow.com/questions/63047955/overriding-defconfig-in-bbappend-file


-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From lukas.bulwahn at gmail.com  Thu Aug 19 04:22:48 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Thu, 19 Aug 2021 13:22:48 +0200
Subject: [PATCH v2 0/5] Kconfig symbol clean-up on gpu
Message-ID: <20210819112253.16484-1-lukas.bulwahn@gmail.com>

Dear DRM maintainers,

The script ./scripts/checkkconfigsymbols.py warns on invalid references to
Kconfig symbols (often, minor typos, name confusions or outdated references).

This patch series addresses all issues reported by ./scripts/checkkconfigsymbols.py
in ./drivers/gpu/ for Kconfig and Makefile files. Issues in the Kconfig and
Makefile files indicate some shortcomings in the overall build definitions, and
often are true actionable issues to address.

These issues can be identified and filtered by:

  ./scripts/checkkconfigsymbols.py | grep -E "drivers/gpu/.*(Kconfig|Makefile)" -B 1 -A 1

After applying this patch series on linux-next (next-20210817), the command
above yields just one further issues to address:

DRM_AMD_DC_DCE11_0
Referencing files: drivers/gpu/drm/amd/display/dc/dce100/Makefile

  Conclusion: No action required.
  Rationale:
    drivers/gpu/drm/amd/display/dc/dce100/Makefile refers to
    DRM_AMD_DC_DCE11_0 in a comment, after an "ifdef 0".


Please pick this patch series into your drm-next tree.

Note that patch "drm: amdgpu: remove obsolete reference to config CHASH"
was already picked and applied by Alex Deucher.


Best regards,

Lukas

v1 -> v2:
  - adjusted sources in drivers/gpu/drm/Kconfig
    for drm: zte: remove obsolete DRM Support for ZTE SoCs
    after report by kernel test robot
  - removed Tomi from recipient list as email is unreachable.

Lukas Bulwahn (5):
  drm: rockchip: remove reference to non-existing config DRM_RGB
  drm: amdgpu: remove obsolete reference to config CHASH
  drm: v3d: correct reference to config ARCH_BRCMSTB
  drm: zte: remove obsolete DRM Support for ZTE SoCs
  drm: omap: remove obsolete selection of OMAP2_DSS in config DRM_OMAP

 drivers/gpu/drm/Kconfig              |   3 -
 drivers/gpu/drm/Makefile             |   1 -
 drivers/gpu/drm/omapdrm/Kconfig      |   1 -
 drivers/gpu/drm/rockchip/Kconfig     |   1 -
 drivers/gpu/drm/v3d/Kconfig          |   2 +-
 drivers/gpu/drm/zte/Kconfig          |  10 -
 drivers/gpu/drm/zte/Makefile         |  10 -
 drivers/gpu/drm/zte/zx_common_regs.h |  28 -
 drivers/gpu/drm/zte/zx_drm_drv.c     | 184 ------
 drivers/gpu/drm/zte/zx_drm_drv.h     |  34 -
 drivers/gpu/drm/zte/zx_hdmi.c        | 760 ----------------------
 drivers/gpu/drm/zte/zx_hdmi_regs.h   |  66 --
 drivers/gpu/drm/zte/zx_plane.c       | 537 ----------------
 drivers/gpu/drm/zte/zx_plane.h       |  26 -
 drivers/gpu/drm/zte/zx_plane_regs.h  | 120 ----
 drivers/gpu/drm/zte/zx_tvenc.c       | 400 ------------
 drivers/gpu/drm/zte/zx_tvenc_regs.h  |  27 -
 drivers/gpu/drm/zte/zx_vga.c         | 527 ---------------
 drivers/gpu/drm/zte/zx_vga_regs.h    |  33 -
 drivers/gpu/drm/zte/zx_vou.c         | 921 ---------------------------
 drivers/gpu/drm/zte/zx_vou.h         |  64 --
 drivers/gpu/drm/zte/zx_vou_regs.h    | 212 ------
 22 files changed, 1 insertion(+), 3966 deletions(-)
 delete mode 100644 drivers/gpu/drm/zte/Kconfig
 delete mode 100644 drivers/gpu/drm/zte/Makefile
 delete mode 100644 drivers/gpu/drm/zte/zx_common_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.c
 delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.h
 delete mode 100644 drivers/gpu/drm/zte/zx_hdmi.c
 delete mode 100644 drivers/gpu/drm/zte/zx_hdmi_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_plane.c
 delete mode 100644 drivers/gpu/drm/zte/zx_plane.h
 delete mode 100644 drivers/gpu/drm/zte/zx_plane_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_tvenc.c
 delete mode 100644 drivers/gpu/drm/zte/zx_tvenc_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vga.c
 delete mode 100644 drivers/gpu/drm/zte/zx_vga_regs.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vou.c
 delete mode 100644 drivers/gpu/drm/zte/zx_vou.h
 delete mode 100644 drivers/gpu/drm/zte/zx_vou_regs.h

-- 
2.26.2



From lukas.bulwahn at gmail.com  Thu Aug 19 04:22:50 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Thu, 19 Aug 2021 13:22:50 +0200
Subject: [PATCH v2 2/5] drm: amdgpu: remove obsolete reference to config CHASH
In-Reply-To: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
References: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
Message-ID: <20210819112253.16484-3-lukas.bulwahn@gmail.com>

Commit 04ed8459f334 ("drm/amdgpu: remove chash") removes the chash
architecture and its corresponding config CHASH.

There is still a reference to CHASH in the config DRM_AMDGPU in
./drivers/gpu/drm/Kconfig.

Remove this obsolete reference to config CHASH.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/gpu/drm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f3bc90baca61..8fc40317f2b7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -257,7 +257,6 @@ config DRM_AMDGPU
 	select HWMON
 	select BACKLIGHT_CLASS_DEVICE
 	select INTERVAL_TREE
-	select CHASH
 	help
 	  Choose this option if you have a recent AMD Radeon graphics card.
 
-- 
2.26.2



From lukas.bulwahn at gmail.com  Thu Aug 19 04:22:49 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Thu, 19 Aug 2021 13:22:49 +0200
Subject: [PATCH v2 1/5] drm: rockchip: remove reference to non-existing config
 DRM_RGB
In-Reply-To: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
References: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
Message-ID: <20210819112253.16484-2-lukas.bulwahn@gmail.com>

commit 1f0f01515172 ("drm/rockchip: Add support for Rockchip Soc RGB
output interface") accidently adds to select the non-existing config
DRM_RGB in ./drivers/gpu/drm/rockchip/Kconfig.

Luckily, ./scripts/checkkconfigsymbols.py warns on non-existing configs:

DRM_RGB
Referencing files: drivers/gpu/drm/rockchip/Kconfig

So, remove the reference to the non-existing config DRM_RGB.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/gpu/drm/rockchip/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 558f1b58bd69..9f1ecefc3933 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -9,7 +9,6 @@ config DRM_ROCKCHIP
 	select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
 	select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
 	select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
-	select DRM_RGB if ROCKCHIP_RGB
 	select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
 	select GENERIC_PHY_MIPI_DPHY if ROCKCHIP_DW_MIPI_DSI
 	select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
-- 
2.26.2



From lukas.bulwahn at gmail.com  Thu Aug 19 04:22:51 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Thu, 19 Aug 2021 13:22:51 +0200
Subject: [PATCH v2 3/5] drm: v3d: correct reference to config ARCH_BRCMSTB
In-Reply-To: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
References: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
Message-ID: <20210819112253.16484-4-lukas.bulwahn@gmail.com>

Commit 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D
V3.x+") adds the config DRM_V3D, which depends on "ARCH_BCMSTB".

Although, a bit confusing: all Broadcom architectures in
./arch/arm/mach-bcm/Kconfig have the prefix "ARCH_BCM", except for
ARCH_BRCMSTB, i.e., the config for Broadcom BCM7XXX based boards.

So, correct the reference ARCH_BCMSTB to the intended ARCH_BRCMSTB.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/gpu/drm/v3d/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/Kconfig b/drivers/gpu/drm/v3d/Kconfig
index 9a5c44606337..e973ec487484 100644
--- a/drivers/gpu/drm/v3d/Kconfig
+++ b/drivers/gpu/drm/v3d/Kconfig
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config DRM_V3D
 	tristate "Broadcom V3D 3.x and newer"
-	depends on ARCH_BCM || ARCH_BCMSTB || COMPILE_TEST
+	depends on ARCH_BCM || ARCH_BRCMSTB || COMPILE_TEST
 	depends on DRM
 	depends on COMMON_CLK
 	depends on MMU
-- 
2.26.2



From lukas.bulwahn at gmail.com  Thu Aug 19 04:22:53 2021
From: lukas.bulwahn at gmail.com (Lukas Bulwahn)
Date: Thu, 19 Aug 2021 13:22:53 +0200
Subject: [PATCH v2 5/5] drm: omap: remove obsolete selection of OMAP2_DSS in
 config DRM_OMAP
In-Reply-To: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
References: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
Message-ID: <20210819112253.16484-6-lukas.bulwahn@gmail.com>

Commit 55b68fb856b5 ("drm/omap: squash omapdrm sub-modules into one")
removes the config OMAP2_DSS in ./drivers/gpu/drm/omapdrm/dss/Kconfig,
while moving the other configs into./drivers/gpu/drm/omapdrm/Kconfig, but
misses to remove an obsolete selection of OMAP2_DSS in config DRM_OMAP.

Hence, ./scripts/checkkconfigsymbols.py warns:

OMAP2_DSS
Referencing files: drivers/gpu/drm/omapdrm/Kconfig

Remove this reference in an obsolete selection.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
---
 drivers/gpu/drm/omapdrm/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index e7281da5bc6a..d6e4df291d6f 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -3,7 +3,6 @@ config DRM_OMAP
 	tristate "OMAP DRM"
 	depends on DRM
 	depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
-	select OMAP2_DSS
 	select DRM_KMS_HELPER
 	select VIDEOMODE_HELPERS
 	select HDMI
-- 
2.26.2



From helgaas at kernel.org  Thu Aug 19 04:29:08 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 19 Aug 2021 06:29:08 -0500
Subject: [PATCH] PCI: uniphier: Take lock in INTX irq_{mask,unmask,ack}
 callbacks
In-Reply-To: <1629370566-29984-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <20210819112908.GA3188927@bjorn-Precision-5520>

Possibly update subject to be more descriptive, along lines of:

  Serialize INTx masking/unmasking

On Thu, Aug 19, 2021 at 07:56:06PM +0900, Kunihiko Hayashi wrote:
> The same condition register PCI_RCV_INTX is used in irq_mask(),
> irq_unmask() and irq_ack() callbacks. Accesses to register can occur at the
> same time without lock.
> This introduces a lock into the callbacks to prevent the issue.

Rewrap into a single paragraph or add blank line between paragraphs.

s/This introduces/Add/ to make this an imperative description of what
you want this patch to do.  No need for "This" since the context is
obvious.

> Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
> Suggested-by: Pali Roh?r <pali at kernel.org>
> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
> ---
>  drivers/pci/controller/dwc/pcie-uniphier.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
> index ebe43e9..5075714 100644
> --- a/drivers/pci/controller/dwc/pcie-uniphier.c
> +++ b/drivers/pci/controller/dwc/pcie-uniphier.c
> @@ -186,12 +186,17 @@ static void uniphier_pcie_irq_ack(struct irq_data *d)
>  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> +	unsigned long flags;
>  	u32 val;
>  
> +	raw_spin_lock_irqsave(&pp->lock, flags);
> +
>  	val = readl(priv->base + PCL_RCV_INTX);
>  	val &= ~PCL_RCV_INTX_ALL_STATUS;
>  	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
>  	writel(val, priv->base + PCL_RCV_INTX);
> +
> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>  }
>  
>  static void uniphier_pcie_irq_mask(struct irq_data *d)
> @@ -199,12 +204,17 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
>  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> +	unsigned long flags;
>  	u32 val;
>  
> +	raw_spin_lock_irqsave(&pp->lock, flags);
> +
>  	val = readl(priv->base + PCL_RCV_INTX);
>  	val &= ~PCL_RCV_INTX_ALL_MASK;
>  	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
>  	writel(val, priv->base + PCL_RCV_INTX);
> +
> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>  }
>  
>  static void uniphier_pcie_irq_unmask(struct irq_data *d)
> @@ -212,12 +222,17 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
>  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> +	unsigned long flags;
>  	u32 val;
>  
> +	raw_spin_lock_irqsave(&pp->lock, flags);
> +
>  	val = readl(priv->base + PCL_RCV_INTX);
>  	val &= ~PCL_RCV_INTX_ALL_MASK;
>  	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
>  	writel(val, priv->base + PCL_RCV_INTX);
> +
> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>  }
>  
>  static struct irq_chip uniphier_pcie_irq_chip = {
> -- 
> 2.7.4
> 


From bot at kernelci.org  Thu Aug 19 04:32:28 2021
From: bot at kernelci.org (kernelci.org bot)
Date: Thu, 19 Aug 2021 04:32:28 -0700 (PDT)
Subject: arm64/for-kernelci baseline: 38 runs,
 3 regressions (v5.14-rc6-3-g4a8d882022c7)
Message-ID: <611e414c.1c69fb81.3e32b.a0f2@mx.google.com>

arm64/for-kernelci baseline: 38 runs, 3 regressions (v5.14-rc6-3-g4a8d882022c7)

Regressions Summary
-------------------

platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
bcm2837-rpi-3-b  | arm64 | lab-baylibre  | gcc-8    | defconfig | 1          
rk3399-gru-kevin | arm64 | lab-collabora | gcc-8    | defconfig | 2          

  Details:  https://kernelci.org/test/job/arm64/branch/for-kernelci/kernel/v5.14-rc6-3-g4a8d882022c7/plan/baseline/

  Test:     baseline
  Tree:     arm64
  Branch:   for-kernelci
  Describe: v5.14-rc6-3-g4a8d882022c7
  URL:      https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  SHA:      4a8d882022c79ae4d10c30f58d17cc6cf57c3079 


Test Regressions
---------------- 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
bcm2837-rpi-3-b  | arm64 | lab-baylibre  | gcc-8    | defconfig | 1          

  Details:     https://kernelci.org/test/plan/id/611e370e7bd73a92d1b1366f

  Results:     0 PASS, 1 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-3-g4a8d882022c7/arm64/defconfig/gcc-8/lab-baylibre/baseline-bcm2837-rpi-3-b.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-3-g4a8d882022c7/arm64/defconfig/gcc-8/lab-baylibre/baseline-bcm2837-rpi-3-b.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.login: https://kernelci.org/test/case/id/611e370e7bd73a92d1b13670
        failing since 37 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1) 
 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
rk3399-gru-kevin | arm64 | lab-collabora | gcc-8    | defconfig | 2          

  Details:     https://kernelci.org/test/plan/id/611e362b8496575070b13672

  Results:     89 PASS, 2 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-3-g4a8d882022c7/arm64/defconfig/gcc-8/lab-collabora/baseline-rk3399-gru-kevin.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc6-3-g4a8d882022c7/arm64/defconfig/gcc-8/lab-collabora/baseline-rk3399-gru-kevin.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.bootrr.rockchip-usb2phy1-probed: https://kernelci.org/test/case/id/611e362b8496575070b1367c
        failing since 37 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1)

    2021-08-19T10:44:55.250670  /lava-4385016/1/../bin/lava-test-case
    2021-08-19T10:44:55.261850  <8>[   24.865996] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=rockchip-usb2phy1-probed RESULT=fail>   

  * baseline.bootrr.rockchip-usb2phy0-probed: https://kernelci.org/test/case/id/611e362b8496575070b1367d
        failing since 37 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1)

    2021-08-19T10:44:54.215986  /lava-4385016/1/../bin/lava-test-case
    2021-08-19T10:44:54.227432  <8>[   23.831720] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=rockchip-usb2phy0-probed RESULT=fail>   
  


From bbhushan2 at marvell.com  Thu Aug 19 04:52:00 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Thu, 19 Aug 2021 11:52:00 +0000
Subject: [EXT] Re: [PATCH v2 2/4] perf/marvell: CN10k DDR performance
 monitor support
In-Reply-To: <c4e9c893-9130-7024-e24e-c63e232be4be@huawei.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
 <20210810094307.29595-3-bbhushan2@marvell.com>
 <c4e9c893-9130-7024-e24e-c63e232be4be@huawei.com>
Message-ID: <CO6PR18MB4465D5490C1F6141DB454064E3C09@CO6PR18MB4465.namprd18.prod.outlook.com>

Please see inline

> -----Original Message-----
> From: John Garry <john.garry at huawei.com>
> Sent: Wednesday, August 18, 2021 7:19 PM
> To: Bharat Bhushan <bbhushan2 at marvell.com>; will at kernel.org;
> mark.rutland at arm.com; robh+dt at kernel.org; linux-arm-
> kernel at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org
> Subject: [EXT] Re: [PATCH v2 2/4] perf/marvell: CN10k DDR performance monitor
> support
> 
> External Email
> 
> ----------------------------------------------------------------------
> On 10/08/2021 10:43, Bharat Bhushan wrote:
> > Marvell CN10k DRAM Subsystem (DSS) supports eight
> > event counters for monitoring performance and software
> > can program each counter to monitor any of the defined
> > performance event. Performance events are for interface
> > between the DDR controller and the PHY, interface between
> > the DDR Controller and the CHI interconnect, or within
> > the DDR Controller. Additionally DSS also supports two
> > fixed performance event counters, one for number of
> > ddr reads and other for ddr writes.
> >
> > This patch add basic support for these performance
> > monitoring events on CN10k.
> 
> please use full 75 char width

Ok,

> 
> >
> > Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
> > ---
> > v1->v2:
> >   - writeq/readq changed to respective relaxed version
> >   - Using PMU_EVENT_ATTR_ID
> >
> >   drivers/perf/Kconfig                 |   7 +
> >   drivers/perf/Makefile                |   1 +
> >   drivers/perf/marvell_cn10k_ddr_pmu.c | 606 +++++++++++++++++++++++++++
> >   3 files changed, 614 insertions(+)
> >   create mode 100644 drivers/perf/marvell_cn10k_ddr_pmu.c
> >
> > diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
> > index 77522e5efe11..41a80a4b8d29 100644
> > --- a/drivers/perf/Kconfig
> > +++ b/drivers/perf/Kconfig
> > @@ -139,4 +139,11 @@ config ARM_DMC620_PMU
> >
> >   source "drivers/perf/hisilicon/Kconfig"
> >
> > +config MARVELL_CN10K_DDR_PMU
> > +	tristate "Enable MARVELL CN10K DRAM Subsystem(DSS) PMU Support"
> > +	depends on ARM64
> 
> Is there anything to stop using adding COMPILE_TEST as a dependency?
> This really helps build coverage testing for other archs

Just keeping same as other drivers

> 
> > +	help
> > +	  Enable perf support for Marvell DDR Performance monitoring
> > +	  event on CN10K platform.
> > +
> >   endmenu
> > diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
> > index 5260b116c7da..ee1126219d8d 100644
> > --- a/drivers/perf/Makefile
> > +++ b/drivers/perf/Makefile
> > @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
> >   obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
> >   obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
> >   obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
> > +obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
> > diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c
> b/drivers/perf/marvell_cn10k_ddr_pmu.c
> > new file mode 100644
> > index 000000000000..8f9e3d1fcd8d
> > --- /dev/null
> > +++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
> > @@ -0,0 +1,606 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/* Marvell CN10K DRAM Subsystem (DSS) Performance Monitor Driver
> > + *
> > + * Copyright (C) 2021 Marvell.
> > + */
> > +
> > +#include <linux/init.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> > +#include <linux/perf_event.h>
> > +
> > +/* Performance Counters Operating Mode Control Registers */
> > +#define DDRC_PERF_CNT_OP_MODE_CTRL	0x8020
> > +#define OP_MODE_CTRL_VAL_MANNUAL	0x1
> > +
> > +/* Performance Counters Start Operation Control Registers */
> > +#define DDRC_PERF_CNT_START_OP_CTRL	0x8028
> > +#define START_OP_CTRL_VAL_START		0x1ULL
> > +#define START_OP_CTRL_VAL_ACTIVE	0x2
> > +
> > +/* Performance Counters End Operation Control Registers */
> > +#define DDRC_PERF_CNT_END_OP_CTRL	0x8030
> > +#define END_OP_CTRL_VAL_END		0x1ULL
> > +
> > +/* Performance Counters End Status Registers */
> > +#define DDRC_PERF_CNT_END_STATUS		0x8038
> > +#define END_STATUS_VAL_END_TIMER_MODE_END	0x1
> > +
> > +/* Performance Counters Configuration Registers */
> > +#define DDRC_PERF_CFG_BASE		0x8040
> > +
> > +/* 8 Generic event counter + 2 fixed event counters */
> > +#define DDRC_PERF_NUM_GEN_COUNTERS	8
> > +#define DDRC_PERF_NUM_FIX_COUNTERS	2
> > +#define DDRC_PERF_READ_COUNTER_IDX
> 	DDRC_PERF_NUM_GEN_COUNTERS
> > +#define DDRC_PERF_WRITE_COUNTER_IDX
> 	(DDRC_PERF_NUM_GEN_COUNTERS + 1)
> > +#define DDRC_PERF_NUM_COUNTERS
> 	(DDRC_PERF_NUM_GEN_COUNTERS + \
> > +					 DDRC_PERF_NUM_FIX_COUNTERS)
> > +
> > +/* Generic event counter registers */
> > +#define DDRC_PERF_CFG(n)		(DDRC_PERF_CFG_BASE + 8 * (n))
> > +#define EVENT_ENABLE			BIT_ULL(63)
> > +
> > +/* Two dedicated event counters for DDR reads and writes */
> > +#define EVENT_DDR_READS			101
> > +#define EVENT_DDR_WRITES		100
> > +
> > +/*
> > + * programmable events IDs in programmable event counters.
> > + * DO NOT change these event-id numbers, they are used to
> > + * program event bitmap in h/w.
> > + */
> > +#define EVENT_OP_IS_ZQLATCH			55
> > +#define EVENT_OP_IS_ZQSTART			54
> > +#define EVENT_OP_IS_TCR_MRR			53
> > +#define EVENT_OP_IS_DQSOSC_MRR			52
> > +#define EVENT_OP_IS_DQSOSC_MPC			51
> > +#define EVENT_VISIBLE_WIN_LIMIT_REACHED_WR	50
> > +#define EVENT_VISIBLE_WIN_LIMIT_REACHED_RD	49
> > +#define EVENT_BSM_STARVATION			48
> > +#define EVENT_BSM_ALLOC				47
> > +#define EVENT_LPR_REQ_WITH_NOCREDIT		46
> > +#define EVENT_HPR_REQ_WITH_NOCREDIT		45
> > +#define EVENT_OP_IS_ZQCS			44
> > +#define EVENT_OP_IS_ZQCL			43
> > +#define EVENT_OP_IS_LOAD_MODE			42
> > +#define EVENT_OP_IS_SPEC_REF			41
> > +#define EVENT_OP_IS_CRIT_REF			40
> > +#define EVENT_OP_IS_REFRESH			39
> > +#define EVENT_OP_IS_ENTER_MPSM			35
> > +#define EVENT_OP_IS_ENTER_POWERDOWN		31
> > +#define EVENT_OP_IS_ENTER_SELFREF		27
> > +#define EVENT_WAW_HAZARD			26
> > +#define EVENT_RAW_HAZARD			25
> > +#define EVENT_WAR_HAZARD			24
> > +#define EVENT_WRITE_COMBINE			23
> > +#define EVENT_RDWR_TRANSITIONS			22
> > +#define EVENT_PRECHARGE_FOR_OTHER		21
> > +#define EVENT_PRECHARGE_FOR_RDWR		20
> > +#define EVENT_OP_IS_PRECHARGE			19
> > +#define EVENT_OP_IS_MWR				18
> > +#define EVENT_OP_IS_WR				17
> > +#define EVENT_OP_IS_RD				16
> > +#define EVENT_OP_IS_RD_ACTIVATE			15
> > +#define EVENT_OP_IS_RD_OR_WR			14
> > +#define EVENT_OP_IS_ACTIVATE			13
> > +#define EVENT_WR_XACT_WHEN_CRITICAL		12
> > +#define EVENT_LPR_XACT_WHEN_CRITICAL		11
> > +#define EVENT_HPR_XACT_WHEN_CRITICAL		10
> > +#define EVENT_DFI_RD_DATA_CYCLES		9
> > +#define EVENT_DFI_WR_DATA_CYCLES		8
> > +#define EVENT_ACT_BYPASS			7
> > +#define EVENT_READ_BYPASS			6
> > +#define EVENT_HIF_HI_PRI_RD			5
> > +#define EVENT_HIF_RMW				4
> > +#define EVENT_HIF_RD				3
> > +#define EVENT_HIF_WR				2
> > +#define EVENT_HIF_RD_OR_WR			1
> > +
> > +/* Event counter value registers */
> > +#define DDRC_PERF_CNT_VALUE_BASE		0x8080
> > +#define DDRC_PERF_CNT_VALUE(n)	(DDRC_PERF_CNT_VALUE_BASE + 8 * (n))
> > +
> > +/* Fixed event counter enable/disable register */
> > +#define DDRC_PERF_CNT_FREERUN_EN	0x80C0
> > +#define DDRC_PERF_FREERUN_WRITE_EN	0x1
> > +#define DDRC_PERF_FREERUN_READ_EN	0x2
> > +
> > +/* Fixed event counter control register */
> > +#define DDRC_PERF_CNT_FREERUN_CTRL	0x80C8
> > +#define DDRC_FREERUN_WRITE_CNT_CLR	0x1
> > +#define DDRC_FREERUN_READ_CNT_CLR	0x2
> > +
> > +/* Fixed event counter value register */
> > +#define DDRC_PERF_CNT_VALUE_WR_OP	0x80D0
> > +#define DDRC_PERF_CNT_VALUE_RD_OP	0x80D8
> > +#define DDRC_PERF_CNT_VALUE_OVERFLOW	BIT_ULL(48)
> > +#define DDRC_PERF_CNT_MAX_VALUE		GENMASK_ULL(48, 0)
> 
> I assume all these macros are used...

Yes, do you see any unused?

> 
> > +
> > +struct cn10k_ddr_pmu {
> > +	struct pmu pmu;
> > +	int id;
> > +	void __iomem *base;
> > +	unsigned int cpu;
> > +	struct	device *dev;
> > +	int active_events;
> > +	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
> > +};
> > +
> > +#define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu,
> pmu)
> > +
> > +static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
> > +					struct device_attribute *attr,
> > +					char *page)
> > +{
> > +	struct perf_pmu_events_attr *pmu_attr;
> > +
> > +	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
> > +	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
> 
> isn't sysfs_emit() preferred now? Need to check.

Yes, Thanks for pointing.

> 
> > +}
> > +
> > +#define CN10K_DDR_PMU_EVENT_ATTR(_name, _id)
> 	     \
> > +	PMU_EVENT_ATTR_ID(_name, cn10k_ddr_pmu_event_show, _id)
> > +
> > +static struct attribute *cn10k_ddr_perf_events_attrs[] = {
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access,
> EVENT_HIF_RD_OR_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access,
> EVENT_HIF_RMW),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess,
> EVENT_HIF_HI_PRI_RD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access,
> EVENT_READ_BYPASS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access,
> EVENT_ACT_BYPASS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_wr_data_access,
> EVENT_DFI_WR_DATA_CYCLES),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_rd_data_access,
> EVENT_DFI_RD_DATA_CYCLES),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
> > +					EVENT_HPR_XACT_WHEN_CRITICAL),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
> > +					EVENT_LPR_XACT_WHEN_CRITICAL),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
> > +					EVENT_WR_XACT_WHEN_CRITICAL),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access,
> EVENT_OP_IS_ACTIVATE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access,
> EVENT_OP_IS_RD_OR_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access,
> EVENT_OP_IS_RD_ACTIVATE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge,
> EVENT_OP_IS_PRECHARGE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr,
> EVENT_PRECHARGE_FOR_RDWR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
> > +					EVENT_PRECHARGE_FOR_OTHER),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions,
> EVENT_RDWR_TRANSITIONS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine,
> EVENT_WRITE_COMBINE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard,
> EVENT_WAR_HAZARD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard,
> EVENT_RAW_HAZARD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard,
> EVENT_WAW_HAZARD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref,
> EVENT_OP_IS_ENTER_SELFREF),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown,
> EVENT_OP_IS_ENTER_POWERDOWN),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_mpsm,
> EVENT_OP_IS_ENTER_MPSM),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode,
> EVENT_OP_IS_LOAD_MODE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqcl, EVENT_OP_IS_ZQCL),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_wr_access,
> EVENT_OP_IS_ZQCS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpr_req_with_nocredit,
> > +					EVENT_HPR_REQ_WITH_NOCREDIT),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpr_req_with_nocredit,
> > +					EVENT_LPR_REQ_WITH_NOCREDIT),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_alloc, EVENT_BSM_ALLOC),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_starvation,
> EVENT_BSM_STARVATION),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
> > +
> 	EVENT_VISIBLE_WIN_LIMIT_REACHED_RD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
> > +
> 	EVENT_VISIBLE_WIN_LIMIT_REACHED_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc,
> EVENT_OP_IS_DQSOSC_MPC),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr,
> EVENT_OP_IS_DQSOSC_MRR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_OP_IS_TCR_MRR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_OP_IS_ZQSTART),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_OP_IS_ZQLATCH),
> > +	/* Free run event counters */
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),
> 
> if you want perf tool to support aliases / metrics for these then a hw
> identifer sysfs file is required, like the freescale imx8 ddr pmu driver
> has, as I assume that this PMU is not tightly coupled always to a
> specific CPU

As of now we do not have ddr pmu versioning.

> 
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
> > +	NULL,
> 
> no need for ',' when the array is not going to be expanded

Oh yes,

> 
> > +};
> > +
> > +static struct attribute_group cn10k_ddr_perf_events_attr_group = {
> > +	.name = "events",
> > +	.attrs = cn10k_ddr_perf_events_attrs,
> > +};
> > +
> > +PMU_FORMAT_ATTR(event, "config:0-8");
> > +
> > +static struct attribute *cn10k_ddr_perf_format_attrs[] = {
> > +	&format_attr_event.attr,
> > +	NULL,
> > +};
> > +
> > +static struct attribute_group cn10k_ddr_perf_format_attr_group = {
> > +	.name = "format",
> > +	.attrs = cn10k_ddr_perf_format_attrs,
> > +};
> > +
> > +static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
> > +					   struct device_attribute *attr,
> > +					   char *buf)
> > +{
> > +	struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
> > +
> > +	return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
> > +}
> > +
> > +static struct device_attribute cn10k_ddr_perf_cpumask_attr =
> > +	__ATTR(cpumask, 0444, cn10k_ddr_perf_cpumask_show, NULL);
> > +
> > +static struct attribute *cn10k_ddr_perf_cpumask_attrs[] = {
> > +	&cn10k_ddr_perf_cpumask_attr.attr,
> > +	NULL,
> > +};
> > +
> > +static struct attribute_group cn10k_ddr_perf_cpumask_attr_group = {
> > +	.attrs = cn10k_ddr_perf_cpumask_attrs,
> > +};
> > +
> > +static const struct attribute_group *cn10k_attr_groups[] = {
> > +	&cn10k_ddr_perf_events_attr_group,
> > +	&cn10k_ddr_perf_format_attr_group,
> > +	&cn10k_ddr_perf_cpumask_attr_group,
> > +	NULL,
> > +};
> > +
> > +static uint64_t ddr_perf_get_event_bitmap(int eventid)
> 
> Don't we use u64 in kernel land as preference?

I am not aware of any guidance or rule, both are being used.
I end up using uint64_t and u64 both, will use one only with next version. 

> 
> > +{
> > +	uint64_t event_bitmap = 0;
> > +
> > +	switch (eventid) {
> > +	case EVENT_HIF_RD_OR_WR ... EVENT_WAW_HAZARD:
> > +	case EVENT_OP_IS_REFRESH ... EVENT_OP_IS_ZQLATCH:
> > +		event_bitmap = (1ULL << (eventid - 1));
> > +		break;
> > +
> > +	case EVENT_OP_IS_ENTER_SELFREF:
> > +	case EVENT_OP_IS_ENTER_POWERDOWN:
> > +	case EVENT_OP_IS_ENTER_MPSM:
> > +		event_bitmap = (0xFULL << (eventid - 1));
> > +		break;
> > +	default:
> > +		pr_err("%s Invalid eventid %d\n", __func__, eventid);
> 
> shouldn't this generate a proper error to its only caller (which can
> actually error)?

Ack, currently it just through error but does not error out.

> 
> > +		break;
> > +	}
> > +
> > +	return event_bitmap;
> > +}
> > +
> > +static int cn10k_ddr_perf_alloc_counter(struct cn10k_ddr_pmu *pmu,
> > +					struct perf_event *event)
> > +{
> > +	uint8_t config = event->attr.config;
> > +	int i;
> > +
> > +	/* DDR read free-run counter index */
> > +	if (config == EVENT_DDR_READS) {
> > +		pmu->events[DDRC_PERF_READ_COUNTER_IDX] = event;
> > +		return DDRC_PERF_READ_COUNTER_IDX;
> > +	}
> > +
> > +	/* DDR write free-run counter index */
> > +	if (config == EVENT_DDR_WRITES) {
> > +		pmu->events[DDRC_PERF_WRITE_COUNTER_IDX] = event;
> > +		return DDRC_PERF_WRITE_COUNTER_IDX;
> > +	}
> > +
> > +	/* Allocate DDR generic counters */
> > +	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
> > +		if (pmu->events[i] == NULL) {
> > +			pmu->events[i] = event;
> > +			return i;
> > +		}
> > +	}
> > +
> > +	return -ENOENT;
> > +}
> > +
> > +static void cn10k_ddr_perf_free_counter(struct cn10k_ddr_pmu *pmu, int
> counter)
> > +{
> > +	pmu->events[counter] = NULL;
> > +}
> > +
> > +static int cn10k_ddr_perf_event_init(struct perf_event *event)
> > +{
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +
> > +	if (event->attr.type != event->pmu->type)
> > +		return -ENOENT;
> > +
> > +	if (is_sampling_event(event)) {
> > +		dev_info(pmu->dev, "Sampling not supported!\n");
> > +		return -EOPNOTSUPP;
> > +	}
> > +
> > +	if (event->cpu < 0) {
> > +		dev_warn(pmu->dev, "Can't provide per-task data!\n");
> > +		return -EOPNOTSUPP;
> > +	}
> > +
> > +	/*  We must NOT create groups containing mixed PMUs */
> > +	if (event->group_leader->pmu != event->pmu &&
> > +			!is_software_event(event->group_leader))
> 
> pay attention to indentation

Accepted, not sure how this got in.

> 
> > +		return -EINVAL;
> > +
> > +	/* Set ownership of event to one CPU, same event can not be observed
> > +	 * on multiple cpus at same time.
> > +	 */
> > +	event->cpu = pmu->cpu;
> > +	hwc->idx = -1;
> > +	return 0;
> > +}
> > +
> > +static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
> > +					  int counter, bool enable)
> > +{
> > +	uint32_t reg;
> > +	uint64_t val;
> > +
> > +	if (counter > DDRC_PERF_NUM_COUNTERS) {
> 
> is this paranoia?

We can not program if counter by any means is out or range.

> 
> > +		pr_err("Error: unsupported counter %d\n", counter);
> > +		return;
> > +	}
> > +
> > +	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
> > +		reg = DDRC_PERF_CFG(counter);
> > +		val = readq_relaxed(pmu->base + reg);
> > +
> > +		if (enable)
> > +			val |= EVENT_ENABLE;
> > +		else
> > +			val &= ~EVENT_ENABLE;
> > +
> > +		writeq_relaxed(val, pmu->base + reg);
> > +	} else {
> > +		val = readq_relaxed(pmu->base +
> DDRC_PERF_CNT_FREERUN_EN);
> > +		if (enable) {
> > +			if (counter == DDRC_PERF_READ_COUNTER_IDX)
> > +				val |= DDRC_PERF_FREERUN_READ_EN;
> > +			else
> > +				val |= DDRC_PERF_FREERUN_WRITE_EN;
> > +		} else {
> > +			if (counter == DDRC_PERF_READ_COUNTER_IDX)
> > +				val &= ~DDRC_PERF_FREERUN_READ_EN;
> > +			else
> > +				val &= ~DDRC_PERF_FREERUN_WRITE_EN;
> > +		}
> > +		writeq_relaxed(val, pmu->base +
> DDRC_PERF_CNT_FREERUN_EN);
> > +	}
> > +}
> > +
> > +static uint64_t cn10k_ddr_perf_read_counter(struct cn10k_ddr_pmu *pmu,
> > +					    int counter)
> > +{
> > +	uint64_t val;
> > +
> > +	if (counter == DDRC_PERF_READ_COUNTER_IDX)
> > +		return readq_relaxed(pmu->base +
> DDRC_PERF_CNT_VALUE_RD_OP);
> > +
> > +	if (counter == DDRC_PERF_WRITE_COUNTER_IDX)
> > +		return readq_relaxed(pmu->base +
> DDRC_PERF_CNT_VALUE_WR_OP);
> > +
> > +	val = readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE(counter));
> > +	return val;
> > +}
> > +
> > +static void cn10k_ddr_perf_event_update(struct perf_event *event)
> > +{
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	uint64_t prev_count, new_count, mask;
> > +
> > +	do {
> > +		prev_count = local64_read(&hwc->prev_count);
> > +		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
> > +	} while (local64_xchg(&hwc->prev_count, new_count) != prev_count);
> > +
> > +	mask = DDRC_PERF_CNT_MAX_VALUE;
> > +
> > +	local64_add((new_count - prev_count) & mask, &event->count);
> > +}
> > +
> > +static void cn10k_ddr_perf_event_start(struct perf_event *event, int flags)
> > +{
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	int counter = hwc->idx;
> > +
> > +	local64_set(&hwc->prev_count, 0);
> > +
> > +	cn10k_ddr_perf_counter_enable(pmu, counter, true);
> > +
> > +	hwc->state = 0;
> > +}
> > +
> > +static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
> > +{
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	uint8_t config = event->attr.config;
> > +	uint32_t reg_offset;
> > +	uint64_t val;
> > +	int counter;
> > +
> > +	counter = cn10k_ddr_perf_alloc_counter(pmu, event);
> > +	if (counter < 0) {
> > +		dev_dbg(pmu->dev, "There are not enough counters\n");
> 
> hmmm .. I'd be inclined to say that there are not enough available. And
> is dev_dbg() really any use?

Maybe we can remove the error print now, and return 

> 
> > +		return -EOPNOTSUPP;
> 
> is that the best error code?

Looks like we should let it try again later  "-EAGAIN"

> 
> > +	}
> > +
> > +	pmu->active_events++;
> > +	hwc->idx = counter;
> > +
> > +	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
> > +		/* Generic counters, configure event id */
> > +		reg_offset = DDRC_PERF_CFG(counter);
> > +		val = ddr_perf_get_event_bitmap(config);
> > +		writeq_relaxed(val, pmu->base + reg_offset);
> > +	} else {
> > +		/* fixed event counter, clear counter value */
> > +		if (counter == DDRC_PERF_READ_COUNTER_IDX)
> > +			val = DDRC_FREERUN_READ_CNT_CLR;
> > +		else
> > +			val = DDRC_FREERUN_WRITE_CNT_CLR;
> > +
> > +		writeq_relaxed(val, pmu->base +
> DDRC_PERF_CNT_FREERUN_CTRL);
> > +	}
> > +
> > +	hwc->state |= PERF_HES_STOPPED;
> > +
> > +	if (flags & PERF_EF_START)
> > +		cn10k_ddr_perf_event_start(event, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static void cn10k_ddr_perf_event_stop(struct perf_event *event, int flags)
> > +{
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	int counter = hwc->idx;
> > +
> > +	cn10k_ddr_perf_counter_enable(pmu, counter, false);
> > +
> > +	if (flags & PERF_EF_UPDATE)
> > +		cn10k_ddr_perf_event_update(event);
> > +
> > +	hwc->state |= PERF_HES_STOPPED;
> > +}
> > +
> > +static void cn10k_ddr_perf_event_del(struct perf_event *event, int flags)
> > +{
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	int counter = hwc->idx;
> > +
> > +	cn10k_ddr_perf_event_stop(event, PERF_EF_UPDATE);
> > +
> > +	cn10k_ddr_perf_free_counter(pmu, counter);
> > +	pmu->active_events--;
> > +	hwc->idx = -1;
> > +}
> > +
> > +static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu)
> > +{
> > +	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
> > +
> > +	writeq_relaxed(START_OP_CTRL_VAL_START, ddr_pmu->base +
> > +		       DDRC_PERF_CNT_START_OP_CTRL);
> > +}
> > +
> > +static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu)
> > +{
> > +	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
> > +
> > +	writeq_relaxed(END_OP_CTRL_VAL_END, ddr_pmu->base +
> > +		       DDRC_PERF_CNT_END_OP_CTRL);
> > +}
> > +
> > +static int cn10k_ddr_perf_probe(struct platform_device *pdev)
> > +{
> > +	struct cn10k_ddr_pmu *ddr_pmu;
> > +	struct resource *res;
> > +	void __iomem *base;
> > +	static int index;
> > +	char *name;
> > +	int ret;
> > +
> > +	ddr_pmu = devm_kzalloc(&pdev->dev, sizeof(*ddr_pmu), GFP_KERNEL);
> > +	if (!ddr_pmu)
> > +		return -ENOMEM;
> > +
> > +	ddr_pmu->dev = &pdev->dev;
> > +	platform_set_drvdata(pdev, ddr_pmu);
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	base = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(base))
> > +		return PTR_ERR(base);
> 
> can you use devm_platform_get_and_ioremap_resource()? I think that there
> is some helper that does both these steps

Yes, devm_platform_get_and_ioremap_resource() does both.
 

> 
> > +
> > +	ddr_pmu->base = base;
> > +
> > +	/* Setup the PMU counter to work in mannual mode */
> 
> manual
> 
> > +	writeq_relaxed(OP_MODE_CTRL_VAL_MANNUAL, ddr_pmu->base +
> > +		       DDRC_PERF_CNT_OP_MODE_CTRL);
> > +
> > +	ddr_pmu->pmu = (struct pmu) {
> > +		.module	      = THIS_MODULE,
> > +		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> > +		.task_ctx_nr = perf_invalid_context,
> > +		.attr_groups = cn10k_attr_groups,
> > +		.event_init  = cn10k_ddr_perf_event_init,
> > +		.add	     = cn10k_ddr_perf_event_add,
> > +		.del	     = cn10k_ddr_perf_event_del,
> > +		.start	     = cn10k_ddr_perf_event_start,
> > +		.stop	     = cn10k_ddr_perf_event_stop,
> > +		.read	     = cn10k_ddr_perf_event_update,
> > +		.pmu_enable  = cn10k_ddr_perf_pmu_enable,
> > +		.pmu_disable = cn10k_ddr_perf_pmu_disable,
> > +	};
> > +
> > +	/* Choose this cpu to collect perf data */
> > +	ddr_pmu->cpu = raw_smp_processor_id();
> > +
> > +	name = devm_kasprintf(ddr_pmu->dev, GFP_KERNEL,
> "mrvl_ddr_pmu@%llx",
> 
> mostly _%llx would be used elsewhere, and I am not sure how perf tool
> likes @ at all

Will be consistent with other,

> 
> > +			      res->start);
> > +	if (!name)
> > +		return -ENOMEM;
> > +
> > +	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ddr_pmu->id = index++;
> 
> where is this used?

Just below to keep count of number of instance.

Thanks for review, will do required changes in next version.

Thanks
-Bharat
> 
> > +	pr_info("CN10K DDR PMU Driver for ddrc@%llx - id-%d\n",
> > +		res->start, ddr_pmu->id);
> > +	return 0;
> > +}
> > +
> > +static int cn10k_ddr_perf_remove(struct platform_device *pdev)
> > +{
> > +	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
> > +
> > +	perf_pmu_unregister(&ddr_pmu->pmu);
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
> > +	{ .compatible = "marvell,cn10k-ddr-pmu", },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
> > +
> > +static struct platform_driver cn10k_ddr_pmu_driver = {
> > +	.driver	= {
> > +		.name   = "cn10k-ddr-pmu",
> > +		.of_match_table = cn10k_ddr_pmu_of_match,
> > +		.suppress_bind_attrs = true,
> > +	},
> > +	.probe		= cn10k_ddr_perf_probe,
> > +	.remove		= cn10k_ddr_perf_remove,
> > +};
> > +
> > +static int __init cn10k_ddr_pmu_init(void)
> > +{
> > +	return platform_driver_register(&cn10k_ddr_pmu_driver);
> > +}
> > +
> > +static void __exit cn10k_ddr_pmu_exit(void)
> > +{
> > +	platform_driver_unregister(&cn10k_ddr_pmu_driver);
> > +}
> > +
> > +module_init(cn10k_ddr_pmu_init);
> > +module_exit(cn10k_ddr_pmu_exit);
> > +
> > +MODULE_AUTHOR("Bharat Bhushan <bbhushan2 at marvell.com>");
> > +MODULE_LICENSE("GPL v2");
> >


From bbhushan2 at marvell.com  Thu Aug 19 04:52:36 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Thu, 19 Aug 2021 11:52:36 +0000
Subject: [EXT] Re: [PATCH v2 2/4] perf/marvell: CN10k DDR performance
 monitor support
In-Reply-To: <329a1d8c-1b93-443c-a1d8-484083a8978f@linux.ibm.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
 <20210810094307.29595-3-bbhushan2@marvell.com>
 <329a1d8c-1b93-443c-a1d8-484083a8978f@linux.ibm.com>
Message-ID: <CO6PR18MB44650D2C095973B511212D45E3C09@CO6PR18MB4465.namprd18.prod.outlook.com>

Please see inline 

> -----Original Message-----
> From: kajoljain <kjain at linux.ibm.com>
> Sent: Wednesday, August 18, 2021 5:58 PM
> To: Bharat Bhushan <bbhushan2 at marvell.com>; will at kernel.org;
> mark.rutland at arm.com; robh+dt at kernel.org; linux-arm-
> kernel at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org
> Subject: [EXT] Re: [PATCH v2 2/4] perf/marvell: CN10k DDR performance monitor
> support
> 
> External Email
> 
> ----------------------------------------------------------------------
> 
> 
> On 8/10/21 3:13 PM, Bharat Bhushan wrote:
> > Marvell CN10k DRAM Subsystem (DSS) supports eight event counters for
> > monitoring performance and software can program each counter to
> > monitor any of the defined performance event. Performance events are
> > for interface between the DDR controller and the PHY, interface
> > between the DDR Controller and the CHI interconnect, or within the DDR
> > Controller. Additionally DSS also supports two fixed performance event
> > counters, one for number of ddr reads and other for ddr writes.
> >
> > This patch add basic support for these performance monitoring events
> > on CN10k.
> >
> > Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
> > ---
> > v1->v2:
> >  - writeq/readq changed to respective relaxed version
> >  - Using PMU_EVENT_ATTR_ID
> >
> >  drivers/perf/Kconfig                 |   7 +
> >  drivers/perf/Makefile                |   1 +
> >  drivers/perf/marvell_cn10k_ddr_pmu.c | 606
> > +++++++++++++++++++++++++++
> >  3 files changed, 614 insertions(+)
> >  create mode 100644 drivers/perf/marvell_cn10k_ddr_pmu.c
> >
> > diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig index
> > 77522e5efe11..41a80a4b8d29 100644
> > --- a/drivers/perf/Kconfig
> > +++ b/drivers/perf/Kconfig
> > @@ -139,4 +139,11 @@ config ARM_DMC620_PMU
> >
> >  source "drivers/perf/hisilicon/Kconfig"
> >
> > +config MARVELL_CN10K_DDR_PMU
> > +	tristate "Enable MARVELL CN10K DRAM Subsystem(DSS) PMU Support"
> > +	depends on ARM64
> > +	help
> > +	  Enable perf support for Marvell DDR Performance monitoring
> > +	  event on CN10K platform.
> > +
> >  endmenu
> > diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile index
> > 5260b116c7da..ee1126219d8d 100644
> > --- a/drivers/perf/Makefile
> > +++ b/drivers/perf/Makefile
> > @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
> >  obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
> >  obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
> >  obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
> > +obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
> > diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c
> > b/drivers/perf/marvell_cn10k_ddr_pmu.c
> > new file mode 100644
> > index 000000000000..8f9e3d1fcd8d
> > --- /dev/null
> > +++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
> > @@ -0,0 +1,606 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/* Marvell CN10K DRAM Subsystem (DSS) Performance Monitor Driver
> > + *
> > + * Copyright (C) 2021 Marvell.
> > + */
> > +
> > +#include <linux/init.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> > +#include <linux/perf_event.h>
> > +
> > +/* Performance Counters Operating Mode Control Registers */
> > +#define DDRC_PERF_CNT_OP_MODE_CTRL	0x8020
> > +#define OP_MODE_CTRL_VAL_MANNUAL	0x1
> > +
> > +/* Performance Counters Start Operation Control Registers */
> > +#define DDRC_PERF_CNT_START_OP_CTRL	0x8028
> > +#define START_OP_CTRL_VAL_START		0x1ULL
> > +#define START_OP_CTRL_VAL_ACTIVE	0x2
> > +
> > +/* Performance Counters End Operation Control Registers */
> > +#define DDRC_PERF_CNT_END_OP_CTRL	0x8030
> > +#define END_OP_CTRL_VAL_END		0x1ULL
> > +
> > +/* Performance Counters End Status Registers */
> > +#define DDRC_PERF_CNT_END_STATUS		0x8038
> > +#define END_STATUS_VAL_END_TIMER_MODE_END	0x1
> > +
> > +/* Performance Counters Configuration Registers */
> > +#define DDRC_PERF_CFG_BASE		0x8040
> > +
> > +/* 8 Generic event counter + 2 fixed event counters */
> > +#define DDRC_PERF_NUM_GEN_COUNTERS	8
> > +#define DDRC_PERF_NUM_FIX_COUNTERS	2
> > +#define DDRC_PERF_READ_COUNTER_IDX
> 	DDRC_PERF_NUM_GEN_COUNTERS
> > +#define DDRC_PERF_WRITE_COUNTER_IDX
> 	(DDRC_PERF_NUM_GEN_COUNTERS + 1)
> > +#define DDRC_PERF_NUM_COUNTERS
> 	(DDRC_PERF_NUM_GEN_COUNTERS + \
> > +					 DDRC_PERF_NUM_FIX_COUNTERS)
> > +
> > +/* Generic event counter registers */
> > +#define DDRC_PERF_CFG(n)		(DDRC_PERF_CFG_BASE + 8 * (n))
> > +#define EVENT_ENABLE			BIT_ULL(63)
> > +
> > +/* Two dedicated event counters for DDR reads and writes */
> > +#define EVENT_DDR_READS			101
> > +#define EVENT_DDR_WRITES		100
> > +
> > +/*
> > + * programmable events IDs in programmable event counters.
> > + * DO NOT change these event-id numbers, they are used to
> > + * program event bitmap in h/w.
> > + */
> > +#define EVENT_OP_IS_ZQLATCH			55
> > +#define EVENT_OP_IS_ZQSTART			54
> > +#define EVENT_OP_IS_TCR_MRR			53
> > +#define EVENT_OP_IS_DQSOSC_MRR			52
> > +#define EVENT_OP_IS_DQSOSC_MPC			51
> > +#define EVENT_VISIBLE_WIN_LIMIT_REACHED_WR	50
> > +#define EVENT_VISIBLE_WIN_LIMIT_REACHED_RD	49
> > +#define EVENT_BSM_STARVATION			48
> > +#define EVENT_BSM_ALLOC				47
> > +#define EVENT_LPR_REQ_WITH_NOCREDIT		46
> > +#define EVENT_HPR_REQ_WITH_NOCREDIT		45
> > +#define EVENT_OP_IS_ZQCS			44
> > +#define EVENT_OP_IS_ZQCL			43
> > +#define EVENT_OP_IS_LOAD_MODE			42
> > +#define EVENT_OP_IS_SPEC_REF			41
> > +#define EVENT_OP_IS_CRIT_REF			40
> > +#define EVENT_OP_IS_REFRESH			39
> > +#define EVENT_OP_IS_ENTER_MPSM			35
> > +#define EVENT_OP_IS_ENTER_POWERDOWN		31
> > +#define EVENT_OP_IS_ENTER_SELFREF		27
> > +#define EVENT_WAW_HAZARD			26
> > +#define EVENT_RAW_HAZARD			25
> > +#define EVENT_WAR_HAZARD			24
> > +#define EVENT_WRITE_COMBINE			23
> > +#define EVENT_RDWR_TRANSITIONS			22
> > +#define EVENT_PRECHARGE_FOR_OTHER		21
> > +#define EVENT_PRECHARGE_FOR_RDWR		20
> > +#define EVENT_OP_IS_PRECHARGE			19
> > +#define EVENT_OP_IS_MWR				18
> > +#define EVENT_OP_IS_WR				17
> > +#define EVENT_OP_IS_RD				16
> > +#define EVENT_OP_IS_RD_ACTIVATE			15
> > +#define EVENT_OP_IS_RD_OR_WR			14
> > +#define EVENT_OP_IS_ACTIVATE			13
> > +#define EVENT_WR_XACT_WHEN_CRITICAL		12
> > +#define EVENT_LPR_XACT_WHEN_CRITICAL		11
> > +#define EVENT_HPR_XACT_WHEN_CRITICAL		10
> > +#define EVENT_DFI_RD_DATA_CYCLES		9
> > +#define EVENT_DFI_WR_DATA_CYCLES		8
> > +#define EVENT_ACT_BYPASS			7
> > +#define EVENT_READ_BYPASS			6
> > +#define EVENT_HIF_HI_PRI_RD			5
> > +#define EVENT_HIF_RMW				4
> > +#define EVENT_HIF_RD				3
> > +#define EVENT_HIF_WR				2
> > +#define EVENT_HIF_RD_OR_WR			1
> > +
> > +/* Event counter value registers */
> > +#define DDRC_PERF_CNT_VALUE_BASE		0x8080
> > +#define DDRC_PERF_CNT_VALUE(n)	(DDRC_PERF_CNT_VALUE_BASE + 8 * (n))
> > +
> > +/* Fixed event counter enable/disable register */
> > +#define DDRC_PERF_CNT_FREERUN_EN	0x80C0
> > +#define DDRC_PERF_FREERUN_WRITE_EN	0x1
> > +#define DDRC_PERF_FREERUN_READ_EN	0x2
> > +
> > +/* Fixed event counter control register */
> > +#define DDRC_PERF_CNT_FREERUN_CTRL	0x80C8
> > +#define DDRC_FREERUN_WRITE_CNT_CLR	0x1
> > +#define DDRC_FREERUN_READ_CNT_CLR	0x2
> > +
> > +/* Fixed event counter value register */
> > +#define DDRC_PERF_CNT_VALUE_WR_OP	0x80D0
> > +#define DDRC_PERF_CNT_VALUE_RD_OP	0x80D8
> > +#define DDRC_PERF_CNT_VALUE_OVERFLOW	BIT_ULL(48)
> > +#define DDRC_PERF_CNT_MAX_VALUE		GENMASK_ULL(48, 0)
> > +
> > +struct cn10k_ddr_pmu {
> > +	struct pmu pmu;
> > +	int id;
> > +	void __iomem *base;
> > +	unsigned int cpu;
> > +	struct	device *dev;
> > +	int active_events;
> > +	struct perf_event *events[DDRC_PERF_NUM_COUNTERS]; };
> > +
> > +#define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu,
> pmu)
> > +
> > +static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
> > +					struct device_attribute *attr,
> > +					char *page)
> > +{
> > +	struct perf_pmu_events_attr *pmu_attr;
> > +
> > +	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
> > +	return sprintf(page, "event=0x%02llx\n", pmu_attr->id); }
> > +
> > +#define CN10K_DDR_PMU_EVENT_ATTR(_name, _id)
> 	     \
> > +	PMU_EVENT_ATTR_ID(_name, cn10k_ddr_pmu_event_show, _id)
> > +
> > +static struct attribute *cn10k_ddr_perf_events_attrs[] = {
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access,
> EVENT_HIF_RD_OR_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access,
> EVENT_HIF_RMW),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess,
> EVENT_HIF_HI_PRI_RD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access,
> EVENT_READ_BYPASS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access,
> EVENT_ACT_BYPASS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_wr_data_access,
> EVENT_DFI_WR_DATA_CYCLES),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_rd_data_access,
> EVENT_DFI_RD_DATA_CYCLES),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
> > +					EVENT_HPR_XACT_WHEN_CRITICAL),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
> > +					EVENT_LPR_XACT_WHEN_CRITICAL),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
> > +					EVENT_WR_XACT_WHEN_CRITICAL),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access,
> EVENT_OP_IS_ACTIVATE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access,
> EVENT_OP_IS_RD_OR_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access,
> EVENT_OP_IS_RD_ACTIVATE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge,
> EVENT_OP_IS_PRECHARGE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr,
> EVENT_PRECHARGE_FOR_RDWR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
> > +					EVENT_PRECHARGE_FOR_OTHER),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions,
> EVENT_RDWR_TRANSITIONS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine,
> EVENT_WRITE_COMBINE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard,
> EVENT_WAR_HAZARD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard,
> EVENT_RAW_HAZARD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard,
> EVENT_WAW_HAZARD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref,
> EVENT_OP_IS_ENTER_SELFREF),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown,
> EVENT_OP_IS_ENTER_POWERDOWN),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_mpsm,
> EVENT_OP_IS_ENTER_MPSM),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode,
> EVENT_OP_IS_LOAD_MODE),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqcl, EVENT_OP_IS_ZQCL),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_wr_access,
> EVENT_OP_IS_ZQCS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpr_req_with_nocredit,
> > +					EVENT_HPR_REQ_WITH_NOCREDIT),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpr_req_with_nocredit,
> > +					EVENT_LPR_REQ_WITH_NOCREDIT),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_alloc, EVENT_BSM_ALLOC),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_starvation,
> EVENT_BSM_STARVATION),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
> > +
> 	EVENT_VISIBLE_WIN_LIMIT_REACHED_RD),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
> > +
> 	EVENT_VISIBLE_WIN_LIMIT_REACHED_WR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc,
> EVENT_OP_IS_DQSOSC_MPC),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr,
> EVENT_OP_IS_DQSOSC_MRR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_OP_IS_TCR_MRR),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_OP_IS_ZQSTART),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_OP_IS_ZQLATCH),
> > +	/* Free run event counters */
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),
> > +	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
> > +	NULL,
> > +};
> > +
> > +static struct attribute_group cn10k_ddr_perf_events_attr_group = {
> > +	.name = "events",
> > +	.attrs = cn10k_ddr_perf_events_attrs, };
> > +
> > +PMU_FORMAT_ATTR(event, "config:0-8");
> > +
> > +static struct attribute *cn10k_ddr_perf_format_attrs[] = {
> > +	&format_attr_event.attr,
> > +	NULL,
> > +};
> > +
> > +static struct attribute_group cn10k_ddr_perf_format_attr_group = {
> > +	.name = "format",
> > +	.attrs = cn10k_ddr_perf_format_attrs, };
> > +
> > +static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
> > +					   struct device_attribute *attr,
> > +					   char *buf)
> > +{
> > +	struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
> > +
> > +	return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu)); }
> > +
> > +static struct device_attribute cn10k_ddr_perf_cpumask_attr =
> > +	__ATTR(cpumask, 0444, cn10k_ddr_perf_cpumask_show, NULL);
> > +
> > +static struct attribute *cn10k_ddr_perf_cpumask_attrs[] = {
> > +	&cn10k_ddr_perf_cpumask_attr.attr,
> > +	NULL,
> > +};
> > +
> > +static struct attribute_group cn10k_ddr_perf_cpumask_attr_group = {
> > +	.attrs = cn10k_ddr_perf_cpumask_attrs, };
> > +
> > +static const struct attribute_group *cn10k_attr_groups[] = {
> > +	&cn10k_ddr_perf_events_attr_group,
> > +	&cn10k_ddr_perf_format_attr_group,
> > +	&cn10k_ddr_perf_cpumask_attr_group,
> > +	NULL,
> > +};
> > +
> > +static uint64_t ddr_perf_get_event_bitmap(int eventid) {
> > +	uint64_t event_bitmap = 0;
> > +
> > +	switch (eventid) {
> > +	case EVENT_HIF_RD_OR_WR ... EVENT_WAW_HAZARD:
> > +	case EVENT_OP_IS_REFRESH ... EVENT_OP_IS_ZQLATCH:
> > +		event_bitmap = (1ULL << (eventid - 1));
> > +		break;
> > +
> > +	case EVENT_OP_IS_ENTER_SELFREF:
> > +	case EVENT_OP_IS_ENTER_POWERDOWN:
> > +	case EVENT_OP_IS_ENTER_MPSM:
> > +		event_bitmap = (0xFULL << (eventid - 1));
> > +		break;
> > +	default:
> > +		pr_err("%s Invalid eventid %d\n", __func__, eventid);
> > +		break;
> > +	}
> > +
> > +	return event_bitmap;
> > +}
> > +
> > +static int cn10k_ddr_perf_alloc_counter(struct cn10k_ddr_pmu *pmu,
> > +					struct perf_event *event)
> > +{
> > +	uint8_t config = event->attr.config;
> > +	int i;
> > +
> > +	/* DDR read free-run counter index */
> > +	if (config == EVENT_DDR_READS) {
> > +		pmu->events[DDRC_PERF_READ_COUNTER_IDX] = event;
> > +		return DDRC_PERF_READ_COUNTER_IDX;
> > +	}
> > +
> > +	/* DDR write free-run counter index */
> > +	if (config == EVENT_DDR_WRITES) {
> > +		pmu->events[DDRC_PERF_WRITE_COUNTER_IDX] = event;
> > +		return DDRC_PERF_WRITE_COUNTER_IDX;
> > +	}
> > +
> > +	/* Allocate DDR generic counters */
> > +	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
> > +		if (pmu->events[i] == NULL) {
> > +			pmu->events[i] = event;
> > +			return i;
> > +		}
> > +	}
> > +
> > +	return -ENOENT;
> > +}
> > +
> > +static void cn10k_ddr_perf_free_counter(struct cn10k_ddr_pmu *pmu,
> > +int counter) {
> > +	pmu->events[counter] = NULL;
> > +}
> > +
> > +static int cn10k_ddr_perf_event_init(struct perf_event *event) {
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +
> > +	if (event->attr.type != event->pmu->type)
> > +		return -ENOENT;
> > +
> > +	if (is_sampling_event(event)) {
> > +		dev_info(pmu->dev, "Sampling not supported!\n");
> > +		return -EOPNOTSUPP;
> > +	}
> > +
> > +	if (event->cpu < 0) {
> > +		dev_warn(pmu->dev, "Can't provide per-task data!\n");
> > +		return -EOPNOTSUPP;
> > +	}
> > +
> > +	/*  We must NOT create groups containing mixed PMUs */
> > +	if (event->group_leader->pmu != event->pmu &&
> > +			!is_software_event(event->group_leader))
> > +		return -EINVAL;
> > +
> > +	/* Set ownership of event to one CPU, same event can not be observed
> > +	 * on multiple cpus at same time.
> > +	 */
> > +	event->cpu = pmu->cpu;
> > +	hwc->idx = -1;
> > +	return 0;
> > +}
> > +
> > +static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
> > +					  int counter, bool enable)
> > +{
> > +	uint32_t reg;
> > +	uint64_t val;
> > +
> > +	if (counter > DDRC_PERF_NUM_COUNTERS) {
> > +		pr_err("Error: unsupported counter %d\n", counter);
> > +		return;
> > +	}
> > +
> > +	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
> > +		reg = DDRC_PERF_CFG(counter);
> > +		val = readq_relaxed(pmu->base + reg);
> > +
> > +		if (enable)
> > +			val |= EVENT_ENABLE;
> > +		else
> > +			val &= ~EVENT_ENABLE;
> > +
> > +		writeq_relaxed(val, pmu->base + reg);
> > +	} else {
> > +		val = readq_relaxed(pmu->base +
> DDRC_PERF_CNT_FREERUN_EN);
> > +		if (enable) {
> > +			if (counter == DDRC_PERF_READ_COUNTER_IDX)
> > +				val |= DDRC_PERF_FREERUN_READ_EN;
> > +			else
> > +				val |= DDRC_PERF_FREERUN_WRITE_EN;
> > +		} else {
> > +			if (counter == DDRC_PERF_READ_COUNTER_IDX)
> > +				val &= ~DDRC_PERF_FREERUN_READ_EN;
> > +			else
> > +				val &= ~DDRC_PERF_FREERUN_WRITE_EN;
> > +		}
> > +		writeq_relaxed(val, pmu->base +
> DDRC_PERF_CNT_FREERUN_EN);
> > +	}
> > +}
> > +
> > +static uint64_t cn10k_ddr_perf_read_counter(struct cn10k_ddr_pmu *pmu,
> > +					    int counter)
> > +{
> > +	uint64_t val;
> > +
> > +	if (counter == DDRC_PERF_READ_COUNTER_IDX)
> > +		return readq_relaxed(pmu->base +
> DDRC_PERF_CNT_VALUE_RD_OP);
> > +
> > +	if (counter == DDRC_PERF_WRITE_COUNTER_IDX)
> > +		return readq_relaxed(pmu->base +
> DDRC_PERF_CNT_VALUE_WR_OP);
> > +
> > +	val = readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE(counter));
> > +	return val;
> > +}
> > +
> > +static void cn10k_ddr_perf_event_update(struct perf_event *event) {
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	uint64_t prev_count, new_count, mask;
> > +
> > +	do {
> > +		prev_count = local64_read(&hwc->prev_count);
> > +		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
> > +	} while (local64_xchg(&hwc->prev_count, new_count) != prev_count);
> > +
> > +	mask = DDRC_PERF_CNT_MAX_VALUE;
> > +
> > +	local64_add((new_count - prev_count) & mask, &event->count); }
> > +
> > +static void cn10k_ddr_perf_event_start(struct perf_event *event, int
> > +flags) {
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	int counter = hwc->idx;
> > +
> > +	local64_set(&hwc->prev_count, 0);
> > +
> > +	cn10k_ddr_perf_counter_enable(pmu, counter, true);
> > +
> > +	hwc->state = 0;
> > +}
> > +
> > +static int cn10k_ddr_perf_event_add(struct perf_event *event, int
> > +flags) {
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	uint8_t config = event->attr.config;
> > +	uint32_t reg_offset;
> > +	uint64_t val;
> > +	int counter;
> > +
> > +	counter = cn10k_ddr_perf_alloc_counter(pmu, event);
> > +	if (counter < 0) {
> > +		dev_dbg(pmu->dev, "There are not enough counters\n");
> > +		return -EOPNOTSUPP;
> > +	}
> > +
> > +	pmu->active_events++;
> > +	hwc->idx = counter;
> > +
> > +	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
> > +		/* Generic counters, configure event id */
> > +		reg_offset = DDRC_PERF_CFG(counter);
> > +		val = ddr_perf_get_event_bitmap(config);
> > +		writeq_relaxed(val, pmu->base + reg_offset);
> > +	} else {
> > +		/* fixed event counter, clear counter value */
> > +		if (counter == DDRC_PERF_READ_COUNTER_IDX)
> > +			val = DDRC_FREERUN_READ_CNT_CLR;
> > +		else
> > +			val = DDRC_FREERUN_WRITE_CNT_CLR;
> > +
> > +		writeq_relaxed(val, pmu->base +
> DDRC_PERF_CNT_FREERUN_CTRL);
> > +	}
> > +
> > +	hwc->state |= PERF_HES_STOPPED;
> > +
> > +	if (flags & PERF_EF_START)
> > +		cn10k_ddr_perf_event_start(event, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static void cn10k_ddr_perf_event_stop(struct perf_event *event, int
> > +flags) {
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	int counter = hwc->idx;
> > +
> > +	cn10k_ddr_perf_counter_enable(pmu, counter, false);
> > +
> > +	if (flags & PERF_EF_UPDATE)
> > +		cn10k_ddr_perf_event_update(event);
> > +
> > +	hwc->state |= PERF_HES_STOPPED;
> > +}
> > +
> > +static void cn10k_ddr_perf_event_del(struct perf_event *event, int
> > +flags) {
> > +	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
> > +	struct hw_perf_event *hwc = &event->hw;
> > +	int counter = hwc->idx;
> > +
> > +	cn10k_ddr_perf_event_stop(event, PERF_EF_UPDATE);
> > +
> > +	cn10k_ddr_perf_free_counter(pmu, counter);
> > +	pmu->active_events--;
> > +	hwc->idx = -1;
> > +}
> > +
> > +static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu) {
> > +	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
> > +
> > +	writeq_relaxed(START_OP_CTRL_VAL_START, ddr_pmu->base +
> > +		       DDRC_PERF_CNT_START_OP_CTRL); }
> > +
> > +static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu) {
> > +	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
> > +
> > +	writeq_relaxed(END_OP_CTRL_VAL_END, ddr_pmu->base +
> > +		       DDRC_PERF_CNT_END_OP_CTRL);
> > +}
> > +
> > +static int cn10k_ddr_perf_probe(struct platform_device *pdev) {
> > +	struct cn10k_ddr_pmu *ddr_pmu;
> > +	struct resource *res;
> > +	void __iomem *base;
> > +	static int index;
> > +	char *name;
> > +	int ret;
> > +
> > +	ddr_pmu = devm_kzalloc(&pdev->dev, sizeof(*ddr_pmu), GFP_KERNEL);
> > +	if (!ddr_pmu)
> > +		return -ENOMEM;
> > +
> > +	ddr_pmu->dev = &pdev->dev;
> > +	platform_set_drvdata(pdev, ddr_pmu);
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	base = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(base))
> > +		return PTR_ERR(base);
> > +
> > +	ddr_pmu->base = base;
> > +
> > +	/* Setup the PMU counter to work in mannual mode */
> > +	writeq_relaxed(OP_MODE_CTRL_VAL_MANNUAL, ddr_pmu->base +
> > +		       DDRC_PERF_CNT_OP_MODE_CTRL);
> > +
> > +	ddr_pmu->pmu = (struct pmu) {
> > +		.module	      = THIS_MODULE,
> > +		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
> > +		.task_ctx_nr = perf_invalid_context,
> > +		.attr_groups = cn10k_attr_groups,
> > +		.event_init  = cn10k_ddr_perf_event_init,
> > +		.add	     = cn10k_ddr_perf_event_add,
> > +		.del	     = cn10k_ddr_perf_event_del,
> > +		.start	     = cn10k_ddr_perf_event_start,
> > +		.stop	     = cn10k_ddr_perf_event_stop,
> > +		.read	     = cn10k_ddr_perf_event_update,
> > +		.pmu_enable  = cn10k_ddr_perf_pmu_enable,
> > +		.pmu_disable = cn10k_ddr_perf_pmu_disable,
> > +	};
> > +
> > +	/* Choose this cpu to collect perf data */
> > +	ddr_pmu->cpu = raw_smp_processor_id();
> > +
> > +	name = devm_kasprintf(ddr_pmu->dev, GFP_KERNEL,
> "mrvl_ddr_pmu@%llx",
> > +			      res->start);
> > +	if (!name)
> > +		return -ENOMEM;
> > +
> > +	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
> > +	if (ret)
> > +		return ret;
> 
> Hi Bharat,
>    Do we need to free memory allocated to ddr_pmu incase perf_pmu_register
> fails? I think right now we might have memory leaks here.

As we used devm_kzalloc() for allocation, it will be freed if probe fails for any reason.

> Also you added cpu hotplug support in patch 4, but cpu variable is added in this
> patch. Will it be better to move addition of cpu part also in patch 4?

This patch set default CPU, while patch 4/4 ad support for cpu hotplug.

Thanks
-Bharat

> 
> Thanks,
> Kajol Jain
> 
> > +
> > +	ddr_pmu->id = index++;
> > +	pr_info("CN10K DDR PMU Driver for ddrc@%llx - id-%d\n",
> > +		res->start, ddr_pmu->id);
> > +	return 0;
> > +}
> > +
> > +static int cn10k_ddr_perf_remove(struct platform_device *pdev) {
> > +	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
> > +
> > +	perf_pmu_unregister(&ddr_pmu->pmu);
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
> > +	{ .compatible = "marvell,cn10k-ddr-pmu", },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
> > +
> > +static struct platform_driver cn10k_ddr_pmu_driver = {
> > +	.driver	= {
> > +		.name   = "cn10k-ddr-pmu",
> > +		.of_match_table = cn10k_ddr_pmu_of_match,
> > +		.suppress_bind_attrs = true,
> > +	},
> > +	.probe		= cn10k_ddr_perf_probe,
> > +	.remove		= cn10k_ddr_perf_remove,
> > +};
> > +
> > +static int __init cn10k_ddr_pmu_init(void) {
> > +	return platform_driver_register(&cn10k_ddr_pmu_driver);
> > +}
> > +
> > +static void __exit cn10k_ddr_pmu_exit(void) {
> > +	platform_driver_unregister(&cn10k_ddr_pmu_driver);
> > +}
> > +
> > +module_init(cn10k_ddr_pmu_init);
> > +module_exit(cn10k_ddr_pmu_exit);
> > +
> > +MODULE_AUTHOR("Bharat Bhushan <bbhushan2 at marvell.com>");
> > +MODULE_LICENSE("GPL v2");
> >

From robin.murphy at arm.com  Thu Aug 19 05:08:36 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 19 Aug 2021 13:08:36 +0100
Subject: [PATCH 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
 <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
Message-ID: <deb50900-fcfd-23d0-ab8a-0e64b2abb063@arm.com>

On 2021-08-17 11:11, Nicolas Frattaroli wrote:
> This adds the YAML bindings for the Rockchip I2S/TDM audio driver.
> 
> Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> ---
>   .../bindings/sound/rockchip,i2s-tdm.yaml      | 221 ++++++++++++++++++
>   include/dt-bindings/sound/rockchip,i2s-tdm.h  |   9 +
>   2 files changed, 230 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
>   create mode 100644 include/dt-bindings/sound/rockchip,i2s-tdm.h
> 
> diff --git a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> new file mode 100644
> index 000000000000..c3022620b47f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> @@ -0,0 +1,221 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip I2S/TDM Controller
> +
> +description:
> +  The Rockchip I2S/TDM Controller is a Time Division Multiplexed
> +  audio interface found in various Rockchip SoCs, allowing up
> +  to 8 channels of audio over a serial interface.
> +
> +maintainers:
> +  - Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - rockchip,px30-i2s-tdm
> +      - rockchip,rk1808-i2s-tdm
> +      - rockchip,rk3308-i2s-tdm
> +      - rockchip,rk3568-i2s-tdm
> +      - rockchip,rv1126-i2s-tdm
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  dmas:
> +    minItems: 1
> +    maxItems: 2
> +
> +  dma-names:
> +    oneOf:
> +      - const: rx
> +      - items:
> +          - const: tx
> +          - const: rx

It seems a bit weird for Rx DMA to be mandatory when other things imply 
that some interfaces may only be used for Tx.

> +
> +  clocks:
> +    items:
> +      - description: clock for TX
> +      - description: clock for RX
> +      - description: clock for I2S bus

Nit: "hclk" normally means the AHB clock driving the bus interface which 
connects to the rest of the SoC (and often doubling up as the core clock 
for the IP block itself) - AIUI the Tx and Rx represent the I2S bus(es).

> +
> +  clock-names:
> +    items:
> +      - const: mclk_tx
> +      - const: mclk_rx
> +      - const: hclk
> +
> +  rockchip,frame-width:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 64
> +    minimum: 32
> +    maximum: 512
> +    description:
> +      Width of a frame, usually slot width multiplied by number of slots.
> +      Must be even.
> +
> +  resets:
> +    items:
> +      - description: reset for TX
> +      - description: reset for RX
> +
> +  reset-names:
> +    items:
> +      - const: tx-m
> +      - const: rx-m
> +
> +  rockchip,cru:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the cru.
> +      Required if both playback and capture are used, i.e. if rockchip,clk-trcm
> +      is 0.
> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the GRF register.
> +
> +  rockchip,mclk-calibrate:
> +    description:
> +      Enable mclk source calibration.
> +    type: boolean
> +
> +  rockchip,trcm-sync:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Which lrck/bclk clocks each direction will sync to. You should use the
> +      constants in <dt-bindings/sound/rockchip,i2s-tdm.h>
> +    oneOf:
> +      - const: 0
> +        description:
> +          RK_TRCM_TXRX. Use both the TX and the RX clock for TX and RX.
> +      - const: 1
> +        description:
> +          RK_TRCM_TX. Use only the TX clock for TX and RX.
> +      - const: 2
> +        description:
> +          RK_TRCM_RX. Use only the RX clock for TX and RX.

I wonder if that might make sense to have boolean properties to describe 
the latter two cases (which would effectively be mutually-exclusive), 
rather than a magic number? Or possibly even just make the respective 
clocks optional, if this is something which would be done per-SoC rather 
than per-board?

> +
> +  "#sound-dai-cells":
> +    const: 0
> +
> +  rockchip,no-dmaengine:
> +    description:
> +      If present, driver will not register a pcm dmaengine, only the dai.
> +      If the dai is part of multi-dais, the property should be present.
> +    type: boolean

That sounds a lot more like a policy decision specific to the Linux 
driver implementation, than something which really belongs in DT as a 
description of the platform.

> +
> +  rockchip,playback-only:
> +    description: Specify that the controller only has playback capability.
> +    type: boolean
> +
> +  rockchip,capture-only:
> +    description: Specify that the controller only has capture capability.
> +    type: boolean

Could those be inferred from the compatible string, or are there cases 
where you have multiple instances of the IP block in different 
configurations within the same SoC? (Or if it's merely reflecting 
whether the respective interface is actually wired up externally, could 
that be inferred from the attached codec?)

Robin.

> +  rockchip,i2s-rx-route:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the mapping of I2S RX sdis to I2S data bus lines.
> +      By default, they are mapped one-to-one.
> +    items:
> +      - description: which sdi to connect to data line 0
> +      - description: which sdi to connect to data line 1
> +      - description: which sdi to connect to data line 2
> +      - description: which sdi to connect to data line 3
> +
> +  rockchip,i2s-tx-route:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the mapping of I2S TX sdos to I2S data bus lines.
> +      By default, they are mapped one-to-one.
> +    items:
> +      - description: which sdo to connect to data line 0
> +      - description: which sdo to connect to data line 1
> +      - description: which sdo to connect to data line 2
> +      - description: which sdo to connect to data line 3
> +
> +  rockchip,tdm-fsync-half-frame:
> +    description: Whether to use half frame fsync.
> +    type: boolean
> +
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - dmas
> +  - dma-names
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - rockchip,grf
> +  - "#sound-dai-cells"
> +  - rockchip,trcm-sync
> +
> +allOf:
> +  - if:
> +      properties:
> +        rockchip,clk-trcm:
> +          contains:
> +            enum: [0]
> +    then:
> +      required:
> +        - rockchip,cru
> +
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/rk3568-cru.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/pinctrl/rockchip.h>
> +    #include <dt-bindings/sound/rockchip,i2s-tdm.h>
> +
> +
> +    foo {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +        i2s at fe410000 {
> +            compatible = "rockchip,rk3568-i2s-tdm";
> +            reg = <0x0 0xfe410000 0x0 0x1000>;
> +            interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
> +            clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
> +                     <&cru HCLK_I2S1_8CH>;
> +            clock-names = "mclk_tx", "mclk_rx", "hclk";
> +            dmas = <&dmac1 2>, <&dmac1 3>;
> +            dma-names = "tx", "rx";
> +            resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
> +            reset-names = "tx-m", "rx-m";
> +            rockchip,trcm-sync = <RK_TRCM_TX>;
> +            rockchip,cru = <&cru>;
> +            rockchip,grf = <&grf>;
> +            #sound-dai-cells = <0>;
> +            pinctrl-names = "default";
> +            pinctrl-0 =
> +                <&i2s1m0_sclktx
> +                &i2s1m0_sclkrx
> +                &i2s1m0_lrcktx
> +                &i2s1m0_lrckrx
> +                &i2s1m0_sdi0
> +                &i2s1m0_sdi1
> +                &i2s1m0_sdi2
> +                &i2s1m0_sdi3
> +                &i2s1m0_sdo0
> +                &i2s1m0_sdo1
> +                &i2s1m0_sdo2
> +                &i2s1m0_sdo3>;
> +            status = "disabled";
> +        };
> +    };
> diff --git a/include/dt-bindings/sound/rockchip,i2s-tdm.h b/include/dt-bindings/sound/rockchip,i2s-tdm.h
> new file mode 100644
> index 000000000000..32494d64cf33
> --- /dev/null
> +++ b/include/dt-bindings/sound/rockchip,i2s-tdm.h
> @@ -0,0 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _DT_BINDINGS_ROCKCHIP_I2S_TDM_H
> +#define _DT_BINDINGS_ROCKCHIP_I2S_TDM_H
> +
> +#define RK_TRCM_TXRX 0
> +#define RK_TRCM_TX 1
> +#define RK_TRCM_RX 2
> +
> +#endif /* _DT_BINDINGS_ROCKCHIP_I2S_TDM_H */
> 


From zajec5 at gmail.com  Thu Aug 19 05:11:08 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 14:11:08 +0200
Subject: [PATCH] arm64: dts: broadcom: bcm4908: Fix NAND node name
Message-ID: <20210819121108.13979-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This matches nand-controller.yaml requirements.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
index a5a64d17d9ea..ae91679a78b1 100644
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
@@ -296,7 +296,7 @@ uart0: serial at 640 {
 			status = "okay";
 		};
 
-		nand at 1800 {
+		nand-controller at 1800 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
-- 
2.26.2



From haibo.chen at nxp.com  Thu Aug 19 04:52:18 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Thu, 19 Aug 2021 19:52:18 +0800
Subject: [PATCH v2] dt-bindings: mmc: fsl-imx-esdhc: change the pinctrl-names
 rule
Message-ID: <1629373938-9226-1-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Change the pinctrl-names rule to cover all cases.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml  | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
index d7c8e5880473..f04728145275 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
@@ -124,12 +124,17 @@ properties:
       - const: per
 
   pinctrl-names:
-    minItems: 1
-    items:
-      - const: default
-      - const: state_100mhz
-      - const: state_200mhz
-      - const: sleep
+    oneOf:
+      - minItems: 3
+        items:
+          - const: default
+          - const: state_100mhz
+          - const: state_200mhz
+          - const: sleep
+      - minItems: 1
+        items:
+          - const: default
+          - const: sleep
 
 required:
   - compatible
-- 
2.17.1



From boqun.feng at gmail.com  Thu Aug 19 05:19:54 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Thu, 19 Aug 2021 20:19:54 +0800
Subject: [PATCH v6 8/8] PCI: hv: Turn on the host bridge probing on ARM64
In-Reply-To: <20210809155343.GA31511@lpieralisi>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-9-boqun.feng@gmail.com>
 <20210803171451.GA15466@lpieralisi>
 <YRE9+LaAjAW3SUvc@boqun-archlinux>
 <20210809155343.GA31511@lpieralisi>
Message-ID: <YR5MaiCZrFJ71AwY@boqun-archlinux>

Hi,

On Mon, Aug 09, 2021 at 04:53:43PM +0100, Lorenzo Pieralisi wrote:
> On Mon, Aug 09, 2021 at 10:38:48PM +0800, Boqun Feng wrote:
> > On Tue, Aug 03, 2021 at 06:14:51PM +0100, Lorenzo Pieralisi wrote:
> > > On Tue, Jul 27, 2021 at 02:06:57AM +0800, Boqun Feng wrote:
> > > > Now we have everything we need, just provide a proper sysdata type for
> > > > the bus to use on ARM64 and everything else works.
> > > > 
> > > > Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
> > > > ---
> > > >  drivers/pci/controller/pci-hyperv.c | 7 +++++++
> > > >  1 file changed, 7 insertions(+)
> > > > 
> > > > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> > > > index e6276aaa4659..62dbe98d1fe1 100644
> > > > --- a/drivers/pci/controller/pci-hyperv.c
> > > > +++ b/drivers/pci/controller/pci-hyperv.c
> > > > @@ -40,6 +40,7 @@
> > > >  #include <linux/kernel.h>
> > > >  #include <linux/module.h>
> > > >  #include <linux/pci.h>
> > > > +#include <linux/pci-ecam.h>
> > > >  #include <linux/delay.h>
> > > >  #include <linux/semaphore.h>
> > > >  #include <linux/irqdomain.h>
> > > > @@ -448,7 +449,11 @@ enum hv_pcibus_state {
> > > >  };
> > > >  
> > > >  struct hv_pcibus_device {
> > > > +#ifdef CONFIG_X86
> > > >  	struct pci_sysdata sysdata;
> > > > +#elif defined(CONFIG_ARM64)
> > > > +	struct pci_config_window sysdata;
> > > 
> > > This is ugly. HV does not need pci_config_window at all right
> > > (other than arm64 pcibios_root_bridge_prepare()) ?
> > > 
> > 
> > Right.
> > 
> > > The issue is that in HV you have to have *some* sysdata != NULL, it is
> > > just some data to retrieve the hv_pcibus_device.
> > > 
> > > Mmaybe we can rework ARM64 ACPI code to store the acpi_device in struct
> > > pci_host_bridge->private instead of retrieving it from pci_config_window
> > > so that we decouple HV from the ARM64 back-end.
> > > 
> > > HV would just set struct pci_host_bridge->private == NULL.
> > > 
> > 
> > Works for me, but please note that pci_sysdata is an x86-specific
> > structure, so we still need to define a fake pci_sysdata inside
> > pci-hyperv.c, like:
> > 
> > 	#ifndef CONFIG_X86
> > 	struct pci_sysdata { };
> > 	#end
> > 
> > > I need to think about this a bit, I don't think it should block
> > > this series though but it would be nicer.
> > 
> > After a quick look into the code, seems that what we need to do is to
> > add an additional parameter for acpi_pci_root_create() and introduce a
> > slightly different version of pci_create_root_bus(). A question is:
> > should we only do this for ARM64, or should we also do this for
> > other acpi_pci_root_create() users (x86 and ia64)? Another question
> > comes to my mind is, while we are at it, is there anything else that we
> > want to move from sysdata to ->private? These questions are out of scope
> > of this patchset, I think. Maybe it's better that we address them in the
> > future, and I can send out separate RFC patches to start the discussion.
> > Does that sound like a plan to you?
> 
> Yes it does and we can start from ARM64 - what I really don't like
> is the arch/arm64 dependency with the HV controller driver as I
> described, being forced to have a struct pci_config_window in the
> driver is not really nice or clean IMO.
> 
> Not that I expect any other PCI host bridge driver with ACPI coming
> anytime soon but even if it is not within set (that we can merge) I'd
> like to see the decoupling rework done asap, let me put it this way.
> 

Just want to check whether the following is a good starter for the
decoupling rework?

	https://lore.kernel.org/lkml/20210811153619.88922-1-boqun.feng at gmail.com/

If so, is there any other concern about taking this patchset? ;-)

Regards,
Boqun

> Thanks,
> Lorenzo
> 
> > Regards,
> > Boqun
> > 
> > > 
> > > Lorenzo
> > > 
> > > > +#endif
> > > >  	struct pci_host_bridge *bridge;
> > > >  	struct fwnode_handle *fwnode;
> > > >  	/* Protocol version negotiated with the host */
> > > > @@ -3075,7 +3080,9 @@ static int hv_pci_probe(struct hv_device *hdev,
> > > >  			 dom_req, dom);
> > > >  
> > > >  	hbus->bridge->domain_nr = dom;
> > > > +#ifdef CONFIG_X86
> > > >  	hbus->sysdata.domain = dom;
> > > > +#endif
> > > >  
> > > >  	hbus->hdev = hdev;
> > > >  	INIT_LIST_HEAD(&hbus->children);
> > > > -- 
> > > > 2.32.0
> > > > 


From zajec5 at gmail.com  Thu Aug 19 05:26:06 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 14:26:06 +0200
Subject: [PATCH] arm64: dts: broadcom: bcm4908: Move reboot syscon out of bus
Message-ID: <20210819122606.15682-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This fixes following error for every bcm4908 DTS file:
bus at ff800000: reboot: {'type': 'object'} is not allowed for {'compatible': ['syscon-reboot'], 'regmap': [[15]], 'offset': [[52]], 'mask': [[1]]}

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
index ae91679a78b1..87076770f4bc 100644
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
@@ -326,12 +326,12 @@ reset-controller at 2644 {
 				#reset-cells = <1>;
 			};
 		};
+	};
 
-		reboot {
-			compatible = "syscon-reboot";
-			regmap = <&timer>;
-			offset = <0x34>;
-			mask = <1>;
-		};
+	reboot {
+		compatible = "syscon-reboot";
+		regmap = <&timer>;
+		offset = <0x34>;
+		mask = <1>;
 	};
 };
-- 
2.26.2



From kishon at ti.com  Thu Aug 19 05:33:35 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:35 +0530
Subject: [PATCH v9 0/8] Add SR-IOV support in PCIe Endpoint Core
Message-ID: <20210819123343.1951-1-kishon@ti.com>

Patch series
*) Adds support to add virtual functions to enable endpoint controller
   which supports SR-IOV capability
*) Add support in Cadence endpoint driver to configure virtual functions
*) Enable pci_endpoint_test driver to create pci_device for virtual
   functions

v1 of the patch series can be found at [1]
v2 of the patch series can be found at [2]
v3 of the patch series can be found at [3]
v4 of the patch series can be found at [4]
v5 of the patch series can be found at [5]
v6 of the patch series can be found at [6]
v7 of the patch series can be found at [7]
v8 of the patch series can be found at [8]

Here both physical functions and virtual functions use the same
pci_endpoint_test driver and existing pcitest utility can be used
to test virtual functions as well.

Changes from v8:
1) Include pci-epf.h in pcie-cadence.h and use BAR_4 instead of 4
2) Get reg for configuring BAR using if..else.. for physical function
and virtual function instead of over-writing reg for virtual function.

Changes from v7:
1) Added conditional operator to consicely write code to configure BAR
   (Added a new patch to first simplify configuring BAR for physical
    function)
2) Return error if virtual function number is > 1 for configuring config
   space header

Changes from v6:
*) Rebased to 5.14-rc4

Changes from v5:
*) Rebased to 5.13-rc1

Changes from v4:
*) Added a fix in Cadence driver which was overwriting BAR configuration
   of physical function.
*) Didn't include Tom's Acked-by since Cadence driver is modified in
   this revision.

Changes from v3:
*) Fixed Rob's comment and added his Reviewed-by as suggested by him.

Changes from v2:
*) Fixed DT binding documentation comment by Rob
*) Fixed the error check in pci-epc-core.c

Changes from v1:
*) Re-based and Re-worked to latest kernel 5.10.0-rc2+ (now has generic
   binding for EP)

[1] -> http://lore.kernel.org/r/20191231113534.30405-1-kishon at ti.com
[2] -> http://lore.kernel.org/r/20201112175358.2653-1-kishon at ti.com
[3] -> https://lore.kernel.org/r/20210305050410.9201-1-kishon at ti.com
[4] -> http://lore.kernel.org/r/20210310160943.7606-1-kishon at ti.com
[5] -> https://lore.kernel.org/r/20210419083401.31628-1-kishon at ti.com
[6] -> http://lore.kernel.org/r/20210517074723.10212-1-kishon at ti.com
[7] -> https://lore.kernel.org/r/20210803050310.27122-1-kishon at ti.com
[8] -> https://lore.kernel.org/r/20210811064656.15399-1-kishon at ti.com

Kishon Vijay Abraham I (8):
  dt-bindings: PCI: pci-ep: Add binding to specify virtual function
  PCI: endpoint: Add support to add virtual function in endpoint core
  PCI: endpoint: Add support to link a physical function to a virtual
    function
  PCI: endpoint: Add virtual function number in pci_epc ops
  PCI: cadence: Simplify code to get register base address for
    configuring BAR
  PCI: cadence: Add support to configure virtual functions
  misc: pci_endpoint_test: Populate sriov_configure ops to configure
    SR-IOV device
  Documentation: PCI: endpoint/pci-endpoint-cfs: Guide to use SR-IOV

 .../PCI/endpoint/pci-endpoint-cfs.rst         |  12 +-
 .../devicetree/bindings/pci/pci-ep.yaml       |   7 +
 drivers/misc/pci_endpoint_test.c              |   1 +
 .../pci/controller/cadence/pcie-cadence-ep.c  | 196 +++++++++++++-----
 drivers/pci/controller/cadence/pcie-cadence.h |  12 ++
 .../pci/controller/dwc/pcie-designware-ep.c   |  36 ++--
 drivers/pci/controller/pcie-rcar-ep.c         |  19 +-
 drivers/pci/controller/pcie-rockchip-ep.c     |  18 +-
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  89 ++++----
 drivers/pci/endpoint/functions/pci-epf-test.c |  74 ++++---
 drivers/pci/endpoint/pci-ep-cfs.c             |  24 +++
 drivers/pci/endpoint/pci-epc-core.c           | 134 ++++++++----
 drivers/pci/endpoint/pci-epf-core.c           | 146 ++++++++++++-
 include/linux/pci-epc.h                       |  57 ++---
 include/linux/pci-epf.h                       |  16 +-
 15 files changed, 616 insertions(+), 225 deletions(-)

-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:33:36 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:36 +0530
Subject: [PATCH v9 1/8] dt-bindings: PCI: pci-ep: Add binding to specify
 virtual function
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <20210819123343.1951-2-kishon@ti.com>

Add binding to specify virtual function (associated with each physical
function) in endpoint mode.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/pci/pci-ep.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/pci-ep.yaml b/Documentation/devicetree/bindings/pci/pci-ep.yaml
index 7847bbcd4a03..ccec51ab5247 100644
--- a/Documentation/devicetree/bindings/pci/pci-ep.yaml
+++ b/Documentation/devicetree/bindings/pci/pci-ep.yaml
@@ -23,6 +23,13 @@ properties:
     default: 1
     maximum: 255
 
+  max-virtual-functions:
+    description: Array representing the number of virtual functions corresponding to each physical
+      function
+    $ref: /schemas/types.yaml#/definitions/uint8-array
+    minItems: 1
+    maxItems: 255
+
   max-link-speed:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [ 1, 2, 3, 4 ]
-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:33:37 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:37 +0530
Subject: [PATCH v9 2/8] PCI: endpoint: Add support to add virtual function in
 endpoint core
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <20210819123343.1951-3-kishon@ti.com>

Add support to add virtual function in endpoint core. The virtual
function can only be associated with a physical function instead of a
endpoint controller. Provide APIs to associate a virtual function with
a physical function here.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
[weiyongjun1 at huawei.com: PCI: endpoint: Fix missing unlock on error in
 pci_epf_add_vepf() - Reported-by: Hulk Robot <hulkci at huawei.com>]
Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>
---
 drivers/pci/endpoint/pci-epc-core.c |  2 +-
 drivers/pci/endpoint/pci-epf-core.c | 98 ++++++++++++++++++++++++++++-
 include/linux/pci-epf.h             | 16 ++++-
 3 files changed, 113 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index adec9bee72cf..01c58ca84dcc 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -548,7 +548,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf,
 	u32 func_no;
 	int ret = 0;
 
-	if (IS_ERR_OR_NULL(epc))
+	if (IS_ERR_OR_NULL(epc) || epf->is_vf)
 		return -EINVAL;
 
 	if (type == PRIMARY_INTERFACE && epf->epc)
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index e9289d10f822..296479659aa2 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -62,13 +62,20 @@ EXPORT_SYMBOL_GPL(pci_epf_type_add_cfs);
  */
 void pci_epf_unbind(struct pci_epf *epf)
 {
+	struct pci_epf *epf_vf;
+
 	if (!epf->driver) {
 		dev_WARN(&epf->dev, "epf device not bound to driver\n");
 		return;
 	}
 
 	mutex_lock(&epf->lock);
-	epf->driver->ops->unbind(epf);
+	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		if (epf_vf->is_bound)
+			epf_vf->driver->ops->unbind(epf_vf);
+	}
+	if (epf->is_bound)
+		epf->driver->ops->unbind(epf);
 	mutex_unlock(&epf->lock);
 	module_put(epf->driver->owner);
 }
@@ -83,6 +90,7 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind);
  */
 int pci_epf_bind(struct pci_epf *epf)
 {
+	struct pci_epf *epf_vf;
 	int ret;
 
 	if (!epf->driver) {
@@ -94,13 +102,97 @@ int pci_epf_bind(struct pci_epf *epf)
 		return -EAGAIN;
 
 	mutex_lock(&epf->lock);
+	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		epf_vf->func_no = epf->func_no;
+		epf_vf->epc = epf->epc;
+		epf_vf->sec_epc = epf->sec_epc;
+		ret = epf_vf->driver->ops->bind(epf_vf);
+		if (ret)
+			goto ret;
+		epf_vf->is_bound = true;
+	}
+
 	ret = epf->driver->ops->bind(epf);
+	if (ret)
+		goto ret;
+	epf->is_bound = true;
+
+	mutex_unlock(&epf->lock);
+	return 0;
+
+ret:
 	mutex_unlock(&epf->lock);
+	pci_epf_unbind(epf);
 
 	return ret;
 }
 EXPORT_SYMBOL_GPL(pci_epf_bind);
 
+/**
+ * pci_epf_add_vepf() - associate virtual EP function to physical EP function
+ * @epf_pf: the physical EP function to which the virtual EP function should be
+ *   associated
+ * @epf_vf: the virtual EP function to be added
+ *
+ * A physical endpoint function can be associated with multiple virtual
+ * endpoint functions. Invoke pci_epf_add_epf() to add a virtual PCI endpoint
+ * function to a physical PCI endpoint function.
+ */
+int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf)
+{
+	u32 vfunc_no;
+
+	if (IS_ERR_OR_NULL(epf_pf) || IS_ERR_OR_NULL(epf_vf))
+		return -EINVAL;
+
+	if (epf_pf->epc || epf_vf->epc || epf_vf->epf_pf)
+		return -EBUSY;
+
+	if (epf_pf->sec_epc || epf_vf->sec_epc)
+		return -EBUSY;
+
+	mutex_lock(&epf_pf->lock);
+	vfunc_no = find_first_zero_bit(&epf_pf->vfunction_num_map,
+				       BITS_PER_LONG);
+	if (vfunc_no >= BITS_PER_LONG) {
+		mutex_unlock(&epf_pf->lock);
+		return -EINVAL;
+	}
+
+	set_bit(vfunc_no, &epf_pf->vfunction_num_map);
+	epf_vf->vfunc_no = vfunc_no;
+
+	epf_vf->epf_pf = epf_pf;
+	epf_vf->is_vf = true;
+
+	list_add_tail(&epf_vf->list, &epf_pf->pci_vepf);
+	mutex_unlock(&epf_pf->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_epf_add_vepf);
+
+/**
+ * pci_epf_remove_vepf() - remove virtual EP function from physical EP function
+ * @epf_pf: the physical EP function from which the virtual EP function should
+ *   be removed
+ * @epf_vf: the virtual EP function to be removed
+ *
+ * Invoke to remove a virtual endpoint function from the physcial endpoint
+ * function.
+ */
+void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf)
+{
+	if (IS_ERR_OR_NULL(epf_pf) || IS_ERR_OR_NULL(epf_vf))
+		return;
+
+	mutex_lock(&epf_pf->lock);
+	clear_bit(epf_vf->vfunc_no, &epf_pf->vfunction_num_map);
+	list_del(&epf_vf->list);
+	mutex_unlock(&epf_pf->lock);
+}
+EXPORT_SYMBOL_GPL(pci_epf_remove_vepf);
+
 /**
  * pci_epf_free_space() - free the allocated PCI EPF register space
  * @epf: the EPF device from whom to free the memory
@@ -317,6 +409,10 @@ struct pci_epf *pci_epf_create(const char *name)
 		return ERR_PTR(-ENOMEM);
 	}
 
+	/* VFs are numbered starting with 1. So set BIT(0) by default */
+	epf->vfunction_num_map = 1;
+	INIT_LIST_HEAD(&epf->pci_vepf);
+
 	dev = &epf->dev;
 	device_initialize(dev);
 	dev->bus = &pci_epf_bus_type;
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 2debc27ba95e..043b4c9c7188 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -121,8 +121,10 @@ struct pci_epf_bar {
  * @bar: represents the BAR of EPF device
  * @msi_interrupts: number of MSI interrupts required by this function
  * @msix_interrupts: number of MSI-X interrupts required by this function
- * @func_no: unique function number within this endpoint device
+ * @func_no: unique (physical) function number within this endpoint device
+ * @vfunc_no: unique virtual function number within a physical function
  * @epc: the EPC device to which this EPF device is bound
+ * @epf_pf: the physical EPF device to which this virtual EPF device is bound
  * @driver: the EPF driver to which this EPF device is bound
  * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc
  * @nb: notifier block to notify EPF of any EPC events (like linkup)
@@ -133,6 +135,10 @@ struct pci_epf_bar {
  * @sec_epc_bar: represents the BAR of EPF device associated with secondary EPC
  * @sec_epc_func_no: unique (physical) function number within the secondary EPC
  * @group: configfs group associated with the EPF device
+ * @is_bound: indicates if bind notification to function driver has been invoked
+ * @is_vf: true - virtual function, false - physical function
+ * @vfunction_num_map: bitmap to manage virtual function number
+ * @pci_vepf: list of virtual endpoint functions associated with this function
  */
 struct pci_epf {
 	struct device		dev;
@@ -142,8 +148,10 @@ struct pci_epf {
 	u8			msi_interrupts;
 	u16			msix_interrupts;
 	u8			func_no;
+	u8			vfunc_no;
 
 	struct pci_epc		*epc;
+	struct pci_epf		*epf_pf;
 	struct pci_epf_driver	*driver;
 	struct list_head	list;
 	struct notifier_block   nb;
@@ -156,6 +164,10 @@ struct pci_epf {
 	struct pci_epf_bar	sec_epc_bar[6];
 	u8			sec_epc_func_no;
 	struct config_group	*group;
+	unsigned int		is_bound;
+	unsigned int		is_vf;
+	unsigned long		vfunction_num_map;
+	struct list_head	pci_vepf;
 };
 
 /**
@@ -199,4 +211,6 @@ int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
 struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf,
 					  struct config_group *group);
+int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);
+void pci_epf_remove_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);
 #endif /* __LINUX_PCI_EPF_H */
-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:33:38 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:38 +0530
Subject: [PATCH v9 3/8] PCI: endpoint: Add support to link a physical function
 to a virtual function
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <20210819123343.1951-4-kishon@ti.com>

While the physical function has to be linked to endpoint controller, the
virtual function has to be linked to a physical function. Add support to
link a physical function to a virtual function in pci-ep-cfs.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/pci/endpoint/pci-ep-cfs.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
index f3a8b833b479..999911801877 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -475,6 +475,28 @@ static struct configfs_attribute *pci_epf_attrs[] = {
 	NULL,
 };
 
+static int pci_epf_vepf_link(struct config_item *epf_pf_item,
+			     struct config_item *epf_vf_item)
+{
+	struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
+	struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
+	struct pci_epf *epf_pf = epf_pf_group->epf;
+	struct pci_epf *epf_vf = epf_vf_group->epf;
+
+	return pci_epf_add_vepf(epf_pf, epf_vf);
+}
+
+static void pci_epf_vepf_unlink(struct config_item *epf_pf_item,
+				struct config_item *epf_vf_item)
+{
+	struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
+	struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
+	struct pci_epf *epf_pf = epf_pf_group->epf;
+	struct pci_epf *epf_vf = epf_vf_group->epf;
+
+	pci_epf_remove_vepf(epf_pf, epf_vf);
+}
+
 static void pci_epf_release(struct config_item *item)
 {
 	struct pci_epf_group *epf_group = to_pci_epf_group(item);
@@ -487,6 +509,8 @@ static void pci_epf_release(struct config_item *item)
 }
 
 static struct configfs_item_operations pci_epf_ops = {
+	.allow_link		= pci_epf_vepf_link,
+	.drop_link		= pci_epf_vepf_unlink,
 	.release		= pci_epf_release,
 };
 
-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:33:39 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:39 +0530
Subject: [PATCH v9 4/8] PCI: endpoint: Add virtual function number in pci_epc
 ops
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <20210819123343.1951-5-kishon@ti.com>

Add virtual function number in pci_epc ops. EPC controller driver
can perform virtual function specific initialization based on the
virtual function number.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c  |  44 +++---
 .../pci/controller/dwc/pcie-designware-ep.c   |  36 ++---
 drivers/pci/controller/pcie-rcar-ep.c         |  19 +--
 drivers/pci/controller/pcie-rockchip-ep.c     |  18 +--
 drivers/pci/endpoint/functions/pci-epf-ntb.c  |  89 +++++++-----
 drivers/pci/endpoint/functions/pci-epf-test.c |  74 +++++-----
 drivers/pci/endpoint/pci-epc-core.c           | 132 +++++++++++++-----
 drivers/pci/endpoint/pci-epf-core.c           |  48 ++++++-
 include/linux/pci-epc.h                       |  57 ++++----
 9 files changed, 328 insertions(+), 189 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 897cdde02bd8..912a15be8bfd 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -16,7 +16,7 @@
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE		0x1
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY	0x3
 
-static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -47,7 +47,7 @@ static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				struct pci_epf_bar *epf_bar)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -117,7 +117,7 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				   struct pci_epf_bar *epf_bar)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -147,8 +147,8 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 	epf->epf_bar[bar] = NULL;
 }
 
-static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
-				 u64 pci_addr, size_t size)
+static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
+				 phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -169,7 +169,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
 	return 0;
 }
 
-static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
@@ -189,7 +189,7 @@ static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
 	clear_bit(r, &ep->ob_region_map);
 }
 
-static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 mmc)
+static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -209,7 +209,7 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 mmc)
 	return 0;
 }
 
-static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -230,7 +230,7 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
 	return mme;
 }
 
-static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -247,8 +247,9 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u16 interrupts,
-				 enum pci_barno bir, u32 offset)
+static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
+				 u16 interrupts, enum pci_barno bir,
+				 u32 offset)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -317,7 +318,8 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
 	writel(0, ep->irq_cpu_addr + offset);
 }
 
-static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 intx)
+static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
+					u8 intx)
 {
 	u16 cmd;
 
@@ -334,7 +336,7 @@ static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 intx)
 	return 0;
 }
 
-static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
+static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				     u8 interrupt_num)
 {
 	struct cdns_pcie *pcie = &ep->pcie;
@@ -382,7 +384,7 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr, u8 interrupt_num,
 				    u32 entry_size, u32 *msi_data,
 				    u32 *msi_addr_offset)
@@ -419,7 +421,7 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
 	pci_addr &= GENMASK_ULL(63, 2);
 
 	for (i = 0; i < interrupt_num; i++) {
-		ret = cdns_pcie_ep_map_addr(epc, fn, addr,
+		ret = cdns_pcie_ep_map_addr(epc, fn, vfn, addr,
 					    pci_addr & ~pci_addr_mask,
 					    entry_size);
 		if (ret)
@@ -433,7 +435,7 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
+static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 				      u16 interrupt_num)
 {
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
@@ -478,7 +480,7 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  enum pci_epc_irq_type type,
 				  u16 interrupt_num)
 {
@@ -486,13 +488,13 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
 
 	switch (type) {
 	case PCI_EPC_IRQ_LEGACY:
-		return cdns_pcie_ep_send_legacy_irq(ep, fn, 0);
+		return cdns_pcie_ep_send_legacy_irq(ep, fn, vfn, 0);
 
 	case PCI_EPC_IRQ_MSI:
-		return cdns_pcie_ep_send_msi_irq(ep, fn, interrupt_num);
+		return cdns_pcie_ep_send_msi_irq(ep, fn, vfn, interrupt_num);
 
 	case PCI_EPC_IRQ_MSIX:
-		return cdns_pcie_ep_send_msix_irq(ep, fn, interrupt_num);
+		return cdns_pcie_ep_send_msix_irq(ep, fn, vfn, interrupt_num);
 
 	default:
 		break;
@@ -531,7 +533,7 @@ static const struct pci_epc_features cdns_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &cdns_pcie_epc_features;
 }
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 8d028a88b375..998b698f4085 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -125,7 +125,7 @@ static u8 dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, u8 func_no, u8 cap)
 	return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap);
 }
 
-static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				   struct pci_epf_header *hdr)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -202,7 +202,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
 	return 0;
 }
 
-static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
+static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				 struct pci_epf_bar *epf_bar)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -217,7 +217,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
 	ep->epf_bar[bar] = NULL;
 }
 
-static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			      struct pci_epf_bar *epf_bar)
 {
 	int ret;
@@ -276,7 +276,7 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
 	return -EINVAL;
 }
 
-static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
+static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				  phys_addr_t addr)
 {
 	int ret;
@@ -292,9 +292,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
 	clear_bit(atu_index, ep->ob_window_map);
 }
 
-static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
-			       phys_addr_t addr,
-			       u64 pci_addr, size_t size)
+static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			       phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	int ret;
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -309,7 +308,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
 	return 0;
 }
 
-static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
+static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -333,7 +332,8 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
+static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			      u8 interrupts)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -358,7 +358,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 	return 0;
 }
 
-static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -382,8 +382,8 @@ static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
 	return val;
 }
 
-static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-			       enum pci_barno bir, u32 offset)
+static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			       u16 interrupts, enum pci_barno bir, u32 offset)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -418,7 +418,7 @@ static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
 	return 0;
 }
 
-static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
+static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				enum pci_epc_irq_type type, u16 interrupt_num)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -450,7 +450,7 @@ static int dw_pcie_ep_start(struct pci_epc *epc)
 }
 
 static const struct pci_epc_features*
-dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 
@@ -525,14 +525,14 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
 	aligned_offset = msg_addr_lower & (epc->mem->window.page_size - 1);
 	msg_addr = ((u64)msg_addr_upper) << 32 |
 			(msg_addr_lower & ~aligned_offset);
-	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
+	ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
 				  epc->mem->window.page_size);
 	if (ret)
 		return ret;
 
 	writel(msg_data | (interrupt_num - 1), ep->msi_mem + aligned_offset);
 
-	dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
+	dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
 
 	return 0;
 }
@@ -593,14 +593,14 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
 	}
 
 	aligned_offset = msg_addr & (epc->mem->window.page_size - 1);
-	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys,  msg_addr,
+	ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
 				  epc->mem->window.page_size);
 	if (ret)
 		return ret;
 
 	writel(msg_data, ep->msi_mem + aligned_offset);
 
-	dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
+	dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys);
 
 	return 0;
 }
diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c
index b4a288e24aaf..6cee4e09acca 100644
--- a/drivers/pci/controller/pcie-rcar-ep.c
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -159,7 +159,7 @@ static int rcar_pcie_ep_get_pdata(struct rcar_pcie_endpoint *ep,
 	return 0;
 }
 
-static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -195,7 +195,7 @@ static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				struct pci_epf_bar *epf_bar)
 {
 	int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT;
@@ -246,7 +246,7 @@ static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
 	return 0;
 }
 
-static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				   struct pci_epf_bar *epf_bar)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -259,7 +259,8 @@ static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 	clear_bit(atu_index + 1, ep->ib_window_map);
 }
 
-static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
+static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
+				u8 interrupts)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
 	struct rcar_pcie *pcie = &ep->pcie;
@@ -272,7 +273,7 @@ static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
 	return 0;
 }
 
-static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
 	struct rcar_pcie *pcie = &ep->pcie;
@@ -285,7 +286,7 @@ static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
 	return ((flags & MSICAP0_MMESE_MASK) >> MSICAP0_MMESE_OFFSET);
 }
 
-static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				 phys_addr_t addr, u64 pci_addr, size_t size)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -322,7 +323,7 @@ static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rcar_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void rcar_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				    phys_addr_t addr)
 {
 	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
@@ -403,7 +404,7 @@ static int rcar_pcie_ep_assert_msi(struct rcar_pcie *pcie,
 	return 0;
 }
 
-static int rcar_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int rcar_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  enum pci_epc_irq_type type,
 				  u16 interrupt_num)
 {
@@ -451,7 +452,7 @@ static const struct pci_epc_features rcar_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-rcar_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+rcar_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &rcar_pcie_epc_features;
 }
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c
index 7631dc3961c1..5fb9ce6e536e 100644
--- a/drivers/pci/controller/pcie-rockchip-ep.c
+++ b/drivers/pci/controller/pcie-rockchip-ep.c
@@ -122,7 +122,7 @@ static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn,
 			    ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(r));
 }
 
-static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 					 struct pci_epf_header *hdr)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -159,7 +159,7 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				    struct pci_epf_bar *epf_bar)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -227,7 +227,7 @@ static int rockchip_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 				       struct pci_epf_bar *epf_bar)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -256,7 +256,7 @@ static void rockchip_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
 			    ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar));
 }
 
-static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 				     phys_addr_t addr, u64 pci_addr,
 				     size_t size)
 {
@@ -284,7 +284,7 @@ static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 					phys_addr_t addr)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -308,7 +308,7 @@ static void rockchip_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
 	clear_bit(r, &ep->ob_region_map);
 }
 
-static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn,
 				    u8 multi_msg_cap)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
@@ -329,7 +329,7 @@ static int rockchip_pcie_ep_set_msi(struct pci_epc *epc, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+static int rockchip_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 {
 	struct rockchip_pcie_ep *ep = epc_get_drvdata(epc);
 	struct rockchip_pcie *rockchip = &ep->rockchip;
@@ -471,7 +471,7 @@ static int rockchip_pcie_ep_send_msi_irq(struct rockchip_pcie_ep *ep, u8 fn,
 	return 0;
 }
 
-static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+static int rockchip_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				      enum pci_epc_irq_type type,
 				      u16 interrupt_num)
 {
@@ -510,7 +510,7 @@ static const struct pci_epc_features rockchip_pcie_epc_features = {
 };
 
 static const struct pci_epc_features*
-rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
+rockchip_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	return &rockchip_pcie_epc_features;
 }
diff --git a/drivers/pci/endpoint/functions/pci-epf-ntb.c b/drivers/pci/endpoint/functions/pci-epf-ntb.c
index bce274d02dcf..8b4756159f15 100644
--- a/drivers/pci/endpoint/functions/pci-epf-ntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-ntb.c
@@ -87,6 +87,7 @@ struct epf_ntb {
 
 struct epf_ntb_epc {
 	u8 func_no;
+	u8 vfunc_no;
 	bool linkup;
 	bool is_msix;
 	int msix_bar;
@@ -143,14 +144,15 @@ static int epf_ntb_link_up(struct epf_ntb *ntb, bool link_up)
 	struct epf_ntb_epc *ntb_epc;
 	struct epf_ntb_ctrl *ctrl;
 	struct pci_epc *epc;
+	u8 func_no, vfunc_no;
 	bool is_msix;
-	u8 func_no;
 	int ret;
 
 	for (type = PRIMARY_INTERFACE; type <= SECONDARY_INTERFACE; type++) {
 		ntb_epc = ntb->epc[type];
 		epc = ntb_epc->epc;
 		func_no = ntb_epc->func_no;
+		vfunc_no = ntb_epc->vfunc_no;
 		is_msix = ntb_epc->is_msix;
 		ctrl = ntb_epc->reg;
 		if (link_up)
@@ -158,7 +160,7 @@ static int epf_ntb_link_up(struct epf_ntb *ntb, bool link_up)
 		else
 			ctrl->link_status &= ~LINK_STATUS_UP;
 		irq_type = is_msix ? PCI_EPC_IRQ_MSIX : PCI_EPC_IRQ_MSI;
-		ret = pci_epc_raise_irq(epc, func_no, irq_type, 1);
+		ret = pci_epc_raise_irq(epc, func_no, vfunc_no, irq_type, 1);
 		if (ret) {
 			dev_err(&epc->dev,
 				"%s intf: Failed to raise Link Up IRQ\n",
@@ -238,10 +240,10 @@ static int epf_ntb_configure_mw(struct epf_ntb *ntb,
 	enum pci_barno peer_barno;
 	struct epf_ntb_ctrl *ctrl;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	u64 addr, size;
 	int ret = 0;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -267,8 +269,9 @@ static int epf_ntb_configure_mw(struct epf_ntb *ntb,
 	}
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	ret = pci_epc_map_addr(epc, func_no, phys_addr, addr, size);
+	ret = pci_epc_map_addr(epc, func_no, vfunc_no, phys_addr, addr, size);
 	if (ret)
 		dev_err(&epc->dev,
 			"%s intf: Failed to map memory window %d address\n",
@@ -296,8 +299,8 @@ static void epf_ntb_teardown_mw(struct epf_ntb *ntb,
 	enum pci_barno peer_barno;
 	struct epf_ntb_ctrl *ctrl;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -311,8 +314,9 @@ static void epf_ntb_teardown_mw(struct epf_ntb *ntb,
 	if (mw + NTB_MW_OFFSET == BAR_DB_MW1)
 		phys_addr += ctrl->mw1_offset;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	pci_epc_unmap_addr(epc, func_no, phys_addr);
+	pci_epc_unmap_addr(epc, func_no, vfunc_no, phys_addr);
 }
 
 /**
@@ -385,8 +389,8 @@ static int epf_ntb_configure_msi(struct epf_ntb *ntb,
 	struct epf_ntb_ctrl *peer_ctrl;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 	int ret, i;
 
 	ntb_epc = ntb->epc[type];
@@ -400,8 +404,9 @@ static int epf_ntb_configure_msi(struct epf_ntb *ntb,
 
 	phys_addr = peer_epf_bar->phys_addr;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	ret = pci_epc_map_msi_irq(epc, func_no, phys_addr, db_count,
+	ret = pci_epc_map_msi_irq(epc, func_no, vfunc_no, phys_addr, db_count,
 				  db_entry_size, &db_data, &db_offset);
 	if (ret) {
 		dev_err(&epc->dev, "%s intf: Failed to map MSI IRQ\n",
@@ -491,10 +496,10 @@ static int epf_ntb_configure_msix(struct epf_ntb *ntb,
 	u32 db_entry_size, msg_data;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	size_t align;
 	u64 msg_addr;
-	u8 func_no;
 	int ret, i;
 
 	ntb_epc = ntb->epc[type];
@@ -512,12 +517,13 @@ static int epf_ntb_configure_msix(struct epf_ntb *ntb,
 	align = epc_features->align;
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	db_entry_size = peer_ctrl->db_entry_size;
 
 	for (i = 0; i < db_count; i++) {
 		msg_addr = ALIGN_DOWN(msix_tbl[i].msg_addr, align);
 		msg_data = msix_tbl[i].msg_data;
-		ret = pci_epc_map_addr(epc, func_no, phys_addr, msg_addr,
+		ret = pci_epc_map_addr(epc, func_no, vfunc_no, phys_addr, msg_addr,
 				       db_entry_size);
 		if (ret) {
 			dev_err(&epc->dev,
@@ -586,8 +592,8 @@ epf_ntb_teardown_db(struct epf_ntb *ntb, enum pci_epc_interface_type type)
 	struct pci_epf_bar *peer_epf_bar;
 	enum pci_barno peer_barno;
 	phys_addr_t phys_addr;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	ntb_epc = ntb->epc[type];
 	epc = ntb_epc->epc;
@@ -597,8 +603,9 @@ epf_ntb_teardown_db(struct epf_ntb *ntb, enum pci_epc_interface_type type)
 	peer_epf_bar = &peer_ntb_epc->epf_bar[peer_barno];
 	phys_addr = peer_epf_bar->phys_addr;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
-	pci_epc_unmap_addr(epc, func_no, phys_addr);
+	pci_epc_unmap_addr(epc, func_no, vfunc_no, phys_addr);
 }
 
 /**
@@ -728,14 +735,15 @@ static void epf_ntb_peer_spad_bar_clear(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
 	epf_bar = &ntb_epc->epf_bar[barno];
-	pci_epc_clear_bar(epc, func_no, epf_bar);
+	pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 }
 
 /**
@@ -775,9 +783,9 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	struct pci_epf_bar *peer_epf_bar, *epf_bar;
 	enum pci_barno peer_barno, barno;
 	u32 peer_spad_offset;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	dev = &ntb->epf->dev;
@@ -790,6 +798,7 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	barno = ntb_epc->epf_ntb_bar[BAR_PEER_SPAD];
 	epf_bar = &ntb_epc->epf_bar[barno];
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	epc = ntb_epc->epc;
 
 	peer_spad_offset = peer_ntb_epc->reg->spad_offset;
@@ -798,7 +807,7 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 	epf_bar->barno = barno;
 	epf_bar->flags = PCI_BASE_ADDRESS_MEM_TYPE_32;
 
-	ret = pci_epc_set_bar(epc, func_no, epf_bar);
+	ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 	if (ret) {
 		dev_err(dev, "%s intf: peer SPAD BAR set failed\n",
 			pci_epc_interface_string(type));
@@ -842,14 +851,15 @@ static void epf_ntb_config_sspad_bar_clear(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
 	epf_bar = &ntb_epc->epf_bar[barno];
-	pci_epc_clear_bar(epc, func_no, epf_bar);
+	pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 }
 
 /**
@@ -886,10 +896,10 @@ static int epf_ntb_config_sspad_bar_set(struct epf_ntb_epc *ntb_epc)
 {
 	struct pci_epf_bar *epf_bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct epf_ntb *ntb;
 	struct pci_epc *epc;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	ntb = ntb_epc->epf_ntb;
@@ -897,10 +907,11 @@ static int epf_ntb_config_sspad_bar_set(struct epf_ntb_epc *ntb_epc)
 
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	barno = ntb_epc->epf_ntb_bar[BAR_CONFIG];
 	epf_bar = &ntb_epc->epf_bar[barno];
 
-	ret = pci_epc_set_bar(epc, func_no, epf_bar);
+	ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 	if (ret) {
 		dev_err(dev, "%s inft: Config/Status/SPAD BAR set failed\n",
 			pci_epc_interface_string(ntb_epc->type));
@@ -1214,17 +1225,18 @@ static void epf_ntb_db_mw_bar_clear(struct epf_ntb_epc *ntb_epc)
 	struct pci_epf_bar *epf_bar;
 	enum epf_ntb_bar bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
-	u8 func_no;
 
 	epc = ntb_epc->epc;
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	for (bar = BAR_DB_MW1; bar < BAR_MW4; bar++) {
 		barno = ntb_epc->epf_ntb_bar[bar];
 		epf_bar = &ntb_epc->epf_bar[barno];
-		pci_epc_clear_bar(epc, func_no, epf_bar);
+		pci_epc_clear_bar(epc, func_no, vfunc_no, epf_bar);
 	}
 }
 
@@ -1263,10 +1275,10 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	const struct pci_epc_features *epc_features;
 	bool msix_capable, msi_capable;
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
 	u32 db_count;
-	u8 func_no;
 	int ret;
 
 	ntb_epc = ntb->epc[type];
@@ -1282,6 +1294,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	}
 
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	db_count = ntb->db_count;
 	if (db_count > MAX_DB_COUNT) {
@@ -1293,7 +1306,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	epc = ntb_epc->epc;
 
 	if (msi_capable) {
-		ret = pci_epc_set_msi(epc, func_no, db_count);
+		ret = pci_epc_set_msi(epc, func_no, vfunc_no, db_count);
 		if (ret) {
 			dev_err(dev, "%s intf: MSI configuration failed\n",
 				pci_epc_interface_string(type));
@@ -1302,7 +1315,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 	}
 
 	if (msix_capable) {
-		ret = pci_epc_set_msix(epc, func_no, db_count,
+		ret = pci_epc_set_msix(epc, func_no, vfunc_no, db_count,
 				       ntb_epc->msix_bar,
 				       ntb_epc->msix_table_offset);
 		if (ret) {
@@ -1423,11 +1436,11 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 	u32 num_mws, db_count;
 	enum epf_ntb_bar bar;
 	enum pci_barno barno;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct device *dev;
 	size_t align;
 	int ret, i;
-	u8 func_no;
 	u64 size;
 
 	ntb_epc = ntb->epc[type];
@@ -1437,6 +1450,7 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 	epc_features = ntb_epc->epc_features;
 	align = epc_features->align;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 	epc = ntb_epc->epc;
 	num_mws = ntb->num_mws;
 	db_count = ntb->db_count;
@@ -1464,7 +1478,7 @@ static int epf_ntb_db_mw_bar_init(struct epf_ntb *ntb,
 		barno = ntb_epc->epf_ntb_bar[bar];
 		epf_bar = &ntb_epc->epf_bar[barno];
 
-		ret = pci_epc_set_bar(epc, func_no, epf_bar);
+		ret = pci_epc_set_bar(epc, func_no, vfunc_no, epf_bar);
 		if (ret) {
 			dev_err(dev, "%s intf: DoorBell BAR set failed\n",
 				pci_epc_interface_string(type));
@@ -1536,9 +1550,9 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 	const struct pci_epc_features *epc_features;
 	struct pci_epf_bar *epf_bar;
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epf *epf;
 	struct device *dev;
-	u8 func_no;
 
 	dev = &ntb->epf->dev;
 
@@ -1547,6 +1561,7 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 		return -ENOMEM;
 
 	epf = ntb->epf;
+	vfunc_no = epf->vfunc_no;
 	if (type == PRIMARY_INTERFACE) {
 		func_no = epf->func_no;
 		epf_bar = epf->bar;
@@ -1558,11 +1573,12 @@ static int epf_ntb_epc_create_interface(struct epf_ntb *ntb,
 	ntb_epc->linkup = false;
 	ntb_epc->epc = epc;
 	ntb_epc->func_no = func_no;
+	ntb_epc->vfunc_no = vfunc_no;
 	ntb_epc->type = type;
 	ntb_epc->epf_bar = epf_bar;
 	ntb_epc->epf_ntb = ntb;
 
-	epc_features = pci_epc_get_features(epc, func_no);
+	epc_features = pci_epc_get_features(epc, func_no, vfunc_no);
 	if (!epc_features)
 		return -EINVAL;
 	ntb_epc->epc_features = epc_features;
@@ -1702,10 +1718,10 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 				      enum pci_epc_interface_type type)
 {
 	struct epf_ntb_epc *ntb_epc;
+	u8 func_no, vfunc_no;
 	struct pci_epc *epc;
 	struct pci_epf *epf;
 	struct device *dev;
-	u8 func_no;
 	int ret;
 
 	ntb_epc = ntb->epc[type];
@@ -1713,6 +1729,7 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 	dev = &epf->dev;
 	epc = ntb_epc->epc;
 	func_no = ntb_epc->func_no;
+	vfunc_no = ntb_epc->vfunc_no;
 
 	ret = epf_ntb_config_sspad_bar_set(ntb->epc[type]);
 	if (ret) {
@@ -1742,11 +1759,13 @@ static int epf_ntb_epc_init_interface(struct epf_ntb *ntb,
 		goto err_db_mw_bar_init;
 	}
 
-	ret = pci_epc_write_header(epc, func_no, epf->header);
-	if (ret) {
-		dev_err(dev, "%s intf: Configuration header write failed\n",
-			pci_epc_interface_string(type));
-		goto err_write_header;
+	if (vfunc_no <= 1) {
+		ret = pci_epc_write_header(epc, func_no, vfunc_no, epf->header);
+		if (ret) {
+			dev_err(dev, "%s intf: Configuration header write failed\n",
+				pci_epc_interface_string(type));
+			goto err_write_header;
+		}
 	}
 
 	INIT_DELAYED_WORK(&ntb->epc[type]->cmd_handler, epf_ntb_cmd_handler);
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index d2708ca4bece..90d84d3bc868 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -247,8 +247,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, src_phys_addr,
+			       reg->src_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map source address\n");
 		reg->status = STATUS_SRC_ADDR_INVALID;
@@ -263,8 +263,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 		goto err_src_map_addr;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, dst_phys_addr,
+			       reg->dst_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map destination address\n");
 		reg->status = STATUS_DST_ADDR_INVALID;
@@ -291,13 +291,13 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 	pci_epf_test_print_rate("COPY", reg->size, &start, &end, use_dma);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, dst_phys_addr);
 
 err_dst_addr:
 	pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
 
 err_src_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, src_phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, src_phys_addr);
 
 err_src_addr:
 	pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
@@ -331,8 +331,8 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, phys_addr,
+			       reg->src_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map address\n");
 		reg->status = STATUS_SRC_ADDR_INVALID;
@@ -386,7 +386,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 	kfree(buf);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, phys_addr);
 
 err_addr:
 	pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
@@ -419,8 +419,8 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr,
-			       reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, epf->vfunc_no, phys_addr,
+			       reg->dst_addr, reg->size);
 	if (ret) {
 		dev_err(dev, "Failed to map address\n");
 		reg->status = STATUS_DST_ADDR_INVALID;
@@ -479,7 +479,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 	kfree(buf);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, epf->vfunc_no, phys_addr);
 
 err_addr:
 	pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
@@ -501,13 +501,16 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq_type,
 
 	switch (irq_type) {
 	case IRQ_TYPE_LEGACY:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_LEGACY, 0);
 		break;
 	case IRQ_TYPE_MSI:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSI, irq);
 		break;
 	case IRQ_TYPE_MSIX:
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX, irq);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSIX, irq);
 		break;
 	default:
 		dev_err(dev, "Failed to raise IRQ, unknown type\n");
@@ -542,7 +545,8 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 
 	if (command & COMMAND_RAISE_LEGACY_IRQ) {
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_LEGACY, 0);
 		goto reset_handler;
 	}
 
@@ -580,22 +584,22 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 	}
 
 	if (command & COMMAND_RAISE_MSI_IRQ) {
-		count = pci_epc_get_msi(epc, epf->func_no);
+		count = pci_epc_get_msi(epc, epf->func_no, epf->vfunc_no);
 		if (reg->irq_number > count || count <= 0)
 			goto reset_handler;
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI,
-				  reg->irq_number);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSI, reg->irq_number);
 		goto reset_handler;
 	}
 
 	if (command & COMMAND_RAISE_MSIX_IRQ) {
-		count = pci_epc_get_msix(epc, epf->func_no);
+		count = pci_epc_get_msix(epc, epf->func_no, epf->vfunc_no);
 		if (reg->irq_number > count || count <= 0)
 			goto reset_handler;
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX,
-				  reg->irq_number);
+		pci_epc_raise_irq(epc, epf->func_no, epf->vfunc_no,
+				  PCI_EPC_IRQ_MSIX, reg->irq_number);
 		goto reset_handler;
 	}
 
@@ -618,7 +622,8 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 		epf_bar = &epf->bar[bar];
 
 		if (epf_test->reg[bar]) {
-			pci_epc_clear_bar(epc, epf->func_no, epf_bar);
+			pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no,
+					  epf_bar);
 			pci_epf_free_space(epf, epf_test->reg[bar], bar,
 					   PRIMARY_INTERFACE);
 		}
@@ -650,7 +655,8 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
 		if (!!(epc_features->reserved_bar & (1 << bar)))
 			continue;
 
-		ret = pci_epc_set_bar(epc, epf->func_no, epf_bar);
+		ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no,
+				      epf_bar);
 		if (ret) {
 			pci_epf_free_space(epf, epf_test->reg[bar], bar,
 					   PRIMARY_INTERFACE);
@@ -674,16 +680,18 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 	bool msi_capable = true;
 	int ret;
 
-	epc_features = pci_epc_get_features(epc, epf->func_no);
+	epc_features = pci_epc_get_features(epc, epf->func_no, epf->vfunc_no);
 	if (epc_features) {
 		msix_capable = epc_features->msix_capable;
 		msi_capable = epc_features->msi_capable;
 	}
 
-	ret = pci_epc_write_header(epc, epf->func_no, header);
-	if (ret) {
-		dev_err(dev, "Configuration header write failed\n");
-		return ret;
+	if (epf->vfunc_no <= 1) {
+		ret = pci_epc_write_header(epc, epf->func_no, epf->vfunc_no, header);
+		if (ret) {
+			dev_err(dev, "Configuration header write failed\n");
+			return ret;
+		}
 	}
 
 	ret = pci_epf_test_set_bar(epf);
@@ -691,7 +699,8 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 		return ret;
 
 	if (msi_capable) {
-		ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
+		ret = pci_epc_set_msi(epc, epf->func_no, epf->vfunc_no,
+				      epf->msi_interrupts);
 		if (ret) {
 			dev_err(dev, "MSI configuration failed\n");
 			return ret;
@@ -699,7 +708,8 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
 	}
 
 	if (msix_capable) {
-		ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts,
+		ret = pci_epc_set_msix(epc, epf->func_no, epf->vfunc_no,
+				       epf->msix_interrupts,
 				       epf_test->test_reg_bar,
 				       epf_test->msix_table_offset);
 		if (ret) {
@@ -832,7 +842,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 	if (WARN_ON_ONCE(!epc))
 		return -EINVAL;
 
-	epc_features = pci_epc_get_features(epc, epf->func_no);
+	epc_features = pci_epc_get_features(epc, epf->func_no, epf->vfunc_no);
 	if (!epc_features) {
 		dev_err(&epf->dev, "epc_features not implemented\n");
 		return -EOPNOTSUPP;
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 01c58ca84dcc..ecbb0fb3b653 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -137,24 +137,29 @@ EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar);
  * @epc: the features supported by *this* EPC device will be returned
  * @func_no: the features supported by the EPC device specific to the
  *	     endpoint function with func_no will be returned
+ * @vfunc_no: the features supported by the EPC device specific to the
+ *	     virtual endpoint function with vfunc_no will be returned
  *
  * Invoke to get the features provided by the EPC which may be
  * specific to an endpoint function. Returns pci_epc_features on success
  * and NULL for any failures.
  */
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
-						    u8 func_no)
+						    u8 func_no, u8 vfunc_no)
 {
 	const struct pci_epc_features *epc_features;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return NULL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return NULL;
+
 	if (!epc->ops->get_features)
 		return NULL;
 
 	mutex_lock(&epc->lock);
-	epc_features = epc->ops->get_features(epc, func_no);
+	epc_features = epc->ops->get_features(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	return epc_features;
@@ -205,13 +210,14 @@ EXPORT_SYMBOL_GPL(pci_epc_start);
 /**
  * pci_epc_raise_irq() - interrupt the host system
  * @epc: the EPC device which has to interrupt the host
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @type: specify the type of interrupt; legacy, MSI or MSI-X
  * @interrupt_num: the MSI or MSI-X interrupt number
  *
  * Invoke to raise an legacy, MSI or MSI-X interrupt
  */
-int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		      enum pci_epc_irq_type type, u16 interrupt_num)
 {
 	int ret;
@@ -219,11 +225,14 @@ int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->raise_irq)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->raise_irq(epc, func_no, type, interrupt_num);
+	ret = epc->ops->raise_irq(epc, func_no, vfunc_no, type, interrupt_num);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -235,6 +244,7 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
  *                         MSI data
  * @epc: the EPC device which has the MSI capability
  * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: the physical address of the outbound region
  * @interrupt_num: the MSI interrupt number
  * @entry_size: Size of Outbound address region for each interrupt
@@ -250,21 +260,25 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
  * physical address (in outbound region) of the other interface to ring
  * doorbell.
  */
-int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, phys_addr_t phys_addr,
-			u8 interrupt_num, u32 entry_size, u32 *msi_data,
-			u32 *msi_addr_offset)
+int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			phys_addr_t phys_addr, u8 interrupt_num, u32 entry_size,
+			u32 *msi_data, u32 *msi_addr_offset)
 {
 	int ret;
 
 	if (IS_ERR_OR_NULL(epc))
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->map_msi_irq)
 		return -EINVAL;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->map_msi_irq(epc, func_no, phys_addr, interrupt_num,
-				    entry_size, msi_data, msi_addr_offset);
+	ret = epc->ops->map_msi_irq(epc, func_no, vfunc_no, phys_addr,
+				    interrupt_num, entry_size, msi_data,
+				    msi_addr_offset);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -274,22 +288,26 @@ EXPORT_SYMBOL_GPL(pci_epc_map_msi_irq);
 /**
  * pci_epc_get_msi() - get the number of MSI interrupt numbers allocated
  * @epc: the EPC device to which MSI interrupts was requested
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  *
  * Invoke to get the number of MSI interrupts allocated by the RC
  */
-int pci_epc_get_msi(struct pci_epc *epc, u8 func_no)
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	int interrupt;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return 0;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return 0;
+
 	if (!epc->ops->get_msi)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	interrupt = epc->ops->get_msi(epc, func_no);
+	interrupt = epc->ops->get_msi(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	if (interrupt < 0)
@@ -304,12 +322,13 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msi);
 /**
  * pci_epc_set_msi() - set the number of MSI interrupt numbers required
  * @epc: the EPC device on which MSI has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @interrupts: number of MSI interrupts required by the EPF
  *
  * Invoke to set the required number of MSI interrupts.
  */
-int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no, u8 interrupts)
 {
 	int ret;
 	u8 encode_int;
@@ -318,13 +337,16 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 	    interrupts > 32)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_msi)
 		return 0;
 
 	encode_int = order_base_2(interrupts);
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_msi(epc, func_no, encode_int);
+	ret = epc->ops->set_msi(epc, func_no, vfunc_no, encode_int);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -334,22 +356,26 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msi);
 /**
  * pci_epc_get_msix() - get the number of MSI-X interrupt numbers allocated
  * @epc: the EPC device to which MSI-X interrupts was requested
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  *
  * Invoke to get the number of MSI-X interrupts allocated by the RC
  */
-int pci_epc_get_msix(struct pci_epc *epc, u8 func_no)
+int pci_epc_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
 	int interrupt;
 
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return 0;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return 0;
+
 	if (!epc->ops->get_msix)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	interrupt = epc->ops->get_msix(epc, func_no);
+	interrupt = epc->ops->get_msix(epc, func_no, vfunc_no);
 	mutex_unlock(&epc->lock);
 
 	if (interrupt < 0)
@@ -362,15 +388,16 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msix);
 /**
  * pci_epc_set_msix() - set the number of MSI-X interrupt numbers required
  * @epc: the EPC device on which MSI-X has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @interrupts: number of MSI-X interrupts required by the EPF
  * @bir: BAR where the MSI-X table resides
  * @offset: Offset pointing to the start of MSI-X table
  *
  * Invoke to set the required number of MSI-X interrupts.
  */
-int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-		     enum pci_barno bir, u32 offset)
+int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		     u16 interrupts, enum pci_barno bir, u32 offset)
 {
 	int ret;
 
@@ -378,11 +405,15 @@ int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
 	    interrupts < 1 || interrupts > 2048)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_msix)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_msix(epc, func_no, interrupts - 1, bir, offset);
+	ret = epc->ops->set_msix(epc, func_no, vfunc_no, interrupts - 1, bir,
+				 offset);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -392,22 +423,26 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msix);
 /**
  * pci_epc_unmap_addr() - unmap CPU address from PCI address
  * @epc: the EPC device on which address is allocated
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: physical address of the local system
  *
  * Invoke to unmap the CPU address from PCI address.
  */
-void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr)
 {
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return;
+
 	if (!epc->ops->unmap_addr)
 		return;
 
 	mutex_lock(&epc->lock);
-	epc->ops->unmap_addr(epc, func_no, phys_addr);
+	epc->ops->unmap_addr(epc, func_no, vfunc_no, phys_addr);
 	mutex_unlock(&epc->lock);
 }
 EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
@@ -415,14 +450,15 @@ EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
 /**
  * pci_epc_map_addr() - map CPU address to PCI address
  * @epc: the EPC device on which address is allocated
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @phys_addr: physical address of the local system
  * @pci_addr: PCI address to which the physical address should be mapped
  * @size: the size of the allocation
  *
  * Invoke to map CPU address with PCI address.
  */
-int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		     phys_addr_t phys_addr, u64 pci_addr, size_t size)
 {
 	int ret;
@@ -430,11 +466,15 @@ int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->map_addr)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->map_addr(epc, func_no, phys_addr, pci_addr, size);
+	ret = epc->ops->map_addr(epc, func_no, vfunc_no, phys_addr, pci_addr,
+				 size);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -444,12 +484,13 @@ EXPORT_SYMBOL_GPL(pci_epc_map_addr);
 /**
  * pci_epc_clear_bar() - reset the BAR
  * @epc: the EPC device for which the BAR has to be cleared
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @epf_bar: the struct epf_bar that contains the BAR information
  *
  * Invoke to reset the BAR of the endpoint device.
  */
-void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		       struct pci_epf_bar *epf_bar)
 {
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions ||
@@ -457,11 +498,14 @@ void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
 	     epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64))
 		return;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return;
+
 	if (!epc->ops->clear_bar)
 		return;
 
 	mutex_lock(&epc->lock);
-	epc->ops->clear_bar(epc, func_no, epf_bar);
+	epc->ops->clear_bar(epc, func_no, vfunc_no, epf_bar);
 	mutex_unlock(&epc->lock);
 }
 EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
@@ -469,12 +513,13 @@ EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
 /**
  * pci_epc_set_bar() - configure BAR in order for host to assign PCI addr space
  * @epc: the EPC device on which BAR has to be configured
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @epf_bar: the struct epf_bar that contains the BAR information
  *
  * Invoke to configure the BAR of the endpoint device.
  */
-int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		    struct pci_epf_bar *epf_bar)
 {
 	int ret;
@@ -489,11 +534,14 @@ int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
 	     !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64)))
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
 	if (!epc->ops->set_bar)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->set_bar(epc, func_no, epf_bar);
+	ret = epc->ops->set_bar(epc, func_no, vfunc_no, epf_bar);
 	mutex_unlock(&epc->lock);
 
 	return ret;
@@ -503,7 +551,8 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
 /**
  * pci_epc_write_header() - write standard configuration header
  * @epc: the EPC device to which the configuration header should be written
- * @func_no: the endpoint function number in the EPC device
+ * @func_no: the physical endpoint function number in the EPC device
+ * @vfunc_no: the virtual endpoint function number in the physical function
  * @header: standard configuration header fields
  *
  * Invoke to write the configuration header to the endpoint controller. Every
@@ -511,7 +560,7 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
  * configuration header would be written. The callback function should write
  * the header fields to this dedicated location.
  */
-int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			 struct pci_epf_header *header)
 {
 	int ret;
@@ -519,11 +568,18 @@ int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
 	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
+	if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
+		return -EINVAL;
+
+	/* Only Virtual Function #1 has deviceID */
+	if (vfunc_no > 1)
+		return -EINVAL;
+
 	if (!epc->ops->write_header)
 		return 0;
 
 	mutex_lock(&epc->lock);
-	ret = epc->ops->write_header(epc, func_no, header);
+	ret = epc->ops->write_header(epc, func_no, vfunc_no, header);
 	mutex_unlock(&epc->lock);
 
 	return ret;
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 296479659aa2..af691b317f74 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -90,11 +90,14 @@ EXPORT_SYMBOL_GPL(pci_epf_unbind);
  */
 int pci_epf_bind(struct pci_epf *epf)
 {
+	struct device *dev = &epf->dev;
 	struct pci_epf *epf_vf;
+	u8 func_no, vfunc_no;
+	struct pci_epc *epc;
 	int ret;
 
 	if (!epf->driver) {
-		dev_WARN(&epf->dev, "epf device not bound to driver\n");
+		dev_WARN(dev, "epf device not bound to driver\n");
 		return -EINVAL;
 	}
 
@@ -103,7 +106,50 @@ int pci_epf_bind(struct pci_epf *epf)
 
 	mutex_lock(&epf->lock);
 	list_for_each_entry(epf_vf, &epf->pci_vepf, list) {
+		vfunc_no = epf_vf->vfunc_no;
+
+		if (vfunc_no < 1) {
+			dev_err(dev, "Invalid virtual function number\n");
+			ret = -EINVAL;
+			goto ret;
+		}
+
+		epc = epf->epc;
+		func_no = epf->func_no;
+		if (!IS_ERR_OR_NULL(epc)) {
+			if (!epc->max_vfs) {
+				dev_err(dev, "No support for virt function\n");
+				ret = -EINVAL;
+				goto ret;
+			}
+
+			if (vfunc_no > epc->max_vfs[func_no]) {
+				dev_err(dev, "PF%d: Exceeds max vfunc number\n",
+					func_no);
+				ret = -EINVAL;
+				goto ret;
+			}
+		}
+
+		epc = epf->sec_epc;
+		func_no = epf->sec_epc_func_no;
+		if (!IS_ERR_OR_NULL(epc)) {
+			if (!epc->max_vfs) {
+				dev_err(dev, "No support for virt function\n");
+				ret = -EINVAL;
+				goto ret;
+			}
+
+			if (vfunc_no > epc->max_vfs[func_no]) {
+				dev_err(dev, "PF%d: Exceeds max vfunc number\n",
+					func_no);
+				ret = -EINVAL;
+				goto ret;
+			}
+		}
+
 		epf_vf->func_no = epf->func_no;
+		epf_vf->sec_epc_func_no = epf->sec_epc_func_no;
 		epf_vf->epc = epf->epc;
 		epf_vf->sec_epc = epf->sec_epc;
 		ret = epf_vf->driver->ops->bind(epf_vf);
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 50a649d33e68..a48778e1a4ee 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -62,31 +62,32 @@ pci_epc_interface_string(enum pci_epc_interface_type type)
  * @owner: the module owner containing the ops
  */
 struct pci_epc_ops {
-	int	(*write_header)(struct pci_epc *epc, u8 func_no,
+	int	(*write_header)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 				struct pci_epf_header *hdr);
-	int	(*set_bar)(struct pci_epc *epc, u8 func_no,
+	int	(*set_bar)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			   struct pci_epf_bar *epf_bar);
-	void	(*clear_bar)(struct pci_epc *epc, u8 func_no,
+	void	(*clear_bar)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			     struct pci_epf_bar *epf_bar);
-	int	(*map_addr)(struct pci_epc *epc, u8 func_no,
+	int	(*map_addr)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			    phys_addr_t addr, u64 pci_addr, size_t size);
-	void	(*unmap_addr)(struct pci_epc *epc, u8 func_no,
+	void	(*unmap_addr)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			      phys_addr_t addr);
-	int	(*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts);
-	int	(*get_msi)(struct pci_epc *epc, u8 func_no);
-	int	(*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts,
-			    enum pci_barno, u32 offset);
-	int	(*get_msix)(struct pci_epc *epc, u8 func_no);
-	int	(*raise_irq)(struct pci_epc *epc, u8 func_no,
+	int	(*set_msi)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			   u8 interrupts);
+	int	(*get_msi)(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+	int	(*set_msix)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+			    u16 interrupts, enum pci_barno, u32 offset);
+	int	(*get_msix)(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+	int	(*raise_irq)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			     enum pci_epc_irq_type type, u16 interrupt_num);
-	int	(*map_msi_irq)(struct pci_epc *epc, u8 func_no,
+	int	(*map_msi_irq)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			       phys_addr_t phys_addr, u8 interrupt_num,
 			       u32 entry_size, u32 *msi_data,
 			       u32 *msi_addr_offset);
 	int	(*start)(struct pci_epc *epc);
 	void	(*stop)(struct pci_epc *epc);
 	const struct pci_epc_features* (*get_features)(struct pci_epc *epc,
-						       u8 func_no);
+						       u8 func_no, u8 vfunc_no);
 	struct module *owner;
 };
 
@@ -128,6 +129,8 @@ struct pci_epc_mem {
  *       single window.
  * @num_windows: number of windows supported by device
  * @max_functions: max number of functions that can be configured in this EPC
+ * @max_vfs: Array indicating the maximum number of virtual functions that can
+ *   be associated with each physical function
  * @group: configfs group representing the PCI EPC device
  * @lock: mutex to protect pci_epc ops
  * @function_num_map: bitmap to manage physical function number
@@ -141,6 +144,7 @@ struct pci_epc {
 	struct pci_epc_mem		*mem;
 	unsigned int			num_windows;
 	u8				max_functions;
+	u8				*max_vfs;
 	struct config_group		*group;
 	/* mutex to protect against concurrent access of EP controller */
 	struct mutex			lock;
@@ -208,31 +212,32 @@ void pci_epc_linkup(struct pci_epc *epc);
 void pci_epc_init_notify(struct pci_epc *epc);
 void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
 			enum pci_epc_interface_type type);
-int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			 struct pci_epf_header *hdr);
-int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		    struct pci_epf_bar *epf_bar);
-void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no,
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		       struct pci_epf_bar *epf_bar);
-int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		     phys_addr_t phys_addr,
 		     u64 pci_addr, size_t size);
-void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr);
-int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
-int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);
-int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts,
-		     enum pci_barno, u32 offset);
-int pci_epc_get_msix(struct pci_epc *epc, u8 func_no);
-int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		    u8 interrupts);
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+		     u16 interrupts, enum pci_barno, u32 offset);
+int pci_epc_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no);
+int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 			phys_addr_t phys_addr, u8 interrupt_num,
 			u32 entry_size, u32 *msi_data, u32 *msi_addr_offset);
-int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
 		      enum pci_epc_irq_type type, u16 interrupt_num);
 int pci_epc_start(struct pci_epc *epc);
 void pci_epc_stop(struct pci_epc *epc);
 const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
-						    u8 func_no);
+						    u8 func_no, u8 vfunc_no);
 enum pci_barno
 pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features);
 enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:33:40 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:40 +0530
Subject: [PATCH v9 5/8] PCI: cadence: Simplify code to get register base
 address for configuring BAR
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <20210819123343.1951-6-kishon@ti.com>

No functional change. Simplify code to get register base address for
configuring PCI BAR.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c   | 18 ++++--------------
 drivers/pci/controller/cadence/pcie-cadence.h  |  3 +++
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 912a15be8bfd..f337f0842400 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -97,13 +97,8 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
 			 addr1);
 
-	if (bar < BAR_4) {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
-		b = bar;
-	} else {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
-		b = bar - BAR_4;
-	}
+	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+	b = (bar < BAR_4) ? bar : bar - BAR_4;
 
 	cfg = cdns_pcie_readl(pcie, reg);
 	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
@@ -126,13 +121,8 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 	enum pci_barno bar = epf_bar->barno;
 	u32 reg, cfg, b, ctrl;
 
-	if (bar < BAR_4) {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
-		b = bar;
-	} else {
-		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
-		b = bar - BAR_4;
-	}
+	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+	b = (bar < BAR_4) ? bar : bar - BAR_4;
 
 	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
 	cfg = cdns_pcie_readl(pcie, reg);
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 30db2d68c17a..347ed7bd2038 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/pci-epf.h>
 #include <linux/phy/phy.h>
 
 /* Parameters for the waiting for link up routine */
@@ -46,6 +47,8 @@
 #define  CDNS_PCIE_LM_EP_ID_BUS_SHIFT	8
 
 /* Endpoint Function f BAR b Configuration Registers */
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn) \
+	(((bar) < BAR_4) ? CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn))
 #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \
 	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
 #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:33:41 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:41 +0530
Subject: [PATCH v9 6/8] PCI: cadence: Add support to configure virtual
 functions
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <20210819123343.1951-7-kishon@ti.com>

Now that support for SR-IOV is added in PCIe endpoint core, add support
to configure virtual functions in the Cadence PCIe EP driver.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 .../pci/controller/cadence/pcie-cadence-ep.c  | 140 +++++++++++++++---
 drivers/pci/controller/cadence/pcie-cadence.h |   9 ++
 2 files changed, 128 insertions(+), 21 deletions(-)

diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index f337f0842400..b693c5f6a449 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -16,11 +16,37 @@
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE		0x1
 #define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY	0x3
 
+static u8 cdns_pcie_get_fn_from_vfn(struct cdns_pcie *pcie, u8 fn, u8 vfn)
+{
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
+	u32 first_vf_offset, stride;
+
+	if (vfn == 0)
+		return fn;
+
+	first_vf_offset = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_SRIOV_VF_OFFSET);
+	stride = cdns_pcie_ep_fn_readw(pcie, fn, cap +  PCI_SRIOV_VF_STRIDE);
+	fn = fn + first_vf_offset + ((vfn - 1) * stride);
+
+	return fn;
+}
+
 static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn, u8 vfn,
 				     struct pci_epf_header *hdr)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	u32 cap = CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET;
 	struct cdns_pcie *pcie = &ep->pcie;
+	u32 reg;
+
+	if (vfn > 1) {
+		dev_err(&epc->dev, "Only Virtual Function #1 has deviceID\n");
+		return -EINVAL;
+	} else if (vfn == 1) {
+		reg = cap + PCI_SRIOV_VF_DID;
+		cdns_pcie_ep_fn_writew(pcie, fn, reg, hdr->deviceid);
+		return 0;
+	}
 
 	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
 	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
@@ -92,21 +118,30 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 
 	addr0 = lower_32_bits(bar_phys);
 	addr1 = upper_32_bits(bar_phys);
+
+	if (vfn == 1)
+		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
+	else
+		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+	b = (bar < BAR_4) ? bar : bar - BAR_4;
+
+	if (vfn == 0 || vfn == 1) {
+		cfg = cdns_pcie_readl(pcie, reg);
+		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+		cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+			CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+		cdns_pcie_writel(pcie, reg, cfg);
+	}
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
 			 addr0);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
 			 addr1);
 
-	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
-	b = (bar < BAR_4) ? bar : bar - BAR_4;
-
-	cfg = cdns_pcie_readl(pcie, reg);
-	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
-		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
-	cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
-		CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
-	cdns_pcie_writel(pcie, reg, cfg);
-
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
 	epf->epf_bar[bar] = epf_bar;
 
 	return 0;
@@ -121,19 +156,27 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn, u8 vfn,
 	enum pci_barno bar = epf_bar->barno;
 	u32 reg, cfg, b, ctrl;
 
-	reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
+	if (vfn == 1)
+		reg = CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn);
+	else
+		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG(bar, fn);
 	b = (bar < BAR_4) ? bar : bar - BAR_4;
 
-	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
-	cfg = cdns_pcie_readl(pcie, reg);
-	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
-		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
-	cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
-	cdns_pcie_writel(pcie, reg, cfg);
+	if (vfn == 0 || vfn == 1) {
+		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
+		cfg = cdns_pcie_readl(pcie, reg);
+		cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+			 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+		cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
+		cdns_pcie_writel(pcie, reg, cfg);
+	}
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0);
 	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0);
 
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
 	epf->epf_bar[bar] = NULL;
 }
 
@@ -151,6 +194,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn,
 		return -EINVAL;
 	}
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
 	cdns_pcie_set_outbound_region(pcie, 0, fn, r, false, addr, pci_addr, size);
 
 	set_bit(r, &ep->ob_region_map);
@@ -186,6 +230,8 @@ static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 vfn, u8 mmc)
 	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
 	u16 flags;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/*
 	 * Set the Multiple Message Capable bitfield into the Message Control
 	 * register.
@@ -206,6 +252,8 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn, u8 vfn)
 	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
 	u16 flags, mme;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/* Validate that the MSI feature is actually enabled. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
 	if (!(flags & PCI_MSI_FLAGS_ENABLE))
@@ -227,6 +275,8 @@ static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
 	u32 val, reg;
 
+	func_no = cdns_pcie_get_fn_from_vfn(pcie, func_no, vfunc_no);
+
 	reg = cap + PCI_MSIX_FLAGS;
 	val = cdns_pcie_ep_fn_readw(pcie, func_no, reg);
 	if (!(val & PCI_MSIX_FLAGS_ENABLE))
@@ -246,6 +296,8 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
 	u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
 	u32 val, reg;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	reg = cap + PCI_MSIX_FLAGS;
 	val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
 	val &= ~PCI_MSIX_FLAGS_QSIZE;
@@ -265,8 +317,8 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u8 vfn,
 	return 0;
 }
 
-static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
-				     u8 intx, bool is_asserted)
+static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn, u8 intx,
+				     bool is_asserted)
 {
 	struct cdns_pcie *pcie = &ep->pcie;
 	unsigned long flags;
@@ -335,6 +387,8 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 	u8 msi_count;
 	u64 pci_addr, pci_addr_mask = 0xff;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/* Check whether the MSI feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
 	if (!(flags & PCI_MSI_FLAGS_ENABLE))
@@ -388,6 +442,8 @@ static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 	int ret;
 	int i;
 
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/* Check whether the MSI feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
 	if (!(flags & PCI_MSI_FLAGS_ENABLE))
@@ -438,6 +494,12 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 	u16 flags;
 	u8 bir;
 
+	epf = &ep->epf[fn];
+	if (vfn > 0)
+		epf = &epf->epf[vfn - 1];
+
+	fn = cdns_pcie_get_fn_from_vfn(pcie, fn, vfn);
+
 	/* Check whether the MSI-X feature has been enabled by the PCI host. */
 	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
 	if (!(flags & PCI_MSIX_FLAGS_ENABLE))
@@ -448,7 +510,6 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, u8 vfn,
 	bir = tbl_offset & PCI_MSIX_TABLE_BIR;
 	tbl_offset &= PCI_MSIX_TABLE_OFFSET;
 
-	epf = &ep->epf[fn];
 	msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
 	msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
 	msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
@@ -475,9 +536,15 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, u8 vfn,
 				  u16 interrupt_num)
 {
 	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	struct device *dev = pcie->dev;
 
 	switch (type) {
 	case PCI_EPC_IRQ_LEGACY:
+		if (vfn > 0) {
+			dev_err(dev, "Cannot raise legacy interrupts for VF\n");
+			return -EINVAL;
+		}
 		return cdns_pcie_ep_send_legacy_irq(ep, fn, vfn, 0);
 
 	case PCI_EPC_IRQ_MSI:
@@ -515,6 +582,13 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
 	return 0;
 }
 
+static const struct pci_epc_features cdns_pcie_epc_vf_features = {
+	.linkup_notifier = false,
+	.msi_capable = true,
+	.msix_capable = true,
+	.align = 65536,
+};
+
 static const struct pci_epc_features cdns_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
@@ -525,7 +599,10 @@ static const struct pci_epc_features cdns_pcie_epc_features = {
 static const struct pci_epc_features*
 cdns_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no)
 {
-	return &cdns_pcie_epc_features;
+	if (!vfunc_no)
+		return &cdns_pcie_epc_features;
+
+	return &cdns_pcie_epc_vf_features;
 }
 
 static const struct pci_epc_ops cdns_pcie_epc_ops = {
@@ -551,9 +628,11 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *np = dev->of_node;
 	struct cdns_pcie *pcie = &ep->pcie;
+	struct cdns_pcie_epf *epf;
 	struct resource *res;
 	struct pci_epc *epc;
 	int ret;
+	int i;
 
 	pcie->is_rc = false;
 
@@ -598,6 +677,25 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
 	if (!ep->epf)
 		return -ENOMEM;
 
+	epc->max_vfs = devm_kcalloc(dev, epc->max_functions,
+				    sizeof(*epc->max_vfs), GFP_KERNEL);
+	if (!epc->max_vfs)
+		return -ENOMEM;
+
+	ret = of_property_read_u8_array(np, "max-virtual-functions",
+					epc->max_vfs, epc->max_functions);
+	if (ret == 0) {
+		for (i = 0; i < epc->max_functions; i++) {
+			epf = &ep->epf[i];
+			if (epc->max_vfs[i] == 0)
+				continue;
+			epf->epf = devm_kcalloc(dev, epc->max_vfs[i],
+						sizeof(*ep->epf), GFP_KERNEL);
+			if (!epf->epf)
+				return -ENOMEM;
+		}
+	}
+
 	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
 			       resource_size(pcie->mem_res), PAGE_SIZE);
 	if (ret < 0) {
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 347ed7bd2038..c3fb9021194c 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -53,6 +53,12 @@
 	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
 #define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
 	(CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG(bar, fn) \
+	(((bar) < BAR_4) ? CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) : CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn))
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG0(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0280 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_VFUNC_BAR_CFG1(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0284 + (fn) * 0x0008)
 #define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
 	(GENMASK(4, 0) << ((b) * 8))
 #define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
@@ -117,6 +123,7 @@
 
 #define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET	0x90
 #define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET	0xb0
+#define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET	0x200
 
 /*
  * Root Port Registers (PCI configuration space for the root port function)
@@ -311,9 +318,11 @@ struct cdns_pcie_rc {
 
 /**
  * struct cdns_pcie_epf - Structure to hold info about endpoint function
+ * @epf: Info about virtual functions attached to the physical function
  * @epf_bar: reference to the pci_epf_bar for the six Base Address Registers
  */
 struct cdns_pcie_epf {
+	struct cdns_pcie_epf *epf;
 	struct pci_epf_bar *epf_bar[PCI_STD_NUM_BARS];
 };
 
-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:33:42 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:42 +0530
Subject: [PATCH v9 7/8] misc: pci_endpoint_test: Populate sriov_configure ops
 to configure SR-IOV device
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <20210819123343.1951-8-kishon@ti.com>

Populate sriov_configure ops with pci_sriov_configure_simple to
configure SR-IOV device.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 drivers/misc/pci_endpoint_test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index 1b2868ca4f2a..c7ee34013485 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -978,6 +978,7 @@ static struct pci_driver pci_endpoint_test_driver = {
 	.id_table	= pci_endpoint_test_tbl,
 	.probe		= pci_endpoint_test_probe,
 	.remove		= pci_endpoint_test_remove,
+	.sriov_configure = pci_sriov_configure_simple,
 };
 module_pci_driver(pci_endpoint_test_driver);
 
-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:33:43 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:03:43 +0530
Subject: [PATCH v9 8/8] Documentation: PCI: endpoint/pci-endpoint-cfs: Guide
 to use SR-IOV
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <20210819123343.1951-9-kishon@ti.com>

Add Documentation to help users use PCI endpoint to create virtual
functions using configfs. An endpoint function is designated as a
virtual endpoint function device when it is linked to a physical
endpoint function device (instead of a endpoint controller).

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 Documentation/PCI/endpoint/pci-endpoint-cfs.rst | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/Documentation/PCI/endpoint/pci-endpoint-cfs.rst b/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
index db609b97ad58..fb73345cfb8a 100644
--- a/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
+++ b/Documentation/PCI/endpoint/pci-endpoint-cfs.rst
@@ -43,6 +43,7 @@ entries corresponding to EPF driver will be created by the EPF core.
 		.. <EPF Driver1>/
 			... <EPF Device 11>/
 			... <EPF Device 21>/
+			... <EPF Device 31>/
 		.. <EPF Driver2>/
 			... <EPF Device 12>/
 			... <EPF Device 22>/
@@ -68,6 +69,7 @@ created)
 				... subsys_vendor_id
 				... subsys_id
 				... interrupt_pin
+			        ... <Symlink EPF Device 31>/
                                 ... primary/
 			                ... <Symlink EPC Device1>/
                                 ... secondary/
@@ -79,6 +81,13 @@ interface should be added in 'primary' directory and symlink of endpoint
 controller connected to secondary interface should be added in 'secondary'
 directory.
 
+The <EPF Device> directory can have a list of symbolic links
+(<Symlink EPF Device 31>) to other <EPF Device>. These symbolic links should
+be created by the user to represent the virtual functions that are bound to
+the physical function. In the above directory structure <EPF Device 11> is a
+physical function and <EPF Device 31> is a virtual function. An EPF device once
+it's linked to another EPF device, cannot be linked to a EPC device.
+
 EPC Device
 ==========
 
@@ -98,7 +107,8 @@ entries corresponding to EPC device will be created by the EPC core.
 
 The <EPC Device> directory will have a list of symbolic links to
 <EPF Device>. These symbolic links should be created by the user to
-represent the functions present in the endpoint device.
+represent the functions present in the endpoint device. Only <EPF Device>
+that represents a physical function can be linked to a EPC device.
 
 The <EPC Device> directory will also have a *start* field. Once
 "1" is written to this field, the endpoint device will be ready to
-- 
2.17.1



From kishon at ti.com  Thu Aug 19 05:42:54 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 18:12:54 +0530
Subject: [PATCH v3 0/5] PCI: Add support for J7200 and AM64
In-Reply-To: <20210811123336.31357-1-kishon@ti.com>
References: <20210811123336.31357-1-kishon@ti.com>
Message-ID: <a618e0af-d95f-8e25-5b86-eff7fd14d186@ti.com>

Hi Lorenzo,

On 11/08/21 6:03 pm, Kishon Vijay Abraham I wrote:
> This series adds the compatible specific to J7200 and AM64 and
> applies the erratas and configuration specific to them.
> 
> This series also includes Nadeem's patch that adds a quirk in
> Cadence driver which is used by J7200 [1].
> 
> The DT binding for both J7200 and AM64 is already merged.
> 
> v1 of the patch series can be found at [2]
> v2 of the patch series can be found at [3]

Gentle ping on this series.

I've dropped "misc: pci_endpoint_test: Do not request or allocate IRQs
in probe" [A] from the previous version of the series which you had
concerns with.

[A] -> http://lore.kernel.org/r/02c1ddb7-539e-20a0-1bef-e10e76922a0e at ti.com

Thanks
Kishon

> 
> Changes from v2:
> 1) Drop the patch that does not request or allocate IRQs in probe for
> J721E/AM654
> 2) Fix other minor comments given by Lorenzo
> 
> Changes from v1:
> 1) As suggested by Bjorn, used unsigned int :1, instead of bool for
> structure members
> 2) Removed using unnecessary local variables and also fixed some
> code alignment
> 
> [1] -> https://lore.kernel.org/r/20210528155626.21793-1-nadeem at cadence.com
> [2] -> https://lore.kernel.org/r/20210706105035.9915-1-kishon at ti.com
> [3] -> https://lore.kernel.org/r/20210803074932.19820-1-kishon at ti.com
> 
> Kishon Vijay Abraham I (4):
>   PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
>   PCI: j721e: Add PCIe support for J7200
>   PCI: j721e: Add PCIe support for AM64
>   misc: pci_endpoint_test: Add deviceID for AM64 and J7200
> 
> Nadeem Athani (1):
>   PCI: cadence: Add quirk flag to set minimum delay in LTSSM
>     Detect.Quiet state
> 
>  drivers/misc/pci_endpoint_test.c              |  8 +++
>  drivers/pci/controller/cadence/pci-j721e.c    | 61 +++++++++++++++++--
>  .../pci/controller/cadence/pcie-cadence-ep.c  |  4 ++
>  .../controller/cadence/pcie-cadence-host.c    |  3 +
>  drivers/pci/controller/cadence/pcie-cadence.c | 16 +++++
>  drivers/pci/controller/cadence/pcie-cadence.h | 17 +++++-
>  6 files changed, 103 insertions(+), 6 deletions(-)
> 


From robh at kernel.org  Thu Aug 19 05:49:09 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 07:49:09 -0500
Subject: [PATCH v6 3/5] dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
In-Reply-To: <20210819070954.16679-4-moudy.ho@mediatek.com>
References: <20210819070954.16679-1-moudy.ho@mediatek.com>
 <20210819070954.16679-4-moudy.ho@mediatek.com>
Message-ID: <1629377349.142826.288207.nullmailer@robh.at.kernel.org>

On Thu, 19 Aug 2021 15:09:52 +0800, Moudy Ho wrote:
> This patch adds DT binding document for Media Data Path 3 (MDP3)
> a unit in multimedia system used for scaling and color format convert.
> 
> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> ---
>  .../bindings/media/mediatek,mdp3-ccorr.yaml   |  58 +++++
>  .../bindings/media/mediatek,mdp3-rdma.yaml    | 241 ++++++++++++++++++
>  .../bindings/media/mediatek,mdp3-rsz.yaml     |  66 +++++
>  .../bindings/media/mediatek,mdp3-wdma.yaml    |  71 ++++++
>  .../bindings/media/mediatek,mdp3-wrot.yaml    |  71 ++++++
>  5 files changed, 507 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
make[1]: *** Deleting file 'Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.example.dts'
Traceback (most recent call last):
  File "/usr/local/bin/dt-extract-example", line 45, in <module>
    binding = yaml.load(open(args.yamlfile, encoding='utf-8').read())
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/main.py", line 434, in load
    return constructor.get_single_data()
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 120, in get_single_data
    node = self.composer.get_single_node()
  File "_ruamel_yaml.pyx", line 706, in _ruamel_yaml.CParser.get_single_node
  File "_ruamel_yaml.pyx", line 724, in _ruamel_yaml.CParser._compose_document
  File "_ruamel_yaml.pyx", line 775, in _ruamel_yaml.CParser._compose_node
  File "_ruamel_yaml.pyx", line 889, in _ruamel_yaml.CParser._compose_mapping_node
  File "_ruamel_yaml.pyx", line 773, in _ruamel_yaml.CParser._compose_node
  File "_ruamel_yaml.pyx", line 848, in _ruamel_yaml.CParser._compose_sequence_node
  File "_ruamel_yaml.pyx", line 904, in _ruamel_yaml.CParser._parse_next_event
ruamel.yaml.scanner.ScannerError: while scanning a block scalar
  in "<unicode string>", line 171, column 5
found a tab character where an indentation space is expected
  in "<unicode string>", line 183, column 1
make[1]: *** [Documentation/devicetree/bindings/Makefile:20: Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.example.dts] Error 1
make[1]: *** Waiting for unfinished jobs....
./Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml:  while scanning a block scalar
  in "<unicode string>", line 171, column 5
found a tab character where an indentation space is expected
  in "<unicode string>", line 183, column 1
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml: ignoring, error parsing file
warning: no schema found in file: ./Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1518477

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Thu Aug 19 05:49:09 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 07:49:09 -0500
Subject: [PATCH v2 1/5] dt-bindings: aspeed: Add eSPI controller
In-Reply-To: <20210819080040.31242-2-chiawei_wang@aspeedtech.com>
References: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
 <20210819080040.31242-2-chiawei_wang@aspeedtech.com>
Message-ID: <1629377349.157361.288210.nullmailer@robh.at.kernel.org>

On Thu, 19 Aug 2021 16:00:36 +0800, Chia-Wei Wang wrote:
> Add dt-bindings for Aspeed eSPI controller
> 
> Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
> ---
>  .../devicetree/bindings/soc/aspeed/espi.yaml  | 158 ++++++++++++++++++
>  1 file changed, 158 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/soc/aspeed/espi.example.dts:35.35-36 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/soc/aspeed/espi.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1518493

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From jianjun.wang at mediatek.com  Thu Aug 19 05:59:39 2021
From: jianjun.wang at mediatek.com (Jianjun Wang)
Date: Thu, 19 Aug 2021 20:59:39 +0800
Subject: [PATCH] PCI: mediatek-gen3: Disable DVFSRC voltage request
Message-ID: <20210819125939.21253-1-jianjun.wang@mediatek.com>

When the DVFSRC feature is not implemented, the MAC layer will
assert a voltage request signal when exit from the L1ss state,
but cannot receive the voltage ready signal, which will cause
the link to fail to exit the L1ss state correctly.

Disable DVFSRC voltage request by default, we need to find
a common way to enable it in the future.

Signed-off-by: Jianjun Wang <jianjun.wang at mediatek.com>
---
 drivers/pci/controller/pcie-mediatek-gen3.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index f3aeb8d4eaca..79fb12fca6a9 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -79,6 +79,9 @@
 #define PCIE_ICMD_PM_REG		0x198
 #define PCIE_TURN_OFF_LINK		BIT(4)
 
+#define PCIE_MISC_CTRL_REG		0x348
+#define PCIE_DISABLE_DVFSRC_VLT_REQ	BIT(1)
+
 #define PCIE_TRANS_TABLE_BASE_REG	0x800
 #define PCIE_ATR_SRC_ADDR_MSB_OFFSET	0x4
 #define PCIE_ATR_TRSL_ADDR_LSB_OFFSET	0x8
@@ -297,6 +300,11 @@ static int mtk_pcie_startup_port(struct mtk_pcie_port *port)
 	val &= ~PCIE_INTX_ENABLE;
 	writel_relaxed(val, port->base + PCIE_INT_ENABLE_REG);
 
+	/* Disable DVFSRC voltage request */
+	val = readl_relaxed(port->base + PCIE_MISC_CTRL_REG);
+	val |= PCIE_DISABLE_DVFSRC_VLT_REQ;
+	writel_relaxed(val, port->base + PCIE_MISC_CTRL_REG);
+
 	/* Assert all reset signals */
 	val = readl_relaxed(port->base + PCIE_RST_CTRL_REG);
 	val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB;
-- 
2.18.0

From john.garry at huawei.com  Thu Aug 19 06:10:57 2021
From: john.garry at huawei.com (John Garry)
Date: Thu, 19 Aug 2021 14:10:57 +0100
Subject: [EXT] Re: [PATCH v2 2/4] perf/marvell: CN10k DDR performance
 monitor support
In-Reply-To: <CO6PR18MB4465D5490C1F6141DB454064E3C09@CO6PR18MB4465.namprd18.prod.outlook.com>
References: <20210810094307.29595-1-bbhushan2@marvell.com>
 <20210810094307.29595-3-bbhushan2@marvell.com>
 <c4e9c893-9130-7024-e24e-c63e232be4be@huawei.com>
 <CO6PR18MB4465D5490C1F6141DB454064E3C09@CO6PR18MB4465.namprd18.prod.outlook.com>
Message-ID: <72430f0f-c22f-0e8a-76db-99fc95d68b49@huawei.com>

On 19/08/2021 12:52, Bharat Bhushan wrote:
>> Is there anything to stop using adding COMPILE_TEST as a dependency?
>> This really helps build coverage testing for other archs
> Just keeping same as other drivers

I think then that may be something which could be improved for other 
drivers.

> 
>>> +	help
>>> +	  Enable perf support for Marvell DDR Performance monitoring
>>> +	  event on CN10K platform.
>>> +
>>>    endmenu
>>> diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
>>> index 5260b116c7da..ee1126219d8d 100644
>>> --- a/drivers/perf/Makefile
>>> +++ b/drivers/perf/Makefile
>>> @@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
>>>    obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
>>>    obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
>>>    obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
>>> +obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
>>> diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c
>> b/drivers/perf/marvell_cn10k_ddr_pmu.c
>>> new file mode 100644
>>> index 000000000000..8f9e3d1fcd8d
>>> --- /dev/null
>>> +++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
>>> @@ -0,0 +1,606 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/* Marvell CN10K DRAM Subsystem (DSS) Performance Monitor Driver
>>> + *
>>> + * Copyright (C) 2021 Marvell.
>>> + */
>>> +

...

>>> +/* Event counter value registers */
>>> +#define DDRC_PERF_CNT_VALUE_BASE		0x8080
>>> +#define DDRC_PERF_CNT_VALUE(n)	(DDRC_PERF_CNT_VALUE_BASE + 8 * (n))
>>> +
>>> +/* Fixed event counter enable/disable register */
>>> +#define DDRC_PERF_CNT_FREERUN_EN	0x80C0
>>> +#define DDRC_PERF_FREERUN_WRITE_EN	0x1
>>> +#define DDRC_PERF_FREERUN_READ_EN	0x2
>>> +
>>> +/* Fixed event counter control register */
>>> +#define DDRC_PERF_CNT_FREERUN_CTRL	0x80C8
>>> +#define DDRC_FREERUN_WRITE_CNT_CLR	0x1
>>> +#define DDRC_FREERUN_READ_CNT_CLR	0x2
>>> +
>>> +/* Fixed event counter value register */
>>> +#define DDRC_PERF_CNT_VALUE_WR_OP	0x80D0
>>> +#define DDRC_PERF_CNT_VALUE_RD_OP	0x80D8
>>> +#define DDRC_PERF_CNT_VALUE_OVERFLOW	BIT_ULL(48)
>>> +#define DDRC_PERF_CNT_MAX_VALUE		GENMASK_ULL(48, 0)
>> I assume all these macros are used...
> Yes, do you see any unused?

I didn't check

> 
>>> +
>>> +struct cn10k_ddr_pmu {
>>> +	struct pmu pmu;

Thanks,
john


From lorenzo.pieralisi at arm.com  Thu Aug 19 06:14:24 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 19 Aug 2021 14:14:24 +0100
Subject: [PATCH v9 0/8] Add SR-IOV support in PCIe Endpoint Core
In-Reply-To: <20210819123343.1951-1-kishon@ti.com>
References: <20210819123343.1951-1-kishon@ti.com>
Message-ID: <162937885162.23420.11118528020954705739.b4-ty@arm.com>

On Thu, 19 Aug 2021 18:03:35 +0530, Kishon Vijay Abraham I wrote:
> Patch series
> *) Adds support to add virtual functions to enable endpoint controller
>    which supports SR-IOV capability
> *) Add support in Cadence endpoint driver to configure virtual functions
> *) Enable pci_endpoint_test driver to create pci_device for virtual
>    functions
> 
> [...]

Applied to pci/endpoint, thanks!

[1/8] dt-bindings: PCI: pci-ep: Add binding to specify virtual function
      https://git.kernel.org/lpieralisi/pci/c/f00bfc6489
[2/8] PCI: endpoint: Add support to add virtual function in endpoint core
      https://git.kernel.org/lpieralisi/pci/c/1cf362e907
[3/8] PCI: endpoint: Add support to link a physical function to a virtual function
      https://git.kernel.org/lpieralisi/pci/c/101600e790
[4/8] PCI: endpoint: Add virtual function number in pci_epc ops
      https://git.kernel.org/lpieralisi/pci/c/53fd3cbe5e
[5/8] PCI: cadence: Simplify code to get register base address for configuring BAR
      https://git.kernel.org/lpieralisi/pci/c/0cf985d611
[6/8] PCI: cadence: Add support to configure virtual functions
      https://git.kernel.org/lpieralisi/pci/c/e19a0adf6e
[7/8] misc: pci_endpoint_test: Populate sriov_configure ops to configure SR-IOV device
      https://git.kernel.org/lpieralisi/pci/c/489b1f41e5
[8/8] Documentation: PCI: endpoint/pci-endpoint-cfs: Guide to use SR-IOV
      https://git.kernel.org/lpieralisi/pci/c/0c84f5bf3e

Thanks,
Lorenzo


From lorenzo.pieralisi at arm.com  Thu Aug 19 06:44:18 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 19 Aug 2021 14:44:18 +0100
Subject: [PATCH v3 0/5] PCI: Add support for J7200 and AM64
In-Reply-To: <a618e0af-d95f-8e25-5b86-eff7fd14d186@ti.com>
References: <20210811123336.31357-1-kishon@ti.com>
 <a618e0af-d95f-8e25-5b86-eff7fd14d186@ti.com>
Message-ID: <20210819134418.GB26966@lpieralisi>

On Thu, Aug 19, 2021 at 06:12:54PM +0530, Kishon Vijay Abraham I wrote:
> Hi Lorenzo,
> 
> On 11/08/21 6:03 pm, Kishon Vijay Abraham I wrote:
> > This series adds the compatible specific to J7200 and AM64 and
> > applies the erratas and configuration specific to them.
> > 
> > This series also includes Nadeem's patch that adds a quirk in
> > Cadence driver which is used by J7200 [1].
> > 
> > The DT binding for both J7200 and AM64 is already merged.
> > 
> > v1 of the patch series can be found at [2]
> > v2 of the patch series can be found at [3]
> 
> Gentle ping on this series.
> 
> I've dropped "misc: pci_endpoint_test: Do not request or allocate IRQs
> in probe" [A] from the previous version of the series which you had
> concerns with.
> 
> [A] -> http://lore.kernel.org/r/02c1ddb7-539e-20a0-1bef-e10e76922a0e at ti.com

Understood. The question is, how did you solve the issue that was
forcing you to have that patch in place in the updated series.

Thanks,
Lorenzo

> 
> Thanks
> Kishon
> 
> > 
> > Changes from v2:
> > 1) Drop the patch that does not request or allocate IRQs in probe for
> > J721E/AM654
> > 2) Fix other minor comments given by Lorenzo
> > 
> > Changes from v1:
> > 1) As suggested by Bjorn, used unsigned int :1, instead of bool for
> > structure members
> > 2) Removed using unnecessary local variables and also fixed some
> > code alignment
> > 
> > [1] -> https://lore.kernel.org/r/20210528155626.21793-1-nadeem at cadence.com
> > [2] -> https://lore.kernel.org/r/20210706105035.9915-1-kishon at ti.com
> > [3] -> https://lore.kernel.org/r/20210803074932.19820-1-kishon at ti.com
> > 
> > Kishon Vijay Abraham I (4):
> >   PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
> >   PCI: j721e: Add PCIe support for J7200
> >   PCI: j721e: Add PCIe support for AM64
> >   misc: pci_endpoint_test: Add deviceID for AM64 and J7200
> > 
> > Nadeem Athani (1):
> >   PCI: cadence: Add quirk flag to set minimum delay in LTSSM
> >     Detect.Quiet state
> > 
> >  drivers/misc/pci_endpoint_test.c              |  8 +++
> >  drivers/pci/controller/cadence/pci-j721e.c    | 61 +++++++++++++++++--
> >  .../pci/controller/cadence/pcie-cadence-ep.c  |  4 ++
> >  .../controller/cadence/pcie-cadence-host.c    |  3 +
> >  drivers/pci/controller/cadence/pcie-cadence.c | 16 +++++
> >  drivers/pci/controller/cadence/pcie-cadence.h | 17 +++++-
> >  6 files changed, 103 insertions(+), 6 deletions(-)
> > 


From broonie at kernel.org  Thu Aug 19 06:42:39 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 14:42:39 +0100
Subject: [PATCH v1 0/6] kselftest/arm64: SVE signal handling tests
Message-ID: <20210819134245.13935-1-broonie@kernel.org>

Currently we have no real tests for SVE signal handling (though the
stress test does trigger the code paths as it regularly sends signals to
the test processes).  Add some basic coverage, this is very much
incomplete but it's more coverage than we currently have, a TODO file is
included with some omissions that occurred to me.

Mark Brown (6):
  kselftest/arm64: signal: Add SVE to the set of features we can check
    for
  kselftest/arm64: signal: Support signal frames with SVE register data
  kselftest/arm64: signal: Check SVE signal frame shows expected vector
    length
  kselftest/arm64: signal: Verify that signals can't change the SVE
    vector length
  kselftest/arm64: signal: Add test case for SVE register state in
    signals
  kselftest/arm64: signal: Add a TODO list for signal handling tests

 .../testing/selftests/arm64/signal/.gitignore |   1 +
 .../selftests/arm64/signal/test_signals.h     |   2 +
 .../arm64/signal/test_signals_utils.c         |   3 +
 .../selftests/arm64/signal/testcases/TODO     |   2 +
 .../testcases/fake_sigreturn_sve_change_vl.c  |  92 +++++++++++++
 .../arm64/signal/testcases/sve_regs.c         | 126 ++++++++++++++++++
 .../selftests/arm64/signal/testcases/sve_vl.c |  68 ++++++++++
 .../arm64/signal/testcases/testcases.c        |  34 ++++-
 8 files changed, 325 insertions(+), 3 deletions(-)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/TODO
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sve_regs.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sve_vl.c


base-commit: ff1176468d368232b684f75e82563369208bc371
-- 
2.20.1



From broonie at kernel.org  Thu Aug 19 06:42:40 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 14:42:40 +0100
Subject: [PATCH v1 1/6] kselftest/arm64: signal: Add SVE to the set of
 features we can check for
In-Reply-To: <20210819134245.13935-1-broonie@kernel.org>
References: <20210819134245.13935-1-broonie@kernel.org>
Message-ID: <20210819134245.13935-2-broonie@kernel.org>

Allow testcases for SVE signal handling to flag the dependency and be
skipped on systems without SVE support.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/signal/test_signals.h       | 2 ++
 tools/testing/selftests/arm64/signal/test_signals_utils.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index f96baf1cef1a..ebe8694dbef0 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -33,10 +33,12 @@
  */
 enum {
 	FSSBS_BIT,
+	FSVE_BIT,
 	FMAX_END
 };
 
 #define FEAT_SSBS		(1UL << FSSBS_BIT)
+#define FEAT_SVE		(1UL << FSVE_BIT)
 
 /*
  * A descriptor used to describe and configure a test case.
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 2de6e5ed5e25..6836510a522f 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -26,6 +26,7 @@ static int sig_copyctx = SIGTRAP;
 
 static char const *const feats_names[FMAX_END] = {
 	" SSBS ",
+	" SVE ",
 };
 
 #define MAX_FEATS_SZ	128
@@ -263,6 +264,8 @@ int test_init(struct tdescr *td)
 		 */
 		if (getauxval(AT_HWCAP) & HWCAP_SSBS)
 			td->feats_supported |= FEAT_SSBS;
+		if (getauxval(AT_HWCAP) & HWCAP_SVE)
+			td->feats_supported |= FEAT_SVE;
 		if (feats_ok(td))
 			fprintf(stderr,
 				"Required Features: [%s] supported\n",
-- 
2.20.1



From broonie at kernel.org  Thu Aug 19 06:42:41 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 14:42:41 +0100
Subject: [PATCH v1 2/6] kselftest/arm64: signal: Support signal frames with
 SVE register data
In-Reply-To: <20210819134245.13935-1-broonie@kernel.org>
References: <20210819134245.13935-1-broonie@kernel.org>
Message-ID: <20210819134245.13935-3-broonie@kernel.org>

A signal frame with SVE may validly either be a bare struct sve_context or
a struct sve_context followed by vector length dependent register data.
Support either in the generic helpers for the signal tests, and while we're
at it validate the SVE vector length reported.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../arm64/signal/testcases/testcases.c        | 34 +++++++++++++++++--
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
index 61ebcdf63831..8c2a57fc2f9c 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.c
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
@@ -50,12 +50,38 @@ bool validate_extra_context(struct extra_context *extra, char **err)
 	return true;
 }
 
+bool validate_sve_context(struct sve_context *sve, char **err)
+{
+	/* Size will be rounded up to a multiple of 16 bytes */
+	size_t regs_size
+		= ((SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve->vl)) + 15) / 16) * 16;
+
+	if (!sve || !err)
+		return false;
+
+	/* Either a bare sve_context or a sve_context followed by regs data */
+	if ((sve->head.size != sizeof(struct sve_context)) &&
+	    (sve->head.size != regs_size)) {
+		*err = "bad size for SVE context";
+		return false;
+	}
+
+	if (!sve_vl_valid(sve->vl)) {
+		*err = "SVE VL invalid";
+
+		return false;
+	}
+
+	return true;
+}
+
 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 {
 	bool terminated = false;
 	size_t offs = 0;
 	int flags = 0;
 	struct extra_context *extra = NULL;
+	struct sve_context *sve = NULL;
 	struct _aarch64_ctx *head =
 		(struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
 
@@ -90,9 +116,8 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 		case SVE_MAGIC:
 			if (flags & SVE_CTX)
 				*err = "Multiple SVE_MAGIC";
-			else if (head->size !=
-				 sizeof(struct sve_context))
-				*err = "Bad size for sve_context";
+			/* Size is validated in validate_sve_context() */
+			sve = (struct sve_context *)head;
 			flags |= SVE_CTX;
 			break;
 		case EXTRA_MAGIC:
@@ -137,6 +162,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 		if (flags & EXTRA_CTX)
 			if (!validate_extra_context(extra, err))
 				return false;
+		if (flags & SVE_CTX)
+			if (!validate_sve_context(sve, err))
+				return false;
 
 		head = GET_RESV_NEXT_HEAD(head);
 	}
-- 
2.20.1



From broonie at kernel.org  Thu Aug 19 06:42:42 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 14:42:42 +0100
Subject: [PATCH v1 3/6] kselftest/arm64: signal: Check SVE signal frame shows
 expected vector length
In-Reply-To: <20210819134245.13935-1-broonie@kernel.org>
References: <20210819134245.13935-1-broonie@kernel.org>
Message-ID: <20210819134245.13935-4-broonie@kernel.org>

As a basic check that the SVE signal frame is being set up correctly
verify that the vector length in the signal frame is the vector length
that the process has.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../testing/selftests/arm64/signal/.gitignore |  1 +
 .../selftests/arm64/signal/testcases/sve_vl.c | 68 +++++++++++++++++++
 2 files changed, 69 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sve_vl.c

diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
index 78c902045ca7..c1742755abb9 100644
--- a/tools/testing/selftests/arm64/signal/.gitignore
+++ b/tools/testing/selftests/arm64/signal/.gitignore
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 mangle_*
 fake_sigreturn_*
+sve_*
 !*.[ch]
diff --git a/tools/testing/selftests/arm64/signal/testcases/sve_vl.c b/tools/testing/selftests/arm64/signal/testcases/sve_vl.c
new file mode 100644
index 000000000000..92904653add1
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sve_vl.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Check that the SVE vector length reported in signal contexts is the
+ * expected one.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+unsigned int vl;
+
+static bool get_sve_vl(struct tdescr *td)
+{
+	int ret = prctl(PR_SVE_GET_VL);
+	if (ret == -1)
+		return false;
+
+	vl = ret;
+
+	return true;
+}
+
+static int sve_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *sve;
+
+	/* Get a signal context which should have a SVE frame in it */
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+	sve = (struct sve_context *)head;
+
+	if (sve->vl != vl) {
+		fprintf(stderr, "sigframe VL %u, expected %u\n",
+			sve->vl, vl);
+		return 1;
+	} else {
+		fprintf(stderr, "got expected VL %u\n", vl);
+	}
+
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "SVE VL",
+	.descr = "Check that we get the right SVE VL reported",
+	.feats_required = FEAT_SVE,
+	.timeout = 3,
+	.init = get_sve_vl,
+	.run = sve_vl,
+};
-- 
2.20.1



From broonie at kernel.org  Thu Aug 19 06:42:43 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 14:42:43 +0100
Subject: [PATCH v1 4/6] kselftest/arm64: signal: Verify that signals can't
 change the SVE vector length
In-Reply-To: <20210819134245.13935-1-broonie@kernel.org>
References: <20210819134245.13935-1-broonie@kernel.org>
Message-ID: <20210819134245.13935-5-broonie@kernel.org>

We do not support changing the SVE vector length as part of signal return,
verify that this is the case if the system supports multiple vector lengths.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../testcases/fake_sigreturn_sve_change_vl.c  | 92 +++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c

diff --git a/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c b/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c
new file mode 100644
index 000000000000..bb50b5adbf10
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Attempt to change the SVE vector length in a signal hander, this is not
+ * supported and is expected to segfault.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+static unsigned int vls[SVE_VQ_MAX];
+unsigned int nvls = 0;
+
+static bool sve_get_vls(struct tdescr *td)
+{
+	int vq, vl;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SVE_SET_VL, vq * 16);
+		if (vl == -1)
+			return false;
+
+		vl &= PR_SVE_VL_LEN_MASK;
+
+		/* Skip missing VLs */
+		vq = sve_vq_from_vl(vl);
+
+		vls[nvls++] = vl;
+	}
+
+	/* We need at least two VLs */
+	if (nvls < 2) {
+		fprintf(stderr, "Only %d VL supported\n", nvls);
+		return false;
+	}
+
+	return true;
+}
+
+static int fake_sigreturn_sve_change_vl(struct tdescr *td,
+					siginfo_t *si, ucontext_t *uc)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *sve;
+
+	/* Get a signal context with a SVE frame in it */
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+
+	if (head->size != sizeof(struct sve_context)) {
+		fprintf(stderr, "SVE register state active, skipping\n");
+		return 1;
+	}
+
+	sve = (struct sve_context *)head;
+
+	/* No changes are supported; init left us at minimum VL so go to max */
+	fprintf(stderr, "Attempting to change VL from %d to %d\n",
+		sve->vl, vls[0]);
+	sve->vl = vls[0];
+
+	fake_sigreturn(&sf, sizeof(sf), 0);
+
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "FAKE_SIGRETURN_SVE_CHANGE",
+	.descr = "Attempt to change SVE VL",
+	.feats_required = FEAT_SVE,
+	.sig_ok = SIGSEGV,
+	.timeout = 3,
+	.init = sve_get_vls,
+	.run = fake_sigreturn_sve_change_vl,
+};
-- 
2.20.1



From broonie at kernel.org  Thu Aug 19 06:42:44 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 14:42:44 +0100
Subject: [PATCH v1 5/6] kselftest/arm64: signal: Add test case for SVE
 register state in signals
In-Reply-To: <20210819134245.13935-1-broonie@kernel.org>
References: <20210819134245.13935-1-broonie@kernel.org>
Message-ID: <20210819134245.13935-6-broonie@kernel.org>

Currently this doesn't actually verify that the register contents do the
right thing, it just verifes that a SVE context with appropriate size
appears.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../arm64/signal/testcases/sve_regs.c         | 126 ++++++++++++++++++
 1 file changed, 126 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sve_regs.c

diff --git a/tools/testing/selftests/arm64/signal/testcases/sve_regs.c b/tools/testing/selftests/arm64/signal/testcases/sve_regs.c
new file mode 100644
index 000000000000..4b2418aa08a9
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sve_regs.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that the SVE register context in signal frames is set up as
+ * expected.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+static unsigned int vls[SVE_VQ_MAX];
+unsigned int nvls = 0;
+
+static bool sve_get_vls(struct tdescr *td)
+{
+	int vq, vl;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SVE_SET_VL, vq * 16);
+		if (vl == -1)
+			return false;
+
+		vl &= PR_SVE_VL_LEN_MASK;
+
+		/* Skip missing VLs */
+		vq = sve_vq_from_vl(vl);
+
+		vls[nvls++] = vl;
+	}
+
+	/* We need at least one VL */
+	if (nvls < 1) {
+		fprintf(stderr, "Only %d VL supported\n", nvls);
+		return false;
+	}
+
+	return true;
+}
+
+static void setup_sve_regs(void)
+{
+	/* RDVL x16, #1 so we should have SVE regs; real data is TODO */
+	asm volatile(".inst 0x04bf5030" : : : "x16" );
+}
+
+static int do_one_sve_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc,
+			 unsigned int vl)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *sve;
+
+	fprintf(stderr, "Testing VL %d\n", vl);
+
+	if (prctl(PR_SVE_SET_VL, vl) == -1) {
+		fprintf(stderr, "Failed to set VL\n");
+		return 1;
+	}
+
+	/*
+	 * Get a signal context which should have a SVE frame and registers
+	 * in it.
+	 */
+	setup_sve_regs();
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+
+	sve = (struct sve_context *)head;
+	if (sve->vl != vl) {
+		fprintf(stderr, "Got VL %d, expected %d\n", sve->vl, vl);
+		return 1;
+	}
+
+	/* The actual size validation is done in get_current_context() */
+	fprintf(stderr, "Got expected size %u and VL %d\n",
+		head->size, sve->vl);
+
+	return 0;
+}
+
+static int sve_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	int i;
+
+	for (i = 0; i < nvls; i++) {
+		/*
+		 * TODO: the signal test helpers can't currently cope
+		 * with signal frames bigger than struct sigcontext,
+		 * skip VLs that will trigger that.
+		 */
+		if (vls[i] > 64)
+			continue;
+
+		if (do_one_sve_vl(td, si, uc, vls[i]))
+			return 1;
+	}
+
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "SVE registers",
+	.descr = "Check that we get the right SVE registers reported",
+	.feats_required = FEAT_SVE,
+	.timeout = 3,
+	.init = sve_get_vls,
+	.run = sve_regs,
+};
-- 
2.20.1



From broonie at kernel.org  Thu Aug 19 06:42:45 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 14:42:45 +0100
Subject: [PATCH v1 6/6] kselftest/arm64: signal: Add a TODO list for signal
 handling tests
In-Reply-To: <20210819134245.13935-1-broonie@kernel.org>
References: <20210819134245.13935-1-broonie@kernel.org>
Message-ID: <20210819134245.13935-7-broonie@kernel.org>

Note down a few gaps in our coverage.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/signal/testcases/TODO | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/TODO

diff --git a/tools/testing/selftests/arm64/signal/testcases/TODO b/tools/testing/selftests/arm64/signal/testcases/TODO
new file mode 100644
index 000000000000..110ff9fd195d
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/TODO
@@ -0,0 +1,2 @@
+- Validate that register contents are saved and restored as expected.
+- Support and validate extra_context.
-- 
2.20.1



From l.stach at pengutronix.de  Thu Aug 19 06:45:40 2021
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 19 Aug 2021 15:45:40 +0200
Subject: [PATCH] ARM: dts: imx: add minor fix to pass schema dtb check
In-Reply-To: <1629277950-7230-1-git-send-email-haibo.chen@nxp.com>
References: <1629277950-7230-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <72e1194e10ccb4f87aed96265114f0963e805092.camel@pengutronix.de>

Am Mittwoch, dem 18.08.2021 um 17:12 +0800 schrieb haibo.chen at nxp.com:
> From: Haibo Chen <haibo.chen at nxp.com>
> 
> Add some fix to pass schema dtb check for fsl-imx-esdhc.yaml

Nack.

As far as I can see the controller is functionally compatible to the
fallback compatibles (in some cases with reduced functionality, like no
HS200) support. Removing those fallback compatibles will break older
kernels that don't have support for the new, preferred compatibles and
other software like bootloaders that might match to the fallback
compatibles, as they don't make use of the extended functionality
anyways.

Please fix the schema to accept the valid fallback compatibles.

Regards,
Lucas

> 
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> ---
>  arch/arm/boot/dts/imx50.dtsi   | 8 ++++----
>  arch/arm/boot/dts/imx6sl.dtsi  | 8 ++++----
>  arch/arm/boot/dts/imx6sll.dtsi | 6 +++---
>  arch/arm/boot/dts/imx6sx.dtsi  | 8 ++++----
>  arch/arm/boot/dts/imx6ul.dtsi  | 4 ++--
>  arch/arm/boot/dts/imx6ull.dtsi | 4 ++--
>  arch/arm/boot/dts/imx7s.dtsi   | 6 +++---
>  arch/arm/boot/dts/imx7ulp.dtsi | 4 ++--
>  arch/arm/boot/dts/vfxxx.dtsi   | 4 ++--
>  9 files changed, 26 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
> index a969f335b240..a1814f10f7f0 100644
> --- a/arch/arm/boot/dts/imx50.dtsi
> +++ b/arch/arm/boot/dts/imx50.dtsi
> @@ -116,7 +116,7 @@
>  				ranges;
>  
>  				esdhc1: mmc at 50004000 {
> -					compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc";
> +					compatible = "fsl,imx53-esdhc";
>  					reg = <0x50004000 0x4000>;
>  					interrupts = <1>;
>  					clocks = <&clks IMX5_CLK_ESDHC1_IPG_GATE>,
> @@ -128,7 +128,7 @@
>  				};
>  
>  				esdhc2: mmc at 50008000 {
> -					compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc";
> +					compatible = "fsl,imx53-esdhc";
>  					reg = <0x50008000 0x4000>;
>  					interrupts = <2>;
>  					clocks = <&clks IMX5_CLK_ESDHC2_IPG_GATE>,
> @@ -177,7 +177,7 @@
>  				};
>  
>  				esdhc3: mmc at 50020000 {
> -					compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc";
> +					compatible = "fsl,imx53-esdhc";
>  					reg = <0x50020000 0x4000>;
>  					interrupts = <3>;
>  					clocks = <&clks IMX5_CLK_ESDHC3_IPG_GATE>,
> @@ -189,7 +189,7 @@
>  				};
>  
>  				esdhc4: mmc at 50024000 {
> -					compatible = "fsl,imx50-esdhc", "fsl,imx53-esdhc";
> +					compatible = "fsl,imx53-esdhc";
>  					reg = <0x50024000 0x4000>;
>  					interrupts = <4>;
>  					clocks = <&clks IMX5_CLK_ESDHC4_IPG_GATE>,
> diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
> index 997b96c1c47b..e40e017b6f38 100644
> --- a/arch/arm/boot/dts/imx6sl.dtsi
> +++ b/arch/arm/boot/dts/imx6sl.dtsi
> @@ -858,7 +858,7 @@
>  			};
>  
>  			usdhc1: mmc at 2190000 {
> -				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
> +				compatible = "fsl,imx6sl-usdhc";
>  				reg = <0x02190000 0x4000>;
>  				interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SL_CLK_USDHC1>,
> @@ -870,7 +870,7 @@
>  			};
>  
>  			usdhc2: mmc at 2194000 {
> -				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
> +				compatible = "fsl,imx6sl-usdhc";
>  				reg = <0x02194000 0x4000>;
>  				interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SL_CLK_USDHC2>,
> @@ -882,7 +882,7 @@
>  			};
>  
>  			usdhc3: mmc at 2198000 {
> -				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
> +				compatible = "fsl,imx6sl-usdhc";
>  				reg = <0x02198000 0x4000>;
>  				interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SL_CLK_USDHC3>,
> @@ -894,7 +894,7 @@
>  			};
>  
>  			usdhc4: mmc at 219c000 {
> -				compatible = "fsl,imx6sl-usdhc", "fsl,imx6q-usdhc";
> +				compatible = "fsl,imx6sl-usdhc";
>  				reg = <0x0219c000 0x4000>;
>  				interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SL_CLK_USDHC4>,
> diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
> index 04f8d637a501..82b248353386 100644
> --- a/arch/arm/boot/dts/imx6sll.dtsi
> +++ b/arch/arm/boot/dts/imx6sll.dtsi
> @@ -711,7 +711,7 @@
>  			};
>  
>  			usdhc1: mmc at 2190000 {
> -				compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
> +				compatible = "fsl,imx6sll-usdhc";
>  				reg = <0x02190000 0x4000>;
>  				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SLL_CLK_USDHC1>,
> @@ -725,7 +725,7 @@
>  			};
>  
>  			usdhc2: mmc at 2194000 {
> -				compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
> +				compatible = "fsl,imx6sll-usdhc";
>  				reg = <0x02194000 0x4000>;
>  				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SLL_CLK_USDHC2>,
> @@ -739,7 +739,7 @@
>  			};
>  
>  			usdhc3: mmc at 2198000 {
> -				compatible = "fsl,imx6sll-usdhc", "fsl,imx6sx-usdhc";
> +				compatible = "fsl,imx6sll-usdhc";
>  				reg = <0x02198000 0x4000>;
>  				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SLL_CLK_USDHC3>,
> diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
> index 8516730778df..acab73c932c1 100644
> --- a/arch/arm/boot/dts/imx6sx.dtsi
> +++ b/arch/arm/boot/dts/imx6sx.dtsi
> @@ -967,7 +967,7 @@
>  			};
>  
>  			usdhc1: mmc at 2190000 {
> -				compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
> +				compatible = "fsl,imx6sx-usdhc";
>  				reg = <0x02190000 0x4000>;
>  				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SX_CLK_USDHC1>,
> @@ -979,7 +979,7 @@
>  			};
>  
>  			usdhc2: mmc at 2194000 {
> -				compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
> +				compatible = "fsl,imx6sx-usdhc";
>  				reg = <0x02194000 0x4000>;
>  				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SX_CLK_USDHC2>,
> @@ -991,7 +991,7 @@
>  			};
>  
>  			usdhc3: mmc at 2198000 {
> -				compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
> +				compatible = "fsl,imx6sx-usdhc";
>  				reg = <0x02198000 0x4000>;
>  				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SX_CLK_USDHC3>,
> @@ -1003,7 +1003,7 @@
>  			};
>  
>  			usdhc4: mmc at 219c000 {
> -				compatible = "fsl,imx6sx-usdhc", "fsl,imx6sl-usdhc";
> +				compatible = "fsl,imx6sx-usdhc";
>  				reg = <0x0219c000 0x4000>;
>  				interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6SX_CLK_USDHC4>,
> diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
> index afeec01f6522..c066d85b2c0a 100644
> --- a/arch/arm/boot/dts/imx6ul.dtsi
> +++ b/arch/arm/boot/dts/imx6ul.dtsi
> @@ -891,7 +891,7 @@
>  			};
>  
>  			usdhc1: mmc at 2190000 {
> -				compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc";
> +				compatible = "fsl,imx6sx-usdhc";
>  				reg = <0x02190000 0x4000>;
>  				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6UL_CLK_USDHC1>,
> @@ -905,7 +905,7 @@
>  			};
>  
>  			usdhc2: mmc at 2194000 {
> -				compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc";
> +				compatible = "fsl,imx6sx-usdhc";
>  				reg = <0x02194000 0x4000>;
>  				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX6UL_CLK_USDHC2>,
> diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
> index 9bf67490ac49..8b1ed3bc7393 100644
> --- a/arch/arm/boot/dts/imx6ull.dtsi
> +++ b/arch/arm/boot/dts/imx6ull.dtsi
> @@ -42,11 +42,11 @@
>  };
>  
>  &usdhc1 {
> -	compatible = "fsl,imx6ull-usdhc", "fsl,imx6sx-usdhc";
> +	compatible = "fsl,imx6ull-usdhc";
>  };
>  
>  &usdhc2 {
> -	compatible = "fsl,imx6ull-usdhc", "fsl,imx6sx-usdhc";
> +	compatible = "fsl,imx6ull-usdhc";
>  };
>  
>  / {
> diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
> index 1843fc053870..075f8e5c0579 100644
> --- a/arch/arm/boot/dts/imx7s.dtsi
> +++ b/arch/arm/boot/dts/imx7s.dtsi
> @@ -1158,7 +1158,7 @@
>  			};
>  
>  			usdhc1: mmc at 30b40000 {
> -				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
> +				compatible = "fsl,imx7d-usdhc";
>  				reg = <0x30b40000 0x10000>;
>  				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
> @@ -1170,7 +1170,7 @@
>  			};
>  
>  			usdhc2: mmc at 30b50000 {
> -				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
> +				compatible = "fsl,imx7d-usdhc";
>  				reg = <0x30b50000 0x10000>;
>  				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
> @@ -1182,7 +1182,7 @@
>  			};
>  
>  			usdhc3: mmc at 30b60000 {
> -				compatible = "fsl,imx7d-usdhc", "fsl,imx6sl-usdhc";
> +				compatible = "fsl,imx7d-usdhc";
>  				reg = <0x30b60000 0x10000>;
>  				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
>  				clocks = <&clks IMX7D_IPG_ROOT_CLK>,
> diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi
> index b7ea37ad4e55..456c3f5f393c 100644
> --- a/arch/arm/boot/dts/imx7ulp.dtsi
> +++ b/arch/arm/boot/dts/imx7ulp.dtsi
> @@ -216,7 +216,7 @@
>  		};
>  
>  		usdhc0: mmc at 40370000 {
> -			compatible = "fsl,imx7ulp-usdhc", "fsl,imx6sx-usdhc";
> +			compatible = "fsl,imx7ulp-usdhc";
>  			reg = <0x40370000 0x10000>;
>  			interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
>  			clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>,
> @@ -230,7 +230,7 @@
>  		};
>  
>  		usdhc1: mmc at 40380000 {
> -			compatible = "fsl,imx7ulp-usdhc", "fsl,imx6sx-usdhc";
> +			compatible = "fsl,imx7ulp-usdhc";
>  			reg = <0x40380000 0x10000>;
>  			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
>  			clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>,
> diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
> index d53f9c9db8bf..c5651f23b3fd 100644
> --- a/arch/arm/boot/dts/vfxxx.dtsi
> +++ b/arch/arm/boot/dts/vfxxx.dtsi
> @@ -574,7 +574,7 @@
>  							<20000000>;
>  			};
>  
> -			esdhc0: esdhc at 400b1000 {
> +			esdhc0: mmc at 400b1000 {
>  				compatible = "fsl,imx53-esdhc";
>  				reg = <0x400b1000 0x1000>;
>  				interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
> @@ -585,7 +585,7 @@
>  				status = "disabled";
>  			};
>  
> -			esdhc1: esdhc at 400b2000 {
> +			esdhc1: mmc at 400b2000 {
>  				compatible = "fsl,imx53-esdhc";
>  				reg = <0x400b2000 0x1000>;
>  				interrupts = <28 IRQ_TYPE_LEVEL_HIGH>;




From frattaroli.nicolas at gmail.com  Thu Aug 19 06:52:55 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Thu, 19 Aug 2021 15:52:55 +0200
Subject: [PATCH 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <deb50900-fcfd-23d0-ab8a-0e64b2abb063@arm.com>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
 <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
 <deb50900-fcfd-23d0-ab8a-0e64b2abb063@arm.com>
Message-ID: <2412250.zZEsDtmPgG@archbook>

On Donnerstag, 19. August 2021 14:08:36 CEST Robin Murphy wrote:
> On 2021-08-17 11:11, Nicolas Frattaroli wrote:
> > +  rockchip,trcm-sync:
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    description:
> > +      Which lrck/bclk clocks each direction will sync to. You should use
> > the +      constants in <dt-bindings/sound/rockchip,i2s-tdm.h>
> > +    oneOf:
> > +      - const: 0
> > +        description:
> > +          RK_TRCM_TXRX. Use both the TX and the RX clock for TX and RX.
> > +      - const: 1
> > +        description:
> > +          RK_TRCM_TX. Use only the TX clock for TX and RX.
> > +      - const: 2
> > +        description:
> > +          RK_TRCM_RX. Use only the RX clock for TX and RX.
> 
> I wonder if that might make sense to have boolean properties to describe
> the latter two cases (which would effectively be mutually-exclusive),
> rather than a magic number? Or possibly even just make the respective
> clocks optional, if this is something which would be done per-SoC rather
> than per-board?
> 

>From what I know from downstream vendor device trees, these are per
board, not for the SoC as a whole. There are I2S/TDM controllers on the
SoC which I think are hardwired to certain other IP blocks, such as I2S0
being connected to HDMI, but I2S1 can be routed outside of the SoC where
these come into play I believe.

As for making them boolean properties, I'd rather not. If I were to make it
two mutually exclusive booleans, this would result in 4 possible states
rather than 3, and require complexity to check it both in the schema and
in the probe function. Like this, I can get away with a switch case that
has a fallthrough, and a list of consts in the schema.

> > +
> > +  "#sound-dai-cells":
> > +    const: 0
> > +
> > +  rockchip,no-dmaengine:
> > +    description:
> > +      If present, driver will not register a pcm dmaengine, only the dai.
> > +      If the dai is part of multi-dais, the property should be present.
> > +    type: boolean
> 
> That sounds a lot more like a policy decision specific to the Linux
> driver implementation, than something which really belongs in DT as a
> description of the platform.

I agree. Should I be refactoring this into a module parameter or
something along those lines? I'm unsure of where this goes.

> 
> > +
> > +  rockchip,playback-only:
> > +    description: Specify that the controller only has playback
> > capability.
> > +    type: boolean
> > +
> > +  rockchip,capture-only:
> > +    description: Specify that the controller only has capture capability.
> > +    type: boolean
> 
> Could those be inferred from the compatible string, or are there cases
> where you have multiple instances of the IP block in different
> configurations within the same SoC? (Or if it's merely reflecting
> whether the respective interface is actually wired up externally, could
> that be inferred from the attached codec?)
> 
> Robin.
> 

They can't be inferred from the SoC because there are indeed multiple
instances of this IP block in different configurations on the same SoC.
The RK3566 and RK3568 have four in total, of two different categories,
each being able to be configured for a different format (though the
number of channels and available formats vary for the two categories,
one group only supports I2S and PCM with two channels)

The particular configuration may even vary per-board; an I2S/TDM
controller may be connected to an external codec which does not
support capture, whereas on another board it may be connected to
one that does.

As an example, if I understand it correctly, I2S3 on the RK3566 and
RK3568 can do 2 channels RX and TX in I2S mode, but only 2 channels
either RX or TX in PCM mode, but I'm unsure of the language in the
(still not public) documentation I have.

Regards,
Nicolas Frattaroli




From nicolas.dufresne at collabora.com  Thu Aug 19 07:00:09 2021
From: nicolas.dufresne at collabora.com (Nicolas Dufresne)
Date: Thu, 19 Aug 2021 10:00:09 -0400
Subject: [PATCH] media: cedrus: Fix SUNXI tile size calculation
Message-ID: <20210819140009.158156-1-nicolas.dufresne@collabora.com>

Tiled formats requires full rows being allocated (even for Chroma
planes). When the number of Luma tiles is odd, we need to round up
to twice the tile width in order to roundup the number of Chroma
tiles.

This was notice with a crash running BA1_FT_C compliance test using
sunxi tiles using GStreamer. Cedrus driver would allocate 9 rows for
Luma, but only 4.5 rows for Chroma, causing userspace to crash.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/staging/media/sunxi/cedrus/cedrus_video.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
index 32c13ecb22d8..a8168ac2fbd0 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
@@ -135,7 +135,7 @@ void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
 		sizeimage = bytesperline * height;
 
 		/* Chroma plane size. */
-		sizeimage += bytesperline * height / 2;
+		sizeimage += bytesperline * ALIGN(height, 64) / 2;
 
 		break;
 
-- 
2.31.1



From marcel at ziswiler.com  Thu Aug 19 07:03:42 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:03:42 +0200
Subject: [PATCH v1 4/7] ARM: imx_v6_v7_defconfig: rebuild default configuration
In-Reply-To: <20210819140345.357167-1-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
Message-ID: <20210819140345.357167-5-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Run "make imx_v6_v7_defconfig; make savedefconfig" to rebuild imx_v6_v7_defconfig.

This dropped the following nowadays obsolete configuration options:

CONFIG_MTD_M25P80=y (got integrated into MTD_SPI_NOR)
CONFIG_CS89x0=y (selected by CS89x0_PLATFORM)
CONFIG_SMSC_PHY=y (selected by USB_NET_SMSC95XX)
CONFIG_GPIO_MC9S08DZ60=y (depends on MACH_MX35_3DS)
CONFIG_REGULATOR=y (selected by various stuff)
CONFIG_MEDIA_CAMERA_SUPPORT=y (defaults to on if MEDIA_CAMERA)
CONFIG_MEDIA_CONTROLLER=y (selected by various stuff)
CONFIG_VIDEO_V4L2_SUBDEV_API=y (selected by various stuff)
CONFIG_SND_SOC_PHYCORE_AC97=y
CONFIG_SND_SOC_IMX_MC13783=y
CONFIG_USB_EHCI_MXC=y
CONFIG_USB_FSL_USB2=y

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/configs/imx_v6_v7_defconfig | 38 ++++++++--------------------
 1 file changed, 11 insertions(+), 27 deletions(-)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 90d6a5cf254e0..21803cd2d1ba7 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -28,9 +28,6 @@ CONFIG_SOC_IMX6UL=y
 CONFIG_SOC_IMX7D=y
 CONFIG_SOC_IMX7ULP=y
 CONFIG_SOC_VF610=y
-CONFIG_PCI=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_IMX6=y
 CONFIG_SMP=y
 CONFIG_ARM_PSCI=y
 CONFIG_HIGHMEM=y
@@ -58,7 +55,6 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -66,9 +62,6 @@ CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_NETFILTER=y
 CONFIG_CAN=y
 CONFIG_CAN_FLEXCAN=y
@@ -81,12 +74,14 @@ CONFIG_CFG80211_WEXT=y
 CONFIG_MAC80211=y
 CONFIG_RFKILL=y
 CONFIG_RFKILL_INPUT=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_IMX6=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 CONFIG_FW_LOADER_USER_HELPER=y
 CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
-CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_IMX_WEIM=y
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
@@ -100,14 +95,12 @@ CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_SST25L=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_NAND_VF610_NFC=y
 CONFIG_MTD_NAND_MXC=y
 CONFIG_MTD_SPI_NOR=y
-CONFIG_SPI_FSL_QUADSPI=y
 CONFIG_MTD_UBI=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_BLOCK=y
@@ -118,6 +111,7 @@ CONFIG_EEPROM_AT24=y
 CONFIG_EEPROM_AT25=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
+# CONFIG_BLK_DEV_BSG is not set
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
@@ -127,7 +121,6 @@ CONFIG_AHCI_IMX=y
 CONFIG_PATA_IMX=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
-CONFIG_CS89x0=y
 CONFIG_CS89x0_PLATFORM=y
 # CONFIG_NET_VENDOR_FARADAY is not set
 # CONFIG_NET_VENDOR_INTEL is not set
@@ -140,9 +133,8 @@ CONFIG_SMC91X=y
 CONFIG_SMC911X=y
 CONFIG_SMSC911X=y
 # CONFIG_NET_VENDOR_STMICRO is not set
-CONFIG_AT803X_PHY=y
 CONFIG_MICREL_PHY=y
-CONFIG_SMSC_PHY=y
+CONFIG_AT803X_PHY=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=y
@@ -205,6 +197,7 @@ CONFIG_I2C_ALGOPCA=m
 CONFIG_I2C_GPIO=y
 CONFIG_I2C_IMX=y
 CONFIG_SPI=y
+CONFIG_SPI_FSL_QUADSPI=y
 CONFIG_SPI_GPIO=y
 CONFIG_SPI_IMX=y
 CONFIG_SPI_FSL_DSPI=y
@@ -213,14 +206,13 @@ CONFIG_PINCTRL_IMX8MN=y
 CONFIG_PINCTRL_IMX8MP=y
 CONFIG_PINCTRL_IMX8MQ=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MXC=y
 CONFIG_GPIO_SIOX=m
 CONFIG_GPIO_MAX732X=y
-CONFIG_GPIO_MC9S08DZ60=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCF857X=y
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_74X164=y
-CONFIG_GPIO_MXC=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_SYSCON=y
 CONFIG_POWER_RESET_SYSCON_POWEROFF=y
@@ -234,8 +226,8 @@ CONFIG_THERMAL_WRITABLE_TRIPS=y
 CONFIG_CPU_THERMAL=y
 CONFIG_IMX_THERMAL=y
 CONFIG_WATCHDOG=y
-CONFIG_DA9062_WATCHDOG=y
 CONFIG_DA9063_WATCHDOG=m
+CONFIG_DA9062_WATCHDOG=y
 CONFIG_RN5T618_WATCHDOG=y
 CONFIG_IMX2_WDT=y
 CONFIG_IMX7ULP_WDT=y
@@ -246,7 +238,6 @@ CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_MFD_MC13XXX_I2C=y
 CONFIG_MFD_RN5T618=y
 CONFIG_MFD_STMPE=y
-CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ANATOP=y
 CONFIG_REGULATOR_DA9052=y
@@ -262,9 +253,6 @@ CONFIG_RC_CORE=y
 CONFIG_RC_DEVICES=y
 CONFIG_IR_GPIO_CIR=y
 CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_CAMERA_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
@@ -272,7 +260,6 @@ CONFIG_VIDEO_MUX=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_CODA=m
 CONFIG_VIDEO_IMX_PXP=y
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_OV2680=m
 CONFIG_VIDEO_OV5640=m
@@ -308,12 +295,10 @@ CONFIG_SND_USB_AUDIO=m
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_FSL_ASRC=y
 CONFIG_SND_IMX_SOC=y
-CONFIG_SND_SOC_PHYCORE_AC97=y
 CONFIG_SND_SOC_EUKREA_TLV320=y
 CONFIG_SND_SOC_IMX_ES8328=y
 CONFIG_SND_SOC_IMX_SGTL5000=y
 CONFIG_SND_SOC_IMX_SPDIF=y
-CONFIG_SND_SOC_IMX_MC13783=y
 CONFIG_SND_SOC_FSL_ASOC_CARD=y
 CONFIG_SND_SOC_AC97_CODEC=y
 CONFIG_SND_SOC_CS42XX8_I2C=y
@@ -325,7 +310,6 @@ CONFIG_HID_MULTITOUCH=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_MXC=y
 CONFIG_USB_ACM=m
 CONFIG_USB_STORAGE=y
 CONFIG_USB_CHIPIDEA=y
@@ -340,7 +324,6 @@ CONFIG_USB_EHSET_TEST_FIXTURE=m
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_MXS_PHY=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_FSL_USB2=y
 CONFIG_USB_CONFIGFS=y
 CONFIG_USB_CONFIGFS_SERIAL=y
 CONFIG_USB_CONFIGFS_ACM=y
@@ -389,11 +372,11 @@ CONFIG_RTC_DRV_ISL1208=y
 CONFIG_RTC_DRV_PCF8523=y
 CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_M41T80=y
+CONFIG_RTC_DRV_RC5T619=y
 CONFIG_RTC_DRV_DA9063=y
 CONFIG_RTC_DRV_MC13XXX=y
 CONFIG_RTC_DRV_MXC=y
 CONFIG_RTC_DRV_MXC_V2=y
-CONFIG_RTC_DRV_RC5T619=y
 CONFIG_RTC_DRV_SNVS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_EDMA=y
@@ -470,13 +453,14 @@ CONFIG_CRC_CCITT=m
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
+CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 CONFIG_PRINTK_TIME=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_PROVE_LOCKING=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FTRACE is not set
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 07:03:45 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:03:45 +0200
Subject: [PATCH v1 7/7] ARM: dts: colibri-imx6ull-emmc: add device trees
In-Reply-To: <20210819140345.357167-1-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
Message-ID: <20210819140345.357167-8-marcel@ziswiler.com>

From: Max Krummenacher <max.krummenacher at toradex.com>

Add devices trees for a Colibri iMX6ULL 1GB which has a eMMC instead of
the raw NAND used on other SKUs.

Related-to: ELB-4056, ELB-4058
Signed-off-by: Max Krummenacher <max.krummenacher at toradex.com>
Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/imx6ull-colibri-emmc-eval-v3.dts |  17 ++
 .../dts/imx6ull-colibri-emmc-nonwifi.dtsi     | 185 ++++++++++++++++++
 arch/arm/boot/dts/imx6ull-colibri.dtsi        |  30 ++-
 4 files changed, 232 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
 create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7e0934180724d..f88ddcc40b6ac 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -671,6 +671,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
 	imx6ul-tx6ul-0011.dtb \
 	imx6ul-tx6ul-mainboard.dtb \
 	imx6ull-14x14-evk.dtb \
+	imx6ull-colibri-emmc-eval-v3.dtb \
 	imx6ull-colibri-eval-v3.dtb \
 	imx6ull-colibri-wifi-eval-v3.dtb \
 	imx6ull-myir-mys-6ulx-eval.dtb \
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts b/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
new file mode 100644
index 0000000000000..70104a6c5bac9
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2021 Toradex AG
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-emmc-nonwifi.dtsi"
+#include "imx6ull-colibri-eval-v3.dtsi"
+
+/ {
+	model = "Toradex Colibri iMX6ULL 1GB (eMMC) on Colibri Evaluation Board V3";
+	compatible = "toradex,colibri-imx6ull-emmc-eval",
+		     "toradex,colibri-imx6ull-emmc",
+		     "toradex,colibri-imx6ull",
+		     "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi
new file mode 100644
index 0000000000000..df055617e51f7
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2021 Toradex AG
+ */
+
+#include "imx6ull-colibri.dtsi"
+
+/ {
+	aliases {
+		mmc0 = &usdhc2; /* eMMC */
+		mmc1 = &usdhc1; /* MMC 4bit slot */
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x10000000>;
+	};
+};
+
+&gpio1 {
+	gpio-line-names = "SODIMM_8",
+			  "SODIMM_6",
+			  "SODIMM_129",
+			  "SODIMM_89",
+			  "SODIMM_19",
+			  "SODIMM_21",
+			  "UNUSABLE_SODIMM_180",
+			  "UNUSABLE_SODIMM_184",
+			  "SODIMM_4",
+			  "SODIMM_2",
+			  "SODIMM_106",
+			  "SODIMM_71",
+			  "SODIMM_23",
+			  "SODIMM_31",
+			  "SODIMM_99",
+			  "SODIMM_102",
+			  "SODIMM_33",
+			  "SODIMM_35",
+			  "SODIMM_25",
+			  "SODIMM_27",
+			  "SODIMM_36",
+			  "SODIMM_38",
+			  "SODIMM_32",
+			  "SODIMM_34",
+			  "SODIMM_135",
+			  "SODIMM_77",
+			  "SODIMM_100",
+			  "SODIMM_186",
+			  "SODIMM_196",
+			  "SODIMM_194";
+};
+
+&gpio2 {
+	gpio-line-names = "SODIMM_55",
+			  "SODIMM_63",
+			  "SODIMM_178",
+			  "SODIMM_188",
+			  "SODIMM_73",
+			  "SODIMM_30",
+			  "SODIMM_67",
+			  "SODIMM_104",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_190",
+			  "SODIMM_47",
+			  "SODIMM_192",
+			  "SODIMM_49",
+			  "SODIMM_51",
+			  "SODIMM_53";
+};
+
+&gpio3 {
+	gpio-line-names = "SODIMM_56",
+			  "SODIMM_44",
+			  "SODIMM_68",
+			  "SODIMM_82",
+			  "",
+			  "SODIMM_76",
+			  "SODIMM_70",
+			  "SODIMM_60",
+			  "SODIMM_58",
+			  "SODIMM_78",
+			  "SODIMM_72",
+			  "SODIMM_80",
+			  "SODIMM_46",
+			  "SODIMM_62",
+			  "SODIMM_48",
+			  "SODIMM_74",
+			  "SODIMM_50",
+			  "SODIMM_52",
+			  "SODIMM_54",
+			  "SODIMM_66",
+			  "SODIMM_64",
+			  "SODIMM_57",
+			  "SODIMM_61",
+			  "SODIMM_29",
+			  "SODIMM_37",
+			  "SODIMM_88",
+			  "SODIMM_86",
+			  "SODIMM_92",
+			  "SODIMM_90";
+};
+
+&gpio4 {
+	gpio-line-names = "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_140",
+			  "SODIMM_59",
+			  "SODIMM_142",
+			  "SODIMM_144",
+			  "SODIMM_133",
+			  "SODIMM_146",
+			  "SODIMM_28",
+			  "SODIMM_75",
+			  "SODIMM_96",
+			  "SODIMM_81",
+			  "SODIMM_94",
+			  "SODIMM_101",
+			  "SODIMM_103",
+			  "SODIMM_79",
+			  "SODIMM_97",
+			  "SODIMM_69",
+			  "SODIMM_98",
+			  "SODIMM_85",
+			  "SODIMM_65";
+};
+
+&gpio5 {
+	gpio-line-names = "SODIMM_43",
+			  "SODIMM_45",
+			  "SODIMM_137",
+			  "SODIMM_95",
+			  "SODIMM_107",
+			  "SODIMM_131",
+			  "SODIMM_93",
+			  "",
+			  "SODIMM_138",
+			  "",
+			  "SODIMM_105",
+			  "SODIMM_127";
+};
+
+&gpmi {
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
+		&pinctrl_gpio4 &pinctrl_gpio6 &pinctrl_gpio7
+		&pinctrl_gpmi_gpio>;
+};
+
+&iomuxc_snvs {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_snvs_gpio1 &pinctrl_snvs_gpio3>;
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2emmc>;
+	assigned-clocks = <&clks IMX6UL_CLK_USDHC2_SEL>, <&clks IMX6UL_CLK_USDHC2>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
+	assigned-clock-rates = <0>, <198000000>;
+	bus-width = <8>;
+	keep-power-in-suspend;
+	no-1-8-v;
+	non-removable;
+	vmmc-supply = <&reg_module_3v3>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi b/arch/arm/boot/dts/imx6ull-colibri.dtsi
index 0cdbf7b6e7285..f432fc0a6a530 100644
--- a/arch/arm/boot/dts/imx6ull-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
- * Copyright 2018 Toradex AG
+ * Copyright 2018-2021 Toradex AG
  */
 
 #include "imx6ull.dtsi"
@@ -345,6 +345,19 @@ MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01	0xb0b0 /* SODIMM 63 */
 		>;
 	};
 
+		/*
+		 * With an eMMC instead of a raw NAND device the following pins
+		 * are available at SODIMM pins
+		 */
+		pinctrl_gpmi_gpio: gpmi-gpio-grp {
+			fsl,pins = <
+				MX6UL_PAD_NAND_ALE__GPIO4_IO10		0x10b0 /* SODIMM 140 */
+				MX6UL_PAD_NAND_CE0_B__GPIO4_IO13	0x10b0 /* SODIMM 144 */
+				MX6UL_PAD_NAND_CLE__GPIO4_IO15		0x10b0 /* SODIMM 146 */
+				MX6UL_PAD_NAND_READY_B__GPIO4_IO12	0x10b0 /* SODIMM 142 */
+			>;
+		};
+
 	pinctrl_gpmi_nand: gpmi-nand-grp {
 		fsl,pins = <
 			MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00	0x100a9
@@ -533,6 +546,21 @@ MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT	0x10
 		>;
 	};
 
+		pinctrl_usdhc2emmc: usdhc2emmcgrp {
+			fsl,pins = <
+				MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x17059
+				MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059
+				MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+				MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+				MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+				MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+				MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+				MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+				MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+				MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+			>;
+		};
+
 	pinctrl_wdog: wdog-grp {
 		fsl,pins = <
 			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 07:03:40 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:03:40 +0200
Subject: [PATCH v1 2/7] ARM: imx_v6_v7_defconfig: enable fb
In-Reply-To: <20210819140345.357167-1-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
Message-ID: <20210819140345.357167-3-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_FB which is nowadays required for CONFIG_DRM_PANEL_LVDS,
CONFIG_DRM_PANEL_SIMPLE, CONFIG_DRM_PANEL_SEIKO_43WVF1G,
CONFIG_FB_MODE_HELPERS, CONFIG_BACKLIGHT_PWM, CONFIG_BACKLIGHT_GPIO,
CONFIG_FRAMEBUFFER_CONSOLE, CONFIG_LOGO, CONFIG_FONTS, CONFIG_FONT_8x8
and CONFIG_FONT_8x16.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 70b3c377c4302..6618a009a105e 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -293,6 +293,7 @@ CONFIG_DRM_IMX_LDB=y
 CONFIG_DRM_IMX_HDMI=y
 CONFIG_DRM_ETNAVIV=y
 CONFIG_DRM_MXSFB=y
+CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 07:03:43 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:03:43 +0200
Subject: [PATCH v1 5/7] ARM: imx_v6_v7_defconfig: build imx sdma driver as
 module
In-Reply-To: <20210819140345.357167-1-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
Message-ID: <20210819140345.357167-6-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build CONFIG_IMX_SDMA as module to avoid the following boot issue:

[    5.214751] imx-sdma 20ec000.sdma: Direct firmware load for
 imx/sdma/sdma-imx6q.bin failed with error -2
[    5.215762] imx-sdma 20ec000.sdma: Falling back to sysfs fallback
 for: imx/sdma/sdma-imx6q.bin

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/configs/imx_v6_v7_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 21803cd2d1ba7..c0008b7faf2ce 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -380,7 +380,7 @@ CONFIG_RTC_DRV_MXC_V2=y
 CONFIG_RTC_DRV_SNVS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_EDMA=y
-CONFIG_IMX_SDMA=y
+CONFIG_IMX_SDMA=m
 CONFIG_MXS_DMA=y
 CONFIG_DMATEST=m
 CONFIG_STAGING=y
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 07:03:39 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:03:39 +0200
Subject: [PATCH v1 1/7] ARM: imx_v6_v7_defconfig: enable mtd physmap
In-Reply-To: <20210819140345.357167-1-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
Message-ID: <20210819140345.357167-2-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_MTD_PHYSMAP which is nowadays required for CONFIG_MTD_PHYSMAP_OF.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index ccee86d0045dd..70b3c377c4302 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -97,6 +97,7 @@ CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_DATAFLASH=y
 CONFIG_MTD_M25P80=y
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 07:03:41 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:03:41 +0200
Subject: [PATCH v1 3/7] ARM: imx_v6_v7_defconfig: change snd soc tlv320aic3x
 to i2c variant
In-Reply-To: <20210819140345.357167-1-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
Message-ID: <20210819140345.357167-4-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Change CONFIG_SND_SOC_TLV320AIC3X to CONFIG_SND_SOC_TLV320AIC3X_I2C. I
did double check all current mainline device trees and they are all
using the I2C rather than the SPI variant.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/configs/imx_v6_v7_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 6618a009a105e..90d6a5cf254e0 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -317,7 +317,7 @@ CONFIG_SND_SOC_IMX_MC13783=y
 CONFIG_SND_SOC_FSL_ASOC_CARD=y
 CONFIG_SND_SOC_AC97_CODEC=y
 CONFIG_SND_SOC_CS42XX8_I2C=y
-CONFIG_SND_SOC_TLV320AIC3X=y
+CONFIG_SND_SOC_TLV320AIC3X_I2C=y
 CONFIG_SND_SOC_WM8960=y
 CONFIG_SND_SOC_WM8962=y
 CONFIG_SND_SIMPLE_CARD=y
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 07:03:38 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:03:38 +0200
Subject: [PATCH v1 0/7] ARM: prepare and add colibri imx6ull 1gb (emmc) support
Message-ID: <20210819140345.357167-1-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>


Clean-up imx_v6_v7_defconfig and then add support for the new Colibri
iMX6ULL 1GB (eMMC) which builds on the success of the existing Colibri
iMX6ULL SKUs using raw NAND but replaces this by more RAM (1 GB) and an
eMMC (4 GB).


Marcel Ziswiler (6):
  ARM: imx_v6_v7_defconfig: enable mtd physmap
  ARM: imx_v6_v7_defconfig: enable fb
  ARM: imx_v6_v7_defconfig: change snd soc tlv320aic3x to i2c variant
  ARM: imx_v6_v7_defconfig: rebuild default configuration
  ARM: imx_v6_v7_defconfig: build imx sdma driver as module
  ARM: imx_v6_v7_defconfig: enable bpf syscall and cgroup bpf

Max Krummenacher (1):
  ARM: dts: colibri-imx6ull-emmc: add device trees

 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/imx6ull-colibri-emmc-eval-v3.dts |  17 ++
 .../dts/imx6ull-colibri-emmc-nonwifi.dtsi     | 185 ++++++++++++++++++
 arch/arm/boot/dts/imx6ull-colibri.dtsi        |  30 ++-
 arch/arm/configs/imx_v6_v7_defconfig          |  46 ++---
 5 files changed, 249 insertions(+), 30 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
 create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi

-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 07:03:44 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:03:44 +0200
Subject: [PATCH v1 6/7] ARM: imx_v6_v7_defconfig: enable bpf syscall and
 cgroup bpf
In-Reply-To: <20210819140345.357167-1-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
Message-ID: <20210819140345.357167-7-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_BPF_SYSCALL and CONFIG_CGROUP_BPF to allow for systemd
interoperability. This avoids the following failure on boot:

[   10.615914] systemd[1]: system-getty.slice: unit configures an IP
 firewall, but the local system does not support BPF/cgroup firewalling.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/configs/imx_v6_v7_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index c0008b7faf2ce..3e58c76763563 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -2,11 +2,13 @@ CONFIG_KERNEL_LZO=y
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_CGROUPS=y
+CONFIG_CGROUP_BPF=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
-- 
2.26.2



From kishon at ti.com  Thu Aug 19 07:09:10 2021
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 19 Aug 2021 19:39:10 +0530
Subject: [PATCH v3 0/5] PCI: Add support for J7200 and AM64
In-Reply-To: <20210819134418.GB26966@lpieralisi>
References: <20210811123336.31357-1-kishon@ti.com>
 <a618e0af-d95f-8e25-5b86-eff7fd14d186@ti.com>
 <20210819134418.GB26966@lpieralisi>
Message-ID: <b70bd865-920d-f736-9e6c-a6bb4442476f@ti.com>

Hi Lorenzo,

On 19/08/21 7:14 pm, Lorenzo Pieralisi wrote:
> On Thu, Aug 19, 2021 at 06:12:54PM +0530, Kishon Vijay Abraham I wrote:
>> Hi Lorenzo,
>>
>> On 11/08/21 6:03 pm, Kishon Vijay Abraham I wrote:
>>> This series adds the compatible specific to J7200 and AM64 and
>>> applies the erratas and configuration specific to them.
>>>
>>> This series also includes Nadeem's patch that adds a quirk in
>>> Cadence driver which is used by J7200 [1].
>>>
>>> The DT binding for both J7200 and AM64 is already merged.
>>>
>>> v1 of the patch series can be found at [2]
>>> v2 of the patch series can be found at [3]
>>
>> Gentle ping on this series.
>>
>> I've dropped "misc: pci_endpoint_test: Do not request or allocate IRQs
>> in probe" [A] from the previous version of the series which you had
>> concerns with.
>>
>> [A] -> http://lore.kernel.org/r/02c1ddb7-539e-20a0-1bef-e10e76922a0e at ti.com
> 
> Understood. The question is, how did you solve the issue that was
> forcing you to have that patch in place in the updated series.

That issue only prevents more than 5 pci-endpoint-test devices to be
tested simultaneously.

For the GIC ITS issue, I'm planning to post the workaround mentioned in
the errata document.

Errata ID #i2101 GIC: ITS Misbehavior
(https://www.ti.com/lit/er/sprz455a/sprz455a.pdf).

Also the GIC ITS issue is not present in J7200 and AM64 which this
series is planning to address. It's present only in J721E and AM65.

Thanks
Kishon

> 
> Thanks,
> Lorenzo
> 
>>
>> Thanks
>> Kishon
>>
>>>
>>> Changes from v2:
>>> 1) Drop the patch that does not request or allocate IRQs in probe for
>>> J721E/AM654
>>> 2) Fix other minor comments given by Lorenzo
>>>
>>> Changes from v1:
>>> 1) As suggested by Bjorn, used unsigned int :1, instead of bool for
>>> structure members
>>> 2) Removed using unnecessary local variables and also fixed some
>>> code alignment
>>>
>>> [1] -> https://lore.kernel.org/r/20210528155626.21793-1-nadeem at cadence.com
>>> [2] -> https://lore.kernel.org/r/20210706105035.9915-1-kishon at ti.com
>>> [3] -> https://lore.kernel.org/r/20210803074932.19820-1-kishon at ti.com
>>>
>>> Kishon Vijay Abraham I (4):
>>>   PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
>>>   PCI: j721e: Add PCIe support for J7200
>>>   PCI: j721e: Add PCIe support for AM64
>>>   misc: pci_endpoint_test: Add deviceID for AM64 and J7200
>>>
>>> Nadeem Athani (1):
>>>   PCI: cadence: Add quirk flag to set minimum delay in LTSSM
>>>     Detect.Quiet state
>>>
>>>  drivers/misc/pci_endpoint_test.c              |  8 +++
>>>  drivers/pci/controller/cadence/pci-j721e.c    | 61 +++++++++++++++++--
>>>  .../pci/controller/cadence/pcie-cadence-ep.c  |  4 ++
>>>  .../controller/cadence/pcie-cadence-host.c    |  3 +
>>>  drivers/pci/controller/cadence/pcie-cadence.c | 16 +++++
>>>  drivers/pci/controller/cadence/pcie-cadence.h | 17 +++++-
>>>  6 files changed, 103 insertions(+), 6 deletions(-)
>>>


From ezequiel at vanguardiasur.com.ar  Thu Aug 19 07:10:25 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Thu, 19 Aug 2021 11:10:25 -0300
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <1b79a67b703d2c894bc4d9458c760e082fc42958.camel@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
 <1b79a67b703d2c894bc4d9458c760e082fc42958.camel@mediatek.com>
Message-ID: <CAAEAJfCTrKj9AFExN-L-TKww4E=us1VVh8LHtZ8Q0j_eaCD4Eg@mail.gmail.com>

On Thu, 19 Aug 2021 at 04:13, yunfei.dong at mediatek.com
<yunfei.dong at mediatek.com> wrote:
>
> Hi Ezequiel,
>
> Thanks for your suggestion.
>
> On Wed, 2021-08-18 at 11:11 -0300, Ezequiel Garcia wrote:
> > +danvet
> >
> > Hi,
> >
> > On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <yunfei.dong at mediatek.com>
> > wrote:
> > >
> > > This series adds support for multi hardware decode into mtk-vcodec,
> > > by first
> > > adding component framework to manage each hardware information:
> > > interrupt,
> > > clock, register bases and power. Secondly add core thread to deal
> > > with core
> > > hardware message, at the same time, add msg queue for different
> > > hardware
> > > share messages. Lastly, the architecture of different specs are not
> > > the same,
> > > using specs type to separate them.
> > >
> >
> > I don't think it's a good idea to introduce the component API in the
> > media subsystem. It doesn't seem to be maintained, IRC there's not
> > even
> > a maintainer for it, and it has some issues that were never
> > addressed.
> >
> > It would be really important to avoid it. Is it really needed in the
> > first place?
> >
> > Thanks,
> > Ezequiel
>
> For there are many hardware need to use, mt8192 is three and mt8195 is
> five. Maybe need more to be used in the feature.
>
> Each hardware has independent clk/power/iommu port/irq.
> Use component interface in prob to get each component's information.
> Just enable the hardware when need to use it, very convenient and
> simple.
>
> I found that there are many modules use component to manage hardware
> information, such as iommu and drm etc.
>

Many drivers support multiple hardware variants, where each variant
has a different number of clocks or interrupts, see for instance
struct hantro_variant which allows to expose different codec cores,
some having both decoder/encoder, and some having just a decoder.

The component API is mostly used by DRM to aggregate independent
subdevices (called components) into an aggregated driver.

For instance, a DRM driver needs to glue together the HDMI, MIPI,
and plany controller, or any other hardware arrangement where
devices can be described independently.

The component API may look simple but has some issues, it's not easy
to debug, and can cause troubles if not used as expected [1].
It's worth making sure you actually need a framework
to glue different devices together.

> Do you have any other suggestion for this architecture?
>

Looking at the different patchsets that are posted, it's not clear
to me what exactly are the different architectures that you intend
to support, can you some documentation which clarifies that?

Thanks,
Ezequiel

[1] https://patchwork.kernel.org/project/linux-rockchip/cover/20200120170602.3832-1-ezequiel at collabora.com/


From l.stach at pengutronix.de  Thu Aug 19 07:11:01 2021
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 19 Aug 2021 16:11:01 +0200
Subject: [PATCH v2 3/6] dt-bindings: mmc: fsl-imx-esdhc: add fsl,
 broken-auto-tuning binding
In-Reply-To: <1629285415-7495-3-git-send-email-haibo.chen@nxp.com>
References: <1629285415-7495-1-git-send-email-haibo.chen@nxp.com>
 <1629285415-7495-3-git-send-email-haibo.chen@nxp.com>
Message-ID: <bb658c8013e2e8e38c21b83d59eec7046d939097.camel@pengutronix.de>

Hi Haibo,

Am Mittwoch, dem 18.08.2021 um 19:16 +0800 schrieb haibo.chen at nxp.com:
> From: Haibo Chen <haibo.chen at nxp.com>
> 
> Add a new fsl,broken-auto-tuning binding for sdio devices. When sdio
> device support sdio interrupt, need to use this property to disable
> auto-tuning. Auto-tuning circuit is conflict with sdio interrupt.
> 
Wouldn't it be possible to do this automatically by the driver without
a DT property when a SDIO card is detected?

Regards,
Lucas

> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> ---
>  Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> index b5baf439fbac..d7c8e5880473 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> @@ -93,6 +93,15 @@ properties:
>        tuning step can't find the proper delay window within limited tuning retries.
>      default: 0
>  
> +  fsl,broken-auto-tuning:
> +    description: |
> +      Recommend for SDIO cards that enables SDIO interrupt for SDR104 and SDR50 mode.
> +      SDIO interrupt uses DAT[1] to signal the card's interrupt. Auto-tuning circuit
> +      will detect this interrupt on DAT[1] when in 4Bit bus mode, and take it just
> +      as normal data, wrongly adjust the delay cell. This property is used to disable
> +      the auto-tuning function.
> +    type: boolean
> +
>    fsl,strobe-dll-delay-target:
>      $ref: /schemas/types.yaml#/definitions/uint32
>      description: |




From broonie at kernel.org  Thu Aug 19 07:16:17 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 15:16:17 +0100
Subject: [PATCH 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <2412250.zZEsDtmPgG@archbook>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
 <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
 <deb50900-fcfd-23d0-ab8a-0e64b2abb063@arm.com>
 <2412250.zZEsDtmPgG@archbook>
Message-ID: <20210819141617.GM4177@sirena.org.uk>

On Thu, Aug 19, 2021 at 03:52:55PM +0200, Nicolas Frattaroli wrote:
> On Donnerstag, 19. August 2021 14:08:36 CEST Robin Murphy wrote:

> > > +  rockchip,no-dmaengine:
> > > +    description:
> > > +      If present, driver will not register a pcm dmaengine, only the dai.
> > > +      If the dai is part of multi-dais, the property should be present.
> > > +    type: boolean

> > That sounds a lot more like a policy decision specific to the Linux
> > driver implementation, than something which really belongs in DT as a
> > description of the platform.

> I agree. Should I be refactoring this into a module parameter or
> something along those lines? I'm unsure of where this goes.

Why is this even required?  What is "multi-dais" and why would
registering the DMA stuff cause a problem?

> The particular configuration may even vary per-board; an I2S/TDM
> controller may be connected to an external codec which does not
> support capture, whereas on another board it may be connected to
> one that does.

If the external device doesn't support both directions then why does the
driver for the I2S controller in the CPU care?  The constraint handling
code in the core will ensure that nothing tries to start something that
isn't supported
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210819/79108bb8/attachment.sig>

From lorenzo.pieralisi at arm.com  Thu Aug 19 07:17:58 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 19 Aug 2021 15:17:58 +0100
Subject: [PATCH v6 0/8] PCI: hv: Support host bridge probing on ARM64
In-Reply-To: <20210726180657.142727-1-boqun.feng@gmail.com>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
Message-ID: <20210819141758.GA27305@lpieralisi>

On Tue, Jul 27, 2021 at 02:06:49AM +0800, Boqun Feng wrote:
> Hi,
> 
> This is the v6 for the preparation of virtual PCI support on Hyper-V
> ARM64, Previous versions:
> 
> v1:	https://lore.kernel.org/lkml/20210319161956.2838291-1-boqun.feng at gmail.com/
> v2:	https://lore.kernel.org/lkml/20210503144635.2297386-1-boqun.feng at gmail.com/
> v3:	https://lore.kernel.org/lkml/20210609163211.3467449-1-boqun.feng at gmail.com/
> v4:	https://lore.kernel.org/lkml/20210714102737.198432-1-boqun.feng at gmail.com/
> v5:	https://lore.kernel.org/lkml/20210720134429.511541-1-boqun.feng at gmail.com/
> 
> Changes since last version:
> 
> *	Rebase to 5.14-rc3
> 
> *	Comment fixes as suggested by Bjorn.
> 
> The basic problem we need to resolve is that ARM64 is an arch with
> PCI_DOMAINS_GENERIC=y, so the bus sysdata is pci_config_window. However,
> Hyper-V PCI provides a paravirtualized PCI interface, so there is no
> actual pci_config_window for a PCI host bridge, so no information can be
> retrieve from the pci_config_window of a Hyper-V virtual PCI bus. Also
> there is no corresponding ACPI device for the Hyper-V PCI root bridge,
> which introduces a special case when trying to find the ACPI device from
> the sysdata (see patch #3).
> 
> With this patchset, we could enable the virtual PCI on Hyper-V ARM64
> guest with other code under development.
> 
> Comments and suggestions are welcome.
> 
> Regards,
> Boqun
> 
> Arnd Bergmann (1):
>   PCI: hv: Generify PCI probing
> 
> Boqun Feng (7):
>   PCI: Introduce domain_nr in pci_host_bridge
>   PCI: Support populating MSI domains of root buses via bridges
>   arm64: PCI: Restructure pcibios_root_bridge_prepare()
>   arm64: PCI: Support root bridge preparation for Hyper-V
>   PCI: hv: Set ->domain_nr of pci_host_bridge at probing time
>   PCI: hv: Set up MSI domain at bridge probing time
>   PCI: hv: Turn on the host bridge probing on ARM64
> 
>  arch/arm64/kernel/pci.c             | 29 +++++++---
>  drivers/pci/controller/pci-hyperv.c | 86 +++++++++++++++++------------
>  drivers/pci/probe.c                 | 12 +++-
>  include/linux/pci.h                 | 11 ++++
>  4 files changed, 93 insertions(+), 45 deletions(-)

If we take this series via the PCI tree we'd need Catalin/Will ACKs on
patches 3-4.

I need some time to look into [1] (thanks for that).

Without [1] patch 8 is ugly, that's no news. The question is whether
it is worth waiting for a kernel cycle to integrate [1] into this series
or not.

Is it really a problem if we postpone this series for another kernel
cycle so that we can look into it ?

[1] https://lore.kernel.org/lkml/20210811153619.88922-1-boqun.feng at gmail.com/


From maz at kernel.org  Thu Aug 19 07:35:56 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Aug 2021 15:35:56 +0100
Subject: [PATCH v4 11/15] KVM: arm64: Guest exit handlers for nVHE hyp
In-Reply-To: <87fsv6snup.wl-maz@kernel.org>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-12-tabba@google.com>
 <87fsv6snup.wl-maz@kernel.org>
Message-ID: <87zgtdqz77.wl-maz@kernel.org>

Hi Fuad,

On Wed, 18 Aug 2021 17:45:50 +0100,
Marc Zyngier <maz at kernel.org> wrote:
> 
> On Tue, 17 Aug 2021 09:11:30 +0100,
> Fuad Tabba <tabba at google.com> wrote:
> > 
> > Add an array of pointers to handlers for various trap reasons in
> > nVHE code.
> > 
> > The current code selects how to fixup a guest on exit based on a
> > series of if/else statements. Future patches will also require
> > different handling for guest exists. Create an array of handlers
> > to consolidate them.
> > 
> > No functional change intended as the array isn't populated yet.
> > 
> > Acked-by: Will Deacon <will at kernel.org>
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/kvm/hyp/include/hyp/switch.h | 43 +++++++++++++++++++++++++
> >  arch/arm64/kvm/hyp/nvhe/switch.c        | 33 +++++++++++++++++++
> >  2 files changed, 76 insertions(+)
> > 
> > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > index a0e78a6027be..5a2b89b96c67 100644
> > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > @@ -409,6 +409,46 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
> >  	return true;
> >  }
> >  
> > +typedef int (*exit_handle_fn)(struct kvm_vcpu *);
> 
> This returns an int...
> 
> > +
> > +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu);
> > +
> > +static exit_handle_fn kvm_get_hyp_exit_handler(struct kvm_vcpu *vcpu)
> > +{
> > +	return is_nvhe_hyp_code() ? kvm_get_nvhe_exit_handler(vcpu) : NULL;
> > +}
> > +
> > +/*
> > + * Allow the hypervisor to handle the exit with an exit handler if it has one.
> > + *
> > + * Returns true if the hypervisor handled the exit, and control should go back
> > + * to the guest, or false if it hasn't.
> > + */
> > +static bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu)
> > +{
> > +	bool is_handled = false;
> 
> ... which you then implicitly cast as a bool.
> 
> > +	exit_handle_fn exit_handler = kvm_get_hyp_exit_handler(vcpu);
> > +
> > +	if (exit_handler) {
> > +		/*
> > +		 * There's limited vcpu context here since it's not synced yet.
> > +		 * Ensure that relevant vcpu context that might be used by the
> > +		 * exit_handler is in sync before it's called and if handled.
> > +		 */
> > +		*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
> > +		*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
> > +
> > +		is_handled = exit_handler(vcpu);
> 
> What does 'is_handled' mean here? By definition, any trap *must* be
> handled, one way or another. By the look of it, what you really mean
> is something like "I have updated the vcpu state and you'd better
> reload it". Is that what it means?
> 
> > +
> > +		if (is_handled) {
> > +			write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
> > +			write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
> > +		}
> > +	}
> > +
> > +	return is_handled;
> > +}
> 
> All these functions really should be marked inline. Have you checked
> how this expands on VHE? I think some compilers could be pretty
> unhappy about the undefined symbol in kvm_get_hyp_exit_handler().
> 
> It is also unfortunate that we get a bunch of tests for various
> flavours of traps (FP, PAuth, page faults...), only to hit yet another
> decoding tree. Is there a way we could use this infrastructure for
> everything?

I realised that I wasn't very forthcoming here. I've decided to put
the code where my mouth is and pushed out a branch [1] with your first
10 patches, followed by my own take on this particular problem. It
compiles, and even managed to boot a Debian guest on a nVHE box.

As you can see, most of the early exit handling is now moved to
specific handlers, unifying the handling. For the protected mode, you
can provide your own handler array (just hack
kvm_get_exit_handler_array() to return something else), which will do
the right thing as long as you call into the existing handlers first.

When it comes to the ELR/SPSR handling, it is better left to the
individual handlers (which we already do in some cases, see how we
skip instructions, for example).

Please let me know what you think.

Thanks,

	M.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/pkvm-fixed-features

-- 
Without deviation from the norm, progress is not possible.


From lorenzo.pieralisi at arm.com  Thu Aug 19 07:38:52 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 19 Aug 2021 15:38:52 +0100
Subject: [PATCH v3 0/5] PCI: Add support for J7200 and AM64
In-Reply-To: <20210811123336.31357-1-kishon@ti.com>
References: <20210811123336.31357-1-kishon@ti.com>
Message-ID: <162938392214.29875.12508742461574225755.b4-ty@arm.com>

On Wed, 11 Aug 2021 18:03:31 +0530, Kishon Vijay Abraham I wrote:
> This series adds the compatible specific to J7200 and AM64 and
> applies the erratas and configuration specific to them.
> 
> This series also includes Nadeem's patch that adds a quirk in
> Cadence driver which is used by J7200 [1].
> 
> The DT binding for both J7200 and AM64 is already merged.
> 
> [...]

Applied to pci/cadence, thanks!

[1/5] PCI: cadence: Use bitfield for *quirk_retrain_flag* instead of bool
      https://git.kernel.org/lpieralisi/pci/c/f4455748b2
[2/5] PCI: cadence: Add quirk flag to set minimum delay in LTSSM Detect.Quiet state
      https://git.kernel.org/lpieralisi/pci/c/09c24094b2
[3/5] PCI: j721e: Add PCIe support for J7200
      https://git.kernel.org/lpieralisi/pci/c/f1de58802f
[4/5] PCI: j721e: Add PCIe support for AM64
      https://git.kernel.org/lpieralisi/pci/c/c8a375a8e1
[5/5] misc: pci_endpoint_test: Add deviceID for AM64 and J7200
      https://git.kernel.org/lpieralisi/pci/c/7c52009d94

Thanks,
Lorenzo


From chunkuang.hu at kernel.org  Thu Aug 19 08:00:02 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 19 Aug 2021 23:00:02 +0800
Subject: [PATCH v8 01/13] dt-bindings: arm: mediatek: mmsys: add mt8195
 SoC binding
In-Reply-To: <20210819022327.13040-2-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-2-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_9Yug-9S4uBkNLTJH+TU8dHCeOjLuwXdNMJ+R89qJyJ9Q@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
>
> 1. There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195.
>    Each of them is bound to a display pipeline, so add their
>    definition in mtk-mmsys documentation with 2 compatibles.
>
> 2. Add description for power-domain property.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> this patch is base on [1][2]
>
> [1] dt-bindings: arm: mediatek: mmsys: convert to YAML format
> - https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-1-fparent at baylibre.com/
> [2] dt-bindings: arm: mediatek: mmsys: add MT8365 SoC binding
> - https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-2-fparent at baylibre.com/
> ---
>  .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml  | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> index 2d4ff0ce387b..68cb330d7595 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> @@ -30,6 +30,8 @@ properties:
>                - mediatek,mt8173-mmsys
>                - mediatek,mt8183-mmsys
>                - mediatek,mt8365-mmsys
> +              - mediatek,mt8195-vdosys0
> +              - mediatek,mt8195-vdosys1
>            - const: syscon
>        - items:
>            - const: mediatek,mt7623-mmsys
> @@ -39,6 +41,12 @@ properties:
>    reg:
>      maxItems: 1
>
> +  power-domains:
> +    description:
> +      A phandle and PM domain specifier as defined by bindings
> +      of the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +

This patch is about mt8195, but mt8173 mmsys also has power domain. So
move this part to another patch.

Regards,
Chun-Kuang.


>    "#clock-cells":
>      const: 1
>
> --
> 2.18.0
>


From gregkh at linuxfoundation.org  Thu Aug 19 08:05:36 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Thu, 19 Aug 2021 17:05:36 +0200
Subject: [PATCH] usb: xhci-mtk: Do not use xhci's virt_dev in drop_endpoint
In-Reply-To: <2593ac262cdf0088e937b9fbc907bb23a6736fb5.camel@mediatek.com>
References: <20210805133731.1.Icc0f080e75b1312692d4c7c7d25e7df9fe1a05c2@changeid>
 <2593ac262cdf0088e937b9fbc907bb23a6736fb5.camel@mediatek.com>
Message-ID: <YR5zQD8dFWsXu5Ns@kroah.com>

On Thu, Aug 19, 2021 at 11:56:59AM +0000, Chunfeng Yun (???) wrote:
> Hi Greg,
> 
> On Thu, 2021-08-05 at 13:37 +0800, Ikjoon Jang wrote:
> > xhci-mtk depends on xhci's internal virt_dev when it retrieves its
> > internal data from usb_host_endpoint both in add_endpoint and
> > drop_endpoint callbacks. But when setup packet was retired by
> > transaction errors in xhci_setup_device() path, a virt_dev for the
> > slot
> > is newly created with real_port 0. This leads to xhci-mtks's NULL
> > pointer
> > dereference from drop_endpoint callback as xhci-mtk assumes that
> > virt_dev's
> > real_port is always started from one. The similar problems were
> > addressed
> > by [1] but that can't cover the failure cases from setup_device.
> > 
> > This patch drops the usages of xhci's virt_dev in xhci-mtk's
> > drop_endpoint
> > callback by adopting rhashtable for searching mtk's schedule entity
> > from a given usb_host_endpoint pointer instead of searching a linked
> > list.
> > So mtk's drop_endpoint callback doesn't have to rely on virt_dev at
> > all.
> > 
> > [1] 
> > https://lore.kernel.org/r/1617179142-2681-2-git-send-email-chunfeng.yun at mediatek.com
> > 
> > Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
> > ---
> > 
> >  drivers/usb/host/xhci-mtk-sch.c | 140 ++++++++++++++++++----------
> > ----
> >  drivers/usb/host/xhci-mtk.h     |  15 ++--
> >  2 files changed, 86 insertions(+), 69 deletions(-)
> > 
> > diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-
> > mtk-sch.c
> > index cffcaf4dfa9f..f9b4d27ce449 100644
> > --- a/drivers/usb/host/xhci-mtk-sch.c
> > +++ b/drivers/usb/host/xhci-mtk-sch.c
> > 
> 
> I see the patch is already in usb-next branch, but find some new bugs
> introduced after I test it (one NULL point dereference oops, two memory
> leakage due to no error handling). 
> What do I need to do? revert this patch then send new version or just
> send fix patches?

Which ever you want to do is fine with me.

thanks,

greg k-h


From marcel at holtmann.org  Thu Aug 19 08:11:50 2021
From: marcel at holtmann.org (Marcel Holtmann)
Date: Thu, 19 Aug 2021 17:11:50 +0200
Subject: [PATCH v3] Bluetooth: btusb: Remove WAKEUP_DISABLE and add 
 WAKEUP_AUTOSUSPEND for Realtek devices
In-Reply-To: <20210817030312.27755-1-max.chou@realtek.com>
References: <20210817030312.27755-1-max.chou@realtek.com>
Message-ID: <F4EB3AD0-2ADF-44C4-83A1-F37F98530B1B@holtmann.org>

Hi Max,

> For the commit of 9e45524a011107a73bc2cdde8370c61e82e93a4d, wakeup is
> always disabled for Realtek devices. However, there's the capability
> for Realtek devices to apply USB wakeup.
> 
> In this commit, remove WAKEUP_DISABLE feature for Realtek devices.
> If users would switch wakeup, they should access
> "/sys/bus/usb/.../power/wakeup"
> 
> In this commit, it also adds the feature as WAKEUP_AUTOSUSPEND
> for Realtek devices because it should set do_remote_wakeup on autosuspend.
> 
> Signed-off-by: Max Chou <max.chou at realtek.com>
> Tested-by: Hilda Wu <hildawu at realtek.com>
> Reviewed-by: Archie Pusaka <apusaka at chromium.org>
> Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit at chromium.org>
> ---
> Changes in v2:
> -fix the compiling error due to the incorrect patch file submited
> 
> Changes in v3:
> -do rebase and make the patch on the latest revision
> ---
> drivers/bluetooth/btusb.c | 28 +++++++++-------------------
> 1 file changed, 9 insertions(+), 19 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel



From abailon at baylibre.com  Thu Aug 19 08:13:36 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Thu, 19 Aug 2021 17:13:36 +0200
Subject: [PATCH v3 0/4]  Add support of mt8183 APU
Message-ID: <20210819151340.741565-1-abailon@baylibre.com>

Some Mediatek's SoC have an Accelerated Processing Unit.
This adds support of the one available in the mt8183
(aswell some derivative SoC).

This v3 attempt to handle memory differently.
In the v2, the memory was reserved in dts and all dma allocation made by
remoteproc was using it. Since we may load many firmwares with different size,
this could lead to a memory waste or out of memory issues.
In addition, the APU itself expect the memory to mapped at a specific address.
The firmware, because of many hardware / software limitations use hardcoded
address.
To simplify memory management of userspace application, kernel and firmware,
and to rmeove a couple of hacks, we changed the way to manage the memory.
With the v3, only the virtio memory (that won't never change) is reserved
in the dts. The firmware declare resource similar to the CARVOUT_RSC 
that used by this driver to allocate and map the memory using the IOMMU.
I am not sure that the best solution but the simplest one I found so far.

Changes in v3:
- Remove IOMMU hack. Instead, manage the IOMMU directly from the driver
- Update the device tree bindings: only use reserved memory for virtio.
  All the other memory allocation will be done using DMA API.
  This sould simplify the memory management.
- Add more comments
Changes in v2:
- Drop the workarounds needed to load bad firmwares
- There are many name for the APU (most common one is VPU).
  Rename many functions and dts nodes to be more consistent.
- Use the bulk clock API, and enable / disable clock at a better place
- add few comments explaining how to start the APU
- update the way to use pinctl for JTAG
- fix some minors issues
- fix device tree bindings

Alexandre Bailon (4):
  dt bindings: remoteproc: Add bindings for MT8183 APU
  remoteproc: Add a remoteproc driver for the MT8183's APU
  remoteproc: mtk_vpu_rproc: Add support of JTAG
  ARM64: mt8183: Add support of APU to mt8183

 .../bindings/remoteproc/mtk,apu.yaml          | 118 ++++
 .../boot/dts/mediatek/mt8183-pumpkin.dts      |  48 ++
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  40 ++
 drivers/remoteproc/Kconfig                    |  19 +
 drivers/remoteproc/Makefile                   |   1 +
 drivers/remoteproc/mtk_apu.c                  | 590 ++++++++++++++++++
 6 files changed, 816 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,apu.yaml
 create mode 100644 drivers/remoteproc/mtk_apu.c

-- 
2.31.1



From abailon at baylibre.com  Thu Aug 19 08:13:38 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Thu, 19 Aug 2021 17:13:38 +0200
Subject: [PATCH v3 2/4] remoteproc: Add a remoteproc driver for the MT8183's
 APU
In-Reply-To: <20210819151340.741565-1-abailon@baylibre.com>
References: <20210819151340.741565-1-abailon@baylibre.com>
Message-ID: <20210819151340.741565-3-abailon@baylibre.com>

This adds a driver to control the APU present in the MT8183.
This loads the firmware and start the DSP.

Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
---
 drivers/remoteproc/Kconfig   |  10 +
 drivers/remoteproc/Makefile  |   1 +
 drivers/remoteproc/mtk_apu.c | 440 +++++++++++++++++++++++++++++++++++
 3 files changed, 451 insertions(+)
 create mode 100644 drivers/remoteproc/mtk_apu.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 9a6eedc3994a5..6c106a6c3ad5d 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -53,6 +53,16 @@ config MTK_SCP
 
 	  It's safe to say N here.
 
+config MTK_APU
+	tristate "Mediatek APU remoteproc support"
+	depends on ARCH_MEDIATEK
+	depends on MTK_IOMMU
+	help
+	  Say y to support the Mediatek's Accelerated Processing Unit (APU) via
+	  the remote processor framework.
+
+	  It's safe to say N here.
+
 config OMAP_REMOTEPROC
 	tristate "OMAP remoteproc support"
 	depends on ARCH_OMAP4 || SOC_OMAP5 || SOC_DRA7XX
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index bb26c9e4ef9cf..e395af86c17b0 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_REMOTEPROC_CDEV)		+= remoteproc_cdev.o
 obj-$(CONFIG_IMX_REMOTEPROC)		+= imx_rproc.o
 obj-$(CONFIG_INGENIC_VPU_RPROC)		+= ingenic_rproc.o
 obj-$(CONFIG_MTK_SCP)			+= mtk_scp.o mtk_scp_ipi.o
+obj-$(CONFIG_MTK_APU)			+= mtk_apu.o
 obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
diff --git a/drivers/remoteproc/mtk_apu.c b/drivers/remoteproc/mtk_apu.c
new file mode 100644
index 0000000000000..0e3f63987bd85
--- /dev/null
+++ b/drivers/remoteproc/mtk_apu.c
@@ -0,0 +1,440 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 BayLibre SAS
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/iommu.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+
+#include "remoteproc_internal.h"
+
+#define SW_RST					(0x0000000C)
+#define SW_RST_OCD_HALT_ON_RST			BIT(12)
+#define SW_RST_IPU_D_RST			BIT(8)
+#define SW_RST_IPU_B_RST			BIT(4)
+#define CORE_CTRL				(0x00000110)
+#define CORE_CTRL_PDEBUG_ENABLE			BIT(31)
+#define CORE_CTRL_SRAM_64K_iMEM			(0x00 << 27)
+#define CORE_CTRL_SRAM_96K_iMEM			(0x01 << 27)
+#define CORE_CTRL_SRAM_128K_iMEM		(0x02 << 27)
+#define CORE_CTRL_SRAM_192K_iMEM		(0x03 << 27)
+#define CORE_CTRL_SRAM_256K_iMEM		(0x04 << 27)
+#define CORE_CTRL_PBCLK_ENABLE			BIT(26)
+#define CORE_CTRL_RUN_STALL			BIT(23)
+#define CORE_CTRL_STATE_VECTOR_SELECT		BIT(19)
+#define CORE_CTRL_PIF_GATED			BIT(17)
+#define CORE_CTRL_NMI				BIT(0)
+#define CORE_XTENSA_INT				(0x00000114)
+#define CORE_CTL_XTENSA_INT			(0x00000118)
+#define CORE_DEFAULT0				(0x0000013C)
+#define CORE_DEFAULT0_QOS_SWAP_0		(0x00 << 28)
+#define CORE_DEFAULT0_QOS_SWAP_1		(0x01 << 28)
+#define CORE_DEFAULT0_QOS_SWAP_2		(0x02 << 28)
+#define CORE_DEFAULT0_QOS_SWAP_3		(0x03 << 28)
+#define CORE_DEFAULT0_ARUSER_USE_IOMMU		(0x10 << 23)
+#define CORE_DEFAULT0_AWUSER_USE_IOMMU		(0x10 << 18)
+#define CORE_DEFAULT1				(0x00000140)
+#define CORE_DEFAULT0_ARUSER_IDMA_USE_IOMMU	(0x10 << 0)
+#define CORE_DEFAULT0_AWUSER_IDMA_USE_IOMMU	(0x10 << 5)
+#define CORE_XTENSA_ALTRESETVEC			(0x000001F8)
+
+#define RSC_VENDOR_CARVEOUT			(RSC_VENDOR_START + 1)
+
+#define APU_RESET_DELAY				(27)
+
+struct mtk_apu_rproc {
+	struct device *dev;
+	void __iomem *base;
+	int irq;
+	struct clk_bulk_data clks[3];
+	struct list_head mappings;
+};
+
+static int mtk_apu_iommu_map(struct rproc *rproc, struct rproc_mem_entry *entry)
+{
+	struct mtk_apu_rproc *apu_rproc = rproc->priv;
+	struct device *dev = rproc->dev.parent;
+	struct rproc_mem_entry *mapping;
+	struct iommu_domain *domain;
+	int ret;
+	u64 pa;
+
+	mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+	if (!mapping)
+		return -ENOMEM;
+
+	if (!entry->va)
+		pa = entry->dma;
+	else
+		pa = rproc_va_to_pa(entry->va);
+
+	if ((strcmp(entry->name, "vdev0vring0") == 0 ||
+		strcmp(entry->name, "vdev0vring1") == 0)) {
+		entry->va = memremap(entry->dma, entry->len, MEMREMAP_WC);
+		if (IS_ERR_OR_NULL(entry->va)) {
+			dev_err(dev, "Unable to map memory region: %pa+%lx\n",
+				&entry->dma, entry->len);
+			ret = PTR_ERR(mapping->va);
+			goto free_mapping;
+		}
+		mapping->va = entry->va;
+	}
+
+	domain = iommu_get_domain_for_dev(dev);
+	ret = iommu_map(domain, entry->da, pa, entry->len, entry->flags);
+	if (ret) {
+		dev_err(dev, "iommu_map failed: %d\n", ret);
+		goto err_memunmap;
+	}
+
+	mapping->da = entry->da;
+	mapping->len = entry->len;
+	list_add_tail(&mapping->node, &apu_rproc->mappings);
+
+	return 0;
+
+err_memunmap:
+	memunmap(mapping->va);
+free_mapping:
+	kfree(mapping);
+
+	return ret;
+}
+
+static void mtk_apu_iommu_unmap_all(struct rproc *rproc)
+{
+	struct mtk_apu_rproc *apu_rproc = rproc->priv;
+	struct device *dev = rproc->dev.parent;
+	struct rproc_mem_entry *entry, *tmp;
+	struct iommu_domain *domain;
+
+	/* clean up iommu mapping entries */
+	list_for_each_entry_safe(entry, tmp, &apu_rproc->mappings, node) {
+		size_t unmapped;
+
+		domain = iommu_get_domain_for_dev(dev);
+		unmapped = iommu_unmap(domain, entry->da, entry->len);
+		if (unmapped != entry->len) {
+			/* nothing much to do besides complaining */
+			dev_err(dev, "failed to unmap %zx/%zu\n", entry->len,
+				unmapped);
+		}
+		memunmap(entry->va);
+
+		list_del(&entry->node);
+		kfree(entry);
+	}
+}
+
+static int mtk_apu_rproc_prepare(struct rproc *rproc)
+{
+	struct mtk_apu_rproc *apu_rproc = rproc->priv;
+	int ret;
+
+	ret = clk_bulk_prepare_enable(ARRAY_SIZE(apu_rproc->clks),
+				      apu_rproc->clks);
+	if (ret)
+		dev_err(apu_rproc->dev, "Failed to enable clocks\n");
+
+	return ret;
+}
+
+static int mtk_apu_rproc_unprepare(struct rproc *rproc)
+{
+	struct mtk_apu_rproc *apu_rproc = rproc->priv;
+
+	clk_bulk_disable_unprepare(ARRAY_SIZE(apu_rproc->clks),
+				   apu_rproc->clks);
+
+	return 0;
+}
+
+static int mtk_apu_rproc_start(struct rproc *rproc)
+{
+	struct mtk_apu_rproc *apu_rproc = rproc->priv;
+	u32 core_ctrl;
+
+	/* Set reset vector of APU firmware boot address */
+	writel(rproc->bootaddr, apu_rproc->base + CORE_XTENSA_ALTRESETVEC);
+
+	/* Turn on the clocks and stall the APU */
+	core_ctrl = readl(apu_rproc->base + CORE_CTRL);
+	core_ctrl |= CORE_CTRL_PDEBUG_ENABLE | CORE_CTRL_PBCLK_ENABLE |
+		     CORE_CTRL_STATE_VECTOR_SELECT | CORE_CTRL_RUN_STALL |
+		     CORE_CTRL_PIF_GATED;
+	writel(core_ctrl, apu_rproc->base + CORE_CTRL);
+
+	/* Reset the APU: this requires 27 ns to be effective on any platform */
+	writel(SW_RST_OCD_HALT_ON_RST | SW_RST_IPU_B_RST | SW_RST_IPU_D_RST,
+		apu_rproc->base + SW_RST);
+	ndelay(APU_RESET_DELAY);
+	writel(0, apu_rproc->base + SW_RST);
+
+	core_ctrl &= ~CORE_CTRL_PIF_GATED;
+	writel(core_ctrl, apu_rproc->base + CORE_CTRL);
+
+	/* Configure memory accesses to go through the IOMMU */
+	writel(CORE_DEFAULT0_AWUSER_USE_IOMMU | CORE_DEFAULT0_ARUSER_USE_IOMMU |
+	      CORE_DEFAULT0_QOS_SWAP_1, apu_rproc->base + CORE_DEFAULT0);
+	writel(CORE_DEFAULT0_AWUSER_IDMA_USE_IOMMU |
+		CORE_DEFAULT0_ARUSER_IDMA_USE_IOMMU,
+		apu_rproc->base + CORE_DEFAULT1);
+
+	/* Release the APU */
+	core_ctrl &= ~CORE_CTRL_RUN_STALL;
+	writel(core_ctrl, apu_rproc->base + CORE_CTRL);
+
+	return 0;
+}
+
+static int mtk_apu_rproc_stop(struct rproc *rproc)
+{
+	struct mtk_apu_rproc *apu_rproc = rproc->priv;
+	u32 core_ctrl;
+
+	core_ctrl = readl(apu_rproc->base + CORE_CTRL);
+	writel(core_ctrl | CORE_CTRL_RUN_STALL, apu_rproc->base + CORE_CTRL);
+
+	mtk_apu_iommu_unmap_all(rproc);
+
+	return 0;
+}
+
+static void mtk_apu_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct mtk_apu_rproc *apu_rproc = rproc->priv;
+
+	writel(1 << vqid, apu_rproc->base + CORE_CTL_XTENSA_INT);
+}
+
+static int mtk_apu_load(struct rproc *rproc, const struct firmware *fw)
+
+{
+	struct rproc_mem_entry *entry, *tmp;
+	int ret;
+
+	ret = rproc_elf_load_segments(rproc, fw);
+	if (ret)
+		return ret;
+
+	list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
+		ret = mtk_apu_iommu_map(rproc, entry);
+		if (ret)
+			goto err_unmap_all;
+	}
+
+	return 0;
+
+err_unmap_all:
+	mtk_apu_iommu_unmap_all(rproc);
+
+	return ret;
+}
+
+static struct reserved_mem *of_reserved_mem_by_name(struct rproc *rproc,
+						    const char *name)
+{
+	struct device *dev = rproc->dev.parent;
+	struct device_node *np = dev->of_node;
+	struct device_node *target;
+	struct reserved_mem *rmem;
+	int idx;
+
+	idx = of_property_match_string(np, "memory-region-names", name);
+	if (idx < 0) {
+		dev_err(dev, "failed to find %s memory\n", name);
+		return NULL;
+	}
+
+	target = of_parse_phandle(np, "memory-region", idx);
+	if (!target)
+		return NULL;
+
+	rmem = of_reserved_mem_lookup(target);
+	if (!rmem)
+		dev_err(dev, "unable to acquire memory-region\n");
+	of_node_put(target);
+
+	return rmem;
+}
+
+static int mtk_apu_handle_rsc(struct rproc *rproc, u32 rsc_type, void *rsc,
+			      int offset, int avail)
+{
+	struct device *dev = rproc->dev.parent;
+
+	if (rsc_type == RSC_VENDOR_CARVEOUT) {
+		struct fw_rsc_carveout *rsc_carveout = rsc;
+		struct rproc_mem_entry *mem;
+		struct reserved_mem *rmem;
+
+		rmem = of_reserved_mem_by_name(rproc, rsc_carveout->name);
+		if (!rmem)
+			return -ENOMEM;
+
+		if (rmem->size < rsc_carveout->len) {
+			dev_err(dev, "The reserved memory is too small\n");
+			return -ENOMEM;
+		}
+
+		mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)rmem->base,
+					   rsc_carveout->len, rsc_carveout->da,
+					   NULL, NULL, rsc_carveout->name);
+		if (!mem)
+			return -ENOMEM;
+
+		mem->flags = rsc_carveout->flags;
+		rsc_carveout->pa = rmem->base;
+		rproc_add_carveout(rproc, mem);
+	}
+
+	return RSC_HANDLED;
+}
+
+static const struct rproc_ops mtk_apu_rproc_ops = {
+	.prepare		= mtk_apu_rproc_prepare,
+	.unprepare		= mtk_apu_rproc_unprepare,
+	.start			= mtk_apu_rproc_start,
+	.stop			= mtk_apu_rproc_stop,
+	.kick			= mtk_apu_rproc_kick,
+	.load			= mtk_apu_load,
+	.parse_fw		= rproc_elf_load_rsc_table,
+	.find_loaded_rsc_table	= rproc_elf_find_loaded_rsc_table,
+	.sanity_check		= rproc_elf_sanity_check,
+	.get_boot_addr		= rproc_elf_get_boot_addr,
+	.handle_rsc		= mtk_apu_handle_rsc,
+};
+
+static irqreturn_t mtk_apu_rproc_callback(int irq, void *data)
+{
+	struct rproc *rproc = data;
+	struct mtk_apu_rproc *apu_rproc = (struct mtk_apu_rproc *)rproc->priv;
+
+	writel(1, apu_rproc->base + CORE_XTENSA_INT);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t handle_event(int irq, void *data)
+{
+	struct rproc *rproc = data;
+
+	rproc_vq_interrupt(rproc, 0);
+	rproc_vq_interrupt(rproc, 1);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_apu_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_apu_rproc *apu_rproc;
+	struct rproc *rproc;
+	struct resource *res;
+	int ret;
+
+	rproc = rproc_alloc(dev, dev_name(dev), &mtk_apu_rproc_ops, NULL,
+			    sizeof(*apu_rproc));
+	if (!rproc)
+		return -ENOMEM;
+
+	rproc->recovery_disabled = true;
+	rproc->has_iommu = false;
+	rproc->auto_boot = false;
+
+	apu_rproc = rproc->priv;
+	apu_rproc->dev = dev;
+	INIT_LIST_HEAD(&apu_rproc->mappings);
+
+	platform_set_drvdata(pdev, rproc);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	apu_rproc->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(apu_rproc->base)) {
+		dev_err(dev, "Failed to map mmio\n");
+		ret = PTR_ERR(apu_rproc->base);
+		goto free_rproc;
+	}
+
+	apu_rproc->irq = platform_get_irq(pdev, 0);
+	if (apu_rproc->irq < 0) {
+		ret = apu_rproc->irq;
+		goto free_rproc;
+	}
+
+	ret = devm_request_threaded_irq(dev, apu_rproc->irq,
+					mtk_apu_rproc_callback, handle_event,
+					IRQF_SHARED | IRQF_ONESHOT,
+					NULL, rproc);
+	if (ret) {
+		dev_err(dev, "devm_request_threaded_irq error: %d\n", ret);
+		goto free_rproc;
+	}
+
+	apu_rproc->clks[0].id = "ipu";
+	apu_rproc->clks[1].id = "axi";
+	apu_rproc->clks[2].id = "jtag";
+
+	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(apu_rproc->clks),
+				apu_rproc->clks);
+	if (ret) {
+		dev_err(dev, "Failed to get clocks\n");
+		goto free_rproc;
+	}
+
+	ret = rproc_add(rproc);
+	if (ret) {
+		dev_err(dev, "rproc_add failed: %d\n", ret);
+		goto free_rproc;
+	}
+
+	return 0;
+
+free_rproc:
+	rproc_free(rproc);
+
+	return ret;
+}
+
+static int mtk_apu_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct mtk_apu_rproc *apu_rproc = (struct mtk_apu_rproc *)rproc->priv;
+	struct device *dev = &pdev->dev;
+
+	disable_irq(apu_rproc->irq);
+
+	rproc_del(rproc);
+	of_reserved_mem_device_release(dev);
+	rproc_free(rproc);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_apu_rproc_of_match[] = {
+	{ .compatible = "mediatek,mt8183-apu", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_apu_rproc_of_match);
+
+static struct platform_driver mtk_apu_rproc_driver = {
+	.probe = mtk_apu_rproc_probe,
+	.remove = mtk_apu_rproc_remove,
+	.driver = {
+		.name = "mtk_apu-rproc",
+		.of_match_table = of_match_ptr(mtk_apu_rproc_of_match),
+	},
+};
+module_platform_driver(mtk_apu_rproc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Alexandre Bailon");
+MODULE_DESCRIPTION("MTK APU Remote Processor control driver");
-- 
2.31.1



From abailon at baylibre.com  Thu Aug 19 08:13:37 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Thu, 19 Aug 2021 17:13:37 +0200
Subject: [PATCH v3 1/4] dt bindings: remoteproc: Add bindings for MT8183 APU
In-Reply-To: <20210819151340.741565-1-abailon@baylibre.com>
References: <20210819151340.741565-1-abailon@baylibre.com>
Message-ID: <20210819151340.741565-2-abailon@baylibre.com>

This adds dt bindings for the APU present in the MT8183.

Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
---
 .../bindings/remoteproc/mtk,apu.yaml          | 118 ++++++++++++++++++
 1 file changed, 118 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,apu.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,apu.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,apu.yaml
new file mode 100644
index 0000000000000..d5da6be66610c
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,apu.yaml
@@ -0,0 +1,118 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+
+---
+$id: "http://devicetree.org/schemas/remoteproc/mtk,apu.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: MT8183 AI Processor Unit (APU) a.k.a. Vision Processor Unit (VPU)
+
+description:
+  This document defines the binding for the APU, a co-processor that could
+  offload the CPU for machine learning and neural network.
+
+maintainers:
+  - Alexandre Bailon <abailon at bayLibre.com>
+
+properties:
+  compatible:
+    const: mediatek,mt8183-apu
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    description:
+      Three clocks are expected for AXI, IPU and JTAG.
+      The JTAG clock seems to be required to run the DSP,
+      even when JTAG is not in use."
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: axi
+      - const: ipu
+      - const: jtag
+
+  iommus:
+    maxItems: 3
+
+  memory-region:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  pinctrl:
+    description: pinctrl handles, required to configure pins for JTAG.
+
+  pinctrl-names:
+    items:
+      - const: jtag
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - memory-region
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+    #include <dt-bindings/power/mt8183-power.h>
+
+    reserved-memory {
+      #address-cells = <1>;
+      #size-cells = <1>;
+      ranges;
+
+      vdev0vring0: vdev0vring0 {
+        compatible = "shared-dma-pool";
+        size = <0 0x00008000>;
+        no-map;
+      };
+
+      vdev0vring1: vdev0vring1 {
+        compatible = "shared-dma-pool";
+        size = <0 0x00008000>;
+        no-map;
+      };
+
+      vdev0buffer: vdev0buffer {
+        compatible = "shared-dma-pool";
+        size = <0 0x00100000>;
+        no-map;
+      };
+    };
+
+    apu0: apu at 19100000 {
+      compatible = "mediatek,mt8183-apu";
+      reg = <0x19180000 0x14000>;
+      interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_LOW>;
+
+      iommus = <&iommu M4U_PORT_IMG_IPUO>,
+         <&iommu M4U_PORT_IMG_IPU3O>,
+         <&iommu M4U_PORT_IMG_IPUI>;
+
+      clocks = <&ipu_core0 CLK_IPU_CORE0_AXI>,
+         <&ipu_core0 CLK_IPU_CORE0_IPU>,
+         <&ipu_core0 CLK_IPU_CORE0_JTAG>;
+
+      clock-names = "axi", "ipu", "jtag";
+
+      power-domains = <&scpsys MT8183_POWER_DOMAIN_VPU_CORE0>;
+      memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>;
+      memory-region-names = "vdev0buffer", "vdev0vring0", "vdev0vring1";
+    };
+...
-- 
2.31.1



From abailon at baylibre.com  Thu Aug 19 08:13:39 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Thu, 19 Aug 2021 17:13:39 +0200
Subject: [PATCH v3 3/4] remoteproc: mtk_vpu_rproc: Add support of JTAG
In-Reply-To: <20210819151340.741565-1-abailon@baylibre.com>
References: <20210819151340.741565-1-abailon@baylibre.com>
Message-ID: <20210819151340.741565-4-abailon@baylibre.com>

The DSP could be debugged using JTAG.
The support of JTAG could enabled at build time and it could be enabled
using debugfs.

Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
---
 drivers/remoteproc/Kconfig   |   9 +++
 drivers/remoteproc/mtk_apu.c | 147 ++++++++++++++++++++++++++++++++++-
 2 files changed, 155 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 6c106a6c3ad5d..cb1a2d9f4a9f6 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -63,6 +63,15 @@ config MTK_APU
 
 	  It's safe to say N here.
 
+config MTK_APU_JTAG
+	bool "Enable support of JTAG"
+	depends on MTK_APU
+	help
+	  Say y to enable support of JTAG.
+	  By default, JTAG will remain disabled until it is enabled using
+	  debugfs: remoteproc/remoteproc0/jtag. Write 1 to enable it and
+	  0 to disable it.
+
 config OMAP_REMOTEPROC
 	tristate "OMAP remoteproc support"
 	depends on ARCH_OMAP4 || SOC_OMAP5 || SOC_DRA7XX
diff --git a/drivers/remoteproc/mtk_apu.c b/drivers/remoteproc/mtk_apu.c
index 0e3f63987bd85..3daed38bb5188 100644
--- a/drivers/remoteproc/mtk_apu.c
+++ b/drivers/remoteproc/mtk_apu.c
@@ -5,12 +5,14 @@
 
 #include <linux/bitops.h>
 #include <linux/clk.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/iommu.h>
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/of_reserved_mem.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/remoteproc.h>
 
@@ -44,6 +46,11 @@
 #define CORE_DEFAULT1				(0x00000140)
 #define CORE_DEFAULT0_ARUSER_IDMA_USE_IOMMU	(0x10 << 0)
 #define CORE_DEFAULT0_AWUSER_IDMA_USE_IOMMU	(0x10 << 5)
+#define CORE_DEFAULT2				(0x00000144)
+#define CORE_DEFAULT2_DBG_EN			BIT(3)
+#define CORE_DEFAULT2_NIDEN			BIT(2)
+#define CORE_DEFAULT2_SPNIDEN			BIT(1)
+#define CORE_DEFAULT2_SPIDEN			BIT(0)
 #define CORE_XTENSA_ALTRESETVEC			(0x000001F8)
 
 #define RSC_VENDOR_CARVEOUT			(RSC_VENDOR_START + 1)
@@ -56,6 +63,13 @@ struct mtk_apu_rproc {
 	int irq;
 	struct clk_bulk_data clks[3];
 	struct list_head mappings;
+
+#ifdef CONFIG_MTK_APU_JTAG
+	struct pinctrl *pinctrl;
+	struct pinctrl_state *pinctrl_jtag;
+	bool jtag_enabled;
+	struct mutex jtag_mutex;
+#endif
 };
 
 static int mtk_apu_iommu_map(struct rproc *rproc, struct rproc_mem_entry *entry)
@@ -333,6 +347,133 @@ static irqreturn_t handle_event(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_MTK_APU_JTAG
+
+static int apu_enable_jtag(struct mtk_apu_rproc *apu_rproc)
+{
+	int ret = 0;
+
+	mutex_lock(&apu_rproc->jtag_mutex);
+	if (apu_rproc->jtag_enabled)
+		goto err_mutex_unlock;
+
+	writel(CORE_DEFAULT2_SPNIDEN | CORE_DEFAULT2_SPIDEN |
+		CORE_DEFAULT2_NIDEN | CORE_DEFAULT2_DBG_EN,
+		apu_rproc->base + CORE_DEFAULT2);
+
+	apu_rproc->jtag_enabled = 1;
+
+err_mutex_unlock:
+	mutex_unlock(&apu_rproc->jtag_mutex);
+
+	return ret;
+}
+
+static int apu_disable_jtag(struct mtk_apu_rproc *apu_rproc)
+{
+	int ret = 0;
+
+	mutex_lock(&apu_rproc->jtag_mutex);
+	if (!apu_rproc->jtag_enabled)
+		goto err_mutex_unlock;
+
+	writel(0, apu_rproc->base + CORE_DEFAULT2);
+
+	apu_rproc->jtag_enabled = 0;
+
+err_mutex_unlock:
+	mutex_unlock(&apu_rproc->jtag_mutex);
+
+	return ret;
+}
+
+static ssize_t rproc_jtag_read(struct file *filp, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	struct mtk_apu_rproc *apu_rproc = (struct mtk_apu_rproc *)rproc->priv;
+	char *buf = apu_rproc->jtag_enabled ? "enabled\n" : "disabled\n";
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
+}
+
+static ssize_t rproc_jtag_write(struct file *filp, const char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	struct mtk_apu_rproc *apu_rproc = (struct mtk_apu_rproc *)rproc->priv;
+	char buf[10];
+	int ret;
+
+	if (count < 1 || count > sizeof(buf))
+		return -EINVAL;
+
+	ret = copy_from_user(buf, user_buf, count);
+	if (ret)
+		return -EFAULT;
+
+	/* remove end of line */
+	if (buf[count - 1] == '\n')
+		buf[count - 1] = '\0';
+
+	if (!strncmp(buf, "enabled", count))
+		ret = apu_enable_jtag(apu_rproc);
+	else if (!strncmp(buf, "disabled", count))
+		ret = apu_disable_jtag(apu_rproc);
+	else
+		return -EINVAL;
+
+	return ret ? ret : count;
+}
+
+static const struct file_operations rproc_jtag_ops = {
+	.read = rproc_jtag_read,
+	.write = rproc_jtag_write,
+	.open = simple_open,
+};
+
+static int apu_jtag_probe(struct mtk_apu_rproc *apu_rproc)
+{
+	int ret;
+
+	if (!apu_rproc->rproc->dbg_dir)
+		return -ENODEV;
+
+	apu_rproc->pinctrl = devm_pinctrl_get(apu_rproc->dev);
+	if (IS_ERR(apu_rproc->pinctrl)) {
+		dev_warn(apu_rproc->dev, "Failed to find JTAG pinctrl\n");
+		return PTR_ERR(apu_rproc->pinctrl);
+	}
+
+	apu_rproc->pinctrl_jtag = pinctrl_lookup_state(apu_rproc->pinctrl,
+						       "jtag");
+	if (IS_ERR(apu_rproc->pinctrl_jtag))
+		return PTR_ERR(apu_rproc->pinctrl_jtag);
+
+	ret = pinctrl_select_state(apu_rproc->pinctrl,
+				   apu_rproc->pinctrl_jtag);
+	if (ret < 0)
+		return ret;
+
+	mutex_init(&apu_rproc->jtag_mutex);
+
+	debugfs_create_file("jtag", 0600, apu_rproc->rproc->dbg_dir,
+			    apu_rproc->rproc, &rproc_jtag_ops);
+
+	return 0;
+}
+#else
+static int apu_jtag_probe(struct mtk_apu_rproc *apu_rproc)
+{
+	return 0;
+}
+
+static int apu_disable_jtag(struct mtk_apu_rproc *apu_rproc)
+{
+	return 0;
+}
+#endif /* CONFIG_MTK_APU_JTAG */
+
 static int mtk_apu_rproc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -396,6 +537,10 @@ static int mtk_apu_rproc_probe(struct platform_device *pdev)
 		goto free_rproc;
 	}
 
+	ret = apu_jtag_probe(apu_rproc);
+	if (ret)
+		dev_warn(dev, "Failed to configure jtag\n");
+
 	return 0;
 
 free_rproc:
@@ -411,7 +556,7 @@ static int mtk_apu_rproc_remove(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 
 	disable_irq(apu_rproc->irq);
-
+	apu_disable_jtag(apu_rproc);
 	rproc_del(rproc);
 	of_reserved_mem_device_release(dev);
 	rproc_free(rproc);
-- 
2.31.1



From abailon at baylibre.com  Thu Aug 19 08:13:40 2021
From: abailon at baylibre.com (Alexandre Bailon)
Date: Thu, 19 Aug 2021 17:13:40 +0200
Subject: [PATCH v3 4/4] ARM64: mt8183: Add support of APU to mt8183
In-Reply-To: <20210819151340.741565-1-abailon@baylibre.com>
References: <20210819151340.741565-1-abailon@baylibre.com>
Message-ID: <20210819151340.741565-5-abailon@baylibre.com>

This adds the support of APU to mt8183.

Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
---
 .../boot/dts/mediatek/mt8183-pumpkin.dts      | 48 +++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      | 40 ++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
index ee912825cfc60..7fbed2b7bc6f8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
@@ -37,6 +37,42 @@ scp_mem_reserved: scp_mem_region at 50000000 {
 			reg = <0 0x50000000 0 0x2900000>;
 			no-map;
 		};
+
+		vdev0vring0: vdev0vring0 {
+			compatible = "shared-dma-pool";
+			size = <0 0x00008000>;
+			no-map;
+		};
+
+		vdev0vring1: vdev0vring1 {
+			compatible = "shared-dma-pool";
+			size = <0 0x00008000>;
+			no-map;
+		};
+
+		vdev0buffer: vdev0buffer {
+			compatible = "shared-dma-pool";
+			size = <0 0x00100000>;
+			no-map;
+		};
+
+		vdev1vring0: vdev1vring0 {
+			compatible = "shared-dma-pool";
+			size = <0 0x00008000>;
+			no-map;
+		};
+
+		vdev1vring1: vdev1vring1 {
+			compatible = "shared-dma-pool";
+			size = <0 0x00008000>;
+			no-map;
+		};
+
+		vdev1buffer: vdev1buffer {
+			compatible = "shared-dma-pool";
+			size = <0 0x00100000>;
+			no-map;
+		};
 	};
 
 	leds {
@@ -381,3 +417,15 @@ &scp {
 &dsi0 {
 	status = "disabled";
 };
+
+&apu0 {
+	memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>;
+	memory-region-names = "vdev0buffer", "vdev0vring0", "vdev0vring1";
+	status = "okay";
+};
+
+&apu1 {
+	memory-region = <&vdev1buffer>, <&vdev1vring0>, <&vdev1vring1>;
+	memory-region-names = "vdev0buffer", "vdev0vring0", "vdev0vring1";
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index f90df6439c088..bf3f315ad3b2f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1447,12 +1447,52 @@ ipu_adl: syscon at 19010000 {
 			#clock-cells = <1>;
 		};
 
+		apu0: apu at 0x19100000 {
+			compatible = "mediatek,mt8183-apu";
+			reg = <0 0x19180000 0 0x14000>;
+			interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_LOW>;
+
+			iommus = <&iommu M4U_PORT_IMG_IPUO>,
+				 <&iommu M4U_PORT_IMG_IPU3O>,
+				 <&iommu M4U_PORT_IMG_IPUI>;
+
+			clocks = <&ipu_core0 CLK_IPU_CORE0_AXI>,
+				 <&ipu_core0 CLK_IPU_CORE0_IPU>,
+				 <&ipu_core0 CLK_IPU_CORE0_JTAG>;
+
+			clock-names = "axi", "ipu", "jtag";
+
+			power-domains = <&spm MT8183_POWER_DOMAIN_VPU_CORE0>;
+
+			status = "disabled";
+		};
+
 		ipu_core0: syscon at 19180000 {
 			compatible = "mediatek,mt8183-ipu_core0", "syscon";
 			reg = <0 0x19180000 0 0x1000>;
 			#clock-cells = <1>;
 		};
 
+		apu1: apu at 19200000 {
+			compatible = "mediatek,mt8183-apu";
+			reg = <0 0x19280000 0 0x14000>;
+			interrupts = <GIC_SPI 293 IRQ_TYPE_LEVEL_LOW>;
+
+			iommus = <&iommu M4U_PORT_CAM_IPUO>,
+				 <&iommu M4U_PORT_CAM_IPU2O>,
+				 <&iommu M4U_PORT_CAM_IPU3O>;
+
+			clocks = <&ipu_core0 CLK_IPU_CORE1_AXI>,
+				 <&ipu_core0 CLK_IPU_CORE1_IPU>,
+				 <&ipu_core0 CLK_IPU_CORE1_JTAG>;
+
+			clock-names = "axi", "ipu", "jtag";
+
+			power-domains = <&spm MT8183_POWER_DOMAIN_VPU_CORE1>;
+
+			status = "disabled";
+		};
+
 		ipu_core1: syscon at 19280000 {
 			compatible = "mediatek,mt8183-ipu_core1", "syscon";
 			reg = <0 0x19280000 0 0x1000>;
-- 
2.31.1



From chunkuang.hu at kernel.org  Thu Aug 19 08:12:57 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 19 Aug 2021 23:12:57 +0800
Subject: [PATCH v8 07/13] soc: mediatek: add mtk-mutex support for mt8195
 vdosys0
In-Reply-To: <20210819022327.13040-8-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-8-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_8xGRJmFaEEsZoJs22zfqm+CO0pFesThwK6K0bknNBtoQ@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
>
> Add mtk-mutex support for mt8195 vdosys0.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-mutex.c | 98 +++++++++++++++++++++++++++++++-
>  1 file changed, 95 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
> index 2e4bcc300576..c177156ee2fa 100644
> --- a/drivers/soc/mediatek/mtk-mutex.c
> +++ b/drivers/soc/mediatek/mtk-mutex.c
> @@ -17,6 +17,9 @@
>  #define MT8183_MUTEX0_MOD0                     0x30
>  #define MT8183_MUTEX0_SOF0                     0x2c
>
> +#define MT8195_DISP_MUTEX0_MOD0                        0x30
> +#define MT8195_DISP_MUTEX0_SOF                 0x2c
> +
>  #define DISP_REG_MUTEX_EN(n)                   (0x20 + 0x20 * (n))
>  #define DISP_REG_MUTEX(n)                      (0x24 + 0x20 * (n))
>  #define DISP_REG_MUTEX_RST(n)                  (0x28 + 0x20 * (n))
> @@ -67,6 +70,36 @@
>  #define MT8173_MUTEX_MOD_DISP_PWM1             24
>  #define MT8173_MUTEX_MOD_DISP_OD               25
>
> +#define MT8195_MUTEX_MOD_DISP_OVL0             0
> +#define MT8195_MUTEX_MOD_DISP_WDMA0            1
> +#define MT8195_MUTEX_MOD_DISP_RDMA0            2
> +#define MT8195_MUTEX_MOD_DISP_COLOR0           3
> +#define MT8195_MUTEX_MOD_DISP_CCORR0           4
> +#define MT8195_MUTEX_MOD_DISP_AAL0             5
> +#define MT8195_MUTEX_MOD_DISP_GAMMA0           6
> +#define MT8195_MUTEX_MOD_DISP_DITHER0          7
> +#define MT8195_MUTEX_MOD_DISP_DSI0             8
> +#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0  9
> +#define MT8195_MUTEX_MOD_DISP_OVL1             10
> +#define MT8195_MUTEX_MOD_DISP_WDMA1            11
> +#define MT8195_MUTEX_MOD_DISP_RDMA1            12
> +#define MT8195_MUTEX_MOD_DISP_COLOR1           13
> +#define MT8195_MUTEX_MOD_DISP_CCORR1           14
> +#define MT8195_MUTEX_MOD_DISP_AAL1             15
> +#define MT8195_MUTEX_MOD_DISP_GAMMA1           16
> +#define MT8195_MUTEX_MOD_DISP_DITHER1          17
> +#define MT8195_MUTEX_MOD_DISP_DSI1             18
> +#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1  19
> +#define MT8195_MUTEX_MOD_DISP_VPP_MERGE                20
> +#define MT8195_MUTEX_MOD_DISP_DP_INTF0         21
> +#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0   22
> +#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1   23
> +#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2   24
> +#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3   25
> +#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4   26
> +#define MT8195_MUTEX_MOD_DISP_PWM0             27
> +#define MT8195_MUTEX_MOD_DISP_PWM1             28
> +
>  #define MT2712_MUTEX_MOD_DISP_PWM2             10
>  #define MT2712_MUTEX_MOD_DISP_OVL0             11
>  #define MT2712_MUTEX_MOD_DISP_OVL1             12
> @@ -101,12 +134,27 @@
>  #define MT2712_MUTEX_SOF_DSI3                  6
>  #define MT8167_MUTEX_SOF_DPI0                  2
>  #define MT8167_MUTEX_SOF_DPI1                  3
> +
>  #define MT8183_MUTEX_SOF_DSI0                  1
>  #define MT8183_MUTEX_SOF_DPI0                  2
>
>  #define MT8183_MUTEX_EOF_DSI0                  (MT8183_MUTEX_SOF_DSI0 << 6)
>  #define MT8183_MUTEX_EOF_DPI0                  (MT8183_MUTEX_SOF_DPI0 << 6)
>
> +#define MT8195_MUTEX_SOF_DSI0                  1
> +#define MT8195_MUTEX_SOF_DSI1                  2
> +#define MT8195_MUTEX_SOF_DP_INTF0              3
> +#define MT8195_MUTEX_SOF_DP_INTF1              4
> +#define MT8195_MUTEX_SOF_DPI0                  6 /* for HDMI_TX */
> +#define MT8195_MUTEX_SOF_DPI1                  5 /* for digital video out */
> +
> +#define MT8195_MUTEX_EOF_DSI0                  (MT8195_MUTEX_SOF_DSI0 << 7)
> +#define MT8195_MUTEX_EOF_DSI1                  (MT8195_MUTEX_SOF_DSI1 << 7)
> +#define MT8195_MUTEX_EOF_DP_INTF0              (MT8195_MUTEX_SOF_DP_INTF0 << 7)
> +#define MT8195_MUTEX_EOF_DP_INTF1              (MT8195_MUTEX_SOF_DP_INTF1 << 7)
> +#define MT8195_MUTEX_EOF_DPI0                  (MT8195_MUTEX_SOF_DPI0 << 7)
> +#define MT8195_MUTEX_EOF_DPI1                  (MT8195_MUTEX_SOF_DPI1 << 7)
> +
>  struct mtk_mutex {
>         int id;
>         bool claimed;
> @@ -120,6 +168,9 @@ enum mtk_mutex_sof_id {
>         MUTEX_SOF_DPI1,
>         MUTEX_SOF_DSI2,
>         MUTEX_SOF_DSI3,
> +       MUTEX_SOF_DP_INTF0,
> +       MUTEX_SOF_DP_INTF1,
> +       DDP_MUTEX_SOF_MAX,
>  };
>
>  struct mtk_mutex_data {
> @@ -214,7 +265,23 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>         [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
>  };
>
> -static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> +static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> +       [DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
> +       [DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
> +       [DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
> +       [DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
> +       [DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
> +       [DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
> +       [DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
> +       [DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
> +       [DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
> +       [DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
> +       [DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
> +       [DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
> +       [DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
> +};
> +
> +static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
>         [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
>         [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
>         [MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
> @@ -224,7 +291,7 @@ static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
>         [MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
>  };
>
> -static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> +static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
>         [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
>         [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
>         [MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
> @@ -232,12 +299,24 @@ static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
>  };
>
>  /* Add EOF setting so overlay hardware can receive frame done irq */
> -static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> +static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
>         [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
>         [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
>         [MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
>  };
>
> +static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
> +       [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> +       [MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
> +       [MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
> +       [MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
> +       [MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
> +       [MUTEX_SOF_DP_INTF0] =
> +               MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
> +       [MUTEX_SOF_DP_INTF1] =
> +               MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,

Why do you or EOF?

Regards,
Chun-Kuang.

> +};
> +
>  static const struct mtk_mutex_data mt2701_mutex_driver_data = {
>         .mutex_mod = mt2701_mutex_mod,
>         .mutex_sof = mt2712_mutex_sof,
> @@ -275,6 +354,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
>         .no_clk = true,
>  };
>
> +static const struct mtk_mutex_data mt8195_mutex_driver_data = {
> +       .mutex_mod = mt8195_mutex_mod,
> +       .mutex_sof = mt8195_mutex_sof,
> +       .mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
> +       .mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
> +};
> +
>  struct mtk_mutex *mtk_mutex_get(struct device *dev)
>  {
>         struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
> @@ -347,6 +433,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
>         case DDP_COMPONENT_DPI1:
>                 sof_id = MUTEX_SOF_DPI1;
>                 break;
> +       case DDP_COMPONENT_DP_INTF0:
> +               sof_id = MUTEX_SOF_DP_INTF0;
> +               break;

How about MUTEX_SOF_DP_INTF1?

>         default:
>                 if (mtx->data->mutex_mod[id] < 32) {
>                         offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
> @@ -386,6 +475,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
>         case DDP_COMPONENT_DSI3:
>         case DDP_COMPONENT_DPI0:
>         case DDP_COMPONENT_DPI1:
> +       case DDP_COMPONENT_DP_INTF0:

Ditto.

Regards,
Chun-Kuang.

>                 writel_relaxed(MUTEX_SOF_SINGLE_MODE,
>                                mtx->regs +
>                                DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
> @@ -507,6 +597,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
>           .data = &mt8173_mutex_driver_data},
>         { .compatible = "mediatek,mt8183-disp-mutex",
>           .data = &mt8183_mutex_driver_data},
> +       { .compatible = "mediatek,mt8195-disp-mutex",
> +         .data = &mt8195_mutex_driver_data},
>         {},
>  };
>  MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
> --
> 2.18.0
>


From chunkuang.hu at kernel.org  Thu Aug 19 08:14:11 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 19 Aug 2021 23:14:11 +0800
Subject: [PATCH v8 08/13] drm/mediatek: remove unused define in
 mtk_drm_ddp_comp.c
In-Reply-To: <20210819022327.13040-9-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-9-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_9_YwZH4dLyVXmW7irQ8WJaKFzT+72Pgczu1X3u4jvnbg@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
>
> Remove the unsed define in mtk_drm_ddp_comp.c

Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 10 ----------
>  1 file changed, 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 75bc00e17fc4..aaa7450b3e2b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -21,8 +21,6 @@
>  #include "mtk_drm_crtc.h"
>
>  #define DISP_OD_EN                             0x0000
> -#define DISP_OD_INTEN                          0x0008
> -#define DISP_OD_INTSTA                         0x000c
>  #define DISP_OD_CFG                            0x0020
>  #define DISP_OD_SIZE                           0x0030
>  #define DISP_DITHER_5                          0x0114
> @@ -42,8 +40,6 @@
>  #define DITHER_ENGINE_EN                       BIT(1)
>  #define DISP_DITHER_SIZE                       0x0030
>
> -#define LUT_10BIT_MASK                         0x03ff
> -
>  #define OD_RELAYMODE                           BIT(0)
>
>  #define UFO_BYPASS                             BIT(2)
> @@ -52,18 +48,12 @@
>
>  #define DISP_DITHERING                         BIT(2)
>  #define DITHER_LSB_ERR_SHIFT_R(x)              (((x) & 0x7) << 28)
> -#define DITHER_OVFLW_BIT_R(x)                  (((x) & 0x7) << 24)
>  #define DITHER_ADD_LSHIFT_R(x)                 (((x) & 0x7) << 20)
> -#define DITHER_ADD_RSHIFT_R(x)                 (((x) & 0x7) << 16)
>  #define DITHER_NEW_BIT_MODE                    BIT(0)
>  #define DITHER_LSB_ERR_SHIFT_B(x)              (((x) & 0x7) << 28)
> -#define DITHER_OVFLW_BIT_B(x)                  (((x) & 0x7) << 24)
>  #define DITHER_ADD_LSHIFT_B(x)                 (((x) & 0x7) << 20)
> -#define DITHER_ADD_RSHIFT_B(x)                 (((x) & 0x7) << 16)
>  #define DITHER_LSB_ERR_SHIFT_G(x)              (((x) & 0x7) << 12)
> -#define DITHER_OVFLW_BIT_G(x)                  (((x) & 0x7) << 8)
>  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
> -#define DITHER_ADD_RSHIFT_G(x)                 (((x) & 0x7) << 0)
>
>  struct mtk_ddp_comp_dev {
>         struct clk *clk;
> --
> 2.18.0
>


From chunkuang.hu at kernel.org  Thu Aug 19 08:17:25 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 19 Aug 2021 23:17:25 +0800
Subject: [PATCH v8 09/13] drm/mediatek: rename the define of register
 offset
In-Reply-To: <20210819022327.13040-10-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-10-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY__WFzVdNcS_dorSs+-H-C=wY6pd4T6R30hGBCJVtSbrdg@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
>
> Add DISP_REG prefix for the define of register offset to
> make the difference from the define of register value.
>

Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 57 +++++++++++----------
>  1 file changed, 29 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index aaa7450b3e2b..93beb980414f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -20,25 +20,25 @@
>  #include "mtk_drm_ddp_comp.h"
>  #include "mtk_drm_crtc.h"
>
> -#define DISP_OD_EN                             0x0000
> -#define DISP_OD_CFG                            0x0020
> -#define DISP_OD_SIZE                           0x0030
> -#define DISP_DITHER_5                          0x0114
> -#define DISP_DITHER_7                          0x011c
> -#define DISP_DITHER_15                         0x013c
> -#define DISP_DITHER_16                         0x0140
> +#define DISP_REG_OD_EN                         0x0000
> +#define DISP_REG_OD_CFG                                0x0020
> +#define DISP_REG_OD_SIZE                       0x0030
> +#define DISP_REG_DITHER_5                      0x0114
> +#define DISP_REG_DITHER_7                      0x011c
> +#define DISP_REG_DITHER_15                     0x013c
> +#define DISP_REG_DITHER_16                     0x0140
>
>  #define DISP_REG_UFO_START                     0x0000
>
> -#define DISP_AAL_EN                            0x0000
> -#define DISP_AAL_SIZE                          0x0030
> +#define DISP_REG_AAL_EN                                0x0000
> +#define DISP_REG_AAL_SIZE                      0x0030
>
> -#define DISP_DITHER_EN                         0x0000
> +#define DISP_REG_DITHER_EN                     0x0000
>  #define DITHER_EN                              BIT(0)
> -#define DISP_DITHER_CFG                                0x0020
> +#define DISP_REG_DITHER_CFG                    0x0020
>  #define DITHER_RELAY_MODE                      BIT(0)
>  #define DITHER_ENGINE_EN                       BIT(1)
> -#define DISP_DITHER_SIZE                       0x0030
> +#define DISP_REG_DITHER_SIZE                   0x0030
>
>  #define OD_RELAYMODE                           BIT(0)
>
> @@ -129,19 +129,19 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
>                 return;
>
>         if (bpc >= MTK_MIN_BPC) {
> -               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
> -               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
> +               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_5);
> +               mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_7);
>                 mtk_ddp_write(cmdq_pkt,
>                               DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
>                               DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
>                               DITHER_NEW_BIT_MODE,
> -                             cmdq_reg, regs, DISP_DITHER_15);
> +                             cmdq_reg, regs, DISP_REG_DITHER_15);
>                 mtk_ddp_write(cmdq_pkt,
>                               DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
>                               DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
>                               DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
>                               DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
> -                             cmdq_reg, regs, DISP_DITHER_16);
> +                             cmdq_reg, regs, DISP_REG_DITHER_16);
>                 mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg);
>         }
>  }
> @@ -161,16 +161,16 @@ static void mtk_od_config(struct device *dev, unsigned int w,
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE);
> -       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG);
> -       mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
> +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
> +       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
> +       mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
>  }
>
>  static void mtk_od_start(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(1, priv->regs + DISP_OD_EN);
> +       writel(1, priv->regs + DISP_REG_OD_EN);
>  }
>
>  static void mtk_ufoe_start(struct device *dev)
> @@ -186,7 +186,7 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
> +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_AAL_SIZE);
>  }
>
>  static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)
> @@ -200,14 +200,14 @@ static void mtk_aal_start(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(AAL_EN, priv->regs + DISP_AAL_EN);
> +       writel(AAL_EN, priv->regs + DISP_REG_AAL_EN);
>  }
>
>  static void mtk_aal_stop(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel_relaxed(0x0, priv->regs + DISP_AAL_EN);
> +       writel_relaxed(0x0, priv->regs + DISP_REG_AAL_EN);
>  }
>
>  static void mtk_dither_config(struct device *dev, unsigned int w,
> @@ -216,9 +216,10 @@ static void mtk_dither_config(struct device *dev, unsigned int w,
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_DITHER_SIZE);
> -       mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, DISP_DITHER_CFG);
> -       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_DITHER_CFG,
> +       mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE);
> +       mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
> +                     DISP_REG_DITHER_CFG);
> +       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
>                               DITHER_ENGINE_EN, cmdq_pkt);
>  }
>
> @@ -226,14 +227,14 @@ static void mtk_dither_start(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
> +       writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
>  }
>
>  static void mtk_dither_stop(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
> +       writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
>  }
>
>  static const struct mtk_ddp_comp_funcs ddp_aal = {
> --
> 2.18.0
>


From zajec5 at gmail.com  Thu Aug 19 08:25:52 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 17:25:52 +0200
Subject: [PATCH] dt-bindings: mfd: add Broadcom's MISC block
Message-ID: <20210819152552.23784-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Broadcom's MISC is an MFD hardware block used on some of their SoCs like
bcm63xx and bcm4908. At this point only PCIe reset is fully understood
and documented. More functions may be added later.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
Broadcom's BCM4908 struct with MISC block registers:

typedef struct Misc {
   uint32 miscStrapBus; /* 0x00 */
   uint32 miscStrapOverride;     /* 0x04 */
   uint32 miscSoftwareDebug[6];  /* 0x08 */
   uint32 miscWDResetCtrl;       /* 0x20 */
   uint32 miscSoftwareDebugNW[2];/* 0x24 */
   uint32 miscSoftResetB;        /* 0x2c */
   uint32 miscQAMPllStatus;      /* 0x30 */
   uint32 miscRsvd1;             /* 0x34 */
   uint32 miscSpiMasterCtrl;     /* 0x38 */
   uint32 miscAltBootVector;     /* 0x3c */
   uint32 miscPeriphCtrl;        /* 0x40 */
   uint32 miscPCIECtrl;          /* 0x44 */
   uint32 miscAdsl_clock_sample; /* 0x48 */
   uint32 miscRngCtrl;           /* 0x4c */
   uint32 miscMbox_data[4];      /* 0x50 */
   uint32 miscMbox_ctrl;         /* 0x60 */
   uint32 miscxMIIPadCtrl[4];    /* 0x64 */
   uint32 miscxMIIPullCtrl[4];    /* 0x74 */
   uint32 miscWDResetEn;          /* 0x84 */
   uint32 miscBootOverlayEn;      /* 0x88 */
   uint32 miscSGMIIFiberDetect;   /* 0x8c */
   uint32 miscUniMacCtrl;         /* 0x90 */
   uint32 miscMaskUBUSErr;        /* 0x94 */
   uint32 miscTOSsync;            /* 0x98 */
   uint32 miscPM0_1_status;       /* 0x9c */
   uint32 miscPM2_3_status;       /* 0xa0 */
   uint32 miscSGB_status;         /* 0xa4 */
   uint32 miscPM0_1_config;       /* 0xa8 */
   uint32 miscPM2_3_config;       /* 0xac */
   uint32 miscSGB_config;         /* 0xb0 */
   uint32 miscPM0_1_tmon_config;  /* 0xb4 */
   uint32 miscPM2_3_tmon_config;  /* 0xb8 */
   uint32 miscSGB_tmon_config;    /* 0xbc */
   uint32 miscMDIOmasterSelect;   /* 0xc0 */
   uint32 miscUSIMCtrl;           /* 0xc4 */
   uint32 miscUSIMPadCtrl;        /* 0xc8 */
   uint32 miscPerSpareReg[3];     /* 0xcc - 0xd4 */
   uint32 miscDgSensePadCtrl;     /* 0xd8 */
   uint32 miscPeriphMiscCtrl;     /* 0xdc */
   uint32 miscPeriphMiscStat;     /* 0xe0 */
} Misc;
---
 .../devicetree/bindings/mfd/brcm,misc.yaml    | 60 +++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/brcm,misc.yaml

diff --git a/Documentation/devicetree/bindings/mfd/brcm,misc.yaml b/Documentation/devicetree/bindings/mfd/brcm,misc.yaml
new file mode 100644
index 000000000000..cff7d772a7db
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/brcm,misc.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/brcm,misc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom's MISC block
+
+maintainers:
+  - Rafa? Mi?ecki <rafal at milecki.pl>
+
+description: |
+  Broadcom's MISC is a hardware block used on some SoCs (e.g. bcm63xx and
+  bcm4908). It's used to implement some simple functions like a watchdog, PCIe
+  reset, UniMAC control and more.
+
+properties:
+  compatible:
+    items:
+      - const: brcm,misc
+      - const: simple-mfd
+
+  reg:
+    description: MISC block registers
+
+  ranges: true
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+patternProperties:
+  '^reset-controller@[a-f0-9]+$':
+    $ref: ../reset/brcm,bcm4908-misc-pcie-reset.yaml
+
+additionalProperties: false
+
+required:
+  - reg
+  - '#address-cells'
+  - '#size-cells'
+
+examples:
+  - |
+    misc at ff802600 {
+        compatible = "brcm,misc", "simple-mfd";
+        reg = <0xff802600 0xe4>;
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0x0 0x0 0xe4>;
+
+        reset-controller at 44 {
+            compatible = "brcm,bcm4908-misc-pcie-reset";
+            reg = <0x44 0x4>;
+            #reset-cells = <1>;
+        };
+    };
-- 
2.26.2



From bigeasy at linutronix.de  Thu Aug 19 08:35:37 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Thu, 19 Aug 2021 17:35:37 +0200
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
Message-ID: <20210819153537.4vxr54rjrj7x5tzt@linutronix.de>

On 2021-08-18 15:46:51 [-0700], Paul E. McKenney wrote:
?
> > +	/*
> > +	 * Ideally these sequences would be detected in debug builds
> > +	 * (regardless of RT), but until then don't stop testing
> > +	 * them on non-RT.
> > +	 */
> > +	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> > +		/*
> > +		 * Can't disable bh in atomic context if bh was already
> > +		 * disabled by another task on the same CPU. Instead of
> > +		 * attempting to track this, just avoid disabling bh in atomic
> > +		 * context.
> > +		 */
> > +		mask &= ~atomic_bhs;
> 
> At some point, we will need to test disabling bh in atomic context,
> correct?  Or am I missing something here?

Ideally there is no disabling bh in atomic context (on RT). Having it
breaks some fundamental rules how softirq handling and the bh related
synchronisation is implemented. Given that the softirq handler is
invoked in thread context and preemption is not disabled as part of
spin_lock(), rcu_read_lock(), and interrupts are in general not disabled
in the interrupt handler or spin_lock_irq() there is close to zero
chance of disabling bh in atomic context on RT.

In reality there is (of course) something that needs to disable bh in
atomic context and it happens only during boot up (or from idle unless
I'm mistaken).
It is required that bh disable and its enable part (later) happens in
the same context that is if bh has been disabled in preemptible context
it must not be enabled in atomic context (and vice versa).

The bottom line is that there must not be a local_bh_disable() in atomic
context if another (preempted) task already did a local_bh_disable() on
the same CPU, like in the following scenario on one CPU:

TASK A                      TASK B
 local_bh_disable();
 ? preempted
                           preempt_disable();
			   local_bh_disable();

Then this breaks the synchronisation that is otherwise provided by
local_bh_disable(). Without that preempt_disable() TASK B would block
(and wait) until TASK A completes its BH section. In atomic context it
is not possible and therefore not allowed.

Sebastian


From zajec5 at gmail.com  Thu Aug 19 08:37:02 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 17:37:02 +0200
Subject: [PATCH] arm64: dts: broadcom: bcm4908: Fix UART clock name
Message-ID: <20210819153702.24394-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

According to the binding the correct clock name is "refclk".

Fixes: 2961f69f151c ("arm64: dts: broadcom: add BCM4908 and Asus GT-AC5300 early DTS files")
Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
index 87076770f4bc..984c737fa627 100644
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
@@ -292,7 +292,7 @@ uart0: serial at 640 {
 			reg = <0x640 0x18>;
 			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&periph_clk>;
-			clock-names = "periph";
+			clock-names = "refclk";
 			status = "okay";
 		};
 
-- 
2.26.2



From bigeasy at linutronix.de  Thu Aug 19 08:39:27 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Thu, 19 Aug 2021 17:39:27 +0200
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
Message-ID: <20210819153927.clqxr4f7qegpflbr@linutronix.de>

On 2021-08-18 15:46:51 [-0700], Paul E. McKenney wrote:
> > ---
> > --- a/kernel/rcu/rcutorture.c
> > +++ b/kernel/rcu/rcutorture.c
> > @@ -61,10 +61,13 @@ MODULE_AUTHOR("Paul E. McKenney <paulmck
?
> > -	/* Next, remove old protection, irq first due to bh conflict. */
> > +	/*
> > +	 * Next, remove old protection, in decreasing order of strength
> > +	 * to avoid unlock paths that aren't safe in the stronger
> > +	 * context.  Disable preemption around the ATOM enables in
> > +	 * case the context was only atomic due to IRQ disabling.
> > +	 */
> > +	preempt_disable();
> >  	if (statesold & RCUTORTURE_RDR_IRQ)
> >  		local_irq_enable();
> > -	if (statesold & RCUTORTURE_RDR_BH)
> > +	if (statesold & RCUTORTURE_RDR_ATOM_BH)
> >  		local_bh_enable();
> > +	if (statesold & RCUTORTURE_RDR_ATOM_RBH)
> > +		rcu_read_unlock_bh();
> > +	preempt_enable();
> 
> The addition of preempt_enable() here prevents rcutorture from covering
> an important part of the mainline RCU state space, namely when an RCU
> read-side section ends with just local_irq_enable().  This situation
> is a challenge for RCU because it must indirectly detect the end of the
> critical section.
> 
> Would it work for RT if the preempt_enable() and preempt_disable()
> were executed only if either RT on the one hand or statesold has the
> RCUTORTURE_RDR_ATOM_BH or RCUTORTURE_RDR_ATOM_RBH bit set on the other?

Now that I stared at it some more (and it stared briefly back at me) I
couldn't explain why we need this and that piece of the patch so I came
up with following which I can explain:

diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 40ef5417d9545..5c8b31b7eff03 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1432,28 +1432,34 @@ static void rcutorture_one_extend(int *readstate, int newstate,
 	/* First, put new protection in place to avoid critical-section gap. */
 	if (statesnew & RCUTORTURE_RDR_BH)
 		local_bh_disable();
+	if (statesnew & RCUTORTURE_RDR_RBH)
+		rcu_read_lock_bh();
 	if (statesnew & RCUTORTURE_RDR_IRQ)
 		local_irq_disable();
 	if (statesnew & RCUTORTURE_RDR_PREEMPT)
 		preempt_disable();
-	if (statesnew & RCUTORTURE_RDR_RBH)
-		rcu_read_lock_bh();
 	if (statesnew & RCUTORTURE_RDR_SCHED)
 		rcu_read_lock_sched();
 	if (statesnew & RCUTORTURE_RDR_RCU)
 		idxnew = cur_ops->readlock() << RCUTORTURE_RDR_SHIFT;
 
-	/* Next, remove old protection, irq first due to bh conflict. */
+	/*
+	 * Next, remove old protection, in decreasing order of strength
+	 * to avoid unlock paths that aren't safe in the stronger
+	 * context. Namely: BH can not be enabled with disabled interrupts.
+	 * Additionally PREEMPT_RT requires that BH is enabled in preemptible
+	 * context.
+	 */
 	if (statesold & RCUTORTURE_RDR_IRQ)
 		local_irq_enable();
-	if (statesold & RCUTORTURE_RDR_BH)
-		local_bh_enable();
 	if (statesold & RCUTORTURE_RDR_PREEMPT)
 		preempt_enable();
-	if (statesold & RCUTORTURE_RDR_RBH)
-		rcu_read_unlock_bh();
 	if (statesold & RCUTORTURE_RDR_SCHED)
 		rcu_read_unlock_sched();
+	if (statesold & RCUTORTURE_RDR_BH)
+		local_bh_enable();
+	if (statesold & RCUTORTURE_RDR_RBH)
+		rcu_read_unlock_bh();
 	if (statesold & RCUTORTURE_RDR_RCU) {
 		bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);
 
@@ -1496,6 +1502,9 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
 	int mask = rcutorture_extend_mask_max();
 	unsigned long randmask1 = torture_random(trsp) >> 8;
 	unsigned long randmask2 = randmask1 >> 3;
+	unsigned long preempts = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;
+	unsigned long preempts_irq = preempts | RCUTORTURE_RDR_IRQ;
+	unsigned long bhs = RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
 
 	WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT);
 	/* Mostly only one bit (need preemption!), sometimes lots of bits. */
@@ -1503,11 +1512,37 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
 		mask = mask & randmask2;
 	else
 		mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS));
-	/* Can't enable bh w/irq disabled. */
-	if ((mask & RCUTORTURE_RDR_IRQ) &&
-	    ((!(mask & RCUTORTURE_RDR_BH) && (oldmask & RCUTORTURE_RDR_BH)) ||
-	     (!(mask & RCUTORTURE_RDR_RBH) && (oldmask & RCUTORTURE_RDR_RBH))))
-		mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
+
+	/*
+	 * Can't enable bh w/irq disabled.
+	 */
+	if (mask & RCUTORTURE_RDR_IRQ)
+		mask |= oldmask & bhs;
+
+	/*
+	 * Ideally these sequences would be detected in debug builds
+	 * (regardless of RT), but until then don't stop testing
+	 * them on non-RT.
+	 */
+	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
+		/*
+		 * Can't release the outermost rcu lock in an irq disabled
+		 * section without preemption also being disabled, if irqs
+		 * had ever been enabled during this RCU critical section
+		 * (could leak a special flag and delay reporting the qs).
+		 */
+		if ((oldmask & RCUTORTURE_RDR_RCU) &&
+		    (mask & RCUTORTURE_RDR_IRQ) &&
+		    !(mask & preempts))
+			mask |= RCUTORTURE_RDR_RCU;
+
+		/* Can't modify bh in atomic context */
+		if (oldmask & preempts_irq)
+			mask &= ~bhs;
+		if ((oldmask | mask) & preempts_irq)
+			mask |= oldmask & bhs;
+	}
+
 	return mask ?: RCUTORTURE_RDR_RCU;
 }
 


From arnd at kernel.org  Thu Aug 19 08:44:54 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 19 Aug 2021 17:44:54 +0200
Subject: [PATCH][PULL/direct] ARM: s3c: delete unneed local variable
 "delay"
In-Reply-To: <20210818204422.17919-1-krzysztof.kozlowski@canonical.com>
References: <20210818204422.17919-1-krzysztof.kozlowski@canonical.com>
Message-ID: <162938788185.467628.13192922419725983504.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 18 Aug 2021 22:44:22 +0200, Krzysztof Kozlowski wrote:
> "delay" variable on line 79 can be deleted by returning "0" on line 88.

Applied to for-next, thanks!

[1/1] ARM: s3c: delete unneed local variable "delay"
      commit: 319a1b58f6c7432345f13383b26c8c10e7eb1dda

       Arnd


From arnd at kernel.org  Thu Aug 19 08:44:55 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 19 Aug 2021 17:44:55 +0200
Subject: [GIT PULL] Fix for omap gpt12 timer error handling
In-Reply-To: <pull-1629354796-830948@atomide.com>
References: <pull-1629354796-830948@atomide.com>
Message-ID: <162938787885.467628.7575175058025149397.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Thu, 19 Aug 2021 09:34:36 +0300, Tony Lindgren wrote:
> The following changes since commit 353b7a55dcaf5fb8758e09ebe2ddf5f3adbac7c5:
> 
>   Merge branch 'fixes-v5.14' into fixes (2021-07-27 11:25:08 +0300)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.14/gpt12-fix-signed
> 
> [...]

Merged into for-next, thanks!

merge commit: 1e16a40211208d2d6e217e5013607219f4272dff

       Arnd


From bigeasy at linutronix.de  Thu Aug 19 08:47:08 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Thu, 19 Aug 2021 17:47:08 +0200
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20210819153927.clqxr4f7qegpflbr@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
 <20210819153927.clqxr4f7qegpflbr@linutronix.de>
Message-ID: <20210819154708.3efz6jtgwtuhpeds@linutronix.de>

On 2021-08-19 17:39:29 [+0200], To Paul E. McKenney wrote:
> up with following which I can explain:
> 
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index 40ef5417d9545..5c8b31b7eff03 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -1432,28 +1432,34 @@ static void rcutorture_one_extend(int *readstate, int newstate,
>  	/* First, put new protection in place to avoid critical-section gap. */
>  	if (statesnew & RCUTORTURE_RDR_BH)
>  		local_bh_disable();
> +	if (statesnew & RCUTORTURE_RDR_RBH)
> +		rcu_read_lock_bh();
>  	if (statesnew & RCUTORTURE_RDR_IRQ)
>  		local_irq_disable();
>  	if (statesnew & RCUTORTURE_RDR_PREEMPT)
>  		preempt_disable();
> -	if (statesnew & RCUTORTURE_RDR_RBH)
> -		rcu_read_lock_bh();
>  	if (statesnew & RCUTORTURE_RDR_SCHED)
>  		rcu_read_lock_sched();
>  	if (statesnew & RCUTORTURE_RDR_RCU)
>  		idxnew = cur_ops->readlock() << RCUTORTURE_RDR_SHIFT;

So the ordering in the enable and disable part regarding BH is
important. First BH, then preemption or IRQ.

> -	/* Next, remove old protection, irq first due to bh conflict. */
> +	/*
> +	 * Next, remove old protection, in decreasing order of strength
> +	 * to avoid unlock paths that aren't safe in the stronger
> +	 * context. Namely: BH can not be enabled with disabled interrupts.
> +	 * Additionally PREEMPT_RT requires that BH is enabled in preemptible
> +	 * context.
> +	 */
>  	if (statesold & RCUTORTURE_RDR_IRQ)
>  		local_irq_enable();
> -	if (statesold & RCUTORTURE_RDR_BH)
> -		local_bh_enable();
>  	if (statesold & RCUTORTURE_RDR_PREEMPT)
>  		preempt_enable();
> -	if (statesold & RCUTORTURE_RDR_RBH)
> -		rcu_read_unlock_bh();
>  	if (statesold & RCUTORTURE_RDR_SCHED)
>  		rcu_read_unlock_sched();
> +	if (statesold & RCUTORTURE_RDR_BH)
> +		local_bh_enable();
> +	if (statesold & RCUTORTURE_RDR_RBH)
> +		rcu_read_unlock_bh();
>  	if (statesold & RCUTORTURE_RDR_RCU) {
>  		bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);

The same in the unlock part so that BH is unlocked in preemptible
context.
Now if you need bh lock/unlock in atomic context (either with disabled
IRQs or preemption) then I would dig out the atomic-bh part again and
make !RT only without the preempt_disable() section around about which
one you did complain.

> @@ -1496,6 +1502,9 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
>  	int mask = rcutorture_extend_mask_max();
>  	unsigned long randmask1 = torture_random(trsp) >> 8;
>  	unsigned long randmask2 = randmask1 >> 3;
> +	unsigned long preempts = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;
> +	unsigned long preempts_irq = preempts | RCUTORTURE_RDR_IRQ;
> +	unsigned long bhs = RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
>  
>  	WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT);
>  	/* Mostly only one bit (need preemption!), sometimes lots of bits. */
> @@ -1503,11 +1512,37 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
>  		mask = mask & randmask2;
>  	else
>  		mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS));
> -	/* Can't enable bh w/irq disabled. */
> -	if ((mask & RCUTORTURE_RDR_IRQ) &&
> -	    ((!(mask & RCUTORTURE_RDR_BH) && (oldmask & RCUTORTURE_RDR_BH)) ||
> -	     (!(mask & RCUTORTURE_RDR_RBH) && (oldmask & RCUTORTURE_RDR_RBH))))
> -		mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
> +
> +	/*
> +	 * Can't enable bh w/irq disabled.
> +	 */
> +	if (mask & RCUTORTURE_RDR_IRQ)
> +		mask |= oldmask & bhs;
> +
> +	/*
> +	 * Ideally these sequences would be detected in debug builds
> +	 * (regardless of RT), but until then don't stop testing
> +	 * them on non-RT.
> +	 */
> +	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> +		/*
> +		 * Can't release the outermost rcu lock in an irq disabled
> +		 * section without preemption also being disabled, if irqs
> +		 * had ever been enabled during this RCU critical section
> +		 * (could leak a special flag and delay reporting the qs).
> +		 */
> +		if ((oldmask & RCUTORTURE_RDR_RCU) &&
> +		    (mask & RCUTORTURE_RDR_IRQ) &&
> +		    !(mask & preempts))
> +			mask |= RCUTORTURE_RDR_RCU;

This piece above, I don't understand. I had it running for a while and
it didn't explode. Let me try TREE01 for 30min without that piece.

> +		/* Can't modify bh in atomic context */
> +		if (oldmask & preempts_irq)
> +			mask &= ~bhs;
> +		if ((oldmask | mask) & preempts_irq)
> +			mask |= oldmask & bhs;

And this is needed because we can't lock/unlock bh while atomic.

> +	}
> +
>  	return mask ?: RCUTORTURE_RDR_RCU;
>  }
>  

Sebastian


From boqun.feng at gmail.com  Thu Aug 19 08:47:52 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Thu, 19 Aug 2021 23:47:52 +0800
Subject: [PATCH v6 0/8] PCI: hv: Support host bridge probing on ARM64
In-Reply-To: <20210819141758.GA27305@lpieralisi>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210819141758.GA27305@lpieralisi>
Message-ID: <YR59KJ+SenbQ58cw@boqun-archlinux>

On Thu, Aug 19, 2021 at 03:17:58PM +0100, Lorenzo Pieralisi wrote:
> On Tue, Jul 27, 2021 at 02:06:49AM +0800, Boqun Feng wrote:
> > Hi,
> > 
> > This is the v6 for the preparation of virtual PCI support on Hyper-V
> > ARM64, Previous versions:
> > 
> > v1:	https://lore.kernel.org/lkml/20210319161956.2838291-1-boqun.feng at gmail.com/
> > v2:	https://lore.kernel.org/lkml/20210503144635.2297386-1-boqun.feng at gmail.com/
> > v3:	https://lore.kernel.org/lkml/20210609163211.3467449-1-boqun.feng at gmail.com/
> > v4:	https://lore.kernel.org/lkml/20210714102737.198432-1-boqun.feng at gmail.com/
> > v5:	https://lore.kernel.org/lkml/20210720134429.511541-1-boqun.feng at gmail.com/
> > 
> > Changes since last version:
> > 
> > *	Rebase to 5.14-rc3
> > 
> > *	Comment fixes as suggested by Bjorn.
> > 
> > The basic problem we need to resolve is that ARM64 is an arch with
> > PCI_DOMAINS_GENERIC=y, so the bus sysdata is pci_config_window. However,
> > Hyper-V PCI provides a paravirtualized PCI interface, so there is no
> > actual pci_config_window for a PCI host bridge, so no information can be
> > retrieve from the pci_config_window of a Hyper-V virtual PCI bus. Also
> > there is no corresponding ACPI device for the Hyper-V PCI root bridge,
> > which introduces a special case when trying to find the ACPI device from
> > the sysdata (see patch #3).
> > 
> > With this patchset, we could enable the virtual PCI on Hyper-V ARM64
> > guest with other code under development.
> > 
> > Comments and suggestions are welcome.
> > 
> > Regards,
> > Boqun
> > 
> > Arnd Bergmann (1):
> >   PCI: hv: Generify PCI probing
> > 
> > Boqun Feng (7):
> >   PCI: Introduce domain_nr in pci_host_bridge
> >   PCI: Support populating MSI domains of root buses via bridges
> >   arm64: PCI: Restructure pcibios_root_bridge_prepare()
> >   arm64: PCI: Support root bridge preparation for Hyper-V
> >   PCI: hv: Set ->domain_nr of pci_host_bridge at probing time
> >   PCI: hv: Set up MSI domain at bridge probing time
> >   PCI: hv: Turn on the host bridge probing on ARM64
> > 
> >  arch/arm64/kernel/pci.c             | 29 +++++++---
> >  drivers/pci/controller/pci-hyperv.c | 86 +++++++++++++++++------------
> >  drivers/pci/probe.c                 | 12 +++-
> >  include/linux/pci.h                 | 11 ++++
> >  4 files changed, 93 insertions(+), 45 deletions(-)
> 
> If we take this series via the PCI tree we'd need Catalin/Will ACKs on
> patches 3-4.
> 

Got it.

> I need some time to look into [1] (thanks for that).
> 
> Without [1] patch 8 is ugly, that's no news. The question is whether
> it is worth waiting for a kernel cycle to integrate [1] into this series
> or not.
> 
> Is it really a problem if we postpone this series for another kernel
> cycle so that we can look into it ?
> 

Well, it's definitely better for me that we can have it in 5.15-rc1 ;-),
because it's a dependency for Hyper-V virtual PCI support on ARM64 and
we plan to send the rest of work in 5.15 cycle. And I can just base on
hyperv-next for the rest of the work if this is in 5.15-rc1. But yes,
it's not really a problem, since this one still needs to work with other
patches to support virtual PCI on ARM64 Hyper-V.

In fact, I personally don't think [1] is better than patch 8 (plus patch
3 & 4): playing with ->private seems dangerous and not very helpful on
readiblity, but I agree that we should explore every potential solution,
and that's why I send [1].

Regards,
Boqun

> [1] https://lore.kernel.org/lkml/20210811153619.88922-1-boqun.feng at gmail.com/


From lutovinova at ispras.ru  Thu Aug 19 08:48:18 2021
From: lutovinova at ispras.ru (Nadezda Lutovinova)
Date: Thu, 19 Aug 2021 18:48:18 +0300
Subject: [PATCH] usb: dwc3: imx8mp: request irq after initializing dwc3
Message-ID: <20210819154818.18334-1-lutovinova@ispras.ru>

If IRQ occurs between calling  devm_request_threaded_irq() and
initializing dwc3_imx->dwc3, then null pointer dereference occurs
since dwc3_imx->dwc3 is used in dwc3_imx8mp_interrupt().

The patch puts registration of the interrupt handler after
initializing of neccesery data.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Nadezda Lutovinova <lutovinova at ispras.ru>
---
 drivers/usb/dwc3/dwc3-imx8mp.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
index 756faa46d33a..d328d20abfbc 100644
--- a/drivers/usb/dwc3/dwc3-imx8mp.c
+++ b/drivers/usb/dwc3/dwc3-imx8mp.c
@@ -152,13 +152,6 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	}
 	dwc3_imx->irq = irq;
 
-	err = devm_request_threaded_irq(dev, irq, NULL, dwc3_imx8mp_interrupt,
-					IRQF_ONESHOT, dev_name(dev), dwc3_imx);
-	if (err) {
-		dev_err(dev, "failed to request IRQ #%d --> %d\n", irq, err);
-		goto disable_clks;
-	}
-
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 	err = pm_runtime_get_sync(dev);
@@ -186,6 +179,13 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	}
 	of_node_put(dwc3_np);
 
+	err = devm_request_threaded_irq(dev, irq, NULL, dwc3_imx8mp_interrupt,
+					IRQF_ONESHOT, dev_name(dev), dwc3_imx);
+	if (err) {
+		dev_err(dev, "failed to request IRQ #%d --> %d\n", irq, err);
+		goto depopulate;
+	}
+
 	device_set_wakeup_capable(dev, true);
 	pm_runtime_put(dev);
 
-- 
2.17.1



From zajec5 at gmail.com  Thu Aug 19 08:54:08 2021
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Thu, 19 Aug 2021 17:54:08 +0200
Subject: [PATCH WIP] arm64: dts: broadcom: bcm4908: Add PCIe controllers
Message-ID: <20210819155408.25770-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

BCM4908 SoC has 3 PCIe controllers. Describe them.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
This is WIP. It's enough to initialize PCIe controllers and detect
attached devices. Checking DTS files however results in complains about
missing "dma-ranges", interrupt mapping & "msi-controller".
---
 .../boot/dts/broadcom/bcm4908/bcm4908.dtsi    | 53 ++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
index 984c737fa627..f09611697863 100644
--- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi
@@ -267,6 +267,57 @@ pmb: power-controller at 2800c0 {
 		};
 	};
 
+	pcie at 80040000 {
+		compatible = "brcm,bcm4908-pcie";
+		reg = <0x0 0x80040000 0x0 0xa000>;
+		power-domains = <&pmb BCM_PMB_PCIE0>;
+		resets = <&pcie_reset 0>;
+		reset-names = "perst";
+		interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie";
+		device_type = "pci";
+		bus-range = <0x00 0xff>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+		// BUS_ADDRESS(3)  CPU_PHYSICAL(2)  SIZE(2)
+		ranges = <0x02000000 0x0 0xc0000000  0x0 0xc0000000  0x0 0x10000000>;
+	};
+
+	pcie at 80050000 {
+		compatible = "brcm,bcm4908-pcie";
+		reg = <0x0 0x80050000 0x0 0xa000>;
+		power-domains = <&pmb BCM_PMB_PCIE1>;
+		resets = <&pcie_reset 1>;
+		reset-names = "perst";
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie";
+		device_type = "pci";
+		bus-range = <0x00 0xff>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+		// BUS_ADDRESS(3)  CPU_PHYSICAL(2)  SIZE(2)
+		ranges = <0x02000000 0x0 0xd0000000  0x0 0xd0000000  0x0 0x10000000>;
+	};
+
+	pcie at 80060000 {
+		compatible = "brcm,bcm4908-pcie";
+		reg = <0x0 0x80060000 0x0 0xa000>;
+		power-domains = <&pmb BCM_PMB_PCIE2>;
+		resets = <&pcie_reset 2>;
+		reset-names = "perst";
+		interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie";
+		device_type = "pci";
+		bus-range = <0x00 0xff>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+		// BUS_ADDRESS(3)  CPU_PHYSICAL(2)  SIZE(2)
+		ranges = <0x02000000 0x0 0xe0000000  0x0 0xe0000000  0x0 0x10000000>;
+	};
+
 	bus at ff800000 {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -320,7 +371,7 @@ misc at 2600 {
 			#size-cells = <1>;
 			ranges = <0x00 0x2600 0xe4>;
 
-			reset-controller at 2644 {
+			pcie_reset: reset-controller at 2644 {
 				compatible = "brcm,bcm4908-misc-pcie-reset";
 				reg = <0x44 0x04>;
 				#reset-cells = <1>;
-- 
2.26.2



From boqun.feng at gmail.com  Thu Aug 19 09:13:22 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Fri, 20 Aug 2021 00:13:22 +0800
Subject: [PATCH v6 4/8] arm64: PCI: Support root bridge preparation for
 Hyper-V
In-Reply-To: <20210726180657.142727-5-boqun.feng@gmail.com>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-5-boqun.feng@gmail.com>
Message-ID: <YR6DIkdkblL8NUP2@boqun-archlinux>

Catalin and Will,

Appreciate it that you can have a look at this one and patch #4, note
that there exists an alternative solution at[1].

The difference is the way used to pass the corresponding ACPI device
pointers for PCI host bridges: currently pci_config_window->parent is
used, and this patch and patch #4 allow the field to be NULL, because
Hyper-V's PCI host bridges don't have ACPI devices, while [1] changes to
use pci_host_bridge->private. And I'm OK with either way, I don't have a
strong opinion here ;-)

Looking forwards to your suggestion, Thanks!

Regards,
Boqun

[1]: https://lore.kernel.org/lkml/20210811153619.88922-1-boqun.feng at gmail.com/

On Tue, Jul 27, 2021 at 02:06:53AM +0800, Boqun Feng wrote:
> Currently at root bridge preparation, the corresponding ACPI device will
> be set as the companion, however for a Hyper-V virtual PCI root bridge,
> there is no corresponding ACPI device, because a Hyper-V virtual PCI
> root bridge is discovered via VMBus rather than ACPI table. In order to
> support this, we need to make pcibios_root_bridge_prepare() work with
> cfg->parent being NULL.
> 
> Use a NULL pointer as the ACPI device if there is no corresponding ACPI
> device, and this is fine because: 1) ACPI_COMPANION_SET() can work with
> the second parameter being NULL, 2) semantically, if a NULL pointer is
> set via ACPI_COMPANION_SET(), ACPI_COMPANION() (the read API for this
> field) will return NULL, and since ACPI_COMPANION() may return NULL, so
> users must have handled the cases where it returns NULL, and 3) since
> there is no corresponding ACPI device, it would be wrong to use any
> other value here.
> 
> Signed-off-by: Boqun Feng <boqun.feng at gmail.com>
> ---
>  arch/arm64/kernel/pci.c | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> index 5148ae242780..2276689b5411 100644
> --- a/arch/arm64/kernel/pci.c
> +++ b/arch/arm64/kernel/pci.c
> @@ -90,7 +90,17 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
>  		return 0;
>  
>  	cfg = bridge->bus->sysdata;
> -	adev = to_acpi_device(cfg->parent);
> +
> +	/*
> +	 * On Hyper-V there is no corresponding ACPI device for a root bridge,
> +	 * therefore ->parent is set as NULL by the driver. And set 'adev' as
> +	 * NULL in this case because there is no proper ACPI device.
> +	 */
> +	if (!cfg->parent)
> +		adev = NULL;
> +	else
> +		adev = to_acpi_device(cfg->parent);
> +
>  	bus_dev = &bridge->bus->dev;
>  
>  	ACPI_COMPANION_SET(&bridge->dev, adev);
> -- 
> 2.32.0
> 


From cki-project at redhat.com  Thu Aug 19 09:18:14 2021
From: cki-project at redhat.com (CKI Project)
Date: Thu, 19 Aug 2021 16:18:14 -0000
Subject: =?utf-8?b?4pyF?= PASS: Test report for kernel 5.14.0-rc6 (arm-next,
 4a8d8820)
Message-ID: <cki.3D482F060E.SH23NZ11G4@redhat.com>


Hello,

We ran automated tests on a recent commit from this kernel tree:

       Kernel repo: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
            Commit: 4a8d882022c7 - Merge branch 'for-next/fixes' into for-kernelci

The results of these automated tests are provided below.

    Overall result: PASSED
             Merge: OK
           Compile: OK
             Tests: OK

All kernel binaries, config files, and logs are available for download here:

  https://arr-cki-prod-datawarehouse-public.s3.amazonaws.com/index.html?prefix=datawarehouse-public/2021/08/19/355715101

Please reply to this email if you have any questions about the tests that we
ran or if you have any suggestions on how to make future tests more effective.

        ,-.   ,-.
       ( C ) ( K )  Continuous
        `-',-.`-'   Kernel
          ( I )     Integration
           `-'
______________________________________________________________________________

Compile testing
---------------

We compiled the kernel for 1 architecture:

    aarch64:
      make options: make -j24 INSTALL_MOD_STRIP=1 targz-pkg



Hardware testing
----------------
We booted each kernel and ran the following tests:

  aarch64:
    Host 1:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ??? ACPI table test
       ??? ACPI enabled test
       ??? LTP
       ??? CIFS Connectathon
       ??? POSIX pjd-fstest suites
       ??? Loopdev Sanity
       ??? jvm - jcstress tests
       ??? Memory: fork_mem
       ??? Memory function: memfd_create
       ??? AMTU (Abstract Machine Test Utility)
       ??? Networking bridge: sanity
       ??? Ethernet drivers sanity
       ??? Networking socket: fuzz
       ??? Networking: igmp conformance test
       ??? Networking route: pmtu
       ??? Networking route_func - local
       ??? Networking route_func - forward
       ??? Networking TCP: keepalive test
       ??? Networking UDP: socket
       ??? Networking cki netfilter test
       ??? Networking tunnel: geneve basic test
       ??? Networking tunnel: gre basic
       ??? L2TP basic test
       ??? Networking tunnel: vxlan basic
       ??? Networking ipsec: basic netns - transport
       ??? Networking ipsec: basic netns - tunnel
       ??? Libkcapi AF_ALG test
       ??? pciutils: update pci ids test
       ??? ALSA PCM loopback test
       ??? ALSA Control (mixer) Userspace Element test
       ??? storage: SCSI VPD
       ??? trace: ftrace/tracer
       ? ??? xarray-idr-radixtree-test
       ? ??? i2c: i2cdetect sanity
       ? ??? NFS Connectathon
       ? ??? Firmware test suite
       ? ??? Memory function: kaslr
       ? ??? audit: audit testsuite test
       ? ??? lvm cache test
       ? ??? lvm snapper test

    Host 2:
       ? Boot test
       ? Reboot test
       ? xfstests - ext4
       ? xfstests - xfs
       ? selinux-policy: serge-testsuite
       ? Storage blktests
       ? storage: software RAID testing
       ? Storage: swraid mdadm raid_module test
       ? ? Podman system integration test - as root
       ? ? Podman system integration test - as user
       ? ? xfstests - btrfs
       ? ? IPMI driver test
       ? ? IPMItool loop stress test
       ? ? Storage block - filesystem fio test
       ? ? Storage block - queue scheduler test
       ? ? Storage nvme - tcp
       ? ? stress: stress-ng

    Host 3:
       ? Boot test
       ? Reboot test
       ? ACPI table test
       ? ACPI enabled test
       ? LTP
       ? CIFS Connectathon
       ? POSIX pjd-fstest suites
       ? Loopdev Sanity
       ? jvm - jcstress tests
       ? Memory: fork_mem
       ? Memory function: memfd_create
       ? AMTU (Abstract Machine Test Utility)
       ? Networking bridge: sanity
       ? Ethernet drivers sanity
       ? Networking socket: fuzz
       ? Networking: igmp conformance test
       ? Networking route: pmtu
       ? Networking route_func - local
       ? Networking route_func - forward
       ? Networking TCP: keepalive test
       ? Networking UDP: socket
       ? Networking cki netfilter test
       ? Networking tunnel: geneve basic test
       ? Networking tunnel: gre basic
       ? L2TP basic test
       ? Networking tunnel: vxlan basic
       ? Networking ipsec: basic netns - transport
       ? Networking ipsec: basic netns - tunnel
       ? Libkcapi AF_ALG test
       ? pciutils: update pci ids test
       ? ALSA PCM loopback test
       ? ALSA Control (mixer) Userspace Element test
       ? storage: SCSI VPD
       ? trace: ftrace/tracer
       ? ? xarray-idr-radixtree-test
       ? ? i2c: i2cdetect sanity
       ? ? NFS Connectathon
       ? ? Firmware test suite
       ? ? Memory function: kaslr
       ? ? audit: audit testsuite test
       ? ? lvm cache test
       ? ? lvm snapper test

  Test sources: https://gitlab.com/cki-project/kernel-tests
    ? Pull requests are welcome for new tests or improvements to existing tests!

Aborted tests
-------------
Tests that didn't complete running successfully are marked with ???.
If this was caused by an infrastructure issue, we try to mark that
explicitly in the report.

Waived tests
------------
If the test run included waived tests, they are marked with ?. Such tests are
executed but their results are not taken into account. Tests are waived when
their results are not reliable enough, e.g. when they're just introduced or are
being fixed.

Testing timeout
---------------
We aim to provide a report within reasonable timeframe. Tests that haven't
finished running yet are marked with ?.



From alim.akhtar at gmail.com  Thu Aug 19 09:18:31 2021
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Thu, 19 Aug 2021 21:48:31 +0530
Subject: [PATCH v11] dt-bindings: ufs: Add bindings for Samsung ufs host
In-Reply-To: <CAGOxZ53emv4H4UqT2L7tDtTXRgDrtrqti=FtfkNWo2M3rTnZMw@mail.gmail.com>
References: <CGME20210803032734epcas5p2143008ddb212fe53fcd28b813c85c9d8@epcas5p2.samsung.com>
 <20210803032539.15676-1-alim.akhtar@samsung.com>
 <CAGOxZ53emv4H4UqT2L7tDtTXRgDrtrqti=FtfkNWo2M3rTnZMw@mail.gmail.com>
Message-ID: <CAGOxZ51qW52r=BzAc9K_NO3fQcRT3DXG-wVyO9-GvACyYgvQwA@mail.gmail.com>

Hi Rob
Can you pick up this patch via your tree? or you want Martin to pick it up?

On Sat, Aug 14, 2021 at 10:25 PM Alim Akhtar <alim.akhtar at gmail.com> wrote:
>
> Ping!!
>
> On Wed, Aug 4, 2021 at 9:01 AM Alim Akhtar <alim.akhtar at samsung.com> wrote:
> >
> > This patch adds DT bindings for Samsung ufs hci
> >
> > Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> > ---
> > Changes since v10
> > * Rebased on v5.14-rc2
> > * removed Rob Herring earlier Reviewed-by tag
> >
> > This patch was part of exynos ufs driver series, somehow
> > this got missed to applied on the tree, sending again as a new
> > patch v11, removing Rob's earlier Reviewed-by tag.
> >
> >  .../bindings/ufs/samsung,exynos-ufs.yaml      | 89 +++++++++++++++++++
> >  1 file changed, 89 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> > new file mode 100644
> > index 000000000000..38193975c9f1
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> > @@ -0,0 +1,89 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/ufs/samsung,exynos-ufs.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Samsung SoC series UFS host controller Device Tree Bindings
> > +
> > +maintainers:
> > +  - Alim Akhtar <alim.akhtar at samsung.com>
> > +
> > +description: |
> > +  Each Samsung UFS host controller instance should have its own node.
> > +  This binding define Samsung specific binding other then what is used
> > +  in the common ufshcd bindings
> > +  [1] Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
> > +
> > +properties:
> > +
> > +  compatible:
> > +    enum:
> > +      - samsung,exynos7-ufs
> > +
> > +  reg:
> > +    items:
> > +     - description: HCI register
> > +     - description: vendor specific register
> > +     - description: unipro register
> > +     - description: UFS protector register
> > +
> > +  reg-names:
> > +    items:
> > +      - const: hci
> > +      - const: vs_hci
> > +      - const: unipro
> > +      - const: ufsp
> > +
> > +  clocks:
> > +    items:
> > +      - description: ufs link core clock
> > +      - description: unipro main clock
> > +
> > +  clock-names:
> > +    items:
> > +      - const: core_clk
> > +      - const: sclk_unipro_main
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  phys:
> > +    maxItems: 1
> > +
> > +  phy-names:
> > +    const: ufs-phy
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - phys
> > +  - phy-names
> > +  - clocks
> > +  - clock-names
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/clock/exynos7-clk.h>
> > +
> > +    ufs: ufs at 15570000 {
> > +       compatible = "samsung,exynos7-ufs";
> > +       reg = <0x15570000 0x100>,
> > +             <0x15570100 0x100>,
> > +             <0x15571000 0x200>,
> > +             <0x15572000 0x300>;
> > +       reg-names = "hci", "vs_hci", "unipro", "ufsp";
> > +       interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
> > +       clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
> > +                <&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
> > +       clock-names = "core_clk", "sclk_unipro_main";
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> > +       phys = <&ufs_phy>;
> > +       phy-names = "ufs-phy";
> > +    };
> > +...
> >
> > base-commit: 2734d6c1b1a089fb593ef6a23d4b70903526fe0c
> > --
> > 2.17.1
> >
>
>
> --
> Regards,
> Alim



-- 
Regards,
Alim


From romain.perier at gmail.com  Thu Aug 19 09:22:29 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Thu, 19 Aug 2021 18:22:29 +0200
Subject: [PATCH v2 3/3] ARM: dts: mstar: Add rtc device node
In-Reply-To: <CAFr9PXmqiu=toGf9DjoH8XMbPaiXaWLV=GsmR7OCkkqix5tRvw@mail.gmail.com>
References: <20210801160921.233081-1-romain.perier@gmail.com>
 <20210801160921.233081-4-romain.perier@gmail.com>
 <CAFr9PXmqiu=toGf9DjoH8XMbPaiXaWLV=GsmR7OCkkqix5tRvw@mail.gmail.com>
Message-ID: <CABgxDoL0sQH4MRBA-1hJtXkNaphnKu7fbW9C++vEQSX4F6Q1yQ@mail.gmail.com>

Hi,

As I need to send a v3, I can fix it, no worries.

Cheers,
Romain

Le lun. 2 ao?t 2021 ? 12:40, Daniel Palmer <daniel at 0x0f.com> a ?crit :
>
> Hi Romain,
>
> On Mon, 2 Aug 2021 at 01:09, Romain Perier <romain.perier at gmail.com> wrote:
> > +++ b/arch/arm/boot/dts/mstar-v7.dtsi
> > @@ -116,6 +116,13 @@ watchdog at 6000 {
> >                                 clocks = <&xtal_div2>;
> >                         };
> >
> > +                       rtc at 2400 {
>
> I think the rtc should be before the watchdog as the address is lower.
> I think maybe this got flipped around during cherry-picking.
> I can flip it around when I pull this into an mstar dts for 5.15
> branch so you don't need to fix it and send a v3 assuming everything
> else is ok.
>
> Thanks,
>
> Daniel


From romain.perier at gmail.com  Thu Aug 19 09:24:11 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Thu, 19 Aug 2021 18:24:11 +0200
Subject: [PATCH v2 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree
 bindings documentation
In-Reply-To: <YQ2riRW1hZmn6x4B@robh.at.kernel.org>
References: <20210801160921.233081-1-romain.perier@gmail.com>
 <20210801160921.233081-2-romain.perier@gmail.com>
 <YQ2riRW1hZmn6x4B@robh.at.kernel.org>
Message-ID: <CABgxDoKYo+_8O+gzGpj0boj4mKRbStbPitZrVzznY_wmq1CGZw@mail.gmail.com>

Hi,

Le ven. 6 ao?t 2021 ? 23:37, Rob Herring <robh at kernel.org> a ?crit :
>
> On Sun, Aug 01, 2021 at 06:09:19PM +0200, Romain Perier wrote:
> > This adds the documentation for the devicetree bindings of the Mstar
> > MSC313e RTC driver, found from MSC313e SoCs and newer.
> >
> > Signed-off-by: Romain Perier <romain.perier at gmail.com>
> > ---
> >  .../bindings/rtc/mstar,msc313-rtc.yaml        | 49 +++++++++++++++++++
> >  1 file changed, 49 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> > new file mode 100644
> > index 000000000000..62bc12b1feb6
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> > @@ -0,0 +1,49 @@
> > +# SPDX-License-Identifier: GPL-2.0
>
> As checkpatch.pl will tell you, should be dual licensed.

Arf, sorry for this, I have completely missed it (it will be fixed in v3).

Romain


From marcel.ziswiler at toradex.com  Thu Aug 19 09:24:38 2021
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Thu, 19 Aug 2021 16:24:38 +0000
Subject: [PATCH v1 7/7] ARM: dts: colibri-imx6ull-emmc: add device trees
In-Reply-To: <20210819140345.357167-8-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
 <20210819140345.357167-8-marcel@ziswiler.com>
Message-ID: <81b0c6edf6d2b50cea08a02650b07df95eb424d7.camel@toradex.com>

On Thu, 2021-08-19 at 16:03 +0200, Marcel Ziswiler wrote:
> From: Max Krummenacher <max.krummenacher at toradex.com>
> 
> Add devices trees for a Colibri iMX6ULL 1GB which has a eMMC instead of
> the raw NAND used on other SKUs.
> 
> Related-to: ELB-4056, ELB-4058
> Signed-off-by: Max Krummenacher <max.krummenacher at toradex.com>
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> ?arch/arm/boot/dts/Makefile??????????????????? |?? 1 +
> ?.../boot/dts/imx6ull-colibri-emmc-eval-v3.dts |? 17 ++
> ?.../dts/imx6ull-colibri-emmc-nonwifi.dtsi???? | 185 ++++++++++++++++++
> ?arch/arm/boot/dts/imx6ull-colibri.dtsi??????? |? 30 ++-
> ?4 files changed, 232 insertions(+), 1 deletion(-)
> ?create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
> ?create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi
> 
> ...
>
> diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi b/arch/arm/boot/dts/imx6ull-colibri.dtsi
> index 0cdbf7b6e7285..f432fc0a6a530 100644
> --- a/arch/arm/boot/dts/imx6ull-colibri.dtsi
> +++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi
> @@ -1,6 +1,6 @@
> ?// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> ?/*
> - * Copyright 2018 Toradex AG
> + * Copyright 2018-2021 Toradex AG
> ? */
> ?
> ?#include "imx6ull.dtsi"
> @@ -345,6 +345,19 @@ MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01???????0xb0b0 /* SODIMM 63 */
> ????????????????>;
> ????????};
> ?
> +???????????????/*
> +??????????????? * With an eMMC instead of a raw NAND device the following pins
> +??????????????? * are available at SODIMM pins
> +??????????????? */
> +???????????????pinctrl_gpmi_gpio: gpmi-gpio-grp {
> +???????????????????????fsl,pins = <
> +???????????????????????????????MX6UL_PAD_NAND_ALE__GPIO4_IO10??????????0x10b0 /* SODIMM 140 */
> +???????????????????????????????MX6UL_PAD_NAND_CE0_B__GPIO4_IO13????????0x10b0 /* SODIMM 144 */
> +???????????????????????????????MX6UL_PAD_NAND_CLE__GPIO4_IO15??????????0x10b0 /* SODIMM 146 */
> +???????????????????????????????MX6UL_PAD_NAND_READY_B__GPIO4_IO12??????0x10b0 /* SODIMM 142 */
> +???????????????????????>;
> +???????????????};
> +

Just noticed that I somehow messed up the indentation above with one spurious tab too much. Will correct that
in a v2. Sorry about that.

> ????????pinctrl_gpmi_nand: gpmi-nand-grp {
> ????????????????fsl,pins = <
> ????????????????????????MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00???0x100a9
> @@ -533,6 +546,21 @@ MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT???????0x10
> ????????????????>;
> ????????};
> ?
> +???????????????pinctrl_usdhc2emmc: usdhc2emmcgrp {
> +???????????????????????fsl,pins = <
> +???????????????????????????????MX6UL_PAD_NAND_RE_B__USDHC2_CLK???? 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_WE_B__USDHC2_CMD???? 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
> +???????????????????????????????MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
> +???????????????????????>;
> +???????????????};
> +

Ditto above.

> ????????pinctrl_wdog: wdog-grp {
> ????????????????fsl,pins = <
> ????????????????????????MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY??? 0x30b0

Cheers

Marcel

From jernej.skrabec at gmail.com  Thu Aug 19 09:30:56 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 19 Aug 2021 18:30:56 +0200
Subject: [PATCH] media: cedrus: Fix SUNXI tile size calculation
In-Reply-To: <20210819140009.158156-1-nicolas.dufresne@collabora.com>
References: <20210819140009.158156-1-nicolas.dufresne@collabora.com>
Message-ID: <3519986.qLKfoAsNv3@jernej-laptop>

Hi Nicolas!

Dne ?etrtek, 19. avgust 2021 ob 16:00:09 CEST je Nicolas Dufresne napisal(a):
> Tiled formats requires full rows being allocated (even for Chroma
> planes). When the number of Luma tiles is odd, we need to round up
> to twice the tile width in order to roundup the number of Chroma
> tiles.
> 
> This was notice with a crash running BA1_FT_C compliance test using
> sunxi tiles using GStreamer. Cedrus driver would allocate 9 rows for
> Luma, but only 4.5 rows for Chroma, causing userspace to crash.
> 
> Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>

Fixes tag would be nice so it would be picked up for stable branches. 
Otherwise it looks good. It also aligns logic with libvdpau-sunxi.

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From romain.perier at gmail.com  Thu Aug 19 09:55:22 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Thu, 19 Aug 2021 18:55:22 +0200
Subject: [PATCH v2 2/3] rtc: Add support for the MSTAR MSC313 RTC
In-Reply-To: <YQ2Pm7nrEFmdS6Ky@piout.net>
References: <20210801160921.233081-1-romain.perier@gmail.com>
 <20210801160921.233081-3-romain.perier@gmail.com> <YQ2Pm7nrEFmdS6Ky@piout.net>
Message-ID: <CABgxDo+deU3J1JCCSFTscQP8sm=XeXKJ=cPf4u78o37f3XBqwA@mail.gmail.com>

Hello,

Le ven. 6 ao?t 2021 ? 21:38, Alexandre Belloni
<alexandre.belloni at bootlin.com> a ?crit :
>
> Hello,
>
> On 01/08/2021 18:09:20+0200, Romain Perier wrote:
> > +static int msc313_rtc_probe(struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct msc313_rtc *priv;
> > +     int ret;
> > +     int irq;
> > +     unsigned long rate;
> > +     u16 reg;
> > +
> > +     priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
> > +     if (!priv)
> > +             return -ENOMEM;
> > +
> > +     priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
> > +     if (IS_ERR(priv->rtc_base))
> > +             return PTR_ERR(priv->rtc_base);
> > +
> > +     irq = platform_get_irq(pdev, 0);
> > +     if (irq < 0)
> > +             return -EINVAL;
> > +
> > +     priv->rtc_dev = devm_rtc_allocate_device(dev);
> > +     if (IS_ERR(priv->rtc_dev))
> > +             return PTR_ERR(priv->rtc_dev);
> > +
> > +     priv->rtc_dev->ops = &msc313_rtc_ops;
> > +     priv->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000;
>
> I'm pretty sure this doesn't fit in this RTC registers, you should
> probably leave range_min to 0 (i.e. not set it at all).

ack

>
> > +     priv->rtc_dev->range_max = U32_MAX - 1; /* 2106-02-07 06:28:14 */
>
> I guess this one should be U32_MAX

ack

> > +
> > +     ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
> > +                            dev_name(&pdev->dev), &pdev->dev);
> > +     if (ret) {
> > +             dev_err(dev, "Could not request IRQ\n");
> > +             return ret;
> > +     }
> > +
> > +     priv->clk = devm_clk_get(dev, NULL);
> > +     if (IS_ERR(priv->clk)) {
> > +             dev_err(dev, "No input reference clock\n");
> > +             return PTR_ERR(priv->clk);
> > +     }
> > +
> > +     ret = clk_prepare_enable(priv->clk);
> > +     if (ret) {
> > +             dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
> > +             return ret;
> > +     }
> > +
> > +     ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, priv->clk);
> > +     if (ret)
> > +             return ret;
> > +
> > +     rate = clk_get_rate(priv->clk);
> > +     writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
> > +     writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
> > +
> > +     reg = readw(priv->rtc_base + REG_RTC_CTRL);
> > +     reg |= CNT_EN_BIT;
> > +     writew(reg, priv->rtc_base + REG_RTC_CTRL);
> > +
>
> If on POR, CNT_EN_BIT is not set, then it would be nice to use that to
> know whether the RTC is properly set. You can then check CNT_EN_BIT in
> .read_time and return -EINVAL if it is not set. Then you can set the bit
> in .set_time. It is anyway useless to let the RTC running if it is not
> set.

Yeah, this is to be sure that the RTC is alive with a valid value
(which makes sense).
Ok I will fix everything in v3, then.

Romain


From broonie at kernel.org  Thu Aug 19 09:57:23 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 17:57:23 +0100
Subject: [PATCH] kselftest/arm64: pac: Fix skipping of tests on systems
 without PAC
Message-ID: <20210819165723.43903-1-broonie@kernel.org>

The PAC tests check to see if the system supports the relevant PAC features
but instead of skipping the tests if they can't be executed they fail the
tests which makes things look like they're not working when they are.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/pauth/pac.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/arm64/pauth/pac.c b/tools/testing/selftests/arm64/pauth/pac.c
index 592fe538506e..b743daa772f5 100644
--- a/tools/testing/selftests/arm64/pauth/pac.c
+++ b/tools/testing/selftests/arm64/pauth/pac.c
@@ -25,13 +25,15 @@
 do { \
 	unsigned long hwcaps = getauxval(AT_HWCAP); \
 	/* data key instructions are not in NOP space. This prevents a SIGILL */ \
-	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \
+	if (!(hwcaps & HWCAP_PACA))					\
+		SKIP(return, "PAUTH not enabled"); \
 } while (0)
 #define ASSERT_GENERIC_PAUTH_ENABLED() \
 do { \
 	unsigned long hwcaps = getauxval(AT_HWCAP); \
 	/* generic key instructions are not in NOP space. This prevents a SIGILL */ \
-	ASSERT_NE(0, hwcaps & HWCAP_PACG) TH_LOG("Generic PAUTH not enabled"); \
+	if (!(hwcaps & HWCAP_PACG)) \
+		SKIP(return, "Generic PAUTH not enabled");	\
 } while (0)
 
 void sign_specific(struct signatures *sign, size_t val)
@@ -256,7 +258,7 @@ TEST(single_thread_different_keys)
 	unsigned long hwcaps = getauxval(AT_HWCAP);
 
 	/* generic and data key instructions are not in NOP space. This prevents a SIGILL */
-	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled");
+	ASSERT_PAUTH_ENABLED();
 	if (!(hwcaps & HWCAP_PACG)) {
 		TH_LOG("WARNING: Generic PAUTH not enabled. Skipping generic key checks");
 		nkeys = NKEYS - 1;
@@ -299,7 +301,7 @@ TEST(exec_changed_keys)
 	unsigned long hwcaps = getauxval(AT_HWCAP);
 
 	/* generic and data key instructions are not in NOP space. This prevents a SIGILL */
-	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled");
+	ASSERT_PAUTH_ENABLED();
 	if (!(hwcaps & HWCAP_PACG)) {
 		TH_LOG("WARNING: Generic PAUTH not enabled. Skipping generic key checks");
 		nkeys = NKEYS - 1;
-- 
2.20.1



From frattaroli.nicolas at gmail.com  Thu Aug 19 10:01:25 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Thu, 19 Aug 2021 19:01:25 +0200
Subject: [PATCH 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210819141617.GM4177@sirena.org.uk>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
 <2412250.zZEsDtmPgG@archbook> <20210819141617.GM4177@sirena.org.uk>
Message-ID: <1870492.5CqhBlFY90@archbook>

On Donnerstag, 19. August 2021 16:16:17 CEST Mark Brown wrote:
> On Thu, Aug 19, 2021 at 03:52:55PM +0200, Nicolas Frattaroli wrote:
> > On Donnerstag, 19. August 2021 14:08:36 CEST Robin Murphy wrote:
> > > > +  rockchip,no-dmaengine:
> > > > +    description:
> > > > +      If present, driver will not register a pcm dmaengine, only the
> > > > dai.
> > > > +      If the dai is part of multi-dais, the property should be
> > > > present.
> > > > +    type: boolean
> > > 
> > > That sounds a lot more like a policy decision specific to the Linux
> > > driver implementation, than something which really belongs in DT as a
> > > description of the platform.
> > 
> > I agree. Should I be refactoring this into a module parameter or
> > something along those lines? I'm unsure of where this goes.
> 
> Why is this even required?  What is "multi-dais" and why would
> registering the DMA stuff cause a problem?

After some research, it appears that multi-dais is a special driver that
downstream uses to allow multiple sub-DAIs to be combined into one DAI
that has all the channels of the sub-DAIs. This does not seem like
something that should be done at that level to me, because it seems
like it's pushing a sound driver configuration into the realm of
hardware description.

In retrospect, I should have stripped this out before submitting it,
because I should not be submitting things I don't understand completely.
I apologise.

> > The particular configuration may even vary per-board; an I2S/TDM
> > controller may be connected to an external codec which does not
> > support capture, whereas on another board it may be connected to
> > one that does.
> 
> If the external device doesn't support both directions then why does the
> driver for the I2S controller in the CPU care?  The constraint handling
> code in the core will ensure that nothing tries to start something that
> isn't supported

I went over the downstream text binding description again and from that
it appears that the playback/capture-only capability is something
specific to the controller, not to any device connected to it.

The downstream device tree for the rk3568 specifies playback-only for
I2S0, a.k.a. the one connected to the HDMI that I can't test because
we currently don't have a video clock. Another downstream device tree,
specific to what appears to be a robot demo for the px30 SoC, uses this
property on i2s1, which tells me that this is not an actual description
of the controller hardware but just a description of the application.

While not relevant to the device tree schema, the driver reacts to these
properties by setting the opposite directions _minimum_ channel number
to 0 (from the default of 2.)

My conclusion from this is that this reeks of nonsense and I will look
into what happens when I simply remove these properties and lower the
channels_min to 0 in the driver. If it turns out that on some SoC for
some I2S/TDM controller instance there is a limitation where specifying
that the controller only handles either capture or playback does make
sense, we can always add it later.

Thank you for your comments,
Nicolas Frattaroli




From robin.murphy at arm.com  Thu Aug 19 10:02:01 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 19 Aug 2021 18:02:01 +0100
Subject: [PATCH 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <2412250.zZEsDtmPgG@archbook>
References: <20210817101119.423853-1-frattaroli.nicolas@gmail.com>
 <20210817101119.423853-3-frattaroli.nicolas@gmail.com>
 <deb50900-fcfd-23d0-ab8a-0e64b2abb063@arm.com> <2412250.zZEsDtmPgG@archbook>
Message-ID: <70cb1e4b-ecb7-2a4b-ee35-02f5a6b8a986@arm.com>

On 2021-08-19 14:52, Nicolas Frattaroli wrote:
> On Donnerstag, 19. August 2021 14:08:36 CEST Robin Murphy wrote:
>> On 2021-08-17 11:11, Nicolas Frattaroli wrote:
>>> +  rockchip,trcm-sync:
>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>> +    description:
>>> +      Which lrck/bclk clocks each direction will sync to. You should use
>>> the +      constants in <dt-bindings/sound/rockchip,i2s-tdm.h>
>>> +    oneOf:
>>> +      - const: 0
>>> +        description:
>>> +          RK_TRCM_TXRX. Use both the TX and the RX clock for TX and RX.
>>> +      - const: 1
>>> +        description:
>>> +          RK_TRCM_TX. Use only the TX clock for TX and RX.
>>> +      - const: 2
>>> +        description:
>>> +          RK_TRCM_RX. Use only the RX clock for TX and RX.
>>
>> I wonder if that might make sense to have boolean properties to describe
>> the latter two cases (which would effectively be mutually-exclusive),
>> rather than a magic number? Or possibly even just make the respective
>> clocks optional, if this is something which would be done per-SoC rather
>> than per-board?
>>
> 
>  From what I know from downstream vendor device trees, these are per
> board, not for the SoC as a whole. There are I2S/TDM controllers on the
> SoC which I think are hardwired to certain other IP blocks, such as I2S0
> being connected to HDMI, but I2S1 can be routed outside of the SoC where
> these come into play I believe.

That's fair enough. I know a lot more about DT bindings than I do about 
I2S, but I did guess it might be related to clocking requirements of the 
connected codec rather than a constraint of the I2S block itself.

> As for making them boolean properties, I'd rather not. If I were to make it
> two mutually exclusive booleans, this would result in 4 possible states
> rather than 3, and require complexity to check it both in the schema and
> in the probe function. Like this, I can get away with a switch case that
> has a fallthrough, and a list of consts in the schema.

Complexity?


	if (of_property_read_bool(node, "rockchip,trcm-sync-tx-only"))
		i2s_tdm->clk_trcm = RK_TRCM_TX;
	if (of_property_read_bool(node, "rockchip,trcm-sync-rx-only")) {
		if (i2s_td->clk_trcm) {
			dev_err(i2s_tdm->dev, "invalid trcm-sync configuration\n");
			return -EINVAL;
		}
		i2s_tdm->clk_trcm = RK_TRCM_RX;
	}
	if (i2s_td->clk_trcm)
		i2s_tdm_dai.symmetric_rate = 1;


If I'm counting correctly, that off-the-top-of-my-head example is a mere 
58% of the size of your switch statement ;)

The usual aim in designing bindings to robustly abstract the underlying 
features, not to be easy to implement. That's why the "put this magic 
value in this register" style of property is generally frowned upon.

As for the schema, it doesn't necessarily have to try to exhaustively 
catch every possible usage error - if a combination of properties is so 
obviously nonsensical that a driver shouldn't accept it anyway, I'd 
imagine it's unlikely to slip through testing.

>>> +
>>> +  "#sound-dai-cells":
>>> +    const: 0
>>> +
>>> +  rockchip,no-dmaengine:
>>> +    description:
>>> +      If present, driver will not register a pcm dmaengine, only the dai.
>>> +      If the dai is part of multi-dais, the property should be present.
>>> +    type: boolean
>>
>> That sounds a lot more like a policy decision specific to the Linux
>> driver implementation, than something which really belongs in DT as a
>> description of the platform.
> 
> I agree. Should I be refactoring this into a module parameter or
> something along those lines? I'm unsure of where this goes.

Depends on what it actually means, and whether that's something the 
driver can figure out for itself. I just see a DT property based around 
a particular Linux API call as a big red flag :)

>>> +
>>> +  rockchip,playback-only:
>>> +    description: Specify that the controller only has playback
>>> capability.
>>> +    type: boolean
>>> +
>>> +  rockchip,capture-only:
>>> +    description: Specify that the controller only has capture capability.
>>> +    type: boolean
>>
>> Could those be inferred from the compatible string, or are there cases
>> where you have multiple instances of the IP block in different
>> configurations within the same SoC? (Or if it's merely reflecting
>> whether the respective interface is actually wired up externally, could
>> that be inferred from the attached codec?)
>>
>> Robin.
>>
> 
> They can't be inferred from the SoC because there are indeed multiple
> instances of this IP block in different configurations on the same SoC.
> The RK3566 and RK3568 have four in total, of two different categories,
> each being able to be configured for a different format (though the
> number of channels and available formats vary for the two categories,
> one group only supports I2S and PCM with two channels)
> 
> The particular configuration may even vary per-board; an I2S/TDM
> controller may be connected to an external codec which does not
> support capture, whereas on another board it may be connected to
> one that does.

Fair enough again, but surely if the codec doesn't support capture then 
in the end no capture interface is going to be exposed anyway - does the 
low-level transport need to care?

> As an example, if I understand it correctly, I2S3 on the RK3566 and
> RK3568 can do 2 channels RX and TX in I2S mode, but only 2 channels
> either RX or TX in PCM mode, but I'm unsure of the language in the
> (still not public) documentation I have.

And that starts to sound like something the driver should probably be 
aware of anyway, but at very least only casts more doubt on these 
particular properties - even if an interface to a stereo PCM codec 
couldn't support simultaneous playback and recording, couldn't it still 
support doing either, separately?

Robin.


From romain.perier at gmail.com  Thu Aug 19 10:02:58 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Thu, 19 Aug 2021 19:02:58 +0200
Subject: [PATCH v3 0/3] Add RTC for MStar SoCs
Message-ID: <20210819170301.10520-1-romain.perier@gmail.com>

This patches series adds a new driver for the RTC found in the Mstar
MSC313e SoCs and newer. It adds a basic rtc driver, the corresponding
devicetree bindings and its documentation.

The rtctest (from selftests) has been passed on this driver, with the
following output:
$ rtctest 
TAP version 13
1..7
# Starting 7 tests from 2 test cases.
#  RUN           rtc.date_read ...
# rtctest.c:47:date_read:Current RTC date/time is 01/01/1970 00:02:03.
#            OK  rtc.date_read
ok 1 rtc.date_read
#  RUN           rtc.uie_read ...
#            OK  rtc.uie_read
ok 2 rtc.uie_read
#  RUN           rtc.uie_select ...
#            OK  rtc.uie_select
ok 3 rtc.uie_select
#  RUN           rtc.alarm_alm_set ...
# rtctest.c:136:alarm_alm_set:Alarm time now set to 00:02:12.
# rtctest.c:156:alarm_alm_set:data: 1a0
#            OK  rtc.alarm_alm_set
ok 4 rtc.alarm_alm_set
#  RUN           rtc.alarm_wkalm_set ...
# rtctest.c:192:alarm_wkalm_set:Alarm time now set to 01/01/1970 00:02:15.
#            OK  rtc.alarm_wkalm_set
ok 5 rtc.alarm_wkalm_set
#  RUN           rtc.alarm_alm_set_minute ...
# rtctest.c:238:alarm_alm_set_minute:Alarm time now set to 00:03:00.
# rtctest.c:258:alarm_alm_set_minute:data: 1a0
#            OK  rtc.alarm_alm_set_minute
ok 6 [  180.545015] random: fast init done
rtc.alarm_alm_set_minute
#  RUN           rtc.alarm_wkalm_set_minute ...
# rtctest.c:294:alarm_wkalm_set_minute:Alarm time now set to 01/01/1970 00:04:00.
#            OK  rtc.alarm_wkalm_set_minute
ok 7 rtc.alarm_wkalm_set_minute
# PASSED: 7 / 7 tests passed.
# Totals: pass:7 fail:0 xfail:0 xpass:0 skip:0 error:0

Changes since v2:
- Added dual-license header to the dt-bindings documentation
- Reordered dts entries, so the rtc device_node is before the watchdog
  device_node (because it has a lower address)
- Updated rtc range_max to U32_MAX
- Leave range_min to 0 (default value when it is not set at all)
- Fixed the CNT_EN_BIT logic, so .read_time will only read the time when
  the RTC has been previously set and has a valid state (which is not
  the case after a POR).

Changes since v1:
- Fixed the DT bindings documentation and fixed dt_binding_check (an
  include was missing)
- Added || COMPILE_TEST to kconfig
- Removed rtc_valid_tm from msc313_rtc_read_time()
- Removed the last write of the msc313_rtc_set_time() function (not
  required) and improved comments
- Replaced the relaxed io by normal io in msc313_rtc_interrupt()
- Added checks to be sure that the alarm fired in msc313_rtc_interrupt()
- Removed msc313_rtc_remove() (replaced by devm_add_action_or_reset)
- Removed unnecessary software reset of the IP in the probe function
  (the soft reset is never executed, it is a mistake from the initial
  refactoring)
- Switched to devm_rtc_allocate_device() and devm_rtc_register_device(),
  and dropped the error message related to the rtc device allocation
- Added an RTC range by setting .range_min and .range_max
- Added the "start-year" property to the DT bindings documentation


Daniel Palmer (1):
  rtc: Add support for the MSTAR MSC313 RTC

Romain Perier (2):
  dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings
    documentation
  ARM: dts: mstar: Add rtc device node

 .../bindings/rtc/mstar,msc313-rtc.yaml        |  49 ++++
 MAINTAINERS                                   |   1 +
 arch/arm/boot/dts/mstar-v7.dtsi               |   8 +
 drivers/rtc/Kconfig                           |  10 +
 drivers/rtc/Makefile                          |   1 +
 drivers/rtc/rtc-msc313.c                      | 258 ++++++++++++++++++
 6 files changed, 327 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
 create mode 100644 drivers/rtc/rtc-msc313.c

-- 
2.30.2



From romain.perier at gmail.com  Thu Aug 19 10:03:01 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Thu, 19 Aug 2021 19:03:01 +0200
Subject: [PATCH v3 3/3] ARM: dts: mstar: Add rtc device node
In-Reply-To: <20210819170301.10520-1-romain.perier@gmail.com>
References: <20210819170301.10520-1-romain.perier@gmail.com>
Message-ID: <20210819170301.10520-4-romain.perier@gmail.com>

This adds the definition of the rtc device node. The RTC being able to
work with the oscillator at 12Mhz for now, it shares the same xtal than
the watchdog.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 982dba9d28eb..89ebfe4f29da 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -110,12 +110,20 @@ reboot {
 				mask = <0x79>;
 			};
 
+			rtc at 2400 {
+				compatible = "mstar,msc313-rtc";
+				reg = <0x2400 0x40>;
+				clocks = <&xtal_div2>;
+				interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
 			watchdog at 6000 {
 				compatible = "mstar,msc313e-wdt";
 				reg = <0x6000 0x1f>;
 				clocks = <&xtal_div2>;
 			};
 
+
 			intc_fiq: interrupt-controller at 201310 {
 				compatible = "mstar,mst-intc";
 				reg = <0x201310 0x40>;
-- 
2.30.2



From romain.perier at gmail.com  Thu Aug 19 10:03:00 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Thu, 19 Aug 2021 19:03:00 +0200
Subject: [PATCH v3 2/3] rtc: Add support for the MSTAR MSC313 RTC
In-Reply-To: <20210819170301.10520-1-romain.perier@gmail.com>
References: <20210819170301.10520-1-romain.perier@gmail.com>
Message-ID: <20210819170301.10520-3-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

This adds support for the RTC block on the Mstar MSC313e SoCs and newer.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Co-developed-by: Romain Perier <romain.perier at gmail.com>
Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 MAINTAINERS              |   1 +
 drivers/rtc/Kconfig      |  10 ++
 drivers/rtc/Makefile     |   1 +
 drivers/rtc/rtc-msc313.c | 258 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 270 insertions(+)
 create mode 100644 drivers/rtc/rtc-msc313.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fd25e4ecf0b9..ebacdd5e8878 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2220,6 +2220,7 @@ F:	arch/arm/boot/dts/mstar-*
 F:	arch/arm/mach-mstar/
 F:	drivers/clk/mstar/
 F:	drivers/gpio/gpio-msc313.c
+F:	drivers/rtc/rtc-msc313.c
 F:	drivers/watchdog/msc313e_wdt.c
 F:	include/dt-bindings/clock/mstar-*
 F:	include/dt-bindings/gpio/msc313-gpio.h
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 12153d5801ce..9ce4baab5fcf 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1925,4 +1925,14 @@ config RTC_DRV_WILCO_EC
 	  This can also be built as a module. If so, the module will
 	  be named "rtc_wilco_ec".
 
+config RTC_DRV_MSC313
+	tristate "MStar MSC313 RTC"
+        depends on ARCH_MSTARV7 || COMPILE_TEST
+	help
+	  If you say yes here you get support for the Mstar MSC313e On-Chip
+	  Real Time Clock.
+
+	  This driver can also be built as a module, if so, the module
+	  will be called "rtc-msc313".
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2dd0dd956b0e..5efda8a60cee 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_RTC_DRV_MCP795)	+= rtc-mcp795.o
 obj-$(CONFIG_RTC_DRV_MESON)	+= rtc-meson.o
 obj-$(CONFIG_RTC_DRV_MOXART)	+= rtc-moxart.o
 obj-$(CONFIG_RTC_DRV_MPC5121)	+= rtc-mpc5121.o
+obj-$(CONFIG_RTC_DRV_MSC313)	+= rtc-msc313.o
 obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
 obj-$(CONFIG_RTC_DRV_MT2712)	+= rtc-mt2712.o
 obj-$(CONFIG_RTC_DRV_MT6397)	+= rtc-mt6397.o
diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c
new file mode 100644
index 000000000000..8cf5d5fb298f
--- /dev/null
+++ b/drivers/rtc/rtc-msc313.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.
+ * Based on "Real Time Clock driver for msb252x." that was contained
+ * in various MStar kernels.
+ *
+ * (C) 2019 Daniel Palmer
+ * (C) 2021 Romain Perier
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* Registers */
+#define REG_RTC_CTRL		0x00
+#define REG_RTC_FREQ_CW_L	0x04
+#define REG_RTC_FREQ_CW_H	0x08
+#define REG_RTC_LOAD_VAL_L	0x0C
+#define REG_RTC_LOAD_VAL_H	0x10
+#define REG_RTC_MATCH_VAL_L	0x14
+#define REG_RTC_MATCH_VAL_H	0x18
+#define REG_RTC_STATUS_INT	0x1C
+#define REG_RTC_CNT_VAL_L	0x20
+#define REG_RTC_CNT_VAL_H	0x24
+
+/* Control bits for REG_RTC_CTRL */
+#define SOFT_RSTZ_BIT		BIT(0)
+#define CNT_EN_BIT		BIT(1)
+#define WRAP_EN_BIT		BIT(2)
+#define LOAD_EN_BIT		BIT(3)
+#define READ_EN_BIT		BIT(4)
+#define INT_MASK_BIT		BIT(5)
+#define INT_FORCE_BIT		BIT(6)
+#define INT_CLEAR_BIT		BIT(7)
+
+/* Control bits for REG_RTC_STATUS_INT */
+#define RAW_INT_BIT		BIT(0)
+#define ALM_INT_BIT		BIT(1)
+
+struct msc313_rtc {
+	struct rtc_device *rtc_dev;
+	void __iomem *rtc_base;
+	struct clk *clk;
+};
+
+static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+
+	seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)
+			| (readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);
+
+	rtc_time64_to_tm(seconds, &alarm->time);
+
+	if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))
+		alarm->enabled = 1;
+
+	return 0;
+}
+
+static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	if (enabled)
+		reg &= ~INT_MASK_BIT;
+	else
+		reg |= INT_MASK_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+	return 0;
+}
+
+static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+
+	seconds = rtc_tm_to_time64(&alarm->time);
+	writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);
+	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);
+
+	msc313_rtc_alarm_irq_enable(dev, alarm->enabled);
+
+	return 0;
+}
+
+static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)
+{
+	return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;
+}
+
+static void msc313_rtc_set_enabled(struct msc313_rtc *priv)
+{
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	reg |= CNT_EN_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+}
+
+static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	u32 seconds;
+	u16 reg;
+
+	if (!msc313_rtc_get_enabled(priv))
+		return -EINVAL;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
+
+	/* Wait for HW latch done */
+	while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)
+		udelay(1);
+
+	seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)
+			| (readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);
+
+	rtc_time64_to_tm(seconds, tm);
+
+	return 0;
+}
+
+static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+	u16 reg;
+
+	seconds = rtc_tm_to_time64(tm);
+	writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);
+	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);
+
+	/* Enable load for loading value into internal RTC counter */
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
+
+	/* Wait for HW latch done */
+	while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
+		udelay(1);
+	msc313_rtc_set_enabled(priv);
+	return 0;
+}
+
+static const struct rtc_class_ops msc313_rtc_ops = {
+	.read_time = msc313_rtc_read_time,
+	.set_time = msc313_rtc_set_time,
+	.read_alarm = msc313_rtc_read_alarm,
+	.set_alarm = msc313_rtc_set_alarm,
+	.alarm_irq_enable = msc313_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev_id);
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);
+	if (!(reg & ALM_INT_BIT))
+		return IRQ_NONE;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	reg |= INT_CLEAR_BIT;
+	reg &= ~INT_FORCE_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+
+	rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static int msc313_rtc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct msc313_rtc *priv;
+	int ret;
+	int irq;
+	unsigned long rate;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->rtc_base))
+		return PTR_ERR(priv->rtc_base);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return -EINVAL;
+
+	priv->rtc_dev = devm_rtc_allocate_device(dev);
+	if (IS_ERR(priv->rtc_dev))
+		return PTR_ERR(priv->rtc_dev);
+
+	priv->rtc_dev->ops = &msc313_rtc_ops;
+	priv->rtc_dev->range_max = U32_MAX;
+
+	ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
+			       dev_name(&pdev->dev), &pdev->dev);
+	if (ret) {
+		dev_err(dev, "Could not request IRQ\n");
+		return ret;
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "No input reference clock\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, priv->clk);
+	if (ret)
+		return ret;
+
+	rate = clk_get_rate(priv->clk);
+	writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
+	writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_rtc_register_device(priv->rtc_dev);
+}
+
+static const struct of_device_id msc313_rtc_of_match_table[] = {
+	{ .compatible = "mstar,msc313-rtc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ms_rtc_of_match_table);
+
+static struct platform_driver msc313_rtc_driver = {
+	.probe = msc313_rtc_probe,
+	.driver = {
+		.name = "msc313-rtc",
+		.of_match_table = msc313_rtc_of_match_table,
+	},
+};
+
+module_platform_driver(msc313_rtc_driver);
+
+MODULE_AUTHOR("Daniel Palmer <daniel at thingy.jp>");
+MODULE_AUTHOR("Romain Perier <romain.perier at gmail.com>");
+MODULE_DESCRIPTION("MStar RTC Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.30.2



From romain.perier at gmail.com  Thu Aug 19 10:02:59 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Thu, 19 Aug 2021 19:02:59 +0200
Subject: [PATCH v3 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree
 bindings documentation
In-Reply-To: <20210819170301.10520-1-romain.perier@gmail.com>
References: <20210819170301.10520-1-romain.perier@gmail.com>
Message-ID: <20210819170301.10520-2-romain.perier@gmail.com>

This adds the documentation for the devicetree bindings of the Mstar
MSC313e RTC driver, found from MSC313e SoCs and newer.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 .../bindings/rtc/mstar,msc313-rtc.yaml        | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml

diff --git a/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
new file mode 100644
index 000000000000..114199cf4d28
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/mstar,msc313-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mstar MSC313e RTC Device Tree Bindings
+
+allOf:
+  - $ref: "rtc.yaml#"
+
+maintainers:
+  - Daniel Palmer <daniel at 0x0f.com>
+  - Romain Perier <romain.perier at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mstar,msc313-rtc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  start-year: true
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    rtc at 2400 {
+        compatible = "mstar,msc313-rtc";
+        reg = <0x2400 0x40>;
+        clocks = <&xtal_div2>;
+        interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+    };
+...
-- 
2.30.2



From tharvey at gateworks.com  Thu Aug 19 10:19:46 2021
From: tharvey at gateworks.com (Tim Harvey)
Date: Thu, 19 Aug 2021 10:19:46 -0700
Subject: arm32 insecure W+X mapping
Message-ID: <CAJ+vNU0PaPNHbJc5RXgrRYJw2aWowrGVMOrU1=hKhsCTXAB=DA@mail.gmail.com>

Greetings,

Since commit a8e53c151fe7 "(ARM: 8737/1: mm: dump: add checking for
writable and executable)" I've been seeing the following appear on my
arm32 kernel:

arm/mm: Found insecure W+X mapping at address 0xf087d000
...
Checked W+X mappings: FAILED, 1 W+X pages found

As I haven't seen others report this I assume it's something unique to
my kernel configuration. How do I debug what is causing the insecure
page?

Best regards,

Tim


From lkp at intel.com  Thu Aug 19 10:27:30 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 20 Aug 2021 01:27:30 +0800
Subject: [PATCH v2 4/5] soc: aspeed: Add eSPI driver
In-Reply-To: <20210819080040.31242-5-chiawei_wang@aspeedtech.com>
References: <20210819080040.31242-5-chiawei_wang@aspeedtech.com>
Message-ID: <202108200149.MsDMcZt1-lkp@intel.com>

Hi Chia-Wei,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on arm/for-next keystone/next soc/for-next rockchip/for-next arm64/for-next/core linus/master joel-aspeed/for-next v5.14-rc6 next-20210819]
[cannot apply to xlnx/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chia-Wei-Wang/arm-aspeed-Add-eSPI-support/20210819-160303
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: sh-allmodconfig (attached as .config)
compiler: sh4-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/cd398492dc8a9d27e1f7b546f1f4df371f058566
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chia-Wei-Wang/arm-aspeed-Add-eSPI-support/20210819-160303
        git checkout cd398492dc8a9d27e1f7b546f1f4df371f058566
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=sh 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All error/warnings (new ones prefixed by >>):

   In file included from drivers/soc/aspeed/aspeed-espi-ctrl.c:21:
   drivers/soc/aspeed/aspeed-espi-perif.h: In function 'aspeed_espi_perif_pc_get_rx':
>> drivers/soc/aspeed/aspeed-espi-perif.h:106:15: error: implicit declaration of function 'vmalloc'; did you mean 'kvmalloc'? [-Werror=implicit-function-declaration]
     106 |         pkt = vmalloc(pkt_len);
         |               ^~~~~~~
         |               kvmalloc
>> drivers/soc/aspeed/aspeed-espi-perif.h:106:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     106 |         pkt = vmalloc(pkt_len);
         |             ^
   drivers/soc/aspeed/aspeed-espi-perif.h: In function 'aspeed_espi_perif_pc_put_tx':
   drivers/soc/aspeed/aspeed-espi-perif.h:163:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     163 |         pkt = vmalloc(ioc->pkt_len);
         |             ^
>> drivers/soc/aspeed/aspeed-espi-perif.h:202:9: error: implicit declaration of function 'vfree'; did you mean 'kfree'? [-Werror=implicit-function-declaration]
     202 |         vfree(pkt);
         |         ^~~~~
         |         kfree
   drivers/soc/aspeed/aspeed-espi-perif.h: In function 'aspeed_espi_perif_np_put_tx':
   drivers/soc/aspeed/aspeed-espi-perif.h:230:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     230 |         pkt = vmalloc(ioc->pkt_len);
         |             ^
   In file included from drivers/soc/aspeed/aspeed-espi-ctrl.c:23:
   drivers/soc/aspeed/aspeed-espi-oob.h: In function 'aspeed_espi_oob_dma_desc_get_rx':
>> drivers/soc/aspeed/aspeed-espi-oob.h:106:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     106 |         pkt = vmalloc(pkt_len);
         |             ^
   drivers/soc/aspeed/aspeed-espi-oob.h: In function 'aspeed_espi_oob_get_rx':
   drivers/soc/aspeed/aspeed-espi-oob.h:203:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     203 |         pkt = vmalloc(pkt_len);
         |             ^
   drivers/soc/aspeed/aspeed-espi-oob.h: In function 'aspeed_espi_oob_dma_desc_put_tx':
>> drivers/soc/aspeed/aspeed-espi-oob.h:262:15: error: implicit declaration of function 'vzalloc'; did you mean 'kvzalloc'? [-Werror=implicit-function-declaration]
     262 |         pkt = vzalloc(ioc->pkt_len);
         |               ^~~~~~~
         |               kvzalloc
   drivers/soc/aspeed/aspeed-espi-oob.h:262:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     262 |         pkt = vzalloc(ioc->pkt_len);
         |             ^
   drivers/soc/aspeed/aspeed-espi-oob.h: In function 'aspeed_espi_oob_put_tx':
   drivers/soc/aspeed/aspeed-espi-oob.h:334:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     334 |         pkt = vmalloc(ioc->pkt_len);
         |             ^
   In file included from drivers/soc/aspeed/aspeed-espi-ctrl.c:24:
   drivers/soc/aspeed/aspeed-espi-flash.h: In function 'aspeed_espi_flash_get_rx':
>> drivers/soc/aspeed/aspeed-espi-flash.h:119:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     119 |         pkt = vmalloc(pkt_len);
         |             ^
   drivers/soc/aspeed/aspeed-espi-flash.h: In function 'aspeed_espi_flash_put_tx':
   drivers/soc/aspeed/aspeed-espi-flash.h:186:13: warning: assignment to 'uint8_t *' {aka 'unsigned char *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
     186 |         pkt = vmalloc(ioc->pkt_len);
         |             ^
   drivers/soc/aspeed/aspeed-espi-ctrl.c: In function 'aspeed_espi_ctrl_probe':
   drivers/soc/aspeed/aspeed-espi-ctrl.c:93:24: warning: unused variable 'scu' [-Wunused-variable]
      93 |         struct regmap *scu;
         |                        ^~~
   drivers/soc/aspeed/aspeed-espi-ctrl.c:90:18: warning: unused variable 'reg' [-Wunused-variable]
      90 |         uint32_t reg;
         |                  ^~~
   cc1: some warnings being treated as errors

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_PDC
   Depends on SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && HAS_DMA
   Selected by
   - SND_ATMEL_SOC_SSC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC
   - SND_ATMEL_SOC_SSC_PDC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && ATMEL_SSC


vim +106 drivers/soc/aspeed/aspeed-espi-perif.h

    46	
    47	static long aspeed_espi_perif_pc_get_rx(struct file *fp,
    48						struct aspeed_espi_ioc *ioc,
    49						struct aspeed_espi_perif *espi_perif)
    50	{
    51		int i, rc;
    52		uint32_t reg;
    53		uint32_t cyc, tag, len;
    54		uint8_t *pkt;
    55		uint32_t pkt_len;
    56		struct espi_comm_hdr *hdr;
    57		unsigned long flags;
    58		struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
    59	
    60		if (!espi_perif->rx_ready) {
    61			if (fp->f_flags & O_NONBLOCK)
    62				return -ENODATA;
    63	
    64			rc = wait_event_interruptible(espi_perif->wq, espi_perif->rx_ready);
    65			if (rc == -ERESTARTSYS)
    66				return -EINTR;
    67		}
    68	
    69		/* common header (i.e. cycle type, tag, and length) is taken by HW */
    70		regmap_read(espi_ctrl->map, ESPI_PERIF_PC_RX_CTRL, &reg);
    71		cyc = (reg & ESPI_PERIF_PC_RX_CTRL_CYC_MASK) >> ESPI_PERIF_PC_RX_CTRL_CYC_SHIFT;
    72		tag = (reg & ESPI_PERIF_PC_RX_CTRL_TAG_MASK) >> ESPI_PERIF_PC_RX_CTRL_TAG_SHIFT;
    73		len = (reg & ESPI_PERIF_PC_RX_CTRL_LEN_MASK) >> ESPI_PERIF_PC_RX_CTRL_LEN_SHIFT;
    74	
    75		/*
    76		 * calculate the length of the rest part of the
    77		 * eSPI packet to be read from HW and copied to
    78		 * user space.
    79		 */
    80		switch (cyc) {
    81		case ESPI_PERIF_MSG:
    82			pkt_len = len + sizeof(struct espi_perif_msg);
    83			break;
    84		case ESPI_PERIF_MSG_D:
    85			pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
    86				  sizeof(struct espi_perif_msg);
    87			break;
    88		case ESPI_PERIF_SUC_CMPLT_D_MIDDLE:
    89		case ESPI_PERIF_SUC_CMPLT_D_FIRST:
    90		case ESPI_PERIF_SUC_CMPLT_D_LAST:
    91		case ESPI_PERIF_SUC_CMPLT_D_ONLY:
    92			pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
    93				  sizeof(struct espi_perif_cmplt);
    94			break;
    95		case ESPI_PERIF_SUC_CMPLT:
    96		case ESPI_PERIF_UNSUC_CMPLT:
    97			pkt_len = len + sizeof(struct espi_perif_cmplt);
    98			break;
    99		default:
   100			return -EFAULT;
   101		}
   102	
   103		if (ioc->pkt_len < pkt_len)
   104			return -EINVAL;
   105	
 > 106		pkt = vmalloc(pkt_len);
   107		if (!pkt)
   108			return -ENOMEM;
   109	
   110		hdr = (struct espi_comm_hdr *)pkt;
   111		hdr->cyc = cyc;
   112		hdr->tag = tag;
   113		hdr->len_h = len >> 8;
   114		hdr->len_l = len & 0xff;
   115	
   116		if (espi_perif->dma_mode) {
   117			memcpy(hdr + 1, espi_perif->dma.pc_rx_virt,
   118			       pkt_len - sizeof(*hdr));
   119		} else {
   120			for (i = sizeof(*hdr); i < pkt_len; ++i) {
   121				regmap_read(espi_ctrl->map,
   122					    ESPI_PERIF_PC_RX_PORT, &reg);
   123				pkt[i] = reg & 0xff;
   124			}
   125		}
   126	
   127		if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len))
   128			return -EFAULT;
   129	
   130		spin_lock_irqsave(&espi_perif->rx_lock, flags);
   131	
   132		regmap_write_bits(espi_ctrl->map, ESPI_PERIF_PC_RX_CTRL,
   133				  ESPI_PERIF_PC_RX_CTRL_PEND_SERV,
   134				  ESPI_PERIF_PC_RX_CTRL_PEND_SERV);
   135	
   136		espi_perif->rx_ready = 0;
   137	
   138		spin_unlock_irqrestore(&espi_perif->rx_lock, flags);
   139	
   140		return pkt_len;
   141	}
   142	
   143	static long aspeed_espi_perif_pc_put_tx(struct file *fp,
   144						struct aspeed_espi_ioc *ioc,
   145						struct aspeed_espi_perif *espi_perif)
   146	{
   147		int i, rc = 0;
   148		uint32_t reg;
   149		uint32_t cyc, tag, len;
   150		uint8_t *pkt;
   151		struct espi_comm_hdr *hdr;
   152		struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
   153	
   154		if (!mutex_trylock(&espi_perif->pc_tx_lock))
   155			return -EAGAIN;
   156	
   157		regmap_read(espi_ctrl->map, ESPI_PERIF_PC_TX_CTRL, &reg);
   158		if (reg & ESPI_PERIF_PC_TX_CTRL_TRIGGER) {
   159			rc = -EBUSY;
   160			goto unlock_n_out;
   161		}
   162	
   163		pkt = vmalloc(ioc->pkt_len);
   164		if (!pkt) {
   165			rc = -ENOMEM;
   166			goto unlock_n_out;
   167		}
   168	
   169		hdr = (struct espi_comm_hdr *)pkt;
   170	
   171		if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
   172			rc = -EFAULT;
   173			goto free_n_out;
   174		}
   175	
   176		/*
   177		 * common header (i.e. cycle type, tag, and length)
   178		 * part is written to HW registers
   179		 */
   180		if (espi_perif->dma_mode) {
   181			memcpy(espi_perif->dma.pc_tx_virt, hdr + 1,
   182			       ioc->pkt_len - sizeof(*hdr));
   183			dma_wmb();
   184		} else {
   185			for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
   186				regmap_write(espi_ctrl->map,
   187					     ESPI_PERIF_PC_TX_PORT, pkt[i]);
   188		}
   189	
   190		cyc = hdr->cyc;
   191		tag = hdr->tag;
   192		len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
   193	
   194		reg = ((cyc << ESPI_PERIF_PC_TX_CTRL_CYC_SHIFT) & ESPI_PERIF_PC_TX_CTRL_CYC_MASK)
   195			| ((tag << ESPI_PERIF_PC_TX_CTRL_TAG_SHIFT) & ESPI_PERIF_PC_TX_CTRL_TAG_MASK)
   196			| ((len << ESPI_PERIF_PC_TX_CTRL_LEN_SHIFT) & ESPI_PERIF_PC_TX_CTRL_LEN_MASK)
   197			| ESPI_PERIF_PC_TX_CTRL_TRIGGER;
   198	
   199		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_TX_CTRL, reg);
   200	
   201	free_n_out:
 > 202		vfree(pkt);
   203	
   204	unlock_n_out:
   205		mutex_unlock(&espi_perif->pc_tx_lock);
   206	
   207		return rc;
   208	}
   209	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 55035 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210820/76379540/attachment-0001.gz>

From broonie at kernel.org  Thu Aug 19 10:29:02 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 18:29:02 +0100
Subject: [PATCH] kselftest/arm64: mte: Fix misleading output when skipping
 tests
Message-ID: <20210819172902.56211-1-broonie@kernel.org>

When skipping the tests due to a lack of system support for MTE we
currently print a message saying FAIL which makes it look like the test
failed even though the test did actually report KSFT_SKIP, creating some
confusion. Change the error message to say SKIP instead so things are
clearer.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/mte/mte_common_util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/mte/mte_common_util.c b/tools/testing/selftests/arm64/mte/mte_common_util.c
index f50ac31920d1..0328a1e08f65 100644
--- a/tools/testing/selftests/arm64/mte/mte_common_util.c
+++ b/tools/testing/selftests/arm64/mte/mte_common_util.c
@@ -298,7 +298,7 @@ int mte_default_setup(void)
 	int ret;
 
 	if (!(hwcaps2 & HWCAP2_MTE)) {
-		ksft_print_msg("FAIL: MTE features unavailable\n");
+		ksft_print_msg("SKIP: MTE features unavailable\n");
 		return KSFT_SKIP;
 	}
 	/* Get current mte mode */
-- 
2.20.1



From nicolas.dufresne at collabora.com  Thu Aug 19 10:54:59 2021
From: nicolas.dufresne at collabora.com (Nicolas Dufresne)
Date: Thu, 19 Aug 2021 13:54:59 -0400
Subject: [PATCH] media: cedrus: Fix SUNXI tile size calculation
In-Reply-To: <3519986.qLKfoAsNv3@jernej-laptop>
References: <20210819140009.158156-1-nicolas.dufresne@collabora.com>
 <3519986.qLKfoAsNv3@jernej-laptop>
Message-ID: <4b67e381c3c6819d5888f4ca713db5236b58d951.camel@collabora.com>

Le jeudi 19 ao?t 2021 ? 18:30 +0200, Jernej ?krabec a ?crit?:
> Hi Nicolas!
> 
> Dne ?etrtek, 19. avgust 2021 ob 16:00:09 CEST je Nicolas Dufresne napisal(a):
> > Tiled formats requires full rows being allocated (even for Chroma
> > planes). When the number of Luma tiles is odd, we need to round up
> > to twice the tile width in order to roundup the number of Chroma
> > tiles.
> > 
> > This was notice with a crash running BA1_FT_C compliance test using
> > sunxi tiles using GStreamer. Cedrus driver would allocate 9 rows for
> > Luma, but only 4.5 rows for Chroma, causing userspace to crash.
> > 
> > Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> 
> Fixes tag would be nice so it would be picked up for stable branches. 
> Otherwise it looks good. It also aligns logic with libvdpau-sunxi.

Sure, I'd say can be merged adding (it was broken since when cedrus was added):

Fixes: 50e761516f2b8 ("media: platform: Add Cedrus VPU decoder driver")

> 
> Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> 
> Best regards,
> Jernej
> 
> 




From maz at kernel.org  Thu Aug 19 11:03:05 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 19 Aug 2021 19:03:05 +0100
Subject: [PATCH v2] KVM: arm64: vgic: Resample HW pending state on deactivation
Message-ID: <20210819180305.1670525-1-maz@kernel.org>

When a mapped level interrupt (a timer, for example) is deactivated
by the guest, the corresponding host interrupt is equally deactivated.
However, the fate of the pending state still needs to be dealt
with in SW.

This is specially true when the interrupt was in the active+pending
state in the virtual distributor at the point where the guest
was entered. On exit, the pending state is potentially stale
(the guest may have put the interrupt in a non-pending state).

If we don't do anything, the interrupt will be spuriously injected
in the guest. Although this shouldn't have any ill effect (spurious
interrupts are always possible), we can improve the emulation by
detecting the deactivation-while-pending case and resample the
interrupt.

While we're at it, move the logic into a common helper that can
be shared between the two GIC implementations.

Fixes: e40cc57bac79 ("KVM: arm/arm64: vgic: Support level-triggered mapped interrupts")
Reported-by: Raghavendra Rao Ananta <rananta at google.com>
Tested-by: Raghavendra Rao Ananta <rananta at google.com>
Reviewed-by: Oliver Upton <oupton at google.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org
---

Notes:
    * From v1:
      - Moved the resampling into a separate helper, and pointed both
        GIC implementations to it.
      - Collected TB, RB, with thanks.

 arch/arm64/kvm/vgic/vgic-v2.c | 36 +++++----------------------------
 arch/arm64/kvm/vgic/vgic-v3.c | 36 +++++----------------------------
 arch/arm64/kvm/vgic/vgic.c    | 38 +++++++++++++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic.h    |  2 ++
 4 files changed, 50 insertions(+), 62 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
index 2c580204f1dc..95a18cec14a3 100644
--- a/arch/arm64/kvm/vgic/vgic-v2.c
+++ b/arch/arm64/kvm/vgic/vgic-v2.c
@@ -60,6 +60,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 		u32 val = cpuif->vgic_lr[lr];
 		u32 cpuid, intid = val & GICH_LR_VIRTUALID;
 		struct vgic_irq *irq;
+		bool deactivated;
 
 		/* Extract the source vCPU id from the LR */
 		cpuid = val & GICH_LR_PHYSID_CPUID;
@@ -75,7 +76,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 
 		raw_spin_lock(&irq->irq_lock);
 
-		/* Always preserve the active bit */
+		/* Always preserve the active bit, note deactivation */
+		deactivated = irq->active && !(val & GICH_LR_ACTIVE_BIT);
 		irq->active = !!(val & GICH_LR_ACTIVE_BIT);
 
 		if (irq->active && vgic_irq_is_sgi(intid))
@@ -96,36 +98,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
 		if (irq->config == VGIC_CONFIG_LEVEL && !(val & GICH_LR_STATE))
 			irq->pending_latch = false;
 
-		/*
-		 * Level-triggered mapped IRQs are special because we only
-		 * observe rising edges as input to the VGIC.
-		 *
-		 * If the guest never acked the interrupt we have to sample
-		 * the physical line and set the line level, because the
-		 * device state could have changed or we simply need to
-		 * process the still pending interrupt later.
-		 *
-		 * If this causes us to lower the level, we have to also clear
-		 * the physical active state, since we will otherwise never be
-		 * told when the interrupt becomes asserted again.
-		 *
-		 * Another case is when the interrupt requires a helping hand
-		 * on deactivation (no HW deactivation, for example).
-		 */
-		if (vgic_irq_is_mapped_level(irq)) {
-			bool resample = false;
-
-			if (val & GICH_LR_PENDING_BIT) {
-				irq->line_level = vgic_get_phys_line_level(irq);
-				resample = !irq->line_level;
-			} else if (vgic_irq_needs_resampling(irq) &&
-				   !(irq->active || irq->pending_latch)) {
-				resample = true;
-			}
-
-			if (resample)
-				vgic_irq_set_phys_active(irq, false);
-		}
+		/* Handle resampling for mapped interrupts if required */
+		vgic_irq_handle_resampling(irq, deactivated, val & GICH_LR_PENDING_BIT);
 
 		raw_spin_unlock(&irq->irq_lock);
 		vgic_put_irq(vcpu->kvm, irq);
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 66004f61cd83..21a6207fb2ee 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -46,6 +46,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 		u32 intid, cpuid;
 		struct vgic_irq *irq;
 		bool is_v2_sgi = false;
+		bool deactivated;
 
 		cpuid = val & GICH_LR_PHYSID_CPUID;
 		cpuid >>= GICH_LR_PHYSID_CPUID_SHIFT;
@@ -68,7 +69,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 
 		raw_spin_lock(&irq->irq_lock);
 
-		/* Always preserve the active bit */
+		/* Always preserve the active bit, note deactivation */
+		deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT);
 		irq->active = !!(val & ICH_LR_ACTIVE_BIT);
 
 		if (irq->active && is_v2_sgi)
@@ -89,36 +91,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 		if (irq->config == VGIC_CONFIG_LEVEL && !(val & ICH_LR_STATE))
 			irq->pending_latch = false;
 
-		/*
-		 * Level-triggered mapped IRQs are special because we only
-		 * observe rising edges as input to the VGIC.
-		 *
-		 * If the guest never acked the interrupt we have to sample
-		 * the physical line and set the line level, because the
-		 * device state could have changed or we simply need to
-		 * process the still pending interrupt later.
-		 *
-		 * If this causes us to lower the level, we have to also clear
-		 * the physical active state, since we will otherwise never be
-		 * told when the interrupt becomes asserted again.
-		 *
-		 * Another case is when the interrupt requires a helping hand
-		 * on deactivation (no HW deactivation, for example).
-		 */
-		if (vgic_irq_is_mapped_level(irq)) {
-			bool resample = false;
-
-			if (val & ICH_LR_PENDING_BIT) {
-				irq->line_level = vgic_get_phys_line_level(irq);
-				resample = !irq->line_level;
-			} else if (vgic_irq_needs_resampling(irq) &&
-				   !(irq->active || irq->pending_latch)) {
-				resample = true;
-			}
-
-			if (resample)
-				vgic_irq_set_phys_active(irq, false);
-		}
+		/* Handle resampling for mapped interrupts if required */
+		vgic_irq_handle_resampling(irq, deactivated, val & ICH_LR_PENDING_BIT);
 
 		raw_spin_unlock(&irq->irq_lock);
 		vgic_put_irq(vcpu->kvm, irq);
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 111bff47e471..42a6ac78fe95 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -1022,3 +1022,41 @@ bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid)
 
 	return map_is_active;
 }
+
+/*
+ * Level-triggered mapped IRQs are special because we only observe rising
+ * edges as input to the VGIC.
+ *
+ * If the guest never acked the interrupt we have to sample the physical
+ * line and set the line level, because the device state could have changed
+ * or we simply need to process the still pending interrupt later.
+ *
+ * We could also have entered the guest with the interrupt active+pending.
+ * On the next exit, we need to re-evaluate the pending state, as it could
+ * otherwise result in a spurious interrupt by injecting a now potentially
+ * stale pending state.
+ *
+ * If this causes us to lower the level, we have to also clear the physical
+ * active state, since we will otherwise never be told when the interrupt
+ * becomes asserted again.
+ *
+ * Another case is when the interrupt requires a helping hand on
+ * deactivation (no HW deactivation, for example).
+ */
+void vgic_irq_handle_resampling(struct vgic_irq *irq,
+				bool lr_deactivated, bool lr_pending)
+{
+	if (vgic_irq_is_mapped_level(irq)) {
+		bool resample = false;
+
+		if (unlikely(vgic_irq_needs_resampling(irq))) {
+			resample = !(irq->active || irq->pending_latch);
+		} else if (lr_pending || (lr_deactivated && irq->line_level)) {
+			irq->line_level = vgic_get_phys_line_level(irq);
+			resample = !irq->line_level;
+		}
+
+		if (resample)
+			vgic_irq_set_phys_active(irq, false);
+	}
+}
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index dc1f3d1657ee..14a9218641f5 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -169,6 +169,8 @@ void vgic_irq_set_phys_active(struct vgic_irq *irq, bool active);
 bool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq,
 			   unsigned long flags);
 void vgic_kick_vcpus(struct kvm *kvm);
+void vgic_irq_handle_resampling(struct vgic_irq *irq,
+				bool lr_deactivated, bool lr_pending);
 
 int vgic_check_ioaddr(struct kvm *kvm, phys_addr_t *ioaddr,
 		      phys_addr_t addr, phys_addr_t alignment);
-- 
2.30.2



From paulmck at kernel.org  Thu Aug 19 11:20:35 2021
From: paulmck at kernel.org (Paul E. McKenney)
Date: Thu, 19 Aug 2021 11:20:35 -0700
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20210819154708.3efz6jtgwtuhpeds@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
 <20210819153927.clqxr4f7qegpflbr@linutronix.de>
 <20210819154708.3efz6jtgwtuhpeds@linutronix.de>
Message-ID: <20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-1>

On Thu, Aug 19, 2021 at 05:47:08PM +0200, Sebastian Andrzej Siewior wrote:
> On 2021-08-19 17:39:29 [+0200], To Paul E. McKenney wrote:
> > up with following which I can explain:
> > 
> > diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> > index 40ef5417d9545..5c8b31b7eff03 100644
> > --- a/kernel/rcu/rcutorture.c
> > +++ b/kernel/rcu/rcutorture.c
> > @@ -1432,28 +1432,34 @@ static void rcutorture_one_extend(int *readstate, int newstate,
> >  	/* First, put new protection in place to avoid critical-section gap. */
> >  	if (statesnew & RCUTORTURE_RDR_BH)
> >  		local_bh_disable();
> > +	if (statesnew & RCUTORTURE_RDR_RBH)
> > +		rcu_read_lock_bh();
> >  	if (statesnew & RCUTORTURE_RDR_IRQ)
> >  		local_irq_disable();
> >  	if (statesnew & RCUTORTURE_RDR_PREEMPT)
> >  		preempt_disable();
> > -	if (statesnew & RCUTORTURE_RDR_RBH)
> > -		rcu_read_lock_bh();
> >  	if (statesnew & RCUTORTURE_RDR_SCHED)
> >  		rcu_read_lock_sched();
> >  	if (statesnew & RCUTORTURE_RDR_RCU)
> >  		idxnew = cur_ops->readlock() << RCUTORTURE_RDR_SHIFT;
> 
> So the ordering in the enable and disable part regarding BH is
> important. First BH, then preemption or IRQ.
> 
> > -	/* Next, remove old protection, irq first due to bh conflict. */
> > +	/*
> > +	 * Next, remove old protection, in decreasing order of strength
> > +	 * to avoid unlock paths that aren't safe in the stronger
> > +	 * context. Namely: BH can not be enabled with disabled interrupts.
> > +	 * Additionally PREEMPT_RT requires that BH is enabled in preemptible
> > +	 * context.
> > +	 */
> >  	if (statesold & RCUTORTURE_RDR_IRQ)
> >  		local_irq_enable();
> > -	if (statesold & RCUTORTURE_RDR_BH)
> > -		local_bh_enable();
> >  	if (statesold & RCUTORTURE_RDR_PREEMPT)
> >  		preempt_enable();
> > -	if (statesold & RCUTORTURE_RDR_RBH)
> > -		rcu_read_unlock_bh();
> >  	if (statesold & RCUTORTURE_RDR_SCHED)
> >  		rcu_read_unlock_sched();
> > +	if (statesold & RCUTORTURE_RDR_BH)
> > +		local_bh_enable();
> > +	if (statesold & RCUTORTURE_RDR_RBH)
> > +		rcu_read_unlock_bh();
> >  	if (statesold & RCUTORTURE_RDR_RCU) {
> >  		bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);
> 
> The same in the unlock part so that BH is unlocked in preemptible
> context.
> Now if you need bh lock/unlock in atomic context (either with disabled
> IRQs or preemption) then I would dig out the atomic-bh part again and
> make !RT only without the preempt_disable() section around about which
> one you did complain.
> 
> > @@ -1496,6 +1502,9 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
> >  	int mask = rcutorture_extend_mask_max();
> >  	unsigned long randmask1 = torture_random(trsp) >> 8;
> >  	unsigned long randmask2 = randmask1 >> 3;
> > +	unsigned long preempts = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;
> > +	unsigned long preempts_irq = preempts | RCUTORTURE_RDR_IRQ;
> > +	unsigned long bhs = RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
> >  
> >  	WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT);
> >  	/* Mostly only one bit (need preemption!), sometimes lots of bits. */
> > @@ -1503,11 +1512,37 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
> >  		mask = mask & randmask2;
> >  	else
> >  		mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS));
> > -	/* Can't enable bh w/irq disabled. */
> > -	if ((mask & RCUTORTURE_RDR_IRQ) &&
> > -	    ((!(mask & RCUTORTURE_RDR_BH) && (oldmask & RCUTORTURE_RDR_BH)) ||
> > -	     (!(mask & RCUTORTURE_RDR_RBH) && (oldmask & RCUTORTURE_RDR_RBH))))
> > -		mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
> > +
> > +	/*
> > +	 * Can't enable bh w/irq disabled.
> > +	 */
> > +	if (mask & RCUTORTURE_RDR_IRQ)
> > +		mask |= oldmask & bhs;
> > +
> > +	/*
> > +	 * Ideally these sequences would be detected in debug builds
> > +	 * (regardless of RT), but until then don't stop testing
> > +	 * them on non-RT.
> > +	 */
> > +	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> > +		/*
> > +		 * Can't release the outermost rcu lock in an irq disabled
> > +		 * section without preemption also being disabled, if irqs
> > +		 * had ever been enabled during this RCU critical section
> > +		 * (could leak a special flag and delay reporting the qs).
> > +		 */
> > +		if ((oldmask & RCUTORTURE_RDR_RCU) &&
> > +		    (mask & RCUTORTURE_RDR_IRQ) &&
> > +		    !(mask & preempts))
> > +			mask |= RCUTORTURE_RDR_RCU;
> 
> This piece above, I don't understand. I had it running for a while and
> it didn't explode. Let me try TREE01 for 30min without that piece.

This might be historical.  There was a time when interrupts being
disabled across rcu_read_unlock() meant that preemption had to have
been disabled across the entire RCU read-side critical section.

I am not seeing a purpose for it now, but I could easily be missing
something, especially given my tenuous grasp of RT.

Either way, looking forward to the next version!

							Thanx, Paul

> > +		/* Can't modify bh in atomic context */
> > +		if (oldmask & preempts_irq)
> > +			mask &= ~bhs;
> > +		if ((oldmask | mask) & preempts_irq)
> > +			mask |= oldmask & bhs;
> 
> And this is needed because we can't lock/unlock bh while atomic.
> 
> > +	}
> > +
> >  	return mask ?: RCUTORTURE_RDR_RCU;
> >  }
> >  
> 
> Sebastian


From krzysztof.kozlowski at canonical.com  Thu Aug 19 11:23:10 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 19 Aug 2021 20:23:10 +0200
Subject: [PATCH 1/2] arm64: dts: allwinner: a64: align operating-points table
 name with dtschema
Message-ID: <20210819182311.223443-1-krzysztof.kozlowski@canonical.com>

Align the name of operating-points node to dtschema to fix warnings like:

  arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dt.yaml:
    opp_table0: $nodename:0: 'opp_table0' does not match '^opp-table(-[a-z0-9]+)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi
index 578c37490d90..d55248bb8ddd 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi
@@ -4,7 +4,7 @@
  */
 
 / {
-	cpu0_opp_table: opp_table0 {
+	cpu0_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Thu Aug 19 11:23:11 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 19 Aug 2021 20:23:11 +0200
Subject: [PATCH 2/2] arm64: dts: rockchip: align operating-points table name
 with dtschema
In-Reply-To: <20210819182311.223443-1-krzysztof.kozlowski@canonical.com>
References: <20210819182311.223443-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210819182311.223443-2-krzysztof.kozlowski@canonical.com>

Align the name of operating-points node to dtschema to fix warnings
like:

  opp-table0: $nodename:0: 'opp-table0' does not match '^opp-table(-[a-z0-9]+)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/rockchip/px30.dtsi           | 4 ++--
 arch/arm64/boot/dts/rockchip/rk3308.dtsi         | 2 +-
 arch/arm64/boot/dts/rockchip/rk3328.dtsi         | 2 +-
 arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi | 6 +++---
 arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi     | 6 +++---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi         | 2 +-
 6 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index 64f643145688..5dbe6bd3b189 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -110,7 +110,7 @@ CLUSTER_SLEEP: cluster-sleep {
 		};
 	};
 
-	cpu0_opp_table: cpu0-opp-table {
+	cpu0_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -1014,7 +1014,7 @@ nfc: nand-controller at ff3b0000 {
 		status = "disabled";
 	};
 
-	gpu_opp_table: opp-table2 {
+	gpu_opp_table: opp-table-1 {
 		compatible = "operating-points-v2";
 
 		opp-200000000 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
index ce6f4a28d169..7ba9ce4e9826 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
@@ -99,7 +99,7 @@ l2: l2-cache {
 		};
 	};
 
-	cpu0_opp_table: cpu0-opp-table {
+	cpu0_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index becc1c61b182..1c1608d8de01 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -105,7 +105,7 @@ l2: l2-cache0 {
 		};
 	};
 
-	cpu0_opp_table: opp_table0 {
+	cpu0_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
index 69cc9b05baa5..2180e0f75003 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
@@ -4,7 +4,7 @@
  */
 
 / {
-	cluster0_opp: opp-table0 {
+	cluster0_opp: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -39,7 +39,7 @@ opp06 {
 		};
 	};
 
-	cluster1_opp: opp-table1 {
+	cluster1_opp: opp-table-1 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -82,7 +82,7 @@ opp08 {
 		};
 	};
 
-	gpu_opp_table: opp-table2 {
+	gpu_opp_table: opp-table-2 {
 		compatible = "operating-points-v2";
 
 		opp00 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi
index da41cd81ebb7..fee5e7111279 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi
@@ -4,7 +4,7 @@
  */
 
 / {
-	cluster0_opp: opp-table0 {
+	cluster0_opp: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -35,7 +35,7 @@ opp05 {
 		};
 	};
 
-	cluster1_opp: opp-table1 {
+	cluster1_opp: opp-table-1 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -74,7 +74,7 @@ opp07 {
 		};
 	};
 
-	gpu_opp_table: opp-table2 {
+	gpu_opp_table: opp-table-2 {
 		compatible = "operating-points-v2";
 
 		opp00 {
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index d89831bee1eb..949322df3b88 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -83,7 +83,7 @@ cpu3: cpu at 300 {
 		};
 	};
 
-	cpu0_opp_table: cpu0-opp-table {
+	cpu0_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
-- 
2.30.2



From robh at kernel.org  Thu Aug 19 11:42:34 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 13:42:34 -0500
Subject: [PATCH 0/5] Arm VExpress/Juno motherboard bus clean-ups
Message-ID: <20210819184239.1192395-1-robh@kernel.org>

I noticed we once again have warnings on VExpress/Juno bus nodes as the
simple-bus schema now expects child nodes to have a unit-address.
Digging into this I noticed the arm,vexpress-juno.yaml schema is out of
date and missing some properties (some of which are unused). I found the
'ranges' handling to be odd as well. This series fixes all those issues.

Rob

Rob Herring (5):
  dt-bindings: arm,vexpress-juno: Fix 'motherboard' node name
  dt-bindings: arm,vexpress-juno: Add missing motherboard properties
  arm: dts: vexpress: Drop unused properties from motherboard node
  arm: dts: vexpress-v2p-ca9: Fix the SMB unit-address
  arm: dts: vexpress: Fix addressing issues with 'motherboard-bus' nodes

 .../bindings/arm/arm,vexpress-juno.yaml       | 46 +++++++++++--------
 arch/arm/boot/dts/vexpress-v2m-rs1.dtsi       | 17 +++++--
 arch/arm/boot/dts/vexpress-v2m.dtsi           | 18 ++++++--
 arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts   | 11 -----
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts    | 11 -----
 arch/arm/boot/dts/vexpress-v2p-ca5s.dts       | 11 -----
 arch/arm/boot/dts/vexpress-v2p-ca9.dts        | 12 +----
 arch/arm64/boot/dts/arm/foundation-v8.dtsi    |  1 -
 arch/arm64/boot/dts/arm/fvp-base-revc.dts     | 11 -----
 arch/arm64/boot/dts/arm/juno-base.dtsi        | 10 ----
 arch/arm64/boot/dts/arm/juno-motherboard.dtsi | 17 +++++--
 arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts    | 11 -----
 .../boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi |  2 +-
 .../boot/dts/arm/rtsm_ve-motherboard.dtsi     | 16 +++++--
 .../boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts | 11 -----
 15 files changed, 78 insertions(+), 127 deletions(-)

-- 
2.30.2



From robh at kernel.org  Thu Aug 19 11:42:35 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 13:42:35 -0500
Subject: [PATCH 1/5] dt-bindings: arm,
 vexpress-juno: Fix 'motherboard' node name
In-Reply-To: <20210819184239.1192395-1-robh@kernel.org>
References: <20210819184239.1192395-1-robh@kernel.org>
Message-ID: <20210819184239.1192395-2-robh@kernel.org>

Commit 9d0a36ddcc52 ("arm64: dts: fvp/juno: Fix bus node names") changed
'motherboard' to 'motherboard-bus', but didn't update the schema. In the
mean time, the simple-bus schema started requiring child nodes to have a
unit-address. Update the schema to address both of these issues.

Cc: Andre Przywara <andre.przywara at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/arm/arm,vexpress-juno.yaml        | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml b/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
index 55ef656d1192..530a808e518a 100644
--- a/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
@@ -154,9 +154,9 @@ patternProperties:
     description: Static Memory Bus (SMB) node, if this exists it describes
       the connection between the motherboard and any tiles. Sometimes the
       compatible is placed directly under this node, sometimes it is placed
-      in a subnode named "motherboard". Sometimes the compatible includes
+      in a subnode named "motherboard-bus". Sometimes the compatible includes
       "arm,vexpress,v2?-p1" sometimes (on software models) is is just
-      "simple-bus". If the compatible is placed in the "motherboard" node,
+      "simple-bus". If the compatible is placed in the "motherboard-bus" node,
       it is stricter and always has two compatibles.
     type: object
     $ref: '/schemas/simple-bus.yaml'
@@ -170,7 +170,9 @@ patternProperties:
                   - arm,vexpress,v2p-p1
               - const: simple-bus
           - const: simple-bus
-      motherboard:
+
+    patternProperties:
+      '^motherboard-bus@':
         type: object
         description: The motherboard description provides a single "motherboard"
           node using 2 address cells corresponding to the Static Memory Bus
-- 
2.30.2



From robh at kernel.org  Thu Aug 19 11:42:36 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 13:42:36 -0500
Subject: [PATCH 2/5] dt-bindings: arm,
 vexpress-juno: Add missing motherboard properties
In-Reply-To: <20210819184239.1192395-1-robh@kernel.org>
References: <20210819184239.1192395-1-robh@kernel.org>
Message-ID: <20210819184239.1192395-3-robh@kernel.org>

The arm,vexpress-juno binding is missing 'ranges', 'arm,vexpress,site', and
'arm,hbi' properties. Add these and and restrict additional properties to
be nodes only.

Cc: Andre Przywara <andre.przywara at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../bindings/arm/arm,vexpress-juno.yaml       | 38 +++++++++++--------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml b/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
index 530a808e518a..a4b4452afc1d 100644
--- a/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
@@ -119,22 +119,6 @@ properties:
           - const: arm,foundation-aarch64
           - const: arm,vexpress
 
-  arm,hbi:
-    $ref: '/schemas/types.yaml#/definitions/uint32'
-    description: This indicates the ARM HBI (Hardware Board ID), this is
-      ARM's unique board model ID, visible on the PCB's silkscreen.
-
-  arm,vexpress,site:
-    description: As Versatile Express can be configured in number of physically
-      different setups, the device tree should describe platform topology.
-      For this reason the root node and main motherboard node must define this
-      property, describing the physical location of the children nodes.
-      0 means motherboard site, while 1 and 2 are daughterboard sites, and
-      0xf means "sisterboard" which is the site containing the main CPU tile.
-    $ref: '/schemas/types.yaml#/definitions/uint32'
-    minimum: 0
-    maximum: 15
-
   arm,vexpress,position:
     description: When daughterboards are stacked on one site, their position
       in the stack be be described this attribute.
@@ -185,6 +169,8 @@ patternProperties:
             const: 2
           "#size-cells":
             const: 1
+          ranges: true
+
           compatible:
             items:
               - enum:
@@ -198,8 +184,28 @@ patternProperties:
               - rs1
               - rs2
 
+          arm,hbi:
+            $ref: '/schemas/types.yaml#/definitions/uint32'
+            description: This indicates the ARM HBI (Hardware Board ID), this is
+              ARM's unique board model ID, visible on the PCB's silkscreen.
+
+          arm,vexpress,site:
+            description: As Versatile Express can be configured in number of physically
+              different setups, the device tree should describe platform topology.
+              For this reason the root node and main motherboard node must define this
+              property, describing the physical location of the children nodes.
+              0 means motherboard site, while 1 and 2 are daughterboard sites, and
+              0xf means "sisterboard" which is the site containing the main CPU tile.
+            $ref: '/schemas/types.yaml#/definitions/uint32'
+            minimum: 0
+            maximum: 15
+
         required:
           - compatible
+
+        additionalProperties:
+          type: object
+
     required:
       - compatible
 
-- 
2.30.2



From robh at kernel.org  Thu Aug 19 11:42:37 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 13:42:37 -0500
Subject: [PATCH 3/5] arm: dts: vexpress: Drop unused properties from
 motherboard node
In-Reply-To: <20210819184239.1192395-1-robh@kernel.org>
References: <20210819184239.1192395-1-robh@kernel.org>
Message-ID: <20210819184239.1192395-4-robh@kernel.org>

Drop the '#interrupt-cells' property in the motherboard node which has no
effect as the node is neither an interrupt-controller or interrupt-map
(that's in the parent node).

Drop 'model' as it is not used by software nor documented.

Drop 'arm,v2m-memory-map' as it is not used by software. The purpose was
to describe which memory map, but that's all described by the DT
already.

Cc: Andre Przywara <andre.przywara at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Rob Herring <robh at kernel.org>
---
 arch/arm/boot/dts/vexpress-v2m-rs1.dtsi          | 3 ---
 arch/arm/boot/dts/vexpress-v2m.dtsi              | 2 --
 arch/arm64/boot/dts/arm/foundation-v8.dtsi       | 1 -
 arch/arm64/boot/dts/arm/juno-motherboard.dtsi    | 3 ---
 arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi | 2 --
 5 files changed, 11 deletions(-)

diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index 2ad9fd7c94ec..f61251b3c74f 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -102,14 +102,11 @@ led-8 {
 
 	bus at 8000000 {
 		motherboard-bus {
-			model = "V2M-P1";
 			arm,hbi = <0x190>;
 			arm,vexpress,site = <0>;
-			arm,v2m-memory-map = "rs1";
 			compatible = "arm,vexpress,v2m-p1", "simple-bus";
 			#address-cells = <2>; /* SMB chipselect number and offset */
 			#size-cells = <1>;
-			#interrupt-cells = <1>;
 			ranges;
 
 			nor_flash: flash at 0 {
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
index ec13ceb9ed36..fb8ca984ce1f 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -21,13 +21,11 @@
 / {
 	bus at 4000000 {
 		motherboard {
-			model = "V2M-P1";
 			arm,hbi = <0x190>;
 			arm,vexpress,site = <0>;
 			compatible = "arm,vexpress,v2m-p1", "simple-bus";
 			#address-cells = <2>; /* SMB chipselect number and offset */
 			#size-cells = <1>;
-			#interrupt-cells = <1>;
 			ranges;
 
 			flash at 0,00000000 {
diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dtsi b/arch/arm64/boot/dts/arm/foundation-v8.dtsi
index 05ae893d1b2e..fbf13f7c2baf 100644
--- a/arch/arm64/boot/dts/arm/foundation-v8.dtsi
+++ b/arch/arm64/boot/dts/arm/foundation-v8.dtsi
@@ -115,7 +115,6 @@ v2m_refclk32khz: refclk32khz {
 
 	bus at 8000000 {
 		compatible = "arm,vexpress,v2m-p1", "simple-bus";
-		arm,v2m-memory-map = "rs1";
 		#address-cells = <2>; /* SMB chipselect number and offset */
 		#size-cells = <1>;
 
diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
index 40d95c58b55e..4203f0a6ddf6 100644
--- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
@@ -96,12 +96,9 @@ motherboard-bus {
 			compatible = "arm,vexpress,v2p-p1", "simple-bus";
 			#address-cells = <2>;  /* SMB chipselect number and offset */
 			#size-cells = <1>;
-			#interrupt-cells = <1>;
 			ranges;
-			model = "V2M-Juno";
 			arm,hbi = <0x252>;
 			arm,vexpress,site = <0>;
-			arm,v2m-memory-map = "rs1";
 
 			flash at 0 {
 				/* 2 * 32MiB NOR Flash memory mounted on CS0 */
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
index 4c4a381d2c75..0459aff22f27 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
@@ -78,11 +78,9 @@ dvimode {
 
 	bus at 8000000 {
 		motherboard-bus {
-			arm,v2m-memory-map = "rs1";
 			compatible = "arm,vexpress,v2m-p1", "simple-bus";
 			#address-cells = <2>; /* SMB chipselect number and offset */
 			#size-cells = <1>;
-			#interrupt-cells = <1>;
 			ranges;
 
 			flash at 0 {
-- 
2.30.2



From robh at kernel.org  Thu Aug 19 11:42:38 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 13:42:38 -0500
Subject: [PATCH 4/5] arm: dts: vexpress-v2p-ca9: Fix the SMB unit-address
In-Reply-To: <20210819184239.1192395-1-robh@kernel.org>
References: <20210819184239.1192395-1-robh@kernel.org>
Message-ID: <20210819184239.1192395-5-robh@kernel.org>

Based on 'ranges', the 'bus at 4000000' node unit-address is off by 1 '0'.

Cc: Andre Przywara <andre.przywara at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Rob Herring <robh at kernel.org>
---
 arch/arm/boot/dts/vexpress-v2m.dtsi    | 2 +-
 arch/arm/boot/dts/vexpress-v2p-ca9.dts | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
index fb8ca984ce1f..0819d112de12 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -19,7 +19,7 @@
  */
 
 / {
-	bus at 4000000 {
+	bus at 40000000 {
 		motherboard {
 			arm,hbi = <0x190>;
 			arm,vexpress,site = <0>;
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 4c5847955856..1317f0f58d53 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -295,7 +295,7 @@ power-vd10-s3 {
 		};
 	};
 
-	smb: bus at 4000000 {
+	smb: bus at 40000000 {
 		compatible = "simple-bus";
 
 		#address-cells = <2>;
-- 
2.30.2



From robh at kernel.org  Thu Aug 19 11:42:39 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 13:42:39 -0500
Subject: [PATCH 5/5] arm: dts: vexpress: Fix addressing issues with
 'motherboard-bus' nodes
In-Reply-To: <20210819184239.1192395-1-robh@kernel.org>
References: <20210819184239.1192395-1-robh@kernel.org>
Message-ID: <20210819184239.1192395-6-robh@kernel.org>

The 'motherboard-bus' node in Arm Ltd boards fails schema checks as
'simple-bus' child nodes must have a unit-address. The 'ranges' handling is
also wrong (or at least strange) as the mapping of SMC chip selects should
be in the 'arm,vexpress,v2m-p1' node rather than a generic 'simple-bus'
node. Either there's 1 too many levels of 'simple-bus' nodes or 'ranges'
should be moved down a level. The latter change is more simple, so let's do
that. As the 'ranges' value doesn't vary for a given motherboard instance,
we can move 'ranges' into the motherboard dtsi files.

Cc: Andre Przywara <andre.przywara at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Rob Herring <robh at kernel.org>
---
 arch/arm/boot/dts/vexpress-v2m-rs1.dtsi            | 14 ++++++++++++--
 arch/arm/boot/dts/vexpress-v2m.dtsi                | 14 ++++++++++++--
 arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts        | 11 -----------
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts         | 11 -----------
 arch/arm/boot/dts/vexpress-v2p-ca5s.dts            | 11 -----------
 arch/arm/boot/dts/vexpress-v2p-ca9.dts             | 10 ----------
 arch/arm64/boot/dts/arm/fvp-base-revc.dts          | 11 -----------
 arch/arm64/boot/dts/arm/juno-base.dtsi             | 10 ----------
 arch/arm64/boot/dts/arm/juno-motherboard.dtsi      | 14 ++++++++++++--
 arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts         | 11 -----------
 .../boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi      |  2 +-
 arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi   | 14 ++++++++++++--
 .../boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts      | 11 -----------
 13 files changed, 49 insertions(+), 95 deletions(-)

diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index f61251b3c74f..19b300532b37 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -101,13 +101,23 @@ led-8 {
 	};
 
 	bus at 8000000 {
-		motherboard-bus {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0x8000000 0 0x8000000 0x18000000>;
+
+		motherboard-bus at 8000000 {
 			arm,hbi = <0x190>;
 			arm,vexpress,site = <0>;
 			compatible = "arm,vexpress,v2m-p1", "simple-bus";
 			#address-cells = <2>; /* SMB chipselect number and offset */
 			#size-cells = <1>;
-			ranges;
+			ranges = <0 0 0 0x08000000 0x04000000>,
+				 <1 0 0 0x14000000 0x04000000>,
+				 <2 0 0 0x18000000 0x04000000>,
+				 <3 0 0 0x1c000000 0x04000000>,
+				 <4 0 0 0x0c000000 0x04000000>,
+				 <5 0 0 0x10000000 0x04000000>;
 
 			nor_flash: flash at 0 {
 				compatible = "arm,vexpress-flash", "cfi-flash";
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
index 0819d112de12..0547f633764f 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -20,13 +20,23 @@
 
 / {
 	bus at 40000000 {
-		motherboard {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x40000000 0x40000000 0x10000000>,
+			 <0x10000000 0x10000000 0x00020000>;
+
+		motherboard-bus at 40000000 {
 			arm,hbi = <0x190>;
 			arm,vexpress,site = <0>;
 			compatible = "arm,vexpress,v2m-p1", "simple-bus";
 			#address-cells = <2>; /* SMB chipselect number and offset */
 			#size-cells = <1>;
-			ranges;
+			ranges = <0 0 0x40000000 0x04000000>,
+				 <1 0 0x44000000 0x04000000>,
+				 <2 0 0x48000000 0x04000000>,
+				 <3 0 0x4c000000 0x04000000>,
+				 <7 0 0x10000000 0x00020000>;
 
 			flash at 0,00000000 {
 				compatible = "arm,vexpress-flash", "cfi-flash";
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index e63c5c0bfb43..26b6862e519f 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -237,17 +237,6 @@ energy {
 	};
 
 	bus at 8000000 {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0  0 4>,
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 012d40a7228c..5ec25eebbd77 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -609,17 +609,6 @@ etm2_out_port: endpoint {
 	};
 
 	smb: bus at 8000000 {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0  0 4>,
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index 7aa64ae25779..f1485ee3ce83 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -207,17 +207,6 @@ temp-dcc {
 	};
 
 	smb: bus at 8000000 {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x04000000>,
-			 <1 0 0x14000000 0x04000000>,
-			 <2 0 0x18000000 0x04000000>,
-			 <3 0 0x1c000000 0x04000000>,
-			 <4 0 0x0c000000 0x04000000>,
-			 <5 0 0x10000000 0x04000000>;
-
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0  0 4>,
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 1317f0f58d53..99b2f339cc04 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -296,16 +296,6 @@ power-vd10-s3 {
 	};
 
 	smb: bus at 40000000 {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x40000000 0x04000000>,
-			 <1 0 0x44000000 0x04000000>,
-			 <2 0 0x48000000 0x04000000>,
-			 <3 0 0x4c000000 0x04000000>,
-			 <7 0 0x10000000 0x00020000>;
-
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0  0 4>,
diff --git a/arch/arm64/boot/dts/arm/fvp-base-revc.dts b/arch/arm64/boot/dts/arm/fvp-base-revc.dts
index b8a21092db4d..5f519affe728 100644
--- a/arch/arm64/boot/dts/arm/fvp-base-revc.dts
+++ b/arch/arm64/boot/dts/arm/fvp-base-revc.dts
@@ -207,17 +207,6 @@ panel-timing {
 	};
 
 	bus at 8000000 {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic 0 0 GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 8e7a66943b01..fd1e9708bdaf 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -804,16 +804,6 @@ memory at 80000000 {
 	};
 
 	bus at 8000000 {
-		compatible = "simple-bus";
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 15>;
 		interrupt-map = <0 0  0 &gic 0 GIC_SPI  68 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
index 4203f0a6ddf6..1578ffb07e03 100644
--- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
@@ -92,11 +92,21 @@ nmi-button {
 	};
 
 	bus at 8000000 {
-		motherboard-bus {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0x8000000 0 0x8000000 0x18000000>;
+
+		motherboard-bus at 8000000 {
 			compatible = "arm,vexpress,v2p-p1", "simple-bus";
 			#address-cells = <2>;  /* SMB chipselect number and offset */
 			#size-cells = <1>;
-			ranges;
+			ranges = <0 0 0 0x08000000 0x04000000>,
+				 <1 0 0 0x14000000 0x04000000>,
+				 <2 0 0 0x18000000 0x04000000>,
+				 <3 0 0 0x1c000000 0x04000000>,
+				 <4 0 0 0x0c000000 0x04000000>,
+				 <5 0 0 0x10000000 0x04000000>;
 			arm,hbi = <0x252>;
 			arm,vexpress,site = <0>;
 
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts
index 3050f45bade4..258991ad7cc0 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts
@@ -133,17 +133,6 @@ panel_in: endpoint {
 	};
 
 	bus at 8000000 {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi
index b917d9d3f1c4..33182d9e5826 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi
@@ -6,7 +6,7 @@
  */
 / {
 	bus at 8000000 {
-		motherboard-bus {
+		motherboard-bus at 8000000 {
 			arm,v2m-memory-map = "rs2";
 
 			iofpga-bus at 300000000 {
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
index 0459aff22f27..a13e71ed524a 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
@@ -77,11 +77,21 @@ dvimode {
 	};
 
 	bus at 8000000 {
-		motherboard-bus {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0x8000000 0 0x8000000 0x18000000>;
+
+		motherboard-bus at 8000000 {
 			compatible = "arm,vexpress,v2m-p1", "simple-bus";
 			#address-cells = <2>; /* SMB chipselect number and offset */
 			#size-cells = <1>;
-			ranges;
+			ranges = <0 0 0 0x08000000 0x04000000>,
+				 <1 0 0 0x14000000 0x04000000>,
+				 <2 0 0 0x18000000 0x04000000>,
+				 <3 0 0 0x1c000000 0x04000000>,
+				 <4 0 0 0x0c000000 0x04000000>,
+				 <5 0 0 0x10000000 0x04000000>;
 
 			flash at 0 {
 				compatible = "arm,vexpress-flash", "cfi-flash";
diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
index d859914500a7..6958469bceaa 100644
--- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
+++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
@@ -145,17 +145,6 @@ temp-fpga {
 	};
 
 	smb: bus at 8000000 {
-		compatible = "simple-bus";
-
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0 0x08000000 0x04000000>,
-			 <1 0 0 0x14000000 0x04000000>,
-			 <2 0 0 0x18000000 0x04000000>,
-			 <3 0 0 0x1c000000 0x04000000>,
-			 <4 0 0 0x0c000000 0x04000000>,
-			 <5 0 0 0x10000000 0x04000000>;
-
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 63>;
 		interrupt-map = <0 0  0 &gic GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.30.2



From mtosatti at redhat.com  Thu Aug 19 11:24:22 2021
From: mtosatti at redhat.com (Marcelo Tosatti)
Date: Thu, 19 Aug 2021 15:24:22 -0300
Subject: [PATCH v7 1/6] KVM: x86: Fix potential race in KVM_GET_CLOCK
In-Reply-To: <20210816001130.3059564-2-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
 <20210816001130.3059564-2-oupton@google.com>
Message-ID: <20210819182422.GA25923@fuller.cnet>

On Mon, Aug 16, 2021 at 12:11:25AM +0000, Oliver Upton wrote:
> Sean noticed that KVM_GET_CLOCK was checking kvm_arch.use_master_clock
> outside of the pvclock sync lock. This is problematic, as the clock
> value written to the user may or may not actually correspond to a stable
> TSC.
> 
> Fix the race by populating the entire kvm_clock_data structure behind
> the pvclock_gtod_sync_lock.

Oliver, 

Can you please describe the race in more detail?

Is it about host TSC going unstable VS parallel KVM_GET_CLOCK ? 



From bigeasy at linutronix.de  Thu Aug 19 11:45:23 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Thu, 19 Aug 2021 20:45:23 +0200
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-1>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
 <20210819153927.clqxr4f7qegpflbr@linutronix.de>
 <20210819154708.3efz6jtgwtuhpeds@linutronix.de>
 <20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-1>
Message-ID: <20210819184523.laa5vwvfsgotbgx5@linutronix.de>

On 2021-08-19 11:20:35 [-0700], Paul E. McKenney wrote:
> > This piece above, I don't understand. I had it running for a while and
> > it didn't explode. Let me try TREE01 for 30min without that piece.
> 
> This might be historical.  There was a time when interrupts being
> disabled across rcu_read_unlock() meant that preemption had to have
> been disabled across the entire RCU read-side critical section.
> 
> I am not seeing a purpose for it now, but I could easily be missing
> something, especially given my tenuous grasp of RT.

Okay. So the 30min test didn't trigger any warnings?

> Either way, looking forward to the next version!

Good. So if you liked what you have seen then I'm going to resubmit the
above as a proper patch then.
Thanks!

> 							Thanx, Paul

Sebastian


From broonie at kernel.org  Thu Aug 19 12:22:08 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 19 Aug 2021 20:22:08 +0100
Subject: [PATCH] ASoC: uniphier: make arrays mul and div static const,
 makes object smaller
In-Reply-To: <20210818151746.38520-1-colin.king@canonical.com>
References: <20210818151746.38520-1-colin.king@canonical.com>
Message-ID: <162940023650.48070.9595577624316730352.b4-ty@kernel.org>

On Wed, 18 Aug 2021 16:17:46 +0100, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
> 
> Don't populate the arrays mul and div on the stack but instead make them
> static const. Makes the object code smaller by 4 bytes.
> 
> Before:
>    text    data     bss     dec     hex filename
>   16226    4984      64   21274    531a ./sound/soc/uniphier/aio-cpu.o
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: uniphier: make arrays mul and div static const, makes object smaller
      commit: 5d925d9823aaf18d55fab784bd4ef11f80fe1099

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From christophe.jaillet at wanadoo.fr  Thu Aug 19 13:05:28 2021
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Thu, 19 Aug 2021 22:05:28 +0200
Subject: [PATCH] media: venus: core: Fix a resource leak in the error handling
 path of 'venus_probe()'
Message-ID: <ea6bddd4da925fcd3016cdb3fc8d40d2311c55a4.1629403336.git.christophe.jaillet@wanadoo.fr>

A successful 'of_platform_populate()' call should be balanced by a
corresponding 'of_platform_depopulate()' call in the error handling path
of the probe, as already done in the remove function.

A successful 'venus_firmware_init()' call should be balanced by a
corresponding 'venus_firmware_deinit()' call in the error handling path
of the probe, as already done in the remove function.

Update the error handling path accordingly.

Fixes: f9799fcce4bb ("media: venus: firmware: register separate platform_device for firmware loader")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
 drivers/media/platform/qcom/venus/core.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 91b15842c555..9cb0ab7d1677 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -349,11 +349,11 @@ static int venus_probe(struct platform_device *pdev)
 
 	ret = venus_firmware_init(core);
 	if (ret)
-		goto err_runtime_disable;
+		goto err_of_depopulate;
 
 	ret = venus_boot(core);
 	if (ret)
-		goto err_runtime_disable;
+		goto err_firmware_deinit;
 
 	ret = hfi_core_resume(core, true);
 	if (ret)
@@ -385,6 +385,10 @@ static int venus_probe(struct platform_device *pdev)
 	v4l2_device_unregister(&core->v4l2_dev);
 err_venus_shutdown:
 	venus_shutdown(core);
+err_firmware_deinit:
+	venus_firmware_deinit(core);
+err_of_depopulate:
+	of_platform_depopulate(dev);
 err_runtime_disable:
 	pm_runtime_put_noidle(dev);
 	pm_runtime_set_suspended(dev);
-- 
2.30.2



From festevam at gmail.com  Thu Aug 19 13:15:38 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 19 Aug 2021 17:15:38 -0300
Subject: [PATCH] usb: dwc3: imx8mp: request irq after initializing dwc3
In-Reply-To: <20210819154818.18334-1-lutovinova@ispras.ru>
References: <20210819154818.18334-1-lutovinova@ispras.ru>
Message-ID: <CAOMZO5DiaNnxc6X77jyPp9PxAUmc2-HdgE0nh4uBda_eLaBimQ@mail.gmail.com>

Hi Nadezda,

On Thu, Aug 19, 2021 at 12:48 PM Nadezda Lutovinova
<lutovinova at ispras.ru> wrote:
>
> If IRQ occurs between calling  devm_request_threaded_irq() and
> initializing dwc3_imx->dwc3, then null pointer dereference occurs
> since dwc3_imx->dwc3 is used in dwc3_imx8mp_interrupt().
>
> The patch puts registration of the interrupt handler after
> initializing of neccesery data.

"necessary"

> Found by Linux Driver Verification project (linuxtesting.org).
>
> Signed-off-by: Nadezda Lutovinova <lutovinova at ispras.ru>

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From marex at denx.de  Thu Aug 19 13:20:36 2021
From: marex at denx.de (Marek Vasut)
Date: Thu, 19 Aug 2021 22:20:36 +0200
Subject: [PATCH] clk: imx8mn: Add M7 core clock
Message-ID: <20210819202036.2084782-1-marex@denx.de>

Add missing M7 core clock entry to the iMX8MN clock driver.

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Abel Vesa <abel.vesa at nxp.com>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Peng Fan <peng.fan at nxp.com>
Cc: Shawn Guo <shawnguo at kernel.org>
---
 drivers/clk/imx/clk-imx8mn.c             | 5 +++++
 include/dt-bindings/clock/imx8mn-clock.h | 4 +++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 212708e9388e2..9dba4eb643ab9 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -40,6 +40,9 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl
 
 static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
 
+static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out",
+				       "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
+
 static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
 						    "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
 						    "video_pll1_out", "audio_pll2_out", };
@@ -421,6 +424,8 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 	hws[IMX8MN_CLK_A53_SRC] = hws[IMX8MN_CLK_A53_DIV];
 	hws[IMX8MN_CLK_A53_CG] = hws[IMX8MN_CLK_A53_DIV];
 
+	hws[IMX8MN_CLK_M7_CORE] = imx8m_clk_hw_composite_core("arm_m7_core", imx8mn_m7_sels, base + 0x8080);
+
 	hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180);
 	hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200);
 
diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
index d24b627cb2e71..01e8bab1d767a 100644
--- a/include/dt-bindings/clock/imx8mn-clock.h
+++ b/include/dt-bindings/clock/imx8mn-clock.h
@@ -241,6 +241,8 @@
 #define IMX8MN_CLK_CLKOUT2_DIV			219
 #define IMX8MN_CLK_CLKOUT2			220
 
-#define IMX8MN_CLK_END				221
+#define IMX8MN_CLK_M7_CORE			221
+
+#define IMX8MN_CLK_END				222
 
 #endif
-- 
2.30.2



From christophe.jaillet at wanadoo.fr  Thu Aug 19 13:21:25 2021
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Thu, 19 Aug 2021 22:21:25 +0200
Subject: [PATCH] media: mtk-vpu: Fix a resource leak in the error handling
 path of 'mtk_vpu_probe()'
Message-ID: <3d4ba5d254044567653a006b18971658ec69560f.1629404378.git.christophe.jaillet@wanadoo.fr>

A successful 'clk_prepare()' call should be balanced by a corresponding
'clk_unprepare()' call in the error handling path of the probe, as already
done in the remove function.

Update the error handling path accordingly.

Fixes: 3003a180ef6b ("[media] VPU: mediatek: support Mediatek VPU")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
 drivers/media/platform/mtk-vpu/mtk_vpu.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c
index ec290dde59cf..7f1647da0ade 100644
--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c
+++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c
@@ -848,7 +848,8 @@ static int mtk_vpu_probe(struct platform_device *pdev)
 	vpu->wdt.wq = create_singlethread_workqueue("vpu_wdt");
 	if (!vpu->wdt.wq) {
 		dev_err(dev, "initialize wdt workqueue failed\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto clk_unprepare;
 	}
 	INIT_WORK(&vpu->wdt.ws, vpu_wdt_reset_func);
 	mutex_init(&vpu->vpu_mutex);
@@ -942,6 +943,8 @@ static int mtk_vpu_probe(struct platform_device *pdev)
 	vpu_clock_disable(vpu);
 workqueue_destroy:
 	destroy_workqueue(vpu->wdt.wq);
+clk_unprepare:
+	clk_unprepare(vpu->clk);
 
 	return ret;
 }
-- 
2.30.2



From robh at kernel.org  Thu Aug 19 14:19:11 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 19 Aug 2021 16:19:11 -0500
Subject: [PATCH v3 1/4] dt bindings: remoteproc: Add bindings for MT8183
 APU
In-Reply-To: <20210819151340.741565-2-abailon@baylibre.com>
References: <20210819151340.741565-1-abailon@baylibre.com>
 <20210819151340.741565-2-abailon@baylibre.com>
Message-ID: <1629407951.460901.1418775.nullmailer@robh.at.kernel.org>

On Thu, 19 Aug 2021 17:13:37 +0200, Alexandre Bailon wrote:
> This adds dt bindings for the APU present in the MT8183.
> 
> Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
> ---
>  .../bindings/remoteproc/mtk,apu.yaml          | 118 ++++++++++++++++++
>  1 file changed, 118 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/remoteproc/mtk,apu.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/remoteproc/mtk,apu.example.dt.yaml:0:0: /example-0/reserved-memory/vdev0vring0: failed to match any schema with compatible: ['shared-dma-pool']
Documentation/devicetree/bindings/remoteproc/mtk,apu.example.dt.yaml:0:0: /example-0/reserved-memory/vdev0vring1: failed to match any schema with compatible: ['shared-dma-pool']
Documentation/devicetree/bindings/remoteproc/mtk,apu.example.dt.yaml:0:0: /example-0/reserved-memory/vdev0buffer: failed to match any schema with compatible: ['shared-dma-pool']
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/remoteproc/mtk,apu.example.dt.yaml: apu at 19100000: memory-region: [[1], [2], [3]] is too long
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/remoteproc/mtk,apu.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/remoteproc/mtk,apu.example.dt.yaml: apu at 19100000: Additional properties are not allowed ('memory-region-names' was unexpected)
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/remoteproc/mtk,apu.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1518714

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From yuzhao at google.com  Thu Aug 19 14:23:02 2021
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 19 Aug 2021 15:23:02 -0600
Subject: [PATCH v4 01/11] mm: x86, arm64: add arch_has_hw_pte_young()
In-Reply-To: <20210819091923.GA15467@willie-the-truck>
References: <20210818063107.2696454-1-yuzhao@google.com>
 <20210818063107.2696454-2-yuzhao@google.com>
 <20210819091923.GA15467@willie-the-truck>
Message-ID: <CAOUHufbysyPZFZDOaGn+FwVojy-krCZR--7dd0qkWqKL+s9S_Q@mail.gmail.com>

On Thu, Aug 19, 2021 at 3:19 AM Will Deacon <will at kernel.org> wrote:
>
> On Wed, Aug 18, 2021 at 12:30:57AM -0600, Yu Zhao wrote:
> > Some architectures set the accessed bit in PTEs automatically, e.g.,
> > x86, and arm64 v8.2 and later. On architectures that do not have this
> > capability, clearing the accessed bit in a PTE triggers a page fault
> > following the TLB miss.
> >
> > Being aware of this capability can help make better decisions, i.e.,
> > whether to limit the size of each batch of PTEs and the burst of
> > batches when clearing the accessed bit.
> >
> > Signed-off-by: Yu Zhao <yuzhao at google.com>
> > ---
> >  arch/arm64/include/asm/cpufeature.h | 19 ++++++-------------
> >  arch/arm64/include/asm/pgtable.h    | 10 ++++------
> >  arch/arm64/kernel/cpufeature.c      | 19 +++++++++++++++++++
> >  arch/arm64/mm/proc.S                | 12 ------------
> >  arch/arm64/tools/cpucaps            |  1 +
> >  arch/x86/include/asm/pgtable.h      |  6 +++---
> >  include/linux/pgtable.h             | 12 ++++++++++++
> >  mm/memory.c                         | 14 +-------------
> >  8 files changed, 46 insertions(+), 47 deletions(-)
>
> Please cc linux-arm-kernel and the maintainers on arm64 patches.

Done. Also adding a link to the original post:
https://lore.kernel.org/patchwork/patch/1478354/

> > diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> > index 9bb9d11750d7..2020b9e818c8 100644
> > --- a/arch/arm64/include/asm/cpufeature.h
> > +++ b/arch/arm64/include/asm/cpufeature.h
> > @@ -776,6 +776,12 @@ static inline bool system_supports_tlb_range(void)
> >               cpus_have_const_cap(ARM64_HAS_TLB_RANGE);
> >  }
> >
> > +/* Check whether hardware update of the Access flag is supported. */
> > +static inline bool system_has_hw_af(void)
> > +{
> > +     return IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && cpus_have_const_cap(ARM64_HW_AF);
> > +}
>
> How accurate does this need to be? Heterogeneous (big/little) systems are
> very common on arm64, so the existing code enables hardware access flag
> unconditionally on CPUs that support it, meaning we could end up running
> on a system where some CPUs have hardware update and others do not.
>
> With your change, we only enable hardware access flag if _all_ CPUs support
> it (and furthermore, we prevent late onlining of CPUs without the feature
> if was detected at boot). This sacrifices a lot of flexibility, particularly
> if we end up tackling CPU errata in this area in future, and it's not clear
> that it's really required for what you're trying to do.

It doesn't need to be accurate but then my question is how helpful it
is if it's not accurate. Conversely, shouldn't all CPUs have it if
it's really helpful? So it seems to me whether such a flexibility is
needed in the future is questionable -- AFAIK, there are no CPUs (ARM
or not) that have such a behavior in the present. I agree we want to
try to be future proof, but usually this comes at a cost. For this
specific case, we would need two functions to detect the capability at
global and local levels to fully explore this theoretical flexibility.

The bottomline is I don't have a problem with having an additional
function to detect the capability at a global level. Note that the
specific concern in this patchset is that if a CPU thinks all other
CPUs have the capability and clears the accessed bit on many PTEs,
then those who don't have the capability may suffer the faults for
that action. (This is different from the cow_user_page() case.)


From linux at armlinux.org.uk  Thu Aug 19 14:28:19 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 19 Aug 2021 22:28:19 +0100
Subject: arm32 insecure W+X mapping
In-Reply-To: <CAJ+vNU0PaPNHbJc5RXgrRYJw2aWowrGVMOrU1=hKhsCTXAB=DA@mail.gmail.com>
References: <CAJ+vNU0PaPNHbJc5RXgrRYJw2aWowrGVMOrU1=hKhsCTXAB=DA@mail.gmail.com>
Message-ID: <20210819212819.GM22278@shell.armlinux.org.uk>

On Thu, Aug 19, 2021 at 10:19:46AM -0700, Tim Harvey wrote:
> Greetings,
> 
> Since commit a8e53c151fe7 "(ARM: 8737/1: mm: dump: add checking for
> writable and executable)" I've been seeing the following appear on my
> arm32 kernel:
> 
> arm/mm: Found insecure W+X mapping at address 0xf087d000
> ...
> Checked W+X mappings: FAILED, 1 W+X pages found
> 
> As I haven't seen others report this I assume it's something unique to
> my kernel configuration. How do I debug what is causing the insecure
> page?

If you check /proc/vmallocinfo, it should tell you the physical
address that was mapped there, and the function that created the
mapping. That should give enough clues to track it down.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From mathieu.desnoyers at efficios.com  Thu Aug 19 14:39:12 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Thu, 19 Aug 2021 17:39:12 -0400 (EDT)
Subject: [PATCH 1/5] KVM: rseq: Update rseq when processing
 NOTIFY_RESUME on xfer to KVM guest
In-Reply-To: <20210818001210.4073390-2-seanjc@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-2-seanjc@google.com>
Message-ID: <1673583543.19718.1629409152244.JavaMail.zimbra@efficios.com>

----- On Aug 17, 2021, at 8:12 PM, Sean Christopherson seanjc at google.com wrote:

> Invoke rseq's NOTIFY_RESUME handler when processing the flag prior to
> transferring to a KVM guest, which is roughly equivalent to an exit to
> userspace and processes many of the same pending actions.  While the task
> cannot be in an rseq critical section as the KVM path is reachable only
> via ioctl(KVM_RUN), the side effects that apply to rseq outside of a
> critical section still apply, e.g. the CPU ID needs to be updated if the
> task is migrated.
> 
> Clearing TIF_NOTIFY_RESUME without informing rseq can lead to segfaults
> and other badness in userspace VMMs that use rseq in combination with KVM,
> e.g. due to the CPU ID being stale after task migration.

I agree with the problem assessment, but I would recommend a small change
to this fix.

> 
> Fixes: 72c3c0fe54a3 ("x86/kvm: Use generic xfer to guest work function")
> Reported-by: Peter Foley <pefoley at google.com>
> Bisected-by: Doug Evans <dje at google.com>
> Cc: Shakeel Butt <shakeelb at google.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: stable at vger.kernel.org
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---
> kernel/entry/kvm.c | 4 +++-
> kernel/rseq.c      | 4 ++--
> 2 files changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
> index 49972ee99aff..049fd06b4c3d 100644
> --- a/kernel/entry/kvm.c
> +++ b/kernel/entry/kvm.c
> @@ -19,8 +19,10 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu,
> unsigned long ti_work)
> 		if (ti_work & _TIF_NEED_RESCHED)
> 			schedule();
> 
> -		if (ti_work & _TIF_NOTIFY_RESUME)
> +		if (ti_work & _TIF_NOTIFY_RESUME) {
> 			tracehook_notify_resume(NULL);
> +			rseq_handle_notify_resume(NULL, NULL);
> +		}
> 
> 		ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
> 		if (ret)
> diff --git a/kernel/rseq.c b/kernel/rseq.c
> index 35f7bd0fced0..58c79a7918cd 100644
> --- a/kernel/rseq.c
> +++ b/kernel/rseq.c
> @@ -236,7 +236,7 @@ static bool in_rseq_cs(unsigned long ip, struct rseq_cs
> *rseq_cs)
> 
> static int rseq_ip_fixup(struct pt_regs *regs)
> {
> -	unsigned long ip = instruction_pointer(regs);
> +	unsigned long ip = regs ? instruction_pointer(regs) : 0;
> 	struct task_struct *t = current;
> 	struct rseq_cs rseq_cs;
> 	int ret;
> @@ -250,7 +250,7 @@ static int rseq_ip_fixup(struct pt_regs *regs)
> 	 * If not nested over a rseq critical section, restart is useless.
> 	 * Clear the rseq_cs pointer and return.
> 	 */
> -	if (!in_rseq_cs(ip, &rseq_cs))
> +	if (!regs || !in_rseq_cs(ip, &rseq_cs))

I think clearing the thread's rseq_cs unconditionally here when regs is NULL
is not the behavior we want when this is called from xfer_to_guest_mode_work.

If we have a scenario where userspace ends up calling this ioctl(KVM_RUN)
from within a rseq c.s., we really want a CONFIG_DEBUG_RSEQ=y kernel to
kill this application in the rseq_syscall handler when exiting back to usermode
when the ioctl eventually returns.

However, clearing the thread's rseq_cs will prevent this from happening.

So I would favor an approach where we simply do:

if (!regs)
     return 0;

Immediately at the beginning of rseq_ip_fixup, before getting the instruction
pointer, so effectively skip all side-effects of the ip fixup code. Indeed, it
is not relevant to do any fixup here, because it is nested in a ioctl system
call.

Effectively, this would preserve the SIGSEGV behavior when this ioctl is
erroneously called by user-space from a rseq critical section.

Thanks for looking into this !

Mathieu

> 		return clear_rseq_cs(t);
> 	ret = rseq_need_restart(t, rseq_cs.flags);
> 	if (ret <= 0)
> --
> 2.33.0.rc1.237.g0d66db33f3-goog

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From mathieu.desnoyers at efficios.com  Thu Aug 19 14:41:07 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Thu, 19 Aug 2021 17:41:07 -0400 (EDT)
Subject: [PATCH 2/5] entry: rseq: Call rseq_handle_notify_resume() in
 tracehook_notify_resume()
In-Reply-To: <20210818001210.4073390-3-seanjc@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-3-seanjc@google.com>
Message-ID: <1359319445.19723.1629409267434.JavaMail.zimbra@efficios.com>

----- On Aug 17, 2021, at 8:12 PM, Sean Christopherson seanjc at google.com wrote:

> Invoke rseq_handle_notify_resume() from tracehook_notify_resume() now
> that the two function are always called back-to-back by architectures
> that have rseq.  The rseq helper is stubbed out for architectures that
> don't support rseq, i.e. this is a nop across the board.
> 
> Note, tracehook_notify_resume() is horribly named and arguably does not
> belong in tracehook.h as literally every line of code in it has nothing
> to do with tracing.  But, that's been true since commit a42c6ded827d
> ("move key_repace_session_keyring() into tracehook_notify_resume()")
> first usurped tracehook_notify_resume() back in 2012.  Punt cleaning that
> mess up to future patches.
> 
> No functional change intended.

This will make it harder to introduce new code paths which consume the
NOTIFY_RESUME without calling the rseq callback, which introduces issues.
Agreed.

Acked-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>

> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---
> arch/arm/kernel/signal.c     | 1 -
> arch/arm64/kernel/signal.c   | 1 -
> arch/csky/kernel/signal.c    | 4 +---
> arch/mips/kernel/signal.c    | 4 +---
> arch/powerpc/kernel/signal.c | 4 +---
> arch/s390/kernel/signal.c    | 1 -
> include/linux/tracehook.h    | 2 ++
> kernel/entry/common.c        | 4 +---
> kernel/entry/kvm.c           | 4 +---
> 9 files changed, 7 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
> index a3a38d0a4c85..9df68d139965 100644
> --- a/arch/arm/kernel/signal.c
> +++ b/arch/arm/kernel/signal.c
> @@ -670,7 +670,6 @@ do_work_pending(struct pt_regs *regs, unsigned int
> thread_flags, int syscall)
> 				uprobe_notify_resume(regs);
> 			} else {
> 				tracehook_notify_resume(regs);
> -				rseq_handle_notify_resume(NULL, regs);
> 			}
> 		}
> 		local_irq_disable();
> diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> index 23036334f4dc..22b55db13da6 100644
> --- a/arch/arm64/kernel/signal.c
> +++ b/arch/arm64/kernel/signal.c
> @@ -951,7 +951,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
> 
> 			if (thread_flags & _TIF_NOTIFY_RESUME) {
> 				tracehook_notify_resume(regs);
> -				rseq_handle_notify_resume(NULL, regs);
> 
> 				/*
> 				 * If we reschedule after checking the affinity
> diff --git a/arch/csky/kernel/signal.c b/arch/csky/kernel/signal.c
> index 312f046d452d..bc4238b9f709 100644
> --- a/arch/csky/kernel/signal.c
> +++ b/arch/csky/kernel/signal.c
> @@ -260,8 +260,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
> 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
> 		do_signal(regs);
> 
> -	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
> +	if (thread_info_flags & _TIF_NOTIFY_RESUME)
> 		tracehook_notify_resume(regs);
> -		rseq_handle_notify_resume(NULL, regs);
> -	}
> }
> diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
> index f1e985109da0..c9b2a75563e1 100644
> --- a/arch/mips/kernel/signal.c
> +++ b/arch/mips/kernel/signal.c
> @@ -906,10 +906,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void
> *unused,
> 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
> 		do_signal(regs);
> 
> -	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
> +	if (thread_info_flags & _TIF_NOTIFY_RESUME)
> 		tracehook_notify_resume(regs);
> -		rseq_handle_notify_resume(NULL, regs);
> -	}
> 
> 	user_enter();
> }
> diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
> index e600764a926c..b93b87df499d 100644
> --- a/arch/powerpc/kernel/signal.c
> +++ b/arch/powerpc/kernel/signal.c
> @@ -293,10 +293,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long
> thread_info_flags)
> 		do_signal(current);
> 	}
> 
> -	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
> +	if (thread_info_flags & _TIF_NOTIFY_RESUME)
> 		tracehook_notify_resume(regs);
> -		rseq_handle_notify_resume(NULL, regs);
> -	}
> }
> 
> static unsigned long get_tm_stackpointer(struct task_struct *tsk)
> diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
> index 78ef53b29958..b307db26bf2d 100644
> --- a/arch/s390/kernel/signal.c
> +++ b/arch/s390/kernel/signal.c
> @@ -537,5 +537,4 @@ void arch_do_signal_or_restart(struct pt_regs *regs, bool
> has_signal)
> void do_notify_resume(struct pt_regs *regs)
> {
> 	tracehook_notify_resume(regs);
> -	rseq_handle_notify_resume(NULL, regs);
> }
> diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
> index 3e80c4bc66f7..2564b7434b4d 100644
> --- a/include/linux/tracehook.h
> +++ b/include/linux/tracehook.h
> @@ -197,6 +197,8 @@ static inline void tracehook_notify_resume(struct pt_regs
> *regs)
> 
> 	mem_cgroup_handle_over_high();
> 	blkcg_maybe_throttle_current();
> +
> +	rseq_handle_notify_resume(NULL, regs);
> }
> 
> /*
> diff --git a/kernel/entry/common.c b/kernel/entry/common.c
> index bf16395b9e13..d5a61d565ad5 100644
> --- a/kernel/entry/common.c
> +++ b/kernel/entry/common.c
> @@ -171,10 +171,8 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs
> *regs,
> 		if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
> 			handle_signal_work(regs, ti_work);
> 
> -		if (ti_work & _TIF_NOTIFY_RESUME) {
> +		if (ti_work & _TIF_NOTIFY_RESUME)
> 			tracehook_notify_resume(regs);
> -			rseq_handle_notify_resume(NULL, regs);
> -		}
> 
> 		/* Architecture specific TIF work */
> 		arch_exit_to_user_mode_work(regs, ti_work);
> diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
> index 049fd06b4c3d..49972ee99aff 100644
> --- a/kernel/entry/kvm.c
> +++ b/kernel/entry/kvm.c
> @@ -19,10 +19,8 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu,
> unsigned long ti_work)
> 		if (ti_work & _TIF_NEED_RESCHED)
> 			schedule();
> 
> -		if (ti_work & _TIF_NOTIFY_RESUME) {
> +		if (ti_work & _TIF_NOTIFY_RESUME)
> 			tracehook_notify_resume(NULL);
> -			rseq_handle_notify_resume(NULL, NULL);
> -		}
> 
> 		ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
> 		if (ret)
> --
> 2.33.0.rc1.237.g0d66db33f3-goog

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From arnd at arndb.de  Thu Aug 19 14:40:57 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 19 Aug 2021 23:40:57 +0200
Subject: [PATCH][PULL/direct] ARM: s3c: delete unneed local variable
 "delay"
In-Reply-To: <162938788185.467628.13192922419725983504.b4-ty@arndb.de>
References: <20210818204422.17919-1-krzysztof.kozlowski@canonical.com>
 <162938788185.467628.13192922419725983504.b4-ty@arndb.de>
Message-ID: <CAK8P3a1RO=PWUGi_aFA2rzn2119W-kX2kTOycEG6hoTqPBj7=Q@mail.gmail.com>

On Thu, Aug 19, 2021 at 5:44 PM Arnd Bergmann <arnd at kernel.org> wrote:
>
> From: Arnd Bergmann <arnd at arndb.de>
>
> On Wed, 18 Aug 2021 22:44:22 +0200, Krzysztof Kozlowski wrote:
> > "delay" variable on line 79 can be deleted by returning "0" on line 88.
>
> Applied to for-next, thanks!
>
> [1/1] ARM: s3c: delete unneed local variable "delay"
>       commit: 319a1b58f6c7432345f13383b26c8c10e7eb1dda

I had accidentally added this to the arm/fixes branch at first, but corrected
that now and applied it to arm/soc instead, as you intended.

          Arnd


From arnd at kernel.org  Thu Aug 19 14:47:20 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 19 Aug 2021 23:47:20 +0200
Subject: [GIT PULL] ARM: SoC fixes for 5.14, part 3
Message-ID: <CAK8P3a12+R4qpANkd4MWHa8YNNhXf0wNnN+GaWk4DqW3NJ+DQQ@mail.gmail.com>

The following changes since commit 36a21d51725af2ce0700c6ebcb6b9594aac658a6:

  Linux 5.14-rc5 (2021-08-08 13:49:31 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
tags/soc-fixes-5.14-3

for you to fetch changes up to 1e16a40211208d2d6e217e5013607219f4272dff:

  Merge tag 'omap-for-v5.14/gpt12-fix-signed' of
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into
arm/fixes (2021-08-19 17:22:47 +0200)

----------------------------------------------------------------
ARM: SoC fixes for 5.14, part 3

Not much to see here. Half the fixes this time are for Qualcomm dts files,
fixing small mistakes on certain machines. The other fixes are:

 - A 5.13 regression fix for freescale QE interrupt controller\

 - A fix for TI OMAP gpt12 timer error handling

 - A randconfig build regression fix for ixp4xx

 - Another defconfig fix following the CONFIG_FB dependency rework

Signed-off-by: Arnd Bergmann <arnd at arndb.de>

----------------------------------------------------------------
Arnd Bergmann (4):
      ARM: ixp4xx: fix building both pci drivers
      Merge tag 'soc-fsl-fix-v5.14' of
git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux into arm/fixes
      Merge tag 'qcom-arm64-fixes-for-5.14' of
git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into
arm/fixes
      Merge tag 'omap-for-v5.14/gpt12-fix-signed' of
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into
arm/fixes

Caleb Connolly (1):
      arm64: dts: qcom: sdm845-oneplus: fix reserved-mem

Linus Walleij (1):
      ARM: configs: Update the nhk8815_defconfig

Maxim Kochetkov (2):
      soc: fsl: qe: convert QE interrupt controller to platform_device
      soc: fsl: qe: fix static checker warning

Petr Vorel (3):
      arm64: dts: qcom: msm8992-bullhead: Remove PSCI
      arm64: dts: qcom: msm8992-bullhead: Fix cont_splash_mem mapping
      arm64: dts: qcom: msm8994-angler: Disable cont_splash_mem

Sibi Sankar (1):
      arm64: dts: qcom: sc7280: Fixup cpufreq domain info for cpu7

Srinivas Kandagatla (1):
      arm64: dts: qcom: c630: fix correct powerdown pin for WSA881x

Tony Lindgren (1):
      bus: ti-sysc: Fix error handling for sysc_check_active_timer()

 arch/arm/configs/nhk8815_defconfig                 |  8 +--
 arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h    | 48 ++++++-------
 .../boot/dts/qcom/msm8992-bullhead-rev-101.dts     | 12 ++++
 .../arm64/boot/dts/qcom/msm8994-angler-rev-101.dts |  4 ++
 arch/arm64/boot/dts/qcom/sc7280.dtsi               |  2 +-
 .../arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi |  4 +-
 .../boot/dts/qcom/sdm850-lenovo-yoga-c630.dts      |  4 +-
 drivers/bus/ti-sysc.c                              |  4 +-
 drivers/pci/controller/pci-ixp4xx.c                |  8 +--
 drivers/soc/fsl/qe/qe_ic.c                         | 84 ++++++++++++----------
 10 files changed, 103 insertions(+), 75 deletions(-)


From mathieu.desnoyers at efficios.com  Thu Aug 19 14:52:36 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Thu, 19 Aug 2021 17:52:36 -0400 (EDT)
Subject: [PATCH 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <20210818001210.4073390-5-seanjc@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-5-seanjc@google.com>
Message-ID: <1540548616.19739.1629409956315.JavaMail.zimbra@efficios.com>

----- On Aug 17, 2021, at 8:12 PM, Sean Christopherson seanjc at google.com wrote:

> Add a test to verify an rseq's CPU ID is updated correctly if the task is
> migrated while the kernel is handling KVM_RUN.  This is a regression test
> for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
> to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
> without updating rseq, leading to a stale CPU ID and other badness.
> 
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---

[...]

> +
> +static void *migration_worker(void *ign)
> +{
> +	cpu_set_t allowed_mask;
> +	int r, i, nr_cpus, cpu;
> +
> +	CPU_ZERO(&allowed_mask);
> +
> +	nr_cpus = CPU_COUNT(&possible_mask);
> +
> +	for (i = 0; i < 20000; i++) {
> +		cpu = i % nr_cpus;
> +		if (!CPU_ISSET(cpu, &possible_mask))
> +			continue;
> +
> +		CPU_SET(cpu, &allowed_mask);
> +
> +		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
> +		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)", errno,
> +			    strerror(errno));
> +
> +		CPU_CLR(cpu, &allowed_mask);
> +
> +		usleep(10);
> +	}
> +	done = true;
> +	return NULL;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	struct kvm_vm *vm;
> +	u32 cpu, rseq_cpu;
> +	int r;
> +
> +	/* Tell stdout not to buffer its content */
> +	setbuf(stdout, NULL);
> +
> +	r = sched_getaffinity(0, sizeof(possible_mask), &possible_mask);
> +	TEST_ASSERT(!r, "sched_getaffinity failed, errno = %d (%s)", errno,
> +		    strerror(errno));
> +
> +	if (CPU_COUNT(&possible_mask) < 2) {
> +		print_skip("Only one CPU, task migration not possible\n");
> +		exit(KSFT_SKIP);
> +	}
> +
> +	sys_rseq(0);
> +
> +	/*
> +	 * Create and run a dummy VM that immediately exits to userspace via
> +	 * GUEST_SYNC, while concurrently migrating the process by setting its
> +	 * CPU affinity.
> +	 */
> +	vm = vm_create_default(VCPU_ID, 0, guest_code);
> +
> +	pthread_create(&migration_thread, NULL, migration_worker, 0);
> +
> +	while (!done) {
> +		vcpu_run(vm, VCPU_ID);
> +		TEST_ASSERT(get_ucall(vm, VCPU_ID, NULL) == UCALL_SYNC,
> +			    "Guest failed?");
> +
> +		cpu = sched_getcpu();
> +		rseq_cpu = READ_ONCE(__rseq.cpu_id);
> +
> +		/*
> +		 * Verify rseq's CPU matches sched's CPU, and that sched's CPU
> +		 * is stable.  This doesn't handle the case where the task is
> +		 * migrated between sched_getcpu() and reading rseq, and again
> +		 * between reading rseq and sched_getcpu(), but in practice no
> +		 * false positives have been observed, while on the other hand
> +		 * blocking migration while this thread reads CPUs messes with
> +		 * the timing and prevents hitting failures on a buggy kernel.
> +		 */

I think you could get a stable cpu id between sched_getcpu and __rseq_abi.cpu_id
if you add a pthread mutex to protect:

sched_getcpu and __rseq_abi.cpu_id  reads

vs

sched_setaffinity calls within the migration thread.

Thoughts ?

Thanks,

Mathieu

> +		TEST_ASSERT(rseq_cpu == cpu || cpu != sched_getcpu(),
> +			    "rseq CPU = %d, sched CPU = %d\n", rseq_cpu, cpu);
> +	}
> +
> +	pthread_join(migration_thread, NULL);
> +
> +	kvm_vm_free(vm);
> +
> +	sys_rseq(RSEQ_FLAG_UNREGISTER);
> +
> +	return 0;
> +}
> --
> 2.33.0.rc1.237.g0d66db33f3-goog

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From jeremy.linton at arm.com  Thu Aug 19 14:56:54 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 19 Aug 2021 16:56:54 -0500
Subject: [PATCH v2 3/4] PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
In-Reply-To: <20210819215655.84866-1-jeremy.linton@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
Message-ID: <20210819215655.84866-4-jeremy.linton@arm.com>

Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/acpi/pci_mcfg.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
index 53cab975f612..4b991ee5c66c 100644
--- a/drivers/acpi/pci_mcfg.c
+++ b/drivers/acpi/pci_mcfg.c
@@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
 	ALTRA_ECAM_QUIRK(1, 13),
 	ALTRA_ECAM_QUIRK(1, 14),
 	ALTRA_ECAM_QUIRK(1, 15),
+
+	{ "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
+	  DEFINE_RES_MEM(0xFD500000, 0xA000) },
 };
 
 static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
@@ -198,8 +201,18 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
 	u16 segment = root->segment;
 	struct resource *bus_range = &root->secondary;
 	struct mcfg_fixup *f;
+	const char *soc;
 	int i;
 
+	/*
+	 * This may be a machine with a PCI/SMC conduit, which means it doesn't
+	 * have an MCFG. Use an ACPI namespace definition instead.
+	 */
+	if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
+					 "linux-ecam-quirk-id", &soc)) {
+		memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
+	}
+
 	for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
 		if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
 			if (f->cfgres.start)
-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug 19 14:56:51 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 19 Aug 2021 16:56:51 -0500
Subject: [PATCH v2 0/4] CM4 ACPI PCIe quirk
Message-ID: <20210819215655.84866-1-jeremy.linton@arm.com>

The PFTF CM4 is an ACPI platform that is following the Arm PCIe SMC
(DEN0115) standard because its PCIe config space isn't ECAM compliant
since it is split into two parts. One part describes the root port
registers, and another contains a moveable window pointing at a given
device's 4K config space. Thus it doesn't have an MCFG table. As
Linux doesn't support the PCI/SMC, a host bridge specific _DSD is
added and associated with custom ECAM ops and cfgres.  The custom cfg
op selects between those two regions, as well as disallowing
problematic accesses.

V1->V2:
	Only move register definitions to new .h file, add
	     include guards.
	Change quirk namespace identifier.
	Update Maintainers file.
	A number of whitespace, grammar, etc fixes.


Jeremy Linton (4):
  PCI: brcmstb: Break register definitions into separate header
  PCI: brcmstb: Add ACPI config space quirk
  PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
  MAINTAINERS: Widen brcmstb PCIe file scope

 MAINTAINERS                                |   2 +-
 drivers/acpi/pci_mcfg.c                    |  13 ++
 drivers/pci/controller/Makefile            |   1 +
 drivers/pci/controller/pcie-brcmstb-acpi.c |  74 ++++++++++
 drivers/pci/controller/pcie-brcmstb.c      | 150 +-------------------
 drivers/pci/controller/pcie-brcmstb.h      | 155 +++++++++++++++++++++
 include/linux/pci-ecam.h                   |   1 +
 7 files changed, 247 insertions(+), 149 deletions(-)
 create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
 create mode 100644 drivers/pci/controller/pcie-brcmstb.h

-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug 19 14:56:55 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 19 Aug 2021 16:56:55 -0500
Subject: [PATCH v2 4/4] MAINTAINERS: Widen brcmstb PCIe file scope
In-Reply-To: <20210819215655.84866-1-jeremy.linton@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
Message-ID: <20210819215655.84866-5-jeremy.linton@arm.com>

The brcmstb PCI hardware is now split across
multiple files. Include them in the maintainers
block.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index fd25e4ecf0b9..605a385cea36 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3500,7 +3500,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nsaenz/linux-rpi.git
 F:	Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
-F:	drivers/pci/controller/pcie-brcmstb.c
+F:	drivers/pci/controller/pcie-brcmstb*
 F:	drivers/staging/vc04_services
 N:	bcm2711
 N:	bcm283*
-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug 19 14:56:53 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 19 Aug 2021 16:56:53 -0500
Subject: [PATCH v2 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210819215655.84866-1-jeremy.linton@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
Message-ID: <20210819215655.84866-3-jeremy.linton@arm.com>

The PFTF CM4 is an ACPI platform that isn't ECAM compliant. Its config
space is in two parts. One part is for the root port registers and a
second moveable window pointing at a device's 4K config space. Thus it
doesn't have an MCFG, and any MCFG provided would be nonsense
anyway. Instead, a Linux specific host bridge _DSD selects a custom
ECAM ops and cfgres. The cfg op picks between those two regions while
disallowing problematic accesses.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/pci/controller/Makefile            |  1 +
 drivers/pci/controller/pcie-brcmstb-acpi.c | 74 ++++++++++++++++++++++
 include/linux/pci-ecam.h                   |  1 +
 3 files changed, 76 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c

diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index aaf30b3dcc14..65aa6fd3ed89 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
 obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
 obj-$(CONFIG_ARM64) += pci-thunder-pem.o
 obj-$(CONFIG_ARM64) += pci-xgene.o
+obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
 endif
 endif
diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
new file mode 100644
index 000000000000..71f6def3074c
--- /dev/null
+++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ACPI quirks for Brcm2711 PCIe host controller
+ * As used on the Raspberry Pi Compute Module 4
+ *
+ * Copyright (C) 2021 Arm Ltd.
+ */
+
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/pci-ecam.h>
+#include "../pci.h"
+#include "pcie-brcmstb.h"
+
+static int brcm_acpi_init(struct pci_config_window *cfg)
+{
+	/*
+	 * This platform doesn't technically have anything that could be called
+	 * ECAM. Its config region has root port specific registers between
+	 * standard PCIe defined config registers. Thus the region setup by the
+	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
+	 * but the footprint isn't a nice power of 2 (40k). For purposes of
+	 * mapping the config region we are just going to squash the standard
+	 * and nonstandard registers together rather than mapping them separately.
+	 */
+	iounmap(cfg->win);
+	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
+	if (!cfg->win)
+		goto err_exit;
+
+	/* MSI is nonstandard as well */
+	pci_no_msi();
+
+	return 0;
+err_exit:
+	dev_err(cfg->parent, "PCI: Failed to remap config\n");
+	return -ENOMEM;
+}
+
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
+					unsigned int devfn, int where)
+{
+	struct pci_config_window *cfg = bus->sysdata;
+	void __iomem *base = cfg->win;
+	int idx;
+	u32 up;
+
+	/* Accesses to the RC go right to the RC registers if slot==0 */
+	if (pci_is_root_bus(bus))
+		return PCI_SLOT(devfn) ? NULL : base + where;
+
+	/* Assure link up before sending request */
+	up = readl(base + PCIE_MISC_PCIE_STATUS);
+	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+		return NULL;
+
+	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+		return NULL;
+
+	/* For devices, write to the config space index register */
+	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
+	writel(idx, base + PCIE_EXT_CFG_INDEX);
+	return base + PCIE_EXT_CFG_DATA + where;
+}
+
+const struct pci_ecam_ops bcm2711_pcie_ops = {
+	.init		= brcm_acpi_init,
+	.bus_shift	= 1,
+	.pci_ops	= {
+		.map_bus	= brcm_pcie_map_conf2,
+		.read		= pci_generic_config_read,
+		.write		= pci_generic_config_write,
+	}
+};
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index adea5a4771cf..a5de0285bb7f 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
 extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
 extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
 extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
+extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
 #endif
 
 #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug 19 14:56:52 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 19 Aug 2021 16:56:52 -0500
Subject: [PATCH v2 1/4] PCI: brcmstb: Break register definitions into separate
 header
In-Reply-To: <20210819215655.84866-1-jeremy.linton@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
Message-ID: <20210819215655.84866-2-jeremy.linton@arm.com>

We are about to create a standalone ACPI quirk module for the
bcmstb controller. Lets move the register definitions into a separate
file so they can be shared between the APCI quirk and the normal
host bridge driver.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 150 +------------------------
 drivers/pci/controller/pcie-brcmstb.h | 155 ++++++++++++++++++++++++++
 2 files changed, 157 insertions(+), 148 deletions(-)
 create mode 100644 drivers/pci/controller/pcie-brcmstb.h

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 08bc788d9422..59a19ae59c8f 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -31,159 +31,12 @@
 #include <linux/types.h>
 
 #include "../pci.h"
-
-/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
-#define BRCM_PCIE_CAP_REGS				0x00ac
-
-/* Broadcom STB PCIe Register Offsets */
-#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1				0x0188
-#define  PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK	0xc
-#define  PCIE_RC_CFG_VENDOR_SPCIFIC_REG1_LITTLE_ENDIAN			0x0
-
-#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
-#define  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK	0xffffff
-
-#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY			0x04dc
-#define  PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK	0xc00
-
-#define PCIE_RC_DL_MDIO_ADDR				0x1100
-#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
-#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
-
-#define PCIE_MISC_MISC_CTRL				0x4008
-#define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK		0x1000
-#define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK	0x2000
-#define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK	0x300000
-
-#define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK		0xf8000000
-#define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK		0x07c00000
-#define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK		0x0000001f
-#define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
-#define PCIE_MEM_WIN0_LO(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
-#define PCIE_MEM_WIN0_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 8)
-
-#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
-#define  PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK		0x1f
-
-#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
-#define  PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK		0x1f
-#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
-
-#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
-#define  PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK		0x1f
-
-#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
-#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
-
-#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
-#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_32		0xffe06540
-#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_8		0xfff86540
-
-#define PCIE_MISC_PCIE_CTRL				0x4064
-#define  PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK	0x1
-#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK		0x4
-
-#define PCIE_MISC_PCIE_STATUS				0x4068
-#define  PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK		0x80
-#define  PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK	0x20
-#define  PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK	0x10
-#define  PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK	0x40
-
-#define PCIE_MISC_REVISION				0x406c
-#define  BRCM_PCIE_HW_REV_33				0x0303
-#define  BRCM_PCIE_HW_REV_3_20				0x0320
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT		0x4070
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK	0xfff00000
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK	0xfff0
-#define PCIE_MEM_WIN0_BASE_LIMIT(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI			0x4080
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK	0xff
-#define PCIE_MEM_WIN0_BASE_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI			0x4084
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK	0xff
-#define PCIE_MEM_WIN0_LIMIT_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
-
-#define PCIE_MISC_HARD_PCIE_HARD_DEBUG					0x4204
-#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
-#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
-
-
-#define PCIE_INTR2_CPU_BASE		0x4300
-#define PCIE_MSI_INTR2_BASE		0x4500
-/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
-#define  MSI_INT_STATUS			0x0
-#define  MSI_INT_CLR			0x8
-#define  MSI_INT_MASK_SET		0x10
-#define  MSI_INT_MASK_CLR		0x14
-
-#define PCIE_EXT_CFG_DATA				0x8000
-#define PCIE_EXT_CFG_INDEX				0x9000
-
-#define  PCIE_RGR1_SW_INIT_1_PERST_MASK			0x1
-#define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT		0x0
-
-#define RGR1_SW_INIT_1_INIT_GENERIC_MASK		0x2
-#define RGR1_SW_INIT_1_INIT_GENERIC_SHIFT		0x1
-#define RGR1_SW_INIT_1_INIT_7278_MASK			0x1
-#define RGR1_SW_INIT_1_INIT_7278_SHIFT			0x0
-
-/* PCIe parameters */
-#define BRCM_NUM_PCIE_OUT_WINS		0x4
-#define BRCM_INT_PCI_MSI_NR		32
-#define BRCM_INT_PCI_MSI_LEGACY_NR	8
-#define BRCM_INT_PCI_MSI_SHIFT		0
-
-/* MSI target adresses */
-#define BRCM_MSI_TARGET_ADDR_LT_4GB	0x0fffffffcULL
-#define BRCM_MSI_TARGET_ADDR_GT_4GB	0xffffffffcULL
-
-/* MDIO registers */
-#define MDIO_PORT0			0x0
-#define MDIO_DATA_MASK			0x7fffffff
-#define MDIO_PORT_MASK			0xf0000
-#define MDIO_REGAD_MASK			0xffff
-#define MDIO_CMD_MASK			0xfff00000
-#define MDIO_CMD_READ			0x1
-#define MDIO_CMD_WRITE			0x0
-#define MDIO_DATA_DONE_MASK		0x80000000
-#define MDIO_RD_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 1 : 0)
-#define MDIO_WT_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 0 : 1)
-#define SSC_REGS_ADDR			0x1100
-#define SET_ADDR_OFFSET			0x1f
-#define SSC_CNTL_OFFSET			0x2
-#define SSC_CNTL_OVRD_EN_MASK		0x8000
-#define SSC_CNTL_OVRD_VAL_MASK		0x4000
-#define SSC_STATUS_OFFSET		0x1
-#define SSC_STATUS_SSC_MASK		0x400
-#define SSC_STATUS_PLL_LOCK_MASK	0x800
-#define PCIE_BRCM_MAX_MEMC		3
+#include "pcie-brcmstb.h"
 
 #define IDX_ADDR(pcie)			(pcie->reg_offsets[EXT_CFG_INDEX])
 #define DATA_ADDR(pcie)			(pcie->reg_offsets[EXT_CFG_DATA])
 #define PCIE_RGR1_SW_INIT_1(pcie)	(pcie->reg_offsets[RGR1_SW_INIT_1])
 
-/* Rescal registers */
-#define PCIE_DVT_PMU_PCIE_PHY_CTRL				0xc700
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS			0x3
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK		0x4
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT	0x2
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK		0x2
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT		0x1
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK		0x1
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT		0x0
-
 /* Forward declarations */
 struct brcm_pcie;
 static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val);
@@ -192,6 +45,7 @@ static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val);
 
+
 enum {
 	RGR1_SW_INIT_1,
 	EXT_CFG_INDEX,
diff --git a/drivers/pci/controller/pcie-brcmstb.h b/drivers/pci/controller/pcie-brcmstb.h
new file mode 100644
index 000000000000..fc20cc7ae02f
--- /dev/null
+++ b/drivers/pci/controller/pcie-brcmstb.h
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (C) 2009 - 2021 Broadcom */
+
+#ifndef _PCIE_BRCMSTB_H
+#define _PCIE_BRCMSTB_H
+
+/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
+#define BRCM_PCIE_CAP_REGS				0x00ac
+
+/* Broadcom STB PCIe Register Offsets */
+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1				0x0188
+#define  PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK	0xc
+#define  PCIE_RC_CFG_VENDOR_SPCIFIC_REG1_LITTLE_ENDIAN			0x0
+
+#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
+#define  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK	0xffffff
+
+#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY			0x04dc
+#define  PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK	0xc00
+
+#define PCIE_RC_DL_MDIO_ADDR				0x1100
+#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
+#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
+
+#define PCIE_MISC_MISC_CTRL				0x4008
+#define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK		0x1000
+#define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK	0x2000
+#define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK	0x300000
+
+#define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK		0xf8000000
+#define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK		0x07c00000
+#define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK		0x0000001f
+#define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
+#define PCIE_MEM_WIN0_LO(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
+#define PCIE_MEM_WIN0_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 8)
+
+#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
+#define  PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK		0x1f
+
+#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
+#define  PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK		0x1f
+#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
+
+#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
+#define  PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK		0x1f
+
+#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
+#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
+
+#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
+#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_32		0xffe06540
+#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_8		0xfff86540
+
+#define PCIE_MISC_PCIE_CTRL				0x4064
+#define  PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK	0x1
+#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK		0x4
+
+#define PCIE_MISC_PCIE_STATUS				0x4068
+#define  PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK		0x80
+#define  PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK	0x20
+#define  PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK	0x10
+#define  PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK	0x40
+
+#define PCIE_MISC_REVISION				0x406c
+#define  BRCM_PCIE_HW_REV_33				0x0303
+#define  BRCM_PCIE_HW_REV_3_20				0x0320
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT		0x4070
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK	0xfff00000
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK	0xfff0
+#define PCIE_MEM_WIN0_BASE_LIMIT(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI			0x4080
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK	0xff
+#define PCIE_MEM_WIN0_BASE_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI			0x4084
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK	0xff
+#define PCIE_MEM_WIN0_LIMIT_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
+
+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG					0x4204
+#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
+#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
+
+
+#define PCIE_INTR2_CPU_BASE		0x4300
+#define PCIE_MSI_INTR2_BASE		0x4500
+/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
+#define  MSI_INT_STATUS			0x0
+#define  MSI_INT_CLR			0x8
+#define  MSI_INT_MASK_SET		0x10
+#define  MSI_INT_MASK_CLR		0x14
+
+#define PCIE_EXT_CFG_DATA				0x8000
+#define PCIE_EXT_CFG_INDEX				0x9000
+
+#define  PCIE_RGR1_SW_INIT_1_PERST_MASK			0x1
+#define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT		0x0
+
+#define RGR1_SW_INIT_1_INIT_GENERIC_MASK		0x2
+#define RGR1_SW_INIT_1_INIT_GENERIC_SHIFT		0x1
+#define RGR1_SW_INIT_1_INIT_7278_MASK			0x1
+#define RGR1_SW_INIT_1_INIT_7278_SHIFT			0x0
+
+/* PCIe parameters */
+#define BRCM_NUM_PCIE_OUT_WINS		0x4
+#define BRCM_INT_PCI_MSI_NR		32
+#define BRCM_INT_PCI_MSI_LEGACY_NR	8
+#define BRCM_INT_PCI_MSI_SHIFT		0
+
+/* MSI target addresses */
+#define BRCM_MSI_TARGET_ADDR_LT_4GB	0x0fffffffcULL
+#define BRCM_MSI_TARGET_ADDR_GT_4GB	0xffffffffcULL
+
+/* MDIO registers */
+#define MDIO_PORT0			0x0
+#define MDIO_DATA_MASK			0x7fffffff
+#define MDIO_PORT_MASK			0xf0000
+#define MDIO_REGAD_MASK			0xffff
+#define MDIO_CMD_MASK			0xfff00000
+#define MDIO_CMD_READ			0x1
+#define MDIO_CMD_WRITE			0x0
+#define MDIO_DATA_DONE_MASK		0x80000000
+#define MDIO_RD_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 1 : 0)
+#define MDIO_WT_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 0 : 1)
+#define SSC_REGS_ADDR			0x1100
+#define SET_ADDR_OFFSET			0x1f
+#define SSC_CNTL_OFFSET			0x2
+#define SSC_CNTL_OVRD_EN_MASK		0x8000
+#define SSC_CNTL_OVRD_VAL_MASK		0x4000
+#define SSC_STATUS_OFFSET		0x1
+#define SSC_STATUS_SSC_MASK		0x400
+#define SSC_STATUS_PLL_LOCK_MASK	0x800
+#define PCIE_BRCM_MAX_MEMC		3
+
+/* Rescal registers */
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL				0xc700
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS			0x3
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK		0x4
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT	0x2
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK		0x2
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT		0x1
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK		0x1
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT		0x0
+
+#endif /* _PCIE_BRCMSTB_H */
-- 
2.31.1



From marcel at ziswiler.com  Thu Aug 19 15:09:02 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:02 +0200
Subject: [PATCH v2 1/9] ARM: imx_v6_v7_defconfig: enable mtd physmap
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-2-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_MTD_PHYSMAP which is nowadays required for
CONFIG_MTD_PHYSMAP_OF.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

(no changes since v1)

 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index ccee86d0045dd..70b3c377c4302 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -97,6 +97,7 @@ CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_DATAFLASH=y
 CONFIG_MTD_M25P80=y
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:03 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:03 +0200
Subject: [PATCH v2 2/9] ARM: imx_v6_v7_defconfig: enable fb
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-3-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_FB which is nowadays required for CONFIG_DRM_PANEL_LVDS,
CONFIG_DRM_PANEL_SIMPLE, CONFIG_DRM_PANEL_SEIKO_43WVF1G,
CONFIG_FB_MODE_HELPERS, CONFIG_BACKLIGHT_PWM, CONFIG_BACKLIGHT_GPIO,
CONFIG_FRAMEBUFFER_CONSOLE, CONFIG_LOGO, CONFIG_FONTS, CONFIG_FONT_8x8
and CONFIG_FONT_8x16.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

(no changes since v1)

 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 70b3c377c4302..6618a009a105e 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -293,6 +293,7 @@ CONFIG_DRM_IMX_LDB=y
 CONFIG_DRM_IMX_HDMI=y
 CONFIG_DRM_ETNAVIV=y
 CONFIG_DRM_MXSFB=y
+CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:05 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:05 +0200
Subject: [PATCH v2 4/9] ARM: imx_v6_v7_defconfig: rebuild default configuration
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-5-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Run "make imx_v6_v7_defconfig; make savedefconfig" to rebuild
imx_v6_v7_defconfig.

This dropped the following nowadays obsolete configuration options:

CONFIG_MTD_M25P80=y (got integrated into MTD_SPI_NOR)
CONFIG_CS89x0=y (selected by CS89x0_PLATFORM)
CONFIG_SMSC_PHY=y (selected by USB_NET_SMSC95XX)
CONFIG_GPIO_MC9S08DZ60=y (depends on MACH_MX35_3DS)
CONFIG_REGULATOR=y (selected by various stuff)
CONFIG_MEDIA_CAMERA_SUPPORT=y (defaults to on if MEDIA_CAMERA)
CONFIG_MEDIA_CONTROLLER=y (selected by various stuff)
CONFIG_VIDEO_V4L2_SUBDEV_API=y (selected by various stuff)
CONFIG_SND_SOC_PHYCORE_AC97=y
CONFIG_SND_SOC_IMX_MC13783=y
CONFIG_USB_EHCI_MXC=y
CONFIG_USB_FSL_USB2=y

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

(no changes since v1)

 arch/arm/configs/imx_v6_v7_defconfig | 38 ++++++++--------------------
 1 file changed, 11 insertions(+), 27 deletions(-)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 90d6a5cf254e0..21803cd2d1ba7 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -28,9 +28,6 @@ CONFIG_SOC_IMX6UL=y
 CONFIG_SOC_IMX7D=y
 CONFIG_SOC_IMX7ULP=y
 CONFIG_SOC_VF610=y
-CONFIG_PCI=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_IMX6=y
 CONFIG_SMP=y
 CONFIG_ARM_PSCI=y
 CONFIG_HIGHMEM=y
@@ -58,7 +55,6 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -66,9 +62,6 @@ CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_NETFILTER=y
 CONFIG_CAN=y
 CONFIG_CAN_FLEXCAN=y
@@ -81,12 +74,14 @@ CONFIG_CFG80211_WEXT=y
 CONFIG_MAC80211=y
 CONFIG_RFKILL=y
 CONFIG_RFKILL_INPUT=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_IMX6=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 CONFIG_FW_LOADER_USER_HELPER=y
 CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
-CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_IMX_WEIM=y
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
@@ -100,14 +95,12 @@ CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_M25P80=y
 CONFIG_MTD_SST25L=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_NAND_VF610_NFC=y
 CONFIG_MTD_NAND_MXC=y
 CONFIG_MTD_SPI_NOR=y
-CONFIG_SPI_FSL_QUADSPI=y
 CONFIG_MTD_UBI=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_BLOCK=y
@@ -118,6 +111,7 @@ CONFIG_EEPROM_AT24=y
 CONFIG_EEPROM_AT25=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
+# CONFIG_BLK_DEV_BSG is not set
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
@@ -127,7 +121,6 @@ CONFIG_AHCI_IMX=y
 CONFIG_PATA_IMX=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
-CONFIG_CS89x0=y
 CONFIG_CS89x0_PLATFORM=y
 # CONFIG_NET_VENDOR_FARADAY is not set
 # CONFIG_NET_VENDOR_INTEL is not set
@@ -140,9 +133,8 @@ CONFIG_SMC91X=y
 CONFIG_SMC911X=y
 CONFIG_SMSC911X=y
 # CONFIG_NET_VENDOR_STMICRO is not set
-CONFIG_AT803X_PHY=y
 CONFIG_MICREL_PHY=y
-CONFIG_SMSC_PHY=y
+CONFIG_AT803X_PHY=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=y
@@ -205,6 +197,7 @@ CONFIG_I2C_ALGOPCA=m
 CONFIG_I2C_GPIO=y
 CONFIG_I2C_IMX=y
 CONFIG_SPI=y
+CONFIG_SPI_FSL_QUADSPI=y
 CONFIG_SPI_GPIO=y
 CONFIG_SPI_IMX=y
 CONFIG_SPI_FSL_DSPI=y
@@ -213,14 +206,13 @@ CONFIG_PINCTRL_IMX8MN=y
 CONFIG_PINCTRL_IMX8MP=y
 CONFIG_PINCTRL_IMX8MQ=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MXC=y
 CONFIG_GPIO_SIOX=m
 CONFIG_GPIO_MAX732X=y
-CONFIG_GPIO_MC9S08DZ60=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCF857X=y
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_74X164=y
-CONFIG_GPIO_MXC=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_SYSCON=y
 CONFIG_POWER_RESET_SYSCON_POWEROFF=y
@@ -234,8 +226,8 @@ CONFIG_THERMAL_WRITABLE_TRIPS=y
 CONFIG_CPU_THERMAL=y
 CONFIG_IMX_THERMAL=y
 CONFIG_WATCHDOG=y
-CONFIG_DA9062_WATCHDOG=y
 CONFIG_DA9063_WATCHDOG=m
+CONFIG_DA9062_WATCHDOG=y
 CONFIG_RN5T618_WATCHDOG=y
 CONFIG_IMX2_WDT=y
 CONFIG_IMX7ULP_WDT=y
@@ -246,7 +238,6 @@ CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_MFD_MC13XXX_I2C=y
 CONFIG_MFD_RN5T618=y
 CONFIG_MFD_STMPE=y
-CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ANATOP=y
 CONFIG_REGULATOR_DA9052=y
@@ -262,9 +253,6 @@ CONFIG_RC_CORE=y
 CONFIG_RC_DEVICES=y
 CONFIG_IR_GPIO_CIR=y
 CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_CAMERA_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
@@ -272,7 +260,6 @@ CONFIG_VIDEO_MUX=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_CODA=m
 CONFIG_VIDEO_IMX_PXP=y
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_OV2680=m
 CONFIG_VIDEO_OV5640=m
@@ -308,12 +295,10 @@ CONFIG_SND_USB_AUDIO=m
 CONFIG_SND_SOC=y
 CONFIG_SND_SOC_FSL_ASRC=y
 CONFIG_SND_IMX_SOC=y
-CONFIG_SND_SOC_PHYCORE_AC97=y
 CONFIG_SND_SOC_EUKREA_TLV320=y
 CONFIG_SND_SOC_IMX_ES8328=y
 CONFIG_SND_SOC_IMX_SGTL5000=y
 CONFIG_SND_SOC_IMX_SPDIF=y
-CONFIG_SND_SOC_IMX_MC13783=y
 CONFIG_SND_SOC_FSL_ASOC_CARD=y
 CONFIG_SND_SOC_AC97_CODEC=y
 CONFIG_SND_SOC_CS42XX8_I2C=y
@@ -325,7 +310,6 @@ CONFIG_HID_MULTITOUCH=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_MXC=y
 CONFIG_USB_ACM=m
 CONFIG_USB_STORAGE=y
 CONFIG_USB_CHIPIDEA=y
@@ -340,7 +324,6 @@ CONFIG_USB_EHSET_TEST_FIXTURE=m
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_MXS_PHY=y
 CONFIG_USB_GADGET=y
-CONFIG_USB_FSL_USB2=y
 CONFIG_USB_CONFIGFS=y
 CONFIG_USB_CONFIGFS_SERIAL=y
 CONFIG_USB_CONFIGFS_ACM=y
@@ -389,11 +372,11 @@ CONFIG_RTC_DRV_ISL1208=y
 CONFIG_RTC_DRV_PCF8523=y
 CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_M41T80=y
+CONFIG_RTC_DRV_RC5T619=y
 CONFIG_RTC_DRV_DA9063=y
 CONFIG_RTC_DRV_MC13XXX=y
 CONFIG_RTC_DRV_MXC=y
 CONFIG_RTC_DRV_MXC_V2=y
-CONFIG_RTC_DRV_RC5T619=y
 CONFIG_RTC_DRV_SNVS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_EDMA=y
@@ -470,13 +453,14 @@ CONFIG_CRC_CCITT=m
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
+CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 CONFIG_PRINTK_TIME=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_PROVE_LOCKING=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FTRACE is not set
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:08 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:08 +0200
Subject: [PATCH v2 7/9] dt-bindings: arm: fsl: clean-up all toradex
 boards/modules
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-8-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Simplify and unify the distinction between modules and carrier boards.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- New patch cleaning-up dt-bindings documentation.

 .../devicetree/bindings/arm/fsl.yaml          | 79 ++++++++++---------
 1 file changed, 41 insertions(+), 38 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 60f4862ba15e7..a95314bd271c7 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -235,7 +235,7 @@ properties:
               - technexion,imx6q-pico-pi      # TechNexion i.MX6Q Pico-Pi
               - technologic,imx6q-ts4900
               - technologic,imx6q-ts7970
-              - toradex,apalis_imx6q      # Apalis iMX6 Module
+              - toradex,apalis_imx6q      # Apalis iMX6 Modules
               - udoo,imx6q-udoo           # Udoo i.MX6 Quad Board
               - uniwest,imx6q-evi         # Uniwest Evi
               - variscite,dt6customboard
@@ -314,18 +314,12 @@ properties:
           - const: phytec,imx6q-pfla02    # PHYTEC phyFLEX-i.MX6 Quad
           - const: fsl,imx6q
 
-      - description: i.MX6Q Boards with Toradex Apalis iMX6Q/D Module
+      - description: i.MX6Q Boards with Toradex Apalis iMX6Q/D Modules
         items:
           - enum:
-              - toradex,apalis_imx6q-ixora  # Apalis iMX6Q/D Module on Ixora Carrier Board
-              - toradex,apalis_imx6q-eval   # Apalis iMX6Q/D Module on Apalis Evaluation Board
-          - const: toradex,apalis_imx6q
-          - const: fsl,imx6q
-
-      - description: i.MX6Q Toradex Apalis iMX6Q/D Module on Ixora Carrier Board V1.1
-        items:
-          - const: toradex,apalis_imx6q-ixora-v1.1
-          - const: toradex,apalis_imx6q-ixora
+              - toradex,apalis_imx6q-ixora      # Apalis iMX6Q/D Module on Ixora Carrier Board
+              - toradex,apalis_imx6q-ixora-v1.1 # Apalis iMX6Q/D Module on Ixora V1.1 Carrier Board
+              - toradex,apalis_imx6q-eval       # Apalis iMX6Q/D Module on Apalis Evaluation Board
           - const: toradex,apalis_imx6q
           - const: fsl,imx6q
 
@@ -393,6 +387,8 @@ properties:
               - technexion,imx6dl-pico-pi      # TechNexion i.MX6DL Pico-Pi
               - technologic,imx6dl-ts4900
               - technologic,imx6dl-ts7970
+              - toradex,colibri_imx6dl      # Colibri iMX6 Modules
+              - toradex,colibri_imx6dl-v1_1 # Colibri iMX6 V1.1 Modules
               - udoo,imx6dl-udoo          # Udoo i.MX6 Dual-lite Board
               - vdl,lanmcu                # Van der Laan LANMCU board
               - wand,imx6dl-wandboard     # Wandboard i.MX6 Dual Lite Board
@@ -466,20 +462,18 @@ properties:
           - const: phytec,imx6dl-pfla02   # PHYTEC phyFLEX-i.MX6 Quad
           - const: fsl,imx6dl
 
-      - description: i.MX6DL Toradex Colibri iMX6 Module on Colibri
-                     Evaluation Board V3
+      - description: i.MX6DL Boards with Toradex Colibri iMX6DL/S Modules
         items:
-          - const: toradex,colibri_imx6dl-eval-v3
-          - const: toradex,colibri_imx6dl          # Colibri iMX6 Module
+          - enum:
+              - toradex,colibri_imx6dl-eval-v3      # Colibri iMX6DL/S Module on Colibri Evaluation Board V3
+          - const: toradex,colibri_imx6dl           # Colibri iMX6DL/S Module
           - const: fsl,imx6dl
 
-      - description: i.MX6DL Toradex Colibri iMX6 Module V1.1 on Colibri
-                     Evaluation Board V3
+      - description: i.MX6DL Boards with Toradex Colibri iMX6DL/S V1.1 Modules
         items:
-          - const: toradex,colibri_imx6dl-v1_1-eval-v3
-          - const: toradex,colibri_imx6dl-v1_1     # Colibri iMX6 Module V1.1
-          - const: toradex,colibri_imx6dl-eval-v3
-          - const: toradex,colibri_imx6dl          # Colibri iMX6 Module
+          - enum:
+              - toradex,colibri_imx6dl-v1_1-eval-v3 # Colibri iMX6DL/S V1.1 Module on Colibri Evaluation Board V3
+          - const: toradex,colibri_imx6dl-v1_1      # Colibri iMX6DL/S V1.1 Module
           - const: fsl,imx6dl
 
       - description: i.MX6S DHCOM DRC02 Board
@@ -586,8 +580,8 @@ properties:
               - fsl,imx6ull-14x14-evk     # i.MX6 UltraLiteLite 14x14 EVK Board
               - kontron,imx6ull-n6411-som # Kontron N6411 SOM
               - myir,imx6ull-mys-6ulx-eval # MYiR Tech iMX6ULL Evaluation Board
-              - toradex,colibri-imx6ull-eval      # Colibri iMX6ULL Module on Colibri Eval Board
-              - toradex,colibri-imx6ull-wifi-eval # Colibri iMX6ULL Wi-Fi / BT Module on Colibri Eval Board
+              - toradex,colibri-imx6ull      # Colibri iMX6ULL Modules
+              - toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Modules
           - const: fsl,imx6ull
 
       - description: i.MX6ULL Armadeus Systems OPOS6ULDev Board
@@ -605,6 +599,20 @@ properties:
           - const: phytec,imx6ull-pcl063  # PHYTEC phyCORE-i.MX 6ULL
           - const: fsl,imx6ull
 
+      - description: i.MX6ULL Boards with Toradex Colibri iMX6ULL Modules
+        items:
+          - enum:
+              - toradex,colibri-imx6ull-eval      # Colibri iMX6ULL Module on Colibri Evaluation Board
+          - const: toradex,colibri-imx6ull        # Colibri iMX6ULL Module
+          - const: fsl,imx6dl
+
+      - description: i.MX6ULL Boards with Toradex Colibri iMX6ULL Wi-Fi / BT Modules
+        items:
+          - enum:
+              - toradex,colibri-imx6ull-wifi-eval # Colibri iMX6ULL Wi-Fi / BT Module on Colibri Evaluation Board
+          - const: toradex,colibri-imx6ull-wifi   # Colibri iMX6ULL Wi-Fi / BT Module
+          - const: fsl,imx6dl
+
       - description: Kontron N6411 S Board
         items:
           - const: kontron,imx6ull-n6411-s
@@ -622,6 +630,7 @@ properties:
         items:
           - enum:
               - element14,imx7s-warp      # Element14 Warp i.MX7 Board
+              - toradex,colibri-imx7s     # Colibri iMX7S Module
           - const: fsl,imx7s
 
       - description: i.MX7S Boards with Toradex Colibri iMX7S Module
@@ -653,15 +662,8 @@ properties:
               - technexion,imx7d-pico-hobbit  # TechNexion i.MX7D Pico-Hobbit
               - technexion,imx7d-pico-nymph   # TechNexion i.MX7D Pico-Nymph
               - technexion,imx7d-pico-pi      # TechNexion i.MX7D Pico-Pi
-              - toradex,colibri-imx7d                   # Colibri iMX7 Dual Module
-              - toradex,colibri-imx7d-aster             # Colibri iMX7 Dual Module on Aster Carrier Board
-              - toradex,colibri-imx7d-emmc              # Colibri iMX7 Dual 1GB (eMMC) Module
-              - toradex,colibri-imx7d-emmc-aster        # Colibri iMX7 Dual 1GB (eMMC) Module on
-                                                        #  Aster Carrier Board
-              - toradex,colibri-imx7d-emmc-eval-v3      # Colibri iMX7 Dual 1GB (eMMC) Module on
-                                                        #  Colibri Evaluation Board V3
-              - toradex,colibri-imx7d-eval-v3           # Colibri iMX7 Dual Module on
-                                                        #  Colibri Evaluation Board V3
+              - toradex,colibri-imx7d         # Colibri iMX7D Module
+              - toradex,colibri-imx7d-emmc    # Colibri iMX7D 1GB (eMMC) Module
               - zii,imx7d-rmu2            # ZII RMU2 Board
               - zii,imx7d-rpu2            # ZII RPU2 Board
           - const: fsl,imx7d
@@ -686,12 +688,12 @@ properties:
       - description: i.MX7D Boards with Toradex Colibri i.MX7D Module
         items:
           - enum:
-              - toradex,colibri-imx7d-aster   # Module on Aster Carrier Board
-              - toradex,colibri-imx7d-eval-v3 # Module on Colibri Evaluation Board V3
+              - toradex,colibri-imx7d-aster   # Colibri iMX7D Module on Aster Carrier Board
+              - toradex,colibri-imx7d-eval-v3 # Colibri iMX7D Module on Colibri Evaluation Board V3
           - const: toradex,colibri-imx7d
           - const: fsl,imx7d
 
-      - description: i.MX7D Boards with Toradex Colibri i.MX7D eMMC Module
+      - description: i.MX7D Boards with Toradex Colibri i.MX7D 1GB (eMMC) Module
         items:
           - enum:
               - toradex,colibri-imx7d-emmc-aster    # Module on Aster Carrier Board
@@ -812,10 +814,10 @@ properties:
           - enum:
               - einfochips,imx8qxp-ai_ml  # i.MX8QXP AI_ML Board
               - fsl,imx8qxp-mek           # i.MX8QXP MEK Board
-              - toradex,colibri-imx8x         # Colibri iMX8X Module
+              - toradex,colibri-imx8x     # Colibri iMX8X Modules
           - const: fsl,imx8qxp
 
-      - description: Toradex Colibri i.MX8 Evaluation Board
+      - description: i.MX8QXP Boards with Toradex Coilbri iMX8X Modules
         items:
           - enum:
               - toradex,colibri-imx8x-eval-v3 # Colibri iMX8X Module on Colibri Evaluation Board V3
@@ -847,9 +849,10 @@ properties:
       - description: VF610 based Boards
         items:
           - enum:
+              - fsl,vf610-twr             # VF610 Tower Board
               - lwn,bk4                   # Liebherr BK4 controller
               - phytec,vf610-cosmic       # PHYTEC Cosmic/Cosmic+ Board
-              - fsl,vf610-twr             # VF610 Tower Board
+              - toradex,vf610-colibri_vf61 # Colibri VF61 Modules
           - const: fsl,vf610
 
       - description: Toradex Colibri VF61 Module on Colibri Evaluation Board
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:06 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:06 +0200
Subject: [PATCH v2 5/9] ARM: imx_v6_v7_defconfig: build imx sdma driver as
 module
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-6-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build CONFIG_IMX_SDMA as a module to avoid the following boot issue:

[    5.214751] imx-sdma 20ec000.sdma: Direct firmware load for
 imx/sdma/sdma-imx6q.bin failed with error -2
[    5.215762] imx-sdma 20ec000.sdma: Falling back to sysfs fallback
 for: imx/sdma/sdma-imx6q.bin

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

(no changes since v1)

 arch/arm/configs/imx_v6_v7_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 21803cd2d1ba7..c0008b7faf2ce 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -380,7 +380,7 @@ CONFIG_RTC_DRV_MXC_V2=y
 CONFIG_RTC_DRV_SNVS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_EDMA=y
-CONFIG_IMX_SDMA=y
+CONFIG_IMX_SDMA=m
 CONFIG_MXS_DMA=y
 CONFIG_DMATEST=m
 CONFIG_STAGING=y
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:09 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:09 +0200
Subject: [PATCH v2 8/9] ARM: dts: colibri-imx6ull-emmc: add device tree
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-9-marcel@ziswiler.com>

From: Max Krummenacher <max.krummenacher at toradex.com>

Add a device tree for a Colibri iMX6ULL 1GB which has a eMMC instead of
the raw NAND used on other SKUs.

Related-to: ELB-4056, ELB-4058, ELB-4070
Signed-off-by: Max Krummenacher <max.krummenacher at toradex.com>
Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- Fix indentation.
- Use latest agreed upon SPDX-License-Identifier GPL-2.0+ OR MIT.
- Drop AG in our copyright statement as recommended by our legal.

 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/imx6ull-colibri-emmc-eval-v3.dts |  17 ++
 .../dts/imx6ull-colibri-emmc-nonwifi.dtsi     | 185 ++++++++++++++++++
 arch/arm/boot/dts/imx6ull-colibri.dtsi        |  32 ++-
 4 files changed, 233 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
 create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7e0934180724d..f88ddcc40b6ac 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -671,6 +671,7 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
 	imx6ul-tx6ul-0011.dtb \
 	imx6ul-tx6ul-mainboard.dtb \
 	imx6ull-14x14-evk.dtb \
+	imx6ull-colibri-emmc-eval-v3.dtb \
 	imx6ull-colibri-eval-v3.dtb \
 	imx6ull-colibri-wifi-eval-v3.dtb \
 	imx6ull-myir-mys-6ulx-eval.dtb \
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts b/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
new file mode 100644
index 0000000000000..61b93cb040c7f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6ull-colibri-emmc-nonwifi.dtsi"
+#include "imx6ull-colibri-eval-v3.dtsi"
+
+/ {
+	model = "Toradex Colibri iMX6ULL 1GB (eMMC) on Colibri Evaluation Board V3";
+	compatible = "toradex,colibri-imx6ull-emmc-eval",
+		     "toradex,colibri-imx6ull-emmc",
+		     "toradex,colibri-imx6ull",
+		     "fsl,imx6ull";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi
new file mode 100644
index 0000000000000..a099abfdfa27c
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright 2021 Toradex
+ */
+
+#include "imx6ull-colibri.dtsi"
+
+/ {
+	aliases {
+		mmc0 = &usdhc2; /* eMMC */
+		mmc1 = &usdhc1; /* MMC 4bit slot */
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x10000000>;
+	};
+};
+
+&gpio1 {
+	gpio-line-names = "SODIMM_8",
+			  "SODIMM_6",
+			  "SODIMM_129",
+			  "SODIMM_89",
+			  "SODIMM_19",
+			  "SODIMM_21",
+			  "UNUSABLE_SODIMM_180",
+			  "UNUSABLE_SODIMM_184",
+			  "SODIMM_4",
+			  "SODIMM_2",
+			  "SODIMM_106",
+			  "SODIMM_71",
+			  "SODIMM_23",
+			  "SODIMM_31",
+			  "SODIMM_99",
+			  "SODIMM_102",
+			  "SODIMM_33",
+			  "SODIMM_35",
+			  "SODIMM_25",
+			  "SODIMM_27",
+			  "SODIMM_36",
+			  "SODIMM_38",
+			  "SODIMM_32",
+			  "SODIMM_34",
+			  "SODIMM_135",
+			  "SODIMM_77",
+			  "SODIMM_100",
+			  "SODIMM_186",
+			  "SODIMM_196",
+			  "SODIMM_194";
+};
+
+&gpio2 {
+	gpio-line-names = "SODIMM_55",
+			  "SODIMM_63",
+			  "SODIMM_178",
+			  "SODIMM_188",
+			  "SODIMM_73",
+			  "SODIMM_30",
+			  "SODIMM_67",
+			  "SODIMM_104",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_190",
+			  "SODIMM_47",
+			  "SODIMM_192",
+			  "SODIMM_49",
+			  "SODIMM_51",
+			  "SODIMM_53";
+};
+
+&gpio3 {
+	gpio-line-names = "SODIMM_56",
+			  "SODIMM_44",
+			  "SODIMM_68",
+			  "SODIMM_82",
+			  "",
+			  "SODIMM_76",
+			  "SODIMM_70",
+			  "SODIMM_60",
+			  "SODIMM_58",
+			  "SODIMM_78",
+			  "SODIMM_72",
+			  "SODIMM_80",
+			  "SODIMM_46",
+			  "SODIMM_62",
+			  "SODIMM_48",
+			  "SODIMM_74",
+			  "SODIMM_50",
+			  "SODIMM_52",
+			  "SODIMM_54",
+			  "SODIMM_66",
+			  "SODIMM_64",
+			  "SODIMM_57",
+			  "SODIMM_61",
+			  "SODIMM_29",
+			  "SODIMM_37",
+			  "SODIMM_88",
+			  "SODIMM_86",
+			  "SODIMM_92",
+			  "SODIMM_90";
+};
+
+&gpio4 {
+	gpio-line-names = "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_140",
+			  "SODIMM_59",
+			  "SODIMM_142",
+			  "SODIMM_144",
+			  "SODIMM_133",
+			  "SODIMM_146",
+			  "SODIMM_28",
+			  "SODIMM_75",
+			  "SODIMM_96",
+			  "SODIMM_81",
+			  "SODIMM_94",
+			  "SODIMM_101",
+			  "SODIMM_103",
+			  "SODIMM_79",
+			  "SODIMM_97",
+			  "SODIMM_69",
+			  "SODIMM_98",
+			  "SODIMM_85",
+			  "SODIMM_65";
+};
+
+&gpio5 {
+	gpio-line-names = "SODIMM_43",
+			  "SODIMM_45",
+			  "SODIMM_137",
+			  "SODIMM_95",
+			  "SODIMM_107",
+			  "SODIMM_131",
+			  "SODIMM_93",
+			  "",
+			  "SODIMM_138",
+			  "",
+			  "SODIMM_105",
+			  "SODIMM_127";
+};
+
+&gpmi {
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3
+		&pinctrl_gpio4 &pinctrl_gpio6 &pinctrl_gpio7
+		&pinctrl_gpmi_gpio>;
+};
+
+&iomuxc_snvs {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_snvs_gpio1 &pinctrl_snvs_gpio3>;
+};
+
+&usdhc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2emmc>;
+	assigned-clocks = <&clks IMX6UL_CLK_USDHC2_SEL>, <&clks IMX6UL_CLK_USDHC2>;
+	assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>;
+	assigned-clock-rates = <0>, <198000000>;
+	bus-width = <8>;
+	keep-power-in-suspend;
+	no-1-8-v;
+	non-removable;
+	vmmc-supply = <&reg_module_3v3>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-colibri.dtsi b/arch/arm/boot/dts/imx6ull-colibri.dtsi
index 0cdbf7b6e7285..7f35a06dff95b 100644
--- a/arch/arm/boot/dts/imx6ull-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6ull-colibri.dtsi
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
 /*
- * Copyright 2018 Toradex AG
+ * Copyright 2018-2021 Toradex
  */
 
 #include "imx6ull.dtsi"
@@ -345,6 +345,19 @@ MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01	0xb0b0 /* SODIMM 63 */
 		>;
 	};
 
+	/*
+	 * With an eMMC instead of a raw NAND device the following pins
+	 * are available at SODIMM pins
+	 */
+	pinctrl_gpmi_gpio: gpmi-gpio-grp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_ALE__GPIO4_IO10		0x10b0 /* SODIMM 140 */
+			MX6UL_PAD_NAND_CE0_B__GPIO4_IO13	0x10b0 /* SODIMM 144 */
+			MX6UL_PAD_NAND_CLE__GPIO4_IO15		0x10b0 /* SODIMM 146 */
+			MX6UL_PAD_NAND_READY_B__GPIO4_IO12	0x10b0 /* SODIMM 142 */
+		>;
+	};
+
 	pinctrl_gpmi_nand: gpmi-nand-grp {
 		fsl,pins = <
 			MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00	0x100a9
@@ -533,6 +546,21 @@ MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT	0x10
 		>;
 	};
 
+	pinctrl_usdhc2emmc: usdhc2emmcgrp {
+		fsl,pins = <
+			MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x17059
+			MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059
+			MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
+			MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
+			MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
+			MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
+			MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
+			MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
+			MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
+			MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
+		>;
+	};
+
 	pinctrl_wdog: wdog-grp {
 		fsl,pins = <
 			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:04 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:04 +0200
Subject: [PATCH v2 3/9] ARM: imx_v6_v7_defconfig: change snd soc tlv320aic3x
 to i2c variant
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-4-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Change CONFIG_SND_SOC_TLV320AIC3X to CONFIG_SND_SOC_TLV320AIC3X_I2C.
I did double check all current mainline device trees and they are all
using the I2C rather than the SPI variant.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

(no changes since v1)

 arch/arm/configs/imx_v6_v7_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 6618a009a105e..90d6a5cf254e0 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -317,7 +317,7 @@ CONFIG_SND_SOC_IMX_MC13783=y
 CONFIG_SND_SOC_FSL_ASOC_CARD=y
 CONFIG_SND_SOC_AC97_CODEC=y
 CONFIG_SND_SOC_CS42XX8_I2C=y
-CONFIG_SND_SOC_TLV320AIC3X=y
+CONFIG_SND_SOC_TLV320AIC3X_I2C=y
 CONFIG_SND_SOC_WM8960=y
 CONFIG_SND_SOC_WM8962=y
 CONFIG_SND_SIMPLE_CARD=y
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:10 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:10 +0200
Subject: [PATCH v2 9/9] dt-bindings: arm: fsl: add toradex,
 colibri-imx6ull-emmc
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-10-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Add toradex,colibri-imx6ull-emmc for our new Colibri iMX6ULL 1GB (eMMC)
Module and the carrier boards (so far only Colibri Evaluation Board) it
may be mated in.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- New patch documenting dt-bindings.

 Documentation/devicetree/bindings/arm/fsl.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index a95314bd271c7..32e2d5537210b 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -581,6 +581,7 @@ properties:
               - kontron,imx6ull-n6411-som # Kontron N6411 SOM
               - myir,imx6ull-mys-6ulx-eval # MYiR Tech iMX6ULL Evaluation Board
               - toradex,colibri-imx6ull      # Colibri iMX6ULL Modules
+              - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module
               - toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Modules
           - const: fsl,imx6ull
 
@@ -606,6 +607,13 @@ properties:
           - const: toradex,colibri-imx6ull        # Colibri iMX6ULL Module
           - const: fsl,imx6dl
 
+      - description: i.MX6ULL Boards with Toradex Colibri iMX6ULL 1GB (eMMC) Module
+        items:
+          - enum:
+              - toradex,colibri-imx6ull-emmc-eval # Colibri iMX6ULL 1GB (eMMC) Module on Colibri Evaluation Board
+          - const: toradex,colibri-imx6ull-emmc   # Colibri iMX6ULL 1GB (eMMC) Module
+          - const: fsl,imx6dl
+
       - description: i.MX6ULL Boards with Toradex Colibri iMX6ULL Wi-Fi / BT Modules
         items:
           - enum:
-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:01 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:01 +0200
Subject: [PATCH v2 0/9] ARM: prepare and add colibri imx6ull 1gb (emmc) support
Message-ID: <20210819220910.586819-1-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>


Clean-up imx_v6_v7_defconfig and then add support for the new Colibri
iMX6ULL 1GB (eMMC) which builds on the success of the existing Colibri
iMX6ULL SKUs using raw NAND but replaces this with more RAM (1 GB) and
an eMMC (4 GB).

Changes in v2:
- New patch cleaning-up dt-bindings documentation.
- Fix indentation.
- Use latest agreed upon SPDX-License-Identifier GPL-2.0+ OR MIT.
- Drop AG in our copyright statement as recommended by our legal.
- New patch documenting dt-bindings.

Marcel Ziswiler (8):
  ARM: imx_v6_v7_defconfig: enable mtd physmap
  ARM: imx_v6_v7_defconfig: enable fb
  ARM: imx_v6_v7_defconfig: change snd soc tlv320aic3x to i2c variant
  ARM: imx_v6_v7_defconfig: rebuild default configuration
  ARM: imx_v6_v7_defconfig: build imx sdma driver as module
  ARM: imx_v6_v7_defconfig: enable bpf syscall and cgroup bpf
  dt-bindings: arm: fsl: clean-up all toradex boards/modules
  dt-bindings: arm: fsl: add toradex,colibri-imx6ull-emmc

Max Krummenacher (1):
  ARM: dts: colibri-imx6ull-emmc: add device tree

 .../devicetree/bindings/arm/fsl.yaml          |  87 ++++----
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/imx6ull-colibri-emmc-eval-v3.dts |  17 ++
 .../dts/imx6ull-colibri-emmc-nonwifi.dtsi     | 185 ++++++++++++++++++
 arch/arm/boot/dts/imx6ull-colibri.dtsi        |  32 ++-
 arch/arm/configs/imx_v6_v7_defconfig          |  46 ++---
 6 files changed, 299 insertions(+), 69 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-eval-v3.dts
 create mode 100644 arch/arm/boot/dts/imx6ull-colibri-emmc-nonwifi.dtsi

-- 
2.26.2



From marcel at ziswiler.com  Thu Aug 19 15:09:07 2021
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 20 Aug 2021 00:09:07 +0200
Subject: [PATCH v2 6/9] ARM: imx_v6_v7_defconfig: enable bpf syscall and
 cgroup bpf
In-Reply-To: <20210819220910.586819-1-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
Message-ID: <20210819220910.586819-7-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_BPF_SYSCALL and CONFIG_CGROUP_BPF to allow for systemd
interoperability. This avoids the following failure on boot:

[   10.615914] systemd[1]: system-getty.slice: unit configures an IP
 firewall, but the local system does not support BPF/cgroup firewalling.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

(no changes since v1)

 arch/arm/configs/imx_v6_v7_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index c0008b7faf2ce..3e58c76763563 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -2,11 +2,13 @@ CONFIG_KERNEL_LZO=y
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_CGROUPS=y
+CONFIG_CGROUP_BPF=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
-- 
2.26.2



From marex at denx.de  Thu Aug 19 15:22:28 2021
From: marex at denx.de (Marek Vasut)
Date: Fri, 20 Aug 2021 00:22:28 +0200
Subject: [PATCH] drm/stm: ltdc: improve pm_runtime to stop clocks
In-Reply-To: <629b6666-74b3-91f0-5c6c-e26d55ea62d8@foss.st.com>
References: <20210629115709.16145-1-raphael.gallais-pou@foss.st.com>
 <420e243d-7541-a07e-177b-d2db11c26aef@denx.de>
 <3bb823e4-4724-7072-fe9f-7b8a355c8e50@foss.st.com>
 <5d65ca80-4f94-49e1-5de1-cf29e8231a6a@denx.de>
 <629b6666-74b3-91f0-5c6c-e26d55ea62d8@foss.st.com>
Message-ID: <a051825c-1795-b7c4-6fdd-64595e52a6ca@denx.de>

On 8/17/21 11:43 AM, Raphael Gallais-Pou wrote:
> 
> On 7/2/21 8:07 PM, Marek Vasut wrote:
>> On 7/2/21 11:23 AM, Raphael Gallais-Pou wrote:
>>> Hello Marek,
>>
>> Hi,
>>
>>> Sorry for the late answer.
>>
>> No worries, take your time
>>
>>> On 6/30/21 2:35 AM, Marek Vasut wrote:
>>>> On 6/29/21 1:58 PM, Raphael GALLAIS-POU - foss wrote:
>>>>
>>>> [...]
>>>>
>>>>> +++ b/drivers/gpu/drm/stm/ltdc.c
>>>>> @@ -425,10 +425,17 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc,
>>>>>  ? {
>>>>>  ????? struct ltdc_device *ldev = crtc_to_ltdc(crtc);
>>>>>  ????? struct drm_device *ddev = crtc->dev;
>>>>> +??? int ret;
>>>>>  ? ????? DRM_DEBUG_DRIVER("\n");
>>>>>  ? -??? pm_runtime_get_sync(ddev->dev);
>>>>> +??? if (!pm_runtime_active(ddev->dev)) {
>>>>> +??????? ret = pm_runtime_get_sync(ddev->dev);
>>>>
>>>> All these if (!pm_runtime_active()) then pm_runtime_get_sync() calls look like workaround for some larger issue. Shouldn't the pm_runtime do some refcounting on its own , so this shouldn't be needed ?
>>>
>>>
>>> This problem purely comes from the driver internals, so I don't think it is a workaround.
>>>
>>> Because of the "ltdc_crtc_mode_set_nofb" function which does not have any "symmetrical" call, such as enable/disable functions, there was two calls to pm_runtime_get_sync against one call to pm_runtime_put_sync.
>>>
>>> This instability resulted in the LTDC clocks being always enabled, even when the peripheral was disabled. This could be seen in the clk_summary as explained in the patch summary among other things.
>>>
>>> By doing so, we first check if the clocks are not already activated, and in that case we call pm_runtime_get_sync.
>>
>> I just have to wonder, how come other drivers don't need these if (!pm_runtime_active()) pm_runtime_get_sync() conditions. I think they just get/put the runtime PM within a call itself, not across function calls. Maybe that could be the right fix here too ?
> 
> 
> Hello Marek,

Hi,

> I've run a deeper analysis over this implementation.

Thank you

> If I may take rockchip's "rockchip_drm_vop.c" driver, there is an boolean "is_enabled" set to true when crtc_atomic_enable is called.
> 
> The above implementation could save us from adding such field in the ltdc_dev structure.
> 
> Another solution could be in order to simply call pm_runtime_get_sync() in ltdc_crtc_mode_set_nofb() and by removing this condition in ltdc_atomic_crtc_disable() the driver behaves just like the first version of this patch.
> 
> In this way, it avoids such conditions and seems more to get along with the current implementation.

Let me maybe ask a different question -- can ltdc_crtc_mode_set_nofb() 
ever be called with the LTDC suspended (so you would have to call 
pm_runtime_get_sync() in that function to power the block up and to get 
access to its registers) ?

[...]


From rdunlap at infradead.org  Thu Aug 19 15:32:37 2021
From: rdunlap at infradead.org (Randy Dunlap)
Date: Thu, 19 Aug 2021 15:32:37 -0700
Subject: [PATCH v2] clk: at91: sama7g5: remove all kernel-doc & kernel-doc
 warnings
Message-ID: <20210819223237.20115-1-rdunlap@infradead.org>

Remove all "/**" kernel-doc markers from sama7g5.c since they are
all internal to this driver source file only.
This eliminates 14 warnings that were reported by the kernel test robot.

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Reported-by: kernel test robot <lkp at intel.com>
Cc: Claudiu Beznea <claudiu.beznea at microchip.com>
Cc: Michael Turquette <mturquette at baylibre.com>
Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Eugen Hristev <eugen.hristev at microchip.com>
Cc: linux-clk at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
v2: use /* instead of /** comments for internal documentation (as
    suggested by Claudiu)

 drivers/clk/at91/sama7g5.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

--- linux-next-20210819.orig/drivers/clk/at91/sama7g5.c
+++ linux-next-20210819/drivers/clk/at91/sama7g5.c
@@ -35,7 +35,7 @@ static DEFINE_SPINLOCK(pmc_pll_lock);
 static DEFINE_SPINLOCK(pmc_mck0_lock);
 static DEFINE_SPINLOCK(pmc_mckX_lock);
 
-/**
+/*
  * PLL clocks identifiers
  * @PLL_ID_CPU:		CPU PLL identifier
  * @PLL_ID_SYS:		System PLL identifier
@@ -56,7 +56,7 @@ enum pll_ids {
 	PLL_ID_MAX,
 };
 
-/**
+/*
  * PLL type identifiers
  * @PLL_TYPE_FRAC:	fractional PLL identifier
  * @PLL_TYPE_DIV:	divider PLL identifier
@@ -118,7 +118,7 @@ static const struct clk_pll_characterist
 	.output = pll_outputs,
 };
 
-/**
+/*
  * PLL clocks description
  * @n:		clock name
  * @p:		clock parent
@@ -285,7 +285,7 @@ static const struct {
 	},
 };
 
-/**
+/*
  * Master clock (MCK[1..4]) description
  * @n:			clock name
  * @ep:			extra parents names array
@@ -337,7 +337,7 @@ static const struct {
 	  .c = 1, },
 };
 
-/**
+/*
  * System clock description
  * @n:	clock name
  * @p:	clock parent name
@@ -361,7 +361,7 @@ static const struct {
 /* Mux table for programmable clocks. */
 static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, };
 
-/**
+/*
  * Peripheral clock description
  * @n:		clock name
  * @p:		clock parent name
@@ -449,7 +449,7 @@ static const struct {
 	{ .n = "uhphs_clk",	.p = "mck1", .id = 106, },
 };
 
-/**
+/*
  * Generic clock description
  * @n:			clock name
  * @pp:			PLL parents


From rananta at google.com  Thu Aug 19 15:34:06 2021
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Thu, 19 Aug 2021 22:34:06 +0000
Subject: [PATCH] KVM: arm64: Ratelimit error log during guest debug exception
Message-ID: <20210819223406.1132426-1-rananta@google.com>

Potentially, the guests could trigger a debug exception that's
outside the exception class range. This could lead to an
excessive syslog flooding. Hence, ratelimit the error message.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 arch/arm64/kvm/handle_exit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 04ebab299aa4..c7cec7ffe93c 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -134,7 +134,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu)
 	case ESR_ELx_EC_BRK64:
 		break;
 	default:
-		kvm_err("%s: un-handled case esr: %#08x\n",
+		kvm_pr_unimpl("%s: un-handled case esr: %#08x\n",
 			__func__, (unsigned int) esr);
 		ret = -1;
 		break;
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From pr-tracker-bot at kernel.org  Thu Aug 19 15:44:59 2021
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Thu, 19 Aug 2021 22:44:59 +0000
Subject: [GIT PULL] ARM: SoC fixes for 5.14, part 3
In-Reply-To: <CAK8P3a12+R4qpANkd4MWHa8YNNhXf0wNnN+GaWk4DqW3NJ+DQQ@mail.gmail.com>
References: <CAK8P3a12+R4qpANkd4MWHa8YNNhXf0wNnN+GaWk4DqW3NJ+DQQ@mail.gmail.com>
Message-ID: <162941309981.30040.17491472610869566678.pr-tracker-bot@kernel.org>

The pull request you sent on Thu, 19 Aug 2021 23:47:20 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-5.14-3

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/d992fe5318d8d7af9510b879439a3c7f283da442

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From hayashi.kunihiko at socionext.com  Thu Aug 19 16:03:02 2021
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Fri, 20 Aug 2021 08:03:02 +0900
Subject: [PATCH] PCI: uniphier: Take lock in INTX irq_{mask,unmask,ack}
 callbacks
In-Reply-To: <20210819112908.GA3188927@bjorn-Precision-5520>
References: <20210819112908.GA3188927@bjorn-Precision-5520>
Message-ID: <6ae226a6-dc3d-94da-a356-6bd78053de06@socionext.com>

Hi Bjorn,
Thank you for checking.

On 2021/08/19 20:29, Bjorn Helgaas wrote:
> Possibly update subject to be more descriptive, along lines of:
> 
>    Serialize INTx masking/unmasking

Okay, I'll apply it to the subject.

> On Thu, Aug 19, 2021 at 07:56:06PM +0900, Kunihiko Hayashi wrote:
>> The same condition register PCI_RCV_INTX is used in irq_mask(),
>> irq_unmask() and irq_ack() callbacks. Accesses to register can occur at the
>> same time without lock.
>> This introduces a lock into the callbacks to prevent the issue.
> 
> Rewrap into a single paragraph or add blank line between paragraphs.
> 
> s/This introduces/Add/ to make this an imperative description of what
> you want this patch to do.  No need for "This" since the context is
> obvious.

I see. I'll rewrite the message to convey it more directly.

Thank you,

---
Best Regards
Kunihiko Hayashi


From heiko at sntech.de  Thu Aug 19 16:04:06 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 20 Aug 2021 01:04:06 +0200
Subject: [PATCH] soc: rockchip: io-domain: Remove unneeded semicolon
In-Reply-To: <1629361749-97977-1-git-send-email-jiapeng.chong@linux.alibaba.com>
References: <1629361749-97977-1-git-send-email-jiapeng.chong@linux.alibaba.com>
Message-ID: <162941424101.2925714.5080372869374112327.b4-ty@sntech.de>

On Thu, 19 Aug 2021 16:29:09 +0800, Jiapeng Chong wrote:
> Fix the following coccicheck warnings:
> 
> ./drivers/soc/rockchip/io-domain.c:118:2-3: Unneeded semicolon.

Applied, thanks!

[1/1] soc: rockchip: io-domain: Remove unneeded semicolon
      commit: 9e5747c57807ad8a04c356340190cfdd0bd54111

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From chunkuang.hu at kernel.org  Thu Aug 19 16:14:30 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Fri, 20 Aug 2021 07:14:30 +0800
Subject: [PATCH v8 10/13] drm/mediatek: adjust to the alphabetic order for
 mediatek-drm
In-Reply-To: <20210819022327.13040-11-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-11-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY__k28K1LeH-ctavFi9GE9p32kL6K3sxhA0TW54XPsEB-w@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:24???
>
> Adjust to the alphabetic order for the define, function, struct
> and array in mediatek-drm driver
>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 133 ++++++++++----------
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  22 ++--
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  76 +++++------
>  3 files changed, 115 insertions(+), 116 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 93beb980414f..28bc42fd0b8a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -20,17 +20,9 @@
>  #include "mtk_drm_ddp_comp.h"
>  #include "mtk_drm_crtc.h"
>
> -#define DISP_REG_OD_EN                         0x0000
> -#define DISP_REG_OD_CFG                                0x0020
> -#define DISP_REG_OD_SIZE                       0x0030
> -#define DISP_REG_DITHER_5                      0x0114
> -#define DISP_REG_DITHER_7                      0x011c
> -#define DISP_REG_DITHER_15                     0x013c
> -#define DISP_REG_DITHER_16                     0x0140
> -
> -#define DISP_REG_UFO_START                     0x0000
>
>  #define DISP_REG_AAL_EN                                0x0000
> +#define AAL_EN                                 BIT(0)
>  #define DISP_REG_AAL_SIZE                      0x0030
>
>  #define DISP_REG_DITHER_EN                     0x0000
> @@ -38,23 +30,29 @@
>  #define DISP_REG_DITHER_CFG                    0x0020
>  #define DITHER_RELAY_MODE                      BIT(0)
>  #define DITHER_ENGINE_EN                       BIT(1)
> -#define DISP_REG_DITHER_SIZE                   0x0030
> -
> -#define OD_RELAYMODE                           BIT(0)
> -
> -#define UFO_BYPASS                             BIT(2)
> -
> -#define AAL_EN                                 BIT(0)
>
>  #define DISP_DITHERING                         BIT(2)
> +#define DISP_REG_DITHER_SIZE                   0x0030
> +#define DISP_REG_DITHER_5                      0x0114
> +#define DISP_REG_DITHER_7                      0x011c
> +#define DISP_REG_DITHER_15                     0x013c
>  #define DITHER_LSB_ERR_SHIFT_R(x)              (((x) & 0x7) << 28)
>  #define DITHER_ADD_LSHIFT_R(x)                 (((x) & 0x7) << 20)
>  #define DITHER_NEW_BIT_MODE                    BIT(0)
> +#define DISP_REG_DITHER_16                     0x0140
>  #define DITHER_LSB_ERR_SHIFT_B(x)              (((x) & 0x7) << 28)
>  #define DITHER_ADD_LSHIFT_B(x)                 (((x) & 0x7) << 20)
>  #define DITHER_LSB_ERR_SHIFT_G(x)              (((x) & 0x7) << 12)
>  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
>
> +#define DISP_REG_OD_EN                         0x0000
> +#define DISP_REG_OD_CFG                                0x0020
> +#define OD_RELAYMODE                           BIT(0)
> +#define DISP_REG_OD_SIZE                       0x0030
> +
> +#define DISP_REG_UFO_START                     0x0000
> +#define UFO_BYPASS                             BIT(2)
> +
>  struct mtk_ddp_comp_dev {
>         struct clk *clk;
>         void __iomem *regs;
> @@ -106,20 +104,6 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
>  #endif
>  }
>
> -static int mtk_ddp_clk_enable(struct device *dev)
> -{
> -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> -
> -       return clk_prepare_enable(priv->clk);
> -}
> -
> -static void mtk_ddp_clk_disable(struct device *dev)
> -{
> -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> -
> -       clk_disable_unprepare(priv->clk);
> -}
> -

I would like to place the same group together. mtk_ddp_clk_enable()
and mtk_ddp_clk_disable() are common function not belong to any sub
driver. So I would like keep these function here.

Regards,
Chun-Kuang.

>  void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
>                            unsigned int bpc, unsigned int cfg,
>                            unsigned int dither_en, struct cmdq_pkt *cmdq_pkt)
> @@ -146,38 +130,19 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
>         }
>  }
>
> -static void mtk_dither_set(struct device *dev, unsigned int bpc,
> -                   unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
> -{
> -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> -
> -       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
> -                             DISP_DITHERING, cmdq_pkt);
> -}
> -
> -static void mtk_od_config(struct device *dev, unsigned int w,
> -                         unsigned int h, unsigned int vrefresh,
> -                         unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> -{
> -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> -
> -       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
> -       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
> -       mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
> -}
>
> -static void mtk_od_start(struct device *dev)
> +static int mtk_ddp_clk_enable(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(1, priv->regs + DISP_REG_OD_EN);
> +       return clk_prepare_enable(priv->clk);
>  }
>
> -static void mtk_ufoe_start(struct device *dev)
> +static void mtk_ddp_clk_disable(struct device *dev)
>  {
>         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
>
> -       writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
> +       clk_disable_unprepare(priv->clk);
>  }
>
>  static void mtk_aal_config(struct device *dev, unsigned int w,
> @@ -237,6 +202,40 @@ static void mtk_dither_stop(struct device *dev)
>         writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
>  }
>
> +static void mtk_dither_set(struct device *dev, unsigned int bpc,
> +                          unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
> +                             DISP_DITHERING, cmdq_pkt);
> +}
> +
> +static void mtk_od_config(struct device *dev, unsigned int w,
> +                         unsigned int h, unsigned int vrefresh,
> +                         unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
> +       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
> +       mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
> +}
> +
> +static void mtk_od_start(struct device *dev)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       writel(1, priv->regs + DISP_REG_OD_EN);
> +}
> +
> +static void mtk_ufoe_start(struct device *dev)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
> +}
> +
>  static const struct mtk_ddp_comp_funcs ddp_aal = {
>         .clk_enable = mtk_ddp_clk_enable,
>         .clk_disable = mtk_ddp_clk_disable,
> @@ -331,22 +330,22 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
>  };
>
>  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> +       [MTK_DISP_AAL] = "aal",
> +       [MTK_DISP_BLS] = "bls",
> +       [MTK_DISP_CCORR] = "ccorr",
> +       [MTK_DISP_COLOR] = "color",
> +       [MTK_DISP_DITHER] = "dither",
> +       [MTK_DISP_GAMMA] = "gamma",
> +       [MTK_DISP_MUTEX] = "mutex",
> +       [MTK_DISP_OD] = "od",
>         [MTK_DISP_OVL] = "ovl",
>         [MTK_DISP_OVL_2L] = "ovl-2l",
> +       [MTK_DISP_PWM] = "pwm",
>         [MTK_DISP_RDMA] = "rdma",
> -       [MTK_DISP_WDMA] = "wdma",
> -       [MTK_DISP_COLOR] = "color",
> -       [MTK_DISP_CCORR] = "ccorr",
> -       [MTK_DISP_AAL] = "aal",
> -       [MTK_DISP_GAMMA] = "gamma",
> -       [MTK_DISP_DITHER] = "dither",
>         [MTK_DISP_UFOE] = "ufoe",
> -       [MTK_DSI] = "dsi",
> +       [MTK_DISP_WDMA] = "wdma",
>         [MTK_DPI] = "dpi",
> -       [MTK_DISP_PWM] = "pwm",
> -       [MTK_DISP_MUTEX] = "mutex",
> -       [MTK_DISP_OD] = "od",
> -       [MTK_DISP_BLS] = "bls",
> +       [MTK_DSI] = "dsi",
>  };
>
>  struct mtk_ddp_comp_match {
> @@ -500,12 +499,12 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>             type == MTK_DISP_CCORR ||
>             type == MTK_DISP_COLOR ||
>             type == MTK_DISP_GAMMA ||
> -           type == MTK_DPI ||
> -           type == MTK_DSI ||
>             type == MTK_DISP_OVL ||
>             type == MTK_DISP_OVL_2L ||
>             type == MTK_DISP_PWM ||
> -           type == MTK_DISP_RDMA)
> +           type == MTK_DISP_RDMA ||
> +           type == MTK_DPI ||
> +           type == MTK_DSI)
>                 return 0;
>
>         priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index bb914d976cf5..d317b944df66 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -18,22 +18,22 @@ struct mtk_plane_state;
>  struct drm_crtc_state;
>
>  enum mtk_ddp_comp_type {
> -       MTK_DISP_OVL,
> -       MTK_DISP_OVL_2L,
> -       MTK_DISP_RDMA,
> -       MTK_DISP_WDMA,
> -       MTK_DISP_COLOR,
> +       MTK_DISP_AAL,
> +       MTK_DISP_BLS,
>         MTK_DISP_CCORR,
> +       MTK_DISP_COLOR,
>         MTK_DISP_DITHER,
> -       MTK_DISP_AAL,
>         MTK_DISP_GAMMA,
> -       MTK_DISP_UFOE,
> -       MTK_DSI,
> -       MTK_DPI,
> -       MTK_DISP_PWM,
>         MTK_DISP_MUTEX,
>         MTK_DISP_OD,
> -       MTK_DISP_BLS,
> +       MTK_DISP_OVL,
> +       MTK_DISP_OVL_2L,
> +       MTK_DISP_PWM,
> +       MTK_DISP_RDMA,
> +       MTK_DISP_UFOE,
> +       MTK_DISP_WDMA,
> +       MTK_DPI,
> +       MTK_DSI,
>         MTK_DDP_COMP_TYPE_MAX,
>  };
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index b46bdb8985da..a95dc1006b82 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -396,50 +396,20 @@ static const struct component_master_ops mtk_drm_ops = {
>  };
>
>  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
> -       { .compatible = "mediatek,mt2701-disp-ovl",
> -         .data = (void *)MTK_DISP_OVL },
> -       { .compatible = "mediatek,mt8173-disp-ovl",
> -         .data = (void *)MTK_DISP_OVL },
> -       { .compatible = "mediatek,mt8183-disp-ovl",
> -         .data = (void *)MTK_DISP_OVL },
> -       { .compatible = "mediatek,mt8183-disp-ovl-2l",
> -         .data = (void *)MTK_DISP_OVL_2L },
> -       { .compatible = "mediatek,mt2701-disp-rdma",
> -         .data = (void *)MTK_DISP_RDMA },
> -       { .compatible = "mediatek,mt8173-disp-rdma",
> -         .data = (void *)MTK_DISP_RDMA },
> -       { .compatible = "mediatek,mt8183-disp-rdma",
> -         .data = (void *)MTK_DISP_RDMA },
> -       { .compatible = "mediatek,mt8173-disp-wdma",
> -         .data = (void *)MTK_DISP_WDMA },
> +       { .compatible = "mediatek,mt8173-disp-aal",
> +         .data = (void *)MTK_DISP_AAL},
>         { .compatible = "mediatek,mt8183-disp-ccorr",
>           .data = (void *)MTK_DISP_CCORR },
>         { .compatible = "mediatek,mt2701-disp-color",
>           .data = (void *)MTK_DISP_COLOR },
>         { .compatible = "mediatek,mt8173-disp-color",
>           .data = (void *)MTK_DISP_COLOR },
> -       { .compatible = "mediatek,mt8173-disp-aal",
> -         .data = (void *)MTK_DISP_AAL},
> +       { .compatible = "mediatek,mt8183-disp-dither",
> +         .data = (void *)MTK_DISP_DITHER },
>         { .compatible = "mediatek,mt8173-disp-gamma",
>           .data = (void *)MTK_DISP_GAMMA, },
>         { .compatible = "mediatek,mt8183-disp-gamma",
>           .data = (void *)MTK_DISP_GAMMA, },
> -       { .compatible = "mediatek,mt8183-disp-dither",
> -         .data = (void *)MTK_DISP_DITHER },
> -       { .compatible = "mediatek,mt8173-disp-ufoe",
> -         .data = (void *)MTK_DISP_UFOE },
> -       { .compatible = "mediatek,mt2701-dsi",
> -         .data = (void *)MTK_DSI },
> -       { .compatible = "mediatek,mt8173-dsi",
> -         .data = (void *)MTK_DSI },
> -       { .compatible = "mediatek,mt8183-dsi",
> -         .data = (void *)MTK_DSI },
> -       { .compatible = "mediatek,mt2701-dpi",
> -         .data = (void *)MTK_DPI },
> -       { .compatible = "mediatek,mt8173-dpi",
> -         .data = (void *)MTK_DPI },
> -       { .compatible = "mediatek,mt8183-dpi",
> -         .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt2701-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt2712-disp-mutex",
> @@ -448,12 +418,42 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt8183-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
> +       { .compatible = "mediatek,mt8173-disp-od",
> +         .data = (void *)MTK_DISP_OD },
> +       { .compatible = "mediatek,mt2701-disp-ovl",
> +         .data = (void *)MTK_DISP_OVL },
> +       { .compatible = "mediatek,mt8173-disp-ovl",
> +         .data = (void *)MTK_DISP_OVL },
> +       { .compatible = "mediatek,mt8183-disp-ovl",
> +         .data = (void *)MTK_DISP_OVL },
> +       { .compatible = "mediatek,mt8183-disp-ovl-2l",
> +         .data = (void *)MTK_DISP_OVL_2L },
>         { .compatible = "mediatek,mt2701-disp-pwm",
>           .data = (void *)MTK_DISP_BLS },
>         { .compatible = "mediatek,mt8173-disp-pwm",
>           .data = (void *)MTK_DISP_PWM },
> -       { .compatible = "mediatek,mt8173-disp-od",
> -         .data = (void *)MTK_DISP_OD },
> +       { .compatible = "mediatek,mt2701-disp-rdma",
> +         .data = (void *)MTK_DISP_RDMA },
> +       { .compatible = "mediatek,mt8173-disp-rdma",
> +         .data = (void *)MTK_DISP_RDMA },
> +       { .compatible = "mediatek,mt8183-disp-rdma",
> +         .data = (void *)MTK_DISP_RDMA },
> +       { .compatible = "mediatek,mt8173-disp-ufoe",
> +         .data = (void *)MTK_DISP_UFOE },
> +       { .compatible = "mediatek,mt8173-disp-wdma",
> +         .data = (void *)MTK_DISP_WDMA },
> +       { .compatible = "mediatek,mt2701-dpi",
> +         .data = (void *)MTK_DPI },
> +       { .compatible = "mediatek,mt8173-dpi",
> +         .data = (void *)MTK_DPI },
> +       { .compatible = "mediatek,mt8183-dpi",
> +         .data = (void *)MTK_DPI },
> +       { .compatible = "mediatek,mt2701-dsi",
> +         .data = (void *)MTK_DSI },
> +       { .compatible = "mediatek,mt8173-dsi",
> +         .data = (void *)MTK_DSI },
> +       { .compatible = "mediatek,mt8183-dsi",
> +         .data = (void *)MTK_DSI },
>         { }
>  };
>
> @@ -542,8 +542,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
>                     comp_type == MTK_DISP_OVL ||
>                     comp_type == MTK_DISP_OVL_2L ||
>                     comp_type == MTK_DISP_RDMA ||
> -                   comp_type == MTK_DSI ||
> -                   comp_type == MTK_DPI) {
> +                   comp_type == MTK_DPI ||
> +                   comp_type == MTK_DSI) {
>                         dev_info(dev, "Adding component match for %pOF\n",
>                                  node);
>                         drm_of_component_match_add(dev, &match, compare_of,
> --
> 2.18.0
>


From chunkuang.hu at kernel.org  Thu Aug 19 16:16:30 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Fri, 20 Aug 2021 07:16:30 +0800
Subject: [PATCH v8 11/13] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20210819022327.13040-12-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-12-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY__jThQhfAyvTxwF16fsS4CHmsuqY0GmdBBESNxhvpDzRg@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
>
> DSC is designed for real-time systems with real-time compression,
> transmission, decompression and display.
> The DSC standard is a specification of the algorithms used for
> compressing and decompressing image display streams, including
> the specification of the syntax and semantics of the compressed
> video bit stream.
>

Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 46 +++++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
>  2 files changed, 47 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 28bc42fd0b8a..929630a6d832 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -45,6 +45,12 @@
>  #define DITHER_LSB_ERR_SHIFT_G(x)              (((x) & 0x7) << 12)
>  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
>
> +#define DISP_REG_DSC_CON                       0x0000
> +#define DSC_EN                                 BIT(0)
> +#define DSC_DUAL_INOUT                         BIT(2)
> +#define DSC_BYPASS                             BIT(4)
> +#define DSC_UFOE_SEL                           BIT(16)
> +
>  #define DISP_REG_OD_EN                         0x0000
>  #define DISP_REG_OD_CFG                                0x0020
>  #define OD_RELAYMODE                           BIT(0)
> @@ -211,6 +217,35 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc,
>                               DISP_DITHERING, cmdq_pkt);
>  }
>
> +static void mtk_dsc_config(struct device *dev, unsigned int w,
> +                          unsigned int h, unsigned int vrefresh,
> +                          unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       /* dsc bypass mode */
> +       mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs,
> +                          DISP_REG_DSC_CON, DSC_BYPASS);
> +       mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs,
> +                          DISP_REG_DSC_CON, DSC_UFOE_SEL);
> +       mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs,
> +                          DISP_REG_DSC_CON, DSC_DUAL_INOUT);
> +}
> +
> +static void mtk_dsc_start(struct device *dev)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       writel_relaxed(DSC_EN, &priv->regs + DISP_REG_DSC_CON);
> +}
> +
> +static void mtk_dsc_stop(struct device *dev)
> +{
> +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> +
> +       writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
> +}
> +
>  static void mtk_od_config(struct device *dev, unsigned int w,
>                           unsigned int h, unsigned int vrefresh,
>                           unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> @@ -274,6 +309,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = {
>         .stop = mtk_dpi_stop,
>  };
>
> +static const struct mtk_ddp_comp_funcs ddp_dsc = {
> +       .clk_enable = mtk_ddp_clk_enable,
> +       .clk_disable = mtk_ddp_clk_disable,
> +       .config = mtk_dsc_config,
> +       .start = mtk_dsc_start,
> +       .stop = mtk_dsc_stop,
> +};
> +
>  static const struct mtk_ddp_comp_funcs ddp_dsi = {
>         .start = mtk_dsi_ddp_start,
>         .stop = mtk_dsi_ddp_stop,
> @@ -335,6 +378,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>         [MTK_DISP_CCORR] = "ccorr",
>         [MTK_DISP_COLOR] = "color",
>         [MTK_DISP_DITHER] = "dither",
> +       [MTK_DISP_DSC] = "dsc",
>         [MTK_DISP_GAMMA] = "gamma",
>         [MTK_DISP_MUTEX] = "mutex",
>         [MTK_DISP_OD] = "od",
> @@ -364,6 +408,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>         [DDP_COMPONENT_DITHER]  = { MTK_DISP_DITHER,    0, &ddp_dither },
>         [DDP_COMPONENT_DPI0]    = { MTK_DPI,            0, &ddp_dpi },
>         [DDP_COMPONENT_DPI1]    = { MTK_DPI,            1, &ddp_dpi },
> +       [DDP_COMPONENT_DSC0]    = { MTK_DISP_DSC,       0, &ddp_dsc },
> +       [DDP_COMPONENT_DSC1]    = { MTK_DISP_DSC,       1, &ddp_dsc },
>         [DDP_COMPONENT_DSI0]    = { MTK_DSI,            0, &ddp_dsi },
>         [DDP_COMPONENT_DSI1]    = { MTK_DSI,            1, &ddp_dsi },
>         [DDP_COMPONENT_DSI2]    = { MTK_DSI,            2, &ddp_dsi },
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index d317b944df66..560be6bc9d0e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
>         MTK_DISP_CCORR,
>         MTK_DISP_COLOR,
>         MTK_DISP_DITHER,
> +       MTK_DISP_DSC,
>         MTK_DISP_GAMMA,
>         MTK_DISP_MUTEX,
>         MTK_DISP_OD,
> --
> 2.18.0
>


From houlong.wei at mediatek.com  Thu Aug 19 16:20:13 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Fri, 20 Aug 2021 07:20:13 +0800
Subject: [PATCH] media: mtk-vpu: Fix a resource leak in the error
 handling path of 'mtk_vpu_probe()'
In-Reply-To: <3d4ba5d254044567653a006b18971658ec69560f.1629404378.git.christophe.jaillet@wanadoo.fr>
References: <3d4ba5d254044567653a006b18971658ec69560f.1629404378.git.christophe.jaillet@wanadoo.fr>
Message-ID: <6cb09965bce5bffe97fc00faecfffae9d3b38b3d.camel@mediatek.com>

On Fri, 2021-08-20 at 04:21 +0800, Christophe JAILLET wrote:
> A successful 'clk_prepare()' call should be balanced by a
> corresponding
> 'clk_unprepare()' call in the error handling path of the probe, as
> already
> done in the remove function.
> 
> Update the error handling path accordingly.
> 
> Fixes: 3003a180ef6b ("[media] VPU: mediatek: support Mediatek VPU")
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
> 
Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>

>  drivers/media/platform/mtk-vpu/mtk_vpu.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c
> b/drivers/media/platform/mtk-vpu/mtk_vpu.c
> index ec290dde59cf..7f1647da0ade 100644
> --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c
> +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c
> @@ -848,7 +848,8 @@ static int mtk_vpu_probe(struct platform_device
> *pdev)
>  	vpu->wdt.wq = create_singlethread_workqueue("vpu_wdt");
>  	if (!vpu->wdt.wq) {
>  		dev_err(dev, "initialize wdt workqueue failed\n");
> -		return -ENOMEM;
> +		ret = -ENOMEM;
> +		goto clk_unprepare;
>  	}
>  	INIT_WORK(&vpu->wdt.ws, vpu_wdt_reset_func);
>  	mutex_init(&vpu->vpu_mutex);
> @@ -942,6 +943,8 @@ static int mtk_vpu_probe(struct platform_device
> *pdev)
>  	vpu_clock_disable(vpu);
>  workqueue_destroy:
>  	destroy_workqueue(vpu->wdt.wq);
> +clk_unprepare:
> +	clk_unprepare(vpu->clk);
>  
>  	return ret;
>  }
> -- 
> 2.30.2
> 

From chunkuang.hu at kernel.org  Thu Aug 19 16:25:24 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Fri, 20 Aug 2021 07:25:24 +0800
Subject: [PATCH v3 02/15] dt-bindings: mediatek: add vdosys1 MERGE
 definition for mt8195
In-Reply-To: <20210818091847.8060-3-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-3-nancy.lin@mediatek.com>
Message-ID: <CAAOTY_-mJ0WHK0pXqASprrc7GW0R_ZTRmJ8Yo8pu9js-cQ5HAw@mail.gmail.com>

Hi, Nancy:

Nancy.Lin <nancy.lin at mediatek.com> ? 2021?8?18? ?? ??5:18???
>
> Add vdosys1 MERGE definition.
>
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  .../devicetree/bindings/display/mediatek/mediatek,merge.yaml    | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
> index 1a27b037086b..ba1e0c837988 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
> @@ -23,6 +23,8 @@ properties:
>            - const: mediatek,mt8173-disp-merge
>        - items:
>            - const: mediatek,mt8195-disp-merge
> +      - items:
> +          - const: mediatek,mt8195-vdo1-merge

I don't know why create a new merge for mt8195. Provide more
information about the difference of these two merge.

Regards,
Chun-Kuang.

>
>    reg:
>      maxItems: 1
> --
> 2.18.0
>


From linus.walleij at linaro.org  Thu Aug 19 16:25:39 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 20 Aug 2021 01:25:39 +0200
Subject: [PATCH 0/5] Arm VExpress/Juno motherboard bus clean-ups
In-Reply-To: <20210819184239.1192395-1-robh@kernel.org>
References: <20210819184239.1192395-1-robh@kernel.org>
Message-ID: <CACRpkdavBq5vfvVQMJm-R32VP-FEO6j6L5pUGGCWEFSiN=tUDw@mail.gmail.com>

On Thu, Aug 19, 2021 at 8:42 PM Rob Herring <robh at kernel.org> wrote:

> I noticed we once again have warnings on VExpress/Juno bus nodes as the
> simple-bus schema now expects child nodes to have a unit-address.
> Digging into this I noticed the arm,vexpress-juno.yaml schema is out of
> date and missing some properties (some of which are unused). I found the
> 'ranges' handling to be odd as well. This series fixes all those issues.

The series looks good to me. Thanks for fixing this up!
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From seanjc at google.com  Thu Aug 19 16:33:50 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Aug 2021 23:33:50 +0000
Subject: [PATCH 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <1540548616.19739.1629409956315.JavaMail.zimbra@efficios.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-5-seanjc@google.com>
 <1540548616.19739.1629409956315.JavaMail.zimbra@efficios.com>
Message-ID: <YR7qXvnI/AQM10gU@google.com>

On Thu, Aug 19, 2021, Mathieu Desnoyers wrote:
> ----- On Aug 17, 2021, at 8:12 PM, Sean Christopherson seanjc at google.com wrote:
> 
> > Add a test to verify an rseq's CPU ID is updated correctly if the task is
> > migrated while the kernel is handling KVM_RUN.  This is a regression test
> > for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
> > to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
> > without updating rseq, leading to a stale CPU ID and other badness.
> > 
> > Signed-off-by: Sean Christopherson <seanjc at google.com>
> > ---
> 
> [...]
> 
> > +	while (!done) {
> > +		vcpu_run(vm, VCPU_ID);
> > +		TEST_ASSERT(get_ucall(vm, VCPU_ID, NULL) == UCALL_SYNC,
> > +			    "Guest failed?");
> > +
> > +		cpu = sched_getcpu();
> > +		rseq_cpu = READ_ONCE(__rseq.cpu_id);
> > +
> > +		/*
> > +		 * Verify rseq's CPU matches sched's CPU, and that sched's CPU
> > +		 * is stable.  This doesn't handle the case where the task is
> > +		 * migrated between sched_getcpu() and reading rseq, and again
> > +		 * between reading rseq and sched_getcpu(), but in practice no
> > +		 * false positives have been observed, while on the other hand
> > +		 * blocking migration while this thread reads CPUs messes with
> > +		 * the timing and prevents hitting failures on a buggy kernel.
> > +		 */
> 
> I think you could get a stable cpu id between sched_getcpu and __rseq_abi.cpu_id
> if you add a pthread mutex to protect:
> 
> sched_getcpu and __rseq_abi.cpu_id  reads
> 
> vs
> 
> sched_setaffinity calls within the migration thread.
> 
> Thoughts ?

I tried that and couldn't reproduce the bug.  That's what I attempted to call out
in the blurb "blocking migration while this thread reads CPUs ... prevents hitting
failures on a buggy kernel".

I considered adding arbitrary delays around the mutex to try and hit the bug, but
I was worried that even if I got it "working" for this bug, the test would be too
tailored to this bug and potentially miss future regression.  Letting the two
threads run wild seemed like it would provide the best coverage, at the cost of
potentially causing to false failures.


From seanjc at google.com  Thu Aug 19 16:48:29 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 19 Aug 2021 23:48:29 +0000
Subject: [PATCH 1/5] KVM: rseq: Update rseq when processing NOTIFY_RESUME
 on xfer to KVM guest
In-Reply-To: <1673583543.19718.1629409152244.JavaMail.zimbra@efficios.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-2-seanjc@google.com>
 <1673583543.19718.1629409152244.JavaMail.zimbra@efficios.com>
Message-ID: <YR7tzZ98XC6OV2vu@google.com>

On Thu, Aug 19, 2021, Mathieu Desnoyers wrote:
> ----- On Aug 17, 2021, at 8:12 PM, Sean Christopherson seanjc at google.com wrote:
> > @@ -250,7 +250,7 @@ static int rseq_ip_fixup(struct pt_regs *regs)
> > 	 * If not nested over a rseq critical section, restart is useless.
> > 	 * Clear the rseq_cs pointer and return.
> > 	 */
> > -	if (!in_rseq_cs(ip, &rseq_cs))
> > +	if (!regs || !in_rseq_cs(ip, &rseq_cs))
> 
> I think clearing the thread's rseq_cs unconditionally here when regs is NULL
> is not the behavior we want when this is called from xfer_to_guest_mode_work.
> 
> If we have a scenario where userspace ends up calling this ioctl(KVM_RUN)
> from within a rseq c.s., we really want a CONFIG_DEBUG_RSEQ=y kernel to
> kill this application in the rseq_syscall handler when exiting back to usermode
> when the ioctl eventually returns.
> 
> However, clearing the thread's rseq_cs will prevent this from happening.
> 
> So I would favor an approach where we simply do:
> 
> if (!regs)
>      return 0;
> 
> Immediately at the beginning of rseq_ip_fixup, before getting the instruction
> pointer, so effectively skip all side-effects of the ip fixup code. Indeed, it
> is not relevant to do any fixup here, because it is nested in a ioctl system
> call.
> 
> Effectively, this would preserve the SIGSEGV behavior when this ioctl is
> erroneously called by user-space from a rseq critical section.

Ha, that's effectively what I implemented first, but I changed it because of the
comment in clear_rseq_cs() that says:

  The rseq_cs field is set to NULL on preemption or signal delivery ... as well
  as well as on top of code outside of the rseq assembly block.

Which makes it sound like something might rely on clearing rseq_cs?

Ah, or is it the case that rseq_cs is non-NULL if and only if userspace is in an
rseq critical section, and because syscalls in critical sections are illegal, by
definition clearing rseq_cs is a nop unless userspace is misbehaving.

If that's true, what about explicitly checking that at NOTIFY_RESUME?  Or is it
not worth the extra code to detect an error that will likely be caught anyways?

diff --git a/kernel/rseq.c b/kernel/rseq.c
index 35f7bd0fced0..28b8342290b0 100644
--- a/kernel/rseq.c
+++ b/kernel/rseq.c
@@ -282,6 +282,13 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)

        if (unlikely(t->flags & PF_EXITING))
                return;
+       if (!regs) {
+#ifdef CONFIG_DEBUG_RSEQ
+               if (t->rseq && rseq_get_rseq_cs(t, &rseq_cs))
+                       goto error;
+#endif
+               return;
+       }
        ret = rseq_ip_fixup(regs);
        if (unlikely(ret < 0))
                goto error;

> Thanks for looking into this !
> 
> Mathieu
> 
> > 		return clear_rseq_cs(t);
> > 	ret = rseq_need_restart(t, rseq_cs.flags);
> > 	if (ret <= 0)
> > --
> > 2.33.0.rc1.237.g0d66db33f3-goog
> 
> -- 
> Mathieu Desnoyers
> EfficiOS Inc.
> http://www.efficios.com


From tharvey at gateworks.com  Thu Aug 19 16:59:15 2021
From: tharvey at gateworks.com (Tim Harvey)
Date: Thu, 19 Aug 2021 16:59:15 -0700
Subject: arm32 insecure W+X mapping
In-Reply-To: <20210819212819.GM22278@shell.armlinux.org.uk>
References: <CAJ+vNU0PaPNHbJc5RXgrRYJw2aWowrGVMOrU1=hKhsCTXAB=DA@mail.gmail.com>
 <20210819212819.GM22278@shell.armlinux.org.uk>
Message-ID: <CAJ+vNU05L1Fyvy1R6_HwpLeo92LSJhDY4BCr-0aqM7rYgh6TVQ@mail.gmail.com>

On Thu, Aug 19, 2021 at 2:28 PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:
>
> On Thu, Aug 19, 2021 at 10:19:46AM -0700, Tim Harvey wrote:
> > Greetings,
> >
> > Since commit a8e53c151fe7 "(ARM: 8737/1: mm: dump: add checking for
> > writable and executable)" I've been seeing the following appear on my
> > arm32 kernel:
> >
> > arm/mm: Found insecure W+X mapping at address 0xf087d000
> > ...
> > Checked W+X mappings: FAILED, 1 W+X pages found
> >
> > As I haven't seen others report this I assume it's something unique to
> > my kernel configuration. How do I debug what is causing the insecure
> > page?
>
> If you check /proc/vmallocinfo, it should tell you the physical
> address that was mapped there, and the function that created the
> mapping. That should give enough clues to track it down.
>

Russell,

Thanks for the tip!

# dmesg | grep insecure
[   13.219582] arm/mm: Found insecure W+X mapping at address 0xf087d000
# cat /proc/vmallocinfo | grep 0xf0
0x5f3045dd-0xf0020e05   20480 imx6_pm_get_base+0x64/0x98 phys=0x020e0000 ioremap
0xf0020e05-0x6e748217    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x127639d7-0x334ee291    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap

So this is saying its dma-coherent mapped from dma_common_continguous_remap?

# cat /proc/vmallocinfo
0x572091e4-0x27690de5   20480 of_iomap+0x44/0x68 phys=0x020d8000 ioremap
0x27690de5-0x35897f01    8192 of_iomap+0x44/0x68 phys=0x00a01000 ioremap
0xe3186ca4-0x0f1ef5e3   20480 of_iomap+0x44/0x68 phys=0x020dc000 ioremap
0x0f1ef5e3-0x5ece7ccc    8192 l2x0_of_init+0x78/0x26c phys=0x00a02000 ioremap
0xb5c85079-0xc2ca2734   20480 of_iomap+0x44/0x68 phys=0x020c4000 ioremap
0xc2ca2734-0xaf3c42de    8192 of_iomap+0x44/0x68 phys=0x020c8000 ioremap
0x28e036be-0xd5974946   20480 of_iomap+0x44/0x68 phys=0x020c4000 ioremap
0xeae42964-0xc4e615a6   20480 of_iomap+0x44/0x68 phys=0x02098000 ioremap
0x6a6bab5f-0x3ecf3e8c    8192 bpf_prog_alloc_no_stats+0x2c/0x118 pages=1 vmalloc
0x3ecf3e8c-0xbb5cf07d  266240 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xbb5cf07d-0x1a6cd05a    8192 gen_pool_add_owner+0x34/0x94 pages=1 vmalloc
0x1a6cd05a-0xcafd679a    8192 of_syscon_register+0xb8/0x2a0
phys=0x020c8000 ioremap
0xcafd679a-0xab606572    8192 __devm_ioremap+0x94/0xa4 phys=0x020c9000 ioremap
0xab606572-0xd42260ec    8192 __devm_ioremap+0x94/0xa4 phys=0x020ca000 ioremap
0xd42260ec-0xcbe84677    8192 gen_pool_add_owner+0x34/0x94 pages=1 vmalloc
0xcbe84677-0x235c7c16   20480 of_iomap+0x44/0x68 phys=0x021b0000 ioremap
0x235c7c16-0xb235d3f3    8192 imx6_pm_common_init+0x118/0x36c
phys=0x00900000 ioremap
0x47e7e130-0x808ca2d4  266240 __devm_ioremap+0x50/0xa4 phys=0x00900000 ioremap
0x808ca2d4-0xfccba85b    8192 imx6_pm_get_base+0x64/0x98 phys=0x00a02000 ioremap
0x800f4671-0xc7775acd   20480 imx6_pm_get_base+0x64/0x98 phys=0x021b0000 ioremap
0xc7775acd-0xa724d9e0    8192 of_syscon_register+0xb8/0x2a0
phys=0x020e0000 ioremap
0xb762f02e-0xed6991ca   20480 imx6_pm_get_base+0x64/0x98 phys=0x020d8000 ioremap
0xed6991ca-0xdbb588fa    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x5f3045dd-0xf0020e05   20480 imx6_pm_get_base+0x64/0x98 phys=0x020e0000 ioremap
0xf0020e05-0x6e748217    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x0b51e410-0x3d898417   20480 imx6_pm_get_base+0x64/0x98 phys=0x020dc000 ioremap
0x3d898417-0x86992438    8192 __devm_ioremap+0x94/0xa4 phys=0x02600000 ioremap
0x6464407c-0x60718db5   20480 __devm_ioremap+0x94/0xa4 phys=0x020e0000 ioremap
0x4c7be824-0xfe1fc1f2   20480 __devm_ioremap+0x94/0xa4 phys=0x0209c000 ioremap
0xfe1fc1f2-0x46954edf    8192 __devm_ioremap+0x94/0xa4 phys=0x02608000 ioremap
0x53446305-0x435a58b4   20480 __devm_ioremap+0x94/0xa4 phys=0x020a0000 ioremap
0x435a58b4-0x2e1fc59d    8192 __devm_ioremap+0x94/0xa4 phys=0x02630000 ioremap
0x3f2c2f34-0x01a2f43c   20480 __devm_ioremap+0x94/0xa4 phys=0x020a4000 ioremap
0x01a2f43c-0x6b20a97a    8192 __devm_ioremap+0x94/0xa4 phys=0x02638000 ioremap
0x6fd6457c-0xe0eb3463   20480 __devm_ioremap+0x94/0xa4 phys=0x020a8000 ioremap
0xe0eb3463-0xec4965e5    8192 __devm_ioremap+0x94/0xa4 phys=0x02620000 ioremap
0x5c03cdf7-0x3b1b3493   20480 __devm_ioremap+0x94/0xa4 phys=0x020ac000 ioremap
0x3b1b3493-0xad9aee67    8192 __devm_ioremap+0x94/0xa4 phys=0x02668000 ioremap
0x92feb1f5-0x7414f542   20480 __devm_ioremap+0x94/0xa4 phys=0x020b0000 ioremap
0x7414f542-0x7a40d77f    8192 __devm_ioremap+0x94/0xa4 phys=0x02640000 ioremap
0x8ee37216-0xbe006eb2   20480 __devm_ioremap+0x94/0xa4 phys=0x020b4000 ioremap
0x29a6ecde-0x80a7a60b   12288 __devm_ioremap+0x94/0xa4 phys=0x00110000 ioremap
0x80a7a60b-0x3db02e14    8192 __devm_ioremap+0x94/0xa4 phys=0x02648000 ioremap
0x60036855-0x1e6802e0   20480 __devm_ioremap+0x94/0xa4 phys=0x021a0000 ioremap
0x1e6802e0-0x62fd3e57    8192 __devm_ioremap+0x94/0xa4 phys=0x02658000 ioremap
0xabcb6908-0xa070b2ec   20480 __devm_ioremap+0x94/0xa4 phys=0x021a4000 ioremap
0xa070b2ec-0xe713ec73    8192 __devm_ioremap+0x94/0xa4 phys=0x02780000 ioremap
0x1d8444e1-0xcac4726c   20480 __devm_ioremap+0x94/0xa4 phys=0x021a8000 ioremap
0xcac4726c-0x8025cc0f    8192 __devm_ioremap+0x94/0xa4 phys=0x02660000 ioremap
0x1ae47ba3-0xf8c7f1ca   20480 __devm_ioremap+0x94/0xa4 phys=0x021d8000 ioremap
0xf8c7f1ca-0x32e09fa4    8192 __devm_ioremap+0x94/0xa4 phys=0x02740000 ioremap
0x4d10befe-0x60b4c1e9   20480 __devm_ioremap+0x94/0xa4 phys=0x01ffc000 ioremap
0x60b4c1e9-0xb3a54244    8192 __devm_ioremap+0x94/0xa4 phys=0x02650000 ioremap
0xe04d1c20-0x97be33d0   20480 __devm_ioremap+0x94/0xa4 phys=0x020ec000 ioremap
0x97be33d0-0xc1afe24c    8192 __devm_ioremap+0x94/0xa4 phys=0x02a00000 ioremap
0xac1caf35-0x7ceb30f1   20480 of_syscon_register+0xb8/0x2a0
phys=0x021bc000 ioremap
0x7ceb30f1-0x245e06af    8192 __devm_ioremap+0x94/0xa4 phys=0x02a08000 ioremap
0x6c5425e7-0x84bc25cc   20480 __devm_ioremap+0x94/0xa4 phys=0x020dc000 ioremap
0x84bc25cc-0x595056c5    8192 __devm_ioremap+0x94/0xa4 phys=0x02a30000 ioremap
0x074d8ed7-0x2e4d1a53   20480 __devm_ioremap+0x94/0xa4 phys=0x02020000 ioremap
0x2e4d1a53-0x95ed192f    8192 __devm_ioremap+0x94/0xa4 phys=0x02a38000 ioremap
0x19e0356d-0x45e14fed   20480 __devm_ioremap+0x94/0xa4 phys=0x021e8000 ioremap
0x45e14fed-0xe690f152    8192 __devm_ioremap+0x94/0xa4 phys=0x02a20000 ioremap
0x991fa501-0x9fdabf5a   20480 __devm_ioremap+0x94/0xa4 phys=0x021f4000 ioremap
0x9fdabf5a-0x3e67dae9    8192 __devm_ioremap+0x94/0xa4 phys=0x02a68000 ioremap
0x82e937d0-0x0811797e   40960 __devm_ioremap+0x94/0xa4 phys=0x00120000 ioremap
0x0811797e-0x923f8a88    8192 __devm_ioremap+0x94/0xa4 phys=0x02a40000 ioremap
0x923f8a88-0x206017e5   20480 __devm_ioremap+0x94/0xa4 phys=0x00130000 ioremap
0x206017e5-0x6c990a7b    8192 __devm_ioremap+0x94/0xa4 phys=0x02a48000 ioremap
0x99673e2c-0x2cac9053   20480 __devm_ioremap+0x94/0xa4 phys=0x00134000 ioremap
0x2cac9053-0x85ae7df8    8192 __devm_ioremap+0x94/0xa4 phys=0x02a58000 ioremap
0x85ae7df8-0x4405ccb4    8192 __devm_ioremap+0x94/0xa4 phys=0x02b80000 ioremap
0x4405ccb4-0xae8efb1a    8192 __devm_ioremap+0x94/0xa4 phys=0x02a60000 ioremap
0x126bbd24-0x2249ff6f  528384 devm_pci_remap_cfgspace+0x3c/0x74
phys=0x01f00000 ioremap
0x2249ff6f-0x8c2e304c  135168 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x8c2e304c-0x0bf3a28c    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x0bf3a28c-0x96e17d3f   20480 __devm_ioremap+0x94/0xa4 phys=0x02204000 ioremap
0x96e17d3f-0xa4daba8c  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xa4daba8c-0xe6185530    8192 __devm_ioremap+0x94/0xa4 phys=0x02b40000 ioremap
0xe6185530-0x821c3b4a    8192 __devm_ioremap+0x94/0xa4 phys=0x02a50000 ioremap
0xbd3e3c5d-0x597081d3  135168 __devm_ioremap+0x94/0xa4 phys=0x02700000 ioremap
0x0f8ddd13-0x32e4fd76   12288 __devm_ioremap+0x94/0xa4 phys=0x00112000 ioremap
0x32e4fd76-0x811b112c    8192 __pci_enable_msix_range+0x1b4/0x50c
phys=0x01420000 ioremap
0xce8aec4a-0xb2dd309c   69632 __devm_ioremap+0x94/0xa4 phys=0x02760000 ioremap
0xb2dd309c-0x5ff80254   81920 pcpu_create_chunk+0x14c/0x290 pages=19 vmalloc
0x6325b825-0xd6880a57    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
0xd6880a57-0x01fdf853  135168 __devm_ioremap+0x94/0xa4 phys=0x02b00000 ioremap
0xfbfae5e4-0x34f66182   12288 __devm_ioremap+0x94/0xa4 phys=0x00114000 ioremap
0x34f66182-0x9759721e    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
0xff9a433f-0x6ffcb3fc   69632 __devm_ioremap+0x94/0xa4 phys=0x02b60000 ioremap
0x6ffcb3fc-0x925370c6 4153344 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x89e10860-0x935fedfd   20480 __devm_ioremap+0x94/0xa4 phys=0x02200000 ioremap
0x935fedfd-0xb3e1eed1   98304 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xb3e1eed1-0xd19ae2f1   36864 iscsi_target_init_module+0xb4/0x234
pages=8 vmalloc
0xd19ae2f1-0x4ef92f29   20480 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x0e67a0eb-0x32add077   20480 __devm_ioremap+0x94/0xa4 phys=0x0200c000 ioremap
0x32add077-0xf2ae7966    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x24b26351-0x10c489ec   20480 __devm_ioremap+0x94/0xa4 phys=0x02188000 ioremap
0x10c489ec-0x99550a81  135168 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x99550a81-0xb8546101   36864 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xb757667d-0x00d14870   20480 __devm_ioremap+0x94/0xa4 phys=0x021e4000 ioremap
0x00d14870-0x4997051a    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xcd1bbc96-0x5470c56e   20480 __devm_ioremap+0x94/0xa4 phys=0x020c0000 ioremap
0x5470c56e-0x5041fe43    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x27c17eec-0x5f300c54   20480 __devm_ioremap+0x94/0xa4 phys=0x02198000 ioremap
0x5f300c54-0x779e324f    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
0x71eda903-0x08c271b0  135168 igb_probe+0x150/0x10a4 phys=0x01400000 ioremap
0x08c271b0-0xaad09678    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x20320ae4-0x995de6c0   20480 __devm_ioremap+0x94/0xa4 phys=0x02034000 ioremap
0x995de6c0-0x53fe07bc    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x66a2a7f0-0x144dcde1   20480 __devm_ioremap+0x94/0xa4 phys=0x02028000 ioremap
0x144dcde1-0x28fcbfb5    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xd4d631e6-0x89b9dbd5   20480 __devm_ioremap+0x94/0xa4 phys=0x0202c000 ioremap
0x89b9dbd5-0xba573900   16384 n_tty_open+0x10/0x9c pages=3 vmalloc
0xf1af7427-0x2dd3f3b0  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x7ea79487-0xb5aa9a4a  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xb5aa9a4a-0x38706b86 1294336 zstd_comp_init+0x58/0xb0 pages=315 vmalloc
0x38706b86-0x2073eebb  163840 zstd_decomp_init+0x14/0x54 pages=39 vmalloc
0x2073eebb-0x0e3cf5f0  274432 deflate_comp_init+0x20/0x90 pages=66 vmalloc
0x0e3cf5f0-0x03c153c7   49152 deflate_decomp_init+0x14/0x58 pages=11 vmalloc
0x32a3b715-0x45627fc0  249856 __devm_ioremap+0x94/0xa4 phys=0x02040000 ioremap
0x45627fc0-0x8420dc4c  212992 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x8420dc4c-0x0268f3a7  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x127639d7-0x334ee291    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap
0x9569c0e1-0x413f89f0 2097152 pci_reserve_io+0x0/0x30 ioremap
0x1fa52fb4-0xe4568750  311296 pcpu_get_vm_areas+0x0/0x10c0 vmalloc
0xe4568750-0x2633c5e5  311296 pcpu_get_vm_areas+0x0/0x10c0 vmalloc
0x8276ef58-0x572091e4   16384 unpurged vm_area
0xd5974946-0xe417a989    8192 unpurged vm_area
0xc4e615a6-0x6a6bab5f    8192 unpurged vm_area
0x60718db5-0x4c7be824 15609856 unpurged vm_area
0x821c3b4a-0xbd3e3c5d   73728 unpurged vm_area
0x597081d3-0x0f8ddd13   36864 unpurged vm_area
0x5ff80254-0x6325b825   36864 unpurged vm_area
0x01fdf853-0xfbfae5e4   36864 unpurged vm_area
0x925370c6-0x208e0e7e  442368 unpurged vm_area
0xe1ca9db2-0xf1af7427  249856 unpurged vm_area
0x2dd3f3b0-0x7ea79487   36864 unpurged vm_area

Thanks,

Tim


From linux at armlinux.org.uk  Thu Aug 19 17:16:46 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 20 Aug 2021 01:16:46 +0100
Subject: arm32 insecure W+X mapping
In-Reply-To: <CAJ+vNU05L1Fyvy1R6_HwpLeo92LSJhDY4BCr-0aqM7rYgh6TVQ@mail.gmail.com>
References: <CAJ+vNU0PaPNHbJc5RXgrRYJw2aWowrGVMOrU1=hKhsCTXAB=DA@mail.gmail.com>
 <20210819212819.GM22278@shell.armlinux.org.uk>
 <CAJ+vNU05L1Fyvy1R6_HwpLeo92LSJhDY4BCr-0aqM7rYgh6TVQ@mail.gmail.com>
Message-ID: <20210820001646.GN22278@shell.armlinux.org.uk>

On Thu, Aug 19, 2021 at 04:59:15PM -0700, Tim Harvey wrote:
> On Thu, Aug 19, 2021 at 2:28 PM Russell King (Oracle)
> <linux at armlinux.org.uk> wrote:
> >
> > On Thu, Aug 19, 2021 at 10:19:46AM -0700, Tim Harvey wrote:
> > > Greetings,
> > >
> > > Since commit a8e53c151fe7 "(ARM: 8737/1: mm: dump: add checking for
> > > writable and executable)" I've been seeing the following appear on my
> > > arm32 kernel:
> > >
> > > arm/mm: Found insecure W+X mapping at address 0xf087d000
> > > ...
> > > Checked W+X mappings: FAILED, 1 W+X pages found
> > >
> > > As I haven't seen others report this I assume it's something unique to
> > > my kernel configuration. How do I debug what is causing the insecure
> > > page?
> >
> > If you check /proc/vmallocinfo, it should tell you the physical
> > address that was mapped there, and the function that created the
> > mapping. That should give enough clues to track it down.
> >
> 
> Russell,
> 
> Thanks for the tip!
> 
> # dmesg | grep insecure
> [   13.219582] arm/mm: Found insecure W+X mapping at address 0xf087d000
> # cat /proc/vmallocinfo | grep 0xf0
> 0x5f3045dd-0xf0020e05   20480 imx6_pm_get_base+0x64/0x98 phys=0x020e0000 ioremap
> 0xf0020e05-0x6e748217    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x127639d7-0x334ee291    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap

Oh... the kernel's %p pointer munging (for security reasons) is
affecting your ability to debug your problem. Assuming this is a
recent kernel, you can disable this by passing "no_hash_pointers"
on the kernel command line. You should then see real addresses (and
a big fat message at boot time about it.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From samuel at sholland.org  Thu Aug 19 17:55:10 2021
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 19 Aug 2021 19:55:10 -0500
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <20210802062212.73220-11-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-11-icenowy@sipeed.com>
Message-ID: <99a74950-fdc0-ecfe-e5f0-ba4a7d8751f0@sholland.org>

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 has clock controls in PRCM, like other new Allwinner
> SoCs.
> 
> Add support for them.
> 
> This driver is added before the main CCU because PLLs are controlled by
> R-CCU on R329.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig                  |   5 +
>  drivers/clk/sunxi-ng/Makefile                 |   1 +
>  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 ++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
>  include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
>  include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 ++
>  6 files changed, 470 insertions(+)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
>  create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
> 
> diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> index cd46d8853876..e49b2c2fa5b7 100644
> --- a/drivers/clk/sunxi-ng/Kconfig
> +++ b/drivers/clk/sunxi-ng/Kconfig
> @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
>  	default ARM64 && ARCH_SUNXI
>  	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
>  
> +config SUN50I_R329_R_CCU
> +	bool "Support for the Allwinner R329 PRCM CCU"
> +	default ARM64 && ARCH_SUNXI
> +	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> +
>  config SUN4I_A10_CCU
>  	bool "Support for the Allwinner A10/A20 CCU"
>  	default MACH_SUN4I
> diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> index 96c324306d97..db338a2188fd 100644
> --- a/drivers/clk/sunxi-ng/Makefile
> +++ b/drivers/clk/sunxi-ng/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
>  obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
>  obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
>  obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
> +obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
>  obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
>  obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
>  obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> new file mode 100644
> index 000000000000..5413a701cb57
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> @@ -0,0 +1,374 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 Sipeed
> + * Based on the H616 CCU driver, which is:
> + *   Copyright (c) 2020 Arm Ltd.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +
> +#include "ccu_common.h"
> +#include "ccu_reset.h"
> +
> +#include "ccu_div.h"
> +#include "ccu_gate.h"
> +#include "ccu_mp.h"
> +#include "ccu_mult.h"
> +#include "ccu_nk.h"
> +#include "ccu_nkm.h"
> +#include "ccu_nkmp.h"
> +#include "ccu_nm.h"
> +
> +#include "ccu-sun50i-r329-r.h"
> +
> +/*
> + * The M factor is present in the register's description, but not in the
> + * frequency formula, and it's documented as "The bit is only for
> + * testing", so it's not modelled and then force to 0.
> + */
> +#define SUN50I_R329_PLL_CPUX_REG	0x1000
> +static struct ccu_mult pll_cpux_clk = {
> +	.enable		= BIT(31),
> +	.lock		= BIT(28),
> +	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +	.common		= {
> +		.reg		= 0x1000,
> +		.hw.init	= CLK_HW_INIT("pll-cpux", "osc24M",
> +					      &ccu_mult_ops,
> +					      CLK_SET_RATE_UNGATE),
> +	},
> +};
> +
> +#define SUN50I_R329_PLL_PERIPH_REG	0x1010
> +static struct ccu_nm pll_periph_base_clk = {
> +	.enable		= BIT(31),
> +	.lock		= BIT(28),
> +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
> +	.common		= {
> +		.reg		= 0x1010,
> +		.hw.init	= CLK_HW_INIT("pll-periph-base", "osc24M",
> +					      &ccu_nm_ops,
> +					      CLK_SET_RATE_UNGATE),
> +	},
> +};
> +
> +static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-base",
> +		   0x1010, 16, 3, 0);
> +static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m", "pll-periph-base",
> +		   0x1010, 20, 3, 0);

M as abbreviation for "mega" should be capitalized.

> +static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
> +			   &pll_periph_2x_clk.common.hw, 2, 1, 0);
> +
> +#define SUN50I_R329_PLL_AUDIO0_REG	0x1020
> +static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
> +	{ .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64 },
> +};
> +
> +static struct ccu_nm pll_audio0_clk = {
> +	.enable		= BIT(31),
> +	.lock		= BIT(28),
> +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +	.m		= _SUNXI_CCU_DIV(1, 1),
> +	.sdm		= _SUNXI_CCU_SDM(pll_audio0_sdm_table,
> +					 BIT(24), 0x1120, BIT(31)),
> +	.common		= {
> +		.features	= CCU_FEATURE_SIGMA_DELTA_MOD,
> +		.reg		= 0x1020,
> +		.hw.init	= CLK_HW_INIT("pll-audio0", "osc24M",
> +					      &ccu_nm_ops,
> +					      CLK_SET_RATE_UNGATE),
> +	},
> +};
> +
> +static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-audio0",
> +		   0x1020, 16, 3, 0);
> +static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-audio0",
> +		   0x1020, 20, 3, 0);
> +
> +/*
> + * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
> + * BSP driver always has M0 = 1 and M1 = 2 (this is also the
> + * reset value in the register).
> + *
> + * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
> + */
> +#define SUN50I_R329_PLL_AUDIO1_REG	0x1030
> +static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
> +	{ .rate = 22579200, .pattern = 0xc001288d, .m = 12, .n = 22 },
> +	{ .rate = 24576000, .pattern = 0xc00126e9, .m = 12, .n = 24 },
> +	{ .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 },
> +	{ .rate = 98304000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
> +};
> +static struct ccu_nm pll_audio1_4x_clk = {
> +	.enable		= BIT(31),
> +	.lock		= BIT(28),
> +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> +	.m		= _SUNXI_CCU_DIV(16, 6),
> +	.fixed_post_div	= 2,
> +	.sdm		= _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
> +					 BIT(24), 0x1130, BIT(31)),
> +	.common		= {
> +		.features	= CCU_FEATURE_FIXED_POSTDIV |
> +				  CCU_FEATURE_SIGMA_DELTA_MOD,
> +		.reg		= 0x1030,
> +		.hw.init	= CLK_HW_INIT("pll-audio1-4x", "osc24M",
> +					      &ccu_nm_ops,
> +					      CLK_SET_RATE_UNGATE),
> +	},
> +};
> +
> +static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
> +			   &pll_audio1_4x_clk.common.hw, 2, 1,
> +			   CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
> +			   &pll_audio1_4x_clk.common.hw, 4, 1,
> +			   CLK_SET_RATE_PARENT);
> +
> +static const char * const r_bus_parents[] = { "osc24M", "osc32k", "iosc",
> +					      "pll-periph-2x",
> +					      "pll-audio0-div2" };
> +static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents, 0x000,
> +			     0, 5,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents, 0x00c,
> +			     0, 5,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents, 0x010,
> +			     0, 5,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);

These are numbered 0 and 1 in the manual and in the BSP. Why number them
differently here?

> +
> +static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
> +		      0x0ec, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c, BIT(0), 0);

BSP has R_TIMER at 0x11c and R_TWD at 0x12c.

> +
> +static const char * const r_pwm_parents[] = { "osc24M", "osc32k", "iosc" };
> +static SUNXI_CCU_MUX_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents, 0x130,
> +			       24, 3,	/* mux */
> +			       BIT(31),	/* gate */
> +			       0);
> +
> +static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c, BIT(0), 0);
> +
> +static const char * const r_audio_parents[] = { "pll-audio0-div5", "pll-audio0-div2",
> +						"pll-audio1-1x", "pll-audio1-4x" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc", r_audio_parents, 0x140,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */

I don't think it matters much, but the audio and IR muxes are documented as
being two bits wide.

> +				  BIT(31),	/* gate */
> +				  0);
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac", r_audio_parents, 0x144,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
> +		      0x14c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic", r_audio_parents, 0x150,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc", "r-apb1",
> +		      0x16c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s", r_audio_parents, 0x170,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
> +				  r_audio_parents, 0x174,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);

The BSP claims there is an R_I2S1 module clock at 0x178. Can you check if that
exists? And the corresponding gate/reset bits in 0x17c?

> +static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart", "r-apb2", 0x18c, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_i2c_clk, "r-bus-i2c", "r-apb2", 0x19c, BIT(0), 0);

R_PPU is at 0x1ac, and R_DSP is at 0x1bc.

> +
> +static const char * const r_ir_parents[] = { "osc32k", "osc24M" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents, 0x1c0,
> +				  0, 5,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
> +		      0x1dc, BIT(0), 0);
> +static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-apb1",
> +		      0x1ec, BIT(0), 0);

R_DSP_SRAM is at 0x1fc.

> +static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
> +		      0x20c, BIT(0), CLK_IS_CRITICAL);

Is this a workaround for the clock consumer missing from the RTC driver?

Also, there is a "PSARM" clock at 0x210 and its gate at 0x21c. I think this may
refer to the NPU from ARM China?

Finally, there is a CPUCFG gate at 0x22c. I'm not sure which CPUCFG this refers to.

> +
> +static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
> +	&pll_cpux_clk.common,
> +	&pll_periph_base_clk.common,
> +	&pll_periph_2x_clk.common,
> +	&pll_periph_800m_clk.common,
> +	&pll_audio0_clk.common,
> +	&pll_audio0_div2_clk.common,
> +	&pll_audio0_div5_clk.common,
> +	&pll_audio1_4x_clk.common,
> +	&r_ahb_clk.common,
> +	&r_apb1_clk.common,
> +	&r_apb2_clk.common,
> +	&r_bus_gpadc_clk.common,
> +	&r_bus_ths_clk.common,
> +	&r_bus_dma_clk.common,
> +	&r_pwm_clk.common,
> +	&r_bus_pwm_clk.common,
> +	&r_codec_adc_clk.common,
> +	&r_codec_dac_clk.common,
> +	&r_bus_codec_clk.common,
> +	&r_dmic_clk.common,
> +	&r_bus_dmic_clk.common,
> +	&r_bus_lradc_clk.common,
> +	&r_i2s_clk.common,
> +	&r_i2s_asrc_clk.common,
> +	&r_bus_i2s_clk.common,
> +	&r_bus_uart_clk.common,
> +	&r_bus_i2c_clk.common,
> +	&r_ir_clk.common,
> +	&r_bus_ir_clk.common,
> +	&r_bus_msgbox_clk.common,
> +	&r_bus_spinlock_clk.common,
> +	&r_bus_rtc_clk.common,
> +};
> +
> +static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
> +	.hws	= {
> +		[CLK_PLL_CPUX]		= &pll_cpux_clk.common.hw,
> +		[CLK_PLL_PERIPH_BASE]	= &pll_periph_base_clk.common.hw,
> +		[CLK_PLL_PERIPH_2X]	= &pll_periph_2x_clk.common.hw,
> +		[CLK_PLL_PERIPH_800M]	= &pll_periph_800m_clk.common.hw,
> +		[CLK_PLL_PERIPH]	= &pll_periph_clk.hw,
> +		[CLK_PLL_AUDIO0]	= &pll_audio0_clk.common.hw,
> +		[CLK_PLL_AUDIO0_DIV2]	= &pll_audio0_div2_clk.common.hw,
> +		[CLK_PLL_AUDIO0_DIV5]	= &pll_audio0_div5_clk.common.hw,
> +		[CLK_PLL_AUDIO1_4X]	= &pll_audio1_4x_clk.common.hw,
> +		[CLK_PLL_AUDIO1_2X]	= &pll_audio1_2x_clk.hw,
> +		[CLK_PLL_AUDIO1]	= &pll_audio1_clk.hw,
> +		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
> +		[CLK_R_APB1]		= &r_apb1_clk.common.hw,
> +		[CLK_R_APB2]		= &r_apb2_clk.common.hw,
> +		[CLK_R_BUS_GPADC]	= &r_bus_gpadc_clk.common.hw,
> +		[CLK_R_BUS_THS]		= &r_bus_ths_clk.common.hw,
> +		[CLK_R_BUS_DMA]		= &r_bus_dma_clk.common.hw,
> +		[CLK_R_PWM]		= &r_pwm_clk.common.hw,
> +		[CLK_R_BUS_PWM]		= &r_bus_pwm_clk.common.hw,
> +		[CLK_R_CODEC_ADC]	= &r_codec_adc_clk.common.hw,
> +		[CLK_R_CODEC_DAC]	= &r_codec_dac_clk.common.hw,
> +		[CLK_R_BUS_CODEC]	= &r_bus_codec_clk.common.hw,
> +		[CLK_R_DMIC]		= &r_dmic_clk.common.hw,
> +		[CLK_R_BUS_DMIC]	= &r_bus_dmic_clk.common.hw,
> +		[CLK_R_BUS_LRADC]	= &r_bus_lradc_clk.common.hw,
> +		[CLK_R_I2S]		= &r_i2s_clk.common.hw,
> +		[CLK_R_I2S_ASRC]	= &r_i2s_asrc_clk.common.hw,
> +		[CLK_R_BUS_I2S]		= &r_bus_i2s_clk.common.hw,
> +		[CLK_R_BUS_UART]	= &r_bus_uart_clk.common.hw,
> +		[CLK_R_BUS_I2C]		= &r_bus_i2c_clk.common.hw,
> +		[CLK_R_IR]		= &r_ir_clk.common.hw,
> +		[CLK_R_BUS_IR]		= &r_bus_ir_clk.common.hw,
> +		[CLK_R_BUS_MSGBOX]	= &r_bus_msgbox_clk.common.hw,
> +		[CLK_R_BUS_SPINLOCK]	= &r_bus_spinlock_clk.common.hw,
> +		[CLK_R_BUS_RTC]		= &r_bus_rtc_clk.common.hw,
> +	},
> +	.num = CLK_NUMBER,
> +};
> +
> +static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
> +	[RST_R_BUS_GPADC]	= { 0x0ec, BIT(16) },
> +	[RST_R_BUS_THS]		= { 0x0fc, BIT(16) },
> +	[RST_R_BUS_DMA]		= { 0x10c, BIT(16) },
> +	[RST_R_BUS_PWM]		= { 0x13c, BIT(16) },
> +	[RST_R_BUS_CODEC]	= { 0x14c, BIT(16) },
> +	[RST_R_BUS_DMIC]	= { 0x15c, BIT(16) },
> +	[RST_R_BUS_LRADC]	= { 0x16c, BIT(16) },
> +	[RST_R_BUS_I2S]		= { 0x17c, BIT(16) },
> +	[RST_R_BUS_UART]	= { 0x18c, BIT(16) },
> +	[RST_R_BUS_I2C]		= { 0x19c, BIT(16) },
> +	[RST_R_BUS_IR]		= { 0x1cc, BIT(16) },
> +	[RST_R_BUS_MSGBOX]	= { 0x1dc, BIT(16) },
> +	[RST_R_BUS_SPINLOCK]	= { 0x1ec, BIT(16) },
> +	[RST_R_BUS_RTC]		= { 0x20c, BIT(16) },
> +};
> +
> +static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
> +	.ccu_clks	= sun50i_r329_r_ccu_clks,
> +	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_r_ccu_clks),
> +
> +	.hw_clks	= &sun50i_r329_r_hw_clks,
> +
> +	.resets		= sun50i_r329_r_ccu_resets,
> +	.num_resets	= ARRAY_SIZE(sun50i_r329_r_ccu_resets),
> +};
> +
> +static const u32 pll_regs[] = {
> +	SUN50I_R329_PLL_CPUX_REG,
> +	SUN50I_R329_PLL_PERIPH_REG,
> +	SUN50I_R329_PLL_AUDIO0_REG,
> +	SUN50I_R329_PLL_AUDIO1_REG,
> +};
> +
> +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> +{
> +	void __iomem *reg;
> +	u32 val;
> +	int i;
> +
> +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> +	if (IS_ERR(reg)) {
> +		pr_err("%pOF: Could not map clock registers\n", node);
> +		return;
> +	}
> +
> +	/* Enable the lock bits and the output enable bits on all PLLs */
> +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> +		val = readl(reg + pll_regs[i]);
> +		val |= BIT(29) | BIT(27);
> +		writel(val, reg + pll_regs[i]);
> +	}
> +
> +	/*
> +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> +	 *
> +	 * See the comment before pll-audio1 definition for the reason.
> +	 */
> +
> +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> +	val &= ~BIT(1);
> +	val |= BIT(0);
> +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> +
> +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> +	if (i)
> +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> +}
> +
> +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> +	       sun50i_r329_r_ccu_setup);

Please make this a platform driver. There is no particular reason why it needs
to be an early OF clock provider.

Regards,
Samuel

> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> new file mode 100644
> index 000000000000..62cf65322116
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _CCU_SUN50I_R329_R_H
> +#define _CCU_SUN50I_R329_R_H
> +
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +#define CLK_PLL_CPUX		0
> +#define CLK_PLL_PERIPH_BASE	1
> +#define CLK_PLL_PERIPH_2X	2
> +#define CLK_PLL_PERIPH_800M	3
> +#define CLK_PLL_PERIPH		4
> +#define CLK_PLL_AUDIO0		5
> +#define CLK_PLL_AUDIO0_DIV2	6
> +#define CLK_PLL_AUDIO0_DIV5	7
> +#define CLK_PLL_AUDIO1_4X	8
> +#define CLK_PLL_AUDIO1_2X	9
> +#define CLK_PLL_AUDIO1		10
> +#define CLK_R_AHB		11
> +
> +/* R_APB1 exported for PIO */
> +
> +#define CLK_R_APB2		13
> +
> +/* All module / bus gate clocks exported */
> +
> +#define CLK_NUMBER	(CLK_R_BUS_RTC + 1)
> +
> +#endif /* _CCU_SUN50I_R329_R_H */
> diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..df9bc58de5c4
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> +
> +#define CLK_R_APB1		12
> +
> +#define CLK_R_BUS_GPADC		14
> +#define CLK_R_BUS_THS		15
> +#define CLK_R_BUS_DMA		16
> +#define CLK_R_PWM		17
> +#define CLK_R_BUS_PWM		18
> +#define CLK_R_CODEC_ADC		19
> +#define CLK_R_CODEC_DAC		20
> +#define CLK_R_BUS_CODEC		21
> +#define CLK_R_DMIC		22
> +#define CLK_R_BUS_DMIC		23
> +#define CLK_R_BUS_LRADC		24
> +#define CLK_R_I2S		25
> +#define CLK_R_I2S_ASRC		26
> +#define CLK_R_BUS_I2S		27
> +#define CLK_R_BUS_UART		28
> +#define CLK_R_BUS_I2C		29
> +#define CLK_R_IR		30
> +#define CLK_R_BUS_IR		31
> +#define CLK_R_BUS_MSGBOX	32
> +#define CLK_R_BUS_SPINLOCK	33
> +#define CLK_R_BUS_RTC		34
> +
> +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
> diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> new file mode 100644
> index 000000000000..40644f2f21c6
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> +
> +#define RST_R_BUS_GPADC		0
> +#define RST_R_BUS_THS		1
> +#define RST_R_BUS_DMA		2
> +#define RST_R_BUS_PWM		3
> +#define RST_R_BUS_CODEC		4
> +#define RST_R_BUS_DMIC		5
> +#define RST_R_BUS_LRADC		6
> +#define RST_R_BUS_I2S		7
> +#define RST_R_BUS_UART		8
> +#define RST_R_BUS_I2C		9
> +#define RST_R_BUS_IR		10
> +#define RST_R_BUS_MSGBOX	11
> +#define RST_R_BUS_SPINLOCK	12
> +#define RST_R_BUS_RTC		13
> +
> +#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */
> 



From christianshewitt at gmail.com  Thu Aug 19 18:27:18 2021
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Fri, 20 Aug 2021 01:27:18 +0000
Subject: [PATCH] soc: amlogic: meson-gx-socinfo: Add S905Y2 ID for Radxa Zero
Message-ID: <20210820012718.10761-1-christianshewitt@gmail.com>

Add the SOC ID for the S905Y2 used in the Radxa Zero. Before/After:

[    0.321650] soc soc0: Amlogic Meson G12A (Unknown) Revision 28:b (30:2) Detected
[    0.318533] soc soc0: Amlogic Meson G12A (S905Y2) Revision 28:b (30:2) Detected

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 drivers/soc/amlogic/meson-gx-socinfo.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c
index 6f54bd832c8b..165f7548401b 100644
--- a/drivers/soc/amlogic/meson-gx-socinfo.c
+++ b/drivers/soc/amlogic/meson-gx-socinfo.c
@@ -65,6 +65,7 @@ static const struct meson_gx_package_id {
 	{ "A113X", 0x25, 0x37, 0xff },
 	{ "A113D", 0x25, 0x22, 0xff },
 	{ "S905D2", 0x28, 0x10, 0xf0 },
+	{ "S905Y2", 0x28, 0x30, 0xf0 },
 	{ "S905X2", 0x28, 0x40, 0xf0 },
 	{ "A311D", 0x29, 0x10, 0xf0 },
 	{ "S922X", 0x29, 0x40, 0xf0 },
-- 
2.17.1



From 21cnbao at gmail.com  Thu Aug 19 18:30:05 2021
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 20 Aug 2021 13:30:05 +1200
Subject: [PATCH 0/3] Represent cluster topology and enable load balance
 between clusters
Message-ID: <20210820013008.12881-1-21cnbao@gmail.com>

From: Barry Song <song.bao.hua at hisilicon.com>

ARM64 machines like kunpeng920 and x86 machines like Jacobsville have a
level of hardware topology in which some CPU cores, typically 4 cores,
share L3 tags or L2 cache.

That means spreading those tasks between clusters will bring more memory
bandwidth and decrease cache contention. But packing tasks might help
decrease the latency of cache synchronization.

We have three series to bring up cluster level scheduler in kernel.
This is the first series.

1st series(this one): make kernel aware of cluster, expose cluster to sysfs
ABI and add SCHED_CLUSTER which can make load balance among clusters to
benefit lots of workload.
Testing shows this can hugely boost the performance, for example, this
can increase 25.1% of SPECrate mcf on Jacobsville and 13.574% of mcf
on kunpeng920.

2nd series(packing path): modify the wake_affine and let kernel select CPUs
within cluster first before scanning the whole LLC so that we can benefit
from the lower latency of the communication within one single cluster.
this series is much more tricky. so we would like to send it after the 1st
series settles down. Prototype here:
https://op-lists.linaro.org/pipermail/linaro-open-discussions/2021-June/000219.html

3rd series: a sysctl to permit users to enable or disable cluster scheduler
from Tim Chen. Prototype here:
Add run time sysctl to enable/disable cluster scheduling
https://op-lists.linaro.org/pipermail/linaro-open-discussions/2021-July/000258.html

This series is rebased on Greg's driver-core-next with the update in topology
sysfs ABI.

-V1:
 differences with RFC v6 
 * rebased on top of the latest update in topology sysfs ABI of Greg's
   driver-core-next
 * removed wake_affine path modifcation, which will be separately b2nd series
 * cluster_id is gotten by detecting valid ID before falling back to use offset
 * lots of benchmark data from both x86 Jacobsville and ARM64 kunpeng920

-RFC v6:
https://lore.kernel.org/lkml/20210420001844.9116-1-song.bao.hua at hisilicon.com/

Barry Song (1):
  scheduler: Add cluster scheduler level in core and related Kconfig for
    ARM64

Jonathan Cameron (1):
  topology: Represent clusters of CPUs within a die

Tim Chen (1):
  scheduler: Add cluster scheduler level for x86

 .../ABI/stable/sysfs-devices-system-cpu       | 15 +++++
 Documentation/admin-guide/cputopology.rst     | 12 ++--
 arch/arm64/Kconfig                            |  7 ++
 arch/arm64/kernel/topology.c                  |  2 +
 arch/x86/Kconfig                              |  8 +++
 arch/x86/include/asm/smp.h                    |  7 ++
 arch/x86/include/asm/topology.h               |  3 +
 arch/x86/kernel/cpu/cacheinfo.c               |  1 +
 arch/x86/kernel/cpu/common.c                  |  3 +
 arch/x86/kernel/smpboot.c                     | 44 +++++++++++-
 drivers/acpi/pptt.c                           | 67 +++++++++++++++++++
 drivers/base/arch_topology.c                  | 14 ++++
 drivers/base/topology.c                       | 10 +++
 include/linux/acpi.h                          |  5 ++
 include/linux/arch_topology.h                 |  5 ++
 include/linux/sched/topology.h                |  7 ++
 include/linux/topology.h                      | 13 ++++
 kernel/sched/topology.c                       |  5 ++
 18 files changed, 223 insertions(+), 5 deletions(-)

-- 
2.25.1



From 21cnbao at gmail.com  Thu Aug 19 18:30:06 2021
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 20 Aug 2021 13:30:06 +1200
Subject: [PATCH 1/3] topology: Represent clusters of CPUs within a die
In-Reply-To: <20210820013008.12881-1-21cnbao@gmail.com>
References: <20210820013008.12881-1-21cnbao@gmail.com>
Message-ID: <20210820013008.12881-2-21cnbao@gmail.com>

From: Jonathan Cameron <Jonathan.Cameron at huawei.com>

Both ACPI and DT provide the ability to describe additional layers of
topology between that of individual cores and higher level constructs
such as the level at which the last level cache is shared.
In ACPI this can be represented in PPTT as a Processor Hierarchy
Node Structure [1] that is the parent of the CPU cores and in turn
has a parent Processor Hierarchy Nodes Structure representing
a higher level of topology.

For example Kunpeng 920 has 6 or 8 clusters in each NUMA node, and each
cluster has 4 cpus. All clusters share L3 cache data, but each cluster
has local L3 tag. On the other hand, each clusters will share some
internal system bus.

+-----------------------------------+                          +---------+
|  +------+    +------+            +---------------------------+         |
|  | CPU0 |    | cpu1 |             |    +-----------+         |         |
|  +------+    +------+             |    |           |         |         |
|                                   +----+    L3     |         |         |
|  +------+    +------+   cluster   |    |    tag    |         |         |
|  | CPU2 |    | CPU3 |             |    |           |         |         |
|  +------+    +------+             |    +-----------+         |         |
|                                   |                          |         |
+-----------------------------------+                          |         |
+-----------------------------------+                          |         |
|  +------+    +------+             +--------------------------+         |
|  |      |    |      |             |    +-----------+         |         |
|  +------+    +------+             |    |           |         |         |
|                                   |    |    L3     |         |         |
|  +------+    +------+             +----+    tag    |         |         |
|  |      |    |      |             |    |           |         |         |
|  +------+    +------+             |    +-----------+         |         |
|                                   |                          |         |
+-----------------------------------+                          |   L3    |
                                                               |   data  |
+-----------------------------------+                          |         |
|  +------+    +------+             |    +-----------+         |         |
|  |      |    |      |             |    |           |         |         |
|  +------+    +------+             +----+    L3     |         |         |
|                                   |    |    tag    |         |         |
|  +------+    +------+             |    |           |         |         |
|  |      |    |      |            ++    +-----------+         |         |
|  +------+    +------+            |---------------------------+         |
+-----------------------------------|                          |         |
+-----------------------------------|                          |         |
|  +------+    +------+            +---------------------------+         |
|  |      |    |      |             |    +-----------+         |         |
|  +------+    +------+             |    |           |         |         |
|                                   +----+    L3     |         |         |
|  +------+    +------+             |    |    tag    |         |         |
|  |      |    |      |             |    |           |         |         |
|  +------+    +------+             |    +-----------+         |         |
|                                   |                          |         |
+-----------------------------------+                          |         |
+-----------------------------------+                          |         |
|  +------+    +------+             +--------------------------+         |
|  |      |    |      |             |   +-----------+          |         |
|  +------+    +------+             |   |           |          |         |
|                                   |   |    L3     |          |         |
|  +------+    +------+             +---+    tag    |          |         |
|  |      |    |      |             |   |           |          |         |
|  +------+    +------+             |   +-----------+          |         |
|                                   |                          |         |
+-----------------------------------+                          |         |
+-----------------------------------+                         ++         |
|  +------+    +------+             +--------------------------+         |
|  |      |    |      |             |  +-----------+           |         |
|  +------+    +------+             |  |           |           |         |
|                                   |  |    L3     |           |         |
|  +------+    +------+             +--+    tag    |           |         |
|  |      |    |      |             |  |           |           |         |
|  +------+    +------+             |  +-----------+           |         |
|                                   |                          +---------+
+-----------------------------------+

That means spreading tasks among clusters will bring more bandwidth
while packing tasks within one cluster will lead to smaller cache
synchronization latency. So both kernel and userspace will have
a chance to leverage this topology to deploy tasks accordingly to
achieve either smaller cache latency within one cluster or an even
distribution of load among clusters for higher throughput.

This patch exposes cluster topology to both kernel and userspace.
Libraried like hwloc will know cluster by cluster_cpus and related
sysfs attributes. PoC of HWLOC support at [2].

Note this patch only handle the ACPI case.

Special consideration is needed for SMT processors, where it is
necessary to move 2 levels up the hierarchy from the leaf nodes
(thus skipping the processor core level).

Note that arm64 / ACPI does not provide any means of identifying
a die level in the topology but that may be unrelate to the cluster
level.

[1] ACPI Specification 6.3 - section 5.2.29.1 processor hierarchy node
    structure (Type 0)
[2] https://github.com/hisilicon/hwloc/tree/linux-cluster

Signed-off-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Tian Tao <tiantao6 at hisilicon.com>
Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
---
 .../ABI/stable/sysfs-devices-system-cpu       | 15 +++++
 Documentation/admin-guide/cputopology.rst     | 12 ++--
 arch/arm64/kernel/topology.c                  |  2 +
 drivers/acpi/pptt.c                           | 67 +++++++++++++++++++
 drivers/base/arch_topology.c                  | 14 ++++
 drivers/base/topology.c                       | 10 +++
 include/linux/acpi.h                          |  5 ++
 include/linux/arch_topology.h                 |  5 ++
 include/linux/topology.h                      |  6 ++
 9 files changed, 132 insertions(+), 4 deletions(-)

diff --git a/Documentation/ABI/stable/sysfs-devices-system-cpu b/Documentation/ABI/stable/sysfs-devices-system-cpu
index 516dafea03eb..3965ce504484 100644
--- a/Documentation/ABI/stable/sysfs-devices-system-cpu
+++ b/Documentation/ABI/stable/sysfs-devices-system-cpu
@@ -42,6 +42,12 @@ Description:    the CPU core ID of cpuX. Typically it is the hardware platform's
                 architecture and platform dependent.
 Values:         integer
 
+What:           /sys/devices/system/cpu/cpuX/topology/cluster_id
+Description:    the cluster ID of cpuX.  Typically it is the hardware platform's
+                identifier (rather than the kernel's). The actual value is
+                architecture and platform dependent.
+Values:         integer
+
 What:           /sys/devices/system/cpu/cpuX/topology/book_id
 Description:    the book ID of cpuX. Typically it is the hardware platform's
                 identifier (rather than the kernel's). The actual value is
@@ -85,6 +91,15 @@ Description:    human-readable list of CPUs within the same die.
                 The format is like 0-3, 8-11, 14,17.
 Values:         decimal list.
 
+What:           /sys/devices/system/cpu/cpuX/topology/cluster_cpus
+Description:    internal kernel map of CPUs within the same cluster.
+Values:         hexadecimal bitmask.
+
+What:           /sys/devices/system/cpu/cpuX/topology/cluster_cpus_list
+Description:    human-readable list of CPUs within the same cluster.
+                The format is like 0-3, 8-11, 14,17.
+Values:         decimal list.
+
 What:           /sys/devices/system/cpu/cpuX/topology/book_siblings
 Description:    internal kernel map of cpuX's hardware threads within the same
                 book_id. it's only used on s390.
diff --git a/Documentation/admin-guide/cputopology.rst b/Documentation/admin-guide/cputopology.rst
index 8632a1db36e4..a5491949880d 100644
--- a/Documentation/admin-guide/cputopology.rst
+++ b/Documentation/admin-guide/cputopology.rst
@@ -19,11 +19,13 @@ these macros in include/asm-XXX/topology.h::
 
 	#define topology_physical_package_id(cpu)
 	#define topology_die_id(cpu)
+	#define topology_cluster_id(cpu)
 	#define topology_core_id(cpu)
 	#define topology_book_id(cpu)
 	#define topology_drawer_id(cpu)
 	#define topology_sibling_cpumask(cpu)
 	#define topology_core_cpumask(cpu)
+	#define topology_cluster_cpumask(cpu)
 	#define topology_die_cpumask(cpu)
 	#define topology_book_cpumask(cpu)
 	#define topology_drawer_cpumask(cpu)
@@ -39,10 +41,12 @@ not defined by include/asm-XXX/topology.h:
 
 1) topology_physical_package_id: -1
 2) topology_die_id: -1
-3) topology_core_id: 0
-4) topology_sibling_cpumask: just the given CPU
-5) topology_core_cpumask: just the given CPU
-6) topology_die_cpumask: just the given CPU
+3) topology_cluster_id: -1
+4) topology_core_id: 0
+5) topology_sibling_cpumask: just the given CPU
+6) topology_core_cpumask: just the given CPU
+7) topology_cluster_cpumask: just the given CPU
+8) topology_die_cpumask: just the given CPU
 
 For architectures that don't support books (CONFIG_SCHED_BOOK) there are no
 default definitions for topology_book_id() and topology_book_cpumask().
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 4dd14a6620c1..9ab78ad826e2 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -103,6 +103,8 @@ int __init parse_acpi_topology(void)
 			cpu_topology[cpu].thread_id  = -1;
 			cpu_topology[cpu].core_id    = topology_id;
 		}
+		topology_id = find_acpi_cpu_topology_cluster(cpu);
+		cpu_topology[cpu].cluster_id = topology_id;
 		topology_id = find_acpi_cpu_topology_package(cpu);
 		cpu_topology[cpu].package_id = topology_id;
 
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index fe69dc518f31..701f61c01359 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -746,6 +746,73 @@ int find_acpi_cpu_topology_package(unsigned int cpu)
 					  ACPI_PPTT_PHYSICAL_PACKAGE);
 }
 
+/**
+ * find_acpi_cpu_topology_cluster() - Determine a unique CPU cluster value
+ * @cpu: Kernel logical CPU number
+ *
+ * Determine a topology unique cluster ID for the given CPU/thread.
+ * This ID can then be used to group peers, which will have matching ids.
+ *
+ * The cluster, if present is the level of topology above CPUs. In a
+ * multi-thread CPU, it will be the level above the CPU, not the thread.
+ * It may not exist in single CPU systems. In simple multi-CPU systems,
+ * it may be equal to the package topology level.
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found
+ * or there is no toplogy level above the CPU..
+ * Otherwise returns a value which represents the package for this CPU.
+ */
+
+int find_acpi_cpu_topology_cluster(unsigned int cpu)
+{
+	struct acpi_table_header *table;
+	acpi_status status;
+	struct acpi_pptt_processor *cpu_node, *cluster_node;
+	u32 acpi_cpu_id;
+	int retval;
+	int is_thread;
+
+	status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+	if (ACPI_FAILURE(status)) {
+		acpi_pptt_warn_missing();
+		return -ENOENT;
+	}
+
+	acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+	cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
+	if (cpu_node == NULL || !cpu_node->parent) {
+		retval = -ENOENT;
+		goto put_table;
+	}
+
+	is_thread = cpu_node->flags & ACPI_PPTT_ACPI_PROCESSOR_IS_THREAD;
+	cluster_node = fetch_pptt_node(table, cpu_node->parent);
+	if (cluster_node == NULL) {
+		retval = -ENOENT;
+		goto put_table;
+	}
+	if (is_thread) {
+		if (!cluster_node->parent) {
+			retval = -ENOENT;
+			goto put_table;
+		}
+		cluster_node = fetch_pptt_node(table, cluster_node->parent);
+		if (cluster_node == NULL) {
+			retval = -ENOENT;
+			goto put_table;
+		}
+	}
+	if (cluster_node->flags & ACPI_PPTT_ACPI_PROCESSOR_ID_VALID)
+		retval = cluster_node->acpi_processor_id;
+	else
+		retval = ACPI_PTR_DIFF(cluster_node, table);
+
+put_table:
+	acpi_put_table(table);
+
+	return retval;
+}
+
 /**
  * find_acpi_cpu_topology_hetero_id() - Get a core architecture tag
  * @cpu: Kernel logical CPU number
diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 921312a8d957..5b1589adacaf 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -598,6 +598,11 @@ const struct cpumask *cpu_coregroup_mask(int cpu)
 	return core_mask;
 }
 
+const struct cpumask *cpu_clustergroup_mask(int cpu)
+{
+	return &cpu_topology[cpu].cluster_sibling;
+}
+
 void update_siblings_masks(unsigned int cpuid)
 {
 	struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
@@ -615,6 +620,11 @@ void update_siblings_masks(unsigned int cpuid)
 		if (cpuid_topo->package_id != cpu_topo->package_id)
 			continue;
 
+		if (cpuid_topo->cluster_id == cpu_topo->cluster_id) {
+			cpumask_set_cpu(cpu, &cpuid_topo->cluster_sibling);
+			cpumask_set_cpu(cpuid, &cpu_topo->cluster_sibling);
+		}
+
 		cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
 		cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
 
@@ -633,6 +643,9 @@ static void clear_cpu_topology(int cpu)
 	cpumask_clear(&cpu_topo->llc_sibling);
 	cpumask_set_cpu(cpu, &cpu_topo->llc_sibling);
 
+	cpumask_clear(&cpu_topo->cluster_sibling);
+	cpumask_set_cpu(cpu, &cpu_topo->cluster_sibling);
+
 	cpumask_clear(&cpu_topo->core_sibling);
 	cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
 	cpumask_clear(&cpu_topo->thread_sibling);
@@ -648,6 +661,7 @@ void __init reset_cpu_topology(void)
 
 		cpu_topo->thread_id = -1;
 		cpu_topo->core_id = -1;
+		cpu_topo->cluster_id = -1;
 		cpu_topo->package_id = -1;
 		cpu_topo->llc_id = -1;
 
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index 43c0940643f5..8f2b641d0b8c 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -48,6 +48,9 @@ static DEVICE_ATTR_RO(physical_package_id);
 define_id_show_func(die_id);
 static DEVICE_ATTR_RO(die_id);
 
+define_id_show_func(cluster_id);
+static DEVICE_ATTR_RO(cluster_id);
+
 define_id_show_func(core_id);
 static DEVICE_ATTR_RO(core_id);
 
@@ -63,6 +66,10 @@ define_siblings_read_func(core_siblings, core_cpumask);
 static BIN_ATTR_RO(core_siblings, 0);
 static BIN_ATTR_RO(core_siblings_list, 0);
 
+define_siblings_read_func(cluster_cpus, cluster_cpumask);
+static BIN_ATTR_RO(cluster_cpus, 0);
+static BIN_ATTR_RO(cluster_cpus_list, 0);
+
 define_siblings_read_func(die_cpus, die_cpumask);
 static BIN_ATTR_RO(die_cpus, 0);
 static BIN_ATTR_RO(die_cpus_list, 0);
@@ -94,6 +101,8 @@ static struct bin_attribute *bin_attrs[] = {
 	&bin_attr_thread_siblings_list,
 	&bin_attr_core_siblings,
 	&bin_attr_core_siblings_list,
+	&bin_attr_cluster_cpus,
+	&bin_attr_cluster_cpus_list,
 	&bin_attr_die_cpus,
 	&bin_attr_die_cpus_list,
 	&bin_attr_package_cpus,
@@ -112,6 +121,7 @@ static struct bin_attribute *bin_attrs[] = {
 static struct attribute *default_attrs[] = {
 	&dev_attr_physical_package_id.attr,
 	&dev_attr_die_id.attr,
+	&dev_attr_cluster_id.attr,
 	&dev_attr_core_id.attr,
 #ifdef CONFIG_SCHED_BOOK
 	&dev_attr_book_id.attr,
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 72e4f7fd268c..6d65427e5f67 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1353,6 +1353,7 @@ static inline int lpit_read_residency_count_address(u64 *address)
 #ifdef CONFIG_ACPI_PPTT
 int acpi_pptt_cpu_is_thread(unsigned int cpu);
 int find_acpi_cpu_topology(unsigned int cpu, int level);
+int find_acpi_cpu_topology_cluster(unsigned int cpu);
 int find_acpi_cpu_topology_package(unsigned int cpu);
 int find_acpi_cpu_topology_hetero_id(unsigned int cpu);
 int find_acpi_cpu_cache_topology(unsigned int cpu, int level);
@@ -1365,6 +1366,10 @@ static inline int find_acpi_cpu_topology(unsigned int cpu, int level)
 {
 	return -EINVAL;
 }
+static inline int find_acpi_cpu_topology_cluster(unsigned int cpu)
+{
+	return -EINVAL;
+}
 static inline int find_acpi_cpu_topology_package(unsigned int cpu)
 {
 	return -EINVAL;
diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h
index f180240dc95f..b97cea83b25e 100644
--- a/include/linux/arch_topology.h
+++ b/include/linux/arch_topology.h
@@ -62,10 +62,12 @@ void topology_set_thermal_pressure(const struct cpumask *cpus,
 struct cpu_topology {
 	int thread_id;
 	int core_id;
+	int cluster_id;
 	int package_id;
 	int llc_id;
 	cpumask_t thread_sibling;
 	cpumask_t core_sibling;
+	cpumask_t cluster_sibling;
 	cpumask_t llc_sibling;
 };
 
@@ -73,13 +75,16 @@ struct cpu_topology {
 extern struct cpu_topology cpu_topology[NR_CPUS];
 
 #define topology_physical_package_id(cpu)	(cpu_topology[cpu].package_id)
+#define topology_cluster_id(cpu)	(cpu_topology[cpu].cluster_id)
 #define topology_core_id(cpu)		(cpu_topology[cpu].core_id)
 #define topology_core_cpumask(cpu)	(&cpu_topology[cpu].core_sibling)
 #define topology_sibling_cpumask(cpu)	(&cpu_topology[cpu].thread_sibling)
+#define topology_cluster_cpumask(cpu)	(&cpu_topology[cpu].cluster_sibling)
 #define topology_llc_cpumask(cpu)	(&cpu_topology[cpu].llc_sibling)
 void init_cpu_topology(void);
 void store_cpu_topology(unsigned int cpuid);
 const struct cpumask *cpu_coregroup_mask(int cpu);
+const struct cpumask *cpu_clustergroup_mask(int cpu);
 void update_siblings_masks(unsigned int cpu);
 void remove_cpu_topology(unsigned int cpuid);
 void reset_cpu_topology(void);
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 7634cd737061..80d27d717631 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -186,6 +186,9 @@ static inline int cpu_to_mem(int cpu)
 #ifndef topology_die_id
 #define topology_die_id(cpu)			((void)(cpu), -1)
 #endif
+#ifndef topology_cluster_id
+#define topology_cluster_id(cpu)		((void)(cpu), -1)
+#endif
 #ifndef topology_core_id
 #define topology_core_id(cpu)			((void)(cpu), 0)
 #endif
@@ -195,6 +198,9 @@ static inline int cpu_to_mem(int cpu)
 #ifndef topology_core_cpumask
 #define topology_core_cpumask(cpu)		cpumask_of(cpu)
 #endif
+#ifndef topology_cluster_cpumask
+#define topology_cluster_cpumask(cpu)		cpumask_of(cpu)
+#endif
 #ifndef topology_die_cpumask
 #define topology_die_cpumask(cpu)		cpumask_of(cpu)
 #endif
-- 
2.25.1



From 21cnbao at gmail.com  Thu Aug 19 18:30:07 2021
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 20 Aug 2021 13:30:07 +1200
Subject: [PATCH 2/3] scheduler: Add cluster scheduler level in core and
 related Kconfig for ARM64
In-Reply-To: <20210820013008.12881-1-21cnbao@gmail.com>
References: <20210820013008.12881-1-21cnbao@gmail.com>
Message-ID: <20210820013008.12881-3-21cnbao@gmail.com>

From: Barry Song <song.bao.hua at hisilicon.com>

This patch adds scheduler level for clusters and automatically enables
the load balance among clusters. It will directly benefit a lot of
workload which loves more resources such as memory bandwidth, caches.

Testing has widely been done in two different hardware configurations of
Kunpeng920:

 24 cores in one NUMA(6 clusters in each NUMA node);
 32 cores in one NUMA(8 clusters in each NUMA node)

Workload is running on either one NUMA node or four NUMA nodes, thus,
this can estimate the effect of cluster spreading w/ and w/o NUMA load
balance.

* Stream benchmark:

4threads stream (on 1NUMA * 24cores = 24cores)
                stream                 stream
                w/o patch              w/ patch
MB/sec copy     29929.64 (   0.00%)    32932.68 (  10.03%)
MB/sec scale    29861.10 (   0.00%)    32710.58 (   9.54%)
MB/sec add      27034.42 (   0.00%)    32400.68 (  19.85%)
MB/sec triad    27225.26 (   0.00%)    31965.36 (  17.41%)

6threads stream (on 1NUMA * 24cores = 24cores)
                stream                 stream
                w/o patch              w/ patch
MB/sec copy     40330.24 (   0.00%)    42377.68 (   5.08%)
MB/sec scale    40196.42 (   0.00%)    42197.90 (   4.98%)
MB/sec add      37427.00 (   0.00%)    41960.78 (  12.11%)
MB/sec triad    37841.36 (   0.00%)    42513.64 (  12.35%)

12threads stream (on 1NUMA * 24cores = 24cores)
                stream                 stream
                w/o patch              w/ patch
MB/sec copy     52639.82 (   0.00%)    53818.04 (   2.24%)
MB/sec scale    52350.30 (   0.00%)    53253.38 (   1.73%)
MB/sec add      53607.68 (   0.00%)    55198.82 (   2.97%)
MB/sec triad    54776.66 (   0.00%)    56360.40 (   2.89%)

Thus, it could help memory-bound workload especially under medium load.
Similar improvement is also seen in lkp-pbzip2:

* lkp-pbzip2 benchmark

2-96 threads (on 4NUMA * 24cores = 96cores)
                  lkp-pbzip2              lkp-pbzip2
                  w/o patch               w/ patch
Hmean     tput-2   11062841.57 (   0.00%)  11341817.51 *   2.52%*
Hmean     tput-5   26815503.70 (   0.00%)  27412872.65 *   2.23%*
Hmean     tput-8   41873782.21 (   0.00%)  43326212.92 *   3.47%*
Hmean     tput-12  61875980.48 (   0.00%)  64578337.51 *   4.37%*
Hmean     tput-21 105814963.07 (   0.00%) 111381851.01 *   5.26%*
Hmean     tput-30 150349470.98 (   0.00%) 156507070.73 *   4.10%*
Hmean     tput-48 237195937.69 (   0.00%) 242353597.17 *   2.17%*
Hmean     tput-79 360252509.37 (   0.00%) 362635169.23 *   0.66%*
Hmean     tput-96 394571737.90 (   0.00%) 400952978.48 *   1.62%*

2-24 threads (on 1NUMA * 24cores = 24cores)
                 lkp-pbzip2               lkp-pbzip2
                 w/o patch                w/ patch
Hmean     tput-2   11071705.49 (   0.00%)  11296869.10 *   2.03%*
Hmean     tput-4   20782165.19 (   0.00%)  21949232.15 *   5.62%*
Hmean     tput-6   30489565.14 (   0.00%)  33023026.96 *   8.31%*
Hmean     tput-8   40376495.80 (   0.00%)  42779286.27 *   5.95%*
Hmean     tput-12  61264033.85 (   0.00%)  62995632.78 *   2.83%*
Hmean     tput-18  86697139.39 (   0.00%)  86461545.74 (  -0.27%)
Hmean     tput-24 104854637.04 (   0.00%) 104522649.46 *  -0.32%*

In the case of 6 threads and 8 threads, we see the greatest performance
improvement.

Similar improvement can be seen on lkp-pixz though the improvement is
smaller:

* lkp-pixz benchmark

2-24 threads lkp-pixz (on 1NUMA * 24cores = 24cores)
                  lkp-pixz               lkp-pixz
                  w/o patch              w/ patch
Hmean     tput-2   6486981.16 (   0.00%)  6561515.98 *   1.15%*
Hmean     tput-4  11645766.38 (   0.00%) 11614628.43 (  -0.27%)
Hmean     tput-6  15429943.96 (   0.00%) 15957350.76 *   3.42%*
Hmean     tput-8  19974087.63 (   0.00%) 20413746.98 *   2.20%*
Hmean     tput-12 28172068.18 (   0.00%) 28751997.06 *   2.06%*
Hmean     tput-18 39413409.54 (   0.00%) 39896830.55 *   1.23%*
Hmean     tput-24 49101815.85 (   0.00%) 49418141.47 *   0.64%*

* SPECrate benchmark

4,8,16 copies mcf_r(on 1NUMA * 32cores = 32cores)
		Base     	 	Base
		Run Time   	 	Rate
		-------  	 	---------
4 Copies	w/o 580 (w/ 570)       	w/o 11.1 (w/ 11.3)
8 Copies	w/o 647 (w/ 605)       	w/o 20.0 (w/ 21.4, +7%)
16 Copies	w/o 844 (w/ 844)       	w/o 30.6 (w/ 30.6)

32 Copies(on 4NUMA * 32 cores = 128cores)
[w/o patch]
                 Base     Base        Base
Benchmarks       Copies  Run Time     Rate
--------------- -------  ---------  ---------
500.perlbench_r      32        584       87.2  *
502.gcc_r            32        503       90.2  *
505.mcf_r            32        745       69.4  *
520.omnetpp_r        32       1031       40.7  *
523.xalancbmk_r      32        597       56.6  *
525.x264_r            1         --            CE
531.deepsjeng_r      32        336      109    *
541.leela_r          32        556       95.4  *
548.exchange2_r      32        513      163    *
557.xz_r             32        530       65.2  *
 Est. SPECrate2017_int_base              80.3

[w/ patch]
                  Base     Base        Base
Benchmarks       Copies  Run Time     Rate
--------------- -------  ---------  ---------
500.perlbench_r      32        580      87.8 (+0.688%)  *
502.gcc_r            32        477      95.1 (+5.432%)  *
505.mcf_r            32        644      80.3 (+13.574%) *
520.omnetpp_r        32        942      44.6 (+9.58%)   *
523.xalancbmk_r      32        560      60.4 (+6.714%%) *
525.x264_r            1         --           CE
531.deepsjeng_r      32        337      109  (+0.000%) *
541.leela_r          32        554      95.6 (+0.210%) *
548.exchange2_r      32        515      163  (+0.000%) *
557.xz_r             32        524      66.0 (+1.227%) *
 Est. SPECrate2017_int_base              83.7 (+4.062%)

On the other hand, it is slightly helpful to CPU-bound tasks like
kernbench:

* 24-96 threads kernbench (on 4NUMA * 24cores = 96cores)
                     kernbench              kernbench
                     w/o cluster            w/ cluster
Min       user-24    12054.67 (   0.00%)    12024.19 (   0.25%)
Min       syst-24     1751.51 (   0.00%)     1731.68 (   1.13%)
Min       elsp-24      600.46 (   0.00%)      598.64 (   0.30%)
Min       user-48    12361.93 (   0.00%)    12315.32 (   0.38%)
Min       syst-48     1917.66 (   0.00%)     1892.73 (   1.30%)
Min       elsp-48      333.96 (   0.00%)      332.57 (   0.42%)
Min       user-96    12922.40 (   0.00%)    12921.17 (   0.01%)
Min       syst-96     2143.94 (   0.00%)     2110.39 (   1.56%)
Min       elsp-96      211.22 (   0.00%)      210.47 (   0.36%)
Amean     user-24    12063.99 (   0.00%)    12030.78 *   0.28%*
Amean     syst-24     1755.20 (   0.00%)     1735.53 *   1.12%*
Amean     elsp-24      601.60 (   0.00%)      600.19 (   0.23%)
Amean     user-48    12362.62 (   0.00%)    12315.56 *   0.38%*
Amean     syst-48     1921.59 (   0.00%)     1894.95 *   1.39%*
Amean     elsp-48      334.10 (   0.00%)      332.82 *   0.38%*
Amean     user-96    12925.27 (   0.00%)    12922.63 (   0.02%)
Amean     syst-96     2146.66 (   0.00%)     2122.20 *   1.14%*
Amean     elsp-96      211.96 (   0.00%)      211.79 (   0.08%)

Note this patch isn't an universal win, it might hurt those workload
which can benefit from packing. Though tasks which want to take
advantages of lower communication latency of one cluster won't
necessarily been packed in one cluster while kernel is not aware of
clusters, they have some chance to been randomly packed. But this
patch will make them spread anyway.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
---
 arch/arm64/Kconfig             | 7 +++++++
 include/linux/sched/topology.h | 7 +++++++
 include/linux/topology.h       | 7 +++++++
 kernel/sched/topology.c        | 5 +++++
 4 files changed, 26 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index fdcd54d39c1e..7a3cc2314a03 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -992,6 +992,13 @@ config SCHED_MC
 	  making when dealing with multi-core CPU chips at a cost of slightly
 	  increased overhead in some places. If unsure say N here.
 
+config SCHED_CLUSTER
+	bool "Cluster scheduler support"
+	help
+	  Cluster scheduler support improves the CPU scheduler's decision
+	  making when dealing with machines that have clusters(sharing internal
+	  bus or sharing LLC cache tag). If unsure say N here.
+
 config SCHED_SMT
 	bool "SMT scheduler support"
 	help
diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
index 8f0f778b7c91..2f9166f6dec8 100644
--- a/include/linux/sched/topology.h
+++ b/include/linux/sched/topology.h
@@ -42,6 +42,13 @@ static inline int cpu_smt_flags(void)
 }
 #endif
 
+#ifdef CONFIG_SCHED_CLUSTER
+static inline int cpu_cluster_flags(void)
+{
+	return SD_SHARE_PKG_RESOURCES;
+}
+#endif
+
 #ifdef CONFIG_SCHED_MC
 static inline int cpu_core_flags(void)
 {
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 80d27d717631..0b3704ad13c8 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -212,6 +212,13 @@ static inline const struct cpumask *cpu_smt_mask(int cpu)
 }
 #endif
 
+#if defined(CONFIG_SCHED_CLUSTER) && !defined(cpu_cluster_mask)
+static inline const struct cpumask *cpu_cluster_mask(int cpu)
+{
+	return topology_cluster_cpumask(cpu);
+}
+#endif
+
 static inline const struct cpumask *cpu_cpu_mask(int cpu)
 {
 	return cpumask_of_node(cpu_to_node(cpu));
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index b77ad49dc14f..546cfb1c728e 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -1625,6 +1625,11 @@ static struct sched_domain_topology_level default_topology[] = {
 #ifdef CONFIG_SCHED_SMT
 	{ cpu_smt_mask, cpu_smt_flags, SD_INIT_NAME(SMT) },
 #endif
+
+#ifdef CONFIG_SCHED_CLUSTER
+	{ cpu_clustergroup_mask, cpu_cluster_flags, SD_INIT_NAME(CLS) },
+#endif
+
 #ifdef CONFIG_SCHED_MC
 	{ cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
 #endif
-- 
2.25.1



From 21cnbao at gmail.com  Thu Aug 19 18:30:08 2021
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 20 Aug 2021 13:30:08 +1200
Subject: [PATCH 3/3] scheduler: Add cluster scheduler level for x86
In-Reply-To: <20210820013008.12881-1-21cnbao@gmail.com>
References: <20210820013008.12881-1-21cnbao@gmail.com>
Message-ID: <20210820013008.12881-4-21cnbao@gmail.com>

From: Tim Chen <tim.c.chen at linux.intel.com>

There are x86 CPU architectures (e.g. Jacobsville) where L2 cahce is
shared among a cluster of cores instead of being exclusive to one
single core.
To prevent oversubscription of L2 cache, load should be balanced
between such L2 clusters, especially for tasks with no shared data.
On benchmark such as SPECrate mcf test, this change provides a
boost to performance especially on medium load system on Jacobsville.
on a Jacobsville that has 24 Atom cores, arranged into 6 clusters
of 4 cores each, the benchmark number is as follow:

 Improvement over baseline kernel for mcf_r
 copies		run time	base rate
 1		-0.1%		-0.2%
 6		25.1%		25.1%
 12		18.8%		19.0%
 24		0.3%		0.3%

So this looks pretty good. In terms of the system's task distribution,
some pretty bad clumping can be seen for the vanilla kernel without
the L2 cluster domain for the 6 and 12 copies case. With the extra
domain for cluster, the load does get evened out between the clusters.

Note this patch isn't an universal win as spreading isn't necessarily
a win, particually for those workload who can benefit from packing.

Signed-off-by: Tim Chen <tim.c.chen at linux.intel.com>
Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
---
 arch/x86/Kconfig                |  8 ++++++
 arch/x86/include/asm/smp.h      |  7 ++++++
 arch/x86/include/asm/topology.h |  3 +++
 arch/x86/kernel/cpu/cacheinfo.c |  1 +
 arch/x86/kernel/cpu/common.c    |  3 +++
 arch/x86/kernel/smpboot.c       | 44 ++++++++++++++++++++++++++++++++-
 6 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 88fb922c23a0..e97356e99bbe 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -996,6 +996,14 @@ config NR_CPUS
 	  This is purely to save memory: each supported CPU adds about 8KB
 	  to the kernel image.
 
+config SCHED_CLUSTER
+	bool "Cluster scheduler support"
+	default n
+	help
+	 Cluster scheduler support improves the CPU scheduler's decision
+	 making when dealing with machines that have clusters of CPUs
+	 sharing L2 cache. If unsure say N here.
+
 config SCHED_SMT
 	def_bool y if SMP
 
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 630ff08532be..08b0e90623ad 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -16,7 +16,9 @@ DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
 DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
 /* cpus sharing the last level cache: */
 DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
+DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map);
 DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id);
+DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id);
 DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number);
 
 static inline struct cpumask *cpu_llc_shared_mask(int cpu)
@@ -24,6 +26,11 @@ static inline struct cpumask *cpu_llc_shared_mask(int cpu)
 	return per_cpu(cpu_llc_shared_map, cpu);
 }
 
+static inline struct cpumask *cpu_l2c_shared_mask(int cpu)
+{
+	return per_cpu(cpu_l2c_shared_map, cpu);
+}
+
 DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid);
 DECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid);
 DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid);
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 9239399e5491..2548d824f103 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -103,17 +103,20 @@ static inline void setup_node_to_cpumask_map(void) { }
 #include <asm-generic/topology.h>
 
 extern const struct cpumask *cpu_coregroup_mask(int cpu);
+extern const struct cpumask *cpu_clustergroup_mask(int cpu);
 
 #define topology_logical_package_id(cpu)	(cpu_data(cpu).logical_proc_id)
 #define topology_physical_package_id(cpu)	(cpu_data(cpu).phys_proc_id)
 #define topology_logical_die_id(cpu)		(cpu_data(cpu).logical_die_id)
 #define topology_die_id(cpu)			(cpu_data(cpu).cpu_die_id)
+#define topology_cluster_id(cpu)		(per_cpu(cpu_l2c_id, cpu))
 #define topology_core_id(cpu)			(cpu_data(cpu).cpu_core_id)
 
 extern unsigned int __max_die_per_package;
 
 #ifdef CONFIG_SMP
 #define topology_die_cpumask(cpu)		(per_cpu(cpu_die_map, cpu))
+#define topology_cluster_cpumask(cpu)		(cpu_clustergroup_mask(cpu))
 #define topology_core_cpumask(cpu)		(per_cpu(cpu_core_map, cpu))
 #define topology_sibling_cpumask(cpu)		(per_cpu(cpu_sibling_map, cpu))
 
diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index d66af2950e06..3528987fef1d 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -846,6 +846,7 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
 		l2 = new_l2;
 #ifdef CONFIG_SMP
 		per_cpu(cpu_llc_id, cpu) = l2_id;
+		per_cpu(cpu_l2c_id, cpu) = l2_id;
 #endif
 	}
 
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 64b805bd6a54..38871f114af1 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -79,6 +79,9 @@ EXPORT_SYMBOL(smp_num_siblings);
 /* Last level cache ID of each logical CPU */
 DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id) = BAD_APICID;
 
+/* L2 cache ID of each logical CPU */
+DEFINE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id) = BAD_APICID;
+
 /* correctly size the local cpu masks */
 void __init setup_cpu_local_masks(void)
 {
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 9320285a5e29..5832c6b6348f 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -101,6 +101,8 @@ EXPORT_PER_CPU_SYMBOL(cpu_die_map);
 
 DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
 
+DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map);
+
 /* Per CPU bogomips and other parameters */
 DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
 EXPORT_PER_CPU_SYMBOL(cpu_info);
@@ -464,6 +466,21 @@ static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 	return false;
 }
 
+static bool match_l2c(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
+{
+	int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
+
+	/* Do not match if we do not have a valid APICID for cpu: */
+	if (per_cpu(cpu_l2c_id, cpu1) == BAD_APICID)
+		return false;
+
+	/* Do not match if L2 cache id does not match: */
+	if (per_cpu(cpu_l2c_id, cpu1) != per_cpu(cpu_l2c_id, cpu2))
+		return false;
+
+	return topology_sane(c, o, "l2c");
+}
+
 /*
  * Unlike the other levels, we do not enforce keeping a
  * multicore group inside a NUMA node.  If this happens, we will
@@ -523,7 +540,7 @@ static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 }
 
 
-#if defined(CONFIG_SCHED_SMT) || defined(CONFIG_SCHED_MC)
+#if defined(CONFIG_SCHED_SMT) || defined(CONFIG_SCHED_CLUSTER) || defined(CONFIG_SCHED_MC)
 static inline int x86_sched_itmt_flags(void)
 {
 	return sysctl_sched_itmt_enabled ? SD_ASYM_PACKING : 0;
@@ -541,12 +558,21 @@ static int x86_smt_flags(void)
 	return cpu_smt_flags() | x86_sched_itmt_flags();
 }
 #endif
+#ifdef CONFIG_SCHED_CLUSTER
+static int x86_cluster_flags(void)
+{
+	return cpu_cluster_flags() | x86_sched_itmt_flags();
+}
+#endif
 #endif
 
 static struct sched_domain_topology_level x86_numa_in_package_topology[] = {
 #ifdef CONFIG_SCHED_SMT
 	{ cpu_smt_mask, x86_smt_flags, SD_INIT_NAME(SMT) },
 #endif
+#ifdef CONFIG_SCHED_CLUSTER
+	{ cpu_clustergroup_mask, x86_cluster_flags, SD_INIT_NAME(CLS) },
+#endif
 #ifdef CONFIG_SCHED_MC
 	{ cpu_coregroup_mask, x86_core_flags, SD_INIT_NAME(MC) },
 #endif
@@ -557,6 +583,9 @@ static struct sched_domain_topology_level x86_topology[] = {
 #ifdef CONFIG_SCHED_SMT
 	{ cpu_smt_mask, x86_smt_flags, SD_INIT_NAME(SMT) },
 #endif
+#ifdef CONFIG_SCHED_CLUSTER
+	{ cpu_clustergroup_mask, x86_cluster_flags, SD_INIT_NAME(CLS) },
+#endif
 #ifdef CONFIG_SCHED_MC
 	{ cpu_coregroup_mask, x86_core_flags, SD_INIT_NAME(MC) },
 #endif
@@ -584,6 +613,7 @@ void set_cpu_sibling_map(int cpu)
 	if (!has_mp) {
 		cpumask_set_cpu(cpu, topology_sibling_cpumask(cpu));
 		cpumask_set_cpu(cpu, cpu_llc_shared_mask(cpu));
+		cpumask_set_cpu(cpu, cpu_l2c_shared_mask(cpu));
 		cpumask_set_cpu(cpu, topology_core_cpumask(cpu));
 		cpumask_set_cpu(cpu, topology_die_cpumask(cpu));
 		c->booted_cores = 1;
@@ -602,6 +632,9 @@ void set_cpu_sibling_map(int cpu)
 		if ((i == cpu) || (has_mp && match_llc(c, o)))
 			link_mask(cpu_llc_shared_mask, cpu, i);
 
+		if ((i == cpu) || (has_mp && match_l2c(c, o)))
+			link_mask(cpu_l2c_shared_mask, cpu, i);
+
 		if ((i == cpu) || (has_mp && match_die(c, o)))
 			link_mask(topology_die_cpumask, cpu, i);
 	}
@@ -649,6 +682,11 @@ const struct cpumask *cpu_coregroup_mask(int cpu)
 	return cpu_llc_shared_mask(cpu);
 }
 
+const struct cpumask *cpu_clustergroup_mask(int cpu)
+{
+	return cpu_l2c_shared_mask(cpu);
+}
+
 static void impress_friends(void)
 {
 	int cpu;
@@ -1332,6 +1370,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 		zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
 		zalloc_cpumask_var(&per_cpu(cpu_die_map, i), GFP_KERNEL);
 		zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL);
+		zalloc_cpumask_var(&per_cpu(cpu_l2c_shared_map, i), GFP_KERNEL);
 	}
 
 	/*
@@ -1556,7 +1595,10 @@ static void remove_siblinginfo(int cpu)
 		cpumask_clear_cpu(cpu, topology_sibling_cpumask(sibling));
 	for_each_cpu(sibling, cpu_llc_shared_mask(cpu))
 		cpumask_clear_cpu(cpu, cpu_llc_shared_mask(sibling));
+	for_each_cpu(sibling, cpu_l2c_shared_mask(cpu))
+		cpumask_clear_cpu(cpu, cpu_l2c_shared_mask(sibling));
 	cpumask_clear(cpu_llc_shared_mask(cpu));
+	cpumask_clear(cpu_l2c_shared_mask(cpu));
 	cpumask_clear(topology_sibling_cpumask(cpu));
 	cpumask_clear(topology_core_cpumask(cpu));
 	cpumask_clear(topology_die_cpumask(cpu));
-- 
2.25.1



From qii.wang at mediatek.com  Thu Aug 19 18:46:21 2021
From: qii.wang at mediatek.com (Qii Wang)
Date: Fri, 20 Aug 2021 09:46:21 +0800
Subject: [PATCH v2 2/5] i2c: mt65xx: fix IRQ check
In-Reply-To: <YRwXZVxORTpddj2k@kunai>
References: <3712e871-bf2f-32c5-f9c2-2968c42087f8@omp.ru>
 <bab29007-8d74-0a68-2378-9db6ba0bc576@omp.ru> <YRwXZVxORTpddj2k@kunai>
Message-ID: <1629423981.19334.3.camel@mhfsdcap03>

On Tue, 2021-08-17 at 22:09 +0200, Wolfram Sang wrote:
> On Sun, Jul 04, 2021 at 05:38:45PM +0300, Sergey Shtylyov wrote:
> > Iff platform_get_irq() returns 0, the driver's probe() method will return 0
> > early (as if the method's call was successful).  Let's consider IRQ0 valid
> > for simplicity -- devm_request_irq() can always override that decision...
> > 
> > Fixes: ce38815d39ea ("I2C: mediatek: Add driver for MediaTek I2C controller")
> > Signed-off-by: Sergey Shtylyov <s.shtylyov at omprussia.ru>
> 
> Qii Wang, do you like this patch?
> 

It is ok.
Reviewed-by: Qii Wang <qii.wang at mediatek.com>

Thanks

> > 
> > ---
> >  drivers/i2c/busses/i2c-mt65xx.c |    2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > Index: linux/drivers/i2c/busses/i2c-mt65xx.c
> > ===================================================================
> > --- linux.orig/drivers/i2c/busses/i2c-mt65xx.c
> > +++ linux/drivers/i2c/busses/i2c-mt65xx.c
> > @@ -1211,7 +1211,7 @@ static int mtk_i2c_probe(struct platform
> >  		return PTR_ERR(i2c->pdmabase);
> >  
> >  	irq = platform_get_irq(pdev, 0);
> > -	if (irq <= 0)
> > +	if (irq < 0)
> >  		return irq;
> >  
> >  	init_completion(&i2c->msg_complete);


From cgel.zte at gmail.com  Thu Aug 19 19:20:54 2021
From: cgel.zte at gmail.com (jing yangyang)
Date: Thu, 19 Aug 2021 19:20:54 -0700
Subject: [PATCH linux-next] clk/keystone: fix application of sizeof to pointer
Message-ID: <84a6ba16686347099a3dab2e5161a930e792eb6e.1629198281.git.jing.yangyang@zte.com.cn>

sizeof when applied to a pointer typed expression gives the size of
the pointer.

./drivers/clk/keystone/sci-clk.c:398:8-14: ERROR application of sizeof to pointer

This issue was detected with the help of Coccinelle.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
---
 drivers/clk/keystone/sci-clk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
index 7e1b136..010a61a 100644
--- a/drivers/clk/keystone/sci-clk.c
+++ b/drivers/clk/keystone/sci-clk.c
@@ -395,7 +395,7 @@ static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
 	key.clk_id = clkspec->args[1];
 
 	clk = bsearch(&key, provider->clocks, provider->num_clocks,
-		      sizeof(clk), _cmp_sci_clk);
+		      sizeof(*clk), _cmp_sci_clk);
 
 	if (!clk)
 		return ERR_PTR(-ENODEV);
-- 
1.8.3.1




From cgel.zte at gmail.com  Thu Aug 19 19:30:16 2021
From: cgel.zte at gmail.com (jing yangyang)
Date: Thu, 19 Aug 2021 19:30:16 -0700
Subject: [PATCH linux-next] firmware/psci: fix application of sizeof to pointer
Message-ID: <61d3cc7e5cd4a819381fcb22e1853d6f48a0c927.1629212319.git.jing.yangyang@zte.com.cn>

sizeof when applied to a pointer typed expression gives the size of
the pointer.

./drivers/firmware/psci/psci_checker.c:158:41-47: ERROR application of sizeof to pointer

This issue was detected with the help of Coccinelle.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
---
 drivers/firmware/psci/psci_checker.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c
index 9a369a2..116eb46 100644
--- a/drivers/firmware/psci/psci_checker.c
+++ b/drivers/firmware/psci/psci_checker.c
@@ -155,7 +155,7 @@ static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups)
 	if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
 		return -ENOMEM;
 
-	cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups),
+	cpu_groups = kcalloc(nb_available_cpus, sizeof(*cpu_groups),
 			     GFP_KERNEL);
 	if (!cpu_groups) {
 		free_cpumask_var(tmp);
-- 
1.8.3.1




From jianjun.wang at mediatek.com  Thu Aug 19 19:35:21 2021
From: jianjun.wang at mediatek.com (Jianjun Wang)
Date: Fri, 20 Aug 2021 10:35:21 +0800
Subject: [PATCH] dt-bindings: PCI: mediatek-gen3: Add support for MT8195
Message-ID: <20210820023521.30716-1-jianjun.wang@mediatek.com>

MT8195 is an ARM platform SoC which has the same PCIe IP with MT8192.

Signed-off-by: Jianjun Wang <jianjun.wang at mediatek.com>
---
 Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
index 742206dbd965..dcebb1036207 100644
--- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
@@ -48,7 +48,9 @@ allOf:
 
 properties:
   compatible:
-    const: mediatek,mt8192-pcie
+    oneOf:
+      - const: mediatek,mt8192-pcie
+      - const: mediatek,mt8195-pcie
 
   reg:
     maxItems: 1
-- 
2.18.0

From samuel at sholland.org  Thu Aug 19 19:41:26 2021
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 19 Aug 2021 21:41:26 -0500
Subject: [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
In-Reply-To: <20210802062212.73220-12-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-12-icenowy@sipeed.com>
Message-ID: <3e56e53f-e6df-50cf-5545-e9132e521ed1@sholland.org>

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 has a CCU that is similar to the H616 one, but it's cut
> down and have PLLs moved out.
> 
> Add support for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig                |   5 +
>  drivers/clk/sunxi-ng/Makefile               |   1 +
>  drivers/clk/sunxi-ng/ccu-sun50i-r329.c      | 526 ++++++++++++++++++++
>  drivers/clk/sunxi-ng/ccu-sun50i-r329.h      |  32 ++
>  include/dt-bindings/clock/sun50i-r329-ccu.h |  73 +++
>  include/dt-bindings/reset/sun50i-r329-ccu.h |  45 ++
>  6 files changed, 682 insertions(+)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
>  create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
>  create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
> 
> diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> index e49b2c2fa5b7..4b32d5f81ea8 100644
> --- a/drivers/clk/sunxi-ng/Kconfig
> +++ b/drivers/clk/sunxi-ng/Kconfig
> @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
>  	default ARM64 && ARCH_SUNXI
>  	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
>  
> +config SUN50I_R329_CCU
> +	bool "Support for the Allwinner R329 CCU"
> +	default ARM64 && ARCH_SUNXI
> +	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> +
>  config SUN50I_R329_R_CCU
>  	bool "Support for the Allwinner R329 PRCM CCU"
>  	default ARM64 && ARCH_SUNXI
> diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> index db338a2188fd..62f3c5bf331c 100644
> --- a/drivers/clk/sunxi-ng/Makefile
> +++ b/drivers/clk/sunxi-ng/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
>  obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
>  obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
>  obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
> +obj-$(CONFIG_SUN50I_R329_CCU)	+= ccu-sun50i-r329.o
>  obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
>  obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
>  obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> new file mode 100644
> index 000000000000..a0b4cfd6e1db
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> @@ -0,0 +1,526 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Based on the H616 CCU driver, which is:
> + *   Copyright (c) 2020 Arm Ltd.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +
> +#include "ccu_common.h"
> +#include "ccu_reset.h"
> +
> +#include "ccu_div.h"
> +#include "ccu_gate.h"
> +#include "ccu_mp.h"
> +#include "ccu_mult.h"
> +#include "ccu_nk.h"
> +#include "ccu_nkm.h"
> +#include "ccu_nkmp.h"
> +#include "ccu_nm.h"
> +
> +#include "ccu-sun50i-r329.h"
> +
> +/*
> + * An external divider of PLL-CPUX is controlled here. As it's similar to
> + * the external divider of PLL-CPUX on previous SoCs (only usable under
> + * 288MHz}, ignore it.

Mismatched (braces} here

> + */
> +static const char * const cpux_parents[] = { "osc24M", "osc32k", "iosc",
> +					     "pll-cpux", "pll-periph",
> +					     "pll-periph-2x",
> +					     "pll=periph-800m" };

= should be a -.

Now that these PLLs are in a different device, how is this supposed to affect
the DT binding? Do we put all of them in the clocks property?

If so, we can use .fw_name at some point. If not, why bother with the clocks
property at all? This is another part of the "let's get the clock tree right
from the start" discussion.

> +static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
> +		     0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
> +static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
> +static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0);
> +
> +static const char * const ahb_parents[] = { "osc24M", "osc32k",
> +					    "iosc", "pll-periph" };
> +static SUNXI_CCU_MP_WITH_MUX(ahb_clk, "ahb",
> +			     ahb_parents, 0x510,
> +			     0, 2,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);
> +
> +static const char * const apb_parents[] = { "osc24M", "osc32k",
> +					    "ahb", "pll-periph" };
> +static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb_parents, 0x520,
> +			     0, 2,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);
> +
> +static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb_parents, 0x524,
> +			     0, 2,	/* M */
> +			     8, 2,	/* P */
> +			     24, 3,	/* mux */
> +			     0);

Hmm, so Allwinner is inconsistent with these. The manual has APB0/APB1, but the
BSP has APB1/APB2.

> +
> +static const char * const ce_parents[] = { "osc24M", "pll-periph-2x" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 1,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb",
> +		      0x68c, BIT(0), 0);
> +
> +static const char * const aipu_parents[] = { "pll-periph-2x", "pll-periph-800m",
> +					     "pll-audio0-div2", "pll-audio0-div5",
> +					     "pll-cpux" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(aipu_clk, "aipu", aipu_parents, 0x6f0,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_aipu_clk, "bus-aipu", "ahb",
> +		      0x6fc, BIT(0), 0);

The manual has separate gates for an AIPU AHB master at bit 1, and an AHB slave
at bit 0.

> +
> +static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb",
> +		      0x70c, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb",
> +		      0x71c, BIT(0), 0);

There are two message boxes (bits 0 and 1).

> +
> +static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb",
> +		      0x72c, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb",
> +		      0x73c, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x740, BIT(31), 0);
> +
> +static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb",
> +		      0x78c, BIT(0), 0);

There is a gate for the PSI clock (the parent for the AHB clocks) at 0x79c.

> +
> +static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
> +
> +static const char * const dram_parents[] = { "pll-periph-2x",
> +					     "pll-periph-800m",
> +					     "pll-audio0-div2",
> +					     "pll-audio0-div5" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(dram_clk, "dram", dram_parents, 0x800,
> +				  0, 2,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  CLK_IS_CRITICAL);
> +
> +
> +static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "dram",
> +		      0x804, BIT(0), 0);
> +static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "dram",
> +		      0x804, BIT(2), 0);
> +static SUNXI_CCU_GATE(mbus_r_dma_clk, "mbus-r-dma", "dram",
> +		      0x804, BIT(3), 0);
> +static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "dram",
> +		      0x804, BIT(5), 0);
> +static SUNXI_CCU_GATE(mbus_aipu_clk, "mbus-aipu", "dram",
> +		      0x804, BIT(16), 0);
> +
> +static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb",
> +		      0x80c, BIT(0), CLK_IS_CRITICAL);

The DRAM bus clock is not critical. It only needs to be enabled for register
access (PMU, DVFS).

> +
> +static const char * const nand_parents[] = { "osc24M", "pll-periph",
> +					     "pll-audio-div2",
> +					     "pll-periph-2x" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_parents, 0x810,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_parents, 0x814,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb", 0x82c, BIT(0), 0);
> +
> +static const char * const mmc_parents[] = { "osc24M", "pll-periph",
> +					    "pll-periph-2x",
> +					    "pll-audio0-div2" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
> +					  0, 4,		/* M */
> +					  8, 2,		/* P */
> +					  24, 2,	/* mux */
> +					  BIT(31),	/* gate */
> +					  2,		/* post-div */
> +					  0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
> +					  0, 4,		/* M */
> +					  8, 2,		/* P */
> +					  24, 2,	/* mux */
> +					  BIT(31),	/* gate */
> +					  2,		/* post-div */

Where does the post-divider come from?

> +					  0);
> +
> +static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb", 0x84c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb", 0x84c, BIT(1), 0);
> +
> +static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0);
> +static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0);
> +static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0);
> +
> +static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0);
> +
> +static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", 0x93c, BIT(0), 0);
> +
> +static const char * const spi_parents[] = { "osc24M", "pll-periph",
> +					    "pll-periph-2x",
> +					    "pll-audio0-div2",
> +					    "pll-audio0-div5" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 3,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb", 0x96c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb", 0x96c, BIT(1), 0);
> +
> +static CLK_FIXED_FACTOR(emac_25m_div_clk, "emac-25m-div", "pll-periph",
> +			2, 1, 0);
> +static SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "emac-25m-div", 0x970,
> +		      BIT(31) | BIT(30), 0);

The divider should be 24, not 2. And you can use CCU_FEATURE_ALL_PREDIV on the
gate to remove the separate divider clock.

> +
> +static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb", 0x97c, BIT(0), 0);
> +
> +static const char * const ir_parents[] = { "osc32k", "iosc",

Both the manual and the BSP have the second parent as osc24M, not iosc.

> +					   "pll-periph", "pll-audio0-div2" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents, 0x990,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "apb1", 0x99c, BIT(0), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents, 0x9c0,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0);
> +
> +static const char * const audio_parents[] = { "pll-audio1",
> +					      "pll-audio1-4x",
> +					      "pll-audio0-div2",
> +					      "pll-audio0-div5" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(i2s0_clk, "i2s0", audio_parents, 0xa10,
> +				  0, 4,		/* M */

All of the audio modules have 5-bit M dividers.

> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(i2s1_clk, "i2s1", audio_parents, 0xa14,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spdif_clk, "spdif", audio_parents, 0xa20,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 2,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0);
> +
> +/*
> + * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports.
> + * We will force them to 0 (12M divided from 48M).
> + */
> +#define SUN50I_R329_USB0_CLK_REG		0xa70
> +#define SUN50I_R329_USB1_CLK_REG		0xa74

This "48M" clock is divided/synchronized from pll-periph, as shown in the
"Module Clock Generation" diagram and USB "PHY Connection Diagram" in the
manual. So I recommend the following structure:

static CLK_FIXED_FACTOR(usb_48M_clk, "usb-48M",
                        "pll-periph", 25, 2, 0);

static CLK_FIXED_FACTOR_HW(usb_12M_clk, "usb-12M",
                           &usb_48M_clk.hw, 4, 1, 0);

static const char *const usb_ohci_parents[] = { "usb-12M", "osc12M",
                                                "osc32k" };
static SUNXI_CCU_MUX_WITH_GATE(usb_ohci0_clk, "usb-ohci0",
                               usb_ohci_parents, 0xa70,
                               24, 2,           /* mux */
                               BIT(31),         /* gate */
                               0);

static SUNXI_CCU_MUX_WITH_GATE(usb_ohci1_clk, "usb-ohci1",
                               usb_ohci_parents, 0xa74,
                               24, 2,           /* mux */
                               BIT(31),         /* gate */
                               0);

For anyone following along without R329 documents, this is all the same as the
D1, though the labels in the diagrams are slightly different. Hooray for finally
documenting this so it is no longer "mysterious"!

Regards,
Samuel

> +
> +static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0);
> +static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0xa70, BIT(29), 0);
> +
> +static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0);
> +static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0xa74, BIT(29), 0);
> +
> +static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb", 0xa8c, BIT(0), 0);
> +static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb", 0xa8c, BIT(1), 0);
> +static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb", 0xa8c, BIT(4), 0);
> +static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb", 0xa8c, BIT(8), 0);
> +
> +static const char * const ledc_parents[] = { "osc24M", "pll-periph" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ledc_clk, "ledc", ledc_parents, 0xbf0,
> +				  0, 4,		/* M */
> +				  8, 2,		/* P */
> +				  24, 1,	/* mux */
> +				  BIT(31),	/* gate */
> +				  0);
> +
> +static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "apb1", 0xbfc, BIT(0), 0);
> +
> +/* Fixed factor clocks */
> +static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
> +
> +static struct ccu_common *sun50i_r329_ccu_clks[] = {
> +	&cpux_clk.common,
> +	&axi_clk.common,
> +	&cpux_apb_clk.common,
> +	&ahb_clk.common,
> +	&apb1_clk.common,
> +	&apb2_clk.common,
> +	&ce_clk.common,
> +	&bus_ce_clk.common,
> +	&aipu_clk.common,
> +	&bus_aipu_clk.common,
> +	&bus_dma_clk.common,
> +	&bus_msgbox_clk.common,
> +	&bus_spinlock_clk.common,
> +	&bus_hstimer_clk.common,
> +	&avs_clk.common,
> +	&bus_dbg_clk.common,
> +	&bus_pwm_clk.common,
> +	&dram_clk.common,
> +	&mbus_dma_clk.common,
> +	&mbus_ce_clk.common,
> +	&mbus_r_dma_clk.common,
> +	&mbus_nand_clk.common,
> +	&mbus_aipu_clk.common,
> +	&bus_dram_clk.common,
> +	&nand0_clk.common,
> +	&nand1_clk.common,
> +	&bus_nand_clk.common,
> +	&mmc0_clk.common,
> +	&mmc1_clk.common,
> +	&bus_mmc0_clk.common,
> +	&bus_mmc1_clk.common,
> +	&bus_uart0_clk.common,
> +	&bus_uart1_clk.common,
> +	&bus_uart2_clk.common,
> +	&bus_uart3_clk.common,
> +	&bus_i2c0_clk.common,
> +	&bus_i2c1_clk.common,
> +	&bus_scr_clk.common,
> +	&spi0_clk.common,
> +	&spi1_clk.common,
> +	&bus_spi0_clk.common,
> +	&bus_spi1_clk.common,
> +	&emac_25m_clk.common,
> +	&bus_emac_clk.common,
> +	&ir_rx_clk.common,
> +	&bus_ir_rx_clk.common,
> +	&ir_tx_clk.common,
> +	&bus_ir_tx_clk.common,
> +	&i2s0_clk.common,
> +	&i2s1_clk.common,
> +	&bus_i2s0_clk.common,
> +	&bus_i2s1_clk.common,
> +	&spdif_clk.common,
> +	&bus_spdif_clk.common,
> +	&usb_ohci0_clk.common,
> +	&usb_phy0_clk.common,
> +	&usb_ohci1_clk.common,
> +	&usb_phy1_clk.common,
> +	&bus_ohci0_clk.common,
> +	&bus_ohci1_clk.common,
> +	&bus_ehci0_clk.common,
> +	&bus_otg_clk.common,
> +	&ledc_clk.common,
> +	&bus_ledc_clk.common,
> +};
> +
> +static struct clk_hw_onecell_data sun50i_r329_hw_clks = {
> +	.hws	= {
> +		[CLK_OSC12M]		= &osc12M_clk.hw,
> +		[CLK_CPUX]		= &cpux_clk.common.hw,
> +		[CLK_AXI]		= &axi_clk.common.hw,
> +		[CLK_CPUX_APB]		= &cpux_apb_clk.common.hw,
> +		[CLK_AHB]		= &ahb_clk.common.hw,
> +		[CLK_APB1]		= &apb1_clk.common.hw,
> +		[CLK_APB2]		= &apb2_clk.common.hw,
> +		[CLK_CE]		= &ce_clk.common.hw,
> +		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
> +		[CLK_AIPU]		= &aipu_clk.common.hw,
> +		[CLK_BUS_AIPU]		= &bus_aipu_clk.common.hw,
> +		[CLK_BUS_DMA]		= &bus_dma_clk.common.hw,
> +		[CLK_BUS_MSGBOX]	= &bus_msgbox_clk.common.hw,
> +		[CLK_BUS_SPINLOCK]	= &bus_spinlock_clk.common.hw,
> +		[CLK_BUS_HSTIMER]	= &bus_hstimer_clk.common.hw,
> +		[CLK_AVS]		= &avs_clk.common.hw,
> +		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
> +		[CLK_BUS_PWM]		= &bus_pwm_clk.common.hw,
> +		[CLK_DRAM]		= &dram_clk.common.hw,
> +		[CLK_MBUS_DMA]		= &mbus_dma_clk.common.hw,
> +		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
> +		[CLK_MBUS_R_DMA]	= &mbus_r_dma_clk.common.hw,
> +		[CLK_MBUS_NAND]		= &mbus_nand_clk.common.hw,
> +		[CLK_MBUS_AIPU]		= &mbus_aipu_clk.common.hw,
> +		[CLK_BUS_DRAM]		= &bus_dram_clk.common.hw,
> +		[CLK_NAND0]		= &nand0_clk.common.hw,
> +		[CLK_NAND1]		= &nand1_clk.common.hw,
> +		[CLK_BUS_NAND]		= &bus_nand_clk.common.hw,
> +		[CLK_MMC0]		= &mmc0_clk.common.hw,
> +		[CLK_MMC1]		= &mmc1_clk.common.hw,
> +		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
> +		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
> +		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
> +		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
> +		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
> +		[CLK_BUS_UART3]		= &bus_uart3_clk.common.hw,
> +		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
> +		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
> +		[CLK_BUS_SCR]		= &bus_scr_clk.common.hw,
> +		[CLK_SPI0]		= &spi0_clk.common.hw,
> +		[CLK_SPI1]		= &spi1_clk.common.hw,
> +		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
> +		[CLK_BUS_SPI1]		= &bus_spi1_clk.common.hw,
> +		[CLK_EMAC_25M_DIV]	= &emac_25m_div_clk.hw,
> +		[CLK_EMAC_25M]		= &emac_25m_clk.common.hw,
> +		[CLK_BUS_EMAC]		= &bus_emac_clk.common.hw,
> +		[CLK_IR_RX]		= &ir_rx_clk.common.hw,
> +		[CLK_BUS_IR_RX]		= &bus_ir_rx_clk.common.hw,
> +		[CLK_IR_TX]		= &ir_tx_clk.common.hw,
> +		[CLK_BUS_IR_TX]		= &bus_ir_tx_clk.common.hw,
> +		[CLK_I2S0]		= &i2s0_clk.common.hw,
> +		[CLK_I2S1]		= &i2s1_clk.common.hw,
> +		[CLK_BUS_I2S0]		= &bus_i2s0_clk.common.hw,
> +		[CLK_BUS_I2S1]		= &bus_i2s1_clk.common.hw,
> +		[CLK_SPDIF]		= &spdif_clk.common.hw,
> +		[CLK_BUS_SPDIF]		= &bus_spdif_clk.common.hw,
> +		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
> +		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
> +		[CLK_USB_OHCI1]		= &usb_ohci1_clk.common.hw,
> +		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
> +		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
> +		[CLK_BUS_OHCI1]		= &bus_ohci1_clk.common.hw,
> +		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
> +		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
> +		[CLK_LEDC]		= &ledc_clk.common.hw,
> +		[CLK_BUS_LEDC]		= &bus_ledc_clk.common.hw,
> +	},
> +	.num = CLK_NUMBER,
> +};
> +
> +static struct ccu_reset_map sun50i_r329_ccu_resets[] = {
> +	[RST_MBUS]		= { 0x540, BIT(30) },
> +
> +	[RST_BUS_CE]		= { 0x68c, BIT(16) },
> +	[RST_BUS_AIPU]		= { 0x6fc, BIT(16) },
> +	[RST_BUS_DMA]		= { 0x70c, BIT(16) },
> +	[RST_BUS_MSGBOX]	= { 0x71c, BIT(16) },
> +	[RST_BUS_SPINLOCK]	= { 0x72c, BIT(16) },
> +	[RST_BUS_HSTIMER]	= { 0x73c, BIT(16) },
> +	[RST_BUS_DBG]		= { 0x78c, BIT(16) },
> +	[RST_BUS_PWM]		= { 0x7ac, BIT(16) },
> +	[RST_BUS_DRAM]		= { 0x80c, BIT(16) },
> +	[RST_BUS_NAND]		= { 0x82c, BIT(16) },
> +	[RST_BUS_MMC0]		= { 0x84c, BIT(16) },
> +	[RST_BUS_MMC1]		= { 0x84c, BIT(17) },
> +	[RST_BUS_UART0]		= { 0x90c, BIT(16) },
> +	[RST_BUS_UART1]		= { 0x90c, BIT(17) },
> +	[RST_BUS_UART2]		= { 0x90c, BIT(18) },
> +	[RST_BUS_UART3]		= { 0x90c, BIT(19) },
> +	[RST_BUS_I2C0]		= { 0x91c, BIT(16) },
> +	[RST_BUS_I2C1]		= { 0x91c, BIT(17) },
> +	[RST_BUS_SCR]		= { 0x93c, BIT(16) },
> +	[RST_BUS_SPI0]		= { 0x96c, BIT(16) },
> +	[RST_BUS_SPI1]		= { 0x96c, BIT(17) },
> +	[RST_BUS_EMAC]		= { 0x97c, BIT(16) },
> +	[RST_BUS_IR_RX]		= { 0x99c, BIT(16) },
> +	[RST_BUS_IR_TX]		= { 0x9cc, BIT(16) },
> +	[RST_BUS_I2S0]		= { 0xa1c, BIT(16) },
> +	[RST_BUS_I2S1]		= { 0xa1c, BIT(17) },
> +	[RST_BUS_SPDIF]		= { 0xa2c, BIT(16) },
> +
> +	[RST_USB_PHY0]		= { 0xa70, BIT(30) },
> +	[RST_USB_PHY1]		= { 0xa74, BIT(30) },
> +
> +	[RST_BUS_OHCI0]		= { 0xa8c, BIT(16) },
> +	[RST_BUS_OHCI1]		= { 0xa8c, BIT(17) },
> +	[RST_BUS_EHCI0]		= { 0xa8c, BIT(20) },
> +	[RST_BUS_OTG]		= { 0xa8c, BIT(24) },
> +
> +	[RST_BUS_LEDC]		= { 0xbfc, BIT(16) },
> +};
> +
> +static const struct sunxi_ccu_desc sun50i_r329_ccu_desc = {
> +	.ccu_clks	= sun50i_r329_ccu_clks,
> +	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_ccu_clks),
> +
> +	.hw_clks	= &sun50i_r329_hw_clks,
> +
> +	.resets		= sun50i_r329_ccu_resets,
> +	.num_resets	= ARRAY_SIZE(sun50i_r329_ccu_resets),
> +};
> +
> +static const u32 sun50i_r329_usb_clk_regs[] = {
> +	SUN50I_R329_USB0_CLK_REG,
> +	SUN50I_R329_USB1_CLK_REG,
> +};
> +
> +static int sun50i_r329_ccu_probe(struct platform_device *pdev)
> +{
> +	void __iomem *reg;
> +	u32 val;
> +	int i;
> +
> +	reg = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(reg))
> +		return PTR_ERR(reg);
> +
> +	/*
> +	 * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz)
> +	 *
> +	 * This clock mux is still mysterious, and the code just enforces
> +	 * it to have a valid clock parent.
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(sun50i_r329_usb_clk_regs); i++) {
> +		val = readl(reg + sun50i_r329_usb_clk_regs[i]);
> +		val &= ~GENMASK(25, 24);
> +		writel(val, reg + sun50i_r329_usb_clk_regs[i]);
> +	}
> +
> +	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_r329_ccu_desc);
> +}
> +
> +static const struct of_device_id sun50i_r329_ccu_ids[] = {
> +	{ .compatible = "allwinner,sun50i-r329-ccu" },
> +	{ }
> +};
> +
> +static struct platform_driver sun50i_r329_ccu_driver = {
> +	.probe	= sun50i_r329_ccu_probe,
> +	.driver	= {
> +		.name	= "sun50i-r329-ccu",
> +		.of_match_table	= sun50i_r329_ccu_ids,
> +	},
> +};
> +module_platform_driver(sun50i_r329_ccu_driver);
> diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.h b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> new file mode 100644
> index 000000000000..144ac9954ef3
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _CCU_SUN50I_R329_H_
> +#define _CCU_SUN50I_R329_H_
> +
> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> +
> +#define CLK_OSC12M		0
> +
> +/* CPUX exported for DVFS */
> +
> +#define CLK_AXI			2
> +#define CLK_CPUX_APB		3
> +#define CLK_AHB			4
> +
> +/* APB1 exported for PIO */
> +
> +#define CLK_APB2		6
> +
> +/* Peripheral module and gate clock exported except for DRAM ones */
> +
> +#define CLK_DRAM		18
> +
> +#define CLK_BUS_DRAM		24
> +
> +#define CLK_NUMBER		(CLK_BUS_LEDC + 1)
> +
> +#endif /* _CCU_SUN50I_R329_H_ */
> diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h b/include/dt-bindings/clock/sun50i-r329-ccu.h
> new file mode 100644
> index 000000000000..116f8d13a9b3
> --- /dev/null
> +++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
> +#define _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
> +
> +#define CLK_CPUX		1
> +
> +#define CLK_APB1		5
> +
> +#define CLK_CE			7
> +#define CLK_BUS_CE		8
> +#define CLK_AIPU		9
> +#define CLK_BUS_AIPU		10
> +#define CLK_BUS_DMA		11
> +#define CLK_BUS_MSGBOX		12
> +#define CLK_BUS_SPINLOCK	13
> +#define CLK_BUS_HSTIMER		14
> +#define CLK_AVS			15
> +#define CLK_BUS_DBG		16
> +#define CLK_BUS_PWM		17
> +
> +#define CLK_MBUS_DMA		19
> +#define CLK_MBUS_CE		20
> +#define CLK_MBUS_R_DMA		21
> +#define CLK_MBUS_NAND		22
> +#define CLK_MBUS_AIPU		23
> +
> +#define CLK_NAND0		25
> +#define CLK_NAND1		26
> +#define CLK_BUS_NAND		27
> +#define CLK_MMC0		28
> +#define CLK_MMC1		29
> +#define CLK_BUS_MMC0		30
> +#define CLK_BUS_MMC1		31
> +#define CLK_BUS_UART0		32
> +#define CLK_BUS_UART1		33
> +#define CLK_BUS_UART2		34
> +#define CLK_BUS_UART3		35
> +#define CLK_BUS_I2C0		36
> +#define CLK_BUS_I2C1		37
> +#define CLK_BUS_SCR		38
> +#define CLK_SPI0		39
> +#define CLK_SPI1		40
> +#define CLK_BUS_SPI0		41
> +#define CLK_BUS_SPI1		42
> +#define CLK_EMAC_25M_DIV	43
> +#define CLK_EMAC_25M		44
> +#define CLK_BUS_EMAC		45
> +#define CLK_IR_RX		46
> +#define CLK_BUS_IR_RX		47
> +#define CLK_IR_TX		48
> +#define CLK_BUS_IR_TX		49
> +#define CLK_I2S0		50
> +#define CLK_I2S1		51
> +#define CLK_BUS_I2S0		52
> +#define CLK_BUS_I2S1		53
> +#define CLK_SPDIF		54
> +#define CLK_BUS_SPDIF		55
> +#define CLK_USB_OHCI0		56
> +#define CLK_USB_PHY0		57
> +#define CLK_USB_OHCI1		58
> +#define CLK_USB_PHY1		59
> +#define CLK_BUS_OHCI0		60
> +#define CLK_BUS_OHCI1		61
> +#define CLK_BUS_EHCI0		62
> +#define CLK_BUS_OTG		63
> +#define CLK_LEDC		64
> +#define CLK_BUS_LEDC		65
> +
> +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_ */
> diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h b/include/dt-bindings/reset/sun50i-r329-ccu.h
> new file mode 100644
> index 000000000000..bb704a82443f
> --- /dev/null
> +++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> +/*
> + * Copyright (c) 2021 Sipeed
> + */
> +
> +#ifndef _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
> +#define _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
> +
> +#define RST_MBUS		0
> +#define RST_BUS_CE		1
> +#define RST_BUS_AIPU		2
> +#define RST_BUS_DMA		3
> +#define RST_BUS_MSGBOX		4
> +#define RST_BUS_SPINLOCK	5
> +#define RST_BUS_HSTIMER		6
> +#define RST_BUS_DBG		7
> +#define RST_BUS_PWM		8
> +#define RST_BUS_DRAM		9
> +#define RST_BUS_NAND		10
> +#define RST_BUS_MMC0		11
> +#define RST_BUS_MMC1		12
> +#define RST_BUS_UART0		13
> +#define RST_BUS_UART1		14
> +#define RST_BUS_UART2		15
> +#define RST_BUS_UART3		16
> +#define RST_BUS_I2C0		17
> +#define RST_BUS_I2C1		18
> +#define RST_BUS_SCR		19
> +#define RST_BUS_SPI0		20
> +#define RST_BUS_SPI1		21
> +#define RST_BUS_EMAC		22
> +#define RST_BUS_IR_RX		23
> +#define RST_BUS_IR_TX		24
> +#define RST_BUS_I2S0		25
> +#define RST_BUS_I2S1		26
> +#define RST_BUS_SPDIF		27
> +#define RST_USB_PHY0		28
> +#define RST_USB_PHY1		29
> +#define RST_BUS_OHCI0		30
> +#define RST_BUS_OHCI1		31
> +#define RST_BUS_EHCI0		32
> +#define RST_BUS_OTG		33
> +#define RST_BUS_LEDC		34
> +
> +#endif /* _DT_BINDINGS_RST_SUN50I_R329_CCU_H_ */
> 



From cgel.zte at gmail.com  Thu Aug 19 19:41:17 2021
From: cgel.zte at gmail.com (jing yangyang)
Date: Thu, 19 Aug 2021 19:41:17 -0700
Subject: [PATCH linux-next] net:wireless:mt76: fix boolreturn.cocci warnings
Message-ID: <20210820024117.11688-1-jing.yangyang@zte.com.cn>

./drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c:172:8-9:WARNING:
return of 0/1 in function 'mt7663_usb_sdio_tx_status_data' with return
type bool

Return statements in functions returning bool should use true/false
instead of 1/0.

Generated by: scripts/coccinelle/misc/boolreturn.cocci

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
---
 drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
index 996d48c..bd2939e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
@@ -169,7 +169,7 @@ bool mt7663_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update)
 	mt7615_mac_sta_poll(dev);
 	mt7615_mutex_release(dev);
 
-	return 0;
+	return false;
 }
 EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_status_data);
 
-- 
1.8.3.1




From samuel at sholland.org  Thu Aug 19 19:43:58 2021
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 19 Aug 2021 21:43:58 -0500
Subject: [PATCH 13/17] mmc: sunxi: add support for R329 MMC controllers
In-Reply-To: <20210802062212.73220-14-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-14-icenowy@sipeed.com>
Message-ID: <9000e312-a0d7-fa52-0a48-439312e12572@sholland.org>

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> The two MMC controllers in Allwinner R329 have a mixed feature set
> comparing to the previous SoCs' ordinary MMC and eMMC controllers.
> 
> Add support for them.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  drivers/mmc/host/sunxi-mmc.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)

Reviewed-by: Samuel Holland <samuel at sholland.org>


From samuel at sholland.org  Thu Aug 19 19:59:08 2021
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 19 Aug 2021 21:59:08 -0500
Subject: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
In-Reply-To: <20210802062212.73220-16-icenowy@sipeed.com>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-16-icenowy@sipeed.com>
Message-ID: <6863e247-9ae5-0f90-bf99-8989efd45352@sholland.org>

On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> Allwinner R329 is a new SoC focused on smart audio devices.
> 
> Add a DTSI file for it.
> 
> Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> ---
>  .../arm64/boot/dts/allwinner/sun50i-r329.dtsi | 244 ++++++++++++++++++
>  1 file changed, 244 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi

One comment below.

All of my other concerns are about the CCU and RTC bindings, which I have
commented on elsewhere.

Regards,
Samuel

> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> new file mode 100644
> index 000000000000..bfefa2b734b0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-r329.dtsi
> @@ -0,0 +1,244 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +// Copyright (c) 2021 Sipeed
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu at 0 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <0>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu1: cpu at 1 {
> +			compatible = "arm,cortex-a53";
> +			device_type = "cpu";
> +			reg = <1>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	osc24M: osc24M_clk {
> +		#clock-cells = <0>;
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "osc24M";
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		arm,no-tick-in-suspend;
> +		interrupts = <GIC_PPI 13
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 11
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 10
> +			(GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		pio: pinctrl at 2000400 {
> +			compatible = "allwinner,sun50i-r329-pinctrl";
> +			reg = <0x02000400 0x400>;
> +			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,

There is an IRQ documented for port C (at SPI 70). Do those pins possibly have
interrupt capability?

> +				     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
> +			clock-names = "apb", "hosc", "losc";
> +			gpio-controller;
> +			#gpio-cells = <3>;
> +			interrupt-controller;
> +			#interrupt-cells = <3>;


From samuel at sholland.org  Thu Aug 19 20:06:43 2021
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 19 Aug 2021 22:06:43 -0500
Subject: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
In-Reply-To: <75ae9ef8-496b-68ca-214e-e8b270648a50@sholland.org>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-16-icenowy@sipeed.com>
 <20210818090139.rllz4fvvq3pzdkls@gilmour>
 <74F51516-2470-4A49-972B-E19D8EDD9A3D@sipeed.com>
 <75ae9ef8-496b-68ca-214e-e8b270648a50@sholland.org>
Message-ID: <8e4a49b8-8f17-d659-0952-0c96b0098139@sholland.org>

On 8/18/21 9:32 PM, Samuel Holland wrote:
> On 8/18/21 4:15 AM, Icenowy Zheng wrote:
>> ? 2021?8?18? GMT+08:00 ??5:01:39, Maxime Ripard <maxime at cerno.tech> ??:
>>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
>>>> +		ccu: clock at 2001000 {
>>>> +			compatible = "allwinner,sun50i-r329-ccu";
>>>> +			reg = <0x02001000 0x1000>;
>>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
>>>> +			clock-names = "hosc", "losc", "iosc";
>>>
>>> Do we have a clock tree for the RTC? Is it the same than the H616?
>>
>> Nope, it's the same with H6 because of external LOSC crystal is
>> possible. (Although production M2A SoMs has it NC for cost control.)
> 
> It is not the same as the H6, either. The clock tree _is_ identical to the D1,
> which has three diagrams on pages 363-364 of its user manual here:
> 
> https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf
> 
> Compared to the H6, the R329/D1:
>  - Loses the LOSC calibration circuit
>  - Gains a third mux input for LOSC (not external 32k) to fanout
>  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
>  - Gains an SPI bus clock input divided from the PRCM AHB
> 
> Compared to the H616, the R329/D1:
>  - Has an external 32k crystal input
>    - Gains the IOSC vs. external 32k crystal mux for LOSC
>    - Switches fanout mux input #1 from pll_periph0/N to external 32k
>  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
>  - Gains an SPI bus clock input divided from the PRCM AHB
> 
> So the R329/D1 RTC has three^Wfour inputs:
>  - SPI clock from PRCM
>  - 24 MHz DCXO crystal
>  - 32 kHz external crystal (optional)

Whoops, I missed one here:
 - Bus clock from PRCM

The SPI clock is new for R329, but the bus clock has been around since H6.

> and four outputs:
>  - 16 MHz "IOSC" RC oscillator
>  - 32 kHz "LOSC"
>  - ~1 kHz for RTC timekeeping

Even though this is internal to the RTC, it is still useful to model, as it can
be used to correct for known RTC drift. (For example, HOSC/750 is 32000 Hz
instead of 32768 Hz, so 2.34375% slow. But that is better than IOSC, which has
unknown error.)

>  - 32 kHz fanout
> 
> (Arguably, since the 24 MHz DCXO can be turned on/off from the RTC registers, it
> should be an "output" and not an "input".)
> 
> Regards,
> Samuel
> 



From cgel.zte at gmail.com  Thu Aug 19 20:19:52 2021
From: cgel.zte at gmail.com (CGEL)
Date: Thu, 19 Aug 2021 20:19:52 -0700
Subject: [PATCH linux-next] spi-stm32: fix Coccinelle warnings
Message-ID: <20210820031952.12746-1-jing.yangyang@zte.com.cn>

From: jing yangyang <jing.yangyang at zte.com.cn>

WARNING !A || A && B is equivalent to !A || B

This issue was detected with the help of Coccinelle.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
---
 drivers/spi/spi-stm32.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index 14ca7ea..cc4a731 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -912,8 +912,8 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
 		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
 			stm32h7_spi_read_rxfifo(spi);
 		if (!spi->cur_usedma ||
-		    (spi->cur_usedma && (spi->cur_comm == SPI_SIMPLEX_TX ||
-		     spi->cur_comm == SPI_3WIRE_TX)))
+			(spi->cur_comm == SPI_SIMPLEX_TX ||
+			spi->cur_comm == SPI_3WIRE_TX))
 			end = true;
 	}
 
-- 
1.8.3.1




From tzungbi at google.com  Thu Aug 19 20:25:23 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri, 20 Aug 2021 11:25:23 +0800
Subject: [PATCH] PCI: mediatek-gen3: Disable DVFSRC voltage request
In-Reply-To: <20210819125939.21253-1-jianjun.wang@mediatek.com>
References: <20210819125939.21253-1-jianjun.wang@mediatek.com>
Message-ID: <YR8go1l0Xnvvqn5E@google.com>

On Thu, Aug 19, 2021 at 08:59:39PM +0800, Jianjun Wang wrote:
> Signed-off-by: Jianjun Wang <jianjun.wang at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>


From swood at redhat.com  Thu Aug 19 20:23:37 2021
From: swood at redhat.com (Scott Wood)
Date: Thu, 19 Aug 2021 22:23:37 -0500
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20210817144018.nqssoq475vitrqlv@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
Message-ID: <20b9051fe47b7068ed3496bd7f5d417b1af69e3a.camel@redhat.com>

On Tue, 2021-08-17 at 16:40 +0200, Sebastian Andrzej Siewior wrote:
> [bigeasy: remove 'preempt_disable(); local_bh_disable(); preempt_enable();
>  local_bh_enable();' from the examples because this works on RT now. ]

Does it actually work?  If preemption is disabled during local_bh_disable,
softirq_ctrl.lock won't be taken.  If you then get preempted between the
preempt_enable() and the local_bh_enable(), and another task tries to do
local_bh_disable(), won't it successfully get softirq_ctrl.lock, add to
softirq_ctrl.cnt, and proceed right into the critical section?

Or am I missing something?

-Scott




From tzungbi at google.com  Thu Aug 19 20:29:32 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Fri, 20 Aug 2021 11:29:32 +0800
Subject: [PATCH v5, 01/15] media: mtk-vcodec: Get numbers of register
 bases from DT
In-Reply-To: <20210811025801.21597-2-yunfei.dong@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-2-yunfei.dong@mediatek.com>
Message-ID: <YR8hnAiKHLpa1bri@google.com>

On Wed, Aug 11, 2021 at 10:57:47AM +0800, Yunfei Dong wrote:
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>


From lkp at intel.com  Thu Aug 19 20:31:20 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 20 Aug 2021 11:31:20 +0800
Subject: [soc:arm/soc] BUILD SUCCESS 9dbacd465ab733d4ac415ccfaf4a0503387377e8
Message-ID: <611f2208.uaKb/kDULG1Wor4G%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/soc
branch HEAD: 9dbacd465ab733d4ac415ccfaf4a0503387377e8  Merge tag 'aspeed-5.15-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/joel/bmc into arm/soc

elapsed time: 721m

configs tested: 143
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210819
i386                 randconfig-c001-20210818
nios2                         3c120_defconfig
m68k                        mvme16x_defconfig
arm                        keystone_defconfig
arm                        vexpress_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                  mpc885_ads_defconfig
powerpc                 mpc8313_rdb_defconfig
powerpc                    klondike_defconfig
powerpc                          g5_defconfig
sparc64                          alldefconfig
riscv                          rv32_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                malta_qemu_32r6_defconfig
mips                     loongson1c_defconfig
csky                             alldefconfig
arm                          ixp4xx_defconfig
arm                      jornada720_defconfig
powerpc                     tqm8541_defconfig
sh                         ap325rxa_defconfig
nds32                             allnoconfig
mips                       capcella_defconfig
mips                      maltaaprp_defconfig
h8300                     edosk2674_defconfig
sh                               allmodconfig
ia64                        generic_defconfig
sh                            shmin_defconfig
mips                            e55_defconfig
sh                ecovec24-romimage_defconfig
arm                            mmp2_defconfig
powerpc                  storcenter_defconfig
sh                        dreamcast_defconfig
ia64                      gensparse_defconfig
sh                          lboxre2_defconfig
powerpc                     mpc5200_defconfig
sh                           se7206_defconfig
xtensa                generic_kc705_defconfig
powerpc                     pseries_defconfig
arm                        magician_defconfig
mips                            gpr_defconfig
arm                       imx_v4_v5_defconfig
sh                         apsh4a3a_defconfig
mips                         rt305x_defconfig
mips                     cu1830-neo_defconfig
sh                           se7751_defconfig
mips                           jazz_defconfig
sh                   secureedge5410_defconfig
sh                           se7750_defconfig
powerpc                     rainier_defconfig
m68k                         amcore_defconfig
m68k                        mvme147_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
x86_64               randconfig-a013-20210819
x86_64               randconfig-a011-20210819
x86_64               randconfig-a012-20210819
x86_64               randconfig-a016-20210819
x86_64               randconfig-a014-20210819
x86_64               randconfig-a015-20210819
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a015-20210819
i386                 randconfig-a011-20210819
i386                 randconfig-a014-20210819
i386                 randconfig-a013-20210819
i386                 randconfig-a016-20210819
i386                 randconfig-a012-20210819
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
x86_64               randconfig-a004-20210819
x86_64               randconfig-a006-20210819
x86_64               randconfig-a003-20210819
x86_64               randconfig-a002-20210819
x86_64               randconfig-a005-20210819
x86_64               randconfig-a001-20210819
i386                 randconfig-a004-20210819
i386                 randconfig-a006-20210819
i386                 randconfig-a001-20210819
i386                 randconfig-a002-20210819
i386                 randconfig-a003-20210819
i386                 randconfig-a005-20210819
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From icenowy at sipeed.com  Thu Aug 19 20:52:22 2021
From: icenowy at sipeed.com (Icenowy Zheng)
Date: Fri, 20 Aug 2021 11:52:22 +0800
Subject: [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
In-Reply-To: <3e56e53f-e6df-50cf-5545-e9132e521ed1@sholland.org>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-12-icenowy@sipeed.com>
 <3e56e53f-e6df-50cf-5545-e9132e521ed1@sholland.org>
Message-ID: <19e439709d73ed3d5c8a5b339c1a3f691f6dd4fe.camel@sipeed.com>+61D9000A175299FB

? 2021-08-19???? 21:41 -0500?Samuel Holland???
> On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> > Allwinner R329 has a CCU that is similar to the H616 one, but it's
> > cut
> > down and have PLLs moved out.
> > 
> > Add support for it.
> > 
> > Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> > ---
> > ?drivers/clk/sunxi-ng/Kconfig??????????????? |?? 5 +
> > ?drivers/clk/sunxi-ng/Makefile?????????????? |?? 1 +
> > ?drivers/clk/sunxi-ng/ccu-sun50i-r329.c????? | 526
> > ++++++++++++++++++++
> > ?drivers/clk/sunxi-ng/ccu-sun50i-r329.h????? |? 32 ++
> > ?include/dt-bindings/clock/sun50i-r329-ccu.h |? 73 +++
> > ?include/dt-bindings/reset/sun50i-r329-ccu.h |? 45 ++
> > ?6 files changed, 682 insertions(+)
> > ?create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> > ?create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> > ?create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
> > ?create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
> > 
> > diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-
> > ng/Kconfig
> > index e49b2c2fa5b7..4b32d5f81ea8 100644
> > --- a/drivers/clk/sunxi-ng/Kconfig
> > +++ b/drivers/clk/sunxi-ng/Kconfig
> > @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
> > ????????default ARM64 && ARCH_SUNXI
> > ????????depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> > ?
> > +config SUN50I_R329_CCU
> > +???????bool "Support for the Allwinner R329 CCU"
> > +???????default ARM64 && ARCH_SUNXI
> > +???????depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> > +
> > ?config SUN50I_R329_R_CCU
> > ????????bool "Support for the Allwinner R329 PRCM CCU"
> > ????????default ARM64 && ARCH_SUNXI
> > diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-
> > ng/Makefile
> > index db338a2188fd..62f3c5bf331c 100644
> > --- a/drivers/clk/sunxi-ng/Makefile
> > +++ b/drivers/clk/sunxi-ng/Makefile
> > @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)???????+= ccu-
> > sun50i-a100-r.o
> > ?obj-$(CONFIG_SUN50I_H6_CCU)????+= ccu-sun50i-h6.o
> > ?obj-$(CONFIG_SUN50I_H616_CCU)??+= ccu-sun50i-h616.o
> > ?obj-$(CONFIG_SUN50I_H6_R_CCU)??+= ccu-sun50i-h6-r.o
> > +obj-$(CONFIG_SUN50I_R329_CCU)??+= ccu-sun50i-r329.o
> > ?obj-$(CONFIG_SUN50I_R329_R_CCU)????????+= ccu-sun50i-r329-r.o
> > ?obj-$(CONFIG_SUN4I_A10_CCU)????+= ccu-sun4i-a10.o
> > ?obj-$(CONFIG_SUN5I_CCU)????????????????+= ccu-sun5i.o
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> > b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> > new file mode 100644
> > index 000000000000..a0b4cfd6e1db
> > --- /dev/null
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> > @@ -0,0 +1,526 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Based on the H616 CCU driver, which is:
> > + *?? Copyright (c) 2020 Arm Ltd.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "ccu_common.h"
> > +#include "ccu_reset.h"
> > +
> > +#include "ccu_div.h"
> > +#include "ccu_gate.h"
> > +#include "ccu_mp.h"
> > +#include "ccu_mult.h"
> > +#include "ccu_nk.h"
> > +#include "ccu_nkm.h"
> > +#include "ccu_nkmp.h"
> > +#include "ccu_nm.h"
> > +
> > +#include "ccu-sun50i-r329.h"
> > +
> > +/*
> > + * An external divider of PLL-CPUX is controlled here. As it's
> > similar to
> > + * the external divider of PLL-CPUX on previous SoCs (only usable
> > under
> > + * 288MHz}, ignore it.
> 
> Mismatched (braces} here
> 
> > + */
> > +static const char * const cpux_parents[] = { "osc24M", "osc32k",
> > "iosc",
> > +??????????????????????????????????????????? "pll-cpux", "pll-
> > periph",
> > +??????????????????????????????????????????? "pll-periph-2x",
> > +??????????????????????????????????????????? "pll=periph-800m" };
> 
> = should be a -.
> 
> Now that these PLLs are in a different device, how is this supposed
> to affect
> the DT binding? Do we put all of them in the clocks property?
> 
> If so, we can use .fw_name at some point. If not, why bother with the
> clocks
> property at all? This is another part of the "let's get the clock
> tree right
> from the start" discussion.

Well we don't now, because I think it's too dirty to put all PLLs into
the device tree, but I must admit that this should be correct.

> 
> > +static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
> > +??????????????????? 0x500, 24, 3, CLK_SET_RATE_PARENT |
> > CLK_IS_CRITICAL);
> > +static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0);
> > +static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2,
> > 0);
> > +
> > +static const char * const ahb_parents[] = { "osc24M", "osc32k",
> > +?????????????????????????????????????????? "iosc", "pll-periph" };
> > +static SUNXI_CCU_MP_WITH_MUX(ahb_clk, "ahb",
> > +??????????????????????????? ahb_parents, 0x510,
> > +??????????????????????????? 0, 2,??????/* M */
> > +??????????????????????????? 8, 2,??????/* P */
> > +??????????????????????????? 24, 3,?????/* mux */
> > +??????????????????????????? 0);
> > +
> > +static const char * const apb_parents[] = { "osc24M", "osc32k",
> > +?????????????????????????????????????????? "ahb", "pll-periph" };
> > +static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb_parents, 0x520,
> > +??????????????????????????? 0, 2,??????/* M */
> > +??????????????????????????? 8, 2,??????/* P */
> > +??????????????????????????? 24, 3,?????/* mux */
> > +??????????????????????????? 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb_parents, 0x524,
> > +??????????????????????????? 0, 2,??????/* M */
> > +??????????????????????????? 8, 2,??????/* P */
> > +??????????????????????????? 24, 3,?????/* mux */
> > +??????????????????????????? 0);
> 
> Hmm, so Allwinner is inconsistent with these. The manual has
> APB0/APB1, but the
> BSP has APB1/APB2.
> 
> > +
> > +static const char * const ce_parents[] = { "osc24M", "pll-periph-
> > 2x" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 1,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb",
> > +???????????????????? 0x68c, BIT(0), 0);
> > +
> > +static const char * const aipu_parents[] = { "pll-periph-2x",
> > "pll-periph-800m",
> > +??????????????????????????????????????????? "pll-audio0-div2",
> > "pll-audio0-div5",
> > +??????????????????????????????????????????? "pll-cpux" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(aipu_clk, "aipu", aipu_parents,
> > 0x6f0,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 3,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_aipu_clk, "bus-aipu", "ahb",
> > +???????????????????? 0x6fc, BIT(0), 0);
> 
> The manual has separate gates for an AIPU AHB master at bit 1, and an
> AHB slave
> at bit 0.
> 
> > +
> > +static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb",
> > +???????????????????? 0x70c, BIT(0), 0);
> > +
> > +static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb",
> > +???????????????????? 0x71c, BIT(0), 0);
> 
> There are two message boxes (bits 0 and 1).
> 
> > +
> > +static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb",
> > +???????????????????? 0x72c, BIT(0), 0);
> > +
> > +static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb",
> > +???????????????????? 0x73c, BIT(0), 0);
> > +
> > +static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x740, BIT(31),
> > 0);
> > +
> > +static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb",
> > +???????????????????? 0x78c, BIT(0), 0);
> 
> There is a gate for the PSI clock (the parent for the AHB clocks) at
> 0x79c.
> 
> > +
> > +static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac,
> > BIT(0), 0);
> > +
> > +static const char * const dram_parents[] = { "pll-periph-2x",
> > +??????????????????????????????????????????? "pll-periph-800m",
> > +??????????????????????????????????????????? "pll-audio0-div2",
> > +??????????????????????????????????????????? "pll-audio0-div5" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(dram_clk, "dram", dram_parents,
> > 0x800,
> > +???????????????????????????????? 0, 2,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 2,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? CLK_IS_CRITICAL);
> > +
> > +
> > +static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "dram",
> > +???????????????????? 0x804, BIT(0), 0);
> > +static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "dram",
> > +???????????????????? 0x804, BIT(2), 0);
> > +static SUNXI_CCU_GATE(mbus_r_dma_clk, "mbus-r-dma", "dram",
> > +???????????????????? 0x804, BIT(3), 0);
> > +static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "dram",
> > +???????????????????? 0x804, BIT(5), 0);
> > +static SUNXI_CCU_GATE(mbus_aipu_clk, "mbus-aipu", "dram",
> > +???????????????????? 0x804, BIT(16), 0);
> > +
> > +static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb",
> > +???????????????????? 0x80c, BIT(0), CLK_IS_CRITICAL);
> 
> The DRAM bus clock is not critical. It only needs to be enabled for
> register
> access (PMU, DVFS).
> 
> > +
> > +static const char * const nand_parents[] = { "osc24M", "pll-
> > periph",
> > +??????????????????????????????????????????? "pll-audio-div2",
> > +??????????????????????????????????????????? "pll-periph-2x" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0",
> > nand_parents, 0x810,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 3,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1",
> > nand_parents, 0x814,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 3,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb", 0x82c,
> > BIT(0), 0);
> > +
> > +static const char * const mmc_parents[] = { "osc24M", "pll-
> > periph",
> > +?????????????????????????????????????????? "pll-periph-2x",
> > +?????????????????????????????????????????? "pll-audio0-div2" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0",
> > mmc_parents, 0x830,
> > +???????????????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????????????? 24, 2,????????/* mux */
> > +???????????????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????????????? 2,????????????/* post-div
> > */
> > +???????????????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1",
> > mmc_parents, 0x834,
> > +???????????????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????????????? 24, 2,????????/* mux */
> > +???????????????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????????????? 2,????????????/* post-div
> > */
> 
> Where does the post-divider come from?
> 
> > +???????????????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb", 0x84c,
> > BIT(0), 0);
> > +static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb", 0x84c,
> > BIT(1), 0);
> > +
> > +static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c,
> > BIT(0), 0);
> > +static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c,
> > BIT(1), 0);
> > +static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c,
> > BIT(2), 0);
> > +static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c,
> > BIT(3), 0);
> > +
> > +static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c,
> > BIT(0), 0);
> > +static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c,
> > BIT(1), 0);
> > +
> > +static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", 0x93c,
> > BIT(0), 0);
> > +
> > +static const char * const spi_parents[] = { "osc24M", "pll-
> > periph",
> > +?????????????????????????????????????????? "pll-periph-2x",
> > +?????????????????????????????????????????? "pll-audio0-div2",
> > +?????????????????????????????????????????? "pll-audio0-div5" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents,
> > 0x940,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 3,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents,
> > 0x944,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 3,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb", 0x96c,
> > BIT(0), 0);
> > +static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb", 0x96c,
> > BIT(1), 0);
> > +
> > +static CLK_FIXED_FACTOR(emac_25m_div_clk, "emac-25m-div", "pll-
> > periph",
> > +???????????????????????2, 1, 0);
> > +static SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "emac-25m-div",
> > 0x970,
> > +???????????????????? BIT(31) | BIT(30), 0);
> 
> The divider should be 24, not 2. And you can use
> CCU_FEATURE_ALL_PREDIV on the
> gate to remove the separate divider clock.
> 
> > +
> > +static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb", 0x97c,
> > BIT(0), 0);
> > +
> > +static const char * const ir_parents[] = { "osc32k", "iosc",
> 
> Both the manual and the BSP have the second parent as osc24M, not
> iosc.
> 
> > +????????????????????????????????????????? "pll-periph", "pll-
> > audio0-div2" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents,
> > 0x990,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 2,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "apb1", 0x99c,
> > BIT(0), 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents,
> > 0x9c0,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 2,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc,
> > BIT(0), 0);
> > +
> > +static const char * const audio_parents[] = { "pll-audio1",
> > +???????????????????????????????????????????? "pll-audio1-4x",
> > +???????????????????????????????????????????? "pll-audio0-div2",
> > +???????????????????????????????????????????? "pll-audio0-div5" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(i2s0_clk, "i2s0", audio_parents,
> > 0xa10,
> > +???????????????????????????????? 0, 4,?????????/* M */
> 
> All of the audio modules have 5-bit M dividers.
> 
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 2,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(i2s1_clk, "i2s1", audio_parents,
> > 0xa14,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 2,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20,
> > BIT(0), 0);
> > +static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20,
> > BIT(1), 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(spdif_clk, "spdif",
> > audio_parents, 0xa20,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 2,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c,
> > BIT(0), 0);
> > +
> > +/*
> > + * There are OHCI 12M clock source selection bits for 2 USB 2.0
> > ports.
> > + * We will force them to 0 (12M divided from 48M).
> > + */
> > +#define SUN50I_R329_USB0_CLK_REG???????????????0xa70
> > +#define SUN50I_R329_USB1_CLK_REG???????????????0xa74
> 
> This "48M" clock is divided/synchronized from pll-periph, as shown in
> the
> "Module Clock Generation" diagram and USB "PHY Connection Diagram" in
> the
> manual. So I recommend the following structure:
> 
> static CLK_FIXED_FACTOR(usb_48M_clk, "usb-48M",
> ??????????????????????? "pll-periph", 25, 2, 0);
> 
> static CLK_FIXED_FACTOR_HW(usb_12M_clk, "usb-12M",
> ?????????????????????????? &usb_48M_clk.hw, 4, 1, 0);
> 
> static const char *const usb_ohci_parents[] = { "usb-12M", "osc12M",
> ??????????????????????????????????????????????? "osc32k" };
> static SUNXI_CCU_MUX_WITH_GATE(usb_ohci0_clk, "usb-ohci0",
> ?????????????????????????????? usb_ohci_parents, 0xa70,
> ?????????????????????????????? 24, 2,?????????? /* mux */
> ?????????????????????????????? BIT(31),???????? /* gate */
> ?????????????????????????????? 0);
> 
> static SUNXI_CCU_MUX_WITH_GATE(usb_ohci1_clk, "usb-ohci1",
> ?????????????????????????????? usb_ohci_parents, 0xa74,
> ?????????????????????????????? 24, 2,?????????? /* mux */
> ?????????????????????????????? BIT(31),???????? /* gate */
> ?????????????????????????????? 0);
> 
> For anyone following along without R329 documents, this is all the
> same as the
> D1, though the labels in the diagrams are slightly different. Hooray
> for finally
> documenting this so it is no longer "mysterious"!
> 
> Regards,
> Samuel
> 
> > +
> > +static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70,
> > BIT(31), 0);
> > +static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 0xa70,
> > BIT(29), 0);
> > +
> > +static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74,
> > BIT(31), 0);
> > +static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 0xa74,
> > BIT(29), 0);
> > +
> > +static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb", 0xa8c,
> > BIT(0), 0);
> > +static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb", 0xa8c,
> > BIT(1), 0);
> > +static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb", 0xa8c,
> > BIT(4), 0);
> > +static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb", 0xa8c,
> > BIT(8), 0);
> > +
> > +static const char * const ledc_parents[] = { "osc24M", "pll-
> > periph" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(ledc_clk, "ledc", ledc_parents,
> > 0xbf0,
> > +???????????????????????????????? 0, 4,?????????/* M */
> > +???????????????????????????????? 8, 2,?????????/* P */
> > +???????????????????????????????? 24, 1,????????/* mux */
> > +???????????????????????????????? BIT(31),??????/* gate */
> > +???????????????????????????????? 0);
> > +
> > +static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "apb1", 0xbfc,
> > BIT(0), 0);
> > +
> > +/* Fixed factor clocks */
> > +static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2,
> > 1, 0);
> > +
> > +static struct ccu_common *sun50i_r329_ccu_clks[] = {
> > +???????&cpux_clk.common,
> > +???????&axi_clk.common,
> > +???????&cpux_apb_clk.common,
> > +???????&ahb_clk.common,
> > +???????&apb1_clk.common,
> > +???????&apb2_clk.common,
> > +???????&ce_clk.common,
> > +???????&bus_ce_clk.common,
> > +???????&aipu_clk.common,
> > +???????&bus_aipu_clk.common,
> > +???????&bus_dma_clk.common,
> > +???????&bus_msgbox_clk.common,
> > +???????&bus_spinlock_clk.common,
> > +???????&bus_hstimer_clk.common,
> > +???????&avs_clk.common,
> > +???????&bus_dbg_clk.common,
> > +???????&bus_pwm_clk.common,
> > +???????&dram_clk.common,
> > +???????&mbus_dma_clk.common,
> > +???????&mbus_ce_clk.common,
> > +???????&mbus_r_dma_clk.common,
> > +???????&mbus_nand_clk.common,
> > +???????&mbus_aipu_clk.common,
> > +???????&bus_dram_clk.common,
> > +???????&nand0_clk.common,
> > +???????&nand1_clk.common,
> > +???????&bus_nand_clk.common,
> > +???????&mmc0_clk.common,
> > +???????&mmc1_clk.common,
> > +???????&bus_mmc0_clk.common,
> > +???????&bus_mmc1_clk.common,
> > +???????&bus_uart0_clk.common,
> > +???????&bus_uart1_clk.common,
> > +???????&bus_uart2_clk.common,
> > +???????&bus_uart3_clk.common,
> > +???????&bus_i2c0_clk.common,
> > +???????&bus_i2c1_clk.common,
> > +???????&bus_scr_clk.common,
> > +???????&spi0_clk.common,
> > +???????&spi1_clk.common,
> > +???????&bus_spi0_clk.common,
> > +???????&bus_spi1_clk.common,
> > +???????&emac_25m_clk.common,
> > +???????&bus_emac_clk.common,
> > +???????&ir_rx_clk.common,
> > +???????&bus_ir_rx_clk.common,
> > +???????&ir_tx_clk.common,
> > +???????&bus_ir_tx_clk.common,
> > +???????&i2s0_clk.common,
> > +???????&i2s1_clk.common,
> > +???????&bus_i2s0_clk.common,
> > +???????&bus_i2s1_clk.common,
> > +???????&spdif_clk.common,
> > +???????&bus_spdif_clk.common,
> > +???????&usb_ohci0_clk.common,
> > +???????&usb_phy0_clk.common,
> > +???????&usb_ohci1_clk.common,
> > +???????&usb_phy1_clk.common,
> > +???????&bus_ohci0_clk.common,
> > +???????&bus_ohci1_clk.common,
> > +???????&bus_ehci0_clk.common,
> > +???????&bus_otg_clk.common,
> > +???????&ledc_clk.common,
> > +???????&bus_ledc_clk.common,
> > +};
> > +
> > +static struct clk_hw_onecell_data sun50i_r329_hw_clks = {
> > +???????.hws????= {
> > +???????????????[CLK_OSC12M]????????????= &osc12M_clk.hw,
> > +???????????????[CLK_CPUX]??????????????= &cpux_clk.common.hw,
> > +???????????????[CLK_AXI]???????????????= &axi_clk.common.hw,
> > +???????????????[CLK_CPUX_APB]??????????= &cpux_apb_clk.common.hw,
> > +???????????????[CLK_AHB]???????????????= &ahb_clk.common.hw,
> > +???????????????[CLK_APB1]??????????????= &apb1_clk.common.hw,
> > +???????????????[CLK_APB2]??????????????= &apb2_clk.common.hw,
> > +???????????????[CLK_CE]????????????????= &ce_clk.common.hw,
> > +???????????????[CLK_BUS_CE]????????????= &bus_ce_clk.common.hw,
> > +???????????????[CLK_AIPU]??????????????= &aipu_clk.common.hw,
> > +???????????????[CLK_BUS_AIPU]??????????= &bus_aipu_clk.common.hw,
> > +???????????????[CLK_BUS_DMA]???????????= &bus_dma_clk.common.hw,
> > +???????????????[CLK_BUS_MSGBOX]????????=
> > &bus_msgbox_clk.common.hw,
> > +???????????????[CLK_BUS_SPINLOCK]??????=
> > &bus_spinlock_clk.common.hw,
> > +???????????????[CLK_BUS_HSTIMER]???????=
> > &bus_hstimer_clk.common.hw,
> > +???????????????[CLK_AVS]???????????????= &avs_clk.common.hw,
> > +???????????????[CLK_BUS_DBG]???????????= &bus_dbg_clk.common.hw,
> > +???????????????[CLK_BUS_PWM]???????????= &bus_pwm_clk.common.hw,
> > +???????????????[CLK_DRAM]??????????????= &dram_clk.common.hw,
> > +???????????????[CLK_MBUS_DMA]??????????= &mbus_dma_clk.common.hw,
> > +???????????????[CLK_MBUS_CE]???????????= &mbus_ce_clk.common.hw,
> > +???????????????[CLK_MBUS_R_DMA]????????=
> > &mbus_r_dma_clk.common.hw,
> > +???????????????[CLK_MBUS_NAND]?????????= &mbus_nand_clk.common.hw,
> > +???????????????[CLK_MBUS_AIPU]?????????= &mbus_aipu_clk.common.hw,
> > +???????????????[CLK_BUS_DRAM]??????????= &bus_dram_clk.common.hw,
> > +???????????????[CLK_NAND0]?????????????= &nand0_clk.common.hw,
> > +???????????????[CLK_NAND1]?????????????= &nand1_clk.common.hw,
> > +???????????????[CLK_BUS_NAND]??????????= &bus_nand_clk.common.hw,
> > +???????????????[CLK_MMC0]??????????????= &mmc0_clk.common.hw,
> > +???????????????[CLK_MMC1]??????????????= &mmc1_clk.common.hw,
> > +???????????????[CLK_BUS_MMC0]??????????= &bus_mmc0_clk.common.hw,
> > +???????????????[CLK_BUS_MMC1]??????????= &bus_mmc1_clk.common.hw,
> > +???????????????[CLK_BUS_UART0]?????????= &bus_uart0_clk.common.hw,
> > +???????????????[CLK_BUS_UART1]?????????= &bus_uart1_clk.common.hw,
> > +???????????????[CLK_BUS_UART2]?????????= &bus_uart2_clk.common.hw,
> > +???????????????[CLK_BUS_UART3]?????????= &bus_uart3_clk.common.hw,
> > +???????????????[CLK_BUS_I2C0]??????????= &bus_i2c0_clk.common.hw,
> > +???????????????[CLK_BUS_I2C1]??????????= &bus_i2c1_clk.common.hw,
> > +???????????????[CLK_BUS_SCR]???????????= &bus_scr_clk.common.hw,
> > +???????????????[CLK_SPI0]??????????????= &spi0_clk.common.hw,
> > +???????????????[CLK_SPI1]??????????????= &spi1_clk.common.hw,
> > +???????????????[CLK_BUS_SPI0]??????????= &bus_spi0_clk.common.hw,
> > +???????????????[CLK_BUS_SPI1]??????????= &bus_spi1_clk.common.hw,
> > +???????????????[CLK_EMAC_25M_DIV]??????= &emac_25m_div_clk.hw,
> > +???????????????[CLK_EMAC_25M]??????????= &emac_25m_clk.common.hw,
> > +???????????????[CLK_BUS_EMAC]??????????= &bus_emac_clk.common.hw,
> > +???????????????[CLK_IR_RX]?????????????= &ir_rx_clk.common.hw,
> > +???????????????[CLK_BUS_IR_RX]?????????= &bus_ir_rx_clk.common.hw,
> > +???????????????[CLK_IR_TX]?????????????= &ir_tx_clk.common.hw,
> > +???????????????[CLK_BUS_IR_TX]?????????= &bus_ir_tx_clk.common.hw,
> > +???????????????[CLK_I2S0]??????????????= &i2s0_clk.common.hw,
> > +???????????????[CLK_I2S1]??????????????= &i2s1_clk.common.hw,
> > +???????????????[CLK_BUS_I2S0]??????????= &bus_i2s0_clk.common.hw,
> > +???????????????[CLK_BUS_I2S1]??????????= &bus_i2s1_clk.common.hw,
> > +???????????????[CLK_SPDIF]?????????????= &spdif_clk.common.hw,
> > +???????????????[CLK_BUS_SPDIF]?????????= &bus_spdif_clk.common.hw,
> > +???????????????[CLK_USB_OHCI0]?????????= &usb_ohci0_clk.common.hw,
> > +???????????????[CLK_USB_PHY0]??????????= &usb_phy0_clk.common.hw,
> > +???????????????[CLK_USB_OHCI1]?????????= &usb_ohci1_clk.common.hw,
> > +???????????????[CLK_USB_PHY1]??????????= &usb_phy1_clk.common.hw,
> > +???????????????[CLK_BUS_OHCI0]?????????= &bus_ohci0_clk.common.hw,
> > +???????????????[CLK_BUS_OHCI1]?????????= &bus_ohci1_clk.common.hw,
> > +???????????????[CLK_BUS_EHCI0]?????????= &bus_ehci0_clk.common.hw,
> > +???????????????[CLK_BUS_OTG]???????????= &bus_otg_clk.common.hw,
> > +???????????????[CLK_LEDC]??????????????= &ledc_clk.common.hw,
> > +???????????????[CLK_BUS_LEDC]??????????= &bus_ledc_clk.common.hw,
> > +???????},
> > +???????.num = CLK_NUMBER,
> > +};
> > +
> > +static struct ccu_reset_map sun50i_r329_ccu_resets[] = {
> > +???????[RST_MBUS]??????????????= { 0x540, BIT(30) },
> > +
> > +???????[RST_BUS_CE]????????????= { 0x68c, BIT(16) },
> > +???????[RST_BUS_AIPU]??????????= { 0x6fc, BIT(16) },
> > +???????[RST_BUS_DMA]???????????= { 0x70c, BIT(16) },
> > +???????[RST_BUS_MSGBOX]????????= { 0x71c, BIT(16) },
> > +???????[RST_BUS_SPINLOCK]??????= { 0x72c, BIT(16) },
> > +???????[RST_BUS_HSTIMER]???????= { 0x73c, BIT(16) },
> > +???????[RST_BUS_DBG]???????????= { 0x78c, BIT(16) },
> > +???????[RST_BUS_PWM]???????????= { 0x7ac, BIT(16) },
> > +???????[RST_BUS_DRAM]??????????= { 0x80c, BIT(16) },
> > +???????[RST_BUS_NAND]??????????= { 0x82c, BIT(16) },
> > +???????[RST_BUS_MMC0]??????????= { 0x84c, BIT(16) },
> > +???????[RST_BUS_MMC1]??????????= { 0x84c, BIT(17) },
> > +???????[RST_BUS_UART0]?????????= { 0x90c, BIT(16) },
> > +???????[RST_BUS_UART1]?????????= { 0x90c, BIT(17) },
> > +???????[RST_BUS_UART2]?????????= { 0x90c, BIT(18) },
> > +???????[RST_BUS_UART3]?????????= { 0x90c, BIT(19) },
> > +???????[RST_BUS_I2C0]??????????= { 0x91c, BIT(16) },
> > +???????[RST_BUS_I2C1]??????????= { 0x91c, BIT(17) },
> > +???????[RST_BUS_SCR]???????????= { 0x93c, BIT(16) },
> > +???????[RST_BUS_SPI0]??????????= { 0x96c, BIT(16) },
> > +???????[RST_BUS_SPI1]??????????= { 0x96c, BIT(17) },
> > +???????[RST_BUS_EMAC]??????????= { 0x97c, BIT(16) },
> > +???????[RST_BUS_IR_RX]?????????= { 0x99c, BIT(16) },
> > +???????[RST_BUS_IR_TX]?????????= { 0x9cc, BIT(16) },
> > +???????[RST_BUS_I2S0]??????????= { 0xa1c, BIT(16) },
> > +???????[RST_BUS_I2S1]??????????= { 0xa1c, BIT(17) },
> > +???????[RST_BUS_SPDIF]?????????= { 0xa2c, BIT(16) },
> > +
> > +???????[RST_USB_PHY0]??????????= { 0xa70, BIT(30) },
> > +???????[RST_USB_PHY1]??????????= { 0xa74, BIT(30) },
> > +
> > +???????[RST_BUS_OHCI0]?????????= { 0xa8c, BIT(16) },
> > +???????[RST_BUS_OHCI1]?????????= { 0xa8c, BIT(17) },
> > +???????[RST_BUS_EHCI0]?????????= { 0xa8c, BIT(20) },
> > +???????[RST_BUS_OTG]???????????= { 0xa8c, BIT(24) },
> > +
> > +???????[RST_BUS_LEDC]??????????= { 0xbfc, BIT(16) },
> > +};
> > +
> > +static const struct sunxi_ccu_desc sun50i_r329_ccu_desc = {
> > +???????.ccu_clks???????= sun50i_r329_ccu_clks,
> > +???????.num_ccu_clks???= ARRAY_SIZE(sun50i_r329_ccu_clks),
> > +
> > +???????.hw_clks????????= &sun50i_r329_hw_clks,
> > +
> > +???????.resets?????????= sun50i_r329_ccu_resets,
> > +???????.num_resets?????= ARRAY_SIZE(sun50i_r329_ccu_resets),
> > +};
> > +
> > +static const u32 sun50i_r329_usb_clk_regs[] = {
> > +???????SUN50I_R329_USB0_CLK_REG,
> > +???????SUN50I_R329_USB1_CLK_REG,
> > +};
> > +
> > +static int sun50i_r329_ccu_probe(struct platform_device *pdev)
> > +{
> > +???????void __iomem *reg;
> > +???????u32 val;
> > +???????int i;
> > +
> > +???????reg = devm_platform_ioremap_resource(pdev, 0);
> > +???????if (IS_ERR(reg))
> > +???????????????return PTR_ERR(reg);
> > +
> > +???????/*
> > +??????? * Force OHCI 12M clock sources to 00 (12MHz divided from
> > 48MHz)
> > +??????? *
> > +??????? * This clock mux is still mysterious, and the code just
> > enforces
> > +??????? * it to have a valid clock parent.
> > +??????? */
> > +???????for (i = 0; i < ARRAY_SIZE(sun50i_r329_usb_clk_regs); i++)
> > {
> > +???????????????val = readl(reg + sun50i_r329_usb_clk_regs[i]);
> > +???????????????val &= ~GENMASK(25, 24);
> > +???????????????writel(val, reg + sun50i_r329_usb_clk_regs[i]);
> > +???????}
> > +
> > +???????return sunxi_ccu_probe(pdev->dev.of_node, reg,
> > &sun50i_r329_ccu_desc);
> > +}
> > +
> > +static const struct of_device_id sun50i_r329_ccu_ids[] = {
> > +???????{ .compatible = "allwinner,sun50i-r329-ccu" },
> > +???????{ }
> > +};
> > +
> > +static struct platform_driver sun50i_r329_ccu_driver = {
> > +???????.probe??= sun50i_r329_ccu_probe,
> > +???????.driver?= {
> > +???????????????.name???= "sun50i-r329-ccu",
> > +???????????????.of_match_table?= sun50i_r329_ccu_ids,
> > +???????},
> > +};
> > +module_platform_driver(sun50i_r329_ccu_driver);
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> > b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> > new file mode 100644
> > index 000000000000..144ac9954ef3
> > --- /dev/null
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> > @@ -0,0 +1,32 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _CCU_SUN50I_R329_H_
> > +#define _CCU_SUN50I_R329_H_
> > +
> > +#include <dt-bindings/clock/sun50i-r329-ccu.h>
> > +#include <dt-bindings/reset/sun50i-r329-ccu.h>
> > +
> > +#define CLK_OSC12M?????????????0
> > +
> > +/* CPUX exported for DVFS */
> > +
> > +#define CLK_AXI????????????????????????2
> > +#define CLK_CPUX_APB???????????3
> > +#define CLK_AHB????????????????????????4
> > +
> > +/* APB1 exported for PIO */
> > +
> > +#define CLK_APB2???????????????6
> > +
> > +/* Peripheral module and gate clock exported except for DRAM ones
> > */
> > +
> > +#define CLK_DRAM???????????????18
> > +
> > +#define CLK_BUS_DRAM???????????24
> > +
> > +#define CLK_NUMBER?????????????(CLK_BUS_LEDC + 1)
> > +
> > +#endif /* _CCU_SUN50I_R329_H_ */
> > diff --git a/include/dt-bindings/clock/sun50i-r329-ccu.h
> > b/include/dt-bindings/clock/sun50i-r329-ccu.h
> > new file mode 100644
> > index 000000000000..116f8d13a9b3
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/sun50i-r329-ccu.h
> > @@ -0,0 +1,73 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
> > +#define _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_
> > +
> > +#define CLK_CPUX???????????????1
> > +
> > +#define CLK_APB1???????????????5
> > +
> > +#define CLK_CE?????????????????7
> > +#define CLK_BUS_CE?????????????8
> > +#define CLK_AIPU???????????????9
> > +#define CLK_BUS_AIPU???????????10
> > +#define CLK_BUS_DMA????????????11
> > +#define CLK_BUS_MSGBOX?????????12
> > +#define CLK_BUS_SPINLOCK???????13
> > +#define CLK_BUS_HSTIMER????????????????14
> > +#define CLK_AVS????????????????????????15
> > +#define CLK_BUS_DBG????????????16
> > +#define CLK_BUS_PWM????????????17
> > +
> > +#define CLK_MBUS_DMA???????????19
> > +#define CLK_MBUS_CE????????????20
> > +#define CLK_MBUS_R_DMA?????????21
> > +#define CLK_MBUS_NAND??????????22
> > +#define CLK_MBUS_AIPU??????????23
> > +
> > +#define CLK_NAND0??????????????25
> > +#define CLK_NAND1??????????????26
> > +#define CLK_BUS_NAND???????????27
> > +#define CLK_MMC0???????????????28
> > +#define CLK_MMC1???????????????29
> > +#define CLK_BUS_MMC0???????????30
> > +#define CLK_BUS_MMC1???????????31
> > +#define CLK_BUS_UART0??????????32
> > +#define CLK_BUS_UART1??????????33
> > +#define CLK_BUS_UART2??????????34
> > +#define CLK_BUS_UART3??????????35
> > +#define CLK_BUS_I2C0???????????36
> > +#define CLK_BUS_I2C1???????????37
> > +#define CLK_BUS_SCR????????????38
> > +#define CLK_SPI0???????????????39
> > +#define CLK_SPI1???????????????40
> > +#define CLK_BUS_SPI0???????????41
> > +#define CLK_BUS_SPI1???????????42
> > +#define CLK_EMAC_25M_DIV???????43
> > +#define CLK_EMAC_25M???????????44
> > +#define CLK_BUS_EMAC???????????45
> > +#define CLK_IR_RX??????????????46
> > +#define CLK_BUS_IR_RX??????????47
> > +#define CLK_IR_TX??????????????48
> > +#define CLK_BUS_IR_TX??????????49
> > +#define CLK_I2S0???????????????50
> > +#define CLK_I2S1???????????????51
> > +#define CLK_BUS_I2S0???????????52
> > +#define CLK_BUS_I2S1???????????53
> > +#define CLK_SPDIF??????????????54
> > +#define CLK_BUS_SPDIF??????????55
> > +#define CLK_USB_OHCI0??????????56
> > +#define CLK_USB_PHY0???????????57
> > +#define CLK_USB_OHCI1??????????58
> > +#define CLK_USB_PHY1???????????59
> > +#define CLK_BUS_OHCI0??????????60
> > +#define CLK_BUS_OHCI1??????????61
> > +#define CLK_BUS_EHCI0??????????62
> > +#define CLK_BUS_OTG????????????63
> > +#define CLK_LEDC???????????????64
> > +#define CLK_BUS_LEDC???????????65
> > +
> > +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_CCU_H_ */
> > diff --git a/include/dt-bindings/reset/sun50i-r329-ccu.h
> > b/include/dt-bindings/reset/sun50i-r329-ccu.h
> > new file mode 100644
> > index 000000000000..bb704a82443f
> > --- /dev/null
> > +++ b/include/dt-bindings/reset/sun50i-r329-ccu.h
> > @@ -0,0 +1,45 @@
> > +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
> > +#define _DT_BINDINGS_RST_SUN50I_R329_CCU_H_
> > +
> > +#define RST_MBUS???????????????0
> > +#define RST_BUS_CE?????????????1
> > +#define RST_BUS_AIPU???????????2
> > +#define RST_BUS_DMA????????????3
> > +#define RST_BUS_MSGBOX?????????4
> > +#define RST_BUS_SPINLOCK???????5
> > +#define RST_BUS_HSTIMER????????????????6
> > +#define RST_BUS_DBG????????????7
> > +#define RST_BUS_PWM????????????8
> > +#define RST_BUS_DRAM???????????9
> > +#define RST_BUS_NAND???????????10
> > +#define RST_BUS_MMC0???????????11
> > +#define RST_BUS_MMC1???????????12
> > +#define RST_BUS_UART0??????????13
> > +#define RST_BUS_UART1??????????14
> > +#define RST_BUS_UART2??????????15
> > +#define RST_BUS_UART3??????????16
> > +#define RST_BUS_I2C0???????????17
> > +#define RST_BUS_I2C1???????????18
> > +#define RST_BUS_SCR????????????19
> > +#define RST_BUS_SPI0???????????20
> > +#define RST_BUS_SPI1???????????21
> > +#define RST_BUS_EMAC???????????22
> > +#define RST_BUS_IR_RX??????????23
> > +#define RST_BUS_IR_TX??????????24
> > +#define RST_BUS_I2S0???????????25
> > +#define RST_BUS_I2S1???????????26
> > +#define RST_BUS_SPDIF??????????27
> > +#define RST_USB_PHY0???????????28
> > +#define RST_USB_PHY1???????????29
> > +#define RST_BUS_OHCI0??????????30
> > +#define RST_BUS_OHCI1??????????31
> > +#define RST_BUS_EHCI0??????????32
> > +#define RST_BUS_OTG????????????33
> > +#define RST_BUS_LEDC???????????34
> > +
> > +#endif /* _DT_BINDINGS_RST_SUN50I_R329_CCU_H_ */
> > 
> 
> 




From samuel at sholland.org  Thu Aug 19 20:57:14 2021
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 19 Aug 2021 22:57:14 -0500
Subject: [PATCH v8 02/11] dt-bindings: rtc: sun6i: Add H616 compatible
 string
In-Reply-To: <20210818100407.7cf7cfb7@slackpad.fritz.box>
References: <20210723153838.6785-1-andre.przywara@arm.com>
 <20210723153838.6785-3-andre.przywara@arm.com>
 <20210726144137.6dauuxdssu7yszox@gilmour>
 <20210802013938.29fa18ed@slackpad.fritz.box>
 <20210817073810.7stuzrppyjf4spab@gilmour>
 <20210818100407.7cf7cfb7@slackpad.fritz.box>
Message-ID: <2b0504f6-9e01-88c1-84c9-c7714715dcb7@sholland.org>

On 8/18/21 4:04 AM, Andre Przywara wrote:
> On Tue, 17 Aug 2021 09:38:10 +0200
> Maxime Ripard <maxime at cerno.tech> wrote:
> 
> Hi Maxime,
> 
>> On Mon, Aug 02, 2021 at 01:39:38AM +0100, Andre Przywara wrote:
>>> On Mon, 26 Jul 2021 16:41:37 +0200
>>> Maxime Ripard <maxime at cerno.tech> wrote:
>>>   
>>>> Hi,
>>>>
>>>> On Fri, Jul 23, 2021 at 04:38:29PM +0100, Andre Przywara wrote:  
>>>>> Add the obvious compatible name to the existing RTC binding.
>>>>> The actual RTC part of the device uses a different day/month/year
>>>>> storage scheme, so it's not compatible with the previous devices.
>>>>> Also the clock part is quite different, as there is no external 32K LOSC
>>>>> oscillator input.
>>>>>
>>>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>>>>
>>>>> ---
>>>>>  .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml      | 14 ++++++++++++++
>>>>>  1 file changed, 14 insertions(+)
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
>>>>> index beeb90e55727..d8a6500e5840 100644
>>>>> --- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
>>>>> +++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
>>>>> @@ -26,6 +26,7 @@ properties:
>>>>>            - const: allwinner,sun50i-a64-rtc
>>>>>            - const: allwinner,sun8i-h3-rtc
>>>>>        - const: allwinner,sun50i-h6-rtc
>>>>> +      - const: allwinner,sun50i-h616-rtc
>>>>>  
>>>>>    reg:
>>>>>      maxItems: 1
>>>>> @@ -104,6 +105,19 @@ allOf:
>>>>>            minItems: 3
>>>>>            maxItems: 3
>>>>>  
>>>>> +  - if:
>>>>> +      properties:
>>>>> +        compatible:
>>>>> +          contains:
>>>>> +            const: allwinner,sun50i-h616-rtc
>>>>> +
>>>>> +    then:
>>>>> +      properties:
>>>>> +        clock-output-names:
>>>>> +          minItems: 3
>>>>> +          maxItems: 3    
>>>>
>>>> You don't need both of them when they are equal
>>>>   
>>>>> +        clocks: false
>>>>> +    
>>>>
>>>> It's not entirely clear to me what those clocks are about though. If we
>>>> look at the clock output in the user manual, it looks like there's only
>>>> two clocks that are actually being output: the 32k "fanout" clock and
>>>> the losc. What are the 3 you're talking about?]  
>>>
>>> I see three: the raw SYSTEM "CLK32K_LOSC", the RTC input + debounce
>>> clock (/32), and the multiplexed PAD.  
>>
>> But the input and debounce clock is only for the RTC itself right? So it
>> should be local to the driver and doesn't need to be made available to
>> the other drivers
> 
> I understood "debounce" as being the clock used for the pinctrl
> debouncer. What would it debounce otherwise? Do you think that this
> "debounce circuit" is something internal to the RTC and is totally
> irrelevant for us?

I'm pretty sure this is the debounce for the NMI and the SoC reset signal, not
the pinctrl. The pinctrl debounce clock pretty clearly references 32 kHz.

> But in general I looked at how many *different* clocks this diagram
> describes, and I count: one unaltered ("SYSTEM"), one "div by
> 32" (RTC/debounce), and one multiplexed. My aim was to avoid
> DT binding changes when we later discover we do need one of them for
> something (as happened in the past). So three seemed to be the safe
> choice here, to avoid surprises. In the worst case we just will never
> reference one of them.

Plus RC16M/IOSC (and depending on how you look at it, DCXO24M/HOSC).

>> Either way, what this list is must be documented.
> 
> You mean to overwrite the "description" stanza for clock-output-names?
> And can this be done in the per-SoC parts in the later part of the
> binding, keeping the existing description?
> 
> Cheers,
> Andre
> 
>>
>>>> Also, it looks like the 32k fanout clock needs at least the hosc or
>>>> pll-periph in input, so we probably don't want to ask for no parent
>>>> clock?  

Do you suggest we fix this for the existing bindings?

>>> Well, we never seem to reference the HOSC this way, this was always
>>> somewhat explicit. And yes, there is PLL-PERIPH as an input, but we
>>> don't support this yet. So I went with 0 input clocks *for now*: the
>>> driver can then ignore all clocks, so any clock referenced in the DT
>>> later won't cause any harm. This will all be addressed by Samuel's RTC
>>> clock patch, which will also touch the H6, IIRC. And it looks like we
>>> will need to touch the binding anyway then, but can then just *extend*
>>> this.  
>>
>> You mentioned that series several times already and never provided an
>> explanation for what it was supposed to be doing except fixing
>> everything. What's the general plan for that series?

This is my fault for not sending anything yet. Since the initial version of the
driver had the RTC providing HOSC, it depended on converting the existing A100,
H6, and H616 CCU drivers to use .fw_name for parents, since those drivers
hardcode two different global names for HOSC. And I had no opportunit to do that
yet.

However, I should really send something that 100% matches the current binding
for SoCs where that exists (i.e. osc24M is a fixed clock), and doing so is a
smaller job.

On the other hand, having osc24M as an RTC *output* neatly sidesteps the fact
that it has been missing from the input list :)

(But on the other-other hand, A50 gets even more fun, as the HOSC crystal may
not be 24MHz anymore. So the RTC has to choose one of three possible HOSC->LOSC
dividers based on the HOSC frequency. But there is no register for HOSC
frequency. So in this case it is convenient to have HOSC as a separate fixed
clock input.)

The basic idea of my patch is that using the CCU library code lets us cleanly
have slightly different clock trees for each of the RTC variants that Allwinner
comes up with.

The secondary goal is to add support for osc32k calibration.

An early version of the patch is here[1], and I will send something as soon as I
have made the modifications described above. But I know you were skeptical about
moving the clock part out of the RTC driver. So if you NACK that, somebody will
have to add all of the variants to the RTC driver.

Regards,
Samuel

[1]: https://github.com/smaeul/linux/commit/9510ca9e95cb.patch


From samuel at sholland.org  Thu Aug 19 21:04:52 2021
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 19 Aug 2021 23:04:52 -0500
Subject: [PATCH v2 1/3] dt-bindings: watchdog: sunxi: Add compatible for
 R329
In-Reply-To: <20210818090732.wdickyw67oc4zqpt@gilmour>
References: <20210805045716.46141-1-samuel@sholland.org>
 <20210818090732.wdickyw67oc4zqpt@gilmour>
Message-ID: <791b7548-cd7b-6cdf-8364-671f6a2029a9@sholland.org>

On 8/18/21 4:07 AM, Maxime Ripard wrote:
> Hi,
> 
> On Wed, Aug 04, 2021 at 11:57:14PM -0500, Samuel Holland wrote:
>> On existing SoCs, the watchdog has a single clock input: HOSC (OSC24M)
>> divided by 750.  However, starting with R329, LOSC (OSC32k) is added as
>> an alternative clock source, with a bit to switch between them.
>>
>> Since 24 MHz / 750 == 32 kHz, not 32.768 kHz, the hardware adjusts the
>> cycle counts to keep the timeouts independent of the clock source. This
>> keeps the programming interface backward-compatible.
>>
>> R329 also adds two new registers, to allow software to immediately drive
>> the SoC reset signal.
>>
>> Signed-off-by: Samuel Holland <samuel at sholland.org>
>> ---
>> Changes v1 to v2:
>>  - Switch from enum to const
>>  - Add descriptions to "clocks" items
>>
>>  .../watchdog/allwinner,sun4i-a10-wdt.yaml     | 32 ++++++++++++++++++-
>>  1 file changed, 31 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
>> index 9aa3c313c49f..8fa5b0d32381 100644
>> --- a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
>> +++ b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
>> @@ -24,6 +24,7 @@ properties:
>>                - allwinner,sun50i-a100-wdt
>>                - allwinner,sun50i-h6-wdt
>>                - allwinner,sun50i-h616-wdt
>> +              - allwinner,sun50i-r329-wdt
>>            - const: allwinner,sun6i-a31-wdt
>>        - items:
>>            - const: allwinner,suniv-f1c100s-wdt
>> @@ -33,7 +34,18 @@ properties:
>>      maxItems: 1
>>  
>>    clocks:
>> -    maxItems: 1
>> +    minItems: 1
>> +    maxItems: 2
>> +    items:
>> +      - description: High-frequency oscillator input, divided internally
>> +      - description: Low-frequency oscillator input, only found on some variants
>> +
>> +  clock-names:
>> +    minItems: 1
>> +    maxItems: 2
>> +    items:
>> +      - const: hosc
>> +      - const: losc
>>  
>>    interrupts:
>>      maxItems: 1
>> @@ -44,6 +56,24 @@ required:
>>    - clocks
>>    - interrupts
>>  
>> +if:
>> +  properties:
>> +    compatible:
>> +      contains:
>> +        enum:
>> +          - allwinner,sun50i-r329-wdt
>> +
>> +then:
>> +  properties:
>> +    clocks:
>> +      minItems: 2
>> +
>> +    clock-names:
>> +      minItems: 2
>> +
>> +  required:
>> +    - clock-names
>> +
> 
> We should also make sure through an else clause that all the other SoCs
> have a length of one for both clocks and clock-names

Yes, I'll do that for v3.

> Also, it looks like you forgot the patch to enable the compatible in the
> driver?

R329 has a fallback to A31, so it doesn't need any changes to the driver.

Regards,
Samuel


From swood at redhat.com  Thu Aug 19 21:11:12 2021
From: swood at redhat.com (Scott Wood)
Date: Thu, 19 Aug 2021 23:11:12 -0500
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-1>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
 <20210819153927.clqxr4f7qegpflbr@linutronix.de>
 <20210819154708.3efz6jtgwtuhpeds@linutronix.de>
 <20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-1>
Message-ID: <561ab28b18c31fbc221f4cb0c4df6db9b0538675.camel@redhat.com>

On Thu, 2021-08-19 at 11:20 -0700, Paul E. McKenney wrote:
> On Thu, Aug 19, 2021 at 05:47:08PM +0200, Sebastian Andrzej Siewior wrote:
> > On 2021-08-19 17:39:29 [+0200], To Paul E. McKenney wrote:
> > > +	/*
> > > +	 * Ideally these sequences would be detected in debug builds
> > > +	 * (regardless of RT), but until then don't stop testing
> > > +	 * them on non-RT.
> > > +	 */
> > > +	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> > > +		/*
> > > +		 * Can't release the outermost rcu lock in an irq disabled
> > > +		 * section without preemption also being disabled, if irqs
> > > +		 * had ever been enabled during this RCU critical section
> > > +		 * (could leak a special flag and delay reporting the qs).
> > > +		 */
> > > +		if ((oldmask & RCUTORTURE_RDR_RCU) &&
> > > +		    (mask & RCUTORTURE_RDR_IRQ) &&
> > > +		    !(mask & preempts))
> > > +			mask |= RCUTORTURE_RDR_RCU;
> > 
> > This piece above, I don't understand. I had it running for a while and
> > it didn't explode. Let me try TREE01 for 30min without that piece.
> 
> This might be historical.  There was a time when interrupts being
> disabled across rcu_read_unlock() meant that preemption had to have
> been disabled across the entire RCU read-side critical section.
> 
> I am not seeing a purpose for it now, but I could easily be missing
> something, especially given my tenuous grasp of RT.

Yeah, I think this was to deal with not having the irq work stuff in RT
at the time.

-Scott



From jernej.skrabec at gmail.com  Thu Aug 19 21:34:38 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Fri, 20 Aug 2021 06:34:38 +0200
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <99a74950-fdc0-ecfe-e5f0-ba4a7d8751f0@sholland.org>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-11-icenowy@sipeed.com>
 <99a74950-fdc0-ecfe-e5f0-ba4a7d8751f0@sholland.org>
Message-ID: <5432230.1UTMcGJKg4@jernej-laptop>

Hi Samuel!

Dne petek, 20. avgust 2021 ob 02:55:10 CEST je Samuel Holland napisal(a):
> On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> > Allwinner R329 has clock controls in PRCM, like other new Allwinner
> > SoCs.
> > 
> > Add support for them.
> > 
> > This driver is added before the main CCU because PLLs are controlled by
> > R-CCU on R329.
> > 
> > Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> > ---
> > 
> >  drivers/clk/sunxi-ng/Kconfig                  |   5 +
> >  drivers/clk/sunxi-ng/Makefile                 |   1 +
> >  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c      | 374 ++++++++++++++++++
> >  drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h      |  33 ++
> >  include/dt-bindings/clock/sun50i-r329-r-ccu.h |  33 ++
> >  include/dt-bindings/reset/sun50i-r329-r-ccu.h |  24 ++
> >  6 files changed, 470 insertions(+)
> >  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> >  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> >  create mode 100644 include/dt-bindings/clock/sun50i-r329-r-ccu.h
> >  create mode 100644 include/dt-bindings/reset/sun50i-r329-r-ccu.h
> > 
> > diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> > index cd46d8853876..e49b2c2fa5b7 100644
> > --- a/drivers/clk/sunxi-ng/Kconfig
> > +++ b/drivers/clk/sunxi-ng/Kconfig
> > @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
> > 
> >  	default ARM64 && ARCH_SUNXI
> >  	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> > 
> > +config SUN50I_R329_R_CCU
> > +	bool "Support for the Allwinner R329 PRCM CCU"
> > +	default ARM64 && ARCH_SUNXI
> > +	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> > +
> > 
> >  config SUN4I_A10_CCU
> >  
> >  	bool "Support for the Allwinner A10/A20 CCU"
> >  	default MACH_SUN4I
> > 
> > diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> > index 96c324306d97..db338a2188fd 100644
> > --- a/drivers/clk/sunxi-ng/Makefile
> > +++ b/drivers/clk/sunxi-ng/Makefile
> > @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-
r.o
> > 
> >  obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
> >  obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
> >  obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
> > 
> > +obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
> > 
> >  obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
> >  obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
> >  obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
> > 
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> > b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c new file mode 100644
> > index 000000000000..5413a701cb57
> > --- /dev/null
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.c
> > @@ -0,0 +1,374 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + * Based on the H616 CCU driver, which is:
> > + *   Copyright (c) 2020 Arm Ltd.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/io.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "ccu_common.h"
> > +#include "ccu_reset.h"
> > +
> > +#include "ccu_div.h"
> > +#include "ccu_gate.h"
> > +#include "ccu_mp.h"
> > +#include "ccu_mult.h"
> > +#include "ccu_nk.h"
> > +#include "ccu_nkm.h"
> > +#include "ccu_nkmp.h"
> > +#include "ccu_nm.h"
> > +
> > +#include "ccu-sun50i-r329-r.h"
> > +
> > +/*
> > + * The M factor is present in the register's description, but not in the
> > + * frequency formula, and it's documented as "The bit is only for
> > + * testing", so it's not modelled and then force to 0.
> > + */
> > +#define SUN50I_R329_PLL_CPUX_REG	0x1000
> > +static struct ccu_mult pll_cpux_clk = {
> > +	.enable		= BIT(31),
> > +	.lock		= BIT(28),
> > +	.mult		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> > +	.common		= {
> > +		.reg		= 0x1000,
> > +		.hw.init	= CLK_HW_INIT("pll-cpux", "osc24M",
> > +					      &ccu_mult_ops,
> > +					      
CLK_SET_RATE_UNGATE),
> > +	},
> > +};
> > +
> > +#define SUN50I_R329_PLL_PERIPH_REG	0x1010
> > +static struct ccu_nm pll_periph_base_clk = {
> > +	.enable		= BIT(31),
> > +	.lock		= BIT(28),
> > +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> > +	.m		= _SUNXI_CCU_DIV(1, 1), /* input divider */
> > +	.common		= {
> > +		.reg		= 0x1010,
> > +		.hw.init	= CLK_HW_INIT("pll-periph-base", "osc24M",
> > +					      &ccu_nm_ops,
> > +					      
CLK_SET_RATE_UNGATE),
> > +	},
> > +};
> > +
> > +static SUNXI_CCU_M(pll_periph_2x_clk, "pll-periph-2x", "pll-periph-base",
> > +		   0x1010, 16, 3, 0);
> > +static SUNXI_CCU_M(pll_periph_800m_clk, "pll-periph-800m",
> > "pll-periph-base", +		   0x1010, 20, 3, 0);
> 
> M as abbreviation for "mega" should be capitalized.
> 
> > +static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
> > +			   &pll_periph_2x_clk.common.hw, 2, 1, 0);
> > +
> > +#define SUN50I_R329_PLL_AUDIO0_REG	0x1020
> > +static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
> > +	{ .rate = 1548288000, .pattern = 0xc0070624, .m = 1, .n = 64 },
> > +};
> > +
> > +static struct ccu_nm pll_audio0_clk = {
> > +	.enable		= BIT(31),
> > +	.lock		= BIT(28),
> > +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> > +	.m		= _SUNXI_CCU_DIV(1, 1),
> > +	.sdm		= _SUNXI_CCU_SDM(pll_audio0_sdm_table,
> > +					 BIT(24), 0x1120, 
BIT(31)),
> > +	.common		= {
> > +		.features	= CCU_FEATURE_SIGMA_DELTA_MOD,
> > +		.reg		= 0x1020,
> > +		.hw.init	= CLK_HW_INIT("pll-audio0", "osc24M",
> > +					      &ccu_nm_ops,
> > +					      
CLK_SET_RATE_UNGATE),
> > +	},
> > +};
> > +
> > +static SUNXI_CCU_M(pll_audio0_div2_clk, "pll-audio0-div2", "pll-audio0",
> > +		   0x1020, 16, 3, 0);
> > +static SUNXI_CCU_M(pll_audio0_div5_clk, "pll-audio0-div5", "pll-audio0",
> > +		   0x1020, 20, 3, 0);
> > +
> > +/*
> > + * PLL-AUDIO1 has 3 dividers defined in the datasheet, however the
> > + * BSP driver always has M0 = 1 and M1 = 2 (this is also the
> > + * reset value in the register).
> > + *
> > + * Here just module it as NM clock, and force M0 = 1 and M1 = 2.
> > + */
> > +#define SUN50I_R329_PLL_AUDIO1_REG	0x1030
> > +static struct ccu_sdm_setting pll_audio1_4x_sdm_table[] = {
> > +	{ .rate = 22579200, .pattern = 0xc001288d, .m = 12, .n = 22 },
> > +	{ .rate = 24576000, .pattern = 0xc00126e9, .m = 12, .n = 24 },
> > +	{ .rate = 90316800, .pattern = 0xc001288d, .m = 3, .n = 22 },
> > +	{ .rate = 98304000, .pattern = 0xc00126e9, .m = 3, .n = 24 },
> > +};
> > +static struct ccu_nm pll_audio1_4x_clk = {
> > +	.enable		= BIT(31),
> > +	.lock		= BIT(28),
> > +	.n		= _SUNXI_CCU_MULT_MIN(8, 8, 12),
> > +	.m		= _SUNXI_CCU_DIV(16, 6),
> > +	.fixed_post_div	= 2,
> > +	.sdm		= _SUNXI_CCU_SDM(pll_audio1_4x_sdm_table,
> > +					 BIT(24), 0x1130, 
BIT(31)),
> > +	.common		= {
> > +		.features	= CCU_FEATURE_FIXED_POSTDIV |
> > +				  CCU_FEATURE_SIGMA_DELTA_MOD,
> > +		.reg		= 0x1030,
> > +		.hw.init	= CLK_HW_INIT("pll-audio1-4x", "osc24M",
> > +					      &ccu_nm_ops,
> > +					      
CLK_SET_RATE_UNGATE),
> > +	},
> > +};
> > +
> > +static CLK_FIXED_FACTOR_HW(pll_audio1_2x_clk, "pll-audio1-2x",
> > +			   &pll_audio1_4x_clk.common.hw, 2, 1,
> > +			   CLK_SET_RATE_PARENT);
> > +static CLK_FIXED_FACTOR_HW(pll_audio1_clk, "pll-audio1",
> > +			   &pll_audio1_4x_clk.common.hw, 4, 1,
> > +			   CLK_SET_RATE_PARENT);
> > +
> > +static const char * const r_bus_parents[] = { "osc24M", "osc32k", "iosc",
> > +					      "pll-periph-2x",
> > +					      "pll-audio0-
div2" };
> > +static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb", r_bus_parents, 0x000,
> > +			     0, 5,	/* M */
> > +			     8, 2,	/* P */
> > +			     24, 3,	/* mux */
> > +			     0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX(r_apb1_clk, "r-apb1", r_bus_parents, 0x00c,
> > +			     0, 5,	/* M */
> > +			     8, 2,	/* P */
> > +			     24, 3,	/* mux */
> > +			     0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX(r_apb2_clk, "r-apb2", r_bus_parents, 0x010,
> > +			     0, 5,	/* M */
> > +			     8, 2,	/* P */
> > +			     24, 3,	/* mux */
> > +			     0);
> 
> These are numbered 0 and 1 in the manual and in the BSP. Why number them
> differently here?
> 
> > +
> > +static SUNXI_CCU_GATE(r_bus_gpadc_clk, "r-bus-gpadc", "r-apb1",
> > +		      0x0ec, BIT(0), 0);
> > +static SUNXI_CCU_GATE(r_bus_ths_clk, "r-bus-ths", "r-apb1", 0x0fc,
> > BIT(0), 0); +
> > +static SUNXI_CCU_GATE(r_bus_dma_clk, "r-bus-dma", "r-apb1", 0x10c,
> > BIT(0), 0);
> BSP has R_TIMER at 0x11c and R_TWD at 0x12c.
> 
> > +
> > +static const char * const r_pwm_parents[] = { "osc24M", "osc32k", "iosc"
> > }; +static SUNXI_CCU_MUX_WITH_GATE(r_pwm_clk, "r-pwm", r_pwm_parents,
> > 0x130, +			       24, 3,	/* mux */
> > +			       BIT(31),	/* gate */
> > +			       0);
> > +
> > +static SUNXI_CCU_GATE(r_bus_pwm_clk, "r-bus-pwm", "r-apb1", 0x13c,
> > BIT(0), 0); +
> > +static const char * const r_audio_parents[] = { "pll-audio0-div5",
> > "pll-audio0-div2", +						
"pll-audio1-1x", "pll-audio1-4x" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_adc_clk, "r-codec-adc",
> > r_audio_parents, 0x140, +				  0, 5,	
	/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> 
> I don't think it matters much, but the audio and IR muxes are documented as
> being two bits wide.
> 
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_codec_dac_clk, "r-codec-dac",
> > r_audio_parents, 0x144, +				  0, 5,	
	/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +
> > +static SUNXI_CCU_GATE(r_bus_codec_clk, "r-bus-codec", "r-apb1",
> > +		      0x14c, BIT(0), 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_dmic_clk, "r-dmic", r_audio_parents,
> > 0x150, +				  0, 5,		/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +
> > +static SUNXI_CCU_GATE(r_bus_dmic_clk, "r-bus-dmic", "r-apb1", 0x15c,
> > BIT(0), 0); +static SUNXI_CCU_GATE(r_bus_lradc_clk, "r-bus-lradc",
> > "r-apb1",
> > +		      0x16c, BIT(0), 0);
> > +
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_clk, "r-i2s", r_audio_parents,
> > 0x170, +				  0, 5,		/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_i2s_asrc_clk, "r-i2s-asrc",
> > +				  r_audio_parents, 0x174,
> > +				  0, 5,		/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> 
> The BSP claims there is an R_I2S1 module clock at 0x178. Can you check if
> that exists? And the corresponding gate/reset bits in 0x17c?
> 
> > +static SUNXI_CCU_GATE(r_bus_i2s_clk, "r-bus-i2s", "r-apb1", 0x17c,
> > BIT(0), 0); +static SUNXI_CCU_GATE(r_bus_uart_clk, "r-bus-uart",
> > "r-apb2", 0x18c, BIT(0), 0); +static SUNXI_CCU_GATE(r_bus_i2c_clk,
> > "r-bus-i2c", "r-apb2", 0x19c, BIT(0), 0);
> R_PPU is at 0x1ac, and R_DSP is at 0x1bc.
> 
> > +
> > +static const char * const r_ir_parents[] = { "osc32k", "osc24M" };
> > +static SUNXI_CCU_MP_WITH_MUX_GATE(r_ir_clk, "r-ir", r_ir_parents, 0x1c0,
> > +				  0, 5,		/* M */
> > +				  8, 2,		/* P */
> > +				  24, 3,	/* mux */
> > +				  BIT(31),	/* gate */
> > +				  0);
> > +
> > +static SUNXI_CCU_GATE(r_bus_ir_clk, "r-bus-ir", "r-apb1", 0x1cc, BIT(0),
> > 0); +static SUNXI_CCU_GATE(r_bus_msgbox_clk, "r-bus-msgbox", "r-apb1",
> > +		      0x1dc, BIT(0), 0);
> > +static SUNXI_CCU_GATE(r_bus_spinlock_clk, "r-bus-spinlock", "r-apb1",
> > +		      0x1ec, BIT(0), 0);
> 
> R_DSP_SRAM is at 0x1fc.
> 
> > +static SUNXI_CCU_GATE(r_bus_rtc_clk, "r-bus-rtc", "r-ahb",
> > +		      0x20c, BIT(0), CLK_IS_CRITICAL);
> 
> Is this a workaround for the clock consumer missing from the RTC driver?
> 
> Also, there is a "PSARM" clock at 0x210 and its gate at 0x21c. I think this
> may refer to the NPU from ARM China?
> 
> Finally, there is a CPUCFG gate at 0x22c. I'm not sure which CPUCFG this
> refers to.
> > +
> > +static struct ccu_common *sun50i_r329_r_ccu_clks[] = {
> > +	&pll_cpux_clk.common,
> > +	&pll_periph_base_clk.common,
> > +	&pll_periph_2x_clk.common,
> > +	&pll_periph_800m_clk.common,
> > +	&pll_audio0_clk.common,
> > +	&pll_audio0_div2_clk.common,
> > +	&pll_audio0_div5_clk.common,
> > +	&pll_audio1_4x_clk.common,
> > +	&r_ahb_clk.common,
> > +	&r_apb1_clk.common,
> > +	&r_apb2_clk.common,
> > +	&r_bus_gpadc_clk.common,
> > +	&r_bus_ths_clk.common,
> > +	&r_bus_dma_clk.common,
> > +	&r_pwm_clk.common,
> > +	&r_bus_pwm_clk.common,
> > +	&r_codec_adc_clk.common,
> > +	&r_codec_dac_clk.common,
> > +	&r_bus_codec_clk.common,
> > +	&r_dmic_clk.common,
> > +	&r_bus_dmic_clk.common,
> > +	&r_bus_lradc_clk.common,
> > +	&r_i2s_clk.common,
> > +	&r_i2s_asrc_clk.common,
> > +	&r_bus_i2s_clk.common,
> > +	&r_bus_uart_clk.common,
> > +	&r_bus_i2c_clk.common,
> > +	&r_ir_clk.common,
> > +	&r_bus_ir_clk.common,
> > +	&r_bus_msgbox_clk.common,
> > +	&r_bus_spinlock_clk.common,
> > +	&r_bus_rtc_clk.common,
> > +};
> > +
> > +static struct clk_hw_onecell_data sun50i_r329_r_hw_clks = {
> > +	.hws	= {
> > +		[CLK_PLL_CPUX]		= 
&pll_cpux_clk.common.hw,
> > +		[CLK_PLL_PERIPH_BASE]	= 
&pll_periph_base_clk.common.hw,
> > +		[CLK_PLL_PERIPH_2X]	= &pll_periph_2x_clk.common.hw,
> > +		[CLK_PLL_PERIPH_800M]	= &pll_periph_800m_clk.common.hw,
> > +		[CLK_PLL_PERIPH]	= &pll_periph_clk.hw,
> > +		[CLK_PLL_AUDIO0]	= &pll_audio0_clk.common.hw,
> > +		[CLK_PLL_AUDIO0_DIV2]	= 
&pll_audio0_div2_clk.common.hw,
> > +		[CLK_PLL_AUDIO0_DIV5]	= 
&pll_audio0_div5_clk.common.hw,
> > +		[CLK_PLL_AUDIO1_4X]	= &pll_audio1_4x_clk.common.hw,
> > +		[CLK_PLL_AUDIO1_2X]	= &pll_audio1_2x_clk.hw,
> > +		[CLK_PLL_AUDIO1]	= &pll_audio1_clk.hw,
> > +		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
> > +		[CLK_R_APB1]		= 
&r_apb1_clk.common.hw,
> > +		[CLK_R_APB2]		= 
&r_apb2_clk.common.hw,
> > +		[CLK_R_BUS_GPADC]	= &r_bus_gpadc_clk.common.hw,
> > +		[CLK_R_BUS_THS]		= 
&r_bus_ths_clk.common.hw,
> > +		[CLK_R_BUS_DMA]		= 
&r_bus_dma_clk.common.hw,
> > +		[CLK_R_PWM]		= &r_pwm_clk.common.hw,
> > +		[CLK_R_BUS_PWM]		= 
&r_bus_pwm_clk.common.hw,
> > +		[CLK_R_CODEC_ADC]	= &r_codec_adc_clk.common.hw,
> > +		[CLK_R_CODEC_DAC]	= &r_codec_dac_clk.common.hw,
> > +		[CLK_R_BUS_CODEC]	= &r_bus_codec_clk.common.hw,
> > +		[CLK_R_DMIC]		= 
&r_dmic_clk.common.hw,
> > +		[CLK_R_BUS_DMIC]	= &r_bus_dmic_clk.common.hw,
> > +		[CLK_R_BUS_LRADC]	= &r_bus_lradc_clk.common.hw,
> > +		[CLK_R_I2S]		= &r_i2s_clk.common.hw,
> > +		[CLK_R_I2S_ASRC]	= &r_i2s_asrc_clk.common.hw,
> > +		[CLK_R_BUS_I2S]		= 
&r_bus_i2s_clk.common.hw,
> > +		[CLK_R_BUS_UART]	= &r_bus_uart_clk.common.hw,
> > +		[CLK_R_BUS_I2C]		= 
&r_bus_i2c_clk.common.hw,
> > +		[CLK_R_IR]		= &r_ir_clk.common.hw,
> > +		[CLK_R_BUS_IR]		= 
&r_bus_ir_clk.common.hw,
> > +		[CLK_R_BUS_MSGBOX]	= &r_bus_msgbox_clk.common.hw,
> > +		[CLK_R_BUS_SPINLOCK]	= &r_bus_spinlock_clk.common.hw,
> > +		[CLK_R_BUS_RTC]		= 
&r_bus_rtc_clk.common.hw,
> > +	},
> > +	.num = CLK_NUMBER,
> > +};
> > +
> > +static struct ccu_reset_map sun50i_r329_r_ccu_resets[] = {
> > +	[RST_R_BUS_GPADC]	= { 0x0ec, BIT(16) },
> > +	[RST_R_BUS_THS]		= { 0x0fc, BIT(16) },
> > +	[RST_R_BUS_DMA]		= { 0x10c, BIT(16) },
> > +	[RST_R_BUS_PWM]		= { 0x13c, BIT(16) },
> > +	[RST_R_BUS_CODEC]	= { 0x14c, BIT(16) },
> > +	[RST_R_BUS_DMIC]	= { 0x15c, BIT(16) },
> > +	[RST_R_BUS_LRADC]	= { 0x16c, BIT(16) },
> > +	[RST_R_BUS_I2S]		= { 0x17c, BIT(16) },
> > +	[RST_R_BUS_UART]	= { 0x18c, BIT(16) },
> > +	[RST_R_BUS_I2C]		= { 0x19c, BIT(16) },
> > +	[RST_R_BUS_IR]		= { 0x1cc, BIT(16) },
> > +	[RST_R_BUS_MSGBOX]	= { 0x1dc, BIT(16) },
> > +	[RST_R_BUS_SPINLOCK]	= { 0x1ec, BIT(16) },
> > +	[RST_R_BUS_RTC]		= { 0x20c, BIT(16) },
> > +};
> > +
> > +static const struct sunxi_ccu_desc sun50i_r329_r_ccu_desc = {
> > +	.ccu_clks	= sun50i_r329_r_ccu_clks,
> > +	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_r_ccu_clks),
> > +
> > +	.hw_clks	= &sun50i_r329_r_hw_clks,
> > +
> > +	.resets		= sun50i_r329_r_ccu_resets,
> > +	.num_resets	= ARRAY_SIZE(sun50i_r329_r_ccu_resets),
> > +};
> > +
> > +static const u32 pll_regs[] = {
> > +	SUN50I_R329_PLL_CPUX_REG,
> > +	SUN50I_R329_PLL_PERIPH_REG,
> > +	SUN50I_R329_PLL_AUDIO0_REG,
> > +	SUN50I_R329_PLL_AUDIO1_REG,
> > +};
> > +
> > +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> > +{
> > +	void __iomem *reg;
> > +	u32 val;
> > +	int i;
> > +
> > +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > +	if (IS_ERR(reg)) {
> > +		pr_err("%pOF: Could not map clock registers\n", node);
> > +		return;
> > +	}
> > +
> > +	/* Enable the lock bits and the output enable bits on all PLLs */
> > +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> > +		val = readl(reg + pll_regs[i]);
> > +		val |= BIT(29) | BIT(27);
> > +		writel(val, reg + pll_regs[i]);
> > +	}
> > +
> > +	/*
> > +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> > +	 *
> > +	 * See the comment before pll-audio1 definition for the reason.
> > +	 */
> > +
> > +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> > +	val &= ~BIT(1);
> > +	val |= BIT(0);
> > +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> > +
> > +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> > +	if (i)
> > +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> > +}
> > +
> > +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> > +	       sun50i_r329_r_ccu_setup);
> 
> Please make this a platform driver. There is no particular reason why it
> needs to be an early OF clock provider.

Why? It's good to have it as early clock provider. It has no dependencies and 
other drivers that depends on it, like IR, can be deferred, if this is loaded 
later.

Best regards,
Jernej

> 
> Regards,
> Samuel
> 
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> > b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h new file mode 100644
> > index 000000000000..62cf65322116
> > --- /dev/null
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329-r.h
> > @@ -0,0 +1,33 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _CCU_SUN50I_R329_R_H
> > +#define _CCU_SUN50I_R329_R_H
> > +
> > +#include <dt-bindings/clock/sun50i-r329-r-ccu.h>
> > +#include <dt-bindings/reset/sun50i-r329-r-ccu.h>
> > +
> > +#define CLK_PLL_CPUX		0
> > +#define CLK_PLL_PERIPH_BASE	1
> > +#define CLK_PLL_PERIPH_2X	2
> > +#define CLK_PLL_PERIPH_800M	3
> > +#define CLK_PLL_PERIPH		4
> > +#define CLK_PLL_AUDIO0		5
> > +#define CLK_PLL_AUDIO0_DIV2	6
> > +#define CLK_PLL_AUDIO0_DIV5	7
> > +#define CLK_PLL_AUDIO1_4X	8
> > +#define CLK_PLL_AUDIO1_2X	9
> > +#define CLK_PLL_AUDIO1		10
> > +#define CLK_R_AHB		11
> > +
> > +/* R_APB1 exported for PIO */
> > +
> > +#define CLK_R_APB2		13
> > +
> > +/* All module / bus gate clocks exported */
> > +
> > +#define CLK_NUMBER	(CLK_R_BUS_RTC + 1)
> > +
> > +#endif /* _CCU_SUN50I_R329_R_H */
> > diff --git a/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> > b/include/dt-bindings/clock/sun50i-r329-r-ccu.h new file mode 100644
> > index 000000000000..df9bc58de5c4
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/sun50i-r329-r-ccu.h
> > @@ -0,0 +1,33 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> > +#define _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_
> > +
> > +#define CLK_R_APB1		12
> > +
> > +#define CLK_R_BUS_GPADC		14
> > +#define CLK_R_BUS_THS		15
> > +#define CLK_R_BUS_DMA		16
> > +#define CLK_R_PWM		17
> > +#define CLK_R_BUS_PWM		18
> > +#define CLK_R_CODEC_ADC		19
> > +#define CLK_R_CODEC_DAC		20
> > +#define CLK_R_BUS_CODEC		21
> > +#define CLK_R_DMIC		22
> > +#define CLK_R_BUS_DMIC		23
> > +#define CLK_R_BUS_LRADC		24
> > +#define CLK_R_I2S		25
> > +#define CLK_R_I2S_ASRC		26
> > +#define CLK_R_BUS_I2S		27
> > +#define CLK_R_BUS_UART		28
> > +#define CLK_R_BUS_I2C		29
> > +#define CLK_R_IR		30
> > +#define CLK_R_BUS_IR		31
> > +#define CLK_R_BUS_MSGBOX	32
> > +#define CLK_R_BUS_SPINLOCK	33
> > +#define CLK_R_BUS_RTC		34
> > +
> > +#endif /* _DT_BINDINGS_CLK_SUN50I_R329_R_CCU_H_ */
> > diff --git a/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> > b/include/dt-bindings/reset/sun50i-r329-r-ccu.h new file mode 100644
> > index 000000000000..40644f2f21c6
> > --- /dev/null
> > +++ b/include/dt-bindings/reset/sun50i-r329-r-ccu.h
> > @@ -0,0 +1,24 @@
> > +/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
> > +/*
> > + * Copyright (c) 2021 Sipeed
> > + */
> > +
> > +#ifndef _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> > +#define _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_
> > +
> > +#define RST_R_BUS_GPADC		0
> > +#define RST_R_BUS_THS		1
> > +#define RST_R_BUS_DMA		2
> > +#define RST_R_BUS_PWM		3
> > +#define RST_R_BUS_CODEC		4
> > +#define RST_R_BUS_DMIC		5
> > +#define RST_R_BUS_LRADC		6
> > +#define RST_R_BUS_I2S		7
> > +#define RST_R_BUS_UART		8
> > +#define RST_R_BUS_I2C		9
> > +#define RST_R_BUS_IR		10
> > +#define RST_R_BUS_MSGBOX	11
> > +#define RST_R_BUS_SPINLOCK	12
> > +#define RST_R_BUS_RTC		13
> > +
> > +#endif /* _DT_BINDINGS_RST_SUN50I_R329_R_CCU_H_ */






From lkp at intel.com  Thu Aug 19 22:32:48 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 20 Aug 2021 13:32:48 +0800
Subject: [soc:arm/drivers] BUILD SUCCESS
 5c785014b67fb25d8e2a36d24940dad0c416a005
Message-ID: <611f3e80.Yadi0bMmeuFfvQuU%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/drivers
branch HEAD: 5c785014b67fb25d8e2a36d24940dad0c416a005  Merge tag 'qcom-drivers-for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/drivers

elapsed time: 2366m

configs tested: 125
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210818
powerpc                      ep88xc_defconfig
arm                         at91_dt_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                     loongson1c_defconfig
arm                        mvebu_v5_defconfig
sh                          rsk7203_defconfig
m68k                             allmodconfig
arm                           stm32_defconfig
powerpc                       ppc64_defconfig
mips                 decstation_r4k_defconfig
mips                           ip27_defconfig
arm                         bcm2835_defconfig
m68k                        m5307c3_defconfig
arm                         mv78xx0_defconfig
sh                     magicpanelr2_defconfig
alpha                            alldefconfig
sh                     sh7710voipgw_defconfig
sh                          r7780mp_defconfig
x86_64                           alldefconfig
mips                        jmr3927_defconfig
powerpc                      acadia_defconfig
mips                   sb1250_swarm_defconfig
arm                  colibri_pxa300_defconfig
sh                   sh7724_generic_defconfig
sparc                            alldefconfig
arm                       imx_v4_v5_defconfig
mips                      pic32mzda_defconfig
sh                        apsh4ad0a_defconfig
xtensa                          iss_defconfig
sh                           se7780_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
x86_64               randconfig-a006-20210816
x86_64               randconfig-a004-20210816
x86_64               randconfig-a003-20210816
x86_64               randconfig-a001-20210816
x86_64               randconfig-a005-20210816
x86_64               randconfig-a002-20210816
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
x86_64               randconfig-a013-20210819
x86_64               randconfig-a011-20210819
x86_64               randconfig-a012-20210819
x86_64               randconfig-a016-20210819
x86_64               randconfig-a014-20210819
x86_64               randconfig-a015-20210819
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
i386                 randconfig-a004-20210817
i386                 randconfig-a003-20210817
i386                 randconfig-a001-20210817
i386                 randconfig-a002-20210817
i386                 randconfig-a006-20210817
i386                 randconfig-a005-20210817
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From alain.volmat at foss.st.com  Thu Aug 19 23:32:02 2021
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Fri, 20 Aug 2021 08:32:02 +0200
Subject: [PATCH linux-next] spi-stm32: fix Coccinelle warnings
In-Reply-To: <20210820031952.12746-1-jing.yangyang@zte.com.cn>
References: <20210820031952.12746-1-jing.yangyang@zte.com.cn>
Message-ID: <20210820063202.GA21711@gnbcxd0016.gnb.st.com>

Hi,

thanks for the patch. We've had this issue reported previously with a patch
provided at
(https://lore.kernel.org/linux-spi/20210713191004.GA14729 at 5eb5c2cbef84/).
I've put my reviewed-by so it should make its way to the linux-next soon.

Regards,
Alain

On Thu, Aug 19, 2021 at 08:19:52PM -0700, CGEL wrote:
> From: jing yangyang <jing.yangyang at zte.com.cn>
> 
> WARNING !A || A && B is equivalent to !A || B
> 
> This issue was detected with the help of Coccinelle.
> 
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
> ---
>  drivers/spi/spi-stm32.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
> index 14ca7ea..cc4a731 100644
> --- a/drivers/spi/spi-stm32.c
> +++ b/drivers/spi/spi-stm32.c
> @@ -912,8 +912,8 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
>  		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
>  			stm32h7_spi_read_rxfifo(spi);
>  		if (!spi->cur_usedma ||
> -		    (spi->cur_usedma && (spi->cur_comm == SPI_SIMPLEX_TX ||
> -		     spi->cur_comm == SPI_3WIRE_TX)))
> +			(spi->cur_comm == SPI_SIMPLEX_TX ||
> +			spi->cur_comm == SPI_3WIRE_TX))
>  			end = true;
>  	}
>  
> -- 
> 1.8.3.1
> 
> 


From anshuman.khandual at arm.com  Thu Aug 19 23:35:31 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Aug 2021 12:05:31 +0530
Subject: [PATCH] arm64/mm: Drop page-def.h
Message-ID: <1629441331-19530-1-git-send-email-anshuman.khandual@arm.com>

PAGE_SHIFT (PAGE_SIZE and PAGE_MASK) which is derived from ARM64_PAGE_SHIFT
should be moved into pgtable-hwdef.h instead, and subsequently page-def.h
can be just dropped off completely.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on 5.14-rc6. Could move these definitions into <asm/page.h>
if that is preferred. But <asm/page-def.h> is neither really required as
a separate header nor is present on other platforms.

 arch/arm64/include/asm/memory.h        |  2 +-
 arch/arm64/include/asm/page-def.h      | 18 ------------------
 arch/arm64/include/asm/page.h          |  2 +-
 arch/arm64/include/asm/pgtable-hwdef.h |  4 ++++
 4 files changed, 6 insertions(+), 20 deletions(-)
 delete mode 100644 arch/arm64/include/asm/page-def.h

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 824a3655dd93..f987204c716a 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -12,7 +12,7 @@
 
 #include <linux/const.h>
 #include <linux/sizes.h>
-#include <asm/page-def.h>
+#include <asm/pgtable-hwdef.h>
 
 /*
  * Size of the PCI I/O space. This must remain a power of two so that
diff --git a/arch/arm64/include/asm/page-def.h b/arch/arm64/include/asm/page-def.h
deleted file mode 100644
index 2403f7b4cdbf..000000000000
--- a/arch/arm64/include/asm/page-def.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Based on arch/arm/include/asm/page.h
- *
- * Copyright (C) 1995-2003 Russell King
- * Copyright (C) 2017 ARM Ltd.
- */
-#ifndef __ASM_PAGE_DEF_H
-#define __ASM_PAGE_DEF_H
-
-#include <linux/const.h>
-
-/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT		CONFIG_ARM64_PAGE_SHIFT
-#define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)
-#define PAGE_MASK		(~(PAGE_SIZE-1))
-
-#endif /* __ASM_PAGE_DEF_H */
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 993a27ea6f54..40313964d4b2 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -8,7 +8,7 @@
 #ifndef __ASM_PAGE_H
 #define __ASM_PAGE_H
 
-#include <asm/page-def.h>
+#include <asm/pgtable-hwdef.h>
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 40085e53f573..be8045080ebd 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -5,6 +5,10 @@
 #ifndef __ASM_PGTABLE_HWDEF_H
 #define __ASM_PGTABLE_HWDEF_H
 
+#define PAGE_SHIFT		CONFIG_ARM64_PAGE_SHIFT
+#define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK		(~(PAGE_SIZE-1))
+
 #include <asm/memory.h>
 
 /*
-- 
2.20.1



From bigeasy at linutronix.de  Thu Aug 19 23:54:17 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Fri, 20 Aug 2021 08:54:17 +0200
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <20b9051fe47b7068ed3496bd7f5d417b1af69e3a.camel@redhat.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20b9051fe47b7068ed3496bd7f5d417b1af69e3a.camel@redhat.com>
Message-ID: <20210820065417.epdjfqsn27gmnx4x@linutronix.de>

On 2021-08-19 22:23:37 [-0500], Scott Wood wrote:
> On Tue, 2021-08-17 at 16:40 +0200, Sebastian Andrzej Siewior wrote:
> > [bigeasy: remove 'preempt_disable(); local_bh_disable(); preempt_enable();
> >  local_bh_enable();' from the examples because this works on RT now. ]
> 
> Does it actually work?  If preemption is disabled during local_bh_disable,
> softirq_ctrl.lock won't be taken.  If you then get preempted between the
> preempt_enable() and the local_bh_enable(), and another task tries to do
> local_bh_disable(), won't it successfully get softirq_ctrl.lock, add to
> softirq_ctrl.cnt, and proceed right into the critical section?
> 
> Or am I missing something?

No, I mixed it up with migrate_disable/enable. I corrected it while
redoing it yesterday.

> -Scott

Sebastian


From joel at jms.id.au  Thu Aug 19 23:57:24 2021
From: joel at jms.id.au (Joel Stanley)
Date: Fri, 20 Aug 2021 06:57:24 +0000
Subject: [GIT PULL] ARM: aspeed: defconfig changes for 5.15
Message-ID: <CACPK8XdzKdnyrpjKukGWieBhLgQnBs+y=LuSr_weot=Ovy3+9A@mail.gmail.com>

Dear Soc maintainers,

This is the last of the aspeed pull requests for v5.15.

Apologies for drip feeding them, I was pressed for time so I started
with the most important and worked down the list.

The following changes since commit 2734d6c1b1a089fb593ef6a23d4b70903526fe0c:

  Linux 5.14-rc2 (2021-07-18 14:13:49 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/joel/bmc.git
tags/aspeed-5.15-defconfig

for you to fetch changes up to a4836d5ad127fe31fecb29878d81f2e9b4a5591c:

  ARM: config: aspeed: Regenerate defconfigs (2021-08-19 16:33:43 +0930)

----------------------------------------------------------------
ASPEED defconfig updates for 5.15

 - Enable new KCS SerIO driver

 - Enable SGPIO and EDAC for AST2400 now they are supported there

 - Switch to SLUB and enable SLAB_FREELIST_HARDENED

 - Regenerate defconfigs atop v5.14-rc2

----------------------------------------------------------------
Joel Stanley (4):
      ARM: config: aspeed: Enable hardened allocator feature
      ARM: config: aspeed: Enable KCS adapter for raw SerIO
      ARM: config: aspeed_g4: Enable EDAC and SPGIO
      ARM: config: aspeed: Regenerate defconfigs

 arch/arm/configs/aspeed_g4_defconfig | 16 +++++-----------
 arch/arm/configs/aspeed_g5_defconfig | 25 +++++++++----------------
 2 files changed, 14 insertions(+), 27 deletions(-)


From chunfeng.yun at mediatek.com  Thu Aug 19 23:59:12 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 20 Aug 2021 14:59:12 +0800
Subject: [PATCH next 1/2] Revert "usb: xhci-mtk: relax TT periodic bandwidth
 allocation"
Message-ID: <20210820065913.64490-1-chunfeng.yun@mediatek.com>

As discussed in following patch:
https://patchwork.kernel.org/patch/12420339

No need calculate number of uframes again, but should use value
form check_sch_tt(), if we plan to remove extra CS, also can do
it in check_sch_tt(). So revert this patch, and prepare to send
new patch for it.

This reverts commit 548011957d1d72e0b662300c8b32b81d593b796e.

Cc: Ikjoon Jang <ikjn at chromium.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk-sch.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 46cbf5d54f4f..f9b4d27ce449 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -459,17 +459,16 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 	u32 num_esit, tmp;
 	int base;
 	int i, j;
-	u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
 
 	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-
-	if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
-		offset++;
-
 	for (i = 0; i < num_esit; i++) {
 		base = offset + i * sch_ep->esit;
 
-		for (j = 0; j < uframes; j++) {
+		/*
+		 * Compared with hs bus, no matter what ep type,
+		 * the hub will always delay one uframe to send data
+		 */
+		for (j = 0; j < sch_ep->cs_count; j++) {
 			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
 			if (tmp > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
@@ -547,8 +546,6 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	u32 base, num_esit;
 	int bw_updated;
 	int i, j;
-	int offset = sch_ep->offset;
-	u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
 
 	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
 
@@ -557,13 +554,10 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	else
 		bw_updated = -sch_ep->bw_cost_per_microframe;
 
-	if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
-		offset++;
-
 	for (i = 0; i < num_esit; i++) {
-		base = offset + i * sch_ep->esit;
+		base = sch_ep->offset + i * sch_ep->esit;
 
-		for (j = 0; j < uframes; j++)
+		for (j = 0; j < sch_ep->cs_count; j++)
 			tt->fs_bus_bw[base + j] += bw_updated;
 	}
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 19 23:59:13 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 20 Aug 2021 14:59:13 +0800
Subject: [PATCH next 2/2] Revert "usb: xhci-mtk: Do not use xhci's virt_dev in
 drop_endpoint"
In-Reply-To: <20210820065913.64490-1-chunfeng.yun@mediatek.com>
References: <20210820065913.64490-1-chunfeng.yun@mediatek.com>
Message-ID: <20210820065913.64490-2-chunfeng.yun@mediatek.com>

I find the patch introduce some issues, e.g.
1. oops happens when xhci_gen_setup() failed, and hash is not init
   but try to destroy it;
2. memory leakage happens when fail to insert ep, need free sch_ep,
   or insert ep after insert int list;
3. memory leakage happens when fail to allocate sch_array, need destroy
   rhashtable;
4. it's better to check ep->hcpriv when drop ep;

so prefer to revert this patch, and resend it after the issues are fixed.

This reverts commit b8731209958a1dffccc2888121f4c0280c990550.

Cc: Ikjoon Jang <ikjn at chromium.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/xhci-mtk-sch.c | 140 ++++++++++++++------------------
 drivers/usb/host/xhci-mtk.h     |  15 ++--
 2 files changed, 69 insertions(+), 86 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index f9b4d27ce449..cffcaf4dfa9f 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -80,7 +80,7 @@ decode_ep(struct usb_host_endpoint *ep, enum usb_device_speed speed)
 		interval /= 1000;
 	}
 
-	snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s",
+	snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s\n",
 		 usb_speed_string(speed), usb_endpoint_num(epd),
 		 usb_endpoint_dir_in(epd) ? "in" : "out",
 		 usb_ep_type_string(usb_endpoint_type(epd)),
@@ -129,12 +129,6 @@ get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
 	int bw_index;
 
 	virt_dev = xhci->devs[udev->slot_id];
-	if (WARN_ONCE(!virt_dev, "xhci-mtk: usb %s has no virt_dev\n",
-				dev_name(&udev->dev)))
-		return NULL;
-	if (WARN_ONCE(!virt_dev->real_port, "xhci-mtk: usb %s has invalid port number\n",
-			dev_name(&udev->dev)))
-		return NULL;
 
 	if (udev->speed >= USB_SPEED_SUPER) {
 		if (usb_endpoint_dir_out(&ep->desc))
@@ -200,6 +194,7 @@ static struct mu3h_sch_tt *find_tt(struct usb_device *udev)
 			}
 			return ERR_PTR(-ENOMEM);
 		}
+		INIT_LIST_HEAD(&tt->ep_list);
 		*ptt = tt;
 	}
 
@@ -229,7 +224,7 @@ static void drop_tt(struct usb_device *udev)
 	}
 
 	tt = *ptt;
-	if (!tt || tt->nr_eps > 0)
+	if (!tt || !list_empty(&tt->ep_list))
 		return;		/* never allocated , or still in use*/
 
 	*ptt = NULL;
@@ -241,19 +236,13 @@ static void drop_tt(struct usb_device *udev)
 	}
 }
 
-static struct mu3h_sch_ep_info *create_sch_ep(struct xhci_hcd_mtk *mtk,
-		struct usb_device *udev, struct usb_host_endpoint *ep,
-		struct xhci_ep_ctx *ep_ctx)
+static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
+	struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
 {
 	struct mu3h_sch_ep_info *sch_ep;
 	struct mu3h_sch_tt *tt = NULL;
 	u32 len_bw_budget_table;
 	size_t mem_size;
-	struct mu3h_sch_bw_info *bw_info;
-
-	bw_info = get_bw_info(mtk, udev, ep);
-	if (!bw_info)
-		return ERR_PTR(-ENODEV);
 
 	if (is_fs_or_ls(udev->speed))
 		len_bw_budget_table = TT_MICROFRAMES_MAX;
@@ -277,10 +266,11 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct xhci_hcd_mtk *mtk,
 		}
 	}
 
-	sch_ep->bw_info = bw_info;
 	sch_ep->sch_tt = tt;
 	sch_ep->ep = ep;
 	sch_ep->speed = udev->speed;
+	INIT_LIST_HEAD(&sch_ep->endpoint);
+	INIT_LIST_HEAD(&sch_ep->tt_endpoint);
 
 	return sch_ep;
 }
@@ -562,9 +552,9 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	}
 
 	if (used)
-		tt->nr_eps++;
-	else if (!WARN_ONCE(tt->nr_eps < 1, "unbalanced sch_tt's ep count"))
-		tt->nr_eps--;
+		list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list);
+	else
+		list_del(&sch_ep->tt_endpoint);
 }
 
 static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw,
@@ -595,9 +585,9 @@ static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
 	return boundary;
 }
 
-static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
+static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
+			struct mu3h_sch_ep_info *sch_ep)
 {
-	struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info;
 	const u32 esit_boundary = get_esit_boundary(sch_ep);
 	const u32 bw_boundary = get_bw_boundary(sch_ep->speed);
 	u32 offset;
@@ -643,33 +633,23 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 	return load_ep_bw(sch_bw, sch_ep, true);
 }
 
-static const struct rhashtable_params sch_ep_table_param = {
-	.key_len	= sizeof(struct usb_host_endpoint *),
-	.key_offset	= offsetof(struct mu3h_sch_ep_info, ep),
-	.head_offset	= offsetof(struct mu3h_sch_ep_info, ep_link),
-};
-
-static void destroy_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
-			   struct mu3h_sch_ep_info *sch_ep)
+static void destroy_sch_ep(struct usb_device *udev,
+	struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
 {
 	/* only release ep bw check passed by check_sch_bw() */
 	if (sch_ep->allocated)
-		load_ep_bw(sch_ep->bw_info, sch_ep, false);
+		load_ep_bw(sch_bw, sch_ep, false);
 
 	if (sch_ep->sch_tt)
 		drop_tt(udev);
 
 	list_del(&sch_ep->endpoint);
-	rhashtable_remove_fast(&mtk->sch_ep_table, &sch_ep->ep_link,
-				sch_ep_table_param);
 	kfree(sch_ep);
 }
 
-static bool need_bw_sch(struct usb_device *udev,
-			struct usb_host_endpoint *ep)
+static bool need_bw_sch(struct usb_host_endpoint *ep,
+	enum usb_device_speed speed, int has_tt)
 {
-	bool has_tt = udev->tt && udev->tt->hub->parent;
-
 	/* only for periodic endpoints */
 	if (usb_endpoint_xfer_control(&ep->desc)
 		|| usb_endpoint_xfer_bulk(&ep->desc))
@@ -680,7 +660,7 @@ static bool need_bw_sch(struct usb_device *udev,
 	 * a TT are also ignored, root-hub will schedule them directly,
 	 * but need set @bpkts field of endpoint context to 1.
 	 */
-	if (is_fs_or_ls(udev->speed) && !has_tt)
+	if (is_fs_or_ls(speed) && !has_tt)
 		return false;
 
 	/* skip endpoint with zero maxpkt */
@@ -695,12 +675,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 	struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd);
 	struct mu3h_sch_bw_info *sch_array;
 	int num_usb_bus;
-	int ret;
-
-	/* mu3h_sch_ep_info table, 'usb_host_endpoint*' as a key */
-	ret = rhashtable_init(&mtk->sch_ep_table, &sch_ep_table_param);
-	if (ret)
-		return ret;
+	int i;
 
 	/* ss IN and OUT are separated */
 	num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports;
@@ -709,6 +684,9 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 	if (sch_array == NULL)
 		return -ENOMEM;
 
+	for (i = 0; i < num_usb_bus; i++)
+		INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
+
 	mtk->sch_array = sch_array;
 
 	INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
@@ -718,7 +696,6 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 
 void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk)
 {
-	rhashtable_destroy(&mtk->sch_ep_table);
 	kfree(mtk->sch_array);
 }
 
@@ -736,7 +713,9 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 	ep_index = xhci_get_endpoint_index(&ep->desc);
 	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
 
-	if (!need_bw_sch(udev, ep)) {
+	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
+
+	if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info)) {
 		/*
 		 * set @bpkts to 1 if it is LS or FS periodic endpoint, and its
 		 * device does not connected through an external HS hub
@@ -748,22 +727,14 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 		return 0;
 	}
 
-	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
-
-	sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx);
+	sch_ep = create_sch_ep(udev, ep, ep_ctx);
 	if (IS_ERR_OR_NULL(sch_ep))
 		return -ENOMEM;
 
-	if (rhashtable_insert_fast(&mtk->sch_ep_table, &sch_ep->ep_link,
-				   sch_ep_table_param))
-		return -EEXIST;
-
 	setup_sch_info(ep_ctx, sch_ep);
 
 	list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list);
 
-	xhci_dbg(xhci, "added sch_ep %p : %p\n", sch_ep, ep);
-
 	return 0;
 }
 
@@ -772,20 +743,25 @@ static void drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 {
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct mu3h_sch_ep_info *sch_ep;
-	void *key = ep;
+	struct xhci_virt_device *virt_dev;
+	struct mu3h_sch_bw_info *sch_bw;
+	struct mu3h_sch_ep_info *sch_ep, *tmp;
 
-	if (!need_bw_sch(udev, ep))
-		return;
+	virt_dev = xhci->devs[udev->slot_id];
 
 	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
 
-	sch_ep = rhashtable_lookup_fast(&mtk->sch_ep_table, &key,
-					sch_ep_table_param);
-	if (sch_ep)
-		destroy_sch_ep(mtk, udev, sch_ep);
-	else
-		xhci_dbg(xhci, "ep %p is not on the bw table\n", ep);
+	if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info))
+		return;
+
+	sch_bw = get_bw_info(mtk, udev, ep);
+
+	list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) {
+		if (sch_ep->ep == ep) {
+			destroy_sch_ep(udev, sch_bw, sch_ep);
+			break;
+		}
+	}
 }
 
 int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
@@ -793,22 +769,30 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 	struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
-	struct mu3h_sch_ep_info *sch_ep;
+	struct mu3h_sch_bw_info *sch_bw;
+	struct mu3h_sch_ep_info *sch_ep, *tmp;
 	int ret;
 
 	xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
 
 	list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) {
-		struct xhci_ep_ctx *ep_ctx;
-		struct usb_host_endpoint *ep = sch_ep->ep;
-		unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
+		sch_bw = get_bw_info(mtk, udev, sch_ep->ep);
 
-		ret = check_sch_bw(sch_ep);
+		ret = check_sch_bw(sch_bw, sch_ep);
 		if (ret) {
 			xhci_err(xhci, "Not enough bandwidth! (%s)\n",
 				 sch_error_string(-ret));
 			return -ENOSPC;
 		}
+	}
+
+	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
+		struct xhci_ep_ctx *ep_ctx;
+		struct usb_host_endpoint *ep = sch_ep->ep;
+		unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
+
+		sch_bw = get_bw_info(mtk, udev, ep);
+		list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
 
 		ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
 		ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(sch_ep->pkts)
@@ -822,23 +806,22 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 			sch_ep->offset, sch_ep->repeat);
 	}
 
-	ret = xhci_check_bandwidth(hcd, udev);
-	if (!ret)
-		INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
-
-	return ret;
+	return xhci_check_bandwidth(hcd, udev);
 }
 
 void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 {
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	struct mu3h_sch_bw_info *sch_bw;
 	struct mu3h_sch_ep_info *sch_ep, *tmp;
 
 	xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
 
-	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint)
-		destroy_sch_ep(mtk, udev, sch_ep);
+	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
+		sch_bw = get_bw_info(mtk, udev, sch_ep->ep);
+		destroy_sch_ep(udev, sch_bw, sch_ep);
+	}
 
 	xhci_reset_bandwidth(hcd, udev);
 }
@@ -867,7 +850,8 @@ int xhci_mtk_drop_ep(struct usb_hcd *hcd, struct usb_device *udev,
 	if (ret)
 		return ret;
 
-	drop_ep_quirk(hcd, udev, ep);
+	if (ep->hcpriv)
+		drop_ep_quirk(hcd, udev, ep);
 
 	return 0;
 }
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index ddcf25524f67..ace432356c41 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -10,7 +10,6 @@
 #define _XHCI_MTK_H_
 
 #include <linux/clk.h>
-#include <linux/rhashtable.h>
 
 #include "xhci.h"
 
@@ -26,34 +25,36 @@
 
 /**
  * @fs_bus_bw: array to keep track of bandwidth already used for FS
- * @nr_eps: number of endpoints using this TT
+ * @ep_list: Endpoints using this TT
  */
 struct mu3h_sch_tt {
 	u32 fs_bus_bw[XHCI_MTK_MAX_ESIT];
-	int nr_eps;
+	struct list_head ep_list;
 };
 
 /**
  * struct mu3h_sch_bw_info: schedule information for bandwidth domain
  *
  * @bus_bw: array to keep track of bandwidth already used at each uframes
+ * @bw_ep_list: eps in the bandwidth domain
  *
  * treat a HS root port as a bandwidth domain, but treat a SS root port as
  * two bandwidth domains, one for IN eps and another for OUT eps.
  */
 struct mu3h_sch_bw_info {
 	u32 bus_bw[XHCI_MTK_MAX_ESIT];
+	struct list_head bw_ep_list;
 };
 
 /**
  * struct mu3h_sch_ep_info: schedule information for endpoint
  *
- * @bw_info: bandwidth domain which this endpoint belongs
  * @esit: unit is 125us, equal to 2 << Interval field in ep-context
  * @num_budget_microframes: number of continuous uframes
  *		(@repeat==1) scheduled within the interval
  * @bw_cost_per_microframe: bandwidth cost per microframe
- * @endpoint: linked into bw_ep_chk_list, used by check_bandwidth hook
+ * @endpoint: linked into bandwidth domain which it belongs to
+ * @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to
  * @sch_tt: mu3h_sch_tt linked into
  * @ep_type: endpoint type
  * @maxpkt: max packet size of endpoint
@@ -81,12 +82,11 @@ struct mu3h_sch_ep_info {
 	u32 num_budget_microframes;
 	u32 bw_cost_per_microframe;
 	struct list_head endpoint;
-	struct mu3h_sch_bw_info *bw_info;
+	struct list_head tt_endpoint;
 	struct mu3h_sch_tt *sch_tt;
 	u32 ep_type;
 	u32 maxpkt;
 	struct usb_host_endpoint *ep;
-	struct rhash_head ep_link;
 	enum usb_device_speed speed;
 	bool allocated;
 	/*
@@ -134,7 +134,6 @@ struct xhci_hcd_mtk {
 	struct device *dev;
 	struct usb_hcd *hcd;
 	struct mu3h_sch_bw_info *sch_array;
-	struct rhashtable sch_ep_table;
 	struct list_head bw_ep_chk_list;
 	struct mu3c_ippc_regs __iomem *ippc_regs;
 	int num_u2_ports;
-- 
2.18.0

From sean.wang at mediatek.com  Fri Aug 20 00:01:13 2021
From: sean.wang at mediatek.com (sean.wang at mediatek.com)
Date: Fri, 20 Aug 2021 15:01:13 +0800
Subject: [v2,
 04/12] pinctrl: mediatek: moore: check if pin_desc is valid before use
In-Reply-To: <20210817074557.30953-5-sam.shih@mediatek.com--annotate>
References: <20210817074557.30953-5-sam.shih@mediatek.com--annotate>
Message-ID: <1629442873-24655-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang at mediatek.com>

>Certain SoC are missing the middle part gpios in consecutive pins, it's better to check if mtk_pin_desc is a valid pin for the extensibility
>
>Signed-off-by: Sam Shih <sam.shih at mediatek.com>
>


>---
>v2: applied the comment suggested by reviewers:
>    - for the pins not ballout, we can fill .name in struct mtk_pin_desc
>      as NULL and return -ENOTSUPP in gpio/pinconf ops.

Thanks for take the suggestion and the improvement.
Acked-by: Sean Wang <sean.wang at mediatek.com>

>
>---
> drivers/pinctrl/mediatek/pinctrl-moore.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
>diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c
>index 3a4a23c40a71..ad3b67163973 100644
>--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
>+++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
>@@ -60,6 +60,8 @@ static int mtk_pinmux_set_mux(struct pinctrl_dev *pctldev,
>		int pin = grp->pins[i];
>
>		desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
>+		if (!desc->name)
>+			return -ENOTSUPP;
>
>		mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
>				 pin_modes[i]);
>@@ -76,6 +78,8 @@ static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
>	const struct mtk_pin_desc *desc;
>
>	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
>+	if (!desc->name)
>+		return -ENOTSUPP;

<snip>

From amit.kachhap at arm.com  Fri Aug 20 00:09:39 2021
From: amit.kachhap at arm.com (Amit Kachhap)
Date: Fri, 20 Aug 2021 12:39:39 +0530
Subject: [PATCH] kselftest/arm64: pac: Fix skipping of tests on systems
 without PAC
In-Reply-To: <20210819165723.43903-1-broonie@kernel.org>
References: <20210819165723.43903-1-broonie@kernel.org>
Message-ID: <a988b3e2-5f88-fbd5-99da-2066a65a17b2@arm.com>



On 8/19/21 10:27 PM, Mark Brown wrote:
> The PAC tests check to see if the system supports the relevant PAC features
> but instead of skipping the tests if they can't be executed they fail the
> tests which makes things look like they're not working when they are.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>   tools/testing/selftests/arm64/pauth/pac.c | 10 ++++++----
>   1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/testing/selftests/arm64/pauth/pac.c b/tools/testing/selftests/arm64/pauth/pac.c
> index 592fe538506e..b743daa772f5 100644
> --- a/tools/testing/selftests/arm64/pauth/pac.c
> +++ b/tools/testing/selftests/arm64/pauth/pac.c
> @@ -25,13 +25,15 @@
>   do { \
>   	unsigned long hwcaps = getauxval(AT_HWCAP); \
>   	/* data key instructions are not in NOP space. This prevents a SIGILL */ \
> -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \
> +	if (!(hwcaps & HWCAP_PACA))					\
> +		SKIP(return, "PAUTH not enabled"); \
>   } while (0)
>   #define ASSERT_GENERIC_PAUTH_ENABLED() \

May be ASSERT_GENERIC_PAUTH_ENABLED can be replaced with
something like VERIFY_GENERIC_PAUTH_ENABLED

or can be modified like below and instead of failing it skips with a
message

   -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \
   +	ASSERT_NE(0, hwcaps & HWCAP_PACA) SKIP(return, "PAUTH not 
enabled"); \					


>   do { \
>   	unsigned long hwcaps = getauxval(AT_HWCAP); \
>   	/* generic key instructions are not in NOP space. This prevents a SIGILL */ \
> -	ASSERT_NE(0, hwcaps & HWCAP_PACG) TH_LOG("Generic PAUTH not enabled"); \
> +	if (!(hwcaps & HWCAP_PACG)) \
> +		SKIP(return, "Generic PAUTH not enabled");	\
>   } while (0)
>   
>   void sign_specific(struct signatures *sign, size_t val)
> @@ -256,7 +258,7 @@ TEST(single_thread_different_keys)
>   	unsigned long hwcaps = getauxval(AT_HWCAP);
>   
>   	/* generic and data key instructions are not in NOP space. This prevents a SIGILL */
> -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled");
> +	ASSERT_PAUTH_ENABLED();
>   	if (!(hwcaps & HWCAP_PACG)) {
>   		TH_LOG("WARNING: Generic PAUTH not enabled. Skipping generic key checks");
>   		nkeys = NKEYS - 1;
> @@ -299,7 +301,7 @@ TEST(exec_changed_keys)
>   	unsigned long hwcaps = getauxval(AT_HWCAP);
>   
>   	/* generic and data key instructions are not in NOP space. This prevents a SIGILL */
> -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled");
> +	ASSERT_PAUTH_ENABLED();
>   	if (!(hwcaps & HWCAP_PACG)) {
>   		TH_LOG("WARNING: Generic PAUTH not enabled. Skipping generic key checks");
>   		nkeys = NKEYS - 1;
> 


From bigeasy at linutronix.de  Fri Aug 20 00:11:06 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Fri, 20 Aug 2021 09:11:06 +0200
Subject: [PATCH] rcutorture: Avoid problematic critical section nesting
 on RT
In-Reply-To: <561ab28b18c31fbc221f4cb0c4df6db9b0538675.camel@redhat.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
 <20210819153927.clqxr4f7qegpflbr@linutronix.de>
 <20210819154708.3efz6jtgwtuhpeds@linutronix.de>
 <20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-1>
 <561ab28b18c31fbc221f4cb0c4df6db9b0538675.camel@redhat.com>
Message-ID: <20210820071106.fba7l6ikgo7aa6xm@linutronix.de>

On 2021-08-19 23:11:12 [-0500], Scott Wood wrote:
> On Thu, 2021-08-19 at 11:20 -0700, Paul E. McKenney wrote:
> > On Thu, Aug 19, 2021 at 05:47:08PM +0200, Sebastian Andrzej Siewior wrote:
> > > On 2021-08-19 17:39:29 [+0200], To Paul E. McKenney wrote:
> > > > +	/*
> > > > +	 * Ideally these sequences would be detected in debug builds
> > > > +	 * (regardless of RT), but until then don't stop testing
> > > > +	 * them on non-RT.
> > > > +	 */
> > > > +	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> > > > +		/*
> > > > +		 * Can't release the outermost rcu lock in an irq disabled
> > > > +		 * section without preemption also being disabled, if irqs
> > > > +		 * had ever been enabled during this RCU critical section
> > > > +		 * (could leak a special flag and delay reporting the qs).
> > > > +		 */
> > > > +		if ((oldmask & RCUTORTURE_RDR_RCU) &&
> > > > +		    (mask & RCUTORTURE_RDR_IRQ) &&
> > > > +		    !(mask & preempts))
> > > > +			mask |= RCUTORTURE_RDR_RCU;
> > > 
> > > This piece above, I don't understand. I had it running for a while and
> > > it didn't explode. Let me try TREE01 for 30min without that piece.
> > 
> > This might be historical.  There was a time when interrupts being
> > disabled across rcu_read_unlock() meant that preemption had to have
> > been disabled across the entire RCU read-side critical section.
> > 
> > I am not seeing a purpose for it now, but I could easily be missing
> > something, especially given my tenuous grasp of RT.
> 
> Yeah, I think this was to deal with not having the irq work stuff in RT
> at the time.

Good. Thank you for the confirmation. 
I run (without the hunk above) 2x 6h of TREE01 and 4x 6h of TREE06 and
it looked good.

> -Scott

Sebastian


From rajan.vaja at xilinx.com  Fri Aug 20 00:38:33 2021
From: rajan.vaja at xilinx.com (Rajan Vaja)
Date: Fri, 20 Aug 2021 00:38:33 -0700
Subject: [PATCH] clk: zynqmp: fix kernel doc
Message-ID: <1629445113-32649-1-git-send-email-rajan.vaja@xilinx.com>

Add missing description of 'custom_type_flag' structure member.

Fixes: e605fa9c4a0c1218e5604b42bef59de0a3a4f813
       ("clk: zynqmp: Add support for custom type flags")

Signed-off-by: Rajan Vaja <rajan.vaja at xilinx.com>
---
 drivers/clk/zynqmp/clk-zynqmp.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h
index 84fa80a..a3cd2f8 100644
--- a/drivers/clk/zynqmp/clk-zynqmp.h
+++ b/drivers/clk/zynqmp/clk-zynqmp.h
@@ -56,6 +56,7 @@ enum topology_type {
  * @type:	Type of topology
  * @flag:	Topology flags
  * @type_flag:	Topology type specific flag
+ * @custom_type_flag: Topology type specific custome flag
  */
 struct clock_topology {
 	u32 type;
-- 
2.7.4



From bigeasy at linutronix.de  Fri Aug 20 00:42:36 2021
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Fri, 20 Aug 2021 09:42:36 +0200
Subject: [PATCH v2] rcutorture: Avoid problematic critical section nesting on
 PREEMPT_RT
In-Reply-To: <561ab28b18c31fbc221f4cb0c4df6db9b0538675.camel@redhat.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
 <20210819153927.clqxr4f7qegpflbr@linutronix.de>
 <20210819154708.3efz6jtgwtuhpeds@linutronix.de>
 <20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-1>
 <561ab28b18c31fbc221f4cb0c4df6db9b0538675.camel@redhat.com>
Message-ID: <20210820074236.2zli4nje7bof62rh@linutronix.de>

From: "From: Scott Wood" <swood at redhat.com>

rcutorture is generating some nesting scenarios that are not compatible on PREEMPT_RT.
For example:
	preempt_disable();
	rcu_read_lock_bh();
	preempt_enable();
	rcu_read_unlock_bh();

The problem here is that on PREEMPT_RT the bottom halves have to be
disabled and enabled in preemptible context.

Reorder locking: start with BH locking and continue with then with
disabling preemption or interrupts. In the unlocking do it reverse by
first enabling interrupts and preemption and BH at the very end.
Ensure that on PREEMPT_RT BH locking remains unchanged if in
non-preemptible context.

Link: https://lkml.kernel.org/r/20190911165729.11178-6-swood at redhat.com
Link: https://lkml.kernel.org/r/20210819182035.GF4126399 at paulmck-ThinkPad-P17-Gen-1
Signed-off-by: Scott Wood <swood at redhat.com>
[bigeasy: Drop ATOM_BH, make it only about changing BH in atomic
context. Allow enabling RCU in IRQ-off section. Reword commit message.]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
---
v1?v2:
  - Drop the ATOM_BH* bits. There don't seem to be needed, Paul did not
    ant the preempt-disable around enabling/disabling BH as it might fix
    things that RCU should take care.

  - Allow enabling RCU with disabled interrupts on RT. Scott confirmed
    that it was needed but might no longer be needed. Paul said that it
    might have been required at some point. It survived multiple 6h long
    TREE01 and TREE06 testing.

 kernel/rcu/rcutorture.c | 48 ++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
index 40ef5417d9545..d2ef535530b10 100644
--- a/kernel/rcu/rcutorture.c
+++ b/kernel/rcu/rcutorture.c
@@ -1432,28 +1432,34 @@ static void rcutorture_one_extend(int *readstate, int newstate,
 	/* First, put new protection in place to avoid critical-section gap. */
 	if (statesnew & RCUTORTURE_RDR_BH)
 		local_bh_disable();
+	if (statesnew & RCUTORTURE_RDR_RBH)
+		rcu_read_lock_bh();
 	if (statesnew & RCUTORTURE_RDR_IRQ)
 		local_irq_disable();
 	if (statesnew & RCUTORTURE_RDR_PREEMPT)
 		preempt_disable();
-	if (statesnew & RCUTORTURE_RDR_RBH)
-		rcu_read_lock_bh();
 	if (statesnew & RCUTORTURE_RDR_SCHED)
 		rcu_read_lock_sched();
 	if (statesnew & RCUTORTURE_RDR_RCU)
 		idxnew = cur_ops->readlock() << RCUTORTURE_RDR_SHIFT;
 
-	/* Next, remove old protection, irq first due to bh conflict. */
+	/*
+	 * Next, remove old protection, in decreasing order of strength
+	 * to avoid unlock paths that aren't safe in the stronger
+	 * context. Namely: BH can not be enabled with disabled interrupts.
+	 * Additionally PREEMPT_RT requires that BH is enabled in preemptible
+	 * context.
+	 */
 	if (statesold & RCUTORTURE_RDR_IRQ)
 		local_irq_enable();
-	if (statesold & RCUTORTURE_RDR_BH)
-		local_bh_enable();
 	if (statesold & RCUTORTURE_RDR_PREEMPT)
 		preempt_enable();
-	if (statesold & RCUTORTURE_RDR_RBH)
-		rcu_read_unlock_bh();
 	if (statesold & RCUTORTURE_RDR_SCHED)
 		rcu_read_unlock_sched();
+	if (statesold & RCUTORTURE_RDR_BH)
+		local_bh_enable();
+	if (statesold & RCUTORTURE_RDR_RBH)
+		rcu_read_unlock_bh();
 	if (statesold & RCUTORTURE_RDR_RCU) {
 		bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);
 
@@ -1496,6 +1502,9 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
 	int mask = rcutorture_extend_mask_max();
 	unsigned long randmask1 = torture_random(trsp) >> 8;
 	unsigned long randmask2 = randmask1 >> 3;
+	unsigned long preempts = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;
+	unsigned long preempts_irq = preempts | RCUTORTURE_RDR_IRQ;
+	unsigned long bhs = RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
 
 	WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT);
 	/* Mostly only one bit (need preemption!), sometimes lots of bits. */
@@ -1503,11 +1512,26 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
 		mask = mask & randmask2;
 	else
 		mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS));
-	/* Can't enable bh w/irq disabled. */
-	if ((mask & RCUTORTURE_RDR_IRQ) &&
-	    ((!(mask & RCUTORTURE_RDR_BH) && (oldmask & RCUTORTURE_RDR_BH)) ||
-	     (!(mask & RCUTORTURE_RDR_RBH) && (oldmask & RCUTORTURE_RDR_RBH))))
-		mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
+
+	/*
+	 * Can't enable bh w/irq disabled.
+	 */
+	if (mask & RCUTORTURE_RDR_IRQ)
+		mask |= oldmask & bhs;
+
+	/*
+	 * Ideally these sequences would be detected in debug builds
+	 * (regardless of RT), but until then don't stop testing
+	 * them on non-RT.
+	 */
+	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
+		/* Can't modify BH in atomic context */
+		if (oldmask & preempts_irq)
+			mask &= ~bhs;
+		if ((oldmask | mask) & preempts_irq)
+			mask |= oldmask & bhs;
+	}
+
 	return mask ?: RCUTORTURE_RDR_RCU;
 }
 
-- 
2.33.0



From yangyingliang at huawei.com  Fri Aug 20 00:49:49 2021
From: yangyingliang at huawei.com (Yang Yingliang)
Date: Fri, 20 Aug 2021 15:49:49 +0800
Subject: [PATCH -next] iommu/arm-smmu: Fix missing unlock on error in
 arm_smmu_device_group()
Message-ID: <20210820074949.1946576-1-yangyingliang@huawei.com>

Add the missing unlock before return from function arm_smmu_device_group()
in the error handling case.

Fixes: b1a1347912a7 ("iommu/arm-smmu: Fix race condition during iommu_group creation")
Reported-by: Hulk Robot <hulkci at huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang at huawei.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 73893180ec7e..4bc75c4ce402 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1478,8 +1478,10 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
 	mutex_lock(&smmu->stream_map_mutex);
 	for_each_cfg_sme(cfg, fwspec, i, idx) {
 		if (group && smmu->s2crs[idx].group &&
-		    group != smmu->s2crs[idx].group)
+		    group != smmu->s2crs[idx].group) {
+			mutex_unlock(&smmu->stream_map_mutex);
 			return ERR_PTR(-EINVAL);
+		}
 
 		group = smmu->s2crs[idx].group;
 	}
-- 
2.25.1



From lkp at intel.com  Fri Aug 20 00:47:28 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 20 Aug 2021 15:47:28 +0800
Subject: [soc:arm/dt] BUILD SUCCESS
 c4d3928250de919a1d324f6c8a7f26f51af40fd2
Message-ID: <611f5e10.lnFWwX/n97pqYSir%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/dt
branch HEAD: c4d3928250de919a1d324f6c8a7f26f51af40fd2  Merge tag 'mvebu-dt64-5.15-1' of git://git.kernel.org/pub/scm/linux/kernel/git/gclement/mvebu into arm/dt

elapsed time: 2501m

configs tested: 100
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210816
i386                 randconfig-c001-20210818
powerpc                      ep88xc_defconfig
arm                         at91_dt_defconfig
powerpc                 mpc832x_rdb_defconfig
mips                     loongson1c_defconfig
arm                        mvebu_v5_defconfig
alpha                            alldefconfig
sh                     sh7710voipgw_defconfig
arm                  colibri_pxa300_defconfig
sh                   sh7724_generic_defconfig
sparc                            alldefconfig
arm                       imx_v4_v5_defconfig
mips                           ip27_defconfig
mips                      pic32mzda_defconfig
sh                        apsh4ad0a_defconfig
xtensa                          iss_defconfig
sh                           se7780_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
i386                 randconfig-a004-20210817
i386                 randconfig-a003-20210817
i386                 randconfig-a001-20210817
i386                 randconfig-a002-20210817
i386                 randconfig-a006-20210817
i386                 randconfig-a005-20210817
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From sean.wang at mediatek.com  Fri Aug 20 00:50:40 2021
From: sean.wang at mediatek.com (sean.wang at mediatek.com)
Date: Fri, 20 Aug 2021 15:50:40 +0800
Subject: [v2,06/12] pinctrl: mediatek: add support for MT7986 SoC
In-Reply-To: <20210817074557.30953-5-sam.shih@mediatek.com--annotate>
References: <20210817074557.30953-5-sam.shih@mediatek.com--annotate>
Message-ID: <1629445840-25510-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang at mediatek.com>

>This commit includes pinctrl driver for Mediatek MT7986
>
>The difference of pinctrl between mt7986a and mt7986b
>is that pin-41 to pin-65 do not exist on mt7986b
>
>Signed-off-by: Sam Shih <sam.shih at mediatek.com>
>
>---
>v2: applied the comment suggested by reviewers:
>    - for the pins not ballout, we can fill .name in struct mtk_pin_desc
>      as NULL and return -ENOTSUPP in gpio/pinconf ops.
>
>---
> drivers/pinctrl/mediatek/Kconfig          |    7 +
> drivers/pinctrl/mediatek/Makefile         |    1 +
> drivers/pinctrl/mediatek/pinctrl-mt7986.c | 1217 +++++++++++++++++++++
> 3 files changed, 1225 insertions(+)
> create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c
>
>diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
>index 7040a7a7bd5d..66db4ac5d169 100644
>--- a/drivers/pinctrl/mediatek/Kconfig
>+++ b/drivers/pinctrl/mediatek/Kconfig
>@@ -119,6 +119,13 @@ config PINCTRL_MT7622
>	default ARM64 && ARCH_MEDIATEK
>	select PINCTRL_MTK_MOORE
>
>+config PINCTRL_MT7986
>+	bool "Mediatek MT7986 pin control"
>+	depends on OF
>+	depends on ARM64 || COMPILE_TEST
>+	default ARM64 && ARCH_MEDIATEK
>+	select PINCTRL_MTK_MOORE
>+
> config PINCTRL_MT8167
>	bool "Mediatek MT8167 pin control"
>	depends on OF
>diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
>index 1bb7f9c65bc2..1e3931d924e7 100644
>--- a/drivers/pinctrl/mediatek/Makefile
>+++ b/drivers/pinctrl/mediatek/Makefile
>@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_MT6797)	+= pinctrl-mt6797.o
> obj-$(CONFIG_PINCTRL_MT7622)	+= pinctrl-mt7622.o
> obj-$(CONFIG_PINCTRL_MT7623)	+= pinctrl-mt7623.o
> obj-$(CONFIG_PINCTRL_MT7629)	+= pinctrl-mt7629.o
>+obj-$(CONFIG_PINCTRL_MT7986)	+= pinctrl-mt7986.o
> obj-$(CONFIG_PINCTRL_MT8167)	+= pinctrl-mt8167.o
> obj-$(CONFIG_PINCTRL_MT8173)	+= pinctrl-mt8173.o
> obj-$(CONFIG_PINCTRL_MT8183)	+= pinctrl-mt8183.o
>diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
>new file mode 100644
>index 000000000000..808ae4e03eb2
>--- /dev/null
>+++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
>@@ -0,0 +1,1217 @@
>+// SPDX-License-Identifier: GPL-2.0
>+/*
>+ * The MT7986 driver based on Linux generic pinctrl binding.
>+ *
>+ * Copyright (C) 2021 MediaTek Inc.
>+ * Author: Sam Shih <sam.shih at mediatek.com>
>+ */
>+
>+#include "pinctrl-moore.h"
>+
>+#define MT7986_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
>+#define MT7986_NOT_BALLOUT_PIN(_number) { .number = _number }

I preferred explict set .name to NULL to indicate the pin is not ball out.

>+
>+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,	\
>+			   _x_bits)														\
>+	PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,		\
>+			   _x_bits, 32, 0)
>+
>+/**
>+ * enum - Locking variants of the iocfg bases
>+ *
>+ * MT7986 have multiple bases to program pin configuration listed as the below:
>+ * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000,
>+ * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000,
>+ * _i_based could be used to indicate what base the pin should be mapped into.
>+ *
>+ * Each iocfg register base control different group of pads on the SoC
>+ *
>+ *
>+ *  chip carrier
>+ *
>+ *      A  B  C  D  E  F  G  H
>+ *    +------------------------+
>+ *  8 | o  o  o  o  o  o  o  o |
>+ *  7 | o  o  o  o  o  o  o  o |
>+ *  6 | o  o  o  o  o  o  o  o |
>+ *  5 | o  o  o  o  o  o  o  o |
>+ *  4 | o  o  o  o  o  o  o  o |
>+ *  3 | o  o  o  o  o  o  o  o |
>+ *  2 | o  o  o  o  o  o  o  o |
>+ *  1 | o  o  o  o  o  o  o  o |
>+ *    +------------------------+
>+ *
>+ *  inside Chip carrier
>+ *
>+ *      A  B  C  D  E  F  G  H
>+ *    +------------------------+
>+ *  8 |                        |
>+ *  7 |        TL  TR          |
>+ *  6 |      +---------+       |
>+ *  5 |   LT |         | RT    |
>+ *  4 |      |         |       |
>+ *  3 |   LB |         | RB    |
>+ *  2 |      +---------+       |
>+ *  1 |                        |
>+ *    +------------------------+
>+ *
>+ */
>+
>+enum {
>+	GPIO_BASE,
>+	IOCFG_RT_BASE,
>+	IOCFG_RB_BASE,
>+	IOCFG_LT_BASE,
>+	IOCFG_LB_BASE,
>+	IOCFG_TR_BASE,
>+	IOCFG_TL_BASE,
>+};
>+
>+static const char *const mt7986_pinctrl_register_base_names[] = {
>+	"gpio_base", "iocfg_rt_base", "iocfg_rb_base", "iocfg_lt_base",
>+	"iocfg_lb_base", "iocfg_tr_base", "iocfg_tl_base",
>+};
>+
>+static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = {
>+	PIN_FIELD(0, 40, 0x300, 0x10, 0, 4),
>+	PIN_FIELD(41, 65, 0x350, 0x10, 4, 4),
>+	PIN_FIELD(66, 68, 0x380, 0x10, 8, 4),
>+	PIN_FIELD(69, 100, 0x380, 0x10, 20, 4),
>+};
>+
>+static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = {
>+	PIN_FIELD(0, 40, 0x0, 0x10, 0, 1),
>+	PIN_FIELD(41, 65, 0x10, 0x10, 9, 1),
>+	PIN_FIELD(66, 68, 0x20, 0x10, 2, 1),
>+	PIN_FIELD(69, 100, 0x20, 0x10, 5, 1),
>+};
>+
>+static const struct mtk_pin_field_calc mt7986_pin_di_range[] = {
>+	PIN_FIELD(0, 40, 0x200, 0x10, 0, 1),
>+	PIN_FIELD(41, 65, 0x210, 0x10, 9, 1),
>+	PIN_FIELD(66, 68, 0x220, 0x10, 2, 1),
>+	PIN_FIELD(69, 100, 0x220, 0x10, 5, 1),
>+};
>+
>+static const struct mtk_pin_field_calc mt7986_pin_do_range[] = {
>+	PIN_FIELD(0, 40, 0x100, 0x10, 0, 1),
>+	PIN_FIELD(41, 65, 0x110, 0x10, 9, 1),
>+	PIN_FIELD(66, 68, 0x120, 0x10, 2, 1),
>+	PIN_FIELD(69, 100, 0x120, 0x10, 5, 1),
>+};
>+
>+static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = {
>+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1),
>+	PIN_FIELD_BASE(1, 1, IOCFG_LT_BASE, 0x20, 0x10, 10, 1),
>+	PIN_FIELD_BASE(2, 2, IOCFG_LT_BASE, 0x20, 0x10, 11, 1),
>+	PIN_FIELD_BASE(3, 3, IOCFG_LB_BASE, 0x20, 0x10, 0, 1),
>+	PIN_FIELD_BASE(4, 4, IOCFG_LB_BASE, 0x20, 0x10, 1, 1),
>+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x40, 0x10, 0, 1),
>+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x40, 0x10, 1, 1),
>+	PIN_FIELD_BASE(7, 7, IOCFG_LT_BASE, 0x20, 0x10, 0, 1),
>+	PIN_FIELD_BASE(8, 8, IOCFG_LT_BASE, 0x20, 0x10, 1, 1),
>+	PIN_FIELD_BASE(9, 9, IOCFG_LT_BASE, 0x20, 0x10, 2, 1),
>+	PIN_FIELD_BASE(10, 10, IOCFG_LT_BASE, 0x20, 0x10, 3, 1),
>+	PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x40, 0x10, 8, 1),
>+	PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x40, 0x10, 9, 1),
>+	PIN_FIELD_BASE(13, 13, IOCFG_RB_BASE, 0x40, 0x10, 10, 1),
>+	PIN_FIELD_BASE(14, 14, IOCFG_RB_BASE, 0x40, 0x10, 11, 1),
>+	PIN_FIELD_BASE(15, 15, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
>+	PIN_FIELD_BASE(16, 16, IOCFG_RB_BASE, 0x40, 0x10, 3, 1),
>+	PIN_FIELD_BASE(17, 17, IOCFG_RB_BASE, 0x40, 0x10, 4, 1),
>+	PIN_FIELD_BASE(18, 18, IOCFG_RB_BASE, 0x40, 0x10, 5, 1),
>+	PIN_FIELD_BASE(19, 19, IOCFG_RB_BASE, 0x40, 0x10, 6, 1),
>+	PIN_FIELD_BASE(20, 20, IOCFG_RB_BASE, 0x40, 0x10, 7, 1),

Actually, we can merge the consecutive entries into one to reduce the table size
For example, we can merge those entries pin 15 ~ 20 into one, from

PIN_FIELD_BASE(15, 15, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
PIN_FIELD_BASE(16, 16, IOCFG_RB_BASE, 0x40, 0x10, 3, 1),
PIN_FIELD_BASE(17, 17, IOCFG_RB_BASE, 0x40, 0x10, 4, 1),
PIN_FIELD_BASE(18, 18, IOCFG_RB_BASE, 0x40, 0x10, 5, 1),
PIN_FIELD_BASE(19, 19, IOCFG_RB_BASE, 0x40, 0x10, 6, 1),
PIN_FIELD_BASE(20, 20, IOCFG_RB_BASE, 0x40, 0x10, 7, 1),

to

PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x40, 0x10, 2, 1).

Also please consider merging all the similar occurrences elsewhere to optimize them.

>+	PIN_FIELD_BASE(21, 21, IOCFG_RT_BASE, 0x30, 0x10, 12, 1),
>+	PIN_FIELD_BASE(22, 22, IOCFG_RT_BASE, 0x30, 0x10, 13, 1),
>+	PIN_FIELD_BASE(23, 23, IOCFG_RT_BASE, 0x30, 0x10, 14, 1),
>+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1),
>+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1),
>+	PIN_FIELD_BASE(26, 26, IOCFG_RT_BASE, 0x30, 0x10, 15, 1),
>+	PIN_FIELD_BASE(27, 27, IOCFG_RT_BASE, 0x30, 0x10, 16, 1),

<snip>

From maz at kernel.org  Fri Aug 20 00:58:22 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 08:58:22 +0100
Subject: [PATCH v2] KVM: arm64: vgic: Resample HW pending state on
 deactivation
In-Reply-To: <20210819180305.1670525-1-maz@kernel.org>
References: <20210819180305.1670525-1-maz@kernel.org>
Message-ID: <162944629227.1671663.6947098620852443792.b4-ty@kernel.org>

On Thu, 19 Aug 2021 19:03:05 +0100, Marc Zyngier wrote:
> When a mapped level interrupt (a timer, for example) is deactivated
> by the guest, the corresponding host interrupt is equally deactivated.
> However, the fate of the pending state still needs to be dealt
> with in SW.
> 
> This is specially true when the interrupt was in the active+pending
> state in the virtual distributor at the point where the guest
> was entered. On exit, the pending state is potentially stale
> (the guest may have put the interrupt in a non-pending state).
> 
> [...]

Applied to next, thanks!

[1/1] KVM: arm64: vgic: Resample HW pending state on deactivation
      commit: 3134cc8beb69d0db9de651081707c4651c011621

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From rajan.vaja at xilinx.com  Fri Aug 20 00:58:14 2021
From: rajan.vaja at xilinx.com (Rajan Vaja)
Date: Fri, 20 Aug 2021 00:58:14 -0700
Subject: [PATCH v2] clk: zynqmp: fix kernel doc
In-Reply-To: <1629445113-32649-1-git-send-email-rajan.vaja@xilinx.com>
References: <1629445113-32649-1-git-send-email-rajan.vaja@xilinx.com>
Message-ID: <1629446294-1056-1-git-send-email-rajan.vaja@xilinx.com>

Add missing description of 'custom_type_flag' structure member.

Fixes: e605fa9c4a0c ("clk: zynqmp: Add support for custom type flags")

Signed-off-by: Rajan Vaja <rajan.vaja at xilinx.com>
---
Changes in v2:
 - Updated Fixes tag.
---
 drivers/clk/zynqmp/clk-zynqmp.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h
index 84fa80a..a3cd2f8 100644
--- a/drivers/clk/zynqmp/clk-zynqmp.h
+++ b/drivers/clk/zynqmp/clk-zynqmp.h
@@ -56,6 +56,7 @@ enum topology_type {
  * @type:	Type of topology
  * @flag:	Topology flags
  * @type_flag:	Topology type specific flag
+ * @custom_type_flag: Topology type specific custome flag
  */
 struct clock_topology {
 	u32 type;
-- 
2.7.4



From yunfei.dong at mediatek.com  Fri Aug 20 00:59:38 2021
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Fri, 20 Aug 2021 15:59:38 +0800
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <CAAEAJfCTrKj9AFExN-L-TKww4E=us1VVh8LHtZ8Q0j_eaCD4Eg@mail.gmail.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
 <1b79a67b703d2c894bc4d9458c760e082fc42958.camel@mediatek.com>
 <CAAEAJfCTrKj9AFExN-L-TKww4E=us1VVh8LHtZ8Q0j_eaCD4Eg@mail.gmail.com>
Message-ID: <1629446378.18871.27.camel@mhfsdcap03>

Hi Ezequiel,

Thanks for your detail feedback. 

On Thu, 2021-08-19 at 11:10 -0300, Ezequiel Garcia wrote:
> On Thu, 19 Aug 2021 at 04:13, yunfei.dong at mediatek.com
> <yunfei.dong at mediatek.com> wrote:
> >
> > Hi Ezequiel,
> >
> > Thanks for your suggestion.
> >
> > On Wed, 2021-08-18 at 11:11 -0300, Ezequiel Garcia wrote:
> > > +danvet
> > >
> > > Hi,
> > >
> > > On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <yunfei.dong at mediatek.com>
> > > wrote:
> > > >
> > > > This series adds support for multi hardware decode into mtk-vcodec,
> > > > by first
> > > > adding component framework to manage each hardware information:
> > > > interrupt,
> > > > clock, register bases and power. Secondly add core thread to deal
> > > > with core
> > > > hardware message, at the same time, add msg queue for different
> > > > hardware
> > > > share messages. Lastly, the architecture of different specs are not
> > > > the same,
> > > > using specs type to separate them.
> > > >
> > >
> > > I don't think it's a good idea to introduce the component API in the
> > > media subsystem. It doesn't seem to be maintained, IRC there's not
> > > even
> > > a maintainer for it, and it has some issues that were never
> > > addressed.
> > >
> > > It would be really important to avoid it. Is it really needed in the
> > > first place?
> > >
> > > Thanks,
> > > Ezequiel
> >
> > For there are many hardware need to use, mt8192 is three and mt8195 is
> > five. Maybe need more to be used in the feature.
> >
> > Each hardware has independent clk/power/iommu port/irq.
> > Use component interface in prob to get each component's information.
> > Just enable the hardware when need to use it, very convenient and
> > simple.
> >
> > I found that there are many modules use component to manage hardware
> > information, such as iommu and drm etc.
> >
> 
> Many drivers support multiple hardware variants, where each variant
> has a different number of clocks or interrupts, see for instance
> struct hantro_variant which allows to expose different codec cores,
> some having both decoder/encoder, and some having just a decoder.
> 
> The component API is mostly used by DRM to aggregate independent
> subdevices (called components) into an aggregated driver.
> 
> For instance, a DRM driver needs to glue together the HDMI, MIPI,
> and plany controller, or any other hardware arrangement where
> devices can be described independently.
> 
The usage scenario is very similar with drm and iommu, So decide to use
component framework.
Decode has three/five or more hardwares, these hardware are independent.
For mt8183 just need core hardware to decode, but mt8192 has lat,soc and
core hardware to decode. When lat need to use, just enable lat hardware,
core is the same.And mt8195 will has two cores, each core can work well
independent.

For each component device just used to open their power/clk/iommu
port/irq when master need to enable it. The main logic is in master
device.

> The component API may look simple but has some issues, it's not easy
> to debug, and can cause troubles if not used as expected [1].
> It's worth making sure you actually need a framework
> to glue different devices together.
> 
Each hardware has its index, master can get hardware information
according these index, looks not complex. What do you mean about not
easy to debug?

> > Do you have any other suggestion for this architecture?
> >
> 
> Looking at the different patchsets that are posted, it's not clear
> to me what exactly are the different architectures that you intend
> to support, can you some documentation which clarifies that?
> 
Have five hardwares lat,soc,core0,core1 and main. Lat thread can use lat
soc and main, core thread can use soc,lat, core0 and core1. Core thread
can be used or not for different project. Also Need to use these
hardware dynamic at the same time. So I use component framework, just
need to know the used  hardware index according to different
project.Need not to do complex logic to manage these hardwares.


> Thanks,
> Ezequiel
> 
> [1] https://patchwork.kernel.org/project/linux-rockchip/cover/20200120170602.3832-1-ezequiel at collabora.com/


Thanks,
Yunfei Dong





From maz at kernel.org  Fri Aug 20 01:01:41 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 09:01:41 +0100
Subject: [PATCH 3/4] KVM: arm64: Convert the host S2 over to
 __load_guest_stage2()
In-Reply-To: <YQ07sPoa4ACizYrp@google.com>
References: <20210806113109.2475-1-will@kernel.org>
 <20210806113109.2475-5-will@kernel.org>
 <YQ07sPoa4ACizYrp@google.com>
Message-ID: <87tujkr1cq.wl-maz@kernel.org>

On Fri, 06 Aug 2021 14:40:00 +0100,
Quentin Perret <qperret at google.com> wrote:
> 
> On Friday 06 Aug 2021 at 12:31:07 (+0100), Will Deacon wrote:
> > From: Marc Zyngier <maz at kernel.org>
> > 
> > The protected mode relies on a separate helper to load the
> > S2 context. Move over to the __load_guest_stage2() helper
> > instead.
> > 
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: Jade Alglave <jade.alglave at arm.com>
> > Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > Signed-off-by: Will Deacon <will at kernel.org>
> > ---
> >  arch/arm64/include/asm/kvm_mmu.h              | 11 +++--------
> >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 +-
> >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         |  2 +-
> >  3 files changed, 5 insertions(+), 10 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> > index 05e089653a1a..934ef0deff9f 100644
> > --- a/arch/arm64/include/asm/kvm_mmu.h
> > +++ b/arch/arm64/include/asm/kvm_mmu.h
> > @@ -267,9 +267,10 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
> >   * Must be called from hyp code running at EL2 with an updated VTTBR
> >   * and interrupts disabled.
> >   */
> > -static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long vtcr)
> > +static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
> > +						struct kvm_arch *arch)
> >  {
> > -	write_sysreg(vtcr, vtcr_el2);
> > +	write_sysreg(arch->vtcr, vtcr_el2);
> >  	write_sysreg(kvm_get_vttbr(mmu), vttbr_el2);
> >  
> >  	/*
> > @@ -280,12 +281,6 @@ static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long
> >  	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
> >  }
> >  
> > -static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
> > -						struct kvm_arch *arch)
> > -{
> > -	__load_stage2(mmu, arch->vtcr);
> > -}
> > -
> >  static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu)
> >  {
> >  	return container_of(mmu->arch, struct kvm, arch);
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > index 9c227d87c36d..a910648bc71b 100644
> > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > @@ -29,7 +29,7 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
> >  static __always_inline void __load_host_stage2(void)
> >  {
> >  	if (static_branch_likely(&kvm_protected_mode_initialized))
> > -		__load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr);
> > +		__load_guest_stage2(&host_kvm.arch.mmu, &host_kvm.arch);
> >  	else
> >  		write_sysreg(0, vttbr_el2);
> >  }
> > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > index d938ce95d3bd..d4e74ca7f876 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > @@ -126,7 +126,7 @@ int __pkvm_prot_finalize(void)
> >  	kvm_flush_dcache_to_poc(params, sizeof(*params));
> >  
> >  	write_sysreg(params->hcr_el2, hcr_el2);
> > -	__load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr);
> > +	__load_guest_stage2(&host_kvm.arch.mmu, &host_kvm.arch);
> 
> Nit: clearly we're not loading a guest stage-2 here, so maybe the
> function should take a more generic name?

How about we rename __load_guest_stage2() to __load_stage2() instead,
with the same parameters?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:14:57 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:14:57 +0200
Subject: [PATCH 1/2] arm64: dts: exynos: align operating-points table name
 with dtschema in Exynos5433
Message-ID: <20210820081458.83406-1-krzysztof.kozlowski@canonical.com>

Align the name of operating-points node to dtschema to fix warnings like:

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi | 10 +++++-----
 arch/arm64/boot/dts/exynos/exynos5433.dtsi     |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
index 8997f8f2b96c..72ccf18eb9d1 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
@@ -87,7 +87,7 @@ bus_noc2: bus9 {
 		status = "disabled";
 	};
 
-	bus_g2d_400_opp_table: opp-table2 {
+	bus_g2d_400_opp_table: opp-table-2 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -117,7 +117,7 @@ opp-100000000 {
 		};
 	};
 
-	bus_g2d_266_opp_table: opp-table3 {
+	bus_g2d_266_opp_table: opp-table-3 {
 		compatible = "operating-points-v2";
 
 		opp-267000000 {
@@ -137,7 +137,7 @@ opp-100000000 {
 		};
 	};
 
-	bus_gscl_opp_table: opp-table4 {
+	bus_gscl_opp_table: opp-table-4 {
 		compatible = "operating-points-v2";
 
 		opp-333000000 {
@@ -151,7 +151,7 @@ opp-166500000 {
 		};
 	};
 
-	bus_hevc_opp_table: opp-table5 {
+	bus_hevc_opp_table: opp-table-5 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -175,7 +175,7 @@ opp-100000000 {
 		};
 	};
 
-	bus_noc2_opp_table: opp-table6 {
+	bus_noc2_opp_table: opp-table-6 {
 		compatible = "operating-points-v2";
 
 		opp-400000000 {
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index 6a6f7dd1d65c..ebd5091d68b4 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -239,7 +239,7 @@ cluster_a53_l2: l2-cache1 {
 		};
 	};
 
-	cluster_a53_opp_table: opp-table0 {
+	cluster_a53_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -285,7 +285,7 @@ opp-1300000000 {
 		};
 	};
 
-	cluster_a57_opp_table: opp-table1 {
+	cluster_a57_opp_table: opp-table-1 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:15:22 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:15:22 +0200
Subject: [PATCH] arm64: dts: hisilicon: align operating-points table name with
 dtschema
Message-ID: <20210820081522.83512-1-krzysztof.kozlowski@canonical.com>

Align the name of operating-points node to dtschema to fix warnings like:

  cpu_opp_table: $nodename:0: 'cpu_opp_table' does not match '^opp-table(-[a-z0-9]+)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 4 ++--
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index 2d5c1a348716..19a979779bdb 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -210,7 +210,7 @@ A73_L2: l2-cache1 {
 		};
 	};
 
-	cluster0_opp: opp_table0 {
+	cluster0_opp: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -245,7 +245,7 @@ opp04 {
 		};
 	};
 
-	cluster1_opp: opp_table1 {
+	cluster1_opp: opp-table-1 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index dde9371dc545..3f2134779115 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -193,7 +193,7 @@ CLUSTER1_L2: l2-cache1 {
 		};
 	};
 
-	cpu_opp_table: cpu_opp_table {
+	cpu_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:15:57 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:15:57 +0200
Subject: [PATCH] arm64: dts: freescale: imx8mq-librem5: align operating-points
 table name with dtschema
Message-ID: <20210820081557.83603-1-krzysztof.kozlowski@canonical.com>

Align the name of operating-points node to dtschema to fix warnings like:

  ddrc-opp-table: $nodename:0: 'ddrc-opp-table' does not match '^opp-table(-[a-z0-9]+)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
index 460ef0d86540..3f7524400a63 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
@@ -225,7 +225,7 @@ &A53_3 {
 &ddrc {
 	operating-points-v2 = <&ddrc_opp_table>;
 
-	ddrc_opp_table: ddrc-opp-table {
+	ddrc_opp_table: opp-table {
 		compatible = "operating-points-v2";
 
 		opp-25M {
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:16:15 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:16:15 +0200
Subject: [PATCH 1/2] arm64: dts: mediatek: align operating-points table name
 with dtschema
Message-ID: <20210820081616.83674-1-krzysztof.kozlowski@canonical.com>

Align the name of operating-points node to dtschema to fix warnings like:

  arch/arm64/boot/dts/mediatek/mt8173-elm.dt.yaml:
    opp_table0: $nodename:0: 'opp_table0' does not match '^opp-table(-[a-z0-9]+)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 4 ++--
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d9e005ae5bb0..49c6b6a5b489 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -57,7 +57,7 @@ aliases {
 		serial3 = &uart3;
 	};
 
-	cluster0_opp: opp_table0 {
+	cluster0_opp: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 		opp-507000000 {
@@ -94,7 +94,7 @@ opp-1703000000 {
 		};
 	};
 
-	cluster1_opp: opp_table1 {
+	cluster1_opp: opp-table-1 {
 		compatible = "operating-points-v2";
 		opp-shared;
 		opp-507000000 {
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 409cf827970c..caab109add28 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -197,7 +197,7 @@ CLUSTER_SLEEP1: cluster-sleep-1 {
 		};
 	};
 
-	gpu_opp_table: opp_table0 {
+	gpu_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:16:16 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:16:16 +0200
Subject: [PATCH 2/2] arm64: dts: mediatek: align thermal zone node names with
 dtschema
In-Reply-To: <20210820081616.83674-1-krzysztof.kozlowski@canonical.com>
References: <20210820081616.83674-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210820081616.83674-2-krzysztof.kozlowski@canonical.com>

Align the name of thermal zone node to dtschema to fix warnings like:

  arch/arm64/boot/dts/mediatek/mt8173-elm.dt.yaml:
    thermal-zones: 'cpu_thermal' does not match any of the regexes: '^[a-zA-Z][a-zA-Z0-9\\-]{1,12}-thermal$', 'pinctrl-[0-9]+'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 4 ++--
 arch/arm64/boot/dts/mediatek/mt8173.dtsi  | 2 +-
 arch/arm64/boot/dts/mediatek/mt8183.dtsi  | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index a9cca9c146fd..640d4fdaa611 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -19,7 +19,7 @@ / {
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	cluster0_opp: opp_table0 {
+	cluster0_opp: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 		opp00 {
@@ -36,7 +36,7 @@ opp02 {
 		};
 	};
 
-	cluster1_opp: opp_table1 {
+	cluster1_opp: opp-table-1 {
 		compatible = "operating-points-v2";
 		opp-shared;
 		opp00 {
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 49c6b6a5b489..066025d80ca4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -273,7 +273,7 @@ cpum_ck: oscillator2 {
 	};
 
 	thermal-zones {
-		cpu_thermal: cpu_thermal {
+		cpu_thermal: cpu-thermal {
 			polling-delay-passive = <1000>; /* milliseconds */
 			polling-delay = <1000>; /* milliseconds */
 
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index caab109add28..d836769b87bb 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -759,7 +759,7 @@ thermal: thermal at 1100b000 {
 		};
 
 		thermal_zones: thermal-zones {
-			cpu_thermal: cpu_thermal {
+			cpu_thermal: cpu-thermal {
 				polling-delay-passive = <100>;
 				polling-delay = <500>;
 				thermal-sensors = <&thermal 0>;
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:16:44 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:16:44 +0200
Subject: [PATCH 1/2] arm64: dts: allwinner: h5: align operating-points table
 name with dtschema
Message-ID: <20210820081645.83796-1-krzysztof.kozlowski@canonical.com>

Align the name of operating-points node to dtschema to fix warnings like:

  arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dt.yaml:
    cpu-opp-table: $nodename:0: 'cpu-opp-table' does not match '^opp-table(-[a-z0-9]+)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
index b2657201957e..0b6914a165b0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
@@ -2,7 +2,7 @@
 // Copyright (C) 2020 Chen-Yu Tsai <wens at csie.org>
 
 / {
-	cpu_opp_table: cpu-opp-table {
+	cpu_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:17:10 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:17:10 +0200
Subject: [PATCH 2/2] arm64: dts: allwinner: align thermal zone node names with
 dtschema
In-Reply-To: <20210820081645.83796-1-krzysztof.kozlowski@canonical.com>
References: <20210820081645.83796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210820081710.83908-1-krzysztof.kozlowski@canonical.com>

Align the name of thermal zone node to dtschema to fix warnings like:

  arch/arm64/boot/dts/allwinner/sun50i-a100-allwinner-perf1.dt.yaml:
    thermal-zones: 'cpu-thermal-zone', 'ddr-thermal-zone', 'gpu-thermal-zone' do not match any of the regexes: '^[a-zA-Z][a-zA-Z0-9\\-]{1,12}-thermal$', 'pinctrl-[0-9]+'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 6 +++---
 arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi   | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
index cc321c04f121..f6d7d7f7fdab 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi
@@ -343,19 +343,19 @@ r_i2c1: i2c at 7081800 {
 	};
 
 	thermal-zones {
-		cpu-thermal-zone {
+		cpu-thermal {
 			polling-delay-passive = <0>;
 			polling-delay = <0>;
 			thermal-sensors = <&ths 0>;
 		};
 
-		ddr-thermal-zone {
+		ddr-thermal {
 			polling-delay-passive = <0>;
 			polling-delay = <0>;
 			thermal-sensors = <&ths 2>;
 		};
 
-		gpu-thermal-zone {
+		gpu-thermal {
 			polling-delay-passive = <0>;
 			polling-delay = <0>;
 			thermal-sensors = <&ths 1>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
index 578a63dedf46..9988e87ea7b3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
@@ -217,7 +217,7 @@ cpu-hot-limit {
 			};
 		};
 
-		gpu_thermal {
+		gpu-thermal {
 			polling-delay-passive = <0>;
 			polling-delay = <0>;
 			thermal-sensors = <&ths 1>;
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:17:31 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:17:31 +0200
Subject: [PATCH 1/3] arm64: dts: arm: align watchdog and mmc node names with
 dtschema
Message-ID: <20210820081733.83976-1-krzysztof.kozlowski@canonical.com>

Align the watchdog and mmc device node names with the schema to fix
warnings like:

  mmci at 50000: $nodename:0: 'mmci at 50000' does not match '^mmc(@.*)?$'
  wdt at f0000: $nodename:0: 'wdt at f0000' does not match '^watchdog(@.*|-[0-9a-f])?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/arm/juno-motherboard.dtsi    | 4 ++--
 arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
index 40d95c58b55e..f45c912b2806 100644
--- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
@@ -218,7 +218,7 @@ led7 {
 					};
 				};
 
-				mmci at 50000 {
+				mmc at 50000 {
 					compatible = "arm,pl180", "arm,primecell";
 					reg = <0x050000 0x1000>;
 					interrupts = <5>;
@@ -246,7 +246,7 @@ kmi at 70000 {
 					clock-names = "KMIREFCLK", "apb_pclk";
 				};
 
-				wdt at f0000 {
+				watchdog at f0000 {
 					compatible = "arm,sp805", "arm,primecell";
 					reg = <0x0f0000 0x10000>;
 					interrupts = <7>;
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
index 4c4a381d2c75..7260bcf4b2ab 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
@@ -130,7 +130,7 @@ aaci at 40000 {
 					clock-names = "apb_pclk";
 				};
 
-				mmci at 50000 {
+				mmc at 50000 {
 					compatible = "arm,pl180", "arm,primecell";
 					reg = <0x050000 0x1000>;
 					interrupts = <9>, <10>;
@@ -190,7 +190,7 @@ v2m_serial3: serial at c0000 {
 					clock-names = "uartclk", "apb_pclk";
 				};
 
-				wdt at f0000 {
+				watchdog at f0000 {
 					compatible = "arm,sp805", "arm,primecell";
 					reg = <0x0f0000 0x1000>;
 					interrupts = <0>;
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:17:32 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:17:32 +0200
Subject: [PATCH 2/3] ARM: dts: arm: align watchdog and mmc node names with
 dtschema
In-Reply-To: <20210820081733.83976-1-krzysztof.kozlowski@canonical.com>
References: <20210820081733.83976-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210820081733.83976-2-krzysztof.kozlowski@canonical.com>

Align the watchdog and mmc device node names with the schema to fix
warnings like:

  mmci at 50000: $nodename:0: 'mmci at 50000' does not match '^mmc(@.*)?$'
  wdt at f0000: $nodename:0: 'wdt at f0000' does not match '^watchdog(@.*|-[0-9a-f])?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index 2ad9fd7c94ec..bcb3f581977a 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -215,7 +215,7 @@ aaci at 40000 {
 					clock-names = "apb_pclk";
 				};
 
-				mmci at 50000 {
+				mmc at 50000 {
 					compatible = "arm,pl180", "arm,primecell";
 					reg = <0x050000 0x1000>;
 					interrupts = <9>, <10>;
@@ -275,7 +275,7 @@ v2m_serial3: serial at c0000 {
 					clock-names = "uartclk", "apb_pclk";
 				};
 
-				wdt at f0000 {
+				watchdog at f0000 {
 					compatible = "arm,sp805", "arm,primecell";
 					reg = <0x0f0000 0x1000>;
 					interrupts = <0>;
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:17:33 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:17:33 +0200
Subject: [PATCH 3/3] arm64: dts: arm: drop unused interrupt-names in MHU
In-Reply-To: <20210820081733.83976-1-krzysztof.kozlowski@canonical.com>
References: <20210820081733.83976-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210820081733.83976-3-krzysztof.kozlowski@canonical.com>

The arm,mhu bindings and driver do not define interrupt-names, so drop
the property to fix warnings:

  arch/arm64/boot/dts/arm/juno-r2.dt.yaml: mhu at 2b1f0000: 'interrupt-names' does not match any of the regexes: 'pinctrl-[0-9]+'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/arm/juno-base.dtsi | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 8e7a66943b01..e4fea639731e 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -27,8 +27,6 @@ mailbox: mhu at 2b1f0000 {
 		reg = <0x0 0x2b1f0000 0x0 0x1000>;
 		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "mhu_lpri_rx",
-				  "mhu_hpri_rx";
 		#mbox-cells = <1>;
 		clocks = <&soc_refclk100mhz>;
 		clock-names = "apb_pclk";
-- 
2.30.2



From Claudiu.Beznea at microchip.com  Fri Aug 20 01:19:16 2021
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Fri, 20 Aug 2021 08:19:16 +0000
Subject: [PATCH v2] clk: at91: sama7g5: remove all kernel-doc & kernel-doc
 warnings
In-Reply-To: <20210819223237.20115-1-rdunlap@infradead.org>
References: <20210819223237.20115-1-rdunlap@infradead.org>
Message-ID: <e88f2e2b-ed2d-fd21-0297-f75ea75c42dc@microchip.com>

On 20.08.2021 01:32, Randy Dunlap wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Remove all "/**" kernel-doc markers from sama7g5.c since they are
> all internal to this driver source file only.
> This eliminates 14 warnings that were reported by the kernel test robot.
> 
> Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
> Reported-by: kernel test robot <lkp at intel.com>
> Cc: Claudiu Beznea <claudiu.beznea at microchip.com>
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: Eugen Hristev <eugen.hristev at microchip.com>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org

Reviewed-by: Claudiu Beznea <claudiu.beznea at microchip.com>

> ---
> v2: use /* instead of /** comments for internal documentation (as
>     suggested by Claudiu)
> 
>  drivers/clk/at91/sama7g5.c |   14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> --- linux-next-20210819.orig/drivers/clk/at91/sama7g5.c
> +++ linux-next-20210819/drivers/clk/at91/sama7g5.c
> @@ -35,7 +35,7 @@ static DEFINE_SPINLOCK(pmc_pll_lock);
>  static DEFINE_SPINLOCK(pmc_mck0_lock);
>  static DEFINE_SPINLOCK(pmc_mckX_lock);
> 
> -/**
> +/*
>   * PLL clocks identifiers
>   * @PLL_ID_CPU:                CPU PLL identifier
>   * @PLL_ID_SYS:                System PLL identifier
> @@ -56,7 +56,7 @@ enum pll_ids {
>         PLL_ID_MAX,
>  };
> 
> -/**
> +/*
>   * PLL type identifiers
>   * @PLL_TYPE_FRAC:     fractional PLL identifier
>   * @PLL_TYPE_DIV:      divider PLL identifier
> @@ -118,7 +118,7 @@ static const struct clk_pll_characterist
>         .output = pll_outputs,
>  };
> 
> -/**
> +/*
>   * PLL clocks description
>   * @n:         clock name
>   * @p:         clock parent
> @@ -285,7 +285,7 @@ static const struct {
>         },
>  };
> 
> -/**
> +/*
>   * Master clock (MCK[1..4]) description
>   * @n:                 clock name
>   * @ep:                        extra parents names array
> @@ -337,7 +337,7 @@ static const struct {
>           .c = 1, },
>  };
> 
> -/**
> +/*
>   * System clock description
>   * @n: clock name
>   * @p: clock parent name
> @@ -361,7 +361,7 @@ static const struct {
>  /* Mux table for programmable clocks. */
>  static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, };
> 
> -/**
> +/*
>   * Peripheral clock description
>   * @n:         clock name
>   * @p:         clock parent name
> @@ -449,7 +449,7 @@ static const struct {
>         { .n = "uhphs_clk",     .p = "mck1", .id = 106, },
>  };
> 
> -/**
> +/*
>   * Generic clock description
>   * @n:                 clock name
>   * @pp:                        PLL parents
> 


From krzysztof.kozlowski at canonical.com  Fri Aug 20 01:21:49 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 10:21:49 +0200
Subject: [PATCH 2/2] arm64: dts: exynos: add proper comaptible FSYS syscon in
 Exynos5433
In-Reply-To: <20210820081458.83406-1-krzysztof.kozlowski@canonical.com>
References: <20210820081458.83406-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210820082149.84613-1-krzysztof.kozlowski@canonical.com>

The syscon nodes should come with specific compatible.  Correct theh
FSYS syscon to fix dtbs_check warnings:

  syscon at 156f0000: compatible: 'anyOf' conditional failed, one must be fixed:
  ['syscon'] is too short

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos5433.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index ebd5091d68b4..4422021cf4b2 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -1132,7 +1132,7 @@ syscon_cam1: syscon at 145f0000 {
 		};
 
 		syscon_fsys: syscon at 156f0000 {
-			compatible = "syscon";
+			compatible = "samsung,exynos5433-sysreg", "syscon";
 			reg = <0x156f0000 0x1044>;
 		};
 
-- 
2.30.2



From will at kernel.org  Fri Aug 20 01:31:31 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 20 Aug 2021 09:31:31 +0100
Subject: [PATCH] arm64/mm: Drop page-def.h
In-Reply-To: <1629441331-19530-1-git-send-email-anshuman.khandual@arm.com>
References: <1629441331-19530-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210820083131.GB16784@willie-the-truck>

On Fri, Aug 20, 2021 at 12:05:31PM +0530, Anshuman Khandual wrote:
> PAGE_SHIFT (PAGE_SIZE and PAGE_MASK) which is derived from ARM64_PAGE_SHIFT
> should be moved into pgtable-hwdef.h instead, and subsequently page-def.h
> can be just dropped off completely.

According to who?

Every other architecture defines PAGE_SHIFT in page.h, so if you're moving
things around then that sounds like a better choice.

Will


From anshuman.khandual at arm.com  Fri Aug 20 01:52:10 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Aug 2021 14:22:10 +0530
Subject: [PATCH] arm64/mm: Drop page-def.h
In-Reply-To: <20210820083131.GB16784@willie-the-truck>
References: <1629441331-19530-1-git-send-email-anshuman.khandual@arm.com>
 <20210820083131.GB16784@willie-the-truck>
Message-ID: <4043e66c-c70b-00f8-4c0f-78b62b21a023@arm.com>



On 8/20/21 2:01 PM, Will Deacon wrote:
> On Fri, Aug 20, 2021 at 12:05:31PM +0530, Anshuman Khandual wrote:
>> PAGE_SHIFT (PAGE_SIZE and PAGE_MASK) which is derived from ARM64_PAGE_SHIFT
>> should be moved into pgtable-hwdef.h instead, and subsequently page-def.h
>> can be just dropped off completely.
> 
> According to who?
> 
> Every other architecture defines PAGE_SHIFT in page.h, so if you're moving
> things around then that sounds like a better choice.

Sure, will change. That is why I had asked the question :)

> 
> Will
> 


From will at kernel.org  Fri Aug 20 01:53:03 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 20 Aug 2021 09:53:03 +0100
Subject: [GIT PULL] arm64 fixes for -rc7
Message-ID: <20210820085302.GA17037@willie-the-truck>

Hi Linus,

Please pull these two straightforward fixes for -rc7. Summary in the tag.

Cheers,

Will

--->8

The following changes since commit 0c32706dac1b0a72713184246952ab0f54327c21:

  arm64: stacktrace: avoid tracing arch_stack_walk() (2021-08-03 10:39:35 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to bde8fff82e4a4b0f000dbf4d5eadab2079be0b56:

  arm64: initialize all of CNTHCTL_EL2 (2021-08-19 10:02:10 +0100)

----------------------------------------------------------------
arm64 fixes for -rc7

- Fix cleaning of vDSO directories

- Ensure CNTHCTL_EL2 is fully initialised when booting at EL2

----------------------------------------------------------------
Andrew Delgadillo (1):
      arm64: clean vdso & vdso32 files

Mark Rutland (1):
      arm64: initialize all of CNTHCTL_EL2

 arch/arm64/Makefile                | 2 ++
 arch/arm64/include/asm/el2_setup.h | 3 +--
 2 files changed, 3 insertions(+), 2 deletions(-)


From qperret at google.com  Fri Aug 20 02:08:56 2021
From: qperret at google.com (Quentin Perret)
Date: Fri, 20 Aug 2021 10:08:56 +0100
Subject: [PATCH 3/4] KVM: arm64: Convert the host S2 over to
 __load_guest_stage2()
In-Reply-To: <87tujkr1cq.wl-maz@kernel.org>
References: <20210806113109.2475-1-will@kernel.org>
 <20210806113109.2475-5-will@kernel.org>
 <YQ07sPoa4ACizYrp@google.com> <87tujkr1cq.wl-maz@kernel.org>
Message-ID: <YR9xKHYl7i2LN+/C@google.com>

On Friday 20 Aug 2021 at 09:01:41 (+0100), Marc Zyngier wrote:
> On Fri, 06 Aug 2021 14:40:00 +0100,
> Quentin Perret <qperret at google.com> wrote:
> > 
> > On Friday 06 Aug 2021 at 12:31:07 (+0100), Will Deacon wrote:
> > > From: Marc Zyngier <maz at kernel.org>
> > > 
> > > The protected mode relies on a separate helper to load the
> > > S2 context. Move over to the __load_guest_stage2() helper
> > > instead.
> > > 
> > > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > > Cc: Jade Alglave <jade.alglave at arm.com>
> > > Cc: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > Signed-off-by: Will Deacon <will at kernel.org>
> > > ---
> > >  arch/arm64/include/asm/kvm_mmu.h              | 11 +++--------
> > >  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  2 +-
> > >  arch/arm64/kvm/hyp/nvhe/mem_protect.c         |  2 +-
> > >  3 files changed, 5 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> > > index 05e089653a1a..934ef0deff9f 100644
> > > --- a/arch/arm64/include/asm/kvm_mmu.h
> > > +++ b/arch/arm64/include/asm/kvm_mmu.h
> > > @@ -267,9 +267,10 @@ static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
> > >   * Must be called from hyp code running at EL2 with an updated VTTBR
> > >   * and interrupts disabled.
> > >   */
> > > -static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long vtcr)
> > > +static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
> > > +						struct kvm_arch *arch)
> > >  {
> > > -	write_sysreg(vtcr, vtcr_el2);
> > > +	write_sysreg(arch->vtcr, vtcr_el2);
> > >  	write_sysreg(kvm_get_vttbr(mmu), vttbr_el2);
> > >  
> > >  	/*
> > > @@ -280,12 +281,6 @@ static __always_inline void __load_stage2(struct kvm_s2_mmu *mmu, unsigned long
> > >  	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
> > >  }
> > >  
> > > -static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu,
> > > -						struct kvm_arch *arch)
> > > -{
> > > -	__load_stage2(mmu, arch->vtcr);
> > > -}
> > > -
> > >  static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu)
> > >  {
> > >  	return container_of(mmu->arch, struct kvm, arch);
> > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > index 9c227d87c36d..a910648bc71b 100644
> > > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> > > @@ -29,7 +29,7 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt);
> > >  static __always_inline void __load_host_stage2(void)
> > >  {
> > >  	if (static_branch_likely(&kvm_protected_mode_initialized))
> > > -		__load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr);
> > > +		__load_guest_stage2(&host_kvm.arch.mmu, &host_kvm.arch);
> > >  	else
> > >  		write_sysreg(0, vttbr_el2);
> > >  }
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > index d938ce95d3bd..d4e74ca7f876 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> > > @@ -126,7 +126,7 @@ int __pkvm_prot_finalize(void)
> > >  	kvm_flush_dcache_to_poc(params, sizeof(*params));
> > >  
> > >  	write_sysreg(params->hcr_el2, hcr_el2);
> > > -	__load_stage2(&host_kvm.arch.mmu, host_kvm.arch.vtcr);
> > > +	__load_guest_stage2(&host_kvm.arch.mmu, &host_kvm.arch);
> > 
> > Nit: clearly we're not loading a guest stage-2 here, so maybe the
> > function should take a more generic name?
> 
> How about we rename __load_guest_stage2() to __load_stage2() instead,
> with the same parameters?

Yep, that'd work for me.

Thanks,
Quentin


From lkp at intel.com  Fri Aug 20 02:15:00 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 20 Aug 2021 17:15:00 +0800
Subject: [soc:for-next] BUILD SUCCESS 4364229fd55868a856a221885d319a50c254e986
Message-ID: <611f7294.ax/tTbJIg/WuA7do%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: 4364229fd55868a856a221885d319a50c254e986  soc: document merges

elapsed time: 974m

configs tested: 119
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
arm64                            allyesconfig
i386                 randconfig-c001-20210820
i386                 randconfig-c001-20210818
s390                          debug_defconfig
mips                         cobalt_defconfig
arc                        nsimosci_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                malta_qemu_32r6_defconfig
mips                     loongson1c_defconfig
csky                             alldefconfig
arm                          ixp4xx_defconfig
arm                      jornada720_defconfig
ia64                             allmodconfig
arm                         hackkit_defconfig
sh                           se7724_defconfig
powerpc                      obs600_defconfig
powerpc                     ksi8560_defconfig
arc                              allyesconfig
xtensa                    smp_lx200_defconfig
alpha                               defconfig
powerpc                       ebony_defconfig
arm                     am200epdkit_defconfig
arm                        cerfcube_defconfig
mips                         tb0226_defconfig
mips                         rt305x_defconfig
arm                             pxa_defconfig
powerpc                      chrp32_defconfig
mips                     loongson2k_defconfig
sh                         ecovec24_defconfig
arm                              alldefconfig
powerpc                 mpc8540_ads_defconfig
mips                     cu1000-neo_defconfig
sh                             espt_defconfig
mips                          rb532_defconfig
h8300                               defconfig
x86_64                            allnoconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
x86_64               randconfig-a005-20210820
x86_64               randconfig-a006-20210820
x86_64               randconfig-a001-20210820
x86_64               randconfig-a003-20210820
x86_64               randconfig-a004-20210820
x86_64               randconfig-a002-20210820
x86_64               randconfig-a013-20210819
x86_64               randconfig-a011-20210819
x86_64               randconfig-a012-20210819
x86_64               randconfig-a016-20210819
x86_64               randconfig-a014-20210819
x86_64               randconfig-a015-20210819
i386                 randconfig-a015-20210819
i386                 randconfig-a011-20210819
i386                 randconfig-a014-20210819
i386                 randconfig-a013-20210819
i386                 randconfig-a016-20210819
i386                 randconfig-a012-20210819
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
i386                 randconfig-c001-20210820
i386                 randconfig-a004-20210819
i386                 randconfig-a006-20210819
i386                 randconfig-a001-20210819
i386                 randconfig-a002-20210819
i386                 randconfig-a003-20210819
i386                 randconfig-a005-20210819
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From maz at kernel.org  Fri Aug 20 02:29:52 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 10:29:52 +0100
Subject: [PATCH] KVM: arm64: Ratelimit error log during guest debug
 exception
In-Reply-To: <20210819223406.1132426-1-rananta@google.com>
References: <20210819223406.1132426-1-rananta@google.com>
Message-ID: <87sfz4qx9r.wl-maz@kernel.org>

On Thu, 19 Aug 2021 23:34:06 +0100,
Raghavendra Rao Ananta <rananta at google.com> wrote:
> 
> Potentially, the guests could trigger a debug exception that's
> outside the exception class range.

How? All the exception classes that lead to this functions are already
handled in the switch/case statement.

> This could lead to an excessive syslog flooding. Hence, ratelimit
> the error message.
> 
> Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> ---
>  arch/arm64/kvm/handle_exit.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 04ebab299aa4..c7cec7ffe93c 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -134,7 +134,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu)
>  	case ESR_ELx_EC_BRK64:
>  		break;
>  	default:
> -		kvm_err("%s: un-handled case esr: %#08x\n",
> +		kvm_pr_unimpl("%s: un-handled case esr: %#08x\n",
>  			__func__, (unsigned int) esr);
>  		ret = -1;
>  		break;

My take on this is that this code isn't reachable, and that it could
be better rewritten as:

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 6f48336b1d86..ae7ec086827b 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -119,28 +119,14 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu)
 {
 	struct kvm_run *run = vcpu->run;
 	u32 esr = kvm_vcpu_get_esr(vcpu);
-	int ret = 0;
 
 	run->exit_reason = KVM_EXIT_DEBUG;
 	run->debug.arch.hsr = esr;
 
-	switch (ESR_ELx_EC(esr)) {
-	case ESR_ELx_EC_WATCHPT_LOW:
+	if (ESR_ELx_EC(esr) ==  ESR_ELx_EC_WATCHPT_LOW)
 		run->debug.arch.far = vcpu->arch.fault.far_el2;
-		fallthrough;
-	case ESR_ELx_EC_SOFTSTP_LOW:
-	case ESR_ELx_EC_BREAKPT_LOW:
-	case ESR_ELx_EC_BKPT32:
-	case ESR_ELx_EC_BRK64:
-		break;
-	default:
-		kvm_err("%s: un-handled case esr: %#08x\n",
-			__func__, (unsigned int) esr);
-		ret = -1;
-		break;
-	}
 
-	return ret;
+	return 0;
 }
 
 static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu)

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From claudiu.beznea at microchip.com  Fri Aug 20 02:27:59 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 20 Aug 2021 12:27:59 +0300
Subject: [PATCH v3 0/4] mmc: pwrseq: sd8787: add support wilc1000 devices
Message-ID: <20210820092803.78523-1-claudiu.beznea@microchip.com>

Hi,

This series adds support for WILC1000 devices on pwrseq-sd8787 driver.
WILC1000 devices needs a minimum delay of 5ms b/w reset and power lines.
Adapt the sd8787 driver for this by adding a new compatible for WILC1000
devices and specify the delay on .data field of struct of_device_id.

Thank you,
Claudiu Beznea

Changes in v3:
- fixed dt binding compilation

Changes in v2:
- changed cover letter title (it was: mmc: pwrseq: sd8787: add support
  for selectable)
- use new compatible in pwrseq-sd8787 driver instead of adding a new
  binding for specifying the delay; with this, the patch 1/1 from v1 is
  not necessary
- adapt patch 3/3 from this version with the new compatible


Claudiu Beznea (3):
  dt-bindings: pwrseq-sd8787: add binding for wilc1000
  mmc: pwrseq: sd8787: add support for wilc1000
  mmc: pwrseq: add wilc1000_sdio dependency for pwrseq_sd8787

Eugen Hristev (1):
  ARM: dts: at91: sama5d27_wlsom1: add wifi device

 .../bindings/mmc/mmc-pwrseq-sd8787.yaml       |  4 +-
 arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi   | 71 +++++++++++++++++++
 drivers/mmc/core/Kconfig                      |  2 +-
 drivers/mmc/core/pwrseq_sd8787.c              | 11 ++-
 4 files changed, 84 insertions(+), 4 deletions(-)

-- 
2.25.1



From claudiu.beznea at microchip.com  Fri Aug 20 02:28:00 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 20 Aug 2021 12:28:00 +0300
Subject: [PATCH v3 1/4] dt-bindings: pwrseq-sd8787: add binding for wilc1000
In-Reply-To: <20210820092803.78523-1-claudiu.beznea@microchip.com>
References: <20210820092803.78523-1-claudiu.beznea@microchip.com>
Message-ID: <20210820092803.78523-2-claudiu.beznea@microchip.com>

Add binding for wilc1000 devices.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
index e0169a285aa2..9e2396751030 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml
@@ -11,7 +11,9 @@ maintainers:
 
 properties:
   compatible:
-    const: mmc-pwrseq-sd8787
+    enum:
+      - mmc-pwrseq-sd8787
+      - mmc-pwrseq-wilc1000
 
   powerdown-gpios:
     minItems: 1
-- 
2.25.1



From claudiu.beznea at microchip.com  Fri Aug 20 02:28:01 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 20 Aug 2021 12:28:01 +0300
Subject: [PATCH v3 2/4] mmc: pwrseq: sd8787: add support for wilc1000
In-Reply-To: <20210820092803.78523-1-claudiu.beznea@microchip.com>
References: <20210820092803.78523-1-claudiu.beznea@microchip.com>
Message-ID: <20210820092803.78523-3-claudiu.beznea@microchip.com>

Add new compatible for wilc1000 devices and specify the delay in .data
member of struct of_device_id. WILC1000, WILC3000 devices needs a minimum
of 5ms delay b/w reset and power lines.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 drivers/mmc/core/pwrseq_sd8787.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c
index 68a826f1c0a1..264e48067af2 100644
--- a/drivers/mmc/core/pwrseq_sd8787.c
+++ b/drivers/mmc/core/pwrseq_sd8787.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -27,6 +28,7 @@ struct mmc_pwrseq_sd8787 {
 	struct mmc_pwrseq pwrseq;
 	struct gpio_desc *reset_gpio;
 	struct gpio_desc *pwrdn_gpio;
+	u32 reset_pwrdwn_delay_ms;
 };
 
 #define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
@@ -37,7 +39,7 @@ static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
 
 	gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
 
-	msleep(300);
+	msleep(pwrseq->reset_pwrdwn_delay_ms);
 	gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
 }
 
@@ -55,7 +57,8 @@ static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
 };
 
 static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
-	{ .compatible = "mmc-pwrseq-sd8787",},
+	{ .compatible = "mmc-pwrseq-sd8787", .data = (void *)300 },
+	{ .compatible = "mmc-pwrseq-wilc1000", .data = (void *)5 },
 	{/* sentinel */},
 };
 MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
@@ -64,11 +67,15 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
 {
 	struct mmc_pwrseq_sd8787 *pwrseq;
 	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
 
 	pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
 	if (!pwrseq)
 		return -ENOMEM;
 
+	match = of_match_node(mmc_pwrseq_sd8787_of_match, pdev->dev.of_node);
+	pwrseq->reset_pwrdwn_delay_ms = (u32)match->data;
+
 	pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW);
 	if (IS_ERR(pwrseq->pwrdn_gpio))
 		return PTR_ERR(pwrseq->pwrdn_gpio);
-- 
2.25.1



From claudiu.beznea at microchip.com  Fri Aug 20 02:28:02 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 20 Aug 2021 12:28:02 +0300
Subject: [PATCH v3 3/4] mmc: pwrseq: add wilc1000_sdio dependency for
 pwrseq_sd8787
In-Reply-To: <20210820092803.78523-1-claudiu.beznea@microchip.com>
References: <20210820092803.78523-1-claudiu.beznea@microchip.com>
Message-ID: <20210820092803.78523-4-claudiu.beznea@microchip.com>

pwseq_sd8787 could also be used with wilc1000_sdio driver. Add
a dependency for this.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 drivers/mmc/core/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index ae8b69aee619..6f25c34e4fec 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -15,7 +15,7 @@ config PWRSEQ_EMMC
 
 config PWRSEQ_SD8787
 	tristate "HW reset support for SD8787 BT + Wifi module"
-	depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO)
+	depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO || WILC1000_SDIO)
 	help
 	  This selects hardware reset support for the SD8787 BT + Wifi
 	  module. By default this option is set to n.
-- 
2.25.1



From claudiu.beznea at microchip.com  Fri Aug 20 02:28:03 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Fri, 20 Aug 2021 12:28:03 +0300
Subject: [PATCH v3 4/4] ARM: dts: at91: sama5d27_wlsom1: add wifi device
In-Reply-To: <20210820092803.78523-1-claudiu.beznea@microchip.com>
References: <20210820092803.78523-1-claudiu.beznea@microchip.com>
Message-ID: <20210820092803.78523-5-claudiu.beznea@microchip.com>

From: Eugen Hristev <eugen.hristev at microchip.com>

SAMA5D27 WLSOM1 boards has a WILC3000 device soldered. Add proper
device tree nodes for this.

[eugen.hristev: original author of this code]
Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
[nicolas.ferre: original author of this code]
Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi | 71 +++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
index 025a78310e3a..c7bcfd3ce91d 100644
--- a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
+++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
@@ -30,6 +30,15 @@ main_xtal {
 			clock-frequency = <24000000>;
 		};
 	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-wilc1000";
+		reset-gpios = <&pioA PIN_PA27 GPIO_ACTIVE_HIGH>;
+		powerdown-gpios = <&pioA PIN_PA29 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&pinctrl_wilc_pwrseq>;
+		pinctrl-names = "default";
+		status = "okay";
+	};
 };
 
 &flx1 {
@@ -310,5 +319,67 @@ pinctrl_qspi1_default: qspi1_default {
 			 <PIN_PB10__QSPI1_IO3>;
 		bias-pull-up;
 	};
+
+	pinctrl_sdmmc1_default: sdmmc1_default {
+		cmd-data {
+			pinmux = <PIN_PA28__SDMMC1_CMD>,
+				 <PIN_PA18__SDMMC1_DAT0>,
+				 <PIN_PA19__SDMMC1_DAT1>,
+				 <PIN_PA20__SDMMC1_DAT2>,
+				 <PIN_PA21__SDMMC1_DAT3>;
+			bias-disable;
+		};
+
+		conf-ck {
+			pinmux = <PIN_PA22__SDMMC1_CK>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_wilc_default: wilc_default {
+		conf-irq {
+			pinmux = <PIN_PB25__GPIO>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_wilc_pwrseq: wilc_pwrseq {
+		conf-ce-nrst {
+			pinmux = <PIN_PA27__GPIO>,
+				 <PIN_PA29__GPIO>;
+			bias-disable;
+		};
+
+		conf-rtcclk {
+			pinmux = <PIN_PB13__PCK1>;
+			bias-disable;
+		};
+	};
+};
+
+&sdmmc1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	no-1-8-v;
+	non-removable;
+	status = "okay";
+
+	wilc: wilc at 0 {
+		reg = <0>;
+		bus-width = <4>;
+		compatible = "microchip,wilc3000", "microchip,wilc1000";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_wilc_default>;
+		irq-gpios = <&pioA PIN_PB25 GPIO_ACTIVE_LOW>;
+		clocks = <&pmc PMC_TYPE_SYSTEM 9>;
+		clock-names = "rtc";
+		assigned-clocks = <&pmc PMC_TYPE_SYSTEM 9>;
+		assigned-clock-rates = <32768>;
+		status = "okay";
+	};
 };
 
-- 
2.25.1



From Jisheng.Zhang at synaptics.com  Fri Aug 20 02:31:08 2021
From: Jisheng.Zhang at synaptics.com (Jisheng Zhang)
Date: Fri, 20 Aug 2021 17:31:08 +0800
Subject: [PATCH] arm64: dts: synaptics: add DT for AS370-RDK
Message-ID: <20210820173108.01d5c6de@xhacker.debian>

Add a basic support for AS370-RDK board based on the AS370 SoC. We can
get a basic shell on the uart console now.

Signed-off-by: Jisheng Zhang <Jisheng.Zhang at synaptics.com>
---
Hi Arnd,

If it's too late, I will add it in a PR for 5.16 in next development window.

Thanks

 arch/arm64/boot/dts/synaptics/Makefile      |  1 +
 arch/arm64/boot/dts/synaptics/as370-rdk.dts | 29 +++++++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 arch/arm64/boot/dts/synaptics/as370-rdk.dts

diff --git a/arch/arm64/boot/dts/synaptics/Makefile b/arch/arm64/boot/dts/synaptics/Makefile
index de71ddda6835..c1c4f6c040b3 100644
--- a/arch/arm64/boot/dts/synaptics/Makefile
+++ b/arch/arm64/boot/dts/synaptics/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 # Berlin SoC Family
+dtb-$(CONFIG_ARCH_BERLIN) += as370-rdk.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-dmp.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-stb.dtb
diff --git a/arch/arm64/boot/dts/synaptics/as370-rdk.dts b/arch/arm64/boot/dts/synaptics/as370-rdk.dts
new file mode 100644
index 000000000000..6f5c37c98be6
--- /dev/null
+++ b/arch/arm64/boot/dts/synaptics/as370-rdk.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2018-2021 Synaptics Incorporated
+ *
+ * Author: Jisheng Zhang <jszhang at kernel.org>
+ */
+
+/dts-v1/;
+
+#include "as370.dtsi"
+
+/ {
+	model = "Synaptics AS370 RDK";
+	compatible = "syna,as370-rdk", "syna,as370";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 1000000 {
+		device_type = "memory";
+		/* the first 16MB is for firmwares' usage */
+		reg = <0 0x01000000 0 0x1f000000>;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
-- 
2.33.0



From ck.hu at mediatek.com  Fri Aug 20 02:37:47 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 20 Aug 2021 17:37:47 +0800
Subject: [PATCH v8 12/13] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20210819022327.13040-13-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-13-jason-jh.lin@mediatek.com>
Message-ID: <1629452267.23725.3.camel@mtksdaap41>

Hi, Jason:

On Thu, 2021-08-19 at 10:23 +0800, jason-jh.lin wrote:
> Add MERGE engine file:
> MERGE module is used to merge two slice-per-line inputs
> into one side-by-side output.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---

[snip]

> +
> +int mtk_merge_clk_enable(struct device *dev)
> +{
> +	int ret = 0;
> +	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +
> +	ret = clk_prepare_enable(priv->clk);
> +	if (ret)
> +		pr_err("merge clk prepare enable failed\n");
> +
> +	if (priv->async_clk) {

This checking is redundant.

> +		ret = clk_prepare_enable(priv->async_clk);
> +		if (ret)
> +			pr_err("async clk prepare enable failed\n");
> +	}
> +
> +	return ret;
> +}
> +
> +void mtk_merge_clk_disable(struct device *dev)
> +{
> +	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
> +
> +	if (priv->async_clk)

Ditto.

Regards,
CK

> +		clk_disable_unprepare(priv->async_clk);
> +
> +	clk_disable_unprepare(priv->clk);
> +}
> +



From rogerq at kernel.org  Fri Aug 20 02:37:44 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 20 Aug 2021 12:37:44 +0300
Subject: [PATCH] ARM: dts: da850-evm: Change aemif node status from "ok" to
 "okay"
Message-ID: <20210820093744.4877-1-rogerq@kernel.org>

As per Device Tree core schema, status parameter of nodes can be either
"okay" or "disabled".

U-boot Driver Model does not recognize status="ok" either and treats
the node as disabled.

[1] https://github.com/devicetree-org/dt-schema/blob/master/schemas/dt-core.yaml#L36

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 arch/arm/boot/dts/da850-evm.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index 87c517d65f62..9dc79b5977bf 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -415,7 +415,7 @@
 &aemif {
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_pins>;
-	status = "ok";
+	status = "okay";
 	cs3 {
 		#address-cells = <2>;
 		#size-cells = <1>;
-- 
2.17.1



From haibo.chen at nxp.com  Fri Aug 20 02:29:49 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Fri, 20 Aug 2021 17:29:49 +0800
Subject: [PATCH 1/2] ARM: dts: imx: change the spi-nor tx
Message-ID: <1629451790-10507-1-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Before commit 0e30f47232ab5 ("mtd: spi-nor: add support for DTR protocol"),
for all PP command, it only support 1-1-1 mode, no matter the tx setting
in dts. But after the upper commit, the logic change. It will choose
the best mode(fastest mode) which flash device and spi-nor host controller
both support.

Though the spi-nor device on imx6sx-sdb/imx6ul(l/z)-14x14-evk board
do not support PP-1-4-4/PP-1-1-4, but if tx is 4 in dts file, it will also
impact the read mode selection. For the spi-nor device on the upper mentioned
boards, they support read 1-4-4 mode and read 1-1-4 mode according to the
device internal sfdp register. But qspi host controller do not support
read 1-4-4 mode. so need to set the tx to 1, let the common code finally
select read 1-1-4 mode, PP-1-1-1 mode.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 arch/arm/boot/dts/imx6sx-sdb.dts        | 4 ++--
 arch/arm/boot/dts/imx6ul-14x14-evk.dtsi | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts
index 5a63ca615722..99f4cf777a38 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb.dts
@@ -114,7 +114,7 @@
 		compatible = "micron,n25q256a", "jedec,spi-nor";
 		spi-max-frequency = <29000000>;
 		spi-rx-bus-width = <4>;
-		spi-tx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
 		reg = <0>;
 	};
 
@@ -124,7 +124,7 @@
 		compatible = "micron,n25q256a", "jedec,spi-nor";
 		spi-max-frequency = <29000000>;
 		spi-rx-bus-width = <4>;
-		spi-tx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
 		reg = <2>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
index 779cc536566d..a3fde3316c73 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
@@ -292,7 +292,7 @@
 		compatible = "micron,n25q256a", "jedec,spi-nor";
 		spi-max-frequency = <29000000>;
 		spi-rx-bus-width = <4>;
-		spi-tx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
 		reg = <0>;
 	};
 };
-- 
2.17.1



From haibo.chen at nxp.com  Fri Aug 20 02:29:50 2021
From: haibo.chen at nxp.com (haibo.chen at nxp.com)
Date: Fri, 20 Aug 2021 17:29:50 +0800
Subject: [PATCH 2/2] arm64: dts: imx8: change the spi-nor tx
In-Reply-To: <1629451790-10507-1-git-send-email-haibo.chen@nxp.com>
References: <1629451790-10507-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <1629451790-10507-2-git-send-email-haibo.chen@nxp.com>

From: Haibo Chen <haibo.chen at nxp.com>

Before commit 0e30f47232ab5 ("mtd: spi-nor: add support for DTR protocol"),
for all PP command, it only support 1-1-1 mode, no matter the tx setting
in dts. But after the upper commit, the logic change. It will choose
the best mode(fastest mode) which flash device and spi-nor host controller
both support.

qspi and fspi host controller do not support read 1-4-4 mode. so need to
set the tx to 1, let the common code finally select read 1-1-4 mode.

Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi        | 2 +-
 arch/arm64/boot/dts/freescale/imx8mm-evk.dts                | 2 +-
 arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi        | 2 +-
 arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi       | 2 +-
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts                | 2 ++
 arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts | 2 +-
 6 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
index 988f8ab679ad..40f5e7a3b064 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
@@ -91,7 +91,7 @@
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
 		spi-max-frequency = <80000000>;
-		spi-tx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <4>;
 	};
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
index 4e2820d19244..a2b24d4d4e3e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dts
@@ -48,7 +48,7 @@
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
 		spi-max-frequency = <80000000>;
-		spi-tx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <4>;
 	};
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
index 54eaf3d6055b..3b2d627a0342 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
@@ -101,7 +101,7 @@
 		#size-cells = <1>;
 		compatible = "jedec,spi-nor";
 		spi-max-frequency = <80000000>;
-		spi-tx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <4>;
 	};
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
index aa78e0d8c72b..fc178eebf8aa 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
@@ -74,7 +74,7 @@
 		compatible = "jedec,spi-nor";
 		reg = <0>;
 		spi-max-frequency = <80000000>;
-		spi-tx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <4>;
 	};
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index 49f9db971f3b..b83df77195ec 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -337,6 +337,8 @@
 		#size-cells = <1>;
 		compatible = "micron,n25q256a", "jedec,spi-nor";
 		spi-max-frequency = <29000000>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts b/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts
index f593e4ff62e1..564746d5000d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts
@@ -281,7 +281,7 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 		reg = <0>;
-		spi-tx-bus-width = <4>;
+		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <4>;
 		m25p,fast-read;
 		spi-max-frequency = <50000000>;
-- 
2.17.1



From lkp at intel.com  Fri Aug 20 02:52:02 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 20 Aug 2021 17:52:02 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS 1e16a40211208d2d6e217e5013607219f4272dff
Message-ID: <611f7b42.9tztB2ZttNcmZIRl%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 1e16a40211208d2d6e217e5013607219f4272dff  Merge tag 'omap-for-v5.14/gpt12-fix-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/fixes

elapsed time: 723m

configs tested: 124
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
h8300                       h8s-sim_defconfig
riscv                            alldefconfig
arm                      pxa255-idp_defconfig
sh                            hp6xx_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                malta_qemu_32r6_defconfig
mips                     loongson1c_defconfig
csky                             alldefconfig
arm                          ixp4xx_defconfig
arm                      jornada720_defconfig
sh                          rsk7203_defconfig
m68k                             allmodconfig
arm                           stm32_defconfig
powerpc                       ppc64_defconfig
mips                 decstation_r4k_defconfig
powerpc                     mpc5200_defconfig
nios2                         3c120_defconfig
s390                             allyesconfig
arm                        keystone_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                       ebony_defconfig
arm                     am200epdkit_defconfig
arm                        cerfcube_defconfig
mips                         tb0226_defconfig
powerpc                     ksi8560_defconfig
powerpc                  mpc885_ads_defconfig
sh                           se7750_defconfig
powerpc                     rainier_defconfig
m68k                         amcore_defconfig
riscv                    nommu_virt_defconfig
m68k                        mvme147_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a006-20210820
i386                 randconfig-a001-20210820
i386                 randconfig-a002-20210820
i386                 randconfig-a005-20210820
i386                 randconfig-a003-20210820
i386                 randconfig-a004-20210820
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
x86_64               randconfig-a013-20210819
x86_64               randconfig-a011-20210819
x86_64               randconfig-a012-20210819
x86_64               randconfig-a016-20210819
x86_64               randconfig-a014-20210819
x86_64               randconfig-a015-20210819
i386                 randconfig-a015-20210819
i386                 randconfig-a011-20210819
i386                 randconfig-a014-20210819
i386                 randconfig-a013-20210819
i386                 randconfig-a016-20210819
i386                 randconfig-a012-20210819
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
i386                 randconfig-c001-20210819
x86_64               randconfig-a004-20210819
x86_64               randconfig-a006-20210819
x86_64               randconfig-a003-20210819
x86_64               randconfig-a002-20210819
x86_64               randconfig-a005-20210819
x86_64               randconfig-a001-20210819
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From ben.tseng at mediatek.com  Fri Aug 20 02:52:06 2021
From: ben.tseng at mediatek.com (Ben Tseng)
Date: Fri, 20 Aug 2021 17:52:06 +0800
Subject: [PATCH v9] thermal: mediatek: add another get_temp ops for thermal
 sensors
Message-ID: <20210820095206.30981-1-ben.tseng@mediatek.com>

From: Michael Kao <michael.kao at mediatek.com>

Provide thermal zone to read thermal sensor
in the SoC. We can read all the thermal sensors
value in the SoC by the node /sys/class/thermal/

In mtk_thermal_bank_temperature, return -EAGAIN instead of -EACCESS
on the first read of sensor that often are bogus values.
This can avoid following warning on boot:

  thermal thermal_zone6: failed to read out thermal zone (-13)

Signed-off-by: Michael Kao <michael.kao at mediatek.com>
Signed-off-by: Hsin-Yi Wang <hsinyi at chromium.org>
Signed-off-by: Ben Tseng <ben.tseng at mediatek.com>
---

This patchset supports for MT8183 chip to mtk_thermal.c.
Add thermal zone of all the thermal sensor in SoC for
another get temperatrue. They don't need to thermal throttle.
And we bind coolers for thermal zone nodes of cpu_thermal.

Changes in V9:
    - Rebase to kernel-v5.14-rc1
    - Bind raw_to_mcelsius_v1 or raw_to_mcelsius_v2 to compatible
      data of struct mtk_thermal_data
    - Remove duplicate struct 'mtk_thermal_bank'
    - Remove unnecessary if condition check
    - Return error if any thermal zone fail to register

Changes in V8:
    - Rebase to kernel-v5.13-rc1
    - Resend

Changes in v7:
    - Fix build error in v6.

Changes in v6:
    - Rebase to kernel-5.11-rc1.
    - [1/3]
        - add interrupts property.
    - [2/3]
        - add the Tested-by in the commit message.
    - [3/3]
        - use the mt->conf->msr[id] instead of conf->msr[id] in the
          _get_sensor_temp and mtk_thermal_bank_temperature.
        - remove the redundant space in _get_sensor_temp and
          mtk_read_sensor_temp.
        - change kmalloc to dev_kmalloc in mtk_thermal_probe.

Changes in v5:
    - Rebase to kernel-5.9-rc1.
    - Revise the title of cover letter.
    - Drop "[v4,7/7] thermal: mediatek: use spinlock to protect PTPCORESEL"
    - [2/2]
        -  Add the judgement to the version of raw_to_mcelsius.

Changes in v4:
    - Rebase to kernel-5.6-rc1.
    - [1/7]
        - Squash thermal zone settings in the dtsi from [v3,5/8]
          arm64: dts: mt8183: Increase polling frequency for CPU thermal zone.
        - Remove the property of interrupts and mediatek,hw-reset-temp.
    - [2/7]
        - Correct commit message.
    - [4/7]
        - Change the target temperature to the 80C and change the commit message.
    - [6/7]
        - Adjust newline alignment.
        - Fix the judgement on the return value of registering thermal zone.

Changes in v3:
    - Rebase to kernel-5.5-rc1.
    - [1/8]
        - Update sustainable power of cpu, tzts1~5 and tztsABB.
    - [7/8]
        - Bypass the failure that non cpu_thermal sensor is not find in thermal-zones
          in dts, which is normal for mt8173, so prompt a warning here instead of
          failing.

	Return -EAGAIN instead of -EACCESS on the first read of sensor that
        often are bogus values. This can avoid following warning on boot:

          thermal thermal_zone6: failed to read out thermal zone (-13)

Changes in v2:
    - [1/8]
        - Add the sustainable-power,trips,cooling-maps to the tzts1~tztsABB.
    - [4/8]
        - Add the min opp of cpu throttle.

Matthias Kaehlcke (1):
  arm64: dts: mt8183: Configure CPU cooling

Michael Kao (2):
  thermal: mediatek: add another get_temp ops for thermal sensors
  arm64: dts: mt8183: add thermal zone node
---
 drivers/thermal/mtk_thermal.c | 95 +++++++++++++++++++++++++++++++------------
 1 file changed, 70 insertions(+), 25 deletions(-)

diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index ede94ea..8bb0bb2 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -271,6 +271,7 @@ struct mtk_thermal_data {
 	bool need_switch_bank;
 	struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
 	enum mtk_thermal_version version;
+	int (*raw_to_mcelsius)(struct mtk_thermal *mt, int sensno, s32 raw);
 };
 
 struct mtk_thermal {
@@ -294,6 +295,9 @@ struct mtk_thermal {
 	struct mtk_thermal_bank banks[MAX_NUM_ZONES];
 };
 
+static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw);
+static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw);
+
 /* MT8183 thermal sensor data */
 static const int mt8183_bank_data[MT8183_NUM_SENSORS] = {
 	MT8183_TS1, MT8183_TS2, MT8183_TS3, MT8183_TS4, MT8183_TS5, MT8183_TSABB
@@ -427,6 +431,7 @@ struct mtk_thermal {
 	.adcpnp = mt8173_adcpnp,
 	.sensor_mux_values = mt8173_mux_values,
 	.version = MTK_THERMAL_V1,
+	.raw_to_mcelsius = raw_to_mcelsius_v1,
 };
 
 /*
@@ -458,6 +463,7 @@ struct mtk_thermal {
 	.adcpnp = mt2701_adcpnp,
 	.sensor_mux_values = mt2701_mux_values,
 	.version = MTK_THERMAL_V1,
+	.raw_to_mcelsius = raw_to_mcelsius_v1,
 };
 
 /*
@@ -489,6 +495,7 @@ struct mtk_thermal {
 	.adcpnp = mt2712_adcpnp,
 	.sensor_mux_values = mt2712_mux_values,
 	.version = MTK_THERMAL_V1,
+	.raw_to_mcelsius = raw_to_mcelsius_v1,
 };
 
 /*
@@ -514,6 +521,7 @@ struct mtk_thermal {
 	.adcpnp = mt7622_adcpnp,
 	.sensor_mux_values = mt7622_mux_values,
 	.version = MTK_THERMAL_V2,
+	.raw_to_mcelsius = raw_to_mcelsius_v2,
 };
 
 /*
@@ -547,6 +555,7 @@ struct mtk_thermal {
 	.adcpnp = mt8183_adcpnp,
 	.sensor_mux_values = mt8183_mux_values,
 	.version = MTK_THERMAL_V1,
+	.raw_to_mcelsius = raw_to_mcelsius_v1,
 };
 
 /**
@@ -639,6 +648,27 @@ static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
 		mutex_unlock(&mt->lock);
 }
 
+static u32 _get_sensor_temp(struct mtk_thermal *mt, int id)
+{
+	u32 raw;
+	int temp;
+
+	raw = readl(mt->thermal_base + mt->conf->msr[id]);
+
+	temp = mt->conf->raw_to_mcelsius(mt, id, raw);
+
+	/*
+	 * The first read of a sensor often contains very high bogus
+	 * temperature value. Filter these out so that the system does
+	 * not immediately shut down.
+	 */
+
+	if (temp > 200000)
+		return -EAGAIN;
+	else
+		return temp;
+}
+
 /**
  * mtk_thermal_bank_temperature - get the temperature of a bank
  * @bank:	The bank
@@ -649,28 +679,11 @@ static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
 static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
 {
 	struct mtk_thermal *mt = bank->mt;
-	const struct mtk_thermal_data *conf = mt->conf;
 	int i, temp = INT_MIN, max = INT_MIN;
-	u32 raw;
-
-	for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
-		raw = readl(mt->thermal_base + conf->msr[i]);
 
-		if (mt->conf->version == MTK_THERMAL_V1) {
-			temp = raw_to_mcelsius_v1(
-				mt, conf->bank_data[bank->id].sensors[i], raw);
-		} else {
-			temp = raw_to_mcelsius_v2(
-				mt, conf->bank_data[bank->id].sensors[i], raw);
-		}
+	for (i = 0; i < mt->conf->bank_data[bank->id].num_sensors; i++) {
 
-		/*
-		 * The first read of a sensor often contains very high bogus
-		 * temperature value. Filter these out so that the system does
-		 * not immediately shut down.
-		 */
-		if (temp > 200000)
-			temp = 0;
+		temp = _get_sensor_temp(mt, i);
 
 		if (temp > max)
 			max = temp;
@@ -681,7 +694,8 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
 
 static int mtk_read_temp(void *data, int *temperature)
 {
-	struct mtk_thermal *mt = data;
+	struct mtk_thermal_bank *tz = data;
+	struct mtk_thermal *mt = tz->mt;
 	int i;
 	int tempmax = INT_MIN;
 
@@ -700,10 +714,25 @@ static int mtk_read_temp(void *data, int *temperature)
 	return 0;
 }
 
+static int mtk_read_sensor_temp(void *data, int *temperature)
+{
+	struct mtk_thermal_bank *tz = data;
+	struct mtk_thermal *mt = tz->mt;
+	int id = tz->id - 1;
+
+	*temperature = _get_sensor_temp(mt, id);
+
+	return 0;
+}
+
 static const struct thermal_zone_of_device_ops mtk_thermal_ops = {
 	.get_temp = mtk_read_temp,
 };
 
+static const struct thermal_zone_of_device_ops mtk_thermal_sensor_ops = {
+	.get_temp = mtk_read_sensor_temp,
+};
+
 static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
 				  u32 apmixed_phys_base, u32 auxadc_phys_base,
 				  int ctrl_id)
@@ -994,6 +1023,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
 	u64 auxadc_phys_base, apmixed_phys_base;
 	struct thermal_zone_device *tzdev;
 	void __iomem *apmixed_base, *auxadc_base;
+	struct mtk_thermal_bank *tz;
 
 	mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
 	if (!mt)
@@ -1082,11 +1112,26 @@ static int mtk_thermal_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mt);
 
-	tzdev = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, mt,
-						     &mtk_thermal_ops);
-	if (IS_ERR(tzdev)) {
-		ret = PTR_ERR(tzdev);
-		goto err_disable_clk_peri_therm;
+	for (i = 0; i < mt->conf->num_sensors + 1; i++) {
+		tz = devm_kmalloc(&pdev->dev, sizeof(*tz), GFP_KERNEL);
+		if (!tz)
+			return -ENOMEM;
+
+		tz->mt = mt;
+		tz->id = i;
+
+		tzdev = devm_thermal_zone_of_sensor_register(
+						&pdev->dev, i, tz, (i == 0) ?
+						&mtk_thermal_ops :
+						&mtk_thermal_sensor_ops);
+
+		if (IS_ERR(tzdev)) {
+			ret = PTR_ERR(tzdev);
+			dev_err(&pdev->dev,
+				"Error: Failed to register thermal zone %d, ret = %d\n",
+				i, ret);
+			goto err_disable_clk_peri_therm;
+		}
 	}
 
 	ret = devm_thermal_add_hwmon_sysfs(tzdev);
-- 
1.8.1.1.dirty

From rogerq at kernel.org  Fri Aug 20 02:53:39 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 20 Aug 2021 12:53:39 +0300
Subject: [PATCH 0/2] ARM: dts: keystone-k2*-evm: Fix mdio and dss node status
Message-ID: <20210820095341.5619-1-rogerq@kernel.org>

Hi Santosh,

This series fixes mdio and dss status nodes from "ok" to "okay"

As per Device Tree core schema [1], status parameter of nodes can be either
"okay" or "disabled".

U-boot Driver Model does not recognize status="ok" either and treats
the node as disabled.

[1] https://github.com/devicetree-org/dt-schema/blob/master/schemas/dt-core.yaml#L36

cheers,
-roger

Roger Quadros (2):
  ARM: dts: keystone-k2*-evm: Fix mdio node status to "okay"
  ARM: dts: keystone-k2g-evm: Fix dss node status to "okay"

 arch/arm/boot/dts/keystone-k2e-evm.dts  | 2 +-
 arch/arm/boot/dts/keystone-k2g-evm.dts  | 2 +-
 arch/arm/boot/dts/keystone-k2hk-evm.dts | 2 +-
 arch/arm/boot/dts/keystone-k2l-evm.dts  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

-- 
2.17.1



From rogerq at kernel.org  Fri Aug 20 02:53:40 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 20 Aug 2021 12:53:40 +0300
Subject: [PATCH 1/2] ARM: dts: keystone-k2*-evm: Fix mdio node status to "okay"
In-Reply-To: <20210820095341.5619-1-rogerq@kernel.org>
References: <20210820095341.5619-1-rogerq@kernel.org>
Message-ID: <20210820095341.5619-2-rogerq@kernel.org>

As per Device Tree core schema [1], status parameter of nodes can be either
"okay" or "disabled".

U-boot Driver Model does not recognize status="ok" either and treats
the node as disabled.

[1] https://github.com/devicetree-org/dt-schema/blob/master/schemas/dt-core.yaml#L36

Cc: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 arch/arm/boot/dts/keystone-k2e-evm.dts  | 2 +-
 arch/arm/boot/dts/keystone-k2hk-evm.dts | 2 +-
 arch/arm/boot/dts/keystone-k2l-evm.dts  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/keystone-k2e-evm.dts b/arch/arm/boot/dts/keystone-k2e-evm.dts
index 66fec5f5d081..acac242ebdf7 100644
--- a/arch/arm/boot/dts/keystone-k2e-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2e-evm.dts
@@ -159,7 +159,7 @@
 };
 
 &mdio {
-	status = "ok";
+	status = "okay";
 	ethphy0: ethernet-phy at 0 {
 		compatible = "marvell,88E1514", "marvell,88E1510", "ethernet-phy-ieee802.3-c22";
 		reg = <0>;
diff --git a/arch/arm/boot/dts/keystone-k2hk-evm.dts b/arch/arm/boot/dts/keystone-k2hk-evm.dts
index ad4e22afe133..5e85f000acc3 100644
--- a/arch/arm/boot/dts/keystone-k2hk-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2hk-evm.dts
@@ -183,7 +183,7 @@
 };
 
 &mdio {
-	status = "ok";
+	status = "okay";
 	ethphy0: ethernet-phy at 0 {
 		compatible = "marvell,88E1111", "ethernet-phy-ieee802.3-c22";
 		reg = <0>;
diff --git a/arch/arm/boot/dts/keystone-k2l-evm.dts b/arch/arm/boot/dts/keystone-k2l-evm.dts
index e200533d26a4..a6cbff4cfe20 100644
--- a/arch/arm/boot/dts/keystone-k2l-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2l-evm.dts
@@ -132,7 +132,7 @@
 };
 
 &mdio {
-	status = "ok";
+	status = "okay";
 	ethphy0: ethernet-phy at 0 {
 		compatible = "marvell,88E1514", "marvell,88E1510", "ethernet-phy-ieee802.3-c22";
 		reg = <0>;
-- 
2.17.1



From rogerq at kernel.org  Fri Aug 20 02:53:41 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 20 Aug 2021 12:53:41 +0300
Subject: [PATCH 2/2] ARM: dts: keystone-k2g-evm: Fix dss node status to "okay"
In-Reply-To: <20210820095341.5619-1-rogerq@kernel.org>
References: <20210820095341.5619-1-rogerq@kernel.org>
Message-ID: <20210820095341.5619-3-rogerq@kernel.org>

As per Device Tree core schema [1], status parameter of nodes can be either
"okay" or "disabled".

U-boot Driver Model does not recognize status="ok" either and treats
the node as disabled.

[1] https://github.com/devicetree-org/dt-schema/blob/master/schemas/dt-core.yaml#L36

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 arch/arm/boot/dts/keystone-k2g-evm.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts b/arch/arm/boot/dts/keystone-k2g-evm.dts
index d800f26b6275..57680323e202 100644
--- a/arch/arm/boot/dts/keystone-k2g-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2g-evm.dts
@@ -534,7 +534,7 @@
 &dss {
 	pinctrl-names = "default";
 	pinctrl-0 = <&vout_pins>;
-	status = "ok";
+	status = "okay";
 
 	port {
 		dpi_out: endpoint {
-- 
2.17.1



From krzysztof.kozlowski at canonical.com  Fri Aug 20 02:59:30 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 11:59:30 +0200
Subject: [PATCH] arm64: dts: synaptics: add DT for AS370-RDK
In-Reply-To: <20210820173108.01d5c6de@xhacker.debian>
References: <20210820173108.01d5c6de@xhacker.debian>
Message-ID: <29e96ece-8541-a7a2-c6a9-453be6644eed@canonical.com>

On 20/08/2021 11:31, Jisheng Zhang wrote:
> Add a basic support for AS370-RDK board based on the AS370 SoC. We can
> get a basic shell on the uart console now.
> 
> Signed-off-by: Jisheng Zhang <Jisheng.Zhang at synaptics.com>
> ---
> Hi Arnd,
> 
> If it's too late, I will add it in a PR for 5.16 in next development window.
> 
> Thanks
> 
>  arch/arm64/boot/dts/synaptics/Makefile      |  1 +
>  arch/arm64/boot/dts/synaptics/as370-rdk.dts | 29 +++++++++++++++++++++
>  2 files changed, 30 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/synaptics/as370-rdk.dts
> 
> diff --git a/arch/arm64/boot/dts/synaptics/Makefile b/arch/arm64/boot/dts/synaptics/Makefile
> index de71ddda6835..c1c4f6c040b3 100644
> --- a/arch/arm64/boot/dts/synaptics/Makefile
> +++ b/arch/arm64/boot/dts/synaptics/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0
>  # Berlin SoC Family
> +dtb-$(CONFIG_ARCH_BERLIN) += as370-rdk.dtb
>  dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-dmp.dtb
>  dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-stb.dtb
> diff --git a/arch/arm64/boot/dts/synaptics/as370-rdk.dts b/arch/arm64/boot/dts/synaptics/as370-rdk.dts
> new file mode 100644
> index 000000000000..6f5c37c98be6
> --- /dev/null
> +++ b/arch/arm64/boot/dts/synaptics/as370-rdk.dts
> @@ -0,0 +1,29 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (C) 2018-2021 Synaptics Incorporated
> + *
> + * Author: Jisheng Zhang <jszhang at kernel.org>
> + */
> +
> +/dts-v1/;
> +
> +#include "as370.dtsi"
> +
> +/ {
> +	model = "Synaptics AS370 RDK";
> +	compatible = "syna,as370-rdk", "syna,as370";

There is no such binding. You need to update the bindings file (first
patch in the series).


Best regards,
Krzysztof


From balbi at kernel.org  Fri Aug 20 03:06:33 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Fri, 20 Aug 2021 13:06:33 +0300
Subject: [PATCH] usb: dwc3: imx8mp: request irq after initializing dwc3
In-Reply-To: <20210819154818.18334-1-lutovinova@ispras.ru>
References: <20210819154818.18334-1-lutovinova@ispras.ru>
Message-ID: <878s0wfn0c.fsf@kernel.org>


Nadezda Lutovinova <lutovinova at ispras.ru> writes:

> If IRQ occurs between calling  devm_request_threaded_irq() and
> initializing dwc3_imx->dwc3, then null pointer dereference occurs
> since dwc3_imx->dwc3 is used in dwc3_imx8mp_interrupt().
>
> The patch puts registration of the interrupt handler after
> initializing of neccesery data.
>
> Found by Linux Driver Verification project (linuxtesting.org).
>
> Signed-off-by: Nadezda Lutovinova <lutovinova at ispras.ru>

Acked-by: Felipe Balbi <balbi at kernel.org>

-- 
balbi


From jiapeng.chong at linux.alibaba.com  Fri Aug 20 03:18:49 2021
From: jiapeng.chong at linux.alibaba.com (Jiapeng Chong)
Date: Fri, 20 Aug 2021 18:18:49 +0800
Subject: [PATCH] drm/rockchip: dsi: Fix duplicate included linux/phy/phy.h
Message-ID: <1629454729-108701-1-git-send-email-jiapeng.chong@linux.alibaba.com>

Clean up the following includecheck warning:

./drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c: linux/phy/phy.h is
included more than once.

Reported-by: Abaci Robot <abaci at linux.alibaba.com>
Fixes: 71f68fe7f121 ("drm/rockchip: dsi: add ability to work as a phy instead of full dsi")
Signed-off-by: Jiapeng Chong <jiapeng.chong at linux.alibaba.com>
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index a2262be..4a6c100 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -14,7 +14,6 @@
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/pm_runtime.h>
-#include <linux/phy/phy.h>
 #include <linux/regmap.h>
 
 #include <video/mipi_display.h>
-- 
1.8.3.1



From catalin.marinas at arm.com  Fri Aug 20 03:21:20 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Aug 2021 11:21:20 +0100
Subject: [PATCH] kselftest/arm64: mte: Fix misleading output when skipping
 tests
In-Reply-To: <20210819172902.56211-1-broonie@kernel.org>
References: <20210819172902.56211-1-broonie@kernel.org>
Message-ID: <162945486488.9629.5209865978733012612.b4-ty@arm.com>

On Thu, 19 Aug 2021 18:29:02 +0100, Mark Brown wrote:
> When skipping the tests due to a lack of system support for MTE we
> currently print a message saying FAIL which makes it look like the test
> failed even though the test did actually report KSFT_SKIP, creating some
> confusion. Change the error message to say SKIP instead so things are
> clearer.

Applied to arm64 (for-next/kselftest), thanks!

[1/1] kselftest/arm64: mte: Fix misleading output when skipping tests
      https://git.kernel.org/arm64/c/83e5dcbece4e

-- 
Catalin



From steven.price at arm.com  Fri Aug 20 03:22:45 2021
From: steven.price at arm.com (Steven Price)
Date: Fri, 20 Aug 2021 11:22:45 +0100
Subject: [PATCH v7 1/9] iommu: Introduce a union to struct
 iommu_resv_region
In-Reply-To: <20210805080724.480-2-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <20210805080724.480-2-shameerali.kolothum.thodi@huawei.com>
Message-ID: <02a2c1cf-11f2-e3c1-95b5-828ceda88517@arm.com>

On 05/08/2021 09:07, Shameer Kolothum wrote:
> A union is introduced to struct iommu_resv_region to hold
> any firmware specific data. This is in preparation to add
> support for IORT RMR reserve regions and the union now holds
> the RMR specific information.
> 
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  include/linux/iommu.h | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 32d448050bf7..bd0e4641c569 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -114,6 +114,13 @@ enum iommu_resv_type {
>  	IOMMU_RESV_SW_MSI,
>  };
>  
> +struct iommu_iort_rmr_data {
> +#define IOMMU_RMR_REMAP_PERMITTED	(1 << 0)
> +	u32 flags;
> +	u32 sid;	/* Stream Id associated with RMR entry */
> +	void *smmu;	/* Associated IORT SMMU node pointer */
> +};
> +
>  /**
>   * struct iommu_resv_region - descriptor for a reserved memory region
>   * @list: Linked list pointers
> @@ -121,6 +128,7 @@ enum iommu_resv_type {
>   * @length: Length of the region in bytes
>   * @prot: IOMMU Protection flags (READ/WRITE/...)
>   * @type: Type of the reserved region
> + * @rmr: ACPI IORT RMR specific data

NIT: This will provoke a kernel-doc warning as the field name in the
structure is 'fw_data' not 'rmr' ('rmr being a field of the anonymous
union).

I've also retested this series on my Juno setup, so feel free to add:

Tested-by: Steven Price <steven.price at arm.com>

Thanks,

Steve

>   */
>  struct iommu_resv_region {
>  	struct list_head	list;
> @@ -128,6 +136,9 @@ struct iommu_resv_region {
>  	size_t			length;
>  	int			prot;
>  	enum iommu_resv_type	type;
> +	union {
> +		struct iommu_iort_rmr_data rmr;
> +	} fw_data;
>  };
>  
>  /**
> 



From shengjiu.wang at nxp.com  Fri Aug 20 03:03:10 2021
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Fri, 20 Aug 2021 18:03:10 +0800
Subject: [PATCH 1/2] dt-bindings: remoteproc: Add fsl,
 imx-dsp-rproc binding document
Message-ID: <1629453791-10580-1-git-send-email-shengjiu.wang@nxp.com>

Define the compatible string and properties needed by imx_dsp_rproc
driver.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
 .../remoteproc/fsl,imx-dsp-rproc.yaml         | 123 ++++++++++++++++++
 1 file changed, 123 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
new file mode 100644
index 000000000000..7eba49aa959e
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
@@ -0,0 +1,123 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/fsl,imx-dsp-rproc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX DSP Remoteproc Devices
+
+maintainers:
+  - Shengjiu Wang <shengjiu.wang at nxp.com>
+
+description:
+  This binding provides support for DSP processors found on i.mX family of SoCs
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-hifi4
+      - fsl,imx8qm-hifi4
+      - fsl,imx8mp-hifi4
+      - fsl,imx8ulp-hifi4
+
+  clocks:
+    description: |
+      Main functional clock for the remote processor
+    minItems: 1
+    maxItems: 32
+
+  clock-names:
+    description:
+      List of clock names for the remote processor.
+      dsp_clkx for clocks of dsp itself.
+      per_clkx for clocks of peripherals used by dsp.
+    minItems: 1
+    maxItems: 32
+
+  syscon:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to syscon block which provide access for processor enablement
+
+  mbox-names:
+    items:
+      - const: tx
+      - const: rx
+      - const: rxdb
+
+  mboxes:
+    description:
+      This property is required only if the rpmsg/virtio functionality is used.
+      List of <&phandle type channel> - 1 channel for TX, 1 channel for RX, 1 channel for RXDB.
+      (see mailbox/fsl,mu.yaml)
+    minItems: 1
+    maxItems: 3
+
+  firmware-name:
+    description: |
+      Default name of the firmware to load to the remote processor.
+
+  memory-region:
+    description:
+      If present, a phandle for a reserved memory area that used for vdev buffer,
+      resource table, vring region and others used by remote processor.
+    minItems: 1
+    maxItems: 32
+
+  reg:
+    description: |
+      Address space for any remoteproc memories present on the SoC.
+
+  power-domains:
+    minItems: 1
+    maxItems: 32
+
+required:
+  - compatible
+  - reg
+  - mboxes
+  - mbox-names
+  - clocks
+  - clock-names
+  - firmware-name
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mp-clock.h>
+    dsp_reserved: dsp at 92400000 {
+      reg = <0x92400000 0x1000000>;
+      no-map;
+    };
+    dsp_vdev0vring0: vdev0vring0 at 942f0000 {
+      reg = <0x942f0000 0x8000>;
+      no-map;
+    };
+    dsp_vdev0vring1: vdev0vring1 at 942f8000 {
+      reg = <0x942f8000 0x8000>;
+      no-map;
+    };
+    dsp_vdev0buffer: vdev0buffer at 94300000 {
+      compatible = "shared-dma-pool";
+      reg = <0x94300000 0x100000>;
+      no-map;
+    };
+
+    dsp: dsp at 3b6e8000 {
+      compatible = "fsl,imx8mp-hifi4";
+      reg = <0x3B6E8000 0x88000>;
+      clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG>,
+               <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSP_ROOT>,
+               <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT>;
+      clock-names = "dsp_clk1", "dsp_clk2", "dsp_clk3";
+      firmware-name = "imx/dsp/hifi4.bin";
+      power-domains = <&audiomix_pd>;
+      mbox-names = "tx", "rx", "rxdb";
+      mboxes = <&mu2 0 0>,
+               <&mu2 1 0>,
+               <&mu2 3 0>;
+      memory-region = <&dsp_vdev0buffer>, <&dsp_vdev0vring0>,
+                      <&dsp_vdev0vring1>, <&dsp_reserved>;
+      syscon = <&audio_blk_ctrl>;
+    };
-- 
2.17.1



From shengjiu.wang at nxp.com  Fri Aug 20 03:03:11 2021
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Fri, 20 Aug 2021 18:03:11 +0800
Subject: [PATCH 2/2] remoteproc: imx_dsp_rproc: add remoteproc driver for dsp
 on i.MX
In-Reply-To: <1629453791-10580-1-git-send-email-shengjiu.wang@nxp.com>
References: <1629453791-10580-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <1629453791-10580-2-git-send-email-shengjiu.wang@nxp.com>

Provide a basic driver to control DSP processor found on NXP i.MX8QM,
i.MX8QXP, i.MX8MP and i.MX8ULP.

Currently it is able to resolve addresses between DSP and main CPU,
start and stop the processor, suspend and resume.

The communication between DSP and main CPU is based on mailbox, there
are three mailbox channels (tx, rx, rxdb).

This driver was tested on NXP i.MX8QM, i.MX8QXP, i.MX8MP and i.MX8ULP.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
 drivers/remoteproc/Kconfig         |   11 +
 drivers/remoteproc/Makefile        |    1 +
 drivers/remoteproc/imx_dsp_rproc.c | 1078 ++++++++++++++++++++++++++++
 3 files changed, 1090 insertions(+)
 create mode 100644 drivers/remoteproc/imx_dsp_rproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 9a6eedc3994a..890a14e6f3f9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -34,6 +34,17 @@ config IMX_REMOTEPROC
 
 	  It's safe to say N here.
 
+config IMX_DSP_REMOTEPROC
+	tristate "i.MX DSP remoteproc support"
+	depends on ARCH_MXC
+	depends on HAVE_ARM_SMCCC
+	select MAILBOX
+	help
+	  Say y here to support iMX's DSP remote processors via the remote
+	  processor framework.
+
+	  It's safe to say N here.
+
 config INGENIC_VPU_RPROC
 	tristate "Ingenic JZ47xx VPU remoteproc support"
 	depends on MIPS || COMPILE_TEST
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index bb26c9e4ef9c..37d5cb1c04bf 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -12,6 +12,7 @@ remoteproc-y				+= remoteproc_virtio.o
 remoteproc-y				+= remoteproc_elf_loader.o
 obj-$(CONFIG_REMOTEPROC_CDEV)		+= remoteproc_cdev.o
 obj-$(CONFIG_IMX_REMOTEPROC)		+= imx_rproc.o
+obj-$(CONFIG_IMX_DSP_REMOTEPROC)	+= imx_dsp_rproc.o
 obj-$(CONFIG_INGENIC_VPU_RPROC)		+= ingenic_rproc.o
 obj-$(CONFIG_MTK_SCP)			+= mtk_scp.o mtk_scp_ipi.o
 obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
new file mode 100644
index 000000000000..2be6c734e7d5
--- /dev/null
+++ b/drivers/remoteproc/imx_dsp_rproc.c
@@ -0,0 +1,1078 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2021 NXP
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/workqueue.h>
+#include <linux/firmware/imx/sci.h>
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <linux/arm-smccc.h>
+
+#include "remoteproc_internal.h"
+#include "remoteproc_elf_helpers.h"
+
+enum imx_dsp_rp_mbox_messages {
+	RP_MBOX_SUSPEND_SYSTEM  = 0xFF11,
+	RP_MBOX_SUSPEND_ACK     = 0xFF12,
+	RP_MBOX_RESUME_SYSTEM   = 0xFF13,
+	RP_MBOX_RESUME_ACK      = 0xFF14,
+};
+
+#define DSP_RPROC_CLK_MAX 32
+
+#define REMOTE_IS_READY			BIT(0)
+#define REMOTE_READY_WAIT_MAX_RETRIES	500
+
+/* att flags */
+/* DSP own area. Can be mapped at probe */
+#define ATT_OWN		BIT(31)
+#define ATT_IRAM	BIT(30)
+
+/* i.MX8MP */
+/* DAP registers */
+#define IMX8M_DAP_DEBUG                0x28800000
+#define IMX8M_DAP_DEBUG_SIZE           (64 * 1024)
+#define IMX8M_DAP_PWRCTL               (0x4000 + 0x3020)
+#define IMX8M_PWRCTL_CORERESET         BIT(16)
+
+/* DSP audio mix registers */
+#define IMX8M_AudioDSP_REG0   0x100
+#define IMX8M_AudioDSP_REG1   0x104
+#define IMX8M_AudioDSP_REG2   0x108
+#define IMX8M_AudioDSP_REG3   0x10c
+
+#define IMX8M_AudioDSP_REG2_RUNSTALL  BIT(5)
+#define IMX8M_AudioDSP_REG2_PWAITMODE BIT(1)
+
+/* i.MX8ULP */
+#define IMX8ULP_SIM_LPAV_REG_SYSCTRL0       0x8
+#define IMX8ULP_SYSCTRL0_DSP_DBG_RST        BIT(25)
+#define IMX8ULP_SYSCTRL0_DSP_PLAT_CLK_EN    BIT(19)
+#define IMX8ULP_SYSCTRL0_DSP_PBCLK_EN       BIT(18)
+#define IMX8ULP_SYSCTRL0_DSP_CLK_EN         BIT(17)
+#define IMX8ULP_SYSCTRL0_DSP_RST            BIT(16)
+#define IMX8ULP_SYSCTRL0_DSP_OCD_HALT       BIT(14)
+#define IMX8ULP_SYSCTRL0_DSP_STALL          BIT(13)
+
+#define IMX8ULP_SIP_HIFI_XRDC         0xc200000e
+
+/* address translation table */
+struct imx_dsp_rproc_att {
+	u32 da;	/* device address (From Cortex M4 view)*/
+	u32 sa;	/* system bus address */
+	u32 size; /* size of reg range */
+	int flags;
+};
+
+/* Remote core start/stop method */
+enum imx_dsp_rproc_method {
+	/* Through syscon regmap */
+	IMX_DSP_MMIO,
+	IMX_DSP_SCU_API,
+};
+
+struct imx_dsp_rproc {
+	struct device			*dev;
+	struct regmap			*regmap;
+	struct rproc			*rproc;
+	const struct imx_dsp_rproc_dcfg	*dcfg;
+	struct clk			*clks[DSP_RPROC_CLK_MAX];
+	struct mbox_client		cl;
+	struct mbox_client		cl_rxdb;
+	struct mbox_chan		*tx_ch;
+	struct mbox_chan		*rx_ch;
+	struct mbox_chan		*rxdb_ch;
+	struct device			**pd_dev;
+	struct device_link		**pd_dev_link;
+	struct imx_sc_ipc		*ipc_handle;
+	struct work_struct		rproc_work;
+	struct workqueue_struct		*workqueue;
+	struct completion		pm_comp;
+	spinlock_t			mbox_lock;    /* lock for mbox */
+	int				num_domains;
+	u32				flags;
+};
+
+struct imx_dsp_rproc_dcfg {
+	u32				src_reg;
+	u32				src_mask;
+	u32				src_start;
+	u32				src_stop;
+	const struct imx_dsp_rproc_att	*att;
+	size_t				att_size;
+	enum imx_dsp_rproc_method	method;
+	int (*reset)(struct imx_dsp_rproc *priv);
+};
+
+static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8qm[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x596e8000, 0x556e8000, 0x00008000, ATT_OWN },
+	{ 0x596f0000, 0x556f0000, 0x00008000, ATT_OWN },
+	{ 0x596f8000, 0x556f8000, 0x00000800, ATT_OWN | ATT_IRAM},
+	{ 0x55700000, 0x55700000, 0x00070000, ATT_OWN },
+	/* DDR (Data) */
+	{ 0x80000000, 0x80000000, 0x60000000, 0},
+};
+
+static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8qxp[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x596e8000, 0x596e8000, 0x00008000, ATT_OWN },
+	{ 0x596f0000, 0x596f0000, 0x00008000, ATT_OWN },
+	{ 0x596f8000, 0x596f8000, 0x00000800, ATT_OWN | ATT_IRAM},
+	{ 0x59700000, 0x59700000, 0x00070000, ATT_OWN },
+	/* DDR (Data) */
+	{ 0x80000000, 0x80000000, 0x60000000, 0},
+};
+
+static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8mp[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x3b6e8000, 0x3b6e8000, 0x00008000, ATT_OWN },
+	{ 0x3b6f0000, 0x3b6f0000, 0x00008000, ATT_OWN },
+	{ 0x3b6f8000, 0x3b6f8000, 0x00000800, ATT_OWN | ATT_IRAM},
+	{ 0x3b700000, 0x3b700000, 0x00040000, ATT_OWN },
+	/* DDR (Data) */
+	{ 0x40000000, 0x40000000, 0x80000000, 0},
+};
+
+static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8ulp[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x21170000, 0x21170000, 0x00010000, ATT_OWN | ATT_IRAM},
+	{ 0x21180000, 0x21180000, 0x00010000, ATT_OWN },
+	/* DDR (Data) */
+	{ 0x0c000000, 0x80000000, 0x10000000, 0},
+	{ 0x30000000, 0x90000000, 0x10000000, 0},
+};
+
+static int imx8mp_dsp_reset(struct imx_dsp_rproc *priv)
+{
+	void __iomem *dap = ioremap_wc(IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE);
+	int pwrctl;
+
+	/* put DSP into reset and stall */
+	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
+	pwrctl |= IMX8M_PWRCTL_CORERESET;
+	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
+
+	/* keep reset asserted for 10 cycles */
+	usleep_range(1, 2);
+
+	regmap_update_bits(priv->regmap, IMX8M_AudioDSP_REG2,
+			   IMX8M_AudioDSP_REG2_RUNSTALL,
+			   IMX8M_AudioDSP_REG2_RUNSTALL);
+
+	/* take the DSP out of reset and keep stalled for FW loading */
+	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
+	pwrctl &= ~IMX8M_PWRCTL_CORERESET;
+	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
+
+	iounmap(dap);
+	return 0;
+}
+
+static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv)
+{
+	struct arm_smccc_res res;
+
+	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+			   IMX8ULP_SYSCTRL0_DSP_RST, IMX8ULP_SYSCTRL0_DSP_RST);
+	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+			   IMX8ULP_SYSCTRL0_DSP_STALL,
+			   IMX8ULP_SYSCTRL0_DSP_STALL);
+
+	arm_smccc_smc(IMX8ULP_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+			   IMX8ULP_SYSCTRL0_DSP_RST, 0);
+	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+			   IMX8ULP_SYSCTRL0_DSP_DBG_RST, 0);
+
+	return 0;
+}
+
+static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = {
+	.src_reg	= IMX8M_AudioDSP_REG2,
+	.src_mask	= IMX8M_AudioDSP_REG2_RUNSTALL,
+	.src_start	= 0,
+	.src_stop	= IMX8M_AudioDSP_REG2_RUNSTALL,
+	.att		= imx_dsp_rproc_att_imx8mp,
+	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8mp),
+	.method		= IMX_DSP_MMIO,
+	.reset          = imx8mp_dsp_reset,
+};
+
+static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8ulp = {
+	.src_reg	= IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+	.src_mask	= IMX8ULP_SYSCTRL0_DSP_STALL,
+	.src_start	= 0,
+	.src_stop	= IMX8ULP_SYSCTRL0_DSP_STALL,
+	.att		= imx_dsp_rproc_att_imx8ulp,
+	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8ulp),
+	.method		= IMX_DSP_MMIO,
+	.reset          = imx8ulp_dsp_reset,
+};
+
+static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qxp = {
+	.att		= imx_dsp_rproc_att_imx8qxp,
+	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qxp),
+	.method		= IMX_DSP_SCU_API,
+};
+
+static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qm = {
+	.att		= imx_dsp_rproc_att_imx8qm,
+	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qm),
+	.method		= IMX_DSP_SCU_API,
+};
+
+static int imx_dsp_rproc_ready(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	int i;
+
+	if (!priv->rxdb_ch)
+		return 0;
+
+	for (i = 0; i < REMOTE_READY_WAIT_MAX_RETRIES; i++) {
+		if (priv->flags & REMOTE_IS_READY)
+			return 0;
+		usleep_range(100, 200);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int imx_dsp_rproc_start(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	int ret;
+
+	switch (dcfg->method) {
+	case IMX_DSP_MMIO:
+		ret = regmap_update_bits(priv->regmap,
+					 dcfg->src_reg,
+					 dcfg->src_mask,
+					 dcfg->src_start);
+		break;
+	case IMX_DSP_SCU_API:
+		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
+					  IMX_SC_R_DSP,
+					  true,
+					  rproc->bootaddr);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	if (ret)
+		dev_err(dev, "Failed to enable remote core!\n");
+	else
+		ret = imx_dsp_rproc_ready(rproc);
+
+	return ret;
+}
+
+static int imx_dsp_rproc_stop(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	int ret = 0;
+
+	if (rproc->state == RPROC_CRASHED) {
+		priv->flags &= ~REMOTE_IS_READY;
+		return 0;
+	}
+
+	switch (dcfg->method) {
+	case IMX_DSP_MMIO:
+		ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
+					 dcfg->src_stop);
+		break;
+	case IMX_DSP_SCU_API:
+		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
+					  IMX_SC_R_DSP,
+					  false,
+					  rproc->bootaddr);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	if (ret)
+		dev_err(dev, "Failed to stop remote core\n");
+	else
+		priv->flags &= ~REMOTE_IS_READY;
+
+	return ret;
+}
+
+static int imx_dsp_rproc_sys_to_da(struct imx_dsp_rproc *priv, u64 sys,
+				   size_t len, u64 *da)
+{
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	int i;
+
+	/* parse address translation table */
+	for (i = 0; i < dcfg->att_size; i++) {
+		const struct imx_dsp_rproc_att *att = &dcfg->att[i];
+
+		if (sys >= att->sa && sys + len <= att->sa + att->size) {
+			unsigned int offset = sys - att->sa;
+
+			*da = att->da + offset;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static void imx_dsp_rproc_vq_work(struct work_struct *work)
+{
+	struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
+						  rproc_work);
+
+	rproc_vq_interrupt(priv->rproc, 0);
+	rproc_vq_interrupt(priv->rproc, 1);
+}
+
+static void imx_dsp_rproc_rx_callback(struct mbox_client *cl, void *data)
+{
+	struct rproc *rproc = dev_get_drvdata(cl->dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+	u32 message = (u32)(*(u32 *)data);
+
+	dev_dbg(priv->dev, "mbox msg: 0x%x\n", message);
+
+	switch (message) {
+	case RP_MBOX_SUSPEND_ACK:
+		complete(&priv->pm_comp);
+		break;
+	case RP_MBOX_RESUME_ACK:
+		complete(&priv->pm_comp);
+		break;
+	default:
+		queue_work(priv->workqueue, &priv->rproc_work);
+		break;
+	}
+}
+
+static void imx_dsp_rproc_rxdb_callback(struct mbox_client *cl, void *msg)
+{
+	struct rproc *rproc = dev_get_drvdata(cl->dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->mbox_lock, flags);
+	priv->flags |= REMOTE_IS_READY;
+	spin_unlock_irqrestore(&priv->mbox_lock, flags);
+}
+
+static int imx_dsp_rproc_mbox_init(struct imx_dsp_rproc *priv)
+{
+	struct device *dev = priv->dev;
+	struct mbox_client *cl;
+	int ret;
+
+	if (!of_get_property(dev->of_node, "mbox-names", NULL))
+		return 0;
+
+	spin_lock_init(&priv->mbox_lock);
+
+	cl = &priv->cl;
+	cl->dev = dev;
+	cl->tx_block = true;
+	cl->tx_tout = 100;
+	cl->knows_txdone = false;
+	cl->rx_callback = imx_dsp_rproc_rx_callback;
+
+	priv->tx_ch = mbox_request_channel_byname(cl, "tx");
+	if (IS_ERR(priv->tx_ch)) {
+		ret = PTR_ERR(priv->tx_ch);
+		dev_dbg(cl->dev, "failed to request tx mailbox channel: %d\n",
+			ret);
+		goto err_out;
+	}
+
+	priv->rx_ch = mbox_request_channel_byname(cl, "rx");
+	if (IS_ERR(priv->rx_ch)) {
+		ret = PTR_ERR(priv->rx_ch);
+		dev_dbg(cl->dev, "failed to request rx mailbox channel: %d\n",
+			ret);
+		goto err_out;
+	}
+
+	cl = &priv->cl_rxdb;
+	cl->dev = dev;
+	cl->rx_callback = imx_dsp_rproc_rxdb_callback;
+
+	/*
+	 * RX door bell is used to receive the ready signal from remote
+	 * after the partition reset of A core.
+	 */
+	priv->rxdb_ch = mbox_request_channel_byname(cl, "rxdb");
+	if (IS_ERR(priv->rxdb_ch)) {
+		ret = PTR_ERR(priv->rxdb_ch);
+		dev_dbg(cl->dev, "failed to request mbox chan rxdb, ret %d\n",
+			ret);
+		goto err_out;
+	}
+
+	return 0;
+
+err_out:
+	if (!IS_ERR(priv->tx_ch))
+		mbox_free_channel(priv->tx_ch);
+	if (!IS_ERR(priv->rx_ch))
+		mbox_free_channel(priv->rx_ch);
+	if (!IS_ERR(priv->rxdb_ch))
+		mbox_free_channel(priv->rxdb_ch);
+
+	return ret;
+}
+
+static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv)
+{
+	mbox_free_channel(priv->tx_ch);
+	mbox_free_channel(priv->rx_ch);
+	mbox_free_channel(priv->rxdb_ch);
+}
+
+static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
+{
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	struct rproc *rproc = priv->rproc;
+	struct device *dev = priv->dev;
+	struct device_node *np = dev->of_node;
+	struct of_phandle_iterator it;
+	struct rproc_mem_entry *mem;
+	struct reserved_mem *rmem;
+	void __iomem *cpu_addr;
+	int a;
+	u64 da;
+
+	/* remap required addresses */
+	for (a = 0; a < dcfg->att_size; a++) {
+		const struct imx_dsp_rproc_att *att = &dcfg->att[a];
+
+		if (!(att->flags & ATT_OWN))
+			continue;
+
+		if (imx_dsp_rproc_sys_to_da(priv, att->sa, att->size, &da))
+			return -EINVAL;
+
+		cpu_addr = devm_ioremap_wc(dev, att->sa, att->size);
+
+		/* Register memory region */
+		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)att->sa,
+					   att->size, da,
+					   NULL,
+					   NULL,
+					   "dsp_mem");
+
+		if (mem)
+			rproc_coredump_add_segment(rproc, da, att->size);
+		else
+			return -ENOMEM;
+
+		rproc_add_carveout(rproc, mem);
+	}
+
+	of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
+	while (of_phandle_iterator_next(&it) == 0) {
+		/*
+		 * Ignore the first memory region which will be used vdev buffer.
+		 * No need to do extra handlings, rproc_add_virtio_dev will handle it.
+		 */
+		if (!strcmp(it.node->name, "vdev0buffer"))
+			continue;
+
+		rmem = of_reserved_mem_lookup(it.node);
+		if (!rmem) {
+			dev_err(dev, "unable to acquire memory-region\n");
+			return -EINVAL;
+		}
+
+		if (imx_dsp_rproc_sys_to_da(priv, rmem->base, rmem->size, &da))
+			return -EINVAL;
+
+		cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
+
+		/* Register memory region */
+		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)rmem->base,
+					   rmem->size, da,
+					   NULL,
+					   NULL,
+					   it.node->name);
+
+		if (mem)
+			rproc_coredump_add_segment(rproc, da, rmem->size);
+		else
+			return -ENOMEM;
+
+		rproc_add_carveout(rproc, mem);
+	}
+
+	return 0;
+}
+
+/*
+ * imx_dsp_rproc_elf_load_segments() specially check if memsz is zero
+ * or not.
+ */
+static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc,
+					   const struct firmware *fw)
+{
+	struct device *dev = &rproc->dev;
+	u8 class = fw_elf_get_class(fw);
+	u32 elf_phdr_get_size = elf_size_of_phdr(class);
+	const u8 *elf_data = fw->data;
+	const void *ehdr, *phdr;
+	int i, ret = 0;
+	u16 phnum;
+
+	ehdr = elf_data;
+	phnum = elf_hdr_get_e_phnum(class, ehdr);
+	phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr);
+
+	/* go through the available ELF segments */
+	for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) {
+		u64 da = elf_phdr_get_p_paddr(class, phdr);
+		u64 memsz = elf_phdr_get_p_memsz(class, phdr);
+		u64 filesz = elf_phdr_get_p_filesz(class, phdr);
+		u64 offset = elf_phdr_get_p_offset(class, phdr);
+		u32 type = elf_phdr_get_p_type(class, phdr);
+		void *ptr;
+		bool is_iomem;
+
+		if (type != PT_LOAD || !memsz)
+			continue;
+
+		dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
+			type, da, memsz, filesz);
+
+		if (filesz > memsz) {
+			dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n",
+				filesz, memsz);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (offset + filesz > fw->size) {
+			dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n",
+				offset + filesz, fw->size);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!rproc_u64_fit_in_size_t(memsz)) {
+			dev_err(dev, "size (%llx) does not fit in size_t type\n",
+				memsz);
+			ret = -EOVERFLOW;
+			break;
+		}
+
+		/* grab the kernel address for this device address */
+		ptr = rproc_da_to_va(rproc, da, memsz, &is_iomem);
+		if (!ptr) {
+			dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da,
+				memsz);
+			ret = -EINVAL;
+			break;
+		}
+
+		/* put the segment where the remote processor expects it */
+		if (filesz)
+			memcpy(ptr, elf_data + offset, filesz);
+
+		/*
+		 * Zero out remaining memory for this segment.
+		 *
+		 * This isn't strictly required since dma_alloc_coherent already
+		 * did this for us. albeit harmless, we may consider removing
+		 * this.
+		 */
+		if (memsz > filesz)
+			memset(ptr + filesz, 0, memsz - filesz);
+	}
+
+	return ret;
+}
+
+static int imx_dsp_rproc_prepare(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	struct device *dev = priv->dev;
+	struct rproc_mem_entry *carveout;
+	int ret;
+
+	ret = imx_dsp_rproc_add_carveout(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_add_carveout\n");
+		return ret;
+	}
+
+	pm_runtime_get_sync(dev);
+
+	/* clear buffers */
+	list_for_each_entry(carveout, &rproc->carveouts, node) {
+		if (carveout->va)
+			memset(carveout->va, 0, carveout->len);
+	}
+
+	return  0;
+}
+
+static int imx_dsp_rproc_unprepare(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+
+	pm_runtime_put_sync(priv->dev);
+
+	return  0;
+}
+
+static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	int err;
+	__u32 mmsg;
+
+	if (!priv->tx_ch) {
+		dev_err(priv->dev, "No initialized mbox tx channel\n");
+		return;
+	}
+
+	/*
+	 * Send the index of the triggered virtqueue as the mu payload.
+	 * Let remote processor know which virtqueue is used.
+	 */
+	mmsg = vqid;
+
+	err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
+	if (err < 0)
+		dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
+			__func__, vqid, err);
+}
+
+static const struct rproc_ops imx_dsp_rproc_ops = {
+	.prepare	= imx_dsp_rproc_prepare,
+	.unprepare	= imx_dsp_rproc_unprepare,
+	.start		= imx_dsp_rproc_start,
+	.stop		= imx_dsp_rproc_stop,
+	.kick		= imx_dsp_rproc_kick,
+	.load		= imx_dsp_rproc_elf_load_segments,
+	.parse_fw	= rproc_elf_load_rsc_table,
+	.sanity_check	= rproc_elf_sanity_check,
+	.get_boot_addr	= rproc_elf_get_boot_addr,
+};
+
+static int imx_dsp_attach_pm_domains(struct imx_dsp_rproc *priv)
+{
+	struct device *dev = priv->dev;
+	int ret, i;
+
+	priv->num_domains = of_count_phandle_with_args(dev->of_node,
+						       "power-domains",
+						       "#power-domain-cells");
+	if (priv->num_domains <= 1)
+		return 0;
+
+	priv->pd_dev = devm_kmalloc_array(dev, priv->num_domains,
+					  sizeof(*priv->pd_dev),
+					  GFP_KERNEL);
+	if (!priv->pd_dev)
+		return -ENOMEM;
+
+	priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_domains,
+					       sizeof(*priv->pd_dev_link),
+					       GFP_KERNEL);
+	if (!priv->pd_dev_link)
+		return -ENOMEM;
+
+	for (i = 0; i < priv->num_domains; i++) {
+		priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
+		if (IS_ERR(priv->pd_dev[i]))
+			return PTR_ERR(priv->pd_dev[i]);
+
+		priv->pd_dev_link[i] = device_link_add(dev,
+						       priv->pd_dev[i],
+						       DL_FLAG_STATELESS |
+						       DL_FLAG_PM_RUNTIME |
+						       DL_FLAG_RPM_ACTIVE);
+		if (IS_ERR(priv->pd_dev_link[i])) {
+			dev_pm_domain_detach(priv->pd_dev[i], false);
+			ret = PTR_ERR(priv->pd_dev_link[i]);
+			goto detach_pm;
+		}
+	}
+
+	return 0;
+
+detach_pm:
+	while (--i >= 0) {
+		device_link_del(priv->pd_dev_link[i]);
+		dev_pm_domain_detach(priv->pd_dev[i], false);
+	}
+
+	return ret;
+}
+
+static int imx_dsp_detach_pm_domains(struct imx_dsp_rproc *priv)
+{
+	int i;
+
+	if (priv->num_domains <= 1)
+		return 0;
+
+	for (i = 0; i < priv->num_domains; i++) {
+		device_link_del(priv->pd_dev_link[i]);
+		dev_pm_domain_detach(priv->pd_dev[i], false);
+	}
+
+	return 0;
+}
+
+static int imx_dsp_rproc_detect_mode(struct imx_dsp_rproc *priv)
+{
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	struct regmap *regmap;
+	int ret = 0;
+
+	switch (dcfg->method) {
+	case IMX_DSP_SCU_API:
+		ret = imx_scu_get_handle(&priv->ipc_handle);
+		if (ret)
+			return ret;
+		return 0;
+	case IMX_DSP_MMIO:
+		regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
+		if (IS_ERR(regmap)) {
+			dev_err(dev, "failed to find syscon\n");
+			return PTR_ERR(regmap);
+		}
+
+		priv->regmap = regmap;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static const char *imx_dsp_clks_names[DSP_RPROC_CLK_MAX] = {
+	/* DSP clocks */
+	"dsp_clk1", "dsp_clk2", "dsp_clk3", "dsp_clk4", "dsp_clk5", "dsp_clk6",
+	"dsp_clk7", "dsp_clk8",
+
+	/* Peripheral clocks */
+	"per_clk1", "per_clk2", "per_clk3", "per_clk4", "per_clk5", "per_clk6",
+	"per_clk7", "per_clk8", "per_clk9", "per_clk10", "per_clk11", "per_clk12",
+	"per_clk13", "per_clk14", "per_clk15", "per_clk16", "per_clk17", "per_clk18",
+};
+
+static int imx_dsp_rproc_clk_get(struct imx_dsp_rproc *priv)
+{
+	int i;
+
+	for (i = 0; i < DSP_RPROC_CLK_MAX; i++) {
+		priv->clks[i] = devm_clk_get_optional(priv->dev,
+						      imx_dsp_clks_names[i]);
+		if (IS_ERR(priv->clks[i])) {
+			dev_err(priv->dev, "Failed to get clock %s\n",
+				imx_dsp_clks_names[i]);
+			return PTR_ERR(priv->clks[i]);
+		}
+	}
+
+	return 0;
+}
+
+static int imx_dsp_rproc_clk_enable(struct imx_dsp_rproc *priv)
+{
+	int i, ret;
+
+	for (i = 0; i < DSP_RPROC_CLK_MAX; i++) {
+		ret = clk_prepare_enable(priv->clks[i]);
+		if (ret < 0) {
+			dev_err(priv->dev, "Failed to enable clk %s\n",
+				imx_dsp_clks_names[i]);
+			goto err_dsp_clks;
+		}
+	}
+
+	return 0;
+
+err_dsp_clks:
+	while (--i >= 0)
+		clk_disable_unprepare(priv->clks[i]);
+
+	return ret;
+}
+
+static void imx_dsp_rproc_clk_disable(struct imx_dsp_rproc *priv)
+{
+	int i;
+
+	for (i = 0; i < DSP_RPROC_CLK_MAX; i++)
+		clk_disable_unprepare(priv->clks[i]);
+}
+
+static int imx_dsp_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct imx_dsp_rproc_dcfg *dcfg;
+	struct imx_dsp_rproc *priv;
+	struct rproc *rproc;
+	const char *fw_name;
+	int ret;
+
+	dcfg = of_device_get_match_data(dev);
+	if (!dcfg)
+		return -ENODEV;
+
+	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
+	if (ret) {
+		dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
+			ret);
+		return ret;
+	}
+
+	rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
+			    sizeof(*priv));
+	if (!rproc)
+		return -ENOMEM;
+
+	priv = rproc->priv;
+	priv->rproc = rproc;
+	priv->dcfg = dcfg;
+	priv->dev = dev;
+
+	dev_set_drvdata(dev, rproc);
+
+	priv->workqueue = create_workqueue(dev_name(dev));
+	if (!priv->workqueue) {
+		dev_err(dev, "cannot create workqueue\n");
+		ret = -ENOMEM;
+		goto err_wkq;
+	}
+
+	INIT_WORK(&priv->rproc_work, imx_dsp_rproc_vq_work);
+
+	ret = imx_dsp_rproc_detect_mode(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
+		goto err_detect;
+	}
+
+	ret = imx_dsp_attach_pm_domains(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
+		goto err_pm;
+	}
+
+	ret = imx_dsp_rproc_clk_get(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_clk_get\n");
+		goto err_clk_get;
+	}
+
+	init_completion(&priv->pm_comp);
+	rproc->auto_boot = false;
+	ret = rproc_add(rproc);
+	if (ret) {
+		dev_err(dev, "rproc_add failed\n");
+		goto err_rproc_add;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+
+err_rproc_add:
+err_clk_get:
+	imx_dsp_detach_pm_domains(priv);
+err_pm:
+err_detect:
+	destroy_workqueue(priv->workqueue);
+err_wkq:
+	rproc_free(rproc);
+
+	return ret;
+}
+
+static int imx_dsp_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+
+	pm_runtime_disable(&pdev->dev);
+	rproc_del(rproc);
+	imx_dsp_detach_pm_domains(priv);
+	destroy_workqueue(priv->workqueue);
+	rproc_free(rproc);
+
+	return 0;
+}
+
+/* pm runtime */
+static int imx_dsp_runtime_resume(struct device *dev)
+{
+	struct rproc *rproc = dev_get_drvdata(dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	int ret;
+
+	ret = imx_dsp_rproc_mbox_init(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_mbox_init\n");
+		return ret;
+	}
+
+	ret = imx_dsp_rproc_clk_enable(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_clk_enable\n");
+		return ret;
+	}
+
+	/* reset DSP if needed */
+	if (dcfg->reset)
+		dcfg->reset(priv);
+
+	return 0;
+}
+
+static int imx_dsp_runtime_suspend(struct device *dev)
+{
+	struct rproc *rproc = dev_get_drvdata(dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+
+	imx_dsp_rproc_clk_disable(priv);
+
+	imx_dsp_rproc_free_mbox(priv);
+
+	return 0;
+}
+
+static void imx_dsp_load_firmware(const struct firmware *fw, void *context)
+{
+	struct rproc *rproc = context;
+	int ret;
+
+	/* load the ELF segments to memory */
+	ret = rproc_load_segments(rproc, fw);
+	if (ret)
+		goto out;
+
+	/* power up the remote processor */
+	ret = rproc->ops->start(rproc);
+	if (ret)
+		goto out;
+
+	/* same flow as first start */
+	rproc->ops->kick(rproc, 0);
+
+out:
+	release_firmware(fw);
+}
+
+static int imx_dsp_suspend(struct device *dev)
+{
+	struct rproc *rproc = dev_get_drvdata(dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+	__u32 mmsg = RP_MBOX_SUSPEND_SYSTEM;
+	int ret;
+
+	if (rproc->state == RPROC_RUNNING) {
+		reinit_completion(&priv->pm_comp);
+
+		ret = mbox_send_message(priv->tx_ch, (void *)&mmsg);
+		if (ret < 0) {
+			dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
+			return ret;
+		}
+
+		if (!wait_for_completion_timeout(&priv->pm_comp, msecs_to_jiffies(100)))
+			return -EBUSY;
+	}
+
+	return pm_runtime_force_suspend(dev);
+}
+
+static int imx_dsp_resume(struct device *dev)
+{
+	struct rproc *rproc = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret)
+		return ret;
+
+	if (rproc->state == RPROC_RUNNING) {
+		/*TODO: load firmware and start */
+		ret = request_firmware_nowait(THIS_MODULE,
+					      FW_ACTION_UEVENT,
+					      rproc->firmware,
+					      dev,
+					      GFP_KERNEL,
+					      rproc,
+					      imx_dsp_load_firmware);
+		if (ret < 0) {
+			dev_err(dev, "load firmware failed: %d\n", ret);
+			goto err;
+		}
+	}
+
+	return 0;
+
+err:
+	pm_runtime_force_suspend(dev);
+
+	return ret;
+}
+
+static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
+	SET_RUNTIME_PM_OPS(imx_dsp_runtime_suspend,
+			   imx_dsp_runtime_resume, NULL)
+};
+
+static const struct of_device_id imx_dsp_rproc_of_match[] = {
+	{ .compatible = "fsl,imx8qxp-hifi4", .data = &imx_dsp_rproc_cfg_imx8qxp },
+	{ .compatible = "fsl,imx8qm-hifi4",  .data = &imx_dsp_rproc_cfg_imx8qm },
+	{ .compatible = "fsl,imx8mp-hifi4",  .data = &imx_dsp_rproc_cfg_imx8mp },
+	{ .compatible = "fsl,imx8ulp-hifi4", .data = &imx_dsp_rproc_cfg_imx8ulp },
+	{},
+};
+MODULE_DEVICE_TABLE(of, imx_dsp_rproc_of_match);
+
+static struct platform_driver imx_dsp_rproc_driver = {
+	.probe = imx_dsp_rproc_probe,
+	.remove = imx_dsp_rproc_remove,
+	.driver = {
+		.name = "imx-dsp-rproc",
+		.of_match_table = imx_dsp_rproc_of_match,
+		.pm = &imx_dsp_rproc_pm_ops,
+	},
+};
+module_platform_driver(imx_dsp_rproc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("i.MX HiFi Core Remote Processor Control Driver");
+MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang at nxp.com>");
-- 
2.17.1



From ck.hu at mediatek.com  Fri Aug 20 03:25:22 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 20 Aug 2021 18:25:22 +0800
Subject: [PATCH v3 12/15] drm/mediatek: add display MDP RDMA support for
 MT8195
In-Reply-To: <20210818091847.8060-13-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-13-nancy.lin@mediatek.com>
Message-ID: <1629455122.11260.2.camel@mtksdaap41>


Hi, Nancy:

On Wed, 2021-08-18 at 17:18 +0800, Nancy.Lin wrote:
> Add MDP_RDMA driver for MT8195. MDP_RDMA is the DMA engine of
> the ovl_adaptor component.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---

[snip]

> +
> +#define MDP_RDMA_EN                                            0x000
> +#define FLD_ROT_ENABLE                            REG_FLD(1, 0)

I would like the bitwise definition has one more indent than the byte
definition.

> +
> +#define MDP_RDMA_RESET                                         0x008
> +
> +#define MDP_RDMA_CON                                           0x020
> +#define FLD_OUTPUT_10B                            REG_FLD(1, 5)
> +#define FLD_SIMPLE_MODE                           REG_FLD(1, 4)
> +
> +#define MDP_RDMA_GMCIF_CON                                     0x028
> +#define FLD_EXT_ULTRA_EN                          REG_FLD(1, 18)
> +#define FLD_PRE_ULTRA_EN                          REG_FLD(2, 16)
> +#define FLD_ULTRA_EN                              REG_FLD(2, 12)
> +#define FLD_RD_REQ_TYPE                           REG_FLD(4, 4)
> +#define VAL_RD_REQ_TYPE_BURST_8_ACCESS       7
> +#define FLD_EXT_PREULTRA_EN                       REG_FLD(1, 3)
> +#define FLD_COMMAND_DIV                           REG_FLD(1, 0)
> +
> +#define MDP_RDMA_SRC_CON                                       0x030
> +#define FLD_OUTPUT_ARGB                           REG_FLD(1, 25)
> +#define FLD_BIT_NUMBER                            REG_FLD(2, 18)
> +#define FLD_UNIFORM_CONFIG                        REG_FLD(1, 17)
> +#define FLD_SWAP                                  REG_FLD(1, 14)
> +#define FLD_SRC_FORMAT                            REG_FLD(4, 0)
> +
> +#define MDP_RDMA_COMP_CON                                      0x038
> +#define FLD_AFBC_EN                               REG_FLD(1, 22)
> +#define FLD_AFBC_YUV_TRANSFORM                    REG_FLD(1, 21)
> +#define FLD_UFBDC_EN                              REG_FLD(1, 12)
> +
> +#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE                          0x060
> +#define FLD_MF_BKGD_WB                            REG_FLD(23, 0)
> +
> +#define MDP_RDMA_MF_BKGD_SIZE_IN_PIXEL                         0x068
> +#define FLD_MF_BKGD_WP                            REG_FLD(23, 0)
> +
> +#define MDP_RDMA_MF_SRC_SIZE                                   0x070
> +#define FLD_MF_SRC_H                              REG_FLD(15, 16)
> +#define FLD_MF_SRC_W                              REG_FLD(15, 0)
> +
> +#define MDP_RDMA_MF_CLIP_SIZE                                  0x078
> +#define FLD_MF_CLIP_H                             REG_FLD(15, 16)
> +#define FLD_MF_CLIP_W                             REG_FLD(15, 0)
> +
> +#define MDP_RDMA_TARGET_LINE                                   0x0a0
> +#define FLD_LINE_THRESHOLD                        REG_FLD(15, 17)
> +#define FLD_TARGET_LINE_EN                        REG_FLD(1, 16)
> +
> +#define MDP_RDMA_SRC_OFFSET_0                                  0x118
> +#define FLD_SRC_OFFSET_0                          REG_FLD(32, 0)
> +
> +#define MDP_RDMA_TRANSFORM_0                                   0x200
> +#define FLD_INT_MATRIX_SEL                        REG_FLD(5, 23)
> +#define FLD_TRANS_EN                              REG_FLD(1, 16)
> +
> +#define MDP_RDMA_UTRA_H_CON_0                                  0x248
> +#define FLD_PREUTRA_H_OFS_0                       REG_FLD(10, 10)
> +
> +#define MDP_RDMA_UTRA_L_CON_0                                  0x250
> +#define FLD_PREUTRA_L_OFS_0                       REG_FLD(10, 10)
> +
> +#define MDP_RDMA_SRC_BASE_0                                    0xf00
> +#define FLD_SRC_BASE_0                            REG_FLD(32, 0)
> +
> +#define RDMA_INPUT_SWAP		BIT(14)
> +#define RDMA_INPUT_10BIT	BIT(18)
> +

[snip]

> +
> +static void mtk_mdp_rdma_fifo_config(void __iomem *base, struct cmdq_pkt *cmdq_pkt,
> +				     struct cmdq_client_reg *cmdq_base)
> +{
> +	unsigned int pre_ultra_h = 156;
> +	unsigned int pre_ultra_l = 104;

Give the reason why this value. You could refer to merge [1].

[1]
https://patchwork.kernel.org/project/linux-mediatek/patch/20210819022327.13040-13-jason-jh.lin at mediatek.com/

> +	unsigned int reg_mask;
> +	unsigned int reg_val;
> +	unsigned int reg;
> +
> +	reg = MDP_RDMA_GMCIF_CON;
> +	reg_val = REG_FLD_VAL(FLD_RD_REQ_TYPE, VAL_RD_REQ_TYPE_BURST_8_ACCESS) |
> +		  REG_FLD_VAL(FLD_COMMAND_DIV, 1) |
> +		  REG_FLD_VAL(FLD_EXT_PREULTRA_EN, 1) |
> +		  REG_FLD_VAL(FLD_ULTRA_EN, 0) |
> +		  REG_FLD_VAL(FLD_PRE_ULTRA_EN, 1) |
> +		  REG_FLD_VAL(FLD_EXT_ULTRA_EN, 1);
> +	reg_mask = REG_FLD_MASK(FLD_RD_REQ_TYPE) |
> +		   REG_FLD_MASK(FLD_COMMAND_DIV) |
> +		   REG_FLD_MASK(FLD_EXT_PREULTRA_EN) |
> +		   REG_FLD_MASK(FLD_ULTRA_EN) |
> +		   REG_FLD_MASK(FLD_PRE_ULTRA_EN) |
> +		   REG_FLD_MASK(FLD_EXT_ULTRA_EN);
> +	mtk_ddp_write_mask(cmdq_pkt, reg_val, cmdq_base, base, reg, reg_mask);

#define FLD_COMMAND_DIV         BIT(0)
#define FLD_EXT_PREULTRA_EN     BIT(3)
#define FLD_RD_REQ_TYPE         GENMASK(7, 4)
#define FLD_ULTRA_EN            GENMASK(13, 12)
#define FLD_PRE_ULTRA_EN        GENMASK(17, 16)
#define FLD_PRE_ULTRA_EN_ENABLE     1
#define FLD_EXT_ULTRA_EN        BIT(18)

mtk_ddp_write_mask(cmdq_pkt, FLD_EXT_ULTRA_EN | FLD_PRE_ULTRA_EN_ENABLE
<< 16 | VAL_RD_REQ_TYPE_BURST_8_ACCESS << 4 | FLD_EXT_PREULTRA_EN |
FLD_COMMAND_DIV, cmdq_base, base, MDP_RDMA_GMCIF_CON, FLD_EXT_ULTRA_EN |
FLD_PRE_ULTRA_EN | FLD_ULTRA_EN | FLD_RD_REQ_TYPE | FLD_EXT_PREULTRA_EN
| FLD_COMMAND_DIV);

> +
> +	reg = MDP_RDMA_UTRA_H_CON_0;
> +	reg_val = REG_FLD_VAL(FLD_PREUTRA_H_OFS_0, pre_ultra_h);
> +	reg_mask = REG_FLD_MASK(FLD_PREUTRA_H_OFS_0);
> +	mtk_ddp_write_mask(cmdq_pkt, reg_val, cmdq_base, base, reg, reg_mask);
> +
> +	reg = MDP_RDMA_UTRA_L_CON_0;
> +	reg_val = REG_FLD_VAL(FLD_PREUTRA_L_OFS_0, pre_ultra_l);
> +	reg_mask = REG_FLD_MASK(FLD_PREUTRA_L_OFS_0);
> +	mtk_ddp_write_mask(cmdq_pkt, reg_val, cmdq_base, base, reg, reg_mask);
> +}
> +

[snip]

> diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
> new file mode 100644
> index 000000000000..50fa6e18d244
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
> @@ -0,0 +1,39 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + */
> +
> +#ifndef __MTK_MDP_RDMA_H__
> +#define __MTK_MDP_RDMA_H__
> +
> +enum mtk_mdp_rdma_profile {
> +	RDMA_CSC_RGB_TO_JPEG = 0,
> +	RDMA_CSC_RGB_TO_FULL709 = 1,
> +	RDMA_CSC_RGB_TO_BT601 = 2,
> +	RDMA_CSC_RGB_TO_BT709 = 3,
> +	RDMA_CSC_JPEG_TO_RGB = 4,
> +	RDMA_CSC_FULL709_TO_RGB = 5,
> +	RDMA_CSC_BT601_TO_RGB = 6,
> +	RDMA_CSC_BT709_TO_RGB = 7,
> +	RDMA_CSC_JPEG_TO_BT601 = 8,
> +	RDMA_CSC_JPEG_TO_BT709 = 9,
> +	RDMA_CSC_BT601_TO_JPEG = 10,
> +	RDMA_CSC_BT709_TO_BT601 = 11,
> +	RDMA_CSC_BT601_TO_BT709 = 12
> +};
> +
> +struct mtk_mdp_rdma_cfg {
> +	enum mtk_mdp_rdma_profile profile;
> +	unsigned int source_width;

source_width is useless, so remove.

Regards,
CK.

> +	unsigned int pitch;
> +	unsigned int addr0;
> +	unsigned int width;
> +	unsigned int height;
> +	unsigned int x_left;
> +	unsigned int y_top;
> +	bool csc_enable;
> +	int fmt;
> +};
> +
> +#endif // __MTK_MDP_RDMA_H__
> +



From Jisheng.Zhang at synaptics.com  Fri Aug 20 03:27:08 2021
From: Jisheng.Zhang at synaptics.com (Jisheng Zhang)
Date: Fri, 20 Aug 2021 18:27:08 +0800
Subject: [PATCH] arm64: dts: synaptics: add DT for AS370-RDK
In-Reply-To: <29e96ece-8541-a7a2-c6a9-453be6644eed@canonical.com>
References: <20210820173108.01d5c6de@xhacker.debian>
 <29e96ece-8541-a7a2-c6a9-453be6644eed@canonical.com>
Message-ID: <20210820182708.51d13e29@xhacker.debian>

On Fri, 20 Aug 2021 11:59:30 +0200
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:

> CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On 20/08/2021 11:31, Jisheng Zhang wrote:
> > Add a basic support for AS370-RDK board based on the AS370 SoC. We can
> > get a basic shell on the uart console now.
> >
> > Signed-off-by: Jisheng Zhang <Jisheng.Zhang at synaptics.com>
> > ---
> > Hi Arnd,
> >
> > If it's too late, I will add it in a PR for 5.16 in next development window.
> >
> > Thanks
> >
> >  arch/arm64/boot/dts/synaptics/Makefile      |  1 +
> >  arch/arm64/boot/dts/synaptics/as370-rdk.dts | 29 +++++++++++++++++++++
> >  2 files changed, 30 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/synaptics/as370-rdk.dts
> >
> > diff --git a/arch/arm64/boot/dts/synaptics/Makefile b/arch/arm64/boot/dts/synaptics/Makefile
> > index de71ddda6835..c1c4f6c040b3 100644
> > --- a/arch/arm64/boot/dts/synaptics/Makefile
> > +++ b/arch/arm64/boot/dts/synaptics/Makefile
> > @@ -1,4 +1,5 @@
> >  # SPDX-License-Identifier: GPL-2.0
> >  # Berlin SoC Family
> > +dtb-$(CONFIG_ARCH_BERLIN) += as370-rdk.dtb
> >  dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-dmp.dtb
> >  dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-stb.dtb
> > diff --git a/arch/arm64/boot/dts/synaptics/as370-rdk.dts b/arch/arm64/boot/dts/synaptics/as370-rdk.dts
> > new file mode 100644
> > index 000000000000..6f5c37c98be6
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/synaptics/as370-rdk.dts
> > @@ -0,0 +1,29 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +/*
> > + * Copyright (C) 2018-2021 Synaptics Incorporated
> > + *
> > + * Author: Jisheng Zhang <jszhang at kernel.org>
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "as370.dtsi"
> > +
> > +/ {
> > +     model = "Synaptics AS370 RDK";
> > +     compatible = "syna,as370-rdk", "syna,as370";  
> 
> There is no such binding. You need to update the bindings file (first
> patch in the series).

This is my plan ;) In fact, "berlin4ct" related binding is also missing.
I want to convert Documentation/devicetree/bindings/arm/syna.txt
to yaml, then add missing bindings. But it's too late for 5.15,

If it's fine to keep as370.dtsi without board user(s), we can drop
this patch. I will solve this issue in next development window.

Thanks

> 
> 
> Best regards,
> Krzysztof



From maz at kernel.org  Fri Aug 20 03:34:20 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 11:34:20 +0100
Subject: [PATCH v4 00/15] KVM: arm64: Fixed features for protected VMs
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>
References: <20210817081134.2918285-1-tabba@google.com>
Message-ID: <162945557041.2025988.6137048861111259637.b4-ty@kernel.org>

On Tue, 17 Aug 2021 09:11:19 +0100, Fuad Tabba wrote:
> Changes since v3 [1]:
> - Redid calculating restricted values of feature register fields, ensuring that
>   the code distinguishes between unsigned and (potentially in the future)
>   signed fields (Will)
> - Refactoring and fixes (Drew, Will)
> - More documentation and comments (Oliver, Will)
> - Dropped patch "Restrict protected VM capabilities", since it should come with
>   or after the user ABI series for pKVM (Will)
> - Carried Will's acks
> 
> [...]

I've taken the first 10 patches of this series in order to
progress it. I also stashed a fixlet on top to address the
tracepoint issue.

Hopefully we can resolve the rest of the issues quickly.

[01/15] KVM: arm64: placeholder to check if VM is protected
        commit: 2ea7f655800b00b109951f22539fe2025add210b
[02/15] KVM: arm64: Remove trailing whitespace in comment
        commit: e6bc555c96990046d680ff92c8e2e7b6b43b509f
[03/15] KVM: arm64: MDCR_EL2 is a 64-bit register
        commit: d6c850dd6ce9ce4b410142a600d8c34dc041d860
[04/15] KVM: arm64: Fix names of config register fields
        commit: dabb1667d8573302712a75530cccfee8f3ffff84
[05/15] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse
        commit: f76f89e2f73d93720cfcad7fb7b24d022b2846bf
[06/15] KVM: arm64: Restore mdcr_el2 from vcpu
        commit: 1460b4b25fde52cbee746c11a4b1d3185f2e2847
[07/15] KVM: arm64: Keep mdcr_el2's value as set by __init_el2_debug
        commit: 12849badc6d2456f15f8f2c93037628d5176810b
[08/15] KVM: arm64: Track value of cptr_el2 in struct kvm_vcpu_arch
        commit: cd496228fd8de2e82b6636d3d89105631ea2b69c
[09/15] KVM: arm64: Add feature register flag definitions
        commit: 95b54c3e4c92b9185b15c83e8baab9ba312195f6
[10/15] KVM: arm64: Add config register bit definitions
        commit: 2d701243b9f231b5d7f9a8cb81870650d3eb32bc

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From will at kernel.org  Fri Aug 20 03:41:11 2021
From: will at kernel.org (Will Deacon)
Date: Fri, 20 Aug 2021 11:41:11 +0100
Subject: [PATCH -next] iommu/arm-smmu: Fix missing unlock on error in
 arm_smmu_device_group()
In-Reply-To: <20210820074949.1946576-1-yangyingliang@huawei.com>
References: <20210820074949.1946576-1-yangyingliang@huawei.com>
Message-ID: <20210820104111.GC17267@willie-the-truck>

On Fri, Aug 20, 2021 at 03:49:49PM +0800, Yang Yingliang wrote:
> Add the missing unlock before return from function arm_smmu_device_group()
> in the error handling case.
> 
> Fixes: b1a1347912a7 ("iommu/arm-smmu: Fix race condition during iommu_group creation")
> Reported-by: Hulk Robot <hulkci at huawei.com>
> Signed-off-by: Yang Yingliang <yangyingliang at huawei.com>
> ---
>  drivers/iommu/arm/arm-smmu/arm-smmu.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> index 73893180ec7e..4bc75c4ce402 100644
> --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
> +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
> @@ -1478,8 +1478,10 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev)
>  	mutex_lock(&smmu->stream_map_mutex);
>  	for_each_cfg_sme(cfg, fwspec, i, idx) {
>  		if (group && smmu->s2crs[idx].group &&
> -		    group != smmu->s2crs[idx].group)
> +		    group != smmu->s2crs[idx].group) {
> +			mutex_unlock(&smmu->stream_map_mutex);
>  			return ERR_PTR(-EINVAL);
> +		}

Urgh, I should really have spotted that in review. Thanks:

Acked-by: Will Deacon <will at kernel.org>

Joerg -- please can you throw this on top?

Will


From broonie at kernel.org  Fri Aug 20 03:55:31 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Aug 2021 11:55:31 +0100
Subject: [PATCH] kselftest/arm64: pac: Fix skipping of tests on systems
 without PAC
In-Reply-To: <a988b3e2-5f88-fbd5-99da-2066a65a17b2@arm.com>
References: <20210819165723.43903-1-broonie@kernel.org>
 <a988b3e2-5f88-fbd5-99da-2066a65a17b2@arm.com>
Message-ID: <20210820105531.GP4177@sirena.org.uk>

On Fri, Aug 20, 2021 at 12:39:39PM +0530, Amit Kachhap wrote:
> On 8/19/21 10:27 PM, Mark Brown wrote:

> > -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \
> > +	if (!(hwcaps & HWCAP_PACA))					\
> > +		SKIP(return, "PAUTH not enabled"); \
> >   } while (0)
> >   #define ASSERT_GENERIC_PAUTH_ENABLED() \

> May be ASSERT_GENERIC_PAUTH_ENABLED can be replaced with
> something like VERIFY_GENERIC_PAUTH_ENABLED

I thought briefly about bikeshedding the name but didn't come up with
anything that was sufficiently better/clearer.

> or can be modified like below and instead of failing it skips with a
> message

>   -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \
>   +	ASSERT_NE(0, hwcaps & HWCAP_PACA) SKIP(return, "PAUTH not enabled");

That's what the patch does?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210820/157054ed/attachment.sig>

From anshuman.khandual at arm.com  Fri Aug 20 04:05:16 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 20 Aug 2021 16:35:16 +0530
Subject: [PATCH V2] arm64/mm: Drop <asm/page-def.h>
Message-ID: <1629457516-32306-1-git-send-email-anshuman.khandual@arm.com>

PAGE_SHIFT (PAGE_SIZE and PAGE_MASK) which is derived from ARM64_PAGE_SHIFT
should be moved into <asm/page.h> instead like in case for other platforms,
and then subsequently <asm/page-def.h> can be just dropped off completely.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on 5.14-rc6.

Changes in V2:

- Moved PAGE_XXX macros into <asm/page.h> instead of <asm/pgtable-hwdef.h>
- Changed the commit message accordingly

Changes in V1:

https://lore.kernel.org/lkml/1629441331-19530-1-git-send-email-anshuman.khandual at arm.com/

 arch/arm64/include/asm/memory.h   |  2 +-
 arch/arm64/include/asm/page-def.h | 18 ------------------
 arch/arm64/include/asm/page.h     |  4 +++-
 3 files changed, 4 insertions(+), 20 deletions(-)
 delete mode 100644 arch/arm64/include/asm/page-def.h

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 824a3655dd93..649d26396f9e 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -12,7 +12,7 @@
 
 #include <linux/const.h>
 #include <linux/sizes.h>
-#include <asm/page-def.h>
+#include <asm/page.h>
 
 /*
  * Size of the PCI I/O space. This must remain a power of two so that
diff --git a/arch/arm64/include/asm/page-def.h b/arch/arm64/include/asm/page-def.h
deleted file mode 100644
index 2403f7b4cdbf..000000000000
--- a/arch/arm64/include/asm/page-def.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Based on arch/arm/include/asm/page.h
- *
- * Copyright (C) 1995-2003 Russell King
- * Copyright (C) 2017 ARM Ltd.
- */
-#ifndef __ASM_PAGE_DEF_H
-#define __ASM_PAGE_DEF_H
-
-#include <linux/const.h>
-
-/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT		CONFIG_ARM64_PAGE_SHIFT
-#define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)
-#define PAGE_MASK		(~(PAGE_SIZE-1))
-
-#endif /* __ASM_PAGE_DEF_H */
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 993a27ea6f54..95c58b00bb71 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -8,7 +8,9 @@
 #ifndef __ASM_PAGE_H
 #define __ASM_PAGE_H
 
-#include <asm/page-def.h>
+#define PAGE_SHIFT		CONFIG_ARM64_PAGE_SHIFT
+#define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK		(~(PAGE_SIZE-1))
 
 #ifndef __ASSEMBLY__
 
-- 
2.20.1



From maz at kernel.org  Fri Aug 20 04:05:44 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 12:05:44 +0100
Subject: (subset) [PATCH 0/2] Fix off-by-one in range_is_memory
In-Reply-To: <20210728153232.1018911-1-dbrazdil@google.com>
References: <20210728153232.1018911-1-dbrazdil@google.com>
Message-ID: <162945752305.2126143.7959914980998500483.b4-ty@kernel.org>

On Wed, 28 Jul 2021 15:32:30 +0000, David Brazdil wrote:
> the range_is_memory function in hyp.
> 
> David Brazdil (2):
>   KVM: arm64: Fix off-by-one in range_is_memory
>   KVM: arm64: Minor optimization of range_is_memory
> 
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)

Applied to kvm-arm64/mmu/el2-tracking, thanks!

[2/2] KVM: arm64: Minor optimization of range_is_memory
      commit: 14ecf075fe5be01860927fdf3aa11d7b18023ab2

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:40 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:40 +0800
Subject: [v2 00/24] Mediatek MT8195 clock support
Message-ID: <20210820111504.350-1-chun-jie.chen@mediatek.com>

this patch series is based on 5.14-rc1 and depends on [1]
- for makefile dependence (patches 7 ~ 19 in [1])
- for common driver dependence (patches 3 ~ 6 in [1])

changes since v1:
- fix resource leak if error condition happens
- refine clock name to match datasheet
- remove redundant data in mux parent source
- seperate clock driver based on IP architecture
- change to dual licence
- refine dt-binding file
- remove audio clock driver (handled in [4])
- integrate vdosys0 and vdosys1 clock registration with mmsys in [2] and [3]

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127
[2] https://patchwork.kernel.org/project/linux-mediatek/list/?series=531695
[3] https://patchwork.kernel.org/project/linux-mediatek/list/?series=519617
[4] https://patchwork.kernel.org/project/linux-mediatek/list/?series=528369

Chun-Jie Chen (24):
  dt-bindings: ARM: Mediatek: Add new document bindings of MT8195 clock
  clk: mediatek: Add dt-bindings of MT8195 clocks
  clk: mediatek: Fix corner case of tuner_en_reg
  clk: mediatek: Add API for clock resource recycle
  clk: mediatek: Fix resource leak in mtk_clk_simple_probe
  clk: mediatek: Add MT8195 apmixedsys clock support
  clk: mediatek: Add MT8195 topckgen clock support
  clk: mediatek: Add MT8195 peripheral clock support
  clk: mediatek: Add MT8195 infrastructure clock support
  clk: mediatek: Add MT8195 camsys clock support
  clk: mediatek: Add MT8195 ccusys clock support
  clk: mediatek: Add MT8195 imgsys clock support
  clk: mediatek: Add MT8195 ipesys clock support
  clk: mediatek: Add MT8195 mfgcfg clock support
  clk: mediatek: Add MT8195 scp adsp clock support
  clk: mediatek: Add MT8195 vdecsys clock support
  clk: mediatek: Add MT8195 vdosys0 clock support
  clk: mediatek: Add MT8195 vdosys1 clock support
  clk: mediatek: Add MT8195 vencsys clock support
  clk: mediatek: Add MT8195 vppsys0 clock support
  clk: mediatek: Add MT8195 vppsys1 clock support
  clk: mediatek: Add MT8195 wpesys clock support
  clk: mediatek: Add MT8195 imp i2c wrapper clock support
  clk: mediatek: Add MT8195 apusys clock support

 .../arm/mediatek/mediatek,mt8195-clock.yaml   |  254 ++++
 .../mediatek/mediatek,mt8195-sys-clock.yaml   |   73 +
 drivers/clk/mediatek/Kconfig                  |    8 +
 drivers/clk/mediatek/Makefile                 |    4 +
 drivers/clk/mediatek/clk-mt8195-apmixedsys.c  |  145 ++
 drivers/clk/mediatek/clk-mt8195-apusys_pll.c  |   92 ++
 drivers/clk/mediatek/clk-mt8195-cam.c         |  142 ++
 drivers/clk/mediatek/clk-mt8195-ccu.c         |   50 +
 drivers/clk/mediatek/clk-mt8195-img.c         |   96 ++
 .../clk/mediatek/clk-mt8195-imp_iic_wrap.c    |   68 +
 drivers/clk/mediatek/clk-mt8195-infra_ao.c    |  211 +++
 drivers/clk/mediatek/clk-mt8195-ipe.c         |   51 +
 drivers/clk/mediatek/clk-mt8195-mfg.c         |   47 +
 drivers/clk/mediatek/clk-mt8195-peri_ao.c     |   62 +
 drivers/clk/mediatek/clk-mt8195-scp_adsp.c    |   47 +
 drivers/clk/mediatek/clk-mt8195-topckgen.c    | 1298 +++++++++++++++++
 drivers/clk/mediatek/clk-mt8195-vdec.c        |  104 ++
 drivers/clk/mediatek/clk-mt8195-vdo0.c        |  123 ++
 drivers/clk/mediatek/clk-mt8195-vdo1.c        |  140 ++
 drivers/clk/mediatek/clk-mt8195-venc.c        |   69 +
 drivers/clk/mediatek/clk-mt8195-vpp0.c        |  110 ++
 drivers/clk/mediatek/clk-mt8195-vpp1.c        |  108 ++
 drivers/clk/mediatek/clk-mt8195-wpe.c         |  143 ++
 drivers/clk/mediatek/clk-mtk.c                |   21 +-
 drivers/clk/mediatek/clk-mtk.h                |    1 +
 drivers/clk/mediatek/clk-pll.c                |    2 +-
 include/dt-bindings/clock/mt8195-clk.h        |  864 +++++++++++
 27 files changed, 4330 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml
 create mode 100644 drivers/clk/mediatek/clk-mt8195-apmixedsys.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-apusys_pll.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-cam.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-ccu.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-infra_ao.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-ipe.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-mfg.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-peri_ao.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-scp_adsp.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-topckgen.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vdec.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vdo0.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vdo1.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-venc.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vpp0.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vpp1.c
 create mode 100644 drivers/clk/mediatek/clk-mt8195-wpe.c
 create mode 100644 include/dt-bindings/clock/mt8195-clk.h

-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:41 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:41 +0800
Subject: [v2 01/24] dt-bindings: ARM: Mediatek: Add new document bindings of
 MT8195 clock
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-2-chun-jie.chen@mediatek.com>

This patch adds the new binding documentation for system clock
and functional clock on Mediatek MT8195.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 .../arm/mediatek/mediatek,mt8195-clock.yaml   | 254 ++++++++++++++++++
 .../mediatek/mediatek,mt8195-sys-clock.yaml   |  73 +++++
 2 files changed, 327 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
new file mode 100644
index 000000000000..17fcbb45d121
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
@@ -0,0 +1,254 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8195-clock.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: MediaTek Functional Clock Controller for MT8195
+
+maintainers:
+  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+description:
+  The clock architecture in Mediatek like below
+  PLLs -->
+          dividers -->
+                      muxes
+                           -->
+                              clock gate
+
+  The devices except apusys_pll provide clock gate control in different IP blocks.
+  The apusys_pll provides Plls which generated from SoC 26m for AI Processing Unit.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8195-scp_adsp
+          - mediatek,mt8195-imp_iic_wrap_s
+          - mediatek,mt8195-imp_iic_wrap_w
+          - mediatek,mt8195-mfgcfg
+          - mediatek,mt8195-vppsys0
+          - mediatek,mt8195-wpesys
+          - mediatek,mt8195-wpesys_vpp0
+          - mediatek,mt8195-wpesys_vpp1
+          - mediatek,mt8195-vppsys1
+          - mediatek,mt8195-imgsys
+          - mediatek,mt8195-imgsys1_dip_top
+          - mediatek,mt8195-imgsys1_dip_nr
+          - mediatek,mt8195-imgsys1_wpe
+          - mediatek,mt8195-ipesys
+          - mediatek,mt8195-camsys
+          - mediatek,mt8195-camsys_rawa
+          - mediatek,mt8195-camsys_yuva
+          - mediatek,mt8195-camsys_rawb
+          - mediatek,mt8195-camsys_yuvb
+          - mediatek,mt8195-camsys_mraw
+          - mediatek,mt8195-ccusys
+          - mediatek,mt8195-vdecsys_soc
+          - mediatek,mt8195-vdecsys
+          - mediatek,mt8195-vdecsys_core1
+          - mediatek,mt8195-vencsys
+          - mediatek,mt8195-vencsys_core1
+          - mediatek,mt8195-apusys_pll
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    scp_adsp: clock-controller at 10720000 {
+        compatible = "mediatek,mt8195-scp_adsp";
+        reg = <0x10720000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imp_iic_wrap_s: clock-controller at 11d03000 {
+        compatible = "mediatek,mt8195-imp_iic_wrap_s";
+        reg = <0x11d03000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imp_iic_wrap_w: clock-controller at 11e05000 {
+        compatible = "mediatek,mt8195-imp_iic_wrap_w";
+        reg = <0x11e05000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    mfgcfg: clock-controller at 13fbf000 {
+        compatible = "mediatek,mt8195-mfgcfg";
+        reg = <0x13fbf000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vppsys0: clock-controller at 14000000 {
+        compatible = "mediatek,mt8195-vppsys0";
+        reg = <0x14000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    wpesys: clock-controller at 14e00000 {
+        compatible = "mediatek,mt8195-wpesys";
+        reg = <0x14e00000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    wpesys_vpp0: clock-controller at 14e02000 {
+        compatible = "mediatek,mt8195-wpesys_vpp0";
+        reg = <0x14e02000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    wpesys_vpp1: clock-controller at 14e03000 {
+        compatible = "mediatek,mt8195-wpesys_vpp1";
+        reg = <0x14e03000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vppsys1: clock-controller at 14f00000 {
+        compatible = "mediatek,mt8195-vppsys1";
+        reg = <0x14f00000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imgsys: clock-controller at 15000000 {
+        compatible = "mediatek,mt8195-imgsys";
+        reg = <0x15000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imgsys1_dip_top: clock-controller at 15110000 {
+        compatible = "mediatek,mt8195-imgsys1_dip_top";
+        reg = <0x15110000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imgsys1_dip_nr: clock-controller at 15130000 {
+        compatible = "mediatek,mt8195-imgsys1_dip_nr";
+        reg = <0x15130000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imgsys1_wpe: clock-controller at 15220000 {
+        compatible = "mediatek,mt8195-imgsys1_wpe";
+        reg = <0x15220000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    ipesys: clock-controller at 15330000 {
+        compatible = "mediatek,mt8195-ipesys";
+        reg = <0x15330000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys: clock-controller at 16000000 {
+        compatible = "mediatek,mt8195-camsys";
+        reg = <0x16000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_rawa: clock-controller at 1604f000 {
+        compatible = "mediatek,mt8195-camsys_rawa";
+        reg = <0x1604f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_yuva: clock-controller at 1606f000 {
+        compatible = "mediatek,mt8195-camsys_yuva";
+        reg = <0x1606f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_rawb: clock-controller at 1608f000 {
+        compatible = "mediatek,mt8195-camsys_rawb";
+        reg = <0x1608f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_yuvb: clock-controller at 160af000 {
+        compatible = "mediatek,mt8195-camsys_yuvb";
+        reg = <0x160af000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_mraw: clock-controller at 16140000 {
+        compatible = "mediatek,mt8195-camsys_mraw";
+        reg = <0x16140000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    ccusys: clock-controller at 17200000 {
+        compatible = "mediatek,mt8195-ccusys";
+        reg = <0x17200000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vdecsys_soc: clock-controller at 1800f000 {
+        compatible = "mediatek,mt8195-vdecsys_soc";
+        reg = <0x1800f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vdecsys: clock-controller at 1802f000 {
+        compatible = "mediatek,mt8195-vdecsys";
+        reg = <0x1802f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vdecsys_core1: clock-controller at 1803f000 {
+        compatible = "mediatek,mt8195-vdecsys_core1";
+        reg = <0x1803f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vencsys: clock-controller at 1a000000 {
+        compatible = "mediatek,mt8195-vencsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vencsys_core1: clock-controller at 1b000000 {
+        compatible = "mediatek,mt8195-vencsys_core1";
+        reg = <0x1b000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    apusys_pll: clock-controller at 190f3000 {
+        compatible = "mediatek,mt8195-apusys_pll";
+        reg = <0x190f3000 0x1000>;
+        #clock-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml
new file mode 100644
index 000000000000..dbf33ea6cb9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8195-sys-clock.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: MediaTek System Clock Controller for MT8195
+
+maintainers:
+  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+description:
+  The clock architecture in Mediaek like below
+  PLLs -->
+          dividers -->
+                      muxes
+                           -->
+                              clock gate
+
+  The apmixedsys provides most of PLLs which generated from SoC 26m.
+  The topckgen provides dividers and muxes which provide the clock source to other IP blocks.
+  The infracfg_ao and pericfg_ao provides clock gate in peripheral and infrastructure IP blocks.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8195-topckgen
+          - mediatek,mt8195-infracfg_ao
+          - mediatek,mt8195-apmixedsys
+          - mediatek,mt8195-pericfg_ao
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    topckgen: syscon at 10000000 {
+        compatible = "mediatek,mt8195-topckgen", "syscon";
+        reg = <0x10000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    infracfg_ao: syscon at 10001000 {
+        compatible = "mediatek,mt8195-infracfg_ao", "syscon";
+        reg = <0x10001000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    apmixedsys: syscon at 1000c000 {
+        compatible = "mediatek,mt8195-apmixedsys", "syscon";
+        reg = <0x1000c000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    pericfg_ao: syscon at 11003000 {
+        compatible = "mediatek,mt8195-pericfg_ao", "syscon";
+        reg = <0x11003000 0x1000>;
+        #clock-cells = <1>;
+    };
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:42 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:42 +0800
Subject: [v2 02/24] clk: mediatek: Add dt-bindings of MT8195 clocks
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-3-chun-jie.chen@mediatek.com>

Add MT8195 clock dt-bindings, include topckgen, apmixedsys,
infracfg_ao, pericfg_ao and subsystem clocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 include/dt-bindings/clock/mt8195-clk.h | 864 +++++++++++++++++++++++++
 1 file changed, 864 insertions(+)
 create mode 100644 include/dt-bindings/clock/mt8195-clk.h

diff --git a/include/dt-bindings/clock/mt8195-clk.h b/include/dt-bindings/clock/mt8195-clk.h
new file mode 100644
index 000000000000..95cf812a0b37
--- /dev/null
+++ b/include/dt-bindings/clock/mt8195-clk.h
@@ -0,0 +1,864 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT8195_H
+#define _DT_BINDINGS_CLK_MT8195_H
+
+/* TOPCKGEN */
+
+#define CLK_TOP_AXI			0
+#define CLK_TOP_SPM			1
+#define CLK_TOP_SCP			2
+#define CLK_TOP_BUS_AXIMEM		3
+#define CLK_TOP_VPP			4
+#define CLK_TOP_ETHDR			5
+#define CLK_TOP_IPE			6
+#define CLK_TOP_CAM			7
+#define CLK_TOP_CCU			8
+#define CLK_TOP_IMG			9
+#define CLK_TOP_CAMTM			10
+#define CLK_TOP_DSP			11
+#define CLK_TOP_DSP1			12
+#define CLK_TOP_DSP2			13
+#define CLK_TOP_DSP3			14
+#define CLK_TOP_DSP4			15
+#define CLK_TOP_DSP5			16
+#define CLK_TOP_DSP6			17
+#define CLK_TOP_DSP7			18
+#define CLK_TOP_IPU_IF			19
+#define CLK_TOP_MFG_CORE_TMP		20
+#define CLK_TOP_CAMTG			21
+#define CLK_TOP_CAMTG2			22
+#define CLK_TOP_CAMTG3			23
+#define CLK_TOP_CAMTG4			24
+#define CLK_TOP_CAMTG5			25
+#define CLK_TOP_UART			26
+#define CLK_TOP_SPI			27
+#define CLK_TOP_SPIS			28
+#define CLK_TOP_MSDC50_0_HCLK		29
+#define CLK_TOP_MSDC50_0		30
+#define CLK_TOP_MSDC30_1		31
+#define CLK_TOP_MSDC30_2		32
+#define CLK_TOP_INTDIR			33
+#define CLK_TOP_AUD_INTBUS		34
+#define CLK_TOP_AUDIO_H			35
+#define CLK_TOP_PWRAP_ULPOSC		36
+#define CLK_TOP_ATB			37
+#define CLK_TOP_PWRMCU			38
+#define CLK_TOP_DP			39
+#define CLK_TOP_EDP			40
+#define CLK_TOP_DPI			41
+#define CLK_TOP_DISP_PWM0		42
+#define CLK_TOP_DISP_PWM1		43
+#define CLK_TOP_USB_TOP			44
+#define CLK_TOP_SSUSB_XHCI		45
+#define CLK_TOP_USB_TOP_1P		46
+#define CLK_TOP_SSUSB_XHCI_1P		47
+#define CLK_TOP_USB_TOP_2P		48
+#define CLK_TOP_SSUSB_XHCI_2P		49
+#define CLK_TOP_USB_TOP_3P		50
+#define CLK_TOP_SSUSB_XHCI_3P		51
+#define CLK_TOP_I2C			52
+#define CLK_TOP_SENINF			53
+#define CLK_TOP_SENINF1			54
+#define CLK_TOP_SENINF2			55
+#define CLK_TOP_SENINF3			56
+#define CLK_TOP_GCPU			57
+#define CLK_TOP_DXCC			58
+#define CLK_TOP_DPMAIF_MAIN		59
+#define CLK_TOP_AES_UFSFDE		60
+#define CLK_TOP_UFS			61
+#define CLK_TOP_UFS_TICK1US		62
+#define CLK_TOP_UFS_MP_SAP_CFG		63
+#define CLK_TOP_VENC			64
+#define CLK_TOP_VDEC			65
+#define CLK_TOP_PWM			66
+#define CLK_TOP_MCUPM			67
+#define CLK_TOP_SPMI_P_MST		68
+#define CLK_TOP_SPMI_M_MST		69
+#define CLK_TOP_DVFSRC			70
+#define CLK_TOP_TL			71
+#define CLK_TOP_TL_P1			72
+#define CLK_TOP_AES_MSDCFDE		73
+#define CLK_TOP_DSI_OCC			74
+#define CLK_TOP_WPE_VPP			75
+#define CLK_TOP_HDCP			76
+#define CLK_TOP_HDCP_24M		77
+#define CLK_TOP_HD20_DACR_REF_CLK	78
+#define CLK_TOP_HD20_HDCP_CCLK		79
+#define CLK_TOP_HDMI_XTAL		80
+#define CLK_TOP_HDMI_APB		81
+#define CLK_TOP_SNPS_ETH_250M		82
+#define CLK_TOP_SNPS_ETH_62P4M_PTP	83
+#define CLK_TOP_SNPS_ETH_50M_RMII	84
+#define CLK_TOP_DGI_OUT			85
+#define CLK_TOP_NNA0			86
+#define CLK_TOP_NNA1			87
+#define CLK_TOP_ADSP			88
+#define CLK_TOP_ASM_H			89
+#define CLK_TOP_ASM_M			90
+#define CLK_TOP_ASM_L			91
+#define CLK_TOP_APLL1			92
+#define CLK_TOP_APLL2			93
+#define CLK_TOP_APLL3			94
+#define CLK_TOP_APLL4			95
+#define CLK_TOP_APLL5			96
+#define CLK_TOP_I2SO1_MCK		97
+#define CLK_TOP_I2SO2_MCK		98
+#define CLK_TOP_I2SI1_MCK		99
+#define CLK_TOP_I2SI2_MCK		100
+#define CLK_TOP_DPTX_MCK		101
+#define CLK_TOP_AUD_IEC_CLK		102
+#define CLK_TOP_A1SYS_HP		103
+#define CLK_TOP_A2SYS_HF		104
+#define CLK_TOP_A3SYS_HF		105
+#define CLK_TOP_A4SYS_HF		106
+#define CLK_TOP_SPINFI_BCLK		107
+#define CLK_TOP_NFI1X			108
+#define CLK_TOP_ECC			109
+#define CLK_TOP_AUDIO_LOCAL_BUS		110
+#define CLK_TOP_SPINOR			111
+#define CLK_TOP_DVIO_DGI_REF		112
+#define CLK_TOP_ULPOSC			113
+#define CLK_TOP_ULPOSC_CORE		114
+#define CLK_TOP_SRCK			115
+#define CLK_TOP_MFG_CK_FAST_REF		116
+#define CLK_TOP_CLK26M_D2		117
+#define CLK_TOP_CLK26M_D52		118
+#define CLK_TOP_IN_DGI			119
+#define CLK_TOP_IN_DGI_D2		120
+#define CLK_TOP_IN_DGI_D4		121
+#define CLK_TOP_IN_DGI_D6		122
+#define CLK_TOP_IN_DGI_D8		123
+#define CLK_TOP_MAINPLL_D3		124
+#define CLK_TOP_MAINPLL_D4		125
+#define CLK_TOP_MAINPLL_D4_D2		126
+#define CLK_TOP_MAINPLL_D4_D4		127
+#define CLK_TOP_MAINPLL_D4_D8		128
+#define CLK_TOP_MAINPLL_D5		129
+#define CLK_TOP_MAINPLL_D5_D2		130
+#define CLK_TOP_MAINPLL_D5_D4		131
+#define CLK_TOP_MAINPLL_D5_D8		132
+#define CLK_TOP_MAINPLL_D6		133
+#define CLK_TOP_MAINPLL_D6_D2		134
+#define CLK_TOP_MAINPLL_D6_D4		135
+#define CLK_TOP_MAINPLL_D6_D8		136
+#define CLK_TOP_MAINPLL_D7		137
+#define CLK_TOP_MAINPLL_D7_D2		138
+#define CLK_TOP_MAINPLL_D7_D4		139
+#define CLK_TOP_MAINPLL_D7_D8		140
+#define CLK_TOP_MAINPLL_D9		141
+#define CLK_TOP_UNIVPLL_D2		142
+#define CLK_TOP_UNIVPLL_D3		143
+#define CLK_TOP_UNIVPLL_D4		144
+#define CLK_TOP_UNIVPLL_D4_D2		145
+#define CLK_TOP_UNIVPLL_D4_D4		146
+#define CLK_TOP_UNIVPLL_D4_D8		147
+#define CLK_TOP_UNIVPLL_D5		148
+#define CLK_TOP_UNIVPLL_D5_D2		149
+#define CLK_TOP_UNIVPLL_D5_D4		150
+#define CLK_TOP_UNIVPLL_D5_D8		151
+#define CLK_TOP_UNIVPLL_D6		152
+#define CLK_TOP_UNIVPLL_D6_D2		153
+#define CLK_TOP_UNIVPLL_D6_D4		154
+#define CLK_TOP_UNIVPLL_D6_D8		155
+#define CLK_TOP_UNIVPLL_D6_D16		156
+#define CLK_TOP_UNIVPLL_D7		157
+#define CLK_TOP_UNIVPLL_192M		158
+#define CLK_TOP_UNIVPLL_192M_D4		159
+#define CLK_TOP_UNIVPLL_192M_D8		160
+#define CLK_TOP_UNIVPLL_192M_D16	161
+#define CLK_TOP_UNIVPLL_192M_D32	162
+#define CLK_TOP_APLL1_D3		163
+#define CLK_TOP_APLL1_D4		164
+#define CLK_TOP_APLL2_D3		165
+#define CLK_TOP_APLL2_D4		166
+#define CLK_TOP_APLL3_D4		167
+#define CLK_TOP_APLL4_D4		168
+#define CLK_TOP_APLL5_D4		169
+#define CLK_TOP_HDMIRX_APLL_D3		170
+#define CLK_TOP_HDMIRX_APLL_D4		171
+#define CLK_TOP_HDMIRX_APLL_D6		172
+#define CLK_TOP_MMPLL_D4		173
+#define CLK_TOP_MMPLL_D4_D2		174
+#define CLK_TOP_MMPLL_D4_D4		175
+#define CLK_TOP_MMPLL_D5		176
+#define CLK_TOP_MMPLL_D5_D2		177
+#define CLK_TOP_MMPLL_D5_D4		178
+#define CLK_TOP_MMPLL_D6		179
+#define CLK_TOP_MMPLL_D6_D2		180
+#define CLK_TOP_MMPLL_D7		181
+#define CLK_TOP_MMPLL_D9		182
+#define CLK_TOP_TVDPLL1_D2		183
+#define CLK_TOP_TVDPLL1_D4		184
+#define CLK_TOP_TVDPLL1_D8		185
+#define CLK_TOP_TVDPLL1_D16		186
+#define CLK_TOP_TVDPLL2_D2		187
+#define CLK_TOP_TVDPLL2_D4		188
+#define CLK_TOP_TVDPLL2_D8		189
+#define CLK_TOP_TVDPLL2_D16		190
+#define CLK_TOP_MSDCPLL_D2		191
+#define CLK_TOP_MSDCPLL_D4		192
+#define CLK_TOP_MSDCPLL_D16		193
+#define CLK_TOP_ETHPLL_D2		194
+#define CLK_TOP_ETHPLL_D8		195
+#define CLK_TOP_ETHPLL_D10		196
+#define CLK_TOP_DGIPLL_D2		197
+#define CLK_TOP_ULPOSC1			198
+#define CLK_TOP_ULPOSC1_D2		199
+#define CLK_TOP_ULPOSC1_D4		200
+#define CLK_TOP_ULPOSC1_D7		201
+#define CLK_TOP_ULPOSC1_D8		202
+#define CLK_TOP_ULPOSC1_D10		203
+#define CLK_TOP_ULPOSC1_D16		204
+#define CLK_TOP_ULPOSC2			205
+#define CLK_TOP_ADSPPLL_D2		206
+#define CLK_TOP_ADSPPLL_D4		207
+#define CLK_TOP_ADSPPLL_D8		208
+#define CLK_TOP_MEM_466M		209
+#define CLK_TOP_MPHONE_SLAVE_B		210
+#define CLK_TOP_PEXTP_PIPE		211
+#define CLK_TOP_UFS_RX_SYMBOL		212
+#define CLK_TOP_UFS_TX_SYMBOL		213
+#define CLK_TOP_SSUSB_U3PHY_P1_P_P0	214
+#define CLK_TOP_UFS_RX_SYMBOL1		215
+#define CLK_TOP_FPC			216
+#define CLK_TOP_HDMIRX_P		217
+#define CLK_TOP_APLL12_DIV0		218
+#define CLK_TOP_APLL12_DIV1		219
+#define CLK_TOP_APLL12_DIV2		220
+#define CLK_TOP_APLL12_DIV3		221
+#define CLK_TOP_APLL12_DIV4		222
+#define CLK_TOP_APLL12_DIV9		223
+#define CLK_TOP_CFG_VPP0		224
+#define CLK_TOP_CFG_VPP1		225
+#define CLK_TOP_CFG_VDO0		226
+#define CLK_TOP_CFG_VDO1		227
+#define CLK_TOP_CFG_UNIPLL_SES		228
+#define CLK_TOP_CFG_26M_VPP0		229
+#define CLK_TOP_CFG_26M_VPP1		230
+#define CLK_TOP_CFG_26M_AUD		231
+#define CLK_TOP_CFG_AXI_EAST		232
+#define CLK_TOP_CFG_AXI_EAST_NORTH	233
+#define CLK_TOP_CFG_AXI_NORTH		234
+#define CLK_TOP_CFG_AXI_SOUTH		235
+#define CLK_TOP_CFG_EXT_TEST		236
+#define CLK_TOP_SSUSB_REF		237
+#define CLK_TOP_SSUSB_PHY_REF		238
+#define CLK_TOP_SSUSB_P1_REF		239
+#define CLK_TOP_SSUSB_PHY_P1_REF	240
+#define CLK_TOP_SSUSB_P2_REF		241
+#define CLK_TOP_SSUSB_PHY_P2_REF	242
+#define CLK_TOP_SSUSB_P3_REF		243
+#define CLK_TOP_SSUSB_PHY_P3_REF	244
+#define CLK_TOP_NR_CLK			245
+
+/* INFRACFG_AO */
+
+#define CLK_INFRA_AO_PMIC_TMR		0
+#define CLK_INFRA_AO_PMIC_AP		1
+#define CLK_INFRA_AO_PMIC_MD		2
+#define CLK_INFRA_AO_PMIC_CONN		3
+#define CLK_INFRA_AO_SEJ		4
+#define CLK_INFRA_AO_APXGPT		5
+#define CLK_INFRA_AO_GCE		6
+#define CLK_INFRA_AO_GCE2		7
+#define CLK_INFRA_AO_THERM		8
+#define CLK_INFRA_AO_PWM_H		9
+#define CLK_INFRA_AO_PWM1		10
+#define CLK_INFRA_AO_PWM2		11
+#define CLK_INFRA_AO_PWM3		12
+#define CLK_INFRA_AO_PWM4		13
+#define CLK_INFRA_AO_PWM		14
+#define CLK_INFRA_AO_UART0		15
+#define CLK_INFRA_AO_UART1		16
+#define CLK_INFRA_AO_UART2		17
+#define CLK_INFRA_AO_UART3		18
+#define CLK_INFRA_AO_UART4		19
+#define CLK_INFRA_AO_GCE_26M		20
+#define CLK_INFRA_AO_CQ_DMA_FPC		21
+#define CLK_INFRA_AO_UART5		22
+#define CLK_INFRA_AO_HDMI_26M		23
+#define CLK_INFRA_AO_SPI0		24
+#define CLK_INFRA_AO_MSDC0		25
+#define CLK_INFRA_AO_MSDC1		26
+#define CLK_INFRA_AO_CG1_MSDC2		27
+#define CLK_INFRA_AO_MSDC0_SRC		28
+#define CLK_INFRA_AO_TRNG		29
+#define CLK_INFRA_AO_AUXADC		30
+#define CLK_INFRA_AO_CPUM		31
+#define CLK_INFRA_AO_HDMI_32K		32
+#define CLK_INFRA_AO_CEC_66M_H		33
+#define CLK_INFRA_AO_IRRX		34
+#define CLK_INFRA_AO_PCIE_TL_26M	35
+#define CLK_INFRA_AO_MSDC1_SRC		36
+#define CLK_INFRA_AO_CEC_66M_B		37
+#define CLK_INFRA_AO_PCIE_TL_96M	38
+#define CLK_INFRA_AO_DEVICE_APC		39
+#define CLK_INFRA_AO_ECC_66M_H		40
+#define CLK_INFRA_AO_DEBUGSYS		41
+#define CLK_INFRA_AO_AUDIO		42
+#define CLK_INFRA_AO_PCIE_TL_32K	43
+#define CLK_INFRA_AO_DBG_TRACE		44
+#define CLK_INFRA_AO_DRAMC_F26M		45
+#define CLK_INFRA_AO_IRTX		46
+#define CLK_INFRA_AO_SSUSB		47
+#define CLK_INFRA_AO_DISP_PWM		48
+#define CLK_INFRA_AO_CLDMA_B		49
+#define CLK_INFRA_AO_AUDIO_26M_B	50
+#define CLK_INFRA_AO_SPI1		51
+#define CLK_INFRA_AO_SPI2		52
+#define CLK_INFRA_AO_SPI3		53
+#define CLK_INFRA_AO_UNIPRO_SYS		54
+#define CLK_INFRA_AO_UNIPRO_TICK	55
+#define CLK_INFRA_AO_UFS_MP_SAP_B	56
+#define CLK_INFRA_AO_PWRMCU		57
+#define CLK_INFRA_AO_PWRMCU_BUS_H	58
+#define CLK_INFRA_AO_APDMA_B		59
+#define CLK_INFRA_AO_SPI4		60
+#define CLK_INFRA_AO_SPI5		61
+#define CLK_INFRA_AO_CQ_DMA		62
+#define CLK_INFRA_AO_AES_UFSFDE		63
+#define CLK_INFRA_AO_AES		64
+#define CLK_INFRA_AO_UFS_TICK		65
+#define CLK_INFRA_AO_SSUSB_XHCI		66
+#define CLK_INFRA_AO_MSDC0_SELF		67
+#define CLK_INFRA_AO_MSDC1_SELF		68
+#define CLK_INFRA_AO_MSDC2_SELF		69
+#define CLK_INFRA_AO_I2S_DMA		70
+#define CLK_INFRA_AO_AP_MSDC0		71
+#define CLK_INFRA_AO_MD_MSDC0		72
+#define CLK_INFRA_AO_CG3_MSDC2		73
+#define CLK_INFRA_AO_GCPU		74
+#define CLK_INFRA_AO_PCIE_PERI_26M	75
+#define CLK_INFRA_AO_GCPU_66M_B		76
+#define CLK_INFRA_AO_GCPU_133M_B	77
+#define CLK_INFRA_AO_DISP_PWM1		78
+#define CLK_INFRA_AO_FBIST2FPC		79
+#define CLK_INFRA_AO_DEVICE_APC_SYNC	80
+#define CLK_INFRA_AO_PCIE_P1_PERI_26M	81
+#define CLK_INFRA_AO_SPIS0		82
+#define CLK_INFRA_AO_SPIS1		83
+#define CLK_INFRA_AO_133M_M_PERI	84
+#define CLK_INFRA_AO_66M_M_PERI		85
+#define CLK_INFRA_AO_PCIE_PL_P_250M_P0	86
+#define CLK_INFRA_AO_PCIE_PL_P_250M_P1	87
+#define CLK_INFRA_AO_PCIE_P1_TL_96M	88
+#define CLK_INFRA_AO_AES_MSDCFDE_0P	89
+#define CLK_INFRA_AO_UFS_TX_SYMBOL	90
+#define CLK_INFRA_AO_UFS_RX_SYMBOL	91
+#define CLK_INFRA_AO_UFS_RX_SYMBOL1	92
+#define CLK_INFRA_AO_PERI_UFS_MEM_SUB	93
+#define CLK_INFRA_AO_NR_CLK		94
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_NNAPLL		0
+#define CLK_APMIXED_RESPLL		1
+#define CLK_APMIXED_ETHPLL		2
+#define CLK_APMIXED_MSDCPLL		3
+#define CLK_APMIXED_TVDPLL1		4
+#define CLK_APMIXED_TVDPLL2		5
+#define CLK_APMIXED_MMPLL		6
+#define CLK_APMIXED_MAINPLL		7
+#define CLK_APMIXED_VDECPLL		8
+#define CLK_APMIXED_IMGPLL		9
+#define CLK_APMIXED_UNIVPLL		10
+#define CLK_APMIXED_HDMIPLL1		11
+#define CLK_APMIXED_HDMIPLL2		12
+#define CLK_APMIXED_HDMIRX_APLL		13
+#define CLK_APMIXED_USB1PLL		14
+#define CLK_APMIXED_ADSPPLL		15
+#define CLK_APMIXED_APLL1		16
+#define CLK_APMIXED_APLL2		17
+#define CLK_APMIXED_APLL3		18
+#define CLK_APMIXED_APLL4		19
+#define CLK_APMIXED_APLL5		20
+#define CLK_APMIXED_MFGPLL		21
+#define CLK_APMIXED_DGIPLL		22
+#define CLK_APMIXED_PLL_SSUSB26M	23
+#define CLK_APMIXED_NR_CLK		24
+
+/* SCP_ADSP */
+
+#define CLK_SCP_ADSP_AUDIODSP		0
+#define CLK_SCP_ADSP_NR_CLK		1
+
+/* PERICFG_AO */
+
+#define CLK_PERI_AO_ETHERNET		0
+#define CLK_PERI_AO_ETHERNET_BUS	1
+#define CLK_PERI_AO_FLASHIF_BUS		2
+#define CLK_PERI_AO_FLASHIF_FLASH	3
+#define CLK_PERI_AO_SSUSB_1P_BUS	4
+#define CLK_PERI_AO_SSUSB_1P_XHCI	5
+#define CLK_PERI_AO_SSUSB_2P_BUS	6
+#define CLK_PERI_AO_SSUSB_2P_XHCI	7
+#define CLK_PERI_AO_SSUSB_3P_BUS	8
+#define CLK_PERI_AO_SSUSB_3P_XHCI	9
+#define CLK_PERI_AO_SPINFI		10
+#define CLK_PERI_AO_ETHERNET_MAC	11
+#define CLK_PERI_AO_NFI_H		12
+#define CLK_PERI_AO_FNFI1X		13
+#define CLK_PERI_AO_PCIE_P0_MEM		14
+#define CLK_PERI_AO_PCIE_P1_MEM		15
+#define CLK_PERI_AO_NR_CLK		16
+
+/* IMP_IIC_WRAP_S */
+
+#define CLK_IMP_IIC_WRAP_S_I2C5		0
+#define CLK_IMP_IIC_WRAP_S_I2C6		1
+#define CLK_IMP_IIC_WRAP_S_I2C7		2
+#define CLK_IMP_IIC_WRAP_S_NR_CLK	3
+
+/* IMP_IIC_WRAP_W */
+
+#define CLK_IMP_IIC_WRAP_W_I2C0		0
+#define CLK_IMP_IIC_WRAP_W_I2C1		1
+#define CLK_IMP_IIC_WRAP_W_I2C2		2
+#define CLK_IMP_IIC_WRAP_W_I2C3		3
+#define CLK_IMP_IIC_WRAP_W_I2C4		4
+#define CLK_IMP_IIC_WRAP_W_NR_CLK	5
+
+/* MFGCFG */
+
+#define CLK_MFG_BG3D			0
+#define CLK_MFG_NR_CLK			1
+
+/* VPPSYS0 */
+
+#define CLK_VPP0_MDP_FG				0
+#define CLK_VPP0_STITCH				1
+#define CLK_VPP0_PADDING			2
+#define CLK_VPP0_MDP_TCC			3
+#define CLK_VPP0_WARP0_ASYNC_TX			4
+#define CLK_VPP0_WARP1_ASYNC_TX			5
+#define CLK_VPP0_MUTEX				6
+#define CLK_VPP0_VPP02VPP1_RELAY		7
+#define CLK_VPP0_VPP12VPP0_ASYNC		8
+#define CLK_VPP0_MMSYSRAM_TOP			9
+#define CLK_VPP0_MDP_AAL			10
+#define CLK_VPP0_MDP_RSZ			11
+#define CLK_VPP0_SMI_COMMON			12
+#define CLK_VPP0_GALS_VDO0_LARB0		13
+#define CLK_VPP0_GALS_VDO0_LARB1		14
+#define CLK_VPP0_GALS_VENCSYS			15
+#define CLK_VPP0_GALS_VENCSYS_CORE1		16
+#define CLK_VPP0_GALS_INFRA			17
+#define CLK_VPP0_GALS_CAMSYS			18
+#define CLK_VPP0_GALS_VPP1_LARB5		19
+#define CLK_VPP0_GALS_VPP1_LARB6		20
+#define CLK_VPP0_SMI_REORDER			21
+#define CLK_VPP0_SMI_IOMMU			22
+#define CLK_VPP0_GALS_IMGSYS_CAMSYS		23
+#define CLK_VPP0_MDP_RDMA			24
+#define CLK_VPP0_MDP_WROT			25
+#define CLK_VPP0_GALS_EMI0_EMI1			26
+#define CLK_VPP0_SMI_SUB_COMMON_REORDER		27
+#define CLK_VPP0_SMI_RSI			28
+#define CLK_VPP0_SMI_COMMON_LARB4		29
+#define CLK_VPP0_GALS_VDEC_VDEC_CORE1		30
+#define CLK_VPP0_GALS_VPP1_WPE			31
+#define CLK_VPP0_GALS_VDO0_VDO1_VENCSYS_CORE1	32
+#define CLK_VPP0_FAKE_ENG			33
+#define CLK_VPP0_MDP_HDR			34
+#define CLK_VPP0_MDP_TDSHP			35
+#define CLK_VPP0_MDP_COLOR			36
+#define CLK_VPP0_MDP_OVL			37
+#define CLK_VPP0_WARP0_RELAY			38
+#define CLK_VPP0_WARP0_MDP_DL_ASYNC		39
+#define CLK_VPP0_WARP1_RELAY			40
+#define CLK_VPP0_WARP1_MDP_DL_ASYNC		41
+#define CLK_VPP0_NR_CLK				42
+
+/* WPESYS */
+
+#define CLK_WPE_VPP0			0
+#define CLK_WPE_VPP1			1
+#define CLK_WPE_SMI_LARB7		2
+#define CLK_WPE_SMI_LARB8		3
+#define CLK_WPE_EVENT_TX		4
+#define CLK_WPE_SMI_LARB7_P		5
+#define CLK_WPE_SMI_LARB8_P		6
+#define CLK_WPE_NR_CLK			7
+
+/* WPESYS_VPP0 */
+
+#define CLK_WPE_VPP0_VECI		0
+#define CLK_WPE_VPP0_VEC2I		1
+#define CLK_WPE_VPP0_VEC3I		2
+#define CLK_WPE_VPP0_WPEO		3
+#define CLK_WPE_VPP0_MSKO		4
+#define CLK_WPE_VPP0_VGEN		5
+#define CLK_WPE_VPP0_EXT		6
+#define CLK_WPE_VPP0_VFC		7
+#define CLK_WPE_VPP0_CACH0_TOP		8
+#define CLK_WPE_VPP0_CACH0_DMA		9
+#define CLK_WPE_VPP0_CACH1_TOP		10
+#define CLK_WPE_VPP0_CACH1_DMA		11
+#define CLK_WPE_VPP0_CACH2_TOP		12
+#define CLK_WPE_VPP0_CACH2_DMA		13
+#define CLK_WPE_VPP0_CACH3_TOP		14
+#define CLK_WPE_VPP0_CACH3_DMA		15
+#define CLK_WPE_VPP0_PSP		16
+#define CLK_WPE_VPP0_PSP2		17
+#define CLK_WPE_VPP0_SYNC		18
+#define CLK_WPE_VPP0_C24		19
+#define CLK_WPE_VPP0_MDP_CROP		20
+#define CLK_WPE_VPP0_ISP_CROP		21
+#define CLK_WPE_VPP0_TOP		22
+#define CLK_WPE_VPP0_NR_CLK		23
+
+/* WPESYS_VPP1 */
+
+#define CLK_WPE_VPP1_VECI		0
+#define CLK_WPE_VPP1_VEC2I		1
+#define CLK_WPE_VPP1_VEC3I		2
+#define CLK_WPE_VPP1_WPEO		3
+#define CLK_WPE_VPP1_MSKO		4
+#define CLK_WPE_VPP1_VGEN		5
+#define CLK_WPE_VPP1_EXT		6
+#define CLK_WPE_VPP1_VFC		7
+#define CLK_WPE_VPP1_CACH0_TOP		8
+#define CLK_WPE_VPP1_CACH0_DMA		9
+#define CLK_WPE_VPP1_CACH1_TOP		10
+#define CLK_WPE_VPP1_CACH1_DMA		11
+#define CLK_WPE_VPP1_CACH2_TOP		12
+#define CLK_WPE_VPP1_CACH2_DMA		13
+#define CLK_WPE_VPP1_CACH3_TOP		14
+#define CLK_WPE_VPP1_CACH3_DMA		15
+#define CLK_WPE_VPP1_PSP		16
+#define CLK_WPE_VPP1_PSP2		17
+#define CLK_WPE_VPP1_SYNC		18
+#define CLK_WPE_VPP1_C24		19
+#define CLK_WPE_VPP1_MDP_CROP		20
+#define CLK_WPE_VPP1_ISP_CROP		21
+#define CLK_WPE_VPP1_TOP		22
+#define CLK_WPE_VPP1_NR_CLK		23
+
+/* VPPSYS1 */
+
+#define CLK_VPP1_SVPP1_MDP_OVL		0
+#define CLK_VPP1_SVPP1_MDP_TCC		1
+#define CLK_VPP1_SVPP1_MDP_WROT		2
+#define CLK_VPP1_SVPP1_VPP_PAD		3
+#define CLK_VPP1_SVPP2_MDP_WROT		4
+#define CLK_VPP1_SVPP2_VPP_PAD		5
+#define CLK_VPP1_SVPP3_MDP_WROT		6
+#define CLK_VPP1_SVPP3_VPP_PAD		7
+#define CLK_VPP1_SVPP1_MDP_RDMA		8
+#define CLK_VPP1_SVPP1_MDP_FG		9
+#define CLK_VPP1_SVPP2_MDP_RDMA		10
+#define CLK_VPP1_SVPP2_MDP_FG		11
+#define CLK_VPP1_SVPP3_MDP_RDMA		12
+#define CLK_VPP1_SVPP3_MDP_FG		13
+#define CLK_VPP1_VPP_SPLIT		14
+#define CLK_VPP1_SVPP2_VDO0_DL_RELAY	15
+#define CLK_VPP1_SVPP1_MDP_TDSHP	16
+#define CLK_VPP1_SVPP1_MDP_COLOR	17
+#define CLK_VPP1_SVPP3_VDO1_DL_RELAY	18
+#define CLK_VPP1_SVPP2_VPP_MERGE	19
+#define CLK_VPP1_SVPP2_MDP_COLOR	20
+#define CLK_VPP1_VPPSYS1_GALS		21
+#define CLK_VPP1_SVPP3_VPP_MERGE	22
+#define CLK_VPP1_SVPP3_MDP_COLOR	23
+#define CLK_VPP1_VPPSYS1_LARB		24
+#define CLK_VPP1_SVPP1_MDP_RSZ		25
+#define CLK_VPP1_SVPP1_MDP_HDR		26
+#define CLK_VPP1_SVPP1_MDP_AAL		27
+#define CLK_VPP1_SVPP2_MDP_HDR		28
+#define CLK_VPP1_SVPP2_MDP_AAL		29
+#define CLK_VPP1_DL_ASYNC		30
+#define CLK_VPP1_LARB5_FAKE_ENG		31
+#define CLK_VPP1_SVPP3_MDP_HDR		32
+#define CLK_VPP1_SVPP3_MDP_AAL		33
+#define CLK_VPP1_SVPP2_VDO1_DL_RELAY	34
+#define CLK_VPP1_LARB6_FAKE_ENG		35
+#define CLK_VPP1_SVPP2_MDP_RSZ		36
+#define CLK_VPP1_SVPP3_MDP_RSZ		37
+#define CLK_VPP1_SVPP3_VDO0_DL_RELAY	38
+#define CLK_VPP1_DISP_MUTEX		39
+#define CLK_VPP1_SVPP2_MDP_TDSHP	40
+#define CLK_VPP1_SVPP3_MDP_TDSHP	41
+#define CLK_VPP1_VPP0_DL1_RELAY		42
+#define CLK_VPP1_HDMI_META		43
+#define CLK_VPP1_VPP_SPLIT_HDMI		44
+#define CLK_VPP1_DGI_IN			45
+#define CLK_VPP1_DGI_OUT		46
+#define CLK_VPP1_VPP_SPLIT_DGI		47
+#define CLK_VPP1_VPP0_DL_ASYNC		48
+#define CLK_VPP1_VPP0_DL_RELAY		49
+#define CLK_VPP1_VPP_SPLIT_26M		50
+#define CLK_VPP1_NR_CLK			51
+
+/* IMGSYS */
+
+#define CLK_IMG_LARB9			0
+#define CLK_IMG_TRAW0			1
+#define CLK_IMG_TRAW1			2
+#define CLK_IMG_TRAW2			3
+#define CLK_IMG_TRAW3			4
+#define CLK_IMG_DIP0			5
+#define CLK_IMG_WPE0			6
+#define CLK_IMG_IPE			7
+#define CLK_IMG_DIP1			8
+#define CLK_IMG_WPE1			9
+#define CLK_IMG_GALS			10
+#define CLK_IMG_NR_CLK			11
+
+/* IMGSYS1_DIP_TOP */
+
+#define CLK_IMG1_DIP_TOP_LARB10		0
+#define CLK_IMG1_DIP_TOP_DIP_TOP	1
+#define CLK_IMG1_DIP_TOP_NR_CLK		2
+
+/* IMGSYS1_DIP_NR */
+
+#define CLK_IMG1_DIP_NR_RESERVE		0
+#define CLK_IMG1_DIP_NR_DIP_NR		1
+#define CLK_IMG1_DIP_NR_NR_CLK		2
+
+/* IMGSYS1_WPE */
+
+#define CLK_IMG1_WPE_LARB11		0
+#define CLK_IMG1_WPE_WPE		1
+#define CLK_IMG1_WPE_NR_CLK		2
+
+/* IPESYS */
+
+#define CLK_IPE_DPE			0
+#define CLK_IPE_FDVT			1
+#define CLK_IPE_ME			2
+#define CLK_IPE_TOP			3
+#define CLK_IPE_SMI_LARB12		4
+#define CLK_IPE_NR_CLK			5
+
+/* CAMSYS */
+
+#define CLK_CAM_LARB13			0
+#define CLK_CAM_LARB14			1
+#define CLK_CAM_MAIN_CAM		2
+#define CLK_CAM_MAIN_CAMTG		3
+#define CLK_CAM_SENINF			4
+#define CLK_CAM_GCAMSVA			5
+#define CLK_CAM_GCAMSVB			6
+#define CLK_CAM_GCAMSVC			7
+#define CLK_CAM_SCAMSA			8
+#define CLK_CAM_SCAMSB			9
+#define CLK_CAM_CAMSV_TOP		10
+#define CLK_CAM_CAMSV_CQ		11
+#define CLK_CAM_ADL			12
+#define CLK_CAM_ASG			13
+#define CLK_CAM_PDA			14
+#define CLK_CAM_FAKE_ENG		15
+#define CLK_CAM_MAIN_MRAW0		16
+#define CLK_CAM_MAIN_MRAW1		17
+#define CLK_CAM_MAIN_MRAW2		18
+#define CLK_CAM_MAIN_MRAW3		19
+#define CLK_CAM_CAM2MM0_GALS		20
+#define CLK_CAM_CAM2MM1_GALS		21
+#define CLK_CAM_CAM2SYS_GALS		22
+#define CLK_CAM_NR_CLK			23
+
+/* CAMSYS_RAWA */
+
+#define CLK_CAM_RAWA_LARBX		0
+#define CLK_CAM_RAWA_CAM		1
+#define CLK_CAM_RAWA_CAMTG		2
+#define CLK_CAM_RAWA_NR_CLK		3
+
+/* CAMSYS_YUVA */
+
+#define CLK_CAM_YUVA_LARBX		0
+#define CLK_CAM_YUVA_CAM		1
+#define CLK_CAM_YUVA_CAMTG		2
+#define CLK_CAM_YUVA_NR_CLK		3
+
+/* CAMSYS_RAWB */
+
+#define CLK_CAM_RAWB_LARBX		0
+#define CLK_CAM_RAWB_CAM		1
+#define CLK_CAM_RAWB_CAMTG		2
+#define CLK_CAM_RAWB_NR_CLK		3
+
+/* CAMSYS_YUVB */
+
+#define CLK_CAM_YUVB_LARBX		0
+#define CLK_CAM_YUVB_CAM		1
+#define CLK_CAM_YUVB_CAMTG		2
+#define CLK_CAM_YUVB_NR_CLK		3
+
+/* CAMSYS_MRAW */
+
+#define CLK_CAM_MRAW_LARBX		0
+#define CLK_CAM_MRAW_CAMTG		1
+#define CLK_CAM_MRAW_MRAW0		2
+#define CLK_CAM_MRAW_MRAW1		3
+#define CLK_CAM_MRAW_MRAW2		4
+#define CLK_CAM_MRAW_MRAW3		5
+#define CLK_CAM_MRAW_NR_CLK		6
+
+/* CCUSYS */
+
+#define CLK_CCU_LARB18			0
+#define CLK_CCU_AHB			1
+#define CLK_CCU_CCU0			2
+#define CLK_CCU_CCU1			3
+#define CLK_CCU_NR_CLK			4
+
+/* VDECSYS_SOC */
+
+#define CLK_VDEC_SOC_LARB1		0
+#define CLK_VDEC_SOC_LAT		1
+#define CLK_VDEC_SOC_VDEC		2
+#define CLK_VDEC_SOC_NR_CLK		3
+
+/* VDECSYS */
+
+#define CLK_VDEC_LARB1			0
+#define CLK_VDEC_LAT			1
+#define CLK_VDEC_VDEC			2
+#define CLK_VDEC_NR_CLK			3
+
+/* VDECSYS_CORE1 */
+
+#define CLK_VDEC_CORE1_LARB1		0
+#define CLK_VDEC_CORE1_LAT		1
+#define CLK_VDEC_CORE1_VDEC		2
+#define CLK_VDEC_CORE1_NR_CLK		3
+
+/* APUSYS_PLL */
+
+#define CLK_APUSYS_PLL_APUPLL		0
+#define CLK_APUSYS_PLL_NPUPLL		1
+#define CLK_APUSYS_PLL_APUPLL1		2
+#define CLK_APUSYS_PLL_APUPLL2		3
+#define CLK_APUSYS_PLL_NR_CLK		4
+
+/* VENCSYS */
+
+#define CLK_VENC_LARB			0
+#define CLK_VENC_VENC			1
+#define CLK_VENC_JPGENC			2
+#define CLK_VENC_JPGDEC			3
+#define CLK_VENC_JPGDEC_C1		4
+#define CLK_VENC_GALS			5
+#define CLK_VENC_NR_CLK			6
+
+/* VENCSYS_CORE1 */
+
+#define CLK_VENC_CORE1_LARB		0
+#define CLK_VENC_CORE1_VENC		1
+#define CLK_VENC_CORE1_JPGENC		2
+#define CLK_VENC_CORE1_JPGDEC		3
+#define CLK_VENC_CORE1_JPGDEC_C1	4
+#define CLK_VENC_CORE1_GALS		5
+#define CLK_VENC_CORE1_NR_CLK		6
+
+/* VDOSYS0 */
+
+#define CLK_VDO0_DISP_OVL0		0
+#define CLK_VDO0_DISP_COLOR0		1
+#define CLK_VDO0_DISP_COLOR1		2
+#define CLK_VDO0_DISP_CCORR0		3
+#define CLK_VDO0_DISP_CCORR1		4
+#define CLK_VDO0_DISP_AAL0		5
+#define CLK_VDO0_DISP_AAL1		6
+#define CLK_VDO0_DISP_GAMMA0		7
+#define CLK_VDO0_DISP_GAMMA1		8
+#define CLK_VDO0_DISP_DITHER0		9
+#define CLK_VDO0_DISP_DITHER1		10
+#define CLK_VDO0_DISP_OVL1		11
+#define CLK_VDO0_DISP_WDMA0		12
+#define CLK_VDO0_DISP_WDMA1		13
+#define CLK_VDO0_DISP_RDMA0		14
+#define CLK_VDO0_DISP_RDMA1		15
+#define CLK_VDO0_DSI0			16
+#define CLK_VDO0_DSI1			17
+#define CLK_VDO0_DSC_WRAP0		18
+#define CLK_VDO0_VPP_MERGE0		19
+#define CLK_VDO0_DP_INTF0		20
+#define CLK_VDO0_DISP_MUTEX0		21
+#define CLK_VDO0_DISP_IL_ROT0		22
+#define CLK_VDO0_APB_BUS		23
+#define CLK_VDO0_FAKE_ENG0		24
+#define CLK_VDO0_FAKE_ENG1		25
+#define CLK_VDO0_DL_ASYNC0		26
+#define CLK_VDO0_DL_ASYNC1		27
+#define CLK_VDO0_DL_ASYNC2		28
+#define CLK_VDO0_DL_ASYNC3		29
+#define CLK_VDO0_DL_ASYNC4		30
+#define CLK_VDO0_DISP_MONITOR0		31
+#define CLK_VDO0_DISP_MONITOR1		32
+#define CLK_VDO0_DISP_MONITOR2		33
+#define CLK_VDO0_DISP_MONITOR3		34
+#define CLK_VDO0_DISP_MONITOR4		35
+#define CLK_VDO0_SMI_GALS		36
+#define CLK_VDO0_SMI_COMMON		37
+#define CLK_VDO0_SMI_EMI		38
+#define CLK_VDO0_SMI_IOMMU		39
+#define CLK_VDO0_SMI_LARB		40
+#define CLK_VDO0_SMI_RSI		41
+#define CLK_VDO0_DSI0_DSI		42
+#define CLK_VDO0_DSI1_DSI		43
+#define CLK_VDO0_DP_INTF0_DP_INTF	44
+#define CLK_VDO0_NR_CLK			45
+
+/* VDOSYS1 */
+
+#define CLK_VDO1_SMI_LARB2			0
+#define CLK_VDO1_SMI_LARB3			1
+#define CLK_VDO1_GALS				2
+#define CLK_VDO1_FAKE_ENG0			3
+#define CLK_VDO1_FAKE_ENG			4
+#define CLK_VDO1_MDP_RDMA0			5
+#define CLK_VDO1_MDP_RDMA1			6
+#define CLK_VDO1_MDP_RDMA2			7
+#define CLK_VDO1_MDP_RDMA3			8
+#define CLK_VDO1_VPP_MERGE0			9
+#define CLK_VDO1_VPP_MERGE1			10
+#define CLK_VDO1_VPP_MERGE2			11
+#define CLK_VDO1_VPP_MERGE3			12
+#define CLK_VDO1_VPP_MERGE4			13
+#define CLK_VDO1_VPP2_TO_VDO1_DL_ASYNC		14
+#define CLK_VDO1_VPP3_TO_VDO1_DL_ASYNC		15
+#define CLK_VDO1_DISP_MUTEX			16
+#define CLK_VDO1_MDP_RDMA4			17
+#define CLK_VDO1_MDP_RDMA5			18
+#define CLK_VDO1_MDP_RDMA6			19
+#define CLK_VDO1_MDP_RDMA7			20
+#define CLK_VDO1_DP_INTF0_MM			21
+#define CLK_VDO1_DPI0_MM			22
+#define CLK_VDO1_DPI1_MM			23
+#define CLK_VDO1_DISP_MONITOR			24
+#define CLK_VDO1_MERGE0_DL_ASYNC		25
+#define CLK_VDO1_MERGE1_DL_ASYNC		26
+#define CLK_VDO1_MERGE2_DL_ASYNC		27
+#define CLK_VDO1_MERGE3_DL_ASYNC		28
+#define CLK_VDO1_MERGE4_DL_ASYNC		29
+#define CLK_VDO1_VDO0_DSC_TO_VDO1_DL_ASYNC	30
+#define CLK_VDO1_VDO0_MERGE_TO_VDO1_DL_ASYNC	31
+#define CLK_VDO1_HDR_VDO_FE0			32
+#define CLK_VDO1_HDR_GFX_FE0			33
+#define CLK_VDO1_HDR_VDO_BE			34
+#define CLK_VDO1_HDR_VDO_FE1			35
+#define CLK_VDO1_HDR_GFX_FE1			36
+#define CLK_VDO1_DISP_MIXER			37
+#define CLK_VDO1_HDR_VDO_FE0_DL_ASYNC		38
+#define CLK_VDO1_HDR_VDO_FE1_DL_ASYNC		39
+#define CLK_VDO1_HDR_GFX_FE0_DL_ASYNC		40
+#define CLK_VDO1_HDR_GFX_FE1_DL_ASYNC		41
+#define CLK_VDO1_HDR_VDO_BE_DL_ASYNC		42
+#define CLK_VDO1_DPI0				43
+#define CLK_VDO1_DISP_MONITOR_DPI0		44
+#define CLK_VDO1_DPI1				45
+#define CLK_VDO1_DISP_MONITOR_DPI1		46
+#define CLK_VDO1_DPINTF				47
+#define CLK_VDO1_DISP_MONITOR_DPINTF		48
+#define CLK_VDO1_26M_SLOW			49
+#define CLK_VDO1_NR_CLK				50
+
+#endif /* _DT_BINDINGS_CLK_MT8195_H */
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:43 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:43 +0800
Subject: [v2 03/24] clk: mediatek: Fix corner case of tuner_en_reg
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-4-chun-jie.chen@mediatek.com>

On MT8195, tuner_en_reg is moved to register offest 0x0.
If we only judge by tuner_en_reg, it may lead to wrong address.
Add tuner_en_bit to the check condition. And it has been confirmed,
on all the MediaTek SoCs, bit0 of offset 0x0 is always occupied by
clock square control.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-pll.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 7fb001a4e7d8..99ada6e06697 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -332,7 +332,7 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
 		pll->pcw_chg_addr = pll->base_addr + REG_CON1;
 	if (data->tuner_reg)
 		pll->tuner_addr = base + data->tuner_reg;
-	if (data->tuner_en_reg)
+	if (data->tuner_en_reg || data->tuner_en_bit)
 		pll->tuner_en_addr = base + data->tuner_en_reg;
 	if (data->en_reg)
 		pll->en_addr = base + data->en_reg;
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:44 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:44 +0800
Subject: [v2 04/24] clk: mediatek: Add API for clock resource recycle
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-5-chun-jie.chen@mediatek.com>

In order to avoid resource leak when fail clock registartion appears,
so add the common interface to handle it.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 9 +++++++++
 drivers/clk/mediatek/clk-mtk.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 4b6096c44d74..c3d385c0cfcb 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -43,6 +43,15 @@ struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
 	return NULL;
 }
 
+void mtk_free_clk_data(struct clk_onecell_data *clk_data)
+{
+	if (!clk_data)
+		return;
+
+	kfree(clk_data->clks);
+	kfree(clk_data);
+}
+
 void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 		int num, struct clk_onecell_data *clk_data)
 {
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 7de41c3b3206..0ff289d93452 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -202,6 +202,7 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 				struct clk_onecell_data *clk_data);
 
 struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
+void mtk_free_clk_data(struct clk_onecell_data *clk_data);
 
 #define HAVE_RST_BAR	BIT(0)
 #define PLL_AO		BIT(1)
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:45 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:45 +0800
Subject: [v2 05/24] clk: mediatek: Fix resource leak in mtk_clk_simple_probe
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-6-chun-jie.chen@mediatek.com>

Release clock data when clock driver probe fail to fix
possible resource leak.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index c3d385c0cfcb..74890759e98c 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -314,7 +314,15 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
 
 	r = mtk_clk_register_gates(node, mcd->clks, mcd->num_clks, clk_data);
 	if (r)
-		return r;
+		goto free_data;
 
-	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto free_data;
+
+	return r;
+
+free_data:
+	mtk_free_clk_data(clk_data);
+	return r;
 }
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:46 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:46 +0800
Subject: [v2 06/24] clk: mediatek: Add MT8195 apmixedsys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-7-chun-jie.chen@mediatek.com>

Add MT8195 apmixedsys clock controller which provides Plls
generated from SoC 26m and ssusb clock gate control.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Kconfig                 |   8 +
 drivers/clk/mediatek/Makefile                |   1 +
 drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 145 +++++++++++++++++++
 3 files changed, 154 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-apmixedsys.c

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 576babd86f98..7ba1f4118e0d 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -580,6 +580,14 @@ config COMMON_CLK_MT8192_VENCSYS
 	help
 	  This driver supports MediaTek MT8192 vencsys clocks.
 
+config COMMON_CLK_MT8195
+        bool "Clock driver for MediaTek MT8195"
+        depends on ARM64 || COMPILE_TEST
+        select COMMON_CLK_MEDIATEK
+        default ARM64
+        help
+          This driver supports MediaTek MT8195 basic clocks.
+
 config COMMON_CLK_MT8516
 	bool "Clock driver for MediaTek MT8516"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 15bc045f0b71..d4157cfca865 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -80,5 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
 obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
+obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
new file mode 100644
index 000000000000..253eb30b22d4
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs apmixed_cg_regs = {
+	.set_ofs = 0x8,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x8,
+};
+
+#define GATE_APMIXED(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &apmixed_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+static const struct mtk_gate apmixed_clks[] = {
+	GATE_APMIXED(CLK_APMIXED_PLL_SSUSB26M, "pll_ssusb26m", "clk26m", 1),
+};
+
+#define MT8195_PLL_FMAX		(3800UL * MHZ)
+#define MT8195_PLL_FMIN		(1500UL * MHZ)
+#define MT8195_INTEGER_BITS	8
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags,		\
+			_rst_bar_mask, _pcwbits, _pd_reg, _pd_shift,	\
+			_tuner_reg, _tuner_en_reg, _tuner_en_bit,	\
+			_pcw_reg, _pcw_shift, _pcw_chg_reg,		\
+			_en_reg, _pll_en_bit) {				\
+		.id = _id,						\
+		.name = _name,						\
+		.reg = _reg,						\
+		.pwr_reg = _pwr_reg,					\
+		.en_mask = _en_mask,					\
+		.flags = _flags,					\
+		.rst_bar_mask = _rst_bar_mask,				\
+		.fmax = MT8195_PLL_FMAX,				\
+		.fmin = MT8195_PLL_FMIN,				\
+		.pcwbits = _pcwbits,					\
+		.pcwibits = MT8195_INTEGER_BITS,			\
+		.pd_reg = _pd_reg,					\
+		.pd_shift = _pd_shift,					\
+		.tuner_reg = _tuner_reg,				\
+		.tuner_en_reg = _tuner_en_reg,				\
+		.tuner_en_bit = _tuner_en_bit,				\
+		.pcw_reg = _pcw_reg,					\
+		.pcw_shift = _pcw_shift,				\
+		.pcw_chg_reg = _pcw_chg_reg,				\
+		.en_reg = _en_reg,					\
+		.pll_en_bit = _pll_en_bit,				\
+	}
+
+static const struct mtk_pll_data plls[] = {
+	PLL(CLK_APMIXED_NNAPLL, "nnapll", 0x0390, 0x03a0, 0,
+	    0, 0, 22, 0x0398, 24, 0, 0, 0, 0x0398, 0, 0x0398, 0, 9),
+	PLL(CLK_APMIXED_RESPLL, "respll", 0x0190, 0x0320, 0,
+	    0, 0, 22, 0x0198, 24, 0, 0, 0, 0x0198, 0, 0x0198, 0, 9),
+	PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x0360, 0x0370, 0,
+	    0, 0, 22, 0x0368, 24, 0, 0, 0, 0x0368, 0, 0x0368, 0, 9),
+	PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0710, 0x0720, 0,
+	    0, 0, 22, 0x0718, 24, 0, 0, 0, 0x0718, 0, 0x0718, 0, 9),
+	PLL(CLK_APMIXED_TVDPLL1, "tvdpll1", 0x00a0, 0x00b0, 0,
+	    0, 0, 22, 0x00a8, 24, 0, 0, 0, 0x00a8, 0, 0x00a8, 0, 9),
+	PLL(CLK_APMIXED_TVDPLL2, "tvdpll2", 0x00c0, 0x00d0, 0,
+	    0, 0, 22, 0x00c8, 24, 0, 0, 0, 0x00c8, 0, 0x00c8, 0, 9),
+	PLL(CLK_APMIXED_MMPLL, "mmpll", 0x00e0, 0x00f0, 0xff000000,
+	    HAVE_RST_BAR, BIT(23), 22, 0x00e8, 24, 0, 0, 0, 0x00e8, 0, 0x00e8, 0, 9),
+	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x01d0, 0x01e0, 0xff000000,
+	    HAVE_RST_BAR, BIT(23), 22, 0x01d8, 24, 0, 0, 0, 0x01d8, 0, 0x01d8, 0, 9),
+	PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x0890, 0x08a0, 0,
+	    0, 0, 22, 0x0898, 24, 0, 0, 0, 0x0898, 0, 0x0898, 0, 9),
+	PLL(CLK_APMIXED_IMGPLL, "imgpll", 0x0100, 0x0110, 0,
+	    0, 0, 22, 0x0108, 24, 0, 0, 0, 0x0108, 0, 0x0108, 0, 9),
+	PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x01f0, 0x0700, 0xff000000,
+	    HAVE_RST_BAR, BIT(23), 22, 0x01f8, 24, 0, 0, 0, 0x01f8, 0, 0x01f8, 0, 9),
+	PLL(CLK_APMIXED_HDMIPLL1, "hdmipll1", 0x08c0, 0x08d0, 0,
+	    0, 0, 22, 0x08c8, 24, 0, 0, 0, 0x08c8, 0, 0x08c8, 0, 9),
+	PLL(CLK_APMIXED_HDMIPLL2, "hdmipll2", 0x0870, 0x0880, 0,
+	    0, 0, 22, 0x0878, 24, 0, 0, 0, 0x0878, 0, 0x0878, 0, 9),
+	PLL(CLK_APMIXED_HDMIRX_APLL, "hdmirx_apll", 0x08e0, 0x0dd4, 0,
+	    0, 0, 32, 0x08e8, 24, 0, 0, 0, 0x08ec, 0, 0x08e8, 0, 9),
+	PLL(CLK_APMIXED_USB1PLL, "usb1pll", 0x01a0, 0x01b0, 0,
+	    0, 0, 22, 0x01a8, 24, 0, 0, 0, 0x01a8, 0, 0x01a8, 0, 9),
+	PLL(CLK_APMIXED_ADSPPLL, "adsppll", 0x07e0, 0x07f0, 0,
+	    0, 0, 22, 0x07e8, 24, 0, 0, 0, 0x07e8, 0, 0x07e8, 0, 9),
+	PLL(CLK_APMIXED_APLL1, "apll1", 0x07c0, 0x0dc0, 0,
+	    0, 0, 32, 0x07c8, 24, 0x0470, 0x0000, 12, 0x07cc, 0, 0x07c8, 0, 9),
+	PLL(CLK_APMIXED_APLL2, "apll2", 0x0780, 0x0dc4, 0,
+	    0, 0, 32, 0x0788, 24, 0x0474, 0x0000, 13, 0x078c, 0, 0x0788, 0, 9),
+	PLL(CLK_APMIXED_APLL3, "apll3", 0x0760, 0x0dc8, 0,
+	    0, 0, 32, 0x0768, 24, 0x0478, 0x0000, 14, 0x076c, 0, 0x0768, 0, 9),
+	PLL(CLK_APMIXED_APLL4, "apll4", 0x0740, 0x0dcc, 0,
+	    0, 0, 32, 0x0748, 24, 0x047C, 0x0000, 15, 0x074c, 0, 0x0748, 0, 9),
+	PLL(CLK_APMIXED_APLL5, "apll5", 0x07a0, 0x0dd0, 0x100000,
+	    0, 0, 32, 0x07a8, 24, 0x0480, 0x0000, 16, 0x07ac, 0, 0x07a8, 0, 9),
+	PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x0340, 0x0350, 0,
+	    0, 0, 22, 0x0348, 24, 0, 0, 0, 0x0348, 0, 0x0348, 0, 9),
+	PLL(CLK_APMIXED_DGIPLL, "dgipll", 0x0150, 0x0160, 0,
+	    0, 0, 22, 0x0158, 24, 0, 0, 0, 0x0158, 0, 0x0158, 0, 9),
+};
+
+static const struct of_device_id of_match_clk_mt8195_apmixed[] = {
+	{ .compatible = "mediatek,mt8195-apmixedsys", },
+	{}
+};
+
+static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+	r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
+	if (r)
+		goto free_apmixed_data;
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto free_apmixed_data;
+
+	return r;
+
+free_apmixed_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static struct platform_driver clk_mt8195_apmixed_drv = {
+	.probe = clk_mt8195_apmixed_probe,
+	.driver = {
+		.name = "clk-mt8195-apmixed",
+		.of_match_table = of_match_clk_mt8195_apmixed,
+	},
+};
+builtin_platform_driver(clk_mt8195_apmixed_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:47 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:47 +0800
Subject: [v2 07/24] clk: mediatek: Add MT8195 topckgen clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-8-chun-jie.chen@mediatek.com>

Add MT8195 topckgen clock controller which provides muxes, dividers
to handle variety clock selection in other IP blocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
The changes as follow:
1. remove 1 on 1 divider
2. merge parent source data in muxes
3. add some comment if the clock is not model by CCF or has special flag
4. remove _SEL suffix in clock name
---
 drivers/clk/mediatek/Makefile              |    2 +-
 drivers/clk/mediatek/clk-mt8195-topckgen.c | 1298 ++++++++++++++++++++
 2 files changed, 1299 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-topckgen.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index d4157cfca865..a142342a0cea 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -80,6 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
 obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
-obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o
+obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-topckgen.c b/drivers/clk/mediatek/clk-mt8195-topckgen.c
new file mode 100644
index 000000000000..3cf113544f59
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-topckgen.c
@@ -0,0 +1,1298 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+static DEFINE_SPINLOCK(mt8195_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+	FIXED_CLK(CLK_TOP_IN_DGI, "in_dgi", NULL, 165000000),
+	FIXED_CLK(CLK_TOP_ULPOSC1, "ulposc1", NULL, 248000000),
+	FIXED_CLK(CLK_TOP_ULPOSC2, "ulposc2", NULL, 326000000),
+	FIXED_CLK(CLK_TOP_MEM_466M, "mem_466m", NULL, 533000000),
+	FIXED_CLK(CLK_TOP_MPHONE_SLAVE_B, "mphone_slave_b", NULL, 49152000),
+	FIXED_CLK(CLK_TOP_PEXTP_PIPE, "pextp_pipe", NULL, 250000000),
+	FIXED_CLK(CLK_TOP_UFS_RX_SYMBOL, "ufs_rx_symbol", NULL, 166000000),
+	FIXED_CLK(CLK_TOP_UFS_TX_SYMBOL, "ufs_tx_symbol", NULL, 166000000),
+	FIXED_CLK(CLK_TOP_SSUSB_U3PHY_P1_P_P0, "ssusb_u3phy_p1_p_p0", NULL, 131000000),
+	FIXED_CLK(CLK_TOP_UFS_RX_SYMBOL1, "ufs_rx_symbol1", NULL, 166000000),
+	FIXED_CLK(CLK_TOP_FPC, "fpc", NULL, 50000000),
+	FIXED_CLK(CLK_TOP_HDMIRX_P, "hdmirx_p", NULL, 594000000),
+};
+
+static const struct mtk_fixed_factor top_early_divs[] = {
+	FACTOR(CLK_TOP_CLK26M_D2, "clk26m_d2", "clk26m", 1, 2),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+	FACTOR(CLK_TOP_CLK26M_D52, "clk26m_d52", "clk26m", 1, 52),
+	FACTOR(CLK_TOP_IN_DGI_D2, "in_dgi_d2", "in_dgi", 1, 2),
+	FACTOR(CLK_TOP_IN_DGI_D4, "in_dgi_d4", "in_dgi", 1, 4),
+	FACTOR(CLK_TOP_IN_DGI_D6, "in_dgi_d6", "in_dgi", 1, 6),
+	FACTOR(CLK_TOP_IN_DGI_D8, "in_dgi_d8", "in_dgi", 1, 8),
+	FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3),
+	FACTOR(CLK_TOP_MAINPLL_D4, "mainpll_d4", "mainpll", 1, 4),
+	FACTOR(CLK_TOP_MAINPLL_D4_D2, "mainpll_d4_d2", "mainpll_d4", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D4_D4, "mainpll_d4_d4", "mainpll_d4", 1, 4),
+	FACTOR(CLK_TOP_MAINPLL_D4_D8, "mainpll_d4_d8", "mainpll_d4", 1, 8),
+	FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5),
+	FACTOR(CLK_TOP_MAINPLL_D5_D2, "mainpll_d5_d2", "mainpll_d5", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D5_D4, "mainpll_d5_d4", "mainpll_d5", 1, 4),
+	FACTOR(CLK_TOP_MAINPLL_D5_D8, "mainpll_d5_d8", "mainpll_d5", 1, 8),
+	FACTOR(CLK_TOP_MAINPLL_D6, "mainpll_d6", "mainpll", 1, 6),
+	FACTOR(CLK_TOP_MAINPLL_D6_D2, "mainpll_d6_d2", "mainpll_d6", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D6_D4, "mainpll_d6_d4", "mainpll_d6", 1, 4),
+	FACTOR(CLK_TOP_MAINPLL_D6_D8, "mainpll_d6_d8", "mainpll_d6", 1, 8),
+	FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7),
+	FACTOR(CLK_TOP_MAINPLL_D7_D2, "mainpll_d7_d2", "mainpll_d7", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D7_D4, "mainpll_d7_d4", "mainpll_d7", 1, 4),
+	FACTOR(CLK_TOP_MAINPLL_D7_D8, "mainpll_d7_d8", "mainpll_d7", 1, 8),
+	FACTOR(CLK_TOP_MAINPLL_D9, "mainpll_d9", "mainpll", 1, 9),
+	FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+	FACTOR(CLK_TOP_UNIVPLL_D4, "univpll_d4", "univpll", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_D4_D2, "univpll_d4_d2", "univpll_d4", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D4_D4, "univpll_d4_d4", "univpll_d4", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_D4_D8, "univpll_d4_d8", "univpll_d4", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+	FACTOR(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2", "univpll_d5", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4", "univpll_d5", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_D5_D8, "univpll_d5_d8", "univpll_d5", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_D6, "univpll_d6", "univpll", 1, 6),
+	FACTOR(CLK_TOP_UNIVPLL_D6_D2, "univpll_d6_d2", "univpll_d6", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D6_D4, "univpll_d6_d4", "univpll_d6", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_D6_D8, "univpll_d6_d8", "univpll_d6", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_D6_D16, "univpll_d6_d16", "univpll_d6", 1, 16),
+	FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
+	FACTOR(CLK_TOP_UNIVPLL_192M, "univpll_192m", "univpll", 1, 13),
+	FACTOR(CLK_TOP_UNIVPLL_192M_D4, "univpll_192m_d4", "univpll_192m", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_192M_D8, "univpll_192m_d8", "univpll_192m", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_192M_D16, "univpll_192m_d16", "univpll_192m", 1, 16),
+	FACTOR(CLK_TOP_UNIVPLL_192M_D32, "univpll_192m_d32", "univpll_192m", 1, 32),
+	FACTOR(CLK_TOP_APLL1_D3, "apll1_d3", "apll1", 1, 3),
+	FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1", 1, 4),
+	FACTOR(CLK_TOP_APLL2_D3, "apll2_d3", "apll2", 1, 3),
+	FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
+	FACTOR(CLK_TOP_APLL3_D4, "apll3_d4", "apll3", 1, 4),
+	FACTOR(CLK_TOP_APLL4_D4, "apll4_d4", "apll4", 1, 4),
+	FACTOR(CLK_TOP_APLL5_D4, "apll5_d4", "apll5", 1, 4),
+	FACTOR(CLK_TOP_HDMIRX_APLL_D3, "hdmirx_apll_d3", "hdmirx_apll", 1, 3),
+	FACTOR(CLK_TOP_HDMIRX_APLL_D4, "hdmirx_apll_d4", "hdmirx_apll", 1, 4),
+	FACTOR(CLK_TOP_HDMIRX_APLL_D6, "hdmirx_apll_d6", "hdmirx_apll", 1, 6),
+	FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1, 4),
+	FACTOR(CLK_TOP_MMPLL_D4_D2, "mmpll_d4_d2", "mmpll_d4", 1, 2),
+	FACTOR(CLK_TOP_MMPLL_D4_D4, "mmpll_d4_d4", "mmpll_d4", 1, 4),
+	FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
+	FACTOR(CLK_TOP_MMPLL_D5_D2, "mmpll_d5_d2", "mmpll_d5", 1, 2),
+	FACTOR(CLK_TOP_MMPLL_D5_D4, "mmpll_d5_d4", "mmpll_d5", 1, 4),
+	FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll", 1, 6),
+	FACTOR(CLK_TOP_MMPLL_D6_D2, "mmpll_d6_d2", "mmpll_d6", 1, 2),
+	FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
+	FACTOR(CLK_TOP_MMPLL_D9, "mmpll_d9", "mmpll", 1, 9),
+	FACTOR(CLK_TOP_TVDPLL1_D2, "tvdpll1_d2", "tvdpll1", 1, 2),
+	FACTOR(CLK_TOP_TVDPLL1_D4, "tvdpll1_d4", "tvdpll1", 1, 4),
+	FACTOR(CLK_TOP_TVDPLL1_D8, "tvdpll1_d8", "tvdpll1", 1, 8),
+	FACTOR(CLK_TOP_TVDPLL1_D16, "tvdpll1_d16", "tvdpll1", 1, 16),
+	FACTOR(CLK_TOP_TVDPLL2_D2, "tvdpll2_d2", "tvdpll2", 1, 2),
+	FACTOR(CLK_TOP_TVDPLL2_D4, "tvdpll2_d4", "tvdpll2", 1, 4),
+	FACTOR(CLK_TOP_TVDPLL2_D8, "tvdpll2_d8", "tvdpll2", 1, 8),
+	FACTOR(CLK_TOP_TVDPLL2_D16, "tvdpll2_d16", "tvdpll2", 1, 16),
+	FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
+	FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
+	FACTOR(CLK_TOP_MSDCPLL_D16, "msdcpll_d16", "msdcpll", 1, 16),
+	FACTOR(CLK_TOP_ETHPLL_D2, "ethpll_d2", "ethpll", 1, 2),
+	FACTOR(CLK_TOP_ETHPLL_D8, "ethpll_d8", "ethpll", 1, 8),
+	FACTOR(CLK_TOP_ETHPLL_D10, "ethpll_d10", "ethpll", 1, 10),
+	FACTOR(CLK_TOP_DGIPLL_D2, "dgipll_d2", "dgipll", 1, 2),
+	FACTOR(CLK_TOP_ULPOSC1_D2, "ulposc1_d2", "ulposc1", 1, 2),
+	FACTOR(CLK_TOP_ULPOSC1_D4, "ulposc1_d4", "ulposc1", 1, 4),
+	FACTOR(CLK_TOP_ULPOSC1_D7, "ulposc1_d7", "ulposc1", 1, 7),
+	FACTOR(CLK_TOP_ULPOSC1_D8, "ulposc1_d8", "ulposc1", 1, 8),
+	FACTOR(CLK_TOP_ULPOSC1_D10, "ulposc1_d10", "ulposc1", 1, 10),
+	FACTOR(CLK_TOP_ULPOSC1_D16, "ulposc1_d16", "ulposc1", 1, 16),
+	FACTOR(CLK_TOP_ADSPPLL_D2, "adsppll_d2", "adsppll", 1, 2),
+	FACTOR(CLK_TOP_ADSPPLL_D4, "adsppll_d4", "adsppll", 1, 4),
+	FACTOR(CLK_TOP_ADSPPLL_D8, "adsppll_d8", "adsppll", 1, 8),
+};
+
+static const char * const axi_parents[] = {
+	"clk26m",
+	"mainpll_d4_d4",
+	"mainpll_d7_d2",
+	"mainpll_d4_d2",
+	"mainpll_d5_d2",
+	"mainpll_d6_d2",
+	"ulposc1_d4"
+};
+
+static const char * const spm_parents[] = {
+	"clk26m",
+	"ulposc1_d10",
+	"mainpll_d7_d4",
+	"clk32k"
+};
+
+static const char * const scp_parents[] = {
+	"clk26m",
+	"univpll_d4",
+	"mainpll_d6",
+	"univpll_d6",
+	"univpll_d4_d2",
+	"mainpll_d4_d2",
+	"mainpll_d4",
+	"mainpll_d6_d2"
+};
+
+static const char * const bus_aximem_parents[] = {
+	"clk26m",
+	"mainpll_d7_d2",
+	"mainpll_d4_d2",
+	"mainpll_d5_d2",
+	"mainpll_d6"
+};
+
+static const char * const vpp_parents[] = {
+	"clk26m",
+	"univpll_d6_d2",
+	"mainpll_d5_d2",
+	"mmpll_d6_d2",
+	"univpll_d5_d2",
+	"univpll_d4_d2",
+	"mmpll_d4_d2",
+	"mmpll_d7",
+	"univpll_d6",
+	"mainpll_d4",
+	"mmpll_d5",
+	"tvdpll1",
+	"tvdpll2",
+	"univpll_d4",
+	"mmpll_d4"
+};
+
+static const char * const ethdr_parents[] = {
+	"clk26m",
+	"univpll_d6_d2",
+	"mainpll_d5_d2",
+	"mmpll_d6_d2",
+	"univpll_d5_d2",
+	"univpll_d4_d2",
+	"mmpll_d4_d2",
+	"mmpll_d7",
+	"univpll_d6",
+	"mainpll_d4",
+	"mmpll_d5_d4",
+	"tvdpll1",
+	"tvdpll2",
+	"univpll_d4",
+	"mmpll_d4"
+};
+
+static const char * const ipe_parents[] = {
+	"clk26m",
+	"imgpll",
+	"mainpll_d4",
+	"mmpll_d6",
+	"univpll_d6",
+	"mainpll_d6",
+	"mmpll_d4_d2",
+	"univpll_d4_d2",
+	"mainpll_d4_d2",
+	"mmpll_d6_d2",
+	"univpll_d5_d2"
+};
+
+static const char * const cam_parents[] = {
+	"clk26m",
+	"mainpll_d4",
+	"mmpll_d4",
+	"univpll_d4",
+	"univpll_d5",
+	"univpll_d6",
+	"mmpll_d7",
+	"univpll_d4_d2",
+	"mainpll_d4_d2",
+	"imgpll"
+};
+
+static const char * const ccu_parents[] = {
+	"clk26m",
+	"univpll_d6",
+	"mainpll_d4_d2",
+	"mainpll_d4",
+	"univpll_d5",
+	"mainpll_d6",
+	"mmpll_d6",
+	"mmpll_d7",
+	"univpll_d4_d2",
+	"univpll_d7"
+};
+
+static const char * const img_parents[] = {
+	"clk26m",
+	"imgpll",
+	"univpll_d4",
+	"mainpll_d4",
+	"univpll_d5",
+	"mmpll_d6",
+	"univpll_d6",
+	"mainpll_d6",
+	"mmpll_d4_d2",
+	"univpll_d4_d2",
+	"mainpll_d4_d2",
+	"univpll_d5_d2"
+};
+
+static const char * const camtm_parents[] = {
+	"clk26m",
+	"univpll_d4_d4",
+	"univpll_d6_d2",
+	"univpll_d6_d4"
+};
+
+static const char * const dsp_parents[] = {
+	"clk26m",
+	"univpll_d6_d2",
+	"univpll_d4_d2",
+	"univpll_d5",
+	"univpll_d4",
+	"mmpll_d4",
+	"mainpll_d3",
+	"univpll_d3"
+};
+
+static const char * const dsp1_parents[] = {
+	"clk26m",
+	"univpll_d6_d2",
+	"mainpll_d4_d2",
+	"univpll_d5",
+	"mmpll_d5",
+	"univpll_d4",
+	"mainpll_d3",
+	"univpll_d3"
+};
+
+static const char * const dsp2_parents[] = {
+	"clk26m",
+	"univpll_d6_d2",
+	"univpll_d4_d2",
+	"mainpll_d4",
+	"univpll_d4",
+	"mmpll_d4",
+	"mainpll_d3",
+	"univpll_d3"
+};
+
+static const char * const dsp3_parents[] = {
+	"clk26m",
+	"univpll_d6_d2",
+	"univpll_d4_d2",
+	"univpll_d5",
+	"univpll_d4",
+	"mmpll_d4",
+	"mainpll_d3",
+	"univpll_d3"
+};
+
+static const char * const ipu_if_parents[] = {
+	"clk26m",
+	"univpll_d6_d2",
+	"univpll_d5_d2",
+	"mainpll_d4_d2",
+	"mainpll_d6",
+	"univpll_d5",
+	"univpll_d4",
+	"mmpll_d4"
+};
+
+static const char * const mfg_parents[] = {
+	"clk26m",
+	"mainpll_d5_d2",
+	"univpll_d6",
+	"univpll_d7"
+};
+
+static const char * const camtg_parents[] = {
+	"clk26m",
+	"univpll_192m_d8",
+	"univpll_d6_d8",
+	"univpll_192m_d4",
+	"univpll_d6_d16",
+	"clk26m_d2",
+	"univpll_192m_d16",
+	"univpll_192m_d32"
+};
+
+static const char * const uart_parents[] = {
+	"clk26m",
+	"univpll_d6_d8"
+};
+
+static const char * const spi_parents[] = {
+	"clk26m",
+	"mainpll_d5_d4",
+	"mainpll_d6_d4",
+	"msdcpll_d4",
+	"univpll_d6_d2",
+	"mainpll_d6_d2",
+	"mainpll_d4_d4",
+	"univpll_d5_d4"
+};
+
+static const char * const spis_parents[] = {
+	"clk26m",
+	"univpll_d6",
+	"mainpll_d6",
+	"univpll_d4_d2",
+	"univpll_d6_d2",
+	"univpll_d4_d4",
+	"univpll_d6_d4",
+	"mainpll_d7_d4"
+};
+
+static const char * const msdc50_0_h_parents[] = {
+	"clk26m",
+	"mainpll_d4_d2",
+	"mainpll_d6_d2"
+};
+
+static const char * const msdc50_0_parents[] = {
+	"clk26m",
+	"msdcpll",
+	"msdcpll_d2",
+	"univpll_d4_d4",
+	"mainpll_d6_d2",
+	"univpll_d4_d2"
+};
+
+static const char * const msdc30_parents[] = {
+	"clk26m",
+	"univpll_d6_d2",
+	"mainpll_d6_d2",
+	"mainpll_d7_d2",
+	"msdcpll_d2"
+};
+
+static const char * const intdir_parents[] = {
+	"clk26m",
+	"univpll_d6",
+	"mainpll_d4",
+	"univpll_d4"
+};
+
+static const char * const aud_intbus_parents[] = {
+	"clk26m",
+	"mainpll_d4_d4",
+	"mainpll_d7_d4"
+};
+
+static const char * const audio_h_parents[] = {
+	"clk26m",
+	"univpll_d7",
+	"apll1",
+	"apll2"
+};
+
+static const char * const pwrap_ulposc_parents[] = {
+	"ulposc1_d10",
+	"clk26m",
+	"ulposc1_d4",
+	"ulposc1_d7",
+	"ulposc1_d8",
+	"ulposc1_d16",
+	"mainpll_d4_d8",
+	"univpll_d5_d8"
+};
+
+static const char * const atb_parents[] = {
+	"clk26m",
+	"mainpll_d4_d2",
+	"mainpll_d5_d2"
+};
+
+static const char * const pwrmcu_parents[] = {
+	"clk26m",
+	"mainpll_d7_d2",
+	"mainpll_d6_d2",
+	"mainpll_d5_d2",
+	"mainpll_d9",
+	"mainpll_d4_d2"
+};
+
+static const char * const dp_parents[] = {
+	"clk26m",
+	"tvdpll1_d2",
+	"tvdpll2_d2",
+	"tvdpll1_d4",
+	"tvdpll2_d4",
+	"tvdpll1_d8",
+	"tvdpll2_d8",
+	"tvdpll1_d16",
+	"tvdpll2_d16"
+};
+
+static const char * const disp_pwm_parents[] = {
+	"clk26m",
+	"univpll_d6_d4",
+	"ulposc1_d2",
+	"ulposc1_d4",
+	"ulposc1_d16"
+};
+
+static const char * const usb_parents[] = {
+	"clk26m",
+	"univpll_d5_d4",
+	"univpll_d6_d4",
+	"univpll_d5_d2"
+};
+
+static const char * const i2c_parents[] = {
+	"clk26m",
+	"mainpll_d4_d8",
+	"univpll_d5_d4"
+};
+
+static const char * const seninf_parents[] = {
+	"clk26m",
+	"univpll_d4_d4",
+	"univpll_d6_d2",
+	"univpll_d4_d2",
+	"univpll_d7",
+	"univpll_d6",
+	"mmpll_d6",
+	"univpll_d5"
+};
+
+static const char * const gcpu_parents[] = {
+	"clk26m",
+	"mainpll_d6",
+	"univpll_d4_d2",
+	"mmpll_d5_d2",
+	"univpll_d5_d2"
+};
+
+static const char * const dxcc_parents[] = {
+	"clk26m",
+	"mainpll_d4_d2",
+	"mainpll_d4_d4",
+	"mainpll_d4_d8"
+};
+
+static const char * const dpmaif_parents[] = {
+	"clk26m",
+	"univpll_d4_d4",
+	"mainpll_d6",
+	"mainpll_d4_d2",
+	"univpll_d4_d2"
+};
+
+static const char * const aes_fde_parents[] = {
+	"clk26m",
+	"mainpll_d4_d2",
+	"mainpll_d6",
+	"mainpll_d4_d4",
+	"univpll_d4_d2",
+	"univpll_d6"
+};
+
+static const char * const ufs_parents[] = {
+	"clk26m",
+	"mainpll_d4_d4",
+	"mainpll_d4_d8",
+	"univpll_d4_d4",
+	"mainpll_d6_d2",
+	"univpll_d6_d2",
+	"msdcpll_d2"
+};
+
+static const char * const ufs_tick1us_parents[] = {
+	"clk26m_d52",
+	"clk26m"
+};
+
+static const char * const ufs_mp_sap_parents[] = {
+	"clk26m",
+	"msdcpll_d16"
+};
+
+static const char * const venc_parents[] = {
+	"clk26m",
+	"mmpll_d4_d2",
+	"mainpll_d6",
+	"univpll_d4_d2",
+	"mainpll_d4_d2",
+	"univpll_d6",
+	"mmpll_d6",
+	"mainpll_d5_d2",
+	"mainpll_d6_d2",
+	"mmpll_d9",
+	"univpll_d4_d4",
+	"mainpll_d4",
+	"univpll_d4",
+	"univpll_d5",
+	"univpll_d5_d2",
+	"mainpll_d5"
+};
+
+static const char * const vdec_parents[] = {
+	"clk26m",
+	"mainpll_d5_d2",
+	"mmpll_d6_d2",
+	"univpll_d4_d2",
+	"mmpll_d4_d2",
+	"mainpll_d5",
+	"mmpll_d6",
+	"mmpll_d5",
+	"vdecpll",
+	"univpll_d4",
+	"mmpll_d4",
+	"univpll_d6_d2",
+	"mmpll_d9",
+	"univpll_d6",
+	"univpll_d5",
+	"mainpll_d4"
+};
+
+static const char * const pwm_parents[] = {
+	"clk26m",
+	"univpll_d4_d8"
+};
+
+static const char * const mcupm_parents[] = {
+	"clk26m",
+	"mainpll_d6_d2",
+	"mainpll_d7_d4",
+};
+
+static const char * const spmi_parents[] = {
+	"clk26m",
+	"clk26m_d2",
+	"ulposc1_d8",
+	"ulposc1_d10",
+	"ulposc1_d16",
+	"ulposc1_d7",
+	"clk32k",
+	"mainpll_d7_d8",
+	"mainpll_d6_d8",
+	"mainpll_d5_d8"
+};
+
+static const char * const dvfsrc_parents[] = {
+	"clk26m",
+	"ulposc1_d10",
+	"univpll_d6_d8",
+	"msdcpll_d16"
+};
+
+static const char * const tl_parents[] = {
+	"clk26m",
+	"univpll_d5_d4",
+	"mainpll_d4_d4"
+};
+
+static const char * const dsi_occ_parents[] = {
+	"clk26m",
+	"mainpll_d6_d2",
+	"univpll_d5_d2",
+	"univpll_d4_d2"
+};
+
+static const char * const wpe_vpp_parents[] = {
+	"clk26m",
+	"mainpll_d5_d2",
+	"mmpll_d6_d2",
+	"univpll_d5_d2",
+	"mainpll_d4_d2",
+	"univpll_d4_d2",
+	"mmpll_d4_d2",
+	"mainpll_d6",
+	"mmpll_d7",
+	"univpll_d6",
+	"mainpll_d5",
+	"univpll_d5",
+	"mainpll_d4",
+	"tvdpll1",
+	"univpll_d4"
+};
+
+static const char * const hdcp_parents[] = {
+	"clk26m",
+	"univpll_d4_d8",
+	"mainpll_d5_d8",
+	"univpll_d6_d4"
+};
+
+static const char * const hdcp_24m_parents[] = {
+	"clk26m",
+	"univpll_192m_d4",
+	"univpll_192m_d8",
+	"univpll_d6_d8"
+};
+
+static const char * const hd20_dacr_ref_parents[] = {
+	"clk26m",
+	"univpll_d4_d2",
+	"univpll_d4_d4",
+	"univpll_d4_d8"
+};
+
+static const char * const hd20_hdcp_c_parents[] = {
+	"clk26m",
+	"msdcpll_d4",
+	"univpll_d4_d8",
+	"univpll_d6_d8"
+};
+
+static const char * const hdmi_xtal_parents[] = {
+	"clk26m",
+	"clk26m_d2"
+};
+
+static const char * const hdmi_apb_parents[] = {
+	"clk26m",
+	"univpll_d6_d4",
+	"msdcpll_d2"
+};
+
+static const char * const snps_eth_250m_parents[] = {
+	"clk26m",
+	"ethpll_d2"
+};
+
+static const char * const snps_eth_62p4m_ptp_parents[] = {
+	"apll2_d3",
+	"apll1_d3",
+	"clk26m",
+	"ethpll_d8"
+};
+
+static const char * const snps_eth_50m_rmii_parents[] = {
+	"clk26m",
+	"ethpll_d10"
+};
+
+static const char * const dgi_out_parents[] = {
+	"clk26m",
+	"dgipll",
+	"dgipll_d2",
+	"in_dgi",
+	"in_dgi_d2",
+	"mmpll_d4_d4"
+};
+
+static const char * const nna_parents[] = {
+	"clk26m",
+	"nnapll",
+	"univpll_d4",
+	"mainpll_d4",
+	"univpll_d5",
+	"mmpll_d6",
+	"univpll_d6",
+	"mainpll_d6",
+	"mmpll_d4_d2",
+	"univpll_d4_d2",
+	"mainpll_d4_d2",
+	"mmpll_d6_d2"
+};
+
+static const char * const adsp_parents[] = {
+	"clk26m",
+	"clk26m_d2",
+	"mainpll_d6",
+	"mainpll_d5_d2",
+	"univpll_d4_d4",
+	"univpll_d4",
+	"univpll_d6",
+	"ulposc1",
+	"adsppll",
+	"adsppll_d2",
+	"adsppll_d4",
+	"adsppll_d8"
+};
+
+static const char * const asm_parents[] = {
+	"clk26m",
+	"univpll_d6_d4",
+	"univpll_d6_d2",
+	"mainpll_d5_d2"
+};
+
+static const char * const apll1_parents[] = {
+	"clk26m",
+	"apll1_d4"
+};
+
+static const char * const apll2_parents[] = {
+	"clk26m",
+	"apll2_d4"
+};
+
+static const char * const apll3_parents[] = {
+	"clk26m",
+	"apll3_d4"
+};
+
+static const char * const apll4_parents[] = {
+	"clk26m",
+	"apll4_d4"
+};
+
+static const char * const apll5_parents[] = {
+	"clk26m",
+	"apll5_d4"
+};
+
+static const char * const i2s_parents[] = {
+	"clk26m",
+	"apll1",
+	"apll2",
+	"apll3",
+	"apll4",
+	"apll5",
+	"hdmirx_apll"
+};
+
+static const char * const a1sys_hp_parents[] = {
+	"clk26m",
+	"apll1_d4"
+};
+
+static const char * const a2sys_parents[] = {
+	"clk26m",
+	"apll2_d4"
+};
+
+static const char * const a3sys_parents[] = {
+	"clk26m",
+	"apll3_d4",
+	"apll4_d4",
+	"apll5_d4",
+	"hdmirx_apll_d3",
+	"hdmirx_apll_d4",
+	"hdmirx_apll_d6"
+};
+
+static const char * const spinfi_b_parents[] = {
+	"clk26m",
+	"univpll_d6_d8",
+	"univpll_d5_d8",
+	"mainpll_d4_d8",
+	"mainpll_d7_d4",
+	"mainpll_d6_d4",
+	"univpll_d6_d4",
+	"univpll_d5_d4"
+};
+
+static const char * const nfi1x_parents[] = {
+	"clk26m",
+	"univpll_d5_d4",
+	"mainpll_d7_d4",
+	"mainpll_d6_d4",
+	"univpll_d6_d4",
+	"mainpll_d4_d4",
+	"mainpll_d7_d2",
+	"mainpll_d6_d2"
+};
+
+static const char * const ecc_parents[] = {
+	"clk26m",
+	"mainpll_d4_d4",
+	"mainpll_d5_d2",
+	"mainpll_d4_d2",
+	"mainpll_d6",
+	"univpll_d6"
+};
+
+static const char * const audio_local_bus_parents[] = {
+	"clk26m",
+	"clk26m_d2",
+	"mainpll_d4_d4",
+	"mainpll_d7_d2",
+	"mainpll_d4_d2",
+	"mainpll_d5_d2",
+	"mainpll_d6_d2",
+	"mainpll_d7",
+	"univpll_d6",
+	"ulposc1",
+	"ulposc1_d4",
+	"ulposc1_d2"
+};
+
+static const char * const spinor_parents[] = {
+	"clk26m",
+	"clk26m_d2",
+	"mainpll_d7_d8",
+	"univpll_d6_d8"
+};
+
+static const char * const dvio_dgi_ref_parents[] = {
+	"clk26m",
+	"in_dgi",
+	"in_dgi_d2",
+	"in_dgi_d4",
+	"in_dgi_d6",
+	"in_dgi_d8",
+	"mmpll_d4_d4"
+};
+
+static const char * const ulposc_parents[] = {
+	"ulposc1",
+	"ethpll_d2",
+	"mainpll_d4_d2",
+	"ethpll_d10"
+};
+
+static const char * const ulposc_core_parents[] = {
+	"ulposc2",
+	"univpll_d7",
+	"mainpll_d6",
+	"ethpll_d10"
+};
+
+static const char * const srck_parents[] = {
+	"ulposc1_d10",
+	"clk26m"
+};
+
+static const char * const mfg_fast_parents[] = {
+	"top_mfg_core_tmp",
+	"mfgpll"
+};
+
+static const struct mtk_mux top_mtk_muxes[] = {
+	/*
+	 * CLK_CFG_0
+	 * top_axi and top_bus_aximem are bus clocks, should not be closed by Linux.
+	 * top_spm and top_scp are main clocks in always-on co-processor.
+	 */
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI, "top_axi",
+		axi_parents, 0x020, 0x024, 0x028, 0, 3, 7, 0x04, 0, CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM, "top_spm",
+		spm_parents, 0x020, 0x024, 0x028, 8, 2, 15, 0x04, 1, CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SCP, "top_scp",
+		scp_parents, 0x020, 0x024, 0x028, 16, 3, 23, 0x04, 2, CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_BUS_AXIMEM, "top_bus_aximem",
+		bus_aximem_parents, 0x020, 0x024, 0x028, 24, 3, 31, 0x04, 3, CLK_IS_CRITICAL),
+	/* CLK_CFG_1 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_VPP, "top_vpp",
+		vpp_parents, 0x02C, 0x030, 0x034, 0, 4, 7, 0x04, 4),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ETHDR, "top_ethdr",
+		ethdr_parents, 0x02C, 0x030, 0x034, 8, 4, 15, 0x04, 5),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_IPE, "top_ipe",
+		ipe_parents, 0x02C, 0x030, 0x034, 16, 4, 23, 0x04, 6),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAM, "top_cam",
+		cam_parents, 0x02C, 0x030, 0x034, 24, 4, 31, 0x04, 7),
+	/* CLK_CFG_2 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CCU, "top_ccu",
+		ccu_parents, 0x038, 0x03C, 0x040, 0, 4, 7, 0x04, 8),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG, "top_img",
+		img_parents, 0x038, 0x03C, 0x040, 8, 4, 15, 0x04, 9),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM, "top_camtm",
+		camtm_parents, 0x038, 0x03C, 0x040, 16, 2, 23, 0x04, 10),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP, "top_dsp",
+		dsp_parents, 0x038, 0x03C, 0x040, 24, 3, 31, 0x04, 11),
+	/* CLK_CFG_3 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP1, "top_dsp1",
+		dsp1_parents, 0x044, 0x048, 0x04C, 0, 3, 7, 0x04, 12),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP2, "top_dsp2",
+		dsp1_parents, 0x044, 0x048, 0x04C, 8, 3, 15, 0x04, 13),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP3, "top_dsp3",
+		dsp1_parents, 0x044, 0x048, 0x04C, 16, 3, 23, 0x04, 14),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP4, "top_dsp4",
+		dsp2_parents, 0x044, 0x048, 0x04C, 24, 3, 31, 0x04, 15),
+	/* CLK_CFG_4 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP5, "top_dsp5",
+		dsp2_parents, 0x050, 0x054, 0x058, 0, 3, 7, 0x04, 16),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP6, "top_dsp6",
+		dsp2_parents, 0x050, 0x054, 0x058, 8, 3, 15, 0x04, 17),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP7, "top_dsp7",
+		dsp3_parents, 0x050, 0x054, 0x058, 16, 3, 23, 0x04, 18),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_IPU_IF, "top_ipu_if",
+		ipu_if_parents, 0x050, 0x054, 0x058, 24, 3, 31, 0x04, 19),
+	/* CLK_CFG_5 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_CORE_TMP, "top_mfg_core_tmp",
+		mfg_parents, 0x05C, 0x060, 0x064, 0, 2, 7, 0x04, 20),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG, "top_camtg",
+		camtg_parents, 0x05C, 0x060, 0x064, 8, 3, 15, 0x04, 21),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2, "top_camtg2",
+		camtg_parents, 0x05C, 0x060, 0x064, 16, 3, 23, 0x04, 22),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3, "top_camtg3",
+		camtg_parents, 0x05C, 0x060, 0x064, 24, 3, 31, 0x04, 23),
+	/* CLK_CFG_6 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG4, "top_camtg4",
+		camtg_parents, 0x068, 0x06C, 0x070, 0, 3, 7, 0x04, 24),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG5, "top_camtg5",
+		camtg_parents, 0x068, 0x06C, 0x070, 8, 3, 15, 0x04, 25),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_UART, "top_uart",
+		uart_parents, 0x068, 0x06C, 0x070, 16, 1, 23, 0x04, 26),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI, "top_spi",
+		spi_parents, 0x068, 0x06C, 0x070, 24, 3, 31, 0x04, 27),
+	/* CLK_CFG_7 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIS, "top_spis",
+		spis_parents, 0x074, 0x078, 0x07C, 0, 3, 7, 0x04, 28),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_HCLK, "top_msdc50_0_hclk",
+		msdc50_0_h_parents, 0x074, 0x078, 0x07C, 8, 2, 15, 0x04, 29),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0, "top_msdc50_0",
+		msdc50_0_parents, 0x074, 0x078, 0x07C, 16, 3, 23, 0x04, 30),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1, "top_msdc30_1",
+		msdc30_parents, 0x074, 0x078, 0x07C, 24, 3, 31, 0x04, 31),
+	/* CLK_CFG_8 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_2, "top_msdc30_2",
+		msdc30_parents, 0x080, 0x084, 0x088, 0, 3, 7, 0x08, 0),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_INTDIR, "top_intdir",
+		intdir_parents, 0x080, 0x084, 0x088, 8, 2, 15, 0x08, 1),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS, "top_aud_intbus",
+		aud_intbus_parents, 0x080, 0x084, 0x088, 16, 2, 23, 0x08, 2),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_H, "top_audio_h",
+		audio_h_parents, 0x080, 0x084, 0x088, 24, 2, 31, 0x08, 3),
+	/*
+	 * CLK_CFG_9
+	 * top_pwrmcu is main clock in other co-processor, should not be
+	 * handled by Linux.
+	 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PWRAP_ULPOSC, "top_pwrap_ulposc",
+		pwrap_ulposc_parents, 0x08C, 0x090, 0x094, 0, 3, 7, 0x08, 4),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB, "top_atb",
+		atb_parents, 0x08C, 0x090, 0x094, 8, 2, 15, 0x08, 5),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_PWRMCU, "top_pwrmcu",
+		pwrmcu_parents, 0x08C, 0x090, 0x094, 16, 3, 23, 0x08, 6, CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DP, "top_dp",
+		dp_parents, 0x08C, 0x090, 0x094, 24, 4, 31, 0x08, 7),
+	/* CLK_CFG_10 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_EDP, "top_edp",
+		dp_parents, 0x098, 0x09C, 0x0A0, 0, 4, 7, 0x08, 8),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI, "top_dpi",
+		dp_parents, 0x098, 0x09C, 0x0A0, 8, 4, 15, 0x08, 9),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM0, "top_disp_pwm0",
+		disp_pwm_parents, 0x098, 0x09C, 0x0A0, 16, 3, 23, 0x08, 10),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM1, "top_disp_pwm1",
+		disp_pwm_parents, 0x098, 0x09C, 0x0A0, 24, 3, 31, 0x08, 11),
+	/* CLK_CFG_11 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP, "top_usb_top",
+		usb_parents, 0x0A4, 0x0A8, 0x0AC, 0, 2, 7, 0x08, 12),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI, "top_ssusb_xhci",
+		usb_parents, 0x0A4, 0x0A8, 0x0AC, 8, 2, 15, 0x08, 13),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP_1P, "top_usb_top_1p",
+		usb_parents, 0x0A4, 0x0A8, 0x0AC, 16, 2, 23, 0x08, 14),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_1P, "top_ssusb_xhci_1p",
+		usb_parents, 0x0A4, 0x0A8, 0x0AC, 24, 2, 31, 0x08, 15),
+	/* CLK_CFG_12 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP_2P, "top_usb_top_2p",
+		usb_parents, 0x0B0, 0x0B4, 0x0B8, 0, 2, 7, 0x08, 16),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_2P, "top_ssusb_xhci_2p",
+		usb_parents, 0x0B0, 0x0B4, 0x0B8, 8, 2, 15, 0x08, 17),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP_3P, "top_usb_top_3p",
+		usb_parents, 0x0B0, 0x0B4, 0x0B8, 16, 2, 23, 0x08, 18),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_3P, "top_ssusb_xhci_3p",
+		usb_parents, 0x0B0, 0x0B4, 0x0B8, 24, 2, 31, 0x08, 19),
+	/* CLK_CFG_13 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C, "top_i2c",
+		i2c_parents, 0x0BC, 0x0C0, 0x0C4, 0, 2, 7, 0x08, 20),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF, "top_seninf",
+		seninf_parents, 0x0BC, 0x0C0, 0x0C4, 8, 3, 15, 0x08, 21),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1, "top_seninf1",
+		seninf_parents, 0x0BC, 0x0C0, 0x0C4, 16, 3, 23, 0x08, 22),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2, "top_seninf2",
+		seninf_parents, 0x0BC, 0x0C0, 0x0C4, 24, 3, 31, 0x08, 23),
+	/* CLK_CFG_14 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF3, "top_seninf3",
+		seninf_parents, 0x0C8, 0x0CC, 0x0D0, 0, 3, 7, 0x08, 24),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_GCPU, "top_gcpu",
+		gcpu_parents, 0x0C8, 0x0CC, 0x0D0, 8, 3, 15, 0x08, 25),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC, "top_dxcc",
+		dxcc_parents, 0x0C8, 0x0CC, 0x0D0, 16, 2, 23, 0x08, 26),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DPMAIF_MAIN, "top_dpmaif_main",
+		dpmaif_parents, 0x0C8, 0x0CC, 0x0D0, 24, 3, 31, 0x08, 27),
+	/* CLK_CFG_15 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_UFSFDE, "top_aes_ufsfde",
+		aes_fde_parents, 0x0D4, 0x0D8, 0x0DC, 0, 3, 7, 0x08, 28),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS, "top_ufs",
+		ufs_parents, 0x0D4, 0x0D8, 0x0DC, 8, 3, 15, 0x08, 29),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS_TICK1US, "top_ufs_tick1us",
+		ufs_tick1us_parents, 0x0D4, 0x0D8, 0x0DC, 16, 1, 23, 0x08, 30),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS_MP_SAP_CFG, "top_ufs_mp_sap_cfg",
+		ufs_mp_sap_parents, 0x0D4, 0x0D8, 0x0DC, 24, 1, 31, 0x08, 31),
+	/*
+	 * CLK_CFG_16
+	 * top_mcupm is main clock in other co-processor, should not be
+	 * handled by Linux.
+	 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_VENC, "top_venc",
+		venc_parents, 0x0E0, 0x0E4, 0x0E8, 0, 4, 7, 0x0C, 0),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC, "top_vdec",
+		vdec_parents, 0x0E0, 0x0E4, 0x0E8, 8, 4, 15, 0x0C, 1),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM, "top_pwm",
+		pwm_parents, 0x0E0, 0x0E4, 0x0E8, 16, 1, 23, 0x0C, 2),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_MCUPM, "top_mcupm",
+		mcupm_parents, 0x0E0, 0x0E4, 0x0E8, 24, 2, 31, 0x0C, 3, CLK_IS_CRITICAL),
+	/*
+	 * CLK_CFG_17
+	 * top_dvfsrc is for internal DVFS usage, should not be handled by Linux.
+	 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_P_MST, "top_spmi_p_mst",
+		spmi_parents, 0x0EC, 0x0F0, 0x0F4, 0, 4, 7, 0x0C, 4),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_M_MST, "top_spmi_m_mst",
+		spmi_parents, 0x0EC, 0x0F0, 0x0F4, 8, 4, 15, 0x0C, 5),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DVFSRC, "top_dvfsrc",
+		dvfsrc_parents, 0x0EC, 0x0F0, 0x0F4, 16, 2, 23, 0x0C, 6, CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_TL, "top_tl",
+		tl_parents, 0x0EC, 0x0F0, 0x0F4, 24, 2, 31, 0x0C, 7),
+	/* CLK_CFG_18 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_TL_P1, "top_tl_p1",
+		tl_parents, 0x0F8, 0x0FC, 0x0100, 0, 2, 7, 0x0C, 8),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_MSDCFDE, "top_aes_msdcfde",
+		aes_fde_parents, 0x0F8, 0x0FC, 0x0100, 8, 3, 15, 0x0C, 9),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSI_OCC, "top_dsi_occ",
+		dsi_occ_parents, 0x0F8, 0x0FC, 0x0100, 16, 2, 23, 0x0C, 10),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_WPE_VPP, "top_wpe_vpp",
+		wpe_vpp_parents, 0x0F8, 0x0FC, 0x0100, 24, 4, 31, 0x0C, 11),
+	/* CLK_CFG_19 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_HDCP, "top_hdcp",
+		hdcp_parents, 0x0104, 0x0108, 0x010C, 0, 2, 7, 0x0C, 12),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_HDCP_24M, "top_hdcp_24m",
+		hdcp_24m_parents, 0x0104, 0x0108, 0x010C, 8, 2, 15, 0x0C, 13),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_HD20_DACR_REF_CLK, "top_hd20_dacr_ref_clk",
+		hd20_dacr_ref_parents, 0x0104, 0x0108, 0x010C, 16, 2, 23, 0x0C, 14),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_HD20_HDCP_CCLK, "top_hd20_hdcp_cclk",
+		hd20_hdcp_c_parents, 0x0104, 0x0108, 0x010C, 24, 2, 31, 0x0C, 15),
+	/* CLK_CFG_20 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_HDMI_XTAL, "top_hdmi_xtal",
+		hdmi_xtal_parents, 0x0110, 0x0114, 0x0118, 0, 1, 7, 0x0C, 16),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_HDMI_APB, "top_hdmi_apb",
+		hdmi_apb_parents, 0x0110, 0x0114, 0x0118, 8, 2, 15, 0x0C, 17),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SNPS_ETH_250M, "top_snps_eth_250m",
+		snps_eth_250m_parents, 0x0110, 0x0114, 0x0118, 16, 1, 23, 0x0C, 18),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SNPS_ETH_62P4M_PTP, "top_snps_eth_62p4m_ptp",
+		snps_eth_62p4m_ptp_parents, 0x0110, 0x0114, 0x0118, 24, 2, 31, 0x0C, 19),
+	/* CLK_CFG_21 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SNPS_ETH_50M_RMII, "snps_eth_50m_rmii",
+		snps_eth_50m_rmii_parents, 0x011C, 0x0120, 0x0124, 0, 1, 7, 0x0C, 20),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DGI_OUT, "top_dgi_out",
+		dgi_out_parents, 0x011C, 0x0120, 0x0124, 8, 3, 15, 0x0C, 21),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NNA0, "top_nna0",
+		nna_parents, 0x011C, 0x0120, 0x0124, 16, 4, 23, 0x0C, 22),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NNA1, "top_nna1",
+		nna_parents, 0x011C, 0x0120, 0x0124, 24, 4, 31, 0x0C, 23),
+	/* CLK_CFG_22 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ADSP, "top_adsp",
+		adsp_parents, 0x0128, 0x012C, 0x0130, 0, 4, 7, 0x0C, 24),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ASM_H, "top_asm_h",
+		asm_parents, 0x0128, 0x012C, 0x0130, 8, 2, 15, 0x0C, 25),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ASM_M, "top_asm_m",
+		asm_parents, 0x0128, 0x012C, 0x0130, 16, 2, 23, 0x0C, 26),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ASM_L, "top_asm_l",
+		asm_parents, 0x0128, 0x012C, 0x0130, 24, 2, 31, 0x0C, 27),
+	/* CLK_CFG_23 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_APLL1, "top_apll1",
+		apll1_parents, 0x0134, 0x0138, 0x013C, 0, 1, 7, 0x0C, 28),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_APLL2, "top_apll2",
+		apll2_parents, 0x0134, 0x0138, 0x013C, 8, 1, 15, 0x0C, 29),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_APLL3, "top_apll3",
+		apll3_parents, 0x0134, 0x0138, 0x013C, 16, 1, 23, 0x0C, 30),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_APLL4, "top_apll4",
+		apll4_parents, 0x0134, 0x0138, 0x013C, 24, 1, 31, 0x0C, 31),
+	/*
+	 * CLK_CFG_24
+	 * i2so4_mck is not used in MT8195.
+	 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_APLL5, "top_apll5",
+		apll5_parents, 0x0140, 0x0144, 0x0148, 0, 1, 7, 0x010, 0),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_I2SO1_MCK, "top_i2so1_mck",
+		i2s_parents, 0x0140, 0x0144, 0x0148, 8, 3, 15, 0x010, 1),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_I2SO2_MCK, "top_i2so2_mck",
+		i2s_parents, 0x0140, 0x0144, 0x0148, 16, 3, 23, 0x010, 2),
+	/*
+	 * CLK_CFG_25
+	 * i2so5_mck and i2si4_mck are not used in MT8195.
+	 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_I2SI1_MCK, "top_i2si1_mck",
+		i2s_parents, 0x014C, 0x0150, 0x0154, 8, 3, 15, 0x010, 5),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_I2SI2_MCK, "top_i2si2_mck",
+		i2s_parents, 0x014C, 0x0150, 0x0154, 16, 3, 23, 0x010, 6),
+	/*
+	 * CLK_CFG_26
+	 * i2si5_mck is not used in MT8195.
+	 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DPTX_MCK, "top_dptx_mck",
+		i2s_parents, 0x0158, 0x015C, 0x0160, 8, 3, 15, 0x010, 9),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_IEC_CLK, "top_aud_iec_clk",
+		i2s_parents, 0x0158, 0x015C, 0x0160, 16, 3, 23, 0x010, 10),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_HP, "top_a1sys_hp",
+		a1sys_hp_parents, 0x0158, 0x015C, 0x0160, 24, 1, 31, 0x010, 11),
+	/* CLK_CFG_27 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_A2SYS_HF, "top_a2sys_hf",
+		a2sys_parents, 0x0164, 0x0168, 0x016C, 0, 1, 7, 0x010, 12),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_A3SYS_HF, "top_a3sys_hf",
+		a3sys_parents, 0x0164, 0x0168, 0x016C, 8, 3, 15, 0x010, 13),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_A4SYS_HF, "top_a4sys_hf",
+		a3sys_parents, 0x0164, 0x0168, 0x016C, 16, 3, 23, 0x010, 14),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_BCLK, "top_spinfi_bclk",
+		spinfi_b_parents, 0x0164, 0x0168, 0x016C, 24, 3, 31, 0x010, 15),
+	/* CLK_CFG_28 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X, "top_nfi1x",
+		nfi1x_parents, 0x0170, 0x0174, 0x0178, 0, 3, 7, 0x010, 16),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ECC, "top_ecc",
+		ecc_parents, 0x0170, 0x0174, 0x0178, 8, 3, 15, 0x010, 17),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_LOCAL_BUS, "top_audio_local_bus",
+		audio_local_bus_parents, 0x0170, 0x0174, 0x0178, 16, 4, 23, 0x010, 18),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINOR, "top_spinor",
+		spinor_parents, 0x0170, 0x0174, 0x0178, 24, 2, 31, 0x010, 19),
+	/* CLK_CFG_29 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DVIO_DGI_REF, "top_dvio_dgi_ref",
+		dvio_dgi_ref_parents, 0x017C, 0x0180, 0x0184, 0, 3, 7, 0x010, 20),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_ULPOSC, "top_ulposc",
+		ulposc_parents, 0x017C, 0x0180, 0x0184, 8, 2, 15, 0x010, 21, CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_ULPOSC_CORE, "top_ulposc_core",
+		ulposc_core_parents, 0x017C, 0x0180, 0x0184, 16, 2, 23, 0x010, 22, CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SRCK, "top_srck",
+		srck_parents, 0x017C, 0x0180, 0x0184, 24, 1, 31, 0x010, 23, CLK_IS_CRITICAL),
+	/*
+	 * the clocks in CLK_CFG_30 ~ 37 are backup clock source, no need to handled
+	 * by Linux.
+	 */
+};
+
+static struct mtk_composite top_muxes[] = {
+	/* CLK_MISC_CFG_3 */
+	MUX(CLK_TOP_MFG_CK_FAST_REF, "mfg_ck_fast_ref", mfg_fast_parents, 0x0250, 8, 1),
+};
+
+/*
+ * apll12_div5 ~ 9 are not used in MT8195.
+ */
+static const struct mtk_composite top_adj_divs[] = {
+	DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0", "top_i2si1_mck", 0x0320, 0, 0x0328, 8, 0),
+	DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1", "top_i2si2_mck", 0x0320, 1, 0x0328, 8, 8),
+	DIV_GATE(CLK_TOP_APLL12_DIV2, "apll12_div2", "top_i2so1_mck", 0x0320, 2, 0x0328, 8, 16),
+	DIV_GATE(CLK_TOP_APLL12_DIV3, "apll12_div3", "top_i2so2_mck", 0x0320, 3, 0x0328, 8, 24),
+	DIV_GATE(CLK_TOP_APLL12_DIV4, "apll12_div4", "top_aud_iec_clk", 0x0320, 4, 0x0334, 8, 0),
+	DIV_GATE(CLK_TOP_APLL12_DIV9, "apll12_div9", "top_dptx_mck", 0x0320, 9, 0x0338, 8, 8),
+};
+
+static const struct mtk_gate_regs top0_cg_regs = {
+	.set_ofs = 0x238,
+	.clr_ofs = 0x238,
+	.sta_ofs = 0x238,
+};
+
+static const struct mtk_gate_regs top1_cg_regs = {
+	.set_ofs = 0x250,
+	.clr_ofs = 0x250,
+	.sta_ofs = 0x250,
+};
+
+#define GATE_TOP0_FLAGS(_id, _name, _parent, _shift, _flag)		\
+	GATE_MTK_FLAGS(_id, _name, _parent, &top0_cg_regs, _shift,	\
+		&mtk_clk_gate_ops_no_setclr_inv, _flag)
+
+#define GATE_TOP0(_id, _name, _parent, _shift)			\
+	GATE_TOP0_FLAGS(_id, _name, _parent, _shift, 0)
+
+#define GATE_TOP1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &top1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+/*
+ * cfg_axi_east, cfg_axi_east_north, cfg_axi_north and cfg_axi_south
+ * are peripheral bus clock branches.
+ */
+static const struct mtk_gate top_clks[] = {
+	/* TOP0 */
+	GATE_TOP0(CLK_TOP_CFG_VPP0, "cfg_vpp0", "top_vpp", 0),
+	GATE_TOP0(CLK_TOP_CFG_VPP1, "cfg_vpp1", "top_vpp", 1),
+	GATE_TOP0(CLK_TOP_CFG_VDO0, "cfg_vdo0", "top_vpp", 2),
+	GATE_TOP0(CLK_TOP_CFG_VDO1, "cfg_vdo1", "top_vpp", 3),
+	GATE_TOP0(CLK_TOP_CFG_UNIPLL_SES, "cfg_unipll_ses", "univpll_d2", 4),
+	GATE_TOP0(CLK_TOP_CFG_26M_VPP0, "cfg_26m_vpp0", "clk26m", 5),
+	GATE_TOP0(CLK_TOP_CFG_26M_VPP1, "cfg_26m_vpp1", "clk26m", 6),
+	GATE_TOP0(CLK_TOP_CFG_26M_AUD, "cfg_26m_aud", "clk26m", 9),
+	GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_EAST, "cfg_axi_east", "top_axi", 10, CLK_IS_CRITICAL),
+	GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_EAST_NORTH, "cfg_axi_east_north", "top_axi", 11,
+		CLK_IS_CRITICAL),
+	GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_NORTH, "cfg_axi_north", "top_axi", 12, CLK_IS_CRITICAL),
+	GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_SOUTH, "cfg_axi_south", "top_axi", 13, CLK_IS_CRITICAL),
+	GATE_TOP0(CLK_TOP_CFG_EXT_TEST, "cfg_ext_test", "msdcpll_d2", 15),
+	/* TOP1 */
+	GATE_TOP1(CLK_TOP_SSUSB_REF, "ssusb_ref", "clk26m", 0),
+	GATE_TOP1(CLK_TOP_SSUSB_PHY_REF, "ssusb_phy_ref", "clk26m", 1),
+	GATE_TOP1(CLK_TOP_SSUSB_P1_REF, "ssusb_p1_ref", "clk26m", 2),
+	GATE_TOP1(CLK_TOP_SSUSB_PHY_P1_REF, "ssusb_phy_p1_ref", "clk26m", 3),
+	GATE_TOP1(CLK_TOP_SSUSB_P2_REF, "ssusb_p2_ref", "clk26m", 4),
+	GATE_TOP1(CLK_TOP_SSUSB_PHY_P2_REF, "ssusb_phy_p2_ref", "clk26m", 5),
+	GATE_TOP1(CLK_TOP_SSUSB_P3_REF, "ssusb_p3_ref", "clk26m", 6),
+	GATE_TOP1(CLK_TOP_SSUSB_PHY_P3_REF, "ssusb_phy_p3_ref", "clk26m", 7),
+};
+
+static struct clk_onecell_data *top_clk_data;
+
+static void clk_mt8195_top_init_early(struct device_node *node)
+{
+	int i;
+
+	top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+	if (!top_clk_data)
+		return;
+
+	for (i = 0; i < CLK_TOP_NR_CLK; i++)
+		top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
+
+	mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);
+
+	if (of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data)) {
+		mtk_free_clk_data(top_clk_data);
+		top_clk_data = NULL;
+	}
+}
+
+CLK_OF_DECLARE_DRIVER(mt8195_topckgen, "mediatek,mt8195-topckgen",
+			clk_mt8195_top_init_early);
+
+static const struct of_device_id of_match_clk_mt8195_topck[] = {
+	{ .compatible = "mediatek,mt8195-topckgen", },
+	{}
+};
+
+static int clk_mt8195_topck_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+	void __iomem *base;
+
+	if (!top_clk_data)
+		return -EFAULT;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+					top_clk_data);
+	mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);
+	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+	mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
+					&mt8195_clk_lock, top_clk_data);
+	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+					&mt8195_clk_lock, top_clk_data);
+	mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
+					&mt8195_clk_lock, top_clk_data);
+	r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+	if (r)
+		return r;
+
+	return of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
+}
+
+static struct platform_driver clk_mt8195_topck_drv = {
+	.probe = clk_mt8195_topck_probe,
+	.driver = {
+		.name = "clk-mt8195-topck",
+		.of_match_table = of_match_clk_mt8195_topck,
+	},
+};
+builtin_platform_driver(clk_mt8195_topck_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:48 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:48 +0800
Subject: [v2 08/24] clk: mediatek: Add MT8195 peripheral clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-9-chun-jie.chen@mediatek.com>

Add MT8195 peripheral clock controller which provides clock
gate control for ethernet/flashif/pcie/ssusb.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile             |  2 +-
 drivers/clk/mediatek/clk-mt8195-peri_ao.c | 62 +++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-peri_ao.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index a142342a0cea..d5ee396dcded 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -80,6 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
 obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
-obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o
+obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-peri_ao.c b/drivers/clk/mediatek/clk-mt8195-peri_ao.c
new file mode 100644
index 000000000000..4059839acae3
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-peri_ao.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs peri_ao_cg_regs = {
+	.set_ofs = 0x10,
+	.clr_ofs = 0x14,
+	.sta_ofs = 0x18,
+};
+
+#define GATE_PERI_AO(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &peri_ao_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate peri_ao_clks[] = {
+	GATE_PERI_AO(CLK_PERI_AO_ETHERNET, "peri_ao_ethernet", "top_axi", 0),
+	GATE_PERI_AO(CLK_PERI_AO_ETHERNET_BUS, "peri_ao_ethernet_bus", "top_axi", 1),
+	GATE_PERI_AO(CLK_PERI_AO_FLASHIF_BUS, "peri_ao_flashif_bus", "top_axi", 3),
+	GATE_PERI_AO(CLK_PERI_AO_FLASHIF_FLASH, "peri_ao_flashif_flash", "top_spinor", 5),
+	GATE_PERI_AO(CLK_PERI_AO_SSUSB_1P_BUS, "peri_ao_ssusb_1p_bus", "top_usb_top_1p", 7),
+	GATE_PERI_AO(CLK_PERI_AO_SSUSB_1P_XHCI, "peri_ao_ssusb_1p_xhci", "top_ssusb_xhci_1p", 8),
+	GATE_PERI_AO(CLK_PERI_AO_SSUSB_2P_BUS, "peri_ao_ssusb_2p_bus", "top_usb_top_2p", 9),
+	GATE_PERI_AO(CLK_PERI_AO_SSUSB_2P_XHCI, "peri_ao_ssusb_2p_xhci", "top_ssusb_xhci_2p", 10),
+	GATE_PERI_AO(CLK_PERI_AO_SSUSB_3P_BUS, "peri_ao_ssusb_3p_bus", "top_usb_top_3p", 11),
+	GATE_PERI_AO(CLK_PERI_AO_SSUSB_3P_XHCI, "peri_ao_ssusb_3p_xhci", "top_ssusb_xhci_3p", 12),
+	GATE_PERI_AO(CLK_PERI_AO_SPINFI, "peri_ao_spinfi", "top_spinfi_bclk", 15),
+	GATE_PERI_AO(CLK_PERI_AO_ETHERNET_MAC, "peri_ao_ethernet_mac", "top_snps_eth_250m", 16),
+	GATE_PERI_AO(CLK_PERI_AO_NFI_H, "peri_ao_nfi_h", "top_axi", 19),
+	GATE_PERI_AO(CLK_PERI_AO_FNFI1X, "peri_ao_fnfi1x", "top_nfi1x", 20),
+	GATE_PERI_AO(CLK_PERI_AO_PCIE_P0_MEM, "peri_ao_pcie_p0_mem", "mem_466m", 24),
+	GATE_PERI_AO(CLK_PERI_AO_PCIE_P1_MEM, "peri_ao_pcie_p1_mem", "mem_466m", 25),
+};
+
+static const struct mtk_clk_desc peri_ao_desc = {
+	.clks = peri_ao_clks,
+	.num_clks = ARRAY_SIZE(peri_ao_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_peri_ao[] = {
+	{
+		.compatible = "mediatek,mt8195-pericfg_ao",
+		.data = &peri_ao_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_peri_ao_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-peri_ao",
+		.of_match_table = of_match_clk_mt8195_peri_ao,
+	},
+};
+builtin_platform_driver(clk_mt8195_peri_ao_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:49 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:49 +0800
Subject: [v2 09/24] clk: mediatek: Add MT8195 infrastructure clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-10-chun-jie.chen@mediatek.com>

Add MT8195 infrastructure clock controller which provides
clock gate control for basic IP like pwm, uart, spi and so on.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile              |   2 +-
 drivers/clk/mediatek/clk-mt8195-infra_ao.c | 211 +++++++++++++++++++++
 2 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-infra_ao.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index d5ee396dcded..c5a80645f10e 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -80,6 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
 obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
-obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o
+obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-infra_ao.c b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
new file mode 100644
index 000000000000..a5794c65f743
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs infra_ao0_cg_regs = {
+	.set_ofs = 0x80,
+	.clr_ofs = 0x84,
+	.sta_ofs = 0x90,
+};
+
+static const struct mtk_gate_regs infra_ao1_cg_regs = {
+	.set_ofs = 0x88,
+	.clr_ofs = 0x8c,
+	.sta_ofs = 0x94,
+};
+
+static const struct mtk_gate_regs infra_ao2_cg_regs = {
+	.set_ofs = 0xa4,
+	.clr_ofs = 0xa8,
+	.sta_ofs = 0xac,
+};
+
+static const struct mtk_gate_regs infra_ao3_cg_regs = {
+	.set_ofs = 0xc0,
+	.clr_ofs = 0xc4,
+	.sta_ofs = 0xc8,
+};
+
+static const struct mtk_gate_regs infra_ao4_cg_regs = {
+	.set_ofs = 0xe0,
+	.clr_ofs = 0xe4,
+	.sta_ofs = 0xe8,
+};
+
+#define GATE_INFRA_AO0_FLAGS(_id, _name, _parent, _shift, _flag)                \
+	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao0_cg_regs, _shift, \
+		&mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA_AO0(_id, _name, _parent, _shift)	\
+	GATE_INFRA_AO0_FLAGS(_id, _name, _parent, _shift, 0)
+
+#define GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, _flag)		\
+	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao1_cg_regs, _shift,	\
+		&mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA_AO1(_id, _name, _parent, _shift)	\
+	GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, 0)
+
+#define GATE_INFRA_AO2(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &infra_ao2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, _flag)		\
+	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao3_cg_regs, _shift,	\
+		&mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA_AO3(_id, _name, _parent, _shift)	\
+	GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, 0)
+
+#define GATE_INFRA_AO4_FLAGS(_id, _name, _parent, _shift, _flag)		\
+	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao4_cg_regs, _shift,	\
+		&mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA_AO4(_id, _name, _parent, _shift)	\
+	GATE_INFRA_AO4_FLAGS(_id, _name, _parent, _shift, 0)
+
+/*
+ * infra_ao_sej is main clock is for secure engin with JTAG support.
+ * infra_133m_m_peri and infra_66m_m_peri are main clocks of peripheral.
+ * infra_device_apc and infra_device_apc_sync are for device access permission control module.
+ */
+static const struct mtk_gate infra_ao_clks[] = {
+	/* INFRA_AO0 */
+	GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_TMR, "infra_ao_pmic_tmr", "top_pwrap_ulposc", 0),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_AP, "infra_ao_pmic_ap", "top_pwrap_ulposc", 1),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_MD, "infra_ao_pmic_md", "top_pwrap_ulposc", 2),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_CONN, "infra_ao_pmic_conn", "top_pwrap_ulposc", 3),
+	GATE_INFRA_AO0_FLAGS(CLK_INFRA_AO_SEJ, "infra_ao_sej", "top_axi", 5, CLK_IS_CRITICAL),
+	GATE_INFRA_AO0(CLK_INFRA_AO_APXGPT, "infra_ao_apxgpt", "top_axi", 6),
+	GATE_INFRA_AO0(CLK_INFRA_AO_GCE, "infra_ao_gce", "top_axi", 8),
+	GATE_INFRA_AO0(CLK_INFRA_AO_GCE2, "infra_ao_gce2", "top_axi", 9),
+	GATE_INFRA_AO0(CLK_INFRA_AO_THERM, "infra_ao_therm", "top_axi", 10),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM_H, "infra_ao_pwm_h", "top_axi", 15),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM1, "infra_ao_pwm1", "top_pwm", 16),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM2, "infra_ao_pwm2", "top_pwm", 17),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM3, "infra_ao_pwm3", "top_pwm", 18),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM4, "infra_ao_pwm4", "top_pwm", 19),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM, "infra_ao_pwm", "top_pwm", 21),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART0, "infra_ao_uart0", "top_uart", 22),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART1, "infra_ao_uart1", "top_uart", 23),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART2, "infra_ao_uart2", "top_uart", 24),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART3, "infra_ao_uart3", "top_uart", 25),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART4, "infra_ao_uart4", "top_uart", 26),
+	GATE_INFRA_AO0(CLK_INFRA_AO_GCE_26M, "infra_ao_gce_26m", "clk26m", 27),
+	GATE_INFRA_AO0(CLK_INFRA_AO_CQ_DMA_FPC, "infra_ao_cq_dma_fpc", "fpc", 28),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART5, "infra_ao_uart5", "top_uart", 29),
+	/* INFRA_AO1 */
+	GATE_INFRA_AO1(CLK_INFRA_AO_HDMI_26M, "infra_ao_hdmi_26m", "clk26m", 0),
+	GATE_INFRA_AO1(CLK_INFRA_AO_SPI0, "infra_ao_spi0", "top_spi", 1),
+	GATE_INFRA_AO1(CLK_INFRA_AO_MSDC0, "infra_ao_msdc0", "top_msdc50_0_hclk", 2),
+	GATE_INFRA_AO1(CLK_INFRA_AO_MSDC1, "infra_ao_msdc1", "top_axi", 4),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CG1_MSDC2, "infra_ao_cg1_msdc2", "top_axi", 5),
+	GATE_INFRA_AO1(CLK_INFRA_AO_MSDC0_SRC, "infra_ao_msdc0_src", "top_msdc50_0", 6),
+	GATE_INFRA_AO1(CLK_INFRA_AO_TRNG, "infra_ao_trng", "top_axi", 9),
+	GATE_INFRA_AO1(CLK_INFRA_AO_AUXADC, "infra_ao_auxadc", "clk26m", 10),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CPUM, "infra_ao_cpum", "top_axi", 11),
+	GATE_INFRA_AO1(CLK_INFRA_AO_HDMI_32K, "infra_ao_hdmi_32k", "clk32k", 12),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CEC_66M_H, "infra_ao_cec_66m_h", "top_axi", 13),
+	GATE_INFRA_AO1(CLK_INFRA_AO_IRRX, "infra_ao_irrx", "top_axi", 14),
+	GATE_INFRA_AO1(CLK_INFRA_AO_PCIE_TL_26M, "infra_ao_pcie_tl_26m", "clk26m", 15),
+	GATE_INFRA_AO1(CLK_INFRA_AO_MSDC1_SRC, "infra_ao_msdc1_src", "top_msdc30_1", 16),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CEC_66M_B, "infra_ao_cec_66m_b", "top_axi", 17),
+	GATE_INFRA_AO1(CLK_INFRA_AO_PCIE_TL_96M, "infra_ao_pcie_tl_96m", "top_tl", 18),
+	GATE_INFRA_AO1_FLAGS(CLK_INFRA_AO_DEVICE_APC, "infra_ao_device_apc", "top_axi", 20,
+		CLK_IS_CRITICAL),
+	GATE_INFRA_AO1(CLK_INFRA_AO_ECC_66M_H, "infra_ao_ecc_66m_h", "top_axi", 23),
+	GATE_INFRA_AO1(CLK_INFRA_AO_DEBUGSYS, "infra_ao_debugsys", "top_axi", 24),
+	GATE_INFRA_AO1(CLK_INFRA_AO_AUDIO, "infra_ao_audio", "top_axi", 25),
+	GATE_INFRA_AO1(CLK_INFRA_AO_PCIE_TL_32K, "infra_ao_pcie_tl_32k", "clk32k", 26),
+	GATE_INFRA_AO1(CLK_INFRA_AO_DBG_TRACE, "infra_ao_dbg_trace", "top_axi", 29),
+	GATE_INFRA_AO1(CLK_INFRA_AO_DRAMC_F26M, "infra_ao_dramc_f26m", "clk26m", 31),
+	/* INFRA_AO2 */
+	GATE_INFRA_AO2(CLK_INFRA_AO_IRTX, "infra_ao_irtx", "top_axi", 0),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB, "infra_ao_ssusb", "top_usb_top", 1),
+	GATE_INFRA_AO2(CLK_INFRA_AO_DISP_PWM, "infra_ao_disp_pwm", "top_disp_pwm0", 2),
+	GATE_INFRA_AO2(CLK_INFRA_AO_CLDMA_B, "infra_ao_cldma_b", "top_axi", 3),
+	GATE_INFRA_AO2(CLK_INFRA_AO_AUDIO_26M_B, "infra_ao_audio_26m_b", "clk26m", 4),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI1, "infra_ao_spi1", "top_spi", 6),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI2, "infra_ao_spi2", "top_spi", 9),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI3, "infra_ao_spi3", "top_spi", 10),
+	GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_SYS, "infra_ao_unipro_sys", "top_ufs", 11),
+	GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_TICK, "infra_ao_unipro_tick", "top_ufs_tick1us", 12),
+	GATE_INFRA_AO2(CLK_INFRA_AO_UFS_MP_SAP_B, "infra_ao_ufs_mp_sap_b", "top_ufs_mp_sap_cfg",
+		13),
+	GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU, "infra_ao_pwrmcu", "top_pwrmcu", 15),
+	GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU_BUS_H, "infra_ao_pwrmcu_bus_h", "top_axi", 17),
+	GATE_INFRA_AO2(CLK_INFRA_AO_APDMA_B, "infra_ao_apdma_b", "top_axi", 18),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI4, "infra_ao_spi4", "top_spi", 25),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI5, "infra_ao_spi5", "top_spi", 26),
+	GATE_INFRA_AO2(CLK_INFRA_AO_CQ_DMA, "infra_ao_cq_dma", "top_axi", 27),
+	GATE_INFRA_AO2(CLK_INFRA_AO_AES_UFSFDE, "infra_ao_aes_ufsfde", "top_ufs", 28),
+	GATE_INFRA_AO2(CLK_INFRA_AO_AES, "infra_ao_aes", "top_aes_ufsfde", 29),
+	GATE_INFRA_AO2(CLK_INFRA_AO_UFS_TICK, "infra_ao_ufs_tick", "top_ufs_tick1us", 30),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_XHCI, "infra_ao_ssusb_xhci", "top_ssusb_xhci", 31),
+	/* INFRA_AO3 */
+	GATE_INFRA_AO3(CLK_INFRA_AO_MSDC0_SELF, "infra_ao_msdc0f", "top_msdc50_0", 0),
+	GATE_INFRA_AO3(CLK_INFRA_AO_MSDC1_SELF, "infra_ao_msdc1f", "top_msdc50_0", 1),
+	GATE_INFRA_AO3(CLK_INFRA_AO_MSDC2_SELF, "infra_ao_msdc2f", "top_msdc50_0", 2),
+	GATE_INFRA_AO3(CLK_INFRA_AO_I2S_DMA, "infra_ao_i2s_dma", "top_axi", 5),
+	GATE_INFRA_AO3(CLK_INFRA_AO_AP_MSDC0, "infra_ao_ap_msdc0", "top_msdc50_0", 7),
+	GATE_INFRA_AO3(CLK_INFRA_AO_MD_MSDC0, "infra_ao_md_msdc0", "top_msdc50_0", 8),
+	GATE_INFRA_AO3(CLK_INFRA_AO_CG3_MSDC2, "infra_ao_cg3_msdc2", "top_msdc30_2", 9),
+	GATE_INFRA_AO3(CLK_INFRA_AO_GCPU, "infra_ao_gcpu", "top_gcpu", 10),
+	GATE_INFRA_AO3(CLK_INFRA_AO_PCIE_PERI_26M, "infra_ao_pcie_peri_26m", "clk26m", 15),
+	GATE_INFRA_AO3(CLK_INFRA_AO_GCPU_66M_B, "infra_ao_gcpu_66m_b", "top_axi", 16),
+	GATE_INFRA_AO3(CLK_INFRA_AO_GCPU_133M_B, "infra_ao_gcpu_133m_b", "top_axi", 17),
+	GATE_INFRA_AO3(CLK_INFRA_AO_DISP_PWM1, "infra_ao_disp_pwm1", "top_disp_pwm1", 20),
+	GATE_INFRA_AO3(CLK_INFRA_AO_FBIST2FPC, "infra_ao_fbist2fpc", "top_msdc50_0", 24),
+	GATE_INFRA_AO3_FLAGS(CLK_INFRA_AO_DEVICE_APC_SYNC, "infra_ao_device_apc_sync", "top_axi",
+		25, CLK_IS_CRITICAL),
+	GATE_INFRA_AO3(CLK_INFRA_AO_PCIE_P1_PERI_26M, "infra_ao_pcie_p1_peri_26m", "clk26m", 26),
+	GATE_INFRA_AO3(CLK_INFRA_AO_SPIS0, "infra_ao_spis0", "top_spis", 28),
+	GATE_INFRA_AO3(CLK_INFRA_AO_SPIS1, "infra_ao_spis1", "top_spis", 29),
+	/* INFRA_AO4 */
+	GATE_INFRA_AO4_FLAGS(CLK_INFRA_AO_133M_M_PERI, "infra_ao_133m_m_peri", "top_axi", 0,
+		CLK_IS_CRITICAL),
+	GATE_INFRA_AO4_FLAGS(CLK_INFRA_AO_66M_M_PERI, "infra_ao_66m_m_peri", "top_spi", 1,
+		CLK_IS_CRITICAL),
+	GATE_INFRA_AO4(CLK_INFRA_AO_PCIE_PL_P_250M_P0, "infra_ao_pcie_pl_p_250m_p0", "pextp_pipe",
+		7),
+	GATE_INFRA_AO4(CLK_INFRA_AO_PCIE_PL_P_250M_P1, "infra_ao_pcie_pl_p_250m_p1",
+		"ssusb_u3phy_p1_p_p0", 8),
+	GATE_INFRA_AO4(CLK_INFRA_AO_PCIE_P1_TL_96M, "infra_ao_pcie_p1_tl_96m", "top_tl_p1", 17),
+	GATE_INFRA_AO4(CLK_INFRA_AO_AES_MSDCFDE_0P, "infra_ao_aes_msdcfde_0p", "top_aes_msdcfde",
+		18),
+	GATE_INFRA_AO4(CLK_INFRA_AO_UFS_TX_SYMBOL, "infra_ao_ufs_tx_symbol", "ufs_tx_symbol", 22),
+	GATE_INFRA_AO4(CLK_INFRA_AO_UFS_RX_SYMBOL, "infra_ao_ufs_rx_symbol", "ufs_rx_symbol", 23),
+	GATE_INFRA_AO4(CLK_INFRA_AO_UFS_RX_SYMBOL1, "infra_ao_ufs_rx_symbol1", "ufs_rx_symbol1",
+		24),
+	GATE_INFRA_AO4(CLK_INFRA_AO_PERI_UFS_MEM_SUB, "infra_ao_peri_ufs_mem_sub", "mem_466m", 31),
+};
+
+static const struct mtk_clk_desc infra_ao_desc = {
+	.clks = infra_ao_clks,
+	.num_clks = ARRAY_SIZE(infra_ao_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_infra_ao[] = {
+	{
+		.compatible = "mediatek,mt8195-infracfg_ao",
+		.data = &infra_ao_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_infra_ao_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-infra_ao",
+		.of_match_table = of_match_clk_mt8195_infra_ao,
+	},
+};
+builtin_platform_driver(clk_mt8195_infra_ao_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:50 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:50 +0800
Subject: [v2 10/24] clk: mediatek: Add MT8195 camsys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-11-chun-jie.chen@mediatek.com>

Add MT8195 camsys clock controllers which provide clock gate
control for camera IP blocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/Makefile         |   2 +-
 drivers/clk/mediatek/clk-mt8195-cam.c | 142 ++++++++++++++++++++++++++
 2 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-cam.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index c5a80645f10e..718bbb04191b 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -80,6 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
 obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
-obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o
+obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-cam.c b/drivers/clk/mediatek/clk-mt8195-cam.c
new file mode 100644
index 000000000000..08ada5673cdf
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-cam.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs cam_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_CAM(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate cam_clks[] = {
+	GATE_CAM(CLK_CAM_LARB13, "cam_larb13", "top_cam", 0),
+	GATE_CAM(CLK_CAM_LARB14, "cam_larb14", "top_cam", 1),
+	GATE_CAM(CLK_CAM_MAIN_CAM, "cam_main_cam", "top_cam", 3),
+	GATE_CAM(CLK_CAM_MAIN_CAMTG, "cam_main_camtg", "top_cam", 4),
+	GATE_CAM(CLK_CAM_SENINF, "cam_seninf", "top_cam", 5),
+	GATE_CAM(CLK_CAM_GCAMSVA, "cam_gcamsva", "top_cam", 6),
+	GATE_CAM(CLK_CAM_GCAMSVB, "cam_gcamsvb", "top_cam", 7),
+	GATE_CAM(CLK_CAM_GCAMSVC, "cam_gcamsvc", "top_cam", 8),
+	GATE_CAM(CLK_CAM_SCAMSA, "cam_scamsa", "top_cam", 9),
+	GATE_CAM(CLK_CAM_SCAMSB, "cam_scamsb", "top_cam", 10),
+	GATE_CAM(CLK_CAM_CAMSV_TOP, "cam_camsv_top", "top_cam", 11),
+	GATE_CAM(CLK_CAM_CAMSV_CQ, "cam_camsv_cq", "top_cam", 12),
+	GATE_CAM(CLK_CAM_ADL, "cam_adl", "top_cam", 16),
+	GATE_CAM(CLK_CAM_ASG, "cam_asg", "top_cam", 17),
+	GATE_CAM(CLK_CAM_PDA, "cam_pda", "top_cam", 18),
+	GATE_CAM(CLK_CAM_FAKE_ENG, "cam_fake_eng", "top_cam", 19),
+	GATE_CAM(CLK_CAM_MAIN_MRAW0, "cam_main_mraw0", "top_cam", 20),
+	GATE_CAM(CLK_CAM_MAIN_MRAW1, "cam_main_mraw1", "top_cam", 21),
+	GATE_CAM(CLK_CAM_MAIN_MRAW2, "cam_main_mraw2", "top_cam", 22),
+	GATE_CAM(CLK_CAM_MAIN_MRAW3, "cam_main_mraw3", "top_cam", 23),
+	GATE_CAM(CLK_CAM_CAM2MM0_GALS, "cam_cam2mm0_gals", "top_cam", 24),
+	GATE_CAM(CLK_CAM_CAM2MM1_GALS, "cam_cam2mm1_gals", "top_cam", 25),
+	GATE_CAM(CLK_CAM_CAM2SYS_GALS, "cam_cam2sys_gals", "top_cam", 26),
+};
+
+static const struct mtk_gate cam_mraw_clks[] = {
+	GATE_CAM(CLK_CAM_MRAW_LARBX, "cam_mraw_larbx", "top_cam", 0),
+	GATE_CAM(CLK_CAM_MRAW_CAMTG, "cam_mraw_camtg", "top_cam", 2),
+	GATE_CAM(CLK_CAM_MRAW_MRAW0, "cam_mraw_mraw0", "top_cam", 3),
+	GATE_CAM(CLK_CAM_MRAW_MRAW1, "cam_mraw_mraw1", "top_cam", 4),
+	GATE_CAM(CLK_CAM_MRAW_MRAW2, "cam_mraw_mraw2", "top_cam", 5),
+	GATE_CAM(CLK_CAM_MRAW_MRAW3, "cam_mraw_mraw3", "top_cam", 6),
+};
+
+static const struct mtk_gate cam_rawa_clks[] = {
+	GATE_CAM(CLK_CAM_RAWA_LARBX, "cam_rawa_larbx", "top_cam", 0),
+	GATE_CAM(CLK_CAM_RAWA_CAM, "cam_rawa_cam", "top_cam", 1),
+	GATE_CAM(CLK_CAM_RAWA_CAMTG, "cam_rawa_camtg", "top_cam", 2),
+};
+
+static const struct mtk_gate cam_rawb_clks[] = {
+	GATE_CAM(CLK_CAM_RAWB_LARBX, "cam_rawb_larbx", "top_cam", 0),
+	GATE_CAM(CLK_CAM_RAWB_CAM, "cam_rawb_cam", "top_cam", 1),
+	GATE_CAM(CLK_CAM_RAWB_CAMTG, "cam_rawb_camtg", "top_cam", 2),
+};
+
+static const struct mtk_gate cam_yuva_clks[] = {
+	GATE_CAM(CLK_CAM_YUVA_LARBX, "cam_yuva_larbx", "top_cam", 0),
+	GATE_CAM(CLK_CAM_YUVA_CAM, "cam_yuva_cam", "top_cam", 1),
+	GATE_CAM(CLK_CAM_YUVA_CAMTG, "cam_yuva_camtg", "top_cam", 2),
+};
+
+static const struct mtk_gate cam_yuvb_clks[] = {
+	GATE_CAM(CLK_CAM_YUVB_LARBX, "cam_yuvb_larbx", "top_cam", 0),
+	GATE_CAM(CLK_CAM_YUVB_CAM, "cam_yuvb_cam", "top_cam", 1),
+	GATE_CAM(CLK_CAM_YUVB_CAMTG, "cam_yuvb_camtg", "top_cam", 2),
+};
+
+static const struct mtk_clk_desc cam_desc = {
+	.clks = cam_clks,
+	.num_clks = ARRAY_SIZE(cam_clks),
+};
+
+static const struct mtk_clk_desc cam_mraw_desc = {
+	.clks = cam_mraw_clks,
+	.num_clks = ARRAY_SIZE(cam_mraw_clks),
+};
+
+static const struct mtk_clk_desc cam_rawa_desc = {
+	.clks = cam_rawa_clks,
+	.num_clks = ARRAY_SIZE(cam_rawa_clks),
+};
+
+static const struct mtk_clk_desc cam_rawb_desc = {
+	.clks = cam_rawb_clks,
+	.num_clks = ARRAY_SIZE(cam_rawb_clks),
+};
+
+static const struct mtk_clk_desc cam_yuva_desc = {
+	.clks = cam_yuva_clks,
+	.num_clks = ARRAY_SIZE(cam_yuva_clks),
+};
+
+static const struct mtk_clk_desc cam_yuvb_desc = {
+	.clks = cam_yuvb_clks,
+	.num_clks = ARRAY_SIZE(cam_yuvb_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_cam[] = {
+	{
+		.compatible = "mediatek,mt8195-camsys",
+		.data = &cam_desc,
+	}, {
+		.compatible = "mediatek,mt8195-camsys_mraw",
+		.data = &cam_mraw_desc,
+	}, {
+		.compatible = "mediatek,mt8195-camsys_rawa",
+		.data = &cam_rawa_desc,
+	}, {
+		.compatible = "mediatek,mt8195-camsys_rawb",
+		.data = &cam_rawb_desc,
+	}, {
+		.compatible = "mediatek,mt8195-camsys_yuva",
+		.data = &cam_yuva_desc,
+	}, {
+		.compatible = "mediatek,mt8195-camsys_yuvb",
+		.data = &cam_yuvb_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_cam_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-cam",
+		.of_match_table = of_match_clk_mt8195_cam,
+	},
+};
+builtin_platform_driver(clk_mt8195_cam_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:51 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:51 +0800
Subject: [v2 11/24] clk: mediatek: Add MT8195 ccusys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-12-chun-jie.chen@mediatek.com>

Add MT8195 ccusys clock controller which provides clock gate
control in Camera Computing Unit.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/Makefile         |  3 +-
 drivers/clk/mediatek/clk-mt8195-ccu.c | 50 +++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-ccu.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 718bbb04191b..03fb020834f3 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
 obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
-obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o
+obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
+					clk-mt8195-ccu.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-ccu.c b/drivers/clk/mediatek/clk-mt8195-ccu.c
new file mode 100644
index 000000000000..d883091e0085
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-ccu.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs ccu_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_CCU(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &ccu_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate ccu_clks[] = {
+	GATE_CCU(CLK_CCU_LARB18, "ccu_larb18", "top_ccu", 0),
+	GATE_CCU(CLK_CCU_AHB, "ccu_ahb", "top_ccu", 1),
+	GATE_CCU(CLK_CCU_CCU0, "ccu_ccu0", "top_ccu", 2),
+	GATE_CCU(CLK_CCU_CCU1, "ccu_ccu1", "top_ccu", 3),
+};
+
+static const struct mtk_clk_desc ccu_desc = {
+	.clks = ccu_clks,
+	.num_clks = ARRAY_SIZE(ccu_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_ccu[] = {
+	{
+		.compatible = "mediatek,mt8195-ccusys",
+		.data = &ccu_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_ccu_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-ccu",
+		.of_match_table = of_match_clk_mt8195_ccu,
+	},
+};
+builtin_platform_driver(clk_mt8195_ccu_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:52 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:52 +0800
Subject: [v2 12/24] clk: mediatek: Add MT8195 imgsys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-13-chun-jie.chen@mediatek.com>

Add MT8195 imgsys clock controllers which provide clock gate
control for img IP blocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/Makefile         |  2 +-
 drivers/clk/mediatek/clk-mt8195-img.c | 96 +++++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-img.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 03fb020834f3..f9736e6640ce 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -81,6 +81,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
-					clk-mt8195-ccu.o
+					clk-mt8195-ccu.o clk-mt8195-img.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-img.c b/drivers/clk/mediatek/clk-mt8195-img.c
new file mode 100644
index 000000000000..ee864a8fe5f1
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-img.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs img_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate img_clks[] = {
+	GATE_IMG(CLK_IMG_LARB9, "img_larb9", "top_img", 0),
+	GATE_IMG(CLK_IMG_TRAW0, "img_traw0", "top_img", 1),
+	GATE_IMG(CLK_IMG_TRAW1, "img_traw1", "top_img", 2),
+	GATE_IMG(CLK_IMG_TRAW2, "img_traw2", "top_img", 3),
+	GATE_IMG(CLK_IMG_TRAW3, "img_traw3", "top_img", 4),
+	GATE_IMG(CLK_IMG_DIP0, "img_dip0", "top_img", 8),
+	GATE_IMG(CLK_IMG_WPE0, "img_wpe0", "top_img", 9),
+	GATE_IMG(CLK_IMG_IPE, "img_ipe", "top_img", 10),
+	GATE_IMG(CLK_IMG_DIP1, "img_dip1", "top_img", 11),
+	GATE_IMG(CLK_IMG_WPE1, "img_wpe1", "top_img", 12),
+	GATE_IMG(CLK_IMG_GALS, "img_gals", "top_img", 31),
+};
+
+static const struct mtk_gate img1_dip_top_clks[] = {
+	GATE_IMG(CLK_IMG1_DIP_TOP_LARB10, "img1_dip_top_larb10", "top_img", 0),
+	GATE_IMG(CLK_IMG1_DIP_TOP_DIP_TOP, "img1_dip_top_dip_top", "top_img", 1),
+};
+
+static const struct mtk_gate img1_dip_nr_clks[] = {
+	GATE_IMG(CLK_IMG1_DIP_NR_RESERVE, "img1_dip_nr_reserve", "top_img", 0),
+	GATE_IMG(CLK_IMG1_DIP_NR_DIP_NR, "img1_dip_nr_dip_nr", "top_img", 1),
+};
+
+static const struct mtk_gate img1_wpe_clks[] = {
+	GATE_IMG(CLK_IMG1_WPE_LARB11, "img1_wpe_larb11", "top_img", 0),
+	GATE_IMG(CLK_IMG1_WPE_WPE, "img1_wpe_wpe", "top_img", 1),
+};
+
+static const struct mtk_clk_desc img_desc = {
+	.clks = img_clks,
+	.num_clks = ARRAY_SIZE(img_clks),
+};
+
+static const struct mtk_clk_desc img1_dip_top_desc = {
+	.clks = img1_dip_top_clks,
+	.num_clks = ARRAY_SIZE(img1_dip_top_clks),
+};
+
+static const struct mtk_clk_desc img1_dip_nr_desc = {
+	.clks = img1_dip_nr_clks,
+	.num_clks = ARRAY_SIZE(img1_dip_nr_clks),
+};
+
+static const struct mtk_clk_desc img1_wpe_desc = {
+	.clks = img1_wpe_clks,
+	.num_clks = ARRAY_SIZE(img1_wpe_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_img[] = {
+	{
+		.compatible = "mediatek,mt8195-imgsys",
+		.data = &img_desc,
+	}, {
+		.compatible = "mediatek,mt8195-imgsys1_dip_top",
+		.data = &img1_dip_top_desc,
+	}, {
+		.compatible = "mediatek,mt8195-imgsys1_dip_nr",
+		.data = &img1_dip_nr_desc,
+	}, {
+		.compatible = "mediatek,mt8195-imgsys1_wpe",
+		.data = &img1_wpe_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_img_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-img",
+		.of_match_table = of_match_clk_mt8195_img,
+	},
+};
+builtin_platform_driver(clk_mt8195_img_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:53 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:53 +0800
Subject: [v2 13/24] clk: mediatek: Add MT8195 ipesys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-14-chun-jie.chen@mediatek.com>

Add MT8195 ipesys clock controller which provides clock gate
control for ipe IP block.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |  2 +-
 drivers/clk/mediatek/clk-mt8195-ipe.c | 51 +++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-ipe.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index f9736e6640ce..84d315a6b3e4 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -81,6 +81,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
-					clk-mt8195-ccu.o clk-mt8195-img.o
+					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-ipe.c b/drivers/clk/mediatek/clk-mt8195-ipe.c
new file mode 100644
index 000000000000..fc176e844973
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-ipe.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs ipe_cg_regs = {
+	.set_ofs = 0x0,
+	.clr_ofs = 0x0,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_IPE(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &ipe_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+static const struct mtk_gate ipe_clks[] = {
+	GATE_IPE(CLK_IPE_DPE, "ipe_dpe", "top_ipe", 0),
+	GATE_IPE(CLK_IPE_FDVT, "ipe_fdvt", "top_ipe", 1),
+	GATE_IPE(CLK_IPE_ME, "ipe_me", "top_ipe", 2),
+	GATE_IPE(CLK_IPE_TOP, "ipe_top", "top_ipe", 3),
+	GATE_IPE(CLK_IPE_SMI_LARB12, "ipe_smi_larb12", "top_ipe", 4),
+};
+
+static const struct mtk_clk_desc ipe_desc = {
+	.clks = ipe_clks,
+	.num_clks = ARRAY_SIZE(ipe_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_ipe[] = {
+	{
+		.compatible = "mediatek,mt8195-ipesys",
+		.data = &ipe_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_ipe_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-ipe",
+		.of_match_table = of_match_clk_mt8195_ipe,
+	},
+};
+builtin_platform_driver(clk_mt8195_ipe_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:54 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:54 +0800
Subject: [v2 14/24] clk: mediatek: Add MT8195 mfgcfg clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-15-chun-jie.chen@mediatek.com>

Add MT8195 mfg clock controller which provides clock gate
control for Main Frame Graphic.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |  2 +-
 drivers/clk/mediatek/clk-mt8195-mfg.c | 47 +++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-mfg.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 84d315a6b3e4..042db433245a 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -81,6 +81,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
-					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o
+					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-mfg.c b/drivers/clk/mediatek/clk-mt8195-mfg.c
new file mode 100644
index 000000000000..0a81fe1fe50e
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-mfg.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs mfg_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_MFG(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mfg_clks[] = {
+	GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "top_mfg_core_tmp", 0),
+};
+
+static const struct mtk_clk_desc mfg_desc = {
+	.clks = mfg_clks,
+	.num_clks = ARRAY_SIZE(mfg_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_mfg[] = {
+	{
+		.compatible = "mediatek,mt8195-mfgcfg",
+		.data = &mfg_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_mfg_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-mfg",
+		.of_match_table = of_match_clk_mt8195_mfg,
+	},
+};
+builtin_platform_driver(clk_mt8195_mfg_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:55 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:55 +0800
Subject: [v2 15/24] clk: mediatek: Add MT8195 scp adsp clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-16-chun-jie.chen@mediatek.com>

Add MT8195 scp adsp clock controller which provides clock gate
control for Audio DSP.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile              |  2 +-
 drivers/clk/mediatek/clk-mt8195-scp_adsp.c | 47 ++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-scp_adsp.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 042db433245a..472e5bc40fcb 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -81,6 +81,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
-					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o
+					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-scp_adsp.c b/drivers/clk/mediatek/clk-mt8195-scp_adsp.c
new file mode 100644
index 000000000000..cd0b9f0f0192
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-scp_adsp.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs scp_adsp_cg_regs = {
+	.set_ofs = 0x180,
+	.clr_ofs = 0x180,
+	.sta_ofs = 0x180,
+};
+
+#define GATE_SCP_ADSP(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &scp_adsp_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+static const struct mtk_gate scp_adsp_clks[] = {
+	GATE_SCP_ADSP(CLK_SCP_ADSP_AUDIODSP, "scp_adsp_audiodsp", "top_adsp", 0),
+};
+
+static const struct mtk_clk_desc scp_adsp_desc = {
+	.clks = scp_adsp_clks,
+	.num_clks = ARRAY_SIZE(scp_adsp_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_scp_adsp[] = {
+	{
+		.compatible = "mediatek,mt8195-scp_adsp",
+		.data = &scp_adsp_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_scp_adsp_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-scp_adsp",
+		.of_match_table = of_match_clk_mt8195_scp_adsp,
+	},
+};
+builtin_platform_driver(clk_mt8195_scp_adsp_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:56 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:56 +0800
Subject: [v2 16/24] clk: mediatek: Add MT8195 vdecsys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-17-chun-jie.chen@mediatek.com>

Add MT8195 vdec clock controllers which provide clock gate
control for video decoder.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile          |   3 +-
 drivers/clk/mediatek/clk-mt8195-vdec.c | 104 +++++++++++++++++++++++++
 2 files changed, 106 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vdec.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 472e5bc40fcb..ac269f6d39e3 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
-					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o
+					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
+					clk-mt8195-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-vdec.c b/drivers/clk/mediatek/clk-mt8195-vdec.c
new file mode 100644
index 000000000000..2acc0cf88331
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-vdec.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+	.set_ofs = 0x0,
+	.clr_ofs = 0x4,
+	.sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+	.set_ofs = 0x200,
+	.clr_ofs = 0x204,
+	.sta_ofs = 0x200,
+};
+
+static const struct mtk_gate_regs vdec2_cg_regs = {
+	.set_ofs = 0x8,
+	.clr_ofs = 0xc,
+	.sta_ofs = 0x8,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+#define GATE_VDEC1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+#define GATE_VDEC2(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdec2_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate vdec_clks[] = {
+	/* VDEC0 */
+	GATE_VDEC0(CLK_VDEC_VDEC, "vdec_vdec", "top_vdec", 0),
+	/* VDEC1 */
+	GATE_VDEC1(CLK_VDEC_LAT, "vdec_lat", "top_vdec", 0),
+	/* VDEC2 */
+	GATE_VDEC2(CLK_VDEC_LARB1, "vdec_larb1", "top_vdec", 0),
+};
+
+static const struct mtk_gate vdec_core1_clks[] = {
+	/* VDEC0 */
+	GATE_VDEC0(CLK_VDEC_CORE1_VDEC, "vdec_core1_vdec", "top_vdec", 0),
+	/* VDEC1 */
+	GATE_VDEC1(CLK_VDEC_CORE1_LAT, "vdec_core1_lat", "top_vdec", 0),
+	/* VDEC2 */
+	GATE_VDEC2(CLK_VDEC_CORE1_LARB1, "vdec_core1_larb1", "top_vdec", 0),
+};
+
+static const struct mtk_gate vdec_soc_clks[] = {
+	/* VDEC0 */
+	GATE_VDEC0(CLK_VDEC_SOC_VDEC, "vdec_soc_vdec", "top_vdec", 0),
+	/* VDEC1 */
+	GATE_VDEC1(CLK_VDEC_SOC_LAT, "vdec_soc_lat", "top_vdec", 0),
+	/* VDEC2 */
+	GATE_VDEC2(CLK_VDEC_SOC_LARB1, "vdec_soc_larb1", "top_vdec", 0),
+};
+
+static const struct mtk_clk_desc vdec_desc = {
+	.clks = vdec_clks,
+	.num_clks = ARRAY_SIZE(vdec_clks),
+};
+
+static const struct mtk_clk_desc vdec_core1_desc = {
+	.clks = vdec_core1_clks,
+	.num_clks = ARRAY_SIZE(vdec_core1_clks),
+};
+
+static const struct mtk_clk_desc vdec_soc_desc = {
+	.clks = vdec_soc_clks,
+	.num_clks = ARRAY_SIZE(vdec_soc_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_vdec[] = {
+	{
+		.compatible = "mediatek,mt8195-vdecsys",
+		.data = &vdec_desc,
+	}, {
+		.compatible = "mediatek,mt8195-vdecsys_core1",
+		.data = &vdec_core1_desc,
+	}, {
+		.compatible = "mediatek,mt8195-vdecsys_soc",
+		.data = &vdec_soc_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_vdec_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-vdec",
+		.of_match_table = of_match_clk_mt8195_vdec,
+	},
+};
+builtin_platform_driver(clk_mt8195_vdec_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:57 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:57 +0800
Subject: [v2 17/24] clk: mediatek: Add MT8195 vdosys0 clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-18-chun-jie.chen@mediatek.com>

Add MT8195 vdosys0 clock controller which providers clock gate
control in video system.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
Integrate with mtk-mmsys driver which will pupulate device by
platform_device_register_data to start vdosys clock driver
---
 drivers/clk/mediatek/Makefile          |   2 +-
 drivers/clk/mediatek/clk-mt8195-vdo0.c | 123 +++++++++++++++++++++++++
 2 files changed, 124 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vdo0.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index ac269f6d39e3..d22731316b7c 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -82,6 +82,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
 					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
-					clk-mt8195-vdec.o
+					clk-mt8195-vdec.o clk-mt8195-vdo0.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
new file mode 100644
index 000000000000..5d8facac3a2b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs vdo0_0_cg_regs = {
+	.set_ofs = 0x104,
+	.clr_ofs = 0x108,
+	.sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs vdo0_1_cg_regs = {
+	.set_ofs = 0x114,
+	.clr_ofs = 0x118,
+	.sta_ofs = 0x110,
+};
+
+static const struct mtk_gate_regs vdo0_2_cg_regs = {
+	.set_ofs = 0x124,
+	.clr_ofs = 0x128,
+	.sta_ofs = 0x120,
+};
+
+#define GATE_VDO0_0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdo0_0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_VDO0_1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdo0_1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_VDO0_2(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdo0_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate vdo0_clks[] = {
+	/* VDO0_0 */
+	GATE_VDO0_0(CLK_VDO0_DISP_OVL0, "vdo0_disp_ovl0", "top_vpp", 0),
+	GATE_VDO0_0(CLK_VDO0_DISP_COLOR0, "vdo0_disp_color0", "top_vpp", 2),
+	GATE_VDO0_0(CLK_VDO0_DISP_COLOR1, "vdo0_disp_color1", "top_vpp", 3),
+	GATE_VDO0_0(CLK_VDO0_DISP_CCORR0, "vdo0_disp_ccorr0", "top_vpp", 4),
+	GATE_VDO0_0(CLK_VDO0_DISP_CCORR1, "vdo0_disp_ccorr1", "top_vpp", 5),
+	GATE_VDO0_0(CLK_VDO0_DISP_AAL0, "vdo0_disp_aal0", "top_vpp", 6),
+	GATE_VDO0_0(CLK_VDO0_DISP_AAL1, "vdo0_disp_aal1", "top_vpp", 7),
+	GATE_VDO0_0(CLK_VDO0_DISP_GAMMA0, "vdo0_disp_gamma0", "top_vpp", 8),
+	GATE_VDO0_0(CLK_VDO0_DISP_GAMMA1, "vdo0_disp_gamma1", "top_vpp", 9),
+	GATE_VDO0_0(CLK_VDO0_DISP_DITHER0, "vdo0_disp_dither0", "top_vpp", 10),
+	GATE_VDO0_0(CLK_VDO0_DISP_DITHER1, "vdo0_disp_dither1", "top_vpp", 11),
+	GATE_VDO0_0(CLK_VDO0_DISP_OVL1, "vdo0_disp_ovl1", "top_vpp", 16),
+	GATE_VDO0_0(CLK_VDO0_DISP_WDMA0, "vdo0_disp_wdma0", "top_vpp", 17),
+	GATE_VDO0_0(CLK_VDO0_DISP_WDMA1, "vdo0_disp_wdma1", "top_vpp", 18),
+	GATE_VDO0_0(CLK_VDO0_DISP_RDMA0, "vdo0_disp_rdma0", "top_vpp", 19),
+	GATE_VDO0_0(CLK_VDO0_DISP_RDMA1, "vdo0_disp_rdma1", "top_vpp", 20),
+	GATE_VDO0_0(CLK_VDO0_DSI0, "vdo0_dsi0", "top_vpp", 21),
+	GATE_VDO0_0(CLK_VDO0_DSI1, "vdo0_dsi1", "top_vpp", 22),
+	GATE_VDO0_0(CLK_VDO0_DSC_WRAP0, "vdo0_dsc_wrap0", "top_vpp", 23),
+	GATE_VDO0_0(CLK_VDO0_VPP_MERGE0, "vdo0_vpp_merge0", "top_vpp", 24),
+	GATE_VDO0_0(CLK_VDO0_DP_INTF0, "vdo0_dp_intf0", "top_vpp", 25),
+	GATE_VDO0_0(CLK_VDO0_DISP_MUTEX0, "vdo0_disp_mutex0", "top_vpp", 26),
+	GATE_VDO0_0(CLK_VDO0_DISP_IL_ROT0, "vdo0_disp_il_rot0", "top_vpp", 27),
+	GATE_VDO0_0(CLK_VDO0_APB_BUS, "vdo0_apb_bus", "top_vpp", 28),
+	GATE_VDO0_0(CLK_VDO0_FAKE_ENG0, "vdo0_fake_eng0", "top_vpp", 29),
+	GATE_VDO0_0(CLK_VDO0_FAKE_ENG1, "vdo0_fake_eng1", "top_vpp", 30),
+	/* VDO0_1 */
+	GATE_VDO0_1(CLK_VDO0_DL_ASYNC0, "vdo0_dl_async0", "top_vpp", 0),
+	GATE_VDO0_1(CLK_VDO0_DL_ASYNC1, "vdo0_dl_async1", "top_vpp", 1),
+	GATE_VDO0_1(CLK_VDO0_DL_ASYNC2, "vdo0_dl_async2", "top_vpp", 2),
+	GATE_VDO0_1(CLK_VDO0_DL_ASYNC3, "vdo0_dl_async3", "top_vpp", 3),
+	GATE_VDO0_1(CLK_VDO0_DL_ASYNC4, "vdo0_dl_async4", "top_vpp", 4),
+	GATE_VDO0_1(CLK_VDO0_DISP_MONITOR0, "vdo0_disp_monitor0", "top_vpp", 5),
+	GATE_VDO0_1(CLK_VDO0_DISP_MONITOR1, "vdo0_disp_monitor1", "top_vpp", 6),
+	GATE_VDO0_1(CLK_VDO0_DISP_MONITOR2, "vdo0_disp_monitor2", "top_vpp", 7),
+	GATE_VDO0_1(CLK_VDO0_DISP_MONITOR3, "vdo0_disp_monitor3", "top_vpp", 8),
+	GATE_VDO0_1(CLK_VDO0_DISP_MONITOR4, "vdo0_disp_monitor4", "top_vpp", 9),
+	GATE_VDO0_1(CLK_VDO0_SMI_GALS, "vdo0_smi_gals", "top_vpp", 10),
+	GATE_VDO0_1(CLK_VDO0_SMI_COMMON, "vdo0_smi_common", "top_vpp", 11),
+	GATE_VDO0_1(CLK_VDO0_SMI_EMI, "vdo0_smi_emi", "top_vpp", 12),
+	GATE_VDO0_1(CLK_VDO0_SMI_IOMMU, "vdo0_smi_iommu", "top_vpp", 13),
+	GATE_VDO0_1(CLK_VDO0_SMI_LARB, "vdo0_smi_larb", "top_vpp", 14),
+	GATE_VDO0_1(CLK_VDO0_SMI_RSI, "vdo0_smi_rsi", "top_vpp", 15),
+	/* VDO0_2 */
+	GATE_VDO0_2(CLK_VDO0_DSI0_DSI, "vdo0_dsi0_dsi", "top_dsi_occ", 0),
+	GATE_VDO0_2(CLK_VDO0_DSI1_DSI, "vdo0_dsi1_dsi", "top_dsi_occ", 8),
+	GATE_VDO0_2(CLK_VDO0_DP_INTF0_DP_INTF, "vdo0_dp_intf0_dp_intf", "top_edp", 16),
+};
+
+static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->parent->of_node;
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_VDO0_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	r = mtk_clk_register_gates(node, vdo0_clks, ARRAY_SIZE(vdo0_clks), clk_data);
+	if (r)
+		goto free_vdo0_data;
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto free_vdo0_data;
+
+	return r;
+
+free_vdo0_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static struct platform_driver clk_mt8195_vdo0_drv = {
+	.probe = clk_mt8195_vdo0_probe,
+	.driver = {
+		.name = "clk-mt8195-vdo0",
+	},
+};
+builtin_platform_driver(clk_mt8195_vdo0_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:59 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:59 +0800
Subject: [v2 19/24] clk: mediatek: Add MT8195 vencsys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-20-chun-jie.chen@mediatek.com>

Add MT8195 vencsys clock controller which provide clock gate
control for video encoder.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile          |  2 +-
 drivers/clk/mediatek/clk-mt8195-venc.c | 69 ++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-venc.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 3c8c8cdbd3ef..82ffcc4f2c52 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -82,6 +82,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
 					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
-					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o
+					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-venc.c b/drivers/clk/mediatek/clk-mt8195-venc.c
new file mode 100644
index 000000000000..10702a4ad5ff
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-venc.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate venc_clks[] = {
+	GATE_VENC(CLK_VENC_LARB, "venc_larb", "top_venc", 0),
+	GATE_VENC(CLK_VENC_VENC, "venc_venc", "top_venc", 4),
+	GATE_VENC(CLK_VENC_JPGENC, "venc_jpgenc", "top_venc", 8),
+	GATE_VENC(CLK_VENC_JPGDEC, "venc_jpgdec", "top_venc", 12),
+	GATE_VENC(CLK_VENC_JPGDEC_C1, "venc_jpgdec_c1", "top_venc", 16),
+	GATE_VENC(CLK_VENC_GALS, "venc_gals", "top_venc", 28),
+};
+
+static const struct mtk_gate venc_core1_clks[] = {
+	GATE_VENC(CLK_VENC_CORE1_LARB, "venc_core1_larb", "top_venc", 0),
+	GATE_VENC(CLK_VENC_CORE1_VENC, "venc_core1_venc", "top_venc", 4),
+	GATE_VENC(CLK_VENC_CORE1_JPGENC, "venc_core1_jpgenc", "top_venc", 8),
+	GATE_VENC(CLK_VENC_CORE1_JPGDEC, "venc_core1_jpgdec", "top_venc", 12),
+	GATE_VENC(CLK_VENC_CORE1_JPGDEC_C1, "venc_core1_jpgdec_c1", "top_venc", 16),
+	GATE_VENC(CLK_VENC_CORE1_GALS, "venc_core1_gals", "top_venc", 28),
+};
+
+static const struct mtk_clk_desc venc_desc = {
+	.clks = venc_clks,
+	.num_clks = ARRAY_SIZE(venc_clks),
+};
+
+static const struct mtk_clk_desc venc_core1_desc = {
+	.clks = venc_core1_clks,
+	.num_clks = ARRAY_SIZE(venc_core1_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_venc[] = {
+	{
+		.compatible = "mediatek,mt8195-vencsys",
+		.data = &venc_desc,
+	}, {
+		.compatible = "mediatek,mt8195-vencsys_core1",
+		.data = &venc_core1_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_venc_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-venc",
+		.of_match_table = of_match_clk_mt8195_venc,
+	},
+};
+builtin_platform_driver(clk_mt8195_venc_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:14:58 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:14:58 +0800
Subject: [v2 18/24] clk: mediatek: Add MT8195 vdosys1 clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-19-chun-jie.chen@mediatek.com>

Add MT8195 vdosys1 clock controller which provides clock gate
control for video system.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
Integrate with mtk-mmsys driver which will pupulate device by
platform_device_register_data to start vdosys clock driver
---
 drivers/clk/mediatek/Makefile          |   2 +-
 drivers/clk/mediatek/clk-mt8195-vdo1.c | 140 +++++++++++++++++++++++++
 2 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vdo1.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index d22731316b7c..3c8c8cdbd3ef 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -82,6 +82,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
 					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
-					clk-mt8195-vdec.o clk-mt8195-vdo0.o
+					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/clk-mt8195-vdo1.c
new file mode 100644
index 000000000000..6ecff1e72443
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs vdo1_0_cg_regs = {
+	.set_ofs = 0x104,
+	.clr_ofs = 0x108,
+	.sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs vdo1_1_cg_regs = {
+	.set_ofs = 0x124,
+	.clr_ofs = 0x128,
+	.sta_ofs = 0x120,
+};
+
+static const struct mtk_gate_regs vdo1_2_cg_regs = {
+	.set_ofs = 0x134,
+	.clr_ofs = 0x138,
+	.sta_ofs = 0x130,
+};
+
+static const struct mtk_gate_regs vdo1_3_cg_regs = {
+	.set_ofs = 0x144,
+	.clr_ofs = 0x148,
+	.sta_ofs = 0x140,
+};
+
+#define GATE_VDO1_0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdo1_0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_VDO1_1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdo1_1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_VDO1_2(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdo1_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_VDO1_3(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdo1_3_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate vdo1_clks[] = {
+	/* VDO1_0 */
+	GATE_VDO1_0(CLK_VDO1_SMI_LARB2, "vdo1_smi_larb2", "top_vpp", 0),
+	GATE_VDO1_0(CLK_VDO1_SMI_LARB3, "vdo1_smi_larb3", "top_vpp", 1),
+	GATE_VDO1_0(CLK_VDO1_GALS, "vdo1_gals", "top_vpp", 2),
+	GATE_VDO1_0(CLK_VDO1_FAKE_ENG0, "vdo1_fake_eng0", "top_vpp", 3),
+	GATE_VDO1_0(CLK_VDO1_FAKE_ENG, "vdo1_fake_eng", "top_vpp", 4),
+	GATE_VDO1_0(CLK_VDO1_MDP_RDMA0, "vdo1_mdp_rdma0", "top_vpp", 5),
+	GATE_VDO1_0(CLK_VDO1_MDP_RDMA1, "vdo1_mdp_rdma1", "top_vpp", 6),
+	GATE_VDO1_0(CLK_VDO1_MDP_RDMA2, "vdo1_mdp_rdma2", "top_vpp", 7),
+	GATE_VDO1_0(CLK_VDO1_MDP_RDMA3, "vdo1_mdp_rdma3", "top_vpp", 8),
+	GATE_VDO1_0(CLK_VDO1_VPP_MERGE0, "vdo1_vpp_merge0", "top_vpp", 9),
+	GATE_VDO1_0(CLK_VDO1_VPP_MERGE1, "vdo1_vpp_merge1", "top_vpp", 10),
+	GATE_VDO1_0(CLK_VDO1_VPP_MERGE2, "vdo1_vpp_merge2", "top_vpp", 11),
+	GATE_VDO1_0(CLK_VDO1_VPP_MERGE3, "vdo1_vpp_merge3", "top_vpp", 12),
+	GATE_VDO1_0(CLK_VDO1_VPP_MERGE4, "vdo1_vpp_merge4", "top_vpp", 13),
+	GATE_VDO1_0(CLK_VDO1_VPP2_TO_VDO1_DL_ASYNC, "vdo1_vpp2_to_vdo1_dl_async", "top_vpp", 14),
+	GATE_VDO1_0(CLK_VDO1_VPP3_TO_VDO1_DL_ASYNC, "vdo1_vpp3_to_vdo1_dl_async", "top_vpp", 15),
+	GATE_VDO1_0(CLK_VDO1_DISP_MUTEX, "vdo1_disp_mutex", "top_vpp", 16),
+	GATE_VDO1_0(CLK_VDO1_MDP_RDMA4, "vdo1_mdp_rdma4", "top_vpp", 17),
+	GATE_VDO1_0(CLK_VDO1_MDP_RDMA5, "vdo1_mdp_rdma5", "top_vpp", 18),
+	GATE_VDO1_0(CLK_VDO1_MDP_RDMA6, "vdo1_mdp_rdma6", "top_vpp", 19),
+	GATE_VDO1_0(CLK_VDO1_MDP_RDMA7, "vdo1_mdp_rdma7", "top_vpp", 20),
+	GATE_VDO1_0(CLK_VDO1_DP_INTF0_MM, "vdo1_dp_intf0_mm", "top_vpp", 21),
+	GATE_VDO1_0(CLK_VDO1_DPI0_MM, "vdo1_dpi0_mm", "top_vpp", 22),
+	GATE_VDO1_0(CLK_VDO1_DPI1_MM, "vdo1_dpi1_mm", "top_vpp", 23),
+	GATE_VDO1_0(CLK_VDO1_DISP_MONITOR, "vdo1_disp_monitor", "top_vpp", 24),
+	GATE_VDO1_0(CLK_VDO1_MERGE0_DL_ASYNC, "vdo1_merge0_dl_async", "top_vpp", 25),
+	GATE_VDO1_0(CLK_VDO1_MERGE1_DL_ASYNC, "vdo1_merge1_dl_async", "top_vpp", 26),
+	GATE_VDO1_0(CLK_VDO1_MERGE2_DL_ASYNC, "vdo1_merge2_dl_async", "top_vpp", 27),
+	GATE_VDO1_0(CLK_VDO1_MERGE3_DL_ASYNC, "vdo1_merge3_dl_async", "top_vpp", 28),
+	GATE_VDO1_0(CLK_VDO1_MERGE4_DL_ASYNC, "vdo1_merge4_dl_async", "top_vpp", 29),
+	GATE_VDO1_0(CLK_VDO1_VDO0_DSC_TO_VDO1_DL_ASYNC, "vdo1_vdo0_dsc_to_vdo1_dl_async",
+		    "top_vpp", 30),
+	GATE_VDO1_0(CLK_VDO1_VDO0_MERGE_TO_VDO1_DL_ASYNC, "vdo1_vdo0_merge_to_vdo1_dl_async",
+		    "top_vpp", 31),
+	/* VDO1_1 */
+	GATE_VDO1_1(CLK_VDO1_HDR_VDO_FE0, "vdo1_hdr_vdo_fe0", "top_vpp", 0),
+	GATE_VDO1_1(CLK_VDO1_HDR_GFX_FE0, "vdo1_hdr_gfx_fe0", "top_vpp", 1),
+	GATE_VDO1_1(CLK_VDO1_HDR_VDO_BE, "vdo1_hdr_vdo_be", "top_vpp", 2),
+	GATE_VDO1_1(CLK_VDO1_HDR_VDO_FE1, "vdo1_hdr_vdo_fe1", "top_vpp", 16),
+	GATE_VDO1_1(CLK_VDO1_HDR_GFX_FE1, "vdo1_hdr_gfx_fe1", "top_vpp", 17),
+	GATE_VDO1_1(CLK_VDO1_DISP_MIXER, "vdo1_disp_mixer", "top_vpp", 18),
+	GATE_VDO1_1(CLK_VDO1_HDR_VDO_FE0_DL_ASYNC, "vdo1_hdr_vdo_fe0_dl_async", "top_vpp", 19),
+	GATE_VDO1_1(CLK_VDO1_HDR_VDO_FE1_DL_ASYNC, "vdo1_hdr_vdo_fe1_dl_async", "top_vpp", 20),
+	GATE_VDO1_1(CLK_VDO1_HDR_GFX_FE0_DL_ASYNC, "vdo1_hdr_gfx_fe0_dl_async", "top_vpp", 21),
+	GATE_VDO1_1(CLK_VDO1_HDR_GFX_FE1_DL_ASYNC, "vdo1_hdr_gfx_fe1_dl_async", "top_vpp", 22),
+	GATE_VDO1_1(CLK_VDO1_HDR_VDO_BE_DL_ASYNC, "vdo1_hdr_vdo_be_dl_async", "top_vpp", 23),
+	/* VDO1_2 */
+	GATE_VDO1_2(CLK_VDO1_DPI0, "vdo1_dpi0", "top_vpp", 0),
+	GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPI0, "vdo1_disp_monitor_dpi0", "top_vpp", 1),
+	GATE_VDO1_2(CLK_VDO1_DPI1, "vdo1_dpi1", "top_vpp", 8),
+	GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPI1, "vdo1_disp_monitor_dpi1", "top_vpp", 9),
+	GATE_VDO1_2(CLK_VDO1_DPINTF, "vdo1_dpintf", "top_vpp", 16),
+	GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPINTF, "vdo1_disp_monitor_dpintf", "top_vpp", 17),
+	/* VDO1_3 */
+	GATE_VDO1_3(CLK_VDO1_26M_SLOW, "vdo1_26m_slow", "clk26m", 8),
+};
+
+static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->parent->of_node;
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_VDO1_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	r = mtk_clk_register_gates(node, vdo1_clks, ARRAY_SIZE(vdo1_clks), clk_data);
+	if (r)
+		goto free_vdo1_data;
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto free_vdo1_data;
+
+	return r;
+
+free_vdo1_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static struct platform_driver clk_mt8195_vdo1_drv = {
+	.probe = clk_mt8195_vdo1_probe,
+	.driver = {
+		.name = "clk-mt8195-vdo1",
+	},
+};
+builtin_platform_driver(clk_mt8195_vdo1_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:15:02 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:15:02 +0800
Subject: [v2 22/24] clk: mediatek: Add MT8195 wpesys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-23-chun-jie.chen@mediatek.com>

Add MT8195 wpesys clock controllers which provide clock gate
control in Wrapping Engine.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |   2 +-
 drivers/clk/mediatek/clk-mt8195-wpe.c | 143 ++++++++++++++++++++++++++
 2 files changed, 144 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-wpe.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 402a809ff6ac..dfe7047c6795 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -83,6 +83,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
 					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
 					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o clk-mt8195-vpp0.o \
-					clk-mt8195-vpp1.o
+					clk-mt8195-vpp1.o clk-mt8195-wpe.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-wpe.c b/drivers/clk/mediatek/clk-mt8195-wpe.c
new file mode 100644
index 000000000000..7e92a3cab497
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-wpe.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs wpe_cg_regs = {
+	.set_ofs = 0x0,
+	.clr_ofs = 0x0,
+	.sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs wpe_vpp0_cg_regs = {
+	.set_ofs = 0x58,
+	.clr_ofs = 0x58,
+	.sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs wpe_vpp1_cg_regs = {
+	.set_ofs = 0x5c,
+	.clr_ofs = 0x5c,
+	.sta_ofs = 0x5c,
+};
+
+#define GATE_WPE(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &wpe_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+#define GATE_WPE_VPP0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &wpe_vpp0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+#define GATE_WPE_VPP1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &wpe_vpp1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+static const struct mtk_gate wpe_clks[] = {
+	GATE_WPE(CLK_WPE_VPP0, "wpe_vpp0", "top_wpe_vpp", 16),
+	GATE_WPE(CLK_WPE_VPP1, "wpe_vpp1", "top_wpe_vpp", 17),
+	GATE_WPE(CLK_WPE_SMI_LARB7, "wpe_smi_larb7", "top_wpe_vpp", 18),
+	GATE_WPE(CLK_WPE_SMI_LARB8, "wpe_smi_larb8", "top_wpe_vpp", 19),
+	GATE_WPE(CLK_WPE_EVENT_TX, "wpe_event_tx", "top_wpe_vpp", 20),
+	GATE_WPE(CLK_WPE_SMI_LARB7_P, "wpe_smi_larb7_p", "top_wpe_vpp", 24),
+	GATE_WPE(CLK_WPE_SMI_LARB8_P, "wpe_smi_larb8_p", "top_wpe_vpp", 25),
+};
+
+static const struct mtk_gate wpe_vpp0_clks[] = {
+	/* WPE_VPP0 */
+	GATE_WPE_VPP0(CLK_WPE_VPP0_VGEN, "wpe_vpp0_vgen", "top_img", 0),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_EXT, "wpe_vpp0_ext", "top_img", 1),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_VFC, "wpe_vpp0_vfc", "top_img", 2),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_CACH0_TOP, "wpe_vpp0_cach0_top", "top_img", 3),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_CACH0_DMA, "wpe_vpp0_cach0_dma", "top_img", 4),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_CACH1_TOP, "wpe_vpp0_cach1_top", "top_img", 5),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_CACH1_DMA, "wpe_vpp0_cach1_dma", "top_img", 6),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_CACH2_TOP, "wpe_vpp0_cach2_top", "top_img", 7),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_CACH2_DMA, "wpe_vpp0_cach2_dma", "top_img", 8),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_CACH3_TOP, "wpe_vpp0_cach3_top", "top_img", 9),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_CACH3_DMA, "wpe_vpp0_cach3_dma", "top_img", 10),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_PSP, "wpe_vpp0_psp", "top_img", 11),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_PSP2, "wpe_vpp0_psp2", "top_img", 12),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_SYNC, "wpe_vpp0_sync", "top_img", 13),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_C24, "wpe_vpp0_c24", "top_img", 14),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_MDP_CROP, "wpe_vpp0_mdp_crop", "top_img", 15),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_ISP_CROP, "wpe_vpp0_isp_crop", "top_img", 16),
+	GATE_WPE_VPP0(CLK_WPE_VPP0_TOP, "wpe_vpp0_top", "top_img", 17),
+	/* WPE_VPP1 */
+	GATE_WPE_VPP1(CLK_WPE_VPP0_VECI, "wpe_vpp0_veci", "top_img", 0),
+	GATE_WPE_VPP1(CLK_WPE_VPP0_VEC2I, "wpe_vpp0_vec2i", "top_img", 1),
+	GATE_WPE_VPP1(CLK_WPE_VPP0_VEC3I, "wpe_vpp0_vec3i", "top_img", 2),
+	GATE_WPE_VPP1(CLK_WPE_VPP0_WPEO, "wpe_vpp0_wpeo", "top_img", 3),
+	GATE_WPE_VPP1(CLK_WPE_VPP0_MSKO, "wpe_vpp0_msko", "top_img", 4),
+};
+
+static const struct mtk_gate wpe_vpp1_clks[] = {
+	/* WPE_VPP0 */
+	GATE_WPE_VPP0(CLK_WPE_VPP1_VGEN, "wpe_vpp1_vgen", "top_img", 0),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_EXT, "wpe_vpp1_ext", "top_img", 1),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_VFC, "wpe_vpp1_vfc", "top_img", 2),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_CACH0_TOP, "wpe_vpp1_cach0_top", "top_img", 3),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_CACH0_DMA, "wpe_vpp1_cach0_dma", "top_img", 4),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_CACH1_TOP, "wpe_vpp1_cach1_top", "top_img", 5),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_CACH1_DMA, "wpe_vpp1_cach1_dma", "top_img", 6),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_CACH2_TOP, "wpe_vpp1_cach2_top", "top_img", 7),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_CACH2_DMA, "wpe_vpp1_cach2_dma", "top_img", 8),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_CACH3_TOP, "wpe_vpp1_cach3_top", "top_img", 9),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_CACH3_DMA, "wpe_vpp1_cach3_dma", "top_img", 10),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_PSP, "wpe_vpp1_psp", "top_img", 11),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_PSP2, "wpe_vpp1_psp2", "top_img", 12),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_SYNC, "wpe_vpp1_sync", "top_img", 13),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_C24, "wpe_vpp1_c24", "top_img", 14),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_MDP_CROP, "wpe_vpp1_mdp_crop", "top_img", 15),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_ISP_CROP, "wpe_vpp1_isp_crop", "top_img", 16),
+	GATE_WPE_VPP0(CLK_WPE_VPP1_TOP, "wpe_vpp1_top", "top_img", 17),
+	/* WPE_VPP1 */
+	GATE_WPE_VPP1(CLK_WPE_VPP1_VECI, "wpe_vpp1_veci", "top_img", 0),
+	GATE_WPE_VPP1(CLK_WPE_VPP1_VEC2I, "wpe_vpp1_vec2i", "top_img", 1),
+	GATE_WPE_VPP1(CLK_WPE_VPP1_VEC3I, "wpe_vpp1_vec3i", "top_img", 2),
+	GATE_WPE_VPP1(CLK_WPE_VPP1_WPEO, "wpe_vpp1_wpeo", "top_img", 3),
+	GATE_WPE_VPP1(CLK_WPE_VPP1_MSKO, "wpe_vpp1_msko", "top_img", 4),
+};
+
+static const struct mtk_clk_desc wpe_desc = {
+	.clks = wpe_clks,
+	.num_clks = ARRAY_SIZE(wpe_clks),
+};
+
+static const struct mtk_clk_desc wpe_vpp0_desc = {
+	.clks = wpe_vpp0_clks,
+	.num_clks = ARRAY_SIZE(wpe_vpp0_clks),
+};
+
+static const struct mtk_clk_desc wpe_vpp1_desc = {
+	.clks = wpe_vpp1_clks,
+	.num_clks = ARRAY_SIZE(wpe_vpp1_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_wpe[] = {
+	{
+		.compatible = "mediatek,mt8195-wpesys",
+		.data = &wpe_desc,
+	}, {
+		.compatible = "mediatek,mt8195-wpesys_vpp0",
+		.data = &wpe_vpp0_desc,
+	}, {
+		.compatible = "mediatek,mt8195-wpesys_vpp1",
+		.data = &wpe_vpp1_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_wpe_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-wpe",
+		.of_match_table = of_match_clk_mt8195_wpe,
+	},
+};
+builtin_platform_driver(clk_mt8195_wpe_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:15:00 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:15:00 +0800
Subject: [v2 20/24] clk: mediatek: Add MT8195 vppsys0 clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-21-chun-jie.chen@mediatek.com>

Add MT8195 vppsys0 clock controller which provides clock gate
controller for Video Processor Pipe.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile          |   2 +-
 drivers/clk/mediatek/clk-mt8195-vpp0.c | 110 +++++++++++++++++++++++++
 2 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vpp0.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 82ffcc4f2c52..8694f070e2d0 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -82,6 +82,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
 					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
-					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o
+					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o clk-mt8195-vpp0.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-vpp0.c b/drivers/clk/mediatek/clk-mt8195-vpp0.c
new file mode 100644
index 000000000000..736bf0948540
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-vpp0.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs vpp0_0_cg_regs = {
+	.set_ofs = 0x24,
+	.clr_ofs = 0x28,
+	.sta_ofs = 0x20,
+};
+
+static const struct mtk_gate_regs vpp0_1_cg_regs = {
+	.set_ofs = 0x30,
+	.clr_ofs = 0x34,
+	.sta_ofs = 0x2c,
+};
+
+static const struct mtk_gate_regs vpp0_2_cg_regs = {
+	.set_ofs = 0x3c,
+	.clr_ofs = 0x40,
+	.sta_ofs = 0x38,
+};
+
+#define GATE_VPP0_0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vpp0_0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_VPP0_1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vpp0_1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_VPP0_2(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vpp0_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate vpp0_clks[] = {
+	/* VPP0_0 */
+	GATE_VPP0_0(CLK_VPP0_MDP_FG, "vpp0_mdp_fg", "top_vpp", 1),
+	GATE_VPP0_0(CLK_VPP0_STITCH, "vpp0_stitch", "top_vpp", 2),
+	GATE_VPP0_0(CLK_VPP0_PADDING, "vpp0_padding", "top_vpp", 7),
+	GATE_VPP0_0(CLK_VPP0_MDP_TCC, "vpp0_mdp_tcc", "top_vpp", 8),
+	GATE_VPP0_0(CLK_VPP0_WARP0_ASYNC_TX, "vpp0_warp0_async_tx", "top_vpp", 10),
+	GATE_VPP0_0(CLK_VPP0_WARP1_ASYNC_TX, "vpp0_warp1_async_tx", "top_vpp", 11),
+	GATE_VPP0_0(CLK_VPP0_MUTEX, "vpp0_mutex", "top_vpp", 13),
+	GATE_VPP0_0(CLK_VPP0_VPP02VPP1_RELAY, "vpp0_vpp02vpp1_relay", "top_vpp", 14),
+	GATE_VPP0_0(CLK_VPP0_VPP12VPP0_ASYNC, "vpp0_vpp12vpp0_async", "top_vpp", 15),
+	GATE_VPP0_0(CLK_VPP0_MMSYSRAM_TOP, "vpp0_mmsysram_top", "top_vpp", 16),
+	GATE_VPP0_0(CLK_VPP0_MDP_AAL, "vpp0_mdp_aal", "top_vpp", 17),
+	GATE_VPP0_0(CLK_VPP0_MDP_RSZ, "vpp0_mdp_rsz", "top_vpp", 18),
+	/* VPP0_1 */
+	GATE_VPP0_1(CLK_VPP0_SMI_COMMON, "vpp0_smi_common", "top_vpp", 0),
+	GATE_VPP0_1(CLK_VPP0_GALS_VDO0_LARB0, "vpp0_gals_vdo0_larb0", "top_vpp", 1),
+	GATE_VPP0_1(CLK_VPP0_GALS_VDO0_LARB1, "vpp0_gals_vdo0_larb1", "top_vpp", 2),
+	GATE_VPP0_1(CLK_VPP0_GALS_VENCSYS, "vpp0_gals_vencsys", "top_vpp", 3),
+	GATE_VPP0_1(CLK_VPP0_GALS_VENCSYS_CORE1, "vpp0_gals_vencsys_core1", "top_vpp", 4),
+	GATE_VPP0_1(CLK_VPP0_GALS_INFRA, "vpp0_gals_infra", "top_vpp", 5),
+	GATE_VPP0_1(CLK_VPP0_GALS_CAMSYS, "vpp0_gals_camsys", "top_vpp", 6),
+	GATE_VPP0_1(CLK_VPP0_GALS_VPP1_LARB5, "vpp0_gals_vpp1_larb5", "top_vpp", 7),
+	GATE_VPP0_1(CLK_VPP0_GALS_VPP1_LARB6, "vpp0_gals_vpp1_larb6", "top_vpp", 8),
+	GATE_VPP0_1(CLK_VPP0_SMI_REORDER, "vpp0_smi_reorder", "top_vpp", 9),
+	GATE_VPP0_1(CLK_VPP0_SMI_IOMMU, "vpp0_smi_iommu", "top_vpp", 10),
+	GATE_VPP0_1(CLK_VPP0_GALS_IMGSYS_CAMSYS, "vpp0_gals_imgsys_camsys", "top_vpp", 11),
+	GATE_VPP0_1(CLK_VPP0_MDP_RDMA, "vpp0_mdp_rdma", "top_vpp", 12),
+	GATE_VPP0_1(CLK_VPP0_MDP_WROT, "vpp0_mdp_wrot", "top_vpp", 13),
+	GATE_VPP0_1(CLK_VPP0_GALS_EMI0_EMI1, "vpp0_gals_emi0_emi1", "top_vpp", 16),
+	GATE_VPP0_1(CLK_VPP0_SMI_SUB_COMMON_REORDER, "vpp0_smi_sub_common_reorder", "top_vpp", 17),
+	GATE_VPP0_1(CLK_VPP0_SMI_RSI, "vpp0_smi_rsi", "top_vpp", 18),
+	GATE_VPP0_1(CLK_VPP0_SMI_COMMON_LARB4, "vpp0_smi_common_larb4", "top_vpp", 19),
+	GATE_VPP0_1(CLK_VPP0_GALS_VDEC_VDEC_CORE1, "vpp0_gals_vdec_vdec_core1", "top_vpp", 20),
+	GATE_VPP0_1(CLK_VPP0_GALS_VPP1_WPE, "vpp0_gals_vpp1_wpe", "top_vpp", 21),
+	GATE_VPP0_1(CLK_VPP0_GALS_VDO0_VDO1_VENCSYS_CORE1, "vpp0_gals_vdo0_vdo1_vencsys_core1",
+		    "top_vpp", 22),
+	GATE_VPP0_1(CLK_VPP0_FAKE_ENG, "vpp0_fake_eng", "top_vpp", 23),
+	GATE_VPP0_1(CLK_VPP0_MDP_HDR, "vpp0_mdp_hdr", "top_vpp", 24),
+	GATE_VPP0_1(CLK_VPP0_MDP_TDSHP, "vpp0_mdp_tdshp", "top_vpp", 25),
+	GATE_VPP0_1(CLK_VPP0_MDP_COLOR, "vpp0_mdp_color", "top_vpp", 26),
+	GATE_VPP0_1(CLK_VPP0_MDP_OVL, "vpp0_mdp_ovl", "top_vpp", 27),
+	/* VPP0_2 */
+	GATE_VPP0_2(CLK_VPP0_WARP0_RELAY, "vpp0_warp0_relay", "top_wpe_vpp", 0),
+	GATE_VPP0_2(CLK_VPP0_WARP0_MDP_DL_ASYNC, "vpp0_warp0_mdp_dl_async", "top_wpe_vpp", 1),
+	GATE_VPP0_2(CLK_VPP0_WARP1_RELAY, "vpp0_warp1_relay", "top_wpe_vpp", 2),
+	GATE_VPP0_2(CLK_VPP0_WARP1_MDP_DL_ASYNC, "vpp0_warp1_mdp_dl_async", "top_wpe_vpp", 3),
+};
+
+static const struct mtk_clk_desc vpp0_desc = {
+	.clks = vpp0_clks,
+	.num_clks = ARRAY_SIZE(vpp0_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_vpp0[] = {
+	{
+		.compatible = "mediatek,mt8195-vppsys0",
+		.data = &vpp0_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_vpp0_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-vpp0",
+		.of_match_table = of_match_clk_mt8195_vpp0,
+	},
+};
+builtin_platform_driver(clk_mt8195_vpp0_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:15:01 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:15:01 +0800
Subject: [v2 21/24] clk: mediatek: Add MT8195 vppsys1 clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-22-chun-jie.chen@mediatek.com>

Add MT8195 vppsys1 clock controller which provides clock gate
controller for Video Processor Pipe.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile          |   3 +-
 drivers/clk/mediatek/clk-mt8195-vpp1.c | 108 +++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-vpp1.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 8694f070e2d0..402a809ff6ac 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
 					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
-					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o clk-mt8195-vpp0.o
+					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o clk-mt8195-vpp0.o \
+					clk-mt8195-vpp1.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-vpp1.c b/drivers/clk/mediatek/clk-mt8195-vpp1.c
new file mode 100644
index 000000000000..774dbd87980f
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-vpp1.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs vpp1_0_cg_regs = {
+	.set_ofs = 0x104,
+	.clr_ofs = 0x108,
+	.sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs vpp1_1_cg_regs = {
+	.set_ofs = 0x114,
+	.clr_ofs = 0x118,
+	.sta_ofs = 0x110,
+};
+
+#define GATE_VPP1_0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vpp1_0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_VPP1_1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vpp1_1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate vpp1_clks[] = {
+	/* VPP1_0 */
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_OVL, "vpp1_svpp1_mdp_ovl", "top_vpp", 0),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_TCC, "vpp1_svpp1_mdp_tcc", "top_vpp", 1),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_WROT, "vpp1_svpp1_mdp_wrot", "top_vpp", 2),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_VPP_PAD, "vpp1_svpp1_vpp_pad", "top_vpp", 3),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_WROT, "vpp1_svpp2_mdp_wrot", "top_vpp", 4),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_VPP_PAD, "vpp1_svpp2_vpp_pad", "top_vpp", 5),
+	GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_WROT, "vpp1_svpp3_mdp_wrot", "top_vpp", 6),
+	GATE_VPP1_0(CLK_VPP1_SVPP3_VPP_PAD, "vpp1_svpp3_vpp_pad", "top_vpp", 7),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_RDMA, "vpp1_svpp1_mdp_rdma", "top_vpp", 8),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_FG, "vpp1_svpp1_mdp_fg", "top_vpp", 9),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_RDMA, "vpp1_svpp2_mdp_rdma", "top_vpp", 10),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_FG, "vpp1_svpp2_mdp_fg", "top_vpp", 11),
+	GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_RDMA, "vpp1_svpp3_mdp_rdma", "top_vpp", 12),
+	GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_FG, "vpp1_svpp3_mdp_fg", "top_vpp", 13),
+	GATE_VPP1_0(CLK_VPP1_VPP_SPLIT, "vpp1_vpp_split", "top_vpp", 14),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_VDO0_DL_RELAY, "vpp1_svpp2_vdo0_dl_relay", "top_vpp", 15),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_TDSHP, "vpp1_svpp1_mdp_tdshp", "top_vpp", 16),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_COLOR, "vpp1_svpp1_mdp_color", "top_vpp", 17),
+	GATE_VPP1_0(CLK_VPP1_SVPP3_VDO1_DL_RELAY, "vpp1_svpp3_vdo1_dl_relay", "top_vpp", 18),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_VPP_MERGE, "vpp1_svpp2_vpp_merge", "top_vpp", 19),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_COLOR, "vpp1_svpp2_mdp_color", "top_vpp", 20),
+	GATE_VPP1_0(CLK_VPP1_VPPSYS1_GALS, "vpp1_vppsys1_gals", "top_vpp", 21),
+	GATE_VPP1_0(CLK_VPP1_SVPP3_VPP_MERGE, "vpp1_svpp3_vpp_merge", "top_vpp", 22),
+	GATE_VPP1_0(CLK_VPP1_SVPP3_MDP_COLOR, "vpp1_svpp3_mdp_color", "top_vpp", 23),
+	GATE_VPP1_0(CLK_VPP1_VPPSYS1_LARB, "vpp1_vppsys1_larb", "top_vpp", 24),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_RSZ, "vpp1_svpp1_mdp_rsz", "top_vpp", 25),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_HDR, "vpp1_svpp1_mdp_hdr", "top_vpp", 26),
+	GATE_VPP1_0(CLK_VPP1_SVPP1_MDP_AAL, "vpp1_svpp1_mdp_aal", "top_vpp", 27),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_HDR, "vpp1_svpp2_mdp_hdr", "top_vpp", 28),
+	GATE_VPP1_0(CLK_VPP1_SVPP2_MDP_AAL, "vpp1_svpp2_mdp_aal", "top_vpp", 29),
+	GATE_VPP1_0(CLK_VPP1_DL_ASYNC, "vpp1_dl_async", "top_vpp", 30),
+	GATE_VPP1_0(CLK_VPP1_LARB5_FAKE_ENG, "vpp1_larb5_fake_eng", "top_vpp", 31),
+	/* VPP1_1 */
+	GATE_VPP1_1(CLK_VPP1_SVPP3_MDP_HDR, "vpp1_svpp3_mdp_hdr", "top_vpp", 0),
+	GATE_VPP1_1(CLK_VPP1_SVPP3_MDP_AAL, "vpp1_svpp3_mdp_aal", "top_vpp", 1),
+	GATE_VPP1_1(CLK_VPP1_SVPP2_VDO1_DL_RELAY, "vpp1_svpp2_vdo1_dl_relay", "top_vpp", 2),
+	GATE_VPP1_1(CLK_VPP1_LARB6_FAKE_ENG, "vpp1_larb6_fake_eng", "top_vpp", 3),
+	GATE_VPP1_1(CLK_VPP1_SVPP2_MDP_RSZ, "vpp1_svpp2_mdp_rsz", "top_vpp", 4),
+	GATE_VPP1_1(CLK_VPP1_SVPP3_MDP_RSZ, "vpp1_svpp3_mdp_rsz", "top_vpp", 5),
+	GATE_VPP1_1(CLK_VPP1_SVPP3_VDO0_DL_RELAY, "vpp1_svpp3_vdo0_dl_relay", "top_vpp", 6),
+	GATE_VPP1_1(CLK_VPP1_DISP_MUTEX, "vpp1_disp_mutex", "top_vpp", 7),
+	GATE_VPP1_1(CLK_VPP1_SVPP2_MDP_TDSHP, "vpp1_svpp2_mdp_tdshp", "top_vpp", 8),
+	GATE_VPP1_1(CLK_VPP1_SVPP3_MDP_TDSHP, "vpp1_svpp3_mdp_tdshp", "top_vpp", 9),
+	GATE_VPP1_1(CLK_VPP1_VPP0_DL1_RELAY, "vpp1_vpp0_dl1_relay", "top_vpp", 10),
+	GATE_VPP1_1(CLK_VPP1_HDMI_META, "vpp1_hdmi_meta", "hdmirx_p", 11),
+	GATE_VPP1_1(CLK_VPP1_VPP_SPLIT_HDMI, "vpp1_vpp_split_hdmi", "hdmirx_p", 12),
+	GATE_VPP1_1(CLK_VPP1_DGI_IN, "vpp1_dgi_in", "in_dgi", 13),
+	GATE_VPP1_1(CLK_VPP1_DGI_OUT, "vpp1_dgi_out", "top_dgi_out", 14),
+	GATE_VPP1_1(CLK_VPP1_VPP_SPLIT_DGI, "vpp1_vpp_split_dgi", "top_dgi_out", 15),
+	GATE_VPP1_1(CLK_VPP1_VPP0_DL_ASYNC, "vpp1_vpp0_dl_async", "top_vpp", 16),
+	GATE_VPP1_1(CLK_VPP1_VPP0_DL_RELAY, "vpp1_vpp0_dl_relay", "top_vpp", 17),
+	GATE_VPP1_1(CLK_VPP1_VPP_SPLIT_26M, "vpp1_vpp_split_26m", "clk26m", 26),
+};
+
+static const struct mtk_clk_desc vpp1_desc = {
+	.clks = vpp1_clks,
+	.num_clks = ARRAY_SIZE(vpp1_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_vpp1[] = {
+	{
+		.compatible = "mediatek,mt8195-vppsys1",
+		.data = &vpp1_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_vpp1_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-vpp1",
+		.of_match_table = of_match_clk_mt8195_vpp1,
+	},
+};
+builtin_platform_driver(clk_mt8195_vpp1_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:15:03 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:15:03 +0800
Subject: [v2 23/24] clk: mediatek: Add MT8195 imp i2c wrapper clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-24-chun-jie.chen@mediatek.com>

Add MT8195 imp i2c wrapper clock controllers which provide clock gate
control in IIC IP blocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile                 |  2 +-
 .../clk/mediatek/clk-mt8195-imp_iic_wrap.c    | 68 +++++++++++++++++++
 2 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index dfe7047c6795..4288ad39ba41 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -83,6 +83,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
 					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
 					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o clk-mt8195-vpp0.o \
-					clk-mt8195-vpp1.o clk-mt8195-wpe.o
+					clk-mt8195-vpp1.o clk-mt8195-wpe.o clk-mt8195-imp_iic_wrap.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
new file mode 100644
index 000000000000..0720903cd1f7
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/mt8195-clk.h>
+
+static const struct mtk_gate_regs imp_iic_wrap_cg_regs = {
+	.set_ofs = 0xe08,
+	.clr_ofs = 0xe04,
+	.sta_ofs = 0xe00,
+};
+
+#define GATE_IMP_IIC_WRAP(_id, _name, _parent, _shift)				\
+	GATE_MTK_FLAGS(_id, _name, _parent, &imp_iic_wrap_cg_regs, _shift,	\
+		&mtk_clk_gate_ops_setclr, CLK_OPS_PARENT_ENABLE)
+
+static const struct mtk_gate imp_iic_wrap_s_clks[] = {
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C5, "imp_iic_wrap_s_i2c5", "top_i2c", 0),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C6, "imp_iic_wrap_s_i2c6", "top_i2c", 1),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C7, "imp_iic_wrap_s_i2c7", "top_i2c", 2),
+};
+
+static const struct mtk_gate imp_iic_wrap_w_clks[] = {
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_W_I2C0, "imp_iic_wrap_w_i2c0", "top_i2c", 0),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_W_I2C1, "imp_iic_wrap_w_i2c1", "top_i2c", 1),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_W_I2C2, "imp_iic_wrap_w_i2c2", "top_i2c", 2),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_W_I2C3, "imp_iic_wrap_w_i2c3", "top_i2c", 3),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_W_I2C4, "imp_iic_wrap_w_i2c4", "top_i2c", 4),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_s_desc = {
+	.clks = imp_iic_wrap_s_clks,
+	.num_clks = ARRAY_SIZE(imp_iic_wrap_s_clks),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_w_desc = {
+	.clks = imp_iic_wrap_w_clks,
+	.num_clks = ARRAY_SIZE(imp_iic_wrap_w_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8195_imp_iic_wrap[] = {
+	{
+		.compatible = "mediatek,mt8195-imp_iic_wrap_s",
+		.data = &imp_iic_wrap_s_desc,
+	}, {
+		.compatible = "mediatek,mt8195-imp_iic_wrap_w",
+		.data = &imp_iic_wrap_w_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8195_imp_iic_wrap_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8195-imp_iic_wrap",
+		.of_match_table = of_match_clk_mt8195_imp_iic_wrap,
+	},
+};
+builtin_platform_driver(clk_mt8195_imp_iic_wrap_drv);
-- 
2.18.0

From chun-jie.chen at mediatek.com  Fri Aug 20 04:15:04 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Fri, 20 Aug 2021 19:15:04 +0800
Subject: [v2 24/24] clk: mediatek: Add MT8195 apusys clock support
In-Reply-To: <20210820111504.350-1-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
Message-ID: <20210820111504.350-25-chun-jie.chen@mediatek.com>

Add MT8195 apusys clock controller which provides PLLs
in AI processor Unit.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile                |  2 +-
 drivers/clk/mediatek/clk-mt8195-apusys_pll.c | 92 ++++++++++++++++++++
 2 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8195-apusys_pll.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 4288ad39ba41..e10b1d6b0cf4 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -83,6 +83,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
 					clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
 					clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o clk-mt8195-vpp0.o \
-					clk-mt8195-vpp1.o clk-mt8195-wpe.o clk-mt8195-imp_iic_wrap.o
+					clk-mt8195-vpp1.o clk-mt8195-wpe.o clk-mt8195-imp_iic_wrap.o clk-mt8195-apusys_pll.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
new file mode 100644
index 000000000000..6868c9ff3e18
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#define MT8195_PLL_FMAX		(3800UL * MHZ)
+#define MT8195_PLL_FMIN		(1500UL * MHZ)
+#define MT8195_INTEGER_BITS	(8)
+#define MT8195_PCW_BITS		(22)
+#define MT8195_POSDIV_SHIFT	(24)
+#define MT8195_PLL_EN_BIT	(0)
+#define MT8195_PCW_SHIFT	(0)
+
+/*
+ * The "en_reg" and "pcw_chg_reg" fields are standard offset register compared
+ * with "reg" field, so set zero to imply it.
+ * No tuner control in apu pll, so set "tuner_XXX" as zero to imply it.
+ * No rst or post divider enable in apu pll, so set "rst_bar_mask" and "en_mask"
+ * as zero to imply it.
+ */
+#define PLL(_id, _name, _reg, _pwr_reg, _pd_reg, _pcw_reg) {		\
+		.id = _id,						\
+		.name = _name,						\
+		.reg = _reg,						\
+		.pwr_reg = _pwr_reg,					\
+		.en_mask = 0,						\
+		.flags = 0,						\
+		.rst_bar_mask = 0,					\
+		.fmax = MT8195_PLL_FMAX,				\
+		.fmin = MT8195_PLL_FMIN,				\
+		.pcwbits = MT8195_PCW_BITS,				\
+		.pcwibits = MT8195_INTEGER_BITS,			\
+		.pd_reg = _pd_reg,					\
+		.pd_shift = MT8195_POSDIV_SHIFT,			\
+		.tuner_reg = 0,						\
+		.tuner_en_reg = 0,					\
+		.tuner_en_bit = 0,					\
+		.pcw_reg = _pcw_reg,					\
+		.pcw_shift = MT8195_PCW_SHIFT,				\
+		.pcw_chg_reg = 0,					\
+		.en_reg = 0,						\
+		.pll_en_bit = MT8195_PLL_EN_BIT,			\
+	}
+
+static const struct mtk_pll_data apusys_plls[] = {
+	PLL(CLK_APUSYS_PLL_APUPLL, "apusys_pll_apupll", 0x008, 0x014, 0x00c, 0x00c),
+	PLL(CLK_APUSYS_PLL_NPUPLL, "apusys_pll_npupll", 0x018, 0x024, 0x01c, 0x01c),
+	PLL(CLK_APUSYS_PLL_APUPLL1, "apusys_pll_apupll1", 0x028, 0x034, 0x02c, 0x02c),
+	PLL(CLK_APUSYS_PLL_APUPLL2, "apusys_pll_apupll2", 0x038, 0x044, 0x03c, 0x03c),
+};
+
+static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_APUSYS_PLL_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto free_apusys_pll_data;
+
+	return r;
+
+free_apusys_pll_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt8195_apusys_pll[] = {
+	{ .compatible = "mediatek,mt8195-apusys_pll", },
+	{}
+};
+
+static struct platform_driver clk_mt8195_apusys_pll_drv = {
+	.probe = clk_mt8195_apusys_pll_probe,
+	.driver = {
+		.name = "clk-mt8195-apusys_pll",
+		.of_match_table = of_match_clk_mt8195_apusys_pll,
+	},
+};
+builtin_platform_driver(clk_mt8195_apusys_pll_drv);
-- 
2.18.0

From amit.kachhap at arm.com  Fri Aug 20 04:35:05 2021
From: amit.kachhap at arm.com (Amit Kachhap)
Date: Fri, 20 Aug 2021 17:05:05 +0530
Subject: [PATCH] kselftest/arm64: pac: Fix skipping of tests on systems
 without PAC
In-Reply-To: <20210820105531.GP4177@sirena.org.uk>
References: <20210819165723.43903-1-broonie@kernel.org>
 <a988b3e2-5f88-fbd5-99da-2066a65a17b2@arm.com>
 <20210820105531.GP4177@sirena.org.uk>
Message-ID: <20d96c3e-36f8-276f-ab02-daf5bc7c976f@arm.com>



On 8/20/21 4:25 PM, Mark Brown wrote:
> On Fri, Aug 20, 2021 at 12:39:39PM +0530, Amit Kachhap wrote:
>> On 8/19/21 10:27 PM, Mark Brown wrote:
> 
>>> -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \
>>> +	if (!(hwcaps & HWCAP_PACA))					\
>>> +		SKIP(return, "PAUTH not enabled"); \
>>>    } while (0)
>>>    #define ASSERT_GENERIC_PAUTH_ENABLED() \
> 
>> May be ASSERT_GENERIC_PAUTH_ENABLED can be replaced with
>> something like VERIFY_GENERIC_PAUTH_ENABLED
> 
> I thought briefly about bikeshedding the name but didn't come up with
> anything that was sufficiently better/clearer.
> 
>> or can be modified like below and instead of failing it skips with a
>> message
> 
>>    -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \
>>    +	ASSERT_NE(0, hwcaps & HWCAP_PACA) SKIP(return, "PAUTH not enabled");
> 
> That's what the patch does?

Agree, I saw few other testcases where ASSERT is used along with SKIP.
(tools/testing/selftests/core/close_range_test.c) so this way 
ASSERT_GENERIC_* macro will be clear. There will be just an extra
log like "hwcaps & HWCAP_PACA = 0" in this case.

Probably your way is consistent as other tests in arm64 also just
skips due to HWCAP mismatch.

> 


From broonie at kernel.org  Fri Aug 20 05:00:09 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Aug 2021 13:00:09 +0100
Subject: [PATCH] kselftest/arm64: pac: Fix skipping of tests on systems
 without PAC
In-Reply-To: <20d96c3e-36f8-276f-ab02-daf5bc7c976f@arm.com>
References: <20210819165723.43903-1-broonie@kernel.org>
 <a988b3e2-5f88-fbd5-99da-2066a65a17b2@arm.com>
 <20210820105531.GP4177@sirena.org.uk>
 <20d96c3e-36f8-276f-ab02-daf5bc7c976f@arm.com>
Message-ID: <20210820120009.GQ4177@sirena.org.uk>

On Fri, Aug 20, 2021 at 05:05:05PM +0530, Amit Kachhap wrote:
> On 8/20/21 4:25 PM, Mark Brown wrote:
> > On Fri, Aug 20, 2021 at 12:39:39PM +0530, Amit Kachhap wrote:

> > >    -	ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \
> > >    +	ASSERT_NE(0, hwcaps & HWCAP_PACA) SKIP(return, "PAUTH not enabled");

> > That's what the patch does?

> Agree, I saw few other testcases where ASSERT is used along with SKIP.
> (tools/testing/selftests/core/close_range_test.c) so this way
> ASSERT_GENERIC_* macro will be clear. There will be just an extra
> log like "hwcaps & HWCAP_PACA = 0" in this case.

I'm not 100% sure I follow what you're saying here?  I don't see a log
message saying "hwcaps & HWCAP_PACA = 0" on non-PAC systems, or is that
what you're saying you want to see?

> Probably your way is consistent as other tests in arm64 also just
> skips due to HWCAP mismatch.

Right, we can't usefully run tests for features not present in the
system - this sort of thing is the intent of the kselftest skip feature.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210820/5c256dbc/attachment-0001.sig>

From wens at csie.org  Fri Aug 20 05:06:12 2021
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 20 Aug 2021 20:06:12 +0800
Subject: [PATCH 2/2] arm64: dts: allwinner: align thermal zone node names
 with dtschema
In-Reply-To: <20210820081710.83908-1-krzysztof.kozlowski@canonical.com>
References: <20210820081645.83796-1-krzysztof.kozlowski@canonical.com>
 <20210820081710.83908-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGb2v66Mx76p0G4nsfAtdLOuzj462Ok1BkqRTgT1BD1ndDqVwA@mail.gmail.com>

On Fri, Aug 20, 2021 at 4:17 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Align the name of thermal zone node to dtschema to fix warnings like:
>
>   arch/arm64/boot/dts/allwinner/sun50i-a100-allwinner-perf1.dt.yaml:
>     thermal-zones: 'cpu-thermal-zone', 'ddr-thermal-zone', 'gpu-thermal-zone' do not match any of the regexes: '^[a-zA-Z][a-zA-Z0-9\\-]{1,12}-thermal$', 'pinctrl-[0-9]+'
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Acked-by: Chen-Yu Tsai <wens at csie.org>


From wens at csie.org  Fri Aug 20 05:11:11 2021
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 20 Aug 2021 20:11:11 +0800
Subject: [PATCH 1/2] arm64: dts: allwinner: h5: align operating-points
 table name with dtschema
In-Reply-To: <20210820081645.83796-1-krzysztof.kozlowski@canonical.com>
References: <20210820081645.83796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGb2v66EnW+iO2CPueauRob+b53pNFEuL6LUoSYb09_TN+=_cw@mail.gmail.com>

On Fri, Aug 20, 2021 at 4:16 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Align the name of operating-points node to dtschema to fix warnings like:
>
>   arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dt.yaml:
>     cpu-opp-table: $nodename:0: 'cpu-opp-table' does not match '^opp-table(-[a-z0-9]+)?$'
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
> index b2657201957e..0b6914a165b0 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
> @@ -2,7 +2,7 @@
>  // Copyright (C) 2020 Chen-Yu Tsai <wens at csie.org>
>
>  / {
> -       cpu_opp_table: cpu-opp-table {
> +       cpu_opp_table: opp-table-0 {

Maybe we should just reorder the name? Name it "opp-table-cpu" instead.
That way if and when we add one for the GPU, we don't accidentally
clash on the name.


ChenYu


From maz at kernel.org  Fri Aug 20 05:22:18 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 13:22:18 +0100
Subject: [PATCH] irqchip/apple-aic: fix irq_disable from within irq
 handlers
In-Reply-To: <20210812100942.17206-1-sven@svenpeter.dev>
References: <20210812100942.17206-1-sven@svenpeter.dev>
Message-ID: <162946212617.2128248.7705849006178271820.b4-ty@kernel.org>

On Thu, 12 Aug 2021 12:09:42 +0200, Sven Peter wrote:
> When disable_irq_nosync for an interrupt is called from within its
> interrupt handler, this interrupt is only marked as disabled with the
> intention to mask it when it triggers again.
> The AIC hardware however automatically masks the interrupt when it is read.
> aic_irq_eoi then unmasks it again if it's not disabled *and* not masked.
> This results in a state mismatch between the hardware state and the
> state kept in irq_data: The hardware interrupt is masked but
> IRQD_IRQ_MASKED is not set. Any further calls to unmask_irq will directly
> return and the interrupt can never be enabled again.
> 
> [...]

Applied to irq/misc-5.15, thanks!

[1/1] irqchip/apple-aic: fix irq_disable from within irq handlers
      commit: 0fb038ba08dba0a5e937b79a67ed9c21ab5b59c5

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From jikos at kernel.org  Fri Aug 20 05:25:30 2021
From: jikos at kernel.org (Jiri Kosina)
Date: Fri, 20 Aug 2021 14:25:30 +0200 (CEST)
Subject: [PATCH 1/3] HID: thrustmaster: Fix memory leaks in probe
In-Reply-To: <20210730165110.24667-1-novikov@ispras.ru>
References: <20210730165110.24667-1-novikov@ispras.ru>
Message-ID: <nycvar.YFH.7.76.2108201425170.15313@cbobk.fhfr.pm>

On Fri, 30 Jul 2021, Evgeny Novikov wrote:

> When thrustmaster_probe() handles errors of usb_submit_urb() it does not
> free allocated resources and fails. The patch fixes that.
> 
> Found by Linux Driver Verification project (linuxtesting.org).
> 
> Signed-off-by: Evgeny Novikov <novikov at ispras.ru>

I've applied all three fixes, thanks.

-- 
Jiri Kosina
SUSE Labs



From joro at 8bytes.org  Fri Aug 20 05:38:55 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Fri, 20 Aug 2021 14:38:55 +0200
Subject: [PATCH -next] iommu/arm-smmu: Fix missing unlock on error in
 arm_smmu_device_group()
In-Reply-To: <20210820104111.GC17267@willie-the-truck>
References: <20210820074949.1946576-1-yangyingliang@huawei.com>
 <20210820104111.GC17267@willie-the-truck>
Message-ID: <YR+iX0HQrr0Un2Kl@8bytes.org>

On Fri, Aug 20, 2021 at 11:41:11AM +0100, Will Deacon wrote:
> Joerg -- please can you throw this on top?

Sure, now applied, thanks.


From lorenzo.pieralisi at arm.com  Fri Aug 20 05:41:21 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 20 Aug 2021 13:41:21 +0100
Subject: [PATCH 0/2] PCI: aardvark: Resource fixes
In-Reply-To: <20210624215546.4015-1-pali@kernel.org>
References: <20210624215546.4015-1-pali@kernel.org>
Message-ID: <162946326563.4746.9940152798050527363.b4-ty@arm.com>

On Thu, 24 Jun 2021 23:55:44 +0200, Pali Roh?r wrote:
> This patch series fixes configuring PCIe resources (IO and MEM) in
> aardvark controller driver. It is required to initialize BARs on systems
> with more cards, e.g. NVMe disks and WiFi AX cards.
> 
> Pali Roh?r (2):
>   PCI: aardvark: Configure PCIe resources from 'ranges' DT property
>   arm64: dts: marvell: armada-37xx: Extend PCIe MEM space
> 
> [...]

Applied to pci/aardvark, thanks!

[1/1] PCI: aardvark: Configure PCIe resources from 'ranges' DT property
      https://git.kernel.org/lpieralisi/pci/c/64f160e19e

Thanks,
Lorenzo


From mtosatti at redhat.com  Fri Aug 20 05:46:11 2021
From: mtosatti at redhat.com (Marcelo Tosatti)
Date: Fri, 20 Aug 2021 09:46:11 -0300
Subject: [PATCH v7 3/6] KVM: x86: Report host tsc and realtime values in
 KVM_GET_CLOCK
In-Reply-To: <20210816001130.3059564-4-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
 <20210816001130.3059564-4-oupton@google.com>
Message-ID: <20210820124611.GA77176@fuller.cnet>

On Mon, Aug 16, 2021 at 12:11:27AM +0000, Oliver Upton wrote:
> Handling the migration of TSCs correctly is difficult, in part because
> Linux does not provide userspace with the ability to retrieve a (TSC,
> realtime) clock pair for a single instant in time. In lieu of a more
> convenient facility, KVM can report similar information in the kvm_clock
> structure.
> 
> Provide userspace with a host TSC & realtime pair iff the realtime clock
> is based on the TSC. If userspace provides KVM_SET_CLOCK with a valid
> realtime value, advance the KVM clock by the amount of elapsed time. Do
> not step the KVM clock backwards, though, as it is a monotonic
> oscillator.
> 
> Suggested-by: Paolo Bonzini <pbonzini at redhat.com>
> Signed-off-by: Oliver Upton <oupton at google.com>

This is a good idea. Userspace could check if host and destination
clocks are up to a certain difference and not use the feature if
not appropriate.

Is there a qemu patch for it?



From krzysztof.kozlowski at canonical.com  Fri Aug 20 05:48:51 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 14:48:51 +0200
Subject: [PATCH 1/2] arm64: dts: allwinner: h5: align operating-points
 table name with dtschema
In-Reply-To: <CAGb2v66EnW+iO2CPueauRob+b53pNFEuL6LUoSYb09_TN+=_cw@mail.gmail.com>
References: <20210820081645.83796-1-krzysztof.kozlowski@canonical.com>
 <CAGb2v66EnW+iO2CPueauRob+b53pNFEuL6LUoSYb09_TN+=_cw@mail.gmail.com>
Message-ID: <adea5de5-30db-72b4-9a65-121b0c3032b5@canonical.com>

On 20/08/2021 14:11, Chen-Yu Tsai wrote:
> On Fri, Aug 20, 2021 at 4:16 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Align the name of operating-points node to dtschema to fix warnings like:
>>
>>   arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-r1s-h5.dt.yaml:
>>     cpu-opp-table: $nodename:0: 'cpu-opp-table' does not match '^opp-table(-[a-z0-9]+)?$'
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
>> index b2657201957e..0b6914a165b0 100644
>> --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi
>> @@ -2,7 +2,7 @@
>>  // Copyright (C) 2020 Chen-Yu Tsai <wens at csie.org>
>>
>>  / {
>> -       cpu_opp_table: cpu-opp-table {
>> +       cpu_opp_table: opp-table-0 {
> 
> Maybe we should just reorder the name? Name it "opp-table-cpu" instead.
> That way if and when we add one for the GPU, we don't accidentally
> clash on the name.

Although the schema allows such name, but still the devicetree
specification says that name should be generic (representing generic
type of a device). Just like there is a "clock-controller" or
"nand-controller", there should be generic "opp-table".


Best regards,
Krzysztof


From maz at kernel.org  Fri Aug 20 05:58:56 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 13:58:56 +0100
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
In-Reply-To: <061bafb6-b0fe-bd7c-1567-a642d3ddd4a5@arm.com>
References: <20210811171505.1502090-1-wenst@chromium.org>
 <87fsvfal4n.wl-maz@kernel.org>
 <79eabae1-e4a3-7a12-7aa0-3680569584e5@arm.com>
 <871r6yajy7.wl-maz@kernel.org>
 <061bafb6-b0fe-bd7c-1567-a642d3ddd4a5@arm.com>
Message-ID: <87pmu8qnlb.wl-maz@kernel.org>

Hi Alex,

On Thu, 12 Aug 2021 15:24:03 +0100,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On 8/12/21 2:09 PM, Marc Zyngier wrote:
> > On Thu, 12 Aug 2021 12:51:34 +0100,
> > Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> >> Hi,
> >>
> >> After re-familiarizing myself with the spec, it starting to look to
> >> me like indeed there's something not quite right (read as: totally
> >> broken) with my patch.
> >>
> >> Arm IHI 0069F, the pseudocode for reading ICC_RPR_EL1 (page 11-797),
> >> says that the priority returned is unchanged if SCTLR_EL3.FIQ ==
> >> 0.
> > Sure, but look at what ICC_RPR_EL1 does for FIQ==1:
> >
> > <quote>
> > if HaveEL(EL3) && !IsSecure() && SCR_EL3.FIQ == '1' then
> >     // A Non-secure GIC access and Group 0 inaccessible to Non-secure.
> >         if pPriority<7> == '0' then
> > 	    // Priority is in Secure half and not visible to Non-secure
> > 	    Priority = Zeros();
> >         elsif !IsOnes(pPriority) then
> > 	    // Non-secure access and not idle, so physical priority must be shifted
> >             pPriority<7:0> = (pPriority AND PRIMask())<6:0>:'0';
> >
> > return ZeroExtend(pPriority);
> > </quote>
> >
> > See how the the priority is shifted *left* (bits [6:0] end up in
> > [7:1])?
> 
> Yes, when SCR_EL3.FIQ=1, but gic_nonsecure_priorities is enabled
> when SCR_EL3.FIQ=0 (gic_has_group0()). In that case ICC_RPR_EL1
> returns (what I assume to be) the highest priority interrupt from
> ICC_AP0R_EL1, ICC_AP1R_EL1NS and ICC_AP1R_EL1S. Isn't that the
> secure view (or Distributor value) of the priority?

Yup. I guess I got confused with what "non-secure" priorities mean in
this context.

[...]

> I don't see how that is the case - ICC_RPR_EL1 contains the priority
> value as seen by the Distributor, and non-secure priorities get
> right-shifted when SCR_EL3.FIQ=0, meaning that GICD_INT_NMI_PRI
> becomes (GICD_INT_NMI_PRI >> 1) | 0x80 in the Distributor. Can you
> elaborate where I'm contradicting myself?

I think I know why I confused myself. When FIQ==0, G0 is NS. On the
face of it, this should mean that no shift occurs. However, G1S is
still in the picture, and we get the extra shift to preserve the
ordering with G1S.

This is a different configuration from that of a guest, where G0 is
also NS, but there is no shift at all, as there is no G1S.

The GIC strikes back. Again.

I run some more tests with this patch, and merge it of nothing breaks.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From chien-yu.lin at mediatek.com  Fri Aug 20 06:02:10 2021
From: chien-yu.lin at mediatek.com (Chien-Yu Lin)
Date: Fri, 20 Aug 2021 21:02:10 +0800
Subject: [PATCH] ASoc: fix ASoC driver to support ops to register get_time_info
Message-ID: <20210820130210.3321-1-chien-yu.lin@mediatek.com>

From: "chien-yu.lin" <chien-yu.lin at mediatek.com>

Because ASoC soc_new_pcm() function didn't register
.get_time_info() ops and cause snd_pcm_update_hw_ptr0() can not find
substream->ops->get_time_info, it will not be called due to ASoC
driver which register in HW device driver.

Add .get_time_info() ops in ASoC soc_new_pcm() and
register by snd_pcm_set_ops() function.
If HW device driver want to implment timestamp by itself,
ASoC should register .get_time_info function.

Signed-off-by: chien-yu.lin <chien-yu.lin at mediatek.com>
---
 include/sound/soc-component.h |  4 ++++
 sound/soc/soc-component.c     | 21 +++++++++++++++++++++
 sound/soc/soc-pcm.c           |  2 ++
 3 files changed, 27 insertions(+)

diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h
index 8c4d6830597f..52b5228b7a8d 100644
--- a/include/sound/soc-component.h
+++ b/include/sound/soc-component.h
@@ -484,6 +484,10 @@ int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream);
 int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
 				    int channel, unsigned long pos,
 				    void __user *buf, unsigned long bytes);
+int snd_soc_pcm_component_get_time_info(struct snd_pcm_substream *substream,
+					struct timespec64 *system_ts, struct timespec64 *audio_ts,
+					struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
+					struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
 struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
 					unsigned long offset);
 int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c
index 3a5e84e16a87..56caec7ec00b 100644
--- a/sound/soc/soc-component.c
+++ b/sound/soc/soc-component.c
@@ -1000,6 +1000,27 @@ int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
 	return -EINVAL;
 }
 
+int snd_soc_pcm_component_get_time_info(struct snd_pcm_substream *substream,
+					struct timespec64 *system_ts, struct timespec64 *audio_ts,
+					struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
+					struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
+{
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct snd_soc_component *component;
+	int i;
+
+	/* FIXME. it returns 1st get_time_info now */
+	for_each_rtd_components(rtd, i, component) {
+		if (component->driver->get_time_info)
+			return soc_component_ret(component,
+				component->driver->get_time_info(component,
+				substream, system_ts, audio_ts,
+				audio_tstamp_config, audio_tstamp_report));
+	}
+
+	return -EINVAL;
+}
+
 struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
 					unsigned long offset)
 {
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index d1c570ca21ea..cff7025027a6 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2786,6 +2786,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 			rtd->ops.mmap		= snd_soc_pcm_component_mmap;
 		if (drv->ack)
 			rtd->ops.ack            = snd_soc_pcm_component_ack;
+		if (drv->get_time_info)
+			rtd->ops.get_time_info	= snd_soc_pcm_component_get_time_info;
 	}
 
 	if (playback)
-- 
2.18.0

From maz at kernel.org  Fri Aug 20 06:12:13 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 14:12:13 +0100
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-5-clin@suse.com>
 <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>
Message-ID: <87o89sqmz6.wl-maz@kernel.org>

On Thu, 12 Aug 2021 18:26:28 +0100,
Andreas F?rber <afaerber at suse.de> wrote:
> 
> Hi Chester et al.,
> 
> On 05.08.21 08:54, Chester Lin wrote:
> > Add an initial dtsi file for generic SoC features of NXP S32G2.
> > 
> > Signed-off-by: Chester Lin <clin at suse.com>
> > ---
> >  arch/arm64/boot/dts/freescale/s32g2.dtsi | 98 ++++++++++++++++++++++++
> >  1 file changed, 98 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > new file mode 100644
> > index 000000000000..3321819c1a2d
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi

[...]

> > +		gic: interrupt-controller at 50800000 {
> > +			compatible = "arm,gic-v3";
> > +			#interrupt-cells = <3>;
> > +			interrupt-controller;
> > +			reg = <0 0x50800000 0 0x10000>,
> > +			      <0 0x50880000 0 0x200000>,

That's enough redistributor space for 16 CPUs. However, you only
describe 4. Either the number of CPUs is wrong, the size is wrong, or
the GIC has been configured for more cores than the SoC has.

> > +			      <0 0x50400000 0 0x2000>,
> > +			      <0 0x50410000 0 0x2000>,
> > +			      <0 0x50420000 0 0x2000>;
> 
> Please order reg after compatible by convention, and sort
> interrupt-controller or at least #interrupt-cells (applying to
> consumers) last, after the below one applying to this device itself.
> 
> > +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
> > +						 IRQ_TYPE_LEVEL_HIGH)>;
> > +		};
> 
> CC'ing Marc for additional GIC scrutiny, often the sizes are wrong.

There is more than just sizes. The interrupt specifier for the
maintenance interrupt is also wrong.

	M.

-- 
Without deviation from the norm, progress is not possible.


From robin.murphy at arm.com  Fri Aug 20 06:14:42 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 20 Aug 2021 14:14:42 +0100
Subject: [PATCH] iommu/io-pgtable: Abstract iommu_iotlb_gather access
Message-ID: <83672ee76f6405c82845a55c148fa836f56fbbc1.1629465282.git.robin.murphy@arm.com>

Previously io-pgtable merely passed the iommu_iotlb_gather pointer
through to helpers, but now it has grown its own direct dereference.
This turns out to break the build for !IOMMU_API configs where the
structure only has a dummy definition. It will probably also crash
drivers who don't use the gather mechanism and simply pass in NULL.

Wrap this dereference in a suitable helper which can both be stubbed
out for !IOMMU_API and encapsulate a NULL check otherwise.

Fixes: 7a7c5badf858 ("iommu: Indicate queued flushes via gather data")
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---
 drivers/iommu/io-pgtable-arm-v7s.c |  2 +-
 drivers/iommu/io-pgtable-arm.c     |  2 +-
 include/linux/iommu.h              | 10 ++++++++++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index e84478d39705..bfb6acb651e5 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -700,7 +700,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
 						ARM_V7S_BLOCK_SIZE(lvl + 1));
 				ptep = iopte_deref(pte[i], lvl, data);
 				__arm_v7s_free_table(ptep, lvl + 1, data);
-			} else if (!gather->queued) {
+			} else if (!iommu_iotlb_gather_queued(gather)) {
 				io_pgtable_tlb_add_page(iop, gather, iova, blk_size);
 			}
 			iova += blk_size;
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 9e3beace0470..dd9e47189d0d 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -650,7 +650,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 				io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
 							  ARM_LPAE_GRANULE(data));
 				__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
-			} else if (!gather->queued) {
+			} else if (!iommu_iotlb_gather_queued(gather)) {
 				io_pgtable_tlb_add_page(iop, gather, iova + i * size, size);
 			}
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index e7581c39f2df..6633040a13f9 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -594,6 +594,11 @@ static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
 	iommu_iotlb_gather_add_range(gather, iova, size);
 }
 
+static inline bool iommu_iotlb_gather_queued(struct iommu_iotlb_gather *gather)
+{
+	return gather && gather->queued;
+}
+
 /* PCI device grouping function */
 extern struct iommu_group *pci_device_group(struct device *dev);
 /* Generic device grouping function */
@@ -942,6 +947,11 @@ static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
 {
 }
 
+static inline bool iommu_iotlb_gather_queued(struct iommu_iotlb_gather *gather)
+{
+	return false;
+}
+
 static inline void iommu_device_unregister(struct iommu_device *iommu)
 {
 }
-- 
2.25.1



From jbx6244 at gmail.com  Fri Aug 20 06:19:20 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Fri, 20 Aug 2021 15:19:20 +0200
Subject: [PATCH] ARM: dts: rockchip: remove cap-mmc-highspeed property from
 mk808 &mmc0 node
Message-ID: <20210820131920.1831-1-jbx6244@gmail.com>

On the MK808 only a microSD slot is connected with the SDMMC Host Controller,
so remove the cap-mmc-highspeed property from the &mmc0 node.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm/boot/dts/rk3066a-mk808.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts
index 9790bc63b..b67f5cb51 100644
--- a/arch/arm/boot/dts/rk3066a-mk808.dts
+++ b/arch/arm/boot/dts/rk3066a-mk808.dts
@@ -123,7 +123,6 @@
 
 &mmc0 {
 	bus-width = <4>;
-	cap-mmc-highspeed;
 	cap-sd-highspeed;
 	vmmc-supply = <&vcc_sd>;
 	status = "okay";
-- 
2.20.1



From vee.khee.wong at linux.intel.com  Fri Aug 20 06:26:22 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Fri, 20 Aug 2021 21:26:22 +0800
Subject: [PATCH net] net: stmmac: fix kernel panic due to NULL pointer
 dereference of plat->est
Message-ID: <20210820132622.4175839-1-vee.khee.wong@linux.intel.com>

In the case of taprio offload is not enabled, the error handling path
causes a kernel crash due to kernel NULL pointer deference.

Fix this by adding check for NULL before attempt to access 'plat->est'
on the mutex_lock() call.

The following kernel panic is observed without this patch:

RIP: 0010:mutex_lock+0x10/0x20
Call Trace:
tc_setup_taprio+0x482/0x560 [stmmac]
kmem_cache_alloc_trace+0x13f/0x490
taprio_disable_offload.isra.0+0x9d/0x180 [sch_taprio]
taprio_destroy+0x6c/0x100 [sch_taprio]
qdisc_create+0x2e5/0x4f0
tc_modify_qdisc+0x126/0x740
rtnetlink_rcv_msg+0x12b/0x380
_raw_spin_lock_irqsave+0x19/0x40
_raw_spin_unlock_irqrestore+0x18/0x30
create_object+0x212/0x340
rtnl_calcit.isra.0+0x110/0x110
netlink_rcv_skb+0x50/0x100
netlink_unicast+0x191/0x230
netlink_sendmsg+0x243/0x470
sock_sendmsg+0x5e/0x60
____sys_sendmsg+0x20b/0x280
copy_msghdr_from_user+0x5c/0x90
__mod_memcg_state+0x87/0xf0
 ___sys_sendmsg+0x7c/0xc0
lru_cache_add+0x7f/0xa0
_raw_spin_unlock+0x16/0x30
wp_page_copy+0x449/0x890
handle_mm_fault+0x921/0xfc0
__sys_sendmsg+0x59/0xa0
do_syscall_64+0x33/0x40
entry_SYSCALL_64_after_hwframe+0x44/0xa9
---[ end trace b1f19b24368a96aa ]---

Fixes: b60189e0392f ("net: stmmac: Integrate EST with TAPRIO scheduler API")
Cc: <stable at vger.kernel.org> # 5.10.x
Signed-off-by: Wong Vee Khee <vee.khee.wong at linux.intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index 4f3b6437b114..8160087ee92f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -884,11 +884,13 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
 	return 0;
 
 disable:
-	mutex_lock(&priv->plat->est->lock);
-	priv->plat->est->enable = false;
-	stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
-			     priv->plat->clk_ptp_rate);
-	mutex_unlock(&priv->plat->est->lock);
+	if (priv->plat->est) {
+		mutex_lock(&priv->plat->est->lock);
+		priv->plat->est->enable = false;
+		stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
+				     priv->plat->clk_ptp_rate);
+		mutex_unlock(&priv->plat->est->lock);
+	}
 
 	priv->plat->fpe_cfg->enable = false;
 	stmmac_fpe_configure(priv, priv->ioaddr,
-- 
2.25.1



From alexandru.elisei at arm.com  Fri Aug 20 06:31:39 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Fri, 20 Aug 2021 14:31:39 +0100
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
In-Reply-To: <20210811171505.1502090-1-wenst@chromium.org>
References: <20210811171505.1502090-1-wenst@chromium.org>
Message-ID: <d279bf85-aeac-1745-9c65-911794343e36@arm.com>

Hello,

Pending Marc's testing (I realized I don't have any hardware to test this on at
the moment), this patch looks correct to me. One comment below.

On 8/11/21 6:15 PM, Chen-Yu Tsai wrote:
> When non-secure priorities are used, compared to the raw priority set,
> the value read back from RPR is also right-shifted by one and the
> highest bit set.
>
> Add a macro to do the modifications to the raw priority when doing the
> comparison against the RPR value. This corrects the pseudo-NMI behavior
> when non-secure priorities in the GIC are used. Tested on 5.10 with
> the "IPI as pseudo-NMI" series [1] applied on MT8195.
>
> [1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg at linaro.org/
>
> Fixes: 336780590990 ("irqchip/gic-v3: Support pseudo-NMIs when SCR_EL3.FIQ == 0")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/irqchip/irq-gic-v3.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index e0f4debe64e1..e7a0b55413db 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -100,6 +100,15 @@ EXPORT_SYMBOL(gic_pmr_sync);
>  DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities);
>  EXPORT_SYMBOL(gic_nonsecure_priorities);
>  
> +#define GICD_INT_RPR_PRI(priority)					\
> +	({								\
> +		u32 __priority = (priority);				\
> +		if (static_branch_unlikely(&gic_nonsecure_priorities))	\
> +			__priority = 0x80 | (__priority >> 1);		\
> +									\
> +		__priority;						\
> +	})

Would you mind adding a comment to the macro explaining why it's needed? This
behaviour is rather subtle and I'm hoping it will save someone's time at some
point in the future. I'm thinking something like this (please ignore it if you can
think of something better):

When the Non-secure world has access to group 0 interrupts (SCR_EL3.FIQ = 0),
reading the ICC_RPR_EL1 register will return the Distributor's view of the
interrupt priority. When GIC security is enabled (GICD_CTLR.DS = 0), the interrupt
priority written by software is moved to the Non-secure range by the Distributor.
If both are true (which is the situation where gic_nonsecure_priorities gets
enabled), then we need to shift down the priority programmed by software if we
want match it against the value returned from ICC_RPR_EL1.

With a comment added:

Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>

Thanks,

Alex

> +
>  /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */
>  static refcount_t *ppi_nmi_refs;
>  
> @@ -687,7 +696,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
>  		return;
>  
>  	if (gic_supports_nmi() &&
> -	    unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) {
> +	    unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) {
>  		gic_handle_nmi(irqnr, regs);
>  		return;
>  	}


From robh+dt at kernel.org  Fri Aug 20 06:31:43 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 20 Aug 2021 08:31:43 -0500
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <aaa53a2a-c15b-8017-4e44-dd3f883b2378@canonical.com>
References: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
 <73eebe7b-46da-137b-1938-09a5b453320a@arm.com>
 <0ec05a0b-9499-3bf4-a231-ea53b1cf99ed@canonical.com>
 <CAL_JsqLOHY0P=Y8-Ss0cYr54SWgpV0zktEg8p-Cj_F+juDQNoA@mail.gmail.com>
 <aaa53a2a-c15b-8017-4e44-dd3f883b2378@canonical.com>
Message-ID: <CAL_Jsq+iG1t=yxsyp2whd_L4p=9udrSvZMiy-y75ppcLYK9acA@mail.gmail.com>

On Wed, Aug 18, 2021 at 9:43 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 18/08/2021 16:31, Rob Herring wrote:
> > On Mon, Aug 16, 2021 at 3:32 AM Krzysztof Kozlowski
> > <krzysztof.kozlowski at canonical.com> wrote:
> >>
> >> On 16/08/2021 09:53, Lukasz Luba wrote:
> >>> Hi Krzysztof,
> >>>
> >>> On 8/13/21 1:54 PM, Krzysztof Kozlowski wrote:
> >>>> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
> >>>> Dynamic Memory Controller to DT schema format using json-schema.
> >>>>
> >>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >>>> ---
> >>>>   .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
> >>>>   .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
> >>>>   MAINTAINERS                                   |   2 +-
> >>>
> >>> I'm not an expert in this DT scripts and why it complains. Maybe it
> >>> complains because the "samsung,exynos-ppmu" is defined in the .txt
> >>> file... (?)
> >>> Although, in general looks OK.
> >>>
> >>> Acked-by: Lukasz Luba <lukasz.luba at arm.com>
> >>
> >> I think the warning (triggered by DT_CHECKER_FLAGS=-m) can be ignored
> >> because it complains about compatible in example which is not present in
> >> the bindings. Usually it means someone wrote example not matching the
> >> bindings (e.g. a typo in compatible) but here it is on purpose.
> >
> > Ultimately, it will mean the binding is undocumented (or a typo). But
> > right now, it means the binding is undocumented with a schema. It's
> > off by default because there's still about 80 warnings. It's turned on
> > for the bot so we don't add more. So please don't ignore it.
> >
>
> By "Ignore" I meant here that it is a false positive, so it can be
> ignored. The warning is about compatible "samsung,exynos-ppmu" used in
> the example. However this exynos-ppmu is not part of this bindings and
> is documented elsewhere:
> Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt

Yes, I understood all that. Let me be clear. I don't want examples
which don't have a schema. So drop the node or convert
exynos-ppmu.txt.

First, when we do add a schema, then we likely have to go fix the
examples. It happens a lot and is not caught with folks using
DT_SCHEMA_FILES. Second, I don't like reporting errors that users
should have gotten by default. We can't turn this check on by default
until the 80 or so cases we already have in the binding examples are
fixed.

Rob


From patchwork-bot+netdevbpf at kernel.org  Fri Aug 20 06:40:08 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 20 Aug 2021 13:40:08 +0000
Subject: [PATCH net-next v2 0/2] Adding Frame DMA functionality to Sparx5
In-Reply-To: <20210819073940.1589383-1-steen.hegelund@microchip.com>
References: <20210819073940.1589383-1-steen.hegelund@microchip.com>
Message-ID: <162946680859.23508.488868985364862077.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (refs/heads/master):

On Thu, 19 Aug 2021 09:39:38 +0200 you wrote:
> v2:
>     Removed an unused variable (proc_ctrl) from sparx5_fdma_start.
> 
> This add frame DMA functionality to the Sparx5 platform.
> 
> Until now the Sparx5 SwitchDev driver has been using register based
> injection and extraction when sending frames to/from the host CPU.
> 
> [...]

Here is the summary with links:
  - [net-next,v2,1/2] net: sparx5: switchdev: adding frame DMA functionality
    https://git.kernel.org/netdev/net-next/c/10615907e9b5
  - [net-next,v2,2/2] arm64: dts: sparx5: Add the Sparx5 switch frame DMA support
    https://git.kernel.org/netdev/net-next/c/920c293af8d0

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From krzysztof.kozlowski at canonical.com  Fri Aug 20 06:53:38 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 15:53:38 +0200
Subject: [PATCH] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <CAL_Jsq+iG1t=yxsyp2whd_L4p=9udrSvZMiy-y75ppcLYK9acA@mail.gmail.com>
References: <20210813125414.104467-1-krzysztof.kozlowski@canonical.com>
 <73eebe7b-46da-137b-1938-09a5b453320a@arm.com>
 <0ec05a0b-9499-3bf4-a231-ea53b1cf99ed@canonical.com>
 <CAL_JsqLOHY0P=Y8-Ss0cYr54SWgpV0zktEg8p-Cj_F+juDQNoA@mail.gmail.com>
 <aaa53a2a-c15b-8017-4e44-dd3f883b2378@canonical.com>
 <CAL_Jsq+iG1t=yxsyp2whd_L4p=9udrSvZMiy-y75ppcLYK9acA@mail.gmail.com>
Message-ID: <d3cf3485-6996-5cb9-6a8a-9b868f86bbea@canonical.com>

On 20/08/2021 15:31, Rob Herring wrote:
> On Wed, Aug 18, 2021 at 9:43 AM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 18/08/2021 16:31, Rob Herring wrote:
>>> On Mon, Aug 16, 2021 at 3:32 AM Krzysztof Kozlowski
>>> <krzysztof.kozlowski at canonical.com> wrote:
>>>>
>>>> On 16/08/2021 09:53, Lukasz Luba wrote:
>>>>> Hi Krzysztof,
>>>>>
>>>>> On 8/13/21 1:54 PM, Krzysztof Kozlowski wrote:
>>>>>> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
>>>>>> Dynamic Memory Controller to DT schema format using json-schema.
>>>>>>
>>>>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>>>> ---
>>>>>>   .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
>>>>>>   .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
>>>>>>   MAINTAINERS                                   |   2 +-
>>>>>
>>>>> I'm not an expert in this DT scripts and why it complains. Maybe it
>>>>> complains because the "samsung,exynos-ppmu" is defined in the .txt
>>>>> file... (?)
>>>>> Although, in general looks OK.
>>>>>
>>>>> Acked-by: Lukasz Luba <lukasz.luba at arm.com>
>>>>
>>>> I think the warning (triggered by DT_CHECKER_FLAGS=-m) can be ignored
>>>> because it complains about compatible in example which is not present in
>>>> the bindings. Usually it means someone wrote example not matching the
>>>> bindings (e.g. a typo in compatible) but here it is on purpose.
>>>
>>> Ultimately, it will mean the binding is undocumented (or a typo). But
>>> right now, it means the binding is undocumented with a schema. It's
>>> off by default because there's still about 80 warnings. It's turned on
>>> for the bot so we don't add more. So please don't ignore it.
>>>
>>
>> By "Ignore" I meant here that it is a false positive, so it can be
>> ignored. The warning is about compatible "samsung,exynos-ppmu" used in
>> the example. However this exynos-ppmu is not part of this bindings and
>> is documented elsewhere:
>> Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt
> 
> Yes, I understood all that. Let me be clear. I don't want examples
> which don't have a schema. So drop the node or convert
> exynos-ppmu.txt.
> 
> First, when we do add a schema, then we likely have to go fix the
> examples. It happens a lot and is not caught with folks using
> DT_SCHEMA_FILES. Second, I don't like reporting errors that users
> should have gotten by default. We can't turn this check on by default
> until the 80 or so cases we already have in the binding examples are
> fixed.

Understood, I'll send both of these bindings.


Best regards,
Krzysztof


From maz at kernel.org  Fri Aug 20 06:55:20 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 14:55:20 +0100
Subject: [PATCH] irqchip/gic-v3: Fix priority comparison when non-secure
 priorities are used
In-Reply-To: <d279bf85-aeac-1745-9c65-911794343e36@arm.com>
References: <20210811171505.1502090-1-wenst@chromium.org>
 <d279bf85-aeac-1745-9c65-911794343e36@arm.com>
Message-ID: <87mtpcqkzb.wl-maz@kernel.org>

On Fri, 20 Aug 2021 14:31:39 +0100,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hello,
> 
> Pending Marc's testing (I realized I don't have any hardware to test
> this on at the moment), this patch looks correct to me. One comment
> below.

Seems good so far. I tested it both in a VM, on a FIQ==1 host, and on
D05, which runs with FIQ==0. Can't be more broken than it was... ;-)

> 
> On 8/11/21 6:15 PM, Chen-Yu Tsai wrote:
> > When non-secure priorities are used, compared to the raw priority set,
> > the value read back from RPR is also right-shifted by one and the
> > highest bit set.
> >
> > Add a macro to do the modifications to the raw priority when doing the
> > comparison against the RPR value. This corrects the pseudo-NMI behavior
> > when non-secure priorities in the GIC are used. Tested on 5.10 with
> > the "IPI as pseudo-NMI" series [1] applied on MT8195.
> >
> > [1] https://lore.kernel.org/linux-arm-kernel/1604317487-14543-1-git-send-email-sumit.garg at linaro.org/
> >
> > Fixes: 336780590990 ("irqchip/gic-v3: Support pseudo-NMIs when SCR_EL3.FIQ == 0")
> > Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> > ---
> >  drivers/irqchip/irq-gic-v3.c | 11 ++++++++++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > index e0f4debe64e1..e7a0b55413db 100644
> > --- a/drivers/irqchip/irq-gic-v3.c
> > +++ b/drivers/irqchip/irq-gic-v3.c
> > @@ -100,6 +100,15 @@ EXPORT_SYMBOL(gic_pmr_sync);
> >  DEFINE_STATIC_KEY_FALSE(gic_nonsecure_priorities);
> >  EXPORT_SYMBOL(gic_nonsecure_priorities);
> >  
> > +#define GICD_INT_RPR_PRI(priority)					\
> > +	({								\
> > +		u32 __priority = (priority);				\
> > +		if (static_branch_unlikely(&gic_nonsecure_priorities))	\
> > +			__priority = 0x80 | (__priority >> 1);		\
> > +									\
> > +		__priority;						\
> > +	})
> 
> Would you mind adding a comment to the macro explaining why it's
> needed? This behaviour is rather subtle and I'm hoping it will save
> someone's time at some point in the future. I'm thinking something
> like this (please ignore it if you can think of something better):
> 
> When the Non-secure world has access to group 0 interrupts
> (SCR_EL3.FIQ = 0), reading the ICC_RPR_EL1 register will return the
> Distributor's view of the interrupt priority. When GIC security is
> enabled (GICD_CTLR.DS = 0), the interrupt priority written by
> software is moved to the Non-secure range by the Distributor.  If
> both are true (which is the situation where gic_nonsecure_priorities
> gets enabled), then we need to shift down the priority programmed by
> software if we want match it against the value returned from
> ICC_RPR_EL1.
> 
> With a comment added:
> 
> Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>

Let me fold this into the commit and push it out again.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From robin.murphy at arm.com  Fri Aug 20 07:17:06 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 20 Aug 2021 15:17:06 +0100
Subject: [PATCH] ARM: dts: rockchip: remove cap-mmc-highspeed property
 from mk808 &mmc0 node
In-Reply-To: <20210820131920.1831-1-jbx6244@gmail.com>
References: <20210820131920.1831-1-jbx6244@gmail.com>
Message-ID: <bf6cba99-da3b-a6fe-4e4b-f4ea6e3c6e63@arm.com>

On 2021-08-20 14:19, Johan Jonker wrote:
> On the MK808 only a microSD slot is connected with the SDMMC Host Controller,
> so remove the cap-mmc-highspeed property from the &mmc0 node.

Why, does it do any harm? It's perfectly possible to connect a 
full-sized card to a microSD slot with an adapter. I came across my old 
SDIO WiFi card a while back and tried it that way for a giggle, but 
unfortunately it turned out not to be a chipset supported by any 
upstream driver.

Robin.

> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
> ---
>   arch/arm/boot/dts/rk3066a-mk808.dts | 1 -
>   1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts
> index 9790bc63b..b67f5cb51 100644
> --- a/arch/arm/boot/dts/rk3066a-mk808.dts
> +++ b/arch/arm/boot/dts/rk3066a-mk808.dts
> @@ -123,7 +123,6 @@
>   
>   &mmc0 {
>   	bus-width = <4>;
> -	cap-mmc-highspeed;
>   	cap-sd-highspeed;
>   	vmmc-supply = <&vcc_sd>;
>   	status = "okay";
> 


From broonie at kernel.org  Fri Aug 20 07:39:09 2021
From: broonie at kernel.org (Mark Brown)
Date: Fri, 20 Aug 2021 15:39:09 +0100
Subject: [PATCH] spi: stm32: fix excluded_middle.cocci warnings
In-Reply-To: <20210713191004.GA14729@5eb5c2cbef84>
References: <202107140345.xyOobAtH-lkp@intel.com>
 <20210713191004.GA14729@5eb5c2cbef84>
Message-ID: <162947034008.30978.4693258068045674131.b4-ty@kernel.org>

On Wed, 14 Jul 2021 03:10:04 +0800, kernel test robot wrote:
> From: kernel test robot <lkp at intel.com>
> 
> drivers/spi/spi-stm32.c:915:23-25: WARNING !A || A && B is equivalent to !A || B
> 
> 
>  Condition !A || A && B is equivalent to !A || B.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: stm32: fix excluded_middle.cocci warnings
      commit: 7a4697b201a617907e4b440ae34df601d4755bef

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From jbx6244 at gmail.com  Fri Aug 20 07:41:32 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Fri, 20 Aug 2021 16:41:32 +0200
Subject: [PATCH] ARM: dts: rockchip: remove cap-mmc-highspeed property
 from mk808 &mmc0 node
In-Reply-To: <bf6cba99-da3b-a6fe-4e4b-f4ea6e3c6e63@arm.com>
References: <20210820131920.1831-1-jbx6244@gmail.com>
 <bf6cba99-da3b-a6fe-4e4b-f4ea6e3c6e63@arm.com>
Message-ID: <c52b4cf0-d018-f6b4-8728-41551b8bf62b@gmail.com>



On 8/20/21 4:17 PM, Robin Murphy wrote:
> On 2021-08-20 14:19, Johan Jonker wrote:
>> On the MK808 only a microSD slot is connected with the SDMMC Host
>> Controller,
>> so remove the cap-mmc-highspeed property from the &mmc0 node.
> 
> Why, does it do any harm? 

Harm not. Example rk3066 u-boot:

>>>>sd_select_mode_and_width
sd card: widths [4, 1, ] modes [MMC legacy, SD High Speed (50MHz), UHS
SDR12 (25MHz), UHS SDR25 (50MHz), ]
host: widths [4, 1, ] modes [MMC legacy, MMC High Speed (26MHz), SD
High Speed (50MHz), MMC High Speed (52MHz), ]
trying mode SD High Speed (50MHz) width 4 (at 50 MHz)

I would say only advertise host capabilities that are under normal
circumstances occur. How realistic is it to use a TF/Micro SD TO SD Card
Extension Cable Adapter (giggle) for a deprecated mmc card?

Johan

It's perfectly possible to connect a
> full-sized card to a microSD slot with an adapter. I came across my old
> SDIO WiFi card a while back and tried it that way for a giggle, but
> unfortunately it turned out not to be a chipset supported by any
> upstream driver.
> 
> Robin.
> 
>> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
>> ---
>> ? arch/arm/boot/dts/rk3066a-mk808.dts | 1 -
>> ? 1 file changed, 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts
>> b/arch/arm/boot/dts/rk3066a-mk808.dts
>> index 9790bc63b..b67f5cb51 100644
>> --- a/arch/arm/boot/dts/rk3066a-mk808.dts
>> +++ b/arch/arm/boot/dts/rk3066a-mk808.dts
>> @@ -123,7 +123,6 @@
>> ? ? &mmc0 {
>> ????? bus-width = <4>;
>> -??? cap-mmc-highspeed;
>> ????? cap-sd-highspeed;
>> ????? vmmc-supply = <&vcc_sd>;
>> ????? status = "okay";
>>


From alim.akhtar at gmail.com  Fri Aug 20 07:44:50 2021
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Fri, 20 Aug 2021 20:14:50 +0530
Subject: [PATCH 1/2] arm64: dts: exynos: align operating-points table name
 with dtschema in Exynos5433
In-Reply-To: <20210820081458.83406-1-krzysztof.kozlowski@canonical.com>
References: <20210820081458.83406-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ53oTWuSLupGKWd+XWPXJZQfZ28-Vo=wWT1exty0LpCfOA@mail.gmail.com>

On Fri, Aug 20, 2021 at 1:51 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Align the name of operating-points node to dtschema to fix warnings like:
>
Did you miss adding warnings here?

> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
Rest looks good.
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi | 10 +++++-----
>  arch/arm64/boot/dts/exynos/exynos5433.dtsi     |  4 ++--
>  2 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
> index 8997f8f2b96c..72ccf18eb9d1 100644
> --- a/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos5433-bus.dtsi
> @@ -87,7 +87,7 @@ bus_noc2: bus9 {
>                 status = "disabled";
>         };
>
> -       bus_g2d_400_opp_table: opp-table2 {
> +       bus_g2d_400_opp_table: opp-table-2 {
>                 compatible = "operating-points-v2";
>                 opp-shared;
>
> @@ -117,7 +117,7 @@ opp-100000000 {
>                 };
>         };
>
> -       bus_g2d_266_opp_table: opp-table3 {
> +       bus_g2d_266_opp_table: opp-table-3 {
>                 compatible = "operating-points-v2";
>
>                 opp-267000000 {
> @@ -137,7 +137,7 @@ opp-100000000 {
>                 };
>         };
>
> -       bus_gscl_opp_table: opp-table4 {
> +       bus_gscl_opp_table: opp-table-4 {
>                 compatible = "operating-points-v2";
>
>                 opp-333000000 {
> @@ -151,7 +151,7 @@ opp-166500000 {
>                 };
>         };
>
> -       bus_hevc_opp_table: opp-table5 {
> +       bus_hevc_opp_table: opp-table-5 {
>                 compatible = "operating-points-v2";
>                 opp-shared;
>
> @@ -175,7 +175,7 @@ opp-100000000 {
>                 };
>         };
>
> -       bus_noc2_opp_table: opp-table6 {
> +       bus_noc2_opp_table: opp-table-6 {
>                 compatible = "operating-points-v2";
>
>                 opp-400000000 {
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> index 6a6f7dd1d65c..ebd5091d68b4 100644
> --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> @@ -239,7 +239,7 @@ cluster_a53_l2: l2-cache1 {
>                 };
>         };
>
> -       cluster_a53_opp_table: opp-table0 {
> +       cluster_a53_opp_table: opp-table-0 {
>                 compatible = "operating-points-v2";
>                 opp-shared;
>
> @@ -285,7 +285,7 @@ opp-1300000000 {
>                 };
>         };
>
> -       cluster_a57_opp_table: opp-table1 {
> +       cluster_a57_opp_table: opp-table-1 {
>                 compatible = "operating-points-v2";
>                 opp-shared;
>
> --
> 2.30.2
>


-- 
Regards,
Alim


From alim.akhtar at gmail.com  Fri Aug 20 07:47:07 2021
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Fri, 20 Aug 2021 20:17:07 +0530
Subject: [PATCH 2/2] arm64: dts: exynos: add proper comaptible FSYS syscon
 in Exynos5433
In-Reply-To: <20210820082149.84613-1-krzysztof.kozlowski@canonical.com>
References: <20210820081458.83406-1-krzysztof.kozlowski@canonical.com>
 <20210820082149.84613-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ53CeRYafwjP45CsDRgBQtuvyVxJQR4CX4qChWyHzO4_fA@mail.gmail.com>

On Fri, Aug 20, 2021 at 1:52 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The syscon nodes should come with specific compatible.  Correct theh
s/theh/the?

> FSYS syscon to fix dtbs_check warnings:
>
>   syscon at 156f0000: compatible: 'anyOf' conditional failed, one must be fixed:
>   ['syscon'] is too short
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
With typo fixed above,
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  arch/arm64/boot/dts/exynos/exynos5433.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> index ebd5091d68b4..4422021cf4b2 100644
> --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
> @@ -1132,7 +1132,7 @@ syscon_cam1: syscon at 145f0000 {
>                 };
>
>                 syscon_fsys: syscon at 156f0000 {
> -                       compatible = "syscon";
> +                       compatible = "samsung,exynos5433-sysreg", "syscon";
>                         reg = <0x156f0000 0x1044>;
>                 };
>
> --
> 2.30.2
>


-- 
Regards,
Alim


From robin.murphy at arm.com  Fri Aug 20 07:49:10 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 20 Aug 2021 15:49:10 +0100
Subject: [PATCH] ARM: dts: rockchip: remove cap-mmc-highspeed property
 from mk808 &mmc0 node
In-Reply-To: <c52b4cf0-d018-f6b4-8728-41551b8bf62b@gmail.com>
References: <20210820131920.1831-1-jbx6244@gmail.com>
 <bf6cba99-da3b-a6fe-4e4b-f4ea6e3c6e63@arm.com>
 <c52b4cf0-d018-f6b4-8728-41551b8bf62b@gmail.com>
Message-ID: <d3b574f5-b49e-60be-1559-b98e0832bd62@arm.com>

On 2021-08-20 15:41, Johan Jonker wrote:
> 
> 
> On 8/20/21 4:17 PM, Robin Murphy wrote:
>> On 2021-08-20 14:19, Johan Jonker wrote:
>>> On the MK808 only a microSD slot is connected with the SDMMC Host
>>> Controller,
>>> so remove the cap-mmc-highspeed property from the &mmc0 node.
>>
>> Why, does it do any harm?
> 
> Harm not. Example rk3066 u-boot:
> 
>>>>> sd_select_mode_and_width
> sd card: widths [4, 1, ] modes [MMC legacy, SD High Speed (50MHz), UHS
> SDR12 (25MHz), UHS SDR25 (50MHz), ]
> host: widths [4, 1, ] modes [MMC legacy, MMC High Speed (26MHz), SD
> High Speed (50MHz), MMC High Speed (52MHz), ]
> trying mode SD High Speed (50MHz) width 4 (at 50 MHz)
> 
> I would say only advertise host capabilities that are under normal
> circumstances occur. How realistic is it to use a TF/Micro SD TO SD Card
> Extension Cable Adapter (giggle) for a deprecated mmc card?

Well, if you want a far more realistic example:

https://www.hardkernel.com/shop/emmc-module-reader-board-for-os-upgrade/

Who are we to dictate what "normal circumstances" are, and what do we 
gain by removing support for modes that could work fine and at least be 
useful to someone on occasion?

Robin.


From krzysztof.kozlowski at canonical.com  Fri Aug 20 08:04:33 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 17:04:33 +0200
Subject: [PATCH 1/2] arm64: dts: exynos: align operating-points table name
 with dtschema in Exynos5433
In-Reply-To: <CAGOxZ53oTWuSLupGKWd+XWPXJZQfZ28-Vo=wWT1exty0LpCfOA@mail.gmail.com>
References: <20210820081458.83406-1-krzysztof.kozlowski@canonical.com>
 <CAGOxZ53oTWuSLupGKWd+XWPXJZQfZ28-Vo=wWT1exty0LpCfOA@mail.gmail.com>
Message-ID: <ed2e81ce-97ac-be28-8db5-3f1242c64a91@canonical.com>

On 20/08/2021 16:44, Alim Akhtar wrote:
> On Fri, Aug 20, 2021 at 1:51 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Align the name of operating-points node to dtschema to fix warnings like:
>>
> Did you miss adding warnings here?

Yeah, I missed. I will add it when applying.

> 
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
> Rest looks good.
> Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

Thanks!


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Fri Aug 20 08:03:50 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 17:03:50 +0200
Subject: [PATCH v2 1/4] dt-bindings: devfreq: event: convert Samsung Exynos
 NoCP to dtschema
Message-ID: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos NoC Probe bindings to DT schema format using
json-schema.

New bindings contain copied description from previous bindings document,
therefore the license is set as GPL-2.0-only.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes since v1:
1. New patch
---
 .../bindings/devfreq/event/exynos-nocp.txt    | 26 ----------
 .../devfreq/event/samsung,exynos-nocp.yaml    | 48 +++++++++++++++++++
 2 files changed, 48 insertions(+), 26 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/devfreq/event/exynos-nocp.txt
 create mode 100644 Documentation/devicetree/bindings/devfreq/event/samsung,exynos-nocp.yaml

diff --git a/Documentation/devicetree/bindings/devfreq/event/exynos-nocp.txt b/Documentation/devicetree/bindings/devfreq/event/exynos-nocp.txt
deleted file mode 100644
index aeaebd425d1f..000000000000
--- a/Documentation/devicetree/bindings/devfreq/event/exynos-nocp.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-
-* Samsung Exynos NoC (Network on Chip) Probe device
-
-The Samsung Exynos542x SoC has NoC (Network on Chip) Probe for NoC bus.
-NoC provides the primitive values to get the performance data. The packets
-that the Network on Chip (NoC) probes detects are transported over
-the network infrastructure to observer units. You can configure probes to
-capture packets with header or data on the data request response network,
-or as traffic debug or statistic collectors. Exynos542x bus has multiple
-NoC probes to provide bandwidth information about behavior of the SoC
-that you can use while analyzing system performance.
-
-Required properties:
-- compatible: Should be "samsung,exynos5420-nocp"
-- reg: physical base address of each NoC Probe and length of memory mapped region.
-
-Optional properties:
-- clock-names : the name of clock used by the NoC Probe, "nocp"
-- clocks : phandles for clock specified in "clock-names" property
-
-Example : NoC Probe nodes in Device Tree are listed below.
-
-	nocp_mem0_0: nocp at 10ca1000 {
-		compatible = "samsung,exynos5420-nocp";
-		reg = <0x10CA1000 0x200>;
-	};
diff --git a/Documentation/devicetree/bindings/devfreq/event/samsung,exynos-nocp.yaml b/Documentation/devicetree/bindings/devfreq/event/samsung,exynos-nocp.yaml
new file mode 100644
index 000000000000..d318fccf78f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/event/samsung,exynos-nocp.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/devfreq/event/samsung,exynos-nocp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos NoC (Network on Chip) Probe
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  The Samsung Exynos542x SoC has a NoC (Network on Chip) Probe for NoC bus.
+  NoC provides the primitive values to get the performance data. The packets
+  that the Network on Chip (NoC) probes detects are transported over the
+  network infrastructure to observer units. You can configure probes to capture
+  packets with header or data on the data request response network, or as
+  traffic debug or statistic collectors. Exynos542x bus has multiple NoC probes
+  to provide bandwidth information about behavior of the SoC that you can use
+  while analyzing system performance.
+
+properties:
+  compatible:
+    const: samsung,exynos5420-nocp
+
+  clock-names:
+    items:
+      - const: nocp
+
+  clocks:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    nocp_mem0_0: nocp at 10ca1000 {
+        compatible = "samsung,exynos5420-nocp";
+        reg = <0x10ca1000 0x200>;
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 08:03:53 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 17:03:53 +0200
Subject: [PATCH v2 4/4] ARM: dts: exynos: align PPMU event node names with
 dtschema
In-Reply-To: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
References: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210820150353.161161-4-krzysztof.kozlowski@canonical.com>

Use hyphen instead of underscore and align the PPMU event node name with
dtschema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes since v1:
1. New patch
---
 arch/arm/boot/dts/exynos5420.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index e23e8ffb093f..10ccd5cb69fd 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -302,7 +302,7 @@ ppmu_dmc0_0: ppmu at 10d00000 {
 			clocks = <&clock CLK_PCLK_PPMU_DREX0_0>;
 			clock-names = "ppmu";
 			events {
-				ppmu_event3_dmc0_0: ppmu-event3-dmc0_0 {
+				ppmu_event3_dmc0_0: ppmu-event3-dmc0-0 {
 					event-name = "ppmu-event3-dmc0_0";
 				};
 			};
@@ -314,7 +314,7 @@ ppmu_dmc0_1: ppmu at 10d10000 {
 			clocks = <&clock CLK_PCLK_PPMU_DREX0_1>;
 			clock-names = "ppmu";
 			events {
-				ppmu_event3_dmc0_1: ppmu-event3-dmc0_1 {
+				ppmu_event3_dmc0_1: ppmu-event3-dmc0-1 {
 					event-name = "ppmu-event3-dmc0_1";
 				};
 			};
@@ -326,7 +326,7 @@ ppmu_dmc1_0: ppmu at 10d60000 {
 			clocks = <&clock CLK_PCLK_PPMU_DREX1_0>;
 			clock-names = "ppmu";
 			events {
-				ppmu_event3_dmc1_0: ppmu-event3-dmc1_0 {
+				ppmu_event3_dmc1_0: ppmu-event3-dmc1-0 {
 					event-name = "ppmu-event3-dmc1_0";
 				};
 			};
@@ -338,7 +338,7 @@ ppmu_dmc1_1: ppmu at 10d70000 {
 			clocks = <&clock CLK_PCLK_PPMU_DREX1_1>;
 			clock-names = "ppmu";
 			events {
-				ppmu_event3_dmc1_1: ppmu-event3-dmc1_1 {
+				ppmu_event3_dmc1_1: ppmu-event3-dmc1-1 {
 					event-name = "ppmu-event3-dmc1_1";
 				};
 			};
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 08:03:51 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 17:03:51 +0200
Subject: [PATCH v2 2/4] dt-bindings: devfreq: event: convert Samsung Exynos
 PPMU to dtschema
In-Reply-To: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
References: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210820150353.161161-2-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos PPMU bindings to DT schema format using
json-schema.  The example is quite different due to the nature of
dtschema examples parsing (no overriding via-label allowed).

New bindings contain copied description from previous bindings document,
therefore the license is set as GPL-2.0-only.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes since v1:
1. New patch
---
 .../bindings/devfreq/event/exynos-ppmu.txt    | 169 -----------------
 .../devfreq/event/samsung,exynos-ppmu.yaml    | 174 ++++++++++++++++++
 2 files changed, 174 insertions(+), 169 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt
 create mode 100644 Documentation/devicetree/bindings/devfreq/event/samsung,exynos-ppmu.yaml

diff --git a/Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt b/Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt
deleted file mode 100644
index fb46b491791c..000000000000
--- a/Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt
+++ /dev/null
@@ -1,169 +0,0 @@
-
-* Samsung Exynos PPMU (Platform Performance Monitoring Unit) device
-
-The Samsung Exynos SoC has PPMU (Platform Performance Monitoring Unit) for
-each IP. PPMU provides the primitive values to get performance data. These
-PPMU events provide information of the SoC's behaviors so that you may
-use to analyze system performance, to make behaviors visible and to count
-usages of each IP (DMC, CPU, RIGHTBUS, LEFTBUS, CAM interface, LCD, G3D, MFC).
-The Exynos PPMU driver uses the devfreq-event class to provide event data
-to various devfreq devices. The devfreq devices would use the event data when
-derterming the current state of each IP.
-
-Required properties for PPMU device:
-- compatible: Should be "samsung,exynos-ppmu" or "samsung,exynos-ppmu-v2.
-- reg: physical base address of each PPMU and length of memory mapped region.
-
-Optional properties for PPMU device:
-- clock-names : the name of clock used by the PPMU, "ppmu"
-- clocks : phandles for clock specified in "clock-names" property
-
-Required properties for 'events' child node of PPMU device:
-- event-name : the unique event name among PPMU device
-Optional properties for 'events' child node of PPMU device:
-- event-data-type : Define the type of data which shell be counted
-by the counter. You can check include/dt-bindings/pmu/exynos_ppmu.h for
-all possible type, i.e. count read requests, count write data in bytes,
-etc. This field is optional and when it is missing, the driver code
-will use default data type.
-
-Example1 : PPMUv1 nodes in exynos3250.dtsi are listed below.
-
-		ppmu_dmc0: ppmu_dmc0 at 106a0000 {
-			compatible = "samsung,exynos-ppmu";
-			reg = <0x106a0000 0x2000>;
-			status = "disabled";
-		};
-
-		ppmu_dmc1: ppmu_dmc1 at 106b0000 {
-			compatible = "samsung,exynos-ppmu";
-			reg = <0x106b0000 0x2000>;
-			status = "disabled";
-		};
-
-		ppmu_cpu: ppmu_cpu at 106c0000 {
-			compatible = "samsung,exynos-ppmu";
-			reg = <0x106c0000 0x2000>;
-			status = "disabled";
-		};
-
-		ppmu_rightbus: ppmu_rightbus at 112a0000 {
-			compatible = "samsung,exynos-ppmu";
-			reg = <0x112a0000 0x2000>;
-			clocks = <&cmu CLK_PPMURIGHT>;
-			clock-names = "ppmu";
-			status = "disabled";
-		};
-
-		ppmu_leftbus: ppmu_leftbus0 at 116a0000 {
-			compatible = "samsung,exynos-ppmu";
-			reg = <0x116a0000 0x2000>;
-			clocks = <&cmu CLK_PPMULEFT>;
-			clock-names = "ppmu";
-			status = "disabled";
-		};
-
-Example2 : Events of each PPMU node in exynos3250-rinato.dts are listed below.
-
-	&ppmu_dmc0 {
-		status = "okay";
-
-		events {
-			ppmu_dmc0_3: ppmu-event3-dmc0 {
-				event-name = "ppmu-event3-dmc0";
-			};
-
-			ppmu_dmc0_2: ppmu-event2-dmc0 {
-				event-name = "ppmu-event2-dmc0";
-			};
-
-			ppmu_dmc0_1: ppmu-event1-dmc0 {
-				event-name = "ppmu-event1-dmc0";
-			};
-
-			ppmu_dmc0_0: ppmu-event0-dmc0 {
-				event-name = "ppmu-event0-dmc0";
-			};
-		};
-	};
-
-	&ppmu_dmc1 {
-		status = "okay";
-
-		events {
-			ppmu_dmc1_3: ppmu-event3-dmc1 {
-				event-name = "ppmu-event3-dmc1";
-			};
-		};
-	};
-
-	&ppmu_leftbus {
-		status = "okay";
-
-		events {
-			ppmu_leftbus_3: ppmu-event3-leftbus {
-				event-name = "ppmu-event3-leftbus";
-			};
-		};
-	};
-
-	&ppmu_rightbus {
-		status = "okay";
-
-		events {
-			ppmu_rightbus_3: ppmu-event3-rightbus {
-				event-name = "ppmu-event3-rightbus";
-			};
-		};
-	};
-
-Example3 : PPMUv2 nodes in exynos5433.dtsi are listed below.
-
-		ppmu_d0_cpu: ppmu_d0_cpu at 10480000 {
-			compatible = "samsung,exynos-ppmu-v2";
-			reg = <0x10480000 0x2000>;
-			status = "disabled";
-		};
-
-		ppmu_d0_general: ppmu_d0_general at 10490000 {
-			compatible = "samsung,exynos-ppmu-v2";
-			reg = <0x10490000 0x2000>;
-			status = "disabled";
-		};
-
-		ppmu_d0_rt: ppmu_d0_rt at 104a0000 {
-			compatible = "samsung,exynos-ppmu-v2";
-			reg = <0x104a0000 0x2000>;
-			status = "disabled";
-		};
-
-		ppmu_d1_cpu: ppmu_d1_cpu at 104b0000 {
-			compatible = "samsung,exynos-ppmu-v2";
-			reg = <0x104b0000 0x2000>;
-			status = "disabled";
-		};
-
-		ppmu_d1_general: ppmu_d1_general at 104c0000 {
-			compatible = "samsung,exynos-ppmu-v2";
-			reg = <0x104c0000 0x2000>;
-			status = "disabled";
-		};
-
-		ppmu_d1_rt: ppmu_d1_rt at 104d0000 {
-			compatible = "samsung,exynos-ppmu-v2";
-			reg = <0x104d0000 0x2000>;
-			status = "disabled";
-		};
-
-Example4 : 'event-data-type' in exynos4412-ppmu-common.dtsi are listed below.
-
-	&ppmu_dmc0 {
-		status = "okay";
-		events {
-			ppmu_dmc0_3: ppmu-event3-dmc0 {
-			event-name = "ppmu-event3-dmc0";
-			event-data-type = <(PPMU_RO_DATA_CNT |
-					PPMU_WO_DATA_CNT)>;
-			};
-		};
-	};
diff --git a/Documentation/devicetree/bindings/devfreq/event/samsung,exynos-ppmu.yaml b/Documentation/devicetree/bindings/devfreq/event/samsung,exynos-ppmu.yaml
new file mode 100644
index 000000000000..d755f4ff1bea
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/event/samsung,exynos-ppmu.yaml
@@ -0,0 +1,174 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/devfreq/event/samsung,exynos-ppmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC PPMU (Platform Performance Monitoring Unit)
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  The Samsung Exynos SoC has PPMU (Platform Performance Monitoring Unit) for
+  each IP. PPMU provides the primitive values to get performance data. These
+  PPMU events provide information of the SoC's behaviors so that you may use to
+  analyze system performance, to make behaviors visible and to count usages of
+  each IP (DMC, CPU, RIGHTBUS, LEFTBUS, CAM interface, LCD, G3D, MFC).  The
+  Exynos PPMU driver uses the devfreq-event class to provide event data to
+  various devfreq devices. The devfreq devices would use the event data when
+  derterming the current state of each IP.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos-ppmu
+      - samsung,exynos-ppmu-v2
+
+  clock-names:
+    items:
+      - const: ppmu
+
+  clocks:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+  events:
+    type: object
+
+    patternProperties:
+      '^ppmu-event[0-9]+(-[a-z0-9]+){,2}$':
+        type: object
+        properties:
+          event-name:
+            description: |
+              The unique event name among PPMU device
+            $ref: /schemas/types.yaml#/definitions/string
+
+          event-data-type:
+            description: |
+              Define the type of data which shell be counted by the counter.
+              You can check include/dt-bindings/pmu/exynos_ppmu.h for all
+              possible type, i.e. count read requests, count write data in
+              bytes, etc.  This field is optional and when it is missing, the
+              driver code will use default data type.
+            $ref: /schemas/types.yaml#/definitions/uint32
+
+        required:
+          - event-name
+
+        additionalProperties: false
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    // PPMUv1 nodes for Exynos3250 (although the board DTS defines events)
+    #include <dt-bindings/clock/exynos3250.h>
+
+    ppmu_dmc0: ppmu at 106a0000 {
+        compatible = "samsung,exynos-ppmu";
+        reg = <0x106a0000 0x2000>;
+
+        events {
+            ppmu_dmc0_3: ppmu-event3-dmc0 {
+                event-name = "ppmu-event3-dmc0";
+            };
+
+            ppmu_dmc0_2: ppmu-event2-dmc0 {
+                event-name = "ppmu-event2-dmc0";
+            };
+
+            ppmu_dmc0_1: ppmu-event1-dmc0 {
+                event-name = "ppmu-event1-dmc0";
+            };
+
+            ppmu_dmc0_0: ppmu-event0-dmc0 {
+                event-name = "ppmu-event0-dmc0";
+            };
+        };
+    };
+
+    ppmu_rightbus: ppmu at 112a0000 {
+        compatible = "samsung,exynos-ppmu";
+        reg = <0x112a0000 0x2000>;
+        clocks = <&cmu CLK_PPMURIGHT>;
+        clock-names = "ppmu";
+
+        events {
+            ppmu_rightbus_3: ppmu-event3-rightbus {
+                event-name = "ppmu-event3-rightbus";
+            };
+        };
+    };
+
+  - |
+    // PPMUv2 nodes in Exynos5433
+    ppmu_d0_cpu: ppmu at 10480000 {
+        compatible = "samsung,exynos-ppmu-v2";
+        reg = <0x10480000 0x2000>;
+        status = "disabled";
+    };
+
+    ppmu_d0_general: ppmu at 10490000 {
+        compatible = "samsung,exynos-ppmu-v2";
+        reg = <0x10490000 0x2000>;
+
+        events {
+            ppmu_event0_d0_general: ppmu-event0-d0-general {
+                event-name = "ppmu-event0-d0-general";
+            };
+        };
+    };
+
+    ppmu_d0_rt: ppmu at 104a0000 {
+        compatible = "samsung,exynos-ppmu-v2";
+        reg = <0x104a0000 0x2000>;
+        status = "disabled";
+    };
+
+    ppmu_d1_cpu: ppmu at 104b0000 {
+        compatible = "samsung,exynos-ppmu-v2";
+        reg = <0x104b0000 0x2000>;
+        status = "disabled";
+    };
+
+    ppmu_d1_general: ppmu at 104c0000 {
+        compatible = "samsung,exynos-ppmu-v2";
+        reg = <0x104c0000 0x2000>;
+        status = "disabled";
+    };
+
+    ppmu_d1_rt: ppmu at 104d0000 {
+        compatible = "samsung,exynos-ppmu-v2";
+        reg = <0x104d0000 0x2000>;
+        status = "disabled";
+    };
+
+  - |
+    // PPMUv1 nodes with event-data-type for Exynos4412
+    #include <dt-bindings/pmu/exynos_ppmu.h>
+
+    ppmu at 106a0000 {
+        compatible = "samsung,exynos-ppmu";
+        reg = <0x106a0000 0x2000>;
+        clocks = <&clock 400>;
+        clock-names = "ppmu";
+
+        events {
+            ppmu-event3-dmc0 {
+                event-name = "ppmu-event3-dmc0";
+                event-data-type = <(PPMU_RO_DATA_CNT |
+                                    PPMU_WO_DATA_CNT)>;
+            };
+        };
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 08:03:52 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 17:03:52 +0200
Subject: [PATCH v2 3/4] dt-bindings: memory: convert Samsung Exynos DMC to
 dtschema
In-Reply-To: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
References: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210820150353.161161-3-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos5422 SoC frequency and voltage scaling for
Dynamic Memory Controller to DT schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Acked-by: Lukasz Luba <lukasz.luba at arm.com>

---

Changes since v1:
1. Corrent PPMU event node name (remove underscore).
2. Add Ack.
---
 .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
 .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
 MAINTAINERS                                   |   2 +-
 3 files changed, 138 insertions(+), 85 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt b/Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
deleted file mode 100644
index 02e4a1f862f1..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-* Exynos5422 frequency and voltage scaling for Dynamic Memory Controller device
-
-The Samsung Exynos5422 SoC has DMC (Dynamic Memory Controller) to which the DRAM
-memory chips are connected. The driver is to monitor the controller in runtime
-and switch frequency and voltage. To monitor the usage of the controller in
-runtime, the driver uses the PPMU (Platform Performance Monitoring Unit), which
-is able to measure the current load of the memory.
-When 'userspace' governor is used for the driver, an application is able to
-switch the DMC and memory frequency.
-
-Required properties for DMC device for Exynos5422:
-- compatible: Should be "samsung,exynos5422-dmc".
-- clocks : list of clock specifiers, must contain an entry for each
-  required entry in clock-names for CLK_FOUT_SPLL, CLK_MOUT_SCLK_SPLL,
-  CLK_FF_DOUT_SPLL2, CLK_FOUT_BPLL, CLK_MOUT_BPLL, CLK_SCLK_BPLL,
-  CLK_MOUT_MX_MSPLL_CCORE, CLK_MOUT_MX_MSPLL_CCORE_PHY, CLK_MOUT_MCLK_CDREX,
-- clock-names : should include "fout_spll", "mout_sclk_spll", "ff_dout_spll2",
-  "fout_bpll", "mout_bpll", "sclk_bpll", "mout_mx_mspll_ccore",
-  "mout_mclk_cdrex"  entries
-- devfreq-events : phandles for PPMU devices connected to this DMC.
-- vdd-supply : phandle for voltage regulator which is connected.
-- reg : registers of two CDREX controllers.
-- operating-points-v2 : phandle for OPPs described in v2 definition.
-- device-handle : phandle of the connected DRAM memory device. For more
-	information please refer to documentation file:
-	Documentation/devicetree/bindings/ddr/lpddr3.txt
-- devfreq-events : phandles of the PPMU events used by the controller.
-- samsung,syscon-clk : phandle of the clock register set used by the controller,
-	these registers are used for enabling a 'pause' feature and are not
-	exposed by clock framework but they must be used in a safe way.
-	The register offsets are in the driver code and specyfic for this SoC
-	type.
-
-Optional properties for DMC device for Exynos5422:
-- interrupt-parent : The parent interrupt controller.
-- interrupts : Contains the IRQ line numbers for the DMC internal performance
-  event counters in DREX0 and DREX1 channels. Align with specification of the
-  interrupt line(s) in the interrupt-parent controller.
-- interrupt-names : IRQ names "drex_0" and "drex_1", the order should be the
-  same as in the 'interrupts' list above.
-
-Example:
-
-	ppmu_dmc0_0: ppmu at 10d00000 {
-		compatible = "samsung,exynos-ppmu";
-		reg = <0x10d00000 0x2000>;
-		clocks = <&clock CLK_PCLK_PPMU_DREX0_0>;
-		clock-names = "ppmu";
-		events {
-			ppmu_event_dmc0_0: ppmu-event3-dmc0_0 {
-				event-name = "ppmu-event3-dmc0_0";
-			};
-		};
-	};
-
-	dmc: memory-controller at 10c20000 {
-		compatible = "samsung,exynos5422-dmc";
-		reg = <0x10c20000 0x10000>, <0x10c30000 0x10000>;
-		clocks = <&clock CLK_FOUT_SPLL>,
-			 <&clock CLK_MOUT_SCLK_SPLL>,
-			 <&clock CLK_FF_DOUT_SPLL2>,
-			 <&clock CLK_FOUT_BPLL>,
-			 <&clock CLK_MOUT_BPLL>,
-			 <&clock CLK_SCLK_BPLL>,
-			 <&clock CLK_MOUT_MX_MSPLL_CCORE>,
-			 <&clock CLK_MOUT_MCLK_CDREX>;
-		clock-names = "fout_spll",
-			      "mout_sclk_spll",
-			      "ff_dout_spll2",
-			      "fout_bpll",
-			      "mout_bpll",
-			      "sclk_bpll",
-			      "mout_mx_mspll_ccore",
-			      "mout_mclk_cdrex";
-		operating-points-v2 = <&dmc_opp_table>;
-		devfreq-events = <&ppmu_event3_dmc0_0>,	<&ppmu_event3_dmc0_1>,
-				 <&ppmu_event3_dmc1_0>, <&ppmu_event3_dmc1_1>;
-		device-handle = <&samsung_K3QF2F20DB>;
-		vdd-supply = <&buck1_reg>;
-		samsung,syscon-clk = <&clock>;
-		interrupt-parent = <&combiner>;
-		interrupts = <16 0>, <16 1>;
-		interrupt-names = "drex_0", "drex_1";
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml b/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
new file mode 100644
index 000000000000..6f4fd5814bf4
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
@@ -0,0 +1,137 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/samsung,exynos5422-dmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: |
+  Samsung Exynos5422 SoC frequency and voltage scaling for Dynamic Memory
+  Controller device
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Lukasz Luba <lukasz.luba at arm.com>
+
+description: |
+  The Samsung Exynos5422 SoC has DMC (Dynamic Memory Controller) to which the
+  DRAM memory chips are connected. The driver is to monitor the controller in
+  runtime and switch frequency and voltage. To monitor the usage of the
+  controller in runtime, the driver uses the PPMU (Platform Performance
+  Monitoring Unit), which is able to measure the current load of the memory.
+  When 'userspace' governor is used for the driver, an application is able to
+  switch the DMC and memory frequency.
+
+properties:
+  compatible:
+    items:
+      - const: samsung,exynos5422-dmc
+
+  clock-names:
+    items:
+      - const: fout_spll
+      - const: mout_sclk_spll
+      - const: ff_dout_spll2
+      - const: fout_bpll
+      - const: mout_bpll
+      - const: sclk_bpll
+      - const: mout_mx_mspll_ccore
+      - const: mout_mclk_cdrex
+
+  clocks:
+    minItems: 8
+    maxItems: 8
+
+  devfreq-events:
+    $ref: '/schemas/types.yaml#/definitions/phandle-array'
+    minItems: 1
+    maxItems: 16
+    description: phandles of the PPMU events used by the controller.
+
+  device-handle:
+    $ref: '/schemas/types.yaml#/definitions/phandle'
+    description: |
+      phandle of the connected DRAM memory device. For more information please
+      refer to documentation file: Documentation/devicetree/bindings/ddr/lpddr3.txt
+
+  operating-points-v2: true
+
+  interrupts:
+    items:
+      - description: DMC internal performance event counters in DREX0
+      - description: DMC internal performance event counters in DREX1
+
+  interrupt-names:
+    items:
+      - const: drex_0
+      - const: drex_1
+
+  reg:
+    items:
+      - description: registers of DREX0
+      - description: registers of DREX1
+
+  samsung,syscon-clk:
+    $ref: '/schemas/types.yaml#/definitions/phandle'
+    description: |
+      Phandle of the clock register set used by the controller, these registers
+      are used for enabling a 'pause' feature and are not exposed by clock
+      framework but they must be used in a safe way.  The register offsets are
+      in the driver code and specyfic for this SoC type.
+
+  vdd-supply: true
+
+required:
+  - compatible
+  - clock-names
+  - clocks
+  - devfreq-events
+  - device-handle
+  - reg
+  - samsung,syscon-clk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5420.h>
+    ppmu_dmc0_0: ppmu at 10d00000 {
+        compatible = "samsung,exynos-ppmu";
+        reg = <0x10d00000 0x2000>;
+        clocks = <&clock CLK_PCLK_PPMU_DREX0_0>;
+        clock-names = "ppmu";
+        events {
+            ppmu_event_dmc0_0: ppmu-event3-dmc0-0 {
+                event-name = "ppmu-event3-dmc0_0";
+            };
+        };
+    };
+
+    memory-controller at 10c20000 {
+        compatible = "samsung,exynos5422-dmc";
+        reg = <0x10c20000 0x10000>, <0x10c30000 0x10000>;
+        clocks = <&clock CLK_FOUT_SPLL>,
+                 <&clock CLK_MOUT_SCLK_SPLL>,
+                 <&clock CLK_FF_DOUT_SPLL2>,
+                 <&clock CLK_FOUT_BPLL>,
+                 <&clock CLK_MOUT_BPLL>,
+                 <&clock CLK_SCLK_BPLL>,
+                 <&clock CLK_MOUT_MX_MSPLL_CCORE>,
+                 <&clock CLK_MOUT_MCLK_CDREX>;
+        clock-names = "fout_spll",
+                      "mout_sclk_spll",
+                      "ff_dout_spll2",
+                      "fout_bpll",
+                      "mout_bpll",
+                      "sclk_bpll",
+                      "mout_mx_mspll_ccore",
+                      "mout_mclk_cdrex";
+        operating-points-v2 = <&dmc_opp_table>;
+        devfreq-events = <&ppmu_event3_dmc0_0>,	<&ppmu_event3_dmc0_1>,
+                         <&ppmu_event3_dmc1_0>, <&ppmu_event3_dmc1_1>;
+        device-handle = <&samsung_K3QF2F20DB>;
+        vdd-supply = <&buck1_reg>;
+        samsung,syscon-clk = <&clock>;
+        interrupt-parent = <&combiner>;
+        interrupts = <16 0>, <16 1>;
+        interrupt-names = "drex_0", "drex_1";
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index ebdb07a49b02..eb4ada858826 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5570,7 +5570,7 @@ M:	Lukasz Luba <lukasz.luba at arm.com>
 L:	linux-pm at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
+F:	Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
 F:	drivers/memory/samsung/exynos5422-dmc.c
 
 DME1737 HARDWARE MONITOR DRIVER
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Fri Aug 20 08:05:02 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 20 Aug 2021 17:05:02 +0200
Subject: [PATCH 2/2] arm64: dts: exynos: add proper comaptible FSYS syscon
 in Exynos5433
In-Reply-To: <CAGOxZ53CeRYafwjP45CsDRgBQtuvyVxJQR4CX4qChWyHzO4_fA@mail.gmail.com>
References: <20210820081458.83406-1-krzysztof.kozlowski@canonical.com>
 <20210820082149.84613-1-krzysztof.kozlowski@canonical.com>
 <CAGOxZ53CeRYafwjP45CsDRgBQtuvyVxJQR4CX4qChWyHzO4_fA@mail.gmail.com>
Message-ID: <b21ceda4-c960-791b-6d09-a7579a35c3a4@canonical.com>

On 20/08/2021 16:47, Alim Akhtar wrote:
> On Fri, Aug 20, 2021 at 1:52 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> The syscon nodes should come with specific compatible.  Correct theh
> s/theh/the?

Indeed, thanks!

> 
>> FSYS syscon to fix dtbs_check warnings:
>>
>>   syscon at 156f0000: compatible: 'anyOf' conditional failed, one must be fixed:
>>   ['syscon'] is too short
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
> With typo fixed above,
> Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>



Best regards,
Krzysztof


From clin at suse.com  Fri Aug 20 08:15:49 2021
From: clin at suse.com (Chester Lin)
Date: Fri, 20 Aug 2021 23:15:49 +0800
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <87o89sqmz6.wl-maz@kernel.org>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-5-clin@suse.com>
 <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>
 <87o89sqmz6.wl-maz@kernel.org>
Message-ID: <YR/HJQDGJ1C+ku6O@linux-8mug>

On Fri, Aug 20, 2021 at 02:12:13PM +0100, Marc Zyngier wrote:
> On Thu, 12 Aug 2021 18:26:28 +0100,
> Andreas F?rber <afaerber at suse.de> wrote:
> > 
> > Hi Chester et al.,
> > 
> > On 05.08.21 08:54, Chester Lin wrote:
> > > Add an initial dtsi file for generic SoC features of NXP S32G2.
> > > 
> > > Signed-off-by: Chester Lin <clin at suse.com>
> > > ---
> > >  arch/arm64/boot/dts/freescale/s32g2.dtsi | 98 ++++++++++++++++++++++++
> > >  1 file changed, 98 insertions(+)
> > >  create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
> > > 
> > > diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > > new file mode 100644
> > > index 000000000000..3321819c1a2d
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> 
> [...]
> 
> > > +		gic: interrupt-controller at 50800000 {
> > > +			compatible = "arm,gic-v3";
> > > +			#interrupt-cells = <3>;
> > > +			interrupt-controller;
> > > +			reg = <0 0x50800000 0 0x10000>,
> > > +			      <0 0x50880000 0 0x200000>,
> 
> That's enough redistributor space for 16 CPUs. However, you only
> describe 4. Either the number of CPUs is wrong, the size is wrong, or
> the GIC has been configured for more cores than the SoC has.

Confirmed the SoC can only find 4 redistributors:

localhost:~ # dmesg | grep CPU
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: detected: GIC system register CPU interface
[    0.000000] CPU features: detected: ARM erratum 845719
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=480 to nr_cpu_ids=4.
[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x0000000050880000
[    0.063865] smp: Bringing up secondary CPUs ...
[    0.068852] Detected VIPT I-cache on CPU1
[    0.068894] GICv3: CPU1: found redistributor 1 region 0:0x00000000508a0000
[    0.068963] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[    0.069809] Detected VIPT I-cache on CPU2
[    0.069851] GICv3: CPU2: found redistributor 100 region 0:0x00000000508c0000
[    0.069903] CPU2: Booted secondary processor 0x0000000100 [0x410fd034]
[    0.070698] Detected VIPT I-cache on CPU3
[    0.070722] GICv3: CPU3: found redistributor 101 region 0:0x00000000508e0000
[    0.070749] CPU3: Booted secondary processor 0x0000000101 [0x410fd034]
[    0.070847] smp: Brought up 1 node, 4 CPUs
<..snip..>

I will correct the size to 0x80000, thanks!

> 
> > > +			      <0 0x50400000 0 0x2000>,
> > > +			      <0 0x50410000 0 0x2000>,
> > > +			      <0 0x50420000 0 0x2000>;
> > 
> > Please order reg after compatible by convention, and sort
> > interrupt-controller or at least #interrupt-cells (applying to
> > consumers) last, after the below one applying to this device itself.
> > 
> > > +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
> > > +						 IRQ_TYPE_LEVEL_HIGH)>;
> > > +		};
> > 
> > CC'ing Marc for additional GIC scrutiny, often the sizes are wrong.
> 
> There is more than just sizes. The interrupt specifier for the
> maintenance interrupt is also wrong.
> 
> 	M.

I will remove the wrong interrupt specifier. Thanks!

Chester.

> 
> -- 
> Without deviation from the norm, progress is not possible.
> 



From joro at 8bytes.org  Fri Aug 20 08:19:03 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Fri, 20 Aug 2021 17:19:03 +0200
Subject: [PATCH] iommu/io-pgtable: Abstract iommu_iotlb_gather access
In-Reply-To: <83672ee76f6405c82845a55c148fa836f56fbbc1.1629465282.git.robin.murphy@arm.com>
References: <83672ee76f6405c82845a55c148fa836f56fbbc1.1629465282.git.robin.murphy@arm.com>
Message-ID: <YR/H57xp/ixTvqvr@8bytes.org>

On Fri, Aug 20, 2021 at 02:14:42PM +0100, Robin Murphy wrote:
>  drivers/iommu/io-pgtable-arm-v7s.c |  2 +-
>  drivers/iommu/io-pgtable-arm.c     |  2 +-
>  include/linux/iommu.h              | 10 ++++++++++
>  3 files changed, 12 insertions(+), 2 deletions(-)

Applied, thanks Robin.



From maz at kernel.org  Fri Aug 20 08:29:00 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 16:29:00 +0100
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <YR/HJQDGJ1C+ku6O@linux-8mug>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-5-clin@suse.com>
 <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>
 <87o89sqmz6.wl-maz@kernel.org> <YR/HJQDGJ1C+ku6O@linux-8mug>
Message-ID: <87lf4wqgn7.wl-maz@kernel.org>

On Fri, 20 Aug 2021 16:15:49 +0100,
Chester Lin <clin at suse.com> wrote:
> 
> On Fri, Aug 20, 2021 at 02:12:13PM +0100, Marc Zyngier wrote:
> > On Thu, 12 Aug 2021 18:26:28 +0100,
> > Andreas F?rber <afaerber at suse.de> wrote:
> > > 
> > > Hi Chester et al.,
> > > 
> > > On 05.08.21 08:54, Chester Lin wrote:
> > > > Add an initial dtsi file for generic SoC features of NXP S32G2.
> > > > 
> > > > Signed-off-by: Chester Lin <clin at suse.com>
> > > > ---
> > > >  arch/arm64/boot/dts/freescale/s32g2.dtsi | 98 ++++++++++++++++++++++++
> > > >  1 file changed, 98 insertions(+)
> > > >  create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > > > new file mode 100644
> > > > index 000000000000..3321819c1a2d
> > > > --- /dev/null
> > > > +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > 
> > [...]
> > 
> > > > +		gic: interrupt-controller at 50800000 {
> > > > +			compatible = "arm,gic-v3";
> > > > +			#interrupt-cells = <3>;
> > > > +			interrupt-controller;
> > > > +			reg = <0 0x50800000 0 0x10000>,
> > > > +			      <0 0x50880000 0 0x200000>,
> > 
> > That's enough redistributor space for 16 CPUs. However, you only
> > describe 4. Either the number of CPUs is wrong, the size is wrong, or
> > the GIC has been configured for more cores than the SoC has.
> 
> Confirmed the SoC can only find 4 redistributors:
> 
> localhost:~ # dmesg | grep CPU
> [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
> [    0.000000] Detected VIPT I-cache on CPU0
> [    0.000000] CPU features: detected: GIC system register CPU interface
> [    0.000000] CPU features: detected: ARM erratum 845719
> [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
> [    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=480 to nr_cpu_ids=4.
> [    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x0000000050880000
> [    0.063865] smp: Bringing up secondary CPUs ...
> [    0.068852] Detected VIPT I-cache on CPU1
> [    0.068894] GICv3: CPU1: found redistributor 1 region 0:0x00000000508a0000
> [    0.068963] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
> [    0.069809] Detected VIPT I-cache on CPU2
> [    0.069851] GICv3: CPU2: found redistributor 100 region 0:0x00000000508c0000
> [    0.069903] CPU2: Booted secondary processor 0x0000000100 [0x410fd034]
> [    0.070698] Detected VIPT I-cache on CPU3
> [    0.070722] GICv3: CPU3: found redistributor 101 region 0:0x00000000508e0000
> [    0.070749] CPU3: Booted secondary processor 0x0000000101 [0x410fd034]
> [    0.070847] smp: Brought up 1 node, 4 CPUs
> <..snip..>

That's not the correct way to find out. Each CPU tries to find its
matching RD in the region. This doesn't mean there aren't more RDs
present in the GIC.

You need to iterate over all the RDs in the region until you find one
that has GICR_TYPER.Last == 1. This will give you the actual count.
Alternatively, you can check whether the RD at 508e0000 has that bit
set. If it doesn't, then you know there are more RDs than CPUs.

	M.

-- 
Without deviation from the norm, progress is not possible.


From chunkuang.hu at kernel.org  Fri Aug 20 08:43:02 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Fri, 20 Aug 2021 23:43:02 +0800
Subject: [PATCH v8 12/13] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20210819022327.13040-13-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-13-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_9+2CvcSxZByqxVM18hLQfE0rt5zf2JLxCYrd8O1_UCAg@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
>
> Add MERGE engine file:
> MERGE module is used to merge two slice-per-line inputs
> into one side-by-side output.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/Makefile           |   1 +
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 268 ++++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  16 ++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   2 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
>  7 files changed, 297 insertions(+)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
>
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index dc54a7a69005..538e0087a44c 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -3,6 +3,7 @@
>  mediatek-drm-y := mtk_disp_ccorr.o \
>                   mtk_disp_color.o \
>                   mtk_disp_gamma.o \
> +                 mtk_disp_merge.o \
>                   mtk_disp_ovl.o \
>                   mtk_disp_rdma.o \
>                   mtk_drm_crtc.o \
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index cafd9df2d63b..f407cd9d873e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -46,6 +46,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
>  void mtk_gamma_start(struct device *dev);
>  void mtk_gamma_stop(struct device *dev);
>
> +int mtk_merge_clk_enable(struct device *dev);
> +void mtk_merge_clk_disable(struct device *dev);
> +void mtk_merge_config(struct device *dev, unsigned int width,
> +                     unsigned int height, unsigned int vrefresh,
> +                     unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> +void mtk_merge_start(struct device *dev);
> +void mtk_merge_stop(struct device *dev);
> +
>  void mtk_ovl_bgclr_in_on(struct device *dev);
>  void mtk_ovl_bgclr_in_off(struct device *dev);
>  void mtk_ovl_bypass_shadow(struct device *dev);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> new file mode 100644
> index 000000000000..ebcb646bde9c
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> @@ -0,0 +1,268 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/soc/mediatek/mtk-cmdq.h>
> +
> +#include "mtk_drm_ddp_comp.h"
> +#include "mtk_drm_drv.h"
> +#include "mtk_disp_drv.h"
> +
> +#define DISP_REG_MERGE_CTRL            0x000
> +#define MERGE_EN                               1
> +#define DISP_REG_MERGE_CFG_0           0x010
> +#define DISP_REG_MERGE_CFG_4           0x020
> +#define DISP_REG_MERGE_CFG_10          0x038
> +/* no swap */
> +#define SWAP_MODE                              0
> +#define FLD_SWAP_MODE                          GENMASK(4, 0)
> +#define DISP_REG_MERGE_CFG_12          0x040
> +#define CFG_10_10_1PI_2PO_BUF_MODE             6
> +#define CFG_10_10_2PI_2PO_BUF_MODE             8
> +#define FLD_CFG_MERGE_MODE                     GENMASK(4, 0)
> +#define DISP_REG_MERGE_CFG_24          0x070
> +#define DISP_REG_MERGE_CFG_25          0x074
> +#define DISP_REG_MERGE_CFG_36          0x0a0
> +#define ULTRA_EN                               1

You could use FLD_ULTRA_EN for this.

> +#define PREULTRA_EN                            1
> +#define HALT_FOR_DVFS_EN                       0

You could just not set this.

> +#define FLD_ULTRA_EN                           GENMASK(0, 0)

#define FLD_ULTRA_EN BIT(0)

Regards,
Chun-Kuang.

> +#define FLD_PREULTRA_EN                                GENMASK(4, 4)
> +#define FLD_HALT_FOR_DVFS_EN                   GENMASK(8, 8)
> +#define DISP_REG_MERGE_CFG_37          0x0a4
> +/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
> +#define BUFFER_MODE                            3
> +#define FLD_BUFFER_MODE                                GENMASK(1, 0)
> +#define DISP_REG_MERGE_CFG_38                  0x0a8
> +#define FLD_VDE_BLOCK_ULTRA                    GENMASK(0, 0)
> +#define FLD_VALID_TH_BLOCK_ULTRA               GENMASK(4, 4)
> +#define FLD_ULTRA_FIFO_VALID_TH                        GENMASK(31, 16)
> +#define DISP_REG_MERGE_CFG_39          0x0ac
> +#define FLD_NVDE_FORCE_PREULTRA                        GENMASK(8, 8)
> +#define FLD_NVALID_TH_FORCE_PREULTRA           GENMASK(12, 12)
> +#define FLD_PREULTRA_FIFO_VALID_TH             GENMASK(31, 16)


From pali at kernel.org  Fri Aug 20 08:50:20 2021
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Fri, 20 Aug 2021 17:50:20 +0200
Subject: [PATCH] PCI: aardvark: Fix masking and unmasking legacy INTx
 interrupts
Message-ID: <20210820155020.3000-1-pali@kernel.org>

irq_mask and irq_unmask callbacks need to be properly guarded by raw spin
locks as masking/unmasking procedure needs atomic read-modify-write
operation on hardware register.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Reported-by: Marc Zyngier <maz at kernel.org>
Cc: stable at vger.kernel.org
---
 drivers/pci/controller/pci-aardvark.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index fb8060160251..a49e8bad9f4f 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -234,6 +234,7 @@ struct advk_pcie {
 	u8 wins_count;
 	struct irq_domain *irq_domain;
 	struct irq_chip irq_chip;
+	raw_spinlock_t irq_lock;
 	struct irq_domain *msi_domain;
 	struct irq_domain *msi_inner_domain;
 	struct irq_chip msi_bottom_irq_chip;
@@ -1087,22 +1088,28 @@ static void advk_pcie_irq_mask(struct irq_data *d)
 {
 	struct advk_pcie *pcie = d->domain->host_data;
 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
 	u32 mask;
 
+	raw_spin_lock_irqsave(&pcie->irq_lock, flags);
 	mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
 	mask |= PCIE_ISR1_INTX_ASSERT(hwirq);
 	advk_writel(pcie, mask, PCIE_ISR1_MASK_REG);
+	raw_spin_unlock_irqrestore(&pcie->irq_lock, flags);
 }
 
 static void advk_pcie_irq_unmask(struct irq_data *d)
 {
 	struct advk_pcie *pcie = d->domain->host_data;
 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
 	u32 mask;
 
+	raw_spin_lock_irqsave(&pcie->irq_lock, flags);
 	mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
 	mask &= ~PCIE_ISR1_INTX_ASSERT(hwirq);
 	advk_writel(pcie, mask, PCIE_ISR1_MASK_REG);
+	raw_spin_unlock_irqrestore(&pcie->irq_lock, flags);
 }
 
 static int advk_pcie_irq_map(struct irq_domain *h,
@@ -1186,6 +1193,8 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
 	struct irq_chip *irq_chip;
 	int ret = 0;
 
+	raw_spin_lock_init(&pcie->irq_lock);
+
 	pcie_intc_node =  of_get_next_child(node, NULL);
 	if (!pcie_intc_node) {
 		dev_err(dev, "No PCIe Intc node found\n");
-- 
2.20.1



From maz at kernel.org  Fri Aug 20 08:56:38 2021
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 20 Aug 2021 16:56:38 +0100
Subject: [PATCH] PCI: aardvark: Fix masking and unmasking legacy INTx
 interrupts
In-Reply-To: <20210820155020.3000-1-pali@kernel.org>
References: <20210820155020.3000-1-pali@kernel.org>
Message-ID: <87h7fkqfd5.wl-maz@kernel.org>

On Fri, 20 Aug 2021 16:50:20 +0100,
Pali Roh?r <pali at kernel.org> wrote:
> 
> irq_mask and irq_unmask callbacks need to be properly guarded by raw spin
> locks as masking/unmasking procedure needs atomic read-modify-write
> operation on hardware register.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Reported-by: Marc Zyngier <maz at kernel.org>
> Cc: stable at vger.kernel.org

Acked-by: Marc Zyngier <maz at kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


From liviu.dudau at arm.com  Fri Aug 20 09:05:09 2021
From: liviu.dudau at arm.com (Liviu Dudau)
Date: Fri, 20 Aug 2021 17:05:09 +0100
Subject: [PATCH v2 02/14] drm/arm/hdlcd: Convert to Linux IRQ interfaces
In-Reply-To: <20210803090704.32152-3-tzimmermann@suse.de>
References: <20210803090704.32152-1-tzimmermann@suse.de>
 <20210803090704.32152-3-tzimmermann@suse.de>
Message-ID: <20210820160509.eo267b4r64v4qa3n@e110455-lin.cambridge.arm.com>

On Tue, Aug 03, 2021 at 11:06:52AM +0200, Thomas Zimmermann wrote:
> Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
> IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
> don't benefit from using it.
> 
> DRM IRQ callbacks are now being called directly or inlined.
> 
> Calls to platform_get_irq() can fail with a negative errno code.
> Abort initialization in this case. The DRM IRQ midlayer does not
> handle this case correctly.
> 
> v2:
> 	* name struct drm_device variables 'drm' (Sam)
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> Acked-by: Sam Ravnborg <sam at ravnborg.org>

Sorry for the delayed response due to holidays.

Acked-by: Liviu Dudau <liviu.dudau at arm.com>

Best regards,
Liviu

> ---
>  drivers/gpu/drm/arm/hdlcd_drv.c | 174 ++++++++++++++++++--------------
>  drivers/gpu/drm/arm/hdlcd_drv.h |   1 +
>  2 files changed, 97 insertions(+), 78 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> index 81ae92390736..479c2422a2e0 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> @@ -29,7 +29,6 @@
>  #include <drm/drm_fb_helper.h>
>  #include <drm/drm_gem_cma_helper.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
> -#include <drm/drm_irq.h>
>  #include <drm/drm_modeset_helper.h>
>  #include <drm/drm_of.h>
>  #include <drm/drm_probe_helper.h>
> @@ -38,6 +37,94 @@
>  #include "hdlcd_drv.h"
>  #include "hdlcd_regs.h"
>  
> +static irqreturn_t hdlcd_irq(int irq, void *arg)
> +{
> +	struct drm_device *drm = arg;
> +	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> +	unsigned long irq_status;
> +
> +	irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
> +
> +#ifdef CONFIG_DEBUG_FS
> +	if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
> +		atomic_inc(&hdlcd->buffer_underrun_count);
> +
> +	if (irq_status & HDLCD_INTERRUPT_DMA_END)
> +		atomic_inc(&hdlcd->dma_end_count);
> +
> +	if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
> +		atomic_inc(&hdlcd->bus_error_count);
> +
> +	if (irq_status & HDLCD_INTERRUPT_VSYNC)
> +		atomic_inc(&hdlcd->vsync_count);
> +
> +#endif
> +	if (irq_status & HDLCD_INTERRUPT_VSYNC)
> +		drm_crtc_handle_vblank(&hdlcd->crtc);
> +
> +	/* acknowledge interrupt(s) */
> +	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void hdlcd_irq_preinstall(struct drm_device *drm)
> +{
> +	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> +	/* Ensure interrupts are disabled */
> +	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
> +	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
> +}
> +
> +static void hdlcd_irq_postinstall(struct drm_device *drm)
> +{
> +#ifdef CONFIG_DEBUG_FS
> +	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> +	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
> +
> +	/* enable debug interrupts */
> +	irq_mask |= HDLCD_DEBUG_INT_MASK;
> +
> +	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
> +#endif
> +}
> +
> +static int hdlcd_irq_install(struct drm_device *drm, int irq)
> +{
> +	int ret;
> +
> +	if (irq == IRQ_NOTCONNECTED)
> +		return -ENOTCONN;
> +
> +	hdlcd_irq_preinstall(drm);
> +
> +	ret = request_irq(irq, hdlcd_irq, 0, drm->driver->name, drm);
> +	if (ret)
> +		return ret;
> +
> +	hdlcd_irq_postinstall(drm);
> +
> +	return 0;
> +}
> +
> +static void hdlcd_irq_uninstall(struct drm_device *drm)
> +{
> +	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> +	/* disable all the interrupts that we might have enabled */
> +	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
> +
> +#ifdef CONFIG_DEBUG_FS
> +	/* disable debug interrupts */
> +	irq_mask &= ~HDLCD_DEBUG_INT_MASK;
> +#endif
> +
> +	/* disable vsync interrupts */
> +	irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
> +	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
> +
> +	free_irq(hdlcd->irq, drm);
> +}
> +
>  static int hdlcd_load(struct drm_device *drm, unsigned long flags)
>  {
>  	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> @@ -90,7 +177,12 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
>  		goto setup_fail;
>  	}
>  
> -	ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret < 0)
> +		goto irq_fail;
> +	hdlcd->irq = ret;
> +
> +	ret = hdlcd_irq_install(drm, hdlcd->irq);
>  	if (ret < 0) {
>  		DRM_ERROR("failed to install IRQ handler\n");
>  		goto irq_fail;
> @@ -122,76 +214,6 @@ static void hdlcd_setup_mode_config(struct drm_device *drm)
>  	drm->mode_config.funcs = &hdlcd_mode_config_funcs;
>  }
>  
> -static irqreturn_t hdlcd_irq(int irq, void *arg)
> -{
> -	struct drm_device *drm = arg;
> -	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> -	unsigned long irq_status;
> -
> -	irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
> -
> -#ifdef CONFIG_DEBUG_FS
> -	if (irq_status & HDLCD_INTERRUPT_UNDERRUN)
> -		atomic_inc(&hdlcd->buffer_underrun_count);
> -
> -	if (irq_status & HDLCD_INTERRUPT_DMA_END)
> -		atomic_inc(&hdlcd->dma_end_count);
> -
> -	if (irq_status & HDLCD_INTERRUPT_BUS_ERROR)
> -		atomic_inc(&hdlcd->bus_error_count);
> -
> -	if (irq_status & HDLCD_INTERRUPT_VSYNC)
> -		atomic_inc(&hdlcd->vsync_count);
> -
> -#endif
> -	if (irq_status & HDLCD_INTERRUPT_VSYNC)
> -		drm_crtc_handle_vblank(&hdlcd->crtc);
> -
> -	/* acknowledge interrupt(s) */
> -	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
> -
> -	return IRQ_HANDLED;
> -}
> -
> -static void hdlcd_irq_preinstall(struct drm_device *drm)
> -{
> -	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> -	/* Ensure interrupts are disabled */
> -	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
> -	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
> -}
> -
> -static int hdlcd_irq_postinstall(struct drm_device *drm)
> -{
> -#ifdef CONFIG_DEBUG_FS
> -	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> -	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
> -
> -	/* enable debug interrupts */
> -	irq_mask |= HDLCD_DEBUG_INT_MASK;
> -
> -	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
> -#endif
> -	return 0;
> -}
> -
> -static void hdlcd_irq_uninstall(struct drm_device *drm)
> -{
> -	struct hdlcd_drm_private *hdlcd = drm->dev_private;
> -	/* disable all the interrupts that we might have enabled */
> -	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
> -
> -#ifdef CONFIG_DEBUG_FS
> -	/* disable debug interrupts */
> -	irq_mask &= ~HDLCD_DEBUG_INT_MASK;
> -#endif
> -
> -	/* disable vsync interrupts */
> -	irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
> -
> -	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
> -}
> -
>  #ifdef CONFIG_DEBUG_FS
>  static int hdlcd_show_underrun_count(struct seq_file *m, void *arg)
>  {
> @@ -236,10 +258,6 @@ DEFINE_DRM_GEM_CMA_FOPS(fops);
>  
>  static const struct drm_driver hdlcd_driver = {
>  	.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
> -	.irq_handler = hdlcd_irq,
> -	.irq_preinstall = hdlcd_irq_preinstall,
> -	.irq_postinstall = hdlcd_irq_postinstall,
> -	.irq_uninstall = hdlcd_irq_uninstall,
>  	DRM_GEM_CMA_DRIVER_OPS,
>  #ifdef CONFIG_DEBUG_FS
>  	.debugfs_init = hdlcd_debugfs_init,
> @@ -316,7 +334,7 @@ static int hdlcd_drm_bind(struct device *dev)
>  err_unload:
>  	of_node_put(hdlcd->crtc.port);
>  	hdlcd->crtc.port = NULL;
> -	drm_irq_uninstall(drm);
> +	hdlcd_irq_uninstall(drm);
>  	of_reserved_mem_device_release(drm->dev);
>  err_free:
>  	drm_mode_config_cleanup(drm);
> @@ -338,7 +356,7 @@ static void hdlcd_drm_unbind(struct device *dev)
>  	hdlcd->crtc.port = NULL;
>  	pm_runtime_get_sync(dev);
>  	drm_atomic_helper_shutdown(drm);
> -	drm_irq_uninstall(drm);
> +	hdlcd_irq_uninstall(drm);
>  	pm_runtime_put(dev);
>  	if (pm_runtime_enabled(dev))
>  		pm_runtime_disable(dev);
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
> index fd438d177b64..909c39c28487 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.h
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.h
> @@ -11,6 +11,7 @@ struct hdlcd_drm_private {
>  	struct clk			*clk;
>  	struct drm_crtc			crtc;
>  	struct drm_plane		*plane;
> +	unsigned int			irq;
>  #ifdef CONFIG_DEBUG_FS
>  	atomic_t buffer_underrun_count;
>  	atomic_t bus_error_count;
> -- 
> 2.32.0
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?


From tharvey at gateworks.com  Fri Aug 20 09:06:42 2021
From: tharvey at gateworks.com (Tim Harvey)
Date: Fri, 20 Aug 2021 09:06:42 -0700
Subject: arm32 insecure W+X mapping
In-Reply-To: <20210820001646.GN22278@shell.armlinux.org.uk>
References: <CAJ+vNU0PaPNHbJc5RXgrRYJw2aWowrGVMOrU1=hKhsCTXAB=DA@mail.gmail.com>
 <20210819212819.GM22278@shell.armlinux.org.uk>
 <CAJ+vNU05L1Fyvy1R6_HwpLeo92LSJhDY4BCr-0aqM7rYgh6TVQ@mail.gmail.com>
 <20210820001646.GN22278@shell.armlinux.org.uk>
Message-ID: <CAJ+vNU1sh9C=vi1TjHtXAY1F=UNY4cSGrc2vkGujW9pQUPeDDg@mail.gmail.com>

On Thu, Aug 19, 2021 at 5:16 PM Russell King (Oracle)
<linux at armlinux.org.uk> wrote:
>
> On Thu, Aug 19, 2021 at 04:59:15PM -0700, Tim Harvey wrote:
> > On Thu, Aug 19, 2021 at 2:28 PM Russell King (Oracle)
> > <linux at armlinux.org.uk> wrote:
> > >
> > > On Thu, Aug 19, 2021 at 10:19:46AM -0700, Tim Harvey wrote:
> > > > Greetings,
> > > >
> > > > Since commit a8e53c151fe7 "(ARM: 8737/1: mm: dump: add checking for
> > > > writable and executable)" I've been seeing the following appear on my
> > > > arm32 kernel:
> > > >
> > > > arm/mm: Found insecure W+X mapping at address 0xf087d000
> > > > ...
> > > > Checked W+X mappings: FAILED, 1 W+X pages found
> > > >
> > > > As I haven't seen others report this I assume it's something unique to
> > > > my kernel configuration. How do I debug what is causing the insecure
> > > > page?
> > >
> > > If you check /proc/vmallocinfo, it should tell you the physical
> > > address that was mapped there, and the function that created the
> > > mapping. That should give enough clues to track it down.
> > >
> >
> > Russell,
> >
> > Thanks for the tip!
> >
> > # dmesg | grep insecure
> > [   13.219582] arm/mm: Found insecure W+X mapping at address 0xf087d000
> > # cat /proc/vmallocinfo | grep 0xf0
> > 0x5f3045dd-0xf0020e05   20480 imx6_pm_get_base+0x64/0x98 phys=0x020e0000 ioremap
> > 0xf0020e05-0x6e748217    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> > 0x127639d7-0x334ee291    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap
>
> Oh... the kernel's %p pointer munging (for security reasons) is
> affecting your ability to debug your problem. Assuming this is a
> recent kernel, you can disable this by passing "no_hash_pointers"
> on the kernel command line. You should then see real addresses (and
> a big fat message at boot time about it.
>

I'm using 5.13 and when I pass in 'no_hash_pointers' I do indeed see
the huge warning but I get similar results that I can't make sense of:
# uname -r
5.13.0-00009-g8beacec9a060
# cat /proc/cmdline
console=ttymxc1,115200 no_hash_pointers
# dmesg | grep insecure
[   13.309537] arm/mm: Found insecure W+X mapping at address 0xf087d000
# cat /proc/vmallocinfo | grep 0xf0
0xf02c73a9-0xfa933595   20480 __devm_ioremap+0x94/0xa4 phys=0x0202c000 ioremap
0xc02cb795-0x054951d9    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap
# cat /proc/vmallocinfo
0xbe008562-0x5576ab44   20480 of_iomap+0x44/0x68 phys=0x020d8000 ioremap
0x5576ab44-0xb255df29    8192 of_iomap+0x44/0x68 phys=0x00a01000 ioremap
0x46b8335b-0x447c6b02   20480 of_iomap+0x44/0x68 phys=0x020dc000 ioremap
0x447c6b02-0x7527802c    8192 l2x0_of_init+0x78/0x26c phys=0x00a02000 ioremap
0xee30b5de-0x9e0d6dbd   20480 of_iomap+0x44/0x68 phys=0x020c4000 ioremap
0x9e0d6dbd-0xf62147bb    8192 of_iomap+0x44/0x68 phys=0x020c8000 ioremap
0xfe3688a4-0xecfce701   20480 of_iomap+0x44/0x68 phys=0x020c4000 ioremap
0x0d7d7401-0xce35bdb8   20480 of_iomap+0x44/0x68 phys=0x02098000 ioremap
0xd0da9915-0xa147e0b3    8192 bpf_prog_alloc_no_stats+0x2c/0x118 pages=1 vmalloc
0xa147e0b3-0xb043f532  266240 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xb043f532-0x7f372e98    8192 gen_pool_add_owner+0x34/0x94 pages=1 vmalloc
0x7f372e98-0x22c0f7fa    8192 of_syscon_register+0xb8/0x2a0
phys=0x020c8000 ioremap
0x22c0f7fa-0xbc80b65b    8192 __devm_ioremap+0x94/0xa4 phys=0x020c9000 ioremap
0xbc80b65b-0x5737939a    8192 __devm_ioremap+0x94/0xa4 phys=0x020ca000 ioremap
0x5737939a-0xfaac3f4b    8192 gen_pool_add_owner+0x34/0x94 pages=1 vmalloc
0xfaac3f4b-0x3400434f   20480 of_iomap+0x44/0x68 phys=0x021b0000 ioremap
0x3400434f-0x4b5b39be    8192 imx6_pm_common_init+0x118/0x36c
phys=0x00900000 ioremap
0xfa6109c5-0x8220d86a  266240 __devm_ioremap+0x50/0xa4 phys=0x00900000 ioremap
0x8220d86a-0xbb32fa78    8192 imx6_pm_get_base+0x64/0x98 phys=0x00a02000 ioremap
0xe37ddad7-0x94023f64   20480 imx6_pm_get_base+0x64/0x98 phys=0x021b0000 ioremap
0x94023f64-0x032e50a3    8192 of_syscon_register+0xb8/0x2a0
phys=0x020e0000 ioremap
0xd41722d0-0x69a3231e   20480 imx6_pm_get_base+0x64/0x98 phys=0x020d8000 ioremap
0x69a3231e-0x6dc29018    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x327a8342-0x78efb8e0   20480 imx6_pm_get_base+0x64/0x98 phys=0x020e0000 ioremap
0x78efb8e0-0xe6178284    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x76f38a9b-0x34af82ac   20480 imx6_pm_get_base+0x64/0x98 phys=0x020dc000 ioremap
0x34af82ac-0x81d03489    8192 __devm_ioremap+0x94/0xa4 phys=0x02600000 ioremap
0x63fe0abd-0x6b04db7d   20480 __devm_ioremap+0x94/0xa4 phys=0x020e0000 ioremap
0xb849bd1c-0xc46ae71e   20480 __devm_ioremap+0x94/0xa4 phys=0x0209c000 ioremap
0xc46ae71e-0x1eb811b8    8192 __devm_ioremap+0x94/0xa4 phys=0x02608000 ioremap
0x2c687987-0xbae166ed   20480 __devm_ioremap+0x94/0xa4 phys=0x020a0000 ioremap
0xbae166ed-0xb27fac72    8192 __devm_ioremap+0x94/0xa4 phys=0x02630000 ioremap
0x0868e824-0xa08b93b8   20480 __devm_ioremap+0x94/0xa4 phys=0x020a4000 ioremap
0xa08b93b8-0x73e79d37    8192 __devm_ioremap+0x94/0xa4 phys=0x02638000 ioremap
0x3ff71a53-0x1664550e   20480 __devm_ioremap+0x94/0xa4 phys=0x020a8000 ioremap
0x1664550e-0xdffb9edc    8192 __devm_ioremap+0x94/0xa4 phys=0x02620000 ioremap
0x1d0f2f08-0xb32e296b   20480 __devm_ioremap+0x94/0xa4 phys=0x020ac000 ioremap
0xb32e296b-0x7062006c    8192 __devm_ioremap+0x94/0xa4 phys=0x02668000 ioremap
0xff2f5a70-0xff7ff60a   20480 __devm_ioremap+0x94/0xa4 phys=0x020b0000 ioremap
0xff7ff60a-0x8779d9bc    8192 __devm_ioremap+0x94/0xa4 phys=0x02640000 ioremap
0xccc5d4a4-0xbbd8184e   20480 __devm_ioremap+0x94/0xa4 phys=0x020b4000 ioremap
0xf3211f15-0xdf4e4390   12288 __devm_ioremap+0x94/0xa4 phys=0x00110000 ioremap
0xdf4e4390-0x8b969f88    8192 __devm_ioremap+0x94/0xa4 phys=0x02648000 ioremap
0x67d4c705-0x2844e8ae   20480 __devm_ioremap+0x94/0xa4 phys=0x021a0000 ioremap
0x2844e8ae-0xe969daac    8192 __devm_ioremap+0x94/0xa4 phys=0x02658000 ioremap
0x6c51de7f-0x13285901   20480 __devm_ioremap+0x94/0xa4 phys=0x021a4000 ioremap
0x13285901-0xcf2d44dd    8192 __devm_ioremap+0x94/0xa4 phys=0x02780000 ioremap
0x632c016d-0x81fc4149   20480 __devm_ioremap+0x94/0xa4 phys=0x021a8000 ioremap
0x81fc4149-0xd005970a    8192 __devm_ioremap+0x94/0xa4 phys=0x02660000 ioremap
0xacd62b34-0x2369ad7d   20480 __devm_ioremap+0x94/0xa4 phys=0x021d8000 ioremap
0x2369ad7d-0x6c218545    8192 __devm_ioremap+0x94/0xa4 phys=0x02740000 ioremap
0xd8caee3b-0x8f7b3eae   20480 __devm_ioremap+0x94/0xa4 phys=0x01ffc000 ioremap
0x8f7b3eae-0x7754f3e6    8192 __devm_ioremap+0x94/0xa4 phys=0x02650000 ioremap
0xcf739a9c-0x86505b25   20480 __devm_ioremap+0x94/0xa4 phys=0x020ec000 ioremap
0x86505b25-0x4419339d    8192 __devm_ioremap+0x94/0xa4 phys=0x02a00000 ioremap
0x38550150-0xee5ad30c   20480 of_syscon_register+0xb8/0x2a0
phys=0x021bc000 ioremap
0xee5ad30c-0x73467058    8192 __devm_ioremap+0x94/0xa4 phys=0x02a08000 ioremap
0x7659aedb-0xd37bf098   20480 __devm_ioremap+0x94/0xa4 phys=0x020dc000 ioremap
0xd37bf098-0x6b62199d    8192 __devm_ioremap+0x94/0xa4 phys=0x02a30000 ioremap
0xe2fcb2be-0x83ac2ff4   20480 __devm_ioremap+0x94/0xa4 phys=0x02020000 ioremap
0x83ac2ff4-0x498e66da    8192 __devm_ioremap+0x94/0xa4 phys=0x02a38000 ioremap
0xda200768-0x9519b5b7   20480 __devm_ioremap+0x94/0xa4 phys=0x021e8000 ioremap
0x9519b5b7-0xd8066315    8192 __devm_ioremap+0x94/0xa4 phys=0x02a20000 ioremap
0x327c6cd3-0xb09836e5   20480 __devm_ioremap+0x94/0xa4 phys=0x021f4000 ioremap
0xb09836e5-0x2ee61e13    8192 __devm_ioremap+0x94/0xa4 phys=0x02a68000 ioremap
0x28a28e71-0xfb74b75d   40960 __devm_ioremap+0x94/0xa4 phys=0x00120000 ioremap
0xfb74b75d-0x94731aa5    8192 __devm_ioremap+0x94/0xa4 phys=0x02a40000 ioremap
0x94731aa5-0x9ed95f4b   20480 __devm_ioremap+0x94/0xa4 phys=0x00130000 ioremap
0x9ed95f4b-0xb6679e93    8192 __devm_ioremap+0x94/0xa4 phys=0x02a48000 ioremap
0xd2083a49-0xd15b1ee5   20480 __devm_ioremap+0x94/0xa4 phys=0x00134000 ioremap
0xd15b1ee5-0xb873e80d    8192 __devm_ioremap+0x94/0xa4 phys=0x02a58000 ioremap
0xb873e80d-0xad853c5f    8192 __devm_ioremap+0x94/0xa4 phys=0x02b80000 ioremap
0xad853c5f-0x727a169b    8192 __devm_ioremap+0x94/0xa4 phys=0x02a60000 ioremap
0x79bcf223-0xd8778c7f  528384 devm_pci_remap_cfgspace+0x3c/0x74
phys=0x01f00000 ioremap
0xd8778c7f-0xcd8f995b  135168 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xcd8f995b-0x0e93c50d    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x0e93c50d-0x35d018fd   20480 __devm_ioremap+0x94/0xa4 phys=0x02204000 ioremap
0x35d018fd-0x30dd9119  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x30dd9119-0x1d49a1b3    8192 __devm_ioremap+0x94/0xa4 phys=0x02b40000 ioremap
0x1d49a1b3-0xe202a461    8192 __devm_ioremap+0x94/0xa4 phys=0x02a50000 ioremap
0x3c5f9898-0x7c998da8  135168 __devm_ioremap+0x94/0xa4 phys=0x02700000 ioremap
0x0be6bff2-0xe617431b   12288 __devm_ioremap+0x94/0xa4 phys=0x00112000 ioremap
0xe617431b-0x1894871f    8192 __pci_enable_msix_range+0x1b4/0x50c
phys=0x01420000 ioremap
0xcc3e24ea-0x24fc33d0   69632 __devm_ioremap+0x94/0xa4 phys=0x02760000 ioremap
0x24fc33d0-0x2ad2fe2c   81920 pcpu_create_chunk+0x14c/0x290 pages=19 vmalloc
0x064e8962-0x041a1631    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
0x041a1631-0xa78f78b0  135168 __devm_ioremap+0x94/0xa4 phys=0x02b00000 ioremap
0x482eea6f-0xa04223bd   12288 __devm_ioremap+0x94/0xa4 phys=0x00114000 ioremap
0xa04223bd-0x47cd64d8    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
0x496ff4b8-0x1b8cd27f   69632 __devm_ioremap+0x94/0xa4 phys=0x02b60000 ioremap
0x1b8cd27f-0x9a03a792 1576960 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x9e844161-0x46bbc5c3    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x46bbc5c3-0x061f37bb   20480 __devm_ioremap+0x94/0xa4 phys=0x02200000 ioremap
0x061f37bb-0x099e44f8   98304 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x099e44f8-0x5a73428f   36864 iscsi_target_init_module+0xb4/0x234
pages=8 vmalloc
0x5a73428f-0x6b24094e   20480 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x8763af88-0xc279660f   20480 __devm_ioremap+0x94/0xa4 phys=0x0200c000 ioremap
0xc279660f-0x0746510e    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xc42e58a5-0x9bb92a15   20480 __devm_ioremap+0x94/0xa4 phys=0x02188000 ioremap
0x9bb92a15-0xbffbc968  135168 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xbffbc968-0xc3135661   36864 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x7f8906cc-0x57602490   20480 __devm_ioremap+0x94/0xa4 phys=0x021e4000 ioremap
0x57602490-0x32a0cd25    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x32a0cd25-0xccf592e4    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
0xccf592e4-0xc3d5117e    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xd80eccd6-0x1eccdd8b  135168 igb_probe+0x150/0x10a4 phys=0x01400000 ioremap
0x1eccdd8b-0x360f1603    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x32fecfc9-0x71e47aa2   20480 __devm_ioremap+0x94/0xa4 phys=0x020c0000 ioremap
0x71e47aa2-0x5098c2fb    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xaf379216-0x24330e7c   20480 __devm_ioremap+0x94/0xa4 phys=0x02198000 ioremap
0x3dd54ba7-0x2392a17a   20480 __devm_ioremap+0x94/0xa4 phys=0x02034000 ioremap
0x2392a17a-0x1e11712d   16384 n_tty_open+0x10/0x9c pages=3 vmalloc
0x300b1fb4-0x33dba900   20480 __devm_ioremap+0x94/0xa4 phys=0x02028000 ioremap
0xf02c73a9-0xfa933595   20480 __devm_ioremap+0x94/0xa4 phys=0x0202c000 ioremap
0xbe5c4daa-0x6af5bd9c  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x6af5bd9c-0x9ea7250e  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0x9ea7250e-0x74bbeefe 1294336 zstd_comp_init+0x58/0xb0 pages=315 vmalloc
0x74bbeefe-0x591c7299  163840 zstd_decomp_init+0x14/0x54 pages=39 vmalloc
0x591c7299-0x27154f89  274432 deflate_comp_init+0x20/0x90 pages=66 vmalloc
0x27154f89-0x3978b460   49152 deflate_decomp_init+0x14/0x58 pages=11 vmalloc
0x3978b460-0x99da8daa  212992 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xe9a5ec5f-0xb0e53888  249856 __devm_ioremap+0x94/0xa4 phys=0x02040000 ioremap
0xb0e53888-0xc24dd16d  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
0xc02cb795-0x054951d9    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap
0x32815c21-0x48bd192d 2097152 pci_reserve_io+0x0/0x30 ioremap
0xba73986b-0x4f91845f  311296 pcpu_get_vm_areas+0x0/0x10c0 vmalloc
0x4f91845f-0x86cbfbfa  311296 pcpu_get_vm_areas+0x0/0x10c0 vmalloc
0x17d9341e-0xbe008562   16384 unpurged vm_area
0xecfce701-0xd35ab9b8    8192 unpurged vm_area
0xce35bdb8-0xd0da9915    8192 unpurged vm_area
0x6b04db7d-0xb849bd1c 15609856 unpurged vm_area
0xe202a461-0x3c5f9898   73728 unpurged vm_area
0x7c998da8-0x0be6bff2   36864 unpurged vm_area
0x2ad2fe2c-0x064e8962   36864 unpurged vm_area
0xa78f78b0-0x482eea6f   36864 unpurged vm_area
0x9a03a792-0x9e844161  442368 unpurged vm_area
0x92d57223-0xd09758da  249856 unpurged vm_area
0xfa933595-0xbe5c4daa   36864 unpurged vm_area

Thanks for your help!

Tim


From robh at kernel.org  Fri Aug 20 09:50:11 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 20 Aug 2021 11:50:11 -0500
Subject: [PATCH] kbuild: Enable dtc 'pci_device_reg' warning by default
Message-ID: <20210820165011.3257112-1-robh@kernel.org>

There's only a couple of instances of the 'pci_device_reg' warnings left
and they look legit, so let's enable the warning by default.

Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Nicolas Saenz Julienne <nsaenz at kernel.org>
Cc: soc at kernel.org
Signed-off-by: Rob Herring <robh at kernel.org>
---
These are the 2 remaining warnings:

arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi:464.3-52: Warning (pci_device_reg): /pcie at f8000000/pcie at 0,0:reg: PCI reg address is not configuration space
arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning (pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format error, expected "0,0"
---
 scripts/Makefile.lib | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 10950559b223..c57f14ac6f99 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -309,8 +309,7 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \
 	-Wno-alias_paths \
 	-Wno-graph_child_address \
 	-Wno-simple_bus_reg \
-	-Wno-unique_unit_address \
-	-Wno-pci_device_reg
+	-Wno-unique_unit_address
 endif
 
 ifneq ($(findstring 2,$(KBUILD_EXTRA_WARN)),)
-- 
2.30.2



From robh at kernel.org  Fri Aug 20 09:52:53 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 20 Aug 2021 11:52:53 -0500
Subject: [PATCH] arm/arm64: dts: Fix remaining dtc 'unit_address_format'
 warnings
Message-ID: <20210820165253.3258557-1-robh@kernel.org>

Fix all the remaining dtc 'unit_address_format' warnings except for the ones
related to 'register-bit-led'. For those, we need to decide on and document
the node name.

Signed-off-by: Rob Herring <robh at kernel.org>
---
Arnd, Olof,

Please apply this directly.

Rob

 arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts  |  2 +-
 arch/arm/boot/dts/at91-sama5d27_som1.dtsi     | 12 ++++----
 arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts     |  4 +--
 arch/arm/boot/dts/at91-sama5d2_xplained.dts   | 14 +++++-----
 arch/arm/boot/dts/dm8148-evm.dts              |  8 +++---
 arch/arm/boot/dts/dm8168-evm.dts              |  8 +++---
 arch/arm/boot/dts/integratorap-im-pd1.dts     |  4 +--
 arch/arm/boot/dts/keystone-k2e-netcp.dtsi     |  2 +-
 arch/arm/boot/dts/keystone-k2hk-netcp.dtsi    |  2 +-
 arch/arm/boot/dts/keystone-k2l-netcp.dtsi     |  2 +-
 arch/arm/boot/dts/nuvoton-npcm750-evb.dts     |  4 +--
 arch/arm/boot/dts/qcom-apq8064.dtsi           | 24 ++++++++--------
 arch/arm/boot/dts/qcom-sdx55.dtsi             |  2 +-
 arch/arm/boot/dts/ste-ab8500.dtsi             | 28 +++++++++----------
 arch/arm/boot/dts/ste-ab8505.dtsi             | 24 ++++++++--------
 arch/arm/boot/dts/ste-db8500.dtsi             |  6 ++--
 arch/arm/boot/dts/ste-db8520.dtsi             |  6 ++--
 .../arm/boot/dts/ste-ux500-samsung-janice.dts |  2 +-
 arch/arm/boot/dts/stm32429i-eval.dts          |  2 +-
 arch/arm/boot/dts/stm32f469-disco.dts         |  2 +-
 .../marvell/armada-8040-clearfog-gt-8k.dts    |  2 +-
 arch/arm64/boot/dts/marvell/cn9130-db.dts     |  2 +-
 arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  2 +-
 23 files changed, 82 insertions(+), 82 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
index d26a9e16ff7c..97cc217fb099 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
@@ -303,7 +303,7 @@ gpio at 0 {
 			type = <PCA955X_TYPE_GPIO>;
 		};
 
-		gpio at 01 {
+		gpio at 1 {
 			reg = <1>;
 			type = <PCA955X_TYPE_GPIO>;
 		};
diff --git a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi
index e3251f3e3eaa..b48ac3b62a31 100644
--- a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi
+++ b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi
@@ -47,32 +47,32 @@ flash at 0 {
 					spi-rx-bus-width = <4>;
 					m25p,fast-read;
 
-					at91bootstrap at 00000000 {
+					at91bootstrap at 0 {
 						label = "at91bootstrap";
 						reg = <0x00000000 0x00040000>;
 					};
 
-					bootloader at 00040000 {
+					bootloader at 40000 {
 						label = "bootloader";
 						reg = <0x00040000 0x000c0000>;
 					};
 
-					bootloaderenvred at 00100000 {
+					bootloaderenvred at 100000 {
 						label = "bootloader env redundant";
 						reg = <0x00100000 0x00040000>;
 					};
 
-					bootloaderenv at 00140000 {
+					bootloaderenv at 140000 {
 						label = "bootloader env";
 						reg = <0x00140000 0x00040000>;
 					};
 
-					dtb at 00180000 {
+					dtb at 180000 {
 						label = "device tree";
 						reg = <0x00180000 0x00080000>;
 					};
 
-					kernel at 00200000 {
+					kernel at 200000 {
 						label = "kernel";
 						reg = <0x00200000 0x00600000>;
 					};
diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
index dfd150eb0fd8..a5515b0dd346 100644
--- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
@@ -93,12 +93,12 @@ bootloader at 40000 {
 							reg = <0x40000 0xc0000>;
 						};
 
-						bootloaderenvred at 0x100000 {
+						bootloaderenvred at 100000 {
 							label = "bootloader env redundant";
 							reg = <0x100000 0x40000>;
 						};
 
-						bootloaderenv at 0x140000 {
+						bootloaderenv at 140000 {
 							label = "bootloader env";
 							reg = <0x140000 0x40000>;
 						};
diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
index 509c732a0d8b..908b2cc22844 100644
--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
@@ -95,37 +95,37 @@ flash at 0 {
 					spi-rx-bus-width = <4>;
 					m25p,fast-read;
 
-					at91bootstrap at 00000000 {
+					at91bootstrap at 0 {
 						label = "at91bootstrap";
 						reg = <0x00000000 0x00040000>;
 					};
 
-					bootloader at 00040000 {
+					bootloader at 40000 {
 						label = "bootloader";
 						reg = <0x00040000 0x000c0000>;
 					};
 
-					bootloaderenvred at 00100000 {
+					bootloaderenvred at 100000 {
 						label = "bootloader env redundant";
 						reg = <0x00100000 0x00040000>;
 					};
 
-					bootloaderenv at 00140000 {
+					bootloaderenv at 140000 {
 						label = "bootloader env";
 						reg = <0x00140000 0x00040000>;
 					};
 
-					dtb at 00180000 {
+					dtb at 180000 {
 						label = "device tree";
 						reg = <0x00180000 0x00080000>;
 					};
 
-					kernel at 00200000 {
+					kernel at 200000 {
 						label = "kernel";
 						reg = <0x00200000 0x00600000>;
 					};
 
-					misc at 00800000 {
+					misc at 800000 {
 						label = "misc";
 						reg = <0x00800000 0x00000000>;
 					};
diff --git a/arch/arm/boot/dts/dm8148-evm.dts b/arch/arm/boot/dts/dm8148-evm.dts
index 91d1018ab75f..8ef48c00f98d 100644
--- a/arch/arm/boot/dts/dm8148-evm.dts
+++ b/arch/arm/boot/dts/dm8148-evm.dts
@@ -80,19 +80,19 @@ partition at 0 {
 			label = "X-Loader";
 			reg = <0 0x80000>;
 		};
-		partition at 0x80000 {
+		partition at 80000 {
 			label = "U-Boot";
 			reg = <0x80000 0x1c0000>;
 		};
-		partition at 0x1c0000 {
+		partition at 1c0000 {
 			label = "Environment";
 			reg = <0x240000 0x40000>;
 		};
-		partition at 0x280000 {
+		partition at 280000 {
 			label = "Kernel";
 			reg = <0x280000 0x500000>;
 		};
-		partition at 0x780000 {
+		partition at 780000 {
 			label = "Filesystem";
 			reg = <0x780000 0xf880000>;
 		};
diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts
index cf05d532db65..5126e2d72ed7 100644
--- a/arch/arm/boot/dts/dm8168-evm.dts
+++ b/arch/arm/boot/dts/dm8168-evm.dts
@@ -154,19 +154,19 @@ partition at 0 {
 			label = "X-Loader";
 			reg = <0 0x80000>;
 		};
-		partition at 0x80000 {
+		partition at 80000 {
 			label = "U-Boot";
 			reg = <0x80000 0x1c0000>;
 		};
-		partition at 0x1c0000 {
+		partition at 1c0000 {
 			label = "Environment";
 			reg = <0x240000 0x40000>;
 		};
-		partition at 0x280000 {
+		partition at 280000 {
 			label = "Kernel";
 			reg = <0x280000 0x500000>;
 		};
-		partition at 0x780000 {
+		partition at 780000 {
 			label = "Filesystem";
 			reg = <0x780000 0xf880000>;
 		};
diff --git a/arch/arm/boot/dts/integratorap-im-pd1.dts b/arch/arm/boot/dts/integratorap-im-pd1.dts
index 1412a1a968fc..f4c0f3d3ab3a 100644
--- a/arch/arm/boot/dts/integratorap-im-pd1.dts
+++ b/arch/arm/boot/dts/integratorap-im-pd1.dts
@@ -29,7 +29,7 @@ syscon at 0 {
 		compatible = "arm,im-pd1-syscon", "syscon";
 		reg = <0x00000000 0x1000>;
 
-		vco1: clock at 00 {
+		vco1-clock {
 			compatible = "arm,impd1-vco1";
 			#clock-cells = <0>;
 			lock-offset = <0x08>;
@@ -38,7 +38,7 @@ vco1: clock at 00 {
 			clock-output-names = "IM-PD1-VCO1";
 		};
 
-		vco2: clock at 04 {
+		vco2-clock {
 			compatible = "arm,impd1-vco2";
 			#clock-cells = <0>;
 			lock-offset = <0x08>;
diff --git a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
index ad15e77874b1..71064483d34f 100644
--- a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
+++ b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
@@ -95,7 +95,7 @@ pdsps {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		pdsp0 at 0x2a10000 {
+		pdsp0 at 2a10000 {
 			reg = <0x2a10000 0x1000    /*iram */
 			       0x2a0f000 0x100     /*reg*/
 			       0x2a0c000 0x3c8	   /*intd */
diff --git a/arch/arm/boot/dts/keystone-k2hk-netcp.dtsi b/arch/arm/boot/dts/keystone-k2hk-netcp.dtsi
index d5a6c1f5633c..022d93c366c7 100644
--- a/arch/arm/boot/dts/keystone-k2hk-netcp.dtsi
+++ b/arch/arm/boot/dts/keystone-k2hk-netcp.dtsi
@@ -112,7 +112,7 @@ pdsps {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		pdsp0 at 0x2a10000 {
+		pdsp0 at 2a10000 {
 			reg = <0x2a10000 0x1000    /*iram */
 			       0x2a0f000 0x100     /*reg*/
 			       0x2a0c000 0x3c8	   /*intd */
diff --git a/arch/arm/boot/dts/keystone-k2l-netcp.dtsi b/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
index c1f982604145..e96ca664abc2 100644
--- a/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
+++ b/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
@@ -94,7 +94,7 @@ pdsps {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		pdsp0 at 0x2a10000 {
+		pdsp0 at 2a10000 {
 			reg = <0x2a10000 0x1000    /*iram */
 			       0x2a0f000 0x100     /*reg*/
 			       0x2a0c000 0x3c8	   /*intd */
diff --git a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
index dea3dbc4a6a5..0334641f8829 100644
--- a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
+++ b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
@@ -105,11 +105,11 @@ rootfs at 600000 {
 				label = "rootfs";
 				reg = <0x0600000 0x700000>;
 				};
-			spare1 at D00000 {
+			spare1 at d00000 {
 				label = "spare1";
 				reg = <0x0D00000 0x200000>;
 				};
-			spare2 at 0F00000 {
+			spare2 at f00000 {
 				label = "spare2";
 				reg = <0x0F00000 0x200000>;
 				};
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 2687c4e890ba..8294ad1548fc 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -766,40 +766,40 @@ xoadc: xoadc at 197 {
 					#size-cells = <0>;
 					#io-channel-cells = <2>;
 
-					vcoin: adc-channel at 00 {
+					vcoin: adc-channel at 0 {
 						reg = <0x00 0x00>;
 					};
-					vbat: adc-channel at 01 {
+					vbat: adc-channel at 1 {
 						reg = <0x00 0x01>;
 					};
-					dcin: adc-channel at 02 {
+					dcin: adc-channel at 2 {
 						reg = <0x00 0x02>;
 					};
-					vph_pwr: adc-channel at 04 {
+					vph_pwr: adc-channel at 4 {
 						reg = <0x00 0x04>;
 					};
-					batt_therm: adc-channel at 08 {
+					batt_therm: adc-channel at 8 {
 						reg = <0x00 0x08>;
 					};
-					batt_id: adc-channel at 09 {
+					batt_id: adc-channel at 9 {
 						reg = <0x00 0x09>;
 					};
-					usb_vbus: adc-channel at 0a {
+					usb_vbus: adc-channel at a {
 						reg = <0x00 0x0a>;
 					};
-					die_temp: adc-channel at 0b {
+					die_temp: adc-channel at b {
 						reg = <0x00 0x0b>;
 					};
-					ref_625mv: adc-channel at 0c {
+					ref_625mv: adc-channel at c {
 						reg = <0x00 0x0c>;
 					};
-					ref_1250mv: adc-channel at 0d {
+					ref_1250mv: adc-channel at d {
 						reg = <0x00 0x0d>;
 					};
-					chg_temp: adc-channel at 0e {
+					chg_temp: adc-channel at e {
 						reg = <0x00 0x0e>;
 					};
-					ref_muxoff: adc-channel at 0f {
+					ref_muxoff: adc-channel at f {
 						reg = <0x00 0x0f>;
 					};
 				};
diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi
index 0057c7c04d31..1e6ce035f76a 100644
--- a/arch/arm/boot/dts/qcom-sdx55.dtsi
+++ b/arch/arm/boot/dts/qcom-sdx55.dtsi
@@ -143,7 +143,7 @@ tz_mem: memory at 8ff00000 {
 			reg = <0x8ff00000 0x100000>;
 		};
 
-		tz_apps_mem: memory at 0x90000000 {
+		tz_apps_mem: memory at 90000000 {
 			no-map;
 			reg = <0x90000000 0x500000>;
 		};
diff --git a/arch/arm/boot/dts/ste-ab8500.dtsi b/arch/arm/boot/dts/ste-ab8500.dtsi
index d0fe3f9aa183..9b735919a4d1 100644
--- a/arch/arm/boot/dts/ste-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-ab8500.dtsi
@@ -58,46 +58,46 @@ gpadc: ab8500-gpadc {
 					#io-channel-cells = <1>;
 
 					/* GPADC channels */
-					bat_ctrl: channel at 01 {
+					bat_ctrl: channel at 1 {
 						reg = <0x01>;
 					};
-					btemp_ball: channel at 02 {
+					btemp_ball: channel at 2 {
 						reg = <0x02>;
 					};
-					main_charger_v: channel at 03 {
+					main_charger_v: channel at 3 {
 						reg = <0x03>;
 					};
-					acc_detect1: channel at 04 {
+					acc_detect1: channel at 4 {
 						reg = <0x04>;
 					};
-					acc_detect2: channel at 05 {
+					acc_detect2: channel at 5 {
 						reg = <0x05>;
 					};
-					adc_aux1: channel at 06 {
+					adc_aux1: channel at 6 {
 						reg = <0x06>;
 					};
-					adc_aux2: channel at 07 {
+					adc_aux2: channel at 7 {
 						reg = <0x07>;
 					};
-					main_batt_v: channel at 08 {
+					main_batt_v: channel at 8 {
 						reg = <0x08>;
 					};
-					vbus_v: channel at 09 {
+					vbus_v: channel at 9 {
 						reg = <0x09>;
 					};
-					main_charger_c: channel at 0a {
+					main_charger_c: channel at a {
 						reg = <0x0a>;
 					};
-					usb_charger_c: channel at 0b {
+					usb_charger_c: channel at b {
 						reg = <0x0b>;
 					};
-					bk_bat_v: channel at 0c {
+					bk_bat_v: channel at c {
 						reg = <0x0c>;
 					};
-					die_temp: channel at 0d {
+					die_temp: channel at d {
 						reg = <0x0d>;
 					};
-					usb_id: channel at 0e {
+					usb_id: channel at e {
 						reg = <0x0e>;
 					};
 					xtal_temp: channel at 12 {
diff --git a/arch/arm/boot/dts/ste-ab8505.dtsi b/arch/arm/boot/dts/ste-ab8505.dtsi
index 0defc15b9bbc..02ce833d142a 100644
--- a/arch/arm/boot/dts/ste-ab8505.dtsi
+++ b/arch/arm/boot/dts/ste-ab8505.dtsi
@@ -54,40 +54,40 @@ gpadc: ab8500-gpadc {
 					#io-channel-cells = <1>;
 
 					/* GPADC channels */
-					bat_ctrl: channel at 01 {
+					bat_ctrl: channel at 1 {
 						reg = <0x01>;
 					};
-					btemp_ball: channel at 02 {
+					btemp_ball: channel at 2 {
 						reg = <0x02>;
 					};
-					acc_detect1: channel at 04 {
+					acc_detect1: channel at 4 {
 						reg = <0x04>;
 					};
-					acc_detect2: channel at 05 {
+					acc_detect2: channel at 5 {
 						reg = <0x05>;
 					};
-					adc_aux1: channel at 06 {
+					adc_aux1: channel at 6 {
 						reg = <0x06>;
 					};
-					adc_aux2: channel at 07 {
+					adc_aux2: channel at 7 {
 						reg = <0x07>;
 					};
-					main_batt_v: channel at 08 {
+					main_batt_v: channel at 8 {
 						reg = <0x08>;
 					};
-					vbus_v: channel at 09 {
+					vbus_v: channel at 9 {
 						reg = <0x09>;
 					};
-					charger_c: channel at 0b {
+					charger_c: channel at b {
 						reg = <0x0b>;
 					};
-					bk_bat_v: channel at 0c {
+					bk_bat_v: channel at c {
 						reg = <0x0c>;
 					};
-					die_temp: channel at 0d {
+					die_temp: channel at d {
 						reg = <0x0d>;
 					};
-					usb_id: channel at 0e {
+					usb_id: channel at e {
 						reg = <0x0e>;
 					};
 				};
diff --git a/arch/arm/boot/dts/ste-db8500.dtsi b/arch/arm/boot/dts/ste-db8500.dtsi
index 344d29853bf7..b67d3bd65de8 100644
--- a/arch/arm/boot/dts/ste-db8500.dtsi
+++ b/arch/arm/boot/dts/ste-db8500.dtsi
@@ -19,19 +19,19 @@ reserved-memory {
 		ranges;
 
 		/* Modem trace memory */
-		ram at 06000000 {
+		ram at 6000000 {
 			reg = <0x06000000 0x00f00000>;
 			no-map;
 		};
 
 		/* Modem shared memory */
-		ram at 06f00000 {
+		ram at 6f00000 {
 			reg = <0x06f00000 0x00100000>;
 			no-map;
 		};
 
 		/* Modem private memory */
-		ram at 07000000 {
+		ram at 7000000 {
 			reg = <0x07000000 0x01000000>;
 			no-map;
 		};
diff --git a/arch/arm/boot/dts/ste-db8520.dtsi b/arch/arm/boot/dts/ste-db8520.dtsi
index 287804e9e183..60d5fb806969 100644
--- a/arch/arm/boot/dts/ste-db8520.dtsi
+++ b/arch/arm/boot/dts/ste-db8520.dtsi
@@ -19,19 +19,19 @@ reserved-memory {
 		ranges;
 
 		/* Modem trace memory */
-		ram at 06000000 {
+		ram at 6000000 {
 			reg = <0x06000000 0x00f00000>;
 			no-map;
 		};
 
 		/* Modem shared memory */
-		ram at 06f00000 {
+		ram at 6f00000 {
 			reg = <0x06f00000 0x00100000>;
 			no-map;
 		};
 
 		/* Modem private memory */
-		ram at 07000000 {
+		ram at 7000000 {
 			reg = <0x07000000 0x01000000>;
 			no-map;
 		};
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
index 25af066f6f3a..aee8439b7e8f 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
@@ -580,7 +580,7 @@ i2c-gate {
 					#size-cells = <0>;
 
 					/* Bosch BMA222 accelerometer */
-					accelerometer at 08 {
+					accelerometer at 8 {
 						compatible = "bosch,bma222";
 						reg = <0x08>;
 						mount-matrix = "0", "1", "0",
diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index 9ac1ffe53413..cb46326a8c75 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -60,7 +60,7 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x2000000>;
 	};
diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
index 8c982ae79f43..30905ce672a0 100644
--- a/arch/arm/boot/dts/stm32f469-disco.dts
+++ b/arch/arm/boot/dts/stm32f469-disco.dts
@@ -60,7 +60,7 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x1000000>;
 	};
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
index 0ec0d5625818..8729c6467303 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
@@ -20,7 +20,7 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x80000000>;
 	};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dts b/arch/arm64/boot/dts/marvell/cn9130-db.dts
index 9758609541c7..47a3b97a0363 100644
--- a/arch/arm64/boot/dts/marvell/cn9130-db.dts
+++ b/arch/arm64/boot/dts/marvell/cn9130-db.dts
@@ -27,7 +27,7 @@ aliases {
 		spi2 = &cp0_spi1;
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x80000000>;
 	};
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 9fa5b028e4f3..23ee1bfa4318 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -151,7 +151,7 @@ reserved-memory {
 		#size-cells = <2>;
 		ranges;
 
-		rpm_msg_ram: memory at 0x60000 {
+		rpm_msg_ram: memory at 60000 {
 			reg = <0x0 0x60000 0x0 0x6000>;
 			no-map;
 		};
-- 
2.30.2



From catalin.marinas at arm.com  Fri Aug 20 09:57:52 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Aug 2021 17:57:52 +0100
Subject: [PATCH] kselftest/arm64: pac: Fix skipping of tests on systems
 without PAC
In-Reply-To: <20210819165723.43903-1-broonie@kernel.org>
References: <20210819165723.43903-1-broonie@kernel.org>
Message-ID: <162947866187.7115.13576102067532420865.b4-ty@arm.com>

On Thu, 19 Aug 2021 17:57:23 +0100, Mark Brown wrote:
> The PAC tests check to see if the system supports the relevant PAC features
> but instead of skipping the tests if they can't be executed they fail the
> tests which makes things look like they're not working when they are.

Applied to arm64 (for-next/kselftest), thanks!

[1/1] kselftest/arm64: pac: Fix skipping of tests on systems without PAC
      https://git.kernel.org/arm64/c/0c69bd2ca6ee

-- 
Catalin



From bjorn.andersson at linaro.org  Fri Aug 20 10:06:13 2021
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Fri, 20 Aug 2021 10:06:13 -0700
Subject: [PATCH v3 06/10] arm64: dts: qcom: sc7280: Update reserved
 memory map
In-Reply-To: <39da02506af192de14d346cdf80d0e4c@codeaurora.org>
References: <1629344185-27368-1-git-send-email-sibis@codeaurora.org>
 <1629344185-27368-7-git-send-email-sibis@codeaurora.org>
 <YR3gAD68xRtNJRhi@matsya>
 <39da02506af192de14d346cdf80d0e4c@codeaurora.org>
Message-ID: <YR/hBYyYuYWN68LV@ripper>

On Fri 20 Aug 07:09 PDT 2021, Sibi Sankar wrote:

> On 2021-08-19 10:07, Vinod Koul wrote:
> > Hi Sibi,
> > 
> > On 19-08-21, 09:06, Sibi Sankar wrote:
> > 
> > > diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi
> > > b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> > > index 5e4f4f3b738a..894106efadfe 100644
> > > --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
> > > +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
> > > @@ -48,6 +48,16 @@
> > >  		#size-cells = <2>;
> > >  		ranges;
> > > 
> > > +		hyp_mem: memory at 80000000 {
> > > +			reg = <0x0 0x80000000 0x0 0x600000>;
> > > +			no-map;
> > 
> > This should conflict with the memory defined in this file:
> > 
> >         memory at 80000000 {
> >                 device_type = "memory";
> >                 /* We expect the bootloader to fill in the size */
> >                 reg = <0 0x80000000 0 0>;
> >         };
> > 
> > I think this should be updated?
> 
> Vinod,
> 
> I prefer we leave ^^ node untouched.  For platforms using hyp_mem, the
> regions defined in the memory map are valid and for the other
> platforms not using hyp_mem we would just delete them in the board
> files anyway.

Logically this node describes where there is RAM, the reserved-memory
then subtracts blocks of memory out of that. So I think it's perfectly
legal for a region at the base to be marked as no-map.

That said, isn't the address in the memory node just a placeholder?

Regards,
Bjorn


From pali at kernel.org  Fri Aug 20 10:22:38 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 20 Aug 2021 19:22:38 +0200
Subject: [PATCH v5 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <20210809145329.24177-1-pali@kernel.org>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210809145329.24177-1-pali@kernel.org>
Message-ID: <20210820172238.ekvo42s7oqxkeomt@pali>

On Monday 09 August 2021 16:53:23 Pali Roh?r wrote:
> This patch series add support for baudrates higher than 230400 on
> Marvell Armada 37xx boards.
> 
> Please review these patches as they touch both Device Tree bindings and
> mvebu-uart.c driver.

Stephen, is this patch series OK now? Or is there any other issue?

> Changes in v5:
> * fixed yaml binding file
> 
> Changes in v4:
> * converted armada3700-uart-clock documentation to YAML
> * split documentation changes into two commits:
>   - first which adds clock documentation
>   - second which updates UART documentation
> 
> Changes in v3:
> v3 is rebased on top of Linus master branch and all already applied patches
> were dropped. There are no changes in patches itself since v2.
> 
> Pali Roh?r (6):
>   math64: New DIV_U64_ROUND_CLOSEST helper
>   serial: mvebu-uart: implement UART clock driver for configuring UART
>     base clock
>   dt-bindings: mvebu-uart: document DT bindings for
>     marvell,armada-3700-uart-clock
>   dt-bindings: mvebu-uart: update information about UART clock
>   arm64: dts: marvell: armada-37xx: add device node for UART clock and
>     use it
>   serial: mvebu-uart: implement support for baudrates higher than 230400
> 
>  .../bindings/clock/armada3700-uart-clock.yaml |  57 ++
>  .../devicetree/bindings/serial/mvebu-uart.txt |   9 +-
>  .../arm64/boot/dts/marvell/armada-3720-db.dts |   4 +
>  .../dts/marvell/armada-3720-espressobin.dtsi  |   4 +
>  .../dts/marvell/armada-3720-turris-mox.dts    |   4 +
>  .../boot/dts/marvell/armada-3720-uDPU.dts     |   4 +
>  arch/arm64/boot/dts/marvell/armada-37xx.dtsi  |  15 +-
>  drivers/tty/serial/Kconfig                    |   1 +
>  drivers/tty/serial/mvebu-uart.c               | 592 +++++++++++++++++-
>  include/linux/math64.h                        |  13 +
>  10 files changed, 682 insertions(+), 21 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> 
> -- 
> 2.20.1
> 


From nm at ti.com  Fri Aug 20 10:30:32 2021
From: nm at ti.com (Nishanth Menon)
Date: Fri, 20 Aug 2021 12:30:32 -0500
Subject: [PATCH 0/2] ARM: dts: keystone-k2*-evm: Fix mdio and dss node
 status
In-Reply-To: <20210820095341.5619-1-rogerq@kernel.org>
References: <20210820095341.5619-1-rogerq@kernel.org>
Message-ID: <20210820173032.45st33x5435tmfyx@fragrance>

On 12:53-20210820, Roger Quadros wrote:
> Hi Santosh,
> 
> This series fixes mdio and dss status nodes from "ok" to "okay"
> 
> As per Device Tree core schema [1], status parameter of nodes can be either
> "okay" or "disabled".
> 
> U-boot Driver Model does not recognize status="ok" either and treats
> the node as disabled.
> 
> [1] https://github.com/devicetree-org/dt-schema/blob/master/schemas/dt-core.yaml#L36


Wondering if it is better to refer to the device tree specification
itself rather than the schema implementation of the specification..


https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3
for example.

> 
> cheers,
> -roger
> 
> Roger Quadros (2):
>   ARM: dts: keystone-k2*-evm: Fix mdio node status to "okay"
>   ARM: dts: keystone-k2g-evm: Fix dss node status to "okay"
> 
>  arch/arm/boot/dts/keystone-k2e-evm.dts  | 2 +-
>  arch/arm/boot/dts/keystone-k2g-evm.dts  | 2 +-
>  arch/arm/boot/dts/keystone-k2hk-evm.dts | 2 +-
>  arch/arm/boot/dts/keystone-k2l-evm.dts  | 2 +-
>  4 files changed, 4 insertions(+), 4 deletions(-)
> 
> -- 
> 2.17.1
> 

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From robin.murphy at arm.com  Fri Aug 20 10:48:07 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 20 Aug 2021 18:48:07 +0100
Subject: arm32 insecure W+X mapping
In-Reply-To: <CAJ+vNU1sh9C=vi1TjHtXAY1F=UNY4cSGrc2vkGujW9pQUPeDDg@mail.gmail.com>
References: <CAJ+vNU0PaPNHbJc5RXgrRYJw2aWowrGVMOrU1=hKhsCTXAB=DA@mail.gmail.com>
 <20210819212819.GM22278@shell.armlinux.org.uk>
 <CAJ+vNU05L1Fyvy1R6_HwpLeo92LSJhDY4BCr-0aqM7rYgh6TVQ@mail.gmail.com>
 <20210820001646.GN22278@shell.armlinux.org.uk>
 <CAJ+vNU1sh9C=vi1TjHtXAY1F=UNY4cSGrc2vkGujW9pQUPeDDg@mail.gmail.com>
Message-ID: <381afc78-5a7f-8286-76ea-2e6c7867972d@arm.com>

On 2021-08-20 17:06, Tim Harvey wrote:
> On Thu, Aug 19, 2021 at 5:16 PM Russell King (Oracle)
> <linux at armlinux.org.uk> wrote:
>>
>> On Thu, Aug 19, 2021 at 04:59:15PM -0700, Tim Harvey wrote:
>>> On Thu, Aug 19, 2021 at 2:28 PM Russell King (Oracle)
>>> <linux at armlinux.org.uk> wrote:
>>>>
>>>> On Thu, Aug 19, 2021 at 10:19:46AM -0700, Tim Harvey wrote:
>>>>> Greetings,
>>>>>
>>>>> Since commit a8e53c151fe7 "(ARM: 8737/1: mm: dump: add checking for
>>>>> writable and executable)" I've been seeing the following appear on my
>>>>> arm32 kernel:
>>>>>
>>>>> arm/mm: Found insecure W+X mapping at address 0xf087d000
>>>>> ...
>>>>> Checked W+X mappings: FAILED, 1 W+X pages found
>>>>>
>>>>> As I haven't seen others report this I assume it's something unique to
>>>>> my kernel configuration. How do I debug what is causing the insecure
>>>>> page?
>>>>
>>>> If you check /proc/vmallocinfo, it should tell you the physical
>>>> address that was mapped there, and the function that created the
>>>> mapping. That should give enough clues to track it down.
>>>>
>>>
>>> Russell,
>>>
>>> Thanks for the tip!
>>>
>>> # dmesg | grep insecure
>>> [   13.219582] arm/mm: Found insecure W+X mapping at address 0xf087d000
>>> # cat /proc/vmallocinfo | grep 0xf0
>>> 0x5f3045dd-0xf0020e05   20480 imx6_pm_get_base+0x64/0x98 phys=0x020e0000 ioremap
>>> 0xf0020e05-0x6e748217    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
>>> 0x127639d7-0x334ee291    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap
>>
>> Oh... the kernel's %p pointer munging (for security reasons) is
>> affecting your ability to debug your problem. Assuming this is a
>> recent kernel, you can disable this by passing "no_hash_pointers"
>> on the kernel command line. You should then see real addresses (and
>> a big fat message at boot time about it.
>>
> 
> I'm using 5.13 and when I pass in 'no_hash_pointers' I do indeed see
> the huge warning but I get similar results that I can't make sense of:

Pointer hashing always trips me up too, so I thought I'd chuck my 
curiosity into the ring...

Between the vmallocinfo and printk code, it looks like you need to set 
/proc/sys/kptr_restrict to 1 and be root (or have CAP_SYSLOG privilege) 
to get non-hashed addresses here. Because having only one way to confuse 
debugging would be far too easy, I guess :/

Robin.

> # uname -r
> 5.13.0-00009-g8beacec9a060
> # cat /proc/cmdline
> console=ttymxc1,115200 no_hash_pointers
> # dmesg | grep insecure
> [   13.309537] arm/mm: Found insecure W+X mapping at address 0xf087d000
> # cat /proc/vmallocinfo | grep 0xf0
> 0xf02c73a9-0xfa933595   20480 __devm_ioremap+0x94/0xa4 phys=0x0202c000 ioremap
> 0xc02cb795-0x054951d9    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap
> # cat /proc/vmallocinfo
> 0xbe008562-0x5576ab44   20480 of_iomap+0x44/0x68 phys=0x020d8000 ioremap
> 0x5576ab44-0xb255df29    8192 of_iomap+0x44/0x68 phys=0x00a01000 ioremap
> 0x46b8335b-0x447c6b02   20480 of_iomap+0x44/0x68 phys=0x020dc000 ioremap
> 0x447c6b02-0x7527802c    8192 l2x0_of_init+0x78/0x26c phys=0x00a02000 ioremap
> 0xee30b5de-0x9e0d6dbd   20480 of_iomap+0x44/0x68 phys=0x020c4000 ioremap
> 0x9e0d6dbd-0xf62147bb    8192 of_iomap+0x44/0x68 phys=0x020c8000 ioremap
> 0xfe3688a4-0xecfce701   20480 of_iomap+0x44/0x68 phys=0x020c4000 ioremap
> 0x0d7d7401-0xce35bdb8   20480 of_iomap+0x44/0x68 phys=0x02098000 ioremap
> 0xd0da9915-0xa147e0b3    8192 bpf_prog_alloc_no_stats+0x2c/0x118 pages=1 vmalloc
> 0xa147e0b3-0xb043f532  266240 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0xb043f532-0x7f372e98    8192 gen_pool_add_owner+0x34/0x94 pages=1 vmalloc
> 0x7f372e98-0x22c0f7fa    8192 of_syscon_register+0xb8/0x2a0
> phys=0x020c8000 ioremap
> 0x22c0f7fa-0xbc80b65b    8192 __devm_ioremap+0x94/0xa4 phys=0x020c9000 ioremap
> 0xbc80b65b-0x5737939a    8192 __devm_ioremap+0x94/0xa4 phys=0x020ca000 ioremap
> 0x5737939a-0xfaac3f4b    8192 gen_pool_add_owner+0x34/0x94 pages=1 vmalloc
> 0xfaac3f4b-0x3400434f   20480 of_iomap+0x44/0x68 phys=0x021b0000 ioremap
> 0x3400434f-0x4b5b39be    8192 imx6_pm_common_init+0x118/0x36c
> phys=0x00900000 ioremap
> 0xfa6109c5-0x8220d86a  266240 __devm_ioremap+0x50/0xa4 phys=0x00900000 ioremap
> 0x8220d86a-0xbb32fa78    8192 imx6_pm_get_base+0x64/0x98 phys=0x00a02000 ioremap
> 0xe37ddad7-0x94023f64   20480 imx6_pm_get_base+0x64/0x98 phys=0x021b0000 ioremap
> 0x94023f64-0x032e50a3    8192 of_syscon_register+0xb8/0x2a0
> phys=0x020e0000 ioremap
> 0xd41722d0-0x69a3231e   20480 imx6_pm_get_base+0x64/0x98 phys=0x020d8000 ioremap
> 0x69a3231e-0x6dc29018    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x327a8342-0x78efb8e0   20480 imx6_pm_get_base+0x64/0x98 phys=0x020e0000 ioremap
> 0x78efb8e0-0xe6178284    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x76f38a9b-0x34af82ac   20480 imx6_pm_get_base+0x64/0x98 phys=0x020dc000 ioremap
> 0x34af82ac-0x81d03489    8192 __devm_ioremap+0x94/0xa4 phys=0x02600000 ioremap
> 0x63fe0abd-0x6b04db7d   20480 __devm_ioremap+0x94/0xa4 phys=0x020e0000 ioremap
> 0xb849bd1c-0xc46ae71e   20480 __devm_ioremap+0x94/0xa4 phys=0x0209c000 ioremap
> 0xc46ae71e-0x1eb811b8    8192 __devm_ioremap+0x94/0xa4 phys=0x02608000 ioremap
> 0x2c687987-0xbae166ed   20480 __devm_ioremap+0x94/0xa4 phys=0x020a0000 ioremap
> 0xbae166ed-0xb27fac72    8192 __devm_ioremap+0x94/0xa4 phys=0x02630000 ioremap
> 0x0868e824-0xa08b93b8   20480 __devm_ioremap+0x94/0xa4 phys=0x020a4000 ioremap
> 0xa08b93b8-0x73e79d37    8192 __devm_ioremap+0x94/0xa4 phys=0x02638000 ioremap
> 0x3ff71a53-0x1664550e   20480 __devm_ioremap+0x94/0xa4 phys=0x020a8000 ioremap
> 0x1664550e-0xdffb9edc    8192 __devm_ioremap+0x94/0xa4 phys=0x02620000 ioremap
> 0x1d0f2f08-0xb32e296b   20480 __devm_ioremap+0x94/0xa4 phys=0x020ac000 ioremap
> 0xb32e296b-0x7062006c    8192 __devm_ioremap+0x94/0xa4 phys=0x02668000 ioremap
> 0xff2f5a70-0xff7ff60a   20480 __devm_ioremap+0x94/0xa4 phys=0x020b0000 ioremap
> 0xff7ff60a-0x8779d9bc    8192 __devm_ioremap+0x94/0xa4 phys=0x02640000 ioremap
> 0xccc5d4a4-0xbbd8184e   20480 __devm_ioremap+0x94/0xa4 phys=0x020b4000 ioremap
> 0xf3211f15-0xdf4e4390   12288 __devm_ioremap+0x94/0xa4 phys=0x00110000 ioremap
> 0xdf4e4390-0x8b969f88    8192 __devm_ioremap+0x94/0xa4 phys=0x02648000 ioremap
> 0x67d4c705-0x2844e8ae   20480 __devm_ioremap+0x94/0xa4 phys=0x021a0000 ioremap
> 0x2844e8ae-0xe969daac    8192 __devm_ioremap+0x94/0xa4 phys=0x02658000 ioremap
> 0x6c51de7f-0x13285901   20480 __devm_ioremap+0x94/0xa4 phys=0x021a4000 ioremap
> 0x13285901-0xcf2d44dd    8192 __devm_ioremap+0x94/0xa4 phys=0x02780000 ioremap
> 0x632c016d-0x81fc4149   20480 __devm_ioremap+0x94/0xa4 phys=0x021a8000 ioremap
> 0x81fc4149-0xd005970a    8192 __devm_ioremap+0x94/0xa4 phys=0x02660000 ioremap
> 0xacd62b34-0x2369ad7d   20480 __devm_ioremap+0x94/0xa4 phys=0x021d8000 ioremap
> 0x2369ad7d-0x6c218545    8192 __devm_ioremap+0x94/0xa4 phys=0x02740000 ioremap
> 0xd8caee3b-0x8f7b3eae   20480 __devm_ioremap+0x94/0xa4 phys=0x01ffc000 ioremap
> 0x8f7b3eae-0x7754f3e6    8192 __devm_ioremap+0x94/0xa4 phys=0x02650000 ioremap
> 0xcf739a9c-0x86505b25   20480 __devm_ioremap+0x94/0xa4 phys=0x020ec000 ioremap
> 0x86505b25-0x4419339d    8192 __devm_ioremap+0x94/0xa4 phys=0x02a00000 ioremap
> 0x38550150-0xee5ad30c   20480 of_syscon_register+0xb8/0x2a0
> phys=0x021bc000 ioremap
> 0xee5ad30c-0x73467058    8192 __devm_ioremap+0x94/0xa4 phys=0x02a08000 ioremap
> 0x7659aedb-0xd37bf098   20480 __devm_ioremap+0x94/0xa4 phys=0x020dc000 ioremap
> 0xd37bf098-0x6b62199d    8192 __devm_ioremap+0x94/0xa4 phys=0x02a30000 ioremap
> 0xe2fcb2be-0x83ac2ff4   20480 __devm_ioremap+0x94/0xa4 phys=0x02020000 ioremap
> 0x83ac2ff4-0x498e66da    8192 __devm_ioremap+0x94/0xa4 phys=0x02a38000 ioremap
> 0xda200768-0x9519b5b7   20480 __devm_ioremap+0x94/0xa4 phys=0x021e8000 ioremap
> 0x9519b5b7-0xd8066315    8192 __devm_ioremap+0x94/0xa4 phys=0x02a20000 ioremap
> 0x327c6cd3-0xb09836e5   20480 __devm_ioremap+0x94/0xa4 phys=0x021f4000 ioremap
> 0xb09836e5-0x2ee61e13    8192 __devm_ioremap+0x94/0xa4 phys=0x02a68000 ioremap
> 0x28a28e71-0xfb74b75d   40960 __devm_ioremap+0x94/0xa4 phys=0x00120000 ioremap
> 0xfb74b75d-0x94731aa5    8192 __devm_ioremap+0x94/0xa4 phys=0x02a40000 ioremap
> 0x94731aa5-0x9ed95f4b   20480 __devm_ioremap+0x94/0xa4 phys=0x00130000 ioremap
> 0x9ed95f4b-0xb6679e93    8192 __devm_ioremap+0x94/0xa4 phys=0x02a48000 ioremap
> 0xd2083a49-0xd15b1ee5   20480 __devm_ioremap+0x94/0xa4 phys=0x00134000 ioremap
> 0xd15b1ee5-0xb873e80d    8192 __devm_ioremap+0x94/0xa4 phys=0x02a58000 ioremap
> 0xb873e80d-0xad853c5f    8192 __devm_ioremap+0x94/0xa4 phys=0x02b80000 ioremap
> 0xad853c5f-0x727a169b    8192 __devm_ioremap+0x94/0xa4 phys=0x02a60000 ioremap
> 0x79bcf223-0xd8778c7f  528384 devm_pci_remap_cfgspace+0x3c/0x74
> phys=0x01f00000 ioremap
> 0xd8778c7f-0xcd8f995b  135168 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0xcd8f995b-0x0e93c50d    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x0e93c50d-0x35d018fd   20480 __devm_ioremap+0x94/0xa4 phys=0x02204000 ioremap
> 0x35d018fd-0x30dd9119  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x30dd9119-0x1d49a1b3    8192 __devm_ioremap+0x94/0xa4 phys=0x02b40000 ioremap
> 0x1d49a1b3-0xe202a461    8192 __devm_ioremap+0x94/0xa4 phys=0x02a50000 ioremap
> 0x3c5f9898-0x7c998da8  135168 __devm_ioremap+0x94/0xa4 phys=0x02700000 ioremap
> 0x0be6bff2-0xe617431b   12288 __devm_ioremap+0x94/0xa4 phys=0x00112000 ioremap
> 0xe617431b-0x1894871f    8192 __pci_enable_msix_range+0x1b4/0x50c
> phys=0x01420000 ioremap
> 0xcc3e24ea-0x24fc33d0   69632 __devm_ioremap+0x94/0xa4 phys=0x02760000 ioremap
> 0x24fc33d0-0x2ad2fe2c   81920 pcpu_create_chunk+0x14c/0x290 pages=19 vmalloc
> 0x064e8962-0x041a1631    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
> 0x041a1631-0xa78f78b0  135168 __devm_ioremap+0x94/0xa4 phys=0x02b00000 ioremap
> 0x482eea6f-0xa04223bd   12288 __devm_ioremap+0x94/0xa4 phys=0x00114000 ioremap
> 0xa04223bd-0x47cd64d8    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
> 0x496ff4b8-0x1b8cd27f   69632 __devm_ioremap+0x94/0xa4 phys=0x02b60000 ioremap
> 0x1b8cd27f-0x9a03a792 1576960 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x9e844161-0x46bbc5c3    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x46bbc5c3-0x061f37bb   20480 __devm_ioremap+0x94/0xa4 phys=0x02200000 ioremap
> 0x061f37bb-0x099e44f8   98304 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x099e44f8-0x5a73428f   36864 iscsi_target_init_module+0xb4/0x234
> pages=8 vmalloc
> 0x5a73428f-0x6b24094e   20480 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x8763af88-0xc279660f   20480 __devm_ioremap+0x94/0xa4 phys=0x0200c000 ioremap
> 0xc279660f-0x0746510e    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0xc42e58a5-0x9bb92a15   20480 __devm_ioremap+0x94/0xa4 phys=0x02188000 ioremap
> 0x9bb92a15-0xbffbc968  135168 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0xbffbc968-0xc3135661   36864 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x7f8906cc-0x57602490   20480 __devm_ioremap+0x94/0xa4 phys=0x021e4000 ioremap
> 0x57602490-0x32a0cd25    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x32a0cd25-0xccf592e4    8192 __devm_ioremap+0x94/0xa4 phys=0x02184000 ioremap
> 0xccf592e4-0xc3d5117e    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0xd80eccd6-0x1eccdd8b  135168 igb_probe+0x150/0x10a4 phys=0x01400000 ioremap
> 0x1eccdd8b-0x360f1603    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x32fecfc9-0x71e47aa2   20480 __devm_ioremap+0x94/0xa4 phys=0x020c0000 ioremap
> 0x71e47aa2-0x5098c2fb    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0xaf379216-0x24330e7c   20480 __devm_ioremap+0x94/0xa4 phys=0x02198000 ioremap
> 0x3dd54ba7-0x2392a17a   20480 __devm_ioremap+0x94/0xa4 phys=0x02034000 ioremap
> 0x2392a17a-0x1e11712d   16384 n_tty_open+0x10/0x9c pages=3 vmalloc
> 0x300b1fb4-0x33dba900   20480 __devm_ioremap+0x94/0xa4 phys=0x02028000 ioremap
> 0xf02c73a9-0xfa933595   20480 __devm_ioremap+0x94/0xa4 phys=0x0202c000 ioremap
> 0xbe5c4daa-0x6af5bd9c  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x6af5bd9c-0x9ea7250e  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0x9ea7250e-0x74bbeefe 1294336 zstd_comp_init+0x58/0xb0 pages=315 vmalloc
> 0x74bbeefe-0x591c7299  163840 zstd_decomp_init+0x14/0x54 pages=39 vmalloc
> 0x591c7299-0x27154f89  274432 deflate_comp_init+0x20/0x90 pages=66 vmalloc
> 0x27154f89-0x3978b460   49152 deflate_decomp_init+0x14/0x58 pages=11 vmalloc
> 0x3978b460-0x99da8daa  212992 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0xe9a5ec5f-0xb0e53888  249856 __devm_ioremap+0x94/0xa4 phys=0x02040000 ioremap
> 0xb0e53888-0xc24dd16d  528384 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> 0xc02cb795-0x054951d9    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap
> 0x32815c21-0x48bd192d 2097152 pci_reserve_io+0x0/0x30 ioremap
> 0xba73986b-0x4f91845f  311296 pcpu_get_vm_areas+0x0/0x10c0 vmalloc
> 0x4f91845f-0x86cbfbfa  311296 pcpu_get_vm_areas+0x0/0x10c0 vmalloc
> 0x17d9341e-0xbe008562   16384 unpurged vm_area
> 0xecfce701-0xd35ab9b8    8192 unpurged vm_area
> 0xce35bdb8-0xd0da9915    8192 unpurged vm_area
> 0x6b04db7d-0xb849bd1c 15609856 unpurged vm_area
> 0xe202a461-0x3c5f9898   73728 unpurged vm_area
> 0x7c998da8-0x0be6bff2   36864 unpurged vm_area
> 0x2ad2fe2c-0x064e8962   36864 unpurged vm_area
> 0xa78f78b0-0x482eea6f   36864 unpurged vm_area
> 0x9a03a792-0x9e844161  442368 unpurged vm_area
> 0x92d57223-0xd09758da  249856 unpurged vm_area
> 0xfa933595-0xbe5c4daa   36864 unpurged vm_area
> 
> Thanks for your help!
> 
> Tim
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From nm at ti.com  Fri Aug 20 10:49:17 2021
From: nm at ti.com (Nishanth Menon)
Date: Fri, 20 Aug 2021 12:49:17 -0500
Subject: [PATCH linux-next] clk/keystone: fix application of sizeof to
 pointer
In-Reply-To: <84a6ba16686347099a3dab2e5161a930e792eb6e.1629198281.git.jing.yangyang@zte.com.cn>
References: <84a6ba16686347099a3dab2e5161a930e792eb6e.1629198281.git.jing.yangyang@zte.com.cn>
Message-ID: <20210820174917.4emwkb75i2yydm7c@expel>

On 19:20-20210819, jing yangyang wrote:
> sizeof when applied to a pointer typed expression gives the size of
> the pointer.
> 
> ./drivers/clk/keystone/sci-clk.c:398:8-14: ERROR application of sizeof to pointer
> 
> This issue was detected with the help of Coccinelle.
> 
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
> ---
>  drivers/clk/keystone/sci-clk.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
> index 7e1b136..010a61a 100644
> --- a/drivers/clk/keystone/sci-clk.c
> +++ b/drivers/clk/keystone/sci-clk.c
> @@ -395,7 +395,7 @@ static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
>  	key.clk_id = clkspec->args[1];
>  
>  	clk = bsearch(&key, provider->clocks, provider->num_clocks,
> -		      sizeof(clk), _cmp_sci_clk);
> +		      sizeof(*clk), _cmp_sci_clk);

I am trying to understand this.. bsearch uses base + size to do
iteration, provider is sci_clk_provider ->num_clocks is struct sci_clk
** same as clk. iteration is done on provider->clocks .. not on *clk,
am I missing something? or is it one of those testing patches?

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From catalin.marinas at arm.com  Fri Aug 20 10:49:47 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Aug 2021 18:49:47 +0100
Subject: [PATCH v6 4/8] arm64: PCI: Support root bridge preparation for
 Hyper-V
In-Reply-To: <YR6DIkdkblL8NUP2@boqun-archlinux>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-5-boqun.feng@gmail.com>
 <YR6DIkdkblL8NUP2@boqun-archlinux>
Message-ID: <20210820174947.GB23080@arm.com>

Hi Boqun,

Sorry, I just got back from holiday and I'm still in the deleting emails
mode.

On Fri, Aug 20, 2021 at 12:13:22AM +0800, Boqun Feng wrote:
> Appreciate it that you can have a look at this one and patch #4, note
> that there exists an alternative solution at[1].
> 
> The difference is the way used to pass the corresponding ACPI device
> pointers for PCI host bridges: currently pci_config_window->parent is
> used, and this patch and patch #4 allow the field to be NULL, because
> Hyper-V's PCI host bridges don't have ACPI devices, while [1] changes to
> use pci_host_bridge->private. And I'm OK with either way, I don't have a
> strong opinion here ;-)
[...]
> [1]: https://lore.kernel.org/lkml/20210811153619.88922-1-boqun.feng at gmail.com/

I'm ok with the arm64 bits in this series and the one you linked above.
It's up to Lorenzo if he's happy with how pci-hyperv.c ends up looking,
I'm not a PCIe expert. My preference would be for a combined series
(this and [1] above).

Happy to ack the arm64 patches in a combined series (if you are going to
post one), the changes would look even simpler.

-- 
Catalin


From nm at ti.com  Fri Aug 20 10:50:22 2021
From: nm at ti.com (Nishanth Menon)
Date: Fri, 20 Aug 2021 12:50:22 -0500
Subject: [PATCH] ARM: dts: da850-evm: Change aemif node status from "ok"
 to "okay"
In-Reply-To: <20210820093744.4877-1-rogerq@kernel.org>
References: <20210820093744.4877-1-rogerq@kernel.org>
Message-ID: <20210820175022.vdx53s4aih2r2xce@joyride>

On 12:37-20210820, Roger Quadros wrote:
> As per Device Tree core schema, status parameter of nodes can be either
> "okay" or "disabled".
> 
> U-boot Driver Model does not recognize status="ok" either and treats
> the node as disabled.
> 
> [1] https://github.com/devicetree-org/dt-schema/blob/master/schemas/dt-core.yaml#L36

May be pointing to the spec is better here..? 



https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  arch/arm/boot/dts/da850-evm.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
> index 87c517d65f62..9dc79b5977bf 100644
> --- a/arch/arm/boot/dts/da850-evm.dts
> +++ b/arch/arm/boot/dts/da850-evm.dts
> @@ -415,7 +415,7 @@
>  &aemif {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&nand_pins>;
> -	status = "ok";
> +	status = "okay";
>  	cs3 {
>  		#address-cells = <2>;
>  		#size-cells = <1>;
> -- 
> 2.17.1
> 

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From oupton at google.com  Fri Aug 20 11:22:38 2021
From: oupton at google.com (Oliver Upton)
Date: Fri, 20 Aug 2021 11:22:38 -0700
Subject: [PATCH v7 1/6] KVM: x86: Fix potential race in KVM_GET_CLOCK
In-Reply-To: <20210819182422.GA25923@fuller.cnet>
References: <20210816001130.3059564-1-oupton@google.com>
 <20210816001130.3059564-2-oupton@google.com>
 <20210819182422.GA25923@fuller.cnet>
Message-ID: <CAOQ_Qsin6YTUdbGaq3GChFWq_fzmXrKOUTQk7FarqL0b5GqC4g@mail.gmail.com>

On Thu, Aug 19, 2021 at 11:43 AM Marcelo Tosatti <mtosatti at redhat.com> wrote:
>
> On Mon, Aug 16, 2021 at 12:11:25AM +0000, Oliver Upton wrote:
> > Sean noticed that KVM_GET_CLOCK was checking kvm_arch.use_master_clock
> > outside of the pvclock sync lock. This is problematic, as the clock
> > value written to the user may or may not actually correspond to a stable
> > TSC.
> >
> > Fix the race by populating the entire kvm_clock_data structure behind
> > the pvclock_gtod_sync_lock.
>
> Oliver,
>
> Can you please describe the race in more detail?
>
> Is it about host TSC going unstable VS parallel KVM_GET_CLOCK ?
>

Yeah, pretty much any event that causes us to set use_master_clock =
false could interleave with the KVM_GET_CLOCK ioctl. A guest could
kick its TSCs out of sync, for example, to cause this too. AFAICT, KVM
serializes the write side (pvclock_update_vm_gtod_copy()) with
pvclock_gtod_sync_lock, as it should.

--
Thanks,
Oliver


From robh+dt at kernel.org  Fri Aug 20 11:27:39 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 20 Aug 2021 13:27:39 -0500
Subject: [PATCH 2/2] dt-bindings: rng: convert Samsung Exynos TRNG to
 dtschema
In-Reply-To: <dleftjtujnemx7.fsf%l.stelmach@samsung.com>
References: <CGME20210817221734eucas1p2e4a0aa41406137b90e49230371b92ac6@eucas1p2.samsung.com>
 <da43d243-35b0-2cc6-f8a0-a5d02c997301@canonical.com>
 <dleftjtujnemx7.fsf%l.stelmach@samsung.com>
Message-ID: <CAL_JsqK7MfUL8=0SfaKDoZmtN7qrgejdsZnNFENeEJpJVDuOKw@mail.gmail.com>

On Tue, Aug 17, 2021 at 5:17 PM Lukasz Stelmach <l.stelmach at samsung.com> wrote:
>
> It was <2021-08-17 wto 16:07>, when Krzysztof Kozlowski wrote:
> > On 17/08/2021 14:34, Lukasz Stelmach wrote:
> >> It was <2021-08-17 wto 12:05>, when Krzysztof Kozlowski wrote:
> >>> On 17/08/2021 11:55, Lukasz Stelmach wrote:
> >>>> It was <2021-08-11 ?ro 10:43>, when Krzysztof Kozlowski wrote:
> >>>>> Convert Samsung Exynos SoC True Random Number Generator bindings to DT
> >>>>> schema format using json-schema.
> >>>>>
> >>>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >>>>> ---
> >>>>>  .../bindings/rng/samsung,exynos5250-trng.txt  | 17 -------
> >>>>>  .../bindings/rng/samsung,exynos5250-trng.yaml | 44 +++++++++++++++++++
> >>>>>  MAINTAINERS                                   |  2 +-
> >>>>>  3 files changed, 45 insertions(+), 18 deletions(-)
> >>>>>  delete mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
> >>>>>  create mode 100644 Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
> >>>>>
> >>>>> diff --git
> >>>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
> >>>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
> >>>>> deleted file mode 100644
> >>>>> index 5a613a4ec780..000000000000
> >>>>> --- a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.txt
> >>>>> +++ /dev/null
> >>>>> @@ -1,17 +0,0 @@
> >>>>> -Exynos True Random Number Generator
> >>>>> -
> >>>>> -Required properties:
> >>>>> -
> >>>>> -- compatible  : Should be "samsung,exynos5250-trng".
> >>>>> -- reg         : Specifies base physical address and size of the registers map.
> >>>>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
> >>>>> -- clock-names : "secss" as a clock name.
> >>>>> -
> >>>>> -Example:
> >>>>> -
> >>>>> - rng at 10830600 {
> >>>>> -         compatible = "samsung,exynos5250-trng";
> >>>>> -         reg = <0x10830600 0x100>;
> >>>>> -         clocks = <&clock CLK_SSS>;
> >>>>> -         clock-names = "secss";
> >>>>> - };
> >>>>> diff --git
> >>>>> a/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
> >>>>> b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
> >>>>> new file mode 100644
> >>>>> index 000000000000..a50c34d5d199
> >>>>> --- /dev/null
> >>>>> +++ b/Documentation/devicetree/bindings/rng/samsung,exynos5250-trng.yaml
> >>>>> @@ -0,0 +1,44 @@
> >>>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> >>>>> +%YAML 1.2
> >>>>> +---
> >>>>> +$id:
> >>>>> https://protect2.fireeye.com/v1/url?k=f38ca35b-ac179a0d-f38d2814-0cc47a31ce52-1faa1ecb65482b8a&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Frng%2Fsamsung%2Cexynos5250-trng.yaml%23
> >>>>> +$schema:
> >>>>> https://protect2.fireeye.com/v1/url?k=9409519d-cb9268cb-9408dad2-0cc47a31ce52-12394c4409905980&q=1&e=8b3490f9-a5fc-4da0-b2ee-7b0aec781403&u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
> >>>>> +
> >>>>> +title: Samsung Exynos SoC True Random Number Generator
> >>>>> +
> >>>>> +maintainers:
> >>>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >>>>> +  - ?ukasz Stelmach <l.stelmach at samsung.com>
> >>>>> +
> >>>>> +properties:
> >>>>> +  compatible:
> >>>>> +    const: samsung,exynos5250-trng
> >>>>> +
> >>>>> +  clocks:
> >>>>> +    maxItems: 1
> >>>>
> >>>> How about copying description from above into the description: property?
> >>>
> >>> But what to copy? There is no description except generic clock bindings.
> >>>
> >>
> >> The description that "was" in the txt file.
> >
> > But there was no description of fields except copy&paste of the core
> > schema. Do you describe C code like:
> >
> > ...
> > /* unsigned int is a integer number greater or equal 0 */
> > unsigned int i;
> > ...
>
> I believe having descriptions for reg and clocks
>
> >>>>> -- reg         : Specifies base physical address and size of the registers map.
> >>>>> -- clocks      : Phandle to clock-controller plus clock-specifier pair.
>
> right next to properties' formal definitions is beneficial for anyone
> browsing the YAML file. If you think otherwise, oh well, I am fine with
> that.

We have 2000 schemas currently (and 2300 still to convert). Of the
~2000, 1646 have 'reg' and 1005 have 'clocks' (I was going to guess
3/4 and 1/2, respectively, but with a nice uniform, parsable format we
don't have to guess). Do we need that many copies of variations of the
same description?

What I would like to have is generated documentation from the schemas.
With that we could either insert a description or a link on all the
common properties. There are already tools that generate documentation
out of json-schema, but I don't have the time to investigate them or
work on any of that.

My other idea is some sort of property grepping utility. While grep
generally works, it would be nice to have some tools aware of the
schema structure where you could just run 'dt-grep clocks' and have it
spit out the description. Another example would be to list all the
valid properties for a given compatible string. Lots of possibilities
with machine readable bindings.

Rob


From frattaroli.nicolas at gmail.com  Fri Aug 20 11:27:27 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Fri, 20 Aug 2021 20:27:27 +0200
Subject: [PATCH v2 0/4] Rockchip I2S/TDM controller
Message-ID: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>

Changes in v2:
 - remove ad-hoc writeq and needless (and broken) optimisation in
   reset assert/deassert. This wouldn't have worked on Big Endian,
   and would've been pointless on any other platform, as the
   overhead for saving one write was comparatively big
 - fix various checkpatch issues
 - get rid of leftover clk-trcm in schema
 - set status = "okay" in example in schema instead of "disabled"
 - change dma-names so rx is first, adjust device trees as necessary
 - properly reference uint32-array for rx-route and tx-route
   instead of uint32
 - replace trcm-sync with two boolean properties, adjust DT changes
   accordingly and also get rid of the header file
 - get rid of rockchip,no-dmaengine. This was only needed for
   some downstream driver and shouldn't be in the DT
 - get rid of rockchip,capture-only/playback-only. Rationale being
   that I have no way to test whether they're needed, and
   unconditionally setting channels_min to 0 breaks everything
 - change hclk description in "clocks"

Additionally, I have been made aware that registers and code seem
to be an extension of the rockchip_i2s driver. This is true,
though merging the two seems like more effort than just slapping
a few compatibles and properties into the mix. I'll investigate
it further in the coming weeks, but would likely still prefer
basing any unified driver on mine rather than the other way
around, since I think it has better code quality now.

Original cover letter:

Hello,

I come bearing four patches for your consideration.

The first of these four patches adds a driver for the Rockchip
I2S/TDM controller, used in interfacing between the AHB bus and the
I2S bus on some Rockchip SoCs. This allows for audio playback with
a matching codec.

The controller has three different modes: I2S, I2S/TDM and PCM.
It is distinct from the earlier Rockchip I2S controller, and
therefore not just an extension of that driver.

The driver is based on the downstream version, though various
changes have been made to hopefully make it more palatable to
upstream. Some needless code duplication has been refactored, and
the probe function will no longer let wrong device tree values
write nonsense to hardware registers. Properties have been renamed
and had their semantics changed. I won't bore you with the details
of what downstream did, since that's not what I'm submitting, but
the changes are significant enough that I've added myself to the
list of authors.

The second patch adds the YAML device tree bindings for this, which
have been written from scratch by yours truly. Since I didn't like
having random integers mean things, I defined them as constants in
a header file for the bindings.

The third patch adds the i2s1 controller to the rk356x device tree.
I didn't add any of the other i2s controllers on that SoC for now as
I have no way of testing them; in particular, i2s0 is tied to HDMI,
so needs a functioning VOP2 driver to even have a chance of working.

The fourth patch makes use of the i2s1 controller to enable analog
audio output on the Quartz64 Model A through its RK817 codec. I've
tested this to work properly at both 44.1 kHz and 96 kHz, so both
mclk_root0 and mclk_root1 are definitely functioning.

This is my first kernel contribution, so I most likely did
something horribly wrong. That's why I'm more than happy to receive
any criticisms and concerns over how the driver is implemented,
because I've run out of ideas on how to make it clearly better
myself.

I'd also like to extend my thanks to Peter Geis, who has been
acting as somewhat of a mentor and gave me occasional feedback
and ideas during the writing of this patch series.

Regards,
Nicolas Frattaroli

Nicolas Frattaroli (4):
  ASoC: rockchip: add support for i2s-tdm controller
  dt-bindings: sound: add rockchip i2s-tdm binding
  arm64: dts: rockchip: add i2s1 on rk356x
  arm64: dts: rockchip: add analog audio on Quartz64

 .../bindings/sound/rockchip,i2s-tdm.yaml      |  193 ++
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   |   35 +-
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |   26 +
 sound/soc/rockchip/Kconfig                    |   11 +
 sound/soc/rockchip/Makefile                   |    2 +
 sound/soc/rockchip/rockchip_i2s_tdm.c         | 1737 +++++++++++++++++
 sound/soc/rockchip/rockchip_i2s_tdm.h         |  398 ++++
 7 files changed, 2401 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.c
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.h

-- 
2.32.0



From frattaroli.nicolas at gmail.com  Fri Aug 20 11:27:28 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Fri, 20 Aug 2021 20:27:28 +0200
Subject: [PATCH v2 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210820182731.29370-2-frattaroli.nicolas@gmail.com>

This commit adds support for the rockchip i2s-tdm controller,
which enables audio output on the following rockchip SoCs:
- px30
- rk1808
- rk3308
- rk3566
- rk3568
- rv1126

This is a cleaned up version of the downstream vendor kernel's
driver. It can be enabled through the SND_SOC_ROCKCHIP_I2S_TDM
configuration option.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 sound/soc/rockchip/Kconfig            |   11 +
 sound/soc/rockchip/Makefile           |    2 +
 sound/soc/rockchip/rockchip_i2s_tdm.c | 1737 +++++++++++++++++++++++++
 sound/soc/rockchip/rockchip_i2s_tdm.h |  398 ++++++
 4 files changed, 2148 insertions(+)
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.c
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.h

diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index 053097b73e28..42f76bc0fb02 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -16,6 +16,17 @@ config SND_SOC_ROCKCHIP_I2S
 	  Rockchip I2S device. The device supports upto maximum of
 	  8 channels each for play and record.
 
+config SND_SOC_ROCKCHIP_I2S_TDM
+	tristate "Rockchip I2S/TDM Device Driver"
+	depends on HAVE_CLK && SND_SOC_ROCKCHIP
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	help
+	  Say Y or M if you want to add support for the I2S/TDM driver for
+	  Rockchip I2S/TDM devices, found in Rockchip SoCs. These devices
+	  interface between the AHB bus and the I2S bus, and support up to a
+	  maximum of 8 channels each for playback and recording.
+
+
 config SND_SOC_ROCKCHIP_PDM
 	tristate "Rockchip PDM Controller Driver"
 	depends on HAVE_CLK && SND_SOC_ROCKCHIP
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 65e814d46006..b10f5e7b136d 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -1,11 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0
 # ROCKCHIP Platform Support
 snd-soc-rockchip-i2s-objs := rockchip_i2s.o
+snd-soc-rockchip-i2s-tdm-objs := rockchip_i2s_tdm.o
 snd-soc-rockchip-pcm-objs := rockchip_pcm.o
 snd-soc-rockchip-pdm-objs := rockchip_pdm.o
 snd-soc-rockchip-spdif-objs := rockchip_spdif.o
 
 obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o snd-soc-rockchip-pcm.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S_TDM) += snd-soc-rockchip-i2s-tdm.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_PDM) += snd-soc-rockchip-pdm.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
 
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
new file mode 100644
index 000000000000..c02b66f3c913
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
@@ -0,0 +1,1737 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
+ *
+ * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
+ * Author: Sugar Zhang <sugar.zhang at rock-chips.com>
+ * Author: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/delay.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+
+#include "rockchip_i2s_tdm.h"
+
+#define DRV_NAME "rockchip-i2s-tdm"
+
+#define DEFAULT_MCLK_FS				256
+#define CH_GRP_MAX				4  /* The max channel 8 / 2 */
+#define MULTIPLEX_CH_MAX			10
+#define CLK_PPM_MIN				(-1000)
+#define CLK_PPM_MAX				(1000)
+
+#define TRCM_TXRX 0
+#define TRCM_TX 1
+#define TRCM_RX 2
+
+struct txrx_config {
+	u32 addr;
+	u32 reg;
+	u32 txonly;
+	u32 rxonly;
+};
+
+struct rk_i2s_soc_data {
+	u32 softrst_offset;
+	u32 grf_reg_offset;
+	u32 grf_shift;
+	int config_count;
+	const struct txrx_config *configs;
+	int (*init)(struct device *dev, u32 addr);
+};
+
+struct rk_i2s_tdm_dev {
+	struct device *dev;
+	struct clk *hclk;
+	struct clk *mclk_tx;
+	struct clk *mclk_rx;
+	/* The mclk_tx_src is parent of mclk_tx */
+	struct clk *mclk_tx_src;
+	/* The mclk_rx_src is parent of mclk_rx */
+	struct clk *mclk_rx_src;
+	/*
+	 * The mclk_root0 and mclk_root1 are root parent and supplies for
+	 * the different FS.
+	 *
+	 * e.g:
+	 * mclk_root0 is VPLL0, used for FS=48000Hz
+	 * mclk_root1 is VPLL1, used for FS=44100Hz
+	 */
+	struct clk *mclk_root0;
+	struct clk *mclk_root1;
+	struct regmap *regmap;
+	struct regmap *grf;
+	struct snd_dmaengine_dai_dma_data capture_dma_data;
+	struct snd_dmaengine_dai_dma_data playback_dma_data;
+	struct reset_control *tx_reset;
+	struct reset_control *rx_reset;
+	struct rk_i2s_soc_data *soc_data;
+	void __iomem *cru_base;
+	bool is_master_mode;
+	bool io_multiplex;
+	bool mclk_calibrate;
+	bool tdm_mode;
+	bool tdm_fsync_half_frame;
+	unsigned int mclk_rx_freq;
+	unsigned int mclk_tx_freq;
+	unsigned int mclk_root0_freq;
+	unsigned int mclk_root1_freq;
+	unsigned int mclk_root0_initial_freq;
+	unsigned int mclk_root1_initial_freq;
+	unsigned int frame_width;
+	unsigned int clk_trcm;
+	unsigned int i2s_sdis[CH_GRP_MAX];
+	unsigned int i2s_sdos[CH_GRP_MAX];
+	int clk_ppm;
+	int tx_reset_id;
+	int rx_reset_id;
+	atomic_t refcount;
+	spinlock_t lock; /* xfer lock */
+};
+
+static int to_ch_num(unsigned int val)
+{
+	switch (val) {
+	case I2S_CHN_4:
+		return 4;
+	case I2S_CHN_6:
+		return 6;
+	case I2S_CHN_8:
+		return 8;
+	default:
+		return 2;
+	}
+}
+
+static int i2s_tdm_runtime_suspend(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+
+	regcache_cache_only(i2s_tdm->regmap, true);
+	if (!IS_ERR(i2s_tdm->mclk_tx))
+		clk_disable_unprepare(i2s_tdm->mclk_tx);
+	if (!IS_ERR(i2s_tdm->mclk_rx))
+		clk_disable_unprepare(i2s_tdm->mclk_rx);
+
+	return 0;
+}
+
+static int i2s_tdm_runtime_resume(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	int ret;
+
+	if (!IS_ERR(i2s_tdm->mclk_tx))
+		clk_prepare_enable(i2s_tdm->mclk_tx);
+	if (!IS_ERR(i2s_tdm->mclk_rx))
+		clk_prepare_enable(i2s_tdm->mclk_rx);
+
+	regcache_cache_only(i2s_tdm->regmap, false);
+	regcache_mark_dirty(i2s_tdm->regmap);
+
+	ret = regcache_sync(i2s_tdm->regmap);
+	if (ret) {
+		if (!IS_ERR(i2s_tdm->mclk_tx))
+			clk_disable_unprepare(i2s_tdm->mclk_tx);
+		if (!IS_ERR(i2s_tdm->mclk_rx))
+			clk_disable_unprepare(i2s_tdm->mclk_rx);
+	}
+
+	return ret;
+}
+
+static inline struct rk_i2s_tdm_dev *to_info(struct snd_soc_dai *dai)
+{
+	return snd_soc_dai_get_drvdata(dai);
+}
+
+static void rockchip_snd_xfer_reset_assert(struct rk_i2s_tdm_dev *i2s_tdm,
+					   int tx_bank, int tx_offset,
+					   int rx_bank, int rx_offset)
+{
+	void __iomem *cru_reset;
+	unsigned long flags;
+
+	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
+
+	if (tx_bank == rx_bank) {
+		writel(BIT(tx_offset) | BIT(rx_offset) |
+		       (BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+	} else {
+		local_irq_save(flags);
+		writel(BIT(tx_offset) | (BIT(tx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+		writel(BIT(rx_offset) | (BIT(rx_offset) << 16),
+		       cru_reset + (rx_bank * 4));
+		local_irq_restore(flags);
+	}
+}
+
+static void rockchip_snd_xfer_reset_deassert(struct rk_i2s_tdm_dev *i2s_tdm,
+					     int tx_bank, int tx_offset,
+					     int rx_bank, int rx_offset)
+{
+	void __iomem *cru_reset;
+	unsigned long flags;
+
+	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
+
+	if (tx_bank == rx_bank) {
+		writel((BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+	} else {
+		local_irq_save(flags);
+		writel((BIT(tx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+		writel((BIT(rx_offset) << 16),
+		       cru_reset + (rx_bank * 4));
+		local_irq_restore(flags);
+	}
+}
+
+/*
+ * Makes sure that both tx and rx are reset at the same time to sync lrck
+ * when clk_trcm > 0.
+ */
+static void rockchip_snd_xfer_sync_reset(struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int tx_id, rx_id;
+	int tx_bank, rx_bank, tx_offset, rx_offset;
+
+	if (!i2s_tdm->cru_base || !i2s_tdm->soc_data)
+		return;
+
+	tx_id = i2s_tdm->tx_reset_id;
+	rx_id = i2s_tdm->rx_reset_id;
+	if (tx_id < 0 || rx_id < 0)
+		return;
+
+	tx_bank = tx_id / 16;
+	tx_offset = tx_id % 16;
+	rx_bank = rx_id / 16;
+	rx_offset = rx_id % 16;
+	dev_dbg(i2s_tdm->dev,
+		"tx_bank: %d, rx_bank: %d, tx_offset: %d, rx_offset: %d\n",
+		tx_bank, rx_bank, tx_offset, rx_offset);
+
+	rockchip_snd_xfer_reset_assert(i2s_tdm, tx_bank, tx_offset,
+				       rx_bank, rx_offset);
+
+	udelay(150);
+
+	rockchip_snd_xfer_reset_deassert(i2s_tdm, tx_bank, tx_offset,
+					 rx_bank, rx_offset);
+}
+
+static void rockchip_snd_reset(struct reset_control *rc)
+{
+	if (IS_ERR(rc))
+		return;
+
+	reset_control_assert(rc);
+	udelay(1);
+	reset_control_deassert(rc);
+}
+
+static void rockchip_snd_xfer_clear(struct rk_i2s_tdm_dev *i2s_tdm,
+				    unsigned int clr)
+{
+	unsigned int xfer_mask;
+	unsigned int xfer_val;
+	unsigned int val;
+	int retry = 10;
+	bool tx = clr & I2S_CLR_TXC;
+	bool rx = clr & I2S_CLR_RXC;
+
+	if (!(rx || tx))
+		return;
+
+	xfer_mask = (tx ? I2S_XFER_TXS_START : 0) |
+		    (rx ? I2S_XFER_RXS_START : 0);
+	xfer_val = (tx ? I2S_XFER_TXS_STOP : 0) |
+		   (rx ? I2S_XFER_RXS_STOP : 0);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_XFER, xfer_mask, xfer_val);
+	udelay(150);
+	regmap_update_bits(i2s_tdm->regmap, I2S_CLR, clr, clr);
+
+	regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
+	/* Wait on the clear operation to finish */
+	while (val) {
+		regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
+		retry--;
+		if (!retry) {
+			dev_warn(i2s_tdm->dev, "clear failed, reset %s%s\n",
+				 tx ? "tx" : "", rx ? "rx" : "");
+			if (rx && tx)
+				rockchip_snd_xfer_sync_reset(i2s_tdm);
+			else if (tx)
+				rockchip_snd_reset(i2s_tdm->tx_reset);
+			else if (rx)
+				rockchip_snd_reset(i2s_tdm->rx_reset);
+			break;
+		}
+	}
+}
+
+/* only used when clk_trcm > 0 */
+static void rockchip_snd_txrxctrl(struct snd_pcm_substream *substream,
+				  struct snd_soc_dai *dai, int on)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	spin_lock(&i2s_tdm->lock);
+	if (on) {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_TDE_ENABLE,
+					   I2S_DMACR_TDE_ENABLE);
+		else
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_RDE_ENABLE,
+					   I2S_DMACR_RDE_ENABLE);
+
+		if (atomic_inc_return(&i2s_tdm->refcount) == 1) {
+			rockchip_snd_xfer_sync_reset(i2s_tdm);
+			regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+					   I2S_XFER_TXS_START |
+					   I2S_XFER_RXS_START,
+					   I2S_XFER_TXS_START |
+					   I2S_XFER_RXS_START);
+		}
+	} else {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_TDE_ENABLE,
+					   I2S_DMACR_TDE_DISABLE);
+		else
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_RDE_ENABLE,
+					   I2S_DMACR_RDE_DISABLE);
+
+		if (atomic_dec_and_test(&i2s_tdm->refcount)) {
+			rockchip_snd_xfer_clear(i2s_tdm,
+						I2S_CLR_TXC | I2S_CLR_RXC);
+		}
+	}
+	spin_unlock(&i2s_tdm->lock);
+}
+
+static void rockchip_snd_txctrl(struct rk_i2s_tdm_dev *i2s_tdm, int on)
+{
+	if (on) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
+
+		regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+				   I2S_XFER_TXS_START,
+				   I2S_XFER_TXS_START);
+	} else {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
+
+		rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_TXC);
+	}
+}
+
+static void rockchip_snd_rxctrl(struct rk_i2s_tdm_dev *i2s_tdm, int on)
+{
+	if (on) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
+
+		regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+				   I2S_XFER_RXS_START,
+				   I2S_XFER_RXS_START);
+	} else {
+		rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_RXC);
+	}
+}
+
+static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
+				    unsigned int fmt)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
+	unsigned int mask = 0, val = 0, tdm_val = 0, txcr_val = 0, rxcr_val = 0;
+	int ret = 0;
+	bool is_tdm = i2s_tdm->tdm_mode;
+
+	pm_runtime_get_sync(cpu_dai->dev);
+	mask = I2S_CKR_MSS_MASK;
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		val = I2S_CKR_MSS_MASTER;
+		i2s_tdm->is_master_mode = true;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		val = I2S_CKR_MSS_SLAVE;
+		i2s_tdm->is_master_mode = false;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val);
+
+	mask = I2S_CKR_CKP_MASK | I2S_CKR_TLP_MASK | I2S_CKR_RLP_MASK;
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		val = I2S_CKR_CKP_NORMAL |
+		      I2S_CKR_TLP_NORMAL |
+		      I2S_CKR_RLP_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		val = I2S_CKR_CKP_NORMAL |
+		      I2S_CKR_TLP_INVERTED |
+		      I2S_CKR_RLP_INVERTED;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		val = I2S_CKR_CKP_INVERTED |
+		      I2S_CKR_TLP_NORMAL |
+		      I2S_CKR_RLP_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		val = I2S_CKR_CKP_INVERTED |
+		      I2S_CKR_TLP_INVERTED |
+		      I2S_CKR_RLP_INVERTED;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_RIGHT_J:
+		txcr_val = I2S_TXCR_IBM_RSJM;
+		rxcr_val = I2S_RXCR_IBM_RSJM;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		txcr_val = I2S_TXCR_IBM_LSJM;
+		rxcr_val = I2S_RXCR_IBM_LSJM;
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		txcr_val = I2S_TXCR_IBM_NORMAL;
+		rxcr_val = I2S_RXCR_IBM_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */
+		txcr_val = I2S_TXCR_TFS_PCM;
+		rxcr_val = I2S_RXCR_TFS_PCM;
+		break;
+	case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */
+		txcr_val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);
+		rxcr_val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	mask = I2S_TXCR_IBM_MASK | I2S_TXCR_TFS_MASK | I2S_TXCR_PBM_MASK;
+	regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, txcr_val);
+
+	mask = I2S_RXCR_IBM_MASK | I2S_RXCR_TFS_MASK | I2S_RXCR_PBM_MASK;
+	regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, rxcr_val);
+
+	if (is_tdm) {
+		switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+		case SND_SOC_DAIFMT_RIGHT_J:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(2);
+			break;
+		case SND_SOC_DAIFMT_LEFT_J:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(1);
+			break;
+		case SND_SOC_DAIFMT_I2S:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(0);
+			break;
+		case SND_SOC_DAIFMT_DSP_A:
+			val = I2S_TXCR_TFS_TDM_PCM;
+			tdm_val = TDM_SHIFT_CTRL(0);
+			break;
+		case SND_SOC_DAIFMT_DSP_B:
+			val = I2S_TXCR_TFS_TDM_PCM;
+			tdm_val = TDM_SHIFT_CTRL(2);
+			break;
+		default:
+			ret = -EINVAL;
+			goto err_pm_put;
+		}
+
+		tdm_val |= TDM_FSYNC_WIDTH_SEL1(1);
+		if (i2s_tdm->tdm_fsync_half_frame)
+			tdm_val |= TDM_FSYNC_WIDTH_HALF_FRAME;
+		else
+			tdm_val |= TDM_FSYNC_WIDTH_ONE_FRAME;
+
+		mask = I2S_TXCR_TFS_MASK;
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, val);
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, val);
+
+		mask = TDM_FSYNC_WIDTH_SEL1_MSK | TDM_FSYNC_WIDTH_SEL0_MSK |
+		       TDM_SHIFT_CTRL_MSK;
+		regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR,
+				   mask, tdm_val);
+		regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR,
+				   mask, tdm_val);
+	}
+
+err_pm_put:
+	pm_runtime_put(cpu_dai->dev);
+
+	return ret;
+}
+
+static void rockchip_i2s_tdm_xfer_pause(struct snd_pcm_substream *substream,
+					struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int stream;
+
+	stream = SNDRV_PCM_STREAM_LAST - substream->stream;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE,
+				   I2S_DMACR_TDE_DISABLE);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE,
+				   I2S_DMACR_RDE_DISABLE);
+
+	rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_TXC | I2S_CLR_RXC);
+}
+
+static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream *substream,
+					 struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int stream;
+
+	stream = SNDRV_PCM_STREAM_LAST - substream->stream;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE,
+				   I2S_DMACR_TDE_ENABLE);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE,
+				   I2S_DMACR_RDE_ENABLE);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+			   I2S_XFER_TXS_START |
+			   I2S_XFER_RXS_START,
+			   I2S_XFER_TXS_START |
+			   I2S_XFER_RXS_START);
+}
+
+static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm,
+					 struct clk *clk, unsigned long rate,
+					 int ppm)
+{
+	unsigned long rate_target;
+	int delta, ret;
+
+	if (ppm == i2s_tdm->clk_ppm)
+		return 0;
+
+	delta = (ppm < 0) ? -1 : 1;
+	delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000,
+				1000000);
+
+	rate_target = rate + delta;
+
+	if (!rate_target)
+		return -EINVAL;
+
+	ret = clk_set_rate(clk, rate_target);
+	if (ret)
+		return ret;
+
+	i2s_tdm->clk_ppm = ppm;
+
+	return ret;
+}
+
+static int rockchip_i2s_tdm_calibrate_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
+					   struct snd_pcm_substream *substream,
+					   unsigned int lrck_freq)
+{
+	struct clk *mclk_root;
+	struct clk *mclk_parent;
+	unsigned int mclk_root_freq;
+	unsigned int mclk_root_initial_freq;
+	unsigned int mclk_parent_freq;
+	unsigned int div, delta;
+	u64 ppm;
+	int ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		mclk_parent = i2s_tdm->mclk_tx_src;
+	else
+		mclk_parent = i2s_tdm->mclk_rx_src;
+
+	switch (lrck_freq) {
+	case 8000:
+	case 16000:
+	case 24000:
+	case 32000:
+	case 48000:
+	case 64000:
+	case 96000:
+	case 192000:
+		mclk_root = i2s_tdm->mclk_root0;
+		mclk_root_freq = i2s_tdm->mclk_root0_freq;
+		mclk_root_initial_freq = i2s_tdm->mclk_root0_initial_freq;
+		mclk_parent_freq = DEFAULT_MCLK_FS * 192000;
+		break;
+	case 11025:
+	case 22050:
+	case 44100:
+	case 88200:
+	case 176400:
+		mclk_root = i2s_tdm->mclk_root1;
+		mclk_root_freq = i2s_tdm->mclk_root1_freq;
+		mclk_root_initial_freq = i2s_tdm->mclk_root1_initial_freq;
+		mclk_parent_freq = DEFAULT_MCLK_FS * 176400;
+		break;
+	default:
+		dev_err(i2s_tdm->dev, "Invalid LRCK freq: %u Hz\n",
+			lrck_freq);
+		return -EINVAL;
+	}
+
+	ret = clk_set_parent(mclk_parent, mclk_root);
+	if (ret)
+		return ret;
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, mclk_root,
+					    mclk_root_freq, 0);
+	if (ret)
+		return ret;
+
+	delta = abs(mclk_root_freq % mclk_parent_freq - mclk_parent_freq);
+	ppm = div64_u64((uint64_t)delta * 1000000, (uint64_t)mclk_root_freq);
+
+	if (ppm) {
+		div = DIV_ROUND_CLOSEST(mclk_root_initial_freq, mclk_parent_freq);
+		if (!div)
+			return -EINVAL;
+
+		mclk_root_freq = mclk_parent_freq * round_up(div, 2);
+
+		ret = clk_set_rate(mclk_root, mclk_root_freq);
+		if (ret)
+			return ret;
+
+		i2s_tdm->mclk_root0_freq = clk_get_rate(i2s_tdm->mclk_root0);
+		i2s_tdm->mclk_root1_freq = clk_get_rate(i2s_tdm->mclk_root1);
+	}
+
+	ret = clk_set_rate(mclk_parent, mclk_parent_freq);
+
+	return ret;
+}
+
+static int rockchip_i2s_tdm_set_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
+				     struct snd_pcm_substream *substream,
+				     struct clk **mclk)
+{
+	unsigned int mclk_freq;
+	int ret;
+
+	if (i2s_tdm->clk_trcm) {
+		if (i2s_tdm->mclk_tx_freq != i2s_tdm->mclk_rx_freq) {
+			dev_err(i2s_tdm->dev,
+				"clk_trcm, tx: %d and rx: %d should be same\n",
+				i2s_tdm->mclk_tx_freq,
+				i2s_tdm->mclk_rx_freq);
+			ret = -EINVAL;
+			return ret;
+		}
+
+		ret = clk_set_rate(i2s_tdm->mclk_tx, i2s_tdm->mclk_tx_freq);
+		if (ret)
+			return ret;
+
+		ret = clk_set_rate(i2s_tdm->mclk_rx, i2s_tdm->mclk_rx_freq);
+		if (ret)
+			return ret;
+
+		/* mclk_rx is also ok. */
+		*mclk = i2s_tdm->mclk_tx;
+	} else {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			*mclk = i2s_tdm->mclk_tx;
+			mclk_freq = i2s_tdm->mclk_tx_freq;
+		} else {
+			*mclk = i2s_tdm->mclk_rx;
+			mclk_freq = i2s_tdm->mclk_rx_freq;
+		}
+
+		ret = clk_set_rate(*mclk, mclk_freq);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_i2s_io_multiplex(struct snd_pcm_substream *substream,
+				     struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+	int usable_chs = MULTIPLEX_CH_MAX;
+	unsigned int val = 0;
+
+	if (!i2s_tdm->io_multiplex)
+		return 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		struct snd_pcm_str *playback_str =
+			&substream->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
+
+		if (playback_str->substream_opened) {
+			regmap_read(i2s_tdm->regmap, I2S_TXCR, &val);
+			val &= I2S_TXCR_CSR_MASK;
+			usable_chs = MULTIPLEX_CH_MAX - to_ch_num(val);
+		}
+
+		regmap_read(i2s_tdm->regmap, I2S_RXCR, &val);
+		val &= I2S_RXCR_CSR_MASK;
+
+		if (to_ch_num(val) > usable_chs) {
+			dev_err(i2s_tdm->dev,
+				"Capture chs(%d) > usable chs(%d)\n",
+				to_ch_num(val), usable_chs);
+			return -EINVAL;
+		}
+
+		switch (val) {
+		case I2S_CHN_4:
+			val = I2S_IO_6CH_OUT_4CH_IN;
+			break;
+		case I2S_CHN_6:
+			val = I2S_IO_4CH_OUT_6CH_IN;
+			break;
+		case I2S_CHN_8:
+			val = I2S_IO_2CH_OUT_8CH_IN;
+			break;
+		default:
+			val = I2S_IO_8CH_OUT_2CH_IN;
+			break;
+		}
+	} else {
+		struct snd_pcm_str *capture_str =
+			&substream->pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
+
+		if (capture_str->substream_opened) {
+			regmap_read(i2s_tdm->regmap, I2S_RXCR, &val);
+			val &= I2S_RXCR_CSR_MASK;
+			usable_chs = MULTIPLEX_CH_MAX - to_ch_num(val);
+		}
+
+		regmap_read(i2s_tdm->regmap, I2S_TXCR, &val);
+		val &= I2S_TXCR_CSR_MASK;
+
+		if (to_ch_num(val) > usable_chs) {
+			dev_err(i2s_tdm->dev,
+				"Playback chs(%d) > usable chs(%d)\n",
+				to_ch_num(val), usable_chs);
+			return -EINVAL;
+		}
+
+		switch (val) {
+		case I2S_CHN_4:
+			val = I2S_IO_4CH_OUT_6CH_IN;
+			break;
+		case I2S_CHN_6:
+			val = I2S_IO_6CH_OUT_4CH_IN;
+			break;
+		case I2S_CHN_8:
+			val = I2S_IO_8CH_OUT_2CH_IN;
+			break;
+		default:
+			val = I2S_IO_2CH_OUT_8CH_IN;
+			break;
+		}
+	}
+
+	val <<= i2s_tdm->soc_data->grf_shift;
+	val |= (I2S_IO_DIRECTION_MASK << i2s_tdm->soc_data->grf_shift) << 16;
+	regmap_write(i2s_tdm->grf, i2s_tdm->soc_data->grf_reg_offset, val);
+
+	return 0;
+}
+
+static int rockchip_i2s_trcm_mode(struct snd_pcm_substream *substream,
+				  struct snd_soc_dai *dai,
+				  unsigned int div_bclk,
+				  unsigned int div_lrck,
+				  unsigned int fmt)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	if (!i2s_tdm->clk_trcm)
+		return 0;
+
+	spin_lock(&i2s_tdm->lock);
+	if (atomic_read(&i2s_tdm->refcount))
+		rockchip_i2s_tdm_xfer_pause(substream, i2s_tdm);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+			   I2S_CLKDIV_TXM_MASK | I2S_CLKDIV_RXM_MASK,
+			   I2S_CLKDIV_TXM(div_bclk) | I2S_CLKDIV_RXM(div_bclk));
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+			   I2S_CKR_TSD_MASK | I2S_CKR_RSD_MASK,
+			   I2S_CKR_TSD(div_lrck) | I2S_CKR_RSD(div_lrck));
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
+				   fmt);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
+				   fmt);
+
+	if (atomic_read(&i2s_tdm->refcount))
+		rockchip_i2s_tdm_xfer_resume(substream, i2s_tdm);
+	spin_unlock(&i2s_tdm->lock);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params,
+				      struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+	struct clk *mclk;
+	int ret = 0;
+	unsigned int val = 0;
+	unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64;
+
+	if (i2s_tdm->is_master_mode) {
+		if (i2s_tdm->mclk_calibrate)
+			rockchip_i2s_tdm_calibrate_mclk(i2s_tdm, substream,
+							params_rate(params));
+
+		ret = rockchip_i2s_tdm_set_mclk(i2s_tdm, substream, &mclk);
+		if (ret)
+			return ret;
+
+		mclk_rate = clk_get_rate(mclk);
+		bclk_rate = i2s_tdm->frame_width * params_rate(params);
+		if (!bclk_rate)
+			return -EINVAL;
+
+		div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
+		div_lrck = bclk_rate / params_rate(params);
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S8:
+		val |= I2S_TXCR_VDW(8);
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+		val |= I2S_TXCR_VDW(16);
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		val |= I2S_TXCR_VDW(20);
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		val |= I2S_TXCR_VDW(24);
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		val |= I2S_TXCR_VDW(32);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (params_channels(params)) {
+	case 8:
+		val |= I2S_CHN_8;
+		break;
+	case 6:
+		val |= I2S_CHN_6;
+		break;
+	case 4:
+		val |= I2S_CHN_4;
+		break;
+	case 2:
+		val |= I2S_CHN_2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (i2s_tdm->clk_trcm) {
+		rockchip_i2s_trcm_mode(substream, dai, div_bclk, div_lrck, val);
+	} else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+				   I2S_CLKDIV_TXM_MASK,
+				   I2S_CLKDIV_TXM(div_bclk));
+		regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+				   I2S_CKR_TSD_MASK,
+				   I2S_CKR_TSD(div_lrck));
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
+				   val);
+	} else {
+		regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+				   I2S_CLKDIV_RXM_MASK,
+				   I2S_CLKDIV_RXM(div_bclk));
+		regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+				   I2S_CKR_RSD_MASK,
+				   I2S_CKR_RSD(div_lrck));
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
+				   val);
+	}
+
+	return rockchip_i2s_io_multiplex(substream, dai);
+}
+
+static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream,
+				    int cmd, struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (i2s_tdm->clk_trcm)
+			rockchip_snd_txrxctrl(substream, dai, 1);
+		else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			rockchip_snd_rxctrl(i2s_tdm, 1);
+		else
+			rockchip_snd_txctrl(i2s_tdm, 1);
+		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (i2s_tdm->clk_trcm)
+			rockchip_snd_txrxctrl(substream, dai, 0);
+		else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			rockchip_snd_rxctrl(i2s_tdm, 0);
+		else
+			rockchip_snd_txctrl(i2s_tdm, 0);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream,
+				       unsigned int freq, int dir)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
+
+	/* Put set mclk rate into rockchip_i2s_tdm_set_mclk() */
+	if (i2s_tdm->clk_trcm) {
+		i2s_tdm->mclk_tx_freq = freq;
+		i2s_tdm->mclk_rx_freq = freq;
+	} else {
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			i2s_tdm->mclk_tx_freq = freq;
+		else
+			i2s_tdm->mclk_rx_freq = freq;
+	}
+
+	dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n",
+		stream ? "rx" : "tx", freq);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
+						  struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = CLK_PPM_MIN;
+	uinfo->value.integer.max = CLK_PPM_MAX;
+	uinfo->value.integer.step = 1;
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
+						 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+
+	ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm;
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
+						 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+	int ret = 0, ppm = 0;
+
+	if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
+	    (ucontrol->value.integer.value[0] > CLK_PPM_MAX))
+		return -EINVAL;
+
+	ppm = ucontrol->value.integer.value[0];
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root0,
+					    i2s_tdm->mclk_root0_freq, ppm);
+	if (ret)
+		return ret;
+
+	if (clk_is_match(i2s_tdm->mclk_root0, i2s_tdm->mclk_root1))
+		return 0;
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root1,
+					    i2s_tdm->mclk_root1_freq, ppm);
+
+	return ret;
+}
+
+static struct snd_kcontrol_new rockchip_i2s_tdm_compensation_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+	.name = "PCM Clk Compensation In PPM",
+	.info = rockchip_i2s_tdm_clk_compensation_info,
+	.get = rockchip_i2s_tdm_clk_compensation_get,
+	.put = rockchip_i2s_tdm_clk_compensation_put,
+};
+
+static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+
+	dai->capture_dma_data = &i2s_tdm->capture_dma_data;
+	dai->playback_dma_data = &i2s_tdm->playback_dma_data;
+
+	if (i2s_tdm->mclk_calibrate)
+		snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1);
+
+	return 0;
+}
+
+static int rockchip_dai_tdm_slot(struct snd_soc_dai *dai,
+				 unsigned int tx_mask, unsigned int rx_mask,
+				 int slots, int slot_width)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+	unsigned int mask, val;
+
+	i2s_tdm->tdm_mode = true;
+	i2s_tdm->frame_width = slots * slot_width;
+	mask = TDM_SLOT_BIT_WIDTH_MSK | TDM_FRAME_WIDTH_MSK;
+	val = TDM_SLOT_BIT_WIDTH(slot_width) |
+	      TDM_FRAME_WIDTH(slots * slot_width);
+	regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR,
+			   mask, val);
+	regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR,
+			   mask, val);
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = {
+	.hw_params = rockchip_i2s_tdm_hw_params,
+	.set_sysclk = rockchip_i2s_tdm_set_sysclk,
+	.set_fmt = rockchip_i2s_tdm_set_fmt,
+	.set_tdm_slot = rockchip_dai_tdm_slot,
+	.trigger = rockchip_i2s_tdm_trigger,
+};
+
+static const struct snd_soc_component_driver rockchip_i2s_tdm_component = {
+	.name = DRV_NAME,
+};
+
+static bool rockchip_i2s_tdm_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXCR:
+	case I2S_RXCR:
+	case I2S_CKR:
+	case I2S_DMACR:
+	case I2S_INTCR:
+	case I2S_XFER:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_TDM_TXCR:
+	case I2S_TDM_RXCR:
+	case I2S_CLKDIV:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXCR:
+	case I2S_RXCR:
+	case I2S_CKR:
+	case I2S_DMACR:
+	case I2S_INTCR:
+	case I2S_XFER:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_RXDR:
+	case I2S_TXFIFOLR:
+	case I2S_INTSR:
+	case I2S_RXFIFOLR:
+	case I2S_TDM_TXCR:
+	case I2S_TDM_RXCR:
+	case I2S_CLKDIV:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXFIFOLR:
+	case I2S_INTSR:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_RXDR:
+	case I2S_RXFIFOLR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_precious_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_RXDR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct reg_default rockchip_i2s_tdm_reg_defaults[] = {
+	{0x00, 0x7200000f},
+	{0x04, 0x01c8000f},
+	{0x08, 0x00001f1f},
+	{0x10, 0x001f0000},
+	{0x14, 0x01f00000},
+	{0x30, 0x00003eff},
+	{0x34, 0x00003eff},
+	{0x38, 0x00000707},
+};
+
+static const struct regmap_config rockchip_i2s_tdm_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = I2S_CLKDIV,
+	.reg_defaults = rockchip_i2s_tdm_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(rockchip_i2s_tdm_reg_defaults),
+	.writeable_reg = rockchip_i2s_tdm_wr_reg,
+	.readable_reg = rockchip_i2s_tdm_rd_reg,
+	.volatile_reg = rockchip_i2s_tdm_volatile_reg,
+	.precious_reg = rockchip_i2s_tdm_precious_reg,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static int common_soc_init(struct device *dev, u32 addr)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	const struct txrx_config *configs = i2s_tdm->soc_data->configs;
+	u32 reg = 0, val = 0, trcm = i2s_tdm->clk_trcm;
+	int i;
+
+	if (trcm == TRCM_TXRX)
+		return 0;
+
+	for (i = 0; i < i2s_tdm->soc_data->config_count; i++) {
+		if (addr != configs[i].addr)
+			continue;
+		reg = configs[i].reg;
+		if (trcm == TRCM_TX)
+			val = configs[i].txonly;
+		else
+			val = configs[i].rxonly;
+
+		if (reg)
+			regmap_write(i2s_tdm->grf, reg, val);
+	}
+
+	return 0;
+}
+
+static const struct txrx_config px30_txrx_config[] = {
+	{ 0xff060000, 0x184, PX30_I2S0_CLK_TXONLY, PX30_I2S0_CLK_RXONLY },
+};
+
+static const struct txrx_config rk1808_txrx_config[] = {
+	{ 0xff7e0000, 0x190, RK1808_I2S0_CLK_TXONLY, RK1808_I2S0_CLK_RXONLY },
+};
+
+static const struct txrx_config rk3308_txrx_config[] = {
+	{ 0xff300000, 0x308, RK3308_I2S0_CLK_TXONLY, RK3308_I2S0_CLK_RXONLY },
+	{ 0xff310000, 0x308, RK3308_I2S1_CLK_TXONLY, RK3308_I2S1_CLK_RXONLY },
+};
+
+static const struct txrx_config rk3568_txrx_config[] = {
+	{ 0xfe410000, 0x504, RK3568_I2S1_CLK_TXONLY, RK3568_I2S1_CLK_RXONLY },
+	{ 0xfe410000, 0x508, RK3568_I2S1_MCLK_TX_OE, RK3568_I2S1_MCLK_RX_OE },
+	{ 0xfe420000, 0x508, RK3568_I2S2_MCLK_OE, RK3568_I2S2_MCLK_OE },
+	{ 0xfe430000, 0x504, RK3568_I2S3_CLK_TXONLY, RK3568_I2S3_CLK_RXONLY },
+	{ 0xfe430000, 0x508, RK3568_I2S3_MCLK_TXONLY, RK3568_I2S3_MCLK_RXONLY },
+	{ 0xfe430000, 0x508, RK3568_I2S3_MCLK_OE, RK3568_I2S3_MCLK_OE },
+};
+
+static const struct txrx_config rv1126_txrx_config[] = {
+	{ 0xff800000, 0x10260, RV1126_I2S0_CLK_TXONLY, RV1126_I2S0_CLK_RXONLY },
+};
+
+static struct rk_i2s_soc_data px30_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = px30_txrx_config,
+	.config_count = ARRAY_SIZE(px30_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk1808_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = rk1808_txrx_config,
+	.config_count = ARRAY_SIZE(rk1808_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk3308_i2s_soc_data = {
+	.softrst_offset = 0x0400,
+	.grf_reg_offset = 0x0308,
+	.grf_shift = 5,
+	.configs = rk3308_txrx_config,
+	.config_count = ARRAY_SIZE(rk3308_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk3568_i2s_soc_data = {
+	.softrst_offset = 0x0400,
+	.configs = rk3568_txrx_config,
+	.config_count = ARRAY_SIZE(rk3568_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rv1126_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = rv1126_txrx_config,
+	.config_count = ARRAY_SIZE(rv1126_txrx_config),
+	.init = common_soc_init,
+};
+
+static const struct of_device_id rockchip_i2s_tdm_match[] = {
+	{ .compatible = "rockchip,px30-i2s-tdm", .data = &px30_i2s_soc_data },
+	{ .compatible = "rockchip,rk1808-i2s-tdm", .data = &rk1808_i2s_soc_data },
+	{ .compatible = "rockchip,rk3308-i2s-tdm", .data = &rk3308_i2s_soc_data },
+	{ .compatible = "rockchip,rk3568-i2s-tdm", .data = &rk3568_i2s_soc_data },
+	{ .compatible = "rockchip,rv1126-i2s-tdm", .data = &rv1126_i2s_soc_data },
+	{},
+};
+
+static int of_i2s_resetid_get(struct device_node *node,
+			      const char *id)
+{
+	struct of_phandle_args args;
+	int index = 0;
+	int ret;
+
+	if (id)
+		index = of_property_match_string(node,
+						 "reset-names", id);
+	ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
+					 index, &args);
+	if (ret)
+		return ret;
+
+	return args.args[0];
+}
+
+static struct snd_soc_dai_driver i2s_tdm_dai = {
+	.probe = rockchip_i2s_tdm_dai_probe,
+	.playback = {
+		.stream_name  = "Playback",
+		.channels_min = 2,
+		.channels_max = 8,
+		.rates        = SNDRV_PCM_RATE_8000_192000,
+		.formats      = (SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S20_3LE |
+				SNDRV_PCM_FMTBIT_S24_LE |
+				SNDRV_PCM_FMTBIT_S32_LE),
+	},
+	.capture = {
+		.stream_name  = "Capture",
+		.channels_min = 2,
+		.channels_max = 8,
+		.rates        = SNDRV_PCM_RATE_8000_192000,
+		.formats      = (SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S20_3LE |
+				SNDRV_PCM_FMTBIT_S24_LE |
+				SNDRV_PCM_FMTBIT_S32_LE),
+	},
+	.ops = &rockchip_i2s_tdm_dai_ops,
+};
+
+static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev *i2s_tdm,
+				       int num,
+				       bool is_rx_path)
+{
+	unsigned int *i2s_data;
+	int i, j;
+
+	if (is_rx_path)
+		i2s_data = i2s_tdm->i2s_sdis;
+	else
+		i2s_data = i2s_tdm->i2s_sdos;
+
+	for (i = 0; i < num; i++) {
+		if (i2s_data[i] > CH_GRP_MAX - 1) {
+			dev_err(i2s_tdm->dev,
+				"%s path i2s_data[%d]: %d is overflow, max is: %d\n",
+				is_rx_path ? "RX" : "TX",
+				i, i2s_data[i], CH_GRP_MAX);
+			return -EINVAL;
+		}
+
+		for (j = 0; j < num; j++) {
+			if (i == j)
+				continue;
+
+			if (i2s_data[i] == i2s_data[j]) {
+				dev_err(i2s_tdm->dev,
+					"%s path invalid routed i2s_data: [%d]%d == [%d]%d\n",
+					is_rx_path ? "RX" : "TX",
+					i, i2s_data[i],
+					j, i2s_data[j]);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void rockchip_i2s_tdm_tx_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					    int num)
+{
+	int idx;
+
+	for (idx = 0; idx < num; idx++) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_PATH_MASK(idx),
+				   I2S_TXCR_PATH(idx, i2s_tdm->i2s_sdos[idx]));
+	}
+}
+
+static void rockchip_i2s_tdm_rx_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					    int num)
+{
+	int idx;
+
+	for (idx = 0; idx < num; idx++) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_PATH_MASK(idx),
+				   I2S_RXCR_PATH(idx, i2s_tdm->i2s_sdis[idx]));
+	}
+}
+
+static void rockchip_i2s_tdm_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					 int num, bool is_rx_path)
+{
+	if (is_rx_path)
+		rockchip_i2s_tdm_rx_path_config(i2s_tdm, num);
+	else
+		rockchip_i2s_tdm_tx_path_config(i2s_tdm, num);
+}
+
+static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					 struct device_node *np,
+					 bool is_rx_path)
+{
+	char *i2s_tx_path_prop = "rockchip,i2s-tx-route";
+	char *i2s_rx_path_prop = "rockchip,i2s-rx-route";
+	char *i2s_path_prop;
+	unsigned int *i2s_data;
+	int num, ret = 0;
+
+	if (is_rx_path) {
+		i2s_path_prop = i2s_rx_path_prop;
+		i2s_data = i2s_tdm->i2s_sdis;
+	} else {
+		i2s_path_prop = i2s_tx_path_prop;
+		i2s_data = i2s_tdm->i2s_sdos;
+	}
+
+	num = of_count_phandle_with_args(np, i2s_path_prop, NULL);
+	if (num < 0) {
+		if (num != -ENOENT) {
+			dev_err(i2s_tdm->dev,
+				"Failed to read '%s' num: %d\n",
+				i2s_path_prop, num);
+			ret = num;
+		}
+		return ret;
+	} else if (num != CH_GRP_MAX) {
+		dev_err(i2s_tdm->dev,
+			"The num: %d should be: %d\n", num, CH_GRP_MAX);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_array(np, i2s_path_prop,
+					 i2s_data, num);
+	if (ret < 0) {
+		dev_err(i2s_tdm->dev,
+			"Failed to read '%s': %d\n",
+			i2s_path_prop, ret);
+		return ret;
+	}
+
+	ret = rockchip_i2s_tdm_path_check(i2s_tdm, num, is_rx_path);
+	if (ret < 0) {
+		dev_err(i2s_tdm->dev,
+			"Failed to check i2s data bus: %d\n", ret);
+		return ret;
+	}
+
+	rockchip_i2s_tdm_path_config(i2s_tdm, num, is_rx_path);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_tx_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					    struct device_node *np)
+{
+	return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 0);
+}
+
+static int rockchip_i2s_tdm_rx_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					    struct device_node *np)
+{
+	return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 1);
+}
+
+static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *cru_node;
+	const struct of_device_id *of_id;
+	struct rk_i2s_tdm_dev *i2s_tdm;
+	struct resource *res;
+	void __iomem *regs;
+	int ret;
+	int val;
+
+	i2s_tdm = devm_kzalloc(&pdev->dev, sizeof(*i2s_tdm), GFP_KERNEL);
+	if (!i2s_tdm)
+		return -ENOMEM;
+
+	i2s_tdm->dev = &pdev->dev;
+
+	of_id = of_match_device(rockchip_i2s_tdm_match, &pdev->dev);
+	if (!of_id || !of_id->data)
+		return -EINVAL;
+
+	spin_lock_init(&i2s_tdm->lock);
+	i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data;
+
+	i2s_tdm->frame_width = 64;
+	if (!of_property_read_u32(node, "rockchip,frame-width", &val)) {
+		if (val >= 32 && (val % 2 == 0) && val <= 512) {
+			i2s_tdm->frame_width = val;
+		} else {
+			dev_err(i2s_tdm->dev, "unsupported frame width: '%d'\n",
+				val);
+			return -EINVAL;
+		}
+	}
+
+	i2s_tdm->clk_trcm = TRCM_TXRX;
+	if (of_property_read_bool(node, "rockchip,trcm-sync-tx-only"))
+		i2s_tdm->clk_trcm = TRCM_TX;
+	if (of_property_read_bool(node, "rockchip,trcm-sync-rx-only")) {
+		if (i2s_tdm->clk_trcm) {
+			dev_err(i2s_tdm->dev, "invalid trcm-sync configuration\n");
+			return -EINVAL;
+		}
+		i2s_tdm->clk_trcm = TRCM_RX;
+	}
+	if (i2s_tdm->clk_trcm != TRCM_TXRX)
+		i2s_tdm_dai.symmetric_rate = 1;
+
+	i2s_tdm->tdm_fsync_half_frame =
+		of_property_read_bool(node, "rockchip,tdm-fsync-half-frame");
+
+	i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
+	if (IS_ERR(i2s_tdm->grf))
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->grf),
+				     "Error in rockchip,grf\n");
+
+	if (i2s_tdm->clk_trcm != TRCM_TXRX) {
+		cru_node = of_parse_phandle(node, "rockchip,cru", 0);
+		i2s_tdm->cru_base = of_iomap(cru_node, 0);
+		of_node_put(cru_node);
+		if (!i2s_tdm->cru_base) {
+			dev_err(i2s_tdm->dev,
+				"Missing or unsupported rockchip,cru node\n");
+			return -ENOENT;
+		}
+
+		i2s_tdm->tx_reset_id = of_i2s_resetid_get(node, "tx-m");
+		i2s_tdm->rx_reset_id = of_i2s_resetid_get(node, "rx-m");
+	}
+
+	i2s_tdm->tx_reset = devm_reset_control_get(&pdev->dev, "tx-m");
+	if (IS_ERR(i2s_tdm->tx_reset)) {
+		ret = PTR_ERR(i2s_tdm->tx_reset);
+		if (ret != -ENOENT)
+			return dev_err_probe(i2s_tdm->dev, ret,
+					     "Error in tx-m reset control\n");
+	}
+
+	i2s_tdm->rx_reset = devm_reset_control_get(&pdev->dev, "rx-m");
+	if (IS_ERR(i2s_tdm->rx_reset)) {
+		ret = PTR_ERR(i2s_tdm->rx_reset);
+		if (ret != -ENOENT)
+			return dev_err_probe(i2s_tdm->dev, ret,
+					     "Error in rx-m reset control\n");
+	}
+
+	i2s_tdm->hclk = devm_clk_get(&pdev->dev, "hclk");
+	if (IS_ERR(i2s_tdm->hclk)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->hclk),
+				     "Failed to get clock hclk\n");
+	}
+
+	ret = clk_prepare_enable(i2s_tdm->hclk);
+	if (ret) {
+		return dev_err_probe(i2s_tdm->dev, ret,
+				     "Failed to enable clock hclk\n");
+	}
+
+	i2s_tdm->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx");
+	if (IS_ERR(i2s_tdm->mclk_tx)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->mclk_tx),
+				     "Failed to get clock mclk_tx\n");
+	}
+
+	i2s_tdm->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx");
+	if (IS_ERR(i2s_tdm->mclk_rx)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->mclk_rx),
+				     "Failed to get clock mclk_rx\n");
+	}
+
+	i2s_tdm->io_multiplex =
+		of_property_read_bool(node, "rockchip,io-multiplex");
+
+	i2s_tdm->mclk_calibrate =
+		of_property_read_bool(node, "rockchip,mclk-calibrate");
+	if (i2s_tdm->mclk_calibrate) {
+		i2s_tdm->mclk_tx_src = devm_clk_get(&pdev->dev, "mclk_tx_src");
+		if (IS_ERR(i2s_tdm->mclk_tx_src)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_tx_src),
+					     "Failed to get clock mclk_tx_src\n");
+		}
+		i2s_tdm->mclk_rx_src = devm_clk_get(&pdev->dev, "mclk_rx_src");
+		if (IS_ERR(i2s_tdm->mclk_rx_src)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_rx_src),
+					     "Failed to get clock mclk_rx_src\n");
+		}
+		i2s_tdm->mclk_root0 = devm_clk_get(&pdev->dev, "mclk_root0");
+		if (IS_ERR(i2s_tdm->mclk_root0)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_root0),
+					     "Failed to get clock mclk_root0\n");
+		}
+		i2s_tdm->mclk_root1 = devm_clk_get(&pdev->dev, "mclk_root1");
+		if (IS_ERR(i2s_tdm->mclk_root1)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_root1),
+					     "Failed to get clock mclk_root1\n");
+		}
+
+		i2s_tdm->mclk_root0_initial_freq = clk_get_rate(i2s_tdm->mclk_root0);
+		i2s_tdm->mclk_root1_initial_freq = clk_get_rate(i2s_tdm->mclk_root1);
+		i2s_tdm->mclk_root0_freq = i2s_tdm->mclk_root0_initial_freq;
+		i2s_tdm->mclk_root1_freq = i2s_tdm->mclk_root1_initial_freq;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(regs),
+				     "Failed to get resource IORESOURCE_MEM\n");
+	}
+
+	i2s_tdm->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+					    &rockchip_i2s_tdm_regmap_config);
+	if (IS_ERR(i2s_tdm->regmap)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->regmap),
+				     "Failed to initialise regmap\n");
+	}
+
+	i2s_tdm->playback_dma_data.addr = res->start + I2S_TXDR;
+	i2s_tdm->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	i2s_tdm->playback_dma_data.maxburst = 8;
+
+	i2s_tdm->capture_dma_data.addr = res->start + I2S_RXDR;
+	i2s_tdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	i2s_tdm->capture_dma_data.maxburst = 8;
+
+	ret = rockchip_i2s_tdm_tx_path_prepare(i2s_tdm, node);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "I2S TX path prepare failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_i2s_tdm_rx_path_prepare(i2s_tdm, node);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "I2S RX path prepare failed: %d\n", ret);
+		return ret;
+	}
+
+	atomic_set(&i2s_tdm->refcount, 0);
+	dev_set_drvdata(&pdev->dev, i2s_tdm);
+
+	pm_runtime_enable(&pdev->dev);
+	if (!pm_runtime_enabled(&pdev->dev)) {
+		ret = i2s_tdm_runtime_resume(&pdev->dev);
+		if (ret)
+			goto err_pm_disable;
+	}
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
+			   I2S_DMACR_TDL(16));
+	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
+			   I2S_DMACR_RDL(16));
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, I2S_CKR_TRCM_MASK,
+			   i2s_tdm->clk_trcm << I2S_CKR_TRCM_SHIFT);
+
+	if (i2s_tdm->soc_data && i2s_tdm->soc_data->init)
+		i2s_tdm->soc_data->init(&pdev->dev, res->start);
+
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &rockchip_i2s_tdm_component,
+					      &i2s_tdm_dai, 1);
+
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register DAI\n");
+		goto err_suspend;
+	}
+
+	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register PCM\n");
+		return ret;
+	}
+
+	return 0;
+
+err_suspend:
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		i2s_tdm_runtime_suspend(&pdev->dev);
+err_pm_disable:
+	pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int rockchip_i2s_tdm_remove(struct platform_device *pdev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		i2s_tdm_runtime_suspend(&pdev->dev);
+
+	if (!IS_ERR(i2s_tdm->mclk_tx))
+		clk_prepare_enable(i2s_tdm->mclk_tx);
+	if (!IS_ERR(i2s_tdm->mclk_rx))
+		clk_prepare_enable(i2s_tdm->mclk_rx);
+	if (!IS_ERR(i2s_tdm->hclk))
+		clk_disable_unprepare(i2s_tdm->hclk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_i2s_tdm_suspend(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+
+	regcache_mark_dirty(i2s_tdm->regmap);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_resume(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0)
+		return ret;
+	ret = regcache_sync(i2s_tdm->regmap);
+	pm_runtime_put(dev);
+
+	return ret;
+}
+#endif
+
+static const struct dev_pm_ops rockchip_i2s_tdm_pm_ops = {
+	SET_RUNTIME_PM_OPS(i2s_tdm_runtime_suspend, i2s_tdm_runtime_resume,
+			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend,
+				rockchip_i2s_tdm_resume)
+};
+
+static struct platform_driver rockchip_i2s_tdm_driver = {
+	.probe = rockchip_i2s_tdm_probe,
+	.remove = rockchip_i2s_tdm_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table = of_match_ptr(rockchip_i2s_tdm_match),
+		.pm = &rockchip_i2s_tdm_pm_ops,
+	},
+};
+module_platform_driver(rockchip_i2s_tdm_driver);
+
+MODULE_DESCRIPTION("ROCKCHIP I2S/TDM ASoC Interface");
+MODULE_AUTHOR("Sugar Zhang <sugar.zhang at rock-chips.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, rockchip_i2s_tdm_match);
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.h b/sound/soc/rockchip/rockchip_i2s_tdm.h
new file mode 100644
index 000000000000..3a9d9e8db262
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.h
@@ -0,0 +1,398 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
+ *
+ * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
+ * Author: Sugar Zhang <sugar.zhang at rock-chips.com>
+ *
+ */
+
+#ifndef _ROCKCHIP_I2S_TDM_H
+#define _ROCKCHIP_I2S_TDM_H
+
+/*
+ * TXCR
+ * transmit operation control register
+ */
+#define I2S_TXCR_PATH_SHIFT(x)	(23 + (x) * 2)
+#define I2S_TXCR_PATH_MASK(x)	(0x3 << I2S_TXCR_PATH_SHIFT(x))
+#define I2S_TXCR_PATH(x, v)	((v) << I2S_TXCR_PATH_SHIFT(x))
+#define I2S_TXCR_RCNT_SHIFT	17
+#define I2S_TXCR_RCNT_MASK	(0x3f << I2S_TXCR_RCNT_SHIFT)
+#define I2S_TXCR_CSR_SHIFT	15
+#define I2S_TXCR_CSR(x)		(x << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_CSR_MASK	(3 << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_HWT		BIT(14)
+#define I2S_TXCR_SJM_SHIFT	12
+#define I2S_TXCR_SJM_R		(0 << I2S_TXCR_SJM_SHIFT)
+#define I2S_TXCR_SJM_L		(1 << I2S_TXCR_SJM_SHIFT)
+#define I2S_TXCR_FBM_SHIFT	11
+#define I2S_TXCR_FBM_MSB	(0 << I2S_TXCR_FBM_SHIFT)
+#define I2S_TXCR_FBM_LSB	(1 << I2S_TXCR_FBM_SHIFT)
+#define I2S_TXCR_IBM_SHIFT	9
+#define I2S_TXCR_IBM_NORMAL	(0 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_LSJM	(1 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_RSJM	(2 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_MASK	(3 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_PBM_SHIFT	7
+#define I2S_TXCR_PBM_MODE(x)	(x << I2S_TXCR_PBM_SHIFT)
+#define I2S_TXCR_PBM_MASK	(3 << I2S_TXCR_PBM_SHIFT)
+#define I2S_TXCR_TFS_SHIFT	5
+#define I2S_TXCR_TFS_I2S	(0 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_PCM	(1 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_TDM_PCM	(2 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_TDM_I2S	(3 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_MASK	(3 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_VDW_SHIFT	0
+#define I2S_TXCR_VDW(x)		((x - 1) << I2S_TXCR_VDW_SHIFT)
+#define I2S_TXCR_VDW_MASK	(0x1f << I2S_TXCR_VDW_SHIFT)
+
+/*
+ * RXCR
+ * receive operation control register
+ */
+#define I2S_RXCR_PATH_SHIFT(x)	(17 + (x) * 2)
+#define I2S_RXCR_PATH_MASK(x)	(0x3 << I2S_RXCR_PATH_SHIFT(x))
+#define I2S_RXCR_PATH(x, v)	((v) << I2S_RXCR_PATH_SHIFT(x))
+#define I2S_RXCR_CSR_SHIFT	15
+#define I2S_RXCR_CSR(x)		(x << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_CSR_MASK	(3 << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_HWT		BIT(14)
+#define I2S_RXCR_SJM_SHIFT	12
+#define I2S_RXCR_SJM_R		(0 << I2S_RXCR_SJM_SHIFT)
+#define I2S_RXCR_SJM_L		(1 << I2S_RXCR_SJM_SHIFT)
+#define I2S_RXCR_FBM_SHIFT	11
+#define I2S_RXCR_FBM_MSB	(0 << I2S_RXCR_FBM_SHIFT)
+#define I2S_RXCR_FBM_LSB	(1 << I2S_RXCR_FBM_SHIFT)
+#define I2S_RXCR_IBM_SHIFT	9
+#define I2S_RXCR_IBM_NORMAL	(0 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_LSJM	(1 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_RSJM	(2 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_MASK	(3 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_PBM_SHIFT	7
+#define I2S_RXCR_PBM_MODE(x)	(x << I2S_RXCR_PBM_SHIFT)
+#define I2S_RXCR_PBM_MASK	(3 << I2S_RXCR_PBM_SHIFT)
+#define I2S_RXCR_TFS_SHIFT	5
+#define I2S_RXCR_TFS_I2S	(0 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_PCM	(1 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_TDM_PCM	(2 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_TDM_I2S	(3 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_MASK	(3 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_VDW_SHIFT	0
+#define I2S_RXCR_VDW(x)		((x - 1) << I2S_RXCR_VDW_SHIFT)
+#define I2S_RXCR_VDW_MASK	(0x1f << I2S_RXCR_VDW_SHIFT)
+
+/*
+ * CKR
+ * clock generation register
+ */
+#define I2S_CKR_TRCM_SHIFT	28
+#define I2S_CKR_TRCM(x)	(x << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_TXRX	(0 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_TXONLY	(1 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_RXONLY	(2 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_MASK	(3 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_MSS_SHIFT	27
+#define I2S_CKR_MSS_MASTER	(0 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_MSS_SLAVE	(1 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_MSS_MASK	(1 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_CKP_SHIFT	26
+#define I2S_CKR_CKP_NORMAL	(0 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_CKP_INVERTED	(1 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_CKP_MASK	(1 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_RLP_SHIFT	25
+#define I2S_CKR_RLP_NORMAL	(0 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_RLP_INVERTED	(1 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_RLP_MASK	(1 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_TLP_SHIFT	24
+#define I2S_CKR_TLP_NORMAL	(0 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_TLP_INVERTED	(1 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_TLP_MASK	(1 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_MDIV_SHIFT	16
+#define I2S_CKR_MDIV(x)		((x - 1) << I2S_CKR_MDIV_SHIFT)
+#define I2S_CKR_MDIV_MASK	(0xff << I2S_CKR_MDIV_SHIFT)
+#define I2S_CKR_RSD_SHIFT	8
+#define I2S_CKR_RSD(x)		((x - 1) << I2S_CKR_RSD_SHIFT)
+#define I2S_CKR_RSD_MASK	(0xff << I2S_CKR_RSD_SHIFT)
+#define I2S_CKR_TSD_SHIFT	0
+#define I2S_CKR_TSD(x)		((x - 1) << I2S_CKR_TSD_SHIFT)
+#define I2S_CKR_TSD_MASK	(0xff << I2S_CKR_TSD_SHIFT)
+
+/*
+ * FIFOLR
+ * FIFO level register
+ */
+#define I2S_FIFOLR_RFL_SHIFT	24
+#define I2S_FIFOLR_RFL_MASK	(0x3f << I2S_FIFOLR_RFL_SHIFT)
+#define I2S_FIFOLR_TFL3_SHIFT	18
+#define I2S_FIFOLR_TFL3_MASK	(0x3f << I2S_FIFOLR_TFL3_SHIFT)
+#define I2S_FIFOLR_TFL2_SHIFT	12
+#define I2S_FIFOLR_TFL2_MASK	(0x3f << I2S_FIFOLR_TFL2_SHIFT)
+#define I2S_FIFOLR_TFL1_SHIFT	6
+#define I2S_FIFOLR_TFL1_MASK	(0x3f << I2S_FIFOLR_TFL1_SHIFT)
+#define I2S_FIFOLR_TFL0_SHIFT	0
+#define I2S_FIFOLR_TFL0_MASK	(0x3f << I2S_FIFOLR_TFL0_SHIFT)
+
+/*
+ * DMACR
+ * DMA control register
+ */
+#define I2S_DMACR_RDE_SHIFT	24
+#define I2S_DMACR_RDE_DISABLE	(0 << I2S_DMACR_RDE_SHIFT)
+#define I2S_DMACR_RDE_ENABLE	(1 << I2S_DMACR_RDE_SHIFT)
+#define I2S_DMACR_RDL_SHIFT	16
+#define I2S_DMACR_RDL(x)	((x - 1) << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_RDL_MASK	(0x1f << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_TDE_SHIFT	8
+#define I2S_DMACR_TDE_DISABLE	(0 << I2S_DMACR_TDE_SHIFT)
+#define I2S_DMACR_TDE_ENABLE	(1 << I2S_DMACR_TDE_SHIFT)
+#define I2S_DMACR_TDL_SHIFT	0
+#define I2S_DMACR_TDL(x)	((x) << I2S_DMACR_TDL_SHIFT)
+#define I2S_DMACR_TDL_MASK	(0x1f << I2S_DMACR_TDL_SHIFT)
+
+/*
+ * INTCR
+ * interrupt control register
+ */
+#define I2S_INTCR_RFT_SHIFT	20
+#define I2S_INTCR_RFT(x)	((x - 1) << I2S_INTCR_RFT_SHIFT)
+#define I2S_INTCR_RXOIC		BIT(18)
+#define I2S_INTCR_RXOIE_SHIFT	17
+#define I2S_INTCR_RXOIE_DISABLE	(0 << I2S_INTCR_RXOIE_SHIFT)
+#define I2S_INTCR_RXOIE_ENABLE	(1 << I2S_INTCR_RXOIE_SHIFT)
+#define I2S_INTCR_RXFIE_SHIFT	16
+#define I2S_INTCR_RXFIE_DISABLE	(0 << I2S_INTCR_RXFIE_SHIFT)
+#define I2S_INTCR_RXFIE_ENABLE	(1 << I2S_INTCR_RXFIE_SHIFT)
+#define I2S_INTCR_TFT_SHIFT	4
+#define I2S_INTCR_TFT(x)	((x - 1) << I2S_INTCR_TFT_SHIFT)
+#define I2S_INTCR_TFT_MASK	(0x1f << I2S_INTCR_TFT_SHIFT)
+#define I2S_INTCR_TXUIC		BIT(2)
+#define I2S_INTCR_TXUIE_SHIFT	1
+#define I2S_INTCR_TXUIE_DISABLE	(0 << I2S_INTCR_TXUIE_SHIFT)
+#define I2S_INTCR_TXUIE_ENABLE	(1 << I2S_INTCR_TXUIE_SHIFT)
+
+/*
+ * INTSR
+ * interrupt status register
+ */
+#define I2S_INTSR_TXEIE_SHIFT	0
+#define I2S_INTSR_TXEIE_DISABLE	(0 << I2S_INTSR_TXEIE_SHIFT)
+#define I2S_INTSR_TXEIE_ENABLE	(1 << I2S_INTSR_TXEIE_SHIFT)
+#define I2S_INTSR_RXOI_SHIFT	17
+#define I2S_INTSR_RXOI_INA	(0 << I2S_INTSR_RXOI_SHIFT)
+#define I2S_INTSR_RXOI_ACT	(1 << I2S_INTSR_RXOI_SHIFT)
+#define I2S_INTSR_RXFI_SHIFT	16
+#define I2S_INTSR_RXFI_INA	(0 << I2S_INTSR_RXFI_SHIFT)
+#define I2S_INTSR_RXFI_ACT	(1 << I2S_INTSR_RXFI_SHIFT)
+#define I2S_INTSR_TXUI_SHIFT	1
+#define I2S_INTSR_TXUI_INA	(0 << I2S_INTSR_TXUI_SHIFT)
+#define I2S_INTSR_TXUI_ACT	(1 << I2S_INTSR_TXUI_SHIFT)
+#define I2S_INTSR_TXEI_SHIFT	0
+#define I2S_INTSR_TXEI_INA	(0 << I2S_INTSR_TXEI_SHIFT)
+#define I2S_INTSR_TXEI_ACT	(1 << I2S_INTSR_TXEI_SHIFT)
+
+/*
+ * XFER
+ * Transfer start register
+ */
+#define I2S_XFER_RXS_SHIFT	1
+#define I2S_XFER_RXS_STOP	(0 << I2S_XFER_RXS_SHIFT)
+#define I2S_XFER_RXS_START	(1 << I2S_XFER_RXS_SHIFT)
+#define I2S_XFER_TXS_SHIFT	0
+#define I2S_XFER_TXS_STOP	(0 << I2S_XFER_TXS_SHIFT)
+#define I2S_XFER_TXS_START	(1 << I2S_XFER_TXS_SHIFT)
+
+/*
+ * CLR
+ * clear SCLK domain logic register
+ */
+#define I2S_CLR_RXC	BIT(1)
+#define I2S_CLR_TXC	BIT(0)
+
+/*
+ * TXDR
+ * Transimt FIFO data register, write only.
+ */
+#define I2S_TXDR_MASK	(0xff)
+
+/*
+ * RXDR
+ * Receive FIFO data register, write only.
+ */
+#define I2S_RXDR_MASK	(0xff)
+
+/*
+ * TDM_CTRL
+ * TDM ctrl register
+ */
+#define TDM_FSYNC_WIDTH_SEL1_MSK	GENMASK(20, 18)
+#define TDM_FSYNC_WIDTH_SEL1(x)		((x - 1) << 18)
+#define TDM_FSYNC_WIDTH_SEL0_MSK	BIT(17)
+#define TDM_FSYNC_WIDTH_HALF_FRAME	0
+#define TDM_FSYNC_WIDTH_ONE_FRAME	BIT(17)
+#define TDM_SHIFT_CTRL_MSK		GENMASK(16, 14)
+#define TDM_SHIFT_CTRL(x)		((x) << 14)
+#define TDM_SLOT_BIT_WIDTH_MSK		GENMASK(13, 9)
+#define TDM_SLOT_BIT_WIDTH(x)		((x - 1) << 9)
+#define TDM_FRAME_WIDTH_MSK		GENMASK(8, 0)
+#define TDM_FRAME_WIDTH(x)		((x - 1) << 0)
+
+/*
+ * CLKDIV
+ * Mclk div register
+ */
+#define I2S_CLKDIV_TXM_SHIFT	0
+#define I2S_CLKDIV_TXM(x)		((x - 1) << I2S_CLKDIV_TXM_SHIFT)
+#define I2S_CLKDIV_TXM_MASK	(0xff << I2S_CLKDIV_TXM_SHIFT)
+#define I2S_CLKDIV_RXM_SHIFT	8
+#define I2S_CLKDIV_RXM(x)		((x - 1) << I2S_CLKDIV_RXM_SHIFT)
+#define I2S_CLKDIV_RXM_MASK	(0xff << I2S_CLKDIV_RXM_SHIFT)
+
+/* Clock divider id */
+enum {
+	ROCKCHIP_DIV_MCLK = 0,
+	ROCKCHIP_DIV_BCLK,
+};
+
+/* channel select */
+#define I2S_CSR_SHIFT	15
+#define I2S_CHN_2	(0 << I2S_CSR_SHIFT)
+#define I2S_CHN_4	(1 << I2S_CSR_SHIFT)
+#define I2S_CHN_6	(2 << I2S_CSR_SHIFT)
+#define I2S_CHN_8	(3 << I2S_CSR_SHIFT)
+
+/* io direction cfg register */
+#define I2S_IO_DIRECTION_MASK	(7)
+#define I2S_IO_8CH_OUT_2CH_IN	(7)
+#define I2S_IO_6CH_OUT_4CH_IN	(3)
+#define I2S_IO_4CH_OUT_6CH_IN	(1)
+#define I2S_IO_2CH_OUT_8CH_IN	(0)
+
+/* I2S REGS */
+#define I2S_TXCR	(0x0000)
+#define I2S_RXCR	(0x0004)
+#define I2S_CKR		(0x0008)
+#define I2S_TXFIFOLR	(0x000c)
+#define I2S_DMACR	(0x0010)
+#define I2S_INTCR	(0x0014)
+#define I2S_INTSR	(0x0018)
+#define I2S_XFER	(0x001c)
+#define I2S_CLR		(0x0020)
+#define I2S_TXDR	(0x0024)
+#define I2S_RXDR	(0x0028)
+#define I2S_RXFIFOLR	(0x002c)
+#define I2S_TDM_TXCR	(0x0030)
+#define I2S_TDM_RXCR	(0x0034)
+#define I2S_CLKDIV	(0x0038)
+
+#define HIWORD_UPDATE(v, h, l)	(((v) << (l)) | (GENMASK((h), (l)) << 16))
+
+/* PX30 GRF CONFIGS */
+#define PX30_I2S0_CLK_IN_SRC_FROM_TX		HIWORD_UPDATE(1, 13, 12)
+#define PX30_I2S0_CLK_IN_SRC_FROM_RX		HIWORD_UPDATE(2, 13, 12)
+#define PX30_I2S0_MCLK_OUT_SRC_FROM_TX		HIWORD_UPDATE(1, 5, 5)
+#define PX30_I2S0_MCLK_OUT_SRC_FROM_RX		HIWORD_UPDATE(0, 5, 5)
+
+#define PX30_I2S0_CLK_TXONLY \
+	(PX30_I2S0_MCLK_OUT_SRC_FROM_TX | PX30_I2S0_CLK_IN_SRC_FROM_TX)
+
+#define PX30_I2S0_CLK_RXONLY \
+	(PX30_I2S0_MCLK_OUT_SRC_FROM_RX | PX30_I2S0_CLK_IN_SRC_FROM_RX)
+
+/* RK1808 GRF CONFIGS */
+#define RK1808_I2S0_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 2, 2)
+#define RK1808_I2S0_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 2, 2)
+#define RK1808_I2S0_CLK_IN_SRC_FROM_TX		HIWORD_UPDATE(1, 1, 0)
+#define RK1808_I2S0_CLK_IN_SRC_FROM_RX		HIWORD_UPDATE(2, 1, 0)
+
+#define RK1808_I2S0_CLK_TXONLY \
+	(RK1808_I2S0_MCLK_OUT_SRC_FROM_TX | RK1808_I2S0_CLK_IN_SRC_FROM_TX)
+
+#define RK1808_I2S0_CLK_RXONLY \
+	(RK1808_I2S0_MCLK_OUT_SRC_FROM_RX | RK1808_I2S0_CLK_IN_SRC_FROM_RX)
+
+/* RK3308 GRF CONFIGS */
+#define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 10, 10)
+#define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 10, 10)
+#define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX	HIWORD_UPDATE(1, 9, 9)
+#define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_RX	HIWORD_UPDATE(0, 9, 9)
+#define RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_RX	HIWORD_UPDATE(1, 8, 8)
+#define RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_TX	HIWORD_UPDATE(0, 8, 8)
+#define RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 2, 2)
+#define RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 2, 2)
+#define RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_TX	HIWORD_UPDATE(1, 1, 1)
+#define RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_RX	HIWORD_UPDATE(0, 1, 1)
+#define RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_RX	HIWORD_UPDATE(1, 0, 0)
+#define RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_TX	HIWORD_UPDATE(0, 0, 0)
+
+#define RK3308_I2S0_CLK_TXONLY \
+	(RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX | \
+	RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX | \
+	RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_TX)
+
+#define RK3308_I2S0_CLK_RXONLY \
+	(RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX | \
+	RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_RX | \
+	RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_RX)
+
+#define RK3308_I2S1_CLK_TXONLY \
+	(RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_TX | \
+	RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_TX | \
+	RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_TX)
+
+#define RK3308_I2S1_CLK_RXONLY \
+	(RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_RX | \
+	RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_RX | \
+	RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_RX)
+
+/* RK3568 GRF CONFIGS */
+#define RK3568_I2S1_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(1, 5, 5)
+#define RK3568_I2S1_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(0, 5, 5)
+
+#define RK3568_I2S1_CLK_TXONLY \
+	RK3568_I2S1_MCLK_OUT_SRC_FROM_TX
+
+#define RK3568_I2S1_CLK_RXONLY \
+	RK3568_I2S1_MCLK_OUT_SRC_FROM_RX
+
+#define RK3568_I2S3_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(1, 15, 15)
+#define RK3568_I2S3_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(0, 15, 15)
+#define RK3568_I2S3_SCLK_SRC_FROM_TX		HIWORD_UPDATE(1, 7, 7)
+#define RK3568_I2S3_SCLK_SRC_FROM_RX		HIWORD_UPDATE(0, 7, 7)
+#define RK3568_I2S3_LRCK_SRC_FROM_TX		HIWORD_UPDATE(1, 6, 6)
+#define RK3568_I2S3_LRCK_SRC_FROM_RX		HIWORD_UPDATE(0, 6, 6)
+
+#define RK3568_I2S3_MCLK_TXONLY \
+	RK3568_I2S3_MCLK_OUT_SRC_FROM_TX
+
+#define RK3568_I2S3_CLK_TXONLY \
+	(RK3568_I2S3_SCLK_SRC_FROM_TX | \
+	RK3568_I2S3_LRCK_SRC_FROM_TX)
+
+#define RK3568_I2S3_MCLK_RXONLY \
+	RK3568_I2S3_MCLK_OUT_SRC_FROM_RX
+
+#define RK3568_I2S3_CLK_RXONLY \
+	(RK3568_I2S3_SCLK_SRC_FROM_RX | \
+	RK3568_I2S3_LRCK_SRC_FROM_RX)
+
+#define RK3568_I2S3_MCLK_IE			HIWORD_UPDATE(0, 3, 3)
+#define RK3568_I2S3_MCLK_OE			HIWORD_UPDATE(1, 3, 3)
+#define RK3568_I2S2_MCLK_IE			HIWORD_UPDATE(0, 2, 2)
+#define RK3568_I2S2_MCLK_OE			HIWORD_UPDATE(1, 2, 2)
+#define RK3568_I2S1_MCLK_TX_IE			HIWORD_UPDATE(0, 1, 1)
+#define RK3568_I2S1_MCLK_TX_OE			HIWORD_UPDATE(1, 1, 1)
+#define RK3568_I2S1_MCLK_RX_IE			HIWORD_UPDATE(0, 0, 0)
+#define RK3568_I2S1_MCLK_RX_OE			HIWORD_UPDATE(1, 0, 0)
+
+/* RV1126 GRF CONFIGS */
+#define RV1126_I2S0_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 9, 9)
+#define RV1126_I2S0_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 9, 9)
+
+#define RV1126_I2S0_CLK_TXONLY \
+	RV1126_I2S0_MCLK_OUT_SRC_FROM_TX
+
+#define RV1126_I2S0_CLK_RXONLY \
+	RV1126_I2S0_MCLK_OUT_SRC_FROM_RX
+
+#endif /* _ROCKCHIP_I2S_TDM_H */
-- 
2.32.0



From frattaroli.nicolas at gmail.com  Fri Aug 20 11:27:29 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Fri, 20 Aug 2021 20:27:29 +0200
Subject: [PATCH v2 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210820182731.29370-3-frattaroli.nicolas@gmail.com>

This adds the YAML bindings for the Rockchip I2S/TDM audio driver.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 .../bindings/sound/rockchip,i2s-tdm.yaml      | 193 ++++++++++++++++++
 1 file changed, 193 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml

diff --git a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
new file mode 100644
index 000000000000..1e8c1500ba40
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
@@ -0,0 +1,193 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip I2S/TDM Controller
+
+description:
+  The Rockchip I2S/TDM Controller is a Time Division Multiplexed
+  audio interface found in various Rockchip SoCs, allowing up
+  to 8 channels of audio over a serial interface.
+
+maintainers:
+  - Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,px30-i2s-tdm
+      - rockchip,rk1808-i2s-tdm
+      - rockchip,rk3308-i2s-tdm
+      - rockchip,rk3568-i2s-tdm
+      - rockchip,rv1126-i2s-tdm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  dmas:
+    minItems: 1
+    maxItems: 2
+
+  dma-names:
+    minItems: 1
+    items:
+      - const: rx
+      - const: tx
+
+  clocks:
+    items:
+      - description: clock for TX
+      - description: clock for RX
+      - description: AHB clock driving the interface
+
+  clock-names:
+    items:
+      - const: mclk_tx
+      - const: mclk_rx
+      - const: hclk
+
+  rockchip,frame-width:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 64
+    minimum: 32
+    maximum: 512
+    description:
+      Width of a frame, usually slot width multiplied by number of slots.
+      Must be even.
+
+  resets:
+    items:
+      - description: reset for TX
+      - description: reset for RX
+
+  reset-names:
+    items:
+      - const: tx-m
+      - const: rx-m
+
+  rockchip,cru:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the cru.
+      Required if both playback and capture are used, i.e. if rockchip,clk-trcm
+      is 0.
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the GRF register.
+
+  rockchip,mclk-calibrate:
+    description:
+      Enable mclk source calibration.
+    type: boolean
+
+  rockchip,trcm-sync-tx-only:
+    type: boolean
+    description: Use TX BCLK/LRCK for both TX and RX.
+
+  rockchip,trcm-sync-rx-only:
+    type: boolean
+    description: Use RX BCLK/LRCK for both TX and RX.
+
+  "#sound-dai-cells":
+    const: 0
+
+  rockchip,i2s-rx-route:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Defines the mapping of I2S RX sdis to I2S data bus lines.
+      By default, they are mapped one-to-one.
+    items:
+      - description: which sdi to connect to data line 0
+      - description: which sdi to connect to data line 1
+      - description: which sdi to connect to data line 2
+      - description: which sdi to connect to data line 3
+
+  rockchip,i2s-tx-route:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Defines the mapping of I2S TX sdos to I2S data bus lines.
+      By default, they are mapped one-to-one.
+    items:
+      - description: which sdo to connect to data line 0
+      - description: which sdo to connect to data line 1
+      - description: which sdo to connect to data line 2
+      - description: which sdo to connect to data line 3
+
+  rockchip,tdm-fsync-half-frame:
+    description: Whether to use half frame fsync.
+    type: boolean
+
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - dmas
+  - dma-names
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - rockchip,grf
+  - "#sound-dai-cells"
+
+allOf:
+  - if:
+      properties:
+        rockchip,trcm-sync-tx-only: false
+        rockchip,trcm-sync-rx-only: false
+    then:
+      required:
+        - rockchip,cru
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3568-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/pinctrl/rockchip.h>
+
+    foo {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        i2s at fe410000 {
+            compatible = "rockchip,rk3568-i2s-tdm";
+            reg = <0x0 0xfe410000 0x0 0x1000>;
+            interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
+                     <&cru HCLK_I2S1_8CH>;
+            clock-names = "mclk_tx", "mclk_rx", "hclk";
+            dmas = <&dmac1 3>, <&dmac1 2>;
+            dma-names = "rx", "tx";
+            resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+            reset-names = "tx-m", "rx-m";
+            rockchip,trcm-sync-tx-only;
+            rockchip,cru = <&cru>;
+            rockchip,grf = <&grf>;
+            #sound-dai-cells = <0>;
+            pinctrl-names = "default";
+            pinctrl-0 =
+                <&i2s1m0_sclktx
+                &i2s1m0_sclkrx
+                &i2s1m0_lrcktx
+                &i2s1m0_lrckrx
+                &i2s1m0_sdi0
+                &i2s1m0_sdi1
+                &i2s1m0_sdi2
+                &i2s1m0_sdi3
+                &i2s1m0_sdo0
+                &i2s1m0_sdo1
+                &i2s1m0_sdo2
+                &i2s1m0_sdo3>;
+            status = "okay";
+        };
+    };
-- 
2.32.0



From frattaroli.nicolas at gmail.com  Fri Aug 20 11:27:30 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Fri, 20 Aug 2021 20:27:30 +0200
Subject: [PATCH v2 3/4] arm64: dts: rockchip: add i2s1 on rk356x
In-Reply-To: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210820182731.29370-4-frattaroli.nicolas@gmail.com>

This adds the necessary device tree node on rk3566 and rk3568
to enable the I2S1 TDM audio controller.

I2S0 has not been added, as it is connected to HDMI and there is
no way to test that it's working without a functioning video
clock (read: VOP2 driver).

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 26 ++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 13b185e1dc5f..fce760996a64 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -559,6 +559,32 @@ sdhci: mmc at fe310000 {
 		status = "disabled";
 	};
 
+	i2s1_8ch: i2s at fe410000 {
+		compatible = "rockchip,rk3568-i2s-tdm";
+		reg = <0x0 0xfe410000 0x0 0x1000>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+		assigned-clocks = <&cru CLK_I2S1_8CH_TX_SRC>, <&cru CLK_I2S1_8CH_RX_SRC>;
+		assigned-clock-rates = <1188000000>, <1188000000>;
+		clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
+		<&cru HCLK_I2S1_8CH>;
+		clock-names = "mclk_tx", "mclk_rx", "hclk";
+		dmas = <&dmac1 3>, <&dmac1 2>;
+		dma-names = "rx", "tx";
+		resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+		reset-names = "tx-m", "rx-m";
+		rockchip,cru = <&cru>;
+		rockchip,grf = <&grf>;
+		#sound-dai-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_sclkrx
+			     &i2s1m0_lrcktx &i2s1m0_lrckrx
+			     &i2s1m0_sdi0   &i2s1m0_sdi1
+			     &i2s1m0_sdi2   &i2s1m0_sdi3
+			     &i2s1m0_sdo0   &i2s1m0_sdo1
+			     &i2s1m0_sdo2   &i2s1m0_sdo3>;
+		status = "disabled";
+	};
+
 	dmac0: dmac at fe530000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xfe530000 0x0 0x4000>;
-- 
2.32.0



From frattaroli.nicolas at gmail.com  Fri Aug 20 11:27:31 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Fri, 20 Aug 2021 20:27:31 +0200
Subject: [PATCH v2 4/4] arm64: dts: rockchip: add analog audio on Quartz64
In-Reply-To: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210820182731.29370-5-frattaroli.nicolas@gmail.com>

On the Quartz64 Model A, the I2S1 TDM controller is connected
to the rk817 codec in I2S mode. Enabling it and adding the
necessary simple-sound-card and codec nodes allows for analog
audio output on the PINE64 Quartz64 Model A SBC.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 35 ++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index b239f314b38a..c974b0e22ac0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -50,6 +50,20 @@ led-diy {
 		};
 	};
 
+	rk817-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,name = "Analog RK817";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s1_8ch>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&rk817>;
+		};
+	};
+
 	vcc12v_dcin: vcc12v_dcin {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc12v_dcin";
@@ -174,8 +188,13 @@ rk817: pmic at 20 {
 		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
 		clock-output-names = "rk808-clkout1", "rk808-clkout2";
 
+		#sound-dai-cells = <0>;
+		clock-names = "mclk";
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&pmic_int_l>;
+		pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
 		rockchip,system-power-controller;
 		wakeup-source;
 		#clock-cells = <1>;
@@ -364,9 +383,23 @@ regulator-state-mem {
 				};
 			};
 		};
+
+		rk817_codec: codec {
+		};
+
 	};
 };
 
+&i2s1_8ch {
+	status = "okay";
+	rockchip,trcm-sync-tx-only;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s1m0_sclktx
+		     &i2s1m0_lrcktx
+		     &i2s1m0_sdi0
+		     &i2s1m0_sdo0>;
+};
+
 &mdio1 {
 	rgmii_phy1: ethernet-phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
-- 
2.32.0



From mathieu.desnoyers at efficios.com  Fri Aug 20 11:31:38 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Fri, 20 Aug 2021 14:31:38 -0400 (EDT)
Subject: [PATCH 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <YR7qXvnI/AQM10gU@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-5-seanjc@google.com>
 <1540548616.19739.1629409956315.JavaMail.zimbra@efficios.com>
 <YR7qXvnI/AQM10gU@google.com>
Message-ID: <407716135.20250.1629484298288.JavaMail.zimbra@efficios.com>

----- On Aug 19, 2021, at 7:33 PM, Sean Christopherson seanjc at google.com wrote:

> On Thu, Aug 19, 2021, Mathieu Desnoyers wrote:
>> ----- On Aug 17, 2021, at 8:12 PM, Sean Christopherson seanjc at google.com wrote:
>> 
>> > Add a test to verify an rseq's CPU ID is updated correctly if the task is
>> > migrated while the kernel is handling KVM_RUN.  This is a regression test
>> > for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
>> > to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
>> > without updating rseq, leading to a stale CPU ID and other badness.
>> > 
>> > Signed-off-by: Sean Christopherson <seanjc at google.com>
>> > ---
>> 
>> [...]
>> 
>> > +	while (!done) {
>> > +		vcpu_run(vm, VCPU_ID);
>> > +		TEST_ASSERT(get_ucall(vm, VCPU_ID, NULL) == UCALL_SYNC,
>> > +			    "Guest failed?");
>> > +
>> > +		cpu = sched_getcpu();
>> > +		rseq_cpu = READ_ONCE(__rseq.cpu_id);
>> > +
>> > +		/*
>> > +		 * Verify rseq's CPU matches sched's CPU, and that sched's CPU
>> > +		 * is stable.  This doesn't handle the case where the task is
>> > +		 * migrated between sched_getcpu() and reading rseq, and again
>> > +		 * between reading rseq and sched_getcpu(), but in practice no
>> > +		 * false positives have been observed, while on the other hand
>> > +		 * blocking migration while this thread reads CPUs messes with
>> > +		 * the timing and prevents hitting failures on a buggy kernel.
>> > +		 */
>> 
>> I think you could get a stable cpu id between sched_getcpu and __rseq_abi.cpu_id
>> if you add a pthread mutex to protect:
>> 
>> sched_getcpu and __rseq_abi.cpu_id  reads
>> 
>> vs
>> 
>> sched_setaffinity calls within the migration thread.
>> 
>> Thoughts ?
> 
> I tried that and couldn't reproduce the bug.  That's what I attempted to call
> out
> in the blurb "blocking migration while this thread reads CPUs ... prevents
> hitting
> failures on a buggy kernel".
> 
> I considered adding arbitrary delays around the mutex to try and hit the bug,
> but
> I was worried that even if I got it "working" for this bug, the test would be
> too
> tailored to this bug and potentially miss future regression.  Letting the two
> threads run wild seemed like it would provide the best coverage, at the cost of
> potentially causing to false failures.

OK, so your point is that using mutual exclusion to ensure stability of the cpu id
changes the timings too much, to a point where the issues don't reproduce. I understand
that this mutex ties the migration thread timings to the vcpu thread's use of the mutex,
which will reduce timings randomness, which is unwanted here.

I still really hate flakiness in tests, because then people stop caring when they
fail once in a while. And with the nature of rseq, a once-in-a-while failure is a
big deal. Let's see if we can use other tricks to ensure stability of the cpu id
without changing timings too much.

One idea would be to use a seqcount lock. But even if we use that, I'm concerned that
the very long writer critical section calling sched_setaffinity would need to be
alternated with a sleep to ensure the read-side progresses. The sleep delay could be
relatively small compared to the duration of the sched_setaffinity call, e.g. ratio
1:10.

static volatile uint64_t seqcnt;

The thread responsible for setting the affinity would do something like:

for (;;) {
  atomic_inc_seq_cst(&seqcnt);
  sched_setaffinity(..., n++ % nr_cpus);
  atomic_inc_seq_cst(&seqcnt);
  usleep(1);  /* this is where read-side is allowed to progress. */
}

And the thread reading the rseq cpu id and calling sched_getcpu():

uint64_t snapshot;

do {
  snapshot = atomic_load(&seqcnt) & ~1; /* force retry if odd */
  smp_rmb();
  cpu = sched_getcpu();
  rseq_cpu = READ_ONCE(__rseq.cpu_id);
  smp_rmb();
} while (snapshot != atomic_load(&seqcnt));

So the reader retry the cpu id reads whenever sched_setaffinity is being
called by the migration thread, and whenever it is preempted for more
than one migration thread loop.

That should achieve our goal of providing cpu id stability without significantly
changing the timings of the migration thread, given that it never blocks waiting
for the reader.

Thoughts ?

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From catalin.marinas at arm.com  Fri Aug 20 11:35:21 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Aug 2021 19:35:21 +0100
Subject: [PATCH V2] arm64/mm: Drop <asm/page-def.h>
In-Reply-To: <1629457516-32306-1-git-send-email-anshuman.khandual@arm.com>
References: <1629457516-32306-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20210820183520.GC23080@arm.com>

On Fri, Aug 20, 2021 at 04:35:16PM +0530, Anshuman Khandual wrote:
> PAGE_SHIFT (PAGE_SIZE and PAGE_MASK) which is derived from ARM64_PAGE_SHIFT
> should be moved into <asm/page.h> instead like in case for other platforms,
> and then subsequently <asm/page-def.h> can be just dropped off completely.

These were moved to page-def.h as part of commit b6531456ba27 ("arm64:
factor out PAGE_* and CONT_* definitions") to avoid some circular header
dependencies.

> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 824a3655dd93..649d26396f9e 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -12,7 +12,7 @@
>  
>  #include <linux/const.h>
>  #include <linux/sizes.h>
> -#include <asm/page-def.h>
> +#include <asm/page.h>

In 5.14-rc3, asm/page.h still includes asm/memory.h.

-- 
Catalin


From tharvey at gateworks.com  Fri Aug 20 11:41:38 2021
From: tharvey at gateworks.com (Tim Harvey)
Date: Fri, 20 Aug 2021 11:41:38 -0700
Subject: arm32 insecure W+X mapping
In-Reply-To: <381afc78-5a7f-8286-76ea-2e6c7867972d@arm.com>
References: <CAJ+vNU0PaPNHbJc5RXgrRYJw2aWowrGVMOrU1=hKhsCTXAB=DA@mail.gmail.com>
 <20210819212819.GM22278@shell.armlinux.org.uk>
 <CAJ+vNU05L1Fyvy1R6_HwpLeo92LSJhDY4BCr-0aqM7rYgh6TVQ@mail.gmail.com>
 <20210820001646.GN22278@shell.armlinux.org.uk>
 <CAJ+vNU1sh9C=vi1TjHtXAY1F=UNY4cSGrc2vkGujW9pQUPeDDg@mail.gmail.com>
 <381afc78-5a7f-8286-76ea-2e6c7867972d@arm.com>
Message-ID: <CAJ+vNU1xP_KL74aWLEYUL_iHPAWZG_QxS0XiXc4yTq4qJW8s=A@mail.gmail.com>

On Fri, Aug 20, 2021 at 10:48 AM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2021-08-20 17:06, Tim Harvey wrote:
> > On Thu, Aug 19, 2021 at 5:16 PM Russell King (Oracle)
> > <linux at armlinux.org.uk> wrote:
> >>
> >> On Thu, Aug 19, 2021 at 04:59:15PM -0700, Tim Harvey wrote:
> >>> On Thu, Aug 19, 2021 at 2:28 PM Russell King (Oracle)
> >>> <linux at armlinux.org.uk> wrote:
> >>>>
> >>>> On Thu, Aug 19, 2021 at 10:19:46AM -0700, Tim Harvey wrote:
> >>>>> Greetings,
> >>>>>
> >>>>> Since commit a8e53c151fe7 "(ARM: 8737/1: mm: dump: add checking for
> >>>>> writable and executable)" I've been seeing the following appear on my
> >>>>> arm32 kernel:
> >>>>>
> >>>>> arm/mm: Found insecure W+X mapping at address 0xf087d000
> >>>>> ...
> >>>>> Checked W+X mappings: FAILED, 1 W+X pages found
> >>>>>
> >>>>> As I haven't seen others report this I assume it's something unique to
> >>>>> my kernel configuration. How do I debug what is causing the insecure
> >>>>> page?
> >>>>
> >>>> If you check /proc/vmallocinfo, it should tell you the physical
> >>>> address that was mapped there, and the function that created the
> >>>> mapping. That should give enough clues to track it down.
> >>>>
> >>>
> >>> Russell,
> >>>
> >>> Thanks for the tip!
> >>>
> >>> # dmesg | grep insecure
> >>> [   13.219582] arm/mm: Found insecure W+X mapping at address 0xf087d000
> >>> # cat /proc/vmallocinfo | grep 0xf0
> >>> 0x5f3045dd-0xf0020e05   20480 imx6_pm_get_base+0x64/0x98 phys=0x020e0000 ioremap
> >>> 0xf0020e05-0x6e748217    8192 dma_common_contiguous_remap+0x88/0xa4 dma-coherent
> >>> 0x127639d7-0x334ee291    4096 iotable_init+0x0/0xf0 phys=0x00a00000 ioremap
> >>
> >> Oh... the kernel's %p pointer munging (for security reasons) is
> >> affecting your ability to debug your problem. Assuming this is a
> >> recent kernel, you can disable this by passing "no_hash_pointers"
> >> on the kernel command line. You should then see real addresses (and
> >> a big fat message at boot time about it.
> >>
> >
> > I'm using 5.13 and when I pass in 'no_hash_pointers' I do indeed see
> > the huge warning but I get similar results that I can't make sense of:
>
> Pointer hashing always trips me up too, so I thought I'd chuck my
> curiosity into the ring...
>
> Between the vmallocinfo and printk code, it looks like you need to set
> /proc/sys/kptr_restrict to 1 and be root (or have CAP_SYSLOG privilege)
> to get non-hashed addresses here. Because having only one way to confuse
> debugging would be far too easy, I guess :/
>

Robin,

Thanks, that's what I needed:

# uname -r
5.13.12
# cat /proc/cmdline
console=ttymxc1,115200 no_hash_pointers
# echo 1 > /proc/sys/kernel/kptr_restrict
# dmesg | grep insecure
[   13.247957] arm/mm: Found insecure W+X mapping at address 0xf087d000
# cat /proc/vmallocinfo | grep 0xf087d000
0xf0878000-0xf087d000   20480 of_iomap+0x44/0x68 phys=0x021b0000 ioremap
0xf087d000-0xf087f000    8192 imx6_pm_common_init+0x118/0x36c
phys=0x00900000 ioremap

Some debugging showed me that 0xf087d000 is 'suspend_ocram_base'
remapped from imx6q_suspend_init() (called form imx6_pm_common_init()
[1]
suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
MX6Q_SUSPEND_OCRAM_SIZE, false);

This should be throwing 'Checked W+X mappings: FAILED, 1 W+X pages
found' messages for all IMX6 users that have CONFIG_SUSPEND and
CONFIG_DEBUG_WX enabled so I'm adding the IMX6 players to the thread
to see if they know why this happens.

Best regards,

Tim
https://elixir.bootlin.com/linux/v5.13.12/source/arch/arm/mach-imx/pm-imx6.c#L509


From catalin.marinas at arm.com  Fri Aug 20 11:50:38 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 20 Aug 2021 19:50:38 +0100
Subject: [PATCH] arm64: replace in_irq() with in_hardirq()
In-Reply-To: <20210814005405.2658-1-changbin.du@gmail.com>
References: <20210814005405.2658-1-changbin.du@gmail.com>
Message-ID: <162948543097.15117.15949920210143809523.b4-ty@arm.com>

On Sat, 14 Aug 2021 08:54:05 +0800, Changbin Du wrote:
> Replace the obsolete and ambiguos macro in_irq() with new
> macro in_hardirq().

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: replace in_irq() with in_hardirq()
      https://git.kernel.org/arm64/c/090bf6f84b4d

-- 
Catalin



From mathieu.desnoyers at efficios.com  Fri Aug 20 11:51:03 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Fri, 20 Aug 2021 14:51:03 -0400 (EDT)
Subject: [PATCH 1/5] KVM: rseq: Update rseq when processing
 NOTIFY_RESUME on xfer to KVM guest
In-Reply-To: <YR7tzZ98XC6OV2vu@google.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-2-seanjc@google.com>
 <1673583543.19718.1629409152244.JavaMail.zimbra@efficios.com>
 <YR7tzZ98XC6OV2vu@google.com>
Message-ID: <1872633041.20290.1629485463253.JavaMail.zimbra@efficios.com>

----- On Aug 19, 2021, at 7:48 PM, Sean Christopherson seanjc at google.com wrote:

> On Thu, Aug 19, 2021, Mathieu Desnoyers wrote:
>> ----- On Aug 17, 2021, at 8:12 PM, Sean Christopherson seanjc at google.com wrote:
>> > @@ -250,7 +250,7 @@ static int rseq_ip_fixup(struct pt_regs *regs)
>> > 	 * If not nested over a rseq critical section, restart is useless.
>> > 	 * Clear the rseq_cs pointer and return.
>> > 	 */
>> > -	if (!in_rseq_cs(ip, &rseq_cs))
>> > +	if (!regs || !in_rseq_cs(ip, &rseq_cs))
>> 
>> I think clearing the thread's rseq_cs unconditionally here when regs is NULL
>> is not the behavior we want when this is called from xfer_to_guest_mode_work.
>> 
>> If we have a scenario where userspace ends up calling this ioctl(KVM_RUN)
>> from within a rseq c.s., we really want a CONFIG_DEBUG_RSEQ=y kernel to
>> kill this application in the rseq_syscall handler when exiting back to usermode
>> when the ioctl eventually returns.
>> 
>> However, clearing the thread's rseq_cs will prevent this from happening.
>> 
>> So I would favor an approach where we simply do:
>> 
>> if (!regs)
>>      return 0;
>> 
>> Immediately at the beginning of rseq_ip_fixup, before getting the instruction
>> pointer, so effectively skip all side-effects of the ip fixup code. Indeed, it
>> is not relevant to do any fixup here, because it is nested in a ioctl system
>> call.
>> 
>> Effectively, this would preserve the SIGSEGV behavior when this ioctl is
>> erroneously called by user-space from a rseq critical section.
> 
> Ha, that's effectively what I implemented first, but I changed it because of the
> comment in clear_rseq_cs() that says:
> 
>  The rseq_cs field is set to NULL on preemption or signal delivery ... as well
>  as well as on top of code outside of the rseq assembly block.
> 
> Which makes it sound like something might rely on clearing rseq_cs?

This comment is describing succinctly the lazy clear scheme for rseq_cs.

Without the lazy clear scheme, a rseq c.s. would look like:

 *                     init(rseq_cs)
 *                     cpu = TLS->rseq::cpu_id_start
 *   [1]               TLS->rseq::rseq_cs = rseq_cs
 *   [start_ip]        ----------------------------
 *   [2]               if (cpu != TLS->rseq::cpu_id)
 *                             goto abort_ip;
 *   [3]               <last_instruction_in_cs>
 *   [post_commit_ip]  ----------------------------
 *   [4]               TLS->rseq::rseq_cs = NULL

But as a fast-path optimization, [4] is not entirely needed because the rseq_cs
descriptor contains information about the instruction pointer range of the critical
section. Therefore, userspace can omit [4], but if the kernel never clears it, it
means that it will have to re-read the rseq_cs descriptor's content each time it
needs to check it to confirm that it is not nested over a rseq c.s..

So making the kernel lazily clear the rseq_cs pointer is just an optimization which
ensures that the kernel won't do useless work the next time it needs to check
rseq_cs, given that it has already validated that the userspace code is currently
not within the rseq c.s. currently advertised by the rseq_cs field.

> 
> Ah, or is it the case that rseq_cs is non-NULL if and only if userspace is in an
> rseq critical section, and because syscalls in critical sections are illegal, by
> definition clearing rseq_cs is a nop unless userspace is misbehaving.

Not quite, as I described above. But we want it to stay set so the CONFIG_DEBUG_RSEQ
code executed when returning from ioctl to userspace will be able to validate that
it is not nested within a rseq critical section.

> 
> If that's true, what about explicitly checking that at NOTIFY_RESUME?  Or is it
> not worth the extra code to detect an error that will likely be caught anyways?

The error will indeed already be caught on return from ioctl to userspace, so I
don't see any added value in duplicating this check.

Thanks,

Mathieu

> 
> diff --git a/kernel/rseq.c b/kernel/rseq.c
> index 35f7bd0fced0..28b8342290b0 100644
> --- a/kernel/rseq.c
> +++ b/kernel/rseq.c
> @@ -282,6 +282,13 @@ void __rseq_handle_notify_resume(struct ksignal *ksig,
> struct pt_regs *regs)
> 
>        if (unlikely(t->flags & PF_EXITING))
>                return;
> +       if (!regs) {
> +#ifdef CONFIG_DEBUG_RSEQ
> +               if (t->rseq && rseq_get_rseq_cs(t, &rseq_cs))
> +                       goto error;
> +#endif
> +               return;
> +       }
>        ret = rseq_ip_fixup(regs);
>        if (unlikely(ret < 0))
>                goto error;
> 
>> Thanks for looking into this !
>> 
>> Mathieu
>> 
>> > 		return clear_rseq_cs(t);
>> > 	ret = rseq_need_restart(t, rseq_cs.flags);
>> > 	if (ret <= 0)
>> > --
>> > 2.33.0.rc1.237.g0d66db33f3-goog
>> 
>> --
>> Mathieu Desnoyers
>> EfficiOS Inc.
> > http://www.efficios.com

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From christophe.jaillet at wanadoo.fr  Fri Aug 20 11:43:33 2021
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Fri, 20 Aug 2021 20:43:33 +0200
Subject: [PATCH] i2c: bcm2835: Fix the error handling in 'bcm2835_i2c_probe()'
Message-ID: <338008c444af4785a07fb5a402b60225a4964ae9.1629484876.git.christophe.jaillet@wanadoo.fr>

Some resource should be released if an error occurs in
'bcm2835_i2c_probe()'.
Add an error handling path and the needed 'clk_disable_unprepare()' and
'clk_rate_exclusive_put()' calls.

While at it, rework the bottom of the function to use this newly added
error handling path and have an explicit and more standard "return 0;" at
the end of the normal path.

Fixes: bebff81fb8b9 ("i2c: bcm2835: Model Divider in CCF")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
 drivers/i2c/busses/i2c-bcm2835.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index 37443edbf754..a2f19b4c2402 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -449,13 +449,14 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 	ret = clk_prepare_enable(i2c_dev->bus_clk);
 	if (ret) {
 		dev_err(&pdev->dev, "Couldn't prepare clock");
-		return ret;
+		goto err_put_exclusive_rate;
 	}
 
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!irq) {
 		dev_err(&pdev->dev, "No IRQ resource\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto err_disable_unprepare_clk;
 	}
 	i2c_dev->irq = irq->start;
 
@@ -463,7 +464,7 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 			  dev_name(&pdev->dev), i2c_dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Could not request IRQ\n");
-		return -ENODEV;
+		goto err_disable_unprepare_clk;
 	}
 
 	adap = &i2c_dev->adapter;
@@ -481,7 +482,16 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 
 	ret = i2c_add_adapter(adap);
 	if (ret)
-		free_irq(i2c_dev->irq, i2c_dev);
+		goto err_free_irq;
+
+	return 0;
+
+err_free_irq:
+	free_irq(i2c_dev->irq, i2c_dev);
+err_disable_unprepare_clk:
+	clk_disable_unprepare(i2c_dev->bus_clk);
+err_put_exclusive_rate:
+	clk_rate_exclusive_put(i2c_dev->bus_clk);
 
 	return ret;
 }
-- 
2.30.2



From pierre-louis.bossart at linux.intel.com  Fri Aug 20 12:02:16 2021
From: pierre-louis.bossart at linux.intel.com (Pierre-Louis Bossart)
Date: Fri, 20 Aug 2021 14:02:16 -0500
Subject: [PATCH v2 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
 <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
Message-ID: <66d6bd43-ee43-eff4-7a68-333fbb996787@linux.intel.com>


> diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
> new file mode 100644
> index 000000000000..c02b66f3c913
> --- /dev/null
> +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
> @@ -0,0 +1,1737 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
> + *
> + * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
> + * Author: Sugar Zhang <sugar.zhang at rock-chips.com>
> + * Author: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/delay.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_device.h>
> +#include <linux/of_address.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/spinlock.h>
> +#include <sound/pcm_params.h>
> +#include <sound/dmaengine_pcm.h>

alphabetical order?

> +static void rockchip_snd_xfer_clear(struct rk_i2s_tdm_dev *i2s_tdm,
> +				    unsigned int clr)
> +{
> +	unsigned int xfer_mask;
> +	unsigned int xfer_val;
> +	unsigned int val;
> +	int retry = 10;
> +	bool tx = clr & I2S_CLR_TXC;
> +	bool rx = clr & I2S_CLR_RXC;
> +
> +	if (!(rx || tx))
> +		return;
> +
> +	xfer_mask = (tx ? I2S_XFER_TXS_START : 0) |
> +		    (rx ? I2S_XFER_RXS_START : 0);
> +	xfer_val = (tx ? I2S_XFER_TXS_STOP : 0) |
> +		   (rx ? I2S_XFER_RXS_STOP : 0);
> +
> +	regmap_update_bits(i2s_tdm->regmap, I2S_XFER, xfer_mask, xfer_val);
> +	udelay(150);
> +	regmap_update_bits(i2s_tdm->regmap, I2S_CLR, clr, clr);
> +
> +	regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
> +	/* Wait on the clear operation to finish */
> +	while (val) {

delay needed here?

> +		regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
> +		retry--;
> +		if (!retry) {
> +			dev_warn(i2s_tdm->dev, "clear failed, reset %s%s\n",
> +				 tx ? "tx" : "", rx ? "rx" : "");
> +			if (rx && tx)
> +				rockchip_snd_xfer_sync_reset(i2s_tdm);
> +			else if (tx)
> +				rockchip_snd_reset(i2s_tdm->tx_reset);
> +			else if (rx)
> +				rockchip_snd_reset(i2s_tdm->rx_reset);
> +			break;
> +		}
> +	}
> +}

> +static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
> +				    unsigned int fmt)
> +{
> +	struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
> +	unsigned int mask = 0, val = 0, tdm_val = 0, txcr_val = 0, rxcr_val = 0;

not all initializations are required. Run e.g. cppcheck.

> +	int ret = 0;
> +	bool is_tdm = i2s_tdm->tdm_mode;
> +
> +	pm_runtime_get_sync(cpu_dai->dev);

test if this worked?

Also if this fails you need to call pm_runtime_put_noidle()

this is what we use.

ret = pm_runtime_get_sync(dev);
if (ret < 0 && ret != -EACCES) {
      pm_runtime_put_noidle(dev);
      return ret;
}


> +	mask = I2S_CKR_MSS_MASK;
> +	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> +	case SND_SOC_DAIFMT_CBS_CFS:
> +		val = I2S_CKR_MSS_MASTER;
> +		i2s_tdm->is_master_mode = true;
> +		break;
> +	case SND_SOC_DAIFMT_CBM_CFM:
> +		val = I2S_CKR_MSS_SLAVE;
> +		i2s_tdm->is_master_mode = false;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		goto err_pm_put;
> +	}
> +
> +	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val);
> +
> +	mask = I2S_CKR_CKP_MASK | I2S_CKR_TLP_MASK | I2S_CKR_RLP_MASK;
> +	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
> +	case SND_SOC_DAIFMT_NB_NF:
> +		val = I2S_CKR_CKP_NORMAL |
> +		      I2S_CKR_TLP_NORMAL |
> +		      I2S_CKR_RLP_NORMAL;
> +		break;
> +	case SND_SOC_DAIFMT_NB_IF:
> +		val = I2S_CKR_CKP_NORMAL |
> +		      I2S_CKR_TLP_INVERTED |
> +		      I2S_CKR_RLP_INVERTED;
> +		break;
> +	case SND_SOC_DAIFMT_IB_NF:
> +		val = I2S_CKR_CKP_INVERTED |
> +		      I2S_CKR_TLP_NORMAL |
> +		      I2S_CKR_RLP_NORMAL;
> +		break;
> +	case SND_SOC_DAIFMT_IB_IF:
> +		val = I2S_CKR_CKP_INVERTED |
> +		      I2S_CKR_TLP_INVERTED |
> +		      I2S_CKR_RLP_INVERTED;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		goto err_pm_put;
> +	}
> +
> +	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val);
> +
> +	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> +	case SND_SOC_DAIFMT_RIGHT_J:
> +		txcr_val = I2S_TXCR_IBM_RSJM;
> +		rxcr_val = I2S_RXCR_IBM_RSJM;
> +		break;
> +	case SND_SOC_DAIFMT_LEFT_J:
> +		txcr_val = I2S_TXCR_IBM_LSJM;
> +		rxcr_val = I2S_RXCR_IBM_LSJM;
> +		break;
> +	case SND_SOC_DAIFMT_I2S:
> +		txcr_val = I2S_TXCR_IBM_NORMAL;
> +		rxcr_val = I2S_RXCR_IBM_NORMAL;
> +		break;
> +	case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */
> +		txcr_val = I2S_TXCR_TFS_PCM;
> +		rxcr_val = I2S_RXCR_TFS_PCM;
> +		break;
> +	case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */
> +		txcr_val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);
> +		rxcr_val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		goto err_pm_put;
> +	}
> +
> +	mask = I2S_TXCR_IBM_MASK | I2S_TXCR_TFS_MASK | I2S_TXCR_PBM_MASK;
> +	regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, txcr_val);
> +
> +	mask = I2S_RXCR_IBM_MASK | I2S_RXCR_TFS_MASK | I2S_RXCR_PBM_MASK;
> +	regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, rxcr_val);
> +
> +	if (is_tdm) {
> +		switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> +		case SND_SOC_DAIFMT_RIGHT_J:
> +			val = I2S_TXCR_TFS_TDM_I2S;
> +			tdm_val = TDM_SHIFT_CTRL(2);
> +			break;
> +		case SND_SOC_DAIFMT_LEFT_J:
> +			val = I2S_TXCR_TFS_TDM_I2S;
> +			tdm_val = TDM_SHIFT_CTRL(1);
> +			break;
> +		case SND_SOC_DAIFMT_I2S:
> +			val = I2S_TXCR_TFS_TDM_I2S;
> +			tdm_val = TDM_SHIFT_CTRL(0);
> +			break;
> +		case SND_SOC_DAIFMT_DSP_A:
> +			val = I2S_TXCR_TFS_TDM_PCM;
> +			tdm_val = TDM_SHIFT_CTRL(0);
> +			break;
> +		case SND_SOC_DAIFMT_DSP_B:
> +			val = I2S_TXCR_TFS_TDM_PCM;
> +			tdm_val = TDM_SHIFT_CTRL(2);
> +			break;
> +		default:
> +			ret = -EINVAL;
> +			goto err_pm_put;
> +		}
> +
> +		tdm_val |= TDM_FSYNC_WIDTH_SEL1(1);
> +		if (i2s_tdm->tdm_fsync_half_frame)
> +			tdm_val |= TDM_FSYNC_WIDTH_HALF_FRAME;
> +		else
> +			tdm_val |= TDM_FSYNC_WIDTH_ONE_FRAME;
> +
> +		mask = I2S_TXCR_TFS_MASK;
> +		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, val);
> +		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, val);
> +
> +		mask = TDM_FSYNC_WIDTH_SEL1_MSK | TDM_FSYNC_WIDTH_SEL0_MSK |
> +		       TDM_SHIFT_CTRL_MSK;
> +		regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR,
> +				   mask, tdm_val);
> +		regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR,
> +				   mask, tdm_val);
> +	}
> +
> +err_pm_put:
> +	pm_runtime_put(cpu_dai->dev);
> +
> +	return ret;
> +}
> +

> +static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm,
> +					 struct clk *clk, unsigned long rate,
> +					 int ppm)
> +{
> +	unsigned long rate_target;
> +	int delta, ret;
> +
> +	if (ppm == i2s_tdm->clk_ppm)
> +		return 0;
> +
> +	delta = (ppm < 0) ? -1 : 1;
> +	delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000,
> +				1000000);

formula looks odd? looks like you are implementing a round to nearest
operation, but that shouldn't require this multiplication?

> +
> +	rate_target = rate + delta;
> +
> +	if (!rate_target)
> +		return -EINVAL;
> +
> +	ret = clk_set_rate(clk, rate_target);
> +	if (ret)
> +		return ret;
> +
> +	i2s_tdm->clk_ppm = ppm;
> +
> +	return ret;
> +}
> +
> +static int rockchip_i2s_tdm_calibrate_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
> +					   struct snd_pcm_substream *substream,
> +					   unsigned int lrck_freq)
> +{
> +	struct clk *mclk_root;
> +	struct clk *mclk_parent;
> +	unsigned int mclk_root_freq;
> +	unsigned int mclk_root_initial_freq;
> +	unsigned int mclk_parent_freq;
> +	unsigned int div, delta;
> +	u64 ppm;
> +	int ret;
> +
> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> +		mclk_parent = i2s_tdm->mclk_tx_src;
> +	else
> +		mclk_parent = i2s_tdm->mclk_rx_src;
> +
> +	switch (lrck_freq) {
> +	case 8000:
> +	case 16000:
> +	case 24000:
> +	case 32000:
> +	case 48000:
> +	case 64000:
> +	case 96000:
> +	case 192000:
> +		mclk_root = i2s_tdm->mclk_root0;
> +		mclk_root_freq = i2s_tdm->mclk_root0_freq;
> +		mclk_root_initial_freq = i2s_tdm->mclk_root0_initial_freq;
> +		mclk_parent_freq = DEFAULT_MCLK_FS * 192000;
> +		break;
> +	case 11025:
> +	case 22050:
> +	case 44100:
> +	case 88200:
> +	case 176400:
> +		mclk_root = i2s_tdm->mclk_root1;
> +		mclk_root_freq = i2s_tdm->mclk_root1_freq;
> +		mclk_root_initial_freq = i2s_tdm->mclk_root1_initial_freq;
> +		mclk_parent_freq = DEFAULT_MCLK_FS * 176400;
> +		break;
> +	default:
> +		dev_err(i2s_tdm->dev, "Invalid LRCK freq: %u Hz\n",
> +			lrck_freq);
> +		return -EINVAL;
> +	}
> +
> +	ret = clk_set_parent(mclk_parent, mclk_root);
> +	if (ret)
> +		return ret;
> +
> +	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, mclk_root,
> +					    mclk_root_freq, 0);
> +	if (ret)
> +		return ret;
> +
> +	delta = abs(mclk_root_freq % mclk_parent_freq - mclk_parent_freq);
> +	ppm = div64_u64((uint64_t)delta * 1000000, (uint64_t)mclk_root_freq);
> +
> +	if (ppm) {
> +		div = DIV_ROUND_CLOSEST(mclk_root_initial_freq, mclk_parent_freq);
> +		if (!div)
> +			return -EINVAL;
> +
> +		mclk_root_freq = mclk_parent_freq * round_up(div, 2);
> +
> +		ret = clk_set_rate(mclk_root, mclk_root_freq);
> +		if (ret)
> +			return ret;
> +
> +		i2s_tdm->mclk_root0_freq = clk_get_rate(i2s_tdm->mclk_root0);
> +		i2s_tdm->mclk_root1_freq = clk_get_rate(i2s_tdm->mclk_root1);
> +	}
> +
> +	ret = clk_set_rate(mclk_parent, mclk_parent_freq);
> +
> +	return ret;

return clk_set_rate(mclk_parent, mclk_parent_freq); ?

> +}
> +
> +static int rockchip_i2s_tdm_set_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
> +				     struct snd_pcm_substream *substream,
> +				     struct clk **mclk)
> +{
> +	unsigned int mclk_freq;
> +	int ret;
> +
> +	if (i2s_tdm->clk_trcm) {
> +		if (i2s_tdm->mclk_tx_freq != i2s_tdm->mclk_rx_freq) {
> +			dev_err(i2s_tdm->dev,
> +				"clk_trcm, tx: %d and rx: %d should be same\n",
> +				i2s_tdm->mclk_tx_freq,
> +				i2s_tdm->mclk_rx_freq);
> +			ret = -EINVAL;
> +			return ret;

return -EINVAL?

> +		}
> +
> +		ret = clk_set_rate(i2s_tdm->mclk_tx, i2s_tdm->mclk_tx_freq);
> +		if (ret)
> +			return ret;
> +
> +		ret = clk_set_rate(i2s_tdm->mclk_rx, i2s_tdm->mclk_rx_freq);
> +		if (ret)
> +			return ret;
> +
> +		/* mclk_rx is also ok. */
> +		*mclk = i2s_tdm->mclk_tx;
> +	} else {
> +		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> +			*mclk = i2s_tdm->mclk_tx;
> +			mclk_freq = i2s_tdm->mclk_tx_freq;
> +		} else {
> +			*mclk = i2s_tdm->mclk_rx;
> +			mclk_freq = i2s_tdm->mclk_rx_freq;
> +		}
> +
> +		ret = clk_set_rate(*mclk, mclk_freq);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +

> +	pm_runtime_enable(&pdev->dev);
> +	if (!pm_runtime_enabled(&pdev->dev)) {
> +		ret = i2s_tdm_runtime_resume(&pdev->dev);

that looks like dead code? you've just enabled pm_runtime, why would
this fail?

> +		if (ret)
> +			goto err_pm_disable;
> +	}
> +
> +	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
> +			   I2S_DMACR_TDL(16));
> +	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
> +			   I2S_DMACR_RDL(16));
> +	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, I2S_CKR_TRCM_MASK,
> +			   i2s_tdm->clk_trcm << I2S_CKR_TRCM_SHIFT);
> +
> +	if (i2s_tdm->soc_data && i2s_tdm->soc_data->init)
> +		i2s_tdm->soc_data->init(&pdev->dev, res->start);
> +
> +	ret = devm_snd_soc_register_component(&pdev->dev,
> +					      &rockchip_i2s_tdm_component,
> +					      &i2s_tdm_dai, 1);
> +
> +	if (ret) {
> +		dev_err(&pdev->dev, "Could not register DAI\n");
> +		goto err_suspend;
> +	}
> +
> +	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Could not register PCM\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +
> +err_suspend:
> +	if (!pm_runtime_status_suspended(&pdev->dev))
> +		i2s_tdm_runtime_suspend(&pdev->dev);

why is this necessary?

> +err_pm_disable:
> +	pm_runtime_disable(&pdev->dev);
> +
> +	return ret;
> +}
> +
> +static int rockchip_i2s_tdm_remove(struct platform_device *pdev)
> +{
> +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(&pdev->dev);
> +
> +	pm_runtime_disable(&pdev->dev);
> +	if (!pm_runtime_status_suspended(&pdev->dev))
> +		i2s_tdm_runtime_suspend(&pdev->dev);

this looks backwards, if you disable pm_runtime first what is the
expectation for the rest.
> +
> +	if (!IS_ERR(i2s_tdm->mclk_tx))
> +		clk_prepare_enable(i2s_tdm->mclk_tx);
> +	if (!IS_ERR(i2s_tdm->mclk_rx))
> +		clk_prepare_enable(i2s_tdm->mclk_rx);
> +	if (!IS_ERR(i2s_tdm->hclk))
> +		clk_disable_unprepare(i2s_tdm->hclk);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP

use __maybe_unused

> +static int rockchip_i2s_tdm_suspend(struct device *dev)
> +{
> +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
> +
> +	regcache_mark_dirty(i2s_tdm->regmap);
> +
> +	return 0;
> +}
> +
> +static int rockchip_i2s_tdm_resume(struct device *dev)
> +{
> +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
> +	int ret;
> +
> +	ret = pm_runtime_get_sync(dev);
> +	if (ret < 0)
> +		return ret;
> +	ret = regcache_sync(i2s_tdm->regmap);
> +	pm_runtime_put(dev);
> +
> +	return ret;
> +}
> +#endif


From helgaas at kernel.org  Fri Aug 20 12:06:04 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 20 Aug 2021 14:06:04 -0500
Subject: [PATCH v2 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210819215655.84866-3-jeremy.linton@arm.com>
Message-ID: <20210820190604.GA3340361@bjorn-Precision-5520>

On Thu, Aug 19, 2021 at 04:56:53PM -0500, Jeremy Linton wrote:
> The PFTF CM4 is an ACPI platform that isn't ECAM compliant. Its config
> space is in two parts. One part is for the root port registers and a
> second moveable window pointing at a device's 4K config space. Thus it
> doesn't have an MCFG, and any MCFG provided would be nonsense
> anyway. Instead, a Linux specific host bridge _DSD selects a custom
> ECAM ops and cfgres. The cfg op picks between those two regions while
> disallowing problematic accesses.

This doesn't actually say what this patch *does*.

Can you expand "PFTF CM4" somehow?  Google (and the comment below, I
guess) suggests it's something to do with Raspberry Pi 4, but it would
be nice if the commit log made sense without Googling or reading the
patch.

> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  drivers/pci/controller/Makefile            |  1 +
>  drivers/pci/controller/pcie-brcmstb-acpi.c | 74 ++++++++++++++++++++++
>  include/linux/pci-ecam.h                   |  1 +
>  3 files changed, 76 insertions(+)
>  create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
> 
> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> index aaf30b3dcc14..65aa6fd3ed89 100644
> --- a/drivers/pci/controller/Makefile
> +++ b/drivers/pci/controller/Makefile
> @@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
>  obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
>  obj-$(CONFIG_ARM64) += pci-thunder-pem.o
>  obj-$(CONFIG_ARM64) += pci-xgene.o
> +obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
>  endif
>  endif
> diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
> new file mode 100644
> index 000000000000..71f6def3074c
> --- /dev/null
> +++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * ACPI quirks for Brcm2711 PCIe host controller
> + * As used on the Raspberry Pi Compute Module 4
> + *
> + * Copyright (C) 2021 Arm Ltd.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/pci.h>
> +#include <linux/pci-ecam.h>
> +#include "../pci.h"
> +#include "pcie-brcmstb.h"
> +
> +static int brcm_acpi_init(struct pci_config_window *cfg)
> +{
> +	/*
> +	 * This platform doesn't technically have anything that could be called
> +	 * ECAM. Its config region has root port specific registers between
> +	 * standard PCIe defined config registers. Thus the region setup by the
> +	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
> +	 * but the footprint isn't a nice power of 2 (40k). For purposes of
> +	 * mapping the config region we are just going to squash the standard
> +	 * and nonstandard registers together rather than mapping them separately.
> +	 */
> +	iounmap(cfg->win);
> +	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
> +	if (!cfg->win)
> +		goto err_exit;
> +
> +	/* MSI is nonstandard as well */
> +	pci_no_msi();
> +
> +	return 0;
> +err_exit:
> +	dev_err(cfg->parent, "PCI: Failed to remap config\n");
> +	return -ENOMEM;
> +}
> +
> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
> +					unsigned int devfn, int where)
> +{
> +	struct pci_config_window *cfg = bus->sysdata;
> +	void __iomem *base = cfg->win;
> +	int idx;
> +	u32 up;
> +
> +	/* Accesses to the RC go right to the RC registers if slot==0 */
> +	if (pci_is_root_bus(bus))
> +		return PCI_SLOT(devfn) ? NULL : base + where;
> +
> +	/* Assure link up before sending request */

Obviously this is horribly racy, since the link may go down after you
check but before you send the request.  Maybe the hardware leaves you
no choice.  I'd feel a little better about it if the comment
acknowledged that (if it's so) and outlined the consequence of losing
the race (panic, recoverable error, etc).

> +	up = readl(base + PCIE_MISC_PCIE_STATUS);
> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
> +		return NULL;
> +
> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
> +		return NULL;
> +
> +	/* For devices, write to the config space index register */
> +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
> +	writel(idx, base + PCIE_EXT_CFG_INDEX);
> +	return base + PCIE_EXT_CFG_DATA + where;
> +}
> +
> +const struct pci_ecam_ops bcm2711_pcie_ops = {
> +	.init		= brcm_acpi_init,
> +	.bus_shift	= 1,
> +	.pci_ops	= {
> +		.map_bus	= brcm_pcie_map_conf2,
> +		.read		= pci_generic_config_read,
> +		.write		= pci_generic_config_write,
> +	}
> +};
> diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
> index adea5a4771cf..a5de0285bb7f 100644
> --- a/include/linux/pci-ecam.h
> +++ b/include/linux/pci-ecam.h
> @@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
>  extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
>  extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
>  extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
> +extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
>  #endif
>  
>  #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
> -- 
> 2.31.1
> 


From helgaas at kernel.org  Fri Aug 20 12:09:17 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 20 Aug 2021 14:09:17 -0500
Subject: [PATCH v2 4/4] MAINTAINERS: Widen brcmstb PCIe file scope
In-Reply-To: <20210819215655.84866-5-jeremy.linton@arm.com>
Message-ID: <20210820190917.GA3340819@bjorn-Precision-5520>

On Thu, Aug 19, 2021 at 04:56:55PM -0500, Jeremy Linton wrote:
> The brcmstb PCI hardware is now split across
> multiple files. Include them in the maintainers
> block.

Rewrap to fill 75 columns or so.

> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  MAINTAINERS | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fd25e4ecf0b9..605a385cea36 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3500,7 +3500,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  S:	Maintained
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nsaenz/linux-rpi.git
>  F:	Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> -F:	drivers/pci/controller/pcie-brcmstb.c
> +F:	drivers/pci/controller/pcie-brcmstb*

There are already two entries that mention
drivers/pci/controller/pcie-brcmstb.c, and a patch headed for v5.14
adds a third.  Do you want to update them all?

>  F:	drivers/staging/vc04_services
>  N:	bcm2711
>  N:	bcm283*
> -- 
> 2.31.1
> 


From helgaas at kernel.org  Fri Aug 20 12:11:14 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 20 Aug 2021 14:11:14 -0500
Subject: [PATCH v2 0/4] CM4 ACPI PCIe quirk
In-Reply-To: <20210819215655.84866-1-jeremy.linton@arm.com>
Message-ID: <20210820191114.GA3341026@bjorn-Precision-5520>

On Thu, Aug 19, 2021 at 04:56:51PM -0500, Jeremy Linton wrote:
> The PFTF CM4 is an ACPI platform that is following the Arm PCIe SMC
> (DEN0115) standard because its PCIe config space isn't ECAM compliant
> since it is split into two parts. One part describes the root port
> registers, and another contains a moveable window pointing at a given
> device's 4K config space. Thus it doesn't have an MCFG table. As
> Linux doesn't support the PCI/SMC, a host bridge specific _DSD is
> added and associated with custom ECAM ops and cfgres.  The custom cfg
> op selects between those two regions, as well as disallowing
> problematic accesses.
> 
> V1->V2:
> 	Only move register definitions to new .h file, add
> 	     include guards.
> 	Change quirk namespace identifier.
> 	Update Maintainers file.
> 	A number of whitespace, grammar, etc fixes.
> 
> 
> Jeremy Linton (4):
>   PCI: brcmstb: Break register definitions into separate header
>   PCI: brcmstb: Add ACPI config space quirk
>   PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
>   MAINTAINERS: Widen brcmstb PCIe file scope
> 
>  MAINTAINERS                                |   2 +-
>  drivers/acpi/pci_mcfg.c                    |  13 ++
>  drivers/pci/controller/Makefile            |   1 +
>  drivers/pci/controller/pcie-brcmstb-acpi.c |  74 ++++++++++
>  drivers/pci/controller/pcie-brcmstb.c      | 150 +-------------------
>  drivers/pci/controller/pcie-brcmstb.h      | 155 +++++++++++++++++++++
>  include/linux/pci-ecam.h                   |   1 +
>  7 files changed, 247 insertions(+), 149 deletions(-)
>  create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
>  create mode 100644 drivers/pci/controller/pcie-brcmstb.h

I'm fine with all of these, given the minor comments I made.

Lorenzo, if you want to pick this up after Jeremy updates it:

Acked-by: Bjorn Helgaas <bhelgaas at google.com>



From arnd at arndb.de  Fri Aug 20 12:55:53 2021
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 20 Aug 2021 21:55:53 +0200
Subject: [PATCH] arm64: dts: synaptics: add DT for AS370-RDK
In-Reply-To: <20210820182708.51d13e29@xhacker.debian>
References: <20210820173108.01d5c6de@xhacker.debian>
 <29e96ece-8541-a7a2-c6a9-453be6644eed@canonical.com>
 <20210820182708.51d13e29@xhacker.debian>
Message-ID: <CAK8P3a2vkZVt1bb7-iDGaSHp20U9d8QXu6AcrUMceJSS9Q_-4Q@mail.gmail.com>

On Fri, Aug 20, 2021 at 12:27 PM Jisheng Zhang
<Jisheng.Zhang at synaptics.com> wrote:
> On Fri, 20 Aug 2021 11:59:30 +0200 Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
> > On 20/08/2021 11:31, Jisheng Zhang wrote:
> >
> > There is no such binding. You need to update the bindings file (first
> > patch in the series).
>
> This is my plan ;) In fact, "berlin4ct" related binding is also missing.
> I want to convert Documentation/devicetree/bindings/arm/syna.txt
> to yaml, then add missing bindings. But it's too late for 5.15,
>
> If it's fine to keep as370.dtsi without board user(s), we can drop
> this patch. I will solve this issue in next development window.

Yes, doing it for the next cycle is ok.

        Arnd


From robh at kernel.org  Fri Aug 20 13:01:55 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 20 Aug 2021 15:01:55 -0500
Subject: [PATCH v2 1/5] dt-bindings: aspeed: Add eSPI controller
In-Reply-To: <20210819080040.31242-2-chiawei_wang@aspeedtech.com>
References: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
 <20210819080040.31242-2-chiawei_wang@aspeedtech.com>
Message-ID: <YSAKM16WLx4UWIQu@robh.at.kernel.org>

On Thu, Aug 19, 2021 at 04:00:36PM +0800, Chia-Wei Wang wrote:
> Add dt-bindings for Aspeed eSPI controller
> 
> Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
> ---
>  .../devicetree/bindings/soc/aspeed/espi.yaml  | 158 ++++++++++++++++++
>  1 file changed, 158 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> 
> diff --git a/Documentation/devicetree/bindings/soc/aspeed/espi.yaml b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> new file mode 100644
> index 000000000000..fec3d37f3ffd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> @@ -0,0 +1,158 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# # Copyright (c) 2021 Aspeed Technology Inc.
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/soc/aspeed/espi.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Aspeed eSPI Controller
> +
> +maintainers:
> +  - Chia-Wei Wang <chiawei_wang at aspeedtech.com>
> +  - Ryan Chen <ryan_chen at aspeedtech.com>
> +
> +description:
> +  Aspeed eSPI controller implements a slave side eSPI endpoint device
> +  supporting the four eSPI channels, namely peripheral, virtual wire,
> +  out-of-band, and flash.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - aspeed,ast2500-espi
> +          - aspeed,ast2600-espi
> +      - const: simple-mfd
> +      - const: syscon

Is this really 2 sub devices that could be used individually or in a 
different combination? If not, then I'd make all this 1 node.

Rob


From pr-tracker-bot at kernel.org  Fri Aug 20 13:09:11 2021
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 20 Aug 2021 20:09:11 +0000
Subject: [GIT PULL] arm64 fixes for -rc7
In-Reply-To: <20210820085302.GA17037@willie-the-truck>
References: <20210820085302.GA17037@willie-the-truck>
Message-ID: <162949015106.21370.16530945310394925488.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 20 Aug 2021 09:53:03 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/54e9ea3cdb13884b8d3a0c13b9b92bab4a1c96f5

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From robh at kernel.org  Fri Aug 20 13:28:51 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 20 Aug 2021 15:28:51 -0500
Subject: [PATCH 1/2] dt-bindings: remoteproc: Add fsl,imx-dsp-rproc
 binding document
In-Reply-To: <1629453791-10580-1-git-send-email-shengjiu.wang@nxp.com>
References: <1629453791-10580-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <YSAQgywy8UW540h9@robh.at.kernel.org>

On Fri, Aug 20, 2021 at 06:03:10PM +0800, Shengjiu Wang wrote:
> Define the compatible string and properties needed by imx_dsp_rproc
> driver.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
> ---
>  .../remoteproc/fsl,imx-dsp-rproc.yaml         | 123 ++++++++++++++++++
>  1 file changed, 123 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
> new file mode 100644
> index 000000000000..7eba49aa959e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
> @@ -0,0 +1,123 @@
> +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/remoteproc/fsl,imx-dsp-rproc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX DSP Remoteproc Devices
> +
> +maintainers:
> +  - Shengjiu Wang <shengjiu.wang at nxp.com>
> +
> +description:
> +  This binding provides support for DSP processors found on i.mX family of SoCs
> +
> +properties:
> +  compatible:
> +    enum:
> +      - fsl,imx8qxp-hifi4
> +      - fsl,imx8qm-hifi4
> +      - fsl,imx8mp-hifi4
> +      - fsl,imx8ulp-hifi4
> +
> +  clocks:
> +    description: |
> +      Main functional clock for the remote processor

Don't need '|' if no formatting. 

> +    minItems: 1
> +    maxItems: 32
> +
> +  clock-names:
> +    description:
> +      List of clock names for the remote processor.
> +      dsp_clkx for clocks of dsp itself.
> +      per_clkx for clocks of peripherals used by dsp.

Sounds like constraints that should be a schema. But this looks like 
some random collection of clocks, not clocks for the DSP h/w.

> +    minItems: 1
> +    maxItems: 32
> +
> +  syscon:

Vendor prefix and name it based on what it points to or is used for.

> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to syscon block which provide access for processor enablement
> +
> +  mbox-names:
> +    items:
> +      - const: tx
> +      - const: rx
> +      - const: rxdb
> +
> +  mboxes:
> +    description:
> +      This property is required only if the rpmsg/virtio functionality is used.
> +      List of <&phandle type channel> - 1 channel for TX, 1 channel for RX, 1 channel for RXDB.
> +      (see mailbox/fsl,mu.yaml)
> +    minItems: 1
> +    maxItems: 3
> +
> +  firmware-name:
> +    description: |
> +      Default name of the firmware to load to the remote processor.
> +
> +  memory-region:
> +    description:
> +      If present, a phandle for a reserved memory area that used for vdev buffer,
> +      resource table, vring region and others used by remote processor.
> +    minItems: 1
> +    maxItems: 32
> +
> +  reg:
> +    description: |
> +      Address space for any remoteproc memories present on the SoC.
> +
> +  power-domains:
> +    minItems: 1
> +    maxItems: 32
> +
> +required:
> +  - compatible
> +  - reg
> +  - mboxes
> +  - mbox-names
> +  - clocks
> +  - clock-names
> +  - firmware-name
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx8mp-clock.h>
> +    dsp_reserved: dsp at 92400000 {
> +      reg = <0x92400000 0x1000000>;
> +      no-map;
> +    };
> +    dsp_vdev0vring0: vdev0vring0 at 942f0000 {
> +      reg = <0x942f0000 0x8000>;
> +      no-map;
> +    };
> +    dsp_vdev0vring1: vdev0vring1 at 942f8000 {
> +      reg = <0x942f8000 0x8000>;
> +      no-map;
> +    };
> +    dsp_vdev0buffer: vdev0buffer at 94300000 {
> +      compatible = "shared-dma-pool";
> +      reg = <0x94300000 0x100000>;
> +      no-map;
> +    };
> +
> +    dsp: dsp at 3b6e8000 {
> +      compatible = "fsl,imx8mp-hifi4";
> +      reg = <0x3B6E8000 0x88000>;
> +      clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG>,
> +               <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSP_ROOT>,
> +               <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT>;
> +      clock-names = "dsp_clk1", "dsp_clk2", "dsp_clk3";
> +      firmware-name = "imx/dsp/hifi4.bin";
> +      power-domains = <&audiomix_pd>;
> +      mbox-names = "tx", "rx", "rxdb";
> +      mboxes = <&mu2 0 0>,
> +               <&mu2 1 0>,
> +               <&mu2 3 0>;
> +      memory-region = <&dsp_vdev0buffer>, <&dsp_vdev0vring0>,
> +                      <&dsp_vdev0vring1>, <&dsp_reserved>;
> +      syscon = <&audio_blk_ctrl>;
> +    };
> -- 
> 2.17.1
> 
> 


From konrad.dybcio at somainline.org  Fri Aug 20 13:29:05 2021
From: konrad.dybcio at somainline.org (Konrad Dybcio)
Date: Fri, 20 Aug 2021 22:29:05 +0200
Subject: [PATCH 2/2] iommu/arm-smmu-qcom: Add SM6350 SMMU compatible
In-Reply-To: <20210820202906.229292-1-konrad.dybcio@somainline.org>
References: <20210820202906.229292-1-konrad.dybcio@somainline.org>
Message-ID: <20210820202906.229292-2-konrad.dybcio@somainline.org>

Add compatible for SM6350 SMMU to use the Qualcomm Technologies, Inc.
specific implementation.

Signed-off-by: Konrad Dybcio <konrad.dybcio at somainline.org>
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 9b9d13ec5a88..b9956294ca2a 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -398,6 +398,7 @@ static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = {
 	{ .compatible = "qcom,sdm630-smmu-v2" },
 	{ .compatible = "qcom,sdm845-smmu-500" },
 	{ .compatible = "qcom,sm6125-smmu-500" },
+	{ .compatible = "qcom,sm6350-smmu-500" },
 	{ .compatible = "qcom,sm8150-smmu-500" },
 	{ .compatible = "qcom,sm8250-smmu-500" },
 	{ .compatible = "qcom,sm8350-smmu-500" },
-- 
2.33.0



From konrad.dybcio at somainline.org  Fri Aug 20 13:29:04 2021
From: konrad.dybcio at somainline.org (Konrad Dybcio)
Date: Fri, 20 Aug 2021 22:29:04 +0200
Subject: [PATCH 1/2] dt-bindings: arm-smmu: Add compatible for SM6350 SoC
Message-ID: <20210820202906.229292-1-konrad.dybcio@somainline.org>

Add the SoC specific compatible for SM6350 implementing
arm,mmu-500.

Signed-off-by: Konrad Dybcio <konrad.dybcio at somainline.org>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
index 03f2b2d4db30..87b93ab3f34e 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -37,6 +37,7 @@ properties:
               - qcom,sc7280-smmu-500
               - qcom,sc8180x-smmu-500
               - qcom,sdm845-smmu-500
+              - qcom,sm6350-smmu-500
               - qcom,sm8150-smmu-500
               - qcom,sm8250-smmu-500
               - qcom,sm8350-smmu-500
-- 
2.33.0



From jeremy.linton at arm.com  Fri Aug 20 13:31:44 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri, 20 Aug 2021 15:31:44 -0500
Subject: [PATCH v2 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210820190604.GA3340361@bjorn-Precision-5520>
References: <20210820190604.GA3340361@bjorn-Precision-5520>
Message-ID: <0f9443fc-51c8-105d-51ac-32725af4e710@arm.com>

Hi,

Thanks for looking at this.

On 8/20/21 2:06 PM, Bjorn Helgaas wrote:
> On Thu, Aug 19, 2021 at 04:56:53PM -0500, Jeremy Linton wrote:
>> The PFTF CM4 is an ACPI platform that isn't ECAM compliant. Its config
>> space is in two parts. One part is for the root port registers and a
>> second moveable window pointing at a device's 4K config space. Thus it
>> doesn't have an MCFG, and any MCFG provided would be nonsense
>> anyway. Instead, a Linux specific host bridge _DSD selects a custom
>> ECAM ops and cfgres. The cfg op picks between those two regions while
>> disallowing problematic accesses.
> 
> This doesn't actually say what this patch *does*.

Ok.

> 
> Can you expand "PFTF CM4" somehow?  Google (and the comment below, I
> guess) suggests it's something to do with Raspberry Pi 4, but it would
> be nice if the commit log made sense without Googling or reading the
> patch.

Yes, sure, as you deduced PFTF is a community project which aims to 
create a systemready UEFI/ACPI platform out of rpi4/rpi400/cm4 systems. 
Its actually fairly far along in that goal, and is capable of booting a 
wide range of arm64 based OS's & Hypervisors. Its acting like a proof of 
concept that putting effort into some basic platform abstractions 
reduces the effort to boot off the shelf OSs. It does this by moving 
much of the platform specific code into firmware.



> 
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>>   drivers/pci/controller/Makefile            |  1 +
>>   drivers/pci/controller/pcie-brcmstb-acpi.c | 74 ++++++++++++++++++++++
>>   include/linux/pci-ecam.h                   |  1 +
>>   3 files changed, 76 insertions(+)
>>   create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
>>
>> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
>> index aaf30b3dcc14..65aa6fd3ed89 100644
>> --- a/drivers/pci/controller/Makefile
>> +++ b/drivers/pci/controller/Makefile
>> @@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
>>   obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
>>   obj-$(CONFIG_ARM64) += pci-thunder-pem.o
>>   obj-$(CONFIG_ARM64) += pci-xgene.o
>> +obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
>>   endif
>>   endif
>> diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
>> new file mode 100644
>> index 000000000000..71f6def3074c
>> --- /dev/null
>> +++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
>> @@ -0,0 +1,74 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * ACPI quirks for Brcm2711 PCIe host controller
>> + * As used on the Raspberry Pi Compute Module 4
>> + *
>> + * Copyright (C) 2021 Arm Ltd.
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/pci.h>
>> +#include <linux/pci-ecam.h>
>> +#include "../pci.h"
>> +#include "pcie-brcmstb.h"
>> +
>> +static int brcm_acpi_init(struct pci_config_window *cfg)
>> +{
>> +	/*
>> +	 * This platform doesn't technically have anything that could be called
>> +	 * ECAM. Its config region has root port specific registers between
>> +	 * standard PCIe defined config registers. Thus the region setup by the
>> +	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
>> +	 * but the footprint isn't a nice power of 2 (40k). For purposes of
>> +	 * mapping the config region we are just going to squash the standard
>> +	 * and nonstandard registers together rather than mapping them separately.
>> +	 */
>> +	iounmap(cfg->win);
>> +	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
>> +	if (!cfg->win)
>> +		goto err_exit;
>> +
>> +	/* MSI is nonstandard as well */
>> +	pci_no_msi();
>> +
>> +	return 0;
>> +err_exit:
>> +	dev_err(cfg->parent, "PCI: Failed to remap config\n");
>> +	return -ENOMEM;
>> +}
>> +
>> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
>> +					unsigned int devfn, int where)
>> +{
>> +	struct pci_config_window *cfg = bus->sysdata;
>> +	void __iomem *base = cfg->win;
>> +	int idx;
>> +	u32 up;
>> +
>> +	/* Accesses to the RC go right to the RC registers if slot==0 */
>> +	if (pci_is_root_bus(bus))
>> +		return PCI_SLOT(devfn) ? NULL : base + where;
>> +
>> +	/* Assure link up before sending request */
> 
> Obviously this is horribly racy, since the link may go down after you
> check but before you send the request.  Maybe the hardware leaves you
> no choice.  I'd feel a little better about it if the comment
> acknowledged that (if it's so) and outlined the consequence of losing
> the race (panic, recoverable error, etc).

Sure, that gets at what appears to be the fundamental problem with this 
bridge, mainly that the HW doesn't appear to be able to handle missing 
config TLP completions in a way that can be recovered.

So, if one loses the race here (and the window is much larger in the DT 
config accessor) the machine takes what is basically an unrecoverable 
exception. I will update the comment to that effect.


> 
>> +	up = readl(base + PCIE_MISC_PCIE_STATUS);
>> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
>> +		return NULL;
>> +
>> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
>> +		return NULL;
>> +
>> +	/* For devices, write to the config space index register */
>> +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
>> +	writel(idx, base + PCIE_EXT_CFG_INDEX);
>> +	return base + PCIE_EXT_CFG_DATA + where;
>> +}
>> +
>> +const struct pci_ecam_ops bcm2711_pcie_ops = {
>> +	.init		= brcm_acpi_init,
>> +	.bus_shift	= 1,
>> +	.pci_ops	= {
>> +		.map_bus	= brcm_pcie_map_conf2,
>> +		.read		= pci_generic_config_read,
>> +		.write		= pci_generic_config_write,
>> +	}
>> +};
>> diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
>> index adea5a4771cf..a5de0285bb7f 100644
>> --- a/include/linux/pci-ecam.h
>> +++ b/include/linux/pci-ecam.h
>> @@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
>>   extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
>>   extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
>>   extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
>> +extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
>>   #endif
>>   
>>   #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
>> -- 
>> 2.31.1
>>



From briannorris at chromium.org  Fri Aug 20 13:38:35 2021
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 20 Aug 2021 13:38:35 -0700
Subject: [PATCH] arm64: dts: rockchip: add RK3399 Gru gpio-line-names
Message-ID: <20210820133829.1.Ica46f428de8c3beb600760dbcd63cf879ec24baf@changeid>

It's convenient to get nice names for GPIOs. In particular, Chrome OS
tooling looks for "AP_FLASH_WP" and "AP_FLASH_WP_L". The rest are
provided for convenience.

Gru-Bob and Gru-Kevin share the gru-chromebook.dtsi, and for the most
part they share pin meanings. I omitted a few areas where components
were available only on one or the other.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 .../dts/rockchip/rk3399-gru-chromebook.dtsi   | 176 +++++++++++++++++
 .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi | 180 ++++++++++++++++++
 2 files changed, 356 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
index 1384dabbdf40..9b2c679f5eca 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
@@ -251,6 +251,182 @@ edp_out_panel: endpoint at 0 {
 	};
 };
 
+&gpio0 {
+	gpio-line-names = /* GPIO0 A 0-7 */
+			  "AP_RTC_CLK_IN",
+			  "EC_AP_INT_L",
+			  "PP1800_AUDIO_EN",
+			  "BT_HOST_WAKE_L",
+			  "WLAN_MODULE_PD_L",
+			  "H1_INT_OD_L",
+			  "CENTERLOGIC_DVS_PWM",
+			  "",
+
+			  /* GPIO0 B 0-4 */
+			  "WIFI_HOST_WAKE_L",
+			  "PMUIO2_33_18_L",
+			  "PP1500_EN",
+			  "AP_EC_WARM_RESET_REQ",
+			  "PP3000_EN";
+};
+
+&gpio1 {
+	gpio-line-names = /* GPIO1 A 0-7 */
+			  "",
+			  "",
+			  "SPK_PA_EN",
+			  "",
+			  "TRACKPAD_INT_L",
+			  "AP_EC_S3_S0_L",
+			  "AP_EC_OVERTEMP",
+			  "AP_SPI_FLASH_MISO",
+
+			  /* GPIO1 B 0-7 */
+			  "AP_SPI_FLASH_MOSI_R",
+			  "AP_SPI_FLASH_CLK_R",
+			  "AP_SPI_FLASH_CS_L_R",
+			  "WLAN_MODULE_RESET_L",
+			  "WIFI_DISABLE_L",
+			  "MIC_INT",
+			  "",
+			  "AP_I2C_DVS_SDA",
+
+			  /* GPIO1 C 0-7 */
+			  "AP_I2C_DVS_SCL",
+			  "AP_BL_EN",
+			  /*
+			   * AP_FLASH_WP is crossystem ABI. Schematics call it
+			   * AP_FW_WP or CPU1_FW_WP, depending on the variant.
+			   */
+			  "AP_FLASH_WP",
+			  "LITCPU_DVS_PWM",
+			  "AP_I2C_AUDIO_SDA",
+			  "AP_I2C_AUDIO_SCL",
+			  "",
+			  "HEADSET_INT_L";
+};
+
+&gpio2 {
+	gpio-line-names = /* GPIO2 A 0-7 */
+			  "",
+			  "",
+			  "SD_IO_PWR_EN",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO2 B 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO2 C 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "AP_SPI_EC_MISO",
+			  "AP_SPI_EC_MOSI",
+			  "AP_SPI_EC_CLK",
+			  "AP_SPI_EC_CS_L",
+
+			  /* GPIO2 D 0-4 */
+			  "BT_DEV_WAKE_L",
+			  "",
+			  "WIFI_PCIE_CLKREQ_L",
+			  "WIFI_PERST_L",
+			  "SD_PWR_3000_1800_L";
+};
+
+&gpio3 {
+	gpio-line-names = /* GPIO3 A 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "AP_SPI_TPM_MISO",
+			  "AP_SPI_TPM_MOSI_R",
+			  "AP_SPI_TPM_CLK_R",
+			  "AP_SPI_TPM_CS_L_R",
+
+			  /* GPIO3 B 0-7 */
+			  "EC_IN_RW",
+			  "",
+			  "AP_I2C_TP_SDA",
+			  "AP_I2C_TP_SCL",
+			  "AP_I2C_TP_PU_EN",
+			  "TOUCH_INT_L",
+			  "",
+			  "",
+
+			  /* GPIO3 C 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO3 D 0-7 */
+			  "I2S0_SCLK",
+			  "I2S0_LRCK_RX",
+			  "I2S0_LRCK_TX",
+			  "I2S0_SDI_0",
+			  "I2S0_SDI_1",
+			  "",
+			  "I2S0_SDO_1",
+			  "I2S0_SDO_0";
+};
+
+&gpio4 {
+	gpio-line-names = /* GPIO4 A 0-7 */
+			  "I2S_MCLK",
+			  "AP_I2C_MIC_SDA",
+			  "AP_I2C_MIC_SCL",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO4 B 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO4 C 0-7 */
+			  "AP_I2C_TS_SDA",
+			  "AP_I2C_TS_SCL",
+			  "GPU_DVS_PWM",
+			  "UART_DBG_TX_AP_RX",
+			  "UART_AP_TX_DBG_RX",
+			  "",
+			  "BIGCPU_DVS_PWM",
+			  "EDP_HPD_3V0",
+
+			  /* GPIO4 D 0-5 */
+			  "SD_CARD_DET_L",
+			  "USB_DP_HPD",
+			  "TOUCH_RESET_L",
+			  "PP3300_DISP_EN",
+			  "",
+			  "SD_SLOT_PWR_EN";
+};
+
 ap_i2c_mic: &i2c1 {
 	status = "okay";
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
index 5d7a9d96d163..61afb5f0f15b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
@@ -389,6 +389,186 @@ &cru {
 		<400000000>;
 };
 
+&gpio0 {
+	gpio-line-names = /* GPIO0 A 0-7 */
+			  "CLK_32K_AP",
+			  "EC_IN_RW_OD",
+			  "SPK_PA_EN",
+			  "WLAN_PERST_1V8_L",
+			  "WLAN_PD_1V8_L",
+			  "WLAN_RF_KILL_1V8_L",
+			  "BIGCPU_DVS_PWM",
+			  "SD_CD_L_JTAG_EN",
+
+			  /* GPIO0 B 0-5 */
+			  "BT_EN_BT_RF_KILL_1V8_L",
+			  "PMUIO2_33_18_L_PP3300_S0_EN",
+			  "TOUCH_RESET_L",
+			  "AP_EC_WARM_RESET_REQ",
+			  "PEN_RESET_L",
+			  /*
+			   * AP_FLASH_WP_L is crossystem ABI. Schematics call
+			   * it AP_FLASH_WP_R_ODL.
+			   */
+			  "AP_FLASH_WP_L";
+};
+
+&gpio1 {
+	gpio-line-names = /* GPIO1 A 0-7 */
+			  "PEN_INT_ODL",
+			  "PEN_EJECT_ODL",
+			  "BT_HOST_WAKE_1V8_L",
+			  "WLAN_HOST_WAKE_1V8_L",
+			  "TOUCH_INT_ODL",
+			  "AP_EC_S3_S0_L",
+			  "AP_EC_OVERTEMP",
+			  "AP_SPI_FLASH_MISO",
+
+			  /* GPIO1 B 0-7 */
+			  "AP_SPI_FLASH_MOSI_R",
+			  "AP_SPI_FLASH_CLK_R",
+			  "AP_SPI_FLASH_CS_L_R",
+			  "SD_CARD_DET_ODL",
+			  "",
+			  "AP_EXPANSION_IO1",
+			  "AP_EXPANSION_IO2",
+			  "AP_I2C_DISP_SDA",
+
+			  /* GPIO1 C 0-7 */
+			  "AP_I2C_DISP_SCL",
+			  "H1_INT_ODL",
+			  "EC_AP_INT_ODL",
+			  "LITCPU_DVS_PWM",
+			  "AP_I2C_AUDIO_SDA",
+			  "AP_I2C_AUDIO_SCL",
+			  "AP_EXPANSION_IO3",
+			  "HEADSET_INT_ODL",
+
+			  /* GPIO1 D0 */
+			  "AP_EXPANSION_IO4";
+};
+
+&gpio2 {
+	gpio-line-names = /* GPIO2 A 0-7 */
+			  "AP_I2C_PEN_SDA",
+			  "AP_I2C_PEN_SCL",
+			  "SD_IO_PWR_EN",
+			  "UCAM_RST_L",
+			  "PP1250_CAM_EN",
+			  "WCAM_RST_L",
+			  "AP_EXPANSION_IO5",
+			  "AP_I2C_CAM_SDA",
+
+			  /* GPIO2 B 0-7 */
+			  "AP_I2C_CAM_SCL",
+			  "AP_H1_SPI_MISO",
+			  "AP_H1_SPI_MOSI",
+			  "AP_H1_SPI_CLK",
+			  "AP_H1_SPI_CS_L",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO2 C 0-7 */
+			  "UART_EXPANSION_TX_AP_RX",
+			  "UART_AP_TX_EXPANSION_RX",
+			  "UART_EXPANSION_RTS_AP_CTS",
+			  "UART_AP_RTS_EXPANSION_CTS",
+			  "AP_SPI_EC_MISO",
+			  "AP_SPI_EC_MOSI",
+			  "AP_SPI_EC_CLK",
+			  "AP_SPI_EC_CS_L",
+
+			  /* GPIO2 D 0-4 */
+			  "PP2800_CAM_EN",
+			  "CLK_24M_CAM",
+			  "WLAN_PCIE_CLKREQ_1V8_L",
+			  "",
+			  "SD_PWR_3000_1800_L";
+};
+
+&gpio3 {
+	gpio-line-names = /* GPIO3 A 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO3 B 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO3 C 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO3 D 0-7 */
+			  "I2S0_SCLK",
+			  "I2S0_LRCK_RX",
+			  "I2S0_LRCK_TX",
+			  "I2S0_SDI_0",
+			  "STRAP_LCDBIAS_L",
+			  "STRAP_FEATURE_1",
+			  "STRAP_FEATURE_2",
+			  "I2S0_SDO_0";
+};
+
+&gpio4 {
+	gpio-line-names = /* GPIO4 A 0-7 */
+			  "I2S_MCLK",
+			  "AP_I2C_EXPANSION_SDA",
+			  "AP_I2C_EXPANSION_SCL",
+			  "DMIC_EN",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO4 B 0-7 */
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+
+			  /* GPIO4 C 0-7 */
+			  "AP_I2C_TS_SDA",
+			  "AP_I2C_TS_SCL",
+			  "GPU_DVS_PWM",
+			  "UART_DBG_TX_AP_RX",
+			  "UART_AP_TX_DBG_RX",
+			  "BL_EN",
+			  "BL_PWM",
+			  "",
+
+			  /* GPIO4 D 0-5 */
+			  "",
+			  "DISPLAY_RST_L",
+			  "",
+			  "PPVARP_LCD_EN",
+			  "PPVARN_LCD_EN",
+			  "SD_SLOT_PWR_EN";
+};
+
 &i2c_tunnel {
 	google,remote-bus = <0>;
 };
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From dianders at chromium.org  Fri Aug 20 14:04:51 2021
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 20 Aug 2021 14:04:51 -0700
Subject: [PATCH] arm64: dts: rockchip: add RK3399 Gru gpio-line-names
In-Reply-To: <20210820133829.1.Ica46f428de8c3beb600760dbcd63cf879ec24baf@changeid>
References: <20210820133829.1.Ica46f428de8c3beb600760dbcd63cf879ec24baf@changeid>
Message-ID: <CAD=FV=UwAcJEDE3BQYuCDq4kRKPFAsuzPOseGY66wfXcW8Wn7A@mail.gmail.com>

Hi,

On Fri, Aug 20, 2021 at 1:38 PM Brian Norris <briannorris at chromium.org> wrote:
>
> It's convenient to get nice names for GPIOs. In particular, Chrome OS
> tooling looks for "AP_FLASH_WP" and "AP_FLASH_WP_L". The rest are
> provided for convenience.
>
> Gru-Bob and Gru-Kevin share the gru-chromebook.dtsi, and for the most
> part they share pin meanings. I omitted a few areas where components
> were available only on one or the other.
>
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
>
>  .../dts/rockchip/rk3399-gru-chromebook.dtsi   | 176 +++++++++++++++++
>  .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi | 180 ++++++++++++++++++
>  2 files changed, 356 insertions(+)

I didn't walk through the schematics and double-check the rails
personally, but the idea here is right. This matches the type of thing
we did for veyron, like in commit ca3516b32cd9 ("ARM: dts: rockchip:
Add pin names for rk3288-veyron-minnie")

I guess one minor nit (now that I look back on the veyron patch where
I mentioned it explicitly in the commit message) is that on the veyron
ones we sorted this down at the bottom with the other pinctrl stuff
instead of sorting it alphabetically with everything else. I'll let
Heiko say which he likes better.

I also notice for veyron that we had a second "ABI" exception for the
recovery mode pin, but I believe that goes through a different
mechanism now so we're good there.

Even though I didn't do a line-by-line review, I'll still give:

Reviewed-by: Douglas Anderson <dianders at chromium.org>

...though it's possible an "Acked-by" would be more in the spirit of
that? Not sure...

-Doug


From briannorris at chromium.org  Fri Aug 20 14:16:23 2021
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 20 Aug 2021 14:16:23 -0700
Subject: [PATCH] arm64: dts: rockchip: add RK3399 Gru gpio-line-names
In-Reply-To: <CAD=FV=UwAcJEDE3BQYuCDq4kRKPFAsuzPOseGY66wfXcW8Wn7A@mail.gmail.com>
References: <20210820133829.1.Ica46f428de8c3beb600760dbcd63cf879ec24baf@changeid>
 <CAD=FV=UwAcJEDE3BQYuCDq4kRKPFAsuzPOseGY66wfXcW8Wn7A@mail.gmail.com>
Message-ID: <CA+ASDXO=Bjr+f4mtXwt7vtiTz6tSw7SPuY1RvNWMp6-43Baqfg@mail.gmail.com>

On Fri, Aug 20, 2021 at 2:05 PM Doug Anderson <dianders at chromium.org> wrote:
> I guess one minor nit (now that I look back on the veyron patch where
> I mentioned it explicitly in the commit message) is that on the veyron
> ones we sorted this down at the bottom with the other pinctrl stuff
> instead of sorting it alphabetically with everything else. I'll let
> Heiko say which he likes better.

Huh, didn't notice that semi-convention. I can sort it however Heiko prefers.

> I also notice for veyron that we had a second "ABI" exception for the
> recovery mode pin, but I believe that goes through a different
> mechanism now so we're good there.

I believe the recovery mode pin is dropped from recent designs (don't
quote me in general on that), and there's a different mechanism used
just to get the at-boot-time "recovery mode" state directly from the
firmware.

> Even though I didn't do a line-by-line review, I'll still give:
>
> Reviewed-by: Douglas Anderson <dianders at chromium.org>
>
> ...though it's possible an "Acked-by" would be more in the spirit of
> that? Not sure...

Thanks!

Brian


From dev at lynxeye.de  Fri Aug 20 14:25:37 2021
From: dev at lynxeye.de (Lucas Stach)
Date: Fri, 20 Aug 2021 23:25:37 +0200
Subject: [PATCH] arm64: dts: imx8mq-reform2: add uSDHC2 CD pinctrl
Message-ID: <20210820212537.1611678-1-dev@lynxeye.de>

The SD card slot on the Reform 2 uses the card detect pad routed to
the uSDHC2 module as intended. This is currently working as it is the
default mux setting for this pad, but better be explicit and add it
to the pinctrl node.

Signed-off-by: Lucas Stach <dev at lynxeye.de>
---
 arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts b/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
index 2535268f0984..4f2db6197b39 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-mnt-reform2.dts
@@ -202,6 +202,7 @@ MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX		0x45
 
 	pinctrl_usdhc2: usdhc2grp {
 		fsl,pins = <
+			MX8MQ_IOMUXC_SD2_CD_B_USDHC2_CD_B		0x0
 			MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK			0x83
 			MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD			0xc3
 			MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0		0xc3
-- 
2.31.1



From paulmck at kernel.org  Fri Aug 20 15:10:56 2021
From: paulmck at kernel.org (Paul E. McKenney)
Date: Fri, 20 Aug 2021 15:10:56 -0700
Subject: [PATCH v2] rcutorture: Avoid problematic critical section
 nesting on PREEMPT_RT
In-Reply-To: <20210820074236.2zli4nje7bof62rh@linutronix.de>
References: <20210811201354.1976839-2-valentin.schneider@arm.com>
 <20210817121345.5iyj5epemczn3a52@linutronix.de>
 <20210817131741.evduh4fw7vyv2dzt@linutronix.de>
 <20210817144018.nqssoq475vitrqlv@linutronix.de>
 <20210818224651.GY4126399@paulmck-ThinkPad-P17-Gen-1>
 <20210819153927.clqxr4f7qegpflbr@linutronix.de>
 <20210819154708.3efz6jtgwtuhpeds@linutronix.de>
 <20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-1>
 <561ab28b18c31fbc221f4cb0c4df6db9b0538675.camel@redhat.com>
 <20210820074236.2zli4nje7bof62rh@linutronix.de>
Message-ID: <20210820221056.GL4126399@paulmck-ThinkPad-P17-Gen-1>

On Fri, Aug 20, 2021 at 09:42:36AM +0200, Sebastian Andrzej Siewior wrote:
> From: "From: Scott Wood" <swood at redhat.com>
> 
> rcutorture is generating some nesting scenarios that are not compatible on PREEMPT_RT.
> For example:
> 	preempt_disable();
> 	rcu_read_lock_bh();
> 	preempt_enable();
> 	rcu_read_unlock_bh();
> 
> The problem here is that on PREEMPT_RT the bottom halves have to be
> disabled and enabled in preemptible context.
> 
> Reorder locking: start with BH locking and continue with then with
> disabling preemption or interrupts. In the unlocking do it reverse by
> first enabling interrupts and preemption and BH at the very end.
> Ensure that on PREEMPT_RT BH locking remains unchanged if in
> non-preemptible context.
> 
> Link: https://lkml.kernel.org/r/20190911165729.11178-6-swood at redhat.com
> Link: https://lkml.kernel.org/r/20210819182035.GF4126399 at paulmck-ThinkPad-P17-Gen-1
> Signed-off-by: Scott Wood <swood at redhat.com>
> [bigeasy: Drop ATOM_BH, make it only about changing BH in atomic
> context. Allow enabling RCU in IRQ-off section. Reword commit message.]
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>

Looks plausible.  ;-)

I have queued this for testing and further review.  If all goes well,
perhaps the v5.16 merge window.

							Thanx, Paul

> ---
> v1?v2:
>   - Drop the ATOM_BH* bits. There don't seem to be needed, Paul did not
>     ant the preempt-disable around enabling/disabling BH as it might fix
>     things that RCU should take care.
> 
>   - Allow enabling RCU with disabled interrupts on RT. Scott confirmed
>     that it was needed but might no longer be needed. Paul said that it
>     might have been required at some point. It survived multiple 6h long
>     TREE01 and TREE06 testing.
> 
>  kernel/rcu/rcutorture.c | 48 ++++++++++++++++++++++++++++++-----------
>  1 file changed, 36 insertions(+), 12 deletions(-)
> 
> diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
> index 40ef5417d9545..d2ef535530b10 100644
> --- a/kernel/rcu/rcutorture.c
> +++ b/kernel/rcu/rcutorture.c
> @@ -1432,28 +1432,34 @@ static void rcutorture_one_extend(int *readstate, int newstate,
>  	/* First, put new protection in place to avoid critical-section gap. */
>  	if (statesnew & RCUTORTURE_RDR_BH)
>  		local_bh_disable();
> +	if (statesnew & RCUTORTURE_RDR_RBH)
> +		rcu_read_lock_bh();
>  	if (statesnew & RCUTORTURE_RDR_IRQ)
>  		local_irq_disable();
>  	if (statesnew & RCUTORTURE_RDR_PREEMPT)
>  		preempt_disable();
> -	if (statesnew & RCUTORTURE_RDR_RBH)
> -		rcu_read_lock_bh();
>  	if (statesnew & RCUTORTURE_RDR_SCHED)
>  		rcu_read_lock_sched();
>  	if (statesnew & RCUTORTURE_RDR_RCU)
>  		idxnew = cur_ops->readlock() << RCUTORTURE_RDR_SHIFT;
>  
> -	/* Next, remove old protection, irq first due to bh conflict. */
> +	/*
> +	 * Next, remove old protection, in decreasing order of strength
> +	 * to avoid unlock paths that aren't safe in the stronger
> +	 * context. Namely: BH can not be enabled with disabled interrupts.
> +	 * Additionally PREEMPT_RT requires that BH is enabled in preemptible
> +	 * context.
> +	 */
>  	if (statesold & RCUTORTURE_RDR_IRQ)
>  		local_irq_enable();
> -	if (statesold & RCUTORTURE_RDR_BH)
> -		local_bh_enable();
>  	if (statesold & RCUTORTURE_RDR_PREEMPT)
>  		preempt_enable();
> -	if (statesold & RCUTORTURE_RDR_RBH)
> -		rcu_read_unlock_bh();
>  	if (statesold & RCUTORTURE_RDR_SCHED)
>  		rcu_read_unlock_sched();
> +	if (statesold & RCUTORTURE_RDR_BH)
> +		local_bh_enable();
> +	if (statesold & RCUTORTURE_RDR_RBH)
> +		rcu_read_unlock_bh();
>  	if (statesold & RCUTORTURE_RDR_RCU) {
>  		bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);
>  
> @@ -1496,6 +1502,9 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
>  	int mask = rcutorture_extend_mask_max();
>  	unsigned long randmask1 = torture_random(trsp) >> 8;
>  	unsigned long randmask2 = randmask1 >> 3;
> +	unsigned long preempts = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;
> +	unsigned long preempts_irq = preempts | RCUTORTURE_RDR_IRQ;
> +	unsigned long bhs = RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
>  
>  	WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT);
>  	/* Mostly only one bit (need preemption!), sometimes lots of bits. */
> @@ -1503,11 +1512,26 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp)
>  		mask = mask & randmask2;
>  	else
>  		mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS));
> -	/* Can't enable bh w/irq disabled. */
> -	if ((mask & RCUTORTURE_RDR_IRQ) &&
> -	    ((!(mask & RCUTORTURE_RDR_BH) && (oldmask & RCUTORTURE_RDR_BH)) ||
> -	     (!(mask & RCUTORTURE_RDR_RBH) && (oldmask & RCUTORTURE_RDR_RBH))))
> -		mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
> +
> +	/*
> +	 * Can't enable bh w/irq disabled.
> +	 */
> +	if (mask & RCUTORTURE_RDR_IRQ)
> +		mask |= oldmask & bhs;
> +
> +	/*
> +	 * Ideally these sequences would be detected in debug builds
> +	 * (regardless of RT), but until then don't stop testing
> +	 * them on non-RT.
> +	 */
> +	if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> +		/* Can't modify BH in atomic context */
> +		if (oldmask & preempts_irq)
> +			mask &= ~bhs;
> +		if ((oldmask | mask) & preempts_irq)
> +			mask |= oldmask & bhs;
> +	}
> +
>  	return mask ?: RCUTORTURE_RDR_RCU;
>  }
>  
> -- 
> 2.33.0
> 


From seanjc at google.com  Fri Aug 20 15:25:11 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 20 Aug 2021 22:25:11 +0000
Subject: [PATCH 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <407716135.20250.1629484298288.JavaMail.zimbra@efficios.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-5-seanjc@google.com>
 <1540548616.19739.1629409956315.JavaMail.zimbra@efficios.com>
 <YR7qXvnI/AQM10gU@google.com>
 <407716135.20250.1629484298288.JavaMail.zimbra@efficios.com>
Message-ID: <YSArx+ppjIH+6/uK@google.com>

On Fri, Aug 20, 2021, Mathieu Desnoyers wrote:
> I still really hate flakiness in tests, because then people stop caring when they
> fail once in a while. And with the nature of rseq, a once-in-a-while failure is a
> big deal. Let's see if we can use other tricks to ensure stability of the cpu id
> without changing timings too much.

Yeah, zero agrument regarding flaky tests.

> One idea would be to use a seqcount lock.

A sequence counter did the trick!  Thanks much!

> But even if we use that, I'm concerned that the very long writer critical
> section calling sched_setaffinity would need to be alternated with a sleep to
> ensure the read-side progresses. The sleep delay could be relatively small
> compared to the duration of the sched_setaffinity call, e.g. ratio 1:10.

I already had an arbitrary usleep(10) to let the reader make progress between
sched_setaffinity() calls.  Dropping it down to 1us didn't affect reproducibility,
so I went with that to shave those precious cycles :-)  Eliminating the delay
entirely did result in no repro, which was a nice confirmation that it's needed
to let the reader get back into KVM_RUN.

Thanks again!


From seanjc at google.com  Fri Aug 20 15:26:53 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 20 Aug 2021 22:26:53 +0000
Subject: [PATCH 1/5] KVM: rseq: Update rseq when processing NOTIFY_RESUME
 on xfer to KVM guest
In-Reply-To: <1872633041.20290.1629485463253.JavaMail.zimbra@efficios.com>
References: <20210818001210.4073390-1-seanjc@google.com>
 <20210818001210.4073390-2-seanjc@google.com>
 <1673583543.19718.1629409152244.JavaMail.zimbra@efficios.com>
 <YR7tzZ98XC6OV2vu@google.com>
 <1872633041.20290.1629485463253.JavaMail.zimbra@efficios.com>
Message-ID: <YSAsLShyWK3xgxse@google.com>

On Fri, Aug 20, 2021, Mathieu Desnoyers wrote:
> Without the lazy clear scheme, a rseq c.s. would look like:
> 
>  *                     init(rseq_cs)
>  *                     cpu = TLS->rseq::cpu_id_start
>  *   [1]               TLS->rseq::rseq_cs = rseq_cs
>  *   [start_ip]        ----------------------------
>  *   [2]               if (cpu != TLS->rseq::cpu_id)
>  *                             goto abort_ip;
>  *   [3]               <last_instruction_in_cs>
>  *   [post_commit_ip]  ----------------------------
>  *   [4]               TLS->rseq::rseq_cs = NULL
> 
> But as a fast-path optimization, [4] is not entirely needed because the rseq_cs
> descriptor contains information about the instruction pointer range of the critical
> section. Therefore, userspace can omit [4], but if the kernel never clears it, it
> means that it will have to re-read the rseq_cs descriptor's content each time it
> needs to check it to confirm that it is not nested over a rseq c.s..
> 
> So making the kernel lazily clear the rseq_cs pointer is just an optimization which
> ensures that the kernel won't do useless work the next time it needs to check
> rseq_cs, given that it has already validated that the userspace code is currently
> not within the rseq c.s. currently advertised by the rseq_cs field.

Thanks for the explanation, much appreciated!


From lkp at intel.com  Fri Aug 20 15:26:47 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Aug 2021 06:26:47 +0800
Subject: [soc:aspeed/soc] BUILD SUCCESS
 2f9b25fa668218f22a85ebe8c55d1d132fc0019d
Message-ID: <61202c27.6Zxl00gI/pyMd+ol%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git aspeed/soc
branch HEAD: 2f9b25fa668218f22a85ebe8c55d1d132fc0019d  soc: aspeed: Re-enable FWH2AHB on AST2600

elapsed time: 2434m

configs tested: 149
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210819
h8300                       h8s-sim_defconfig
sh                           se7750_defconfig
riscv                            alldefconfig
arm                      pxa255-idp_defconfig
sh                            hp6xx_defconfig
nios2                         3c120_defconfig
m68k                        mvme16x_defconfig
arm                        keystone_defconfig
arm                        vexpress_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                  mpc885_ads_defconfig
powerpc                 mpc8313_rdb_defconfig
powerpc                    klondike_defconfig
powerpc                          g5_defconfig
sparc64                          alldefconfig
riscv                          rv32_defconfig
sh                ecovec24-romimage_defconfig
arm                            mmp2_defconfig
powerpc                  storcenter_defconfig
sh                        dreamcast_defconfig
ia64                      gensparse_defconfig
sh                          lboxre2_defconfig
powerpc                     tqm8555_defconfig
arc                     nsimosci_hs_defconfig
openrisc                    or1ksim_defconfig
m68k                            q40_defconfig
mips                        qi_lb60_defconfig
powerpc                      ppc6xx_defconfig
powerpc                 mpc837x_mds_defconfig
arm                         nhk8815_defconfig
powerpc                     mpc5200_defconfig
sh                           se7206_defconfig
xtensa                generic_kc705_defconfig
powerpc                     pseries_defconfig
arm                        magician_defconfig
mips                            gpr_defconfig
arm                       imx_v4_v5_defconfig
h8300                     edosk2674_defconfig
sh                         apsh4a3a_defconfig
xtensa                         virt_defconfig
csky                             alldefconfig
mips                        nlm_xlr_defconfig
mips                       lemote2f_defconfig
mips                           ci20_defconfig
m68k                        stmark2_defconfig
mips                         rt305x_defconfig
mips                     cu1830-neo_defconfig
sh                         ap325rxa_defconfig
sh                           se7751_defconfig
mips                           jazz_defconfig
sh                   secureedge5410_defconfig
powerpc                     rainier_defconfig
m68k                         amcore_defconfig
m68k                        mvme147_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
x86_64               randconfig-a013-20210819
x86_64               randconfig-a011-20210819
x86_64               randconfig-a012-20210819
x86_64               randconfig-a016-20210819
x86_64               randconfig-a014-20210819
x86_64               randconfig-a015-20210819
i386                 randconfig-a015-20210819
i386                 randconfig-a011-20210819
i386                 randconfig-a014-20210819
i386                 randconfig-a013-20210819
i386                 randconfig-a016-20210819
i386                 randconfig-a012-20210819
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210818
i386                 randconfig-c001-20210819
x86_64               randconfig-a004-20210819
x86_64               randconfig-a006-20210819
x86_64               randconfig-a003-20210819
x86_64               randconfig-a002-20210819
x86_64               randconfig-a005-20210819
x86_64               randconfig-a001-20210819
i386                 randconfig-a004-20210819
i386                 randconfig-a006-20210819
i386                 randconfig-a001-20210819
i386                 randconfig-a002-20210819
i386                 randconfig-a003-20210819
i386                 randconfig-a005-20210819
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From rdunlap at infradead.org  Fri Aug 20 15:29:53 2021
From: rdunlap at infradead.org (Randy Dunlap)
Date: Fri, 20 Aug 2021 15:29:53 -0700
Subject: [PATCH v2] clk: zynqmp: fix kernel doc
In-Reply-To: <1629446294-1056-1-git-send-email-rajan.vaja@xilinx.com>
References: <1629445113-32649-1-git-send-email-rajan.vaja@xilinx.com>
 <1629446294-1056-1-git-send-email-rajan.vaja@xilinx.com>
Message-ID: <cd0903a4-6d7a-ab52-7dec-dfd8e978daf7@infradead.org>

On 8/20/21 12:58 AM, Rajan Vaja wrote:
> Add missing description of 'custom_type_flag' structure member.
> 
> Fixes: e605fa9c4a0c ("clk: zynqmp: Add support for custom type flags")
> 
> Signed-off-by: Rajan Vaja <rajan.vaja at xilinx.com>
> ---
> Changes in v2:
>   - Updated Fixes tag.
> ---
>   drivers/clk/zynqmp/clk-zynqmp.h | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h
> index 84fa80a..a3cd2f8 100644
> --- a/drivers/clk/zynqmp/clk-zynqmp.h
> +++ b/drivers/clk/zynqmp/clk-zynqmp.h
> @@ -56,6 +56,7 @@ enum topology_type {
>    * @type:	Type of topology
>    * @flag:	Topology flags
>    * @type_flag:	Topology type specific flag
> + * @custom_type_flag: Topology type specific custome flag

                                                 custom

>    */
>   struct clock_topology {
>   	u32 type;
> 


-- 
~Randy



From l.stach at pengutronix.de  Fri Aug 20 15:44:02 2021
From: l.stach at pengutronix.de (Lucas Stach)
Date: Sat, 21 Aug 2021 00:44:02 +0200
Subject: [PATCH] arm64: dts: zii-ultra: add PCIe PHY supply
Message-ID: <20210820224402.2011354-1-l.stach@pengutronix.de>

The ZII Ultra board uses the same design as the EVK board supplying
PCIE_VPH with 3.3V. Add this connection to the DT to allow the PCIe
driver to enable the internal PHY regulator, as required by the
reference manual.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
index a08a568c31d9..2222ef7b3eab 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
@@ -555,6 +555,7 @@ &pcie0 {
 	         <&clk IMX8MQ_CLK_PCIE1_PHY>,
 	         <&pcie0_refclk>;
 	clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+	vph-supply = <&vgen5_reg>;
 	status = "okay";
 };
 
@@ -567,6 +568,7 @@ &pcie1 {
 	         <&clk IMX8MQ_CLK_PCIE2_PHY>,
 	         <&pcie1_refclk>;
 	clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+	vph-supply = <&vgen5_reg>;
 	status = "okay";
 };
 
-- 
2.30.2



From seanjc at google.com  Fri Aug 20 15:49:57 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 20 Aug 2021 15:49:57 -0700
Subject: [PATCH v2 0/5] KVM: rseq: Fix and a test for a KVM+rseq bug
Message-ID: <20210820225002.310652-1-seanjc@google.com>

Patch 1 fixes a KVM+rseq bug where KVM's handling of TIF_NOTIFY_RESUME,
e.g. for task migration, clears the flag without informing rseq and leads
to stale data in userspace's rseq struct.

Patch 2 is a cleanup to try and make future bugs less likely.  It's also
a baby step towards moving and renaming tracehook_notify_resume() since
it has nothing to do with tracing.

Patch 3 is a fix/cleanup to stop overriding x86's unistd_{32,64}.h when
the include path (intentionally) omits tools' uapi headers.  KVM's
selftests do exactly that so that they can pick up the uapi headers from
the installed kernel headers, and still use various tools/ headers that
mirror kernel code, e.g. linux/types.h.  This allows the new test in
patch 4 to reference __NR_rseq without having to manually define it.

Patch 4 is a regression test for the KVM+rseq bug.

Patch 5 is a cleanup made possible by patch 3.

v2:
  - Don't touch rseq_cs when handling KVM case so that rseq_syscall() will
    still detect a naughty userspace. [Mathieu]
  - Use a sequence counter + retry in the test to ensure the process isn't
    migrated between sched_getcpu() and reading rseq.cpu_id, i.e. to
    avoid a flaky test. [Mathieu]
  - Add Mathieu's ack for patch 2.
  - Add more comments in the test.

v1: https://lkml.kernel.org/r/20210818001210.4073390-1-seanjc at google.com

Sean Christopherson (5):
  KVM: rseq: Update rseq when processing NOTIFY_RESUME on xfer to KVM
    guest
  entry: rseq: Call rseq_handle_notify_resume() in
    tracehook_notify_resume()
  tools: Move x86 syscall number fallbacks to .../uapi/
  KVM: selftests: Add a test for KVM_RUN+rseq to detect task migration
    bugs
  KVM: selftests: Remove __NR_userfaultfd syscall fallback

 arch/arm/kernel/signal.c                      |   1 -
 arch/arm64/kernel/signal.c                    |   1 -
 arch/csky/kernel/signal.c                     |   4 +-
 arch/mips/kernel/signal.c                     |   4 +-
 arch/powerpc/kernel/signal.c                  |   4 +-
 arch/s390/kernel/signal.c                     |   1 -
 include/linux/tracehook.h                     |   2 +
 kernel/entry/common.c                         |   4 +-
 kernel/rseq.c                                 |  14 +-
 .../x86/include/{ => uapi}/asm/unistd_32.h    |   0
 .../x86/include/{ => uapi}/asm/unistd_64.h    |   3 -
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   3 +
 tools/testing/selftests/kvm/rseq_test.c       | 154 ++++++++++++++++++
 14 files changed, 175 insertions(+), 21 deletions(-)
 rename tools/arch/x86/include/{ => uapi}/asm/unistd_32.h (100%)
 rename tools/arch/x86/include/{ => uapi}/asm/unistd_64.h (83%)
 create mode 100644 tools/testing/selftests/kvm/rseq_test.c

-- 
2.33.0.rc2.250.ged5fa647cd-goog



From seanjc at google.com  Fri Aug 20 15:49:58 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 20 Aug 2021 15:49:58 -0700
Subject: [PATCH v2 1/5] KVM: rseq: Update rseq when processing NOTIFY_RESUME
 on xfer to KVM guest
In-Reply-To: <20210820225002.310652-1-seanjc@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
Message-ID: <20210820225002.310652-2-seanjc@google.com>

Invoke rseq's NOTIFY_RESUME handler when processing the flag prior to
transferring to a KVM guest, which is roughly equivalent to an exit to
userspace and processes many of the same pending actions.  While the task
cannot be in an rseq critical section as the KVM path is reachable only
by via ioctl(KVM_RUN), the side effects that apply to rseq outside of a
critical section still apply, e.g. the current CPU needs to be updated if
the task is migrated.

Clearing TIF_NOTIFY_RESUME without informing rseq can lead to segfaults
and other badness in userspace VMMs that use rseq in combination with KVM,
e.g. due to the CPU ID being stale after task migration.

Fixes: 72c3c0fe54a3 ("x86/kvm: Use generic xfer to guest work function")
Reported-by: Peter Foley <pefoley at google.com>
Bisected-by: Doug Evans <dje at google.com>
Cc: Shakeel Butt <shakeelb at google.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: stable at vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 kernel/entry/kvm.c |  4 +++-
 kernel/rseq.c      | 14 +++++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
index 49972ee99aff..049fd06b4c3d 100644
--- a/kernel/entry/kvm.c
+++ b/kernel/entry/kvm.c
@@ -19,8 +19,10 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
 		if (ti_work & _TIF_NEED_RESCHED)
 			schedule();
 
-		if (ti_work & _TIF_NOTIFY_RESUME)
+		if (ti_work & _TIF_NOTIFY_RESUME) {
 			tracehook_notify_resume(NULL);
+			rseq_handle_notify_resume(NULL, NULL);
+		}
 
 		ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
 		if (ret)
diff --git a/kernel/rseq.c b/kernel/rseq.c
index 35f7bd0fced0..6d45ac3dae7f 100644
--- a/kernel/rseq.c
+++ b/kernel/rseq.c
@@ -282,9 +282,17 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
 
 	if (unlikely(t->flags & PF_EXITING))
 		return;
-	ret = rseq_ip_fixup(regs);
-	if (unlikely(ret < 0))
-		goto error;
+
+	/*
+	 * regs is NULL if and only if the caller is in a syscall path.  Skip
+	 * fixup and leave rseq_cs as is so that rseq_sycall() will detect and
+	 * kill a misbehaving userspace on debug kernels.
+	 */
+	if (regs) {
+		ret = rseq_ip_fixup(regs);
+		if (unlikely(ret < 0))
+			goto error;
+	}
 	if (unlikely(rseq_update_cpu_id(t)))
 		goto error;
 	return;
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From seanjc at google.com  Fri Aug 20 15:49:59 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 20 Aug 2021 15:49:59 -0700
Subject: [PATCH v2 2/5] entry: rseq: Call rseq_handle_notify_resume() in
 tracehook_notify_resume()
In-Reply-To: <20210820225002.310652-1-seanjc@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
Message-ID: <20210820225002.310652-3-seanjc@google.com>

Invoke rseq_handle_notify_resume() from tracehook_notify_resume() now
that the two function are always called back-to-back by architectures
that have rseq.  The rseq helper is stubbed out for architectures that
don't support rseq, i.e. this is a nop across the board.

Note, tracehook_notify_resume() is horribly named and arguably does not
belong in tracehook.h as literally every line of code in it has nothing
to do with tracing.  But, that's been true since commit a42c6ded827d
("move key_repace_session_keyring() into tracehook_notify_resume()")
first usurped tracehook_notify_resume() back in 2012.  Punt cleaning that
mess up to future patches.

No functional change intended.

Acked-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm/kernel/signal.c     | 1 -
 arch/arm64/kernel/signal.c   | 1 -
 arch/csky/kernel/signal.c    | 4 +---
 arch/mips/kernel/signal.c    | 4 +---
 arch/powerpc/kernel/signal.c | 4 +---
 arch/s390/kernel/signal.c    | 1 -
 include/linux/tracehook.h    | 2 ++
 kernel/entry/common.c        | 4 +---
 kernel/entry/kvm.c           | 4 +---
 9 files changed, 7 insertions(+), 18 deletions(-)

diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index a3a38d0a4c85..9df68d139965 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -670,7 +670,6 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 				uprobe_notify_resume(regs);
 			} else {
 				tracehook_notify_resume(regs);
-				rseq_handle_notify_resume(NULL, regs);
 			}
 		}
 		local_irq_disable();
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 23036334f4dc..22b55db13da6 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -951,7 +951,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 
 			if (thread_flags & _TIF_NOTIFY_RESUME) {
 				tracehook_notify_resume(regs);
-				rseq_handle_notify_resume(NULL, regs);
 
 				/*
 				 * If we reschedule after checking the affinity
diff --git a/arch/csky/kernel/signal.c b/arch/csky/kernel/signal.c
index 312f046d452d..bc4238b9f709 100644
--- a/arch/csky/kernel/signal.c
+++ b/arch/csky/kernel/signal.c
@@ -260,8 +260,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
 		do_signal(regs);
 
-	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+	if (thread_info_flags & _TIF_NOTIFY_RESUME)
 		tracehook_notify_resume(regs);
-		rseq_handle_notify_resume(NULL, regs);
-	}
 }
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index f1e985109da0..c9b2a75563e1 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -906,10 +906,8 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
 		do_signal(regs);
 
-	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+	if (thread_info_flags & _TIF_NOTIFY_RESUME)
 		tracehook_notify_resume(regs);
-		rseq_handle_notify_resume(NULL, regs);
-	}
 
 	user_enter();
 }
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index e600764a926c..b93b87df499d 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -293,10 +293,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
 		do_signal(current);
 	}
 
-	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+	if (thread_info_flags & _TIF_NOTIFY_RESUME)
 		tracehook_notify_resume(regs);
-		rseq_handle_notify_resume(NULL, regs);
-	}
 }
 
 static unsigned long get_tm_stackpointer(struct task_struct *tsk)
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 78ef53b29958..b307db26bf2d 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -537,5 +537,4 @@ void arch_do_signal_or_restart(struct pt_regs *regs, bool has_signal)
 void do_notify_resume(struct pt_regs *regs)
 {
 	tracehook_notify_resume(regs);
-	rseq_handle_notify_resume(NULL, regs);
 }
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index 3e80c4bc66f7..2564b7434b4d 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -197,6 +197,8 @@ static inline void tracehook_notify_resume(struct pt_regs *regs)
 
 	mem_cgroup_handle_over_high();
 	blkcg_maybe_throttle_current();
+
+	rseq_handle_notify_resume(NULL, regs);
 }
 
 /*
diff --git a/kernel/entry/common.c b/kernel/entry/common.c
index bf16395b9e13..d5a61d565ad5 100644
--- a/kernel/entry/common.c
+++ b/kernel/entry/common.c
@@ -171,10 +171,8 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
 		if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
 			handle_signal_work(regs, ti_work);
 
-		if (ti_work & _TIF_NOTIFY_RESUME) {
+		if (ti_work & _TIF_NOTIFY_RESUME)
 			tracehook_notify_resume(regs);
-			rseq_handle_notify_resume(NULL, regs);
-		}
 
 		/* Architecture specific TIF work */
 		arch_exit_to_user_mode_work(regs, ti_work);
diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
index 049fd06b4c3d..49972ee99aff 100644
--- a/kernel/entry/kvm.c
+++ b/kernel/entry/kvm.c
@@ -19,10 +19,8 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
 		if (ti_work & _TIF_NEED_RESCHED)
 			schedule();
 
-		if (ti_work & _TIF_NOTIFY_RESUME) {
+		if (ti_work & _TIF_NOTIFY_RESUME)
 			tracehook_notify_resume(NULL);
-			rseq_handle_notify_resume(NULL, NULL);
-		}
 
 		ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
 		if (ret)
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From seanjc at google.com  Fri Aug 20 15:50:00 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 20 Aug 2021 15:50:00 -0700
Subject: [PATCH v2 3/5] tools: Move x86 syscall number fallbacks to .../uapi/
In-Reply-To: <20210820225002.310652-1-seanjc@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
Message-ID: <20210820225002.310652-4-seanjc@google.com>

Move unistd_{32,64}.h from x86/include/asm to x86/include/uapi/asm so
that tools/selftests that install kernel headers, e.g. KVM selftests, can
include non-uapi tools headers, e.g. to get 'struct list_head', without
effectively overriding the installed non-tool uapi headers.

Swapping KVM's search order, e.g. to search the kernel headers before
tool headers, is not a viable option as doing results in linux/type.h and
other core headers getting pulled from the kernel headers, which do not
have the kernel-internal typedefs that are used through tools, including
many files outside of selftests/kvm's control.

Prior to commit cec07f53c398 ("perf tools: Move syscall number fallbacks
from perf-sys.h to tools/arch/x86/include/asm/"), the handcoded numbers
were actual fallbacks, i.e. overriding unistd_{32,64}.h from the kernel
headers was unintentional.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/arch/x86/include/{ => uapi}/asm/unistd_32.h | 0
 tools/arch/x86/include/{ => uapi}/asm/unistd_64.h | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename tools/arch/x86/include/{ => uapi}/asm/unistd_32.h (100%)
 rename tools/arch/x86/include/{ => uapi}/asm/unistd_64.h (100%)

diff --git a/tools/arch/x86/include/asm/unistd_32.h b/tools/arch/x86/include/uapi/asm/unistd_32.h
similarity index 100%
rename from tools/arch/x86/include/asm/unistd_32.h
rename to tools/arch/x86/include/uapi/asm/unistd_32.h
diff --git a/tools/arch/x86/include/asm/unistd_64.h b/tools/arch/x86/include/uapi/asm/unistd_64.h
similarity index 100%
rename from tools/arch/x86/include/asm/unistd_64.h
rename to tools/arch/x86/include/uapi/asm/unistd_64.h
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From seanjc at google.com  Fri Aug 20 15:50:01 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 20 Aug 2021 15:50:01 -0700
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to detect
 task migration bugs
In-Reply-To: <20210820225002.310652-1-seanjc@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
Message-ID: <20210820225002.310652-5-seanjc@google.com>

Add a test to verify an rseq's CPU ID is updated correctly if the task is
migrated while the kernel is handling KVM_RUN.  This is a regression test
for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
without updating rseq, leading to a stale CPU ID and other badness.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/testing/selftests/kvm/.gitignore  |   1 +
 tools/testing/selftests/kvm/Makefile    |   3 +
 tools/testing/selftests/kvm/rseq_test.c | 154 ++++++++++++++++++++++++
 3 files changed, 158 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/rseq_test.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 0709af0144c8..6d031ff6b68e 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -47,6 +47,7 @@
 /kvm_page_table_test
 /memslot_modification_stress_test
 /memslot_perf_test
+/rseq_test
 /set_memory_region_test
 /steal_time
 /kvm_binary_stats_test
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 5832f510a16c..0756e79cb513 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -80,6 +80,7 @@ TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus
 TEST_GEN_PROGS_x86_64 += kvm_page_table_test
 TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test
 TEST_GEN_PROGS_x86_64 += memslot_perf_test
+TEST_GEN_PROGS_x86_64 += rseq_test
 TEST_GEN_PROGS_x86_64 += set_memory_region_test
 TEST_GEN_PROGS_x86_64 += steal_time
 TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
@@ -92,6 +93,7 @@ TEST_GEN_PROGS_aarch64 += dirty_log_test
 TEST_GEN_PROGS_aarch64 += dirty_log_perf_test
 TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
 TEST_GEN_PROGS_aarch64 += kvm_page_table_test
+TEST_GEN_PROGS_aarch64 += rseq_test
 TEST_GEN_PROGS_aarch64 += set_memory_region_test
 TEST_GEN_PROGS_aarch64 += steal_time
 TEST_GEN_PROGS_aarch64 += kvm_binary_stats_test
@@ -103,6 +105,7 @@ TEST_GEN_PROGS_s390x += demand_paging_test
 TEST_GEN_PROGS_s390x += dirty_log_test
 TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
 TEST_GEN_PROGS_s390x += kvm_page_table_test
+TEST_GEN_PROGS_s390x += rseq_test
 TEST_GEN_PROGS_s390x += set_memory_region_test
 TEST_GEN_PROGS_s390x += kvm_binary_stats_test
 
diff --git a/tools/testing/selftests/kvm/rseq_test.c b/tools/testing/selftests/kvm/rseq_test.c
new file mode 100644
index 000000000000..d28d7ba1a64a
--- /dev/null
+++ b/tools/testing/selftests/kvm/rseq_test.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#define _GNU_SOURCE /* for program_invocation_short_name */
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <syscall.h>
+#include <sys/ioctl.h>
+#include <asm/atomic.h>
+#include <asm/barrier.h>
+#include <linux/rseq.h>
+#include <linux/unistd.h>
+
+#include "kvm_util.h"
+#include "processor.h"
+#include "test_util.h"
+
+#define VCPU_ID 0
+
+static __thread volatile struct rseq __rseq = {
+	.cpu_id = RSEQ_CPU_ID_UNINITIALIZED,
+};
+
+#define RSEQ_SIG 0xdeadbeef
+
+static pthread_t migration_thread;
+static cpu_set_t possible_mask;
+static bool done;
+
+static atomic_t seq_cnt;
+
+static void guest_code(void)
+{
+	for (;;)
+		GUEST_SYNC(0);
+}
+
+static void sys_rseq(int flags)
+{
+	int r;
+
+	r = syscall(__NR_rseq, &__rseq, sizeof(__rseq), flags, RSEQ_SIG);
+	TEST_ASSERT(!r, "rseq failed, errno = %d (%s)", errno, strerror(errno));
+}
+
+static void *migration_worker(void *ign)
+{
+	cpu_set_t allowed_mask;
+	int r, i, nr_cpus, cpu;
+
+	CPU_ZERO(&allowed_mask);
+
+	nr_cpus = CPU_COUNT(&possible_mask);
+
+	for (i = 0; i < 20000; i++) {
+		cpu = i % nr_cpus;
+		if (!CPU_ISSET(cpu, &possible_mask))
+			continue;
+
+		CPU_SET(cpu, &allowed_mask);
+
+		/*
+		 * Bump the sequence count twice to allow the reader to detect
+		 * that a migration may have occurred in between rseq and sched
+		 * CPU ID reads.  An odd sequence count indicates a migration
+		 * is in-progress, while a completely different count indicates
+		 * a migration occurred since the count was last read.
+		 */
+		atomic_inc(&seq_cnt);
+		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
+		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)",
+			    errno, strerror(errno));
+		atomic_inc(&seq_cnt);
+
+		CPU_CLR(cpu, &allowed_mask);
+
+		/*
+		 * Let the read-side get back into KVM_RUN to improve the odds
+		 * of task migration coinciding with KVM's run loop.
+		 */
+		usleep(1);
+	}
+	done = true;
+	return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+	struct kvm_vm *vm;
+	u32 cpu, rseq_cpu;
+	int r, snapshot;
+
+	/* Tell stdout not to buffer its content */
+	setbuf(stdout, NULL);
+
+	r = sched_getaffinity(0, sizeof(possible_mask), &possible_mask);
+	TEST_ASSERT(!r, "sched_getaffinity failed, errno = %d (%s)", errno,
+		    strerror(errno));
+
+	if (CPU_COUNT(&possible_mask) < 2) {
+		print_skip("Only one CPU, task migration not possible\n");
+		exit(KSFT_SKIP);
+	}
+
+	sys_rseq(0);
+
+	/*
+	 * Create and run a dummy VM that immediately exits to userspace via
+	 * GUEST_SYNC, while concurrently migrating the process by setting its
+	 * CPU affinity.
+	 */
+	vm = vm_create_default(VCPU_ID, 0, guest_code);
+
+	pthread_create(&migration_thread, NULL, migration_worker, 0);
+
+	while (!done) {
+		vcpu_run(vm, VCPU_ID);
+		TEST_ASSERT(get_ucall(vm, VCPU_ID, NULL) == UCALL_SYNC,
+			    "Guest failed?");
+
+		/*
+		 * Verify rseq's CPU matches sched's CPU.  Ensure migration
+		 * doesn't occur between sched_getcpu() and reading the rseq
+		 * cpu_id by rereading both if the sequence count changes, or
+		 * if the count is odd (migration in-progress).
+		 */
+		do {
+			/*
+			 * Drop bit 0 to force a mismatch if the count is odd,
+			 * i.e. if a migration is in-progress.
+			 */
+			snapshot = atomic_read(&seq_cnt) & ~1;
+			smp_rmb();
+			cpu = sched_getcpu();
+			rseq_cpu = READ_ONCE(__rseq.cpu_id);
+			smp_rmb();
+		} while (snapshot != atomic_read(&seq_cnt));
+
+		TEST_ASSERT(rseq_cpu == cpu,
+			    "rseq CPU = %d, sched CPU = %d\n", rseq_cpu, cpu);
+	}
+
+	pthread_join(migration_thread, NULL);
+
+	kvm_vm_free(vm);
+
+	sys_rseq(RSEQ_FLAG_UNREGISTER);
+
+	return 0;
+}
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From seanjc at google.com  Fri Aug 20 15:50:02 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 20 Aug 2021 15:50:02 -0700
Subject: [PATCH v2 5/5] KVM: selftests: Remove __NR_userfaultfd syscall
 fallback
In-Reply-To: <20210820225002.310652-1-seanjc@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
Message-ID: <20210820225002.310652-6-seanjc@google.com>

Revert the __NR_userfaultfd syscall fallback added for KVM selftests now
that x86's unistd_{32,63}.h overrides are under uapi/ and thus not in
KVM sefltests' search path, i.e. now that KVM gets x86 syscall numbers
from the installed kernel headers.

No functional change intended.

Cc: Ben Gardon <bgardon at google.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 tools/arch/x86/include/uapi/asm/unistd_64.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/arch/x86/include/uapi/asm/unistd_64.h b/tools/arch/x86/include/uapi/asm/unistd_64.h
index 4205ed4158bf..cb52a3a8b8fc 100644
--- a/tools/arch/x86/include/uapi/asm/unistd_64.h
+++ b/tools/arch/x86/include/uapi/asm/unistd_64.h
@@ -1,7 +1,4 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __NR_userfaultfd
-#define __NR_userfaultfd 282
-#endif
 #ifndef __NR_perf_event_open
 # define __NR_perf_event_open 298
 #endif
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From chunkuang.hu at kernel.org  Fri Aug 20 16:37:36 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sat, 21 Aug 2021 07:37:36 +0800
Subject: [PATCH v3 15/15] drm/mediatek: add mediatek-drm of vdosys1
 support for MT8195
In-Reply-To: <20210818091847.8060-16-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-16-nancy.lin@mediatek.com>
Message-ID: <CAAOTY_8UUyT1u1bNqK-rNjKaFUo5=MVVrfMF6CUXmcXDb-xV1w@mail.gmail.com>

Hi, Nancy:

Nancy.Lin <nancy.lin at mediatek.com> ? 2021?8?18? ?? ??5:18???
>
> Add driver data of mt8195 vdosys1 to mediatek-drm and modify drm for
> multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring
> up two drm drivers, only one drm driver register as the drm device.
> Each drm driver binds its own component. The first bind drm driver
> will allocate the drm device, and the last bind drm driver registers
> the drm device to drm core. Each crtc path is created with the
> corresponding drm driver data.

Separate this patch to two patch. One is support two mmsys, and
another one is support mt8195 vdosys1.

Regards,
Chun-Kuang.

>
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c   |   4 +
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |  25 +-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |   3 +-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  15 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 372 ++++++++++++++++----
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   8 +-
>  7 files changed, 354 insertions(+), 74 deletions(-)
>
>


From yuzenghui at huawei.com  Fri Aug 20 20:05:19 2021
From: yuzenghui at huawei.com (Zenghui Yu)
Date: Sat, 21 Aug 2021 11:05:19 +0800
Subject: [PATCH] arm64: defconfig: drop obsolete ARCH_* configs
Message-ID: <20210821030519.127-1-yuzenghui@huawei.com>

Per commit 4a9a1a5602d8 ("arm64: socfpga: merge Agilex and N5X into
ARCH_INTEL_SOCFPGA") and commit 89d4f98ae90d ("ARM: remove zte zx
platform"), they can be dropped from defconfig now.

Cc: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Cc: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Zenghui Yu <yuzenghui at huawei.com>
---
 arch/arm64/configs/defconfig | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f423d08b9a71..50cebeececa0 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -28,8 +28,6 @@ CONFIG_KALLSYMS_ALL=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_PROFILING=y
 CONFIG_ARCH_ACTIONS=y
-CONFIG_ARCH_AGILEX=y
-CONFIG_ARCH_N5X=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
 CONFIG_ARCH_APPLE=y
@@ -63,7 +61,6 @@ CONFIG_ARCH_UNIPHIER=y
 CONFIG_ARCH_VEXPRESS=y
 CONFIG_ARCH_VISCONTI=y
 CONFIG_ARCH_XGENE=y
-CONFIG_ARCH_ZX=y
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_ARM64_VA_BITS_48=y
 CONFIG_SCHED_MC=y
-- 
2.19.1



From cgel.zte at gmail.com  Fri Aug 20 20:50:33 2021
From: cgel.zte at gmail.com (CGEL)
Date: Fri, 20 Aug 2021 20:50:33 -0700
Subject: [PATCH linux-next] media:meson-ir-tx: fix platform_no_drv_owner.cocci
 warnings
Message-ID: <20210821035033.28210-1-jing.yangyang@zte.com.cn>

From: jing yangyang <jing.yangyang at zte.com.cn>

./drivers/media/rc/meson-ir-tx.c:398:3-8: No need to set .owner here. The core will do it.

Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>
---
 drivers/media/rc/meson-ir-tx.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/media/rc/meson-ir-tx.c b/drivers/media/rc/meson-ir-tx.c
index 3055f8e..c22cd26 100644
--- a/drivers/media/rc/meson-ir-tx.c
+++ b/drivers/media/rc/meson-ir-tx.c
@@ -395,7 +395,6 @@ static int meson_irtx_remove(struct platform_device *pdev)
 	.remove = meson_irtx_remove,
 	.driver = {
 		.name = DRIVER_NAME,
-		.owner  = THIS_MODULE,
 		.of_match_table = meson_irtx_dt_match,
 	},
 };
-- 
1.8.3.1




From rocco.yue at mediatek.com  Fri Aug 20 23:10:30 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Sat, 21 Aug 2021 14:10:30 +0800
Subject: [PATCH net-next v4] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <ad32c931-3056-cdef-4b9b-aab654c61cb9@gmail.com>
References: <ad32c931-3056-cdef-4b9b-aab654c61cb9@gmail.com>
Message-ID: <20210821061030.26632-1-rocco.yue@mediatek.com>

On Tue, 2021-08-17 at 09:05 -0600, David Ahern wrote:
On 8/17/21 1:26 AM, Rocco Yue wrote:
>> @@ -1496,6 +1490,11 @@ static void ndisc_router_discovery(struct sk_buff *skb)
>>  		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
>>  		mtu = ntohl(n);
>>  
>> +		if (in6_dev->ra_mtu != mtu) {
>> +			in6_dev->ra_mtu = mtu;
>> +			send_ifinfo_notify = true;
>> +		}
>> +
>>  		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
>>  			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
>>  		} else if (in6_dev->cnf.mtu6 != mtu) {
> 
> 
> If an RA no longer carries an MTU or if accept_ra_mtu is reset, then
> in6_dev->ra_mtu should be reset to 0 right?
> 
> rest of the change looks good to me.

Hi David,

Thanks for your review.

In this patch, if an RA no longer carries an MTU or if accept_ra_mtu is reset,
in6_dev->ra_mtu will not be reset to 0, its value will remain the previous
accept_ra_mtu=1 and the value of the mtu carried in the RA msg. This behavior
is same with mtu6. This should be reasonable, it would show that the device
had indeed received the ra_mtu before set accept_ra_mtu to 0 or an RA no longer
carries an mtu value. I am willing to listen to your suggestions and make
changes if needed, maybe it needs to add a new separate proc handler for
accept_ra_mtu.

In addition, at your prompt, I find that this patch maybe have a defect for
some types of virtual devices, that is, when the state of the virtual device
updates the value of ra_mtu during the UP period, when its state is set to
DOWN, ra_mtu is not reset to 0, so that its ra_mtu value remains the previous
value after the interface is re-UP. I think I need to fix it.

Thanks
Rocco

From lkp at intel.com  Sat Aug 21 00:15:28 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 21 Aug 2021 15:15:28 +0800
Subject: [PATCH] arm/arm64: dts: Fix remaining dtc 'unit_address_format'
 warnings
In-Reply-To: <20210820165253.3258557-1-robh@kernel.org>
References: <20210820165253.3258557-1-robh@kernel.org>
Message-ID: <202108211510.RhWpg5f0-lkp@intel.com>

Hi Rob,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on keystone/next stm32/stm32-next v5.14-rc6]
[cannot apply to next-20210820]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Rob-Herring/arm-arm64-dts-Fix-remaining-dtc-unit_address_format-warnings/20210821-005448
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm-buildonly-randconfig-r004-20210821 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d9c5613e856cf2addfbf892fc4c1ce9ef9feceaa)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/84081696046fc0a6d93a8233321629bd3a4a46fd
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Rob-Herring/arm-arm64-dts-Fix-remaining-dtc-unit_address_format-warnings/20210821-005448
        git checkout 84081696046fc0a6d93a8233321629bd3a4a46fd
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> ERROR: Input tree has errors, aborting (use -f to force output)

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for QCOM_SCM
   Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
   Selected by
   - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 33490 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210821/738c295e/attachment-0001.gz>

From christophe.jaillet at wanadoo.fr  Sat Aug 21 00:17:22 2021
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 21 Aug 2021 09:17:22 +0200
Subject: [PATCH] i2c: busses: i2c-nomadik: Remove a useless call in the remove
 function
Message-ID: <4f4c2c5c20b61c4bb28cb3e9ab4640534dd2adec.1629530169.git.christophe.jaillet@wanadoo.fr>

Since commit a410963ba4c0 ("Merge branch 'i2c-embedded/for-next' of
git://git.pengutronix.de/git/wsa/linux"), there is no more
'request_mem_region()' call in this driver.

So remove the 'release_mem_region()' call from the remove function which is
likely a left over.

There is no details in the above commit log, but at its end we can read:
   Conflicts:
	   drivers/i2c/busses/i2c-nomadik.c

This may explain why this call has been left here.

Fixes: a410963ba4c0 ("Merge branch 'i2c-embedded/for-next' of git://git.pengutronix.de/git/wsa/linux
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
This patch is completely speculative and without details about commit
a410963ba4c0 it's hard to be sure of the intent.

All I can say is that it looks logical to me and that it compiles!
---
 drivers/i2c/busses/i2c-nomadik.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index a2d12a5b1c34..e215a7357873 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -1057,7 +1057,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 
 static void nmk_i2c_remove(struct amba_device *adev)
 {
-	struct resource *res = &adev->res;
 	struct nmk_i2c_dev *dev = amba_get_drvdata(adev);
 
 	i2c_del_adapter(&dev->adap);
@@ -1067,7 +1066,6 @@ static void nmk_i2c_remove(struct amba_device *adev)
 	/* disable the controller */
 	i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
 	clk_disable_unprepare(dev->clk);
-	release_mem_region(res->start, resource_size(res));
 }
 
 static struct i2c_vendor_data vendor_stn8815 = {
-- 
2.30.2



From kewei.xu at mediatek.com  Sat Aug 21 00:40:45 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 21 Aug 2021 15:40:45 +0800
Subject: [PATCH v4 3/8] i2c: mediatek: Reset the handshake signal
 between i2c and dma
In-Reply-To: <CAGXv+5EGpUV0eaQ6duZ8y8u2dvc1y3uc2YwWP=07D+ZZpzMCvQ@mail.gmail.com>
References: <1626517079-9057-1-git-send-email-kewei.xu@mediatek.com>
 <1626517079-9057-4-git-send-email-kewei.xu@mediatek.com>
 <CAGXv+5EGpUV0eaQ6duZ8y8u2dvc1y3uc2YwWP=07D+ZZpzMCvQ@mail.gmail.com>
Message-ID: <fce8934ec25d18307df11e2f308a255da5a25ce3.camel@mediatek.com>

On Wed, 2021-08-11 at 16:41 +0800, Chen-Yu Tsai wrote:
> Hi,
> 
> On Sat, Jul 17, 2021 at 6:29 PM Kewei Xu <kewei.xu at mediatek.com>
> wrote:
> > 
> > Due to changes in the hardware design of the handshaking signal
> > between i2c and dma, it is necessary to reset the handshaking
> > signal before each transfer to ensure that the multi-msgs can
> > be transferred correctly.
> 
> This also affects MT8192. Has this been tested on that SoC as well?

Yes, It has been tested on MT8192.

> 
> > Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
> > ---
> >  drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/drivers/i2c/busses/i2c-mt65xx.c
> > b/drivers/i2c/busses/i2c-mt65xx.c
> > index 222ff765e55d..c0108387f34b 100644
> > --- a/drivers/i2c/busses/i2c-mt65xx.c
> > +++ b/drivers/i2c/busses/i2c-mt65xx.c
> > @@ -47,6 +47,9 @@
> >  #define I2C_RD_TRANAC_VALUE            0x0001
> >  #define I2C_SCL_MIS_COMP_VALUE         0x0000
> >  #define I2C_CHN_CLR_FLAG               0x0000
> > +#define I2C_CLR_DEBUGCTR               0x0000
> > +#define I2C_RELIABILITY                        0x0010
> > +#define I2C_DMAACK_ENABLE              0x0008
> > 
> >  #define I2C_DMA_CON_TX                 0x0000
> >  #define I2C_DMA_CON_RX                 0x0001
> > @@ -850,6 +853,17 @@ static int mtk_i2c_do_transfer(struct mtk_i2c
> > *i2c, struct i2c_msg *msgs,
> > 
> >         reinit_completion(&i2c->msg_complete);
> > 
> > +       if (i2c->dev_comp->apdma_sync) {
> > +               mtk_i2c_writew(i2c, I2C_CLR_DEBUGCTR,
> > OFFSET_DEBUGCTRL);
> > +               writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_WARM_RST,
> > +                      i2c->pdmabase + OFFSET_RST);
> > +               writel(I2C_DMA_CLR_FLAG, i2c->pdmabase +
> > OFFSET_RST);
> 
> I2C_DMA_WARM_RST is self-clearing. Is I2C_DMA_HANDSHAKE_RST not
> self-clearing? If both are self-clearing, don't you need to wait and
> check for them to cleared? If they aren't self-clearing, do you need
> to delay some time for them to complete?
> 

Thank you for your suggestion. We will appropriately add the delay in
the next version of patch according to the hardware behavior
characteristics. 

Regards
Kewei

> > +               mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST,
> > OFFSET_SOFTRESET);
> > +               mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG,
> > OFFSET_SOFTRESET);
> 
> Same here. No time delay needed?
> 
> > +               mtk_i2c_writew(i2c, I2C_RELIABILITY |
> > I2C_DMAACK_ENABLE,
> > +                              OFFSET_DEBUGCTRL);
> 
> A comment explaining what the section above does would be nice.
> AFAICU
> this is force resetting the DMA handling.
> 
> 
> Regards
> ChenYu
> 
> > +       }
> > +
> >         control_reg = mtk_i2c_readw(i2c, OFFSET_CONTROL) &
> >                         ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
> >         if ((i2c->speed_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) ||
> > (left_num >= 1))
> > --
> > 2.18.0
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek

From sven at svenpeter.dev  Sat Aug 21 01:55:52 2021
From: sven at svenpeter.dev (Sven Peter)
Date: Sat, 21 Aug 2021 10:55:52 +0200
Subject: [PATCH v4 00/24] iommu: Refactor DMA domain strictness
In-Reply-To: <914d7243-7f9d-425e-1ff7-6be218e04913@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
 <YRzvGxTW8m+NUcSi@8bytes.org> <914d7243-7f9d-425e-1ff7-6be218e04913@arm.com>
Message-ID: <5704924b-e3e3-404a-a4f4-e38ece82673b@www.fastmail.com>



On Wed, Aug 18, 2021, at 17:13, Robin Murphy wrote:
> Sven - I've prepared the follow-up patches already[1], so consider 
> yourself off the hook (I see no point in trying to fix the nominal DART 
> cookie bugs between now and then) :)
> 

Great, thanks for taking care of that! :)
Just tested your branch and everything works. Feel free to add 
Acked-by: Sven Peter <sven at svenpeter.dev>
Tested-by: Sven Peter <sven at svenpeter.dev>


Best,


Sven


From vilhelm.gray at gmail.com  Sat Aug 21 03:52:27 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Sat, 21 Aug 2021 19:52:27 +0900
Subject: [PATCH v15 07/13] docs: counter: Document character device
 interface
In-Reply-To: <20210815175102.4a10a28f@jic23-huawei>
References: <cover.1628511445.git.vilhelm.gray@gmail.com>
 <a6f7be32b8ff7cc1e8e416599820a30fa9aab9f5.1628511445.git.vilhelm.gray@gmail.com>
 <20210815175102.4a10a28f@jic23-huawei>
Message-ID: <YSDa667n6pi4O8iT@shinobu>

On Sun, Aug 15, 2021 at 05:51:02PM +0100, Jonathan Cameron wrote:
> On Mon,  9 Aug 2021 21:37:32 +0900
> William Breathitt Gray <vilhelm.gray at gmail.com> wrote:
> 
> > This patch adds high-level documentation about the Counter subsystem
> > character device interface.
> > 
> > Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
> 
> Hi William,
> 
> Trivial probable typo inline.
> 
> I'm struggling somewhat with these interfaces because I simply don't know
> enough about how people use counters to know whether they provide everything
> people will want. They feel similar to the event handling type functions you
> can set up in motor drives, so they may well make sense, but ideally
> we need review from someone (other than yourself!) who actually uses this
> stuff on a regular basis.
> 
> If we don't get any additional review I guess we go ahead anyway
> next cycle.
> 
> Jonathan
> 
> > ---
> 
> > +
> > +Counter events can be configured by users to report various Counter
> > +data of interest. This can be conceptualized as a list of Counter
> > +component read calls to perform. For example:
> > +
> > +        +-------------------------------------------------+
> > +        | COUNTER_EVENT_OVERFLOW | COUNTER_EVENT_INDEX    |
> > +        +========================+========================+
> > +        | Channel 0              | Channel 0              |
> > +        +------------------------+------------------------+
> > +        | * Count 0              | * Signal 0             |
> > +        | * Count 1              | * Signal 0 Extension 0 |
> > +        | * Signal 3             | * Extension 4          |
> > +        | * Count 4 Extension 2  +------------------------+
> > +        | * Signal 5 Extension 0 | Channel 1              |
> > +        |                        +------------------------+
> > +        |                        | * Signal 4             |
> > +        |                        | * Signal 4 Extension 0 |
> > +        |                        | * Count 7              |
> > +        +------------------------+------------------------+
> > +
> > +When ``counter_push_event(counter, COUNTER_EVENT_INDEX, 1)`` is called
> > +for example, it will go down the list for the ``COUNTER_EVENT_INDEX``
> > +event channel 1 and execute the read callbacks for Signal 4, Signal 4
> > +Extension 0, and Count 4 -- the data returned for each is pushed to a
> 
> Count 7?

Looks like my finger slipped on my numpad and hit 4 when I intended 7.
I'll fix this for v16, thanks.

William Breathitt Gray
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210821/ca26bccf/attachment.sig>

From maz at kernel.org  Sat Aug 21 03:56:46 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 21 Aug 2021 11:56:46 +0100
Subject: [PATCH] KVM: arm64: Ratelimit error log during guest debug
 exception
In-Reply-To: <CAJHc60wn7PP1zQ5EKOGQDFbZsf=d9codWTuWbtMT5AHegfbVHw@mail.gmail.com>
References: <20210819223406.1132426-1-rananta@google.com>
 <87sfz4qx9r.wl-maz@kernel.org>
 <CAJHc60wn7PP1zQ5EKOGQDFbZsf=d9codWTuWbtMT5AHegfbVHw@mail.gmail.com>
Message-ID: <875yvzqd5d.wl-maz@kernel.org>

On Sat, 21 Aug 2021 00:01:24 +0100,
Raghavendra Rao Ananta <rananta at google.com> wrote:
> 
> [1  <text/plain; UTF-8 (7bit)>]
> On Fri, Aug 20, 2021 at 2:29 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Thu, 19 Aug 2021 23:34:06 +0100,
> > Raghavendra Rao Ananta <rananta at google.com> wrote:
> > >
> > > Potentially, the guests could trigger a debug exception that's
> > > outside the exception class range.
> >
> > How? All the exception classes that lead to this functions are already
> > handled in the switch/case statement.
> >
> I guess I didn't think this through. Landing into kvm_handle_guest_debug()
> itself is not possible :)

Exactly.

> > My take on this is that this code isn't reachable, and that it could
> > be better rewritten as:
> >
> > diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> > index 6f48336b1d86..ae7ec086827b 100644
> > --- a/arch/arm64/kvm/handle_exit.c
> > +++ b/arch/arm64/kvm/handle_exit.c
> > @@ -119,28 +119,14 @@ static int kvm_handle_guest_debug(struct kvm_vcpu
> *vcpu)
> >  {
> >         struct kvm_run *run = vcpu->run;
> >         u32 esr = kvm_vcpu_get_esr(vcpu);
> > -       int ret = 0;
> >
> >         run->exit_reason = KVM_EXIT_DEBUG;
> >         run->debug.arch.hsr = esr;
> >
> > -       switch (ESR_ELx_EC(esr)) {
> > -       case ESR_ELx_EC_WATCHPT_LOW:
> > +       if (ESR_ELx_EC(esr) ==  ESR_ELx_EC_WATCHPT_LOW)
> >                 run->debug.arch.far = vcpu->arch.fault.far_el2;
> > -               fallthrough;
> > -       case ESR_ELx_EC_SOFTSTP_LOW:
> > -       case ESR_ELx_EC_BREAKPT_LOW:
> > -       case ESR_ELx_EC_BKPT32:
> > -       case ESR_ELx_EC_BRK64:
> > -               break;
> > -       default:
> > -               kvm_err("%s: un-handled case esr: %#08x\n",
> > -                       __func__, (unsigned int) esr);
> > -               ret = -1;
> > -               break;
> > -       }
> >
> > -       return ret;
> > +       return 0;
> >  }
> >
> This looks better, but do you think we would be compromising on readability?

I don't think so. The exit handler table is, on its own, pretty
explicit about what we route to this handler, and the comment above
the function clearly states that we exit to userspace for all the
debug ECs.

	M.

-- 
Without deviation from the norm, progress is not possible.


From christophe.jaillet at wanadoo.fr  Sat Aug 21 04:12:53 2021
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 21 Aug 2021 13:12:53 +0200
Subject: [PATCH] media: imx-jpeg: Fix the error handling path of
 'mxc_jpeg_probe()'
Message-ID: <925bbb0c4c7d7b197ade5bb282d7be8a44921845.1629544232.git.christophe.jaillet@wanadoo.fr>

A successful 'mxc_jpeg_attach_pm_domains()' call should be balanced by a
corresponding 'mxc_jpeg_detach_pm_domains()' call in the error handling
path of the probe, as already done in the remove function.

Update the error handling path accordingly.

Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
 drivers/media/platform/imx-jpeg/mxc-jpeg.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
index 755138063ee6..a0c520678c6d 100644
--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
@@ -2088,6 +2088,8 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
 	v4l2_device_unregister(&jpeg->v4l2_dev);
 
 err_register:
+	mxc_jpeg_detach_pm_domains(jpeg);
+
 err_irq:
 	return ret;
 }
-- 
2.30.2



From clin at suse.com  Sat Aug 21 05:39:04 2021
From: clin at suse.com (Chester Lin)
Date: Sat, 21 Aug 2021 20:39:04 +0800
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <87lf4wqgn7.wl-maz@kernel.org>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-5-clin@suse.com>
 <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>
 <87o89sqmz6.wl-maz@kernel.org> <YR/HJQDGJ1C+ku6O@linux-8mug>
 <87lf4wqgn7.wl-maz@kernel.org>
Message-ID: <YSDz6EiNifqV2NAT@linux-8mug>

Hi Marc,

On Fri, Aug 20, 2021 at 04:29:00PM +0100, Marc Zyngier wrote:
> On Fri, 20 Aug 2021 16:15:49 +0100,
> Chester Lin <clin at suse.com> wrote:
> > 
> > On Fri, Aug 20, 2021 at 02:12:13PM +0100, Marc Zyngier wrote:
> > > On Thu, 12 Aug 2021 18:26:28 +0100,
> > > Andreas F?rber <afaerber at suse.de> wrote:
> > > > 
> > > > Hi Chester et al.,
> > > > 
> > > > On 05.08.21 08:54, Chester Lin wrote:
> > > > > Add an initial dtsi file for generic SoC features of NXP S32G2.
> > > > > 
> > > > > Signed-off-by: Chester Lin <clin at suse.com>
> > > > > ---
> > > > >  arch/arm64/boot/dts/freescale/s32g2.dtsi | 98 ++++++++++++++++++++++++
> > > > >  1 file changed, 98 insertions(+)
> > > > >  create mode 100644 arch/arm64/boot/dts/freescale/s32g2.dtsi
> > > > > 
> > > > > diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > > > > new file mode 100644
> > > > > index 000000000000..3321819c1a2d
> > > > > --- /dev/null
> > > > > +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
> > > 
> > > [...]
> > > 
> > > > > +		gic: interrupt-controller at 50800000 {
> > > > > +			compatible = "arm,gic-v3";
> > > > > +			#interrupt-cells = <3>;
> > > > > +			interrupt-controller;
> > > > > +			reg = <0 0x50800000 0 0x10000>,
> > > > > +			      <0 0x50880000 0 0x200000>,
> > > 
> > > That's enough redistributor space for 16 CPUs. However, you only
> > > describe 4. Either the number of CPUs is wrong, the size is wrong, or
> > > the GIC has been configured for more cores than the SoC has.
> > 
> > Confirmed the SoC can only find 4 redistributors:
> > 
> > localhost:~ # dmesg | grep CPU
> > [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
> > [    0.000000] Detected VIPT I-cache on CPU0
> > [    0.000000] CPU features: detected: GIC system register CPU interface
> > [    0.000000] CPU features: detected: ARM erratum 845719
> > [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
> > [    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=480 to nr_cpu_ids=4.
> > [    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x0000000050880000
> > [    0.063865] smp: Bringing up secondary CPUs ...
> > [    0.068852] Detected VIPT I-cache on CPU1
> > [    0.068894] GICv3: CPU1: found redistributor 1 region 0:0x00000000508a0000
> > [    0.068963] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
> > [    0.069809] Detected VIPT I-cache on CPU2
> > [    0.069851] GICv3: CPU2: found redistributor 100 region 0:0x00000000508c0000
> > [    0.069903] CPU2: Booted secondary processor 0x0000000100 [0x410fd034]
> > [    0.070698] Detected VIPT I-cache on CPU3
> > [    0.070722] GICv3: CPU3: found redistributor 101 region 0:0x00000000508e0000
> > [    0.070749] CPU3: Booted secondary processor 0x0000000101 [0x410fd034]
> > [    0.070847] smp: Brought up 1 node, 4 CPUs
> > <..snip..>
> 
> That's not the correct way to find out. Each CPU tries to find its
> matching RD in the region. This doesn't mean there aren't more RDs
> present in the GIC.
> 
> You need to iterate over all the RDs in the region until you find one
> that has GICR_TYPER.Last == 1. This will give you the actual count.
> Alternatively, you can check whether the RD at 508e0000 has that bit
> set. If it doesn't, then you know there are more RDs than CPUs.
> 
> 	M.
> 

Thanks for your guidance. Not sure if any debug log can be enabled for this
check so I temporarily add an ugly message as below:


diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e0f4debe64e1..5998306fff39 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -866,10 +866,11 @@ static int __gic_populate_rdist(struct redist_region *region, void __iomem *ptr)
 		gic_data_rdist_rd_base() = ptr;
 		gic_data_rdist()->phys_base = region->phys_base + offset;
 
-		pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
+		pr_info("CPU%d: found redistributor %lx region %d:%pa last: %d\n",
 			smp_processor_id(), mpidr,
 			(int)(region - gic_data.redist_regions),
-			&gic_data_rdist()->phys_base);
+			&gic_data_rdist()->phys_base,
+			(typer & GICR_TYPER_LAST) ? 1 : 0);
 		return 0;
 	}


The following log shows that the "Last" bit (GICR_TYPER[4]) of RD at
508e0000 has been set.

localhost:~ # dmesg | grep GIC
[    0.000000] CPU features: detected: GIC system register CPU interface
[    0.000000] GICv3: 544 SPIs implemented
[    0.000000] GICv3: 0 Extended SPIs implemented
[    0.000000] GICv3: Distributor has no Range Selector support
[    0.000000] GICv3: 16 PPIs implemented
[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x0000000050880000 last: 0
[    0.078745] GICv3: CPU1: found redistributor 1 region 0:0x00000000508a0000 last: 0
[    0.089598] GICv3: CPU2: found redistributor 100 region 0:0x00000000508c0000 last: 0
[    0.100395] GICv3: CPU3: found redistributor 101 region 0:0x00000000508e0000 last: 1



From jon.lin at rock-chips.com  Sat Aug 21 05:49:25 2021
From: jon.lin at rock-chips.com (Jon Lin)
Date: Sat, 21 Aug 2021 20:49:25 +0800
Subject: [PATCH] spi: rockchip-sfc: Remove redundant IO operations
Message-ID: <20210821124925.6066-1-jon.lin@rock-chips.com>

Coherent dma buffer is uncached and memcpy is enough.

Signed-off-by: Jon Lin <jon.lin at rock-chips.com>
---

 drivers/spi/spi-rockchip-sfc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c
index 7c4d47fe80c2..81154a8836fc 100644
--- a/drivers/spi/spi-rockchip-sfc.c
+++ b/drivers/spi/spi-rockchip-sfc.c
@@ -453,7 +453,7 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
 	dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
 
 	if (op->data.dir == SPI_MEM_DATA_OUT)
-		memcpy_toio(sfc->buffer, op->data.buf.out, len);
+		memcpy(sfc->buffer, op->data.buf.out, len);
 
 	ret = rockchip_sfc_fifo_transfer_dma(sfc, sfc->dma_buffer, len);
 	if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) {
@@ -462,7 +462,7 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
 	}
 	rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA);
 	if (op->data.dir == SPI_MEM_DATA_IN)
-		memcpy_fromio(op->data.buf.in, sfc->buffer, len);
+		memcpy(op->data.buf.in, sfc->buffer, len);
 
 	return ret;
 }
-- 
2.17.1





From maz at kernel.org  Sat Aug 21 07:20:30 2021
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 21 Aug 2021 15:20:30 +0100
Subject: [PATCH 4/8] arm64: dts: add NXP S32G2 support
In-Reply-To: <YSDz6EiNifqV2NAT@linux-8mug>
References: <20210805065429.27485-1-clin@suse.com>
 <20210805065429.27485-5-clin@suse.com>
 <d09ed0fd-83e7-a6aa-0bd6-f679ffb64eaf@suse.de>
 <87o89sqmz6.wl-maz@kernel.org> <YR/HJQDGJ1C+ku6O@linux-8mug>
 <87lf4wqgn7.wl-maz@kernel.org> <YSDz6EiNifqV2NAT@linux-8mug>
Message-ID: <874kbiria9.wl-maz@kernel.org>

On Sat, 21 Aug 2021 13:39:04 +0100,
Chester Lin <clin at suse.com> wrote:
> 
> The following log shows that the "Last" bit (GICR_TYPER[4]) of RD at
> 508e0000 has been set.
> 
> localhost:~ # dmesg | grep GIC
> [    0.000000] CPU features: detected: GIC system register CPU interface
> [    0.000000] GICv3: 544 SPIs implemented
> [    0.000000] GICv3: 0 Extended SPIs implemented
> [    0.000000] GICv3: Distributor has no Range Selector support
> [    0.000000] GICv3: 16 PPIs implemented
> [    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x0000000050880000 last: 0
> [    0.078745] GICv3: CPU1: found redistributor 1 region 0:0x00000000508a0000 last: 0
> [    0.089598] GICv3: CPU2: found redistributor 100 region 0:0x00000000508c0000 last: 0
> [    0.100395] GICv3: CPU3: found redistributor 101 region 0:0x00000000508e0000 last: 1

Looks convincing enough. Trimming the RD range to 512kB is then the
right thing to do.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From heiko at sntech.de  Sat Aug 21 08:28:40 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 21 Aug 2021 17:28:40 +0200
Subject: [PATCH] arm64: dts: rockchip: add RK3399 Gru gpio-line-names
In-Reply-To: <CA+ASDXO=Bjr+f4mtXwt7vtiTz6tSw7SPuY1RvNWMp6-43Baqfg@mail.gmail.com>
References: <20210820133829.1.Ica46f428de8c3beb600760dbcd63cf879ec24baf@changeid>
 <CAD=FV=UwAcJEDE3BQYuCDq4kRKPFAsuzPOseGY66wfXcW8Wn7A@mail.gmail.com>
 <CA+ASDXO=Bjr+f4mtXwt7vtiTz6tSw7SPuY1RvNWMp6-43Baqfg@mail.gmail.com>
Message-ID: <10392569.T7Z3S40VBb@phil>

Am Freitag, 20. August 2021, 23:16:23 CEST schrieb Brian Norris:
> On Fri, Aug 20, 2021 at 2:05 PM Doug Anderson <dianders at chromium.org> wrote:
> > I guess one minor nit (now that I look back on the veyron patch where
> > I mentioned it explicitly in the commit message) is that on the veyron
> > ones we sorted this down at the bottom with the other pinctrl stuff
> > instead of sorting it alphabetically with everything else. I'll let
> > Heiko say which he likes better.
> 
> Huh, didn't notice that semi-convention. I can sort it however Heiko prefers.

Hmm, I wouldn't call it a semi-convention ... it was more an idea of
getting all the longer pages of "stuff" out of the way.

I don't think I have a real hard preference for the gpioX nodes
and I guess in the long run it might be helpful to try to limit the
number of "semi-conventions" .

I still like "pinctrl at the bottom", but I guess it might be easier to
with alphabetical for nodes with the rest :-) .


Heiko



> > I also notice for veyron that we had a second "ABI" exception for the
> > recovery mode pin, but I believe that goes through a different
> > mechanism now so we're good there.
> 
> I believe the recovery mode pin is dropped from recent designs (don't
> quote me in general on that), and there's a different mechanism used
> just to get the at-boot-time "recovery mode" state directly from the
> firmware.
> 
> > Even though I didn't do a line-by-line review, I'll still give:
> >
> > Reviewed-by: Douglas Anderson <dianders at chromium.org>
> >
> > ...though it's possible an "Acked-by" would be more in the spirit of
> > that? Not sure...
> 
> Thanks!
> 
> Brian
> 






From heiko at sntech.de  Sat Aug 21 09:20:13 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 21 Aug 2021 18:20:13 +0200
Subject: [PATCH] arm64: dts: rockchip: add RK3399 Gru gpio-line-names
In-Reply-To: <20210820133829.1.Ica46f428de8c3beb600760dbcd63cf879ec24baf@changeid>
References: <20210820133829.1.Ica46f428de8c3beb600760dbcd63cf879ec24baf@changeid>
Message-ID: <162956281042.2943041.17828992937259243282.b4-ty@sntech.de>

On Fri, 20 Aug 2021 13:38:35 -0700, Brian Norris wrote:
> It's convenient to get nice names for GPIOs. In particular, Chrome OS
> tooling looks for "AP_FLASH_WP" and "AP_FLASH_WP_L". The rest are
> provided for convenience.
> 
> Gru-Bob and Gru-Kevin share the gru-chromebook.dtsi, and for the most
> part they share pin meanings. I omitted a few areas where components
> were available only on one or the other.

Applied, thanks!

[1/1] arm64: dts: rockchip: add RK3399 Gru gpio-line-names
      commit: 9a35fd01f4abc3974e12539448038307acf27f16

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From semen.protsenko at linaro.org  Sat Aug 21 13:04:14 2021
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 21 Aug 2021 23:04:14 +0300
Subject: [PATCH v3 7/7] arm64: dts: exynos: Add Exynos850 SoC support
In-Reply-To: <YRwDETpe019RFU/q@robh.at.kernel.org>
References: <20210811114827.27322-1-semen.protsenko@linaro.org>
 <20210811114827.27322-8-semen.protsenko@linaro.org>
 <YRwDETpe019RFU/q@robh.at.kernel.org>
Message-ID: <CAPLW+4mt8x3XacrOHBSgOPZckUbhs=7ee4MCZwEP3ziPYRD7bw@mail.gmail.com>

On Tue, 17 Aug 2021 at 21:42, Rob Herring <robh at kernel.org> wrote:
>
> On Wed, Aug 11, 2021 at 02:48:27PM +0300, Sam Protsenko wrote:
> > Samsung Exynos850 is ARMv8-based mobile-oriented SoC.
> >
> > This patch adds minimal SoC support by including next Device Tree nodes:
> >
> > 1. Octa cores (Cortex-A55), supporting PSCI v1.0
> > 2. ARM architecture timer (armv8-timer)
> > 3. Interrupt controller (GIC-400)
> > 4. Pinctrl nodes for GPIO
> > 5. Serial node
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> > Changes in v3:
> >  - Used generic fixed clock for serial
> >
> > Changes in v2:
> >  * Commit message:
> >    - Documented added dts features instead of CPU features
> >
> >  * exynos850-usi.dtsi:
> >    - Removed, moved everything to exynos850.dtsi
> >
> >  * exynos850.dtsi:
> >    - Root node:
> >      - Added comment about engineering name (Exynos3830)
> >      - Renamed pinctrl nodes, adding domain names
> >      - Used hard coded IRQ numbers instead of named constants everywhere
> >      - Added soc node, moved next nodes there: gic, clock, pinctrls and
> >        serial
> >      - Used address-cells=1 for soc node and removed unneeded 0x0 from
> >        reg properties
> >      - Moved exynos850-pinctrl.dtsi include line to the end of
> >        exynos850.dtsi
> >      - Coding style fixes
> >    - cpus:
> >      - Used address-cells=1 for cpus node
> >      - Renamed cpu at 0001 to cpu at 1, and so on
> >      - Left only "arm,cortex-a55" for cpus compatible
> >      - Renamed reg = <0x0001> to <0x1> for cpus
> >    - armv8 timer:
> >      - Add comment about missing HV timer IRQ to armv8 timer node
> >      - Removed not existing properties from armv8 timer node
> >      - Fixed cpu number in CPU_MASK()
> >      - Removed obsolete clock-frequency property
> >    - GIC:
> >      - Fixed GIC type to be GIC-400
> >      - Fixed size of GIC's 2nd region to be 0x2000
> >    - serial node:
> >      - Hard coded clock number for serial_0 for now; will replace with
> >        named const once proper clock driver is implemented
> >      - Removed gate_uart_clk0 clock from serial_0, as that clock is not
> >        supported in serial driver anyway (yet)
> >    - clock node:
> >      - Fixed clock controller node name (@0x12.. -> @12..)
> >
> >  * exynos850-pinctrl.dtsi:
> >    - Referenced pinctrl nodes instead of defining those again in root node
> >    - Fixed interrupt-cells (3 -> 2)
> >    - Fixed USI related comments for pin config nodes
> >    - Removed decon_f_te_* and fm_lna_en nodes (won't be used)
> >    - Reordered pin config nodes by pin numbers
> >    - Improved all comments
> >    - Used existing named constants for pin-function and pin-pud
> >    - Fixed node names (used hyphens instead of underscore)
> >    - Fixed warnings found in W=1 build
> >
> >  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 748 ++++++++++++++++++
> >  arch/arm64/boot/dts/exynos/exynos850.dtsi     | 261 ++++++
> >  2 files changed, 1009 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> >  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > new file mode 100644
> > index 000000000000..ba5d5f33e2f6
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > @@ -0,0 +1,748 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
> > + *
> > + * Copyright (C) 2017 Samsung Electronics Co., Ltd.
> > + * Copyright (C) 2021 Linaro Ltd.
> > + *
> > + * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
> > + * tree nodes in this file.
> > + */
> > +
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/pinctrl/samsung.h>
> > +
> > +&pinctrl_alive {
> > +     gpa0: gpa0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpa1: gpa1 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpa2: gpa2 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpa3: gpa3 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpa4: gpa4 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
> > +                          <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpq0: gpq0 {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +     };
> > +
> > +     /* I2C5 (also called CAM_PMIC_I2C in TRM) */
> > +     i2c5_bus: i2c5-bus {
>
> Please name all the pinctrl nodes with some pattern you can match on
> once there is a schema. '-pins$' is my suggestion.
>

Done. This looks much better, the change will be present in new patch
series including board dts.

Can I ask for more info about schema you mentioned: is there some doc
or examples I can check? And is it something generic, or I have to
implement it for Exynos850 dts?

Thanks!

> > +             samsung,pins = "gpa3-5", "gpa3-6";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };
> > +
> > +     /* I2C6 (also called MOTOR_I2C in TRM) */
> > +     i2c6_bus: i2c6-bus {
> > +             samsung,pins = "gpa3-7", "gpa4-0";
> > +             samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> > +             samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> > +             samsung,pin-drv = <0>;
> > +     };


From frattaroli.nicolas at gmail.com  Sat Aug 21 13:45:52 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Sat, 21 Aug 2021 22:45:52 +0200
Subject: [PATCH v2 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <66d6bd43-ee43-eff4-7a68-333fbb996787@linux.intel.com>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
 <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
 <66d6bd43-ee43-eff4-7a68-333fbb996787@linux.intel.com>
Message-ID: <3469189.PC3msRC2N5@archbook>

On Freitag, 20. August 2021 21:02:16 CEST Pierre-Louis Bossart wrote:
> > +	regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
> > +	/* Wait on the clear operation to finish */
> > +	while (val) {
> 
> delay needed here?
> 

The rockchip_i2s.c code doesn't have a delay here either, but I can
add one of 1 usec for good measure, it seems weird to retry the
read as fast as it can.

> > +static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm,
> > +					 struct clk *clk, unsigned long rate,
> > +					 int ppm)
> > +{
> > +	unsigned long rate_target;
> > +	int delta, ret;
> > +
> > +	if (ppm == i2s_tdm->clk_ppm)
> > +		return 0;
> > +
> > +	delta = (ppm < 0) ? -1 : 1;
> > +	delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000,
> > +				1000000);
> 
> formula looks odd? looks like you are implementing a round to nearest
> operation, but that shouldn't require this multiplication?
> 

I believe the multiplication is there to compensate for clock drift.
ppm is a value between -1000 and 1000 that specifies the clock drift
in presumably parts per million, going by the variable name.

> > +	pm_runtime_enable(&pdev->dev);
> > +	if (!pm_runtime_enabled(&pdev->dev)) {
> > +		ret = i2s_tdm_runtime_resume(&pdev->dev);
> 
> that looks like dead code? you've just enabled pm_runtime, why would
> this fail?
> 

I've had a look at the upstream rockchip_i2s.c code which does the
same thing, and I believe the idea here is that we need to manually
prepare and enable the master clocks (mclk_rx/mclk_tx) if pm_runtime
is not available. Otherwise, pm_runtime will presumably call our
resume callback at some point.

If runtime power management is disabled in the kernel config then 
pm_runtime_enabled is always going to return false.

> > +err_suspend:
> > +	if (!pm_runtime_status_suspended(&pdev->dev))
> > +		i2s_tdm_runtime_suspend(&pdev->dev);
> 
> why is this necessary?

I believe this is the same kind of situation as before, and the
other driver does this too: if pm_runtime is not available, we
need to stop our clocks manually on probe failure.
 
> > +err_pm_disable:
> > +	pm_runtime_disable(&pdev->dev);
> > +
> > +	return ret;
> > +}
> > +
> > +static int rockchip_i2s_tdm_remove(struct platform_device *pdev)
> > +{
> > +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(&pdev->dev);
> > +
> > +	pm_runtime_disable(&pdev->dev);
> > +	if (!pm_runtime_status_suspended(&pdev->dev))
> > +		i2s_tdm_runtime_suspend(&pdev->dev);
> 
> this looks backwards, if you disable pm_runtime first what is the
> expectation for the rest.

I'm not well versed in the PM code but if my theory of this being
related to unavailable PM is correct, then my best guess is that
pm_runtime_disable does suspend the device, so if it's not
suspended then we don't have pm_runtime and therefore need to call
it manually.

> > +
> > +	if (!IS_ERR(i2s_tdm->mclk_tx))
> > +		clk_prepare_enable(i2s_tdm->mclk_tx);
> > +	if (!IS_ERR(i2s_tdm->mclk_rx))
> > +		clk_prepare_enable(i2s_tdm->mclk_rx);
> > +	if (!IS_ERR(i2s_tdm->hclk))
> > +		clk_disable_unprepare(i2s_tdm->hclk);
> > +
> > +	return 0;
> > +}
> > +
> > +#ifdef CONFIG_PM_SLEEP
> 
> use __maybe_unused

You mean instead of the ifdef stuff to just add this attribute to
the following functions like this?

static int rockchip_i2s_tdm_suspend(struct device *dev) __maybe_unused

> 
> > +static int rockchip_i2s_tdm_suspend(struct device *dev)
> > +{
> > +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
> > +
> > +	regcache_mark_dirty(i2s_tdm->regmap);
> > +
> > +	return 0;
> > +}
> > +
> > +static int rockchip_i2s_tdm_resume(struct device *dev)
> > +{
> > +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
> > +	int ret;
> > +
> > +	ret = pm_runtime_get_sync(dev);
> > +	if (ret < 0)
> > +		return ret;
> > +	ret = regcache_sync(i2s_tdm->regmap);
> > +	pm_runtime_put(dev);
> > +
> > +	return ret;
> > +}
> > +#endif

Thank you for your review!

Regards,
Nicolas Frattaroli





From chunkuang.hu at kernel.org  Sat Aug 21 16:14:00 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sun, 22 Aug 2021 07:14:00 +0800
Subject: [PATCH v8 03/13] dt-bindings: mediatek: add mediatek, dsc.yaml for
 mt8195 SoC binding
In-Reply-To: <20210819022327.13040-4-jason-jh.lin@mediatek.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-4-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY_9BUZ3x01FXY=UKmcrqGxmP7bfpqyz7zCJXK=+2xUhrYA@mail.gmail.com>

Hi, Jason:

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
>
> 1. Add mediatek,dsc.yaml to describe DSC module in details.
> 2. Add mt8195 SoC binding to mediatek,dsc.yaml.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  .../display/mediatek/mediatek,dsc.yaml        | 69 +++++++++++++++++++
>  1 file changed, 69 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
> new file mode 100644
> index 000000000000..f94a95c6a1c5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
> @@ -0,0 +1,69 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: mediatek display DSC controller
> +
> +maintainers:
> +  - CK Hu <ck.hu at mediatek.com>

According to [1], the maintainer should be

Chun-Kuang Hu <chunkuang.hu at kernel.org>, Philipp Zabel <p.zabel at pengutronix.de>

[1] https://www.kernel.org/doc/html/latest/process/maintainers.html

> +
> +description: |
> +  The DSC standard is a specification of the algorithms used for
> +  compressing and decompressing image display streams, including
> +  the specification of the syntax and semantics of the compressed
> +  video bit stream. DSC is designed for real-time systems with
> +  real-time compression, transmission, decompression and Display.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8195-disp-dsc
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: DSC Wrapper Clock
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  mediatek,gce-client-reg:
> +      description:
> +        The register of display function block to be set by gce. There are 4 arguments,
> +        such as gce node, subsys id, offset and register size. The subsys id that is
> +        mapping to the register of display function blocks is defined in the gce header
> +        include/include/dt-bindings/gce/<chip>-gce.h of each chips.
> +      $ref: /schemas/types.yaml#/definitions/phandle-array
> +      maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    dsc0: disp_dsc_wrap at 1c009000 {
> +        compatible = "mediatek,mt8195-disp-dsc";
> +        reg = <0 0x1c009000 0 0x1000>;
> +        interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +        clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
> +        mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
> +    };
> +
> --
> 2.18.0
>


From chunkuang.hu at kernel.org  Sat Aug 21 16:47:52 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sun, 22 Aug 2021 07:47:52 +0800
Subject: [PATCH v3 13/15] drm/mediatek: add ovl_adaptor support for MT8195
In-Reply-To: <20210818091847.8060-14-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-14-nancy.lin@mediatek.com>
Message-ID: <CAAOTY_-WUWzThnddWNwMzd=BTBsbFRfMs4ABKJk6huADHUWrgQ@mail.gmail.com>

Hi, Nancy:

Nancy.Lin <nancy.lin at mediatek.com> ? 2021?8?18? ?? ??5:19???
>
> Add ovl_adaptor driver for MT8195.
> Ovl_adaptor is an encapsulated module and designed for simplified
> DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and
> an ETHDR. Two RDMAs merge into one layer, so this module support 4
> layers.
>
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/Makefile             |   3 +-
>  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 528 ++++++++++++++++++
>  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.h   |  19 +
>  3 files changed, 549 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
>
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index 38ec2354a894..f04ac86c9593 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \
>                   mtk_drm_plane.o \
>                   mtk_dsi.o \
>                   mtk_dpi.o \
> -                 mtk_mdp_rdma.o
> +                 mtk_mdp_rdma.o \
> +                 mtk_disp_ovl_adaptor.o

Alphabetic order.

>
>  obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> new file mode 100644
> index 000000000000..8222ec5ff799
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> @@ -0,0 +1,528 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + */
> +
> +#include <drm/drm_fourcc.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/component.h>

Alphabetic order.

> +#include <linux/of_device.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/soc/mediatek/mtk-mmsys.h>
> +#include <linux/soc/mediatek/mtk-cmdq.h>
> +
> +#include "mtk_drm_drv.h"
> +#include "mtk_drm_crtc.h"
> +#include "mtk_drm_ddp_comp.h"
> +#include "mtk_disp_drv.h"
> +#include "mtk_disp_ovl_adaptor.h"
> +
> +#define DISP_MERGE_ENABLE      0x0
> +       #define MERGE_ENABLE BIT(0)

I would like

#define DISP_MERGE_ENABLE      0x0
#define MERGE_ENABLE                           BIT(0)

> +#define DISP_MERGE_CFG_0       0x10
> +#define DISP_MERGE_CFG_1       0x14
> +#define DISP_MERGE_CFG_4       0x20
> +#define DISP_MERGE_CFG_5       0x24
> +#define DISP_MERGE_CFG_10      0x38
> +       #define CFG_10_NO_SWAP 0
> +#define DISP_MERGE_CFG_12      0x40
> +       #define CFG12_10_10_1PI_2PO_BUF_MODE 6
> +       #define CFG12_11_10_1PI_2PO_MERGE 18
> +#define DISP_MERGE_CFG_24      0x70
> +#define DISP_MERGE_CFG_25      0x74
> +#define DISP_MERGE_CFG_26      0x78
> +#define DISP_MERGE_CFG_27      0x7c
> +#define DISP_MERGE_MUTE_0      0xf00
> +
> +#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
> +#define MTK_OVL_ADAPTOR_LAYER_NUM 4
> +
> +enum mtk_ovl_adaptor_comp_type {
> +       OVL_ADAPTOR_TYPE_RDMA = 0,
> +       OVL_ADAPTOR_TYPE_MERGE,
> +       OVL_ADAPTOR_TYPE_NUM,
> +};
> +
> +enum mtk_ovl_adaptor_comp_id {
> +       OVL_ADAPTOR_MDP_RDMA0,
> +       OVL_ADAPTOR_MDP_RDMA1,
> +       OVL_ADAPTOR_MDP_RDMA2,
> +       OVL_ADAPTOR_MDP_RDMA3,
> +       OVL_ADAPTOR_MDP_RDMA4,
> +       OVL_ADAPTOR_MDP_RDMA5,
> +       OVL_ADAPTOR_MDP_RDMA6,
> +       OVL_ADAPTOR_MDP_RDMA7,
> +       OVL_ADAPTOR_MERGE0,
> +       OVL_ADAPTOR_MERGE1,
> +       OVL_ADAPTOR_MERGE2,
> +       OVL_ADAPTOR_MERGE3,
> +       OVL_ADAPTOR_ID_MAX
> +};
> +
> +struct ovl_adaptor_comp_match {
> +       enum mtk_ovl_adaptor_comp_type type;
> +       int alias_id;
> +};
> +
> +struct ovl_adaptor_merge_config {
> +       unsigned int fmt;
> +       unsigned int merge_mode;
> +       unsigned int in_w[2];
> +       unsigned int out_w[2];
> +       unsigned int in_h;
> +};
> +
> +struct mtk_ovl_adaptor_comp {
> +       struct device *dev;
> +       struct clk *clks[2];
> +       struct cmdq_client_reg cmdq_base;
> +       void __iomem *regs;
> +};

keep only dev, other value should be moved to dev private data.

> +
> +struct mtk_disp_ovl_adaptor {
> +       struct mtk_ovl_adaptor_comp ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
> +       struct device *mmsys_dev;
> +};
> +
> +static const char * const ovl_adaptor_comp_str[] = {
> +       "OVL_ADAPTOR_MDP_RDMA0",
> +       "OVL_ADAPTOR_MDP_RDMA1",
> +       "OVL_ADAPTOR_MDP_RDMA2",
> +       "OVL_ADAPTOR_MDP_RDMA3",
> +       "OVL_ADAPTOR_MDP_RDMA4",
> +       "OVL_ADAPTOR_MDP_RDMA5",
> +       "OVL_ADAPTOR_MDP_RDMA6",
> +       "OVL_ADAPTOR_MDP_RDMA7",
> +       "OVL_ADAPTOR_MERGE0",
> +       "OVL_ADAPTOR_MERGE1",
> +       "OVL_ADAPTOR_MERGE2",
> +       "OVL_ADAPTOR_MERGE3",
> +       "OVL_ADAPTOR_ID_MAX"
> +};
> +
> +static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
> +       [OVL_ADAPTOR_TYPE_RDMA] = "vdo1_rdma",
> +       [OVL_ADAPTOR_TYPE_MERGE] = "merge",
> +};
> +
> +static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
> +       [OVL_ADAPTOR_MDP_RDMA0] =       { OVL_ADAPTOR_TYPE_RDMA, 0 },
> +       [OVL_ADAPTOR_MDP_RDMA1] =       { OVL_ADAPTOR_TYPE_RDMA, 1 },
> +       [OVL_ADAPTOR_MDP_RDMA2] =       { OVL_ADAPTOR_TYPE_RDMA, 2 },
> +       [OVL_ADAPTOR_MDP_RDMA3] =       { OVL_ADAPTOR_TYPE_RDMA, 3 },
> +       [OVL_ADAPTOR_MDP_RDMA4] =       { OVL_ADAPTOR_TYPE_RDMA, 4 },
> +       [OVL_ADAPTOR_MDP_RDMA5] =       { OVL_ADAPTOR_TYPE_RDMA, 5 },
> +       [OVL_ADAPTOR_MDP_RDMA6] =       { OVL_ADAPTOR_TYPE_RDMA, 6 },
> +       [OVL_ADAPTOR_MDP_RDMA7] =       { OVL_ADAPTOR_TYPE_RDMA, 7 },
> +       [OVL_ADAPTOR_MERGE0] =  { OVL_ADAPTOR_TYPE_MERGE, 1 },
> +       [OVL_ADAPTOR_MERGE1] =  { OVL_ADAPTOR_TYPE_MERGE, 2 },
> +       [OVL_ADAPTOR_MERGE2] =  { OVL_ADAPTOR_TYPE_MERGE, 3 },
> +       [OVL_ADAPTOR_MERGE3] =  { OVL_ADAPTOR_TYPE_MERGE, 4 },
> +};
> +
> +static void mtk_ovl_adaptor_merge_config(struct mtk_ovl_adaptor_comp *comp,
> +                                        struct ovl_adaptor_merge_config *merge_cfg,
> +                                        struct cmdq_pkt *cmdq_pkt)
> +{
> +       switch (merge_cfg->merge_mode) {
> +       case 6:
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_0);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->out_w[0]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_4);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_24);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_25);
> +               break;
> +       case 18:
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_0);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[1]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_1);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->out_w[0]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_4);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_24);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[1]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_25);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[0]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_26);
> +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 | merge_cfg->in_w[1]),
> +                             &comp->cmdq_base, comp->regs, DISP_MERGE_CFG_27);
> +               break;
> +       default:
> +               break;
> +       }
> +
> +       mtk_ddp_write(cmdq_pkt, merge_cfg->merge_mode, &comp->cmdq_base,
> +                     comp->regs, DISP_MERGE_CFG_12);
> +       mtk_ddp_write(cmdq_pkt, CFG_10_NO_SWAP, &comp->cmdq_base,
> +                     comp->regs, DISP_MERGE_CFG_10);
> +       mtk_ddp_write_mask(cmdq_pkt, 1, &comp->cmdq_base, comp->regs,
> +                          DISP_MERGE_ENABLE, MERGE_ENABLE);

Move this function to merge driver.

> +}
> +
> +void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
> +                                 struct mtk_plane_state *state,
> +                                 struct cmdq_pkt *cmdq_pkt)
> +{
> +       struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
> +       struct mtk_plane_pending_state *pending = &state->pending;
> +       struct ovl_adaptor_merge_config merge_cfg = {0};
> +       struct mtk_mdp_rdma_cfg rdma_config = {0};
> +       struct mtk_ovl_adaptor_comp *rdma_l;
> +       struct mtk_ovl_adaptor_comp *rdma_r;
> +       struct mtk_ovl_adaptor_comp *merge;
> +       const struct drm_format_info *fmt_info = drm_format_info(pending->format);
> +       bool use_dual_pipe = false;
> +
> +       dev_dbg(dev, "%s+ idx:%d, enable:%d, fmt:0x%x\n", __func__, idx,
> +               pending->enable, pending->format);
> +       dev_dbg(dev, "addr 0x%lx, fb w:%d, {%d,%d,%d,%d}\n",
> +               pending->addr, (pending->pitch / fmt_info->cpp[0]),
> +               pending->x, pending->y, pending->width, pending->height);
> +
> +       rdma_l = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx];
> +       rdma_r = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx + 1];
> +       merge = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
> +
> +       if (!pending->enable) {
> +               mtk_ddp_write_mask(cmdq_pkt, 0x0, &merge->cmdq_base, merge->regs,
> +                                  DISP_MERGE_ENABLE, MERGE_ENABLE);

Ditto.

> +               mtk_mdp_rdma_stop(rdma_l->regs, cmdq_pkt, &rdma_l->cmdq_base);
> +               mtk_mdp_rdma_stop(rdma_r->regs, cmdq_pkt, &rdma_r->cmdq_base);
> +               return;
> +       }
> +
> +       if (pending->width > MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH)
> +               use_dual_pipe = true;
> +
> +       merge_cfg.out_w[0] = pending->width;
> +       merge_cfg.in_h = pending->height;
> +       merge_cfg.fmt = pending->format;
> +       if (use_dual_pipe) {
> +               merge_cfg.merge_mode = CFG12_11_10_1PI_2PO_MERGE;
> +               merge_cfg.in_w[0] = (pending->width / 2) + ((pending->width / 2) % 2);
> +               merge_cfg.in_w[1] = (pending->width / 2) - ((pending->width / 2) % 2);

merge_cfg.in_w[1] = pending->width - merge_cfg.in_w[0];

> +       } else {
> +               merge_cfg.merge_mode = CFG12_10_10_1PI_2PO_BUF_MODE;
> +               merge_cfg.in_w[0] = pending->width;
> +       }
> +       mtk_ovl_adaptor_merge_config(merge, &merge_cfg, cmdq_pkt);
> +
> +       mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev, MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
> +                            idx, pending->width / 2, cmdq_pkt);
> +       mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev, MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
> +                            idx, pending->height, cmdq_pkt);
> +
> +       rdma_config.source_width = pending->pitch / fmt_info->cpp[0];
> +       rdma_config.csc_enable = fmt_info->is_yuv ? true : false;
> +       rdma_config.profile = RDMA_CSC_FULL709_TO_RGB;
> +       rdma_config.width = merge_cfg.in_w[0];
> +       rdma_config.height = pending->height;
> +       rdma_config.addr0 = pending->addr;
> +       rdma_config.pitch = pending->pitch;
> +       rdma_config.fmt = pending->format;
> +       mtk_mdp_rdma_config(rdma_l->regs, &rdma_config, cmdq_pkt, &rdma_l->cmdq_base);
> +
> +       rdma_config.x_left = merge_cfg.in_w[0];
> +       rdma_config.width = merge_cfg.in_w[1];
> +       mtk_mdp_rdma_config(rdma_r->regs, &rdma_config, cmdq_pkt, &rdma_r->cmdq_base);
> +
> +       mtk_ddp_write_mask(cmdq_pkt, 0x1, &merge->cmdq_base, merge->regs,
> +                          DISP_MERGE_ENABLE, MERGE_ENABLE);
> +       mtk_ddp_write_mask(cmdq_pkt, 0x0, &merge->cmdq_base, merge->regs,
> +                          DISP_MERGE_MUTE_0, 0x1);

Move this to merge driver.

> +
> +       mtk_mdp_rdma_start(rdma_l->regs, cmdq_pkt, &rdma_l->cmdq_base);
> +       if (use_dual_pipe)
> +               mtk_mdp_rdma_start(rdma_r->regs, cmdq_pkt, &rdma_r->cmdq_base);
> +       else
> +               mtk_mdp_rdma_stop(rdma_r->regs, cmdq_pkt, &rdma_r->cmdq_base);
> +}
> +
> +void mtk_ovl_adaptor_stop(struct device *dev)
> +{
> +       struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
> +       struct mtk_ovl_adaptor_comp *rdma_l;
> +       struct mtk_ovl_adaptor_comp *rdma_r;
> +       struct mtk_ovl_adaptor_comp *merge;
> +       unsigned int reg;
> +       u32 i;
> +
> +       for (i = 0; i < MTK_OVL_ADAPTOR_LAYER_NUM; i++) {
> +               rdma_l = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * i];
> +               rdma_r = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * i + 1];
> +               merge = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + i];
> +
> +               mtk_mdp_rdma_stop(rdma_l->regs, NULL, &rdma_l->cmdq_base);
> +               mtk_mdp_rdma_stop(rdma_r->regs, NULL, &rdma_r->cmdq_base);
> +
> +               reg = readl(merge->regs + DISP_MERGE_ENABLE);
> +               reg = reg & ~MERGE_ENABLE;
> +               writel_relaxed(reg, merge->regs + DISP_MERGE_ENABLE);

Ditto.

> +
> +               device_reset_optional(merge->dev);
> +       }
> +}
> +
> +int mtk_ovl_adaptor_clk_enable(struct device *dev)
> +{
> +       struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
> +       struct mtk_ovl_adaptor_comp *comp;
> +       int ret;
> +       int i;
> +       int j;
> +
> +       for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_ID_MAX; i++) {
> +               comp = &ovl_adaptor->ovl_adaptor_comp[i];
> +               if (!comp->dev)
> +                       continue;
> +
> +               /* Need to power on for private rdma devices */
> +               if (i < OVL_ADAPTOR_MERGE0) {
> +                       ret = pm_runtime_get_sync(comp->dev);
> +                       if (ret < 0)
> +                               dev_err(dev,
> +                                       "Failed to power on, err %d-%s\n",
> +                                       ret, ovl_adaptor_comp_str[i]);

undo previos pm_runtime_get_sync() and return error.

> +               }
> +
> +               for (j = 0; j < ARRAY_SIZE(comp->clks); j++) {
> +                       if (IS_ERR(comp->clks[j]))
> +                               break;
> +
> +                       ret = clk_prepare_enable(comp->clks[j]);
> +                       if (ret)
> +                               dev_err(dev,
> +                                       "Failed to enable clock %d, err %d-%s\n",
> +                                       i, ret, ovl_adaptor_comp_str[i]);

undo and previous job and return error.

> +               }
> +       }
> +
> +       return ret;
> +}
> +
> +void mtk_ovl_adaptor_clk_disable(struct device *dev)
> +{
> +       struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
> +       struct mtk_ovl_adaptor_comp *comp;
> +       int ret;
> +       int i;
> +       int j;
> +
> +       for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_ID_MAX; i++) {
> +               comp = &ovl_adaptor->ovl_adaptor_comp[i];
> +               if (!comp->dev)
> +                       continue;
> +
> +               for (j = 0; i < ARRAY_SIZE(comp->clks); j++) {
> +                       if (IS_ERR(comp->clks[j]))
> +                               break;
> +                       clk_disable_unprepare(comp->clks[j]);
> +               }
> +
> +               /* Need to power off for private rdma devices */
> +               if (i < OVL_ADAPTOR_MERGE0) {
> +                       ret = pm_runtime_put(comp->dev);
> +                       if (ret < 0)
> +                               dev_err(dev,
> +                                       "Failed to power off, err-%s\n",
> +                                       ret, ovl_adaptor_comp_str[i]);
> +               }
> +       }
> +}
> +
> +static int ovl_adaptor_comp_get_id(struct device *dev, struct device_node *node,
> +                                  enum mtk_ovl_adaptor_comp_type type)
> +{
> +       int alias_id = of_alias_get_id(node, private_comp_stem[type]);
> +       int ret;
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
> +               if (comp_matches[i].type == type &&
> +                   comp_matches[i].alias_id == alias_id)
> +                       return i;
> +
> +       dev_err(dev, "Failed to get id. type: %d, alias: %d\n", type, alias_id);
> +       return -EINVAL;
> +}
> +
> +static int private_comp_init(struct device *dev, struct device_node *node,
> +                            struct mtk_ovl_adaptor_comp *comp,
> +                            enum mtk_ovl_adaptor_comp_id id)
> +{
> +       struct platform_device *comp_pdev;
> +       int ret;
> +       int i;
> +
> +       if (id < 0 || id >= OVL_ADAPTOR_ID_MAX) {
> +               dev_err(dev, "Invalid component id %d\n", id);
> +               return -EINVAL;
> +       }
> +
> +       comp_pdev = of_find_device_by_node(node);
> +       if (!comp_pdev) {
> +               dev_warn(dev, "can't find platform device of node:%s\n",
> +                        node->name);
> +               return -ENODEV;
> +       }
> +       comp->dev = &comp_pdev->dev;
> +       comp->regs = of_iomap(node, 0);
> +
> +       for (i = 0; i < ARRAY_SIZE(comp->clks); i++) {
> +               comp->clks[i] = of_clk_get(node, i);
> +               if (IS_ERR(comp->clks[i]))
> +                       break;
> +       }
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +       ret = cmdq_dev_get_client_reg(comp->dev, &comp->cmdq_base, 0);
> +       if (ret)
> +               dev_info(dev, "get mediatek,gce-client-reg fail!\n");
> +#endif
> +
> +       if (id < OVL_ADAPTOR_MERGE0)
> +               pm_runtime_enable(comp->dev);
> +
> +       dev_info(dev, "[DRM]regs:0x%p, node:%s\n", comp->regs, ovl_adaptor_comp_str[id]);
> +
> +       return 0;
> +}
> +
> +static int mtk_disp_ovl_adaptor_comp_probe(struct platform_device *pdev)
> +{
> +       return 0;
> +}
> +
> +static int mtk_disp_ovl_adaptor_comp_remove(struct platform_device *pdev)
> +{
> +       return 0;
> +}
> +
> +static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = {
> +       {
> +               .compatible = "mediatek,mt8195-vdo1-rdma",
> +               .data = (void *)OVL_ADAPTOR_TYPE_RDMA,
> +       }, {
> +               .compatible = "mediatek,mt8195-vdo1-merge",
> +               .data = (void *)OVL_ADAPTOR_TYPE_MERGE,
> +       },
> +       {},
> +};
> +
> +static struct platform_driver mtk_disp_ovl_adaptor_comp_driver = {
> +       .probe          = mtk_disp_ovl_adaptor_comp_probe,
> +       .remove         = mtk_disp_ovl_adaptor_comp_remove,
> +       .driver = {
> +               .name   = "mediatek-disp-ovl-adaptor-comp",
> +               .owner  = THIS_MODULE,
> +               .of_match_table = mtk_ovl_adaptor_comp_dt_ids,
> +       },
> +};
> +module_platform_driver(mtk_disp_ovl_adaptor_comp_driver);
> +
> +static int ovl_adaptor_comp_init(struct device *dev)
> +{
> +       struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
> +       struct device_node *node, *parent;
> +       int i, ret;
> +
> +       parent = dev->parent->of_node->parent;
> +
> +       for_each_child_of_node(parent, node) {
> +               const struct of_device_id *of_id;
> +               enum mtk_ovl_adaptor_comp_type type;
> +               struct mtk_ovl_adaptor_comp *comp;
> +               int id;
> +
> +               of_id = of_match_node(mtk_ovl_adaptor_comp_dt_ids, node);
> +               if (!of_id)
> +                       continue;
> +
> +               if (!of_device_is_available(node)) {
> +                       dev_info(dev, "Skipping disabled component %pOF\n",
> +                                node);
> +                       continue;
> +               }
> +
> +               type = (enum mtk_ovl_adaptor_comp_type)of_id->data;
> +               id = ovl_adaptor_comp_get_id(dev, node, type);
> +               if (id < 0) {
> +                       dev_warn(dev, "Skipping unknown component %pOF\n",
> +                                node);
> +                       continue;
> +               }
> +
> +               ret = private_comp_init(dev, node, &priv->ovl_adaptor_comp[id], id);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id ovl_adaptor_driver_dt_match[] = {
> +       { .compatible = "mediatek,mt8195-disp-ethdr"},
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, mtk_disp_ovl_adaptor_driver_dt_match);
> +
> +static int mtk_disp_ovl_adaptor_probe(struct platform_device *pdev)
> +{
> +       struct mtk_disp_ovl_adaptor *priv;
> +       struct device *dev = &pdev->dev;
> +       struct device_node *phandle = dev->parent->of_node;
> +       const struct of_device_id *of_id;
> +       int ret;
> +       int i;
> +
> +       dev_info(dev, "%s+\n", __func__);
> +
> +       of_id = of_match_node(ovl_adaptor_driver_dt_match, phandle);
> +       if (!of_id)
> +               return -ENODEV;
> +
> +       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       priv->mmsys_dev = pdev->dev.platform_data;
> +
> +       platform_set_drvdata(pdev, priv);
> +
> +       ret = ovl_adaptor_comp_init(dev);
> +       if (ret) {
> +               dev_notice(dev, "ovl_adaptor comp init fail\n");
> +               return ret;
> +       }
> +
> +       dev_info(dev, "%s-\n", __func__);
> +       return ret;
> +}
> +
> +static int mtk_disp_ovl_adaptor_remove(struct platform_device *pdev)
> +{
> +       struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(&pdev->dev);
> +       int i;
> +
> +       for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_MERGE0; i++)
> +               pm_runtime_disable(ovl_adaptor->ovl_adaptor_comp[i].dev);
> +
> +       return 0;
> +}
> +
> +struct platform_driver mtk_disp_ovl_adaptor_driver = {
> +       .probe = mtk_disp_ovl_adaptor_probe,
> +       .remove = mtk_disp_ovl_adaptor_remove,
> +       .driver = {
> +                       .name = "mediatek-disp-ovl-adaptor",
> +                       .owner = THIS_MODULE,
> +               },
> +};
> +module_platform_driver(mtk_disp_ovl_adaptor_driver);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
> new file mode 100644
> index 000000000000..7d757be1f491
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + */
> +
> +#ifndef __MTK_DISP_OVL_ADAPTOR_H__
> +#define __MTK_DISP_OVL_ADAPTOR_H__
> +
> +#include <drm/mediatek_drm.h>
> +
> +void mtk_ovl_adaptor_stop(struct device *dev);
> +int mtk_ovl_adaptor_clk_enable(struct device *dev);
> +void mtk_ovl_adaptor_clk_disable(struct device *dev);
> +void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
> +                                 struct mtk_plane_state *state,
> +                                 struct cmdq_pkt *cmdq_pkt);
> +
> +#endif
> +
> --
> 2.18.0
>


From chunkuang.hu at kernel.org  Sat Aug 21 18:14:24 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sun, 22 Aug 2021 09:14:24 +0800
Subject: [PATCH v3 15/15] drm/mediatek: add mediatek-drm of vdosys1
 support for MT8195
In-Reply-To: <20210818091847.8060-16-nancy.lin@mediatek.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-16-nancy.lin@mediatek.com>
Message-ID: <CAAOTY_99QLpRHLei2PzD8vsuoOaZae++NqczPCM+r9YMZ01btw@mail.gmail.com>

Hi, Nancy:

Nancy.Lin <nancy.lin at mediatek.com> ? 2021?8?18? ?? ??5:18???
>
> Add driver data of mt8195 vdosys1 to mediatek-drm and modify drm for
> multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring
> up two drm drivers, only one drm driver register as the drm device.
> Each drm driver binds its own component. The first bind drm driver
> will allocate the drm device, and the last bind drm driver registers
> the drm device to drm core. Each crtc path is created with the
> corresponding drm driver data.
>
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
>
>
> +static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
> +       .clk_enable = mtk_ethdr_clk_enable,
> +       .clk_disable = mtk_ethdr_clk_disable,
> +       .config = mtk_ethdr_config,
> +       .start = mtk_ethdr_start,
> +       .stop = mtk_ethdr_stop,
> +       .layer_nr = mtk_ethdr_layer_nr,
> +       .layer_config = mtk_ethdr_layer_config,
> +       .enable_vblank = mtk_ethdr_enable_vblank,
> +       .disable_vblank = mtk_ethdr_disable_vblank,
> +};

I think ethdr is inside the group of ovl_adpator. I preter this
function is implemented by ovl_adaptor, and ovl_adaptor control rdma,
merge, ethdr.

Regards,
Chun-Kuang.

> +
>


From akiyks at gmail.com  Sat Aug 21 19:03:38 2021
From: akiyks at gmail.com (Akira Yokosawa)
Date: Sun, 22 Aug 2021 11:03:38 +0900
Subject: [PATCH v15 07/13] docs: counter: Document character device
 interface
In-Reply-To: <YSDa667n6pi4O8iT@shinobu>
References: <YSDa667n6pi4O8iT@shinobu>
Message-ID: <f6930072-c487-a102-931c-53a79515d5fa@gmail.com>

(dropped most CCs)

Hello William,

I spotted a minor error while browsing documentation updates.

On Sat, 21 Aug 2021 19:52:27 +0900, William Breathitt Gray wrote:
> On Sun, Aug 15, 2021 at 05:51:02PM +0100, Jonathan Cameron wrote:
>> On Mon,  9 Aug 2021 21:37:32 +0900
>> William Breathitt Gray <vilhelm.gray at gmail.com> wrote:
...
>> > +
>> > +Counter events can be configured by users to report various Counter
>> > +data of interest. This can be conceptualized as a list of Counter
>> > +component read calls to perform. For example:
>> > +
>> > +        +-------------------------------------------------+

This needs to be:

              +------------------------+------------------------+

, so that the table structure can be properly recognized by Sphinx
(kernel-doc tool).

        Thanks, Akira

>> > +        | COUNTER_EVENT_OVERFLOW | COUNTER_EVENT_INDEX    |
>> > +        +========================+========================+
>> > +        | Channel 0              | Channel 0              |
>> > +        +------------------------+------------------------+
>> > +        | * Count 0              | * Signal 0             |
>> > +        | * Count 1              | * Signal 0 Extension 0 |
>> > +        | * Signal 3             | * Extension 4          |
>> > +        | * Count 4 Extension 2  +------------------------+
>> > +        | * Signal 5 Extension 0 | Channel 1              |
>> > +        |                        +------------------------+
>> > +        |                        | * Signal 4             |
>> > +        |                        | * Signal 4 Extension 0 |
>> > +        |                        | * Count 7              |
>> > +        +------------------------+------------------------+
>> > +


From tangbin at cmss.chinamobile.com  Sat Aug 21 20:28:06 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Sun, 22 Aug 2021 11:28:06 +0800
Subject: [PATCH 3/3] serial: vt8500: Use of_device_get_match_data
In-Reply-To: <20210822032806.3256-1-tangbin@cmss.chinamobile.com>
References: <20210822032806.3256-1-tangbin@cmss.chinamobile.com>
Message-ID: <20210822032806.3256-4-tangbin@cmss.chinamobile.com>

Retrieve OF match data, it's better and cleaner to use
'of_device_get_match_data' over 'of_match_device'.

Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 drivers/tty/serial/vt8500_serial.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c
index c5edd56ff..e15b2bf69 100644
--- a/drivers/tty/serial/vt8500_serial.c
+++ b/drivers/tty/serial/vt8500_serial.c
@@ -623,17 +623,14 @@ static int vt8500_serial_probe(struct platform_device *pdev)
 	struct vt8500_port *vt8500_port;
 	struct resource *mmres, *irqres;
 	struct device_node *np = pdev->dev.of_node;
-	const struct of_device_id *match;
 	const unsigned int *flags;
 	int ret;
 	int port;
 
-	match = of_match_device(wmt_dt_ids, &pdev->dev);
-	if (!match)
+	flags = of_device_get_match_data(&pdev->dev);
+	if (!flags)
 		return -EINVAL;
 
-	flags = match->data;
-
 	mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!mmres || !irqres)
-- 
2.20.1.windows.1





From tangbin at cmss.chinamobile.com  Sat Aug 21 20:28:03 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Sun, 22 Aug 2021 11:28:03 +0800
Subject: [PATCH 0/3] serial: Use of_device_get_match_data
Message-ID: <20210822032806.3256-1-tangbin@cmss.chinamobile.com>

Hi all:

This patch series replace 'of_match_device' with
'of_device_get_match_data', to make code cleaner and better.

Thanks

Tang Bin (3):
  serial: 8250_ingenic: Use of_device_get_match_data
  serial: tegra: Use of_device_get_match_data
  serial: vt8500: Use of_device_get_match_data

 drivers/tty/serial/8250/8250_ingenic.c | 6 ++----
 drivers/tty/serial/serial-tegra.c      | 6 ++----
 drivers/tty/serial/vt8500_serial.c     | 7 ++-----
 3 files changed, 6 insertions(+), 13 deletions(-)

-- 
2.20.1.windows.1





From tangbin at cmss.chinamobile.com  Sat Aug 21 20:28:05 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Sun, 22 Aug 2021 11:28:05 +0800
Subject: [PATCH 2/3] serial: tegra: Use of_device_get_match_data
In-Reply-To: <20210822032806.3256-1-tangbin@cmss.chinamobile.com>
References: <20210822032806.3256-1-tangbin@cmss.chinamobile.com>
Message-ID: <20210822032806.3256-3-tangbin@cmss.chinamobile.com>

Retrieve OF match data, it's better and cleaner to use
'of_device_get_match_data' over 'of_match_device'.

Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 drivers/tty/serial/serial-tegra.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
index eba5b9ecb..45e2e4109 100644
--- a/drivers/tty/serial/serial-tegra.c
+++ b/drivers/tty/serial/serial-tegra.c
@@ -1568,14 +1568,12 @@ static int tegra_uart_probe(struct platform_device *pdev)
 	struct resource *resource;
 	int ret;
 	const struct tegra_uart_chip_data *cdata;
-	const struct of_device_id *match;
 
-	match = of_match_device(tegra_uart_of_match, &pdev->dev);
-	if (!match) {
+	cdata = of_device_get_match_data(&pdev->dev);
+	if (!cdata) {
 		dev_err(&pdev->dev, "Error: No device match found\n");
 		return -ENODEV;
 	}
-	cdata = match->data;
 
 	tup = devm_kzalloc(&pdev->dev, sizeof(*tup), GFP_KERNEL);
 	if (!tup) {
-- 
2.20.1.windows.1





From tangbin at cmss.chinamobile.com  Sat Aug 21 20:28:04 2021
From: tangbin at cmss.chinamobile.com (Tang Bin)
Date: Sun, 22 Aug 2021 11:28:04 +0800
Subject: [PATCH 1/3] serial: 8250_ingenic: Use of_device_get_match_data
In-Reply-To: <20210822032806.3256-1-tangbin@cmss.chinamobile.com>
References: <20210822032806.3256-1-tangbin@cmss.chinamobile.com>
Message-ID: <20210822032806.3256-2-tangbin@cmss.chinamobile.com>

Retrieve OF match data, it's better and cleaner to use
'of_device_get_match_data' over 'of_match_device'.

Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>
---
 drivers/tty/serial/8250/8250_ingenic.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
index 988bf6bcc..65402d05e 100644
--- a/drivers/tty/serial/8250/8250_ingenic.c
+++ b/drivers/tty/serial/8250/8250_ingenic.c
@@ -209,16 +209,14 @@ static int ingenic_uart_probe(struct platform_device *pdev)
 	struct uart_8250_port uart = {};
 	struct ingenic_uart_data *data;
 	const struct ingenic_uart_config *cdata;
-	const struct of_device_id *match;
 	struct resource *regs;
 	int irq, err, line;
 
-	match = of_match_device(of_match, &pdev->dev);
-	if (!match) {
+	cdata = of_device_get_match_data(&pdev->dev);
+	if (!cdata) {
 		dev_err(&pdev->dev, "Error: No device match found\n");
 		return -ENODEV;
 	}
-	cdata = match->data;
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
-- 
2.20.1.windows.1





From mans0n at gorani.run  Sat Aug 21 21:13:32 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Sun, 22 Aug 2021 13:13:32 +0900
Subject: [PATCH v3 0/1] Add MUSB for MT7623
In-Reply-To: <20210808123840.176738-1-mans0n@gorani.run>
References: <20210808123840.176738-1-mans0n@gorani.run>
Message-ID: <20210822041333.5264-1-mans0n@gorani.run>

These patches add support for the MUSB controller on Mediatek MT7623.
Tested on Mercury RUSH-318AC Wi-Fi router.

v3:
* dt-bindings
  * remove the queued patch
* DTS
  * remove unnecessary status=okay from u2port2

v2:
* dt-bindings
  * add reviewed by Matthias
* DTS
  * rename usb3 label to usb0
  * move usb0 & u2phy1 nodes to the right sorted place
  * disable u2phy1 by default
  * correct u2port2 node name to match its reg address

Sungbo Eo (1):
  arm: dts: mt7623: add musb device nodes

 arch/arm/boot/dts/mt7623.dtsi  | 33 +++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
 2 files changed, 37 insertions(+)

-- 
2.33.0



From mans0n at gorani.run  Sat Aug 21 21:13:33 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Sun, 22 Aug 2021 13:13:33 +0900
Subject: [PATCH v3 1/1] arm: dts: mt7623: add musb device nodes
In-Reply-To: <20210822041333.5264-1-mans0n@gorani.run>
References: <20210808123840.176738-1-mans0n@gorani.run>
 <20210822041333.5264-1-mans0n@gorani.run>
Message-ID: <20210822041333.5264-2-mans0n@gorani.run>

MT7623 has an musb controller that is compatible with the one from MT2701.

Signed-off-by: Sungbo Eo <mans0n at gorani.run>
---
v3:
* remove unnecessary status=okay from u2port2

v2:
* rename usb3 label to usb0
* move usb0 & u2phy1 nodes to the right sorted place
* disable u2phy1 by default
* correct u2port2 node name to match its reg address
---
 arch/arm/boot/dts/mt7623.dtsi  | 33 +++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index 3c11f7cfcc40..21c8a291b74e 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -585,6 +585,39 @@ spi2: spi at 11017000 {
 		status = "disabled";
 	};
 
+	usb0: usb at 11200000 {
+		compatible = "mediatek,mt7623-musb",
+			     "mediatek,mtk-musb";
+		reg = <0 0x11200000 0 0x1000>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "mc";
+		phys = <&u2port2 PHY_TYPE_USB2>;
+		dr_mode = "otg";
+		clocks = <&pericfg CLK_PERI_USB0>,
+			 <&pericfg CLK_PERI_USB0_MCU>,
+			 <&pericfg CLK_PERI_USB_SLV>;
+		clock-names = "main","mcu","univpll";
+		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
+		status = "disabled";
+	};
+
+	u2phy1: t-phy at 11210000 {
+		compatible = "mediatek,mt7623-tphy",
+			     "mediatek,generic-tphy-v1";
+		reg = <0 0x11210000 0 0x0800>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		u2port2: usb-phy at 11210800 {
+			reg = <0 0x11210800 0 0x0100>;
+			clocks = <&topckgen CLK_TOP_USB_PHY48M>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+		};
+	};
+
 	audsys: clock-controller at 11220000 {
 		compatible = "mediatek,mt7623-audsys",
 			     "mediatek,mt2701-audsys",
diff --git a/arch/arm/boot/dts/mt7623a.dtsi b/arch/arm/boot/dts/mt7623a.dtsi
index 0735a1fb8ad9..d304b62d24b5 100644
--- a/arch/arm/boot/dts/mt7623a.dtsi
+++ b/arch/arm/boot/dts/mt7623a.dtsi
@@ -35,6 +35,10 @@ &scpsys {
 	clock-names = "ethif";
 };
 
+&usb0 {
+	power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>;
+};
+
 &usb1 {
 	power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>;
 };
-- 
2.33.0



From christophe.jaillet at wanadoo.fr  Sun Aug 22 00:39:45 2021
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun, 22 Aug 2021 09:39:45 +0200
Subject: [PATCH] mt76: switch from 'pci_' to 'dma_' API
Message-ID: <83b2da6ff8a07d576fa3627051daa705aba37a3c.1629617782.git.christophe.jaillet@wanadoo.fr>

The wrappers in include/linux/pci-dma-compat.h should go away.

The patch has been generated with the coccinelle script below.

It has been compile tested.


@@
@@
-    PCI_DMA_BIDIRECTIONAL
+    DMA_BIDIRECTIONAL

@@
@@
-    PCI_DMA_TODEVICE
+    DMA_TO_DEVICE

@@
@@
-    PCI_DMA_FROMDEVICE
+    DMA_FROM_DEVICE

@@
@@
-    PCI_DMA_NONE
+    DMA_NONE

@@
expression e1, e2, e3;
@@
-    pci_alloc_consistent(e1, e2, e3)
+    dma_alloc_coherent(&e1->dev, e2, e3, GFP_)

@@
expression e1, e2, e3;
@@
-    pci_zalloc_consistent(e1, e2, e3)
+    dma_alloc_coherent(&e1->dev, e2, e3, GFP_)

@@
expression e1, e2, e3, e4;
@@
-    pci_free_consistent(e1, e2, e3, e4)
+    dma_free_coherent(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-    pci_map_single(e1, e2, e3, e4)
+    dma_map_single(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-    pci_unmap_single(e1, e2, e3, e4)
+    dma_unmap_single(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4, e5;
@@
-    pci_map_page(e1, e2, e3, e4, e5)
+    dma_map_page(&e1->dev, e2, e3, e4, e5)

@@
expression e1, e2, e3, e4;
@@
-    pci_unmap_page(e1, e2, e3, e4)
+    dma_unmap_page(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-    pci_map_sg(e1, e2, e3, e4)
+    dma_map_sg(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-    pci_unmap_sg(e1, e2, e3, e4)
+    dma_unmap_sg(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-    pci_dma_sync_single_for_cpu(e1, e2, e3, e4)
+    dma_sync_single_for_cpu(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-    pci_dma_sync_single_for_device(e1, e2, e3, e4)
+    dma_sync_single_for_device(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-    pci_dma_sync_sg_for_cpu(e1, e2, e3, e4)
+    dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4)

@@
expression e1, e2, e3, e4;
@@
-    pci_dma_sync_sg_for_device(e1, e2, e3, e4)
+    dma_sync_sg_for_device(&e1->dev, e2, e3, e4)

@@
expression e1, e2;
@@
-    pci_dma_mapping_error(e1, e2)
+    dma_mapping_error(&e1->dev, e2)

@@
expression e1, e2;
@@
-    pci_set_dma_mask(e1, e2)
+    dma_set_mask(&e1->dev, e2)

@@
expression e1, e2;
@@
-    pci_set_consistent_dma_mask(e1, e2)
+    dma_set_coherent_mask(&e1->dev, e2)

Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
If needed, see post from Christoph Hellwig on the kernel-janitors ML:
   https://marc.info/?l=kernel-janitors&m=158745678307186&w=4
---
 drivers/net/wireless/mediatek/mt76/mt7603/pci.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7615/pci.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt76x2/pci.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7915/pci.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/pci.c b/drivers/net/wireless/mediatek/mt76/mt7603/pci.c
index aa6cb668b012..3d94cdb4314a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/pci.c
@@ -28,7 +28,7 @@ mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	pci_set_master(pdev);
 
-	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
index 11f169cdd603..7a54ea6a86d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci.c
@@ -39,7 +39,7 @@ static int mt7615_pci_probe(struct pci_dev *pdev,
 	if (ret < 0)
 		return ret;
 
-	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret)
 		goto error;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index b795e7245c07..92ddb8c68938 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -176,7 +176,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	pci_set_master(pdev);
 
-	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
index adf288e50e21..fb8de1833937 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
@@ -47,7 +47,7 @@ mt76x2e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	pci_set_master(pdev);
 
-	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
index 340b364da5f0..c79b526346e7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
@@ -251,7 +251,7 @@ static int mt7915_pci_probe(struct pci_dev *pdev,
 
 	pci_set_master(pdev);
 
-	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret)
 		return ret;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index c3905bcab360..7e8cff3a1b94 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -128,7 +128,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
 	if (ret < 0)
 		return ret;
 
-	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret)
 		goto err_free_pci_vec;
 
-- 
2.30.2



From f.fainelli at gmail.com  Sun Aug 22 01:49:56 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 10:49:56 +0200
Subject: [PATCH v2 1/4] PCI: brcmstb: Break register definitions into
 separate header
In-Reply-To: <20210819215655.84866-2-jeremy.linton@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
 <20210819215655.84866-2-jeremy.linton@arm.com>
Message-ID: <f791df30-4916-fd58-e7fe-472f101247c1@gmail.com>



On 8/19/2021 11:56 PM, Jeremy Linton wrote:
> We are about to create a standalone ACPI quirk module for the
> bcmstb controller. Lets move the register definitions into a separate
> file so they can be shared between the APCI quirk and the normal
> host bridge driver.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>

Acked-by: Florian Fainelli <f.fainelli at gmail.com>
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 01:52:25 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 10:52:25 +0200
Subject: [PATCH v2 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210819215655.84866-3-jeremy.linton@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
 <20210819215655.84866-3-jeremy.linton@arm.com>
Message-ID: <f2cc62e2-276b-e6a9-3b2c-48a61061be25@gmail.com>



On 8/19/2021 11:56 PM, Jeremy Linton wrote:
> The PFTF CM4 is an ACPI platform that isn't ECAM compliant. Its config
> space is in two parts. One part is for the root port registers and a
> second moveable window pointing at a device's 4K config space. Thus it
> doesn't have an MCFG, and any MCFG provided would be nonsense
> anyway. Instead, a Linux specific host bridge _DSD selects a custom
> ECAM ops and cfgres. The cfg op picks between those two regions while
> disallowing problematic accesses.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>

Once you address Bjorn's feedback, feel free to add:

Acked-by: Florian Fainelli <f.fainelli at gmail.com>

I do wonder if squashing patches 2 and 3 would make more sense, 
otherwise we have a bcm2711_pcie_ops that is unused in patch 2.
-- 
Florian


From f.fainelli at gmail.com  Sun Aug 22 01:53:33 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 10:53:33 +0200
Subject: [PATCH v2 3/4] PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
In-Reply-To: <20210819215655.84866-4-jeremy.linton@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
 <20210819215655.84866-4-jeremy.linton@arm.com>
Message-ID: <9796674a-5870-135c-2fdc-fb0d5347d7c7@gmail.com>



On 8/19/2021 11:56 PM, Jeremy Linton wrote:
> Now that there is a bcm2711 quirk, it needs to be enabled when the
> MCFG is missing. Use an ACPI namespace _DSD property
> "linux-ecam-quirk-id" as an alternative to the MCFG OEM.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>   drivers/acpi/pci_mcfg.c | 13 +++++++++++++
>   1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
> index 53cab975f612..4b991ee5c66c 100644
> --- a/drivers/acpi/pci_mcfg.c
> +++ b/drivers/acpi/pci_mcfg.c
> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>   	ALTRA_ECAM_QUIRK(1, 13),
>   	ALTRA_ECAM_QUIRK(1, 14),
>   	ALTRA_ECAM_QUIRK(1, 15),
> +
> +	{ "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
> +	  DEFINE_RES_MEM(0xFD500000, 0xA000) },
>   };
>   
>   static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
> @@ -198,8 +201,18 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
>   	u16 segment = root->segment;
>   	struct resource *bus_range = &root->secondary;
>   	struct mcfg_fixup *f;
> +	const char *soc;
>   	int i;
>   
> +	/*
> +	 * This may be a machine with a PCI/SMC conduit, which means it doesn't
> +	 * have an MCFG. Use an ACPI namespace definition instead.
> +	 */
> +	if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
> +					 "linux-ecam-quirk-id", &soc)) {
> +		memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);

Being super paranoid here, can we use one of the "safe" string copy 
routines here just in case?

> +	}
> +
>   	for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
>   		if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
>   			if (f->cfgres.start)
> 

-- 
Florian


From f.fainelli at gmail.com  Sun Aug 22 01:55:51 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 10:55:51 +0200
Subject: [PATCH v2 4/4] MAINTAINERS: Widen brcmstb PCIe file scope
In-Reply-To: <20210820190917.GA3340819@bjorn-Precision-5520>
References: <20210820190917.GA3340819@bjorn-Precision-5520>
Message-ID: <44703985-286c-4f57-c4ef-7b4cbd82a8d7@gmail.com>



On 8/20/2021 9:09 PM, Bjorn Helgaas wrote:
> On Thu, Aug 19, 2021 at 04:56:55PM -0500, Jeremy Linton wrote:
>> The brcmstb PCI hardware is now split across
>> multiple files. Include them in the maintainers
>> block.
> 
> Rewrap to fill 75 columns or so.
> 
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>>   MAINTAINERS | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index fd25e4ecf0b9..605a385cea36 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -3500,7 +3500,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>>   S:	Maintained
>>   T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nsaenz/linux-rpi.git
>>   F:	Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
>> -F:	drivers/pci/controller/pcie-brcmstb.c
>> +F:	drivers/pci/controller/pcie-brcmstb*
> 
> There are already two entries that mention
> drivers/pci/controller/pcie-brcmstb.c, and a patch headed for v5.14
> adds a third.  Do you want to update them all?

That would be a good idea, the patch that Bjorn is referring to is:

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=e647eff57466c8cf7547532d6b26166b9b17f341

With that fixed:

Acked-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From f.fainelli at gmail.com  Sun Aug 22 02:07:05 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 11:07:05 +0200
Subject: [PATCH] PCI: brcmstb: implement BCM4908 support
In-Reply-To: <20210816125029.16879-1-zajec5@gmail.com>
References: <20210816125029.16879-1-zajec5@gmail.com>
Message-ID: <afe78c58-c89e-e0c0-2f84-06e36dd44864@gmail.com>

+JimQ,

On 8/16/2021 2:50 PM, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> BCM4908 is Broadcom's 64-bit platform with Broadcom's own Brahma-B53
> CPU(s). It uses the same PCIe hardware block as STB (Set-Top-Box) family
> but in a slightly different revision & setup.
> 
> Registers in BCM4908 variant are mostly the same but controller setup
> differs a bit. It requires setting few extra registers and takes
> slightly different bars setup.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>   drivers/pci/controller/pcie-brcmstb.c | 137 +++++++++++++++++++++++---
>   1 file changed, 123 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
> index cc30215f5a43..24bc7efcfdd5 100644
> --- a/drivers/pci/controller/pcie-brcmstb.c
> +++ b/drivers/pci/controller/pcie-brcmstb.c
> @@ -51,15 +51,20 @@
>   #define PCIE_RC_DL_MDIO_RD_DATA				0x1108
>   
>   #define PCIE_MISC_MISC_CTRL				0x4008
> +#define  PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE		0x00000080
> +#define  PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE		0x00000400
> +#define  PCIE_MISC_MISC_CTRL_PCIE_IN_WR_COMBINE		0x00000800
>   #define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK		0x1000
>   #define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK	0x2000
>   #define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK	0x300000
> +#define  PCIE_MISC_MISC_CTRL_BURST_ALIGN_MASK		0x00080000
>   
>   #define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK		0xf8000000
>   #define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK		0x07c00000
>   #define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK		0x0000001f
>   #define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
>   
> +
>   #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
>   #define PCIE_MEM_WIN0_LO(win)	\
>   		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
> @@ -115,6 +120,9 @@
>   #define PCIE_MEM_WIN0_LIMIT_HI(win)	\
>   		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
>   
> +#define PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_OFFSET		0x40ac
> +#define  PCIE_MISC_UBUS_BAR_CONFIG_ACCESS_EN		0x00000001
> +
>   #define PCIE_MISC_HARD_PCIE_HARD_DEBUG					0x4204
>   #define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
>   #define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
> @@ -131,6 +139,13 @@
>   #define PCIE_EXT_CFG_DATA				0x8000
>   #define PCIE_EXT_CFG_INDEX				0x9000
>   
> +#define PCIE_CPU_INTR1_INTR_MASK_CLEAR_OFFSET		0x940c
> +#define  PCIE_CPU_INTR1_PCIE_INTA_CPU_INTR		0x00000002
> +#define  PCIE_CPU_INTR1_PCIE_INTB_CPU_INTR		0x00000004
> +#define  PCIE_CPU_INTR1_PCIE_INTC_CPU_INTR		0x00000008
> +#define  PCIE_CPU_INTR1_PCIE_INTD_CPU_INTR		0x00000010
> +#define  PCIE_CPU_INTR1_PCIE_INTR_CPU_INTR		0x00000020
> +
>   #define  PCIE_RGR1_SW_INIT_1_PERST_MASK			0x1
>   #define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT		0x0
>   
> @@ -746,13 +761,19 @@ static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32
>   
>   static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
>   {
> -	if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
> -		return;
> +	if (pcie->hw_rev >= BRCM_PCIE_HW_REV_3_20) {
> +		brcm_pcie_perst_set_7278(pcie, val);
> +	} else {
> +		if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
> +			return;
>   
> -	if (val)
> -		reset_control_assert(pcie->perst_reset);
> -	else
> -		reset_control_deassert(pcie->perst_reset);
> +		if (val)
> +			reset_control_assert(pcie->perst_reset);
> +		else
> +			reset_control_deassert(pcie->perst_reset);
> +	}
> +
> +	usleep_range(10000, 20000);

This delay would warrant a comment.

>   }
>   
>   static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
> @@ -861,6 +882,86 @@ static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
>   	return 0;
>   }
>   
> +static int brcm_pcie_setup_bcm4908(struct brcm_pcie *pcie)
> +{
> +	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
> +	void __iomem *base = pcie->base;
> +	struct device *dev = pcie->dev;
> +	struct resource_entry *entry;
> +	u32 burst_align;
> +	u32 burst;
> +	u32 tmp;
> +	int win;
> +
> +	pcie->perst_set(pcie, 0);
> +
> +	msleep(500);
> +
> +	if (!brcm_pcie_link_up(pcie)) {
> +		dev_err(dev, "link down\n");
> +		return -ENODEV;
> +	}
> +
> +	/* setup lgacy outband interrupts */

s/lgacy/legacy/

> +	tmp = PCIE_CPU_INTR1_PCIE_INTA_CPU_INTR |
> +	      PCIE_CPU_INTR1_PCIE_INTB_CPU_INTR |
> +	      PCIE_CPU_INTR1_PCIE_INTC_CPU_INTR |
> +	      PCIE_CPU_INTR1_PCIE_INTD_CPU_INTR;
> +	writel(tmp, base + PCIE_CPU_INTR1_INTR_MASK_CLEAR_OFFSET);
> +
> +	win = 0;
> +	resource_list_for_each_entry(entry, &bridge->windows) {
> +		struct resource *res = entry->res;
> +		u64 pcie_addr;
> +
> +		if (resource_type(res) != IORESOURCE_MEM)
> +			continue;
> +
> +		if (win >= BRCM_NUM_PCIE_OUT_WINS) {
> +			dev_err(pcie->dev, "too many outbound wins\n");
> +			return -EINVAL;
> +		}
> +
> +		tmp = 0;
> +		u32p_replace_bits(&tmp, res->start / SZ_1M,
> +				  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK);
> +		u32p_replace_bits(&tmp, res->end / SZ_1M,
> +				  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK);
> +		writel(tmp, base + PCIE_MEM_WIN0_BASE_LIMIT(win));
> +
> +		pcie_addr = res->start - entry->offset;
> +		writel(lower_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_LO(win));
> +		writel(upper_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_HI(win));
> +
> +		win++;
> +	}
> +
> +	writel(0xf, base + PCIE_MISC_RC_BAR1_CONFIG_LO);
> +
> +	tmp = PCIE_MISC_UBUS_BAR_CONFIG_ACCESS_EN;
> +	writel(tmp, base + PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_OFFSET);
> +
> +	tmp = readl(base + PCIE_RC_CFG_PRIV1_ID_VAL3);
> +	u32p_replace_bits(&tmp, PCI_CLASS_BRIDGE_PCI << 8,
> +			  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK);
> +	writel(tmp, base + PCIE_RC_CFG_PRIV1_ID_VAL3);
> +
> +	/* Burst */
> +	burst = 0x1; /* 128 B */
> +	burst_align = 1;
> +
> +	tmp = readl(base + PCIE_MISC_MISC_CTRL);
> +	u32p_replace_bits(&tmp, burst_align, PCIE_MISC_MISC_CTRL_BURST_ALIGN_MASK);
> +	u32p_replace_bits(&tmp, burst, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK);
> +	u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK);
> +	u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_IN_WR_COMBINE);
> +	u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE);
> +	u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE);
> +	writel(tmp, base + PCIE_MISC_MISC_CTRL);

I see why you have made the 4908 bridge setup completely indepdent from 
the STB version of brcm_pcie_setup() however in the process there is a 
number of possibly equally relevant initialization that is not done and 
may assume firmware initialized or hardware default values (those would 
not survive suspend/resume states). Can you see about making minimal 
changes to brcm_pcie_setup() such that it supports the way 4908 should 
be initialized?

> +
> +	return 0;
> +}
> +
>   static int brcm_pcie_setup(struct brcm_pcie *pcie)
>   {
>   	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
> @@ -1284,6 +1385,13 @@ static int brcm_pcie_probe(struct platform_device *pdev)
>   		return PTR_ERR(pcie->perst_reset);
>   	}
>   
> +	if (pcie->type == BCM4908) {
> +		/* On BCM4908 we can read rev early and perst_set needs it */
> +		pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION);
> +
> +		pcie->perst_set(pcie, 1);
> +	}
> +
>   	ret = reset_control_reset(pcie->rescal);
>   	if (ret)
>   		dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
> @@ -1295,16 +1403,17 @@ static int brcm_pcie_probe(struct platform_device *pdev)
>   		return ret;
>   	}
>   
> -	ret = brcm_pcie_setup(pcie);
> -	if (ret)
> -		goto fail;
> +	if (pcie->type == BCM4908) {
> +		ret = brcm_pcie_setup_bcm4908(pcie);
> +		if (ret)
> +			goto fail;
> +	} else {
> +		ret = brcm_pcie_setup(pcie);
> +		if (ret)
> +			goto fail;
> +	}
>   
>   	pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION);
> -	if (pcie->type == BCM4908 && pcie->hw_rev >= BRCM_PCIE_HW_REV_3_20) {
> -		dev_err(pcie->dev, "hardware revision with unsupported PERST# setup\n");
> -		ret = -ENODEV;
> -		goto fail;
> -	}
>   
>   	msi_np = of_parse_phandle(pcie->np, "msi-parent", 0);
>   	if (pci_msi_enabled() && msi_np == pcie->np) {
> 

-- 
Florian


From heiko at sntech.de  Sun Aug 22 03:15:43 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 22 Aug 2021 12:15:43 +0200
Subject: [GIT PULL] Rockchip driver changes for 5.15
Message-ID: <9718620.EvYhyI6sBW@phil>

Hi Arnd, Kevin, Olof,

please find below (and in the next mails) changes for
Rockchip platforms for 5.15.

Please pull

Thanks
Heiko


The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v5.15-rockchip-driver1

for you to fetch changes up to 9e5747c57807ad8a04c356340190cfdd0bd54111:

  soc: rockchip: io-domain: Remove unneeded semicolon (2021-08-19 23:56:38 +0200)

----------------------------------------------------------------
Yaml conversion of io-domain bindings and addition of
rk3568 io domains.

----------------------------------------------------------------
Geert Uytterhoeven (1):
      soc: rockchip: ROCKCHIP_GRF should not default to y, unconditionally

Jianqun Xu (1):
      soc: rockchip: io-domain: add rk3568 support

Jiapeng Chong (1):
      soc: rockchip: io-domain: Remove unneeded semicolon

Johan Jonker (2):
      dt-bindings: power: convert rockchip-io-domain.txt to YAML
      dt-bindings: soc: rockchip: add rockchip-io-domain.yaml object to grf.yaml

Michael Riesch (1):
      dt-bindings: power: add rk3568-pmu-io-domain support

 .../bindings/power/rockchip-io-domain.txt          | 135 --------
 .../bindings/power/rockchip-io-domain.yaml         | 360 +++++++++++++++++++++
 .../devicetree/bindings/soc/rockchip/grf.yaml      |  19 +-
 drivers/soc/rockchip/Kconfig                       |   4 +-
 drivers/soc/rockchip/io-domain.c                   |  88 ++++-
 5 files changed, 455 insertions(+), 151 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/power/rockchip-io-domain.txt
 create mode 100644 Documentation/devicetree/bindings/power/rockchip-io-domain.yaml





From heiko at sntech.de  Sun Aug 22 03:16:12 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 22 Aug 2021 12:16:12 +0200
Subject: [GIT PULL] Rockchip dts32 changes for 5.14
Message-ID: <5824467.iIbC2pHGDl@phil>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v5.15-rockchip-dts32-1

for you to fetch changes up to 9d508827c7939242e8ed6b06f66aa87d9f7ea832:

  ARM: dts: rockchip: Add SFC to RV1108 (2021-08-18 23:48:35 +0200)

----------------------------------------------------------------
io-domains for rk3188 and rv1108, sfc (flash) support fpr rv1108
and some cleanups.

----------------------------------------------------------------
Chris Morgan (1):
      ARM: dts: rockchip: Add SFC to RV1108

Johan Jonker (6):
      ARM: dts: rockchip: rename pcfg_* nodenames for rk3066/rk3188
      ARM: dts: rockchip: add space after &grf on rk3188
      ARM: dts: rockchip: rename timer compatible strings for rk3066a
      ARM: dts: rockchip: remove interrupt-names from iommu nodes
      ARM: dts: rockchip: add io-domains node to rk3188.dtsi
      ARM: dts: rockchip: add io-domains nodes to rv1108.dtsi

 arch/arm/boot/dts/rk3066a.dtsi | 10 ++++-----
 arch/arm/boot/dts/rk3188.dtsi  | 13 +++++++----
 arch/arm/boot/dts/rk3288.dtsi  |  6 ------
 arch/arm/boot/dts/rv1108.dtsi  | 49 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 62 insertions(+), 16 deletions(-)





From heiko at sntech.de  Sun Aug 22 03:17:12 2021
From: heiko at sntech.de (heiko at sntech.de)
Date: Sun, 22 Aug 2021 12:17:12 +0200
Subject: [GIT PULL] Rockchip dts32 changes for 5.14
In-Reply-To: <5824467.iIbC2pHGDl@phil>
References: <5824467.iIbC2pHGDl@phil>
Message-ID: <5500960.5fSG56mABF@phil>

Hi,

Sorry, wrong subject
new mail coming up for clarity.

Heiko

Am Sonntag, 22. August 2021, 12:16:12 CEST schrieb Heiko Stuebner:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v5.15-rockchip-dts32-1
> 
> for you to fetch changes up to 9d508827c7939242e8ed6b06f66aa87d9f7ea832:
> 
>   ARM: dts: rockchip: Add SFC to RV1108 (2021-08-18 23:48:35 +0200)
> 
> ----------------------------------------------------------------
> io-domains for rk3188 and rv1108, sfc (flash) support fpr rv1108
> and some cleanups.
> 
> ----------------------------------------------------------------
> Chris Morgan (1):
>       ARM: dts: rockchip: Add SFC to RV1108
> 
> Johan Jonker (6):
>       ARM: dts: rockchip: rename pcfg_* nodenames for rk3066/rk3188
>       ARM: dts: rockchip: add space after &grf on rk3188
>       ARM: dts: rockchip: rename timer compatible strings for rk3066a
>       ARM: dts: rockchip: remove interrupt-names from iommu nodes
>       ARM: dts: rockchip: add io-domains node to rk3188.dtsi
>       ARM: dts: rockchip: add io-domains nodes to rv1108.dtsi
> 
>  arch/arm/boot/dts/rk3066a.dtsi | 10 ++++-----
>  arch/arm/boot/dts/rk3188.dtsi  | 13 +++++++----
>  arch/arm/boot/dts/rk3288.dtsi  |  6 ------
>  arch/arm/boot/dts/rv1108.dtsi  | 49 +++++++++++++++++++++++++++++++++++++++++-
>  4 files changed, 62 insertions(+), 16 deletions(-)
> 






From heiko at sntech.de  Sun Aug 22 03:17:36 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 22 Aug 2021 12:17:36 +0200
Subject: [GIT PULL] Rockchip dts32 changes for 5.15
Message-ID: <4142796.VLH7GnMWUR@phil>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v5.15-rockchip-dts32-1

for you to fetch changes up to 9d508827c7939242e8ed6b06f66aa87d9f7ea832:

  ARM: dts: rockchip: Add SFC to RV1108 (2021-08-18 23:48:35 +0200)

----------------------------------------------------------------
io-domains for rk3188 and rv1108, sfc (flash) support fpr rv1108
and some cleanups.

----------------------------------------------------------------
Chris Morgan (1):
      ARM: dts: rockchip: Add SFC to RV1108

Johan Jonker (6):
      ARM: dts: rockchip: rename pcfg_* nodenames for rk3066/rk3188
      ARM: dts: rockchip: add space after &grf on rk3188
      ARM: dts: rockchip: rename timer compatible strings for rk3066a
      ARM: dts: rockchip: remove interrupt-names from iommu nodes
      ARM: dts: rockchip: add io-domains node to rk3188.dtsi
      ARM: dts: rockchip: add io-domains nodes to rv1108.dtsi

 arch/arm/boot/dts/rk3066a.dtsi | 10 ++++-----
 arch/arm/boot/dts/rk3188.dtsi  | 13 +++++++----
 arch/arm/boot/dts/rk3288.dtsi  |  6 ------
 arch/arm/boot/dts/rv1108.dtsi  | 49 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 62 insertions(+), 16 deletions(-)





From heiko at sntech.de  Sun Aug 22 03:18:06 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 22 Aug 2021 12:18:06 +0200
Subject: [GIT PULL] Rockchip dts64 changes for 5.15
Message-ID: <4327460.usQuhbGJ8B@phil>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v5.15-rockchip-dts64-1

for you to fetch changes up to 9a35fd01f4abc3974e12539448038307acf27f16:

  arm64: dts: rockchip: add RK3399 Gru gpio-line-names (2021-08-21 18:18:50 +0200)

----------------------------------------------------------------
New boards: Firefly roc-rk3399-pc-pls and rk3328-pc; Scarlet-Dumo
tablet variant; Rock Pi 4 A+, B+; Pine64 Quartz64-A (rk3566-based)

Big additions for the rk3568: tsadc; saradc; gpio-support; gmac 1+2;
watchdog; pmu; io-domains and enabling these new things on the
rk3568-evb.

Addition of the rk3566 - a variant of the rk3568 with slightly less
peripherals.

SFC (serial flash controller) for rk3308 and px30 (including the
Odroid Go2)

Support for the rk3399's second image signal processor and vpu on px30
A number of smaller additions to multiple boards (Rock Pi 4, Pinebook Pro
and helios64) and cleanups in some parts.

----------------------------------------------------------------
Alex Bee (5):
      dt-bindings: Add doc for ROCK Pi 4 A+ and B+
      arm64: dts: rockchip: Add RK3399 ROCK Pi 4A+ board
      arm64: dts: rockchip: Add RK3399 ROCK Pi 4B+ board
      arm64: dts: rockchip: add ES8316 codec for ROCK Pi 4
      arm64: dts: rockchip: add SPDIF node for ROCK Pi 4

Brian Norris (1):
      arm64: dts: rockchip: add RK3399 Gru gpio-line-names

Chen-Yu Tsai (2):
      dt-bindings: arm: rockchip: Add gru-scarlet-dumo board
      arm64: dts: rockchip: Add gru-scarlet-dumo board

Chris Morgan (3):
      arm64: dts: rockchip: Add SFC to PX30
      arm64: dts: rockchip: Add SFC to RK3308
      arm64: dts: rockchip: Enable SFC for Odroid Go Advance

Dan Johansen (1):
      arm64: dts: rockchip: Setup USB typec port as datarole on for Pinebook Pro

Dennis Gilmore (3):
      arm64: dts: rockchip: set stdout-path on helios64
      arm64: dts: rockchip: add SPI support to helios64
      arm64: dts: rockchip: enable tsadc on helios64

Heiko Stuebner (4):
      arm64: dts: rockchip: add csi-dphy to px30
      arm64: dts: rockchip: add #phy-cells to mipi-dsi1 on rk3399
      arm64: dts: rockchip: add cif clk-control pinctrl for rk3399
      arm64: dts: rockchip: add isp1 node on rk3399

Johan Jonker (4):
      arm64: dts: rockchip: remove interrupt-names from iommu nodes
      arm64: dts: rockchip: rename flash nodenames
      arm64: dts: rockchip: remove clock_in_out from gmac2phy node in rk3318-a95x-z2.dts
      arm64: dts: rockchip: remove ddc-i2c-scl-* properties from rk3318-a95x-z2.dts

Levin Du (4):
      dt-bindings: add doc for Firefly ROC-RK3328-PC
      arm64: dts: rockchip: add support for Firefly ROC-RK3328-PC
      dt-bindings: add doc for Firefly ROC-RK3399-PC-PLUS
      arm64: dts: rockchip: add support for Firefly ROC-RK3399-PC-PLUS

Liang Chen (3):
      dt-bindings: arm: rockchip: add rk3568 compatible string to pmu.yaml
      arm64: dts: rockchip: add pmu and qos nodes for rk3568
      arm64: dts: rockchip: add watchdog to rk3568

Matthias Brugger (1):
      arm64: dts: rockchip: Disable CDN DP on Pinebook Pro

Michael Riesch (7):
      arm64: dts: rockchip: add gmac0 node to rk3568
      arm64: dts: rockchip: rk3568-evb1-v10: add ethernet support
      arm64: dts: rockchip: add core io domains node for rk356x
      arm64: dts: rockchip: enable io domains on rk3568-evb1-v10
      arm64: dts: rockchip: add regulators of rk809 pmic to rk3568-evb1-v10
      arm64: dts: rockchip: add node for sd card to rk3568-evb1-v10
      arm64: dts: rockchip: add pinctrl and alias to emmc node to rk3568-evb1-v10

Paul Kocialkowski (1):
      arm64: dts: rockchip: Add VPU support for the PX30

Peter Geis (12):
      arm64: dts: rockchip: move rk3568 dtsi to rk356x dtsi
      arm64: dts: rockchip: split rk3568 device tree
      arm64: dts: rockchip: add rk3566 dtsi
      arm64: dts: rockchip: add basic dts for Pine64 Quartz64-A
      arm64: dts: rockchip: fix rk3568 mbi-alias
      arm64: dts: rockchip: add rk356x gmac1 node
      arm64: dts: rockchip: adjust rk3568 pll clocks
      arm64: dts: rockchip: enable gmac node on quartz64-a
      arm64: dts: rockchip: add thermal fan control to rockpro64
      arm64: dts: rockchip: add rk356x gpio debounce clocks
      arm64: dts: rockchip: add rk3568 tsadc nodes
      arm64: dts: rockchip: add thermal support to Quartz64 Model A

Simon Xue (1):
      arm64: dts: rockchip: add saradc node for rk3568

 .../devicetree/bindings/arm/rockchip.yaml          |  48 +-
 .../devicetree/bindings/arm/rockchip/pmu.yaml      |   2 +
 arch/arm64/boot/dts/rockchip/Makefile              |   6 +
 arch/arm64/boot/dts/rockchip/px30.dtsi             |  73 ++
 arch/arm64/boot/dts/rockchip/rk3308.dtsi           |  37 +
 arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts    |   3 -
 arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts |  16 +
 arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts     | 110 +++
 arch/arm64/boot/dts/rockchip/rk3328-rock64.dts     |   2 +-
 arch/arm64/boot/dts/rockchip/rk3328.dtsi           |   5 -
 arch/arm64/boot/dts/rockchip/rk3368.dtsi           |   5 -
 .../boot/dts/rockchip/rk3399-gru-chromebook.dtsi   | 176 ++++
 .../boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts  |  41 +
 .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi      | 180 ++++
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi       |   2 +-
 .../boot/dts/rockchip/rk3399-kobol-helios64.dts    |  36 +
 .../boot/dts/rockchip/rk3399-pinebook-pro.dts      |   6 +-
 .../arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts | 218 +++++
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi |  54 ++
 .../boot/dts/rockchip/rk3399-rock-pi-4a-plus.dts   |  14 +
 .../boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts   |  47 ++
 arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi |  29 +
 arch/arm64/boot/dts/rockchip/rk3399.dtsi           |  47 +-
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 497 +++++++++++
 arch/arm64/boot/dts/rockchip/rk3566.dtsi           |  20 +
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts   | 308 +++++++
 arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi   |   9 +
 arch/arm64/boot/dts/rockchip/rk3568.dtsi           | 644 ++------------
 arch/arm64/boot/dts/rockchip/rk356x.dtsi           | 930 +++++++++++++++++++++
 29 files changed, 2966 insertions(+), 599 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-roc-pc.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a-plus.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk356x.dtsi





From f.fainelli at gmail.com  Sun Aug 22 03:30:02 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:30:02 +0200
Subject: [PATCH] dt-bindings: clock: brcm,iproc-clocks: fix armpll
 properties
In-Reply-To: <20210819052918.6753-1-zajec5@gmail.com>
References: <20210819052918.6753-1-zajec5@gmail.com>
Message-ID: <8b0c6b0c-b58b-816b-968b-97c71aced3c8@gmail.com>



On 8/19/2021 7:29 AM, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> armpll clocks (available on Cygnus and Northstar Plus) are simple clocks
> with no cells. Adjust binding props #clock-cells and clock-output-names
> to handle them.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Acked-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From f.fainelli at gmail.com  Sun Aug 22 03:31:58 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:31:58 +0200
Subject: [PATCH V2 00/10] ARM: dts: Add Raspberry Pi CM4 & CM4 IO Board
 support
In-Reply-To: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <fb80f7a5-8fd4-73e3-4c64-77f120546cc4@gmail.com>



On 8/7/2021 1:06 PM, Stefan Wahren wrote:
> This series add support for the Raspberry Pi Compute Module 4 and its
> IO board.
> 
> Changes in V2:
> - drop emmc2bus patch as it affects userspace (thanks to Marc Zyngier)
> - tested with CM4 and integrate sdhci patches from Nicolas (just include kHz fixups)
> - add Rob's Acked-by
> - add HS200 property to emmc2 node for a slight performance gain
> - move antenna comment to the proper position

Nicolas, I am assuming you will be picking up these patches and submit a 
BCM283x pull request with them. Thanks!

> 
> Nicolas Saenz Julienne (2):
>    mmc: sdhci-iproc: Cap min clock frequency on BCM2711
>    mmc: sdhci-iproc: Set SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711
> 
> Stefan Wahren (8):
>    ARM: dts: bcm2711: fix MDIO #address- and #size-cells
>    ARM: dts: bcm2711-rpi-4-b: fix sd_io_1v8_reg regulator states
>    dt-bindings: display: bcm2835: add optional property power-domains
>    ARM: dts: bcm283x-rpi: Move Wifi/BT into separate dtsi
>    dt-bindings: arm: bcm2835: Add Raspberry Pi Compute Module 4
>    ARM: dts: Add Raspberry Pi Compute Module 4
>    ARM: dts: Add Raspberry Pi Compute Module 4 IO Board
>    arm64: dts: broadcom: Add reference to RPi CM4 IO Board
> 
>   .../devicetree/bindings/arm/bcm/bcm2835.yaml       |   1 +
>   .../bindings/display/brcm,bcm2835-dsi0.yaml        |   3 +
>   .../bindings/display/brcm,bcm2835-hdmi.yaml        |   3 +
>   .../bindings/display/brcm,bcm2835-v3d.yaml         |   3 +
>   .../bindings/display/brcm,bcm2835-vec.yaml         |   3 +
>   arch/arm/boot/dts/Makefile                         |   1 +
>   arch/arm/boot/dts/bcm2711-rpi-4-b.dts              |  42 ++-----
>   arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts           | 138 +++++++++++++++++++++
>   arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi             | 113 +++++++++++++++++
>   arch/arm/boot/dts/bcm2711.dtsi                     |   4 +-
>   arch/arm/boot/dts/bcm2835-rpi-zero-w.dts           |  31 ++---
>   arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts         |  36 ++----
>   arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts         |  36 ++----
>   arch/arm/boot/dts/bcm2837-rpi-3-b.dts              |  36 ++----
>   arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi         |  34 +++++
>   arch/arm64/boot/dts/broadcom/Makefile              |   1 +
>   .../arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts |   2 +
>   drivers/mmc/host/sdhci-iproc.c                     |  21 +++-
>   18 files changed, 366 insertions(+), 142 deletions(-)
>   create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>   create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4.dtsi
>   create mode 100644 arch/arm/boot/dts/bcm283x-rpi-wifi-bt.dtsi
>   create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
> 

-- 
Florian


From f.fainelli at gmail.com  Sun Aug 22 03:34:14 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:34:14 +0200
Subject: [PATCH] dt-bindings: mfd: add Broadcom's MISC block
In-Reply-To: <20210819152552.23784-1-zajec5@gmail.com>
References: <20210819152552.23784-1-zajec5@gmail.com>
Message-ID: <b4647c69-6727-79c4-7881-938ec19841ce@gmail.com>



On 8/19/2021 5:25 PM, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Broadcom's MISC is an MFD hardware block used on some of their SoCs like
> bcm63xx and bcm4908. At this point only PCIe reset is fully understood
> and documented. More functions may be added later.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Acked-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From paul at crapouillou.net  Sun Aug 22 04:16:29 2021
From: paul at crapouillou.net (Paul Cercueil)
Date: Sun, 22 Aug 2021 12:16:29 +0100
Subject: [PATCH 1/3] serial: 8250_ingenic: Use of_device_get_match_data
In-Reply-To: <20210822032806.3256-2-tangbin@cmss.chinamobile.com>
References: <20210822032806.3256-1-tangbin@cmss.chinamobile.com>
 <20210822032806.3256-2-tangbin@cmss.chinamobile.com>
Message-ID: <HBN8YQ.GODLCGECPCT01@crapouillou.net>

Hi,

Le dim., ao?t 22 2021 at 11:28:04 +0800, Tang Bin 
<tangbin at cmss.chinamobile.com> a ?crit :
> Retrieve OF match data, it's better and cleaner to use
> 'of_device_get_match_data' over 'of_match_device'.
> 
> Signed-off-by: Zhang Shengju <zhangshengju at cmss.chinamobile.com>
> Signed-off-by: Tang Bin <tangbin at cmss.chinamobile.com>

Acked-by: Paul Cercueil <paul at crapouillou.net>

Cheers,
-Paul

> ---
>  drivers/tty/serial/8250/8250_ingenic.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/8250_ingenic.c 
> b/drivers/tty/serial/8250/8250_ingenic.c
> index 988bf6bcc..65402d05e 100644
> --- a/drivers/tty/serial/8250/8250_ingenic.c
> +++ b/drivers/tty/serial/8250/8250_ingenic.c
> @@ -209,16 +209,14 @@ static int ingenic_uart_probe(struct 
> platform_device *pdev)
>  	struct uart_8250_port uart = {};
>  	struct ingenic_uart_data *data;
>  	const struct ingenic_uart_config *cdata;
> -	const struct of_device_id *match;
>  	struct resource *regs;
>  	int irq, err, line;
> 
> -	match = of_match_device(of_match, &pdev->dev);
> -	if (!match) {
> +	cdata = of_device_get_match_data(&pdev->dev);
> +	if (!cdata) {
>  		dev_err(&pdev->dev, "Error: No device match found\n");
>  		return -ENODEV;
>  	}
> -	cdata = match->data;
> 
>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0)
> --
> 2.20.1.windows.1
> 
> 
> 




From f.fainelli at gmail.com  Sun Aug 22 04:31:38 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 13:31:38 +0200
Subject: [PATCH 0/5] arm64: Survival kit for SCR_EL3.HCE==0 conditions
In-Reply-To: <874kbr12in.wl-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
 <7ffa35bb-1f2c-19ff-fe4b-33267fba80e8@gmail.com>
 <874kbr12in.wl-maz@kernel.org>
Message-ID: <0d3de5dd-f85c-d6d6-2c1b-1248847c0a09@gmail.com>



On 8/15/2021 11:27 AM, Marc Zyngier wrote:
> On Sun, 15 Aug 2021 08:28:47 +0100,
> Florian Fainelli <f.fainelli at gmail.com> wrote:
>>
>>
>>
>> On 8/12/2021 9:02 PM, Marc Zyngier wrote:
>>> Anyone vaguely familiar with the ARMv8 architecture would quickly
>>> understand that entering the kernel at EL2 without enabling the HVC
>>> instruction is... living dangerously. But as it turns out [0], there
>>> is a whole range of (*cough*) "high quality" (*cough*) Broadcom
>>> systems out there configured exactly like that.
>>
>> Some Broadcom systems, namely the 4908 and all of those using CFE,
>> they later switched to u-boot and ATF and got it right.
> 
> Do we have a list of the affected systems?

That is going to be hard to come up with given that OEMs such as Asus, 
TP-Link, or Netgear and multiple devices are affected. I would start 
with this list which is far from exhaustive: Netgear R8000P, TP-Link 
Archer C2300, Asus GT AC5300.

> 
>>
>>>
>>> If you are speechless, I'm right with you.
>>>
>>> These machines have stopped being able to boot an upstream kernel
>>> since 5.12, where we changed the way we switch from nVHE to VHE, as
>>> this relies on the HVC instruction being usable... It is also worth
>>> noting that these systems have never been able to use KVM. Or kexec.
>>>
>>> This small series addresses the issue by detecting an UNDEFing HVC in
>>> a fairly controlled environment, and in this case pretend that we have
>>> booted at EL1. It also documents the requirement for SCR_EL3.HCE to be
>>> set to *1* if the kernel is entered at EL2. Turns out that we really
>>> have to state the obvious.
>>>
>>> This has been tested on a FVP model with a hacked-up boot-wrapper.
>>>
>>> Note that I really don't think any of this is -stable material, except
>>> maybe for the documentation. It isn't 5.14 material either. Best case,
>>> this is 5.15, or maybe even later. If ever.
>>
>> While I am very appreciative of the work you have done here to try to
>> get the dysfunctional systems to warn and continue to boot, I would
>> rather we try to load a minimal shim at EL3 capable of fixing up any
>> incorrect EL3 register setting ahead of loading the kernel provided
>> this is possible at all on a commercially available system.
> 
> That would be the best thing to do, and would make the machine fully
> usable. I still think we need to have something in the kernel to at
> least let the user know that their system is misconfigured though.
> 
> If CFE allows a payload to be loaded at EL3 and executed on all CPUs,
> that would be absolutely awesome. It would even allow switching over
> to ATF...

Supposedly there are GPL tarballs containing an u-boot that is suitable 
for the 4908, however I have no idea where to find those. In premise you 
could chainload those to CFE and a get seemingly functional system.
-- 
Florian


From knaerzche at gmail.com  Sun Aug 22 04:57:55 2021
From: knaerzche at gmail.com (Alex Bee)
Date: Sun, 22 Aug 2021 13:57:55 +0200
Subject: [PATCH] arm64: dts: rockchip: Re-add interrupt-names for RK3399's vpu
Message-ID: <20210822115755.3171937-1-knaerzche@gmail.com>

Commit a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
intended to remove the interrupt-names property for mmu nodes, but it
also removed it for the vpu node in rk3399.dtsi. That makes the driver
fail probing currently.
Fix this by re-adding the property for this node.

Fixes: a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
Signed-off-by: Alex Bee <knaerzche at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 9db9484ca38f..44def886b391 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1240,6 +1240,7 @@ vpu: video-codec at ff650000 {
 		reg = <0x0 0xff650000 0x0 0x800>;
 		interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "vepu", "vdpu";
 		clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>;
 		clock-names = "aclk", "hclk";
 		iommus = <&vpu_mmu>;

base-commit: 5936c9eb785b46fdc5563d1c5c34b5558e3fa156
-- 
2.30.2



From bilbao at vt.edu  Sun Aug 22 06:15:50 2021
From: bilbao at vt.edu (Carlos Bilbao)
Date: Sun, 22 Aug 2021 09:15:50 -0400
Subject: [PATCH v4.1] include: linux: Reorganize timekeeping and ktime headers
In-Reply-To: <b5d4536f-a096-b259-1385-3c1d32754dbf@vt.edu>
References: <b5d4536f-a096-b259-1385-3c1d32754dbf@vt.edu>
Message-ID: <095645cd-ce53-a803-cb99-522545a409b8@vt.edu>

Reorganize and separate the headers by making ktime.h take care of the 
ktime_get() family of functions, and reserve timekeeping.h for the actual 
timekeeping. This also helps to avoid implicit function errors and strengthens
the header dependencies, since timekeeping.h was using ktime_to_ns(), a static 
function defined in a header it does no include, ktime.h. Include the header 
timekeeping.h wherever it is necessary for a successful compilation after the 
header code reorganization.

Signed-off-by: Carlos Bilbao <bilbao at vt.edu>
Acked-by: Geert Uytterhoeven <geert at linux-m68k.org>
Reported-by: kernel test robot <lkp at intel.com>
---
Changelog:
- v2: Add three more files that also needed a header update for x86: 
  pps_kernel.h, posix-timers.c and hda_controller.c
- v3: Cover build tests for other architectures than x86. To compile arm64, 
  update arch/arm64/kvm/hypercalls.c, include/linux/stmmac.h, and 
  drivers/rtc/class.c. No other arch/ seems to need fixes but to be on the safe
  side compiled arm, mips, powerpc, sparc, s390, riscv and i386.
- v4: 4.0 Fix kernel test robot warnings for ia64 and x86.
      4.1 Fix kernel test robot warnings for m68k and powerpc.
---
 arch/arm64/kvm/hypercalls.c    |   1 +
 arch/ia64/kernel/time.c        |   1 +
 arch/m68k/atari/time.c         |   1 +
 arch/m68k/hp300/time.c         |   2 +
 arch/m68k/mac/via.c            |   1 +
 arch/m68k/mvme16x/config.c     |   1 +
 arch/m68k/sun3/sun3ints.c      |   1 +
 arch/powerpc/kernel/time.c     |   1 +
 arch/x86/kernel/rtc.c          |   1 +
 arch/x86/kernel/tsc.c          |   1 +
 drivers/rtc/class.c            |   1 +
 include/linux/ktime.h          | 196 +++++++++++++++++++++++++++++++-
 include/linux/pps_kernel.h     |   1 +
 include/linux/sched_clock.h    |   2 +
 include/linux/stmmac.h         |   1 +
 include/linux/timekeeping.h    | 197 +--------------------------------
 init/main.c                    |   1 +
 kernel/time/ntp.c              |   1 +
 kernel/time/posix-timers.c     |   1 +
 kernel/time/tick-legacy.c      |   1 +
 kernel/time/time.c             |   1 +
 kernel/time/timekeeping.c      |   1 +
 sound/pci/hda/hda_controller.c |   1 +
 23 files changed, 218 insertions(+), 198 deletions(-)

diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 30da78f72b3b..41499c1d7379 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -3,6 +3,7 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/kvm_host.h>
+#include <linux/timekeeping.h>
 
 #include <asm/kvm_emulate.h>
 
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index fa9c0ab8c6fc..85e79ff3c98e 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/efi.h>
 #include <linux/timex.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/platform_device.h>
 #include <linux/sched/cputime.h>
 
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 7e44d0e9d0f8..b09d3ff40b36 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -19,6 +19,7 @@
 #include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/timekeeping.h>
 
 #include <asm/atariints.h>
 #include <asm/machdep.h>
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index 1d1b7b3b5dd4..56c575096bcb 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -14,6 +14,8 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
+
 #include <asm/machdep.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 3d11d6219cdd..6dd8f85288e4 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/irq.h>
+#include <linux/timekeeping.h>
 
 #include <asm/macintosh.h>
 #include <asm/macints.h>
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index b59593c7cfb9..bb2ae926bb17 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -28,6 +28,7 @@
 #include <linux/rtc.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/timekeeping.h>
 
 #include <asm/bootinfo.h>
 #include <asm/bootinfo-vme.h>
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 41ae422119d3..3834a172be47 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
 #include <asm/segment.h>
 #include <asm/intersil.h>
 #include <asm/oplib.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index e45ce427bffb..4b6952165a0a 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -55,6 +55,7 @@
 #include <linux/sched/cputime.h>
 #include <linux/sched/clock.h>
 #include <linux/processor.h>
+#include <linux/timekeeping.h>
 #include <asm/trace.h>
 
 #include <asm/interrupt.h>
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 586f718b8e95..98ea05cc6aeb 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -9,6 +9,7 @@
 #include <linux/export.h>
 #include <linux/pnp.h>
 #include <linux/of.h>
+#include <linux/timekeeping.h>
 
 #include <asm/vsyscall.h>
 #include <asm/x86_init.h>
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 2e076a459a0c..b730cb20f5fd 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -15,6 +15,7 @@
 #include <linux/timex.h>
 #include <linux/static_key.h>
 #include <linux/static_call.h>
+#include <linux/timekeeping.h>
 
 #include <asm/hpet.h>
 #include <asm/timer.h>
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index f77bc089eb6b..1bdf1f790beb 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 #include <linux/workqueue.h>
 
 #include "rtc-core.h"
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 73f20deb497d..37955d6664dd 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -229,6 +229,198 @@ static inline ktime_t ms_to_ktime(u64 ms)
 	return ms * NSEC_PER_MSEC;
 }
 
-# include <linux/timekeeping.h>
+/*
+ * ktime_get() family: read the current time in a multitude of ways,
+ *
+ * The default time reference is CLOCK_MONOTONIC, starting at
+ * boot time but not counting the time spent in suspend.
+ * For other references, use the functions with "real", "clocktai",
+ * "boottime" and "raw" suffixes.
+ *
+ * To get the time in a different format, use the ones wit
+ * "ns", "ts64" and "seconds" suffix.
+ *
+ * See Documentation/core-api/timekeeping.rst for more details.
+ */
 
-#endif
+
+/*
+ * timespec64 based interfaces
+ */
+extern void ktime_get_raw_ts64(struct timespec64 *ts);
+extern void ktime_get_ts64(struct timespec64 *ts);
+extern void ktime_get_real_ts64(struct timespec64 *tv);
+extern void ktime_get_coarse_ts64(struct timespec64 *ts);
+extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
+
+void getboottime64(struct timespec64 *ts);
+
+/*
+ * time64_t base interfaces
+ */
+extern time64_t ktime_get_seconds(void);
+extern time64_t __ktime_get_real_seconds(void);
+extern time64_t ktime_get_real_seconds(void);
+
+/*
+ * ktime_t based interfaces
+ */
+
+enum tk_offsets {
+       TK_OFFS_REAL,
+       TK_OFFS_BOOT,
+       TK_OFFS_TAI,
+       TK_OFFS_MAX,
+};
+
+extern ktime_t ktime_get(void);
+extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
+extern ktime_t ktime_get_raw(void);
+extern u32 ktime_get_resolution_ns(void);
+
+/**
+ * ktime_get_real - get the real (wall-) time in ktime_t format
+ */
+static inline ktime_t ktime_get_real(void)
+{
+       return ktime_get_with_offset(TK_OFFS_REAL);
+}
+
+static inline ktime_t ktime_get_coarse_real(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_REAL);
+}
+
+/**
+ * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
+ *
+ * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
+ * time spent in suspend.
+ */
+static inline ktime_t ktime_get_boottime(void)
+{
+       return ktime_get_with_offset(TK_OFFS_BOOT);
+}
+
+static inline ktime_t ktime_get_coarse_boottime(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
+}
+
+/**
+ * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
+ */
+static inline ktime_t ktime_get_clocktai(void)
+{
+       return ktime_get_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse_clocktai(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse(void)
+{
+       struct timespec64 ts;
+
+       ktime_get_coarse_ts64(&ts);
+       return timespec64_to_ktime(ts);
+}
+
+static inline u64 ktime_get_coarse_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse());
+}
+
+static inline u64 ktime_get_coarse_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_real());
+}
+
+static inline u64 ktime_get_coarse_boottime_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_boottime());
+}
+
+static inline u64 ktime_get_coarse_clocktai_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_clocktai());
+}
+
+/**
+ * ktime_mono_to_real - Convert monotonic time to clock realtime
+ */
+static inline ktime_t ktime_mono_to_real(ktime_t mono)
+{
+       return ktime_mono_to_any(mono, TK_OFFS_REAL);
+}
+
+static inline u64 ktime_get_ns(void)
+{
+       return ktime_to_ns(ktime_get());
+}
+
+static inline u64 ktime_get_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_real());
+}
+
+static inline u64 ktime_get_boottime_ns(void)
+{
+       return ktime_to_ns(ktime_get_boottime());
+}
+
+static inline u64 ktime_get_clocktai_ns(void)
+{
+       return ktime_to_ns(ktime_get_clocktai());
+}
+
+static inline u64 ktime_get_raw_ns(void)
+{
+       return ktime_to_ns(ktime_get_raw());
+}
+
+extern u64 ktime_get_mono_fast_ns(void);
+extern u64 ktime_get_raw_fast_ns(void);
+extern u64 ktime_get_boot_fast_ns(void);
+extern u64 ktime_get_real_fast_ns(void);
+
+/*
+ * timespec64/time64_t interfaces utilizing the ktime based ones
+ * for API completeness, these could be implemented more efficiently
+ * if needed.
+ */
+static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_boottime());
+}
+
+static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_coarse_boottime());
+}
+
+static inline time64_t ktime_get_boottime_seconds(void)
+{
+       return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
+}
+
+static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_clocktai());
+}
+
+static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
+}
+
+static inline time64_t ktime_get_clocktai_seconds(void)
+{
+       return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
+}
+
+#endif /* _LINUX_KTIME_H */
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h
index 78c8ac4951b5..24970c202ac6 100644
--- a/include/linux/pps_kernel.h
+++ b/include/linux/pps_kernel.h
@@ -12,6 +12,7 @@
 #include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 
 /*
  * Global defines
diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h
index 835ee87ed792..f0fa287710da 100644
--- a/include/linux/sched_clock.h
+++ b/include/linux/sched_clock.h
@@ -5,6 +5,8 @@
 #ifndef LINUX_SCHED_CLOCK
 #define LINUX_SCHED_CLOCK
 
+#include <linux/timekeeping.h>
+
 #ifdef CONFIG_GENERIC_SCHED_CLOCK
 /**
  * struct clock_read_data - data required to read from sched_clock()
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..bf235ff101d5 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -14,6 +14,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/timekeeping.h>
 
 #define MTL_MAX_RX_QUEUES	8
 #define MTL_MAX_TX_QUEUES	8
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 78a98bdff76d..b1c54f5ff91e 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -19,201 +19,6 @@ extern void legacy_timer_tick(unsigned long ticks);
 extern int do_settimeofday64(const struct timespec64 *ts);
 extern int do_sys_settimeofday64(const struct timespec64 *tv,
 				 const struct timezone *tz);
-
-/*
- * ktime_get() family: read the current time in a multitude of ways,
- *
- * The default time reference is CLOCK_MONOTONIC, starting at
- * boot time but not counting the time spent in suspend.
- * For other references, use the functions with "real", "clocktai",
- * "boottime" and "raw" suffixes.
- *
- * To get the time in a different format, use the ones wit
- * "ns", "ts64" and "seconds" suffix.
- *
- * See Documentation/core-api/timekeeping.rst for more details.
- */
-
-
-/*
- * timespec64 based interfaces
- */
-extern void ktime_get_raw_ts64(struct timespec64 *ts);
-extern void ktime_get_ts64(struct timespec64 *ts);
-extern void ktime_get_real_ts64(struct timespec64 *tv);
-extern void ktime_get_coarse_ts64(struct timespec64 *ts);
-extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
-
-void getboottime64(struct timespec64 *ts);
-
-/*
- * time64_t base interfaces
- */
-extern time64_t ktime_get_seconds(void);
-extern time64_t __ktime_get_real_seconds(void);
-extern time64_t ktime_get_real_seconds(void);
-
-/*
- * ktime_t based interfaces
- */
-
-enum tk_offsets {
-	TK_OFFS_REAL,
-	TK_OFFS_BOOT,
-	TK_OFFS_TAI,
-	TK_OFFS_MAX,
-};
-
-extern ktime_t ktime_get(void);
-extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
-extern ktime_t ktime_get_raw(void);
-extern u32 ktime_get_resolution_ns(void);
-
-/**
- * ktime_get_real - get the real (wall-) time in ktime_t format
- */
-static inline ktime_t ktime_get_real(void)
-{
-	return ktime_get_with_offset(TK_OFFS_REAL);
-}
-
-static inline ktime_t ktime_get_coarse_real(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_REAL);
-}
-
-/**
- * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
- *
- * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
- * time spent in suspend.
- */
-static inline ktime_t ktime_get_boottime(void)
-{
-	return ktime_get_with_offset(TK_OFFS_BOOT);
-}
-
-static inline ktime_t ktime_get_coarse_boottime(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
-}
-
-/**
- * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
- */
-static inline ktime_t ktime_get_clocktai(void)
-{
-	return ktime_get_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse_clocktai(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse(void)
-{
-	struct timespec64 ts;
-
-	ktime_get_coarse_ts64(&ts);
-	return timespec64_to_ktime(ts);
-}
-
-static inline u64 ktime_get_coarse_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse());
-}
-
-static inline u64 ktime_get_coarse_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_real());
-}
-
-static inline u64 ktime_get_coarse_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_boottime());
-}
-
-static inline u64 ktime_get_coarse_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_clocktai());
-}
-
-/**
- * ktime_mono_to_real - Convert monotonic time to clock realtime
- */
-static inline ktime_t ktime_mono_to_real(ktime_t mono)
-{
-	return ktime_mono_to_any(mono, TK_OFFS_REAL);
-}
-
-static inline u64 ktime_get_ns(void)
-{
-	return ktime_to_ns(ktime_get());
-}
-
-static inline u64 ktime_get_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_real());
-}
-
-static inline u64 ktime_get_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_boottime());
-}
-
-static inline u64 ktime_get_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_clocktai());
-}
-
-static inline u64 ktime_get_raw_ns(void)
-{
-	return ktime_to_ns(ktime_get_raw());
-}
-
-extern u64 ktime_get_mono_fast_ns(void);
-extern u64 ktime_get_raw_fast_ns(void);
-extern u64 ktime_get_boot_fast_ns(void);
-extern u64 ktime_get_real_fast_ns(void);
-
-/*
- * timespec64/time64_t interfaces utilizing the ktime based ones
- * for API completeness, these could be implemented more efficiently
- * if needed.
- */
-static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_boottime());
-}
-
-static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_boottime());
-}
-
-static inline time64_t ktime_get_boottime_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
-}
-
-static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_clocktai());
-}
-
-static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
-}
-
-static inline time64_t ktime_get_clocktai_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
-}
-
 /*
  * RTC specific
  */
@@ -308,4 +113,4 @@ void read_persistent_wall_and_boot_offset(struct timespec64 *wall_clock,
 extern int update_persistent_clock64(struct timespec64 now);
 #endif
 
-#endif
+#endif /* _LINUX_TIMEKEEPING_H */
diff --git a/init/main.c b/init/main.c
index f5b8246e8aa1..a8db3a136d6a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -100,6 +100,7 @@
 #include <linux/kcsan.h>
 #include <linux/init_syscalls.h>
 #include <linux/stackdepot.h>
+#include <linux/timekeeping.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 406dccb79c2b..804f06801737 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "ntp_internal.h"
 #include "timekeeping_internal.h"
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index dd5697d7347b..14f82cd95d10 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 #include <linux/mutex.h>
 #include <linux/sched/task.h>
 
diff --git a/kernel/time/tick-legacy.c b/kernel/time/tick-legacy.c
index af225b32f5b3..9a534f716462 100644
--- a/kernel/time/tick-legacy.c
+++ b/kernel/time/tick-legacy.c
@@ -7,6 +7,7 @@
 #include <linux/irq.h>
 #include <linux/profile.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 29923b20e0e4..7292ed074742 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -29,6 +29,7 @@
 #include <linux/timex.h>
 #include <linux/capability.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/errno.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8a364aa9881a..4dfee925adc8 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -22,6 +22,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index ca2f2ecd1488..efbbe624d81d 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 
 #ifdef CONFIG_X86
 /* for art-tsc conversion */
-- 
2.25.1


From gregkh at linuxfoundation.org  Sun Aug 22 06:23:35 2021
From: gregkh at linuxfoundation.org (Greg KH)
Date: Sun, 22 Aug 2021 15:23:35 +0200
Subject: [PATCH v4.1] include: linux: Reorganize timekeeping and ktime
 headers
In-Reply-To: <095645cd-ce53-a803-cb99-522545a409b8@vt.edu>
References: <b5d4536f-a096-b259-1385-3c1d32754dbf@vt.edu>
 <095645cd-ce53-a803-cb99-522545a409b8@vt.edu>
Message-ID: <YSJP18Z72t0X+xsp@kroah.com>

On Sun, Aug 22, 2021 at 09:15:50AM -0400, Carlos Bilbao wrote:
> - v4: 4.0 Fix kernel test robot warnings for ia64 and x86.
>       4.1 Fix kernel test robot warnings for m68k and powerpc.

Please just use whole numbers for patch versions, there's no need for .X
for this type of thing as our tools do not know how to catch that, and
it makes no sense.

Just keep bumping the number please.

greg k-h


From bilbao at vt.edu  Sun Aug 22 06:27:26 2021
From: bilbao at vt.edu (Carlos Bilbao)
Date: Sun, 22 Aug 2021 09:27:26 -0400
Subject: [PATCH v5] include: linux: Reorganize timekeeping and ktime headers
In-Reply-To: <YSJP18Z72t0X+xsp@kroah.com>
References: <b5d4536f-a096-b259-1385-3c1d32754dbf@vt.edu>
 <095645cd-ce53-a803-cb99-522545a409b8@vt.edu> <YSJP18Z72t0X+xsp@kroah.com>
Message-ID: <1c156aca-d0ad-e7e8-2238-5c3d904d171c@vt.edu>

Reorganize and separate the headers by making ktime.h take care of the 
ktime_get() family of functions, and reserve timekeeping.h for the actual 
timekeeping. This also helps to avoid implicit function errors and strengthens
the header dependencies, since timekeeping.h was using ktime_to_ns(), a static 
function defined in a header it does no include, ktime.h. Include the header 
timekeeping.h wherever it is necessary for a successful compilation after the 
header code reorganization.

Signed-off-by: Carlos Bilbao <bilbao at vt.edu>
Acked-by: Geert Uytterhoeven <geert at linux-m68k.org>
Reported-by: kernel test robot <lkp at intel.com>
---
Changelog:
- v2: Add three more files that also needed a header update for x86: 
  pps_kernel.h, posix-timers.c and hda_controller.c
- v3: Cover build tests for other architectures than x86. To compile arm64, 
  update arch/arm64/kvm/hypercalls.c, include/linux/stmmac.h, and 
  drivers/rtc/class.c. No other arch/ seems to need fixes but to be on the safe
  side compiled arm, mips, powerpc, sparc, s390, riscv and i386.
- v4: Fix kernel test robot warnings for ia64 and x86.
- v5: Fix kernel test robot warnings for m68k and powerpc.
---
 arch/arm64/kvm/hypercalls.c    |   1 +
 arch/ia64/kernel/time.c        |   1 +
 arch/m68k/atari/time.c         |   1 +
 arch/m68k/hp300/time.c         |   2 +
 arch/m68k/mac/via.c            |   1 +
 arch/m68k/mvme16x/config.c     |   1 +
 arch/m68k/sun3/sun3ints.c      |   1 +
 arch/powerpc/kernel/time.c     |   1 +
 arch/x86/kernel/rtc.c          |   1 +
 arch/x86/kernel/tsc.c          |   1 +
 drivers/rtc/class.c            |   1 +
 include/linux/ktime.h          | 196 +++++++++++++++++++++++++++++++-
 include/linux/pps_kernel.h     |   1 +
 include/linux/sched_clock.h    |   2 +
 include/linux/stmmac.h         |   1 +
 include/linux/timekeeping.h    | 197 +--------------------------------
 init/main.c                    |   1 +
 kernel/time/ntp.c              |   1 +
 kernel/time/posix-timers.c     |   1 +
 kernel/time/tick-legacy.c      |   1 +
 kernel/time/time.c             |   1 +
 kernel/time/timekeeping.c      |   1 +
 sound/pci/hda/hda_controller.c |   1 +
 23 files changed, 218 insertions(+), 198 deletions(-)

diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 30da78f72b3b..41499c1d7379 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -3,6 +3,7 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/kvm_host.h>
+#include <linux/timekeeping.h>
 
 #include <asm/kvm_emulate.h>
 
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index fa9c0ab8c6fc..85e79ff3c98e 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/efi.h>
 #include <linux/timex.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/platform_device.h>
 #include <linux/sched/cputime.h>
 
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 7e44d0e9d0f8..b09d3ff40b36 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -19,6 +19,7 @@
 #include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/timekeeping.h>
 
 #include <asm/atariints.h>
 #include <asm/machdep.h>
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index 1d1b7b3b5dd4..56c575096bcb 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -14,6 +14,8 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
+
 #include <asm/machdep.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 3d11d6219cdd..6dd8f85288e4 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/irq.h>
+#include <linux/timekeeping.h>
 
 #include <asm/macintosh.h>
 #include <asm/macints.h>
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index b59593c7cfb9..bb2ae926bb17 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -28,6 +28,7 @@
 #include <linux/rtc.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/timekeeping.h>
 
 #include <asm/bootinfo.h>
 #include <asm/bootinfo-vme.h>
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 41ae422119d3..3834a172be47 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
 #include <asm/segment.h>
 #include <asm/intersil.h>
 #include <asm/oplib.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index e45ce427bffb..4b6952165a0a 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -55,6 +55,7 @@
 #include <linux/sched/cputime.h>
 #include <linux/sched/clock.h>
 #include <linux/processor.h>
+#include <linux/timekeeping.h>
 #include <asm/trace.h>
 
 #include <asm/interrupt.h>
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 586f718b8e95..98ea05cc6aeb 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -9,6 +9,7 @@
 #include <linux/export.h>
 #include <linux/pnp.h>
 #include <linux/of.h>
+#include <linux/timekeeping.h>
 
 #include <asm/vsyscall.h>
 #include <asm/x86_init.h>
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 2e076a459a0c..b730cb20f5fd 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -15,6 +15,7 @@
 #include <linux/timex.h>
 #include <linux/static_key.h>
 #include <linux/static_call.h>
+#include <linux/timekeeping.h>
 
 #include <asm/hpet.h>
 #include <asm/timer.h>
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index f77bc089eb6b..1bdf1f790beb 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 #include <linux/workqueue.h>
 
 #include "rtc-core.h"
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 73f20deb497d..37955d6664dd 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -229,6 +229,198 @@ static inline ktime_t ms_to_ktime(u64 ms)
 	return ms * NSEC_PER_MSEC;
 }
 
-# include <linux/timekeeping.h>
+/*
+ * ktime_get() family: read the current time in a multitude of ways,
+ *
+ * The default time reference is CLOCK_MONOTONIC, starting at
+ * boot time but not counting the time spent in suspend.
+ * For other references, use the functions with "real", "clocktai",
+ * "boottime" and "raw" suffixes.
+ *
+ * To get the time in a different format, use the ones wit
+ * "ns", "ts64" and "seconds" suffix.
+ *
+ * See Documentation/core-api/timekeeping.rst for more details.
+ */
 
-#endif
+
+/*
+ * timespec64 based interfaces
+ */
+extern void ktime_get_raw_ts64(struct timespec64 *ts);
+extern void ktime_get_ts64(struct timespec64 *ts);
+extern void ktime_get_real_ts64(struct timespec64 *tv);
+extern void ktime_get_coarse_ts64(struct timespec64 *ts);
+extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
+
+void getboottime64(struct timespec64 *ts);
+
+/*
+ * time64_t base interfaces
+ */
+extern time64_t ktime_get_seconds(void);
+extern time64_t __ktime_get_real_seconds(void);
+extern time64_t ktime_get_real_seconds(void);
+
+/*
+ * ktime_t based interfaces
+ */
+
+enum tk_offsets {
+       TK_OFFS_REAL,
+       TK_OFFS_BOOT,
+       TK_OFFS_TAI,
+       TK_OFFS_MAX,
+};
+
+extern ktime_t ktime_get(void);
+extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
+extern ktime_t ktime_get_raw(void);
+extern u32 ktime_get_resolution_ns(void);
+
+/**
+ * ktime_get_real - get the real (wall-) time in ktime_t format
+ */
+static inline ktime_t ktime_get_real(void)
+{
+       return ktime_get_with_offset(TK_OFFS_REAL);
+}
+
+static inline ktime_t ktime_get_coarse_real(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_REAL);
+}
+
+/**
+ * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
+ *
+ * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
+ * time spent in suspend.
+ */
+static inline ktime_t ktime_get_boottime(void)
+{
+       return ktime_get_with_offset(TK_OFFS_BOOT);
+}
+
+static inline ktime_t ktime_get_coarse_boottime(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
+}
+
+/**
+ * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
+ */
+static inline ktime_t ktime_get_clocktai(void)
+{
+       return ktime_get_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse_clocktai(void)
+{
+       return ktime_get_coarse_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse(void)
+{
+       struct timespec64 ts;
+
+       ktime_get_coarse_ts64(&ts);
+       return timespec64_to_ktime(ts);
+}
+
+static inline u64 ktime_get_coarse_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse());
+}
+
+static inline u64 ktime_get_coarse_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_real());
+}
+
+static inline u64 ktime_get_coarse_boottime_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_boottime());
+}
+
+static inline u64 ktime_get_coarse_clocktai_ns(void)
+{
+       return ktime_to_ns(ktime_get_coarse_clocktai());
+}
+
+/**
+ * ktime_mono_to_real - Convert monotonic time to clock realtime
+ */
+static inline ktime_t ktime_mono_to_real(ktime_t mono)
+{
+       return ktime_mono_to_any(mono, TK_OFFS_REAL);
+}
+
+static inline u64 ktime_get_ns(void)
+{
+       return ktime_to_ns(ktime_get());
+}
+
+static inline u64 ktime_get_real_ns(void)
+{
+       return ktime_to_ns(ktime_get_real());
+}
+
+static inline u64 ktime_get_boottime_ns(void)
+{
+       return ktime_to_ns(ktime_get_boottime());
+}
+
+static inline u64 ktime_get_clocktai_ns(void)
+{
+       return ktime_to_ns(ktime_get_clocktai());
+}
+
+static inline u64 ktime_get_raw_ns(void)
+{
+       return ktime_to_ns(ktime_get_raw());
+}
+
+extern u64 ktime_get_mono_fast_ns(void);
+extern u64 ktime_get_raw_fast_ns(void);
+extern u64 ktime_get_boot_fast_ns(void);
+extern u64 ktime_get_real_fast_ns(void);
+
+/*
+ * timespec64/time64_t interfaces utilizing the ktime based ones
+ * for API completeness, these could be implemented more efficiently
+ * if needed.
+ */
+static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_boottime());
+}
+
+static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_coarse_boottime());
+}
+
+static inline time64_t ktime_get_boottime_seconds(void)
+{
+       return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
+}
+
+static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_clocktai());
+}
+
+static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
+}
+
+static inline time64_t ktime_get_clocktai_seconds(void)
+{
+       return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
+}
+
+#endif /* _LINUX_KTIME_H */
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h
index 78c8ac4951b5..24970c202ac6 100644
--- a/include/linux/pps_kernel.h
+++ b/include/linux/pps_kernel.h
@@ -12,6 +12,7 @@
 #include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 
 /*
  * Global defines
diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h
index 835ee87ed792..f0fa287710da 100644
--- a/include/linux/sched_clock.h
+++ b/include/linux/sched_clock.h
@@ -5,6 +5,8 @@
 #ifndef LINUX_SCHED_CLOCK
 #define LINUX_SCHED_CLOCK
 
+#include <linux/timekeeping.h>
+
 #ifdef CONFIG_GENERIC_SCHED_CLOCK
 /**
  * struct clock_read_data - data required to read from sched_clock()
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..bf235ff101d5 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -14,6 +14,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/timekeeping.h>
 
 #define MTL_MAX_RX_QUEUES	8
 #define MTL_MAX_TX_QUEUES	8
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 78a98bdff76d..b1c54f5ff91e 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -19,201 +19,6 @@ extern void legacy_timer_tick(unsigned long ticks);
 extern int do_settimeofday64(const struct timespec64 *ts);
 extern int do_sys_settimeofday64(const struct timespec64 *tv,
 				 const struct timezone *tz);
-
-/*
- * ktime_get() family: read the current time in a multitude of ways,
- *
- * The default time reference is CLOCK_MONOTONIC, starting at
- * boot time but not counting the time spent in suspend.
- * For other references, use the functions with "real", "clocktai",
- * "boottime" and "raw" suffixes.
- *
- * To get the time in a different format, use the ones wit
- * "ns", "ts64" and "seconds" suffix.
- *
- * See Documentation/core-api/timekeeping.rst for more details.
- */
-
-
-/*
- * timespec64 based interfaces
- */
-extern void ktime_get_raw_ts64(struct timespec64 *ts);
-extern void ktime_get_ts64(struct timespec64 *ts);
-extern void ktime_get_real_ts64(struct timespec64 *tv);
-extern void ktime_get_coarse_ts64(struct timespec64 *ts);
-extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
-
-void getboottime64(struct timespec64 *ts);
-
-/*
- * time64_t base interfaces
- */
-extern time64_t ktime_get_seconds(void);
-extern time64_t __ktime_get_real_seconds(void);
-extern time64_t ktime_get_real_seconds(void);
-
-/*
- * ktime_t based interfaces
- */
-
-enum tk_offsets {
-	TK_OFFS_REAL,
-	TK_OFFS_BOOT,
-	TK_OFFS_TAI,
-	TK_OFFS_MAX,
-};
-
-extern ktime_t ktime_get(void);
-extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
-extern ktime_t ktime_get_raw(void);
-extern u32 ktime_get_resolution_ns(void);
-
-/**
- * ktime_get_real - get the real (wall-) time in ktime_t format
- */
-static inline ktime_t ktime_get_real(void)
-{
-	return ktime_get_with_offset(TK_OFFS_REAL);
-}
-
-static inline ktime_t ktime_get_coarse_real(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_REAL);
-}
-
-/**
- * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
- *
- * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
- * time spent in suspend.
- */
-static inline ktime_t ktime_get_boottime(void)
-{
-	return ktime_get_with_offset(TK_OFFS_BOOT);
-}
-
-static inline ktime_t ktime_get_coarse_boottime(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
-}
-
-/**
- * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
- */
-static inline ktime_t ktime_get_clocktai(void)
-{
-	return ktime_get_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse_clocktai(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse(void)
-{
-	struct timespec64 ts;
-
-	ktime_get_coarse_ts64(&ts);
-	return timespec64_to_ktime(ts);
-}
-
-static inline u64 ktime_get_coarse_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse());
-}
-
-static inline u64 ktime_get_coarse_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_real());
-}
-
-static inline u64 ktime_get_coarse_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_boottime());
-}
-
-static inline u64 ktime_get_coarse_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_clocktai());
-}
-
-/**
- * ktime_mono_to_real - Convert monotonic time to clock realtime
- */
-static inline ktime_t ktime_mono_to_real(ktime_t mono)
-{
-	return ktime_mono_to_any(mono, TK_OFFS_REAL);
-}
-
-static inline u64 ktime_get_ns(void)
-{
-	return ktime_to_ns(ktime_get());
-}
-
-static inline u64 ktime_get_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_real());
-}
-
-static inline u64 ktime_get_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_boottime());
-}
-
-static inline u64 ktime_get_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_clocktai());
-}
-
-static inline u64 ktime_get_raw_ns(void)
-{
-	return ktime_to_ns(ktime_get_raw());
-}
-
-extern u64 ktime_get_mono_fast_ns(void);
-extern u64 ktime_get_raw_fast_ns(void);
-extern u64 ktime_get_boot_fast_ns(void);
-extern u64 ktime_get_real_fast_ns(void);
-
-/*
- * timespec64/time64_t interfaces utilizing the ktime based ones
- * for API completeness, these could be implemented more efficiently
- * if needed.
- */
-static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_boottime());
-}
-
-static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_boottime());
-}
-
-static inline time64_t ktime_get_boottime_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
-}
-
-static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_clocktai());
-}
-
-static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
-}
-
-static inline time64_t ktime_get_clocktai_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
-}
-
 /*
  * RTC specific
  */
@@ -308,4 +113,4 @@ void read_persistent_wall_and_boot_offset(struct timespec64 *wall_clock,
 extern int update_persistent_clock64(struct timespec64 now);
 #endif
 
-#endif
+#endif /* _LINUX_TIMEKEEPING_H */
diff --git a/init/main.c b/init/main.c
index f5b8246e8aa1..a8db3a136d6a 100644
--- a/init/main.c
+++ b/init/main.c
@@ -100,6 +100,7 @@
 #include <linux/kcsan.h>
 #include <linux/init_syscalls.h>
 #include <linux/stackdepot.h>
+#include <linux/timekeeping.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 406dccb79c2b..804f06801737 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "ntp_internal.h"
 #include "timekeeping_internal.h"
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index dd5697d7347b..14f82cd95d10 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 #include <linux/mutex.h>
 #include <linux/sched/task.h>
 
diff --git a/kernel/time/tick-legacy.c b/kernel/time/tick-legacy.c
index af225b32f5b3..9a534f716462 100644
--- a/kernel/time/tick-legacy.c
+++ b/kernel/time/tick-legacy.c
@@ -7,6 +7,7 @@
 #include <linux/irq.h>
 #include <linux/profile.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 29923b20e0e4..7292ed074742 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -29,6 +29,7 @@
 #include <linux/timex.h>
 #include <linux/capability.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/errno.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8a364aa9881a..4dfee925adc8 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -22,6 +22,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index ca2f2ecd1488..efbbe624d81d 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 
 #ifdef CONFIG_X86
 /* for art-tsc conversion */
-- 
2.25.1


From ezequiel at vanguardiasur.com.ar  Sun Aug 22 07:32:32 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sun, 22 Aug 2021 11:32:32 -0300
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <1629446378.18871.27.camel@mhfsdcap03>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
 <1b79a67b703d2c894bc4d9458c760e082fc42958.camel@mediatek.com>
 <CAAEAJfCTrKj9AFExN-L-TKww4E=us1VVh8LHtZ8Q0j_eaCD4Eg@mail.gmail.com>
 <1629446378.18871.27.camel@mhfsdcap03>
Message-ID: <CAAEAJfCdvj4drV+YSbvyR30b0+50RpJcOYdEoNODTdrAoL6+vA@mail.gmail.com>

On Fri, 20 Aug 2021 at 04:59, yunfei.dong at mediatek.com
<yunfei.dong at mediatek.com> wrote:
>
> Hi Ezequiel,
>
> Thanks for your detail feedback.
>
> On Thu, 2021-08-19 at 11:10 -0300, Ezequiel Garcia wrote:
> > On Thu, 19 Aug 2021 at 04:13, yunfei.dong at mediatek.com
> > <yunfei.dong at mediatek.com> wrote:
> > >
> > > Hi Ezequiel,
> > >
> > > Thanks for your suggestion.
> > >
> > > On Wed, 2021-08-18 at 11:11 -0300, Ezequiel Garcia wrote:
> > > > +danvet
> > > >
> > > > Hi,
> > > >
> > > > On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <yunfei.dong at mediatek.com>
> > > > wrote:
> > > > >
> > > > > This series adds support for multi hardware decode into mtk-vcodec,
> > > > > by first
> > > > > adding component framework to manage each hardware information:
> > > > > interrupt,
> > > > > clock, register bases and power. Secondly add core thread to deal
> > > > > with core
> > > > > hardware message, at the same time, add msg queue for different
> > > > > hardware
> > > > > share messages. Lastly, the architecture of different specs are not
> > > > > the same,
> > > > > using specs type to separate them.
> > > > >
> > > >
> > > > I don't think it's a good idea to introduce the component API in the
> > > > media subsystem. It doesn't seem to be maintained, IRC there's not
> > > > even
> > > > a maintainer for it, and it has some issues that were never
> > > > addressed.
> > > >
> > > > It would be really important to avoid it. Is it really needed in the
> > > > first place?
> > > >
> > > > Thanks,
> > > > Ezequiel
> > >
> > > For there are many hardware need to use, mt8192 is three and mt8195 is
> > > five. Maybe need more to be used in the feature.
> > >
> > > Each hardware has independent clk/power/iommu port/irq.
> > > Use component interface in prob to get each component's information.
> > > Just enable the hardware when need to use it, very convenient and
> > > simple.
> > >
> > > I found that there are many modules use component to manage hardware
> > > information, such as iommu and drm etc.
> > >
> >
> > Many drivers support multiple hardware variants, where each variant
> > has a different number of clocks or interrupts, see for instance
> > struct hantro_variant which allows to expose different codec cores,
> > some having both decoder/encoder, and some having just a decoder.
> >
> > The component API is mostly used by DRM to aggregate independent
> > subdevices (called components) into an aggregated driver.
> >
> > For instance, a DRM driver needs to glue together the HDMI, MIPI,
> > and plany controller, or any other hardware arrangement where
> > devices can be described independently.
> >
> The usage scenario is very similar with drm and iommu, So decide to use
> component framework.
> Decode has three/five or more hardwares, these hardware are independent.
> For mt8183 just need core hardware to decode, but mt8192 has lat,soc and
> core hardware to decode. When lat need to use, just enable lat hardware,
> core is the same.And mt8195 will has two cores, each core can work well
> independent.
>
> For each component device just used to open their power/clk/iommu
> port/irq when master need to enable it. The main logic is in master
> device.
>
> > The component API may look simple but has some issues, it's not easy
> > to debug, and can cause troubles if not used as expected [1].
> > It's worth making sure you actually need a framework
> > to glue different devices together.
> >
> Each hardware has its index, master can get hardware information
> according these index, looks not complex. What do you mean about not
> easy to debug?
>
> > > Do you have any other suggestion for this architecture?
> > >
> >
> > Looking at the different patchsets that are posted, it's not clear
> > to me what exactly are the different architectures that you intend
> > to support, can you some documentation which clarifies that?
> >
> Have five hardwares lat,soc,core0,core1 and main. Lat thread can use lat
> soc and main, core thread can use soc,lat, core0 and core1. Core thread
> can be used or not for different project.

Can you explain what are these lat,soc and core threads for?

> Also Need to use these
> hardware dynamic at the same time. So I use component framework, just
> need to know the used  hardware index according to different
> project.Need not to do complex logic to manage these hardwares.
>

I am not thrilled to see the component framework introduced to the
media subsystem. Like I said, it has no clear maintainer, and it's not
easy to use.

The media subsystem has some support which AFAIK does the same thing,
see v4l2-async, which is maintained by media people.

Please push a branch based on media/master containing these changes.
I see there are other patch series for this device, but it's hard to track
which goes first, etc.

Thanks,
Ezequiel


From ezequiel at vanguardiasur.com.ar  Sun Aug 22 07:37:24 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sun, 22 Aug 2021 11:37:24 -0300
Subject: [PATCH] arm64: dts: rockchip: Re-add interrupt-names for RK3399's
 vpu
In-Reply-To: <20210822115755.3171937-1-knaerzche@gmail.com>
References: <20210822115755.3171937-1-knaerzche@gmail.com>
Message-ID: <CAAEAJfDLvctAk3omLgFBBbzvufFKwSW5_cQZ+MjvyN4khGOe_w@mail.gmail.com>

Hi Alex, Heiko,

On Sun, 22 Aug 2021 at 08:58, Alex Bee <knaerzche at gmail.com> wrote:
>
> Commit a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
> intended to remove the interrupt-names property for mmu nodes, but it
> also removed it for the vpu node in rk3399.dtsi. That makes the driver
> fail probing currently.
> Fix this by re-adding the property for this node.
>
> Fixes: a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")

AFAICS a728c10dd62a removed lots of interrupt-names properties
from devices other than IOMMU.

Maybe it's best to revert it?

Thanks,
Ezequiel


From daniel at ffwll.ch  Sun Aug 22 09:50:23 2021
From: daniel at ffwll.ch (Daniel Vetter)
Date: Sun, 22 Aug 2021 18:50:23 +0200
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
Message-ID: <CAKMK7uFW3Z=Up=OCJO4dNR9ffaTdFjHwoND9CrUw6LHmQ4t_AQ@mail.gmail.com>

On Wed, Aug 18, 2021 at 4:12 PM Ezequiel Garcia
<ezequiel at vanguardiasur.com.ar> wrote:
>
> +danvet
>
> Hi,
>
> On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <yunfei.dong at mediatek.com> wrote:
> >
> > This series adds support for multi hardware decode into mtk-vcodec, by first
> > adding component framework to manage each hardware information: interrupt,
> > clock, register bases and power. Secondly add core thread to deal with core
> > hardware message, at the same time, add msg queue for different hardware
> > share messages. Lastly, the architecture of different specs are not the same,
> > using specs type to separate them.
> >
>
> I don't think it's a good idea to introduce the component API in the
> media subsystem. It doesn't seem to be maintained, IRC there's not even
> a maintainer for it, and it has some issues that were never addressed.

Defacto dri-devel folks are maintainer component.c, but also I'm not
aware of anything missing there?

There has been discussions that in various drm subsystems like
drm_bridge or drm_panel a few things are missing, which prevent
drivers from moving _away_ from component.c to the more specific
solutions for panel/bridges. But nothing that's preventing them from
using component.c itself.

I'm happy to merge a MAINTAINERS patch to clarify the situation if
that's needed.
-Daniel

> It would be really important to avoid it. Is it really needed in the
> first place?
>
> Thanks,
> Ezequiel



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From valentin.schneider at arm.com  Sun Aug 22 10:31:11 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sun, 22 Aug 2021 18:31:11 +0100
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <20210817144348.kkgoytuz3766jeoz@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
 <20210817144348.kkgoytuz3766jeoz@linutronix.de>
Message-ID: <87h7fh75eo.mognet@arm.com>

On 17/08/21 16:43, Sebastian Andrzej Siewior wrote:
> On 2021-08-11 21:13:52 [+0100], Valentin Schneider wrote:
>> diff --git a/include/linux/sched.h b/include/linux/sched.h
>> index debc960f41e3..8ba7b4a7ee69 100644
>> --- a/include/linux/sched.h
>> +++ b/include/linux/sched.h
>> @@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
>>  #endif
>>  }
>>
>> +/* Is the current task guaranteed to stay on its current CPU? */
>> +static inline bool migratable(void)
>> +{
>> +#ifdef CONFIG_SMP
>> +	return preemptible() && !current->migration_disabled;
>> +#else
>> +	return true;
>
> shouldn't this be false in the UP case?
>

Yes indeed, forgot to flip that one when inverting the logic.


From mark.kettenis at xs4all.nl  Sun Aug 22 10:44:22 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Sun, 22 Aug 2021 19:44:22 +0200 (CEST)
Subject: [PATCH v3 1/2] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <CAL_JsqJ-YDNWOoo8TUupDox31YreUNQAPXHnMMtXakQs0S_BDA@mail.gmail.com>
 (message from Rob Herring on Wed, 18 Aug 2021 15:51:11 -0500)
References: <20210726083204.93196-1-mark.kettenis@xs4all.nl>
 <20210726083204.93196-2-mark.kettenis@xs4all.nl>
 <20210726231848.GA1025245@robh.at.kernel.org>
 <87sfzt1pg9.wl-maz@kernel.org>
 <CAL_JsqLvqWiuib9s4PzX8pOQYJQ0eR7Gxz==J849eVJ5MDq4SA@mail.gmail.com>
 <8735ra1x8t.wl-maz@kernel.org>
 <CAL_JsqJ5M3soMT30ntSTbqqdrQP8TT26mHL-0xExsn10MWPofA@mail.gmail.com>
 <56140331bd735d61@bloch.sibelius.xs4all.nl>
 <CAL_JsqJ-YDNWOoo8TUupDox31YreUNQAPXHnMMtXakQs0S_BDA@mail.gmail.com>
Message-ID: <56140c26d86f4733@bloch.sibelius.xs4all.nl>

> From: Rob Herring <robh at kernel.org>
> Date: Wed, 18 Aug 2021 15:51:11 -0500

Hi Rob,

> On Wed, Aug 18, 2021 at 2:56 PM Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
> >
> > > From: Rob Herring <robh at kernel.org>
> > > Date: Sun, 15 Aug 2021 14:19:57 -0500
> > >
> > > On Sun, Aug 15, 2021 at 11:36 AM Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > Hi Rob,
> > > >
> > > > Apologies for the delay, I somehow misplaced this email...
> > > >
> > > > On Mon, 02 Aug 2021 17:10:39 +0100,
> > > > Rob Herring <robh at kernel.org> wrote:
> > > > >
> > > > > On Sun, Aug 1, 2021 at 3:31 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > > >
> > > > > > On Tue, 27 Jul 2021 00:18:48 +0100,
> > > > > > Rob Herring <robh at kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, Jul 26, 2021 at 10:32:00AM +0200, Mark Kettenis wrote:
> > > > > > > > From: Mark Kettenis <kettenis at openbsd.org>
> > > > > > > >
> > > > > > > > The Apple PCIe host controller is a PCIe host controller with
> > > > > > > > multiple root ports present in Apple ARM SoC platforms, including
> > > > > > > > various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > > > >
> > > > > > > > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > > > > > > > ---
> > > > > > > >  .../devicetree/bindings/pci/apple,pcie.yaml   | 166 ++++++++++++++++++
> > > > > > > >  MAINTAINERS                                   |   1 +
> > > > > > > >  2 files changed, 167 insertions(+)
> > > > > > > >  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > > >
> > > > > > > > diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > > > new file mode 100644
> > > > > > > > index 000000000000..bfcbdee79c64
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > > > @@ -0,0 +1,166 @@
> > > > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > > > > +%YAML 1.2
> > > > > > > > +---
> > > > > > > > +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> > > > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > > > > +
> > > > > > > > +title: Apple PCIe host controller
> > > > > > > > +
> > > > > > > > +maintainers:
> > > > > > > > +  - Mark Kettenis <kettenis at openbsd.org>
> > > > > > > > +
> > > > > > > > +description: |
> > > > > > > > +  The Apple PCIe host controller is a PCIe host controller with
> > > > > > > > +  multiple root ports present in Apple ARM SoC platforms, including
> > > > > > > > +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > > > > +  The controller incorporates Synopsys DesigWare PCIe logic to
> > > > > > > > +  implements its root ports.  But the ATU found on most DesignWare
> > > > > > > > +  PCIe host bridges is absent.
> > > > > > >
> > > > > > > blank line
> > > > > > >
> > > > > > > > +  All root ports share a single ECAM space, but separate GPIOs are
> > > > > > > > +  used to take the PCI devices on those ports out of reset.  Therefore
> > > > > > > > +  the standard "reset-gpio" and "max-link-speed" properties appear on
> > > > > > >
> > > > > > > reset-gpios
> > > > > > >
> > > > > > > > +  the child nodes that represent the PCI bridges that correspond to
> > > > > > > > +  the individual root ports.
> > > > > > >
> > > > > > > blank line
> > > > > > >
> > > > > > > > +  MSIs are handled by the PCIe controller and translated into regular
> > > > > > > > +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> > > > > > > > +  distributed over the root ports as the OS sees fit by programming
> > > > > > > > +  the PCIe controller's port registers.
> > > > > > > > +
> > > > > > > > +allOf:
> > > > > > > > +  - $ref: /schemas/pci/pci-bus.yaml#
> > > > > > > > +
> > > > > > > > +properties:
> > > > > > > > +  compatible:
> > > > > > > > +    items:
> > > > > > > > +      - const: apple,t8103-pcie
> > > > > > > > +      - const: apple,pcie
> > > > > > > > +
> > > > > > > > +  reg:
> > > > > > > > +    minItems: 3
> > > > > > > > +    maxItems: 5
> > > > > > > > +
> > > > > > > > +  reg-names:
> > > > > > > > +    minItems: 3
> > > > > > > > +    maxItems: 5
> > > > > > > > +    items:
> > > > > > > > +      - const: config
> > > > > > > > +      - const: rc
> > > > > > > > +      - const: port0
> > > > > > > > +      - const: port1
> > > > > > > > +      - const: port2
> > > > > > > > +
> > > > > > > > +  ranges:
> > > > > > > > +    minItems: 2
> > > > > > > > +    maxItems: 2
> > > > > > > > +
> > > > > > > > +  interrupts:
> > > > > > > > +    description:
> > > > > > > > +      Interrupt specifiers, one for each root port.
> > > > > > > > +    minItems: 1
> > > > > > > > +    maxItems: 3
> > > > > > > > +
> > > > > > > > +  msi-controller: true
> > > > > > > > +  msi-parent: true
> 
> BTW, I don't think msi-parent and msi-controller together is valid?

There is an existing example in:

arm64/boot/dts/marvell/armada-37xx.dtsi

I think it makes sense as the pcie bridge itself serves as the MSI
controller.

> > > > > > > > +
> > > > > > > > +  msi-ranges:
> > > > > > > > +    description:
> > > > > > > > +      A list of pairs <intid span>, where "intid" is the first
> > > > > > > > +      interrupt number that can be used as an MSI, and "span" the size
> > > > > > > > +      of that range.
> > > > > > > > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > > > > > > > +    items:
> > > > > > > > +      minItems: 2
> > > > > > > > +      maxItems: 2
> > > > > > >
> > > > > > > I still have issues I raised on v1 with this property. It's genericish
> > > > > > > looking, but not generic. 'intid' as a single cell can't specify any
> > > > > > > parent interrupt such as a GIC which uses 3 cells. You could put in all
> > > > > > > the cells, but you'd still be assuming which cell you can increment.
> > > > > >
> > > > > > The GIC bindings already use similar abstractions, see what we do for
> > > > > > both GICv2m and GICv3 MBIs. Other MSI controllers use similar
> > > > > > properties (alpine and loongson, for example).
> > > > >
> > > > > That's the problem. Everyone making up their own crap.
> > > >
> > > > And that crap gets approved:
> > > >
> > > > https://lore.kernel.org/lkml/20200512205704.GA10412 at bogus/
> > > >
> > > > I'm not trying to be antagonistic here, but it seems that your
> > > > position on this very subject has changed recently.
> > >
> > > Not really, I think it's not the first time we've discussed this. But
> > > as I see things over and over, my tolerance for another instance
> > > without solving the problem for everyone diminishes. And what other
> > > leverage do I have?
> > >
> > > Additionally, how long we have to support something comes into play. I
> > > have no idea for a Loongson MSI controller. I have a better idea on an
> > > Apple product...
> > >
> > > > > > > I think you should just list all these under 'interrupts' using
> > > > > > > interrupt-names to make your life easier:
> > > > > > >
> > > > > > > interrupt-names:
> > > > > > >   items:
> > > > > > >     - const: port0
> > > > > > >     - const: port1
> > > > > > >     - const: port2
> > > > > > >     - const: msi0
> > > > > > >     - const: msi1
> > > > > > >     - const: msi2
> > > > > > >     - const: msi3
> > > > > > >     ...
> > > > > > >
> > > > > > > Yeah, it's kind of verbose, but if the h/w block handles N interrupts,
> > > > > > > you should list N interrupts. The worst case for the above is N entries
> > > > > > > too if not contiguous.
> > > > > >
> > > > > > And that's where I beg to differ, again.
> > > > > >
> > > > > > Specifying interrupts like this gives the false impression that these
> > > > > > interrupts are generated by the device that owns them (the RC). Which
> > > > > > for MSIs is not the case.
> > > > >
> > > > > It's no different than an interrupt controller node having an
> > > > > interrupts property. The source is downstream and the interrupt
> > > > > controller is combining/translating the interrupts.
> > > > >
> > > > > The physical interrupt signals are connected to and originating in
> > > > > this block.
> > > >
> > > > Oh, I also object to this, for the same reasons. The only case where
> > > > it makes sense IMHO is when the interrupt controller is a multiplexer.
> > >
> > > So we've had the same kind of property for interrupt multiplexers. I'm
> > > fine if you think an 'MSI to interrupts mapping property' should be
> > > named something else.
> > >
> > > > > That sounds like perfectly 'describing the h/w' to me.
> > > >
> > > > I guess we have a different view of about these things. At the end of
> > > > the day, I don't care enough as long as we can expose a range of
> > > > interrupts one way or another.
> > >
> > > I don't really either. I just don't want 10 ways AND another...
> > >
> > > > > > This is not only verbose, this is
> > > > > > semantically dubious. And what should we do when the number of
> > > > > > possible interrupt is ridiculously large, as it is for the GICv3 ITS?
> > > > >
> > > > > I don't disagree with the verbose part. But that's not really an issue
> > > > > in this case.
> > > > >
> > > > > > I wish we had a standard way to express these constraints. Until we
> > > > > > do, I don't think enumerating individual interrupts is a practical
> > > > > > thing to do, nor that it actually represents the topology of the
> > > > > > system.
> > > > >
> > > > > The only way a standard way will happen is to stop accepting the
> > > > > custom properties.
> > > > >
> > > > > All the custom properties suffer from knowledge of what the parent
> > > > > interrupt controller is. To fix that, I think we need something like
> > > > > this:
> > > > >
> > > > > msi-ranges = <intspec base>, <intspec step>, <intspec end>;
> > > > >
> > > > > 'intspec' is defined by the parent interrupt-controller cells. step is
> > > > > the value to add. And end is what to match on to stop aka the last
> > > > > interrupt in the range. For example, if the GIC is the parent, we'd
> > > > > have something like this:
> > > > >
> > > > > <GIC_SPI 123 0>, <0 1 0>, <GIC_SPI 124 0>
> > > > >
> > > > > Does this apply to cases other than MSI? I think so as don't we have
> > > > > the same type of properties with the low power mode shadow interrupt
> > > > > controllers?  So 'interrupt-ranges'?
> > > >
> > > > This would work, though the increment seems a bit over-engineered. You
> > > > also may need this property to accept multiple ranges.
> > >
> > > Yes, certainly. Worst case is a map.
> > >
> > > > > It looks to me like there's an assumption in the kernel that an MSI
> > > > > controller has a linear range of parent interrupts? Is that correct
> > > > > and something that's guaranteed? That assumption leaks into the
> > > > > existing bindings.
> > > >
> > > > Depends on how the controller works. In general, the range maps to the
> > > > MultiMSI requirements where the message is an offset from the base of
> > > > the interrupt range. So you generally end-up with ranges of at least
> > > > 32 contiguous MSIs. Anything under that is sub-par and probably not
> > > > worth supporting.
> > >
> > > Maybe just this is enough:
> > > msi-ranges = <intspec base>, <length>, <intspec base>, <length>, ...
> > >
> > > While I say 'length' here, that's really up to the interrupt parent to
> > > interpret the intspec cells.
> >
> > So for the Apple PCIe controller we'd have:
> >
> >    msi-ranges = <AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
> >
> > That would work just fine.
> >
> > Should this be documented in the apple,pcie binding, or somewhere more
> > generic?
> 
> It doesn't have an 'apple,' prefix, so somewhere generic. Probably
> bindings/interrupt-controller/msi.txt. Or start an msi-controller.yaml
> schema as I'd rather not add things we can't validate, but I don't
> want to gate this on converting all the MSI bindings. Someone that
> understands MSI better than me should review too.

Yes, I'd like to avoid converting all the MSI bindings, but I could
add an msi-controller.yaml file and use it in the appropriate
interrupt controller and pci host bridge bindings that have been
converted to yaml.

> Another thing I thought of is the above is assuming the interrupt
> parent is the same as any interrupts for the node and that all MSIs go
> to 1 interrupt controller. Also, given Marc doesn't think using
> 'interrupts' is right, then using 'interrupt-parent' isn't either
> (though many of the examples below do just that). So maybe we need the
> phandle in there:
> 
> msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;

That makes sense.

> Other examples of this type of property include:
> al,msi-base-spi/al,msi-base-spi
> arm,msi-base-spi/arm,msi-num-spis
> mbi-ranges
> loongson,msi-base-vec/loongson,msi-num-vecs
> marvell,spi-ranges
> ti,interrupt-ranges?
> 
> We should make sure msi-ranges works for all of these cases at least
> even if we can't change them.

I think this scheme would work for all of these although it isn't
entirely clear to me whether ti,interrupt-ranges is about just MSIs or
if it also maps some other kind of interrupts.

marvell,spi-ranges is an interesting one since it typically specifies
two ranges of 64 MSIs.  But that's something your proposal addresses
just fine.  I suppose we will provide a phandle for the parent
interrupt controller for each individual range?

If Marc agrees, I'll get working on implementing the
msi-controller.yaml schema.

Thanks,

Mark


From lkp at intel.com  Sun Aug 22 10:51:13 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 23 Aug 2021 01:51:13 +0800
Subject: [arm-platforms:hack/m1-pcie-v2 6/21]
 drivers/clk/clk-apple-gate.c:113:16: warning: no previous prototype for
 'apple_clk_hw_onecell_get'
Message-ID: <202108230107.GEmscoyG-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git hack/m1-pcie-v2
head:   2c9981b6a289354c22989e70cef0e51b9e632091
commit: 9404863043f90db4d8e377ac211584660c6acbec [6/21] clk: add support for gate clocks on Apple SoCs
config: arm64-randconfig-r003-20210822 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=9404863043f90db4d8e377ac211584660c6acbec
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms hack/m1-pcie-v2
        git checkout 9404863043f90db4d8e377ac211584660c6acbec
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/clk/clk-apple-gate.c:113:16: warning: no previous prototype for 'apple_clk_hw_onecell_get' [-Wmissing-prototypes]
     113 | struct clk_hw *apple_clk_hw_onecell_get(struct of_phandle_args *clkspec,
         |                ^~~~~~~~~~~~~~~~~~~~~~~~


vim +/apple_clk_hw_onecell_get +113 drivers/clk/clk-apple-gate.c

   112	
 > 113	struct clk_hw *apple_clk_hw_onecell_get(struct of_phandle_args *clkspec,
   114						void *data)
   115	{
   116		struct clk_hw *hw = NULL;
   117		struct clk_hw_onecell_data *hw_data = data;
   118		unsigned int idx = clkspec->args[0];
   119	
   120		if (idx % 8) {
   121			pr_err("%s: unaligned index: %u\n", __func__, idx);
   122			return ERR_PTR(-EINVAL);
   123		}
   124	
   125		idx /= 8;
   126		if (idx >= hw_data->num) {
   127			pr_err("%s: index out of bounds: %u\n", __func__, idx);
   128			return ERR_PTR(-EINVAL);
   129		}
   130	
   131		hw = hw_data->hws[idx];
   132		if (!hw)
   133			return ERR_PTR(-EINVAL);
   134		return hw;
   135	}
   136	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 46089 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210823/5aaa17a8/attachment-0001.gz>

From ezequiel at vanguardiasur.com.ar  Sun Aug 22 10:57:15 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sun, 22 Aug 2021 14:57:15 -0300
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <CAKMK7uFW3Z=Up=OCJO4dNR9ffaTdFjHwoND9CrUw6LHmQ4t_AQ@mail.gmail.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
 <CAKMK7uFW3Z=Up=OCJO4dNR9ffaTdFjHwoND9CrUw6LHmQ4t_AQ@mail.gmail.com>
Message-ID: <CAAEAJfB3CoTU7bZe08wYEfTTm6=6UPOae9u39AtdbJ9saYknBA@mail.gmail.com>

On Sun, 22 Aug 2021 at 13:50, Daniel Vetter <daniel at ffwll.ch> wrote:
>
> On Wed, Aug 18, 2021 at 4:12 PM Ezequiel Garcia
> <ezequiel at vanguardiasur.com.ar> wrote:
> >
> > +danvet
> >
> > Hi,
> >
> > On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <yunfei.dong at mediatek.com> wrote:
> > >
> > > This series adds support for multi hardware decode into mtk-vcodec, by first
> > > adding component framework to manage each hardware information: interrupt,
> > > clock, register bases and power. Secondly add core thread to deal with core
> > > hardware message, at the same time, add msg queue for different hardware
> > > share messages. Lastly, the architecture of different specs are not the same,
> > > using specs type to separate them.
> > >
> >
> > I don't think it's a good idea to introduce the component API in the
> > media subsystem. It doesn't seem to be maintained, IRC there's not even
> > a maintainer for it, and it has some issues that were never addressed.
>
> Defacto dri-devel folks are maintainer component.c, but also I'm not
> aware of anything missing there?
>

A while ago, I tried to fix a crash in the Rockchip DRM driver
(I was then told there can be similar issues on the IMX driver too,
but I forgot the details of that).

I sent a patchset trying to address it and got total silence back.
Although you could argue the issue is in how drivers use the component
API, AFAICR the abuse is spreaded across a few drivers, so it felt
more reasonable to improve the component API itself, instead of changing
all the drivers.

See below:

https://patchwork.kernel.org/project/linux-rockchip/cover/20200120170602.3832-1-ezequiel at collabora.com/

> There has been discussions that in various drm subsystems like
> drm_bridge or drm_panel a few things are missing, which prevent
> drivers from moving _away_ from component.c to the more specific
> solutions for panel/bridges. But nothing that's preventing them from
> using component.c itself.
>
> I'm happy to merge a MAINTAINERS patch to clarify the situation if
> that's needed.

Indeed, that would be good.

Thanks,
Ezequiel


From valentin.schneider at arm.com  Sun Aug 22 11:14:18 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sun, 22 Aug 2021 19:14:18 +0100
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <20210817170925.2jwqvgvmqab2glwu@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
 <20210817170925.2jwqvgvmqab2glwu@linutronix.de>
Message-ID: <87czq573et.mognet@arm.com>

On 17/08/21 19:09, Sebastian Andrzej Siewior wrote:
> On 2021-08-11 21:13:52 [+0100], Valentin Schneider wrote:
>> diff --git a/include/linux/sched.h b/include/linux/sched.h
>> index debc960f41e3..8ba7b4a7ee69 100644
>> --- a/include/linux/sched.h
>> +++ b/include/linux/sched.h
>> @@ -1715,6 +1715,16 @@ static inline bool is_percpu_thread(void)
>>  #endif
>>  }
>>
>> +/* Is the current task guaranteed to stay on its current CPU? */
>> +static inline bool migratable(void)
>
> I'm going to rename this in my tree to `is_migratable' because of

<snip>

Thanks for carrying it through, I'll keep that change for the next version.

> Sebastian


From valentin.schneider at arm.com  Sun Aug 22 11:15:32 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sun, 22 Aug 2021 19:15:32 +0100
Subject: [PATCH v3 3/4] rcu/nocb: Protect NOCB state via local_lock()
 under PREEMPT_RT
In-Reply-To: <20210817153613.l5f66czar6pajexo@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-4-valentin.schneider@arm.com>
 <20210817153613.l5f66czar6pajexo@linutronix.de>
Message-ID: <87bl5p73cr.mognet@arm.com>

On 17/08/21 17:36, Sebastian Andrzej Siewior wrote:
>> +static inline int rcu_lockdep_is_held_nocb_local(struct rcu_data *rdp)
>> +{
>> +	return lockdep_is_held(
>> +#ifdef CONFIG_PREEMPT_RT
>> +		&rdp->nocb_local_lock.lock
>> +#else
>> +		&rdp->nocb_local_lock
>> +#endif
>> +	);
>> +}
>
> Now that I see it and Paul asked for it, please just use !RT version.
>       return lockdep_is_held(&rdp->nocb_local_lock);
>
> and RT will work, too.
>

The above was required due to the (previous) definition of local_lock_t:

  typedef struct {
          spinlock_t		lock;
  } local_lock_t;

On -rt11 I see this is now:

  typedef spinlock_t local_lock_t;

which indeed means the iffdefery can (actually it *has* to) go.

>>  static inline bool rcu_current_is_nocb_kthread(struct rcu_data *rdp)
>>  {
>>      /* Race on early boot between thread creation and assignment */
>> @@ -1629,6 +1664,22 @@ static void rcu_nocb_unlock_irqrestore(struct rcu_data *rdp,
>>      }
>>  }
>>
>> +/*
>> + * The invocation of rcu_core() within the RCU core kthreads remains preemptible
>> + * under PREEMPT_RT, thus the offload state of a CPU could change while
>> + * said kthreads are preempted. Prevent this from happening by protecting the
>> + * offload state with a local_lock().
>> + */
>> +static void rcu_nocb_local_lock(struct rcu_data *rdp)
>> +{
>> +	local_lock(&rcu_data.nocb_local_lock);
>> +}
>> +
>> +static void rcu_nocb_local_unlock(struct rcu_data *rdp)
>> +{
>> +	local_unlock(&rcu_data.nocb_local_lock);
>> +}
>> +
> Do you need to pass rdp given that it is not used?
>

Not anymore, you're right.

>>  /* Lockdep check that ->cblist may be safely accessed. */
>>  static void rcu_lockdep_assert_cblist_protected(struct rcu_data *rdp)
>>  {
>
> Sebastian


From f.fainelli at gmail.com  Sun Aug 22 12:06:49 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:06:49 -0700
Subject: [PATCH v5 1/5] ARM: dts: NSP: Add common bindings for MX64/MX65
In-Reply-To: <20210806204446.2981299-2-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
 <20210806204446.2981299-2-mnhagan88@gmail.com>
Message-ID: <20210822190649.3713909-1-f.fainelli@gmail.com>

On Fri,  6 Aug 2021 21:44:32 +0100, Matthew Hagan <mnhagan88 at gmail.com> wrote:
> These bindings are required for all Meraki MX64/MX65 devices. These
> common bindings include memory (2GB), PWM LEDs, AMAC, I2C (AT24), NAND
> partitions, EHCI, OHCI and pinctrl.
> 
> Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/master, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:07:11 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:07:11 -0700
Subject: [PATCH v5 2/5] ARM: dts: NSP: Add Ax stepping modifications
In-Reply-To: <20210806204446.2981299-3-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
 <20210806204446.2981299-3-mnhagan88@gmail.com>
Message-ID: <20210822190711.3714024-1-f.fainelli@gmail.com>

On Fri,  6 Aug 2021 21:44:33 +0100, Matthew Hagan <mnhagan88 at gmail.com> wrote:
> While uncommon, some Ax NSP SoCs exist in the wild. This stepping
> requires a modified secondary CPU boot-reg and removal of DMA coherency
> properties. Without these modifications, the secondary CPU will be
> inactive and many peripherals will exhibit undefined behaviour.
> 
> Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/master, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:07:34 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:07:34 -0700
Subject: [PATCH v5 3/5] ARM: dts: NSP: Add DT files for Meraki MX64 series
In-Reply-To: <20210806204446.2981299-4-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
 <20210806204446.2981299-4-mnhagan88@gmail.com>
Message-ID: <20210822190734.3714140-1-f.fainelli@gmail.com>

On Fri,  6 Aug 2021 21:44:34 +0100, Matthew Hagan <mnhagan88 at gmail.com> wrote:
> MX64 & MX64W Hardware info:
>   - CPU: Broadcom BCM58625 Cortex A9 @ 1200Mhz
>   - RAM: 2 GB (4 x 4Gb SK Hynix H5TC4G83CFR)
>   - Storage: 1 GB (Micron MT29F8G08ABACA)
>   - Networking: BCM58625 internal switch (5x 1GbE ports)
>   - USB: 1x USB2.0
>   - Serial: Internal header
>   - WLAN(MX64W only): 2x Broadcom BCM43520KMLG on the PCI bus
> 
> This patch adds the Meraki MX64 series-specific bindings. Since some
> devices make use of the older A0 SoC, changes need to be made to
> accommodate this case, including removal of coherency options and
> modification to the secondary-boot-reg.
> 
> Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/master, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:08:00 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:08:00 -0700
Subject: [PATCH v5 4/5] ARM: dts: NSP: Add DT files for Meraki MX65 series
In-Reply-To: <20210806204446.2981299-5-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
 <20210806204446.2981299-5-mnhagan88@gmail.com>
Message-ID: <20210822190800.3714263-1-f.fainelli@gmail.com>

On Fri,  6 Aug 2021 21:44:35 +0100, Matthew Hagan <mnhagan88 at gmail.com> wrote:
> MX65 & MX65W Hardware info:
>   - CPU: Broadcom BCM58625 Cortex A9 @ 1200Mhz
>   - RAM: 2 GB (4 x 4Gb SK Hynix H5TC4G83CFR)
>   - Storage: 1 GB (Micron MT29F8G08ABACA)
>   - Networking: BCM58625 switch (2x 1GbE ports)
>     2x Qualcomm QCA8337 switches (10x 1GbE ports total)
>   - PSE: Broadcom BCM59111KMLG connected to LAN ports 11 & 12
>   - USB: 1x USB2.0
>   - Serial: Internal header
>   - WLAN(MX65W Only): 2x Broadcom BCM43520KMLG on the PCI bus.
> 
> Note that a driver and firmware image for the BCM59111 PSE has been
> released under GPL, but this is not present in the kernel.
> 
> Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/master, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:11:00 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:11:00 -0700
Subject: [PATCH v5 5/5] dt-bindings: arm: bcm: NSP: add Meraki MX64/MX65
In-Reply-To: <20210806204446.2981299-6-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
 <20210806204446.2981299-6-mnhagan88@gmail.com>
Message-ID: <20210822191100.3714613-1-f.fainelli@gmail.com>

On Fri,  6 Aug 2021 21:44:36 +0100, Matthew Hagan <mnhagan88 at gmail.com> wrote:
> Add bindings for the Meraki MX64/MX65 series.
> 
> Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree/next, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:11:57 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 21:11:57 +0200
Subject: [PATCH v5 0/5] ARM: dts: NSP: add Meraki MX64/MX65 series
In-Reply-To: <20210806204446.2981299-1-mnhagan88@gmail.com>
References: <20210806204446.2981299-1-mnhagan88@gmail.com>
Message-ID: <f8510e24-3f1d-47e2-3981-7415f0926a1d@gmail.com>



On 8/6/2021 10:44 PM, Matthew Hagan wrote:
> Changes from v2:
>    - Introduce boards to Makefile in same patch as the board dts is added
>      (Vladimir Oltean)
>    - Use alphabetical ordering for labels (Vladimir Oltean)
>    - Remove address-cells and size-cells in qca8337 switch nodes (Vladimir
>      Oltean)
>    - Remove "cpu" labels from switch nodes' CPU ports (Vladimir Oltean)
>    - Various LED fixes, utilising dt-bindings/leds/common.h and correctly
>      specifying LEDs in the form "led-N" and with the color/function/
>      function-enumerator properties.
>    - Fix PWM LEDs and corresponding pinctrl bindings. (Vladimir Oltean)
> 
> The following changes were submitted as a separate series:
>    - Introduce patches to disable QSPI by default and enable where used
>      (Vladimir Oltean)
>    - Move mdio at 18032000 node from board related file to SoC (Vladimir
>      Oltean)
>    - In addition to above, relocate mdio-mux to bcm-nsp.dtsi and fix
>      the resulting usb3_phy issues
> 
> Changes from v3:
>    - Sort labels on mx64 a0 dts files into alphabetical order as well
>    - move include directives for input/input.h and leds/common.h to
>      bcm958625-mx6x-common.dtsi
>    - Whitespace fixes in bcm958625-mx6x-common.dtsi
>    - rename "senao_nvram" partition to "nvram"
> 
> Changes from v4:
>    - Move chosen and memory nodes from bcm958625-mx6x-common.dtsi to
>      each .dts file (Arnd Bergmann).
>    - Append [@<unit-address>] to memory nodes.
>    - Create Ax stepping-specific dtsi for Ax devices (Arnd Bergmann).
>    - Append read-only property to at24 eeprom node.
>    - Remove L2 properties which should be defined at platform-level.
>    - Correct NAND node names.

I applied patch 1 first such that we don't get warnings when we apply 
patches from there on during bisection builds.
-- 
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:12:44 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:12:44 -0700
Subject: [PATCH 1/3] ARM: dts: BCM5301X: Fix nodes names
In-Reply-To: <20210819065702.15406-1-zajec5@gmail.com>
References: <20210819065702.15406-1-zajec5@gmail.com>
Message-ID: <20210822191244.3714895-1-f.fainelli@gmail.com>

On Thu, 19 Aug 2021 08:57:00 +0200, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This fixes following errors for all BCM5301X dts files:
> chipcommonA at 18000000: $nodename:0: 'chipcommonA at 18000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
> mpcore at 19000000: $nodename:0: 'mpcore at 19000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
> mdio-bus-mux at 18003000: $nodename:0: 'mdio-bus-mux at 18003000' does not match '^mdio-mux[\\-@]?'
> dmu at 1800c000: $nodename:0: 'dmu at 1800c000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree/next, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:12:56 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:12:56 -0700
Subject: [PATCH 2/3] ARM: dts: BCM5301X: Fix MDIO mux binding
In-Reply-To: <20210819065702.15406-2-zajec5@gmail.com>
References: <20210819065702.15406-1-zajec5@gmail.com>
 <20210819065702.15406-2-zajec5@gmail.com>
Message-ID: <20210822191256.3715003-1-f.fainelli@gmail.com>

On Thu, 19 Aug 2021 08:57:01 +0200, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This fixes following error for all BCM5301X dts files:
> mdio-bus-mux at 18003000: compatible: ['mdio-mux-mmioreg'] is too short
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree/next, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:13:25 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:13:25 -0700
Subject: [PATCH 3/3] ARM: dts: BCM5301X: Fix memory nodes names
In-Reply-To: <20210819065702.15406-3-zajec5@gmail.com>
References: <20210819065702.15406-1-zajec5@gmail.com>
 <20210819065702.15406-3-zajec5@gmail.com>
Message-ID: <20210822191325.3715246-1-f.fainelli@gmail.com>

On Thu, 19 Aug 2021 08:57:02 +0200, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Thix fixes:
> arch/arm/boot/dts/bcm4708-netgear-r6250.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
> arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
> arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 402653184]]}
> arch/arm/boot/dts/bcm4709-linksys-ea9200.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
> arch/arm/boot/dts/bcm4709-netgear-r7000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
> arch/arm/boot/dts/bcm4709-netgear-r8000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]}
> arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]}
> arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 402653184]]}
> arch/arm/boot/dts/bcm53016-meraki-mr32.dt.yaml: /: memory: False schema does not allow {'reg': [[0, 134217728]], 'device_type': ['memory']}
> arch/arm/boot/dts/bcm94708.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]}
> arch/arm/boot/dts/bcm94709.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]}
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree/next, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:14:08 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:14:08 -0700
Subject: [PATCH] arm64: dts: broadcom: bcm4908: Fix NAND node name
In-Reply-To: <20210819121108.13979-1-zajec5@gmail.com>
References: <20210819121108.13979-1-zajec5@gmail.com>
Message-ID: <20210822191408.3715427-1-f.fainelli@gmail.com>

On Thu, 19 Aug 2021 14:11:08 +0200, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This matches nand-controller.yaml requirements.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree-arm64/next, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:14:48 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:14:48 -0700
Subject: [PATCH] arm64: dts: broadcom: bcm4908: Move reboot syscon out of
 bus
In-Reply-To: <20210819122606.15682-1-zajec5@gmail.com>
References: <20210819122606.15682-1-zajec5@gmail.com>
Message-ID: <20210822191448.3715549-1-f.fainelli@gmail.com>

On Thu, 19 Aug 2021 14:26:06 +0200, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> This fixes following error for every bcm4908 DTS file:
> bus at ff800000: reboot: {'type': 'object'} is not allowed for {'compatible': ['syscon-reboot'], 'regmap': [[15]], 'offset': [[52]], 'mask': [[1]]}
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree-arm64/next, thanks!
--
Florian


From f.fainelli at gmail.com  Sun Aug 22 12:15:03 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 22 Aug 2021 12:15:03 -0700
Subject: [PATCH] arm64: dts: broadcom: bcm4908: Fix UART clock name
In-Reply-To: <20210819153702.24394-1-zajec5@gmail.com>
References: <20210819153702.24394-1-zajec5@gmail.com>
Message-ID: <20210822191503.3715661-1-f.fainelli@gmail.com>

On Thu, 19 Aug 2021 17:37:02 +0200, Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> According to the binding the correct clock name is "refclk".
> 
> Fixes: 2961f69f151c ("arm64: dts: broadcom: add BCM4908 and Asus GT-AC5300 early DTS files")
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---

Applied to https://github.com/Broadcom/stblinux/commits/devicetree-arm64/next, thanks!
--
Florian


From deller at gmx.de  Sun Aug 22 12:48:36 2021
From: deller at gmx.de (Helge Deller)
Date: Sun, 22 Aug 2021 21:48:36 +0200
Subject: [PATCH v2] init: consolidate trap_init()
In-Reply-To: <20210414180037.14602dab@xhacker.debian>
References: <20210414165808.458a3d11@xhacker.debian>
 <20210414180037.14602dab@xhacker.debian>
Message-ID: <8638c5bc-71cd-9407-e597-77bf9bec17ee@gmx.de>

On 4/14/21 12:00 PM, Jisheng Zhang wrote:
> Many architectures implement the trap_init() as NOP, since there is
> no such default for trap_init(), this empty stub is duplicated among
> these architectures. Provide a generic but weak NOP implementation
> to drop the empty stubs of trap_init() in these architectures.
>
> The alpha, microblaze and sparc32 have real trap_init() implementation
> but the __init marker is missing, so add it to these three platforms.
>
> Signed-off-by: Jisheng Zhang <Jisheng.Zhang at synaptics.com>
> ---
> Since v1:
>   - add __init marker to trap_init() for alpha, microblaze and sparc32
>   - adjust the generic weak NOP trap_init() location to make it sits with
>     other NOP implementations together
>
>   arch/alpha/kernel/traps.c      |  2 +-
>   arch/arc/kernel/traps.c        |  5 -----
>   arch/arm/kernel/traps.c        |  5 -----
>   arch/h8300/kernel/traps.c      | 13 -------------
>   arch/hexagon/kernel/traps.c    |  4 ----
>   arch/microblaze/kernel/traps.c |  2 +-
>   arch/nds32/kernel/traps.c      |  5 -----
>   arch/nios2/kernel/traps.c      |  5 -----
>   arch/openrisc/kernel/traps.c   |  5 -----
>   arch/parisc/kernel/traps.c     |  4 ----
>   arch/powerpc/kernel/traps.c    |  5 -----
>   arch/riscv/kernel/traps.c      |  5 -----
>   arch/sparc/kernel/traps_32.c   |  2 +-
>   arch/um/kernel/trap.c          |  4 ----
>   init/main.c                    |  2 ++
>   15 files changed, 5 insertions(+), 63 deletions(-)


For parisc:

Acked-by: Helge Deller <deller at gmx.de> # parisc

Thanks!
Helge

>
> diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
> index 921d4b6e4d95..96b203199c6c 100644
> --- a/arch/alpha/kernel/traps.c
> +++ b/arch/alpha/kernel/traps.c
> @@ -973,7 +973,7 @@ do_entUnaUser(void __user * va, unsigned long opcode,
>   	return;
>   }
>
> -void
> +void __init
>   trap_init(void)
>   {
>   	/* Tell PAL-code what global pointer we want in the kernel.  */
> diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c
> index 57235e5c0cea..6b83e3f2b41c 100644
> --- a/arch/arc/kernel/traps.c
> +++ b/arch/arc/kernel/traps.c
> @@ -20,11 +20,6 @@
>   #include <asm/unaligned.h>
>   #include <asm/kprobes.h>
>
> -void __init trap_init(void)
> -{
> -	return;
> -}
> -
>   void die(const char *str, struct pt_regs *regs, unsigned long address)
>   {
>   	show_kernel_fault_diag(str, regs, address);
> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
> index 17d5a785df28..9baccef20392 100644
> --- a/arch/arm/kernel/traps.c
> +++ b/arch/arm/kernel/traps.c
> @@ -780,11 +780,6 @@ void abort(void)
>   	panic("Oops failed to kill thread");
>   }
>
> -void __init trap_init(void)
> -{
> -	return;
> -}
> -
>   #ifdef CONFIG_KUSER_HELPERS
>   static void __init kuser_init(void *vectors)
>   {
> diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
> index 5d8b969cd8f3..c3a3ebf77fbb 100644
> --- a/arch/h8300/kernel/traps.c
> +++ b/arch/h8300/kernel/traps.c
> @@ -30,19 +30,6 @@
>
>   static DEFINE_SPINLOCK(die_lock);
>
> -/*
> - * this must be called very early as the kernel might
> - * use some instruction that are emulated on the 060
> - */
> -
> -void __init base_trap_init(void)
> -{
> -}
> -
> -void __init trap_init(void)
> -{
> -}
> -
>   asmlinkage void set_esp0(unsigned long ssp)
>   {
>   	current->thread.esp0 = ssp;
> diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
> index 904134b37232..edfc35dafeb1 100644
> --- a/arch/hexagon/kernel/traps.c
> +++ b/arch/hexagon/kernel/traps.c
> @@ -28,10 +28,6 @@
>   #define TRAP_SYSCALL	1
>   #define TRAP_DEBUG	0xdb
>
> -void __init trap_init(void)
> -{
> -}
> -
>   #ifdef CONFIG_GENERIC_BUG
>   /* Maybe should resemble arch/sh/kernel/traps.c ?? */
>   int is_valid_bugaddr(unsigned long addr)
> diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c
> index 94b6fe93147d..7c15704fe56e 100644
> --- a/arch/microblaze/kernel/traps.c
> +++ b/arch/microblaze/kernel/traps.c
> @@ -18,7 +18,7 @@
>   #include <asm/exceptions.h>
>   #include <asm/unwind.h>
>
> -void trap_init(void)
> +void __init trap_init(void)
>   {
>   	__enable_hw_exceptions();
>   }
> diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
> index ee0d9ae192a5..f06421c645af 100644
> --- a/arch/nds32/kernel/traps.c
> +++ b/arch/nds32/kernel/traps.c
> @@ -183,11 +183,6 @@ void __pgd_error(const char *file, int line, unsigned long val)
>   }
>
>   extern char *exception_vector, *exception_vector_end;
> -void __init trap_init(void)
> -{
> -	return;
> -}
> -
>   void __init early_trap_init(void)
>   {
>   	unsigned long ivb = 0;
> diff --git a/arch/nios2/kernel/traps.c b/arch/nios2/kernel/traps.c
> index b172da4eb1a9..596986a74a26 100644
> --- a/arch/nios2/kernel/traps.c
> +++ b/arch/nios2/kernel/traps.c
> @@ -105,11 +105,6 @@ void show_stack(struct task_struct *task, unsigned long *stack,
>   	printk("%s\n", loglvl);
>   }
>
> -void __init trap_init(void)
> -{
> -	/* Nothing to do here */
> -}
> -
>   /* Breakpoint handler */
>   asmlinkage void breakpoint_c(struct pt_regs *fp)
>   {
> diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
> index 4d61333c2623..aa1e709405ac 100644
> --- a/arch/openrisc/kernel/traps.c
> +++ b/arch/openrisc/kernel/traps.c
> @@ -231,11 +231,6 @@ void unhandled_exception(struct pt_regs *regs, int ea, int vector)
>   	die("Oops", regs, 9);
>   }
>
> -void __init trap_init(void)
> -{
> -	/* Nothing needs to be done */
> -}
> -
>   asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
>   {
>   	force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
> diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
> index 8d8441d4562a..747c328fb886 100644
> --- a/arch/parisc/kernel/traps.c
> +++ b/arch/parisc/kernel/traps.c
> @@ -859,7 +859,3 @@ void  __init early_trap_init(void)
>
>   	initialize_ivt(&fault_vector_20);
>   }
> -
> -void __init trap_init(void)
> -{
> -}
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index a44a30b0688c..e952bee89684 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -2207,11 +2207,6 @@ DEFINE_INTERRUPT_HANDLER(kernel_bad_stack)
>   	die("Bad kernel stack pointer", regs, SIGABRT);
>   }
>
> -void __init trap_init(void)
> -{
> -}
> -
> -
>   #ifdef CONFIG_PPC_EMULATED_STATS
>
>   #define WARN_EMULATED_SETUP(type)	.type = { .name = #type }
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 0879b5df11b9..b3f3d84de779 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -194,8 +194,3 @@ int is_valid_bugaddr(unsigned long pc)
>   		return ((insn & __COMPRESSED_INSN_MASK) == __BUG_INSN_16);
>   }
>   #endif /* CONFIG_GENERIC_BUG */
> -
> -/* stvec & scratch is already set from head.S */
> -void trap_init(void)
> -{
> -}
> diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
> index 247a0d9683b2..c4df20ec01e2 100644
> --- a/arch/sparc/kernel/traps_32.c
> +++ b/arch/sparc/kernel/traps_32.c
> @@ -365,7 +365,7 @@ EXPORT_SYMBOL(do_BUG);
>    * up here so that timer interrupts work during initialization.
>    */
>
> -void trap_init(void)
> +void __init trap_init(void)
>   {
>   	extern void thread_info_offsets_are_bolixed_pete(void);
>
> diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
> index ad12f78bda7e..3198c4767387 100644
> --- a/arch/um/kernel/trap.c
> +++ b/arch/um/kernel/trap.c
> @@ -311,7 +311,3 @@ void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
>   {
>   	do_IRQ(WINCH_IRQ, regs);
>   }
> -
> -void trap_init(void)
> -{
> -}
> diff --git a/init/main.c b/init/main.c
> index 53b278845b88..8d14674c4e00 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -779,6 +779,8 @@ void __init __weak poking_init(void) { }
>
>   void __init __weak pgtable_cache_init(void) { }
>
> +void __init __weak trap_init(void) { }
> +
>   bool initcall_debug;
>   core_param(initcall_debug, initcall_debug, bool, 0644);
>
>



From heiko at sntech.de  Sun Aug 22 13:25:36 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 22 Aug 2021 22:25:36 +0200
Subject: [PATCH] arm64: dts: rockchip: Re-add interrupt-names for RK3399's
 vpu
In-Reply-To: <CAAEAJfDLvctAk3omLgFBBbzvufFKwSW5_cQZ+MjvyN4khGOe_w@mail.gmail.com>
References: <20210822115755.3171937-1-knaerzche@gmail.com>
 <CAAEAJfDLvctAk3omLgFBBbzvufFKwSW5_cQZ+MjvyN4khGOe_w@mail.gmail.com>
Message-ID: <24767661.6Emhk5qWAg@phil>

Hi,

Am Sonntag, 22. August 2021, 16:37:24 CEST schrieb Ezequiel Garcia:
> Hi Alex, Heiko,
> 
> On Sun, 22 Aug 2021 at 08:58, Alex Bee <knaerzche at gmail.com> wrote:
> >
> > Commit a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
> > intended to remove the interrupt-names property for mmu nodes, but it
> > also removed it for the vpu node in rk3399.dtsi. That makes the driver
> > fail probing currently.
> > Fix this by re-adding the property for this node.
> >
> > Fixes: a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
> 
> AFAICS a728c10dd62a removed lots of interrupt-names properties
> from devices other than IOMMU.
> 
> Maybe it's best to revert it?

where did you see more mistakes in it?

I.e. first of all, at least when grepping through my kernel history, I only see
  commit 53a05c8f6e8e ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
with a different hash and at least there I see a lot of iommu interrupt removals
and this one line removing the vpu irqs in error.

So from my glance at it, applying Alex' patch should solve the issue?

Heiko




From knaerzche at gmail.com  Sun Aug 22 14:24:35 2021
From: knaerzche at gmail.com (Alex Bee)
Date: Sun, 22 Aug 2021 23:24:35 +0200
Subject: [PATCH] arm64: dts: rockchip: Re-add interrupt-names for RK3399's
 vpu
In-Reply-To: <24767661.6Emhk5qWAg@phil>
References: <20210822115755.3171937-1-knaerzche@gmail.com>
 <CAAEAJfDLvctAk3omLgFBBbzvufFKwSW5_cQZ+MjvyN4khGOe_w@mail.gmail.com>
 <24767661.6Emhk5qWAg@phil>
Message-ID: <62e8d794-4125-68da-186e-80465179f506@gmail.com>

Hi Heiko, Hi Ezequiel,

Am 22.08.21 um 22:25 schrieb Heiko Stuebner:
> Hi,
>
> Am Sonntag, 22. August 2021, 16:37:24 CEST schrieb Ezequiel Garcia:
>> Hi Alex, Heiko,
>>
>> On Sun, 22 Aug 2021 at 08:58, Alex Bee <knaerzche at gmail.com> wrote:
>>> Commit a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
>>> intended to remove the interrupt-names property for mmu nodes, but it
>>> also removed it for the vpu node in rk3399.dtsi. That makes the driver
>>> fail probing currently.
>>> Fix this by re-adding the property for this node.
>>>
>>> Fixes: a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
>> AFAICS a728c10dd62a removed lots of interrupt-names properties
>> from devices other than IOMMU.
>>
>> Maybe it's best to revert it?
> where did you see more mistakes in it?
Yes, all the other removals in that commit are for iommu nodes.
>
> I.e. first of all, at least when grepping through my kernel history, I only see
>    commit 53a05c8f6e8e ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")

Oops, yes: I took the commit id of my local tree: could you please fix 
the commit message with the correct id, before applying?

Thanks,

Alex

> with a different hash and at least there I see a lot of iommu interrupt removals
> and this one line removing the vpu irqs in error.
>
> So from my glance at it, applying Alex' patch should solve the issue?
>
> Heiko
>
>


From valentin.schneider at arm.com  Sun Aug 22 15:16:10 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Sun, 22 Aug 2021 23:16:10 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87czqasn9u.wl-maz@kernel.org>
References: <20210814194737.GA3951530@roeck-us.net>
 <87sfzb7jeo.mognet@arm.com> <87eeav19mc.wl-maz@kernel.org>
 <87k0kk7w0c.mognet@arm.com> <87czqasn9u.wl-maz@kernel.org>
Message-ID: <878s0t6s7p.mognet@arm.com>

On 18/08/21 17:58, Marc Zyngier wrote:
> On Tue, 17 Aug 2021 01:30:43 +0100,
> Valentin Schneider <valentin.schneider at arm.com> wrote:
>> Are we guaranteed to have
>>
>>   .irq_ack \in {NULL, irq_chip_ack_parent}
>>
>> for all intermediate (!root) irqchips? I don't see why that wouldn't
>> be the case, and with that in mind what you described makes sense to
>> me.
>
> An intermediate layer is allowed to implement its own irq_ack that is
> not irq_chip_ack_parent, but it then has to call irq_chip_ack_parent
> itself.
>

Right, makes sense.

> There is the bizarre case of drivers/gpio/gpio-thunderx.c that changes
> the irqchip flow to use either handle_fasteoi_ack_irq or
> handle_fasteoi_mask_irq, which won't play very nicely with this.
> Someone said Cavium?
>

Humph...

I'm not familiar at all with the gpiolib irqchips, but I was under the
impression those would involve chained IRQs (it does appear to be the case
for the pl061 GPIOs on a Juno). For those, the innermost desc would be handled
via chained_irq_{enter, exit}() [!!!], and the outermost one via whatever
flow was installed by the relevant driver.

I can't easily grok what goes on between that gpio-thunderx.c driver and
gpiolib, but since that GPIO chip has

        .irq_eoi		= irq_chip_eoi_parent,

and

        girq->parent_domain =
                irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;

(GPIOs hooked to MSI-X? Do I want to know?)

I'm guessing it is *not* chained, which means the irq_set_handler_locked()
affects the entire stack :/

[!!!] Speaking of chained IRQs, I'm now thinking this series breaks them;
chained_irq_enter() + chained_irq_exit() will only issue an ->irq_eoi(),
skipping the ->irq_ack()... One more thing to add to the list!

>>
>> > In order to restore -next into a working state, I'm temporarily
>> > dropping this series. Hopefully, we can sort this out before the merge
>> > window and reinstate it.
>> >
>>
>> I'm away from any keyboard for most of this week, but I'll get to it by the
>> weekend.
>
> No worries, enjoy your break!
>

I sure did, Thanks!

>       M.
>
> --
> Without deviation from the norm, progress is not possible.


From knaerzche at gmail.com  Sun Aug 22 15:19:08 2021
From: knaerzche at gmail.com (Alex Bee)
Date: Mon, 23 Aug 2021 00:19:08 +0200
Subject: [PATCH] arm64: dts: rockchip: Fix GPU register width for RK3328
In-Reply-To: <20210623115926.164861-1-knaerzche@gmail.com>
References: <20210623115926.164861-1-knaerzche@gmail.com>
Message-ID: <c586d864-994f-2d24-9b29-2933b567be84@gmail.com>

Hi Heiko,

is there anything left to do for this one?

Same for:

https://patchwork.kernel.org/project/linux-rockchip/patch/20210623145918.187018-1-knaerzche at gmail.com/

and

https://patchwork.kernel.org/project/linux-rockchip/patch/20210623150208.187201-1-knaerzche at gmail.com/

Alex

Am 23.06.21 um 13:59 schrieb Alex Bee:
> As can be seen in RK3328's TRM the register range for the GPU is
> 0xff300000 to 0xff330000.
> It would (and does in vendor kernel) overlap with the registers of
> the HEVC encoder (node/driver do not exist yet in upstream kernel).
> See already existing h265e_mmu node.
>
> Fixes: 752fbc0c8da7 ("arm64: dts: rockchip: add rk3328 mali gpu node")
> Signed-off-by: Alex Bee <knaerzche at gmail.com>
> ---
>   arch/arm64/boot/dts/rockchip/rk3328.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> index 8c821acb21ff..da84be6f4715 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> @@ -599,7 +599,7 @@ saradc: adc at ff280000 {
>   
>   	gpu: gpu at ff300000 {
>   		compatible = "rockchip,rk3328-mali", "arm,mali-450";
> -		reg = <0x0 0xff300000 0x0 0x40000>;
> +		reg = <0x0 0xff300000 0x0 0x30000>;
>   		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
>   			     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
>   			     <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,


From brad at pensando.io  Sun Aug 22 17:54:10 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 17:54:10 -0700
Subject: [PATCH 7/8] arm64: dts: Add Pensando Elba SoC support
In-Reply-To: <20210304080355.cc37g7jagswro3dg@mobilestation>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-8-brad@pensando.io>
 <20210304080355.cc37g7jagswro3dg@mobilestation>
Message-ID: <CAK9rFnzBNjiUARvAe6k9DnDV-RCG9L0ARaiFVPQbUhv1UqTDRA@mail.gmail.com>

Hi Sergey,

On Thu, Mar 4, 2021 at 12:03 AM Serge Semin <fancer.lancer at gmail.com> wrote:
>
> On Wed, Mar 03, 2021 at 07:41:40PM -0800, Brad Larson wrote:
> > Add Pensando common and Elba SoC specific device nodes
> > and corresponding binding documentation.
>
> This also needs to be split up into sub-patches seeing these are
> unrelated changes like device bindings update, new platform DT file.
>
> Note text-based bindings are deprecated in favor of the DT schemas.
> Also note dts needs to pass dtbs_check validation. So all new HW/DT
> nodes need to be reflected in the DT-schemas. See [1] for details.
>
> [1] Documentation/devicetree/writing-schema.rst

Yes, patchset v2 was a first cut at organizing into sub-patches and in
v2 I used DT schemas for new files.  I will need to add additional new
sub-patches per review comments for v3 of the patchset.

> > diff --git a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml
> > index af7442f73881..645ae696ba24 100644
> > --- a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml
> > +++ b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml
> > @@ -122,7 +122,7 @@ unevaluatedProperties: false
> >  examples:
> >    - |
> >      emmc: mmc at 5a000000 {
>
> > -        compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc";
> > +        compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc", "pensando,elba-emmc";
>
> Alas it's not enough. New HW compatible strings shall be defined in the
> binding schema.

Based upon the next-20210818 version of cdns,sdhci.yaml below is the
proposed change.  In terms of defining new HW compatible strings is an
added example sufficient for pensando,elba-emmc?  There is no
additional definition for socionext,uniphier-sd4hc other than the
example in this file.

--- a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml
+++ b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml
@@ -15,9 +15,12 @@ allOf:
 properties:
   compatible:
-    items:
-      - enum:
-          - socionext,uniphier-sd4hc
+    oneOf:
+      - items:
+          - enum:
+              - socionext,uniphier-sd4hc
+              - pensando,elba-emmc
+          - const: cdns,sd4hc
       - const: cdns,sd4hc

   reg:
@@ -132,3 +135,17 @@ examples:
         mmc-hs400-1_8v;
         cdns,phy-dll-delay-sdclk = <0>;
     };
+  - |
+    emmc: mmc at 30440000 {
+        compatible = "pensando,elba-emmc", "cdns,sd4hc";
+        clocks = <&emmc_clk>;
+        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+        reg = <0x0 0x30440000 0x0 0x10000
+               0x0 0x30480044 0x0 0x4>;
+        cdns,phy-input-delay-sd-highspeed = <0x4>;
+        cdns,phy-input-delay-legacy = <0x4>;
+        cdns,phy-input-delay-sd-uhs-sdr50 = <0x6>;
+        cdns,phy-input-delay-sd-uhs-ddr50 = <0x16>;
+        cdns,mmc-ddr-1_8v;
+    };

> > diff --git a/Documentation/devicetree/bindings/spi/cadence-quadspi.txt b/Documentation/devicetree/bindings/spi/cadence-quadspi.txt
> > index 8ace832a2d80..dbb346b2b1d7 100644
> > --- a/Documentation/devicetree/bindings/spi/cadence-quadspi.txt
> > +++ b/Documentation/devicetree/bindings/spi/cadence-quadspi.txt
> > @@ -6,6 +6,7 @@ Required properties:
> >       For TI 66AK2G SoC - "ti,k2g-qspi", "cdns,qspi-nor".
> >       For TI AM654 SoC  - "ti,am654-ospi", "cdns,qspi-nor".
> >       For Intel LGM SoC - "intel,lgm-qspi", "cdns,qspi-nor".
>
> > +     For Pensando SoC - "pensando,cdns-qspi".
>
> What about converting this file to DT-schema and adding new HW
> bindings in there?

The file cadence-quadspi.txt has been converted to cdns,qspi-nor.yaml
in next-20210818.  This would be the updated change where
pensando,cdns-qspi is now pensando,elba-qspi to be more specific.

--- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
+++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
@@ -20,6 +20,7 @@ properties:
               - ti,k2g-qspi
               - ti,am654-ospi
               - intel,lgm-qspi
+              - pensando,elba-qspi
           - const: cdns,qspi-nor
       - const: cdns,qspi-nor

> > +     chosen {
>
> > +             stdout-path = "serial0:19200n8";
>
> Baudrate of 19200? So sad.(

The default baudrate for patchset v3 will be 115200  :-)

> > +&spi0 {
> > +     num-cs = <4>;
>
> > +     cs-gpios = <&spics 0 0>, <&spics 1 0>, <&porta 1 0>, <&porta 7 0>;
>
> Oh, you've got four peripheral SPI devices connected with only two native CS
> available. Hmm, then I don't really know a better way, but just to forget about
> the native DW APB CS functionality and activate the direct driving of
> all the CS-pins at the moment of the DW APB SPI controller probe
> procedure. Then indeed you'll need a custom CS function defined in the DW APB
> SPI driver to handle that.

Right, confusion was created by leaving in code implying that the two
native CS are supported.  CS0 is used just to start the serial engine.
The existing dw_spi_set_cs() function works fine resulting in this
implementation.

static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
{
        spi->chip_select = 0;
        dw_spi_set_cs(spi, enable);
}

> > +             spics: spics at 307c2468 {
> > +                     compatible = "pensando,elba-spics";
> > +                     reg = <0x0 0x307c2468 0x0 0x4>;
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +             };
>
> So that GPIO-controller is just a single register which provides a way
> to toggle the DW APB SPI CS-mode together with their output value.
> If so and seeing there are a few more tiny spaces of config
> registers added to eMMC, PCI, etc DT node, I suppose all of them
> belong to some bigger config space of the SoC. Thus I'd suggest to at
> least implement them as part of a System Controller DT node. Then use
> that device service to switch on/off corresponding functionality.
> See [2] and the rest of added to the kernel DTS files with
> syscon-nodes for example.
>
> [2] Documentation/devicetree/bindings/mfd/syscon.yaml
>
> -Sergey
>

I've looked at the syscon documentation, other drivers that use it and
tried the below proposed example with variations.  The result is Elba
works ok for its four SPI devices but the host has a machine check
which must be due to a pcie access error.  From another thread on this
topic here is the recommended change to using syscon.

> Rob, please see here having a small sized reg-space one more time.
> Having so many small-sized registers scattered around the dts file
> makes me thinking that most of them likely belong to some bigger
> block like "System Controller". If so then there must be a main node
> compatible with "syscon" device, which phandle would be referenced in
> the particular device nodes. Like this:
>
> \ {
>         soc {
>                 syscon: syscon at 307c0000 {
>                         compatible = "pensando,elba-sys-con", "syscon", "simple-mfd";
>                         reg = <0x0 0x307c0000 0x0 0x10000>;
>
>                         spics: spics at 307c2468 {
>                                 compatible = "pensando,elba-spics";
>                                 gpio-controller;
>                                 #gpio-cells = <2>;
>                         };
>                 };
>                 pcie at 307c2480 {
>                         compatible = "pensando,pcie";
>                         reg = <0x0 0x20000000 0x0 0x00380000>; /* PXB Base */
>
>                         syscon = <&syscon>;
>                 };
>
>                 /* etc */
>         };
> };

The current pcie node is

>         pcie at 307c2480 {
>                 compatible = "pensando,pcie";
>                 reg = <0x0 0x307c2480 0x0 0x4           /* MS CFG_WDT */
>                        0x0 0x1400 0x0 0x10              /* WDT0 */
>                        0x0 0x20000000 0x0 0x380000>;    /* PXB Base */
>         };

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:05:04 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:05:04 -0700
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CACRpkdbQD6p7fbGtuu1c92uXfSFDCTwqjqsXHpgnD5Lg4v0Okw@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CACRpkdbQD6p7fbGtuu1c92uXfSFDCTwqjqsXHpgnD5Lg4v0Okw@mail.gmail.com>
Message-ID: <CAK9rFnyf3WLSPe8A=WWCBUqs3htkAmhDQq0ftcEOq_fnenWQPA@mail.gmail.com>

Hi Linus,

On Thu, Mar 4, 2021 at 12:29 AM Linus Walleij <linus.walleij at linaro.org> wrote:
> On Thu, Mar 4, 2021 at 4:42 AM Brad Larson <brad at pensando.io> wrote:
>
> > This GPIO driver is for the Pensando Elba SoC which
> > provides control of four chip selects on two SPI busses.
[...]
> > +#include <linux/gpio.h>
>
> Use this in new drivers:
> #include <linux/gpio/driver.h>

The updated patchset will use linux/gpio/driver.h

> > + * pin:             3            2        |       1            0
> > + * bit:         7------6------5------4----|---3------2------1------0
> > + *     cs1  cs1_ovr  cs0  cs0_ovr |  cs1  cs1_ovr  cs0  cs0_ovr
> > + *                ssi1            |             ssi0
> > + */
> > +#define SPICS_PIN_SHIFT(pin)   (2 * (pin))
> > +#define SPICS_MASK(pin)                (0x3 << SPICS_PIN_SHIFT(pin))
> > +#define SPICS_SET(pin, val)    ((((val) << 1) | 0x1) << SPICS_PIN_SHIFT(pin))
>
> So 2 bits per GPIO line in one register? (Nice doc!)
>
> > +struct elba_spics_priv {
> > +       void __iomem *base;
> > +       spinlock_t lock;
> > +       struct gpio_chip chip;
> > +};
> > +
> > +static int elba_spics_get_value(struct gpio_chip *chip, unsigned int pin)
> > +{
> > +       return -ENXIO;
> > +}
>
> Write a comment that the chip only supports output mode,
> because it repurposes SPI CS pins as generic GPIO out,
> maybe at the top of the file?

The top of the file will look like this in the updated patchset.

 * Pensando Elba ASIC SPI chip select driver.  The SoC supports output
 * direction only as it uses a generic GPIO pin for SPI CS.

> I suppose these systems also actually (ab)use the SPI cs
> for things that are not really SPI CS? Because otherwise
> this could just be part of the SPI driver (native chip select).

The SPI cs are not used for any other purpose, we needed four chip
selects and native DW supports two.

> > +static const struct of_device_id ebla_spics_of_match[] = {
> > +       { .compatible = "pensando,elba-spics" },
>
> Have you documented this?

Yes as part of patchset v2: [PATCH v2 11/13] dt-bindings: gpio: Add
Pensando Elba SoC support
which documents "pensando,elba-spics" in new file
bindings/gpio/pensando,elba-spics.yaml.

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:05:52 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:05:52 -0700
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CACRpkdZroi+_oHqipS71MAGif190y7jWU5Myf55vz=_um4w5cQ@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CACRpkdbQD6p7fbGtuu1c92uXfSFDCTwqjqsXHpgnD5Lg4v0Okw@mail.gmail.com>
 <20210304091025.ny52qjm7wbfvmjgl@mobilestation>
 <CACRpkdZroi+_oHqipS71MAGif190y7jWU5Myf55vz=_um4w5cQ@mail.gmail.com>
Message-ID: <CAK9rFnzDZ4MNm68AJ75g7zegLD-7UMHyoVR-4ssitYTTEeQm5g@mail.gmail.com>

Hi Linus,

On Thu, Mar 4, 2021 at 5:38 AM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Thu, Mar 4, 2021 at 10:10 AM Serge Semin <fancer.lancer at gmail.com> wrote:
> > On Thu, Mar 04, 2021 at 09:29:33AM +0100, Linus Walleij wrote:
>
> > > > + * pin:             3            2        |       1            0
> > > > + * bit:         7------6------5------4----|---3------2------1------0
> > > > + *             cs1  cs1_ovr  cs0  cs0_ovr |  cs1  cs1_ovr  cs0  cs0_ovr
> > > > + *                        ssi1            |             ssi0
> > > > + */
> > > > +#define SPICS_PIN_SHIFT(pin)   (2 * (pin))
> > > > +#define SPICS_MASK(pin)                (0x3 << SPICS_PIN_SHIFT(pin))
> > > > +#define SPICS_SET(pin, val)    ((((val) << 1) | 0x1) << SPICS_PIN_SHIFT(pin))
> > >
> >
> > > So 2 bits per GPIO line in one register? (Nice doc!)
> >
> > I suppose the first bit is the CS-pin-override flag. So when it's set
> > the output is directly driven by the second bit, otherwise the
> > corresponding DW APB SPI controller drives it. That's how the
> > multiplexing is implemented here.
>
> If these output lines are so tightly coupled to the SPI block
> and will not be used for any other GPO (general purpose output)
> I think it makes more sense to bundle the handling into the
> DW SPI driver, and activate it based on the Elba compatible
> string (if of_is_compatible(...)).
>
> I am a bit cautious because it has happened in the past that
> people repurpose CS lines who were originally for SPI CS
> to all kind of other purposes, such as a power-on LED and
> in that case it needs to be a separate GPIO driver. So the
> author needs to have a good idea about what is a realistic
> use case here.

The gpio pins being used for the Elba SoC SPI CS are dedicated to this
function.  Are you recommending that the code in
drivers/gpio/gpio-elba-spics.c be integrated into
drivers/spi/spi-dw-mmio.c?

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:06:51 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:06:51 -0700
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <TU4PR8401MB1055D51E8D1B48DC7D7294E3AB979@TU4PR8401MB1055.NAMPRD84.PROD.OUTLOOK.COM>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <TU4PR8401MB1055D51E8D1B48DC7D7294E3AB979@TU4PR8401MB1055.NAMPRD84.PROD.OUTLOOK.COM>
Message-ID: <CAK9rFnz+PksEFjUh5ZpRLyvk21ZpVTxtwDYn_OhOEBJWjEYe7w@mail.gmail.com>

Hi Elliott,

On Thu, Mar 4, 2021 at 12:44 PM Elliott, Robert (Servers)
<elliott at hpe.com> wrote:
[...]
> > +config GPIO_ELBA_SPICS
> > +     bool "Pensando Elba SPI chip-select"
> > +     depends on ARCH_PENSANDO_ELBA_SOC
> > +     help
> > +       Say yes here to support the Pensndo Elba SoC SPI chip-select
> > driver
>
> Pensndo should be Pensando

Fixed the typo, thanks.

> > diff --git a/drivers/gpio/gpio-elba-spics.c b/drivers/gpio/gpio-elba-spics.c
> > + * Pensando Elba ASIC SPI chip select driver
> ...
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("Elba SPI chip-select driver");
>
> I think it's conventional to include the company name there, so
> start that with "Pensando Elba"

Ok, thanks.  BTW I deleted these lines as I should have used
builtin_platform_driver() and not a loadable module.

> Also, "SoC" and "ASIC" are sometimes included after Elba, but sometimes
> are not. Consistency might be helpful.
>
> > +static const struct of_device_id ebla_spics_of_match[] = {
> ...
> > +             .of_match_table = ebla_spics_of_match,
>
> ebla should be elba

Fixed the typo and using SoC which is more accurate.

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:07:48 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:07:48 -0700
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <605880ad-6c12-bf1d-45f8-ef70181e4eec@canonical.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <605880ad-6c12-bf1d-45f8-ef70181e4eec@canonical.com>
Message-ID: <CAK9rFnxhv88Bc9A_ksFUaKgFp7acxnxM7ujR1GrTCPNLLEwHBw@mail.gmail.com>

Hi Krzysztof,

On Fri, Mar 5, 2021 at 3:25 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 04/03/2021 04:41, Brad Larson wrote:
> > This GPIO driver is for the Pensando Elba SoC which
> > provides control of four chip selects on two SPI busses.
[...]
> > +     ret = devm_gpiochip_add_data(&pdev->dev, &p->chip, p);
> > +     if (ret) {
> > +             dev_err(&pdev->dev, "unable to add gpio chip\n");
> > +             return ret;
> > +     }
> > +
> > +     dev_info(&pdev->dev, "elba spics registered\n");
>
> Don't print trivial probe results, unless you print here something
> useful. If you need it for debugging, keep it dev_dbg.

Removed that extraneous logging

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:08:13 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:08:13 -0700
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CAMuHMdUsFb-qpssVXkxv0gV8qpi6mUNx+3o+ZUhc5UMCKppzrQ@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CAMuHMdUsFb-qpssVXkxv0gV8qpi6mUNx+3o+ZUhc5UMCKppzrQ@mail.gmail.com>
Message-ID: <CAK9rFnwAiKgb-RJGipVCqSZmeCvKfUA+zQxG9TPDXV6CkTvs6Q@mail.gmail.com>

Hi Geert,

On Fri, Mar 5, 2021 at 5:57 AM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hi Brad,
>
> On Thu, Mar 4, 2021 at 4:59 AM Brad Larson <brad at pensando.io> wrote:
> > This GPIO driver is for the Pensando Elba SoC which
> > provides control of four chip selects on two SPI busses.
[...]
> > +config GPIO_ELBA_SPICS
> > +       bool "Pensando Elba SPI chip-select"
> > +       depends on ARCH_PENSANDO_ELBA_SOC
>
> Any specific reason this can't be "... || COMPILE_TEST"?

Added COMPILE_TEST

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:10:16 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:10:16 -0700
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CAHp75VcG9KajNpDbewDq7QzotB6t7MfwiGk15FaobX+cmMVSzg@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CAHp75VcG9KajNpDbewDq7QzotB6t7MfwiGk15FaobX+cmMVSzg@mail.gmail.com>
Message-ID: <CAK9rFnxgdyxM11n6PaqG_phuDMXnHYWSm+Xaqg89dMYCF3CN8g@mail.gmail.com>

Hi Andy,

On Sun, Mar 7, 2021 at 11:21 AM Andy Shevchenko
<andy.shevchenko at gmail.com> wrote:
>
> On Thu, Mar 4, 2021 at 4:40 PM Brad Larson <brad at pensando.io> wrote:
> >
> > This GPIO driver is for the Pensando Elba SoC which
> > provides control of four chip selects on two SPI busses.
>
> I will try to avoid repeating otheris in their reviews, but my comments below.
>
> ...
>
> > +config GPIO_ELBA_SPICS
> > +       bool "Pensando Elba SPI chip-select"
>
> Can't it be a module? Why?
>
> > +       depends on ARCH_PENSANDO_ELBA_SOC
> > +       help
> > +         Say yes here to support the Pensndo Elba SoC SPI chip-select driver
>
> Please give more explanation what it is and why users might need it,
> and also tell users how the module will be named (if there is no
> strong argument why it can't be a  module).
>
> ...
>
> > +#include <linux/of.h>
>
> It's not used here, but you missed mod_devicetable.h.

Based on the feedback I realized this should not be a loadable module.
I should be using builtin_platform_driver(elba_spics_driver).
Currently I have this for gpio/Kconfig

config GPIO_ELBA_SPICS
        def_bool y
        depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST

> > +/*
> > + * pin:             3            2        |       1            0
> > + * bit:         7------6------5------4----|---3------2------1------0
> > + *     cs1  cs1_ovr  cs0  cs0_ovr |  cs1  cs1_ovr  cs0  cs0_ovr
> > + *                ssi1            |             ssi0
> > + */
> > +#define SPICS_PIN_SHIFT(pin)   (2 * (pin))
> > +#define SPICS_MASK(pin)                (0x3 << SPICS_PIN_SHIFT(pin))
>
> > +#define SPICS_SET(pin, val)    ((((val) << 1) | 0x1) << SPICS_PIN_SHIFT(pin))
>
> Isn't it easier to define as ((value) << (2 * (pin) + 1) | BIT(2 * (pin)))

Both are functionally correct.  I don't have a preference, do you want
this change?

> > +struct elba_spics_priv {
> > +       void __iomem *base;
> > +       spinlock_t lock;
>
> > +       struct gpio_chip chip;
>
> If you put it as a first member a container_of() becomes a no-op. OTOH
> dunno if there is any such container_of() use in the code.

There is no use of container_of() for this structure

> > +static int elba_spics_get_value(struct gpio_chip *chip, unsigned int pin)
> > +{
> > +       return -ENXIO;
>
> Hmm... Is it really acceptable error code here?

No it's not, thanks.  Changed to -ENOTSUPP as gpio output direction
only is supported.

> > +static int elba_spics_direction_input(struct gpio_chip *chip, unsigned int pin)
> > +{
> > +       return -ENXIO;
>
> Ditto.

Changed to ENOTSUPP

> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       p->base = devm_ioremap_resource(&pdev->dev, res);
>
> p->base = devm_platform_ioremap_resource(pdev, 0);

Changed to single call to devm_platform_ioremap_resource(pdev, 0)

> > +       if (IS_ERR(p->base)) {
>
> > +               dev_err(&pdev->dev, "failed to remap I/O memory\n");
>
> Duplicate noisy message.

Removed extra log message

> > +               return PTR_ERR(p->base);
> > +       }
>
> > +       ret = devm_gpiochip_add_data(&pdev->dev, &p->chip, p);
> > +       if (ret) {
> > +               dev_err(&pdev->dev, "unable to add gpio chip\n");
>
> > +               return ret;
> > +       }
> > +
> > +       dev_info(&pdev->dev, "elba spics registered\n");
> > +       return 0;
>
> if (ret)
>   dev_err(...);
> return ret;

Yes, made this change and will include in v3 patchset

--- a/drivers/gpio/gpio-elba-spics.c
+++ b/drivers/gpio/gpio-elba-spics.c
@@ -91,13 +91,9 @@ static int elba_spics_probe(struct platform_device *pdev)
        ret = devm_gpiochip_add_data(&pdev->dev, &p->chip, p);
-       if (ret) {
+       if (ret)
                dev_err(&pdev->dev, "unable to add gpio chip\n");
-               return ret;
-       }
-
-       dev_info(&pdev->dev, "elba spics registered\n");
-       return 0;
+       return ret;

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:13:50 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:13:50 -0700
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CAHp75VdfrJ3JV_gL3xCLHOiw6Tj-5Ep7z5JKWUFKFbUt8gobcw@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CAHp75VcG9KajNpDbewDq7QzotB6t7MfwiGk15FaobX+cmMVSzg@mail.gmail.com>
 <CAK9rFnwrA=W2Vk5yFwG4N_WS=eBXXnhtexA+tqgAYb6xOAO4oQ@mail.gmail.com>
 <CAHp75VdfrJ3JV_gL3xCLHOiw6Tj-5Ep7z5JKWUFKFbUt8gobcw@mail.gmail.com>
Message-ID: <CAK9rFnx--z_pr_yR6CqGsH04ddwUtx4rxc7MxNNmy7ZSF86+Mg@mail.gmail.com>

Hi Andy,

On Mon, Mar 29, 2021 at 3:40 AM Andy Shevchenko
<andy.shevchenko at gmail.com> wrote:
>
> On Mon, Mar 29, 2021 at 4:19 AM Brad Larson <brad at pensando.io> wrote:
> > On Sun, Mar 7, 2021 at 11:21 AM Andy Shevchenko
> > <andy.shevchenko at gmail.com> wrote:
> > > On Thu, Mar 4, 2021 at 4:40 PM Brad Larson <brad at pensando.io> wrote:
>
> ...
>
> > > > +config GPIO_ELBA_SPICS
> > > > +       bool "Pensando Elba SPI chip-select"
> > >
> > > Can't it be a module? Why?
> >
> > All Elba SoC based platforms require this driver to be built-in to boot and
> > removing the module would result in a variety of exceptions/errors.
>
> Needs to be at least in the commit message.
>
>
>
> > > > +       depends on ARCH_PENSANDO_ELBA_SOC
> > > > +       help
> > > > +         Say yes here to support the Pensndo Elba SoC SPI chip-select driver
> > >
> > > Please give more explanation what it is and why users might need it,
> > > and also tell users how the module will be named (if there is no
> > > strong argument why it can't be a  module).
> > >
> > Fixed the typo.
>
> Yeah, according to the above, you better elaborate what this module is
> and why people would need it.
> Also can be a good hint to add
> default ARCH_MY_COOL_PLATFORM

Regarding the above module question and Kconfig definition, since I
first looked at this and reviewed the comments I realized I should be
using builtin.  The file gpio/Kconfig is currently this

config GPIO_ELBA_SPICS
        def_bool y
        depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST

> ...
>
> > > > +#include <linux/of.h>
> > >
> > > It's not used here, but you missed mod_devicetable.h.
> >
> > Removed <linux/of.h>.  There is no dependency on mod_devicetable.h.
>
> What do you mean? You don't use data structures from that?
> of_device_id or other ID structures are defined there. Your module
> works without them?
>
I typed the wrong filename.  I do still have <linux/of.h>

> > > > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > > +       p->base = devm_ioremap_resource(&pdev->dev, res);
> > >
> > > p->base = devm_platform_ioremap_resource(pdev, 0);
> >
> > Implementation follows devm_ioremap_resource() example in lib/devres.c.
>
> So? How does this make it impossible to address my comment?

I was simply stating that I followed the recommended API per the
source code although I don't recall if I was looking at 4.14, 5.10 or
linux-next at the time.  Changed to using
devm_platform_ioremap_resource().

> > > > +       if (IS_ERR(p->base)) {
> > >
> > > > +               dev_err(&pdev->dev, "failed to remap I/O memory\n");
> > >
> > > Duplicate noisy message.
> > >
> > > > +               return PTR_ERR(p->base);
> > > > +       }

Yep, I've removed the extraneous log message.

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:17:05 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:17:05 -0700
Subject: [PATCH 3/8] spi: dw: Add support for Pensando Elba SoC SPI
In-Reply-To: <20210304064433.vqyqg3byedvc4quz@mobilestation>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-4-brad@pensando.io>
 <20210304064433.vqyqg3byedvc4quz@mobilestation>
Message-ID: <CAK9rFnzwtxhg9DBW7=s9FaOwWNCstfRW5T_MjQiM51GxiM6ZyA@mail.gmail.com>

Hi Sergey,

Thanks again for the reviews.  I've been able to work on this recently
and test the changes using 5.10.28 on a production server.  I'm going
back to the beginning to reply to each comment and work towards
closure of open issues before preparing patchset v3 which will need to
be re-done against the latest linux-next.

On Wed, Mar 3, 2021 at 10:44 PM Serge Semin <fancer.lancer at gmail.com> wrote:
>
> Hello Brad.
> Thanks for the patch. See my comments below.
>
> On Wed, Mar 03, 2021 at 07:41:36PM -0800, Brad Larson wrote:
> > The Pensando Elba SoC uses a GPIO based chip select
> > for two DW SPI busses with each bus having two
> > chip selects.
>
> I see a contradiction here. Normally GPIO-based chip-select is a
> property of a platform, but not a SoC/CPU/MCU/etc. Most of the time
> SoC SPI interfaces still get to have native CS pins, while at some
> platform configurations (like in case of DW APB SPI, which doesn't
> provide a way to directly toggle its native CSs) it's easier or even
> safer to use GPIOs as CS signals. Of course theoretically a SoC could
> be synthesized so it doesn't have native CS output pins, but only some
> virtual internal CS flags, but I've never seen such. Anyway according
> to the custom CS method below it's not your case because you still
> provide support for SPI-devices handled by native CS (else branch in
> the if (spi->cs_gpiod) {} else {} statement).

The native DW CS is not supported, that code is removed which caused
the confusion.  The existing dw_spi_set_cs() works fine with the
updated version of this function being

/*
 * Using a GPIO-based chip-select, the DW SPI controller still needs
 * its own CS bit selected to start the serial engine.  On Elba the
 * specific CS doesn't matter, so use CS0.
 */
static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
{
        spi->chip_select = 0;
        dw_spi_set_cs(spi, enable);
}

which is much better than the original version shown below

> > +static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
> > +{
> > +     struct dw_spi *dws = spi_master_get_devdata(spi->master);
> > +
> > +     if (!enable) {
> > +             if (spi->cs_gpiod) {
> > +                     /*
> > +                      * Using a GPIO-based chip-select, the DW SPI
> > +                      * controller still needs its own CS bit selected
> > +                      * to start the serial engine.  On Elba the specific
> > +                      * CS doesn't matter, so use CS0.
> > +                      */
> > +                     dw_writel(dws, DW_SPI_SER, BIT(0));
> > +             } else {
> > +                     /*
> > +                      * Using the intrinsic DW chip-select; set the
> > +                      * appropriate CS.
> > +                      */
> > +                     dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select));
> > +             }
> > -     } else
>   +     } else {
> > +             dw_writel(dws, DW_SPI_SER, 0);
>   +     } /* See [1] */
> > +}
>
> The custom CS-method above doesn't look much different from the
> dw_spi_set_cs() method defined in the spi-dw-core.o driver, except
> having at least two problems:
> 1) It assumes that "enable" argument means the CS-enabling flag, while
> in fact it's the CS-level which depending on the SPI_CS_HIGH flag
> set/cleared will be 1/0 respectively if CS is supposed to be enabled.
> That aspect has already been fixed in the dw_spi_set_cs() method.
> 2) The method enables CS[0] if GPIO-CS is used for a particular SPI
> device. That will cause problems for a GPIO/native CS intermixed case
> of having for instance one SPI-device connected to native CS[0] and
> another one - to a GPIO. So trying to communicate with the second SPI
> device you'll end up having the native CS[0] activated too thus
> having an SPI transfer sent to two SPI-device at the same time.
> Of course that's not what you'd want.
>
> Anyway I don't really see why you even need a custom CS method here. A
> generic method dw_spi_set_cs() shall work for your SPI interface.
> If I am wrong, please explain why. Did you try the generic CS method
> on your platform?
>
> [1] Placing Braces and Spaces. Chapter 3). Documentation/process/coding-style.rst

Yes, exactly.  The generic method dw_spi_set_cs() works ok and
correctly handles active high/low.

> > +static int dw_spi_elba_init(struct platform_device *pdev,
> > +                         struct dw_spi_mmio *dwsmmio)
> > +{
> > +     dwsmmio->dws.set_cs = dw_spi_elba_set_cs;
> > +
> > +     return 0;
> > +}
> > +
> >  static int dw_spi_mmio_probe(struct platform_device *pdev)
> >  {
> >       int (*init_func)(struct platform_device *pdev,
> > @@ -351,6 +383,7 @@ static const struct of_device_id dw_spi_mmio_of_match[] = {
> >       { .compatible = "intel,keembay-ssi", .data = dw_spi_keembay_init},
> >       { .compatible = "microchip,sparx5-spi", dw_spi_mscc_sparx5_init},
> >       { .compatible = "canaan,k210-spi", dw_spi_canaan_k210_init},
>
> > +     { .compatible = "pensando,elba-spi", .data = dw_spi_elba_init },
>
> If you agree with me and remove the custom CS-method defined above in
> this patch, then all you'll need is just to add "pensando,elba-spi" here
> with generic init-callback set - dw_spi_dw_apb_init.

The existing dw_spi_set_cs() is now being used.  Using
dw_spi_dw_apb_init results in every spi transfer failing which is why
dw_spi_elba_init() is still proposed which results in set_cs calling
dw_spi_elba_set_cs().

> Finally defining new compatible string requires the bindings update.
> In the framework of DW APB SPI interface they are defined in:
> Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
> So you need to have that DT-schema accordingly altered.
>
> The bindings note concerns the rest of the updates in your patchset too.
>
> -Sergey

Patchset v2 separated out the bindings updates.  There will be more
bindings needed for v3 of the patchset.  I won't be sending v3 until
all discussions are resolved.

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:18:29 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:18:29 -0700
Subject: [PATCH v2 00/13] Support Pensando Elba SoC
In-Reply-To: <20210331161738.rc6oecz25z6ywqhl@mobilestation>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210331161738.rc6oecz25z6ywqhl@mobilestation>
Message-ID: <CAK9rFnxrY7XGJ6QAxH0Wx7X9dQ_9RYe8uapgpRs6LWBBrE=ufA@mail.gmail.com>

Hi Sergey,

On Wed, Mar 31, 2021 at 9:17 AM Serge Semin <fancer.lancer at gmail.com> wrote:
>
> Hi Brad
>
> On Sun, Mar 28, 2021 at 06:59:25PM -0700, Brad Larson wrote:
> > This series enables support for Pensando Elba SoC based platforms.
> > The Elba SoC has the following features:
[...]
> > See below for an overview of changes since v1.
> >
> > == Patch overview ==
> >
> > - 01    Fix typo, return code value and log message.
> > - 03    Remove else clause, intrinsic DW chip-select is never used.
> > - 08-11 Split out dts and bindings to sub-patches
> > - 10    Converted existing cadence-quadspi.txt to YAML schema
> > - 13    New driver should use <linux/gpio/driver.h>
>
> That would be super-useful if each changelog entry was also added to the
> individual patches below "---" splitter.

I'll do that for the v3 patchset once the discussions are resolved.

Regards,
Brad


From chiawei_wang at aspeedtech.com  Sun Aug 22 18:21:15 2021
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Mon, 23 Aug 2021 01:21:15 +0000
Subject: [PATCH v2 1/5] dt-bindings: aspeed: Add eSPI controller
In-Reply-To: <YSAKM16WLx4UWIQu@robh.at.kernel.org>
References: <20210819080040.31242-1-chiawei_wang@aspeedtech.com>
 <20210819080040.31242-2-chiawei_wang@aspeedtech.com>
 <YSAKM16WLx4UWIQu@robh.at.kernel.org>
Message-ID: <HK0PR06MB3779C39208BDFEB6A80006AF91C49@HK0PR06MB3779.apcprd06.prod.outlook.com>

Hi Rob,

> -----Original Message-----
> From: Rob Herring <robh at kernel.org>
> Sent: Saturday, August 21, 2021 4:02 AM
> To: ChiaWei Wang <chiawei_wang at aspeedtech.com>
> Cc: joel at jms.id.au; andrew at aj.id.au; linux-aspeed at lists.ozlabs.org;
> openbmc at lists.ozlabs.org; devicetree at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Ryan Chen
> <ryan_chen at aspeedtech.com>
> Subject: Re: [PATCH v2 1/5] dt-bindings: aspeed: Add eSPI controller
> 
> On Thu, Aug 19, 2021 at 04:00:36PM +0800, Chia-Wei Wang wrote:
> > Add dt-bindings for Aspeed eSPI controller
> >
> > Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
> > ---
> >  .../devicetree/bindings/soc/aspeed/espi.yaml  | 158
> > ++++++++++++++++++
> >  1 file changed, 158 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> > b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> > new file mode 100644
> > index 000000000000..fec3d37f3ffd
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> > @@ -0,0 +1,158 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) # #
> > +Copyright (c) 2021 Aspeed Technology Inc.
> > +%YAML 1.2
> > +---
> > +$id: "http://devicetree.org/schemas/soc/aspeed/espi.yaml#"
> > +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> > +
> > +title: Aspeed eSPI Controller
> > +
> > +maintainers:
> > +  - Chia-Wei Wang <chiawei_wang at aspeedtech.com>
> > +  - Ryan Chen <ryan_chen at aspeedtech.com>
> > +
> > +description:
> > +  Aspeed eSPI controller implements a slave side eSPI endpoint device
> > +  supporting the four eSPI channels, namely peripheral, virtual wire,
> > +  out-of-band, and flash.
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - enum:
> > +          - aspeed,ast2500-espi
> > +          - aspeed,ast2600-espi
> > +      - const: simple-mfd
> > +      - const: syscon
> 
> Is this really 2 sub devices that could be used individually or in a different
> combination? If not, then I'd make all this 1 node.

espi-mmbi has individual function and control registers.
However, espi-mmbi is also a feature extended based on the memory cycle of eSPI peripheral channel.
Thereby, it has dependency on the eSPI channel initialization conducted by espi-ctrl.
The scenario is similar to the lpc-ctrl and other lpc-xxx drivers of Aspeed SoCs.

Chiawei


From brad at pensando.io  Sun Aug 22 18:22:39 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:22:39 -0700
Subject: [PATCH v2 01/13] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CAHp75VczOyiD+F9MDqdZdZGhAFF5Kh5U7CAmTj+i-Fy7KZsEog@mail.gmail.com>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-2-brad@pensando.io>
 <CAHp75VczOyiD+F9MDqdZdZGhAFF5Kh5U7CAmTj+i-Fy7KZsEog@mail.gmail.com>
Message-ID: <CAK9rFnyu5ZutLGM+OFAANOfcrC5OSVjcaoy_rbq0m+WafDhqoA@mail.gmail.com>

Hi Andy,

On Mon, Mar 29, 2021 at 3:41 AM Andy Shevchenko
<andy.shevchenko at gmail.com> wrote:
>
> On Mon, Mar 29, 2021 at 5:01 AM Brad Larson <brad at pensando.io> wrote:
> >
> > This GPIO driver is for the Pensando Elba SoC which
> > provides control of four chip selects on two SPI busses.
[...]
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("Pensando Elba SoC SPI chip-select driver");
>
> It's funny, you told it can't be a module and you add a dead code. Be
> somehow consistent, please.

Yes the code was not consistent with statement that the module cannot
being loadable in my reply.  I had not used builtin_platform_driver()
previously.  The updated patchset will be changed to this for the
driver.

-module_platform_driver(elba_spics_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Elba SPI chip-select driver");
+builtin_platform_driver(elba_spics_driver);

where drivers/gpio/Kconfig could be changed to this

--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -241,10 +241,8 @@ config GPIO_EIC_SPRD
          Say yes here to support Spreadtrum EIC device.

 config GPIO_ELBA_SPICS
-       bool "Pensando Elba SPI chip-select"
+       def_bool y
        depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST
-       help
-         Say yes here to support the Pensando Elba SoC SPI chip-select driver

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:24:35 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:24:35 -0700
Subject: [PATCH v2 01/13] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <20210331181041.me5mqqagtml355vk@mobilestation>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-2-brad@pensando.io>
 <20210331181041.me5mqqagtml355vk@mobilestation>
Message-ID: <CAK9rFnxKHmzoZhbc-FK_BML-2rCY64x4REhkdZE+TWYm+VWHFg@mail.gmail.com>

Hi Sergey,

On Wed, Mar 31, 2021 at 11:10 AM Serge Semin <fancer.lancer at gmail.com> wrote:
>
> On Sun, Mar 28, 2021 at 06:59:26PM -0700, Brad Larson wrote:
> > This GPIO driver is for the Pensando Elba SoC which
> > provides control of four chip selects on two SPI busses.
[...]
> > +static int elba_spics_probe(struct platform_device *pdev)
> > +{
> > +     struct elba_spics_priv *p;
> > +     struct resource *res;
> > +     int ret = 0;
> > +
> > +     p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
> > +     if (!p)
> > +             return -ENOMEM;
> > +
>
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +     p->base = devm_ioremap_resource(&pdev->dev, res);
>
> In accordance with the DTS-node this is just a single register
> 0x307c2468-0x307c24C picked from some bigger block, which most likely
> belongs to something like a system controller. PCIe node has got
> another register from there "0x307c2480-0x307c2484/* MS CFG_WDT */",
> and some BSM device too "0x307c2080-0x307c2084". Please consider using
> syscon instead of directly requesting the resource here.
>
> -Sergey

I've looked into a few syscon based implementations which resulted in
a regressions to include Elba spi probe failure and host machine check
trying to perform PCIe access to Elba SoC.  I like the idea of
refactoring to use syscon but I don't have a functional solution to do
so.

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:25:35 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:25:35 -0700
Subject: [PATCH v2 03/13] spi: dw: Add support for Pensando Elba SoC SPI
In-Reply-To: <CAHp75VfmSKVRB+Rm+sWDjZaJwdX4qt56Qj6aehe4YnA5d6+a6Q@mail.gmail.com>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-4-brad@pensando.io>
 <CAHp75VfmSKVRB+Rm+sWDjZaJwdX4qt56Qj6aehe4YnA5d6+a6Q@mail.gmail.com>
Message-ID: <CAK9rFnzdPpVBZu8uxHU04pak9OxPMjFqAt_qnPQY2qK2WK4rTQ@mail.gmail.com>

Hi Andy,

On Mon, Mar 29, 2021 at 3:43 AM Andy Shevchenko
<andy.shevchenko at gmail.com> wrote:
>
> On Mon, Mar 29, 2021 at 5:01 AM Brad Larson <brad at pensando.io> wrote:
> >
> > The Pensando Elba SoC uses a GPIO based chip select
> > for two DW SPI busses with each bus having two
> > chip selects.
...
> > +static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
> > +{
> > +       struct dw_spi *dws = spi_master_get_devdata(spi->master);
> > +
> > +       if (!enable) {
>
> Can you use positive conditional?

This function has been re-written to use the existing dw_spi_set_cs().
This is what I currently plan for the v3 patchset.

static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
{
        spi->chip_select = 0;
        dw_spi_set_cs(spi, enable);
}

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:26:56 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:26:56 -0700
Subject: [PATCH v2 03/13] spi: dw: Add support for Pensando Elba SoC SPI
In-Reply-To: <20210331180018.jir2vusuf3sbare5@mobilestation>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-4-brad@pensando.io>
 <20210331180018.jir2vusuf3sbare5@mobilestation>
Message-ID: <CAK9rFnxs_8fFnQPCDuW-=w36zq8+TStRVSBijjkGsEaMF-R6MA@mail.gmail.com>

Hi Sergey,

On Wed, Mar 31, 2021 at 11:00 AM Serge Semin <fancer.lancer at gmail.com> wrote:
>
> On Sun, Mar 28, 2021 at 06:59:28PM -0700, Brad Larson wrote:
> > The Pensando Elba SoC uses a GPIO based chip select
> > for two DW SPI busses with each bus having two
> > chip selects.
(...)
> > +static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
> > +{
> > +     struct dw_spi *dws = spi_master_get_devdata(spi->master);
> > +
>
> > +     if (!enable) {
>
> Please, be more attentive to the review-comments given to you before
> resending a new patchset. One more time. This version of set_cs won't
> work for Active-high CS. Each SPI controller working with GPIO-based
> chip-select is marked as supporting that feature. So your DW
> SPI controller won't be able to work correctly with SPI-devices
> activated by active-high chip-select signal. Note default
> dw_spi_set_cs() callback supports that.

Thanks for your patience.  It took me a while to understand what you
were asking about regarding dw_spi_set_cs() due to the unnecessarily
complicated function that was being used.  The current implementation
I propose for v3 patchset is this which as you identified handles cs
active high/low properly.

static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
{
        spi->chip_select = 0;
        dw_spi_set_cs(spi, enable);
}

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:28:50 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:28:50 -0700
Subject: [PATCH v2 05/13] mmc: sdhci-cadence: Add Pensando Elba SoC support
In-Reply-To: <CAPDyKFpg1qJD0r54sBC3hCoFey_+gwAL1n2o-aGwnAzAan5p7w@mail.gmail.com>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-6-brad@pensando.io>
 <CAPDyKFpg1qJD0r54sBC3hCoFey_+gwAL1n2o-aGwnAzAan5p7w@mail.gmail.com>
Message-ID: <CAK9rFnwBGV=J+duhoFkX4Npr+fbf-EyP0UnhzMVGfJr77f=KFw@mail.gmail.com>

Hi Uffe,

On Tue, Mar 30, 2021 at 3:31 AM Ulf Hansson <ulf.hansson at linaro.org> wrote:
>
> + Masahiro Yamada (main author of the driver)
>
> On Mon, 29 Mar 2021 at 03:59, Brad Larson <brad at pensando.io> wrote:
> >
> > Add support for Pensando Elba SoC which explicitly controls
> > byte-lane enables on writes.  Refactor to allow platform
> > specific write ops.
> >
> > Signed-off-by: Brad Larson <brad at pensando.io>
> > ---
> >  drivers/mmc/host/Kconfig              |  15 +++
> >  drivers/mmc/host/Makefile             |   1 +
> >  drivers/mmc/host/sdhci-cadence-elba.c | 137 ++++++++++++++++++++++++++
>
> By looking at the amount of code changes that seem to be needed to
> support the Pensando Elba variant, I don't think it's necessary to
> split this into a separate file.
>
> Unless Yamada-san has a different opinion, I would rather just stick
> with using sdhci-cadence.c.

Yamada-san agreed with the recommendation.  This is a summary of the
changes for the updated patchset based upon all the review comments.

- Add Elba support into sdhci-cadence.c
- Removes new files sdhci-cadence-elba.c and sdhci-cadence.h.
- Remove Kconfig option MMC_SDHCI_CADENCE_ELBA
- Use the existing SDHCI_CDNS_* register defines
- Prefixed the remaining Elba SoC specific functions with elba_
- Use C Comment syntax
- The Elba specific phy init code is removed and the existing
sdhci_cdns_phy_init() is used for these Elba properties set in the DT

cdns,phy-input-delay-sd-highspeed = <0x4>;
cdns,phy-input-delay-legacy = <0x4>;
cdns,phy-input-delay-sd-uhs-sdr50 = <0x6>;
cdns,phy-input-delay-sd-uhs-ddr50 = <0x16>;

> > +config MMC_SDHCI_CADENCE_ELBA
> > +       tristate "SDHCI support for the Pensando/Cadence SD/SDIO/eMMC controller"
> > +       depends on ARCH_PENSANDO_ELBA_SOC
> > +       depends on MMC_SDHCI
> > +       depends on OF
> > +       depends on MMC_SDHCI_CADENCE
> > +       depends on MMC_SDHCI_PLTFM
> > +       select MMC_SDHCI_IO_ACCESSORS
>
> According to the comment above - then you should probably just extend
> the conditions for when building MMC_SDHCI_CADENCE, rather than having
> to add a new Kconfig for "*_ELBA".

Yes, config MMC_SDHCI_CADENCE_ELBA is removed.  Elba support is
enabled with CONFIG_MMC_SDHCI_CADENCE.

> > +// delay regs address
>
> Please don't use "//" when adding comments, but instead "/* ... */".
> This applies to several more places of the patch.
>

Only C syntax is now used for comments.

> > +static void sd4_set_dlyvr(struct sdhci_host *host,
> > +                         unsigned char addr, unsigned char data)
>
> Please, try to think of a better function name that's more
> descriptive. Moreover, please use a common prefix for functions that
> is used on elba.

The Elba specific functions such as sd4_set_dlyvr() are deleted and
the existing sdhci_cdns_phy_init() with DT properties are used for PHY
init.  The remaining Elba specific functions have the prefix elba_

> > +{
> > +       unsigned long dlyrv_reg;
> > +
> > +       dlyrv_reg = ((unsigned long)data << 8);
> > +       dlyrv_reg |= addr;
> > +
> > +       // set data and address
> > +       writel(dlyrv_reg, host->ioaddr + SDIO_REG_HRS4);
> > +       dlyrv_reg |= (1uL << 24uL);
> > +       // send write request
> > +       writel(dlyrv_reg, host->ioaddr + SDIO_REG_HRS4);
> > +       dlyrv_reg &= ~(1uL << 24);
> > +       // clear write request
> > +       writel(dlyrv_reg, host->ioaddr + SDIO_REG_HRS4);
> > +}
> > +
> > +static void phy_config(struct sdhci_host *host)
>
> Ditto.

Yes, C syntax only.  Refactored to use existing sdhci_cdns_phy_init()
and removed phy_config().

> > @@ -453,8 +444,14 @@ static const struct dev_pm_ops sdhci_cdns_pm_ops = {
> >  static const struct of_device_id sdhci_cdns_match[] = {
> >         {
> >                 .compatible = "socionext,uniphier-sd4hc",
> > -               .data = &sdhci_cdns_uniphier_pltfm_data,
> > +               .data = &sdhci_cdns_uniphier_drv_data,
> >         },
> > +#ifdef CONFIG_MMC_SDHCI_CADENCE_ELBA
>
> No need to hide this minor piece of code behind ifdefs.

No longer hidden by an ifdef, the config option
CONFIG_MMC_SDHCI_CADENCE_ELBA is gone.

> > --- /dev/null
> > +++ b/drivers/mmc/host/sdhci-cadence.h
>
> This new header file can go away too, if you fold in all the code in
> the common c-file.

Exactly, the added file sdhci-cadence.h is gone.

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:31:37 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:31:37 -0700
Subject: [PATCH v2 05/13] mmc: sdhci-cadence: Add Pensando Elba SoC support
In-Reply-To: <CAK7LNAQYptL=wJ1ofauX41oV+bZRaSq1V5FabMz4eyZBzxDQaw@mail.gmail.com>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-6-brad@pensando.io>
 <CAPDyKFpg1qJD0r54sBC3hCoFey_+gwAL1n2o-aGwnAzAan5p7w@mail.gmail.com>
 <CAK7LNAQYptL=wJ1ofauX41oV+bZRaSq1V5FabMz4eyZBzxDQaw@mail.gmail.com>
Message-ID: <CAK9rFnwQ0g=B-=k9KLx=3tRgshkDLji+tKjsG3_Y5RrSeP-SMQ@mail.gmail.com>

Hi Yamada-san,

On Fri, Apr 9, 2021 at 1:25 AM Masahiro Yamada <masahiroy at kernel.org> wrote:
>
> On Tue, Mar 30, 2021 at 7:31 PM Ulf Hansson <ulf.hansson at linaro.org> wrote:
> >
> > + Masahiro Yamada (main author of the driver)
> >
> > On Mon, 29 Mar 2021 at 03:59, Brad Larson <brad at pensando.io> wrote:
> > >
> > > Add support for Pensando Elba SoC which explicitly controls
> > > byte-lane enables on writes.  Refactor to allow platform
> > > specific write ops.
> > >
> > > Signed-off-by: Brad Larson <brad at pensando.io>
> > > ---
> > >  drivers/mmc/host/Kconfig              |  15 +++
> > >  drivers/mmc/host/Makefile             |   1 +
> > >  drivers/mmc/host/sdhci-cadence-elba.c | 137 ++++++++++++++++++++++++++
> >
> > By looking at the amount of code changes that seem to be needed to
> > support the Pensando Elba variant, I don't think it's necessary to
> > split this into a separate file.
> >
> > Unless Yamada-san has a different opinion, I would rather just stick
> > with using sdhci-cadence.c.
>
>
> I agree with Ulf.

I've folded Elba SoC support into sdhci-cadence.c.

> BTW, this patch cannot probe
> "pensando,elba-emmc"
> when CONFIG_MMC_SDHCI_CADENCE_ELBA=m.

Right, that issue is gone now.  There is no separate sdhci-cadence-elba.c

> > > +#define SDIO_REG_HRS4          0x10
>
> This is the same as SDHCI_CDNS_HRS04
>
>
>
> > > +#define REG_DELAY_HS           0x00
>
> This is the same as SDHCI_CDNS_PHY_DLY_SD_HS
>
>
> > > +#define REG_DELAY_DEFAULT      0x01
>
>
> This is the same as SDHCI_CDNS_PHY_DLY_SD_DEFAULT
>
>
>
> > > +#define REG_DELAY_UHSI_SDR50   0x04
>
> This is the same as SDHCI_CDNS_PHY_DLY_UHS_SDR50
>
>
>
> > > +#define REG_DELAY_UHSI_DDR50   0x05
>
>
> This is the same as SDHCI_CDNS_PHY_DLY_UHS_DDR50
>

All of those redundant definitions are gone, I'm now using the
existing definitions you're identifying.

> > > +
> > > +static void elba_write_l(struct sdhci_host *host, u32 val, int reg)
> > > +{
> > > +       struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(&priv->wrlock, flags);
> > > +       writel(0x78, priv->ctl_addr);
> > > +       writel(val, host->ioaddr + reg);
> > > +       spin_unlock_irqrestore(&priv->wrlock, flags);
> > > +}
[...]
> > > +static void elba_priv_write_l(struct sdhci_cdns_priv *priv,
> > > +               u32 val, void __iomem *reg)
> > > +{
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(&priv->wrlock, flags);
> > > +       writel(0x78, priv->ctl_addr);
> > > +       writel(val, reg);
> > > +       spin_unlock_irqrestore(&priv->wrlock, flags);
> > > +}
>
>
> Maybe, can this avoid code duplication?
>
> static void elba_hrs_write_l(struct sdhci_cdns_priv *priv,
>                               u32 val, int reg)
> {
>         unsigned long flags;
>
>         spin_lock_irqsave(&priv->wrlock, flags);
>         writel(0x78, priv->ctl_addr);
>         writel(val, priv->hrs_addr + reg);
>         spin_unlock_irqrestore(&priv->wrlock, flags);
> }
>
> static void elba_write_l(struct sdhci_host *host, u32 val, int reg)
> {
>         elba_hrs_write_l(sdhci_cdns_priv(host), val, SDHCI_CDNS_SRS_BASE + reg);
> }

Yes, some code can be reduced.   This is the current implementation I
propose to include with the v3 patchset

/*
 * The Pensando Elba SoC explicitly controls byte-lane enables on writes
 * which includes writes to the HRS registers.
 */
static void elba_priv_write_l(struct sdhci_cdns_priv *priv, u32 val,
                              void __iomem *reg)
{
        unsigned long flags;

        spin_lock_irqsave(&priv->wrlock, flags);
        writel(0x78, priv->ctl_addr);
        writel(val, reg);
        spin_unlock_irqrestore(&priv->wrlock, flags);
}

static void elba_write_l(struct sdhci_host *host, u32 val, int reg)
{
        elba_priv_write_l(sdhci_cdns_priv(host), val, host->ioaddr + reg);
}

> > > +static void sd4_set_dlyvr(struct sdhci_host *host,
> > > +                         unsigned char addr, unsigned char data)
> >
> > Please, try to think of a better function name that's more
> > descriptive. Moreover, please use a common prefix for functions that
> > is used on elba.

This function is removed and the existing sdhci_cdns_phy_init() is
used with DT properties

> > > +{
> > > +       unsigned long dlyrv_reg;
> > > +
> > > +       dlyrv_reg = ((unsigned long)data << 8);
> > > +       dlyrv_reg |= addr;
> > > +
> > > +       // set data and address
> > > +       writel(dlyrv_reg, host->ioaddr + SDIO_REG_HRS4);
> > > +       dlyrv_reg |= (1uL << 24uL);
> > > +       // send write request
> > > +       writel(dlyrv_reg, host->ioaddr + SDIO_REG_HRS4);
> > > +       dlyrv_reg &= ~(1uL << 24);
> > > +       // clear write request
> > > +       writel(dlyrv_reg, host->ioaddr + SDIO_REG_HRS4);
>
>
> This seems to be equivalent to sdhci_cdns_write_phy_reg().

Yes after looking at the implementation it is, there was nothing
special required for Elba.  I've refactored and the function
sdhci_cdns_write_phy_reg() which is used in sdhci_cdns_phy_init()
dependent on DT properties is now used for Elba phy init.

> > > +static void phy_config(struct sdhci_host *host)
> >
> > Ditto.
> >
> > > +{
> > > +       sd4_set_dlyvr(host, REG_DELAY_DEFAULT, 0x04);
> > > +       sd4_set_dlyvr(host, REG_DELAY_HS, 0x04);
> > > +       sd4_set_dlyvr(host, REG_DELAY_UHSI_SDR50, 0x06);
> > > +       sd4_set_dlyvr(host, REG_DELAY_UHSI_DDR50, 0x16);
>
>
> Hard-code board (or chip) specific parameters to the driver?
>
> This should go to DT properties.
>
> See Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml

Exactly, v3 of the patchset will incorporate this recommendation.  In
the case of Elba SoC these are the DT properties being used

cdns,phy-input-delay-sd-highspeed = <0x4>;
cdns,phy-input-delay-legacy = <0x4>;
cdns,phy-input-delay-sd-uhs-sdr50 = <0x6>;
cdns,phy-input-delay-sd-uhs-ddr50 = <0x16>;

> > > +static int elba_drv_init(struct platform_device *pdev)
> > > +{
> > > +       struct sdhci_host *host = platform_get_drvdata(pdev);
> > > +       struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
> > > +       struct resource *iomem;
> > > +       void __iomem *ioaddr;
> > > +
> > > +       host->mmc->caps |= (MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA);
> > > +       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > > +       if (!iomem)
> > > +               return -ENOMEM;
> > > +       ioaddr = devm_ioremap_resource(&pdev->dev, iomem);
> > > +       if (IS_ERR(ioaddr))
> > > +               return PTR_ERR(ioaddr);
>
>
>
> Use  devm_platform_ioremap_resource(pdev, 1)

Replaced devm_ioremap_resource(&pdev->dev, iomem) with
devm_platform_ioremap_resource(pdev, 1).  The change will be in v3 of
the patchset.

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:36:58 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:36:58 -0700
Subject: [PATCH v2 07/13] arm64: dts: Add Pensando Elba SoC support
In-Reply-To: <20210330215541.GA729679@robh.at.kernel.org>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-8-brad@pensando.io>
 <20210330215541.GA729679@robh.at.kernel.org>
Message-ID: <CAK9rFnzxPFm3aJDUh0eZnV5q8EpGwqGkcKM=RbiVdp5C5UhaqQ@mail.gmail.com>

Hi Rob,

On Tue, Mar 30, 2021 at 2:55 PM Rob Herring <robh at kernel.org> wrote:
>
> On Sun, Mar 28, 2021 at 06:59:32PM -0700, Brad Larson wrote:
> > Add Pensando common and Elba SoC specific device nodes
>
> Build your dtb with W=1 and 'make dtbs_check' and fix warnings.

I'll do that thanks.

> > +
> > +             // CLUSTER 0
> > +             cpu0: cpu at 0 {
> > +                     device_type = "cpu";
> > +                     compatible = "arm,cortex-a72", "arm,armv8";
>
> This should give you a warning.

I'll be sure to W=1 and make dtbs_check.  All the C++ comments are C syntax now.

> > +&qspi {
> > +     status = "okay";
> > +     flash0: mt25q at 0 {
>
> flash at 0

Yes, generic node name should be used.  Changed mt25q to flash.
-       flash0: mt25q at 0 {
+       flash0: flash at 0 {

> > +             compatible = "jdec,spi-nor";
>
> jedec,spi-nor

Changed jdec to jedec
-               compatible = "jdec,spi-nor";
+               compatible = "jedec,spi-nor";

> > +     spi at 0 {
>
> 'spi@' is reserved for SPI controllers.

Changed the node name to indicate the spi bus number and chip select

&spi0 {
        num-cs = <4>;
        cs-gpios = <&spics 0 GPIO_ACTIVE_LOW>, <&spics 1 GPIO_ACTIVE_LOW>,
                   <&porta 1 GPIO_ACTIVE_LOW>, <&porta 7 GPIO_ACTIVE_LOW>;
        status = "okay";
-       spi at 0 {
+       spi0_cs0 at 0 {
                compatible = "pensando,cpld";
                #address-cells = <1>;
                #size-cells = <1>;
                spi-max-frequency = <12000000>;
                reg = <0>;
        };
-       spi at 1 {
+       spi0_cs1 at 1 {
        ...

> > +             compatible = "pensando,cpld";
>
> Any new compatibles need to be documented with schema.

I'll create the bindings file for the v3 patchset dependent on the
discussion revolving around adding pensando,cpld to this list in
spi/spidev.c.

static const struct of_device_id spidev_dt_ids[] = {
        { .compatible = "rohm,dh2228fv" },
        { .compatible = "lineartechnology,ltc2488" },
        { .compatible = "ge,achc" },
        { .compatible = "semtech,sx1301" },
        { .compatible = "lwn,bk4" },
        { .compatible = "dh,dhcom-board" },
        { .compatible = "menlo,m53cpld" },
        { .compatible = "pensando,cpld" },    <===
        {},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);

> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/pensando/elba-flash-parts.dtsi
> > @@ -0,0 +1,78 @@
> > +&flash0 {
> > +     partitions {
> > +             compatible = "fixed-partitions";
>
> This should just be moved into elba-asic-common.dtsi IMO unless you have
> good reasons to keep it separate.

This file is shared across platforms which have additional flash
devices and partition schemes.

> You need SPDX license tags at the top of each file. checkpatch.pl should
> tell you this.

I don't recall checkpatch.pl reporting that for device tree files.
I've added to each file now.

> > +/*
> > + * Copyright (c) 2019, Pensando Systems Inc.
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include "dt-bindings/interrupt-controller/arm-gic.h"
> > +
> > +/ {
> > +     compatible = "pensando,elba";
>
> This needs an SoC family schema.
>
> Generally this and 'model' should be in the same file (the board file).

Will add schema for pensando,elba in the v3 patchset.  The compatible
and model are now in the board file elba-asic.dts as shown below

+/ {
+       model = "Elba ASIC Board";
+       compatible = "pensando,elba";
+
+       aliases {
+               serial0 = &uart0;
+               spi0 = &spi0;
+               spi1 = &qspi;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};

> > +
> > +     interrupt-parent = <&gic>;
> > +     #address-cells = <2>;
> > +     #size-cells = <2>;
> > +
> > +     clocks {
>
> Drop this container node.

Removed the container node.

> > +     /* Common UIO device for MSI drivers */
> > +     uio_penmsi {
> > +             compatible = "pensando,uio_penmsi";
> > +             name = "uio_penmsi";
>
> No. What's UIO?

UIO nodes are removed, only core SoC support will be included

> > +     soc: soc {
> > +             compatible = "simple-bus";
> > +             #address-cells = <2>;
> > +             #size-cells = <2>;
> > +             ranges;
> > +
> > +             gic: interrupt-controller at 800000 {
>
> Order nodes by increasing unit address.

Yes, I've done this and will be part of the v3 patchset

> > +             /*
> > +              * Until we  know the interrupt domain following this, we
> > +              * are forced to use this is the place where interrupts from
> > +              * PCI converge. In the ideal case, we use one domain higher,
> > +              * where the PCI-ness has been shed.
> > +              */
> > +             pxc0_intr: intc at 20102200 {
>
> interrupt-controller at ...

Changed intc to interrupt-controller

> > +                     compatible = "pensando,soc-ictlr-csrintr";
> > +                     interrupt-controller;
> > +                     reg = <0x0 0x20102200 0x0 0x4>;
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> > +                     interrupt-names = "pxc0_intr";
> > +             };
> > +
> > +             uart0: serial at 4800 {
> > +                     device_type = "serial";
>
> Drop 'device_type'. It's deprecated for all but memory and pci.
>

Removed  device_type = "serial";

> > +             gpio0: gpio at 4000 {
> > +                     #address-cells = <1>;
> > +                     #size-cells = <0>;
> > +                     compatible = "snps,dw-apb-gpio";
> > +                     reg = <0x0 0x4000 0x0 0x78>;
> > +                     status = "disabled";
> > +
> > +                     porta: gpio-controller at 0 {
>
> gpio at 0

Changed from gpio at 0 to gpio-port at 0 based on additional reviewer input

-                       porta: gpio-controller at 0 {
+                       porta: gpio-port at 0 {

> > +
> > +             /* UIO device using interrupt line PCIEMAC */
>
> UIO is a kernel thing. It doesn't belong in DT.

UIO nodes are removed for core SoC support patchset

> > +
> > +             emmc: mmc at 30440000 {
> > +                     compatible = "pensando,elba-emmc", "cdns,sd4hc";
> > +                     clocks = <&emmc_clk>;
> > +                     interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
> > +                     reg = <0x0 0x30440000 0x0 0x10000
> > +                            0x0 0x30480044 0x0 0x4>;
>
> Use <> around each entry.

The system fails to boot if I make that change, mmc probe fails and
rootfs not found

-               reg = <0x0 0x30440000 0x0 0x10000
-                      0x0 0x30480044 0x0 0x4>;
+               reg = <0x0 0x30440000 0x0 0x10000>,
+                     <0x0 0x30480044 0x0 0x4>;

Regards,
Brad


From hongxing.zhu at nxp.com  Sun Aug 22 18:52:57 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Mon, 23 Aug 2021 01:52:57 +0000
Subject: [PATCH v1 2/3] arm: dts: imx: fix the schema check errors
In-Reply-To: <cbd278b1828d4b8fbfd885e56731d82355d2112b.camel@pengutronix.de>
References: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
 <20210819071408.3856475-3-hongxing.zhu@nxp.com>
 <cbd278b1828d4b8fbfd885e56731d82355d2112b.camel@pengutronix.de>
Message-ID: <VI1PR04MB585360C501595D8EAE9F0E468CC49@VI1PR04MB5853.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Lucas Stach <l.stach at pengutronix.de>
> Sent: Thursday, August 19, 2021 7:11 PM
> To: Richard Zhu <hongxing.zhu at nxp.com>; robh at kernel.org;
> galak at kernel.crashing.org; shawnguo at kernel.org
> Cc: devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; dl-linux-imx
> <linux-imx at nxp.com>; kernel at pengutronix.de;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v1 2/3] arm: dts: imx: fix the schema check errors
> 
> Hi Richard,
> 
> Am Donnerstag, dem 19.08.2021 um 15:14 +0800 schrieb Richard Zhu:
> > - the ranges should be aligned to $ref: /schemas/pci/pci-bus.yaml#
> 
> I failed to parse this part of the commit message and expected to see an
> actual change in the addresses of the ranges or something. I think it would be
> better to phrase this something like: "group ranges property by region" or
> something to make it clear that this is purely a DTS representation change,
> with no functional change.
> 
[Richard Zhu] Hi Lucas:
Thanks.
Would change as "group ranges property by region" refer to your review comments.

Best Regards
Richard Zhu

> > - num-viewport is required, add it in imx6sx.dtsi.
> > - only one propert is allowed in the compatible string, remove
> >   "snps,dw-pcie".
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
> 
> Other than the nit above, this is:
> Reviewed-by: Lucas Stach <l.stach at pengutronix.de>
> 
> > ---
> >  arch/arm/boot/dts/imx6qdl.dtsi | 6 +++---
> > arch/arm/boot/dts/imx6qp.dtsi  | 2 +-  arch/arm/boot/dts/imx6sx.dtsi
> > | 7 ++++---
> >  arch/arm/boot/dts/imx7d.dtsi   | 6 +++---
> >  4 files changed, 11 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/arm/boot/dts/imx6qdl.dtsi
> > b/arch/arm/boot/dts/imx6qdl.dtsi index 82e01ce026ea..cb43c72806a1
> > 100644
> > --- a/arch/arm/boot/dts/imx6qdl.dtsi
> > +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> > @@ -264,7 +264,7 @@ L2: cache-controller at a02000 {
> >  		};
> >
> >  		pcie: pcie at 1ffc000 {
> > -			compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
> > +			compatible = "fsl,imx6q-pcie";
> >  			reg = <0x01ffc000 0x04000>,
> >  			      <0x01f00000 0x80000>;
> >  			reg-names = "dbi", "config";
> > @@ -272,8 +272,8 @@ pcie: pcie at 1ffc000 {
> >  			#size-cells = <2>;
> >  			device_type = "pci";
> >  			bus-range = <0x00 0xff>;
> > -			ranges = <0x81000000 0 0          0x01f80000 0
> 0x00010000 /* downstream I/O */
> > -				  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
> /* non-prefetchable memory */
> > +			ranges = <0x81000000 0 0          0x01f80000 0
> 0x00010000>, /* downstream I/O */
> > +				 <0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
> /*
> > +non-prefetchable memory */
> >  			num-lanes = <1>;
> >  			num-viewport = <4>;
> >  			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; diff --git
> > a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi index
> > b310f13a53f2..050365513836 100644
> > --- a/arch/arm/boot/dts/imx6qp.dtsi
> > +++ b/arch/arm/boot/dts/imx6qp.dtsi
> > @@ -110,5 +110,5 @@ &mmdc0 {
> >  };
> >
> >  &pcie {
> > -	compatible = "fsl,imx6qp-pcie", "snps,dw-pcie";
> > +	compatible = "fsl,imx6qp-pcie";
> >  };
> > diff --git a/arch/arm/boot/dts/imx6sx.dtsi
> > b/arch/arm/boot/dts/imx6sx.dtsi index 8516730778df..0324f9e17389
> > 100644
> > --- a/arch/arm/boot/dts/imx6sx.dtsi
> > +++ b/arch/arm/boot/dts/imx6sx.dtsi
> > @@ -1395,16 +1395,17 @@ pwm8: pwm at 22b0000 {
> >  		};
> >
> >  		pcie: pcie at 8ffc000 {
> > -			compatible = "fsl,imx6sx-pcie", "snps,dw-pcie";
> > +			compatible = "fsl,imx6sx-pcie";
> >  			reg = <0x08ffc000 0x04000>, <0x08f00000 0x80000>;
> >  			reg-names = "dbi", "config";
> >  			#address-cells = <3>;
> >  			#size-cells = <2>;
> >  			device_type = "pci";
> >  			bus-range = <0x00 0xff>;
> > -			ranges = <0x81000000 0 0          0x08f80000 0
> 0x00010000 /* downstream I/O */
> > -				  0x82000000 0 0x08000000 0x08000000 0 0x00f00000>;
> /* non-prefetchable memory */
> > +			ranges = <0x81000000 0 0          0x08f80000 0
> 0x00010000>, /* downstream I/O */
> > +				 <0x82000000 0 0x08000000 0x08000000 0 0x00f00000>;
> /*
> > +non-prefetchable memory */
> >  			num-lanes = <1>;
> > +			num-viewport = <4>;
> >  			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> >  			interrupt-names = "msi";
> >  			#interrupt-cells = <1>;
> > diff --git a/arch/arm/boot/dts/imx7d.dtsi
> > b/arch/arm/boot/dts/imx7d.dtsi index b0bcfa9094a3..0cb8c8df87ef
> 100644
> > --- a/arch/arm/boot/dts/imx7d.dtsi
> > +++ b/arch/arm/boot/dts/imx7d.dtsi
> > @@ -164,7 +164,7 @@ fec2: ethernet at 30bf0000 {
> >  	};
> >
> >  	pcie: pcie at 33800000 {
> > -		compatible = "fsl,imx7d-pcie", "snps,dw-pcie";
> > +		compatible = "fsl,imx7d-pcie";
> >  		reg = <0x33800000 0x4000>,
> >  		      <0x4ff00000 0x80000>;
> >  		reg-names = "dbi", "config";
> > @@ -172,8 +172,8 @@ pcie: pcie at 33800000 {
> >  		#size-cells = <2>;
> >  		device_type = "pci";
> >  		bus-range = <0x00 0xff>;
> > -		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000
> /* downstream I/O */
> > -			  0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /*
> non-prefetchable memory */
> > +		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000>,
> /* downstream I/O */
> > +			 <0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /*
> > +non-prefetchable memory */
> >  		num-lanes = <1>;
> >  		num-viewport = <4>;
> >  		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
> 


From brad at pensando.io  Sun Aug 22 18:55:32 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:55:32 -0700
Subject: [PATCH v2 07/13] arm64: dts: Add Pensando Elba SoC support
In-Reply-To: <20210331175130.mhub5yxc3szfsl5q@mobilestation>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-8-brad@pensando.io>
 <20210331175130.mhub5yxc3szfsl5q@mobilestation>
Message-ID: <CAK9rFnxX+AOkZ6TWogG7G=FqMs_JhH2RUDw=8gZ=Gsf=Vk+9aw@mail.gmail.com>

Hi Sergey,

On Wed, Mar 31, 2021 at 10:51 AM Serge Semin <fancer.lancer at gmail.com> wrote:
>
> Rob,
> Could you give your opinion on my comment regarding the nodes
> layout in this dts-file. I was told to fix a similar problem in one of
> patches submitted by me some time ago. Please see my last comment in
> this message.
>
> On Sun, Mar 28, 2021 at 06:59:32PM -0700, Brad Larson wrote:
> > Add Pensando common and Elba SoC specific device nodes
[...]
> > +
>
> > +             // CLUSTER 0
>
> What does chackpatch.pl tell you about C++ comment?

I don't recall a warning for this but I think I forgot to use W=1 to
check dtbs.  Will make sure it's clean before submitting the v3
patchset.

[...]
> > +             // CLUSTER 1
>
> ditto

I've changed all C++ comments to C syntax

[...]
> > diff --git a/arch/arm64/boot/dts/pensando/elba-asic-common.dtsi b/arch/arm64/boot/dts/pensando/elba-asic-common.dtsi
> > new file mode 100644
> > index 000000000000..7de2c35e7fcc
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/pensando/elba-asic-common.dtsi
> > @@ -0,0 +1,112 @@
> > +
> > +/ {
> > +     model = "Elba ASIC Board";
> > +
> > +     aliases {
>
> > +             serial0 = &uart0;
> > +                spi0 = &spi0;
> > +                spi1 = &qspi;
>
> Brad, if you checkpatch.pl'ed this patch, that would have told you
> regarding leading spaces here.

I did run it but must have missed that or used it incorrectly for the
dtsi files.

[...]
> > +             pxc0_intr: intc at 20102200 {
> > +                     compatible = "pensando,soc-ictlr-csrintr";
> > +                     interrupt-controller;
>
> > +                     reg = <0x0 0x20102200 0x0 0x4>;
>
> Rob, please note the reg-space size here.
>
> > +                     #interrupt-cells = <3>;
> > +                     interrupt-parent = <&gic>;
> > +                     interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> > +                     interrupt-names = "pxc0_intr";
> > +             };
> > +
> > +             uart0: serial at 4800 {
> > +                     device_type = "serial";
> > +                     compatible = "ns16550a";
> > +                     reg = <0x0 0x4800 0x0 0x100>;
> > +                     clocks = <&ref_clk>;
> > +                     interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
> > +                     reg-shift = <2>;
> > +                     reg-io-width = <4>;
> > +             };
> > +
> > +             qspi: spi at 2400 {
> > +                     compatible = "pensando,cdns-qspi";
> > +                     #address-cells = <1>;
> > +                     #size-cells = <0>;
> > +                     reg = <0x0 0x2400 0x0 0x400>,
> > +                           <0x0 0x7fff0000 0x0 0x1000>;
> > +                     interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
> > +                     clocks = <&flash_clk>;
> > +                     cdns,fifo-depth = <1024>;
> > +                     cdns,fifo-width = <4>;
> > +                     cdns,trigger-address = <0x7fff0000>;
> > +                     status = "disabled";
> > +             };
> > +
> > +             gpio0: gpio at 4000 {
> > +                     #address-cells = <1>;
> > +                     #size-cells = <0>;
> > +                     compatible = "snps,dw-apb-gpio";
>
>
> > +                     reg = <0x0 0x4000 0x0 0x78>;
>
> Brad, are you sure the reg-space is just 0x78 bytes in this DW GPIO
> module? Normally the system bus blocks are aligned to something
> no less than 1KB...

In the memory map the devices stride 1KB but the last register for
this IP is at 0x74..0x77.  Looks like this will need to be revisited
should a working syscon usage be discovered.

>
> > +                     status = "disabled";
> > +
>
> > +                     porta: gpio-controller at 0 {
>
> Brad, I'd prefer to name the sub-nodes as "gpio-port" for DW APB GPIO
> because hardware considers each of them as dedicated port of the
> GPIO controller. I know the bindings file permits using "-controller"
> suffix, but that is allowed only because the bindings file was submitted
> much later than the driver was. So I didn't want to have the dtbs_check
> printing errors for already available dts-files.
>

Named these sub-nodes "gpio-port"

> > +                             compatible = "snps,dw-apb-gpio-port";
> > +                             reg = <0>;
> > +                             gpio-controller;
> > +                             #gpio-cells = <2>;
> > +                             ngpios = <8>;
> > +                             interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
> > +                             interrupt-controller;
> > +                             interrupt-parent = <&gic>;
> > +                             #interrupt-cells = <2>;
> > +                     };
> > +                     portb: gpio-controller at 1 {
> > +                             compatible = "snps,dw-apb-gpio-port";
> > +                             reg = <1>;
> > +                             gpio-controller;
> > +                             #gpio-cells = <2>;
> > +                             ngpios = <8>;
> > +                     };
> > +             };
> > +
> > +             i2c0: i2c at 400 {
> > +                     compatible = "snps,designware-i2c";
> > +                     reg = <0x0 0x400 0x0 0x100>;
> > +                     clocks = <&ahb_clk>;
> > +                     #address-cells = <1>;
> > +                     #size-cells = <0>;
> > +                     i2c-sda-hold-time-ns = <480>;
> > +                     snps,sda-timeout-ms = <750>;
> > +                     interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
> > +                     status = "disabled";
> > +             };
> > +
> > +             /* UIO device using interrupt line PCIEMAC */
> > +             pciemac at 20102200 {
> > +                     #address-cells = <2>;
> > +                     #size-cells = <2>;
> > +                     #interrupt-cells = <3>;
> > +
> > +                     compatible = "pensando,uio_pciemac";
> > +                     register-type = "csr-interrupt";
> > +                     interrupt-parent = <&pxc0_intr>;
> > +                     interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
> > +                     reg = <0x0 0x20102200 0x0 0x10>; /* pxc0_intr */
> > +
> > +                     enable_csr_paddr = <0x0 0x20102200 0x0 0x10>;
> > +                     enable_mask = <(1 << 0)>;
> > +             };
> > +
> > +             /* MSI UIO device 1 */
> > +             uio_penmsi1 at 520000 {
> > +                     compatible = "pensando,uio_penmsi1";
> > +                     reg = <0x0 0x520000 0x0 0x10000>;
> > +                     msi-parent = <&its 0xa>;
> > +                     num-interrupts = <16>;  /* # MSI interrupts to get */
> > +             };
> > +
> > +             spics: spics at 307c2468 {
> > +                     compatible = "pensando,elba-spics";
>
> > +                     reg = <0x0 0x307c2468 0x0 0x4>;
>
> Rob, please note the reg-space base address and size here.
>
> > +                     gpio-controller;
> > +                     #gpio-cells = <2>;
> > +             };
> > +
> > +             spi0: spi at 2800 {
> > +                     compatible = "pensando,elba-spi";
> > +                     reg = <0x0 0x2800 0x0 0x100>;
> > +                     clocks = <&ahb_clk>;
> > +                     interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > +                     #address-cells = <1>;
> > +                     #size-cells = <0>;
> > +                     num-cs = <2>;
> > +                     status = "disabled";
> > +             };
> > +
> > +             wdt0: watchdog at 1400 {
> > +                     compatible = "snps,dw-wdt";
> > +                     reg = <0x0 0x1400 0x0 0x100>;
> > +                     clocks = <&ahb_clk>;
> > +                     interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> > +                     status = "disabled";
> > +             };
> > +             wdt1: watchdog at 1800 {
> > +                     compatible = "snps,dw-wdt";
> > +                     reg = <0x0 0x1800 0x0 0x100>;
> > +                     clocks = <&ahb_clk>;
> > +                     interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
> > +                     status = "disabled";
> > +             };
> > +             wdt2: watchdog at 1c00 {
> > +                     compatible = "snps,dw-wdt";
> > +                     reg = <0x0 0x1c00 0x0 0x100>;
> > +                     clocks = <&ahb_clk>;
> > +                     interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
> > +                     status = "disabled";
> > +             };
> > +             wdt3: watchdog at 2000 {
> > +                     compatible = "snps,dw-wdt";
> > +                     reg = <0x0 0x2000 0x0 0x100>;
> > +                     clocks = <&ahb_clk>;
> > +                     interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
> > +                     status = "disabled";
> > +             };
> > +
> > +             emmc: mmc at 30440000 {
> > +                     compatible = "pensando,elba-emmc", "cdns,sd4hc";
> > +                     clocks = <&emmc_clk>;
> > +                     interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
> > +                     reg = <0x0 0x30440000 0x0 0x10000
>
> > +                            0x0 0x30480044 0x0 0x4>;
>
> Rob, please also note the reg-space base address and size here.
> Brad just writes some magic numbers to this register in the MMC drive.
> The field is named as "ctl_addr" in the driver.
>
> > +                     cdns,phy-input-delay-sd-highspeed = <0x4>;
> > +                     cdns,phy-input-delay-legacy = <0x4>;
> > +                     cdns,phy-input-delay-sd-uhs-sdr50 = <0x6>;
> > +                     cdns,phy-input-delay-sd-uhs-ddr50 = <0x16>;
> > +                     cdns,mmc-ddr-1_8v;
> > +                     status = "disabled";
> > +             } ;
> > +
> > +             pcie at 307c2480 {
> > +                     compatible = "pensando,pcie";
>
> > +                     reg = <0x0 0x307c2480 0x0 0x4   /* MS CFG_WDT */
>
> Rob, please note the reg-space base address and size here.
>
> > +                            0x0 0x00001400 0x0 0x10  /* WDT0 */
> > +                            0x0 0x20000000 0x0 0x00380000>; /* PXB Base */
> > +             };
> > +
> > +             panic: panicdump at 0 {
> > +                     compatible = "pensando,pen-crash";
> > +                     status = "disabled";
> > +             };
> > +
> > +             bsm at 307c2080 {
> > +                     compatible = "pensando,bsm";
>
> > +                     reg = <0x0 0x307c2080 0x0 0x4>;
>
> Rob, please see here having a small sized reg-space one more time.
> Having so many small-sized registers scattered around the dts file
> makes me thinking that most of them likely belong to some bigger
> block like "System Controller". If so then there must be a main node
> compatible with "syscon" device, which phandle would be referenced in
> the particular device nodes. Like this:
>
> \ {
>         soc {
>                 syscon: syscon at 307c0000 {
>                         compatible = "pensando,elba-sys-con", "syscon", "simple-mfd";
>                         reg = <0x0 0x307c0000 0x0 0x10000>;
>
>                         spics: spics at 307c2468 {
>                                 compatible = "pensando,elba-spics";
>                                 gpio-controller;
>                                 #gpio-cells = <2>;
>                         };
>                 };
>
>                 pcie at 307c2480 {
>                         compatible = "pensando,pcie";
>                         reg = <0x0 0x20000000 0x0 0x00380000>; /* PXB Base */
>
>                         syscon = <&syscon>;
>                 };
>
>                 /* etc */
>         };
> };
>
> Rob, what do you think about that? Correct me if I am wrong.
>
> Brad, it's not about "To us it was more understandable" like you
> responded to my comment in v1, but about having the DTS correctly
> describing the hardware. Splitting the system controller registers up
> isn't good in that regard even if you think it makes the driver code
> more "understandable" and so on.
>
> Also Brad, don't hurry with re-sending the patchset before finishing
> all the discussions. I'd understand you doing so if noone would have
> given you any comment in a long time, but you've got tons of them
> nearly within one-two days after the v1 patchset submission. So you
> should have answered to the comments first, settled all the issues,
> then respined the series. Otherwise it seems as if you just disregard
> all the work the reviewers did giving you the comments.

Yes I appreciate the feedback and only recently had time to go through
all of the input, refactor, clean-up, and test on our 5.10 production
server.  Once all issues are resolved and tested on 5.10 and works
then I can redo the series using the latest linux-next.  Syscon in the
DT as mentioned above I've taken a few passes at with DT and
accompanying device driver changes and no joy yet.

Regards,
Brad


From brad at pensando.io  Sun Aug 22 18:57:29 2021
From: brad at pensando.io (Brad Larson)
Date: Sun, 22 Aug 2021 18:57:29 -0700
Subject: [PATCH v2 10/13] dt-bindings: spi: cadence-qspi: Add support for
 Pensando Elba SoC
In-Reply-To: <20210330111243.ne23j7ycsvy634rw@ti.com>
References: <20210329015938.20316-1-brad@pensando.io>
 <20210329015938.20316-11-brad@pensando.io>
 <20210330111243.ne23j7ycsvy634rw@ti.com>
Message-ID: <CAK9rFnx4jBAEMYVcVW+D5bRRzJA22wzYzyaCT9Q+y2Xw638bfQ@mail.gmail.com>

Hi Pratyush,

On Tue, Mar 30, 2021 at 4:12 AM Pratyush Yadav <p.yadav at ti.com> wrote:
>
> Hi Brad,
>
> On 28/03/21 06:59PM, Brad Larson wrote:
> > Add new vendor Pensando Systems Elba SoC compatible
> > string and convert to json-schema.
> >
> > Signed-off-by: Brad Larson <brad at pensando.io>
> > ---
> >  .../bindings/spi/cadence-quadspi.txt          |  68 --------
> >  .../bindings/spi/cadence-quadspi.yaml         | 153 ++++++++++++++++++
(...)
> > +properties:
> > +  compatible:
> > +    contains:
> > +      enum:
> > +        - cdns,qspi-nor       # Generic default
> > +        - ti,k2g-qspi         # TI 66AK2G SoC
> > +        - ti,am654-ospi       # TI AM654 SoC
> > +        - intel,lgm-qspi      # Intel LGM SoC
> > +        - pensando,cdns-qspi  # Pensando Elba SoC
>
> Wouldn't this allow any combination of all 5 strings? So for example
> this would allow "ti,am654-ospi", "pensando,cdns-qspi" which is
> obviously not correct.
>
> I sent a patch recently [0] that does this correctly and it has gotten
> Rob's blessing. So I suggest you build your patch on top of that.

Thanks for the pointer to the patch that creates yaml binding
spi/cdns,qspi-nor.yaml.  All I will need to do now for the updated
patchset is this

--- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
+++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
@@ -20,6 +20,7 @@ properties:
               - ti,k2g-qspi
               - ti,am654-ospi
               - intel,lgm-qspi
+              - pensando,elba-qspi
           - const: cdns,qspi-nor
       - const: cdns,qspi-nor

Regards,
Brad


From wangkefeng.wang at huawei.com  Sun Aug 22 19:19:23 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 23 Aug 2021 10:19:23 +0800
Subject: [PATCH 0/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <YRw32YE4cnNnWSvl@robh.at.kernel.org>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <YRw32YE4cnNnWSvl@robh.at.kernel.org>
Message-ID: <b5ccbf00-b686-d35b-c81a-0ec69f4677a0@huawei.com>


On 2021/8/18 6:27, Rob Herring wrote:
> On Mon, Aug 16, 2021 at 03:46:16PM +0800, Kefeng Wang wrote:
>> Patch 1 and 2 make some cleanup, and patch 3 use of_irq_get() instead of
>> irq_of_parse_and_map() to get irq number, return -EPROBE_DEFER if the irq
>> domain is not yet created, amba_device_add() will properly to handle the
>> no IRQ domain issue via deferred probe.
>>
>> Kefeng Wang (3):
>>    amba: Drop unused functions about APB/AHB devices add
>>    Revert "ARM: amba: make use of -1 IRQs warn"
>>    amba: Properly handle device probe without IRQ domain
>>
>>   drivers/amba/bus.c       | 100 ++++++++++-----------------------------
>>   drivers/of/platform.c    |   6 +--
>>   include/linux/amba/bus.h |  18 -------
>>   3 files changed, 27 insertions(+), 97 deletions(-)
> Reviewed-by: Rob Herring <robh at kernel.org>

Thanks Rob.

Hi Russell, should I send the patches to the ARM patch system?

> .
>


From wangkefeng.wang at huawei.com  Sun Aug 22 19:29:32 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 23 Aug 2021 10:29:32 +0800
Subject: [PATCH v3 0/3] arm64: support page mapping percpu first chunk
 allocator
In-Reply-To: <9b75f4e5-a675-1227-0476-43fc21509086@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <9b75f4e5-a675-1227-0476-43fc21509086@huawei.com>
Message-ID: <7904a638-3ee2-381f-6dfb-3d011df42c40@huawei.com>


On 2021/8/12 14:07, Kefeng Wang wrote:
> Hi Catalin and Will?
>
> The drivers/base/arch_numa.c is only shared by riscv and arm64,
>
> and the change from patch2 won't broke riscv.
>
> Could all patches be merged by arm64 tree? or any new comments?

Kindly ping...

>
> Many thanks.
>
> On 2021/8/9 17:37, Kefeng Wang wrote:
>> Percpu embedded first chunk allocator is the firstly option, but it
>> could fails on ARM64, eg,
>> ?? "percpu: max_distance=0x5fcfdc640000 too large for vmalloc space 
>> 0x781fefff0000"
>> ?? "percpu: max_distance=0x600000540000 too large for vmalloc space 
>> 0x7dffb7ff0000"
>> ?? "percpu: max_distance=0x5fff9adb0000 too large for vmalloc space 
>> 0x5dffb7ff0000"
>>
>> then we could meet "WARNING: CPU: 15 PID: 461 at vmalloc.c:3087 
>> pcpu_get_vm_areas+0x488/0x838",
>> even the system could not boot successfully.
>>
>> Let's implement page mapping percpu first chunk allocator as a fallback
>> to the embedding allocator to increase the robustness of the system.
>>
>> Also fix a crash when both NEED_PER_CPU_PAGE_FIRST_CHUNK and 
>> KASAN_VMALLOC enabled.
>>
>> Tested on ARM64 qemu with cmdline "percpu_alloc=page" based on 
>> v5.14-rc5.
>>
>> v3:
>> - search for a range that fits instead of always picking the end from
>> ?? vmalloc area suggested by Catalin.
>> - use NUMA_NO_NODE to avoid "virt_to_phys used for non-linear address:"
>> ?? issue in arm64 kasan_populate_early_vm_area_shadow().
>> - add Acked-by: Marco Elver <elver at google.com> to patch v3
>>
>> V2:
>> - fix build error when CONFIG_KASAN disabled, found by lkp at intel.com
>> - drop wrong __weak comment from kasan_populate_early_vm_area_shadow(),
>> ?? found by Marco Elver <elver at google.com>
>>
>> Kefeng Wang (3):
>> ?? vmalloc: Choose a better start address in vm_area_register_early()
>> ?? arm64: Support page mapping percpu first chunk allocator
>> ?? kasan: arm64: Fix pcpu_page_first_chunk crash with KASAN_VMALLOC
>>
>> ? arch/arm64/Kconfig???????? |? 4 ++
>> ? arch/arm64/mm/kasan_init.c | 16 ++++++++
>> ? drivers/base/arch_numa.c?? | 82 +++++++++++++++++++++++++++++++++-----
>> ? include/linux/kasan.h????? |? 6 +++
>> ? mm/kasan/init.c??????????? |? 5 +++
>> ? mm/vmalloc.c?????????????? | 17 +++++---
>> ? 6 files changed, 115 insertions(+), 15 deletions(-)
>>


From moudy.ho at mediatek.com  Sun Aug 22 19:32:43 2021
From: moudy.ho at mediatek.com (moudy.ho)
Date: Mon, 23 Aug 2021 10:32:43 +0800
Subject: [PATCH v6 3/5] dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
In-Reply-To: <1629377349.142826.288207.nullmailer@robh.at.kernel.org>
References: <20210819070954.16679-1-moudy.ho@mediatek.com>
 <20210819070954.16679-4-moudy.ho@mediatek.com>
 <1629377349.142826.288207.nullmailer@robh.at.kernel.org>
Message-ID: <63dfd3b3bf0bba7cd87f41d278ae52cae42d8481.camel@mediatek.com>

On Thu, 2021-08-19 at 07:49 -0500, Rob Herring wrote:
> On Thu, 19 Aug 2021 15:09:52 +0800, Moudy Ho wrote:
> > This patch adds DT binding document for Media Data Path 3 (MDP3)
> > a unit in multimedia system used for scaling and color format
> > convert.
> > 
> > Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> > ---
> >  .../bindings/media/mediatek,mdp3-ccorr.yaml   |  58 +++++
> >  .../bindings/media/mediatek,mdp3-rdma.yaml    | 241
> > ++++++++++++++++++
> >  .../bindings/media/mediatek,mdp3-rsz.yaml     |  66 +++++
> >  .../bindings/media/mediatek,mdp3-wdma.yaml    |  71 ++++++
> >  .../bindings/media/mediatek,mdp3-wrot.yaml    |  71 ++++++
> >  5 files changed, 507 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
> > 
Sorry for missing a space on line:183 of the file "mediatek,mdp3-
rdma.yaml " caused an alignment error that make "dt_binding_check"
fail.
It will be fixed in the further.
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m
> dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> make[1]: *** Deleting file
> 'Documentation/devicetree/bindings/media/mediatek,mdp3-
> rdma.example.dts'
> Traceback (most recent call last):
>   File "/usr/local/bin/dt-extract-example", line 45, in <module>
>     binding = yaml.load(open(args.yamlfile, encoding='utf-8').read())
>   File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/main.py",
> line 434, in load
>     return constructor.get_single_data()
>   File "/usr/local/lib/python3.8/dist-
> packages/ruamel/yaml/constructor.py", line 120, in get_single_data
>     node = self.composer.get_single_node()
>   File "_ruamel_yaml.pyx", line 706, in
> _ruamel_yaml.CParser.get_single_node
>   File "_ruamel_yaml.pyx", line 724, in
> _ruamel_yaml.CParser._compose_document
>   File "_ruamel_yaml.pyx", line 775, in
> _ruamel_yaml.CParser._compose_node
>   File "_ruamel_yaml.pyx", line 889, in
> _ruamel_yaml.CParser._compose_mapping_node
>   File "_ruamel_yaml.pyx", line 773, in
> _ruamel_yaml.CParser._compose_node
>   File "_ruamel_yaml.pyx", line 848, in
> _ruamel_yaml.CParser._compose_sequence_node
>   File "_ruamel_yaml.pyx", line 904, in
> _ruamel_yaml.CParser._parse_next_event
> ruamel.yaml.scanner.ScannerError: while scanning a block scalar
>   in "<unicode string>", line 171, column 5
> found a tab character where an indentation space is expected
>   in "<unicode string>", line 183, column 1
> make[1]: *** [Documentation/devicetree/bindings/Makefile:20:
> Documentation/devicetree/bindings/media/mediatek,mdp3-
> rdma.example.dts] Error 1
> make[1]: *** Waiting for unfinished jobs....
> ./Documentation/devicetree/bindings/media/mediatek,mdp3-
> rdma.yaml:  while scanning a block scalar
>   in "<unicode string>", line 171, column 5
> found a tab character where an indentation space is expected
>   in "<unicode string>", line 183, column 1
> /builds/robherring/linux-dt-
> review/Documentation/devicetree/bindings/media/mediatek,mdp3-
> rdma.yaml: ignoring, error parsing file
> warning: no schema found in file:
> ./Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> make: *** [Makefile:1419: dt_binding_check] Error 2
> 
> doc reference errors (make refcheckdocs):
> 
> See 
> https://urldefense.com/v3/__https://patchwork.ozlabs.org/patch/1518477__;!!CTRNKA9wMg0ARbw!2av75m5eJ2hSjFAgkXmPi-gQOv7ITc4RcVm1365xi_QcwQlFdg7oYQsw4pZf2ft_$
>  
> 
> This check can fail if there are any dependencies. The base for a
> patch
> series is generally the most recent rc1.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up
> to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 

From dsahern at gmail.com  Sun Aug 22 20:01:44 2021
From: dsahern at gmail.com (David Ahern)
Date: Sun, 22 Aug 2021 20:01:44 -0700
Subject: [PATCH net-next v4] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value in the RA message
In-Reply-To: <20210821061030.26632-1-rocco.yue@mediatek.com>
References: <ad32c931-3056-cdef-4b9b-aab654c61cb9@gmail.com>
 <20210821061030.26632-1-rocco.yue@mediatek.com>
Message-ID: <a4a52162-c645-b369-a9f3-120f48115cde@gmail.com>

On 8/21/21 12:10 AM, Rocco Yue wrote:
> In this patch, if an RA no longer carries an MTU or if accept_ra_mtu is reset,
> in6_dev->ra_mtu will not be reset to 0, its value will remain the previous
> accept_ra_mtu=1 and the value of the mtu carried in the RA msg. This behavior
> is same with mtu6. This should be reasonable, it would show that the device
> had indeed received the ra_mtu before set accept_ra_mtu to 0 or an RA no longer
> carries an mtu value. I am willing to listen to your suggestions and make
> changes if needed, maybe it needs to add a new separate proc handler for
> accept_ra_mtu.

fair point. Consistency is important.


> 
> In addition, at your prompt, I find that this patch maybe have a defect for
> some types of virtual devices, that is, when the state of the virtual device
> updates the value of ra_mtu during the UP period, when its state is set to
> DOWN, ra_mtu is not reset to 0, so that its ra_mtu value remains the previous
> value after the interface is re-UP. I think I need to fix it.
> 

Please do. Also, that problem should apply to all netdev's not just
virtual devices if you are referring to admin down (e.g., ip link set
$DEV down)


From chuanjia.liu at mediatek.com  Sun Aug 22 20:27:54 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 23 Aug 2021 11:27:54 +0800
Subject: [PATCH v12 0/6] PCI: mediatek: Spilt PCIe node to comply with
 hardware design 
Message-ID: <20210823032800.1660-1-chuanjia.liu@mediatek.com>

There are two independent PCIe controllers in MT2712 and MT7622 platform.
Each of them should contain an independent MSI domain.
 
In old dts architecture, MSI domain will be inherited from the root
bridge, and all of the devices will share the same MSI domain.Hence that,
the PCIe devices will not work properly if the irq number which required
is more than 32.
 
Split the PCIe node for MT2712 and MT7622 platform to comply with 
the hardware design and fix MSI issue.
 
change note:
 v12:Add Reviwe by Rob. According to Bjorn's suggestion, 
     split the driver patch into three parts and rewrite 
     the commit logs, there is no code change
 v11:Rebase for 5.14-rc1 and add "interrupt-names", "linux,pci-domain"
     description in binding file. No code change.
 v10:Rebase for 5.13-rc1, no code change.
 v9:fix kernel-ci bot warning. In the scene of using new dts format,
    when mtk_pcie_parse_port fails, of_node_put don't need to be called.
 v8:remove slot node and fix yaml warning.
 v7:dt-bindings file was modified as suggested by Rob, other file no
    change.
 v6:Fix yaml error. make sure driver compatible with old and
    new DTS format.
 v5:rebase for 5.9-rc1, no code change.
 v4:change commit message due to bayes statistical bogofilter
    considers this series patch SPAM.
 v3:rebase for 5.8-rc1. Only collect ack of Ryder, No code change.
 v2:change the allocation of MT2712 PCIe MMIO space due to the
    allocation size is not right in v1.
				      
Chuanjia Liu (6):
  dt-bindings: PCI: mediatek: Update the Device tree bindings
  PCI: mediatek: Add new method to get shared pcie-cfg base address
  PCI: mediatek: Add new method to get irq number
  PCI: mediatek: Get pci domain and decide how to parse node
  arm64: dts: mediatek: Split PCIe node for MT2712 and MT7622
  ARM: dts: mediatek: Update MT7629 PCIe node for new format

  .../bindings/pci/mediatek-pcie-cfg.yaml       |  39 ++++
  .../devicetree/bindings/pci/mediatek-pcie.txt | 206 ++++++++++--------
  arch/arm/boot/dts/mt7629-rfb.dts              |   3 +-
  arch/arm/boot/dts/mt7629.dtsi                 |  45 ++--
  arch/arm64/boot/dts/mediatek/mt2712e.dtsi     |  97 +++++----
  .../dts/mediatek/mt7622-bananapi-bpi-r64.dts  |  16 +-
  arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts  |   6 +-
  arch/arm64/boot/dts/mediatek/mt7622.dtsi      | 112 +++++-----
  drivers/pci/controller/pcie-mediatek.c        |  52 +++--
9 files changed, 330 insertions(+), 246 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml
 
--
2.18.0
	 

From chuanjia.liu at mediatek.com  Sun Aug 22 20:27:55 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 23 Aug 2021 11:27:55 +0800
Subject: [PATCH v12 1/6] dt-bindings: PCI: mediatek: Update the Device tree
 bindings
In-Reply-To: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
References: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
Message-ID: <20210823032800.1660-2-chuanjia.liu@mediatek.com>

There are two independent PCIe controllers in MT2712 and MT7622
platform. Each of them should contain an independent MSI domain.

In old dts architecture, MSI domain will be inherited from the root
bridge, and all of the devices will share the same MSI domain.
Hence that, the PCIe devices will not work properly if the irq number
which required is more than 32.

Split the PCIe node for MT2712 and MT7622 platform to comply with
the hardware design and fix MSI issue.

Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
Acked-by: Ryder Lee <ryder.lee at mediatek.com>
Reviewed-by: Rob Herring <robh+dt at kernel.org>

---
 .../bindings/pci/mediatek-pcie-cfg.yaml       |  39 ++++
 .../devicetree/bindings/pci/mediatek-pcie.txt | 206 ++++++++++--------
 2 files changed, 150 insertions(+), 95 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml

diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml
new file mode 100644
index 000000000000..841a3d284bbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/mediatek-pcie-cfg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek PCIECFG controller
+
+maintainers:
+  - Chuanjia Liu <chuanjia.liu at mediatek.com>
+  - Jianjun Wang <jianjun.wang at mediatek.com>
+
+description: |
+  The MediaTek PCIECFG controller controls some feature about
+  LTSSM, ASPM and so on.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,generic-pciecfg
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    pciecfg: pciecfg at 1a140000 {
+        compatible = "mediatek,generic-pciecfg", "syscon";
+        reg = <0x1a140000 0x1000>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
index 7468d666763a..57ae73462272 100644
--- a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
@@ -8,7 +8,7 @@ Required properties:
 	"mediatek,mt7623-pcie"
 	"mediatek,mt7629-pcie"
 - device_type: Must be "pci"
-- reg: Base addresses and lengths of the PCIe subsys and root ports.
+- reg: Base addresses and lengths of the root ports.
 - reg-names: Names of the above areas to use during resource lookup.
 - #address-cells: Address representation for root ports (must be 3)
 - #size-cells: Size representation for root ports (must be 2)
@@ -47,9 +47,12 @@ Required properties for MT7623/MT2701:
 - reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the
   number of root ports.
 
-Required properties for MT2712/MT7622:
+Required properties for MT2712/MT7622/MT7629:
 -interrupts: A list of interrupt outputs of the controller, must have one
 	     entry for each PCIe port
+- interrupt-names: Must include the following entries:
+	- "pcie_irq": The interrupt that is asserted when an MSI/INTX is received
+- linux,pci-domain: PCI domain ID. Should be unique for each host controller
 
 In addition, the device tree node must have sub-nodes describing each
 PCIe port interface, having the following mandatory properties:
@@ -143,130 +146,143 @@ Examples for MT7623:
 
 Examples for MT2712:
 
-	pcie: pcie at 11700000 {
+	pcie1: pcie at 112ff000 {
 		compatible = "mediatek,mt2712-pcie";
 		device_type = "pci";
-		reg = <0 0x11700000 0 0x1000>,
-		      <0 0x112ff000 0 0x1000>;
-		reg-names = "port0", "port1";
+		reg = <0 0x112ff000 0 0x1000>;
+		reg-names = "port1";
+		linux,pci-domain = <1>;
 		#address-cells = <3>;
 		#size-cells = <2>;
-		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>,
-			 <&topckgen CLK_TOP_PE2_MAC_P1_SEL>,
-			 <&pericfg CLK_PERI_PCIE0>,
+		interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie_irq";
+		clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>,
 			 <&pericfg CLK_PERI_PCIE1>;
-		clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1";
-		phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>;
-		phy-names = "pcie-phy0", "pcie-phy1";
+		clock-names = "sys_ck1", "ahb_ck1";
+		phys = <&u3port1 PHY_TYPE_PCIE>;
+		phy-names = "pcie-phy1";
 		bus-range = <0x00 0xff>;
-		ranges = <0x82000000 0 0x20000000  0x0 0x20000000  0 0x10000000>;
+		ranges = <0x82000000 0 0x11400000  0x0 0x11400000  0 0x300000>;
+		status = "disabled";
 
-		pcie0: pcie at 0,0 {
-			reg = <0x0000 0 0 0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+		#interrupt-cells = <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>;
-			ranges;
-			interrupt-map-mask = <0 0 0 7>;
-			interrupt-map = <0 0 0 1 &pcie_intc0 0>,
-					<0 0 0 2 &pcie_intc0 1>,
-					<0 0 0 3 &pcie_intc0 2>,
-					<0 0 0 4 &pcie_intc0 3>;
-			pcie_intc0: interrupt-controller {
-				interrupt-controller;
-				#address-cells = <0>;
-				#interrupt-cells = <1>;
-			};
 		};
+	};
 
-		pcie1: pcie at 1,0 {
-			reg = <0x0800 0 0 0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+	pcie0: pcie at 11700000 {
+		compatible = "mediatek,mt2712-pcie";
+		device_type = "pci";
+		reg = <0 0x11700000 0 0x1000>;
+		reg-names = "port0";
+		linux,pci-domain = <0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie_irq";
+		clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>,
+			 <&pericfg CLK_PERI_PCIE0>;
+		clock-names = "sys_ck0", "ahb_ck0";
+		phys = <&u3port0 PHY_TYPE_PCIE>;
+		phy-names = "pcie-phy0";
+		bus-range = <0x00 0xff>;
+		ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
+		status = "disabled";
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+				<0 0 0 2 &pcie_intc0 1>,
+				<0 0 0 3 &pcie_intc0 2>,
+				<0 0 0 4 &pcie_intc0 3>;
+		pcie_intc0: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
 			#interrupt-cells = <1>;
-			ranges;
-			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>;
-			};
 		};
 	};
 
 Examples for MT7622:
 
-	pcie: pcie at 1a140000 {
+	pcie0: pcie at 1a143000 {
 		compatible = "mediatek,mt7622-pcie";
 		device_type = "pci";
-		reg = <0 0x1a140000 0 0x1000>,
-		      <0 0x1a143000 0 0x1000>,
-		      <0 0x1a145000 0 0x1000>;
-		reg-names = "subsys", "port0", "port1";
+		reg = <0 0x1a143000 0 0x1000>;
+		reg-names = "port0";
+		linux,pci-domain = <0>;
 		#address-cells = <3>;
 		#size-cells = <2>;
-		interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
+		interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "pcie_irq";
 		clocks = <&pciesys CLK_PCIE_P0_MAC_EN>,
-			 <&pciesys CLK_PCIE_P1_MAC_EN>,
 			 <&pciesys CLK_PCIE_P0_AHB_EN>,
-			 <&pciesys CLK_PCIE_P1_AHB_EN>,
 			 <&pciesys CLK_PCIE_P0_AUX_EN>,
-			 <&pciesys CLK_PCIE_P1_AUX_EN>,
 			 <&pciesys CLK_PCIE_P0_AXI_EN>,
-			 <&pciesys CLK_PCIE_P1_AXI_EN>,
 			 <&pciesys CLK_PCIE_P0_OBFF_EN>,
-			 <&pciesys CLK_PCIE_P1_OBFF_EN>,
-			 <&pciesys CLK_PCIE_P0_PIPE_EN>,
-			 <&pciesys CLK_PCIE_P1_PIPE_EN>;
-		clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1",
-			      "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1",
-			      "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1";
-		phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>;
-		phy-names = "pcie-phy0", "pcie-phy1";
+			 <&pciesys CLK_PCIE_P0_PIPE_EN>;
+		clock-names = "sys_ck0", "ahb_ck0", "aux_ck0",
+			      "axi_ck0", "obff_ck0", "pipe_ck0";
+
 		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
 		bus-range = <0x00 0xff>;
-		ranges = <0x82000000 0 0x20000000  0x0 0x20000000  0 0x10000000>;
+		ranges = <0x82000000 0 0x20000000  0x0 0x20000000  0 0x8000000>;
+		status = "disabled";
 
-		pcie0: pcie at 0,0 {
-			reg = <0x0000 0 0 0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+				<0 0 0 2 &pcie_intc0 1>,
+				<0 0 0 3 &pcie_intc0 2>,
+				<0 0 0 4 &pcie_intc0 3>;
+		pcie_intc0: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
 			#interrupt-cells = <1>;
-			ranges;
-			interrupt-map-mask = <0 0 0 7>;
-			interrupt-map = <0 0 0 1 &pcie_intc0 0>,
-					<0 0 0 2 &pcie_intc0 1>,
-					<0 0 0 3 &pcie_intc0 2>,
-					<0 0 0 4 &pcie_intc0 3>;
-			pcie_intc0: interrupt-controller {
-				interrupt-controller;
-				#address-cells = <0>;
-				#interrupt-cells = <1>;
-			};
 		};
+	};
 
-		pcie1: pcie at 1,0 {
-			reg = <0x0800 0 0 0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+	pcie1: pcie at 1a145000 {
+		compatible = "mediatek,mt7622-pcie";
+		device_type = "pci";
+		reg = <0 0x1a145000 0 0x1000>;
+		reg-names = "port1";
+		linux,pci-domain = <1>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "pcie_irq";
+		clocks = <&pciesys CLK_PCIE_P1_MAC_EN>,
+			 /* designer has connect RC1 with p0_ahb clock */
+			 <&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";
+
+		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
+		bus-range = <0x00 0xff>;
+		ranges = <0x82000000 0 0x28000000  0x0 0x28000000  0 0x8000000>;
+		status = "disabled";
+
+		#interrupt-cells = <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>;
-			ranges;
-			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>;
-			};
 		};
 	};
-- 
2.18.0

From chuanjia.liu at mediatek.com  Sun Aug 22 20:27:56 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 23 Aug 2021 11:27:56 +0800
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared pcie-cfg
 base address
In-Reply-To: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
References: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
Message-ID: <20210823032800.1660-3-chuanjia.liu@mediatek.com>

For the new dts format, add a new method to get
shared pcie-cfg base address and use it to configure
the PCIECFG controller

Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
Acked-by: Ryder Lee <ryder.lee at mediatek.com>
---
 drivers/pci/controller/pcie-mediatek.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index 25bee693834f..4296d9e04240 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -14,6 +14,7 @@
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
 #include <linux/msi.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
@@ -23,6 +24,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/regmap.h>
 #include <linux/reset.h>
 
 #include "../pci.h"
@@ -207,6 +209,7 @@ struct mtk_pcie_port {
  * struct mtk_pcie - PCIe host information
  * @dev: pointer to PCIe device
  * @base: IO mapped register base
+ * @cfg: IO mapped register map for PCIe config
  * @free_ck: free-run reference clock
  * @mem: non-prefetchable memory resource
  * @ports: pointer to PCIe port information
@@ -215,6 +218,7 @@ struct mtk_pcie_port {
 struct mtk_pcie {
 	struct device *dev;
 	void __iomem *base;
+	struct regmap *cfg;
 	struct clk *free_ck;
 
 	struct list_head ports;
@@ -682,6 +686,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
 		val |= PCIE_CSR_LTSSM_EN(port->slot) |
 		       PCIE_CSR_ASPM_L1_EN(port->slot);
 		writel(val, pcie->base + PCIE_SYS_CFG_V2);
+	} else if (pcie->cfg) {
+		val = PCIE_CSR_LTSSM_EN(port->slot) |
+		      PCIE_CSR_ASPM_L1_EN(port->slot);
+		regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
 	}
 
 	/* Assert all reset signals */
@@ -985,6 +993,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
 	struct device *dev = pcie->dev;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct resource *regs;
+	struct device_node *cfg_node;
 	int err;
 
 	/* get shared registers, which are optional */
@@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
 			return PTR_ERR(pcie->base);
 	}
 
+	cfg_node = of_find_compatible_node(NULL, NULL,
+					   "mediatek,generic-pciecfg");
+	if (cfg_node) {
+		pcie->cfg = syscon_node_to_regmap(cfg_node);
+		if (IS_ERR(pcie->cfg))
+			return PTR_ERR(pcie->cfg);
+	}
+
 	pcie->free_ck = devm_clk_get(dev, "free_ck");
 	if (IS_ERR(pcie->free_ck)) {
 		if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
-- 
2.18.0

From chuanjia.liu at mediatek.com  Sun Aug 22 20:27:57 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 23 Aug 2021 11:27:57 +0800
Subject: [PATCH v12 3/6] PCI: mediatek: Add new method to get irq number
In-Reply-To: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
References: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
Message-ID: <20210823032800.1660-4-chuanjia.liu@mediatek.com>

Use platform_get_irq_byname() to get the irq number
if the property of "interrupt-names" is defined.

Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
Acked-by: Ryder Lee <ryder.lee at mediatek.com>
---
 drivers/pci/controller/pcie-mediatek.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index 4296d9e04240..19e35ac62d43 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -654,7 +654,11 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
 		return err;
 	}
 
-	port->irq = platform_get_irq(pdev, port->slot);
+	if (of_find_property(dev->of_node, "interrupt-names", NULL))
+		port->irq = platform_get_irq_byname(pdev, "pcie_irq");
+	else
+		port->irq = platform_get_irq(pdev, port->slot);
+
 	if (port->irq < 0)
 		return port->irq;
 
-- 
2.18.0

From chuanjia.liu at mediatek.com  Sun Aug 22 20:27:58 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 23 Aug 2021 11:27:58 +0800
Subject: [PATCH v12 4/6] PCI: mediatek: Get pci domain and decide how to parse
 node
In-Reply-To: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
References: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
Message-ID: <20210823032800.1660-5-chuanjia.liu@mediatek.com>

Use of_get_pci_domain_nr() to get the pci domain.
If the property of "linux,pci-domain" is defined in node,
we assume that the PCIe bridge is an individual bridge,
hence that we only need to parse one port.

Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
Acked-by: Ryder Lee <ryder.lee at mediatek.com>
---
 drivers/pci/controller/pcie-mediatek.c | 29 +++++++++++++++-----------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index 19e35ac62d43..928e0983a900 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -1048,22 +1048,27 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
 	struct device *dev = pcie->dev;
 	struct device_node *node = dev->of_node, *child;
 	struct mtk_pcie_port *port, *tmp;
-	int err;
+	int err, slot;
+
+	slot = of_get_pci_domain_nr(dev->of_node);
+	if (slot < 0) {
+		for_each_available_child_of_node(node, child) {
+			err = of_pci_get_devfn(child);
+			if (err < 0) {
+				dev_err(dev, "failed to get devfn: %d\n", err);
+				goto error_put_node;
+			}
 
-	for_each_available_child_of_node(node, child) {
-		int slot;
+			slot = PCI_SLOT(err);
 
-		err = of_pci_get_devfn(child);
-		if (err < 0) {
-			dev_err(dev, "failed to parse devfn: %d\n", err);
-			goto error_put_node;
+			err = mtk_pcie_parse_port(pcie, child, slot);
+			if (err)
+				goto error_put_node;
 		}
-
-		slot = PCI_SLOT(err);
-
-		err = mtk_pcie_parse_port(pcie, child, slot);
+	} else {
+		err = mtk_pcie_parse_port(pcie, node, slot);
 		if (err)
-			goto error_put_node;
+			return err;
 	}
 
 	err = mtk_pcie_subsys_powerup(pcie);
-- 
2.18.0

From chuanjia.liu at mediatek.com  Sun Aug 22 20:27:59 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 23 Aug 2021 11:27:59 +0800
Subject: [PATCH v12 5/6] arm64: dts: mediatek: Split PCIe node for MT2712 and
 MT7622
In-Reply-To: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
References: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
Message-ID: <20210823032800.1660-6-chuanjia.liu@mediatek.com>

There are two independent PCIe controllers in MT2712 and MT7622
platform. Each of them should contain an independent MSI domain.

In old dts architecture, MSI domain will be inherited from the root
bridge, and all of the devices will share the same MSI domain.
Hence that, the PCIe devices will not work properly if the irq number
which required is more than 32.

Split the PCIe node for MT2712 and MT7622 platform to comply with
the hardware design and fix MSI issue.

Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
Acked-by: Ryder Lee <ryder.lee at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi     |  97 +++++++--------
 .../dts/mediatek/mt7622-bananapi-bpi-r64.dts  |  16 ++-
 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts  |   6 +-
 arch/arm64/boot/dts/mediatek/mt7622.dtsi      | 112 ++++++++++--------
 4 files changed, 118 insertions(+), 113 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index a9cca9c146fd..de16c0d80c30 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -915,64 +915,67 @@
 		};
 	};
 
-	pcie: pcie at 11700000 {
+	pcie1: pcie at 112ff000 {
 		compatible = "mediatek,mt2712-pcie";
 		device_type = "pci";
-		reg = <0 0x11700000 0 0x1000>,
-		      <0 0x112ff000 0 0x1000>;
-		reg-names = "port0", "port1";
+		reg = <0 0x112ff000 0 0x1000>;
+		reg-names = "port1";
+		linux,pci-domain = <1>;
 		#address-cells = <3>;
 		#size-cells = <2>;
-		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>,
-			 <&topckgen CLK_TOP_PE2_MAC_P1_SEL>,
-			 <&pericfg CLK_PERI_PCIE0>,
+		interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie_irq";
+		clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>,
 			 <&pericfg CLK_PERI_PCIE1>;
-		clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1";
-		phys = <&u3port0 PHY_TYPE_PCIE>, <&u3port1 PHY_TYPE_PCIE>;
-		phy-names = "pcie-phy0", "pcie-phy1";
+		clock-names = "sys_ck1", "ahb_ck1";
+		phys = <&u3port1 PHY_TYPE_PCIE>;
+		phy-names = "pcie-phy1";
 		bus-range = <0x00 0xff>;
-		ranges = <0x82000000 0 0x20000000  0x0 0x20000000  0 0x10000000>;
+		ranges = <0x82000000 0 0x11400000  0x0 0x11400000  0 0x300000>;
+		status = "disabled";
 
-		pcie0: pcie at 0,0 {
-			device_type = "pci";
-			status = "disabled";
-			reg = <0x0000 0 0 0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+		#interrupt-cells = <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>;
-			ranges;
-			interrupt-map-mask = <0 0 0 7>;
-			interrupt-map = <0 0 0 1 &pcie_intc0 0>,
-					<0 0 0 2 &pcie_intc0 1>,
-					<0 0 0 3 &pcie_intc0 2>,
-					<0 0 0 4 &pcie_intc0 3>;
-			pcie_intc0: interrupt-controller {
-				interrupt-controller;
-				#address-cells = <0>;
-				#interrupt-cells = <1>;
-			};
 		};
+	};
 
-		pcie1: pcie at 1,0 {
-			device_type = "pci";
-			status = "disabled";
-			reg = <0x0800 0 0 0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+	pcie0: pcie at 11700000 {
+		compatible = "mediatek,mt2712-pcie";
+		device_type = "pci";
+		reg = <0 0x11700000 0 0x1000>;
+		reg-names = "port0";
+		linux,pci-domain = <0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie_irq";
+		clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>,
+			 <&pericfg CLK_PERI_PCIE0>;
+		clock-names = "sys_ck0", "ahb_ck0";
+		phys = <&u3port0 PHY_TYPE_PCIE>;
+		phy-names = "pcie-phy0";
+		bus-range = <0x00 0xff>;
+		ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
+		status = "disabled";
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+				<0 0 0 2 &pcie_intc0 1>,
+				<0 0 0 3 &pcie_intc0 2>,
+				<0 0 0 4 &pcie_intc0 3>;
+		pcie_intc0: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
 			#interrupt-cells = <1>;
-			ranges;
-			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>;
-			};
 		};
 	};
 
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
index 2f77dc40b9b8..2b9bf8dd14ec 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -257,18 +257,16 @@
 	};
 };
 
-&pcie {
+&pcie0 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>;
+	pinctrl-0 = <&pcie0_pins>;
 	status = "okay";
+};
 
-	pcie at 0,0 {
-		status = "okay";
-	};
-
-	pcie at 1,0 {
-		status = "okay";
-	};
+&pcie1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_pins>;
+	status = "okay";
 };
 
 &pio {
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index f2dc850010f1..596c073d8b05 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -234,14 +234,10 @@
 	};
 };
 
-&pcie {
+&pcie0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie0_pins>;
 	status = "okay";
-
-	pcie at 0,0 {
-		status = "okay";
-	};
 };
 
 &pio {
diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index 890a942ec608..6f8cb3ad1e84 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -781,75 +781,83 @@
 		#reset-cells = <1>;
 	};
 
-	pcie: pcie at 1a140000 {
+	pciecfg: pciecfg at 1a140000 {
+		compatible = "mediatek,generic-pciecfg", "syscon";
+		reg = <0 0x1a140000 0 0x1000>;
+	};
+
+	pcie0: pcie at 1a143000 {
 		compatible = "mediatek,mt7622-pcie";
 		device_type = "pci";
-		reg = <0 0x1a140000 0 0x1000>,
-		      <0 0x1a143000 0 0x1000>,
-		      <0 0x1a145000 0 0x1000>;
-		reg-names = "subsys", "port0", "port1";
+		reg = <0 0x1a143000 0 0x1000>;
+		reg-names = "port0";
+		linux,pci-domain = <0>;
 		#address-cells = <3>;
 		#size-cells = <2>;
-		interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
+		interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "pcie_irq";
 		clocks = <&pciesys CLK_PCIE_P0_MAC_EN>,
-			 <&pciesys CLK_PCIE_P1_MAC_EN>,
-			 <&pciesys CLK_PCIE_P0_AHB_EN>,
 			 <&pciesys CLK_PCIE_P0_AHB_EN>,
 			 <&pciesys CLK_PCIE_P0_AUX_EN>,
-			 <&pciesys CLK_PCIE_P1_AUX_EN>,
 			 <&pciesys CLK_PCIE_P0_AXI_EN>,
-			 <&pciesys CLK_PCIE_P1_AXI_EN>,
 			 <&pciesys CLK_PCIE_P0_OBFF_EN>,
-			 <&pciesys CLK_PCIE_P1_OBFF_EN>,
-			 <&pciesys CLK_PCIE_P0_PIPE_EN>,
-			 <&pciesys CLK_PCIE_P1_PIPE_EN>;
-		clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1",
-			      "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1",
-			      "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1";
+			 <&pciesys CLK_PCIE_P0_PIPE_EN>;
+		clock-names = "sys_ck0", "ahb_ck0", "aux_ck0",
+			      "axi_ck0", "obff_ck0", "pipe_ck0";
+
 		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
 		bus-range = <0x00 0xff>;
-		ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>;
+		ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
 		status = "disabled";
 
-		pcie0: pcie at 0,0 {
-			reg = <0x0000 0 0 0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+				<0 0 0 2 &pcie_intc0 1>,
+				<0 0 0 3 &pcie_intc0 2>,
+				<0 0 0 4 &pcie_intc0 3>;
+		pcie_intc0: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
 			#interrupt-cells = <1>;
-			ranges;
-			status = "disabled";
-
-			interrupt-map-mask = <0 0 0 7>;
-			interrupt-map = <0 0 0 1 &pcie_intc0 0>,
-					<0 0 0 2 &pcie_intc0 1>,
-					<0 0 0 3 &pcie_intc0 2>,
-					<0 0 0 4 &pcie_intc0 3>;
-			pcie_intc0: interrupt-controller {
-				interrupt-controller;
-				#address-cells = <0>;
-				#interrupt-cells = <1>;
-			};
 		};
+	};
 
-		pcie1: pcie at 1,0 {
-			reg = <0x0800 0 0 0 0>;
-			#address-cells = <3>;
-			#size-cells = <2>;
+	pcie1: pcie at 1a145000 {
+		compatible = "mediatek,mt7622-pcie";
+		device_type = "pci";
+		reg = <0 0x1a145000 0 0x1000>;
+		reg-names = "port1";
+		linux,pci-domain = <1>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "pcie_irq";
+		clocks = <&pciesys CLK_PCIE_P1_MAC_EN>,
+			 /* designer has connect RC1 with p0_ahb clock */
+			 <&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";
+
+		power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
+		bus-range = <0x00 0xff>;
+		ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
+		status = "disabled";
+
+		#interrupt-cells = <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>;
-			ranges;
-			status = "disabled";
-
-			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>;
-			};
 		};
 	};
 
-- 
2.18.0

From chuanjia.liu at mediatek.com  Sun Aug 22 20:28:00 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 23 Aug 2021 11:28:00 +0800
Subject: [PATCH v12 6/6] ARM: dts: mediatek: Update MT7629 PCIe node for new
 format
In-Reply-To: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
References: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
Message-ID: <20210823032800.1660-7-chuanjia.liu@mediatek.com>

To match the new dts binding. Remove "subsys",unused
interrupt and slot node.Add "interrupt-names",
"linux,pci-domain" and pciecfg node.

Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
Acked-by: Ryder Lee <ryder.lee at mediatek.com>
---
 arch/arm/boot/dts/mt7629-rfb.dts |  3 ++-
 arch/arm/boot/dts/mt7629.dtsi    | 45 +++++++++++++++-----------------
 2 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/arch/arm/boot/dts/mt7629-rfb.dts b/arch/arm/boot/dts/mt7629-rfb.dts
index 9980c10c6e29..eb536cbebd9b 100644
--- a/arch/arm/boot/dts/mt7629-rfb.dts
+++ b/arch/arm/boot/dts/mt7629-rfb.dts
@@ -140,9 +140,10 @@
 	};
 };
 
-&pcie {
+&pcie1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie_pins>;
+	status = "okay";
 };
 
 &pciephy1 {
diff --git a/arch/arm/boot/dts/mt7629.dtsi b/arch/arm/boot/dts/mt7629.dtsi
index 874043f0490d..46fc236e1b89 100644
--- a/arch/arm/boot/dts/mt7629.dtsi
+++ b/arch/arm/boot/dts/mt7629.dtsi
@@ -361,16 +361,21 @@
 			#reset-cells = <1>;
 		};
 
-		pcie: pcie at 1a140000 {
+		pciecfg: pciecfg at 1a140000 {
+			compatible = "mediatek,generic-pciecfg", "syscon";
+			reg = <0x1a140000 0x1000>;
+		};
+
+		pcie1: pcie at 1a145000 {
 			compatible = "mediatek,mt7629-pcie";
 			device_type = "pci";
-			reg = <0x1a140000 0x1000>,
-			      <0x1a145000 0x1000>;
-			reg-names = "subsys","port1";
+			reg = <0x1a145000 0x1000>;
+			reg-names = "port1";
+			linux,pci-domain = <1>;
 			#address-cells = <3>;
 			#size-cells = <2>;
-			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_LOW>,
-				     <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
+			interrupt-names = "pcie_irq";
 			clocks = <&pciesys CLK_PCIE_P1_MAC_EN>,
 				 <&pciesys CLK_PCIE_P0_AHB_EN>,
 				 <&pciesys CLK_PCIE_P1_AUX_EN>,
@@ -391,26 +396,18 @@
 			power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
 			bus-range = <0x00 0xff>;
 			ranges = <0x82000000 0 0x20000000 0x20000000 0 0x10000000>;
+			status = "disabled";
 
-			pcie1: pcie at 1,0 {
-				device_type = "pci";
-				reg = <0x0800 0 0 0 0>;
-				#address-cells = <3>;
-				#size-cells = <2>;
+			#interrupt-cells = <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>;
-				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>;
-				};
 			};
 		};
 
-- 
2.18.0

From dqfext at gmail.com  Sun Aug 22 21:44:21 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Mon, 23 Aug 2021 12:44:21 +0800
Subject: [PATCH net] net: phy: mediatek: add the missing suspend/resume
 callbacks
Message-ID: <20210823044422.164184-1-dqfext@gmail.com>

Without suspend/resume callbacks, the PHY cannot be powered down/up
administratively.

Fixes: e40d2cca0189 ("net: phy: add MediaTek Gigabit Ethernet PHY driver")
Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 drivers/net/phy/mediatek-ge.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/phy/mediatek-ge.c b/drivers/net/phy/mediatek-ge.c
index 11ff335d6228..b7a5ae20edd5 100644
--- a/drivers/net/phy/mediatek-ge.c
+++ b/drivers/net/phy/mediatek-ge.c
@@ -81,6 +81,8 @@ static struct phy_driver mtk_gephy_driver[] = {
 		 */
 		.config_intr	= genphy_no_config_intr,
 		.handle_interrupt = genphy_handle_interrupt_no_ack,
+		.suspend	= genphy_suspend,
+		.resume		= genphy_resume,
 		.read_page	= mtk_gephy_read_page,
 		.write_page	= mtk_gephy_write_page,
 	},
@@ -93,6 +95,8 @@ static struct phy_driver mtk_gephy_driver[] = {
 		 */
 		.config_intr	= genphy_no_config_intr,
 		.handle_interrupt = genphy_handle_interrupt_no_ack,
+		.suspend	= genphy_suspend,
+		.resume		= genphy_resume,
 		.read_page	= mtk_gephy_read_page,
 		.write_page	= mtk_gephy_write_page,
 	},
-- 
2.25.1



From caihuoqing at baidu.com  Sun Aug 22 21:58:07 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Mon, 23 Aug 2021 12:58:07 +0800
Subject: [PATCH] usb: gadget: aspeed: Remove repeated verbose license text
Message-ID: <20210823045807.49-1-caihuoqing@baidu.com>

remove it because SPDX-License-Identifier is already used

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/usb/gadget/udc/aspeed-vhub/core.c | 5 -----
 drivers/usb/gadget/udc/aspeed-vhub/dev.c  | 5 -----
 drivers/usb/gadget/udc/aspeed-vhub/ep0.c  | 5 -----
 drivers/usb/gadget/udc/aspeed-vhub/epn.c  | 5 -----
 drivers/usb/gadget/udc/aspeed-vhub/hub.c  | 5 -----
 5 files changed, 25 deletions(-)

diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c
index d11d3d14313f..7a635c499777 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/core.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c
@@ -5,11 +5,6 @@
  * core.c - Top level support
  *
  * Copyright 2017 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
index d268306a7bfe..d918e8b2af3c 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
@@ -5,11 +5,6 @@
  * dev.c - Individual device/gadget management (ie, a port = a gadget)
  *
  * Copyright 2017 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/ep0.c b/drivers/usb/gadget/udc/aspeed-vhub/ep0.c
index 022b777b85f8..74ea36c19b1e 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/ep0.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/ep0.c
@@ -5,11 +5,6 @@
  * ep0.c - Endpoint 0 handling
  *
  * Copyright 2017 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c b/drivers/usb/gadget/udc/aspeed-vhub/epn.c
index cb164c615e6f..917892ca8753 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/epn.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/epn.c
@@ -5,11 +5,6 @@
  * epn.c - Generic endpoints management
  *
  * Copyright 2017 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
index 5c7dea5e0ff1..b9960fdd8a51 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
@@ -5,11 +5,6 @@
  * hub.c - virtual hub handling
  *
  * Copyright 2017 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/kernel.h>
-- 
2.25.1



From wenst at chromium.org  Sun Aug 22 23:40:26 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 14:40:26 +0800
Subject: [v2 04/24] clk: mediatek: Add API for clock resource recycle
In-Reply-To: <20210820111504.350-5-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-5-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5G8WUW5ByA12ELrUvHVshwj2nm2wMLYZeFt82g4C7BXpw@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:18 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> In order to avoid resource leak when fail clock registartion appears,

Typo. Please fix if you respin a new version.

> so add the common interface to handle it.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From wenst at chromium.org  Sun Aug 22 23:42:42 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 14:42:42 +0800
Subject: [v2 05/24] clk: mediatek: Fix resource leak in
 mtk_clk_simple_probe
In-Reply-To: <20210820111504.350-6-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-6-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5EReMTGS02SgVO_yrpChOiw++3rwfc0Jx66CBzuDHOXAQ@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:19 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Release clock data when clock driver probe fail to fix
> possible resource leak.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

> ---
>  drivers/clk/mediatek/clk-mtk.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index c3d385c0cfcb..74890759e98c 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -314,7 +314,15 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
>
>         r = mtk_clk_register_gates(node, mcd->clks, mcd->num_clks, clk_data);

Note for future reference: there is no unregister counterpart for
mtk_clk_register_*.


>         if (r)
> -               return r;
> +               goto free_data;
>
> -       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +       if (r)
> +               goto free_data;
> +
> +       return r;
> +
> +free_data:
> +       mtk_free_clk_data(clk_data);
> +       return r;
>  }
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From bbhushan2 at marvell.com  Sun Aug 22 23:51:17 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Mon, 23 Aug 2021 12:21:17 +0530
Subject: [PATCH v3 0/4] cn10k DDR Performance monitor support
Message-ID: <20210823065121.19494-1-bbhushan2@marvell.com>

This patch series adds DDR performance monitor support
on Marvell cn10k series of processor.

First patch adds device tree binding changes.
Second patch add basic support (without overflow and event
ownership). Third and fourth patch adds overflow and event
ownership respectively.

Seems like 4th patch can be merged in second patch,
For easy review it is currently separate

v2->v3:
 - dt-binding, ddrcpmu at 1 -> pmu at 87e1c0000000
 - Add COMPILE_TEST as a dependency
 - Switch to sysfs_emit()
 - Error propagation when invalif event requested
 - Switch to devm_platform_get_and_ioremap_resource()
 - Other review comments on v2.

v1->v2:
 - DT binding changed to new DT Schema
 - writeq/readq changed to respective relaxed
 - Using PMU_EVENT_ATTR_ID

Bharat Bhushan (4):
  dt-bindings: perf: marvell: cn10k ddr performance monitor
  perf/marvell: CN10k DDR performance monitor support
  perf/marvell: cn10k DDR perfmon event overflow handling
  perf/marvell: cn10k DDR perf event core ownership

 .../bindings/perf/marvell-cn10k-ddr.yaml      |  37 +
 drivers/perf/Kconfig                          |   7 +
 drivers/perf/Makefile                         |   1 +
 drivers/perf/marvell_cn10k_ddr_pmu.c          | 756 ++++++++++++++++++
 include/linux/cpuhotplug.h                    |   1 +
 5 files changed, 802 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
 create mode 100644 drivers/perf/marvell_cn10k_ddr_pmu.c

-- 
2.17.1



From bbhushan2 at marvell.com  Sun Aug 22 23:51:18 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Mon, 23 Aug 2021 12:21:18 +0530
Subject: [PATCH v3 1/4] dt-bindings: perf: marvell: cn10k ddr performance
 monitor
In-Reply-To: <20210823065121.19494-1-bbhushan2@marvell.com>
References: <20210823065121.19494-1-bbhushan2@marvell.com>
Message-ID: <20210823065121.19494-2-bbhushan2@marvell.com>

Add binding documentation for the Marvell CN10k DDR
performance monitor unit.

Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
---
v2->v3:
 - dt-binding, ddrcpmu at 1 -> pmu at 87e1c0000000

v1->v2:
 - DT binding changed to new DT Schema

 .../bindings/perf/marvell-cn10k-ddr.yaml      | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml

diff --git a/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
new file mode 100644
index 000000000000..a18dd0a8c43a
--- /dev/null
+++ b/Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/perf/marvell-cn10k-ddr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell CN10K DDR performance monitor
+
+maintainers:
+  - Bharat Bhushan <bbhushan2 at marvell.com>
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - marvell,cn10k-ddr-pmu
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    bus {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        pmu at 87e1c0000000 {
+            compatible = "marvell,cn10k-ddr-pmu";
+            reg = <0x87e1 0xc0000000 0x0 0x10000>;
+        };
+    };
-- 
2.17.1



From bbhushan2 at marvell.com  Sun Aug 22 23:51:19 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Mon, 23 Aug 2021 12:21:19 +0530
Subject: [PATCH v3 2/4] perf/marvell: CN10k DDR performance monitor support
In-Reply-To: <20210823065121.19494-1-bbhushan2@marvell.com>
References: <20210823065121.19494-1-bbhushan2@marvell.com>
Message-ID: <20210823065121.19494-3-bbhushan2@marvell.com>

Marvell CN10k DRAM Subsystem (DSS) supports eight event counters for
monitoring performance and software can program each counter to monitor
any of the defined performance event. Performance events are for
interface between the DDR controller and the PHY, interface between the
DDR Controller and the CHI interconnect, or within the DDR Controller.
Additionally DSS also supports two fixed performance event counters, one
for number of ddr reads and other for ddr writes.

This patch add basic support for these performance monitoring events
on CN10k.

Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
---
v2->v3:
 - Add COMPILE_TEST as a dependency
 - Switch to sysfs_emit()
 - Error propagation when invalif event requested
 - Switch to devm_platform_get_and_ioremap_resource()
 - Other review comments on v2.

v1->v2:
  - writeq/readq changed to respective relaxed version
  - Using PMU_EVENT_ATTR_ID

 drivers/perf/Kconfig                 |   7 +
 drivers/perf/Makefile                |   1 +
 drivers/perf/marvell_cn10k_ddr_pmu.c | 599 +++++++++++++++++++++++++++
 3 files changed, 607 insertions(+)
 create mode 100644 drivers/perf/marvell_cn10k_ddr_pmu.c

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 77522e5efe11..41a80a4b8d29 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -139,4 +139,11 @@ config ARM_DMC620_PMU
 
 source "drivers/perf/hisilicon/Kconfig"
 
+config MARVELL_CN10K_DDR_PMU
+	tristate "Enable MARVELL CN10K DRAM Subsystem(DSS) PMU Support"
+	depends on ARM64
+	help
+	  Enable perf support for Marvell DDR Performance monitoring
+	  event on CN10K platform.
+
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 5260b116c7da..ee1126219d8d 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
 obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
+obj-$(CONFIG_MARVELL_CN10K_DDR_PMU) += marvell_cn10k_ddr_pmu.o
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
new file mode 100644
index 000000000000..9b6d5e716b94
--- /dev/null
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -0,0 +1,599 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell CN10K DRAM Subsystem (DSS) Performance Monitor Driver
+ *
+ * Copyright (C) 2021 Marvell.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/perf_event.h>
+
+/* Performance Counters Operating Mode Control Registers */
+#define DDRC_PERF_CNT_OP_MODE_CTRL	0x8020
+#define OP_MODE_CTRL_VAL_MANNUAL	0x1
+
+/* Performance Counters Start Operation Control Registers */
+#define DDRC_PERF_CNT_START_OP_CTRL	0x8028
+#define START_OP_CTRL_VAL_START		0x1ULL
+#define START_OP_CTRL_VAL_ACTIVE	0x2
+
+/* Performance Counters End Operation Control Registers */
+#define DDRC_PERF_CNT_END_OP_CTRL	0x8030
+#define END_OP_CTRL_VAL_END		0x1ULL
+
+/* Performance Counters End Status Registers */
+#define DDRC_PERF_CNT_END_STATUS		0x8038
+#define END_STATUS_VAL_END_TIMER_MODE_END	0x1
+
+/* Performance Counters Configuration Registers */
+#define DDRC_PERF_CFG_BASE		0x8040
+
+/* 8 Generic event counter + 2 fixed event counters */
+#define DDRC_PERF_NUM_GEN_COUNTERS	8
+#define DDRC_PERF_NUM_FIX_COUNTERS	2
+#define DDRC_PERF_READ_COUNTER_IDX	DDRC_PERF_NUM_GEN_COUNTERS
+#define DDRC_PERF_WRITE_COUNTER_IDX	(DDRC_PERF_NUM_GEN_COUNTERS + 1)
+#define DDRC_PERF_NUM_COUNTERS		(DDRC_PERF_NUM_GEN_COUNTERS + \
+					 DDRC_PERF_NUM_FIX_COUNTERS)
+
+/* Generic event counter registers */
+#define DDRC_PERF_CFG(n)		(DDRC_PERF_CFG_BASE + 8 * (n))
+#define EVENT_ENABLE			BIT_ULL(63)
+
+/* Two dedicated event counters for DDR reads and writes */
+#define EVENT_DDR_READS			101
+#define EVENT_DDR_WRITES		100
+
+/*
+ * programmable events IDs in programmable event counters.
+ * DO NOT change these event-id numbers, they are used to
+ * program event bitmap in h/w.
+ */
+#define EVENT_OP_IS_ZQLATCH			55
+#define EVENT_OP_IS_ZQSTART			54
+#define EVENT_OP_IS_TCR_MRR			53
+#define EVENT_OP_IS_DQSOSC_MRR			52
+#define EVENT_OP_IS_DQSOSC_MPC			51
+#define EVENT_VISIBLE_WIN_LIMIT_REACHED_WR	50
+#define EVENT_VISIBLE_WIN_LIMIT_REACHED_RD	49
+#define EVENT_BSM_STARVATION			48
+#define EVENT_BSM_ALLOC				47
+#define EVENT_LPR_REQ_WITH_NOCREDIT		46
+#define EVENT_HPR_REQ_WITH_NOCREDIT		45
+#define EVENT_OP_IS_ZQCS			44
+#define EVENT_OP_IS_ZQCL			43
+#define EVENT_OP_IS_LOAD_MODE			42
+#define EVENT_OP_IS_SPEC_REF			41
+#define EVENT_OP_IS_CRIT_REF			40
+#define EVENT_OP_IS_REFRESH			39
+#define EVENT_OP_IS_ENTER_MPSM			35
+#define EVENT_OP_IS_ENTER_POWERDOWN		31
+#define EVENT_OP_IS_ENTER_SELFREF		27
+#define EVENT_WAW_HAZARD			26
+#define EVENT_RAW_HAZARD			25
+#define EVENT_WAR_HAZARD			24
+#define EVENT_WRITE_COMBINE			23
+#define EVENT_RDWR_TRANSITIONS			22
+#define EVENT_PRECHARGE_FOR_OTHER		21
+#define EVENT_PRECHARGE_FOR_RDWR		20
+#define EVENT_OP_IS_PRECHARGE			19
+#define EVENT_OP_IS_MWR				18
+#define EVENT_OP_IS_WR				17
+#define EVENT_OP_IS_RD				16
+#define EVENT_OP_IS_RD_ACTIVATE			15
+#define EVENT_OP_IS_RD_OR_WR			14
+#define EVENT_OP_IS_ACTIVATE			13
+#define EVENT_WR_XACT_WHEN_CRITICAL		12
+#define EVENT_LPR_XACT_WHEN_CRITICAL		11
+#define EVENT_HPR_XACT_WHEN_CRITICAL		10
+#define EVENT_DFI_RD_DATA_CYCLES		9
+#define EVENT_DFI_WR_DATA_CYCLES		8
+#define EVENT_ACT_BYPASS			7
+#define EVENT_READ_BYPASS			6
+#define EVENT_HIF_HI_PRI_RD			5
+#define EVENT_HIF_RMW				4
+#define EVENT_HIF_RD				3
+#define EVENT_HIF_WR				2
+#define EVENT_HIF_RD_OR_WR			1
+
+/* Event counter value registers */
+#define DDRC_PERF_CNT_VALUE_BASE		0x8080
+#define DDRC_PERF_CNT_VALUE(n)	(DDRC_PERF_CNT_VALUE_BASE + 8 * (n))
+
+/* Fixed event counter enable/disable register */
+#define DDRC_PERF_CNT_FREERUN_EN	0x80C0
+#define DDRC_PERF_FREERUN_WRITE_EN	0x1
+#define DDRC_PERF_FREERUN_READ_EN	0x2
+
+/* Fixed event counter control register */
+#define DDRC_PERF_CNT_FREERUN_CTRL	0x80C8
+#define DDRC_FREERUN_WRITE_CNT_CLR	0x1
+#define DDRC_FREERUN_READ_CNT_CLR	0x2
+
+/* Fixed event counter value register */
+#define DDRC_PERF_CNT_VALUE_WR_OP	0x80D0
+#define DDRC_PERF_CNT_VALUE_RD_OP	0x80D8
+#define DDRC_PERF_CNT_VALUE_OVERFLOW	BIT_ULL(48)
+#define DDRC_PERF_CNT_MAX_VALUE		GENMASK_ULL(48, 0)
+
+struct cn10k_ddr_pmu {
+	struct pmu pmu;
+	void __iomem *base;
+	unsigned int cpu;
+	struct	device *dev;
+	int active_events;
+	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
+};
+
+#define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu, pmu)
+
+static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
+					struct device_attribute *attr,
+					char *page)
+{
+	struct perf_pmu_events_attr *pmu_attr;
+
+	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
+	return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id);
+
+}
+
+#define CN10K_DDR_PMU_EVENT_ATTR(_name, _id)				     \
+	PMU_EVENT_ATTR_ID(_name, cn10k_ddr_pmu_event_show, _id)
+
+static struct attribute *cn10k_ddr_perf_events_attrs[] = {
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access, EVENT_HIF_RD_OR_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access, EVENT_HIF_RMW),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess, EVENT_HIF_HI_PRI_RD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access, EVENT_READ_BYPASS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access, EVENT_ACT_BYPASS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_wr_data_access, EVENT_DFI_WR_DATA_CYCLES),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_dif_rd_data_access, EVENT_DFI_RD_DATA_CYCLES),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
+					EVENT_HPR_XACT_WHEN_CRITICAL),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
+					EVENT_LPR_XACT_WHEN_CRITICAL),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
+					EVENT_WR_XACT_WHEN_CRITICAL),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access, EVENT_OP_IS_ACTIVATE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access, EVENT_OP_IS_RD_OR_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access, EVENT_OP_IS_RD_ACTIVATE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge, EVENT_OP_IS_PRECHARGE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr, EVENT_PRECHARGE_FOR_RDWR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
+					EVENT_PRECHARGE_FOR_OTHER),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions, EVENT_RDWR_TRANSITIONS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine, EVENT_WRITE_COMBINE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard, EVENT_WAR_HAZARD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard, EVENT_RAW_HAZARD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard, EVENT_WAW_HAZARD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref, EVENT_OP_IS_ENTER_SELFREF),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown, EVENT_OP_IS_ENTER_POWERDOWN),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_mpsm, EVENT_OP_IS_ENTER_MPSM),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode, EVENT_OP_IS_LOAD_MODE),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqcl, EVENT_OP_IS_ZQCL),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_wr_access, EVENT_OP_IS_ZQCS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_hpr_req_with_nocredit,
+					EVENT_HPR_REQ_WITH_NOCREDIT),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_lpr_req_with_nocredit,
+					EVENT_LPR_REQ_WITH_NOCREDIT),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_alloc, EVENT_BSM_ALLOC),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_bsm_starvation, EVENT_BSM_STARVATION),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
+					EVENT_VISIBLE_WIN_LIMIT_REACHED_RD),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
+					EVENT_VISIBLE_WIN_LIMIT_REACHED_WR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc, EVENT_OP_IS_DQSOSC_MPC),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr, EVENT_OP_IS_DQSOSC_MRR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_OP_IS_TCR_MRR),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_OP_IS_ZQSTART),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_OP_IS_ZQLATCH),
+	/* Free run event counters */
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),
+	CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
+	NULL
+};
+
+static struct attribute_group cn10k_ddr_perf_events_attr_group = {
+	.name = "events",
+	.attrs = cn10k_ddr_perf_events_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-8");
+
+static struct attribute *cn10k_ddr_perf_format_attrs[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static struct attribute_group cn10k_ddr_perf_format_attr_group = {
+	.name = "format",
+	.attrs = cn10k_ddr_perf_format_attrs,
+};
+
+static ssize_t cn10k_ddr_perf_cpumask_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct cn10k_ddr_pmu *pmu = dev_get_drvdata(dev);
+
+	return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
+}
+
+static struct device_attribute cn10k_ddr_perf_cpumask_attr =
+	__ATTR(cpumask, 0444, cn10k_ddr_perf_cpumask_show, NULL);
+
+static struct attribute *cn10k_ddr_perf_cpumask_attrs[] = {
+	&cn10k_ddr_perf_cpumask_attr.attr,
+	NULL,
+};
+
+static struct attribute_group cn10k_ddr_perf_cpumask_attr_group = {
+	.attrs = cn10k_ddr_perf_cpumask_attrs,
+};
+
+static const struct attribute_group *cn10k_attr_groups[] = {
+	&cn10k_ddr_perf_events_attr_group,
+	&cn10k_ddr_perf_format_attr_group,
+	&cn10k_ddr_perf_cpumask_attr_group,
+	NULL,
+};
+
+static int ddr_perf_get_event_bitmap(int eventid, u64 *event_bitmap)
+{
+	switch (eventid) {
+	case EVENT_HIF_RD_OR_WR ... EVENT_WAW_HAZARD:
+	case EVENT_OP_IS_REFRESH ... EVENT_OP_IS_ZQLATCH:
+		*event_bitmap = (1ULL << (eventid - 1));
+		break;
+	case EVENT_OP_IS_ENTER_SELFREF:
+	case EVENT_OP_IS_ENTER_POWERDOWN:
+	case EVENT_OP_IS_ENTER_MPSM:
+		*event_bitmap = (0xFULL << (eventid - 1));
+		break;
+	default:
+		pr_err("%s Invalid eventid %d\n", __func__, eventid);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int cn10k_ddr_perf_alloc_counter(struct cn10k_ddr_pmu *pmu,
+					struct perf_event *event)
+{
+	u8 config = event->attr.config;
+	int i;
+
+	/* DDR read free-run counter index */
+	if (config == EVENT_DDR_READS) {
+		pmu->events[DDRC_PERF_READ_COUNTER_IDX] = event;
+		return DDRC_PERF_READ_COUNTER_IDX;
+	}
+
+	/* DDR write free-run counter index */
+	if (config == EVENT_DDR_WRITES) {
+		pmu->events[DDRC_PERF_WRITE_COUNTER_IDX] = event;
+		return DDRC_PERF_WRITE_COUNTER_IDX;
+	}
+
+	/* Allocate DDR generic counters */
+	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+		if (pmu->events[i] == NULL) {
+			pmu->events[i] = event;
+			return i;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static void cn10k_ddr_perf_free_counter(struct cn10k_ddr_pmu *pmu, int counter)
+{
+	pmu->events[counter] = NULL;
+}
+
+static int cn10k_ddr_perf_event_init(struct perf_event *event)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	if (is_sampling_event(event)) {
+		dev_info(pmu->dev, "Sampling not supported!\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (event->cpu < 0) {
+		dev_warn(pmu->dev, "Can't provide per-task data!\n");
+		return -EOPNOTSUPP;
+	}
+
+	/*  We must NOT create groups containing mixed PMUs */
+	if (event->group_leader->pmu != event->pmu &&
+	    !is_software_event(event->group_leader))
+		return -EINVAL;
+
+	/* Set ownership of event to one CPU, same event can not be observed
+	 * on multiple cpus at same time.
+	 */
+	event->cpu = pmu->cpu;
+	hwc->idx = -1;
+	return 0;
+}
+
+static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
+					  int counter, bool enable)
+{
+	u32 reg;
+	u64 val;
+
+	if (counter > DDRC_PERF_NUM_COUNTERS) {
+		pr_err("Error: unsupported counter %d\n", counter);
+		return;
+	}
+
+	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
+		reg = DDRC_PERF_CFG(counter);
+		val = readq_relaxed(pmu->base + reg);
+
+		if (enable)
+			val |= EVENT_ENABLE;
+		else
+			val &= ~EVENT_ENABLE;
+
+		writeq_relaxed(val, pmu->base + reg);
+	} else {
+		val = readq_relaxed(pmu->base + DDRC_PERF_CNT_FREERUN_EN);
+		if (enable) {
+			if (counter == DDRC_PERF_READ_COUNTER_IDX)
+				val |= DDRC_PERF_FREERUN_READ_EN;
+			else
+				val |= DDRC_PERF_FREERUN_WRITE_EN;
+		} else {
+			if (counter == DDRC_PERF_READ_COUNTER_IDX)
+				val &= ~DDRC_PERF_FREERUN_READ_EN;
+			else
+				val &= ~DDRC_PERF_FREERUN_WRITE_EN;
+		}
+		writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_EN);
+	}
+}
+
+static u64 cn10k_ddr_perf_read_counter(struct cn10k_ddr_pmu *pmu, int counter)
+{
+	u64 val;
+
+	if (counter == DDRC_PERF_READ_COUNTER_IDX)
+		return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_RD_OP);
+
+	if (counter == DDRC_PERF_WRITE_COUNTER_IDX)
+		return readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE_WR_OP);
+
+	val = readq_relaxed(pmu->base + DDRC_PERF_CNT_VALUE(counter));
+	return val;
+}
+
+static void cn10k_ddr_perf_event_update(struct perf_event *event)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u64 prev_count, new_count, mask;
+
+	do {
+		prev_count = local64_read(&hwc->prev_count);
+		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+	} while (local64_xchg(&hwc->prev_count, new_count) != prev_count);
+
+	mask = DDRC_PERF_CNT_MAX_VALUE;
+
+	local64_add((new_count - prev_count) & mask, &event->count);
+}
+
+static void cn10k_ddr_perf_event_start(struct perf_event *event, int flags)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int counter = hwc->idx;
+
+	local64_set(&hwc->prev_count, 0);
+
+	cn10k_ddr_perf_counter_enable(pmu, counter, true);
+
+	hwc->state = 0;
+}
+
+static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u8 config = event->attr.config;
+	int counter, ret;
+	u32 reg_offset;
+	u64 val;
+
+	counter = cn10k_ddr_perf_alloc_counter(pmu, event);
+	if (counter < 0)
+		return -EAGAIN;
+
+	pmu->active_events++;
+	hwc->idx = counter;
+
+	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
+		/* Generic counters, configure event id */
+		reg_offset = DDRC_PERF_CFG(counter);
+		ret = ddr_perf_get_event_bitmap(config, &val);
+		if (ret)
+			return ret;
+
+		writeq_relaxed(val, pmu->base + reg_offset);
+	} else {
+		/* fixed event counter, clear counter value */
+		if (counter == DDRC_PERF_READ_COUNTER_IDX)
+			val = DDRC_FREERUN_READ_CNT_CLR;
+		else
+			val = DDRC_FREERUN_WRITE_CNT_CLR;
+
+		writeq_relaxed(val, pmu->base + DDRC_PERF_CNT_FREERUN_CTRL);
+	}
+
+	hwc->state |= PERF_HES_STOPPED;
+
+	if (flags & PERF_EF_START)
+		cn10k_ddr_perf_event_start(event, flags);
+
+	return 0;
+}
+
+static void cn10k_ddr_perf_event_stop(struct perf_event *event, int flags)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int counter = hwc->idx;
+
+	cn10k_ddr_perf_counter_enable(pmu, counter, false);
+
+	if (flags & PERF_EF_UPDATE)
+		cn10k_ddr_perf_event_update(event);
+
+	hwc->state |= PERF_HES_STOPPED;
+}
+
+static void cn10k_ddr_perf_event_del(struct perf_event *event, int flags)
+{
+	struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int counter = hwc->idx;
+
+	cn10k_ddr_perf_event_stop(event, PERF_EF_UPDATE);
+
+	cn10k_ddr_perf_free_counter(pmu, counter);
+	pmu->active_events--;
+	hwc->idx = -1;
+}
+
+static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu)
+{
+	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
+
+	writeq_relaxed(START_OP_CTRL_VAL_START, ddr_pmu->base +
+		       DDRC_PERF_CNT_START_OP_CTRL);
+}
+
+static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu)
+{
+	struct cn10k_ddr_pmu *ddr_pmu = to_cn10k_ddr_pmu(pmu);
+
+	writeq_relaxed(END_OP_CTRL_VAL_END, ddr_pmu->base +
+		       DDRC_PERF_CNT_END_OP_CTRL);
+}
+
+static int cn10k_ddr_perf_probe(struct platform_device *pdev)
+{
+	struct cn10k_ddr_pmu *ddr_pmu;
+	struct resource *res;
+	void __iomem *base;
+	char *name;
+	int ret;
+
+	ddr_pmu = devm_kzalloc(&pdev->dev, sizeof(*ddr_pmu), GFP_KERNEL);
+	if (!ddr_pmu)
+		return -ENOMEM;
+
+	ddr_pmu->dev = &pdev->dev;
+	platform_set_drvdata(pdev, ddr_pmu);
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	ddr_pmu->base = base;
+
+	/* Setup the PMU counter to work in manual mode */
+	writeq_relaxed(OP_MODE_CTRL_VAL_MANNUAL, ddr_pmu->base +
+		       DDRC_PERF_CNT_OP_MODE_CTRL);
+
+	ddr_pmu->pmu = (struct pmu) {
+		.module	      = THIS_MODULE,
+		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+		.task_ctx_nr = perf_invalid_context,
+		.attr_groups = cn10k_attr_groups,
+		.event_init  = cn10k_ddr_perf_event_init,
+		.add	     = cn10k_ddr_perf_event_add,
+		.del	     = cn10k_ddr_perf_event_del,
+		.start	     = cn10k_ddr_perf_event_start,
+		.stop	     = cn10k_ddr_perf_event_stop,
+		.read	     = cn10k_ddr_perf_event_update,
+		.pmu_enable  = cn10k_ddr_perf_pmu_enable,
+		.pmu_disable = cn10k_ddr_perf_pmu_disable,
+	};
+
+	/* Choose this cpu to collect perf data */
+	ddr_pmu->cpu = raw_smp_processor_id();
+
+	name = devm_kasprintf(ddr_pmu->dev, GFP_KERNEL, "mrvl_ddr_pmu_%llx",
+			      res->start);
+	if (!name)
+		return -ENOMEM;
+
+	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
+	if (ret)
+		return ret;
+
+	pr_info("CN10K DDR PMU Driver for ddrc@%llx\n", res->start);
+	return 0;
+}
+
+static int cn10k_ddr_perf_remove(struct platform_device *pdev)
+{
+	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
+
+	perf_pmu_unregister(&ddr_pmu->pmu);
+	return 0;
+}
+
+static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
+	{ .compatible = "marvell,cn10k-ddr-pmu", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
+
+static struct platform_driver cn10k_ddr_pmu_driver = {
+	.driver	= {
+		.name   = "cn10k-ddr-pmu",
+		.of_match_table = cn10k_ddr_pmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe		= cn10k_ddr_perf_probe,
+	.remove		= cn10k_ddr_perf_remove,
+};
+
+static int __init cn10k_ddr_pmu_init(void)
+{
+	return platform_driver_register(&cn10k_ddr_pmu_driver);
+}
+
+static void __exit cn10k_ddr_pmu_exit(void)
+{
+	platform_driver_unregister(&cn10k_ddr_pmu_driver);
+}
+
+module_init(cn10k_ddr_pmu_init);
+module_exit(cn10k_ddr_pmu_exit);
+
+MODULE_AUTHOR("Bharat Bhushan <bbhushan2 at marvell.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1



From bbhushan2 at marvell.com  Sun Aug 22 23:51:20 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Mon, 23 Aug 2021 12:21:20 +0530
Subject: [PATCH v3 3/4] perf/marvell: cn10k DDR perfmon event overflow handling
In-Reply-To: <20210823065121.19494-1-bbhushan2@marvell.com>
References: <20210823065121.19494-1-bbhushan2@marvell.com>
Message-ID: <20210823065121.19494-4-bbhushan2@marvell.com>

CN10k DSS h/w perfmon does not support event overflow interrupt, so
periodic timer is being used. Each event counter is 48bit, which in worst
case scenario can increment at maximum 5.6 GT/s. At this rate it may take
many hours to overflow these counters. Therefore polling period for
overflow is set to 100 sec, which can be changed using sysfs parameter.

Two fixed event counters starts counting from zero on overflow, so
overflow condition is when new count less than previous count. While
eight programmable event counters freezes at maximum value. Also individual
counter cannot be restarted, so need to restart all eight counters.

Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
---
v2->v3:
 - uintXX_t -> uXX

 drivers/perf/marvell_cn10k_ddr_pmu.c | 111 +++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index 9b6d5e716b94..21fccb9090c5 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -11,6 +11,7 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/perf_event.h>
+#include <linux/hrtimer.h>
 
 /* Performance Counters Operating Mode Control Registers */
 #define DDRC_PERF_CNT_OP_MODE_CTRL	0x8020
@@ -127,6 +128,7 @@ struct cn10k_ddr_pmu {
 	struct	device *dev;
 	int active_events;
 	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
+	struct hrtimer hrtimer;
 };
 
 #define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu, pmu)
@@ -251,6 +253,18 @@ static const struct attribute_group *cn10k_attr_groups[] = {
 	NULL,
 };
 
+/* Default poll timeout is 100 sec, which is very sufficient for
+ * 48 bit counter incremented max at 5.6 GT/s, which may take many
+ * hours to overflow.
+ */
+static unsigned long cn10k_ddr_pmu_poll_period_sec = 100;
+module_param_named(poll_period_sec, cn10k_ddr_pmu_poll_period_sec, ulong, 0644);
+
+static ktime_t cn10k_ddr_pmu_timer_period(void)
+{
+	return ms_to_ktime((u64)cn10k_ddr_pmu_poll_period_sec * USEC_PER_SEC);
+}
+
 static int ddr_perf_get_event_bitmap(int eventid, u64 *event_bitmap)
 {
 	switch (eventid) {
@@ -433,6 +447,10 @@ static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
 	pmu->active_events++;
 	hwc->idx = counter;
 
+	if (pmu->active_events == 1)
+		hrtimer_start(&pmu->hrtimer, cn10k_ddr_pmu_timer_period(),
+			      HRTIMER_MODE_REL_PINNED);
+
 	if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
 		/* Generic counters, configure event id */
 		reg_offset = DDRC_PERF_CFG(counter);
@@ -484,6 +502,10 @@ static void cn10k_ddr_perf_event_del(struct perf_event *event, int flags)
 	cn10k_ddr_perf_free_counter(pmu, counter);
 	pmu->active_events--;
 	hwc->idx = -1;
+
+	/* Cancel timer when no events to capture */
+	if (pmu->active_events == 0)
+		hrtimer_cancel(&pmu->hrtimer);
 }
 
 static void cn10k_ddr_perf_pmu_enable(struct pmu *pmu)
@@ -502,6 +524,92 @@ static void cn10k_ddr_perf_pmu_disable(struct pmu *pmu)
 		       DDRC_PERF_CNT_END_OP_CTRL);
 }
 
+static void cn10k_ddr_perf_event_update_all(struct cn10k_ddr_pmu *pmu)
+{
+	struct hw_perf_event *hwc;
+	int i;
+
+	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+		if (pmu->events[i] == NULL)
+			continue;
+
+		cn10k_ddr_perf_event_update(pmu->events[i]);
+	}
+
+	/* Reset previous count as h/w counter are reset */
+	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+		if (pmu->events[i] == NULL)
+			continue;
+
+		hwc = &pmu->events[i]->hw;
+		local64_set(&hwc->prev_count, 0);
+	}
+}
+
+static irqreturn_t cn10k_ddr_pmu_overflow_handler(struct cn10k_ddr_pmu *pmu)
+{
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	u64 prev_count, new_count;
+	u64 value;
+	int i;
+
+	event = pmu->events[DDRC_PERF_READ_COUNTER_IDX];
+	if (event) {
+		hwc = &event->hw;
+		prev_count = local64_read(&hwc->prev_count);
+		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+
+		/* Overflow condition is when new count less than
+		 * previous count
+		 */
+		if (new_count < prev_count)
+			cn10k_ddr_perf_event_update(event);
+	}
+
+	event = pmu->events[DDRC_PERF_WRITE_COUNTER_IDX];
+	if (event) {
+		hwc = &event->hw;
+		prev_count = local64_read(&hwc->prev_count);
+		new_count = cn10k_ddr_perf_read_counter(pmu, hwc->idx);
+
+		/* Overflow condition is when new count less than
+		 * previous count
+		 */
+		if (new_count < prev_count)
+			cn10k_ddr_perf_event_update(event);
+	}
+
+	for (i = 0; i < DDRC_PERF_NUM_GEN_COUNTERS; i++) {
+		if (pmu->events[i] == NULL)
+			continue;
+
+		value = cn10k_ddr_perf_read_counter(pmu, i);
+		if (value == DDRC_PERF_CNT_MAX_VALUE) {
+			pr_info("Counter-(%d) reached max value\n", i);
+			cn10k_ddr_perf_event_update_all(pmu);
+			cn10k_ddr_perf_pmu_disable(&pmu->pmu);
+			cn10k_ddr_perf_pmu_enable(&pmu->pmu);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static enum hrtimer_restart cn10k_ddr_pmu_timer_handler(struct hrtimer *hrtimer)
+{
+	struct cn10k_ddr_pmu *pmu = container_of(hrtimer, struct cn10k_ddr_pmu,
+						 hrtimer);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	cn10k_ddr_pmu_overflow_handler(pmu);
+	local_irq_restore(flags);
+
+	hrtimer_forward_now(hrtimer, cn10k_ddr_pmu_timer_period());
+	return HRTIMER_RESTART;
+}
+
 static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 {
 	struct cn10k_ddr_pmu *ddr_pmu;
@@ -550,6 +658,9 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 	if (!name)
 		return -ENOMEM;
 
+	hrtimer_init(&ddr_pmu->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	ddr_pmu->hrtimer.function = cn10k_ddr_pmu_timer_handler;
+
 	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
 	if (ret)
 		return ret;
-- 
2.17.1



From bbhushan2 at marvell.com  Sun Aug 22 23:51:21 2021
From: bbhushan2 at marvell.com (Bharat Bhushan)
Date: Mon, 23 Aug 2021 12:21:21 +0530
Subject: [PATCH v3 4/4] perf/marvell: cn10k DDR perf event core ownership
In-Reply-To: <20210823065121.19494-1-bbhushan2@marvell.com>
References: <20210823065121.19494-1-bbhushan2@marvell.com>
Message-ID: <20210823065121.19494-5-bbhushan2@marvell.com>

As DDR perf event counters are not per core, so they should be accessed
only by one core at a time. Select new core when previously owning core
is going offline.

Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
---
v2->v3:
 - No change

 drivers/perf/marvell_cn10k_ddr_pmu.c | 50 ++++++++++++++++++++++++++--
 include/linux/cpuhotplug.h           |  1 +
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index 21fccb9090c5..bef0cee3a46a 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -129,6 +129,7 @@ struct cn10k_ddr_pmu {
 	int active_events;
 	struct perf_event *events[DDRC_PERF_NUM_COUNTERS];
 	struct hrtimer hrtimer;
+	struct hlist_node node;
 };
 
 #define to_cn10k_ddr_pmu(p)	container_of(p, struct cn10k_ddr_pmu, pmu)
@@ -610,6 +611,24 @@ static enum hrtimer_restart cn10k_ddr_pmu_timer_handler(struct hrtimer *hrtimer)
 	return HRTIMER_RESTART;
 }
 
+static int cn10k_ddr_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct cn10k_ddr_pmu *pmu = hlist_entry_safe(node, struct cn10k_ddr_pmu,
+						     node);
+	unsigned int target;
+
+	if (cpu != pmu->cpu)
+		return 0;
+
+	target = cpumask_any_but(cpu_online_mask, cpu);
+	if (target >= nr_cpu_ids)
+		return 0;
+
+	perf_pmu_migrate_context(&pmu->pmu, cpu, target);
+	pmu->cpu = target;
+	return 0;
+}
+
 static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 {
 	struct cn10k_ddr_pmu *ddr_pmu;
@@ -661,18 +680,31 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
 	hrtimer_init(&ddr_pmu->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	ddr_pmu->hrtimer.function = cn10k_ddr_pmu_timer_handler;
 
+	cpuhp_state_add_instance_nocalls(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+				&ddr_pmu->node);
+
 	ret = perf_pmu_register(&ddr_pmu->pmu, name, -1);
 	if (ret)
-		return ret;
+		goto error;
 
 	pr_info("CN10K DDR PMU Driver for ddrc@%llx\n", res->start);
 	return 0;
+error:
+	cpuhp_state_remove_instance_nocalls(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+				&ddr_pmu->node);
+	return ret;
 }
 
 static int cn10k_ddr_perf_remove(struct platform_device *pdev)
 {
 	struct cn10k_ddr_pmu *ddr_pmu = platform_get_drvdata(pdev);
 
+	cpuhp_state_remove_instance_nocalls(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+				&ddr_pmu->node);
+
 	perf_pmu_unregister(&ddr_pmu->pmu);
 	return 0;
 }
@@ -695,12 +727,26 @@ static struct platform_driver cn10k_ddr_pmu_driver = {
 
 static int __init cn10k_ddr_pmu_init(void)
 {
-	return platform_driver_register(&cn10k_ddr_pmu_driver);
+	int ret;
+
+	ret = cpuhp_setup_state_multi(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
+				"perf/marvell/cn10k/ddr:online", NULL,
+				cn10k_ddr_pmu_offline_cpu);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&cn10k_ddr_pmu_driver);
+	if (ret)
+		cpuhp_remove_multi_state(
+				CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE);
+	return ret;
 }
 
 static void __exit cn10k_ddr_pmu_exit(void)
 {
 	platform_driver_unregister(&cn10k_ddr_pmu_driver);
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE);
 }
 
 module_init(cn10k_ddr_pmu_init);
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 47e13582d9fc..ce7f2740d7db 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -185,6 +185,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
 	CPUHP_AP_PERF_ARM_APM_XGENE_ONLINE,
 	CPUHP_AP_PERF_ARM_CAVIUM_TX2_UNCORE_ONLINE,
+	CPUHP_AP_PERF_ARM_MARVELL_CN10K_DDR_ONLINE,
 	CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE,
 	CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE,
 	CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE,
-- 
2.17.1



From wenst at chromium.org  Sun Aug 22 23:53:34 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 14:53:34 +0800
Subject: [v2 01/24] dt-bindings: ARM: Mediatek: Add new document bindings
 of MT8195 clock
In-Reply-To: <20210820111504.350-2-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-2-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5FAEFD+dQsZzyZOzmwDDnwLZO3Z8wv8Z-=wVYdjjc3FYg@mail.gmail.com>

Hi,

On Fri, Aug 20, 2021 at 7:17 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> This patch adds the new binding documentation for system clock
> and functional clock on Mediatek MT8195.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  .../arm/mediatek/mediatek,mt8195-clock.yaml   | 254 ++++++++++++++++++
>  .../mediatek/mediatek,mt8195-sys-clock.yaml   |  73 +++++
>  2 files changed, 327 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml
>
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
> new file mode 100644
> index 000000000000..17fcbb45d121
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
> @@ -0,0 +1,254 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8195-clock.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: MediaTek Functional Clock Controller for MT8195
> +
> +maintainers:
> +  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +description:
> +  The clock architecture in Mediatek like below
> +  PLLs -->
> +          dividers -->
> +                      muxes
> +                           -->
> +                              clock gate
> +
> +  The devices except apusys_pll provide clock gate control in different IP blocks.
> +  The apusys_pll provides Plls which generated from SoC 26m for AI Processing Unit.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - mediatek,mt8195-scp_adsp
> +          - mediatek,mt8195-imp_iic_wrap_s
> +          - mediatek,mt8195-imp_iic_wrap_w
> +          - mediatek,mt8195-mfgcfg
> +          - mediatek,mt8195-vppsys0
> +          - mediatek,mt8195-wpesys
> +          - mediatek,mt8195-wpesys_vpp0
> +          - mediatek,mt8195-wpesys_vpp1
> +          - mediatek,mt8195-vppsys1
> +          - mediatek,mt8195-imgsys
> +          - mediatek,mt8195-imgsys1_dip_top
> +          - mediatek,mt8195-imgsys1_dip_nr
> +          - mediatek,mt8195-imgsys1_wpe
> +          - mediatek,mt8195-ipesys
> +          - mediatek,mt8195-camsys
> +          - mediatek,mt8195-camsys_rawa
> +          - mediatek,mt8195-camsys_yuva
> +          - mediatek,mt8195-camsys_rawb
> +          - mediatek,mt8195-camsys_yuvb
> +          - mediatek,mt8195-camsys_mraw
> +          - mediatek,mt8195-ccusys
> +          - mediatek,mt8195-vdecsys_soc
> +          - mediatek,mt8195-vdecsys
> +          - mediatek,mt8195-vdecsys_core1
> +          - mediatek,mt8195-vencsys
> +          - mediatek,mt8195-vencsys_core1
> +          - mediatek,mt8195-apusys_pll

The indentation is slightly off by 2 extra spaces.

[...]

> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml
> new file mode 100644
> index 000000000000..dbf33ea6cb9f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml
> @@ -0,0 +1,73 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8195-sys-clock.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: MediaTek System Clock Controller for MT8195
> +
> +maintainers:
> +  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +description:
> +  The clock architecture in Mediaek like below

Typo.

> +  PLLs -->
> +          dividers -->
> +                      muxes
> +                           -->
> +                              clock gate
> +
> +  The apmixedsys provides most of PLLs which generated from SoC 26m.
> +  The topckgen provides dividers and muxes which provide the clock source to other IP blocks.
> +  The infracfg_ao and pericfg_ao provides clock gate in peripheral and infrastructure IP blocks.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - mediatek,mt8195-topckgen
> +          - mediatek,mt8195-infracfg_ao
> +          - mediatek,mt8195-apmixedsys
> +          - mediatek,mt8195-pericfg_ao

Indentation off here as well.

Otherwise,

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:26 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:26 +0800
Subject: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-2-billy_tsai@aspeedtech.com>

Add device tree bindings document for the aspeed ast2600 adc device
driver.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 .../bindings/iio/adc/aspeed,ast2600-adc.yaml  | 97 +++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml

diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
new file mode 100644
index 000000000000..248cda7d91e9
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ADC that forms part of an ASPEED server management processor.
+
+maintainers:
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+description: |
+  ? 10-bits resolution for 16 voltage channels.
+  ? The device split into two individual engine and each contains 8 voltage
+  channels.
+  ? Channel scanning can be non-continuous.
+  ? Programmable ADC clock frequency.
+  ? Programmable upper and lower threshold for each channels.
+  ? Interrupt when larger or less than threshold for each channels.
+  ? Support hysteresis for each channels.
+  ? Built-in a compensating method.
+  ? Built-in a register to trim internal reference voltage.
+  ? Internal or External reference voltage.
+  ? Support 2 Internal reference voltage 1.2v or 2.5v.
+  ? Integrate dividing circuit for battery sensing.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2600-adc0
+      - aspeed,ast2600-adc1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    description:
+      Input clock used to derive the sample clock. Expected to be the
+      SoC's APB clock.
+
+  resets:
+    maxItems: 1
+
+  "#io-channel-cells":
+    const: 1
+
+  vref-supply:
+    description:
+      The external regulator supply ADC reference voltage.
+
+  aspeed,int_vref_mv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1200, 2500]
+    description:
+      ADC internal reference voltage in millivolts.
+
+  aspeed,battery-sensing:
+    type: boolean
+    description:
+      Inform the driver that last channel will be used to sensor battery.
+
+  aspeed,trim-data-valid:
+    type: boolean
+    description: |
+      The ADC reference voltage can be calibrated to obtain the trimming
+      data which will be stored in otp. This property informs the driver that
+      the data store in the otp is valid.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+  - "#io-channel-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/ast2600-clock.h>
+    adc0: adc at 1e6e9000 {
+        compatible = "aspeed,ast2600-adc0";
+        reg = <0x1e6e9000 0x100>;
+        clocks = <&syscon ASPEED_CLK_APB2>;
+        resets = <&syscon ASPEED_RESET_ADC>;
+        #io-channel-cells = <1>;
+        aspeed,int_vref_mv = <2500>;
+    };
+    adc1: adc at 1e6e9100 {
+        compatible = "aspeed,ast2600-adc1";
+        reg = <0x1e6e9100 0x100>;
+        clocks = <&syscon ASPEED_CLK_APB2>;
+        resets = <&syscon ASPEED_RESET_ADC>;
+        #io-channel-cells = <1>;
+        aspeed,int_vref_mv = <2500>;
+    };
+...
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:32 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:32 +0800
Subject: [v4 07/15] iio: adc: aspeed: Set num_channels with model data
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-8-billy_tsai@aspeedtech.com>

Use the model_data member num_channels to set the num_channels of iio
device.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f260e40ab9b2..2d6215a91f99 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -291,7 +291,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-	indio_dev->num_channels = ARRAY_SIZE(aspeed_adc_iio_channels);
+	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
 	if (ret)
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:34 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:34 +0800
Subject: [v4 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-10-billy_tsai@aspeedtech.com>

This patch use devm_add_action_or_reset to handle the error in probe
phase.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 92 +++++++++++++++++++++---------------
 1 file changed, 55 insertions(+), 37 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 52db38be9699..1c87e12a0cab 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -187,6 +187,27 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static void aspeed_adc_unregister_divider(void *data)
+{
+	struct clk_hw *clk = data;
+
+	clk_hw_unregister_divider(clk);
+}
+
+static void aspeed_adc_reset_assert(void *data)
+{
+	struct reset_control *rst = data;
+
+	reset_control_assert(rst);
+}
+
+static void aspeed_adc_clk_disable_unprepare(void *data)
+{
+	struct clk *clk = data;
+
+	clk_disable_unprepare(clk);
+}
+
 static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			&data->clk_lock);
 		if (IS_ERR(data->clk_prescaler))
 			return PTR_ERR(data->clk_prescaler);
+
+		ret = devm_add_action_or_reset(data->dev,
+					       aspeed_adc_unregister_divider,
+					       data->clk_prescaler);
+		if (ret)
+			return ret;
 		snprintf(clk_parent_name, 32, clk_name);
 		scaler_flags = CLK_SET_RATE_PARENT;
 	}
@@ -244,23 +271,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
 		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
 		data->model_data->scaler_bit_width, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_scaler)) {
-		ret = PTR_ERR(data->clk_scaler);
-		goto scaler_error;
-	}
+	if (IS_ERR(data->clk_scaler))
+		return PTR_ERR(data->clk_scaler);
+
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
+				       data->clk_scaler);
+	if (ret)
+		return ret;
 
 	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(data->rst)) {
 		dev_err(&pdev->dev,
 			"invalid or missing reset controller device tree entry");
-		ret = PTR_ERR(data->rst);
-		goto reset_error;
+		return PTR_ERR(data->rst);
 	}
 	reset_control_deassert(data->rst);
 
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
+				       data->rst);
+	if (ret)
+		return ret;
+
 	ret = aspeed_adc_vref_config(indio_dev);
 	if (ret)
-		goto vref_config_error;
+		return ret;
 
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
@@ -277,13 +311,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 					 ASPEED_ADC_INIT_POLLING_TIME,
 					 ASPEED_ADC_INIT_TIMEOUT);
 		if (ret)
-			goto poll_timeout_error;
+			return ret;
 	}
 
 	/* Start all channels in normal mode. */
 	ret = clk_prepare_enable(data->clk_scaler->clk);
 	if (ret)
-		goto clk_enable_error;
+		return ret;
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_clk_disable_unprepare,
+				       data->clk_scaler->clk);
+	if (ret)
+		return ret;
 
 	adc_engine_control_reg_val =
 		ASPEED_ADC_CTRL_CHANNEL |
@@ -299,41 +339,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto iio_register_error;
-
+	if (ret) {
+		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+				  ASPEED_ADC_OP_MODE_PWR_DOWN),
+		       data->base + ASPEED_REG_ENGINE_CONTROL);
+		return ret;
+	}
 	return 0;
-
-iio_register_error:
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-clk_enable_error:
-poll_timeout_error:
-vref_config_error:
-	reset_control_assert(data->rst);
-reset_error:
-	clk_hw_unregister_divider(data->clk_scaler);
-scaler_error:
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-	return ret;
 }
 
 static int aspeed_adc_remove(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-	struct aspeed_adc_data *data = iio_priv(indio_dev);
-
 	iio_device_unregister(indio_dev);
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-	reset_control_assert(data->rst);
-	clk_hw_unregister_divider(data->clk_scaler);
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-
 	return 0;
 }
 
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:25 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:25 +0800
Subject: [v4 00/15] Add support for ast2600 ADC
Message-ID: <20210823070240.12600-1-billy_tsai@aspeedtech.com>

This patch serials make aspeed_adc.c can support ast2600 and backward
compatible.

Change since v3:
dt-bindings:
  - Fix properties:aspeed,int_vref_mv type error.

Change since v2:
dt-bindings:
  - Create a new dt-bindings for ast2600 adc
aspeed_adc.c:
  - Splits the patch for more details
  - Remove version enum and use the flags in model data to distinguish
  hardware feature
  - Support trimming data get and set.
  - Use devm_add_action_or_reset to simplify probe error handling.

Changes since v1:
dt-bindings:
  - Fix the aspeed,adc.yaml check error.
  - Add battery-sensing property.
aspeed_adc.c:
  - Change the init flow:
    Clock and reference voltage setting should be completed before adc
    engine enable.
  - Change the default sampling rate to meet most user case.
  - Add patch #8 to suppoert battery sensing mode.

Billy Tsai (15):
  dt-bindings: iio: adc: Add ast2600-adc bindings
  iio: adc: aspeed: completes the bitfield declare.
  iio: adc: aspeed: set driver data when adc probe.
  iio: adc: aspeed: Keep model data to driver data.
  iio: adc: aspeed: Refactory model data structure
  iio: adc: aspeed: Add vref config function
  iio: adc: aspeed: Set num_channels with model data
  iio: adc: aspeed: Use model_data to set clk scaler.
  iio: adc: aspeed: Use devm_add_action_or_reset.
  iio: adc: aspeed: Support ast2600 adc.
  iio: adc: aspeed: Fix the calculate error of clock.
  iio: adc: aspeed: Add func to set sampling rate.
  iio: adc: aspeed: Add compensation phase.
  iio: adc: aspeed: Support battery sensing.
  iio: adc: aspeed: Get and set trimming data.

 .../bindings/iio/adc/aspeed,ast2600-adc.yaml  |  97 +++
 drivers/iio/adc/aspeed_adc.c                  | 562 +++++++++++++++---
 2 files changed, 569 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml

-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:27 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:27 +0800
Subject: [v4 02/15] iio: adc: aspeed: completes the bitfield declare.
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-3-billy_tsai@aspeedtech.com>

This patch completes the declare of adc register bitfields and uses the
same prefix ASPEED_ADC_* for these bitfields.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 56 +++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 19efaa41bc34..7010d56ac3b9 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -3,6 +3,7 @@
  * Aspeed AST2400/2500 ADC
  *
  * Copyright (C) 2017 Google, Inc.
+ * Copyright (C) 2021 Aspeed Technology Inc.
  */
 
 #include <linux/clk.h>
@@ -16,6 +17,7 @@
 #include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/bitfield.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
@@ -28,15 +30,31 @@
 #define ASPEED_REG_INTERRUPT_CONTROL	0x04
 #define ASPEED_REG_VGA_DETECT_CONTROL	0x08
 #define ASPEED_REG_CLOCK_CONTROL	0x0C
-#define ASPEED_REG_MAX			0xC0
-
-#define ASPEED_OPERATION_MODE_POWER_DOWN	(0x0 << 1)
-#define ASPEED_OPERATION_MODE_STANDBY		(0x1 << 1)
-#define ASPEED_OPERATION_MODE_NORMAL		(0x7 << 1)
-
-#define ASPEED_ENGINE_ENABLE		BIT(0)
-
-#define ASPEED_ADC_CTRL_INIT_RDY	BIT(8)
+#define ASPEED_REG_COMPENSATION_TRIM	0xC4
+#define ASPEED_REG_MAX			0xCC
+
+#define ASPEED_ADC_ENGINE_ENABLE		BIT(0)
+#define ASPEED_ADC_OP_MODE			GENMASK(3, 1)
+#define ASPEED_ADC_OP_MODE_PWR_DOWN		0
+#define ASPEED_ADC_OP_MODE_STANDBY		1
+#define ASPEED_ADC_OP_MODE_NORMAL		7
+#define ASPEED_ADC_CTRL_COMPENSATION		BIT(4)
+#define ASPEED_ADC_AUTO_COMPENSATION		BIT(5)
+#define ASPEED_ADC_REF_VOLTAGE			GENMASK(7, 6)
+#define ASPEED_ADC_REF_VOLTAGE_2500mV		0
+#define ASPEED_ADC_REF_VOLTAGE_1200mV		1
+#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH		2
+#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW		3
+#define ASPEED_ADC_BAT_SENSING_DIV		BIT(6)
+#define ASPEED_ADC_BAT_SENSING_DIV_2_3		0
+#define ASPEED_ADC_BAT_SENSING_DIV_1_3		1
+#define ASPEED_ADC_CTRL_INIT_RDY		BIT(8)
+#define ASPEED_ADC_CH7_MODE			BIT(12)
+#define ASPEED_ADC_CH7_NORMAL			0
+#define ASPEED_ADC_CH7_BAT			1
+#define ASPEED_ADC_BAT_SENSING_ENABLE		BIT(13)
+#define ASPEED_ADC_CTRL_CHANNEL			GENMASK(31, 16)
+#define ASPEED_ADC_CTRL_CHANNEL_ENABLE(ch)	FIELD_PREP(ASPEED_ADC_CTRL_CHANNEL, BIT(ch))
 
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
@@ -226,7 +244,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	if (model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
-		writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
+		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+				  ASPEED_ADC_OP_MODE_NORMAL) |
+			       ASPEED_ADC_ENGINE_ENABLE,
 		       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 		/* Wait for initial sequence complete. */
@@ -245,10 +265,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		goto clk_enable_error;
 
-	adc_engine_control_reg_val = GENMASK(31, 16) |
-		ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE;
+	adc_engine_control_reg_val =
+		ASPEED_ADC_CTRL_CHANNEL |
+		FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
+		ASPEED_ADC_ENGINE_ENABLE;
 	writel(adc_engine_control_reg_val,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 	model_data = of_device_get_match_data(&pdev->dev);
 	indio_dev->name = model_data->model_name;
@@ -264,8 +286,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	return 0;
 
 iio_register_error:
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
 poll_timeout_error:
@@ -283,8 +305,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
 	clk_hw_unregister_divider(data->clk_scaler);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:33 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:33 +0800
Subject: [v4 08/15] iio: adc: aspeed: Use model_data to set clk scaler.
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-9-billy_tsai@aspeedtech.com>

This patch use need_prescaler and scaler_bit_width to set the adc clock
scaler.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 39 +++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 2d6215a91f99..52db38be9699 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -202,9 +202,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
 	struct aspeed_adc_data *data;
-	const char *clk_parent_name;
 	int ret;
 	u32 adc_engine_control_reg_val;
+	unsigned long scaler_flags = 0;
+	char clk_name[32], clk_parent_name[32];
 
 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
 	if (!indio_dev)
@@ -221,24 +222,28 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	/* Register ADC clock prescaler with source specified by device tree. */
 	spin_lock_init(&data->clk_lock);
-	clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
-
-	data->clk_prescaler = clk_hw_register_divider(
-				&pdev->dev, "prescaler", clk_parent_name, 0,
-				data->base + ASPEED_REG_CLOCK_CONTROL,
-				17, 15, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_prescaler))
-		return PTR_ERR(data->clk_prescaler);
-
+	snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));
+	if (data->model_data->need_prescaler) {
+		snprintf(clk_name, 32, "%s-prescaler",
+			 data->model_data->model_name);
+		data->clk_prescaler = clk_hw_register_divider(
+			&pdev->dev, clk_name, clk_parent_name, 0,
+			data->base + ASPEED_REG_CLOCK_CONTROL, 17, 15, 0,
+			&data->clk_lock);
+		if (IS_ERR(data->clk_prescaler))
+			return PTR_ERR(data->clk_prescaler);
+		snprintf(clk_parent_name, 32, clk_name);
+		scaler_flags = CLK_SET_RATE_PARENT;
+	}
 	/*
 	 * Register ADC clock scaler downstream from the prescaler. Allow rate
 	 * setting to adjust the prescaler as well.
 	 */
+	snprintf(clk_name, 32, "%s-scaler", data->model_data->model_name);
 	data->clk_scaler = clk_hw_register_divider(
-				&pdev->dev, "scaler", "prescaler",
-				CLK_SET_RATE_PARENT,
-				data->base + ASPEED_REG_CLOCK_CONTROL,
-				0, 10, 0, &data->clk_lock);
+		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
+		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
+		data->model_data->scaler_bit_width, 0, &data->clk_lock);
 	if (IS_ERR(data->clk_scaler)) {
 		ret = PTR_ERR(data->clk_scaler);
 		goto scaler_error;
@@ -310,7 +315,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 reset_error:
 	clk_hw_unregister_divider(data->clk_scaler);
 scaler_error:
-	clk_hw_unregister_divider(data->clk_prescaler);
+	if (data->model_data->need_prescaler)
+		clk_hw_unregister_divider(data->clk_prescaler);
 	return ret;
 }
 
@@ -325,7 +331,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
 	clk_hw_unregister_divider(data->clk_scaler);
-	clk_hw_unregister_divider(data->clk_prescaler);
+	if (data->model_data->need_prescaler)
+		clk_hw_unregister_divider(data->clk_prescaler);
 
 	return 0;
 }
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:28 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:28 +0800
Subject: [v4 03/15] iio: adc: aspeed: set driver data when adc probe.
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-4-billy_tsai@aspeedtech.com>

Fix the issue when adc remove will get the null driver data.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 7010d56ac3b9..20462cf659e4 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -201,6 +201,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	platform_set_drvdata(pdev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->base))
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:29 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:29 +0800
Subject: [v4 04/15] iio: adc: aspeed: Keep model data to driver data.
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-5-billy_tsai@aspeedtech.com>

Keep the model data pointer to driver data for reducing the usage of
of_device_get_match_data().

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 20462cf659e4..d85aa31ee3b1 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -69,6 +69,7 @@ struct aspeed_adc_model_data {
 
 struct aspeed_adc_data {
 	struct device		*dev;
+	const struct aspeed_adc_model_data *model_data;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
 	struct clk_hw		*clk_prescaler;
@@ -110,8 +111,6 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       int *val, int *val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -119,7 +118,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = model_data->vref_voltage;
+		*val = data->model_data->vref_voltage;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -138,13 +137,11 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,
 				int val, int val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val < model_data->min_sampling_rate ||
-			val > model_data->max_sampling_rate)
+		if (val < data->model_data->min_sampling_rate ||
+			val > data->model_data->max_sampling_rate)
 			return -EINVAL;
 
 		clk_set_rate(data->clk_scaler->clk,
@@ -190,7 +187,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
 	struct aspeed_adc_data *data;
-	const struct aspeed_adc_model_data *model_data;
 	const char *clk_parent_name;
 	int ret;
 	u32 adc_engine_control_reg_val;
@@ -201,6 +197,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	data->model_data = of_device_get_match_data(&pdev->dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
@@ -241,9 +238,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-
-	if (model_data->wait_init_sequence) {
+	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
 				  ASPEED_ADC_OP_MODE_NORMAL) |
@@ -273,8 +268,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	writel(adc_engine_control_reg_val,
 	       data->base + ASPEED_REG_ENGINE_CONTROL);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-	indio_dev->name = model_data->model_name;
+	indio_dev->name = data->model_data->model_name;
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:30 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:30 +0800
Subject: [v4 05/15] iio: adc: aspeed: Refactory model data structure
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-6-billy_tsai@aspeedtech.com>

This patch refactory the model data structure to distinguish the
function form differnet version of aspeed adc.
- Rename the vref_voltag to vref_fixed and add vref driver data
When driver probe will check vref_fixed value and store it
to vref which isn't const value.
- Add num_channels
Make num_channles of iio device can be changed by differnet model_data
- Add need_prescaler flag and scaler_bit_width
The need_prescaler flag used to tell the driver the clock divider needs
another prescaler and the scaler_bit_width to set the clock divider
bitfiled width.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index d85aa31ee3b1..f03c7921d534 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -63,8 +63,11 @@ struct aspeed_adc_model_data {
 	const char *model_name;
 	unsigned int min_sampling_rate;	// Hz
 	unsigned int max_sampling_rate;	// Hz
-	unsigned int vref_voltage;	// mV
+	unsigned int vref_fixed;	// mV
 	bool wait_init_sequence;
+	bool need_prescaler;
+	u8 scaler_bit_width;
+	unsigned int num_channels;
 };
 
 struct aspeed_adc_data {
@@ -75,6 +78,7 @@ struct aspeed_adc_data {
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
+	int			vref;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -118,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = data->model_data->vref_voltage;
+		*val = data->model_data->vref_fixed;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -312,17 +316,23 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 
 static const struct aspeed_adc_model_data ast2400_model_data = {
 	.model_name = "ast2400-adc",
-	.vref_voltage = 2500, // mV
+	.vref_fixed = 2500, // mV
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
+	.need_prescaler = true,
+	.scaler_bit_width = 10,
+	.num_channels = 16,
 };
 
 static const struct aspeed_adc_model_data ast2500_model_data = {
 	.model_name = "ast2500-adc",
-	.vref_voltage = 1800, // mV
+	.vref_fixed = 1800, // mV
 	.min_sampling_rate = 1,
 	.max_sampling_rate = 1000000,
 	.wait_init_sequence = true,
+	.need_prescaler = true,
+	.scaler_bit_width = 10,
+	.num_channels = 16,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
-- 
2.25.1



From billy_tsai at aspeedtech.com  Mon Aug 23 00:02:31 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 23 Aug 2021 15:02:31 +0800
Subject: [v4 06/15] iio: adc: aspeed: Add vref config function
In-Reply-To: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
Message-ID: <20210823070240.12600-7-billy_tsai@aspeedtech.com>

Add the function to check the vref_fixed and set the value to driver
data.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f03c7921d534..f260e40ab9b2 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -122,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = data->model_data->vref_fixed;
+		*val = data->vref;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -187,6 +187,17 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	if (data->model_data->vref_fixed) {
+		data->vref = data->model_data->vref_fixed;
+		return 0;
+	}
+	return 0;
+}
+
 static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
@@ -242,6 +253,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
+	ret = aspeed_adc_vref_config(indio_dev);
+	if (ret)
+		goto vref_config_error;
+
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
@@ -290,6 +305,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
 poll_timeout_error:
+vref_config_error:
 	reset_control_assert(data->rst);
 reset_error:
 	clk_hw_unregister_divider(data->clk_scaler);
-- 
2.25.1



From dqfext at gmail.com  Mon Aug 23 00:09:27 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Mon, 23 Aug 2021 15:09:27 +0800
Subject: [PATCH 5.4.y] net: dsa: mt7530: fix VLAN traffic leaks again
Message-ID: <20210823070928.166082-1-dqfext@gmail.com>

[ Upstream commit 7428022b50d0fbb4846dd0f00639ea09d36dff02 ]

When a port leaves a VLAN-aware bridge, the current code does not clear
other ports' matrix field bit. If the bridge is later set to VLAN-unaware
mode, traffic in the bridge may leak to that port.

Remove the VLAN filtering check in mt7530_port_bridge_leave.

Fixes: 4fe4e1f48ba1 ("net: dsa: mt7530: fix VLAN traffic leaks")
Fixes: 83163f7dca56 ("net: dsa: mediatek: add VLAN support for MT7530")
Signed-off-by: DENG Qingfang <dqfext at gmail.com>
Reviewed-by: Vladimir Oltean <olteanv at gmail.com>
Signed-off-by: David S. Miller <davem at davemloft.net>
---
 drivers/net/dsa/mt7530.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index aec606058d98..fc45af12612f 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -840,11 +840,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 		/* Remove this port from the port matrix of the other ports
 		 * in the same bridge. If the port is disabled, port matrix
 		 * is kept and not being setup until the port becomes enabled.
-		 * And the other port's port matrix cannot be broken when the
-		 * other port is still a VLAN-aware port.
 		 */
-		if (dsa_is_user_port(ds, i) && i != port &&
-		   !dsa_port_is_vlan_filtering(&ds->ports[i])) {
+		if (dsa_is_user_port(ds, i) && i != port) {
 			if (dsa_to_port(ds, i)->bridge_dev != bridge)
 				continue;
 			if (priv->ports[i].enable)
-- 
2.25.1



From iwamatsu at nigauri.org  Mon Aug 23 00:28:52 2021
From: iwamatsu at nigauri.org (Nobuhiro Iwamatsu)
Date: Mon, 23 Aug 2021 16:28:52 +0900
Subject: [PATCH v3 2/3] rtc: Add support for the MSTAR MSC313 RTC
In-Reply-To: <20210819170301.10520-3-romain.perier@gmail.com>
References: <20210819170301.10520-1-romain.perier@gmail.com>
 <20210819170301.10520-3-romain.perier@gmail.com>
Message-ID: <CABMQnVJwFf4nX6ApdobBnwfzmWSsYHcabFqZd8rUQw=T7V=vcA@mail.gmail.com>

Hi!

2021?8?20?(?) 2:03 Romain Perier <romain.perier at gmail.com>:
>
> From: Daniel Palmer <daniel at 0x0f.com>
>
> This adds support for the RTC block on the Mstar MSC313e SoCs and newer.
>
> Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
> Co-developed-by: Romain Perier <romain.perier at gmail.com>
> Signed-off-by: Romain Perier <romain.perier at gmail.com>
> ---
>  MAINTAINERS              |   1 +
>  drivers/rtc/Kconfig      |  10 ++
>  drivers/rtc/Makefile     |   1 +
>  drivers/rtc/rtc-msc313.c | 258 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 270 insertions(+)
>  create mode 100644 drivers/rtc/rtc-msc313.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fd25e4ecf0b9..ebacdd5e8878 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2220,6 +2220,7 @@ F:        arch/arm/boot/dts/mstar-*
>  F:     arch/arm/mach-mstar/
>  F:     drivers/clk/mstar/
>  F:     drivers/gpio/gpio-msc313.c
> +F:     drivers/rtc/rtc-msc313.c
>  F:     drivers/watchdog/msc313e_wdt.c
>  F:     include/dt-bindings/clock/mstar-*
>  F:     include/dt-bindings/gpio/msc313-gpio.h
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 12153d5801ce..9ce4baab5fcf 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1925,4 +1925,14 @@ config RTC_DRV_WILCO_EC
>           This can also be built as a module. If so, the module will
>           be named "rtc_wilco_ec".
>
> +config RTC_DRV_MSC313
> +       tristate "MStar MSC313 RTC"
> +        depends on ARCH_MSTARV7 || COMPILE_TEST
> +       help
> +         If you say yes here you get support for the Mstar MSC313e On-Chip
> +         Real Time Clock.
> +
> +         This driver can also be built as a module, if so, the module
> +         will be called "rtc-msc313".
> +
>  endif # RTC_CLASS
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 2dd0dd956b0e..5efda8a60cee 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_RTC_DRV_MCP795)        += rtc-mcp795.o
>  obj-$(CONFIG_RTC_DRV_MESON)    += rtc-meson.o
>  obj-$(CONFIG_RTC_DRV_MOXART)   += rtc-moxart.o
>  obj-$(CONFIG_RTC_DRV_MPC5121)  += rtc-mpc5121.o
> +obj-$(CONFIG_RTC_DRV_MSC313)   += rtc-msc313.o
>  obj-$(CONFIG_RTC_DRV_MSM6242)  += rtc-msm6242.o
>  obj-$(CONFIG_RTC_DRV_MT2712)   += rtc-mt2712.o
>  obj-$(CONFIG_RTC_DRV_MT6397)   += rtc-mt6397.o
> diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c
> new file mode 100644
> index 000000000000..8cf5d5fb298f
> --- /dev/null
> +++ b/drivers/rtc/rtc-msc313.c
> @@ -0,0 +1,258 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.
> + * Based on "Real Time Clock driver for msb252x." that was contained
> + * in various MStar kernels.
> + *
> + * (C) 2019 Daniel Palmer
> + * (C) 2021 Romain Perier
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/platform_device.h>
> +#include <linux/rtc.h>
> +
> +/* Registers */
> +#define REG_RTC_CTRL           0x00
> +#define REG_RTC_FREQ_CW_L      0x04
> +#define REG_RTC_FREQ_CW_H      0x08
> +#define REG_RTC_LOAD_VAL_L     0x0C
> +#define REG_RTC_LOAD_VAL_H     0x10
> +#define REG_RTC_MATCH_VAL_L    0x14
> +#define REG_RTC_MATCH_VAL_H    0x18
> +#define REG_RTC_STATUS_INT     0x1C
> +#define REG_RTC_CNT_VAL_L      0x20
> +#define REG_RTC_CNT_VAL_H      0x24
> +
> +/* Control bits for REG_RTC_CTRL */
> +#define SOFT_RSTZ_BIT          BIT(0)
> +#define CNT_EN_BIT             BIT(1)
> +#define WRAP_EN_BIT            BIT(2)
> +#define LOAD_EN_BIT            BIT(3)
> +#define READ_EN_BIT            BIT(4)
> +#define INT_MASK_BIT           BIT(5)
> +#define INT_FORCE_BIT          BIT(6)
> +#define INT_CLEAR_BIT          BIT(7)
> +
> +/* Control bits for REG_RTC_STATUS_INT */
> +#define RAW_INT_BIT            BIT(0)
> +#define ALM_INT_BIT            BIT(1)
> +
> +struct msc313_rtc {
> +       struct rtc_device *rtc_dev;
> +       void __iomem *rtc_base;
> +       struct clk *clk;

The clk variable is only used in msc313_rtc_probe(). Therefore, it is
not necessary to have it in this structure.

> +};
> +
> +static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       unsigned long seconds;
> +
> +       seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)
> +                       | (readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);
> +
> +       rtc_time64_to_tm(seconds, &alarm->time);
> +
> +       if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))
> +               alarm->enabled = 1;
> +
> +       return 0;
> +}
> +
> +static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       u16 reg;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       if (enabled)
> +               reg &= ~INT_MASK_BIT;
> +       else
> +               reg |= INT_MASK_BIT;
> +       writew(reg, priv->rtc_base + REG_RTC_CTRL);
> +       return 0;
> +}
> +
> +static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       unsigned long seconds;
> +
> +       seconds = rtc_tm_to_time64(&alarm->time);
> +       writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);
> +       writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);
> +
> +       msc313_rtc_alarm_irq_enable(dev, alarm->enabled);
> +
> +       return 0;
> +}
> +
> +static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)
> +{
> +       return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;
> +}
> +
> +static void msc313_rtc_set_enabled(struct msc313_rtc *priv)
> +{
> +       u16 reg;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       reg |= CNT_EN_BIT;
> +       writew(reg, priv->rtc_base + REG_RTC_CTRL);
> +}
> +
> +static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       u32 seconds;
> +       u16 reg;
> +
> +       if (!msc313_rtc_get_enabled(priv))
> +               return -EINVAL;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
> +
> +       /* Wait for HW latch done */
> +       while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)
> +               udelay(1);
> +
> +       seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)
> +                       | (readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);
> +
> +       rtc_time64_to_tm(seconds, tm);
> +
> +       return 0;
> +}
> +
> +static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       unsigned long seconds;
> +       u16 reg;
> +
> +       seconds = rtc_tm_to_time64(tm);
> +       writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);
> +       writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);
> +
> +       /* Enable load for loading value into internal RTC counter */
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
> +
> +       /* Wait for HW latch done */
> +       while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
> +               udelay(1);
> +       msc313_rtc_set_enabled(priv);
> +       return 0;
> +}
> +
> +static const struct rtc_class_ops msc313_rtc_ops = {
> +       .read_time = msc313_rtc_read_time,
> +       .set_time = msc313_rtc_set_time,
> +       .read_alarm = msc313_rtc_read_alarm,
> +       .set_alarm = msc313_rtc_set_alarm,
> +       .alarm_irq_enable = msc313_rtc_alarm_irq_enable,
> +};
> +
> +static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev_id);
> +       u16 reg;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);
> +       if (!(reg & ALM_INT_BIT))
> +               return IRQ_NONE;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       reg |= INT_CLEAR_BIT;
> +       reg &= ~INT_FORCE_BIT;
> +       writew(reg, priv->rtc_base + REG_RTC_CTRL);
> +
> +       rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int msc313_rtc_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct msc313_rtc *priv;
> +       int ret;
> +       int irq;
> +       unsigned long rate;

Please use reverse christmas tree ordering for local variable.

> +
> +       priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(priv->rtc_base))
> +               return PTR_ERR(priv->rtc_base);
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (irq < 0)
> +               return -EINVAL;
> +
> +       priv->rtc_dev = devm_rtc_allocate_device(dev);
> +       if (IS_ERR(priv->rtc_dev))
> +               return PTR_ERR(priv->rtc_dev);
> +
> +       priv->rtc_dev->ops = &msc313_rtc_ops;
> +       priv->rtc_dev->range_max = U32_MAX;
> +
> +       ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
> +                              dev_name(&pdev->dev), &pdev->dev);
> +       if (ret) {
> +               dev_err(dev, "Could not request IRQ\n");
> +               return ret;
> +       }
> +
> +       priv->clk = devm_clk_get(dev, NULL);
> +       if (IS_ERR(priv->clk)) {
> +               dev_err(dev, "No input reference clock\n");
> +               return PTR_ERR(priv->clk);
> +       }
> +
> +       ret = clk_prepare_enable(priv->clk);
> +       if (ret) {
> +               dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
> +               return ret;
> +       }
> +
> +       ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, priv->clk);
> +       if (ret)
> +               return ret;
> +
> +       rate = clk_get_rate(priv->clk);
> +       writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
> +       writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
> +
> +       platform_set_drvdata(pdev, priv);
> +
> +       return devm_rtc_register_device(priv->rtc_dev);
> +}
> +
> +static const struct of_device_id msc313_rtc_of_match_table[] = {
> +       { .compatible = "mstar,msc313-rtc" },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, ms_rtc_of_match_table);

msc313_rtc_of_match_table ?

> +
> +static struct platform_driver msc313_rtc_driver = {
> +       .probe = msc313_rtc_probe,
> +       .driver = {
> +               .name = "msc313-rtc",
> +               .of_match_table = msc313_rtc_of_match_table,
> +       },
> +};
> +
> +module_platform_driver(msc313_rtc_driver);
> +
> +MODULE_AUTHOR("Daniel Palmer <daniel at thingy.jp>");
> +MODULE_AUTHOR("Romain Perier <romain.perier at gmail.com>");
> +MODULE_DESCRIPTION("MStar RTC Driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.30.2
>

Best regards,
  Nobuhiro

-- 
Nobuhiro Iwamatsu
   iwamatsu at {nigauri.org / debian.org / kernel.org}
   GPG ID: 40AD1FA6


From geert at linux-m68k.org  Mon Aug 23 00:50:16 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 23 Aug 2021 09:50:16 +0200
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CAK9rFnx--z_pr_yR6CqGsH04ddwUtx4rxc7MxNNmy7ZSF86+Mg@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CAHp75VcG9KajNpDbewDq7QzotB6t7MfwiGk15FaobX+cmMVSzg@mail.gmail.com>
 <CAK9rFnwrA=W2Vk5yFwG4N_WS=eBXXnhtexA+tqgAYb6xOAO4oQ@mail.gmail.com>
 <CAHp75VdfrJ3JV_gL3xCLHOiw6Tj-5Ep7z5JKWUFKFbUt8gobcw@mail.gmail.com>
 <CAK9rFnx--z_pr_yR6CqGsH04ddwUtx4rxc7MxNNmy7ZSF86+Mg@mail.gmail.com>
Message-ID: <CAMuHMdUz4vUQzXBHA9AiT3w6L20yBpgd0emVZJb=v_qw70qiJQ@mail.gmail.com>

Hi Brad,

On Mon, Aug 23, 2021 at 3:14 AM Brad Larson <brad at pensando.io> wrote:
> On Mon, Mar 29, 2021 at 3:40 AM Andy Shevchenko
> <andy.shevchenko at gmail.com> wrote:
> >
> > On Mon, Mar 29, 2021 at 4:19 AM Brad Larson <brad at pensando.io> wrote:
> > > On Sun, Mar 7, 2021 at 11:21 AM Andy Shevchenko
> > > <andy.shevchenko at gmail.com> wrote:
> > > > On Thu, Mar 4, 2021 at 4:40 PM Brad Larson <brad at pensando.io> wrote:
> >
> > ...
> >
> > > > > +config GPIO_ELBA_SPICS
> > > > > +       bool "Pensando Elba SPI chip-select"
> > > >
> > > > Can't it be a module? Why?
> > >
> > > All Elba SoC based platforms require this driver to be built-in to boot and
> > > removing the module would result in a variety of exceptions/errors.
> >
> > Needs to be at least in the commit message.
> >
> > > > > +       depends on ARCH_PENSANDO_ELBA_SOC
> > > > > +       help
> > > > > +         Say yes here to support the Pensndo Elba SoC SPI chip-select driver

Pensando

> > > >
> > > > Please give more explanation what it is and why users might need it,
> > > > and also tell users how the module will be named (if there is no
> > > > strong argument why it can't be a  module).
> > > >
> > > Fixed the typo.
> >
> > Yeah, according to the above, you better elaborate what this module is
> > and why people would need it.
> > Also can be a good hint to add
> > default ARCH_MY_COOL_PLATFORM
>
> Regarding the above module question and Kconfig definition, since I
> first looked at this and reviewed the comments I realized I should be
> using builtin.  The file gpio/Kconfig is currently this
>
> config GPIO_ELBA_SPICS
>         def_bool y
>         depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST

That means the driver will default to yes by merely enabling
COMPILE_TEST, which is a no-go.

    config GPIO_ELBA_SPICS
            bool "one-line summary"
            depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST
            default y if ARCH_PENSANDO_ELBA_SOC

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From bgolaszewski at baylibre.com  Mon Aug 23 01:02:20 2021
From: bgolaszewski at baylibre.com (Bartosz Golaszewski)
Date: Mon, 23 Aug 2021 10:02:20 +0200
Subject: [PATCH V3 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <20210818081018.2620544-4-piyush.mehta@xilinx.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-4-piyush.mehta@xilinx.com>
Message-ID: <CAMpxmJUvPg3LvT1EJa-ZecXMWpR82EQMr8vhTjBpO3_6iiGecQ@mail.gmail.com>

On Wed, Aug 18, 2021 at 10:11 AM Piyush Mehta <piyush.mehta at xilinx.com> wrote:
>
> This patch adds driver support for the zynqmp modepin GPIO controller.
> GPIO modepin driver set and get the value and status of the PS_MODE pin,
> based on device-tree pin configuration. These four mode pins are
> configurable as input/output. The mode pin has a control register, which
> have lower four-bits [0:3] are configurable as input/output, next four-bits
> can be used for reading the data  as input[4:7], and next setting the
> output pin state output[8:11].
>
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> Acked-by: Michal Simek <michal.simek at xilinx.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> ---

Which tree should this go through?

Bart


From michal.simek at xilinx.com  Mon Aug 23 01:14:11 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 23 Aug 2021 10:14:11 +0200
Subject: [PATCH V3 3/3] gpio: modepin: Add driver support for modepin GPIO
 controller
In-Reply-To: <CAMpxmJUvPg3LvT1EJa-ZecXMWpR82EQMr8vhTjBpO3_6iiGecQ@mail.gmail.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-4-piyush.mehta@xilinx.com>
 <CAMpxmJUvPg3LvT1EJa-ZecXMWpR82EQMr8vhTjBpO3_6iiGecQ@mail.gmail.com>
Message-ID: <2286343a-e061-d5bb-b266-6f657cba63e2@xilinx.com>

Hi Bart,

On 8/23/21 10:02 AM, Bartosz Golaszewski wrote:
> On Wed, Aug 18, 2021 at 10:11 AM Piyush Mehta <piyush.mehta at xilinx.com> wrote:
>>
>> This patch adds driver support for the zynqmp modepin GPIO controller.
>> GPIO modepin driver set and get the value and status of the PS_MODE pin,
>> based on device-tree pin configuration. These four mode pins are
>> configurable as input/output. The mode pin has a control register, which
>> have lower four-bits [0:3] are configurable as input/output, next four-bits
>> can be used for reading the data  as input[4:7], and next setting the
>> output pin state output[8:11].
>>
>> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
>> Acked-by: Michal Simek <michal.simek at xilinx.com>
>> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
>> ---
> 
> Which tree should this go through?

I would prefer to go this via gpio tree.

Thanks,
Michal


From benjamin.gaignard at collabora.com  Mon Aug 23 01:27:58 2021
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Mon, 23 Aug 2021 10:27:58 +0200
Subject: [PATCH v13 2/9] media: hevc: Add decode params control
In-Reply-To: <8aa297e9c71ea74804824214e9d3c8a8d2b015e2.camel@ndufresne.ca>
References: <20210603115004.915294-1-benjamin.gaignard@collabora.com>
 <20210603115004.915294-3-benjamin.gaignard@collabora.com>
 <h8e2hgh73r8lqgr8lgmuobubj2jcdg6mv5@4ax.com>
 <8aa297e9c71ea74804824214e9d3c8a8d2b015e2.camel@ndufresne.ca>
Message-ID: <41f10a78-482d-1c2b-6393-679073ece583@collabora.com>


Le 17/08/2021 ? 16:22, Nicolas Dufresne a ?crit?:
> Le lundi 09 ao?t 2021 ? 15:29 +0100, John Cox a ?crit?:
>> Hi
>>
>>> Add decode params control and the associated structure to group
>>> all the information that are needed to decode a reference frame as
>>> is described in ITU-T Rec. H.265 section "8.3.2 Decoding process
>>> for reference picture set".
>> I'm sorry I'm commenting late but I've only just got round to
>> implementing code based on this.
>>
>>> Adapt Cedrus driver to these changes.
>>>
>>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
>>> Reviewed-by: Ezequiel Garcia <ezequiel at collabora.com>
>>> ---
>>> version 11:
>>> - Split what was done in v4l2-ctrls.c in v4l2-ctrls-core.c and v4l2-ctrls-defs.c
>>>
>>> .../media/v4l/ext-ctrls-codec.rst             | 94 +++++++++++++++----
>>> .../media/v4l/vidioc-queryctrl.rst            |  6 ++
>>> drivers/media/v4l2-core/v4l2-ctrls-core.c     | 21 +++--
>>> drivers/media/v4l2-core/v4l2-ctrls-defs.c     |  4 +
>>> drivers/staging/media/sunxi/cedrus/cedrus.c   |  6 ++
>>> drivers/staging/media/sunxi/cedrus/cedrus.h   |  1 +
>>> .../staging/media/sunxi/cedrus/cedrus_dec.c   |  2 +
>>> .../staging/media/sunxi/cedrus/cedrus_h265.c  | 12 ++-
>>> include/media/hevc-ctrls.h                    | 29 ++++--
>>> 9 files changed, 136 insertions(+), 39 deletions(-)
>>>
>>> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>>> index 9cfb471fc6be..9120c5bcaf90 100644
>>> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>>> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>>> @@ -2997,9 +2997,6 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>>>      * - __u8
>>>        - ``pic_struct``
>>>        -
>>> -    * - __u8
>>> -      - ``num_active_dpb_entries``
>>> -      - The number of entries in ``dpb``.
>>>      * - __u8
>>>        - ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>>>        - The list of L0 reference elements as indices in the DPB.
>>> @@ -3007,22 +3004,8 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>>>        - ``ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>>>        - The list of L1 reference elements as indices in the DPB.
>>>      * - __u8
>>> -      - ``num_rps_poc_st_curr_before``
>>> -      - The number of reference pictures in the short-term set that come before
>>> -        the current frame.
>>> -    * - __u8
>>> -      - ``num_rps_poc_st_curr_after``
>>> -      - The number of reference pictures in the short-term set that come after
>>> -        the current frame.
>>> -    * - __u8
>>> -      - ``num_rps_poc_lt_curr``
>>> -      - The number of reference pictures in the long-term set.
>>> -    * - __u8
>>> -      - ``padding[7]``
>>> +      - ``padding``
>>>        - Applications and drivers must set this to zero.
>>> -    * - struct :c:type:`v4l2_hevc_dpb_entry`
>>> -      - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>>> -      - The decoded picture buffer, for meta-data about reference frames.
>>>      * - struct :c:type:`v4l2_hevc_pred_weight_table`
>>>        - ``pred_weight_table``
>>>        - The prediction weight coefficients for inter-picture prediction.
>>> @@ -3278,3 +3261,78 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>>>      encoding the next frame queued after setting this control.
>>>      This provides a bitmask which consists of bits [0, LTR_COUNT-1].
>>>      This is applicable to the H264 and HEVC encoders.
>>> +
>>> +``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (struct)``
>>> +    Specifies various decode parameters, especially the references picture order
>>> +    count (POC) for all the lists (short, long, before, current, after) and the
>>> +    number of entries for each of them.
>>> +    These parameters are defined according to :ref:`hevc`.
>>> +    They are described in section 8.3 "Slice decoding process" of the
>>> +    specification.
>>> +
>>> +.. c:type:: v4l2_ctrl_hevc_decode_params
>>> +
>>> +.. cssclass:: longtable
>>> +
>>> +.. flat-table:: struct v4l2_ctrl_hevc_decode_params
>>> +    :header-rows:  0
>>> +    :stub-columns: 0
>>> +    :widths:       1 1 2
>>> +
>>> +    * - __s32
>>> +      - ``pic_order_cnt_val``
>>> +      - PicOrderCntVal as described in section 8.3.1 "Decoding process
>>> +        for picture order count" of the specification.
>>> +    * - __u8
>>> +      - ``num_active_dpb_entries``
>>> +      - The number of entries in ``dpb``.
>>> +    * - struct :c:type:`v4l2_hevc_dpb_entry`
>>> +      - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>>> +      - The decoded picture buffer, for meta-data about reference frames.
>>> +    * - __u8
>>> +      - ``num_poc_st_curr_before``
>>> +      - The number of reference pictures in the short-term set that come before
>>> +        the current frame.
>>> +    * - __u8
>>> +      - ``num_poc_st_curr_after``
>>> +      - The number of reference pictures in the short-term set that come after
>>> +        the current frame.
>>> +    * - __u8
>>> +      - ``num_poc_lt_curr``
>>> +      - The number of reference pictures in the long-term set.
>>> +    * - __u8
>>> +      - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>>> +      - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
>>> +        picture set.
>>> +    * - __u8
>>> +      - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>>> +      - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
>>> +        picture set.
>>> +    * - __u8
>>> +      - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>>> +      - PocLtCurr as described in section 8.3.2 "Decoding process for reference
>>> +        picture set.
>> Two things here
>>
>> 1) By my understanding poc_st_curr_before/after & poc_lt_curr attempt to
>> hold a POC (as per 8.3.2). That is a 32bit signed value not U8.  You can
>> get away with U16 if you mask & sign extend your comparisions but U8 I'm
>> pretty sure is too small.

I will send a patch to change the type of these lists.

Benjamin

>>
>> 2) I think you can calculate these list from the info in the DPB
>> structure. Certainly v4l2_hevc_dpb_entry.rps contains which list every
>> entry is in.
> Putting my userspace guy hat, we calculate these lists separately in userspace,
> because we need them, we do some extra effort to mark them into the DPB entry
> flags. I believe there is a redundancy issue in the uAPI too with this version.
> But it would be nice if we didn't have to translate twice.
>
>> Regards
>>
>> John Cox
>>
>>
>>> +    * - __u64
>>> +      - ``flags``
>>> +      - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
>>> +
>>> +.. _hevc_decode_params_flags:
>>> +
>>> +``Decode Parameters Flags``
>>> +
>>> +.. cssclass:: longtable
>>> +
>>> +.. flat-table::
>>> +    :header-rows:  0
>>> +    :stub-columns: 0
>>> +    :widths:       1 1 2
>>> +
>>> +    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC``
>>> +      - 0x00000001
>>> +      -
>>> +    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC``
>>> +      - 0x00000002
>>> +      -
>>> +    * - ``V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR``
>>> +      - 0x00000004
>>> +      -
>>> diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
>>> index 07e54029e1e9..f9ecf6276129 100644
>>> --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
>>> +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
>>> @@ -501,6 +501,12 @@ See also the examples in :ref:`control`.
>>>        - n/a
>>>        - A struct :c:type:`v4l2_ctrl_vp8_frame`, containing VP8
>>> 	frame parameters for stateless video decoders.
>>> +    * - ``V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS``
>>> +      - n/a
>>> +      - n/a
>>> +      - n/a
>>> +      - A struct :c:type:`v4l2_ctrl_hevc_decode_params`, containing HEVC
>>> +	decoding parameters for stateless video decoders.
>>>
>>> .. raw:: latex
>>>
>>> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
>>> index 081439224357..c4b5082849b6 100644
>>> --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
>>> +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
>>> @@ -337,6 +337,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>>> 	struct v4l2_ctrl_hevc_pps *p_hevc_pps;
>>> 	struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
>>> 	struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
>>> +	struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params;
>>> 	struct v4l2_area *area;
>>> 	void *p = ptr.p + idx * ctrl->elem_size;
>>> 	unsigned int i;
>>> @@ -616,23 +617,26 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>>> 		zero_padding(*p_hevc_pps);
>>> 		break;
>>>
>>> -	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
>>> -		p_hevc_slice_params = p;
>>> +	case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
>>> +		p_hevc_decode_params = p;
>>>
>>> -		if (p_hevc_slice_params->num_active_dpb_entries >
>>> +		if (p_hevc_decode_params->num_active_dpb_entries >
>>> 		    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
>>> 			return -EINVAL;
>>>
>>> -		zero_padding(p_hevc_slice_params->pred_weight_table);
>>> -
>>> -		for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries;
>>> +		for (i = 0; i < p_hevc_decode_params->num_active_dpb_entries;
>>> 		     i++) {
>>> 			struct v4l2_hevc_dpb_entry *dpb_entry =
>>> -				&p_hevc_slice_params->dpb[i];
>>> +				&p_hevc_decode_params->dpb[i];
>>>
>>> 			zero_padding(*dpb_entry);
>>> 		}
>>> +		break;
>>>
>>> +	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
>>> +		p_hevc_slice_params = p;
>>> +
>>> +		zero_padding(p_hevc_slice_params->pred_weight_table);
>>> 		zero_padding(*p_hevc_slice_params);
>>> 		break;
>>>
>>> @@ -1236,6 +1240,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
>>> 	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
>>> 		elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
>>> 		break;
>>> +	case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
>>> +		elem_size = sizeof(struct v4l2_ctrl_hevc_decode_params);
>>> +		break;
>>> 	case V4L2_CTRL_TYPE_HDR10_CLL_INFO:
>>> 		elem_size = sizeof(struct v4l2_ctrl_hdr10_cll_info);
>>> 		break;
>>> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>>> index 7963c7b43450..b6344bbf1e00 100644
>>> --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>>> +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>>> @@ -996,6 +996,7 @@ const char *v4l2_ctrl_get_name(u32 id)
>>> 	case V4L2_CID_MPEG_VIDEO_HEVC_SPS:			return "HEVC Sequence Parameter Set";
>>> 	case V4L2_CID_MPEG_VIDEO_HEVC_PPS:			return "HEVC Picture Parameter Set";
>>> 	case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:		return "HEVC Slice Parameters";
>>> +	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:		return "HEVC Decode Parameters";
>>> 	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:		return "HEVC Decode Mode";
>>> 	case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:		return "HEVC Start Code";
>>>
>>> @@ -1487,6 +1488,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
>>> 	case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
>>> 		*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
>>> 		break;
>>> +	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS:
>>> +		*type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS;
>>> +		break;
>>> 	case V4L2_CID_UNIT_CELL_SIZE:
>>> 		*type = V4L2_CTRL_TYPE_AREA;
>>> 		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
>>> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
>>> index fa348c09f844..c0d005dafc6c 100644
>>> --- a/drivers/staging/media/sunxi/cedrus/cedrus.c
>>> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
>>> @@ -157,6 +157,12 @@ static const struct cedrus_control cedrus_controls[] = {
>>> 		},
>>> 		.codec		= CEDRUS_CODEC_VP8,
>>> 	},
>>> +	{
>>> +		.cfg = {
>>> +			.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS,
>>> +		},
>>> +		.codec		= CEDRUS_CODEC_H265,
>>> +	},
>>> };
>>>
>>> #define CEDRUS_CONTROLS_COUNT	ARRAY_SIZE(cedrus_controls)
>>> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
>>> index bbcdcd0787cf..88afba17b78b 100644
>>> --- a/drivers/staging/media/sunxi/cedrus/cedrus.h
>>> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
>>> @@ -77,6 +77,7 @@ struct cedrus_h265_run {
>>> 	const struct v4l2_ctrl_hevc_sps			*sps;
>>> 	const struct v4l2_ctrl_hevc_pps			*pps;
>>> 	const struct v4l2_ctrl_hevc_slice_params	*slice_params;
>>> +	const struct v4l2_ctrl_hevc_decode_params	*decode_params;
>>> };
>>>
>>> struct cedrus_vp8_run {
>>> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
>>> index 97e410d92506..40e8c4123f76 100644
>>> --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
>>> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
>>> @@ -70,6 +70,8 @@ void cedrus_device_run(void *priv)
>>> 			V4L2_CID_MPEG_VIDEO_HEVC_PPS);
>>> 		run.h265.slice_params = cedrus_find_control_data(ctx,
>>> 			V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
>>> +		run.h265.decode_params = cedrus_find_control_data(ctx,
>>> +			V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS);
>>> 		break;
>>>
>>> 	case V4L2_PIX_FMT_VP8_FRAME:
>>> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>>> index 10744fab7cea..6821e3d05d34 100644
>>> --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>>> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>>> @@ -245,6 +245,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
>>> 	const struct v4l2_ctrl_hevc_sps *sps;
>>> 	const struct v4l2_ctrl_hevc_pps *pps;
>>> 	const struct v4l2_ctrl_hevc_slice_params *slice_params;
>>> +	const struct v4l2_ctrl_hevc_decode_params *decode_params;
>>> 	const struct v4l2_hevc_pred_weight_table *pred_weight_table;
>>> 	dma_addr_t src_buf_addr;
>>> 	dma_addr_t src_buf_end_addr;
>>> @@ -256,6 +257,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
>>> 	sps = run->h265.sps;
>>> 	pps = run->h265.pps;
>>> 	slice_params = run->h265.slice_params;
>>> +	decode_params = run->h265.decode_params;
>>> 	pred_weight_table = &slice_params->pred_weight_table;
>>>
>>> 	/* MV column buffer size and allocation. */
>>> @@ -487,7 +489,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
>>>
>>> 	reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) |
>>> 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) |
>>> -	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(slice_params->num_rps_poc_st_curr_after == 0) |
>>> +	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(decode_params->num_poc_st_curr_after == 0) |
>>> 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) |
>>> 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) |
>>> 	      VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta);
>>> @@ -527,8 +529,8 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
>>> 	cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg);
>>>
>>> 	/* Write decoded picture buffer in pic list. */
>>> -	cedrus_h265_frame_info_write_dpb(ctx, slice_params->dpb,
>>> -					 slice_params->num_active_dpb_entries);
>>> +	cedrus_h265_frame_info_write_dpb(ctx, decode_params->dpb,
>>> +					 decode_params->num_active_dpb_entries);
>>>
>>> 	/* Output frame. */
>>>
>>> @@ -545,7 +547,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
>>>
>>> 	/* Reference picture list 0 (for P/B frames). */
>>> 	if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) {
>>> -		cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
>>> +		cedrus_h265_ref_pic_list_write(dev, decode_params->dpb,
>>> 					       slice_params->ref_idx_l0,
>>> 					       slice_params->num_ref_idx_l0_active_minus1 + 1,
>>> 					       VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
>>> @@ -564,7 +566,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
>>>
>>> 	/* Reference picture list 1 (for B frames). */
>>> 	if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) {
>>> -		cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
>>> +		cedrus_h265_ref_pic_list_write(dev, decode_params->dpb,
>>> 					       slice_params->ref_idx_l1,
>>> 					       slice_params->num_ref_idx_l1_active_minus1 + 1,
>>> 					       VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
>>> diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
>>> index 245052c15864..e53666a1127f 100644
>>> --- a/include/media/hevc-ctrls.h
>>> +++ b/include/media/hevc-ctrls.h
>>> @@ -19,6 +19,7 @@
>>> #define V4L2_CID_MPEG_VIDEO_HEVC_SPS		(V4L2_CID_CODEC_BASE + 1008)
>>> #define V4L2_CID_MPEG_VIDEO_HEVC_PPS		(V4L2_CID_CODEC_BASE + 1009)
>>> #define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS	(V4L2_CID_CODEC_BASE + 1010)
>>> +#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS	(V4L2_CID_CODEC_BASE + 1012)
>>> #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE	(V4L2_CID_CODEC_BASE + 1015)
>>> #define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE	(V4L2_CID_CODEC_BASE + 1016)
>>>
>>> @@ -26,6 +27,7 @@
>>> #define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
>>> #define V4L2_CTRL_TYPE_HEVC_PPS 0x0121
>>> #define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122
>>> +#define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124
>>>
>>> enum v4l2_mpeg_video_hevc_decode_mode {
>>> 	V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
>>> @@ -195,18 +197,10 @@ struct v4l2_ctrl_hevc_slice_params {
>>> 	__u8	pic_struct;
>>>
>>> 	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
>>> -	__u8	num_active_dpb_entries;
>>> 	__u8	ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>>> 	__u8	ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>>>
>>> -	__u8	num_rps_poc_st_curr_before;
>>> -	__u8	num_rps_poc_st_curr_after;
>>> -	__u8	num_rps_poc_lt_curr;
>>> -
>>> -	__u8	padding;
>>> -
>>> -	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
>>> -	struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>>> +	__u8	padding[5];
>>>
>>> 	/* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
>>> 	struct v4l2_hevc_pred_weight_table pred_weight_table;
>>> @@ -214,4 +208,21 @@ struct v4l2_ctrl_hevc_slice_params {
>>> 	__u64	flags;
>>> };
>>>
>>> +#define V4L2_HEVC_DECODE_PARAM_FLAG_IRAP_PIC		0x1
>>> +#define V4L2_HEVC_DECODE_PARAM_FLAG_IDR_PIC		0x2
>>> +#define V4L2_HEVC_DECODE_PARAM_FLAG_NO_OUTPUT_OF_PRIOR  0x4
>>> +
>>> +struct v4l2_ctrl_hevc_decode_params {
>>> +	__s32	pic_order_cnt_val;
>>> +	__u8	num_active_dpb_entries;
>>> +	struct	v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>>> +	__u8	num_poc_st_curr_before;
>>> +	__u8	num_poc_st_curr_after;
>>> +	__u8	num_poc_lt_curr;
>>> +	__u8	poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>>> +	__u8	poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>>> +	__u8	poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
>>> +	__u64	flags;
>>> +};
>>> +
>>> #endif
>


From linux at armlinux.org.uk  Mon Aug 23 02:05:09 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 23 Aug 2021 10:05:09 +0100
Subject: [PATCH 0/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <b5ccbf00-b686-d35b-c81a-0ec69f4677a0@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <YRw32YE4cnNnWSvl@robh.at.kernel.org>
 <b5ccbf00-b686-d35b-c81a-0ec69f4677a0@huawei.com>
Message-ID: <20210823090508.GO22278@shell.armlinux.org.uk>

On Mon, Aug 23, 2021 at 10:19:23AM +0800, Kefeng Wang wrote:
> 
> On 2021/8/18 6:27, Rob Herring wrote:
> > On Mon, Aug 16, 2021 at 03:46:16PM +0800, Kefeng Wang wrote:
> > > Patch 1 and 2 make some cleanup, and patch 3 use of_irq_get() instead of
> > > irq_of_parse_and_map() to get irq number, return -EPROBE_DEFER if the irq
> > > domain is not yet created, amba_device_add() will properly to handle the
> > > no IRQ domain issue via deferred probe.
> > > 
> > > Kefeng Wang (3):
> > >    amba: Drop unused functions about APB/AHB devices add
> > >    Revert "ARM: amba: make use of -1 IRQs warn"
> > >    amba: Properly handle device probe without IRQ domain
> > > 
> > >   drivers/amba/bus.c       | 100 ++++++++++-----------------------------
> > >   drivers/of/platform.c    |   6 +--
> > >   include/linux/amba/bus.h |  18 -------
> > >   3 files changed, 27 insertions(+), 97 deletions(-)
> > Reviewed-by: Rob Herring <robh at kernel.org>
> 
> Thanks Rob.
> 
> Hi Russell, should I send the patches to the ARM patch system?

Yes please - I'll try to squeeze it in for this cycle but it's getting
a tad late for that. Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From lorenzo.pieralisi at arm.com  Mon Aug 23 02:12:14 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 23 Aug 2021 10:12:14 +0100
Subject: [PATCH v6 4/8] arm64: PCI: Support root bridge preparation for
 Hyper-V
In-Reply-To: <20210820174947.GB23080@arm.com>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-5-boqun.feng@gmail.com>
 <YR6DIkdkblL8NUP2@boqun-archlinux> <20210820174947.GB23080@arm.com>
Message-ID: <20210823091214.GA1193@lpieralisi>

On Fri, Aug 20, 2021 at 06:49:47PM +0100, Catalin Marinas wrote:
> Hi Boqun,
> 
> Sorry, I just got back from holiday and I'm still in the deleting emails
> mode.
> 
> On Fri, Aug 20, 2021 at 12:13:22AM +0800, Boqun Feng wrote:
> > Appreciate it that you can have a look at this one and patch #4, note
> > that there exists an alternative solution at[1].
> > 
> > The difference is the way used to pass the corresponding ACPI device
> > pointers for PCI host bridges: currently pci_config_window->parent is
> > used, and this patch and patch #4 allow the field to be NULL, because
> > Hyper-V's PCI host bridges don't have ACPI devices, while [1] changes to
> > use pci_host_bridge->private. And I'm OK with either way, I don't have a
> > strong opinion here ;-)
> [...]
> > [1]: https://lore.kernel.org/lkml/20210811153619.88922-1-boqun.feng at gmail.com/
> 
> I'm ok with the arm64 bits in this series and the one you linked above.
> It's up to Lorenzo if he's happy with how pci-hyperv.c ends up looking,
> I'm not a PCIe expert. My preference would be for a combined series
> (this and [1] above).
> 
> Happy to ack the arm64 patches in a combined series (if you are going to
> post one), the changes would look even simpler.

I believe [1] above is an experiment - therefore it is best to stick to
this series as it is for the time being, pending refactoring that
requires more time, I would not rush it.

If you can ACK the arm64 patches (3,4) please I will pull the series
into the PCI tree asap.

Thanks,
Lorenzo


From wenst at chromium.org  Mon Aug 23 02:21:50 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 17:21:50 +0800
Subject: [v2 06/24] clk: mediatek: Add MT8195 apmixedsys clock support
In-Reply-To: <20210820111504.350-7-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-7-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5FVGQkR=OpyBA7rjE0sLLqVoTpgHJuG8YDaCnWFCdDM8A@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:20 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 apmixedsys clock controller which provides Plls
> generated from SoC 26m and ssusb clock gate control.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Kconfig                 |   8 +
>  drivers/clk/mediatek/Makefile                |   1 +
>  drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 145 +++++++++++++++++++
>  3 files changed, 154 insertions(+)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-apmixedsys.c
>
> diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
> index 576babd86f98..7ba1f4118e0d 100644
> --- a/drivers/clk/mediatek/Kconfig
> +++ b/drivers/clk/mediatek/Kconfig
> @@ -580,6 +580,14 @@ config COMMON_CLK_MT8192_VENCSYS
>         help
>           This driver supports MediaTek MT8192 vencsys clocks.
>
> +config COMMON_CLK_MT8195
> +        bool "Clock driver for MediaTek MT8195"
> +        depends on ARM64 || COMPILE_TEST
> +        select COMMON_CLK_MEDIATEK
> +        default ARM64
> +        help
> +          This driver supports MediaTek MT8195 basic clocks.

Since we will have all clocks under the same Kconfig option, please
drop the word "basic".

> +
>  config COMMON_CLK_MT8516
>         bool "Clock driver for MediaTek MT8516"
>         depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 15bc045f0b71..d4157cfca865 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -80,5 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
> +obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o
>  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
>  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> new file mode 100644
> index 000000000000..253eb30b22d4
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> @@ -0,0 +1,145 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Copyright (c) 2021 MediaTek Inc.
> +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +
> +#include <dt-bindings/clock/mt8195-clk.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +
> +static const struct mtk_gate_regs apmixed_cg_regs = {
> +       .set_ofs = 0x8,
> +       .clr_ofs = 0x8,
> +       .sta_ofs = 0x8,
> +};
> +
> +#define GATE_APMIXED(_id, _name, _parent, _shift)                      \
> +       GATE_MTK(_id, _name, _parent, &apmixed_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> +
> +static const struct mtk_gate apmixed_clks[] = {
> +       GATE_APMIXED(CLK_APMIXED_PLL_SSUSB26M, "pll_ssusb26m", "clk26m", 1),
> +};
> +
> +#define MT8195_PLL_FMAX                (3800UL * MHZ)
> +#define MT8195_PLL_FMIN                (1500UL * MHZ)
> +#define MT8195_INTEGER_BITS    8
> +
> +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags,              \
> +                       _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift,    \
> +                       _tuner_reg, _tuner_en_reg, _tuner_en_bit,       \
> +                       _pcw_reg, _pcw_shift, _pcw_chg_reg,             \
> +                       _en_reg, _pll_en_bit) {                         \

Nit: Even for macro definitions, you could align the lines to the opening
parenthesis. That would give you more room. And it would make it slightly
easier to read.

Otherwise,

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

[...]


From chun-jie.chen at mediatek.com  Mon Aug 23 02:23:48 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 23 Aug 2021 17:23:48 +0800
Subject: [v4 0/5] Mediatek MT8195 power domain support
Message-ID: <20210823092353.3502-1-chun-jie.chen@mediatek.com>

This patch series adds power domain support for MT8195
and is based on 5.14-rc1.

change since v3:
- remove redundant bus protection steps
- remove unused power domain

change since v2:
- move modification of wakeup capacity to single patch

reason for resend v2:
- miss patch version in series

changes since v1:
- fix signed-off name
- describe more detail in patch 3
- move modification of removing redundant macro to single patch

Chun-Jie Chen (5):
  dt-bindings: power: Add MT8195 power domains
  soc: mediatek: pm-domains: Add wakeup capacity support in power domain
  soc: mediatek: pm-domains: Remove unused macro
  soc: mediatek: pm-domains: Move power status offset to power domain
    data
  soc: mediatek: pm-domains: Add support for mt8195

 .../power/mediatek,power-controller.yaml      |   2 +
 drivers/soc/mediatek/mt8167-pm-domains.h      |  16 +-
 drivers/soc/mediatek/mt8173-pm-domains.h      |  22 +-
 drivers/soc/mediatek/mt8183-pm-domains.h      |  32 +-
 drivers/soc/mediatek/mt8192-pm-domains.h      |  44 +-
 drivers/soc/mediatek/mt8195-pm-domains.h      | 613 ++++++++++++++++++
 drivers/soc/mediatek/mtk-pm-domains.c         |  12 +-
 drivers/soc/mediatek/mtk-pm-domains.h         |   8 +-
 include/dt-bindings/power/mt8195-power.h      |  46 ++
 include/linux/soc/mediatek/infracfg.h         |  82 +++
 10 files changed, 862 insertions(+), 15 deletions(-)
 create mode 100644 drivers/soc/mediatek/mt8195-pm-domains.h
 create mode 100644 include/dt-bindings/power/mt8195-power.h

-- 
2.18.0

From chun-jie.chen at mediatek.com  Mon Aug 23 02:23:49 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 23 Aug 2021 17:23:49 +0800
Subject: [v4 1/5] dt-bindings: power: Add MT8195 power domains
In-Reply-To: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
References: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
Message-ID: <20210823092353.3502-2-chun-jie.chen@mediatek.com>

Add power domains dt-bindings for MT8195.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
---
remove unused power domain like audio_src, nna and hdmi_rx.
---
 .../power/mediatek,power-controller.yaml      |  2 +
 include/dt-bindings/power/mt8195-power.h      | 46 +++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 include/dt-bindings/power/mt8195-power.h

diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
index f234a756c193..d6ebd77d28a7 100644
--- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
+++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
@@ -27,6 +27,7 @@ properties:
       - mediatek,mt8173-power-controller
       - mediatek,mt8183-power-controller
       - mediatek,mt8192-power-controller
+      - mediatek,mt8195-power-controller
 
   '#power-domain-cells':
     const: 1
@@ -64,6 +65,7 @@ patternProperties:
               "include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain.
               "include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain.
               "include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain.
+              "include/dt-bindings/power/mt8195-power.h" - for MT8195 type power domain.
         maxItems: 1
 
       clocks:
diff --git a/include/dt-bindings/power/mt8195-power.h b/include/dt-bindings/power/mt8195-power.h
new file mode 100644
index 000000000000..b20ca4b3e3a8
--- /dev/null
+++ b/include/dt-bindings/power/mt8195-power.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT8195_POWER_H
+#define _DT_BINDINGS_POWER_MT8195_POWER_H
+
+#define MT8195_POWER_DOMAIN_PCIE_MAC_P0		0
+#define MT8195_POWER_DOMAIN_PCIE_MAC_P1		1
+#define MT8195_POWER_DOMAIN_PCIE_PHY		2
+#define MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY	3
+#define MT8195_POWER_DOMAIN_CSI_RX_TOP		4
+#define MT8195_POWER_DOMAIN_ETHER		5
+#define MT8195_POWER_DOMAIN_ADSP		6
+#define MT8195_POWER_DOMAIN_AUDIO		7
+#define MT8195_POWER_DOMAIN_MFG0		8
+#define MT8195_POWER_DOMAIN_MFG1		9
+#define MT8195_POWER_DOMAIN_MFG2		10
+#define MT8195_POWER_DOMAIN_MFG3		11
+#define MT8195_POWER_DOMAIN_MFG4		12
+#define MT8195_POWER_DOMAIN_MFG5		13
+#define MT8195_POWER_DOMAIN_MFG6		14
+#define MT8195_POWER_DOMAIN_VPPSYS0		15
+#define MT8195_POWER_DOMAIN_VDOSYS0		16
+#define MT8195_POWER_DOMAIN_VPPSYS1		17
+#define MT8195_POWER_DOMAIN_VDOSYS1		18
+#define MT8195_POWER_DOMAIN_DP_TX		19
+#define MT8195_POWER_DOMAIN_EPD_TX		20
+#define MT8195_POWER_DOMAIN_HDMI_TX		21
+#define MT8195_POWER_DOMAIN_WPESYS		22
+#define MT8195_POWER_DOMAIN_VDEC0		23
+#define MT8195_POWER_DOMAIN_VDEC1		24
+#define MT8195_POWER_DOMAIN_VDEC2		25
+#define MT8195_POWER_DOMAIN_VENC		26
+#define MT8195_POWER_DOMAIN_VENC_CORE1		27
+#define MT8195_POWER_DOMAIN_IMG			28
+#define MT8195_POWER_DOMAIN_DIP			29
+#define MT8195_POWER_DOMAIN_IPE			30
+#define MT8195_POWER_DOMAIN_CAM			31
+#define MT8195_POWER_DOMAIN_CAM_RAWA		32
+#define MT8195_POWER_DOMAIN_CAM_RAWB		33
+#define MT8195_POWER_DOMAIN_CAM_MRAW		34
+
+#endif /* _DT_BINDINGS_POWER_MT8195_POWER_H */
-- 
2.18.0

From chun-jie.chen at mediatek.com  Mon Aug 23 02:23:50 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 23 Aug 2021 17:23:50 +0800
Subject: [v4 2/5] soc: mediatek: pm-domains: Add wakeup capacity support in
 power domain
In-Reply-To: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
References: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
Message-ID: <20210823092353.3502-3-chun-jie.chen@mediatek.com>

Due to some power domain needs to keep on for wakeup in system suspend,
so add GENPD_FLAG_ACTIVE_WAKEUP support in Mediatek power domain driver.

Fixes: 59b644b01cf4 ("soc: mediatek: Add MediaTek SCPSYS power domains")
Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/soc/mediatek/mtk-pm-domains.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
index b762bc40f56b..afd2fd74802d 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.c
+++ b/drivers/soc/mediatek/mtk-pm-domains.c
@@ -443,6 +443,9 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
 	pd->genpd.power_off = scpsys_power_off;
 	pd->genpd.power_on = scpsys_power_on;
 
+	if (MTK_SCPD_CAPS(pd, MTK_SCPD_ACTIVE_WAKEUP))
+		pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
+
 	if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF))
 		pm_genpd_init(&pd->genpd, NULL, true);
 	else
-- 
2.18.0

From chun-jie.chen at mediatek.com  Mon Aug 23 02:23:51 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 23 Aug 2021 17:23:51 +0800
Subject: [v4 3/5] soc: mediatek: pm-domains: Remove unused macro
In-Reply-To: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
References: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
Message-ID: <20210823092353.3502-4-chun-jie.chen@mediatek.com>

Due to clk resource data will be allocated dynamically by
searching parent count of clk in power domain node, so remove
the unused marco MAX_SUBSYS_CLKS for static allocation.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
---
 drivers/soc/mediatek/mtk-pm-domains.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h
index 21a4e113bbec..1e033bde0629 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.h
+++ b/drivers/soc/mediatek/mtk-pm-domains.h
@@ -72,8 +72,6 @@ struct scpsys_bus_prot_data {
 	bool ignore_clr_ack;
 };
 
-#define MAX_SUBSYS_CLKS 10
-
 /**
  * struct scpsys_domain_data - scp domain data for power on/off flow
  * @name: The name of the power domain.
-- 
2.18.0

From chun-jie.chen at mediatek.com  Mon Aug 23 02:23:52 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 23 Aug 2021 17:23:52 +0800
Subject: [v4 4/5] soc: mediatek: pm-domains: Move power status offset to power
 domain data
In-Reply-To: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
References: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
Message-ID: <20210823092353.3502-5-chun-jie.chen@mediatek.com>

MT8195 has more than 32 power domains so it needs
two set of pwr_sta and pwr_sta2nd registers,
so move the register offset from soc data into power domain data.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
---
 drivers/soc/mediatek/mt8167-pm-domains.h | 16 +++++++--
 drivers/soc/mediatek/mt8173-pm-domains.h | 22 ++++++++++--
 drivers/soc/mediatek/mt8183-pm-domains.h | 32 +++++++++++++++--
 drivers/soc/mediatek/mt8192-pm-domains.h | 44 ++++++++++++++++++++++--
 drivers/soc/mediatek/mtk-pm-domains.c    |  4 +--
 drivers/soc/mediatek/mtk-pm-domains.h    |  4 +--
 6 files changed, 110 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/mediatek/mt8167-pm-domains.h b/drivers/soc/mediatek/mt8167-pm-domains.h
index 15559ddf26e4..4d6c32759606 100644
--- a/drivers/soc/mediatek/mt8167-pm-domains.h
+++ b/drivers/soc/mediatek/mt8167-pm-domains.h
@@ -18,6 +18,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "mm",
 		.sta_mask = PWR_STATUS_DISP,
 		.ctl_offs = SPM_DIS_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -30,6 +32,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "vdec",
 		.sta_mask = PWR_STATUS_VDEC,
 		.ctl_offs = SPM_VDE_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -38,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "isp",
 		.sta_mask = PWR_STATUS_ISP,
 		.ctl_offs = SPM_ISP_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -46,6 +52,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "mfg_async",
 		.sta_mask = MT8167_PWR_STATUS_MFG_ASYNC,
 		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = 0,
 		.sram_pdn_ack_bits = 0,
 		.bp_infracfg = {
@@ -57,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "mfg_2d",
 		.sta_mask = MT8167_PWR_STATUS_MFG_2D,
 		.ctl_offs = SPM_MFG_2D_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -64,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "mfg",
 		.sta_mask = PWR_STATUS_MFG,
 		.ctl_offs = SPM_MFG_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -71,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "conn",
 		.sta_mask = PWR_STATUS_CONN,
 		.ctl_offs = SPM_CONN_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = 0,
 		.caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -85,8 +99,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 static const struct scpsys_soc_data mt8167_scpsys_data = {
 	.domains_data = scpsys_domain_data_mt8167,
 	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167),
-	.pwr_sta_offs = SPM_PWR_STATUS,
-	.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 };
 
 #endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mt8173-pm-domains.h b/drivers/soc/mediatek/mt8173-pm-domains.h
index 654c717e5467..a4f58c2b44b1 100644
--- a/drivers/soc/mediatek/mt8173-pm-domains.h
+++ b/drivers/soc/mediatek/mt8173-pm-domains.h
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "vdec",
 		.sta_mask = PWR_STATUS_VDEC,
 		.ctl_offs = SPM_VDE_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "venc",
 		.sta_mask = PWR_STATUS_VENC,
 		.ctl_offs = SPM_VEN_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -29,6 +33,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "isp",
 		.sta_mask = PWR_STATUS_ISP,
 		.ctl_offs = SPM_ISP_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 	},
@@ -36,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "mm",
 		.sta_mask = PWR_STATUS_DISP,
 		.ctl_offs = SPM_DIS_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -47,6 +55,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "venc_lt",
 		.sta_mask = PWR_STATUS_VENC_LT,
 		.ctl_offs = SPM_VEN2_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -54,6 +64,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "audio",
 		.sta_mask = PWR_STATUS_AUDIO,
 		.ctl_offs = SPM_AUDIO_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -61,6 +73,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "usb",
 		.sta_mask = PWR_STATUS_USB,
 		.ctl_offs = SPM_USB_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 		.caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -69,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "mfg_async",
 		.sta_mask = PWR_STATUS_MFG_ASYNC,
 		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = 0,
 	},
@@ -76,6 +92,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "mfg_2d",
 		.sta_mask = PWR_STATUS_MFG_2D,
 		.ctl_offs = SPM_MFG_2D_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 	},
@@ -83,6 +101,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "mfg",
 		.sta_mask = PWR_STATUS_MFG,
 		.ctl_offs = SPM_MFG_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(13, 8),
 		.sram_pdn_ack_bits = GENMASK(21, 16),
 		.bp_infracfg = {
@@ -97,8 +117,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 static const struct scpsys_soc_data mt8173_scpsys_data = {
 	.domains_data = scpsys_domain_data_mt8173,
 	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173),
-	.pwr_sta_offs = SPM_PWR_STATUS,
-	.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 };
 
 #endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mt8183-pm-domains.h b/drivers/soc/mediatek/mt8183-pm-domains.h
index 98a9940d05fb..71b8757e552d 100644
--- a/drivers/soc/mediatek/mt8183-pm-domains.h
+++ b/drivers/soc/mediatek/mt8183-pm-domains.h
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "audio",
 		.sta_mask = PWR_STATUS_AUDIO,
 		.ctl_offs = 0x0314,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "conn",
 		.sta_mask = PWR_STATUS_CONN,
 		.ctl_offs = 0x032c,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = 0,
 		.sram_pdn_ack_bits = 0,
 		.bp_infracfg = {
@@ -33,6 +37,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg_async",
 		.sta_mask = PWR_STATUS_MFG_ASYNC,
 		.ctl_offs = 0x0334,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = 0,
 		.sram_pdn_ack_bits = 0,
 	},
@@ -40,6 +46,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg",
 		.sta_mask = PWR_STATUS_MFG,
 		.ctl_offs = 0x0338,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.caps = MTK_SCPD_DOMAIN_SUPPLY,
@@ -48,6 +56,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg_core0",
 		.sta_mask = BIT(7),
 		.ctl_offs = 0x034c,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -55,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg_core1",
 		.sta_mask = BIT(20),
 		.ctl_offs = 0x0310,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -62,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg_2d",
 		.sta_mask = PWR_STATUS_MFG_2D,
 		.ctl_offs = 0x0348,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -75,6 +89,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "disp",
 		.sta_mask = PWR_STATUS_DISP,
 		.ctl_offs = 0x030c,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -94,6 +110,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "cam",
 		.sta_mask = BIT(25),
 		.ctl_offs = 0x0344,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(9, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.bp_infracfg = {
@@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "isp",
 		.sta_mask = PWR_STATUS_ISP,
 		.ctl_offs = 0x0308,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(9, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.bp_infracfg = {
@@ -140,6 +160,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "vdec",
 		.sta_mask = BIT(31),
 		.ctl_offs = 0x0300,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_smi = {
@@ -153,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "venc",
 		.sta_mask = PWR_STATUS_VENC,
 		.ctl_offs = 0x0304,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 		.bp_smi = {
@@ -166,6 +190,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "vpu_top",
 		.sta_mask = BIT(26),
 		.ctl_offs = 0x0324,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -193,6 +219,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "vpu_core0",
 		.sta_mask = BIT(27),
 		.ctl_offs = 0x33c,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.bp_infracfg = {
@@ -211,6 +239,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "vpu_core1",
 		.sta_mask = BIT(28),
 		.ctl_offs = 0x0340,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.bp_infracfg = {
@@ -230,8 +260,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 static const struct scpsys_soc_data mt8183_scpsys_data = {
 	.domains_data = scpsys_domain_data_mt8183,
 	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183),
-	.pwr_sta_offs = 0x0180,
-	.pwr_sta2nd_offs = 0x0184
 };
 
 #endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mt8192-pm-domains.h b/drivers/soc/mediatek/mt8192-pm-domains.h
index 543dda70de01..558c4ee4784a 100644
--- a/drivers/soc/mediatek/mt8192-pm-domains.h
+++ b/drivers/soc/mediatek/mt8192-pm-domains.h
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "audio",
 		.sta_mask = BIT(21),
 		.ctl_offs = 0x0354,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -28,6 +30,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "conn",
 		.sta_mask = PWR_STATUS_CONN,
 		.ctl_offs = 0x0304,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = 0,
 		.sram_pdn_ack_bits = 0,
 		.bp_infracfg = {
@@ -50,6 +54,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg0",
 		.sta_mask = BIT(2),
 		.ctl_offs = 0x0308,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -57,6 +63,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg1",
 		.sta_mask = BIT(3),
 		.ctl_offs = 0x030c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -82,6 +90,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg2",
 		.sta_mask = BIT(4),
 		.ctl_offs = 0x0310,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -89,6 +99,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg3",
 		.sta_mask = BIT(5),
 		.ctl_offs = 0x0314,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -96,6 +108,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg4",
 		.sta_mask = BIT(6),
 		.ctl_offs = 0x0318,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -103,6 +117,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg5",
 		.sta_mask = BIT(7),
 		.ctl_offs = 0x031c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -110,6 +126,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg6",
 		.sta_mask = BIT(8),
 		.ctl_offs = 0x0320,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "disp",
 		.sta_mask = BIT(20),
 		.ctl_offs = 0x0350,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -146,6 +166,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "ipe",
 		.sta_mask = BIT(14),
 		.ctl_offs = 0x0338,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -163,6 +185,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "isp",
 		.sta_mask = BIT(12),
 		.ctl_offs = 0x0330,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -180,6 +204,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "isp2",
 		.sta_mask = BIT(13),
 		.ctl_offs = 0x0334,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -197,6 +223,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mdp",
 		.sta_mask = BIT(19),
 		.ctl_offs = 0x034c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -214,6 +242,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "venc",
 		.sta_mask = BIT(17),
 		.ctl_offs = 0x0344,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -231,6 +261,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "vdec",
 		.sta_mask = BIT(15),
 		.ctl_offs = 0x033c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -248,6 +280,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "vdec2",
 		.sta_mask = BIT(16),
 		.ctl_offs = 0x0340,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -255,6 +289,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "cam",
 		.sta_mask = BIT(23),
 		.ctl_offs = 0x035c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -284,6 +320,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "cam_rawa",
 		.sta_mask = BIT(24),
 		.ctl_offs = 0x0360,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -291,6 +329,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "cam_rawb",
 		.sta_mask = BIT(25),
 		.ctl_offs = 0x0364,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -298,6 +338,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "cam_rawc",
 		.sta_mask = BIT(26),
 		.ctl_offs = 0x0368,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -306,8 +348,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 static const struct scpsys_soc_data mt8192_scpsys_data = {
 	.domains_data = scpsys_domain_data_mt8192,
 	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192),
-	.pwr_sta_offs = 0x016c,
-	.pwr_sta2nd_offs = 0x0170,
 };
 
 #endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
index afd2fd74802d..ad06b6f90435 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.c
+++ b/drivers/soc/mediatek/mtk-pm-domains.c
@@ -60,10 +60,10 @@ static bool scpsys_domain_is_on(struct scpsys_domain *pd)
 	struct scpsys *scpsys = pd->scpsys;
 	u32 status, status2;
 
-	regmap_read(scpsys->base, scpsys->soc_data->pwr_sta_offs, &status);
+	regmap_read(scpsys->base, pd->data->pwr_sta_offs, &status);
 	status &= pd->data->sta_mask;
 
-	regmap_read(scpsys->base, scpsys->soc_data->pwr_sta2nd_offs, &status2);
+	regmap_read(scpsys->base, pd->data->pwr_sta2nd_offs, &status2);
 	status2 &= pd->data->sta_mask;
 
 	/* A domain is on when both status bits are set. */
diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h
index 1e033bde0629..4f076f24dd52 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.h
+++ b/drivers/soc/mediatek/mtk-pm-domains.h
@@ -92,13 +92,13 @@ struct scpsys_domain_data {
 	u8 caps;
 	const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];
 	const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];
+	int pwr_sta_offs;
+	int pwr_sta2nd_offs;
 };
 
 struct scpsys_soc_data {
 	const struct scpsys_domain_data *domains_data;
 	int num_domains;
-	int pwr_sta_offs;
-	int pwr_sta2nd_offs;
 };
 
 #endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
-- 
2.18.0

From chun-jie.chen at mediatek.com  Mon Aug 23 02:23:53 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 23 Aug 2021 17:23:53 +0800
Subject: [v4 5/5] soc: mediatek: pm-domains: Add support for mt8195
In-Reply-To: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
References: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
Message-ID: <20210823092353.3502-6-chun-jie.chen@mediatek.com>

Add domain control data including bus protection data size
change due to more protection steps in mt8195.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
remove duplicated protection steps and unused power domain
like audio_src, nna and hdmi_rx.
---
 drivers/soc/mediatek/mt8195-pm-domains.h | 613 +++++++++++++++++++++++
 drivers/soc/mediatek/mtk-pm-domains.c    |   5 +
 drivers/soc/mediatek/mtk-pm-domains.h    |   2 +-
 include/linux/soc/mediatek/infracfg.h    |  82 +++
 4 files changed, 701 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soc/mediatek/mt8195-pm-domains.h

diff --git a/drivers/soc/mediatek/mt8195-pm-domains.h b/drivers/soc/mediatek/mt8195-pm-domains.h
new file mode 100644
index 000000000000..1379aa39bf16
--- /dev/null
+++ b/drivers/soc/mediatek/mt8195-pm-domains.h
@@ -0,0 +1,613 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+ */
+
+#ifndef __SOC_MEDIATEK_MT8195_PM_DOMAINS_H
+#define __SOC_MEDIATEK_MT8195_PM_DOMAINS_H
+
+#include "mtk-pm-domains.h"
+#include <dt-bindings/power/mt8195-power.h>
+
+/*
+ * MT8195 power domain support
+ */
+
+static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
+	[MT8195_POWER_DOMAIN_PCIE_MAC_P0] = {
+		.name = "pcie_mac_p0",
+		.sta_mask = BIT(11),
+		.ctl_offs = 0x328,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_PCIE_MAC_P1] = {
+		.name = "pcie_mac_p1",
+		.sta_mask = BIT(12),
+		.ctl_offs = 0x32C,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_PCIE_PHY] = {
+		.name = "pcie_phy",
+		.sta_mask = BIT(13),
+		.ctl_offs = 0x330,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.caps = MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY] = {
+		.name = "ssusb_pcie_phy",
+		.sta_mask = BIT(14),
+		.ctl_offs = 0x334,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.caps = MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_CSI_RX_TOP] = {
+		.name = "csi_rx_top",
+		.sta_mask = BIT(18),
+		.ctl_offs = 0x3C4,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_ETHER] = {
+		.name = "ether",
+		.sta_mask = BIT(3),
+		.ctl_offs = 0x344,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_ADSP] = {
+		.name = "adsp",
+		.sta_mask = BIT(10),
+		.ctl_offs = 0x360,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_ADSP,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+		},
+		.caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_AUDIO] = {
+		.name = "audio",
+		.sta_mask = BIT(8),
+		.ctl_offs = 0x358,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_AUDIO,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_MFG0] = {
+		.name = "mfg0",
+		.sta_mask = BIT(1),
+		.ctl_offs = 0x300,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG1] = {
+		.name = "mfg1",
+		.sta_mask = BIT(2),
+		.ctl_offs = 0x304,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_MFG1,
+				    MT8195_TOP_AXI_PROT_EN_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_1_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG2] = {
+		.name = "mfg2",
+		.sta_mask = BIT(3),
+		.ctl_offs = 0x308,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG3] = {
+		.name = "mfg3",
+		.sta_mask = BIT(4),
+		.ctl_offs = 0x30C,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG4] = {
+		.name = "mfg4",
+		.sta_mask = BIT(5),
+		.ctl_offs = 0x310,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG5] = {
+		.name = "mfg5",
+		.sta_mask = BIT(6),
+		.ctl_offs = 0x314,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG6] = {
+		.name = "mfg6",
+		.sta_mask = BIT(7),
+		.ctl_offs = 0x318,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VPPSYS0] = {
+		.name = "vppsys0",
+		.sta_mask = BIT(11),
+		.ctl_offs = 0x364,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_VDOSYS0] = {
+		.name = "vdosys0",
+		.sta_mask = BIT(13),
+		.ctl_offs = 0x36C,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDOSYS0,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_VPPSYS1] = {
+		.name = "vppsys1",
+		.sta_mask = BIT(12),
+		.ctl_offs = 0x368,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_VDOSYS1] = {
+		.name = "vdosys1",
+		.sta_mask = BIT(14),
+		.ctl_offs = 0x370,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_DP_TX] = {
+		.name = "dp_tx",
+		.sta_mask = BIT(16),
+		.ctl_offs = 0x378,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_EPD_TX] = {
+		.name = "epd_tx",
+		.sta_mask = BIT(17),
+		.ctl_offs = 0x37C,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_HDMI_TX] = {
+		.name = "hdmi_tx",
+		.sta_mask = BIT(18),
+		.ctl_offs = 0x380,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_WPESYS] = {
+		.name = "wpesys",
+		.sta_mask = BIT(15),
+		.ctl_offs = 0x374,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_WPESYS,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_VDEC0] = {
+		.name = "vdec0",
+		.sta_mask = BIT(20),
+		.ctl_offs = 0x388,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VDEC1] = {
+		.name = "vdec1",
+		.sta_mask = BIT(21),
+		.ctl_offs = 0x38C,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VDEC2] = {
+		.name = "vdec2",
+		.sta_mask = BIT(22),
+		.ctl_offs = 0x390,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VENC] = {
+		.name = "venc",
+		.sta_mask = BIT(23),
+		.ctl_offs = 0x394,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VENC_CORE1] = {
+		.name = "venc_core1",
+		.sta_mask = BIT(24),
+		.ctl_offs = 0x398,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_IMG] = {
+		.name = "img",
+		.sta_mask = BIT(29),
+		.ctl_offs = 0x3AC,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_DIP] = {
+		.name = "dip",
+		.sta_mask = BIT(30),
+		.ctl_offs = 0x3B0,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_IPE] = {
+		.name = "ipe",
+		.sta_mask = BIT(31),
+		.ctl_offs = 0x3B4,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IPE,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_IPE,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_CAM] = {
+		.name = "cam",
+		.sta_mask = BIT(25),
+		.ctl_offs = 0x39C,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_CAM,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_CAM,
+				    MT8195_TOP_AXI_PROT_EN_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_1_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_CAM,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_CAM_RAWA] = {
+		.name = "cam_rawa",
+		.sta_mask = BIT(26),
+		.ctl_offs = 0x3A0,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_CAM_RAWB] = {
+		.name = "cam_rawb",
+		.sta_mask = BIT(27),
+		.ctl_offs = 0x3A4,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_CAM_MRAW] = {
+		.name = "cam_mraw",
+		.sta_mask = BIT(28),
+		.ctl_offs = 0x3A8,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+};
+
+static const struct scpsys_soc_data mt8195_scpsys_data = {
+	.domains_data = scpsys_domain_data_mt8195,
+	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8195),
+};
+
+#endif /* __SOC_MEDIATEK_MT8195_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
index ad06b6f90435..61973a306e97 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.c
+++ b/drivers/soc/mediatek/mtk-pm-domains.c
@@ -20,6 +20,7 @@
 #include "mt8173-pm-domains.h"
 #include "mt8183-pm-domains.h"
 #include "mt8192-pm-domains.h"
+#include "mt8195-pm-domains.h"
 
 #define MTK_POLL_DELAY_US		10
 #define MTK_POLL_TIMEOUT		USEC_PER_SEC
@@ -569,6 +570,10 @@ static const struct of_device_id scpsys_of_match[] = {
 		.compatible = "mediatek,mt8192-power-controller",
 		.data = &mt8192_scpsys_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-power-controller",
+		.data = &mt8195_scpsys_data,
+	},
 	{ }
 };
 
diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h
index 4f076f24dd52..1b8967b9829e 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.h
+++ b/drivers/soc/mediatek/mtk-pm-domains.h
@@ -37,7 +37,7 @@
 #define PWR_STATUS_AUDIO		BIT(24)
 #define PWR_STATUS_USB			BIT(25)
 
-#define SPM_MAX_BUS_PROT_DATA		5
+#define SPM_MAX_BUS_PROT_DATA		6
 
 #define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) {	\
 		.bus_prot_mask = (_mask),			\
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
index 4615a228da51..d858e0bab7a2 100644
--- a/include/linux/soc/mediatek/infracfg.h
+++ b/include/linux/soc/mediatek/infracfg.h
@@ -2,6 +2,88 @@
 #ifndef __SOC_MEDIATEK_INFRACFG_H
 #define __SOC_MEDIATEK_INFRACFG_H
 
+#define MT8195_TOP_AXI_PROT_EN_STA1                     0x228
+#define MT8195_TOP_AXI_PROT_EN_1_STA1                   0x258
+#define MT8195_TOP_AXI_PROT_EN_SET			0x2a0
+#define MT8195_TOP_AXI_PROT_EN_CLR                      0x2a4
+#define MT8195_TOP_AXI_PROT_EN_1_SET                    0x2a8
+#define MT8195_TOP_AXI_PROT_EN_1_CLR                    0x2ac
+#define MT8195_TOP_AXI_PROT_EN_MM_SET                   0x2d4
+#define MT8195_TOP_AXI_PROT_EN_MM_CLR                   0x2d8
+#define MT8195_TOP_AXI_PROT_EN_MM_STA1                  0x2ec
+#define MT8195_TOP_AXI_PROT_EN_2_SET                    0x714
+#define MT8195_TOP_AXI_PROT_EN_2_CLR                    0x718
+#define MT8195_TOP_AXI_PROT_EN_2_STA1                   0x724
+#define MT8195_TOP_AXI_PROT_EN_VDNR_SET                 0xb84
+#define MT8195_TOP_AXI_PROT_EN_VDNR_CLR                 0xb88
+#define MT8195_TOP_AXI_PROT_EN_VDNR_STA1                0xb90
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_SET               0xba4
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR               0xba8
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1              0xbb0
+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_SET               0xbb8
+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_CLR               0xbbc
+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_STA1              0xbc4
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET       0xbcc
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR       0xbd0
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1      0xbd8
+#define MT8195_TOP_AXI_PROT_EN_MM_2_SET                 0xdcc
+#define MT8195_TOP_AXI_PROT_EN_MM_2_CLR                 0xdd0
+#define MT8195_TOP_AXI_PROT_EN_MM_2_STA1                0xdd8
+
+#define MT8195_TOP_AXI_PROT_EN_VDOSYS0			BIT(6)
+#define MT8195_TOP_AXI_PROT_EN_VPPSYS0			BIT(10)
+#define MT8195_TOP_AXI_PROT_EN_MFG1			BIT(11)
+#define MT8195_TOP_AXI_PROT_EN_MFG1_2ND			GENMASK(22, 21)
+#define MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND		BIT(23)
+#define MT8195_TOP_AXI_PROT_EN_1_MFG1			GENMASK(20, 19)
+#define MT8195_TOP_AXI_PROT_EN_1_CAM			BIT(22)
+#define MT8195_TOP_AXI_PROT_EN_2_CAM			BIT(0)
+#define MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND		GENMASK(6, 5)
+#define MT8195_TOP_AXI_PROT_EN_2_MFG1			BIT(7)
+#define MT8195_TOP_AXI_PROT_EN_2_AUDIO			(BIT(9) | BIT(11))
+#define MT8195_TOP_AXI_PROT_EN_2_ADSP			(BIT(12) | GENMASK(16, 14))
+#define MT8195_TOP_AXI_PROT_EN_MM_CAM			(BIT(0) | BIT(2) | BIT(4))
+#define MT8195_TOP_AXI_PROT_EN_MM_IPE			BIT(1)
+#define MT8195_TOP_AXI_PROT_EN_MM_IMG			BIT(3)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0		GENMASK(21, 17)
+#define MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1		GENMASK(8, 5)
+#define MT8195_TOP_AXI_PROT_EN_MM_VENC			(BIT(9) | BIT(11))
+#define MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1		(BIT(10) | BIT(12))
+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC0			BIT(13)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC1			BIT(14)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND		BIT(22)
+#define MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND		BIT(23)
+#define MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND		BIT(24)
+#define MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND		BIT(25)
+#define MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND		BIT(26)
+#define MT8195_TOP_AXI_PROT_EN_MM_WPESYS		BIT(27)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND		BIT(28)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND		BIT(29)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1		GENMASK(31, 30)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND		(GENMASK(1, 0) | BIT(4) | BIT(11))
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VENC		BIT(2)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1		(BIT(3) | BIT(15))
+#define MT8195_TOP_AXI_PROT_EN_MM_2_CAM			(BIT(5) | BIT(17))
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1		(GENMASK(7, 6) | BIT(18))
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0		GENMASK(9, 8)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1		BIT(10)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND		BIT(12)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND		BIT(13)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND		BIT(14)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_IPE			BIT(16)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2		BIT(21)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0		BIT(22)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS		GENMASK(24, 23)
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX		BIT(1)
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX		BIT(2)
+#define MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0		(BIT(11) | BIT(28))
+#define MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1		(BIT(12) | BIT(29))
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0	BIT(13)
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1	BIT(14)
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1	(BIT(17) | BIT(19))
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0	BIT(20)
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0	BIT(21)
+
 #define MT8192_TOP_AXI_PROT_EN_STA1			0x228
 #define MT8192_TOP_AXI_PROT_EN_1_STA1			0x258
 #define MT8192_TOP_AXI_PROT_EN_SET			0x2a0
-- 
2.18.0

From maz at kernel.org  Mon Aug 23 02:33:40 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 23 Aug 2021 10:33:40 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <878s0t6s7p.mognet@arm.com>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
 <87eeav19mc.wl-maz@kernel.org> <87k0kk7w0c.mognet@arm.com>
 <87czqasn9u.wl-maz@kernel.org> <878s0t6s7p.mognet@arm.com>
Message-ID: <87czq4qzd7.wl-maz@kernel.org>

On Sun, 22 Aug 2021 23:16:10 +0100,
Valentin Schneider <valentin.schneider at arm.com> wrote:
> 
> On 18/08/21 17:58, Marc Zyngier wrote:
> > On Tue, 17 Aug 2021 01:30:43 +0100,
> > Valentin Schneider <valentin.schneider at arm.com> wrote:
> >> Are we guaranteed to have
> >>
> >>   .irq_ack \in {NULL, irq_chip_ack_parent}
> >>
> >> for all intermediate (!root) irqchips? I don't see why that wouldn't
> >> be the case, and with that in mind what you described makes sense to
> >> me.
> >
> > An intermediate layer is allowed to implement its own irq_ack that is
> > not irq_chip_ack_parent, but it then has to call irq_chip_ack_parent
> > itself.
> >
> 
> Right, makes sense.
> 
> > There is the bizarre case of drivers/gpio/gpio-thunderx.c that changes
> > the irqchip flow to use either handle_fasteoi_ack_irq or
> > handle_fasteoi_mask_irq, which won't play very nicely with this.
> > Someone said Cavium?
> >
> 
> Humph...
> 
> I'm not familiar at all with the gpiolib irqchips, but I was under the
> impression those would involve chained IRQs (it does appear to be the case
> for the pl061 GPIOs on a Juno). For those, the innermost desc would be handled
> via chained_irq_{enter, exit}() [!!!], and the outermost one via whatever
> flow was installed by the relevant driver.

Not all of them are built like this. There is actually a bunch of
these build as full hierarchies (QC, nvidia and some others).

> I can't easily grok what goes on between that gpio-thunderx.c driver and
> gpiolib, but since that GPIO chip has
> 
>         .irq_eoi		= irq_chip_eoi_parent,
> 
> and
> 
>         girq->parent_domain =
>                 irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;
> 
> (GPIOs hooked to MSI-X? Do I want to know?)

It's good, isn't it? TX1 has all its HW appearing as PCI, even if it
clearly isn't PCI underneath.

> 
> I'm guessing it is *not* chained, which means the irq_set_handler_locked()
> affects the entire stack :/

It does. We can probably fix that, but I won't be able to test (my TX1
was taken away a few months ago...). I'll accept body donations, for
scientific purposes.

> 
> [!!!] Speaking of chained IRQs, I'm now thinking this series breaks them;
> chained_irq_enter() + chained_irq_exit() will only issue an ->irq_eoi(),
> skipping the ->irq_ack()... One more thing to add to the list!

Urghh... Yeah, that's awful.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From ada at thorsis.com  Mon Aug 23 02:24:35 2021
From: ada at thorsis.com (Alexander Dahl)
Date: Mon, 23 Aug 2021 11:24:35 +0200
Subject: Enable HSIC Host Port on Atmel/Microchip SAMA5D2
Message-ID: <2869763.XZdSvA6Ref@ada>

Hello,

for a new embedded board featuring a Microchip SAMA5D2 SoC (64 MiB SiP variant 
SAMA5D27C-D5M) we connected the third USB host port (HSIC only) with an 
USB3503 hub chip. This doesn't work out of the box with the Linux kernel 
currently, because neither the SoC nor the kernel does enable the HSIC 
interface by default.

That SoC has three USB host ports, from the SAMA5D2 Series Datasheet [1] I 
learned there's a flag in an EHCI register, which has to be set to enable the 
HSIC interface on port C, the third port. (Section "41.7.14 EHCI: REG08 - HSIC 
Enable/Disable" of the datasheet.) I suppose that register is vendor specific. 
The register definitions in '/include/linux/usb/ehci_def.h' do not contain 
that register.

Where would I add that register definition and set that flag in the kernel 
then?  I suppose in the vendor specific ehci driver?  
That would be 'drivers/usb/host/ehci-atmel.c' right?

Since that feature is optional (other boards don't need to turn on hsic on 
that port), some driver specific new device tree binding would be necessary, 
right?  I suppose that would have to be documented in 'Documentation/
devicetree/bindings/usb/atmel-usb.txt' right? (Or that would have to be 
converted to yaml first?)

Is this the right track?  If yes, I'm going to develop patches for this. 
Otherwise any hint into the right direction are highly appreciated.

FWIW, I'm not the first one struggling [2] with this problem. ;-)

Greets
Alex

[1] https://www.microchip.com/en-us/product/ATSAMA5D27C-D5M#document-table
[2] https://community.atmel.com/forum/sama5d2-using-hsic-under-linux





From catalin.marinas at arm.com  Mon Aug 23 02:43:27 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 23 Aug 2021 10:43:27 +0100
Subject: [PATCH v6 3/8] arm64: PCI: Restructure
 pcibios_root_bridge_prepare()
In-Reply-To: <20210726180657.142727-4-boqun.feng@gmail.com>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-4-boqun.feng@gmail.com>
Message-ID: <20210823094326.GA8603@arm.com>

On Tue, Jul 27, 2021 at 02:06:52AM +0800, Boqun Feng wrote:
> Restructure the pcibios_root_bridge_prepare() as the preparation for
> supporting cases when no real ACPI device is related to the PCI host
> bridge.
> 
> No functional change.
> 
> Signed-off-by: Boqun Feng <boqun.feng at gmail.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Mon Aug 23 02:43:44 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 23 Aug 2021 10:43:44 +0100
Subject: [PATCH v6 4/8] arm64: PCI: Support root bridge preparation for
 Hyper-V
In-Reply-To: <20210726180657.142727-5-boqun.feng@gmail.com>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210726180657.142727-5-boqun.feng@gmail.com>
Message-ID: <20210823094343.GB8603@arm.com>

On Tue, Jul 27, 2021 at 02:06:53AM +0800, Boqun Feng wrote:
> Currently at root bridge preparation, the corresponding ACPI device will
> be set as the companion, however for a Hyper-V virtual PCI root bridge,
> there is no corresponding ACPI device, because a Hyper-V virtual PCI
> root bridge is discovered via VMBus rather than ACPI table. In order to
> support this, we need to make pcibios_root_bridge_prepare() work with
> cfg->parent being NULL.
> 
> Use a NULL pointer as the ACPI device if there is no corresponding ACPI
> device, and this is fine because: 1) ACPI_COMPANION_SET() can work with
> the second parameter being NULL, 2) semantically, if a NULL pointer is
> set via ACPI_COMPANION_SET(), ACPI_COMPANION() (the read API for this
> field) will return NULL, and since ACPI_COMPANION() may return NULL, so
> users must have handled the cases where it returns NULL, and 3) since
> there is no corresponding ACPI device, it would be wrong to use any
> other value here.
> 
> Signed-off-by: Boqun Feng <boqun.feng at gmail.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From shengjiu.wang at gmail.com  Mon Aug 23 02:45:20 2021
From: shengjiu.wang at gmail.com (Shengjiu Wang)
Date: Mon, 23 Aug 2021 17:45:20 +0800
Subject: [PATCH 1/2] dt-bindings: remoteproc: Add fsl,imx-dsp-rproc
 binding document
In-Reply-To: <YSAQgywy8UW540h9@robh.at.kernel.org>
References: <1629453791-10580-1-git-send-email-shengjiu.wang@nxp.com>
 <YSAQgywy8UW540h9@robh.at.kernel.org>
Message-ID: <CAA+D8AM1Ti5+LAwx+b5ZEy7Xi8Tx4n2Dh0ZW9faFDB04pLECRw@mail.gmail.com>

Hi Rob

On Sat, Aug 21, 2021 at 4:28 AM Rob Herring <robh at kernel.org> wrote:
>
> On Fri, Aug 20, 2021 at 06:03:10PM +0800, Shengjiu Wang wrote:
> > Define the compatible string and properties needed by imx_dsp_rproc
> > driver.
> >
> > Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
> > ---
> >  .../remoteproc/fsl,imx-dsp-rproc.yaml         | 123 ++++++++++++++++++
> >  1 file changed, 123 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
> > new file mode 100644
> > index 000000000000..7eba49aa959e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
> > @@ -0,0 +1,123 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/remoteproc/fsl,imx-dsp-rproc.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: i.MX DSP Remoteproc Devices
> > +
> > +maintainers:
> > +  - Shengjiu Wang <shengjiu.wang at nxp.com>
> > +
> > +description:
> > +  This binding provides support for DSP processors found on i.mX family of SoCs
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - fsl,imx8qxp-hifi4
> > +      - fsl,imx8qm-hifi4
> > +      - fsl,imx8mp-hifi4
> > +      - fsl,imx8ulp-hifi4
> > +
> > +  clocks:
> > +    description: |
> > +      Main functional clock for the remote processor
>
> Don't need '|' if no formatting.

Ok,  will update it.

>
> > +    minItems: 1
> > +    maxItems: 32
> > +
> > +  clock-names:
> > +    description:
> > +      List of clock names for the remote processor.
> > +      dsp_clkx for clocks of dsp itself.
> > +      per_clkx for clocks of peripherals used by dsp.
>
> Sounds like constraints that should be a schema. But this looks like
> some random collection of clocks, not clocks for the DSP h/w.

The DSP may use some peripheral devices, then we need to
enable the clock in this driver. Using which peripherals
depends on the DSP firmware, so we didn't specify the clock
name here.

I will add below items for this.
    items:
      - const: dsp_clk1
      - const: dsp_clk2
      - const: dsp_clk3
      - const: dsp_clk4
      - const: dsp_clk5
      - const: dsp_clk6
      - const: dsp_clk7
      - const: dsp_clk8
      - const: per_clk1
      - const: per_clk2
      - const: per_clk3
      - const: per_clk4
      - const: per_clk5
      - const: per_clk6
      - const: per_clk7
      - const: per_clk8
      - const: per_clk9
      - const: per_clk10
      - const: per_clk11
      - const: per_clk12
      - const: per_clk13
      - const: per_clk14
      - const: per_clk15
      - const: per_clk16
      - const: per_clk17
      - const: per_clk18

>
> > +    minItems: 1
> > +    maxItems: 32
> > +
> > +  syscon:
>
> Vendor prefix and name it based on what it points to or is used for.

Ok, will update it.

best regards
Wang shengjiu


From leo.yan at linaro.org  Mon Aug 23 02:51:55 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 23 Aug 2021 17:51:55 +0800
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <2b4e0c07-a8df-cca6-6a94-328560f4b0c6@arm.com>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-3-leo.yan@linaro.org>
 <2b4e0c07-a8df-cca6-6a94-328560f4b0c6@arm.com>
Message-ID: <20210823095155.GC100516@leoy-ThinkPad-X240s>

Hi James,

On Fri, Aug 13, 2021 at 05:22:31PM +0100, James Clark wrote:
> On 09/08/2021 12:27, Leo Yan wrote:
> > +/*
> > + * In the compat mode kernel runs in 64-bit and perf tool runs in 32-bit mode,
> > + * 32-bit perf tool cannot access 64-bit value atomically, which might lead to
> > + * the issues caused by the below sequence on multiple CPUs: when perf tool
> > + * accesses either the load operation or the store operation for 64-bit value,
> > + * on some architectures the operation is divided into two instructions, one
> > + * is for accessing the low 32-bit value and another is for the high 32-bit;
> > + * thus these two user operations can give the kernel chances to access the
> > + * 64-bit value, and thus leads to the unexpected load values.
> > + *
> > + *   kernel (64-bit)                        user (32-bit)
> > + *
> > + *   if (LOAD ->aux_tail) { --,             LOAD ->aux_head_lo
> > + *       STORE $aux_data      |       ,--->
> > + *       FLUSH $aux_data      |       |     LOAD ->aux_head_hi
> > + *       STORE ->aux_head   --|-------`     smp_rmb()
> > + *   }                        |             LOAD $data
> > + *                            |             smp_mb()
> > + *                            |             STORE ->aux_tail_lo
> > + *                            `----------->
> > + *                                          STORE ->aux_tail_hi
> > + *
> > + * For this reason, it's impossible for the perf tool to work correctly when
> > + * the AUX head or tail is bigger than 4GB (more than 32 bits length); and we
> > + * can not simply limit the AUX ring buffer to less than 4GB, the reason is
> > + * the pointers can be increased monotonically, whatever the buffer size it is,
> > + * at the end the head and tail can be bigger than 4GB and carry out to the
> > + * high 32-bit.
> > + *
> > + * To mitigate the issues and improve the user experience, we can allow the
> > + * perf tool working in certain conditions and bail out with error if detect
> > + * any overflow cannot be handled.
> > + *
> > + * For reading the AUX head, it reads out the values for three times, and
> > + * compares the high 4 bytes of the values between the first time and the last
> > + * time, if there has no change for high 4 bytes injected by the kernel during
> > + * the user reading sequence, it's safe for use the second value.
> > + *
> > + * When update the AUX tail and detects any carrying in the high 32 bits, it
> > + * means there have two store operations in user space and it cannot promise
> > + * the atomicity for 64-bit write, so return '-1' in this case to tell the
> > + * caller an overflow error has happened.
> > + */
> > +u64 __weak compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> > +{
> > +	struct perf_event_mmap_page *pc = mm->userpg;
> > +	u64 first, second, last;
> > +	u64 mask = (u64)(UINT32_MAX) << 32;
> > +
> > +	do {
> > +		first = READ_ONCE(pc->aux_head);
> > +		/* Ensure all reads are done after we read the head */
> > +		smp_rmb();
> > +		second = READ_ONCE(pc->aux_head);
> > +		/* Ensure all reads are done after we read the head */
> > +		smp_rmb();
> > +		last = READ_ONCE(pc->aux_head);
> > +	} while ((first & mask) != (last & mask));
> > +
> > +	return second;
> > +}
> > +
> 
> Hi Leo,
> 
> I had a couple of questions about this bit. If we're assuming that the
> high bytes of 'first' and 'last' are equal, then 'second' is supposed
> to be somewhere in between or equal to 'first' and 'last'.
> 
> If that's the case, wouldn't it be better to return 'last', because it's
> closer to the value at the time of reading?

> And then in that case, if last is returned, then why do a read for
> 'second' at all? Can 'second' be skipped and just read first and last?

Simply to say, the logic can be depicted as:

  step 1: read 'first'
  step 2: read 'second' -> There have no any atomicity risk if 'first'
                           is same with 'last'
  step 3: read 'last'

The key point is if the 'first' and 'last' have the same value in the
high word, there have no any increment for high word in the middle of
'first' and 'last', so we don't worry about the atomicity for 'second'.

But we cannot promise the atomicity for reading 'last', let's see
below sequence:

             CPU(a)                                 CPU(b)
  step 1: read 'first' (high word)
          read 'first' (low word)
  step 2: read 'second' (high word)
          read 'second' (low word)
  step 3: read 'last' (high word)
                                       --> write 'last' (high word)
                                       --> write 'last' (low word)
          read 'last' (low word)


Even 'first' and 'last' have the same high word, but the 'last' cannot
be trusted.

> Also maybe it won't make a difference, but is there a missing smp_rmb()
> between the read of 'last' and 'first'?

Good question, from my understanding, we only need to promise the flow
from step 1 to step 3, it's not necessary to add barrier in the middle
of the two continuous loops.

Thanks for reviewing!

Leo


From wenst at chromium.org  Mon Aug 23 02:56:22 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 17:56:22 +0800
Subject: [v2 06/24] clk: mediatek: Add MT8195 apmixedsys clock support
In-Reply-To: <CAGXv+5FVGQkR=OpyBA7rjE0sLLqVoTpgHJuG8YDaCnWFCdDM8A@mail.gmail.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-7-chun-jie.chen@mediatek.com>
 <CAGXv+5FVGQkR=OpyBA7rjE0sLLqVoTpgHJuG8YDaCnWFCdDM8A@mail.gmail.com>
Message-ID: <CAGXv+5E2G-OBwQyKdMVavw5hTNQsNe7v=yHc720csxOchV9wpA@mail.gmail.com>

On Mon, Aug 23, 2021 at 5:21 PM Chen-Yu Tsai <wenst at chromium.org> wrote:
>
> On Fri, Aug 20, 2021 at 7:20 PM Chun-Jie Chen
> <chun-jie.chen at mediatek.com> wrote:
> >
> > Add MT8195 apmixedsys clock controller which provides Plls
> > generated from SoC 26m and ssusb clock gate control.
> >
> > Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > ---
> >  drivers/clk/mediatek/Kconfig                 |   8 +
> >  drivers/clk/mediatek/Makefile                |   1 +
> >  drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 145 +++++++++++++++++++
> >  3 files changed, 154 insertions(+)
> >  create mode 100644 drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> >
> > diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
> > index 576babd86f98..7ba1f4118e0d 100644
> > --- a/drivers/clk/mediatek/Kconfig
> > +++ b/drivers/clk/mediatek/Kconfig
> > @@ -580,6 +580,14 @@ config COMMON_CLK_MT8192_VENCSYS
> >         help
> >           This driver supports MediaTek MT8192 vencsys clocks.
> >
> > +config COMMON_CLK_MT8195
> > +        bool "Clock driver for MediaTek MT8195"
> > +        depends on ARM64 || COMPILE_TEST
> > +        select COMMON_CLK_MEDIATEK
> > +        default ARM64
> > +        help
> > +          This driver supports MediaTek MT8195 basic clocks.
>
> Since we will have all clocks under the same Kconfig option, please
> drop the word "basic".
>
> > +
> >  config COMMON_CLK_MT8516
> >         bool "Clock driver for MediaTek MT8516"
> >         depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> > index 15bc045f0b71..d4157cfca865 100644
> > --- a/drivers/clk/mediatek/Makefile
> > +++ b/drivers/clk/mediatek/Makefile
> > @@ -80,5 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
> >  obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
> >  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
> >  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
> > +obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o
> >  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
> >  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> > diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> > new file mode 100644
> > index 000000000000..253eb30b22d4
> > --- /dev/null
> > +++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> > @@ -0,0 +1,145 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)

I actually only requested the files related to DT bindings, which includes
`Documentation/device-tree/bindings/*` and `include/dt-bindings/*`, be dual
licensed.

I'm not sure dual licensing the actual driver code makes sense, or is
even valid, since this calls into existing GPL-2.0 code. But I am not
a lawyer.


ChenYu

> > +//
> > +// Copyright (c) 2021 MediaTek Inc.
> > +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > +
> > +#include "clk-gate.h"
> > +#include "clk-mtk.h"
> > +
> > +#include <dt-bindings/clock/mt8195-clk.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +
> > +static const struct mtk_gate_regs apmixed_cg_regs = {
> > +       .set_ofs = 0x8,
> > +       .clr_ofs = 0x8,
> > +       .sta_ofs = 0x8,
> > +};
> > +
> > +#define GATE_APMIXED(_id, _name, _parent, _shift)                      \
> > +       GATE_MTK(_id, _name, _parent, &apmixed_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> > +
> > +static const struct mtk_gate apmixed_clks[] = {
> > +       GATE_APMIXED(CLK_APMIXED_PLL_SSUSB26M, "pll_ssusb26m", "clk26m", 1),
> > +};
> > +
> > +#define MT8195_PLL_FMAX                (3800UL * MHZ)
> > +#define MT8195_PLL_FMIN                (1500UL * MHZ)
> > +#define MT8195_INTEGER_BITS    8
> > +
> > +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags,              \
> > +                       _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift,    \
> > +                       _tuner_reg, _tuner_en_reg, _tuner_en_bit,       \
> > +                       _pcw_reg, _pcw_shift, _pcw_chg_reg,             \
> > +                       _en_reg, _pll_en_bit) {                         \
>
> Nit: Even for macro definitions, you could align the lines to the opening
> parenthesis. That would give you more room. And it would make it slightly
> easier to read.
>
> Otherwise,
>
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
>
> [...]


From tzungbi at google.com  Mon Aug 23 03:01:40 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Mon, 23 Aug 2021 18:01:40 +0800
Subject: [PATCH 2/9] media: mtk-vcodec: Use component framework to manage
 encoder hardware
In-Reply-To: <20210816105934.28265-3-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-3-irui.wang@mediatek.com>
Message-ID: <YSNyBE4yF6VDt3cC@google.com>

On Mon, Aug 16, 2021 at 06:59:27PM +0800, Irui Wang wrote:
> +static struct component_match *mtk_venc_match_add(struct mtk_vcodec_dev *dev)
> +{
> +	struct platform_device *pdev = dev->plat_dev;
> +	struct component_match *match = NULL;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(mtk_venc_comp_ids); i++) {
> +		enum mtk_venc_hw_id comp_idx;
> +		struct device_node *comp_node;
> +		const struct of_device_id *of_id;
To be neat, prefer to define the variables outside of the loop (i.e. at the beginning of the function).

> +
> +		comp_node = of_find_compatible_node(NULL, NULL,
> +			mtk_venc_comp_ids[i].compatible);
> +		if (!comp_node)
> +			continue;
> +
> +		of_id = of_match_node(mtk_venc_comp_ids, comp_node);
> +		if (!of_id) {
> +			dev_err(&pdev->dev, "Failed to get match node\n");
Need to call of_node_put() actually, but see comment below.

> +			return ERR_PTR(-EINVAL);
> +		}
> +
> +		comp_idx = (enum mtk_venc_hw_id)of_id->data;
For getting the comp_idx, mtk_venc_comp_ids[i].data should be sufficient.  If so, of_match_node() can be removed so that the error handling path won't need to call of_node_put().

> @@ -239,6 +314,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>  	phandle rproc_phandle;
>  	enum mtk_vcodec_fw_type fw_type;
>  	int ret;
> +	struct component_match *match = NULL;
It doesn't need to be initialized.

> -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> -	if (res == NULL) {
> -		dev_err(&pdev->dev, "failed to get irq resource");
> -		ret = -ENOENT;
> -		goto err_res;
> -	}
> +		res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> +		if (!res) {
> +			dev_err(&pdev->dev, "failed to get irq resource");
> +			ret = -ENOENT;
> +			goto err_res;
> +		}
res is not used.  Can be removed in next version or in another patch.

> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
> new file mode 100644
> index 000000000000..4e6a8a81ff67
> --- /dev/null
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_hw.c
> @@ -0,0 +1,179 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + */
> +
> +#include <linux/pm_runtime.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/module.h>
Would be better to maintain an order.

> +#include "mtk_vcodec_enc_hw.h"
> +#include "mtk_vcodec_enc.h"
Would be better to maintain an order.

> +static irqreturn_t mtk_enc_comp_irq_handler(int irq, void *priv)
> +{
> +	struct mtk_venc_comp_dev *dev = priv;
> +	struct mtk_vcodec_ctx *ctx;
> +	unsigned long flags;
> +	void __iomem *addr;
> +
> +	spin_lock_irqsave(&dev->master_dev->irqlock, flags);
> +	ctx = dev->curr_ctx;
> +	spin_unlock_irqrestore(&dev->master_dev->irqlock, flags);
> +	if (!ctx)
> +		return IRQ_HANDLED;
Here is a read lock for the curr_ctx.  The patch doesn't contain the write lock part.

I am not sure if the following situation would be happened:
1. curr_ctx is not NULL.
2. mtk_enc_comp_irq_handler() gets the curr_ctx.
3. The curr_ctx has been destroyed somewhere.
4. mtk_enc_comp_irq_handler() finds the ctx is not NULL so that it continues to execute.
5. Something wrong in latter mtk_enc_comp_irq_handler() because the ctx has been destroyed.

Does it make more sense to set curr_ctx to NULL to indicate the ownership has been transferred to mtk_enc_comp_irq_handler()?  For example:

spin_lock_irqsave(...);
ctx = dev->curr_ctx;
dev->curr_ctx = NULL;
spin_unlock_irqrestore(...);

> +static int mtk_venc_comp_bind(struct device *dev,
> +			      struct device *master, void *data)
> +{
> +	struct mtk_venc_comp_dev *comp_dev = dev_get_drvdata(dev);
> +	struct mtk_vcodec_dev *master_dev = data;
> +	int i;
> +
> +	for (i = 0; i < MTK_VENC_HW_MAX; i++) {
> +		if (dev->of_node != master_dev->enc_comp_node[i])
> +			continue;
> +
> +		/*add component device by order*/
> +		if (comp_dev->core_id == MTK_VENC_CORE0)
> +			master_dev->enc_comp_dev[MTK_VENC_CORE0] = comp_dev;
> +		else if (comp_dev->core_id == MTK_VENC_CORE1)
> +			master_dev->enc_comp_dev[MTK_VENC_CORE1] = comp_dev;
> +		else
> +			return -EINVAL;
if (comp_dev->core_id < 0 || comp_dev->core_id >= MTK_VENC_HW_MAX)
    return -EINVAL;

master_dev->enc_comp_dev[comp_dev->core_id] = comp_dev;


From lorenzo.pieralisi at arm.com  Mon Aug 23 03:02:16 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 23 Aug 2021 11:02:16 +0100
Subject: [PATCH v6 0/8] PCI: hv: Support host bridge probing on ARM64
In-Reply-To: <20210726180657.142727-1-boqun.feng@gmail.com>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
Message-ID: <162971291667.27395.14375494235091415545.b4-ty@arm.com>

On Tue, 27 Jul 2021 02:06:49 +0800, Boqun Feng wrote:
> This is the v6 for the preparation of virtual PCI support on Hyper-V
> ARM64, Previous versions:
> 
> v1:	https://lore.kernel.org/lkml/20210319161956.2838291-1-boqun.feng at gmail.com/
> v2:	https://lore.kernel.org/lkml/20210503144635.2297386-1-boqun.feng at gmail.com/
> v3:	https://lore.kernel.org/lkml/20210609163211.3467449-1-boqun.feng at gmail.com/
> v4:	https://lore.kernel.org/lkml/20210714102737.198432-1-boqun.feng at gmail.com/
> v5:	https://lore.kernel.org/lkml/20210720134429.511541-1-boqun.feng at gmail.com/
> 
> [...]

Applied to pci/hyper-v, thanks!

[1/8] PCI: Introduce domain_nr in pci_host_bridge
      https://git.kernel.org/lpieralisi/pci/c/15d82ca23c
[2/8] PCI: Support populating MSI domains of root buses via bridges
      https://git.kernel.org/lpieralisi/pci/c/41dd40fd71
[3/8] arm64: PCI: Restructure pcibios_root_bridge_prepare()
      https://git.kernel.org/lpieralisi/pci/c/b424d4d426
[4/8] arm64: PCI: Support root bridge preparation for Hyper-V
      https://git.kernel.org/lpieralisi/pci/c/7d40c0f70d
[5/8] PCI: hv: Generify PCI probing
      https://git.kernel.org/lpieralisi/pci/c/418cb6c8e0
[6/8] PCI: hv: Set ->domain_nr of pci_host_bridge at probing time
      https://git.kernel.org/lpieralisi/pci/c/38c0d266dc
[7/8] PCI: hv: Set up MSI domain at bridge probing time
      https://git.kernel.org/lpieralisi/pci/c/9e7f9178ab
[8/8] PCI: hv: Turn on the host bridge probing on ARM64
      https://git.kernel.org/lpieralisi/pci/c/88f94c7f8f

Thanks,
Lorenzo


From claudiu.beznea at microchip.com  Mon Aug 23 03:03:55 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 13:03:55 +0300
Subject: [PATCH 2/3] ARM: dts: at91: add bindins for securam
In-Reply-To: <20210823100356.22206-1-claudiu.beznea@microchip.com>
References: <20210823100356.22206-1-claudiu.beznea@microchip.com>
Message-ID: <20210823100356.22206-3-claudiu.beznea@microchip.com>

Add bindings for securam.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/sama7g5.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index ecabab4343b6..3a4315ac0eb0 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -75,6 +75,17 @@ soc {
 		#size-cells = <1>;
 		ranges;
 
+		securam: securam at e0000000 {
+			compatible = "microchip,sama7g5-securam", "atmel,sama5d2-securam", "mmio-sram";
+			reg = <0xe0000000 0x4000>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 18>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0xe0000000 0x4000>;
+			no-memory-wc;
+			status = "okay";
+		};
+
 		secumod: secumod at e0004000 {
 			compatible = "microchip,sama7g5-secumod", "atmel,sama5d2-secumod", "syscon";
 			reg = <0xe0004000 0x4000>;
-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 23 03:03:53 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 13:03:53 +0300
Subject: [PATCH 0/3] ARM: dts: at91: enable ips for sama7g5
Message-ID: <20210823100356.22206-1-claudiu.beznea@microchip.com>

Hi,

The following patches enable UDDRC, DDR3 PHY, SECURAM and SHDWC IPs
on SAMA7G5.

Thank you,
Claudiu Beznea

Claudiu Beznea (3):
  ARM: dts: at91: add ram bindings
  ARM: dts: at91: add bindins for securam
  ARM: dts: at91: add bindings for shdwc

 arch/arm/boot/dts/at91-sama7g5ek.dts |  9 ++++++++
 arch/arm/boot/dts/sama7g5.dtsi       | 34 ++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 23 03:03:54 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 13:03:54 +0300
Subject: [PATCH 1/3] ARM: dts: at91: add ram bindings
In-Reply-To: <20210823100356.22206-1-claudiu.beznea@microchip.com>
References: <20210823100356.22206-1-claudiu.beznea@microchip.com>
Message-ID: <20210823100356.22206-2-claudiu.beznea@microchip.com>

Add bindings for RAM (controller and PHY). These are necessary
for platform specific power management code.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/sama7g5.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index cc6be6db7b80..ecabab4343b6 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -515,6 +515,18 @@ spi11: spi at 400 {
 			};
 		};
 
+		uddrc: uddrc at e3800000 {
+			compatible = "microchip,sama7g5-uddrc";
+			reg = <0xe3800000 0x4000>;
+			status = "okay";
+		};
+
+		ddr3phy: ddr3phy at e3804000 {
+			compatible = "microchip,sama7g5-ddr3phy";
+			reg = <0xe3804000 0x1000>;
+			status = "okay";
+		};
+
 		gic: interrupt-controller at e8c11000 {
 			compatible = "arm,cortex-a7-gic";
 			#interrupt-cells = <3>;
-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 23 03:03:56 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 13:03:56 +0300
Subject: [PATCH 3/3] ARM: dts: at91: add bindings for shdwc
In-Reply-To: <20210823100356.22206-1-claudiu.beznea@microchip.com>
References: <20210823100356.22206-1-claudiu.beznea@microchip.com>
Message-ID: <20210823100356.22206-4-claudiu.beznea@microchip.com>

Add DT bindings for shutdown controller and enable it.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91-sama7g5ek.dts |  9 +++++++++
 arch/arm/boot/dts/sama7g5.dtsi       | 11 +++++++++++
 2 files changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts
index 4cbed98cc2f4..8b13b031a167 100644
--- a/arch/arm/boot/dts/at91-sama7g5ek.dts
+++ b/arch/arm/boot/dts/at91-sama7g5ek.dts
@@ -634,6 +634,15 @@ &sdmmc2 {
 	pinctrl-0 = <&pinctrl_sdmmc2_default>;
 };
 
+&shdwc {
+	atmel,shdwc-debouncer = <976>;
+	status = "okay";
+
+	input at 0 {
+		reg = <0>;
+	};
+};
+
 &spdifrx {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_spdifrx_default>;
diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index 3a4315ac0eb0..e50806cf7660 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -122,6 +122,17 @@ pmc: pmc at e0018000 {
 			clock-names = "td_slck", "md_slck", "main_xtal";
 		};
 
+		shdwc: shdwc at e001d010 {
+			compatible = "microchip,sama7g5-shdwc", "syscon";
+			reg = <0xe001d010 0x10>;
+			clocks = <&clk32k 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			atmel,wakeup-rtc-timer;
+			atmel,wakeup-rtt-timer;
+			status = "disabled";
+		};
+
 		rtt: rtt at e001d020 {
 			compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
 			reg = <0xe001d020 0x30>;
-- 
2.25.1



From lorenzo.pieralisi at arm.com  Mon Aug 23 03:10:00 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 23 Aug 2021 11:10:00 +0100
Subject: [PATCH v6 0/8] PCI: hv: Support host bridge probing on ARM64
In-Reply-To: <YR59KJ+SenbQ58cw@boqun-archlinux>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210819141758.GA27305@lpieralisi>
 <YR59KJ+SenbQ58cw@boqun-archlinux>
Message-ID: <20210823100959.GA3294@lpieralisi>

On Thu, Aug 19, 2021 at 11:47:52PM +0800, Boqun Feng wrote:
> On Thu, Aug 19, 2021 at 03:17:58PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Jul 27, 2021 at 02:06:49AM +0800, Boqun Feng wrote:
> > > Hi,
> > > 
> > > This is the v6 for the preparation of virtual PCI support on Hyper-V
> > > ARM64, Previous versions:
> > > 
> > > v1:	https://lore.kernel.org/lkml/20210319161956.2838291-1-boqun.feng at gmail.com/
> > > v2:	https://lore.kernel.org/lkml/20210503144635.2297386-1-boqun.feng at gmail.com/
> > > v3:	https://lore.kernel.org/lkml/20210609163211.3467449-1-boqun.feng at gmail.com/
> > > v4:	https://lore.kernel.org/lkml/20210714102737.198432-1-boqun.feng at gmail.com/
> > > v5:	https://lore.kernel.org/lkml/20210720134429.511541-1-boqun.feng at gmail.com/
> > > 
> > > Changes since last version:
> > > 
> > > *	Rebase to 5.14-rc3
> > > 
> > > *	Comment fixes as suggested by Bjorn.
> > > 
> > > The basic problem we need to resolve is that ARM64 is an arch with
> > > PCI_DOMAINS_GENERIC=y, so the bus sysdata is pci_config_window. However,
> > > Hyper-V PCI provides a paravirtualized PCI interface, so there is no
> > > actual pci_config_window for a PCI host bridge, so no information can be
> > > retrieve from the pci_config_window of a Hyper-V virtual PCI bus. Also
> > > there is no corresponding ACPI device for the Hyper-V PCI root bridge,
> > > which introduces a special case when trying to find the ACPI device from
> > > the sysdata (see patch #3).
> > > 
> > > With this patchset, we could enable the virtual PCI on Hyper-V ARM64
> > > guest with other code under development.
> > > 
> > > Comments and suggestions are welcome.
> > > 
> > > Regards,
> > > Boqun
> > > 
> > > Arnd Bergmann (1):
> > >   PCI: hv: Generify PCI probing
> > > 
> > > Boqun Feng (7):
> > >   PCI: Introduce domain_nr in pci_host_bridge
> > >   PCI: Support populating MSI domains of root buses via bridges
> > >   arm64: PCI: Restructure pcibios_root_bridge_prepare()
> > >   arm64: PCI: Support root bridge preparation for Hyper-V
> > >   PCI: hv: Set ->domain_nr of pci_host_bridge at probing time
> > >   PCI: hv: Set up MSI domain at bridge probing time
> > >   PCI: hv: Turn on the host bridge probing on ARM64
> > > 
> > >  arch/arm64/kernel/pci.c             | 29 +++++++---
> > >  drivers/pci/controller/pci-hyperv.c | 86 +++++++++++++++++------------
> > >  drivers/pci/probe.c                 | 12 +++-
> > >  include/linux/pci.h                 | 11 ++++
> > >  4 files changed, 93 insertions(+), 45 deletions(-)
> > 
> > If we take this series via the PCI tree we'd need Catalin/Will ACKs on
> > patches 3-4.
> > 
> 
> Got it.
> 
> > I need some time to look into [1] (thanks for that).
> > 
> > Without [1] patch 8 is ugly, that's no news. The question is whether
> > it is worth waiting for a kernel cycle to integrate [1] into this series
> > or not.
> > 
> > Is it really a problem if we postpone this series for another kernel
> > cycle so that we can look into it ?
> > 
> 
> Well, it's definitely better for me that we can have it in 5.15-rc1 ;-),
> because it's a dependency for Hyper-V virtual PCI support on ARM64 and
> we plan to send the rest of work in 5.15 cycle. And I can just base on
> hyperv-next for the rest of the work if this is in 5.15-rc1. But yes,
> it's not really a problem, since this one still needs to work with other
> patches to support virtual PCI on ARM64 Hyper-V.
> 
> In fact, I personally don't think [1] is better than patch 8 (plus patch
> 3 & 4): playing with ->private seems dangerous and not very helpful on
> readiblity, but I agree that we should explore every potential solution,
> and that's why I send [1].

Pulled the current series - now let's work together to improve it, I
will have a look into [1] in the weeks to come and get back to you with
some feedback.

Thanks,
Lorenzo

> Regards,
> Boqun
> 
> > [1] https://lore.kernel.org/lkml/20210811153619.88922-1-boqun.feng at gmail.com/


From mark.rutland at arm.com  Mon Aug 23 03:12:53 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 23 Aug 2021 11:12:53 +0100
Subject: [PATCH v2] arm64: head: avoid over-mapping in map_memory
Message-ID: <20210823101253.55567-1-mark.rutland@arm.com>

The `compute_indices` and `populate_entries` macros operate on inclusive
bounds, and thus the `map_memory` macro which uses them also operates
on inclusive bounds.

We pass `_end` and `_idmap_text_end` to `map_memory`, but these are
exclusive bounds, and if one of these is sufficiently aligned (as a
result of kernel configuration, physical placement, and KASLR), then:

* In `compute_indices`, the computed `iend` will be in the page/block *after*
  the final byte of the intended mapping.

* In `populate_entries`, an unnecessary entry will be created at the end
  of each level of table. At the leaf level, this entry will map up to
  SWAPPER_BLOCK_SIZE bytes of physical addresses that we did not intend
  to map.

As we may map up to SWAPPER_BLOCK_SIZE bytes more than intended, we may
violate the boot protocol and map physical address past the 2MiB-aligned
end address we are permitted to map. As we map these with Normal memory
attributes, this may result in further problems depending on what these
physical addresses correspond to.

The final entry at each level may require an additional table at that
level. As EARLY_ENTRIES() calculates an inclusive bound, we allocate
enough memory for this.

Avoid the extraneous mapping by having map_memory convert the exclusive
end address to an inclusive end address by subtracting one, and do
likewise in EARLY_ENTRIES() when calculating the number of required
tables. For clarity, comments are updated to more clearly document which
boundaries the macros operate on.  For consistency with the other
macros, the comments in map_memory are also updated to describe `vstart`
and `vend` as virtual addresses.

Fixes: 0370b31e48454d8c ("arm64: Extend early page table code to allow for larger kernel")
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Anshuman Khandual <anshuman.khandual at arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Steve Capper <steve.capper at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/kernel-pgtable.h |  4 ++--
 arch/arm64/kernel/head.S                | 11 ++++++-----
 2 files changed, 8 insertions(+), 7 deletions(-)

Since v1 [1]:
* Subtract in map_memory macro
* Update EARLY_ENTRIES()
* Follow existing comment style

[1] https://lore.kernel.org/r/20210810152756.23903-1-mark.rutland at arm.com

Mark.

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 3512184cfec17..96dc0f7da258d 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -65,8 +65,8 @@
 #define EARLY_KASLR	(0)
 #endif
 
-#define EARLY_ENTRIES(vstart, vend, shift) (((vend) >> (shift)) \
-					- ((vstart) >> (shift)) + 1 + EARLY_KASLR)
+#define EARLY_ENTRIES(vstart, vend, shift) \
+	((((vend) - 1) >> (shift)) - ((vstart) >> (shift)) + 1 + EARLY_KASLR)
 
 #define EARLY_PGDS(vstart, vend) (EARLY_ENTRIES(vstart, vend, PGDIR_SHIFT))
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c5c994a73a645..17962452e31de 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -177,7 +177,7 @@ SYM_CODE_END(preserve_boot_args)
  * to be composed of multiple pages. (This effectively scales the end index).
  *
  *	vstart:	virtual address of start of range
- *	vend:	virtual address of end of range
+ *	vend:	virtual address of end of range - we map [vstart, vend]
  *	shift:	shift used to transform virtual address into index
  *	ptrs:	number of entries in page table
  *	istart:	index in table corresponding to vstart
@@ -214,17 +214,18 @@ SYM_CODE_END(preserve_boot_args)
  *
  *	tbl:	location of page table
  *	rtbl:	address to be used for first level page table entry (typically tbl + PAGE_SIZE)
- *	vstart:	start address to map
- *	vend:	end address to map - we map [vstart, vend]
+ *	vstart:	virtual address of start of range
+ *	vend:	virtual address of end of range - we map [vstart, vend - 1]
  *	flags:	flags to use to map last level entries
  *	phys:	physical address corresponding to vstart - physical memory is contiguous
  *	pgds:	the number of pgd entries
  *
  * Temporaries:	istart, iend, tmp, count, sv - these need to be different registers
- * Preserves:	vstart, vend, flags
- * Corrupts:	tbl, rtbl, istart, iend, tmp, count, sv
+ * Preserves:	vstart, flags
+ * Corrupts:	tbl, rtbl, vend, istart, iend, tmp, count, sv
  */
 	.macro map_memory, tbl, rtbl, vstart, vend, flags, phys, pgds, istart, iend, tmp, count, sv
+	sub \vend, \vend, #1
 	add \rtbl, \tbl, #PAGE_SIZE
 	mov \sv, \rtbl
 	mov \count, #0
-- 
2.11.0



From geert at linux-m68k.org  Mon Aug 23 03:13:29 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 23 Aug 2021 12:13:29 +0200
Subject: [PATCH v5 0/9] Add generic support for kdump DT properties
In-Reply-To: <YRkxzx/1XM3r64Ee@robh.at.kernel.org>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <YRkxzx/1XM3r64Ee@robh.at.kernel.org>
Message-ID: <CAMuHMdXs0+7K4N0mg6qX6X1cr_8dBr_HdTahdfORMk76wCJcEA@mail.gmail.com>

Hi Rob,

On Sun, Aug 15, 2021 at 5:25 PM Rob Herring <robh at kernel.org> wrote:
> On Wed, Aug 11, 2021 at 10:50:58AM +0200, Geert Uytterhoeven wrote:
> > This patch series adds generic support for parsing DT properties related
> > to crash dump kernels ("linux,elfcorehdr" and "linux,elfcorehdr" under
> > the "/chosen" node), makes use of it on arm32, and performs a few
> > cleanups.  It is an evolution of the combination of [1] and [2].
>
> The DT bits look fine to me. How do you expect this to be merged? I'm
> happy to take it if arch maintainers can ack it.

I had hoped you could take the series...

> > The series consists of 6 parts:
> >   1. Patch 1 prepares architecture-specific code (needed for MIPS only)
> >      to avoid duplicating elf core header reservation later.
> >   2. Patch 2 prepares the visibility of variables used to hold
> >      information retrieved from the DT properties.
> >   3. Patches 3-5 add support to the FDT core for handling the
> >      properties.
> >      This can co-exist safely with architecture-specific handling, until
> >      the latter has been removed.
>
> Looks like patch 5 doesn't have any dependencies with the series?

Indeed. So you can take it independently.

> >   4. Patch 6 removes the non-standard handling of "linux,elfcorehdr" on
> >      riscv.
>
> I thought this should be applied for 5.14?

Me too, but unfortunately that hasn't happened yet...

> >   5. Patches 7-8 convert arm64 to use the generic handling instead of
> >      its own implementation.
> >   6. Patch 9 adds support for kdump properties to arm32.
> >      The corresponding patch for kexec-tools is "[PATCH] arm: kdump: Add
> >      DT properties to crash dump kernel's DTB"[3], which is still valid.
>
> This one can be applied on its own, right?

While that wouldn't break anything (i.e. no regression), it still
wouldn't work if the DT properties are present, and the now-legacy
"mem=" kernel command line parameter is not.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From tzungbi at google.com  Mon Aug 23 03:16:47 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Mon, 23 Aug 2021 18:16:47 +0800
Subject: [PATCH 3/9] media: mtk-vcodec: Rewrite venc power manage interface
In-Reply-To: <20210816105934.28265-4-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-4-irui.wang@mediatek.com>
Message-ID: <YSN1j7o5+Tzk0HlH@google.com>

On Mon, Aug 16, 2021 at 06:59:28PM +0800, Irui Wang wrote:
> @@ -105,6 +106,14 @@ static int mtk_venc_comp_probe(struct platform_device *pdev)
>  
>  	comp_dev->plat_dev = pdev;
>  
> +	ret = mtk_vcodec_init_enc_pm(pdev, &comp_dev->pm);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to get venc component clock source!");
> +		return ret;
> +	}
> +
> +	pm_runtime_enable(&pdev->dev);
mtk_vcodec_init_enc_pm() and mtk_vcodec_release_enc_pm() is more like a pair.  Does it make more sense to call pm_runtime_enable() in mtk_vcodec_init_enc_pm()?


From geert at linux-m68k.org  Mon Aug 23 03:17:50 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 23 Aug 2021 12:17:50 +0200
Subject: [PATCH v5 1/9] MIPS: Avoid future duplicate elf core header
 reservation
In-Reply-To: <YRn9DHlB/pdNPJyP@kernel.org>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>
 <YRn9DHlB/pdNPJyP@kernel.org>
Message-ID: <CAMuHMdVdqR7gw+2O2v=qv_BB=+X2wEXN9jXV=np=jRayadwj7g@mail.gmail.com>

Hi Mike,

On Mon, Aug 16, 2021 at 7:52 AM Mike Rapoport <rppt at kernel.org> wrote:
> On Wed, Aug 11, 2021 at 10:50:59AM +0200, Geert Uytterhoeven wrote:
> > Prepare for early_init_fdt_scan_reserved_mem() reserving the memory
> > occupied by an elf core header described in the device tree.
> > As arch_mem_init() calls early_init_fdt_scan_reserved_mem() before
> > mips_reserve_vmcore(), the latter needs to check if the memory has
> > already been reserved before.
>
> Doing memblock_reserve() for the same region is usually fine, did you
> encounter any issues without this patch?

Does it also work if the same region is part of an earlier larger
reservation?  I am no memblock expert, so I don't know.
I didn't run into any issues, as my MIPS platform is non-DT, but I
assume arch/arm64/mm/init.c:reserve_elfcorehdr() had the check for
a reason.

Thanks!

>
> > Note that mips_reserve_vmcore() cannot just be removed, as not all MIPS
> > systems use DT.
> >
> > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> > ---
> > v5:
> >   - New.
> > ---
> >  arch/mips/kernel/setup.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> > index 23a140327a0bac1b..4693add05743d78b 100644
> > --- a/arch/mips/kernel/setup.c
> > +++ b/arch/mips/kernel/setup.c
> > @@ -429,7 +429,8 @@ static void __init mips_reserve_vmcore(void)
> >       pr_info("Reserving %ldKB of memory at %ldKB for kdump\n",
> >               (unsigned long)elfcorehdr_size >> 10, (unsigned long)elfcorehdr_addr >> 10);
> >
> > -     memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
> > +     if (!memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)
> > +             memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
> >  #endif
> >  }

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From tabba at google.com  Mon Aug 23 03:21:05 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 23 Aug 2021 11:21:05 +0100
Subject: [PATCH v4 11/15] KVM: arm64: Guest exit handlers for nVHE hyp
In-Reply-To: <87zgtdqz77.wl-maz@kernel.org>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-12-tabba@google.com>
 <87fsv6snup.wl-maz@kernel.org> <87zgtdqz77.wl-maz@kernel.org>
Message-ID: <CA+EHjTwyC-ZMpKQWGPqqYGHHR+YvyG3cdaxdwJfmYYf7XbBWEw@mail.gmail.com>

Hi Marc,

On Thu, Aug 19, 2021 at 3:36 PM Marc Zyngier <maz at kernel.org> wrote:
>
> Hi Fuad,
>
> On Wed, 18 Aug 2021 17:45:50 +0100,
> Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Tue, 17 Aug 2021 09:11:30 +0100,
> > Fuad Tabba <tabba at google.com> wrote:
> > >
> > > Add an array of pointers to handlers for various trap reasons in
> > > nVHE code.
> > >
> > > The current code selects how to fixup a guest on exit based on a
> > > series of if/else statements. Future patches will also require
> > > different handling for guest exists. Create an array of handlers
> > > to consolidate them.
> > >
> > > No functional change intended as the array isn't populated yet.
> > >
> > > Acked-by: Will Deacon <will at kernel.org>
> > > Signed-off-by: Fuad Tabba <tabba at google.com>
> > > ---
> > >  arch/arm64/kvm/hyp/include/hyp/switch.h | 43 +++++++++++++++++++++++++
> > >  arch/arm64/kvm/hyp/nvhe/switch.c        | 33 +++++++++++++++++++
> > >  2 files changed, 76 insertions(+)
> > >
> > > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > > index a0e78a6027be..5a2b89b96c67 100644
> > > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> > > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > > @@ -409,6 +409,46 @@ static inline bool __hyp_handle_ptrauth(struct kvm_vcpu *vcpu)
> > >     return true;
> > >  }
> > >
> > > +typedef int (*exit_handle_fn)(struct kvm_vcpu *);
> >
> > This returns an int...
> >
> > > +
> > > +exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu);
> > > +
> > > +static exit_handle_fn kvm_get_hyp_exit_handler(struct kvm_vcpu *vcpu)
> > > +{
> > > +   return is_nvhe_hyp_code() ? kvm_get_nvhe_exit_handler(vcpu) : NULL;
> > > +}
> > > +
> > > +/*
> > > + * Allow the hypervisor to handle the exit with an exit handler if it has one.
> > > + *
> > > + * Returns true if the hypervisor handled the exit, and control should go back
> > > + * to the guest, or false if it hasn't.
> > > + */
> > > +static bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu)
> > > +{
> > > +   bool is_handled = false;
> >
> > ... which you then implicitly cast as a bool.
> >
> > > +   exit_handle_fn exit_handler = kvm_get_hyp_exit_handler(vcpu);
> > > +
> > > +   if (exit_handler) {
> > > +           /*
> > > +            * There's limited vcpu context here since it's not synced yet.
> > > +            * Ensure that relevant vcpu context that might be used by the
> > > +            * exit_handler is in sync before it's called and if handled.
> > > +            */
> > > +           *vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
> > > +           *vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
> > > +
> > > +           is_handled = exit_handler(vcpu);
> >
> > What does 'is_handled' mean here? By definition, any trap *must* be
> > handled, one way or another. By the look of it, what you really mean
> > is something like "I have updated the vcpu state and you'd better
> > reload it". Is that what it means?
> >
> > > +
> > > +           if (is_handled) {
> > > +                   write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
> > > +                   write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
> > > +           }
> > > +   }
> > > +
> > > +   return is_handled;
> > > +}
> >
> > All these functions really should be marked inline. Have you checked
> > how this expands on VHE? I think some compilers could be pretty
> > unhappy about the undefined symbol in kvm_get_hyp_exit_handler().
> >
> > It is also unfortunate that we get a bunch of tests for various
> > flavours of traps (FP, PAuth, page faults...), only to hit yet another
> > decoding tree. Is there a way we could use this infrastructure for
> > everything?
>
> I realised that I wasn't very forthcoming here. I've decided to put
> the code where my mouth is and pushed out a branch [1] with your first
> 10 patches, followed by my own take on this particular problem. It
> compiles, and even managed to boot a Debian guest on a nVHE box.
>
> As you can see, most of the early exit handling is now moved to
> specific handlers, unifying the handling. For the protected mode, you
> can provide your own handler array (just hack
> kvm_get_exit_handler_array() to return something else), which will do
> the right thing as long as you call into the existing handlers first.
> When it comes to the ELR/SPSR handling, it is better left to the
> individual handlers (which we already do in some cases, see how we
> skip instructions, for example).
> Please let me know what you think.

Thanks a lot for this and sorry for being late to reply. I've been travelling.

I think that your proposal looks great. All handling is consolidated
now and handling for protected VMs can just be added on top. There are
some small issues with what parameters we need (e.g., passing struct
kvm to kvm_get_exit_handler_array), but I will sort them out and
submit them in the next round.

Cheers,
/fuad

> Thanks,
>
>         M.
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/pkvm-fixed-features
>
> --
> Without deviation from the norm, progress is not possible.


From tabba at google.com  Mon Aug 23 03:23:46 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 23 Aug 2021 11:23:46 +0100
Subject: [PATCH v4 00/15] KVM: arm64: Fixed features for protected VMs
In-Reply-To: <162945557041.2025988.6137048861111259637.b4-ty@kernel.org>
References: <20210817081134.2918285-1-tabba@google.com>
 <162945557041.2025988.6137048861111259637.b4-ty@kernel.org>
Message-ID: <CA+EHjTzZn+_4VZ+J7gToBv6XYXUBDxmHT0zkHVy+-2RDFY=-wQ@mail.gmail.com>

Hi Marc,

On Fri, Aug 20, 2021 at 11:34 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Tue, 17 Aug 2021 09:11:19 +0100, Fuad Tabba wrote:
> > Changes since v3 [1]:
> > - Redid calculating restricted values of feature register fields, ensuring that
> >   the code distinguishes between unsigned and (potentially in the future)
> >   signed fields (Will)
> > - Refactoring and fixes (Drew, Will)
> > - More documentation and comments (Oliver, Will)
> > - Dropped patch "Restrict protected VM capabilities", since it should come with
> >   or after the user ABI series for pKVM (Will)
> > - Carried Will's acks
> >
> > [...]
>
> I've taken the first 10 patches of this series in order to
> progress it. I also stashed a fixlet on top to address the
> tracepoint issue.
>
> Hopefully we can resolve the rest of the issues quickly.

Thanks. I am working on a patch series with the remaining patches to
address the issues. Stay tuned :)

Cheers,
/fuad

> [01/15] KVM: arm64: placeholder to check if VM is protected
>         commit: 2ea7f655800b00b109951f22539fe2025add210b
> [02/15] KVM: arm64: Remove trailing whitespace in comment
>         commit: e6bc555c96990046d680ff92c8e2e7b6b43b509f
> [03/15] KVM: arm64: MDCR_EL2 is a 64-bit register
>         commit: d6c850dd6ce9ce4b410142a600d8c34dc041d860
> [04/15] KVM: arm64: Fix names of config register fields
>         commit: dabb1667d8573302712a75530cccfee8f3ffff84
> [05/15] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse
>         commit: f76f89e2f73d93720cfcad7fb7b24d022b2846bf
> [06/15] KVM: arm64: Restore mdcr_el2 from vcpu
>         commit: 1460b4b25fde52cbee746c11a4b1d3185f2e2847
> [07/15] KVM: arm64: Keep mdcr_el2's value as set by __init_el2_debug
>         commit: 12849badc6d2456f15f8f2c93037628d5176810b
> [08/15] KVM: arm64: Track value of cptr_el2 in struct kvm_vcpu_arch
>         commit: cd496228fd8de2e82b6636d3d89105631ea2b69c
> [09/15] KVM: arm64: Add feature register flag definitions
>         commit: 95b54c3e4c92b9185b15c83e8baab9ba312195f6
> [10/15] KVM: arm64: Add config register bit definitions
>         commit: 2d701243b9f231b5d7f9a8cb81870650d3eb32bc
>
> Cheers,
>
>         M.
> --
> Without deviation from the norm, progress is not possible.
>
>

On Fri, Aug 20, 2021 at 11:34 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Tue, 17 Aug 2021 09:11:19 +0100, Fuad Tabba wrote:
> > Changes since v3 [1]:
> > - Redid calculating restricted values of feature register fields, ensuring that
> >   the code distinguishes between unsigned and (potentially in the future)
> >   signed fields (Will)
> > - Refactoring and fixes (Drew, Will)
> > - More documentation and comments (Oliver, Will)
> > - Dropped patch "Restrict protected VM capabilities", since it should come with
> >   or after the user ABI series for pKVM (Will)
> > - Carried Will's acks
> >
> > [...]
>
> I've taken the first 10 patches of this series in order to
> progress it. I also stashed a fixlet on top to address the
> tracepoint issue.
>
> Hopefully we can resolve the rest of the issues quickly.
>
> [01/15] KVM: arm64: placeholder to check if VM is protected
>         commit: 2ea7f655800b00b109951f22539fe2025add210b
> [02/15] KVM: arm64: Remove trailing whitespace in comment
>         commit: e6bc555c96990046d680ff92c8e2e7b6b43b509f
> [03/15] KVM: arm64: MDCR_EL2 is a 64-bit register
>         commit: d6c850dd6ce9ce4b410142a600d8c34dc041d860
> [04/15] KVM: arm64: Fix names of config register fields
>         commit: dabb1667d8573302712a75530cccfee8f3ffff84
> [05/15] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse
>         commit: f76f89e2f73d93720cfcad7fb7b24d022b2846bf
> [06/15] KVM: arm64: Restore mdcr_el2 from vcpu
>         commit: 1460b4b25fde52cbee746c11a4b1d3185f2e2847
> [07/15] KVM: arm64: Keep mdcr_el2's value as set by __init_el2_debug
>         commit: 12849badc6d2456f15f8f2c93037628d5176810b
> [08/15] KVM: arm64: Track value of cptr_el2 in struct kvm_vcpu_arch
>         commit: cd496228fd8de2e82b6636d3d89105631ea2b69c
> [09/15] KVM: arm64: Add feature register flag definitions
>         commit: 95b54c3e4c92b9185b15c83e8baab9ba312195f6
> [10/15] KVM: arm64: Add config register bit definitions
>         commit: 2d701243b9f231b5d7f9a8cb81870650d3eb32bc
>
> Cheers,
>
>         M.
> --
> Without deviation from the norm, progress is not possible.
>
>


From tabba at google.com  Mon Aug 23 03:25:20 2021
From: tabba at google.com (Fuad Tabba)
Date: Mon, 23 Aug 2021 11:25:20 +0100
Subject: [PATCH v4 15/15] KVM: arm64: Handle protected guests at 32 bits
In-Reply-To: <CAOQ_QsgSfHVjJkSJku5DwUe0_=ds4GduPbJ7vC-t+4_=fPVFBQ@mail.gmail.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-16-tabba@google.com>
 <CAOQ_QsgSfHVjJkSJku5DwUe0_=ds4GduPbJ7vC-t+4_=fPVFBQ@mail.gmail.com>
Message-ID: <CA+EHjTwPgjXtrR5dFx0RBN9xdX0j7ugO=NqAmkmZqYE9N_jP7w@mail.gmail.com>

Hi Oliver,

On Thu, Aug 19, 2021 at 9:10 AM Oliver Upton <oupton at google.com> wrote:
>
> Hi Fuad,
>
> On Tue, Aug 17, 2021 at 1:12 AM Fuad Tabba <tabba at google.com> wrote:
> >
> > Protected KVM does not support protected AArch32 guests. However,
> > it is possible for the guest to force run AArch32, potentially
> > causing problems. Add an extra check so that if the hypervisor
> > catches the guest doing that, it can prevent the guest from
> > running again by resetting vcpu->arch.target and returning
> > ARM_EXCEPTION_IL.
> >
> > If this were to happen, The VMM can try and fix it by re-
> > initializing the vcpu with KVM_ARM_VCPU_INIT, however, this is
> > likely not possible for protected VMs.
> >
> > Adapted from commit 22f553842b14 ("KVM: arm64: Handle Asymmetric
> > AArch32 systems")
> >
> > Signed-off-by: Fuad Tabba <tabba at google.com>
> > ---
> >  arch/arm64/kvm/hyp/nvhe/switch.c | 37 ++++++++++++++++++++++++++++++++
> >  1 file changed, 37 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> > index 398e62098898..0c24b7f473bf 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> > @@ -20,6 +20,7 @@
> >  #include <asm/kprobes.h>
> >  #include <asm/kvm_asm.h>
> >  #include <asm/kvm_emulate.h>
> > +#include <asm/kvm_fixed_config.h>
> >  #include <asm/kvm_hyp.h>
> >  #include <asm/kvm_mmu.h>
> >  #include <asm/fpsimd.h>
> > @@ -195,6 +196,39 @@ exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
> >                 return NULL;
> >  }
> >
> > +/*
> > + * Some guests (e.g., protected VMs) might not be allowed to run in AArch32. The
> > + * check below is based on the one in kvm_arch_vcpu_ioctl_run().
> > + * The ARMv8 architecture does not give the hypervisor a mechanism to prevent a
> > + * guest from dropping to AArch32 EL0 if implemented by the CPU. If the
> > + * hypervisor spots a guest in such a state ensure it is handled, and don't
> > + * trust the host to spot or fix it.
> > + *
> > + * Returns true if the check passed and the guest run loop can continue, or
> > + * false if the guest should exit to the host.
> > + */
> > +static bool check_aarch32_guest(struct kvm_vcpu *vcpu, u64 *exit_code)
>
> This does a bit more than just check & return, so maybe call it
> handle_aarch32_guest()?
>
> > +{
> > +       if (kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)) &&
>
> maybe initialize a local with a hyp pointer to the kvm structure.

Will do.

> > +           vcpu_mode_is_32bit(vcpu) &&
> > +           FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0),
> > +                                        PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) <
> > +               ID_AA64PFR0_ELx_32BIT_64BIT) {
>
> It may be more readable to initialize a local variable with this
> feature check, i.e:
>
> bool aarch32_allowed = FIELD_GET(...) == ID_AA64PFR0_ELx_32BIT_64BIT;
>
> and then:
>
>   if (kvm_vm_is_protected(kvm) && vcpu_mode_is_32bit(vcpu) &&
> !aarch32_allowed) {

I agree.

Thanks,
/fuad

> > +               /*
> > +                * As we have caught the guest red-handed, decide that it isn't
> > +                * fit for purpose anymore by making the vcpu invalid. The VMM
> > +                * can try and fix it by re-initializing the vcpu with
> > +                * KVM_ARM_VCPU_INIT, however, this is likely not possible for
> > +                * protected VMs.
> > +                */
> > +               vcpu->arch.target = -1;
> > +               *exit_code = ARM_EXCEPTION_IL;
> > +               return false;
> > +       }
> > +
> > +       return true;
> > +}
> > +
> >  /* Switch to the guest for legacy non-VHE systems */
> >  int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
> >  {
> > @@ -255,6 +289,9 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
> >                 /* Jump in the fire! */
> >                 exit_code = __guest_enter(vcpu);
> >
> > +               if (unlikely(!check_aarch32_guest(vcpu, &exit_code)))
> > +                       break;
> > +
> >                 /* And we're baaack! */
> >         } while (fixup_guest_exit(vcpu, &exit_code));
> >
> > --
> > 2.33.0.rc1.237.g0d66db33f3-goog
> >


From valentin.schneider at arm.com  Mon Aug 23 03:38:58 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Mon, 23 Aug 2021 11:38:58 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87czq4qzd7.wl-maz@kernel.org>
References: <20210814194737.GA3951530@roeck-us.net>
 <87sfzb7jeo.mognet@arm.com> <87eeav19mc.wl-maz@kernel.org>
 <87k0kk7w0c.mognet@arm.com> <87czqasn9u.wl-maz@kernel.org>
 <878s0t6s7p.mognet@arm.com> <87czq4qzd7.wl-maz@kernel.org>
Message-ID: <875yvw78e5.mognet@arm.com>

On 23/08/21 10:33, Marc Zyngier wrote:
> On Sun, 22 Aug 2021 23:16:10 +0100,
> Valentin Schneider <valentin.schneider at arm.com> wrote:
>>
>> On 18/08/21 17:58, Marc Zyngier wrote:
>> > There is the bizarre case of drivers/gpio/gpio-thunderx.c that changes
>> > the irqchip flow to use either handle_fasteoi_ack_irq or
>> > handle_fasteoi_mask_irq, which won't play very nicely with this.
>> > Someone said Cavium?
>> >
>>
>> Humph...
>>
>> I'm not familiar at all with the gpiolib irqchips, but I was under the
>> impression those would involve chained IRQs (it does appear to be the case
>> for the pl061 GPIOs on a Juno). For those, the innermost desc would be handled
>> via chained_irq_{enter, exit}() [!!!], and the outermost one via whatever
>> flow was installed by the relevant driver.
>
> Not all of them are built like this. There is actually a bunch of
> these build as full hierarchies (QC, nvidia and some others).
>

I see, thanks!

>> I can't easily grok what goes on between that gpio-thunderx.c driver and
>> gpiolib, but since that GPIO chip has
>>
>>         .irq_eoi		= irq_chip_eoi_parent,
>>
>> and
>>
>>         girq->parent_domain =
>>                 irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;
>>
>> (GPIOs hooked to MSI-X? Do I want to know?)
>
> It's good, isn't it? TX1 has all its HW appearing as PCI, even if it
> clearly isn't PCI underneath.
>
>>
>> I'm guessing it is *not* chained, which means the irq_set_handler_locked()
>> affects the entire stack :/
>
> It does. We can probably fix that, but I won't be able to test (my TX1
> was taken away a few months ago...). I'll accept body donations, for
> scientific purposes.
>

Looks like there are still some over on s/packet/equinix/, so I should be
able to poke at one.


From lorenzo.pieralisi at arm.com  Mon Aug 23 03:46:18 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 23 Aug 2021 11:46:18 +0100
Subject: [PATCH RESEND v3] ACPI: Add memory semantics to acpi_os_map_memory()
In-Reply-To: <20210802152359.12623-1-lorenzo.pieralisi@arm.com>
References: <20210802152359.12623-1-lorenzo.pieralisi@arm.com>
Message-ID: <20210823104618.14552-1-lorenzo.pieralisi@arm.com>

The memory attributes attached to memory regions depend on architecture
specific mappings.

For some memory regions, the attributes specified by firmware (eg
uncached) are not sufficient to determine how a memory region should be
mapped by an OS (for instance a region that is define as uncached in
firmware can be mapped as Normal or Device memory on arm64) and
therefore the OS must be given control on how to map the region to match
the expected mapping behaviour (eg if a mapping is requested with memory
semantics, it must allow unaligned accesses).

Rework acpi_os_map_memory() and acpi_os_ioremap() back-end to split
them into two separate code paths:

acpi_os_memmap() -> memory semantics
acpi_os_ioremap() -> MMIO semantics

The split allows the architectural implementation back-ends to detect
the default memory attributes required by the mapping in question
(ie the mapping API defines the semantics memory vs MMIO) and map the
memory accordingly.

Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702 at arm.com
Tested-by: Hanjun Guo <guohanjun at huawei.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Will Deacon <will at kernel.org>
Cc: Hanjun Guo <guohanjun at huawei.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
---
Resending with all lists CC'ed.

Patch series is a v3 of a previous version[2]:

v2->v3:
	- Dropped first two-patches following LKML feedback[2]
v1->v2
	- Added patch 1 and 2 according to feedback received on[1]

[1] https://lore.kernel.org/linux-acpi/20210726100026.12538-1-lorenzo.pieralisi at arm.com
[2] https://lore.kernel.org/linux-acpi/20210802152359.12623-1-lorenzo.pieralisi at arm.com

 arch/arm64/include/asm/acpi.h |  3 +++
 arch/arm64/kernel/acpi.c      | 19 ++++++++++++++++---
 drivers/acpi/osl.c            | 23 ++++++++++++++++-------
 include/acpi/acpi_io.h        |  8 ++++++++
 4 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index bd68e1b7f29f..7535dc7cc5aa 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -50,6 +50,9 @@ pgprot_t __acpi_get_mem_attribute(phys_addr_t addr);
 void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size);
 #define acpi_os_ioremap acpi_os_ioremap
 
+void __iomem *acpi_os_memmap(acpi_physical_address phys, acpi_size size);
+#define acpi_os_memmap acpi_os_memmap
+
 typedef u64 phys_cpuid_t;
 #define PHYS_CPUID_INVALID INVALID_HWID
 
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index f3851724fe35..1c9c2f7a1c04 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -273,7 +273,8 @@ pgprot_t __acpi_get_mem_attribute(phys_addr_t addr)
 	return __pgprot(PROT_DEVICE_nGnRnE);
 }
 
-void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+static void __iomem *__acpi_os_ioremap(acpi_physical_address phys,
+				       acpi_size size, bool memory)
 {
 	efi_memory_desc_t *md, *region = NULL;
 	pgprot_t prot;
@@ -299,9 +300,11 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
 	 * It is fine for AML to remap regions that are not represented in the
 	 * EFI memory map at all, as it only describes normal memory, and MMIO
 	 * regions that require a virtual mapping to make them accessible to
-	 * the EFI runtime services.
+	 * the EFI runtime services. Determine the region default
+	 * attributes by checking the requested memory semantics.
 	 */
-	prot = __pgprot(PROT_DEVICE_nGnRnE);
+	prot = memory ? __pgprot(PROT_NORMAL_NC) :
+			__pgprot(PROT_DEVICE_nGnRnE);
 	if (region) {
 		switch (region->type) {
 		case EFI_LOADER_CODE:
@@ -361,6 +364,16 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
 	return __ioremap(phys, size, prot);
 }
 
+void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+{
+	return __acpi_os_ioremap(phys, size, false);
+}
+
+void __iomem *acpi_os_memmap(acpi_physical_address phys, acpi_size size)
+{
+	return __acpi_os_ioremap(phys, size, true);
+}
+
 /*
  * Claim Synchronous External Aborts as a firmware first notification.
  *
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 45c5c0e45e33..a43f1521efe6 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -284,7 +284,8 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
 #define should_use_kmap(pfn)   page_is_ram(pfn)
 #endif
 
-static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
+static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz,
+			      bool memory)
 {
 	unsigned long pfn;
 
@@ -294,7 +295,8 @@ static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
 			return NULL;
 		return (void __iomem __force *)kmap(pfn_to_page(pfn));
 	} else
-		return acpi_os_ioremap(pg_off, pg_sz);
+		return memory ? acpi_os_memmap(pg_off, pg_sz) :
+				acpi_os_ioremap(pg_off, pg_sz);
 }
 
 static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
@@ -309,9 +311,10 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
 }
 
 /**
- * acpi_os_map_iomem - Get a virtual address for a given physical address range.
+ * __acpi_os_map_iomem - Get a virtual address for a given physical address range.
  * @phys: Start of the physical address range to map.
  * @size: Size of the physical address range to map.
+ * @memory: true if remapping memory, false if IO
  *
  * Look up the given physical address range in the list of existing ACPI memory
  * mappings.  If found, get a reference to it and return a pointer to it (its
@@ -321,8 +324,8 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
  * During early init (when acpi_permanent_mmap has not been set yet) this
  * routine simply calls __acpi_map_table() to get the job done.
  */
-void __iomem __ref
-*acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
+static void __iomem __ref
+*__acpi_os_map_iomem(acpi_physical_address phys, acpi_size size, bool memory)
 {
 	struct acpi_ioremap *map;
 	void __iomem *virt;
@@ -353,7 +356,7 @@ void __iomem __ref
 
 	pg_off = round_down(phys, PAGE_SIZE);
 	pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
-	virt = acpi_map(phys, size);
+	virt = acpi_map(phys, size, memory);
 	if (!virt) {
 		mutex_unlock(&acpi_ioremap_lock);
 		kfree(map);
@@ -372,11 +375,17 @@ void __iomem __ref
 	mutex_unlock(&acpi_ioremap_lock);
 	return map->virt + (phys - map->phys);
 }
+
+void __iomem *__ref
+acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
+{
+	return __acpi_os_map_iomem(phys, size, false);
+}
 EXPORT_SYMBOL_GPL(acpi_os_map_iomem);
 
 void *__ref acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
-	return (void *)acpi_os_map_iomem(phys, size);
+	return (void *)__acpi_os_map_iomem(phys, size, true);
 }
 EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
index 027faa8883aa..a0212e67d6f4 100644
--- a/include/acpi/acpi_io.h
+++ b/include/acpi/acpi_io.h
@@ -14,6 +14,14 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
 }
 #endif
 
+#ifndef acpi_os_memmap
+static inline void __iomem *acpi_os_memmap(acpi_physical_address phys,
+					    acpi_size size)
+{
+	return ioremap_cache(phys, size);
+}
+#endif
+
 extern bool acpi_permanent_mmap;
 
 void __iomem __ref
-- 
2.31.0



From sugar.zhang at rock-chips.com  Mon Aug 23 03:48:14 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Mon, 23 Aug 2021 18:48:14 +0800
Subject: [PATCH v1 0/15] Patches to update for rockchip i2s
Message-ID: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>

These patches fixup or update for rockchip i2s.


Sugar Zhang (13):
  ASoC: rockchip: i2s: Add support for set bclk ratio
  ASoC: rockchip: i2s: Fixup clk div error
  ASoC: rockchip: i2s: Improve dma data transfer efficiency
  ASoC: rockchip: i2s: Fix regmap_ops hang
  ASoC: rockchip: i2s: Fix concurrency between tx/rx
  ASoC: rockchip: i2s: Reset the controller if soft reset failed
  ASoC: dt-bindings: rockchip: Document reset property for i2s
  ASoC: rockchip: i2s: Add property to specify play/cap capability
  ASoC: dt-bindings: rockchip: i2s: Document property for
    playback/capture
  ASoC: rockchip: i2s: Add compatible for more SoCs
  ASoC: dt-bindings: rockchip: Add compatible strings for more SoCs
  ASoC: rockchip: i2s: Add support for frame inversion
  ASoC: dt-bindings: rockchip: i2s: Document property 'clk-trcm'

Xiaotan Luo (1):
  ASoC: rockchip: i2s: Fixup config for DAIFMT_DSP_A/B

Xing Zheng (1):
  ASoC: rockchip: i2s: Add support for 'rockchip,clk-trcm' property

 .../devicetree/bindings/sound/rockchip-i2s.yaml    |  30 ++++
 sound/soc/rockchip/rockchip_i2s.c                  | 153 ++++++++++++++++-----
 sound/soc/rockchip/rockchip_i2s.h                  |  10 +-
 3 files changed, 157 insertions(+), 36 deletions(-)

-- 
2.7.4





From sugar.zhang at rock-chips.com  Mon Aug 23 03:48:18 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Mon, 23 Aug 2021 18:48:18 +0800
Subject: [PATCH v1 04/15] ASoC: rockchip: i2s: Fix regmap_ops hang
In-Reply-To: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <1629715710-21137-5-git-send-email-sugar.zhang@rock-chips.com>

API 'set_fmt' maybe called when PD is off, in the situation,
any register access will hang the system. so, enable PD
before r/w register.

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

 sound/soc/rockchip/rockchip_i2s.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 2e0047d..90877e8 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -187,7 +187,9 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 {
 	struct rk_i2s_dev *i2s = to_info(cpu_dai);
 	unsigned int mask = 0, val = 0;
+	int ret = 0;
 
+	pm_runtime_get_sync(cpu_dai->dev);
 	mask = I2S_CKR_MSS_MASK;
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
@@ -200,7 +202,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 		i2s->is_master_mode = false;
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_pm_put;
 	}
 
 	regmap_update_bits(i2s->regmap, I2S_CKR, mask, val);
@@ -214,7 +217,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 		val = I2S_CKR_CKP_POS;
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_pm_put;
 	}
 
 	regmap_update_bits(i2s->regmap, I2S_CKR, mask, val);
@@ -237,7 +241,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 		val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_pm_put;
 	}
 
 	regmap_update_bits(i2s->regmap, I2S_TXCR, mask, val);
@@ -260,12 +265,16 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 		val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_pm_put;
 	}
 
 	regmap_update_bits(i2s->regmap, I2S_RXCR, mask, val);
 
-	return 0;
+err_pm_put:
+	pm_runtime_put(cpu_dai->dev);
+
+	return ret;
 }
 
 static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
-- 
2.7.4





From sugar.zhang at rock-chips.com  Mon Aug 23 03:48:16 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Mon, 23 Aug 2021 18:48:16 +0800
Subject: [PATCH v1 02/15] ASoC: rockchip: i2s: Fixup clk div error
In-Reply-To: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <1629715710-21137-3-git-send-email-sugar.zhang@rock-chips.com>

MCLK maybe not precise as required because of PLL,
but which still can be used and no side effect. so,
using DIV_ROUND_CLOSEST instead div.

e.g.

set mclk to 11289600 Hz, but get 11289598 Hz.

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

 sound/soc/rockchip/rockchip_i2s.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index c9d5c52..05fce2c 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -280,10 +280,10 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
 	if (i2s->is_master_mode) {
 		mclk_rate = clk_get_rate(i2s->mclk);
 		bclk_rate = i2s->bclk_ratio * params_rate(params);
-		if (bclk_rate == 0 || mclk_rate % bclk_rate)
+		if (!bclk_rate)
 			return -EINVAL;
 
-		div_bclk = mclk_rate / bclk_rate;
+		div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
 		div_lrck = bclk_rate / params_rate(params);
 		regmap_update_bits(i2s->regmap, I2S_CKR,
 				   I2S_CKR_MDIV_MASK,
-- 
2.7.4





From sugar.zhang at rock-chips.com  Mon Aug 23 03:48:17 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Mon, 23 Aug 2021 18:48:17 +0800
Subject: [PATCH v1 03/15] ASoC: rockchip: i2s: Improve dma data transfer
 efficiency
In-Reply-To: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <1629715710-21137-4-git-send-email-sugar.zhang@rock-chips.com>

This patch changes dma data burst from 4 to 8 to improve
data transfer efficiency.

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

 sound/soc/rockchip/rockchip_i2s.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 05fce2c..2e0047d 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -644,11 +644,11 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
 
 	i2s->playback_dma_data.addr = res->start + I2S_TXDR;
 	i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	i2s->playback_dma_data.maxburst = 4;
+	i2s->playback_dma_data.maxburst = 8;
 
 	i2s->capture_dma_data.addr = res->start + I2S_RXDR;
 	i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	i2s->capture_dma_data.maxburst = 4;
+	i2s->capture_dma_data.maxburst = 8;
 
 	i2s->bclk_ratio = 64;
 
-- 
2.7.4





From sugar.zhang at rock-chips.com  Mon Aug 23 03:48:15 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Mon, 23 Aug 2021 18:48:15 +0800
Subject: [PATCH v1 01/15] ASoC: rockchip: i2s: Add support for set bclk ratio
In-Reply-To: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629715710-21137-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <1629715710-21137-2-git-send-email-sugar.zhang@rock-chips.com>

This patch adds support for set bclk ratio from machine driver.

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

 sound/soc/rockchip/rockchip_i2s.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index c7dc350..c9d5c52 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -49,6 +49,7 @@ struct rk_i2s_dev {
 	bool rx_start;
 	bool is_master_mode;
 	const struct rk_i2s_pins *pins;
+	unsigned int bclk_ratio;
 };
 
 static int i2s_runtime_suspend(struct device *dev)
@@ -278,7 +279,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
 
 	if (i2s->is_master_mode) {
 		mclk_rate = clk_get_rate(i2s->mclk);
-		bclk_rate = 2 * 32 * params_rate(params);
+		bclk_rate = i2s->bclk_ratio * params_rate(params);
 		if (bclk_rate == 0 || mclk_rate % bclk_rate)
 			return -EINVAL;
 
@@ -413,6 +414,16 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream,
 	return ret;
 }
 
+static int rockchip_i2s_set_bclk_ratio(struct snd_soc_dai *dai,
+				       unsigned int ratio)
+{
+	struct rk_i2s_dev *i2s = to_info(dai);
+
+	i2s->bclk_ratio = ratio;
+
+	return 0;
+}
+
 static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
 				   unsigned int freq, int dir)
 {
@@ -441,6 +452,7 @@ static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai)
 
 static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
 	.hw_params = rockchip_i2s_hw_params,
+	.set_bclk_ratio	= rockchip_i2s_set_bclk_ratio,
 	.set_sysclk = rockchip_i2s_set_sysclk,
 	.set_fmt = rockchip_i2s_set_fmt,
 	.trigger = rockchip_i2s_trigger,
@@ -638,6 +650,8 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
 	i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	i2s->capture_dma_data.maxburst = 4;
 
+	i2s->bclk_ratio = 64;
+
 	dev_set_drvdata(&pdev->dev, i2s);
 
 	pm_runtime_enable(&pdev->dev);
-- 
2.7.4





From p.zabel at pengutronix.de  Mon Aug 23 03:56:23 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Mon, 23 Aug 2021 12:56:23 +0200
Subject: [PATCH] reset: reset-zynqmp: Fixed the argument data type
In-Reply-To: <925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek@xilinx.com>
References: <925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek@xilinx.com>
Message-ID: <8c6674e387615b49bf2aa3304bd49c0e99e37094.camel@pengutronix.de>

Hi Michal,

On Wed, 2021-06-23 at 13:46 +0200, Michal Simek wrote:
> From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> 
> This patch changes the data type of the variable 'val' from
> int to u32.
> 
> Addresses-Coverity: argument of type "int *" is incompatible with parameter of type "u32 *"
> Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
> 
>  drivers/reset/reset-zynqmp.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
> index daa425e74c96..59dc0ff9af9e 100644
> --- a/drivers/reset/reset-zynqmp.c
> +++ b/drivers/reset/reset-zynqmp.c
> @@ -53,7 +53,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
>  			       unsigned long id)
>  {
>  	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
> -	int val, err;
> +	int err;
> +	u32 val;
>  
>  	err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val);
>  	if (err)

Thank you, applied to reset/fixes.

regards
Philipp


From wangkefeng.wang at huawei.com  Mon Aug 23 03:57:40 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 23 Aug 2021 18:57:40 +0800
Subject: [PATCH 0/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <20210823090508.GO22278@shell.armlinux.org.uk>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <YRw32YE4cnNnWSvl@robh.at.kernel.org>
 <b5ccbf00-b686-d35b-c81a-0ec69f4677a0@huawei.com>
 <20210823090508.GO22278@shell.armlinux.org.uk>
Message-ID: <d0d1c3d2-bbb6-426a-0512-52d37150e981@huawei.com>


On 2021/8/23 17:05, Russell King (Oracle) wrote:
> On Mon, Aug 23, 2021 at 10:19:23AM +0800, Kefeng Wang wrote:
>> On 2021/8/18 6:27, Rob Herring wrote:
>>> On Mon, Aug 16, 2021 at 03:46:16PM +0800, Kefeng Wang wrote:
>>>> Patch 1 and 2 make some cleanup, and patch 3 use of_irq_get() instead of
>>>> irq_of_parse_and_map() to get irq number, return -EPROBE_DEFER if the irq
>>>> domain is not yet created, amba_device_add() will properly to handle the
>>>> no IRQ domain issue via deferred probe.
>>>>
>>>> Kefeng Wang (3):
>>>>     amba: Drop unused functions about APB/AHB devices add
>>>>     Revert "ARM: amba: make use of -1 IRQs warn"
>>>>     amba: Properly handle device probe without IRQ domain
>>>>
>>>>    drivers/amba/bus.c       | 100 ++++++++++-----------------------------
>>>>    drivers/of/platform.c    |   6 +--
>>>>    include/linux/amba/bus.h |  18 -------
>>>>    3 files changed, 27 insertions(+), 97 deletions(-)
>>> Reviewed-by: Rob Herring <robh at kernel.org>
>> Thanks Rob.
>>
>> Hi Russell, should I send the patches to the ARM patch system?
> Yes please - I'll try to squeeze it in for this cycle but it's getting
> a tad late for that. Thanks.

Done, but the sequence of patches is reordered at ARM patch system, 
(using git send-email

and deliver patch1/2/3 in order).

BTW,? could you give me some direction the following patchset[1] too if 
you have time, I have

addressed your comments and resend, but there's been no new feedback for 
a long time.

If it is too late for this cycle, I could resend them after 5.15-rc1.

Many thanks.

[1] 
https://lore.kernel.org/linux-arm-kernel/20210610123556.171328-1-wangkefeng.wang at huawei.com/



>


From james.clark at arm.com  Mon Aug 23 03:57:52 2021
From: james.clark at arm.com (James Clark)
Date: Mon, 23 Aug 2021 11:57:52 +0100
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210823095155.GC100516@leoy-ThinkPad-X240s>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-3-leo.yan@linaro.org>
 <2b4e0c07-a8df-cca6-6a94-328560f4b0c6@arm.com>
 <20210823095155.GC100516@leoy-ThinkPad-X240s>
Message-ID: <319ee11a-06f7-abde-6495-d2175928b9fe@arm.com>



On 23/08/2021 10:51, Leo Yan wrote:
> Hi James,
> 
> On Fri, Aug 13, 2021 at 05:22:31PM +0100, James Clark wrote:
>> On 09/08/2021 12:27, Leo Yan wrote:
>>> +/*
>>> + * In the compat mode kernel runs in 64-bit and perf tool runs in 32-bit mode,
>>> + * 32-bit perf tool cannot access 64-bit value atomically, which might lead to
>>> + * the issues caused by the below sequence on multiple CPUs: when perf tool
>>> + * accesses either the load operation or the store operation for 64-bit value,
>>> + * on some architectures the operation is divided into two instructions, one
>>> + * is for accessing the low 32-bit value and another is for the high 32-bit;
>>> + * thus these two user operations can give the kernel chances to access the
>>> + * 64-bit value, and thus leads to the unexpected load values.
>>> + *
>>> + *   kernel (64-bit)                        user (32-bit)
>>> + *
>>> + *   if (LOAD ->aux_tail) { --,             LOAD ->aux_head_lo
>>> + *       STORE $aux_data      |       ,--->
>>> + *       FLUSH $aux_data      |       |     LOAD ->aux_head_hi
>>> + *       STORE ->aux_head   --|-------`     smp_rmb()
>>> + *   }                        |             LOAD $data
>>> + *                            |             smp_mb()
>>> + *                            |             STORE ->aux_tail_lo
>>> + *                            `----------->
>>> + *                                          STORE ->aux_tail_hi
>>> + *
>>> + * For this reason, it's impossible for the perf tool to work correctly when
>>> + * the AUX head or tail is bigger than 4GB (more than 32 bits length); and we
>>> + * can not simply limit the AUX ring buffer to less than 4GB, the reason is
>>> + * the pointers can be increased monotonically, whatever the buffer size it is,
>>> + * at the end the head and tail can be bigger than 4GB and carry out to the
>>> + * high 32-bit.
>>> + *
>>> + * To mitigate the issues and improve the user experience, we can allow the
>>> + * perf tool working in certain conditions and bail out with error if detect
>>> + * any overflow cannot be handled.
>>> + *
>>> + * For reading the AUX head, it reads out the values for three times, and
>>> + * compares the high 4 bytes of the values between the first time and the last
>>> + * time, if there has no change for high 4 bytes injected by the kernel during
>>> + * the user reading sequence, it's safe for use the second value.
>>> + *
>>> + * When update the AUX tail and detects any carrying in the high 32 bits, it
>>> + * means there have two store operations in user space and it cannot promise
>>> + * the atomicity for 64-bit write, so return '-1' in this case to tell the
>>> + * caller an overflow error has happened.
>>> + */
>>> +u64 __weak compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
>>> +{
>>> +	struct perf_event_mmap_page *pc = mm->userpg;
>>> +	u64 first, second, last;
>>> +	u64 mask = (u64)(UINT32_MAX) << 32;
>>> +
>>> +	do {
>>> +		first = READ_ONCE(pc->aux_head);
>>> +		/* Ensure all reads are done after we read the head */
>>> +		smp_rmb();
>>> +		second = READ_ONCE(pc->aux_head);
>>> +		/* Ensure all reads are done after we read the head */
>>> +		smp_rmb();
>>> +		last = READ_ONCE(pc->aux_head);
>>> +	} while ((first & mask) != (last & mask));
>>> +
>>> +	return second;
>>> +}
>>> +
>>
>> Hi Leo,
>>
>> I had a couple of questions about this bit. If we're assuming that the
>> high bytes of 'first' and 'last' are equal, then 'second' is supposed
>> to be somewhere in between or equal to 'first' and 'last'.
>>
>> If that's the case, wouldn't it be better to return 'last', because it's
>> closer to the value at the time of reading?
> 
>> And then in that case, if last is returned, then why do a read for
>> 'second' at all? Can 'second' be skipped and just read first and last?
> 
> Simply to say, the logic can be depicted as:
> 
>   step 1: read 'first'
>   step 2: read 'second' -> There have no any atomicity risk if 'first'
>                            is same with 'last'
>   step 3: read 'last'
> 
> The key point is if the 'first' and 'last' have the same value in the
> high word, there have no any increment for high word in the middle of
> 'first' and 'last', so we don't worry about the atomicity for 'second'.
> 
> But we cannot promise the atomicity for reading 'last', let's see
> below sequence:
> 
>              CPU(a)                                 CPU(b)
>   step 1: read 'first' (high word)
>           read 'first' (low word)
>   step 2: read 'second' (high word)
>           read 'second' (low word)
>   step 3: read 'last' (high word)
>                                        --> write 'last' (high word)
>                                        --> write 'last' (low word)
>           read 'last' (low word)
> 
> 
> Even 'first' and 'last' have the same high word, but the 'last' cannot
> be trusted.
> 
>> Also maybe it won't make a difference, but is there a missing smp_rmb()
>> between the read of 'last' and 'first'?
> 
> Good question, from my understanding, we only need to promise the flow
> from step 1 to step 3, it's not necessary to add barrier in the middle
> of the two continuous loops.
> 
> Thanks for reviewing!
> 

Ok thanks for the explanation, that makes sense now. I do have one other
point about the documentation for the function:

> + * When update the AUX tail and detects any carrying in the high 32 bits, it
> + * means there have two store operations in user space and it cannot promise
> + * the atomicity for 64-bit write, so return '-1' in this case to tell the
> + * caller an overflow error has happened.
> + */

I couldn't see how it can ever return -1, it seems like it would loop forever
until it reads the correct value.


> Leo
> 


From patchwork-bot+netdevbpf at kernel.org  Mon Aug 23 04:00:05 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Mon, 23 Aug 2021 11:00:05 +0000
Subject: [PATCH net] net: stmmac: fix kernel panic due to NULL pointer
 dereference of plat->est
In-Reply-To: <20210820132622.4175839-1-vee.khee.wong@linux.intel.com>
References: <20210820132622.4175839-1-vee.khee.wong@linux.intel.com>
Message-ID: <162971640578.3591.684307191157307528.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (refs/heads/master):

On Fri, 20 Aug 2021 21:26:22 +0800 you wrote:
> In the case of taprio offload is not enabled, the error handling path
> causes a kernel crash due to kernel NULL pointer deference.
> 
> Fix this by adding check for NULL before attempt to access 'plat->est'
> on the mutex_lock() call.
> 
> The following kernel panic is observed without this patch:
> 
> [...]

Here is the summary with links:
  - [net] net: stmmac: fix kernel panic due to NULL pointer dereference of plat->est
    https://git.kernel.org/netdev/net/c/82a44ae113b7

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From michael.riesch at wolfvision.net  Mon Aug 23 04:07:16 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 23 Aug 2021 13:07:16 +0200
Subject: [PATCH] arm64: dts: rockchip: add saradc to rk3568-evb1-v10
Message-ID: <20210823110716.10038-1-michael.riesch@wolfvision.net>

Add the SARADC to the device tree of the RK3568 EVB1.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 1bc79e95b2fb..184e2aa2416a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -360,6 +360,11 @@
 	status = "okay";
 };
 
+&saradc {
+	vref-supply = <&vcca_1v8>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	max-frequency = <200000000>;
-- 
2.17.1



From wenst at chromium.org  Mon Aug 23 04:16:56 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 19:16:56 +0800
Subject: [v2 07/24] clk: mediatek: Add MT8195 topckgen clock support
In-Reply-To: <20210820111504.350-8-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-8-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5GaUBWV0tD4uP6Gx6Pg7BvF_Dzp5pdV73b_0MD1kYr03A@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:20 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 topckgen clock controller which provides muxes, dividers
> to handle variety clock selection in other IP blocks.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
> The changes as follow:
> 1. remove 1 on 1 divider
> 2. merge parent source data in muxes
> 3. add some comment if the clock is not model by CCF or has special flag
> 4. remove _SEL suffix in clock name
> ---
>  drivers/clk/mediatek/Makefile              |    2 +-
>  drivers/clk/mediatek/clk-mt8195-topckgen.c | 1298 ++++++++++++++++++++
>  2 files changed, 1299 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-topckgen.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index d4157cfca865..a142342a0cea 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -80,6 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
> -obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o
> +obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o
>  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
>  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> diff --git a/drivers/clk/mediatek/clk-mt8195-topckgen.c b/drivers/clk/mediatek/clk-mt8195-topckgen.c
> new file mode 100644
> index 000000000000..3cf113544f59
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8195-topckgen.c
> @@ -0,0 +1,1298 @@

[...]

> +static const char * const dsp_parents[] = {
> +       "clk26m",
> +       "univpll_d6_d2",
> +       "univpll_d4_d2",
> +       "univpll_d5",
> +       "univpll_d4",
> +       "mmpll_d4",
> +       "mainpll_d3",
> +       "univpll_d3"
> +};
> +
> +static const char * const dsp1_parents[] = {
> +       "clk26m",
> +       "univpll_d6_d2",
> +       "mainpll_d4_d2",
> +       "univpll_d5",
> +       "mmpll_d5",
> +       "univpll_d4",
> +       "mainpll_d3",
> +       "univpll_d3"
> +};
> +
> +static const char * const dsp2_parents[] = {
> +       "clk26m",
> +       "univpll_d6_d2",
> +       "univpll_d4_d2",
> +       "mainpll_d4",
> +       "univpll_d4",
> +       "mmpll_d4",
> +       "mainpll_d3",
> +       "univpll_d3"
> +};
> +
> +static const char * const dsp3_parents[] = {
> +       "clk26m",
> +       "univpll_d6_d2",
> +       "univpll_d4_d2",
> +       "univpll_d5",
> +       "univpll_d4",
> +       "mmpll_d4",
> +       "mainpll_d3",
> +       "univpll_d3"
> +};

dsp3_parents looks like it matches dsp_parents. If so, please deduplicate.

[...]

> +static const struct mtk_mux top_mtk_muxes[] = {

[...]

> +       /* CLK_CFG_29 */
> +       MUX_GATE_CLR_SET_UPD(CLK_TOP_DVIO_DGI_REF, "top_dvio_dgi_ref",
> +               dvio_dgi_ref_parents, 0x017C, 0x0180, 0x0184, 0, 3, 7, 0x010, 20),
> +       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_ULPOSC, "top_ulposc",
> +               ulposc_parents, 0x017C, 0x0180, 0x0184, 8, 2, 15, 0x010, 21, CLK_IS_CRITICAL),
> +       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_ULPOSC_CORE, "top_ulposc_core",
> +               ulposc_core_parents, 0x017C, 0x0180, 0x0184, 16, 2, 23, 0x010, 22, CLK_IS_CRITICAL),
> +       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SRCK, "top_srck",
> +               srck_parents, 0x017C, 0x0180, 0x0184, 24, 1, 31, 0x010, 23, CLK_IS_CRITICAL),

Any comments regarding the three critical clocks?

> +       /*
> +        * the clocks in CLK_CFG_30 ~ 37 are backup clock source, no need to handled
> +        * by Linux.
> +        */
> +};
> +
> +static struct mtk_composite top_muxes[] = {
> +       /* CLK_MISC_CFG_3 */
> +       MUX(CLK_TOP_MFG_CK_FAST_REF, "mfg_ck_fast_ref", mfg_fast_parents, 0x0250, 8, 1),
> +};
> +
> +/*
> + * apll12_div5 ~ 9 are not used in MT8195.
> + */
> +static const struct mtk_composite top_adj_divs[] = {
> +       DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0", "top_i2si1_mck", 0x0320, 0, 0x0328, 8, 0),
> +       DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1", "top_i2si2_mck", 0x0320, 1, 0x0328, 8, 8),
> +       DIV_GATE(CLK_TOP_APLL12_DIV2, "apll12_div2", "top_i2so1_mck", 0x0320, 2, 0x0328, 8, 16),
> +       DIV_GATE(CLK_TOP_APLL12_DIV3, "apll12_div3", "top_i2so2_mck", 0x0320, 3, 0x0328, 8, 24),
> +       DIV_GATE(CLK_TOP_APLL12_DIV4, "apll12_div4", "top_aud_iec_clk", 0x0320, 4, 0x0334, 8, 0),

The comment could be inlined here directly:

          /* apll12_div5 ~ 9 are not used in MT8195 */

> +       DIV_GATE(CLK_TOP_APLL12_DIV9, "apll12_div9", "top_dptx_mck", 0x0320, 9, 0x0338, 8, 8),
> +};
> +
> +static const struct mtk_gate_regs top0_cg_regs = {
> +       .set_ofs = 0x238,
> +       .clr_ofs = 0x238,
> +       .sta_ofs = 0x238,
> +};
> +
> +static const struct mtk_gate_regs top1_cg_regs = {
> +       .set_ofs = 0x250,
> +       .clr_ofs = 0x250,
> +       .sta_ofs = 0x250,
> +};
> +
> +#define GATE_TOP0_FLAGS(_id, _name, _parent, _shift, _flag)            \
> +       GATE_MTK_FLAGS(_id, _name, _parent, &top0_cg_regs, _shift,      \
> +               &mtk_clk_gate_ops_no_setclr_inv, _flag)
> +
> +#define GATE_TOP0(_id, _name, _parent, _shift)                 \
> +       GATE_TOP0_FLAGS(_id, _name, _parent, _shift, 0)
> +
> +#define GATE_TOP1(_id, _name, _parent, _shift)                 \
> +       GATE_MTK(_id, _name, _parent, &top1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> +
> +/*
> + * cfg_axi_east, cfg_axi_east_north, cfg_axi_north and cfg_axi_south
> + * are peripheral bus clock branches.
> + */
> +static const struct mtk_gate top_clks[] = {
> +       /* TOP0 */
> +       GATE_TOP0(CLK_TOP_CFG_VPP0, "cfg_vpp0", "top_vpp", 0),
> +       GATE_TOP0(CLK_TOP_CFG_VPP1, "cfg_vpp1", "top_vpp", 1),
> +       GATE_TOP0(CLK_TOP_CFG_VDO0, "cfg_vdo0", "top_vpp", 2),
> +       GATE_TOP0(CLK_TOP_CFG_VDO1, "cfg_vdo1", "top_vpp", 3),
> +       GATE_TOP0(CLK_TOP_CFG_UNIPLL_SES, "cfg_unipll_ses", "univpll_d2", 4),
> +       GATE_TOP0(CLK_TOP_CFG_26M_VPP0, "cfg_26m_vpp0", "clk26m", 5),
> +       GATE_TOP0(CLK_TOP_CFG_26M_VPP1, "cfg_26m_vpp1", "clk26m", 6),
> +       GATE_TOP0(CLK_TOP_CFG_26M_AUD, "cfg_26m_aud", "clk26m", 9),
> +       GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_EAST, "cfg_axi_east", "top_axi", 10, CLK_IS_CRITICAL),
> +       GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_EAST_NORTH, "cfg_axi_east_north", "top_axi", 11,
> +               CLK_IS_CRITICAL),
> +       GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_NORTH, "cfg_axi_north", "top_axi", 12, CLK_IS_CRITICAL),
> +       GATE_TOP0_FLAGS(CLK_TOP_CFG_AXI_SOUTH, "cfg_axi_south", "top_axi", 13, CLK_IS_CRITICAL),
> +       GATE_TOP0(CLK_TOP_CFG_EXT_TEST, "cfg_ext_test", "msdcpll_d2", 15),
> +       /* TOP1 */
> +       GATE_TOP1(CLK_TOP_SSUSB_REF, "ssusb_ref", "clk26m", 0),
> +       GATE_TOP1(CLK_TOP_SSUSB_PHY_REF, "ssusb_phy_ref", "clk26m", 1),
> +       GATE_TOP1(CLK_TOP_SSUSB_P1_REF, "ssusb_p1_ref", "clk26m", 2),
> +       GATE_TOP1(CLK_TOP_SSUSB_PHY_P1_REF, "ssusb_phy_p1_ref", "clk26m", 3),
> +       GATE_TOP1(CLK_TOP_SSUSB_P2_REF, "ssusb_p2_ref", "clk26m", 4),
> +       GATE_TOP1(CLK_TOP_SSUSB_PHY_P2_REF, "ssusb_phy_p2_ref", "clk26m", 5),
> +       GATE_TOP1(CLK_TOP_SSUSB_P3_REF, "ssusb_p3_ref", "clk26m", 6),
> +       GATE_TOP1(CLK_TOP_SSUSB_PHY_P3_REF, "ssusb_phy_p3_ref", "clk26m", 7),
> +};
> +
> +static struct clk_onecell_data *top_clk_data;
> +
> +static void clk_mt8195_top_init_early(struct device_node *node)
> +{
> +       int i;
> +
> +       top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
> +       if (!top_clk_data)
> +               return;
> +
> +       for (i = 0; i < CLK_TOP_NR_CLK; i++)
> +               top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
> +
> +       mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);

It's still not clear to me why this is needed...

> +
> +       if (of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data)) {
> +               mtk_free_clk_data(top_clk_data);
> +               top_clk_data = NULL;
> +       }
> +}
> +
> +CLK_OF_DECLARE_DRIVER(mt8195_topckgen, "mediatek,mt8195-topckgen",
> +                       clk_mt8195_top_init_early);
> +
> +static const struct of_device_id of_match_clk_mt8195_topck[] = {
> +       { .compatible = "mediatek,mt8195-topckgen", },
> +       {}
> +};
> +
> +static int clk_mt8195_topck_probe(struct platform_device *pdev)
> +{
> +       struct device_node *node = pdev->dev.of_node;
> +       int r;
> +       void __iomem *base;
> +
> +       if (!top_clk_data)
> +               return -EFAULT;

-ENODEV is more appropriate. -EFAULT signals a bad address (access).

See include/uapi/asm-generic/errno-base.h

> +
> +       base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(base))
> +               return PTR_ERR(base);
> +
> +       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
> +                                       top_clk_data);
> +       mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);

And this second invocation will fail because the same clocks have already
been registered. It seems like this invocation is enough to have "clk26m_d2"
registered before all of its children.

If so then CLK_OF_DECLARE_DRIVER is not necessary, that part could be
dropped, and the clk_data initialization moved into this probe function.
And `top_early_divs` could be merged with `top_divs`.

> +       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
> +       mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
> +                                       &mt8195_clk_lock, top_clk_data);
> +       mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
> +                                       &mt8195_clk_lock, top_clk_data);
> +       mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
> +                                       &mt8195_clk_lock, top_clk_data);

Please align wrapped lines with the opening parenthesis.


Regards
ChenYu

> +       r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
> +       if (r)
> +               return r;
> +
> +       return of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
> +}
> +
> +static struct platform_driver clk_mt8195_topck_drv = {
> +       .probe = clk_mt8195_topck_probe,
> +       .driver = {
> +               .name = "clk-mt8195-topck",
> +               .of_match_table = of_match_clk_mt8195_topck,
> +       },
> +};
> +builtin_platform_driver(clk_mt8195_topck_drv);
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From hayashi.kunihiko at socionext.com  Mon Aug 23 04:18:20 2021
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Mon, 23 Aug 2021 20:18:20 +0900
Subject: [PATCH] PCI: uniphier: Serialize INTx masking/unmasking
Message-ID: <1629717500-19396-1-git-send-email-hayashi.kunihiko@socionext.com>

The condition register PCI_RCV_INTX is used in irq_mask(), irq_unmask()
and irq_ack() callbacks. Accesses to register can occur at the same time
without a lock.
Add a lock into each callback to prevent the issue.

Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
Suggested-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pci/controller/dwc/pcie-uniphier.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

The previous patch is as follows:
https://lore.kernel.org/linux-pci/1629370566-29984-1-git-send-email-hayashi.kunihiko at socionext.com/

Changes in the previous patch:
- Change the subject and commit message

diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index ebe43e9..5075714 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -186,12 +186,17 @@ static void uniphier_pcie_irq_ack(struct irq_data *d)
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+	unsigned long flags;
 	u32 val;
 
+	raw_spin_lock_irqsave(&pp->lock, flags);
+
 	val = readl(priv->base + PCL_RCV_INTX);
 	val &= ~PCL_RCV_INTX_ALL_STATUS;
 	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
+
+	raw_spin_unlock_irqrestore(&pp->lock, flags);
 }
 
 static void uniphier_pcie_irq_mask(struct irq_data *d)
@@ -199,12 +204,17 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+	unsigned long flags;
 	u32 val;
 
+	raw_spin_lock_irqsave(&pp->lock, flags);
+
 	val = readl(priv->base + PCL_RCV_INTX);
 	val &= ~PCL_RCV_INTX_ALL_MASK;
 	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
+
+	raw_spin_unlock_irqrestore(&pp->lock, flags);
 }
 
 static void uniphier_pcie_irq_unmask(struct irq_data *d)
@@ -212,12 +222,17 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+	unsigned long flags;
 	u32 val;
 
+	raw_spin_lock_irqsave(&pp->lock, flags);
+
 	val = readl(priv->base + PCL_RCV_INTX);
 	val &= ~PCL_RCV_INTX_ALL_MASK;
 	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
+
+	raw_spin_unlock_irqrestore(&pp->lock, flags);
 }
 
 static struct irq_chip uniphier_pcie_irq_chip = {
-- 
2.7.4



From broonie at kernel.org  Mon Aug 23 04:19:38 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 23 Aug 2021 12:19:38 +0100
Subject: [PATCH v2 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <3469189.PC3msRC2N5@archbook>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
 <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
 <66d6bd43-ee43-eff4-7a68-333fbb996787@linux.intel.com>
 <3469189.PC3msRC2N5@archbook>
Message-ID: <20210823111938.GC4380@sirena.org.uk>

On Sat, Aug 21, 2021 at 10:45:52PM +0200, Nicolas Frattaroli wrote:
> On Freitag, 20. August 2021 21:02:16 CEST Pierre-Louis Bossart wrote:
> > > +	regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
> > > +	/* Wait on the clear operation to finish */
> > > +	while (val) {

> > delay needed here?

> The rockchip_i2s.c code doesn't have a delay here either, but I can
> add one of 1 usec for good measure, it seems weird to retry the
> read as fast as it can.

You should probably have a cpu_relax() in there at least.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210823/a1909a74/attachment.sig>

From wenst at chromium.org  Mon Aug 23 04:22:39 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 19:22:39 +0800
Subject: [v2 08/24] clk: mediatek: Add MT8195 peripheral clock support
In-Reply-To: <20210820111504.350-9-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-9-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5GqELj5QEx7bCvyMkKdjG5jOFziefA4pHZGqiZgHR58BQ@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:20 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 peripheral clock controller which provides clock
> gate control for ethernet/flashif/pcie/ssusb.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile             |  2 +-
>  drivers/clk/mediatek/clk-mt8195-peri_ao.c | 62 +++++++++++++++++++++++
>  2 files changed, 63 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-peri_ao.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index a142342a0cea..d5ee396dcded 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -80,6 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
> -obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o
> +obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o

This line is getting too long. Please wrap it to within 100 characters.

Otherwise,

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From wenst at chromium.org  Mon Aug 23 04:32:57 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 19:32:57 +0800
Subject: [v2 09/24] clk: mediatek: Add MT8195 infrastructure clock support
In-Reply-To: <20210820111504.350-10-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-10-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5Hz0_LXz+k9dDgojUH79gzUYhXhWf275yU0hE1bzNNJOA@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:21 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 infrastructure clock controller which provides
> clock gate control for basic IP like pwm, uart, spi and so on.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile              |   2 +-
>  drivers/clk/mediatek/clk-mt8195-infra_ao.c | 211 +++++++++++++++++++++
>  2 files changed, 212 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-infra_ao.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index d5ee396dcded..c5a80645f10e 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -80,6 +80,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
> -obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o
> +obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o

Same thing about line width.

>  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
>  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> diff --git a/drivers/clk/mediatek/clk-mt8195-infra_ao.c b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
> new file mode 100644
> index 000000000000..a5794c65f743
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
> @@ -0,0 +1,211 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Copyright (c) 2021 MediaTek Inc.
> +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +
> +#include <dt-bindings/clock/mt8195-clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +static const struct mtk_gate_regs infra_ao0_cg_regs = {
> +       .set_ofs = 0x80,
> +       .clr_ofs = 0x84,
> +       .sta_ofs = 0x90,
> +};
> +
> +static const struct mtk_gate_regs infra_ao1_cg_regs = {
> +       .set_ofs = 0x88,
> +       .clr_ofs = 0x8c,
> +       .sta_ofs = 0x94,
> +};
> +
> +static const struct mtk_gate_regs infra_ao2_cg_regs = {
> +       .set_ofs = 0xa4,
> +       .clr_ofs = 0xa8,
> +       .sta_ofs = 0xac,
> +};
> +
> +static const struct mtk_gate_regs infra_ao3_cg_regs = {
> +       .set_ofs = 0xc0,
> +       .clr_ofs = 0xc4,
> +       .sta_ofs = 0xc8,
> +};
> +
> +static const struct mtk_gate_regs infra_ao4_cg_regs = {
> +       .set_ofs = 0xe0,
> +       .clr_ofs = 0xe4,
> +       .sta_ofs = 0xe8,
> +};
> +
> +#define GATE_INFRA_AO0_FLAGS(_id, _name, _parent, _shift, _flag)                \
> +       GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao0_cg_regs, _shift, \
> +               &mtk_clk_gate_ops_setclr, _flag)
> +
> +#define GATE_INFRA_AO0(_id, _name, _parent, _shift)    \
> +       GATE_INFRA_AO0_FLAGS(_id, _name, _parent, _shift, 0)
> +
> +#define GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, _flag)               \
> +       GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao1_cg_regs, _shift, \
> +               &mtk_clk_gate_ops_setclr, _flag)
> +
> +#define GATE_INFRA_AO1(_id, _name, _parent, _shift)    \
> +       GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, 0)
> +
> +#define GATE_INFRA_AO2(_id, _name, _parent, _shift)                    \
> +       GATE_MTK(_id, _name, _parent, &infra_ao2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
> +
> +#define GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, _flag)               \
> +       GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao3_cg_regs, _shift, \
> +               &mtk_clk_gate_ops_setclr, _flag)
> +
> +#define GATE_INFRA_AO3(_id, _name, _parent, _shift)    \
> +       GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, 0)
> +
> +#define GATE_INFRA_AO4_FLAGS(_id, _name, _parent, _shift, _flag)               \
> +       GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao4_cg_regs, _shift, \
> +               &mtk_clk_gate_ops_setclr, _flag)
> +
> +#define GATE_INFRA_AO4(_id, _name, _parent, _shift)    \
> +       GATE_INFRA_AO4_FLAGS(_id, _name, _parent, _shift, 0)
> +
> +/*
> + * infra_ao_sej is main clock is for secure engin with JTAG support.

                                                   ^ Typo?

> + * infra_133m_m_peri and infra_66m_m_peri are main clocks of peripheral.
> + * infra_device_apc and infra_device_apc_sync are for device access permission control module.

Since this is quite far from the clock definition, could you split this
comment and inline them before the actual definition instead? That would
make it easier to reference together.

> + */
> +static const struct mtk_gate infra_ao_clks[] = {
> +       /* INFRA_AO0 */
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_TMR, "infra_ao_pmic_tmr", "top_pwrap_ulposc", 0),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_AP, "infra_ao_pmic_ap", "top_pwrap_ulposc", 1),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_MD, "infra_ao_pmic_md", "top_pwrap_ulposc", 2),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_CONN, "infra_ao_pmic_conn", "top_pwrap_ulposc", 3),
> +       GATE_INFRA_AO0_FLAGS(CLK_INFRA_AO_SEJ, "infra_ao_sej", "top_axi", 5, CLK_IS_CRITICAL),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_APXGPT, "infra_ao_apxgpt", "top_axi", 6),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_GCE, "infra_ao_gce", "top_axi", 8),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_GCE2, "infra_ao_gce2", "top_axi", 9),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_THERM, "infra_ao_therm", "top_axi", 10),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PWM_H, "infra_ao_pwm_h", "top_axi", 15),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PWM1, "infra_ao_pwm1", "top_pwm", 16),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PWM2, "infra_ao_pwm2", "top_pwm", 17),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PWM3, "infra_ao_pwm3", "top_pwm", 18),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PWM4, "infra_ao_pwm4", "top_pwm", 19),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_PWM, "infra_ao_pwm", "top_pwm", 21),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_UART0, "infra_ao_uart0", "top_uart", 22),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_UART1, "infra_ao_uart1", "top_uart", 23),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_UART2, "infra_ao_uart2", "top_uart", 24),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_UART3, "infra_ao_uart3", "top_uart", 25),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_UART4, "infra_ao_uart4", "top_uart", 26),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_GCE_26M, "infra_ao_gce_26m", "clk26m", 27),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_CQ_DMA_FPC, "infra_ao_cq_dma_fpc", "fpc", 28),
> +       GATE_INFRA_AO0(CLK_INFRA_AO_UART5, "infra_ao_uart5", "top_uart", 29),
> +       /* INFRA_AO1 */
> +       GATE_INFRA_AO1(CLK_INFRA_AO_HDMI_26M, "infra_ao_hdmi_26m", "clk26m", 0),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_SPI0, "infra_ao_spi0", "top_spi", 1),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_MSDC0, "infra_ao_msdc0", "top_msdc50_0_hclk", 2),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_MSDC1, "infra_ao_msdc1", "top_axi", 4),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_CG1_MSDC2, "infra_ao_cg1_msdc2", "top_axi", 5),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_MSDC0_SRC, "infra_ao_msdc0_src", "top_msdc50_0", 6),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_TRNG, "infra_ao_trng", "top_axi", 9),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_AUXADC, "infra_ao_auxadc", "clk26m", 10),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_CPUM, "infra_ao_cpum", "top_axi", 11),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_HDMI_32K, "infra_ao_hdmi_32k", "clk32k", 12),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_CEC_66M_H, "infra_ao_cec_66m_h", "top_axi", 13),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_IRRX, "infra_ao_irrx", "top_axi", 14),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_PCIE_TL_26M, "infra_ao_pcie_tl_26m", "clk26m", 15),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_MSDC1_SRC, "infra_ao_msdc1_src", "top_msdc30_1", 16),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_CEC_66M_B, "infra_ao_cec_66m_b", "top_axi", 17),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_PCIE_TL_96M, "infra_ao_pcie_tl_96m", "top_tl", 18),
> +       GATE_INFRA_AO1_FLAGS(CLK_INFRA_AO_DEVICE_APC, "infra_ao_device_apc", "top_axi", 20,
> +               CLK_IS_CRITICAL),

Please align wrapped lines with opening parenthesis.

> +       GATE_INFRA_AO1(CLK_INFRA_AO_ECC_66M_H, "infra_ao_ecc_66m_h", "top_axi", 23),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_DEBUGSYS, "infra_ao_debugsys", "top_axi", 24),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_AUDIO, "infra_ao_audio", "top_axi", 25),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_PCIE_TL_32K, "infra_ao_pcie_tl_32k", "clk32k", 26),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_DBG_TRACE, "infra_ao_dbg_trace", "top_axi", 29),
> +       GATE_INFRA_AO1(CLK_INFRA_AO_DRAMC_F26M, "infra_ao_dramc_f26m", "clk26m", 31),
> +       /* INFRA_AO2 */
> +       GATE_INFRA_AO2(CLK_INFRA_AO_IRTX, "infra_ao_irtx", "top_axi", 0),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB, "infra_ao_ssusb", "top_usb_top", 1),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_DISP_PWM, "infra_ao_disp_pwm", "top_disp_pwm0", 2),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_CLDMA_B, "infra_ao_cldma_b", "top_axi", 3),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_AUDIO_26M_B, "infra_ao_audio_26m_b", "clk26m", 4),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_SPI1, "infra_ao_spi1", "top_spi", 6),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_SPI2, "infra_ao_spi2", "top_spi", 9),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_SPI3, "infra_ao_spi3", "top_spi", 10),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_SYS, "infra_ao_unipro_sys", "top_ufs", 11),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_TICK, "infra_ao_unipro_tick", "top_ufs_tick1us", 12),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_UFS_MP_SAP_B, "infra_ao_ufs_mp_sap_b", "top_ufs_mp_sap_cfg",
> +               13),

same here.

> +       GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU, "infra_ao_pwrmcu", "top_pwrmcu", 15),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU_BUS_H, "infra_ao_pwrmcu_bus_h", "top_axi", 17),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_APDMA_B, "infra_ao_apdma_b", "top_axi", 18),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_SPI4, "infra_ao_spi4", "top_spi", 25),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_SPI5, "infra_ao_spi5", "top_spi", 26),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_CQ_DMA, "infra_ao_cq_dma", "top_axi", 27),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_AES_UFSFDE, "infra_ao_aes_ufsfde", "top_ufs", 28),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_AES, "infra_ao_aes", "top_aes_ufsfde", 29),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_UFS_TICK, "infra_ao_ufs_tick", "top_ufs_tick1us", 30),
> +       GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_XHCI, "infra_ao_ssusb_xhci", "top_ssusb_xhci", 31),
> +       /* INFRA_AO3 */
> +       GATE_INFRA_AO3(CLK_INFRA_AO_MSDC0_SELF, "infra_ao_msdc0f", "top_msdc50_0", 0),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_MSDC1_SELF, "infra_ao_msdc1f", "top_msdc50_0", 1),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_MSDC2_SELF, "infra_ao_msdc2f", "top_msdc50_0", 2),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_I2S_DMA, "infra_ao_i2s_dma", "top_axi", 5),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_AP_MSDC0, "infra_ao_ap_msdc0", "top_msdc50_0", 7),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_MD_MSDC0, "infra_ao_md_msdc0", "top_msdc50_0", 8),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_CG3_MSDC2, "infra_ao_cg3_msdc2", "top_msdc30_2", 9),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_GCPU, "infra_ao_gcpu", "top_gcpu", 10),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_PCIE_PERI_26M, "infra_ao_pcie_peri_26m", "clk26m", 15),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_GCPU_66M_B, "infra_ao_gcpu_66m_b", "top_axi", 16),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_GCPU_133M_B, "infra_ao_gcpu_133m_b", "top_axi", 17),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_DISP_PWM1, "infra_ao_disp_pwm1", "top_disp_pwm1", 20),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_FBIST2FPC, "infra_ao_fbist2fpc", "top_msdc50_0", 24),
> +       GATE_INFRA_AO3_FLAGS(CLK_INFRA_AO_DEVICE_APC_SYNC, "infra_ao_device_apc_sync", "top_axi",
> +               25, CLK_IS_CRITICAL),

And here.

> +       GATE_INFRA_AO3(CLK_INFRA_AO_PCIE_P1_PERI_26M, "infra_ao_pcie_p1_peri_26m", "clk26m", 26),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_SPIS0, "infra_ao_spis0", "top_spis", 28),
> +       GATE_INFRA_AO3(CLK_INFRA_AO_SPIS1, "infra_ao_spis1", "top_spis", 29),
> +       /* INFRA_AO4 */
> +       GATE_INFRA_AO4_FLAGS(CLK_INFRA_AO_133M_M_PERI, "infra_ao_133m_m_peri", "top_axi", 0,
> +               CLK_IS_CRITICAL),
> +       GATE_INFRA_AO4_FLAGS(CLK_INFRA_AO_66M_M_PERI, "infra_ao_66m_m_peri", "top_spi", 1,
> +               CLK_IS_CRITICAL),
> +       GATE_INFRA_AO4(CLK_INFRA_AO_PCIE_PL_P_250M_P0, "infra_ao_pcie_pl_p_250m_p0", "pextp_pipe",
> +               7),

And these.

> +       GATE_INFRA_AO4(CLK_INFRA_AO_PCIE_PL_P_250M_P1, "infra_ao_pcie_pl_p_250m_p1",
> +               "ssusb_u3phy_p1_p_p0", 8),
> +       GATE_INFRA_AO4(CLK_INFRA_AO_PCIE_P1_TL_96M, "infra_ao_pcie_p1_tl_96m", "top_tl_p1", 17),
> +       GATE_INFRA_AO4(CLK_INFRA_AO_AES_MSDCFDE_0P, "infra_ao_aes_msdcfde_0p", "top_aes_msdcfde",
> +               18),

Ditto.

> +       GATE_INFRA_AO4(CLK_INFRA_AO_UFS_TX_SYMBOL, "infra_ao_ufs_tx_symbol", "ufs_tx_symbol", 22),
> +       GATE_INFRA_AO4(CLK_INFRA_AO_UFS_RX_SYMBOL, "infra_ao_ufs_rx_symbol", "ufs_rx_symbol", 23),
> +       GATE_INFRA_AO4(CLK_INFRA_AO_UFS_RX_SYMBOL1, "infra_ao_ufs_rx_symbol1", "ufs_rx_symbol1",
> +               24),

Ditto.

Since this is already going past 80 characters and close to 100, I would
just keep them on the same line. Having just one or two fields wrapped
on a few lines actually makes it harder to read. I would probably keep
the "CLK_INFRA_AO_DEVICE_APC_SYNC" line wrapped, since that line is way
longer.


Regards
ChenYu

> +       GATE_INFRA_AO4(CLK_INFRA_AO_PERI_UFS_MEM_SUB, "infra_ao_peri_ufs_mem_sub", "mem_466m", 31),
> +};
> +
> +static const struct mtk_clk_desc infra_ao_desc = {
> +       .clks = infra_ao_clks,
> +       .num_clks = ARRAY_SIZE(infra_ao_clks),
> +};
> +
> +static const struct of_device_id of_match_clk_mt8195_infra_ao[] = {
> +       {
> +               .compatible = "mediatek,mt8195-infracfg_ao",
> +               .data = &infra_ao_desc,
> +       }, {
> +               /* sentinel */
> +       }
> +};
> +
> +static struct platform_driver clk_mt8195_infra_ao_drv = {
> +       .probe = mtk_clk_simple_probe,
> +       .driver = {
> +               .name = "clk-mt8195-infra_ao",
> +               .of_match_table = of_match_clk_mt8195_infra_ao,
> +       },
> +};
> +builtin_platform_driver(clk_mt8195_infra_ao_drv);
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From michal.simek at xilinx.com  Mon Aug 23 04:33:47 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 23 Aug 2021 13:33:47 +0200
Subject: [PATCH] clk: zynqmp: Fix kernel-doc format
Message-ID: <26526e144296373b2c75e75865dd023158f9bfc7.1629718424.git.michal.simek@xilinx.com>

Align structure and function names with definitions.

Issues are reported by kernel-doc script as:
drivers/clk/zynqmp/clk-gate-zynqmp.c:24: warning: expecting prototype for
struct clk_gate. Prototype was for struct zynqmp_clk_gate instead
drivers/clk/zynqmp/clk-gate-zynqmp.c:75: warning: expecting prototype for
zynqmp_clk_gate_is_enable(). Prototype was for zynqmp_clk_gate_is_enabled()
instead

Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 drivers/clk/zynqmp/clk-gate-zynqmp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
index 695feaa82da5..565ed67a0430 100644
--- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
@@ -12,7 +12,7 @@
 #include "clk-zynqmp.h"
 
 /**
- * struct clk_gate - gating clock
+ * struct zynqmp_clk_gate - gating clock
  * @hw:		handle between common and hardware-specific interfaces
  * @flags:	hardware-specific flags
  * @clk_id:	Id of clock
@@ -66,7 +66,7 @@ static void zynqmp_clk_gate_disable(struct clk_hw *hw)
 }
 
 /**
- * zynqmp_clk_gate_is_enable() - Check clock state
+ * zynqmp_clk_gate_is_enabled() - Check clock state
  * @hw:		handle between common and hardware-specific interfaces
  *
  * Return: 1 if enabled, 0 if disabled else error code
-- 
2.33.0



From wenst at chromium.org  Mon Aug 23 05:02:32 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 20:02:32 +0800
Subject: [v2 14/24] clk: mediatek: Add MT8195 mfgcfg clock support
In-Reply-To: <20210820111504.350-15-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-15-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5H-NqZYeGUwsZQnu45DQLn=JX=4zrpuGHZ4ArC7p3Ks=Q@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:26 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 mfg clock controller which provides clock gate
> control for Main Frame Graphic.

I think it would be easier to understand if it just said GPU instead. Or
it could write:

     ... for Main Frame Graphic, aka integrated GPU.

Try to use more generic terms. The idea is for people with at least some
basic knowledge to be able to understand.

> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile         |  2 +-
>  drivers/clk/mediatek/clk-mt8195-mfg.c | 47 +++++++++++++++++++++++++++
>  2 files changed, 48 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-mfg.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 84d315a6b3e4..042db433245a 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -81,6 +81,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
> -                                       clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o
> +                                       clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o

Wrap line, please.


Regards
ChenYu


>  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
>  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> diff --git a/drivers/clk/mediatek/clk-mt8195-mfg.c b/drivers/clk/mediatek/clk-mt8195-mfg.c
> new file mode 100644
> index 000000000000..0a81fe1fe50e
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8195-mfg.c
> @@ -0,0 +1,47 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Copyright (c) 2021 MediaTek Inc.
> +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +
> +#include <dt-bindings/clock/mt8195-clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +static const struct mtk_gate_regs mfg_cg_regs = {
> +       .set_ofs = 0x4,
> +       .clr_ofs = 0x8,
> +       .sta_ofs = 0x0,
> +};
> +
> +#define GATE_MFG(_id, _name, _parent, _shift)                  \
> +       GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
> +
> +static const struct mtk_gate mfg_clks[] = {
> +       GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "top_mfg_core_tmp", 0),
> +};
> +
> +static const struct mtk_clk_desc mfg_desc = {
> +       .clks = mfg_clks,
> +       .num_clks = ARRAY_SIZE(mfg_clks),
> +};
> +
> +static const struct of_device_id of_match_clk_mt8195_mfg[] = {
> +       {
> +               .compatible = "mediatek,mt8195-mfgcfg",
> +               .data = &mfg_desc,
> +       }, {
> +               /* sentinel */
> +       }
> +};
> +
> +static struct platform_driver clk_mt8195_mfg_drv = {
> +       .probe = mtk_clk_simple_probe,
> +       .driver = {
> +               .name = "clk-mt8195-mfg",
> +               .of_match_table = of_match_clk_mt8195_mfg,
> +       },
> +};
> +builtin_platform_driver(clk_mt8195_mfg_drv);
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From p.zabel at pengutronix.de  Mon Aug 23 05:03:25 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Mon, 23 Aug 2021 14:03:25 +0200
Subject: [PATCH v2 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
 <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
Message-ID: <6bc6330215980f10853a2dac69f0bdfd9c8fb303.camel@pengutronix.de>

Hi Nicolas,

On Fri, 2021-08-20 at 20:27 +0200, Nicolas Frattaroli wrote:
[...]
> diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
> new file mode 100644
> index 000000000000..c02b66f3c913
> --- /dev/null
> +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
> @@ -0,0 +1,1737 @@
[...]
> +static void rockchip_snd_xfer_reset_assert(struct rk_i2s_tdm_dev *i2s_tdm,
> +					   int tx_bank, int tx_offset,
> +					   int rx_bank, int rx_offset)
> +{
> +	void __iomem *cru_reset;
> +	unsigned long flags;
> +
> +	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
> +
> +	if (tx_bank == rx_bank) {
> +		writel(BIT(tx_offset) | BIT(rx_offset) |
> +		       (BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
> +		       cru_reset + (tx_bank * 4));
> +	} else {
> +		local_irq_save(flags);
> +		writel(BIT(tx_offset) | (BIT(tx_offset) << 16),
> +		       cru_reset + (tx_bank * 4));
> +		writel(BIT(rx_offset) | (BIT(rx_offset) << 16),
> +		       cru_reset + (rx_bank * 4));
> +		local_irq_restore(flags);
> +	}
> +}
> +
> +static void rockchip_snd_xfer_reset_deassert(struct rk_i2s_tdm_dev *i2s_tdm,
> +					     int tx_bank, int tx_offset,
> +					     int rx_bank, int rx_offset)
> +{
> +	void __iomem *cru_reset;
> +	unsigned long flags;
> +
> +	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
> +
> +	if (tx_bank == rx_bank) {
> +		writel((BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
> +		       cru_reset + (tx_bank * 4));
> +	} else {
> +		local_irq_save(flags);
> +		writel((BIT(tx_offset) << 16),
> +		       cru_reset + (tx_bank * 4));
> +		writel((BIT(rx_offset) << 16),
> +		       cru_reset + (rx_bank * 4));
> +		local_irq_restore(flags);
> +	}
> +}
> +
> +/*
> + * Makes sure that both tx and rx are reset at the same time to sync lrck
> + * when clk_trcm > 0.
> + */
> +static void rockchip_snd_xfer_sync_reset(struct rk_i2s_tdm_dev *i2s_tdm)
> +{
> +	int tx_id, rx_id;
> +	int tx_bank, rx_bank, tx_offset, rx_offset;
> +
> +	if (!i2s_tdm->cru_base || !i2s_tdm->soc_data)
> +		return;
> +
> +	tx_id = i2s_tdm->tx_reset_id;
> +	rx_id = i2s_tdm->rx_reset_id;
> +	if (tx_id < 0 || rx_id < 0)
> +		return;
> +
> +	tx_bank = tx_id / 16;
> +	tx_offset = tx_id % 16;
> +	rx_bank = rx_id / 16;
> +	rx_offset = rx_id % 16;
> +	dev_dbg(i2s_tdm->dev,
> +		"tx_bank: %d, rx_bank: %d, tx_offset: %d, rx_offset: %d\n",
> +		tx_bank, rx_bank, tx_offset, rx_offset);
> +
> +	rockchip_snd_xfer_reset_assert(i2s_tdm, tx_bank, tx_offset,
> +				       rx_bank, rx_offset);
> +
> +	udelay(150);
> +
> +	rockchip_snd_xfer_reset_deassert(i2s_tdm, tx_bank, tx_offset,
> +					 rx_bank, rx_offset);
> +}

I'm not too fond of reimplementing half a reset controller in here.
The reset framework does not support synchronized (de)assertion of
multiple reset controls, I wonder if this would be useful to add.
Without having thought about this too hard, I could imagine this as an
extension to the bulk API, or possibly a call to join multiple reset
controls into a reset control array.

> +static void rockchip_snd_reset(struct reset_control *rc)
> +{
> +	if (IS_ERR(rc))
> +		return;

This shouldn't be called with an error code, see the comment about
optional reset controls below.

> +
> +	reset_control_assert(rc);
> +	udelay(1);

What is the reason for the different delays in
rockchip_snd_xfer_sync_reset() and rockchip_snd_reset()?

> +	reset_control_deassert(rc);
> +}
[...]
> +static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct device_node *cru_node;
> +	const struct of_device_id *of_id;
> +	struct rk_i2s_tdm_dev *i2s_tdm;
> +	struct resource *res;
> +	void __iomem *regs;
> +	int ret;
> +	int val;
> +
> +	i2s_tdm = devm_kzalloc(&pdev->dev, sizeof(*i2s_tdm), GFP_KERNEL);
> +	if (!i2s_tdm)
> +		return -ENOMEM;
> +
> +	i2s_tdm->dev = &pdev->dev;
> +
> +	of_id = of_match_device(rockchip_i2s_tdm_match, &pdev->dev);
> +	if (!of_id || !of_id->data)
> +		return -EINVAL;
> +
> +	spin_lock_init(&i2s_tdm->lock);
> +	i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data;
> +
> +	i2s_tdm->frame_width = 64;
> +	if (!of_property_read_u32(node, "rockchip,frame-width", &val)) {
> +		if (val >= 32 && (val % 2 == 0) && val <= 512) {
> +			i2s_tdm->frame_width = val;
> +		} else {
> +			dev_err(i2s_tdm->dev, "unsupported frame width: '%d'\n",
> +				val);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	i2s_tdm->clk_trcm = TRCM_TXRX;
> +	if (of_property_read_bool(node, "rockchip,trcm-sync-tx-only"))
> +		i2s_tdm->clk_trcm = TRCM_TX;
> +	if (of_property_read_bool(node, "rockchip,trcm-sync-rx-only")) {
> +		if (i2s_tdm->clk_trcm) {
> +			dev_err(i2s_tdm->dev, "invalid trcm-sync configuration\n");
> +			return -EINVAL;
> +		}
> +		i2s_tdm->clk_trcm = TRCM_RX;
> +	}
> +	if (i2s_tdm->clk_trcm != TRCM_TXRX)
> +		i2s_tdm_dai.symmetric_rate = 1;
> +
> +	i2s_tdm->tdm_fsync_half_frame =
> +		of_property_read_bool(node, "rockchip,tdm-fsync-half-frame");
> +
> +	i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
> +	if (IS_ERR(i2s_tdm->grf))
> +		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->grf),
> +				     "Error in rockchip,grf\n");
> +
> +	if (i2s_tdm->clk_trcm != TRCM_TXRX) {
> +		cru_node = of_parse_phandle(node, "rockchip,cru", 0);
> +		i2s_tdm->cru_base = of_iomap(cru_node, 0);

This is a bit ugly if there is another driver sitting on the
rockchip,cru compatible node. Which reset controller driver is backing
the reset controls below?

> +		of_node_put(cru_node);
> +		if (!i2s_tdm->cru_base) {
> +			dev_err(i2s_tdm->dev,
> +				"Missing or unsupported rockchip,cru node\n");
> +			return -ENOENT;
> +		}
> +
> +		i2s_tdm->tx_reset_id = of_i2s_resetid_get(node, "tx-m");
> +		i2s_tdm->rx_reset_id = of_i2s_resetid_get(node, "rx-m");
> +	}
> +
> +	i2s_tdm->tx_reset = devm_reset_control_get(&pdev->dev, "tx-m");

Please use devm_reset_control_get_exclusive() instead.

> +	if (IS_ERR(i2s_tdm->tx_reset)) {
> +		ret = PTR_ERR(i2s_tdm->tx_reset);
> +		if (ret != -ENOENT)
> +			return dev_err_probe(i2s_tdm->dev, ret,
> +					     "Error in tx-m reset control\n");
> +	}
> +
> +	i2s_tdm->rx_reset = devm_reset_control_get(&pdev->dev, "rx-m");
> +	if (IS_ERR(i2s_tdm->rx_reset)) {
> +		ret = PTR_ERR(i2s_tdm->rx_reset);
> +		if (ret != -ENOENT)

Why is -ENOENT acceptable? If you want these to be optional, use
devm_reset_control_get_optional_exclusive() [1] instead. That will
return NULL if the reset is not specified in the device tree, which will
be ignored by reset_control_(de)assert().

[1] https://www.kernel.org/doc/html/latest/driver-api/reset.html#c.devm_reset_control_get_optional_exclusive

> +			return dev_err_probe(i2s_tdm->dev, ret,
> +					     "Error in rx-m reset control\n");
> +	}
> +
> +	i2s_tdm->hclk = devm_clk_get(&pdev->dev, "hclk");
> +	if (IS_ERR(i2s_tdm->hclk)) {
> +		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->hclk),
> +				     "Failed to get clock hclk\n");
> +	}
> +
> +	ret = clk_prepare_enable(i2s_tdm->hclk);
> +	if (ret) {
> +		return dev_err_probe(i2s_tdm->dev, ret,
> +				     "Failed to enable clock hclk\n");
> +	}

This clock is left enabled in all the error paths below. You could
install a cleanup action with devm_add_action_or_reset(), or better
start enabling the hardware only after acquisition of all required
resources has succeeded.

[...]
> +static int rockchip_i2s_tdm_remove(struct platform_device *pdev)
> +{
> +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(&pdev->dev);
> +
> +	pm_runtime_disable(&pdev->dev);
> +	if (!pm_runtime_status_suspended(&pdev->dev))
> +		i2s_tdm_runtime_suspend(&pdev->dev);
> +
> +	if (!IS_ERR(i2s_tdm->mclk_tx))
> +		clk_prepare_enable(i2s_tdm->mclk_tx);
> +	if (!IS_ERR(i2s_tdm->mclk_rx))
> +		clk_prepare_enable(i2s_tdm->mclk_rx);

Why are we enabling these clocks now?

> +	if (!IS_ERR(i2s_tdm->hclk))
> +		clk_disable_unprepare(i2s_tdm->hclk);
> +
> +	return 0;
> +}

regards
Philipp


From rajan.vaja at xilinx.com  Mon Aug 23 05:07:13 2021
From: rajan.vaja at xilinx.com (Rajan Vaja)
Date: Mon, 23 Aug 2021 05:07:13 -0700
Subject: [PATCH v3] clk: zynqmp: fix kernel doc
In-Reply-To: <1629446294-1056-1-git-send-email-rajan.vaja@xilinx.com>
References: <1629446294-1056-1-git-send-email-rajan.vaja@xilinx.com>
Message-ID: <1629720433-19019-1-git-send-email-rajan.vaja@xilinx.com>

Add missing description of 'custom_type_flag' structure member.

Fixes: e605fa9c4a0c ("clk: zynqmp: Add support for custom type flags")

Signed-off-by: Rajan Vaja <rajan.vaja at xilinx.com>
---
Changes in v3:
 - Fixed typo in description of 'custom_type_flag' structure member.
Changes in v2:
 - Updated Fixes tag.
---
 drivers/clk/zynqmp/clk-zynqmp.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h
index 84fa80a..60cbc06 100644
--- a/drivers/clk/zynqmp/clk-zynqmp.h
+++ b/drivers/clk/zynqmp/clk-zynqmp.h
@@ -56,6 +56,7 @@ enum topology_type {
  * @type:	Type of topology
  * @flag:	Topology flags
  * @type_flag:	Topology type specific flag
+ * @custom_type_flag: Topology type specific custom flag
  */
 struct clock_topology {
 	u32 type;
-- 
2.7.4



From wenst at chromium.org  Mon Aug 23 05:08:05 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 20:08:05 +0800
Subject: [v2 15/24] clk: mediatek: Add MT8195 scp adsp clock support
In-Reply-To: <20210820111504.350-16-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-16-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5FcV0NrA+gES78jUSgWDt15q4h66=PkPGGT_85QOVMGqQ@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:27 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 scp adsp clock controller which provides clock gate
> control for Audio DSP.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile              |  2 +-
>  drivers/clk/mediatek/clk-mt8195-scp_adsp.c | 47 ++++++++++++++++++++++
>  2 files changed, 48 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-scp_adsp.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 042db433245a..472e5bc40fcb 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -81,6 +81,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
> -                                       clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o
> +                                       clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o

Wrap line, please.

Otherwise,

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From maz at kernel.org  Mon Aug 23 05:10:11 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 23 Aug 2021 13:10:11 +0100
Subject: [PATCH v4 11/15] KVM: arm64: Guest exit handlers for nVHE hyp
In-Reply-To: <CA+EHjTwyC-ZMpKQWGPqqYGHHR+YvyG3cdaxdwJfmYYf7XbBWEw@mail.gmail.com>
References: <20210817081134.2918285-1-tabba@google.com>
 <20210817081134.2918285-12-tabba@google.com>
 <87fsv6snup.wl-maz@kernel.org> <87zgtdqz77.wl-maz@kernel.org>
 <CA+EHjTwyC-ZMpKQWGPqqYGHHR+YvyG3cdaxdwJfmYYf7XbBWEw@mail.gmail.com>
Message-ID: <875yvwqs4c.wl-maz@kernel.org>

Hi Fuad,

On Mon, 23 Aug 2021 11:21:05 +0100,
Fuad Tabba <tabba at google.com> wrote:
> 
> Hi Marc,
> 
> On Thu, Aug 19, 2021 at 3:36 PM Marc Zyngier <maz at kernel.org> wrote:
> > I realised that I wasn't very forthcoming here. I've decided to put
> > the code where my mouth is and pushed out a branch [1] with your first
> > 10 patches, followed by my own take on this particular problem. It
> > compiles, and even managed to boot a Debian guest on a nVHE box.
> >
> > As you can see, most of the early exit handling is now moved to
> > specific handlers, unifying the handling. For the protected mode, you
> > can provide your own handler array (just hack
> > kvm_get_exit_handler_array() to return something else), which will do
> > the right thing as long as you call into the existing handlers first.
> > When it comes to the ELR/SPSR handling, it is better left to the
> > individual handlers (which we already do in some cases, see how we
> > skip instructions, for example).
> > Please let me know what you think.
> 
> Thanks a lot for this and sorry for being late to reply. I've been
> travelling.

No worries, it should be me who apologies for getting to this that late.

> I think that your proposal looks great. All handling is consolidated
> now and handling for protected VMs can just be added on top. There are
> some small issues with what parameters we need (e.g., passing struct
> kvm to kvm_get_exit_handler_array), but I will sort them out and
> submit them in the next round.

OK. Please base these changes on top of the three patches in my
branch, which I will update with actual commit messages.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From leo.yan at linaro.org  Mon Aug 23 05:13:48 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 23 Aug 2021 20:13:48 +0800
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <319ee11a-06f7-abde-6495-d2175928b9fe@arm.com>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-3-leo.yan@linaro.org>
 <2b4e0c07-a8df-cca6-6a94-328560f4b0c6@arm.com>
 <20210823095155.GC100516@leoy-ThinkPad-X240s>
 <319ee11a-06f7-abde-6495-d2175928b9fe@arm.com>
Message-ID: <20210823121348.GE100516@leoy-ThinkPad-X240s>

On Mon, Aug 23, 2021 at 11:57:52AM +0100, James Clark wrote:

[...]

> Ok thanks for the explanation, that makes sense now. I do have one other
> point about the documentation for the function:

Welcome!

> > + * When update the AUX tail and detects any carrying in the high 32 bits, it
> > + * means there have two store operations in user space and it cannot promise
> > + * the atomicity for 64-bit write, so return '-1' in this case to tell the
> > + * caller an overflow error has happened.
> > + */
> 
> I couldn't see how it can ever return -1, it seems like it would loop forever
> until it reads the correct value.

I use this chunk comment to address the function
compat_auxtrace_mmap__write_tail():

+int __weak compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+	u64 mask = (u64)(UINT32_MAX) << 32;
+
+	if (tail & mask)
+		return -1;
+
+	/* Ensure all reads are done before we write the tail out */
+	smp_mb();
+	WRITE_ONCE(pc->aux_tail, tail);
+	return 0;
+}

Please let me know if this is okay or not?  Otherwise, if you think
the format can cause confusion, I'd like to split the comments into
two sections, one section for reading AUX head and another is for
writing AUX tail.

Thanks,
Leo


From wenst at chromium.org  Mon Aug 23 05:13:56 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 20:13:56 +0800
Subject: [v2 11/24] clk: mediatek: Add MT8195 ccusys clock support
In-Reply-To: <20210820111504.350-12-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-12-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5EMoZq8BohUA_OoChmEdHL988pphxUJX077hO88htRUtA@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:23 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 ccusys clock controller which provides clock gate
> control in Camera Computing Unit.

Could you offer a bit more explanation about this unit? Is it an ISP?
Or some other function that does computation on images?

> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/clk/mediatek/Makefile         |  3 +-
>  drivers/clk/mediatek/clk-mt8195-ccu.c | 50 +++++++++++++++++++++++++++
>  2 files changed, 52 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-ccu.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 718bbb04191b..03fb020834f3 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -80,6 +80,7 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
> -obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o
> +obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
> +                                       clk-mt8195-ccu.o

When wrapping, please align with previous line. "clk-mt8195-ccu.o" should
align with "clk-mt8195-apmixedsys.o".


ChenYu


From maz at kernel.org  Mon Aug 23 05:17:03 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 23 Aug 2021 13:17:03 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <875yvw78e5.mognet@arm.com>
References: <20210814194737.GA3951530@roeck-us.net> <87sfzb7jeo.mognet@arm.com>
 <87eeav19mc.wl-maz@kernel.org> <87k0kk7w0c.mognet@arm.com>
 <87czqasn9u.wl-maz@kernel.org> <878s0t6s7p.mognet@arm.com>
 <87czq4qzd7.wl-maz@kernel.org> <875yvw78e5.mognet@arm.com>
Message-ID: <874kbgqrsw.wl-maz@kernel.org>

On Mon, 23 Aug 2021 11:38:58 +0100,
Valentin Schneider <valentin.schneider at arm.com> wrote:
> 
> On 23/08/21 10:33, Marc Zyngier wrote:
> > On Sun, 22 Aug 2021 23:16:10 +0100,
> > Valentin Schneider <valentin.schneider at arm.com> wrote:
> >>
> >> On 18/08/21 17:58, Marc Zyngier wrote:
> >> > There is the bizarre case of drivers/gpio/gpio-thunderx.c that changes
> >> > the irqchip flow to use either handle_fasteoi_ack_irq or
> >> > handle_fasteoi_mask_irq, which won't play very nicely with this.
> >> > Someone said Cavium?
> >> >
> >>
> >> Humph...
> >>
> >> I'm not familiar at all with the gpiolib irqchips, but I was under the
> >> impression those would involve chained IRQs (it does appear to be the case
> >> for the pl061 GPIOs on a Juno). For those, the innermost desc would be handled
> >> via chained_irq_{enter, exit}() [!!!], and the outermost one via whatever
> >> flow was installed by the relevant driver.
> >
> > Not all of them are built like this. There is actually a bunch of
> > these build as full hierarchies (QC, nvidia and some others).
> >
> 
> I see, thanks!
> 
> >> I can't easily grok what goes on between that gpio-thunderx.c driver and
> >> gpiolib, but since that GPIO chip has
> >>
> >>         .irq_eoi		= irq_chip_eoi_parent,
> >>
> >> and
> >>
> >>         girq->parent_domain =
> >>                 irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;
> >>
> >> (GPIOs hooked to MSI-X? Do I want to know?)
> >
> > It's good, isn't it? TX1 has all its HW appearing as PCI, even if it
> > clearly isn't PCI underneath.
> >
> >>
> >> I'm guessing it is *not* chained, which means the irq_set_handler_locked()
> >> affects the entire stack :/
> >
> > It does. We can probably fix that, but I won't be able to test (my TX1
> > was taken away a few months ago...). I'll accept body donations, for
> > scientific purposes.
> >
> 
> Looks like there are still some over on s/packet/equinix/, so I should be
> able to poke at one.

That's where mine used to live, but the WoA people decided that I
really didn't need one, and I'm now only allowed to borrow one of the
old eMAGs. If you can pull strings, let me know! :D

	M.

-- 
Without deviation from the norm, progress is not possible.


From alexandre.belloni at bootlin.com  Mon Aug 23 05:18:44 2021
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Mon, 23 Aug 2021 14:18:44 +0200
Subject: [PATCH 0/3] ARM: dts: at91: enable ips for sama7g5
In-Reply-To: <20210823100356.22206-1-claudiu.beznea@microchip.com>
References: <20210823100356.22206-1-claudiu.beznea@microchip.com>
Message-ID: <YSOSJK0FmbgNynRc@piout.net>

On 23/08/2021 13:03:53+0300, Claudiu Beznea wrote:
> Hi,
> 
> The following patches enable UDDRC, DDR3 PHY, SECURAM and SHDWC IPs
> on SAMA7G5.
> 
> Thank you,
> Claudiu Beznea
> 
> Claudiu Beznea (3):
>   ARM: dts: at91: add ram bindings
>   ARM: dts: at91: add bindins for securam
>   ARM: dts: at91: add bindings for shdwc

I think you meant node instead of bindings.


-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From wenst at chromium.org  Mon Aug 23 05:20:24 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 20:20:24 +0800
Subject: [v2 13/24] clk: mediatek: Add MT8195 ipesys clock support
In-Reply-To: <20210820111504.350-14-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-14-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5Fj69MQroMZV5ecpEg7cBcin0rA7C6XNCZcvcHebV-HQg@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:25 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 ipesys clock controller which provides clock gate
> control for ipe IP block.

Could you describe "ipe" in generic terms?

ChenYu


From wenst at chromium.org  Mon Aug 23 05:21:53 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 20:21:53 +0800
Subject: [v2 16/24] clk: mediatek: Add MT8195 vdecsys clock support
In-Reply-To: <20210820111504.350-17-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-17-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5HGjd4tQ4rg11VmQYOzUxkSrGStV8vS7kXkKWS1N4nM3Q@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:28 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 vdec clock controllers which provide clock gate
> control for video decoder.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile          |   3 +-
>  drivers/clk/mediatek/clk-mt8195-vdec.c | 104 +++++++++++++++++++++++++
>  2 files changed, 106 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-vdec.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 472e5bc40fcb..ac269f6d39e3 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -81,6 +81,7 @@ obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
> -                                       clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o
> +                                       clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
> +                                       clk-mt8195-vdec.o

Apart from the line wrapping,

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From james.clark at arm.com  Mon Aug 23 05:23:42 2021
From: james.clark at arm.com (James Clark)
Date: Mon, 23 Aug 2021 13:23:42 +0100
Subject: [PATCH v1 3/3] perf auxtrace arm: Support
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210809112727.596876-4-leo.yan@linaro.org>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-4-leo.yan@linaro.org>
Message-ID: <6ce4057a-57cf-501d-6449-2069cd00ba57@arm.com>



On 09/08/2021 12:27, Leo Yan wrote:
> When the tool runs with compat mode on Arm platform, the kernel is in
> 64-bit mode and user space is in 32-bit mode; the user space can use
> instructions "ldrd" and "strd" for 64-bit value atomicity.
> 
> This patch adds compat_auxtrace_mmap__{read_head|write_tail} for arm
> building, it uses "ldrd" and "strd" instructions to ensure accessing
> atomicity for aux head and tail.  The file arch/arm/util/auxtrace.c is
> built for arm and arm64 building, these two functions are not needed for
> arm64, so check the compiler macro "__arm__" to only include them for
> arm building.
> 
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>  tools/perf/arch/arm/util/auxtrace.c | 32 +++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c
> index b187bddbd01a..c7c7ec0812d5 100644
> --- a/tools/perf/arch/arm/util/auxtrace.c
> +++ b/tools/perf/arch/arm/util/auxtrace.c
> @@ -107,3 +107,35 @@ struct auxtrace_record
>  	*err = 0;
>  	return NULL;
>  }
> +
> +#if defined(__arm__)
> +u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> +{
> +	struct perf_event_mmap_page *pc = mm->userpg;
> +	u64 result;
> +
> +	__asm__ __volatile__(
> +"	ldrd    %0, %H0, [%1]"
> +	: "=&r" (result)
> +	: "r" (&pc->aux_head), "Qo" (pc->aux_head)
> +	);
> +
> +	return result;
> +}

Hi Leo,

I see that this is a duplicate of the atomic read in arch/arm/include/asm/atomic.h

For x86, it's possible to include tools/include/asm/atomic.h, but that doesn't
include arch/arm/include/asm/atomic.h and there are some other #ifdefs that might
make it not so easy for Arm. Just wondering if you considered trying to include the
existing one? Or decided that it was easier to duplicate it?

Other than that, I have tested that the change works with a 32bit build with snapshot
and normal mode.

Reviewed by: James Clark <james.clark at arm.com>
Tested by: James Clark <james.clark at arm.com>
 
> +
> +int compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
> +{
> +	struct perf_event_mmap_page *pc = mm->userpg;
> +
> +	/* Ensure all reads are done before we write the tail out */
> +	smp_mb();
> +
> +	__asm__ __volatile__(
> +"	strd    %2, %H2, [%1]"
> +	: "=Qo" (pc->aux_tail)
> +	: "r" (&pc->aux_tail), "r" (tail)
> +	);
> +
> +	return 0;
> +}
> +#endif
> 


From catalin.marinas at arm.com  Mon Aug 23 05:30:52 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 23 Aug 2021 13:30:52 +0100
Subject: [PATCH RESEND v3] ACPI: Add memory semantics to
 acpi_os_map_memory()
In-Reply-To: <20210823104618.14552-1-lorenzo.pieralisi@arm.com>
References: <20210802152359.12623-1-lorenzo.pieralisi@arm.com>
 <20210823104618.14552-1-lorenzo.pieralisi@arm.com>
Message-ID: <20210823123052.GC8603@arm.com>

On Mon, Aug 23, 2021 at 11:46:18AM +0100, Lorenzo Pieralisi wrote:
> The memory attributes attached to memory regions depend on architecture
> specific mappings.
> 
> For some memory regions, the attributes specified by firmware (eg
> uncached) are not sufficient to determine how a memory region should be
> mapped by an OS (for instance a region that is define as uncached in
> firmware can be mapped as Normal or Device memory on arm64) and
> therefore the OS must be given control on how to map the region to match
> the expected mapping behaviour (eg if a mapping is requested with memory
> semantics, it must allow unaligned accesses).
> 
> Rework acpi_os_map_memory() and acpi_os_ioremap() back-end to split
> them into two separate code paths:
> 
> acpi_os_memmap() -> memory semantics
> acpi_os_ioremap() -> MMIO semantics
> 
> The split allows the architectural implementation back-ends to detect
> the default memory attributes required by the mapping in question
> (ie the mapping API defines the semantics memory vs MMIO) and map the
> memory accordingly.
> 
> Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702 at arm.com
> Tested-by: Hanjun Guo <guohanjun at huawei.com>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Acked-by: Ard Biesheuvel <ardb at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Will Deacon <will at kernel.org>
> Cc: Hanjun Guo <guohanjun at huawei.com>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
> ---
> Resending with all lists CC'ed.
> 
> Patch series is a v3 of a previous version[2]:
> 
> v2->v3:
> 	- Dropped first two-patches following LKML feedback[2]
> v1->v2
> 	- Added patch 1 and 2 according to feedback received on[1]
> 
> [1] https://lore.kernel.org/linux-acpi/20210726100026.12538-1-lorenzo.pieralisi at arm.com
> [2] https://lore.kernel.org/linux-acpi/20210802152359.12623-1-lorenzo.pieralisi at arm.com
> 
>  arch/arm64/include/asm/acpi.h |  3 +++
>  arch/arm64/kernel/acpi.c      | 19 ++++++++++++++++---
>  drivers/acpi/osl.c            | 23 ++++++++++++++++-------
>  include/acpi/acpi_io.h        |  8 ++++++++
>  4 files changed, 43 insertions(+), 10 deletions(-)

For arm64:

Acked-by: Catalin Marinas <catalin.marinas at arm.com>

I presume this patch would go in via the acpi tree.

-- 
Catalin


From michael.riesch at wolfvision.net  Mon Aug 23 05:39:10 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 23 Aug 2021 14:39:10 +0200
Subject: [PATCH 0/1] arm64: dts: rockchip: add missing rockchip,
 grf property to rk356x
Message-ID: <20210823123911.12095-1-michael.riesch@wolfvision.net>

Hi all,

The following error messages appear on my RK3568 EVB1 board during boot:

  rockchip_clk_register_muxgrf: regmap not available
  rockchip_clk_register_branches: failed to register clock clk_ddr1x: -524

These can be fixed by providing the missing rockchip,grf property to the
device tree (similar to other Rockchip SoCs, such as the RK3399).

However, the rockchip,rk3568-cru bindings do not specify a property of that
name. Am I missing something or should this property be added to the bindings?

Best regards,
Michael

Michael Riesch (1):
  arm64: dts: rockchip: add missing rockchip,grf property to rk356x

 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 1 +
 1 file changed, 1 insertion(+)

-- 
2.17.1



From michael.riesch at wolfvision.net  Mon Aug 23 05:39:11 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 23 Aug 2021 14:39:11 +0200
Subject: [PATCH 1/1] arm64: dts: rockchip: add missing rockchip,
 grf property to rk356x
In-Reply-To: <20210823123911.12095-1-michael.riesch@wolfvision.net>
References: <20210823123911.12095-1-michael.riesch@wolfvision.net>
Message-ID: <20210823123911.12095-2-michael.riesch@wolfvision.net>

This commit fixes the error messages

  rockchip_clk_register_muxgrf: regmap not available
  rockchip_clk_register_branches: failed to register clock clk_ddr1x: -524

during boot by providing the missing rockchip,grf property.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 23949e79d8ce..0a1d07c96b2e 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -233,6 +233,7 @@
 		#reset-cells = <1>;
 		assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>;
 		assigned-clock-rates = <1200000000>, <200000000>;
+		rockchip,grf = <&grf>;
 	};
 
 	i2c0: i2c at fdd40000 {
-- 
2.17.1



From wenst at chromium.org  Mon Aug 23 05:48:25 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 20:48:25 +0800
Subject: [v2 24/24] clk: mediatek: Add MT8195 apusys clock support
In-Reply-To: <20210820111504.350-25-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-25-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5H6pLtNk_KzAoCreX24t4Fs-7wswPwiZaJYmpXo=9p5iw@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:37 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 apusys clock controller which provides PLLs
> in AI processor Unit.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile                |  2 +-
>  drivers/clk/mediatek/clk-mt8195-apusys_pll.c | 92 ++++++++++++++++++++
>  2 files changed, 93 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-apusys_pll.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 4288ad39ba41..e10b1d6b0cf4 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -83,6 +83,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
>                                         clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
>                                         clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o clk-mt8195-vpp0.o \
> -                                       clk-mt8195-vpp1.o clk-mt8195-wpe.o clk-mt8195-imp_iic_wrap.o
> +                                       clk-mt8195-vpp1.o clk-mt8195-wpe.o clk-mt8195-imp_iic_wrap.o clk-mt8195-apusys_pll.o

Wrap line ...

Otherwise,

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From boqun.feng at gmail.com  Mon Aug 23 05:49:29 2021
From: boqun.feng at gmail.com (Boqun Feng)
Date: Mon, 23 Aug 2021 20:49:29 +0800
Subject: [PATCH v6 0/8] PCI: hv: Support host bridge probing on ARM64
In-Reply-To: <20210823100959.GA3294@lpieralisi>
References: <20210726180657.142727-1-boqun.feng@gmail.com>
 <20210819141758.GA27305@lpieralisi>
 <YR59KJ+SenbQ58cw@boqun-archlinux>
 <20210823100959.GA3294@lpieralisi>
Message-ID: <YSOZWTPabTwlzbSP@boqun-archlinux>

On Mon, Aug 23, 2021 at 11:10:00AM +0100, Lorenzo Pieralisi wrote:
> On Thu, Aug 19, 2021 at 11:47:52PM +0800, Boqun Feng wrote:
> > On Thu, Aug 19, 2021 at 03:17:58PM +0100, Lorenzo Pieralisi wrote:
> > > On Tue, Jul 27, 2021 at 02:06:49AM +0800, Boqun Feng wrote:
> > > > Hi,
> > > > 
> > > > This is the v6 for the preparation of virtual PCI support on Hyper-V
> > > > ARM64, Previous versions:
> > > > 
> > > > v1:	https://lore.kernel.org/lkml/20210319161956.2838291-1-boqun.feng at gmail.com/
> > > > v2:	https://lore.kernel.org/lkml/20210503144635.2297386-1-boqun.feng at gmail.com/
> > > > v3:	https://lore.kernel.org/lkml/20210609163211.3467449-1-boqun.feng at gmail.com/
> > > > v4:	https://lore.kernel.org/lkml/20210714102737.198432-1-boqun.feng at gmail.com/
> > > > v5:	https://lore.kernel.org/lkml/20210720134429.511541-1-boqun.feng at gmail.com/
> > > > 
> > > > Changes since last version:
> > > > 
> > > > *	Rebase to 5.14-rc3
> > > > 
> > > > *	Comment fixes as suggested by Bjorn.
> > > > 
> > > > The basic problem we need to resolve is that ARM64 is an arch with
> > > > PCI_DOMAINS_GENERIC=y, so the bus sysdata is pci_config_window. However,
> > > > Hyper-V PCI provides a paravirtualized PCI interface, so there is no
> > > > actual pci_config_window for a PCI host bridge, so no information can be
> > > > retrieve from the pci_config_window of a Hyper-V virtual PCI bus. Also
> > > > there is no corresponding ACPI device for the Hyper-V PCI root bridge,
> > > > which introduces a special case when trying to find the ACPI device from
> > > > the sysdata (see patch #3).
> > > > 
> > > > With this patchset, we could enable the virtual PCI on Hyper-V ARM64
> > > > guest with other code under development.
> > > > 
> > > > Comments and suggestions are welcome.
> > > > 
> > > > Regards,
> > > > Boqun
> > > > 
> > > > Arnd Bergmann (1):
> > > >   PCI: hv: Generify PCI probing
> > > > 
> > > > Boqun Feng (7):
> > > >   PCI: Introduce domain_nr in pci_host_bridge
> > > >   PCI: Support populating MSI domains of root buses via bridges
> > > >   arm64: PCI: Restructure pcibios_root_bridge_prepare()
> > > >   arm64: PCI: Support root bridge preparation for Hyper-V
> > > >   PCI: hv: Set ->domain_nr of pci_host_bridge at probing time
> > > >   PCI: hv: Set up MSI domain at bridge probing time
> > > >   PCI: hv: Turn on the host bridge probing on ARM64
> > > > 
> > > >  arch/arm64/kernel/pci.c             | 29 +++++++---
> > > >  drivers/pci/controller/pci-hyperv.c | 86 +++++++++++++++++------------
> > > >  drivers/pci/probe.c                 | 12 +++-
> > > >  include/linux/pci.h                 | 11 ++++
> > > >  4 files changed, 93 insertions(+), 45 deletions(-)
> > > 
> > > If we take this series via the PCI tree we'd need Catalin/Will ACKs on
> > > patches 3-4.
> > > 
> > 
> > Got it.
> > 
> > > I need some time to look into [1] (thanks for that).
> > > 
> > > Without [1] patch 8 is ugly, that's no news. The question is whether
> > > it is worth waiting for a kernel cycle to integrate [1] into this series
> > > or not.
> > > 
> > > Is it really a problem if we postpone this series for another kernel
> > > cycle so that we can look into it ?
> > > 
> > 
> > Well, it's definitely better for me that we can have it in 5.15-rc1 ;-),
> > because it's a dependency for Hyper-V virtual PCI support on ARM64 and
> > we plan to send the rest of work in 5.15 cycle. And I can just base on
> > hyperv-next for the rest of the work if this is in 5.15-rc1. But yes,
> > it's not really a problem, since this one still needs to work with other
> > patches to support virtual PCI on ARM64 Hyper-V.
> > 
> > In fact, I personally don't think [1] is better than patch 8 (plus patch
> > 3 & 4): playing with ->private seems dangerous and not very helpful on
> > readiblity, but I agree that we should explore every potential solution,
> > and that's why I send [1].
> 
> Pulled the current series - now let's work together to improve it, I
> will have a look into [1] in the weeks to come and get back to you with
> some feedback.
> 

Thanks a lot! Looking forwards to your feedback ;-)

Regards,
Boqun

> Thanks,
> Lorenzo
> 
> > Regards,
> > Boqun
> > 
> > > [1] https://lore.kernel.org/lkml/20210811153619.88922-1-boqun.feng at gmail.com/


From wenst at chromium.org  Mon Aug 23 05:50:13 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 23 Aug 2021 20:50:13 +0800
Subject: [v2 23/24] clk: mediatek: Add MT8195 imp i2c wrapper clock support
In-Reply-To: <20210820111504.350-24-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-24-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5EDn=OjghzN6wzx0RF4k=h6eKAY6qdf278WZbANHnoGUw@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:36 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 imp i2c wrapper clock controllers which provide clock gate
> control in IIC IP blocks.

Standard terminology is I2C.

Otherwise,

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From catalin.marinas at arm.com  Mon Aug 23 05:55:19 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 23 Aug 2021 13:55:19 +0100
Subject: [PATCH v5 7/9] arm64: kdump: Remove custom linux,elfcorehdr
 handling
In-Reply-To: <3b8f801f9b92066855e87f3079fafc153ab20f69.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <3b8f801f9b92066855e87f3079fafc153ab20f69.1628670468.git.geert+renesas@glider.be>
Message-ID: <20210823125519.GD8603@arm.com>

On Wed, Aug 11, 2021 at 10:51:05AM +0200, Geert Uytterhoeven wrote:
> Remove the architecture-specific code for handling the
> "linux,elfcorehdr" property under the "/chosen" node in DT, as the
> platform-agnostic handling in the FDT core code already takes care of
> this.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Mon Aug 23 05:55:33 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 23 Aug 2021 13:55:33 +0100
Subject: [PATCH v5 8/9] arm64: kdump: Remove custom
 linux,usable-memory-range handling
In-Reply-To: <7356c531c49a24b4a55577bf8e46d93f4d8ae460.1628670468.git.geert+renesas@glider.be>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <7356c531c49a24b4a55577bf8e46d93f4d8ae460.1628670468.git.geert+renesas@glider.be>
Message-ID: <20210823125533.GE8603@arm.com>

On Wed, Aug 11, 2021 at 10:51:06AM +0200, Geert Uytterhoeven wrote:
> Remove the architecture-specific code for handling the
> "linux,usable-memory-range" property under the "/chosen" node in DT, as
> the platform-agnostic FDT core code already takes care of this.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Mon Aug 23 05:58:35 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 23 Aug 2021 13:58:35 +0100
Subject: [PATCH v1 0/6] kselftest/arm64: SVE signal handling tests
In-Reply-To: <20210819134245.13935-1-broonie@kernel.org>
References: <20210819134245.13935-1-broonie@kernel.org>
Message-ID: <162972351131.16315.329516738132119653.b4-ty@arm.com>

On Thu, 19 Aug 2021 14:42:39 +0100, Mark Brown wrote:
> Currently we have no real tests for SVE signal handling (though the
> stress test does trigger the code paths as it regularly sends signals to
> the test processes).  Add some basic coverage, this is very much
> incomplete but it's more coverage than we currently have, a TODO file is
> included with some omissions that occurred to me.
> 
> Mark Brown (6):
>   kselftest/arm64: signal: Add SVE to the set of features we can check
>     for
>   kselftest/arm64: signal: Support signal frames with SVE register data
>   kselftest/arm64: signal: Check SVE signal frame shows expected vector
>     length
>   kselftest/arm64: signal: Verify that signals can't change the SVE
>     vector length
>   kselftest/arm64: signal: Add test case for SVE register state in
>     signals
>   kselftest/arm64: signal: Add a TODO list for signal handling tests
> 
> [...]

Applied to arm64 (for-next/kselftest), thanks!

[1/6] kselftest/arm64: signal: Add SVE to the set of features we can check for
      https://git.kernel.org/arm64/c/d4e4dc4fab68
[2/6] kselftest/arm64: signal: Support signal frames with SVE register data
      https://git.kernel.org/arm64/c/ace19b1845a5
[3/6] kselftest/arm64: signal: Check SVE signal frame shows expected vector length
      https://git.kernel.org/arm64/c/c1f67a19c12e
[4/6] kselftest/arm64: signal: Verify that signals can't change the SVE vector length
      https://git.kernel.org/arm64/c/d25ac50ce8f7
[5/6] kselftest/arm64: signal: Add test case for SVE register state in signals
      https://git.kernel.org/arm64/c/5262b216f4a9
[6/6] kselftest/arm64: signal: Add a TODO list for signal handling tests
      https://git.kernel.org/arm64/c/fa5ca80db89e

-- 
Catalin



From andrew at lunn.ch  Mon Aug 23 06:00:08 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 23 Aug 2021 15:00:08 +0200
Subject: [PATCH net] net: phy: mediatek: add the missing suspend/resume
 callbacks
In-Reply-To: <20210823044422.164184-1-dqfext@gmail.com>
References: <20210823044422.164184-1-dqfext@gmail.com>
Message-ID: <YSOb2P43svWca9IJ@lunn.ch>

On Mon, Aug 23, 2021 at 12:44:21PM +0800, DENG Qingfang wrote:
> Without suspend/resume callbacks, the PHY cannot be powered down/up
> administratively.
> 
> Fixes: e40d2cca0189 ("net: phy: add MediaTek Gigabit Ethernet PHY driver")
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From krzysztof.kozlowski at canonical.com  Mon Aug 23 06:01:24 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 23 Aug 2021 15:01:24 +0200
Subject: [PATCH] arm64: defconfig: drop obsolete ARCH_* configs
In-Reply-To: <20210821030519.127-1-yuzenghui@huawei.com>
References: <20210821030519.127-1-yuzenghui@huawei.com>
Message-ID: <39c2b2f9-4de2-8e7d-2135-96f1dab750e0@canonical.com>

On 21/08/2021 05:05, Zenghui Yu wrote:
> Per commit 4a9a1a5602d8 ("arm64: socfpga: merge Agilex and N5X into
> ARCH_INTEL_SOCFPGA") and commit 89d4f98ae90d ("ARM: remove zte zx
> platform"), they can be dropped from defconfig now.
> 
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Zenghui Yu <yuzenghui at huawei.com>
> ---
>  arch/arm64/configs/defconfig | 3 ---
>  1 file changed, 3 deletions(-)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From kewei.xu at mediatek.com  Mon Aug 23 06:05:30 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Mon, 23 Aug 2021 21:05:30 +0800
Subject: [PATCH v5 0/7] Introducing an attribute to select the time setting
Message-ID: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>

v5:
1. Replace the previous variable name "default_timing_adjust" with "use-default-timing"
2. Added waiting for dma reset mechanism
3. Remove received patch(dt-bindings: i2c: update bindings for MT8195 SOC)

v4:
1. Remove the repeated assignment of the inter_clk_div parameter
2. Modify the wrong assignment of OFFSET_MULTI_DMA
3. Unify the log print format of the i2c_dump_register() and drop the extra outer parentheses
4. Place the fixes at the very least
5. Add fixed tags 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183")
6. Add "i2c: mediatek: modify bus speed calculation formula"
7. Fix single line characters exceeding 80 characters
8. Combine two different series of patches.

v3:
1. Fix code errors caused by v2 modification

v2:
1. Add "dt-bindings: i2c: add attribute default-timing-adjust"
2. Split the fix into sepatate patch.

Kewei Xu (7):
  i2c: mediatek: fixing the incorrect register offset
  i2c: mediatek: Reset the handshake signal between i2c and dma
  i2c: mediatek: Dump i2c/dma register when a timeout occurs
  dt-bindings: i2c: add attribute use-default-timing
  i2c: mediatek: Add OFFSET_EXT_CONF setting back
  i2c: mediatek: Isolate speed setting via dts for special devices
  i2c: mediatek: modify bus speed calculation formula

 .../devicetree/bindings/i2c/i2c-mt65xx.txt    |   2 +
 drivers/i2c/busses/i2c-mt65xx.c               | 207 ++++++++++++++++--
 2 files changed, 192 insertions(+), 17 deletions(-)

-- 
2.18.0

From kewei.xu at mediatek.com  Mon Aug 23 06:05:31 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Mon, 23 Aug 2021 21:05:31 +0800
Subject: [PATCH 1/7] i2c: mediatek: fixing the incorrect register offset
In-Reply-To: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
References: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629723937-10839-2-git-send-email-kewei.xu@mediatek.com>

The reason for the modification here is that the previous
offset information is incorrect, OFFSET_DEBUGSTAT = 0xE4 is
the correct value.

Fixes: 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/i2c/busses/i2c-mt65xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 4ca716e..2661ed0 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -193,7 +193,7 @@ enum I2C_REGS_OFFSET {
 	[OFFSET_CLOCK_DIV] = 0x48,
 	[OFFSET_SOFTRESET] = 0x50,
 	[OFFSET_SCL_MIS_COMP_POINT] = 0x90,
-	[OFFSET_DEBUGSTAT] = 0xe0,
+	[OFFSET_DEBUGSTAT] = 0xe4,
 	[OFFSET_DEBUGCTRL] = 0xe8,
 	[OFFSET_FIFO_STAT] = 0xf4,
 	[OFFSET_FIFO_THRESH] = 0xf8,
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 06:05:34 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Mon, 23 Aug 2021 21:05:34 +0800
Subject: [PATCH 4/7] dt-bindings: i2c: add attribute use-default-timing
In-Reply-To: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
References: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629723937-10839-5-git-send-email-kewei.xu@mediatek.com>

Add attribute use-default-timing for DT-binding document.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
index 5ea216a..4dbb697 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
@@ -34,6 +34,8 @@ Optional properties:
     Only mt6589 and mt8135 support this feature.
   - mediatek,use-push-pull: IO config use push-pull mode.
   - vbus-supply: phandle to the regulator that provides power to SCL/SDA.
+  - mediatek,use-default-timing: use default timing calculation, no timing
+    adjustment.
 
 Example:
 
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 06:05:32 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Mon, 23 Aug 2021 21:05:32 +0800
Subject: [PATCH 2/7] i2c: mediatek: Reset the handshake signal between i2c and
 dma
In-Reply-To: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
References: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629723937-10839-3-git-send-email-kewei.xu@mediatek.com>

Due to changes in the hardware design of the handshaking signal
between i2c and dma, it is necessary to reset the handshaking
signal before each transfer to ensure that the multi-msgs can
be transferred correctly.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 2661ed0..abda525 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -47,6 +48,9 @@
 #define I2C_RD_TRANAC_VALUE		0x0001
 #define I2C_SCL_MIS_COMP_VALUE		0x0000
 #define I2C_CHN_CLR_FLAG		0x0000
+#define I2C_CLR_DEBUGCTR		0x0000
+#define I2C_RELIABILITY			0x0010
+#define I2C_DMAACK_ENABLE		0x0008
 
 #define I2C_DMA_CON_TX			0x0000
 #define I2C_DMA_CON_RX			0x0001
@@ -842,6 +846,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 	u16 restart_flag = 0;
 	u16 dma_sync = 0;
 	u32 reg_4g_mode;
+	u32 reg_dma_reset;
 	u8 *dma_rd_buf = NULL;
 	u8 *dma_wr_buf = NULL;
 	dma_addr_t rpaddr = 0;
@@ -855,6 +860,27 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 
 	reinit_completion(&i2c->msg_complete);
 
+	if (i2c->dev_comp->apdma_sync && left_num > 1) {
+		mtk_i2c_writew(i2c, I2C_CLR_DEBUGCTR, OFFSET_DEBUGCTRL);
+		writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_WARM_RST,
+		       i2c->pdmabase + OFFSET_RST);
+
+		ret = readw_poll_timeout(i2c->pdmabase + OFFSET_RST,
+					 reg_dma_reset,
+					 !(reg_dma_reset & I2C_DMA_WARM_RST),
+					 0, 100);
+		if (ret) {
+			dev_err(i2c->dev, "DMA warm reset timeout\n");
+			return -ETIMEDOUT;
+		}
+
+		writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
+		mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST, OFFSET_SOFTRESET);
+		mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET);
+		mtk_i2c_writew(i2c, I2C_RELIABILITY | I2C_DMAACK_ENABLE,
+			       OFFSET_DEBUGCTRL);
+	}
+
 	control_reg = mtk_i2c_readw(i2c, OFFSET_CONTROL) &
 			~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
 	if ((i2c->speed_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) || (left_num >= 1))
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 06:05:36 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Mon, 23 Aug 2021 21:05:36 +0800
Subject: [PATCH 6/7] i2c: mediatek: Isolate speed setting via dts for special
 devices
In-Reply-To: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
References: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629723937-10839-7-git-send-email-kewei.xu@mediatek.com>

In the commit be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust
support"), the I2C timing calculation has been revised to support
ac-timing adjustment, however that will break on some I2C components.
As a result we want to introduce a new setting "default-adjust-timing"
so those components can choose to use the old (default) timing algorithm.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 77 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 4da6b43..18b5659 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -66,6 +66,7 @@
 #define I2C_DMA_HARD_RST		0x0002
 #define I2C_DMA_HANDSHAKE_RST		0x0004
 
+#define I2C_DEFAULT_CLK_DIV		5
 #define MAX_SAMPLE_CNT_DIV		8
 #define MAX_STEP_CNT_DIV		64
 #define MAX_CLOCK_DIV			256
@@ -250,6 +251,7 @@ struct mtk_i2c {
 	struct clk *clk_arb;		/* Arbitrator clock for i2c */
 	bool have_pmic;			/* can use i2c pins from PMIC */
 	bool use_push_pull;		/* IO config push-pull mode */
+	bool use_default_timing;	/* no timing adjust mode */
 
 	u16 irq_stat;			/* interrupt status */
 	unsigned int clk_src_div;
@@ -532,7 +534,11 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 	else
 		ext_conf_val = I2C_FS_START_CON;
 
-	if (i2c->dev_comp->timing_adjust) {
+	if (i2c->use_default_timing) {
+		if (i2c->dev_comp->timing_adjust)
+			mtk_i2c_writew(i2c, I2C_DEFAULT_CLK_DIV - 1,
+				       OFFSET_CLOCK_DIV);
+	} else if (i2c->dev_comp->timing_adjust) {
 		ext_conf_val = i2c->ac_timing.ext;
 		mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
 			       OFFSET_CLOCK_DIV);
@@ -615,7 +621,7 @@ static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c,
 	unsigned int sample_ns = div_u64(1000000000ULL * (sample_cnt + 1),
 					 clk_src);
 
-	if (!i2c->dev_comp->timing_adjust)
+	if (i2c->use_default_timing || !i2c->dev_comp->timing_adjust)
 		return 0;
 
 	if (i2c->dev_comp->ltiming_adjust)
@@ -775,7 +781,65 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	return 0;
 }
 
-static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
+static int mtk_i2c_set_speed_default_timing(struct mtk_i2c *i2c,
+					    unsigned int parent_clk)
+{
+	unsigned int clk_src;
+	unsigned int step_cnt;
+	unsigned int sample_cnt;
+	unsigned int l_step_cnt;
+	unsigned int l_sample_cnt;
+	unsigned int target_speed;
+	int ret;
+
+	if (i2c->dev_comp->timing_adjust)
+		i2c->clk_src_div *= I2C_DEFAULT_CLK_DIV;
+
+	clk_src = parent_clk / i2c->clk_src_div;
+	target_speed = i2c->speed_hz;
+
+	if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) {
+		/* Set master code speed register */
+		ret = mtk_i2c_calculate_speed(i2c, clk_src,
+					      I2C_MAX_FAST_MODE_FREQ,
+					      &l_step_cnt, &l_sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->timing_reg = (l_sample_cnt << 8) | l_step_cnt;
+
+		/* Set the high speed mode register */
+		ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->high_speed_reg = I2C_TIME_DEFAULT_VALUE |
+			(sample_cnt << 12) | (step_cnt << 8);
+
+		if (i2c->dev_comp->ltiming_adjust)
+			i2c->ltiming_reg = (l_sample_cnt << 6) | l_step_cnt |
+					   (sample_cnt << 12) | (step_cnt << 9);
+	} else {
+		ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->timing_reg = (sample_cnt << 8) | step_cnt;
+
+		/* Disable the high speed transaction */
+		i2c->high_speed_reg = I2C_TIME_CLR_VALUE;
+
+		if (i2c->dev_comp->ltiming_adjust)
+			i2c->ltiming_reg = (sample_cnt << 6) | step_cnt;
+	}
+
+	return 0;
+}
+
+static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
+					   unsigned int parent_clk)
 {
 	unsigned int clk_src;
 	unsigned int step_cnt;
@@ -1271,6 +1335,8 @@ static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c)
 	i2c->have_pmic = of_property_read_bool(np, "mediatek,have-pmic");
 	i2c->use_push_pull =
 		of_property_read_bool(np, "mediatek,use-push-pull");
+	i2c->use_default_timing =
+		of_property_read_bool(np, "mediatek,use-default-timing");
 
 	i2c_parse_fw_timings(i2c->dev, &i2c->timing_info, true);
 
@@ -1357,7 +1423,10 @@ static int mtk_i2c_probe(struct platform_device *pdev)
 
 	strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
 
-	ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk));
+	if (i2c->use_default_timing)
+		ret = mtk_i2c_set_speed_default_timing(i2c, clk_get_rate(clk));
+	else
+		ret = mtk_i2c_set_speed_adjust_timing(i2c, clk_get_rate(clk));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to set the speed.\n");
 		return -EINVAL;
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 06:05:37 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Mon, 23 Aug 2021 21:05:37 +0800
Subject: [PATCH 7/7] i2c: mediatek: modify bus speed calculation formula
In-Reply-To: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
References: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629723937-10839-8-git-send-email-kewei.xu@mediatek.com>

When clock-div is 0 or greater than 1, the bus speed
calculated by the old speed calculation formula will be
larger than the target speed. So we update the formula.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 18b5659..0b42acd8 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -69,11 +69,12 @@
 #define I2C_DEFAULT_CLK_DIV		5
 #define MAX_SAMPLE_CNT_DIV		8
 #define MAX_STEP_CNT_DIV		64
-#define MAX_CLOCK_DIV			256
+#define MAX_CLOCK_DIV_8BITS		256
+#define MAX_CLOCK_DIV_5BITS		32
 #define MAX_HS_STEP_CNT_DIV		8
-#define I2C_STANDARD_MODE_BUFFER	(1000 / 2)
-#define I2C_FAST_MODE_BUFFER		(300 / 2)
-#define I2C_FAST_MODE_PLUS_BUFFER	(20 / 2)
+#define I2C_STANDARD_MODE_BUFFER	(1000 / 3)
+#define I2C_FAST_MODE_BUFFER		(300 / 3)
+#define I2C_FAST_MODE_PLUS_BUFFER	(20 / 3)
 
 #define I2C_CONTROL_RS                  (0x1 << 1)
 #define I2C_CONTROL_DMA_EN              (0x1 << 2)
@@ -725,14 +726,26 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	unsigned int best_mul;
 	unsigned int cnt_mul;
 	int ret = -EINVAL;
+	int clock_div_constraint = 0;
 
 	if (target_speed > I2C_MAX_HIGH_SPEED_MODE_FREQ)
 		target_speed = I2C_MAX_HIGH_SPEED_MODE_FREQ;
 
+	if (i2c->use_default_timing) {
+		clock_div_constraint = 0;
+	} else if (i2c->dev_comp->ltiming_adjust &&
+		   i2c->ac_timing.inter_clk_div > 1) {
+		clock_div_constraint = 1;
+	} else if (i2c->dev_comp->ltiming_adjust &&
+		   i2c->ac_timing.inter_clk_div == 0) {
+		clock_div_constraint = -1;
+	}
+
 	max_step_cnt = mtk_i2c_max_step_cnt(target_speed);
 	base_step_cnt = max_step_cnt;
 	/* Find the best combination */
-	opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
+	opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed) +
+		  clock_div_constraint;
 	best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
 
 	/* Search for the best pair (sample_cnt, step_cnt) with
@@ -767,7 +780,8 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	sample_cnt = base_sample_cnt;
 	step_cnt = base_step_cnt;
 
-	if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
+	if ((clk_src / (2 * (sample_cnt * step_cnt - clock_div_constraint))) >
+		 target_speed) {
 		/* In this case, hardware can't support such
 		 * low i2c_bus_freq
 		 */
@@ -854,13 +868,16 @@ static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
 	target_speed = i2c->speed_hz;
 	parent_clk /= i2c->clk_src_div;
 
-	if (i2c->dev_comp->timing_adjust)
-		max_clk_div = MAX_CLOCK_DIV;
+	if (i2c->dev_comp->timing_adjust && i2c->dev_comp->ltiming_adjust)
+		max_clk_div = MAX_CLOCK_DIV_5BITS;
+	else if (i2c->dev_comp->timing_adjust)
+		max_clk_div = MAX_CLOCK_DIV_8BITS;
 	else
 		max_clk_div = 1;
 
 	for (clk_div = 1; clk_div <= max_clk_div; clk_div++) {
 		clk_src = parent_clk / clk_div;
+		i2c->ac_timing.inter_clk_div = clk_div - 1;
 
 		if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) {
 			/* Set master code speed register */
@@ -907,8 +924,6 @@ static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
 		break;
 	}
 
-	i2c->ac_timing.inter_clk_div = clk_div - 1;
-
 	return 0;
 }
 
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 06:05:33 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Mon, 23 Aug 2021 21:05:33 +0800
Subject: [PATCH 3/7] i2c: mediatek: Dump i2c/dma register when a timeout occurs
In-Reply-To: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
References: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629723937-10839-4-git-send-email-kewei.xu@mediatek.com>

When a timeout error occurs in i2c transter, it is usually related
to the i2c/dma IP hardware configuration. Therefore, the purpose of
this patch is to dump the key register values of i2c/dma when a
timeout occurs in i2c for debugging.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 56 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index abda525..633bce4 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -129,6 +129,7 @@ enum I2C_REGS_OFFSET {
 	OFFSET_HS,
 	OFFSET_SOFTRESET,
 	OFFSET_DCM_EN,
+	OFFSET_MULTI_DMA,
 	OFFSET_PATH_DIR,
 	OFFSET_DEBUGSTAT,
 	OFFSET_DEBUGCTRL,
@@ -196,6 +197,7 @@ enum I2C_REGS_OFFSET {
 	[OFFSET_TRANSFER_LEN_AUX] = 0x44,
 	[OFFSET_CLOCK_DIV] = 0x48,
 	[OFFSET_SOFTRESET] = 0x50,
+	[OFFSET_MULTI_DMA] = 0x8c,
 	[OFFSET_SCL_MIS_COMP_POINT] = 0x90,
 	[OFFSET_DEBUGSTAT] = 0xe4,
 	[OFFSET_DEBUGCTRL] = 0xe8,
@@ -837,6 +839,57 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
 	return 0;
 }
 
+static void i2c_dump_register(struct mtk_i2c *i2c)
+{
+	dev_err(i2c->dev, "SLAVE_ADDR: 0x%x, INTR_MASK: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_SLAVE_ADDR),
+		mtk_i2c_readw(i2c, OFFSET_INTR_MASK));
+	dev_err(i2c->dev, "INTR_STAT: 0x%x, CONTROL: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_INTR_STAT),
+		mtk_i2c_readw(i2c, OFFSET_CONTROL));
+	dev_err(i2c->dev, "TRANSFER_LEN: 0x%x, TRANSAC_LEN: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN),
+		mtk_i2c_readw(i2c, OFFSET_TRANSAC_LEN));
+	dev_err(i2c->dev, "DELAY_LEN: 0x%x, HTIMING: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DELAY_LEN),
+		mtk_i2c_readw(i2c, OFFSET_TIMING));
+	dev_err(i2c->dev, "START: 0x%x, EXT_CONF: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_START),
+		mtk_i2c_readw(i2c, OFFSET_EXT_CONF));
+	dev_err(i2c->dev, "HS: 0x%x, IO_CONFIG: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_HS),
+		mtk_i2c_readw(i2c, OFFSET_IO_CONFIG));
+	dev_err(i2c->dev, "DCM_EN: 0x%x, TRANSFER_LEN_AUX: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DCM_EN),
+		mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN_AUX));
+	dev_err(i2c->dev, "CLOCK_DIV: 0x%x, FIFO_STAT: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_CLOCK_DIV),
+		mtk_i2c_readw(i2c, OFFSET_FIFO_STAT));
+	dev_err(i2c->dev, "DEBUGCTRL : 0x%x, DEBUGSTAT: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DEBUGCTRL),
+		mtk_i2c_readw(i2c, OFFSET_DEBUGSTAT));
+	if (i2c->dev_comp->regs == mt_i2c_regs_v2) {
+		dev_err(i2c->dev, "LTIMING: 0x%x, MULTI_DMA: 0x%x\n",
+			mtk_i2c_readw(i2c, OFFSET_LTIMING),
+			mtk_i2c_readw(i2c, OFFSET_MULTI_DMA));
+	}
+	dev_err(i2c->dev, "\nDMA_INT_FLAG: 0x%x, DMA_INT_EN: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_INT_FLAG),
+		readl(i2c->pdmabase + OFFSET_INT_EN));
+	dev_err(i2c->dev, "DMA_EN: 0x%x, DMA_CON: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_EN),
+		readl(i2c->pdmabase + OFFSET_CON));
+	dev_err(i2c->dev, "DMA_TX_MEM_ADDR: 0x%x, DMA_RX_MEM_ADDR: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_TX_MEM_ADDR),
+		readl(i2c->pdmabase + OFFSET_RX_MEM_ADDR));
+	dev_err(i2c->dev, "DMA_TX_LEN: 0x%x, DMA_RX_LEN: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_TX_LEN),
+		readl(i2c->pdmabase + OFFSET_RX_LEN));
+	dev_err(i2c->dev, "DMA_TX_4G_MODE: 0x%x, DMA_RX_4G_MODE: 0x%x",
+		readl(i2c->pdmabase + OFFSET_TX_4G_MODE),
+		readl(i2c->pdmabase + OFFSET_RX_4G_MODE));
+}
+
 static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 			       int num, int left_num)
 {
@@ -1065,7 +1118,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 	}
 
 	if (ret == 0) {
-		dev_dbg(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
+		dev_err(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
+		i2c_dump_register(i2c);
 		mtk_i2c_init_hw(i2c);
 		return -ETIMEDOUT;
 	}
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 06:05:35 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Mon, 23 Aug 2021 21:05:35 +0800
Subject: [PATCH 5/7] i2c: mediatek: Add OFFSET_EXT_CONF setting back
In-Reply-To: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
References: <1629723937-10839-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629723937-10839-6-git-send-email-kewei.xu@mediatek.com>

In the commit be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust
support"), we miss setting OFFSET_EXT_CONF register if
i2c->dev_comp->timing_adjust is false, now add it back.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 633bce4..4da6b43 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -42,6 +42,8 @@
 #define I2C_HANDSHAKE_RST		0x0020
 #define I2C_FIFO_ADDR_CLR		0x0001
 #define I2C_DELAY_LEN			0x0002
+#define I2C_ST_START_CON		0x8001
+#define I2C_FS_START_CON		0x1800
 #define I2C_TIME_CLR_VALUE		0x0000
 #define I2C_TIME_DEFAULT_VALUE		0x0003
 #define I2C_WRRD_TRANAC_VALUE		0x0002
@@ -486,6 +488,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 {
 	u16 control_reg;
 	u16 intr_stat_reg;
+	u16 ext_conf_val;
 
 	mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_START);
 	intr_stat_reg = mtk_i2c_readw(i2c, OFFSET_INTR_STAT);
@@ -524,8 +527,13 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 	if (i2c->dev_comp->ltiming_adjust)
 		mtk_i2c_writew(i2c, i2c->ltiming_reg, OFFSET_LTIMING);
 
+	if (i2c->speed_hz <= I2C_MAX_STANDARD_MODE_FREQ)
+		ext_conf_val = I2C_ST_START_CON;
+	else
+		ext_conf_val = I2C_FS_START_CON;
+
 	if (i2c->dev_comp->timing_adjust) {
-		mtk_i2c_writew(i2c, i2c->ac_timing.ext, OFFSET_EXT_CONF);
+		ext_conf_val = i2c->ac_timing.ext;
 		mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
 			       OFFSET_CLOCK_DIV);
 		mtk_i2c_writew(i2c, I2C_SCL_MIS_COMP_VALUE,
@@ -550,6 +558,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 				       OFFSET_HS_STA_STO_AC_TIMING);
 		}
 	}
+	mtk_i2c_writew(i2c, ext_conf_val, OFFSET_EXT_CONF);
 
 	/* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */
 	if (i2c->have_pmic)
-- 
1.9.1

From rppt at kernel.org  Mon Aug 23 06:09:47 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 23 Aug 2021 16:09:47 +0300
Subject: [PATCH v5 1/9] MIPS: Avoid future duplicate elf core header
 reservation
In-Reply-To: <CAMuHMdVdqR7gw+2O2v=qv_BB=+X2wEXN9jXV=np=jRayadwj7g@mail.gmail.com>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>
 <YRn9DHlB/pdNPJyP@kernel.org>
 <CAMuHMdVdqR7gw+2O2v=qv_BB=+X2wEXN9jXV=np=jRayadwj7g@mail.gmail.com>
Message-ID: <YSOeGzowhV/R9QS/@kernel.org>

On Mon, Aug 23, 2021 at 12:17:50PM +0200, Geert Uytterhoeven wrote:
> Hi Mike,
> 
> On Mon, Aug 16, 2021 at 7:52 AM Mike Rapoport <rppt at kernel.org> wrote:
> > On Wed, Aug 11, 2021 at 10:50:59AM +0200, Geert Uytterhoeven wrote:
> > > Prepare for early_init_fdt_scan_reserved_mem() reserving the memory
> > > occupied by an elf core header described in the device tree.
> > > As arch_mem_init() calls early_init_fdt_scan_reserved_mem() before
> > > mips_reserve_vmcore(), the latter needs to check if the memory has
> > > already been reserved before.
> >
> > Doing memblock_reserve() for the same region is usually fine, did you
> > encounter any issues without this patch?
> 
> Does it also work if the same region is part of an earlier larger
> reservation?  I am no memblock expert, so I don't know.
> I didn't run into any issues, as my MIPS platform is non-DT, but I
> assume arch/arm64/mm/init.c:reserve_elfcorehdr() had the check for
> a reason.

The memory will be reserved regardless of the earlier reservation, the
issue may appear when the reservations are made for different purpose. E.g.
if there was crash kernel allocation before the reservation of elfcorehdr.

The check in such case will prevent the second reservation, but, at least
in arch/arm64/mm/init.c:reserve_elfcorehdr() it does not seem to prevent
different users of the overlapping regions to step on each others toes.

Moreover, arm64::reserve_elfcorehdr() seems buggy to me, because of there
is only a partial overlap of the elfcorehdr with the previous reservation,
the non-overlapping part of elfcorehdr won't get reserved at all.

> Thanks!
> 
> >
> > > Note that mips_reserve_vmcore() cannot just be removed, as not all MIPS
> > > systems use DT.
> > >
> > > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> > > ---
> > > v5:
> > >   - New.
> > > ---
> > >  arch/mips/kernel/setup.c | 3 ++-
> > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> > > index 23a140327a0bac1b..4693add05743d78b 100644
> > > --- a/arch/mips/kernel/setup.c
> > > +++ b/arch/mips/kernel/setup.c
> > > @@ -429,7 +429,8 @@ static void __init mips_reserve_vmcore(void)
> > >       pr_info("Reserving %ldKB of memory at %ldKB for kdump\n",
> > >               (unsigned long)elfcorehdr_size >> 10, (unsigned long)elfcorehdr_addr >> 10);
> > >
> > > -     memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
> > > +     if (!memblock_is_region_reserved(elfcorehdr_addr, elfcorehdr_size)
> > > +             memblock_reserve(elfcorehdr_addr, elfcorehdr_size);
> > >  #endif
> > >  }
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> -- 
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

-- 
Sincerely yours,
Mike.


From pgwipeout at gmail.com  Mon Aug 23 06:12:10 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Mon, 23 Aug 2021 09:12:10 -0400
Subject: [PATCH 1/1] arm64: dts: rockchip: add missing rockchip,grf
 property to rk356x
In-Reply-To: <20210823123911.12095-2-michael.riesch@wolfvision.net>
References: <20210823123911.12095-1-michael.riesch@wolfvision.net>
 <20210823123911.12095-2-michael.riesch@wolfvision.net>
Message-ID: <CAMdYzYr4ZTXvfJaeMejuRHBkBAVKcEUseskhEVqLMSYR+Dv4uw@mail.gmail.com>

On Mon, Aug 23, 2021 at 8:39 AM Michael Riesch
<michael.riesch at wolfvision.net> wrote:
>
> This commit fixes the error messages
>
>   rockchip_clk_register_muxgrf: regmap not available
>   rockchip_clk_register_branches: failed to register clock clk_ddr1x: -524
>
> during boot by providing the missing rockchip,grf property.

Good Morning,

This was fixed by commit: 6fffe52fb336 clk: rockchip: drop GRF
dependency for rk3328/rk3036 pll types
which was merged in -next. I don't believe it's going to be backported
to 5.14 due to 5.14 not being able to fully boot.

Very Respectfully,
Peter Geis

>
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  arch/arm64/boot/dts/rockchip/rk356x.dtsi | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> index 23949e79d8ce..0a1d07c96b2e 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> @@ -233,6 +233,7 @@
>                 #reset-cells = <1>;
>                 assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>;
>                 assigned-clock-rates = <1200000000>, <200000000>;
> +               rockchip,grf = <&grf>;
>         };
>
>         i2c0: i2c at fdd40000 {
> --
> 2.17.1
>


From claudiu.beznea at microchip.com  Mon Aug 23 06:19:11 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 16:19:11 +0300
Subject: [PATCH v2 0/4] ARM: at91: add new nodes to DT and fix for PM
Message-ID: <20210823131915.23857-1-claudiu.beznea@microchip.com>

Hi,

The following patches enable UDDRC, DDR3 PHY, SECURAM and SHDWC IPs
on SAMA7G5.

Besides this patch 1/1 avoid the panic on PM initialization code allowing
the system to boot when PM is enabled but not enough information is
provided in DT.

Thank you,
Claudiu Beznea

Changes in v2:
- changes cover letter title from
  "ARM: dts: at91: enable ips for sama7g5" to
  "ARM: at91: add new nodes to DT and fix for PM"
- update the device tree patches title and description
- added patch "ARM: at91: pm: do not panic if ram controllers are not
  enabled"

Claudiu Beznea (4):
  ARM: at91: pm: do not panic if ram controllers are not enabled
  ARM: dts: at91: sama7g5: add ram controllers
  ARM: dts: at91: sama7g5: add securam node
  ARM: dts: at91: sama7g5: add shdwc node

 arch/arm/boot/dts/at91-sama7g5ek.dts |  9 ++++
 arch/arm/boot/dts/sama7g5.dtsi       | 34 ++++++++++++
 arch/arm/mach-at91/pm.c              | 78 ++++++++++++++++++++++------
 3 files changed, 105 insertions(+), 16 deletions(-)

-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 23 06:19:12 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 16:19:12 +0300
Subject: [PATCH v2 1/4] ARM: at91: pm: do not panic if ram controllers are not
 enabled
In-Reply-To: <20210823131915.23857-1-claudiu.beznea@microchip.com>
References: <20210823131915.23857-1-claudiu.beznea@microchip.com>
Message-ID: <20210823131915.23857-2-claudiu.beznea@microchip.com>

In case PM is enabled but there is no RAM controller information
in DT the code will panic. Avoid such scenarios by not initializing
platform specific PM code in case RAM controller is not provided
via DT.

Reported-by: Eugen Hristev <eugen.hristev at microchip.com>
Fixes: 827de1f123ba0 ("ARM: at91: remove at91_dt_initialize and machine init_early()")
Fixes: 892e1f4a3ae58 ("ARM: at91: pm: add sama7g5 ddr phy controller")
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/mach-at91/pm.c | 78 ++++++++++++++++++++++++++++++++---------
 1 file changed, 62 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index d6cfe7c4bb00..d92afca64b49 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -589,18 +589,22 @@ static const struct of_device_id ramc_phy_ids[] __initconst = {
 	{ /* Sentinel. */ },
 };
 
-static __init void at91_dt_ramc(bool phy_mandatory)
+static __init int at91_dt_ramc(bool phy_mandatory)
 {
 	struct device_node *np;
 	const struct of_device_id *of_id;
 	int idx = 0;
 	void *standby = NULL;
 	const struct ramc_info *ramc;
+	int ret;
 
 	for_each_matching_node_and_match(np, ramc_ids, &of_id) {
 		soc_pm.data.ramc[idx] = of_iomap(np, 0);
-		if (!soc_pm.data.ramc[idx])
-			panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
+		if (!soc_pm.data.ramc[idx]) {
+			pr_err("unable to map ramc[%d] cpu registers\n", idx);
+			ret = -ENOMEM;
+			goto unmap_ramc;
+		}
 
 		ramc = of_id->data;
 		if (ramc) {
@@ -612,25 +616,42 @@ static __init void at91_dt_ramc(bool phy_mandatory)
 		idx++;
 	}
 
-	if (!idx)
-		panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
+	if (!idx) {
+		pr_err("unable to find compatible ram controller node in dtb\n");
+		ret = -ENODEV;
+		goto unmap_ramc;
+	}
 
 	/* Lookup for DDR PHY node, if any. */
 	for_each_matching_node_and_match(np, ramc_phy_ids, &of_id) {
 		soc_pm.data.ramc_phy = of_iomap(np, 0);
-		if (!soc_pm.data.ramc_phy)
-			panic(pr_fmt("unable to map ramc phy cpu registers\n"));
+		if (!soc_pm.data.ramc_phy) {
+			pr_err("unable to map ramc phy cpu registers\n");
+			ret = -ENOMEM;
+			goto unmap_ramc;
+		}
 	}
 
-	if (phy_mandatory && !soc_pm.data.ramc_phy)
-		panic(pr_fmt("DDR PHY is mandatory!\n"));
+	if (phy_mandatory && !soc_pm.data.ramc_phy) {
+		pr_err("DDR PHY is mandatory!\n");
+		ret = -ENODEV;
+		goto unmap_ramc;
+	}
 
 	if (!standby) {
 		pr_warn("ramc no standby function available\n");
-		return;
+		return 0;
 	}
 
 	at91_cpuidle_device.dev.platform_data = standby;
+
+	return 0;
+
+unmap_ramc:
+	while (idx)
+		iounmap(soc_pm.data.ramc[--idx]);
+
+	return ret;
 }
 
 static void at91rm9200_idle(void)
@@ -1017,6 +1038,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
 
 void __init at91rm9200_pm_init(void)
 {
+	int ret;
+
 	if (!IS_ENABLED(CONFIG_SOC_AT91RM9200))
 		return;
 
@@ -1028,7 +1051,9 @@ void __init at91rm9200_pm_init(void)
 	soc_pm.data.standby_mode = AT91_PM_STANDBY;
 	soc_pm.data.suspend_mode = AT91_PM_ULP0;
 
-	at91_dt_ramc(false);
+	ret = at91_dt_ramc(false);
+	if (ret)
+		return;
 
 	/*
 	 * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
@@ -1046,13 +1071,17 @@ void __init sam9x60_pm_init(void)
 	static const int iomaps[] __initconst = {
 		[AT91_PM_ULP1]		= AT91_PM_IOMAP(SHDWC),
 	};
+	int ret;
 
 	if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
 		return;
 
 	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
 	at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
-	at91_dt_ramc(false);
+	ret = at91_dt_ramc(false);
+	if (ret)
+		return;
+
 	at91_pm_init(NULL);
 
 	soc_pm.ws_ids = sam9x60_ws_ids;
@@ -1061,6 +1090,8 @@ void __init sam9x60_pm_init(void)
 
 void __init at91sam9_pm_init(void)
 {
+	int ret;
+
 	if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
 		return;
 
@@ -1072,7 +1103,10 @@ void __init at91sam9_pm_init(void)
 	soc_pm.data.standby_mode = AT91_PM_STANDBY;
 	soc_pm.data.suspend_mode = AT91_PM_ULP0;
 
-	at91_dt_ramc(false);
+	ret = at91_dt_ramc(false);
+	if (ret)
+		return;
+
 	at91_pm_init(at91sam9_idle);
 }
 
@@ -1081,12 +1115,16 @@ void __init sama5_pm_init(void)
 	static const int modes[] __initconst = {
 		AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST,
 	};
+	int ret;
 
 	if (!IS_ENABLED(CONFIG_SOC_SAMA5))
 		return;
 
 	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
-	at91_dt_ramc(false);
+	ret = at91_dt_ramc(false);
+	if (ret)
+		return;
+
 	at91_pm_init(NULL);
 }
 
@@ -1101,13 +1139,17 @@ void __init sama5d2_pm_init(void)
 		[AT91_PM_BACKUP]	= AT91_PM_IOMAP(SHDWC) |
 					  AT91_PM_IOMAP(SFRBU),
 	};
+	int ret;
 
 	if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
 		return;
 
 	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
 	at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
-	at91_dt_ramc(false);
+	ret = at91_dt_ramc(false);
+	if (ret)
+		return;
+
 	at91_pm_init(NULL);
 
 	soc_pm.ws_ids = sama5d2_ws_ids;
@@ -1127,13 +1169,17 @@ void __init sama7_pm_init(void)
 		[AT91_PM_BACKUP]	= AT91_PM_IOMAP(SFRBU) |
 					  AT91_PM_IOMAP(SHDWC),
 	};
+	int ret;
 
 	if (!IS_ENABLED(CONFIG_SOC_SAMA7))
 		return;
 
 	at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
 
-	at91_dt_ramc(true);
+	ret = at91_dt_ramc(true);
+	if (ret)
+		return;
+
 	at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
 	at91_pm_init(NULL);
 
-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 23 06:19:15 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 16:19:15 +0300
Subject: [PATCH v2 4/4] ARM: dts: at91: sama7g5: add shdwc node
In-Reply-To: <20210823131915.23857-1-claudiu.beznea@microchip.com>
References: <20210823131915.23857-1-claudiu.beznea@microchip.com>
Message-ID: <20210823131915.23857-5-claudiu.beznea@microchip.com>

Add shutdown controller node and enable it.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91-sama7g5ek.dts |  9 +++++++++
 arch/arm/boot/dts/sama7g5.dtsi       | 11 +++++++++++
 2 files changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts
index 4cbed98cc2f4..8b13b031a167 100644
--- a/arch/arm/boot/dts/at91-sama7g5ek.dts
+++ b/arch/arm/boot/dts/at91-sama7g5ek.dts
@@ -634,6 +634,15 @@ &sdmmc2 {
 	pinctrl-0 = <&pinctrl_sdmmc2_default>;
 };
 
+&shdwc {
+	atmel,shdwc-debouncer = <976>;
+	status = "okay";
+
+	input at 0 {
+		reg = <0>;
+	};
+};
+
 &spdifrx {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_spdifrx_default>;
diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index 3a4315ac0eb0..e50806cf7660 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -122,6 +122,17 @@ pmc: pmc at e0018000 {
 			clock-names = "td_slck", "md_slck", "main_xtal";
 		};
 
+		shdwc: shdwc at e001d010 {
+			compatible = "microchip,sama7g5-shdwc", "syscon";
+			reg = <0xe001d010 0x10>;
+			clocks = <&clk32k 0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			atmel,wakeup-rtc-timer;
+			atmel,wakeup-rtt-timer;
+			status = "disabled";
+		};
+
 		rtt: rtt at e001d020 {
 			compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
 			reg = <0xe001d020 0x30>;
-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 23 06:19:14 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 16:19:14 +0300
Subject: [PATCH v2 3/4] ARM: dts: at91: sama7g5: add securam node
In-Reply-To: <20210823131915.23857-1-claudiu.beznea@microchip.com>
References: <20210823131915.23857-1-claudiu.beznea@microchip.com>
Message-ID: <20210823131915.23857-4-claudiu.beznea@microchip.com>

Add securam node.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/sama7g5.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index ecabab4343b6..3a4315ac0eb0 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -75,6 +75,17 @@ soc {
 		#size-cells = <1>;
 		ranges;
 
+		securam: securam at e0000000 {
+			compatible = "microchip,sama7g5-securam", "atmel,sama5d2-securam", "mmio-sram";
+			reg = <0xe0000000 0x4000>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 18>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0xe0000000 0x4000>;
+			no-memory-wc;
+			status = "okay";
+		};
+
 		secumod: secumod at e0004000 {
 			compatible = "microchip,sama7g5-secumod", "atmel,sama5d2-secumod", "syscon";
 			reg = <0xe0004000 0x4000>;
-- 
2.25.1



From claudiu.beznea at microchip.com  Mon Aug 23 06:19:13 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 23 Aug 2021 16:19:13 +0300
Subject: [PATCH v2 2/4] ARM: dts: at91: sama7g5: add ram controllers
In-Reply-To: <20210823131915.23857-1-claudiu.beznea@microchip.com>
References: <20210823131915.23857-1-claudiu.beznea@microchip.com>
Message-ID: <20210823131915.23857-3-claudiu.beznea@microchip.com>

Add RAM and RAMC PHY controllers. These are necessary for platform
specific power management code.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/sama7g5.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index cc6be6db7b80..ecabab4343b6 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -515,6 +515,18 @@ spi11: spi at 400 {
 			};
 		};
 
+		uddrc: uddrc at e3800000 {
+			compatible = "microchip,sama7g5-uddrc";
+			reg = <0xe3800000 0x4000>;
+			status = "okay";
+		};
+
+		ddr3phy: ddr3phy at e3804000 {
+			compatible = "microchip,sama7g5-ddr3phy";
+			reg = <0xe3804000 0x1000>;
+			status = "okay";
+		};
+
 		gic: interrupt-controller at e8c11000 {
 			compatible = "arm,cortex-a7-gic";
 			#interrupt-cells = <3>;
-- 
2.25.1



From ezequiel at vanguardiasur.com.ar  Mon Aug 23 06:29:33 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 23 Aug 2021 10:29:33 -0300
Subject: [PATCH] arm64: dts: rockchip: Re-add interrupt-names for RK3399's
 vpu
In-Reply-To: <24767661.6Emhk5qWAg@phil>
References: <20210822115755.3171937-1-knaerzche@gmail.com>
 <CAAEAJfDLvctAk3omLgFBBbzvufFKwSW5_cQZ+MjvyN4khGOe_w@mail.gmail.com>
 <24767661.6Emhk5qWAg@phil>
Message-ID: <CAAEAJfA0QGcDJLOh=-zZKnd7=UFchDAqkK+OSMgm4yv524OHuA@mail.gmail.com>

On Sun, 22 Aug 2021 at 17:25, Heiko Stuebner <heiko at sntech.de> wrote:
>
> Hi,
>
> Am Sonntag, 22. August 2021, 16:37:24 CEST schrieb Ezequiel Garcia:
> > Hi Alex, Heiko,
> >
> > On Sun, 22 Aug 2021 at 08:58, Alex Bee <knaerzche at gmail.com> wrote:
> > >
> > > Commit a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
> > > intended to remove the interrupt-names property for mmu nodes, but it
> > > also removed it for the vpu node in rk3399.dtsi. That makes the driver
> > > fail probing currently.
> > > Fix this by re-adding the property for this node.
> > >
> > > Fixes: a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
> >
> > AFAICS a728c10dd62a removed lots of interrupt-names properties
> > from devices other than IOMMU.
> >
> > Maybe it's best to revert it?
>
> where did you see more mistakes in it?
>
> I.e. first of all, at least when grepping through my kernel history, I only see
>   commit 53a05c8f6e8e ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
> with a different hash and at least there I see a lot of iommu interrupt removals
> and this one line removing the vpu irqs in error.
>
> So from my glance at it, applying Alex' patch should solve the issue?
>

Ah, seems you are right. Sorry for the noise!

Thanks,
Ezequiel


From leo.yan at linaro.org  Mon Aug 23 06:30:43 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 23 Aug 2021 21:30:43 +0800
Subject: [PATCH v1 3/3] perf auxtrace arm: Support
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <6ce4057a-57cf-501d-6449-2069cd00ba57@arm.com>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-4-leo.yan@linaro.org>
 <6ce4057a-57cf-501d-6449-2069cd00ba57@arm.com>
Message-ID: <20210823133043.GF100516@leoy-ThinkPad-X240s>

Hi James,

On Mon, Aug 23, 2021 at 01:23:42PM +0100, James Clark wrote:
> 
> 
> On 09/08/2021 12:27, Leo Yan wrote:
> > When the tool runs with compat mode on Arm platform, the kernel is in
> > 64-bit mode and user space is in 32-bit mode; the user space can use
> > instructions "ldrd" and "strd" for 64-bit value atomicity.
> > 
> > This patch adds compat_auxtrace_mmap__{read_head|write_tail} for arm
> > building, it uses "ldrd" and "strd" instructions to ensure accessing
> > atomicity for aux head and tail.  The file arch/arm/util/auxtrace.c is
> > built for arm and arm64 building, these two functions are not needed for
> > arm64, so check the compiler macro "__arm__" to only include them for
> > arm building.
> > 
> > Signed-off-by: Leo Yan <leo.yan at linaro.org>
> > ---
> >  tools/perf/arch/arm/util/auxtrace.c | 32 +++++++++++++++++++++++++++++
> >  1 file changed, 32 insertions(+)
> > 
> > diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c
> > index b187bddbd01a..c7c7ec0812d5 100644
> > --- a/tools/perf/arch/arm/util/auxtrace.c
> > +++ b/tools/perf/arch/arm/util/auxtrace.c
> > @@ -107,3 +107,35 @@ struct auxtrace_record
> >  	*err = 0;
> >  	return NULL;
> >  }
> > +
> > +#if defined(__arm__)
> > +u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> > +{
> > +	struct perf_event_mmap_page *pc = mm->userpg;
> > +	u64 result;
> > +
> > +	__asm__ __volatile__(
> > +"	ldrd    %0, %H0, [%1]"
> > +	: "=&r" (result)
> > +	: "r" (&pc->aux_head), "Qo" (pc->aux_head)
> > +	);
> > +
> > +	return result;
> > +}
> 
> Hi Leo,
> 
> I see that this is a duplicate of the atomic read in arch/arm/include/asm/atomic.h

Exactly.

> For x86, it's possible to include tools/include/asm/atomic.h, but that doesn't
> include arch/arm/include/asm/atomic.h and there are some other #ifdefs that might
> make it not so easy for Arm. Just wondering if you considered trying to include the
> existing one? Or decided that it was easier to duplicate it?

Good finding!

With you reminding, I recognized that the atomic operations for
arm/arm64 should be improved for user space program.  So far, perf tool
simply uses the compiler's atomic implementations (from
asm-generic/atomic-gcc.h) for arm/arm64; but for a more reliable
implementation, I think we should improve the user space program with
architecture's atomic instructions.

So I think your question should be converted to: should we export the
arm/arm64 atomicity operations to user space program?  Seems to me this
is a challenge work, we need at least to finish below items:

- Support arm64 atomic operations and reuse kernel's
  arch/arm/include/asm/atomic.h;
- Support arm atomic operation and reuse kernel's
  arch/arm/include/asm/atomic.h;
- For aarch32 building, we need to use configurations to distinguish
  different cases, like LPAE, Armv7, and ARMv6 variants (so far I have
  no idea how to use a graceful way to distinguish these different
  building in perf tool).

I am not sure if there have any existed ongoing effort for this part,
if anyone is working on this (or before have started related work),
then definitely we should look into how we can reuse the arch's
atomic headers.

Otherwise, I prefer to firstly merge this patch with dozen lines of
duplicate code; afterwards, we can send a separate patch set to
support arm/arm64 atomic operations in user space.

If any Arm/Arm64 maintainers could shed some light for this part work,
I think it would be very helpful.

> Other than that, I have tested that the change works with a 32bit build with snapshot
> and normal mode.
> 
> Reviewed by: James Clark <james.clark at arm.com>
> Tested by: James Clark <james.clark at arm.com>

Thanks for test and review!

Leo


From michael.riesch at wolfvision.net  Mon Aug 23 06:39:13 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 23 Aug 2021 15:39:13 +0200
Subject: [PATCH 1/1] arm64: dts: rockchip: add missing rockchip,grf
 property to rk356x
In-Reply-To: <CAMdYzYr4ZTXvfJaeMejuRHBkBAVKcEUseskhEVqLMSYR+Dv4uw@mail.gmail.com>
References: <20210823123911.12095-1-michael.riesch@wolfvision.net>
 <20210823123911.12095-2-michael.riesch@wolfvision.net>
 <CAMdYzYr4ZTXvfJaeMejuRHBkBAVKcEUseskhEVqLMSYR+Dv4uw@mail.gmail.com>
Message-ID: <426f77fb-f0ca-9431-45e4-66b885516c76@wolfvision.net>

Hi Peter,

On 8/23/21 3:12 PM, Peter Geis wrote:
> On Mon, Aug 23, 2021 at 8:39 AM Michael Riesch
> <michael.riesch at wolfvision.net> wrote:
>>
>> This commit fixes the error messages
>>
>>   rockchip_clk_register_muxgrf: regmap not available
>>   rockchip_clk_register_branches: failed to register clock clk_ddr1x: -524
>>
>> during boot by providing the missing rockchip,grf property.
> 
> Good Morning,
> 
> This was fixed by commit: 6fffe52fb336 clk: rockchip: drop GRF
> dependency for rk3328/rk3036 pll types
> which was merged in -next. I don't believe it's going to be backported
> to 5.14 due to 5.14 not being able to fully boot.

Unfortunately not, I am afraid. I am working on Heiko's current -next
and the commit you mentioned is present. Nevertheless I got these error
messages.

They can be traced down to "rockchip_clk_register_muxgrf", which fails
as the passed argument regmap is invalid due to the missing device tree
property. The clock "clk_ddr1x" is added in clk-rk3568.c as "MUXGRF",
which leads me to believe that the grf property is actually required.

Best regards,
Michael

> 
> Very Respectfully,
> Peter Geis
> 
>>
>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>> ---
>>  arch/arm64/boot/dts/rockchip/rk356x.dtsi | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> index 23949e79d8ce..0a1d07c96b2e 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> @@ -233,6 +233,7 @@
>>                 #reset-cells = <1>;
>>                 assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>;
>>                 assigned-clock-rates = <1200000000>, <200000000>;
>> +               rockchip,grf = <&grf>;
>>         };
>>
>>         i2c0: i2c at fdd40000 {
>> --
>> 2.17.1
>>


From linux at armlinux.org.uk  Mon Aug 23 06:39:18 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 23 Aug 2021 14:39:18 +0100
Subject: [PATCH v1 3/3] perf auxtrace arm: Support
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210823133043.GF100516@leoy-ThinkPad-X240s>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-4-leo.yan@linaro.org>
 <6ce4057a-57cf-501d-6449-2069cd00ba57@arm.com>
 <20210823133043.GF100516@leoy-ThinkPad-X240s>
Message-ID: <20210823133918.GP22278@shell.armlinux.org.uk>

On Mon, Aug 23, 2021 at 09:30:43PM +0800, Leo Yan wrote:
> Hi James,
> 
> On Mon, Aug 23, 2021 at 01:23:42PM +0100, James Clark wrote:
> > 
> > 
> > On 09/08/2021 12:27, Leo Yan wrote:
> > > When the tool runs with compat mode on Arm platform, the kernel is in
> > > 64-bit mode and user space is in 32-bit mode; the user space can use
> > > instructions "ldrd" and "strd" for 64-bit value atomicity.
> > > 
> > > This patch adds compat_auxtrace_mmap__{read_head|write_tail} for arm
> > > building, it uses "ldrd" and "strd" instructions to ensure accessing
> > > atomicity for aux head and tail.  The file arch/arm/util/auxtrace.c is
> > > built for arm and arm64 building, these two functions are not needed for
> > > arm64, so check the compiler macro "__arm__" to only include them for
> > > arm building.
> > > 
> > > Signed-off-by: Leo Yan <leo.yan at linaro.org>
> > > ---
> > >  tools/perf/arch/arm/util/auxtrace.c | 32 +++++++++++++++++++++++++++++
> > >  1 file changed, 32 insertions(+)
> > > 
> > > diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c
> > > index b187bddbd01a..c7c7ec0812d5 100644
> > > --- a/tools/perf/arch/arm/util/auxtrace.c
> > > +++ b/tools/perf/arch/arm/util/auxtrace.c
> > > @@ -107,3 +107,35 @@ struct auxtrace_record
> > >  	*err = 0;
> > >  	return NULL;
> > >  }
> > > +
> > > +#if defined(__arm__)
> > > +u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
> > > +{
> > > +	struct perf_event_mmap_page *pc = mm->userpg;
> > > +	u64 result;
> > > +
> > > +	__asm__ __volatile__(
> > > +"	ldrd    %0, %H0, [%1]"
> > > +	: "=&r" (result)
> > > +	: "r" (&pc->aux_head), "Qo" (pc->aux_head)
> > > +	);
> > > +
> > > +	return result;
> > > +}
> > 
> > Hi Leo,
> > 
> > I see that this is a duplicate of the atomic read in arch/arm/include/asm/atomic.h
> 
> Exactly.
> 
> > For x86, it's possible to include tools/include/asm/atomic.h, but that doesn't
> > include arch/arm/include/asm/atomic.h and there are some other #ifdefs that might
> > make it not so easy for Arm. Just wondering if you considered trying to include the
> > existing one? Or decided that it was easier to duplicate it?
> 
> Good finding!
> 
> With you reminding, I recognized that the atomic operations for
> arm/arm64 should be improved for user space program.  So far, perf tool
> simply uses the compiler's atomic implementations (from
> asm-generic/atomic-gcc.h) for arm/arm64; but for a more reliable
> implementation, I think we should improve the user space program with
> architecture's atomic instructions.

No we should not. Sometimes, what's in the kernel is for the kernel's
use only, and not for userspace's use. That may be because what works
in kernel space does not work in userspace.

For example, the ARMv6+ atomic operations can be executed in userspace
_provided_ they are only used on memory which has an exclusive monitor.
They can't be used on anything that is not "normal memory". Prior to
ARMv6, the atomic operations rely on disabling interrupts. That
facility is simply not available to userspace, so these must not be
made available to userspace.

The same applies to bitops.

We've been here before in the past, when the kernel headers were not
separated from the user ABI headers, and people would write programs
that included e.g. bitops.h on x86 because they had optimised bitops
code. This made the userspace programs very non-portable - without
re-implementing userspace versions of this stuff in every userspace
program that did this stuff.

So no, having experienced the effects of this kind of thing in the
past, the kernel should _not_ export architecture specific code in
header files to userspace.

Also, it should be pointed out that by doing so, you create a licensing
issue. If the code is GPLv2, and you build your program such that it
incorporates GPLv2 code, then if the userspace program is not GPLv2
compliant, you have a licensing problem, and in effect the program
can be distributed.

Please do not go down this route.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From james.quinlan at broadcom.com  Mon Aug 23 06:44:47 2021
From: james.quinlan at broadcom.com (Jim Quinlan)
Date: Mon, 23 Aug 2021 09:44:47 -0400
Subject: [PATCH] PCI: brcmstb: implement BCM4908 support
In-Reply-To: <20210816125029.16879-1-zajec5@gmail.com>
References: <20210816125029.16879-1-zajec5@gmail.com>
Message-ID: <CA+-6iNxOa0uGSwoySWgfVn3wZw5jh6d3R2oHgVGs5NsQmt+=qA@mail.gmail.com>

Hello,
Some comments below...


On Mon, Aug 16, 2021 at 8:51 AM Rafa? Mi?ecki <zajec5 at gmail.com> wrote:
>
> From: Rafa? Mi?ecki <rafal at milecki.pl>
>
> BCM4908 is Broadcom's 64-bit platform with Broadcom's own Brahma-B53
> CPU(s). It uses the same PCIe hardware block as STB (Set-Top-Box) family
> but in a slightly different revision & setup.
>
> Registers in BCM4908 variant are mostly the same but controller setup
> differs a bit. It requires setting few extra registers and takes
> slightly different bars setup.
>
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  drivers/pci/controller/pcie-brcmstb.c | 137 +++++++++++++++++++++++---
>  1 file changed, 123 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
> index cc30215f5a43..24bc7efcfdd5 100644
> --- a/drivers/pci/controller/pcie-brcmstb.c
> +++ b/drivers/pci/controller/pcie-brcmstb.c
> @@ -51,15 +51,20 @@
>  #define PCIE_RC_DL_MDIO_RD_DATA                                0x1108
>
>  #define PCIE_MISC_MISC_CTRL                            0x4008
> +#define  PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE         0x00000080
> +#define  PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE         0x00000400
> +#define  PCIE_MISC_MISC_CTRL_PCIE_IN_WR_COMBINE                0x00000800
>  #define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK                0x1000
>  #define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK     0x2000
>  #define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK       0x300000
> +#define  PCIE_MISC_MISC_CTRL_BURST_ALIGN_MASK          0x00080000
>
>  #define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK            0xf8000000
>  #define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK            0x07c00000
>  #define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK            0x0000001f
>  #define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
>
> +
Extra WS

>  #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO               0x400c
>  #define PCIE_MEM_WIN0_LO(win)  \
>                 PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
> @@ -115,6 +120,9 @@
>  #define PCIE_MEM_WIN0_LIMIT_HI(win)    \
>                 PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
>
> +#define PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_OFFSET                0x40ac
> +#define  PCIE_MISC_UBUS_BAR_CONFIG_ACCESS_EN           0x00000001
> +
>  #define PCIE_MISC_HARD_PCIE_HARD_DEBUG                                 0x4204
>  #define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK       0x2
>  #define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK               0x08000000
> @@ -131,6 +139,13 @@
>  #define PCIE_EXT_CFG_DATA                              0x8000
>  #define PCIE_EXT_CFG_INDEX                             0x9000
>
> +#define PCIE_CPU_INTR1_INTR_MASK_CLEAR_OFFSET          0x940c
> +#define  PCIE_CPU_INTR1_PCIE_INTA_CPU_INTR             0x00000002
> +#define  PCIE_CPU_INTR1_PCIE_INTB_CPU_INTR             0x00000004
> +#define  PCIE_CPU_INTR1_PCIE_INTC_CPU_INTR             0x00000008
> +#define  PCIE_CPU_INTR1_PCIE_INTD_CPU_INTR             0x00000010
> +#define  PCIE_CPU_INTR1_PCIE_INTR_CPU_INTR             0x00000020
> +
>  #define  PCIE_RGR1_SW_INIT_1_PERST_MASK                        0x1
>  #define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT               0x0
>
> @@ -746,13 +761,19 @@ static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32
>
>  static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
>  {
> -       if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
> -               return;
> +       if (pcie->hw_rev >= BRCM_PCIE_HW_REV_3_20) {
> +               brcm_pcie_perst_set_7278(pcie, val);
> +       } else {
> +               if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
> +                       return;
Is this necessary?  Better to just assume it is there and call the
assert/deassrt routines always as they work on NULL.
>
> -       if (val)
> -               reset_control_assert(pcie->perst_reset);
> -       else
> -               reset_control_deassert(pcie->perst_reset);
> +               if (val)
> +                       reset_control_assert(pcie->perst_reset);
> +               else
> +                       reset_control_deassert(pcie->perst_reset);
> +       }
> +
> +       usleep_range(10000, 20000);
Why so long?  And does it need to be long for both directions (assert/deassert)?

>  }
>
>  static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
> @@ -861,6 +882,86 @@ static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
>         return 0;
>  }
>
> +static int brcm_pcie_setup_bcm4908(struct brcm_pcie *pcie)
> +{
> +       struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
> +       void __iomem *base = pcie->base;
> +       struct device *dev = pcie->dev;
> +       struct resource_entry *entry;
> +       u32 burst_align;
> +       u32 burst;
> +       u32 tmp;
> +       int win;
> +
> +       pcie->perst_set(pcie, 0);
> +
> +       msleep(500);
> +
> +       if (!brcm_pcie_link_up(pcie)) {
> +               dev_err(dev, "link down\n");
> +               return -ENODEV;
> +       }
> +
> +       /* setup lgacy outband interrupts */
> +       tmp = PCIE_CPU_INTR1_PCIE_INTA_CPU_INTR |
> +             PCIE_CPU_INTR1_PCIE_INTB_CPU_INTR |
> +             PCIE_CPU_INTR1_PCIE_INTC_CPU_INTR |
> +             PCIE_CPU_INTR1_PCIE_INTD_CPU_INTR;
> +       writel(tmp, base + PCIE_CPU_INTR1_INTR_MASK_CLEAR_OFFSET);
Shouldn't this be taken care of by the interrupt-map and interrupt-map
mask properties of the PCIe DT node?  For example, most of our STB
chips use something like this:

interrupt-map-mask = <0x0 0x0 0x0 0x7>;
interrupt-map = <
0 0 0 1 &intc 0 44 4
0 0 0 2 &intc 0 45 4
0 0 0 3 &intc 0 46 4
0 0 0 4 &intc 0 47 4>;

If you  don't have an interrupt controller DT node/driver, try looking
at the existing BRCM ones or you  may have to craft your own.

> +
> +       win = 0;
> +       resource_list_for_each_entry(entry, &bridge->windows) {
> +               struct resource *res = entry->res;
> +               u64 pcie_addr;
> +
> +               if (resource_type(res) != IORESOURCE_MEM)
> +                       continue;
> +
> +               if (win >= BRCM_NUM_PCIE_OUT_WINS) {
> +                       dev_err(pcie->dev, "too many outbound wins\n");
> +                       return -EINVAL;
> +               }
> +
> +               tmp = 0;
> +               u32p_replace_bits(&tmp, res->start / SZ_1M,
> +                                 PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK);
> +               u32p_replace_bits(&tmp, res->end / SZ_1M,
> +                                 PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK);
> +               writel(tmp, base + PCIE_MEM_WIN0_BASE_LIMIT(win));
> +
> +               pcie_addr = res->start - entry->offset;
> +               writel(lower_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_LO(win));
> +               writel(upper_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_HI(win));
Again, can you try using the PCIe DT ranges/dma-ranges node properties
instead?

> +
> +               win++;
> +       }
> +
> +       writel(0xf, base + PCIE_MISC_RC_BAR1_CONFIG_LO);
> +
> +       tmp = PCIE_MISC_UBUS_BAR_CONFIG_ACCESS_EN;
> +       writel(tmp, base + PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_OFFSET);
> +
> +       tmp = readl(base + PCIE_RC_CFG_PRIV1_ID_VAL3);
> +       u32p_replace_bits(&tmp, PCI_CLASS_BRIDGE_PCI << 8,
> +                         PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK);
> +       writel(tmp, base + PCIE_RC_CFG_PRIV1_ID_VAL3);
Isn't this already in the driver?  If it is, you should at least make
it a function and call it -- the same code should not exist in
multiple places.

> +
> +       /* Burst */
> +       burst = 0x1; /* 128 B */
> +       burst_align = 1;
> +
> +       tmp = readl(base + PCIE_MISC_MISC_CTRL);if (
> +       u32p_replace_bits(&tmp, burst_align, PCIE_MISC_MISC_CTRL_BURST_ALIGN_MASK);
> +       u32p_replace_bits(&tmp, burst, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK);
> +       u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK);
> +       u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_IN_WR_COMBINE);
> +       u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE);
> +       u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE);
It would be better if you could use the vanilla brcm_pcie_setup()
function and do something like
if (pcie->type == BCM4908)
    do_this();
else
    /* ... */

> +       writel(tmp, base + PCIE_MISC_MISC_CTRL);
> +
> +       return 0;
> +}
> +
>  static int brcm_pcie_setup(struct brcm_pcie *pcie)
>  {
>         struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
> @@ -1284,6 +1385,13 @@ static int brcm_pcie_probe(struct platform_device *pdev)
>                 return PTR_ERR(pcie->perst_reset);
>         }
>
> +       if (pcie->type == BCM4908) {
> +               /* On BCM4908 we can read rev early and perst_set needs it */
> +               pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION);
We might as well do this in all cases, no need for the 4908 qualifier.

> +
> +               pcie->perst_set(pcie, 1); +               writel(lower_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_LO(win));
> +               writel(upper_32_bits(pcie_addr), pcie->base + PCIE_MEM_WIN0_HI(win));
Again, can you try using the PCIe DT ranges/dma-ranges node properties instead?

> +
> +               win++;
> +       }
> +
> +       writel(0xf, base + PCIE_MISC_RC_BAR1_CONFIG_LO);
> +
> +       tmp = PCIE_MISC_UBUS_BAR_CONFIG_ACCESS_EN;
> +       writel(tmp, base + PCIE_MISC_UBUS_BAR1_CONFIG_REMAP_OFFSET);
> +
> +       tmp = readl(base + PCIE_RC_CFG_PRIV1_ID_VAL3);
> +       u32p_replace_bits(&tmp, PCI_CLASS_BRIDGE_PCI << 8,
> +                         PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK);
> +       writel(tmp, base + PCIE_RC_CFG_PRIV1_ID_VAL3);
Isn't this already in the driver?  If it is, it you should at least
make it a function and call it -- the same code should not exist in
multiple places.

> +
> +       /* Burst */
> +       burst = 0x1; /* 128 B */
> +       burst_align = 1;
> +
> +       tmp = readl(base + PCIE_MISC_MISC_CTRL);if (
> +       u32p_replace_bits(&tmp, burst_align, PCIE_MISC_MISC_CTRL_BURST_ALIGN_MASK);
> +       u32p_replace_bits(&tmp, burst, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK);
> +       u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK);
> +       u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_IN_WR_COMBINE);
> +       u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_MPS_MODE);
> +       u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_PCIE_RCB_64B_MODE);
It would be better if you could use the vanilla brcm_pcie_setup()
function and do something like
if (pcie->type == BCM4908)
    do_this();
else
    /* ... */

> +       writel(tmp, base + PCIE_MISC_MISC_CTRL);
> +
b
> +       }
> +
>         ret = reset_control_reset(pcie->rescal);
>         if (ret)
>                 dev_err(&pdev->dev, "failed to deassert 'rescal'\n");
> @@ -1295,16 +1403,17 @@ static int brcm_pcie_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> -       ret = brcm_pcie_setup(pcie);
> -       if (ret)
> -               goto fail;
> +       if (pcie->type == BCM4908) {
> +               ret = brcm_pcie_setup_bcm4908(pcie);
> +               if (ret)
> +                       goto fail;
> +       } else {
> +               ret = brcm_pcie_setup(pcie);
> +               if (ret)
> +                       goto fail;
> +       }
As Florian said, try to use the existing routine with clauses for
4908-specific code.

Regards,
Jim Quinlan, Broadcom STB
>
>         pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION);
> -       if (pcie->type == BCM4908 && pcie->hw_rev >= BRCM_PCIE_HW_REV_3_20) {
> -               dev_err(pcie->dev, "hardware revision with unsupported PERST# setup\n");
> -               ret = -ENODEV;
> -               goto fail;
> -       }
>
>         msi_np = of_parse_phandle(pcie->np, "msi-parent", 0);
>         if (pci_msi_enabled() && msi_np == pcie->np) {
> --
> 2.26.2
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4210 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210823/c74c3bec/attachment-0001.p7s>

From pgwipeout at gmail.com  Mon Aug 23 06:51:33 2021
From: pgwipeout at gmail.com (Peter Geis)
Date: Mon, 23 Aug 2021 09:51:33 -0400
Subject: [PATCH 1/1] arm64: dts: rockchip: add missing rockchip,grf
 property to rk356x
In-Reply-To: <426f77fb-f0ca-9431-45e4-66b885516c76@wolfvision.net>
References: <20210823123911.12095-1-michael.riesch@wolfvision.net>
 <20210823123911.12095-2-michael.riesch@wolfvision.net>
 <CAMdYzYr4ZTXvfJaeMejuRHBkBAVKcEUseskhEVqLMSYR+Dv4uw@mail.gmail.com>
 <426f77fb-f0ca-9431-45e4-66b885516c76@wolfvision.net>
Message-ID: <CAMdYzYpSHkW3NDztmw=CUbYbqQFP+qYdavr6AQZfxwmWJ4eYAw@mail.gmail.com>

On Mon, Aug 23, 2021 at 9:39 AM Michael Riesch
<michael.riesch at wolfvision.net> wrote:
>
> Hi Peter,
>
> On 8/23/21 3:12 PM, Peter Geis wrote:
> > On Mon, Aug 23, 2021 at 8:39 AM Michael Riesch
> > <michael.riesch at wolfvision.net> wrote:
> >>
> >> This commit fixes the error messages
> >>
> >>   rockchip_clk_register_muxgrf: regmap not available
> >>   rockchip_clk_register_branches: failed to register clock clk_ddr1x: -524
> >>
> >> during boot by providing the missing rockchip,grf property.
> >
> > Good Morning,
> >
> > This was fixed by commit: 6fffe52fb336 clk: rockchip: drop GRF
> > dependency for rk3328/rk3036 pll types
> > which was merged in -next. I don't believe it's going to be backported
> > to 5.14 due to 5.14 not being able to fully boot.
>
> Unfortunately not, I am afraid. I am working on Heiko's current -next
> and the commit you mentioned is present. Nevertheless I got these error
> messages.
>
> They can be traced down to "rockchip_clk_register_muxgrf", which fails
> as the passed argument regmap is invalid due to the missing device tree
> property. The clock "clk_ddr1x" is added in clk-rk3568.c as "MUXGRF",
> which leads me to believe that the grf property is actually required.

Ah, yes it seems you are correct.
I had inadvertently fixed this a while ago in my own tree.
Confirmed without the GRF ddr1x clk doesn't register.

Tested-by: Peter Geis <pgwipeout at gmail.com>

On a related note, are you planning on working on the DVFS driver,
since it will be the only consumer of this clock?

>
> Best regards,
> Michael
>
> >
> > Very Respectfully,
> > Peter Geis
> >
> >>
> >> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> >> ---
> >>  arch/arm64/boot/dts/rockchip/rk356x.dtsi | 1 +
> >>  1 file changed, 1 insertion(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >> index 23949e79d8ce..0a1d07c96b2e 100644
> >> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >> @@ -233,6 +233,7 @@
> >>                 #reset-cells = <1>;
> >>                 assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>;
> >>                 assigned-clock-rates = <1200000000>, <200000000>;
> >> +               rockchip,grf = <&grf>;
> >>         };
> >>
> >>         i2c0: i2c at fdd40000 {
> >> --
> >> 2.17.1
> >>


From benjamin.gaignard at collabora.com  Mon Aug 23 06:56:06 2021
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Mon, 23 Aug 2021 15:56:06 +0200
Subject: [PATCH] media: hantro: Trace hevc hw cycles performance register
Message-ID: <20210823135606.633052-1-benjamin.gaignard@collabora.com>

After each hevc decoded frame trace the hardware performance.
It provides the number of hw cycles spend per decoded macroblock.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 Documentation/admin-guide/media/hantro.rst    | 14 +++++++
 .../admin-guide/media/v4l-drivers.rst         |  1 +
 drivers/staging/media/hantro/hantro_drv.c     |  3 ++
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 16 ++++++++
 drivers/staging/media/hantro/hantro_g2_regs.h |  1 +
 drivers/staging/media/hantro/hantro_hw.h      |  1 +
 drivers/staging/media/hantro/hantro_trace.h   | 41 +++++++++++++++++++
 drivers/staging/media/hantro/imx8m_vpu_hw.c   |  1 +
 8 files changed, 78 insertions(+)
 create mode 100644 Documentation/admin-guide/media/hantro.rst
 create mode 100644 drivers/staging/media/hantro/hantro_trace.h

diff --git a/Documentation/admin-guide/media/hantro.rst b/Documentation/admin-guide/media/hantro.rst
new file mode 100644
index 000000000000..6cb552a5dfcb
--- /dev/null
+++ b/Documentation/admin-guide/media/hantro.rst
@@ -0,0 +1,14 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+The hantro driver
+=================
+
+Trace
+~~~~~
+
+You can trace the hardware decoding performances by using event tracing::
+
+    # echo hantro_hevc_perf >> /sys/kernel/debug/tracing/set_event
+
+That will keep a log of the number of hardware cycles spend per decoded macroblock
diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst
index 9c7ebe2ca3bd..4f2f72a2b3b5 100644
--- a/Documentation/admin-guide/media/v4l-drivers.rst
+++ b/Documentation/admin-guide/media/v4l-drivers.rst
@@ -15,6 +15,7 @@ Video4Linux (V4L) driver-specific documentation
 	cx88
 	davinci-vpbe
 	fimc
+        hantro
 	imx
 	imx7
 	ipu3
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index 8a2edd67f2c6..236160c51e59 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -28,6 +28,9 @@
 #include "hantro.h"
 #include "hantro_hw.h"
 
+#define CREATE_TRACE_POINTS
+#include "hantro_trace.h"
+
 #define DRIVER_NAME "hantro-vpu"
 
 int hantro_debug;
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 340efb57fd18..fef16d1724da 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -7,6 +7,7 @@
 
 #include "hantro_hw.h"
 #include "hantro_g2_regs.h"
+#include "hantro_trace.h"
 
 #define HEVC_DEC_MODE	0xC
 
@@ -22,6 +23,21 @@ static inline void hantro_write_addr(struct hantro_dev *vpu,
 	vdpu_write(vpu, addr & 0xffffffff, offset);
 }
 
+void hantro_g2_hevc_dec_done(struct hantro_ctx *ctx)
+{
+	const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
+	const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
+	struct hantro_dev *vpu = ctx->dev;
+	u32 hw_cycles = 0;
+	u32 mbs = (sps->pic_width_in_luma_samples *
+		   sps->pic_height_in_luma_samples) >> 8;
+
+	if (mbs)
+		hw_cycles = vdpu_read(vpu, G2_HW_PERFORMANCE) / mbs;
+
+	trace_hantro_hevc_perf(ctx, hw_cycles);
+}
+
 static void prepare_tile_info_buffer(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h
index bb22fa921914..17d84ec9c5c2 100644
--- a/drivers/staging/media/hantro/hantro_g2_regs.h
+++ b/drivers/staging/media/hantro/hantro_g2_regs.h
@@ -177,6 +177,7 @@
 #define G2_REG_CONFIG_DEC_CLK_GATE_E		BIT(16)
 #define G2_REG_CONFIG_DEC_CLK_GATE_IDLE_E	BIT(17)
 
+#define G2_HW_PERFORMANCE	(G2_SWREG(63))
 #define G2_ADDR_DST		(G2_SWREG(65))
 #define G2_REG_ADDR_REF(i)	(G2_SWREG(67)  + ((i) * 0x8))
 #define G2_ADDR_DST_CHR		(G2_SWREG(99))
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index df7b5e3a57b9..ab6f379354cc 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -250,6 +250,7 @@ void hantro_h264_dec_exit(struct hantro_ctx *ctx);
 int hantro_hevc_dec_init(struct hantro_ctx *ctx);
 void hantro_hevc_dec_exit(struct hantro_ctx *ctx);
 int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx);
+void hantro_g2_hevc_dec_done(struct hantro_ctx *ctx);
 int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
 dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
 void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
diff --git a/drivers/staging/media/hantro/hantro_trace.h b/drivers/staging/media/hantro/hantro_trace.h
new file mode 100644
index 000000000000..fa8fec26fa3c
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_trace.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if !defined(__HANTRO_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ)
+#define __HANTRO_TRACE_H__
+
+#include <linux/tracepoint.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "hantro.h"
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM hantro
+#define TRACE_INCLUDE_FILE hantro_trace
+
+TRACE_EVENT(hantro_hevc_perf,
+	TP_PROTO(struct hantro_ctx *ctx, u32 hw_cycles),
+
+	TP_ARGS(ctx, hw_cycles),
+
+	TP_STRUCT__entry(
+		__field(int, minor)
+		__field(struct v4l2_fh *, fh)
+		__field(u32, hw_cycles)
+	),
+
+	TP_fast_assign(
+		__entry->minor = ctx->fh.vdev->minor;
+		__entry->fh = &ctx->fh;
+		__entry->hw_cycles = hw_cycles;
+	),
+
+	TP_printk("minor = %d, fh = %p, %8d cycles / mb",
+		  __entry->minor, __entry->fh, __entry->hw_cycles)
+);
+
+#endif /* __HANTRO_TRACE_H__ */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../drivers/staging/media/hantro
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index ea919bfb9891..7e9e24bb5057 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -239,6 +239,7 @@ static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
 		.reset = imx8m_vpu_g2_reset,
 		.init = hantro_hevc_dec_init,
 		.exit = hantro_hevc_dec_exit,
+		.done = hantro_g2_hevc_dec_done,
 	},
 };
 
-- 
2.25.1



From stern at rowland.harvard.edu  Mon Aug 23 07:00:52 2021
From: stern at rowland.harvard.edu (Alan Stern)
Date: Mon, 23 Aug 2021 10:00:52 -0400
Subject: Enable HSIC Host Port on Atmel/Microchip SAMA5D2
In-Reply-To: <2869763.XZdSvA6Ref@ada>
References: <2869763.XZdSvA6Ref@ada>
Message-ID: <20210823140052.GA120849@rowland.harvard.edu>

On Mon, Aug 23, 2021 at 11:24:35AM +0200, Alexander Dahl wrote:
> Hello,
> 
> for a new embedded board featuring a Microchip SAMA5D2 SoC (64 MiB SiP variant 
> SAMA5D27C-D5M) we connected the third USB host port (HSIC only) with an 
> USB3503 hub chip. This doesn't work out of the box with the Linux kernel 
> currently, because neither the SoC nor the kernel does enable the HSIC 
> interface by default.
> 
> That SoC has three USB host ports, from the SAMA5D2 Series Datasheet [1] I 
> learned there's a flag in an EHCI register, which has to be set to enable the 
> HSIC interface on port C, the third port. (Section "41.7.14 EHCI: REG08 - HSIC 
> Enable/Disable" of the datasheet.) I suppose that register is vendor specific. 
> The register definitions in '/include/linux/usb/ehci_def.h' do not contain 
> that register.
> 
> Where would I add that register definition and set that flag in the kernel 
> then?  I suppose in the vendor specific ehci driver?  
> That would be 'drivers/usb/host/ehci-atmel.c' right?

That is where you would set the flag.  You might want to put the 
register definition in ehci_def.h, with the other definitions.

> Since that feature is optional (other boards don't need to turn on hsic on 
> that port), some driver specific new device tree binding would be necessary, 
> right?  I suppose that would have to be documented in 'Documentation/
> devicetree/bindings/usb/atmel-usb.txt' right? (Or that would have to be 
> converted to yaml first?)

Yes, it would have to go into the device tree data somehow.  I don't 
know the best way to do this; people who know more about DT may be able 
to tell you.

> Is this the right track?  If yes, I'm going to develop patches for this. 
> Otherwise any hint into the right direction are highly appreciated.

Yes, this is the right approach.

Alan Stern

> FWIW, I'm not the first one struggling [2] with this problem. ;-)
> 
> Greets
> Alex
> 
> [1] https://www.microchip.com/en-us/product/ATSAMA5D27C-D5M#document-table
> [2] https://community.atmel.com/forum/sama5d2-using-hsic-under-linux


From borntraeger at de.ibm.com  Mon Aug 23 07:12:40 2021
From: borntraeger at de.ibm.com (Christian Borntraeger)
Date: Mon, 23 Aug 2021 16:12:40 +0200
Subject: [PATCH v2 1/2] KVM: Refactor kvm_arch_vcpu_fault() to return a
 struct page pointer
In-Reply-To: <98adbd3c-ec6f-5689-1686-2a8a7909951a@redhat.com>
References: <YRQcZqCWwVH8bCGc@google.com>
 <1c510b24fc1d7cbae8aa4b69c0799ebd32e65b82.1628739116.git.houwenlong93@linux.alibaba.com>
 <98adbd3c-ec6f-5689-1686-2a8a7909951a@redhat.com>
Message-ID: <c228bf78-28fb-8666-e394-5ebfa1de0862@de.ibm.com>



On 12.08.21 11:04, David Hildenbrand wrote:
> On 12.08.21 06:02, Hou Wenlong wrote:
>> From: Sean Christopherson <seanjc at google.com>
>>
>> Refactor kvm_arch_vcpu_fault() to return 'struct page *' instead of
>> 'vm_fault_t' to simplify architecture specific implementations that do
>> more than return SIGBUS.? Currently this only applies to s390, but a
>> future patch will move x86's pio_data handling into x86 where it belongs.
>>
>> No functional changed intended.
>>
>> Cc: Hou Wenlong <houwenlong93 at linux.alibaba.com>
>> Signed-off-by: Sean Christopherson <seanjc at google.com>
>> Signed-off-by: Hou Wenlong <houwenlong93 at linux.alibaba.com>
>> ---
>> ? arch/arm64/kvm/arm.c?????? |? 4 ++--
>> ? arch/mips/kvm/mips.c?????? |? 4 ++--
>> ? arch/powerpc/kvm/powerpc.c |? 4 ++--
>> ? arch/s390/kvm/kvm-s390.c?? | 12 ++++--------
>> ? arch/x86/kvm/x86.c???????? |? 4 ++--
>> ? include/linux/kvm_host.h?? |? 2 +-
>> ? virt/kvm/kvm_main.c??????? |? 5 ++++-
>> ? 7 files changed, 17 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
>> index e9a2b8f27792..83f4ffe3e4f2 100644
>> --- a/arch/arm64/kvm/arm.c
>> +++ b/arch/arm64/kvm/arm.c
>> @@ -161,9 +161,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>> ????? return ret;
>> ? }
>> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> ? {
>> -??? return VM_FAULT_SIGBUS;
>> +??? return NULL;
>> ? }
>> diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
>> index af9dd029a4e1..ae79874e6fd2 100644
>> --- a/arch/mips/kvm/mips.c
>> +++ b/arch/mips/kvm/mips.c
>> @@ -1053,9 +1053,9 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
>> ????? return -ENOIOCTLCMD;
>> ? }
>> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> ? {
>> -??? return VM_FAULT_SIGBUS;
>> +??? return NULL;
>> ? }
>> ? int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
>> index be33b5321a76..b9c21f9ab784 100644
>> --- a/arch/powerpc/kvm/powerpc.c
>> +++ b/arch/powerpc/kvm/powerpc.c
>> @@ -2090,9 +2090,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
>> ????? return r;
>> ? }
>> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> ? {
>> -??? return VM_FAULT_SIGBUS;
>> +??? return NULL;
>> ? }
>> ? static int kvm_vm_ioctl_get_pvinfo(struct kvm_ppc_pvinfo *pvinfo)
>> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
>> index 02574d7b3612..e1b69833e228 100644
>> --- a/arch/s390/kvm/kvm-s390.c
>> +++ b/arch/s390/kvm/kvm-s390.c
>> @@ -4979,17 +4979,13 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
>> ????? return r;
>> ? }
>> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> ? {
>> ? #ifdef CONFIG_KVM_S390_UCONTROL
>> -??? if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
>> -???????? && (kvm_is_ucontrol(vcpu->kvm))) {
>> -??????? vmf->page = virt_to_page(vcpu->arch.sie_block);
>> -??????? get_page(vmf->page);
>> -??????? return 0;
>> -??? }
>> +??? if (vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET && kvm_is_ucontrol(vcpu->kvm))
>> +??????? return virt_to_page(vcpu->arch.sie_block);
>> ? #endif
>> -??? return VM_FAULT_SIGBUS;
>> +??? return NULL;
>> ? }
>> ? /* Section: memory related */
>> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
>> index 3cedc7cc132a..1e3bbe5cd33a 100644
>> --- a/arch/x86/kvm/x86.c
>> +++ b/arch/x86/kvm/x86.c
>> @@ -5347,9 +5347,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
>> ????? return r;
>> ? }
>> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
>> ? {
>> -??? return VM_FAULT_SIGBUS;
>> +??? return NULL;
>> ? }
>> ? static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr)
>> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
>> index 492d183dd7d0..a949de534722 100644
>> --- a/include/linux/kvm_host.h
>> +++ b/include/linux/kvm_host.h
>> @@ -995,7 +995,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
>> ????????????? unsigned int ioctl, unsigned long arg);
>> ? long kvm_arch_vcpu_ioctl(struct file *filp,
>> ?????????????? unsigned int ioctl, unsigned long arg);
>> -vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
>> +struct page *kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
>> ? int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext);
>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>> index 30d322519253..f7d21418971b 100644
>> --- a/virt/kvm/kvm_main.c
>> +++ b/virt/kvm/kvm_main.c
>> @@ -3448,7 +3448,10 @@ static vm_fault_t kvm_vcpu_fault(struct vm_fault *vmf)
>> ????????????? &vcpu->dirty_ring,
>> ????????????? vmf->pgoff - KVM_DIRTY_LOG_PAGE_OFFSET);
>> ????? else
>> -??????? return kvm_arch_vcpu_fault(vcpu, vmf);
>> +??????? page = kvm_arch_vcpu_fault(vcpu, vmf);
>> +??? if (!page)
>> +??????? return VM_FAULT_SIGBUS;
>> +
>> ????? get_page(page);
>> ????? vmf->page = page;
>> ????? return 0;
>>
> 
> Reviewed-by: David Hildenbrand <david at redhat.com>
> 
> But at the same time I wonder if we should just get rid of CONFIG_KVM_S390_UCONTROL and consequently kvm_arch_vcpu_fault().
> 
> 
> In practice CONFIG_KVM_S390_UCONTROL, is never enabled in any reasonable kernel build and consequently it's never tested; further, exposing the sie_block to user space allows user space to generate random SIE validity intercepts.
> 
> CONFIG_KVM_S390_UCONTROL feels like something that should just be maintained out of tree by someone who really needs to hack deep into hw virtualization for testing purposes etc.

I recently talked to the ucontrol users and they will look into selftests.


From daniel at 0x0f.com  Mon Aug 23 07:19:02 2021
From: daniel at 0x0f.com (Daniel Palmer)
Date: Mon, 23 Aug 2021 23:19:02 +0900
Subject: [PATCH v3] mtd: spinand: add support for Foresee FS35ND0*G parts
In-Reply-To: <20210816101143.2a64d7b9@xps13>
References: <20210811084924.52293-1-daniel@0x0f.com>
 <20210816101143.2a64d7b9@xps13>
Message-ID: <CAFr9PXnna+b3ChVUftT7YbU1kYR=5JDcik3bMNqzKK-LW=GQzw@mail.gmail.com>

Hi Miquel,

> > +     /*
> > +      * The datasheet says *successful* with 4 bits flipped.
> > +      * nandbiterrs always complains that the read reported
> > +      * successful but the data is incorrect.
> > +      */
> > +     case FS35ND01G_S1Y2_STATUS_ECC_4_BITFLIPS:
> > +             return 4;
>
> This is a real issue. Can you use the nandflipbits tool from the
> mtd-utils package (you should take a recent version of the package) and
> try to observe what happens when you insert a 4th bitflip in a section?
>
> I generally believe the tool more than the datasheet :)

Maybe I'm using it incorrectly but I can't get a 4 bit flipped
situation to happen.

I erased the paged so it's all 0xFF:

# flash_erase /dev/mtd0 0x8000000 1
Erasing 128 Kibyte @ 8000000 -- 100 % complete
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0
ECC failed: 0
ECC corrected: 6234
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|

Then used nandflipbits to flip a bunch of bits in the first byte and
then a few other bytes:

# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0
ECC failed: 0
ECC corrected: 6246
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: f0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: eb ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ef ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ef ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|

Anyhow,
I think we should probably return -EBADMSG if the 4 bit flips status
appears as nandbiterrs always complains that the data is wrong.

Cheers,

Daniel


From miquel.raynal at bootlin.com  Mon Aug 23 07:21:48 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 23 Aug 2021 16:21:48 +0200
Subject: [PATCH v3] mtd: spinand: add support for Foresee FS35ND0*G parts
In-Reply-To: <CAFr9PXnna+b3ChVUftT7YbU1kYR=5JDcik3bMNqzKK-LW=GQzw@mail.gmail.com>
References: <20210811084924.52293-1-daniel@0x0f.com>
 <20210816101143.2a64d7b9@xps13>
 <CAFr9PXnna+b3ChVUftT7YbU1kYR=5JDcik3bMNqzKK-LW=GQzw@mail.gmail.com>
Message-ID: <20210823162148.35a24183@xps13>

Hi Daniel,

Daniel Palmer <daniel at 0x0f.com> wrote on Mon, 23 Aug 2021 23:19:02
+0900:

> Hi Miquel,
> 
> > > +     /*
> > > +      * The datasheet says *successful* with 4 bits flipped.
> > > +      * nandbiterrs always complains that the read reported
> > > +      * successful but the data is incorrect.
> > > +      */
> > > +     case FS35ND01G_S1Y2_STATUS_ECC_4_BITFLIPS:
> > > +             return 4;  
> >
> > This is a real issue. Can you use the nandflipbits tool from the
> > mtd-utils package (you should take a recent version of the package) and
> > try to observe what happens when you insert a 4th bitflip in a section?
> >
> > I generally believe the tool more than the datasheet :)  
> 
> Maybe I'm using it incorrectly but I can't get a 4 bit flipped
> situation to happen.
> 
> I erased the paged so it's all 0xFF:
> 
> # flash_erase /dev/mtd0 0x8000000 1
> Erasing 128 Kibyte @ 8000000 -- 100 % complete
> # nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0
> ECC failed: 0
> ECC corrected: 6234
> Number of bad blocks: 0
> Number of bbt blocks: 0
> Block size 131072, page size 2048, OOB size 64
> Dumping data starting at 0x08000000 and ending at 0x08000001...
> ECC: 3 corrected bitflip(s) at offset 0x08000000
> 0x08000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 
> Then used nandflipbits to flip a bunch of bits in the first byte and
> then a few other bytes:
> 
> # nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0
> ECC failed: 0
> ECC corrected: 6246
> Number of bad blocks: 0
> Number of bbt blocks: 0
> Block size 131072, page size 2048, OOB size 64
> Dumping data starting at 0x08000000 and ending at 0x08000001...
> ECC: 3 corrected bitflip(s) at offset 0x08000000
> 0x08000000: f0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000010: eb ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000020: ef ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000060: ef ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 
> Anyhow,
> I think we should probably return -EBADMSG if the 4 bit flips status
> appears as nandbiterrs always complains that the data is wrong.

I am not sure to follow, above the software says "3 corrected bf" while
I thought the problem was when getting 4 bf, but the dump show many
more. Can you show me how it behaves:
* erase (like you did)
* insert {1, 2, 3, 4, 5} bf and show the dump each time?

Thanks,
Miqu?l


From frattaroli.nicolas at gmail.com  Mon Aug 23 07:35:42 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Mon, 23 Aug 2021 16:35:42 +0200
Subject: [PATCH v2 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <6bc6330215980f10853a2dac69f0bdfd9c8fb303.camel@pengutronix.de>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
 <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
 <6bc6330215980f10853a2dac69f0bdfd9c8fb303.camel@pengutronix.de>
Message-ID: <9368735.gdWEK3B62L@archbook>

Hi Philipp,

On Montag, 23. August 2021 14:03:25 CEST Philipp Zabel wrote:
> Hi Nicolas,
> 
> On Fri, 2021-08-20 at 20:27 +0200, Nicolas Frattaroli wrote:
> [...]
> 
> > diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c
> > b/sound/soc/rockchip/rockchip_i2s_tdm.c new file mode 100644
> > index 000000000000..c02b66f3c913
> > --- /dev/null
> > +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
> > @@ -0,0 +1,1737 @@
> 
> [...]
> 
> > +static void rockchip_snd_xfer_reset_assert(struct rk_i2s_tdm_dev
> > *i2s_tdm,
> > +					   int tx_bank, int tx_offset,
> > +					   int rx_bank, int rx_offset)
> > +{
> > +	void __iomem *cru_reset;
> > +	unsigned long flags;
> > +
> > +	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
> > +
> > +	if (tx_bank == rx_bank) {
> > +		writel(BIT(tx_offset) | BIT(rx_offset) |
> > +		       (BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
> > +		       cru_reset + (tx_bank * 4));
> > +	} else {
> > +		local_irq_save(flags);
> > +		writel(BIT(tx_offset) | (BIT(tx_offset) << 16),
> > +		       cru_reset + (tx_bank * 4));
> > +		writel(BIT(rx_offset) | (BIT(rx_offset) << 16),
> > +		       cru_reset + (rx_bank * 4));
> > +		local_irq_restore(flags);
> > +	}
> > +}
> > +
> > +static void rockchip_snd_xfer_reset_deassert(struct rk_i2s_tdm_dev
> > *i2s_tdm, +					     int tx_bank, int 
tx_offset,
> > +					     int rx_bank, int rx_offset)
> > +{
> > +	void __iomem *cru_reset;
> > +	unsigned long flags;
> > +
> > +	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
> > +
> > +	if (tx_bank == rx_bank) {
> > +		writel((BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
> > +		       cru_reset + (tx_bank * 4));
> > +	} else {
> > +		local_irq_save(flags);
> > +		writel((BIT(tx_offset) << 16),
> > +		       cru_reset + (tx_bank * 4));
> > +		writel((BIT(rx_offset) << 16),
> > +		       cru_reset + (rx_bank * 4));
> > +		local_irq_restore(flags);
> > +	}
> > +}
> > +
> > +/*
> > + * Makes sure that both tx and rx are reset at the same time to sync lrck
> > + * when clk_trcm > 0.
> > + */
> > +static void rockchip_snd_xfer_sync_reset(struct rk_i2s_tdm_dev *i2s_tdm)
> > +{
> > +	int tx_id, rx_id;
> > +	int tx_bank, rx_bank, tx_offset, rx_offset;
> > +
> > +	if (!i2s_tdm->cru_base || !i2s_tdm->soc_data)
> > +		return;
> > +
> > +	tx_id = i2s_tdm->tx_reset_id;
> > +	rx_id = i2s_tdm->rx_reset_id;
> > +	if (tx_id < 0 || rx_id < 0)
> > +		return;
> > +
> > +	tx_bank = tx_id / 16;
> > +	tx_offset = tx_id % 16;
> > +	rx_bank = rx_id / 16;
> > +	rx_offset = rx_id % 16;
> > +	dev_dbg(i2s_tdm->dev,
> > +		"tx_bank: %d, rx_bank: %d, tx_offset: %d, rx_offset: %d\n",
> > +		tx_bank, rx_bank, tx_offset, rx_offset);
> > +
> > +	rockchip_snd_xfer_reset_assert(i2s_tdm, tx_bank, tx_offset,
> > +				       rx_bank, rx_offset);
> > +
> > +	udelay(150);
> > +
> > +	rockchip_snd_xfer_reset_deassert(i2s_tdm, tx_bank, tx_offset,
> > +					 rx_bank, rx_offset);
> > +}
> 
> I'm not too fond of reimplementing half a reset controller in here.
> The reset framework does not support synchronized (de)assertion of
> multiple reset controls, I wonder if this would be useful to add.
> Without having thought about this too hard, I could imagine this as an
> extension to the bulk API, or possibly a call to join multiple reset
> controls into a reset control array.

I agree, the code required for synchronised reset seems to be a good
candidate for a generalised solution elsewhere.
However, I'm not sure if I'm the right candidate to design this API
as my first kernel contribution when the board I'm currently testing
this with doesn't even utilise the synchronized reset.

If I come across an opportunity to test synchronised resets, I'll
definitely look into refactoring this. I'd also be happy to hear of
any other driver which is currently implementing its own synchronised
reset.

[...]
 
> > +
> > +	reset_control_assert(rc);
> > +	udelay(1);
> 
> What is the reason for the different delays in
> rockchip_snd_xfer_sync_reset() and rockchip_snd_reset()?
> 

Simply put: I have no idea. This is what downstream does, and it
appears to work for me. The git history of the downstream kernel
also doesn't tell me anything about why the sync reset is 150
and this one is 1.

I've got no device to test the sync reset with at the moment so
I'm wary of playing with the delay value.

> > +	reset_control_deassert(rc);
> > +}
> 
> [...]
> 
> > +static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
> > +{
> > +	struct device_node *node = pdev->dev.of_node;
> > +	struct device_node *cru_node;
> > +	const struct of_device_id *of_id;
> > +	struct rk_i2s_tdm_dev *i2s_tdm;
> > +	struct resource *res;
> > +	void __iomem *regs;
> > +	int ret;
> > +	int val;
> > +
> > +	i2s_tdm = devm_kzalloc(&pdev->dev, sizeof(*i2s_tdm), GFP_KERNEL);
> > +	if (!i2s_tdm)
> > +		return -ENOMEM;
> > +
> > +	i2s_tdm->dev = &pdev->dev;
> > +
> > +	of_id = of_match_device(rockchip_i2s_tdm_match, &pdev->dev);
> > +	if (!of_id || !of_id->data)
> > +		return -EINVAL;
> > +
> > +	spin_lock_init(&i2s_tdm->lock);
> > +	i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data;
> > +
> > +	i2s_tdm->frame_width = 64;
> > +	if (!of_property_read_u32(node, "rockchip,frame-width", &val)) {
> > +		if (val >= 32 && (val % 2 == 0) && val <= 512) {
> > +			i2s_tdm->frame_width = val;
> > +		} else {
> > +			dev_err(i2s_tdm->dev, "unsupported frame width: 
'%d'\n",
> > +				val);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	i2s_tdm->clk_trcm = TRCM_TXRX;
> > +	if (of_property_read_bool(node, "rockchip,trcm-sync-tx-only"))
> > +		i2s_tdm->clk_trcm = TRCM_TX;
> > +	if (of_property_read_bool(node, "rockchip,trcm-sync-rx-only")) {
> > +		if (i2s_tdm->clk_trcm) {
> > +			dev_err(i2s_tdm->dev, "invalid trcm-sync 
configuration\n");
> > +			return -EINVAL;
> > +		}
> > +		i2s_tdm->clk_trcm = TRCM_RX;
> > +	}
> > +	if (i2s_tdm->clk_trcm != TRCM_TXRX)
> > +		i2s_tdm_dai.symmetric_rate = 1;
> > +
> > +	i2s_tdm->tdm_fsync_half_frame =
> > +		of_property_read_bool(node, "rockchip,tdm-fsync-half-frame");
> > +
> > +	i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
> > +	if (IS_ERR(i2s_tdm->grf))
> > +		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->grf),
> > +				     "Error in rockchip,grf\n");
> > +
> > +	if (i2s_tdm->clk_trcm != TRCM_TXRX) {
> > +		cru_node = of_parse_phandle(node, "rockchip,cru", 0);
> > +		i2s_tdm->cru_base = of_iomap(cru_node, 0);
> 
> This is a bit ugly if there is another driver sitting on the
> rockchip,cru compatible node. Which reset controller driver is backing
> the reset controls below?

I'm not sure if I understand the question (I only just today learned that
reset controls have drivers) but I think the reset it is using in the
Quartz64 dts is backed by rk3568-cru. Let me know if I misunderstood you.

[...]

> > +static int rockchip_i2s_tdm_remove(struct platform_device *pdev)
> > +{
> > +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(&pdev->dev);
> > +
> > +	pm_runtime_disable(&pdev->dev);
> > +	if (!pm_runtime_status_suspended(&pdev->dev))
> > +		i2s_tdm_runtime_suspend(&pdev->dev);
> > +
> > +	if (!IS_ERR(i2s_tdm->mclk_tx))
> > +		clk_prepare_enable(i2s_tdm->mclk_tx);
> > +	if (!IS_ERR(i2s_tdm->mclk_rx))
> > +		clk_prepare_enable(i2s_tdm->mclk_rx);
> 
> Why are we enabling these clocks now?
> 

I wondered that too while I was looking into the pm_runtime stuff,
and decided to just throw these two calls out. They don't seem to
make sense to me, and nothing I tested broke when I removed them.

If left in (and the code works as I hypothesise it works) then
this would simply re-enable clocks we have just disabled, which
would make the number of enable and disable calls unbalanced.
Highly sus, as the kids would say, and completely omits the other
mclk_tx_src etc. clocks. (Though those are forgotten elsewhere in
the code as well, which I have since fixed, along with any of the
review points I don't directly respond to.)

> > +	if (!IS_ERR(i2s_tdm->hclk))
> > +		clk_disable_unprepare(i2s_tdm->hclk);
> > +
> > +	return 0;
> > +}
> 
> regards
> Philipp

Regards,
Nicolas Frattaroli




From michael.riesch at wolfvision.net  Mon Aug 23 07:37:54 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 23 Aug 2021 16:37:54 +0200
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
Message-ID: <20210823143754.14294-1-michael.riesch@wolfvision.net>

This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
"net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
unbalanced pm_runtime_enable warnings.

In the commit to be reverted, support for power management was
introduced to the Rockchip glue code. Later, power management support
was introduced to the stmmac core code, resulting in multiple
invocations of pm_runtime_{enable,disable,get_sync,put_sync}.

The multiple invocations happen in rk_gmac_powerup and
stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
stmmac_{dvr_remove, suspend}, respectively, which are always called
in conjunction.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 280ac0129572..ed817011a94a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
-#include <linux/pm_runtime.h>
 
 #include "stmmac_platform.h"
 
@@ -1529,9 +1528,6 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
 		return ret;
 	}
 
-	pm_runtime_enable(dev);
-	pm_runtime_get_sync(dev);
-
 	if (bsp_priv->integrated_phy)
 		rk_gmac_integrated_phy_powerup(bsp_priv);
 
@@ -1540,14 +1536,9 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
 
 static void rk_gmac_powerdown(struct rk_priv_data *gmac)
 {
-	struct device *dev = &gmac->pdev->dev;
-
 	if (gmac->integrated_phy)
 		rk_gmac_integrated_phy_powerdown(gmac);
 
-	pm_runtime_put_sync(dev);
-	pm_runtime_disable(dev);
-
 	phy_power_on(gmac, false);
 	gmac_clk_enable(gmac, false);
 }
-- 
2.17.1



From mathieu.poirier at linaro.org  Mon Aug 23 07:41:36 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 23 Aug 2021 08:41:36 -0600
Subject: [PATCH 0/2] Add Coresight support for RB5 board
In-Reply-To: <1629365324-5891-1-git-send-email-quic_taozha@quicinc.com>
References: <1629365324-5891-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <CANLsYkxw9nXb=vsWhf8=Sf6Bnm23doTaYOS7WChxOGhudt23-w@mail.gmail.com>

Hi Tao,

On Thu, 19 Aug 2021 at 03:29, Tao Zhang <quic_taozha at quicinc.com> wrote:
>
> This series adds Coresight support for SM8250 Soc on RB5 board.
> It is composed of two elements.
> a) Add ETM PID for Kryo-5XX.
> b) Add coresight support to DTS for RB5.
>
> This series applies to coresight/next
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
>
> Tao Zhang (2):
>   coresight: etm4x: Add ETM PID for Kryo-5XX
>   arm64: dts: qcom: sm8250: Add Coresight support
>
>  arch/arm64/boot/dts/qcom/qrb5165-rb5.dts      | 442 +++++++++++++++++-
>  .../coresight/coresight-etm4x-core.c          |   1 +
>  2 files changed, 439 insertions(+), 4 deletions(-)
>

I have added your work to my patchset queue.  On the other hand I have
a lot of patches to review these days and as such won't be able to
look at it for 4 to 5 weeks.

Thanks,
Mathieu

> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>


From robh+dt at kernel.org  Mon Aug 23 07:44:55 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Mon, 23 Aug 2021 09:44:55 -0500
Subject: [PATCH v5 1/9] MIPS: Avoid future duplicate elf core header
 reservation
In-Reply-To: <YSOeGzowhV/R9QS/@kernel.org>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>
 <YRn9DHlB/pdNPJyP@kernel.org>
 <CAMuHMdVdqR7gw+2O2v=qv_BB=+X2wEXN9jXV=np=jRayadwj7g@mail.gmail.com>
 <YSOeGzowhV/R9QS/@kernel.org>
Message-ID: <CAL_JsqLMv4fKebJEOv=7UXvy_qqut0N42psS-PSgRMU-qhiFLQ@mail.gmail.com>

On Mon, Aug 23, 2021 at 8:10 AM Mike Rapoport <rppt at kernel.org> wrote:
>
> On Mon, Aug 23, 2021 at 12:17:50PM +0200, Geert Uytterhoeven wrote:
> > Hi Mike,
> >
> > On Mon, Aug 16, 2021 at 7:52 AM Mike Rapoport <rppt at kernel.org> wrote:
> > > On Wed, Aug 11, 2021 at 10:50:59AM +0200, Geert Uytterhoeven wrote:
> > > > Prepare for early_init_fdt_scan_reserved_mem() reserving the memory
> > > > occupied by an elf core header described in the device tree.
> > > > As arch_mem_init() calls early_init_fdt_scan_reserved_mem() before
> > > > mips_reserve_vmcore(), the latter needs to check if the memory has
> > > > already been reserved before.
> > >
> > > Doing memblock_reserve() for the same region is usually fine, did you
> > > encounter any issues without this patch?
> >
> > Does it also work if the same region is part of an earlier larger
> > reservation?  I am no memblock expert, so I don't know.
> > I didn't run into any issues, as my MIPS platform is non-DT, but I
> > assume arch/arm64/mm/init.c:reserve_elfcorehdr() had the check for
> > a reason.
>
> The memory will be reserved regardless of the earlier reservation, the
> issue may appear when the reservations are made for different purpose. E.g.
> if there was crash kernel allocation before the reservation of elfcorehdr.
>
> The check in such case will prevent the second reservation, but, at least
> in arch/arm64/mm/init.c:reserve_elfcorehdr() it does not seem to prevent
> different users of the overlapping regions to step on each others toes.

If the kernel has been passed in overlapping regions, is there
anything you can do other than hope to get a message out?

> Moreover, arm64::reserve_elfcorehdr() seems buggy to me, because of there
> is only a partial overlap of the elfcorehdr with the previous reservation,
> the non-overlapping part of elfcorehdr won't get reserved at all.

What do you suggest as the arm64 version is not the common version?

Rob


From daniel at 0x0f.com  Mon Aug 23 07:54:20 2021
From: daniel at 0x0f.com (Daniel Palmer)
Date: Mon, 23 Aug 2021 23:54:20 +0900
Subject: [PATCH v3] mtd: spinand: add support for Foresee FS35ND0*G parts
In-Reply-To: <20210823162148.35a24183@xps13>
References: <20210811084924.52293-1-daniel@0x0f.com>
 <20210816101143.2a64d7b9@xps13>
 <CAFr9PXnna+b3ChVUftT7YbU1kYR=5JDcik3bMNqzKK-LW=GQzw@mail.gmail.com>
 <20210823162148.35a24183@xps13>
Message-ID: <CAFr9PXkSeeHNn-KVyrVxp6RRdLYExTgWpheWKLLSZqEo_EHvRg@mail.gmail.com>

Hi Miquel,

On Mon, 23 Aug 2021 at 23:21, Miquel Raynal <miquel.raynal at bootlin.com> wrote:
> I am not sure to follow, above the software says "3 corrected bf" while

Due to the status being "between 0 and 3 bitflips" I think it'll
basically report 3 most of the time.
As a refresher we seem to have a status for 0 - 3 flips but ok, 4 bit
flips but ok, and >4 flips no go.
In most cases (0 - 3) the driver is reporting 3.

> I thought the problem was when getting 4 bf, but the dump show many
> more. Can you show me how it behaves:
> * erase (like you did)
> * insert {1, 2, 3, 4, 5} bf and show the dump each time?

Here's a complete log of erasing the page then flipping all the bits
in the first byte.

# flash_erase /dev/mtd0 0x8000000 1
Erasing 128 Kibyte @ 8000000 -- 100 % complete
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6249
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandflipbits /dev/mtd0 0 at 0x8000000
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6252
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: fe ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandflipbits /dev/mtd0 1 at 0x8000000
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6255
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: fc ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandflipbits /dev/mtd0 2 at 0x8000000
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6258
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: f8 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandflipbits /dev/mtd0 3 at 0x8000000
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6261
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: f0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandflipbits /dev/mtd0 4 at 0x8000000
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6264
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: e0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandflipbits /dev/mtd0 5 at 0x8000000
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6267
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandflipbits /dev/mtd0 6 at 0x8000000
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6270
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: 80 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandflipbits /dev/mtd0 7 at 0x8000000
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6273
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
#

For completeness logs of what nandbiterrs does:

# flash_erase /dev/mtd0 0x8000000 1
Erasing 128 Kibyte @ 8000000 -- 100 % complete
# nandbiterrs -i ^C 1024 /dev/mtd0
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6478
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandbiterrs -i -b 1024 /dev/mtd0
incremental biterrors test
Read reported 3 corrected bit errors
Successfully corrected 0 bit errors per subpage
Inserted biterror @ 0/5
Read reported 4 corrected bit errors
ECC failure, invalid data despite read success
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6488
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 4 corrected bitflip(s) at offset 0x08000000
0x08000000: 05 a5 65 e5 05 85 45 c5 b5 35 f5 75 95 15 d5 55  |..e...E..5.u...U|
0x08000010: 6d ed 2d ad 4d cd 0d 8d fd 7d bd 3d dd 5d 9d 1d  |m.-.M....}.=.]..|
0x08000020: 81 01 c1 41 a1 21 e1 61 11 91 51 d1 31 b1 71 f1  |...A.!.a..Q.1.q.|
0x08000030: c9 49 89 09 e9 69 a9 29 59 d9 19 99 79 f9 39 b9  |.I...i.)Y...y.9.|
0x08000040: 77 d7 37 b7 57 d7 17 97 e7 67 a7 27 c7 47 87 07  |w.7.W....g.'.G..|
0x08000050: 3f bf 7f ff 1f 9f 5f df af 2f ef 6f 8f 0f cf 4f  |?....._../.o...O|
0x08000060: d3 53 93 13 f3 73 b3 33 43 c3 03 83 63 e3 23 a3  |.S...s.3C...c.#.|
0x08000070: 9b 1b db 5b bb 3b fb 7b 0b 8b 4b cb 2b ab 6b eb  |...[.;.{..K.+.k.|
0x08000080: 0c 8c 4c cc 2c ac 6c ec 9c 1c dc 5c bc 3c fc 7c  |..L.,.l....\.<.||
0x08000090: 44 c4 04 84 64 e4 24 a4 d4 54 94 14 f4 74 b4 34  |D...d.$..T...t.4|
#

# flash_erase /dev/mtd0 0x8000000 1
Erasing 128 Kibyte @ 8000000 -- 100 % complete
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 0
ECC corrected: 6492
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
# nandbiterrs -o -b 1024 /dev/mtd0
overwrite biterrors test
Read reported 3 corrected bit errors
Read reported 4 corrected bit errors
Failed to recover 1 bitflips
Bit error histogram (873 operations total):
Page reads with   0 corrected bit errors: 0
Page reads with   1 corrected bit errors: 0
Page reads with   2 corrected bit errors: 0
Page reads with   3 corrected bit errors: 785
# nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
ECC failed: 1
ECC corrected: 9202
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x08000000 and ending at 0x08000001...
ECC: 3 corrected bitflip(s) at offset 0x08000000
0x08000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|

Cheers,

Daniel


From robh at kernel.org  Mon Aug 23 07:52:20 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 23 Aug 2021 09:52:20 -0500
Subject: [PATCH v5 0/9] Add generic support for kdump DT properties
In-Reply-To: <CAMuHMdXs0+7K4N0mg6qX6X1cr_8dBr_HdTahdfORMk76wCJcEA@mail.gmail.com>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <YRkxzx/1XM3r64Ee@robh.at.kernel.org>
 <CAMuHMdXs0+7K4N0mg6qX6X1cr_8dBr_HdTahdfORMk76wCJcEA@mail.gmail.com>
Message-ID: <CAL_JsqK63hoEMafLP+5eeQR1qrhOO76J4KEQG_By6QnLfhF=dw@mail.gmail.com>

On Mon, Aug 23, 2021 at 5:13 AM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hi Rob,
>
> On Sun, Aug 15, 2021 at 5:25 PM Rob Herring <robh at kernel.org> wrote:
> > On Wed, Aug 11, 2021 at 10:50:58AM +0200, Geert Uytterhoeven wrote:
> > > This patch series adds generic support for parsing DT properties related
> > > to crash dump kernels ("linux,elfcorehdr" and "linux,elfcorehdr" under
> > > the "/chosen" node), makes use of it on arm32, and performs a few
> > > cleanups.  It is an evolution of the combination of [1] and [2].
> >
> > The DT bits look fine to me. How do you expect this to be merged? I'm
> > happy to take it if arch maintainers can ack it.
>
> I had hoped you could take the series...

My current thought is I'll take 2-5, 7 and 8 given that's what I have
acks for and the others can be applied independently.

> > > The series consists of 6 parts:
> > >   1. Patch 1 prepares architecture-specific code (needed for MIPS only)
> > >      to avoid duplicating elf core header reservation later.
> > >   2. Patch 2 prepares the visibility of variables used to hold
> > >      information retrieved from the DT properties.
> > >   3. Patches 3-5 add support to the FDT core for handling the
> > >      properties.
> > >      This can co-exist safely with architecture-specific handling, until
> > >      the latter has been removed.
> >
> > Looks like patch 5 doesn't have any dependencies with the series?
>
> Indeed. So you can take it independently.
>
> > >   4. Patch 6 removes the non-standard handling of "linux,elfcorehdr" on
> > >      riscv.
> >
> > I thought this should be applied for 5.14?
>
> Me too, but unfortunately that hasn't happened yet...

Buried in the middle of this series is not going to encourage it to be
picked up as a fix.

Rob


From leo.yan at linaro.org  Mon Aug 23 07:54:17 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 23 Aug 2021 22:54:17 +0800
Subject: [PATCH v1 3/3] perf auxtrace arm: Support
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210823133918.GP22278@shell.armlinux.org.uk>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-4-leo.yan@linaro.org>
 <6ce4057a-57cf-501d-6449-2069cd00ba57@arm.com>
 <20210823133043.GF100516@leoy-ThinkPad-X240s>
 <20210823133918.GP22278@shell.armlinux.org.uk>
Message-ID: <20210823145417.GA169379@leoy-ThinkPad-X240s>

Hi Russell,

On Mon, Aug 23, 2021 at 02:39:18PM +0100, Russell King (Oracle) wrote:
> On Mon, Aug 23, 2021 at 09:30:43PM +0800, Leo Yan wrote:
> > On Mon, Aug 23, 2021 at 01:23:42PM +0100, James Clark wrote:

[...]

> > > For x86, it's possible to include tools/include/asm/atomic.h, but that doesn't
> > > include arch/arm/include/asm/atomic.h and there are some other #ifdefs that might
> > > make it not so easy for Arm. Just wondering if you considered trying to include the
> > > existing one? Or decided that it was easier to duplicate it?
> > 
> > Good finding!
> > 
> > With you reminding, I recognized that the atomic operations for
> > arm/arm64 should be improved for user space program.  So far, perf tool
> > simply uses the compiler's atomic implementations (from
> > asm-generic/atomic-gcc.h) for arm/arm64; but for a more reliable
> > implementation, I think we should improve the user space program with
> > architecture's atomic instructions.
> 
> No we should not. Sometimes, what's in the kernel is for the kernel's
> use only, and not for userspace's use. That may be because what works
> in kernel space does not work in userspace.
> 
> For example, the ARMv6+ atomic operations can be executed in userspace
> _provided_ they are only used on memory which has an exclusive monitor.
> They can't be used on anything that is not "normal memory".

Okay, IIUC, the requirement for "normal memory" and exclusive monitor
should also apply on aarch64 for ldrex/strex, Load-Acquire and
Store-Release instructions, etc.  Otherwise, it's heavily dependent on
the exclusive monitors outside the cache coherency domain (but this is
out of the scopes for CPU).

perf tool is very likely to map memory with "normal memory" but we
cannot say it's always true.

So I agree there have risk for exporting the aarch32/aarch64 atomic
headers to user space.

> Prior to
> ARMv6, the atomic operations rely on disabling interrupts. That
> facility is simply not available to userspace, so these must not be
> made available to userspace.
> 
> The same applies to bitops.
> 
> We've been here before in the past, when the kernel headers were not
> separated from the user ABI headers, and people would write programs
> that included e.g. bitops.h on x86 because they had optimised bitops
> code. This made the userspace programs very non-portable - without
> re-implementing userspace versions of this stuff in every userspace
> program that did this stuff.
> 
> So no, having experienced the effects of this kind of thing in the
> past, the kernel should _not_ export architecture specific code in
> header files to userspace.
> 
> Also, it should be pointed out that by doing so, you create a licensing
> issue. If the code is GPLv2, and you build your program such that it
> incorporates GPLv2 code, then if the userspace program is not GPLv2
> compliant, you have a licensing problem, and in effect the program
> can be distributed.
> 
> Please do not go down this route.

Thanks a lot for the suggestion and quick response.

Leo


From mathieu.desnoyers at efficios.com  Mon Aug 23 08:00:03 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Mon, 23 Aug 2021 11:00:03 -0400 (EDT)
Subject: [PATCH v2 1/5] KVM: rseq: Update rseq when processing
 NOTIFY_RESUME on xfer to KVM guest
In-Reply-To: <20210820225002.310652-2-seanjc@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-2-seanjc@google.com>
Message-ID: <733947967.21669.1629730803567.JavaMail.zimbra@efficios.com>

----- On Aug 20, 2021, at 6:49 PM, Sean Christopherson seanjc at google.com wrote:

> Invoke rseq's NOTIFY_RESUME handler when processing the flag prior to
> transferring to a KVM guest, which is roughly equivalent to an exit to
> userspace and processes many of the same pending actions.  While the task
> cannot be in an rseq critical section as the KVM path is reachable only
> by via ioctl(KVM_RUN), the side effects that apply to rseq outside of a
> critical section still apply, e.g. the current CPU needs to be updated if
> the task is migrated.
> 
> Clearing TIF_NOTIFY_RESUME without informing rseq can lead to segfaults
> and other badness in userspace VMMs that use rseq in combination with KVM,
> e.g. due to the CPU ID being stale after task migration.

Acked-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>

> 
> Fixes: 72c3c0fe54a3 ("x86/kvm: Use generic xfer to guest work function")
> Reported-by: Peter Foley <pefoley at google.com>
> Bisected-by: Doug Evans <dje at google.com>
> Cc: Shakeel Butt <shakeelb at google.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: stable at vger.kernel.org
> Signed-off-by: Sean Christopherson <seanjc at google.com>
> ---
> kernel/entry/kvm.c |  4 +++-
> kernel/rseq.c      | 14 +++++++++++---
> 2 files changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
> index 49972ee99aff..049fd06b4c3d 100644
> --- a/kernel/entry/kvm.c
> +++ b/kernel/entry/kvm.c
> @@ -19,8 +19,10 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu,
> unsigned long ti_work)
> 		if (ti_work & _TIF_NEED_RESCHED)
> 			schedule();
> 
> -		if (ti_work & _TIF_NOTIFY_RESUME)
> +		if (ti_work & _TIF_NOTIFY_RESUME) {
> 			tracehook_notify_resume(NULL);
> +			rseq_handle_notify_resume(NULL, NULL);
> +		}
> 
> 		ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
> 		if (ret)
> diff --git a/kernel/rseq.c b/kernel/rseq.c
> index 35f7bd0fced0..6d45ac3dae7f 100644
> --- a/kernel/rseq.c
> +++ b/kernel/rseq.c
> @@ -282,9 +282,17 @@ void __rseq_handle_notify_resume(struct ksignal *ksig,
> struct pt_regs *regs)
> 
> 	if (unlikely(t->flags & PF_EXITING))
> 		return;
> -	ret = rseq_ip_fixup(regs);
> -	if (unlikely(ret < 0))
> -		goto error;
> +
> +	/*
> +	 * regs is NULL if and only if the caller is in a syscall path.  Skip
> +	 * fixup and leave rseq_cs as is so that rseq_sycall() will detect and
> +	 * kill a misbehaving userspace on debug kernels.
> +	 */
> +	if (regs) {
> +		ret = rseq_ip_fixup(regs);
> +		if (unlikely(ret < 0))
> +			goto error;
> +	}
> 	if (unlikely(rseq_update_cpu_id(t)))
> 		goto error;
> 	return;
> --
> 2.33.0.rc2.250.ged5fa647cd-goog

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From pierre-louis.bossart at linux.intel.com  Mon Aug 23 08:02:18 2021
From: pierre-louis.bossart at linux.intel.com (Pierre-Louis Bossart)
Date: Mon, 23 Aug 2021 10:02:18 -0500
Subject: [PATCH v2 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <3469189.PC3msRC2N5@archbook>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
 <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
 <66d6bd43-ee43-eff4-7a68-333fbb996787@linux.intel.com>
 <3469189.PC3msRC2N5@archbook>
Message-ID: <a2aa0525-326e-9364-1907-c1d53bca39cf@linux.intel.com>



On 8/21/21 3:45 PM, Nicolas Frattaroli wrote:
> On Freitag, 20. August 2021 21:02:16 CEST Pierre-Louis Bossart wrote:
>>> +	regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
>>> +	/* Wait on the clear operation to finish */
>>> +	while (val) {
>>
>> delay needed here?
>>
> 
> The rockchip_i2s.c code doesn't have a delay here either, but I can
> add one of 1 usec for good measure, it seems weird to retry the
> read as fast as it can.

yep.

>>> +static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm,
>>> +					 struct clk *clk, unsigned long rate,
>>> +					 int ppm)
>>> +{
>>> +	unsigned long rate_target;
>>> +	int delta, ret;
>>> +
>>> +	if (ppm == i2s_tdm->clk_ppm)
>>> +		return 0;
>>> +
>>> +	delta = (ppm < 0) ? -1 : 1;
>>> +	delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000,
>>> +				1000000);
>>
>> formula looks odd? looks like you are implementing a round to nearest
>> operation, but that shouldn't require this multiplication?
>>
> 
> I believe the multiplication is there to compensate for clock drift.
> ppm is a value between -1000 and 1000 that specifies the clock drift
> in presumably parts per million, going by the variable name.

I meant using a signed division with lsb round-to-nearest, something like:

delta = (int)div64_u64((u64)rate * (u64)(ppm) + 500000,
			1000000);

> 
>>> +	pm_runtime_enable(&pdev->dev);
>>> +	if (!pm_runtime_enabled(&pdev->dev)) {
>>> +		ret = i2s_tdm_runtime_resume(&pdev->dev);
>>
>> that looks like dead code? you've just enabled pm_runtime, why would
>> this fail?
>>
> 
> I've had a look at the upstream rockchip_i2s.c code which does the
> same thing, and I believe the idea here is that we need to manually
> prepare and enable the master clocks (mclk_rx/mclk_tx) if pm_runtime
> is not available. Otherwise, pm_runtime will presumably call our
> resume callback at some point.
> 
> If runtime power management is disabled in the kernel config then 
> pm_runtime_enabled is always going to return false.

that seems very odd. why not enable the clocks by default and let them
stop in suspend.

>>> +err_suspend:
>>> +	if (!pm_runtime_status_suspended(&pdev->dev))
>>> +		i2s_tdm_runtime_suspend(&pdev->dev);
>>
>> why is this necessary?
> 
> I believe this is the same kind of situation as before, and the
> other driver does this too: if pm_runtime is not available, we
> need to stop our clocks manually on probe failure.

then use pm_runtime_disable() and manually stop the clocks...

>>> +err_pm_disable:
>>> +	pm_runtime_disable(&pdev->dev);>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static int rockchip_i2s_tdm_remove(struct platform_device *pdev)
>>> +{
>>> +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(&pdev->dev);
>>> +
>>> +	pm_runtime_disable(&pdev->dev);
>>> +	if (!pm_runtime_status_suspended(&pdev->dev))
>>> +		i2s_tdm_runtime_suspend(&pdev->dev);
>>
>> this looks backwards, if you disable pm_runtime first what is the
>> expectation for the rest.
> 
> I'm not well versed in the PM code but if my theory of this being
> related to unavailable PM is correct, then my best guess is that
> pm_runtime_disable does suspend the device, so if it's not
> suspended then we don't have pm_runtime and therefore need to call
> it manually.

I think this is really doing things backwards. You want to
unconditionally enable all resources on probe, and let them go to idle
when no one needs them - or if pm_runtime is disabled.

>>> +
>>> +	if (!IS_ERR(i2s_tdm->mclk_tx))
>>> +		clk_prepare_enable(i2s_tdm->mclk_tx);
>>> +	if (!IS_ERR(i2s_tdm->mclk_rx))
>>> +		clk_prepare_enable(i2s_tdm->mclk_rx);
>>> +	if (!IS_ERR(i2s_tdm->hclk))
>>> +		clk_disable_unprepare(i2s_tdm->hclk);
>>> +
>>> +	return 0;>>> +}
>>> +
>>> +#ifdef CONFIG_PM_SLEEP
>>
>> use __maybe_unused
> 
> You mean instead of the ifdef stuff to just add this attribute to
> the following functions like this?
> 
> static int rockchip_i2s_tdm_suspend(struct device *dev) __maybe_unused

yes

> 
>>
>>> +static int rockchip_i2s_tdm_suspend(struct device *dev)
>>> +{
>>> +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
>>> +
>>> +	regcache_mark_dirty(i2s_tdm->regmap);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int rockchip_i2s_tdm_resume(struct device *dev)
>>> +{
>>> +	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
>>> +	int ret;
>>> +
>>> +	ret = pm_runtime_get_sync(dev);
>>> +	if (ret < 0)
>>> +		return ret;
>>> +	ret = regcache_sync(i2s_tdm->regmap);
>>> +	pm_runtime_put(dev);
>>> +
>>> +	return ret;
>>> +}
>>> +#endif
> 
> Thank you for your review!
> 
> Regards,
> Nicolas Frattaroli
> 
> 
> 


From miquel.raynal at bootlin.com  Mon Aug 23 08:03:54 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 23 Aug 2021 17:03:54 +0200
Subject: [PATCH v3] mtd: spinand: add support for Foresee FS35ND0*G parts
In-Reply-To: <CAFr9PXkSeeHNn-KVyrVxp6RRdLYExTgWpheWKLLSZqEo_EHvRg@mail.gmail.com>
References: <20210811084924.52293-1-daniel@0x0f.com>
 <20210816101143.2a64d7b9@xps13>
 <CAFr9PXnna+b3ChVUftT7YbU1kYR=5JDcik3bMNqzKK-LW=GQzw@mail.gmail.com>
 <20210823162148.35a24183@xps13>
 <CAFr9PXkSeeHNn-KVyrVxp6RRdLYExTgWpheWKLLSZqEo_EHvRg@mail.gmail.com>
Message-ID: <20210823170354.2dccabd5@xps13>

Hi Daniel,

Daniel Palmer <daniel at 0x0f.com> wrote on Mon, 23 Aug 2021 23:54:20
+0900:

> Hi Miquel,
> 
> On Mon, 23 Aug 2021 at 23:21, Miquel Raynal <miquel.raynal at bootlin.com> wrote:
> > I am not sure to follow, above the software says "3 corrected bf" while  
> 
> Due to the status being "between 0 and 3 bitflips" I think it'll
> basically report 3 most of the time.
> As a refresher we seem to have a status for 0 - 3 flips but ok, 4 bit
> flips but ok, and >4 flips no go.
> In most cases (0 - 3) the driver is reporting 3.
> 
> > I thought the problem was when getting 4 bf, but the dump show many
> > more. Can you show me how it behaves:
> > * erase (like you did)
> > * insert {1, 2, 3, 4, 5} bf and show the dump each time?  
> 
> Here's a complete log of erasing the page then flipping all the bits
> in the first byte.
> 
> # flash_erase /dev/mtd0 0x8000000 1
> Erasing 128 Kibyte @ 8000000 -- 100 % complete
> # nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
> ECC failed: 0
> ECC corrected: 6249
> Number of bad blocks: 0
> Number of bbt blocks: 0
> Block size 131072, page size 2048, OOB size 64
> Dumping data starting at 0x08000000 and ending at 0x08000001...
> ECC: 3 corrected bitflip(s) at offset 0x08000000
> 0x08000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> # nandflipbits /dev/mtd0 0 at 0x8000000
> # nanddump --bb=dumpbad -s 0x8000000 -l 1 -c -p /dev/mtd0 | head -n 10
> ECC failed: 0
> ECC corrected: 6252
> Number of bad blocks: 0
> Number of bbt blocks: 0
> Block size 131072, page size 2048, OOB size 64
> Dumping data starting at 0x08000000 and ending at 0x08000001...
> ECC: 3 corrected bitflip(s) at offset 0x08000000
> 0x08000000: fe ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|

How is this result possible? You are dumping with the ECC engine
enabled, it reports 3 bf (meaning that it is actually running, at least
the software really thinks there is an on-die engine enabled) but the
data has not been corrected. I expect the first byte to be 0xFF after
correction. Only with -n (raw dump) we should see this.

> 0x08000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
> 0x08000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|

Thanks,
Miqu?l


From pali at kernel.org  Mon Aug 23 08:09:27 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Mon, 23 Aug 2021 17:09:27 +0200
Subject: [PATCH] PCI: uniphier: Serialize INTx masking/unmasking
In-Reply-To: <1629717500-19396-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1629717500-19396-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <20210823150927.jhobzfxy6e4s663r@pali>

+ Marc (who originally reported this issue)

On Monday 23 August 2021 20:18:20 Kunihiko Hayashi wrote:
> The condition register PCI_RCV_INTX is used in irq_mask(), irq_unmask()
> and irq_ack() callbacks. Accesses to register can occur at the same time
> without a lock.
> Add a lock into each callback to prevent the issue.
> 
> Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
> Suggested-by: Pali Roh?r <pali at kernel.org>
> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>

Acked-by: Pali Roh?r <pali at kernel.org>

> ---
>  drivers/pci/controller/dwc/pcie-uniphier.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> The previous patch is as follows:
> https://lore.kernel.org/linux-pci/1629370566-29984-1-git-send-email-hayashi.kunihiko at socionext.com/
> 
> Changes in the previous patch:
> - Change the subject and commit message
> 
> diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
> index ebe43e9..5075714 100644
> --- a/drivers/pci/controller/dwc/pcie-uniphier.c
> +++ b/drivers/pci/controller/dwc/pcie-uniphier.c
> @@ -186,12 +186,17 @@ static void uniphier_pcie_irq_ack(struct irq_data *d)
>  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> +	unsigned long flags;
>  	u32 val;
>  
> +	raw_spin_lock_irqsave(&pp->lock, flags);
> +
>  	val = readl(priv->base + PCL_RCV_INTX);
>  	val &= ~PCL_RCV_INTX_ALL_STATUS;
>  	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
>  	writel(val, priv->base + PCL_RCV_INTX);
> +
> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>  }
>  
>  static void uniphier_pcie_irq_mask(struct irq_data *d)
> @@ -199,12 +204,17 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
>  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> +	unsigned long flags;
>  	u32 val;
>  
> +	raw_spin_lock_irqsave(&pp->lock, flags);
> +
>  	val = readl(priv->base + PCL_RCV_INTX);
>  	val &= ~PCL_RCV_INTX_ALL_MASK;
>  	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
>  	writel(val, priv->base + PCL_RCV_INTX);
> +
> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>  }
>  
>  static void uniphier_pcie_irq_unmask(struct irq_data *d)
> @@ -212,12 +222,17 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
>  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> +	unsigned long flags;
>  	u32 val;
>  
> +	raw_spin_lock_irqsave(&pp->lock, flags);
> +
>  	val = readl(priv->base + PCL_RCV_INTX);
>  	val &= ~PCL_RCV_INTX_ALL_MASK;
>  	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
>  	writel(val, priv->base + PCL_RCV_INTX);
> +
> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>  }
>  
>  static struct irq_chip uniphier_pcie_irq_chip = {
> -- 
> 2.7.4
> 


From mathieu.desnoyers at efficios.com  Mon Aug 23 08:18:54 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Mon, 23 Aug 2021 11:18:54 -0400 (EDT)
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <20210820225002.310652-5-seanjc@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-5-seanjc@google.com>
Message-ID: <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>

----- On Aug 20, 2021, at 6:50 PM, Sean Christopherson seanjc at google.com wrote:

> Add a test to verify an rseq's CPU ID is updated correctly if the task is
> migrated while the kernel is handling KVM_RUN.  This is a regression test
> for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
> to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
> without updating rseq, leading to a stale CPU ID and other badness.
> 

[...]

+#define RSEQ_SIG 0xdeadbeef

Is there any reason for defining a custom signature rather than including
tools/testing/selftests/rseq/rseq.h ? This should take care of including
the proper architecture header which will define the appropriate signature.

Arguably you don't define rseq critical sections in this test per se, but
I'm wondering why the custom signature here.

[...]

> +
> +static void *migration_worker(void *ign)
> +{
> +	cpu_set_t allowed_mask;
> +	int r, i, nr_cpus, cpu;
> +
> +	CPU_ZERO(&allowed_mask);
> +
> +	nr_cpus = CPU_COUNT(&possible_mask);
> +
> +	for (i = 0; i < 20000; i++) {
> +		cpu = i % nr_cpus;
> +		if (!CPU_ISSET(cpu, &possible_mask))
> +			continue;
> +
> +		CPU_SET(cpu, &allowed_mask);
> +
> +		/*
> +		 * Bump the sequence count twice to allow the reader to detect
> +		 * that a migration may have occurred in between rseq and sched
> +		 * CPU ID reads.  An odd sequence count indicates a migration
> +		 * is in-progress, while a completely different count indicates
> +		 * a migration occurred since the count was last read.
> +		 */
> +		atomic_inc(&seq_cnt);

So technically this atomic_inc contains the required barriers because the selftests
implementation uses "__sync_add_and_fetch(&addr->val, 1)". But it's rather odd that
the semantic differs from the kernel implementation in terms of memory barriers: the
kernel implementation of atomic_inc guarantees no memory barriers, but this one
happens to provide full barriers pretty much by accident (selftests
futex/include/atomic.h documents no such guarantee).

If this full barrier guarantee is indeed provided by the selftests atomic.h header,
I would really like a comment stating that in the atomic.h header so the carpet is
not pulled from under our feet by a future optimization.


> +		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
> +		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)",
> +			    errno, strerror(errno));
> +		atomic_inc(&seq_cnt);
> +
> +		CPU_CLR(cpu, &allowed_mask);
> +
> +		/*
> +		 * Let the read-side get back into KVM_RUN to improve the odds
> +		 * of task migration coinciding with KVM's run loop.

This comment should be about increasing the odds of letting the seqlock read-side
complete. Otherwise, the delay between the two back-to-back atomic_inc is so small
that the seqlock read-side may never have time to complete the reading the rseq
cpu id and the sched_getcpu() call, and can retry forever.

I'm wondering if 1 microsecond is sufficient on other architectures as well. One
alternative way to make this depend less on the architecture's implementation of
sched_getcpu (whether it's a vDSO, or goes through a syscall) would be to read
the rseq cpu id and call sched_getcpu a few times (e.g. 3 times) in the migration
thread rather than use usleep, and throw away the value read. This would ensure
the delay is appropriate on all architectures.

Thanks!

Mathieu

> +		 */
> +		usleep(1);
> +	}
> +	done = true;
> +	return NULL;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	struct kvm_vm *vm;
> +	u32 cpu, rseq_cpu;
> +	int r, snapshot;
> +
> +	/* Tell stdout not to buffer its content */
> +	setbuf(stdout, NULL);
> +
> +	r = sched_getaffinity(0, sizeof(possible_mask), &possible_mask);
> +	TEST_ASSERT(!r, "sched_getaffinity failed, errno = %d (%s)", errno,
> +		    strerror(errno));
> +
> +	if (CPU_COUNT(&possible_mask) < 2) {
> +		print_skip("Only one CPU, task migration not possible\n");
> +		exit(KSFT_SKIP);
> +	}
> +
> +	sys_rseq(0);
> +
> +	/*
> +	 * Create and run a dummy VM that immediately exits to userspace via
> +	 * GUEST_SYNC, while concurrently migrating the process by setting its
> +	 * CPU affinity.
> +	 */
> +	vm = vm_create_default(VCPU_ID, 0, guest_code);
> +
> +	pthread_create(&migration_thread, NULL, migration_worker, 0);
> +
> +	while (!done) {
> +		vcpu_run(vm, VCPU_ID);
> +		TEST_ASSERT(get_ucall(vm, VCPU_ID, NULL) == UCALL_SYNC,
> +			    "Guest failed?");
> +
> +		/*
> +		 * Verify rseq's CPU matches sched's CPU.  Ensure migration
> +		 * doesn't occur between sched_getcpu() and reading the rseq
> +		 * cpu_id by rereading both if the sequence count changes, or
> +		 * if the count is odd (migration in-progress).
> +		 */
> +		do {
> +			/*
> +			 * Drop bit 0 to force a mismatch if the count is odd,
> +			 * i.e. if a migration is in-progress.
> +			 */
> +			snapshot = atomic_read(&seq_cnt) & ~1;
> +			smp_rmb();
> +			cpu = sched_getcpu();
> +			rseq_cpu = READ_ONCE(__rseq.cpu_id);
> +			smp_rmb();
> +		} while (snapshot != atomic_read(&seq_cnt));
> +
> +		TEST_ASSERT(rseq_cpu == cpu,
> +			    "rseq CPU = %d, sched CPU = %d\n", rseq_cpu, cpu);
> +	}
> +
> +	pthread_join(migration_thread, NULL);
> +
> +	kvm_vm_free(vm);
> +
> +	sys_rseq(RSEQ_FLAG_UNREGISTER);
> +
> +	return 0;
> +}
> --
> 2.33.0.rc2.250.ged5fa647cd-goog

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From mathieu.desnoyers at efficios.com  Mon Aug 23 08:20:17 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Mon, 23 Aug 2021 11:20:17 -0400 (EDT)
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-5-seanjc@google.com>
 <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>
Message-ID: <282257549.21721.1629732017655.JavaMail.zimbra@efficios.com>

[ re-send to Darren Hart ]

----- On Aug 23, 2021, at 11:18 AM, Mathieu Desnoyers mathieu.desnoyers at efficios.com wrote:

> ----- On Aug 20, 2021, at 6:50 PM, Sean Christopherson seanjc at google.com wrote:
> 
>> Add a test to verify an rseq's CPU ID is updated correctly if the task is
>> migrated while the kernel is handling KVM_RUN.  This is a regression test
>> for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
>> to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
>> without updating rseq, leading to a stale CPU ID and other badness.
>> 
> 
> [...]
> 
> +#define RSEQ_SIG 0xdeadbeef
> 
> Is there any reason for defining a custom signature rather than including
> tools/testing/selftests/rseq/rseq.h ? This should take care of including
> the proper architecture header which will define the appropriate signature.
> 
> Arguably you don't define rseq critical sections in this test per se, but
> I'm wondering why the custom signature here.
> 
> [...]
> 
>> +
>> +static void *migration_worker(void *ign)
>> +{
>> +	cpu_set_t allowed_mask;
>> +	int r, i, nr_cpus, cpu;
>> +
>> +	CPU_ZERO(&allowed_mask);
>> +
>> +	nr_cpus = CPU_COUNT(&possible_mask);
>> +
>> +	for (i = 0; i < 20000; i++) {
>> +		cpu = i % nr_cpus;
>> +		if (!CPU_ISSET(cpu, &possible_mask))
>> +			continue;
>> +
>> +		CPU_SET(cpu, &allowed_mask);
>> +
>> +		/*
>> +		 * Bump the sequence count twice to allow the reader to detect
>> +		 * that a migration may have occurred in between rseq and sched
>> +		 * CPU ID reads.  An odd sequence count indicates a migration
>> +		 * is in-progress, while a completely different count indicates
>> +		 * a migration occurred since the count was last read.
>> +		 */
>> +		atomic_inc(&seq_cnt);
> 
> So technically this atomic_inc contains the required barriers because the
> selftests
> implementation uses "__sync_add_and_fetch(&addr->val, 1)". But it's rather odd
> that
> the semantic differs from the kernel implementation in terms of memory barriers:
> the
> kernel implementation of atomic_inc guarantees no memory barriers, but this one
> happens to provide full barriers pretty much by accident (selftests
> futex/include/atomic.h documents no such guarantee).
> 
> If this full barrier guarantee is indeed provided by the selftests atomic.h
> header,
> I would really like a comment stating that in the atomic.h header so the carpet
> is
> not pulled from under our feet by a future optimization.
> 
> 
>> +		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
>> +		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)",
>> +			    errno, strerror(errno));
>> +		atomic_inc(&seq_cnt);
>> +
>> +		CPU_CLR(cpu, &allowed_mask);
>> +
>> +		/*
>> +		 * Let the read-side get back into KVM_RUN to improve the odds
>> +		 * of task migration coinciding with KVM's run loop.
> 
> This comment should be about increasing the odds of letting the seqlock
> read-side
> complete. Otherwise, the delay between the two back-to-back atomic_inc is so
> small
> that the seqlock read-side may never have time to complete the reading the rseq
> cpu id and the sched_getcpu() call, and can retry forever.
> 
> I'm wondering if 1 microsecond is sufficient on other architectures as well. One
> alternative way to make this depend less on the architecture's implementation of
> sched_getcpu (whether it's a vDSO, or goes through a syscall) would be to read
> the rseq cpu id and call sched_getcpu a few times (e.g. 3 times) in the
> migration
> thread rather than use usleep, and throw away the value read. This would ensure
> the delay is appropriate on all architectures.
> 
> Thanks!
> 
> Mathieu
> 
>> +		 */
>> +		usleep(1);
>> +	}
>> +	done = true;
>> +	return NULL;
>> +}
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +	struct kvm_vm *vm;
>> +	u32 cpu, rseq_cpu;
>> +	int r, snapshot;
>> +
>> +	/* Tell stdout not to buffer its content */
>> +	setbuf(stdout, NULL);
>> +
>> +	r = sched_getaffinity(0, sizeof(possible_mask), &possible_mask);
>> +	TEST_ASSERT(!r, "sched_getaffinity failed, errno = %d (%s)", errno,
>> +		    strerror(errno));
>> +
>> +	if (CPU_COUNT(&possible_mask) < 2) {
>> +		print_skip("Only one CPU, task migration not possible\n");
>> +		exit(KSFT_SKIP);
>> +	}
>> +
>> +	sys_rseq(0);
>> +
>> +	/*
>> +	 * Create and run a dummy VM that immediately exits to userspace via
>> +	 * GUEST_SYNC, while concurrently migrating the process by setting its
>> +	 * CPU affinity.
>> +	 */
>> +	vm = vm_create_default(VCPU_ID, 0, guest_code);
>> +
>> +	pthread_create(&migration_thread, NULL, migration_worker, 0);
>> +
>> +	while (!done) {
>> +		vcpu_run(vm, VCPU_ID);
>> +		TEST_ASSERT(get_ucall(vm, VCPU_ID, NULL) == UCALL_SYNC,
>> +			    "Guest failed?");
>> +
>> +		/*
>> +		 * Verify rseq's CPU matches sched's CPU.  Ensure migration
>> +		 * doesn't occur between sched_getcpu() and reading the rseq
>> +		 * cpu_id by rereading both if the sequence count changes, or
>> +		 * if the count is odd (migration in-progress).
>> +		 */
>> +		do {
>> +			/*
>> +			 * Drop bit 0 to force a mismatch if the count is odd,
>> +			 * i.e. if a migration is in-progress.
>> +			 */
>> +			snapshot = atomic_read(&seq_cnt) & ~1;
>> +			smp_rmb();
>> +			cpu = sched_getcpu();
>> +			rseq_cpu = READ_ONCE(__rseq.cpu_id);
>> +			smp_rmb();
>> +		} while (snapshot != atomic_read(&seq_cnt));
>> +
>> +		TEST_ASSERT(rseq_cpu == cpu,
>> +			    "rseq CPU = %d, sched CPU = %d\n", rseq_cpu, cpu);
>> +	}
>> +
>> +	pthread_join(migration_thread, NULL);
>> +
>> +	kvm_vm_free(vm);
>> +
>> +	sys_rseq(RSEQ_FLAG_UNREGISTER);
>> +
>> +	return 0;
>> +}
>> --
>> 2.33.0.rc2.250.ged5fa647cd-goog
> 
> --
> Mathieu Desnoyers
> EfficiOS Inc.
> http://www.efficios.com

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From rppt at kernel.org  Mon Aug 23 08:20:20 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 23 Aug 2021 18:20:20 +0300
Subject: [PATCH v5 1/9] MIPS: Avoid future duplicate elf core header
 reservation
In-Reply-To: <CAL_JsqLMv4fKebJEOv=7UXvy_qqut0N42psS-PSgRMU-qhiFLQ@mail.gmail.com>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <92b6718f5618d5469f67b48fbea189cca0c12f4b.1628670468.git.geert+renesas@glider.be>
 <YRn9DHlB/pdNPJyP@kernel.org>
 <CAMuHMdVdqR7gw+2O2v=qv_BB=+X2wEXN9jXV=np=jRayadwj7g@mail.gmail.com>
 <YSOeGzowhV/R9QS/@kernel.org>
 <CAL_JsqLMv4fKebJEOv=7UXvy_qqut0N42psS-PSgRMU-qhiFLQ@mail.gmail.com>
Message-ID: <YSO8tJxbuADEeL7I@kernel.org>

On Mon, Aug 23, 2021 at 09:44:55AM -0500, Rob Herring wrote:
> On Mon, Aug 23, 2021 at 8:10 AM Mike Rapoport <rppt at kernel.org> wrote:
> >
> > On Mon, Aug 23, 2021 at 12:17:50PM +0200, Geert Uytterhoeven wrote:
> > > Hi Mike,
> > >
> > > On Mon, Aug 16, 2021 at 7:52 AM Mike Rapoport <rppt at kernel.org> wrote:
> > > > On Wed, Aug 11, 2021 at 10:50:59AM +0200, Geert Uytterhoeven wrote:
> > > > > Prepare for early_init_fdt_scan_reserved_mem() reserving the memory
> > > > > occupied by an elf core header described in the device tree.
> > > > > As arch_mem_init() calls early_init_fdt_scan_reserved_mem() before
> > > > > mips_reserve_vmcore(), the latter needs to check if the memory has
> > > > > already been reserved before.
> > > >
> > > > Doing memblock_reserve() for the same region is usually fine, did you
> > > > encounter any issues without this patch?
> > >
> > > Does it also work if the same region is part of an earlier larger
> > > reservation?  I am no memblock expert, so I don't know.
> > > I didn't run into any issues, as my MIPS platform is non-DT, but I
> > > assume arch/arm64/mm/init.c:reserve_elfcorehdr() had the check for
> > > a reason.
> >
> > The memory will be reserved regardless of the earlier reservation, the
> > issue may appear when the reservations are made for different purpose. E.g.
> > if there was crash kernel allocation before the reservation of elfcorehdr.
> >
> > The check in such case will prevent the second reservation, but, at least
> > in arch/arm64/mm/init.c:reserve_elfcorehdr() it does not seem to prevent
> > different users of the overlapping regions to step on each others toes.
> 
> If the kernel has been passed in overlapping regions, is there
> anything you can do other than hope to get a message out?

Nothing really. I've been thinking about adding flags to memblock.reserved
to at least distinguish firmware regions from the kernel allocations, but I
never got to that.
 
> > Moreover, arm64::reserve_elfcorehdr() seems buggy to me, because of there
> > is only a partial overlap of the elfcorehdr with the previous reservation,
> > the non-overlapping part of elfcorehdr won't get reserved at all.
> 
> What do you suggest as the arm64 version is not the common version?

I'm not really familiar with crash dump internals, so I don't know if
resetting elfcorehdr_addr to ELFCORE_ADDR_ERR is a good idea. I think at
least arm64::reserve_elfcorehdr() should reserve the entire elfcorehdr area
regardless of the overlap. Otherwise it might get overwritten by a random
memblock_alloc().

> Rob

-- 
Sincerely yours,
Mike.


From robh at kernel.org  Mon Aug 23 08:24:27 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 23 Aug 2021 10:24:27 -0500
Subject: [PATCH v3 1/2] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <56140c26d86f4733@bloch.sibelius.xs4all.nl>
References: <20210726083204.93196-1-mark.kettenis@xs4all.nl>
 <20210726083204.93196-2-mark.kettenis@xs4all.nl>
 <20210726231848.GA1025245@robh.at.kernel.org>
 <87sfzt1pg9.wl-maz@kernel.org>
 <CAL_JsqLvqWiuib9s4PzX8pOQYJQ0eR7Gxz==J849eVJ5MDq4SA@mail.gmail.com>
 <8735ra1x8t.wl-maz@kernel.org>
 <CAL_JsqJ5M3soMT30ntSTbqqdrQP8TT26mHL-0xExsn10MWPofA@mail.gmail.com>
 <56140331bd735d61@bloch.sibelius.xs4all.nl>
 <CAL_JsqJ-YDNWOoo8TUupDox31YreUNQAPXHnMMtXakQs0S_BDA@mail.gmail.com>
 <56140c26d86f4733@bloch.sibelius.xs4all.nl>
Message-ID: <CAL_JsqJNs7QskN=jD3dvgxtXU-CBf6To6gSQn0PX1Pk5VkkD+g@mail.gmail.com>

On Sun, Aug 22, 2021 at 12:44 PM Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
>
> > From: Rob Herring <robh at kernel.org>
> > Date: Wed, 18 Aug 2021 15:51:11 -0500
>
> Hi Rob,
>
> > On Wed, Aug 18, 2021 at 2:56 PM Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
> > >
> > > > From: Rob Herring <robh at kernel.org>
> > > > Date: Sun, 15 Aug 2021 14:19:57 -0500
> > > >
> > > > On Sun, Aug 15, 2021 at 11:36 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > >
> > > > > Hi Rob,
> > > > >
> > > > > Apologies for the delay, I somehow misplaced this email...
> > > > >
> > > > > On Mon, 02 Aug 2021 17:10:39 +0100,
> > > > > Rob Herring <robh at kernel.org> wrote:
> > > > > >
> > > > > > On Sun, Aug 1, 2021 at 3:31 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > > > >
> > > > > > > On Tue, 27 Jul 2021 00:18:48 +0100,
> > > > > > > Rob Herring <robh at kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, Jul 26, 2021 at 10:32:00AM +0200, Mark Kettenis wrote:
> > > > > > > > > From: Mark Kettenis <kettenis at openbsd.org>
> > > > > > > > >
> > > > > > > > > The Apple PCIe host controller is a PCIe host controller with
> > > > > > > > > multiple root ports present in Apple ARM SoC platforms, including
> > > > > > > > > various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > > > > > > > > ---
> > > > > > > > >  .../devicetree/bindings/pci/apple,pcie.yaml   | 166 ++++++++++++++++++
> > > > > > > > >  MAINTAINERS                                   |   1 +
> > > > > > > > >  2 files changed, 167 insertions(+)
> > > > > > > > >  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > > > >
> > > > > > > > > diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > > > > new file mode 100644
> > > > > > > > > index 000000000000..bfcbdee79c64
> > > > > > > > > --- /dev/null
> > > > > > > > > +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> > > > > > > > > @@ -0,0 +1,166 @@
> > > > > > > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > > > > > > +%YAML 1.2
> > > > > > > > > +---
> > > > > > > > > +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> > > > > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > > > > > +
> > > > > > > > > +title: Apple PCIe host controller
> > > > > > > > > +
> > > > > > > > > +maintainers:
> > > > > > > > > +  - Mark Kettenis <kettenis at openbsd.org>
> > > > > > > > > +
> > > > > > > > > +description: |
> > > > > > > > > +  The Apple PCIe host controller is a PCIe host controller with
> > > > > > > > > +  multiple root ports present in Apple ARM SoC platforms, including
> > > > > > > > > +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> > > > > > > > > +  The controller incorporates Synopsys DesigWare PCIe logic to
> > > > > > > > > +  implements its root ports.  But the ATU found on most DesignWare
> > > > > > > > > +  PCIe host bridges is absent.
> > > > > > > >
> > > > > > > > blank line
> > > > > > > >
> > > > > > > > > +  All root ports share a single ECAM space, but separate GPIOs are
> > > > > > > > > +  used to take the PCI devices on those ports out of reset.  Therefore
> > > > > > > > > +  the standard "reset-gpio" and "max-link-speed" properties appear on
> > > > > > > >
> > > > > > > > reset-gpios
> > > > > > > >
> > > > > > > > > +  the child nodes that represent the PCI bridges that correspond to
> > > > > > > > > +  the individual root ports.
> > > > > > > >
> > > > > > > > blank line
> > > > > > > >
> > > > > > > > > +  MSIs are handled by the PCIe controller and translated into regular
> > > > > > > > > +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> > > > > > > > > +  distributed over the root ports as the OS sees fit by programming
> > > > > > > > > +  the PCIe controller's port registers.
> > > > > > > > > +
> > > > > > > > > +allOf:
> > > > > > > > > +  - $ref: /schemas/pci/pci-bus.yaml#
> > > > > > > > > +
> > > > > > > > > +properties:
> > > > > > > > > +  compatible:
> > > > > > > > > +    items:
> > > > > > > > > +      - const: apple,t8103-pcie
> > > > > > > > > +      - const: apple,pcie
> > > > > > > > > +
> > > > > > > > > +  reg:
> > > > > > > > > +    minItems: 3
> > > > > > > > > +    maxItems: 5
> > > > > > > > > +
> > > > > > > > > +  reg-names:
> > > > > > > > > +    minItems: 3
> > > > > > > > > +    maxItems: 5
> > > > > > > > > +    items:
> > > > > > > > > +      - const: config
> > > > > > > > > +      - const: rc
> > > > > > > > > +      - const: port0
> > > > > > > > > +      - const: port1
> > > > > > > > > +      - const: port2
> > > > > > > > > +
> > > > > > > > > +  ranges:
> > > > > > > > > +    minItems: 2
> > > > > > > > > +    maxItems: 2
> > > > > > > > > +
> > > > > > > > > +  interrupts:
> > > > > > > > > +    description:
> > > > > > > > > +      Interrupt specifiers, one for each root port.
> > > > > > > > > +    minItems: 1
> > > > > > > > > +    maxItems: 3
> > > > > > > > > +
> > > > > > > > > +  msi-controller: true
> > > > > > > > > +  msi-parent: true
> >
> > BTW, I don't think msi-parent and msi-controller together is valid?
>
> There is an existing example in:
>
> arm64/boot/dts/marvell/armada-37xx.dtsi
>
> I think it makes sense as the pcie bridge itself serves as the MSI
> controller.

That's pretty common such as all the DWC implementations using the
built-in MSI controller (in that case 'msi-parent' present means no
built-in controller). AFAICT, 'msi-parent' is just redundant here
because the fallback if msi-parent is not found is checking the bus's
DT node for a domain. See pci_host_bridge_of_msi_domain().

> > > > > > > > > +  msi-ranges:
> > > > > > > > > +    description:
> > > > > > > > > +      A list of pairs <intid span>, where "intid" is the first
> > > > > > > > > +      interrupt number that can be used as an MSI, and "span" the size
> > > > > > > > > +      of that range.
> > > > > > > > > +    $ref: /schemas/types.yaml#/definitions/uint32-matrix
> > > > > > > > > +    items:
> > > > > > > > > +      minItems: 2
> > > > > > > > > +      maxItems: 2
> > > > > > > >
> > > > > > > > I still have issues I raised on v1 with this property. It's genericish
> > > > > > > > looking, but not generic. 'intid' as a single cell can't specify any
> > > > > > > > parent interrupt such as a GIC which uses 3 cells. You could put in all
> > > > > > > > the cells, but you'd still be assuming which cell you can increment.
> > > > > > >
> > > > > > > The GIC bindings already use similar abstractions, see what we do for
> > > > > > > both GICv2m and GICv3 MBIs. Other MSI controllers use similar
> > > > > > > properties (alpine and loongson, for example).
> > > > > >
> > > > > > That's the problem. Everyone making up their own crap.
> > > > >
> > > > > And that crap gets approved:
> > > > >
> > > > > https://lore.kernel.org/lkml/20200512205704.GA10412 at bogus/
> > > > >
> > > > > I'm not trying to be antagonistic here, but it seems that your
> > > > > position on this very subject has changed recently.
> > > >
> > > > Not really, I think it's not the first time we've discussed this. But
> > > > as I see things over and over, my tolerance for another instance
> > > > without solving the problem for everyone diminishes. And what other
> > > > leverage do I have?
> > > >
> > > > Additionally, how long we have to support something comes into play. I
> > > > have no idea for a Loongson MSI controller. I have a better idea on an
> > > > Apple product...
> > > >
> > > > > > > > I think you should just list all these under 'interrupts' using
> > > > > > > > interrupt-names to make your life easier:
> > > > > > > >
> > > > > > > > interrupt-names:
> > > > > > > >   items:
> > > > > > > >     - const: port0
> > > > > > > >     - const: port1
> > > > > > > >     - const: port2
> > > > > > > >     - const: msi0
> > > > > > > >     - const: msi1
> > > > > > > >     - const: msi2
> > > > > > > >     - const: msi3
> > > > > > > >     ...
> > > > > > > >
> > > > > > > > Yeah, it's kind of verbose, but if the h/w block handles N interrupts,
> > > > > > > > you should list N interrupts. The worst case for the above is N entries
> > > > > > > > too if not contiguous.
> > > > > > >
> > > > > > > And that's where I beg to differ, again.
> > > > > > >
> > > > > > > Specifying interrupts like this gives the false impression that these
> > > > > > > interrupts are generated by the device that owns them (the RC). Which
> > > > > > > for MSIs is not the case.
> > > > > >
> > > > > > It's no different than an interrupt controller node having an
> > > > > > interrupts property. The source is downstream and the interrupt
> > > > > > controller is combining/translating the interrupts.
> > > > > >
> > > > > > The physical interrupt signals are connected to and originating in
> > > > > > this block.
> > > > >
> > > > > Oh, I also object to this, for the same reasons. The only case where
> > > > > it makes sense IMHO is when the interrupt controller is a multiplexer.
> > > >
> > > > So we've had the same kind of property for interrupt multiplexers. I'm
> > > > fine if you think an 'MSI to interrupts mapping property' should be
> > > > named something else.
> > > >
> > > > > > That sounds like perfectly 'describing the h/w' to me.
> > > > >
> > > > > I guess we have a different view of about these things. At the end of
> > > > > the day, I don't care enough as long as we can expose a range of
> > > > > interrupts one way or another.
> > > >
> > > > I don't really either. I just don't want 10 ways AND another...
> > > >
> > > > > > > This is not only verbose, this is
> > > > > > > semantically dubious. And what should we do when the number of
> > > > > > > possible interrupt is ridiculously large, as it is for the GICv3 ITS?
> > > > > >
> > > > > > I don't disagree with the verbose part. But that's not really an issue
> > > > > > in this case.
> > > > > >
> > > > > > > I wish we had a standard way to express these constraints. Until we
> > > > > > > do, I don't think enumerating individual interrupts is a practical
> > > > > > > thing to do, nor that it actually represents the topology of the
> > > > > > > system.
> > > > > >
> > > > > > The only way a standard way will happen is to stop accepting the
> > > > > > custom properties.
> > > > > >
> > > > > > All the custom properties suffer from knowledge of what the parent
> > > > > > interrupt controller is. To fix that, I think we need something like
> > > > > > this:
> > > > > >
> > > > > > msi-ranges = <intspec base>, <intspec step>, <intspec end>;
> > > > > >
> > > > > > 'intspec' is defined by the parent interrupt-controller cells. step is
> > > > > > the value to add. And end is what to match on to stop aka the last
> > > > > > interrupt in the range. For example, if the GIC is the parent, we'd
> > > > > > have something like this:
> > > > > >
> > > > > > <GIC_SPI 123 0>, <0 1 0>, <GIC_SPI 124 0>
> > > > > >
> > > > > > Does this apply to cases other than MSI? I think so as don't we have
> > > > > > the same type of properties with the low power mode shadow interrupt
> > > > > > controllers?  So 'interrupt-ranges'?
> > > > >
> > > > > This would work, though the increment seems a bit over-engineered. You
> > > > > also may need this property to accept multiple ranges.
> > > >
> > > > Yes, certainly. Worst case is a map.
> > > >
> > > > > > It looks to me like there's an assumption in the kernel that an MSI
> > > > > > controller has a linear range of parent interrupts? Is that correct
> > > > > > and something that's guaranteed? That assumption leaks into the
> > > > > > existing bindings.
> > > > >
> > > > > Depends on how the controller works. In general, the range maps to the
> > > > > MultiMSI requirements where the message is an offset from the base of
> > > > > the interrupt range. So you generally end-up with ranges of at least
> > > > > 32 contiguous MSIs. Anything under that is sub-par and probably not
> > > > > worth supporting.
> > > >
> > > > Maybe just this is enough:
> > > > msi-ranges = <intspec base>, <length>, <intspec base>, <length>, ...
> > > >
> > > > While I say 'length' here, that's really up to the interrupt parent to
> > > > interpret the intspec cells.
> > >
> > > So for the Apple PCIe controller we'd have:
> > >
> > >    msi-ranges = <AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
> > >
> > > That would work just fine.
> > >
> > > Should this be documented in the apple,pcie binding, or somewhere more
> > > generic?
> >
> > It doesn't have an 'apple,' prefix, so somewhere generic. Probably
> > bindings/interrupt-controller/msi.txt. Or start an msi-controller.yaml
> > schema as I'd rather not add things we can't validate, but I don't
> > want to gate this on converting all the MSI bindings. Someone that
> > understands MSI better than me should review too.
>
> Yes, I'd like to avoid converting all the MSI bindings, but I could
> add an msi-controller.yaml file and use it in the appropriate
> interrupt controller and pci host bridge bindings that have been
> converted to yaml.

I didn't mean converting *all* MSI users, just what's in msi.txt and
maybe the PCI MSI stuff. Just starting a msi-controller.yaml schema
with the new properties is fine. Not that I wouldn't love for someone
to do all of msi.txt.

> > Another thing I thought of is the above is assuming the interrupt
> > parent is the same as any interrupts for the node and that all MSIs go
> > to 1 interrupt controller. Also, given Marc doesn't think using
> > 'interrupts' is right, then using 'interrupt-parent' isn't either
> > (though many of the examples below do just that). So maybe we need the
> > phandle in there:
> >
> > msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
>
> That makes sense.
>
> > Other examples of this type of property include:
> > al,msi-base-spi/al,msi-base-spi
> > arm,msi-base-spi/arm,msi-num-spis
> > mbi-ranges
> > loongson,msi-base-vec/loongson,msi-num-vecs
> > marvell,spi-ranges
> > ti,interrupt-ranges?
> >
> > We should make sure msi-ranges works for all of these cases at least
> > even if we can't change them.
>
> I think this scheme would work for all of these although it isn't
> entirely clear to me whether ti,interrupt-ranges is about just MSIs or
> if it also maps some other kind of interrupts.
>
> marvell,spi-ranges is an interesting one since it typically specifies
> two ranges of 64 MSIs.  But that's something your proposal addresses
> just fine.  I suppose we will provide a phandle for the parent
> interrupt controller for each individual range?

Right.

Rob


From alyssa at rosenzweig.io  Mon Aug 23 08:17:38 2021
From: alyssa at rosenzweig.io (Alyssa Rosenzweig)
Date: Mon, 23 Aug 2021 11:17:38 -0400
Subject: [PATCH] maintainers: Add Alyssa Rosenzweig as M1 reviewer
Message-ID: <20210823151738.6273-1-alyssa@rosenzweig.io>

Add myself as a reviewer for Asahi Linux (Apple M1) patches.

I would like to be CC'ed on Asahi Linux patches for review and testing.
I am also collecting Asahi Linux patches downstream, rebasing on
linux-next periodically, and would like to be notified of what to
cherry-pick from lists.

Signed-off-by: Alyssa Rosenzweig <alyssa at rosenzweig.io>
Cc: Hector Martin <marcan at marcan.st>
Cc: Sven Peter <sven at svenpeter.dev>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b63403793c81..399e536bf629 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1264,6 +1264,7 @@ F:	drivers/input/mouse/bcm5974.c
 
 APPLE DART IOMMU DRIVER
 M:	Sven Peter <sven at svenpeter.dev>
+R:	Alyssa Rosenzweig <alyssa at rosenzweig.io>
 L:	iommu at lists.linux-foundation.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/iommu/apple,dart.yaml
@@ -1693,6 +1694,7 @@ F:	drivers/*/*alpine*
 
 ARM/APPLE MACHINE SUPPORT
 M:	Hector Martin <marcan at marcan.st>
+R:	Alyssa Rosenzweig <alyssa at rosenzweig.io>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 W:	https://asahilinux.org
-- 
2.30.2



From mathieu.poirier at linaro.org  Mon Aug 23 08:29:30 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 23 Aug 2021 09:29:30 -0600
Subject: [PATCH v3 2/2] remoteproc: meson-mx-ao-arc: Add a driver for the
 AO ARC remote procesor
In-Reply-To: <20210805161506.GA3205691@p14s>
References: <20210717234859.351911-1-martin.blumenstingl@googlemail.com>
 <20210717234859.351911-3-martin.blumenstingl@googlemail.com>
 <20210728175823.GA2766167@p14s>
 <CAFBinCB0-bAa7Y+YhscczarGrGuio37F8vRyfW6U2DiiDAvr-g@mail.gmail.com>
 <20210805161506.GA3205691@p14s>
Message-ID: <20210823152930.GA595498@p14s>

On Thu, Aug 05, 2021 at 10:15:06AM -0600, Mathieu Poirier wrote:
> On Wed, Aug 04, 2021 at 11:03:57PM +0200, Martin Blumenstingl wrote:
> > Hi Mathieu,
> > 
> > thanks for taking the time to look into this!
> > 
> > (I will address any of your comments that I am not mentioning in this
> > email anymore. Thanks a lot for the suggestions!)
> > 
> > On Wed, Jul 28, 2021 at 7:58 PM Mathieu Poirier
> > <mathieu.poirier at linaro.org> wrote:
> > [...]
> > > > +     writel(FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
> > > > +                            priv->sram_pa >> 14),
> > > Indentation problem
> > The idea here is to align priv->sram_pa with AO_REMAP_REG0... which
> > are both arguments to FIELD_PREP
> 
> Right, this is what I would have expected.  When I applied the patch on my side
> "priv->sram_pa ..." was aligned wiht the 'M' of "AO_REMAP_ ...".  
> 
> > Maybe using something like this will make that easier to read:
> >     tmp = FIELD_PREP(AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU,
> >                                      priv->sram_pa >> 14);
> >     writel(tmp, priv->remap_base + AO_REMAP_REG0);
> 
> I think the main problem is that
> AO_REMAP_REG0_REMAP_AHB_SRAM_BITS_17_14_FOR_ARM_CPU is simply too long.  I
> suggest making is shorter and add a comment to describe exactly what it does.
> 
> > 
> > What do you think: leave it as is or use a separate variable?
> > 
> > [...]
> > > > +     usleep_range(10, 100);
> > >
> > > I've seen this kind of mysterious timeouts in other patchset based vendor trees.
> > > You likely don't know why it is needed so I won't ask.
> > unfortunately this is also the case here
> > 
> > [...]
> > > > +     priv->arc_reset = devm_reset_control_get_exclusive(dev, NULL);
> > > > +     if (IS_ERR(priv->arc_reset)) {
> > >
> > > Function __reset_control_get() in __devm_reset_control_get() can return NULL so
> > > this should be IS_ERR_OR_NULL().
> > The logic in there is: return optional ? NULL : ERR_PTR(-...);
> 
> Ok, so you meant to do that.  And I just checked reset_control_reset() and it does
> account for a NULL parameter.  I'm good with this one but add a comment to
> make sure future readers don't think you've omitted to properly deal with the
> NULL return value.
> 
> > I am requesting a mandatory reset line here, so reset core will never
> > return NULL
> > See also [0]
> 
> Indeed, I've read that too.  Nonetheless __reset_control_get() can return NULL
> by way of __reset_control_get_from_lookup().
> 

You are correct, in your case checking for IS_ERR() is sufficient.

> > 
> > For this reason I am not planning to change this
> > 
> > [...]
> > > This driver is squeaky clean. With the above:
> > >
> > > Reviewed-by: Mathieu Poirier <mathieu.poirier at linaro.org>
> > awesome, thank you!
> > 
> > 
> > Best regards,
> > Martin
> > 
> > 
> > [0] https://elixir.bootlin.com/linux/v5.14-rc4/source/include/linux/reset.h#L227


From james.clark at arm.com  Mon Aug 23 09:00:14 2021
From: james.clark at arm.com (James Clark)
Date: Mon, 23 Aug 2021 17:00:14 +0100
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210823121348.GE100516@leoy-ThinkPad-X240s>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-3-leo.yan@linaro.org>
 <2b4e0c07-a8df-cca6-6a94-328560f4b0c6@arm.com>
 <20210823095155.GC100516@leoy-ThinkPad-X240s>
 <319ee11a-06f7-abde-6495-d2175928b9fe@arm.com>
 <20210823121348.GE100516@leoy-ThinkPad-X240s>
Message-ID: <1c0101fd-2ca6-4741-5d72-82d3e00bfeb6@arm.com>



On 23/08/2021 13:13, Leo Yan wrote:
> On Mon, Aug 23, 2021 at 11:57:52AM +0100, James Clark wrote:
> 
> [...]
> 
>> Ok thanks for the explanation, that makes sense now. I do have one other
>> point about the documentation for the function:
> 
> Welcome!
> 
>>> + * When update the AUX tail and detects any carrying in the high 32 bits, it
>>> + * means there have two store operations in user space and it cannot promise
>>> + * the atomicity for 64-bit write, so return '-1' in this case to tell the
>>> + * caller an overflow error has happened.
>>> + */
>>
>> I couldn't see how it can ever return -1, it seems like it would loop forever
>> until it reads the correct value.
> 
> I use this chunk comment to address the function
> compat_auxtrace_mmap__write_tail():
> 
> +int __weak compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
> +{
> +	struct perf_event_mmap_page *pc = mm->userpg;
> +	u64 mask = (u64)(UINT32_MAX) << 32;
> +
> +	if (tail & mask)
> +		return -1;
> +
> +	/* Ensure all reads are done before we write the tail out */
> +	smp_mb();
> +	WRITE_ONCE(pc->aux_tail, tail);
> +	return 0;
> +}
> 
> Please let me know if this is okay or not?  Otherwise, if you think
> the format can cause confusion, I'd like to split the comments into
> two sections, one section for reading AUX head and another is for
> writing AUX tail.

I see what you mean now, I think keeping it in one section is fine, I would just
replace "When update the AUX tail and detects" with "When
compat_auxtrace_mmap__write_tail() detects". If the function name is there then
it's clear that it's not the return value of compat_auxtrace_mmap__read_head()

Thanks
James

> 
> Thanks,
> Leo
> 


From p.zabel at pengutronix.de  Mon Aug 23 09:03:31 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Mon, 23 Aug 2021 18:03:31 +0200
Subject: [PATCH v2 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <9368735.gdWEK3B62L@archbook>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
 <20210820182731.29370-2-frattaroli.nicolas@gmail.com>
 <6bc6330215980f10853a2dac69f0bdfd9c8fb303.camel@pengutronix.de>
 <9368735.gdWEK3B62L@archbook>
Message-ID: <b596373b280dfe23a7e932b84ce31a2dbb806912.camel@pengutronix.de>

Hi Nicolas,

On Mon, 2021-08-23 at 16:35 +0200, Nicolas Frattaroli wrote:
[...]
> > I'm not too fond of reimplementing half a reset controller in here.
> > The reset framework does not support synchronized (de)assertion of
> > multiple reset controls, I wonder if this would be useful to add.
> > Without having thought about this too hard, I could imagine this as an
> > extension to the bulk API, or possibly a call to join multiple reset
> > controls into a reset control array.
> 
> I agree, the code required for synchronised reset seems to be a good
> candidate for a generalised solution elsewhere.
> However, I'm not sure if I'm the right candidate to design this API
> as my first kernel contribution when the board I'm currently testing
> this with doesn't even utilise the synchronized reset.
> 
> If I come across an opportunity to test synchronised resets, I'll
> definitely look into refactoring this. I'd also be happy to hear of
> any other driver which is currently implementing its own synchronised
> reset.
[...] 
> > What is the reason for the different delays in
> > rockchip_snd_xfer_sync_reset() and rockchip_snd_reset()?
> > 
> 
> Simply put: I have no idea. This is what downstream does, and it
> appears to work for me. The git history of the downstream kernel
> also doesn't tell me anything about why the sync reset is 150
> and this one is 1.
> 
> I've got no device to test the sync reset with at the moment so
> I'm wary of playing with the delay value.

Fair points. You could remove the untested synchronized reset support
for now; that would allow to get rid of the rockchip,cru device tree
property, which is only required to let this driver access the CRU
registers behind the clock/reset controller driver's back.

[...]
> > > +	if (i2s_tdm->clk_trcm != TRCM_TXRX) {
> > > +		cru_node = of_parse_phandle(node, "rockchip,cru", 0);
> > > +		i2s_tdm->cru_base = of_iomap(cru_node, 0);
> > 
> > This is a bit ugly if there is another driver sitting on the
> > rockchip,cru compatible node. Which reset controller driver is backing
> > the reset controls below?
> 
> I'm not sure if I understand the question (I only just today learned that
> reset controls have drivers) but I think the reset it is using in the
> Quartz64 dts is backed by rk3568-cru. Let me know if I misunderstood you.

That's the one, thanks.

The devm_reset_control_get() calls below follow the "reset-names"
and "resets" device tree properties. Those point (&cru) to a
clock-controller node with compatible = "rockchip,rk3568-cru".

The corresponding driver is drivers/clk/rockchip/clk-rk3568.c,
so the reset controller is provided by the reset_controller_register()
call in drivers/clk/rockchip/softrst.c.

regards
Philipp


From p.zabel at pengutronix.de  Mon Aug 23 09:12:30 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Mon, 23 Aug 2021 18:12:30 +0200
Subject: [GIT PULL] Reset controller fixes for v5.14
Message-ID: <e543959c5b5ee7b25686f81049bf187d602daeda.camel@pengutronix.de>

Dear SoC maintainers,

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.pengutronix.de/pza/linux tags/reset-fixes-for-v5.14

for you to fetch changes up to ed104ca4bd9c405b41e968ad4ece51f6462e90b6:

  reset: reset-zynqmp: Fixed the argument data type (2021-08-23 12:55:18 +0200)

----------------------------------------------------------------
Reset controller fixes for v5.14

Hide the Sparx5 reset driver unless the ARCH_SPARX5 or COMPILE_TEST
options are enabled, to avoid unnecessarily asking users about this
driver. Fix a return value argument type in the ZynqMP reset driver.

----------------------------------------------------------------
Geert Uytterhoeven (1):
      reset: RESET_MCHP_SPARX5 should depend on ARCH_SPARX5

Sai Krishna Potthuri (1):
      reset: reset-zynqmp: Fixed the argument data type

 drivers/reset/Kconfig        | 2 +-
 drivers/reset/reset-zynqmp.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)


From p.zabel at pengutronix.de  Mon Aug 23 09:12:55 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Mon, 23 Aug 2021 18:12:55 +0200
Subject: [GIT PULL] Reset controller updates for v5.15
Message-ID: <d42a75fc17ce718ef1b3fa4c5d3f5c7fb0bd2bc2.camel@pengutronix.de>

Dear SoC maintainers,

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.pengutronix.de/pza/linux tags/reset-for-v5.15

for you to fetch changes up to 09f3824342f665d222fb7ac17c91f8334779630b:

  reset: simple: remove ZTE details in Kconfig help (2021-08-23 12:53:32 +0200)

----------------------------------------------------------------
Reset controller updates for v5.15

Add support for the SC7280 PDC Global and RZ/G2L USB/PHY reset
controllers, convert UniPhier glue device tree bindings to json-schema
and remove a leftover mention of ZTE zx2967 from Kconfig.

----------------------------------------------------------------
Biju Das (2):
      dt-bindings: reset: Document RZ/G2L USBPHY Control bindings
      reset: renesas: Add RZ/G2L usbphy control driver

Kunihiko Hayashi (1):
      dt-bindings: reset: Convert UniPhier glue reset to json-schema

Peter Robinson (1):
      reset: simple: remove ZTE details in Kconfig help

Sibi Sankar (3):
      dt-bindings: reset: aoss: Add AOSS reset controller binding
      dt-bindings: reset: pdc: Add PDC Global bindings
      reset: qcom: Add PDC Global reset signals for WPSS

 .../devicetree/bindings/reset/qcom,aoss-reset.yaml |   5 +
 .../devicetree/bindings/reset/qcom,pdc-global.yaml |   4 +
 .../bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml  |  65 ++++++++
 .../reset/socionext,uniphier-glue-reset.yaml       |  88 +++++++++++
 .../devicetree/bindings/reset/uniphier-reset.txt   |  61 -------
 drivers/reset/Kconfig                              |   8 +-
 drivers/reset/Makefile                             |   1 +
 drivers/reset/reset-qcom-pdc.c                     |  62 ++++++--
 drivers/reset/reset-rzg2l-usbphy-ctrl.c            | 175 +++++++++++++++++++++
 include/dt-bindings/reset/qcom,sdm845-pdc.h        |   2 +
 10 files changed, 398 insertions(+), 73 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml
 create mode 100644 Documentation/devicetree/bindings/reset/socionext,uniphier-glue-reset.yaml
 delete mode 100644 Documentation/devicetree/bindings/reset/uniphier-reset.txt
 create mode 100644 drivers/reset/reset-rzg2l-usbphy-ctrl.c


From daniel at 0x0f.com  Mon Aug 23 09:16:58 2021
From: daniel at 0x0f.com (Daniel Palmer)
Date: Tue, 24 Aug 2021 01:16:58 +0900
Subject: [PATCH v3] mtd: spinand: add support for Foresee FS35ND0*G parts
In-Reply-To: <20210823170354.2dccabd5@xps13>
References: <20210811084924.52293-1-daniel@0x0f.com>
 <20210816101143.2a64d7b9@xps13>
 <CAFr9PXnna+b3ChVUftT7YbU1kYR=5JDcik3bMNqzKK-LW=GQzw@mail.gmail.com>
 <20210823162148.35a24183@xps13>
 <CAFr9PXkSeeHNn-KVyrVxp6RRdLYExTgWpheWKLLSZqEo_EHvRg@mail.gmail.com>
 <20210823170354.2dccabd5@xps13>
Message-ID: <CAFr9PXk3bUU+7gu2DJL_OrW3AwiG2YaTUot4Q-_9BJ0cKQ_pQQ@mail.gmail.com>

Hi Miquel,

Thank you for your patience on this..

On Tue, 24 Aug 2021 at 00:03, Miquel Raynal <miquel.raynal at bootlin.com> wrote:
> > ECC: 3 corrected bitflip(s) at offset 0x08000000
> > 0x08000000: fe ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  |................|
>
> How is this result possible? You are dumping with the ECC engine
> enabled, it reports 3 bf (meaning that it is actually running, at least
> the software really thinks there is an on-die engine enabled) but the
> data has not been corrected. I expect the first byte to be 0xFF after
> correction. Only with -n (raw dump) we should see this.

I did a bit of searching to see if a newer/more detailed datasheet has
come about and found some vendor code I hadn't seen before:

https://github.com/100askTeam/NezaD1_u-boot-2018/blob/1f8b282626f0b9f29f96c57d6b1a5d728e523893/drivers/mtd/awnand/spinand/physic/core.c#L46

This says the ECC enable bit is non-standard and in a register that
isn't documented at all in the datasheet.

I guess the spi nand core isn't able to actually control the ECC on
these chips at the moment and flipping the bits is updating the ECC
too.
Or the ECC isn't enabled at all.

I couldn't see an easy way of overriding which register gets updated
so I haven't tried it yet.

Cheers,

Daniel


From lorenzo.pieralisi at arm.com  Mon Aug 23 09:15:27 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 23 Aug 2021 17:15:27 +0100
Subject: [PATCH v2] PCI: rockchip-dwc: Potential error pointer
 dereference in probe
In-Reply-To: <20210813142648.GA12057@kili>
References: <20210813141257.GB7722@kadam>
 <20210813142648.GA12057@kili>
Message-ID: <20210823161527.GA8289@lpieralisi>

On Fri, Aug 13, 2021 at 05:26:48PM +0300, Dan Carpenter wrote:
> If devm_regulator_get_optional() returns -ENODEV then it would lead
> to an error pointer dereference on the next line and in the error
> handling code.
> 
> Fixes: e1229e884e19 ("PCI: rockchip-dwc: Add Rockchip RK356X host controller driver")
> Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
> ---
> v2: The -ENODEV from devm_regulator_get_optional() has to be handled
>     specially.
> 
>  drivers/pci/controller/dwc/pcie-dw-rockchip.c | 17 ++++++++++-------
>  1 file changed, 10 insertions(+), 7 deletions(-)

I squashed it in with the patch that is fixing, thanks a lot.

Lorenzo

> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 20cef2e06f66..c9b341e55cbb 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -224,15 +224,17 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>  
>  	/* DON'T MOVE ME: must be enable before PHY init */
>  	rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
> -	if (IS_ERR(rockchip->vpcie3v3))
> +	if (IS_ERR(rockchip->vpcie3v3)) {
>  		if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV)
>  			return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3),
>  					"failed to get vpcie3v3 regulator\n");
> -
> -	ret = regulator_enable(rockchip->vpcie3v3);
> -	if (ret) {
> -		dev_err(dev, "failed to enable vpcie3v3 regulator\n");
> -		return ret;
> +		rockchip->vpcie3v3 = NULL;
> +	} else {
> +		ret = regulator_enable(rockchip->vpcie3v3);
> +		if (ret) {
> +			dev_err(dev, "failed to enable vpcie3v3 regulator\n");
> +			return ret;
> +		}
>  	}
>  
>  	ret = rockchip_pcie_phy_init(rockchip);
> @@ -255,7 +257,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>  deinit_phy:
>  	rockchip_pcie_phy_deinit(rockchip);
>  disable_regulator:
> -	regulator_disable(rockchip->vpcie3v3);
> +	if (rockchip->vpcie3v3)
> +		regulator_disable(rockchip->vpcie3v3);
>  
>  	return ret;
>  }
> -- 
> 2.20.1
> 


From benjamin.gaignard at collabora.com  Mon Aug 23 09:29:16 2021
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Mon, 23 Aug 2021 18:29:16 +0200
Subject: [PATCH] media: hantro: Add support of compressed reference buffers
Message-ID: <20210823162916.824336-1-benjamin.gaignard@collabora.com>

Reference frame compression is a feature added in G2 decoder to compress
frame buffers so that the bandwidth of storing/loading reference frames
can be reduced, especially when the resolution of decoded stream is of
high definition.

Compressed help to increase the performance of the whole stack, it could
be up to 50 fps (against 45 fps) on IMX8MQ.
The impact of compressed frames is confirmed when using perf to monitor
the number of memory accesses with or without compression feature.
The following command
perf stat -a -e imx8_ddr0/cycles/,imx8_ddr0/read-cycles/,imx8_ddr0/write-cycles/ gst-launch-1.0 filesrc location=Jockey_3840x2160_120fps_420_8bit_HEVC_RAW.hevc ! queue ! h265parse ! v4l2slh265dec ! fakesink

give us these results
without compression feature:
 Performance counter stats for 'system wide':

       14965816743      imx8_ddr0/cycles/
         889197312      imx8_ddr0/read-cycles/
        1819348862      imx8_ddr0/write-cycles/

      18.707373001 seconds time elapsed

with compression feature:
Performance counter stats for 'system wide':

       13750218243      imx8_ddr0/cycles/
         402428744      imx8_ddr0/read-cycles/
        1255676693      imx8_ddr0/write-cycles/

      17.188320061 seconds time elapsed

As expected the number of read/write cycles are really lower when compression
is used.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 31 ++++++++++++--
 drivers/staging/media/hantro/hantro_g2_regs.h |  4 ++
 drivers/staging/media/hantro/hantro_hevc.c    | 41 ++++++++++++++++++-
 drivers/staging/media/hantro/hantro_hw.h      |  2 +
 4 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 340efb57fd18..da90acd922f7 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -366,10 +366,12 @@ static int set_ref(struct hantro_ctx *ctx)
 	const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps;
 	const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
 	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
-	dma_addr_t luma_addr, chroma_addr, mv_addr = 0;
+	dma_addr_t luma_addr, chroma_addr, mv_addr, compress_luma_addr, compress_chroma_addr = 0;
 	struct hantro_dev *vpu = ctx->dev;
 	size_t cr_offset = hantro_hevc_chroma_offset(sps);
 	size_t mv_offset = hantro_hevc_motion_vectors_offset(sps);
+	size_t compress_luma_offset = hantro_hevc_luma_compress_offset(sps);
+	size_t compress_chroma_offset = hantro_hevc_chroma_compress_offset(sps);
 	u32 max_ref_frames;
 	u16 dpb_longterm_e;
 	static const struct hantro_reg cur_poc[] = {
@@ -442,15 +444,28 @@ static int set_ref(struct hantro_ctx *ctx)
 		if (!luma_addr)
 			return -ENOMEM;
 
+		/*
+		 * An allocated frame stores Y and UV planes, motion vectors and
+		 * compressed Y and UV planes. Compute all these offsets given
+		 * the frame resolution and the pixel format.
+		 */
 		chroma_addr = luma_addr + cr_offset;
 		mv_addr = luma_addr + mv_offset;
+		compress_luma_addr = luma_addr + compress_luma_offset;
+		compress_chroma_addr = luma_addr + compress_chroma_offset;
 
 		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
 			dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
 
+		/*
+		 * For each reference frame Y, UV, motion vector and
+		 * compressed Y, UV buffers addresses must be set.
+		 */
 		hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr);
 		hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr);
 		hantro_write_addr(vpu, G2_REG_DMV_REF(i), mv_addr);
+		hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), compress_luma_addr);
+		hantro_write_addr(vpu, G2_COMP_CHR_REF(i), compress_chroma_addr);
 	}
 
 	luma_addr = hantro_hevc_get_ref_buf(ctx, decode_params->pic_order_cnt_val);
@@ -459,7 +474,12 @@ static int set_ref(struct hantro_ctx *ctx)
 
 	chroma_addr = luma_addr + cr_offset;
 	mv_addr = luma_addr + mv_offset;
+	compress_luma_addr = luma_addr + compress_luma_offset;
+	compress_chroma_addr = luma_addr + compress_chroma_offset;
 
+	/* The next decoded frame as to be put as the last reference frame entry */
+	hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), compress_luma_addr);
+	hantro_write_addr(vpu, G2_COMP_CHR_REF(i), compress_chroma_addr);
 	hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr);
 	hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr);
 	hantro_write_addr(vpu, G2_REG_DMV_REF(i++), mv_addr);
@@ -467,13 +487,18 @@ static int set_ref(struct hantro_ctx *ctx)
 	hantro_write_addr(vpu, G2_ADDR_DST, luma_addr);
 	hantro_write_addr(vpu, G2_ADDR_DST_CHR, chroma_addr);
 	hantro_write_addr(vpu, G2_ADDR_DST_MV, mv_addr);
+	hantro_write_addr(vpu, G2_COMP_ADDR_DST, compress_luma_addr);
+	hantro_write_addr(vpu, G2_COMP_CHR, compress_chroma_addr);
 
 	hantro_hevc_ref_remove_unused(ctx);
 
+	/* Unused reference frames entries most be cleared */
 	for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
 		hantro_write_addr(vpu, G2_REG_ADDR_REF(i), 0);
 		hantro_write_addr(vpu, G2_REG_CHR_REF(i), 0);
 		hantro_write_addr(vpu, G2_REG_DMV_REF(i), 0);
+		hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), 0);
+		hantro_write_addr(vpu, G2_COMP_CHR_REF(i), 0);
 	}
 
 	hantro_reg_write(vpu, &g2_refer_lterm_e, dpb_longterm_e);
@@ -564,8 +589,8 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx)
 	/* Don't disable output */
 	hantro_reg_write(vpu, &g2_out_dis, 0);
 
-	/* Don't compress buffers */
-	hantro_reg_write(vpu, &g2_ref_compress_bypass, 1);
+	/* Compress buffers */
+	hantro_reg_write(vpu, &g2_ref_compress_bypass, 0);
 
 	/* use NV12 as output format */
 	hantro_reg_write(vpu, &g2_out_rs_e, 1);
diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h
index bb22fa921914..2a23e8657db1 100644
--- a/drivers/staging/media/hantro/hantro_g2_regs.h
+++ b/drivers/staging/media/hantro/hantro_g2_regs.h
@@ -191,6 +191,10 @@
 #define G2_TILE_FILTER		(G2_SWREG(179))
 #define G2_TILE_SAO		(G2_SWREG(181))
 #define G2_TILE_BSD		(G2_SWREG(183))
+#define G2_COMP_ADDR_DST	(G2_SWREG(190))
+#define G2_COMP_ADDR_REF(i)	(G2_SWREG(192) + ((i) * 0x8))
+#define G2_COMP_CHR		(G2_SWREG(224))
+#define G2_COMP_CHR_REF(i)	(G2_SWREG(226) + ((i) * 0x8))
 
 #define g2_strm_buffer_len	G2_DEC_REG(258, 0, 0xffffffff)
 #define g2_strm_start_offset	G2_DEC_REG(259, 0, 0xffffffff)
diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
index 5347f5a41c2a..78e5ceda520c 100644
--- a/drivers/staging/media/hantro/hantro_hevc.c
+++ b/drivers/staging/media/hantro/hantro_hevc.c
@@ -27,6 +27,13 @@
 
 #define G2_ALIGN		16
 
+#define CBS_SIZE	16	/* compression table size in bytes */
+#define CBS_LUMA 	8	/* luminance CBS is composed of 1 8x8 coded block */
+#define CBS_CHROMA_W	(8 * 2)	/* chrominance CBS is composed of two 8x4 coded
+				 * blocks, with Cb CB first then Cr CB following
+				 */
+#define CBS_CHROMA_H	4
+
 size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps)
 {
 	int bytes_per_pixel = sps->bit_depth_luma_minus8 == 0 ? 1 : 2;
@@ -61,12 +68,44 @@ static size_t hantro_hevc_mv_size(const struct v4l2_ctrl_hevc_sps *sps)
 	return mv_size;
 }
 
+size_t hantro_hevc_luma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps)
+{
+	return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps);
+}
+
+static size_t hantro_hevc_luma_compress_size(const struct v4l2_ctrl_hevc_sps *sps)
+{
+	u32 pic_width_in_cbsy =
+		round_up((sps->pic_width_in_luma_samples + CBS_LUMA - 1) / CBS_LUMA, CBS_SIZE);
+	u32 pic_height_in_cbsy = (sps->pic_height_in_luma_samples + CBS_LUMA - 1) / CBS_LUMA;
+
+	return round_up(pic_width_in_cbsy * pic_height_in_cbsy, CBS_SIZE);
+}
+
+size_t hantro_hevc_chroma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps)
+{
+	return hantro_hevc_luma_compress_offset(sps) + hantro_hevc_luma_compress_size(sps);
+}
+
+static size_t hantro_hevc_chroma_compress_size(const struct v4l2_ctrl_hevc_sps *sps)
+{
+	u32 pic_width_in_cbsc =
+		round_up((sps->pic_width_in_luma_samples + CBS_CHROMA_W - 1)
+			 / CBS_CHROMA_W, CBS_SIZE);
+	u32 pic_height_in_cbsc = (sps->pic_height_in_luma_samples / 2 + CBS_CHROMA_H - 1)
+				 / CBS_CHROMA_H;
+
+	return round_up(pic_width_in_cbsc * pic_height_in_cbsc, CBS_SIZE);
+}
+
 static size_t hantro_hevc_ref_size(struct hantro_ctx *ctx)
 {
 	const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
 	const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
 
-	return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps);
+	return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps) +
+	       hantro_hevc_luma_compress_size(sps) +
+	       hantro_hevc_chroma_compress_size(sps);
 }
 
 static void hantro_hevc_ref_free(struct hantro_ctx *ctx)
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index df7b5e3a57b9..d5c002d0e765 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -255,6 +255,8 @@ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
 void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
 size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps);
 size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps);
+size_t hantro_hevc_luma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps);
+size_t hantro_hevc_chroma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps);
 
 static inline size_t
 hantro_h264_mv_size(unsigned int width, unsigned int height)
-- 
2.25.1



From brad at pensando.io  Mon Aug 23 09:30:47 2021
From: brad at pensando.io (Brad Larson)
Date: Mon, 23 Aug 2021 09:30:47 -0700
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CAMuHMdUz4vUQzXBHA9AiT3w6L20yBpgd0emVZJb=v_qw70qiJQ@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CAHp75VcG9KajNpDbewDq7QzotB6t7MfwiGk15FaobX+cmMVSzg@mail.gmail.com>
 <CAK9rFnwrA=W2Vk5yFwG4N_WS=eBXXnhtexA+tqgAYb6xOAO4oQ@mail.gmail.com>
 <CAHp75VdfrJ3JV_gL3xCLHOiw6Tj-5Ep7z5JKWUFKFbUt8gobcw@mail.gmail.com>
 <CAK9rFnx--z_pr_yR6CqGsH04ddwUtx4rxc7MxNNmy7ZSF86+Mg@mail.gmail.com>
 <CAMuHMdUz4vUQzXBHA9AiT3w6L20yBpgd0emVZJb=v_qw70qiJQ@mail.gmail.com>
Message-ID: <CAK9rFnw-j8whcsK-NQ4w4+sCdrumCk7Bb=J+KfsF9ZO2Tf5r5g@mail.gmail.com>

Hi Geert,

On Mon, Aug 23, 2021 at 12:50 AM Geert Uytterhoeven
<geert at linux-m68k.org> wrote:
>
> Hi Brad,
>
> On Mon, Aug 23, 2021 at 3:14 AM Brad Larson <brad at pensando.io> wrote:
> > On Mon, Mar 29, 2021 at 3:40 AM Andy Shevchenko
[...]
> > Regarding the above module question and Kconfig definition, since I
> > first looked at this and reviewed the comments I realized I should be
> > using builtin.  The file gpio/Kconfig is currently this
> >
> > config GPIO_ELBA_SPICS
> >         def_bool y
> >         depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST
>
> That means the driver will default to yes by merely enabling
> COMPILE_TEST, which is a no-go.
>
>     config GPIO_ELBA_SPICS
>             bool "one-line summary"
>             depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST
>             default y if ARCH_PENSANDO_ELBA_SOC

Thanks Geert, changed to this

--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -241,8 +241,9 @@ config GPIO_EIC_SPRD
          Say yes here to support Spreadtrum EIC device.

 config GPIO_ELBA_SPICS
+       bool "Pensando Elba SoC SPI Chip Select as GPIO support"
+       depends on ARCH_PENSANDO_ELBA_SOC
        def_bool y
-       depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST

Regards,
Brad


From maxime at cerno.tech  Mon Aug 23 09:31:14 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Mon, 23 Aug 2021 18:31:14 +0200
Subject: [PATCH 10/54] dt-bindings: display: panel-lvds: Document panel
 compatibles
In-Reply-To: <CAL_JsqJjnGhXpfvPWU0HM8YHk5PyDup7ors3ewa17vc0bnVCmQ@mail.gmail.com>
References: <20210721140424.725744-1-maxime@cerno.tech>
 <20210721140424.725744-11-maxime@cerno.tech>
 <20210722022947.GA3168293@robh.at.kernel.org>
 <20210818124304.2jxsf44bcbprcvbk@gilmour>
 <CAL_JsqJjnGhXpfvPWU0HM8YHk5PyDup7ors3ewa17vc0bnVCmQ@mail.gmail.com>
Message-ID: <20210823163114.ohmdpc7pn22p5ycd@gilmour>

Hi,

On Wed, Aug 18, 2021 at 08:48:46AM -0500, Rob Herring wrote:
> On Wed, Aug 18, 2021 at 7:43 AM Maxime Ripard <maxime at cerno.tech> wrote:
> >
> > Hi Rob, Sam,
> >
> > On Wed, Jul 21, 2021 at 08:29:47PM -0600, Rob Herring wrote:
> > > On Wed, Jul 21, 2021 at 04:03:40PM +0200, Maxime Ripard wrote:
> > > > The binding mentions that all the drivers using that driver must use a
> > > > vendor-specific compatible but never enforces it, nor documents the
> > > > vendor-specific compatibles.
> > > >
> > > > Let's make we document all of them, and that the binding will create an
> > > > error if we add one that isn't.
> > > >
> > > > Cc: dri-devel at lists.freedesktop.org
> > > > Cc: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > > > Cc: Sam Ravnborg <sam at ravnborg.org>
> > > > Cc: Thierry Reding <thierry.reding at gmail.com>
> > > > Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> > > > ---
> > > >  .../bindings/display/panel/lvds.yaml           | 18 ++++++++++++------
> > > >  1 file changed, 12 insertions(+), 6 deletions(-)
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/display/panel/lvds.yaml b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > > index 49460c9dceea..d1513111eb48 100644
> > > > --- a/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > > +++ b/Documentation/devicetree/bindings/display/panel/lvds.yaml
> > > > @@ -31,12 +31,18 @@ allOf:
> > > >
> > > >  properties:
> > > >    compatible:
> > > > -    contains:
> > > > -      const: panel-lvds
> > > > -    description:
> > > > -      Shall contain "panel-lvds" in addition to a mandatory panel-specific
> > > > -      compatible string defined in individual panel bindings. The "panel-lvds"
> > > > -      value shall never be used on its own.
> > > > +    items:
> > > > +      - enum:
> > > > +          - advantech,idk-1110wr
> > >
> > > At least this one is documented elsewhere.
> >
> > Indeed, I missed it.
> >
> > > You can add 'minItems: 2' if you want to just enforce having 2 compatibles. Or do:
> > >
> > > items:
> > >   - {}
> > >   - const: panel-lvds
> > >
> > > Which also enforces the order.
> >
> > It's not just about the order since a missing compatible will also raise
> > a warning.
> >
> > Some of those panels have a binding of their own, but some probably
> > won't (and I can't find anything specific about the one I'm most
> > interested in: tbs,a711-panel)
> >
> > Can we have something like:
> >
> > compatible:
> >   oneOf:
> >     - items:
> >       - enum:
> >         - tbs,a711-panel
> >       - const: panel-lvds
> >
> >     - items:
> >       - {}
> >       - const: panel-lvds
> >
> > That would work for both cases I guess?
> 
> No, both conditions will be true. If you use 'anyOf', then we're never
> really checking the specific compatible.
> 
> I think the problem here is trying to mix a common binding (aka an
> incomplete collection of properties) and a specific binding.

I'm not entirely sure why we have specific bindings for this in the
first place.

We currently have 6 specific bindings, and for 5 of them the only
specific thing in there are the data-mapping value to force and their
dimension.

I'd argue that the dimension shouldn't even be set in stone: you could
very well imagine a screen with exactly the same timings but a different
size. We would consider it compatible.

And the data-mapping can be dealt with with an if clause fairly easily.

And for the last one, the specific thing about it is that it's using a
dual-link output, which is a generic binding and could thus be described
in panel-lvds too.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210823/a6494b05/attachment-0001.sig>

From kuba at kernel.org  Mon Aug 23 09:44:25 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 23 Aug 2021 09:44:25 -0700
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <20210823143754.14294-1-michael.riesch@wolfvision.net>
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
Message-ID: <20210823094425.78d7a73e@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Mon, 23 Aug 2021 16:37:54 +0200 Michael Riesch wrote:
> In the commit to be reverted, support for power management was
> introduced to the Rockchip glue code. Later, power management support
> was introduced to the stmmac core code, resulting in multiple
> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.

Can we get a Fixes tag? I.e. reference to the earliest commit where 
the warning can be triggered?

> The multiple invocations happen in rk_gmac_powerup and
> stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
> stmmac_{dvr_remove, suspend}, respectively, which are always called
> in conjunction.


From robh at kernel.org  Mon Aug 23 09:51:26 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 23 Aug 2021 11:51:26 -0500
Subject: [PATCH v2] arm/arm64: dts: Fix remaining dtc 'unit_address_format'
 warnings
Message-ID: <20210823165126.2320910-1-robh@kernel.org>

Fix all the remaining dtc 'unit_address_format' warnings except for the ones
related to 'register-bit-led'. For those, we need to decide on and document
the node name.

Signed-off-by: Rob Herring <robh at kernel.org>
---
v2:
 - Add back intergrator vco1/2 labels.

Arnd, Olof,

Please apply this directly.

Rob
---
 arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts  |  2 +-
 arch/arm/boot/dts/at91-sama5d27_som1.dtsi     | 12 ++++----
 arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts     |  4 +--
 arch/arm/boot/dts/at91-sama5d2_xplained.dts   | 14 +++++-----
 arch/arm/boot/dts/dm8148-evm.dts              |  8 +++---
 arch/arm/boot/dts/dm8168-evm.dts              |  8 +++---
 arch/arm/boot/dts/integratorap-im-pd1.dts     |  4 +--
 arch/arm/boot/dts/keystone-k2e-netcp.dtsi     |  2 +-
 arch/arm/boot/dts/keystone-k2hk-netcp.dtsi    |  2 +-
 arch/arm/boot/dts/keystone-k2l-netcp.dtsi     |  2 +-
 arch/arm/boot/dts/nuvoton-npcm750-evb.dts     |  4 +--
 arch/arm/boot/dts/qcom-apq8064.dtsi           | 24 ++++++++--------
 arch/arm/boot/dts/qcom-sdx55.dtsi             |  2 +-
 arch/arm/boot/dts/ste-ab8500.dtsi             | 28 +++++++++----------
 arch/arm/boot/dts/ste-ab8505.dtsi             | 24 ++++++++--------
 arch/arm/boot/dts/ste-db8500.dtsi             |  6 ++--
 arch/arm/boot/dts/ste-db8520.dtsi             |  6 ++--
 .../arm/boot/dts/ste-ux500-samsung-janice.dts |  2 +-
 arch/arm/boot/dts/stm32429i-eval.dts          |  2 +-
 arch/arm/boot/dts/stm32f469-disco.dts         |  2 +-
 .../marvell/armada-8040-clearfog-gt-8k.dts    |  2 +-
 arch/arm64/boot/dts/marvell/cn9130-db.dts     |  2 +-
 arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  2 +-
 23 files changed, 82 insertions(+), 82 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
index d26a9e16ff7c..97cc217fb099 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
@@ -303,7 +303,7 @@ gpio at 0 {
 			type = <PCA955X_TYPE_GPIO>;
 		};
 
-		gpio at 01 {
+		gpio at 1 {
 			reg = <1>;
 			type = <PCA955X_TYPE_GPIO>;
 		};
diff --git a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi
index e3251f3e3eaa..b48ac3b62a31 100644
--- a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi
+++ b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi
@@ -47,32 +47,32 @@ flash at 0 {
 					spi-rx-bus-width = <4>;
 					m25p,fast-read;
 
-					at91bootstrap at 00000000 {
+					at91bootstrap at 0 {
 						label = "at91bootstrap";
 						reg = <0x00000000 0x00040000>;
 					};
 
-					bootloader at 00040000 {
+					bootloader at 40000 {
 						label = "bootloader";
 						reg = <0x00040000 0x000c0000>;
 					};
 
-					bootloaderenvred at 00100000 {
+					bootloaderenvred at 100000 {
 						label = "bootloader env redundant";
 						reg = <0x00100000 0x00040000>;
 					};
 
-					bootloaderenv at 00140000 {
+					bootloaderenv at 140000 {
 						label = "bootloader env";
 						reg = <0x00140000 0x00040000>;
 					};
 
-					dtb at 00180000 {
+					dtb at 180000 {
 						label = "device tree";
 						reg = <0x00180000 0x00080000>;
 					};
 
-					kernel at 00200000 {
+					kernel at 200000 {
 						label = "kernel";
 						reg = <0x00200000 0x00600000>;
 					};
diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
index dfd150eb0fd8..a5515b0dd346 100644
--- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
@@ -93,12 +93,12 @@ bootloader at 40000 {
 							reg = <0x40000 0xc0000>;
 						};
 
-						bootloaderenvred at 0x100000 {
+						bootloaderenvred at 100000 {
 							label = "bootloader env redundant";
 							reg = <0x100000 0x40000>;
 						};
 
-						bootloaderenv at 0x140000 {
+						bootloaderenv at 140000 {
 							label = "bootloader env";
 							reg = <0x140000 0x40000>;
 						};
diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
index 509c732a0d8b..908b2cc22844 100644
--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
@@ -95,37 +95,37 @@ flash at 0 {
 					spi-rx-bus-width = <4>;
 					m25p,fast-read;
 
-					at91bootstrap at 00000000 {
+					at91bootstrap at 0 {
 						label = "at91bootstrap";
 						reg = <0x00000000 0x00040000>;
 					};
 
-					bootloader at 00040000 {
+					bootloader at 40000 {
 						label = "bootloader";
 						reg = <0x00040000 0x000c0000>;
 					};
 
-					bootloaderenvred at 00100000 {
+					bootloaderenvred at 100000 {
 						label = "bootloader env redundant";
 						reg = <0x00100000 0x00040000>;
 					};
 
-					bootloaderenv at 00140000 {
+					bootloaderenv at 140000 {
 						label = "bootloader env";
 						reg = <0x00140000 0x00040000>;
 					};
 
-					dtb at 00180000 {
+					dtb at 180000 {
 						label = "device tree";
 						reg = <0x00180000 0x00080000>;
 					};
 
-					kernel at 00200000 {
+					kernel at 200000 {
 						label = "kernel";
 						reg = <0x00200000 0x00600000>;
 					};
 
-					misc at 00800000 {
+					misc at 800000 {
 						label = "misc";
 						reg = <0x00800000 0x00000000>;
 					};
diff --git a/arch/arm/boot/dts/dm8148-evm.dts b/arch/arm/boot/dts/dm8148-evm.dts
index 91d1018ab75f..8ef48c00f98d 100644
--- a/arch/arm/boot/dts/dm8148-evm.dts
+++ b/arch/arm/boot/dts/dm8148-evm.dts
@@ -80,19 +80,19 @@ partition at 0 {
 			label = "X-Loader";
 			reg = <0 0x80000>;
 		};
-		partition at 0x80000 {
+		partition at 80000 {
 			label = "U-Boot";
 			reg = <0x80000 0x1c0000>;
 		};
-		partition at 0x1c0000 {
+		partition at 1c0000 {
 			label = "Environment";
 			reg = <0x240000 0x40000>;
 		};
-		partition at 0x280000 {
+		partition at 280000 {
 			label = "Kernel";
 			reg = <0x280000 0x500000>;
 		};
-		partition at 0x780000 {
+		partition at 780000 {
 			label = "Filesystem";
 			reg = <0x780000 0xf880000>;
 		};
diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts
index cf05d532db65..5126e2d72ed7 100644
--- a/arch/arm/boot/dts/dm8168-evm.dts
+++ b/arch/arm/boot/dts/dm8168-evm.dts
@@ -154,19 +154,19 @@ partition at 0 {
 			label = "X-Loader";
 			reg = <0 0x80000>;
 		};
-		partition at 0x80000 {
+		partition at 80000 {
 			label = "U-Boot";
 			reg = <0x80000 0x1c0000>;
 		};
-		partition at 0x1c0000 {
+		partition at 1c0000 {
 			label = "Environment";
 			reg = <0x240000 0x40000>;
 		};
-		partition at 0x280000 {
+		partition at 280000 {
 			label = "Kernel";
 			reg = <0x280000 0x500000>;
 		};
-		partition at 0x780000 {
+		partition at 780000 {
 			label = "Filesystem";
 			reg = <0x780000 0xf880000>;
 		};
diff --git a/arch/arm/boot/dts/integratorap-im-pd1.dts b/arch/arm/boot/dts/integratorap-im-pd1.dts
index 1412a1a968fc..0614f82b808e 100644
--- a/arch/arm/boot/dts/integratorap-im-pd1.dts
+++ b/arch/arm/boot/dts/integratorap-im-pd1.dts
@@ -29,7 +29,7 @@ syscon at 0 {
 		compatible = "arm,im-pd1-syscon", "syscon";
 		reg = <0x00000000 0x1000>;
 
-		vco1: clock at 00 {
+		vco1: vco1-clock {
 			compatible = "arm,impd1-vco1";
 			#clock-cells = <0>;
 			lock-offset = <0x08>;
@@ -38,7 +38,7 @@ vco1: clock at 00 {
 			clock-output-names = "IM-PD1-VCO1";
 		};
 
-		vco2: clock at 04 {
+		vco2: vco2-clock {
 			compatible = "arm,impd1-vco2";
 			#clock-cells = <0>;
 			lock-offset = <0x08>;
diff --git a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
index ad15e77874b1..71064483d34f 100644
--- a/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
+++ b/arch/arm/boot/dts/keystone-k2e-netcp.dtsi
@@ -95,7 +95,7 @@ pdsps {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		pdsp0 at 0x2a10000 {
+		pdsp0 at 2a10000 {
 			reg = <0x2a10000 0x1000    /*iram */
 			       0x2a0f000 0x100     /*reg*/
 			       0x2a0c000 0x3c8	   /*intd */
diff --git a/arch/arm/boot/dts/keystone-k2hk-netcp.dtsi b/arch/arm/boot/dts/keystone-k2hk-netcp.dtsi
index d5a6c1f5633c..022d93c366c7 100644
--- a/arch/arm/boot/dts/keystone-k2hk-netcp.dtsi
+++ b/arch/arm/boot/dts/keystone-k2hk-netcp.dtsi
@@ -112,7 +112,7 @@ pdsps {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		pdsp0 at 0x2a10000 {
+		pdsp0 at 2a10000 {
 			reg = <0x2a10000 0x1000    /*iram */
 			       0x2a0f000 0x100     /*reg*/
 			       0x2a0c000 0x3c8	   /*intd */
diff --git a/arch/arm/boot/dts/keystone-k2l-netcp.dtsi b/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
index c1f982604145..e96ca664abc2 100644
--- a/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
+++ b/arch/arm/boot/dts/keystone-k2l-netcp.dtsi
@@ -94,7 +94,7 @@ pdsps {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ranges;
-		pdsp0 at 0x2a10000 {
+		pdsp0 at 2a10000 {
 			reg = <0x2a10000 0x1000    /*iram */
 			       0x2a0f000 0x100     /*reg*/
 			       0x2a0c000 0x3c8	   /*intd */
diff --git a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
index dea3dbc4a6a5..0334641f8829 100644
--- a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
+++ b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
@@ -105,11 +105,11 @@ rootfs at 600000 {
 				label = "rootfs";
 				reg = <0x0600000 0x700000>;
 				};
-			spare1 at D00000 {
+			spare1 at d00000 {
 				label = "spare1";
 				reg = <0x0D00000 0x200000>;
 				};
-			spare2 at 0F00000 {
+			spare2 at f00000 {
 				label = "spare2";
 				reg = <0x0F00000 0x200000>;
 				};
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 2687c4e890ba..8294ad1548fc 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -766,40 +766,40 @@ xoadc: xoadc at 197 {
 					#size-cells = <0>;
 					#io-channel-cells = <2>;
 
-					vcoin: adc-channel at 00 {
+					vcoin: adc-channel at 0 {
 						reg = <0x00 0x00>;
 					};
-					vbat: adc-channel at 01 {
+					vbat: adc-channel at 1 {
 						reg = <0x00 0x01>;
 					};
-					dcin: adc-channel at 02 {
+					dcin: adc-channel at 2 {
 						reg = <0x00 0x02>;
 					};
-					vph_pwr: adc-channel at 04 {
+					vph_pwr: adc-channel at 4 {
 						reg = <0x00 0x04>;
 					};
-					batt_therm: adc-channel at 08 {
+					batt_therm: adc-channel at 8 {
 						reg = <0x00 0x08>;
 					};
-					batt_id: adc-channel at 09 {
+					batt_id: adc-channel at 9 {
 						reg = <0x00 0x09>;
 					};
-					usb_vbus: adc-channel at 0a {
+					usb_vbus: adc-channel at a {
 						reg = <0x00 0x0a>;
 					};
-					die_temp: adc-channel at 0b {
+					die_temp: adc-channel at b {
 						reg = <0x00 0x0b>;
 					};
-					ref_625mv: adc-channel at 0c {
+					ref_625mv: adc-channel at c {
 						reg = <0x00 0x0c>;
 					};
-					ref_1250mv: adc-channel at 0d {
+					ref_1250mv: adc-channel at d {
 						reg = <0x00 0x0d>;
 					};
-					chg_temp: adc-channel at 0e {
+					chg_temp: adc-channel at e {
 						reg = <0x00 0x0e>;
 					};
-					ref_muxoff: adc-channel at 0f {
+					ref_muxoff: adc-channel at f {
 						reg = <0x00 0x0f>;
 					};
 				};
diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi
index 0057c7c04d31..1e6ce035f76a 100644
--- a/arch/arm/boot/dts/qcom-sdx55.dtsi
+++ b/arch/arm/boot/dts/qcom-sdx55.dtsi
@@ -143,7 +143,7 @@ tz_mem: memory at 8ff00000 {
 			reg = <0x8ff00000 0x100000>;
 		};
 
-		tz_apps_mem: memory at 0x90000000 {
+		tz_apps_mem: memory at 90000000 {
 			no-map;
 			reg = <0x90000000 0x500000>;
 		};
diff --git a/arch/arm/boot/dts/ste-ab8500.dtsi b/arch/arm/boot/dts/ste-ab8500.dtsi
index d0fe3f9aa183..9b735919a4d1 100644
--- a/arch/arm/boot/dts/ste-ab8500.dtsi
+++ b/arch/arm/boot/dts/ste-ab8500.dtsi
@@ -58,46 +58,46 @@ gpadc: ab8500-gpadc {
 					#io-channel-cells = <1>;
 
 					/* GPADC channels */
-					bat_ctrl: channel at 01 {
+					bat_ctrl: channel at 1 {
 						reg = <0x01>;
 					};
-					btemp_ball: channel at 02 {
+					btemp_ball: channel at 2 {
 						reg = <0x02>;
 					};
-					main_charger_v: channel at 03 {
+					main_charger_v: channel at 3 {
 						reg = <0x03>;
 					};
-					acc_detect1: channel at 04 {
+					acc_detect1: channel at 4 {
 						reg = <0x04>;
 					};
-					acc_detect2: channel at 05 {
+					acc_detect2: channel at 5 {
 						reg = <0x05>;
 					};
-					adc_aux1: channel at 06 {
+					adc_aux1: channel at 6 {
 						reg = <0x06>;
 					};
-					adc_aux2: channel at 07 {
+					adc_aux2: channel at 7 {
 						reg = <0x07>;
 					};
-					main_batt_v: channel at 08 {
+					main_batt_v: channel at 8 {
 						reg = <0x08>;
 					};
-					vbus_v: channel at 09 {
+					vbus_v: channel at 9 {
 						reg = <0x09>;
 					};
-					main_charger_c: channel at 0a {
+					main_charger_c: channel at a {
 						reg = <0x0a>;
 					};
-					usb_charger_c: channel at 0b {
+					usb_charger_c: channel at b {
 						reg = <0x0b>;
 					};
-					bk_bat_v: channel at 0c {
+					bk_bat_v: channel at c {
 						reg = <0x0c>;
 					};
-					die_temp: channel at 0d {
+					die_temp: channel at d {
 						reg = <0x0d>;
 					};
-					usb_id: channel at 0e {
+					usb_id: channel at e {
 						reg = <0x0e>;
 					};
 					xtal_temp: channel at 12 {
diff --git a/arch/arm/boot/dts/ste-ab8505.dtsi b/arch/arm/boot/dts/ste-ab8505.dtsi
index 0defc15b9bbc..02ce833d142a 100644
--- a/arch/arm/boot/dts/ste-ab8505.dtsi
+++ b/arch/arm/boot/dts/ste-ab8505.dtsi
@@ -54,40 +54,40 @@ gpadc: ab8500-gpadc {
 					#io-channel-cells = <1>;
 
 					/* GPADC channels */
-					bat_ctrl: channel at 01 {
+					bat_ctrl: channel at 1 {
 						reg = <0x01>;
 					};
-					btemp_ball: channel at 02 {
+					btemp_ball: channel at 2 {
 						reg = <0x02>;
 					};
-					acc_detect1: channel at 04 {
+					acc_detect1: channel at 4 {
 						reg = <0x04>;
 					};
-					acc_detect2: channel at 05 {
+					acc_detect2: channel at 5 {
 						reg = <0x05>;
 					};
-					adc_aux1: channel at 06 {
+					adc_aux1: channel at 6 {
 						reg = <0x06>;
 					};
-					adc_aux2: channel at 07 {
+					adc_aux2: channel at 7 {
 						reg = <0x07>;
 					};
-					main_batt_v: channel at 08 {
+					main_batt_v: channel at 8 {
 						reg = <0x08>;
 					};
-					vbus_v: channel at 09 {
+					vbus_v: channel at 9 {
 						reg = <0x09>;
 					};
-					charger_c: channel at 0b {
+					charger_c: channel at b {
 						reg = <0x0b>;
 					};
-					bk_bat_v: channel at 0c {
+					bk_bat_v: channel at c {
 						reg = <0x0c>;
 					};
-					die_temp: channel at 0d {
+					die_temp: channel at d {
 						reg = <0x0d>;
 					};
-					usb_id: channel at 0e {
+					usb_id: channel at e {
 						reg = <0x0e>;
 					};
 				};
diff --git a/arch/arm/boot/dts/ste-db8500.dtsi b/arch/arm/boot/dts/ste-db8500.dtsi
index 344d29853bf7..b67d3bd65de8 100644
--- a/arch/arm/boot/dts/ste-db8500.dtsi
+++ b/arch/arm/boot/dts/ste-db8500.dtsi
@@ -19,19 +19,19 @@ reserved-memory {
 		ranges;
 
 		/* Modem trace memory */
-		ram at 06000000 {
+		ram at 6000000 {
 			reg = <0x06000000 0x00f00000>;
 			no-map;
 		};
 
 		/* Modem shared memory */
-		ram at 06f00000 {
+		ram at 6f00000 {
 			reg = <0x06f00000 0x00100000>;
 			no-map;
 		};
 
 		/* Modem private memory */
-		ram at 07000000 {
+		ram at 7000000 {
 			reg = <0x07000000 0x01000000>;
 			no-map;
 		};
diff --git a/arch/arm/boot/dts/ste-db8520.dtsi b/arch/arm/boot/dts/ste-db8520.dtsi
index 287804e9e183..60d5fb806969 100644
--- a/arch/arm/boot/dts/ste-db8520.dtsi
+++ b/arch/arm/boot/dts/ste-db8520.dtsi
@@ -19,19 +19,19 @@ reserved-memory {
 		ranges;
 
 		/* Modem trace memory */
-		ram at 06000000 {
+		ram at 6000000 {
 			reg = <0x06000000 0x00f00000>;
 			no-map;
 		};
 
 		/* Modem shared memory */
-		ram at 06f00000 {
+		ram at 6f00000 {
 			reg = <0x06f00000 0x00100000>;
 			no-map;
 		};
 
 		/* Modem private memory */
-		ram at 07000000 {
+		ram at 7000000 {
 			reg = <0x07000000 0x01000000>;
 			no-map;
 		};
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
index 25af066f6f3a..aee8439b7e8f 100644
--- a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+++ b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
@@ -580,7 +580,7 @@ i2c-gate {
 					#size-cells = <0>;
 
 					/* Bosch BMA222 accelerometer */
-					accelerometer at 08 {
+					accelerometer at 8 {
 						compatible = "bosch,bma222";
 						reg = <0x08>;
 						mount-matrix = "0", "1", "0",
diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index 9ac1ffe53413..cb46326a8c75 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -60,7 +60,7 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x2000000>;
 	};
diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts
index 8c982ae79f43..30905ce672a0 100644
--- a/arch/arm/boot/dts/stm32f469-disco.dts
+++ b/arch/arm/boot/dts/stm32f469-disco.dts
@@ -60,7 +60,7 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x00000000 0x1000000>;
 	};
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
index 0ec0d5625818..8729c6467303 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
@@ -20,7 +20,7 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x80000000>;
 	};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dts b/arch/arm64/boot/dts/marvell/cn9130-db.dts
index 9758609541c7..47a3b97a0363 100644
--- a/arch/arm64/boot/dts/marvell/cn9130-db.dts
+++ b/arch/arm64/boot/dts/marvell/cn9130-db.dts
@@ -27,7 +27,7 @@ aliases {
 		spi2 = &cp0_spi1;
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x80000000>;
 	};
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 9fa5b028e4f3..23ee1bfa4318 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -151,7 +151,7 @@ reserved-memory {
 		#size-cells = <2>;
 		ranges;
 
-		rpm_msg_ram: memory at 0x60000 {
+		rpm_msg_ram: memory at 60000 {
 			reg = <0x0 0x60000 0x0 0x6000>;
 			no-map;
 		};
-- 
2.30.2



From maz at kernel.org  Mon Aug 23 09:57:08 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 23 Aug 2021 17:57:08 +0100
Subject: [PATCH] PCI: uniphier: Serialize INTx masking/unmasking
In-Reply-To: <20210823150927.jhobzfxy6e4s663r@pali>
References: <1629717500-19396-1-git-send-email-hayashi.kunihiko@socionext.com>
 <20210823150927.jhobzfxy6e4s663r@pali>
Message-ID: <87zgt8p09n.wl-maz@kernel.org>

On Mon, 23 Aug 2021 16:09:27 +0100,
Pali Roh?r <pali at kernel.org> wrote:
> 
> + Marc (who originally reported this issue)
> 
> On Monday 23 August 2021 20:18:20 Kunihiko Hayashi wrote:
> > The condition register PCI_RCV_INTX is used in irq_mask(), irq_unmask()
> > and irq_ack() callbacks. Accesses to register can occur at the same time
> > without a lock.
> > Add a lock into each callback to prevent the issue.
> > 
> > Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
> > Suggested-by: Pali Roh?r <pali at kernel.org>
> > Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
> 
> Acked-by: Pali Roh?r <pali at kernel.org>
> 
> > ---
> >  drivers/pci/controller/dwc/pcie-uniphier.c | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> > 
> > The previous patch is as follows:
> > https://lore.kernel.org/linux-pci/1629370566-29984-1-git-send-email-hayashi.kunihiko at socionext.com/
> > 
> > Changes in the previous patch:
> > - Change the subject and commit message
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
> > index ebe43e9..5075714 100644
> > --- a/drivers/pci/controller/dwc/pcie-uniphier.c
> > +++ b/drivers/pci/controller/dwc/pcie-uniphier.c
> > @@ -186,12 +186,17 @@ static void uniphier_pcie_irq_ack(struct irq_data *d)
> >  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
> >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> >  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> > +	unsigned long flags;
> >  	u32 val;
> >  
> > +	raw_spin_lock_irqsave(&pp->lock, flags);
> > +
> >  	val = readl(priv->base + PCL_RCV_INTX);
> >  	val &= ~PCL_RCV_INTX_ALL_STATUS;
> >  	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
> >  	writel(val, priv->base + PCL_RCV_INTX);
> > +
> > +	raw_spin_unlock_irqrestore(&pp->lock, flags);
> >  }
> >  
> >  static void uniphier_pcie_irq_mask(struct irq_data *d)
> > @@ -199,12 +204,17 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
> >  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
> >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> >  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> > +	unsigned long flags;
> >  	u32 val;
> >  
> > +	raw_spin_lock_irqsave(&pp->lock, flags);
> > +
> >  	val = readl(priv->base + PCL_RCV_INTX);
> >  	val &= ~PCL_RCV_INTX_ALL_MASK;
> >  	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);

This looks extremely suspicious. You clear all the INTX mask bits, and
only set the one you need. How about the pre-existing bits?

> >  	writel(val, priv->base + PCL_RCV_INTX);
> > +
> > +	raw_spin_unlock_irqrestore(&pp->lock, flags);
> >  }
> >  
> >  static void uniphier_pcie_irq_unmask(struct irq_data *d)
> > @@ -212,12 +222,17 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
> >  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
> >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> >  	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> > +	unsigned long flags;
> >  	u32 val;
> >  
> > +	raw_spin_lock_irqsave(&pp->lock, flags);
> > +
> >  	val = readl(priv->base + PCL_RCV_INTX);
> >  	val &= ~PCL_RCV_INTX_ALL_MASK;
> >  	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);

And by the same token, this second line is totally useless.

I think masking/unmasking is broken in this driver, locking or not.

	M.

-- 
Without deviation from the norm, progress is not possible.


From romain.perier at gmail.com  Mon Aug 23 10:16:13 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Mon, 23 Aug 2021 19:16:13 +0200
Subject: [PATCH v4 3/3] ARM: dts: mstar: Add rtc device node
In-Reply-To: <20210823171613.18941-1-romain.perier@gmail.com>
References: <20210823171613.18941-1-romain.perier@gmail.com>
Message-ID: <20210823171613.18941-4-romain.perier@gmail.com>

This adds the definition of the rtc device node. The RTC being able to
work with the oscillator at 12Mhz for now, it shares the same xtal than
the watchdog.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 982dba9d28eb..89ebfe4f29da 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -110,12 +110,20 @@ reboot {
 				mask = <0x79>;
 			};
 
+			rtc at 2400 {
+				compatible = "mstar,msc313-rtc";
+				reg = <0x2400 0x40>;
+				clocks = <&xtal_div2>;
+				interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
 			watchdog at 6000 {
 				compatible = "mstar,msc313e-wdt";
 				reg = <0x6000 0x1f>;
 				clocks = <&xtal_div2>;
 			};
 
+
 			intc_fiq: interrupt-controller at 201310 {
 				compatible = "mstar,mst-intc";
 				reg = <0x201310 0x40>;
-- 
2.30.2



From romain.perier at gmail.com  Mon Aug 23 10:16:10 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Mon, 23 Aug 2021 19:16:10 +0200
Subject: [PATCH v4 0/3] Add RTC for MStar SoCs
Message-ID: <20210823171613.18941-1-romain.perier@gmail.com>

This patches series adds a new driver for the RTC found in the Mstar
MSC313e SoCs and newer. It adds a basic rtc driver, the corresponding
devicetree bindings and its documentation.

The rtctest (from selftests) has been passed on this driver, with the
following output:
$ rtctest 
TAP version 13
1..7
# Starting 7 tests from 2 test cases.
#  RUN           rtc.date_read ...
# rtctest.c:47:date_read:Current RTC date/time is 01/01/1970 00:02:03.
#            OK  rtc.date_read
ok 1 rtc.date_read
#  RUN           rtc.uie_read ...
#            OK  rtc.uie_read
ok 2 rtc.uie_read
#  RUN           rtc.uie_select ...
#            OK  rtc.uie_select
ok 3 rtc.uie_select
#  RUN           rtc.alarm_alm_set ...
# rtctest.c:136:alarm_alm_set:Alarm time now set to 00:02:12.
# rtctest.c:156:alarm_alm_set:data: 1a0
#            OK  rtc.alarm_alm_set
ok 4 rtc.alarm_alm_set
#  RUN           rtc.alarm_wkalm_set ...
# rtctest.c:192:alarm_wkalm_set:Alarm time now set to 01/01/1970 00:02:15.
#            OK  rtc.alarm_wkalm_set
ok 5 rtc.alarm_wkalm_set
#  RUN           rtc.alarm_alm_set_minute ...
# rtctest.c:238:alarm_alm_set_minute:Alarm time now set to 00:03:00.
# rtctest.c:258:alarm_alm_set_minute:data: 1a0
#            OK  rtc.alarm_alm_set_minute
ok 6 [  180.545015] random: fast init done
rtc.alarm_alm_set_minute
#  RUN           rtc.alarm_wkalm_set_minute ...
# rtctest.c:294:alarm_wkalm_set_minute:Alarm time now set to 01/01/1970 00:04:00.
#            OK  rtc.alarm_wkalm_set_minute
ok 7 rtc.alarm_wkalm_set_minute
# PASSED: 7 / 7 tests passed.
# Totals: pass:7 fail:0 xfail:0 xpass:0 skip:0 error:0

Changes since v3:
- Fixed bad device table in MODULE_DEVICE_TABLE()
- Use reverse christmas tree ordering for local variables in the probe()
  function
- Removed the "clk" field from the msc313_rtc data structure (not
  required, only used in the probe function)

Changes since v2:
- Added dual-license header to the dt-bindings documentation
- Reordered dts entries, so the rtc device_node is before the watchdog
  device_node (because it has a lower address)
- Updated rtc range_max to U32_MAX
- Leave range_min to 0 (default value when it is not set at all)
- Fixed the CNT_EN_BIT logic, so .read_time will only read the time when
  the RTC has been previously set and has a valid state (which is not
  the case after a POR).

Changes since v1:
- Fixed the DT bindings documentation and fixed dt_binding_check (an
  include was missing)
- Added || COMPILE_TEST to kconfig
- Removed rtc_valid_tm from msc313_rtc_read_time()
- Removed the last write of the msc313_rtc_set_time() function (not
  required) and improved comments
- Replaced the relaxed io by normal io in msc313_rtc_interrupt()
- Added checks to be sure that the alarm fired in msc313_rtc_interrupt()
- Removed msc313_rtc_remove() (replaced by devm_add_action_or_reset)
- Removed unnecessary software reset of the IP in the probe function
  (the soft reset is never executed, it is a mistake from the initial
  refactoring)
- Switched to devm_rtc_allocate_device() and devm_rtc_register_device(),
  and dropped the error message related to the rtc device allocation
- Added an RTC range by setting .range_min and .range_max
- Added the "start-year" property to the DT bindings documentation

Daniel Palmer (1):
  rtc: Add support for the MSTAR MSC313 RTC

Romain Perier (2):
  dt-bindings: rtc: Add Mstar MSC313e RTC devicetree bindings
    documentation
  ARM: dts: mstar: Add rtc device node

 .../bindings/rtc/mstar,msc313-rtc.yaml        |  49 ++++
 MAINTAINERS                                   |   1 +
 arch/arm/boot/dts/mstar-v7.dtsi               |   8 +
 drivers/rtc/Kconfig                           |  10 +
 drivers/rtc/Makefile                          |   1 +
 drivers/rtc/rtc-msc313.c                      | 258 ++++++++++++++++++
 6 files changed, 327 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
 create mode 100644 drivers/rtc/rtc-msc313.c

-- 
2.30.2



From romain.perier at gmail.com  Mon Aug 23 10:16:12 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Mon, 23 Aug 2021 19:16:12 +0200
Subject: [PATCH v4 2/3] rtc: Add support for the MSTAR MSC313 RTC
In-Reply-To: <20210823171613.18941-1-romain.perier@gmail.com>
References: <20210823171613.18941-1-romain.perier@gmail.com>
Message-ID: <20210823171613.18941-3-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

This adds support for the RTC block on the Mstar MSC313e SoCs and newer.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Co-developed-by: Romain Perier <romain.perier at gmail.com>
Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 MAINTAINERS              |   1 +
 drivers/rtc/Kconfig      |  10 ++
 drivers/rtc/Makefile     |   1 +
 drivers/rtc/rtc-msc313.c | 258 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 270 insertions(+)
 create mode 100644 drivers/rtc/rtc-msc313.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fd25e4ecf0b9..ebacdd5e8878 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2220,6 +2220,7 @@ F:	arch/arm/boot/dts/mstar-*
 F:	arch/arm/mach-mstar/
 F:	drivers/clk/mstar/
 F:	drivers/gpio/gpio-msc313.c
+F:	drivers/rtc/rtc-msc313.c
 F:	drivers/watchdog/msc313e_wdt.c
 F:	include/dt-bindings/clock/mstar-*
 F:	include/dt-bindings/gpio/msc313-gpio.h
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 12153d5801ce..9ce4baab5fcf 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1925,4 +1925,14 @@ config RTC_DRV_WILCO_EC
 	  This can also be built as a module. If so, the module will
 	  be named "rtc_wilco_ec".
 
+config RTC_DRV_MSC313
+	tristate "MStar MSC313 RTC"
+        depends on ARCH_MSTARV7 || COMPILE_TEST
+	help
+	  If you say yes here you get support for the Mstar MSC313e On-Chip
+	  Real Time Clock.
+
+	  This driver can also be built as a module, if so, the module
+	  will be called "rtc-msc313".
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2dd0dd956b0e..5efda8a60cee 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_RTC_DRV_MCP795)	+= rtc-mcp795.o
 obj-$(CONFIG_RTC_DRV_MESON)	+= rtc-meson.o
 obj-$(CONFIG_RTC_DRV_MOXART)	+= rtc-moxart.o
 obj-$(CONFIG_RTC_DRV_MPC5121)	+= rtc-mpc5121.o
+obj-$(CONFIG_RTC_DRV_MSC313)	+= rtc-msc313.o
 obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
 obj-$(CONFIG_RTC_DRV_MT2712)	+= rtc-mt2712.o
 obj-$(CONFIG_RTC_DRV_MT6397)	+= rtc-mt6397.o
diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c
new file mode 100644
index 000000000000..f493ca5f181b
--- /dev/null
+++ b/drivers/rtc/rtc-msc313.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.
+ * Based on "Real Time Clock driver for msb252x." that was contained
+ * in various MStar kernels.
+ *
+ * (C) 2019 Daniel Palmer
+ * (C) 2021 Romain Perier
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* Registers */
+#define REG_RTC_CTRL		0x00
+#define REG_RTC_FREQ_CW_L	0x04
+#define REG_RTC_FREQ_CW_H	0x08
+#define REG_RTC_LOAD_VAL_L	0x0C
+#define REG_RTC_LOAD_VAL_H	0x10
+#define REG_RTC_MATCH_VAL_L	0x14
+#define REG_RTC_MATCH_VAL_H	0x18
+#define REG_RTC_STATUS_INT	0x1C
+#define REG_RTC_CNT_VAL_L	0x20
+#define REG_RTC_CNT_VAL_H	0x24
+
+/* Control bits for REG_RTC_CTRL */
+#define SOFT_RSTZ_BIT		BIT(0)
+#define CNT_EN_BIT		BIT(1)
+#define WRAP_EN_BIT		BIT(2)
+#define LOAD_EN_BIT		BIT(3)
+#define READ_EN_BIT		BIT(4)
+#define INT_MASK_BIT		BIT(5)
+#define INT_FORCE_BIT		BIT(6)
+#define INT_CLEAR_BIT		BIT(7)
+
+/* Control bits for REG_RTC_STATUS_INT */
+#define RAW_INT_BIT		BIT(0)
+#define ALM_INT_BIT		BIT(1)
+
+struct msc313_rtc {
+	struct rtc_device *rtc_dev;
+	void __iomem *rtc_base;
+};
+
+static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+
+	seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)
+			| (readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);
+
+	rtc_time64_to_tm(seconds, &alarm->time);
+
+	if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))
+		alarm->enabled = 1;
+
+	return 0;
+}
+
+static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	if (enabled)
+		reg &= ~INT_MASK_BIT;
+	else
+		reg |= INT_MASK_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+	return 0;
+}
+
+static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+
+	seconds = rtc_tm_to_time64(&alarm->time);
+	writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);
+	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);
+
+	msc313_rtc_alarm_irq_enable(dev, alarm->enabled);
+
+	return 0;
+}
+
+static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)
+{
+	return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;
+}
+
+static void msc313_rtc_set_enabled(struct msc313_rtc *priv)
+{
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	reg |= CNT_EN_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+}
+
+static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	u32 seconds;
+	u16 reg;
+
+	if (!msc313_rtc_get_enabled(priv))
+		return -EINVAL;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
+
+	/* Wait for HW latch done */
+	while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)
+		udelay(1);
+
+	seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)
+			| (readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);
+
+	rtc_time64_to_tm(seconds, tm);
+
+	return 0;
+}
+
+static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev);
+	unsigned long seconds;
+	u16 reg;
+
+	seconds = rtc_tm_to_time64(tm);
+	writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);
+	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);
+
+	/* Enable load for loading value into internal RTC counter */
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
+
+	/* Wait for HW latch done */
+	while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
+		udelay(1);
+	msc313_rtc_set_enabled(priv);
+	return 0;
+}
+
+static const struct rtc_class_ops msc313_rtc_ops = {
+	.read_time = msc313_rtc_read_time,
+	.set_time = msc313_rtc_set_time,
+	.read_alarm = msc313_rtc_read_alarm,
+	.set_alarm = msc313_rtc_set_alarm,
+	.alarm_irq_enable = msc313_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)
+{
+	struct msc313_rtc *priv = dev_get_drvdata(dev_id);
+	u16 reg;
+
+	reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);
+	if (!(reg & ALM_INT_BIT))
+		return IRQ_NONE;
+
+	reg = readw(priv->rtc_base + REG_RTC_CTRL);
+	reg |= INT_CLEAR_BIT;
+	reg &= ~INT_FORCE_BIT;
+	writew(reg, priv->rtc_base + REG_RTC_CTRL);
+
+	rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static int msc313_rtc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct msc313_rtc *priv;
+	unsigned long rate;
+	struct clk *clk;
+	int ret;
+	int irq;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->rtc_base))
+		return PTR_ERR(priv->rtc_base);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return -EINVAL;
+
+	priv->rtc_dev = devm_rtc_allocate_device(dev);
+	if (IS_ERR(priv->rtc_dev))
+		return PTR_ERR(priv->rtc_dev);
+
+	priv->rtc_dev->ops = &msc313_rtc_ops;
+	priv->rtc_dev->range_max = U32_MAX;
+
+	ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
+			       dev_name(&pdev->dev), &pdev->dev);
+	if (ret) {
+		dev_err(dev, "Could not request IRQ\n");
+		return ret;
+	}
+
+	clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(clk)) {
+		dev_err(dev, "No input reference clock\n");
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, clk);
+	if (ret)
+		return ret;
+
+	rate = clk_get_rate(clk);
+	writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
+	writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_rtc_register_device(priv->rtc_dev);
+}
+
+static const struct of_device_id msc313_rtc_of_match_table[] = {
+	{ .compatible = "mstar,msc313-rtc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, msc313_rtc_of_match_table);
+
+static struct platform_driver msc313_rtc_driver = {
+	.probe = msc313_rtc_probe,
+	.driver = {
+		.name = "msc313-rtc",
+		.of_match_table = msc313_rtc_of_match_table,
+	},
+};
+
+module_platform_driver(msc313_rtc_driver);
+
+MODULE_AUTHOR("Daniel Palmer <daniel at thingy.jp>");
+MODULE_AUTHOR("Romain Perier <romain.perier at gmail.com>");
+MODULE_DESCRIPTION("MStar RTC Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.30.2



From romain.perier at gmail.com  Mon Aug 23 10:16:11 2021
From: romain.perier at gmail.com (Romain Perier)
Date: Mon, 23 Aug 2021 19:16:11 +0200
Subject: [PATCH v4 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC devicetree
 bindings documentation
In-Reply-To: <20210823171613.18941-1-romain.perier@gmail.com>
References: <20210823171613.18941-1-romain.perier@gmail.com>
Message-ID: <20210823171613.18941-2-romain.perier@gmail.com>

This adds the documentation for the devicetree bindings of the Mstar
MSC313e RTC driver, found from MSC313e SoCs and newer.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 .../bindings/rtc/mstar,msc313-rtc.yaml        | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml

diff --git a/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
new file mode 100644
index 000000000000..114199cf4d28
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/mstar,msc313-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mstar MSC313e RTC Device Tree Bindings
+
+allOf:
+  - $ref: "rtc.yaml#"
+
+maintainers:
+  - Daniel Palmer <daniel at 0x0f.com>
+  - Romain Perier <romain.perier at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - mstar,msc313-rtc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  start-year: true
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    rtc at 2400 {
+        compatible = "mstar,msc313-rtc";
+        reg = <0x2400 0x40>;
+        clocks = <&xtal_div2>;
+        interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+    };
+...
-- 
2.30.2



From broonie at kernel.org  Mon Aug 23 10:37:50 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 23 Aug 2021 18:37:50 +0100
Subject: [PATCH][next] spi: rockchip-sfc: Fix assigned but never used
 return error codes
In-Reply-To: <20210818141051.36320-1-colin.king@canonical.com>
References: <20210818141051.36320-1-colin.king@canonical.com>
Message-ID: <162974017516.3286.9365314960815127788.b4-ty@kernel.org>

On Wed, 18 Aug 2021 15:10:51 +0100, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
> 
> Currently there are two places where the error return variable ret is
> being assigned -ETIMEDOUT on timeout errors and this value is not
> being returned. Fix this by returning -ETIMEDOUT rather than redundantly
> assiging it to ret.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: rockchip-sfc: Fix assigned but never used return error codes
      commit: 745649c59a0d1fde9dcc02286f23f8c78a1f724d

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Mon Aug 23 10:37:51 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 23 Aug 2021 18:37:51 +0100
Subject: [PATCH] spi: rockchip-sfc: Remove redundant IO operations
In-Reply-To: <20210821124925.6066-1-jon.lin@rock-chips.com>
References: <20210821124925.6066-1-jon.lin@rock-chips.com>
Message-ID: <162974017517.3286.666459658265810667.b4-ty@kernel.org>

On Sat, 21 Aug 2021 20:49:25 +0800, Jon Lin wrote:
> Coherent dma buffer is uncached and memcpy is enough.
> 
> 
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: rockchip-sfc: Remove redundant IO operations
      commit: 8d00f9819458b95301e274c6df705df2963ba34f

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From tim.c.chen at linux.intel.com  Mon Aug 23 10:49:33 2021
From: tim.c.chen at linux.intel.com (Tim Chen)
Date: Mon, 23 Aug 2021 10:49:33 -0700
Subject: [PATCH 3/3] scheduler: Add cluster scheduler level for x86
In-Reply-To: <20210820013008.12881-4-21cnbao@gmail.com>
References: <20210820013008.12881-1-21cnbao@gmail.com>
 <20210820013008.12881-4-21cnbao@gmail.com>
Message-ID: <32bcec89-57d5-65e3-970b-affcf4f41667@linux.intel.com>



On 8/19/21 6:30 PM, Barry Song wrote:
> From: Tim Chen <tim.c.chen at linux.intel.com>
> 
> There are x86 CPU architectures (e.g. Jacobsville) where L2 cahce is
> shared among a cluster of cores instead of being exclusive to one
> single core.
> To prevent oversubscription of L2 cache, load should be balanced
> between such L2 clusters, especially for tasks with no shared data.
> On benchmark such as SPECrate mcf test, this change provides a
> boost to performance especially on medium load system on Jacobsville.
> on a Jacobsville that has 24 Atom cores, arranged into 6 clusters
> of 4 cores each, the benchmark number is as follow:
> 
>  Improvement over baseline kernel for mcf_r
>  copies		run time	base rate
>  1		-0.1%		-0.2%
>  6		25.1%		25.1%
>  12		18.8%		19.0%
>  24		0.3%		0.3%
> 
> So this looks pretty good. In terms of the system's task distribution,
> some pretty bad clumping can be seen for the vanilla kernel without
> the L2 cluster domain for the 6 and 12 copies case. With the extra
> domain for cluster, the load does get evened out between the clusters.
> 
> Note this patch isn't an universal win as spreading isn't necessarily
> a win, particually for those workload who can benefit from packing.

I have another patch set to make cluster scheduling selectable at run
time and boot time.  Will like to see people's feed back on this patch
set first before sending that out.

Thanks.

Tim


From lkp at intel.com  Mon Aug 23 10:55:53 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 24 Aug 2021 01:55:53 +0800
Subject: [arm-platforms:hack/m1-pcie-v2 6/21]
 drivers/clk/clk-apple-gate.c:113:16: warning: no previous prototype for
 function 'apple_clk_hw_onecell_get'
Message-ID: <202108240150.I6uHQ62D-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git hack/m1-pcie-v2
head:   2c9981b6a289354c22989e70cef0e51b9e632091
commit: 9404863043f90db4d8e377ac211584660c6acbec [6/21] clk: add support for gate clocks on Apple SoCs
config: arm64-randconfig-r016-20210822 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 79b55e5038324e61a3abf4e6a9a949c473edd858)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=9404863043f90db4d8e377ac211584660c6acbec
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms hack/m1-pcie-v2
        git checkout 9404863043f90db4d8e377ac211584660c6acbec
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/clk/clk-apple-gate.c:113:16: warning: no previous prototype for function 'apple_clk_hw_onecell_get' [-Wmissing-prototypes]
   struct clk_hw *apple_clk_hw_onecell_get(struct of_phandle_args *clkspec,
                  ^
   drivers/clk/clk-apple-gate.c:113:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   struct clk_hw *apple_clk_hw_onecell_get(struct of_phandle_args *clkspec,
   ^
   static 
   1 warning generated.


vim +/apple_clk_hw_onecell_get +113 drivers/clk/clk-apple-gate.c

   112	
 > 113	struct clk_hw *apple_clk_hw_onecell_get(struct of_phandle_args *clkspec,
   114						void *data)
   115	{
   116		struct clk_hw *hw = NULL;
   117		struct clk_hw_onecell_data *hw_data = data;
   118		unsigned int idx = clkspec->args[0];
   119	
   120		if (idx % 8) {
   121			pr_err("%s: unaligned index: %u\n", __func__, idx);
   122			return ERR_PTR(-EINVAL);
   123		}
   124	
   125		idx /= 8;
   126		if (idx >= hw_data->num) {
   127			pr_err("%s: index out of bounds: %u\n", __func__, idx);
   128			return ERR_PTR(-EINVAL);
   129		}
   130	
   131		hw = hw_data->hws[idx];
   132		if (!hw)
   133			return ERR_PTR(-EINVAL);
   134		return hw;
   135	}
   136	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 44264 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210824/6fdd55ba/attachment-0001.gz>

From robh at kernel.org  Mon Aug 23 11:09:29 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 23 Aug 2021 13:09:29 -0500
Subject: [PATCH V3 2/3] dt-bindings: gpio: zynqmp: Add binding
 documentation for modepin
In-Reply-To: <20210818081018.2620544-3-piyush.mehta@xilinx.com>
References: <20210818081018.2620544-1-piyush.mehta@xilinx.com>
 <20210818081018.2620544-3-piyush.mehta@xilinx.com>
Message-ID: <YSPkWUs0Y2zDiHQU@robh.at.kernel.org>

On Wed, 18 Aug 2021 13:40:17 +0530, Piyush Mehta wrote:
> This patch adds DT binding document for zynqmp modepin GPIO controller.
> Modepin GPIO controller has four GPIO pins which can be configurable
> as input or output.
> 
> Modepin driver is a bridge between the peripheral driver and GPIO pins.
> It has set and get APIs for accessing GPIO pins, based on the device-tree
> entry of reset-gpio property in the peripheral driver, every pin can be
> configured as input/output and trigger GPIO pin.
> 
> For more information please refer zynqMp TRM link:
> Link: https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
> Chapter 2: Signals, Interfaces, and Pins
> Table 2-2: Clock, Reset, and Configuration Pins - PS_MODE
> 
> Signed-off-by: Piyush Mehta <piyush.mehta at xilinx.com>
> Acked-by: Michal Simek <michal.simek at xilinx.com>
> ---
> Changes in v2:
> - Addressed review comments: Update commit message
> 
> Review Comments:
> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#mbd1fbda813e33b19397b350bde75747c92a0d7e1
> https://lore.kernel.org/linux-arm-kernel/20210615080553.2021061-2-piyush.mehta at xilinx.com/T/#me82b1444ab3776162cdb0077dfc9256365c7e736
> 
> Changes in v3:
> - Addressed Rob and Michal review comments:
>   - Update DT example.
> 
> Review Comments:
> https://lore.kernel.org/linux-arm-kernel/YRbBnRS0VosXcZWz at robh.at.kernel.org/
> https://lore.kernel.org/linux-arm-kernel/d71ad7f9-6972-8cc0-6dfb-b5306c9900d0 at xilinx.com/
> ---
>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 41 ++++++++++++++++++++++
>  .../bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml    | 43 ++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/xlnx,zynqmp-gpio-modepin.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From rananta at google.com  Mon Aug 23 11:13:06 2021
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Mon, 23 Aug 2021 11:13:06 -0700
Subject: [PATCH] KVM: arm64: Ratelimit error log during guest debug
 exception
In-Reply-To: <875yvzqd5d.wl-maz@kernel.org>
References: <20210819223406.1132426-1-rananta@google.com>
 <87sfz4qx9r.wl-maz@kernel.org>
 <CAJHc60wn7PP1zQ5EKOGQDFbZsf=d9codWTuWbtMT5AHegfbVHw@mail.gmail.com>
 <875yvzqd5d.wl-maz@kernel.org>
Message-ID: <CAJHc60wLPFZ5XFwWVyex5GXr=qm7QWc2yOmkECxLh=L2QnvgWg@mail.gmail.com>

On Sat, Aug 21, 2021 at 3:56 AM Marc Zyngier <maz at kernel.org> wrote:
>
> On Sat, 21 Aug 2021 00:01:24 +0100,
> Raghavendra Rao Ananta <rananta at google.com> wrote:
> >
> > [1  <text/plain; UTF-8 (7bit)>]
> > On Fri, Aug 20, 2021 at 2:29 AM Marc Zyngier <maz at kernel.org> wrote:
> > >
> > > On Thu, 19 Aug 2021 23:34:06 +0100,
> > > Raghavendra Rao Ananta <rananta at google.com> wrote:
> > > >
> > > > Potentially, the guests could trigger a debug exception that's
> > > > outside the exception class range.
> > >
> > > How? All the exception classes that lead to this functions are already
> > > handled in the switch/case statement.
> > >
> > I guess I didn't think this through. Landing into kvm_handle_guest_debug()
> > itself is not possible :)
>
> Exactly.
>
> > > My take on this is that this code isn't reachable, and that it could
> > > be better rewritten as:
> > >
> > > diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> > > index 6f48336b1d86..ae7ec086827b 100644
> > > --- a/arch/arm64/kvm/handle_exit.c
> > > +++ b/arch/arm64/kvm/handle_exit.c
> > > @@ -119,28 +119,14 @@ static int kvm_handle_guest_debug(struct kvm_vcpu
> > *vcpu)
> > >  {
> > >         struct kvm_run *run = vcpu->run;
> > >         u32 esr = kvm_vcpu_get_esr(vcpu);
> > > -       int ret = 0;
> > >
> > >         run->exit_reason = KVM_EXIT_DEBUG;
> > >         run->debug.arch.hsr = esr;
> > >
> > > -       switch (ESR_ELx_EC(esr)) {
> > > -       case ESR_ELx_EC_WATCHPT_LOW:
> > > +       if (ESR_ELx_EC(esr) ==  ESR_ELx_EC_WATCHPT_LOW)
> > >                 run->debug.arch.far = vcpu->arch.fault.far_el2;
> > > -               fallthrough;
> > > -       case ESR_ELx_EC_SOFTSTP_LOW:
> > > -       case ESR_ELx_EC_BREAKPT_LOW:
> > > -       case ESR_ELx_EC_BKPT32:
> > > -       case ESR_ELx_EC_BRK64:
> > > -               break;
> > > -       default:
> > > -               kvm_err("%s: un-handled case esr: %#08x\n",
> > > -                       __func__, (unsigned int) esr);
> > > -               ret = -1;
> > > -               break;
> > > -       }
> > >
> > > -       return ret;
> > > +       return 0;
> > >  }
> > >
> > This looks better, but do you think we would be compromising on readability?
>
> I don't think so. The exit handler table is, on its own, pretty
> explicit about what we route to this handler, and the comment above
> the function clearly states that we exit to userspace for all the
> debug ECs.

Sounds great. I'm happy to send out a patch with you as 'Suggested-by' , if you
are okay with it.

Regards,
Raghavendra
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


From robh at kernel.org  Mon Aug 23 11:24:33 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 23 Aug 2021 13:24:33 -0500
Subject: [PATCH] dt-bindings: clock: brcm,iproc-clocks: fix armpll
 properties
In-Reply-To: <20210819052918.6753-1-zajec5@gmail.com>
References: <20210819052918.6753-1-zajec5@gmail.com>
Message-ID: <YSPn4Y+Rgs83lg/g@robh.at.kernel.org>

On Thu, 19 Aug 2021 07:29:18 +0200, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> armpll clocks (available on Cygnus and Northstar Plus) are simple clocks
> with no cells. Adjust binding props #clock-cells and clock-output-names
> to handle them.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  .../bindings/clock/brcm,iproc-clocks.yaml     | 27 +++++++++++++++++--
>  1 file changed, 25 insertions(+), 2 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Mon Aug 23 11:34:08 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 23 Aug 2021 13:34:08 -0500
Subject: [PATCH v1 1/3] dt-bindings: PCI: imx6: convert the imx pcie
 controller to dtschema
In-Reply-To: <20210819071408.3856475-2-hongxing.zhu@nxp.com>
References: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
 <20210819071408.3856475-2-hongxing.zhu@nxp.com>
Message-ID: <YSPqIEmngxjCCn+v@robh.at.kernel.org>

On Thu, Aug 19, 2021 at 03:14:06PM +0800, Richard Zhu wrote:
> Convert the fsl,imx6q-pcie.txt into a schema.
> - the ranges should be aligned to $ref: /schemas/pci/pci-bus.yaml#
> - only one propert is allowed in the compatible string, remove
>   "snps,dw-pcie".

Didn't I already see a v1?

> 
> Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
> ---
>  .../bindings/pci/fsl,imx6q-pcie.txt           | 100 ---------
>  .../bindings/pci/fsl,imx6q-pcie.yaml          | 207 ++++++++++++++++++
>  MAINTAINERS                                   |   2 +-
>  3 files changed, 208 insertions(+), 101 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
>  create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
> deleted file mode 100644
> index d8971ab99274..000000000000
> --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
> +++ /dev/null
> @@ -1,100 +0,0 @@
> -* Freescale i.MX6 PCIe interface
> -
> -This PCIe host controller is based on the Synopsys DesignWare PCIe IP
> -and thus inherits all the common properties defined in designware-pcie.txt.
> -
> -Required properties:
> -- compatible:
> -	- "fsl,imx6q-pcie"
> -	- "fsl,imx6sx-pcie",
> -	- "fsl,imx6qp-pcie"
> -	- "fsl,imx7d-pcie"
> -	- "fsl,imx8mq-pcie"
> -- reg: base address and length of the PCIe controller
> -- interrupts: A list of interrupt outputs of the controller. Must contain an
> -  entry for each entry in the interrupt-names property.
> -- interrupt-names: Must include the following entries:
> -	- "msi": The interrupt that is asserted when an MSI is received
> -- clock-names: Must include the following additional entries:
> -	- "pcie_phy"
> -
> -Optional properties:
> -- fsl,tx-deemph-gen1: Gen1 De-emphasis value. Default: 0
> -- fsl,tx-deemph-gen2-3p5db: Gen2 (3.5db) De-emphasis value. Default: 0
> -- fsl,tx-deemph-gen2-6db: Gen2 (6db) De-emphasis value. Default: 20
> -- fsl,tx-swing-full: Gen2 TX SWING FULL value. Default: 127
> -- fsl,tx-swing-low: TX launch amplitude swing_low value. Default: 127
> -- fsl,max-link-speed: Specify PCI gen for link capability. Must be '2' for
> -  gen2, otherwise will default to gen1. Note that the IMX6 LVDS clock outputs
> -  do not meet gen2 jitter requirements and thus for gen2 capability a gen2
> -  compliant clock generator should be used and configured.
> -- reset-gpio: Should specify the GPIO for controlling the PCI bus device reset
> -  signal. It's not polarity aware and defaults to active-low reset sequence
> -  (L=reset state, H=operation state).
> -- reset-gpio-active-high: If present then the reset sequence using the GPIO
> -  specified in the "reset-gpio" property is reversed (H=reset state,
> -  L=operation state).
> -- vpcie-supply: Should specify the regulator in charge of PCIe port power.
> -  The regulator will be enabled when initializing the PCIe host and
> -  disabled either as part of the init process or when shutting down the
> -  host.
> -- vph-supply: Should specify the regulator in charge of VPH one of the three
> -  PCIe PHY powers. This regulator can be supplied by both 1.8v and 3.3v voltage
> -  supplies.
> -
> -Additional required properties for imx6sx-pcie:
> -- clock names: Must include the following additional entries:
> -	- "pcie_inbound_axi"
> -- power-domains: Must be set to phandles pointing to the DISPLAY and
> -  PCIE_PHY power domains
> -- power-domain-names: Must be "pcie", "pcie_phy"
> -
> -Additional required properties for imx7d-pcie and imx8mq-pcie:
> -- power-domains: Must be set to a phandle pointing to PCIE_PHY power domain
> -- resets: Must contain phandles to PCIe-related reset lines exposed by SRC
> -  IP block
> -- reset-names: Must contain the following entries:
> -	       - "pciephy"
> -	       - "apps"
> -	       - "turnoff"
> -- fsl,imx7d-pcie-phy: A phandle to an fsl,imx7d-pcie-phy node.
> -
> -Additional required properties for imx8mq-pcie:
> -- clock-names: Must include the following additional entries:
> -	- "pcie_aux"
> -
> -Example:
> -
> -	pcie at 01000000 {
> -		compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
> -		reg = <0x01ffc000 0x04000>,
> -		      <0x01f00000 0x80000>;
> -		reg-names = "dbi", "config";
> -		#address-cells = <3>;
> -		#size-cells = <2>;
> -		device_type = "pci";
> -		ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000
> -			  0x81000000 0 0          0x01f80000 0 0x00010000
> -			  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
> -		num-lanes = <1>;
> -		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> -		interrupt-names = "msi";
> -		#interrupt-cells = <1>;
> -		interrupt-map-mask = <0 0 0 0x7>;
> -		interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
> -		                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
> -		                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
> -		                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> -		clocks = <&clks 144>, <&clks 206>, <&clks 189>;
> -		clock-names = "pcie", "pcie_bus", "pcie_phy";
> -	};
> -
> -* Freescale i.MX7d PCIe PHY
> -
> -This is the PHY associated with the IMX7d PCIe controller.  It's used by the
> -PCI-e controller via the fsl,imx7d-pcie-phy phandle.
> -
> -Required properties:
> -- compatible:
> -	- "fsl,imx7d-pcie-phy"
> -- reg: base address and length of the PCIe PHY controller
> diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> new file mode 100644
> index 000000000000..3503ce3de05d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> @@ -0,0 +1,207 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/fsl,imx6q-pcie.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Freescale i.MX6 PCIe host controller
> +
> +maintainers:
> +  - Lucas Stach <l.stach at pengutronix.de>
> +  - Richard Zhu <hongxing.zhu at nxp.com>
> +
> +description: |+
> +  This PCIe host controller is based on the Synopsys DesignWare PCIe IP
> +  and thus inherits all the common properties defined in snps,dw-pcie.yaml.

Don't need a freeform text reference, but...
> +
> +allOf:
> +  - $ref: /schemas/pci/pci-bus.yaml#

...this needs to reference the snps,dw-pcie.yaml DWC schema.

> +
> +properties:
> +  compatible:
> +    enum:
> +      - fsl,imx6q-pcie
> +      - fsl,imx6sx-pcie
> +      - fsl,imx6qp-pcie
> +      - fsl,imx7d-pcie
> +      - fsl,imx8mq-pcie
> +
> +  reg:
> +    items:
> +      - description: Data Bus Interface (DBI) registers.
> +      - description: PCIe configuration space region.
> +
> +  reg-names:
> +    items:
> +      - const: dbi
> +      - const: config
> +
> +  interrupts:
> +    minItems: 1

Don't need 'minItems: 1' when there's only 1 possible item:

> +    items:
> +      - description: builtin MSI controller.
> +
> +  interrupt-names:
> +    minItems: 1
> +    items:
> +      - const: msi
> +
> +  clocks:
> +    minItems: 3
> +    maxItems: 4

Don't need maxItems here.

> +    items:
> +      - description: PCIe bridge clock.
> +      - description: PCIe bus clock.
> +      - description: PCIe PHY clock.
> +      - description: Additional required clock entry for imx6sx-pcie,
> +          imx8mq-pcie.
> +
> +  clock-names:
> +    minItems: 3
> +    maxItems: 4

And here.

> +    items:
> +      - const: pcie
> +      - const: pcie_bus
> +      - const: pcie_phy
> +      - const: pcie_inbound_axi for imx6sx-pcie, pcie_aux for imx8mq-pcie
> +
> +  num-lanes:
> +    const: 1
> +
> +  num-viewport:
> +    const: 4

This is deprecated. The driver detects this now.

> +
> +  fsl,imx7d-pcie-phy:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: A phandle to an fsl,imx7d-pcie-phy node. Additional
> +      required properties for imx7d-pcie and imx8mq-pcie.
> +
> +  power-domains:
> +    maxItems: 2
> +    description: The first phandle pointing to the DISPLAY domain for
> +      imx6sx-pcie, to PCIE_PHY power domain for imx7d-pcie and imx8mq-pcie.
> +      The second phandle pointing to the PCIE_PHY power domains for imx6sx-pcie.

Split the description:

items:
  - description: ...
  - description: ...

> +
> +  power-domain-names:
> +    maxItems: 2

You have to define the names.

> +
> +  resets:
> +    maxItems: 3
> +    description: Phandles to PCIe-related reset lines exposed by SRC
> +      IP block. Additional required by imx7d-pcie and imx8mq-pcie.
> +
> +  reset-names:
> +    items:
> +      - const: pciephy
> +      - const: apps
> +      - const: turnoff
> +
> +  fsl,tx-deemph-gen1:
> +    description: Gen1 De-emphasis value (optional required).

optional or required? 

> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 0
> +
> +  fsl,tx-deemph-gen2-3p5db:
> +    description: Gen2 (3.5db) De-emphasis value (optional required).
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 0
> +
> +  fsl,tx-deemph-gen2-6db:
> +    description: Gen2 (6db) De-emphasis value (optional required).
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 20
> +
> +  fsl,tx-swing-full:
> +    description: Gen2 TX SWING FULL value (optional required).
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 127
> +
> +  fsl,tx-swing-low:
> +    description: TX launch amplitude swing_low value (optional required).
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 127
> +
> +  fsl,max-link-speed:
> +    description: Specify PCI Gen for link capability (optional required).
> +      Note that the IMX6 LVDS clock outputs do not meet gen2 jitter
> +      requirements and thus for gen2 capability a gen2 compliant clock
> +      generator should be used and configured.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [1, 2, 3, 4]
> +    default: 1
> +
> +  reset-gpio:

Deprecated.

> +    description: Should specify the GPIO for controlling the PCI bus device
> +      reset signal. It's not polarity aware and defaults to active-low reset
> +      sequence (L=reset state, H=operation state) (optional required).
> +
> +  reset-gpio-active-high:

Deprecated. This should only be used on older compatibles I hope...

> +    description: If present then the reset sequence using the GPIO
> +      specified in the "reset-gpio" property is reversed (H=reset state,
> +      L=operation state) (optional required).
> +
> +  vpcie-supply:
> +    description: Should specify the regulator in charge of PCIe port power.
> +      The regulator will be enabled when initializing the PCIe host and
> +      disabled either as part of the init process or when shutting down
> +      the host (optional required).
> +
> +  vph-supply:
> +    description: Should specify the regulator in charge of VPH one of
> +      the three PCIe PHY powers. This regulator can be supplied by both
> +      1.8v and 3.3v voltage supplies (optional required).
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - "#address-cells"
> +  - "#size-cells"
> +  - device_type
> +  - bus-range
> +  - ranges
> +  - num-lanes
> +  - num-viewport
> +  - interrupts
> +  - interrupt-names
> +  - "#interrupt-cells"
> +  - interrupt-map-mask
> +  - interrupt-map
> +  - clocks
> +  - clock-names
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imx6qdl-clock.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    pcie: pcie at 1ffc000 {
> +        compatible = "fsl,imx6q-pcie";
> +        reg = <0x01ffc000 0x04000>,
> +              <0x01f00000 0x80000>;
> +        reg-names = "dbi", "config";
> +        #address-cells = <3>;
> +        #size-cells = <2>;
> +        device_type = "pci";
> +        bus-range = <0x00 0xff>;
> +        ranges = <0x81000000 0 0          0x01f80000 0 0x00010000>,
> +                 <0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
> +        num-lanes = <1>;
> +        num-viewport = <4>;
> +        interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-names = "msi";
> +        #interrupt-cells = <1>;
> +        interrupt-map-mask = <0 0 0 0x7>;
> +        interrupt-map = <0 0 0 1 &gpc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
> +                        <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
> +                        <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
> +                        <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> +        clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
> +                <&clks IMX6QDL_CLK_LVDS1_GATE>,
> +                <&clks IMX6QDL_CLK_PCIE_REF_125M>;
> +        clock-names = "pcie", "pcie_bus", "pcie_phy";
> +        status = "disabled";

Why are you disabling your example? 

> +    };
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f73fef615702..a1e2cc0be9e8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14187,7 +14187,7 @@ M:	Lucas Stach <l.stach at pengutronix.de>
>  L:	linux-pci at vger.kernel.org
>  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  S:	Maintained
> -F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
> +F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
>  F:	drivers/pci/controller/dwc/*imx6*
>  
>  PCI DRIVER FOR FU740
> -- 
> 2.25.1
> 
> 


From heiko at sntech.de  Mon Aug 23 11:42:14 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 23 Aug 2021 20:42:14 +0200
Subject: [PATCH] arm64: dts: rockchip: Re-add interrupt-names for RK3399's
 vpu
In-Reply-To: <20210822115755.3171937-1-knaerzche@gmail.com>
References: <20210822115755.3171937-1-knaerzche@gmail.com>
Message-ID: <162974163915.2977894.410070798189660023.b4-ty@sntech.de>

On Sun, 22 Aug 2021 13:57:55 +0200, Alex Bee wrote:
> Commit a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes")
> intended to remove the interrupt-names property for mmu nodes, but it
> also removed it for the vpu node in rk3399.dtsi. That makes the driver
> fail probing currently.
> Fix this by re-adding the property for this node.

Applied, thanks!

[1/1] arm64: dts: rockchip: Re-add interrupt-names for RK3399's vpu
      commit: 6b9b7968ff78d5b9a079da2f8decba873af54192

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Mon Aug 23 11:42:13 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 23 Aug 2021 20:42:13 +0200
Subject: [PATCH] arm64: dts: rockchip: Fix GPU register width for RK3328
In-Reply-To: <20210623115926.164861-1-knaerzche@gmail.com>
References: <20210623115926.164861-1-knaerzche@gmail.com>
Message-ID: <162974163915.2977894.9290643400538669916.b4-ty@sntech.de>

On Wed, 23 Jun 2021 13:59:26 +0200, Alex Bee wrote:
> As can be seen in RK3328's TRM the register range for the GPU is
> 0xff300000 to 0xff330000.
> It would (and does in vendor kernel) overlap with the registers of
> the HEVC encoder (node/driver do not exist yet in upstream kernel).
> See already existing h265e_mmu node.

Applied, thanks!

[1/1] arm64: dts: rockchip: Fix GPU register width for RK3328
      commit: 3f1c9b99f22c4784bd6f439a63bbf8a61c0335b1

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Mon Aug 23 11:42:15 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 23 Aug 2021 20:42:15 +0200
Subject: [PATCH 0/1] arm64: dts: rockchip: add missing rockchip,
 grf property to rk356x
In-Reply-To: <20210823123911.12095-1-michael.riesch@wolfvision.net>
References: <20210823123911.12095-1-michael.riesch@wolfvision.net>
Message-ID: <162974163915.2977894.4550089121639046770.b4-ty@sntech.de>

On Mon, 23 Aug 2021 14:39:10 +0200, Michael Riesch wrote:
> The following error messages appear on my RK3568 EVB1 board during boot:
> 
>   rockchip_clk_register_muxgrf: regmap not available
>   rockchip_clk_register_branches: failed to register clock clk_ddr1x: -524
> 
> These can be fixed by providing the missing rockchip,grf property to the
> device tree (similar to other Rockchip SoCs, such as the RK3399).
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: add missing rockchip,grf property to rk356x
      commit: 7e0a31c49b5a1dc16540581d2a9cbe35da97c06c

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Mon Aug 23 11:42:16 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 23 Aug 2021 20:42:16 +0200
Subject: [PATCH] arm64: dts: rockchip: add saradc to rk3568-evb1-v10
In-Reply-To: <20210823110716.10038-1-michael.riesch@wolfvision.net>
References: <20210823110716.10038-1-michael.riesch@wolfvision.net>
Message-ID: <162974163916.2977894.3931424916722931571.b4-ty@sntech.de>

On Mon, 23 Aug 2021 13:07:16 +0200, Michael Riesch wrote:
> Add the SARADC to the device tree of the RK3568 EVB1.

Applied, thanks!

[1/1] arm64: dts: rockchip: add saradc to rk3568-evb1-v10
      commit: b12a5946f5ea7a54b8b983c42f0812152e3122de

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Mon Aug 23 11:45:00 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 23 Aug 2021 20:45:00 +0200
Subject: [GIT PULL] Rockchip dts64 changes for 5.15 - #2
Message-ID: <6569432.ejJDZkT8p0@phil>

Hi Arnd, Kevin, Olof,

another late (and now final addition) hopefully for 5.15.
This includes some dts fixes for changes from previous pull request.

So if it's still suitable, please pull.

Thanks
Heiko


The following changes since commit 9a35fd01f4abc3974e12539448038307acf27f16:

  arm64: dts: rockchip: add RK3399 Gru gpio-line-names (2021-08-21 18:18:50 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v5.15-rockchip-dts64-2

for you to fetch changes up to b12a5946f5ea7a54b8b983c42f0812152e3122de:

  arm64: dts: rockchip: add saradc to rk3568-evb1-v10 (2021-08-23 19:56:32 +0200)

----------------------------------------------------------------
Some fixes and the tiny addition of the saradc to the rk3568-evb

----------------------------------------------------------------
Alex Bee (2):
      arm64: dts: rockchip: Re-add interrupt-names for RK3399's vpu
      arm64: dts: rockchip: Fix GPU register width for RK3328

Michael Riesch (2):
      arm64: dts: rockchip: add missing rockchip,grf property to rk356x
      arm64: dts: rockchip: add saradc to rk3568-evb1-v10

 arch/arm64/boot/dts/rockchip/rk3328.dtsi         | 2 +-
 arch/arm64/boot/dts/rockchip/rk3399.dtsi         | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts | 5 +++++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi         | 1 +
 4 files changed, 8 insertions(+), 1 deletion(-)





From geert at linux-m68k.org  Mon Aug 23 13:11:27 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 23 Aug 2021 22:11:27 +0200
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CAK9rFnw-j8whcsK-NQ4w4+sCdrumCk7Bb=J+KfsF9ZO2Tf5r5g@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CAHp75VcG9KajNpDbewDq7QzotB6t7MfwiGk15FaobX+cmMVSzg@mail.gmail.com>
 <CAK9rFnwrA=W2Vk5yFwG4N_WS=eBXXnhtexA+tqgAYb6xOAO4oQ@mail.gmail.com>
 <CAHp75VdfrJ3JV_gL3xCLHOiw6Tj-5Ep7z5JKWUFKFbUt8gobcw@mail.gmail.com>
 <CAK9rFnx--z_pr_yR6CqGsH04ddwUtx4rxc7MxNNmy7ZSF86+Mg@mail.gmail.com>
 <CAMuHMdUz4vUQzXBHA9AiT3w6L20yBpgd0emVZJb=v_qw70qiJQ@mail.gmail.com>
 <CAK9rFnw-j8whcsK-NQ4w4+sCdrumCk7Bb=J+KfsF9ZO2Tf5r5g@mail.gmail.com>
Message-ID: <CAMuHMdW0s=x+DBZffeuEcyifDRfy8YM3c_wEAZscO7twR2wj3Q@mail.gmail.com>

Hi Brad,

On Mon, Aug 23, 2021 at 6:31 PM Brad Larson <brad at pensando.io> wrote:
> On Mon, Aug 23, 2021 at 12:50 AM Geert Uytterhoeven
> <geert at linux-m68k.org> wrote:
> > On Mon, Aug 23, 2021 at 3:14 AM Brad Larson <brad at pensando.io> wrote:
> > > On Mon, Mar 29, 2021 at 3:40 AM Andy Shevchenko
> [...]
> > > Regarding the above module question and Kconfig definition, since I
> > > first looked at this and reviewed the comments I realized I should be
> > > using builtin.  The file gpio/Kconfig is currently this
> > >
> > > config GPIO_ELBA_SPICS
> > >         def_bool y
> > >         depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST
> >
> > That means the driver will default to yes by merely enabling
> > COMPILE_TEST, which is a no-go.
> >
> >     config GPIO_ELBA_SPICS
> >             bool "one-line summary"
> >             depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST
> >             default y if ARCH_PENSANDO_ELBA_SOC
>
> Thanks Geert, changed to this
>
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -241,8 +241,9 @@ config GPIO_EIC_SPRD
>           Say yes here to support Spreadtrum EIC device.
>
>  config GPIO_ELBA_SPICS
> +       bool "Pensando Elba SoC SPI Chip Select as GPIO support"
> +       depends on ARCH_PENSANDO_ELBA_SOC
>         def_bool y
> -       depends on ARCH_PENSANDO_ELBA_SOC || COMPILE_TEST

So we're losing the COMPILE_TEST ability again?

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From swboyd at chromium.org  Mon Aug 23 13:12:02 2021
From: swboyd at chromium.org (Stephen Boyd)
Date: Mon, 23 Aug 2021 15:12:02 -0500
Subject: [PATCH v3 10/10] arm64: dts: qcom: sc7280: Update Q6V5 MSS node
In-Reply-To: <1629344185-27368-11-git-send-email-sibis@codeaurora.org>
References: <1629344185-27368-1-git-send-email-sibis@codeaurora.org>
 <1629344185-27368-11-git-send-email-sibis@codeaurora.org>
Message-ID: <CAE-0n50_nRZc+YCYwFdBe+4oMpxovQgiF9e_ciDwAJussUAwmw@mail.gmail.com>

Quoting Sibi Sankar (2021-08-18 20:36:25)
> Update MSS node to support MSA based modem boot on SC7280 SoCs.
>
> Signed-off-by: Sibi Sankar <sibis at codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <swboyd at chromium.org>

>
> v3:
>  * Place remoteproc_mpss node in alphabetical order above pinctrl
>    section. [Stephen]
>
>  arch/arm64/boot/dts/qcom/sc7280-idp.dtsi |  7 +++++++
>  arch/arm64/boot/dts/qcom/sc7280.dtsi     | 19 ++++++++++++++++---
>  2 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
> index 103d89c1e1c7..f1c8641b0c26 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
> @@ -263,6 +263,13 @@
>         status = "okay";
>  };
>
> +&remoteproc_mpss {
> +       status = "okay";
> +       compatible = "qcom,sc7280-mss-pil";
> +       iommus = <&apps_smmu 0x124 0x0>, <&apps_smmu 0x488 0x7>;
> +       memory-region = <&mba_mem &mpss_mem>;

Nitpick:

	memory-region = <&mba_mem>, <&mpss_mem>;

would be better as it indicates that &mpss_mem isn't being parsed when
&mba_mem is being parsed, i.e. they're independent phandles.

> +};
> +
>  &sdhc_1 {
>         status = "okay";
>


From swboyd at chromium.org  Mon Aug 23 13:12:29 2021
From: swboyd at chromium.org (Stephen Boyd)
Date: Mon, 23 Aug 2021 15:12:29 -0500
Subject: [PATCH v3 08/10] arm64: dts: qcom: sc7280: Add nodes to boot modem
In-Reply-To: <1629344185-27368-9-git-send-email-sibis@codeaurora.org>
References: <1629344185-27368-1-git-send-email-sibis@codeaurora.org>
 <1629344185-27368-9-git-send-email-sibis@codeaurora.org>
Message-ID: <CAE-0n50g=tKv7dmRKPZsOsT8ezTOXK2MmCxPo4hT5vek8KYc2w@mail.gmail.com>

Quoting Sibi Sankar (2021-08-18 20:36:23)
> Add miscellaneous nodes to boot the modem and support post-mortem debug
> on SC7280 SoCs.
>
> Signed-off-by: Sibi Sankar <sibis at codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <swboyd at chromium.org>


From swboyd at chromium.org  Mon Aug 23 13:14:15 2021
From: swboyd at chromium.org (Stephen Boyd)
Date: Mon, 23 Aug 2021 15:14:15 -0500
Subject: [PATCH v3 03/10] dt-bindings: remoteproc: qcom: Update Q6V5 Modem
 PIL binding
In-Reply-To: <1629344185-27368-4-git-send-email-sibis@codeaurora.org>
References: <1629344185-27368-1-git-send-email-sibis@codeaurora.org>
 <1629344185-27368-4-git-send-email-sibis@codeaurora.org>
Message-ID: <CAE-0n51ZtuPeK+77YUygOBOj4YAQjq=0CX7bH5udu+8HQw55gA@mail.gmail.com>

Quoting Sibi Sankar (2021-08-18 20:36:18)
> Add a new modem compatible string for QTI SC7280 SoCs and introduce the
> "qcom,ext-regs" and "qcom,qaccept-regs" properties needed by the modem
> sub-system running on SC7280 SoCs.
>
> Signed-off-by: Sibi Sankar <sibis at codeaurora.org>
> Acked-by: Rob Herring <robh at kernel.org>
> ---

Reviewed-by: Stephen Boyd <swboyd at chromium.org>


From swboyd at chromium.org  Mon Aug 23 13:14:30 2021
From: swboyd at chromium.org (Stephen Boyd)
Date: Mon, 23 Aug 2021 15:14:30 -0500
Subject: [PATCH v3 02/10] remoteproc: qcom: pas: Add SC7280 Modem support
In-Reply-To: <1629344185-27368-3-git-send-email-sibis@codeaurora.org>
References: <1629344185-27368-1-git-send-email-sibis@codeaurora.org>
 <1629344185-27368-3-git-send-email-sibis@codeaurora.org>
Message-ID: <CAE-0n52PEJnsW1bGNZcRuRJVaAPK2CHn9jepjNvRy6=BearZNg@mail.gmail.com>

Quoting Sibi Sankar (2021-08-18 20:36:17)
> Add support for booting the Modem DSP found on QTI SC7280 SoCs.
>
> Signed-off-by: Sibi Sankar <sibis at codeaurora.org>
> Reviewed-by: Matthias Kaehlcke <mka at chromium.org>
> ---

Reviewed-by: Stephen Boyd <swboyd at chromium.org>


From swboyd at chromium.org  Mon Aug 23 13:14:50 2021
From: swboyd at chromium.org (Stephen Boyd)
Date: Mon, 23 Aug 2021 15:14:50 -0500
Subject: [PATCH v3 01/10] dt-bindings: remoteproc: qcom: pas: Add SC7280
 MPSS support
In-Reply-To: <1629344185-27368-2-git-send-email-sibis@codeaurora.org>
References: <1629344185-27368-1-git-send-email-sibis@codeaurora.org>
 <1629344185-27368-2-git-send-email-sibis@codeaurora.org>
Message-ID: <CAE-0n52t6QkvgzxbmV_sy6b-Bmou7Rsx8WyxN8LKOpJKP7S4KQ@mail.gmail.com>

Quoting Sibi Sankar (2021-08-18 20:36:16)
> Add MPSS PAS support for SC7280 SoCs.
>
> Signed-off-by: Sibi Sankar <sibis at codeaurora.org>
> Reviewed-by: Matthias Kaehlcke <mka at chromium.org>
> Acked-by: Rob Herring <robh at kernel.org>
> ---

Reviewed-by: Stephen Boyd <swboyd at chromium.org>


From oupton at google.com  Mon Aug 23 13:56:30 2021
From: oupton at google.com (Oliver Upton)
Date: Mon, 23 Aug 2021 13:56:30 -0700
Subject: [PATCH v7 6/6] KVM: x86: Expose TSC offset controls to userspace
In-Reply-To: <20210816001130.3059564-7-oupton@google.com>
References: <20210816001130.3059564-1-oupton@google.com>
 <20210816001130.3059564-7-oupton@google.com>
Message-ID: <CAOQ_Qsj_MfRNRRSK1UswsfBw4c9ugSW6tKXNua=3O78sHEonvA@mail.gmail.com>

Paolo,

On Sun, Aug 15, 2021 at 5:11 PM Oliver Upton <oupton at google.com> wrote:
>
> To date, VMM-directed TSC synchronization and migration has been a bit
> messy. KVM has some baked-in heuristics around TSC writes to infer if
> the VMM is attempting to synchronize. This is problematic, as it depends
> on host userspace writing to the guest's TSC within 1 second of the last
> write.
>
> A much cleaner approach to configuring the guest's views of the TSC is to
> simply migrate the TSC offset for every vCPU. Offsets are idempotent,
> and thus not subject to change depending on when the VMM actually
> reads/writes values from/to KVM. The VMM can then read the TSC once with
> KVM_GET_CLOCK to capture a (realtime, host_tsc) pair at the instant when
> the guest is paused.
>
> Cc: David Matlack <dmatlack at google.com>
> Cc: Sean Christopherson <seanjc at google.com>
> Signed-off-by: Oliver Upton <oupton at google.com>

Could you please squash the following into this patch? We need to
advertise KVM_CAP_VCPU_ATTRIBUTES to userspace. Otherwise, happy to
resend.

Thanks,
Oliver

 arch/x86/kvm/x86.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b946430faaae..b5be1ca07704 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4070,6 +4070,7 @@ int kvm_vm_ioctl_check_extension(struct kvm
*kvm, long ext)
        case KVM_CAP_VM_COPY_ENC_CONTEXT_FROM:
        case KVM_CAP_SREGS2:
        case KVM_CAP_EXIT_ON_EMULATION_FAILURE:
+       case KVM_CAP_VCPU_ATTRIBUTES:
                r = 1;
                break;
        case KVM_CAP_EXIT_HYPERCALL:
-- 
2.33.0.rc2.250.ged5fa647cd-goog


From heiko at sntech.de  Mon Aug 23 14:20:04 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 23 Aug 2021 23:20:04 +0200
Subject: [PATCH] arm64: dts: rockchip: Fix GPU register width for RK3328
In-Reply-To: <c586d864-994f-2d24-9b29-2933b567be84@gmail.com>
References: <20210623115926.164861-1-knaerzche@gmail.com>
 <c586d864-994f-2d24-9b29-2933b567be84@gmail.com>
Message-ID: <7657417.31r3eYUQgx@phil>

Hi Alex,

Am Montag, 23. August 2021, 00:19:08 CEST schrieb Alex Bee:
> Hi Heiko,
> 
> is there anything left to do for this one?

nope, there wasn't anything missing, I just somehow managed to overlook
the patch till your ping. As you can see from the other mail, it is
applied now :-)

Heiko

> 
> Same for:
> 
> https://patchwork.kernel.org/project/linux-rockchip/patch/20210623145918.187018-1-knaerzche at gmail.com/
> 
> and
> 
> https://patchwork.kernel.org/project/linux-rockchip/patch/20210623150208.187201-1-knaerzche at gmail.com/
> 
> Alex
> 
> Am 23.06.21 um 13:59 schrieb Alex Bee:
> > As can be seen in RK3328's TRM the register range for the GPU is
> > 0xff300000 to 0xff330000.
> > It would (and does in vendor kernel) overlap with the registers of
> > the HEVC encoder (node/driver do not exist yet in upstream kernel).
> > See already existing h265e_mmu node.
> >
> > Fixes: 752fbc0c8da7 ("arm64: dts: rockchip: add rk3328 mali gpu node")
> > Signed-off-by: Alex Bee <knaerzche at gmail.com>
> > ---
> >   arch/arm64/boot/dts/rockchip/rk3328.dtsi | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > index 8c821acb21ff..da84be6f4715 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
> > @@ -599,7 +599,7 @@ saradc: adc at ff280000 {
> >   
> >   	gpu: gpu at ff300000 {
> >   		compatible = "rockchip,rk3328-mali", "arm,mali-450";
> > -		reg = <0x0 0xff300000 0x0 0x40000>;
> > +		reg = <0x0 0xff300000 0x0 0x30000>;
> >   		interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
> >   			     <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
> >   			     <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
> 






From maz at kernel.org  Mon Aug 23 14:51:48 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 23 Aug 2021 22:51:48 +0100
Subject: [PATCH] KVM: arm64: Ratelimit error log during guest debug
 exception
In-Reply-To: <CAJHc60wLPFZ5XFwWVyex5GXr=qm7QWc2yOmkECxLh=L2QnvgWg@mail.gmail.com>
References: <20210819223406.1132426-1-rananta@google.com>
 <87sfz4qx9r.wl-maz@kernel.org>
 <CAJHc60wn7PP1zQ5EKOGQDFbZsf=d9codWTuWbtMT5AHegfbVHw@mail.gmail.com>
 <875yvzqd5d.wl-maz@kernel.org>
 <CAJHc60wLPFZ5XFwWVyex5GXr=qm7QWc2yOmkECxLh=L2QnvgWg@mail.gmail.com>
Message-ID: <1a0dfd2bc950cb84e7344973657c6b23@kernel.org>

On 2021-08-23 19:13, Raghavendra Rao Ananta wrote:
> On Sat, Aug 21, 2021 at 3:56 AM Marc Zyngier <maz at kernel.org> wrote:
>> 
>> On Sat, 21 Aug 2021 00:01:24 +0100,
>> Raghavendra Rao Ananta <rananta at google.com> wrote:
>> >
>> > [1  <text/plain; UTF-8 (7bit)>]
>> > On Fri, Aug 20, 2021 at 2:29 AM Marc Zyngier <maz at kernel.org> wrote:
>> > >
>> > > On Thu, 19 Aug 2021 23:34:06 +0100,
>> > > Raghavendra Rao Ananta <rananta at google.com> wrote:
>> > > >
>> > > > Potentially, the guests could trigger a debug exception that's
>> > > > outside the exception class range.
>> > >
>> > > How? All the exception classes that lead to this functions are already
>> > > handled in the switch/case statement.
>> > >
>> > I guess I didn't think this through. Landing into kvm_handle_guest_debug()
>> > itself is not possible :)
>> 
>> Exactly.
>> 
>> > > My take on this is that this code isn't reachable, and that it could
>> > > be better rewritten as:
>> > >
>> > > diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
>> > > index 6f48336b1d86..ae7ec086827b 100644
>> > > --- a/arch/arm64/kvm/handle_exit.c
>> > > +++ b/arch/arm64/kvm/handle_exit.c
>> > > @@ -119,28 +119,14 @@ static int kvm_handle_guest_debug(struct kvm_vcpu
>> > *vcpu)
>> > >  {
>> > >         struct kvm_run *run = vcpu->run;
>> > >         u32 esr = kvm_vcpu_get_esr(vcpu);
>> > > -       int ret = 0;
>> > >
>> > >         run->exit_reason = KVM_EXIT_DEBUG;
>> > >         run->debug.arch.hsr = esr;
>> > >
>> > > -       switch (ESR_ELx_EC(esr)) {
>> > > -       case ESR_ELx_EC_WATCHPT_LOW:
>> > > +       if (ESR_ELx_EC(esr) ==  ESR_ELx_EC_WATCHPT_LOW)
>> > >                 run->debug.arch.far = vcpu->arch.fault.far_el2;
>> > > -               fallthrough;
>> > > -       case ESR_ELx_EC_SOFTSTP_LOW:
>> > > -       case ESR_ELx_EC_BREAKPT_LOW:
>> > > -       case ESR_ELx_EC_BKPT32:
>> > > -       case ESR_ELx_EC_BRK64:
>> > > -               break;
>> > > -       default:
>> > > -               kvm_err("%s: un-handled case esr: %#08x\n",
>> > > -                       __func__, (unsigned int) esr);
>> > > -               ret = -1;
>> > > -               break;
>> > > -       }
>> > >
>> > > -       return ret;
>> > > +       return 0;
>> > >  }
>> > >
>> > This looks better, but do you think we would be compromising on readability?
>> 
>> I don't think so. The exit handler table is, on its own, pretty
>> explicit about what we route to this handler, and the comment above
>> the function clearly states that we exit to userspace for all the
>> debug ECs.
> 
> Sounds great. I'm happy to send out a patch with you as 'Suggested-by' 
> , if you
> are okay with it.

Fire away!

         M.
-- 
Jazz is not dead. It just smells funny...


From michael at walle.cc  Mon Aug 23 15:17:50 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 24 Aug 2021 00:17:50 +0200
Subject: [PATCH v2 01/35] mtd: spi-nor: core: Introduce SPI_NOR_PARSE_SFDP
In-Reply-To: <20210727045222.905056-2-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-2-tudor.ambarus@microchip.com>
Message-ID: <dea2bcb1c6ad0e1018d29f16d0997c92@walle.cc>

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
> SPI NOR flashes that statically declare one of the
> SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
> the RDSFDP command are gratuiously receiving the RDSFDP command
> in the attempt of parsing the SFDP tables. It is not desirable to issue
> commands that are not supported, so introduce a flag to help on this
> situation.
> 
> New flash additions that support the SFDP standard should be declared
> using SPI_NOR_PARSE_SFDP. Support that can be discovered when parsing
> SFDP should not be duplicated by explicit flags at flash declaration.
> All the flash parameters will be discovered when parsing SFDP.
> Sometimes manufacturers wrongly define some fields in the SFDP tables.
> If that's the case, SFDP data can be amended with the fixups() hooks.
> It is not common, but if the SFDP tables are entirely wrong, and it
> does not worth the hassle to tweak the SFDP parameters by using the
> fixups hooks, or if the flash does not define the SFDP tables at all,
> then statically init the flash with the SPI_NOR_SKIP_SFDP flag and
> specify the rest of flash capabilities with the flash info flags.
> 
> With time, we want to convert all flashes to SPI_NOR_PARSE_SFDP and
> stop triggering the SFDP parsing with the
> SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
> SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable, the rest
> are a long term goal.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> Reviewed-by: Heiko Thiery <heiko.thiery at gmail.com>

Reviewed-by: Michael Walle <michael at walle.cc>


From michael at walle.cc  Mon Aug 23 15:32:27 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 24 Aug 2021 00:32:27 +0200
Subject: [PATCH v2 02/35] mtd: spi-nor: core: Report correct name in case
 of ID collisions
In-Reply-To: <20210804082345.ztciqvdeljvyx5by@ti.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-3-tudor.ambarus@microchip.com>
 <20210804082345.ztciqvdeljvyx5by@ti.com>
Message-ID: <2bf49b90095c96316fe4cec584ce0a0a@walle.cc>

Am 2021-08-04 10:23, schrieb Pratyush Yadav:
> On 27/07/21 07:51AM, Tudor Ambarus wrote:
>> Provide a way to report the correct flash name in case of ID 
>> collisions.
>> There will be a single flash_info entry when flash IDs collide, and 
>> the
>> differentiation between the flash types will be made at runtime
>> if possible.
> 
> I have the same comments as last time around. I am not convinced that
> this approach is better than having multiple entries, one for each
> colliding flash. I wonder how you will handle different fixups for the
> colliding flashes for example, since nor->info is const.

I thought of multple entries in xx_parts[], too. But how would you 
choose
between those? The flash id is the same, only the name would be 
different.
Searching by name seems cumbersome. Also, the fixup of the first match
will change the pointer (or maybe an additional pointer, so we still
have the original match), and thus also changes the pointer to the fixup
itself.

-michael


From rananta at google.com  Mon Aug 23 15:39:40 2021
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Mon, 23 Aug 2021 22:39:40 +0000
Subject: [PATCH] KVM: arm64: Trim guest debug exception handling
Message-ID: <20210823223940.1878930-1-rananta@google.com>

The switch-case for handling guest debug exception covers
all the debug exception classes, but functionally, doesn't
do anything with them other than ESR_ELx_EC_WATCHPT_LOW.
Moreover, even though handled well, the 'default' case
could be confusing from a security point of view, stating
that the guests' actions can potentially flood the syslog.
But in reality, the code is unreachable.

Hence, trim down the function to only handle the case with
ESR_ELx_EC_WATCHPT_LOW with a simple 'if' check.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 arch/arm64/kvm/handle_exit.c | 20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 04ebab299aa4..275a27368a04 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -113,34 +113,20 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu)
  * guest and host are using the same debug facilities it will be up to
  * userspace to re-inject the correct exception for guest delivery.
  *
- * @return: 0 (while setting vcpu->run->exit_reason), -1 for error
+ * @return: 0 (while setting vcpu->run->exit_reason)
  */
 static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu)
 {
 	struct kvm_run *run = vcpu->run;
 	u32 esr = kvm_vcpu_get_esr(vcpu);
-	int ret = 0;
 
 	run->exit_reason = KVM_EXIT_DEBUG;
 	run->debug.arch.hsr = esr;
 
-	switch (ESR_ELx_EC(esr)) {
-	case ESR_ELx_EC_WATCHPT_LOW:
+	if (ESR_ELx_EC(esr) == ESR_ELx_EC_WATCHPT_LOW)
 		run->debug.arch.far = vcpu->arch.fault.far_el2;
-		fallthrough;
-	case ESR_ELx_EC_SOFTSTP_LOW:
-	case ESR_ELx_EC_BREAKPT_LOW:
-	case ESR_ELx_EC_BKPT32:
-	case ESR_ELx_EC_BRK64:
-		break;
-	default:
-		kvm_err("%s: un-handled case esr: %#08x\n",
-			__func__, (unsigned int) esr);
-		ret = -1;
-		break;
-	}
 
-	return ret;
+	return 0;
 }
 
 static int kvm_handle_unknown_ec(struct kvm_vcpu *vcpu)
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From michael at walle.cc  Mon Aug 23 15:42:17 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 24 Aug 2021 00:42:17 +0200
Subject: [PATCH v2 03/35] mtd: spi-nor: macronix: Handle ID collision b/w
 MX25L3233F and MX25L3205D
In-Reply-To: <20210727045222.905056-4-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-4-tudor.ambarus@microchip.com>
Message-ID: <e41e5aa88846c87d041e3c3ea7845202@walle.cc>

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
> Macronix has a bad habbit of reusing flash IDs. While MX25L3233F 
> supports
> RDSFDP opcode, MX25L3205D does not support it and does not recommend
> issuing opcodes that are not supported ("It is not recommended to adopt
> any other code not in the command definition table, which will 
> potentially
> enter the hidden mode.").
> 
> We tested the RDSFDP on the MX25L3205D and the conclusion is that the
> flash didn't reply anything. Given that it is unlikely that RDSFDP will
> cause any problems for the old MX25L3205D, differentiate between the 
> two
> flashes by parsing SFDP.
> 
> Tested MX25L3233F. Generated a 256 Kbyte random data and did an erase,
> write, read back and compare test. The flash uses for reads
> SPINOR_OP_READ_1_4_4 0xeb, for erases SPINOR_OP_BE_4K 0x20, and for 
> writes
> SPINOR_OP_PP 0x02.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> Acked-by: Pratyush Yadav <p.yadav at ti.com>
> ---
> root at sama5d2-xplained:~# find / -iname spi-nor
> /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
> /sys/devices/platform/ahb/ahb:apb/f8000000.spi/spi_master/spi0/spi0.0/spi-nor
> /sys/bus/spi/drivers/spi-nor
> root at sama5d2-xplained:~# ls -al
> /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
> total 0
> drwxr-xr-x 2 root root    0 Mar  9 14:51 .
> drwxr-xr-x 6 root root    0 Mar  9 14:50 ..
> -r--r--r-- 1 root root 4096 Mar  9 14:51 jedec_id
> -r--r--r-- 1 root root 4096 Mar  9 14:51 manufacturer
> -r--r--r-- 1 root root 4096 Mar  9 14:51 partname
> -r--r--r-- 1 root root    0 Mar  9 14:51 sfdp
> root at sama5d2-xplained:~# cat
> /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
> c22016
> root at sama5d2-xplained:~# cat
> /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
> macronix
> root at sama5d2-xplained:~# cat
> /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname
> mx25l3233f
> root at sama5d2-xplained:~# cat
> /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp
> > mx25l3233f-sfdp
> root at sama5d2-xplained:~# hexdump mx25l3233f-sfdp

use xxd if possible and the sha1sum/md5sum is missing.

> 0000000 4653 5044 0100 ff01 0000 0901 0030 ff00
> 0000010 00c2 0401 0060 ff00 ffff ffff ffff ffff
> 0000020 ffff ffff ffff ffff ffff ffff ffff ffff
> 0000030 20e5 fff1 ffff 01ff eb44 6b08 3b08 bb04
> 0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
> 0000050 d810 ff00 ffff ffff ffff ffff ffff ffff
> 0000060 3600 2650 f99c 6477 cffe ffff ffff ffff
> 0000070
> 
>  drivers/mtd/spi-nor/macronix.c | 23 ++++++++++++++++++++++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/macronix.c 
> b/drivers/mtd/spi-nor/macronix.c
> index 27498ed0cc0d..68f6ac060bc6 100644
> --- a/drivers/mtd/spi-nor/macronix.c
> +++ b/drivers/mtd/spi-nor/macronix.c
> @@ -8,6 +8,24 @@
> 
>  #include "core.h"
> 
> +static int mx25l3233f_post_bfpt_fixups(struct spi_nor *nor,
> +				const struct sfdp_parameter_header *bfpt_header,
> +				const struct sfdp_bfpt *bfpt)
> +{
> +	/*
> +	 * Macronix has a bad habit of reusing flash IDs: MX25L3233F collides
> +	 * with MX25L3205D. MX25L3233F defines SFDP tables, while the older
> +	 * variant does not.
> +	 */
> +	nor->name = "mx25l3233f";
> +
> +	return 0;
> +}
> +
> +static struct spi_nor_fixups mx25l3233f_fixups = {
> +	.post_bfpt = mx25l3233f_post_bfpt_fixups,
> +};
> +
>  static int
>  mx25l25635_post_bfpt_fixups(struct spi_nor *nor,
>  			    const struct sfdp_parameter_header *bfpt_header,
> @@ -39,7 +57,10 @@ static const struct flash_info macronix_parts[] = {
>  	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
>  	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
>  	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
> -	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SECT_4K) },
> +	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SPI_NOR_PARSE_SFDP 
> |
> +			      SECT_4K)
> +		/* ID collision with mx25l3233f. */
> +		.fixups = &mx25l3233f_fixups },

Shouldn't we use mx25l3205d_fixups as name here? What if there are more
flashes with the same id. Using the name of the colliding flash here
doesn't really scale.

-michael

>  	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
>  	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
>  	{ "mx25u2033e",  INFO(0xc22532, 0, 64 * 1024,   4, SECT_4K) },


From michael at walle.cc  Mon Aug 23 15:44:08 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 24 Aug 2021 00:44:08 +0200
Subject: [PATCH v2 04/35] mtd: spi-nor: macronix: Handle ID collision b/w
 MX25L12805D and MX25L12835F
In-Reply-To: <20210727045222.905056-5-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-5-tudor.ambarus@microchip.com>
Message-ID: <afaa6337b35c79dc39dff5a821fb449b@walle.cc>

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
> MX25L12835F define SFDP, while MX25L12805D does not.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> Testd-by: Heiko Thiery <heiko.thiery at gmail.com>
> Acked-by: Pratyush Yadav <p.yadav at ti.com>

Same remarks as patch #3.

-michael

> # cat 
> /sys/devices/platform/soc at 0/30800000.bus/30bb0000.spi/spi_master/spi0/spi0
> .0/spi-nor/sfdp | xxd -p
> 53464450000101ff00000109300000ffc2000104600000ffffffffffffff
> ffffffffffffffffffffffffffffffffffffe520f1ffffffff0744eb086b
> 083b04bbfeffffffffff00ffffff44eb0c200f5210d800ffffffffffffff
> ffffffffffff003600279df9c06485cbffffffffffff
> 
>  drivers/mtd/spi-nor/macronix.c | 24 ++++++++++++++++++++++--
>  1 file changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/macronix.c 
> b/drivers/mtd/spi-nor/macronix.c
> index 68f6ac060bc6..fba85efafb47 100644
> --- a/drivers/mtd/spi-nor/macronix.c
> +++ b/drivers/mtd/spi-nor/macronix.c
> @@ -8,6 +8,24 @@
> 
>  #include "core.h"
> 
> +static int mx25l12835f_post_bfpt_fixups(struct spi_nor *nor,
> +				const struct sfdp_parameter_header *bfpt_header,
> +				const struct sfdp_bfpt *bfpt)
> +{
> +	/*
> +	 * Macronix has a bad habit of reusing flash IDs: MX25L12835F 
> collides
> +	 * with MX25L12805D. MX25L12835F defines SFDP tables, while the older
> +	 * variant does not.
> +	 */
> +	nor->name = "mx25l12835f";
> +
> +	return 0;
> +}
> +
> +static struct spi_nor_fixups mx25l12835f_fixups = {
> +	.post_bfpt = mx25l12835f_post_bfpt_fixups,
> +};
> +
>  static int mx25l3233f_post_bfpt_fixups(struct spi_nor *nor,
>  				const struct sfdp_parameter_header *bfpt_header,
>  				const struct sfdp_bfpt *bfpt)
> @@ -70,8 +88,10 @@ static const struct flash_info macronix_parts[] = {
>  	{ "mx25u4035",   INFO(0xc22533, 0, 64 * 1024,   8, SECT_4K) },
>  	{ "mx25u8035",   INFO(0xc22534, 0, 64 * 1024,  16, SECT_4K) },
>  	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
> -	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, SECT_4K |
> -			      SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) },
> +	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP 
> |
> +			      SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP)
> +		/* ID collision with mx25l12835f. */
> +		.fixups = &mx25l12835f_fixups },
>  	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
>  	{ "mx25r1635f",  INFO(0xc22815, 0, 64 * 1024,  32,
>  			      SECT_4K | SPI_NOR_DUAL_READ |


From michael at walle.cc  Mon Aug 23 15:47:33 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 24 Aug 2021 00:47:33 +0200
Subject: [PATCH v2 05/35] mtd: spi-nor: Introduce Manufacturer ID
 collisions driver
In-Reply-To: <20210727045222.905056-6-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-6-tudor.ambarus@microchip.com>
Message-ID: <fb581e64c1af72f30fdd10157e7275d4@walle.cc>

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
> Some manufacturers completely ignore the manufacturer's identification 
> code
> standard (JEP106) and do not define the manufacturer ID continuation
> scheme. This will result in manufacturer ID collisions.
> 
> An an example, JEP106BA requires Boya that it's manufacturer ID to be
> preceded by 8 continuation codes. Boya's identification code must be:
> 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x68. But Boya ignores 
> the
> continuation scheme and its ID collides with the manufacturer defined 
> in
> bank one: Convex Computer.
> 
> Introduce the manuf-id-collisions driver in order to address ID 
> collisions
> between manufacturers. flash_info entries will be added in a first 
> come,
> first served manner. Differentiation between flashes will be done at
> runtime if possible. Where runtime differentiation is not possible, new
> compatibles will be introduced, but this will be done as a last resort.
> Every new flash addition that define the SFDP tables, should dump its 
> SFDP
> tables in the patch's comment section below the --- line, so that we 
> can
> reference it in case of collisions.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/Makefile              |  1 +
>  drivers/mtd/spi-nor/core.c                |  1 +
>  drivers/mtd/spi-nor/core.h                |  1 +
>  drivers/mtd/spi-nor/manuf-id-collisions.c | 22 ++++++++++++++++++++++
>  4 files changed, 25 insertions(+)
>  create mode 100644 drivers/mtd/spi-nor/manuf-id-collisions.c
> 
> diff --git a/drivers/mtd/spi-nor/Makefile 
> b/drivers/mtd/spi-nor/Makefile
> index 6b904e439372..48763d10daad 100644
> --- a/drivers/mtd/spi-nor/Makefile
> +++ b/drivers/mtd/spi-nor/Makefile
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
> 
>  spi-nor-objs			:= core.o sfdp.o swp.o otp.o sysfs.o
> +spi-nor-objs			+= manuf-id-collisions.o
>  spi-nor-objs			+= atmel.o
>  spi-nor-objs			+= catalyst.o
>  spi-nor-objs			+= eon.o
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 1a278d33b02d..d30c8f350dc1 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -1829,6 +1829,7 @@ int spi_nor_sr2_bit7_quad_enable(struct spi_nor 
> *nor)
>  }
> 
>  static const struct spi_nor_manufacturer *manufacturers[] = {
> +	&spi_nor_manuf_id_collisions,

Intentionally at the beginning of all the flashes? So these
might take precedence over "normal" ones? Shouldn't it be
the other way around?

>  	&spi_nor_atmel,
>  	&spi_nor_catalyst,
>  	&spi_nor_eon,
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 55fceb0ec894..e9896cd60695 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -476,6 +476,7 @@ struct sfdp {
>  };
> 
>  /* Manufacturer drivers. */
> +extern const struct spi_nor_manufacturer spi_nor_manuf_id_collisions;
>  extern const struct spi_nor_manufacturer spi_nor_atmel;
>  extern const struct spi_nor_manufacturer spi_nor_catalyst;
>  extern const struct spi_nor_manufacturer spi_nor_eon;
> diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c
> b/drivers/mtd/spi-nor/manuf-id-collisions.c
> new file mode 100644
> index 000000000000..bf7dba34f018
> --- /dev/null
> +++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Used to handle collisions between manufacturers, where 
> manufacturers are
> + * ignorant enough to not implement the ID continuation scheme 
> described in the
> + * JEP106 JEDEC standard.
> + */
> +
> +#include <linux/mtd/spi-nor.h>
> +#include "core.h"
> +
> +static const struct flash_info id_collision_parts[] = {
> +	/* Boya */
> +	{ "by25q128as", INFO(0x684018, 0, 64 * 1024, 256, SPI_NOR_SKIP_SFDP |
> +			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> +			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
> +};
> +
> +const struct spi_nor_manufacturer spi_nor_manuf_id_collisions = {
> +	.name = "manufacturer ID collisions",

mhh, so we loose the manufacturer name. Doh. Can we do better?

-michael

> +	.parts = id_collision_parts,
> +	.nparts = ARRAY_SIZE(id_collision_parts),
> +};


From bgardon at google.com  Mon Aug 23 16:46:30 2021
From: bgardon at google.com (Ben Gardon)
Date: Mon, 23 Aug 2021 16:46:30 -0700
Subject: [PATCH v2 5/5] KVM: selftests: Remove __NR_userfaultfd syscall
 fallback
In-Reply-To: <20210820225002.310652-6-seanjc@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-6-seanjc@google.com>
Message-ID: <CANgfPd_Vh52oWyMMcqL2iTVgcXQp3QDsM5MrAZxr=xe33rPMhg@mail.gmail.com>

On Fri, Aug 20, 2021 at 3:50 PM Sean Christopherson <seanjc at google.com> wrote:
>
> Revert the __NR_userfaultfd syscall fallback added for KVM selftests now
> that x86's unistd_{32,63}.h overrides are under uapi/ and thus not in
> KVM sefltests' search path, i.e. now that KVM gets x86 syscall numbers
> from the installed kernel headers.
>
> No functional change intended.
>
> Cc: Ben Gardon <bgardon at google.com>
> Signed-off-by: Sean Christopherson <seanjc at google.com>

Reviewed-by: Ben Gardon <bgardon at google.com>

> ---
>  tools/arch/x86/include/uapi/asm/unistd_64.h | 3 ---
>  1 file changed, 3 deletions(-)
>
> diff --git a/tools/arch/x86/include/uapi/asm/unistd_64.h b/tools/arch/x86/include/uapi/asm/unistd_64.h
> index 4205ed4158bf..cb52a3a8b8fc 100644
> --- a/tools/arch/x86/include/uapi/asm/unistd_64.h
> +++ b/tools/arch/x86/include/uapi/asm/unistd_64.h
> @@ -1,7 +1,4 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef __NR_userfaultfd
> -#define __NR_userfaultfd 282
> -#endif
>  #ifndef __NR_perf_event_open
>  # define __NR_perf_event_open 298
>  #endif
> --
> 2.33.0.rc2.250.ged5fa647cd-goog
>


From sfr at canb.auug.org.au  Mon Aug 23 16:49:01 2021
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Tue, 24 Aug 2021 09:49:01 +1000
Subject: linux-next: manual merge of the arm-soc tree with the arm-soc-fixes
 tree
Message-ID: <20210824094901.57a3ab0c@canb.auug.org.au>

Hi all,

Today's linux-next merge of the arm-soc tree got a conflict in:

  arch/arm64/boot/dts/marvell/cn9130-db.dts

between commit:

  054bc6a105d7 ("arm/arm64: dts: Fix remaining dtc 'unit_address_format' warnings")

from the arm-soc-fixes tree and commit:

  4c43a41e5b8c ("arm64: dts: cn913x: add device trees for topology B boards")

from the arm-soc tree.

I fixed it up (used this file from the latter and applied the following
merge resolution patch) and can carry the fix as necessary. This is now
fixed as far as linux-next is concerned, but any non trivial conflicts
should be mentioned to your upstream maintainer when your tree is
submitted for merging.  You may also want to consider cooperating with
the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

From: Stephen Rothwell <sfr at canb.auug.org.au>
Date: Tue, 24 Aug 2021 09:44:25 +1000
Subject: [PATCH] arm64: dts: cn913x: fixup for ("arm/arm64: dts: Fix remaining dtc 'unit_address_format' warnings"

Signed-off-by: Stephen Rothwell <sfr at canb.auug.org.au>
---
 arch/arm64/boot/dts/marvell/cn9130-db.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
index 2cd4bb09e8ff..c00b69b88bd2 100644
--- a/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
+++ b/arch/arm64/boot/dts/marvell/cn9130-db.dtsi
@@ -25,7 +25,7 @@ aliases {
 		spi2 = &cp0_spi1;
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x80000000>;
 	};
-- 
2.32.0

-- 
Cheers,
Stephen Rothwell
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210824/bb67340e/attachment.sig>

From sashal at kernel.org  Mon Aug 23 17:53:56 2021
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 23 Aug 2021 20:53:56 -0400
Subject: [PATCH AUTOSEL 5.13 26/26] arm64: initialize all of CNTHCTL_EL2
In-Reply-To: <20210824005356.630888-1-sashal@kernel.org>
References: <20210824005356.630888-1-sashal@kernel.org>
Message-ID: <20210824005356.630888-26-sashal@kernel.org>

From: Mark Rutland <mark.rutland at arm.com>

[ Upstream commit bde8fff82e4a4b0f000dbf4d5eadab2079be0b56 ]

In __init_el2_timers we initialize CNTHCTL_EL2.{EL1PCEN,EL1PCTEN} with a
RMW sequence, leaving all other bits UNKNOWN.

In general, we should initialize all bits in a register rather than
using an RMW sequence, since most bits are UNKNOWN out of reset, and as
new bits are added to the reigster their reset value might not result in
expected behaviour.

In the case of CNTHCTL_EL2, FEAT_ECV added a number of new control bits
in previously RES0 bits, which reset to UNKNOWN values, and may cause
issues for EL1 and EL0:

* CNTHCTL_EL2.ECV enables the CNTPOFF_EL2 offset (which itself resets to
  an UNKNOWN value) at EL0 and EL1. Since the offset could reset to
  distinct values across CPUs, when the control bit resets to 1 this
  could break timekeeping generally.

* CNTHCTL_EL2.{EL1TVT,EL1TVCT} trap EL0 and EL1 accesses to the EL1
  virtual timer/counter registers to EL2. When reset to 1, this could
  cause unexpected traps to EL2.

Initializing these bits to zero avoids these problems, and all other
bits in CNTHCTL_EL2 other than EL1PCEN and EL1PCTEN can safely be reset
to zero.

This patch ensures we initialize CNTHCTL_EL2 accordingly, only setting
EL1PCEN and EL1PCTEN, and setting all other bits to zero.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Oliver Upton <oupton at google.com>
Cc: Will Deacon <will at kernel.org>
Reviewed-by: Oliver Upton <oupton at google.com>
Acked-by: Marc Zyngier <maz at kernel.org>
Link: https://lore.kernel.org/r/20210818161535.52786-1-mark.rutland at arm.com
Signed-off-by: Will Deacon <will at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 21fa330f498d..b83fb24954b7 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -33,8 +33,7 @@
  * EL2.
  */
 .macro __init_el2_timers
-	mrs	x0, cnthctl_el2
-	orr	x0, x0, #3			// Enable EL1 physical timers
+	mov	x0, #3				// Enable EL1 physical timers
 	msr	cnthctl_el2, x0
 	msr	cntvoff_el2, xzr		// Clear virtual offset
 .endm
-- 
2.30.2



From leo.yan at linaro.org  Mon Aug 23 19:13:11 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 24 Aug 2021 10:13:11 +0800
Subject: [PATCH v1 2/3] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <1c0101fd-2ca6-4741-5d72-82d3e00bfeb6@arm.com>
References: <20210809112727.596876-1-leo.yan@linaro.org>
 <20210809112727.596876-3-leo.yan@linaro.org>
 <2b4e0c07-a8df-cca6-6a94-328560f4b0c6@arm.com>
 <20210823095155.GC100516@leoy-ThinkPad-X240s>
 <319ee11a-06f7-abde-6495-d2175928b9fe@arm.com>
 <20210823121348.GE100516@leoy-ThinkPad-X240s>
 <1c0101fd-2ca6-4741-5d72-82d3e00bfeb6@arm.com>
Message-ID: <20210824021311.GB169379@leoy-ThinkPad-X240s>

On Mon, Aug 23, 2021 at 05:00:14PM +0100, James Clark wrote:

[...]

> >> I couldn't see how it can ever return -1, it seems like it would loop forever
> >> until it reads the correct value.
> > 
> > I use this chunk comment to address the function
> > compat_auxtrace_mmap__write_tail():
> > 
> > +int __weak compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
> > +{
> > +	struct perf_event_mmap_page *pc = mm->userpg;
> > +	u64 mask = (u64)(UINT32_MAX) << 32;
> > +
> > +	if (tail & mask)
> > +		return -1;
> > +
> > +	/* Ensure all reads are done before we write the tail out */
> > +	smp_mb();
> > +	WRITE_ONCE(pc->aux_tail, tail);
> > +	return 0;
> > +}
> > 
> > Please let me know if this is okay or not?  Otherwise, if you think
> > the format can cause confusion, I'd like to split the comments into
> > two sections, one section for reading AUX head and another is for
> > writing AUX tail.
> 
> I see what you mean now, I think keeping it in one section is fine, I would just
> replace "When update the AUX tail and detects" with "When
> compat_auxtrace_mmap__write_tail() detects". If the function name is there then
> it's clear that it's not the return value of compat_auxtrace_mmap__read_head()

Sure, will update and send out the new patch.

Thanks for suggestion.
Leo


From sashal at kernel.org  Mon Aug 23 19:58:02 2021
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 23 Aug 2021 22:58:02 -0400
Subject: FAILED: Patch "mmc: sdhci-iproc: Cap min clock frequency on BCM2711"
 failed to apply to 5.4-stable tree
Message-ID: <20210824025802.658609-1-sashal@kernel.org>

The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From c9107dd0b851777d7e134420baf13a5c5343bc16 Mon Sep 17 00:00:00 2001
From: Nicolas Saenz Julienne <nsaenz at kernel.org>
Date: Sat, 7 Aug 2021 13:06:35 +0200
Subject: [PATCH] mmc: sdhci-iproc: Cap min clock frequency on BCM2711

There is a known bug on BCM2711's SDHCI core integration where the
controller will hang when the difference between the core clock and the
bus clock is too great. Specifically this can be reproduced under the
following conditions:

- No SD card plugged in, polling thread is running, probing cards at
  100 kHz.
- BCM2711's core clock configured at 500MHz or more.

So set 200 kHz as the minimum clock frequency available for that board.

For more information on the issue see this:
https://lore.kernel.org/linux-mmc/20210322185816.27582-1-nsaenz at kernel.org/T/#m11f2783a09b581da6b8a15f302625b43a6ecdeca

Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/1628334401-6577-5-git-send-email-stefan.wahren at i2se.com
Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
---
 drivers/mmc/host/sdhci-iproc.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index cce390fe9cf3..032bf852397f 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -173,6 +173,23 @@ static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host)
 		return pltfm_host->clock;
 }
 
+/*
+ * There is a known bug on BCM2711's SDHCI core integration where the
+ * controller will hang when the difference between the core clock and the bus
+ * clock is too great. Specifically this can be reproduced under the following
+ * conditions:
+ *
+ *  - No SD card plugged in, polling thread is running, probing cards at
+ *    100 kHz.
+ *  - BCM2711's core clock configured at 500MHz or more
+ *
+ * So we set 200kHz as the minimum clock frequency available for that SoC.
+ */
+static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
+{
+	return 200000;
+}
+
 static const struct sdhci_ops sdhci_iproc_ops = {
 	.set_clock = sdhci_set_clock,
 	.get_max_clock = sdhci_iproc_get_max_clock,
@@ -271,6 +288,7 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
 	.set_clock = sdhci_set_clock,
 	.set_power = sdhci_set_power_and_bus_voltage,
 	.get_max_clock = sdhci_iproc_get_max_clock,
+	.get_min_clock = sdhci_iproc_bcm2711_get_min_clock,
 	.set_bus_width = sdhci_set_bus_width,
 	.reset = sdhci_reset,
 	.set_uhs_signaling = sdhci_set_uhs_signaling,
-- 
2.30.2






From sashal at kernel.org  Mon Aug 23 19:58:04 2021
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 23 Aug 2021 22:58:04 -0400
Subject: FAILED: Patch "mmc: sdhci-iproc: Set
 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711" failed to apply to 5.4-stable
 tree
Message-ID: <20210824025805.658683-1-sashal@kernel.org>

The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable at vger.kernel.org>.

Thanks,
Sasha

------------------ original commit in Linus's tree ------------------

>From 419dd626e357e89fc9c4e3863592c8b38cfe1571 Mon Sep 17 00:00:00 2001
From: Nicolas Saenz Julienne <nsaenz at kernel.org>
Date: Sat, 7 Aug 2021 13:06:36 +0200
Subject: [PATCH] mmc: sdhci-iproc: Set SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on
 BCM2711

The controller doesn't seem to pick-up on clock changes, so set the
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN flag to query the clock frequency
directly from the clock.

Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/1628334401-6577-6-git-send-email-stefan.wahren at i2se.com
Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
---
 drivers/mmc/host/sdhci-iproc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
index 032bf852397f..e7565c671998 100644
--- a/drivers/mmc/host/sdhci-iproc.c
+++ b/drivers/mmc/host/sdhci-iproc.c
@@ -295,7 +295,8 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
 };
 
 static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
-	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
+	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
+		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
 	.ops = &sdhci_iproc_bcm2711_ops,
 };
 
-- 
2.30.2






From kewei.xu at mediatek.com  Mon Aug 23 20:30:21 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 24 Aug 2021 11:30:21 +0800
Subject: [RESEND PATCH v5 0/7] Introducing an attribute to select the time
 setting
Message-ID: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>

v5:
1. Replace the previous variable name "default_timing_adjust" with "use-default-timing"
2. Added waiting for dma reset mechanism
3. Remove received patch(dt-bindings: i2c: update bindings for MT8195 SOC)

v4:
1. Remove the repeated assignment of the inter_clk_div parameter
2. Modify the wrong assignment of OFFSET_MULTI_DMA
3. Unify the log print format of the i2c_dump_register() and drop the extra outer parentheses
4. Place the fixes at the very least
5. Add fixed tags 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183")
6. Add "i2c: mediatek: modify bus speed calculation formula"
7. Fix single line characters exceeding 80 characters
8. Combine two different series of patches.

v3:
1. Fix code errors caused by v2 modification

v2:
1. Add "dt-bindings: i2c: add attribute default-timing-adjust"
2. Split the fix into sepatate patch.

Kewei Xu (7):
  i2c: mediatek: fixing the incorrect register offset
  i2c: mediatek: Reset the handshake signal between i2c and dma
  i2c: mediatek: Dump i2c/dma register when a timeout occurs
  dt-bindings: i2c: add attribute use-default-timing
  i2c: mediatek: Add OFFSET_EXT_CONF setting back
  i2c: mediatek: Isolate speed setting via dts for special devices
  i2c: mediatek: modify bus speed calculation formula

 .../devicetree/bindings/i2c/i2c-mt65xx.txt         |   2 +
 drivers/i2c/busses/i2c-mt65xx.c                    | 207 +++++++++++++++++++--
 2 files changed, 192 insertions(+), 17 deletions(-)

-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 20:30:22 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 24 Aug 2021 11:30:22 +0800
Subject: [RESEND PATCH v5 1/7] i2c: mediatek: fixing the incorrect register
 offset
In-Reply-To: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
References: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629775828-19993-2-git-send-email-kewei.xu@mediatek.com>

The reason for the modification here is that the previous
offset information is incorrect, OFFSET_DEBUGSTAT = 0xE4 is
the correct value.

Fixes: 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/i2c/busses/i2c-mt65xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 4ca716e..2661ed0 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -193,7 +193,7 @@ enum I2C_REGS_OFFSET {
 	[OFFSET_CLOCK_DIV] = 0x48,
 	[OFFSET_SOFTRESET] = 0x50,
 	[OFFSET_SCL_MIS_COMP_POINT] = 0x90,
-	[OFFSET_DEBUGSTAT] = 0xe0,
+	[OFFSET_DEBUGSTAT] = 0xe4,
 	[OFFSET_DEBUGCTRL] = 0xe8,
 	[OFFSET_FIFO_STAT] = 0xf4,
 	[OFFSET_FIFO_THRESH] = 0xf8,
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 20:30:23 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 24 Aug 2021 11:30:23 +0800
Subject: [RESEND PATCH v5 2/7] i2c: mediatek: Reset the handshake signal
 between i2c and dma
In-Reply-To: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
References: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629775828-19993-3-git-send-email-kewei.xu@mediatek.com>

Due to changes in the hardware design of the handshaking signal
between i2c and dma, it is necessary to reset the handshaking
signal before each transfer to ensure that the multi-msgs can
be transferred correctly.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 2661ed0..abda525 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -47,6 +48,9 @@
 #define I2C_RD_TRANAC_VALUE		0x0001
 #define I2C_SCL_MIS_COMP_VALUE		0x0000
 #define I2C_CHN_CLR_FLAG		0x0000
+#define I2C_CLR_DEBUGCTR		0x0000
+#define I2C_RELIABILITY			0x0010
+#define I2C_DMAACK_ENABLE		0x0008
 
 #define I2C_DMA_CON_TX			0x0000
 #define I2C_DMA_CON_RX			0x0001
@@ -842,6 +846,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 	u16 restart_flag = 0;
 	u16 dma_sync = 0;
 	u32 reg_4g_mode;
+	u32 reg_dma_reset;
 	u8 *dma_rd_buf = NULL;
 	u8 *dma_wr_buf = NULL;
 	dma_addr_t rpaddr = 0;
@@ -855,6 +860,27 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 
 	reinit_completion(&i2c->msg_complete);
 
+	if (i2c->dev_comp->apdma_sync && left_num > 1) {
+		mtk_i2c_writew(i2c, I2C_CLR_DEBUGCTR, OFFSET_DEBUGCTRL);
+		writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_WARM_RST,
+		       i2c->pdmabase + OFFSET_RST);
+
+		ret = readw_poll_timeout(i2c->pdmabase + OFFSET_RST,
+					 reg_dma_reset,
+					 !(reg_dma_reset & I2C_DMA_WARM_RST),
+					 0, 100);
+		if (ret) {
+			dev_err(i2c->dev, "DMA warm reset timeout\n");
+			return -ETIMEDOUT;
+		}
+
+		writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
+		mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST, OFFSET_SOFTRESET);
+		mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET);
+		mtk_i2c_writew(i2c, I2C_RELIABILITY | I2C_DMAACK_ENABLE,
+			       OFFSET_DEBUGCTRL);
+	}
+
 	control_reg = mtk_i2c_readw(i2c, OFFSET_CONTROL) &
 			~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
 	if ((i2c->speed_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) || (left_num >= 1))
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 20:30:25 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 24 Aug 2021 11:30:25 +0800
Subject: [RESEND PATCH v5 4/7] dt-bindings: i2c: add attribute
 use-default-timing
In-Reply-To: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
References: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629775828-19993-5-git-send-email-kewei.xu@mediatek.com>

Add attribute use-default-timing for DT-binding document.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
index 5ea216a..4dbb697 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
@@ -34,6 +34,8 @@ Optional properties:
     Only mt6589 and mt8135 support this feature.
   - mediatek,use-push-pull: IO config use push-pull mode.
   - vbus-supply: phandle to the regulator that provides power to SCL/SDA.
+  - mediatek,use-default-timing: use default timing calculation, no timing
+    adjustment.
 
 Example:
 
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 20:30:24 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 24 Aug 2021 11:30:24 +0800
Subject: [RESEND PATCH v5 3/7] i2c: mediatek: Dump i2c/dma register when a
 timeout occurs
In-Reply-To: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
References: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629775828-19993-4-git-send-email-kewei.xu@mediatek.com>

When a timeout error occurs in i2c transter, it is usually related
to the i2c/dma IP hardware configuration. Therefore, the purpose of
this patch is to dump the key register values of i2c/dma when a
timeout occurs in i2c for debugging.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 56 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index abda525..633bce4 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -129,6 +129,7 @@ enum I2C_REGS_OFFSET {
 	OFFSET_HS,
 	OFFSET_SOFTRESET,
 	OFFSET_DCM_EN,
+	OFFSET_MULTI_DMA,
 	OFFSET_PATH_DIR,
 	OFFSET_DEBUGSTAT,
 	OFFSET_DEBUGCTRL,
@@ -196,6 +197,7 @@ enum I2C_REGS_OFFSET {
 	[OFFSET_TRANSFER_LEN_AUX] = 0x44,
 	[OFFSET_CLOCK_DIV] = 0x48,
 	[OFFSET_SOFTRESET] = 0x50,
+	[OFFSET_MULTI_DMA] = 0x8c,
 	[OFFSET_SCL_MIS_COMP_POINT] = 0x90,
 	[OFFSET_DEBUGSTAT] = 0xe4,
 	[OFFSET_DEBUGCTRL] = 0xe8,
@@ -837,6 +839,57 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
 	return 0;
 }
 
+static void i2c_dump_register(struct mtk_i2c *i2c)
+{
+	dev_err(i2c->dev, "SLAVE_ADDR: 0x%x, INTR_MASK: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_SLAVE_ADDR),
+		mtk_i2c_readw(i2c, OFFSET_INTR_MASK));
+	dev_err(i2c->dev, "INTR_STAT: 0x%x, CONTROL: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_INTR_STAT),
+		mtk_i2c_readw(i2c, OFFSET_CONTROL));
+	dev_err(i2c->dev, "TRANSFER_LEN: 0x%x, TRANSAC_LEN: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN),
+		mtk_i2c_readw(i2c, OFFSET_TRANSAC_LEN));
+	dev_err(i2c->dev, "DELAY_LEN: 0x%x, HTIMING: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DELAY_LEN),
+		mtk_i2c_readw(i2c, OFFSET_TIMING));
+	dev_err(i2c->dev, "START: 0x%x, EXT_CONF: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_START),
+		mtk_i2c_readw(i2c, OFFSET_EXT_CONF));
+	dev_err(i2c->dev, "HS: 0x%x, IO_CONFIG: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_HS),
+		mtk_i2c_readw(i2c, OFFSET_IO_CONFIG));
+	dev_err(i2c->dev, "DCM_EN: 0x%x, TRANSFER_LEN_AUX: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DCM_EN),
+		mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN_AUX));
+	dev_err(i2c->dev, "CLOCK_DIV: 0x%x, FIFO_STAT: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_CLOCK_DIV),
+		mtk_i2c_readw(i2c, OFFSET_FIFO_STAT));
+	dev_err(i2c->dev, "DEBUGCTRL : 0x%x, DEBUGSTAT: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DEBUGCTRL),
+		mtk_i2c_readw(i2c, OFFSET_DEBUGSTAT));
+	if (i2c->dev_comp->regs == mt_i2c_regs_v2) {
+		dev_err(i2c->dev, "LTIMING: 0x%x, MULTI_DMA: 0x%x\n",
+			mtk_i2c_readw(i2c, OFFSET_LTIMING),
+			mtk_i2c_readw(i2c, OFFSET_MULTI_DMA));
+	}
+	dev_err(i2c->dev, "\nDMA_INT_FLAG: 0x%x, DMA_INT_EN: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_INT_FLAG),
+		readl(i2c->pdmabase + OFFSET_INT_EN));
+	dev_err(i2c->dev, "DMA_EN: 0x%x, DMA_CON: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_EN),
+		readl(i2c->pdmabase + OFFSET_CON));
+	dev_err(i2c->dev, "DMA_TX_MEM_ADDR: 0x%x, DMA_RX_MEM_ADDR: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_TX_MEM_ADDR),
+		readl(i2c->pdmabase + OFFSET_RX_MEM_ADDR));
+	dev_err(i2c->dev, "DMA_TX_LEN: 0x%x, DMA_RX_LEN: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_TX_LEN),
+		readl(i2c->pdmabase + OFFSET_RX_LEN));
+	dev_err(i2c->dev, "DMA_TX_4G_MODE: 0x%x, DMA_RX_4G_MODE: 0x%x",
+		readl(i2c->pdmabase + OFFSET_TX_4G_MODE),
+		readl(i2c->pdmabase + OFFSET_RX_4G_MODE));
+}
+
 static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 			       int num, int left_num)
 {
@@ -1065,7 +1118,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 	}
 
 	if (ret == 0) {
-		dev_dbg(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
+		dev_err(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
+		i2c_dump_register(i2c);
 		mtk_i2c_init_hw(i2c);
 		return -ETIMEDOUT;
 	}
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 20:30:26 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 24 Aug 2021 11:30:26 +0800
Subject: [RESEND PATCH v5 5/7] i2c: mediatek: Add OFFSET_EXT_CONF setting back
In-Reply-To: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
References: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629775828-19993-6-git-send-email-kewei.xu@mediatek.com>

In the commit be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust
support"), we miss setting OFFSET_EXT_CONF register if
i2c->dev_comp->timing_adjust is false, now add it back.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 633bce4..4da6b43 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -42,6 +42,8 @@
 #define I2C_HANDSHAKE_RST		0x0020
 #define I2C_FIFO_ADDR_CLR		0x0001
 #define I2C_DELAY_LEN			0x0002
+#define I2C_ST_START_CON		0x8001
+#define I2C_FS_START_CON		0x1800
 #define I2C_TIME_CLR_VALUE		0x0000
 #define I2C_TIME_DEFAULT_VALUE		0x0003
 #define I2C_WRRD_TRANAC_VALUE		0x0002
@@ -486,6 +488,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 {
 	u16 control_reg;
 	u16 intr_stat_reg;
+	u16 ext_conf_val;
 
 	mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_START);
 	intr_stat_reg = mtk_i2c_readw(i2c, OFFSET_INTR_STAT);
@@ -524,8 +527,13 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 	if (i2c->dev_comp->ltiming_adjust)
 		mtk_i2c_writew(i2c, i2c->ltiming_reg, OFFSET_LTIMING);
 
+	if (i2c->speed_hz <= I2C_MAX_STANDARD_MODE_FREQ)
+		ext_conf_val = I2C_ST_START_CON;
+	else
+		ext_conf_val = I2C_FS_START_CON;
+
 	if (i2c->dev_comp->timing_adjust) {
-		mtk_i2c_writew(i2c, i2c->ac_timing.ext, OFFSET_EXT_CONF);
+		ext_conf_val = i2c->ac_timing.ext;
 		mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
 			       OFFSET_CLOCK_DIV);
 		mtk_i2c_writew(i2c, I2C_SCL_MIS_COMP_VALUE,
@@ -550,6 +558,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 				       OFFSET_HS_STA_STO_AC_TIMING);
 		}
 	}
+	mtk_i2c_writew(i2c, ext_conf_val, OFFSET_EXT_CONF);
 
 	/* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */
 	if (i2c->have_pmic)
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 20:30:27 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 24 Aug 2021 11:30:27 +0800
Subject: [RESEND PATCH v5 6/7] i2c: mediatek: Isolate speed setting via dts
 for special devices
In-Reply-To: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
References: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629775828-19993-7-git-send-email-kewei.xu@mediatek.com>

In the commit be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust
support"), the I2C timing calculation has been revised to support
ac-timing adjustment, however that will break on some I2C components.
As a result we want to introduce a new setting "default-adjust-timing"
so those components can choose to use the old (default) timing algorithm.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 77 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 4da6b43..18b5659 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -66,6 +66,7 @@
 #define I2C_DMA_HARD_RST		0x0002
 #define I2C_DMA_HANDSHAKE_RST		0x0004
 
+#define I2C_DEFAULT_CLK_DIV		5
 #define MAX_SAMPLE_CNT_DIV		8
 #define MAX_STEP_CNT_DIV		64
 #define MAX_CLOCK_DIV			256
@@ -250,6 +251,7 @@ struct mtk_i2c {
 	struct clk *clk_arb;		/* Arbitrator clock for i2c */
 	bool have_pmic;			/* can use i2c pins from PMIC */
 	bool use_push_pull;		/* IO config push-pull mode */
+	bool use_default_timing;	/* no timing adjust mode */
 
 	u16 irq_stat;			/* interrupt status */
 	unsigned int clk_src_div;
@@ -532,7 +534,11 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 	else
 		ext_conf_val = I2C_FS_START_CON;
 
-	if (i2c->dev_comp->timing_adjust) {
+	if (i2c->use_default_timing) {
+		if (i2c->dev_comp->timing_adjust)
+			mtk_i2c_writew(i2c, I2C_DEFAULT_CLK_DIV - 1,
+				       OFFSET_CLOCK_DIV);
+	} else if (i2c->dev_comp->timing_adjust) {
 		ext_conf_val = i2c->ac_timing.ext;
 		mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
 			       OFFSET_CLOCK_DIV);
@@ -615,7 +621,7 @@ static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c,
 	unsigned int sample_ns = div_u64(1000000000ULL * (sample_cnt + 1),
 					 clk_src);
 
-	if (!i2c->dev_comp->timing_adjust)
+	if (i2c->use_default_timing || !i2c->dev_comp->timing_adjust)
 		return 0;
 
 	if (i2c->dev_comp->ltiming_adjust)
@@ -775,7 +781,65 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	return 0;
 }
 
-static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
+static int mtk_i2c_set_speed_default_timing(struct mtk_i2c *i2c,
+					    unsigned int parent_clk)
+{
+	unsigned int clk_src;
+	unsigned int step_cnt;
+	unsigned int sample_cnt;
+	unsigned int l_step_cnt;
+	unsigned int l_sample_cnt;
+	unsigned int target_speed;
+	int ret;
+
+	if (i2c->dev_comp->timing_adjust)
+		i2c->clk_src_div *= I2C_DEFAULT_CLK_DIV;
+
+	clk_src = parent_clk / i2c->clk_src_div;
+	target_speed = i2c->speed_hz;
+
+	if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) {
+		/* Set master code speed register */
+		ret = mtk_i2c_calculate_speed(i2c, clk_src,
+					      I2C_MAX_FAST_MODE_FREQ,
+					      &l_step_cnt, &l_sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->timing_reg = (l_sample_cnt << 8) | l_step_cnt;
+
+		/* Set the high speed mode register */
+		ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->high_speed_reg = I2C_TIME_DEFAULT_VALUE |
+			(sample_cnt << 12) | (step_cnt << 8);
+
+		if (i2c->dev_comp->ltiming_adjust)
+			i2c->ltiming_reg = (l_sample_cnt << 6) | l_step_cnt |
+					   (sample_cnt << 12) | (step_cnt << 9);
+	} else {
+		ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->timing_reg = (sample_cnt << 8) | step_cnt;
+
+		/* Disable the high speed transaction */
+		i2c->high_speed_reg = I2C_TIME_CLR_VALUE;
+
+		if (i2c->dev_comp->ltiming_adjust)
+			i2c->ltiming_reg = (sample_cnt << 6) | step_cnt;
+	}
+
+	return 0;
+}
+
+static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
+					   unsigned int parent_clk)
 {
 	unsigned int clk_src;
 	unsigned int step_cnt;
@@ -1271,6 +1335,8 @@ static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c)
 	i2c->have_pmic = of_property_read_bool(np, "mediatek,have-pmic");
 	i2c->use_push_pull =
 		of_property_read_bool(np, "mediatek,use-push-pull");
+	i2c->use_default_timing =
+		of_property_read_bool(np, "mediatek,use-default-timing");
 
 	i2c_parse_fw_timings(i2c->dev, &i2c->timing_info, true);
 
@@ -1357,7 +1423,10 @@ static int mtk_i2c_probe(struct platform_device *pdev)
 
 	strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
 
-	ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk));
+	if (i2c->use_default_timing)
+		ret = mtk_i2c_set_speed_default_timing(i2c, clk_get_rate(clk));
+	else
+		ret = mtk_i2c_set_speed_adjust_timing(i2c, clk_get_rate(clk));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to set the speed.\n");
 		return -EINVAL;
-- 
1.9.1

From kewei.xu at mediatek.com  Mon Aug 23 20:30:28 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 24 Aug 2021 11:30:28 +0800
Subject: [RESEND PATCH v5 7/7] i2c: mediatek: modify bus speed calculation
 formula
In-Reply-To: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
References: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1629775828-19993-8-git-send-email-kewei.xu@mediatek.com>

When clock-div is 0 or greater than 1, the bus speed
calculated by the old speed calculation formula will be
larger than the target speed. So we update the formula.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 18b5659..0b42acd8 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -69,11 +69,12 @@
 #define I2C_DEFAULT_CLK_DIV		5
 #define MAX_SAMPLE_CNT_DIV		8
 #define MAX_STEP_CNT_DIV		64
-#define MAX_CLOCK_DIV			256
+#define MAX_CLOCK_DIV_8BITS		256
+#define MAX_CLOCK_DIV_5BITS		32
 #define MAX_HS_STEP_CNT_DIV		8
-#define I2C_STANDARD_MODE_BUFFER	(1000 / 2)
-#define I2C_FAST_MODE_BUFFER		(300 / 2)
-#define I2C_FAST_MODE_PLUS_BUFFER	(20 / 2)
+#define I2C_STANDARD_MODE_BUFFER	(1000 / 3)
+#define I2C_FAST_MODE_BUFFER		(300 / 3)
+#define I2C_FAST_MODE_PLUS_BUFFER	(20 / 3)
 
 #define I2C_CONTROL_RS                  (0x1 << 1)
 #define I2C_CONTROL_DMA_EN              (0x1 << 2)
@@ -725,14 +726,26 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	unsigned int best_mul;
 	unsigned int cnt_mul;
 	int ret = -EINVAL;
+	int clock_div_constraint = 0;
 
 	if (target_speed > I2C_MAX_HIGH_SPEED_MODE_FREQ)
 		target_speed = I2C_MAX_HIGH_SPEED_MODE_FREQ;
 
+	if (i2c->use_default_timing) {
+		clock_div_constraint = 0;
+	} else if (i2c->dev_comp->ltiming_adjust &&
+		   i2c->ac_timing.inter_clk_div > 1) {
+		clock_div_constraint = 1;
+	} else if (i2c->dev_comp->ltiming_adjust &&
+		   i2c->ac_timing.inter_clk_div == 0) {
+		clock_div_constraint = -1;
+	}
+
 	max_step_cnt = mtk_i2c_max_step_cnt(target_speed);
 	base_step_cnt = max_step_cnt;
 	/* Find the best combination */
-	opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
+	opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed) +
+		  clock_div_constraint;
 	best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
 
 	/* Search for the best pair (sample_cnt, step_cnt) with
@@ -767,7 +780,8 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	sample_cnt = base_sample_cnt;
 	step_cnt = base_step_cnt;
 
-	if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
+	if ((clk_src / (2 * (sample_cnt * step_cnt - clock_div_constraint))) >
+		 target_speed) {
 		/* In this case, hardware can't support such
 		 * low i2c_bus_freq
 		 */
@@ -854,13 +868,16 @@ static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
 	target_speed = i2c->speed_hz;
 	parent_clk /= i2c->clk_src_div;
 
-	if (i2c->dev_comp->timing_adjust)
-		max_clk_div = MAX_CLOCK_DIV;
+	if (i2c->dev_comp->timing_adjust && i2c->dev_comp->ltiming_adjust)
+		max_clk_div = MAX_CLOCK_DIV_5BITS;
+	else if (i2c->dev_comp->timing_adjust)
+		max_clk_div = MAX_CLOCK_DIV_8BITS;
 	else
 		max_clk_div = 1;
 
 	for (clk_div = 1; clk_div <= max_clk_div; clk_div++) {
 		clk_src = parent_clk / clk_div;
+		i2c->ac_timing.inter_clk_div = clk_div - 1;
 
 		if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) {
 			/* Set master code speed register */
@@ -907,8 +924,6 @@ static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
 		break;
 	}
 
-	i2c->ac_timing.inter_clk_div = clk_div - 1;
-
 	return 0;
 }
 
-- 
1.9.1

From macroalpha82 at gmail.com  Mon Aug 23 21:09:51 2021
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Mon, 23 Aug 2021 23:09:51 -0500
Subject: [PATCH v4 0/4] power: supply: Add Support for RK817 Charger
Message-ID: <20210824040955.29112-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

This series is to add support for the Rockchip rk817 battery charger
which is present in all Rockchip RK817 PMICs. The driver was written
as a joint effort by Maya Matuszczyk <maccraft123mc at gmail.com> and
myself Chris Morgan <macromorgan at hotmail.com>.

The driver requires some basic parameters be described about the
battery in the devicetree such as the maximum capacity, the minimum
and maximum voltage for the battery, the maximum charge current, the
maximum charge voltage, and the value of sample resistors and sleep
currents.

The hardware itself contains an ADC capable of measuring the voltage,
current, and temperature of the battery (though my implementation of an
Odroid Go Advance lacks a thermistor for temperature). It also contains
a columb counter, registers for tracking the measured voltage and
current at boot, and a few bytes of nvram for storing data.

Changes from V3:

 - Corrected issues in device tree documentation.
 - Added additional logic to battery to correct for columb counter
   drift when the device stays plugged in at a full charge state.

Changes from V2:

 - Updated devicetree bindings to use common property units.
 - Removed unneeded includes.
 - Updated rk817_chg_cur_to_reg to make more legible.
 - Simplified formula for displaying calibrated voltage.
 - Updated power supply type to POWER_SUPPLY_TYPE_USB.
 - Implemented get/put_unaligned macros for bulk reads and writes.
 - Changed numerous dev_err() to dev_err_probe().
 - Call power_supply_put_battery_info() at end of probe function.
 - Removed unneeded whitespace.

Changes from V1:

 - Fixed a CLANG warning regarding an uninitalized variable.
 - Fixed a CLANG warning regarding a pointer as a bool value always
   returning as true.
 - Added Maya Matuszczyk to the Signed-off-by.

Chris Morgan (4):
  dt-bindings: Add Rockchip rk817 battery charger support
  mfd: Add Rockchip rk817 battery charger support
  power: supply: Add charger driver for Rockchip RK817
  arm64: dts: rockchip: add rk817 charger to Odroid Go Advance

 .../devicetree/bindings/mfd/rk808.txt         |  38 +
 .../boot/dts/rockchip/rk3326-odroid-go2.dts   |  26 +
 drivers/mfd/rk808.c                           |  16 +-
 drivers/power/supply/Kconfig                  |   6 +
 drivers/power/supply/Makefile                 |   1 +
 drivers/power/supply/rk817_charger.c          | 959 ++++++++++++++++++
 include/linux/mfd/rk808.h                     |  87 ++
 7 files changed, 1132 insertions(+), 1 deletion(-)
 create mode 100644 drivers/power/supply/rk817_charger.c

-- 
2.25.1



From macroalpha82 at gmail.com  Mon Aug 23 21:09:52 2021
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Mon, 23 Aug 2021 23:09:52 -0500
Subject: [PATCH v4 1/4] dt-bindings: Add Rockchip rk817 battery charger support
In-Reply-To: <20210824040955.29112-1-macroalpha82@gmail.com>
References: <20210824040955.29112-1-macroalpha82@gmail.com>
Message-ID: <20210824040955.29112-2-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Create dt-binding documentation to document rk817 battery and charger
usage. New device-tree properties have been added.

- rockchip,resistor-sense-micro-ohms: The value in microohms of the
                                      sample resistor.
- rockchip,sleep-enter-current-microamp: The value in microamps of the
                                         sleep enter current.
- rockchip,sleep-filter-current: The value in microamps of the sleep
                                 filter current.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
---
 .../devicetree/bindings/mfd/rk808.txt         | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
index 23a17a6663ec..6e1b9fb1f64a 100644
--- a/Documentation/devicetree/bindings/mfd/rk808.txt
+++ b/Documentation/devicetree/bindings/mfd/rk808.txt
@@ -77,6 +77,37 @@ Optional RK817 properties:
 - rockchip,mic-in-differential: Telling if the microphone uses differential
 				mode. Should be under the codec child node.
 
+- battery:	The child node for the charger to hold additional properties.
+		If a battery is not in use, this node can be omitted. If a
+		battery node is used, the following values are required in the
+		battery node itself:
+		rockchip,resistor-sense-micro-ohms,
+		rockchip,sleep-enter-current-microamp,
+		rockchip,sleep-filter-current-microamp,
+		Additionally, a phandle to a monitored-battery node that
+		contains the following is also required:
+		charge-full-design-microamp-hours,
+		charge-term-current-microamp,
+		constant-charge-current-max-microamp,
+		constant-charge-voltage-max-microvolt,
+		voltage-max-design-microvolt,
+		voltage-min-design-microvolt,
+		and a valid ocv-capacity table.
+- rockchip,resistor-sense-micro-ohms: Value in microohms of the battery sense
+				      resistor. The PMIC only supports values
+				      of either 10000 or 20000. This value is
+				      used by the driver to set the correct
+				      divisor value to translate ADC readings
+				      into the proper units of measure.
+- rockchip,sleep-enter-current-microamp: Value in microamps of the sleep enter
+					 current for the charger. Value is used
+					 by the driver to calibrate the relax
+					 threshold.
+- rockchip,sleep-filter-current-microamp: Value in microamps of the sleep
+					  filter current for the charger.
+					  Value is used by the driver to derive
+					  the sleep sample current.
+
 Optional RK818 properties:
 - vcc1-supply:  The input supply for DCDC_REG1
 - vcc2-supply:  The input supply for DCDC_REG2
@@ -459,6 +490,13 @@ Example:
 			};
 		};
 
+		rk817_battery: battery {
+			monitored-battery = <&battery_cell>;
+			rockchip,resistor-sense-micro-ohms = <10000>;
+			rockchip,sleep-enter-current-microamp = <300000>;
+			rockchip,sleep-filter-current-microamp = <100000>;
+		};
+
 		rk817_codec: codec {
 			rockchip,mic-in-differential;
 		};
-- 
2.25.1



From macroalpha82 at gmail.com  Mon Aug 23 21:09:53 2021
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Mon, 23 Aug 2021 23:09:53 -0500
Subject: [PATCH v4 2/4] mfd: Add Rockchip rk817 battery charger support
In-Reply-To: <20210824040955.29112-1-macroalpha82@gmail.com>
References: <20210824040955.29112-1-macroalpha82@gmail.com>
Message-ID: <20210824040955.29112-3-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add rk817 charger support cell to rk808 mfd driver.

Acked-for-MFD-by: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
---
 drivers/mfd/rk808.c       | 16 ++++++-
 include/linux/mfd/rk808.h | 87 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 77ccd31ca1d9..edc779aee667 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -66,6 +66,10 @@ static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
 	case RK817_SECONDS_REG ... RK817_WEEKS_REG:
 	case RK817_RTC_STATUS_REG:
 	case RK817_CODEC_DTOP_LPT_SRST:
+	case RK817_GAS_GAUGE_ADC_CONFIG0 ... RK817_GAS_GAUGE_CUR_ADC_K0:
+	case RK817_PMIC_CHRG_STS:
+	case RK817_PMIC_CHRG_OUT:
+	case RK817_PMIC_CHRG_IN:
 	case RK817_INT_STS_REG0:
 	case RK817_INT_STS_REG1:
 	case RK817_INT_STS_REG2:
@@ -73,7 +77,7 @@ static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
 		return true;
 	}
 
-	return true;
+	return false;
 }
 
 static const struct regmap_config rk818_regmap_config = {
@@ -126,6 +130,11 @@ static const struct resource rk817_pwrkey_resources[] = {
 	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
 };
 
+static const struct resource rk817_charger_resources[] = {
+	DEFINE_RES_IRQ(RK817_IRQ_PLUG_IN),
+	DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT),
+};
+
 static const struct mfd_cell rk805s[] = {
 	{ .name = "rk808-clkout", },
 	{ .name = "rk808-regulator", },
@@ -165,6 +174,11 @@ static const struct mfd_cell rk817s[] = {
 		.resources = &rk817_rtc_resources[0],
 	},
 	{ .name = "rk817-codec",},
+	{
+		.name = "rk817-charger",
+		.num_resources = ARRAY_SIZE(rk817_charger_resources),
+		.resources = &rk817_charger_resources[0],
+	},
 };
 
 static const struct mfd_cell rk818s[] = {
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index a96e6d43ca06..1390432c0222 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -518,6 +518,74 @@ enum rk809_reg_id {
 #define MIC_DIFF_DIS			(0x0 << 7)
 #define MIC_DIFF_EN			(0x1 << 7)
 
+/* RK817 Battery Registers */
+#define RK817_GAS_GAUGE_ADC_CONFIG0	0x50
+#define RK817_GG_EN			(0x1 << 7)
+#define RK817_SYS_VOL_ADC_EN		(0x1 << 6)
+#define RK817_TS_ADC_EN			(0x1 << 5)
+#define RK817_USB_VOL_ADC_EN		(0x1 << 4)
+#define RK817_BAT_VOL_ADC_EN		(0x1 << 3)
+#define RK817_BAT_CUR_ADC_EN		(0x1 << 2)
+
+#define RK817_GAS_GAUGE_ADC_CONFIG1	0x55
+
+#define RK817_CUR_CALIB_UPD		(0x1 << 7)
+#define RK817_VOL_CALIB_UPD		(0x1 << 6)
+
+#define RK817_GAS_GAUGE_GG_CON		0x56
+#define RK817_GAS_GAUGE_GG_STS		0x57
+
+#define RK817_RELAX_VOL_UPD		(0x3 << 2)
+#define RK817_RELAX_STS			(0x1 << 1)
+
+#define RK817_GAS_GAUGE_RELAX_THRE_H	0x58
+#define RK817_GAS_GAUGE_RELAX_THRE_L	0x59
+#define RK817_GAS_GAUGE_OCV_THRE_VOL	0x62
+#define RK817_GAS_GAUGE_OCV_VOL_H	0x63
+#define RK817_GAS_GAUGE_OCV_VOL_L	0x64
+#define RK817_GAS_GAUGE_PWRON_VOL_H	0x6b
+#define RK817_GAS_GAUGE_PWRON_VOL_L	0x6c
+#define RK817_GAS_GAUGE_PWRON_CUR_H	0x6d
+#define RK817_GAS_GAUGE_PWRON_CUR_L	0x6e
+#define RK817_GAS_GAUGE_OFF_CNT		0x6f
+#define RK817_GAS_GAUGE_Q_INIT_H3	0x70
+#define RK817_GAS_GAUGE_Q_INIT_H2	0x71
+#define RK817_GAS_GAUGE_Q_INIT_L1	0x72
+#define RK817_GAS_GAUGE_Q_INIT_L0	0x73
+#define RK817_GAS_GAUGE_Q_PRES_H3	0x74
+#define RK817_GAS_GAUGE_Q_PRES_H2	0x75
+#define RK817_GAS_GAUGE_Q_PRES_L1	0x76
+#define RK817_GAS_GAUGE_Q_PRES_L0	0x77
+#define RK817_GAS_GAUGE_BAT_VOL_H	0x78
+#define RK817_GAS_GAUGE_BAT_VOL_L	0x79
+#define RK817_GAS_GAUGE_BAT_CUR_H	0x7a
+#define RK817_GAS_GAUGE_BAT_CUR_L	0x7b
+#define RK817_GAS_GAUGE_USB_VOL_H	0x7e
+#define RK817_GAS_GAUGE_USB_VOL_L	0x7f
+#define RK817_GAS_GAUGE_SYS_VOL_H	0x80
+#define RK817_GAS_GAUGE_SYS_VOL_L	0x81
+#define RK817_GAS_GAUGE_Q_MAX_H3	0x82
+#define RK817_GAS_GAUGE_Q_MAX_H2	0x83
+#define RK817_GAS_GAUGE_Q_MAX_L1	0x84
+#define RK817_GAS_GAUGE_Q_MAX_L0	0x85
+#define RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H	0x8f
+#define RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_L	0x90
+#define RK817_GAS_GAUGE_CAL_OFFSET_H	0x91
+#define RK817_GAS_GAUGE_CAL_OFFSET_L	0x92
+#define RK817_GAS_GAUGE_VCALIB0_H	0x93
+#define RK817_GAS_GAUGE_VCALIB0_L	0x94
+#define RK817_GAS_GAUGE_VCALIB1_H	0x95
+#define RK817_GAS_GAUGE_VCALIB1_L	0x96
+#define RK817_GAS_GAUGE_IOFFSET_H	0x97
+#define RK817_GAS_GAUGE_IOFFSET_L	0x98
+#define RK817_GAS_GAUGE_BAT_R1		0x9a
+#define RK817_GAS_GAUGE_BAT_R2		0x9b
+#define RK817_GAS_GAUGE_BAT_R3		0x9c
+#define RK817_GAS_GAUGE_DATA3		0xa0
+#define RK817_GAS_GAUGE_DATA4		0xa1
+#define RK817_GAS_GAUGE_DATA5		0xa2
+#define RK817_GAS_GAUGE_CUR_ADC_K0	0xb0
+
 #define RK817_POWER_EN_REG(i)		(0xb1 + (i))
 #define RK817_POWER_SLP_EN_REG(i)	(0xb5 + (i))
 
@@ -543,10 +611,29 @@ enum rk809_reg_id {
 #define RK817_LDO_ON_VSEL_REG(idx)	(0xcc + (idx) * 2)
 #define RK817_BOOST_OTG_CFG		(0xde)
 
+#define RK817_PMIC_CHRG_OUT		0xe4
+#define RK817_CHRG_VOL_SEL		(0x07 << 4)
+#define RK817_CHRG_CUR_SEL		(0x07 << 0)
+
+#define RK817_PMIC_CHRG_IN		0xe5
+#define RK817_USB_VLIM_EN		(0x01 << 7)
+#define RK817_USB_VLIM_SEL		(0x07 << 4)
+#define RK817_USB_ILIM_EN		(0x01 << 3)
+#define RK817_USB_ILIM_SEL		(0x07 << 0)
+#define RK817_PMIC_CHRG_TERM		0xe6
+#define RK817_CHRG_TERM_ANA_DIG		(0x01 << 2)
+#define RK817_CHRG_TERM_ANA_SEL		(0x03 << 0)
+#define RK817_CHRG_EN			(0x01 << 6)
+
+#define RK817_PMIC_CHRG_STS		0xeb
+#define RK817_CHG_STS			(0x07 << 4)
+
 #define RK817_ID_MSB			0xed
 #define RK817_ID_LSB			0xee
 
 #define RK817_SYS_STS			0xf0
+#define RK817_PLUG_IN_STS		(0x1 << 6)
+
 #define RK817_SYS_CFG(i)		(0xf1 + (i))
 
 #define RK817_ON_SOURCE_REG		0xf5
-- 
2.25.1



From macroalpha82 at gmail.com  Mon Aug 23 21:09:55 2021
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Mon, 23 Aug 2021 23:09:55 -0500
Subject: [PATCH v4 4/4] arm64: dts: rockchip: add rk817 charger to Odroid Go
 Advance
In-Reply-To: <20210824040955.29112-1-macroalpha82@gmail.com>
References: <20210824040955.29112-1-macroalpha82@gmail.com>
Message-ID: <20210824040955.29112-5-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add the new rk817 charger driver to the Odroid Go Advance. Create a
monitored battery node as well for the charger to use. All values
from monitored battery are gathered from the BSP kernel for the
Odroid Go Advance provided by HardKernel.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
---
 .../boot/dts/rockchip/rk3326-odroid-go2.dts   | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts b/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts
index 7fc674a99a6c..aff8d0768c5a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3326-odroid-go2.dts
@@ -52,6 +52,25 @@ backlight: backlight {
 		pwms = <&pwm1 0 25000 0>;
 	};
 
+	battery_cell: battery-cell {
+		compatible = "simple-battery";
+		charge-full-design-microamp-hours = <3000000>;
+		charge-term-current-microamp = <300000>;
+		constant-charge-current-max-microamp = <2000000>;
+		constant-charge-voltage-max-microvolt = <4200000>;
+		factory-internal-resistance-micro-ohms = <180000>;
+		voltage-max-design-microvolt = <4100000>;
+		voltage-min-design-microvolt = <3500000>;
+
+		ocv-capacity-celsius = <20>;
+		ocv-capacity-table-0 =	<4106000 100>, <4071000 95>, <4018000 90>, <3975000 85>,
+					<3946000 80>, <3908000 75>, <3877000 70>, <3853000 65>,
+					<3834000 60>, <3816000 55>, <3802000 50>, <3788000 45>,
+					<3774000 40>, <3760000 35>, <3748000 30>, <3735000 25>,
+					<3718000 20>, <3697000 15>, <3685000 10>, <3625000 5>,
+					<3500000 0>;
+	};
+
 	gpio-keys {
 		compatible = "gpio-keys";
 		pinctrl-names = "default";
@@ -462,6 +481,13 @@ regulator-state-mem {
 			};
 		};
 
+		rk817_battery: battery {
+			monitored-battery = <&battery_cell>;
+			rockchip,resistor-sense-micro-ohms = <10000>;
+			rockchip,sleep-enter-current-microamp = <300000>;
+			rockchip,sleep-filter-current-microamp = <100000>;
+		};
+
 		rk817_codec: codec {
 			rockchip,mic-in-differential;
 		};
-- 
2.25.1



From macroalpha82 at gmail.com  Mon Aug 23 21:09:54 2021
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Mon, 23 Aug 2021 23:09:54 -0500
Subject: [PATCH v4 3/4] power: supply: Add charger driver for Rockchip RK817
In-Reply-To: <20210824040955.29112-1-macroalpha82@gmail.com>
References: <20210824040955.29112-1-macroalpha82@gmail.com>
Message-ID: <20210824040955.29112-4-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the Rockchip rk817 battery charger integrated into the
rk817 PMIC.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
Signed-off-by: Maya Matuszczyk <maccraft123mc at gmail.com>
---
 drivers/power/supply/Kconfig         |   6 +
 drivers/power/supply/Makefile        |   1 +
 drivers/power/supply/rk817_charger.c | 959 +++++++++++++++++++++++++++
 3 files changed, 966 insertions(+)
 create mode 100644 drivers/power/supply/rk817_charger.c

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 11f5368e810e..311130da36ff 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -666,6 +666,12 @@ config CHARGER_BQ256XX
 	  charge management and system power path management devices for single
 	  cell Li-ion and Li-polymer batteries.
 
+config CHARGER_RK817
+	tristate "Rockchip RK817 PMIC Battery Charger"
+	depends on MFD_RK808
+	help
+	  Say Y to include support for Rockchip RK817 Battery Charger.
+
 config CHARGER_SMB347
 	tristate "Summit Microelectronics SMB3XX Battery Charger"
 	depends on I2C
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 33059a91f60c..9497d2105712 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_CHARGER_BQ2515X)	+= bq2515x_charger.o
 obj-$(CONFIG_CHARGER_BQ25890)	+= bq25890_charger.o
 obj-$(CONFIG_CHARGER_BQ25980)	+= bq25980_charger.o
 obj-$(CONFIG_CHARGER_BQ256XX)	+= bq256xx_charger.o
+obj-$(CONFIG_CHARGER_RK817)	+= rk817_charger.o
 obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
 obj-$(CONFIG_CHARGER_TPS65090)	+= tps65090-charger.o
 obj-$(CONFIG_CHARGER_TPS65217)	+= tps65217_charger.o
diff --git a/drivers/power/supply/rk817_charger.c b/drivers/power/supply/rk817_charger.c
new file mode 100644
index 000000000000..34338aebe269
--- /dev/null
+++ b/drivers/power/supply/rk817_charger.c
@@ -0,0 +1,959 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Charger Driver for Rockchip rk817
+ *
+ * Copyright (c) 2021
+ *
+ * Authors: Maya Matuszczyk <maccraft123mc at gmail.com>
+ *	    Chris Morgan <macromorgan at hotmail.com>
+ */
+
+#include <linux/mfd/rk808.h>
+#include <linux/irq.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/power_supply.h>
+#include <asm/unaligned.h>
+
+/* Charging statuses reported by hardware register */
+enum rk817_charge_status {
+	CHRG_OFF,
+	DEAD_CHRG,
+	TRICKLE_CHRG,
+	CC_OR_CV_CHRG,
+	CHARGE_FINISH,
+	USB_OVER_VOL,
+	BAT_TMP_ERR,
+	BAT_TIM_ERR,
+};
+
+/* Max charging current read to/written from hardware register.
+ * Note how highest value corresponding to 0x7 is the lowest
+ * current, this is per the datasheet.
+ */
+enum rk817_chg_cur {
+	CHG_1A,
+	CHG_1_5A,
+	CHG_2A,
+	CHG_2_5A,
+	CHG_2_75A,
+	CHG_3A,
+	CHG_3_5A,
+	CHG_0_5A,
+};
+
+struct rk817_charger {
+	struct device *dev;
+	struct rk808 *rk808;
+
+	struct power_supply *bat_ps;
+	struct power_supply *chg_ps;
+	bool plugged_in;
+
+	/* The voltage_k and voltage_b values are used to calibrate the ADC
+	 * voltage readings. While they are documented in the BSP kernel and
+	 * datasheet as voltage_k and voltage_b, there is no further
+	 * information explaining them in more detail.
+	 */
+
+	uint32_t voltage_k;
+	uint32_t voltage_b;
+
+	/* Storing immutable values of battery here so we can release
+	 * get_battery_info after the probe and use these values.
+	 */
+	int bat_charge_full_design_uah;
+	int bat_voltage_min_design_uv;
+	int bat_voltage_max_design_uv;
+
+	/* dsoc seems to be difference between full charge and actual charge in
+	 * BSP stored as a percentage, to the thousandth.
+	 */
+	int dsoc;
+
+	/* Calibrate the DSOC on a fully charged battery, this way we can use
+	 * the calibrated DSOC value to correct for columb counter drift.
+	 */
+	bool dsoc_cal;
+
+	/* Implementation specific properties from device tree */
+	int res_div;
+	int sleep_enter_current;
+	int sleep_filter_current;
+};
+
+/* ADC coefficients extracted from BSP kernel */
+#define ADC_TO_CURRENT(adc_value, res_div)	\
+	(adc_value * 172 / res_div)
+
+#define CURRENT_TO_ADC(current, samp_res)	\
+	(current * samp_res / 172)
+
+#define CHARGE_TO_ADC(capacity, res_div)	\
+	(capacity * res_div * 3600 / 172 * 1000)
+
+#define ADC_TO_CHARGE_UAH(adc_value, res_div)	\
+	(adc_value / 3600 * 172 / res_div)
+
+#define ADC_TO_CAPACITY(adc_value, res_div)	\
+	(adc_value / 1000 * 172 / 3600 / res_div)
+
+static u8 rk817_chg_cur_to_reg(u32 chg_cur_ma)
+{
+	if (chg_cur_ma > 3500)
+		return CHG_3_5A;
+	else if (chg_cur_ma > 3000)
+		return CHG_3A;
+	else if (chg_cur_ma > 2750)
+		return CHG_2_75A;
+	else if (chg_cur_ma > 2500)
+		return CHG_2_5A;
+	else if (chg_cur_ma > 2000)
+		return CHG_2A;
+	else if (chg_cur_ma > 1500)
+		return CHG_1_5A;
+	else if (chg_cur_ma > 1000)
+		return CHG_1A;
+	else if (chg_cur_ma > 500)
+		return CHG_0_5A;
+	else
+		return -EINVAL;
+}
+
+static int rk817_chg_cur_from_reg(u8 reg)
+{
+	switch (reg) {
+	case CHG_0_5A:
+		return 500000;
+	case CHG_1A:
+		return 1000000;
+	case CHG_1_5A:
+		return 1500000;
+	case CHG_2A:
+		return 2000000;
+	case CHG_2_5A:
+		return 2500000;
+	case CHG_2_75A:
+		return 2750000;
+	case CHG_3A:
+		return 3000000;
+	case CHG_3_5A:
+		return 3500000;
+	default:
+		return -EINVAL;
+	}
+}
+
+static void rk817_bat_calib_vol(struct rk817_charger *charger)
+{
+	uint32_t vcalib0 = 0;
+	uint32_t vcalib1 = 0;
+	u8 bulk_reg[2];
+
+	/* calibrate voltage */
+	regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_VCALIB0_H,
+			 bulk_reg, 2);
+	vcalib0 = get_unaligned_be16(bulk_reg);
+
+	regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_VCALIB1_H,
+			 bulk_reg, 2);
+	vcalib1 = get_unaligned_be16(bulk_reg);
+
+	/* values were taken from BSP kernel */
+	charger->voltage_k = (4025 - 2300) * 1000 /
+			     ((vcalib1 - vcalib0) ? (vcalib1 - vcalib0) : 1);
+	charger->voltage_b = 4025 - (charger->voltage_k * vcalib1) / 1000;
+}
+
+static void rk817_bat_calib_cur(struct rk817_charger *charger)
+{
+	u8 bulk_reg[2];
+
+	/* calibrate current */
+	regmap_bulk_read(charger->rk808->regmap, RK817_GAS_GAUGE_IOFFSET_H,
+			 bulk_reg, 2);
+	regmap_bulk_write(charger->rk808->regmap, RK817_GAS_GAUGE_CAL_OFFSET_H,
+			  bulk_reg, 2);
+}
+
+static int rk817_bat_calib_cap(struct rk817_charger *charger)
+{
+	struct rk808 *rk808 = charger->rk808;
+	int reg, tmp, charge_now, charge_now_adc, dsoc_value;
+	u8 bulk_reg[4];
+
+	/* Calibrate the dsoc on a fully charged battery */
+
+	regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
+	tmp = (reg >> 4) & 0x07;
+	if (tmp == CHARGE_FINISH) {
+		/* Read the columb counter */
+		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
+				 bulk_reg, 4);
+		charge_now_adc = get_unaligned_be32(bulk_reg);
+		if (charge_now_adc < 0)
+			charge_now_adc = 0;
+		charge_now = ADC_TO_CHARGE_UAH(charge_now_adc, charger->res_div);
+
+		/* Get and set our DSOC value with a full charge */
+
+		dsoc_value = ((charge_now * 100) /
+			      (charger->bat_charge_full_design_uah / 1000));
+
+		if (!charger->dsoc_cal) {
+			if (dsoc_value > 100000)
+				charger->dsoc = 100000;
+			if (dsoc_value != charger->dsoc) {
+				charger->dsoc = dsoc_value;
+				put_unaligned_le24(dsoc_value, bulk_reg);
+				regmap_bulk_write(rk808->regmap,
+						  RK817_GAS_GAUGE_BAT_R1,
+						  bulk_reg, 3);
+			}
+			/* Mark our dsoc as calibrated. */
+			charger->dsoc_cal = 1;
+		}
+
+		/* In the event our columb counter has drifted over the
+		 * calibrated dsoc of the battery, adjust the columb counter
+		 * to correct the drift. Don't do this unless we already
+		 * calibrated our dsoc at a fully charged state.
+		 */
+
+		if (dsoc_value > charger->dsoc && charger->dsoc_cal) {
+			/* Order of operations matters here to ensure we keep
+			 * enough precision until the last step to keep from
+			 * making needless updates to columb counter.
+			 */
+			charge_now = charger->dsoc *
+				     (charger->bat_charge_full_design_uah
+				     / 1000) / 100;
+			charge_now_adc = CHARGE_TO_ADC((charge_now / 1000),
+					 charger->res_div);
+
+			put_unaligned_be32(charge_now_adc, bulk_reg);
+			regmap_bulk_write(rk808->regmap,
+					  RK817_GAS_GAUGE_Q_INIT_H3,
+					  bulk_reg, 4);
+		}
+	}
+
+	return 0;
+}
+
+static int rk817_bat_get_prop(struct power_supply *ps,
+		enum power_supply_property prop,
+		union power_supply_propval *val)
+{
+	struct rk817_charger *charger = power_supply_get_drvdata(ps);
+	uint32_t tmp = 0;
+	/* Registers for current is a signed 16bit int */
+	short int cur = 0;
+	/* Registers for capacity-now is a signed 32bit int */
+	int32_t charge_now = 0;
+	int ret = 0;
+	int reg = 0;
+	u8 bulk_reg[4];
+	struct rk808 *rk808 = charger->rk808;
+
+	/* Recalibrate voltage and current readings if we need to BSP does both
+	 * on CUR_CALIB_UPD, ignoring VOL_CALIB_UPD. Curiously enough, both
+	 * documentation and the BSP show that you perform an update if bit 7
+	 * is 1, but you clear the status by writing a 1 to bit 7.
+	 */
+	regmap_read(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1, &reg);
+	tmp = (reg >> 7) & 0x01;
+	if (tmp) {
+		rk817_bat_calib_cur(charger);
+		rk817_bat_calib_vol(charger);
+		regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG1,
+				   RK817_CUR_CALIB_UPD, (1 << 7));
+	}
+
+	rk817_bat_calib_cap(charger);
+
+	switch (prop) {
+	case POWER_SUPPLY_PROP_PRESENT:
+		regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
+		val->intval = (reg >> 7);
+		break;
+	case POWER_SUPPLY_PROP_STATUS:
+		if (!charger->plugged_in) {
+			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+			break;
+		}
+		ret = regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
+		if (ret)
+			return ret;
+		tmp = (reg >> 4) & 0x07;
+		switch (tmp) {
+		case CHRG_OFF:
+			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+			break;
+		/* Dead charge is documented, but not explained. I never
+		 * observed it but assume it's a pre-charge for a dead
+		 * battery.
+		 */
+		case DEAD_CHRG:
+		case TRICKLE_CHRG:
+		case CC_OR_CV_CHRG:
+			val->intval = POWER_SUPPLY_STATUS_CHARGING;
+			break;
+		case CHARGE_FINISH:
+			val->intval = POWER_SUPPLY_STATUS_FULL;
+			break;
+		default:
+			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+			return -EINVAL;
+
+		}
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_TYPE:
+		ret = regmap_read(rk808->regmap, RK817_PMIC_CHRG_STS, &reg);
+		if (ret)
+			return ret;
+		tmp = (reg >> 4) & 0x07;
+		switch (tmp) {
+		case CHRG_OFF:
+		case CHARGE_FINISH:
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
+			break;
+		case TRICKLE_CHRG:
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+			break;
+		case DEAD_CHRG:
+		case CC_OR_CV_CHRG:
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
+			break;
+		default:
+			val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+			break;
+		}
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL:
+		val->intval = ((charger->bat_charge_full_design_uah /
+			       1000) * charger->dsoc) / 100;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+		val->intval = charger->bat_charge_full_design_uah;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
+		val->intval = 0;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_NOW:
+		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_Q_PRES_H3,
+				 bulk_reg, 4);
+		charge_now = get_unaligned_be32(bulk_reg);
+		if (charge_now < 0)
+			charge_now = 0;
+		val->intval = ADC_TO_CHARGE_UAH(charge_now, charger->res_div);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		val->intval = charger->bat_voltage_min_design_uv;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_BOOT:
+		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_PWRON_VOL_H,
+				 bulk_reg, 2);
+		tmp = get_unaligned_be16(bulk_reg);
+		val->intval = (charger->voltage_k * tmp) +
+			       1000 * charger->voltage_b;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_BAT_VOL_H,
+				 bulk_reg, 2);
+		tmp = get_unaligned_be16(bulk_reg);
+		val->intval = (charger->voltage_k * tmp) +
+			       1000 * charger->voltage_b;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_OCV:
+		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_OCV_VOL_H,
+				 bulk_reg, 2);
+		tmp = get_unaligned_be16(bulk_reg);
+		val->intval = (charger->voltage_k * tmp) +
+			       1000 * charger->voltage_b;
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_BOOT:
+		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_PWRON_CUR_H,
+				 bulk_reg, 2);
+		cur = get_unaligned_be16(bulk_reg);
+		val->intval = ADC_TO_CURRENT(cur, charger->res_div);
+		break;
+	case POWER_SUPPLY_PROP_CURRENT_AVG:
+		regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_BAT_CUR_H,
+				 bulk_reg, 2);
+		cur = get_unaligned_be16(bulk_reg);
+		val->intval = ADC_TO_CURRENT(cur, charger->res_div);
+		break;
+	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
+		regmap_read(rk808->regmap, RK817_PMIC_CHRG_OUT, &tmp);
+		val->intval = rk817_chg_cur_from_reg(tmp & RK817_CHRG_CUR_SEL);
+		break;
+	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
+		regmap_read(rk808->regmap, RK817_PMIC_CHRG_OUT, &tmp);
+		val->intval = ((((tmp & RK817_CHRG_VOL_SEL) >> 4) * 50000) +
+			       4100000);
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+		val->intval = charger->bat_voltage_max_design_uv;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int rk817_chg_get_prop(struct power_supply *ps,
+			      enum power_supply_property prop,
+			      union power_supply_propval *val)
+{
+	struct rk817_charger *charger = power_supply_get_drvdata(ps);
+	int vol, tmp = 0;
+	u8 bulk_reg[2];
+
+	switch (prop) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = charger->plugged_in;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+		/* max voltage from datasheet at 5.5v (default 5.0v) */
+		val->intval = 5500000;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+		/* min voltage from datasheet at 3.8v (default 5.0v) */
+		val->intval = 3800000;
+		break;
+	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+		/* Note that on my example hardware (an Odroid Go Advance) the
+		 * voltage of the power connector is measured on the register
+		 * labelled USB in the datasheet; I don't know if this is how
+		 * it is designed or just a quirk of the implementation. I
+		 * believe this will also measure the voltage of the USB output
+		 * when in OTG mode, if that is the case we may need to change
+		 * this in the future to return 0 if the power supply status
+		 * is offline.
+		 */
+		regmap_bulk_read(charger->rk808->regmap,
+				 RK817_GAS_GAUGE_USB_VOL_H,
+				 bulk_reg, 2);
+		tmp = get_unaligned_be16(bulk_reg);
+		vol = ((charger->voltage_k * tmp / 1000 + charger->voltage_b) *
+		       60 / 46);
+		val->intval = vol * 1000;
+		break;
+	/* While it's possible that other implementations could use different
+	 * USB types, the current implementation for this PMIC (the Odroid Go
+	 * Advance) only uses a dedicated charging port with no rx/tx lines.
+	 */
+	case POWER_SUPPLY_PROP_USB_TYPE:
+		val->intval = POWER_SUPPLY_USB_TYPE_DCP;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+
+}
+
+static irqreturn_t rk817_plug_in_isr(int irq, void *cg)
+{
+	struct rk817_charger *charger;
+
+	charger = (struct rk817_charger *)cg;
+	charger->plugged_in = 1;
+	power_supply_changed(charger->chg_ps);
+	power_supply_changed(charger->bat_ps);
+	dev_dbg(charger->dev, "Power Cord Inserted\n");
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t rk817_plug_out_isr(int irq, void *cg)
+{
+	struct rk817_charger *charger;
+	struct rk808 *rk808;
+
+	charger = (struct rk817_charger *)cg;
+	rk808 = charger->rk808;
+	charger->plugged_in = 0;
+	power_supply_changed(charger->bat_ps);
+	power_supply_changed(charger->chg_ps);
+
+	/* For some reason the bits of RK817_PMIC_CHRG_IN reset whenever the
+	 * power cord is unplugged. This was not documented in the BSP kernel
+	 * or the datasheet and only discovered by trial and error. Set minimum
+	 * USB input voltage to 4.5v and enable USB voltage input limit.
+	 */
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
+			  RK817_USB_VLIM_SEL, (0x05 << 4));
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN,
+			  (0x01 << 7));
+
+	/* Set average USB input current limit to 1.5A and enable USB current
+	 * input limit.
+	 */
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
+			  RK817_USB_ILIM_SEL, 0x03);
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN,
+			  (0x01 << 3));
+
+	dev_dbg(charger->dev, "Power Cord Removed\n");
+
+	return IRQ_HANDLED;
+}
+
+static enum power_supply_property rk817_bat_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_CHARGE_TYPE,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
+	POWER_SUPPLY_PROP_VOLTAGE_BOOT,
+	POWER_SUPPLY_PROP_VOLTAGE_AVG,
+	POWER_SUPPLY_PROP_VOLTAGE_OCV,
+	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+	POWER_SUPPLY_PROP_CURRENT_BOOT,
+	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+};
+
+static enum power_supply_property rk817_chg_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_USB_TYPE,
+	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+	POWER_SUPPLY_PROP_VOLTAGE_AVG,
+};
+
+static enum power_supply_usb_type rk817_usb_type[] = {
+	POWER_SUPPLY_USB_TYPE_DCP,
+	POWER_SUPPLY_USB_TYPE_UNKNOWN,
+};
+
+static const struct power_supply_desc rk817_bat_desc = {
+	.name = "rk817-battery",
+	.type = POWER_SUPPLY_TYPE_BATTERY,
+	.properties = rk817_bat_props,
+	.num_properties = ARRAY_SIZE(rk817_bat_props),
+	.get_property = rk817_bat_get_prop,
+};
+
+static const struct power_supply_desc rk817_chg_desc = {
+	.name = "rk817-charger",
+	.type = POWER_SUPPLY_TYPE_USB,
+	.usb_types = rk817_usb_type,
+	.num_usb_types = ARRAY_SIZE(rk817_usb_type),
+	.properties = rk817_chg_props,
+	.num_properties = ARRAY_SIZE(rk817_chg_props),
+	.get_property = rk817_chg_get_prop,
+};
+
+static int
+rk817_read_or_set_full_charge_on_boot(struct rk817_charger *charger,
+				      struct power_supply_battery_info *bat_info)
+{
+	struct rk808 *rk808 = charger->rk808;
+	u8 bulk_reg[4];
+	u32 design_charge_mah = (charger->bat_charge_full_design_uah / 1000);
+	u32 boot_voltage, boot_charge, tmp, full_charge_cap;
+	int ret, boot_capacity;
+
+	/* Read DSOC value if pre-existing. If not, initialize at 100%.
+	 * Note endianness, also register says it's for resistance,
+	 * however BSP kernel treats this as an nvram field for the DSOC
+	 * as best I can tell. Doing the same for backwards compatibility.
+	 */
+	ret = regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_BAT_R1, bulk_reg, 3);
+	if (ret < 0)
+		return ret;
+	charger->dsoc = get_unaligned_le24(bulk_reg);
+	/* If we have an invalid DSOC, write 100 (100000) as default. */
+	if (charger->dsoc < 1000 || charger->dsoc > 100000) {
+		charger->dsoc = 100000;
+		put_unaligned_le24(charger->dsoc, bulk_reg);
+		regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_BAT_R1,
+				  bulk_reg, 3);
+	}
+
+	/* Register appears to be nvram that stores capacity in mAH. Note
+	 * endianness, keeping consistent with BSP kernel, however it looks
+	 * like we can use any arbitrary method to store value if we don't care
+	 * about compatibility. Additionally, it doesn't appear that this value
+	 * is used for anything, so realistically getting it and setting it is
+	 * to ensure backward compatibility with BSP and serves no purpose with
+	 * this driver, and I'm not sure if the BSP driver does anything with
+	 * this value either.
+	 */
+
+	ret = regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_DATA3, bulk_reg, 3);
+	if (ret < 0)
+		return ret;
+
+	full_charge_cap = get_unaligned_le24(bulk_reg);
+
+	/* Sanity checking for values equal to zero or less than would be
+	 * practical for this device (BSP Kernel assumes 500mAH or less) for
+	 * practicality purposes.
+	 */
+	if (full_charge_cap < 500) {
+		put_unaligned_le24(design_charge_mah, bulk_reg);
+		ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_DATA3, bulk_reg, 3);
+		if (ret < 0)
+			return ret;
+		dev_info(charger->dev,
+			 "Invalid NVRAM Data for max charge, setting to design capacity %u uAH\n",
+			 design_charge_mah*1000);
+	}
+
+	/* Capture boot voltage and look up boot capacity from OCV tables. */
+
+	regmap_bulk_read(rk808->regmap, RK817_GAS_GAUGE_PWRON_VOL_H,
+			 bulk_reg, 2);
+	tmp = get_unaligned_be16(bulk_reg);
+	boot_voltage = (charger->voltage_k * tmp) + 1000 * charger->voltage_b;
+	/* Since only implementation has no working thermistor, assume 20C for
+	 * OCV lookup. If lookup fails, report error with OCV table.
+	 */
+	boot_capacity = power_supply_batinfo_ocv2cap(bat_info, boot_voltage, 20);
+	if (boot_capacity < 0) {
+		return dev_err_probe(charger->dev,
+				     boot_capacity,
+				     "Unable to read boot charge from OCV table: %i\n",
+				     boot_capacity);
+	}
+
+	/* Write boot charge to registers, estimate boot charge based on
+	 * capacity and max charge of battery.
+	 */
+	boot_charge = (boot_capacity * charger->bat_charge_full_design_uah) / 100;
+	tmp = CHARGE_TO_ADC((boot_charge / 1000), charger->res_div);
+	put_unaligned_be32(tmp, bulk_reg);
+	regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_INIT_H3,
+			  bulk_reg, 4);
+
+	/* Set QMAX value to max design capacity. */
+	tmp = CHARGE_TO_ADC((charger->bat_charge_full_design_uah / 1000),
+			    charger->res_div);
+	put_unaligned_be32(tmp, bulk_reg);
+	ret = regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_Q_MAX_H3,
+				bulk_reg, 4);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int rk817_battery_init(struct rk817_charger *charger,
+			      struct power_supply_battery_info *bat_info)
+{
+	struct rk808 *rk808 = charger->rk808;
+	u32 tmp, max_chg_vol_mv, max_chg_cur_ma;
+	u8 max_chg_vol_reg, chg_term_i_reg, max_chg_cur_reg;
+	int ret, chg_term_ma;
+	u8 bulk_reg[2];
+
+	/* Get initial plug state */
+	regmap_read(rk808->regmap, RK817_SYS_STS, &tmp);
+	charger->plugged_in = (tmp & RK817_PLUG_IN_STS);
+
+	/* Turn on all ADC functions to measure battery, USB, and sys voltage,
+	 * as well as batt temp. Note only tested implementation so far does
+	 * not use a battery with a thermistor.
+	 */
+	regmap_write(rk808->regmap, RK817_GAS_GAUGE_ADC_CONFIG0, 0xfc);
+
+	/* Set relax mode voltage sampling interval and ADC offset calibration
+	 * interval to 8 minutes to mirror BSP kernel. Set voltage and current
+	 * modes to average to mirror BSP kernel.
+	 */
+	regmap_write(rk808->regmap, RK817_GAS_GAUGE_GG_CON, 0x04);
+
+	/* Write relax threshold, derived from sleep enter current. */
+	tmp = CURRENT_TO_ADC(charger->sleep_enter_current, charger->res_div);
+	put_unaligned_be16(tmp, bulk_reg);
+	regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_RELAX_THRE_H,
+			  bulk_reg, 2);
+
+	/* Write sleep sample current, derived from sleep filter current. */
+	tmp = CURRENT_TO_ADC(charger->sleep_filter_current, charger->res_div);
+	put_unaligned_be16(tmp, bulk_reg);
+	regmap_bulk_write(rk808->regmap, RK817_GAS_GAUGE_SLEEP_CON_SAMP_CUR_H,
+			  bulk_reg, 2);
+
+	/* Restart battery relax voltage */
+	regmap_write_bits(rk808->regmap, RK817_GAS_GAUGE_GG_STS,
+			  RK817_RELAX_VOL_UPD, (0x0 << 2));
+
+	/* Set OCV Threshold Voltage to 127.5mV. This was hard coded like this
+	 * in the BSP.
+	 */
+	regmap_write(rk808->regmap, RK817_GAS_GAUGE_OCV_THRE_VOL, 0xff);
+
+	/* Set maximum charging voltage to battery max voltage. Trying to be
+	 * incredibly safe with these value, as setting them wrong could
+	 * overcharge the battery, which would be very bad.
+	 */
+	max_chg_vol_mv = bat_info->constant_charge_voltage_max_uv / 1000;
+	max_chg_cur_ma = bat_info->constant_charge_current_max_ua / 1000;
+
+	if (max_chg_vol_mv < 4100) {
+		return dev_err_probe(charger->dev, -EINVAL,
+		       "invalid max charger voltage, value %u unsupported\n",
+			max_chg_vol_mv * 1000);
+	}
+	if (max_chg_vol_mv > 4450) {
+		dev_info(charger->dev,
+			 "Setting max charge voltage to 4450000uv\n");
+		max_chg_vol_mv = 4450;
+	}
+
+	if (max_chg_cur_ma < 500) {
+		return dev_err_probe(charger->dev, -EINVAL,
+		       "invalid max charger current, value %u unsupported\n",
+		       max_chg_cur_ma * 1000);
+	}
+	if (max_chg_cur_ma > 3500)
+		dev_info(charger->dev,
+			 "Setting max charge current to 3500000ua\n");
+
+	/* Now that the values are sanity checked, if we subtract 4100 from the
+	 * max voltage and divide by 50, we conviently get the exact value for
+	 * the registers, which are 4.1v, 4.15v, 4.2v, 4.25v, 4.3v, 4.35v,
+	 * 4.4v, and 4.45v; these correspond to values 0x00 through 0x07.
+	 */
+	max_chg_vol_reg = (max_chg_vol_mv - 4100) / 50;
+
+	max_chg_cur_reg = rk817_chg_cur_to_reg(max_chg_cur_ma);
+
+	if (max_chg_vol_reg < 0 || max_chg_vol_reg > 7) {
+		return dev_err_probe(charger->dev, -EINVAL,
+		       "invalid max charger voltage, value %u unsupported\n",
+		       max_chg_vol_mv * 1000);
+	}
+	if (max_chg_cur_reg < 0 || max_chg_cur_reg > 7) {
+		return dev_err_probe(charger->dev, -EINVAL,
+		       "invalid max charger current, value %u unsupported\n",
+		       max_chg_cur_ma * 1000);
+	}
+
+	/* Write the values to the registers, and deliver an emergency warning
+	 * in the event they are not written correctly.
+	 */
+	ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT,
+				RK817_CHRG_VOL_SEL, (max_chg_vol_reg << 4));
+	if (ret) {
+		dev_emerg(charger->dev,
+			  "Danger, unable to set max charger voltage: %u\n",
+			  ret);
+	}
+
+	ret = regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_OUT,
+				RK817_CHRG_CUR_SEL, max_chg_cur_reg);
+	if (ret) {
+		dev_emerg(charger->dev,
+			  "Danger, unable to set max charger current: %u\n",
+			  ret);
+	}
+
+	/* Set charge finishing mode to analog */
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM,
+			  RK817_CHRG_TERM_ANA_DIG, (0x0 << 2));
+
+	/* Set charge finish current, warn if value not in range and keep
+	 * default.
+	 */
+	chg_term_ma = bat_info->charge_term_current_ua / 1000;
+	if (chg_term_ma < 150 || chg_term_ma > 400) {
+		dev_warn(charger->dev,
+			 "Invalid charge termination value %u, keeping default\n",
+			 chg_term_ma * 1000);
+		chg_term_ma = 200;
+	}
+
+	/* Values of 150ma, 200ma, 300ma, and 400ma correspond to 00, 01, 10,
+	 * and 11.
+	 */
+	chg_term_i_reg = (chg_term_ma - 100) / 100;
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_TERM,
+			  RK817_CHRG_TERM_ANA_SEL, chg_term_i_reg);
+
+	ret = rk817_read_or_set_full_charge_on_boot(charger, bat_info);
+	if (ret < 0)
+		return ret;
+
+	/* Set minimum USB input voltage to 4.5v and enable USB voltage input
+	 * limit.
+	 */
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
+			  RK817_USB_VLIM_SEL, (0x05 << 4));
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN,
+			  (0x01 << 7));
+
+	/* Set average USB input current limit to 1.5A and enable USB current
+	 * input limit.
+	 */
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
+			  RK817_USB_ILIM_SEL, 0x03);
+	regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN,
+			  (0x01 << 3));
+
+	return 0;
+}
+
+static int rk817_charger_probe(struct platform_device *pdev)
+{
+	struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
+	struct rk817_charger *charger;
+	struct device_node *node;
+	struct power_supply_battery_info bat_info = { };
+	struct device *dev = &pdev->dev;
+	struct power_supply_config pscfg = {};
+	int plugin_irq, plugout_irq;
+	int of_value;
+	int ret;
+
+	node = of_get_child_by_name(dev->parent->of_node, "battery");
+	if (!node)
+		return -ENODEV;
+
+	charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
+	if (!charger)
+		return -ENOMEM;
+
+	charger->rk808 = rk808;
+
+	charger->dev = &pdev->dev;
+	platform_set_drvdata(pdev, charger);
+
+	rk817_bat_calib_vol(charger);
+
+	pscfg.drv_data = charger;
+	pscfg.of_node = node;
+
+	/* Get sample resistor value. Note only values of 10000 or 20000
+	 * microohms are allowed. Schematic for my test implementation (an
+	 * Odroid Go Advance) shows a 10 milliohm resistor for reference.
+	 */
+	ret = of_property_read_u32(node, "rockchip,resistor-sense-micro-ohms",
+				   &of_value);
+	if (ret < 0) {
+		return dev_err_probe(dev, ret,
+				     "Error reading sample resistor value\n");
+	}
+	/* Store as a 1 or a 2, since all we really use the value for is as a
+	 * divisor in some calculations.
+	 */
+	charger->res_div = (of_value == 20000) ? 2 : 1;
+
+	/* Get sleep enter current value. Not sure what this value is for
+	 * other than to help calibrate the relax threshold.
+	 */
+	ret = of_property_read_u32(node,
+				   "rockchip,sleep-enter-current-microamp",
+				   &of_value);
+	if (ret < 0) {
+		return dev_err_probe(dev, ret,
+				     "Error reading sleep enter cur value\n");
+	}
+	charger->sleep_enter_current = of_value;
+
+	/* Get sleep filter current value */
+	ret = of_property_read_u32(node,
+				   "rockchip,sleep-filter-current-microamp",
+				   &of_value);
+	if (ret < 0) {
+		return dev_err_probe(dev, ret,
+				     "Error reading sleep filter cur value\n");
+	}
+
+	charger->sleep_filter_current = of_value;
+
+	charger->bat_ps = devm_power_supply_register(&pdev->dev,
+						     &rk817_bat_desc, &pscfg);
+
+	charger->chg_ps = devm_power_supply_register(&pdev->dev,
+						     &rk817_chg_desc, &pscfg);
+
+	if (IS_ERR(charger->chg_ps))
+		return dev_err_probe(dev, -EINVAL,
+				     "Battery failed to probe\n");
+
+	if (IS_ERR(charger->chg_ps))
+		return dev_err_probe(dev, -EINVAL,
+				     "Charger failed to probe\n");
+
+	ret = power_supply_get_battery_info(charger->bat_ps,
+					    &bat_info);
+	if (ret) {
+		return dev_err_probe(dev, ret,
+				     "Unable to get battery info: %d\n", ret);
+	}
+
+	if ((!bat_info.charge_full_design_uah) ||
+	    (!bat_info.voltage_min_design_uv) ||
+	    (!bat_info.voltage_max_design_uv) ||
+	    (!bat_info.constant_charge_voltage_max_uv) ||
+	    (!bat_info.constant_charge_current_max_ua) ||
+	    (!bat_info.charge_term_current_ua)) {
+		return dev_err_probe(dev, -EINVAL,
+				     "Required battery info missing.\n");
+	}
+
+	charger->bat_charge_full_design_uah = bat_info.charge_full_design_uah;
+	charger->bat_voltage_min_design_uv = bat_info.voltage_min_design_uv;
+	charger->bat_voltage_max_design_uv = bat_info.voltage_max_design_uv;
+
+	/* Has to run after power_supply_get_battery_info as it depends on some
+	 * values discovered from that routine.
+	 */
+	ret = rk817_battery_init(charger, &bat_info);
+	if (ret)
+		return ret;
+
+	power_supply_put_battery_info(charger->bat_ps, &bat_info);
+
+	plugin_irq = platform_get_irq(pdev, 0);
+	if (plugin_irq < 0)
+		return plugin_irq;
+
+	plugout_irq = platform_get_irq(pdev, 1);
+	if (plugout_irq < 0)
+		return plugout_irq;
+
+	ret = devm_request_threaded_irq(charger->dev, plugin_irq, NULL,
+					rk817_plug_in_isr,
+					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					"rk817_plug_in", charger);
+	if (ret) {
+		return dev_err_probe(&pdev->dev, ret,
+				      "plug_in_irq request failed!\n");
+	}
+
+	ret = devm_request_threaded_irq(charger->dev, plugout_irq, NULL,
+					rk817_plug_out_isr,
+					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					"rk817_plug_out", charger);
+	if (ret) {
+		return dev_err_probe(&pdev->dev, ret,
+				     "plug_out_irq request failed!\n");
+	}
+
+	return 0;
+}
+
+
+static struct platform_driver rk817_charger_driver = {
+	.probe    = rk817_charger_probe,
+	.driver   = {
+		.name  = "rk817-charger",
+	},
+};
+module_platform_driver(rk817_charger_driver);
+
+MODULE_DESCRIPTION("Battery power supply driver for RK817 PMIC");
+MODULE_AUTHOR("Maya Matuszczyk <maccraft123mc at gmail.com>");
+MODULE_LICENSE("GPL");
-- 
2.25.1



From cgel.zte at gmail.com  Mon Aug 23 21:11:12 2021
From: cgel.zte at gmail.com (CGEL)
Date: Mon, 23 Aug 2021 21:11:12 -0700
Subject: [PATCH linux-next] arm:nommu: fix boolreturn.cocci warnings
Message-ID: <20210824041112.57915-1-deng.changcheng@zte.com.cn>

From: Jing Yangyang <jing.yangyang at zte.com.cn>

./arch/arm/mm/nommu.c:59:8-9:WARNING:return of 0/1 in function
'security_extensions_enabled' with return type bool

Return statements in functions returning bool should use true/false
instead of 1/0.

Generated by: scripts/coccinelle/misc/boolreturn.cocci

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Jing Yangyang <jing.yangyang at zte.com.cn>
---
 arch/arm/mm/nommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 2658f52..7256ac1 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -56,7 +56,7 @@ static inline bool security_extensions_enabled(void)
 	if ((read_cpuid_id() & 0x000f0000) == 0x000f0000)
 		return cpuid_feature_extract(CPUID_EXT_PFR1, 4) ||
 			cpuid_feature_extract(CPUID_EXT_PFR1, 20);
-	return 0;
+	return false;
 }
 
 unsigned long setup_vectors_base(void)
-- 
1.8.3.1




From nancy.lin at mediatek.com  Mon Aug 23 21:52:06 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Tue, 24 Aug 2021 12:52:06 +0800
Subject: [PATCH v3 15/15] drm/mediatek: add mediatek-drm of vdosys1
 support for MT8195
In-Reply-To: <CAAOTY_99QLpRHLei2PzD8vsuoOaZae++NqczPCM+r9YMZ01btw@mail.gmail.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-16-nancy.lin@mediatek.com>
 <CAAOTY_99QLpRHLei2PzD8vsuoOaZae++NqczPCM+r9YMZ01btw@mail.gmail.com>
Message-ID: <b19a2f09b44b4664182720a6bdb526d338f8db37.camel@mediatek.com>

Hi Chun-Kuang,
	Thanks for the review.

On Sun, 2021-08-22 at 09:14 +0800, Chun-Kuang Hu wrote:
> Hi, Nancy:
> 
> Nancy.Lin <nancy.lin at mediatek.com> ? 2021?8?18? ?? ??5:18???
> > 
> > Add driver data of mt8195 vdosys1 to mediatek-drm and modify drm
> > for
> > multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring
> > up two drm drivers, only one drm driver register as the drm device.
> > Each drm driver binds its own component. The first bind drm driver
> > will allocate the drm device, and the last bind drm driver
> > registers
> > the drm device to drm core. Each crtc path is created with the
> > corresponding drm driver data.
> > 
> > Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> > 
> > 
> > +static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
> > +       .clk_enable = mtk_ethdr_clk_enable,
> > +       .clk_disable = mtk_ethdr_clk_disable,
> > +       .config = mtk_ethdr_config,
> > +       .start = mtk_ethdr_start,
> > +       .stop = mtk_ethdr_stop,
> > +       .layer_nr = mtk_ethdr_layer_nr,
> > +       .layer_config = mtk_ethdr_layer_config,
> > +       .enable_vblank = mtk_ethdr_enable_vblank,
> > +       .disable_vblank = mtk_ethdr_disable_vblank,
> > +};
> 
> I think ethdr is inside the group of ovl_adpator. I preter this
> function is implemented by ovl_adaptor, and ovl_adaptor control rdma,
> merge, ethdr.
> 
> Regards,
> Chun-Kuang.
> 
OK, I will change it to the ovl_adaptor function.

> > +
> > 

From nancy.lin at mediatek.com  Mon Aug 23 21:53:49 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Tue, 24 Aug 2021 12:53:49 +0800
Subject: [PATCH v3 15/15] drm/mediatek: add mediatek-drm of vdosys1
 support for MT8195
In-Reply-To: <CAAOTY_8UUyT1u1bNqK-rNjKaFUo5=MVVrfMF6CUXmcXDb-xV1w@mail.gmail.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-16-nancy.lin@mediatek.com>
 <CAAOTY_8UUyT1u1bNqK-rNjKaFUo5=MVVrfMF6CUXmcXDb-xV1w@mail.gmail.com>
Message-ID: <231a458307f3037034cfbcb9254b5d6b20df7922.camel@mediatek.com>

Hi Chun-Kuang,

	Thanks for the review.

On Sat, 2021-08-21 at 07:37 +0800, Chun-Kuang Hu wrote:
> Hi, Nancy:
> 
> Nancy.Lin <nancy.lin at mediatek.com> ? 2021?8?18? ?? ??5:18???
> > 
> > Add driver data of mt8195 vdosys1 to mediatek-drm and modify drm
> > for
> > multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring
> > up two drm drivers, only one drm driver register as the drm device.
> > Each drm driver binds its own component. The first bind drm driver
> > will allocate the drm device, and the last bind drm driver
> > registers
> > the drm device to drm core. Each crtc path is created with the
> > corresponding drm driver data.
> 
> Separate this patch to two patch. One is support two mmsys, and
> another one is support mt8195 vdosys1.
> 
> Regards,
> Chun-Kuang.
> 
OK, I will separate it into two patches.
> > 
> > Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_disp_merge.c   |   4 +
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |  25 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |   3 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  15 +
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 372
> > ++++++++++++++++----
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   8 +-
> >  7 files changed, 354 insertions(+), 74 deletions(-)
> > 
> > 

From nancy.lin at mediatek.com  Mon Aug 23 21:58:46 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Tue, 24 Aug 2021 12:58:46 +0800
Subject: [PATCH v3 13/15] drm/mediatek: add ovl_adaptor support for MT8195
In-Reply-To: <CAAOTY_-WUWzThnddWNwMzd=BTBsbFRfMs4ABKJk6huADHUWrgQ@mail.gmail.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-14-nancy.lin@mediatek.com>
 <CAAOTY_-WUWzThnddWNwMzd=BTBsbFRfMs4ABKJk6huADHUWrgQ@mail.gmail.com>
Message-ID: <fd9d237051655c88f22b3c24f31c27fb281782ba.camel@mediatek.com>

Hi Chun-Kuang,

Thanks for the review.

On Sun, 2021-08-22 at 07:47 +0800, Chun-Kuang Hu wrote:
> Hi, Nancy:
> 
> Nancy.Lin <nancy.lin at mediatek.com> ? 2021?8?18? ?? ??5:19???
> > 
> > Add ovl_adaptor driver for MT8195.
> > Ovl_adaptor is an encapsulated module and designed for simplified
> > DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and
> > an ETHDR. Two RDMAs merge into one layer, so this module support 4
> > layers.
> > 
> > Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/Makefile             |   3 +-
> >  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 528
> > ++++++++++++++++++
> >  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.h   |  19 +
> >  3 files changed, 549 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
> > 
> > diff --git a/drivers/gpu/drm/mediatek/Makefile
> > b/drivers/gpu/drm/mediatek/Makefile
> > index 38ec2354a894..f04ac86c9593 100644
> > --- a/drivers/gpu/drm/mediatek/Makefile
> > +++ b/drivers/gpu/drm/mediatek/Makefile
> > @@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_ccorr.o \
> >                   mtk_drm_plane.o \
> >                   mtk_dsi.o \
> >                   mtk_dpi.o \
> > -                 mtk_mdp_rdma.o
> > +                 mtk_mdp_rdma.o \
> > +                 mtk_disp_ovl_adaptor.o
> 
> Alphabetic order.
> 
OK.
> > 
> >  obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > new file mode 100644
> > index 000000000000..8222ec5ff799
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > @@ -0,0 +1,528 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + */
> > +
> > +#include <drm/drm_fourcc.h>
> > +#include <linux/clk.h>
> > +#include <linux/reset.h>
> > +#include <linux/component.h>
> 
> Alphabetic order.

OK.
> 
> > +#include <linux/of_device.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/soc/mediatek/mtk-mmsys.h>
> > +#include <linux/soc/mediatek/mtk-cmdq.h>
> > +
> > +#include "mtk_drm_drv.h"
> > +#include "mtk_drm_crtc.h"
> > +#include "mtk_drm_ddp_comp.h"
> > +#include "mtk_disp_drv.h"
> > +#include "mtk_disp_ovl_adaptor.h"
> > +
> > +#define DISP_MERGE_ENABLE      0x0
> > +       #define MERGE_ENABLE BIT(0)
> 
> I would like
> 
> #define DISP_MERGE_ENABLE      0x0
> #define MERGE_ENABLE                           BIT(0)
> 
I will use merge common driver instead of ovl merge driver. Will remove
merge related part.

> > +#define DISP_MERGE_CFG_0       0x10
> > +#define DISP_MERGE_CFG_1       0x14
> > +#define DISP_MERGE_CFG_4       0x20
> > +#define DISP_MERGE_CFG_5       0x24
> > +#define DISP_MERGE_CFG_10      0x38
> > +       #define CFG_10_NO_SWAP 0
> > +#define DISP_MERGE_CFG_12      0x40
> > +       #define CFG12_10_10_1PI_2PO_BUF_MODE 6
> > +       #define CFG12_11_10_1PI_2PO_MERGE 18
> > +#define DISP_MERGE_CFG_24      0x70
> > +#define DISP_MERGE_CFG_25      0x74
> > +#define DISP_MERGE_CFG_26      0x78
> > +#define DISP_MERGE_CFG_27      0x7c
> > +#define DISP_MERGE_MUTE_0      0xf00
> > +
> > +#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
> > +#define MTK_OVL_ADAPTOR_LAYER_NUM 4
> > +
> > +enum mtk_ovl_adaptor_comp_type {
> > +       OVL_ADAPTOR_TYPE_RDMA = 0,
> > +       OVL_ADAPTOR_TYPE_MERGE,
> > +       OVL_ADAPTOR_TYPE_NUM,
> > +};
> > +
> > +enum mtk_ovl_adaptor_comp_id {
> > +       OVL_ADAPTOR_MDP_RDMA0,
> > +       OVL_ADAPTOR_MDP_RDMA1,
> > +       OVL_ADAPTOR_MDP_RDMA2,
> > +       OVL_ADAPTOR_MDP_RDMA3,
> > +       OVL_ADAPTOR_MDP_RDMA4,
> > +       OVL_ADAPTOR_MDP_RDMA5,
> > +       OVL_ADAPTOR_MDP_RDMA6,
> > +       OVL_ADAPTOR_MDP_RDMA7,
> > +       OVL_ADAPTOR_MERGE0,
> > +       OVL_ADAPTOR_MERGE1,
> > +       OVL_ADAPTOR_MERGE2,
> > +       OVL_ADAPTOR_MERGE3,
> > +       OVL_ADAPTOR_ID_MAX
> > +};
> > +
> > +struct ovl_adaptor_comp_match {
> > +       enum mtk_ovl_adaptor_comp_type type;
> > +       int alias_id;
> > +};
> > +
> > +struct ovl_adaptor_merge_config {
> > +       unsigned int fmt;
> > +       unsigned int merge_mode;
> > +       unsigned int in_w[2];
> > +       unsigned int out_w[2];
> > +       unsigned int in_h;
> > +};
> > +
> > +struct mtk_ovl_adaptor_comp {
> > +       struct device *dev;
> > +       struct clk *clks[2];
> > +       struct cmdq_client_reg cmdq_base;
> > +       void __iomem *regs;
> > +};
> 
> keep only dev, other value should be moved to dev private data.
> 
OK.
> > +
> > +struct mtk_disp_ovl_adaptor {
> > +       struct mtk_ovl_adaptor_comp
> > ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
> > +       struct device *mmsys_dev;
> > +};
> > +
> > +static const char * const ovl_adaptor_comp_str[] = {
> > +       "OVL_ADAPTOR_MDP_RDMA0",
> > +       "OVL_ADAPTOR_MDP_RDMA1",
> > +       "OVL_ADAPTOR_MDP_RDMA2",
> > +       "OVL_ADAPTOR_MDP_RDMA3",
> > +       "OVL_ADAPTOR_MDP_RDMA4",
> > +       "OVL_ADAPTOR_MDP_RDMA5",
> > +       "OVL_ADAPTOR_MDP_RDMA6",
> > +       "OVL_ADAPTOR_MDP_RDMA7",
> > +       "OVL_ADAPTOR_MERGE0",
> > +       "OVL_ADAPTOR_MERGE1",
> > +       "OVL_ADAPTOR_MERGE2",
> > +       "OVL_ADAPTOR_MERGE3",
> > +       "OVL_ADAPTOR_ID_MAX"
> > +};
> > +
> > +static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM]
> > = {
> > +       [OVL_ADAPTOR_TYPE_RDMA] = "vdo1_rdma",
> > +       [OVL_ADAPTOR_TYPE_MERGE] = "merge",
> > +};
> > +
> > +static const struct ovl_adaptor_comp_match
> > comp_matches[OVL_ADAPTOR_ID_MAX] = {
> > +       [OVL_ADAPTOR_MDP_RDMA0] =       { OVL_ADAPTOR_TYPE_RDMA, 0
> > },
> > +       [OVL_ADAPTOR_MDP_RDMA1] =       { OVL_ADAPTOR_TYPE_RDMA, 1
> > },
> > +       [OVL_ADAPTOR_MDP_RDMA2] =       { OVL_ADAPTOR_TYPE_RDMA, 2
> > },
> > +       [OVL_ADAPTOR_MDP_RDMA3] =       { OVL_ADAPTOR_TYPE_RDMA, 3
> > },
> > +       [OVL_ADAPTOR_MDP_RDMA4] =       { OVL_ADAPTOR_TYPE_RDMA, 4
> > },
> > +       [OVL_ADAPTOR_MDP_RDMA5] =       { OVL_ADAPTOR_TYPE_RDMA, 5
> > },
> > +       [OVL_ADAPTOR_MDP_RDMA6] =       { OVL_ADAPTOR_TYPE_RDMA, 6
> > },
> > +       [OVL_ADAPTOR_MDP_RDMA7] =       { OVL_ADAPTOR_TYPE_RDMA, 7
> > },
> > +       [OVL_ADAPTOR_MERGE0] =  { OVL_ADAPTOR_TYPE_MERGE, 1 },
> > +       [OVL_ADAPTOR_MERGE1] =  { OVL_ADAPTOR_TYPE_MERGE, 2 },
> > +       [OVL_ADAPTOR_MERGE2] =  { OVL_ADAPTOR_TYPE_MERGE, 3 },
> > +       [OVL_ADAPTOR_MERGE3] =  { OVL_ADAPTOR_TYPE_MERGE, 4 },
> > +};
> > +
> > +static void mtk_ovl_adaptor_merge_config(struct
> > mtk_ovl_adaptor_comp *comp,
> > +                                        struct
> > ovl_adaptor_merge_config *merge_cfg,
> > +                                        struct cmdq_pkt *cmdq_pkt)
> > +{
> > +       switch (merge_cfg->merge_mode) {
> > +       case 6:
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[0]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_0);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->out_w[0]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_4);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[0]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_24);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[0]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_25);
> > +               break;
> > +       case 18:
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[0]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_0);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[1]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_1);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->out_w[0]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_4);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[0]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_24);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[1]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_25);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[0]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_26);
> > +               mtk_ddp_write(cmdq_pkt, (merge_cfg->in_h << 16 |
> > merge_cfg->in_w[1]),
> > +                             &comp->cmdq_base, comp->regs,
> > DISP_MERGE_CFG_27);
> > +               break;
> > +       default:
> > +               break;
> > +       }
> > +
> > +       mtk_ddp_write(cmdq_pkt, merge_cfg->merge_mode, &comp-
> > >cmdq_base,
> > +                     comp->regs, DISP_MERGE_CFG_12);
> > +       mtk_ddp_write(cmdq_pkt, CFG_10_NO_SWAP, &comp->cmdq_base,
> > +                     comp->regs, DISP_MERGE_CFG_10);
> > +       mtk_ddp_write_mask(cmdq_pkt, 1, &comp->cmdq_base, comp-
> > >regs,
> > +                          DISP_MERGE_ENABLE, MERGE_ENABLE);
> 
> Move this function to merge driver.
> 
OK.
> > +}
> > +
> > +void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int
> > idx,
> > +                                 struct mtk_plane_state *state,
> > +                                 struct cmdq_pkt *cmdq_pkt)
> > +{
> > +       struct mtk_disp_ovl_adaptor *ovl_adaptor =
> > dev_get_drvdata(dev);
> > +       struct mtk_plane_pending_state *pending = &state->pending;
> > +       struct ovl_adaptor_merge_config merge_cfg = {0};
> > +       struct mtk_mdp_rdma_cfg rdma_config = {0};
> > +       struct mtk_ovl_adaptor_comp *rdma_l;
> > +       struct mtk_ovl_adaptor_comp *rdma_r;
> > +       struct mtk_ovl_adaptor_comp *merge;
> > +       const struct drm_format_info *fmt_info =
> > drm_format_info(pending->format);
> > +       bool use_dual_pipe = false;
> > +
> > +       dev_dbg(dev, "%s+ idx:%d, enable:%d, fmt:0x%x\n", __func__,
> > idx,
> > +               pending->enable, pending->format);
> > +       dev_dbg(dev, "addr 0x%lx, fb w:%d, {%d,%d,%d,%d}\n",
> > +               pending->addr, (pending->pitch / fmt_info->cpp[0]),
> > +               pending->x, pending->y, pending->width, pending-
> > >height);
> > +
> > +       rdma_l = &ovl_adaptor-
> > >ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx];
> > +       rdma_r = &ovl_adaptor-
> > >ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx + 1];
> > +       merge = &ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 +
> > idx];
> > +
> > +       if (!pending->enable) {
> > +               mtk_ddp_write_mask(cmdq_pkt, 0x0, &merge-
> > >cmdq_base, merge->regs,
> > +                                  DISP_MERGE_ENABLE,
> > MERGE_ENABLE);
> 
> Ditto.

OK.
> 
> > +               mtk_mdp_rdma_stop(rdma_l->regs, cmdq_pkt, &rdma_l-
> > >cmdq_base);
> > +               mtk_mdp_rdma_stop(rdma_r->regs, cmdq_pkt, &rdma_r-
> > >cmdq_base);
> > +               return;
> > +       }
> > +
> > +       if (pending->width > MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH)
> > +               use_dual_pipe = true;
> > +
> > +       merge_cfg.out_w[0] = pending->width;
> > +       merge_cfg.in_h = pending->height;
> > +       merge_cfg.fmt = pending->format;
> > +       if (use_dual_pipe) {
> > +               merge_cfg.merge_mode = CFG12_11_10_1PI_2PO_MERGE;
> > +               merge_cfg.in_w[0] = (pending->width / 2) +
> > ((pending->width / 2) % 2);
> > +               merge_cfg.in_w[1] = (pending->width / 2) -
> > ((pending->width / 2) % 2);
> 
> merge_cfg.in_w[1] = pending->width - merge_cfg.in_w[0];
> 
> > +       } else {
> > +               merge_cfg.merge_mode =
> > CFG12_10_10_1PI_2PO_BUF_MODE;
> > +               merge_cfg.in_w[0] = pending->width;
> > +       }
> > +       mtk_ovl_adaptor_merge_config(merge, &merge_cfg, cmdq_pkt);
> > +
> > +       mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev,
> > MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
> > +                            idx, pending->width / 2, cmdq_pkt);
> > +       mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev,
> > MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
> > +                            idx, pending->height, cmdq_pkt);
> > +
> > +       rdma_config.source_width = pending->pitch / fmt_info-
> > >cpp[0];
> > +       rdma_config.csc_enable = fmt_info->is_yuv ? true : false;
> > +       rdma_config.profile = RDMA_CSC_FULL709_TO_RGB;
> > +       rdma_config.width = merge_cfg.in_w[0];
> > +       rdma_config.height = pending->height;
> > +       rdma_config.addr0 = pending->addr;
> > +       rdma_config.pitch = pending->pitch;
> > +       rdma_config.fmt = pending->format;
> > +       mtk_mdp_rdma_config(rdma_l->regs, &rdma_config, cmdq_pkt,
> > &rdma_l->cmdq_base);
> > +
> > +       rdma_config.x_left = merge_cfg.in_w[0];
> > +       rdma_config.width = merge_cfg.in_w[1];
> > +       mtk_mdp_rdma_config(rdma_r->regs, &rdma_config, cmdq_pkt,
> > &rdma_r->cmdq_base);
> > +
> > +       mtk_ddp_write_mask(cmdq_pkt, 0x1, &merge->cmdq_base, merge-
> > >regs,
> > +                          DISP_MERGE_ENABLE, MERGE_ENABLE);
> > +       mtk_ddp_write_mask(cmdq_pkt, 0x0, &merge->cmdq_base, merge-
> > >regs,
> > +                          DISP_MERGE_MUTE_0, 0x1);
> 
> Move this to merge driver.
OK.
> 
> > +
> > +       mtk_mdp_rdma_start(rdma_l->regs, cmdq_pkt, &rdma_l-
> > >cmdq_base);
> > +       if (use_dual_pipe)
> > +               mtk_mdp_rdma_start(rdma_r->regs, cmdq_pkt, &rdma_r-
> > >cmdq_base);
> > +       else
> > +               mtk_mdp_rdma_stop(rdma_r->regs, cmdq_pkt, &rdma_r-
> > >cmdq_base);
> > +}
> > +
> > +void mtk_ovl_adaptor_stop(struct device *dev)
> > +{
> > +       struct mtk_disp_ovl_adaptor *ovl_adaptor =
> > dev_get_drvdata(dev);
> > +       struct mtk_ovl_adaptor_comp *rdma_l;
> > +       struct mtk_ovl_adaptor_comp *rdma_r;
> > +       struct mtk_ovl_adaptor_comp *merge;
> > +       unsigned int reg;
> > +       u32 i;
> > +
> > +       for (i = 0; i < MTK_OVL_ADAPTOR_LAYER_NUM; i++) {
> > +               rdma_l = &ovl_adaptor-
> > >ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * i];
> > +               rdma_r = &ovl_adaptor-
> > >ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * i + 1];
> > +               merge = &ovl_adaptor-
> > >ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + i];
> > +
> > +               mtk_mdp_rdma_stop(rdma_l->regs, NULL, &rdma_l-
> > >cmdq_base);
> > +               mtk_mdp_rdma_stop(rdma_r->regs, NULL, &rdma_r-
> > >cmdq_base);
> > +
> > +               reg = readl(merge->regs + DISP_MERGE_ENABLE);
> > +               reg = reg & ~MERGE_ENABLE;
> > +               writel_relaxed(reg, merge->regs +
> > DISP_MERGE_ENABLE);
> 
> Ditto.
OK.
> 
> > +
> > +               device_reset_optional(merge->dev);
> > +       }
> > +}
> > +
> > +int mtk_ovl_adaptor_clk_enable(struct device *dev)
> > +{
> > +       struct mtk_disp_ovl_adaptor *ovl_adaptor =
> > dev_get_drvdata(dev);
> > +       struct mtk_ovl_adaptor_comp *comp;
> > +       int ret;
> > +       int i;
> > +       int j;
> > +
> > +       for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_ID_MAX;
> > i++) {
> > +               comp = &ovl_adaptor->ovl_adaptor_comp[i];
> > +               if (!comp->dev)
> > +                       continue;
> > +
> > +               /* Need to power on for private rdma devices */
> > +               if (i < OVL_ADAPTOR_MERGE0) {
> > +                       ret = pm_runtime_get_sync(comp->dev);
> > +                       if (ret < 0)
> > +                               dev_err(dev,
> > +                                       "Failed to power on, err
> > %d-%s\n",
> > +                                       ret,
> > ovl_adaptor_comp_str[i]);
> 
> undo previos pm_runtime_get_sync() and return error.

OK, I will add error handling.
> 
> > +               }
> > +
> > +               for (j = 0; j < ARRAY_SIZE(comp->clks); j++) {
> > +                       if (IS_ERR(comp->clks[j]))
> > +                               break;
> > +
> > +                       ret = clk_prepare_enable(comp->clks[j]);
> > +                       if (ret)
> > +                               dev_err(dev,
> > +                                       "Failed to enable clock %d,
> > err %d-%s\n",
> > +                                       i, ret,
> > ovl_adaptor_comp_str[i]);
> 
> undo and previous job and return error.

OK, I will add error handling.
> 
> > +               }
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +void mtk_ovl_adaptor_clk_disable(struct device *dev)
> > +{
> > +       struct mtk_disp_ovl_adaptor *ovl_adaptor =
> > dev_get_drvdata(dev);
> > +       struct mtk_ovl_adaptor_comp *comp;
> > +       int ret;
> > +       int i;
> > +       int j;
> > +
> > +       for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_ID_MAX;
> > i++) {
> > +               comp = &ovl_adaptor->ovl_adaptor_comp[i];
> > +               if (!comp->dev)
> > +                       continue;
> > +
> > +               for (j = 0; i < ARRAY_SIZE(comp->clks); j++) {
> > +                       if (IS_ERR(comp->clks[j]))
> > +                               break;
> > +                       clk_disable_unprepare(comp->clks[j]);
> > +               }
> > +
> > +               /* Need to power off for private rdma devices */
> > +               if (i < OVL_ADAPTOR_MERGE0) {
> > +                       ret = pm_runtime_put(comp->dev);
> > +                       if (ret < 0)
> > +                               dev_err(dev,
> > +                                       "Failed to power off, err-
> > %s\n",
> > +                                       ret,
> > ovl_adaptor_comp_str[i]);
> > +               }
> > +       }
> > +}
> > +
> > +static int ovl_adaptor_comp_get_id(struct device *dev, struct
> > device_node *node,
> > +                                  enum mtk_ovl_adaptor_comp_type
> > type)
> > +{
> > +       int alias_id = of_alias_get_id(node,
> > private_comp_stem[type]);
> > +       int ret;
> > +       int i;
> > +
> > +       for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
> > +               if (comp_matches[i].type == type &&
> > +                   comp_matches[i].alias_id == alias_id)
> > +                       return i;
> > +
> > +       dev_err(dev, "Failed to get id. type: %d, alias: %d\n",
> > type, alias_id);
> > +       return -EINVAL;
> > +}
> > +
> > +static int private_comp_init(struct device *dev, struct
> > device_node *node,
> > +                            struct mtk_ovl_adaptor_comp *comp,
> > +                            enum mtk_ovl_adaptor_comp_id id)
> > +{
> > +       struct platform_device *comp_pdev;
> > +       int ret;
> > +       int i;
> > +
> > +       if (id < 0 || id >= OVL_ADAPTOR_ID_MAX) {
> > +               dev_err(dev, "Invalid component id %d\n", id);
> > +               return -EINVAL;
> > +       }
> > +
> > +       comp_pdev = of_find_device_by_node(node);
> > +       if (!comp_pdev) {
> > +               dev_warn(dev, "can't find platform device of
> > node:%s\n",
> > +                        node->name);
> > +               return -ENODEV;
> > +       }
> > +       comp->dev = &comp_pdev->dev;
> > +       comp->regs = of_iomap(node, 0);
> > +
> > +       for (i = 0; i < ARRAY_SIZE(comp->clks); i++) {
> > +               comp->clks[i] = of_clk_get(node, i);
> > +               if (IS_ERR(comp->clks[i]))
> > +                       break;
> > +       }
> > +
> > +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> > +       ret = cmdq_dev_get_client_reg(comp->dev, &comp->cmdq_base,
> > 0);
> > +       if (ret)
> > +               dev_info(dev, "get mediatek,gce-client-reg
> > fail!\n");
> > +#endif
> > +
> > +       if (id < OVL_ADAPTOR_MERGE0)
> > +               pm_runtime_enable(comp->dev);
> > +
> > +       dev_info(dev, "[DRM]regs:0x%p, node:%s\n", comp->regs,
> > ovl_adaptor_comp_str[id]);
> > +
> > +       return 0;
> > +}
> > +
> > +static int mtk_disp_ovl_adaptor_comp_probe(struct platform_device
> > *pdev)
> > +{
> > +       return 0;
> > +}
> > +
> > +static int mtk_disp_ovl_adaptor_comp_remove(struct platform_device
> > *pdev)
> > +{
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = {
> > +       {
> > +               .compatible = "mediatek,mt8195-vdo1-rdma",
> > +               .data = (void *)OVL_ADAPTOR_TYPE_RDMA,
> > +       }, {
> > +               .compatible = "mediatek,mt8195-vdo1-merge",
> > +               .data = (void *)OVL_ADAPTOR_TYPE_MERGE,
> > +       },
> > +       {},
> > +};
> > +
> > +static struct platform_driver mtk_disp_ovl_adaptor_comp_driver = {
> > +       .probe          = mtk_disp_ovl_adaptor_comp_probe,
> > +       .remove         = mtk_disp_ovl_adaptor_comp_remove,
> > +       .driver = {
> > +               .name   = "mediatek-disp-ovl-adaptor-comp",
> > +               .owner  = THIS_MODULE,
> > +               .of_match_table = mtk_ovl_adaptor_comp_dt_ids,
> > +       },
> > +};
> > +module_platform_driver(mtk_disp_ovl_adaptor_comp_driver);
> > +
> > +static int ovl_adaptor_comp_init(struct device *dev)
> > +{
> > +       struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
> > +       struct device_node *node, *parent;
> > +       int i, ret;
> > +
> > +       parent = dev->parent->of_node->parent;
> > +
> > +       for_each_child_of_node(parent, node) {
> > +               const struct of_device_id *of_id;
> > +               enum mtk_ovl_adaptor_comp_type type;
> > +               struct mtk_ovl_adaptor_comp *comp;
> > +               int id;
> > +
> > +               of_id = of_match_node(mtk_ovl_adaptor_comp_dt_ids,
> > node);
> > +               if (!of_id)
> > +                       continue;
> > +
> > +               if (!of_device_is_available(node)) {
> > +                       dev_info(dev, "Skipping disabled component
> > %pOF\n",
> > +                                node);
> > +                       continue;
> > +               }
> > +
> > +               type = (enum mtk_ovl_adaptor_comp_type)of_id->data;
> > +               id = ovl_adaptor_comp_get_id(dev, node, type);
> > +               if (id < 0) {
> > +                       dev_warn(dev, "Skipping unknown component
> > %pOF\n",
> > +                                node);
> > +                       continue;
> > +               }
> > +
> > +               ret = private_comp_init(dev, node, &priv-
> > >ovl_adaptor_comp[id], id);
> > +               if (ret)
> > +                       return ret;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id ovl_adaptor_driver_dt_match[] = {
> > +       { .compatible = "mediatek,mt8195-disp-ethdr"},
> > +       {},
> > +};
> > +MODULE_DEVICE_TABLE(of, mtk_disp_ovl_adaptor_driver_dt_match);
> > +
> > +static int mtk_disp_ovl_adaptor_probe(struct platform_device
> > *pdev)
> > +{
> > +       struct mtk_disp_ovl_adaptor *priv;
> > +       struct device *dev = &pdev->dev;
> > +       struct device_node *phandle = dev->parent->of_node;
> > +       const struct of_device_id *of_id;
> > +       int ret;
> > +       int i;
> > +
> > +       dev_info(dev, "%s+\n", __func__);
> > +
> > +       of_id = of_match_node(ovl_adaptor_driver_dt_match,
> > phandle);
> > +       if (!of_id)
> > +               return -ENODEV;
> > +
> > +       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +       if (!priv)
> > +               return -ENOMEM;
> > +
> > +       priv->mmsys_dev = pdev->dev.platform_data;
> > +
> > +       platform_set_drvdata(pdev, priv);
> > +
> > +       ret = ovl_adaptor_comp_init(dev);
> > +       if (ret) {
> > +               dev_notice(dev, "ovl_adaptor comp init fail\n");
> > +               return ret;
> > +       }
> > +
> > +       dev_info(dev, "%s-\n", __func__);
> > +       return ret;
> > +}
> > +
> > +static int mtk_disp_ovl_adaptor_remove(struct platform_device
> > *pdev)
> > +{
> > +       struct mtk_disp_ovl_adaptor *ovl_adaptor =
> > dev_get_drvdata(&pdev->dev);
> > +       int i;
> > +
> > +       for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_MERGE0;
> > i++)
> > +               pm_runtime_disable(ovl_adaptor-
> > >ovl_adaptor_comp[i].dev);
> > +
> > +       return 0;
> > +}
> > +
> > +struct platform_driver mtk_disp_ovl_adaptor_driver = {
> > +       .probe = mtk_disp_ovl_adaptor_probe,
> > +       .remove = mtk_disp_ovl_adaptor_remove,
> > +       .driver = {
> > +                       .name = "mediatek-disp-ovl-adaptor",
> > +                       .owner = THIS_MODULE,
> > +               },
> > +};
> > +module_platform_driver(mtk_disp_ovl_adaptor_driver);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
> > new file mode 100644
> > index 000000000000..7d757be1f491
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.h
> > @@ -0,0 +1,19 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + */
> > +
> > +#ifndef __MTK_DISP_OVL_ADAPTOR_H__
> > +#define __MTK_DISP_OVL_ADAPTOR_H__
> > +
> > +#include <drm/mediatek_drm.h>
> > +
> > +void mtk_ovl_adaptor_stop(struct device *dev);
> > +int mtk_ovl_adaptor_clk_enable(struct device *dev);
> > +void mtk_ovl_adaptor_clk_disable(struct device *dev);
> > +void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int
> > idx,
> > +                                 struct mtk_plane_state *state,
> > +                                 struct cmdq_pkt *cmdq_pkt);
> > +
> > +#endif
> > +
> > --
> > 2.18.0
> > 

From ck.hu at mediatek.com  Mon Aug 23 22:02:31 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Tue, 24 Aug 2021 13:02:31 +0800
Subject: [PATCH v6 4/5] dts: arm64: mt8183: Add Mediatek MDP3 nodes
In-Reply-To: <20210819070954.16679-5-moudy.ho@mediatek.com>
References: <20210819070954.16679-1-moudy.ho@mediatek.com>
 <20210819070954.16679-5-moudy.ho@mediatek.com>
Message-ID: <1629781351.32243.3.camel@mtksdaap41>

Hi, Moudy:

On Thu, 2021-08-19 at 15:09 +0800, Moudy Ho wrote:
> Add device nodes for Media Data Path 3 (MDP3) modules.
> 
> Signed-off-by: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
> Signed-off-by: daoyuan huang <daoyuan.huang at mediatek.com>
> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt8183.dtsi | 110 +++++++++++++++++++++++
>  1 file changed, 110 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> index f90df6439c08..7cb1fcfeefb6 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> @@ -1232,6 +1232,108 @@
>  			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
>  		};
>  
> +		mdp3_rdma0: mdp3_rdma0 at 14001000 {
> +			compatible = "mediatek,mt8183-mdp3",
> +				     "mediatek,mt8183-mdp3-rdma";
> +			mediatek,scp = <&scp>;
> +			mediatek,mdp3-id = <0>;
> +			mdp3-comps = "mediatek,mt8183-mdp3-dl1", "mediatek,mt8183-mdp3-dl2",
> +				     "mediatek,mt8183-mdp3-path1", "mediatek,mt8183-mdp3-path2",
> +				     "mediatek,mt8183-mdp3-imgi", "mediatek,mt8183-mdp3-exto";
> +			mdp3-comp-ids = <0 1 0 1 0 1>;
> +			reg = <0 0x14001000 0 0x1000>,
> +			      <0 0x14000000 0 0x1000>,
> +			      <0 0x14005000 0 0x1000>,
> +			      <0 0x14006000 0 0x1000>,
> +			      <0 0x15020000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
> +						  <&gce SUBSYS_1400XXXX 0 0x1000>,
> +						  <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
> +						  <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
> +						  <&gce SUBSYS_1502XXXX 0 0x1000>;
> +			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +			clocks = <&mmsys CLK_MM_MDP_RDMA0>,
> +				 <&mmsys CLK_MM_MDP_RSZ1>,
> +				 <&mmsys CLK_MM_MDP_DL_TXCK>,
> +				 <&mmsys CLK_MM_MDP_DL_RX>,
> +				 <&mmsys CLK_MM_IPU_DL_TXCK>,
> +				 <&mmsys CLK_MM_IPU_DL_RX>;
> +			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
> +			mediatek,mmsys = <&mmsys>;
> +			mediatek,mm-mutex = <&mutex>;
> +			mediatek,mailbox-gce = <&gce>;
> +			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
> +				 <&gce 21 CMDQ_THR_PRIO_LOWEST 0>,
> +				 <&gce 22 CMDQ_THR_PRIO_LOWEST 0>,
> +				 <&gce 23 CMDQ_THR_PRIO_LOWEST 0>;
> +			gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
> +				     <&gce 0x14010000 SUBSYS_1401XXXX>,
> +				     <&gce 0x14020000 SUBSYS_1402XXXX>,
> +				     <&gce 0x15020000 SUBSYS_1502XXXX>;
> +			mediatek,gce-events = <CMDQ_EVENT_MDP_RDMA0_SOF>,
> +					      <CMDQ_EVENT_MDP_RDMA0_EOF>,
> +					      <CMDQ_EVENT_MDP_RSZ0_SOF>,

CMDQ_EVENT_MDP_RSZ0_SOF is sent from rsz0 to gce, so move this event to
rsz0.

Regards,
CK

> +					      <CMDQ_EVENT_MDP_RSZ1_SOF>,
> +					      <CMDQ_EVENT_MDP_TDSHP_SOF>,
> +					      <CMDQ_EVENT_MDP_WROT0_SOF>,
> +					      <CMDQ_EVENT_MDP_WROT0_EOF>,
> +					      <CMDQ_EVENT_MDP_WDMA0_SOF>,
> +					      <CMDQ_EVENT_MDP_WDMA0_EOF>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_0>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_1>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_2>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_3>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_4>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_5>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_6>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_7>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_8>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_9>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_10>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_11>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_12>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_13>,
> +					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_14>,
> +					      <CMDQ_EVENT_WPE_A_DONE>,
> +					      <CMDQ_EVENT_SPE_B_DONE>;
> +		};
> +
> +		mdp3_rsz0: mdp3_rsz0 at 14003000 {
> +			compatible = "mediatek,mt8183-mdp3-rsz";
> +			mediatek,mdp3-id = <0>;
> +			reg = <0 0x14003000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
> +			clocks = <&mmsys CLK_MM_MDP_RSZ0>;
> +		};
> +
> +		mdp3_rsz1: mdp3_rsz1 at 14004000 {
> +			compatible = "mediatek,mt8183-mdp3-rsz";
> +			mediatek,mdp3-id = <1>;
> +			reg = <0 0x14004000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
> +			clocks = <&mmsys CLK_MM_MDP_RSZ1>;
> +		};
> +
> +		mdp3_wrot0: mdp3_wrot0 at 14005000 {
> +			compatible = "mediatek,mt8183-mdp3-wrot";
> +			mediatek,mdp3-id = <0>;
> +			reg = <0 0x14005000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
> +			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +			clocks = <&mmsys CLK_MM_MDP_WROT0>;
> +			iommus = <&iommu M4U_PORT_MDP_WROT0>;
> +		};
> +
> +		mdp3_wdma: mdp3_wdma at 14006000 {
> +			compatible = "mediatek,mt8183-mdp3-wdma";
> +			mediatek,mdp3-id = <0>;
> +			reg = <0 0x14006000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
> +			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +			clocks = <&mmsys CLK_MM_MDP_WDMA0>;
> +			iommus = <&iommu M4U_PORT_MDP_WDMA0>;
> +		};
> +
>  		ovl0: ovl at 14008000 {
>  			compatible = "mediatek,mt8183-disp-ovl";
>  			reg = <0 0x14008000 0 0x1000>;
> @@ -1378,6 +1480,14 @@
>  			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
>  		};
>  
> +		mdp3_ccorr: mdp3_ccorr at 1401c000 {
> +			compatible = "mediatek,mt8183-mdp3-ccorr";
> +			mediatek,mdp3-id = <0>;
> +			reg = <0 0x1401c000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
> +			clocks = <&mmsys CLK_MM_MDP_CCORR>;
> +		};
> +
>  		imgsys: syscon at 15020000 {
>  			compatible = "mediatek,mt8183-imgsys", "syscon";
>  			reg = <0 0x15020000 0 0x1000>;


From nancy.lin at mediatek.com  Mon Aug 23 22:07:50 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Tue, 24 Aug 2021 13:07:50 +0800
Subject: [PATCH v3 02/15] dt-bindings: mediatek: add vdosys1 MERGE
 definition for mt8195
In-Reply-To: <CAAOTY_-mJ0WHK0pXqASprrc7GW0R_ZTRmJ8Yo8pu9js-cQ5HAw@mail.gmail.com>
References: <20210818091847.8060-1-nancy.lin@mediatek.com>
 <20210818091847.8060-3-nancy.lin@mediatek.com>
 <CAAOTY_-mJ0WHK0pXqASprrc7GW0R_ZTRmJ8Yo8pu9js-cQ5HAw@mail.gmail.com>
Message-ID: <9ce23e77e8ea5706b1d52700d655958f49eb911e.camel@mediatek.com>

Hi Chun-Kuang,

Thanks for the review.

On Fri, 2021-08-20 at 07:25 +0800, Chun-Kuang Hu wrote:
> Hi, Nancy:
> 
> Nancy.Lin <nancy.lin at mediatek.com> ? 2021?8?18? ?? ??5:18???
> > 
> > Add vdosys1 MERGE definition.
> > 
> > Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> > ---
> >  .../devicetree/bindings/display/mediatek/mediatek,merge.yaml    |
> > 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge
> > .yaml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge
> > .yaml
> > index 1a27b037086b..ba1e0c837988 100644
> > ---
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge
> > .yaml
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge
> > .yaml
> > @@ -23,6 +23,8 @@ properties:
> >            - const: mediatek,mt8173-disp-merge
> >        - items:
> >            - const: mediatek,mt8195-disp-merge
> > +      - items:
> > +          - const: mediatek,mt8195-vdo1-merge
> 
> I don't know why create a new merge for mt8195. Provide more
> information about the difference of these two merge.
> 
Compared with MT8195 merge0 and merge5, merge1~4 has more mute
function. I will remove this new compatible, move ovl_adaptor merge to
merge common driver, and add new merge binding property to increase
mute function.

> Regards,
> Chun-Kuang.
> 
> > 
> >    reg:
> >      maxItems: 1
> > --
> > 2.18.0
> > 

From dqfext at gmail.com  Mon Aug 23 22:50:19 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue, 24 Aug 2021 13:50:19 +0800
Subject: [PATCH 5.10.y] net: dsa: mt7530: disable learning on standalone ports
Message-ID: <20210824055020.1315672-1-dqfext@gmail.com>

This is a partial backport of commit 5a30833b9a16f8d1aa15de06636f9317ca51f9df
("net: dsa: mt7530: support MDB and bridge flag operations") upstream.

Make sure that the standalone ports start up with learning disabled.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 drivers/net/dsa/mt7530.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 3fa2f81c8b47..c9c02da3382d 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1083,6 +1083,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
 			   PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
 	priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
 
+	mt7530_clear(priv, MT7530_PSC_P(port), SA_DIS);
+
 	mutex_unlock(&priv->reg_mutex);
 
 	return 0;
@@ -1183,6 +1185,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 			   PCR_MATRIX(BIT(MT7530_CPU_PORT)));
 	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
 
+	mt7530_set(priv, MT7530_PSC_P(port), SA_DIS);
+
 	mutex_unlock(&priv->reg_mutex);
 }
 
@@ -1636,9 +1640,13 @@ mt7530_setup(struct dsa_switch *ds)
 			ret = mt753x_cpu_port_enable(ds, i);
 			if (ret)
 				return ret;
-		} else
+		} else {
 			mt7530_port_disable(ds, i);
 
+			/* Disable learning by default on all user ports */
+			mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+		}
+
 		/* Enable consistent egress tag */
 		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
@@ -1792,9 +1800,13 @@ mt7531_setup(struct dsa_switch *ds)
 			ret = mt753x_cpu_port_enable(ds, i);
 			if (ret)
 				return ret;
-		} else
+		} else {
 			mt7530_port_disable(ds, i);
 
+			/* Disable learning by default on all user ports */
+			mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+		}
+
 		/* Enable consistent egress tag */
 		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
-- 
2.25.1



From dqfext at gmail.com  Mon Aug 23 22:52:50 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue, 24 Aug 2021 13:52:50 +0800
Subject: [PATCH 5.4.y] net: dsa: mt7530: disable learning on standalone ports
Message-ID: <20210824055250.1315862-1-dqfext@gmail.com>

This is a partial backport of commit 5a30833b9a16f8d1aa15de06636f9317ca51f9df
("net: dsa: mt7530: support MDB and bridge flag operations") upstream.

Make sure that the standalone ports start up with learning disabled.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 drivers/net/dsa/mt7530.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index e1a3c33fdad9..b21444b38377 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -764,6 +764,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
 			   PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
 	priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
 
+	mt7530_clear(priv, MT7530_PSC_P(port), SA_DIS);
+
 	mutex_unlock(&priv->reg_mutex);
 
 	return 0;
@@ -864,6 +866,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 			   PCR_MATRIX(BIT(MT7530_CPU_PORT)));
 	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
 
+	mt7530_set(priv, MT7530_PSC_P(port), SA_DIS);
+
 	mutex_unlock(&priv->reg_mutex);
 }
 
@@ -1246,11 +1250,15 @@ mt7530_setup(struct dsa_switch *ds)
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
 
-		if (dsa_is_cpu_port(ds, i))
+		if (dsa_is_cpu_port(ds, i)) {
 			mt7530_cpu_port_enable(priv, i);
-		else
+		} else {
 			mt7530_port_disable(ds, i);
 
+			/* Disable learning by default on all user ports */
+			mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+		}
+
 		/* Enable consistent egress tag */
 		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
-- 
2.25.1



From nobuta.keiya at fujitsu.com  Mon Aug 23 22:55:01 2021
From: nobuta.keiya at fujitsu.com (nobuta.keiya at fujitsu.com)
Date: Tue, 24 Aug 2021 05:55:01 +0000
Subject: [RFC PATCH v8 3/4] arm64: Introduce stack trace reliability
 checks in the unwinder
In-Reply-To: <20210812190603.25326-4-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-4-madvenka@linux.microsoft.com>
Message-ID: <TY2PR01MB5257EA835C6F28ABF457EB0B85C59@TY2PR01MB5257.jpnprd01.prod.outlook.com>

Hi Madhavan,

> @@ -245,7 +271,36 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>  		fp = thread_saved_fp(task);
>  		pc = thread_saved_pc(task);
>  	}
> -	unwind(consume_entry, cookie, task, fp, pc);
> +	unwind(consume_entry, cookie, task, fp, pc, false);
> +}
> +
> +/*
> + * arch_stack_walk_reliable() may not be used for livepatch until all of
> + * the reliability checks are in place in unwind_consume(). However,
> + * debug and test code can choose to use it even if all the checks are not
> + * in place.
> + */

I'm glad to see the long-awaited function :)

Does the above comment mean that this comment will be removed by
another patch series that about live patch enablement, instead of [PATCH 4/4]?

It seems to take time... But I start thinking about test code.

Thanks,
Keiya


> +noinline int notrace arch_stack_walk_reliable(stack_trace_consume_fn consume_fn,
> +					      void *cookie,
> +					      struct task_struct *task)
> +{
> +	unsigned long fp, pc;
> +
> +	if (!task)
> +		task = current;
> +
> +	if (task == current) {
> +		/* Skip arch_stack_walk_reliable() in the stack trace. */
> +		fp = (unsigned long)__builtin_frame_address(1);
> +		pc = (unsigned long)__builtin_return_address(0);
> +	} else {
> +		/* Caller guarantees that the task is not running. */
> +		fp = thread_saved_fp(task);
> +		pc = thread_saved_pc(task);
> +	}
> +	if (unwind(consume_fn, cookie, task, fp, pc, true))
> +		return 0;
> +	return -EINVAL;
>  }
> 
>  #endif
> --
> 2.25.1


From dqfext at gmail.com  Mon Aug 23 22:55:08 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue, 24 Aug 2021 13:55:08 +0800
Subject: [PATCH 4.19.y] net: dsa: mt7530: disable learning on standalone ports
Message-ID: <20210824055509.1316124-1-dqfext@gmail.com>

This is a partial backport of commit 5a30833b9a16f8d1aa15de06636f9317ca51f9df
("net: dsa: mt7530: support MDB and bridge flag operations") upstream.

Make sure that the standalone ports start up with learning disabled.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 drivers/net/dsa/mt7530.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 6335c4ea0957..67dfab774618 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -803,6 +803,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
 			   PCR_MATRIX_MASK, PCR_MATRIX(port_bitmap));
 	priv->ports[port].pm |= PCR_MATRIX(port_bitmap);
 
+	mt7530_clear(priv, MT7530_PSC_P(port), SA_DIS);
+
 	mutex_unlock(&priv->reg_mutex);
 
 	return 0;
@@ -907,6 +909,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
 
 	mt7530_port_set_vlan_unaware(ds, port);
 
+	mt7530_set(priv, MT7530_PSC_P(port), SA_DIS);
+
 	mutex_unlock(&priv->reg_mutex);
 }
 
@@ -1287,11 +1291,15 @@ mt7530_setup(struct dsa_switch *ds)
 		mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
 			   PCR_MATRIX_CLR);
 
-		if (dsa_is_cpu_port(ds, i))
+		if (dsa_is_cpu_port(ds, i)) {
 			mt7530_cpu_port_enable(priv, i);
-		else
+		} else {
 			mt7530_port_disable(ds, i, NULL);
 
+			/* Disable learning by default on all user ports */
+			mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
+		}
+
 		/* Enable consistent egress tag */
 		mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
-- 
2.25.1



From hongxing.zhu at nxp.com  Mon Aug 23 23:04:19 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Tue, 24 Aug 2021 06:04:19 +0000
Subject: [PATCH v1 1/3] dt-bindings: PCI: imx6: convert the imx pcie
 controller to dtschema
In-Reply-To: <YSPqIEmngxjCCn+v@robh.at.kernel.org>
References: <20210819071408.3856475-1-hongxing.zhu@nxp.com>
 <20210819071408.3856475-2-hongxing.zhu@nxp.com>
 <YSPqIEmngxjCCn+v@robh.at.kernel.org>
Message-ID: <VI1PR04MB5853D9B0E217390C52E40FFE8CC59@VI1PR04MB5853.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Rob Herring <robh at kernel.org>
> Sent: Tuesday, August 24, 2021 2:34 AM
> To: Richard Zhu <hongxing.zhu at nxp.com>
> Cc: l.stach at pengutronix.de; galak at kernel.crashing.org;
> shawnguo at kernel.org; devicetree at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> dl-linux-imx <linux-imx at nxp.com>; kernel at pengutronix.de
> Subject: Re: [PATCH v1 1/3] dt-bindings: PCI: imx6: convert the imx pcie
> controller to dtschema
> 
> On Thu, Aug 19, 2021 at 03:14:06PM +0800, Richard Zhu wrote:
> > Convert the fsl,imx6q-pcie.txt into a schema.
> > - the ranges should be aligned to $ref: /schemas/pci/pci-bus.yaml#
> > - only one propert is allowed in the compatible string, remove
> >   "snps,dw-pcie".
> 
> Didn't I already see a v1?
[Richard Zhu] I assume that the RFC version as the v0, not formal v1.
Would pay attention to that.

> 
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
> > ---
> >  .../bindings/pci/fsl,imx6q-pcie.txt           | 100 ---------
> >  .../bindings/pci/fsl,imx6q-pcie.yaml          | 207
> ++++++++++++++++++
> >  MAINTAINERS                                   |   2 +-
> >  3 files changed, 208 insertions(+), 101 deletions(-)  delete mode
> > 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
> >  create mode 100644
> > Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
> > b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
> > deleted file mode 100644
> > index d8971ab99274..000000000000
> > --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
> > +++ /dev/null
> > @@ -1,100 +0,0 @@
> > -* Freescale i.MX6 PCIe interface
> > -
> > -This PCIe host controller is based on the Synopsys DesignWare PCIe IP
> > -and thus inherits all the common properties defined in designware-pcie.txt.
> > -
> > -Required properties:
> > -- compatible:
> > -	- "fsl,imx6q-pcie"
> > -	- "fsl,imx6sx-pcie",
> > -	- "fsl,imx6qp-pcie"
> > -	- "fsl,imx7d-pcie"
> > -	- "fsl,imx8mq-pcie"
> > -- reg: base address and length of the PCIe controller
> > -- interrupts: A list of interrupt outputs of the controller. Must
> > contain an
> > -  entry for each entry in the interrupt-names property.
> > -- interrupt-names: Must include the following entries:
> > -	- "msi": The interrupt that is asserted when an MSI is received
> > -- clock-names: Must include the following additional entries:
> > -	- "pcie_phy"
> > -
> > -Optional properties:
> > -- fsl,tx-deemph-gen1: Gen1 De-emphasis value. Default: 0
> > -- fsl,tx-deemph-gen2-3p5db: Gen2 (3.5db) De-emphasis value. Default:
> > 0
> > -- fsl,tx-deemph-gen2-6db: Gen2 (6db) De-emphasis value. Default: 20
> > -- fsl,tx-swing-full: Gen2 TX SWING FULL value. Default: 127
> > -- fsl,tx-swing-low: TX launch amplitude swing_low value. Default: 127
> > -- fsl,max-link-speed: Specify PCI gen for link capability. Must be
> > '2' for
> > -  gen2, otherwise will default to gen1. Note that the IMX6 LVDS clock
> > outputs
> > -  do not meet gen2 jitter requirements and thus for gen2 capability a
> > gen2
> > -  compliant clock generator should be used and configured.
> > -- reset-gpio: Should specify the GPIO for controlling the PCI bus
> > device reset
> > -  signal. It's not polarity aware and defaults to active-low reset
> > sequence
> > -  (L=reset state, H=operation state).
> > -- reset-gpio-active-high: If present then the reset sequence using
> > the GPIO
> > -  specified in the "reset-gpio" property is reversed (H=reset state,
> > -  L=operation state).
> > -- vpcie-supply: Should specify the regulator in charge of PCIe port power.
> > -  The regulator will be enabled when initializing the PCIe host and
> > -  disabled either as part of the init process or when shutting down
> > the
> > -  host.
> > -- vph-supply: Should specify the regulator in charge of VPH one of
> > the three
> > -  PCIe PHY powers. This regulator can be supplied by both 1.8v and
> > 3.3v voltage
> > -  supplies.
> > -
> > -Additional required properties for imx6sx-pcie:
> > -- clock names: Must include the following additional entries:
> > -	- "pcie_inbound_axi"
> > -- power-domains: Must be set to phandles pointing to the DISPLAY and
> > -  PCIE_PHY power domains
> > -- power-domain-names: Must be "pcie", "pcie_phy"
> > -
> > -Additional required properties for imx7d-pcie and imx8mq-pcie:
> > -- power-domains: Must be set to a phandle pointing to PCIE_PHY power
> > domain
> > -- resets: Must contain phandles to PCIe-related reset lines exposed
> > by SRC
> > -  IP block
> > -- reset-names: Must contain the following entries:
> > -	       - "pciephy"
> > -	       - "apps"
> > -	       - "turnoff"
> > -- fsl,imx7d-pcie-phy: A phandle to an fsl,imx7d-pcie-phy node.
> > -
> > -Additional required properties for imx8mq-pcie:
> > -- clock-names: Must include the following additional entries:
> > -	- "pcie_aux"
> > -
> > -Example:
> > -
> > -	pcie at 01000000 {
> > -		compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
> > -		reg = <0x01ffc000 0x04000>,
> > -		      <0x01f00000 0x80000>;
> > -		reg-names = "dbi", "config";
> > -		#address-cells = <3>;
> > -		#size-cells = <2>;
> > -		device_type = "pci";
> > -		ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000
> > -			  0x81000000 0 0          0x01f80000 0 0x00010000
> > -			  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
> > -		num-lanes = <1>;
> > -		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> > -		interrupt-names = "msi";
> > -		#interrupt-cells = <1>;
> > -		interrupt-map-mask = <0 0 0 0x7>;
> > -		interrupt-map = <0 0 0 1 &intc GIC_SPI 123
> IRQ_TYPE_LEVEL_HIGH>,
> > -		                <0 0 0 2 &intc GIC_SPI 122
> IRQ_TYPE_LEVEL_HIGH>,
> > -		                <0 0 0 3 &intc GIC_SPI 121
> IRQ_TYPE_LEVEL_HIGH>,
> > -		                <0 0 0 4 &intc GIC_SPI 120
> IRQ_TYPE_LEVEL_HIGH>;
> > -		clocks = <&clks 144>, <&clks 206>, <&clks 189>;
> > -		clock-names = "pcie", "pcie_bus", "pcie_phy";
> > -	};
> > -
> > -* Freescale i.MX7d PCIe PHY
> > -
> > -This is the PHY associated with the IMX7d PCIe controller.  It's used
> > by the -PCI-e controller via the fsl,imx7d-pcie-phy phandle.
> > -
> > -Required properties:
> > -- compatible:
> > -	- "fsl,imx7d-pcie-phy"
> > -- reg: base address and length of the PCIe PHY controller diff --git
> > a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> > b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> > new file mode 100644
> > index 000000000000..3503ce3de05d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> > @@ -0,0 +1,207 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id:
> > +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
> >
> +cetree.org%2Fschemas%2Fpci%2Ffsl%2Cimx6q-pcie.yaml%23&amp;data=0
> 4%7C0
> >
> +1%7Chongxing.zhu%40nxp.com%7Ca0e50943284145edfdc808d966649a08
> %7C686ea
> >
> +1d3bc2b4c6fa92cd99c5c301635%7C0%7C1%7C637653404543147546%7C
> Unknown%7C
> >
> +TWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwi
> LCJXV
> >
> +CI6Mn0%3D%7C3000&amp;sdata=mW%2FTR8dffuxQDk%2Fm1eiUd8IIRBjE
> mJMhkxQZPo
> > +GYfHM%3D&amp;reserved=0
> > +$schema:
> > +https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevi
> >
> +cetree.org%2Fmeta-schemas%2Fcore.yaml%23&amp;data=04%7C01%7Cho
> ngxing.
> >
> +zhu%40nxp.com%7Ca0e50943284145edfdc808d966649a08%7C686ea1d3b
> c2b4c6fa9
> >
> +2cd99c5c301635%7C0%7C1%7C637653404543147546%7CUnknown%7CT
> WFpbGZsb3d8e
> >
> +yJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3
> D%7C3
> >
> +000&amp;sdata=Gh1dUyXO80b2aKvWKe0Q2GIN4w%2BCit1oj06AvToamuE
> %3D&amp;re
> > +served=0
> > +
> > +title: Freescale i.MX6 PCIe host controller
> > +
> > +maintainers:
> > +  - Lucas Stach <l.stach at pengutronix.de>
> > +  - Richard Zhu <hongxing.zhu at nxp.com>
> > +
> > +description: |+
> > +  This PCIe host controller is based on the Synopsys DesignWare PCIe
> > +IP
> > +  and thus inherits all the common properties defined in
> snps,dw-pcie.yaml.
> 
> Don't need a freeform text reference, but...
[Richard Zhu] This part is copied from the description of previous the binding document.
Should I remove them totally?

> > +
> > +allOf:
> > +  - $ref: /schemas/pci/pci-bus.yaml#
> 
> ...this needs to reference the snps,dw-pcie.yaml DWC schema.
> 
[Richard Zhu] Got that, would be change in next version patch.

> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - fsl,imx6q-pcie
> > +      - fsl,imx6sx-pcie
> > +      - fsl,imx6qp-pcie
> > +      - fsl,imx7d-pcie
> > +      - fsl,imx8mq-pcie
> > +
> > +  reg:
> > +    items:
> > +      - description: Data Bus Interface (DBI) registers.
> > +      - description: PCIe configuration space region.
> > +
> > +  reg-names:
> > +    items:
> > +      - const: dbi
> > +      - const: config
> > +
> > +  interrupts:
> > +    minItems: 1
> 
> Don't need 'minItems: 1' when there's only 1 possible item:
[Richard Zhu] Okay, would be removed.

> 
> > +    items:
> > +      - description: builtin MSI controller.
> > +
> > +  interrupt-names:
> > +    minItems: 1
> > +    items:
> > +      - const: msi
> > +
> > +  clocks:
> > +    minItems: 3
> > +    maxItems: 4
> 
> Don't need maxItems here.
> 
[Richard Zhu] Okay, would be removed.

> > +    items:
> > +      - description: PCIe bridge clock.
> > +      - description: PCIe bus clock.
> > +      - description: PCIe PHY clock.
> > +      - description: Additional required clock entry for imx6sx-pcie,
> > +          imx8mq-pcie.
> > +
> > +  clock-names:
> > +    minItems: 3
> > +    maxItems: 4
> 
> And here.
> 
[Richard Zhu] Okay, would be removed.

> > +    items:
> > +      - const: pcie
> > +      - const: pcie_bus
> > +      - const: pcie_phy
> > +      - const: pcie_inbound_axi for imx6sx-pcie, pcie_aux for
> > + imx8mq-pcie
> > +
> > +  num-lanes:
> > +    const: 1
> > +
> > +  num-viewport:
> > +    const: 4
> 
> This is deprecated. The driver detects this now.
[Richard Zhu] Got that, thanks. Would delete this property.

> 
> > +
> > +  fsl,imx7d-pcie-phy:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description: A phandle to an fsl,imx7d-pcie-phy node. Additional
> > +      required properties for imx7d-pcie and imx8mq-pcie.
> > +
> > +  power-domains:
> > +    maxItems: 2
> > +    description: The first phandle pointing to the DISPLAY domain for
> > +      imx6sx-pcie, to PCIE_PHY power domain for imx7d-pcie and
> imx8mq-pcie.
> > +      The second phandle pointing to the PCIE_PHY power domains for
> imx6sx-pcie.
> 
> Split the description:
> 
> items:
>   - description: ...
>   - description: ...
> 
[Richard Zhu] Got that, thanks.

> > +
> > +  power-domain-names:
> > +    maxItems: 2
> 
> You have to define the names.
> 
[Richard Zhu] Okay, would be added in next version patch.

> > +
> > +  resets:
> > +    maxItems: 3
> > +    description: Phandles to PCIe-related reset lines exposed by SRC
> > +      IP block. Additional required by imx7d-pcie and imx8mq-pcie.
> > +
> > +  reset-names:
> > +    items:
> > +      - const: pciephy
> > +      - const: apps
> > +      - const: turnoff
> > +
> > +  fsl,tx-deemph-gen1:
> > +    description: Gen1 De-emphasis value (optional required).
> 
> optional or required?
[Richard Zhu] Yes, it's optional required by i.MX6Q/DL PCIe.
> 
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    default: 0
> > +
> > +  fsl,tx-deemph-gen2-3p5db:
> > +    description: Gen2 (3.5db) De-emphasis value (optional required).
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    default: 0
> > +
> > +  fsl,tx-deemph-gen2-6db:
> > +    description: Gen2 (6db) De-emphasis value (optional required).
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    default: 20
> > +
> > +  fsl,tx-swing-full:
> > +    description: Gen2 TX SWING FULL value (optional required).
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    default: 127
> > +
> > +  fsl,tx-swing-low:
> > +    description: TX launch amplitude swing_low value (optional required).
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    default: 127
> > +
> > +  fsl,max-link-speed:
> > +    description: Specify PCI Gen for link capability (optional required).
> > +      Note that the IMX6 LVDS clock outputs do not meet gen2 jitter
> > +      requirements and thus for gen2 capability a gen2 compliant clock
> > +      generator should be used and configured.
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    enum: [1, 2, 3, 4]
> > +    default: 1
> > +
> > +  reset-gpio:
> 
> Deprecated.
[Richard Zhu] The reset-gpio is designed to connect the PERST# signal on the slot.
And it is derived from the previous binding document.

> 
> > +    description: Should specify the GPIO for controlling the PCI bus device
> > +      reset signal. It's not polarity aware and defaults to active-low reset
> > +      sequence (L=reset state, H=operation state) (optional required).
> > +
> > +  reset-gpio-active-high:
> 
> Deprecated. This should only be used on older compatibles I hope...
[Richard Zhu] Because that the polarity of the PERST-active is reversed on some i.MX6 customer's
hardware board designs.
This property is derived from the previous binding document, and only be used
on older compatibles. So, this is optional required.

> 
> > +    description: If present then the reset sequence using the GPIO
> > +      specified in the "reset-gpio" property is reversed (H=reset state,
> > +      L=operation state) (optional required).
> > +
> > +  vpcie-supply:
> > +    description: Should specify the regulator in charge of PCIe port power.
> > +      The regulator will be enabled when initializing the PCIe host and
> > +      disabled either as part of the init process or when shutting down
> > +      the host (optional required).
> > +
> > +  vph-supply:
> > +    description: Should specify the regulator in charge of VPH one of
> > +      the three PCIe PHY powers. This regulator can be supplied by both
> > +      1.8v and 3.3v voltage supplies (optional required).
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - reg-names
> > +  - "#address-cells"
> > +  - "#size-cells"
> > +  - device_type
> > +  - bus-range
> > +  - ranges
> > +  - num-lanes
> > +  - num-viewport
> > +  - interrupts
> > +  - interrupt-names
> > +  - "#interrupt-cells"
> > +  - interrupt-map-mask
> > +  - interrupt-map
> > +  - clocks
> > +  - clock-names
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/imx6qdl-clock.h>
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +
> > +    pcie: pcie at 1ffc000 {
> > +        compatible = "fsl,imx6q-pcie";
> > +        reg = <0x01ffc000 0x04000>,
> > +              <0x01f00000 0x80000>;
> > +        reg-names = "dbi", "config";
> > +        #address-cells = <3>;
> > +        #size-cells = <2>;
> > +        device_type = "pci";
> > +        bus-range = <0x00 0xff>;
> > +        ranges = <0x81000000 0 0          0x01f80000 0
> 0x00010000>,
> > +                 <0x82000000 0 0x01000000 0x01000000 0
> 0x00f00000>;
> > +        num-lanes = <1>;
> > +        num-viewport = <4>;
> > +        interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> > +        interrupt-names = "msi";
> > +        #interrupt-cells = <1>;
> > +        interrupt-map-mask = <0 0 0 0x7>;
> > +        interrupt-map = <0 0 0 1 &gpc GIC_SPI 123
> IRQ_TYPE_LEVEL_HIGH>,
> > +                        <0 0 0 2 &gpc GIC_SPI 122
> IRQ_TYPE_LEVEL_HIGH>,
> > +                        <0 0 0 3 &gpc GIC_SPI 121
> IRQ_TYPE_LEVEL_HIGH>,
> > +                        <0 0 0 4 &gpc GIC_SPI 120
> IRQ_TYPE_LEVEL_HIGH>;
> > +        clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
> > +                <&clks IMX6QDL_CLK_LVDS1_GATE>,
> > +                <&clks IMX6QDL_CLK_PCIE_REF_125M>;
> > +        clock-names = "pcie", "pcie_bus", "pcie_phy";
> > +        status = "disabled";
> 
> Why are you disabling your example?
[Richard Zhu] Would remove the disable later. Thanks.

> 
> > +    };
> > +...
> > diff --git a/MAINTAINERS b/MAINTAINERS index
> > f73fef615702..a1e2cc0be9e8 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -14187,7 +14187,7 @@ M:	Lucas Stach <l.stach at pengutronix.de>
> >  L:	linux-pci at vger.kernel.org
> >  L:	linux-arm-kernel at lists.infradead.org (moderated for
> non-subscribers)
> >  S:	Maintained
> > -F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
> > +F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> >  F:	drivers/pci/controller/dwc/*imx6*
> >
> >  PCI DRIVER FOR FU740
> > --
> > 2.25.1
> >
> >


From Christine.Zhu at mediatek.com  Mon Aug 23 23:26:32 2021
From: Christine.Zhu at mediatek.com (Christine Zhu)
Date: Tue, 24 Aug 2021 14:26:32 +0800
Subject: [RESEND v8,0/2] watchdog: mt8195: add wdt support
Message-ID: <20210824062633.14374-1-Christine.Zhu@mediatek.com>

Supports MT8195 watchdog device. Supports MT8195 watchdog reset-controller feature.

Change since v7:
  -remove "[v7,1/3] dt-bindings: mediatek: mt8195: update mtk-wdt document", because the patch has been applied.

Change since v6:
  -move the reset-controller header file to 'include/dt-bindings/reset', in order to be consistent with [1]
   [1] https://patchwork.kernel.org/project/linux-mediatek/patch/20210714121116.v2.1.I514d9aafff3a062f751b37d3fea7402f67595b86 at changeid/

Change since v5:
  -fix author and license in [v5,2/3].

Change since v4:
  -fix name formatting in Signed-off-bys and author in [v4,3/3].

Change since v3:
  -fix name formatting in Signed-off-bys and author for all the patches.

Change since v2:
  -fix typos in [v2,0/3] [v2,1/3] [v2,2/3].

Change since v1:
  -Remove the unneeded tag in [v1,1/3] [v1,2/3] [v1,3/3]
  -Add of_device_id of MT8195 in [v1,3/3]
  -use more proper prefixes, such as "dt-bindings: mediatek: mt8195:"
  -provide more information in the cover letter

Christine Zhu (2):
  dt-bindings: reset: mt8195: add toprgu reset-controller header file
  watchdog: mediatek: mt8195: add wdt support

 drivers/watchdog/mtk_wdt.c                |  6 +++++
 include/dt-bindings/reset/mt8195-resets.h | 29 +++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt8195-resets.h


From Christine.Zhu at mediatek.com  Mon Aug 23 23:26:36 2021
From: Christine.Zhu at mediatek.com (Christine Zhu)
Date: Tue, 24 Aug 2021 14:26:36 +0800
Subject: [RESEND v8,2/2] watchdog: mediatek: mt8195: add wdt support
In-Reply-To: <20210824062633.14374-1-Christine.Zhu@mediatek.com>
References: <20210824062633.14374-1-Christine.Zhu@mediatek.com>
Message-ID: <20210824062633.14374-3-Christine.Zhu@mediatek.com>

Support MT8195 watchdog device.

Signed-off-by: Christine Zhu <Christine.Zhu at mediatek.com>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
---
 drivers/watchdog/mtk_wdt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index 16b6aff324a7..796fbb048cbe 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -12,6 +12,7 @@
 #include <dt-bindings/reset-controller/mt2712-resets.h>
 #include <dt-bindings/reset-controller/mt8183-resets.h>
 #include <dt-bindings/reset-controller/mt8192-resets.h>
+#include <dt-bindings/reset/mt8195-resets.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/init.h>
@@ -82,6 +83,10 @@ static const struct mtk_wdt_data mt8192_data = {
 	.toprgu_sw_rst_num = MT8192_TOPRGU_SW_RST_NUM,
 };
 
+static const struct mtk_wdt_data mt8195_data = {
+	.toprgu_sw_rst_num = MT8195_TOPRGU_SW_RST_NUM,
+};
+
 static int toprgu_reset_update(struct reset_controller_dev *rcdev,
 			       unsigned long id, bool assert)
 {
@@ -408,6 +413,7 @@ static const struct of_device_id mtk_wdt_dt_ids[] = {
 	{ .compatible = "mediatek,mt6589-wdt" },
 	{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
 	{ .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
+	{ .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
-- 
2.18.0

From Christine.Zhu at mediatek.com  Mon Aug 23 23:26:35 2021
From: Christine.Zhu at mediatek.com (Christine Zhu)
Date: Tue, 24 Aug 2021 14:26:35 +0800
Subject: [RESEND v8,
 1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header
 file
In-Reply-To: <20210824062633.14374-1-Christine.Zhu@mediatek.com>
References: <20210824062633.14374-1-Christine.Zhu@mediatek.com>
Message-ID: <20210824062633.14374-2-Christine.Zhu@mediatek.com>

Add toprgu reset-controller header file for MT8195 platform.

Signed-off-by: Christine Zhu <Christine.Zhu at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
---
 include/dt-bindings/reset/mt8195-resets.h | 29 +++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt8195-resets.h

diff --git a/include/dt-bindings/reset/mt8195-resets.h b/include/dt-bindings/reset/mt8195-resets.h
new file mode 100644
index 000000000000..a26bccc8b957
--- /dev/null
+++ b/include/dt-bindings/reset/mt8195-resets.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)*/
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Christine Zhu <christine.zhu at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8195
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8195
+
+#define MT8195_TOPRGU_CONN_MCU_SW_RST          0
+#define MT8195_TOPRGU_INFRA_GRST_SW_RST        1
+#define MT8195_TOPRGU_APU_SW_RST               2
+#define MT8195_TOPRGU_INFRA_AO_GRST_SW_RST     6
+#define MT8195_TOPRGU_MMSYS_SW_RST             7
+#define MT8195_TOPRGU_MFG_SW_RST               8
+#define MT8195_TOPRGU_VENC_SW_RST              9
+#define MT8195_TOPRGU_VDEC_SW_RST              10
+#define MT8195_TOPRGU_IMG_SW_RST               11
+#define MT8195_TOPRGU_APMIXEDSYS_SW_RST        13
+#define MT8195_TOPRGU_AUDIO_SW_RST             14
+#define MT8195_TOPRGU_CAMSYS_SW_RST            15
+#define MT8195_TOPRGU_EDPTX_SW_RST             16
+#define MT8195_TOPRGU_ADSPSYS_SW_RST           21
+#define MT8195_TOPRGU_DPTX_SW_RST              22
+#define MT8195_TOPRGU_SPMI_MST_SW_RST          23
+
+#define MT8195_TOPRGU_SW_RST_NUM               16
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
-- 
2.18.0

From ada at thorsis.com  Mon Aug 23 23:37:02 2021
From: ada at thorsis.com (Alexander Dahl)
Date: Tue, 24 Aug 2021 08:37:02 +0200
Subject: [RFC PATCH] USB: host: ehci-atmel: Allow enabling HSIC on SAMA5D2
In-Reply-To: <20210823140052.GA120849@rowland.harvard.edu>
References: <20210823140052.GA120849@rowland.harvard.edu>
Message-ID: <20210824063702.24586-1-ada@thorsis.com>

Unlike other SoC series featuring the 'atmel,at91sam9g45-ehci' USB EHCI
controller, which have embedded USB high-speed transceivers for each
port, the third port on the SAMA5D2 series is HSIC only.  That HSIC
interface is not enabled after a power-on reset, but can be enabled by
setting a flag in a vendor specific EHCI register.

The register offsets added to the new header file were compared with
those for the SAM9G45, SAM9X25, SAMA5D3, SAMA5D4, and SAM9X60 series and
there are no differences in the offsets or contents of those registers.
Which of those additional vendor specific registers are supported,
differs by SoC family.  So while the HSIC enable feature is currently
only present for SAMA5D2, it probably does not hurt to set it on the
other families, hence no additional check for SoC family here.

Tested on a custom board featuring a SAMA5D27C-D5M SiP connected to an
USB3503 hub with an upstream HSIC interface.

Link: https://community.atmel.com/forum/sama5d2-using-hsic-under-linux
Signed-off-by: Alexander Dahl <ada at thorsis.com>
---

Notes:
    - for introducing new dt binding, would be nice to convert old one
      first, probably needs split up and multiple iteration review?
    - name of that new dt property?
    - register definitions put to a separate file, like
      'drivers/usb/host/ehci-fsl.h'
    - unsure where exactly in the probe process that register write should
      happen, datasheet gives no hint
    - should suspend/resume be considered?

 drivers/usb/host/ehci-atmel.c | 17 +++++++++++++++++
 drivers/usb/host/ehci-atmel.h | 19 +++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 drivers/usb/host/ehci-atmel.h

diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index e893467d659c..f8d9e686c082 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -20,6 +20,7 @@
 #include <linux/usb/hcd.h>
 
 #include "ehci.h"
+#include "ehci-atmel.h"
 
 #define DRIVER_DESC "EHCI Atmel driver"
 
@@ -85,6 +86,7 @@ static void atmel_stop_ehci(struct platform_device *pdev)
 
 static int ehci_atmel_drv_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct usb_hcd *hcd;
 	const struct hc_driver *driver = &ehci_atmel_hc_driver;
 	struct resource *res;
@@ -149,6 +151,14 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
 
 	atmel_start_ehci(pdev);
 
+	if (of_property_read_bool(np, "atmel,enable-hsic")) {
+		u32 tmp;
+
+		tmp = ehci_readl(ehci, hcd->regs + AT91_UHPHS_INSNREG08);
+		tmp |= AT91_UHPHS_HSIC_EN;
+		ehci_writel(ehci, tmp, hcd->regs + AT91_UHPHS_INSNREG08);
+	}
+
 	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (retval)
 		goto fail_add_hcd;
@@ -170,10 +180,17 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
 static int ehci_atmel_drv_remove(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ehci_hcd *ehci;
+	u32 tmp;
 
 	usb_remove_hcd(hcd);
 	usb_put_hcd(hcd);
 
+	ehci = hcd_to_ehci(hcd);
+	tmp = ehci_readl(ehci, hcd->regs + AT91_UHPHS_INSNREG08);
+	tmp &= ~AT91_UHPHS_HSIC_EN;
+	ehci_writel(ehci, tmp, hcd->regs + AT91_UHPHS_INSNREG08);
+
 	atmel_stop_ehci(pdev);
 
 	return 0;
diff --git a/drivers/usb/host/ehci-atmel.h b/drivers/usb/host/ehci-atmel.h
new file mode 100644
index 000000000000..4c4998c2a6dd
--- /dev/null
+++ b/drivers/usb/host/ehci-atmel.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Vendor specific definitions for EHCI on Atmel/Microchip SoCs.
+ *
+ * ? 2021 Alexander Dahl <ada at thorsis.com>
+ */
+#ifndef EHCI_ATMEL_H
+#define EHCI_ATMEL_H
+
+/* device specific register offsets, taken from SAMA5D2 datasheet */
+
+#define AT91_UHPHS_INSNREG06    0xA8        /* AHB Error Status Register */
+
+#define AT91_UHPHS_INSNREG07    0xAC        /* AHB Master Error Address Register */
+
+#define AT91_UHPHS_INSNREG08    0xB0        /* HSIC Enable/Disable Register */
+#define AT91_UHPHS_HSIC_EN      (1 << 2)    /* HSIC Enable/Disable */
+
+#endif /* ECHI_ATMEL_H */

base-commit: e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93
-- 
2.30.2



From gregkh at linuxfoundation.org  Mon Aug 23 23:45:25 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 24 Aug 2021 08:45:25 +0200
Subject: [RFC PATCH] USB: host: ehci-atmel: Allow enabling HSIC on SAMA5D2
In-Reply-To: <20210824063702.24586-1-ada@thorsis.com>
References: <20210823140052.GA120849@rowland.harvard.edu>
 <20210824063702.24586-1-ada@thorsis.com>
Message-ID: <YSSVhblgt/45TvzF@kroah.com>

On Tue, Aug 24, 2021 at 08:37:02AM +0200, Alexander Dahl wrote:
> Unlike other SoC series featuring the 'atmel,at91sam9g45-ehci' USB EHCI
> controller, which have embedded USB high-speed transceivers for each
> port, the third port on the SAMA5D2 series is HSIC only.  That HSIC
> interface is not enabled after a power-on reset, but can be enabled by
> setting a flag in a vendor specific EHCI register.
> 
> The register offsets added to the new header file were compared with
> those for the SAM9G45, SAM9X25, SAMA5D3, SAMA5D4, and SAM9X60 series and
> there are no differences in the offsets or contents of those registers.
> Which of those additional vendor specific registers are supported,
> differs by SoC family.  So while the HSIC enable feature is currently
> only present for SAMA5D2, it probably does not hurt to set it on the
> other families, hence no additional check for SoC family here.
> 
> Tested on a custom board featuring a SAMA5D27C-D5M SiP connected to an
> USB3503 hub with an upstream HSIC interface.
> 
> Link: https://community.atmel.com/forum/sama5d2-using-hsic-under-linux
> Signed-off-by: Alexander Dahl <ada at thorsis.com>
> ---
> 
> Notes:
>     - for introducing new dt binding, would be nice to convert old one
>       first, probably needs split up and multiple iteration review?
>     - name of that new dt property?
>     - register definitions put to a separate file, like
>       'drivers/usb/host/ehci-fsl.h'
>     - unsure where exactly in the probe process that register write should
>       happen, datasheet gives no hint
>     - should suspend/resume be considered?
> 
>  drivers/usb/host/ehci-atmel.c | 17 +++++++++++++++++
>  drivers/usb/host/ehci-atmel.h | 19 +++++++++++++++++++

No need for a new .h file that is only used in a single .c file.  Just
put those few lines in the .c file please.

thanks,

greg k-h


From cgel.zte at gmail.com  Mon Aug 23 23:51:31 2021
From: cgel.zte at gmail.com (CGEL)
Date: Mon, 23 Aug 2021 23:51:31 -0700
Subject: [PATCH linux-next] tools:signal: fix boolreturn.cocci warnings
Message-ID: <20210824065131.60346-1-deng.changcheng@zte.com.cn>

From: Jing Yangyang <jing.yangyang at zte.com.cn>

./tools/testing/selftests/arm64/signal/test_signals_utils.h:112:9-10
WARNING: return of 0/1 in function 'get_current_context' with
return type bool

Return statements in functions returning bool should use true/false
instead of 1/0.

Generated by: scripts/coccinelle/misc/boolreturn.cocci

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Jing Yangyang <jing.yangyang at zte.com.cn>
---
 tools/testing/selftests/arm64/signal/test_signals_utils.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
index 6772b5c..66122e6 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
@@ -109,7 +109,7 @@ static __always_inline bool get_current_context(struct tdescr *td,
 	if (seen_already) {
 		fprintf(stdout,
 			"Unexpected successful sigreturn detected: live_uc is stale !\n");
-		return 0;
+		return false;
 	}
 	seen_already = 1;
 
-- 
1.8.3.1




From leo.yan at linaro.org  Mon Aug 23 23:53:19 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 24 Aug 2021 14:53:19 +0800
Subject: [PATCH v2 2/9] perf cs-etm: Initialise architecture based on
 TRCIDR1
In-Reply-To: <20210806134109.1182235-3-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
 <20210806134109.1182235-3-james.clark@arm.com>
Message-ID: <20210824065319.GA204566@leoy-ThinkPad-X240s>

On Fri, Aug 06, 2021 at 02:41:02PM +0100, James Clark wrote:
> Currently the architecture is hard coded as ARCH_V8, but from ETMv4.4
> onwards this should be ARCH_AA64.
> 
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> index 187c038caa19..787b19642e78 100644
> --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> @@ -126,6 +126,20 @@ static int cs_etm_decoder__gen_etmv3_config(struct cs_etm_trace_params *params,
>  	return 0;
>  }
>  
> +#define TRCIDR1_TRCARCHMIN_SHIFT 4
> +#define TRCIDR1_TRCARCHMIN_MASK  GENMASK(7, 4)
> +#define TRCIDR1_TRCARCHMIN(x)    (((x) & TRCIDR1_TRCARCHMIN_MASK) >> TRCIDR1_TRCARCHMIN_SHIFT)
> +static enum _ocsd_arch_version cs_etm_decoder__get_etmv4_arch_ver(u32 reg_idr1)
> +{
> +	/*
> +	 * For ETMv4 if the trace minor version is 4 or more then we can assume
> +	 * the architecture is ARCH_AA64 rather than just V8.
> +	 * ARCH_V8 = V8 architecture
> +	 * ARCH_AA64 = Min v8r3 plus additional AA64 PE features
> +	 */
> +	return TRCIDR1_TRCARCHMIN(reg_idr1) >= 4 ? ARCH_AA64 : ARCH_V8;
> +}
> +
>  static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params,
>  					     ocsd_etmv4_cfg *config)
>  {
> @@ -140,7 +154,7 @@ static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params,
>  	config->reg_idr11 = 0;
>  	config->reg_idr12 = 0;
>  	config->reg_idr13 = 0;
> -	config->arch_ver = ARCH_V8;
> +	config->arch_ver = cs_etm_decoder__get_etmv4_arch_ver(params->etmv4.reg_idr1);
>  	config->core_prof = profile_CortexA;
>  }

Reviewed-by: Leo Yan <leo.yan at linaro.org>

>  
> -- 
> 2.28.0
> 


From leo.yan at linaro.org  Mon Aug 23 23:58:48 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 24 Aug 2021 14:58:48 +0800
Subject: [PATCH v2 3/9] perf cs-etm: Refactor out ETMv4 header saving
In-Reply-To: <20210806134109.1182235-4-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
 <20210806134109.1182235-4-james.clark@arm.com>
Message-ID: <20210824065848.GB204566@leoy-ThinkPad-X240s>

On Fri, Aug 06, 2021 at 02:41:03PM +0100, James Clark wrote:
> Extract a function for saving the ETMv4 header because this will be used
> for ETE in a later commit.
> 
> Signed-off-by: James Clark <james.clark at arm.com>

Reviewed-by: Leo Yan <leo.yan at linaro.org>

> ---
>  tools/perf/arch/arm/util/cs-etm.c | 46 +++++++++++++++----------------
>  1 file changed, 23 insertions(+), 23 deletions(-)
> 
> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> index 85168d87b2d7..ecb6fa55a210 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -607,6 +607,28 @@ static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
>  	return val;
>  }
>  
> +static void cs_etm_save_etmv4_header(__u64 data[], struct auxtrace_record *itr, int cpu)
> +{
> +	struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr);
> +	struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
> +
> +	/* Get trace configuration register */
> +	data[CS_ETMV4_TRCCONFIGR] = cs_etmv4_get_config(itr);
> +	/* Get traceID from the framework */
> +	data[CS_ETMV4_TRCTRACEIDR] = coresight_get_trace_id(cpu);
> +	/* Get read-only information from sysFS */
> +	data[CS_ETMV4_TRCIDR0] = cs_etm_get_ro(cs_etm_pmu, cpu,
> +					       metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
> +	data[CS_ETMV4_TRCIDR1] = cs_etm_get_ro(cs_etm_pmu, cpu,
> +					       metadata_etmv4_ro[CS_ETMV4_TRCIDR1]);
> +	data[CS_ETMV4_TRCIDR2] = cs_etm_get_ro(cs_etm_pmu, cpu,
> +					       metadata_etmv4_ro[CS_ETMV4_TRCIDR2]);
> +	data[CS_ETMV4_TRCIDR8] = cs_etm_get_ro(cs_etm_pmu, cpu,
> +					       metadata_etmv4_ro[CS_ETMV4_TRCIDR8]);
> +	data[CS_ETMV4_TRCAUTHSTATUS] = cs_etm_get_ro(cs_etm_pmu, cpu,
> +						     metadata_etmv4_ro[CS_ETMV4_TRCAUTHSTATUS]);
> +}
> +
>  static void cs_etm_get_metadata(int cpu, u32 *offset,
>  				struct auxtrace_record *itr,
>  				struct perf_record_auxtrace_info *info)
> @@ -620,29 +642,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
>  	/* first see what kind of tracer this cpu is affined to */
>  	if (cs_etm_is_etmv4(itr, cpu)) {
>  		magic = __perf_cs_etmv4_magic;
> -		/* Get trace configuration register */
> -		info->priv[*offset + CS_ETMV4_TRCCONFIGR] =
> -						cs_etmv4_get_config(itr);
> -		/* Get traceID from the framework */
> -		info->priv[*offset + CS_ETMV4_TRCTRACEIDR] =
> -						coresight_get_trace_id(cpu);
> -		/* Get read-only information from sysFS */
> -		info->priv[*offset + CS_ETMV4_TRCIDR0] =
> -			cs_etm_get_ro(cs_etm_pmu, cpu,
> -				      metadata_etmv4_ro[CS_ETMV4_TRCIDR0]);
> -		info->priv[*offset + CS_ETMV4_TRCIDR1] =
> -			cs_etm_get_ro(cs_etm_pmu, cpu,
> -				      metadata_etmv4_ro[CS_ETMV4_TRCIDR1]);
> -		info->priv[*offset + CS_ETMV4_TRCIDR2] =
> -			cs_etm_get_ro(cs_etm_pmu, cpu,
> -				      metadata_etmv4_ro[CS_ETMV4_TRCIDR2]);
> -		info->priv[*offset + CS_ETMV4_TRCIDR8] =
> -			cs_etm_get_ro(cs_etm_pmu, cpu,
> -				      metadata_etmv4_ro[CS_ETMV4_TRCIDR8]);
> -		info->priv[*offset + CS_ETMV4_TRCAUTHSTATUS] =
> -			cs_etm_get_ro(cs_etm_pmu, cpu,
> -				      metadata_etmv4_ro
> -				      [CS_ETMV4_TRCAUTHSTATUS]);
> +		cs_etm_save_etmv4_header(&info->priv[*offset], itr, cpu);
>  
>  		/* How much space was used */
>  		increment = CS_ETMV4_PRIV_MAX;
> -- 
> 2.28.0
> 


From hsinyi at chromium.org  Tue Aug 24 00:10:12 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Tue, 24 Aug 2021 15:10:12 +0800
Subject: [PATCH v2 11/29] iommu/mediatek: Always pm_runtime_get while tlb
 flush
In-Reply-To: <20210813065324.29220-12-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
 <20210813065324.29220-12-yong.wu@mediatek.com>
Message-ID: <CAJMQK-hkufqh2vaEKcuO+k0v2SzpCHcyZuEqrvJ__rrAek2P0A@mail.gmail.com>

On Fri, Aug 13, 2021 at 2:57 PM Yong Wu <yong.wu at mediatek.com> wrote:
>
> Prepare for 2 HWs that sharing pgtable in different power-domains.
>
> The previous SoC don't have PM. Only mt8192 has power-domain,
> and it is display's power-domain which nearly always is enabled.
>
> When there are 2 M4U HWs, it may has problem.
> In this function, we get the pm_status via the m4u dev, but it don't
> reflect the real power-domain status of the HW since there may be other
> HW also use that power-domain.
>
> Currently we could not get the real power-domain status, thus always
> pm_runtime_get here.
>
> Prepare for mt8195, thus, no need fix tags here.
>
> This patch may drop the performance, we expect the user could
> pm_runtime_get_sync before dma_alloc_attrs which need tlb ops.

Can you check if there are existing users that need to add this change?


>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
<snip>


From leo.yan at linaro.org  Tue Aug 24 00:14:36 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 24 Aug 2021 15:14:36 +0800
Subject: [PATCH v2 4/9] perf cs-etm: Save TRCDEVARCH register
In-Reply-To: <20210806134109.1182235-5-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
 <20210806134109.1182235-5-james.clark@arm.com>
Message-ID: <20210824071436.GC204566@leoy-ThinkPad-X240s>

On Fri, Aug 06, 2021 at 02:41:04PM +0100, James Clark wrote:
> When ETE is present save the TRCDEVARCH register and set a new magic
> number. It will be used to configure the decoder in a later commit.
> 
> Old versions of perf will not be able to open files with this new magic
> number, but old files will still work with newer versions of perf.
> 
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  tools/perf/arch/arm/util/cs-etm.c | 49 +++++++++++++++++++++++++++----
>  tools/perf/util/cs-etm.c          | 16 ++++++++--
>  tools/perf/util/cs-etm.h          | 10 +++++++
>  3 files changed, 68 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> index ecb6fa55a210..e3500b79d972 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -47,15 +47,17 @@ static const char *metadata_etmv3_ro[CS_ETM_PRIV_MAX] = {
>  	[CS_ETM_ETMIDR]		= "mgmt/etmidr",
>  };
>  
> -static const char *metadata_etmv4_ro[CS_ETMV4_PRIV_MAX] = {
> +static const char * const metadata_etmv4_ro[] = {
>  	[CS_ETMV4_TRCIDR0]		= "trcidr/trcidr0",
>  	[CS_ETMV4_TRCIDR1]		= "trcidr/trcidr1",
>  	[CS_ETMV4_TRCIDR2]		= "trcidr/trcidr2",
>  	[CS_ETMV4_TRCIDR8]		= "trcidr/trcidr8",
>  	[CS_ETMV4_TRCAUTHSTATUS]	= "mgmt/trcauthstatus",
> +	[CS_ETE_TRCDEVARCH]		= "mgmt/trcdevarch"
>  };
>  
>  static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu);
> +static bool cs_etm_is_ete(struct auxtrace_record *itr, int cpu);
>  
>  static int cs_etm_set_context_id(struct auxtrace_record *itr,
>  				 struct evsel *evsel, int cpu)
> @@ -533,7 +535,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>  		      struct evlist *evlist __maybe_unused)
>  {
>  	int i;
> -	int etmv3 = 0, etmv4 = 0;
> +	int etmv3 = 0, etmv4 = 0, ete = 0;
>  	struct perf_cpu_map *event_cpus = evlist->core.cpus;
>  	struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL);
>  
> @@ -544,7 +546,9 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>  			    !cpu_map__has(online_cpus, i))
>  				continue;
>  
> -			if (cs_etm_is_etmv4(itr, i))
> +			if (cs_etm_is_ete(itr, i))
> +				ete++;
> +			else if (cs_etm_is_etmv4(itr, i))
>  				etmv4++;
>  			else
>  				etmv3++;
> @@ -555,7 +559,9 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>  			if (!cpu_map__has(online_cpus, i))
>  				continue;
>  
> -			if (cs_etm_is_etmv4(itr, i))
> +			if (cs_etm_is_ete(itr, i))
> +				ete++;
> +			else if (cs_etm_is_etmv4(itr, i))
>  				etmv4++;
>  			else
>  				etmv3++;
> @@ -565,6 +571,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
>  	perf_cpu_map__put(online_cpus);
>  
>  	return (CS_ETM_HEADER_SIZE +
> +	       (ete   * CS_ETE_PRIV_SIZE) +
>  	       (etmv4 * CS_ETMV4_PRIV_SIZE) +
>  	       (etmv3 * CS_ETMV3_PRIV_SIZE));
>  }
> @@ -607,6 +614,27 @@ static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
>  	return val;
>  }
>  
> +#define TRCDEVARCH_ARCHPART_SHIFT 0
> +#define TRCDEVARCH_ARCHPART_MASK  GENMASK(11, 0)
> +#define TRCDEVARCH_ARCHPART(x)    (((x) & TRCDEVARCH_ARCHPART_MASK) >> TRCDEVARCH_ARCHPART_SHIFT)
> +
> +#define TRCDEVARCH_ARCHVER_SHIFT 12
> +#define TRCDEVARCH_ARCHVER_MASK  GENMASK(15, 12)
> +#define TRCDEVARCH_ARCHVER(x)    (((x) & TRCDEVARCH_ARCHVER_MASK) >> TRCDEVARCH_ARCHVER_SHIFT)
> +
> +static bool cs_etm_is_ete(struct auxtrace_record *itr, int cpu)
> +{
> +	struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr);
> +	struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
> +	int trcdevarch = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETE_TRCDEVARCH]);
> +
> +	/*
> +	 * ETE if ARCHVER is 5 (ARCHVER is 4 for ETM) and ARCHPART is 0xA13.
> +	 * See ETM_DEVARCH_ETE_ARCH in coresight-etm4x.h
> +	 */
> +	return TRCDEVARCH_ARCHVER(trcdevarch) == 5 && TRCDEVARCH_ARCHPART(trcdevarch) == 0xA13;
> +}
> +
>  static void cs_etm_save_etmv4_header(__u64 data[], struct auxtrace_record *itr, int cpu)
>  {
>  	struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr);
> @@ -640,7 +668,18 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
>  	struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
>  
>  	/* first see what kind of tracer this cpu is affined to */
> -	if (cs_etm_is_etmv4(itr, cpu)) {
> +	if (cs_etm_is_ete(itr, cpu)) {
> +		magic = __perf_cs_ete_magic;
> +		/* ETE uses the same registers as ETMv4 plus TRCDEVARCH */
> +		cs_etm_save_etmv4_header(&info->priv[*offset], itr, cpu);
> +		info->priv[*offset + CS_ETE_TRCDEVARCH] =
> +			cs_etm_get_ro(cs_etm_pmu, cpu,
> +				      metadata_etmv4_ro[CS_ETE_TRCDEVARCH]);
> +
> +		/* How much space was used */
> +		increment = CS_ETE_PRIV_MAX;
> +		nr_trc_params = CS_ETE_PRIV_MAX - CS_ETM_COMMON_BLK_MAX_V1;
> +	} else if (cs_etm_is_etmv4(itr, cpu)) {
>  		magic = __perf_cs_etmv4_magic;
>  		cs_etm_save_etmv4_header(&info->priv[*offset], itr, cpu);
>  
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index f4b2bff533f3..d540512a3c96 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -2512,6 +2512,7 @@ static const char * const cs_etmv4_priv_fmts[] = {
>  	[CS_ETMV4_TRCIDR2]	= "	TRCIDR2			       %llx\n",
>  	[CS_ETMV4_TRCIDR8]	= "	TRCIDR8			       %llx\n",
>  	[CS_ETMV4_TRCAUTHSTATUS] = "	TRCAUTHSTATUS		       %llx\n",
> +	[CS_ETE_TRCDEVARCH]	= "	TRCDEVARCH                     %llx\n"
>  };
>  
>  static const char * const param_unk_fmt =
> @@ -2571,10 +2572,15 @@ static int cs_etm__print_cpu_metadata_v1(__u64 *val, int *offset)
>  			else
>  				fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
>  		}
> -	} else if (magic == __perf_cs_etmv4_magic) {
> +	} else if (magic == __perf_cs_etmv4_magic || magic == __perf_cs_ete_magic) {
> +		/*
> +		 * ETE and ETMv4 can be printed in the same block because the number of parameters
> +		 * is saved and they share the list of parameter names. ETE is also only supported
> +		 * in V1 files.
> +		 */
>  		for (j = 0; j < total_params; j++, i++) {
>  			/* if newer record - could be excess params */
> -			if (j >= CS_ETMV4_PRIV_MAX)
> +			if (j >= CS_ETE_PRIV_MAX)
>  				fprintf(stdout, param_unk_fmt, j, val[i]);
>  			else
>  				fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
> @@ -2943,6 +2949,12 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
>  
>  			/* The traceID is our handle */
>  			trcidr_idx = CS_ETMV4_TRCTRACEIDR;
> +		} else if (ptr[i] == __perf_cs_ete_magic) {
> +			metadata[j] =
> +				cs_etm__create_meta_blk(ptr, &i, CS_ETE_PRIV_MAX, -1);

The last parameter is passed with '-1', means the ETE metadata block
uses version 1, nr_params_v0 is not used thus pass '-1' for it.

It is fine for me.

> +
> +			/* ETE shares first part of metadata with ETMv4 */
> +			trcidr_idx = CS_ETMV4_TRCTRACEIDR;
>  		}
>  
>  		if (!metadata[j]) {
> diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h
> index d65c7b19407d..08b84c21f065 100644
> --- a/tools/perf/util/cs-etm.h
> +++ b/tools/perf/util/cs-etm.h
> @@ -76,6 +76,14 @@ enum {
>  /* define fixed version 0 length - allow new format reader to read old files. */
>  #define CS_ETMV4_NR_TRC_PARAMS_V0 (CS_ETMV4_TRCAUTHSTATUS - CS_ETMV4_TRCCONFIGR + 1)
>  
> +/* ETE metadata is ETMv4 plus TRCDEVARCH register and doesn't support header V0 since it was
> + * added in header V1
> + */
> +enum {
> +	CS_ETE_TRCDEVARCH = CS_ETMV4_PRIV_MAX,
> +	CS_ETE_PRIV_MAX
> +};
> +
>  /*
>   * ETMv3 exception encoding number:
>   * See Embedded Trace Macrocell specification (ARM IHI 0014Q)
> @@ -187,8 +195,10 @@ struct cs_etm_packet_queue {
>  
>  #define __perf_cs_etmv3_magic 0x3030303030303030ULL
>  #define __perf_cs_etmv4_magic 0x4040404040404040ULL
> +#define __perf_cs_ete_magic   0x5050505050505050ULL
>  #define CS_ETMV3_PRIV_SIZE (CS_ETM_PRIV_MAX * sizeof(u64))
>  #define CS_ETMV4_PRIV_SIZE (CS_ETMV4_PRIV_MAX * sizeof(u64))
> +#define CS_ETE_PRIV_SIZE (CS_ETE_PRIV_MAX * sizeof(u64))

I went through the patch twice and looks good to me:

Reviewed-by: Leo Yan <leo.yan at linaro.org>

>  
>  #ifdef HAVE_CSTRACE_SUPPORT
>  int cs_etm__process_auxtrace_info(union perf_event *event,
> -- 
> 2.28.0
> 


From leo.yan at linaro.org  Tue Aug 24 00:15:12 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 24 Aug 2021 15:15:12 +0800
Subject: [PATCH v2 5/9] perf cs-etm: Fix typo
In-Reply-To: <20210806134109.1182235-6-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
 <20210806134109.1182235-6-james.clark@arm.com>
Message-ID: <20210824071512.GD204566@leoy-ThinkPad-X240s>

On Fri, Aug 06, 2021 at 02:41:05PM +0100, James Clark wrote:
> TRCIRD2 should be TRCIDR2
> 
> Signed-off-by: James Clark <james.clark at arm.com>

Reviewed-by: Leo Yan <leo.yan at linaro.org>

> ---
>  tools/perf/arch/arm/util/cs-etm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> index e3500b79d972..515aae470e23 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -75,7 +75,7 @@ static int cs_etm_set_context_id(struct auxtrace_record *itr,
>  	if (!cs_etm_is_etmv4(itr, cpu))
>  		goto out;
>  
> -	/* Get a handle on TRCIRD2 */
> +	/* Get a handle on TRCIDR2 */
>  	snprintf(path, PATH_MAX, "cpu%d/%s",
>  		 cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR2]);
>  	err = perf_pmu__scan_file(cs_etm_pmu, path, "%x", &val);
> -- 
> 2.28.0
> 


From hsinyi at chromium.org  Tue Aug 24 00:35:05 2021
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Tue, 24 Aug 2021 15:35:05 +0800
Subject: [PATCH v2 16/29] iommu/mediatek: Adjust device link when it is
 sub-common
In-Reply-To: <20210813065324.29220-17-yong.wu@mediatek.com>
References: <20210813065324.29220-1-yong.wu@mediatek.com>
 <20210813065324.29220-17-yong.wu@mediatek.com>
Message-ID: <CAJMQK-ir-wLy4OHkWEWZf=CZcURMhRvHnOjBLWXaezhukJh2JA@mail.gmail.com>

On Fri, Aug 13, 2021 at 3:03 PM Yong Wu <yong.wu at mediatek.com> wrote:
>
> For MM IOMMU, We always add device link between smi-common and IOMMU HW.
> In mt8195, we add smi-sub-common. Thus, if the node is sub-common, we still
> need find again to get smi-common, then do device link.
>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>  drivers/iommu/mtk_iommu.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index a4479916ad33..a72241724adb 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -845,6 +845,17 @@ static int mtk_iommu_mm_dts_parse(struct device *dev,
>         if (!smicomm_node)
>                 return -EINVAL;
>
> +       /* Find smi-common again if this is smi-sub-common */
> +       if (of_property_read_bool(smicomm_node, "mediatek,smi_sub_common")) {
> +               of_node_put(smicomm_node); /* put the sub common */
> +
> +               smicomm_node = of_parse_phandle(smicomm_node, "mediatek,smi", 0);

This only checks 1 level here, and does not check if the mediatek,smi
of a sub-common node is not another sub-common node.
So maybe add a check that the updated node here doesn't have
mediatek,smi_sub_common property.

> +               if (!smicomm_node) {
> +                       dev_err(dev, "sub-comm has no common.\n");
> +                       return -EINVAL;
> +               }
> +       }
> +
>         plarbdev = of_find_device_by_node(smicomm_node);
>         of_node_put(smicomm_node);
>         data->smicomm_dev = &plarbdev->dev;
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From vladimir.murzin at arm.com  Tue Aug 24 01:25:39 2021
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Tue, 24 Aug 2021 09:25:39 +0100
Subject: [PATCH linux-next] arm:nommu: fix boolreturn.cocci warnings
In-Reply-To: <20210824041112.57915-1-deng.changcheng@zte.com.cn>
References: <20210824041112.57915-1-deng.changcheng@zte.com.cn>
Message-ID: <328bbb63-f8a6-2c50-2264-1fd404ff1f9d@arm.com>

On 8/24/21 5:11 AM, CGEL wrote:
> From: Jing Yangyang <jing.yangyang at zte.com.cn>
> 
> ./arch/arm/mm/nommu.c:59:8-9:WARNING:return of 0/1 in function
> 'security_extensions_enabled' with return type bool
> 
> Return statements in functions returning bool should use true/false
> instead of 1/0.
> 
> Generated by: scripts/coccinelle/misc/boolreturn.cocci
> 
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: Jing Yangyang <jing.yangyang at zte.com.cn>
> ---
>  arch/arm/mm/nommu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
> index 2658f52..7256ac1 100644
> --- a/arch/arm/mm/nommu.c
> +++ b/arch/arm/mm/nommu.c
> @@ -56,7 +56,7 @@ static inline bool security_extensions_enabled(void)
>  	if ((read_cpuid_id() & 0x000f0000) == 0x000f0000)
>  		return cpuid_feature_extract(CPUID_EXT_PFR1, 4) ||
>  			cpuid_feature_extract(CPUID_EXT_PFR1, 20);
> -	return 0;
> +	return false;
>  }
>  
>  unsigned long setup_vectors_base(void)
> 

The same patch was sent before [1] by Huilong Deng. It was reviewed
and author was advised to submit it into RMK's Patch system.  


[1] https://lore.kernel.org/linux-arm-kernel/1e30b659-a91a-58f6-f9aa-d0f0259eb9e8 at arm.com/T/#t

Cheers
Vladimir


From leo.yan at linaro.org  Tue Aug 24 01:33:05 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 24 Aug 2021 16:33:05 +0800
Subject: [PATCH v2 7/9] perf cs-etm: Create ETE decoder
In-Reply-To: <20210806134109.1182235-8-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
 <20210806134109.1182235-8-james.clark@arm.com>
Message-ID: <20210824083305.GE204566@leoy-ThinkPad-X240s>

On Fri, Aug 06, 2021 at 02:41:07PM +0100, James Clark wrote:
> If the magic number indicates ETE instantiate a OCSD_BUILTIN_DCD_ETE
> decoder instead of OCSD_BUILTIN_DCD_ETMV4I. ETE is the new trace feature
> for Armv9.
> 
> Testing performed
> =================
> 
> * Old files with v0 and v1 headers for ETMv4 still open correctly
> * New files with new magic number open on new versions of perf
> * New files with new magic number fail to open on old versions of perf
> * Decoding with the ETE decoder results in the same output as the ETMv4
>   decoder as long as there are no new ETE packet types
> 
> Signed-off-by: James Clark <james.clark at arm.com>
>
> ---
>  .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 20 +++++++++++++++++++
>  .../perf/util/cs-etm-decoder/cs-etm-decoder.h | 12 +++++++++++
>  tools/perf/util/cs-etm.c                      | 18 +++++++++++++++++
>  3 files changed, 50 insertions(+)
> 
> diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> index 12cee321fbf2..3071e5deddcc 100644
> --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
> @@ -156,6 +156,20 @@ static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params,
>  	config->core_prof = profile_CortexA;
>  }
>  
> +static void cs_etm_decoder__gen_ete_config(struct cs_etm_trace_params *params,
> +					   ocsd_ete_cfg *config)
> +{
> +	config->reg_configr = params->ete.reg_configr;
> +	config->reg_traceidr = params->ete.reg_traceidr;
> +	config->reg_idr0 = params->ete.reg_idr0;
> +	config->reg_idr1 = params->ete.reg_idr1;
> +	config->reg_idr2 = params->ete.reg_idr2;
> +	config->reg_idr8 = params->ete.reg_idr8;
> +	config->reg_devarch = params->ete.reg_devarch;
> +	config->arch_ver = ARCH_AA64;

Just a nitpick: if we connect with patch 02, it implement function
cs_etm_decoder__get_etmv4_arch_ver().  We can extend it to a more
general function cs_etm_decoder__get_arch_ver(); this can allow us to
have a central place to calculate 'arch_ver' for different archs.

I understand your patch doesn't want to mix things between ETMv4 and
ETE, either way is okay for me:

Reviewed-by: Leo Yan <leo.yan at linaro.org>

> +	config->core_prof = profile_CortexA;
> +}
> +
>  static void cs_etm_decoder__print_str_cb(const void *p_context,
>  					 const char *msg,
>  					 const int str_len)
> @@ -603,6 +617,7 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
>  	const char *decoder_name;
>  	ocsd_etmv3_cfg config_etmv3;
>  	ocsd_etmv4_cfg trace_config_etmv4;
> +	ocsd_ete_cfg trace_config_ete;
>  	void *trace_config;
>  	u8 csid;
>  
> @@ -620,6 +635,11 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params,
>  		decoder_name = OCSD_BUILTIN_DCD_ETMV4I;
>  		trace_config = &trace_config_etmv4;
>  		break;
> +	case CS_ETM_PROTO_ETE:
> +		cs_etm_decoder__gen_ete_config(t_params, &trace_config_ete);
> +		decoder_name = OCSD_BUILTIN_DCD_ETE;
> +		trace_config = &trace_config_ete;
> +		break;
>  	default:
>  		return -1;
>  	}
> diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
> index 11f3391d06f2..0102ece5ca3e 100644
> --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
> +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
> @@ -37,11 +37,22 @@ struct cs_etmv4_trace_params {
>  	u32 reg_traceidr;
>  };
>  
> +struct cs_ete_trace_params {
> +	u32 reg_idr0;
> +	u32 reg_idr1;
> +	u32 reg_idr2;
> +	u32 reg_idr8;
> +	u32 reg_configr;
> +	u32 reg_traceidr;
> +	u32 reg_devarch;
> +};
> +
>  struct cs_etm_trace_params {
>  	int protocol;
>  	union {
>  		struct cs_etmv3_trace_params etmv3;
>  		struct cs_etmv4_trace_params etmv4;
> +		struct cs_ete_trace_params ete;
>  	};
>  };
>  
> @@ -65,6 +76,7 @@ enum {
>  	CS_ETM_PROTO_ETMV4i,
>  	CS_ETM_PROTO_ETMV4d,
>  	CS_ETM_PROTO_PTM,
> +	CS_ETM_PROTO_ETE
>  };
>  
>  enum cs_etm_decoder_operation {
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index d540512a3c96..e5649e9ea140 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -460,6 +460,21 @@ static void cs_etm__set_trace_param_etmv4(struct cs_etm_trace_params *t_params,
>  	t_params[idx].etmv4.reg_traceidr = metadata[idx][CS_ETMV4_TRCTRACEIDR];
>  }
>  
> +static void cs_etm__set_trace_param_ete(struct cs_etm_trace_params *t_params,
> +					  struct cs_etm_auxtrace *etm, int idx)
> +{
> +	u64 **metadata = etm->metadata;
> +
> +	t_params[idx].protocol = CS_ETM_PROTO_ETE;
> +	t_params[idx].ete.reg_idr0 = metadata[idx][CS_ETMV4_TRCIDR0];
> +	t_params[idx].ete.reg_idr1 = metadata[idx][CS_ETMV4_TRCIDR1];
> +	t_params[idx].ete.reg_idr2 = metadata[idx][CS_ETMV4_TRCIDR2];
> +	t_params[idx].ete.reg_idr8 = metadata[idx][CS_ETMV4_TRCIDR8];
> +	t_params[idx].ete.reg_configr = metadata[idx][CS_ETMV4_TRCCONFIGR];
> +	t_params[idx].ete.reg_traceidr = metadata[idx][CS_ETMV4_TRCTRACEIDR];
> +	t_params[idx].ete.reg_devarch = metadata[idx][CS_ETE_TRCDEVARCH];
> +}
> +
>  static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params,
>  				     struct cs_etm_auxtrace *etm,
>  				     int decoders)
> @@ -479,6 +494,9 @@ static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params,
>  		case __perf_cs_etmv4_magic:
>  			cs_etm__set_trace_param_etmv4(t_params, etm, i);
>  			break;
> +		case __perf_cs_ete_magic:
> +			cs_etm__set_trace_param_ete(t_params, etm, i);
> +			break;
>  		default:
>  			return -EINVAL;
>  		}
> -- 
> 2.28.0
> 


From leo.yan at linaro.org  Tue Aug 24 01:36:15 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 24 Aug 2021 16:36:15 +0800
Subject: [PATCH v2 9/9] perf cs-etm: Show a warning for an unknown magic
 number
In-Reply-To: <20210806134109.1182235-10-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
 <20210806134109.1182235-10-james.clark@arm.com>
Message-ID: <20210824083615.GF204566@leoy-ThinkPad-X240s>

On Fri, Aug 06, 2021 at 02:41:09PM +0100, James Clark wrote:
> Currently perf reports "Cannot allocate memory" which isn't very helpful
> for a potentially user facing issue. If we add a new magic number in
> the future, perf will be able to report unrecognised magic numbers.
> 
> Signed-off-by: James Clark <james.clark at arm.com>

Reviewed-by: Leo Yan <leo.yan at linaro.org>

> ---
>  tools/perf/util/cs-etm.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index 788ad5a099f6..5b276bdb96a6 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -2973,6 +2973,11 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
>  
>  			/* ETE shares first part of metadata with ETMv4 */
>  			trcidr_idx = CS_ETMV4_TRCTRACEIDR;
> +		} else {
> +			ui__error("CS ETM Trace: Unrecognised magic number %#"PRIx64". File could be from a newer version of perf.\n",
> +				  ptr[i]);
> +			err = -EINVAL;
> +			goto err_free_metadata;
>  		}
>  
>  		if (!metadata[j]) {
> -- 
> 2.28.0
> 


From leo.yan at linaro.org  Tue Aug 24 01:47:20 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 24 Aug 2021 16:47:20 +0800
Subject: [PATCH v2 0/9] Support ETE decoding
In-Reply-To: <20210806134109.1182235-1-james.clark@arm.com>
References: <20210806134109.1182235-1-james.clark@arm.com>
Message-ID: <20210824084720.GG204566@leoy-ThinkPad-X240s>

Hi Mathieu, Suzuki, Mike,

On Fri, Aug 06, 2021 at 02:41:00PM +0100, James Clark wrote:
> Changes since v1:
>  * Re-implement with a new magic number instead of piggybacking on ETMv4
>  * Improve comments and function name around cs_etm_decoder__get_etmv4_arch_ver()
>  * Add a warning for unrecognised magic numbers
>  * Split typo fix into new commit
>  * Add Leo's reviewed-by tags
>  * Create a new struct for ETE config (cs_ete_trace_params) instead of re-using ETMv4 config
> 
> Applies to perf/core f3c33cbd922
> Also available at https://gitlab.arm.com/linux-arm/linux-jc/-/tree/james-ete-v2

I have finished the review for this patch series and it's good form for
me.  Since this patch series is to enable new feature for ETE, it's
good if any of you could review as well before merging.

Thanks,
Leo


From Fengquan.Chen at mediatek.com  Tue Aug 24 02:23:10 2021
From: Fengquan.Chen at mediatek.com (Fengquan Chen)
Date: Tue, 24 Aug 2021 17:23:10 +0800
Subject: [PATCH] [v5,
 1/1] clocksource/drivers/timer-mediatek: optimize systimer irq clear
 flow on shutdown
In-Reply-To: <1629796990-28361-1-git-send-email-Fengquan.Chen@mediatek.com>
References: <1629796990-28361-1-git-send-email-Fengquan.Chen@mediatek.com>
Message-ID: <1629796990-28361-2-git-send-email-Fengquan.Chen@mediatek.com>

From: "fengquan.chen" <fengquan.chen at mediatek.com>

mtk_syst_clkevt_shutdown is called after irq disabled in suspend flow,
clear any pending systimer irq when shutdown to avoid suspend aborted
due to timer irq pending

Also as for systimer in mediatek socs, there must be firstly enable
timer before clear systimer irq

Fixes: e3af677607d9("clocksource/drivers/timer-mediatek: Add support for system timer")
Signed-off-by: Fengquan Chen <fengquan.chen at mediatek.com>
---
 drivers/clocksource/timer-mediatek.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index 9318edc..6461fd3 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -60,9 +60,9 @@
  * SYST_CON_EN: Clock enable. Shall be set to
  *   - Start timer countdown.
  *   - Allow timeout ticks being updated.
- *   - Allow changing interrupt functions.
+ *   - Allow changing interrupt status,like clear irq pending.
  *
- * SYST_CON_IRQ_EN: Set to allow interrupt.
+ * SYST_CON_IRQ_EN: Set to enable interrupt.
  *
  * SYST_CON_IRQ_CLR: Set to clear interrupt.
  */
@@ -75,6 +75,7 @@
 static void mtk_syst_ack_irq(struct timer_of *to)
 {
 	/* Clear and disable interrupt */
+	writel(SYST_CON_EN, SYST_CON_REG(to));
 	writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to));
 }
 
@@ -111,6 +112,9 @@ static int mtk_syst_clkevt_next_event(unsigned long ticks,
 
 static int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt)
 {
+	/* Clear any irq */
+	mtk_syst_ack_irq(to_timer_of(clkevt));
+
 	/* Disable timer */
 	writel(0, SYST_CON_REG(to_timer_of(clkevt)));
 
-- 
1.8.1.1.dirty

From Fengquan.Chen at mediatek.com  Tue Aug 24 02:23:09 2021
From: Fengquan.Chen at mediatek.com (Fengquan Chen)
Date: Tue, 24 Aug 2021 17:23:09 +0800
Subject: [v5,
 1/1] clocksource/drivers/timer-mediatek: optimize systimer irq clear
 flow on shutdown
Message-ID: <1629796990-28361-1-git-send-email-Fengquan.Chen@mediatek.com>

From: "fengquan.chen" <fengquan.chen at mediatek.com>

mtk_syst_clkevt_shutdown is called after irq disabled in suspend flow,
clear any pending systimer irq when shutdown to avoid suspend aborted
due to timer irq pending

Also as for systimer in mediatek socs, there must be firstly enable
timer before clear systimer irq

fengquan.chen (1):
  [v5, 1/1] clocksource/drivers/timer-mediatek: optimize systimer irq   
     clear flow on shutdown

 drivers/clocksource/timer-mediatek.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

-- 
1.8.1.1.dirty

From sam.shih at mediatek.com  Tue Aug 24 02:29:03 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 24 Aug 2021 17:29:03 +0800
Subject: [v3,
 04/12] pinctrl: mediatek: moore: check if pin_desc is valid before use
Message-ID: <20210824092904.25439-1-sam.shih@mediatek.com>

Certain SoC are missing the middle part gpios in consecutive pins,
it's better to check if mtk_pin_desc is a valid pin for the extensibility

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Acked-by: Sean Wang <sean.wang at mediatek.com>

---
v3: added an Acked-by tag.
v2: applied the comment suggested by reviewers:
    - for the pins not ballout, we can fill .name in struct mtk_pin_desc
      as NULL and return -ENOTSUPP in gpio/pinconf ops.
---
 drivers/pinctrl/mediatek/pinctrl-moore.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c
index 3a4a23c40a71..ad3b67163973 100644
--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
+++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
@@ -60,6 +60,8 @@ static int mtk_pinmux_set_mux(struct pinctrl_dev *pctldev,
 		int pin = grp->pins[i];
 
 		desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+		if (!desc->name)
+			return -ENOTSUPP;
 
 		mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
 				 pin_modes[i]);
@@ -76,6 +78,8 @@ static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	const struct mtk_pin_desc *desc;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE,
 				hw->soc->gpio_m);
@@ -89,6 +93,8 @@ static int mtk_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 	const struct mtk_pin_desc *desc;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	/* hardware would take 0 as input direction */
 	return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !input);
@@ -103,6 +109,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 	const struct mtk_pin_desc *desc;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	switch (param) {
 	case PIN_CONFIG_BIAS_DISABLE:
@@ -218,6 +226,8 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 	int cfg, err = 0;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	for (cfg = 0; cfg < num_configs; cfg++) {
 		param = pinconf_to_config_param(configs[cfg]);
@@ -435,6 +445,8 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
 	int value, err;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
 	if (err)
@@ -449,6 +461,10 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
 	const struct mtk_pin_desc *desc;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+	if (!desc->name) {
+		dev_err(hw->dev, "Failed to set gpio %d\n", gpio);
+		return;
+	}
 
 	mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
 }
@@ -490,6 +506,8 @@ static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
 	u32 debounce;
 
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset];
+	if (!desc->name)
+		return -ENOTSUPP;
 
 	if (!hw->eint ||
 	    pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE ||
-- 
2.29.2

From sam.shih at mediatek.com  Tue Aug 24 02:29:04 2021
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 24 Aug 2021 17:29:04 +0800
Subject: [v3,06/12] pinctrl: mediatek: add support for MT7986 SoC
In-Reply-To: <20210824092904.25439-1-sam.shih@mediatek.com>
References: <20210824092904.25439-1-sam.shih@mediatek.com>
Message-ID: <20210824092904.25439-2-sam.shih@mediatek.com>

This commit includes pinctrl driver for Mediatek MT7986

The difference of pinctrl between mt7986a and mt7986b
is that pin-41 to pin-65 do not exist on mt7986b

Signed-off-by: Sam Shih <sam.shih at mediatek.com>

---
v3: applied the comment suggested by reviewers:
    - merge the consecutive entries into one to reduce the table size
    - set .name to NULL to indicate the pin is not ball out
v2: applied the comment suggested by reviewers:
    - for the pins not ballout, we can fill .name in struct mtk_pin_desc
      as NULL and return -ENOTSUPP in gpio/pinconf ops.
---
 drivers/pinctrl/mediatek/Kconfig          |   7 +
 drivers/pinctrl/mediatek/Makefile         |   1 +
 drivers/pinctrl/mediatek/pinctrl-mt7986.c | 928 ++++++++++++++++++++++
 3 files changed, 936 insertions(+)
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c

diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 7040a7a7bd5d..66db4ac5d169 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -119,6 +119,13 @@ config PINCTRL_MT7622
 	default ARM64 && ARCH_MEDIATEK
 	select PINCTRL_MTK_MOORE
 
+config PINCTRL_MT7986
+	bool "Mediatek MT7986 pin control"
+	depends on OF
+	depends on ARM64 || COMPILE_TEST
+	default ARM64 && ARCH_MEDIATEK
+	select PINCTRL_MTK_MOORE
+
 config PINCTRL_MT8167
 	bool "Mediatek MT8167 pin control"
 	depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 1bb7f9c65bc2..1e3931d924e7 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_MT6797)	+= pinctrl-mt6797.o
 obj-$(CONFIG_PINCTRL_MT7622)	+= pinctrl-mt7622.o
 obj-$(CONFIG_PINCTRL_MT7623)	+= pinctrl-mt7623.o
 obj-$(CONFIG_PINCTRL_MT7629)	+= pinctrl-mt7629.o
+obj-$(CONFIG_PINCTRL_MT7986)	+= pinctrl-mt7986.o
 obj-$(CONFIG_PINCTRL_MT8167)	+= pinctrl-mt8167.o
 obj-$(CONFIG_PINCTRL_MT8173)	+= pinctrl-mt8173.o
 obj-$(CONFIG_PINCTRL_MT8183)	+= pinctrl-mt8183.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
new file mode 100644
index 000000000000..df839c7ff7dd
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
@@ -0,0 +1,928 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7986 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ */
+
+#include "pinctrl-moore.h"
+
+#define MT7986_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
+#define MT7986_NOT_BALLOUT_PIN(_number) { .number = _number, .name = NULL }
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,	\
+			_x_bits)	\
+		PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,	\
+			_x_bits, 32, 0)
+
+/**
+ * enum - Locking variants of the iocfg bases
+ *
+ * MT7986 have multiple bases to program pin configuration listed as the below:
+ * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000,
+ * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000,
+ * _i_based could be used to indicate what base the pin should be mapped into.
+ *
+ * Each iocfg register base control different group of pads on the SoC
+ *
+ *
+ *  chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 | o  o  o  o  o  o  o  o |
+ *  7 | o  o  o  o  o  o  o  o |
+ *  6 | o  o  o  o  o  o  o  o |
+ *  5 | o  o  o  o  o  o  o  o |
+ *  4 | o  o  o  o  o  o  o  o |
+ *  3 | o  o  o  o  o  o  o  o |
+ *  2 | o  o  o  o  o  o  o  o |
+ *  1 | o  o  o  o  o  o  o  o |
+ *    +------------------------+
+ *
+ *  inside Chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 |                        |
+ *  7 |        TL  TR          |
+ *  6 |      +---------+       |
+ *  5 |   LT |         | RT    |
+ *  4 |      |         |       |
+ *  3 |   LB |         | RB    |
+ *  2 |      +---------+       |
+ *  1 |                        |
+ *    +------------------------+
+ *
+ */
+
+enum {
+	GPIO_BASE,
+	IOCFG_RT_BASE,
+	IOCFG_RB_BASE,
+	IOCFG_LT_BASE,
+	IOCFG_LB_BASE,
+	IOCFG_TR_BASE,
+	IOCFG_TL_BASE,
+};
+
+static const char *const mt7986_pinctrl_register_base_names[] = {
+	"gpio_base", "iocfg_rt_base", "iocfg_rb_base", "iocfg_lt_base",
+	"iocfg_lb_base", "iocfg_tr_base", "iocfg_tl_base",
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = {
+	PIN_FIELD(0, 100, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = {
+	PIN_FIELD(0, 100, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_di_range[] = {
+	PIN_FIELD(0, 100, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_do_range[] = {
+	PIN_FIELD(0, 100, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x20, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x20, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x30, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x30, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x30, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x30, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x30, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x20, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x20, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x20, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x20, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x20, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x40, 0x10, 22, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x40, 0x10, 20, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x40, 0x10, 26, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x40, 0x10, 24, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x40, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x20, 0x10, 2, 1),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x30, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x30, 0x10, 6, 1),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x30, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x30, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x30, 0x10, 12, 1),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x30, 0x10, 2, 1),
+	PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x30, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_smt_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0xf0, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x90, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0xf0, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x90, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0xf0, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0xf0, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0xc0, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0xc0, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0xc0, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0xc0, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0xc0, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0xc0, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0xc0, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0xc0, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x90, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x90, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x90, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x90, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x90, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0xf0, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0xf0, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0xf0, 0x10, 22, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0xf0, 0x10, 20, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0xf0, 0x10, 26, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0xf0, 0x10, 24, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0xc0, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0xc0, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0xc0, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0xc0, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0xf0, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0xf0, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0xf0, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0xf0, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x90, 0x10, 2, 1),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x80, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x80, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x80, 0x10, 6, 1),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x80, 0x10, 9, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x80, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x70, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x70, 0x10, 4, 1),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x70, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pu_range[] = {
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x50, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x50, 0x10, 6, 1),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x50, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x50, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pd_range[] = {
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x40, 0x10, 16, 1),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x40, 0x10, 6, 1),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x40, 0x10, 14, 1),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x40, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_drv_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x00, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(11, 12, IOCFG_RB_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(13, 14, IOCFG_RB_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x10, 0x10, 24, 3),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x10, 0x10, 21, 3),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x20, 0x10, 6, 3),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x00, 0x10, 21, 3),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x10, 0x10, 27, 3),
+	PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x20, 0x10, 0, 3),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x20, 0x10, 9, 3),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x20, 0x10, 3, 3),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x20, 0x10, 21, 3),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x20, 0x10, 15, 3),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x10, 0x10, 15, 3),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x10, 0x10, 9, 3),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x00, 0x10, 2, 3),
+	PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x10, 0x10, 18, 3),
+	PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(74, 77, IOCFG_TR_BASE, 0x00, 0x10, 15, 3),
+	PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x00, 0x10, 27, 3),
+	PIN_FIELD_BASE(81, 84, IOCFG_TR_BASE, 0x10, 0x10, 0, 3),
+	PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x00, 0x10, 3, 3),
+	PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x00, 0x10, 0, 3),
+	PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x10, 0x10, 12, 3),
+	PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x10, 0x10, 6, 3),
+	PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x00, 0x10, 12, 3),
+	PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x00, 0x10, 6, 3),
+	PIN_FIELD_BASE(97, 98, IOCFG_TL_BASE, 0x00, 0x10, 24, 3),
+	PIN_FIELD_BASE(99, 100, IOCFG_TL_BASE, 0x10, 0x10, 2, 3),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x30, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x30, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x60, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x40, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x40, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x40, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x40, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x40, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x40, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x40, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x40, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x30, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x30, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x30, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x30, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 22, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 20, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 26, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 24, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x60, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x60, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x60, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x60, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x40, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x70, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x40, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x70, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x40, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x70, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x70, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x50, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x50, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x50, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x50, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x50, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x50, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x50, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x50, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x40, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x40, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x40, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x40, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 22, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 20, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 26, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 24, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x70, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x70, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x70, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x70, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x50, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = {
+	PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x80, 0x10, 17, 1),
+	PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x50, 0x10, 10, 1),
+	PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x80, 0x10, 0, 1),
+	PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x50, 0x10, 0, 1),
+	PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x80, 0x10, 8, 1),
+	PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x80, 0x10, 2, 1),
+	PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x60, 0x10, 12, 1),
+	PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x60, 0x10, 18, 1),
+	PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x60, 0x10, 17, 1),
+	PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x60, 0x10, 15, 1),
+	PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x60, 0x10, 19, 1),
+	PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x60, 0x10, 23, 1),
+	PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x60, 0x10, 22, 1),
+	PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x60, 0x10, 21, 1),
+	PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x50, 0x10, 4, 1),
+	PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x50, 0x10, 8, 1),
+	PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x50, 0x10, 7, 1),
+	PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x50, 0x10, 5, 1),
+	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1),
+	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1),
+	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1),
+	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 22, 1),
+	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 20, 1),
+	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 26, 1),
+	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 24, 1),
+	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1),
+	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1),
+	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1),
+	PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x60, 0x10, 10, 1),
+	PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x80, 0x10, 15, 1),
+	PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x80, 0x10, 14, 1),
+	PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x80, 0x10, 13, 1),
+	PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x80, 0x10, 16, 1),
+	PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_reg_calc mt7986_reg_cals[] = {
+	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range),
+	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range),
+	[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7986_pin_di_range),
+	[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7986_pin_do_range),
+	[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7986_pin_smt_range),
+	[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7986_pin_ies_range),
+	[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7986_pin_drv_range),
+	[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7986_pin_pu_range),
+	[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7986_pin_pd_range),
+	[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7986_pin_pupd_range),
+	[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7986_pin_r0_range),
+	[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7986_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7986a_pins[] = {
+	MT7986_PIN(0, "SYS_WATCHDOG"),
+	MT7986_PIN(1, "WF2G_LED"),
+	MT7986_PIN(2, "WF5G_LED"),
+	MT7986_PIN(3, "I2C_SCL"),
+	MT7986_PIN(4, "I2C_SDA"),
+	MT7986_PIN(5, "GPIO_0"),
+	MT7986_PIN(6, "GPIO_1"),
+	MT7986_PIN(7, "GPIO_2"),
+	MT7986_PIN(8, "GPIO_3"),
+	MT7986_PIN(9, "GPIO_4"),
+	MT7986_PIN(10, "GPIO_5"),
+	MT7986_PIN(11, "GPIO_6"),
+	MT7986_PIN(12, "GPIO_7"),
+	MT7986_PIN(13, "GPIO_8"),
+	MT7986_PIN(14, "GPIO_9"),
+	MT7986_PIN(15, "GPIO_10"),
+	MT7986_PIN(16, "GPIO_11"),
+	MT7986_PIN(17, "GPIO_12"),
+	MT7986_PIN(18, "GPIO_13"),
+	MT7986_PIN(19, "GPIO_14"),
+	MT7986_PIN(20, "GPIO_15"),
+	MT7986_PIN(21, "PWM0"),
+	MT7986_PIN(22, "PWM1"),
+	MT7986_PIN(23, "SPI0_CLK"),
+	MT7986_PIN(24, "SPI0_MOSI"),
+	MT7986_PIN(25, "SPI0_MISO"),
+	MT7986_PIN(26, "SPI0_CS"),
+	MT7986_PIN(27, "SPI0_HOLD"),
+	MT7986_PIN(28, "SPI0_WP"),
+	MT7986_PIN(29, "SPI1_CLK"),
+	MT7986_PIN(30, "SPI1_MOSI"),
+	MT7986_PIN(31, "SPI1_MISO"),
+	MT7986_PIN(32, "SPI1_CS"),
+	MT7986_PIN(33, "SPI2_CLK"),
+	MT7986_PIN(34, "SPI2_MOSI"),
+	MT7986_PIN(35, "SPI2_MISO"),
+	MT7986_PIN(36, "SPI2_CS"),
+	MT7986_PIN(37, "SPI2_HOLD"),
+	MT7986_PIN(38, "SPI2_WP"),
+	MT7986_PIN(39, "UART0_RXD"),
+	MT7986_PIN(40, "UART0_TXD"),
+	MT7986_PIN(41, "PCIE_PERESET_N"),
+	MT7986_PIN(42, "UART1_RXD"),
+	MT7986_PIN(43, "UART1_TXD"),
+	MT7986_PIN(44, "UART1_CTS"),
+	MT7986_PIN(45, "UART1_RTS"),
+	MT7986_PIN(46, "UART2_RXD"),
+	MT7986_PIN(47, "UART2_TXD"),
+	MT7986_PIN(48, "UART2_CTS"),
+	MT7986_PIN(49, "UART2_RTS"),
+	MT7986_PIN(50, "EMMC_DATA_0"),
+	MT7986_PIN(51, "EMMC_DATA_1"),
+	MT7986_PIN(52, "EMMC_DATA_2"),
+	MT7986_PIN(53, "EMMC_DATA_3"),
+	MT7986_PIN(54, "EMMC_DATA_4"),
+	MT7986_PIN(55, "EMMC_DATA_5"),
+	MT7986_PIN(56, "EMMC_DATA_6"),
+	MT7986_PIN(57, "EMMC_DATA_7"),
+	MT7986_PIN(58, "EMMC_CMD"),
+	MT7986_PIN(59, "EMMC_CK"),
+	MT7986_PIN(60, "EMMC_DSL"),
+	MT7986_PIN(61, "EMMC_RSTB"),
+	MT7986_PIN(62, "PCM_DTX"),
+	MT7986_PIN(63, "PCM_DRX"),
+	MT7986_PIN(64, "PCM_CLK"),
+	MT7986_PIN(65, "PCM_FS"),
+	MT7986_PIN(66, "MT7531_INT"),
+	MT7986_PIN(67, "SMI_MDC"),
+	MT7986_PIN(68, "SMI_MDIO"),
+	MT7986_PIN(69, "WF0_DIG_RESETB"),
+	MT7986_PIN(70, "WF0_CBA_RESETB"),
+	MT7986_PIN(71, "WF0_XO_REQ"),
+	MT7986_PIN(72, "WF0_TOP_CLK"),
+	MT7986_PIN(73, "WF0_TOP_DATA"),
+	MT7986_PIN(74, "WF0_HB1"),
+	MT7986_PIN(75, "WF0_HB2"),
+	MT7986_PIN(76, "WF0_HB3"),
+	MT7986_PIN(77, "WF0_HB4"),
+	MT7986_PIN(78, "WF0_HB0"),
+	MT7986_PIN(79, "WF0_HB0_B"),
+	MT7986_PIN(80, "WF0_HB5"),
+	MT7986_PIN(81, "WF0_HB6"),
+	MT7986_PIN(82, "WF0_HB7"),
+	MT7986_PIN(83, "WF0_HB8"),
+	MT7986_PIN(84, "WF0_HB9"),
+	MT7986_PIN(85, "WF0_HB10"),
+	MT7986_PIN(86, "WF1_DIG_RESETB"),
+	MT7986_PIN(87, "WF1_CBA_RESETB"),
+	MT7986_PIN(88, "WF1_XO_REQ"),
+	MT7986_PIN(89, "WF1_TOP_CLK"),
+	MT7986_PIN(90, "WF1_TOP_DATA"),
+	MT7986_PIN(91, "WF1_HB1"),
+	MT7986_PIN(92, "WF1_HB2"),
+	MT7986_PIN(93, "WF1_HB3"),
+	MT7986_PIN(94, "WF1_HB4"),
+	MT7986_PIN(95, "WF1_HB0"),
+	MT7986_PIN(96, "WF1_HB0_B"),
+	MT7986_PIN(97, "WF1_HB5"),
+	MT7986_PIN(98, "WF1_HB6"),
+	MT7986_PIN(99, "WF1_HB7"),
+	MT7986_PIN(100, "WF1_HB8"),
+};
+
+static const struct mtk_pin_desc mt7986b_pins[] = {
+	MT7986_PIN(0, "SYS_WATCHDOG"),
+	MT7986_PIN(1, "WF2G_LED"),
+	MT7986_PIN(2, "WF5G_LED"),
+	MT7986_PIN(3, "I2C_SCL"),
+	MT7986_PIN(4, "I2C_SDA"),
+	MT7986_PIN(5, "GPIO_0"),
+	MT7986_PIN(6, "GPIO_1"),
+	MT7986_PIN(7, "GPIO_2"),
+	MT7986_PIN(8, "GPIO_3"),
+	MT7986_PIN(9, "GPIO_4"),
+	MT7986_PIN(10, "GPIO_5"),
+	MT7986_PIN(11, "GPIO_6"),
+	MT7986_PIN(12, "GPIO_7"),
+	MT7986_PIN(13, "GPIO_8"),
+	MT7986_PIN(14, "GPIO_9"),
+	MT7986_PIN(15, "GPIO_10"),
+	MT7986_PIN(16, "GPIO_11"),
+	MT7986_PIN(17, "GPIO_12"),
+	MT7986_PIN(18, "GPIO_13"),
+	MT7986_PIN(19, "GPIO_14"),
+	MT7986_PIN(20, "GPIO_15"),
+	MT7986_PIN(21, "PWM0"),
+	MT7986_PIN(22, "PWM1"),
+	MT7986_PIN(23, "SPI0_CLK"),
+	MT7986_PIN(24, "SPI0_MOSI"),
+	MT7986_PIN(25, "SPI0_MISO"),
+	MT7986_PIN(26, "SPI0_CS"),
+	MT7986_PIN(27, "SPI0_HOLD"),
+	MT7986_PIN(28, "SPI0_WP"),
+	MT7986_PIN(29, "SPI1_CLK"),
+	MT7986_PIN(30, "SPI1_MOSI"),
+	MT7986_PIN(31, "SPI1_MISO"),
+	MT7986_PIN(32, "SPI1_CS"),
+	MT7986_PIN(33, "SPI2_CLK"),
+	MT7986_PIN(34, "SPI2_MOSI"),
+	MT7986_PIN(35, "SPI2_MISO"),
+	MT7986_PIN(36, "SPI2_CS"),
+	MT7986_PIN(37, "SPI2_HOLD"),
+	MT7986_PIN(38, "SPI2_WP"),
+	MT7986_PIN(39, "UART0_RXD"),
+	MT7986_PIN(40, "UART0_TXD"),
+	MT7986_NOT_BALLOUT_PIN(41),
+	MT7986_NOT_BALLOUT_PIN(42),
+	MT7986_NOT_BALLOUT_PIN(43),
+	MT7986_NOT_BALLOUT_PIN(44),
+	MT7986_NOT_BALLOUT_PIN(45),
+	MT7986_NOT_BALLOUT_PIN(46),
+	MT7986_NOT_BALLOUT_PIN(47),
+	MT7986_NOT_BALLOUT_PIN(48),
+	MT7986_NOT_BALLOUT_PIN(49),
+	MT7986_NOT_BALLOUT_PIN(50),
+	MT7986_NOT_BALLOUT_PIN(51),
+	MT7986_NOT_BALLOUT_PIN(52),
+	MT7986_NOT_BALLOUT_PIN(53),
+	MT7986_NOT_BALLOUT_PIN(54),
+	MT7986_NOT_BALLOUT_PIN(55),
+	MT7986_NOT_BALLOUT_PIN(56),
+	MT7986_NOT_BALLOUT_PIN(57),
+	MT7986_NOT_BALLOUT_PIN(58),
+	MT7986_NOT_BALLOUT_PIN(59),
+	MT7986_NOT_BALLOUT_PIN(60),
+	MT7986_NOT_BALLOUT_PIN(61),
+	MT7986_NOT_BALLOUT_PIN(62),
+	MT7986_NOT_BALLOUT_PIN(63),
+	MT7986_NOT_BALLOUT_PIN(64),
+	MT7986_NOT_BALLOUT_PIN(65),
+	MT7986_PIN(66, "MT7531_INT"),
+	MT7986_PIN(67, "SMI_MDC"),
+	MT7986_PIN(68, "SMI_MDIO"),
+	MT7986_PIN(69, "WF0_DIG_RESETB"),
+	MT7986_PIN(70, "WF0_CBA_RESETB"),
+	MT7986_PIN(71, "WF0_XO_REQ"),
+	MT7986_PIN(72, "WF0_TOP_CLK"),
+	MT7986_PIN(73, "WF0_TOP_DATA"),
+	MT7986_PIN(74, "WF0_HB1"),
+	MT7986_PIN(75, "WF0_HB2"),
+	MT7986_PIN(76, "WF0_HB3"),
+	MT7986_PIN(77, "WF0_HB4"),
+	MT7986_PIN(78, "WF0_HB0"),
+	MT7986_PIN(79, "WF0_HB0_B"),
+	MT7986_PIN(80, "WF0_HB5"),
+	MT7986_PIN(81, "WF0_HB6"),
+	MT7986_PIN(82, "WF0_HB7"),
+	MT7986_PIN(83, "WF0_HB8"),
+	MT7986_PIN(84, "WF0_HB9"),
+	MT7986_PIN(85, "WF0_HB10"),
+	MT7986_PIN(86, "WF1_DIG_RESETB"),
+	MT7986_PIN(87, "WF1_CBA_RESETB"),
+	MT7986_PIN(88, "WF1_XO_REQ"),
+	MT7986_PIN(89, "WF1_TOP_CLK"),
+	MT7986_PIN(90, "WF1_TOP_DATA"),
+	MT7986_PIN(91, "WF1_HB1"),
+	MT7986_PIN(92, "WF1_HB2"),
+	MT7986_PIN(93, "WF1_HB3"),
+	MT7986_PIN(94, "WF1_HB4"),
+	MT7986_PIN(95, "WF1_HB0"),
+	MT7986_PIN(96, "WF1_HB0_B"),
+	MT7986_PIN(97, "WF1_HB5"),
+	MT7986_PIN(98, "WF1_HB6"),
+	MT7986_PIN(99, "WF1_HB7"),
+	MT7986_PIN(100, "WF1_HB8"),
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+static int mt7986_watchdog_pins[] = { 0, };
+static int mt7986_watchdog_funcs[] = { 1, };
+
+static int mt7986_wifi_led_pins[] = { 1, 2, };
+static int mt7986_wifi_led_funcs[] = { 1, 1, };
+
+static int mt7986_i2c_pins[] = { 3, 4, };
+static int mt7986_i2c_funcs[] = { 1, 1, };
+
+static int mt7986_uart1_0_pins[] = { 7, 8, 9, 10, };
+static int mt7986_uart1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_spi1_0_pins[] = { 11, 12, 13, 14, };
+static int mt7986_spi1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_pwm1_1_pins[] = { 20, };
+static int mt7986_pwm1_1_funcs[] = { 2, };
+
+static int mt7986_pwm0_pins[] = { 21, };
+static int mt7986_pwm0_funcs[] = { 1, };
+
+static int mt7986_pwm1_0_pins[] = { 22, };
+static int mt7986_pwm1_0_funcs[] = { 1, };
+
+static int mt7986_emmc_45_pins[] = {
+	22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, };
+static int mt7986_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_snfi_pins[] = { 23, 24, 25, 26, 27, 28, };
+static int mt7986_snfi_funcs[] = { 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_spi1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_spi1_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_uart1_1_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi0_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_spi0_wp_hold_pins[] = { 37, 38, };
+static int mt7986_spi0_wp_hold_funcs[] = { 1, 1, };
+
+static int mt7986_uart2_1_pins[] = { 33, 34, 35, 36, };
+static int mt7986_uart2_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_3_rx_tx_pins[] = { 35, 36, };
+static int mt7986_uart1_3_rx_tx_funcs[] = { 2, 2, };
+
+static int mt7986_uart1_3_cts_rts_pins[] = { 37, 38, };
+static int mt7986_uart1_3_cts_rts_funcs[] = { 2, 2, };
+
+static int mt7986_spi1_3_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi1_3_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_uart0_pins[] = { 39, 40, };
+static int mt7986_uart0_funcs[] = { 1, 1, };
+
+static int mt7986_pcie_reset_pins[] = { 41, };
+static int mt7986_pcie_reset_funcs[] = { 1, };
+
+static int mt7986_uart1_pins[] = { 42, 43, 44, 45, };
+static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart2_pins[] = { 46, 47, 48, 49, };
+static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_emmc_51_pins[] = {
+	50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, };
+static int mt7986_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_pcm_pins[] = { 62, 63, 64, 65, };
+static int mt7986_pcm_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_i2s_pins[] = { 62, 63, 64, 65, };
+static int mt7986_i2s_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_switch_int_pins[] = { 66, };
+static int mt7986_switch_int_funcs[] = { 1, };
+
+static int mt7986_mdc_mdio_pins[] = { 67, 68, };
+static int mt7986_mdc_mdio_funcs[] = { 1, 1, };
+
+static int mt7986_wf_2g_pins[] = {74, 75, 76, 77, 78, 79, 80, 81, 82, 83, };
+static int mt7986_wf_2g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_5g_pins[] = {91, 92, 93, 94, 95, 96, 97, 98, 99, 100, };
+static int mt7986_wf_5g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_dbdc_pins[] = {
+	74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, };
+static int mt7986_wf_dbdc_funcs[] = {
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_pcie_clk_pins[] = { 9, };
+static int mt7986_pcie_clk_funcs[] = { 1, };
+
+static int mt7986_pcie_wake_pins[] = { 10, };
+static int mt7986_pcie_wake_funcs[] = { 1, };
+
+static const struct group_desc mt7986_groups[] = {
+	PINCTRL_PIN_GROUP("watchdog", mt7986_watchdog),
+	PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led),
+	PINCTRL_PIN_GROUP("i2c", mt7986_i2c),
+	PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0),
+	PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk),
+	PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake),
+	PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0),
+	PINCTRL_PIN_GROUP("pwm1_1", mt7986_pwm1_1),
+	PINCTRL_PIN_GROUP("pwm0", mt7986_pwm0),
+	PINCTRL_PIN_GROUP("pwm1_0", mt7986_pwm1_0),
+	PINCTRL_PIN_GROUP("emmc_45", mt7986_emmc_45),
+	PINCTRL_PIN_GROUP("snfi", mt7986_snfi),
+	PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1),
+	PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1),
+	PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2),
+	PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2),
+	PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0),
+	PINCTRL_PIN_GROUP("spi0", mt7986_spi0),
+	PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold),
+	PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1),
+	PINCTRL_PIN_GROUP("uart1_3_rx_tx", mt7986_uart1_3_rx_tx),
+	PINCTRL_PIN_GROUP("uart1_3_cts_rts", mt7986_uart1_3_cts_rts),
+	PINCTRL_PIN_GROUP("spi1_3", mt7986_spi1_3),
+	PINCTRL_PIN_GROUP("uart0", mt7986_uart0),
+	PINCTRL_PIN_GROUP("switch_int", mt7986_switch_int),
+	PINCTRL_PIN_GROUP("mdc_mdio", mt7986_mdc_mdio),
+	PINCTRL_PIN_GROUP("pcie_pereset", mt7986_pcie_reset),
+	PINCTRL_PIN_GROUP("uart1", mt7986_uart1),
+	PINCTRL_PIN_GROUP("uart2", mt7986_uart2),
+	PINCTRL_PIN_GROUP("emmc_51", mt7986_emmc_51),
+	PINCTRL_PIN_GROUP("pcm", mt7986_pcm),
+	PINCTRL_PIN_GROUP("i2s", mt7986_i2s),
+	PINCTRL_PIN_GROUP("wf_2g", mt7986_wf_2g),
+	PINCTRL_PIN_GROUP("wf_5g", mt7986_wf_5g),
+	PINCTRL_PIN_GROUP("wf_dbdc", mt7986_wf_dbdc),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+
+static const char * const mt7986_audio_groups[] = { "pcm", "i2s" };
+static const char * const mt7986_emmc_groups[] = {
+	"emmc_45", "emmc_51", };
+static const char * const mt7986_ethernet_groups[] = {
+	"switch_int", "mdc_mdio", };
+static const char * const mt7986_i2c_groups[] = { "i2c", };
+static const char * const mt7986_led_groups[] = { "wifi_led", };
+static const char * const mt7986_flash_groups[] = { "snfi", };
+static const char * const mt7986_pcie_groups[] = {
+	"pcie_clk", "pcie_wake", "pcie_pereset" };
+static const char * const mt7986_pwm_groups[] = { "pwm0", "pwm1_0", "pwm1_1", };
+static const char * const mt7986_spi_groups[] = {
+	"spi0", "spi0_wp_hold", "spi1_0", "spi1_1", "spi1_2", "spi1_3", };
+static const char * const mt7986_uart_groups[] = {
+	"uart1_0", "uart1_1", "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts",
+	"uart2_0", "uart2_1", "uart0", "uart1", "uart2",
+};
+static const char * const mt7986_wdt_groups[] = { "watchdog", };
+static const char * const mt7986_wf_groups[] = { "wf_2g", "wf_5g", "wf_dbdc", };
+
+static const struct function_desc mt7986_functions[] = {
+	{"audio", mt7986_audio_groups, ARRAY_SIZE(mt7986_audio_groups)},
+	{"emmc", mt7986_emmc_groups, ARRAY_SIZE(mt7986_emmc_groups)},
+	{"eth", mt7986_ethernet_groups, ARRAY_SIZE(mt7986_ethernet_groups)},
+	{"i2c", mt7986_i2c_groups, ARRAY_SIZE(mt7986_i2c_groups)},
+	{"led", mt7986_led_groups, ARRAY_SIZE(mt7986_led_groups)},
+	{"flash", mt7986_flash_groups, ARRAY_SIZE(mt7986_flash_groups)},
+	{"pcie", mt7986_pcie_groups, ARRAY_SIZE(mt7986_pcie_groups)},
+	{"pwm", mt7986_pwm_groups, ARRAY_SIZE(mt7986_pwm_groups)},
+	{"spi", mt7986_spi_groups, ARRAY_SIZE(mt7986_spi_groups)},
+	{"uart", mt7986_uart_groups, ARRAY_SIZE(mt7986_uart_groups)},
+	{"watchdog", mt7986_wdt_groups, ARRAY_SIZE(mt7986_wdt_groups)},
+	{"wifi", mt7986_wf_groups, ARRAY_SIZE(mt7986_wf_groups)},
+};
+
+static const struct mtk_eint_hw mt7986a_eint_hw = {
+	.port_mask = 7,
+	.ports = 7,
+	.ap_num = ARRAY_SIZE(mt7986a_pins),
+	.db_cnt = 16,
+};
+
+static const struct mtk_eint_hw mt7986b_eint_hw = {
+	.port_mask = 7,
+	.ports = 7,
+	.ap_num = ARRAY_SIZE(mt7986b_pins),
+	.db_cnt = 16,
+};
+
+static struct mtk_pin_soc mt7986a_data = {
+	.reg_cal = mt7986_reg_cals,
+	.pins = mt7986a_pins,
+	.npins = ARRAY_SIZE(mt7986a_pins),
+	.grps = mt7986_groups,
+	.ngrps = ARRAY_SIZE(mt7986_groups),
+	.funcs = mt7986_functions,
+	.nfuncs = ARRAY_SIZE(mt7986_functions),
+	.eint_hw = &mt7986a_eint_hw,
+	.gpio_m = 0,
+	.ies_present = false,
+	.base_names = mt7986_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+	.bias_set_combo = mtk_pinconf_bias_set_combo,
+	.bias_get_combo = mtk_pinconf_bias_get_combo,
+	.drive_set = mtk_pinconf_drive_set_rev1,
+	.drive_get = mtk_pinconf_drive_get_rev1,
+	.adv_pull_get = mtk_pinconf_adv_pull_get,
+	.adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static struct mtk_pin_soc mt7986b_data = {
+	.reg_cal = mt7986_reg_cals,
+	.pins = mt7986b_pins,
+	.npins = ARRAY_SIZE(mt7986b_pins),
+	.grps = mt7986_groups,
+	.ngrps = ARRAY_SIZE(mt7986_groups),
+	.funcs = mt7986_functions,
+	.nfuncs = ARRAY_SIZE(mt7986_functions),
+	.eint_hw = &mt7986b_eint_hw,
+	.gpio_m = 0,
+	.ies_present = false,
+	.base_names = mt7986_pinctrl_register_base_names,
+	.nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+	.bias_set_combo = mtk_pinconf_bias_set_combo,
+	.bias_get_combo = mtk_pinconf_bias_get_combo,
+	.drive_set = mtk_pinconf_drive_set_rev1,
+	.drive_get = mtk_pinconf_drive_get_rev1,
+	.adv_pull_get = mtk_pinconf_adv_pull_get,
+	.adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static const struct of_device_id mt7986a_pinctrl_of_match[] = {
+	{.compatible = "mediatek,mt7986a-pinctrl",},
+	{}
+};
+
+static const struct of_device_id mt7986b_pinctrl_of_match[] = {
+	{.compatible = "mediatek,mt7986b-pinctrl",},
+	{}
+};
+
+static int mt7986a_pinctrl_probe(struct platform_device *pdev)
+{
+	return mtk_moore_pinctrl_probe(pdev, &mt7986a_data);
+}
+
+static int mt7986b_pinctrl_probe(struct platform_device *pdev)
+{
+	return mtk_moore_pinctrl_probe(pdev, &mt7986b_data);
+}
+
+static struct platform_driver mt7986a_pinctrl_driver = {
+	.driver = {
+		.name = "mt7986a-pinctrl",
+		.of_match_table = mt7986a_pinctrl_of_match,
+	},
+	.probe = mt7986a_pinctrl_probe,
+};
+
+static struct platform_driver mt7986b_pinctrl_driver = {
+	.driver = {
+		.name = "mt7986b-pinctrl",
+		.of_match_table = mt7986b_pinctrl_of_match,
+	},
+	.probe = mt7986b_pinctrl_probe,
+};
+
+static int __init mt7986a_pinctrl_init(void)
+{
+	return platform_driver_register(&mt7986a_pinctrl_driver);
+}
+
+static int __init mt7986b_pinctrl_init(void)
+{
+	return platform_driver_register(&mt7986b_pinctrl_driver);
+}
+
+arch_initcall(mt7986a_pinctrl_init);
+arch_initcall(mt7986b_pinctrl_init);
+
-- 
2.29.2

From tzungbi at google.com  Tue Aug 24 02:53:21 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Tue, 24 Aug 2021 17:53:21 +0800
Subject: [PATCH 4/9] media: mtk-vcodec: Add venc power on/off interface
In-Reply-To: <20210816105934.28265-5-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-5-irui.wang@mediatek.com>
Message-ID: <YSTBkZg0LBJGJsrE@google.com>

On Mon, Aug 16, 2021 at 06:59:29PM +0800, Irui Wang wrote:
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
> @@ -16,6 +16,7 @@
>  #include "mtk_vcodec_intr.h"
>  #include "mtk_vcodec_util.h"
>  #include "venc_drv_if.h"
> +#include "mtk_vcodec_enc_pm.h"
Please try to maintain the order.

> @@ -285,11 +291,12 @@ static int fops_vcodec_release(struct file *file)
>  	mtk_v4l2_debug(1, "[%d] encoder", ctx->id);
>  	mutex_lock(&dev->dev_mutex);
>  
> +	v4l2_m2m_ctx_release(ctx->m2m_ctx);
>  	mtk_vcodec_enc_release(ctx);
>  	v4l2_fh_del(&ctx->fh);
>  	v4l2_fh_exit(&ctx->fh);
>  	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
> -	v4l2_m2m_ctx_release(ctx->m2m_ctx);
> +	mtk_vcodec_enc_power_off(ctx);
Any reason to move the v4l2_m2m_ctx_release()?

> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
> @@ -12,6 +12,7 @@
>  
>  #include "mtk_vcodec_enc_pm.h"
>  #include "mtk_vcodec_util.h"
> +#include "mtk_vcodec_enc_hw.h"
Please try to maintain the order.

> +int mtk_venc_enable_comp_hw(struct mtk_vcodec_dev *dev)
> +{
> +	int i, ret;
> +	struct mtk_venc_comp_dev *venc_comp;
> +
> +	/*
> +	 * frame_racing mode needs power on all available component devices.
> +	 */
> +	for (i = 0; i < MTK_VENC_HW_MAX; i++) {
> +		venc_comp = (struct mtk_venc_comp_dev *)dev->enc_comp_dev[i];
> +		if (!venc_comp)
> +			return 0;
> +
> +		ret = mtk_smi_larb_get(venc_comp->pm.larbvenc);
> +		if (ret < 0) {
> +			mtk_v4l2_err("power on core[%d] fail %d", i, ret);
> +				goto pw_err;
The goto statement has extra indent layer.

> +int mtk_venc_disable_comp_hw(struct mtk_vcodec_dev *dev)
> +{
> +	int i;
> +	struct mtk_venc_comp_dev *venc_comp;
> +
> +	/*power off all available component device*/
Need extra space between /* */.

> +int mtk_vcodec_enc_power_on(struct mtk_vcodec_ctx *ctx)
> +{
> +	int ret;
> +	struct mtk_vcodec_dev *dev = ctx->dev;
> +
> +	if (dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
> +		ret = mtk_venc_enable_comp_hw(dev);
> +		if (ret < 0) {
> +			mtk_v4l2_err("enable venc comp hw fail :%d", ret);
> +			return ret;
> +		}
> +	} else {
> +		ret = mtk_smi_larb_get(dev->pm.larbvenc);
> +		if (ret < 0) {
> +			mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
> +			return ret;
> +		}
> +	}
> +	return 0;
> +}
It seems the function doesn't need struct mtk_vcodec_ctx.

Does mtk_vcodec_enc_power_on(struct mtk_vcodec_dev* ) make more sense?

> +int mtk_vcodec_enc_power_off(struct mtk_vcodec_ctx *ctx)
> +{
> +	struct mtk_vcodec_dev *dev = ctx->dev;
> +
> +	if (dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE)
> +		mtk_venc_disable_comp_hw(dev);
> +	else
> +		mtk_smi_larb_put(dev->pm.larbvenc);
> +
> +	return 0;
> +}
It seems the function doesn't need struct mtk_vcodec_ctx.


From jbx6244 at gmail.com  Tue Aug 24 02:56:37 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Tue, 24 Aug 2021 11:56:37 +0200
Subject: [PATCH v1] dt-bindings: timer: remove rockchip,
 rk3066-timer compatible string from rockchip, rk-timer.yaml
Message-ID: <20210824095637.2547-1-jbx6244@gmail.com>

The Rockchip rk3066 timers have a different register layout then rk3288
with only a 32 vs 64 bits timer channel. The timers in rk3066a.dtsi have
"snps,dw-apb-timer" as compatible string, so remove the
"rockchip,rk3066-timer" from rockchip,rk-timer.yaml

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml
index e26ecb589..5d157d87d 100644
--- a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml
+++ b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml
@@ -18,7 +18,6 @@ properties:
           - enum:
               - rockchip,rv1108-timer
               - rockchip,rk3036-timer
-              - rockchip,rk3066-timer
               - rockchip,rk3188-timer
               - rockchip,rk3228-timer
               - rockchip,rk3229-timer
-- 
2.20.1



From moudy.ho at mediatek.com  Tue Aug 24 03:00:26 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 24 Aug 2021 18:00:26 +0800
Subject: [PATCH v7 4/5] dts: arm64: mt8183: Add Mediatek MDP3 nodes
In-Reply-To: <20210824100027.25989-1-moudy.ho@mediatek.com>
References: <20210824100027.25989-1-moudy.ho@mediatek.com>
Message-ID: <20210824100027.25989-5-moudy.ho@mediatek.com>

Add device nodes for Media Data Path 3 (MDP3) modules.

Signed-off-by: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
Signed-off-by: daoyuan huang <daoyuan.huang at mediatek.com>
Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 110 +++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index f90df6439c08..067cfb0d6621 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1232,6 +1232,82 @@
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
 		};
 
+		mdp3_rdma0: mdp3_rdma0 at 14001000 {
+			compatible = "mediatek,mt8183-mdp3",
+				     "mediatek,mt8183-mdp3-rdma";
+			mediatek,scp = <&scp>;
+			mediatek,mdp3-id = <0>;
+			mdp3-comps = "mediatek,mt8183-mdp3-dl1", "mediatek,mt8183-mdp3-dl2",
+				     "mediatek,mt8183-mdp3-path1", "mediatek,mt8183-mdp3-path2",
+				     "mediatek,mt8183-mdp3-imgi", "mediatek,mt8183-mdp3-exto";
+			mdp3-comp-ids = <0 1 0 1 0 1>;
+			reg = <0 0x14001000 0 0x1000>,
+			      <0 0x14000000 0 0x1000>,
+			      <0 0x14005000 0 0x1000>,
+			      <0 0x14006000 0 0x1000>,
+			      <0 0x15020000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
+						  <&gce SUBSYS_1502XXXX 0 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_RDMA0>,
+				 <&mmsys CLK_MM_MDP_RSZ1>,
+				 <&mmsys CLK_MM_MDP_DL_TXCK>,
+				 <&mmsys CLK_MM_MDP_DL_RX>,
+				 <&mmsys CLK_MM_IPU_DL_TXCK>,
+				 <&mmsys CLK_MM_IPU_DL_RX>;
+			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
+			mediatek,mmsys = <&mmsys>;
+			mediatek,mm-mutex = <&mutex>;
+			mediatek,mailbox-gce = <&gce>;
+			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
+				 <&gce 21 CMDQ_THR_PRIO_LOWEST 0>,
+				 <&gce 22 CMDQ_THR_PRIO_LOWEST 0>,
+				 <&gce 23 CMDQ_THR_PRIO_LOWEST 0>;
+			gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
+				     <&gce 0x14010000 SUBSYS_1401XXXX>,
+				     <&gce 0x14020000 SUBSYS_1402XXXX>,
+				     <&gce 0x15020000 SUBSYS_1502XXXX>;
+		};
+
+		mdp3_rsz0: mdp3_rsz0 at 14003000 {
+			compatible = "mediatek,mt8183-mdp3-rsz";
+			mediatek,mdp3-id = <0>;
+			reg = <0 0x14003000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_RSZ0>;
+		};
+
+		mdp3_rsz1: mdp3_rsz1 at 14004000 {
+			compatible = "mediatek,mt8183-mdp3-rsz";
+			mediatek,mdp3-id = <1>;
+			reg = <0 0x14004000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_RSZ1>;
+		};
+
+		mdp3_wrot0: mdp3_wrot0 at 14005000 {
+			compatible = "mediatek,mt8183-mdp3-wrot";
+			mediatek,mdp3-id = <0>;
+			reg = <0 0x14005000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_WROT0>;
+			iommus = <&iommu M4U_PORT_MDP_WROT0>;
+		};
+
+		mdp3_wdma: mdp3_wdma at 14006000 {
+			compatible = "mediatek,mt8183-mdp3-wdma";
+			mediatek,mdp3-id = <0>;
+			reg = <0 0x14006000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_WDMA0>;
+			iommus = <&iommu M4U_PORT_MDP_WDMA0>;
+		};
+
 		ovl0: ovl at 14008000 {
 			compatible = "mediatek,mt8183-disp-ovl";
 			reg = <0 0x14008000 0 0x1000>;
@@ -1355,6 +1431,32 @@
 			reg = <0 0x14016000 0 0x1000>;
 			interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_LOW>;
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			mediatek,gce-events = <CMDQ_EVENT_MDP_RDMA0_SOF>,
+					      <CMDQ_EVENT_MDP_RDMA0_EOF>,
+					      <CMDQ_EVENT_MDP_RSZ0_SOF>,
+					      <CMDQ_EVENT_MDP_RSZ1_SOF>,
+					      <CMDQ_EVENT_MDP_TDSHP_SOF>,
+					      <CMDQ_EVENT_MDP_WROT0_SOF>,
+					      <CMDQ_EVENT_MDP_WROT0_EOF>,
+					      <CMDQ_EVENT_MDP_WDMA0_SOF>,
+					      <CMDQ_EVENT_MDP_WDMA0_EOF>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_0>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_1>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_2>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_3>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_4>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_5>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_6>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_7>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_8>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_9>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_10>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_11>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_12>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_13>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_14>,
+					      <CMDQ_EVENT_WPE_A_DONE>,
+					      <CMDQ_EVENT_SPE_B_DONE>;
 		};
 
 		larb0: larb at 14017000 {
@@ -1378,6 +1480,14 @@
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 		};
 
+		mdp3_ccorr: mdp3_ccorr at 1401c000 {
+			compatible = "mediatek,mt8183-mdp3-ccorr";
+			mediatek,mdp3-id = <0>;
+			reg = <0 0x1401c000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_CCORR>;
+		};
+
 		imgsys: syscon at 15020000 {
 			compatible = "mediatek,mt8183-imgsys", "syscon";
 			reg = <0 0x15020000 0 0x1000>;
-- 
2.18.0

From moudy.ho at mediatek.com  Tue Aug 24 03:00:23 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 24 Aug 2021 18:00:23 +0800
Subject: [PATCH v7 1/5] soc: mediatek: mutex: add support for MDP
In-Reply-To: <20210824100027.25989-1-moudy.ho@mediatek.com>
References: <20210824100027.25989-1-moudy.ho@mediatek.com>
Message-ID: <20210824100027.25989-2-moudy.ho@mediatek.com>

Add functions to support MDP:
  1. Get mutex function
  2. Enable/disable mutex
  3. Enable MDP's modules
  4. Write register via CMDQ

Add MDP related settings for 8183 SoC
  1. Register settings

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c       | 106 +++++++++++++++++++++++--
 include/linux/soc/mediatek/mtk-mutex.h |   8 ++
 2 files changed, 108 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2e4bcc300576..935f2849a094 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -7,9 +7,11 @@
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
 
 #define MT2701_MUTEX0_MOD0			0x2c
@@ -107,6 +109,10 @@
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
 
+#define MT8183_MUTEX_MDP_START			5
+#define MT8183_MUTEX_MDP_MOD_MASK		0x07FFFFFF
+#define MT8183_MUTEX_MDP_SOF_MASK		0x00000007
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -123,11 +129,14 @@ enum mtk_mutex_sof_id {
 };
 
 struct mtk_mutex_data {
-	const unsigned int *mutex_mod;
-	const unsigned int *mutex_sof;
-	const unsigned int mutex_mod_reg;
-	const unsigned int mutex_sof_reg;
-	const bool no_clk;
+	const unsigned int	*mutex_mod;
+	const unsigned int	*mutex_sof;
+	const unsigned int	mutex_mod_reg;
+	const unsigned int	mutex_sof_reg;
+	const unsigned int	*mutex_mdp_offset;
+	const unsigned int	mutex_mdp_mod_mask;
+	const unsigned int	mutex_mdp_sof_mask;
+	const bool		no_clk;
 };
 
 struct mtk_mutex_ctx {
@@ -136,6 +145,8 @@ struct mtk_mutex_ctx {
 	void __iomem			*regs;
 	struct mtk_mutex		mutex[10];
 	const struct mtk_mutex_data	*data;
+	phys_addr_t			addr;
+	u8				subsys_id;
 };
 
 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
@@ -238,6 +249,14 @@ static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
 };
 
+/* indicate which mutex is used by each pipepline */
+static const unsigned int mt8183_mutex_mdp_offset[MDP_PIPE_MAX] = {
+	[MDP_PIPE_IMGI] = MT8183_MUTEX_MDP_START,
+	[MDP_PIPE_RDMA0] = MT8183_MUTEX_MDP_START + 1,
+	[MDP_PIPE_WPEI] = MT8183_MUTEX_MDP_START + 2,
+	[MDP_PIPE_WPEI2] = MT8183_MUTEX_MDP_START + 3
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -272,6 +291,9 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.mutex_sof = mt8183_mutex_sof,
 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
+	.mutex_mdp_offset = mt8183_mutex_mdp_offset,
+	.mutex_mdp_mod_mask = MT8183_MUTEX_MDP_MOD_MASK,
+	.mutex_mdp_sof_mask = MT8183_MUTEX_MDP_SOF_MASK,
 	.no_clk = true,
 };
 
@@ -290,6 +312,21 @@ struct mtk_mutex *mtk_mutex_get(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_get);
 
+struct mtk_mutex *mtk_mutex_mdp_get(struct device *dev,
+				    enum mtk_mdp_pipe_id id)
+{
+	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
+	int i = mtx->data->mutex_mdp_offset[id];
+
+	if (!mtx->mutex[i].claimed) {
+		mtx->mutex[i].claimed = true;
+		return &mtx->mutex[i];
+	}
+
+	return ERR_PTR(-EBUSY);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_mdp_get);
+
 void mtk_mutex_put(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -369,6 +406,25 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_add_comp);
 
+void mtk_mutex_add_mdp_mod(struct mtk_mutex *mutex, u32 mod,
+			   struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+	unsigned int offset;
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, mutex->id);
+	cmdq_pkt_write_mask(cmd->pkt, mtx->subsys_id, mtx->addr + offset,
+			    mod, mtx->data->mutex_mdp_mod_mask);
+
+	offset = DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id);
+	cmdq_pkt_write_mask(cmd->pkt, mtx->subsys_id, mtx->addr + offset,
+			    0, mtx->data->mutex_mdp_sof_mask);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_add_mdp_mod);
+
 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 			   enum mtk_ddp_comp_id id)
 {
@@ -420,6 +476,20 @@ void mtk_mutex_enable(struct mtk_mutex *mutex)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_enable);
 
+void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex,
+			      struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	cmdq_pkt_write_mask(cmd->pkt, mtx->subsys_id,
+			    mtx->addr + DISP_REG_MUTEX_EN(mutex->id),
+			    0x1, 0x00000001);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq);
+
 void mtk_mutex_disable(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -431,6 +501,20 @@ void mtk_mutex_disable(struct mtk_mutex *mutex)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_disable);
 
+void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex,
+			       struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	cmdq_pkt_write_mask(cmd->pkt, mtx->subsys_id,
+			    mtx->addr + DISP_REG_MUTEX_EN(mutex->id),
+			    0x0, 0x00000001);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_disable_by_cmdq);
+
 void mtk_mutex_acquire(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -458,7 +542,8 @@ static int mtk_mutex_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_mutex_ctx *mtx;
-	struct resource *regs;
+	struct cmdq_client_reg cmdq_reg;
+	struct resource *regs, addr;
 	int i;
 
 	mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL);
@@ -479,6 +564,15 @@ static int mtk_mutex_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (of_address_to_resource(dev->of_node, 0, &addr) < 0)
+		mtx->addr = 0L;
+	else
+		mtx->addr = addr.start;
+
+	if (cmdq_dev_get_client_reg(dev, &cmdq_reg, 0) != 0)
+		dev_info(dev, "cmdq subsys id has not been set\n");
+	mtx->subsys_id = cmdq_reg.subsys;
+
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mtx->regs = devm_ioremap_resource(dev, regs);
 	if (IS_ERR(mtx->regs)) {
diff --git a/include/linux/soc/mediatek/mtk-mutex.h b/include/linux/soc/mediatek/mtk-mutex.h
index 6fe4ffbde290..d08b98419dd9 100644
--- a/include/linux/soc/mediatek/mtk-mutex.h
+++ b/include/linux/soc/mediatek/mtk-mutex.h
@@ -11,11 +11,19 @@ struct device;
 struct mtk_mutex;
 
 struct mtk_mutex *mtk_mutex_get(struct device *dev);
+struct mtk_mutex *mtk_mutex_mdp_get(struct device *dev,
+				    enum mtk_mdp_pipe_id id);
 int mtk_mutex_prepare(struct mtk_mutex *mutex);
 void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 			enum mtk_ddp_comp_id id);
+void mtk_mutex_add_mdp_mod(struct mtk_mutex *mutex, u32 mod,
+			   struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_enable(struct mtk_mutex *mutex);
+void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex,
+			      struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_disable(struct mtk_mutex *mutex);
+void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex,
+			       struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 			   enum mtk_ddp_comp_id id);
 void mtk_mutex_unprepare(struct mtk_mutex *mutex);
-- 
2.18.0

From moudy.ho at mediatek.com  Tue Aug 24 03:00:22 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 24 Aug 2021 18:00:22 +0800
Subject: [PATCH v7 0/5] media: mediatek: support mdp3 on mt8183 platform
Message-ID: <20210824100027.25989-1-moudy.ho@mediatek.com>

Changes since v6:
- Refactor GCE event to corresponding node.
- Fix dt_binding_check fail.
- Fix compilation errors.

Changes since v5:
- Rebase on v5.14-rc6.
- Move MMSYS/Mutex settings to corresponding driver.
- Revise the software license description and copyright.
- Remove unnecessary enum. or definitions.
- Optimize platform/chip definition conditions.
- Use general printing functions instead of MDP3 private ones.
- Fix compile warning.

Changes since v4:
- Rebase on v5.13-rc1.
- Remove the CMDQ flush flow to match the CMDQ API change.
- Integrate four of MDP's direct-link subcomponents into MDP controller node
  from syscon node to avoid illegal clock usage.
- Rewrite dt-binding in a JSON compatible subset of YAML
- Fix a bit of macro argument precedence.

Changes since v3:
- Rebase on v5.9-rc1.
- modify code for review comment from Rob Herring, cancel multiple nodes using
  same register base situation.
- control IOMMU port through pm runtime get/put to DMA components' device.
- SCP(VPU) driver revision.
- stop queuing jobs(remove flush_workqueue()) after mdp_m2m_release().
- add computation of plane address with data_offset.
- fix scale ratio check issue.
- add default v4l2_format setting.

Changes since v2:
- modify code for review comment from Tomasz Figa & Alexandre Courbot
- review comment from Rob Herring will offer code revision in v4, due to
  it's related to device node modification, will need to modify code
  architecture

Changes since v1:
- modify code for CMDQ v3 API support
- EC ipi cmd migration
- fix compliance test fail item (m2m cmd with -f) due to there is two problem in runing all format(-f) cmd:
1. out of memory before test complete
        Due to capture buffer mmap (refcount + 1) after reqbuf but seems
        no corresponding munmap called before device close.
        There are total 12XX items(formats) in format test and each format
        alloc 8 capture/output buffers.
2. unceasingly captureBufs() (randomly)
        Seems the break statement didn't catch the count == 0 situation:
        In v4l2-test-buffers.cpp, function: captureBufs()
                        ...
                        count--;
                        if (!node->is_m2m && !count)
                                break;
        Log is as attachment

I will paste the test result with problem part in another e-mail

Hi,

This is the first version of RFC patch for Media Data Path 3 (MDP3),
MDP3 is used for scaling and color format conversion.
support using GCE to write register in critical time limitation.
support V4L2 m2m device control.

Moudy Ho (5):
  soc: mediatek: mutex: add support for MDP
  soc: mediatek: mmsys: Add support for MDP
  dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
  dts: arm64: mt8183: Add Mediatek MDP3 nodes
  media: platform: mtk-mdp3: Add Mediatek MDP3 driver

 .../bindings/media/mediatek,mdp3-ccorr.yaml   |   57 +
 .../bindings/media/mediatek,mdp3-rdma.yaml    |  207 +++
 .../bindings/media/mediatek,mdp3-rsz.yaml     |   65 +
 .../bindings/media/mediatek,mdp3-wdma.yaml    |   71 +
 .../bindings/media/mediatek,mdp3-wrot.yaml    |   71 +
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  110 ++
 drivers/media/platform/Kconfig                |   19 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/mtk-mdp3/Makefile      |    6 +
 .../media/platform/mtk-mdp3/mdp_reg_ccorr.h   |   19 +
 drivers/media/platform/mtk-mdp3/mdp_reg_isp.h |   27 +
 .../media/platform/mtk-mdp3/mdp_reg_rdma.h    |   65 +
 drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h |   39 +
 .../media/platform/mtk-mdp3/mdp_reg_wdma.h    |   47 +
 .../media/platform/mtk-mdp3/mdp_reg_wrot.h    |   55 +
 drivers/media/platform/mtk-mdp3/mtk-img-ipi.h |  280 ++++
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.c   |  507 +++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.h   |   46 +
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 1307 +++++++++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.h   |  147 ++
 .../media/platform/mtk-mdp3/mtk-mdp3-core.c   |  329 +++++
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |   75 +
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    |  801 ++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.h    |   41 +
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   |  746 ++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |  372 +++++
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.c    |  312 ++++
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.h    |   78 +
 drivers/soc/mediatek/mt8183-mmsys.h           |  235 +++
 drivers/soc/mediatek/mtk-mmsys.c              |  164 +++
 drivers/soc/mediatek/mtk-mmsys.h              |    9 +-
 drivers/soc/mediatek/mtk-mutex.c              |  106 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |   81 +
 include/linux/soc/mediatek/mtk-mutex.h        |    8 +
 34 files changed, 6495 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
 create mode 100644 drivers/media/platform/mtk-mdp3/Makefile
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_ccorr.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_isp.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_rdma.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_wdma.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_wrot.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-img-ipi.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h

-- 
2.18.0

From moudy.ho at mediatek.com  Tue Aug 24 03:00:25 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 24 Aug 2021 18:00:25 +0800
Subject: [PATCH v7 3/5] dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
In-Reply-To: <20210824100027.25989-1-moudy.ho@mediatek.com>
References: <20210824100027.25989-1-moudy.ho@mediatek.com>
Message-ID: <20210824100027.25989-4-moudy.ho@mediatek.com>

This patch adds DT binding document for Media Data Path 3 (MDP3)
a unit in multimedia system used for scaling and color format convert.

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 .../bindings/media/mediatek,mdp3-ccorr.yaml   |  57 +++++
 .../bindings/media/mediatek,mdp3-rdma.yaml    | 207 ++++++++++++++++++
 .../bindings/media/mediatek,mdp3-rsz.yaml     |  65 ++++++
 .../bindings/media/mediatek,mdp3-wdma.yaml    |  71 ++++++
 .../bindings/media/mediatek,mdp3-wrot.yaml    |  71 ++++++
 5 files changed, 471 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
new file mode 100644
index 000000000000..59fd68b46022
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 CCORR Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to do color correction with 3X3 matrix.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8183-mdp3-ccorr
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+
+    mdp3_ccorr: mdp3_ccorr at 1401c000 {
+      compatible = "mediatek,mt8183-mdp3-ccorr";
+      mediatek,mdp3-id = <0>;
+      reg = <0x1401c000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_CCORR>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
new file mode 100644
index 000000000000..b355d7fe791e
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
@@ -0,0 +1,207 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to do read DMA.
+  RDMA0 is also used to be a controller node containing MMSYS,
+  MUTEX, GCE and SCP settings.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+        - enum:
+          # controller node
+          - mediatek,mt8183-mdp3
+        - enum:
+          - mediatek,mt8183-mdp3-rdma
+
+      - items:
+        - enum:
+          # read DMA
+          - mediatek,mt8183-mdp3-rdma
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of system control processor (SCP), using
+      the remoteproc & rpmsg framework.
+      $ref: /schemas/remoteproc/mtk,scp.yaml
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      In MDP3, it can allocate multiple identical modules for
+      different data path selection or multi-pipeline execution.
+      This node is used to indicate the ID of each module.
+
+  mdp3-comps:
+    $ref: /schemas/types.yaml#/definitions/string-array
+    items:
+        - enum:
+          # MDP direct-link input path selection, create a
+          # component for path connectedness of HW pipe control
+          - mediatek,mt8183-mdp3-dl1
+        - enum:
+          - mediatek,mt8183-mdp3-dl2
+        - enum:
+          # MDP direct-link output path selection, create a
+          # component for path connectedness of HW pipe control
+          - mediatek,mt8183-mdp3-path1
+        - enum:
+          - mediatek,mt8183-mdp3-path2
+        - enum:
+          # Input DMA of ISP PASS2 (DIP) module for raw image input
+          - mediatek,mt8183-mdp3-imgi
+        - enum:
+          # Output DMA of ISP PASS2 (DIP) module for YUV image output
+          - mediatek,mt8183-mdp3-exto
+
+  mdp3-comp-ids:
+    maxItems: 1
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description: |
+      Pipeline ID of MDP direct-link or DIP.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 6
+
+  iommus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Should point to the respective IOMMU block with master
+      port as argument.
+      $ref: /schemas/iommu/mediatek,iommu.yaml
+
+  mediatek,mmsys:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of mux(multiplexer) controller for HW connections.
+
+  mediatek,mm-mutex:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of sof(start of frame) signal controller.
+
+  mediatek,mailbox-gce:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      The node of global command engine (GCE), used to read/write
+      registers with critical time limitation.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  mboxes:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      $ref: /schemas/mailbox/mailbox.txt
+
+  gce-subsys:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+if:
+  properties:
+    compatible:
+      items:
+        - enum:
+          - mediatek,mt8183-mdp3
+        - enum:
+          - mediatek,mt8183-mdp3-rdma
+
+then:
+  required:
+    - mediatek,scp
+    - mediatek,mmsys
+    - mediatek,mm-mutex
+    - mediatek,mailbox-gce
+    - mboxes
+    - gce-subsys
+
+required:
+  - compatible
+  - mediatek,mdp3-id
+  - reg
+  - clocks
+  - mediatek,gce-client-reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_rdma0: mdp3_rdma0 at 14001000 {
+      compatible = "mediatek,mt8183-mdp3",
+                   "mediatek,mt8183-mdp3-rdma";
+      mediatek,scp = <&scp>;
+      mediatek,mdp3-id = <0>;
+      mdp3-comps = "mediatek,mt8183-mdp3-dl1", "mediatek,mt8183-mdp3-dl2",
+                   "mediatek,mt8183-mdp3-path1", "mediatek,mt8183-mdp3-path2",
+                   "mediatek,mt8183-mdp3-imgi", "mediatek,mt8183-mdp3-exto";
+      mdp3-comp-ids = <0 1 0 1 0 1>;
+      reg = <0x14001000 0x1000>,
+            <0x14000000 0x1000>,
+            <0x14005000 0x1000>,
+            <0x14006000 0x1000>,
+            <0x15020000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
+                                <&gce SUBSYS_1502XXXX 0 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_RDMA0>,
+               <&mmsys CLK_MM_MDP_RSZ1>,
+               <&mmsys CLK_MM_MDP_DL_TXCK>,
+               <&mmsys CLK_MM_MDP_DL_RX>,
+               <&mmsys CLK_MM_IPU_DL_TXCK>,
+               <&mmsys CLK_MM_IPU_DL_RX>;
+      iommus = <&iommu>;
+      mediatek,mmsys = <&mmsys>;
+      mediatek,mm-mutex = <&mutex>;
+      mediatek,mailbox-gce = <&gce>;
+      mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
+               <&gce 21 CMDQ_THR_PRIO_LOWEST 0>,
+               <&gce 22 CMDQ_THR_PRIO_LOWEST 0>,
+               <&gce 23 CMDQ_THR_PRIO_LOWEST 0>;
+      gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
+                   <&gce 0x14010000 SUBSYS_1401XXXX>,
+                   <&gce 0x14020000 SUBSYS_1402XXXX>,
+                   <&gce 0x15020000 SUBSYS_1502XXXX>;
+    };
\ No newline at end of file
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
new file mode 100644
index 000000000000..c55a52cd32b7
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-rsz.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 Resizer Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to do frame resizing.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8183-mdp3-rsz
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+
+    mdp3_rsz0: mdp3_rsz0 at 14003000 {
+      compatible = "mediatek,mt8183-mdp3-rsz";
+      mediatek,mdp3-id = <0>;
+      reg = <0x14003000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_RSZ0>;
+    };
+
+    mdp3_rsz1: mdp3_rsz1 at 14004000 {
+      compatible = "mediatek,mt8183-mdp3-rsz";
+      mediatek,mdp3-id = <1>;
+      reg = <0x14004000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_RSZ1>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
new file mode 100644
index 000000000000..93e6f331ada8
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to write DMA.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8183-mdp3-wdma
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+  iommus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Should point to the respective IOMMU block with master
+      port as argument.
+      $ref: /schemas/iommu/mediatek,iommu.yaml
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_wdma: mdp3_wdma at 14006000 {
+      compatible = "mediatek,mt8183-mdp3-wdma";
+      mediatek,mdp3-id = <0>;
+      reg = <0x14006000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_WDMA0>;
+      iommus = <&iommu>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
new file mode 100644
index 000000000000..2993da04c562
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-wrot.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 Device Tree Bindings
+
+maintainers:
+  - Daoyuan Huang <daoyuan.huang at mediatek.com>
+  - Moudy Ho <moudy.ho at mediatek.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to write DMA with frame rotation.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8183-mdp3-wrot
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    description: |
+      Physical base address and length of the function block
+      register space, the number aligns with the component
+      and its own subcomponent.
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+  iommus:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: |
+      Should point to the respective IOMMU block with master
+      port as argument.
+      $ref: /schemas/iommu/mediatek,iommu.yaml
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_wrot0: mdp3_wrot0 at 14005000 {
+      compatible = "mediatek,mt8183-mdp3-wrot";
+      mediatek,mdp3-id = <0>;
+      reg = <0x14005000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_WROT0>;
+      iommus = <&iommu>;
+    };
-- 
2.18.0

From moudy.ho at mediatek.com  Tue Aug 24 03:00:24 2021
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 24 Aug 2021 18:00:24 +0800
Subject: [PATCH v7 2/5] soc: mediatek: mmsys: Add support for MDP
In-Reply-To: <20210824100027.25989-1-moudy.ho@mediatek.com>
References: <20210824100027.25989-1-moudy.ho@mediatek.com>
Message-ID: <20210824100027.25989-3-moudy.ho@mediatek.com>

Add functions to support MDP:
  1. MDP connect/disconnect functions
  2. ISP control function
  3. Write register via CMDQ

Add MDP related settings for 8183 SoC
  1. Register settings
  2. MDP route table

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 drivers/soc/mediatek/mt8183-mmsys.h    | 235 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 164 +++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       |   9 +-
 include/linux/soc/mediatek/mtk-mmsys.h |  81 +++++++++
 4 files changed, 486 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mt8183-mmsys.h b/drivers/soc/mediatek/mt8183-mmsys.h
index 579dfc8dc8fc..2fa79e745a45 100644
--- a/drivers/soc/mediatek/mt8183-mmsys.h
+++ b/drivers/soc/mediatek/mt8183-mmsys.h
@@ -12,6 +12,32 @@
 #define MT8183_DISP_DPI0_SEL_IN			0xf30
 #define MT8183_DISP_RDMA0_SOUT_SEL_IN		0xf50
 #define MT8183_DISP_RDMA1_SOUT_SEL_IN		0xf54
+#define MT8183_MDP_ISP_MOUT_EN			0xf80
+#define MT8183_MDP_RDMA0_MOUT_EN		0xf84
+#define MT8183_MDP_PRZ0_MOUT_EN			0xf8c
+#define MT8183_MDP_PRZ1_MOUT_EN			0xf90
+#define MT8183_MDP_COLOR_MOUT_EN		0xf94
+#define MT8183_MDP_IPU_MOUT_EN			0xf98
+#define MT8183_MDP_PATH0_SOUT_SEL		0xfa8
+#define MT8183_MDP_PATH1_SOUT_SEL		0xfac
+#define MT8183_MDP_PRZ0_SEL_IN			0xfc0
+#define MT8183_MDP_PRZ1_SEL_IN			0xfc4
+#define MT8183_MDP_TDSHP_SEL_IN			0xfc8
+#define MT8183_MDP_WROT0_SEL_IN			0xfd0
+#define MT8183_MDP_WDMA_SEL_IN			0xfd4
+#define MT8183_MDP_PATH0_SEL_IN			0xfe0
+#define MT8183_MDP_PATH1_SEL_IN			0xfe4
+#define MT8183_MDP_AAL_MOUT_EN			0xfe8
+#define MT8183_MDP_AAL_SEL_IN			0xfec
+#define MT8183_MDP_CCORR_SEL_IN			0xff0
+#define MT8183_MDP_CCORR_SOUT_SEL		0xff4
+
+#define MT8183_ISP_CTRL_MMSYS_SW0_RST_B		0x140
+#define MT8183_ISP_CTRL_MMSYS_SW1_RST_B		0x144
+#define MT8183_ISP_CTRL_MDP_ASYNC_CFG_WD	0x934
+#define MT8183_ISP_CTRL_MDP_ASYNC_IPU_CFG_WD	0x93C
+#define MT8183_ISP_CTRL_ISP_RELAY_CFG_WD	0x994
+#define MT8183_ISP_CTRL_IPU_RELAY_CFG_WD	0x9a0
 
 #define MT8183_OVL0_MOUT_EN_OVL0_2L		BIT(4)
 #define MT8183_OVL0_2L_MOUT_EN_DISP_PATH0	BIT(0)
@@ -24,6 +50,55 @@
 #define MT8183_DPI0_SEL_IN_RDMA1		0x2
 #define MT8183_RDMA0_SOUT_COLOR0		0x1
 #define MT8183_RDMA1_SOUT_DSI0			0x1
+#define MT8183_MDP_ISP_MOUT_EN_CCORR0		BIT(0)
+#define MT8183_MDP_ISP_MOUT_EN_RSZ1		BIT(1)
+#define MT8183_MDP_ISP_MOUT_EN_AAL0		BIT(2)
+#define MT8183_MDP_IPU_MOUT_EN_CCORR0		BIT(0)
+#define MT8183_MDP_IPU_MOUT_EN_RSZ1		BIT(1)
+#define MT8183_MDP_IPU_MOUT_EN_AAL0		BIT(2)
+#define MT8183_MDP_RDMA0_MOUT_EN_CCORR0		BIT(0)
+#define MT8183_MDP_RDMA0_MOUT_EN_RSZ1		BIT(1)
+#define MT8183_MDP_RDMA0_MOUT_EN_PATH0_OUT	BIT(2)
+#define MT8183_MDP_RDMA0_MOUT_EN_AAL0		BIT(3)
+#define MT8183_MDP_AAL_MOUT_EN_CCORR0		BIT(0)
+#define MT8183_MDP_AAL_MOUT_EN_RSZ1		BIT(1)
+#define MT8183_MDP_AAL_MOUT_EN_RSZ0		BIT(2)
+#define MT8183_MDP_PRZ0_MOUT_EN_PATH0_OUT	BIT(0)
+#define MT8183_MDP_PRZ0_MOUT_EN_TDSHP0		BIT(1)
+#define MT8183_MDP_PRZ1_MOUT_EN_PATH0_OUT	BIT(0)
+#define MT8183_MDP_PRZ1_MOUT_EN_TDSHP0		BIT(1)
+#define MT8183_MDP_PRZ1_MOUT_EN_PATH1_OUT	BIT(2)
+#define MT8183_MDP_PRZ1_MOUT_EN_COLOR0		BIT(4)
+#define MT8183_MDP_COLOR_MOUT_EN_PATH0_OUT	BIT(0)
+#define MT8183_MDP_COLOR_MOUT_EN_PATH1_OUT	BIT(1)
+#define MT8183_MDP_AAL_SEL_IN_CAMIN		0
+#define MT8183_MDP_AAL_SEL_IN_RDMA0		1
+#define MT8183_MDP_AAL_SEL_IN_CAMIN2		2
+#define MT8183_MDP_AAL_SEL_IN_CCORR0		3
+#define MT8183_MDP_CCORR_SEL_IN_CAMIN		0
+#define MT8183_MDP_CCORR_SEL_IN_RDMA0		1
+#define MT8183_MDP_CCORR_SEL_IN_CAMIN2		3
+#define MT8183_MDP_CCORR_SEL_IN_AAL0		4
+#define MT8183_MDP_PRZ0_SEL_IN_AAL0		0
+#define MT8183_MDP_PRZ0_SEL_IN_CCORR0		1
+#define MT8183_MDP_PRZ1_SEL_IN_CAMIN		0
+#define MT8183_MDP_PRZ1_SEL_IN_RDMA0		1
+#define MT8183_MDP_PRZ1_SEL_IN_CAMIN2		4
+#define MT8183_MDP_PRZ1_SEL_IN_AAL0		5
+#define MT8183_MDP_TDSHP_SEL_IN_RSZ0		0
+#define MT8183_MDP_TDSHP_SEL_IN_RSZ1		1
+#define MT8183_MDP_PATH0_SEL_IN_RSZ0		0
+#define MT8183_MDP_PATH0_SEL_IN_RSZ1		1
+#define MT8183_MDP_PATH0_SEL_IN_COLOR0		2
+#define MT8183_MDP_PATH0_SEL_IN_RDMA0		3
+#define MT8183_MDP_PATH1_SEL_IN_RSZ1		0
+#define MT8183_MDP_PATH1_SEL_IN_COLOR0		1
+#define MT8183_MDP_WROT0_SEL_IN_PATH0_OUT	0
+#define MT8183_MDP_WDMA_SEL_IN_PATH1_OUT	0
+#define MT8183_MDP_CCORR_SOUT_SEL_AAL0		0
+#define MT8183_MDP_CCORR_SOUT_SEL_RSZ0		1
+#define MT8183_MDP_PATH0_SOUT_SEL_WROT0		0
+#define MT8183_MDP_PATH1_SOUT_SEL_WDMA		0
 
 static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
 	{
@@ -50,5 +125,165 @@ static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
 	}
 };
 
+static const struct mtk_mmsys_routes mmsys_mt8183_mdp_routing_table[] = {
+	{
+		MDP_COMP_CAMIN, MDP_COMP_CCORR0,
+		MT8183_MDP_ISP_MOUT_EN, MT8183_MDP_ISP_MOUT_EN_CCORR0
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_RSZ1,
+		MT8183_MDP_ISP_MOUT_EN, MT8183_MDP_ISP_MOUT_EN_RSZ1
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_AAL0,
+		MT8183_MDP_ISP_MOUT_EN, MT8183_MDP_ISP_MOUT_EN_AAL0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_CCORR0,
+		MT8183_MDP_IPU_MOUT_EN, MT8183_MDP_IPU_MOUT_EN_CCORR0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_RSZ1,
+		MT8183_MDP_IPU_MOUT_EN, MT8183_MDP_IPU_MOUT_EN_RSZ1
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_AAL0,
+		MT8183_MDP_IPU_MOUT_EN, MT8183_MDP_IPU_MOUT_EN_AAL0
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_CCORR0,
+		MT8183_MDP_RDMA0_MOUT_EN, MT8183_MDP_RDMA0_MOUT_EN_CCORR0
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_RSZ1,
+		MT8183_MDP_RDMA0_MOUT_EN, MT8183_MDP_RDMA0_MOUT_EN_RSZ1
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_RDMA0_MOUT_EN, MT8183_MDP_RDMA0_MOUT_EN_PATH0_OUT
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_AAL0,
+		MT8183_MDP_RDMA0_MOUT_EN, MT8183_MDP_RDMA0_MOUT_EN_AAL0
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_CCORR0,
+		MT8183_MDP_AAL_MOUT_EN, MT8183_MDP_AAL_MOUT_EN_CCORR0
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_RSZ1,
+		MT8183_MDP_AAL_MOUT_EN, MT8183_MDP_AAL_MOUT_EN_RSZ1
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_RSZ0,
+		MT8183_MDP_AAL_MOUT_EN, MT8183_MDP_AAL_MOUT_EN_RSZ0
+	}, {
+		MDP_COMP_RSZ0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PRZ0_MOUT_EN, MT8183_MDP_PRZ0_MOUT_EN_PATH0_OUT
+	}, {
+		MDP_COMP_RSZ0, MDP_COMP_TDSHP0,
+		MT8183_MDP_PRZ0_MOUT_EN, MT8183_MDP_PRZ0_MOUT_EN_TDSHP0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PRZ1_MOUT_EN, MT8183_MDP_PRZ1_MOUT_EN_PATH0_OUT
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_TDSHP0,
+		MT8183_MDP_PRZ1_MOUT_EN, MT8183_MDP_PRZ1_MOUT_EN_TDSHP0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_PATH1_SOUT,
+		MT8183_MDP_PRZ1_MOUT_EN, MT8183_MDP_PRZ1_MOUT_EN_PATH1_OUT
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_COLOR0,
+		MT8183_MDP_PRZ1_MOUT_EN, MT8183_MDP_PRZ1_MOUT_EN_COLOR0
+	}, {
+		MDP_COMP_COLOR0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_COLOR_MOUT_EN, MT8183_MDP_COLOR_MOUT_EN_PATH0_OUT
+	}, {
+		MDP_COMP_COLOR0, MDP_COMP_PATH1_SOUT,
+		MT8183_MDP_COLOR_MOUT_EN, MT8183_MDP_COLOR_MOUT_EN_PATH1_OUT
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_AAL0,
+		MT8183_MDP_AAL_SEL_IN, MT8183_MDP_AAL_SEL_IN_CAMIN
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_AAL0,
+		MT8183_MDP_AAL_SEL_IN, MT8183_MDP_AAL_SEL_IN_RDMA0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_AAL0,
+		MT8183_MDP_AAL_SEL_IN, MT8183_MDP_AAL_SEL_IN_CAMIN2
+	}, {
+		MDP_COMP_CCORR0, MDP_COMP_AAL0,
+		MT8183_MDP_AAL_SEL_IN, MT8183_MDP_AAL_SEL_IN_CCORR0
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_CCORR0,
+		MT8183_MDP_CCORR_SEL_IN, MT8183_MDP_CCORR_SEL_IN_CAMIN
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_CCORR0,
+		MT8183_MDP_CCORR_SEL_IN, MT8183_MDP_CCORR_SEL_IN_RDMA0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_CCORR0,
+		MT8183_MDP_CCORR_SEL_IN, MT8183_MDP_CCORR_SEL_IN_CAMIN2
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_CCORR0,
+		MT8183_MDP_CCORR_SEL_IN, MT8183_MDP_CCORR_SEL_IN_AAL0
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_RSZ0,
+		MT8183_MDP_PRZ0_SEL_IN, MT8183_MDP_PRZ0_SEL_IN_AAL0
+	}, {
+		MDP_COMP_CCORR0, MDP_COMP_RSZ0,
+		MT8183_MDP_PRZ0_SEL_IN, MT8183_MDP_PRZ0_SEL_IN_CCORR0
+	}, {
+		MDP_COMP_CAMIN, MDP_COMP_RSZ1,
+		MT8183_MDP_PRZ1_SEL_IN, MT8183_MDP_PRZ1_SEL_IN_CAMIN
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_RSZ1,
+		MT8183_MDP_PRZ1_SEL_IN, MT8183_MDP_PRZ1_SEL_IN_RDMA0
+	}, {
+		MDP_COMP_CAMIN2, MDP_COMP_RSZ1,
+		MT8183_MDP_PRZ1_SEL_IN, MT8183_MDP_PRZ1_SEL_IN_CAMIN2
+	}, {
+		MDP_COMP_AAL0, MDP_COMP_RSZ1,
+		MT8183_MDP_PRZ1_SEL_IN, MT8183_MDP_PRZ1_SEL_IN_AAL0
+	}, {
+		MDP_COMP_RSZ0, MDP_COMP_TDSHP0,
+		MT8183_MDP_TDSHP_SEL_IN, MT8183_MDP_TDSHP_SEL_IN_RSZ0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_TDSHP0,
+		MT8183_MDP_TDSHP_SEL_IN, MT8183_MDP_TDSHP_SEL_IN_RSZ1
+	}, {
+		MDP_COMP_RSZ0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PATH0_SEL_IN, MT8183_MDP_PATH0_SEL_IN_RSZ0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PATH0_SEL_IN, MT8183_MDP_PATH0_SEL_IN_RSZ1
+	}, {
+		MDP_COMP_COLOR0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PATH0_SEL_IN, MT8183_MDP_PATH0_SEL_IN_COLOR0
+	}, {
+		MDP_COMP_RDMA0, MDP_COMP_PATH0_SOUT,
+		MT8183_MDP_PATH0_SEL_IN, MT8183_MDP_PATH0_SEL_IN_RDMA0
+	}, {
+		MDP_COMP_RSZ1, MDP_COMP_PATH1_SOUT,
+		MT8183_MDP_PATH1_SEL_IN, MT8183_MDP_PATH1_SEL_IN_RSZ1
+	}, {
+		MDP_COMP_COLOR0, MDP_COMP_PATH1_SOUT,
+		MT8183_MDP_PATH1_SEL_IN, MT8183_MDP_PATH1_SEL_IN_COLOR0
+	}, {
+		MDP_COMP_PATH0_SOUT, MDP_COMP_WROT0,
+		MT8183_MDP_WROT0_SEL_IN, MT8183_MDP_WROT0_SEL_IN_PATH0_OUT
+	}, {
+		MDP_COMP_PATH1_SOUT, MDP_COMP_WDMA,
+		MT8183_MDP_WDMA_SEL_IN, MT8183_MDP_WDMA_SEL_IN_PATH1_OUT
+	}, {
+		MDP_COMP_CCORR0, MDP_COMP_AAL0,
+		MT8183_MDP_CCORR_SOUT_SEL, MT8183_MDP_CCORR_SOUT_SEL_AAL0
+	}, {
+		MDP_COMP_CCORR0, MDP_COMP_RSZ0,
+		MT8183_MDP_CCORR_SOUT_SEL, MT8183_MDP_CCORR_SOUT_SEL_RSZ0
+	}, {
+		MDP_COMP_PATH0_SOUT, MDP_COMP_WROT0,
+		MT8183_MDP_PATH0_SOUT_SEL, MT8183_MDP_PATH0_SOUT_SEL_WROT0
+	}, {
+		MDP_COMP_PATH1_SOUT, MDP_COMP_WDMA,
+		MT8183_MDP_PATH1_SOUT_SEL, MT8183_MDP_PATH1_SOUT_SEL_WDMA
+	}
+};
+
+static const unsigned int mmsys_mt8183_mdp_isp_ctrl_table[ISP_CTRL_MAX] = {
+	[ISP_CTRL_MMSYS_SW0_RST_B] = MT8183_ISP_CTRL_MMSYS_SW0_RST_B,
+	[ISP_CTRL_MMSYS_SW1_RST_B] = MT8183_ISP_CTRL_MMSYS_SW1_RST_B,
+	[ISP_CTRL_MDP_ASYNC_CFG_WD] = MT8183_ISP_CTRL_MDP_ASYNC_CFG_WD,
+	[ISP_CTRL_MDP_ASYNC_IPU_CFG_WD] = MT8183_ISP_CTRL_MDP_ASYNC_IPU_CFG_WD,
+	[ISP_CTRL_ISP_RELAY_CFG_WD] = MT8183_ISP_CTRL_ISP_RELAY_CFG_WD,
+	[ISP_CTRL_IPU_RELAY_CFG_WD] = MT8183_ISP_CTRL_IPU_RELAY_CFG_WD,
+};
+
 #endif /* __SOC_MEDIATEK_MT8183_MMSYS_H */
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 080660ef11bf..c4b99a99ee1e 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -7,8 +7,10 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk-mmsys.h"
 #include "mt8167-mmsys.h"
@@ -50,11 +52,16 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.clk_driver = "clk-mt8183-mm",
 	.routes = mmsys_mt8183_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
+	.mdp_routes = mmsys_mt8183_mdp_routing_table,
+	.mdp_num_routes = ARRAY_SIZE(mmsys_mt8183_mdp_routing_table),
+	.mdp_isp_ctrl = mmsys_mt8183_mdp_isp_ctrl_table,
 };
 
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
+	phys_addr_t addr;
+	u8 subsys_id;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -91,12 +98,160 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
+void mtk_mmsys_mdp_connect(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			   enum mtk_mdp_comp_id cur,
+			   enum mtk_mdp_comp_id next)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const struct mtk_mmsys_routes *routes = mmsys->data->mdp_routes;
+	int i;
+
+	WARN_ON(!routes);
+	WARN_ON(mmsys->subsys_id == 0);
+	for (i = 0; i < mmsys->data->mdp_num_routes; i++)
+		if (cur == routes[i].from_comp && next == routes[i].to_comp)
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id,
+					    mmsys->addr + routes[i].addr,
+					    routes[i].val, 0xFFFFFFFF);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_connect);
+
+void mtk_mmsys_mdp_disconnect(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id cur,
+			      enum mtk_mdp_comp_id next)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const struct mtk_mmsys_routes *routes = mmsys->data->mdp_routes;
+	int i;
+
+	WARN_ON(mmsys->subsys_id == 0);
+	for (i = 0; i < mmsys->data->mdp_num_routes; i++)
+		if (cur == routes[i].from_comp && next == routes[i].to_comp)
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id,
+					    mmsys->addr + routes[i].addr,
+					    0, 0xFFFFFFFF);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_disconnect);
+
+void mtk_mmsys_mdp_isp_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			    enum mtk_mdp_comp_id id)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const unsigned int *isp_ctrl = mmsys->data->mdp_isp_ctrl;
+	u32 reg;
+
+	WARN_ON(mmsys->subsys_id == 0);
+	/* Direct link */
+	if (id == MDP_COMP_CAMIN) {
+		/* Reset MDP_DL_ASYNC_TX */
+		/* Bit  3: MDP_DL_ASYNC_TX / MDP_RELAY */
+		if (isp_ctrl[ISP_CTRL_MMSYS_SW0_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MMSYS_SW0_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0x0, 0x00000008);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    1 << 3, 0x00000008);
+		}
+
+		/* Reset MDP_DL_ASYNC_RX */
+		/* Bit  10: MDP_DL_ASYNC_RX */
+		if (isp_ctrl[ISP_CTRL_MMSYS_SW1_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MMSYS_SW1_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0x0, 0x00000400);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    1 << 10, 0x00000400);
+		}
+
+		/* Enable sof mode */
+		if (isp_ctrl[ISP_CTRL_ISP_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_ISP_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0 << 31, 0x80000000);
+		}
+	}
+
+	if (id == MDP_COMP_CAMIN2) {
+		/* Reset MDP_DL_ASYNC2_TX */
+		/* Bit  4: MDP_DL_ASYNC2_TX / MDP_RELAY2 */
+		if (isp_ctrl[ISP_CTRL_MMSYS_SW0_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MMSYS_SW0_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0x0, 0x00000010);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    1 << 4, 0x00000010);
+		}
+
+		/* Reset MDP_DL_ASYNC2_RX */
+		/* Bit  11: MDP_DL_ASYNC2_RX */
+		if (isp_ctrl[ISP_CTRL_MMSYS_SW1_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MMSYS_SW1_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0x0, 0x00000800);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    1 << 11, 0x00000800);
+		}
+
+		/* Enable sof mode */
+		if (isp_ctrl[ISP_CTRL_IPU_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_IPU_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    0 << 31, 0x80000000);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_isp_ctrl);
+
+void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id id, u32 camin_w, u32 camin_h)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const unsigned int *isp_ctrl = mmsys->data->mdp_isp_ctrl;
+	u32 reg;
+
+	WARN_ON(mmsys->subsys_id == 0);
+	/* Config for direct link */
+	if (id == MDP_COMP_CAMIN) {
+		if (isp_ctrl[ISP_CTRL_MDP_ASYNC_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_MDP_ASYNC_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+
+		if (isp_ctrl[ISP_CTRL_ISP_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_ISP_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+	}
+	if (id == MDP_COMP_CAMIN2) {
+		if (isp_ctrl[ISP_CTRL_MDP_ASYNC_IPU_CFG_WD]) {
+			reg = mmsys->addr +
+			      isp_ctrl[ISP_CTRL_MDP_ASYNC_IPU_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+		if (isp_ctrl[ISP_CTRL_IPU_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_CTRL_IPU_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->subsys_id, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_camin_ctrl);
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct platform_device *clks;
 	struct platform_device *drm;
 	struct mtk_mmsys *mmsys;
+	struct resource res;
+	struct cmdq_client_reg cmdq_reg;
 	int ret;
 
 	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
@@ -110,6 +265,15 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	if (of_address_to_resource(dev->of_node, 0, &res) < 0)
+		mmsys->addr = 0L;
+	else
+		mmsys->addr = res.start;
+
+	if (cmdq_dev_get_client_reg(dev, &cmdq_reg, 0) != 0)
+		dev_info(dev, "cmdq subsys id has not been set\n");
+	mmsys->subsys_id = cmdq_reg.subsys;
+
 	mmsys->data = of_device_get_match_data(&pdev->dev);
 	platform_set_drvdata(pdev, mmsys);
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index a760a34e6eca..025d4bc9c8cc 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -74,9 +74,12 @@ struct mtk_mmsys_routes {
 };
 
 struct mtk_mmsys_driver_data {
-	const char *clk_driver;
-	const struct mtk_mmsys_routes *routes;
-	const unsigned int num_routes;
+	const char		*clk_driver;
+	const struct		mtk_mmsys_routes *routes;
+	const unsigned int	num_routes;
+	const struct		mtk_mmsys_routes *mdp_routes;
+	const unsigned int	mdp_num_routes;
+	const unsigned int	*mdp_isp_ctrl;
 };
 
 /*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 2228bf6133da..4eb48d073d2a 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -7,8 +7,14 @@
 #define __MTK_MMSYS_H
 
 enum mtk_ddp_comp_id;
+enum mtk_mdp_comp_id;
 struct device;
 
+struct mmsys_cmdq_cmd {
+	struct cmdq_pkt *pkt;
+	s32 *event;
+};
+
 enum mtk_ddp_comp_id {
 	DDP_COMPONENT_AAL0,
 	DDP_COMPONENT_AAL1,
@@ -42,6 +48,64 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_ID_MAX,
 };
 
+enum mtk_mdp_comp_id {
+	MDP_COMP_NONE = -1,	/* Invalid engine */
+
+	/* ISP */
+	MDP_COMP_WPEI = 0,
+	MDP_COMP_WPEO,		/* 1 */
+	MDP_COMP_WPEI2,		/* 2 */
+	MDP_COMP_WPEO2,		/* 3 */
+	MDP_COMP_ISP_IMGI,	/* 4 */
+	MDP_COMP_ISP_IMGO,	/* 5 */
+	MDP_COMP_ISP_IMG2O,	/* 6 */
+
+	/* IPU */
+	MDP_COMP_IPUI,		/* 7 */
+	MDP_COMP_IPUO,		/* 8 */
+
+	/* MDP */
+	MDP_COMP_CAMIN,		/* 9 */
+	MDP_COMP_CAMIN2,	/* 10 */
+	MDP_COMP_RDMA0,		/* 11 */
+	MDP_COMP_AAL0,		/* 12 */
+	MDP_COMP_CCORR0,	/* 13 */
+	MDP_COMP_RSZ0,		/* 14 */
+	MDP_COMP_RSZ1,		/* 15 */
+	MDP_COMP_TDSHP0,	/* 16 */
+	MDP_COMP_COLOR0,	/* 17 */
+	MDP_COMP_PATH0_SOUT,	/* 18 */
+	MDP_COMP_PATH1_SOUT,	/* 19 */
+	MDP_COMP_WROT0,		/* 20 */
+	MDP_COMP_WDMA,		/* 21 */
+
+	/* Dummy Engine */
+	MDP_COMP_RDMA1,		/* 22 */
+	MDP_COMP_RSZ2,		/* 23 */
+	MDP_COMP_TDSHP1,	/* 24 */
+	MDP_COMP_WROT1,		/* 25 */
+
+	MDP_MAX_COMP_COUNT	/* ALWAYS keep at the end */
+};
+
+enum mtk_mdp_pipe_id {
+	MDP_PIPE_RDMA0,
+	MDP_PIPE_IMGI,
+	MDP_PIPE_WPEI,
+	MDP_PIPE_WPEI2,
+	MDP_PIPE_MAX
+};
+
+enum mtk_isp_ctrl {
+	ISP_CTRL_MMSYS_SW0_RST_B,
+	ISP_CTRL_MMSYS_SW1_RST_B,
+	ISP_CTRL_MDP_ASYNC_CFG_WD,
+	ISP_CTRL_MDP_ASYNC_IPU_CFG_WD,
+	ISP_CTRL_ISP_RELAY_CFG_WD,
+	ISP_CTRL_IPU_RELAY_CFG_WD,
+	ISP_CTRL_MAX
+};
+
 void mtk_mmsys_ddp_connect(struct device *dev,
 			   enum mtk_ddp_comp_id cur,
 			   enum mtk_ddp_comp_id next);
@@ -50,4 +114,21 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id cur,
 			      enum mtk_ddp_comp_id next);
 
+void mtk_mmsys_mdp_connect(struct device *dev,
+			   struct mmsys_cmdq_cmd *cmd,
+			   enum mtk_mdp_comp_id cur,
+			   enum mtk_mdp_comp_id next);
+
+void mtk_mmsys_mdp_disconnect(struct device *dev,
+			      struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id cur,
+			      enum mtk_mdp_comp_id next);
+
+void mtk_mmsys_mdp_isp_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			    enum mtk_mdp_comp_id id);
+
+void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id id,
+			      u32 camin_w, u32 camin_h);
+
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0

From ck.hu at mediatek.com  Tue Aug 24 03:14:43 2021
From: ck.hu at mediatek.com (CK Hu)
Date: Tue, 24 Aug 2021 18:14:43 +0800
Subject: [PATCH v5 2/5] dt-bindings: gce: add gce header file for mt8195
In-Reply-To: <20210818024037.11396-3-jason-jh.lin@mediatek.com>
References: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
 <20210818024037.11396-3-jason-jh.lin@mediatek.com>
Message-ID: <1629800083.22373.4.camel@mtksdaap41>

Hi, Jason:

On Wed, 2021-08-18 at 10:40 +0800, jason-jh.lin wrote:
> To define the subsys id and event id, add gce header file for mt8195.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
>  include/dt-bindings/gce/mt8195-gce.h | 920 +++++++++++++++++++++++++++
>  1 file changed, 920 insertions(+)
>  create mode 100644 include/dt-bindings/gce/mt8195-gce.h
> 
> diff --git a/include/dt-bindings/gce/mt8195-gce.h b/include/dt-bindings/gce/mt8195-gce.h
> new file mode 100644
> index 000000000000..8c309e59491d
> --- /dev/null
> +++ b/include/dt-bindings/gce/mt8195-gce.h
> @@ -0,0 +1,920 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2018 MediaTek Inc.
> + *
> + */
> +
> +#ifndef _DT_BINDINGS_GCE_MT8195_H
> +#define _DT_BINDINGS_GCE_MT8195_H
> +
> +/* assign timeout 0 also means default */
> +#define CMDQ_NO_TIMEOUT		0xffffffff
> +#define CMDQ_TIMEOUT_DEFAULT	1000
> +
> +/* GCE thread priority */
> +#define CMDQ_THR_PRIO_LOWEST	0
> +#define CMDQ_THR_PRIO_1		1
> +#define CMDQ_THR_PRIO_2		2
> +#define CMDQ_THR_PRIO_3		3
> +#define CMDQ_THR_PRIO_4		4
> +#define CMDQ_THR_PRIO_5		5
> +#define CMDQ_THR_PRIO_6		6
> +#define CMDQ_THR_PRIO_HIGHEST	7
> +
> +/* CPR count in 32bit register */
> +#define GCE_CPR_COUNT		1312
> +
> +/* GCE subsys table */
> +#define SUBSYS_1400XXXX		0
> +#define SUBSYS_1401XXXX		1
> +#define SUBSYS_1402XXXX		2
> +#define SUBSYS_1c00XXXX		3
> +#define SUBSYS_1c01XXXX		4
> +#define SUBSYS_1c02XXXX		5
> +#define SUBSYS_1c10XXXX		6
> +#define SUBSYS_1c11XXXX		7
> +#define SUBSYS_1c12XXXX		8
> +#define SUBSYS_14f0XXXX		9
> +#define SUBSYS_14f1XXXX		10
> +#define SUBSYS_14f2XXXX		11
> +#define SUBSYS_1800XXXX		12
> +#define SUBSYS_1801XXXX		13
> +#define SUBSYS_1802XXXX		14
> +#define SUBSYS_1803XXXX		15
> +#define SUBSYS_1032XXXX		16
> +#define SUBSYS_1033XXXX		17
> +#define SUBSYS_1600XXXX		18
> +#define SUBSYS_1601XXXX		19
> +#define SUBSYS_14e0XXXX		20
> +#define SUBSYS_1c20XXXX		21
> +#define SUBSYS_1c30XXXX		22
> +#define SUBSYS_1c40XXXX		23
> +#define SUBSYS_1c50XXXX		24
> +#define SUBSYS_1c60XXXX		25
> +#define SUBSYS_NO_SUPPORT	99

Why define SUBSYS_NO_SUPPORT?

> +
> +/* GCE General Purpose Register (GPR) support
> + * Leave note for scenario usage here
> + */
> +/* GCE: write mask */
> +#define GCE_GPR_R00		0x00
> +#define GCE_GPR_R01		0x01
> +/* MDP: P1: JPEG dest */
> +#define GCE_GPR_R02		0x02
> +#define GCE_GPR_R03		0x03
> +/* MDP: PQ color */
> +#define GCE_GPR_R04		0x04
> +/* MDP: 2D sharpness */
> +#define GCE_GPR_R05		0x05
> +/* DISP: poll esd */
> +#define GCE_GPR_R06		0x06
> +#define GCE_GPR_R07		0x07
> +/* MDP: P4: 2D sharpness dst */
> +#define GCE_GPR_R08		0x08
> +#define GCE_GPR_R09		0x09
> +/* VCU: poll with timeout for GPR timer */
> +#define GCE_GPR_R10		0x0A
> +#define GCE_GPR_R11		0x0B
> +/* CMDQ: debug */
> +#define GCE_GPR_R12		0x0C
> +#define GCE_GPR_R13		0x0D
> +/* CMDQ: P7: debug */
> +#define GCE_GPR_R14		0x0E
> +#define GCE_GPR_R15		0x0F

GPR is general purpose register, so do not limit the usage of each GPR.

> +

[snip]

> +
> +/* end of hw event */
> +#define CMDQ_MAX_HW_EVENT				1019
> +
> +/* sw token should use the unused event id from 0 to 1023 */

SW token usage could be changed by different software design. So do not
define in binding document.

Regards,
CK

> +#define CMDQ_SYNC_TOKEN_INVALID				(-1)
> +
> +/* Event for imgsys flow control */
> +#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_EIS			33
> +#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_TNR			34
> +#define CMDQ_SYNC_TOKEN_IMGSYS_TRAW			35
> +#define CMDQ_SYNC_TOKEN_IMGSYS_LTRAW			36
> +#define CMDQ_SYNC_TOKEN_IMGSYS_DIP			37
> +#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_A			38
> +#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_B			39
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_1			41
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_2			42
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_3			43
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_4			44
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_5			45
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_6			46
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_7			47
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_8			48
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_9			49
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_10			50
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_11			51
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_12			52
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_13			53
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_14			54
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_15			55
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_16			56
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_17			57
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_18			58
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_19			59
> +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_20			60
> +/* Config thread notify trigger thread */
> +#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY			971
> +/* Trigger thread notify config thread */
> +#define CMDQ_SYNC_TOKEN_STREAM_EOF			972
> +/* Block Trigger thread until the ESD check finishes. */
> +#define CMDQ_SYNC_TOKEN_ESD_EOF				973
> +#define CMDQ_SYNC_TOKEN_STREAM_BLOCK			974
> +/* check CABC setup finish */
> +#define CMDQ_SYNC_TOKEN_CABC_EOF			975
> +/* Pass-2 notifies VENC frame is ready to be encoded */
> +#define CMDQ_SYNC_TOKEN_VENC_INPUT_READY		976
> +/* VENC notifies Pass-2 encode done so next frame may start */
> +#define CMDQ_SYNC_TOKEN_VENC_EOF			977
> +
> +/* Notify normal CMDQ there are some secure task done
> + * MUST NOT CHANGE, this token sync with secure world
> + */
> +#define CMDQ_SYNC_SECURE_THR_EOF			980
> +#define CMDQ_SYNC_SECURE_THR_EOF_DBG			995
> +
> +/* CMDQ use sw token */
> +#define CMDQ_SYNC_TOKEN_USER_0				981
> +#define CMDQ_SYNC_TOKEN_USER_1				982
> +#define CMDQ_SYNC_TOKEN_POLL_MONITOR			983
> +#define CMDQ_SYNC_TOKEN_TPR_LOCK			984
> +
> +/* ISP sw token */
> +#define CMDQ_SYNC_TOKEN_MSS				985
> +#define CMDQ_SYNC_TOKEN_MSF				986
> +
> +/* GPR access tokens (for register backup)
> + * There are 15 32-bit GPR, 3 GPR form a set
> + * (64-bit for address, 32-bit for value)
> + * MUST NOT CHANGE, these tokens sync with MDP
> + */
> +#define CMDQ_SYNC_TOKEN_GPR_SET_0			987
> +#define CMDQ_SYNC_TOKEN_GPR_SET_1			988
> +#define CMDQ_SYNC_TOKEN_GPR_SET_2			989
> +#define CMDQ_SYNC_TOKEN_GPR_SET_3			990
> +#define CMDQ_SYNC_TOKEN_GPR_SET_4			991
> +
> +/* Resource lock event to control resource in GCE thread */
> +#define CMDQ_SYNC_RESOURCE_WROT0			992
> +#define CMDQ_SYNC_RESOURCE_WROT1			993
> +
> +/* Event for gpr timer, used in sleep and poll with timeout */
> +#define CMDQ_TOKEN_GPR_TIMER_R0				996
> +#define CMDQ_TOKEN_GPR_TIMER_R1				997
> +#define CMDQ_TOKEN_GPR_TIMER_R2				998
> +#define CMDQ_TOKEN_GPR_TIMER_R3				999
> +#define CMDQ_TOKEN_GPR_TIMER_R4				1000
> +#define CMDQ_TOKEN_GPR_TIMER_R5				1001
> +#define CMDQ_TOKEN_GPR_TIMER_R6				1002
> +#define CMDQ_TOKEN_GPR_TIMER_R7				1003
> +#define CMDQ_TOKEN_GPR_TIMER_R8				1004
> +#define CMDQ_TOKEN_GPR_TIMER_R9				1005
> +#define CMDQ_TOKEN_GPR_TIMER_R10			1006
> +#define CMDQ_TOKEN_GPR_TIMER_R11			1007
> +#define CMDQ_TOKEN_GPR_TIMER_R12			1008
> +#define CMDQ_TOKEN_GPR_TIMER_R13			1009
> +#define CMDQ_TOKEN_GPR_TIMER_R14			1010
> +#define CMDQ_TOKEN_GPR_TIMER_R15			1011
> +
> +/* defined in mtk-cmdq-mailbox.h */
> +/* #define CMDQ_EVENT_MAX					0x3ff */
> +
> +#endif


From sugar.zhang at rock-chips.com  Tue Aug 24 03:15:58 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Tue, 24 Aug 2021 18:15:58 +0800
Subject: [PATCH v1 0/4] Patches to update for rockchip spdif
Message-ID: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>

These patches fixup or update for rockchip spdif.


Sugar Zhang (4):
  ASoC: rockchip: spdif: Mark SPDIF_SMPDR as volatile
  ASoC: rockchip: spdif: Fix some coding style
  ASoC: rockchip: spdif: Add support for rk3568 spdif
  ASoC: dt-bindings: rockchip: Add compatible for rk3568 spdif

 .../devicetree/bindings/sound/rockchip-spdif.yaml  |  1 +
 sound/soc/rockchip/rockchip_spdif.c                | 38 ++++++++++++----------
 2 files changed, 22 insertions(+), 17 deletions(-)

-- 
2.7.4





From sugar.zhang at rock-chips.com  Tue Aug 24 03:15:59 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Tue, 24 Aug 2021 18:15:59 +0800
Subject: [PATCH v1 1/4] ASoC: rockchip: spdif: Mark SPDIF_SMPDR as volatile
In-Reply-To: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <1629800162-12824-2-git-send-email-sugar.zhang@rock-chips.com>

This patch marks SPDIF_SMPDR as volatile to make it resaonable,
which also requires marking it as readable, even though it isn't.

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

 sound/soc/rockchip/rockchip_spdif.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
index 73226a4..8baa473 100644
--- a/sound/soc/rockchip/rockchip_spdif.c
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -247,6 +247,7 @@ static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg)
 	case SPDIF_INTCR:
 	case SPDIF_INTSR:
 	case SPDIF_XFER:
+	case SPDIF_SMPDR:
 		return true;
 	default:
 		return false;
@@ -258,6 +259,7 @@ static bool rk_spdif_volatile_reg(struct device *dev, unsigned int reg)
 	switch (reg) {
 	case SPDIF_INTSR:
 	case SPDIF_SDBLR:
+	case SPDIF_SMPDR:
 		return true;
 	default:
 		return false;
-- 
2.7.4





From sugar.zhang at rock-chips.com  Tue Aug 24 03:16:01 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Tue, 24 Aug 2021 18:16:01 +0800
Subject: [PATCH v1 3/4] ASoC: rockchip: spdif: Add support for rk3568 spdif
In-Reply-To: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <1629800162-12824-4-git-send-email-sugar.zhang@rock-chips.com>

This patch adds support for rk3568 spdif which is the same
with rk3366.

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

 sound/soc/rockchip/rockchip_spdif.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
index 92b27b6..d027ca4 100644
--- a/sound/soc/rockchip/rockchip_spdif.c
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -58,6 +58,8 @@ static const struct of_device_id rk_spdif_match[] __maybe_unused = {
 	  .data = (void *)RK_SPDIF_RK3366 },
 	{ .compatible = "rockchip,rk3399-spdif",
 	  .data = (void *)RK_SPDIF_RK3366 },
+	{ .compatible = "rockchip,rk3568-spdif",
+	  .data = (void *)RK_SPDIF_RK3366 },
 	{},
 };
 MODULE_DEVICE_TABLE(of, rk_spdif_match);
-- 
2.7.4





From sugar.zhang at rock-chips.com  Tue Aug 24 03:16:02 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Tue, 24 Aug 2021 18:16:02 +0800
Subject: [PATCH v1 4/4] ASoC: dt-bindings: rockchip: Add compatible for rk3568
 spdif
In-Reply-To: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <1629800162-12824-5-git-send-email-sugar.zhang@rock-chips.com>

This patch adds compatible string for rk3568 spdif.

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

 Documentation/devicetree/bindings/sound/rockchip-spdif.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
index 62a61b6..d0a24bf 100644
--- a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
+++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
@@ -23,6 +23,7 @@ properties:
       - const: rockchip,rk3366-spdif
       - const: rockchip,rk3368-spdif
       - const: rockchip,rk3399-spdif
+      - const: rockchip,rk3568-spdif
       - items:
           - enum:
               - rockchip,rk3188-spdif
-- 
2.7.4





From sugar.zhang at rock-chips.com  Tue Aug 24 03:16:00 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Tue, 24 Aug 2021 18:16:00 +0800
Subject: [PATCH v1 2/4] ASoC: rockchip: spdif: Fix some coding style
In-Reply-To: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <1629800162-12824-3-git-send-email-sugar.zhang@rock-chips.com>

This patch fix some coding style.

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

 sound/soc/rockchip/rockchip_spdif.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
index 8baa473..92b27b6 100644
--- a/sound/soc/rockchip/rockchip_spdif.c
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -103,8 +103,8 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev)
 }
 
 static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
-				  struct snd_pcm_hw_params *params,
-				  struct snd_soc_dai *dai)
+			      struct snd_pcm_hw_params *params,
+			      struct snd_soc_dai *dai)
 {
 	struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
 	unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
@@ -137,15 +137,15 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
 	}
 
 	ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
-		SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE |
-		SDPIF_CFGR_VDW_MASK,
-		val);
+				 SPDIF_CFGR_CLK_DIV_MASK |
+				 SPDIF_CFGR_HALFWORD_ENABLE |
+				 SDPIF_CFGR_VDW_MASK, val);
 
 	return ret;
 }
 
 static int rk_spdif_trigger(struct snd_pcm_substream *substream,
-				int cmd, struct snd_soc_dai *dai)
+			    int cmd, struct snd_soc_dai *dai)
 {
 	struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
 	int ret;
@@ -155,31 +155,31 @@ static int rk_spdif_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
-				   SPDIF_DMACR_TDE_ENABLE |
-				   SPDIF_DMACR_TDL_MASK,
-				   SPDIF_DMACR_TDE_ENABLE |
-				   SPDIF_DMACR_TDL(16));
+					 SPDIF_DMACR_TDE_ENABLE |
+					 SPDIF_DMACR_TDL_MASK,
+					 SPDIF_DMACR_TDE_ENABLE |
+					 SPDIF_DMACR_TDL(16));
 
 		if (ret != 0)
 			return ret;
 
 		ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
-				   SPDIF_XFER_TXS_START,
-				   SPDIF_XFER_TXS_START);
+					 SPDIF_XFER_TXS_START,
+					 SPDIF_XFER_TXS_START);
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
-				   SPDIF_DMACR_TDE_ENABLE,
-				   SPDIF_DMACR_TDE_DISABLE);
+					 SPDIF_DMACR_TDE_ENABLE,
+					 SPDIF_DMACR_TDE_DISABLE);
 
 		if (ret != 0)
 			return ret;
 
 		ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
-				   SPDIF_XFER_TXS_START,
-				   SPDIF_XFER_TXS_STOP);
+					 SPDIF_XFER_TXS_START,
+					 SPDIF_XFER_TXS_STOP);
 		break;
 	default:
 		ret = -EINVAL;
@@ -293,7 +293,7 @@ static int rk_spdif_probe(struct platform_device *pdev)
 		grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
 		if (IS_ERR(grf)) {
 			dev_err(&pdev->dev,
-				"rockchip_spdif missing 'rockchip,grf' \n");
+				"rockchip_spdif missing 'rockchip,grf'\n");
 			return PTR_ERR(grf);
 		}
 
-- 
2.7.4





From yunfei.dong at mediatek.com  Tue Aug 24 03:21:48 2021
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Tue, 24 Aug 2021 18:21:48 +0800
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <CAAEAJfCdvj4drV+YSbvyR30b0+50RpJcOYdEoNODTdrAoL6+vA@mail.gmail.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
 <1b79a67b703d2c894bc4d9458c760e082fc42958.camel@mediatek.com>
 <CAAEAJfCTrKj9AFExN-L-TKww4E=us1VVh8LHtZ8Q0j_eaCD4Eg@mail.gmail.com>
 <1629446378.18871.27.camel@mhfsdcap03>
 <CAAEAJfCdvj4drV+YSbvyR30b0+50RpJcOYdEoNODTdrAoL6+vA@mail.gmail.com>
Message-ID: <6224223ec1ead769f281af54f93bd3142a8e212b.camel@mediatek.com>

Hi Ezequiel,

Thanks for your suggestion.

On Sun, 2021-08-22 at 11:32 -0300, Ezequiel Garcia wrote:
> On Fri, 20 Aug 2021 at 04:59, yunfei.dong at mediatek.com
> <yunfei.dong at mediatek.com> wrote:
> > 
> > Hi Ezequiel,
> > 
> > Thanks for your detail feedback.
> > 
> > On Thu, 2021-08-19 at 11:10 -0300, Ezequiel Garcia wrote:
> > > On Thu, 19 Aug 2021 at 04:13, yunfei.dong at mediatek.com
> > > <yunfei.dong at mediatek.com> wrote:
> > > > 
> > > > Hi Ezequiel,
> > > > 
> > > > Thanks for your suggestion.
> > > > 
> > > > On Wed, 2021-08-18 at 11:11 -0300, Ezequiel Garcia wrote:
> > > > > +danvet
> > > > > 
> > > > > Hi,
> > > > > 
> > > > > On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <
> > > > > yunfei.dong at mediatek.com>
> > > > > wrote:
> > > > > > 
> > > > > > This series adds support for multi hardware decode into
> > > > > > mtk-vcodec,
> > > > > > by first
> > > > > > adding component framework to manage each hardware
> > > > > > information:
> > > > > > interrupt,
> > > > > > clock, register bases and power. Secondly add core thread
> > > > > > to deal
> > > > > > with core
> > > > > > hardware message, at the same time, add msg queue for
> > > > > > different
> > > > > > hardware
> > > > > > share messages. Lastly, the architecture of different specs
> > > > > > are not
> > > > > > the same,
> > > > > > using specs type to separate them.
> > > > > > 
> > > > > 
> > > > > I don't think it's a good idea to introduce the component API
> > > > > in the
> > > > > media subsystem. It doesn't seem to be maintained, IRC
> > > > > there's not
> > > > > even
> > > > > a maintainer for it, and it has some issues that were never
> > > > > addressed.
> > > > > 
> > > > > It would be really important to avoid it. Is it really needed
> > > > > in the
> > > > > first place?
> > > > > 
> > > > > Thanks,
> > > > > Ezequiel
> > > > 
> > > > For there are many hardware need to use, mt8192 is three and
> > > > mt8195 is
> > > > five. Maybe need more to be used in the feature.
> > > > 
> > > > Each hardware has independent clk/power/iommu port/irq.
> > > > Use component interface in prob to get each component's
> > > > information.
> > > > Just enable the hardware when need to use it, very convenient
> > > > and
> > > > simple.
> > > > 
> > > > I found that there are many modules use component to manage
> > > > hardware
> > > > information, such as iommu and drm etc.
> > > > 
> > > 
> > > Many drivers support multiple hardware variants, where each
> > > variant
> > > has a different number of clocks or interrupts, see for instance
> > > struct hantro_variant which allows to expose different codec
> > > cores,
> > > some having both decoder/encoder, and some having just a decoder.
> > > 
> > > The component API is mostly used by DRM to aggregate independent
> > > subdevices (called components) into an aggregated driver.
> > > 
> > > For instance, a DRM driver needs to glue together the HDMI, MIPI,
> > > and plany controller, or any other hardware arrangement where
> > > devices can be described independently.
> > > 
> > 
> > The usage scenario is very similar with drm and iommu, So decide to
> > use
> > component framework.
> > Decode has three/five or more hardwares, these hardware are
> > independent.
> > For mt8183 just need core hardware to decode, but mt8192 has
> > lat,soc and
> > core hardware to decode. When lat need to use, just enable lat
> > hardware,
> > core is the same.And mt8195 will has two cores, each core can work
> > well
> > independent.
> > 
> > For each component device just used to open their power/clk/iommu
> > port/irq when master need to enable it. The main logic is in master
> > device.
> > 
> > > The component API may look simple but has some issues, it's not
> > > easy
> > > to debug, and can cause troubles if not used as expected [1].
> > > It's worth making sure you actually need a framework
> > > to glue different devices together.
> > > 
> > 
> > Each hardware has its index, master can get hardware information
> > according these index, looks not complex. What do you mean about
> > not
> > easy to debug?
> > 
> > > > Do you have any other suggestion for this architecture?
> > > > 
> > > 
> > > Looking at the different patchsets that are posted, it's not
> > > clear
> > > to me what exactly are the different architectures that you
> > > intend
> > > to support, can you some documentation which clarifies that?
> > > 
> > 
> > Have five hardwares lat,soc,core0,core1 and main. Lat thread can
> > use lat
> > soc and main, core thread can use soc,lat, core0 and core1. Core
> > thread
> > can be used or not for different project.
> 
> Can you explain what are these lat,soc and core threads for?
> 
You can regards lat,soc and core as hardware, each hardware can work
independent. Lat and core threads used to control hardware to decode.
> > Also Need to use these
> > hardware dynamic at the same time. So I use component framework,
> > just
> > need to know the used  hardware index according to different
> > project.Need not to do complex logic to manage these hardwares.
> > 
> 
> I am not thrilled to see the component framework introduced to the
> media subsystem. Like I said, it has no clear maintainer, and it's
> not
> easy to use.
> 
How do you think about Deniel Vetter's mail ? It looks that there are
maintainer for it.
> The media subsystem has some support which AFAIK does the same thing,
> see v4l2-async, which is maintained by media people.
> 
If component can be used, I prefer to use it. At the other hand, I will
try to use these method as compared.
> Please push a branch based on media/master containing these changes.
> I see there are other patch series for this device, but it's hard to
> track
> which goes first, etc.
> 
I need time to push a branch, or you can get the latest kernel and git
am these patches, maybe much quicker.
> Thanks,
> Ezequiel

Thanks,
Yunfei Dong

From tzungbi at google.com  Tue Aug 24 03:24:29 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Tue, 24 Aug 2021 18:24:29 +0800
Subject: [PATCH 5/9] media: mtk-vcodec: Rewrite venc clock interface
In-Reply-To: <20210816105934.28265-6-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-6-irui.wang@mediatek.com>
Message-ID: <YSTI3QjTnGZEgwOM@google.com>

On Mon, Aug 16, 2021 at 06:59:30PM +0800, Irui Wang wrote:
> -void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
> +void mtk_vcodec_enc_clock_on(struct mtk_vcodec_dev *dev, int core_id)
>  {
> -	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
> -	int ret, i = 0;
> +	struct mtk_venc_comp_dev *venc;
> +	struct mtk_vcodec_pm *enc_pm;
> +	struct mtk_vcodec_clk *enc_clk;
> +	struct clk		*clk;
To be neat, remove the extra spaces.

> -	ret = mtk_smi_larb_get(pm->larbvenc);
> -	if (ret) {
> -		mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret);
> -		goto clkerr;
I may miss the context but why does it remove mtk_smi_larb_get()?

> -void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
> +void mtk_vcodec_enc_clock_off(struct mtk_vcodec_dev *dev, int core_id)
>  {
> -	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
> -	int i = 0;
> +	struct mtk_venc_comp_dev *venc;
> +	struct mtk_vcodec_pm *enc_pm;
> +	struct mtk_vcodec_clk *enc_clk;
> +	int i;
>  
> -	mtk_smi_larb_put(pm->larbvenc);
Same here.  Why does it remove mtk_smi_larb_put()?

>  int mtk_venc_enable_comp_hw(struct mtk_vcodec_dev *dev)
>  {
>  	int i, ret;
>  	struct mtk_venc_comp_dev *venc_comp;
> +	struct mtk_vcodec_clk *enc_clk;
> +	int j = 0;
It doesn't need to be initialized.  Can inline to "int i, ret;".


From catalin.marinas at arm.com  Tue Aug 24 03:32:14 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 11:32:14 +0100
Subject: [PATCH] arm64/sve: Better handle failure to allocate SVE
 register storage
In-Reply-To: <20210817171330.25847-1-broonie@kernel.org>
References: <20210817171330.25847-1-broonie@kernel.org>
Message-ID: <20210824103213.GA623@arm.com>

On Tue, Aug 17, 2021 at 06:13:30PM +0100, Mark Brown wrote:
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index eb8d972ad3d2..5a294f20e9de 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -520,12 +520,6 @@ void sve_alloc(struct task_struct *task)
>  	/* This is a small allocation (maximum ~8KB) and Should Not Fail. */
>  	task->thread.sve_state =
>  		kzalloc(sve_state_size(task), GFP_KERNEL);
> -
> -	/*
> -	 * If future SVE revisions can have larger vectors though,
> -	 * this may cease to be true:
> -	 */
> -	BUG_ON(!task->thread.sve_state);
>  }

I think we should keep a WARN_ON_ONCE here in case one wonders why the
app was suddenly killed.

-- 
Catalin


From will at kernel.org  Tue Aug 24 03:42:35 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 24 Aug 2021 11:42:35 +0100
Subject: [PATCH v2] arm64: head: avoid over-mapping in map_memory
In-Reply-To: <20210823101253.55567-1-mark.rutland@arm.com>
References: <20210823101253.55567-1-mark.rutland@arm.com>
Message-ID: <20210824104234.GA22752@willie-the-truck>

On Mon, Aug 23, 2021 at 11:12:53AM +0100, Mark Rutland wrote:
> The `compute_indices` and `populate_entries` macros operate on inclusive
> bounds, and thus the `map_memory` macro which uses them also operates
> on inclusive bounds.
> 
> We pass `_end` and `_idmap_text_end` to `map_memory`, but these are
> exclusive bounds, and if one of these is sufficiently aligned (as a
> result of kernel configuration, physical placement, and KASLR), then:
> 
> * In `compute_indices`, the computed `iend` will be in the page/block *after*
>   the final byte of the intended mapping.
> 
> * In `populate_entries`, an unnecessary entry will be created at the end
>   of each level of table. At the leaf level, this entry will map up to
>   SWAPPER_BLOCK_SIZE bytes of physical addresses that we did not intend
>   to map.
> 
> As we may map up to SWAPPER_BLOCK_SIZE bytes more than intended, we may
> violate the boot protocol and map physical address past the 2MiB-aligned
> end address we are permitted to map. As we map these with Normal memory
> attributes, this may result in further problems depending on what these
> physical addresses correspond to.
> 
> The final entry at each level may require an additional table at that
> level. As EARLY_ENTRIES() calculates an inclusive bound, we allocate
> enough memory for this.
> 
> Avoid the extraneous mapping by having map_memory convert the exclusive
> end address to an inclusive end address by subtracting one, and do
> likewise in EARLY_ENTRIES() when calculating the number of required
> tables. For clarity, comments are updated to more clearly document which
> boundaries the macros operate on.  For consistency with the other
> macros, the comments in map_memory are also updated to describe `vstart`
> and `vend` as virtual addresses.
> 
> Fixes: 0370b31e48454d8c ("arm64: Extend early page table code to allow for larger kernel")
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Steve Capper <steve.capper at arm.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/kernel-pgtable.h |  4 ++--
>  arch/arm64/kernel/head.S                | 11 ++++++-----
>  2 files changed, 8 insertions(+), 7 deletions(-)

Acked-by: Will Deacon <will at kernel.org>

Will


From catalin.marinas at arm.com  Tue Aug 24 03:49:01 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 11:49:01 +0100
Subject: [PATCH 5/5] arm64: Document the requirement for SCR_EL3.HCE
In-Reply-To: <20210812190213.2601506-6-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-6-maz@kernel.org>
Message-ID: <20210824104900.GB623@arm.com>

On Thu, Aug 12, 2021 at 08:02:13PM +0100, Marc Zyngier wrote:
> It is amazing that we never documented this absolutely basic
> requirement: if you boot the kernel at EL2, you'd better
> enable the HVC instruction from EL3.
> 
> Really, just do it.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  Documentation/arm64/booting.rst | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
> index a9192e7a231b..6c729d0c4bc2 100644
> --- a/Documentation/arm64/booting.rst
> +++ b/Documentation/arm64/booting.rst
> @@ -212,6 +212,11 @@ Before jumping into the kernel, the following conditions must be met:
>    - The value of SCR_EL3.FIQ must be the same as the one present at boot
>      time whenever the kernel is executing.
>  
> +  For all systems:
> +  - If EL3 is present and the kernel is entered at EL2:
> +
> +    - SCR_EL3.HCE (bit 8) must be initialised to 0b1.
> +
>    For systems with a GICv3 interrupt controller to be used in v3 mode:
>    - If EL3 is present:

I'll queue this patch only for now.

A nitpick, I think we should move "For all systems" and "If EL3 is
present..." above the lines describing the SCR_EL3.FIQ requirement (I
can make the change locally).

-- 
Catalin


From mark.rutland at arm.com  Tue Aug 24 03:50:01 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 11:50:01 +0100
Subject: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210818073336.59678-3-liuqi115@huawei.com>
References: <20210818073336.59678-1-liuqi115@huawei.com>
 <20210818073336.59678-3-liuqi115@huawei.com>
Message-ID: <20210824105001.GA96738@C02TD0UTHF1T.local>

Hi,

I have a bunch of comments below.

At a high-level, I'm not all that keen on adding yet another set of
trampolines, especially given we have constraints on how we can branch
to them which render this not that useful in common configurations (e.g.
where KASLR and module randomization is enabled).

So importantly, do we actually need this? I don't think the sampel is
that compelling since we can already use ftrace to measure function
latencies.

If we do need this, I think we need to do some more substantial rework
to address those branch range limitations. I know that we could permit
arbitrary branching if we expand the ftrace-with-regs callsites to ~6
instructions, but that interacts rather poorly with stacktracing and
will make the kernel a bit bigger.

On Wed, Aug 18, 2021 at 03:33:36PM +0800, Qi Liu wrote:
> This patch introduce optprobe for ARM64. In optprobe, probed
> instruction is replaced by a branch instruction to detour
> buffer. Detour buffer contains trampoline code and a call to
> optimized_callback(). optimized_callback() calls opt_pre_handler()
> to execute kprobe handler.
> 
> Performance of optprobe on Hip08 platform is test using kprobe
> example module[1] to analyze the latency of a kernel function,
> and here is the result:
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> 
> kprobe before optimized:
> [280709.846380] do_empty returned 0 and took 1530 ns to execute
> [280709.852057] do_empty returned 0 and took 550 ns to execute
> [280709.857631] do_empty returned 0 and took 440 ns to execute
> [280709.863215] do_empty returned 0 and took 380 ns to execute
> [280709.868787] do_empty returned 0 and took 360 ns to execute
> [280709.874362] do_empty returned 0 and took 340 ns to execute
> [280709.879936] do_empty returned 0 and took 320 ns to execute
> [280709.885505] do_empty returned 0 and took 300 ns to execute
> [280709.891075] do_empty returned 0 and took 280 ns to execute
> [280709.896646] do_empty returned 0 and took 290 ns to execute
> [280709.902220] do_empty returned 0 and took 290 ns to execute
> [280709.907807] do_empty returned 0 and took 290 ns to execute
> 
> optprobe:
> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> [ 2966.029158] do_empty returned 0 and took 70 ns to execute

Do we have any examples of where this latency matters in practice?

> 
> Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> 
> Note:
> To guarantee the offset between probe point and kprobe pre_handler
> is smaller than 128MiB, users should set
> CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
> optprobe will not work and fall back to normal kprobe.

Hmm... I don't think that's something we want to recommend, and
certainly distros *should* use KASLR and
CONFIG_RANDOMIZE_MODULE_REGION_FULL.

What happens with defconfig? Do we always get the fallback behaviour?

> ---
>  arch/arm64/Kconfig                            |   1 +
>  arch/arm64/include/asm/kprobes.h              |  24 ++
>  arch/arm64/kernel/probes/Makefile             |   2 +
>  arch/arm64/kernel/probes/kprobes.c            |  19 +-
>  arch/arm64/kernel/probes/opt_arm64.c          | 276 ++++++++++++++++++
>  .../arm64/kernel/probes/optprobe_trampoline.S |  37 +++
>  6 files changed, 356 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm64/kernel/probes/opt_arm64.c
>  create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b5b13a932561..b05d1d275d87 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -200,6 +200,7 @@ config ARM64
>  	select HAVE_STACKPROTECTOR
>  	select HAVE_SYSCALL_TRACEPOINTS
>  	select HAVE_KPROBES
> +	select HAVE_OPTPROBES
>  	select HAVE_KRETPROBES
>  	select HAVE_GENERIC_VDSO
>  	select IOMMU_DMA if IOMMU_SUPPORT
> diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
> index 5d38ff4a4806..6b2fdd2ad7d8 100644
> --- a/arch/arm64/include/asm/kprobes.h
> +++ b/arch/arm64/include/asm/kprobes.h
> @@ -39,6 +39,30 @@ void arch_remove_kprobe(struct kprobe *);
>  int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
>  int kprobe_exceptions_notify(struct notifier_block *self,
>  			     unsigned long val, void *data);
> +
> +#define RELATIVEJUMP_SIZE (4)
> +#define MAX_COPIED_INSN	DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))

On arm64, instructions are always 4 bytes, so this can be:

| #define MAX_COPIED_INSN		AARCH64_INSN_SIZE

Note: AARCH64_INSN_SIZE == sizeof(kprobe_opcode_t), so either could be
used here.

> +struct arch_optimized_insn {
> +	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];

This is always a single insn. For clarity, it would be nicer to call
this something like `orig_insn`.

> +	/* detour code buffer */
> +	kprobe_opcode_t *insn;

Could we call this `trampoline`?

> +};
> +
> +/* optinsn template addresses */
> +extern __visible kprobe_opcode_t optprobe_template_entry[];
> +extern __visible kprobe_opcode_t optprobe_template_val[];
> +extern __visible kprobe_opcode_t optprobe_template_call[];
> +extern __visible kprobe_opcode_t optprobe_template_end[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
> +extern __visible kprobe_opcode_t optprobe_template_restore_end[];
> +extern __visible kprobe_opcode_t optprobe_template_max_length[];

Why is this called "max_length"? It's the end of the template, value
included. Other architectures (e.g. arm) include that between
optprobe_template_entry and optprobe_template_end, so I don't believe we
need to separate that out.

> +
> +#define MAX_OPTIMIZED_LENGTH	4

As above, please define this as either AARCH64_INSN_SIZE or
sizeof(kprobe_opcode_t).

> +#define MAX_OPTINSN_SIZE				\
> +	((unsigned long)optprobe_template_end -	\
> +	 (unsigned long)optprobe_template_entry)

As above, this seems to be the trampoline size minus the size of the
value, which doesn't match other architectures, and doesn't seem right.
The kprobe core code has:

| kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;

... which IIUC is used to alocate the buffers, so surely we *must* take
the size of the value into account?

> +
>  void kretprobe_trampoline(void);
>  void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
>  
> diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
> index 8e4be92e25b1..07105fd3261d 100644
> --- a/arch/arm64/kernel/probes/Makefile
> +++ b/arch/arm64/kernel/probes/Makefile
> @@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)		+= kprobes.o decode-insn.o	\
>  				   simulate-insn.o
>  obj-$(CONFIG_UPROBES)		+= uprobes.o decode-insn.o	\
>  				   simulate-insn.o
> +obj-$(CONFIG_OPTPROBES)		+= opt_arm64.o			\
> +				   optprobe_trampoline.o
> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> index 6dbcc89f6662..83755ad62abe 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> @@ -11,6 +11,7 @@
>  #include <linux/kasan.h>
>  #include <linux/kernel.h>
>  #include <linux/kprobes.h>
> +#include <linux/moduleloader.h>
>  #include <linux/sched/debug.h>
>  #include <linux/set_memory.h>
>  #include <linux/slab.h>
> @@ -113,9 +114,21 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
>  
>  void *alloc_insn_page(void)
>  {
> -	return __vmalloc_node_range(PAGE_SIZE, 1, VMALLOC_START, VMALLOC_END,
> -			GFP_KERNEL, PAGE_KERNEL_ROX, VM_FLUSH_RESET_PERMS,
> -			NUMA_NO_NODE, __builtin_return_address(0));
> +	void *page;
> +
> +	page = module_alloc(PAGE_SIZE);
> +	if (!page)
> +		return NULL;
> +
> +	set_vm_flush_reset_perms(page);
> +	/*
> +	 * First make the page read-only, and only then make it executable to
> +	 * prevent it from being W+X in between.
> +	 */
> +	set_memory_ro((unsigned long)page, 1);
> +	set_memory_x((unsigned long)page, 1);
> +
> +	return page;
>  }

Today this is only used for xol pages, which don't need to live in the
module space. Why is this not a separate function?

>  /* arm kprobe: install breakpoint in text */
> diff --git a/arch/arm64/kernel/probes/opt_arm64.c b/arch/arm64/kernel/probes/opt_arm64.c
> new file mode 100644
> index 000000000000..4de535bee534
> --- /dev/null
> +++ b/arch/arm64/kernel/probes/opt_arm64.c
> @@ -0,0 +1,276 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Code for Kernel probes Jump optimization.
> + *
> + * Copyright (C) 2021 Hisilicon Limited
> + */
> +
> +#include <linux/jump_label.h>
> +#include <linux/kprobes.h>
> +
> +#include <asm/cacheflush.h>
> +#include <asm/insn.h>
> +#include <asm/kprobes.h>
> +#include <asm/patching.h>
> +
> +#define TMPL_VAL_IDX \
> +	(optprobe_template_val - optprobe_template_entry)
> +#define TMPL_CALL_BACK \
> +	(optprobe_template_call - optprobe_template_entry)
> +#define TMPL_END_IDX \
> +	(optprobe_template_end - optprobe_template_entry)
> +#define TMPL_RESTORE_ORIGN_INSN \
> +	(optprobe_template_restore_orig_insn - optprobe_template_entry)
> +#define TMPL_RESTORE_END \
> +	(optprobe_template_restore_end - optprobe_template_entry)
> +#define TMPL_MAX_LENGTH \
> +	(optprobe_template_max_length - optprobe_template_entry)
> +#define OPTPROBE_BATCH_SIZE 64

What is batch size, and why is it 64?

> +
> +int arch_check_optimized_kprobe(struct optimized_kprobe *op)
> +{
> +	return 0;
> +}
> +

The core code has the comment:

|	/* Check there is no other kprobes at the optimized instructions */
|	if (arch_check_optimized_kprobe(op) < 0) 
|		return;

... is that comment misleading, or do we need to do something here?

> +int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
> +{
> +	return optinsn->insn != NULL;
> +}
> +
> +int arch_within_optimized_kprobe(struct optimized_kprobe *op,
> +				unsigned long addr)
> +{
> +	return ((unsigned long)op->kp.addr <= addr &&
> +		(unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
> +}

Since we have a single instruction, and all instructions are naturally aligned 4 bytes, this can be:

|	return (unsigned long)op->kp.addr == addr;

> +
> +static void
> +optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
> +{
> +	/* This is possible if op is under delayed unoptimizing */

I see this is a copy-paste from x86 andor powerpc, but it's a bit hard
to understand, and I'm not sure what it is trying to say. What scenario
is this trying to handle?

I note that arch/arm doesn't seem to do this -- is that a bug?

> +	if (kprobe_disabled(&op->kp))
> +		return;
> +
> +	preempt_disable();
> +
> +	if (kprobe_running()) {
> +		kprobes_inc_nmissed_count(&op->kp);
> +	} else {
> +		__this_cpu_write(current_kprobe, &op->kp);
> +		regs->pc = (unsigned long)op->kp.addr;
> +		get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
> +		opt_pre_handler(&op->kp, regs);
> +		__this_cpu_write(current_kprobe, NULL);
> +	}


The body of this looks like it could be factored out in to the core
kprobes code if we had an arch hook to save any missed registers
(apparently just the pc on arm64).

> +	preempt_enable_no_resched();

Why the `_no_resched` variant? I see that x86 just does a plain
preempt_enable().

> +}
> +NOKPROBE_SYMBOL(optimized_callback)
> +
> +static bool is_offset_in_range(unsigned long start, unsigned long end)
> +{
> +	long offset = end - start;
> +
> +	/*
> +	 * Verify if the address gap is in 128MiB range, because this uses
> +	 * a relative jump.
> +	 *
> +	 * kprobe opt use a 'b' instruction to branch to optinsn.insn.
> +	 * According to ARM manual, branch instruction is:
> +	 *
> +	 *   31  30                  25              0
> +	 *  +----+---+---+---+---+---+---------------+
> +	 *  |cond| 0 | 0 | 1 | 0 | 1 |     imm26     |
> +	 *  +----+---+---+---+---+---+---------------+
> +	 *
> +	 * imm26 is a signed 26 bits integer. The real branch offset is computed
> +	 * by: imm64 = SignExtend(imm26:'00', 64);
> +	 *
> +	 * So the maximum forward branch should be:
> +	 *   (0x01ffffff << 2) = 0x07fffffc
> +	 * The maximum backward branch should be:
> +	 *   (0xfe000000 << 2) = 0xFFFFFFFFF8000000 = -0x08000000
> +	 *
> +	 * We can simply check (rel & 0xf8000003):
> +	 *  if rel is positive, (rel & 0xf8000003) should be 0
> +	 *  if rel is negitive, (rel & 0xf8000003) should be 0xf8000000
> +	 *  the last '3' is used for alignment checking.
> +	 */
> +	return (offset >= -0x8000000 && offset <= 0x7fffffc && !(offset & 0x3));
> +}

Please re-use existing code for this. In insn.c we already have
branch_imm_common() and aarch64_insn_gen_branch_imm(), which we should
be able to refactor for easier usage (and should move ftrace_make_nop()
over to that too).

We could *also* add a aarch64_insn_try_gen_branch_imm() helper that
returns an error code rather than printing an error, which would allow
us to consolidate the checks with the codegen, and would be more robust
if this changes in future.

> +
> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op,
> +				  struct kprobe *orig)
> +{
> +	kprobe_opcode_t *code, *buf;
> +	void **addrs;
> +	u32 insn;
> +	int ret, i;
> +
> +	addrs = kcalloc(TMPL_MAX_LENGTH, sizeof(void *), GFP_KERNEL);
> +	if (!addrs)
> +		return -ENOMEM;

As a general thing, when using allocators, please use sizeof() on the
pointer being allocated, e.g.

	addrs = kcalloc(TMPL_MAX_LENGTH, sizeof(*addrs), GFP_KERNEL);

... as that ensures the type is always correct, even if the type of the
pointer is changed later.

That said, I don't believe this needs to be allocated from the heap.
It's only used for the duration of this function, it's relatively small,
and we could add a wrapper in insn.c to patch a range of instructions,
which would avoid the need for the array entirely.

> +
> +	buf = kcalloc(TMPL_MAX_LENGTH, sizeof(kprobe_opcode_t), GFP_KERNEL);
> +	if (!buf) {
> +		kfree(addrs);
> +		return -ENOMEM;
> +	}
> +
> +	code = get_optinsn_slot();
> +	if (!code) {
> +		kfree(addrs);
> +		kfree(buf);
> +		return -ENOMEM;
> +	}

You can initialize `ret` to -ENOMEM, and goto `out` here.

> +
> +	if (!is_offset_in_range((unsigned long)code,
> +				(unsigned long)orig->addr + 8)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	if (!is_offset_in_range((unsigned long)code + TMPL_CALL_BACK,
> +				(unsigned long)optimized_callback)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	if (!is_offset_in_range((unsigned long)&code[TMPL_RESTORE_END],
> +				(unsigned long)op->kp.addr + 4)) {
> +		ret = -ERANGE;
> +		goto error;
> +	}
> +
> +	memcpy(buf, optprobe_template_entry,
> +	       TMPL_END_IDX * sizeof(kprobe_opcode_t));

Why do we need to copy this into a temporary buffer? Can't we work on it
directly in the destination?

> +
> +	buf[TMPL_VAL_IDX] = FIELD_GET(GENMASK(31, 0), (unsigned long long)op);
> +	buf[TMPL_VAL_IDX + 1] =
> +		FIELD_GET(GENMASK(63, 32), (unsigned long long)op);

This is a 64-bit pointer, and needs to be treated as a single unit. The
above is broken for big-endian kernels.

Rather than using instruction indices (and pretending this pointer is
two instructions), it would be nicer to use byte offsets consistently.

> +	buf[TMPL_RESTORE_ORIGN_INSN] = orig->opcode;
> +
> +	insn = aarch64_insn_gen_branch_imm(
> +		(unsigned long)(&code[TMPL_CALL_BACK]),
> +		(unsigned long)optimized_callback, AARCH64_INSN_BRANCH_LINK);
> +	buf[TMPL_CALL_BACK] = insn;
> +
> +	insn = aarch64_insn_gen_branch_imm(
> +		(unsigned long)(&code[TMPL_RESTORE_END]),
> +		(unsigned long)(op->kp.addr) + 4, AARCH64_INSN_BRANCH_NOLINK);
> +	buf[TMPL_RESTORE_END] = insn;
> +
> +	/* Setup template */
> +	for (i = 0; i < TMPL_MAX_LENGTH; i++)
> +		addrs[i] = code + i;
> +
> +	ret = aarch64_insn_patch_text(addrs, buf, TMPL_MAX_LENGTH);
> +	if (ret < 0)
> +		goto error;

This does a stop_machine(), which isn't strictly necessary here if we
write the buffer *then* swing the direct branch.

> +
> +	flush_icache_range((unsigned long)code,
> +			   (unsigned long)(&code[TMPL_END_IDX]));
> +
> +	/* Set op->optinsn.insn means prepared. */
> +	op->optinsn.insn = code;
> +
> +out:
> +	kfree(addrs);
> +	kfree(buf);
> +	return ret;
> +
> +error:
> +	free_optinsn_slot(code, 0);
> +	goto out;
> +}
> +
> +void arch_optimize_kprobes(struct list_head *oplist)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +	kprobe_opcode_t *insns;
> +	void **addrs;
> +	int i = 0;
> +
> +	addrs = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(void *), GFP_KERNEL);
> +	if (!addrs)
> +		return;
> +
> +	insns = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(kprobe_opcode_t), GFP_KERNEL);
> +	if (!insns) {
> +		kfree(addrs);
> +		return;
> +	}

Why do these need to be dynamically allocated? They have small fixed
sizes.

> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		WARN_ON(kprobe_disabled(&op->kp));
> +
> +		/*
> +		 * Backup instructions which will be replaced
> +		 * by jump address
> +		 */
> +		memcpy(op->optinsn.copied_insn, op->kp.addr,
> +			RELATIVEJUMP_SIZE);

Hmmm... how does this end up getting restored? This hasn't been through
an le32_to_cpu(), so if we patch it back with the usual insn functions
we'll restore the wrong thing on a big-endian kernel.

> +		addrs[i] = (void *)op->kp.addr;
> +		insns[i] = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
> +				(unsigned long)op->optinsn.insn,
> +				AARCH64_INSN_BRANCH_NOLINK);
> +
> +		list_del_init(&op->list);
> +		if (++i == OPTPROBE_BATCH_SIZE)
> +			break;
> +	}

What happens if the list was bigger than OPTPROBE_BATCH_SIZE?

> +
> +	aarch64_insn_patch_text(addrs, insns, i);
> +	kfree(addrs);
> +	kfree(insns);
> +}
> +
> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
> +{
> +	arch_arm_kprobe(&op->kp);
> +}
> +
> +/*
> + * Recover original instructions and breakpoints from relative jumps.
> + * Caller must call with locking kprobe_mutex.
> + */
> +void arch_unoptimize_kprobes(struct list_head *oplist,
> +			    struct list_head *done_list)
> +{
> +	struct optimized_kprobe *op, *tmp;
> +	kprobe_opcode_t *insns;
> +	void **addrs;
> +	int i = 0;
> +
> +	addrs = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(void *), GFP_KERNEL);
> +	if (!addrs)
> +		return;
> +
> +	insns = kcalloc(OPTPROBE_BATCH_SIZE, sizeof(kprobe_opcode_t), GFP_KERNEL);
> +	if (!insns) {
> +		kfree(addrs);
> +		return;
> +	}

Again, I do not think these need to be dynamically allocated.

> +
> +	list_for_each_entry_safe(op, tmp, oplist, list) {
> +		addrs[i] = (void *)op->kp.addr;
> +		insns[i] = BRK64_OPCODE_KPROBES;
> +		list_move(&op->list, done_list);
> +
> +		if (++i == OPTPROBE_BATCH_SIZE)
> +			break;

What happens if the list was larger rthan OPTPROBE_BATCH_SIZE ?

> +	}
> +
> +	aarch64_insn_patch_text(addrs, insns, i);
> +	kfree(addrs);
> +	kfree(insns);
> +}
> +
> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
> +{
> +	if (op->optinsn.insn) {
> +		free_optinsn_slot(op->optinsn.insn, 1);
> +		op->optinsn.insn = NULL;
> +	}
> +}
> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
> new file mode 100644
> index 000000000000..24d713d400cd
> --- /dev/null
> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
> @@ -0,0 +1,37 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * trampoline entry and return code for optprobes.
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/assembler.h>
> +
> +	.global optprobe_template_entry
> +optprobe_template_entry:

Please use SYM_*(); see arch/arm64/kernel/entry-ftrace.S for examples of
how to use that for trampolines.

This should be:

SYM_CODE_START(optprobe_template)

... and note the matching end below.

> +	sub sp, sp, #PT_REGS_SIZE
> +	save_all_base_regs
> +	/* Get parameters to optimized_callback() */
> +	ldr	x0, 1f
> +	mov	x1, sp
> +	/* Branch to optimized_callback() */
> +	.global optprobe_template_call
> +optprobe_template_call:

SYM_INNER_LABEL(optprobe_template_call, SYM_L_GLOBAL)

...and likewise for all the other labels.

> +	nop
> +	restore_all_base_regs
> +	ldr lr, [sp, #S_LR]
> +        add sp, sp, #PT_REGS_SIZE
> +	.global optprobe_template_restore_orig_insn
> +optprobe_template_restore_orig_insn:
> +	nop
> +	.global optprobe_template_restore_end
> +optprobe_template_restore_end:
> +	nop
> +	.global optprobe_template_end
> +optprobe_template_end:
> +	.global optprobe_template_val
> +optprobe_template_val:
> +	1:	.long 0
> +		.long 0
> +	.global optprobe_template_max_length
> +optprobe_template_max_length:

SYM_INNER_LABEL(optprobe_template_end, SYM_L_GLOBAL)
SYM_CODE_END(optprobe_template)

Thanks,
Mark.

> -- 
> 2.17.1
> 


From mark.rutland at arm.com  Tue Aug 24 03:52:02 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 11:52:02 +0100
Subject: [PATCH 5/5] arm64: Document the requirement for SCR_EL3.HCE
In-Reply-To: <20210824104900.GB623@arm.com>
References: <20210812190213.2601506-1-maz@kernel.org>
 <20210812190213.2601506-6-maz@kernel.org>
 <20210824104900.GB623@arm.com>
Message-ID: <20210824105202.GB96738@C02TD0UTHF1T.local>

On Tue, Aug 24, 2021 at 11:49:01AM +0100, Catalin Marinas wrote:
> On Thu, Aug 12, 2021 at 08:02:13PM +0100, Marc Zyngier wrote:
> > It is amazing that we never documented this absolutely basic
> > requirement: if you boot the kernel at EL2, you'd better
> > enable the HVC instruction from EL3.
> > 
> > Really, just do it.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  Documentation/arm64/booting.rst | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
> > index a9192e7a231b..6c729d0c4bc2 100644
> > --- a/Documentation/arm64/booting.rst
> > +++ b/Documentation/arm64/booting.rst
> > @@ -212,6 +212,11 @@ Before jumping into the kernel, the following conditions must be met:
> >    - The value of SCR_EL3.FIQ must be the same as the one present at boot
> >      time whenever the kernel is executing.
> >  
> > +  For all systems:
> > +  - If EL3 is present and the kernel is entered at EL2:
> > +
> > +    - SCR_EL3.HCE (bit 8) must be initialised to 0b1.
> > +
> >    For systems with a GICv3 interrupt controller to be used in v3 mode:
> >    - If EL3 is present:
> 
> I'll queue this patch only for now.
> 
> A nitpick, I think we should move "For all systems" and "If EL3 is
> present..." above the lines describing the SCR_EL3.FIQ requirement (I
> can make the change locally).


FWIW, with that:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.


From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:28 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:28 +0800
Subject: [RESEND v4 00/15] Add support for ast2600 ADC
Message-ID: <20210824091243.9393-1-billy_tsai@aspeedtech.com>

This patch serials make aspeed_adc.c can support ast2600 and backward
compatible.

RESEND due to miss some patches when sent patch v4.
Change since v3:
dt-bindings:
  - Fix properties:aspeed,int_vref_mv type error.

Change since v2:
dt-bindings:
  - Create a new dt-bindings for ast2600 adc
aspeed_adc.c:
  - Splits the patch for more details
  - Remove version enum and use the flags in model data to distinguish
  hardware feature
  - Support trimming data get and set.
  - Use devm_add_action_or_reset to simplify probe error handling.

Changes since v1:
dt-bindings:
  - Fix the aspeed,adc.yaml check error.
  - Add battery-sensing property.
aspeed_adc.c:
  - Change the init flow:
    Clock and reference voltage setting should be completed before adc
    engine enable.
  - Change the default sampling rate to meet most user case.
  - Add patch #8 to suppoert battery sensing mode.

Billy Tsai (15):
  dt-bindings: iio: adc: Add ast2600-adc bindings
  iio: adc: aspeed: completes the bitfield declare.
  iio: adc: aspeed: set driver data when adc probe.
  iio: adc: aspeed: Keep model data to driver data.
  iio: adc: aspeed: Refactory model data structure
  iio: adc: aspeed: Add vref config function
  iio: adc: aspeed: Set num_channels with model data
  iio: adc: aspeed: Use model_data to set clk scaler.
  iio: adc: aspeed: Use devm_add_action_or_reset.
  iio: adc: aspeed: Support ast2600 adc.
  iio: adc: aspeed: Fix the calculate error of clock.
  iio: adc: aspeed: Add func to set sampling rate.
  iio: adc: aspeed: Add compensation phase.
  iio: adc: aspeed: Support battery sensing.
  iio: adc: aspeed: Get and set trimming data.

 .../bindings/iio/adc/aspeed,ast2600-adc.yaml  |  97 +++
 drivers/iio/adc/aspeed_adc.c                  | 562 +++++++++++++++---
 2 files changed, 569 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml

-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:29 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:29 +0800
Subject: [RESEND v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-2-billy_tsai@aspeedtech.com>

Add device tree bindings document for the aspeed ast2600 adc device
driver.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 .../bindings/iio/adc/aspeed,ast2600-adc.yaml  | 97 +++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml

diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
new file mode 100644
index 000000000000..248cda7d91e9
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ADC that forms part of an ASPEED server management processor.
+
+maintainers:
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+description: |
+  ? 10-bits resolution for 16 voltage channels.
+  ? The device split into two individual engine and each contains 8 voltage
+  channels.
+  ? Channel scanning can be non-continuous.
+  ? Programmable ADC clock frequency.
+  ? Programmable upper and lower threshold for each channels.
+  ? Interrupt when larger or less than threshold for each channels.
+  ? Support hysteresis for each channels.
+  ? Built-in a compensating method.
+  ? Built-in a register to trim internal reference voltage.
+  ? Internal or External reference voltage.
+  ? Support 2 Internal reference voltage 1.2v or 2.5v.
+  ? Integrate dividing circuit for battery sensing.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2600-adc0
+      - aspeed,ast2600-adc1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    description:
+      Input clock used to derive the sample clock. Expected to be the
+      SoC's APB clock.
+
+  resets:
+    maxItems: 1
+
+  "#io-channel-cells":
+    const: 1
+
+  vref-supply:
+    description:
+      The external regulator supply ADC reference voltage.
+
+  aspeed,int_vref_mv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1200, 2500]
+    description:
+      ADC internal reference voltage in millivolts.
+
+  aspeed,battery-sensing:
+    type: boolean
+    description:
+      Inform the driver that last channel will be used to sensor battery.
+
+  aspeed,trim-data-valid:
+    type: boolean
+    description: |
+      The ADC reference voltage can be calibrated to obtain the trimming
+      data which will be stored in otp. This property informs the driver that
+      the data store in the otp is valid.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+  - "#io-channel-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/ast2600-clock.h>
+    adc0: adc at 1e6e9000 {
+        compatible = "aspeed,ast2600-adc0";
+        reg = <0x1e6e9000 0x100>;
+        clocks = <&syscon ASPEED_CLK_APB2>;
+        resets = <&syscon ASPEED_RESET_ADC>;
+        #io-channel-cells = <1>;
+        aspeed,int_vref_mv = <2500>;
+    };
+    adc1: adc at 1e6e9100 {
+        compatible = "aspeed,ast2600-adc1";
+        reg = <0x1e6e9100 0x100>;
+        clocks = <&syscon ASPEED_CLK_APB2>;
+        resets = <&syscon ASPEED_RESET_ADC>;
+        #io-channel-cells = <1>;
+        aspeed,int_vref_mv = <2500>;
+    };
+...
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:31 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:31 +0800
Subject: [RESEND v4 03/15] iio: adc: aspeed: set driver data when adc probe.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-4-billy_tsai@aspeedtech.com>

Fix the issue when adc remove will get the null driver data.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 7010d56ac3b9..20462cf659e4 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -201,6 +201,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	platform_set_drvdata(pdev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->base))
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:32 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:32 +0800
Subject: [RESEND v4 04/15] iio: adc: aspeed: Keep model data to driver data.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-5-billy_tsai@aspeedtech.com>

Keep the model data pointer to driver data for reducing the usage of
of_device_get_match_data().

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 20462cf659e4..d85aa31ee3b1 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -69,6 +69,7 @@ struct aspeed_adc_model_data {
 
 struct aspeed_adc_data {
 	struct device		*dev;
+	const struct aspeed_adc_model_data *model_data;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
 	struct clk_hw		*clk_prescaler;
@@ -110,8 +111,6 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       int *val, int *val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -119,7 +118,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = model_data->vref_voltage;
+		*val = data->model_data->vref_voltage;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -138,13 +137,11 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,
 				int val, int val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val < model_data->min_sampling_rate ||
-			val > model_data->max_sampling_rate)
+		if (val < data->model_data->min_sampling_rate ||
+			val > data->model_data->max_sampling_rate)
 			return -EINVAL;
 
 		clk_set_rate(data->clk_scaler->clk,
@@ -190,7 +187,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
 	struct aspeed_adc_data *data;
-	const struct aspeed_adc_model_data *model_data;
 	const char *clk_parent_name;
 	int ret;
 	u32 adc_engine_control_reg_val;
@@ -201,6 +197,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	data->model_data = of_device_get_match_data(&pdev->dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
@@ -241,9 +238,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-
-	if (model_data->wait_init_sequence) {
+	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
 				  ASPEED_ADC_OP_MODE_NORMAL) |
@@ -273,8 +268,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	writel(adc_engine_control_reg_val,
 	       data->base + ASPEED_REG_ENGINE_CONTROL);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-	indio_dev->name = model_data->model_name;
+	indio_dev->name = data->model_data->model_name;
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:35 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:35 +0800
Subject: [RESEND v4 07/15] iio: adc: aspeed: Set num_channels with model data
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-8-billy_tsai@aspeedtech.com>

Use the model_data member num_channels to set the num_channels of iio
device.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f260e40ab9b2..2d6215a91f99 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -291,7 +291,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-	indio_dev->num_channels = ARRAY_SIZE(aspeed_adc_iio_channels);
+	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
 	if (ret)
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:34 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:34 +0800
Subject: [RESEND v4 06/15] iio: adc: aspeed: Add vref config function
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-7-billy_tsai@aspeedtech.com>

Add the function to check the vref_fixed and set the value to driver
data.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f03c7921d534..f260e40ab9b2 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -122,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = data->model_data->vref_fixed;
+		*val = data->vref;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -187,6 +187,17 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	if (data->model_data->vref_fixed) {
+		data->vref = data->model_data->vref_fixed;
+		return 0;
+	}
+	return 0;
+}
+
 static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
@@ -242,6 +253,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
+	ret = aspeed_adc_vref_config(indio_dev);
+	if (ret)
+		goto vref_config_error;
+
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
@@ -290,6 +305,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
 poll_timeout_error:
+vref_config_error:
 	reset_control_assert(data->rst);
 reset_error:
 	clk_hw_unregister_divider(data->clk_scaler);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:39 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:39 +0800
Subject: [RESEND v4 11/15] iio: adc: aspeed: Fix the calculate error of clock.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-12-billy_tsai@aspeedtech.com>

The adc clcok formula is
ast2400/2500:
ADC clock period = PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
ast2600:
ADC clock period = PCLK * 2 * (ADC0C[15:0] + 1)
They all have one fixed divided 2 and the legacy driver didn't handle it.
This patch register the fixed factory clock device as the parent of adc
clock scaler to fix this issue.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index ea3e9a52fcc9..8fe7da1a651f 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -4,6 +4,12 @@
  *
  * Copyright (C) 2017 Google, Inc.
  * Copyright (C) 2021 Aspeed Technology Inc.
+ *
+ * ADC clock formula:
+ * Ast2400/Ast2500:
+ * clock period = period of PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
+ * Ast2600:
+ * clock period = period of PCLK * 2 * (ADC0C[15:0] + 1)
  */
 
 #include <linux/clk.h>
@@ -77,6 +83,7 @@ struct aspeed_adc_data {
 	struct regulator	*regulator;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
+	struct clk_hw		*fixed_div_clk;
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
@@ -196,6 +203,13 @@ static void aspeed_adc_unregister_divider(void *data)
 	clk_hw_unregister_divider(clk);
 }
 
+static void aspeed_adc_unregister_fixed_divider(void *data)
+{
+	struct clk_hw *clk = data;
+
+	clk_hw_unregister_fixed_factor(clk);
+}
+
 static void aspeed_adc_reset_assert(void *data)
 {
 	struct reset_control *rst = data;
@@ -312,6 +326,18 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	/* Register ADC clock prescaler with source specified by device tree. */
 	spin_lock_init(&data->clk_lock);
 	snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));
+	snprintf(clk_name, 32, "%s-fixed-div", data->model_data->model_name);
+	data->fixed_div_clk = clk_hw_register_fixed_factor(
+		&pdev->dev, clk_name, clk_parent_name, 0, 1, 2);
+	if (IS_ERR(data->fixed_div_clk))
+		return PTR_ERR(data->fixed_div_clk);
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_unregister_fixed_divider,
+				       data->clk_prescaler);
+	if (ret)
+		return ret;
+	snprintf(clk_parent_name, 32, clk_name);
 	if (data->model_data->need_prescaler) {
 		snprintf(clk_name, 32, "%s-prescaler",
 			 data->model_data->model_name);
-- 
2.25.1



From rogerq at kernel.org  Tue Aug 24 03:55:12 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 24 Aug 2021 13:55:12 +0300
Subject: [PATCH v2] ARM: dts: da850-evm: Change aemif node status from "ok" to
 "okay"
Message-ID: <20210824105512.19242-1-rogerq@kernel.org>

As per Device Tree Specification [1], the status parameter of nodes can
be "okay", "disabled", etc. "ok" is not a valid parameter.

U-boot Driver Model does not recognize status="ok" either and treats
the node as disabled.

[1] https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
Changelog:
v2
-refer to DT spec instead of schema in commit log.

 arch/arm/boot/dts/da850-evm.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index 87c517d65f62..9dc79b5977bf 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -415,7 +415,7 @@
 &aemif {
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_pins>;
-	status = "ok";
+	status = "okay";
 	cs3 {
 		#address-cells = <2>;
 		#size-cells = <1>;
-- 
2.17.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:30 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:30 +0800
Subject: [RESEND v4 02/15] iio: adc: aspeed: completes the bitfield declare.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-3-billy_tsai@aspeedtech.com>

This patch completes the declare of adc register bitfields and uses the
same prefix ASPEED_ADC_* for these bitfields.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 56 +++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 19efaa41bc34..7010d56ac3b9 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -3,6 +3,7 @@
  * Aspeed AST2400/2500 ADC
  *
  * Copyright (C) 2017 Google, Inc.
+ * Copyright (C) 2021 Aspeed Technology Inc.
  */
 
 #include <linux/clk.h>
@@ -16,6 +17,7 @@
 #include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/bitfield.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
@@ -28,15 +30,31 @@
 #define ASPEED_REG_INTERRUPT_CONTROL	0x04
 #define ASPEED_REG_VGA_DETECT_CONTROL	0x08
 #define ASPEED_REG_CLOCK_CONTROL	0x0C
-#define ASPEED_REG_MAX			0xC0
-
-#define ASPEED_OPERATION_MODE_POWER_DOWN	(0x0 << 1)
-#define ASPEED_OPERATION_MODE_STANDBY		(0x1 << 1)
-#define ASPEED_OPERATION_MODE_NORMAL		(0x7 << 1)
-
-#define ASPEED_ENGINE_ENABLE		BIT(0)
-
-#define ASPEED_ADC_CTRL_INIT_RDY	BIT(8)
+#define ASPEED_REG_COMPENSATION_TRIM	0xC4
+#define ASPEED_REG_MAX			0xCC
+
+#define ASPEED_ADC_ENGINE_ENABLE		BIT(0)
+#define ASPEED_ADC_OP_MODE			GENMASK(3, 1)
+#define ASPEED_ADC_OP_MODE_PWR_DOWN		0
+#define ASPEED_ADC_OP_MODE_STANDBY		1
+#define ASPEED_ADC_OP_MODE_NORMAL		7
+#define ASPEED_ADC_CTRL_COMPENSATION		BIT(4)
+#define ASPEED_ADC_AUTO_COMPENSATION		BIT(5)
+#define ASPEED_ADC_REF_VOLTAGE			GENMASK(7, 6)
+#define ASPEED_ADC_REF_VOLTAGE_2500mV		0
+#define ASPEED_ADC_REF_VOLTAGE_1200mV		1
+#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH		2
+#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW		3
+#define ASPEED_ADC_BAT_SENSING_DIV		BIT(6)
+#define ASPEED_ADC_BAT_SENSING_DIV_2_3		0
+#define ASPEED_ADC_BAT_SENSING_DIV_1_3		1
+#define ASPEED_ADC_CTRL_INIT_RDY		BIT(8)
+#define ASPEED_ADC_CH7_MODE			BIT(12)
+#define ASPEED_ADC_CH7_NORMAL			0
+#define ASPEED_ADC_CH7_BAT			1
+#define ASPEED_ADC_BAT_SENSING_ENABLE		BIT(13)
+#define ASPEED_ADC_CTRL_CHANNEL			GENMASK(31, 16)
+#define ASPEED_ADC_CTRL_CHANNEL_ENABLE(ch)	FIELD_PREP(ASPEED_ADC_CTRL_CHANNEL, BIT(ch))
 
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
@@ -226,7 +244,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	if (model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
-		writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
+		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+				  ASPEED_ADC_OP_MODE_NORMAL) |
+			       ASPEED_ADC_ENGINE_ENABLE,
 		       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 		/* Wait for initial sequence complete. */
@@ -245,10 +265,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		goto clk_enable_error;
 
-	adc_engine_control_reg_val = GENMASK(31, 16) |
-		ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE;
+	adc_engine_control_reg_val =
+		ASPEED_ADC_CTRL_CHANNEL |
+		FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
+		ASPEED_ADC_ENGINE_ENABLE;
 	writel(adc_engine_control_reg_val,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 	model_data = of_device_get_match_data(&pdev->dev);
 	indio_dev->name = model_data->model_name;
@@ -264,8 +286,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	return 0;
 
 iio_register_error:
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
 poll_timeout_error:
@@ -283,8 +305,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
 	clk_hw_unregister_divider(data->clk_scaler);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:38 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:38 +0800
Subject: [RESEND v4 10/15] iio: adc: aspeed: Support ast2600 adc.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-11-billy_tsai@aspeedtech.com>

Make driver to support ast2600 adc device.
- Use shared reset controller
- Complete the vref configure function
- Add the model data for ast2600 adc

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 106 +++++++++++++++++++++++++++++++++--
 1 file changed, 100 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 1c87e12a0cab..ea3e9a52fcc9 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Aspeed AST2400/2500 ADC
+ * Aspeed AST2400/2500/2600 ADC
  *
  * Copyright (C) 2017 Google, Inc.
  * Copyright (C) 2021 Aspeed Technology Inc.
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
@@ -73,6 +74,7 @@ struct aspeed_adc_model_data {
 struct aspeed_adc_data {
 	struct device		*dev;
 	const struct aspeed_adc_model_data *model_data;
+	struct regulator	*regulator;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
 	struct clk_hw		*clk_prescaler;
@@ -208,14 +210,80 @@ static void aspeed_adc_clk_disable_unprepare(void *data)
 	clk_disable_unprepare(clk);
 }
 
+static void aspeed_adc_reg_disable(void *data)
+{
+	struct regulator *reg = data;
+
+	regulator_disable(reg);
+}
+
 static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	int ret;
+	u32 adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
 
 	if (data->model_data->vref_fixed) {
 		data->vref = data->model_data->vref_fixed;
 		return 0;
 	}
+
+	data->regulator = devm_regulator_get_optional(data->dev, "vref");
+	if (!IS_ERR(data->regulator)) {
+		ret = regulator_enable(data->regulator);
+		if (ret)
+			return ret;
+		ret = devm_add_action_or_reset(
+			data->dev, aspeed_adc_reg_disable, data->regulator);
+		if (ret)
+			return ret;
+		data->vref = regulator_get_voltage(data->regulator);
+		/* Conversion from uV to mV */
+		data->vref /= 1000;
+		if ((data->vref >= 1550) && (data->vref <= 2700))
+			writel(adc_engine_control_reg_val |
+				       FIELD_PREP(
+					       ASPEED_ADC_REF_VOLTAGE,
+					       ASPEED_ADC_REF_VOLTAGE_EXT_HIGH),
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		else if ((data->vref >= 900) && (data->vref <= 1650))
+			writel(adc_engine_control_reg_val |
+				       FIELD_PREP(
+					       ASPEED_ADC_REF_VOLTAGE,
+					       ASPEED_ADC_REF_VOLTAGE_EXT_LOW),
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		else {
+			dev_err(data->dev, "Regulator voltage %d not support",
+				data->vref);
+			return -EOPNOTSUPP;
+		}
+	} else {
+		if (PTR_ERR(data->regulator) != -ENODEV)
+			return PTR_ERR(data->regulator);
+		ret = of_property_read_u32(data->dev->of_node,
+					   "aspeed,int_vref_mv", &data->vref);
+		if (ret < 0) {
+			dev_warn(data->dev,
+				 "Using default vref: internal 2500 mv");
+			data->vref = 2500;
+		}
+		if (data->vref == 2500)
+			writel(adc_engine_control_reg_val |
+				       FIELD_PREP(ASPEED_ADC_REF_VOLTAGE,
+						  ASPEED_ADC_REF_VOLTAGE_2500mV),
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		else if (data->vref == 1200)
+			writel(adc_engine_control_reg_val |
+				       FIELD_PREP(ASPEED_ADC_REF_VOLTAGE,
+						  ASPEED_ADC_REF_VOLTAGE_1200mV),
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		else {
+			dev_err(data->dev, "Voltage %d not support", data->vref);
+			return -EOPNOTSUPP;
+		}
+	}
+
 	return 0;
 }
 
@@ -279,7 +347,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	data->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
 	if (IS_ERR(data->rst)) {
 		dev_err(&pdev->dev,
 			"invalid or missing reset controller device tree entry");
@@ -297,10 +365,14 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		return ret;
 
 	if (data->model_data->wait_init_sequence) {
+		adc_engine_control_reg_val =
+			readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+		adc_engine_control_reg_val |=
+			FIELD_PREP(ASPEED_ADC_OP_MODE,
+				   ASPEED_ADC_OP_MODE_NORMAL) |
+			ASPEED_ADC_ENGINE_ENABLE;
 		/* Enable engine in normal mode. */
-		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
-				  ASPEED_ADC_OP_MODE_NORMAL) |
-			       ASPEED_ADC_ENGINE_ENABLE,
+		writel(adc_engine_control_reg_val,
 		       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 		/* Wait for initial sequence complete. */
@@ -326,6 +398,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		return ret;
 
 	adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+	adc_engine_control_reg_val |=
 		ASPEED_ADC_CTRL_CHANNEL |
 		FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
 		ASPEED_ADC_ENGINE_ENABLE;
@@ -376,9 +450,29 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
 	.num_channels = 16,
 };
 
+static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
+	.model_name = "ast2600-adc0",
+	.min_sampling_rate = 10000,
+	.max_sampling_rate = 500000,
+	.wait_init_sequence = true,
+	.scaler_bit_width = 16,
+	.num_channels = 8,
+};
+
+static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
+	.model_name = "ast2600-adc1",
+	.min_sampling_rate = 10000,
+	.max_sampling_rate = 500000,
+	.wait_init_sequence = true,
+	.scaler_bit_width = 16,
+	.num_channels = 8,
+};
+
 static const struct of_device_id aspeed_adc_matches[] = {
 	{ .compatible = "aspeed,ast2400-adc", .data = &ast2400_model_data },
 	{ .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data },
+	{ .compatible = "aspeed,ast2600-adc0", .data = &ast2600_adc0_model_data },
+	{ .compatible = "aspeed,ast2600-adc1", .data = &ast2600_adc1_model_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, aspeed_adc_matches);
@@ -395,5 +489,5 @@ static struct platform_driver aspeed_adc_driver = {
 module_platform_driver(aspeed_adc_driver);
 
 MODULE_AUTHOR("Rick Altherr <raltherr at google.com>");
-MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver");
+MODULE_DESCRIPTION("Aspeed AST2400/2500/2600 ADC Driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:33 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:33 +0800
Subject: [RESEND v4 05/15] iio: adc: aspeed: Refactory model data structure
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <20210824091243.9393-6-billy_tsai@aspeedtech.com>

This patch refactory the model data structure to distinguish the
function form differnet version of aspeed adc.
- Rename the vref_voltag to vref_fixed and add vref driver data
When driver probe will check vref_fixed value and store it
to vref which isn't const value.
- Add num_channels
Make num_channles of iio device can be changed by differnet model_data
- Add need_prescaler flag and scaler_bit_width
The need_prescaler flag used to tell the driver the clock divider needs
another prescaler and the scaler_bit_width to set the clock divider
bitfiled width.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index d85aa31ee3b1..f03c7921d534 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -63,8 +63,11 @@ struct aspeed_adc_model_data {
 	const char *model_name;
 	unsigned int min_sampling_rate;	// Hz
 	unsigned int max_sampling_rate;	// Hz
-	unsigned int vref_voltage;	// mV
+	unsigned int vref_fixed;	// mV
 	bool wait_init_sequence;
+	bool need_prescaler;
+	u8 scaler_bit_width;
+	unsigned int num_channels;
 };
 
 struct aspeed_adc_data {
@@ -75,6 +78,7 @@ struct aspeed_adc_data {
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
+	int			vref;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -118,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = data->model_data->vref_voltage;
+		*val = data->model_data->vref_fixed;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -312,17 +316,23 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 
 static const struct aspeed_adc_model_data ast2400_model_data = {
 	.model_name = "ast2400-adc",
-	.vref_voltage = 2500, // mV
+	.vref_fixed = 2500, // mV
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
+	.need_prescaler = true,
+	.scaler_bit_width = 10,
+	.num_channels = 16,
 };
 
 static const struct aspeed_adc_model_data ast2500_model_data = {
 	.model_name = "ast2500-adc",
-	.vref_voltage = 1800, // mV
+	.vref_fixed = 1800, // mV
 	.min_sampling_rate = 1,
 	.max_sampling_rate = 1000000,
 	.wait_init_sequence = true,
+	.need_prescaler = true,
+	.scaler_bit_width = 10,
+	.num_channels = 16,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
-- 
2.25.1



From ionela.voinescu at arm.com  Tue Aug 24 03:56:48 2021
From: ionela.voinescu at arm.com (Ionela Voinescu)
Date: Tue, 24 Aug 2021 11:56:48 +0100
Subject: [PATCH v2 0/3] arch_topology, ACPI: populate cpu capacity from CPPC
Message-ID: <20210824105651.28660-1-ionela.voinescu@arm.com>

Hi all,

Apologies for the long delay in posting v2.

v1->v2:
 - v1 can be found at [1]
 - Changed debug prints to the format used on the DT path
 - s/init_cpu_capacity_cppc/topology_init_cpu_capacity_cppc

Patches are based on v5.14-rc7.

The patches have been build tested on x86 and more thoroughly tested on
Juno R2 (arm64), which uses the new functionality, with the following
results:

root at buildroot:~# dmesg | grep cpu_capacity
[    2.191152] cpu_capacity: CPU0 cpu_capacity=38300 (raw).
[    2.196482] cpu_capacity: CPU1 cpu_capacity=38300 (raw).
[    2.201809] cpu_capacity: CPU2 cpu_capacity=38300 (raw).
[    2.207136] cpu_capacity: CPU3 cpu_capacity=38300 (raw).
[    2.212463] cpu_capacity: CPU4 cpu_capacity=102400 (raw).
[    2.217877] cpu_capacity: CPU5 cpu_capacity=102400 (raw).
[    2.223291] cpu_capacity: capacity_scale=102400
[    2.227834] cpu_capacity: CPU0 cpu_capacity=383
[    2.232376] cpu_capacity: CPU1 cpu_capacity=383
[    2.236919] cpu_capacity: CPU2 cpu_capacity=383
[    2.241462] cpu_capacity: CPU3 cpu_capacity=383
[    2.246004] cpu_capacity: CPU4 cpu_capacity=1024
[    2.250634] cpu_capacity: CPU5 cpu_capacity=1024
[    2.255321] cpu_capacity: cpu_capacity initialization done

root at buildroot:~# tail -n +1 /sys/devices/system/cpu/cpu*/cpu_capacity
==> /sys/devices/system/cpu/cpu0/cpu_capacity <==
383
==> /sys/devices/system/cpu/cpu1/cpu_capacity <==
383
==> /sys/devices/system/cpu/cpu2/cpu_capacity <==
383
==> /sys/devices/system/cpu/cpu3/cpu_capacity <==
383
==> /sys/devices/system/cpu/cpu4/cpu_capacity <==
1024
==> /sys/devices/system/cpu/cpu5/cpu_capacity <==
1024

[1]
https://lore.kernel.org/lkml/20210514095339.12979-1-ionela.voinescu at arm.com/

Thanks,
Ionela.

Ionela Voinescu (3):
  x86, ACPI: rename init_freq_invariance_cppc to
    arch_init_invariance_cppc
  arch_topology: obtain cpu capacity using information from CPPC
  arm64, topology: enable use of init_cpu_capacity_cppc()

 arch/arm64/include/asm/topology.h |  4 ++++
 arch/x86/include/asm/topology.h   |  2 +-
 drivers/acpi/cppc_acpi.c          |  6 ++---
 drivers/base/arch_topology.c      | 37 +++++++++++++++++++++++++++++++
 include/linux/arch_topology.h     |  4 ++++
 5 files changed, 49 insertions(+), 4 deletions(-)

-- 
2.29.2.dirty



From ionela.voinescu at arm.com  Tue Aug 24 03:56:49 2021
From: ionela.voinescu at arm.com (Ionela Voinescu)
Date: Tue, 24 Aug 2021 11:56:49 +0100
Subject: [PATCH v2 1/3] x86,
 ACPI: rename init_freq_invariance_cppc to arch_init_invariance_cppc
In-Reply-To: <20210824105651.28660-1-ionela.voinescu@arm.com>
References: <20210824105651.28660-1-ionela.voinescu@arm.com>
Message-ID: <20210824105651.28660-2-ionela.voinescu@arm.com>

init_freq_invariance_cppc() was called in acpi_cppc_processor_probe(),
after CPU performance information and controls were populated from the
per-cpu _CPC objects.

But these _CPC objects provide information that helps with both CPU
(u-arch) and frequency invariance. Therefore, change the function name
to a more generic one, while adding the arch_ prefix, as this function
is expected to be defined differently by different architectures.

Signed-off-by: Ionela Voinescu <ionela.voinescu at arm.com>
Tested-by: Valentin Schneider <valentin.schneider at arm.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Giovanni Gherdovich <ggherdovich at suse.cz>
Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
---
 arch/x86/include/asm/topology.h | 2 +-
 drivers/acpi/cppc_acpi.c        | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 9239399e5491..61d73013cab8 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -220,7 +220,7 @@ static inline void arch_set_max_freq_ratio(bool turbo_disabled)
 
 #ifdef CONFIG_ACPI_CPPC_LIB
 void init_freq_invariance_cppc(void);
-#define init_freq_invariance_cppc init_freq_invariance_cppc
+#define arch_init_invariance_cppc init_freq_invariance_cppc
 #endif
 
 #endif /* _ASM_X86_TOPOLOGY_H */
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index a4d4eebba1da..c211d77310e8 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -660,8 +660,8 @@ static bool is_cppc_supported(int revision, int num_ent)
  *	}
  */
 
-#ifndef init_freq_invariance_cppc
-static inline void init_freq_invariance_cppc(void) { }
+#ifndef arch_init_invariance_cppc
+static inline void arch_init_invariance_cppc(void) { }
 #endif
 
 /**
@@ -826,7 +826,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
 		goto out_free;
 	}
 
-	init_freq_invariance_cppc();
+	arch_init_invariance_cppc();
 
 	kfree(output.pointer);
 	return 0;
-- 
2.29.2.dirty



From ionela.voinescu at arm.com  Tue Aug 24 03:56:50 2021
From: ionela.voinescu at arm.com (Ionela Voinescu)
Date: Tue, 24 Aug 2021 11:56:50 +0100
Subject: [PATCH v2 2/3] arch_topology: obtain cpu capacity using information
 from CPPC
In-Reply-To: <20210824105651.28660-1-ionela.voinescu@arm.com>
References: <20210824105651.28660-1-ionela.voinescu@arm.com>
Message-ID: <20210824105651.28660-3-ionela.voinescu@arm.com>

Define topology_init_cpu_capacity_cppc() to use highest performance
values from _CPC objects to obtain and set maximum capacity information
for each CPU. acpi_cppc_processor_probe() is a good point at which to
trigger the initialization of CPU (u-arch) capacity values, as at this
point the highest performance values can be obtained from each CPU's
_CPC objects. Architectures can therefore use this functionality
through arch_init_invariance_cppc().

The performance scale used by CPPC is a unified scale for all CPUs in
the system. Therefore, by obtaining the raw highest performance values
from the _CPC objects, and normalizing them on the [0, 1024] capacity
scale, used by the task scheduler, we obtain the CPU capacity of each
CPU.

While an ACPI Notify(0x85) could alert about a change in the highest
performance value, which should in turn retrigger the CPU capacity
computations, this notification is not currently handled by the ACPI
processor driver. When supported, a call to arch_init_invariance_cppc()
would perform the update.

Signed-off-by: Ionela Voinescu <ionela.voinescu at arm.com>
Tested-by: Valentin Schneider <valentin.schneider at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
---
 drivers/base/arch_topology.c  | 37 +++++++++++++++++++++++++++++++++++
 include/linux/arch_topology.h |  4 ++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 921312a8d957..358e22cd629e 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -306,6 +306,43 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
 	return !ret;
 }
 
+#ifdef CONFIG_ACPI_CPPC_LIB
+#include <acpi/cppc_acpi.h>
+
+void topology_init_cpu_capacity_cppc(void)
+{
+	struct cppc_perf_caps perf_caps;
+	int cpu;
+
+	if (likely(acpi_disabled || !acpi_cpc_valid()))
+		return;
+
+	raw_capacity = kcalloc(num_possible_cpus(), sizeof(*raw_capacity),
+			       GFP_KERNEL);
+	if (!raw_capacity)
+		return;
+
+	for_each_possible_cpu(cpu) {
+		if (!cppc_get_perf_caps(cpu, &perf_caps)) {
+			raw_capacity[cpu] = perf_caps.highest_perf;
+			pr_debug("cpu_capacity: CPU%d cpu_capacity=%u (raw).\n",
+				 cpu, raw_capacity[cpu]);
+		} else {
+			pr_err("cpu_capacity: CPU%d missing highest performance.\n", cpu);
+			pr_err("cpu_capacity: partial information: fallback to 1024 for all CPUs\n");
+			goto exit;
+		}
+	}
+
+	topology_normalize_cpu_scale();
+	schedule_work(&update_topology_flags_work);
+	pr_debug("cpu_capacity: cpu_capacity initialization done\n");
+
+exit:
+	free_raw_capacity();
+}
+#endif
+
 #ifdef CONFIG_CPU_FREQ
 static cpumask_var_t cpus_to_visit;
 static void parsing_done_workfn(struct work_struct *work);
diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h
index f180240dc95f..9cf1a17938f0 100644
--- a/include/linux/arch_topology.h
+++ b/include/linux/arch_topology.h
@@ -11,6 +11,10 @@
 void topology_normalize_cpu_scale(void);
 int topology_update_cpu_topology(void);
 
+#ifdef CONFIG_ACPI_CPPC_LIB
+void topology_init_cpu_capacity_cppc(void);
+#endif
+
 struct device_node;
 bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu);
 
-- 
2.29.2.dirty



From ionela.voinescu at arm.com  Tue Aug 24 03:56:51 2021
From: ionela.voinescu at arm.com (Ionela Voinescu)
Date: Tue, 24 Aug 2021 11:56:51 +0100
Subject: [PATCH v2 3/3] arm64, topology: enable use of init_cpu_capacity_cppc()
In-Reply-To: <20210824105651.28660-1-ionela.voinescu@arm.com>
References: <20210824105651.28660-1-ionela.voinescu@arm.com>
Message-ID: <20210824105651.28660-4-ionela.voinescu@arm.com>

Now that the arch topology driver provides a method of setting CPU
capacity values based on information on highest performance from CPPC,
use this functionality on arm64 platforms.

Signed-off-by: Ionela Voinescu <ionela.voinescu at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Tested-by: Valentin Schneider <valentin.schneider at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/topology.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
index ec2db3419c41..5ebe51ef6d6c 100644
--- a/arch/arm64/include/asm/topology.h
+++ b/arch/arm64/include/asm/topology.h
@@ -24,6 +24,10 @@ void update_freq_counters_refs(void);
 #define arch_scale_freq_capacity topology_get_freq_scale
 #define arch_scale_freq_invariant topology_scale_freq_invariant
 
+#ifdef CONFIG_ACPI_CPPC_LIB
+#define arch_init_invariance_cppc topology_init_cpu_capacity_cppc
+#endif
+
 /* Replace task scheduler's default cpu-invariant accounting */
 #define arch_scale_cpu_capacity topology_get_cpu_scale
 
-- 
2.29.2.dirty



From mark.rutland at arm.com  Tue Aug 24 03:58:24 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 11:58:24 +0100
Subject: [PATCH linux-next] firmware/psci: fix application of sizeof to
 pointer
In-Reply-To: <61d3cc7e5cd4a819381fcb22e1853d6f48a0c927.1629212319.git.jing.yangyang@zte.com.cn>
References: <61d3cc7e5cd4a819381fcb22e1853d6f48a0c927.1629212319.git.jing.yangyang@zte.com.cn>
Message-ID: <20210824105824.GC96738@C02TD0UTHF1T.local>

On Thu, Aug 19, 2021 at 07:30:16PM -0700, jing yangyang wrote:
> sizeof when applied to a pointer typed expression gives the size of
> the pointer.
> 
> ./drivers/firmware/psci/psci_checker.c:158:41-47: ERROR application of sizeof to pointer
> 
> This issue was detected with the help of Coccinelle.
> 
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: jing yangyang <jing.yangyang at zte.com.cn>

>From looking at the git history, we should add:

  Fixes: 7401056de5f8d4ea ("drivers/firmware: psci_checker: stash and use topology_core_cpumask for hotplug tests)"

With that:

  Acked-by: Mark Rutland <mark.rutland at arm.com>

Lorenzo, how do we normally direct these patches?

Thanks,
Mark.


> ---
>  drivers/firmware/psci/psci_checker.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c
> index 9a369a2..116eb46 100644
> --- a/drivers/firmware/psci/psci_checker.c
> +++ b/drivers/firmware/psci/psci_checker.c
> @@ -155,7 +155,7 @@ static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups)
>  	if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
>  		return -ENOMEM;
>  
> -	cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups),
> +	cpu_groups = kcalloc(nb_available_cpus, sizeof(*cpu_groups),
>  			     GFP_KERNEL);
>  	if (!cpu_groups) {
>  		free_cpumask_var(tmp);
> -- 
> 1.8.3.1
> 
> 


From rogerq at kernel.org  Tue Aug 24 03:58:56 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 24 Aug 2021 13:58:56 +0300
Subject: [PATCH v2 0/2] ARM: dts: keystone-k2*-evm: Fix mdio and dss node
 status
Message-ID: <20210824105858.19496-1-rogerq@kernel.org>

Hi Santosh,

This series fixes mdio and dss status nodes from "ok" to "okay"

As per Device Tree Specification [1], the status parameter of nodes can
be "okay", "disabled", etc. "ok" is not a valid parameter.

U-boot Driver Model does not recognize status="ok" either and treats
the node as disabled.

[1] https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3

cheers,
-roger

Roger Quadros (2):
  ARM: dts: keystone-k2*-evm: Fix mdio node status to "okay"
  ARM: dts: keystone-k2g-evm: Fix dss node status to "okay"

 arch/arm/boot/dts/keystone-k2e-evm.dts  | 2 +-
 arch/arm/boot/dts/keystone-k2g-evm.dts  | 2 +-
 arch/arm/boot/dts/keystone-k2hk-evm.dts | 2 +-
 arch/arm/boot/dts/keystone-k2l-evm.dts  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

-- 
2.17.1



From rogerq at kernel.org  Tue Aug 24 03:58:57 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 24 Aug 2021 13:58:57 +0300
Subject: [PATCH v2 1/2] ARM: dts: keystone-k2*-evm: Fix mdio node status to
 "okay"
In-Reply-To: <20210824105858.19496-1-rogerq@kernel.org>
References: <20210824105858.19496-1-rogerq@kernel.org>
Message-ID: <20210824105858.19496-2-rogerq@kernel.org>

As per Device Tree Specification [1], the status parameter of nodes can
be "okay", "disabled", etc. "ok" is not a valid parameter.

U-boot Driver Model does not recognize status="ok" either and treats
the node as disabled.

[1] https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3

Cc: Grygorii Strashko <grygorii.strashko at ti.com>
Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 arch/arm/boot/dts/keystone-k2e-evm.dts  | 2 +-
 arch/arm/boot/dts/keystone-k2hk-evm.dts | 2 +-
 arch/arm/boot/dts/keystone-k2l-evm.dts  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/keystone-k2e-evm.dts b/arch/arm/boot/dts/keystone-k2e-evm.dts
index 66fec5f5d081..acac242ebdf7 100644
--- a/arch/arm/boot/dts/keystone-k2e-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2e-evm.dts
@@ -159,7 +159,7 @@
 };
 
 &mdio {
-	status = "ok";
+	status = "okay";
 	ethphy0: ethernet-phy at 0 {
 		compatible = "marvell,88E1514", "marvell,88E1510", "ethernet-phy-ieee802.3-c22";
 		reg = <0>;
diff --git a/arch/arm/boot/dts/keystone-k2hk-evm.dts b/arch/arm/boot/dts/keystone-k2hk-evm.dts
index ad4e22afe133..5e85f000acc3 100644
--- a/arch/arm/boot/dts/keystone-k2hk-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2hk-evm.dts
@@ -183,7 +183,7 @@
 };
 
 &mdio {
-	status = "ok";
+	status = "okay";
 	ethphy0: ethernet-phy at 0 {
 		compatible = "marvell,88E1111", "ethernet-phy-ieee802.3-c22";
 		reg = <0>;
diff --git a/arch/arm/boot/dts/keystone-k2l-evm.dts b/arch/arm/boot/dts/keystone-k2l-evm.dts
index e200533d26a4..a6cbff4cfe20 100644
--- a/arch/arm/boot/dts/keystone-k2l-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2l-evm.dts
@@ -132,7 +132,7 @@
 };
 
 &mdio {
-	status = "ok";
+	status = "okay";
 	ethphy0: ethernet-phy at 0 {
 		compatible = "marvell,88E1514", "marvell,88E1510", "ethernet-phy-ieee802.3-c22";
 		reg = <0>;
-- 
2.17.1



From rogerq at kernel.org  Tue Aug 24 03:58:58 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 24 Aug 2021 13:58:58 +0300
Subject: [PATCH v2 2/2] ARM: dts: keystone-k2g-evm: Fix dss node status to
 "okay"
In-Reply-To: <20210824105858.19496-1-rogerq@kernel.org>
References: <20210824105858.19496-1-rogerq@kernel.org>
Message-ID: <20210824105858.19496-3-rogerq@kernel.org>

As per Device Tree Specification [1], the status parameter of nodes can
be "okay", "disabled", etc. "ok" is not a valid parameter.

U-boot Driver Model does not recognize status="ok" either and treats
the node as disabled.

[1] https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 arch/arm/boot/dts/keystone-k2g-evm.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts b/arch/arm/boot/dts/keystone-k2g-evm.dts
index d800f26b6275..57680323e202 100644
--- a/arch/arm/boot/dts/keystone-k2g-evm.dts
+++ b/arch/arm/boot/dts/keystone-k2g-evm.dts
@@ -534,7 +534,7 @@
 &dss {
 	pinctrl-names = "default";
 	pinctrl-0 = <&vout_pins>;
-	status = "ok";
+	status = "okay";
 
 	port {
 		dpi_out: endpoint {
-- 
2.17.1



From will at kernel.org  Tue Aug 24 03:59:20 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 24 Aug 2021 11:59:20 +0100
Subject: [RFC PATCH] arm64: mm: limit linear region to 51 bits for KVM in
 nVHE mode
In-Reply-To: <20210810161244.84231-1-ardb@kernel.org>
References: <20210810161244.84231-1-ardb@kernel.org>
Message-ID: <20210824105920.GB22752@willie-the-truck>

On Tue, Aug 10, 2021 at 06:12:44PM +0200, Ard Biesheuvel wrote:
> KVM in nVHE mode divides up its VA space into two equal halves, and
> picks the half that does not conflict with the HYP ID map to map its
> linear region. This worked fine when the kernel's linear map itself was
> guaranteed to cover precisely as many bits of VA space, but this was
> changed by commit f4693c2716b35d08 ("arm64: mm: extend linear region for
> 52-bit VA configurations").
> 
> The result is that, depending on the placement of the ID map, kernel-VA
> to hyp-VA translations may produce addresses that either conflict with
> other HYP mappings (including the ID map itself) or generate addresses
> outside of the 52-bit addressable range, neither of which is likely to
> lead to anything useful.
> 
> Given that 52-bit capable cores are guaranteed to implement VHE, this
> only affects configurations such as pKVM where we opt into non-VHE mode
> even if the hardware is VHE capable. So just for these configurations,
> let's limit the kernel linear map to 51 bits and work around the
> problem.
> 
> Fixes:f4693c2716b35d08 ("arm64: mm: extend linear region for 52-bit VA configurations")
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
> NOTE: build tested only
> 
>  arch/arm64/mm/init.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 8490ed2917ff..542dad13e2fc 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -282,7 +282,21 @@ static void __init fdt_enforce_memory_region(void)
>  
>  void __init arm64_memblock_init(void)
>  {
> -	const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> +	s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> +
> +	/*
> +	 * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
> +	 * be limited in their ability to support a linear map that exceeds 51
> +	 * bits of VA space, depending on the placement of the ID map. Given
> +	 * that the placement of the ID map may be randomized, let's simply
> +	 * limit the kernel's linear map to 51 bits as well if we detect this
> +	 * configuration.
> +	 */
> +	if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 &&
> +	    !is_kernel_in_hyp_mode()) {
> +		pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n");
> +		linear_region_size = BIT(51);
> +	}

Slight nit, but to avoid having to think about PAGE_END I think this would
be a little clearer as:

	if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode())
		linear_region_size = min_t(u64, linear_region_size, BIT(51));

Will


From lkp at intel.com  Tue Aug 24 04:01:59 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 24 Aug 2021 19:01:59 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS 054bc6a105d715bff4eba9606c34b8e0bc685a8c
Message-ID: <6124d1a7./yG88u/Q7RD7Gg7n%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 054bc6a105d715bff4eba9606c34b8e0bc685a8c  arm/arm64: dts: Fix remaining dtc 'unit_address_format' warnings

elapsed time: 724m

configs tested: 40
configs skipped: 100

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210824
x86_64               randconfig-a006-20210824
x86_64               randconfig-a001-20210824
x86_64               randconfig-a003-20210824
x86_64               randconfig-a004-20210824
x86_64               randconfig-a002-20210824
i386                 randconfig-a006-20210824
i386                 randconfig-a001-20210824
i386                 randconfig-a002-20210824
i386                 randconfig-a005-20210824
i386                 randconfig-a003-20210824
i386                 randconfig-a004-20210824
um                           x86_64_defconfig
um                             i386_defconfig

clang tested configs:
hexagon              randconfig-r041-20210824
hexagon              randconfig-r045-20210824
riscv                randconfig-r042-20210824
s390                 randconfig-r044-20210824

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Tue Aug 24 04:01:46 2021
From: lkp at intel.com (kernel test robot)
Date: Tue, 24 Aug 2021 19:01:46 +0800
Subject: [soc:aspeed/defconfig] BUILD SUCCESS
 a4836d5ad127fe31fecb29878d81f2e9b4a5591c
Message-ID: <6124d19a.XaGgO+m6lokttlY4%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git aspeed/defconfig
branch HEAD: a4836d5ad127fe31fecb29878d81f2e9b4a5591c  ARM: config: aspeed: Regenerate defconfigs

elapsed time: 7409m

configs tested: 279
configs skipped: 120

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210824
i386                 randconfig-c001-20210819
s390                          debug_defconfig
m68k                          atari_defconfig
openrisc                            defconfig
arm                           omap1_defconfig
mips                      maltasmvp_defconfig
h8300                       h8s-sim_defconfig
powerpc                       maple_defconfig
sh                           se7751_defconfig
arm                        realview_defconfig
mips                      loongson3_defconfig
s390                                defconfig
mips                         rt305x_defconfig
arc                              allyesconfig
powerpc                 linkstation_defconfig
arm                       netwinder_defconfig
alpha                               defconfig
riscv                    nommu_k210_defconfig
h8300                     edosk2674_defconfig
m68k                       m5208evb_defconfig
arm                         s3c6400_defconfig
arm                           h5000_defconfig
arm                        spear6xx_defconfig
mips                malta_qemu_32r6_defconfig
sh                          sdk7786_defconfig
xtensa                       common_defconfig
mips                           gcw0_defconfig
powerpc                          g5_defconfig
powerpc                        fsp2_defconfig
mips                        nlm_xlr_defconfig
s390                       zfcpdump_defconfig
arm                       aspeed_g4_defconfig
arm                         s5pv210_defconfig
powerpc                      acadia_defconfig
powerpc                    sam440ep_defconfig
powerpc                     pq2fads_defconfig
m68k                        m5407c3_defconfig
sh                               j2_defconfig
m68k                         amcore_defconfig
arm                           viper_defconfig
mips                           ip28_defconfig
sh                          urquell_defconfig
arm                      tct_hammer_defconfig
csky                             alldefconfig
arc                          axs101_defconfig
sh                 kfr2r09-romimage_defconfig
sh                         ap325rxa_defconfig
mips                          rm200_defconfig
openrisc                    or1ksim_defconfig
sh                         microdev_defconfig
mips                          rb532_defconfig
powerpc                 mpc836x_mds_defconfig
arm                         nhk8815_defconfig
sh                          rsk7269_defconfig
arm64                            alldefconfig
sh                        apsh4ad0a_defconfig
mips                       bmips_be_defconfig
m68k                                defconfig
powerpc                 mpc837x_rdb_defconfig
sh                        edosk7760_defconfig
powerpc                    klondike_defconfig
arm                          pxa168_defconfig
sh                          rsk7201_defconfig
arm                    vt8500_v6_v7_defconfig
arc                              alldefconfig
riscv                          rv32_defconfig
nios2                         10m50_defconfig
m68k                       m5249evb_defconfig
m68k                       bvme6000_defconfig
microblaze                          defconfig
um                                  defconfig
mips                     loongson2k_defconfig
mips                           mtx1_defconfig
m68k                       m5275evb_defconfig
arm                  colibri_pxa270_defconfig
nios2                               defconfig
powerpc                     tqm8541_defconfig
powerpc                 mpc8560_ads_defconfig
powerpc                     kilauea_defconfig
powerpc                      makalu_defconfig
arm                          moxart_defconfig
mips                      malta_kvm_defconfig
mips                           ip22_defconfig
sh                   sh7770_generic_defconfig
arm                          iop32x_defconfig
powerpc                        icon_defconfig
m68k                            mac_defconfig
powerpc                   currituck_defconfig
sh                  sh7785lcr_32bit_defconfig
arm                          lpd270_defconfig
powerpc                 mpc8315_rdb_defconfig
i386                             alldefconfig
arc                        vdk_hs38_defconfig
x86_64                              defconfig
powerpc                 mpc8540_ads_defconfig
powerpc                     mpc83xx_defconfig
ia64                      gensparse_defconfig
sh                           se7712_defconfig
sh                        sh7785lcr_defconfig
xtensa                  cadence_csp_defconfig
powerpc                           allnoconfig
mips                  maltasmvp_eva_defconfig
arm                            pleb_defconfig
sh                            titan_defconfig
sparc                       sparc32_defconfig
arc                          axs103_defconfig
nios2                            allyesconfig
arm                         cm_x300_defconfig
mips                        workpad_defconfig
arm                           corgi_defconfig
xtensa                  audio_kc705_defconfig
mips                   sb1250_swarm_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                             allyesconfig
nds32                             allnoconfig
nds32                               defconfig
csky                                defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
x86_64               randconfig-a005-20210822
x86_64               randconfig-a006-20210822
x86_64               randconfig-a001-20210822
x86_64               randconfig-a003-20210822
x86_64               randconfig-a004-20210822
x86_64               randconfig-a002-20210822
x86_64               randconfig-a005-20210824
x86_64               randconfig-a006-20210824
x86_64               randconfig-a001-20210824
x86_64               randconfig-a003-20210824
x86_64               randconfig-a004-20210824
x86_64               randconfig-a002-20210824
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
i386                 randconfig-a006-20210824
i386                 randconfig-a001-20210824
i386                 randconfig-a002-20210824
i386                 randconfig-a005-20210824
i386                 randconfig-a003-20210824
i386                 randconfig-a004-20210824
i386                 randconfig-a006-20210822
i386                 randconfig-a001-20210822
i386                 randconfig-a002-20210822
i386                 randconfig-a005-20210822
i386                 randconfig-a003-20210822
i386                 randconfig-a004-20210822
x86_64               randconfig-a013-20210819
x86_64               randconfig-a011-20210819
x86_64               randconfig-a012-20210819
x86_64               randconfig-a016-20210819
x86_64               randconfig-a014-20210819
x86_64               randconfig-a015-20210819
i386                 randconfig-a015-20210819
i386                 randconfig-a011-20210819
i386                 randconfig-a014-20210819
i386                 randconfig-a013-20210819
i386                 randconfig-a016-20210819
i386                 randconfig-a012-20210819
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
riscv                randconfig-c006-20210818
s390                 randconfig-c005-20210818
powerpc              randconfig-c003-20210818
mips                 randconfig-c004-20210818
x86_64               randconfig-c007-20210818
i386                 randconfig-c001-20210818
arm                  randconfig-c002-20210818
i386                 randconfig-c001-20210824
s390                 randconfig-c005-20210824
arm                  randconfig-c002-20210824
riscv                randconfig-c006-20210824
x86_64               randconfig-c007-20210824
mips                 randconfig-c004-20210824
i386                 randconfig-c001-20210822
s390                 randconfig-c005-20210822
arm                  randconfig-c002-20210822
riscv                randconfig-c006-20210822
powerpc              randconfig-c003-20210822
x86_64               randconfig-c007-20210822
mips                 randconfig-c004-20210822
riscv                randconfig-c006-20210819
s390                 randconfig-c005-20210819
mips                 randconfig-c004-20210819
i386                 randconfig-c001-20210819
x86_64               randconfig-c007-20210819
arm                  randconfig-c002-20210819
x86_64               randconfig-a004-20210819
x86_64               randconfig-a006-20210819
x86_64               randconfig-a003-20210819
x86_64               randconfig-a002-20210819
x86_64               randconfig-a005-20210819
x86_64               randconfig-a001-20210819
i386                 randconfig-a004-20210819
i386                 randconfig-a006-20210819
i386                 randconfig-a001-20210819
i386                 randconfig-a002-20210819
i386                 randconfig-a003-20210819
i386                 randconfig-a005-20210819
x86_64               randconfig-a014-20210822
x86_64               randconfig-a016-20210822
x86_64               randconfig-a015-20210822
x86_64               randconfig-a013-20210822
x86_64               randconfig-a012-20210822
x86_64               randconfig-a011-20210822
x86_64               randconfig-a014-20210824
x86_64               randconfig-a015-20210824
x86_64               randconfig-a016-20210824
x86_64               randconfig-a013-20210824
x86_64               randconfig-a012-20210824
x86_64               randconfig-a011-20210824
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
i386                 randconfig-a011-20210824
i386                 randconfig-a016-20210824
i386                 randconfig-a012-20210824
i386                 randconfig-a014-20210824
i386                 randconfig-a013-20210824
i386                 randconfig-a015-20210824
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818
hexagon              randconfig-r041-20210818
riscv                randconfig-r042-20210818
s390                 randconfig-r044-20210818
hexagon              randconfig-r045-20210818
hexagon              randconfig-r041-20210824
hexagon              randconfig-r045-20210824
riscv                randconfig-r042-20210824
s390                 randconfig-r044-20210824
hexagon              randconfig-r041-20210819
hexagon              randconfig-r045-20210819

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From ezequiel at vanguardiasur.com.ar  Tue Aug 24 04:02:54 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Tue, 24 Aug 2021 08:02:54 -0300
Subject: [PATCH 1/9] dt-bindings: media: mtk-vcodec: Add binding for
 MT8195 two venc cores
In-Reply-To: <20210816105934.28265-2-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-2-irui.wang@mediatek.com>
Message-ID: <CAAEAJfDoSW3F85bFKTRvvGZXTZbCBRpUwZzEyx3zhrA6psiZfA@mail.gmail.com>

Hi Irui,

On Mon, 16 Aug 2021 at 08:00, Irui Wang <irui.wang at mediatek.com> wrote:
>
> Enable MT8195 two H.264 venc cores, updates vcodec binding document.
>
> Signed-off-by: Irui Wang <irui.wang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> index de961699ba0a..eb2e24c32426 100644
> --- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> +++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> @@ -11,6 +11,8 @@ Required properties:
>    "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
>    "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
>    "mediatek,mt8195-vcodec-enc" for MT8195 encoder.
> +  "mediatek,mtk-venc-core0" for MT8195 avc core0 device.
> +  "mediatek,mtk-venc-core1" for MT8195 avc core1 device.

What is the difference between core0 and core1?

Thanks,
Ezequiel


From rogerq at kernel.org  Tue Aug 24 04:05:09 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 24 Aug 2021 14:05:09 +0300
Subject: [PATCH v2 0/2] ARM: dts: keystone-k2*-evm: Fix mdio and dss node
 status
In-Reply-To: <20210824105858.19496-1-rogerq@kernel.org>
References: <20210824105858.19496-1-rogerq@kernel.org>
Message-ID: <6e5a4ef9-3611-25b4-9f79-5776f708dafa@kernel.org>



On 24/08/2021 13:58, Roger Quadros wrote:
> Hi Santosh,
> 
> This series fixes mdio and dss status nodes from "ok" to "okay"
> 
> As per Device Tree Specification [1], the status parameter of nodes can
> be "okay", "disabled", etc. "ok" is not a valid parameter.
> 
> U-boot Driver Model does not recognize status="ok" either and treats
> the node as disabled.
> 
> [1] https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3
> 
> cheers,
> -roger
> 
> Roger Quadros (2):
>   ARM: dts: keystone-k2*-evm: Fix mdio node status to "okay"
>   ARM: dts: keystone-k2g-evm: Fix dss node status to "okay"
> 
>  arch/arm/boot/dts/keystone-k2e-evm.dts  | 2 +-
>  arch/arm/boot/dts/keystone-k2g-evm.dts  | 2 +-
>  arch/arm/boot/dts/keystone-k2hk-evm.dts | 2 +-
>  arch/arm/boot/dts/keystone-k2l-evm.dts  | 2 +-
>  4 files changed, 4 insertions(+), 4 deletions(-)
> 

Changes in this version:
- updated commit message to point to DT spec instead of schema.


From ezequiel at vanguardiasur.com.ar  Tue Aug 24 04:22:24 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Tue, 24 Aug 2021 08:22:24 -0300
Subject: [PATCH] media: hantro: Add support of compressed reference buffers
In-Reply-To: <20210823162916.824336-1-benjamin.gaignard@collabora.com>
References: <20210823162916.824336-1-benjamin.gaignard@collabora.com>
Message-ID: <CAAEAJfCxhe8EubESc4HnO63JnOqVCRTNU62Qrm8wX+Rsc_tSUg@mail.gmail.com>

Hi Benjamin,

On Mon, 23 Aug 2021 at 13:29, Benjamin Gaignard
<benjamin.gaignard at collabora.com> wrote:
>
> Reference frame compression is a feature added in G2 decoder to compress
> frame buffers so that the bandwidth of storing/loading reference frames
> can be reduced, especially when the resolution of decoded stream is of
> high definition.
>
> Compressed help to increase the performance of the whole stack, it could
> be up to 50 fps (against 45 fps) on IMX8MQ.
> The impact of compressed frames is confirmed when using perf to monitor
> the number of memory accesses with or without compression feature.
> The following command
> perf stat -a -e imx8_ddr0/cycles/,imx8_ddr0/read-cycles/,imx8_ddr0/write-cycles/ gst-launch-1.0 filesrc location=Jockey_3840x2160_120fps_420_8bit_HEVC_RAW.hevc ! queue ! h265parse ! v4l2slh265dec ! fakesink
>
> give us these results
> without compression feature:
>  Performance counter stats for 'system wide':
>
>        14965816743      imx8_ddr0/cycles/
>          889197312      imx8_ddr0/read-cycles/
>         1819348862      imx8_ddr0/write-cycles/
>
>       18.707373001 seconds time elapsed
>
> with compression feature:
> Performance counter stats for 'system wide':
>
>        13750218243      imx8_ddr0/cycles/
>          402428744      imx8_ddr0/read-cycles/
>         1255676693      imx8_ddr0/write-cycles/
>
>       17.188320061 seconds time elapsed
>
> As expected the number of read/write cycles are really lower when compression
> is used.
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
> ---
>  .../staging/media/hantro/hantro_g2_hevc_dec.c | 31 ++++++++++++--
>  drivers/staging/media/hantro/hantro_g2_regs.h |  4 ++
>  drivers/staging/media/hantro/hantro_hevc.c    | 41 ++++++++++++++++++-
>  drivers/staging/media/hantro/hantro_hw.h      |  2 +
>  4 files changed, 74 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> index 340efb57fd18..da90acd922f7 100644
> --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> @@ -366,10 +366,12 @@ static int set_ref(struct hantro_ctx *ctx)
>         const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps;
>         const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
>         const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
> -       dma_addr_t luma_addr, chroma_addr, mv_addr = 0;
> +       dma_addr_t luma_addr, chroma_addr, mv_addr, compress_luma_addr, compress_chroma_addr = 0;
>         struct hantro_dev *vpu = ctx->dev;
>         size_t cr_offset = hantro_hevc_chroma_offset(sps);
>         size_t mv_offset = hantro_hevc_motion_vectors_offset(sps);
> +       size_t compress_luma_offset = hantro_hevc_luma_compress_offset(sps);
> +       size_t compress_chroma_offset = hantro_hevc_chroma_compress_offset(sps);
>         u32 max_ref_frames;
>         u16 dpb_longterm_e;
>         static const struct hantro_reg cur_poc[] = {
> @@ -442,15 +444,28 @@ static int set_ref(struct hantro_ctx *ctx)
>                 if (!luma_addr)
>                         return -ENOMEM;
>
> +               /*
> +                * An allocated frame stores Y and UV planes, motion vectors and
> +                * compressed Y and UV planes. Compute all these offsets given
> +                * the frame resolution and the pixel format.
> +                */

The patch looks good, but I feel we still need to answer some questions
before it can be merged.

* Is this a G2 feature? If so, can it be used on VP9?

* Enabling compression needs more memory. You are proposing
to allocate frames and compressed frames contiguously,
but so we need to measure the impact of that. Perhaps separate
buffers will be better to avoid CMA pressure? Perhaps a given
user will want to turn this off to reduce memory usage?

More importantly, I'm wary of adding HEVC features
without being able to test anything.

Can you work with NXP maintainers to get the GPC/BLK-CTRL [1] sorted out?

Then, we have the issue of missing mainlined userspace as well,
but I suppose that's well underway :-)

[1] https://www.spinics.net/lists/arm-kernel/msg913881.html

Cheers,
Eze

>                 chroma_addr = luma_addr + cr_offset;
>                 mv_addr = luma_addr + mv_offset;
> +               compress_luma_addr = luma_addr + compress_luma_offset;
> +               compress_chroma_addr = luma_addr + compress_chroma_offset;
>
>                 if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>                         dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
>
> +               /*
> +                * For each reference frame Y, UV, motion vector and
> +                * compressed Y, UV buffers addresses must be set.
> +                */
>                 hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr);
>                 hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr);
>                 hantro_write_addr(vpu, G2_REG_DMV_REF(i), mv_addr);
> +               hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), compress_luma_addr);
> +               hantro_write_addr(vpu, G2_COMP_CHR_REF(i), compress_chroma_addr);
>         }
>
>         luma_addr = hantro_hevc_get_ref_buf(ctx, decode_params->pic_order_cnt_val);
> @@ -459,7 +474,12 @@ static int set_ref(struct hantro_ctx *ctx)
>
>         chroma_addr = luma_addr + cr_offset;
>         mv_addr = luma_addr + mv_offset;
> +       compress_luma_addr = luma_addr + compress_luma_offset;
> +       compress_chroma_addr = luma_addr + compress_chroma_offset;
>
> +       /* The next decoded frame as to be put as the last reference frame entry */
> +       hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), compress_luma_addr);
> +       hantro_write_addr(vpu, G2_COMP_CHR_REF(i), compress_chroma_addr);
>         hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr);
>         hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr);
>         hantro_write_addr(vpu, G2_REG_DMV_REF(i++), mv_addr);
> @@ -467,13 +487,18 @@ static int set_ref(struct hantro_ctx *ctx)
>         hantro_write_addr(vpu, G2_ADDR_DST, luma_addr);
>         hantro_write_addr(vpu, G2_ADDR_DST_CHR, chroma_addr);
>         hantro_write_addr(vpu, G2_ADDR_DST_MV, mv_addr);
> +       hantro_write_addr(vpu, G2_COMP_ADDR_DST, compress_luma_addr);
> +       hantro_write_addr(vpu, G2_COMP_CHR, compress_chroma_addr);
>
>         hantro_hevc_ref_remove_unused(ctx);
>
> +       /* Unused reference frames entries most be cleared */
>         for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
>                 hantro_write_addr(vpu, G2_REG_ADDR_REF(i), 0);
>                 hantro_write_addr(vpu, G2_REG_CHR_REF(i), 0);
>                 hantro_write_addr(vpu, G2_REG_DMV_REF(i), 0);
> +               hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), 0);
> +               hantro_write_addr(vpu, G2_COMP_CHR_REF(i), 0);
>         }
>
>         hantro_reg_write(vpu, &g2_refer_lterm_e, dpb_longterm_e);
> @@ -564,8 +589,8 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx)
>         /* Don't disable output */
>         hantro_reg_write(vpu, &g2_out_dis, 0);
>
> -       /* Don't compress buffers */
> -       hantro_reg_write(vpu, &g2_ref_compress_bypass, 1);
> +       /* Compress buffers */
> +       hantro_reg_write(vpu, &g2_ref_compress_bypass, 0);
>
>         /* use NV12 as output format */
>         hantro_reg_write(vpu, &g2_out_rs_e, 1);
> diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h
> index bb22fa921914..2a23e8657db1 100644
> --- a/drivers/staging/media/hantro/hantro_g2_regs.h
> +++ b/drivers/staging/media/hantro/hantro_g2_regs.h
> @@ -191,6 +191,10 @@
>  #define G2_TILE_FILTER         (G2_SWREG(179))
>  #define G2_TILE_SAO            (G2_SWREG(181))
>  #define G2_TILE_BSD            (G2_SWREG(183))
> +#define G2_COMP_ADDR_DST       (G2_SWREG(190))
> +#define G2_COMP_ADDR_REF(i)    (G2_SWREG(192) + ((i) * 0x8))
> +#define G2_COMP_CHR            (G2_SWREG(224))
> +#define G2_COMP_CHR_REF(i)     (G2_SWREG(226) + ((i) * 0x8))
>
>  #define g2_strm_buffer_len     G2_DEC_REG(258, 0, 0xffffffff)
>  #define g2_strm_start_offset   G2_DEC_REG(259, 0, 0xffffffff)
> diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
> index 5347f5a41c2a..78e5ceda520c 100644
> --- a/drivers/staging/media/hantro/hantro_hevc.c
> +++ b/drivers/staging/media/hantro/hantro_hevc.c
> @@ -27,6 +27,13 @@
>
>  #define G2_ALIGN               16
>
> +#define CBS_SIZE       16      /* compression table size in bytes */
> +#define CBS_LUMA       8       /* luminance CBS is composed of 1 8x8 coded block */
> +#define CBS_CHROMA_W   (8 * 2) /* chrominance CBS is composed of two 8x4 coded
> +                                * blocks, with Cb CB first then Cr CB following
> +                                */
> +#define CBS_CHROMA_H   4
> +
>  size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps)
>  {
>         int bytes_per_pixel = sps->bit_depth_luma_minus8 == 0 ? 1 : 2;
> @@ -61,12 +68,44 @@ static size_t hantro_hevc_mv_size(const struct v4l2_ctrl_hevc_sps *sps)
>         return mv_size;
>  }
>
> +size_t hantro_hevc_luma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps)
> +{
> +       return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps);
> +}
> +
> +static size_t hantro_hevc_luma_compress_size(const struct v4l2_ctrl_hevc_sps *sps)
> +{
> +       u32 pic_width_in_cbsy =
> +               round_up((sps->pic_width_in_luma_samples + CBS_LUMA - 1) / CBS_LUMA, CBS_SIZE);
> +       u32 pic_height_in_cbsy = (sps->pic_height_in_luma_samples + CBS_LUMA - 1) / CBS_LUMA;
> +
> +       return round_up(pic_width_in_cbsy * pic_height_in_cbsy, CBS_SIZE);
> +}
> +
> +size_t hantro_hevc_chroma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps)
> +{
> +       return hantro_hevc_luma_compress_offset(sps) + hantro_hevc_luma_compress_size(sps);
> +}
> +
> +static size_t hantro_hevc_chroma_compress_size(const struct v4l2_ctrl_hevc_sps *sps)
> +{
> +       u32 pic_width_in_cbsc =
> +               round_up((sps->pic_width_in_luma_samples + CBS_CHROMA_W - 1)
> +                        / CBS_CHROMA_W, CBS_SIZE);
> +       u32 pic_height_in_cbsc = (sps->pic_height_in_luma_samples / 2 + CBS_CHROMA_H - 1)
> +                                / CBS_CHROMA_H;
> +
> +       return round_up(pic_width_in_cbsc * pic_height_in_cbsc, CBS_SIZE);
> +}
> +
>  static size_t hantro_hevc_ref_size(struct hantro_ctx *ctx)
>  {
>         const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
>         const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
>
> -       return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps);
> +       return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps) +
> +              hantro_hevc_luma_compress_size(sps) +
> +              hantro_hevc_chroma_compress_size(sps);
>  }
>
>  static void hantro_hevc_ref_free(struct hantro_ctx *ctx)
> diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
> index df7b5e3a57b9..d5c002d0e765 100644
> --- a/drivers/staging/media/hantro/hantro_hw.h
> +++ b/drivers/staging/media/hantro/hantro_hw.h
> @@ -255,6 +255,8 @@ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
>  void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
>  size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps);
>  size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps);
> +size_t hantro_hevc_luma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps);
> +size_t hantro_hevc_chroma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps);
>
>  static inline size_t
>  hantro_h264_mv_size(unsigned int width, unsigned int height)
> --
> 2.25.1
>


From 21cnbao at gmail.com  Tue Aug 24 04:50:08 2021
From: 21cnbao at gmail.com (Barry Song)
Date: Tue, 24 Aug 2021 23:50:08 +1200
Subject: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210824105001.GA96738@C02TD0UTHF1T.local>
References: <20210818073336.59678-1-liuqi115@huawei.com>
 <20210818073336.59678-3-liuqi115@huawei.com>
 <20210824105001.GA96738@C02TD0UTHF1T.local>
Message-ID: <CAGsJ_4wU3g5i4PPo+cw3ZyGyswnFp7p7vERaq_aUuhmCCyvqmg@mail.gmail.com>

On Tue, Aug 24, 2021 at 10:51 PM Mark Rutland <mark.rutland at arm.com> wrote:
>
> Hi,
>
> I have a bunch of comments below.
>
> At a high-level, I'm not all that keen on adding yet another set of
> trampolines, especially given we have constraints on how we can branch
> to them which render this not that useful in common configurations (e.g.
> where KASLR and module randomization is enabled).
>
> So importantly, do we actually need this? I don't think the sampel is
> that compelling since we can already use ftrace to measure function
> latencies.

Hopefully I can help answer some general questions. for code details,
I'll still rely on liuqi.

As far as I know, the functionality of ftrace is very limited. kprobe,
on the other hand, can do a lot of
things, for example, hooking some ebpf code.
Tons of userspace tools depend on kprobe, eg. ebpf/bcc which is widely
used nowadays:
https://github.com/iovisor/bcc

Function latency is really a very small part of what kprobe can do.
kprobe can do much much
more. For example, while doing disksnoop by kprobe, we are easily
collecting the request struct,
and get the layout of each IO request. without kprobe, we will
probably need to add tracepoints
here and there in kernel code to achieve the same goal.

I believe Masami and kprobe maintainers can answer this question better than me.

>
> If we do need this, I think we need to do some more substantial rework
> to address those branch range limitations. I know that we could permit
> arbitrary branching if we expand the ftrace-with-regs callsites to ~6
> instructions, but that interacts rather poorly with stacktracing and
> will make the kernel a bit bigger.

This patch is probably the first step towards a faster kprobe on ARM64.
I assume PLT or some similar tech will help break the limitation next
step.

>
> On Wed, Aug 18, 2021 at 03:33:36PM +0800, Qi Liu wrote:
> > This patch introduce optprobe for ARM64. In optprobe, probed
> > instruction is replaced by a branch instruction to detour
> > buffer. Detour buffer contains trampoline code and a call to
> > optimized_callback(). optimized_callback() calls opt_pre_handler()
> > to execute kprobe handler.
> >
> > Performance of optprobe on Hip08 platform is test using kprobe
> > example module[1] to analyze the latency of a kernel function,
> > and here is the result:
> >
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> >
> > kprobe before optimized:
> > [280709.846380] do_empty returned 0 and took 1530 ns to execute
> > [280709.852057] do_empty returned 0 and took 550 ns to execute
> > [280709.857631] do_empty returned 0 and took 440 ns to execute
> > [280709.863215] do_empty returned 0 and took 380 ns to execute
> > [280709.868787] do_empty returned 0 and took 360 ns to execute
> > [280709.874362] do_empty returned 0 and took 340 ns to execute
> > [280709.879936] do_empty returned 0 and took 320 ns to execute
> > [280709.885505] do_empty returned 0 and took 300 ns to execute
> > [280709.891075] do_empty returned 0 and took 280 ns to execute
> > [280709.896646] do_empty returned 0 and took 290 ns to execute
> > [280709.902220] do_empty returned 0 and took 290 ns to execute
> > [280709.907807] do_empty returned 0 and took 290 ns to execute
> >
> > optprobe:
> > [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> > [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> > [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> > [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> > [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> > [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> > [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> > [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> > [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> > [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> > [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> > [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> > [ 2966.029158] do_empty returned 0 and took 70 ns to execute
>
> Do we have any examples of where this latency matters in practice?

While doing performance analysis or debugging performance issues  in
lab, the big latency of the current kprobe
can significantly impact the real result.

And it is particularly important when we want to do some online
diagnostics where machines are running on the cloud.
we need to minimally affect the real system while watching the system.

For example, https://gitee.com/xiebaoyou/diagnosis_tools is an
open-source tool which is used by alibaba, it uses
kprobe a lot to detect various problems running on aloud.

>
> >
> > Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> >
> > Note:
> > To guarantee the offset between probe point and kprobe pre_handler
> > is smaller than 128MiB, users should set
> > CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
> > optprobe will not work and fall back to normal kprobe.
>
> Hmm... I don't think that's something we want to recommend, and
> certainly distros *should* use KASLR and
> CONFIG_RANDOMIZE_MODULE_REGION_FULL.
>
> What happens with defconfig? Do we always get the fallback behaviour?

For this stage, with no_kaslr cmdline for defconfig, we are always
going to optprobe. otherwise, it
always goes to the fallback behaviour. So for this stage, it is
probably only useful in lab while people
are debugging problems. but this is still a widely useful scenario.
>

Thanks
Barry


From eugen.hristev at microchip.com  Tue Aug 24 04:54:31 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:31 +0300
Subject: [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for sama7g5
Message-ID: <20210824115441.681253-1-eugen.hristev@microchip.com>


Hi,

This series adds support for sama7g5.

The sama7g5 is slightly different from sama5d2, but has the same basic
operations. The register map is a bit different, so, I added some primitives
to differentiate between the two classes of hardware blocks (sama5d2-sam9x60
and sama7g5).

Sama7g5 has 16 channels ADC, no resistive touch, and extra features
(FIFOs, better oversampling , not implemented yet).

It is a rework of the series initially sent here:
https://marc.info/?l=linux-iio&m=161461656807826&w=2

I reworked this according to review by Jonathan, meaning that first I created
a no-op patch that will convert the driver to a more platform specific data
dedicated type of driver. This adds various structures that hold things like
register layout and channel information.
After this I created few patches that implement the main differences between
sama7g5 and older products: the end-of-conversion new register. I added
helper functions to make code more easy to read and more simple.
One the last patches adds the layout and channels for sama7g5.
At this moment in linux-next, the DT for sama7g5 and sama7g5ek is present,
and the last patches add and enable this node in DT for this board.

Eugen



Eugen Hristev (10):
  dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
  iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
  iio: adc: at91-sama5d2_adc: remove unused definition
  iio: adc: at91-sama5d2_adc: convert to platform specific data
    structures
  iio: adc: at91-sama5d2-adc: add support for separate end of conversion
    registers
  iio: adc: at91-sama5d2_adc: add helper for COR register
  iio: adc: at91-sama5d2_adc: add support for sama7g5 device
  iio: adc: at91-sama5d2_adc: update copyright and authors information
  ARM: dts: at91: sama7g5: add node for the ADC
  ARM: dts: at91: sama7g5ek: enable ADC on the board

 .../bindings/iio/adc/atmel,sama5d2-adc.yaml   |   1 +
 arch/arm/boot/dts/at91-sama7g5ek.dts          |   8 +
 arch/arm/boot/dts/sama7g5.dtsi                |  16 +
 drivers/iio/adc/at91-sama5d2_adc.c            | 586 ++++++++++++------
 4 files changed, 425 insertions(+), 186 deletions(-)

-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:32 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:32 +0300
Subject: [PATCH v2 01/10] dt-bindings: iio: adc: at91-sama5d2: add compatible
 for sama7g5-adc
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-2-eugen.hristev@microchip.com>

Add compatible for microchip,sama7g5-adc device.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
index 79c13b408eda..efed361215b4 100644
--- a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
@@ -15,6 +15,7 @@ properties:
     enum:
       - atmel,sama5d2-adc
       - microchip,sam9x60-adc
+      - microchip,sama7g5-adc
 
   reg:
     maxItems: 1
-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:33 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:33 +0300
Subject: [PATCH v2 02/10] iio: adc: at91-sama5d2_adc: initialize hardware
 after clock is started
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-3-eugen.hristev@microchip.com>

The hw_init hardware init call must happen after the clock is prepared and
enabled. Otherwise, writing to the registers might lead to a block or
external abort.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index ea5ca163d879..1f4d461c2c18 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -1833,12 +1833,12 @@ static int at91_adc_probe(struct platform_device *pdev)
 		goto vref_disable;
 	}
 
-	at91_adc_hw_init(indio_dev);
-
 	ret = clk_prepare_enable(st->per_clk);
 	if (ret)
 		goto vref_disable;
 
+	at91_adc_hw_init(indio_dev);
+
 	platform_set_drvdata(pdev, indio_dev);
 
 	ret = at91_adc_buffer_and_trigger_init(&pdev->dev, indio_dev);
-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:34 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:34 +0300
Subject: [PATCH v2 03/10] iio: adc: at91-sama5d2_adc: remove unused definition
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-4-eugen.hristev@microchip.com>

Remove unused register definition

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 1f4d461c2c18..9d71dcffcf93 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -143,8 +143,6 @@
 #define AT91_SAMA5D2_COR	0x4c
 #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
 
-/* Channel Data Register 0 */
-#define AT91_SAMA5D2_CDR0	0x50
 /* Analog Control Register */
 #define AT91_SAMA5D2_ACR	0x94
 /* Analog Control Register - Pen detect sensitivity mask */
-- 
2.25.1



From geert at linux-m68k.org  Tue Aug 24 04:55:34 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 24 Aug 2021 13:55:34 +0200
Subject: [PATCH v5 0/9] Add generic support for kdump DT properties
In-Reply-To: <CAL_JsqK63hoEMafLP+5eeQR1qrhOO76J4KEQG_By6QnLfhF=dw@mail.gmail.com>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <YRkxzx/1XM3r64Ee@robh.at.kernel.org>
 <CAMuHMdXs0+7K4N0mg6qX6X1cr_8dBr_HdTahdfORMk76wCJcEA@mail.gmail.com>
 <CAL_JsqK63hoEMafLP+5eeQR1qrhOO76J4KEQG_By6QnLfhF=dw@mail.gmail.com>
Message-ID: <CAMuHMdVNi4bh0Kp43BrVVKD8YY5ac4yi9=W3QZmw=stmwwtuiQ@mail.gmail.com>

On Mon, Aug 23, 2021 at 4:52 PM Rob Herring <robh at kernel.org> wrote:
> On Mon, Aug 23, 2021 at 5:13 AM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > On Sun, Aug 15, 2021 at 5:25 PM Rob Herring <robh at kernel.org> wrote:
> > > On Wed, Aug 11, 2021 at 10:50:58AM +0200, Geert Uytterhoeven wrote:
> > > > This patch series adds generic support for parsing DT properties related
> > > > to crash dump kernels ("linux,elfcorehdr" and "linux,elfcorehdr" under
> > > > the "/chosen" node), makes use of it on arm32, and performs a few
> > > > cleanups.  It is an evolution of the combination of [1] and [2].
> > >
> > > The DT bits look fine to me. How do you expect this to be merged? I'm
> > > happy to take it if arch maintainers can ack it.
> >
> > I had hoped you could take the series...
>
> My current thought is I'll take 2-5, 7 and 8 given that's what I have
> acks for and the others can be applied independently.

Note that Palmer did ack patch 6, so you can include it.

Russell: any thoughts about patch 9?

Thanks!

> > > > The series consists of 6 parts:
> > > >   1. Patch 1 prepares architecture-specific code (needed for MIPS only)
> > > >      to avoid duplicating elf core header reservation later.
> > > >   2. Patch 2 prepares the visibility of variables used to hold
> > > >      information retrieved from the DT properties.
> > > >   3. Patches 3-5 add support to the FDT core for handling the
> > > >      properties.
> > > >      This can co-exist safely with architecture-specific handling, until
> > > >      the latter has been removed.
> > >
> > > Looks like patch 5 doesn't have any dependencies with the series?
> >
> > Indeed. So you can take it independently.
> >
> > > >   4. Patch 6 removes the non-standard handling of "linux,elfcorehdr" on
> > > >      riscv.
> > >
> > > I thought this should be applied for 5.14?
> >
> > Me too, but unfortunately that hasn't happened yet...
>
> Buried in the middle of this series is not going to encourage it to be
> picked up as a fix.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From eugen.hristev at microchip.com  Tue Aug 24 04:54:35 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:35 +0300
Subject: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform
 specific data structures
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-5-eugen.hristev@microchip.com>

Convert the driver to platform specific structures. This means:
- create a register layout struct that will hold offsets for registers
- create a platform struct that will hold platform information (number of
channels, indexes for different channels and pointer to layout struct)
- convert specific macros that are platform dependent into platform variables

This step is in fact a no-op, but allows the driver to be more flexible
and for future enhancement including adding new platforms that are partly
compatible with the current driver and differ slightly in register layout
or capabilities for example.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
 1 file changed, 247 insertions(+), 163 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 9d71dcffcf93..8ede18b8d789 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -27,8 +27,9 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/regulator/consumer.h>
 
+struct at91_adc_reg_layout {
 /* Control Register */
-#define AT91_SAMA5D2_CR		0x00
+	u16				CR;
 /* Software Reset */
 #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
 /* Start Conversion */
@@ -39,7 +40,7 @@
 #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
 
 /* Mode Register */
-#define AT91_SAMA5D2_MR		0x04
+	u16				MR;
 /* Trigger Selection */
 #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
 /* ADTRG */
@@ -82,19 +83,19 @@
 #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
 
 /* Channel Sequence Register 1 */
-#define AT91_SAMA5D2_SEQR1	0x08
+	u16				SEQR1;
 /* Channel Sequence Register 2 */
-#define AT91_SAMA5D2_SEQR2	0x0c
+	u16				SEQR2;
 /* Channel Enable Register */
-#define AT91_SAMA5D2_CHER	0x10
+	u16				CHER;
 /* Channel Disable Register */
-#define AT91_SAMA5D2_CHDR	0x14
+	u16				CHDR;
 /* Channel Status Register */
-#define AT91_SAMA5D2_CHSR	0x18
+	u16				CHSR;
 /* Last Converted Data Register */
-#define AT91_SAMA5D2_LCDR	0x20
+	u16				LCDR;
 /* Interrupt Enable Register */
-#define AT91_SAMA5D2_IER	0x24
+	u16				IER;
 /* Interrupt Enable Register - TS X measurement ready */
 #define AT91_SAMA5D2_IER_XRDY   BIT(20)
 /* Interrupt Enable Register - TS Y measurement ready */
@@ -109,22 +110,23 @@
 #define AT91_SAMA5D2_IER_PEN    BIT(29)
 /* Interrupt Enable Register - No pen detect */
 #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
+
 /* Interrupt Disable Register */
-#define AT91_SAMA5D2_IDR	0x28
+	u16				IDR;
 /* Interrupt Mask Register */
-#define AT91_SAMA5D2_IMR	0x2c
+	u16				IMR;
 /* Interrupt Status Register */
-#define AT91_SAMA5D2_ISR	0x30
+	u16				ISR;
 /* Interrupt Status Register - Pen touching sense status */
 #define AT91_SAMA5D2_ISR_PENS   BIT(31)
 /* Last Channel Trigger Mode Register */
-#define AT91_SAMA5D2_LCTMR	0x34
+	u16				LCTMR;
 /* Last Channel Compare Window Register */
-#define AT91_SAMA5D2_LCCWR	0x38
+	u16				LCCWR;
 /* Overrun Status Register */
-#define AT91_SAMA5D2_OVER	0x3c
+	u16				OVER;
 /* Extended Mode Register */
-#define AT91_SAMA5D2_EMR	0x40
+	u16				EMR;
 /* Extended Mode Register - Oversampling rate */
 #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
 #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
@@ -134,22 +136,22 @@
 
 /* Extended Mode Register - Averaging on single trigger event */
 #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
+
 /* Compare Window Register */
-#define AT91_SAMA5D2_CWR	0x44
+	u16				CWR;
 /* Channel Gain Register */
-#define AT91_SAMA5D2_CGR	0x48
-
+	u16				CGR;
 /* Channel Offset Register */
-#define AT91_SAMA5D2_COR	0x4c
+	u16				COR;
 #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
 
 /* Analog Control Register */
-#define AT91_SAMA5D2_ACR	0x94
+	u16				ACR;
 /* Analog Control Register - Pen detect sensitivity mask */
 #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
 
 /* Touchscreen Mode Register */
-#define AT91_SAMA5D2_TSMR	0xb0
+	u16				TSMR;
 /* Touchscreen Mode Register - No touch mode */
 #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
 /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
@@ -178,13 +180,13 @@
 #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
 
 /* Touchscreen X Position Register */
-#define AT91_SAMA5D2_XPOSR	0xb4
+	u16				XPOSR;
 /* Touchscreen Y Position Register */
-#define AT91_SAMA5D2_YPOSR	0xb8
+	u16				YPOSR;
 /* Touchscreen Pressure Register */
-#define AT91_SAMA5D2_PRESSR	0xbc
+	u16				PRESSR;
 /* Trigger Register */
-#define AT91_SAMA5D2_TRGR	0xc0
+	u16				TRGR;
 /* Mask for TRGMOD field of TRGR register */
 #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
 /* No trigger, only software trigger can start conversions */
@@ -203,30 +205,52 @@
 #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
 
 /* Correction Select Register */
-#define AT91_SAMA5D2_COSR	0xd0
+	u16				COSR;
 /* Correction Value Register */
-#define AT91_SAMA5D2_CVR	0xd4
+	u16				CVR;
 /* Channel Error Correction Register */
-#define AT91_SAMA5D2_CECR	0xd8
+	u16				CECR;
 /* Write Protection Mode Register */
-#define AT91_SAMA5D2_WPMR	0xe4
+	u16				WPMR;
 /* Write Protection Status Register */
-#define AT91_SAMA5D2_WPSR	0xe8
+	u16				WPSR;
 /* Version Register */
-#define AT91_SAMA5D2_VERSION	0xfc
-
-#define AT91_SAMA5D2_HW_TRIG_CNT 3
-#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
-#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
-
-#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
+	u16				VERSION;
+};
 
-#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
-#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
-#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
-#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
+static const struct at91_adc_reg_layout sama5d2_layout = {
+	.CR =			0x00,
+	.MR =			0x04,
+	.SEQR1 =		0x08,
+	.SEQR2 =		0x0c,
+	.CHER =			0x10,
+	.CHDR =			0x14,
+	.CHSR =			0x18,
+	.LCDR =			0x20,
+	.IER =			0x24,
+	.IDR =			0x28,
+	.IMR =			0x2c,
+	.ISR =			0x30,
+	.LCTMR =		0x34,
+	.LCCWR =		0x38,
+	.OVER =			0x3c,
+	.EMR =			0x40,
+	.CWR =			0x44,
+	.CGR =			0x48,
+	.COR =			0x4c,
+	.ACR =			0x94,
+	.TSMR =			0xb0,
+	.XPOSR =		0xb4,
+	.YPOSR =		0xb8,
+	.PRESSR =		0xbc,
+	.TRGR =			0xc0,
+	.COSR =			0xd0,
+	.CVR =			0xd4,
+	.CECR =			0xd8,
+	.WPMR =			0xe4,
+	.WPSR =			0xe8,
+	.VERSION =		0xfc,
+};
 
 #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
 #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
@@ -235,18 +259,6 @@
 
 #define AT91_SAMA5D2_MAX_POS_BITS			12
 
-/*
- * Maximum number of bytes to hold conversion from all channels
- * without the timestamp.
- */
-#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
-					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
-
-/* This total must also include the timestamp */
-#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
-
-#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
-
 #define AT91_HWFIFO_MAX_SIZE_STR	"128"
 #define AT91_HWFIFO_MAX_SIZE		128
 
@@ -255,12 +267,12 @@
 #define AT91_OSR_4SAMPLES		4
 #define AT91_OSR_16SAMPLES		16
 
-#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
+#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
 	{								\
 		.type = IIO_VOLTAGE,					\
 		.channel = num,						\
 		.address = addr,					\
-		.scan_index = num,					\
+		.scan_index = index,					\
 		.scan_type = {						\
 			.sign = 'u',					\
 			.realbits = 14,					\
@@ -274,14 +286,14 @@
 		.indexed = 1,						\
 	}
 
-#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
+#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
 	{								\
 		.type = IIO_VOLTAGE,					\
 		.differential = 1,					\
 		.channel = num,						\
 		.channel2 = num2,					\
 		.address = addr,					\
-		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
+		.scan_index = index,					\
 		.scan_type = {						\
 			.sign = 's',					\
 			.realbits = 14,					\
@@ -328,13 +340,48 @@
 		.datasheet_name = name,					\
 	}
 
-#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
-#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
+#define at91_adc_readl(st, reg)						\
+	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
+#define at91_adc_read_chan(st, reg)					\
+	readl_relaxed((st)->base + reg)
+#define at91_adc_writel(st, reg, val)					\
+	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
+
+/**
+ * struct at91_adc_platform - at91-sama5d2 platform information struct
+ * @layout:		pointer to the reg layout struct
+ * @adc_channels:	pointer to an array of channels for registering in
+ *			the iio subsystem
+ * @nr_channels:	number of physical channels available
+ * @touch_chan_x:	index of the touchscreen X channel
+ * @touch_chan_y:	index of the touchscreen Y channel
+ * @touch_chan_p:	index of the touchscreen P channel
+ * @max_channels:	number of total channels
+ * @hw_trig_cnt:	number of possible hardware triggers
+ */
+struct at91_adc_platform {
+	const struct at91_adc_reg_layout	*layout;
+	const struct iio_chan_spec		(*adc_channels)[];
+	unsigned int				nr_channels;
+	unsigned int				touch_chan_x;
+	unsigned int				touch_chan_y;
+	unsigned int				touch_chan_p;
+	unsigned int				max_channels;
+	unsigned int				hw_trig_cnt;
+};
 
+/**
+ * struct at91_adc_soc_info - at91-sama5d2 soc information struct
+ * @startup_time:	device startup time
+ * @min_sample_rate:	minimum sample rate in Hz
+ * @max_sample_rate:	maximum sample rate in Hz
+ * @platform:		pointer to the platform structure
+ */
 struct at91_adc_soc_info {
 	unsigned			startup_time;
 	unsigned			min_sample_rate;
 	unsigned			max_sample_rate;
+	const struct at91_adc_platform	*platform;
 };
 
 struct at91_adc_trigger {
@@ -382,6 +429,15 @@ struct at91_adc_touch {
 	struct work_struct		workq;
 };
 
+/*
+ * Buffer size requirements:
+ * No channels * bytes_per_channel(2) + timestamp bytes (8)
+ * Divided by 2 because we need half words.
+ * We assume 32 channels for now, has to be increased if needed.
+ * Nobody minds a buffer being too big.
+ */
+#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
+
 struct at91_adc_state {
 	void __iomem			*base;
 	int				irq;
@@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
 	},
 };
 
-static const struct iio_chan_spec at91_adc_channels[] = {
-	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
-	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
-	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
-	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
-	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
-	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
-	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
-	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
-	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
-	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
-	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
-	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
-	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
-	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
-	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
-	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
-	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
-	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
-	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
-	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
-	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
-	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
+static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
+	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
+	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
+	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
+	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
+	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
+	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
+	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
+	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
+	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
+	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
+	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
+	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
+	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
+	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
+	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
+	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
+	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
+	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
+	IIO_CHAN_SOFT_TIMESTAMP(18),
+	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
+	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
+	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
+};
+
+static const struct at91_adc_platform sama5d2_platform = {
+	.layout = &sama5d2_layout,
+	.adc_channels = &at91_sama5d2_adc_channels,
+#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
+#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
+	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
+		       AT91_SAMA5D2_DIFF_CHAN_CNT,
+#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
+					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
+	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
+#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
+	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
+#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
+	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
+#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
+	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
+#define AT91_SAMA5D2_HW_TRIG_CNT	3
+	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
 };
 
 static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
@@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 {
 	u32 mask = 0;
 	u8 bit;
+	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	for_each_set_bit(bit, indio_dev->active_scan_mask,
 			 indio_dev->num_channels) {
@@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 		mask |= BIT(chan->channel);
 	}
 
-	return mask & GENMASK(11, 0);
+	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
 static void at91_adc_config_emr(struct at91_adc_state *st)
 {
 	/* configure the extended mode register */
-	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
+	unsigned int emr = at91_adc_readl(st, EMR);
 
 	/* select oversampling per single trigger event */
 	emr |= AT91_SAMA5D2_EMR_ASTE(1);
@@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
 		break;
 	}
 
-	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
+	at91_adc_writel(st, EMR, emr);
 }
 
 static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
@@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
 
 	if (!state) {
 		/* disabling touch IRQs and setting mode to no touch enabled */
-		at91_adc_writel(st, AT91_SAMA5D2_IDR,
+		at91_adc_writel(st, IDR,
 				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
-		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
+		at91_adc_writel(st, TSMR, 0);
 		return 0;
 	}
 	/*
@@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
 	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
 	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
 
-	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
+	at91_adc_writel(st, TSMR, tsmr);
 
-	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
+	acr =  at91_adc_readl(st, ACR);
 	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
 	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
-	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
+	at91_adc_writel(st, ACR, acr);
 
 	/* Sample Period Time = (TRGPER + 1) / ADCClock */
 	st->touch_st.sample_period_val =
 				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
 				 clk_khz / 1000) - 1, 1);
 	/* enable pen detect IRQ */
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
 
 	return 0;
 }
@@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
 	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
 	 */
 	/* first half of register is the x or y, second half is the scale */
-	val = at91_adc_readl(st, reg);
+	if (reg == st->soc_info.platform->layout->XPOSR)
+		val = at91_adc_readl(st, XPOSR);
+	else if (reg == st->soc_info.platform->layout->YPOSR)
+		val = at91_adc_readl(st, YPOSR);
+
 	if (!val)
 		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
 
@@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
 
 static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
 {
-	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
+	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
 	return st->touch_st.x_pos;
 }
 
 static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
 {
-	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
+	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
 }
 
 static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
@@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
 	u32 factor = 1000;
 
 	/* calculate the pressure */
-	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
+	val = at91_adc_readl(st, PRESSR);
 	z1 = val & AT91_SAMA5D2_XYZ_MASK;
 	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
 
@@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
 	*val = 0;
 	if (!st->touch_st.touching)
 		return -ENODATA;
-	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
+	if (chan == st->soc_info.platform->touch_chan_x)
 		*val = at91_adc_touch_x_pos(st);
-	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
+	else if (chan == st->soc_info.platform->touch_chan_y)
 		*val = at91_adc_touch_y_pos(st);
 	else
 		return -ENODATA;
@@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
 	*val = 0;
 	if (!st->touch_st.touching)
 		return -ENODATA;
-	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
+	if (chan == st->soc_info.platform->touch_chan_y)
 		*val = at91_adc_touch_pressure(st);
 	else
 		return -ENODATA;
@@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
 {
 	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
+	u32 status = at91_adc_readl(st, TRGR);
 
 	/* clear TRGMOD */
 	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
@@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
 		status |= st->selected_trig->trgmod_value;
 
 	/* set/unset hw trigger */
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
+	at91_adc_writel(st, TRGR, status);
 
 	return 0;
 }
@@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
 	enable_irq(st->irq);
 
 	/* Needed to ACK the DRDY interruption */
-	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
+	at91_adc_readl(st, LCDR);
 }
 
 static const struct iio_trigger_ops at91_adc_trigger_ops = {
@@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
 	}
 
 	/* enable general overrun error signaling */
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
 	/* Issue pending DMA requests */
 	dma_async_issue_pending(st->dma_st.dma_chan);
 
@@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
 
 	return !!bitmap_subset(indio_dev->active_scan_mask,
 			       &st->touch_st.channels_bitmask,
-			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
+			       st->soc_info.platform->max_channels + 1);
 }
 
 static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
@@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
+		cor = at91_adc_readl(st, COR);
 
 		if (chan->differential)
 			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
@@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 			cor &= ~(BIT(chan->channel) <<
 			       AT91_SAMA5D2_COR_DIFF_OFFSET);
 
-		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
+		at91_adc_writel(st, COR, cor);
 
-		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
+		at91_adc_writel(st, CHER, BIT(chan->channel));
 	}
 
 	if (at91_adc_buffer_check_use_irq(indio_dev, st))
-		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
+		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
 
 	return 0;
 }
@@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
+		at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 		if (st->dma_st.dma_chan)
-			at91_adc_readl(st, chan->address);
+			at91_adc_read_chan(st, chan->address);
 	}
 
 	if (at91_adc_buffer_check_use_irq(indio_dev, st))
-		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
+		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
 
 	/* read overflow register to clear possible overflow status */
-	at91_adc_readl(st, AT91_SAMA5D2_OVER);
+	at91_adc_readl(st, OVER);
 
 	/* if we are using DMA we must clear registers and end DMA */
 	if (st->dma_st.dma_chan)
@@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 	 * Check if the conversion is ready. If not, wait a little bit, and
 	 * in case of timeout exit with an error.
 	 */
-	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
+	while ((at91_adc_readl(st, ISR) & mask) != mask &&
 	       timeout) {
 		usleep_range(50, 100);
 		timeout--;
@@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 		 * Thus, emit a warning.
 		 */
 		if (chan->type == IIO_VOLTAGE) {
-			val = at91_adc_readl(st, chan->address);
+			val = at91_adc_read_chan(st, chan->address);
 			at91_adc_adjust_val_osr(st, &val);
 			st->buffer[i] = val;
 		} else {
@@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
 	s64 interval;
 	int sample_index = 0, sample_count, sample_size;
 
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
+	u32 status = at91_adc_readl(st, ISR);
 	/* if we reached this point, we cannot sample faster */
 	if (status & AT91_SAMA5D2_IER_GOVRE)
 		pr_info_ratelimited("%s: conversion overrun detected\n",
@@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
 	 * actually polling the trigger now.
 	 */
 	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
-		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
+		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	if (st->dma_st.dma_chan)
 		at91_adc_trigger_handler_dma(indio_dev);
@@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
 	startup = at91_adc_startup_time(st->soc_info.startup_time,
 					freq / 1000);
 
-	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
+	mr = at91_adc_readl(st, MR);
 	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
 	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
 	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
-	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
+	at91_adc_writel(st, MR, mr);
 
 	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
 		freq, startup, prescal);
@@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
 	int i = 0;
 
 	for_each_set_bit(bit, indio_dev->active_scan_mask,
-			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
+			 st->soc_info.platform->max_channels + 1) {
 		struct iio_chan_spec const *chan =
 					 at91_adc_chan_get(indio_dev, bit);
 
@@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
 
 static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
 {
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
+	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
 			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY);
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
-			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
+	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
 			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
 	st->touch_st.touching = true;
 }
@@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
-			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
+	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
+	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
 			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY);
 	st->touch_st.touching = false;
 
 	at91_adc_touch_data_handler(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
+	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
 }
 
 static void at91_adc_workq_handler(struct work_struct *workq)
@@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 {
 	struct iio_dev *indio = private;
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
-	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
+	u32 status = at91_adc_readl(st, ISR);
+	u32 imr = at91_adc_readl(st, IMR);
 	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY;
 
@@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 		 * touching, but the measurements are not ready yet.
 		 * read and ignore.
 		 */
-		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
-		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
-		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
+		status = at91_adc_readl(st, XPOSR);
+		status = at91_adc_readl(st, YPOSR);
+		status = at91_adc_readl(st, PRESSR);
 	} else if (iio_buffer_enabled(indio) &&
 		   (status & AT91_SAMA5D2_IER_DRDY)) {
 		/* triggered buffer without DMA */
@@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 		WARN(true, "Unexpected irq occurred\n");
 	} else if (!iio_buffer_enabled(indio)) {
 		/* software requested conversion */
-		st->conversion_value = at91_adc_readl(st, st->chan->address);
+		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
 		st->conversion_done = true;
 		wake_up_interruptible(&st->wq_data_available);
 	}
@@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
 		      AT91_SAMA5D2_COR_DIFF_OFFSET;
 
-	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
-	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
+	at91_adc_writel(st, COR, cor);
+	at91_adc_writel(st, CHER, BIT(chan->channel));
+	at91_adc_writel(st, IER, BIT(chan->channel));
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	ret = wait_event_interruptible_timeout(st->wq_data_available,
 					       st->conversion_done,
@@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		st->conversion_done = false;
 	}
 
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
-	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
+	at91_adc_writel(st, IDR, BIT(chan->channel));
+	at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 	/* Needed to ACK the DRDY interruption */
-	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
+	at91_adc_readl(st, LCDR);
 
 	mutex_unlock(&st->lock);
 
@@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct at91_adc_state *st = iio_priv(indio_dev);
 	struct dma_slave_config config = {0};
+	/* we have 2 bytes for each channel */
+	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
 	/*
 	 * We make the buffer double the size of the fifo,
 	 * such that DMA uses one half of the buffer (full fifo size)
 	 * and the software uses the other half to read/write.
 	 */
 	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
-					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
-					  PAGE_SIZE);
+					  sample_size * 2, PAGE_SIZE);
 
 	if (st->dma_st.dma_chan)
 		return;
@@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
 	/* Configure DMA channel to read data register */
 	config.direction = DMA_DEV_TO_MEM;
 	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
-			  + AT91_SAMA5D2_LCDR);
+			  + st->soc_info.platform->layout->LCDR);
 	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
 	config.src_maxburst = 1;
 	config.dst_maxburst = 1;
@@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct at91_adc_state *st = iio_priv(indio_dev);
+	/* we have 2 bytes for each channel */
+	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
 	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
-					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
-					  PAGE_SIZE);
+					  sample_size * 2, PAGE_SIZE);
 
 	/* if we are not using DMA, just return */
 	if (!st->dma_st.dma_chan)
@@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
-			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
+			  st->soc_info.platform->max_channels + 1))
 		return 0;
 	/*
 	 * if the new bitmap is a combination of touchscreen and regular
 	 * channels, then we are not fine
 	 */
 	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
-			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
+			      st->soc_info.platform->max_channels + 1))
 		return -EINVAL;
 	return 0;
 }
@@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
-	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
+	at91_adc_writel(st, IDR, 0xffffffff);
 	/*
 	 * Transfer field must be set to 2 according to the datasheet and
 	 * allows different analog settings for each channel.
 	 */
-	at91_adc_writel(st, AT91_SAMA5D2_MR,
+	at91_adc_writel(st, MR,
 			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
 
 	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
@@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
 	if (!indio_dev)
 		return -ENOMEM;
 
+	st = iio_priv(indio_dev);
+	st->indio_dev = indio_dev;
+
+	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
+
 	indio_dev->name = dev_name(&pdev->dev);
 	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
 	indio_dev->info = &at91_adc_info;
-	indio_dev->channels = at91_adc_channels;
-	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
-
-	st = iio_priv(indio_dev);
-	st->indio_dev = indio_dev;
+	indio_dev->channels = *st->soc_info.platform->adc_channels;
+	indio_dev->num_channels = st->soc_info.platform->max_channels;
 
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_x, 1);
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_y, 1);
 	bitmap_set(&st->touch_st.channels_bitmask,
-		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
+		   st->soc_info.platform->touch_chan_p, 1);
 
 	st->oversampling_ratio = AT91_OSR_1SAMPLES;
 
@@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 	st->selected_trig = NULL;
 
 	/* find the right trigger, or no trigger at all */
-	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
+	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
 		if (at91_adc_trigger_list[i].edge_type == edge_type) {
 			st->selected_trig = &at91_adc_trigger_list[i];
 			break;
@@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 			 st->selected_trig->name);
 
 	dev_info(&pdev->dev, "version: %x\n",
-		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
+		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
 
 	return 0;
 
@@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
 	 * and can be used by for other devices.
 	 * Otherwise, ADC will hog them and we can't go to suspend mode.
 	 */
-	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
+	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
 
 	clk_disable_unprepare(st->per_clk);
 	regulator_disable(st->vref);
@@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
 static const struct of_device_id at91_adc_dt_match[] = {
 	{
 		.compatible = "atmel,sama5d2-adc",
+		.data = (const void *)&sama5d2_platform,
 	}, {
 		/* sentinel */
 	}
-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:36 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:36 +0300
Subject: [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for separate
 end of conversion registers
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-6-eugen.hristev@microchip.com>

Some platforms have separated the end-of-conversion information from the
usual ISR/IMR/IER/IDR registers, into EOC_ISR/EOC_IMR/EOC_IER/EOC_IDR.
To cope with both variants, helpers are being added, that will make
code more clear and more easy to read.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 66 ++++++++++++++++++++++++++----
 1 file changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 8ede18b8d789..23be7cec063e 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -117,6 +117,14 @@ struct at91_adc_reg_layout {
 	u16				IMR;
 /* Interrupt Status Register */
 	u16				ISR;
+/* End of Conversion Interrupt Enable Register */
+	u16				EOC_IER;
+/* End of Conversion Interrupt Disable Register */
+	u16				EOC_IDR;
+/* End of Conversion Interrupt Mask Register */
+	u16				EOC_IMR;
+/* End of Conversion Interrupt Status Register */
+	u16				EOC_ISR;
 /* Interrupt Status Register - Pen touching sense status */
 #define AT91_SAMA5D2_ISR_PENS   BIT(31)
 /* Last Channel Trigger Mode Register */
@@ -581,6 +589,44 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
+static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
+				u32 *eoc)
+{
+	*status = at91_adc_readl(st, ISR);
+	if (st->soc_info.platform->layout->EOC_ISR)
+		*eoc = at91_adc_readl(st, EOC_ISR);
+	else
+		*eoc = *status;
+}
+
+static void at91_adc_irq_mask(struct at91_adc_state *st, u32 *status, u32 *eoc)
+{
+	*status = at91_adc_readl(st, IMR);
+	if (st->soc_info.platform->layout->EOC_IMR)
+		*eoc = at91_adc_readl(st, EOC_IMR);
+	else
+		*eoc = *status;
+}
+
+static void at91_adc_eoc_dis(struct at91_adc_state *st, unsigned int channel)
+{
+	/*
+	 * On some products having the EOC bits in a separate register,
+	 * errata recommends not writing this register (EOC_IDR).
+	 * On products having the EOC bits in the IDR register, it's fine to write it.
+	 */
+	if (!st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, IDR, BIT(channel));
+}
+
+static void at91_adc_eoc_ena(struct at91_adc_state *st, unsigned int channel)
+{
+	if (!st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, IER, BIT(channel));
+	else
+		at91_adc_writel(st, EOC_IER, BIT(channel));
+}
+
 static void at91_adc_config_emr(struct at91_adc_state *st)
 {
 	/* configure the extended mode register */
@@ -1100,13 +1146,15 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
 	u8 bit;
 	u32 mask = at91_adc_active_scan_mask_to_reg(indio_dev);
 	unsigned int timeout = 50;
+	u32 status, imr, eoc = 0, eoc_imr;
 
 	/*
 	 * Check if the conversion is ready. If not, wait a little bit, and
 	 * in case of timeout exit with an error.
 	 */
-	while ((at91_adc_readl(st, ISR) & mask) != mask &&
-	       timeout) {
+	while (((eoc & mask) != mask) && timeout) {
+		at91_adc_irq_status(st, &status, &eoc);
+		at91_adc_irq_mask(st, &imr, &eoc_imr);
 		usleep_range(50, 100);
 		timeout--;
 	}
@@ -1342,12 +1390,14 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
 {
 	struct iio_dev *indio = private;
 	struct at91_adc_state *st = iio_priv(indio);
-	u32 status = at91_adc_readl(st, ISR);
-	u32 imr = at91_adc_readl(st, IMR);
+	u32 status, eoc, imr, eoc_imr;
 	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
 			AT91_SAMA5D2_IER_PRDY;
 
-	if (!(status & imr))
+	at91_adc_irq_status(st, &status, &eoc);
+	at91_adc_irq_mask(st, &imr, &eoc_imr);
+
+	if (!(status & imr) && !(eoc & eoc_imr))
 		return IRQ_NONE;
 	if (status & AT91_SAMA5D2_IER_PEN) {
 		/* pen detected IRQ */
@@ -1441,7 +1491,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 
 	at91_adc_writel(st, COR, cor);
 	at91_adc_writel(st, CHER, BIT(chan->channel));
-	at91_adc_writel(st, IER, BIT(chan->channel));
+	at91_adc_eoc_ena(st, chan->channel);
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
 
 	ret = wait_event_interruptible_timeout(st->wq_data_available,
@@ -1458,7 +1508,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 		st->conversion_done = false;
 	}
 
-	at91_adc_writel(st, IDR, BIT(chan->channel));
+	at91_adc_eoc_dis(st, st->chan->channel);
 	at91_adc_writel(st, CHDR, BIT(chan->channel));
 
 	/* Needed to ACK the DRDY interruption */
@@ -1676,6 +1726,8 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
 	struct at91_adc_state *st = iio_priv(indio_dev);
 
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
+	if (st->soc_info.platform->layout->EOC_IDR)
+		at91_adc_writel(st, EOC_IDR, 0xffffffff);
 	at91_adc_writel(st, IDR, 0xffffffff);
 	/*
 	 * Transfer field must be set to 2 according to the datasheet and
-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:37 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:37 +0300
Subject: [PATCH v2 06/10] iio: adc: at91-sama5d2_adc: add helper for COR
 register
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-7-eugen.hristev@microchip.com>

Add helper for the COR register. This helper allows to modify the COR
register, removes duplicate code and improves readability.
The COR offset is now part of the register layout. This will allow
different platform with a different offset to use the same helper.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 40 +++++++++++++++---------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 23be7cec063e..bb4e5e1e3ce4 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -151,8 +151,8 @@ struct at91_adc_reg_layout {
 	u16				CGR;
 /* Channel Offset Register */
 	u16				COR;
-#define AT91_SAMA5D2_COR_DIFF_OFFSET	16
-
+/* Channel Offset Register differential offset - constant, not a register */
+	u16				COR_diff_offset;
 /* Analog Control Register */
 	u16				ACR;
 /* Analog Control Register - Pen detect sensitivity mask */
@@ -246,6 +246,7 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
 	.CWR =			0x44,
 	.CGR =			0x48,
 	.COR =			0x4c,
+	.COR_diff_offset =	16,
 	.ACR =			0x94,
 	.TSMR =			0xb0,
 	.XPOSR =		0xb4,
@@ -589,6 +590,21 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
 	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
 }
 
+static void at91_adc_cor(struct at91_adc_state *st,
+			 struct iio_chan_spec const *chan)
+{
+	u32 cor, cur_cor;
+
+	cor = (BIT(chan->channel) | BIT(chan->channel2));
+
+	cur_cor = at91_adc_readl(st, COR);
+	cor <<= st->soc_info.platform->layout->COR_diff_offset;
+	if (chan->differential)
+		at91_adc_writel(st, COR, cur_cor | cor);
+	else
+		at91_adc_writel(st, COR, cur_cor & ~cor);
+}
+
 static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
 				u32 *eoc)
 {
@@ -1033,8 +1049,6 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 			 indio_dev->num_channels) {
 		struct iio_chan_spec const *chan =
 					at91_adc_chan_get(indio_dev, bit);
-		u32 cor;
-
 		if (!chan)
 			continue;
 		/* these channel types cannot be handled by this trigger */
@@ -1042,16 +1056,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
 		    chan->type == IIO_PRESSURE)
 			continue;
 
-		cor = at91_adc_readl(st, COR);
-
-		if (chan->differential)
-			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
-				AT91_SAMA5D2_COR_DIFF_OFFSET;
-		else
-			cor &= ~(BIT(chan->channel) <<
-			       AT91_SAMA5D2_COR_DIFF_OFFSET);
-
-		at91_adc_writel(st, COR, cor);
+		at91_adc_cor(st, chan);
 
 		at91_adc_writel(st, CHER, BIT(chan->channel));
 	}
@@ -1439,7 +1444,6 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 				  struct iio_chan_spec const *chan, int *val)
 {
 	struct at91_adc_state *st = iio_priv(indio_dev);
-	u32 cor = 0;
 	u16 tmp_val;
 	int ret;
 
@@ -1485,11 +1489,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
 
 	st->chan = chan;
 
-	if (chan->differential)
-		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
-		      AT91_SAMA5D2_COR_DIFF_OFFSET;
-
-	at91_adc_writel(st, COR, cor);
+	at91_adc_cor(st, chan);
 	at91_adc_writel(st, CHER, BIT(chan->channel));
 	at91_adc_eoc_ena(st, chan->channel);
 	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:38 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:38 +0300
Subject: [PATCH v2 07/10] iio: adc: at91-sama5d2_adc: add support for sama7g5
 device
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-8-eugen.hristev@microchip.com>

Add support to sama7g5 ADC which is similar with sama5d2/sam9x60 device.
Differences are highlighted by compatible.
Main differences include 16 channels instead of 12 and missing
resistive touchscreen.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 77 ++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index bb4e5e1e3ce4..f3f5230eac54 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -261,6 +261,38 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
 	.VERSION =		0xfc,
 };
 
+static const struct at91_adc_reg_layout sama7g5_layout = {
+	.CR =			0x00,
+	.MR =			0x04,
+	.SEQR1 =		0x08,
+	.SEQR2 =		0x0c,
+	.CHER =			0x10,
+	.CHDR =			0x14,
+	.CHSR =			0x18,
+	.LCDR =			0x20,
+	.IER =			0x24,
+	.IDR =			0x28,
+	.IMR =			0x2c,
+	.ISR =			0x30,
+	.EOC_IER =		0x34,
+	.EOC_IDR =		0x38,
+	.EOC_IMR =		0x3c,
+	.EOC_ISR =		0x40,
+	.OVER =			0x4c,
+	.EMR =			0x50,
+	.CWR =			0x54,
+	.COR =			0x5c,
+	.COR_diff_offset =	0,
+	.ACR =			0xe0,
+	.TRGR =			0x100,
+	.COSR =			0x104,
+	.CVR =			0x108,
+	.CECR =			0x10c,
+	.WPMR =			0x118,
+	.WPSR =			0x11c,
+	.VERSION =		0x130,
+};
+
 #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
 #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
 
@@ -527,6 +559,34 @@ static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
 	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
 };
 
+static const struct iio_chan_spec at91_sama7g5_adc_channels[] = {
+	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x60),
+	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x64),
+	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x68),
+	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x6c),
+	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x70),
+	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x74),
+	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x78),
+	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x7c),
+	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x80),
+	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x84),
+	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x88),
+	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x8c),
+	AT91_SAMA5D2_CHAN_SINGLE(12, 12, 0x90),
+	AT91_SAMA5D2_CHAN_SINGLE(13, 13, 0x94),
+	AT91_SAMA5D2_CHAN_SINGLE(14, 14, 0x98),
+	AT91_SAMA5D2_CHAN_SINGLE(15, 15, 0x9c),
+	AT91_SAMA5D2_CHAN_DIFF(16, 0, 1, 0x60),
+	AT91_SAMA5D2_CHAN_DIFF(17, 2, 3, 0x68),
+	AT91_SAMA5D2_CHAN_DIFF(18, 4, 5, 0x70),
+	AT91_SAMA5D2_CHAN_DIFF(19, 6, 7, 0x78),
+	AT91_SAMA5D2_CHAN_DIFF(20, 8, 9, 0x80),
+	AT91_SAMA5D2_CHAN_DIFF(21, 10, 11, 0x88),
+	AT91_SAMA5D2_CHAN_DIFF(22, 12, 13, 0x90),
+	AT91_SAMA5D2_CHAN_DIFF(23, 14, 15, 0x98),
+	IIO_CHAN_SOFT_TIMESTAMP(24),
+};
+
 static const struct at91_adc_platform sama5d2_platform = {
 	.layout = &sama5d2_layout,
 	.adc_channels = &at91_sama5d2_adc_channels,
@@ -547,6 +607,20 @@ static const struct at91_adc_platform sama5d2_platform = {
 	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
 };
 
+static const struct at91_adc_platform sama7g5_platform = {
+	.layout = &sama7g5_layout,
+	.adc_channels = &at91_sama7g5_adc_channels,
+#define AT91_SAMA7G5_SINGLE_CHAN_CNT	16
+#define AT91_SAMA7G5_DIFF_CHAN_CNT	8
+	.nr_channels = AT91_SAMA7G5_SINGLE_CHAN_CNT +
+		       AT91_SAMA7G5_DIFF_CHAN_CNT,
+#define AT91_SAMA7G5_MAX_CHAN_IDX	(AT91_SAMA7G5_SINGLE_CHAN_CNT + \
+					AT91_SAMA7G5_DIFF_CHAN_CNT)
+	.max_channels = ARRAY_SIZE(at91_sama7g5_adc_channels),
+#define AT91_SAMA7G5_HW_TRIG_CNT	3
+	.hw_trig_cnt = AT91_SAMA7G5_HW_TRIG_CNT,
+};
+
 static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
 {
 	int i;
@@ -2094,6 +2168,9 @@ static const struct of_device_id at91_adc_dt_match[] = {
 	{
 		.compatible = "atmel,sama5d2-adc",
 		.data = (const void *)&sama5d2_platform,
+	}, {
+		.compatible = "microchip,sama7g5-adc",
+		.data = (const void *)&sama7g5_platform,
 	}, {
 		/* sentinel */
 	}
-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:39 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:39 +0300
Subject: [PATCH v2 08/10] iio: adc: at91-sama5d2_adc: update copyright and
 authors information
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-9-eugen.hristev@microchip.com>

Update copyright and authors information (corrected e-mail address), and
add myself as one of the authors.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index f3f5230eac54..d2bce04a5caf 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -4,6 +4,8 @@
  *
  * Copyright (C) 2015 Atmel,
  *               2015 Ludovic Desroches <ludovic.desroches at atmel.com>
+ *		 2021 Microchip Technology, Inc. and its subsidiaries
+ *		 2021 Eugen Hristev <eugen.hristev at microchip.com>
  */
 
 #include <linux/bitops.h>
@@ -2188,6 +2190,7 @@ static struct platform_driver at91_adc_driver = {
 };
 module_platform_driver(at91_adc_driver)
 
-MODULE_AUTHOR("Ludovic Desroches <ludovic.desroches at atmel.com>");
+MODULE_AUTHOR("Ludovic Desroches <ludovic.desroches at microchip.com>");
+MODULE_AUTHOR("Eugen Hristev <eugen.hristev at microchip.com");
 MODULE_DESCRIPTION("Atmel AT91 SAMA5D2 ADC");
 MODULE_LICENSE("GPL v2");
-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:40 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:40 +0300
Subject: [PATCH v2 09/10] ARM: dts: at91: sama7g5: add node for the ADC
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-10-eugen.hristev@microchip.com>

Add node for the ADC controller in sama7g5 SoC.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 arch/arm/boot/dts/sama7g5.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index f9ad5365862f..de960519c72a 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -137,6 +137,22 @@ ps_wdt: watchdog at e001d180 {
 			clocks = <&clk32k 0>;
 		};
 
+		adc: adc at e1000000 {
+			compatible = "microchip,sama7g5-adc";
+			reg = <0xe1000000 0x200>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_GCK 26>;
+			assigned-clocks = <&pmc PMC_TYPE_GCK 26>;
+			assigned-clock-rates = <100000000>;
+			clock-names = "adc_clk";
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(0)>;
+			dma-names = "rx";
+			atmel,min-sample-rate-hz = <200000>;
+			atmel,max-sample-rate-hz = <20000000>;
+			atmel,startup-time-ms = <4>;
+			status = "disabled";
+		};
+
 		sdmmc0: mmc at e1204000 {
 			compatible = "microchip,sama7g5-sdhci", "microchip,sam9x60-sdhci";
 			reg = <0xe1204000 0x4000>;
-- 
2.25.1



From eugen.hristev at microchip.com  Tue Aug 24 04:54:41 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 24 Aug 2021 14:54:41 +0300
Subject: [PATCH v2 10/10] ARM: dts: at91: sama7g5ek: enable ADC on the board
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210824115441.681253-11-eugen.hristev@microchip.com>

The ADC controller on the board is fed by a 2.5V reference voltage.
By default the channels #14 and #15 are dedicated to analog input
(marked AN on the board), on the connectors mikrobus1 and mikrobus2.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 arch/arm/boot/dts/at91-sama7g5ek.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts
index 4cbed98cc2f4..c46be165f2ba 100644
--- a/arch/arm/boot/dts/at91-sama7g5ek.dts
+++ b/arch/arm/boot/dts/at91-sama7g5ek.dts
@@ -122,6 +122,14 @@ spdif_out: spdif-out {
 	};
 };
 
+&adc {
+	vddana-supply = <&vddout25>;
+	vref-supply = <&vddout25>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu-supply = <&vddcpu>;
 };
-- 
2.25.1



From wangborong at cdjrlc.com  Tue Aug 24 05:01:23 2021
From: wangborong at cdjrlc.com (Jason Wang)
Date: Tue, 24 Aug 2021 20:01:23 +0800
Subject: [PATCH] ARM: OMAP2+: Fix typo in some comments
Message-ID: <20210824120123.10899-1-wangborong@cdjrlc.com>

The double `the' in comment "get a struct clk * for the the hwmod's ..."
is repeated. Therefore, we should remove one of them from the comments.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
---
 arch/arm/mach-omap2/omap_hwmod.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 12b26e04686f..a78ef7e7ce23 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -812,7 +812,7 @@ static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
 }
 
 /**
- * _init_main_clk - get a struct clk * for the the hwmod's main functional clk
+ * _init_main_clk - get a struct clk * for the hwmod's main functional clk
  * @oh: struct omap_hwmod *
  *
  * Called from _init_clocks().  Populates the @oh _clk (main
@@ -862,7 +862,7 @@ static int _init_main_clk(struct omap_hwmod *oh)
 }
 
 /**
- * _init_interface_clks - get a struct clk * for the the hwmod's interface clks
+ * _init_interface_clks - get a struct clk * for the hwmod's interface clks
  * @oh: struct omap_hwmod *
  *
  * Called from _init_clocks().  Populates the @oh OCP slave interface
@@ -901,7 +901,7 @@ static int _init_interface_clks(struct omap_hwmod *oh)
 }
 
 /**
- * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks
+ * _init_opt_clk - get a struct clk * for the hwmod's optional clocks
  * @oh: struct omap_hwmod *
  *
  * Called from _init_clocks().  Populates the @oh omap_hwmod_opt_clk
-- 
2.32.0



From mark.rutland at arm.com  Tue Aug 24 05:11:45 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 13:11:45 +0100
Subject: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <CAGsJ_4wU3g5i4PPo+cw3ZyGyswnFp7p7vERaq_aUuhmCCyvqmg@mail.gmail.com>
References: <20210818073336.59678-1-liuqi115@huawei.com>
 <20210818073336.59678-3-liuqi115@huawei.com>
 <20210824105001.GA96738@C02TD0UTHF1T.local>
 <CAGsJ_4wU3g5i4PPo+cw3ZyGyswnFp7p7vERaq_aUuhmCCyvqmg@mail.gmail.com>
Message-ID: <20210824121145.GD96738@C02TD0UTHF1T.local>

On Tue, Aug 24, 2021 at 11:50:08PM +1200, Barry Song wrote:
> On Tue, Aug 24, 2021 at 10:51 PM Mark Rutland <mark.rutland at arm.com> wrote:
> >
> > Hi,
> >
> > I have a bunch of comments below.
> >
> > At a high-level, I'm not all that keen on adding yet another set of
> > trampolines, especially given we have constraints on how we can branch
> > to them which render this not that useful in common configurations (e.g.
> > where KASLR and module randomization is enabled).
> >
> > So importantly, do we actually need this? I don't think the sampel is
> > that compelling since we can already use ftrace to measure function
> > latencies.
> 
> Hopefully I can help answer some general questions. for code details,
> I'll still rely on liuqi.
> 
> As far as I know, the functionality of ftrace is very limited. kprobe,
> on the other hand, can do a lot of
> things, for example, hooking some ebpf code.
> Tons of userspace tools depend on kprobe, eg. ebpf/bcc which is widely
> used nowadays:
> https://github.com/iovisor/bcc
> 
> Function latency is really a very small part of what kprobe can do.

I appreciate that, but *functionally* we can already do the other bits
with the existing kprobes code, so the question for this series is where
the latency/overhead matters in practice.

> kprobe can do much much more. For example, while doing disksnoop by
> kprobe, we are easily collecting the request struct, and get the
> layout of each IO request. without kprobe, we will probably need to
> add tracepoints here and there in kernel code to achieve the same
> goal.
> 
> I believe Masami and kprobe maintainers can answer this question better than me.
> 
> > If we do need this, I think we need to do some more substantial rework
> > to address those branch range limitations. I know that we could permit
> > arbitrary branching if we expand the ftrace-with-regs callsites to ~6
> > instructions, but that interacts rather poorly with stacktracing and
> > will make the kernel a bit bigger.
> 
> This patch is probably the first step towards a faster kprobe on ARM64.
> I assume PLT or some similar tech will help break the limitation next
> step.

I have ideas about how we can make that work (basically an inline PLT
next to the function), but the implementation is *very* different, and
my thinking is that either:

* The latency/overhead is a real concern generally, and this needs to
  work in the majority of cases (e.g. where KASLR and module
  randomization are on). If so, I think we should implement the more
  invasive but complete solution in one go rather than implementing
  something we know we're going to have to throw away.

* The latency is not that much of a concern, or is only a concern ina
  few niche cases. If so, it's not clear to me whether this is
  worthwhile as-is.

> > On Wed, Aug 18, 2021 at 03:33:36PM +0800, Qi Liu wrote:
> > > This patch introduce optprobe for ARM64. In optprobe, probed
> > > instruction is replaced by a branch instruction to detour
> > > buffer. Detour buffer contains trampoline code and a call to
> > > optimized_callback(). optimized_callback() calls opt_pre_handler()
> > > to execute kprobe handler.
> > >
> > > Performance of optprobe on Hip08 platform is test using kprobe
> > > example module[1] to analyze the latency of a kernel function,
> > > and here is the result:
> > >
> > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> > >
> > > kprobe before optimized:
> > > [280709.846380] do_empty returned 0 and took 1530 ns to execute
> > > [280709.852057] do_empty returned 0 and took 550 ns to execute
> > > [280709.857631] do_empty returned 0 and took 440 ns to execute
> > > [280709.863215] do_empty returned 0 and took 380 ns to execute
> > > [280709.868787] do_empty returned 0 and took 360 ns to execute
> > > [280709.874362] do_empty returned 0 and took 340 ns to execute
> > > [280709.879936] do_empty returned 0 and took 320 ns to execute
> > > [280709.885505] do_empty returned 0 and took 300 ns to execute
> > > [280709.891075] do_empty returned 0 and took 280 ns to execute
> > > [280709.896646] do_empty returned 0 and took 290 ns to execute
> > > [280709.902220] do_empty returned 0 and took 290 ns to execute
> > > [280709.907807] do_empty returned 0 and took 290 ns to execute
> > >
> > > optprobe:
> > > [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> > > [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> > > [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> > > [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> > > [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> > > [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> > > [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> > > [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.029158] do_empty returned 0 and took 70 ns to execute
> >
> > Do we have any examples of where this latency matters in practice?
> 
> While doing performance analysis or debugging performance issues  in
> lab, the big latency of the current kprobe
> can significantly impact the real result.
> 
> And it is particularly important when we want to do some online
> diagnostics where machines are running on the cloud.
> we need to minimally affect the real system while watching the system.
> 
> For example, https://gitee.com/xiebaoyou/diagnosis_tools is an
> open-source tool which is used by alibaba, it uses
> kprobe a lot to detect various problems running on aloud.

Ok. It would be good to mention something like this in the commit
message. If it's possible to get an estimate of the overhead reduction,
that would be great.

> > > Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> > >
> > > Note:
> > > To guarantee the offset between probe point and kprobe pre_handler
> > > is smaller than 128MiB, users should set
> > > CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
> > > optprobe will not work and fall back to normal kprobe.
> >
> > Hmm... I don't think that's something we want to recommend, and
> > certainly distros *should* use KASLR and
> > CONFIG_RANDOMIZE_MODULE_REGION_FULL.
> >
> > What happens with defconfig? Do we always get the fallback behaviour?
> 
> For this stage, with no_kaslr cmdline for defconfig, we are always
> going to optprobe. otherwise, it always goes to the fallback
> behaviour. So for this stage, it is probably only useful in lab while
> people are debugging problems. but this is still a widely useful
> scenario.

If it's only going to be used for lab debugging, why is the existing
kprobes logic not sufficient?

Thanks,
Mark.


From robh at kernel.org  Tue Aug 24 05:13:04 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 07:13:04 -0500
Subject: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <20210823070240.12600-2-billy_tsai@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
 <20210823070240.12600-2-billy_tsai@aspeedtech.com>
Message-ID: <YSTiUPQa+HYSA63t@robh.at.kernel.org>

On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
> Add device tree bindings document for the aspeed ast2600 adc device
> driver.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  .../bindings/iio/adc/aspeed,ast2600-adc.yaml  | 97 +++++++++++++++++++
>  1 file changed, 97 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> new file mode 100644
> index 000000000000..248cda7d91e9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> @@ -0,0 +1,97 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ADC that forms part of an ASPEED server management processor.
> +
> +maintainers:
> +  - Billy Tsai <billy_tsai at aspeedtech.com>
> +
> +description: |
> +  ? 10-bits resolution for 16 voltage channels.
> +  ? The device split into two individual engine and each contains 8 voltage
> +  channels.
> +  ? Channel scanning can be non-continuous.
> +  ? Programmable ADC clock frequency.
> +  ? Programmable upper and lower threshold for each channels.
> +  ? Interrupt when larger or less than threshold for each channels.
> +  ? Support hysteresis for each channels.
> +  ? Built-in a compensating method.
> +  ? Built-in a register to trim internal reference voltage.
> +  ? Internal or External reference voltage.
> +  ? Support 2 Internal reference voltage 1.2v or 2.5v.
> +  ? Integrate dividing circuit for battery sensing.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - aspeed,ast2600-adc0
> +      - aspeed,ast2600-adc1

What's the difference between 0 and 1?

> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    description:
> +      Input clock used to derive the sample clock. Expected to be the
> +      SoC's APB clock.

How many clocks?

> +
> +  resets:
> +    maxItems: 1
> +
> +  "#io-channel-cells":
> +    const: 1
> +
> +  vref-supply:
> +    description:
> +      The external regulator supply ADC reference voltage.
> +
> +  aspeed,int_vref_mv:

Don't use '_' in property names.

Use standard unit suffixes as defined in property-units.yaml.

> +    $ref: /schemas/types.yaml#/definitions/uint32

And then you can drop this.

> +    enum: [1200, 2500]
> +    description:
> +      ADC internal reference voltage in millivolts.
> +
> +  aspeed,battery-sensing:
> +    type: boolean
> +    description:
> +      Inform the driver that last channel will be used to sensor battery.
> +
> +  aspeed,trim-data-valid:
> +    type: boolean
> +    description: |
> +      The ADC reference voltage can be calibrated to obtain the trimming
> +      data which will be stored in otp. This property informs the driver that
> +      the data store in the otp is valid.
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - resets
> +  - "#io-channel-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/ast2600-clock.h>
> +    adc0: adc at 1e6e9000 {
> +        compatible = "aspeed,ast2600-adc0";
> +        reg = <0x1e6e9000 0x100>;
> +        clocks = <&syscon ASPEED_CLK_APB2>;
> +        resets = <&syscon ASPEED_RESET_ADC>;
> +        #io-channel-cells = <1>;
> +        aspeed,int_vref_mv = <2500>;
> +    };
> +    adc1: adc at 1e6e9100 {
> +        compatible = "aspeed,ast2600-adc1";
> +        reg = <0x1e6e9100 0x100>;
> +        clocks = <&syscon ASPEED_CLK_APB2>;
> +        resets = <&syscon ASPEED_RESET_ADC>;
> +        #io-channel-cells = <1>;
> +        aspeed,int_vref_mv = <2500>;
> +    };
> +...
> -- 
> 2.25.1
> 
> 


From robh at kernel.org  Tue Aug 24 05:13:53 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 07:13:53 -0500
Subject: [PATCH v4 1/3] dt-bindings: rtc: Add Mstar MSC313e RTC
 devicetree bindings documentation
In-Reply-To: <20210823171613.18941-2-romain.perier@gmail.com>
References: <20210823171613.18941-1-romain.perier@gmail.com>
 <20210823171613.18941-2-romain.perier@gmail.com>
Message-ID: <YSTigWESfHO5VLtH@robh.at.kernel.org>

On Mon, 23 Aug 2021 19:16:11 +0200, Romain Perier wrote:
> This adds the documentation for the devicetree bindings of the Mstar
> MSC313e RTC driver, found from MSC313e SoCs and newer.
> 
> Signed-off-by: Romain Perier <romain.perier at gmail.com>
> ---
>  .../bindings/rtc/mstar,msc313-rtc.yaml        | 49 +++++++++++++++++++
>  1 file changed, 49 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rtc/mstar,msc313-rtc.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From abel.vesa at nxp.com  Tue Aug 24 05:14:01 2021
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 24 Aug 2021 15:14:01 +0300
Subject: [PATCH] clk: imx8mn: Add M7 core clock
In-Reply-To: <20210819202036.2084782-1-marex@denx.de>
References: <20210819202036.2084782-1-marex@denx.de>
Message-ID: <YSTiid0DyCebErn0@ryzen>

On 21-08-19 22:20:36, Marek Vasut wrote:
> Add missing M7 core clock entry to the iMX8MN clock driver.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Abel Vesa <abel.vesa at nxp.com>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Peng Fan <peng.fan at nxp.com>
> Cc: Shawn Guo <shawnguo at kernel.org>

I'm OK with it.

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

> ---
>  drivers/clk/imx/clk-imx8mn.c             | 5 +++++
>  include/dt-bindings/clock/imx8mn-clock.h | 4 +++-
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
> index 212708e9388e2..9dba4eb643ab9 100644
> --- a/drivers/clk/imx/clk-imx8mn.c
> +++ b/drivers/clk/imx/clk-imx8mn.c
> @@ -40,6 +40,9 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl
>  
>  static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
>  
> +static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out",
> +				       "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
> +
>  static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
>  						    "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
>  						    "video_pll1_out", "audio_pll2_out", };
> @@ -421,6 +424,8 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
>  	hws[IMX8MN_CLK_A53_SRC] = hws[IMX8MN_CLK_A53_DIV];
>  	hws[IMX8MN_CLK_A53_CG] = hws[IMX8MN_CLK_A53_DIV];
>  
> +	hws[IMX8MN_CLK_M7_CORE] = imx8m_clk_hw_composite_core("arm_m7_core", imx8mn_m7_sels, base + 0x8080);
> +
>  	hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180);
>  	hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200);
>  
> diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
> index d24b627cb2e71..01e8bab1d767a 100644
> --- a/include/dt-bindings/clock/imx8mn-clock.h
> +++ b/include/dt-bindings/clock/imx8mn-clock.h
> @@ -241,6 +241,8 @@
>  #define IMX8MN_CLK_CLKOUT2_DIV			219
>  #define IMX8MN_CLK_CLKOUT2			220
>  
> -#define IMX8MN_CLK_END				221
> +#define IMX8MN_CLK_M7_CORE			221
> +
> +#define IMX8MN_CLK_END				222
>  
>  #endif
> -- 
> 2.30.2
> 


From abel.vesa at nxp.com  Tue Aug 24 05:15:05 2021
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 24 Aug 2021 15:15:05 +0300
Subject: [PATCH] clk: imx8m: fix clock tree update of TF-A managed clocks
In-Reply-To: <20210810151432.9228-1-a.fatoum@pengutronix.de>
References: <20210810151432.9228-1-a.fatoum@pengutronix.de>
Message-ID: <YSTiyR/uvpYa0jUb@ryzen>

On 21-08-10 17:14:33, Ahmad Fatoum wrote:
> On the i.MX8M*, the TF-A exposes a SiP (Silicon Provider) service
> for DDR frequency scaling. The imx8m-ddrc-devfreq driver calls the
> SiP and then does clk_set_parent on the DDR muxes to synchronize
> the clock tree.
> 
> Since 936c383673b9 ("clk: imx: fix composite peripheral flags"),
> these TF-A managed muxes have SET_PARENT_GATE set, which results
> in imx8m-ddrc-devfreq's clk_set_parent after SiP failing with -EBUSY:
> 
> 	echo 25000000 > userspace/set_freq
> 	imx8m-ddrc-devfreq 3d400000.memory-controller: failed to set
> 		dram_apb parent: -16
> 
> Fix this by adding a new i.MX composite flag for firmware managed
> clocks, which clears SET_PARENT_GATE.
> 
> This is safe to do, because updating the Linux clock tree to reflect
> reality will always be glitch-free.
> 
> Fixes: 936c383673b9 ("clk: imx: fix composite peripheral flags")
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>


Applied, thanks.

> ---
> To: Abel Vesa <abel.vesa at nxp.com>
> To: Michael Turquette <mturquette at baylibre.com>
> To: Stephen Boyd <sboyd at kernel.org>
> To: Shawn Guo <shawnguo at kernel.org>
> To: Sascha Hauer <s.hauer at pengutronix.de>
> To: Pengutronix Kernel Team <kernel at pengutronix.de>
> To: Fabio Estevam <festevam at gmail.com>
> To: NXP Linux Team <linux-imx at nxp.com>
> To: Peng Fan <peng.fan at nxp.com>
> To: Leonard Crestez <leonard.crestez at nxp.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-clk at vger.kernel.org
> ---
>  drivers/clk/imx/clk-composite-8m.c |  3 ++-
>  drivers/clk/imx/clk-imx8mm.c       |  7 ++++---
>  drivers/clk/imx/clk-imx8mn.c       |  7 ++++---
>  drivers/clk/imx/clk-imx8mq.c       |  7 ++++---
>  drivers/clk/imx/clk.h              | 16 ++++++++++++++--
>  5 files changed, 28 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
> index 2c309e3dc8e3..04e728538cef 100644
> --- a/drivers/clk/imx/clk-composite-8m.c
> +++ b/drivers/clk/imx/clk-composite-8m.c
> @@ -216,7 +216,8 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>  		div->width = PCG_PREDIV_WIDTH;
>  		divider_ops = &imx8m_clk_composite_divider_ops;
>  		mux_ops = &clk_mux_ops;
> -		flags |= CLK_SET_PARENT_GATE;
> +		if (!(composite_flags & IMX_COMPOSITE_FW_MANAGED))
> +			flags |= CLK_SET_PARENT_GATE;
>  	}
>  
>  	div->lock = &imx_ccm_lock;
> diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
> index f1919fafb124..73cc9805ec59 100644
> --- a/drivers/clk/imx/clk-imx8mm.c
> +++ b/drivers/clk/imx/clk-imx8mm.c
> @@ -470,10 +470,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
>  
>  	/*
>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> +	 * as div value should always be read from hardware
>  	 */
> -	hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> -	hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> +	hws[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
> +	hws[IMX8MM_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
>  
>  	/* IP */
>  	hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
> diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
> index 88f6630cd472..0a76f969b28b 100644
> --- a/drivers/clk/imx/clk-imx8mn.c
> +++ b/drivers/clk/imx/clk-imx8mn.c
> @@ -453,10 +453,11 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
>  
>  	/*
>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> +	 * as div value should always be read from hardware
>  	 */
> -	hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> -	hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> +	hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
> +	hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
>  
>  	hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
>  	hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> index c491bc9c61ce..83cc2b1c3294 100644
> --- a/drivers/clk/imx/clk-imx8mq.c
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -449,11 +449,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
>  
>  	/*
>  	 * DRAM clocks are manipulated from TF-A outside clock framework.
> -	 * Mark with GET_RATE_NOCACHE to always read div value from hardware
> +	 * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE
> +	 * as div value should always be read from hardware
>  	 */
>  	hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
> -	hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
> -	hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> +	hws[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
> +	hws[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
>  
>  	/* IP */
>  	hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
> index 7571603bee23..e144f983fd8c 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -530,8 +530,9 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
>  		struct clk *div, struct clk *mux, struct clk *pll,
>  		struct clk *step);
>  
> -#define IMX_COMPOSITE_CORE	BIT(0)
> -#define IMX_COMPOSITE_BUS	BIT(1)
> +#define IMX_COMPOSITE_CORE		BIT(0)
> +#define IMX_COMPOSITE_BUS		BIT(1)
> +#define IMX_COMPOSITE_FW_MANAGED	BIT(2)
>  
>  struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>  					    const char * const *parent_names,
> @@ -567,6 +568,17 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
>  		ARRAY_SIZE(parent_names), reg, 0, \
>  		flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
>  
> +#define __imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, flags) \
> +	imx8m_clk_hw_composite_flags(name, parent_names, \
> +		ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_FW_MANAGED, \
> +		flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
> +
> +#define imx8m_clk_hw_fw_managed_composite(name, parent_names, reg) \
> +	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, 0)
> +
> +#define imx8m_clk_hw_fw_managed_composite_critical(name, parent_names, reg) \
> +	__imx8m_clk_hw_fw_managed_composite(name, parent_names, reg, CLK_IS_CRITICAL)
> +
>  #define __imx8m_clk_composite(name, parent_names, reg, flags) \
>  	to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
>  
> -- 
> 2.30.2
> 


From madvenka at linux.microsoft.com  Tue Aug 24 05:19:52 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Tue, 24 Aug 2021 07:19:52 -0500
Subject: [RFC PATCH v8 3/4] arm64: Introduce stack trace reliability
 checks in the unwinder
In-Reply-To: <TY2PR01MB5257EA835C6F28ABF457EB0B85C59@TY2PR01MB5257.jpnprd01.prod.outlook.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-4-madvenka@linux.microsoft.com>
 <TY2PR01MB5257EA835C6F28ABF457EB0B85C59@TY2PR01MB5257.jpnprd01.prod.outlook.com>
Message-ID: <62d8969d-8ba1-4554-16b4-1c0bd4f8d9e7@linux.microsoft.com>



On 8/24/21 12:55 AM, nobuta.keiya at fujitsu.com wrote:
> Hi Madhavan,
> 
>> @@ -245,7 +271,36 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>>  		fp = thread_saved_fp(task);
>>  		pc = thread_saved_pc(task);
>>  	}
>> -	unwind(consume_entry, cookie, task, fp, pc);
>> +	unwind(consume_entry, cookie, task, fp, pc, false);
>> +}
>> +
>> +/*
>> + * arch_stack_walk_reliable() may not be used for livepatch until all of
>> + * the reliability checks are in place in unwind_consume(). However,
>> + * debug and test code can choose to use it even if all the checks are not
>> + * in place.
>> + */
> 
> I'm glad to see the long-awaited function :)
> 
> Does the above comment mean that this comment will be removed by
> another patch series that about live patch enablement, instead of [PATCH 4/4]?
> 
> It seems to take time... But I start thinking about test code.
> 

Yes. This comment will be removed when livepatch will be enabled eventually.
So, AFAICT, there are 4 pieces that are needed:

- Reliable stack trace in the kernel. I am trying to address that with my patch
  series.

- Mark Rutland's work for making patching safe on ARM64.

- Objtool (or alternative method) for stack validation.

- Suraj Jitindar Singh's patch for miscellaneous things needed to enable live patch.

Once all of these pieces are in place, livepatch can be enabled.

That said, arch_stack_walk_reliable() can be used for test and debug purposes anytime
once this patch series gets accepted.

Thanks.

Madhavan


From robh at kernel.org  Tue Aug 24 05:23:50 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 07:23:50 -0500
Subject: [PATCH v3 4/4] ARM: dts: at91: sama5d27_wlsom1: add wifi device
In-Reply-To: <20210820092803.78523-5-claudiu.beznea@microchip.com>
References: <20210820092803.78523-1-claudiu.beznea@microchip.com>
 <20210820092803.78523-5-claudiu.beznea@microchip.com>
Message-ID: <YSTk1pUTAUJLBJQl@robh.at.kernel.org>

On Fri, Aug 20, 2021 at 12:28:03PM +0300, Claudiu Beznea wrote:
> From: Eugen Hristev <eugen.hristev at microchip.com>
> 
> SAMA5D27 WLSOM1 boards has a WILC3000 device soldered. Add proper
> device tree nodes for this.
> 
> [eugen.hristev: original author of this code]
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> [nicolas.ferre: original author of this code]
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi | 71 +++++++++++++++++++++
>  1 file changed, 71 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
> index 025a78310e3a..c7bcfd3ce91d 100644
> --- a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
> +++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
> @@ -30,6 +30,15 @@ main_xtal {
>  			clock-frequency = <24000000>;
>  		};
>  	};
> +
> +	wifi_pwrseq: wifi_pwrseq {
> +		compatible = "mmc-pwrseq-wilc1000";
> +		reset-gpios = <&pioA PIN_PA27 GPIO_ACTIVE_HIGH>;
> +		powerdown-gpios = <&pioA PIN_PA29 GPIO_ACTIVE_HIGH>;
> +		pinctrl-0 = <&pinctrl_wilc_pwrseq>;
> +		pinctrl-names = "default";
> +		status = "okay";

'okay' is the default, so you can drop this.

> +	};
>  };
>  
>  &flx1 {
> @@ -310,5 +319,67 @@ pinctrl_qspi1_default: qspi1_default {
>  			 <PIN_PB10__QSPI1_IO3>;
>  		bias-pull-up;
>  	};
> +
> +	pinctrl_sdmmc1_default: sdmmc1_default {
> +		cmd-data {
> +			pinmux = <PIN_PA28__SDMMC1_CMD>,
> +				 <PIN_PA18__SDMMC1_DAT0>,
> +				 <PIN_PA19__SDMMC1_DAT1>,
> +				 <PIN_PA20__SDMMC1_DAT2>,
> +				 <PIN_PA21__SDMMC1_DAT3>;
> +			bias-disable;
> +		};
> +
> +		conf-ck {
> +			pinmux = <PIN_PA22__SDMMC1_CK>;
> +			bias-disable;
> +		};
> +	};
> +
> +	pinctrl_wilc_default: wilc_default {
> +		conf-irq {
> +			pinmux = <PIN_PB25__GPIO>;
> +			bias-disable;
> +		};
> +	};
> +
> +	pinctrl_wilc_pwrseq: wilc_pwrseq {
> +		conf-ce-nrst {
> +			pinmux = <PIN_PA27__GPIO>,
> +				 <PIN_PA29__GPIO>;
> +			bias-disable;
> +		};
> +
> +		conf-rtcclk {
> +			pinmux = <PIN_PB13__PCK1>;
> +			bias-disable;
> +		};
> +	};
> +};
> +
> +&sdmmc1 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	bus-width = <4>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sdmmc1_default>;
> +	mmc-pwrseq = <&wifi_pwrseq>;
> +	no-1-8-v;
> +	non-removable;
> +	status = "okay";
> +
> +	wilc: wilc at 0 {

wifi at 0

> +		reg = <0>;
> +		bus-width = <4>;
> +		compatible = "microchip,wilc3000", "microchip,wilc1000";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_wilc_default>;
> +		irq-gpios = <&pioA PIN_PB25 GPIO_ACTIVE_LOW>;
> +		clocks = <&pmc PMC_TYPE_SYSTEM 9>;
> +		clock-names = "rtc";
> +		assigned-clocks = <&pmc PMC_TYPE_SYSTEM 9>;
> +		assigned-clock-rates = <32768>;
> +		status = "okay";

Again, that's the default so drop.

Did you run validation (make dtbs_check) on your changes because I see 
multiple problems.

Rob


From robh at kernel.org  Tue Aug 24 05:24:05 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 07:24:05 -0500
Subject: [PATCH v3 1/4] dt-bindings: pwrseq-sd8787: add binding for
 wilc1000
In-Reply-To: <20210820092803.78523-2-claudiu.beznea@microchip.com>
References: <20210820092803.78523-1-claudiu.beznea@microchip.com>
 <20210820092803.78523-2-claudiu.beznea@microchip.com>
Message-ID: <YSTk5cbpne4QPazI@robh.at.kernel.org>

On Fri, 20 Aug 2021 12:28:00 +0300, Claudiu Beznea wrote:
> Add binding for wilc1000 devices.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 

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


From geert+renesas at glider.be  Tue Aug 24 05:27:41 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue, 24 Aug 2021 14:27:41 +0200
Subject: [PATCH] firmware: qcom_scm: QCOM_SCM should depend on ARCH_QCOM
Message-ID: <5cda77085c07dc2e8d2195507b287457cb2f09e9.1629807831.git.geert+renesas@glider.be>

The Qualcomm Secure Channel Manager (SCM) is only present on Qualcomm
SoCs.  All drivers using it select QCOM_SCM, and depend on ARCH_QCOM.
Until recently, QCOM_SCM was an invisible symbol, but this was changed
by adding loadable module support, exposing it to all ARM and ARM64
users.  Hence add a dependency on ARCH_QCOM, to prevent asking the user
about this driver when configuring a kernel without Qualcomm SoC
support.

While at it, drop the dependency on ARM || ARM64, as that is implied by
HAVE_ARM_SMCCC.

Fixes: b42000e4b8741bf6 ("firmware: qcom_scm: Allow qcom_scm driver to be loadable as a permenent module")
Fixes: 2954a6f12f250890 ("firmware: qcom-scm: Fix QCOM_SCM configuration")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 drivers/firmware/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 220a58cf0a441ca2..0bebd5a62a9f4d66 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -204,7 +204,7 @@ config INTEL_STRATIX10_RSU
 
 config QCOM_SCM
 	tristate "Qcom SCM driver"
-	depends on ARM || ARM64
+	depends on ARCH_QCOM || COMPILE_TEST
 	depends on HAVE_ARM_SMCCC
 	select RESET_CONTROLLER
 
-- 
2.25.1



From robh at kernel.org  Tue Aug 24 05:28:36 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 07:28:36 -0500
Subject: [PATCH v3 1/4] dt-bindings: perf: marvell: cn10k ddr performance
 monitor
In-Reply-To: <20210823065121.19494-2-bbhushan2@marvell.com>
References: <20210823065121.19494-1-bbhushan2@marvell.com>
 <20210823065121.19494-2-bbhushan2@marvell.com>
Message-ID: <YSTl9PQpwP9OiCbY@robh.at.kernel.org>

On Mon, 23 Aug 2021 12:21:18 +0530, Bharat Bhushan wrote:
> Add binding documentation for the Marvell CN10k DDR
> performance monitor unit.
> 
> Signed-off-by: Bharat Bhushan <bbhushan2 at marvell.com>
> ---
> v2->v3:
>  - dt-binding, ddrcpmu at 1 -> pmu at 87e1c0000000
> 
> v1->v2:
>  - DT binding changed to new DT Schema
> 
>  .../bindings/perf/marvell-cn10k-ddr.yaml      | 37 +++++++++++++++++++
>  1 file changed, 37 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn10k-ddr.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From festevam at gmail.com  Tue Aug 24 05:28:36 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 24 Aug 2021 09:28:36 -0300
Subject: [PATCH] clk: imx8mn: Add M7 core clock
In-Reply-To: <20210819202036.2084782-1-marex@denx.de>
References: <20210819202036.2084782-1-marex@denx.de>
Message-ID: <CAOMZO5DsfdBxZLWpLRaBXF5KwWY5JZUx9PJ7PGGNa+VfucHzDQ@mail.gmail.com>

Hi Marek,

On Thu, Aug 19, 2021 at 5:20 PM Marek Vasut <marex at denx.de> wrote:
>
> Add missing M7 core clock entry to the iMX8MN clock driver.
>
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Abel Vesa <abel.vesa at nxp.com>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Peng Fan <peng.fan at nxp.com>
> Cc: Shawn Guo <shawnguo at kernel.org>

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From benjamin.gaignard at collabora.com  Tue Aug 24 05:35:32 2021
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue, 24 Aug 2021 14:35:32 +0200
Subject: [PATCH] media: hantro: Add support of compressed reference buffers
In-Reply-To: <CAAEAJfCxhe8EubESc4HnO63JnOqVCRTNU62Qrm8wX+Rsc_tSUg@mail.gmail.com>
References: <20210823162916.824336-1-benjamin.gaignard@collabora.com>
 <CAAEAJfCxhe8EubESc4HnO63JnOqVCRTNU62Qrm8wX+Rsc_tSUg@mail.gmail.com>
Message-ID: <541e9ace-3b54-b46d-30ef-c01afc84fc41@collabora.com>


Le 24/08/2021 ? 13:22, Ezequiel Garcia a ?crit?:
> Hi Benjamin,
>
> On Mon, 23 Aug 2021 at 13:29, Benjamin Gaignard
> <benjamin.gaignard at collabora.com> wrote:
>> Reference frame compression is a feature added in G2 decoder to compress
>> frame buffers so that the bandwidth of storing/loading reference frames
>> can be reduced, especially when the resolution of decoded stream is of
>> high definition.
>>
>> Compressed help to increase the performance of the whole stack, it could
>> be up to 50 fps (against 45 fps) on IMX8MQ.
>> The impact of compressed frames is confirmed when using perf to monitor
>> the number of memory accesses with or without compression feature.
>> The following command
>> perf stat -a -e imx8_ddr0/cycles/,imx8_ddr0/read-cycles/,imx8_ddr0/write-cycles/ gst-launch-1.0 filesrc location=Jockey_3840x2160_120fps_420_8bit_HEVC_RAW.hevc ! queue ! h265parse ! v4l2slh265dec ! fakesink
>>
>> give us these results
>> without compression feature:
>>   Performance counter stats for 'system wide':
>>
>>         14965816743      imx8_ddr0/cycles/
>>           889197312      imx8_ddr0/read-cycles/
>>          1819348862      imx8_ddr0/write-cycles/
>>
>>        18.707373001 seconds time elapsed
>>
>> with compression feature:
>> Performance counter stats for 'system wide':
>>
>>         13750218243      imx8_ddr0/cycles/
>>           402428744      imx8_ddr0/read-cycles/
>>          1255676693      imx8_ddr0/write-cycles/
>>
>>        17.188320061 seconds time elapsed
>>
>> As expected the number of read/write cycles are really lower when compression
>> is used.
>>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
>> ---
>>   .../staging/media/hantro/hantro_g2_hevc_dec.c | 31 ++++++++++++--
>>   drivers/staging/media/hantro/hantro_g2_regs.h |  4 ++
>>   drivers/staging/media/hantro/hantro_hevc.c    | 41 ++++++++++++++++++-
>>   drivers/staging/media/hantro/hantro_hw.h      |  2 +
>>   4 files changed, 74 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>> index 340efb57fd18..da90acd922f7 100644
>> --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>> +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>> @@ -366,10 +366,12 @@ static int set_ref(struct hantro_ctx *ctx)
>>          const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps;
>>          const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
>>          const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
>> -       dma_addr_t luma_addr, chroma_addr, mv_addr = 0;
>> +       dma_addr_t luma_addr, chroma_addr, mv_addr, compress_luma_addr, compress_chroma_addr = 0;
>>          struct hantro_dev *vpu = ctx->dev;
>>          size_t cr_offset = hantro_hevc_chroma_offset(sps);
>>          size_t mv_offset = hantro_hevc_motion_vectors_offset(sps);
>> +       size_t compress_luma_offset = hantro_hevc_luma_compress_offset(sps);
>> +       size_t compress_chroma_offset = hantro_hevc_chroma_compress_offset(sps);
>>          u32 max_ref_frames;
>>          u16 dpb_longterm_e;
>>          static const struct hantro_reg cur_poc[] = {
>> @@ -442,15 +444,28 @@ static int set_ref(struct hantro_ctx *ctx)
>>                  if (!luma_addr)
>>                          return -ENOMEM;
>>
>> +               /*
>> +                * An allocated frame stores Y and UV planes, motion vectors and
>> +                * compressed Y and UV planes. Compute all these offsets given
>> +                * the frame resolution and the pixel format.
>> +                */
> The patch looks good, but I feel we still need to answer some questions
> before it can be merged.
>
> * Is this a G2 feature? If so, can it be used on VP9?

It isn't tagged as HEVC feature in the hardware spec so I guess it could
be used for VP9 too.

>
> * Enabling compression needs more memory. You are proposing
> to allocate frames and compressed frames contiguously,
> but so we need to measure the impact of that. Perhaps separate
> buffers will be better to avoid CMA pressure? Perhaps a given
> user will want to turn this off to reduce memory usage?

I could add a module parameter to turn on/off this feature but the among
of additional memory used is very limited compare to frame size.
For example for a 3840x2160 video it adds 68KB while the frame itself is around 12150KB.

>
> More importantly, I'm wary of adding HEVC features
> without being able to test anything.
>
> Can you work with NXP maintainers to get the GPC/BLK-CTRL [1] sorted out?

Yes, I have already give a try:
https://lkml.org/lkml/2021/7/7/836

Benjamin

>
> Then, we have the issue of missing mainlined userspace as well,
> but I suppose that's well underway :-)
>
> [1] https://www.spinics.net/lists/arm-kernel/msg913881.html
>
> Cheers,
> Eze
>
>>                  chroma_addr = luma_addr + cr_offset;
>>                  mv_addr = luma_addr + mv_offset;
>> +               compress_luma_addr = luma_addr + compress_luma_offset;
>> +               compress_chroma_addr = luma_addr + compress_chroma_offset;
>>
>>                  if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>>                          dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
>>
>> +               /*
>> +                * For each reference frame Y, UV, motion vector and
>> +                * compressed Y, UV buffers addresses must be set.
>> +                */
>>                  hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr);
>>                  hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr);
>>                  hantro_write_addr(vpu, G2_REG_DMV_REF(i), mv_addr);
>> +               hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), compress_luma_addr);
>> +               hantro_write_addr(vpu, G2_COMP_CHR_REF(i), compress_chroma_addr);
>>          }
>>
>>          luma_addr = hantro_hevc_get_ref_buf(ctx, decode_params->pic_order_cnt_val);
>> @@ -459,7 +474,12 @@ static int set_ref(struct hantro_ctx *ctx)
>>
>>          chroma_addr = luma_addr + cr_offset;
>>          mv_addr = luma_addr + mv_offset;
>> +       compress_luma_addr = luma_addr + compress_luma_offset;
>> +       compress_chroma_addr = luma_addr + compress_chroma_offset;
>>
>> +       /* The next decoded frame as to be put as the last reference frame entry */
>> +       hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), compress_luma_addr);
>> +       hantro_write_addr(vpu, G2_COMP_CHR_REF(i), compress_chroma_addr);
>>          hantro_write_addr(vpu, G2_REG_ADDR_REF(i), luma_addr);
>>          hantro_write_addr(vpu, G2_REG_CHR_REF(i), chroma_addr);
>>          hantro_write_addr(vpu, G2_REG_DMV_REF(i++), mv_addr);
>> @@ -467,13 +487,18 @@ static int set_ref(struct hantro_ctx *ctx)
>>          hantro_write_addr(vpu, G2_ADDR_DST, luma_addr);
>>          hantro_write_addr(vpu, G2_ADDR_DST_CHR, chroma_addr);
>>          hantro_write_addr(vpu, G2_ADDR_DST_MV, mv_addr);
>> +       hantro_write_addr(vpu, G2_COMP_ADDR_DST, compress_luma_addr);
>> +       hantro_write_addr(vpu, G2_COMP_CHR, compress_chroma_addr);
>>
>>          hantro_hevc_ref_remove_unused(ctx);
>>
>> +       /* Unused reference frames entries most be cleared */
>>          for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
>>                  hantro_write_addr(vpu, G2_REG_ADDR_REF(i), 0);
>>                  hantro_write_addr(vpu, G2_REG_CHR_REF(i), 0);
>>                  hantro_write_addr(vpu, G2_REG_DMV_REF(i), 0);
>> +               hantro_write_addr(vpu, G2_COMP_ADDR_REF(i), 0);
>> +               hantro_write_addr(vpu, G2_COMP_CHR_REF(i), 0);
>>          }
>>
>>          hantro_reg_write(vpu, &g2_refer_lterm_e, dpb_longterm_e);
>> @@ -564,8 +589,8 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx)
>>          /* Don't disable output */
>>          hantro_reg_write(vpu, &g2_out_dis, 0);
>>
>> -       /* Don't compress buffers */
>> -       hantro_reg_write(vpu, &g2_ref_compress_bypass, 1);
>> +       /* Compress buffers */
>> +       hantro_reg_write(vpu, &g2_ref_compress_bypass, 0);
>>
>>          /* use NV12 as output format */
>>          hantro_reg_write(vpu, &g2_out_rs_e, 1);
>> diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h
>> index bb22fa921914..2a23e8657db1 100644
>> --- a/drivers/staging/media/hantro/hantro_g2_regs.h
>> +++ b/drivers/staging/media/hantro/hantro_g2_regs.h
>> @@ -191,6 +191,10 @@
>>   #define G2_TILE_FILTER         (G2_SWREG(179))
>>   #define G2_TILE_SAO            (G2_SWREG(181))
>>   #define G2_TILE_BSD            (G2_SWREG(183))
>> +#define G2_COMP_ADDR_DST       (G2_SWREG(190))
>> +#define G2_COMP_ADDR_REF(i)    (G2_SWREG(192) + ((i) * 0x8))
>> +#define G2_COMP_CHR            (G2_SWREG(224))
>> +#define G2_COMP_CHR_REF(i)     (G2_SWREG(226) + ((i) * 0x8))
>>
>>   #define g2_strm_buffer_len     G2_DEC_REG(258, 0, 0xffffffff)
>>   #define g2_strm_start_offset   G2_DEC_REG(259, 0, 0xffffffff)
>> diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
>> index 5347f5a41c2a..78e5ceda520c 100644
>> --- a/drivers/staging/media/hantro/hantro_hevc.c
>> +++ b/drivers/staging/media/hantro/hantro_hevc.c
>> @@ -27,6 +27,13 @@
>>
>>   #define G2_ALIGN               16
>>
>> +#define CBS_SIZE       16      /* compression table size in bytes */
>> +#define CBS_LUMA       8       /* luminance CBS is composed of 1 8x8 coded block */
>> +#define CBS_CHROMA_W   (8 * 2) /* chrominance CBS is composed of two 8x4 coded
>> +                                * blocks, with Cb CB first then Cr CB following
>> +                                */
>> +#define CBS_CHROMA_H   4
>> +
>>   size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps)
>>   {
>>          int bytes_per_pixel = sps->bit_depth_luma_minus8 == 0 ? 1 : 2;
>> @@ -61,12 +68,44 @@ static size_t hantro_hevc_mv_size(const struct v4l2_ctrl_hevc_sps *sps)
>>          return mv_size;
>>   }
>>
>> +size_t hantro_hevc_luma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps)
>> +{
>> +       return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps);
>> +}
>> +
>> +static size_t hantro_hevc_luma_compress_size(const struct v4l2_ctrl_hevc_sps *sps)
>> +{
>> +       u32 pic_width_in_cbsy =
>> +               round_up((sps->pic_width_in_luma_samples + CBS_LUMA - 1) / CBS_LUMA, CBS_SIZE);
>> +       u32 pic_height_in_cbsy = (sps->pic_height_in_luma_samples + CBS_LUMA - 1) / CBS_LUMA;
>> +
>> +       return round_up(pic_width_in_cbsy * pic_height_in_cbsy, CBS_SIZE);
>> +}
>> +
>> +size_t hantro_hevc_chroma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps)
>> +{
>> +       return hantro_hevc_luma_compress_offset(sps) + hantro_hevc_luma_compress_size(sps);
>> +}
>> +
>> +static size_t hantro_hevc_chroma_compress_size(const struct v4l2_ctrl_hevc_sps *sps)
>> +{
>> +       u32 pic_width_in_cbsc =
>> +               round_up((sps->pic_width_in_luma_samples + CBS_CHROMA_W - 1)
>> +                        / CBS_CHROMA_W, CBS_SIZE);
>> +       u32 pic_height_in_cbsc = (sps->pic_height_in_luma_samples / 2 + CBS_CHROMA_H - 1)
>> +                                / CBS_CHROMA_H;
>> +
>> +       return round_up(pic_width_in_cbsc * pic_height_in_cbsc, CBS_SIZE);
>> +}
>> +
>>   static size_t hantro_hevc_ref_size(struct hantro_ctx *ctx)
>>   {
>>          const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
>>          const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
>>
>> -       return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps);
>> +       return hantro_hevc_motion_vectors_offset(sps) + hantro_hevc_mv_size(sps) +
>> +              hantro_hevc_luma_compress_size(sps) +
>> +              hantro_hevc_chroma_compress_size(sps);
>>   }
>>
>>   static void hantro_hevc_ref_free(struct hantro_ctx *ctx)
>> diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
>> index df7b5e3a57b9..d5c002d0e765 100644
>> --- a/drivers/staging/media/hantro/hantro_hw.h
>> +++ b/drivers/staging/media/hantro/hantro_hw.h
>> @@ -255,6 +255,8 @@ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc);
>>   void hantro_hevc_ref_remove_unused(struct hantro_ctx *ctx);
>>   size_t hantro_hevc_chroma_offset(const struct v4l2_ctrl_hevc_sps *sps);
>>   size_t hantro_hevc_motion_vectors_offset(const struct v4l2_ctrl_hevc_sps *sps);
>> +size_t hantro_hevc_luma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps);
>> +size_t hantro_hevc_chroma_compress_offset(const struct v4l2_ctrl_hevc_sps *sps);
>>
>>   static inline size_t
>>   hantro_h264_mv_size(unsigned int width, unsigned int height)
>> --
>> 2.25.1
>>


From 21cnbao at gmail.com  Tue Aug 24 05:42:52 2021
From: 21cnbao at gmail.com (Barry Song)
Date: Wed, 25 Aug 2021 00:42:52 +1200
Subject: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210824121145.GD96738@C02TD0UTHF1T.local>
References: <20210818073336.59678-1-liuqi115@huawei.com>
 <20210818073336.59678-3-liuqi115@huawei.com>
 <20210824105001.GA96738@C02TD0UTHF1T.local>
 <CAGsJ_4wU3g5i4PPo+cw3ZyGyswnFp7p7vERaq_aUuhmCCyvqmg@mail.gmail.com>
 <20210824121145.GD96738@C02TD0UTHF1T.local>
Message-ID: <CAGsJ_4zD5E3hM4GU=d2LdhAueXMW0QWcKXyCfAORokbE6aG1OA@mail.gmail.com>

On Wed, Aug 25, 2021 at 12:11 AM Mark Rutland <mark.rutland at arm.com> wrote:
>
> On Tue, Aug 24, 2021 at 11:50:08PM +1200, Barry Song wrote:
> > On Tue, Aug 24, 2021 at 10:51 PM Mark Rutland <mark.rutland at arm.com> wrote:
> > >
> > > Hi,
> > >
> > > I have a bunch of comments below.
> > >
> > > At a high-level, I'm not all that keen on adding yet another set of
> > > trampolines, especially given we have constraints on how we can branch
> > > to them which render this not that useful in common configurations (e.g.
> > > where KASLR and module randomization is enabled).
> > >
> > > So importantly, do we actually need this? I don't think the sampel is
> > > that compelling since we can already use ftrace to measure function
> > > latencies.
> >
> > Hopefully I can help answer some general questions. for code details,
> > I'll still rely on liuqi.
> >
> > As far as I know, the functionality of ftrace is very limited. kprobe,
> > on the other hand, can do a lot of
> > things, for example, hooking some ebpf code.
> > Tons of userspace tools depend on kprobe, eg. ebpf/bcc which is widely
> > used nowadays:
> > https://github.com/iovisor/bcc
> >
> > Function latency is really a very small part of what kprobe can do.
>
> I appreciate that, but *functionally* we can already do the other bits
> with the existing kprobes code, so the question for this series is where
> the latency/overhead matters in practice.
>
> > kprobe can do much much more. For example, while doing disksnoop by
> > kprobe, we are easily collecting the request struct, and get the
> > layout of each IO request. without kprobe, we will probably need to
> > add tracepoints here and there in kernel code to achieve the same
> > goal.
> >
> > I believe Masami and kprobe maintainers can answer this question better than me.
> >
> > > If we do need this, I think we need to do some more substantial rework
> > > to address those branch range limitations. I know that we could permit
> > > arbitrary branching if we expand the ftrace-with-regs callsites to ~6
> > > instructions, but that interacts rather poorly with stacktracing and
> > > will make the kernel a bit bigger.
> >
> > This patch is probably the first step towards a faster kprobe on ARM64.
> > I assume PLT or some similar tech will help break the limitation next
> > step.
>
> I have ideas about how we can make that work (basically an inline PLT
> next to the function), but the implementation is *very* different, and
> my thinking is that either:
>
> * The latency/overhead is a real concern generally, and this needs to
>   work in the majority of cases (e.g. where KASLR and module
>   randomization are on). If so, I think we should implement the more
>   invasive but complete solution in one go rather than implementing
>   something we know we're going to have to throw away.

For an online scenario, I do think we should have a complete implementation
to make it more useful as we can't force users to use nokaslr. in this
thread V1:
https://lore.kernel.org/lkml/6a97dff6c33c4b84887223de2502bd3d at hisilicon.com/
I actually also posted some similar ideas with you regarding using PLT to break
the limitation.

>
> * The latency is not that much of a concern, or is only a concern ina
>   few niche cases. If so, it's not clear to me whether this is
>   worthwhile as-is.
>
> > > On Wed, Aug 18, 2021 at 03:33:36PM +0800, Qi Liu wrote:
> > > > This patch introduce optprobe for ARM64. In optprobe, probed
> > > > instruction is replaced by a branch instruction to detour
> > > > buffer. Detour buffer contains trampoline code and a call to
> > > > optimized_callback(). optimized_callback() calls opt_pre_handler()
> > > > to execute kprobe handler.
> > > >
> > > > Performance of optprobe on Hip08 platform is test using kprobe
> > > > example module[1] to analyze the latency of a kernel function,
> > > > and here is the result:
> > > >
> > > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> > > >
> > > > kprobe before optimized:
> > > > [280709.846380] do_empty returned 0 and took 1530 ns to execute
> > > > [280709.852057] do_empty returned 0 and took 550 ns to execute
> > > > [280709.857631] do_empty returned 0 and took 440 ns to execute
> > > > [280709.863215] do_empty returned 0 and took 380 ns to execute
> > > > [280709.868787] do_empty returned 0 and took 360 ns to execute
> > > > [280709.874362] do_empty returned 0 and took 340 ns to execute
> > > > [280709.879936] do_empty returned 0 and took 320 ns to execute
> > > > [280709.885505] do_empty returned 0 and took 300 ns to execute
> > > > [280709.891075] do_empty returned 0 and took 280 ns to execute
> > > > [280709.896646] do_empty returned 0 and took 290 ns to execute
> > > > [280709.902220] do_empty returned 0 and took 290 ns to execute
> > > > [280709.907807] do_empty returned 0 and took 290 ns to execute
> > > >
> > > > optprobe:
> > > > [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> > > > [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> > > > [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> > > > [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> > > > [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> > > > [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> > > > [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> > > > [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> > > > [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> > > > [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> > > > [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> > > > [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> > > > [ 2966.029158] do_empty returned 0 and took 70 ns to execute
> > >
> > > Do we have any examples of where this latency matters in practice?
> >
> > While doing performance analysis or debugging performance issues  in
> > lab, the big latency of the current kprobe
> > can significantly impact the real result.
> >
> > And it is particularly important when we want to do some online
> > diagnostics where machines are running on the cloud.
> > we need to minimally affect the real system while watching the system.
> >
> > For example, https://gitee.com/xiebaoyou/diagnosis_tools is an
> > open-source tool which is used by alibaba, it uses
> > kprobe a lot to detect various problems running on aloud.
>
> Ok. It would be good to mention something like this in the commit
> message. If it's possible to get an estimate of the overhead reduction,
> that would be great.

I believe liuqi's commit log has estimated the overhead reduction.
The below is exactly the overhead of kprobe before and after the patch.
not only does it decrease the overhead,  it also makes the
standard deviation more even.

i believe liuqi's estimation doesn't open cpufreq, if cpufreq is open,
un-optimized kprobe
latency can be much much bigger and have much much bigger stdev.

kprobe before optimized:
[280709.846380] do_empty returned 0 and took 1530 ns to execute
[280709.852057] do_empty returned 0 and took 550 ns to execute
[280709.857631] do_empty returned 0 and took 440 ns to execute
[280709.863215] do_empty returned 0 and took 380 ns to execute
[280709.868787] do_empty returned 0 and took 360 ns to execute
[280709.874362] do_empty returned 0 and took 340 ns to execute
[280709.879936] do_empty returned 0 and took 320 ns to execute
[280709.885505] do_empty returned 0 and took 300 ns to execute
[280709.891075] do_empty returned 0 and took 280 ns to execute
[280709.896646] do_empty returned 0 and took 290 ns to execute
[280709.902220] do_empty returned 0 and took 290 ns to execute
[280709.907807] do_empty returned 0 and took 290 ns to execute

optprobe:
[ 2965.964572] do_empty returned 0 and took 90 ns to execute
[ 2965.969952] do_empty returned 0 and took 80 ns to execute
[ 2965.975332] do_empty returned 0 and took 70 ns to execute
[ 2965.980714] do_empty returned 0 and took 60 ns to execute
[ 2965.986128] do_empty returned 0 and took 80 ns to execute
[ 2965.991507] do_empty returned 0 and took 70 ns to execute
[ 2965.996884] do_empty returned 0 and took 70 ns to execute
[ 2966.002262] do_empty returned 0 and took 80 ns to execute
[ 2966.007642] do_empty returned 0 and took 70 ns to execute
[ 2966.013020] do_empty returned 0 and took 70 ns to execute
[ 2966.018400] do_empty returned 0 and took 70 ns to execute
[ 2966.023779] do_empty returned 0 and took 70 ns to execute
[ 2966.029158] do_empty returned 0 and took 70 ns to execute

>
> > > > Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> > > >
> > > > Note:
> > > > To guarantee the offset between probe point and kprobe pre_handler
> > > > is smaller than 128MiB, users should set
> > > > CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
> > > > optprobe will not work and fall back to normal kprobe.
> > >
> > > Hmm... I don't think that's something we want to recommend, and
> > > certainly distros *should* use KASLR and
> > > CONFIG_RANDOMIZE_MODULE_REGION_FULL.
> > >
> > > What happens with defconfig? Do we always get the fallback behaviour?
> >
> > For this stage, with no_kaslr cmdline for defconfig, we are always
> > going to optprobe. otherwise, it always goes to the fallback
> > behaviour. So for this stage, it is probably only useful in lab while
> > people are debugging problems. but this is still a widely useful
> > scenario.
>
> If it's only going to be used for lab debugging, why is the existing
> kprobes logic not sufficient?

My understanding is the lab needs to emulate the real scenario while
it is not a real
online system. The huge latency of the existing un-optimized kprobe
make all the data
from ebpf/bcc tools seriously distorted.


>
> Thanks,
> Mark.

Thanks
barry


From broonie at kernel.org  Tue Aug 24 05:48:39 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 24 Aug 2021 13:48:39 +0100
Subject: [PATCH] arm64/sve: Better handle failure to allocate SVE
 register storage
In-Reply-To: <20210824103213.GA623@arm.com>
References: <20210817171330.25847-1-broonie@kernel.org>
 <20210824103213.GA623@arm.com>
Message-ID: <20210824124839.GA4393@sirena.org.uk>

On Tue, Aug 24, 2021 at 11:32:14AM +0100, Catalin Marinas wrote:
> On Tue, Aug 17, 2021 at 06:13:30PM +0100, Mark Brown wrote:

> > -	BUG_ON(!task->thread.sve_state);

> I think we should keep a WARN_ON_ONCE here in case one wonders why the
> app was suddenly killed.

OOM is very noisy already, the general advice is not to issue any
extra diagnostics on allocation failures as there's already going to be
at the very least a backtrace from the allocation failure site.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210824/e6fd78a4/attachment.sig>

From ardb at kernel.org  Tue Aug 24 05:56:22 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 24 Aug 2021 14:56:22 +0200
Subject: [RFC PATCH] arm64: mm: limit linear region to 51 bits for KVM in
 nVHE mode
In-Reply-To: <20210824105920.GB22752@willie-the-truck>
References: <20210810161244.84231-1-ardb@kernel.org>
 <20210824105920.GB22752@willie-the-truck>
Message-ID: <CAMj1kXHKvUng_z5Gfd0bsFgbnpVPA-JjPLCRTa=87yVa4j7kHA@mail.gmail.com>

On Tue, 24 Aug 2021 at 12:59, Will Deacon <will at kernel.org> wrote:
>
> On Tue, Aug 10, 2021 at 06:12:44PM +0200, Ard Biesheuvel wrote:
> > KVM in nVHE mode divides up its VA space into two equal halves, and
> > picks the half that does not conflict with the HYP ID map to map its
> > linear region. This worked fine when the kernel's linear map itself was
> > guaranteed to cover precisely as many bits of VA space, but this was
> > changed by commit f4693c2716b35d08 ("arm64: mm: extend linear region for
> > 52-bit VA configurations").
> >
> > The result is that, depending on the placement of the ID map, kernel-VA
> > to hyp-VA translations may produce addresses that either conflict with
> > other HYP mappings (including the ID map itself) or generate addresses
> > outside of the 52-bit addressable range, neither of which is likely to
> > lead to anything useful.
> >
> > Given that 52-bit capable cores are guaranteed to implement VHE, this
> > only affects configurations such as pKVM where we opt into non-VHE mode
> > even if the hardware is VHE capable. So just for these configurations,
> > let's limit the kernel linear map to 51 bits and work around the
> > problem.
> >
> > Fixes:f4693c2716b35d08 ("arm64: mm: extend linear region for 52-bit VA configurations")
> > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> > ---
> > NOTE: build tested only
> >
> >  arch/arm64/mm/init.c | 16 +++++++++++++++-
> >  1 file changed, 15 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index 8490ed2917ff..542dad13e2fc 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -282,7 +282,21 @@ static void __init fdt_enforce_memory_region(void)
> >
> >  void __init arm64_memblock_init(void)
> >  {
> > -     const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > +     s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > +
> > +     /*
> > +      * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
> > +      * be limited in their ability to support a linear map that exceeds 51
> > +      * bits of VA space, depending on the placement of the ID map. Given
> > +      * that the placement of the ID map may be randomized, let's simply
> > +      * limit the kernel's linear map to 51 bits as well if we detect this
> > +      * configuration.
> > +      */
> > +     if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 &&
> > +         !is_kernel_in_hyp_mode()) {
> > +             pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n");
> > +             linear_region_size = BIT(51);
> > +     }
>
> Slight nit, but to avoid having to think about PAGE_END I think this would
> be a little clearer as:
>
>         if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode())
>                 linear_region_size = min_t(u64, linear_region_size, BIT(51));
>

Fair enough.


From robh at kernel.org  Tue Aug 24 06:01:58 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 08:01:58 -0500
Subject: [PATCH v2 1/4] dt-bindings: devfreq: event: convert Samsung
 Exynos NoCP to dtschema
In-Reply-To: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
References: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YSTtxgAV1W1Yf8wZ@robh.at.kernel.org>

On Fri, 20 Aug 2021 17:03:50 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos NoC Probe bindings to DT schema format using
> json-schema.
> 
> New bindings contain copied description from previous bindings document,
> therefore the license is set as GPL-2.0-only.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> 
> ---
> 
> Changes since v1:
> 1. New patch
> ---
>  .../bindings/devfreq/event/exynos-nocp.txt    | 26 ----------
>  .../devfreq/event/samsung,exynos-nocp.yaml    | 48 +++++++++++++++++++
>  2 files changed, 48 insertions(+), 26 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/devfreq/event/exynos-nocp.txt
>  create mode 100644 Documentation/devicetree/bindings/devfreq/event/samsung,exynos-nocp.yaml
> 

Applied, thanks!


From robh at kernel.org  Tue Aug 24 06:02:17 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 08:02:17 -0500
Subject: [PATCH v2 2/4] dt-bindings: devfreq: event: convert Samsung
 Exynos PPMU to dtschema
In-Reply-To: <20210820150353.161161-2-krzysztof.kozlowski@canonical.com>
References: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
 <20210820150353.161161-2-krzysztof.kozlowski@canonical.com>
Message-ID: <YSTt2d5uIfXhjuQd@robh.at.kernel.org>

On Fri, 20 Aug 2021 17:03:51 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos PPMU bindings to DT schema format using
> json-schema.  The example is quite different due to the nature of
> dtschema examples parsing (no overriding via-label allowed).
> 
> New bindings contain copied description from previous bindings document,
> therefore the license is set as GPL-2.0-only.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> 
> ---
> 
> Changes since v1:
> 1. New patch
> ---
>  .../bindings/devfreq/event/exynos-ppmu.txt    | 169 -----------------
>  .../devfreq/event/samsung,exynos-ppmu.yaml    | 174 ++++++++++++++++++
>  2 files changed, 174 insertions(+), 169 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/devfreq/event/exynos-ppmu.txt
>  create mode 100644 Documentation/devicetree/bindings/devfreq/event/samsung,exynos-ppmu.yaml
> 

Applied, thanks!


From robh at kernel.org  Tue Aug 24 06:02:37 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 08:02:37 -0500
Subject: [PATCH v2 3/4] dt-bindings: memory: convert Samsung Exynos DMC
 to dtschema
In-Reply-To: <20210820150353.161161-3-krzysztof.kozlowski@canonical.com>
References: <20210820150353.161161-1-krzysztof.kozlowski@canonical.com>
 <20210820150353.161161-3-krzysztof.kozlowski@canonical.com>
Message-ID: <YSTt7Q7Gfv/T9PeO@robh.at.kernel.org>

On Fri, 20 Aug 2021 17:03:52 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos5422 SoC frequency and voltage scaling for
> Dynamic Memory Controller to DT schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Acked-by: Lukasz Luba <lukasz.luba at arm.com>
> 
> ---
> 
> Changes since v1:
> 1. Corrent PPMU event node name (remove underscore).
> 2. Add Ack.
> ---
>  .../memory-controllers/exynos5422-dmc.txt     |  84 -----------
>  .../samsung,exynos5422-dmc.yaml               | 137 ++++++++++++++++++
>  MAINTAINERS                                   |   2 +-
>  3 files changed, 138 insertions(+), 85 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/exynos5422-dmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml
> 

Applied, thanks!


From abel.vesa at nxp.com  Tue Aug 24 06:05:54 2021
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 24 Aug 2021 16:05:54 +0300
Subject: [PATCH] clk: imx8mn: Add M7 core clock
In-Reply-To: <20210819202036.2084782-1-marex@denx.de>
References: <20210819202036.2084782-1-marex@denx.de>
Message-ID: <YSTusuQJlTKtYkAQ@ryzen>

On 21-08-19 22:20:36, Marek Vasut wrote:
> Add missing M7 core clock entry to the iMX8MN clock driver.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Abel Vesa <abel.vesa at nxp.com>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Peng Fan <peng.fan at nxp.com>
> Cc: Shawn Guo <shawnguo at kernel.org>

Applied, thanks.

> ---
>  drivers/clk/imx/clk-imx8mn.c             | 5 +++++
>  include/dt-bindings/clock/imx8mn-clock.h | 4 +++-
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
> index 212708e9388e2..9dba4eb643ab9 100644
> --- a/drivers/clk/imx/clk-imx8mn.c
> +++ b/drivers/clk/imx/clk-imx8mn.c
> @@ -40,6 +40,9 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl
>  
>  static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
>  
> +static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out",
> +				       "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
> +
>  static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
>  						    "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
>  						    "video_pll1_out", "audio_pll2_out", };
> @@ -421,6 +424,8 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
>  	hws[IMX8MN_CLK_A53_SRC] = hws[IMX8MN_CLK_A53_DIV];
>  	hws[IMX8MN_CLK_A53_CG] = hws[IMX8MN_CLK_A53_DIV];
>  
> +	hws[IMX8MN_CLK_M7_CORE] = imx8m_clk_hw_composite_core("arm_m7_core", imx8mn_m7_sels, base + 0x8080);
> +
>  	hws[IMX8MN_CLK_GPU_CORE] = imx8m_clk_hw_composite_core("gpu_core", imx8mn_gpu_core_sels, base + 0x8180);
>  	hws[IMX8MN_CLK_GPU_SHADER] = imx8m_clk_hw_composite_core("gpu_shader", imx8mn_gpu_shader_sels, base + 0x8200);
>  
> diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
> index d24b627cb2e71..01e8bab1d767a 100644
> --- a/include/dt-bindings/clock/imx8mn-clock.h
> +++ b/include/dt-bindings/clock/imx8mn-clock.h
> @@ -241,6 +241,8 @@
>  #define IMX8MN_CLK_CLKOUT2_DIV			219
>  #define IMX8MN_CLK_CLKOUT2			220
>  
> -#define IMX8MN_CLK_END				221
> +#define IMX8MN_CLK_M7_CORE			221
> +
> +#define IMX8MN_CLK_END				222
>  
>  #endif
> -- 
> 2.30.2
> 


From mark.rutland at arm.com  Tue Aug 24 06:13:44 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 14:13:44 +0100
Subject: [RFC PATCH v8 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210812190603.25326-2-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-2-madvenka@linux.microsoft.com>
Message-ID: <20210824131344.GE96738@C02TD0UTHF1T.local>

On Thu, Aug 12, 2021 at 02:06:00PM -0500, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Currently, there are multiple functions in ARM64 code that walk the
> stack using start_backtrace() and unwind_frame(). Convert all of
> them to use arch_stack_walk(). This makes maintenance easier.

It would be good to split this into a series of patches as Mark Brown
suggested in v7.

> Here is the list of functions:
> 
> 	perf_callchain_kernel()
> 	get_wchan()
> 	return_address()
> 	dump_backtrace()
> 	profile_pc()

Note that arch_stack_walk() depends on CONFIG_STACKTRACE (which is not in
defconfig), so we'll need to reorganise things such that it's always defined,
or factor out the core of that function and add a wrapper such that we
can always use it.

> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
> ---
>  arch/arm64/include/asm/stacktrace.h |  3 ---
>  arch/arm64/kernel/perf_callchain.c  |  5 +---
>  arch/arm64/kernel/process.c         | 39 ++++++++++++++++++-----------
>  arch/arm64/kernel/return_address.c  |  6 +----
>  arch/arm64/kernel/stacktrace.c      | 38 +++-------------------------
>  arch/arm64/kernel/time.c            | 22 +++++++++-------
>  6 files changed, 43 insertions(+), 70 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
> index 8aebc00c1718..e43dea1c6b41 100644
> --- a/arch/arm64/include/asm/stacktrace.h
> +++ b/arch/arm64/include/asm/stacktrace.h
> @@ -61,9 +61,6 @@ struct stackframe {
>  #endif
>  };
>  
> -extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
> -extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
> -			    bool (*fn)(void *, unsigned long), void *data);
>  extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>  			   const char *loglvl);
>  
> diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
> index 4a72c2727309..2f289013c9c9 100644
> --- a/arch/arm64/kernel/perf_callchain.c
> +++ b/arch/arm64/kernel/perf_callchain.c
> @@ -147,15 +147,12 @@ static bool callchain_trace(void *data, unsigned long pc)
>  void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
>  			   struct pt_regs *regs)
>  {
> -	struct stackframe frame;
> -
>  	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
>  		/* We don't support guest os callchain now */
>  		return;
>  	}
>  
> -	start_backtrace(&frame, regs->regs[29], regs->pc);
> -	walk_stackframe(current, &frame, callchain_trace, entry);
> +	arch_stack_walk(callchain_trace, entry, current, regs);
>  }

We can also update callchain_trace take the return value of
perf_callchain_store into acount, e.g.

| static bool callchain_trace(void *data, unsigned long pc) 
| {
| 	struct perf_callchain_entry_ctx *entry = data;
| 	return perf_callchain_store(entry, pc) == 0;
| }

>  
>  unsigned long perf_instruction_pointer(struct pt_regs *regs)
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index c8989b999250..52c12fd26407 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -544,11 +544,28 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
>  	return last;
>  }
>  
> +struct wchan_info {
> +	unsigned long	pc;
> +	int		count;
> +};
> +
> +static bool get_wchan_cb(void *arg, unsigned long pc)
> +{
> +	struct wchan_info *wchan_info = arg;
> +
> +	if (!in_sched_functions(pc)) {
> +		wchan_info->pc = pc;
> +		return false;
> +	}
> +	wchan_info->count--;
> +	return !!wchan_info->count;
> +}

This will terminate one entry earlier than the old logic since we used
to use a post-increment (testing the prior value), and now we're
effectively using a pre-decrement (testing the new value).

I don't think that matters all that much in practice, but it might be
best to keep the original logic, e.g. initialize `count` to 0 and here
do:

	return wchan_info->count++ < 16;

> +
>  unsigned long get_wchan(struct task_struct *p)
>  {
> -	struct stackframe frame;
> -	unsigned long stack_page, ret = 0;
> -	int count = 0;
> +	unsigned long stack_page;
> +	struct wchan_info wchan_info;
> +
>  	if (!p || p == current || task_is_running(p))
>  		return 0;
>  
> @@ -556,20 +573,12 @@ unsigned long get_wchan(struct task_struct *p)
>  	if (!stack_page)
>  		return 0;
>  
> -	start_backtrace(&frame, thread_saved_fp(p), thread_saved_pc(p));
> +	wchan_info.pc = 0;
> +	wchan_info.count = 16;
> +	arch_stack_walk(get_wchan_cb, &wchan_info, p, NULL);
>  
> -	do {
> -		if (unwind_frame(p, &frame))
> -			goto out;
> -		if (!in_sched_functions(frame.pc)) {
> -			ret = frame.pc;
> -			goto out;
> -		}
> -	} while (count++ < 16);
> -
> -out:
>  	put_task_stack(p);
> -	return ret;
> +	return wchan_info.pc;
>  }

Other than the comment above, this looks good to me.

>  unsigned long arch_align_stack(unsigned long sp)
> diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c
> index a6d18755652f..92a0f4d434e4 100644
> --- a/arch/arm64/kernel/return_address.c
> +++ b/arch/arm64/kernel/return_address.c
> @@ -35,15 +35,11 @@ NOKPROBE_SYMBOL(save_return_addr);
>  void *return_address(unsigned int level)
>  {
>  	struct return_address_data data;
> -	struct stackframe frame;
>  
>  	data.level = level + 2;
>  	data.addr = NULL;
>  
> -	start_backtrace(&frame,
> -			(unsigned long)__builtin_frame_address(0),
> -			(unsigned long)return_address);
> -	walk_stackframe(current, &frame, save_return_addr, &data);
> +	arch_stack_walk(save_return_addr, &data, current, NULL);
>  
>  	if (!data.level)
>  		return data.addr;

Nor that arch_stack_walk() will start with it's caller, so
return_address() will be included in the trace where it wasn't
previously, which implies we need to skip an additional level.

That said, I'm not entirely sure why we need to skip 2 levels today; it
might be worth checking that's correct.

We should also mark return_address() as noinline to avoid surprises with
LTO.

> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index 8982a2b78acf..1800310f92be 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -151,23 +151,21 @@ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
>  }
>  NOKPROBE_SYMBOL(walk_stackframe);
>  
> -static void dump_backtrace_entry(unsigned long where, const char *loglvl)
> +static bool dump_backtrace_entry(void *arg, unsigned long where)
>  {
> +	char *loglvl = arg;
>  	printk("%s %pSb\n", loglvl, (void *)where);
> +	return true;
>  }
>  
>  void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>  		    const char *loglvl)
>  {
> -	struct stackframe frame;
> -	int skip = 0;
> -
>  	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
>  
>  	if (regs) {
>  		if (user_mode(regs))
>  			return;
> -		skip = 1;
>  	}

We can simplifiy this to:

	if (regs && user_mode(regs))
		return;

>  
>  	if (!tsk)
> @@ -176,36 +174,8 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>  	if (!try_get_task_stack(tsk))
>  		return;
>  
> -	if (tsk == current) {
> -		start_backtrace(&frame,
> -				(unsigned long)__builtin_frame_address(0),
> -				(unsigned long)dump_backtrace);
> -	} else {
> -		/*
> -		 * task blocked in __switch_to
> -		 */
> -		start_backtrace(&frame,
> -				thread_saved_fp(tsk),
> -				thread_saved_pc(tsk));
> -	}
> -
>  	printk("%sCall trace:\n", loglvl);
> -	do {
> -		/* skip until specified stack frame */
> -		if (!skip) {
> -			dump_backtrace_entry(frame.pc, loglvl);
> -		} else if (frame.fp == regs->regs[29]) {
> -			skip = 0;
> -			/*
> -			 * Mostly, this is the case where this function is
> -			 * called in panic/abort. As exception handler's
> -			 * stack frame does not contain the corresponding pc
> -			 * at which an exception has taken place, use regs->pc
> -			 * instead.
> -			 */
> -			dump_backtrace_entry(regs->pc, loglvl);
> -		}
> -	} while (!unwind_frame(tsk, &frame));
> +	arch_stack_walk(dump_backtrace_entry, (void *)loglvl, tsk, regs);

It turns out we currently need this skipping to get the balance the
ftrace call stack, and arch_stack_walk() doesn't currently do the right
thing when starting from regs. That balancing isn't quite right, and
will be wrong in some case when unwinding across exception boundaries;
we could implement HAVE_FUNCTION_GRAPH_RET_ADDR_PTR using the FP to
solve that.

>  
>  	put_task_stack(tsk);
>  }
> diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
> index eebbc8d7123e..671b3038a772 100644
> --- a/arch/arm64/kernel/time.c
> +++ b/arch/arm64/kernel/time.c
> @@ -32,22 +32,26 @@
>  #include <asm/stacktrace.h>
>  #include <asm/paravirt.h>
>  
> +static bool profile_pc_cb(void *arg, unsigned long pc)
> +{
> +	unsigned long *prof_pc = arg;
> +
> +	if (in_lock_functions(pc))
> +		return true;
> +	*prof_pc = pc;
> +	return false;
> +}
> +
>  unsigned long profile_pc(struct pt_regs *regs)
>  {
> -	struct stackframe frame;
> +	unsigned long prof_pc = 0;
>  
>  	if (!in_lock_functions(regs->pc))
>  		return regs->pc;
>  
> -	start_backtrace(&frame, regs->regs[29], regs->pc);
> -
> -	do {
> -		int ret = unwind_frame(NULL, &frame);
> -		if (ret < 0)
> -			return 0;
> -	} while (in_lock_functions(frame.pc));
> +	arch_stack_walk(profile_pc_cb, &prof_pc, current, regs);
>  
> -	return frame.pc;
> +	return prof_pc;
>  }
>  EXPORT_SYMBOL(profile_pc);

Mdoulo the problem above w.r.t. unwinding from regs, this looks good.

Thanks,
Mark.

>  
> -- 
> 2.25.1
> 


From ulf.hansson at linaro.org  Tue Aug 24 06:15:28 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 24 Aug 2021 15:15:28 +0200
Subject: [PATCH 1/1] mmc: mediatek: fixed clk contrl flow
In-Reply-To: <20210816073813.11715-1-Mason.Zhang@mediatek.com>
References: <20210816073813.11715-1-Mason.Zhang@mediatek.com>
Message-ID: <CAPDyKFpSOcX6End_L0mLRt61s0aS_zT19snM71j9bxgMi1oUuA@mail.gmail.com>

On Mon, 16 Aug 2021 at 09:39, Mason Zhang <Mason.Zhang at mediatek.com> wrote:
>
> this patch fixed clk contrl flow in set clk rate, no need close clk src,
> gate cg is enough, so no need call clk prepare/unprepare.

No, this isn't the way we should deploy clock support in drivers.

If the driver doesn't need to gate/ungate clocks from atomic context,
the proper thing is to use the slow path APIs, clk_prepare_enable()
and clk_disable_unprepare().

Kind regards
Uffe

>
> Signed-off-by: Mason Zhang <Mason.Zhang at mediatek.com>
> ---
>  drivers/mmc/host/mtk-sd.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 4dfc246c5f95..d9835b272c1f 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -895,9 +895,9 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
>          * So if want to only gate src_clk, need gate its parent(mux).
>          */
>         if (host->src_clk_cg)
> -               clk_disable_unprepare(host->src_clk_cg);
> +               clk_disable(host->src_clk_cg);
>         else
> -               clk_disable_unprepare(clk_get_parent(host->src_clk));
> +               clk_disable(clk_get_parent(host->src_clk));
>         if (host->dev_comp->clk_div_bits == 8)
>                 sdr_set_field(host->base + MSDC_CFG,
>                               MSDC_CFG_CKMOD | MSDC_CFG_CKDIV,
> @@ -907,9 +907,9 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
>                               MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA,
>                               (mode << 12) | div);
>         if (host->src_clk_cg)
> -               clk_prepare_enable(host->src_clk_cg);
> +               clk_enable(host->src_clk_cg);
>         else
> -               clk_prepare_enable(clk_get_parent(host->src_clk));
> +               clk_enable(clk_get_parent(host->src_clk));
>
>         while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
>                 cpu_relax();
> --
> 2.18.0
>


From alexandru.elisei at arm.com  Tue Aug 24 06:24:59 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 24 Aug 2021 14:24:59 +0100
Subject: [PATCH] arm64: Do not trap PMSNEVFR_EL1
Message-ID: <20210824132459.562923-1-alexandru.elisei@arm.com>

Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed
the fine grained trap registers to prevent unwanted register traps from
occuring. However, for the PMSNEVFR_EL1 register, the corresponding
HDFGRTR_EL2.nPMSNEVFR_EL1 field must be 1 to disable trapping. Set the
field to 1 if FEAT_SPEv1p2 is detected.

Fixes: 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot")
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
Based on v5.14-rc7. Also, we could write 1 << 62 to HDFGRTR_EL2 unconditionally
since the field is RAZ/WI if !FEAT_SPEv1p2. I don't have a strong preference for
either approaches, but I chose this implementation because it's clearer (even
though it's more verbose and it's one extra trap on NV).

Tested on the model, using boot-wrapper built from commit 5cd6238ec4ef
("aarch32: fix .globl replacement"). Without this patch, in NVHE mode, the model
freezes when I try to read PMSNEVFR_EL1. With this patch, the model doesn't hang
when I read the register, but it hangs when I write to it. I've gone throught
the pseudocode for reading and writing to PMSNEVFR_EL1 and from what I can tell
nothing should be trapping the accesses. On top of that, this is what I tried on
the model with this patch applied:

1. VHE mode, I can read and write to PMSNEVFR_EL1 without any issues, so the
hang is not caused by an incorrect EL3 configuration.

2. NVHE mode, I can read and write just fine to *PMSEVFR_EL1*, so the hang is
not caused by an EL2 trap that affects the rest of the profiling control
registers. I have tried printing the HDFGRTR_EL2 value in this situation using
semihosting, the value is what it is programmed by __init_el2_fgt (that is,
1 << 62).

At this point, I am inclined to think it's a model bug because reading works,
but writing causes a hang and that looks very suspicious to me. I'm going to
open a model bug internally and see what comes of it.

 arch/arm64/include/asm/el2_setup.h | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index b83fb24954b7..8a9adb2039fd 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -149,7 +149,16 @@
 	ubfx	x1, x1, #ID_AA64MMFR0_FGT_SHIFT, #4
 	cbz	x1, .Lskip_fgt_\@
 
-	msr_s	SYS_HDFGRTR_EL2, xzr
+	mov	x0, xzr
+	mrs	x1, id_aa64dfr0_el1
+	ubfx	x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4
+	cmp	x1, #3
+	b.lt	.Lset_fgt_\@
+	/* Set HDFGRTR_EL2.nPMSNEVFR_EL1 to disable the register trap */
+	orr	x0, x0, #(1 << 62)
+
+.Lset_fgt_\@:
+	msr_s	SYS_HDFGRTR_EL2, x0
 	msr_s	SYS_HDFGWTR_EL2, xzr
 	msr_s	SYS_HFGRTR_EL2, xzr
 	msr_s	SYS_HFGWTR_EL2, xzr
-- 
2.33.0



From festevam at gmail.com  Tue Aug 24 06:24:03 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 24 Aug 2021 10:24:03 -0300
Subject: [PATCH] arm64: dts: zii-ultra: add PCIe PHY supply
In-Reply-To: <20210820224402.2011354-1-l.stach@pengutronix.de>
References: <20210820224402.2011354-1-l.stach@pengutronix.de>
Message-ID: <CAOMZO5Dtz6wkWvYJD3fDMuzriLLCe4WKXqYdByWxuoP_ettY5Q@mail.gmail.com>

Hi Lucas,

On Fri, Aug 20, 2021 at 7:44 PM Lucas Stach <l.stach at pengutronix.de> wrote:
>
> The ZII Ultra board uses the same design as the EVK board supplying
> PCIE_VPH with 3.3V. Add this connection to the DT to allow the PCIe
> driver to enable the internal PHY regulator, as required by the
> reference manual.
>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From geert at linux-m68k.org  Tue Aug 24 06:25:38 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 24 Aug 2021 15:25:38 +0200
Subject: [PATCH v4 15/24] iommu/io-pgtable: Remove non-strict quirk
In-Reply-To: <155b5c621cd8936472e273a8b07a182f62c6c20d.1628682049.git.robin.murphy@arm.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
 <155b5c621cd8936472e273a8b07a182f62c6c20d.1628682049.git.robin.murphy@arm.com>
Message-ID: <CAMuHMdX+VSr0TJabMBNqob0MkD2o0RBNp8E5QYNx0jFucW1Aew@mail.gmail.com>

Hi Robin,

On Wed, Aug 11, 2021 at 2:24 PM Robin Murphy <robin.murphy at arm.com> wrote:
> IO_PGTABLE_QUIRK_NON_STRICT was never a very comfortable fit, since it's
> not a quirk of the pagetable format itself. Now that we have a more
> appropriate way to convey non-strict unmaps, though, this last of the
> non-quirk quirks can also go, and with the flush queue code also now
> enforcing its own ordering we can have a lovely cleanup all round.
>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Thanks for your patch, which is now commit a8e5f04458c4e496
("iommu/io-pgtable: Remove non-strict quirk") in iommu/next.

> --- a/drivers/iommu/io-pgtable-arm-v7s.c
> +++ b/drivers/iommu/io-pgtable-arm-v7s.c
> @@ -700,14 +700,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
>                                                 ARM_V7S_BLOCK_SIZE(lvl + 1));
>                                 ptep = iopte_deref(pte[i], lvl, data);
>                                 __arm_v7s_free_table(ptep, lvl + 1, data);
> -                       } else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
> -                               /*
> -                                * Order the PTE update against queueing the IOVA, to
> -                                * guarantee that a flush callback from a different CPU
> -                                * has observed it before the TLBIALL can be issued.
> -                                */
> -                               smp_wmb();
> -                       } else {
> +                       } else if (!gather->queued) {

If CONFIG_IOMMU_API=n:

error: ?struct iommu_iotlb_gather? has no member named ?queued?

This can be reproduced using e.g. shmobile_defconfig with
    CONFIG_IOMMU_SUPPORT=y
    CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y


>                                 io_pgtable_tlb_add_page(iop, gather, iova, blk_size);
>                         }
>                         iova += blk_size;

> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -638,14 +638,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
>                                 io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
>                                                           ARM_LPAE_GRANULE(data));
>                                 __arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
> -                       } else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
> -                               /*
> -                                * Order the PTE update against queueing the IOVA, to
> -                                * guarantee that a flush callback from a different CPU
> -                                * has observed it before the TLBIALL can be issued.
> -                                */
> -                               smp_wmb();
> -                       } else {
> +                       } else if (!gather->queued) {

If CONFIG_IOMMU_API=n:

error: ?struct iommu_iotlb_gather? has no member named ?queued?

This can be reproduced using e.g. shmobile_defconfig with
    CONFIG_IOMMU_SUPPORT=y
    CONFIG_IOMMU_IO_PGTABLE_LPAE=y

>                                 io_pgtable_tlb_add_page(iop, gather, iova + i * size, size);
>                         }
>

Perhaps "select IOMMU_API" should be added (moved from individual
drivers) to both IOMMU_IO_PGTABLE_ARMV7S and IOMMU_IO_PGTABLE_LPAE?
Or iommu_iotlb_gather.queued should not be accessed here, or the
access wrapped into a static inline helper function with a dummy for
the CONFIG_IOMMU_API=n case?

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From alexandru.elisei at arm.com  Tue Aug 24 06:28:45 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 24 Aug 2021 14:28:45 +0100
Subject: [PATCH] arm64: Do not trap PMSNEVFR_EL1
In-Reply-To: <20210824132459.562923-1-alexandru.elisei@arm.com>
References: <20210824132459.562923-1-alexandru.elisei@arm.com>
Message-ID: <01117fe3-d4fa-a735-36e1-ac9003e7b5cb@arm.com>

Errr... somehow I forgot to add the arm64 maintainers. Fixing that.

On 8/24/21 2:24 PM, Alexandru Elisei wrote:
> Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed
> the fine grained trap registers to prevent unwanted register traps from
> occuring. However, for the PMSNEVFR_EL1 register, the corresponding
> HDFGRTR_EL2.nPMSNEVFR_EL1 field must be 1 to disable trapping. Set the
> field to 1 if FEAT_SPEv1p2 is detected.
>
> Fixes: 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot")
> Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> ---
> Based on v5.14-rc7. Also, we could write 1 << 62 to HDFGRTR_EL2 unconditionally
> since the field is RAZ/WI if !FEAT_SPEv1p2. I don't have a strong preference for
> either approaches, but I chose this implementation because it's clearer (even
> though it's more verbose and it's one extra trap on NV).
>
> Tested on the model, using boot-wrapper built from commit 5cd6238ec4ef
> ("aarch32: fix .globl replacement"). Without this patch, in NVHE mode, the model
> freezes when I try to read PMSNEVFR_EL1. With this patch, the model doesn't hang
> when I read the register, but it hangs when I write to it. I've gone throught
> the pseudocode for reading and writing to PMSNEVFR_EL1 and from what I can tell
> nothing should be trapping the accesses. On top of that, this is what I tried on
> the model with this patch applied:
>
> 1. VHE mode, I can read and write to PMSNEVFR_EL1 without any issues, so the
> hang is not caused by an incorrect EL3 configuration.
>
> 2. NVHE mode, I can read and write just fine to *PMSEVFR_EL1*, so the hang is
> not caused by an EL2 trap that affects the rest of the profiling control
> registers. I have tried printing the HDFGRTR_EL2 value in this situation using
> semihosting, the value is what it is programmed by __init_el2_fgt (that is,
> 1 << 62).
>
> At this point, I am inclined to think it's a model bug because reading works,
> but writing causes a hang and that looks very suspicious to me. I'm going to
> open a model bug internally and see what comes of it.
>
>  arch/arm64/include/asm/el2_setup.h | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index b83fb24954b7..8a9adb2039fd 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -149,7 +149,16 @@
>  	ubfx	x1, x1, #ID_AA64MMFR0_FGT_SHIFT, #4
>  	cbz	x1, .Lskip_fgt_\@
>  
> -	msr_s	SYS_HDFGRTR_EL2, xzr
> +	mov	x0, xzr
> +	mrs	x1, id_aa64dfr0_el1
> +	ubfx	x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4
> +	cmp	x1, #3
> +	b.lt	.Lset_fgt_\@
> +	/* Set HDFGRTR_EL2.nPMSNEVFR_EL1 to disable the register trap */
> +	orr	x0, x0, #(1 << 62)
> +
> +.Lset_fgt_\@:
> +	msr_s	SYS_HDFGRTR_EL2, x0
>  	msr_s	SYS_HDFGWTR_EL2, xzr
>  	msr_s	SYS_HFGRTR_EL2, xzr
>  	msr_s	SYS_HFGWTR_EL2, xzr


From knaerzche at gmail.com  Tue Aug 24 06:40:47 2021
From: knaerzche at gmail.com (Alex Bee)
Date: Tue, 24 Aug 2021 15:40:47 +0200
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
Message-ID: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>

Hi list(s),

it seems there is a regression in arm64 memory mapping in 5.14, since it 
fails on Rockchip RK3328 when the pl330 dmac tries to map with:

[??? 8.921909] ------------[ cut here ]------------
[??? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 
dma_map_resource+0x68/0xc0
[??? 8.921973] Modules linked in: spi_rockchip(+) fuse
[??? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 
5.14.0-rc7 #1
[??? 8.922004] Hardware name: Pine64 Rock64 (DT)
[??? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
[??? 8.922018] pc : dma_map_resource+0x68/0xc0
[??? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
[??? 8.922040] sp : ffff800012102ae0
[??? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 
0000000000000000
[??? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 
0000000000000001
[??? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 
0000000000000001
[??? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 
0000000000000000
[??? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 
0000000000000000
[??? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 
0000000000000000
[??? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : 
ffff800012102a80
[??? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : 
ffff0000fe7b1100
[??? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 
0000000000000001
[??? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : 
ffff000000628c00
[??? 8.922158] Call trace:
[??? 8.922163]? dma_map_resource+0x68/0xc0
[??? 8.922173]? pl330_prep_slave_sg+0x58/0x220
[??? 8.922181]? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
[??? 8.922208]? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
[??? 8.922220]? spi_transfer_one_message+0x284/0x57c
[??? 8.922232]? __spi_pump_messages+0x3dc/0x650
[??? 8.922240]? __spi_sync+0x3e4/0x48c
[??? 8.922247]? spi_sync+0x30/0x54
[??? 8.922253]? spi_mem_exec_op+0x264/0x444
[??? 8.922260]? spi_nor_spimem_read_data+0x148/0x160
[??? 8.922269]? spi_nor_read_data+0x30/0x40
[??? 8.922276]? spi_nor_read_sfdp+0x74/0xe4
[??? 8.922285]? spi_nor_parse_sfdp+0x1d0/0x1130
[??? 8.922293]? spi_nor_sfdp_init_params+0x3c/0x90
[??? 8.922304]? spi_nor_scan+0x7b4/0xacc
[??? 8.922311]? spi_nor_probe+0x94/0x2d0
[??? 8.922317]? spi_mem_probe+0x6c/0xb0
[??? 8.922325]? spi_probe+0x84/0xe4
[??? 8.922335]? really_probe+0xb4/0x45c
[??? 8.922349]? __driver_probe_device+0x114/0x190
[??? 8.922358]? driver_probe_device+0x40/0x100
[??? 8.922367]? __device_attach_driver+0x98/0x130
[??? 8.922375]? bus_for_each_drv+0x78/0xd0
[??? 8.922383]? __device_attach+0xdc/0x1c0
[??? 8.922391]? device_initial_probe+0x14/0x20
[??? 8.922400]? bus_probe_device+0x98/0xa0
[??? 8.922408]? device_add+0x36c/0x8c0
[??? 8.922416]? __spi_add_device+0x74/0x170
[??? 8.922423]? spi_add_device+0x64/0xa4
[??? 8.922429]? of_register_spi_device+0x21c/0x36c
[??? 8.922436]? spi_register_controller+0x5e0/0x834
[??? 8.922443]? devm_spi_register_controller+0x24/0x80
[??? 8.922450]? rockchip_spi_probe+0x434/0x5b0 [spi_rockchip]
[??? 8.922468]? platform_probe+0x68/0xe0
[??? 8.922478]? really_probe+0xb4/0x45c
[??? 8.922487]? __driver_probe_device+0x114/0x190
[??? 8.922497]? driver_probe_device+0x40/0x100
[??? 8.922507]? __driver_attach+0xcc/0x1e0
[??? 8.922516]? bus_for_each_dev+0x70/0xd0
[??? 8.922524]? driver_attach+0x24/0x30
[??? 8.922533]? bus_add_driver+0x140/0x234
[??? 8.922540]? driver_register+0x78/0x130
[??? 8.922547]? __platform_driver_register+0x28/0x34
[??? 8.922554]? rockchip_spi_driver_init+0x20/0x1000 [spi_rockchip]
[??? 8.922566]? do_one_initcall+0x50/0x1b0
[??? 8.922579]? do_init_module+0x54/0x250
[??? 8.922589]? load_module+0x2230/0x285c
[??? 8.922597]? __do_sys_finit_module+0xbc/0x12c
[??? 8.922605]? __arm64_sys_finit_module+0x24/0x30
[??? 8.922613]? invoke_syscall+0x48/0x114
[??? 8.922625]? el0_svc_common+0x40/0xfc
[??? 8.922632]? do_el0_svc_compat+0x20/0x50
[??? 8.922640]? el0_svc_compat+0x2c/0x54
[??? 8.922652]? el0t_32_sync_handler+0x90/0x140
[??? 8.922660]? el0t_32_sync+0x19c/0x1a0
[??? 8.922669] ---[ end trace 2245d8ba23a1d75c ]---

Note: This does not relate to the spi driver - when disabling this 
device in the device tree it fails for any other (i2s, for instance) 
which uses dma.
Commenting out the failing check at [1], however, helps and the mapping 
works again.

I tried to follow the recent changes for arm64 mm which could relate to 
the check failing at [1] and reverting
 ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
helps and makes it work again, but I'm 100% uncertain if that commit is 
really the culprit.

Note, that the firmware (legacy u-boot) injects memory configuration in 
the device tree as follows:

/memreserve/??? 0x00000000fcefc000 0x000000000000d000;
/ {
..
 ??? compatible = "pine64,rock64\0rockchip,rk3328";
..
 ??? memory {
 ??? ??? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
 ??? ??? device_type = "memory";
 ??? };

..
}

So: there is a "hole" in the mappable memory and reading the commit 
message of
 ? commit a7d9f306ba70 ("arm64: drop pfn_valid_within() and simplify 
pfn_valid()")
suggests, there was a change for that case recently.

I also noticed there is a diff in the kernel log regarding memory init 
up until 5.13.12 it says

[??? 0.000000] Zone ranges:
[??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
[??? 0.000000]?? DMA32??? empty
[??? 0.000000]?? Normal?? empty
[??? 0.000000] Movable zone start for each node
[??? 0.000000] Early memory node ranges
[??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
[??? 0.000000] Initmem setup node 0 [mem 
0x0000000000200000-0x00000000feffffff]
[??? 0.000000] On node 0 totalpages: 1043968
[??? 0.000000]?? DMA zone: 16312 pages used for memmap
[??? 0.000000]?? DMA zone: 0 pages reserved
[??? 0.000000]?? DMA zone: 1043968 pages, LIFO batch:63


In contrary in 5.14-rc7 it says:

[??? 0.000000] Zone ranges:
[??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
[??? 0.000000]?? DMA32??? empty
[??? 0.000000]?? Normal?? empty
[??? 0.000000] Movable zone start for each node
[??? 0.000000] Early memory node ranges
[??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
[??? 0.000000] Initmem setup node 0 [mem 
0x0000000000200000-0x00000000feffffff]
[??? 0.000000] On node 0, zone DMA: 512 pages in unavailable ranges
[??? 0.000000] On node 0, zone DMA: 4096 pages in unavailable ranges

(note the "unavailable ranges")
I'm uncertain again here, if that diff is expected behavior because of 
those recent mm changes for arm64.

After reverting
 ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
the log changes to

[??? 0.000000] Zone ranges:
[??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
[??? 0.000000]?? DMA32??? empty
[??? 0.000000]?? Normal?? empty
[??? 0.000000] Movable zone start for each node
[??? 0.000000] Early memory node ranges
[??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
[??? 0.000000] Initmem setup node 0 [mem 
0x0000000000200000-0x00000000feffffff]

(no DMA zones here)

As you might have noticed I have _zero_ clue about memory mapping and 
dma subsystem - so let me know if there is any more information needed 
for that and thanks for your help.

Alex

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/dma/mapping.c?id=e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93#n235



From robin.murphy at arm.com  Tue Aug 24 06:46:02 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 24 Aug 2021 14:46:02 +0100
Subject: [PATCH v4 15/24] iommu/io-pgtable: Remove non-strict quirk
In-Reply-To: <CAMuHMdX+VSr0TJabMBNqob0MkD2o0RBNp8E5QYNx0jFucW1Aew@mail.gmail.com>
References: <cover.1628682048.git.robin.murphy@arm.com>
 <155b5c621cd8936472e273a8b07a182f62c6c20d.1628682049.git.robin.murphy@arm.com>
 <CAMuHMdX+VSr0TJabMBNqob0MkD2o0RBNp8E5QYNx0jFucW1Aew@mail.gmail.com>
Message-ID: <1f7de684-c646-cda9-b246-3712f046f2b0@arm.com>

Hi Geert,

On 2021-08-24 14:25, Geert Uytterhoeven wrote:
> Hi Robin,
> 
> On Wed, Aug 11, 2021 at 2:24 PM Robin Murphy <robin.murphy at arm.com> wrote:
>> IO_PGTABLE_QUIRK_NON_STRICT was never a very comfortable fit, since it's
>> not a quirk of the pagetable format itself. Now that we have a more
>> appropriate way to convey non-strict unmaps, though, this last of the
>> non-quirk quirks can also go, and with the flush queue code also now
>> enforcing its own ordering we can have a lovely cleanup all round.
>>
>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> 
> Thanks for your patch, which is now commit a8e5f04458c4e496
> ("iommu/io-pgtable: Remove non-strict quirk") in iommu/next.
> 
>> --- a/drivers/iommu/io-pgtable-arm-v7s.c
>> +++ b/drivers/iommu/io-pgtable-arm-v7s.c
>> @@ -700,14 +700,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
>>                                                  ARM_V7S_BLOCK_SIZE(lvl + 1));
>>                                  ptep = iopte_deref(pte[i], lvl, data);
>>                                  __arm_v7s_free_table(ptep, lvl + 1, data);
>> -                       } else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
>> -                               /*
>> -                                * Order the PTE update against queueing the IOVA, to
>> -                                * guarantee that a flush callback from a different CPU
>> -                                * has observed it before the TLBIALL can be issued.
>> -                                */
>> -                               smp_wmb();
>> -                       } else {
>> +                       } else if (!gather->queued) {
> 
> If CONFIG_IOMMU_API=n:
> 
> error: ?struct iommu_iotlb_gather? has no member named ?queued?
> 
> This can be reproduced using e.g. shmobile_defconfig with
>      CONFIG_IOMMU_SUPPORT=y
>      CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
> 
> 
>>                                  io_pgtable_tlb_add_page(iop, gather, iova, blk_size);
>>                          }
>>                          iova += blk_size;
> 
>> --- a/drivers/iommu/io-pgtable-arm.c
>> +++ b/drivers/iommu/io-pgtable-arm.c
>> @@ -638,14 +638,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
>>                                  io_pgtable_tlb_flush_walk(iop, iova + i * size, size,
>>                                                            ARM_LPAE_GRANULE(data));
>>                                  __arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
>> -                       } else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
>> -                               /*
>> -                                * Order the PTE update against queueing the IOVA, to
>> -                                * guarantee that a flush callback from a different CPU
>> -                                * has observed it before the TLBIALL can be issued.
>> -                                */
>> -                               smp_wmb();
>> -                       } else {
>> +                       } else if (!gather->queued) {
> 
> If CONFIG_IOMMU_API=n:
> 
> error: ?struct iommu_iotlb_gather? has no member named ?queued?
> 
> This can be reproduced using e.g. shmobile_defconfig with
>      CONFIG_IOMMU_SUPPORT=y
>      CONFIG_IOMMU_IO_PGTABLE_LPAE=y
> 
>>                                  io_pgtable_tlb_add_page(iop, gather, iova + i * size, size);
>>                          }
>>
> 
> Perhaps "select IOMMU_API" should be added (moved from individual
> drivers) to both IOMMU_IO_PGTABLE_ARMV7S and IOMMU_IO_PGTABLE_LPAE?
> Or iommu_iotlb_gather.queued should not be accessed here, or the
> access wrapped into a static inline helper function with a dummy for
> the CONFIG_IOMMU_API=n case?

Those (and worse) should be fixed by this patch:

https://lore.kernel.org/linux-iommu/83672ee76f6405c82845a55c148fa836f56fbbc1.1629465282.git.robin.murphy at arm.com/

which apparently hasn't made it to -next yet.

Thanks,
Robin.

> 
> Gr{oetje,eeting}s,
> 
>                          Geert
> 


From mark.rutland at arm.com  Tue Aug 24 06:48:55 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 14:48:55 +0100
Subject: [boot-wrapper PATCH 0/5] Misc cleanups
Message-ID: <20210824134900.34849-1-mark.rutland@arm.com>

These are a few cleanup patches I've split out of my ongoing bootwrapper
rework, and intend to apply by the end of this week.

My WIP cleanup branch with subsequent patches can be found at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git cleanup

Thanks,
Mark.

Mark Rutland (5):
  Remove unused Set/Way cache helpers
  aarch32: simplify _switch_monitor
  GICv3: initialize without RMW
  Rename kernel *_RESET values to *_KERNEL
  Rename `CNTFRQ` -> `COUNTER_FREQ`

 Makefile.am                       |  4 ++--
 arch/aarch32/boot.S               | 25 +++++++------------------
 arch/aarch32/include/asm/cpu.h    | 30 ++----------------------------
 arch/aarch32/include/asm/gic-v3.h |  7 -------
 arch/aarch64/boot.S               |  6 +++---
 arch/aarch64/include/asm/cpu.h    | 32 +++-----------------------------
 arch/aarch64/include/asm/gic-v3.h |  7 -------
 common/gic-v3.c                   |  8 +++-----
 8 files changed, 20 insertions(+), 99 deletions(-)

-- 
2.11.0



From mark.rutland at arm.com  Tue Aug 24 06:48:56 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 14:48:56 +0100
Subject: [boot-wrapper PATCH 1/5] Remove unused Set/Way cache helpers
In-Reply-To: <20210824134900.34849-1-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
Message-ID: <20210824134900.34849-2-mark.rutland@arm.com>

We removed the Set/Way cache maintenance in commit:

  864182b26c20a39d ("Remove cache maintenance")

... but forgot to remove the arch helpers which are now unused.

Remove the unused helpers.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/include/asm/cpu.h | 26 --------------------------
 arch/aarch64/include/asm/cpu.h | 26 --------------------------
 2 files changed, 52 deletions(-)

diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index 878be67..a7993f0 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -56,32 +56,6 @@ static inline uint32_t read_id_pfr1(void)
 	return val;
 }
 
-static inline uint32_t read_clidr(void)
-{
-	uint32_t val;
-
-	asm volatile ("mrc	p15, 1, %0, c0, c0, 1" : "=r" (val));
-	return val;
-}
-
-static inline uint32_t read_ccsidr(void)
-{
-	uint32_t val;
-
-	asm volatile ("mrc	p15, 1, %0, c0, c0, 0" : "=r" (val));
-	return val;
-}
-
-static inline void write_csselr(uint32_t val)
-{
-	asm volatile ("mcr	p15, 2, %0, c0, c0, 0" : : "r" (val));
-}
-
-static inline void dccisw(uint32_t val)
-{
-	asm volatile ("mcr	p15, 0, %0, c7, c14, 2" : : "r" (val));
-}
-
 static inline void iciallu(void)
 {
 	uint32_t val = 0;
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index ccb5397..1cddbb8 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -66,32 +66,6 @@ static inline uint64_t read_id_aa64pfr0(void)
 	return val;
 }
 
-static inline uint32_t read_clidr(void)
-{
-	uint32_t val;
-
-	asm volatile ("mrs	%0, clidr_el1" : "=r" (val));
-	return val;
-}
-
-static inline uint32_t read_ccsidr(void)
-{
-	uint32_t val;
-
-	asm volatile ("mrs	%0, ccsidr_el1" : "=r" (val));
-	return val;
-}
-
-static inline void write_csselr(uint32_t val)
-{
-	asm volatile ("msr	csselr_el1, %0" : : "r" (val));
-}
-
-static inline void dccisw(uint32_t val)
-{
-	asm volatile ("dc	cisw, %0" : : "r" (val));
-}
-
 static inline void iciallu(void)
 {
 	asm volatile ("ic	iallu");
-- 
2.11.0



From mark.rutland at arm.com  Tue Aug 24 06:48:57 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 14:48:57 +0100
Subject: [boot-wrapper PATCH 2/5] aarch32: simplify _switch_monitor
In-Reply-To: <20210824134900.34849-1-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
Message-ID: <20210824134900.34849-3-mark.rutland@arm.com>

If we're lucky enough to have been booted into secure PL1, we can switch
to monitor mode with an exception return rather than an SMC call, which
avoids the need for boot-time vectors.

Note that while all Secure PL1 register state is accessible in Secure
SVC mode, we must switch to Monitor mode before we set SCR.NS=1.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 82927de..e397cb0 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -37,9 +37,10 @@ ASM_FUNC(_start)
 	b	start_no_el3
 
 _switch_monitor:
-	ldr	r0, =boot_vectors
-	bl	setup_vector
-	smc	#0
+	adr	lr, _monitor
+	ldr	r0, =(PSR_A | PSR_I | PSR_F | PSR_MON)
+	msr	spsr, r0
+	movs	pc, lr
 
 _monitor:
 	/* Move the stack to Monitor mode*/
@@ -102,18 +103,6 @@ ASM_FUNC(jump_kernel)
 	msr	spsr_cxf, r4
 	movs	pc, lr
 
-	.section .vectors
-	.align 6
-boot_vectors:
-	b	.
-	b	.
-	b	_monitor
-	b	.
-	b	.
-	b	.
-	b	.
-	b	.
-
 	.section .data
 	.align 2
 flag_no_el3:
-- 
2.11.0



From mark.rutland at arm.com  Tue Aug 24 06:48:58 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 14:48:58 +0100
Subject: [boot-wrapper PATCH 3/5] GICv3: initialize without RMW
In-Reply-To: <20210824134900.34849-1-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
Message-ID: <20210824134900.34849-4-mark.rutland@arm.com>

There's no need to perform an RMW sequence to initialize ICC_SRE_EL3, as
there are no bits that we need to preserve, and generally we should
reset registers to specific values such that RESx bits aren't configured
to UNKNOWN values that could be problematic in future architecture
versions.

Instead, let's initialize ICC_SRE_EL3 with a constant value. Since the
`DIB` and `DFB` fields are RAO/WI in some configurations and we have no
reason to initialize these to 0, we always initialize these to 1, in
addition to `SRE` and `SRE_Enable`.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Alexandru Elisei <alexandru.elisei at arm.com>
Cc: Andre Przywara <andre.przywara at arm.com>
---
 arch/aarch32/include/asm/gic-v3.h | 7 -------
 arch/aarch64/include/asm/gic-v3.h | 7 -------
 common/gic-v3.c                   | 8 +++-----
 3 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
index ec9a327..65f38de 100644
--- a/arch/aarch32/include/asm/gic-v3.h
+++ b/arch/aarch32/include/asm/gic-v3.h
@@ -9,13 +9,6 @@
 #ifndef __ASM_AARCH32_GICV3_H
 #define __ASM_AARCH32_GICV3_H
 
-static inline uint32_t gic_read_icc_sre(void)
-{
-	uint32_t val;
-	asm volatile ("mrc p15, 6, %0, c12, c12, 5" : "=r" (val));
-	return val;
-}
-
 static inline void gic_write_icc_sre(uint32_t val)
 {
 	asm volatile ("mcr p15, 6, %0, c12, c12, 5" : : "r" (val));
diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h
index e743c02..5b32380 100644
--- a/arch/aarch64/include/asm/gic-v3.h
+++ b/arch/aarch64/include/asm/gic-v3.h
@@ -15,13 +15,6 @@
 #define ICC_CTLR_EL3	"S3_6_C12_C12_4"
 #define ICC_PMR_EL1	"S3_0_C4_C6_0"
 
-static inline uint32_t gic_read_icc_sre(void)
-{
-	uint32_t val;
-	asm volatile ("mrs %0, " ICC_SRE_EL3 : "=r" (val));
-	return val;
-}
-
 static inline void gic_write_icc_sre(uint32_t val)
 {
 	asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
diff --git a/common/gic-v3.c b/common/gic-v3.c
index 62f9676..6207007 100644
--- a/common/gic-v3.c
+++ b/common/gic-v3.c
@@ -42,6 +42,8 @@
 #define GICR_TYPER_Last			(1 << 4)
 
 #define ICC_SRE_SRE			(1 << 0)
+#define ICC_SRE_DFB			(1 << 1)
+#define ICC_SRE_DIB			(1 << 2)
 #define ICC_SRE_Enable			(1 << 3)
 
 void gic_secure_init_primary(void)
@@ -101,8 +103,6 @@ void gic_secure_init_primary(void)
 
 void gic_secure_init(void)
 {
-	uint32_t sre;
-
 	/*
 	 * If GICv3 is not available, skip initialisation. The OS will probably
 	 * fail with a warning, but this should be easier to debug than a
@@ -114,9 +114,7 @@ void gic_secure_init(void)
 	if (this_cpu_logical_id() == 0)
 		gic_secure_init_primary();
 
-	sre = gic_read_icc_sre();
-	sre |= ICC_SRE_Enable | ICC_SRE_SRE;
-	gic_write_icc_sre(sre);
+	gic_write_icc_sre(ICC_SRE_Enable | ICC_SRE_DIB | ICC_SRE_DFB | ICC_SRE_SRE);
 	isb();
 
 	gic_write_icc_ctlr(0);
-- 
2.11.0



From mark.rutland at arm.com  Tue Aug 24 06:48:59 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 14:48:59 +0100
Subject: [boot-wrapper PATCH 4/5] Rename kernel *_RESET values to *_KERNEL
In-Reply-To: <20210824134900.34849-1-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
Message-ID: <20210824134900.34849-5-mark.rutland@arm.com>

Our *_RESET constants are used to initalize state for the kernel rather
than the bootwrapper itself, so for clarity we should use a *_KERNEL
suffix rather than a _RESET suffix.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S            | 4 ++--
 arch/aarch32/include/asm/cpu.h | 4 ++--
 arch/aarch64/boot.S            | 4 ++--
 arch/aarch64/include/asm/cpu.h | 6 +++---
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index e397cb0..08bf932 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -76,10 +76,10 @@ ASM_FUNC(jump_kernel)
 	push	{r0 - r3}
 	mov	r5, sp
 
-	ldr	r0, =HSCTLR_RESET
+	ldr	r0, =HSCTLR_KERNEL
 	mcr	p15, 4, r0, c1, c0, 0		@ HSCTLR
 
-	ldr	r0, =SCTLR_RESET
+	ldr	r0, =SCTLR_KERNEL
 	mcr	p15, 0, r0, c1, c0, 0		@ SCTLR
 
 	/* Reset our stack pointer */
diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index a7993f0..105cae5 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -13,8 +13,8 @@
 #define MPIDR_INVALID		(-1)
 
 /* Only RES1 bits and CP15 barriers for the kernel */
-#define HSCTLR_RESET		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
-#define SCTLR_RESET		(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
+#define HSCTLR_KERNEL		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
+#define SCTLR_KERNEL		(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
 
 #define PSR_SVC			0x13
 #define PSR_HYP			0x1a
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index d8d7ccd..587a25f 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -140,10 +140,10 @@ ASM_FUNC(jump_kernel)
 	mov	x22, x3
 	mov	x23, x4
 
-	ldr	x0, =SCTLR_EL1_RESET
+	ldr	x0, =SCTLR_EL1_KERNEL
 	msr	sctlr_el1, x0
 
-	ldr	x0, =SCTLR_EL2_RESET
+	ldr	x0, =SCTLR_EL2_KERNEL
 	msr	sctlr_el2, x0
 
 	cpuid	x0, x1
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 1cddbb8..63eb1c3 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -17,7 +17,7 @@
  * RES1 bits,  little-endian, caches and MMU off, no alignment checking,
  * no WXN.
  */
-#define SCTLR_EL2_RESET		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
+#define SCTLR_EL2_KERNEL	(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
 
 #define SPSR_A			(1 << 8)	/* System Error masked */
 #define SPSR_D			(1 << 9)	/* Debug masked */
@@ -37,10 +37,10 @@
 
 #ifdef KERNEL_32
 /* 32-bit kernel decompressor uses CP15 barriers */
-#define SCTLR_EL1_RESET		(SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
+#define SCTLR_EL1_KERNEL	(SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
 #define SPSR_KERNEL		(SPSR_A | SPSR_I | SPSR_F | SPSR_HYP)
 #else
-#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
+#define SCTLR_EL1_KERNEL	SCTLR_EL1_RES1
 #define SPSR_KERNEL		(SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL2H)
 #endif
 
-- 
2.11.0



From mark.rutland at arm.com  Tue Aug 24 06:49:00 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 14:49:00 +0100
Subject: [boot-wrapper PATCH 5/5] Rename `CNTFRQ` -> `COUNTER_FREQ`
In-Reply-To: <20210824134900.34849-1-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
Message-ID: <20210824134900.34849-6-mark.rutland@arm.com>

To avoid any confusuion between the CNTFRQ/CNTFRQ_EL0 register and the
vallue it will be progrmamed with, rename the `CNTFRQ` constant to
`COUNTER_FREQ.

In future patches this will allow us to use `CNTFRQ` as a macro for the
AArch32 CP15 register encoding.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am         | 4 ++--
 arch/aarch32/boot.S | 2 +-
 arch/aarch64/boot.S | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 3591d23..d0a68df 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,12 +13,12 @@ SCRIPT_DIR	:= $(top_srcdir)/scripts
 PHYS_OFFSET	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findmem.pl $(KERNEL_DTB))
 UART_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,pl011')
 SYSREGS_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,vexpress-sysreg' 2> /dev/null)
-CNTFRQ		:= 24000000
+COUNTER_FREQ	:= 24000000
 
 CPU_IDS		:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findcpuids.pl $(KERNEL_DTB))
 NR_CPUS         := $(shell echo $(CPU_IDS) | tr ',' ' ' | wc -w)
 
-DEFINES		= -DCNTFRQ=$(CNTFRQ)
+DEFINES		= -DCOUNTER_FREQ=$(COUNTER_FREQ)
 DEFINES		+= -DCPU_IDS=$(CPU_IDS)
 DEFINES		+= -DNR_CPUS=$(NR_CPUS)
 DEFINES		+= $(if $(SYSREGS_BASE), -DSYSREGS_BASE=$(SYSREGS_BASE), )
diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 08bf932..4add338 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -54,7 +54,7 @@ _monitor:
 	mov	r0, #(1 << 10 | 1 << 11)	@ Enable NS access to CPACR
 	mcr	p15, 0, r0, c1, c1, 2		@ NSACR
 
-	ldr	r0, =CNTFRQ
+	ldr	r0, =COUNTER_FREQ
 	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
 
 	bl	gic_secure_init
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 587a25f..bfbb6ec 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -118,7 +118,7 @@ ASM_FUNC(_start)
 	msr	ZCR_EL3, x0			// for EL2.
 
 1:
-	ldr	x0, =CNTFRQ
+	ldr	x0, =COUNTER_FREQ
 	msr	cntfrq_el0, x0
 
 	bl	gic_secure_init
-- 
2.11.0



From ulf.hansson at linaro.org  Tue Aug 24 06:52:33 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 24 Aug 2021 15:52:33 +0200
Subject: [PATCH 1/6] mmc: sdhci-esdhc-imx: remove redundant code for
 manual tuning
In-Reply-To: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <CAPDyKFr2z6t0uefxioLHaszvwrc9Pkf1OJDi=jozjpEZcKP5ng@mail.gmail.com>

On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
>
> From: Haibo Chen <haibo.chen at nxp.com>
>
> For manual tuning method, already call esdhc_prepare_tuning()
> config the necessary registers, so remove the redundant code
> in esdhc_writew_le() for SDHCI_HOST_CONTROL2.
>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

While discussions on the DT binding, etc, continue with Lucas and Rob
on patch 3 - do you want me to apply patch1 and patch2?

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 12 +-----------
>  1 file changed, 1 insertion(+), 11 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 57b19ca1ad6d..a49fac719fca 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -628,17 +628,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
>                 else
>                         new_val &= ~ESDHC_VENDOR_SPEC_VSELECT;
>                 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
> -               if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
> -                       new_val = readl(host->ioaddr + ESDHC_MIX_CTRL);
> -                       if (val & SDHCI_CTRL_TUNED_CLK) {
> -                               new_val |= ESDHC_MIX_CTRL_SMPCLK_SEL;
> -                               new_val |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
> -                       } else {
> -                               new_val &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
> -                               new_val &= ~ESDHC_MIX_CTRL_AUTO_TUNE_EN;
> -                       }
> -                       writel(new_val , host->ioaddr + ESDHC_MIX_CTRL);
> -               } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
> +               if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
>                         u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS);
>                         u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
>                         if (val & SDHCI_CTRL_TUNED_CLK) {
> --
> 2.17.1
>


From geert at linux-m68k.org  Tue Aug 24 06:55:43 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 24 Aug 2021 15:55:43 +0200
Subject: [PATCH] iommu/io-pgtable: Abstract iommu_iotlb_gather access
In-Reply-To: <83672ee76f6405c82845a55c148fa836f56fbbc1.1629465282.git.robin.murphy@arm.com>
References: <83672ee76f6405c82845a55c148fa836f56fbbc1.1629465282.git.robin.murphy@arm.com>
Message-ID: <CAMuHMdXL7ZtY8kBx=RHsRy1JECsGPDe+E3SM=--w7bUHMYHFBQ@mail.gmail.com>

Hi Robin,

On Fri, Aug 20, 2021 at 3:22 PM Robin Murphy <robin.murphy at arm.com> wrote:
> Previously io-pgtable merely passed the iommu_iotlb_gather pointer
> through to helpers, but now it has grown its own direct dereference.
> This turns out to break the build for !IOMMU_API configs where the
> structure only has a dummy definition. It will probably also crash
> drivers who don't use the gather mechanism and simply pass in NULL.
>
> Wrap this dereference in a suitable helper which can both be stubbed
> out for !IOMMU_API and encapsulate a NULL check otherwise.
>
> Fixes: 7a7c5badf858 ("iommu: Indicate queued flushes via gather data")

Is this the right Fixes tag?

The build issue was introduced by:
Fixes: a8e5f04458c4e496 ("iommu/io-pgtable: Remove non-strict quirk")

> Reported-by: kernel test robot <lkp at intel.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Thanks, this fixes the build issues I was seeing.

Tested-by: Geert Uytterhoeven <geert+renesas at glider.be>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From cristian.marussi at arm.com  Tue Aug 24 06:59:29 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:29 +0100
Subject: [PATCH v4 0/12] Introduce atomic support for SCMI transports
Message-ID: <20210824135941.38656-1-cristian.marussi@arm.com>

Hi all,

This series mainly aims to introduce atomic support for transports
that can support it.

At first in [2/12], as a closely related addition, it is introduced a
common way for a transport to signal to the SCMI core that it does not
offer completion interrupts, so that the usual polling behaviour based
on .poll_done() will be required: this can be done enabling statically
a global polling behaviour for the whole transport with flag
scmi_desc.force_polling OR dynamically enabling at runtime such polling
behaviour on a per-channel basis with scmi_chan_info.no_completion_irq,
typically during .chan_setup(). The usual per-command polling selection
behaviour based on hdr.poll_completion is preserved as before.

Then in [3/12], a transport that supports atomic operations on its TX path
can now declare itself as .atomic_capable and as a consequence the SCMI
core will refrain itself too from sleeping on the correspondent RX-path
even when using completion IRQs.

In [6/12] a simple method is introduced so that an SCMI driver can easily
query the core to check if the currently used transport is configured to
behave in an atomic manner: in this way, interested SCMI driver users, like
Clock framework [7/12], can optionally support atomic operations when
operating on an atomically configured transport.

In [8/12] virtio transport is declared atomic.

Finally there are 4 *tentative" RFC patch related to SMC transport.

At first [9/12] ports SMC to use the common core completions when
completion interrupt is available or otherwise revert to use common core
polling mechanism above introduced: this avoids the improper call of
scmi_rx_callback directly in smc_send_message.
Then in [10/12] SMC is converted to be .atomic_capable by substituting
the mutexes with busy-waiting to keep the channel 'locked'.

With [11/12] I introduce a flag to allow a transport to signal to the core
that upon return of a .send_message() the requested command execution can
be assumed by the core to have been fully completed by the platform, so
that the response payload (if any) can be immediately fetched without the
need to poll the channel.

Finally in [12/12] I enable the above flag for SMC transport.

As a side note on the sync_cmds_atomic_replies flag added in [11/12], note
that such flag assumes that a specific transport can set it and so
univocally assure to the SCMI core that the described behavior holds true
anytime for the said transport; in reality, in a transport like SMC such
behavior could also be dependent on the effective placement of the SCMI
platform server: while a pure EL-3 SCMI server could reasonably assure
that upon smc call termination the command is fully completed, the same
could not be true for an SCMI server living in S-EL1.

For such reasons a possible evolution could be to add also some DT property
to enable the SMC transport to conditionally enable the flag at run-time
depending on the effective runtime platform configuration in terms of
SCMI server placement.

This whole matter is up for discussion, though, maybe it's not even a real
possibility an S-EL1 SCMI server using an SMC transport, so the DT patch
has not been included in this series.

Moreover, SMC changes have NOT been tested so far (I cannot), AND they are
just a proposal at this stage to try to better abstract and unify behaviour
with the SCMI core, so they are marked as RFCs.

Atomic support has been minimally tested against the upcoming virtio
transport V7 series, while polling has been tested with mailbox transports.

The series is based on linux-next/master on top of tag next-20210824 so as
to include the recently queued series on SCMI virtio and its core changes
currently queued also on sudeep/for-next/scmi [1].

Given I'm still gathering feedback on this, I still not have CCed any
maintainer out of SCMI subsystem.

Any feedback welcome.

Thanks,

Cristian

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git/log/?h=for-next/scmi 

---

V3 --> V4
- rebased on linux-next/master next-20210824
- renamed .needs_polling to .no_completion_irq
- added .sync_cmds_atomic_replies
- make SMC use .sync_cmd_atomic_replies

V2 --> v3
- rebased on SCMI VirtIO V6 which in turn is based on v5.14-rc1


Cristian Marussi (12):
  firmware: arm_scmi: Perform earlier cinfo lookup call in do_xfer
  firmware: arm_scmi: Add configurable polling mode for transports
  firmware: arm_scmi: Add support for atomic transports
  include: trace: Add new scmi_xfer_response_wait event
  firmware: arm_scmi: Use new trace event scmi_xfer_response_wait
  firmware: arm_scmi: Add is_transport_atomic() handle method
  clk: scmi: Support atomic enable/disable API
  firmware: arm_scmi: Declare virtio transport .atomic_capable
  [RFC] firmware: arm_scmi: Make smc transport use common completions
  [RFC] firmware: arm_scmi: Make smc transport atomic
  [RFC] firmware: arm_scmi: Add sync_cmds_atomic_replies transport flag
  [RFC] firmware: arm_scmi: Make smc support atomic commands replies

 drivers/clk/clk-scmi.c             |  44 ++++--
 drivers/firmware/arm_scmi/common.h |  22 +++
 drivers/firmware/arm_scmi/driver.c | 224 +++++++++++++++++++++++------
 drivers/firmware/arm_scmi/smc.c    |  61 +++++---
 drivers/firmware/arm_scmi/virtio.c |   1 +
 include/linux/scmi_protocol.h      |   8 ++
 include/trace/events/scmi.h        |  28 ++++
 7 files changed, 311 insertions(+), 77 deletions(-)

-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:31 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:31 +0100
Subject: [PATCH v4 02/12] firmware: arm_scmi: Add configurable polling mode
 for transports
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-3-cristian.marussi@arm.com>

SCMI communications along TX channels can optionally be provided of a
completion interrupt; when such interrupt is not available, command
transactions should rely on polling, where the SCMI core takes care to
repeatedly evaluate the transport-specific .poll_done() function to
determine if and when a request was fully completed or timed out.

Such mechanism is already present and working on a single transfer base:
SCMI protocols can indeed enable hdr.poll_completion on specific commands
ahead of each transfer and cause that transaction to be handled with
polling.

Introduce a couple of flags to be able to enforce such polling behaviour
globally at will:

 - scmi_desc.force_polling: to statically switch the whole transport to
   polling mode.

 - scmi_chan_info.no_completion_irq: to switch a single channel dynamically
   to polling mode if at runtime is determined that no completion interrupt
   was available for such channel.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v3 --> v4:
- renamed .needs_polling flag to .no_completion_irq
- refactored error path when polling needed but not supported
---
 drivers/firmware/arm_scmi/common.h | 11 +++++++++++
 drivers/firmware/arm_scmi/driver.c | 29 +++++++++++++++++++++++------
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index dea1bfbe1052..67c761141a48 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -339,11 +339,19 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
  * @dev: Reference to device in the SCMI hierarchy corresponding to this
  *	 channel
  * @handle: Pointer to SCMI entity handle
+ * @no_completion_irq: Flag to indicate that this channel has no completion
+ *		       interrupt mechanism, so it needs SCMI core to poll,
+ *		       using .poll_done(), to determine when a command has
+ *		       completed.
+ *		       This can be dynamically set by transports at run-time
+ *		       inside their provided .chan_setup() when they determine
+ *		       no completion interrupt is available.
  * @transport_info: Transport layer related information
  */
 struct scmi_chan_info {
 	struct device *dev;
 	struct scmi_handle *handle;
+	bool no_completion_irq;
 	void *transport_info;
 };
 
@@ -402,6 +410,8 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
  *	be pending simultaneously in the system. May be overridden by the
  *	get_max_msg op.
  * @max_msg_size: Maximum size of data per message that can be handled.
+ * @force_polling: Flag to force this whole transport to use SCMI core polling
+ *		   mechanism instead of completion interrupts even if available.
  */
 struct scmi_desc {
 	int (*transport_init)(void);
@@ -410,6 +420,7 @@ struct scmi_desc {
 	int max_rx_timeout_ms;
 	int max_msg;
 	int max_msg_size;
+	bool force_polling;
 };
 
 #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 01c79a8fa77f..a3700f49e8ac 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -656,6 +656,15 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
 		return;
 	}
 
+	/* Discard unexpected messages when polling is active. */
+	if (xfer->hdr.type != MSG_TYPE_DELAYED_RESP &&
+	    xfer->hdr.poll_completion) {
+		WARN_ON_ONCE(1);
+		dev_dbg(cinfo->dev,
+			"Completion IRQ received but using polling. Ignore.\n");
+		return;
+	}
+
 	/* rx.len could be shrunk in the sync do_xfer, so reset to maxsz */
 	if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP)
 		xfer->rx.len = info->desc->max_msg_size;
@@ -760,16 +769,19 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 	struct device *dev = info->dev;
 	struct scmi_chan_info *cinfo;
 
-	if (xfer->hdr.poll_completion && !info->desc->ops->poll_done) {
-		dev_warn_once(dev,
-			      "Polling mode is not supported by transport.\n");
-		return -EINVAL;
-	}
-
 	cinfo = idr_find(&info->tx_idr, pi->proto->id);
 	if (unlikely(!cinfo))
 		return -EINVAL;
 
+	if (info->desc->force_polling || cinfo->no_completion_irq) {
+		if (!info->desc->ops->poll_done) {
+			dev_warn_once(dev,
+				      "Polling mode is not supported by transport.\n");
+			return -EINVAL;
+		}
+		xfer->hdr.poll_completion = true;
+	}
+
 	/*
 	 * Initialise protocol id now from protocol handle to avoid it being
 	 * overridden by mistake (or malice) by the protocol code mangling with
@@ -1499,6 +1511,11 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
 	if (ret)
 		return ret;
 
+	if (tx && (cinfo->no_completion_irq || info->desc->force_polling))
+		dev_info(dev,
+			 "Enabled polling mode for TX channel - prot_id:%d\n",
+			 prot_id);
+
 idr_alloc:
 	ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
 	if (ret != prot_id) {
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:30 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:30 +0100
Subject: [PATCH v4 01/12] firmware: arm_scmi: Perform earlier cinfo lookup
 call in do_xfer
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-2-cristian.marussi@arm.com>

Lookup cinfo data early in do_xfer so as to avoid any further init work
on xfer structure in case of error.

No functional change.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index b406b3f78f46..01c79a8fa77f 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -766,6 +766,10 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 		return -EINVAL;
 	}
 
+	cinfo = idr_find(&info->tx_idr, pi->proto->id);
+	if (unlikely(!cinfo))
+		return -EINVAL;
+
 	/*
 	 * Initialise protocol id now from protocol handle to avoid it being
 	 * overridden by mistake (or malice) by the protocol code mangling with
@@ -774,10 +778,6 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 	xfer->hdr.protocol_id = pi->proto->id;
 	reinit_completion(&xfer->done);
 
-	cinfo = idr_find(&info->tx_idr, xfer->hdr.protocol_id);
-	if (unlikely(!cinfo))
-		return -EINVAL;
-
 	trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
 			      xfer->hdr.protocol_id, xfer->hdr.seq,
 			      xfer->hdr.poll_completion);
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:32 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:32 +0100
Subject: [PATCH v4 03/12] firmware: arm_scmi: Add support for atomic transports
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-4-cristian.marussi@arm.com>

An SCMI transport can declare itself as .atomic_capable in order to signal
to the SCMI core that all its transmit path can be executed in atomic
context: the core as a consequence will take care not to sleep to in the
corresponding rx path while waiting for a response or a delayed response.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/common.h |   3 +
 drivers/firmware/arm_scmi/driver.c | 167 ++++++++++++++++++++++-------
 2 files changed, 132 insertions(+), 38 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 67c761141a48..4ab310c2eae5 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -412,6 +412,8 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
  * @max_msg_size: Maximum size of data per message that can be handled.
  * @force_polling: Flag to force this whole transport to use SCMI core polling
  *		   mechanism instead of completion interrupts even if available.
+ * @atomic_capable: Flag to indicate that this transport is assured not to sleep
+ *		    on the TX path.
  */
 struct scmi_desc {
 	int (*transport_init)(void);
@@ -421,6 +423,7 @@ struct scmi_desc {
 	int max_msg;
 	int max_msg_size;
 	bool force_polling;
+	bool atomic_capable;
 };
 
 #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index a3700f49e8ac..2ca1602afd80 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -681,6 +681,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
 		scmi_clear_channel(info, cinfo);
 		complete(xfer->async_done);
 	} else {
+		/*
+		 * This same xfer->done completion is used in atomic mode as a
+		 * flag for polling.
+		 */
 		complete(&xfer->done);
 	}
 
@@ -733,8 +737,6 @@ static void xfer_put(const struct scmi_protocol_handle *ph,
 	__scmi_xfer_put(&info->tx_minfo, xfer);
 }
 
-#define SCMI_MAX_POLL_TO_NS	(100 * NSEC_PER_USEC)
-
 static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
 				      struct scmi_xfer *xfer, ktime_t stop)
 {
@@ -749,6 +751,90 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
 	       ktime_after(ktime_get(), stop);
 }
 
+static bool xfer_complete_or_timeout(struct completion *done, ktime_t stop)
+{
+	return try_wait_for_completion(done) || ktime_after(ktime_get(), stop);
+}
+
+static int spin_for_completion_timeout(struct completion *done, int timeout_ms)
+{
+	ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
+
+	spin_until_cond(xfer_complete_or_timeout(done, stop));
+	if (ktime_after(ktime_get(), stop))
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+/**
+ * scmi_wait_for_message_response  - An helper to group all the possible ways of
+ * waiting for a synchronous message response.
+ *
+ * @cinfo: SCMI channel info
+ * @xfer: Reference to the transfer being waited for.
+ *
+ * Chooses waiting strategy (sleep-waiting vs busy-waiting) depending on flags
+ * configuration like xfer->hdr.poll_completion and scmi_desc.atomic.capable.
+ *
+ * Return: 0 on Success, error otherwise.
+ */
+static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo,
+					  struct scmi_xfer *xfer)
+{
+	struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
+	struct device *dev = info->dev;
+	int ret = 0, timeout_ms = info->desc->max_rx_timeout_ms;
+
+	if (!xfer->hdr.poll_completion) {
+		if (!info->desc->atomic_capable) {
+			if (!wait_for_completion_timeout(&xfer->done,
+							 msecs_to_jiffies(timeout_ms))) {
+				dev_err(dev, "timed out in resp(caller: %pS)\n",
+					(void *)_RET_IP_);
+				ret = -ETIMEDOUT;
+			}
+		} else {
+			/* Poll on xfer->done waiting for completion by interrupt */
+			ret = spin_for_completion_timeout(&xfer->done,
+							  timeout_ms);
+			if (ret)
+				dev_err(dev,
+					"timed out in resp(caller: %pS) - atomic\n",
+					(void *)_RET_IP_);
+		}
+	} else {
+		/*
+		 * Poll on xfer using transport provided .poll_done();
+		 * assumes no completion interrupt was available.
+		 */
+		ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
+
+		spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
+		if (ktime_before(ktime_get(), stop)) {
+			unsigned long flags;
+
+			/*
+			 * Do not fetch_response if an out-of-order
+			 * delayed response is being processed.
+			 */
+			spin_lock_irqsave(&xfer->lock, flags);
+			if (xfer->state == SCMI_XFER_SENT_OK) {
+				info->desc->ops->fetch_response(cinfo, xfer);
+				xfer->state = SCMI_XFER_RESP_OK;
+			}
+			spin_unlock_irqrestore(&xfer->lock, flags);
+		} else {
+			dev_err(dev,
+				"timed out in resp(caller: %pS) - polling\n",
+				(void *)_RET_IP_);
+			ret = -ETIMEDOUT;
+		}
+	}
+
+	return ret;
+}
+
 /**
  * do_xfer() - Do one transfer
  *
@@ -763,7 +849,6 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 		   struct scmi_xfer *xfer)
 {
 	int ret;
-	int timeout;
 	const struct scmi_protocol_instance *pi = ph_to_pi(ph);
 	struct scmi_info *info = handle_to_scmi_info(pi->handle);
 	struct device *dev = info->dev;
@@ -810,36 +895,7 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
 		return ret;
 	}
 
-	if (xfer->hdr.poll_completion) {
-		ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
-
-		spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
-		if (ktime_before(ktime_get(), stop)) {
-			unsigned long flags;
-
-			/*
-			 * Do not fetch_response if an out-of-order delayed
-			 * response is being processed.
-			 */
-			spin_lock_irqsave(&xfer->lock, flags);
-			if (xfer->state == SCMI_XFER_SENT_OK) {
-				info->desc->ops->fetch_response(cinfo, xfer);
-				xfer->state = SCMI_XFER_RESP_OK;
-			}
-			spin_unlock_irqrestore(&xfer->lock, flags);
-		} else {
-			ret = -ETIMEDOUT;
-		}
-	} else {
-		/* And we wait for the response. */
-		timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
-		if (!wait_for_completion_timeout(&xfer->done, timeout)) {
-			dev_err(dev, "timed out in resp(caller: %pS)\n",
-				(void *)_RET_IP_);
-			ret = -ETIMEDOUT;
-		}
-	}
-
+	ret = scmi_wait_for_message_response(cinfo, xfer);
 	if (!ret && xfer->hdr.status)
 		ret = scmi_to_linux_errno(xfer->hdr.status);
 
@@ -861,7 +917,7 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph,
 	xfer->rx.len = info->desc->max_msg_size;
 }
 
-#define SCMI_MAX_RESPONSE_TIMEOUT	(2 * MSEC_PER_SEC)
+#define SCMI_DRESP_TIMEOUT	(2 * MSEC_PER_SEC)
 
 /**
  * do_xfer_with_response() - Do one transfer and wait until the delayed
@@ -870,22 +926,57 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph,
  * @ph: Pointer to SCMI protocol handle
  * @xfer: Transfer to initiate and wait for response
  *
+ * Avois sleeping in favour of busy-waiting if the underlying transport was
+ * declared as .atomic_capable.
+ *
+ * Note that using asynchronous commands when running on top of atomic
+ * transports should be avoided since it could cause long busy-waiting here,
+ * but, once a transport is declared atomic, upper layers using the SCMI stack
+ * can freely make assumptions about the 'non-sleeping' nature of the stack
+ * (e.g. Clock framework) and it cannot be excluded that asynchronous commands
+ * could be exposed by the platform and so used.
+ *
+ * The only other option would have been to refrain from using any asynchronous
+ * command even if made available, when an atomic transport is detected, and
+ * instead forcibly use the synchronous version (thing that can be easily
+ * attained at the protocol layer), but this would also have led to longer
+ * stalls of the channel for synchronous commands and possibly timeouts.
+ * (in other words there is usually a good reason if a platform provides an
+ *  asynchronous version of a command and we should prefer to use it)
+ *
  * Return: -ETIMEDOUT in case of no delayed response, if transmit error,
  *	return corresponding error, else if all goes well, return 0.
  */
 static int do_xfer_with_response(const struct scmi_protocol_handle *ph,
 				 struct scmi_xfer *xfer)
 {
-	int ret, timeout = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT);
+	int ret, timeout = msecs_to_jiffies(SCMI_DRESP_TIMEOUT);
+	const struct scmi_protocol_instance *pi = ph_to_pi(ph);
+	struct scmi_info *info = handle_to_scmi_info(pi->handle);
 	DECLARE_COMPLETION_ONSTACK(async_response);
 
 	xfer->async_done = &async_response;
 
 	ret = do_xfer(ph, xfer);
 	if (!ret) {
-		if (!wait_for_completion_timeout(xfer->async_done, timeout))
-			ret = -ETIMEDOUT;
-		else if (xfer->hdr.status)
+		if (!info->desc->atomic_capable) {
+			if (!wait_for_completion_timeout(xfer->async_done,
+							 timeout)) {
+				dev_err(ph->dev,
+					"timed out in delayed resp(caller: %pS)\n",
+					(void *)_RET_IP_);
+				ret = -ETIMEDOUT;
+			}
+		} else {
+			ret = spin_for_completion_timeout(xfer->async_done,
+							  SCMI_DRESP_TIMEOUT);
+			if (ret)
+				dev_err(ph->dev,
+					"timed out in delayed resp(caller: %pS) - atomic\n",
+					(void *)_RET_IP_);
+		}
+
+		if (!ret && xfer->hdr.status)
 			ret = scmi_to_linux_errno(xfer->hdr.status);
 	}
 
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:33 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:33 +0100
Subject: [PATCH v4 04/12] include: trace: Add new scmi_xfer_response_wait event
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-5-cristian.marussi@arm.com>

Having a new step to trace SCMI stack while it waits for synchronous
responses is useful to analyze system performance when changing waiting
mode between polling and interrupt completion.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 include/trace/events/scmi.h | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/include/trace/events/scmi.h b/include/trace/events/scmi.h
index f3a4b4d60714..ba82082f30d7 100644
--- a/include/trace/events/scmi.h
+++ b/include/trace/events/scmi.h
@@ -33,6 +33,34 @@ TRACE_EVENT(scmi_xfer_begin,
 		__entry->seq, __entry->poll)
 );
 
+TRACE_EVENT(scmi_xfer_response_wait,
+	TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
+		 bool poll, bool atomic),
+	TP_ARGS(transfer_id, msg_id, protocol_id, seq, poll, atomic),
+
+	TP_STRUCT__entry(
+		__field(int, transfer_id)
+		__field(u8, msg_id)
+		__field(u8, protocol_id)
+		__field(u16, seq)
+		__field(bool, poll)
+		__field(bool, atomic)
+	),
+
+	TP_fast_assign(
+		__entry->transfer_id = transfer_id;
+		__entry->msg_id = msg_id;
+		__entry->protocol_id = protocol_id;
+		__entry->seq = seq;
+		__entry->poll = poll;
+		__entry->atomic = atomic;
+	),
+
+	TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u poll=%u atomic=%u",
+		__entry->transfer_id, __entry->msg_id, __entry->protocol_id,
+		__entry->seq, __entry->poll, __entry->atomic)
+);
+
 TRACE_EVENT(scmi_xfer_end,
 	TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
 		 int status),
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:34 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:34 +0100
Subject: [PATCH v4 05/12] firmware: arm_scmi: Use new trace event
 scmi_xfer_response_wait
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-6-cristian.marussi@arm.com>

Use new trace event to mark start of waiting for response section.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 2ca1602afd80..1320a00a6339 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -786,6 +786,11 @@ static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo,
 	struct device *dev = info->dev;
 	int ret = 0, timeout_ms = info->desc->max_rx_timeout_ms;
 
+	trace_scmi_xfer_response_wait(xfer->transfer_id, xfer->hdr.id,
+				      xfer->hdr.protocol_id, xfer->hdr.seq,
+				      xfer->hdr.poll_completion,
+				      info->desc->atomic_capable);
+
 	if (!xfer->hdr.poll_completion) {
 		if (!info->desc->atomic_capable) {
 			if (!wait_for_completion_timeout(&xfer->done,
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:35 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:35 +0100
Subject: [PATCH v4 06/12] firmware: arm_scmi: Add is_transport_atomic() handle
 method
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-7-cristian.marussi@arm.com>

Add a method to check if the underlying transport configured for an SCMI
instance is configured to support atomic transaction of SCMI commands.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 16 ++++++++++++++++
 include/linux/scmi_protocol.h      |  8 ++++++++
 2 files changed, 24 insertions(+)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 1320a00a6339..852baac0e614 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -1416,6 +1416,21 @@ static void scmi_devm_protocol_put(struct scmi_device *sdev, u8 protocol_id)
 	WARN_ON(ret);
 }
 
+/**
+ * scmi_is_transport_atomic  - Method to check if underlying transport for an
+ * SCMI instance is configured as atomic.
+ *
+ * @handle: A reference to the SCMI platform instance.
+ *
+ * Return: True if transport is configured as atomic
+ */
+static bool scmi_is_transport_atomic(const struct scmi_handle *handle)
+{
+	struct scmi_info *info = handle_to_scmi_info(handle);
+
+	return info->desc->atomic_capable;
+}
+
 static inline
 struct scmi_handle *scmi_handle_get_from_info_unlocked(struct scmi_info *info)
 {
@@ -1948,6 +1963,7 @@ static int scmi_probe(struct platform_device *pdev)
 	handle->version = &info->version;
 	handle->devm_protocol_get = scmi_devm_protocol_get;
 	handle->devm_protocol_put = scmi_devm_protocol_put;
+	handle->is_transport_atomic = scmi_is_transport_atomic;
 
 	if (desc->ops->link_supplier) {
 		ret = desc->ops->link_supplier(dev);
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 80e781c51ddc..9f895cb81818 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -612,6 +612,13 @@ struct scmi_notify_ops {
  * @devm_protocol_get: devres managed method to acquire a protocol and get specific
  *		       operations and a dedicated protocol handler
  * @devm_protocol_put: devres managed method to release a protocol
+ * @is_transport_atomic: method to check if the underlying transport for this
+ *			 instance handle is configured to support atomic
+ *			 transactions for commands.
+ *			 Some users of the SCMI stack in the upper layers could
+ *			 be interested to know if they can assume SCMI
+ *			 command transactions associated to this handle will
+ *			 never sleep and act accordingly.
  * @notify_ops: pointer to set of notifications related operations
  */
 struct scmi_handle {
@@ -622,6 +629,7 @@ struct scmi_handle {
 		(*devm_protocol_get)(struct scmi_device *sdev, u8 proto,
 				     struct scmi_protocol_handle **ph);
 	void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);
+	bool (*is_transport_atomic)(const struct scmi_handle *handle);
 
 	const struct scmi_notify_ops *notify_ops;
 };
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:36 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:36 +0100
Subject: [PATCH v4 07/12] clk: scmi: Support atomic enable/disable API
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-8-cristian.marussi@arm.com>

Support enable/disable clk_ops instead of prepare/unprepare when the
underlying SCMI transport is configured to support atomic transactions for
synchronous commands.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/clk/clk-scmi.c | 44 +++++++++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 1e357d364ca2..a07117d5e5bd 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -88,21 +88,42 @@ static void scmi_clk_disable(struct clk_hw *hw)
 	scmi_proto_clk_ops->disable(clk->ph, clk->id);
 }
 
+/*
+ * We can provide enable/disable atomic callbacks only if the underlying SCMI
+ * transport for this SCMI instance is configured to handle synchronous commands
+ * in an atomic manner.
+ *
+ * When no SCMI atomic transport support is available we instead provide the
+ * prepare/unprepare API, as allowed by the clock framework where atomic calls
+ * are not available.
+ *
+ * Note that the provided clk_ops implementations are the same in both cases,
+ * using indeed the same underlying SCMI clock_protocol operations, it's just
+ * that they are assured to act in an atomic manner or not depending on the
+ * actual underlying SCMI transport configuration.
+ *
+ * Two distinct sets of clk_ops are provided since we could have multiple SCMI
+ * instances with different underlying transport quality, so they cannot be
+ * shared.
+ */
 static const struct clk_ops scmi_clk_ops = {
 	.recalc_rate = scmi_clk_recalc_rate,
 	.round_rate = scmi_clk_round_rate,
 	.set_rate = scmi_clk_set_rate,
-	/*
-	 * We can't provide enable/disable callback as we can't perform the same
-	 * in atomic context. Since the clock framework provides standard API
-	 * clk_prepare_enable that helps cases using clk_enable in non-atomic
-	 * context, it should be fine providing prepare/unprepare.
-	 */
 	.prepare = scmi_clk_enable,
 	.unprepare = scmi_clk_disable,
 };
 
-static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
+static const struct clk_ops scmi_atomic_clk_ops = {
+	.recalc_rate = scmi_clk_recalc_rate,
+	.round_rate = scmi_clk_round_rate,
+	.set_rate = scmi_clk_set_rate,
+	.enable = scmi_clk_enable,
+	.disable = scmi_clk_disable,
+};
+
+static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
+			     const struct clk_ops *scmi_ops)
 {
 	int ret;
 	unsigned long min_rate, max_rate;
@@ -110,7 +131,7 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
 	struct clk_init_data init = {
 		.flags = CLK_GET_RATE_NOCACHE,
 		.num_parents = 0,
-		.ops = &scmi_clk_ops,
+		.ops = scmi_ops,
 		.name = sclk->info->name,
 	};
 
@@ -145,6 +166,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 	struct device_node *np = dev->of_node;
 	const struct scmi_handle *handle = sdev->handle;
 	struct scmi_protocol_handle *ph;
+	bool is_atomic;
 
 	if (!handle)
 		return -ENODEV;
@@ -168,6 +190,8 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 	clk_data->num = count;
 	hws = clk_data->hws;
 
+	is_atomic = handle->is_transport_atomic(handle);
+
 	for (idx = 0; idx < count; idx++) {
 		struct scmi_clk *sclk;
 
@@ -184,7 +208,9 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 		sclk->id = idx;
 		sclk->ph = ph;
 
-		err = scmi_clk_ops_init(dev, sclk);
+		err = scmi_clk_ops_init(dev, sclk,
+					is_atomic ? &scmi_atomic_clk_ops :
+					&scmi_clk_ops);
 		if (err) {
 			dev_err(dev, "failed to register clock %d\n", idx);
 			devm_kfree(dev, sclk);
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:37 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:37 +0100
Subject: [PATCH v4 08/12] firmware: arm_scmi: Declare virtio transport
 .atomic_capable
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-9-cristian.marussi@arm.com>

SCMI virtio transport support does not contain any sleeping pattern, so
declare it as .atomic_capable.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/virtio.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
index 224577f86928..eabe430595f0 100644
--- a/drivers/firmware/arm_scmi/virtio.c
+++ b/drivers/firmware/arm_scmi/virtio.c
@@ -488,4 +488,5 @@ const struct scmi_desc scmi_virtio_desc = {
 	.max_rx_timeout_ms = 60000, /* for non-realtime virtio devices */
 	.max_msg = 0, /* overridden by virtio_get_max_msg() */
 	.max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
+	.atomic_capable = true,
 };
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:38 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:38 +0100
Subject: [PATCH v4 09/12] [RFC] firmware: arm_scmi: Make smc transport use
 common completions
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-10-cristian.marussi@arm.com>

When a completion irq is available use it and delegate command completion
handling to the core SCMI completion mechanism.

If no completion irq is available revert to polling, using the core common
polling machinery.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
v3 --> v4
- renamed usage of .needs_polling to .no_completion_irq
---
 drivers/firmware/arm_scmi/smc.c | 40 ++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index 4effecc3bb46..adaa40df3855 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -25,8 +25,6 @@
  * @shmem: Transmit/Receive shared memory area
  * @shmem_lock: Lock to protect access to Tx/Rx shared memory area
  * @func_id: smc/hvc call function id
- * @irq: Optional; employed when platforms indicates msg completion by intr.
- * @tx_complete: Optional, employed only when irq is valid.
  */
 
 struct scmi_smc {
@@ -34,15 +32,14 @@ struct scmi_smc {
 	struct scmi_shared_mem __iomem *shmem;
 	struct mutex shmem_lock;
 	u32 func_id;
-	int irq;
-	struct completion tx_complete;
 };
 
 static irqreturn_t smc_msg_done_isr(int irq, void *data)
 {
 	struct scmi_smc *scmi_info = data;
 
-	complete(&scmi_info->tx_complete);
+	scmi_rx_callback(scmi_info->cinfo,
+			 shmem_read_header(scmi_info->shmem), NULL);
 
 	return IRQ_HANDLED;
 }
@@ -111,8 +108,8 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 			dev_err(dev, "failed to setup SCMI smc irq\n");
 			return ret;
 		}
-		init_completion(&scmi_info->tx_complete);
-		scmi_info->irq = irq;
+	} else {
+		cinfo->no_completion_irq = true;
 	}
 
 	scmi_info->func_id = func_id;
@@ -142,26 +139,21 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
 	struct scmi_smc *scmi_info = cinfo->transport_info;
 	struct arm_smccc_res res;
 
+	/*
+	 * Channel lock will be released only once response has been
+	 * surely fully retrieved, so after .mark_txdone()
+	 */
 	mutex_lock(&scmi_info->shmem_lock);
-
 	shmem_tx_prepare(scmi_info->shmem, xfer);
 
-	if (scmi_info->irq)
-		reinit_completion(&scmi_info->tx_complete);
-
 	arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
 
-	if (scmi_info->irq)
-		wait_for_completion(&scmi_info->tx_complete);
-
-	scmi_rx_callback(scmi_info->cinfo,
-			 shmem_read_header(scmi_info->shmem), NULL);
-
-	mutex_unlock(&scmi_info->shmem_lock);
-
 	/* Only SMCCC_RET_NOT_SUPPORTED is valid error code */
-	if (res.a0)
+	if (res.a0) {
+		mutex_unlock(&scmi_info->shmem_lock);
 		return -EOPNOTSUPP;
+	}
+
 	return 0;
 }
 
@@ -173,6 +165,13 @@ static void smc_fetch_response(struct scmi_chan_info *cinfo,
 	shmem_fetch_response(scmi_info->shmem, xfer);
 }
 
+static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret)
+{
+	struct scmi_smc *scmi_info = cinfo->transport_info;
+
+	mutex_unlock(&scmi_info->shmem_lock);
+}
+
 static bool
 smc_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
 {
@@ -186,6 +185,7 @@ static const struct scmi_transport_ops scmi_smc_ops = {
 	.chan_setup = smc_chan_setup,
 	.chan_free = smc_chan_free,
 	.send_message = smc_send_message,
+	.mark_txdone = smc_mark_txdone,
 	.fetch_response = smc_fetch_response,
 	.poll_done = smc_poll_done,
 };
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:39 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:39 +0100
Subject: [PATCH v4 10/12] [RFC] firmware: arm_scmi: Make smc transport atomic
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-11-cristian.marussi@arm.com>

Substitute mutex usages with busy-waiting and declare smc transport as
.atomic_capable.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/smc.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index adaa40df3855..c13edaace8a3 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/atomic.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
@@ -14,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/processor.h>
 #include <linux/slab.h>
 
 #include "common.h"
@@ -23,14 +25,15 @@
  *
  * @cinfo: SCMI channel info
  * @shmem: Transmit/Receive shared memory area
- * @shmem_lock: Lock to protect access to Tx/Rx shared memory area
+ * @inflight: Atomic flag to protect access to Tx/Rx shared memory area
  * @func_id: smc/hvc call function id
  */
 
 struct scmi_smc {
 	struct scmi_chan_info *cinfo;
 	struct scmi_shared_mem __iomem *shmem;
-	struct mutex shmem_lock;
+#define INFLIGHT_NONE	MSG_TOKEN_MAX
+	atomic_t inflight;
 	u32 func_id;
 };
 
@@ -114,7 +117,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 
 	scmi_info->func_id = func_id;
 	scmi_info->cinfo = cinfo;
-	mutex_init(&scmi_info->shmem_lock);
+	atomic_set(&scmi_info->inflight, INFLIGHT_NONE);
 	cinfo->transport_info = scmi_info;
 
 	return 0;
@@ -133,6 +136,15 @@ static int smc_chan_free(int id, void *p, void *data)
 	return 0;
 }
 
+static bool smc_xfer_inflight(struct scmi_xfer *xfer, atomic_t *inflight)
+{
+	int ret;
+
+	ret = atomic_cmpxchg(inflight, INFLIGHT_NONE, xfer->hdr.seq);
+
+	return ret == INFLIGHT_NONE;
+}
+
 static int smc_send_message(struct scmi_chan_info *cinfo,
 			    struct scmi_xfer *xfer)
 {
@@ -140,17 +152,18 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
 	struct arm_smccc_res res;
 
 	/*
-	 * Channel lock will be released only once response has been
+	 * Channel will be released only once response has been
 	 * surely fully retrieved, so after .mark_txdone()
 	 */
-	mutex_lock(&scmi_info->shmem_lock);
+	spin_until_cond(smc_xfer_inflight(xfer, &scmi_info->inflight));
+
 	shmem_tx_prepare(scmi_info->shmem, xfer);
 
 	arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
 
 	/* Only SMCCC_RET_NOT_SUPPORTED is valid error code */
 	if (res.a0) {
-		mutex_unlock(&scmi_info->shmem_lock);
+		atomic_set(&scmi_info->inflight, INFLIGHT_NONE);
 		return -EOPNOTSUPP;
 	}
 
@@ -169,7 +182,7 @@ static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret)
 {
 	struct scmi_smc *scmi_info = cinfo->transport_info;
 
-	mutex_unlock(&scmi_info->shmem_lock);
+	atomic_set(&scmi_info->inflight, INFLIGHT_NONE);
 }
 
 static bool
@@ -195,4 +208,5 @@ const struct scmi_desc scmi_smc_desc = {
 	.max_rx_timeout_ms = 30,
 	.max_msg = 20,
 	.max_msg_size = 128,
+	.atomic_capable = true,
 };
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:40 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:40 +0100
Subject: [PATCH v4 11/12] [RFC] firmware: arm_scmi: Add
 sync_cmds_atomic_replies transport flag
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-12-cristian.marussi@arm.com>

A flag is added to let the transport signal the core that its handling of
synchronous command messages implies that, after .send_message has returned
successfully, the requested command can be assumed to be fully and
completely executed on SCMI platform side so that any possible response
value is already immediately available to be retrieved by a .fetch_reponse:
in other words the polling phase can be skipped in such a case and the
response values accessed straight away.

Note that all of the above applies only when polling mode of operation was
selected by the core: if instead a completion IRQ was found to be available
the normal response processing path based on completions will still be
followed.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/common.h |  8 ++++++++
 drivers/firmware/arm_scmi/driver.c | 29 +++++++++++++++++------------
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 4ab310c2eae5..2ce6b38d1270 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -412,6 +412,13 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
  * @max_msg_size: Maximum size of data per message that can be handled.
  * @force_polling: Flag to force this whole transport to use SCMI core polling
  *		   mechanism instead of completion interrupts even if available.
+ * @sync_cmds_atomic_replies: Flag to indicate that the transport assures
+ *			      synchronous-command messages are atomically
+ *			      completed on .send_message: no need to poll
+ *			      actively waiting for a response.
+ *			      Used by core internally only when polling is
+ *			      selected as a waiting for reply method: i.e.
+ *			      if a completion irq was found use that anyway.
  * @atomic_capable: Flag to indicate that this transport is assured not to sleep
  *		    on the TX path.
  */
@@ -423,6 +430,7 @@ struct scmi_desc {
 	int max_msg;
 	int max_msg_size;
 	bool force_polling;
+	bool sync_cmds_atomic_replies;
 	bool atomic_capable;
 };
 
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 852baac0e614..e17285f11ce3 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -809,14 +809,24 @@ static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo,
 					(void *)_RET_IP_);
 		}
 	} else {
-		/*
-		 * Poll on xfer using transport provided .poll_done();
-		 * assumes no completion interrupt was available.
-		 */
-		ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
+		if (!info->desc->sync_cmds_atomic_replies) {
+			/*
+			 * Poll on xfer using transport provided .poll_done();
+			 * assumes no completion interrupt was available.
+			 */
+			ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
+
+			spin_until_cond(scmi_xfer_done_no_timeout(cinfo,
+								  xfer, stop));
+			if (ktime_after(ktime_get(), stop)) {
+				dev_err(dev,
+					"timed out in resp(caller: %pS) - polling\n",
+					(void *)_RET_IP_);
+				ret = -ETIMEDOUT;
+			}
+		}
 
-		spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
-		if (ktime_before(ktime_get(), stop)) {
+		if (!ret) {
 			unsigned long flags;
 
 			/*
@@ -829,11 +839,6 @@ static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo,
 				xfer->state = SCMI_XFER_RESP_OK;
 			}
 			spin_unlock_irqrestore(&xfer->lock, flags);
-		} else {
-			dev_err(dev,
-				"timed out in resp(caller: %pS) - polling\n",
-				(void *)_RET_IP_);
-			ret = -ETIMEDOUT;
 		}
 	}
 
-- 
2.17.1



From cristian.marussi at arm.com  Tue Aug 24 06:59:41 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 24 Aug 2021 14:59:41 +0100
Subject: [PATCH v4 12/12] [RFC] firmware: arm_scmi: Make smc support atomic
 commands replies
In-Reply-To: <20210824135941.38656-1-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
Message-ID: <20210824135941.38656-13-cristian.marussi@arm.com>

Enable sync_cmds_atomic_replies in the SMC transport descriptor.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
NOTE THAT this flag is probably better to be also optionally settable
using an optional DT property to address the fact that the same
transport could expose or not this feature depending on where the SCMI
server sits.
(e.g. an SCMI server in S-EL1 accessed via smc dispatcher sitting in EL3)
---
 drivers/firmware/arm_scmi/smc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
index c13edaace8a3..479382f3cc96 100644
--- a/drivers/firmware/arm_scmi/smc.c
+++ b/drivers/firmware/arm_scmi/smc.c
@@ -209,4 +209,5 @@ const struct scmi_desc scmi_smc_desc = {
 	.max_msg = 20,
 	.max_msg_size = 128,
 	.atomic_capable = true,
+	.sync_cmds_atomic_replies = true,
 };
-- 
2.17.1



From robh at kernel.org  Tue Aug 24 07:25:41 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 09:25:41 -0500
Subject: [PATCH v2] dt-bindings: mmc: fsl-imx-esdhc: change the
 pinctrl-names rule
In-Reply-To: <1629373938-9226-1-git-send-email-haibo.chen@nxp.com>
References: <1629373938-9226-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <YSUBZbGOnl7C597b@robh.at.kernel.org>

On Thu, 19 Aug 2021 19:52:18 +0800, haibo.chen at nxp.com wrote:
> From: Haibo Chen <haibo.chen at nxp.com>
> 
> Change the pinctrl-names rule to cover all cases.
> 
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> ---
>  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml  | 17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Aug 24 07:30:26 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 09:30:26 -0500
Subject: [PATCH] dt-bindings: mfd: add Broadcom's MISC block
In-Reply-To: <20210819152552.23784-1-zajec5@gmail.com>
References: <20210819152552.23784-1-zajec5@gmail.com>
Message-ID: <YSUCgmC3pr7NbSDG@robh.at.kernel.org>

On Thu, 19 Aug 2021 17:25:52 +0200, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Broadcom's MISC is an MFD hardware block used on some of their SoCs like
> bcm63xx and bcm4908. At this point only PCIe reset is fully understood
> and documented. More functions may be added later.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
> Broadcom's BCM4908 struct with MISC block registers:
> 
> typedef struct Misc {
>    uint32 miscStrapBus; /* 0x00 */
>    uint32 miscStrapOverride;     /* 0x04 */
>    uint32 miscSoftwareDebug[6];  /* 0x08 */
>    uint32 miscWDResetCtrl;       /* 0x20 */
>    uint32 miscSoftwareDebugNW[2];/* 0x24 */
>    uint32 miscSoftResetB;        /* 0x2c */
>    uint32 miscQAMPllStatus;      /* 0x30 */
>    uint32 miscRsvd1;             /* 0x34 */
>    uint32 miscSpiMasterCtrl;     /* 0x38 */
>    uint32 miscAltBootVector;     /* 0x3c */
>    uint32 miscPeriphCtrl;        /* 0x40 */
>    uint32 miscPCIECtrl;          /* 0x44 */
>    uint32 miscAdsl_clock_sample; /* 0x48 */
>    uint32 miscRngCtrl;           /* 0x4c */
>    uint32 miscMbox_data[4];      /* 0x50 */
>    uint32 miscMbox_ctrl;         /* 0x60 */
>    uint32 miscxMIIPadCtrl[4];    /* 0x64 */
>    uint32 miscxMIIPullCtrl[4];    /* 0x74 */
>    uint32 miscWDResetEn;          /* 0x84 */
>    uint32 miscBootOverlayEn;      /* 0x88 */
>    uint32 miscSGMIIFiberDetect;   /* 0x8c */
>    uint32 miscUniMacCtrl;         /* 0x90 */
>    uint32 miscMaskUBUSErr;        /* 0x94 */
>    uint32 miscTOSsync;            /* 0x98 */
>    uint32 miscPM0_1_status;       /* 0x9c */
>    uint32 miscPM2_3_status;       /* 0xa0 */
>    uint32 miscSGB_status;         /* 0xa4 */
>    uint32 miscPM0_1_config;       /* 0xa8 */
>    uint32 miscPM2_3_config;       /* 0xac */
>    uint32 miscSGB_config;         /* 0xb0 */
>    uint32 miscPM0_1_tmon_config;  /* 0xb4 */
>    uint32 miscPM2_3_tmon_config;  /* 0xb8 */
>    uint32 miscSGB_tmon_config;    /* 0xbc */
>    uint32 miscMDIOmasterSelect;   /* 0xc0 */
>    uint32 miscUSIMCtrl;           /* 0xc4 */
>    uint32 miscUSIMPadCtrl;        /* 0xc8 */
>    uint32 miscPerSpareReg[3];     /* 0xcc - 0xd4 */
>    uint32 miscDgSensePadCtrl;     /* 0xd8 */
>    uint32 miscPeriphMiscCtrl;     /* 0xdc */
>    uint32 miscPeriphMiscStat;     /* 0xe0 */
> } Misc;
> ---
>  .../devicetree/bindings/mfd/brcm,misc.yaml    | 60 +++++++++++++++++++
>  1 file changed, 60 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/brcm,misc.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From will at kernel.org  Tue Aug 24 07:31:38 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 24 Aug 2021 15:31:38 +0100
Subject: [PATCH v9 2/2] drivers/perf: hisi: Add driver for HiSilicon PCIe
 PMU
In-Reply-To: <20210818051246.29545-3-liuqi115@huawei.com>
References: <20210818051246.29545-1-liuqi115@huawei.com>
 <20210818051246.29545-3-liuqi115@huawei.com>
Message-ID: <20210824143137.GA23146@willie-the-truck>

Hi,

On Wed, Aug 18, 2021 at 01:12:46PM +0800, Qi Liu wrote:
> PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported
> to sample bandwidth, latency, buffer occupation etc.
> 
> Each PMU RCiEP device monitors multiple Root Ports, and each RCiEP is
> registered as a PMU in /sys/bus/event_source/devices, so users can
> select target PMU, and use filter to do further sets.
> 
> Filtering options contains:
> event     - select the event.
> port      - select target Root Ports. Information of Root Ports are
>             shown under sysfs.
> bdf       - select requester_id of target EP device.
> trig_len  - set trigger condition for starting event statistics.
> trig_mode - set trigger mode. 0 means starting to statistic when bigger
>             than trigger condition, and 1 means smaller.
> thr_len   - set threshold for statistics.
> thr_mode  - set threshold mode. 0 means count when bigger than threshold,
>             and 1 means smaller.

I think this is getting there now, thanks for sticking with it. Just a
couple of comments below..

> +static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)
> +{
> +	struct perf_event *sibling, *leader = event->group_leader;
> +	int counters = 1;
> +
> +	if (!is_software_event(leader)) {
> +		if (leader->pmu != event->pmu)
> +			return false;
> +
> +		if (leader != event)
> +			counters++;
> +	}
> +
> +	for_each_sibling_event(sibling, event->group_leader) {
> +		if (is_software_event(sibling))
> +			continue;
> +
> +		if (sibling->pmu != event->pmu)
> +			return false;
> +
> +		counters++;
> +	}
> +
> +	return counters <= HISI_PCIE_MAX_COUNTERS;
> +}

Given that this function doesn't look at the event numbers, doesn't this
over-provision the counter registers? For example, if I create a group
containing 4 of the same event, then we'll allocate four counters but only
use one. Similarly, if I create a group containing two events, one for the
normal counter and one for the extended counter, then we'll again allocate
two counters instead of one.

Have I misunderstood?

> +static int hisi_pcie_pmu_event_init(struct perf_event *event)
> +{
> +	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	event->cpu = pcie_pmu->on_cpu;
> +
> +	if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event)))
> +		hwc->event_base = HISI_PCIE_EXT_CNT;
> +	else
> +		hwc->event_base = HISI_PCIE_CNT;
> +
> +	if (event->attr.type != event->pmu->type)
> +		return -ENOENT;
> +
> +	/* Sampling is not supported. */
> +	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
> +		return -EOPNOTSUPP;
> +
> +	if (!hisi_pcie_pmu_valid_filter(event, pcie_pmu)) {
> +		pci_err(pcie_pmu->pdev, "Invalid filter!\n");

Please remove this message, as it's triggerable from userspace.

Will


From robh at kernel.org  Tue Aug 24 07:38:16 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 09:38:16 -0500
Subject: [PATCH v2 7/9] dt-bindings: arm: fsl: clean-up all toradex
 boards/modules
In-Reply-To: <20210819220910.586819-8-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
 <20210819220910.586819-8-marcel@ziswiler.com>
Message-ID: <YSUEWO++4FrLS8LL@robh.at.kernel.org>

On Fri, 20 Aug 2021 00:09:08 +0200, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Simplify and unify the distinction between modules and carrier boards.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> Changes in v2:
> - New patch cleaning-up dt-bindings documentation.
> 
>  .../devicetree/bindings/arm/fsl.yaml          | 79 ++++++++++---------
>  1 file changed, 41 insertions(+), 38 deletions(-)
> 

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


From robh at kernel.org  Tue Aug 24 07:38:34 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 09:38:34 -0500
Subject: [PATCH v2 9/9] dt-bindings: arm: fsl: add
 toradex,colibri-imx6ull-emmc
In-Reply-To: <20210819220910.586819-10-marcel@ziswiler.com>
References: <20210819220910.586819-1-marcel@ziswiler.com>
 <20210819220910.586819-10-marcel@ziswiler.com>
Message-ID: <YSUEajJuiF5zQDBd@robh.at.kernel.org>

On Fri, 20 Aug 2021 00:09:10 +0200, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Add toradex,colibri-imx6ull-emmc for our new Colibri iMX6ULL 1GB (eMMC)
> Module and the carrier boards (so far only Colibri Evaluation Board) it
> may be mated in.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> Changes in v2:
> - New patch documenting dt-bindings.
> 
>  Documentation/devicetree/bindings/arm/fsl.yaml | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 

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


From robh at kernel.org  Tue Aug 24 07:39:01 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 09:39:01 -0500
Subject: [PATCH] dt-bindings: PCI: mediatek-gen3: Add support for MT8195
In-Reply-To: <20210820023521.30716-1-jianjun.wang@mediatek.com>
References: <20210820023521.30716-1-jianjun.wang@mediatek.com>
Message-ID: <YSUEhTbzz9x1UeaB@robh.at.kernel.org>

On Fri, Aug 20, 2021 at 10:35:21AM +0800, Jianjun Wang wrote:
> MT8195 is an ARM platform SoC which has the same PCIe IP with MT8192.
> 
> Signed-off-by: Jianjun Wang <jianjun.wang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> index 742206dbd965..dcebb1036207 100644
> --- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> @@ -48,7 +48,9 @@ allOf:
>  
>  properties:
>    compatible:
> -    const: mediatek,mt8192-pcie
> +    oneOf:
> +      - const: mediatek,mt8192-pcie
> +      - const: mediatek,mt8195-pcie

Use 'enum' instead of oneOf+const.

>  
>    reg:
>      maxItems: 1
> -- 
> 2.18.0
> 
> 


From skhan at linuxfoundation.org  Tue Aug 24 07:39:10 2021
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Tue, 24 Aug 2021 08:39:10 -0600
Subject: [PATCH linux-next] tools:signal: fix boolreturn.cocci warnings
In-Reply-To: <20210824065131.60346-1-deng.changcheng@zte.com.cn>
References: <20210824065131.60346-1-deng.changcheng@zte.com.cn>
Message-ID: <16561a4f-6043-cc5b-7a50-5be1ff10bfa5@linuxfoundation.org>

On 8/24/21 12:51 AM, CGEL wrote:
> From: Jing Yangyang <jing.yangyang at zte.com.cn>
> 
> ./tools/testing/selftests/arm64/signal/test_signals_utils.h:112:9-10
> WARNING: return of 0/1 in function 'get_current_context' with
> return type bool
> 
> Return statements in functions returning bool should use true/false
> instead of 1/0.
> 
> Generated by: scripts/coccinelle/misc/boolreturn.cocci
> 
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: Jing Yangyang <jing.yangyang at zte.com.cn>
> ---
>   tools/testing/selftests/arm64/signal/test_signals_utils.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
> index 6772b5c..66122e6 100644
> --- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
> @@ -109,7 +109,7 @@ static __always_inline bool get_current_context(struct tdescr *td,
>   	if (seen_already) {
>   		fprintf(stdout,
>   			"Unexpected successful sigreturn detected: live_uc is stale !\n");
> -		return 0;
> +		return false;
>   	}
>   	seen_already = 1;
>   
> 

We can't accept this patch. The from and Signed-off-by don't match.

thanks,
-- Shuah


From robh at kernel.org  Tue Aug 24 07:40:19 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 09:40:19 -0500
Subject: [PATCH] dt-bindings: PCI: mediatek-gen3: Add support for MT8195
In-Reply-To: <20210820023521.30716-1-jianjun.wang@mediatek.com>
References: <20210820023521.30716-1-jianjun.wang@mediatek.com>
Message-ID: <YSUE08dgiGhFsjwH@robh.at.kernel.org>

On Fri, Aug 20, 2021 at 10:35:21AM +0800, Jianjun Wang wrote:
> MT8195 is an ARM platform SoC which has the same PCIe IP with MT8192.

If it is the same, then 8192 should be a fallback compatible. 'The same' 
means the current driver for 8192 will work unchanged.

> 
> Signed-off-by: Jianjun Wang <jianjun.wang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> index 742206dbd965..dcebb1036207 100644
> --- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> @@ -48,7 +48,9 @@ allOf:
>  
>  properties:
>    compatible:
> -    const: mediatek,mt8192-pcie
> +    oneOf:
> +      - const: mediatek,mt8192-pcie
> +      - const: mediatek,mt8195-pcie
>  
>    reg:
>      maxItems: 1
> -- 
> 2.18.0
> 
> 


From robh at kernel.org  Tue Aug 24 07:44:39 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 09:44:39 -0500
Subject: [v2 01/24] dt-bindings: ARM: Mediatek: Add new document bindings
 of MT8195 clock
In-Reply-To: <CAGXv+5FAEFD+dQsZzyZOzmwDDnwLZO3Z8wv8Z-=wVYdjjc3FYg@mail.gmail.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-2-chun-jie.chen@mediatek.com>
 <CAGXv+5FAEFD+dQsZzyZOzmwDDnwLZO3Z8wv8Z-=wVYdjjc3FYg@mail.gmail.com>
Message-ID: <YSUF18AZ2HgOnkce@robh.at.kernel.org>

On Mon, Aug 23, 2021 at 02:53:34PM +0800, Chen-Yu Tsai wrote:
> Hi,
> 
> On Fri, Aug 20, 2021 at 7:17 PM Chun-Jie Chen
> <chun-jie.chen at mediatek.com> wrote:
> >
> > This patch adds the new binding documentation for system clock
> > and functional clock on Mediatek MT8195.
> >
> > Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > ---
> >  .../arm/mediatek/mediatek,mt8195-clock.yaml   | 254 ++++++++++++++++++
> >  .../mediatek/mediatek,mt8195-sys-clock.yaml   |  73 +++++
> >  2 files changed, 327 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
> >  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-sys-clock.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
> > new file mode 100644
> > index 000000000000..17fcbb45d121
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
> > @@ -0,0 +1,254 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8195-clock.yaml#"
> > +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> > +
> > +title: MediaTek Functional Clock Controller for MT8195
> > +
> > +maintainers:
> > +  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
> > +
> > +description:
> > +  The clock architecture in Mediatek like below
> > +  PLLs -->
> > +          dividers -->
> > +                      muxes
> > +                           -->
> > +                              clock gate
> > +
> > +  The devices except apusys_pll provide clock gate control in different IP blocks.
> > +  The apusys_pll provides Plls which generated from SoC 26m for AI Processing Unit.
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - enum:
> > +          - mediatek,mt8195-scp_adsp
> > +          - mediatek,mt8195-imp_iic_wrap_s
> > +          - mediatek,mt8195-imp_iic_wrap_w
> > +          - mediatek,mt8195-mfgcfg
> > +          - mediatek,mt8195-vppsys0
> > +          - mediatek,mt8195-wpesys
> > +          - mediatek,mt8195-wpesys_vpp0
> > +          - mediatek,mt8195-wpesys_vpp1
> > +          - mediatek,mt8195-vppsys1
> > +          - mediatek,mt8195-imgsys
> > +          - mediatek,mt8195-imgsys1_dip_top
> > +          - mediatek,mt8195-imgsys1_dip_nr
> > +          - mediatek,mt8195-imgsys1_wpe
> > +          - mediatek,mt8195-ipesys
> > +          - mediatek,mt8195-camsys
> > +          - mediatek,mt8195-camsys_rawa
> > +          - mediatek,mt8195-camsys_yuva
> > +          - mediatek,mt8195-camsys_rawb
> > +          - mediatek,mt8195-camsys_yuvb
> > +          - mediatek,mt8195-camsys_mraw
> > +          - mediatek,mt8195-ccusys
> > +          - mediatek,mt8195-vdecsys_soc
> > +          - mediatek,mt8195-vdecsys
> > +          - mediatek,mt8195-vdecsys_core1
> > +          - mediatek,mt8195-vencsys
> > +          - mediatek,mt8195-vencsys_core1
> > +          - mediatek,mt8195-apusys_pll
> 
> The indentation is slightly off by 2 extra spaces.

No it's not. Indentation is always 2 more that the prior keyword. If in 
doubt, make sure yamllint is installed and this is checked as part of 
the build.

Rob


From ulf.hansson at linaro.org  Tue Aug 24 07:56:34 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 24 Aug 2021 16:56:34 +0200
Subject: [PATCH] dt-bindings: mmc: fsl-imx-esdhc: add a new compatible
 string
In-Reply-To: <1629278277-7313-1-git-send-email-haibo.chen@nxp.com>
References: <1629278277-7313-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <CAPDyKFouXOzV4Lfk4v2Hrj_OPg5jL7h_WoNnM2sH3h44q+6NRA@mail.gmail.com>

On Wed, 18 Aug 2021 at 11:39, <haibo.chen at nxp.com> wrote:
>
> From: Haibo Chen <haibo.chen at nxp.com>
>
> Lack a compatible string "fsl,imx6sll-usdhc", so add it here.
>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> index 8a9f1775b0e2..1457eb21473e 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> @@ -29,6 +29,7 @@ properties:
>            - fsl,imx53-esdhc
>            - fsl,imx6q-usdhc
>            - fsl,imx6sl-usdhc
> +          - fsl,imx6sll-usdhc
>            - fsl,imx6sx-usdhc
>            - fsl,imx6ull-usdhc
>            - fsl,imx7d-usdhc
> --
> 2.17.1
>


From ulf.hansson at linaro.org  Tue Aug 24 07:56:38 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 24 Aug 2021 16:56:38 +0200
Subject: [PATCH v2] dt-bindings: mmc: fsl-imx-esdhc: change the
 pinctrl-names rule
In-Reply-To: <1629373938-9226-1-git-send-email-haibo.chen@nxp.com>
References: <1629373938-9226-1-git-send-email-haibo.chen@nxp.com>
Message-ID: <CAPDyKFojnR8W4g+8dVQ+i9XPSDpb-vDCrq38ZhnhmkyqyoyTqg@mail.gmail.com>

On Thu, 19 Aug 2021 at 14:14, <haibo.chen at nxp.com> wrote:
>
> From: Haibo Chen <haibo.chen at nxp.com>
>
> Change the pinctrl-names rule to cover all cases.
>
> Signed-off-by: Haibo Chen <haibo.chen at nxp.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml  | 17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> index d7c8e5880473..f04728145275 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> @@ -124,12 +124,17 @@ properties:
>        - const: per
>
>    pinctrl-names:
> -    minItems: 1
> -    items:
> -      - const: default
> -      - const: state_100mhz
> -      - const: state_200mhz
> -      - const: sleep
> +    oneOf:
> +      - minItems: 3
> +        items:
> +          - const: default
> +          - const: state_100mhz
> +          - const: state_200mhz
> +          - const: sleep
> +      - minItems: 1
> +        items:
> +          - const: default
> +          - const: sleep
>
>  required:
>    - compatible
> --
> 2.17.1
>


From ulf.hansson at linaro.org  Tue Aug 24 07:56:42 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 24 Aug 2021 16:56:42 +0200
Subject: [PATCH v3 0/4] mmc: pwrseq: sd8787: add support wilc1000 devices
In-Reply-To: <20210820092803.78523-1-claudiu.beznea@microchip.com>
References: <20210820092803.78523-1-claudiu.beznea@microchip.com>
Message-ID: <CAPDyKFrcBS2tf32H9+wsy7=TsHkaqtw0cZcSAgZc3XjnLzJ__w@mail.gmail.com>

On Fri, 20 Aug 2021 at 11:30, Claudiu Beznea
<claudiu.beznea at microchip.com> wrote:
>
> Hi,
>
> This series adds support for WILC1000 devices on pwrseq-sd8787 driver.
> WILC1000 devices needs a minimum delay of 5ms b/w reset and power lines.
> Adapt the sd8787 driver for this by adding a new compatible for WILC1000
> devices and specify the delay on .data field of struct of_device_id.
>
> Thank you,
> Claudiu Beznea
>
> Changes in v3:
> - fixed dt binding compilation
>
> Changes in v2:
> - changed cover letter title (it was: mmc: pwrseq: sd8787: add support
>   for selectable)
> - use new compatible in pwrseq-sd8787 driver instead of adding a new
>   binding for specifying the delay; with this, the patch 1/1 from v1 is
>   not necessary
> - adapt patch 3/3 from this version with the new compatible
>
>
> Claudiu Beznea (3):
>   dt-bindings: pwrseq-sd8787: add binding for wilc1000
>   mmc: pwrseq: sd8787: add support for wilc1000
>   mmc: pwrseq: add wilc1000_sdio dependency for pwrseq_sd8787
>
> Eugen Hristev (1):
>   ARM: dts: at91: sama5d27_wlsom1: add wifi device
>
>  .../bindings/mmc/mmc-pwrseq-sd8787.yaml       |  4 +-
>  arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi   | 71 +++++++++++++++++++
>  drivers/mmc/core/Kconfig                      |  2 +-
>  drivers/mmc/core/pwrseq_sd8787.c              | 11 ++-
>  4 files changed, 84 insertions(+), 4 deletions(-)
>

Applied patch1 -> patch3, thanks! I leave patch 4 for soc maintainers.

Kind regards
Uffe


From linux at roeck-us.net  Tue Aug 24 08:06:17 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Tue, 24 Aug 2021 08:06:17 -0700
Subject: [RESEND v8,0/2] watchdog: mt8195: add wdt support
In-Reply-To: <20210824062633.14374-1-Christine.Zhu@mediatek.com>
References: <20210824062633.14374-1-Christine.Zhu@mediatek.com>
Message-ID: <20210824150617.GA3394785@roeck-us.net>

Hi,

On Tue, Aug 24, 2021 at 02:26:32PM +0800, Christine Zhu wrote:
> Supports MT8195 watchdog device. Supports MT8195 watchdog reset-controller feature.
> 

The series is already queued in my watchdog-next branch; no need to resend.
We'll have to wait for Wim to pick it up from there.

Thanks,
Guenter


From broonie at kernel.org  Tue Aug 24 08:10:15 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 24 Aug 2021 16:10:15 +0100
Subject: [PATCH] arm64: Do not trap PMSNEVFR_EL1
In-Reply-To: <20210824132459.562923-1-alexandru.elisei@arm.com>
References: <20210824132459.562923-1-alexandru.elisei@arm.com>
Message-ID: <20210824151015.GB4393@sirena.org.uk>

On Tue, Aug 24, 2021 at 02:24:59PM +0100, Alexandru Elisei wrote:

> Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed
> the fine grained trap registers to prevent unwanted register traps from
> occuring. However, for the PMSNEVFR_EL1 register, the corresponding
> HDFGRTR_EL2.nPMSNEVFR_EL1 field must be 1 to disable trapping. Set the
> field to 1 if FEAT_SPEv1p2 is detected.

Oh, that's a shame :/  I wonder why this feature is different to the
others, I just had a quick check and didn't see any other issues but...

> Based on v5.14-rc7. Also, we could write 1 << 62 to HDFGRTR_EL2 unconditionally
> since the field is RAZ/WI if !FEAT_SPEv1p2. I don't have a strong preference for
> either approaches, but I chose this implementation because it's clearer (even
> though it's more verbose and it's one extra trap on NV).

Yes, the explicit feature check is both clearer and more conservative -
it's unlikely to have a practical impact but 

> At this point, I am inclined to think it's a model bug because reading works,
> but writing causes a hang and that looks very suspicious to me. I'm going to
> open a model bug internally and see what comes of it.

...are you sure this isn't that the same issue also exists with the
equivalent field HDFGWTR_EL2 - glancing at the XML it appears to have
the same issue?  One of the fine grained aspects of fine grained traps
is that there's separate read and write traps!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210824/d8fd79a0/attachment-0001.sig>

From robh at kernel.org  Tue Aug 24 08:17:40 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 10:17:40 -0500
Subject: [v2 02/24] clk: mediatek: Add dt-bindings of MT8195 clocks
In-Reply-To: <20210820111504.350-3-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-3-chun-jie.chen@mediatek.com>
Message-ID: <YSUNlPq2jY6ZM09J@robh.at.kernel.org>

On Fri, 20 Aug 2021 19:14:42 +0800, Chun-Jie Chen wrote:
> Add MT8195 clock dt-bindings, include topckgen, apmixedsys,
> infracfg_ao, pericfg_ao and subsystem clocks.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  include/dt-bindings/clock/mt8195-clk.h | 864 +++++++++++++++++++++++++
>  1 file changed, 864 insertions(+)
>  create mode 100644 include/dt-bindings/clock/mt8195-clk.h
> 

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


From will at kernel.org  Tue Aug 24 08:26:22 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 24 Aug 2021 16:26:22 +0100
Subject: [PATCH v9 1/3] arm64: perf: Add userspace counter access disable
 switch
In-Reply-To: <20210806225123.1958497-2-robh@kernel.org>
References: <20210806225123.1958497-1-robh@kernel.org>
 <20210806225123.1958497-2-robh@kernel.org>
Message-ID: <20210824152621.GB23146@willie-the-truck>

On Fri, Aug 06, 2021 at 04:51:21PM -0600, Rob Herring wrote:
> Like x86, some users may want to disable userspace PMU counter
> altogether. Add a sysctl 'perf_user_access' file to control userspace
> counter access. The default is '0' which is disabled. Writing '1'
> enables access.
> 
> Note that x86 also supports writing '2' to globally enable user access.
> As there's not existing userspace support to worry about, this shouldn't
> be necessary for Arm. It could be added later if the need arises.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
> Cc: Jiri Olsa <jolsa at redhat.com>
> Cc: Namhyung Kim <namhyung at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-perf-users at vger.kernel.org
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
> v9:
>  - Use sysctl instead of sysfs attr
>  - Default to disabled
> v8:
>  - New patch
> 
> ---
>  arch/arm64/kernel/perf_event.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> index d07788dad388..74f77b68f5f0 100644
> --- a/arch/arm64/kernel/perf_event.c
> +++ b/arch/arm64/kernel/perf_event.c
> @@ -286,6 +286,21 @@ static const struct attribute_group armv8_pmuv3_events_attr_group = {
>  PMU_FORMAT_ATTR(event, "config:0-15");
>  PMU_FORMAT_ATTR(long, "config1:0");
>  
> +static int sysctl_perf_user_access __read_mostly;
> +
> +static struct ctl_table armv8_pmu_sysctl_table[] = {
> +	{
> +		.procname       = "perf_user_access",
> +		.data		= &sysctl_perf_user_access,
> +		.maxlen		= sizeof(unsigned int),
> +		.mode           = 0644,
> +		.proc_handler	= proc_dointvec_minmax,
> +		.extra1		= SYSCTL_ZERO,
> +		.extra2		= SYSCTL_ONE,
> +	},
> +	{ }
> +};

This should be documented somewhere. Maybe add an entry to
Documentation/admin-guide/sysctl/kernel.rst which points at the doc in patch
3, which needs updating to talk about this control?

Otherwise, looks good:

Acked-by: Will Deacon <will at kernel.org>

Will


From Claudiu.Beznea at microchip.com  Tue Aug 24 08:26:35 2021
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Tue, 24 Aug 2021 15:26:35 +0000
Subject: [PATCH v3 4/4] ARM: dts: at91: sama5d27_wlsom1: add wifi device
In-Reply-To: <YSTk1pUTAUJLBJQl@robh.at.kernel.org>
References: <20210820092803.78523-1-claudiu.beznea@microchip.com>
 <20210820092803.78523-5-claudiu.beznea@microchip.com>
 <YSTk1pUTAUJLBJQl@robh.at.kernel.org>
Message-ID: <2ccefcb4-cf6a-a675-4ff3-b7a2d314333a@microchip.com>

On 24.08.2021 15:23, Rob Herring wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Fri, Aug 20, 2021 at 12:28:03PM +0300, Claudiu Beznea wrote:
>> From: Eugen Hristev <eugen.hristev at microchip.com>
>>
>> SAMA5D27 WLSOM1 boards has a WILC3000 device soldered. Add proper
>> device tree nodes for this.
>>
>> [eugen.hristev: original author of this code]
>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>> [nicolas.ferre: original author of this code]
>> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
>> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
>> ---
>>  arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi | 71 +++++++++++++++++++++
>>  1 file changed, 71 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
>> index 025a78310e3a..c7bcfd3ce91d 100644
>> --- a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
>> +++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
>> @@ -30,6 +30,15 @@ main_xtal {
>>                       clock-frequency = <24000000>;
>>               };
>>       };
>> +
>> +     wifi_pwrseq: wifi_pwrseq {
>> +             compatible = "mmc-pwrseq-wilc1000";
>> +             reset-gpios = <&pioA PIN_PA27 GPIO_ACTIVE_HIGH>;
>> +             powerdown-gpios = <&pioA PIN_PA29 GPIO_ACTIVE_HIGH>;
>> +             pinctrl-0 = <&pinctrl_wilc_pwrseq>;
>> +             pinctrl-names = "default";
>> +             status = "okay";
> 
> 'okay' is the default, so you can drop this.
> 
>> +     };
>>  };
>>
>>  &flx1 {
>> @@ -310,5 +319,67 @@ pinctrl_qspi1_default: qspi1_default {
>>                        <PIN_PB10__QSPI1_IO3>;
>>               bias-pull-up;
>>       };
>> +
>> +     pinctrl_sdmmc1_default: sdmmc1_default {
>> +             cmd-data {
>> +                     pinmux = <PIN_PA28__SDMMC1_CMD>,
>> +                              <PIN_PA18__SDMMC1_DAT0>,
>> +                              <PIN_PA19__SDMMC1_DAT1>,
>> +                              <PIN_PA20__SDMMC1_DAT2>,
>> +                              <PIN_PA21__SDMMC1_DAT3>;
>> +                     bias-disable;
>> +             };
>> +
>> +             conf-ck {
>> +                     pinmux = <PIN_PA22__SDMMC1_CK>;
>> +                     bias-disable;
>> +             };
>> +     };
>> +
>> +     pinctrl_wilc_default: wilc_default {
>> +             conf-irq {
>> +                     pinmux = <PIN_PB25__GPIO>;
>> +                     bias-disable;
>> +             };
>> +     };
>> +
>> +     pinctrl_wilc_pwrseq: wilc_pwrseq {
>> +             conf-ce-nrst {
>> +                     pinmux = <PIN_PA27__GPIO>,
>> +                              <PIN_PA29__GPIO>;
>> +                     bias-disable;
>> +             };
>> +
>> +             conf-rtcclk {
>> +                     pinmux = <PIN_PB13__PCK1>;
>> +                     bias-disable;
>> +             };
>> +     };
>> +};
>> +
>> +&sdmmc1 {
>> +     #address-cells = <1>;
>> +     #size-cells = <0>;
>> +     bus-width = <4>;
>> +     pinctrl-names = "default";
>> +     pinctrl-0 = <&pinctrl_sdmmc1_default>;
>> +     mmc-pwrseq = <&wifi_pwrseq>;
>> +     no-1-8-v;
>> +     non-removable;
>> +     status = "okay";
>> +
>> +     wilc: wilc at 0 {
> 
> wifi at 0
> 
>> +             reg = <0>;
>> +             bus-width = <4>;
>> +             compatible = "microchip,wilc3000", "microchip,wilc1000";
>> +             pinctrl-names = "default";
>> +             pinctrl-0 = <&pinctrl_wilc_default>;
>> +             irq-gpios = <&pioA PIN_PB25 GPIO_ACTIVE_LOW>;
>> +             clocks = <&pmc PMC_TYPE_SYSTEM 9>;
>> +             clock-names = "rtc";
>> +             assigned-clocks = <&pmc PMC_TYPE_SYSTEM 9>;
>> +             assigned-clock-rates = <32768>;
>> +             status = "okay";
> 
> Again, that's the default so drop.
> 
> Did you run validation (make dtbs_check) on your changes because I see
> multiple problems.

No, I haven't. Apologies! I'll do the proper adjustments in v3.

Thank you for your review,
Claudiu Beznea

> 
> Rob
> 


From will at kernel.org  Tue Aug 24 08:27:20 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 24 Aug 2021 16:27:20 +0100
Subject: [PATCH v9 2/3] arm64: perf: Enable PMU counter userspace access
 for perf event
In-Reply-To: <20210806225123.1958497-3-robh@kernel.org>
References: <20210806225123.1958497-1-robh@kernel.org>
 <20210806225123.1958497-3-robh@kernel.org>
Message-ID: <20210824152720.GC23146@willie-the-truck>

On Fri, Aug 06, 2021 at 04:51:22PM -0600, Rob Herring wrote:
> Arm PMUs can support direct userspace access of counters which allows for
> low overhead (i.e. no syscall) self-monitoring of tasks. The same feature
> exists on x86 called 'rdpmc'. Unlike x86, userspace access will only be
> enabled for thread bound events. This could be extended if needed, but
> simplifies the implementation and reduces the chances for any
> information leaks (which the x86 implementation suffers from).
> 
> When an event is capable of userspace access and has been mmapped, userspace
> access is enabled when the event is scheduled on a CPU's PMU. There's some
> additional overhead clearing counters when disabled in order to prevent
> leaking disabled counter data from other tasks.
> 
> Unlike x86, enabling of userspace access must be requested with a new
> attr bit: config1:1. If the user requests userspace access and 64-bit
> counters, then chaining will be disabled and the user will get the
> maximum size counter the underlying h/w can support. The modes for
> config1 are as follows:
> 
> config1 = 0 : user access disabled and always 32-bit
> config1 = 1 : user access disabled and always 64-bit (using chaining if needed)
> config1 = 2 : user access enabled and always 32-bit
> config1 = 3 : user access enabled and counter size matches underlying counter.
> 
> Based on work by Raphael Gault <raphael.gault at arm.com>, but has been
> completely re-written.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
> Cc: Jiri Olsa <jolsa at redhat.com>
> Cc: Namhyung Kim <namhyung at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-perf-users at vger.kernel.org
> Signed-off-by: Rob Herring <robh at kernel.org>
> 
> ---
> v9:
>  - Enabling/disabling of user access is now controlled in .start() and
>    mmap hooks which are now called on CPUs that the event is on.
>    Depends on rework of perf core and x86 RDPMC code posted here:
>    https://lore.kernel.org/lkml/20210728230230.1911468-1-robh at kernel.org/
> 
> v8:
>  - Rework user access tracking and enabling to be done on task
>    context changes using sched_task() hook. This avoids the need for any
>    IPIs, mm_switch hooks or undef instr handler.
>  - Only support user access when explicitly requested on open and
>    only for a thread bound events. This avoids some of the information
>    leaks x86 has and simplifies the implementation.
> 
> v7:
>  - Clear disabled counters when user access is enabled for a task to
>    avoid leaking other tasks counter data.
>  - Rework context switch handling utilizing sched_task callback
>  - Add armv8pmu_event_can_chain() helper
>  - Rework config1 flags handling structure
>  - Use ARMV8_IDX_CYCLE_COUNTER_USER define for remapped user cycle
>    counter index
> 
> v6:
>  - Add new attr.config1 rdpmc bit for userspace to hint it wants
>    userspace access when also requesting 64-bit counters.
> 
> v5:
>  - Only set cap_user_rdpmc if event is on current cpu
>  - Limit enabling/disabling access to CPUs associated with the PMU
>    (supported_cpus) and with the mm_struct matching current->active_mm.
> 
> v2:
>  - Move mapped/unmapped into arm64 code. Fixes arm32.
>  - Rebase on cap_user_time_short changes
> 
> Changes from Raphael's v4:
>   - Drop homogeneous check
>   - Disable access for chained counters
>   - Set pmc_width in user page
> ---
>  arch/arm64/kernel/perf_event.c | 137 +++++++++++++++++++++++++++++++--
>  include/linux/perf/arm_pmu.h   |   6 ++
>  2 files changed, 135 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> index 74f77b68f5f0..66d8bf62e99c 100644
> --- a/arch/arm64/kernel/perf_event.c
> +++ b/arch/arm64/kernel/perf_event.c
> @@ -285,6 +285,7 @@ static const struct attribute_group armv8_pmuv3_events_attr_group = {
>  
>  PMU_FORMAT_ATTR(event, "config:0-15");
>  PMU_FORMAT_ATTR(long, "config1:0");
> +PMU_FORMAT_ATTR(rdpmc, "config1:1");
>  
>  static int sysctl_perf_user_access __read_mostly;
>  
> @@ -306,9 +307,15 @@ static inline bool armv8pmu_event_is_64bit(struct perf_event *event)
>  	return event->attr.config1 & 0x1;
>  }
>  
> +static inline bool armv8pmu_event_want_user_access(struct perf_event *event)
> +{
> +	return event->attr.config1 & 0x2;
> +}
> +
>  static struct attribute *armv8_pmuv3_format_attrs[] = {
>  	&format_attr_event.attr,
>  	&format_attr_long.attr,
> +	&format_attr_rdpmc.attr,
>  	NULL,
>  };
>  
> @@ -377,7 +384,7 @@ static const struct attribute_group armv8_pmuv3_caps_attr_group = {
>   */
>  #define	ARMV8_IDX_CYCLE_COUNTER	0
>  #define	ARMV8_IDX_COUNTER0	1
> -
> +#define	ARMV8_IDX_CYCLE_COUNTER_USER	32
>  
>  /*
>   * We unconditionally enable ARMv8.5-PMU long event counter support
> @@ -389,6 +396,15 @@ static bool armv8pmu_has_long_event(struct arm_pmu *cpu_pmu)
>  	return (cpu_pmu->pmuver >= ID_AA64DFR0_PMUVER_8_5);
>  }
>  
> +static inline bool armv8pmu_event_can_chain(struct perf_event *event)
> +{
> +	struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
> +
> +	return !(event->hw.flags & PERF_EVENT_FLAG_USER_READ_CNT) &&
> +	       armv8pmu_event_is_64bit(event) &&
> +	       !armv8pmu_has_long_event(cpu_pmu);

Could check against ARMV8_IDX_CYCLE_COUNTER here...

> +}
> +
>  /*
>   * We must chain two programmable counters for 64 bit events,
>   * except when we have allocated the 64bit cycle counter (for CPU
> @@ -398,11 +414,9 @@ static bool armv8pmu_has_long_event(struct arm_pmu *cpu_pmu)
>  static inline bool armv8pmu_event_is_chained(struct perf_event *event)
>  {
>  	int idx = event->hw.idx;
> -	struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
>  
>  	return !WARN_ON(idx < 0) &&
> -	       armv8pmu_event_is_64bit(event) &&
> -	       !armv8pmu_has_long_event(cpu_pmu) &&
> +	       armv8pmu_event_can_chain(event) &&
>  	       (idx != ARMV8_IDX_CYCLE_COUNTER);

... then we wouldn't need to here.

>  }
>  
> @@ -733,6 +747,35 @@ static inline u32 armv8pmu_getreset_flags(void)
>  	return value;
>  }
>  
> +static void armv8pmu_disable_user_access(void)
> +{
> +	write_sysreg(0, pmuserenr_el0);
> +}
> +
> +static void armv8pmu_enable_user_access(struct arm_pmu *cpu_pmu)
> +{
> +	struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
> +
> +	if (!sysctl_perf_user_access)
> +		return;
> +
> +	if (!bitmap_empty(cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS)) {
> +		int i;
> +		/* Don't need to clear assigned counters. */
> +		bitmap_xor(cpuc->dirty_mask, cpuc->dirty_mask, cpuc->used_mask, ARMPMU_MAX_HWEVENTS);
> +
> +		for_each_set_bit(i, cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS) {
> +			if (i == ARMV8_IDX_CYCLE_COUNTER)
> +				write_sysreg(0, pmccntr_el0);
> +			else
> +				armv8pmu_write_evcntr(i, 0);
> +		}

Given that we can't expose individual counters, why isn't this just:

	for_each_clear_bit(i, cpuc->used_mask, ARMPMU_MAX_HWEVENTS)
		...

and we could get rid of the dirty_mask altogether? i.e. just zero everything
that isn't assigned.

> +		bitmap_zero(cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS);
> +	}
> +
> +	write_sysreg(ARMV8_PMU_USERENR_ER | ARMV8_PMU_USERENR_CR, pmuserenr_el0);
> +}
> +
>  static void armv8pmu_enable_event(struct perf_event *event)
>  {
>  	/*
> @@ -776,6 +819,16 @@ static void armv8pmu_disable_event(struct perf_event *event)
>  
>  static void armv8pmu_start(struct arm_pmu *cpu_pmu)
>  {
> +	if (sysctl_perf_user_access) {

armv8pmu_enable_user_access() already checks this.

> +		struct perf_cpu_context *cpuctx = this_cpu_ptr(cpu_pmu->pmu.pmu_cpu_context);
> +		struct perf_event_context *task_ctx = cpuctx->task_ctx;
> +		if (atomic_read(&cpuctx->ctx.nr_user) ||

I thought we only enabled this for per-task events, so not sure why we need
this check. But actually, I don't get why we need any extra logic in this
function at all; why aren't the ->mapped/->unmapped functions sufficient?

Will


From sashal at kernel.org  Tue Aug 24 08:29:27 2021
From: sashal at kernel.org (Sasha Levin)
Date: Tue, 24 Aug 2021 11:29:27 -0400
Subject: [PATCH 4.19.y] net: dsa: mt7530: disable learning on standalone
 ports
In-Reply-To: <20210824055509.1316124-1-dqfext@gmail.com>
References: <20210824055509.1316124-1-dqfext@gmail.com>
Message-ID: <YSUQV3jhfbhbf5Ct@sashalap>

On Tue, Aug 24, 2021 at 01:55:08PM +0800, DENG Qingfang wrote:
>This is a partial backport of commit 5a30833b9a16f8d1aa15de06636f9317ca51f9df
>("net: dsa: mt7530: support MDB and bridge flag operations") upstream.
>
>Make sure that the standalone ports start up with learning disabled.

What's the reasoning behind:

1. Backporting this patch?
2. A partial backport of this patch?

-- 
Thanks,
Sasha


From robin.murphy at arm.com  Tue Aug 24 08:33:16 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 24 Aug 2021 16:33:16 +0100
Subject: [PATCH] iommu/io-pgtable: Abstract iommu_iotlb_gather access
In-Reply-To: <CAMuHMdXL7ZtY8kBx=RHsRy1JECsGPDe+E3SM=--w7bUHMYHFBQ@mail.gmail.com>
References: <83672ee76f6405c82845a55c148fa836f56fbbc1.1629465282.git.robin.murphy@arm.com>
 <CAMuHMdXL7ZtY8kBx=RHsRy1JECsGPDe+E3SM=--w7bUHMYHFBQ@mail.gmail.com>
Message-ID: <ad5ae140-6398-a2d2-ed90-2d59cab01f0f@arm.com>

On 2021-08-24 14:55, Geert Uytterhoeven wrote:
> Hi Robin,
> 
> On Fri, Aug 20, 2021 at 3:22 PM Robin Murphy <robin.murphy at arm.com> wrote:
>> Previously io-pgtable merely passed the iommu_iotlb_gather pointer
>> through to helpers, but now it has grown its own direct dereference.
>> This turns out to break the build for !IOMMU_API configs where the
>> structure only has a dummy definition. It will probably also crash
>> drivers who don't use the gather mechanism and simply pass in NULL.
>>
>> Wrap this dereference in a suitable helper which can both be stubbed
>> out for !IOMMU_API and encapsulate a NULL check otherwise.
>>
>> Fixes: 7a7c5badf858 ("iommu: Indicate queued flushes via gather data")
> 
> Is this the right Fixes tag?

Conceptually, yes - that's where the new member was introduced, so 
that's where its accessor should have been introduced as well, had I not 
managed to overlook the structure being conditionally defined and assume 
it didn't need anything special doing. Of course it's not going to make 
much difference in practice since they are immediately adjacent commits 
anyway, but it felt right to point at where I made the fundamental 
mistake rather than where the symptom appeared :)

> The build issue was introduced by:
> Fixes: a8e5f04458c4e496 ("iommu/io-pgtable: Remove non-strict quirk")
> 
>> Reported-by: kernel test robot <lkp at intel.com>
>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> 
> Thanks, this fixes the build issues I was seeing.
> 
> Tested-by: Geert Uytterhoeven <geert+renesas at glider.be>

Thanks for confirming!

Robin.

> 
> Gr{oetje,eeting}s,
> 
>                          Geert
> 


From broonie at kernel.org  Tue Aug 24 08:34:17 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 24 Aug 2021 16:34:17 +0100
Subject: [PATCH v2] arm64/sve: Better handle failure to allocate SVE register
 storage
Message-ID: <20210824153417.18371-1-broonie@kernel.org>

Currently we "handle" failure to allocate the SVE register storage by
doing a BUG_ON() and hoping for the best. This is obviously not great and
the memory allocation failure will already be loud enough without the
BUG_ON(). As the comment says it is a corner case but let's try to do a bit
better, remove the BUG_ON() and add code to handle the failure in the
callers.

For the ptrace and signal code we can return -ENOMEM gracefully however
we have no real error reporting path available to us for the SVE access
trap so instead generate a SIGKILL if the allocation fails there. This
at least means that we won't try to soldier on and end up trying to
access the nonexistant state and while it's obviously not ideal for
userspace SIGKILL doesn't allow any handling so minimises the ABI
impact, making it easier to improve the interface later if we come up
with a better idea.

Signed-off-by: Mark Brown <broonie at kernel.org>
---

v2: On signal handling and ptrace allocation failures clear TIF_SVE so
    we don't later attempt to use the sve_state.

 arch/arm64/kernel/fpsimd.c | 10 ++++------
 arch/arm64/kernel/ptrace.c |  5 +++++
 arch/arm64/kernel/signal.c |  5 +++++
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index eb8d972ad3d2..5a294f20e9de 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -520,12 +520,6 @@ void sve_alloc(struct task_struct *task)
 	/* This is a small allocation (maximum ~8KB) and Should Not Fail. */
 	task->thread.sve_state =
 		kzalloc(sve_state_size(task), GFP_KERNEL);
-
-	/*
-	 * If future SVE revisions can have larger vectors though,
-	 * this may cease to be true:
-	 */
-	BUG_ON(!task->thread.sve_state);
 }
 
 
@@ -945,6 +939,10 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
 	}
 
 	sve_alloc(current);
+	if (!current->thread.sve_state) {
+		force_sig(SIGKILL);
+		return;
+	}
 
 	get_cpu_fpsimd_context();
 
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index b381a1ee9ea7..e26196a33cf4 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -845,6 +845,11 @@ static int sve_set(struct task_struct *target,
 	}
 
 	sve_alloc(target);
+	if (!target->thread.sve_state) {
+		ret = -ENOMEM;
+		clear_tsk_thread_flag(target, TIF_SVE);
+		goto out;
+	}
 
 	/*
 	 * Ensure target->thread.sve_state is up to date with target's
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index aa46168bff32..298be5865dc4 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -290,6 +290,11 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
 
 	sve_alloc(current);
+	if (!current->thread.sve_state) {
+		clear_thread_flag(TIF_SVE);
+		return -ENOMEM;
+	}
+
 	err = __copy_from_user(current->thread.sve_state,
 			       (char __user const *)user->sve +
 					SVE_SIG_REGS_OFFSET,
-- 
2.20.1



From alexandru.elisei at arm.com  Tue Aug 24 08:30:58 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 24 Aug 2021 16:30:58 +0100
Subject: [PATCH] arm64: Do not trap PMSNEVFR_EL1
In-Reply-To: <20210824151015.GB4393@sirena.org.uk>
References: <20210824132459.562923-1-alexandru.elisei@arm.com>
 <20210824151015.GB4393@sirena.org.uk>
Message-ID: <95ae126a-8fc2-1db1-a1fd-d6811644f507@arm.com>

Hi Mark,

On 8/24/21 4:10 PM, Mark Brown wrote:
> On Tue, Aug 24, 2021 at 02:24:59PM +0100, Alexandru Elisei wrote:
>
>> Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed
>> the fine grained trap registers to prevent unwanted register traps from
>> occuring. However, for the PMSNEVFR_EL1 register, the corresponding
>> HDFGRTR_EL2.nPMSNEVFR_EL1 field must be 1 to disable trapping. Set the
>> field to 1 if FEAT_SPEv1p2 is detected.
> Oh, that's a shame :/  I wonder why this feature is different to the
> others, I just had a quick check and didn't see any other issues but...
>
>> Based on v5.14-rc7. Also, we could write 1 << 62 to HDFGRTR_EL2 unconditionally
>> since the field is RAZ/WI if !FEAT_SPEv1p2. I don't have a strong preference for
>> either approaches, but I chose this implementation because it's clearer (even
>> though it's more verbose and it's one extra trap on NV).
> Yes, the explicit feature check is both clearer and more conservative -
> it's unlikely to have a practical impact but 
>
>> At this point, I am inclined to think it's a model bug because reading works,
>> but writing causes a hang and that looks very suspicious to me. I'm going to
>> open a model bug internally and see what comes of it.
> ...are you sure this isn't that the same issue also exists with the
> equivalent field HDFGWTR_EL2 - glancing at the XML it appears to have
> the same issue?  One of the fine grained aspects of fine grained traps
> is that there's separate read and write traps!

Yes, you are right, when I read the MSR PMSNEVFR_EL1, <Xt> pseudocode I missed the
fact that for writes the trap is controlled by HDFG*W*TR_EL1, not by
HDFG*R*TR_EL1. I set? the nPMSNEVFR_EL1 bit in HDFGWRTR_EL1, and Linux doesn't
hang anymore when I try to write to the register. Will send v2 shortly.

Thanks,

Alex



From alexandru.elisei at arm.com  Tue Aug 24 08:45:23 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 24 Aug 2021 16:45:23 +0100
Subject: [PATCH v2] arm64: Do not trap PMSNEVFR_EL1
Message-ID: <20210824154523.906270-1-alexandru.elisei@arm.com>

Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed
the fine grained trap registers to prevent unwanted register traps from
occuring. However, for the PMSNEVFR_EL1 register, the corresponding
HDFG{R,W}TR_EL2.nPMSNEVFR_EL1 fields must be 1 to disable trapping. Set
both fields to 1 if FEAT_SPEv1p2 is detected to disable read and write
traps.

Fixes: 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot")
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
Based on v5.14-rc7. Tested on the model, using boot-wrapper built from
commit 5cd6238ec4ef ("aarch32: fix .globl replacement"). Without this
patch, in NVHE mode, the model freezes when I try to access PMSNEVFR_EL1.
With this patch, the model doesn't hang anymore.

Changes since v1:

* Set the corresponding bit in HDFGWRTR_EL2 to also disable write traps. My
  thanks to Mark for pointing it out.

 arch/arm64/include/asm/el2_setup.h | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index b83fb24954b7..3198acb2aad8 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -149,8 +149,17 @@
 	ubfx	x1, x1, #ID_AA64MMFR0_FGT_SHIFT, #4
 	cbz	x1, .Lskip_fgt_\@
 
-	msr_s	SYS_HDFGRTR_EL2, xzr
-	msr_s	SYS_HDFGWTR_EL2, xzr
+	mov	x0, xzr
+	mrs	x1, id_aa64dfr0_el1
+	ubfx	x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4
+	cmp	x1, #3
+	b.lt	.Lset_fgt_\@
+	/* Disable PMSNEVFR_EL1 read and write traps */
+	orr	x0, x0, #(1 << 62)
+
+.Lset_fgt_\@:
+	msr_s	SYS_HDFGRTR_EL2, x0
+	msr_s	SYS_HDFGWTR_EL2, x0
 	msr_s	SYS_HFGRTR_EL2, xzr
 	msr_s	SYS_HFGWTR_EL2, xzr
 	msr_s	SYS_HFGITR_EL2, xzr
-- 
2.33.0



From broonie at kernel.org  Tue Aug 24 08:53:12 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 24 Aug 2021 16:53:12 +0100
Subject: [PATCH v2] arm64: Do not trap PMSNEVFR_EL1
In-Reply-To: <20210824154523.906270-1-alexandru.elisei@arm.com>
References: <20210824154523.906270-1-alexandru.elisei@arm.com>
Message-ID: <20210824155312.GD4393@sirena.org.uk>

On Tue, Aug 24, 2021 at 04:45:23PM +0100, Alexandru Elisei wrote:

> Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed
> the fine grained trap registers to prevent unwanted register traps from
> occuring. However, for the PMSNEVFR_EL1 register, the corresponding
> HDFG{R,W}TR_EL2.nPMSNEVFR_EL1 fields must be 1 to disable trapping. Set
> both fields to 1 if FEAT_SPEv1p2 is detected to disable read and write
> traps.

Reviewed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210824/cc2e322f/attachment-0001.sig>

From dqfext at gmail.com  Tue Aug 24 08:57:53 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Tue, 24 Aug 2021 23:57:53 +0800
Subject: [PATCH 4.19.y] net: dsa: mt7530: disable learning on standalone
 ports
In-Reply-To: <YSUQV3jhfbhbf5Ct@sashalap>
References: <20210824055509.1316124-1-dqfext@gmail.com>
 <YSUQV3jhfbhbf5Ct@sashalap>
Message-ID: <CALW65ja3hYGmEqcWZzifP2-0WsJOnxcUXsey2ZH5vDbD0-nDeQ@mail.gmail.com>

Hi Sasha,

On Tue, Aug 24, 2021 at 11:29 PM Sasha Levin <sashal at kernel.org> wrote:
> What's the reasoning behind:
>
> 1. Backporting this patch?

Standalone ports should have address learning disabled, according to
the documentation:
https://www.kernel.org/doc/html/v5.14-rc7/networking/dsa/dsa.html#bridge-layer
dsa_switch_ops on 5.10 or earlier does not have .port_bridge_flags
function so it has to be done differently.

I've identified an issue related to this.

> 2. A partial backport of this patch?

The other part does not actually fix anything.

>
> --
> Thanks,
> Sasha


From yoong.siang.song at intel.com  Tue Aug 24 08:56:12 2021
From: yoong.siang.song at intel.com (Song Yoong Siang)
Date: Tue, 24 Aug 2021 23:56:12 +0800
Subject: [PATCH net 1/1] net: stmmac: fix kernel panic due to NULL pointer
 dereference of xsk_pool
Message-ID: <20210824155612.978529-1-yoong.siang.song@intel.com>

After free xsk_pool, there is possibility that napi polling is still
running in the middle, thus causes a kernel crash due to kernel NULL
pointer dereference of rx_q->xsk_pool and tx_q->xsk_pool.

Fix this by changing the XDP pool setup sequence to:
 1. disable napi before free xsk_pool
 2. enable napi after init xsk_pool

The following kernel panic is observed without this patch:

RIP: 0010:xsk_uses_need_wakeup+0x5/0x10
Call Trace:
stmmac_napi_poll_rxtx+0x3a9/0xae0 [stmmac]
__napi_poll+0x27/0x130
net_rx_action+0x233/0x280
__do_softirq+0xe2/0x2b6
run_ksoftirqd+0x1a/0x20
smpboot_thread_fn+0xac/0x140
? sort_range+0x20/0x20
kthread+0x124/0x150
? set_kthread_struct+0x40/0x40
ret_from_fork+0x1f/0x30
---[ end trace a77c8956b79ac107 ]---

Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy")
Cc: <stable at vger.kernel.org> # 5.13.x
Signed-off-by: Song Yoong Siang <yoong.siang.song at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
index 105821b53020..2a616c6f7cd0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
@@ -34,18 +34,18 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv,
 	need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
 
 	if (need_update) {
-		stmmac_disable_rx_queue(priv, queue);
-		stmmac_disable_tx_queue(priv, queue);
 		napi_disable(&ch->rx_napi);
 		napi_disable(&ch->tx_napi);
+		stmmac_disable_rx_queue(priv, queue);
+		stmmac_disable_tx_queue(priv, queue);
 	}
 
 	set_bit(queue, priv->af_xdp_zc_qps);
 
 	if (need_update) {
-		napi_enable(&ch->rxtx_napi);
 		stmmac_enable_rx_queue(priv, queue);
 		stmmac_enable_tx_queue(priv, queue);
+		napi_enable(&ch->rxtx_napi);
 
 		err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX);
 		if (err)
@@ -72,10 +72,10 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
 	need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
 
 	if (need_update) {
+		napi_disable(&ch->rxtx_napi);
 		stmmac_disable_rx_queue(priv, queue);
 		stmmac_disable_tx_queue(priv, queue);
 		synchronize_rcu();
-		napi_disable(&ch->rxtx_napi);
 	}
 
 	xsk_pool_dma_unmap(pool, STMMAC_RX_DMA_ATTR);
@@ -83,10 +83,10 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
 	clear_bit(queue, priv->af_xdp_zc_qps);
 
 	if (need_update) {
-		napi_enable(&ch->rx_napi);
-		napi_enable(&ch->tx_napi);
 		stmmac_enable_rx_queue(priv, queue);
 		stmmac_enable_tx_queue(priv, queue);
+		napi_enable(&ch->rx_napi);
+		napi_enable(&ch->tx_napi);
 	}
 
 	return 0;
-- 
2.25.1



From yoong.siang.song at intel.com  Tue Aug 24 09:00:15 2021
From: yoong.siang.song at intel.com (Song Yoong Siang)
Date: Wed, 25 Aug 2021 00:00:15 +0800
Subject: [PATCH net 1/1] net: stmmac: fix kernel panic due to NULL pointer
 dereference of buf->xdp
Message-ID: <20210824160015.979155-1-yoong.siang.song@intel.com>

Ensure a valid XSK buffer before proceed to free the xdp buffer.

The following kernel panic is observed without this patch:

RIP: 0010:xp_free+0x5/0x40
Call Trace:
stmmac_napi_poll_rxtx+0x332/0xb30 [stmmac]
? stmmac_tx_timer+0x3c/0xb0 [stmmac]
net_rx_action+0x13d/0x3d0
__do_softirq+0xfc/0x2fb
? smpboot_register_percpu_thread+0xe0/0xe0
run_ksoftirqd+0x32/0x70
smpboot_thread_fn+0x1d8/0x2c0
kthread+0x169/0x1a0
? kthread_park+0x90/0x90
ret_from_fork+0x1f/0x30
---[ end trace 0000000000000002 ]---

Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy")
Cc: <stable at vger.kernel.org> # 5.13.x
Suggested-by: Ong Boon Leong <boon.leong.ong at intel.com>
Signed-off-by: Song Yoong Siang <yoong.siang.song at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7b8404a21544..fa90bcdf4e45 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4914,6 +4914,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
 
 		prefetch(np);
 
+		/* Ensure a valid XSK buffer before proceed */
+		if (!buf->xdp)
+			break;
+
 		if (priv->extend_desc)
 			stmmac_rx_extended_status(priv, &priv->dev->stats,
 						  &priv->xstats,
@@ -4934,10 +4938,6 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
 			continue;
 		}
 
-		/* Ensure a valid XSK buffer before proceed */
-		if (!buf->xdp)
-			break;
-
 		/* XSK pool expects RX frame 1:1 mapped to XSK buffer */
 		if (likely(status & rx_not_ls)) {
 			xsk_buff_free(buf->xdp);
-- 
2.25.1



From jason-jh.lin at mediatek.com  Tue Aug 24 09:11:50 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 25 Aug 2021 00:11:50 +0800
Subject: [PATCH v8 01/13] dt-bindings: arm: mediatek: mmsys: add mt8195
 SoC binding
In-Reply-To: <CAAOTY_9Yug-9S4uBkNLTJH+TU8dHCeOjLuwXdNMJ+R89qJyJ9Q@mail.gmail.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-2-jason-jh.lin@mediatek.com>
 <CAAOTY_9Yug-9S4uBkNLTJH+TU8dHCeOjLuwXdNMJ+R89qJyJ9Q@mail.gmail.com>
Message-ID: <2ca1c446d01a20cc60010b1069056724bc921faf.camel@mediatek.com>

Hi Chun-Kuang,

Thanks for the review.

On Thu, 2021-08-19 at 23:00 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
> > 
> > 1. There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195.
> >    Each of them is bound to a display pipeline, so add their
> >    definition in mtk-mmsys documentation with 2 compatibles.
> > 
> > 2. Add description for power-domain property.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> > this patch is base on [1][2]
> > 
> > [1] dt-bindings: arm: mediatek: mmsys: convert to YAML format
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-1-fparent at baylibre.com/__;!!CTRNKA9wMg0ARbw!w8o5bmoiLe92jLT1-_lV_0q9mlcvIOcACUoTI-VjaVv3tGtKr414AQyDnf1ywivw9BHJ$
> >  
> > [2] dt-bindings: arm: mediatek: mmsys: add MT8365 SoC binding
> > - 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-2-fparent at baylibre.com/__;!!CTRNKA9wMg0ARbw!w8o5bmoiLe92jLT1-_lV_0q9mlcvIOcACUoTI-VjaVv3tGtKr414AQyDnf1ywmNF79JZ$
> >  
> > ---
> >  .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml  | 8
> > ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yam
> > l
> > b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yam
> > l
> > index 2d4ff0ce387b..68cb330d7595 100644
> > ---
> > a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yam
> > l
> > +++
> > b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yam
> > l
> > @@ -30,6 +30,8 @@ properties:
> >                - mediatek,mt8173-mmsys
> >                - mediatek,mt8183-mmsys
> >                - mediatek,mt8365-mmsys
> > +              - mediatek,mt8195-vdosys0
> > +              - mediatek,mt8195-vdosys1
> >            - const: syscon
> >        - items:
> >            - const: mediatek,mt7623-mmsys
> > @@ -39,6 +41,12 @@ properties:
> >    reg:
> >      maxItems: 1
> > 
> > +  power-domains:
> > +    description:
> > +      A phandle and PM domain specifier as defined by bindings
> > +      of the power controller specified by phandle. See
> > +      Documentation/devicetree/bindings/power/power-domain.yaml
> > for details.
> > +
> 
> This patch is about mt8195, but mt8173 mmsys also has power domain.
> So
> move this part to another patch.
> 
> Regards,
> Chun-Kuang.
> 
OK, I'll move this part to another patch.

Regards,
Jason-JH.Lin

> 
> >    "#clock-cells":
> >      const: 1
> > 
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From catalin.marinas at arm.com  Tue Aug 24 09:17:34 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 17:17:34 +0100
Subject: [PATCH] arm64/sve: Add a comment documenting the binutils needed
 for SVE asm
In-Reply-To: <20210816125024.8112-1-broonie@kernel.org>
References: <20210816125024.8112-1-broonie@kernel.org>
Message-ID: <162982183774.27939.5884020939902835259.b4-ty@arm.com>

On Mon, 16 Aug 2021 13:50:23 +0100, Mark Brown wrote:
> At some point it would be nice to avoid the need to manually encode SVE
> instructions, add a note of the binutils version required to save looking
> it up.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/sve: Add a comment documenting the binutils needed for SVE asm
      https://git.kernel.org/arm64/c/04fa17d1368c

-- 
Catalin



From catalin.marinas at arm.com  Tue Aug 24 09:17:53 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 17:17:53 +0100
Subject: [PATCH] arm64/sve: Add some comments for sve_save/load_state()
In-Reply-To: <20210812201143.35578-1-broonie@kernel.org>
References: <20210812201143.35578-1-broonie@kernel.org>
Message-ID: <162982183774.27939.11875075684114438912.b4-ty@arm.com>

On Thu, 12 Aug 2021 21:11:43 +0100, Mark Brown wrote:
> The use of macros for the actual function bodies means legibility is always
> going to be a bit of a challenge, especially while we can't rely on SVE
> support in the toolchain, but this helps a little.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/sve: Add some comments for sve_save/load_state()
      https://git.kernel.org/arm64/c/38ee3c5e36a1

-- 
Catalin



From catalin.marinas at arm.com  Tue Aug 24 09:18:08 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 17:18:08 +0100
Subject: [PATCH v2] arm64/sve: Better handle failure to allocate SVE
 register storage
In-Reply-To: <20210824153417.18371-1-broonie@kernel.org>
References: <20210824153417.18371-1-broonie@kernel.org>
Message-ID: <162982183775.27939.16414570053218110312.b4-ty@arm.com>

On Tue, 24 Aug 2021 16:34:17 +0100, Mark Brown wrote:
> Currently we "handle" failure to allocate the SVE register storage by
> doing a BUG_ON() and hoping for the best. This is obviously not great and
> the memory allocation failure will already be loud enough without the
> BUG_ON(). As the comment says it is a corner case but let's try to do a bit
> better, remove the BUG_ON() and add code to handle the failure in the
> callers.
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64/sve: Better handle failure to allocate SVE register storage
      https://git.kernel.org/arm64/c/7559b7d7d651

-- 
Catalin



From catalin.marinas at arm.com  Tue Aug 24 09:18:37 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 17:18:37 +0100
Subject: [PATCH v2] arm64: head: avoid over-mapping in map_memory
In-Reply-To: <20210823101253.55567-1-mark.rutland@arm.com>
References: <20210823101253.55567-1-mark.rutland@arm.com>
Message-ID: <162982183774.27939.5700909687106508447.b4-ty@arm.com>

On Mon, 23 Aug 2021 11:12:53 +0100, Mark Rutland wrote:
> The `compute_indices` and `populate_entries` macros operate on inclusive
> bounds, and thus the `map_memory` macro which uses them also operates
> on inclusive bounds.
> 
> We pass `_end` and `_idmap_text_end` to `map_memory`, but these are
> exclusive bounds, and if one of these is sufficiently aligned (as a
> result of kernel configuration, physical placement, and KASLR), then:
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: head: avoid over-mapping in map_memory
      https://git.kernel.org/arm64/c/90268574a3e8

-- 
Catalin



From catalin.marinas at arm.com  Tue Aug 24 09:19:07 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 17:19:07 +0100
Subject: (subset) [PATCH 0/5] arm64: Survival kit for SCR_EL3.HCE==0
 conditions
In-Reply-To: <20210812190213.2601506-1-maz@kernel.org>
References: <20210812190213.2601506-1-maz@kernel.org>
Message-ID: <162982183775.27939.2596397506711756472.b4-ty@arm.com>

On Thu, 12 Aug 2021 20:02:08 +0100, Marc Zyngier wrote:
> Anyone vaguely familiar with the ARMv8 architecture would quickly
> understand that entering the kernel at EL2 without enabling the HVC
> instruction is... living dangerously. But as it turns out [0], there
> is a whole range of (*cough*) "high quality" (*cough*) Broadcom
> systems out there configured exactly like that.
> 
> If you are speechless, I'm right with you.
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[5/5] arm64: Document the requirement for SCR_EL3.HCE
      https://git.kernel.org/arm64/c/e3849765037b

-- 
Catalin



From mark.rutland at arm.com  Tue Aug 24 09:20:42 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 17:20:42 +0100
Subject: [PATCH 01/13] clocksource/arm_arch_timer: Drop CNT*_TVAL read
 accessors
In-Reply-To: <20210809152651.2297337-2-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-2-maz@kernel.org>
Message-ID: <20210824162042.GF96738@C02TD0UTHF1T.local>

On Mon, Aug 09, 2021 at 04:26:39PM +0100, Marc Zyngier wrote:
> The arch timer driver never reads the various TVAL registers, only
> writes to them. It is thus pointless to provide accessors
> for them and to implement errata workarounds.
> 
> Drop these read-side accessors, and add a couple of BUG() statements
> for the time being. These statements will be removed further down
> the line.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm/include/asm/arch_timer.h    |  6 ++--
>  arch/arm64/include/asm/arch_timer.h  | 17 ++---------
>  drivers/clocksource/arm_arch_timer.c | 44 ++--------------------------
>  3 files changed, 6 insertions(+), 61 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
> index 99175812d903..0c09afaa590d 100644
> --- a/arch/arm/include/asm/arch_timer.h
> +++ b/arch/arm/include/asm/arch_timer.h
> @@ -60,8 +60,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>  			asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> -			asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
> -			break;
> +			BUG();

It would be nice if we had:

	default:
		BUG(); // or maybe BUILD_BUG()

... in all these switches to avoid surprises in future.

If we did that as a prep patch, this patch would be a pure deletion.

Either way, this looks good:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Builds cleanly, and boots fine on a fast model (both arm/arm64):

Tested-by: Mark Rutland <mark.rutland at arm.com>

Thanks,
Mark.

>  		}
>  	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
>  		switch (reg) {
> @@ -69,8 +68,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>  			asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> -			asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
> -			break;
> +			BUG();
>  		}
>  	}
>  
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index 88d20f04c64a..8e3b2ac60c30 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -52,8 +52,6 @@ struct arch_timer_erratum_workaround {
>  	enum arch_timer_erratum_match_type match_type;
>  	const void *id;
>  	const char *desc;
> -	u32 (*read_cntp_tval_el0)(void);
> -	u32 (*read_cntv_tval_el0)(void);
>  	u64 (*read_cntpct_el0)(void);
>  	u64 (*read_cntvct_el0)(void);
>  	int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
> @@ -64,17 +62,6 @@ struct arch_timer_erratum_workaround {
>  DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
>  		timer_unstable_counter_workaround);
>  
> -/* inline sysreg accessors that make erratum_handler() work */
> -static inline notrace u32 arch_timer_read_cntp_tval_el0(void)
> -{
> -	return read_sysreg(cntp_tval_el0);
> -}
> -
> -static inline notrace u32 arch_timer_read_cntv_tval_el0(void)
> -{
> -	return read_sysreg(cntv_tval_el0);
> -}
> -
>  static inline notrace u64 arch_timer_read_cntpct_el0(void)
>  {
>  	return read_sysreg(cntpct_el0);
> @@ -135,14 +122,14 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>  		case ARCH_TIMER_REG_CTRL:
>  			return read_sysreg(cntp_ctl_el0);
>  		case ARCH_TIMER_REG_TVAL:
> -			return arch_timer_reg_read_stable(cntp_tval_el0);
> +			break;
>  		}
>  	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
>  		switch (reg) {
>  		case ARCH_TIMER_REG_CTRL:
>  			return read_sysreg(cntv_ctl_el0);
>  		case ARCH_TIMER_REG_TVAL:
> -			return arch_timer_reg_read_stable(cntv_tval_el0);
> +			break;
>  		}
>  	}
>  
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index be6d741d404c..9db5c16e31e7 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -141,8 +141,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
>  			val = readl_relaxed(timer->base + CNTP_CTL);
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> -			val = readl_relaxed(timer->base + CNTP_TVAL);
> -			break;
> +			BUG();
>  		}
>  	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
>  		struct arch_timer *timer = to_arch_timer(clk);
> @@ -151,8 +150,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
>  			val = readl_relaxed(timer->base + CNTV_CTL);
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> -			val = readl_relaxed(timer->base + CNTV_TVAL);
> -			break;
> +			BUG();
>  		}
>  	} else {
>  		val = arch_timer_reg_read_cp15(access, reg);
> @@ -239,16 +237,6 @@ struct ate_acpi_oem_info {
>  	_new;						\
>  })
>  
> -static u32 notrace fsl_a008585_read_cntp_tval_el0(void)
> -{
> -	return __fsl_a008585_read_reg(cntp_tval_el0);
> -}
> -
> -static u32 notrace fsl_a008585_read_cntv_tval_el0(void)
> -{
> -	return __fsl_a008585_read_reg(cntv_tval_el0);
> -}
> -
>  static u64 notrace fsl_a008585_read_cntpct_el0(void)
>  {
>  	return __fsl_a008585_read_reg(cntpct_el0);
> @@ -285,16 +273,6 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void)
>  	_new;							\
>  })
>  
> -static u32 notrace hisi_161010101_read_cntp_tval_el0(void)
> -{
> -	return __hisi_161010101_read_reg(cntp_tval_el0);
> -}
> -
> -static u32 notrace hisi_161010101_read_cntv_tval_el0(void)
> -{
> -	return __hisi_161010101_read_reg(cntv_tval_el0);
> -}
> -
>  static u64 notrace hisi_161010101_read_cntpct_el0(void)
>  {
>  	return __hisi_161010101_read_reg(cntpct_el0);
> @@ -379,16 +357,6 @@ static u64 notrace sun50i_a64_read_cntvct_el0(void)
>  {
>  	return __sun50i_a64_read_reg(cntvct_el0);
>  }
> -
> -static u32 notrace sun50i_a64_read_cntp_tval_el0(void)
> -{
> -	return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0();
> -}
> -
> -static u32 notrace sun50i_a64_read_cntv_tval_el0(void)
> -{
> -	return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0();
> -}
>  #endif
>  
>  #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
> @@ -438,8 +406,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  		.match_type = ate_match_dt,
>  		.id = "fsl,erratum-a008585",
>  		.desc = "Freescale erratum a005858",
> -		.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
> -		.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
>  		.read_cntpct_el0 = fsl_a008585_read_cntpct_el0,
>  		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
>  		.set_next_event_phys = erratum_set_next_event_tval_phys,
> @@ -451,8 +417,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  		.match_type = ate_match_dt,
>  		.id = "hisilicon,erratum-161010101",
>  		.desc = "HiSilicon erratum 161010101",
> -		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
> -		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
>  		.read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
>  		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
>  		.set_next_event_phys = erratum_set_next_event_tval_phys,
> @@ -462,8 +426,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  		.match_type = ate_match_acpi_oem_info,
>  		.id = hisi_161010101_oem_info,
>  		.desc = "HiSilicon erratum 161010101",
> -		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
> -		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
>  		.read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
>  		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
>  		.set_next_event_phys = erratum_set_next_event_tval_phys,
> @@ -484,8 +446,6 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  		.match_type = ate_match_dt,
>  		.id = "allwinner,erratum-unknown1",
>  		.desc = "Allwinner erratum UNKNOWN1",
> -		.read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0,
> -		.read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0,
>  		.read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
>  		.read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
>  		.set_next_event_phys = erratum_set_next_event_tval_phys,
> -- 
> 2.30.2
> 


From mark.rutland at arm.com  Tue Aug 24 09:20:54 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 17:20:54 +0100
Subject: [PATCH 02/13] clocksource/arm_arch_timer: Extend write side of
 timer register accessors to u64
In-Reply-To: <20210809152651.2297337-3-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-3-maz@kernel.org>
Message-ID: <20210824162054.GG96738@C02TD0UTHF1T.local>

On Mon, Aug 09, 2021 at 04:26:40PM +0100, Marc Zyngier wrote:
> The various accessors for the timer sysreg and MMIO registers are
> currently hardwired to 32bit. However, we are about to introduce
> the use of the CVAL registers, which require a 64bit access.
> 
> Upgrade the write side of the accessors to take a 64bit value
> (the read side is left untouched as we don't plan to ever read
> back any of these registers).
> 
> No functional change expected.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Looks good, builds cleanly, and boots fine on both arm/arm64:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>
Tested-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm/include/asm/arch_timer.h    | 10 +++++-----
>  arch/arm64/include/asm/arch_timer.h  |  2 +-
>  drivers/clocksource/arm_arch_timer.c | 10 +++++-----
>  3 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
> index 0c09afaa590d..88075c7f4bfd 100644
> --- a/arch/arm/include/asm/arch_timer.h
> +++ b/arch/arm/include/asm/arch_timer.h
> @@ -24,24 +24,24 @@ int arch_timer_arch_init(void);
>   * the code. At least it does so with a recent GCC (4.6.3).
>   */
>  static __always_inline
> -void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
> +void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>  {
>  	if (access == ARCH_TIMER_PHYS_ACCESS) {
>  		switch (reg) {
>  		case ARCH_TIMER_REG_CTRL:
> -			asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
> +			asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> -			asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
> +			asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val));
>  			break;
>  		}
>  	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
>  		switch (reg) {
>  		case ARCH_TIMER_REG_CTRL:
> -			asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
> +			asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> -			asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
> +			asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val));
>  			break;
>  		}
>  	}
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index 8e3b2ac60c30..107afb721749 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -89,7 +89,7 @@ static inline notrace u64 arch_timer_read_cntvct_el0(void)
>   * the code.
>   */
>  static __always_inline
> -void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u32 val)
> +void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>  {
>  	if (access == ARCH_TIMER_PHYS_ACCESS) {
>  		switch (reg) {
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 9db5c16e31e7..0b2bac3ef7ce 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -100,27 +100,27 @@ early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
>   */
>  
>  static __always_inline
> -void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
> +void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
>  			  struct clock_event_device *clk)
>  {
>  	if (access == ARCH_TIMER_MEM_PHYS_ACCESS) {
>  		struct arch_timer *timer = to_arch_timer(clk);
>  		switch (reg) {
>  		case ARCH_TIMER_REG_CTRL:
> -			writel_relaxed(val, timer->base + CNTP_CTL);
> +			writel_relaxed((u32)val, timer->base + CNTP_CTL);
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> -			writel_relaxed(val, timer->base + CNTP_TVAL);
> +			writel_relaxed((u32)val, timer->base + CNTP_TVAL);
>  			break;
>  		}
>  	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
>  		struct arch_timer *timer = to_arch_timer(clk);
>  		switch (reg) {
>  		case ARCH_TIMER_REG_CTRL:
> -			writel_relaxed(val, timer->base + CNTV_CTL);
> +			writel_relaxed((u32)val, timer->base + CNTV_CTL);
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> -			writel_relaxed(val, timer->base + CNTV_TVAL);
> +			writel_relaxed((u32)val, timer->base + CNTV_TVAL);
>  			break;
>  		}
>  	} else {
> -- 
> 2.30.2
> 


From mark.rutland at arm.com  Tue Aug 24 09:21:22 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 17:21:22 +0100
Subject: [PATCH 03/13] clocksource/arm_arch_timer: Move system register
 timer programming over to CVAL
In-Reply-To: <20210809152651.2297337-4-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-4-maz@kernel.org>
Message-ID: <20210824162122.GH96738@C02TD0UTHF1T.local>

On Mon, Aug 09, 2021 at 04:26:41PM +0100, Marc Zyngier wrote:
> In order to cope better with high frequency counters, move the
> programming of the timers from the countdown timer (TVAL) over
> to the comparator (CVAL).
> 
> The programming model is slightly different, as we now need to
> read the current counter value to have an absolute deadline
> instead of a relative one.
> 
> There is a small overhead to this change, which we will address
> in the following patches.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Looks good, builds cleanly, and boots fine on both arm/arm64:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>
Tested-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm/include/asm/arch_timer.h    | 14 ++++++++----
>  arch/arm64/include/asm/arch_timer.h  | 16 +++++++++-----
>  drivers/clocksource/arm_arch_timer.c | 32 +++++++++++++++++++++++++---
>  include/clocksource/arm_arch_timer.h |  1 +
>  4 files changed, 51 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
> index 88075c7f4bfd..b48de9d26f27 100644
> --- a/arch/arm/include/asm/arch_timer.h
> +++ b/arch/arm/include/asm/arch_timer.h
> @@ -31,18 +31,22 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>  		case ARCH_TIMER_REG_CTRL:
>  			asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
>  			break;
> -		case ARCH_TIMER_REG_TVAL:
> -			asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" ((u32)val));
> +		case ARCH_TIMER_REG_CVAL:
> +			asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
>  			break;
> +		case ARCH_TIMER_REG_TVAL:
> +			BUG();
>  		}
>  	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
>  		switch (reg) {
>  		case ARCH_TIMER_REG_CTRL:
>  			asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
>  			break;
> -		case ARCH_TIMER_REG_TVAL:
> -			asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" ((u32)val));
> +		case ARCH_TIMER_REG_CVAL:
> +			asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
>  			break;
> +		case ARCH_TIMER_REG_TVAL:
> +			BUG();
>  		}
>  	}
>  
> @@ -60,6 +64,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>  			asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> +		case ARCH_TIMER_REG_CVAL:
>  			BUG();
>  		}
>  	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
> @@ -68,6 +73,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>  			asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> +		case ARCH_TIMER_REG_CVAL:
>  			BUG();
>  		}
>  	}
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index 107afb721749..6ceb050ae7b9 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -96,18 +96,22 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>  		case ARCH_TIMER_REG_CTRL:
>  			write_sysreg(val, cntp_ctl_el0);
>  			break;
> -		case ARCH_TIMER_REG_TVAL:
> -			write_sysreg(val, cntp_tval_el0);
> +		case ARCH_TIMER_REG_CVAL:
> +			write_sysreg(val, cntp_cval_el0);
>  			break;
> +		case ARCH_TIMER_REG_TVAL:
> +			BUG();
>  		}
>  	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
>  		switch (reg) {
>  		case ARCH_TIMER_REG_CTRL:
>  			write_sysreg(val, cntv_ctl_el0);
>  			break;
> -		case ARCH_TIMER_REG_TVAL:
> -			write_sysreg(val, cntv_tval_el0);
> +		case ARCH_TIMER_REG_CVAL:
> +			write_sysreg(val, cntv_cval_el0);
>  			break;
> +		case ARCH_TIMER_REG_TVAL:
> +			BUG();
>  		}
>  	}
>  
> @@ -115,13 +119,14 @@ void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
>  }
>  
>  static __always_inline
> -u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
> +u64 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>  {
>  	if (access == ARCH_TIMER_PHYS_ACCESS) {
>  		switch (reg) {
>  		case ARCH_TIMER_REG_CTRL:
>  			return read_sysreg(cntp_ctl_el0);
>  		case ARCH_TIMER_REG_TVAL:
> +		case ARCH_TIMER_REG_CVAL:
>  			break;
>  		}
>  	} else if (access == ARCH_TIMER_VIRT_ACCESS) {
> @@ -129,6 +134,7 @@ u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
>  		case ARCH_TIMER_REG_CTRL:
>  			return read_sysreg(cntv_ctl_el0);
>  		case ARCH_TIMER_REG_TVAL:
> +		case ARCH_TIMER_REG_CVAL:
>  			break;
>  		}
>  	}
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 0b2bac3ef7ce..898a07dc01cd 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -112,6 +112,8 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
>  		case ARCH_TIMER_REG_TVAL:
>  			writel_relaxed((u32)val, timer->base + CNTP_TVAL);
>  			break;
> +		case ARCH_TIMER_REG_CVAL:
> +			BUG();
>  		}
>  	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
>  		struct arch_timer *timer = to_arch_timer(clk);
> @@ -122,6 +124,8 @@ void arch_timer_reg_write(int access, enum arch_timer_reg reg, u64 val,
>  		case ARCH_TIMER_REG_TVAL:
>  			writel_relaxed((u32)val, timer->base + CNTV_TVAL);
>  			break;
> +		case ARCH_TIMER_REG_CVAL:
> +			BUG();
>  		}
>  	} else {
>  		arch_timer_reg_write_cp15(access, reg, val);
> @@ -141,6 +145,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
>  			val = readl_relaxed(timer->base + CNTP_CTL);
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> +		case ARCH_TIMER_REG_CVAL:
>  			BUG();
>  		}
>  	} else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) {
> @@ -150,6 +155,7 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
>  			val = readl_relaxed(timer->base + CNTV_CTL);
>  			break;
>  		case ARCH_TIMER_REG_TVAL:
> +		case ARCH_TIMER_REG_CVAL:
>  			BUG();
>  		}
>  	} else {
> @@ -687,10 +693,18 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
>  					   struct clock_event_device *clk)
>  {
>  	unsigned long ctrl;
> +	u64 cnt;
> +
>  	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
>  	ctrl |= ARCH_TIMER_CTRL_ENABLE;
>  	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
> -	arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
> +
> +	if (access == ARCH_TIMER_PHYS_ACCESS)
> +		cnt = __arch_counter_get_cntpct();
> +	else
> +		cnt = __arch_counter_get_cntvct();
> +
> +	arch_timer_reg_write(access, ARCH_TIMER_REG_CVAL, evt + cnt, clk);
>  	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
>  }
>  
> @@ -708,17 +722,29 @@ static int arch_timer_set_next_event_phys(unsigned long evt,
>  	return 0;
>  }
>  
> +static __always_inline void set_next_event_mem(const int access, unsigned long evt,
> +					   struct clock_event_device *clk)
> +{
> +	unsigned long ctrl;
> +	ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
> +	ctrl |= ARCH_TIMER_CTRL_ENABLE;
> +	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
> +
> +	arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk);
> +	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
> +}
> +
>  static int arch_timer_set_next_event_virt_mem(unsigned long evt,
>  					      struct clock_event_device *clk)
>  {
> -	set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
> +	set_next_event_mem(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
>  	return 0;
>  }
>  
>  static int arch_timer_set_next_event_phys_mem(unsigned long evt,
>  					      struct clock_event_device *clk)
>  {
> -	set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
> +	set_next_event_mem(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
>  	return 0;
>  }
>  
> diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
> index 73c7139c866f..d59537afb29d 100644
> --- a/include/clocksource/arm_arch_timer.h
> +++ b/include/clocksource/arm_arch_timer.h
> @@ -25,6 +25,7 @@
>  enum arch_timer_reg {
>  	ARCH_TIMER_REG_CTRL,
>  	ARCH_TIMER_REG_TVAL,
> +	ARCH_TIMER_REG_CVAL,
>  };
>  
>  enum arch_timer_ppi_nr {
> -- 
> 2.30.2
> 


From mark.rutland at arm.com  Tue Aug 24 09:29:53 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 17:29:53 +0100
Subject: [PATCH 04/13] clocksource/arm_arch_timer: Move drop _tval from
 erratum function names
In-Reply-To: <20210809152651.2297337-5-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-5-maz@kernel.org>
Message-ID: <20210824162953.GI96738@C02TD0UTHF1T.local>

On Mon, Aug 09, 2021 at 04:26:42PM +0100, Marc Zyngier wrote:
> The '_tval' name in the erratum handling function names doesn't
> make much sense anymore (and they were using CVAL the first place).
> 
> Drop the _tval tag.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Looks good, builds cleanly, and boots fine on both arm/arm64:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>
Tested-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  drivers/clocksource/arm_arch_timer.c | 26 +++++++++++++-------------
>  1 file changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 898a07dc01cd..160464f75017 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -371,7 +371,7 @@ EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
>  
>  static atomic_t timer_unstable_counter_workaround_in_use = ATOMIC_INIT(0);
>  
> -static void erratum_set_next_event_tval_generic(const int access, unsigned long evt,
> +static void erratum_set_next_event_generic(const int access, unsigned long evt,
>  						struct clock_event_device *clk)
>  {
>  	unsigned long ctrl;
> @@ -392,17 +392,17 @@ static void erratum_set_next_event_tval_generic(const int access, unsigned long
>  	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
>  }
>  
> -static __maybe_unused int erratum_set_next_event_tval_virt(unsigned long evt,
> +static __maybe_unused int erratum_set_next_event_virt(unsigned long evt,
>  					    struct clock_event_device *clk)
>  {
> -	erratum_set_next_event_tval_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
> +	erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
>  	return 0;
>  }
>  
> -static __maybe_unused int erratum_set_next_event_tval_phys(unsigned long evt,
> +static __maybe_unused int erratum_set_next_event_phys(unsigned long evt,
>  					    struct clock_event_device *clk)
>  {
> -	erratum_set_next_event_tval_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
> +	erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
>  	return 0;
>  }
>  
> @@ -414,8 +414,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  		.desc = "Freescale erratum a005858",
>  		.read_cntpct_el0 = fsl_a008585_read_cntpct_el0,
>  		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
> -		.set_next_event_phys = erratum_set_next_event_tval_phys,
> -		.set_next_event_virt = erratum_set_next_event_tval_virt,
> +		.set_next_event_phys = erratum_set_next_event_phys,
> +		.set_next_event_virt = erratum_set_next_event_virt,
>  	},
>  #endif
>  #ifdef CONFIG_HISILICON_ERRATUM_161010101
> @@ -425,8 +425,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  		.desc = "HiSilicon erratum 161010101",
>  		.read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
>  		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
> -		.set_next_event_phys = erratum_set_next_event_tval_phys,
> -		.set_next_event_virt = erratum_set_next_event_tval_virt,
> +		.set_next_event_phys = erratum_set_next_event_phys,
> +		.set_next_event_virt = erratum_set_next_event_virt,
>  	},
>  	{
>  		.match_type = ate_match_acpi_oem_info,
> @@ -434,8 +434,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  		.desc = "HiSilicon erratum 161010101",
>  		.read_cntpct_el0 = hisi_161010101_read_cntpct_el0,
>  		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
> -		.set_next_event_phys = erratum_set_next_event_tval_phys,
> -		.set_next_event_virt = erratum_set_next_event_tval_virt,
> +		.set_next_event_phys = erratum_set_next_event_phys,
> +		.set_next_event_virt = erratum_set_next_event_virt,
>  	},
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_858921
> @@ -454,8 +454,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
>  		.desc = "Allwinner erratum UNKNOWN1",
>  		.read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
>  		.read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
> -		.set_next_event_phys = erratum_set_next_event_tval_phys,
> -		.set_next_event_virt = erratum_set_next_event_tval_virt,
> +		.set_next_event_phys = erratum_set_next_event_phys,
> +		.set_next_event_virt = erratum_set_next_event_virt,
>  	},
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_1418040
> -- 
> 2.30.2
> 


From robh at kernel.org  Tue Aug 24 09:42:05 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 11:42:05 -0500
Subject: [PATCH v2 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210820182731.29370-3-frattaroli.nicolas@gmail.com>
References: <20210820182731.29370-1-frattaroli.nicolas@gmail.com>
 <20210820182731.29370-3-frattaroli.nicolas@gmail.com>
Message-ID: <YSUhXa0o4aWGXN0B@robh.at.kernel.org>

On Fri, Aug 20, 2021 at 08:27:29PM +0200, Nicolas Frattaroli wrote:
> This adds the YAML bindings for the Rockchip I2S/TDM audio driver.
> 
> Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> ---
>  .../bindings/sound/rockchip,i2s-tdm.yaml      | 193 ++++++++++++++++++
>  1 file changed, 193 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> 
> diff --git a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> new file mode 100644
> index 000000000000..1e8c1500ba40
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> @@ -0,0 +1,193 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip I2S/TDM Controller
> +
> +description:
> +  The Rockchip I2S/TDM Controller is a Time Division Multiplexed
> +  audio interface found in various Rockchip SoCs, allowing up
> +  to 8 channels of audio over a serial interface.
> +
> +maintainers:
> +  - Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - rockchip,px30-i2s-tdm
> +      - rockchip,rk1808-i2s-tdm
> +      - rockchip,rk3308-i2s-tdm
> +      - rockchip,rk3568-i2s-tdm
> +      - rockchip,rv1126-i2s-tdm
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  dmas:
> +    minItems: 1
> +    maxItems: 2
> +
> +  dma-names:
> +    minItems: 1
> +    items:
> +      - const: rx
> +      - const: tx
> +
> +  clocks:
> +    items:
> +      - description: clock for TX
> +      - description: clock for RX
> +      - description: AHB clock driving the interface
> +
> +  clock-names:
> +    items:
> +      - const: mclk_tx
> +      - const: mclk_rx
> +      - const: hclk
> +
> +  rockchip,frame-width:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 64
> +    minimum: 32
> +    maximum: 512
> +    description:
> +      Width of a frame, usually slot width multiplied by number of slots.
> +      Must be even.
> +
> +  resets:
> +    items:
> +      - description: reset for TX
> +      - description: reset for RX
> +
> +  reset-names:
> +    items:
> +      - const: tx-m
> +      - const: rx-m
> +
> +  rockchip,cru:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the cru.
> +      Required if both playback and capture are used, i.e. if rockchip,clk-trcm
> +      is 0.

Another case of the nonexistent rockchip,clk-trcm.


> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the GRF register.
> +
> +  rockchip,mclk-calibrate:
> +    description:
> +      Enable mclk source calibration.
> +    type: boolean
> +
> +  rockchip,trcm-sync-tx-only:
> +    type: boolean
> +    description: Use TX BCLK/LRCK for both TX and RX.
> +
> +  rockchip,trcm-sync-rx-only:
> +    type: boolean
> +    description: Use RX BCLK/LRCK for both TX and RX.
> +
> +  "#sound-dai-cells":
> +    const: 0
> +
> +  rockchip,i2s-rx-route:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      Defines the mapping of I2S RX sdis to I2S data bus lines.
> +      By default, they are mapped one-to-one.
> +    items:
> +      - description: which sdi to connect to data line 0
> +      - description: which sdi to connect to data line 1
> +      - description: which sdi to connect to data line 2
> +      - description: which sdi to connect to data line 3
> +
> +  rockchip,i2s-tx-route:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      Defines the mapping of I2S TX sdos to I2S data bus lines.
> +      By default, they are mapped one-to-one.
> +    items:
> +      - description: which sdo to connect to data line 0
> +      - description: which sdo to connect to data line 1
> +      - description: which sdo to connect to data line 2
> +      - description: which sdo to connect to data line 3
> +
> +  rockchip,tdm-fsync-half-frame:
> +    description: Whether to use half frame fsync.
> +    type: boolean
> +
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - dmas
> +  - dma-names
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - rockchip,grf
> +  - "#sound-dai-cells"
> +
> +allOf:
> +  - if:
> +      properties:
> +        rockchip,trcm-sync-tx-only: false
> +        rockchip,trcm-sync-rx-only: false
> +    then:
> +      required:
> +        - rockchip,cru
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/rk3568-cru.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/pinctrl/rockchip.h>
> +
> +    foo {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +        i2s at fe410000 {
> +            compatible = "rockchip,rk3568-i2s-tdm";
> +            reg = <0x0 0xfe410000 0x0 0x1000>;
> +            interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
> +            clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
> +                     <&cru HCLK_I2S1_8CH>;
> +            clock-names = "mclk_tx", "mclk_rx", "hclk";
> +            dmas = <&dmac1 3>, <&dmac1 2>;
> +            dma-names = "rx", "tx";
> +            resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
> +            reset-names = "tx-m", "rx-m";
> +            rockchip,trcm-sync-tx-only;
> +            rockchip,cru = <&cru>;
> +            rockchip,grf = <&grf>;
> +            #sound-dai-cells = <0>;
> +            pinctrl-names = "default";
> +            pinctrl-0 =
> +                <&i2s1m0_sclktx
> +                &i2s1m0_sclkrx
> +                &i2s1m0_lrcktx
> +                &i2s1m0_lrckrx
> +                &i2s1m0_sdi0
> +                &i2s1m0_sdi1
> +                &i2s1m0_sdi2
> +                &i2s1m0_sdi3
> +                &i2s1m0_sdo0
> +                &i2s1m0_sdo1
> +                &i2s1m0_sdo2
> +                &i2s1m0_sdo3>;
> +            status = "okay";

Sorry if I wasn't clear, but you don't need status at all in examples as 
okay is the default.

Rob


From robh at kernel.org  Tue Aug 24 09:42:25 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 11:42:25 -0500
Subject: [PATCH 1/2] dt-bindings: arm-smmu: Add compatible for SM6350 SoC
In-Reply-To: <20210820202906.229292-1-konrad.dybcio@somainline.org>
References: <20210820202906.229292-1-konrad.dybcio@somainline.org>
Message-ID: <YSUhcfEIY/wOiOIt@robh.at.kernel.org>

On Fri, 20 Aug 2021 22:29:04 +0200, Konrad Dybcio wrote:
> Add the SoC specific compatible for SM6350 implementing
> arm,mmu-500.
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio at somainline.org>
> ---
>  Documentation/devicetree/bindings/iommu/arm,smmu.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From mark.rutland at arm.com  Tue Aug 24 09:44:51 2021
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 24 Aug 2021 17:44:51 +0100
Subject: [PATCH 05/13] clocksource/arm_arch_timer: Fix MMIO base address
 vs callback ordering issue
In-Reply-To: <20210809152651.2297337-6-maz@kernel.org>
References: <20210809152651.2297337-1-maz@kernel.org>
 <20210809152651.2297337-6-maz@kernel.org>
Message-ID: <20210824164451.GJ96738@C02TD0UTHF1T.local>

On Mon, Aug 09, 2021 at 04:26:43PM +0100, Marc Zyngier wrote:
> The MMIO timer base address gets published after we have registered
> the callbacks and the interrupt handler, which is... a bit dangerous.
> 
> Fix this by moving the base address publication to the point where
> we register the timer, and expose a pointer to the timer structure
> itself rather than a naked value.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

I don't have agood setup to test this with, but this looks good to me,
and builds cleanly for arm/arm64, so:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  drivers/clocksource/arm_arch_timer.c | 27 +++++++++++++--------------
>  1 file changed, 13 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
> index 160464f75017..ca7761d8459a 100644
> --- a/drivers/clocksource/arm_arch_timer.c
> +++ b/drivers/clocksource/arm_arch_timer.c
> @@ -54,13 +54,13 @@
>  
>  static unsigned arch_timers_present __initdata;
>  
> -static void __iomem *arch_counter_base __ro_after_init;
> -
>  struct arch_timer {
>  	void __iomem *base;
>  	struct clock_event_device evt;
>  };
>  
> +static struct arch_timer *arch_timer_mem __ro_after_init;
> +
>  #define to_arch_timer(e) container_of(e, struct arch_timer, evt)
>  
>  static u32 arch_timer_rate __ro_after_init;
> @@ -975,9 +975,9 @@ static u64 arch_counter_get_cntvct_mem(void)
>  	u32 vct_lo, vct_hi, tmp_hi;
>  
>  	do {
> -		vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI);
> -		vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO);
> -		tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI);
> +		vct_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI);
> +		vct_lo = readl_relaxed(arch_timer_mem->base + CNTVCT_LO);
> +		tmp_hi = readl_relaxed(arch_timer_mem->base + CNTVCT_HI);
>  	} while (vct_hi != tmp_hi);
>  
>  	return ((u64) vct_hi << 32) | vct_lo;
> @@ -1168,25 +1168,25 @@ static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq)
>  {
>  	int ret;
>  	irq_handler_t func;
> -	struct arch_timer *t;
>  
> -	t = kzalloc(sizeof(*t), GFP_KERNEL);
> -	if (!t)
> +	arch_timer_mem = kzalloc(sizeof(*arch_timer_mem), GFP_KERNEL);
> +	if (!arch_timer_mem)
>  		return -ENOMEM;
>  
> -	t->base = base;
> -	t->evt.irq = irq;
> -	__arch_timer_setup(ARCH_TIMER_TYPE_MEM, &t->evt);
> +	arch_timer_mem->base = base;
> +	arch_timer_mem->evt.irq = irq;
> +	__arch_timer_setup(ARCH_TIMER_TYPE_MEM, &arch_timer_mem->evt);
>  
>  	if (arch_timer_mem_use_virtual)
>  		func = arch_timer_handler_virt_mem;
>  	else
>  		func = arch_timer_handler_phys_mem;
>  
> -	ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &t->evt);
> +	ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &arch_timer_mem->evt);
>  	if (ret) {
>  		pr_err("Failed to request mem timer irq\n");
> -		kfree(t);
> +		kfree(arch_timer_mem);
> +		arch_timer_mem = NULL;
>  	}
>  
>  	return ret;
> @@ -1444,7 +1444,6 @@ arch_timer_mem_frame_register(struct arch_timer_mem_frame *frame)
>  		return ret;
>  	}
>  
> -	arch_counter_base = base;
>  	arch_timers_present |= ARCH_TIMER_TYPE_MEM;
>  
>  	return 0;
> -- 
> 2.30.2
> 


From andre.przywara at arm.com  Tue Aug 24 09:49:59 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 24 Aug 2021 17:49:59 +0100
Subject: [boot-wrapper PATCH 1/5] Remove unused Set/Way cache helpers
In-Reply-To: <20210824134900.34849-2-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
 <20210824134900.34849-2-mark.rutland@arm.com>
Message-ID: <2c7e6afe-e54c-c716-61c2-08facf4190ab@arm.com>

On 8/24/21 2:48 PM, Mark Rutland wrote:
> We removed the Set/Way cache maintenance in commit:
> 
>    864182b26c20a39d ("Remove cache maintenance")
> 
> ... but forgot to remove the arch helpers which are now unused.
> 
> Remove the unused helpers.

Indeed, no users in the tree.

> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Thanks,
Andre

> ---
>   arch/aarch32/include/asm/cpu.h | 26 --------------------------
>   arch/aarch64/include/asm/cpu.h | 26 --------------------------
>   2 files changed, 52 deletions(-)
> 
> diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
> index 878be67..a7993f0 100644
> --- a/arch/aarch32/include/asm/cpu.h
> +++ b/arch/aarch32/include/asm/cpu.h
> @@ -56,32 +56,6 @@ static inline uint32_t read_id_pfr1(void)
>   	return val;
>   }
>   
> -static inline uint32_t read_clidr(void)
> -{
> -	uint32_t val;
> -
> -	asm volatile ("mrc	p15, 1, %0, c0, c0, 1" : "=r" (val));
> -	return val;
> -}
> -
> -static inline uint32_t read_ccsidr(void)
> -{
> -	uint32_t val;
> -
> -	asm volatile ("mrc	p15, 1, %0, c0, c0, 0" : "=r" (val));
> -	return val;
> -}
> -
> -static inline void write_csselr(uint32_t val)
> -{
> -	asm volatile ("mcr	p15, 2, %0, c0, c0, 0" : : "r" (val));
> -}
> -
> -static inline void dccisw(uint32_t val)
> -{
> -	asm volatile ("mcr	p15, 0, %0, c7, c14, 2" : : "r" (val));
> -}
> -
>   static inline void iciallu(void)
>   {
>   	uint32_t val = 0;
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index ccb5397..1cddbb8 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -66,32 +66,6 @@ static inline uint64_t read_id_aa64pfr0(void)
>   	return val;
>   }
>   
> -static inline uint32_t read_clidr(void)
> -{
> -	uint32_t val;
> -
> -	asm volatile ("mrs	%0, clidr_el1" : "=r" (val));
> -	return val;
> -}
> -
> -static inline uint32_t read_ccsidr(void)
> -{
> -	uint32_t val;
> -
> -	asm volatile ("mrs	%0, ccsidr_el1" : "=r" (val));
> -	return val;
> -}
> -
> -static inline void write_csselr(uint32_t val)
> -{
> -	asm volatile ("msr	csselr_el1, %0" : : "r" (val));
> -}
> -
> -static inline void dccisw(uint32_t val)
> -{
> -	asm volatile ("dc	cisw, %0" : : "r" (val));
> -}
> -
>   static inline void iciallu(void)
>   {
>   	asm volatile ("ic	iallu");
> 



From andre.przywara at arm.com  Tue Aug 24 09:50:23 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 24 Aug 2021 17:50:23 +0100
Subject: [boot-wrapper PATCH 2/5] aarch32: simplify _switch_monitor
In-Reply-To: <20210824134900.34849-3-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
 <20210824134900.34849-3-mark.rutland@arm.com>
Message-ID: <cb6dcb78-a5d6-f1e9-7c49-c1d194e8e568@arm.com>

On 8/24/21 2:48 PM, Mark Rutland wrote:
> If we're lucky enough to have been booted into secure PL1, we can switch
> to monitor mode with an exception return rather than an SMC call, which
> avoids the need for boot-time vectors.
> 
> Note that while all Secure PL1 register state is accessible in Secure
> SVC mode, we must switch to Monitor mode before we set SCR.NS=1.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

I don't know much about the subtle differences between smc, movs pc and 
eret, but from what I read this is indeed an easier way to get to MON.

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>   arch/aarch32/boot.S | 19 ++++---------------
>   1 file changed, 4 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index 82927de..e397cb0 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -37,9 +37,10 @@ ASM_FUNC(_start)
>   	b	start_no_el3
>   
>   _switch_monitor:
> -	ldr	r0, =boot_vectors
> -	bl	setup_vector
> -	smc	#0
> +	adr	lr, _monitor
> +	ldr	r0, =(PSR_A | PSR_I | PSR_F | PSR_MON)
> +	msr	spsr, r0
> +	movs	pc, lr
>   
>   _monitor:
>   	/* Move the stack to Monitor mode*/
> @@ -102,18 +103,6 @@ ASM_FUNC(jump_kernel)
>   	msr	spsr_cxf, r4
>   	movs	pc, lr
>   
> -	.section .vectors
> -	.align 6
> -boot_vectors:
> -	b	.
> -	b	.
> -	b	_monitor
> -	b	.
> -	b	.
> -	b	.
> -	b	.
> -	b	.
> -
>   	.section .data
>   	.align 2
>   flag_no_el3:
> 



From andre.przywara at arm.com  Tue Aug 24 09:50:43 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 24 Aug 2021 17:50:43 +0100
Subject: [boot-wrapper PATCH 3/5] GICv3: initialize without RMW
In-Reply-To: <20210824134900.34849-4-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
 <20210824134900.34849-4-mark.rutland@arm.com>
Message-ID: <32fc73f9-7eef-d6e2-1f5c-491e330e5b70@arm.com>

On 8/24/21 2:48 PM, Mark Rutland wrote:
> There's no need to perform an RMW sequence to initialize ICC_SRE_EL3, as
> there are no bits that we need to preserve, and generally we should
> reset registers to specific values such that RESx bits aren't configured
> to UNKNOWN values that could be problematic in future architecture
> versions.
> 
> Instead, let's initialize ICC_SRE_EL3 with a constant value. Since the
> `DIB` and `DFB` fields are RAO/WI in some configurations and we have no
> reason to initialize these to 0, we always initialize these to 1, in
> addition to `SRE` and `SRE_Enable`.

Indeed, actually the architectural reset value is 0 (bypass enabled), 
and we seem to be just saved by the fact that the model implements them 
as RAO/WI. So forcing a value is the right thing to do.

> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Alexandru Elisei <alexandru.elisei at arm.com>
> Cc: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>   arch/aarch32/include/asm/gic-v3.h | 7 -------
>   arch/aarch64/include/asm/gic-v3.h | 7 -------
>   common/gic-v3.c                   | 8 +++-----
>   3 files changed, 3 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
> index ec9a327..65f38de 100644
> --- a/arch/aarch32/include/asm/gic-v3.h
> +++ b/arch/aarch32/include/asm/gic-v3.h
> @@ -9,13 +9,6 @@
>   #ifndef __ASM_AARCH32_GICV3_H
>   #define __ASM_AARCH32_GICV3_H
>   
> -static inline uint32_t gic_read_icc_sre(void)
> -{
> -	uint32_t val;
> -	asm volatile ("mrc p15, 6, %0, c12, c12, 5" : "=r" (val));
> -	return val;
> -}
> -
>   static inline void gic_write_icc_sre(uint32_t val)
>   {
>   	asm volatile ("mcr p15, 6, %0, c12, c12, 5" : : "r" (val));
> diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h
> index e743c02..5b32380 100644
> --- a/arch/aarch64/include/asm/gic-v3.h
> +++ b/arch/aarch64/include/asm/gic-v3.h
> @@ -15,13 +15,6 @@
>   #define ICC_CTLR_EL3	"S3_6_C12_C12_4"
>   #define ICC_PMR_EL1	"S3_0_C4_C6_0"
>   
> -static inline uint32_t gic_read_icc_sre(void)
> -{
> -	uint32_t val;
> -	asm volatile ("mrs %0, " ICC_SRE_EL3 : "=r" (val));
> -	return val;
> -}
> -
>   static inline void gic_write_icc_sre(uint32_t val)
>   {
>   	asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
> diff --git a/common/gic-v3.c b/common/gic-v3.c
> index 62f9676..6207007 100644
> --- a/common/gic-v3.c
> +++ b/common/gic-v3.c
> @@ -42,6 +42,8 @@
>   #define GICR_TYPER_Last			(1 << 4)
>   
>   #define ICC_SRE_SRE			(1 << 0)
> +#define ICC_SRE_DFB			(1 << 1)
> +#define ICC_SRE_DIB			(1 << 2)
>   #define ICC_SRE_Enable			(1 << 3)
>   
>   void gic_secure_init_primary(void)
> @@ -101,8 +103,6 @@ void gic_secure_init_primary(void)
>   
>   void gic_secure_init(void)
>   {
> -	uint32_t sre;
> -
>   	/*
>   	 * If GICv3 is not available, skip initialisation. The OS will probably
>   	 * fail with a warning, but this should be easier to debug than a
> @@ -114,9 +114,7 @@ void gic_secure_init(void)
>   	if (this_cpu_logical_id() == 0)
>   		gic_secure_init_primary();
>   
> -	sre = gic_read_icc_sre();
> -	sre |= ICC_SRE_Enable | ICC_SRE_SRE;
> -	gic_write_icc_sre(sre);
> +	gic_write_icc_sre(ICC_SRE_Enable | ICC_SRE_DIB | ICC_SRE_DFB | ICC_SRE_SRE);
>   	isb();
>   
>   	gic_write_icc_ctlr(0);
> 



From andre.przywara at arm.com  Tue Aug 24 09:50:56 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 24 Aug 2021 17:50:56 +0100
Subject: [boot-wrapper PATCH 4/5] Rename kernel *_RESET values to *_KERNEL
In-Reply-To: <20210824134900.34849-5-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
 <20210824134900.34849-5-mark.rutland@arm.com>
Message-ID: <18228acf-b145-810c-93ea-20047915b462@arm.com>

On 8/24/21 2:48 PM, Mark Rutland wrote:
> Our *_RESET constants are used to initalize state for the kernel rather
> than the bootwrapper itself, so for clarity we should use a *_KERNEL
> suffix rather than a _RESET suffix.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

It's indeed only renaming:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>   arch/aarch32/boot.S            | 4 ++--
>   arch/aarch32/include/asm/cpu.h | 4 ++--
>   arch/aarch64/boot.S            | 4 ++--
>   arch/aarch64/include/asm/cpu.h | 6 +++---
>   4 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index e397cb0..08bf932 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -76,10 +76,10 @@ ASM_FUNC(jump_kernel)
>   	push	{r0 - r3}
>   	mov	r5, sp
>   
> -	ldr	r0, =HSCTLR_RESET
> +	ldr	r0, =HSCTLR_KERNEL
>   	mcr	p15, 4, r0, c1, c0, 0		@ HSCTLR
>   
> -	ldr	r0, =SCTLR_RESET
> +	ldr	r0, =SCTLR_KERNEL
>   	mcr	p15, 0, r0, c1, c0, 0		@ SCTLR
>   
>   	/* Reset our stack pointer */
> diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
> index a7993f0..105cae5 100644
> --- a/arch/aarch32/include/asm/cpu.h
> +++ b/arch/aarch32/include/asm/cpu.h
> @@ -13,8 +13,8 @@
>   #define MPIDR_INVALID		(-1)
>   
>   /* Only RES1 bits and CP15 barriers for the kernel */
> -#define HSCTLR_RESET		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
> -#define SCTLR_RESET		(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
> +#define HSCTLR_KERNEL		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
> +#define SCTLR_KERNEL		(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
>   
>   #define PSR_SVC			0x13
>   #define PSR_HYP			0x1a
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index d8d7ccd..587a25f 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -140,10 +140,10 @@ ASM_FUNC(jump_kernel)
>   	mov	x22, x3
>   	mov	x23, x4
>   
> -	ldr	x0, =SCTLR_EL1_RESET
> +	ldr	x0, =SCTLR_EL1_KERNEL
>   	msr	sctlr_el1, x0
>   
> -	ldr	x0, =SCTLR_EL2_RESET
> +	ldr	x0, =SCTLR_EL2_KERNEL
>   	msr	sctlr_el2, x0
>   
>   	cpuid	x0, x1
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index 1cddbb8..63eb1c3 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -17,7 +17,7 @@
>    * RES1 bits,  little-endian, caches and MMU off, no alignment checking,
>    * no WXN.
>    */
> -#define SCTLR_EL2_RESET		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
> +#define SCTLR_EL2_KERNEL	(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
>   
>   #define SPSR_A			(1 << 8)	/* System Error masked */
>   #define SPSR_D			(1 << 9)	/* Debug masked */
> @@ -37,10 +37,10 @@
>   
>   #ifdef KERNEL_32
>   /* 32-bit kernel decompressor uses CP15 barriers */
> -#define SCTLR_EL1_RESET		(SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
> +#define SCTLR_EL1_KERNEL	(SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
>   #define SPSR_KERNEL		(SPSR_A | SPSR_I | SPSR_F | SPSR_HYP)
>   #else
> -#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
> +#define SCTLR_EL1_KERNEL	SCTLR_EL1_RES1
>   #define SPSR_KERNEL		(SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL2H)
>   #endif
>   
> 



From andre.przywara at arm.com  Tue Aug 24 09:51:04 2021
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 24 Aug 2021 17:51:04 +0100
Subject: [boot-wrapper PATCH 5/5] Rename `CNTFRQ` -> `COUNTER_FREQ`
In-Reply-To: <20210824134900.34849-6-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
 <20210824134900.34849-6-mark.rutland@arm.com>
Message-ID: <6f884767-f06a-c5e5-cb6e-9b34136030fd@arm.com>

On 8/24/21 2:49 PM, Mark Rutland wrote:
> To avoid any confusuion between the CNTFRQ/CNTFRQ_EL0 register and the
> vallue it will be progrmamed with, rename the `CNTFRQ` constant to
> `COUNTER_FREQ.
> 
> In future patches this will allow us to use `CNTFRQ` as a macro for the
> AArch32 CP15 register encoding.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Confirmed to be just renaming:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>   Makefile.am         | 4 ++--
>   arch/aarch32/boot.S | 2 +-
>   arch/aarch64/boot.S | 2 +-
>   3 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 3591d23..d0a68df 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -13,12 +13,12 @@ SCRIPT_DIR	:= $(top_srcdir)/scripts
>   PHYS_OFFSET	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findmem.pl $(KERNEL_DTB))
>   UART_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,pl011')
>   SYSREGS_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,vexpress-sysreg' 2> /dev/null)
> -CNTFRQ		:= 24000000
> +COUNTER_FREQ	:= 24000000
>   
>   CPU_IDS		:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findcpuids.pl $(KERNEL_DTB))
>   NR_CPUS         := $(shell echo $(CPU_IDS) | tr ',' ' ' | wc -w)
>   
> -DEFINES		= -DCNTFRQ=$(CNTFRQ)
> +DEFINES		= -DCOUNTER_FREQ=$(COUNTER_FREQ)
>   DEFINES		+= -DCPU_IDS=$(CPU_IDS)
>   DEFINES		+= -DNR_CPUS=$(NR_CPUS)
>   DEFINES		+= $(if $(SYSREGS_BASE), -DSYSREGS_BASE=$(SYSREGS_BASE), )
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index 08bf932..4add338 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -54,7 +54,7 @@ _monitor:
>   	mov	r0, #(1 << 10 | 1 << 11)	@ Enable NS access to CPACR
>   	mcr	p15, 0, r0, c1, c1, 2		@ NSACR
>   
> -	ldr	r0, =CNTFRQ
> +	ldr	r0, =COUNTER_FREQ
>   	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
>   
>   	bl	gic_secure_init
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 587a25f..bfbb6ec 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -118,7 +118,7 @@ ASM_FUNC(_start)
>   	msr	ZCR_EL3, x0			// for EL2.
>   
>   1:
> -	ldr	x0, =CNTFRQ
> +	ldr	x0, =COUNTER_FREQ
>   	msr	cntfrq_el0, x0
>   
>   	bl	gic_secure_init
> 



From robh at kernel.org  Tue Aug 24 09:52:09 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 11:52:09 -0500
Subject: [RESEND PATCH v5 4/7] dt-bindings: i2c: add attribute
 use-default-timing
In-Reply-To: <1629775828-19993-5-git-send-email-kewei.xu@mediatek.com>
References: <1629775828-19993-1-git-send-email-kewei.xu@mediatek.com>
 <1629775828-19993-5-git-send-email-kewei.xu@mediatek.com>
Message-ID: <YSUjuZIm4C2B0sDs@robh.at.kernel.org>

On Tue, 24 Aug 2021 11:30:25 +0800, Kewei Xu wrote:
> Add attribute use-default-timing for DT-binding document.
> 
> Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
> Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
> ---
>  Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 

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


From dqfext at gmail.com  Tue Aug 24 09:52:52 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed, 25 Aug 2021 00:52:52 +0800
Subject: [PATCH net-next] net: dsa: mt7530: manually set up VLAN ID 0
Message-ID: <20210824165253.1691315-1-dqfext@gmail.com>

The driver was relying on dsa_slave_vlan_rx_add_vid to add VLAN ID 0. After
the blamed commit, VLAN ID 0 won't be set up anymore, breaking software
bridging fallback on VLAN-unaware bridges.

Manually set up VLAN ID 0 to fix this.

Fixes: 06cfb2df7eb0 ("net: dsa: don't advertise 'rx-vlan-filter' when not needed")
Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 drivers/net/dsa/mt7530.c | 25 +++++++++++++++++++++++++
 drivers/net/dsa/mt7530.h |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index d757d9dcba51..d0cba2d1cd68 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1599,6 +1599,21 @@ mt7530_hw_vlan_update(struct mt7530_priv *priv, u16 vid,
 	mt7530_vlan_cmd(priv, MT7530_VTCR_WR_VID, vid);
 }
 
+static int
+mt7530_setup_vlan0(struct mt7530_priv *priv)
+{
+	u32 val;
+
+	/* Validate the entry with independent learning, keep the original
+	 * ingress tag attribute.
+	 */
+	val = IVL_MAC | EG_CON | PORT_MEM(MT7530_ALL_MEMBERS) | FID(FID_BRIDGED) |
+	      VLAN_VALID;
+	mt7530_write(priv, MT7530_VAWD1, val);
+
+	return mt7530_vlan_cmd(priv, MT7530_VTCR_WR_VID, 0);
+}
+
 static int
 mt7530_port_vlan_add(struct dsa_switch *ds, int port,
 		     const struct switchdev_obj_port_vlan *vlan,
@@ -2174,6 +2189,11 @@ mt7530_setup(struct dsa_switch *ds)
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 	}
 
+	/* Setup VLAN ID 0 for VLAN-unaware bridges */
+	ret = mt7530_setup_vlan0(priv);
+	if (ret)
+		return ret;
+
 	/* Setup port 5 */
 	priv->p5_intf_sel = P5_DISABLED;
 	interface = PHY_INTERFACE_MODE_NA;
@@ -2346,6 +2366,11 @@ mt7531_setup(struct dsa_switch *ds)
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 	}
 
+	/* Setup VLAN ID 0 for VLAN-unaware bridges */
+	ret = mt7530_setup_vlan0(priv);
+	if (ret)
+		return ret;
+
 	ds->assisted_learning_on_cpu_port = true;
 	ds->mtu_enforcement_ingress = true;
 
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index fe4cd2ac26d0..91508e2feef9 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -145,6 +145,8 @@ enum mt7530_vlan_cmd {
 #define  PORT_STAG			BIT(31)
 /* Independent VLAN Learning */
 #define  IVL_MAC			BIT(30)
+/* Egress Tag Consistent */
+#define  EG_CON				BIT(29)
 /* Per VLAN Egress Tag Control */
 #define  VTAG_EN			BIT(28)
 /* VLAN Member Control */
-- 
2.25.1



From olteanv at gmail.com  Tue Aug 24 09:57:42 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 24 Aug 2021 19:57:42 +0300
Subject: [PATCH net-next] net: dsa: mt7530: manually set up VLAN ID 0
In-Reply-To: <20210824165253.1691315-1-dqfext@gmail.com>
References: <20210824165253.1691315-1-dqfext@gmail.com>
Message-ID: <20210824165742.xvkb3ke7boryfoj4@skbuf>

On Wed, Aug 25, 2021 at 12:52:52AM +0800, DENG Qingfang wrote:
> The driver was relying on dsa_slave_vlan_rx_add_vid to add VLAN ID 0. After
> the blamed commit, VLAN ID 0 won't be set up anymore, breaking software
> bridging fallback on VLAN-unaware bridges.
> 
> Manually set up VLAN ID 0 to fix this.
> 
> Fixes: 06cfb2df7eb0 ("net: dsa: don't advertise 'rx-vlan-filter' when not needed")
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---

I understand that this is how you noticed the issue, but please remember
that one can always compile a kernel with CONFIG_VLAN_8021Q=n. So the
issue predates my patch by much longer. You might reconsider the Fixes:
tag in light of this, maybe the patch needs to be sent to stable.

>  drivers/net/dsa/mt7530.c | 25 +++++++++++++++++++++++++
>  drivers/net/dsa/mt7530.h |  2 ++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index d757d9dcba51..d0cba2d1cd68 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -1599,6 +1599,21 @@ mt7530_hw_vlan_update(struct mt7530_priv *priv, u16 vid,
>  	mt7530_vlan_cmd(priv, MT7530_VTCR_WR_VID, vid);
>  }
>  
> +static int
> +mt7530_setup_vlan0(struct mt7530_priv *priv)
> +{
> +	u32 val;
> +
> +	/* Validate the entry with independent learning, keep the original
> +	 * ingress tag attribute.
> +	 */
> +	val = IVL_MAC | EG_CON | PORT_MEM(MT7530_ALL_MEMBERS) | FID(FID_BRIDGED) |

FID_BRIDGED?

> +	      VLAN_VALID;
> +	mt7530_write(priv, MT7530_VAWD1, val);
> +
> +	return mt7530_vlan_cmd(priv, MT7530_VTCR_WR_VID, 0);
> +}
> +
>  static int
>  mt7530_port_vlan_add(struct dsa_switch *ds, int port,
>  		     const struct switchdev_obj_port_vlan *vlan,
> @@ -2174,6 +2189,11 @@ mt7530_setup(struct dsa_switch *ds)
>  			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
>  	}
>  
> +	/* Setup VLAN ID 0 for VLAN-unaware bridges */
> +	ret = mt7530_setup_vlan0(priv);
> +	if (ret)
> +		return ret;
> +
>  	/* Setup port 5 */
>  	priv->p5_intf_sel = P5_DISABLED;
>  	interface = PHY_INTERFACE_MODE_NA;
> @@ -2346,6 +2366,11 @@ mt7531_setup(struct dsa_switch *ds)
>  			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
>  	}
>  
> +	/* Setup VLAN ID 0 for VLAN-unaware bridges */
> +	ret = mt7530_setup_vlan0(priv);
> +	if (ret)
> +		return ret;
> +
>  	ds->assisted_learning_on_cpu_port = true;
>  	ds->mtu_enforcement_ingress = true;
>  
> diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
> index fe4cd2ac26d0..91508e2feef9 100644
> --- a/drivers/net/dsa/mt7530.h
> +++ b/drivers/net/dsa/mt7530.h
> @@ -145,6 +145,8 @@ enum mt7530_vlan_cmd {
>  #define  PORT_STAG			BIT(31)
>  /* Independent VLAN Learning */
>  #define  IVL_MAC			BIT(30)
> +/* Egress Tag Consistent */
> +#define  EG_CON				BIT(29)
>  /* Per VLAN Egress Tag Control */
>  #define  VTAG_EN			BIT(28)
>  /* VLAN Member Control */
> -- 
> 2.25.1
> 


From olteanv at gmail.com  Tue Aug 24 10:16:49 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 24 Aug 2021 20:16:49 +0300
Subject: [PATCH net-next] net: dsa: mt7530: manually set up VLAN ID 0
In-Reply-To: <20210824165742.xvkb3ke7boryfoj4@skbuf>
References: <20210824165253.1691315-1-dqfext@gmail.com>
 <20210824165742.xvkb3ke7boryfoj4@skbuf>
Message-ID: <20210824171649.ebcolsbsqczomiee@skbuf>

On Tue, Aug 24, 2021 at 07:57:42PM +0300, Vladimir Oltean wrote:
> > +static int
> > +mt7530_setup_vlan0(struct mt7530_priv *priv)
> > +{
> > +	u32 val;
> > +
> > +	/* Validate the entry with independent learning, keep the original
> > +	 * ingress tag attribute.
> > +	 */
> > +	val = IVL_MAC | EG_CON | PORT_MEM(MT7530_ALL_MEMBERS) | FID(FID_BRIDGED) |
> 
> FID_BRIDGED?

yes, FID_BRIDGED.

Please confirm that the Fixes: tag is the one you intend. The patch appears fine otherwise.


From robh at kernel.org  Tue Aug 24 10:21:24 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 12:21:24 -0500
Subject: [PATCH v1] dt-bindings: timer: remove rockchip,rk3066-timer
 compatible string from rockchip,rk-timer.yaml
In-Reply-To: <20210824095637.2547-1-jbx6244@gmail.com>
References: <20210824095637.2547-1-jbx6244@gmail.com>
Message-ID: <YSUqlE2S+YGR6680@robh.at.kernel.org>

On Tue, 24 Aug 2021 11:56:37 +0200, Johan Jonker wrote:
> The Rockchip rk3066 timers have a different register layout then rk3288
> with only a 32 vs 64 bits timer channel. The timers in rk3066a.dtsi have
> "snps,dw-apb-timer" as compatible string, so remove the
> "rockchip,rk3066-timer" from rockchip,rk-timer.yaml
> 
> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
> ---
>  Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml | 1 -
>  1 file changed, 1 deletion(-)
> 

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


From madvenka at linux.microsoft.com  Tue Aug 24 10:21:28 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Tue, 24 Aug 2021 12:21:28 -0500
Subject: [RFC PATCH v8 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210824131344.GE96738@C02TD0UTHF1T.local>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-2-madvenka@linux.microsoft.com>
 <20210824131344.GE96738@C02TD0UTHF1T.local>
Message-ID: <da2bb980-09c3-5a39-73cd-ca4de4c38d51@linux.microsoft.com>

Thanks for the review. Responses inline...

On 8/24/21 8:13 AM, Mark Rutland wrote:
> On Thu, Aug 12, 2021 at 02:06:00PM -0500, madvenka at linux.microsoft.com wrote:
>> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
>>
>> Currently, there are multiple functions in ARM64 code that walk the
>> stack using start_backtrace() and unwind_frame(). Convert all of
>> them to use arch_stack_walk(). This makes maintenance easier.
> 
> It would be good to split this into a series of patches as Mark Brown
> suggested in v7.
> 

Will do.

>> Here is the list of functions:
>>
>> 	perf_callchain_kernel()
>> 	get_wchan()
>> 	return_address()
>> 	dump_backtrace()
>> 	profile_pc()
> 
> Note that arch_stack_walk() depends on CONFIG_STACKTRACE (which is not in
> defconfig), so we'll need to reorganise things such that it's always defined,
> or factor out the core of that function and add a wrapper such that we
> can always use it.
> 

I will include CONFIG_STACKTRACE in defconfig, if that is OK with you and
Mark Brown.

>> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
>> ---
>>  arch/arm64/include/asm/stacktrace.h |  3 ---
>>  arch/arm64/kernel/perf_callchain.c  |  5 +---
>>  arch/arm64/kernel/process.c         | 39 ++++++++++++++++++-----------
>>  arch/arm64/kernel/return_address.c  |  6 +----
>>  arch/arm64/kernel/stacktrace.c      | 38 +++-------------------------
>>  arch/arm64/kernel/time.c            | 22 +++++++++-------
>>  6 files changed, 43 insertions(+), 70 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
>> index 8aebc00c1718..e43dea1c6b41 100644
>> --- a/arch/arm64/include/asm/stacktrace.h
>> +++ b/arch/arm64/include/asm/stacktrace.h
>> @@ -61,9 +61,6 @@ struct stackframe {
>>  #endif
>>  };
>>  
>> -extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
>> -extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
>> -			    bool (*fn)(void *, unsigned long), void *data);
>>  extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>>  			   const char *loglvl);
>>  
>> diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
>> index 4a72c2727309..2f289013c9c9 100644
>> --- a/arch/arm64/kernel/perf_callchain.c
>> +++ b/arch/arm64/kernel/perf_callchain.c
>> @@ -147,15 +147,12 @@ static bool callchain_trace(void *data, unsigned long pc)
>>  void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
>>  			   struct pt_regs *regs)
>>  {
>> -	struct stackframe frame;
>> -
>>  	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
>>  		/* We don't support guest os callchain now */
>>  		return;
>>  	}
>>  
>> -	start_backtrace(&frame, regs->regs[29], regs->pc);
>> -	walk_stackframe(current, &frame, callchain_trace, entry);
>> +	arch_stack_walk(callchain_trace, entry, current, regs);
>>  }
> 
> We can also update callchain_trace take the return value of
> perf_callchain_store into acount, e.g.
> 
> | static bool callchain_trace(void *data, unsigned long pc) 
> | {
> | 	struct perf_callchain_entry_ctx *entry = data;
> | 	return perf_callchain_store(entry, pc) == 0;
> | }
> 

OK.

>>  
>>  unsigned long perf_instruction_pointer(struct pt_regs *regs)
>> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
>> index c8989b999250..52c12fd26407 100644
>> --- a/arch/arm64/kernel/process.c
>> +++ b/arch/arm64/kernel/process.c
>> @@ -544,11 +544,28 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
>>  	return last;
>>  }
>>  
>> +struct wchan_info {
>> +	unsigned long	pc;
>> +	int		count;
>> +};
>> +
>> +static bool get_wchan_cb(void *arg, unsigned long pc)
>> +{
>> +	struct wchan_info *wchan_info = arg;
>> +
>> +	if (!in_sched_functions(pc)) {
>> +		wchan_info->pc = pc;
>> +		return false;
>> +	}
>> +	wchan_info->count--;
>> +	return !!wchan_info->count;
>> +}
> 
> This will terminate one entry earlier than the old logic since we used
> to use a post-increment (testing the prior value), and now we're
> effectively using a pre-decrement (testing the new value).
> 
> I don't think that matters all that much in practice, but it might be
> best to keep the original logic, e.g. initialize `count` to 0 and here
> do:
> 
> 	return wchan_info->count++ < 16;
> 

The reason I did it this way is that with the old logic the actual limit
implemented is 17 instead of 16. That seemed odd. But I could do it the
way you have suggested.


>> +
>>  unsigned long get_wchan(struct task_struct *p)
>>  {
>> -	struct stackframe frame;
>> -	unsigned long stack_page, ret = 0;
>> -	int count = 0;
>> +	unsigned long stack_page;
>> +	struct wchan_info wchan_info;
>> +
>>  	if (!p || p == current || task_is_running(p))
>>  		return 0;
>>  
>> @@ -556,20 +573,12 @@ unsigned long get_wchan(struct task_struct *p)
>>  	if (!stack_page)
>>  		return 0;
>>  
>> -	start_backtrace(&frame, thread_saved_fp(p), thread_saved_pc(p));
>> +	wchan_info.pc = 0;
>> +	wchan_info.count = 16;
>> +	arch_stack_walk(get_wchan_cb, &wchan_info, p, NULL);
>>  
>> -	do {
>> -		if (unwind_frame(p, &frame))
>> -			goto out;
>> -		if (!in_sched_functions(frame.pc)) {
>> -			ret = frame.pc;
>> -			goto out;
>> -		}
>> -	} while (count++ < 16);
>> -
>> -out:
>>  	put_task_stack(p);
>> -	return ret;
>> +	return wchan_info.pc;
>>  }
> 
> Other than the comment above, this looks good to me.
> 

OK.

>>  unsigned long arch_align_stack(unsigned long sp)
>> diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c
>> index a6d18755652f..92a0f4d434e4 100644
>> --- a/arch/arm64/kernel/return_address.c
>> +++ b/arch/arm64/kernel/return_address.c
>> @@ -35,15 +35,11 @@ NOKPROBE_SYMBOL(save_return_addr);
>>  void *return_address(unsigned int level)
>>  {
>>  	struct return_address_data data;
>> -	struct stackframe frame;
>>  
>>  	data.level = level + 2;
>>  	data.addr = NULL;
>>  
>> -	start_backtrace(&frame,
>> -			(unsigned long)__builtin_frame_address(0),
>> -			(unsigned long)return_address);
>> -	walk_stackframe(current, &frame, save_return_addr, &data);
>> +	arch_stack_walk(save_return_addr, &data, current, NULL);
>>  
>>  	if (!data.level)
>>  		return data.addr;
> 
> Nor that arch_stack_walk() will start with it's caller, so
> return_address() will be included in the trace where it wasn't
> previously, which implies we need to skip an additional level.
> 

You are correct. I will fix this. Thanks for catching this.

> That said, I'm not entirely sure why we need to skip 2 levels today; it
> might be worth checking that's correct.
> 

AFAICT, return_address() acts like builtin_return_address(). That is, it
returns the address of the caller. If func() calls return_address(),
func() wants its caller's address. So, return_address() and func() need to
be skipped.

I will change it to skip 3 levels instead of 2.


> We should also mark return_address() as noinline to avoid surprises with
> LTO.
> 

Will do.

>> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
>> index 8982a2b78acf..1800310f92be 100644
>> --- a/arch/arm64/kernel/stacktrace.c
>> +++ b/arch/arm64/kernel/stacktrace.c
>> @@ -151,23 +151,21 @@ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
>>  }
>>  NOKPROBE_SYMBOL(walk_stackframe);
>>  
>> -static void dump_backtrace_entry(unsigned long where, const char *loglvl)
>> +static bool dump_backtrace_entry(void *arg, unsigned long where)
>>  {
>> +	char *loglvl = arg;
>>  	printk("%s %pSb\n", loglvl, (void *)where);
>> +	return true;
>>  }
>>  
>>  void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>>  		    const char *loglvl)
>>  {
>> -	struct stackframe frame;
>> -	int skip = 0;
>> -
>>  	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
>>  
>>  	if (regs) {
>>  		if (user_mode(regs))
>>  			return;
>> -		skip = 1;
>>  	}
> 
> We can simplifiy this to:
> 
> 	if (regs && user_mode(regs))
> 		return;
> 

OK.

>>  
>>  	if (!tsk)
>> @@ -176,36 +174,8 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>>  	if (!try_get_task_stack(tsk))
>>  		return;
>>  
>> -	if (tsk == current) {
>> -		start_backtrace(&frame,
>> -				(unsigned long)__builtin_frame_address(0),
>> -				(unsigned long)dump_backtrace);
>> -	} else {
>> -		/*
>> -		 * task blocked in __switch_to
>> -		 */
>> -		start_backtrace(&frame,
>> -				thread_saved_fp(tsk),
>> -				thread_saved_pc(tsk));
>> -	}
>> -
>>  	printk("%sCall trace:\n", loglvl);
>> -	do {
>> -		/* skip until specified stack frame */
>> -		if (!skip) {
>> -			dump_backtrace_entry(frame.pc, loglvl);
>> -		} else if (frame.fp == regs->regs[29]) {
>> -			skip = 0;
>> -			/*
>> -			 * Mostly, this is the case where this function is
>> -			 * called in panic/abort. As exception handler's
>> -			 * stack frame does not contain the corresponding pc
>> -			 * at which an exception has taken place, use regs->pc
>> -			 * instead.
>> -			 */
>> -			dump_backtrace_entry(regs->pc, loglvl);
>> -		}
>> -	} while (!unwind_frame(tsk, &frame));
>> +	arch_stack_walk(dump_backtrace_entry, (void *)loglvl, tsk, regs);
> 
> It turns out we currently need this skipping to get the balance the
> ftrace call stack, and arch_stack_walk() doesn't currently do the right
> thing when starting from regs. That balancing isn't quite right, and
> will be wrong in some case when unwinding across exception boundaries;
> we could implement HAVE_FUNCTION_GRAPH_RET_ADDR_PTR using the FP to
> solve that.
> 

I am not sure that I completely understand. So, I will study this and get back
to you with any questions.

>>  
>>  	put_task_stack(tsk);
>>  }
>> diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
>> index eebbc8d7123e..671b3038a772 100644
>> --- a/arch/arm64/kernel/time.c
>> +++ b/arch/arm64/kernel/time.c
>> @@ -32,22 +32,26 @@
>>  #include <asm/stacktrace.h>
>>  #include <asm/paravirt.h>
>>  
>> +static bool profile_pc_cb(void *arg, unsigned long pc)
>> +{
>> +	unsigned long *prof_pc = arg;
>> +
>> +	if (in_lock_functions(pc))
>> +		return true;
>> +	*prof_pc = pc;
>> +	return false;
>> +}
>> +
>>  unsigned long profile_pc(struct pt_regs *regs)
>>  {
>> -	struct stackframe frame;
>> +	unsigned long prof_pc = 0;
>>  
>>  	if (!in_lock_functions(regs->pc))
>>  		return regs->pc;
>>  
>> -	start_backtrace(&frame, regs->regs[29], regs->pc);
>> -
>> -	do {
>> -		int ret = unwind_frame(NULL, &frame);
>> -		if (ret < 0)
>> -			return 0;
>> -	} while (in_lock_functions(frame.pc));
>> +	arch_stack_walk(profile_pc_cb, &prof_pc, current, regs);
>>  
>> -	return frame.pc;
>> +	return prof_pc;
>>  }
>>  EXPORT_SYMBOL(profile_pc);
> 
> Mdoulo the problem above w.r.t. unwinding from regs, this looks good.
> 

Great. Thanks.

Madhavan


From p.yadav at ti.com  Tue Aug 24 10:30:20 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 24 Aug 2021 23:00:20 +0530
Subject: [PATCH v2 26/35] mtd: spi-nor: core: Introduce
 spi_nor_init_default_params()
In-Reply-To: <20210727045222.905056-27-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-27-tudor.ambarus@microchip.com>
Message-ID: <20210824173018.n6fw6t6mg4bwah37@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Called for all flashes, regardless if they define SFDP tables or not.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c | 92 +++++++++++++++++++++-----------------
>  1 file changed, 52 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index b3a01d7d6f0b..9193317f897d 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -2543,6 +2543,56 @@ static int spi_nor_setup(struct spi_nor *nor,
>  	return spi_nor_set_addr_width(nor);
>  }
>  
> +/**
> + * spi_nor_init_default_params() - Default initialization of flash parameters
> + * and settings. Done for all flashes, regardless is they define SFDP tables
> + * or not.
> + * @nor:	pointer to a 'struct spi_nor'.
> + */
> +static void spi_nor_init_default_params(struct spi_nor *nor)
> +{
> +	struct spi_nor_flash_parameter *params = nor->params;
> +	const struct flash_info *info = nor->info;
> +	struct device_node *np = spi_nor_get_flash_node(nor);
> +
> +	params->quad_enable = spi_nor_sr2_bit1_quad_enable;
> +	params->set_4byte_addr_mode = spansion_set_4byte_addr_mode;
> +	params->setup = spi_nor_default_setup;
> +	params->otp.org = &info->otp_org;
> +
> +	/* Default to 16-bit Write Status (01h) Command */
> +	nor->flags |= SNOR_F_HAS_16BIT_SR;
> +
> +	/* Set SPI NOR sizes. */
> +	params->writesize = 1;
> +	params->size = (u64)info->sector_size * info->n_sectors;
> +	params->page_size = info->page_size;

I think these two lines should go in spi_nor_info_init_params() since 
you are using the nor info to initialize these parameters. Otherwise, 
what even is the difference between these two functions?

> +
> +	if (!(info->flags & SPI_NOR_NO_FR)) {
> +		/* Default to Fast Read for DT and non-DT platform devices. */
> +		params->hwcaps.mask |= SNOR_HWCAPS_READ_FAST;
> +
> +		/* Mask out Fast Read if not requested at DT instantiation. */
> +		if (np && !of_property_read_bool(np, "m25p,fast-read"))
> +			params->hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST;
> +	}
> +
> +	/* (Fast) Read settings. */
> +	params->hwcaps.mask |= SNOR_HWCAPS_READ;
> +	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ],
> +				  0, 0, SPINOR_OP_READ,
> +				  SNOR_PROTO_1_1_1);
> +
> +	if (params->hwcaps.mask & SNOR_HWCAPS_READ_FAST)
> +		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_FAST],
> +					  0, 8, SPINOR_OP_READ_FAST,
> +					  SNOR_PROTO_1_1_1);
> +	/* Page Program settings. */
> +	params->hwcaps.mask |= SNOR_HWCAPS_PP;
> +	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
> +				SPINOR_OP_PP, SNOR_PROTO_1_1_1);
> +}
> +
>  /**
>   * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and
>   * settings based on MFR register and ->default_init() hook.
> @@ -2609,43 +2659,8 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
>  	struct spi_nor_flash_parameter *params = nor->params;
>  	struct spi_nor_erase_map *map = &params->erase_map;
>  	const struct flash_info *info = nor->info;
> -	struct device_node *np = spi_nor_get_flash_node(nor);
>  	u8 i, erase_mask;
>  
> -	/* Initialize default flash parameters and settings. */
> -	params->quad_enable = spi_nor_sr2_bit1_quad_enable;
> -	params->set_4byte_addr_mode = spansion_set_4byte_addr_mode;
> -	params->setup = spi_nor_default_setup;
> -	params->otp.org = &info->otp_org;
> -
> -	/* Default to 16-bit Write Status (01h) Command */
> -	nor->flags |= SNOR_F_HAS_16BIT_SR;
> -
> -	/* Set SPI NOR sizes. */
> -	params->writesize = 1;
> -	params->size = (u64)info->sector_size * info->n_sectors;
> -	params->page_size = info->page_size;
> -
> -	if (!(info->flags & SPI_NOR_NO_FR)) {
> -		/* Default to Fast Read for DT and non-DT platform devices. */
> -		params->hwcaps.mask |= SNOR_HWCAPS_READ_FAST;
> -
> -		/* Mask out Fast Read if not requested at DT instantiation. */
> -		if (np && !of_property_read_bool(np, "m25p,fast-read"))
> -			params->hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST;
> -	}
> -
> -	/* (Fast) Read settings. */
> -	params->hwcaps.mask |= SNOR_HWCAPS_READ;
> -	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ],
> -				  0, 0, SPINOR_OP_READ,
> -				  SNOR_PROTO_1_1_1);
> -
> -	if (params->hwcaps.mask & SNOR_HWCAPS_READ_FAST)
> -		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_FAST],
> -					  0, 8, SPINOR_OP_READ_FAST,
> -					  SNOR_PROTO_1_1_1);
> -
>  	if (info->flags & SPI_NOR_DUAL_READ) {
>  		params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2;
>  		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_1_1_2],
> @@ -2674,11 +2689,6 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
>  					  SNOR_PROTO_8_8_8_DTR);
>  	}
>  
> -	/* Page Program settings. */
> -	params->hwcaps.mask |= SNOR_HWCAPS_PP;
> -	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
> -				SPINOR_OP_PP, SNOR_PROTO_1_1_1);
> -
>  	if (info->flags & SPI_NOR_OCTAL_DTR_PP) {
>  		params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
>  		/*
> @@ -2823,6 +2833,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
>  	if (!nor->params)
>  		return -ENOMEM;
>  
> +	spi_nor_init_default_params(nor);
> +
>  	spi_nor_info_init_params(nor);
>  
>  	spi_nor_manufacturer_init_params(nor);

I am neutral towards this patch. I don't think it improves much, but at 
the same time it doesn't make anything worse either.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From dqfext at gmail.com  Tue Aug 24 10:32:37 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed, 25 Aug 2021 01:32:37 +0800
Subject: [PATCH net-next] net: dsa: mt7530: manually set up VLAN ID 0
In-Reply-To: <20210824165742.xvkb3ke7boryfoj4@skbuf>
References: <20210824165253.1691315-1-dqfext@gmail.com>
 <20210824165742.xvkb3ke7boryfoj4@skbuf>
Message-ID: <20210824173237.1691654-1-dqfext@gmail.com>

On Tue, Aug 24, 2021 at 07:57:42PM +0300, Vladimir Oltean wrote:
> I understand that this is how you noticed the issue, but please remember
> that one can always compile a kernel with CONFIG_VLAN_8021Q=n. So the
> issue predates my patch by much longer. You might reconsider the Fixes:
> tag in light of this, maybe the patch needs to be sent to stable.

Okay. So the Fixes tag should be 6087175b7991, which initially adds the
software fallback support for mt7530.

> 
> > +static int
> > +mt7530_setup_vlan0(struct mt7530_priv *priv)
> > +{
> > +	u32 val;
> > +
> > +	/* Validate the entry with independent learning, keep the original
> > +	 * ingress tag attribute.
> > +	 */
> > +	val = IVL_MAC | EG_CON | PORT_MEM(MT7530_ALL_MEMBERS) | FID(FID_BRIDGED) |
> 
> FID_BRIDGED?

What's wrong with that?

> 
> > +	      VLAN_VALID;
> > +	mt7530_write(priv, MT7530_VAWD1, val);
> > +
> > +	return mt7530_vlan_cmd(priv, MT7530_VTCR_WR_VID, 0);
> > +}
> 


From olteanv at gmail.com  Tue Aug 24 10:37:14 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Tue, 24 Aug 2021 20:37:14 +0300
Subject: [PATCH net-next] net: dsa: mt7530: manually set up VLAN ID 0
In-Reply-To: <20210824173237.1691654-1-dqfext@gmail.com>
References: <20210824165253.1691315-1-dqfext@gmail.com>
 <20210824165742.xvkb3ke7boryfoj4@skbuf>
 <20210824173237.1691654-1-dqfext@gmail.com>
Message-ID: <20210824173714.cgpt2addxyjzlbyy@skbuf>

On Wed, Aug 25, 2021 at 01:32:37AM +0800, DENG Qingfang wrote:
> On Tue, Aug 24, 2021 at 07:57:42PM +0300, Vladimir Oltean wrote:
> > I understand that this is how you noticed the issue, but please remember
> > that one can always compile a kernel with CONFIG_VLAN_8021Q=n. So the
> > issue predates my patch by much longer. You might reconsider the Fixes:
> > tag in light of this, maybe the patch needs to be sent to stable.
>
> Okay. So the Fixes tag should be 6087175b7991, which initially adds the
> software fallback support for mt7530.

Ok. Did the old code not need VLAN 0 for VLAN-unaware ports, or are you
saying that since the VLAN table lookup was bypassed completely in the
old code, 'no VLAN 0' was an inconsequential error?

I think it's the latter. Just wanted to make sure. So that means, either
this Fixes: tag or the other, the patch still belongs to net-next. From
my side you shouldn't need to resend.

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>

> > > +static int
> > > +mt7530_setup_vlan0(struct mt7530_priv *priv)
> > > +{
> > > +	u32 val;
> > > +
> > > +	/* Validate the entry with independent learning, keep the original
> > > +	 * ingress tag attribute.
> > > +	 */
> > > +	val = IVL_MAC | EG_CON | PORT_MEM(MT7530_ALL_MEMBERS) | FID(FID_BRIDGED) |
> >
> > FID_BRIDGED?
>
> What's wrong with that?

Nothing, I had a senior moment and I forgot how mt7530 sets up things.


From catalin.marinas at arm.com  Tue Aug 24 10:37:41 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 18:37:41 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
Message-ID: <20210824173741.GC623@arm.com>

Hi Alex,

Thanks for the report.

On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
> it seems there is a regression in arm64 memory mapping in 5.14, since it
> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
> 
> [??? 8.921909] ------------[ cut here ]------------
> [??? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
> [??? 8.921973] Modules linked in: spi_rockchip(+) fuse
> [??? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
> [??? 8.922004] Hardware name: Pine64 Rock64 (DT)
> [??? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
> [??? 8.922018] pc : dma_map_resource+0x68/0xc0
> [??? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
> [??? 8.922040] sp : ffff800012102ae0
> [??? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
> [??? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
> [??? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
> [??? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
> [??? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> [??? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
> [??? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
> [??? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
> [??? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
> [??? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
> [??? 8.922158] Call trace:
> [??? 8.922163]? dma_map_resource+0x68/0xc0
> [??? 8.922173]? pl330_prep_slave_sg+0x58/0x220
> [??? 8.922181]? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
> [??? 8.922208]? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
[...]
> Note: This does not relate to the spi driver - when disabling this device in
> the device tree it fails for any other (i2s, for instance) which uses dma.
> Commenting out the failing check at [1], however, helps and the mapping
> works again.

Do you know which address dma_map_resource() is trying to map (maybe
add some printk())? It's not supposed to map RAM, hence the warning.
Random guess, the address is 0xff190800 (based on the x1 above but the
regs might as well be mangled).

> I tried to follow the recent changes for arm64 mm which could relate to the
> check failing at [1] and reverting
> ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
> helps and makes it work again, but I'm 100% uncertain if that commit is
> really the culprit.
> 
> Note, that the firmware (legacy u-boot) injects memory configuration in the
> device tree as follows:
> 
> /memreserve/??? 0x00000000fcefc000 0x000000000000d000;
> / {
> ..
> ??? compatible = "pine64,rock64\0rockchip,rk3328";
> ..
> ??? memory {
> ??? ??? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
> ??? ??? device_type = "memory";
> ??? };
> 
> ..
> }

Either pfn_valid() gets confused in 5.14 or something is wrong with the
DT. I have a suspicion it's the former since reverting the above commit
makes it disappear.

> So: there is a "hole" in the mappable memory and reading the commit message
> of
> ? commit a7d9f306ba70 ("arm64: drop pfn_valid_within() and simplify
> pfn_valid()")
> suggests, there was a change for that case recently.

I think the change from the arm64 pfn_valid() to the generic one is
avoiding the call to memblock_is_memory(). I wonder whether pfn_valid()
returns true just because we have a struct page available but the memory
may have been reserved.

Cc'ing Mike R.

> I also noticed there is a diff in the kernel log regarding memory init up
> until 5.13.12 it says
> 
> [??? 0.000000] Zone ranges:
> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
> [??? 0.000000]?? DMA32??? empty
> [??? 0.000000]?? Normal?? empty
> [??? 0.000000] Movable zone start for each node
> [??? 0.000000] Early memory node ranges
> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
> [??? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
> [??? 0.000000] On node 0 totalpages: 1043968
> [??? 0.000000]?? DMA zone: 16312 pages used for memmap
> [??? 0.000000]?? DMA zone: 0 pages reserved
> [??? 0.000000]?? DMA zone: 1043968 pages, LIFO batch:63
> 
> In contrary in 5.14-rc7 it says:
> 
> [??? 0.000000] Zone ranges:
> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
> [??? 0.000000]?? DMA32??? empty
> [??? 0.000000]?? Normal?? empty
> [??? 0.000000] Movable zone start for each node
> [??? 0.000000] Early memory node ranges
> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
> [??? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
> [??? 0.000000] On node 0, zone DMA: 512 pages in unavailable ranges
> [??? 0.000000] On node 0, zone DMA: 4096 pages in unavailable ranges
> 
> (note the "unavailable ranges")
> I'm uncertain again here, if that diff is expected behavior because of those
> recent mm changes for arm64.
> 
> After reverting
> ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
> the log changes to
> 
> [??? 0.000000] Zone ranges:
> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
> [??? 0.000000]?? DMA32??? empty
> [??? 0.000000]?? Normal?? empty
> [??? 0.000000] Movable zone start for each node
> [??? 0.000000] Early memory node ranges
> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
> [??? 0.000000] Initmem setup node 0 [mem
> 0x0000000000200000-0x00000000feffffff]
> 
> (no DMA zones here)
> 
> As you might have noticed I have _zero_ clue about memory mapping and dma
> subsystem - so let me know if there is any more information needed for that
> and thanks for your help.

Adding Robin as well, he has a better clue than us on DMA ;).

> Alex
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/dma/mapping.c?id=e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93#n235

-- 
Catalin


From madvenka at linux.microsoft.com  Tue Aug 24 10:38:25 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Tue, 24 Aug 2021 12:38:25 -0500
Subject: [RFC PATCH v8 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <da2bb980-09c3-5a39-73cd-ca4de4c38d51@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-2-madvenka@linux.microsoft.com>
 <20210824131344.GE96738@C02TD0UTHF1T.local>
 <da2bb980-09c3-5a39-73cd-ca4de4c38d51@linux.microsoft.com>
Message-ID: <66d0ff83-bf67-5576-4c74-10f825855091@linux.microsoft.com>



>>> diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c
>>> index a6d18755652f..92a0f4d434e4 100644
>>> --- a/arch/arm64/kernel/return_address.c
>>> +++ b/arch/arm64/kernel/return_address.c
>>> @@ -35,15 +35,11 @@ NOKPROBE_SYMBOL(save_return_addr);
>>>  void *return_address(unsigned int level)
>>>  {
>>>  	struct return_address_data data;
>>> -	struct stackframe frame;
>>>  
>>>  	data.level = level + 2;
>>>  	data.addr = NULL;
>>>  
>>> -	start_backtrace(&frame,
>>> -			(unsigned long)__builtin_frame_address(0),
>>> -			(unsigned long)return_address);
>>> -	walk_stackframe(current, &frame, save_return_addr, &data);
>>> +	arch_stack_walk(save_return_addr, &data, current, NULL);
>>>  
>>>  	if (!data.level)
>>>  		return data.addr;
>>
>> Nor that arch_stack_walk() will start with it's caller, so
>> return_address() will be included in the trace where it wasn't
>> previously, which implies we need to skip an additional level.
>>
> 
> You are correct. I will fix this. Thanks for catching this.
> 
>> That said, I'm not entirely sure why we need to skip 2 levels today; it
>> might be worth checking that's correct.
>>
> 
> AFAICT, return_address() acts like builtin_return_address(). That is, it
> returns the address of the caller. If func() calls return_address(),
> func() wants its caller's address. So, return_address() and func() need to
> be skipped.
> 
> I will change it to skip 3 levels instead of 2.
> 

Actually, I take that back. I remember now. return_address() used to start
with PC=return_address(). That is, it used to start with itself. arch_stack_walk()
starts with its caller which, in this case, is return_address(). So, I don't need
to change anything.

Do you agree?

Madhavan


From broonie at kernel.org  Tue Aug 24 10:38:50 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 24 Aug 2021 18:38:50 +0100
Subject: [RFC PATCH v8 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <da2bb980-09c3-5a39-73cd-ca4de4c38d51@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-2-madvenka@linux.microsoft.com>
 <20210824131344.GE96738@C02TD0UTHF1T.local>
 <da2bb980-09c3-5a39-73cd-ca4de4c38d51@linux.microsoft.com>
Message-ID: <20210824173850.GN4393@sirena.org.uk>

On Tue, Aug 24, 2021 at 12:21:28PM -0500, Madhavan T. Venkataraman wrote:
> On 8/24/21 8:13 AM, Mark Rutland wrote:
> > On Thu, Aug 12, 2021 at 02:06:00PM -0500, madvenka at linux.microsoft.com wrote:

> > Note that arch_stack_walk() depends on CONFIG_STACKTRACE (which is not in
> > defconfig), so we'll need to reorganise things such that it's always defined,
> > or factor out the core of that function and add a wrapper such that we
> > can always use it.

> I will include CONFIG_STACKTRACE in defconfig, if that is OK with you and
> Mark Brown.

That might be separately useful but it doesn't address the issue, if
something is optional we need to handle the case where that option is
disabled.  It'll need to be one of the two options Mark Rutland
mentioned above.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210824/c111fd5a/attachment.sig>

From madvenka at linux.microsoft.com  Tue Aug 24 10:40:53 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Tue, 24 Aug 2021 12:40:53 -0500
Subject: [RFC PATCH v8 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210824173850.GN4393@sirena.org.uk>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-2-madvenka@linux.microsoft.com>
 <20210824131344.GE96738@C02TD0UTHF1T.local>
 <da2bb980-09c3-5a39-73cd-ca4de4c38d51@linux.microsoft.com>
 <20210824173850.GN4393@sirena.org.uk>
Message-ID: <f906ab5f-cfa8-17b5-843f-77869cf48586@linux.microsoft.com>



On 8/24/21 12:38 PM, Mark Brown wrote:
> On Tue, Aug 24, 2021 at 12:21:28PM -0500, Madhavan T. Venkataraman wrote:
>> On 8/24/21 8:13 AM, Mark Rutland wrote:
>>> On Thu, Aug 12, 2021 at 02:06:00PM -0500, madvenka at linux.microsoft.com wrote:
> 
>>> Note that arch_stack_walk() depends on CONFIG_STACKTRACE (which is not in
>>> defconfig), so we'll need to reorganise things such that it's always defined,
>>> or factor out the core of that function and add a wrapper such that we
>>> can always use it.
> 
>> I will include CONFIG_STACKTRACE in defconfig, if that is OK with you and
>> Mark Brown.
> 
> That might be separately useful but it doesn't address the issue, if
> something is optional we need to handle the case where that option is
> disabled.  It'll need to be one of the two options Mark Rutland
> mentioned above.
> 

OK. I will do it so it is always defined.

Thanks.

Madhavan


From jason-jh.lin at mediatek.com  Tue Aug 24 10:47:29 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 25 Aug 2021 01:47:29 +0800
Subject: [PATCH v8 07/13] soc: mediatek: add mtk-mutex support for
 mt8195 vdosys0
In-Reply-To: <CAAOTY_8xGRJmFaEEsZoJs22zfqm+CO0pFesThwK6K0bknNBtoQ@mail.gmail.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-8-jason-jh.lin@mediatek.com>
 <CAAOTY_8xGRJmFaEEsZoJs22zfqm+CO0pFesThwK6K0bknNBtoQ@mail.gmail.com>
Message-ID: <8ea537f131ae75b6a7ef67c7622f929edff92318.camel@mediatek.com>

Hi Chun-Kuang,

Thanks for the review.

On Thu, 2021-08-19 at 23:12 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
> > 
> > Add mtk-mutex support for mt8195 vdosys0.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> >  drivers/soc/mediatek/mtk-mutex.c | 98
> > +++++++++++++++++++++++++++++++-
> >  1 file changed, 95 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-mutex.c
> > b/drivers/soc/mediatek/mtk-mutex.c
> > index 2e4bcc300576..c177156ee2fa 100644
> > --- a/drivers/soc/mediatek/mtk-mutex.c
> > +++ b/drivers/soc/mediatek/mtk-mutex.c
> > @@ -17,6 +17,9 @@
> >  #define MT8183_MUTEX0_MOD0                     0x30
> >  #define MT8183_MUTEX0_SOF0                     0x2c
> > 
> > +#define MT8195_DISP_MUTEX0_MOD0                        0x30
> > +#define MT8195_DISP_MUTEX0_SOF                 0x2c
> > +
> >  #define DISP_REG_MUTEX_EN(n)                   (0x20 + 0x20 * (n))
> >  #define DISP_REG_MUTEX(n)                      (0x24 + 0x20 * (n))
> >  #define DISP_REG_MUTEX_RST(n)                  (0x28 + 0x20 * (n))
> > @@ -67,6 +70,36 @@
> >  #define MT8173_MUTEX_MOD_DISP_PWM1             24
> >  #define MT8173_MUTEX_MOD_DISP_OD               25
> > 
> > +#define MT8195_MUTEX_MOD_DISP_OVL0             0
> > +#define MT8195_MUTEX_MOD_DISP_WDMA0            1
> > +#define MT8195_MUTEX_MOD_DISP_RDMA0            2
> > +#define MT8195_MUTEX_MOD_DISP_COLOR0           3
> > +#define MT8195_MUTEX_MOD_DISP_CCORR0           4
> > +#define MT8195_MUTEX_MOD_DISP_AAL0             5
> > +#define MT8195_MUTEX_MOD_DISP_GAMMA0           6
> > +#define MT8195_MUTEX_MOD_DISP_DITHER0          7
> > +#define MT8195_MUTEX_MOD_DISP_DSI0             8
> > +#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0  9
> > +#define MT8195_MUTEX_MOD_DISP_OVL1             10
> > +#define MT8195_MUTEX_MOD_DISP_WDMA1            11
> > +#define MT8195_MUTEX_MOD_DISP_RDMA1            12
> > +#define MT8195_MUTEX_MOD_DISP_COLOR1           13
> > +#define MT8195_MUTEX_MOD_DISP_CCORR1           14
> > +#define MT8195_MUTEX_MOD_DISP_AAL1             15
> > +#define MT8195_MUTEX_MOD_DISP_GAMMA1           16
> > +#define MT8195_MUTEX_MOD_DISP_DITHER1          17
> > +#define MT8195_MUTEX_MOD_DISP_DSI1             18
> > +#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1  19
> > +#define MT8195_MUTEX_MOD_DISP_VPP_MERGE                20
> > +#define MT8195_MUTEX_MOD_DISP_DP_INTF0         21
> > +#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0   22
> > +#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1   23
> > +#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2   24
> > +#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3   25
> > +#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4   26
> > +#define MT8195_MUTEX_MOD_DISP_PWM0             27
> > +#define MT8195_MUTEX_MOD_DISP_PWM1             28
> > +
> >  #define MT2712_MUTEX_MOD_DISP_PWM2             10
> >  #define MT2712_MUTEX_MOD_DISP_OVL0             11
> >  #define MT2712_MUTEX_MOD_DISP_OVL1             12
> > @@ -101,12 +134,27 @@
> >  #define MT2712_MUTEX_SOF_DSI3                  6
> >  #define MT8167_MUTEX_SOF_DPI0                  2
> >  #define MT8167_MUTEX_SOF_DPI1                  3
> > +
> >  #define MT8183_MUTEX_SOF_DSI0                  1
> >  #define MT8183_MUTEX_SOF_DPI0                  2
> > 
> >  #define
> > MT8183_MUTEX_EOF_DSI0                  (MT8183_MUTEX_SOF_DSI0 << 6)
> >  #define
> > MT8183_MUTEX_EOF_DPI0                  (MT8183_MUTEX_SOF_DPI0 << 6)
> > 
> > +#define MT8195_MUTEX_SOF_DSI0                  1
> > +#define MT8195_MUTEX_SOF_DSI1                  2
> > +#define MT8195_MUTEX_SOF_DP_INTF0              3
> > +#define MT8195_MUTEX_SOF_DP_INTF1              4
> > +#define MT8195_MUTEX_SOF_DPI0                  6 /* for HDMI_TX */
> > +#define MT8195_MUTEX_SOF_DPI1                  5 /* for digital
> > video out */
> > +
> > +#define
> > MT8195_MUTEX_EOF_DSI0                  (MT8195_MUTEX_SOF_DSI0 << 7)
> > +#define
> > MT8195_MUTEX_EOF_DSI1                  (MT8195_MUTEX_SOF_DSI1 << 7)
> > +#define
> > MT8195_MUTEX_EOF_DP_INTF0              (MT8195_MUTEX_SOF_DP_INTF0
> > << 7)
> > +#define
> > MT8195_MUTEX_EOF_DP_INTF1              (MT8195_MUTEX_SOF_DP_INTF1
> > << 7)
> > +#define
> > MT8195_MUTEX_EOF_DPI0                  (MT8195_MUTEX_SOF_DPI0 << 7)
> > +#define
> > MT8195_MUTEX_EOF_DPI1                  (MT8195_MUTEX_SOF_DPI1 << 7)
> > +
> >  struct mtk_mutex {
> >         int id;
> >         bool claimed;
> > @@ -120,6 +168,9 @@ enum mtk_mutex_sof_id {
> >         MUTEX_SOF_DPI1,
> >         MUTEX_SOF_DSI2,
> >         MUTEX_SOF_DSI3,
> > +       MUTEX_SOF_DP_INTF0,
> > +       MUTEX_SOF_DP_INTF1,
> > +       DDP_MUTEX_SOF_MAX,
> >  };
> > 
> >  struct mtk_mutex_data {
> > @@ -214,7 +265,23 @@ static const unsigned int
> > mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> >         [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
> >  };
> > 
> > -static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> > +static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] =
> > {
> > +       [DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
> > +       [DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
> > +       [DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
> > +       [DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
> > +       [DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
> > +       [DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
> > +       [DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
> > +       [DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
> > +       [DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
> > +       [DDP_COMPONENT_DSC0] =
> > MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
> > +       [DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
> > +       [DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
> > +       [DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
> > +};
> > +
> > +static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
> >         [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> >         [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
> >         [MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
> > @@ -224,7 +291,7 @@ static const unsigned int
> > mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> >         [MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
> >  };
> > 
> > -static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> > +static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
> >         [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> >         [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
> >         [MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
> > @@ -232,12 +299,24 @@ static const unsigned int
> > mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> >  };
> > 
> >  /* Add EOF setting so overlay hardware can receive frame done irq
> > */
> > -static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> > +static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
> >         [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> >         [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
> >         [MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 |
> > MT8183_MUTEX_EOF_DPI0,
> >  };
> > 
> > +static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
> > +       [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> > +       [MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 |
> > MT8195_MUTEX_EOF_DSI0,
> > +       [MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 |
> > MT8195_MUTEX_EOF_DSI1,
> > +       [MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 |
> > MT8195_MUTEX_EOF_DPI0,
> > +       [MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 |
> > MT8195_MUTEX_EOF_DPI1,
> > +       [MUTEX_SOF_DP_INTF0] =
> > +               MT8195_MUTEX_SOF_DP_INTF0 |
> > MT8195_MUTEX_EOF_DP_INTF0,
> > +       [MUTEX_SOF_DP_INTF1] =
> > +               MT8195_MUTEX_SOF_DP_INTF1 |
> > MT8195_MUTEX_EOF_DP_INTF1,
> 
> Why do you or EOF?
> 
> Regards,
> Chun-Kuang.
> 

The value of mt8195_mutex_sof will be set into this register,
#define MT8195_DISP_MUTEX0_SOF			0x2c
which is providing the source module selection of SOF(Start of Frame)
and EOF(End of Frame) in current stream(MUTEX).

MUTEX will send the EOF trigger signal to all sourcesub-module whose
EOF is selected in this register.

So I think we should or EOF to make sure sub-module cloud get both SOF
and EOF trigger signal for status checking, error handling or
debugging.

> > +};
> > +
> >  static const struct mtk_mutex_data mt2701_mutex_driver_data = {
> >         .mutex_mod = mt2701_mutex_mod,
> >         .mutex_sof = mt2712_mutex_sof,
> > @@ -275,6 +354,13 @@ static const struct mtk_mutex_data
> > mt8183_mutex_driver_data = {
> >         .no_clk = true,
> >  };
> > 
> > +static const struct mtk_mutex_data mt8195_mutex_driver_data = {
> > +       .mutex_mod = mt8195_mutex_mod,
> > +       .mutex_sof = mt8195_mutex_sof,
> > +       .mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
> > +       .mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
> > +};
> > +
> >  struct mtk_mutex *mtk_mutex_get(struct device *dev)
> >  {
> >         struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
> > @@ -347,6 +433,9 @@ void mtk_mutex_add_comp(struct mtk_mutex
> > *mutex,
> >         case DDP_COMPONENT_DPI1:
> >                 sof_id = MUTEX_SOF_DPI1;
> >                 break;
> > +       case DDP_COMPONENT_DP_INTF0:
> > +               sof_id = MUTEX_SOF_DP_INTF0;
> > +               break;
> 
> How about MUTEX_SOF_DP_INTF1?

MUTEX_SOF_DP_INTF1 won't use in vdosys0, so it will be added at the
patch [1] in vdosys1 series.
[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20210818091847.8060-12-nancy.lin at mediatek.com/
> 
> >         default:
> >                 if (mtx->data->mutex_mod[id] < 32) {
> >                         offset = DISP_REG_MUTEX_MOD(mtx->data-
> > >mutex_mod_reg,
> > @@ -386,6 +475,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex
> > *mutex,
> >         case DDP_COMPONENT_DSI3:
> >         case DDP_COMPONENT_DPI0:
> >         case DDP_COMPONENT_DPI1:
> > +       case DDP_COMPONENT_DP_INTF0:
> 
> Ditto.
> 
> Regards,
> Chun-Kuang.
> 
Ditto.

Regards,
Jason-JH.Lin

> >                 writel_relaxed(MUTEX_SOF_SINGLE_MODE,
> >                                mtx->regs +
> >                                DISP_REG_MUTEX_SOF(mtx->data-
> > >mutex_sof_reg,
> > @@ -507,6 +597,8 @@ static const struct of_device_id
> > mutex_driver_dt_match[] = {
> >           .data = &mt8173_mutex_driver_data},
> >         { .compatible = "mediatek,mt8183-disp-mutex",
> >           .data = &mt8183_mutex_driver_data},
> > +       { .compatible = "mediatek,mt8195-disp-mutex",
> > +         .data = &mt8195_mutex_driver_data},
> >         {},
> >  };
> >  MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From p.yadav at ti.com  Tue Aug 24 10:51:40 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 24 Aug 2021 23:21:40 +0530
Subject: [PATCH v2 27/35] mtd: spi-nor: core: Init flash params based on
 SFDP first for new flash additions
In-Reply-To: <20210727045222.905056-28-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-28-tudor.ambarus@microchip.com>
Message-ID: <20210824175138.vggtefa5xoomcjto@ti.com>

On 27/07/21 07:52AM, Tudor Ambarus wrote:
> Remove the spagetti way of initializing flash parameters and settings,
> at least for the new flash additions (for now). All flash entries should
> be converted to either use SPI_NOR_PARSE_SFDP or SPI_NOR_SKIP_SFDP.
> SPI_NOR_SKIP_SFDP should be set either when the SFDP tables are completely
> wrong and we can't parse relevant data, or when the SFDP tables are not
> defined at all, or when RDSFDP command is not supported by the flash.
> After all the flash entries will be converted to use these flags and after
> the default_init() hook will be removed, the
> spi_nor_init_params_deprecated() will be replaced by
> spi_nor_info_init_params(). The flash parameters and settings will be
> initialized either by parsing SFDP, or via the flash info flags.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  drivers/mtd/spi-nor/core.c | 103 +++++++++++++++++++++++++------------
>  1 file changed, 70 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 9193317f897d..ef06a8d6abb8 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -2627,28 +2627,6 @@ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
>  		nor->info->fixups->post_sfdp(nor);
>  }
>  
> -/**
> - * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
> - * based on JESD216 SFDP standard.
> - * @nor:	pointer to a 'struct spi_nor'.
> - *
> - * The method has a roll-back mechanism: in case the SFDP parsing fails, the
> - * legacy flash parameters and settings will be restored.
> - */
> -static void spi_nor_sfdp_init_params(struct spi_nor *nor)
> -{
> -	struct spi_nor_flash_parameter sfdp_params;
> -
> -	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
> -
> -	if (!spi_nor_parse_sfdp(nor))
> -		return spi_nor_post_sfdp_fixups(nor);
> -
> -	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
> -	nor->addr_width = 0;
> -	nor->flags &= ~SNOR_F_4B_OPCODES;
> -}
> -
>  /**
>   * spi_nor_info_init_params() - Initialize the flash's parameters and settings
>   * based on nor->info data.
> @@ -2722,6 +2700,39 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
>  	spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
>  }
>  
> +/**
> + * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
> + * based on JESD216 SFDP standard.
> + * @nor:	pointer to a 'struct spi_nor'.

Missing documentation for treat_id_collisions.

Also, I assume this will go away when we get rid of 
spi_nor_init_params_deprecated(), correct?

> + *
> + * The method has a roll-back mechanism: in case the SFDP parsing fails, the
> + * legacy flash parameters and settings will be restored.
> + */
> +static void spi_nor_sfdp_init_params(struct spi_nor *nor,
> +				     bool treat_id_collisions)
> +{
> +	struct spi_nor_flash_parameter sfdp_params;
> +
> +	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
> +
> +	if (!spi_nor_parse_sfdp(nor))
> +		return spi_nor_post_sfdp_fixups(nor);
> +
> +	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
> +	nor->addr_width = 0;
> +	nor->flags &= ~SNOR_F_4B_OPCODES;
> +
> +	if (!treat_id_collisions)
> +		return;

No, this doesn't seem quite right. Why would you not want to treat ID 
collisions for flashes that use spi_nor_init_params_deprecated()? What 
makes this not possible for them?

Anyway, even if we don't want to treat ID collisions for those flashes, 
we can't just return here. In the previous code, nor->params is already 
initialized by spi_nor_info_init_params() so restoring that via memcpy() 
would make sense since it would restore the info-initialized state. Now 
it would be just 0, with no useful information in there. You are bound 
to run into errors somewhere down the line.

So I think you either need to make this function return an error and 
propagate it up the call chain or run spi_nor_info_init_params() for 
both type of flashes to make sure we do our best effort to initialize 
the flash.

> +	/*
> +	 * Fallback to flash info params init in case the SFDP parsing fails.
> +	 * Used to handle ID collisions between flashes that define the SFDP
> +	 * tables and flashes that don't.
> +	 */
> +	spi_nor_info_init_params(nor);
> +	spi_nor_manufacturer_init_params(nor);
> +}
> +
>  /**
>   * spi_nor_late_init_params() - Late initialization of default flash parameters.
>   * @nor:	pointer to a 'struct spi_nor'
> @@ -2797,7 +2808,9 @@ static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
>  }
>  
>  /**
> - * spi_nor_init_params() - Initialize the flash's parameters and settings.
> + * spi_nor_init_params_deprecated() - Initialize the flash's parameters and
> + * settings. The function is deprecated, it will be removed and replaced with
> + * spi_nor_info_init_params().
>   * @nor:	pointer to a 'struct spi_nor'.
>   *
>   * The flash parameters and settings are initialized based on a sequence of
> @@ -2821,11 +2834,40 @@ static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
>   *    Please note that there are ->post_{bfpt, sfdp}() fixup hooks that can
>   *    overwrite the flash parameters and settings immediately after table
>   *    parsing.
> + */
> +static void spi_nor_init_params_deprecated(struct spi_nor *nor)
> +{
> +	spi_nor_info_init_params(nor);
> +	spi_nor_manufacturer_init_params(nor);
> +
> +	if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> +				 SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&
> +	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
> +		spi_nor_sfdp_init_params(nor, false);
> +}
> +
> +/**
> + * spi_nor_init_params() - Initialize the flash's parameters and settings.
> + * @nor:	pointer to a 'struct spi_nor'.
> + *
> + * The flash parameters and settings are initialized based on a sequence of
> + * calls that are ordered by priority:
> + *
> + * 1/ Default flash parameters initialization. The initializations are done
> + *    for all the flashes, regardless if the support SFDP or not.
> + *		spi_nor_init_default_params()
> + * which can be overwritten by:
>   *
> + * 2/ SFDP based or the deprecated way of initializing flash parameters.
> + * Ideally at this step the flash parameters init will be done either by
> + * parsing SFDP, where supported, or statically via flash_info flags.
> + *		spi_nor_sfdp_init_params() or spi_nor_init_params_deprecated()
>   * which can be overwritten by:
> - * 4/ Late flash parameters initialization, used to initialize flash
> + *
> + * 3/ Late flash parameters initialization, used to initialize flash
>   * parameters that are not declared in the JESD216 SFDP standard.
>   *		spi_nor_late_init_params()
> + *

Not really related to this patch, but we need to document the return 
value here as well.

>   */
>  static int spi_nor_init_params(struct spi_nor *nor)
>  {
> @@ -2835,15 +2877,10 @@ static int spi_nor_init_params(struct spi_nor *nor)
>  
>  	spi_nor_init_default_params(nor);
>  
> -	spi_nor_info_init_params(nor);
> -
> -	spi_nor_manufacturer_init_params(nor);
> -
> -	if ((nor->info->flags & (SPI_NOR_PARSE_SFDP |
> -				 SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -				 SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&
> -	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
> -		spi_nor_sfdp_init_params(nor);
> +	if (nor->info->flags & SPI_NOR_PARSE_SFDP)
> +		spi_nor_sfdp_init_params(nor, true);
> +	else
> +		spi_nor_init_params_deprecated(nor);
>  
>  	spi_nor_late_init_params(nor);
>  
> -- 
> 2.25.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From jason-jh.lin at mediatek.com  Tue Aug 24 10:55:26 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 25 Aug 2021 01:55:26 +0800
Subject: [PATCH v8 10/13] drm/mediatek: adjust to the alphabetic order
 for mediatek-drm
In-Reply-To: <CAAOTY__k28K1LeH-ctavFi9GE9p32kL6K3sxhA0TW54XPsEB-w@mail.gmail.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-11-jason-jh.lin@mediatek.com>
 <CAAOTY__k28K1LeH-ctavFi9GE9p32kL6K3sxhA0TW54XPsEB-w@mail.gmail.com>
Message-ID: <655a9f82a9f19f506acfc05bf7bac4502e32b785.camel@mediatek.com>

Hi Chun-Kuang,

Thanks for the review.

On Fri, 2021-08-20 at 07:14 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:24???
> > 
> > Adjust to the alphabetic order for the define, function, struct
> > and array in mediatek-drm driver
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 133 ++++++++++----
> > ------
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  22 ++--
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  76 +++++------
> >  3 files changed, 115 insertions(+), 116 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 93beb980414f..28bc42fd0b8a 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -20,17 +20,9 @@
> >  #include "mtk_drm_ddp_comp.h"
> >  #include "mtk_drm_crtc.h"
> > 
> > -#define DISP_REG_OD_EN                         0x0000
> > -#define DISP_REG_OD_CFG                                0x0020
> > -#define DISP_REG_OD_SIZE                       0x0030
> > -#define DISP_REG_DITHER_5                      0x0114
> > -#define DISP_REG_DITHER_7                      0x011c
> > -#define DISP_REG_DITHER_15                     0x013c
> > -#define DISP_REG_DITHER_16                     0x0140
> > -
> > -#define DISP_REG_UFO_START                     0x0000
> > 
> >  #define DISP_REG_AAL_EN                                0x0000
> > +#define AAL_EN                                 BIT(0)
> >  #define DISP_REG_AAL_SIZE                      0x0030
> > 
> >  #define DISP_REG_DITHER_EN                     0x0000
> > @@ -38,23 +30,29 @@
> >  #define DISP_REG_DITHER_CFG                    0x0020
> >  #define DITHER_RELAY_MODE                      BIT(0)
> >  #define DITHER_ENGINE_EN                       BIT(1)
> > -#define DISP_REG_DITHER_SIZE                   0x0030
> > -
> > -#define OD_RELAYMODE                           BIT(0)
> > -
> > -#define UFO_BYPASS                             BIT(2)
> > -
> > -#define AAL_EN                                 BIT(0)
> > 
> >  #define DISP_DITHERING                         BIT(2)
> > +#define DISP_REG_DITHER_SIZE                   0x0030
> > +#define DISP_REG_DITHER_5                      0x0114
> > +#define DISP_REG_DITHER_7                      0x011c
> > +#define DISP_REG_DITHER_15                     0x013c
> >  #define DITHER_LSB_ERR_SHIFT_R(x)              (((x) & 0x7) << 28)
> >  #define DITHER_ADD_LSHIFT_R(x)                 (((x) & 0x7) << 20)
> >  #define DITHER_NEW_BIT_MODE                    BIT(0)
> > +#define DISP_REG_DITHER_16                     0x0140
> >  #define DITHER_LSB_ERR_SHIFT_B(x)              (((x) & 0x7) << 28)
> >  #define DITHER_ADD_LSHIFT_B(x)                 (((x) & 0x7) << 20)
> >  #define DITHER_LSB_ERR_SHIFT_G(x)              (((x) & 0x7) << 12)
> >  #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
> > 
> > +#define DISP_REG_OD_EN                         0x0000
> > +#define DISP_REG_OD_CFG                                0x0020
> > +#define OD_RELAYMODE                           BIT(0)
> > +#define DISP_REG_OD_SIZE                       0x0030
> > +
> > +#define DISP_REG_UFO_START                     0x0000
> > +#define UFO_BYPASS                             BIT(2)
> > +
> >  struct mtk_ddp_comp_dev {
> >         struct clk *clk;
> >         void __iomem *regs;
> > @@ -106,20 +104,6 @@ void mtk_ddp_write_mask(struct cmdq_pkt
> > *cmdq_pkt, unsigned int value,
> >  #endif
> >  }
> > 
> > -static int mtk_ddp_clk_enable(struct device *dev)
> > -{
> > -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > -
> > -       return clk_prepare_enable(priv->clk);
> > -}
> > -
> > -static void mtk_ddp_clk_disable(struct device *dev)
> > -{
> > -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > -
> > -       clk_disable_unprepare(priv->clk);
> > -}
> > -
> 
> I would like to place the same group together. mtk_ddp_clk_enable()
> and mtk_ddp_clk_disable() are common function not belong to any sub
> driver. So I would like keep these function here.
> 
> Regards,
> Chun-Kuang.

OK, I'll kepp them here.

Regards,
Jason-JH.Lin
> 
> >  void mtk_dither_set_common(void __iomem *regs, struct
> > cmdq_client_reg *cmdq_reg,
> >                            unsigned int bpc, unsigned int cfg,
> >                            unsigned int dither_en, struct cmdq_pkt
> > *cmdq_pkt)
> > @@ -146,38 +130,19 @@ void mtk_dither_set_common(void __iomem
> > *regs, struct cmdq_client_reg *cmdq_reg,
> >         }
> >  }
> > 
> > -static void mtk_dither_set(struct device *dev, unsigned int bpc,
> > -                   unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
> > -{
> > -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > -
> > -       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc,
> > cfg,
> > -                             DISP_DITHERING, cmdq_pkt);
> > -}
> > -
> > -static void mtk_od_config(struct device *dev, unsigned int w,
> > -                         unsigned int h, unsigned int vrefresh,
> > -                         unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > -{
> > -       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > -
> > -       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv-
> > >regs, DISP_REG_OD_SIZE);
> > -       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg,
> > priv->regs, DISP_REG_OD_CFG);
> > -       mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
> > -}
> > 
> > -static void mtk_od_start(struct device *dev)
> > +static int mtk_ddp_clk_enable(struct device *dev)
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       writel(1, priv->regs + DISP_REG_OD_EN);
> > +       return clk_prepare_enable(priv->clk);
> >  }
> > 
> > -static void mtk_ufoe_start(struct device *dev)
> > +static void mtk_ddp_clk_disable(struct device *dev)
> >  {
> >         struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > 
> > -       writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
> > +       clk_disable_unprepare(priv->clk);
> >  }
> > 
> >  static void mtk_aal_config(struct device *dev, unsigned int w,
> > @@ -237,6 +202,40 @@ static void mtk_dither_stop(struct device
> > *dev)
> >         writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
> >  }
> > 
> > +static void mtk_dither_set(struct device *dev, unsigned int bpc,
> > +                          unsigned int cfg, struct cmdq_pkt
> > *cmdq_pkt)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc,
> > cfg,
> > +                             DISP_DITHERING, cmdq_pkt);
> > +}
> > +
> > +static void mtk_od_config(struct device *dev, unsigned int w,
> > +                         unsigned int h, unsigned int vrefresh,
> > +                         unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv-
> > >regs, DISP_REG_OD_SIZE);
> > +       mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg,
> > priv->regs, DISP_REG_OD_CFG);
> > +       mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
> > +}
> > +
> > +static void mtk_od_start(struct device *dev)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       writel(1, priv->regs + DISP_REG_OD_EN);
> > +}
> > +
> > +static void mtk_ufoe_start(struct device *dev)
> > +{
> > +       struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> > +
> > +       writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
> > +}
> > +
> >  static const struct mtk_ddp_comp_funcs ddp_aal = {
> >         .clk_enable = mtk_ddp_clk_enable,
> >         .clk_disable = mtk_ddp_clk_disable,
> > @@ -331,22 +330,22 @@ static const struct mtk_ddp_comp_funcs
> > ddp_ufoe = {
> >  };
> > 
> >  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX]
> > = {
> > +       [MTK_DISP_AAL] = "aal",
> > +       [MTK_DISP_BLS] = "bls",
> > +       [MTK_DISP_CCORR] = "ccorr",
> > +       [MTK_DISP_COLOR] = "color",
> > +       [MTK_DISP_DITHER] = "dither",
> > +       [MTK_DISP_GAMMA] = "gamma",
> > +       [MTK_DISP_MUTEX] = "mutex",
> > +       [MTK_DISP_OD] = "od",
> >         [MTK_DISP_OVL] = "ovl",
> >         [MTK_DISP_OVL_2L] = "ovl-2l",
> > +       [MTK_DISP_PWM] = "pwm",
> >         [MTK_DISP_RDMA] = "rdma",
> > -       [MTK_DISP_WDMA] = "wdma",
> > -       [MTK_DISP_COLOR] = "color",
> > -       [MTK_DISP_CCORR] = "ccorr",
> > -       [MTK_DISP_AAL] = "aal",
> > -       [MTK_DISP_GAMMA] = "gamma",
> > -       [MTK_DISP_DITHER] = "dither",
> >         [MTK_DISP_UFOE] = "ufoe",
> > -       [MTK_DSI] = "dsi",
> > +       [MTK_DISP_WDMA] = "wdma",
> >         [MTK_DPI] = "dpi",
> > -       [MTK_DISP_PWM] = "pwm",
> > -       [MTK_DISP_MUTEX] = "mutex",
> > -       [MTK_DISP_OD] = "od",
> > -       [MTK_DISP_BLS] = "bls",
> > +       [MTK_DSI] = "dsi",
> >  };
> > 
> >  struct mtk_ddp_comp_match {
> > @@ -500,12 +499,12 @@ int mtk_ddp_comp_init(struct device_node
> > *node, struct mtk_ddp_comp *comp,
> >             type == MTK_DISP_CCORR ||
> >             type == MTK_DISP_COLOR ||
> >             type == MTK_DISP_GAMMA ||
> > -           type == MTK_DPI ||
> > -           type == MTK_DSI ||
> >             type == MTK_DISP_OVL ||
> >             type == MTK_DISP_OVL_2L ||
> >             type == MTK_DISP_PWM ||
> > -           type == MTK_DISP_RDMA)
> > +           type == MTK_DISP_RDMA ||
> > +           type == MTK_DPI ||
> > +           type == MTK_DSI)
> >                 return 0;
> > 
> >         priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > index bb914d976cf5..d317b944df66 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> > @@ -18,22 +18,22 @@ struct mtk_plane_state;
> >  struct drm_crtc_state;
> > 
> >  enum mtk_ddp_comp_type {
> > -       MTK_DISP_OVL,
> > -       MTK_DISP_OVL_2L,
> > -       MTK_DISP_RDMA,
> > -       MTK_DISP_WDMA,
> > -       MTK_DISP_COLOR,
> > +       MTK_DISP_AAL,
> > +       MTK_DISP_BLS,
> >         MTK_DISP_CCORR,
> > +       MTK_DISP_COLOR,
> >         MTK_DISP_DITHER,
> > -       MTK_DISP_AAL,
> >         MTK_DISP_GAMMA,
> > -       MTK_DISP_UFOE,
> > -       MTK_DSI,
> > -       MTK_DPI,
> > -       MTK_DISP_PWM,
> >         MTK_DISP_MUTEX,
> >         MTK_DISP_OD,
> > -       MTK_DISP_BLS,
> > +       MTK_DISP_OVL,
> > +       MTK_DISP_OVL_2L,
> > +       MTK_DISP_PWM,
> > +       MTK_DISP_RDMA,
> > +       MTK_DISP_UFOE,
> > +       MTK_DISP_WDMA,
> > +       MTK_DPI,
> > +       MTK_DSI,
> >         MTK_DDP_COMP_TYPE_MAX,
> >  };
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index b46bdb8985da..a95dc1006b82 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -396,50 +396,20 @@ static const struct component_master_ops
> > mtk_drm_ops = {
> >  };
> > 
> >  static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
> > -       { .compatible = "mediatek,mt2701-disp-ovl",
> > -         .data = (void *)MTK_DISP_OVL },
> > -       { .compatible = "mediatek,mt8173-disp-ovl",
> > -         .data = (void *)MTK_DISP_OVL },
> > -       { .compatible = "mediatek,mt8183-disp-ovl",
> > -         .data = (void *)MTK_DISP_OVL },
> > -       { .compatible = "mediatek,mt8183-disp-ovl-2l",
> > -         .data = (void *)MTK_DISP_OVL_2L },
> > -       { .compatible = "mediatek,mt2701-disp-rdma",
> > -         .data = (void *)MTK_DISP_RDMA },
> > -       { .compatible = "mediatek,mt8173-disp-rdma",
> > -         .data = (void *)MTK_DISP_RDMA },
> > -       { .compatible = "mediatek,mt8183-disp-rdma",
> > -         .data = (void *)MTK_DISP_RDMA },
> > -       { .compatible = "mediatek,mt8173-disp-wdma",
> > -         .data = (void *)MTK_DISP_WDMA },
> > +       { .compatible = "mediatek,mt8173-disp-aal",
> > +         .data = (void *)MTK_DISP_AAL},
> >         { .compatible = "mediatek,mt8183-disp-ccorr",
> >           .data = (void *)MTK_DISP_CCORR },
> >         { .compatible = "mediatek,mt2701-disp-color",
> >           .data = (void *)MTK_DISP_COLOR },
> >         { .compatible = "mediatek,mt8173-disp-color",
> >           .data = (void *)MTK_DISP_COLOR },
> > -       { .compatible = "mediatek,mt8173-disp-aal",
> > -         .data = (void *)MTK_DISP_AAL},
> > +       { .compatible = "mediatek,mt8183-disp-dither",
> > +         .data = (void *)MTK_DISP_DITHER },
> >         { .compatible = "mediatek,mt8173-disp-gamma",
> >           .data = (void *)MTK_DISP_GAMMA, },
> >         { .compatible = "mediatek,mt8183-disp-gamma",
> >           .data = (void *)MTK_DISP_GAMMA, },
> > -       { .compatible = "mediatek,mt8183-disp-dither",
> > -         .data = (void *)MTK_DISP_DITHER },
> > -       { .compatible = "mediatek,mt8173-disp-ufoe",
> > -         .data = (void *)MTK_DISP_UFOE },
> > -       { .compatible = "mediatek,mt2701-dsi",
> > -         .data = (void *)MTK_DSI },
> > -       { .compatible = "mediatek,mt8173-dsi",
> > -         .data = (void *)MTK_DSI },
> > -       { .compatible = "mediatek,mt8183-dsi",
> > -         .data = (void *)MTK_DSI },
> > -       { .compatible = "mediatek,mt2701-dpi",
> > -         .data = (void *)MTK_DPI },
> > -       { .compatible = "mediatek,mt8173-dpi",
> > -         .data = (void *)MTK_DPI },
> > -       { .compatible = "mediatek,mt8183-dpi",
> > -         .data = (void *)MTK_DPI },
> >         { .compatible = "mediatek,mt2701-disp-mutex",
> >           .data = (void *)MTK_DISP_MUTEX },
> >         { .compatible = "mediatek,mt2712-disp-mutex",
> > @@ -448,12 +418,42 @@ static const struct of_device_id
> > mtk_ddp_comp_dt_ids[] = {
> >           .data = (void *)MTK_DISP_MUTEX },
> >         { .compatible = "mediatek,mt8183-disp-mutex",
> >           .data = (void *)MTK_DISP_MUTEX },
> > +       { .compatible = "mediatek,mt8173-disp-od",
> > +         .data = (void *)MTK_DISP_OD },
> > +       { .compatible = "mediatek,mt2701-disp-ovl",
> > +         .data = (void *)MTK_DISP_OVL },
> > +       { .compatible = "mediatek,mt8173-disp-ovl",
> > +         .data = (void *)MTK_DISP_OVL },
> > +       { .compatible = "mediatek,mt8183-disp-ovl",
> > +         .data = (void *)MTK_DISP_OVL },
> > +       { .compatible = "mediatek,mt8183-disp-ovl-2l",
> > +         .data = (void *)MTK_DISP_OVL_2L },
> >         { .compatible = "mediatek,mt2701-disp-pwm",
> >           .data = (void *)MTK_DISP_BLS },
> >         { .compatible = "mediatek,mt8173-disp-pwm",
> >           .data = (void *)MTK_DISP_PWM },
> > -       { .compatible = "mediatek,mt8173-disp-od",
> > -         .data = (void *)MTK_DISP_OD },
> > +       { .compatible = "mediatek,mt2701-disp-rdma",
> > +         .data = (void *)MTK_DISP_RDMA },
> > +       { .compatible = "mediatek,mt8173-disp-rdma",
> > +         .data = (void *)MTK_DISP_RDMA },
> > +       { .compatible = "mediatek,mt8183-disp-rdma",
> > +         .data = (void *)MTK_DISP_RDMA },
> > +       { .compatible = "mediatek,mt8173-disp-ufoe",
> > +         .data = (void *)MTK_DISP_UFOE },
> > +       { .compatible = "mediatek,mt8173-disp-wdma",
> > +         .data = (void *)MTK_DISP_WDMA },
> > +       { .compatible = "mediatek,mt2701-dpi",
> > +         .data = (void *)MTK_DPI },
> > +       { .compatible = "mediatek,mt8173-dpi",
> > +         .data = (void *)MTK_DPI },
> > +       { .compatible = "mediatek,mt8183-dpi",
> > +         .data = (void *)MTK_DPI },
> > +       { .compatible = "mediatek,mt2701-dsi",
> > +         .data = (void *)MTK_DSI },
> > +       { .compatible = "mediatek,mt8173-dsi",
> > +         .data = (void *)MTK_DSI },
> > +       { .compatible = "mediatek,mt8183-dsi",
> > +         .data = (void *)MTK_DSI },
> >         { }
> >  };
> > 
> > @@ -542,8 +542,8 @@ static int mtk_drm_probe(struct platform_device
> > *pdev)
> >                     comp_type == MTK_DISP_OVL ||
> >                     comp_type == MTK_DISP_OVL_2L ||
> >                     comp_type == MTK_DISP_RDMA ||
> > -                   comp_type == MTK_DSI ||
> > -                   comp_type == MTK_DPI) {
> > +                   comp_type == MTK_DPI ||
> > +                   comp_type == MTK_DSI) {
> >                         dev_info(dev, "Adding component match for
> > %pOF\n",
> >                                  node);
> >                         drm_of_component_match_add(dev, &match,
> > compare_of,
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From p.yadav at ti.com  Tue Aug 24 10:58:42 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 24 Aug 2021 23:28:42 +0530
Subject: [PATCH v2 35/35] docs: mtd: spi-nor: Add details about how to
 propose a new flash addition
In-Reply-To: <4304e19f3399a0a6e856119d01ccabe0@walle.cc>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-36-tudor.ambarus@microchip.com>
 <4304e19f3399a0a6e856119d01ccabe0@walle.cc>
Message-ID: <20210824175840.276vh2qaltjmsdte@ti.com>

On 27/07/21 09:22AM, Michael Walle wrote:
> Am 2021-07-27 06:52, schrieb Tudor Ambarus:
> > Add some guideliness on how to propose a new flash addition.
> > 
> > Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> > ---
> >  Documentation/driver-api/mtd/spi-nor.rst | 65 ++++++++++++++++++++++++
> >  1 file changed, 65 insertions(+)
> > 
> > diff --git a/Documentation/driver-api/mtd/spi-nor.rst
> > b/Documentation/driver-api/mtd/spi-nor.rst
> > index 4a3adca417fd..ffb8d97a2766 100644
> > --- a/Documentation/driver-api/mtd/spi-nor.rst
> > +++ b/Documentation/driver-api/mtd/spi-nor.rst
> [..]
> > +Every new flash addition that define the SFDP tables, should hexdump
> > its SFDP
> > +tables in the patch's comment section below the --- line, so that we
> > can
> > +reference it in case of ID collisions.
> 
> Nice, but could you add some guidelines how to do it? That is the exact
> commands, maybe with a notice one should use these whenever possible. I
> want to prevent having all sorts of variations of the output and I want
> to be able to reverse the operation and verify it.
> 
> # xxd -p /path/to/sfdp
> # md5sum /path/to/sfdp
> # cat /path/to/jedec_id
> # cat /path/to/partname
> # cat /path/to/manufacturer

It would be nice if we could have checkpatch.pl check for these. But I 
don't know how difficult that would be to add.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From jason-jh.lin at mediatek.com  Tue Aug 24 10:59:27 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 25 Aug 2021 01:59:27 +0800
Subject: [PATCH v8 03/13] dt-bindings: mediatek: add mediatek,dsc.yaml
 for mt8195 SoC binding
In-Reply-To: <CAAOTY_9BUZ3x01FXY=UKmcrqGxmP7bfpqyz7zCJXK=+2xUhrYA@mail.gmail.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-4-jason-jh.lin@mediatek.com>
 <CAAOTY_9BUZ3x01FXY=UKmcrqGxmP7bfpqyz7zCJXK=+2xUhrYA@mail.gmail.com>
Message-ID: <27c7b466b6197c9bdb0ced778b77981881a08162.camel@mediatek.com>

Hi Chun-Kuang,

Thanks for the review.

On Sun, 2021-08-22 at 07:14 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
> > 
> > 1. Add mediatek,dsc.yaml to describe DSC module in details.
> > 2. Add mt8195 SoC binding to mediatek,dsc.yaml.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> >  .../display/mediatek/mediatek,dsc.yaml        | 69
> > +++++++++++++++++++
> >  1 file changed, 69 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yam
> > l
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.y
> > aml
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.y
> > aml
> > new file mode 100644
> > index 000000000000..f94a95c6a1c5
> > --- /dev/null
> > +++
> > b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.y
> > aml
> > @@ -0,0 +1,69 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: 
> > https://urldefense.com/v3/__http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml*__;Iw!!CTRNKA9wMg0ARbw!2qwvJnFTgJzfk1n0OVXqGlPjYco2bBUZtWFzb4n8gzHXyFFJZ7MT4QWO4RDznHmSWyiO$
> >  
> > +$schema: 
> > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!2qwvJnFTgJzfk1n0OVXqGlPjYco2bBUZtWFzb4n8gzHXyFFJZ7MT4QWO4RDznNC1w7FX$
> >  
> > +
> > +title: mediatek display DSC controller
> > +
> > +maintainers:
> > +  - CK Hu <ck.hu at mediatek.com>
> 
> According to [1], the maintainer should be
> 
> Chun-Kuang Hu <chunkuang.hu at kernel.org>, Philipp Zabel <
> p.zabel at pengutronix.de>
> 
> [1] 
> https://urldefense.com/v3/__https://www.kernel.org/doc/html/latest/process/maintainers.html__;!!CTRNKA9wMg0ARbw!2qwvJnFTgJzfk1n0OVXqGlPjYco2bBUZtWFzb4n8gzHXyFFJZ7MT4QWO4RDznMdx7tAe$
>  
OK, I'll fix it and also the [PATCH v8 02/13] in this series.

Regards,
Jason-JH.Lin
> 
> > +
> > +description: |
> > +  The DSC standard is a specification of the algorithms used for
> > +  compressing and decompressing image display streams, including
> > +  the specification of the syntax and semantics of the compressed
> > +  video bit stream. DSC is designed for real-time systems with
> > +  real-time compression, transmission, decompression and Display.
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - items:
> > +          - const: mediatek,mt8195-disp-dsc
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: DSC Wrapper Clock
> > +
> > +  power-domains:
> > +    description: A phandle and PM domain specifier as defined by
> > bindings of
> > +      the power controller specified by phandle. See
> > +      Documentation/devicetree/bindings/power/power-domain.yaml
> > for details.
> > +
> > +  mediatek,gce-client-reg:
> > +      description:
> > +        The register of display function block to be set by gce.
> > There are 4 arguments,
> > +        such as gce node, subsys id, offset and register size. The
> > subsys id that is
> > +        mapping to the register of display function blocks is
> > defined in the gce header
> > +        include/include/dt-bindings/gce/<chip>-gce.h of each
> > chips.
> > +      $ref: /schemas/types.yaml#/definitions/phandle-array
> > +      maxItems: 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - power-domains
> > +  - clocks
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +
> > +    dsc0: disp_dsc_wrap at 1c009000 {
> > +        compatible = "mediatek,mt8195-disp-dsc";
> > +        reg = <0 0x1c009000 0 0x1000>;
> > +        interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> > +        clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
> > +        mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000
> > 0x1000>;
> > +    };
> > +
> > --
> > 2.18.0
> > 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From robh at kernel.org  Tue Aug 24 11:02:54 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 13:02:54 -0500
Subject: [PATCH v7 3/5] dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
In-Reply-To: <20210824100027.25989-4-moudy.ho@mediatek.com>
References: <20210824100027.25989-1-moudy.ho@mediatek.com>
 <20210824100027.25989-4-moudy.ho@mediatek.com>
Message-ID: <YSU0TrfFCsaI1TqV@robh.at.kernel.org>

On Tue, Aug 24, 2021 at 06:00:25PM +0800, Moudy Ho wrote:
> This patch adds DT binding document for Media Data Path 3 (MDP3)
> a unit in multimedia system used for scaling and color format convert.
> 
> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> ---
>  .../bindings/media/mediatek,mdp3-ccorr.yaml   |  57 +++++
>  .../bindings/media/mediatek,mdp3-rdma.yaml    | 207 ++++++++++++++++++
>  .../bindings/media/mediatek,mdp3-rsz.yaml     |  65 ++++++
>  .../bindings/media/mediatek,mdp3-wdma.yaml    |  71 ++++++
>  .../bindings/media/mediatek,mdp3-wrot.yaml    |  71 ++++++
>  5 files changed, 471 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
> new file mode 100644
> index 000000000000..59fd68b46022
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
> @@ -0,0 +1,57 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/mediatek,mdp3-ccorr.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Media Data Path 3 CCORR Device Tree Bindings
> +
> +maintainers:
> +  - Daoyuan Huang <daoyuan.huang at mediatek.com>
> +  - Moudy Ho <moudy.ho at mediatek.com>
> +
> +description: |
> +  One of Media Data Path 3 (MDP3) components used to do color correction with 3X3 matrix.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +        - mediatek,mt8183-mdp3-ccorr
> +
> +  mediatek,mdp3-id:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    maxItems: 1
> +    description: |
> +      HW index to distinguish same functionality modules.

If we wanted h/w indexes in DT, we'd have a standard property. Why do 
you need this?

> +
> +  reg:
> +    description: |
> +      Physical base address and length of the function block
> +      register space, the number aligns with the component
> +      and its own subcomponent.

Drop and add 'maxItems: 1'

> +
> +  mediatek,gce-client-reg:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description: |
> +      sub-system id corresponding to the global command engine (GCE)

You mean 'phandle to GCE and sub-system id'?

> +      register address.
> +      $ref: /schemas/mailbox/mtk-gce.txt

Kind of looks like jsonschema but in the description and to a .txt 
file...

> +
> +  clocks:
> +    minItems: 1
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt8183-clk.h>
> +    #include <dt-bindings/gce/mt8183-gce.h>
> +
> +    mdp3_ccorr: mdp3_ccorr at 1401c000 {
> +      compatible = "mediatek,mt8183-mdp3-ccorr";
> +      mediatek,mdp3-id = <0>;
> +      reg = <0x1401c000 0x1000>;
> +      mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
> +      clocks = <&mmsys CLK_MM_MDP_CCORR>;
> +    };
> diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> new file mode 100644
> index 000000000000..b355d7fe791e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> @@ -0,0 +1,207 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Media Data Path 3 Device Tree Bindings
> +
> +maintainers:
> +  - Daoyuan Huang <daoyuan.huang at mediatek.com>
> +  - Moudy Ho <moudy.ho at mediatek.com>
> +
> +description: |
> +  One of Media Data Path 3 (MDP3) components used to do read DMA.
> +  RDMA0 is also used to be a controller node containing MMSYS,
> +  MUTEX, GCE and SCP settings.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +        - enum:

Should be indented 2 more spaces. Install yamllint and check with 'make 
dt_binding_check'.

> +          # controller node
> +          - mediatek,mt8183-mdp3

And then 2 more here.

> +        - enum:
> +          - mediatek,mt8183-mdp3-rdma
> +
> +      - items:
> +        - enum:
> +          # read DMA
> +          - mediatek,mt8183-mdp3-rdma
> +
> +  mediatek,scp:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1
> +    description: |
> +      The node of system control processor (SCP), using
> +      the remoteproc & rpmsg framework.
> +      $ref: /schemas/remoteproc/mtk,scp.yaml
> +
> +  mediatek,mdp3-id:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    maxItems: 1
> +    description: |
> +      In MDP3, it can allocate multiple identical modules for
> +      different data path selection or multi-pipeline execution.
> +      This node is used to indicate the ID of each module.
> +
> +  mdp3-comps:
> +    $ref: /schemas/types.yaml#/definitions/string-array
> +    items:
> +        - enum:

And this is 2 too many spaces...

> +          # MDP direct-link input path selection, create a
> +          # component for path connectedness of HW pipe control
> +          - mediatek,mt8183-mdp3-dl1
> +        - enum:
> +          - mediatek,mt8183-mdp3-dl2
> +        - enum:
> +          # MDP direct-link output path selection, create a
> +          # component for path connectedness of HW pipe control
> +          - mediatek,mt8183-mdp3-path1
> +        - enum:
> +          - mediatek,mt8183-mdp3-path2
> +        - enum:
> +          # Input DMA of ISP PASS2 (DIP) module for raw image input
> +          - mediatek,mt8183-mdp3-imgi
> +        - enum:
> +          # Output DMA of ISP PASS2 (DIP) module for YUV image output
> +          - mediatek,mt8183-mdp3-exto
> +
> +  mdp3-comp-ids:
> +    maxItems: 1
> +    $ref: /schemas/types.yaml#/definitions/uint32-array

If only a single item, then it's a 'uint32' not an array.

> +    description: |
> +      Pipeline ID of MDP direct-link or DIP.
> +
> +  reg:
> +    description: |
> +      Physical base address and length of the function block
> +      register space, the number aligns with the component
> +      and its own subcomponent.
> +
> +  mediatek,gce-client-reg:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description: |
> +      sub-system id corresponding to the global command engine (GCE)
> +      register address.
> +      $ref: /schemas/mailbox/mtk-gce.txt
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  clocks:
> +    minItems: 1
> +    maxItems: 6

Need to define what they are.

> +
> +  iommus:
> +    $ref: /schemas/types.yaml#/definitions/phandle

iommus already has a type definition.

> +    description: |
> +      Should point to the respective IOMMU block with master
> +      port as argument.
> +      $ref: /schemas/iommu/mediatek,iommu.yaml

No. Drop (the whole description because you don't need generic 
descriptions for common properties).

What's needed is how many entries (maxItems: 1).

> +
> +  mediatek,mmsys:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1
> +    description: |
> +      The node of mux(multiplexer) controller for HW connections.
> +
> +  mediatek,mm-mutex:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1
> +    description: |
> +      The node of sof(start of frame) signal controller.
> +
> +  mediatek,mailbox-gce:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: |
> +      The node of global command engine (GCE), used to read/write
> +      registers with critical time limitation.
> +      $ref: /schemas/mailbox/mtk-gce.txt
> +
> +  mboxes:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description: |
> +      $ref: /schemas/mailbox/mailbox.txt
> +
> +  gce-subsys:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description: |
> +      sub-system id corresponding to the global command engine (GCE)
> +      register address.
> +      $ref: /schemas/mailbox/mtk-gce.txt
> +
> +if:
> +  properties:
> +    compatible:
> +      items:
> +        - enum:
> +          - mediatek,mt8183-mdp3
> +        - enum:
> +          - mediatek,mt8183-mdp3-rdma

Normally, you want to use 'contains' for if/then schemas:

compatible:
  contains:
    const: mediatek,mt8183-mdp3

> +
> +then:
> +  required:
> +    - mediatek,scp
> +    - mediatek,mmsys
> +    - mediatek,mm-mutex
> +    - mediatek,mailbox-gce
> +    - mboxes
> +    - gce-subsys
> +
> +required:
> +  - compatible
> +  - mediatek,mdp3-id
> +  - reg
> +  - clocks
> +  - mediatek,gce-client-reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt8183-clk.h>
> +    #include <dt-bindings/gce/mt8183-gce.h>
> +    #include <dt-bindings/power/mt8183-power.h>
> +    #include <dt-bindings/memory/mt8183-larb-port.h>
> +
> +    mdp3_rdma0: mdp3_rdma0 at 14001000 {
> +      compatible = "mediatek,mt8183-mdp3",
> +                   "mediatek,mt8183-mdp3-rdma";
> +      mediatek,scp = <&scp>;
> +      mediatek,mdp3-id = <0>;
> +      mdp3-comps = "mediatek,mt8183-mdp3-dl1", "mediatek,mt8183-mdp3-dl2",
> +                   "mediatek,mt8183-mdp3-path1", "mediatek,mt8183-mdp3-path2",
> +                   "mediatek,mt8183-mdp3-imgi", "mediatek,mt8183-mdp3-exto";
> +      mdp3-comp-ids = <0 1 0 1 0 1>;
> +      reg = <0x14001000 0x1000>,
> +            <0x14000000 0x1000>,
> +            <0x14005000 0x1000>,
> +            <0x14006000 0x1000>,
> +            <0x15020000 0x1000>;
> +      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
> +                                <&gce SUBSYS_1400XXXX 0 0x1000>,
> +                                <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
> +                                <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
> +                                <&gce SUBSYS_1502XXXX 0 0x1000>;
> +      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +      clocks = <&mmsys CLK_MM_MDP_RDMA0>,
> +               <&mmsys CLK_MM_MDP_RSZ1>,
> +               <&mmsys CLK_MM_MDP_DL_TXCK>,
> +               <&mmsys CLK_MM_MDP_DL_RX>,
> +               <&mmsys CLK_MM_IPU_DL_TXCK>,
> +               <&mmsys CLK_MM_IPU_DL_RX>;
> +      iommus = <&iommu>;
> +      mediatek,mmsys = <&mmsys>;
> +      mediatek,mm-mutex = <&mutex>;
> +      mediatek,mailbox-gce = <&gce>;
> +      mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
> +               <&gce 21 CMDQ_THR_PRIO_LOWEST 0>,
> +               <&gce 22 CMDQ_THR_PRIO_LOWEST 0>,
> +               <&gce 23 CMDQ_THR_PRIO_LOWEST 0>;
> +      gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
> +                   <&gce 0x14010000 SUBSYS_1401XXXX>,
> +                   <&gce 0x14020000 SUBSYS_1402XXXX>,
> +                   <&gce 0x15020000 SUBSYS_1502XXXX>;
> +    };
> \ No newline at end of file

Fix this.

Similar comments on the rest.

Rob


From robh at kernel.org  Tue Aug 24 11:03:18 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 13:03:18 -0500
Subject: [PATCH v1 4/4] ASoC: dt-bindings: rockchip: Add compatible for
 rk3568 spdif
In-Reply-To: <1629800162-12824-5-git-send-email-sugar.zhang@rock-chips.com>
References: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
 <1629800162-12824-5-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <YSU0Zk5LpSX9xZG1@robh.at.kernel.org>

On Tue, 24 Aug 2021 18:16:02 +0800, Sugar Zhang wrote:
> This patch adds compatible string for rk3568 spdif.
> 
> Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
> ---
> 
>  Documentation/devicetree/bindings/sound/rockchip-spdif.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

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


From catalin.marinas at arm.com  Tue Aug 24 11:05:56 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 24 Aug 2021 19:05:56 +0100
Subject: [PATCH v16 00/15] arm64: MMU enabled kexec relocation
In-Reply-To: <20210802215408.804942-1-pasha.tatashin@soleen.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
Message-ID: <20210824180555.GD623@arm.com>

Hi Pavel,

This series is still missing reviews from those who understand kexec
better than me.

On Mon, Aug 02, 2021 at 05:53:53PM -0400, Pavel Tatashin wrote:
> Enable MMU during kexec relocation in order to improve reboot performance.
> 
> If kexec functionality is used for a fast system update, with a minimal
> downtime, the relocation of kernel + initramfs takes a significant portion
> of reboot.
> 
> The reason for slow relocation is because it is done without MMU, and thus
> not benefiting from D-Cache.

The performance improvements are indeed significant on some platforms
(going from 7s to ~40ms), so I think the merging the series is worth it.
Some general questions so I better understand the impact:

- Is the kdump path affected in any way? IIUC that doesn't need any
  relocation but we should also make sure we don't create the additional
  page table unnecessarily (should keep as much memory intact as
  possible). Maybe that's already handled.

- What happens if trans_pgd_create_copy() fails to allocate memory. Does
  it fall back to an MMU-off relocation?

And I presume this series does not introduce any changes to the kexec
tools ABI.

Thanks.

-- 
Catalin


From robin.murphy at arm.com  Tue Aug 24 11:06:01 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 24 Aug 2021 19:06:01 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210824173741.GC623@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com>
Message-ID: <77eb6abd-4369-eb8f-e323-cf4e6f2ffce5@arm.com>

On 2021-08-24 18:37, Catalin Marinas wrote:
> Hi Alex,
> 
> Thanks for the report.
> 
> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>> it seems there is a regression in arm64 memory mapping in 5.14, since it
>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>
>> [????????? 8.921909] ------------[ cut here ]------------
>> [????????? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>> [????????? 8.921973] Modules linked in: spi_rockchip(+) fuse
>> [????????? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>> [????????? 8.922004] Hardware name: Pine64 Rock64 (DT)
>> [????????? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>> [????????? 8.922018] pc : dma_map_resource+0x68/0xc0
>> [????????? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
>> [????????? 8.922040] sp : ffff800012102ae0
>> [????????? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>> [????????? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>> [????????? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>> [????????? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>> [????????? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>> [????????? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>> [????????? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>> [????????? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>> [????????? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>> [????????? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>> [????????? 8.922158] Call trace:
>> [????????? 8.922163]??? dma_map_resource+0x68/0xc0
>> [????????? 8.922173]??? pl330_prep_slave_sg+0x58/0x220
>> [????????? 8.922181]??? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>> [????????? 8.922208]??? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
> [...]
>> Note: This does not relate to the spi driver - when disabling this device in
>> the device tree it fails for any other (i2s, for instance) which uses dma.
>> Commenting out the failing check at [1], however, helps and the mapping
>> works again.
> 
> Do you know which address dma_map_resource() is trying to map (maybe
> add some printk())? It's not supposed to map RAM, hence the warning.
> Random guess, the address is 0xff190800 (based on the x1 above but the
> regs might as well be mangled).

Yup, that fits the signature of dma_map_resource(), and would indeed be 
right in the middle of the SPI peripheral on RK3328.

FWIW the comment about RAM there is a little inaccurate, but the point 
remains that anything which *is* backed by a page should probably be 
handled by dma_map_page() if at all.

>> I tried to follow the recent changes for arm64 mm which could relate to the
>> check failing at [1] and reverting
>> ??? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>> helps and makes it work again, but I'm 100% uncertain if that commit is
>> really the culprit.
>>
>> Note, that the firmware (legacy u-boot) injects memory configuration in the
>> device tree as follows:
>>
>> /memreserve/????????? 0x00000000fcefc000 0x000000000000d000;
>> / {
>> ..
>> ????????? compatible = "pine64,rock64\0rockchip,rk3328";
>> ..
>> ????????? memory {
>> ????????? ????????? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
>> ????????? ????????? device_type = "memory";
>> ????????? };
>>
>> ..
>> }
> 
> Either pfn_valid() gets confused in 5.14 or something is wrong with the
> DT. I have a suspicion it's the former since reverting the above commit
> makes it disappear.
> 
>> So: there is a "hole" in the mappable memory and reading the commit message
>> of
>> ??? commit a7d9f306ba70 ("arm64: drop pfn_valid_within() and simplify
>> pfn_valid()")
>> suggests, there was a change for that case recently.
> 
> I think the change from the arm64 pfn_valid() to the generic one is
> avoiding the call to memblock_is_memory(). I wonder whether pfn_valid()
> returns true just because we have a struct page available but the memory
> may have been reserved.

Either way I think something's gone pretty badly wrong if Linux ends up 
thinking that an MMIO region beyond the bounds of any possible RAM 
should be page-backed :/

Robin.

> 
> Cc'ing Mike R.
> 
>> I also noticed there is a diff in the kernel log regarding memory init up
>> until 5.13.12 it says
>>
>> [????????? 0.000000] Zone ranges:
>> [????????? 0.000000]?????? DMA??????????????? [mem 0x0000000000200000-0x00000000feffffff]
>> [????????? 0.000000]?????? DMA32????????? empty
>> [????????? 0.000000]?????? Normal?????? empty
>> [????????? 0.000000] Movable zone start for each node
>> [????????? 0.000000] Early memory node ranges
>> [????????? 0.000000]?????? node?????? 0: [mem 0x0000000000200000-0x00000000feffffff]
>> [????????? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
>> [????????? 0.000000] On node 0 totalpages: 1043968
>> [????????? 0.000000]?????? DMA zone: 16312 pages used for memmap
>> [????????? 0.000000]?????? DMA zone: 0 pages reserved
>> [????????? 0.000000]?????? DMA zone: 1043968 pages, LIFO batch:63
>>
>> In contrary in 5.14-rc7 it says:
>>
>> [????????? 0.000000] Zone ranges:
>> [????????? 0.000000]?????? DMA??????????????? [mem 0x0000000000200000-0x00000000feffffff]
>> [????????? 0.000000]?????? DMA32????????? empty
>> [????????? 0.000000]?????? Normal?????? empty
>> [????????? 0.000000] Movable zone start for each node
>> [????????? 0.000000] Early memory node ranges
>> [????????? 0.000000]?????? node?????? 0: [mem 0x0000000000200000-0x00000000feffffff]
>> [????????? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
>> [????????? 0.000000] On node 0, zone DMA: 512 pages in unavailable ranges
>> [????????? 0.000000] On node 0, zone DMA: 4096 pages in unavailable ranges
>>
>> (note the "unavailable ranges")
>> I'm uncertain again here, if that diff is expected behavior because of those
>> recent mm changes for arm64.
>>
>> After reverting
>> ??? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>> the log changes to
>>
>> [????????? 0.000000] Zone ranges:
>> [????????? 0.000000]?????? DMA??????????????? [mem 0x0000000000200000-0x00000000feffffff]
>> [????????? 0.000000]?????? DMA32????????? empty
>> [????????? 0.000000]?????? Normal?????? empty
>> [????????? 0.000000] Movable zone start for each node
>> [????????? 0.000000] Early memory node ranges
>> [????????? 0.000000]?????? node?????? 0: [mem 0x0000000000200000-0x00000000feffffff]
>> [????????? 0.000000] Initmem setup node 0 [mem
>> 0x0000000000200000-0x00000000feffffff]
>>
>> (no DMA zones here)
>>
>> As you might have noticed I have _zero_ clue about memory mapping and dma
>> subsystem - so let me know if there is any more information needed for that
>> and thanks for your help.
> 
> Adding Robin as well, he has a better clue than us on DMA ;).
> 
>> Alex
>>
>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/dma/mapping.c?id=e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93#n235
> 


From rppt at kernel.org  Tue Aug 24 11:28:05 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 24 Aug 2021 21:28:05 +0300
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210824173741.GC623@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com>
Message-ID: <YSU6NVZ3j0XCurWC@kernel.org>

On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
> Hi Alex,
> 
> Thanks for the report.
> 
> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
> > it seems there is a regression in arm64 memory mapping in 5.14, since it
> > fails on Rockchip RK3328 when the pl330 dmac tries to map with:
> > 
> > [??? 8.921909] ------------[ cut here ]------------
> > [??? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
> > [??? 8.921973] Modules linked in: spi_rockchip(+) fuse
> > [??? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
> > [??? 8.922004] Hardware name: Pine64 Rock64 (DT)
> > [??? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
> > [??? 8.922018] pc : dma_map_resource+0x68/0xc0
> > [??? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
> > [??? 8.922040] sp : ffff800012102ae0
> > [??? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
> > [??? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
> > [??? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
> > [??? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
> > [??? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> > [??? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
> > [??? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
> > [??? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
> > [??? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
> > [??? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
> > [??? 8.922158] Call trace:
> > [??? 8.922163]? dma_map_resource+0x68/0xc0
> > [??? 8.922173]? pl330_prep_slave_sg+0x58/0x220
> > [??? 8.922181]? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
> > [??? 8.922208]? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
> [...]
> > Note: This does not relate to the spi driver - when disabling this device in
> > the device tree it fails for any other (i2s, for instance) which uses dma.
> > Commenting out the failing check at [1], however, helps and the mapping
> > works again.

> Do you know which address dma_map_resource() is trying to map (maybe
> add some printk())? It's not supposed to map RAM, hence the warning.
> Random guess, the address is 0xff190800 (based on the x1 above but the
> regs might as well be mangled).

0xff190800 will cause this warning for sure. It has a memory map, but it is
not RAM so old version of pfn_valid() would return 0 and the new one
returns 1.
 
> > I tried to follow the recent changes for arm64 mm which could relate to the
> > check failing at [1] and reverting
> > ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
> > helps and makes it work again, but I'm 100% uncertain if that commit is
> > really the culprit.
> > 
> > Note, that the firmware (legacy u-boot) injects memory configuration in the
> > device tree as follows:
> > 
> > /memreserve/??? 0x00000000fcefc000 0x000000000000d000;
> > / {
> > ..
> > ??? compatible = "pine64,rock64\0rockchip,rk3328";
> > ..
> > ??? memory {
> > ??? ??? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
> > ??? ??? device_type = "memory";
> > ??? };
> > 
> > ..
> > }
> 
> Either pfn_valid() gets confused in 5.14 or something is wrong with the
> DT. I have a suspicion it's the former since reverting the above commit
> makes it disappear.

I think pfn_valid() actually behaves as expected but the caller is wrong
because pfn_valid != RAM (this applies btw to !arm64 as well).

	/* Don't allow RAM to be mapped */
	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
		return DMA_MAPPING_ERROR;

Alex, can you please try this patch:

diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 2b06a809d0b9..4715e9641a29 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -232,7 +232,7 @@ dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr,
 		return DMA_MAPPING_ERROR;
 
 	/* Don't allow RAM to be mapped */
-	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
+	if (WARN_ON_ONCE(!memblock_is_memory(phys_addr)))
 		return DMA_MAPPING_ERROR;
 
 	if (dma_map_direct(dev, ops))
 
> > So: there is a "hole" in the mappable memory and reading the commit message
> > of
> > ? commit a7d9f306ba70 ("arm64: drop pfn_valid_within() and simplify
> > pfn_valid()")
> > suggests, there was a change for that case recently.
> 
> I think the change from the arm64 pfn_valid() to the generic one is
> avoiding the call to memblock_is_memory(). I wonder whether pfn_valid()
> returns true just because we have a struct page available but the memory
> may have been reserved.
> 
> Cc'ing Mike R.
> 
> > I also noticed there is a diff in the kernel log regarding memory init up
> > until 5.13.12 it says
> > 
> > [??? 0.000000] Zone ranges:
> > [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
> > [??? 0.000000]?? DMA32??? empty
> > [??? 0.000000]?? Normal?? empty
> > [??? 0.000000] Movable zone start for each node
> > [??? 0.000000] Early memory node ranges
> > [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
> > [??? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
> > [??? 0.000000] On node 0 totalpages: 1043968
> > [??? 0.000000]?? DMA zone: 16312 pages used for memmap
> > [??? 0.000000]?? DMA zone: 0 pages reserved
> > [??? 0.000000]?? DMA zone: 1043968 pages, LIFO batch:63
> > 
> > In contrary in 5.14-rc7 it says:
> > 
> > [??? 0.000000] Zone ranges:
> > [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
> > [??? 0.000000]?? DMA32??? empty
> > [??? 0.000000]?? Normal?? empty
> > [??? 0.000000] Movable zone start for each node
> > [??? 0.000000] Early memory node ranges
> > [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
> > [??? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
> > [??? 0.000000] On node 0, zone DMA: 512 pages in unavailable ranges
> > [??? 0.000000] On node 0, zone DMA: 4096 pages in unavailable ranges
> > 
> > (note the "unavailable ranges")
> > I'm uncertain again here, if that diff is expected behavior because of those
> > recent mm changes for arm64.
> > 
> > After reverting
> > ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
> > the log changes to
> > 
> > [??? 0.000000] Zone ranges:
> > [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
> > [??? 0.000000]?? DMA32??? empty
> > [??? 0.000000]?? Normal?? empty
> > [??? 0.000000] Movable zone start for each node
> > [??? 0.000000] Early memory node ranges
> > [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
> > [??? 0.000000] Initmem setup node 0 [mem
> > 0x0000000000200000-0x00000000feffffff]
> > 
> > (no DMA zones here)
> > 
> > As you might have noticed I have _zero_ clue about memory mapping and dma
> > subsystem - so let me know if there is any more information needed for that
> > and thanks for your help.
> 
> Adding Robin as well, he has a better clue than us on DMA ;).
> 
> > Alex
> > 
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/dma/mapping.c?id=e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93#n235
> 
> -- 
> Catalin

-- 
Sincerely yours,
Mike.


From robin.murphy at arm.com  Tue Aug 24 11:46:42 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 24 Aug 2021 19:46:42 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <YSU6NVZ3j0XCurWC@kernel.org>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
Message-ID: <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>

On 2021-08-24 19:28, Mike Rapoport wrote:
> On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
>> Hi Alex,
>>
>> Thanks for the report.
>>
>> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>>> it seems there is a regression in arm64 memory mapping in 5.14, since it
>>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>>
>>> [????????? 8.921909] ------------[ cut here ]------------
>>> [????????? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>>> [????????? 8.921973] Modules linked in: spi_rockchip(+) fuse
>>> [????????? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>>> [????????? 8.922004] Hardware name: Pine64 Rock64 (DT)
>>> [????????? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>>> [????????? 8.922018] pc : dma_map_resource+0x68/0xc0
>>> [????????? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
>>> [????????? 8.922040] sp : ffff800012102ae0
>>> [????????? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>>> [????????? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>>> [????????? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>>> [????????? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>>> [????????? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>>> [????????? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>>> [????????? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>>> [????????? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>>> [????????? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>>> [????????? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>>> [????????? 8.922158] Call trace:
>>> [????????? 8.922163]??? dma_map_resource+0x68/0xc0
>>> [????????? 8.922173]??? pl330_prep_slave_sg+0x58/0x220
>>> [????????? 8.922181]??? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>>> [????????? 8.922208]??? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
>> [...]
>>> Note: This does not relate to the spi driver - when disabling this device in
>>> the device tree it fails for any other (i2s, for instance) which uses dma.
>>> Commenting out the failing check at [1], however, helps and the mapping
>>> works again.
> 
>> Do you know which address dma_map_resource() is trying to map (maybe
>> add some printk())? It's not supposed to map RAM, hence the warning.
>> Random guess, the address is 0xff190800 (based on the x1 above but the
>> regs might as well be mangled).
> 
> 0xff190800 will cause this warning for sure. It has a memory map, but it is
> not RAM so old version of pfn_valid() would return 0 and the new one
> returns 1.

How does that happen, though? It's not a memory address, and it's not 
even within the bounds of anywhere there should or could be memory. This 
SoC has a simple memory map - everything from 0 to 0xfeffffff goes to 
the DRAM controller (which may not all be populated, and may have pieces 
carved out by secure firmware), while 0xff000000-0xffffffff is MMIO. Why 
do we have pages (or at least the assumption of pages) for somewhere 
which by all rights should not have them?

>>> I tried to follow the recent changes for arm64 mm which could relate to the
>>> check failing at [1] and reverting
>>> ??? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>>> helps and makes it work again, but I'm 100% uncertain if that commit is
>>> really the culprit.
>>>
>>> Note, that the firmware (legacy u-boot) injects memory configuration in the
>>> device tree as follows:
>>>
>>> /memreserve/????????? 0x00000000fcefc000 0x000000000000d000;
>>> / {
>>> ..
>>> ????????? compatible = "pine64,rock64\0rockchip,rk3328";
>>> ..
>>> ????????? memory {
>>> ????????? ????????? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
>>> ????????? ????????? device_type = "memory";
>>> ????????? };
>>>
>>> ..
>>> }
>>
>> Either pfn_valid() gets confused in 5.14 or something is wrong with the
>> DT. I have a suspicion it's the former since reverting the above commit
>> makes it disappear.
> 
> I think pfn_valid() actually behaves as expected but the caller is wrong
> because pfn_valid != RAM (this applies btw to !arm64 as well).
> 
> 	/* Don't allow RAM to be mapped */
> 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> 		return DMA_MAPPING_ERROR;
> 
> Alex, can you please try this patch:

That will certainly paper over the issue, but it's avoiding the question 
of what went wrong with the memory map in the first place. The comment 
is indeed a bit inaccurate, but ultimately dma_map_resource() exists for 
addresses that would be wrong to pass to dma_map_page(), so I believe 
pfn_valid() is still the correct check.

Robin.

> diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
> index 2b06a809d0b9..4715e9641a29 100644
> --- a/kernel/dma/mapping.c
> +++ b/kernel/dma/mapping.c
> @@ -232,7 +232,7 @@ dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr,
>   		return DMA_MAPPING_ERROR;
>   
>   	/* Don't allow RAM to be mapped */
> -	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> +	if (WARN_ON_ONCE(!memblock_is_memory(phys_addr)))
>   		return DMA_MAPPING_ERROR;
>   
>   	if (dma_map_direct(dev, ops))
>   
>>> So: there is a "hole" in the mappable memory and reading the commit message
>>> of
>>> ??? commit a7d9f306ba70 ("arm64: drop pfn_valid_within() and simplify
>>> pfn_valid()")
>>> suggests, there was a change for that case recently.
>>
>> I think the change from the arm64 pfn_valid() to the generic one is
>> avoiding the call to memblock_is_memory(). I wonder whether pfn_valid()
>> returns true just because we have a struct page available but the memory
>> may have been reserved.
>>
>> Cc'ing Mike R.
>>
>>> I also noticed there is a diff in the kernel log regarding memory init up
>>> until 5.13.12 it says
>>>
>>> [????????? 0.000000] Zone ranges:
>>> [????????? 0.000000]?????? DMA??????????????? [mem 0x0000000000200000-0x00000000feffffff]
>>> [????????? 0.000000]?????? DMA32????????? empty
>>> [????????? 0.000000]?????? Normal?????? empty
>>> [????????? 0.000000] Movable zone start for each node
>>> [????????? 0.000000] Early memory node ranges
>>> [????????? 0.000000]?????? node?????? 0: [mem 0x0000000000200000-0x00000000feffffff]
>>> [????????? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
>>> [????????? 0.000000] On node 0 totalpages: 1043968
>>> [????????? 0.000000]?????? DMA zone: 16312 pages used for memmap
>>> [????????? 0.000000]?????? DMA zone: 0 pages reserved
>>> [????????? 0.000000]?????? DMA zone: 1043968 pages, LIFO batch:63
>>>
>>> In contrary in 5.14-rc7 it says:
>>>
>>> [????????? 0.000000] Zone ranges:
>>> [????????? 0.000000]?????? DMA??????????????? [mem 0x0000000000200000-0x00000000feffffff]
>>> [????????? 0.000000]?????? DMA32????????? empty
>>> [????????? 0.000000]?????? Normal?????? empty
>>> [????????? 0.000000] Movable zone start for each node
>>> [????????? 0.000000] Early memory node ranges
>>> [????????? 0.000000]?????? node?????? 0: [mem 0x0000000000200000-0x00000000feffffff]
>>> [????????? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
>>> [????????? 0.000000] On node 0, zone DMA: 512 pages in unavailable ranges
>>> [????????? 0.000000] On node 0, zone DMA: 4096 pages in unavailable ranges
>>>
>>> (note the "unavailable ranges")
>>> I'm uncertain again here, if that diff is expected behavior because of those
>>> recent mm changes for arm64.
>>>
>>> After reverting
>>> ??? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>>> the log changes to
>>>
>>> [????????? 0.000000] Zone ranges:
>>> [????????? 0.000000]?????? DMA??????????????? [mem 0x0000000000200000-0x00000000feffffff]
>>> [????????? 0.000000]?????? DMA32????????? empty
>>> [????????? 0.000000]?????? Normal?????? empty
>>> [????????? 0.000000] Movable zone start for each node
>>> [????????? 0.000000] Early memory node ranges
>>> [????????? 0.000000]?????? node?????? 0: [mem 0x0000000000200000-0x00000000feffffff]
>>> [????????? 0.000000] Initmem setup node 0 [mem
>>> 0x0000000000200000-0x00000000feffffff]
>>>
>>> (no DMA zones here)
>>>
>>> As you might have noticed I have _zero_ clue about memory mapping and dma
>>> subsystem - so let me know if there is any more information needed for that
>>> and thanks for your help.
>>
>> Adding Robin as well, he has a better clue than us on DMA ;).
>>
>>> Alex
>>>
>>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/dma/mapping.c?id=e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93#n235
>>
>> -- 
>> Catalin
> 


From tzungbi at google.com  Tue Aug 24 11:54:53 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Wed, 25 Aug 2021 02:54:53 +0800
Subject: [PATCH 6/9] media: mtk-vcodec: Add new venc drv interface for
 frame_racing mode
In-Reply-To: <20210816105934.28265-7-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-7-irui.wang@mediatek.com>
Message-ID: <YSVAfbC93/PzPuuZ@google.com>

On Mon, Aug 16, 2021 at 06:59:31PM +0800, Irui Wang wrote:
> Frame-racing mode encoding need more venc working buffers, it
> will break the compatibility if we just add venc_vsi in AP-Kernel
> but not in firmware, so add a new venc driver interface to
> distinguish the sigle_core_mode and frame_racing mode.
> 
> The new driver interface can be used for different codecs in
> the future.
The patch contains more code than the commit message explains that I couldn't understand.  Only find some nits.

> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
> @@ -9,6 +9,7 @@
>  
>  #include "mtk_vcodec_drv.h"
>  #include "mtk_vcodec_util.h"
> +#include "mtk_vcodec_enc_hw.h"
Please try to maintain the order.

> +void __iomem *mtk_get_venc_comp_reg_addr(struct mtk_vcodec_ctx *data,
> +					 unsigned int hw_id)
> +{
> +	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data;
typeof(ctx) == typeof(data), rename the function argument 'data' to 'ctx'.

> +static int venc_alloc_work_buf(struct venc_common_inst *inst)
> +{
> +	int i;
> +	int ret = 0;
It doesn't need to be initialized.  See comment below.

> +	mtk_vcodec_debug_leave(inst);
> +
> +	return ret;
It is more clear if just return 0 here.  In the meantime, ret doesn't need to be initialized.

> +static unsigned int venc_wait_comp_done(struct venc_common_inst *inst,
> +					unsigned int hw_id)
> +{
> +	unsigned int irq_status = 0;
> +	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
No need to cast.

> +static int venc_encode_sps(struct venc_common_inst *inst,
> +			   struct mtk_vcodec_mem *bs_buf,
> +			   unsigned int *bs_size)
> +{
> +	int ret = 0;
Same.

> +	*bs_size = venc_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT,
> +				 MTK_VENC_CORE0);
> +	mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
> +
> +	return ret;
Same.

> +static int venc_encode_pps(struct venc_common_inst *inst,
> +			   struct mtk_vcodec_mem *bs_buf,
> +			   unsigned int *bs_size)
> +{
> +	int ret = 0;
Same.

> +	*bs_size = venc_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT,
> +				 MTK_VENC_CORE0);
> +	mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
> +
> +	return ret;
Same.

> +static int venc_encode_header(struct venc_common_inst *inst,
> +			      struct mtk_vcodec_mem *bs_buf,
> +			      unsigned int *bs_size)
> +{
> +	int ret = 0;
Same.

> +	memcpy(bs_buf->va + bs_size_sps, inst->pps_buf.va, bs_size_pps);
> +	*bs_size = bs_size_sps + bs_size_pps;
> +
> +	return ret;
Same.

> +static int venc_encode_frame(struct venc_common_inst *inst,
> +			     struct venc_frm_buf *frm_buf,
> +			     struct mtk_vcodec_mem *bs_buf,
> +			     unsigned int *bs_size,
> +			     int hw_id)
> +{
> +	int ret = 0;
Same.

> +	++inst->frm_cnt;
> +	mtk_vcodec_debug(inst, "frm %d bs_size %d key_frm %d <-",
> +			 inst->frm_cnt, *bs_size, inst->vpu_inst.is_key_frm);
> +
> +	return ret;
Same.

> +static void h264_encode_filler(struct venc_common_inst *inst, void *buf,
> +			       int size)
> +{
> +	unsigned char *p = buf;
> +
> +	if (size < H264_FILLER_MARKER_SIZE) {
> +		mtk_vcodec_err(inst, "filler size too small %d", size);
> +		return;
> +	}
> +
> +	memcpy(p, h264_filler_marker, ARRAY_SIZE(h264_filler_marker));
Replace ARRAY_SIZE(h264_filler_marker) to H264_FILLER_MARKER_SIZE.

> +static int venc_init(struct mtk_vcodec_ctx *ctx)
> +{
> +	int i;
> +	int ret = 0;
> +	struct venc_common_inst *inst;
> +
> +	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
> +	if (!inst)
> +		return -ENOMEM;
> +
> +	inst->ctx = ctx;
> +	inst->vpu_inst.ctx = ctx;
> +	inst->vpu_inst.id = SCP_IPI_VENC_H264;
> +
> +	mtk_vcodec_debug_enter(inst);
> +
> +	ret = vpu_enc_init(&inst->vpu_inst);
> +
> +	inst->vsi = (struct venc_vsi *)inst->vpu_inst.vsi;
No need to cast.

> +static int venc_encode(void *handle,
> +		       enum venc_start_opt opt,
> +		       struct venc_frm_buf *frm_buf,
> +		       struct mtk_vcodec_mem *bs_buf,
> +		       struct venc_done_result *result)
> +{
> +	int ret;
> +	struct venc_common_inst *inst = (struct venc_common_inst *)handle;
No need to cast.

> +	default:
> +		mtk_vcodec_err(inst, "venc_start_opt %d not supported", opt);
> +		return -EINVAL;
> +	}
> +
> +	return ret;
It is more clear if just return 0 here.

> +static int venc_set_param(void *handle,
> +			  enum venc_set_param_type type,
> +			  struct venc_enc_param *enc_prm)
> +{
> +	int ret = 0;
> +	struct venc_common_inst *inst = (struct venc_common_inst *)handle;
No need to cast.

> +static int venc_deinit(void *handle)
> +{
> +	int ret = 0;
Same.

> +	struct venc_common_inst *inst = (struct venc_common_inst *)handle;
No need to cast.

> +	mtk_vcodec_debug_leave(inst);
> +	kfree(inst);
> +
> +	return ret;
Same.


From david at redhat.com  Tue Aug 24 11:59:22 2021
From: david at redhat.com (David Hildenbrand)
Date: Tue, 24 Aug 2021 20:59:22 +0200
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
Message-ID: <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>

On 24.08.21 20:46, Robin Murphy wrote:
> On 2021-08-24 19:28, Mike Rapoport wrote:
>> On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
>>> Hi Alex,
>>>
>>> Thanks for the report.
>>>
>>> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>>>> it seems there is a regression in arm64 memory mapping in 5.14, since it
>>>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>>>
>>>> [????????? 8.921909] ------------[ cut here ]------------
>>>> [????????? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>>>> [????????? 8.921973] Modules linked in: spi_rockchip(+) fuse
>>>> [????????? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>>>> [????????? 8.922004] Hardware name: Pine64 Rock64 (DT)
>>>> [????????? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>>>> [????????? 8.922018] pc : dma_map_resource+0x68/0xc0
>>>> [????????? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
>>>> [????????? 8.922040] sp : ffff800012102ae0
>>>> [????????? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>>>> [????????? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>>>> [????????? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>>>> [????????? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>>>> [????????? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>>>> [????????? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>>>> [????????? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>>>> [????????? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>>>> [????????? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>>>> [????????? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>>>> [????????? 8.922158] Call trace:
>>>> [????????? 8.922163]??? dma_map_resource+0x68/0xc0
>>>> [????????? 8.922173]??? pl330_prep_slave_sg+0x58/0x220
>>>> [????????? 8.922181]??? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>>>> [????????? 8.922208]??? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
>>> [...]
>>>> Note: This does not relate to the spi driver - when disabling this device in
>>>> the device tree it fails for any other (i2s, for instance) which uses dma.
>>>> Commenting out the failing check at [1], however, helps and the mapping
>>>> works again.
>>
>>> Do you know which address dma_map_resource() is trying to map (maybe
>>> add some printk())? It's not supposed to map RAM, hence the warning.
>>> Random guess, the address is 0xff190800 (based on the x1 above but the
>>> regs might as well be mangled).
>>
>> 0xff190800 will cause this warning for sure. It has a memory map, but it is
>> not RAM so old version of pfn_valid() would return 0 and the new one
>> returns 1.
> 
> How does that happen, though? It's not a memory address, and it's not
> even within the bounds of anywhere there should or could be memory. This
> SoC has a simple memory map - everything from 0 to 0xfeffffff goes to
> the DRAM controller (which may not all be populated, and may have pieces
> carved out by secure firmware), while 0xff000000-0xffffffff is MMIO. Why
> do we have pages (or at least the assumption of pages) for somewhere
> which by all rights should not have them?

Simple: we allocate the vmemmap for whole sections (e.g., 128 MiB) to 
avoid any such hacks. If there is a memory hole, it gets a memmap as well.

Tricking pfn_valid() into returning "false" where we actually have a 
memmap only makes it look like there is no memmap; but there is one, and
it's PG_reserved.

[...]

>>> Either pfn_valid() gets confused in 5.14 or something is wrong with the
>>> DT. I have a suspicion it's the former since reverting the above commit
>>> makes it disappear.
>>
>> I think pfn_valid() actually behaves as expected but the caller is wrong
>> because pfn_valid != RAM (this applies btw to !arm64 as well).
>>
>> 	/* Don't allow RAM to be mapped */
>> 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
>> 		return DMA_MAPPING_ERROR;
>>
>> Alex, can you please try this patch:
> 
> That will certainly paper over the issue, but it's avoiding the question
> of what went wrong with the memory map in the first place. The comment
> is indeed a bit inaccurate, but ultimately dma_map_resource() exists for
> addresses that would be wrong to pass to dma_map_page(), so I believe
> pfn_valid() is still the correct check.

If we want to check for RAM, pfn_valid() would be wrong. If we want to 
check for "is there a memmap, for whatever lives or does not live 
there", pfn_valid() is the right check.


-- 
Thanks,

David / dhildenb



From helgaas at kernel.org  Tue Aug 24 12:00:39 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 24 Aug 2021 14:00:39 -0500
Subject: [RESEND PATCH 2/5] PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros
In-Reply-To: <20210624222621.4776-3-pali@kernel.org>
Message-ID: <20210824190039.GA3486187@bjorn-Precision-5520>

On Fri, Jun 25, 2021 at 12:26:18AM +0200, Pali Roh?r wrote:
> Define a macro PCI_EXP_DEVCTL_PAYLOAD_* for every possible Max Payload
> Size in linux/pci_regs.h, in the same style as PCI_EXP_DEVCTL_READRQ_*.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Reviewed-by: Marek Beh?n <kabel at kernel.org>

Acked-by: Bjorn Helgaas <bhelgaas at google.com>

> ---
>  include/uapi/linux/pci_regs.h | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> index e709ae8235e7..ff6ccbc6efe9 100644
> --- a/include/uapi/linux/pci_regs.h
> +++ b/include/uapi/linux/pci_regs.h
> @@ -504,6 +504,12 @@
>  #define  PCI_EXP_DEVCTL_URRE	0x0008	/* Unsupported Request Reporting En. */
>  #define  PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
>  #define  PCI_EXP_DEVCTL_PAYLOAD	0x00e0	/* Max_Payload_Size */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_128B 0x0000 /* 128 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_256B 0x0020 /* 256 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_512B 0x0040 /* 512 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_1024B 0x0060 /* 1024 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_2048B 0x0080 /* 2048 Bytes */
> +#define  PCI_EXP_DEVCTL_PAYLOAD_4096B 0x00a0 /* 4096 Bytes */
>  #define  PCI_EXP_DEVCTL_EXT_TAG	0x0100	/* Extended Tag Field Enable */
>  #define  PCI_EXP_DEVCTL_PHANTOM	0x0200	/* Phantom Functions Enable */
>  #define  PCI_EXP_DEVCTL_AUX_PME	0x0400	/* Auxiliary Power PM Enable */
> -- 
> 2.20.1
> 


From f.fainelli at gmail.com  Tue Aug 24 12:11:02 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 24 Aug 2021 21:11:02 +0200
Subject: [PATCH net-next] net: dsa: mt7530: manually set up VLAN ID 0
In-Reply-To: <20210824165253.1691315-1-dqfext@gmail.com>
References: <20210824165253.1691315-1-dqfext@gmail.com>
Message-ID: <92f006f1-bcd2-1d27-3f46-491242565e0b@gmail.com>



On 8/24/2021 6:52 PM, DENG Qingfang wrote:
> The driver was relying on dsa_slave_vlan_rx_add_vid to add VLAN ID 0. After
> the blamed commit, VLAN ID 0 won't be set up anymore, breaking software
> bridging fallback on VLAN-unaware bridges.
> 
> Manually set up VLAN ID 0 to fix this.
> 
> Fixes: 06cfb2df7eb0 ("net: dsa: don't advertise 'rx-vlan-filter' when not needed")
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From tzungbi at google.com  Tue Aug 24 12:20:39 2021
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Wed, 25 Aug 2021 03:20:39 +0800
Subject: [PATCH 7/9] media: mtk-vcodec: Add frame racing mode encode
 process
In-Reply-To: <20210816105934.28265-8-irui.wang@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-8-irui.wang@mediatek.com>
Message-ID: <YSVGh0/6mAgHFmPb@google.com>

On Mon, Aug 16, 2021 at 06:59:32PM +0800, Irui Wang wrote:
> The frame_racing mode encoding is try to use the two venc cores:
s/is try/tries/

> frame#0 use core#0, frame#1 use core#1, frame#2 use core#0...,
s/use/uses/g

> Lock the device and enabe the clock by used core, for sequence
s/enabe/enable/

> header encoding, it always used core#0.
s/used/uses/

> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -273,6 +273,7 @@ struct vdec_pic_info {
>   * @decoded_frame_cnt: number of decoded frames
>   * @lock: protect variables accessed by V4L2 threads and worker thread such as
>   *	  mtk_video_dec_buf.
> + * @enc_idx: used to record encoded frame count
>   */
>  struct mtk_vcodec_ctx {
>  	enum mtk_instance_type type;
> @@ -313,6 +314,8 @@ struct mtk_vcodec_ctx {
>  	int decoded_frame_cnt;
>  	struct mutex lock;
>  
> +	int hw_id;
> +	int enc_idx;
hw_id lacks of kerneldoc which could introduce smatch warning.

> --- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
> +++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
> @@ -15,6 +15,7 @@
>  
>  #include "mtk_vcodec_enc.h"
>  #include "mtk_vcodec_enc_pm.h"
> +#include "mtk_vcodec_enc_hw.h"
Please try to maintain the order.

> @@ -34,9 +35,9 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
>  		return -EINVAL;
>  	}
>  
> -	mtk_venc_lock(ctx);
> +	mtk_venc_lock(ctx, 0);
Does it make more sense to use ctx->hw_id instead 0 (even if it is always 0 in the path)?

>  	ret = ctx->enc_if->init(ctx);
> -	mtk_venc_unlock(ctx);
> +	mtk_venc_unlock(ctx, 0);
Same.

> @@ -46,9 +47,9 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
>  {
>  	int ret = 0;
>  
> -	mtk_venc_lock(ctx);
> +	mtk_venc_lock(ctx, 0);
Same.

>  	ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
> -	mtk_venc_unlock(ctx);
> +	mtk_venc_unlock(ctx, 0);
Same.

> @@ -87,11 +76,67 @@ int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
>  	if (!ctx->drv_handle)
>  		return 0;
>  
> -	mtk_venc_lock(ctx);
> +	mtk_venc_lock(ctx, 0);
Same.

>  	ret = ctx->enc_if->deinit(ctx->drv_handle);
> -	mtk_venc_unlock(ctx);
> +	mtk_venc_unlock(ctx, 0);
Same.

> +void venc_encode_unprepare(struct mtk_vcodec_ctx *ctx,
> +			   enum venc_start_opt opt)
> +{
> +	unsigned long flags;
> +	struct mtk_venc_comp_dev *venc;
> +
> +	/*clock off and unlock after irq done*/
> +	if (ctx->dev->venc_pdata->hw_mode == VENC_FRAME_RACING_MODE) {
> +		if (opt == VENC_START_OPT_ENCODE_SEQUENCE_HEADER) {
> +			mtk_vcodec_enc_clock_off(ctx->dev, ctx->hw_id);
> +			spin_lock_irqsave(&ctx->dev->irqlock, flags);
> +			venc = ctx->dev->enc_comp_dev[ctx->hw_id];
> +			venc->curr_ctx = NULL;
> +			spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
> +			mtk_venc_unlock(ctx, ctx->hw_id);
> +		}
> +	} else {
> +		mtk_vcodec_enc_clock_off(ctx->dev, ctx->hw_id);
> +		spin_lock_irqsave(&ctx->dev->irqlock, flags);
> +		ctx->dev->curr_ctx = NULL;
> +		spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
> +		mtk_venc_unlock(ctx, ctx->hw_id);
The few statements are identical.  Should try to reuse them.


From robh+dt at kernel.org  Tue Aug 24 13:05:23 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 15:05:23 -0500
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <20210816074619.177383-4-wangkefeng.wang@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
Message-ID: <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>

+Saravana

Saravana mentioned to me there may be some issues with this one...


On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
> of_amba_device_create() uses irq_of_parse_and_map() to translate
> a DT interrupt specification into a Linux virtual interrupt number.
>
> But it doesn't properly handle the case where the interrupt controller
> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
> interrupt controller, because the mbigen initialization is too late,
> which will lead to no IRQ due to no IRQ domain found, log is shown below,
>   "irq: no irq domain found for uart0 !"
>
> use of_irq_get() to return -EPROBE_DEFER as above, and in the function
> amba_device_try_add()/amba_device_add(), it will properly handle in such
> case, also return 0 in other fail cases to be consistent as before.
>
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Frank Rowand <frowand.list at gmail.com>
> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
>  drivers/of/platform.c |  6 +-----
>  2 files changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index 36f2f42c8014..720aa6cdd402 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -19,6 +19,7 @@
>  #include <linux/clk/clk-conf.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset.h>
> +#include <linux/of_irq.h>
>
>  #include <asm/irq.h>
>
> @@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
>         kfree(d);
>  }
>
> +static int of_amba_device_decode_irq(struct amba_device *dev)
> +{
> +       struct device_node *node = dev->dev.of_node;
> +       int i, irq = 0;
> +
> +       if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
> +               /* Decode the IRQs and address ranges */
> +               for (i = 0; i < AMBA_NR_IRQS; i++) {
> +                       irq = of_irq_get(node, i);
> +                       if (irq < 0) {
> +                               if (irq == -EPROBE_DEFER)
> +                                       return irq;
> +                               irq = 0;
> +                       }
> +
> +                       dev->irq[i] = irq;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
>  static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
>  {
>         u32 size;
>         void __iomem *tmp;
>         int i, ret;
>
> +       ret = of_amba_device_decode_irq(dev);
> +       if (ret)
> +               goto err_out;
> +
>         ret = request_resource(parent, &dev->res);
>         if (ret)
>                 goto err_out;
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 74afbb7a4f5e..32d5ff8df747 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -222,7 +222,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  {
>         struct amba_device *dev;
>         const void *prop;
> -       int i, ret;
> +       int ret;
>
>         pr_debug("Creating amba device %pOF\n", node);
>
> @@ -253,10 +253,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>         if (prop)
>                 dev->periphid = of_read_ulong(prop, 1);
>
> -       /* Decode the IRQs and address ranges */
> -       for (i = 0; i < AMBA_NR_IRQS; i++)
> -               dev->irq[i] = irq_of_parse_and_map(node, i);
> -
>         ret = of_address_to_resource(node, 0, &dev->res);
>         if (ret) {
>                 pr_err("amba: of_address_to_resource() failed (%d) for %pOF\n",
> --
> 2.26.2
>


From knaerzche at gmail.com  Tue Aug 24 13:07:14 2021
From: knaerzche at gmail.com (Alex Bee)
Date: Tue, 24 Aug 2021 22:07:14 +0200
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210824173741.GC623@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com>
Message-ID: <72d211b4-fe40-cc88-e831-9257ccad48af@gmail.com>

Hi Catalin,

thanks for your quick reply.

Am 24.08.21 um 19:37 schrieb Catalin Marinas:
> Hi Alex,
>
> Thanks for the report.
>
> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>> it seems there is a regression in arm64 memory mapping in 5.14, since it
>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>
>> [??? 8.921909] ------------[ cut here ]------------
>> [??? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>> [??? 8.921973] Modules linked in: spi_rockchip(+) fuse
>> [??? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>> [??? 8.922004] Hardware name: Pine64 Rock64 (DT)
>> [??? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>> [??? 8.922018] pc : dma_map_resource+0x68/0xc0
>> [??? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
>> [??? 8.922040] sp : ffff800012102ae0
>> [??? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>> [??? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>> [??? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>> [??? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>> [??? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>> [??? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>> [??? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>> [??? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>> [??? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>> [??? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>> [??? 8.922158] Call trace:
>> [??? 8.922163]? dma_map_resource+0x68/0xc0
>> [??? 8.922173]? pl330_prep_slave_sg+0x58/0x220
>> [??? 8.922181]? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>> [??? 8.922208]? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
> [...]
>> Note: This does not relate to the spi driver - when disabling this device in
>> the device tree it fails for any other (i2s, for instance) which uses dma.
>> Commenting out the failing check at [1], however, helps and the mapping
>> works again.
> Do you know which address dma_map_resource() is trying to map (maybe
> add some printk())? It's not supposed to map RAM, hence the warning.
> Random guess, the address is 0xff190800 (based on the x1 above but the
> regs might as well be mangled).

Confirmed:

[..]

[??? 8.353879] dma_map_resource Failed to map address 0xff190800

[..]

Alex

>
>> I tried to follow the recent changes for arm64 mm which could relate to the
>> check failing at [1] and reverting
>>  ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>> helps and makes it work again, but I'm 100% uncertain if that commit is
>> really the culprit.
>>
>> Note, that the firmware (legacy u-boot) injects memory configuration in the
>> device tree as follows:
>>
>> /memreserve/??? 0x00000000fcefc000 0x000000000000d000;
>> / {
>> ..
>>  ??? compatible = "pine64,rock64\0rockchip,rk3328";
>> ..
>>  ??? memory {
>>  ??? ??? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
>>  ??? ??? device_type = "memory";
>>  ??? };
>>
>> ..
>> }
> Either pfn_valid() gets confused in 5.14 or something is wrong with the
> DT. I have a suspicion it's the former since reverting the above commit
> makes it disappear.
>
>> So: there is a "hole" in the mappable memory and reading the commit message
>> of
>>  ? commit a7d9f306ba70 ("arm64: drop pfn_valid_within() and simplify
>> pfn_valid()")
>> suggests, there was a change for that case recently.
> I think the change from the arm64 pfn_valid() to the generic one is
> avoiding the call to memblock_is_memory(). I wonder whether pfn_valid()
> returns true just because we have a struct page available but the memory
> may have been reserved.
>
> Cc'ing Mike R.
>
>> I also noticed there is a diff in the kernel log regarding memory init up
>> until 5.13.12 it says
>>
>> [??? 0.000000] Zone ranges:
>> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
>> [??? 0.000000]?? DMA32??? empty
>> [??? 0.000000]?? Normal?? empty
>> [??? 0.000000] Movable zone start for each node
>> [??? 0.000000] Early memory node ranges
>> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
>> [??? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
>> [??? 0.000000] On node 0 totalpages: 1043968
>> [??? 0.000000]?? DMA zone: 16312 pages used for memmap
>> [??? 0.000000]?? DMA zone: 0 pages reserved
>> [??? 0.000000]?? DMA zone: 1043968 pages, LIFO batch:63
>>
>> In contrary in 5.14-rc7 it says:
>>
>> [??? 0.000000] Zone ranges:
>> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
>> [??? 0.000000]?? DMA32??? empty
>> [??? 0.000000]?? Normal?? empty
>> [??? 0.000000] Movable zone start for each node
>> [??? 0.000000] Early memory node ranges
>> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
>> [??? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
>> [??? 0.000000] On node 0, zone DMA: 512 pages in unavailable ranges
>> [??? 0.000000] On node 0, zone DMA: 4096 pages in unavailable ranges
>>
>> (note the "unavailable ranges")
>> I'm uncertain again here, if that diff is expected behavior because of those
>> recent mm changes for arm64.
>>
>> After reverting
>>  ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>> the log changes to
>>
>> [??? 0.000000] Zone ranges:
>> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
>> [??? 0.000000]?? DMA32??? empty
>> [??? 0.000000]?? Normal?? empty
>> [??? 0.000000] Movable zone start for each node
>> [??? 0.000000] Early memory node ranges
>> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
>> [??? 0.000000] Initmem setup node 0 [mem
>> 0x0000000000200000-0x00000000feffffff]
>>
>> (no DMA zones here)
>>
>> As you might have noticed I have _zero_ clue about memory mapping and dma
>> subsystem - so let me know if there is any more information needed for that
>> and thanks for your help.
> Adding Robin as well, he has a better clue than us on DMA ;).
>
>> Alex
>>
>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/dma/mapping.c?id=e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93#n235


From saravanak at google.com  Tue Aug 24 13:08:19 2021
From: saravanak at google.com (Saravana Kannan)
Date: Tue, 24 Aug 2021 13:08:19 -0700
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
Message-ID: <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>

On Tue, Aug 24, 2021 at 1:05 PM Rob Herring <robh+dt at kernel.org> wrote:
>
> +Saravana
>
> Saravana mentioned to me there may be some issues with this one...
>
>
> On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> >
> > of_amba_device_create() uses irq_of_parse_and_map() to translate
> > a DT interrupt specification into a Linux virtual interrupt number.
> >
> > But it doesn't properly handle the case where the interrupt controller
> > is not yet available, eg, when pl011 interrupt is connected to MBIGEN
> > interrupt controller, because the mbigen initialization is too late,
> > which will lead to no IRQ due to no IRQ domain found, log is shown below,
> >   "irq: no irq domain found for uart0 !"
> >
> > use of_irq_get() to return -EPROBE_DEFER as above, and in the function
> > amba_device_try_add()/amba_device_add(), it will properly handle in such
> > case, also return 0 in other fail cases to be consistent as before.
> >
> > Cc: Russell King <linux at armlinux.org.uk>
> > Cc: Rob Herring <robh+dt at kernel.org>
> > Cc: Frank Rowand <frowand.list at gmail.com>
> > Reported-by: Ruizhe Lin <linruizhe at huawei.com>
> > Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> > ---
> >  drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
> >  drivers/of/platform.c |  6 +-----
> >  2 files changed, 28 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> > index 36f2f42c8014..720aa6cdd402 100644
> > --- a/drivers/amba/bus.c
> > +++ b/drivers/amba/bus.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/clk/clk-conf.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/reset.h>
> > +#include <linux/of_irq.h>
> >
> >  #include <asm/irq.h>
> >
> > @@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
> >         kfree(d);
> >  }
> >
> > +static int of_amba_device_decode_irq(struct amba_device *dev)
> > +{
> > +       struct device_node *node = dev->dev.of_node;
> > +       int i, irq = 0;
> > +
> > +       if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
> > +               /* Decode the IRQs and address ranges */
> > +               for (i = 0; i < AMBA_NR_IRQS; i++) {
> > +                       irq = of_irq_get(node, i);
> > +                       if (irq < 0) {
> > +                               if (irq == -EPROBE_DEFER)
> > +                                       return irq;
> > +                               irq = 0;
> > +                       }
> > +
> > +                       dev->irq[i] = irq;
> > +               }
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> >  static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
> >  {
> >         u32 size;
> >         void __iomem *tmp;
> >         int i, ret;
> >
> > +       ret = of_amba_device_decode_irq(dev);
> > +       if (ret)
> > +               goto err_out;
> > +

Similar to other resources the AMBA bus "gets" for the device, I think
this should be moved into amba_probe() and not here. There's no reason
to delay the addition of the device (and loading its module) because
the IRQ isn't ready yet.

-Saravana

> >         ret = request_resource(parent, &dev->res);
> >         if (ret)
> >                 goto err_out;
> > diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> > index 74afbb7a4f5e..32d5ff8df747 100644
> > --- a/drivers/of/platform.c
> > +++ b/drivers/of/platform.c
> > @@ -222,7 +222,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
> >  {
> >         struct amba_device *dev;
> >         const void *prop;
> > -       int i, ret;
> > +       int ret;
> >
> >         pr_debug("Creating amba device %pOF\n", node);
> >
> > @@ -253,10 +253,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
> >         if (prop)
> >                 dev->periphid = of_read_ulong(prop, 1);
> >
> > -       /* Decode the IRQs and address ranges */
> > -       for (i = 0; i < AMBA_NR_IRQS; i++)
> > -               dev->irq[i] = irq_of_parse_and_map(node, i);
> > -
> >         ret = of_address_to_resource(node, 0, &dev->res);
> >         if (ret) {
> >                 pr_err("amba: of_address_to_resource() failed (%d) for %pOF\n",
> > --
> > 2.26.2
> >


From knaerzche at gmail.com  Tue Aug 24 13:14:01 2021
From: knaerzche at gmail.com (Alex Bee)
Date: Tue, 24 Aug 2021 22:14:01 +0200
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <YSU6NVZ3j0XCurWC@kernel.org>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
Message-ID: <b37fc109-06d3-0c86-a3c8-e5d7f21f296b@gmail.com>

Hi Mike,

thanks for your reply

Am 24.08.21 um 20:28 schrieb Mike Rapoport:
> On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
>> Hi Alex,
>>
>> Thanks for the report.
>>
>> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>>> it seems there is a regression in arm64 memory mapping in 5.14, since it
>>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>>
>>> [??? 8.921909] ------------[ cut here ]------------
>>> [??? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>>> [??? 8.921973] Modules linked in: spi_rockchip(+) fuse
>>> [??? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>>> [??? 8.922004] Hardware name: Pine64 Rock64 (DT)
>>> [??? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>>> [??? 8.922018] pc : dma_map_resource+0x68/0xc0
>>> [??? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
>>> [??? 8.922040] sp : ffff800012102ae0
>>> [??? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>>> [??? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>>> [??? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>>> [??? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>>> [??? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>>> [??? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>>> [??? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>>> [??? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>>> [??? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>>> [??? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>>> [??? 8.922158] Call trace:
>>> [??? 8.922163]? dma_map_resource+0x68/0xc0
>>> [??? 8.922173]? pl330_prep_slave_sg+0x58/0x220
>>> [??? 8.922181]? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>>> [??? 8.922208]? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
>> [...]
>>> Note: This does not relate to the spi driver - when disabling this device in
>>> the device tree it fails for any other (i2s, for instance) which uses dma.
>>> Commenting out the failing check at [1], however, helps and the mapping
>>> works again.
>> Do you know which address dma_map_resource() is trying to map (maybe
>> add some printk())? It's not supposed to map RAM, hence the warning.
>> Random guess, the address is 0xff190800 (based on the x1 above but the
>> regs might as well be mangled).
> 0xff190800 will cause this warning for sure. It has a memory map, but it is
> not RAM so old version of pfn_valid() would return 0 and the new one
> returns 1.
>   
>>> I tried to follow the recent changes for arm64 mm which could relate to the
>>> check failing at [1] and reverting
>>>  ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>>> helps and makes it work again, but I'm 100% uncertain if that commit is
>>> really the culprit.
>>>
>>> Note, that the firmware (legacy u-boot) injects memory configuration in the
>>> device tree as follows:
>>>
>>> /memreserve/??? 0x00000000fcefc000 0x000000000000d000;
>>> / {
>>> ..
>>>  ??? compatible = "pine64,rock64\0rockchip,rk3328";
>>> ..
>>>  ??? memory {
>>>  ??? ??? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
>>>  ??? ??? device_type = "memory";
>>>  ??? };
>>>
>>> ..
>>> }
>> Either pfn_valid() gets confused in 5.14 or something is wrong with the
>> DT. I have a suspicion it's the former since reverting the above commit
>> makes it disappear.
> I think pfn_valid() actually behaves as expected but the caller is wrong
> because pfn_valid != RAM (this applies btw to !arm64 as well).
>
> 	/* Don't allow RAM to be mapped */
> 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> 		return DMA_MAPPING_ERROR;
>
> Alex, can you please try this patch:
>
> diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
> index 2b06a809d0b9..4715e9641a29 100644
> --- a/kernel/dma/mapping.c
> +++ b/kernel/dma/mapping.c
> @@ -232,7 +232,7 @@ dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr,
>   		return DMA_MAPPING_ERROR;
>   
>   	/* Don't allow RAM to be mapped */
> -	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> +	if (WARN_ON_ONCE(!memblock_is_memory(phys_addr)))
>   		return DMA_MAPPING_ERROR;
>   
>   	if (dma_map_direct(dev, ops))
>   

Nope, doesn't help:

[??? 8.353879] dma_map_resource Failed to map address 0xff190800
[??? 8.353886] dma_map_resource pfn_valid(PHYS_PFN(0xff190800)): 1
[??? 8.353892] dma_map_resource memblock_is_memory(0xff190800): 0

If understand the comment for that check correct, that we _don't_ want 
RAM to be mapped - shoudn't that be:

+	if (WARN_ON_ONCE(memblock_is_memory(phys_addr)))

?

Alex

>>> So: there is a "hole" in the mappable memory and reading the commit message
>>> of
>>>  ? commit a7d9f306ba70 ("arm64: drop pfn_valid_within() and simplify
>>> pfn_valid()")
>>> suggests, there was a change for that case recently.
>> I think the change from the arm64 pfn_valid() to the generic one is
>> avoiding the call to memblock_is_memory(). I wonder whether pfn_valid()
>> returns true just because we have a struct page available but the memory
>> may have been reserved.
>>
>> Cc'ing Mike R.
>>
>>> I also noticed there is a diff in the kernel log regarding memory init up
>>> until 5.13.12 it says
>>>
>>> [??? 0.000000] Zone ranges:
>>> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
>>> [??? 0.000000]?? DMA32??? empty
>>> [??? 0.000000]?? Normal?? empty
>>> [??? 0.000000] Movable zone start for each node
>>> [??? 0.000000] Early memory node ranges
>>> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
>>> [??? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
>>> [??? 0.000000] On node 0 totalpages: 1043968
>>> [??? 0.000000]?? DMA zone: 16312 pages used for memmap
>>> [??? 0.000000]?? DMA zone: 0 pages reserved
>>> [??? 0.000000]?? DMA zone: 1043968 pages, LIFO batch:63
>>>
>>> In contrary in 5.14-rc7 it says:
>>>
>>> [??? 0.000000] Zone ranges:
>>> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
>>> [??? 0.000000]?? DMA32??? empty
>>> [??? 0.000000]?? Normal?? empty
>>> [??? 0.000000] Movable zone start for each node
>>> [??? 0.000000] Early memory node ranges
>>> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
>>> [??? 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x00000000feffffff]
>>> [??? 0.000000] On node 0, zone DMA: 512 pages in unavailable ranges
>>> [??? 0.000000] On node 0, zone DMA: 4096 pages in unavailable ranges
>>>
>>> (note the "unavailable ranges")
>>> I'm uncertain again here, if that diff is expected behavior because of those
>>> recent mm changes for arm64.
>>>
>>> After reverting
>>>  ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>>> the log changes to
>>>
>>> [??? 0.000000] Zone ranges:
>>> [??? 0.000000]?? DMA????? [mem 0x0000000000200000-0x00000000feffffff]
>>> [??? 0.000000]?? DMA32??? empty
>>> [??? 0.000000]?? Normal?? empty
>>> [??? 0.000000] Movable zone start for each node
>>> [??? 0.000000] Early memory node ranges
>>> [??? 0.000000]?? node?? 0: [mem 0x0000000000200000-0x00000000feffffff]
>>> [??? 0.000000] Initmem setup node 0 [mem
>>> 0x0000000000200000-0x00000000feffffff]
>>>
>>> (no DMA zones here)
>>>
>>> As you might have noticed I have _zero_ clue about memory mapping and dma
>>> subsystem - so let me know if there is any more information needed for that
>>> and thanks for your help.
>> Adding Robin as well, he has a better clue than us on DMA ;).
>>
>>> Alex
>>>
>>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/dma/mapping.c?id=e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93#n235
>> -- 
>> Catalin


From oupton at google.com  Tue Aug 24 14:15:03 2021
From: oupton at google.com (Oliver Upton)
Date: Tue, 24 Aug 2021 21:15:03 +0000
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
Message-ID: <YSVhV+UIMY12u2PW@google.com>

Hey folks,

Ricardo and I were discussing hypercall support in KVM/arm64 and
something seems to be a bit problematic. I do not see anywhere that KVM
requires opt-in from the VMM to expose new hypercalls to the guest. To
name a few, the TRNG and KVM PTP hypercalls are unconditionally provided
to the guest.

Exposing new hypercalls to guests in this manner seems very unsafe to
me. Suppose an operator is trying to upgrade from kernel N to kernel
N+1, which brings in the new 'widget' hypercall. Guests are live
migrated onto the N+1 kernel, but the operator finds a defect that
warrants a kernel rollback. VMs are then migrated from kernel N+1 -> N.
Any guests that discovered the 'widget' hypercall are likely going to
get fussy _very_ quickly on the old kernel.

Really, we need to ensure that the exposed guest ABI is
backwards-compatible. Running a VMM that is blissfully unaware of the
'widget' hypercall should not implicitly expose it to its guest on a new
kernel.

This conversation was in the context of devising a new UAPI that allows
VMMs to trap hypercalls to userspace. While such an interface would
easily work around the issue, the onus of ABI compatibility lies with
the kernel.

So, this is all a long-winded way of asking: how do we dig ourselves out
of this situation, and how to we avoid it happening again in the future?
I believe the answer to both is to have new VM capabilities for sets of
hypercalls exposed to the guest. Unfortunately, the unconditional
exposure of TRNG and PTP hypercalls is ABI now, so we'd have to provide
an opt-out at this point. For anything new, require opt-in from the VMM
before we give it to the guest.

Have I missed something blatantly obvious, or do others see this as an
issue as well? I'll reply with an example of adding opt-out for PTP.
I'm sure other hypercalls could be handled similarly.

--
Thanks,
Oliver


From jeremy.linton at arm.com  Tue Aug 24 14:39:20 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Tue, 24 Aug 2021 16:39:20 -0500
Subject: [PATCH v2 3/4] PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
In-Reply-To: <9796674a-5870-135c-2fdc-fb0d5347d7c7@gmail.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
 <20210819215655.84866-4-jeremy.linton@arm.com>
 <9796674a-5870-135c-2fdc-fb0d5347d7c7@gmail.com>
Message-ID: <ddffee4b-8136-9ca1-85f7-bfdbac07bfe7@arm.com>

Hi,

On 8/22/21 3:53 AM, Florian Fainelli wrote:
> 
> 
> On 8/19/2021 11:56 PM, Jeremy Linton wrote:
>> Now that there is a bcm2711 quirk, it needs to be enabled when the
>> MCFG is missing. Use an ACPI namespace _DSD property
>> "linux-ecam-quirk-id" as an alternative to the MCFG OEM.
>>
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>> ? drivers/acpi/pci_mcfg.c | 13 +++++++++++++
>> ? 1 file changed, 13 insertions(+)
>>
>> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
>> index 53cab975f612..4b991ee5c66c 100644
>> --- a/drivers/acpi/pci_mcfg.c
>> +++ b/drivers/acpi/pci_mcfg.c
>> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>> ????? ALTRA_ECAM_QUIRK(1, 13),
>> ????? ALTRA_ECAM_QUIRK(1, 14),
>> ????? ALTRA_ECAM_QUIRK(1, 15),
>> +
>> +??? { "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
>> +????? DEFINE_RES_MEM(0xFD500000, 0xA000) },
>> ? };
>> ? static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
>> @@ -198,8 +201,18 @@ static void pci_mcfg_apply_quirks(struct 
>> acpi_pci_root *root,
>> ????? u16 segment = root->segment;
>> ????? struct resource *bus_range = &root->secondary;
>> ????? struct mcfg_fixup *f;
>> +??? const char *soc;
>> ????? int i;
>> +??? /*
>> +???? * This may be a machine with a PCI/SMC conduit, which means it 
>> doesn't
>> +???? * have an MCFG. Use an ACPI namespace definition instead.
>> +???? */
>> +??? if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
>> +???????????????????? "linux-ecam-quirk-id", &soc)) {
>> +??????? memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
> 
> Being super paranoid here, can we use one of the "safe" string copy 
> routines here just in case?

Hmm, I went around with this a bit when I first wrote it, because the 
OEM fields in the ACPI tables are fixed len and don't have null 
termination. Maybe the right thing to do here is verify the string size 
is at least as long as the OEM_ID_SIZE and then continue to use the memcpy.

> 
>> +??? }
>> +
>> ????? for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, 
>> f++) {
>> ????????? if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
>> ????????????? if (f->cfgres.start)
>>
> 



From nfraprado at collabora.com  Tue Aug 24 14:45:15 2021
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Tue, 24 Aug 2021 18:45:15 -0300
Subject: [PATCH v3 2/5] leds: Add driver for QCOM SPMI Flash LEDs
In-Reply-To: <b1060e9a-f78e-fbe9-bde3-2b4d89cbc73e@gmail.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
 <20210803162641.1525980-3-nfraprado@collabora.com>
 <b1060e9a-f78e-fbe9-bde3-2b4d89cbc73e@gmail.com>
Message-ID: <20210824214515.ekjpvaymkgxltlzp@notapiano>

Hi Jacek,

Thank you for the review. I'll answer below.

On Tue, Aug 17, 2021 at 12:03:49AM +0200, Jacek Anaszewski wrote:
> Hi Nicolas,
> 
> Thanks for the update. See my comments below.
> 
> On 8/3/21 6:26 PM, N?colas F. R. A. Prado wrote:
> > Add driver for Qualcomm's SPMI Flash LEDs. These are controlled
> > through an SPMI bus and are part of the PM8941 PMIC. There are two LEDs
> > present on the chip, which can be used independently as camera flash or,
> > when in torch mode, as a lantern.
> > 
> > Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
> > ---
> > 
> > Changes in v3:
> > - The two LEDs can now be operated independently even when in torch mode
> > - The flashes can now strobe consecutive times without needing to manually
> >    disable them between strobes
> > - Implemented strobe_get()
> > - Moved dt parsing to a separate function
> > - Split multiplexed torch/flash on/off and torch/flash regulator on/off
> >    functions
> > - Set current on brightness callback and timeout on timeout callback, instead of
> >    setting everything every time when strobing/turning torch on
> > - And a whole lot of other minor changes
> > 
> > Changes in v2:
> > - Thanks to Jacek:
> >    - Implemented flash LED class framework
> > - Thanks to Bjorn:
> >    - Renamed driver to "qcom spmi flash"
> > - Refactored code
> > - Added missing copyright
> > 
> >   drivers/leds/flash/Kconfig                |    8 +
> >   drivers/leds/flash/Makefile               |    1 +
> >   drivers/leds/flash/leds-qcom-spmi-flash.c | 1251 +++++++++++++++++++++
> >   3 files changed, 1260 insertions(+)
> >   create mode 100644 drivers/leds/flash/leds-qcom-spmi-flash.c
> > 
> > diff --git a/drivers/leds/flash/Kconfig b/drivers/leds/flash/Kconfig
> > index 3f49f3edbffb..72f61323cd2a 100644
> > --- a/drivers/leds/flash/Kconfig
> > +++ b/drivers/leds/flash/Kconfig
> > @@ -24,4 +24,12 @@ config LEDS_RT8515
> >   	  To compile this driver as a module, choose M here: the module
> >   	  will be called leds-rt8515.
> > +config LEDS_QCOM_SPMI_FLASH
> > +	tristate "Support for QCOM SPMI Flash LEDs"
> > +	depends on REGMAP_SPMI
> > +	depends on OF
> > +	help
> > +	  This option enables support for the flash/torch LEDs present in
> > +	  Qualcomm's PM8941 PMIC.
> > +
> >   endif # LEDS_CLASS_FLASH
> > diff --git a/drivers/leds/flash/Makefile b/drivers/leds/flash/Makefile
> > index 09aee561f769..c141d277e9b6 100644
> > --- a/drivers/leds/flash/Makefile
> > +++ b/drivers/leds/flash/Makefile
> > @@ -2,3 +2,4 @@
> >   obj-$(CONFIG_LEDS_RT4505)	+= leds-rt4505.o
> >   obj-$(CONFIG_LEDS_RT8515)	+= leds-rt8515.o
> > +obj-$(CONFIG_LEDS_QCOM_SPMI_FLASH)	+= leds-qcom-spmi-flash.o
> > diff --git a/drivers/leds/flash/leds-qcom-spmi-flash.c b/drivers/leds/flash/leds-qcom-spmi-flash.c
> > new file mode 100644
> > index 000000000000..9763707bb986
> > --- /dev/null
> > +++ b/drivers/leds/flash/leds-qcom-spmi-flash.c
> > @@ -0,0 +1,1251 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Qualcomm SPMI Flash LEDs Driver
> > + *
> > + * Copyright (c) 2020-2021, N?colas F. R. A. Prado <n at nfraprado.net>
> > + * Copyright (c) 2021, Collabora Ltd.
> > + *
> > + * Based on QPNP LEDs driver from downstream MSM kernel sources.
> > + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/device.h>
> > +#include <linux/kernel.h>
> > +#include <linux/led-class-flash.h>
> > +#include <linux/module.h>
> > +#include <linux/mutex.h>
> > +#include <linux/of_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <linux/spmi.h>
> > +#include <linux/string.h>
> > +#include <linux/sysfs.h>
> > +#include <linux/types.h>
> > +
> > +#define QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE	0x05
> > +#define QCOM_FLASH_ADDR_STATUS			0x10
> > +#define QCOM_FLASH_ADDR_SAFETY_TIMER		0x40
> > +#define QCOM_FLASH_ADDR_MAX_CURR		0x41
> > +#define QCOM_FLASH_ADDR_CURR_LED0		0x42
> > +#define QCOM_FLASH_ADDR_CURR_LED1		0x43
> > +#define QCOM_FLASH_ADDR_CLAMP_CURR		0x44
> > +#define QCOM_FLASH_ADDR_ENABLE_CONTROL		0x46
> > +#define QCOM_FLASH_ADDR_LED_STROBE_CTRL		0x47
> > +#define QCOM_FLASH_ADDR_LED_TMR_CTRL		0x48
> > +#define QCOM_FLASH_ADDR_HEADROOM		0x4A
> > +#define QCOM_FLASH_ADDR_STARTUP_DELAY		0x4B
> > +#define QCOM_FLASH_ADDR_MASK_ENABLE		0x4C
> > +#define QCOM_FLASH_ADDR_VREG_OK_FORCE		0x4F
> > +#define QCOM_FLASH_ADDR_LED_UNLOCK_SECURE	0xD0
> > +#define QCOM_FLASH_ADDR_LED_TORCH		0xE4
> > +#define QCOM_FLASH_ADDR_FAULT_DETECT		0x51
> > +#define QCOM_FLASH_ADDR_RAMP_RATE		0x54
> > +#define QCOM_FLASH_ADDR_VPH_PWR_DROOP		0x5A
> > +
> > +#define QCOM_FLASH_MAX_LEVEL		0x4F
> > +#define QCOM_FLASH_TORCH_MAX_LEVEL	0x0F
> > +#define	QCOM_FLASH_NO_MASK		0x00
> > +
> > +#define QCOM_FLASH_MASK_1		0x20
> > +#define QCOM_FLASH_MASK_REG_MASK	0xE0
> > +#define QCOM_FLASH_HEADROOM_MASK	0x03
> > +#define QCOM_FLASH_SAFETY_TIMER_MASK	0x7F
> > +#define QCOM_FLASH_CURRENT_MASK		0xFF
> > +#define QCOM_FLASH_MAX_CURRENT_MASK	0x7F
> > +#define QCOM_FLASH_TMR_MASK		0x03
> > +#define QCOM_FLASH_TMR_WATCHDOG		0x03
> > +#define QCOM_FLASH_TMR_SAFETY		0x00
> > +#define QCOM_FLASH_FAULT_DETECT_MASK	0x80
> > +#define QCOM_FLASH_HW_VREG_OK		0x40
> > +#define QCOM_FLASH_VREG_MASK		0xC0
> > +#define QCOM_FLASH_STARTUP_DLY_MASK	0x02
> > +#define QCOM_FLASH_RAMP_RATE_MASK	0xBF
> > +#define QCOM_FLASH_VPH_PWR_DROOP_MASK	0xF3
> > +
> > +#define QCOM_FLASH_ENABLE_ALL		0xE0
> > +#define QCOM_FLASH_ENABLE_MODULE	0x80
> > +#define QCOM_FLASH_ENABLE_MODULE_MASK	0x80
> > +#define QCOM_FLASH_DISABLE_ALL		0x00
> > +#define QCOM_FLASH_ENABLE_MASK		0xE0
> > +#define QCOM_FLASH_ENABLE_LED0		0xC0
> > +#define QCOM_FLASH_ENABLE_LED1		0xA0
> > +#define QCOM_FLASH_INIT_MASK		0xE0
> > +#define QCOM_FLASH_SELFCHECK_ENABLE	0x80
> > +#define QCOM_FLASH_SELFCHECK_DISABLE	0x00
> > +
> > +#define QCOM_FLASH_STROBE_SW		0xC0
> > +#define QCOM_FLASH_STROBE_HW		0x04
> > +#define QCOM_FLASH_STROBE_MASK		0xC7
> > +#define QCOM_FLASH_STROBE_LED0		0x80
> > +#define QCOM_FLASH_STROBE_LED1		0x40
> > +
> > +#define QCOM_FLASH_TORCH_MASK		0x03
> > +#define QCOM_FLASH_LED_TORCH_ENABLE	0x00
> > +#define QCOM_FLASH_LED_TORCH_DISABLE	0x03
> > +#define QCOM_FLASH_UNLOCK_SECURE	0xA5
> > +#define QCOM_FLASH_SECURE_MASK		0xFF
> > +
> > +#define QCOM_FLASH_SUBTYPE_DUAL		0x01
> > +#define QCOM_FLASH_SUBTYPE_SINGLE	0x02
> > +
> > +#define QCOM_FLASH_DURATION_STEP	10000
> > +#define QCOM_FLASH_DURATION_MIN		10000
> > +#define QCOM_FLASH_DURATION_DEFAULT	200000
> > +
> > +#define QCOM_FLASH_CURRENT_STEP		12500
> > +#define QCOM_FLASH_CURRENT_MIN		12500
> > +
> > +#define QCOM_FLASH_DEFAULT_CLAMP	200000
> > +
> > +#define QCOM_FLASH_MASK_ON_LED0		0x8
> > +#define QCOM_FLASH_MASK_ON_LED1		0x2
> > +#define QCOM_FLASH_MASK_STATUS_TIMEDOUT	0x5
> > +
> > +enum qcom_flash_headroom {
> > +	QCOM_FLASH_HEADROOM_250MV,
> > +	QCOM_FLASH_HEADROOM_300MV,
> > +	QCOM_FLASH_HEADROOM_400MV,
> > +	QCOM_FLASH_HEADROOM_500MV,
> > +};
> > +
> > +enum qcom_flash_startup_dly {
> > +	QCOM_FLASH_STARTUP_DLY_10US,
> > +	QCOM_FLASH_STARTUP_DLY_32US,
> > +	QCOM_FLASH_STARTUP_DLY_64US,
> > +	QCOM_FLASH_STARTUP_DLY_128US,
> > +};
> > +
> > +enum qcom_flash_ids {
> > +	QCOM_FLASH_ID_LED0,
> > +	QCOM_FLASH_ID_LED1,
> > +};
> > +
> > +/**
> > + * struct qcom_flash_led - Represents each individual flash LED
> > + * @fled_cdev: flash LED classdev
> > + * @id: LED ID as given by enum qcom_flash_ids
> > + * @default_on: default state for the LED
> > + * @flash_enable_cmd: enable command for particular flash
> > + * @flash_strobe_cmd: strobe command for particular flash
> > + * @current_addr: address to write for current
> > + * @mask_led_on: bitmask for STATUS register that shows if LED is on
> > + * @flash_current_invalidated: whether the flash current in the current register
> > + *	was invalidated by torch usage
> > + */
> > +struct qcom_flash_led {
> > +	struct led_classdev_flash fled_cdev;
> > +	enum qcom_flash_ids id;
> > +	bool default_on;
> > +	u8 flash_enable_cmd;
> > +	u8 flash_strobe_cmd;
> > +	u16 current_addr;
> > +	u8 mask_led_on;
> > +	bool flash_current_invalidated;
> > +};
> > +
> > +/**
> > + * struct qcom_flash_device - QCOM SPMI Flash device, contains 2 flash LEDs
> > + * @regmap: regmap used to access LED registers over SPMI
> > + * @base: base register given in device tree
> > + * @dev: device from devicetree
> > + * @flash_supply: voltage regulator to supply the flashes
> > + * @torch_supply: voltage regulator to supply torch mode
> > + * @leds: flash LEDs
> > + * @num_leds: number of LEDs registered (between 0 and 2)
> > + * @lock: lock to protect SPMI transactions
> > + * @torch_enable_cmd: enable flash LED torch mode
> > + * @peripheral_subtype: module peripheral subtype
> > + * @flash_regulator_on: flash regulator status
> > + * @torch_regulator_on: torch regulator status
> > + * @torch_enabled: whether torch mode is enabled
> > + */
> > +struct qcom_flash_device {
> > +	struct regmap *regmap;
> > +	unsigned int base;
> > +	struct device *dev;
> > +	struct regulator *flash_supply;
> > +	struct regulator *torch_supply;
> > +	struct qcom_flash_led leds[2];
> > +	u8 num_leds;
> > +	struct mutex lock;
> > +	u8 torch_enable_cmd;
> > +	unsigned int peripheral_subtype;
> > +	bool flash_regulator_on;
> > +	bool torch_regulator_on;
> > +	bool torch_enabled;
> > +};
> > +
> > +struct qcom_flash_config {
> > +	unsigned int base;
> > +	struct regulator *flash_supply;
> > +	struct regulator *torch_supply;
> > +	unsigned int num_leds;
> > +
> > +	enum qcom_flash_ids id[2];
> > +	bool default_on[2];
> > +	u32 led_max_brightness[2];
> > +	u32 flash_max_brightness[2];
> > +	u32 flash_max_timeout[2];
> > +};
> > +
> > +static inline struct qcom_flash_led *flcdev_to_led(struct led_classdev_flash *fled_cdev)
> > +{
> > +	return container_of(fled_cdev, struct qcom_flash_led, fled_cdev);
> > +}
> > +
> > +static inline struct qcom_flash_device *led_to_leds_dev(struct qcom_flash_led *led)
> > +{
> > +	return container_of(led, struct qcom_flash_device, leds[led->id]);
> > +}
> > +
> > +static inline int qcom_flash_read_reg(struct qcom_flash_device *leds_dev,
> > +				      unsigned int reg, unsigned int *val)
> > +{
> > +	return regmap_read(leds_dev->regmap, leds_dev->base + reg, val);
> > +}
> > +
> > +static inline int qcom_flash_masked_write(struct qcom_flash_device *leds_dev,
> > +					  unsigned int reg, unsigned int mask,
> > +					  unsigned int val)
> > +{
> > +	return regmap_update_bits(leds_dev->regmap, leds_dev->base + reg, mask,
> > +				  val);
> > +}
> > +
> > +static u8 qcom_flash_duration_to_reg(u32 us)
> > +{
> > +	if (us < QCOM_FLASH_DURATION_MIN)
> > +		us = QCOM_FLASH_DURATION_MIN;
> > +	return (us - QCOM_FLASH_DURATION_MIN) / QCOM_FLASH_DURATION_STEP;
> > +}
> > +
> > +static u8 qcom_flash_current_to_reg(u32 ua)
> > +{
> > +	if (ua < QCOM_FLASH_CURRENT_MIN)
> > +		ua = QCOM_FLASH_CURRENT_MIN;
> > +	return (ua - QCOM_FLASH_CURRENT_MIN) / QCOM_FLASH_CURRENT_STEP;
> > +}
> > +
> > +static void clamp_align(u32 *v, u32 min, u32 max, u32 step)
> > +{
> > +	*v = clamp_val(*v, min, max);
> > +	if (step > 1)
> > +		*v = (*v - min) / step * step + min;
> > +}
> > +
> > +static int qcom_flash_status_get(struct qcom_flash_led *led)
> > +{
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	unsigned int status;
> > +	int rc;
> > +
> > +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_STATUS, &status);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Failure reading status, rc =  %d\n",
> > +			rc);
> > +		return rc;
> > +	}
> > +
> > +	return status & led->mask_led_on;
> > +}
> > +
> > +static int qcom_flash_status_clear(struct qcom_flash_device *leds_dev)
> > +{
> > +	unsigned int enable_val;
> > +	int rc;
> > +
> > +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +				 &enable_val);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Enable reg read failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +				     QCOM_FLASH_ENABLE_MASK, QCOM_FLASH_DISABLE_ALL);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +				     QCOM_FLASH_ENABLE_MASK, enable_val);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> 
> It would be good to have different error messages to discern between
> the two above calls' failures.

Indeed.

> 
> > +		return rc;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_check_timedout(struct qcom_flash_device *leds_dev)
> > +{
> > +	unsigned int status;
> > +	int rc;
> > +
> > +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_STATUS, &status);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Failure reading status, rc =  %d\n",
> > +			rc);
> > +		return rc;
> > +	}
> > +
> > +	return status & QCOM_FLASH_MASK_STATUS_TIMEDOUT;
> > +}
> > +
> > +static int qcom_flash_torch_reg_enable(struct qcom_flash_device *leds_dev,
> > +				       bool state)
> > +{
> > +	int rc;
> > +
> > +	if (leds_dev->torch_enabled == state)
> > +		return 0;
> > +
> > +	/*
> > +	 * For the TORCH register (0xE4) to become writable, the UNLOCK_SECURE
> > +	 * register (0xD0) needs to be written with the UNLOCK_SECURE value
> > +	 * (0xA5) first.
> > +	 * It gets re-locked after any register write.
> > +	 */
> > +	rc = qcom_flash_masked_write(leds_dev,
> > +				     QCOM_FLASH_ADDR_LED_UNLOCK_SECURE,
> > +				     QCOM_FLASH_SECURE_MASK,
> > +				     QCOM_FLASH_UNLOCK_SECURE);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Secure reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_TORCH,
> > +				     QCOM_FLASH_TORCH_MASK,
> > +				     state ? QCOM_FLASH_LED_TORCH_ENABLE :
> > +					     QCOM_FLASH_LED_TORCH_DISABLE);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Torch reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_max_brightness_set(struct qcom_flash_led *led,
> > +					 unsigned int brightness)
> > +{
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	struct device *dev = leds_dev->dev;
> > +	int rc;
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_MAX_CURR,
> > +				     QCOM_FLASH_CURRENT_MASK, brightness);
> > +	if (rc) {
> > +		dev_err(dev, "Max current reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_brightness_set(struct qcom_flash_led *led,
> > +				     unsigned int brightness)
> > +{
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	struct device *dev = leds_dev->dev;
> > +	int rc;
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, led->current_addr,
> > +				     QCOM_FLASH_CURRENT_MASK, brightness);
> > +	if (rc) {
> > +		dev_err(dev, "Current reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_fled_regulator_on(struct qcom_flash_device *leds_dev)
> > +{
> > +	int rc;
> > +
> > +	if (leds_dev->flash_regulator_on)
> > +		return 0;
> > +
> > +	rc = regulator_enable(leds_dev->flash_supply);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Regulator enable failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	leds_dev->flash_regulator_on = true;
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_fled_regulator_off(struct qcom_flash_device *leds_dev)
> > +{
> > +	unsigned int i;
> > +	u8 enable = 0;
> > +	int rc;
> > +
> > +	if (!leds_dev->flash_regulator_on)
> > +		return 0;
> > +
> > +	for (i = 0; i < leds_dev->num_leds; i++) {
> > +		rc = qcom_flash_status_get(&leds_dev->leds[i]);
> > +		if (rc < 0)
> > +			return rc;
> > +
> > +		if (!rc)
> > +			continue;
> > +
> > +		enable |= leds_dev->leds[i].flash_enable_cmd;
> > +	}
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +				     QCOM_FLASH_ENABLE_MASK, enable);
> > +	if (rc)
> > +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> > +
> > +	if (enable)
> > +		return 0;
> > +
> > +	rc = regulator_disable(leds_dev->flash_supply);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Regulator disable failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	leds_dev->flash_regulator_on = false;
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_torch_regulator_on(struct qcom_flash_device *leds_dev)
> > +{
> > +	int rc;
> > +
> > +	if (leds_dev->torch_regulator_on)
> > +		return 0;
> > +
> > +	rc = regulator_enable(leds_dev->torch_supply);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Regulator enable failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	leds_dev->torch_regulator_on = true;
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_torch_regulator_off(struct qcom_flash_device *leds_dev)
> > +{
> > +	int rc;
> > +
> > +	if (!leds_dev->torch_regulator_on)
> > +		return 0;
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +				     QCOM_FLASH_ENABLE_MODULE_MASK,
> > +				     QCOM_FLASH_DISABLE_ALL);
> > +	if (rc)
> > +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> > +
> > +	rc = regulator_disable(leds_dev->torch_supply);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Regulator disable failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	leds_dev->torch_regulator_on = false;
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_fled_on(struct qcom_flash_led *led)
> > +{
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	struct device *dev = leds_dev->dev;
> > +	int rc, error;
> > +
> > +	rc = qcom_flash_fled_regulator_on(leds_dev);
> > +	if (rc)
> > +		goto error_flash_set;
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +				     led->flash_enable_cmd,
> > +				     led->flash_enable_cmd);
> > +	if (rc) {
> > +		dev_err(dev, "Enable reg write failed(%d)\n", rc);
> > +		goto error_flash_set;
> > +	}
> > +
> > +	/*
> > +	 * TODO The downstream driver also allowed HW strobe. Add support for it
> > +	 * after v4l2 support is added and ISP can be used
> > +	 */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> > +				     led->flash_strobe_cmd,
> > +				     led->flash_strobe_cmd);
> > +	if (rc) {
> > +		dev_err(dev, "LED %d strobe reg write failed(%d)\n", led->id,
> > +			rc);
> > +		goto error_flash_set;
> > +	}
> > +
> > +	return 0;
> > +
> > +error_flash_set:
> > +	error = qcom_flash_fled_regulator_off(leds_dev);
> > +	if (error)
> > +		return error;
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_fled_off(struct qcom_flash_led *led)
> > +{
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	struct device *dev = leds_dev->dev;
> > +	int rc, error;
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> > +				     led->flash_strobe_cmd,
> > +				     QCOM_FLASH_DISABLE_ALL);
> > +	if (rc)
> > +		dev_err(dev, "LED %d flash write failed(%d)\n", led->id, rc);
> > +
> > +	error = qcom_flash_fled_regulator_off(leds_dev);
> > +	if (error)
> > +		return error;
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_torch_on(struct qcom_flash_led *led)
> > +{
> > +	int rc, error;
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	struct device *dev = leds_dev->dev;
> > +
> > +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
> > +		rc = qcom_flash_torch_regulator_on(leds_dev);
> > +		if (rc)
> > +			goto error_reg_write;
> > +	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
> > +		rc = qcom_flash_fled_regulator_on(leds_dev);
> 
> Why for torch mode you need to enable fled regulator?

Based on [1], apparently the hardware present in the Single variant of the PMIC
has some limitation that requires the use of the flash regulator and the value
QCOM_FLASH_ENABLE_ALL to enable the LEDs for the torch mode. The Dual variant on
the other hand can just use the torch regulator and enables the LEDs with
QCOM_FLASH_ENABLE_MODULE.

[1] https://github.com/AICP/kernel_lge_hammerhead/commit/0f47c747c074993655d0bfebd045e8ddd228fe4c

I'm honestly not sure what the impact is on using the different regulators and
enable values. I have tested enabling the Dual PMIC with different enable values
and all seemed to work the same, so must be some hardware detail.

I left that Single codepath in the hope that it is useful for devices that have
that variant of the hardware, but I have only actually tested the Dual PMIC,
which is the one present on the Nexus 5.

> 
> > +		if (rc)
> > +			goto error_flash_set;
> > +
> > +		/*
> > +		 * Write 0x80 to MODULE_ENABLE before writing
> > +		 * 0xE0 in order to avoid a hardware bug caused
> > +		 * by register value going from 0x00 to 0xE0.
> > +		 */
> > +		rc = qcom_flash_masked_write(leds_dev,
> > +					     QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +					     QCOM_FLASH_ENABLE_MODULE_MASK,
> > +					     QCOM_FLASH_ENABLE_MODULE);
> > +		if (rc) {
> > +			dev_err(dev, "Enable reg write failed(%d)\n", rc);
> > +			goto error_flash_set;
> > +		}
> > +	}
> > +
> > +	rc = qcom_flash_torch_reg_enable(leds_dev, true);
> > +	if (rc)
> > +		goto error_reg_write;
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +				     QCOM_FLASH_ENABLE_MASK,
> > +				     leds_dev->torch_enable_cmd);
> > +	if (rc) {
> > +		dev_err(dev, "Enable reg write failed(%d)\n", rc);
> > +		goto error_reg_write;
> > +	}
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> > +				     led->flash_strobe_cmd,
> > +				     led->flash_strobe_cmd);
> 
> Just to make sure - the hardware requires strobe cmd to enable torch?

Yes. The strobe value is the one that actually turns each of the LEDs on,
doesn't matter if it's on flash or torch mode. The difference in torch mode is
actually just that the timeout on the LEDs is disabled (done by writing 0x00
into the TORCH, 0xE4, register).
So for both modes, the LEDs are turned on by writing to the STROBE_CTRL, 0x47,
register. If torch is on they'll stay on indefinitely, while on flash mode
they'll turn off after the timeout.

Perhaps it's just a naming issue?

> 
> > +	if (rc) {
> > +		dev_err(dev, "LED %d strobe reg write failed(%d)\n", led->id,
> > +			rc);
> > +		goto error_reg_write;
> > +	}
> > +
> > +	leds_dev->torch_enabled = true;
> > +
> > +	return 0;
> > +
> > +error_reg_write:
> > +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE)
> > +		goto error_flash_set;
> > +
> > +	error = qcom_flash_torch_regulator_off(leds_dev);
> > +	if (error)
> > +		return error;
> > +	return rc;
> > +
> > +error_flash_set:
> > +	error = qcom_flash_fled_regulator_off(leds_dev);
> > +	if (error)
> > +		return error;
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_torch_off(struct qcom_flash_led *led)
> > +{
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	struct device *dev = leds_dev->dev;
> > +	int rc, error;
> > +	unsigned int i;
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> > +				     led->flash_strobe_cmd, QCOM_FLASH_DISABLE_ALL);
> > +	if (rc) {
> > +		dev_err(dev, "LED %d flash write failed(%d)\n", led->id, rc);
> > +		goto error_torch_set;
> > +	}
> > +
> > +	/* Keep torch on if the other LED is still on */
> > +	for (i = 0; i < leds_dev->num_leds; i++)
> > +		if (leds_dev->leds[i].fled_cdev.led_cdev.brightness)
> > +			return 0;
> > +
> > +	rc = qcom_flash_torch_reg_enable(leds_dev, false);
> > +	if (rc)
> > +		goto error_torch_set;
> > +
> > +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
> > +		rc = qcom_flash_torch_regulator_off(leds_dev);
> > +		if (rc)
> > +			return rc;
> > +	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
> > +		rc = qcom_flash_fled_regulator_off(leds_dev);
> > +		if (rc)
> > +			return rc;
> > +	}
> > +
> > +	leds_dev->torch_enabled = false;
> > +
> > +	return 0;
> > +
> > +error_torch_set:
> > +	error = qcom_flash_torch_regulator_off(leds_dev);
> > +	if (error)
> > +		return error;
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_ledcdev_brightness_set(struct led_classdev *led_cdev,
> > +					     enum led_brightness value)
> > +{
> > +	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
> > +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	unsigned int max_brightness;
> > +	int rc;
> > +
> > +	if (value > led_cdev->max_brightness) {
> 
> LED framework takes care of it. You can skip this.

Ok.

> 
> > +		dev_err(leds_dev->dev, "Invalid brightness value\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	mutex_lock(&leds_dev->lock);
> > +	if (!value) {
> > +		rc = qcom_flash_torch_off(led);
> > +	} else {
> > +		/*
> > +		 * The minimum on value for the brightness register is 0, but for
> > +		 * led_classdev is 1, as 0 there means off.
> > +		 */
> > +		rc = qcom_flash_brightness_set(led, led_cdev->brightness - 1);
> > +		if (rc)
> > +			goto unlock;
> > +
> > +		led->flash_current_invalidated = true;
> > +
> > +		if (leds_dev->torch_enabled) {
> > +			/* Clear status to update brightness */
> > +			rc = qcom_flash_status_clear(leds_dev);
> > +			if (rc)
> > +				goto unlock;
> > +		} else {
> > +			/*
> > +			 * Clear status from previous flash strobe so the LED
> > +			 * can turn on
> > +			 */
> > +			rc = qcom_flash_check_timedout(leds_dev);
> > +			if (rc > 0)
> > +				rc = qcom_flash_status_clear(leds_dev);
> > +			else if (rc < 0)
> > +				goto unlock;
> > +
> > +			max_brightness = led_cdev->max_brightness - 1;
> > +			rc = qcom_flash_max_brightness_set(led, max_brightness);
> > +			if (rc)
> > +				goto unlock;
> > +		}
> > +		rc = qcom_flash_torch_on(led);
> > +	}
> > +
> > +unlock:
> > +	mutex_unlock(&leds_dev->lock);
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_flcdev_brightness_set(struct led_classdev_flash *fled_cdev,
> > +					    u32 brightness)
> > +{
> > +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	unsigned int bright;
> > +	int rc;
> > +
> > +	/* Can't operate on flash if torch is on */
> > +	if (leds_dev->torch_enabled)
> > +		return -EBUSY;
> > +
> > +	clamp_align(&brightness, QCOM_FLASH_CURRENT_MIN,
> > +		    fled_cdev->brightness.max, QCOM_FLASH_CURRENT_STEP);
> > +	fled_cdev->brightness.val = brightness;
> > +
> > +	bright = qcom_flash_current_to_reg(brightness);
> > +
> > +	mutex_lock(&leds_dev->lock);
> > +	rc = qcom_flash_brightness_set(led, bright);
> > +	if (rc)
> > +		goto unlock;
> > +
> > +	if (led->flash_current_invalidated) {
> > +		bright = qcom_flash_current_to_reg(fled_cdev->brightness.max);
> > +		rc = qcom_flash_max_brightness_set(led, bright);
> > +		if (rc)
> > +			goto unlock;
> > +	}
> > +
> > +	led->flash_current_invalidated = false;
> > +
> > +unlock:
> > +	mutex_unlock(&leds_dev->lock);
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_flcdev_strobe_set(struct led_classdev_flash *fled_cdev,
> > +					bool state)
> > +{
> > +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	unsigned int bright;
> > +	unsigned int i;
> > +	int rc;
> > +
> > +	/* Can't operate on flash if torch is on */
> > +	if (leds_dev->torch_enabled)
> > +		return -EBUSY;
> > +
> > +	mutex_lock(&leds_dev->lock);
> > +	if (!state) {
> > +		rc = qcom_flash_fled_off(led);
> > +	} else {
> > +		/*
> > +		 * Turn off flash LEDs from previous strobe
> > +		 */
> > +		rc = qcom_flash_check_timedout(leds_dev);
> > +		if (rc > 0) {
> > +			for (i = 0; i < leds_dev->num_leds; i++) {
> > +				rc = qcom_flash_fled_off(&leds_dev->leds[i]);
> > +				if (rc)
> > +					goto unlock;
> > +			}
> > +		} else if (rc < 0) {
> > +			goto unlock;
> > +		}
> 
> What if flash gets timed out after this check here? Why do you need to
> call qcom_flash_fled_off() if it has already timed out?

The issue is that after the flash times out, the hardware is not ready for
another strobe.

When I strobe LED0 for example, the STATUS register, 0x10, gets set to 0x08
indicating the LED0 is on. After the timeout, it changes to 0x04. At that point
if I try to strobe LED0 again, it doesn't work. When I turn the LED0 off (write
0x00 to either the ENABLE or STROBE register), the STATUS is reset to 0x00. Now
I'm able to strobe the LED0 again.

I'm not sure if this is the normal behavior on other flash LED controllers, and
maybe there's even some configuration of this PMIC that resets the LED status
automatically after the strobe timeout, but I have not been able to do that. So
that's why I reset the status manually everytime it's needed.

> 
> > +		if (led->flash_current_invalidated) {
> > +			bright = qcom_flash_current_to_reg(fled_cdev->brightness.val);
> > +			rc = qcom_flash_brightness_set(led, bright);
> > +			if (rc)
> > +				goto unlock;
> > +
> > +			bright = qcom_flash_current_to_reg(fled_cdev->brightness.max);
> > +			rc = qcom_flash_max_brightness_set(led, bright);
> > +			if (rc)
> > +				goto unlock;
> > +
> > +			led->flash_current_invalidated = false;
> > +		}
> > +
> > +		rc = qcom_flash_fled_on(led);
> > +	}
> > +
> > +unlock:
> > +	mutex_unlock(&leds_dev->lock);
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_flcdev_strobe_get(struct led_classdev_flash *fled_cdev,
> > +					bool *state)
> > +{
> > +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	int status;
> > +
> > +	mutex_lock(&leds_dev->lock);
> > +	status = qcom_flash_status_get(led);
> > +	mutex_unlock(&leds_dev->lock);
> > +	if (status < 0)
> > +		return status;
> > +
> > +	*state = status && !leds_dev->torch_enabled;
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_flcdev_timeout_set(struct led_classdev_flash *fled_cdev,
> > +					 u32 timeout)
> > +{
> > +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	unsigned int time, i;
> > +	int rc;
> > +
> > +	clamp_align(&timeout, QCOM_FLASH_DURATION_MIN, fled_cdev->timeout.max,
> > +		    QCOM_FLASH_DURATION_STEP);
> > +
> > +	/* Since the timeout register is shared between LEDs, update for all */
> > +	for (i = 0; i < leds_dev->num_leds; i++)
> > +		leds_dev->leds[i].fled_cdev.timeout.val = timeout;
> > +
> > +	time = qcom_flash_duration_to_reg(fled_cdev->timeout.val);
> > +
> > +	mutex_lock(&leds_dev->lock);
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_SAFETY_TIMER,
> > +				     QCOM_FLASH_SAFETY_TIMER_MASK, time);
> > +	if (rc)
> > +		dev_err(leds_dev->dev, "Safety timer reg write failed(%d)\n",
> > +			rc);
> > +	mutex_unlock(&leds_dev->lock);
> > +
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_flcdev_fault_get(struct led_classdev_flash *fled_cdev,
> > +				       u32 *fault)
> > +{
> > +	/*
> > +	 * TODO Add fault detection when we find out how to. No clue from
> > +	 * inspecting the SPMI registers
> > +	 */
> > +	*fault = 0;
> > +	return 0;
> > +}
> > +
> > +static const struct led_flash_ops flash_ops = {
> > +	.flash_brightness_set	= qcom_flash_flcdev_brightness_set,
> > +	.strobe_set		= qcom_flash_flcdev_strobe_set,
> > +	.strobe_get		= qcom_flash_flcdev_strobe_get,
> > +	.timeout_set		= qcom_flash_flcdev_timeout_set,
> > +	.fault_get		= qcom_flash_flcdev_fault_get,
> > +};
> > +
> > +static int qcom_flash_setup_flcdev(struct qcom_flash_config *cfg,
> > +				   struct qcom_flash_led *led,
> > +				   struct device_node *node)
> > +{
> > +	int rc;
> > +	struct device *dev = led_to_leds_dev(led)->dev;
> > +	struct led_classdev_flash *fled_cdev = &led->fled_cdev;
> > +	struct led_classdev *led_cdev = &fled_cdev->led_cdev;
> > +	struct led_init_data init_data = {};
> > +	struct led_flash_setting *setting;
> > +
> > +	init_data.fwnode = of_fwnode_handle(node);
> > +
> > +	led_cdev->brightness_set_blocking = qcom_flash_ledcdev_brightness_set;
> > +
> > +	led_cdev->max_brightness = cfg->led_max_brightness[led->id];
> > +	led_cdev->max_brightness /= QCOM_FLASH_CURRENT_STEP;
> 
> Just assign the result of division:
> 
> led_cdev->max_brightness = cfg->led_max_brightness[led->id] /
>                            QCOM_FLASH_CURRENT_STEP;
> 
> Two consecutive assignments look a bit convoluted.

Sure.

> 
> > +
> > +	setting = &fled_cdev->brightness;
> > +	setting->max = cfg->flash_max_brightness[led->id];
> > +	setting->min = QCOM_FLASH_CURRENT_MIN;
> > +	setting->step = QCOM_FLASH_CURRENT_STEP;
> > +	setting->val = setting->min;
> > +
> > +	setting = &fled_cdev->timeout;
> > +	setting->max = cfg->flash_max_timeout[led->id];
> > +	setting->min = QCOM_FLASH_DURATION_MIN;
> > +	setting->step = QCOM_FLASH_DURATION_STEP;
> > +	setting->val = QCOM_FLASH_DURATION_DEFAULT;
> > +
> > +	fled_cdev->ops = &flash_ops;
> > +	led_cdev->flags |= LED_DEV_CAP_FLASH;
> > +
> > +	rc = devm_led_classdev_flash_register_ext(dev, fled_cdev, &init_data);
> > +	if (rc)
> > +		dev_err(dev, "unable to register led %d,rc=%d\n", led->id, rc);
> > +
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_setup_fled(struct qcom_flash_config *cfg,
> > +				 struct qcom_flash_led *led,
> > +				 enum qcom_flash_ids id)
> > +{
> > +	led->id = cfg->id[id];
> > +	led->default_on = cfg->default_on[id];
> > +	led->flash_current_invalidated = true;
> > +
> > +	if (led->id == QCOM_FLASH_ID_LED0) {
> > +		led->flash_enable_cmd = QCOM_FLASH_ENABLE_LED0;
> > +		led->flash_strobe_cmd = QCOM_FLASH_STROBE_LED0;
> > +		led->current_addr = QCOM_FLASH_ADDR_CURR_LED0;
> > +		led->mask_led_on = QCOM_FLASH_MASK_ON_LED0;
> > +	} else {
> > +		led->flash_enable_cmd = QCOM_FLASH_ENABLE_LED1;
> > +		led->flash_strobe_cmd = QCOM_FLASH_STROBE_LED1;
> > +		led->current_addr = QCOM_FLASH_ADDR_CURR_LED1;
> > +		led->mask_led_on = QCOM_FLASH_MASK_ON_LED1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_setup_regs(struct qcom_flash_device *leds_dev)
> > +{
> > +	int rc;
> > +
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> > +				     QCOM_FLASH_STROBE_MASK,
> > +				     QCOM_FLASH_DISABLE_ALL);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "LED flash write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Disable flash LED module */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> > +				     QCOM_FLASH_ENABLE_MASK,
> > +				     QCOM_FLASH_DISABLE_ALL);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Set Vreg force */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_VREG_OK_FORCE,
> > +				     QCOM_FLASH_VREG_MASK,
> > +				     QCOM_FLASH_HW_VREG_OK);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Vreg OK reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Set self fault check */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_FAULT_DETECT,
> > +				     QCOM_FLASH_FAULT_DETECT_MASK,
> > +				     QCOM_FLASH_SELFCHECK_DISABLE);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Fault detect reg write failed(%d)\n",
> > +			rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Set mask enable */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_MASK_ENABLE,
> > +				     QCOM_FLASH_MASK_REG_MASK,
> > +				     QCOM_FLASH_MASK_1);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Mask enable reg write failed(%d)\n",
> > +			rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Set ramp rate */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_RAMP_RATE,
> > +				     QCOM_FLASH_RAMP_RATE_MASK, 0xBF);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Ramp rate reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Enable VPH_PWR_DROOP and set threshold to 2.9V */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_VPH_PWR_DROOP,
> > +				     QCOM_FLASH_VPH_PWR_DROOP_MASK, 0xC2);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "VPH_PWR_DROOP reg write failed(%d)\n",
> > +			rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Set headroom */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_HEADROOM,
> > +				     QCOM_FLASH_HEADROOM_MASK,
> > +				     QCOM_FLASH_HEADROOM_500MV);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Headroom reg write failed(%d)\n", rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Set startup delay */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_STARTUP_DELAY,
> > +				     QCOM_FLASH_STARTUP_DLY_MASK,
> > +				     QCOM_FLASH_STARTUP_DLY_10US);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "Startup delay reg write failed(%d)\n",
> > +			rc);
> > +		return rc;
> > +	}
> > +
> > +	/*
> > +	 * TODO The downstream driver also supported watchdog mode. Not sure
> > +	 * about the difference, so only support safety timer for now
> > +	 */
> > +	/* Set timer control */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_TMR_CTRL,
> > +				     QCOM_FLASH_TMR_MASK,
> > +				     QCOM_FLASH_TMR_SAFETY);
> > +	if (rc) {
> > +		dev_err(leds_dev->dev, "LED timer ctrl reg write failed(%d)\n",
> > +			rc);
> > +		return rc;
> > +	}
> > +
> > +	/* Set clamp current */
> > +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_CLAMP_CURR,
> > +				     QCOM_FLASH_CURRENT_MASK,
> > +				     qcom_flash_current_to_reg(QCOM_FLASH_DEFAULT_CLAMP));
> > +	if (rc)
> > +		dev_err(leds_dev->dev, "Clamp current reg write failed(%d)\n",
> > +			rc);
> > +
> > +	return rc;
> > +}
> > +
> > +static int qcom_flash_setup_led(struct qcom_flash_config *cfg,
> > +				struct qcom_flash_led *led,
> > +				enum qcom_flash_ids id,
> > +				struct device_node *node)
> > +{
> > +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> > +	struct led_classdev *led_cdev = &led->fled_cdev.led_cdev;
> > +	int rc;
> > +
> > +	rc = qcom_flash_setup_fled(cfg, led, id);
> > +	if (rc)
> > +		return rc;
> > +
> > +	rc = qcom_flash_setup_flcdev(cfg, led, node);
> > +	if (rc)
> > +		return rc;
> > +
> > +	/* configure default state */
> > +	if (!led->default_on) {
> > +		led_cdev->brightness = LED_OFF;
> > +	} else {
> > +		led_cdev->brightness = led_cdev->max_brightness;
> > +		mutex_lock(&leds_dev->lock);
> > +		rc = qcom_flash_torch_on(led);
> > +		mutex_unlock(&leds_dev->lock);
> > +		if (rc)
> > +			return rc;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_setup_leds_device(struct qcom_flash_device *leds_dev,
> > +					struct qcom_flash_config *cfg,
> > +					struct device *dev)
> > +{
> > +	int rc;
> > +
> > +	leds_dev->dev = dev;
> > +
> > +	leds_dev->base = cfg->base;
> > +	leds_dev->num_leds = cfg->num_leds;
> > +
> > +	leds_dev->regmap = dev_get_regmap(dev->parent, NULL);
> > +	if (!leds_dev->regmap) {
> > +		dev_err(dev, "Failure getting regmap\n");
> > +		return -ENODEV;
> > +	}
> > +
> > +	rc = qcom_flash_setup_regs(leds_dev);
> > +	if (rc)
> > +		return rc;
> > +
> > +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE,
> > +				 &leds_dev->peripheral_subtype);
> > +	if (rc) {
> > +		dev_err(dev, "Unable to read from addr=%x, rc(%d)\n",
> > +			QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE, rc);
> > +		return rc;
> > +	}
> > +
> > +	leds_dev->flash_supply = cfg->flash_supply;
> > +
> > +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
> > +		leds_dev->torch_supply = cfg->torch_supply;
> > +		leds_dev->torch_enable_cmd = QCOM_FLASH_ENABLE_MODULE;
> > +	} else {
> > +		leds_dev->torch_enable_cmd = QCOM_FLASH_ENABLE_ALL;
> > +	}
> > +
> > +	mutex_init(&leds_dev->lock);
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_parse_dt(struct device *dev,
> > +			       struct qcom_flash_config *cfg,
> > +			       struct device_node *sub_nodes[])
> > +{
> > +	struct device_node *node = dev->of_node;
> > +	struct device_node *child_node;
> > +	const char *temp_string;
> > +	int rc, parsed_leds = 0;
> > +	u32 val;
> > +
> > +	rc = of_property_read_u32(node, "reg", &val);
> > +	if (rc < 0) {
> > +		dev_err(dev, "Failure reading reg, rc = %d\n", rc);
> > +		return rc;
> > +	}
> > +	cfg->base = val;
> > +
> > +	cfg->flash_supply = devm_regulator_get(dev, "flash-boost");
> > +	cfg->torch_supply = devm_regulator_get(dev, "torch-boost");
> > +
> > +	for_each_available_child_of_node(node, child_node) {
> > +		/* LED properties */
> > +
> > +		rc = of_property_read_u32(child_node, "reg",
> > +					  &cfg->id[parsed_leds]);
> > +		if (rc) {
> > +			dev_err(dev, "Failure reading led id, rc =  %d\n", rc);
> > +			of_node_put(child_node);
> > +			return rc;
> > +		}
> > +
> > +		/* Assume LED IDs are ordered in DT for simplicity */
> 
> You need to mention this requirement in DT bindings, but I am not sure
> if DT child nodes parsing order is guaranteed to be top-down.

Ok, I'll take a look at the documentation for the DT bindings if there's any
clue on that, and check what other drivers normally do. I did that just because
it's simpler, but I guess I could use a linked list for the nodes instead of an
array, or maybe even simpler, have an array for the LED IDs read, so we can
remove this restriction.

Thanks,
N?colas

> 
> > +		if (cfg->id[parsed_leds] != parsed_leds) {
> > +			dev_err(dev, "Unordered LED nodes in DT\n");
> > +			of_node_put(child_node);
> > +			return -EINVAL;
> > +		}
> > +
> > +		sub_nodes[parsed_leds] = child_node;
> > +
> > +		rc = of_property_read_string(child_node, "default-state",
> > +					     &temp_string);
> > +		if (!rc) {
> > +			if (strncmp(temp_string, "on", sizeof("on")) == 0)
> > +				cfg->default_on[parsed_leds] = true;
> > +		} else if (rc != -EINVAL) {
> > +			dev_err(dev,
> > +				"Failure reading default-state, rc =  %d\n",
> > +				rc);
> > +			of_node_put(child_node);
> > +			return rc;
> > +		}
> > +
> > +		/* FLED properties */
> > +
> > +		rc = of_property_read_u32(child_node, "led-max-microamp",
> > +					  &cfg->led_max_brightness[parsed_leds]);
> > +		if (rc < 0) {
> > +			dev_err(dev, "Failure reading max_current, rc =  %d\n",
> > +				rc);
> > +			of_node_put(child_node);
> > +			return rc;
> > +		}
> > +
> > +		rc = of_property_read_u32(child_node, "flash-max-microamp",
> > +					  &cfg->flash_max_brightness[parsed_leds]);
> > +		if (rc < 0) {
> > +			dev_err(dev, "Failure reading max_current, rc =  %d\n",
> > +				rc);
> > +			of_node_put(child_node);
> > +			return rc;
> > +		}
> > +
> > +		rc = of_property_read_u32(child_node, "flash-max-timeout-us",
> > +					  &cfg->flash_max_timeout[parsed_leds]);
> > +		if (rc < 0) {
> > +			dev_err(dev, "Failure reading max_timeout, rc =  %d\n",
> > +				rc);
> > +			of_node_put(child_node);
> > +			return rc;
> > +		}
> > +
> > +		parsed_leds++;
> > +		if (parsed_leds >= 2) {
> > +			of_node_put(child_node);
> > +			break;
> > +		}
> > +	}
> > +	cfg->num_leds = parsed_leds;
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct qcom_flash_device *leds_dev;
> > +	struct qcom_flash_config cfg = { 0 };
> > +	struct device_node *sub_nodes[2];
> > +	unsigned int i;
> > +	int rc;
> > +
> > +	leds_dev = devm_kzalloc(dev, sizeof(*leds_dev), GFP_KERNEL);
> > +	if (!leds_dev)
> > +		return -ENOMEM;
> > +
> > +	rc = qcom_flash_parse_dt(dev, &cfg, sub_nodes);
> > +	if (rc)
> > +		return rc;
> > +
> > +	rc = qcom_flash_setup_leds_device(leds_dev, &cfg, dev);
> > +	if (rc)
> > +		return rc;
> > +
> > +	for (i = 0; i < leds_dev->num_leds; i++) {
> > +		rc = qcom_flash_setup_led(&cfg, &leds_dev->leds[i], i,
> > +					  sub_nodes[i]);
> > +		if (rc)
> > +			return rc;
> > +	}
> > +
> > +	platform_set_drvdata(pdev, leds_dev);
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_flash_remove(struct platform_device *pdev)
> > +{
> > +	struct qcom_flash_device *leds_dev = platform_get_drvdata(pdev);
> > +
> > +	mutex_destroy(&leds_dev->lock);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id qcom_flash_spmi_of_match[] = {
> > +	{ .compatible = "qcom,spmi-flash-leds" },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, qcom_flash_spmi_of_match);
> > +
> > +static struct platform_driver qcom_flash_driver = {
> > +	.driver		= {
> > +		.name	= "qcom,spmi-flash-leds",
> > +		.of_match_table = qcom_flash_spmi_of_match,
> > +	},
> > +	.probe		= qcom_flash_probe,
> > +	.remove		= qcom_flash_remove,
> > +};
> > +module_platform_driver(qcom_flash_driver);
> > +
> > +MODULE_DESCRIPTION("Qualcomm SPMI Flash LED driver");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_AUTHOR("N?colas F. R. A. Prado <n at nfraprado.net>");
> > 
> 
> -- 
> Best regards,
> Jacek Anaszewski


From robh at kernel.org  Tue Aug 24 14:58:27 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 16:58:27 -0500
Subject: [PATCH v9 2/3] arm64: perf: Enable PMU counter userspace access
 for perf event
In-Reply-To: <20210824152720.GC23146@willie-the-truck>
References: <20210806225123.1958497-1-robh@kernel.org>
 <20210806225123.1958497-3-robh@kernel.org>
 <20210824152720.GC23146@willie-the-truck>
Message-ID: <CAL_Jsq+HY8o=DPf0Yhbjhu1=_yBwoV7rBL7gK2MJCpezwi7vwQ@mail.gmail.com>

On Tue, Aug 24, 2021 at 10:27 AM Will Deacon <will at kernel.org> wrote:
>
> On Fri, Aug 06, 2021 at 04:51:22PM -0600, Rob Herring wrote:
> > Arm PMUs can support direct userspace access of counters which allows for
> > low overhead (i.e. no syscall) self-monitoring of tasks. The same feature
> > exists on x86 called 'rdpmc'. Unlike x86, userspace access will only be
> > enabled for thread bound events. This could be extended if needed, but
> > simplifies the implementation and reduces the chances for any
> > information leaks (which the x86 implementation suffers from).
> >
> > When an event is capable of userspace access and has been mmapped, userspace
> > access is enabled when the event is scheduled on a CPU's PMU. There's some
> > additional overhead clearing counters when disabled in order to prevent
> > leaking disabled counter data from other tasks.
> >
> > Unlike x86, enabling of userspace access must be requested with a new
> > attr bit: config1:1. If the user requests userspace access and 64-bit
> > counters, then chaining will be disabled and the user will get the
> > maximum size counter the underlying h/w can support. The modes for
> > config1 are as follows:
> >
> > config1 = 0 : user access disabled and always 32-bit
> > config1 = 1 : user access disabled and always 64-bit (using chaining if needed)
> > config1 = 2 : user access enabled and always 32-bit
> > config1 = 3 : user access enabled and counter size matches underlying counter.
> >
> > Based on work by Raphael Gault <raphael.gault at arm.com>, but has been
> > completely re-written.
> >
> > Cc: Will Deacon <will at kernel.org>
> > Cc: Mark Rutland <mark.rutland at arm.com>
> > Cc: Peter Zijlstra <peterz at infradead.org>
> > Cc: Ingo Molnar <mingo at redhat.com>
> > Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> > Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
> > Cc: Jiri Olsa <jolsa at redhat.com>
> > Cc: Namhyung Kim <namhyung at kernel.org>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: linux-arm-kernel at lists.infradead.org
> > Cc: linux-perf-users at vger.kernel.org
> > Signed-off-by: Rob Herring <robh at kernel.org>
> >
> > ---
> > v9:
> >  - Enabling/disabling of user access is now controlled in .start() and
> >    mmap hooks which are now called on CPUs that the event is on.
> >    Depends on rework of perf core and x86 RDPMC code posted here:
> >    https://lore.kernel.org/lkml/20210728230230.1911468-1-robh at kernel.org/
> >
> > v8:
> >  - Rework user access tracking and enabling to be done on task
> >    context changes using sched_task() hook. This avoids the need for any
> >    IPIs, mm_switch hooks or undef instr handler.
> >  - Only support user access when explicitly requested on open and
> >    only for a thread bound events. This avoids some of the information
> >    leaks x86 has and simplifies the implementation.
> >
> > v7:
> >  - Clear disabled counters when user access is enabled for a task to
> >    avoid leaking other tasks counter data.
> >  - Rework context switch handling utilizing sched_task callback
> >  - Add armv8pmu_event_can_chain() helper
> >  - Rework config1 flags handling structure
> >  - Use ARMV8_IDX_CYCLE_COUNTER_USER define for remapped user cycle
> >    counter index
> >
> > v6:
> >  - Add new attr.config1 rdpmc bit for userspace to hint it wants
> >    userspace access when also requesting 64-bit counters.
> >
> > v5:
> >  - Only set cap_user_rdpmc if event is on current cpu
> >  - Limit enabling/disabling access to CPUs associated with the PMU
> >    (supported_cpus) and with the mm_struct matching current->active_mm.
> >
> > v2:
> >  - Move mapped/unmapped into arm64 code. Fixes arm32.
> >  - Rebase on cap_user_time_short changes
> >
> > Changes from Raphael's v4:
> >   - Drop homogeneous check
> >   - Disable access for chained counters
> >   - Set pmc_width in user page
> > ---
> >  arch/arm64/kernel/perf_event.c | 137 +++++++++++++++++++++++++++++++--
> >  include/linux/perf/arm_pmu.h   |   6 ++
> >  2 files changed, 135 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > index 74f77b68f5f0..66d8bf62e99c 100644
> > --- a/arch/arm64/kernel/perf_event.c
> > +++ b/arch/arm64/kernel/perf_event.c
> > @@ -285,6 +285,7 @@ static const struct attribute_group armv8_pmuv3_events_attr_group = {
> >
> >  PMU_FORMAT_ATTR(event, "config:0-15");
> >  PMU_FORMAT_ATTR(long, "config1:0");
> > +PMU_FORMAT_ATTR(rdpmc, "config1:1");
> >
> >  static int sysctl_perf_user_access __read_mostly;
> >
> > @@ -306,9 +307,15 @@ static inline bool armv8pmu_event_is_64bit(struct perf_event *event)
> >       return event->attr.config1 & 0x1;
> >  }
> >
> > +static inline bool armv8pmu_event_want_user_access(struct perf_event *event)
> > +{
> > +     return event->attr.config1 & 0x2;
> > +}
> > +
> >  static struct attribute *armv8_pmuv3_format_attrs[] = {
> >       &format_attr_event.attr,
> >       &format_attr_long.attr,
> > +     &format_attr_rdpmc.attr,
> >       NULL,
> >  };
> >
> > @@ -377,7 +384,7 @@ static const struct attribute_group armv8_pmuv3_caps_attr_group = {
> >   */
> >  #define      ARMV8_IDX_CYCLE_COUNTER 0
> >  #define      ARMV8_IDX_COUNTER0      1
> > -
> > +#define      ARMV8_IDX_CYCLE_COUNTER_USER    32
> >
> >  /*
> >   * We unconditionally enable ARMv8.5-PMU long event counter support
> > @@ -389,6 +396,15 @@ static bool armv8pmu_has_long_event(struct arm_pmu *cpu_pmu)
> >       return (cpu_pmu->pmuver >= ID_AA64DFR0_PMUVER_8_5);
> >  }
> >
> > +static inline bool armv8pmu_event_can_chain(struct perf_event *event)
> > +{
> > +     struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
> > +
> > +     return !(event->hw.flags & PERF_EVENT_FLAG_USER_READ_CNT) &&
> > +            armv8pmu_event_is_64bit(event) &&
> > +            !armv8pmu_has_long_event(cpu_pmu);
>
> Could check against ARMV8_IDX_CYCLE_COUNTER here...
>
> > +}
> > +
> >  /*
> >   * We must chain two programmable counters for 64 bit events,
> >   * except when we have allocated the 64bit cycle counter (for CPU
> > @@ -398,11 +414,9 @@ static bool armv8pmu_has_long_event(struct arm_pmu *cpu_pmu)
> >  static inline bool armv8pmu_event_is_chained(struct perf_event *event)
> >  {
> >       int idx = event->hw.idx;
> > -     struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
> >
> >       return !WARN_ON(idx < 0) &&
> > -            armv8pmu_event_is_64bit(event) &&
> > -            !armv8pmu_has_long_event(cpu_pmu) &&
> > +            armv8pmu_event_can_chain(event) &&
> >              (idx != ARMV8_IDX_CYCLE_COUNTER);
>
> ... then we wouldn't need to here.

Hum, well armv8pmu_event_can_chain() is supposed to answer is there
any possibility that the event will ever be chained regardless of
whether it's assigned or not. Changing it would mostly work for idx<0,
but it could return the wrong answer if idx ==
ARMV8_IDX_CYCLE_COUNTER. However, that won't happen in the current
code (just as the WARN_ON won't). If we're going to smear the meaning,
then we only need one function here if we get rid of the WARN_ON. We
can call it armv8pmu_event_is_chained_or_might_be_chained() to make it
clear... JK (on the name)

>
> >  }
> >
> > @@ -733,6 +747,35 @@ static inline u32 armv8pmu_getreset_flags(void)
> >       return value;
> >  }
> >
> > +static void armv8pmu_disable_user_access(void)
> > +{
> > +     write_sysreg(0, pmuserenr_el0);
> > +}
> > +
> > +static void armv8pmu_enable_user_access(struct arm_pmu *cpu_pmu)
> > +{
> > +     struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
> > +
> > +     if (!sysctl_perf_user_access)
> > +             return;
> > +
> > +     if (!bitmap_empty(cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS)) {
> > +             int i;
> > +             /* Don't need to clear assigned counters. */
> > +             bitmap_xor(cpuc->dirty_mask, cpuc->dirty_mask, cpuc->used_mask, ARMPMU_MAX_HWEVENTS);
> > +
> > +             for_each_set_bit(i, cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS) {
> > +                     if (i == ARMV8_IDX_CYCLE_COUNTER)
> > +                             write_sysreg(0, pmccntr_el0);
> > +                     else
> > +                             armv8pmu_write_evcntr(i, 0);
> > +             }
>
> Given that we can't expose individual counters, why isn't this just:
>
>         for_each_clear_bit(i, cpuc->used_mask, ARMPMU_MAX_HWEVENTS)
>                 ...
>
> and we could get rid of the dirty_mask altogether? i.e. just zero everything
> that isn't assigned.

Sure. It's just an optimization following what x86 did.

Though we'd want to limit it to num_events, not ARMPMU_MAX_HWEVENTS.
No point in clearing nonexistent counters.

>
> > +             bitmap_zero(cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS);
> > +     }
> > +
> > +     write_sysreg(ARMV8_PMU_USERENR_ER | ARMV8_PMU_USERENR_CR, pmuserenr_el0);
> > +}
> > +
> >  static void armv8pmu_enable_event(struct perf_event *event)
> >  {
> >       /*
> > @@ -776,6 +819,16 @@ static void armv8pmu_disable_event(struct perf_event *event)
> >
> >  static void armv8pmu_start(struct arm_pmu *cpu_pmu)
> >  {
> > +     if (sysctl_perf_user_access) {
>
> armv8pmu_enable_user_access() already checks this.

Yes, because not all callers (event_mapped) check it. I put it here so
we check it first and avoid checking all the subsequent conditions
when the feature is disabled. Though I guess the ordering here is not
guaranteed.

> > +             struct perf_cpu_context *cpuctx = this_cpu_ptr(cpu_pmu->pmu.pmu_cpu_context);
> > +             struct perf_event_context *task_ctx = cpuctx->task_ctx;
> > +             if (atomic_read(&cpuctx->ctx.nr_user) ||
>
> I thought we only enabled this for per-task events, so not sure why we need
> this check. But actually, I don't get why we need any extra logic in this
> function at all; why aren't the ->mapped/->unmapped functions sufficient?

Yes, checking cpuctx->ctx.nr_user can be dropped. I went back and
forth on this as this is now the only thing we have to do to allow per
cpu events. IOW, not supporting per cpu events doesn't simplify things
with this version. The main reason now is one less thing exposed to
user space, and user space reading of per cpu events is somewhat
pointless IMO.

The ->mapped/->unmapped functions are only called when we mmap/munmap
the event. In addition to enabling/disabling access at that point, we
need to enable/disable access every time the event's context is
scheduled on or off the PMU. This is replacing doing it in switch_mm()
which you didn't like. The sched_task() hook didn't work either as it
is not called at the right times. That could be fixed in the core as
that's what I did in v8, but doing it in enable() turns out to be
simpler.

Rob


From robh at kernel.org  Tue Aug 24 15:43:48 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 24 Aug 2021 17:43:48 -0500
Subject: [PATCH v5 0/9] Add generic support for kdump DT properties
In-Reply-To: <CAMuHMdVNi4bh0Kp43BrVVKD8YY5ac4yi9=W3QZmw=stmwwtuiQ@mail.gmail.com>
References: <cover.1628670468.git.geert+renesas@glider.be>
 <YRkxzx/1XM3r64Ee@robh.at.kernel.org>
 <CAMuHMdXs0+7K4N0mg6qX6X1cr_8dBr_HdTahdfORMk76wCJcEA@mail.gmail.com>
 <CAL_JsqK63hoEMafLP+5eeQR1qrhOO76J4KEQG_By6QnLfhF=dw@mail.gmail.com>
 <CAMuHMdVNi4bh0Kp43BrVVKD8YY5ac4yi9=W3QZmw=stmwwtuiQ@mail.gmail.com>
Message-ID: <CAL_JsqL_D85DWrbOEghNqbqdMaCabSJ5X7zKKJjn2uoB7=XN6g@mail.gmail.com>

On Tue, Aug 24, 2021 at 6:55 AM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> On Mon, Aug 23, 2021 at 4:52 PM Rob Herring <robh at kernel.org> wrote:
> > On Mon, Aug 23, 2021 at 5:13 AM Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> > > On Sun, Aug 15, 2021 at 5:25 PM Rob Herring <robh at kernel.org> wrote:
> > > > On Wed, Aug 11, 2021 at 10:50:58AM +0200, Geert Uytterhoeven wrote:
> > > > > This patch series adds generic support for parsing DT properties related
> > > > > to crash dump kernels ("linux,elfcorehdr" and "linux,elfcorehdr" under
> > > > > the "/chosen" node), makes use of it on arm32, and performs a few
> > > > > cleanups.  It is an evolution of the combination of [1] and [2].
> > > >
> > > > The DT bits look fine to me. How do you expect this to be merged? I'm
> > > > happy to take it if arch maintainers can ack it.
> > >
> > > I had hoped you could take the series...
> >
> > My current thought is I'll take 2-5, 7 and 8 given that's what I have
> > acks for and the others can be applied independently.
>
> Note that Palmer did ack patch 6, so you can include it.

Right, but Palmer should have taken it if it's for 5.14.

Anyways, I've now applied patches 2-8. If we want to improve the
handling over what arm64 code did as discussed, I think that's a
separate patch anyways.

Rob


From kuba at kernel.org  Tue Aug 24 16:53:29 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 24 Aug 2021 16:53:29 -0700
Subject: [PATCH net] net: phy: mediatek: add the missing suspend/resume
 callbacks
In-Reply-To: <YSOb2P43svWca9IJ@lunn.ch>
References: <20210823044422.164184-1-dqfext@gmail.com>
 <YSOb2P43svWca9IJ@lunn.ch>
Message-ID: <20210824165329.7318588d@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Mon, 23 Aug 2021 15:00:08 +0200 Andrew Lunn wrote:
> On Mon, Aug 23, 2021 at 12:44:21PM +0800, DENG Qingfang wrote:
> > Without suspend/resume callbacks, the PHY cannot be powered down/up
> > administratively.
> > 
> > Fixes: e40d2cca0189 ("net: phy: add MediaTek Gigabit Ethernet PHY driver")
> > Signed-off-by: DENG Qingfang <dqfext at gmail.com>  
> 
> Reviewed-by: Andrew Lunn <andrew at lunn.ch>

Applied, thanks!


From hayashi.kunihiko at socionext.com  Tue Aug 24 17:01:08 2021
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Wed, 25 Aug 2021 09:01:08 +0900
Subject: [PATCH] PCI: uniphier: Serialize INTx masking/unmasking
In-Reply-To: <87zgt8p09n.wl-maz@kernel.org>
References: <1629717500-19396-1-git-send-email-hayashi.kunihiko@socionext.com>
 <20210823150927.jhobzfxy6e4s663r@pali> <87zgt8p09n.wl-maz@kernel.org>
Message-ID: <f4d13190-facf-55ca-58c5-cd0d68e377d7@socionext.com>

Hi Marc,

On 2021/08/24 1:57, Marc Zyngier wrote:
> On Mon, 23 Aug 2021 16:09:27 +0100,
> Pali Roh?r <pali at kernel.org> wrote:
>>
>> + Marc (who originally reported this issue)
>>
>> On Monday 23 August 2021 20:18:20 Kunihiko Hayashi wrote:
>>> The condition register PCI_RCV_INTX is used in irq_mask(), irq_unmask()
>>> and irq_ack() callbacks. Accesses to register can occur at the same time
>>> without a lock.
>>> Add a lock into each callback to prevent the issue.
>>>
>>> Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
>>> Suggested-by: Pali Roh?r <pali at kernel.org>
>>> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
>>
>> Acked-by: Pali Roh?r <pali at kernel.org>
>>
>>> ---
>>>   drivers/pci/controller/dwc/pcie-uniphier.c | 15 +++++++++++++++
>>>   1 file changed, 15 insertions(+)
>>>
>>> The previous patch is as follows:
>>> https://lore.kernel.org/linux-pci/1629370566-29984-1-git-send-email-hayashi.kunihiko at socionext.com/
>>>
>>> Changes in the previous patch:
>>> - Change the subject and commit message
>>>
>>> diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
>>> index ebe43e9..5075714 100644
>>> --- a/drivers/pci/controller/dwc/pcie-uniphier.c
>>> +++ b/drivers/pci/controller/dwc/pcie-uniphier.c
>>> @@ -186,12 +186,17 @@ static void uniphier_pcie_irq_ack(struct irq_data *d)
>>>   	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>>>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>>   	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
>>> +	unsigned long flags;
>>>   	u32 val;
>>>   
>>> +	raw_spin_lock_irqsave(&pp->lock, flags);
>>> +
>>>   	val = readl(priv->base + PCL_RCV_INTX);
>>>   	val &= ~PCL_RCV_INTX_ALL_STATUS;
>>>   	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
>>>   	writel(val, priv->base + PCL_RCV_INTX);
>>> +
>>> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>>>   }
>>>   
>>>   static void uniphier_pcie_irq_mask(struct irq_data *d)
>>> @@ -199,12 +204,17 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
>>>   	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>>>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>>   	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
>>> +	unsigned long flags;
>>>   	u32 val;
>>>   
>>> +	raw_spin_lock_irqsave(&pp->lock, flags);
>>> +
>>>   	val = readl(priv->base + PCL_RCV_INTX);
>>>   	val &= ~PCL_RCV_INTX_ALL_MASK;
>>>   	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
> 
> This looks extremely suspicious. You clear all the INTX mask bits, and
> only set the one you need. How about the pre-existing bits?

Thanks for pointing out. No need to clear all INTX mask bits.
The pre-existing bits should be preserved.

> 
>>>   	writel(val, priv->base + PCL_RCV_INTX);
>>> +
>>> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>>>   }
>>>   
>>>   static void uniphier_pcie_irq_unmask(struct irq_data *d)
>>> @@ -212,12 +222,17 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
>>>   	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>>>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>>   	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
>>> +	unsigned long flags;
>>>   	u32 val;
>>>   
>>> +	raw_spin_lock_irqsave(&pp->lock, flags);
>>> +
>>>   	val = readl(priv->base + PCL_RCV_INTX);
>>>   	val &= ~PCL_RCV_INTX_ALL_MASK;
>>>   	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
> 
> And by the same token, this second line is totally useless.
> 
> I think masking/unmasking is broken in this driver, locking or not.

Yes, this second line should be removed, too.
I'll fix this bug and add mask locking.

Thank you,

---
Best Regards
Kunihiko Hayashi


From nobuta.keiya at fujitsu.com  Tue Aug 24 17:01:16 2021
From: nobuta.keiya at fujitsu.com (nobuta.keiya at fujitsu.com)
Date: Wed, 25 Aug 2021 00:01:16 +0000
Subject: [RFC PATCH v8 3/4] arm64: Introduce stack trace reliability
 checks in the unwinder
In-Reply-To: <62d8969d-8ba1-4554-16b4-1c0bd4f8d9e7@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-4-madvenka@linux.microsoft.com>
 <TY2PR01MB5257EA835C6F28ABF457EB0B85C59@TY2PR01MB5257.jpnprd01.prod.outlook.com>
 <62d8969d-8ba1-4554-16b4-1c0bd4f8d9e7@linux.microsoft.com>
Message-ID: <TY2PR01MB5257492F3B6B2E904AF5E46285C69@TY2PR01MB5257.jpnprd01.prod.outlook.com>

> > Hi Madhavan,
> >
> >> @@ -245,7 +271,36 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
> >>  		fp = thread_saved_fp(task);
> >>  		pc = thread_saved_pc(task);
> >>  	}
> >> -	unwind(consume_entry, cookie, task, fp, pc);
> >> +	unwind(consume_entry, cookie, task, fp, pc, false); }
> >> +
> >> +/*
> >> + * arch_stack_walk_reliable() may not be used for livepatch until
> >> +all of
> >> + * the reliability checks are in place in unwind_consume(). However,
> >> + * debug and test code can choose to use it even if all the checks
> >> +are not
> >> + * in place.
> >> + */
> >
> > I'm glad to see the long-awaited function :)
> >
> > Does the above comment mean that this comment will be removed by
> > another patch series that about live patch enablement, instead of [PATCH 4/4]?
> >
> > It seems to take time... But I start thinking about test code.
> >
> 
> Yes. This comment will be removed when livepatch will be enabled eventually.
> So, AFAICT, there are 4 pieces that are needed:
> 
> - Reliable stack trace in the kernel. I am trying to address that with my patch
>   series.
> 
> - Mark Rutland's work for making patching safe on ARM64.
> 
> - Objtool (or alternative method) for stack validation.
> 
> - Suraj Jitindar Singh's patch for miscellaneous things needed to enable live patch.
> 
> Once all of these pieces are in place, livepatch can be enabled.
> 
> That said, arch_stack_walk_reliable() can be used for test and debug purposes anytime once this patch series gets accepted.
> 
> Thanks.
> 
> Madhavan


Thank you for the information.

Keiya


From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:37 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:37 +0800
Subject: [RESEND v4 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <202108250004.17P04L8S094371@twspam01.aspeedtech.com>

This patch use devm_add_action_or_reset to handle the error in probe
phase.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 92 +++++++++++++++++++++---------------
 1 file changed, 55 insertions(+), 37 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 52db38be9699..1c87e12a0cab 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -187,6 +187,27 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static void aspeed_adc_unregister_divider(void *data)
+{
+	struct clk_hw *clk = data;
+
+	clk_hw_unregister_divider(clk);
+}
+
+static void aspeed_adc_reset_assert(void *data)
+{
+	struct reset_control *rst = data;
+
+	reset_control_assert(rst);
+}
+
+static void aspeed_adc_clk_disable_unprepare(void *data)
+{
+	struct clk *clk = data;
+
+	clk_disable_unprepare(clk);
+}
+
 static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			&data->clk_lock);
 		if (IS_ERR(data->clk_prescaler))
 			return PTR_ERR(data->clk_prescaler);
+
+		ret = devm_add_action_or_reset(data->dev,
+					       aspeed_adc_unregister_divider,
+					       data->clk_prescaler);
+		if (ret)
+			return ret;
 		snprintf(clk_parent_name, 32, clk_name);
 		scaler_flags = CLK_SET_RATE_PARENT;
 	}
@@ -244,23 +271,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
 		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
 		data->model_data->scaler_bit_width, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_scaler)) {
-		ret = PTR_ERR(data->clk_scaler);
-		goto scaler_error;
-	}
+	if (IS_ERR(data->clk_scaler))
+		return PTR_ERR(data->clk_scaler);
+
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
+				       data->clk_scaler);
+	if (ret)
+		return ret;
 
 	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(data->rst)) {
 		dev_err(&pdev->dev,
 			"invalid or missing reset controller device tree entry");
-		ret = PTR_ERR(data->rst);
-		goto reset_error;
+		return PTR_ERR(data->rst);
 	}
 	reset_control_deassert(data->rst);
 
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
+				       data->rst);
+	if (ret)
+		return ret;
+
 	ret = aspeed_adc_vref_config(indio_dev);
 	if (ret)
-		goto vref_config_error;
+		return ret;
 
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
@@ -277,13 +311,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 					 ASPEED_ADC_INIT_POLLING_TIME,
 					 ASPEED_ADC_INIT_TIMEOUT);
 		if (ret)
-			goto poll_timeout_error;
+			return ret;
 	}
 
 	/* Start all channels in normal mode. */
 	ret = clk_prepare_enable(data->clk_scaler->clk);
 	if (ret)
-		goto clk_enable_error;
+		return ret;
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_clk_disable_unprepare,
+				       data->clk_scaler->clk);
+	if (ret)
+		return ret;
 
 	adc_engine_control_reg_val =
 		ASPEED_ADC_CTRL_CHANNEL |
@@ -299,41 +339,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto iio_register_error;
-
+	if (ret) {
+		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+				  ASPEED_ADC_OP_MODE_PWR_DOWN),
+		       data->base + ASPEED_REG_ENGINE_CONTROL);
+		return ret;
+	}
 	return 0;
-
-iio_register_error:
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-clk_enable_error:
-poll_timeout_error:
-vref_config_error:
-	reset_control_assert(data->rst);
-reset_error:
-	clk_hw_unregister_divider(data->clk_scaler);
-scaler_error:
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-	return ret;
 }
 
 static int aspeed_adc_remove(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-	struct aspeed_adc_data *data = iio_priv(indio_dev);
-
 	iio_device_unregister(indio_dev);
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-	reset_control_assert(data->rst);
-	clk_hw_unregister_divider(data->clk_scaler);
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-
 	return 0;
 }
 
-- 
2.25.1



From yoong.siang.song at intel.com  Tue Aug 24 17:55:29 2021
From: yoong.siang.song at intel.com (Song Yoong Siang)
Date: Wed, 25 Aug 2021 08:55:29 +0800
Subject: [PATCH net v2 1/1] net: stmmac: fix kernel panic due to NULL pointer
 dereference of xsk_pool
Message-ID: <20210825005529.980109-1-yoong.siang.song@intel.com>

After free xsk_pool, there is possibility that napi polling is still
running in the middle, thus causes a kernel crash due to kernel NULL
pointer dereference of rx_q->xsk_pool and tx_q->xsk_pool.

Fix this by changing the XDP pool setup sequence to:
 1. disable napi before free xsk_pool
 2. enable napi after init xsk_pool

The following kernel panic is observed without this patch:

RIP: 0010:xsk_uses_need_wakeup+0x5/0x10
Call Trace:
stmmac_napi_poll_rxtx+0x3a9/0xae0 [stmmac]
__napi_poll+0x27/0x130
net_rx_action+0x233/0x280
__do_softirq+0xe2/0x2b6
run_ksoftirqd+0x1a/0x20
smpboot_thread_fn+0xac/0x140
? sort_range+0x20/0x20
kthread+0x124/0x150
? set_kthread_struct+0x40/0x40
ret_from_fork+0x1f/0x30
---[ end trace a77c8956b79ac107 ]---

Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy")
Cc: <stable at vger.kernel.org> # 5.13.x
Signed-off-by: Song Yoong Siang <yoong.siang.song at intel.com>
---
v2 changelog:
 - Add stable at vger.kernel.org in email cc list.
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
index 105821b53020..2a616c6f7cd0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
@@ -34,18 +34,18 @@ static int stmmac_xdp_enable_pool(struct stmmac_priv *priv,
 	need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
 
 	if (need_update) {
-		stmmac_disable_rx_queue(priv, queue);
-		stmmac_disable_tx_queue(priv, queue);
 		napi_disable(&ch->rx_napi);
 		napi_disable(&ch->tx_napi);
+		stmmac_disable_rx_queue(priv, queue);
+		stmmac_disable_tx_queue(priv, queue);
 	}
 
 	set_bit(queue, priv->af_xdp_zc_qps);
 
 	if (need_update) {
-		napi_enable(&ch->rxtx_napi);
 		stmmac_enable_rx_queue(priv, queue);
 		stmmac_enable_tx_queue(priv, queue);
+		napi_enable(&ch->rxtx_napi);
 
 		err = stmmac_xsk_wakeup(priv->dev, queue, XDP_WAKEUP_RX);
 		if (err)
@@ -72,10 +72,10 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
 	need_update = netif_running(priv->dev) && stmmac_xdp_is_enabled(priv);
 
 	if (need_update) {
+		napi_disable(&ch->rxtx_napi);
 		stmmac_disable_rx_queue(priv, queue);
 		stmmac_disable_tx_queue(priv, queue);
 		synchronize_rcu();
-		napi_disable(&ch->rxtx_napi);
 	}
 
 	xsk_pool_dma_unmap(pool, STMMAC_RX_DMA_ATTR);
@@ -83,10 +83,10 @@ static int stmmac_xdp_disable_pool(struct stmmac_priv *priv, u16 queue)
 	clear_bit(queue, priv->af_xdp_zc_qps);
 
 	if (need_update) {
-		napi_enable(&ch->rx_napi);
-		napi_enable(&ch->tx_napi);
 		stmmac_enable_rx_queue(priv, queue);
 		stmmac_enable_tx_queue(priv, queue);
+		napi_enable(&ch->rx_napi);
+		napi_enable(&ch->tx_napi);
 	}
 
 	return 0;
-- 
2.25.1



From yoong.siang.song at intel.com  Tue Aug 24 17:57:42 2021
From: yoong.siang.song at intel.com (Song Yoong Siang)
Date: Wed, 25 Aug 2021 08:57:42 +0800
Subject: [PATCH net v2 1/1] net: stmmac: fix kernel panic due to NULL pointer
 dereference of buf->xdp
Message-ID: <20210825005742.980267-1-yoong.siang.song@intel.com>

Ensure a valid XSK buffer before proceed to free the xdp buffer.

The following kernel panic is observed without this patch:

RIP: 0010:xp_free+0x5/0x40
Call Trace:
stmmac_napi_poll_rxtx+0x332/0xb30 [stmmac]
? stmmac_tx_timer+0x3c/0xb0 [stmmac]
net_rx_action+0x13d/0x3d0
__do_softirq+0xfc/0x2fb
? smpboot_register_percpu_thread+0xe0/0xe0
run_ksoftirqd+0x32/0x70
smpboot_thread_fn+0x1d8/0x2c0
kthread+0x169/0x1a0
? kthread_park+0x90/0x90
ret_from_fork+0x1f/0x30
---[ end trace 0000000000000002 ]---

Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy")
Cc: <stable at vger.kernel.org> # 5.13.x
Suggested-by: Ong Boon Leong <boon.leong.ong at intel.com>
Signed-off-by: Song Yoong Siang <yoong.siang.song at intel.com>
---
v2 changelog:
 - Add stable at vger.kernel.org in email cc list.
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7b8404a21544..fa90bcdf4e45 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4914,6 +4914,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
 
 		prefetch(np);
 
+		/* Ensure a valid XSK buffer before proceed */
+		if (!buf->xdp)
+			break;
+
 		if (priv->extend_desc)
 			stmmac_rx_extended_status(priv, &priv->dev->stats,
 						  &priv->xstats,
@@ -4934,10 +4938,6 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
 			continue;
 		}
 
-		/* Ensure a valid XSK buffer before proceed */
-		if (!buf->xdp)
-			break;
-
 		/* XSK pool expects RX frame 1:1 mapped to XSK buffer */
 		if (likely(status & rx_not_ls)) {
 			xsk_buff_free(buf->xdp);
-- 
2.25.1



From chun-jie.chen at mediatek.com  Tue Aug 24 18:04:26 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 25 Aug 2021 09:04:26 +0800
Subject: [v5] arm64: dts: mediatek: Add mt8192 power domains controller
Message-ID: <20210825010426.30303-1-chun-jie.chen@mediatek.com>

Add power domains controller node for SoC mt8192

Signed-off-by: Weiyi Lu <weiyi.lu at mediatek.com>
Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
This patch is base on v5.14-rc1,
series "Mediatek MT8192 clock support"[1] and [2].
No changes compare v4

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127
[2] https://patchwork.kernel.org/project/linux-mediatek/patch/20210727023205.20319-2-chun-jie.chen at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 201 +++++++++++++++++++++++
 1 file changed, 201 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index c7c7d4e017ae..a0084a7a5bcd 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -9,6 +9,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/mt8192-pinfunc.h>
+#include <dt-bindings/power/mt8192-power.h>
 
 / {
 	compatible = "mediatek,mt8192";
@@ -301,6 +302,206 @@
 			#interrupt-cells = <2>;
 		};
 
+		scpsys: syscon at 10006000 {
+			compatible = "syscon", "simple-mfd";
+			reg = <0 0x10006000 0 0x1000>;
+			#power-domain-cells = <1>;
+
+			/* System Power Manager */
+			spm: power-controller {
+				compatible = "mediatek,mt8192-power-controller";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				#power-domain-cells = <1>;
+
+				/* power domain of the SoC */
+				power-domain at MT8192_POWER_DOMAIN_AUDIO {
+					reg = <MT8192_POWER_DOMAIN_AUDIO>;
+					clocks = <&topckgen CLK_TOP_AUD_INTBUS_SEL>,
+						 <&infracfg CLK_INFRA_AUDIO_26M_B>,
+						 <&infracfg CLK_INFRA_AUDIO>;
+					clock-names = "audio", "audio1", "audio2";
+					mediatek,infracfg = <&infracfg>;
+					#power-domain-cells = <0>;
+				};
+
+				power-domain at MT8192_POWER_DOMAIN_CONN {
+					reg = <MT8192_POWER_DOMAIN_CONN>;
+					clocks = <&infracfg CLK_INFRA_PMIC_CONN>;
+					clock-names = "conn";
+					mediatek,infracfg = <&infracfg>;
+					#power-domain-cells = <0>;
+				};
+
+				power-domain at MT8192_POWER_DOMAIN_MFG0 {
+					reg = <MT8192_POWER_DOMAIN_MFG0>;
+					clocks = <&topckgen CLK_TOP_MFG_PLL_SEL>;
+					clock-names = "mfg";
+					#address-cells = <1>;
+					#size-cells = <0>;
+					#power-domain-cells = <1>;
+
+					power-domain at MT8192_POWER_DOMAIN_MFG1 {
+						reg = <MT8192_POWER_DOMAIN_MFG1>;
+						mediatek,infracfg = <&infracfg>;
+						#address-cells = <1>;
+						#size-cells = <0>;
+						#power-domain-cells = <1>;
+
+						power-domain at MT8192_POWER_DOMAIN_MFG2 {
+							reg = <MT8192_POWER_DOMAIN_MFG2>;
+							#power-domain-cells = <0>;
+						};
+
+						power-domain at MT8192_POWER_DOMAIN_MFG3 {
+							reg = <MT8192_POWER_DOMAIN_MFG3>;
+							#power-domain-cells = <0>;
+						};
+
+						power-domain at MT8192_POWER_DOMAIN_MFG4 {
+							reg = <MT8192_POWER_DOMAIN_MFG4>;
+							#power-domain-cells = <0>;
+						};
+
+						power-domain at MT8192_POWER_DOMAIN_MFG5 {
+							reg = <MT8192_POWER_DOMAIN_MFG5>;
+							#power-domain-cells = <0>;
+						};
+
+						power-domain at MT8192_POWER_DOMAIN_MFG6 {
+							reg = <MT8192_POWER_DOMAIN_MFG6>;
+							#power-domain-cells = <0>;
+						};
+					};
+				};
+
+				power-domain at MT8192_POWER_DOMAIN_DISP {
+					reg = <MT8192_POWER_DOMAIN_DISP>;
+					clocks = <&topckgen CLK_TOP_DISP_SEL>,
+						 <&mmsys CLK_MM_SMI_INFRA>,
+						 <&mmsys CLK_MM_SMI_COMMON>,
+						 <&mmsys CLK_MM_SMI_GALS>,
+						 <&mmsys CLK_MM_SMI_IOMMU>;
+					clock-names = "disp", "disp-0", "disp-1", "disp-2",
+						      "disp-3";
+					mediatek,infracfg = <&infracfg>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+					#power-domain-cells = <1>;
+
+					power-domain at MT8192_POWER_DOMAIN_IPE {
+						reg = <MT8192_POWER_DOMAIN_IPE>;
+						clocks = <&topckgen CLK_TOP_IPE_SEL>,
+							 <&ipesys CLK_IPE_LARB19>,
+							 <&ipesys CLK_IPE_LARB20>,
+							 <&ipesys CLK_IPE_SMI_SUBCOM>,
+							 <&ipesys CLK_IPE_GALS>;
+						clock-names = "ipe", "ipe-0", "ipe-1", "ipe-2",
+							      "ipe-3";
+						mediatek,infracfg = <&infracfg>;
+						#power-domain-cells = <0>;
+					};
+
+					power-domain at MT8192_POWER_DOMAIN_ISP {
+						reg = <MT8192_POWER_DOMAIN_ISP>;
+						clocks = <&topckgen CLK_TOP_IMG1_SEL>,
+							 <&imgsys CLK_IMG_LARB9>,
+							 <&imgsys CLK_IMG_GALS>;
+						clock-names = "isp", "isp-0", "isp-1";
+						mediatek,infracfg = <&infracfg>;
+						#power-domain-cells = <0>;
+					};
+
+					power-domain at MT8192_POWER_DOMAIN_ISP2 {
+						reg = <MT8192_POWER_DOMAIN_ISP2>;
+						clocks = <&topckgen CLK_TOP_IMG2_SEL>,
+							 <&imgsys2 CLK_IMG2_LARB11>,
+							 <&imgsys2 CLK_IMG2_GALS>;
+						clock-names = "isp2", "isp2-0", "isp2-1";
+						mediatek,infracfg = <&infracfg>;
+						#power-domain-cells = <0>;
+					};
+
+					power-domain at MT8192_POWER_DOMAIN_MDP {
+						reg = <MT8192_POWER_DOMAIN_MDP>;
+						clocks = <&topckgen CLK_TOP_MDP_SEL>,
+							 <&mdpsys CLK_MDP_SMI0>;
+						clock-names = "mdp", "mdp-0";
+						mediatek,infracfg = <&infracfg>;
+						#power-domain-cells = <0>;
+					};
+
+					power-domain at MT8192_POWER_DOMAIN_VENC {
+						reg = <MT8192_POWER_DOMAIN_VENC>;
+						clocks = <&topckgen CLK_TOP_VENC_SEL>,
+							 <&vencsys CLK_VENC_SET1_VENC>;
+						clock-names = "venc", "venc-0";
+						mediatek,infracfg = <&infracfg>;
+						#power-domain-cells = <0>;
+					};
+
+					power-domain at MT8192_POWER_DOMAIN_VDEC {
+						reg = <MT8192_POWER_DOMAIN_VDEC>;
+						clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+							 <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
+							 <&vdecsys_soc CLK_VDEC_SOC_LAT>,
+							 <&vdecsys_soc CLK_VDEC_SOC_LARB1>;
+						clock-names = "vdec", "vdec-0", "vdec-1", "vdec-2";
+						mediatek,infracfg = <&infracfg>;
+						#address-cells = <1>;
+						#size-cells = <0>;
+						#power-domain-cells = <1>;
+
+						power-domain at MT8192_POWER_DOMAIN_VDEC2 {
+							reg = <MT8192_POWER_DOMAIN_VDEC2>;
+							clocks = <&vdecsys CLK_VDEC_VDEC>,
+								 <&vdecsys CLK_VDEC_LAT>,
+								 <&vdecsys CLK_VDEC_LARB1>;
+							clock-names = "vdec2-0", "vdec2-1",
+								      "vdec2-2";
+							#power-domain-cells = <0>;
+						};
+					};
+
+					power-domain at MT8192_POWER_DOMAIN_CAM {
+						reg = <MT8192_POWER_DOMAIN_CAM>;
+						clocks = <&topckgen CLK_TOP_CAM_SEL>,
+							 <&camsys CLK_CAM_LARB13>,
+							 <&camsys CLK_CAM_LARB14>,
+							 <&camsys CLK_CAM_CCU_GALS>,
+							 <&camsys CLK_CAM_CAM2MM_GALS>;
+						clock-names = "cam", "cam-0", "cam-1", "cam-2",
+							      "cam-3";
+						mediatek,infracfg = <&infracfg>;
+						#address-cells = <1>;
+						#size-cells = <0>;
+						#power-domain-cells = <1>;
+
+						power-domain at MT8192_POWER_DOMAIN_CAM_RAWA {
+							reg = <MT8192_POWER_DOMAIN_CAM_RAWA>;
+							clocks = <&camsys_rawa CLK_CAM_RAWA_LARBX>;
+							clock-names = "cam_rawa-0";
+							#power-domain-cells = <0>;
+						};
+
+						power-domain at MT8192_POWER_DOMAIN_CAM_RAWB {
+							reg = <MT8192_POWER_DOMAIN_CAM_RAWB>;
+							clocks = <&camsys_rawb CLK_CAM_RAWB_LARBX>;
+							clock-names = "cam_rawb-0";
+							#power-domain-cells = <0>;
+						};
+
+						power-domain at MT8192_POWER_DOMAIN_CAM_RAWC {
+							reg = <MT8192_POWER_DOMAIN_CAM_RAWC>;
+							clocks = <&camsys_rawc CLK_CAM_RAWC_LARBX>;
+							clock-names = "cam_rawc-0";
+							#power-domain-cells = <0>;
+						};
+					};
+				};
+			};
+		};
+
 		apmixedsys: syscon at 1000c000 {
 			compatible = "mediatek,mt8192-apmixedsys", "syscon";
 			reg = <0 0x1000c000 0 0x1000>;
-- 
2.18.0

From chun-jie.chen at mediatek.com  Tue Aug 24 18:11:15 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 25 Aug 2021 09:11:15 +0800
Subject: [v1 0/5] Update MT8192 Clock Setting
Message-ID: <20210825011120.30481-1-chun-jie.chen@mediatek.com>

This patch is base on v5.14-rc1,
series "Mediatek MT8192 clock support"[1] and [2].

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127
[2] https://patchwork.kernel.org/project/linux-mediatek/patch/20210727023205.20319-2-chun-jie.chen at mediatek.com/

Chun-Jie Chen (5):
  arm64: dts: mediatek: Correct system timer clock of MT8192
  arm64: dts: mediatek: Correct UART clock of MT8192
  arm64: dts: mediatek: Correct SPI clock of MT8192
  arm64: dts: mediatek: Correct Nor Flash clock of MT8192
  arm64: dts: mediatek: Correct I2C clock of MT8192

 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 90 +++++++++++++-----------
 1 file changed, 50 insertions(+), 40 deletions(-)

--
2.18.0

From chun-jie.chen at mediatek.com  Tue Aug 24 18:11:16 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 25 Aug 2021 09:11:16 +0800
Subject: [v1 1/5] arm64: dts: mediatek: Correct system timer clock of MT8192
In-Reply-To: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
References: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
Message-ID: <20210825011120.30481-2-chun-jie.chen@mediatek.com>

update systimer clock to the real one.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index c7c7d4e017ae..2b63d2ea6cb6 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -312,7 +312,7 @@
 				     "mediatek,mt6765-timer";
 			reg = <0 0x10017000 0 0x1000>;
 			interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>;
+			clocks = <&topckgen CLK_TOP_CSW_F26M_D2>;
 			clock-names = "clk13m";
 		};
 
-- 
2.18.0

From chun-jie.chen at mediatek.com  Tue Aug 24 18:11:17 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 25 Aug 2021 09:11:17 +0800
Subject: [v1 2/5] arm64: dts: mediatek: Correct UART clock of MT8192
In-Reply-To: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
References: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
Message-ID: <20210825011120.30481-3-chun-jie.chen@mediatek.com>

update uart0 and uart1 bus clock to the real one.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 2b63d2ea6cb6..31d135e18784 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -327,7 +327,7 @@
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11002000 0 0x1000>;
 			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART0>;
 			clock-names = "baud", "bus";
 			status = "disabled";
 		};
@@ -337,7 +337,7 @@
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11003000 0 0x1000>;
 			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART1>;
 			clock-names = "baud", "bus";
 			status = "disabled";
 		};
-- 
2.18.0

From chun-jie.chen at mediatek.com  Tue Aug 24 18:11:18 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 25 Aug 2021 09:11:18 +0800
Subject: [v1 3/5] arm64: dts: mediatek: Correct SPI clock of MT8192
In-Reply-To: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
References: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
Message-ID: <20210825011120.30481-4-chun-jie.chen@mediatek.com>

update uart0 ~ 7 clocks to the real ones.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 48 ++++++++++++------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 31d135e18784..d1c85d3e152b 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -355,9 +355,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1100a000 0 0x1000>;
 			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI0>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -369,9 +369,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11010000 0 0x1000>;
 			interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI1>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -383,9 +383,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11012000 0 0x1000>;
 			interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI2>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -397,9 +397,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11013000 0 0x1000>;
 			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI3>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -411,9 +411,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11018000 0 0x1000>;
 			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI4>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -425,9 +425,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11019000 0 0x1000>;
 			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI5>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -439,9 +439,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1101d000 0 0x1000>;
 			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI6>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -453,9 +453,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1101e000 0 0x1000>;
 			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI7>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
-- 
2.18.0

From chun-jie.chen at mediatek.com  Tue Aug 24 18:11:19 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 25 Aug 2021 09:11:19 +0800
Subject: [v1 4/5] arm64: dts: mediatek: Correct Nor Flash clock of MT8192
In-Reply-To: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
References: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
Message-ID: <20210825011120.30481-5-chun-jie.chen@mediatek.com>

update nor flash clock to the real one.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index d1c85d3e152b..db6f4c6dc404 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -464,9 +464,9 @@
 			compatible = "mediatek,mt8192-nor";
 			reg = <0 0x11234000 0 0xe0>;
 			interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_SFLASH_SEL>,
+				 <&infracfg CLK_INFRA_FLASHIF_SFLASH>,
+				 <&infracfg CLK_INFRA_FLASHIF_TOP_H_133M>;
 			clock-names = "spi", "sf", "axi";
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
2.18.0

From chun-jie.chen at mediatek.com  Tue Aug 24 18:11:20 2021
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Wed, 25 Aug 2021 09:11:20 +0800
Subject: [v1 5/5] arm64: dts: mediatek: Correct I2C clock of MT8192
In-Reply-To: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
References: <20210825011120.30481-1-chun-jie.chen@mediatek.com>
Message-ID: <20210825011120.30481-6-chun-jie.chen@mediatek.com>

update i2c 0 ~ 9 clocks to the real ones.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 30 ++++++++++++++++--------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index db6f4c6dc404..866b04e78690 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -484,7 +484,8 @@
 			reg = <0 0x11cb0000 0 0x1000>,
 			      <0 0x10217300 0 0x80>;
 			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_e CLK_IMP_IIC_WRAP_E_I2C3>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -503,7 +504,8 @@
 			reg = <0 0x11d00000 0 0x1000>,
 			      <0 0x10217600 0 0x180>;
 			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -516,7 +518,8 @@
 			reg = <0 0x11d01000 0 0x1000>,
 			      <0 0x10217780 0 0x180>;
 			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C8>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -529,7 +532,8 @@
 			reg = <0 0x11d02000 0 0x1000>,
 			      <0 0x10217900 0 0x180>;
 			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C9>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -548,7 +552,8 @@
 			reg = <0 0x11d20000 0 0x1000>,
 			      <0 0x10217100 0 0x80>;
 			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C1>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -561,7 +566,8 @@
 			reg = <0 0x11d21000 0 0x1000>,
 			      <0 0x10217180 0 0x180>;
 			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C2>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -574,7 +580,8 @@
 			reg = <0 0x11d22000 0 0x1000>,
 			      <0 0x10217380 0 0x180>;
 			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C4>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -593,7 +600,8 @@
 			reg = <0 0x11e00000 0 0x1000>,
 			      <0 0x10217500 0 0x80>;
 			interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C5>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -612,7 +620,8 @@
 			reg = <0 0x11f00000 0 0x1000>,
 			      <0 0x10217080 0 0x80>;
 			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C0>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -625,7 +634,8 @@
 			reg = <0 0x11f01000 0 0x1000>,
 			      <0 0x10217580 0 0x80>;
 			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C6>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
-- 
2.18.0

From billy_tsai at aspeedtech.com  Tue Aug 24 17:06:47 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Wed, 25 Aug 2021 00:06:47 +0000
Subject: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <YSTiUPQa+HYSA63t@robh.at.kernel.org>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
 <20210823070240.12600-2-billy_tsai@aspeedtech.com>
 <YSTiUPQa+HYSA63t@robh.at.kernel.org>
Message-ID: <DEB9D606-6489-4993-A5E7-6E4F3226EE5A@aspeedtech.com>

Hi Rob,

On 2021/8/24, 8:13 PM, "Rob Herring" <robh at kernel.org> wrote:

    On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
    >   > +properties:
    >   > +  compatible:
    >   > +    enum:
    >   > +      - aspeed,ast2600-adc0
    >   > +      - aspeed,ast2600-adc1

    > What's the difference between 0 and 1?

Their trimming data, which is used to calibrate internal reference volage,
locates in different address of OTP.

Best Regards,
Billy Tsai

 


From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:42 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:42 +0800
Subject: [RESEND v4 14/15] iio: adc: aspeed: Support battery sensing.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <202108250005.17P058ou095848@twspam01.aspeedtech.com>

In ast2600, ADC integrate dividing circuit at last input channel for
battery sensing. This patch use the dts property "battery-sensing" to
enable this feature makes the last channel of each adc can tolerance
higher voltage than reference voltage.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 62 +++++++++++++++++++++++++++++++++---
 1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 20caf28dff18..0c5d84e82561 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -79,10 +79,16 @@ struct aspeed_adc_model_data {
 	unsigned int vref_fixed;	// mV
 	bool wait_init_sequence;
 	bool need_prescaler;
+	bool bat_sense_sup;
 	u8 scaler_bit_width;
 	unsigned int num_channels;
 };
 
+struct adc_gain {
+	u8 mult;
+	u8 div;
+};
+
 struct aspeed_adc_data {
 	struct device		*dev;
 	const struct aspeed_adc_model_data *model_data;
@@ -96,6 +102,8 @@ struct aspeed_adc_data {
 	int			vref;
 	u32			sample_period_ns;
 	int			cv;
+	bool			battery_sensing;
+	struct adc_gain		battery_mode_gain;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -103,10 +111,10 @@ struct aspeed_adc_data {
 	.indexed = 1,						\
 	.channel = (_idx),					\
 	.address = (_data_reg_addr),				\
-	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
-	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
-				BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
 				BIT(IIO_CHAN_INFO_OFFSET),	\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
+				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 }
 
 static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
@@ -196,14 +204,39 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       int *val, int *val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	u32 adc_engine_control_reg_val;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		*val = readw(data->base + chan->address);
+		if (data->battery_sensing && chan->channel == 7) {
+			adc_engine_control_reg_val =
+				readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+			writel(adc_engine_control_reg_val |
+				       FIELD_PREP(ASPEED_ADC_CH7_MODE,
+						  ASPEED_ADC_CH7_BAT) |
+				       ASPEED_ADC_BAT_SENSING_ENABLE,
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+			/*
+			 * After enable battery sensing mode need to wait some time for adc stable
+			 * Experiment result is 1ms.
+			 */
+			mdelay(1);
+			*val = readw(data->base + chan->address);
+			*val = (*val * data->battery_mode_gain.mult) /
+			       data->battery_mode_gain.div;
+			/* Restore control register value */
+			writel(adc_engine_control_reg_val,
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		} else
+			*val = readw(data->base + chan->address);
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_OFFSET:
-		*val = data->cv;
+		if (data->battery_sensing && chan->channel == 7)
+			*val = (data->cv * data->battery_mode_gain.mult) /
+			       data->battery_mode_gain.div;
+		else
+			*val = data->cv;
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
@@ -473,6 +506,23 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
+			     NULL)) {
+		if (data->model_data->bat_sense_sup) {
+			data->battery_sensing = 1;
+			if (readl(data->base + ASPEED_REG_ENGINE_CONTROL) &
+			ASPEED_ADC_BAT_SENSING_DIV) {
+				data->battery_mode_gain.mult = 3;
+				data->battery_mode_gain.div = 1;
+			} else {
+				data->battery_mode_gain.mult = 3;
+				data->battery_mode_gain.div = 2;
+			}
+		} else
+			dev_warn(&pdev->dev,
+				"Failed to enable battey-sensing mode\n");
+	}
+
 	if (data->model_data->wait_init_sequence) {
 		adc_engine_control_reg_val =
 			readl(data->base + ASPEED_REG_ENGINE_CONTROL);
@@ -555,6 +605,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
 	.wait_init_sequence = true,
+	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
 };
@@ -564,6 +615,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
 	.wait_init_sequence = true,
+	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
 };
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:40 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:40 +0800
Subject: [RESEND v4 12/15] iio: adc: aspeed: Add func to set sampling rate.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <202108250003.17P036bM092211@twspam01.aspeedtech.com>

Add the function to set the sampling rate and keep the sampling period
for a driver used to wait the lastest value.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 58 +++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 18 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 8fe7da1a651f..4d979dd7fe88 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -65,6 +65,12 @@
 
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
+/*
+ * When the sampling rate is too high, the ADC may not have enough charging
+ * time, resulting in a low voltage value. Thus, default use slow sampling
+ * rate for most user case.
+ */
+#define ASPEED_ADC_DEF_SAMPLING_RATE	65000
 
 struct aspeed_adc_model_data {
 	const char *model_name;
@@ -88,6 +94,7 @@ struct aspeed_adc_data {
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
 	int			vref;
+	u32			sample_period_ns;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -119,6 +126,24 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	if (rate < data->model_data->min_sampling_rate ||
+	    rate > data->model_data->max_sampling_rate)
+		return -EINVAL;
+	/* Each sampling needs 12 clocks to covert.*/
+	clk_set_rate(data->clk_scaler->clk, rate * ASPEED_CLOCKS_PER_SAMPLE);
+	rate = clk_get_rate(data->clk_scaler->clk);
+	data->sample_period_ns = DIV_ROUND_UP_ULL(
+		(u64)NSEC_PER_SEC * ASPEED_CLOCKS_PER_SAMPLE, rate);
+	dev_dbg(data->dev, "Adc clock = %d sample period = %d ns", rate,
+		data->sample_period_ns);
+
+	return 0;
+}
+
 static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       struct iio_chan_spec const *chan,
 			       int *val, int *val2, long mask)
@@ -149,17 +174,10 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,
 				struct iio_chan_spec const *chan,
 				int val, int val2, long mask)
 {
-	struct aspeed_adc_data *data = iio_priv(indio_dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val < data->model_data->min_sampling_rate ||
-			val > data->model_data->max_sampling_rate)
-			return -EINVAL;
-
-		clk_set_rate(data->clk_scaler->clk,
-				val * ASPEED_CLOCKS_PER_SAMPLE);
-		return 0;
+		return aspeed_adc_set_sampling_rate(indio_dev, val);
 
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_RAW:
@@ -386,6 +404,20 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = clk_prepare_enable(data->clk_scaler->clk);
+	if (ret)
+		return ret;
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_clk_disable_unprepare,
+				       data->clk_scaler->clk);
+	if (ret)
+		return ret;
+
+	ret = aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE);
+	if (ret)
+		return ret;
+
 	ret = aspeed_adc_vref_config(indio_dev);
 	if (ret)
 		return ret;
@@ -413,16 +445,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 
 	/* Start all channels in normal mode. */
-	ret = clk_prepare_enable(data->clk_scaler->clk);
-	if (ret)
-		return ret;
-
-	ret = devm_add_action_or_reset(data->dev,
-				       aspeed_adc_clk_disable_unprepare,
-				       data->clk_scaler->clk);
-	if (ret)
-		return ret;
-
 	adc_engine_control_reg_val =
 		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
 	adc_engine_control_reg_val |=
-- 
2.25.1



From mhiramat at kernel.org  Tue Aug 24 19:13:39 2021
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Wed, 25 Aug 2021 11:13:39 +0900
Subject: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210824105001.GA96738@C02TD0UTHF1T.local>
References: <20210818073336.59678-1-liuqi115@huawei.com>
 <20210818073336.59678-3-liuqi115@huawei.com>
 <20210824105001.GA96738@C02TD0UTHF1T.local>
Message-ID: <20210825111339.dcf494abb0c27508d2d1f645@kernel.org>

On Tue, 24 Aug 2021 11:50:01 +0100
Mark Rutland <mark.rutland at arm.com> wrote:

> Hi,
> 
> I have a bunch of comments below.
> 
> At a high-level, I'm not all that keen on adding yet another set of
> trampolines, especially given we have constraints on how we can branch
> to them which render this not that useful in common configurations (e.g.
> where KASLR and module randomization is enabled).

Yes, that makes kprobe jump optimization hard to implement on
RISC architecture in general. (x86 has 32bit offset jump instruction)
To solve this issue, something like "intermedate jump area" is needed
for each module. (Or, overwriting multiple instructions)

> 
> So importantly, do we actually need this? I don't think the sampel is
> that compelling since we can already use ftrace to measure function
> latencies.

That depends on what you use it for, as you may know, kprobes allows
you to put the probes on function body (and inlined function),
on the other hand, ftrace can put only on the entry of the function.
I guess Qi may want to use it for improving performance of BPF.

(BTW, as far as I know, Jisheng Zhang once tried to implement
kprobe on ftrace, that may be more helpful in this example.
https://lore.kernel.org/linux-arm-kernel/20191225172625.69811b3e at xhacker.debian/T/#m23a7aa55d32d140ee6a92102534446cfd4a43007
I will pick them up again)

> 
> If we do need this, I think we need to do some more substantial rework
> to address those branch range limitations. I know that we could permit
> arbitrary branching if we expand the ftrace-with-regs callsites to ~6
> instructions, but that interacts rather poorly with stacktracing and
> will make the kernel a bit bigger.

Would you mean we reuse the ftrace-with-regs callsites for kprobes?

arm32 avoids this limitation partially with reserved text pages
for trampoline in the kernel. But I think that is also a partial
solution. It may not work with module randomization at least on
arm64.

On arm64, I think there are several way to solve it.

- Add optprobe trampoline buffer for each module.
  This is the simplest way to solve this issue, but requires some
  pages to be added to each module (and kernel).

- Add intermediate trampoline area for each module. (2-stage jump)
  This jumps into an intermediate trampoline entry, save a partial
  registers and jump the actual trampoline using that register.
  This can reduce the size of trampoline buffer for each module.

- Replace multiple instructions with the above intermediate jump
  code. (single jump, but replace multiple instructions)
  This requires to emulate multiple instructions and also the
  kprobe must decode the instructions in the target function to
  identify the replaced instructions are in one basic block. But
  no need to add intermediate trampoline area (page).



> 
> On Wed, Aug 18, 2021 at 03:33:36PM +0800, Qi Liu wrote:
> > This patch introduce optprobe for ARM64. In optprobe, probed
> > instruction is replaced by a branch instruction to detour
> > buffer. Detour buffer contains trampoline code and a call to
> > optimized_callback(). optimized_callback() calls opt_pre_handler()
> > to execute kprobe handler.
> > 
> > Performance of optprobe on Hip08 platform is test using kprobe
> > example module[1] to analyze the latency of a kernel function,
> > and here is the result:
> > 
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> > 
> > kprobe before optimized:
> > [280709.846380] do_empty returned 0 and took 1530 ns to execute
> > [280709.852057] do_empty returned 0 and took 550 ns to execute
> > [280709.857631] do_empty returned 0 and took 440 ns to execute
> > [280709.863215] do_empty returned 0 and took 380 ns to execute
> > [280709.868787] do_empty returned 0 and took 360 ns to execute
> > [280709.874362] do_empty returned 0 and took 340 ns to execute
> > [280709.879936] do_empty returned 0 and took 320 ns to execute
> > [280709.885505] do_empty returned 0 and took 300 ns to execute
> > [280709.891075] do_empty returned 0 and took 280 ns to execute
> > [280709.896646] do_empty returned 0 and took 290 ns to execute
> > [280709.902220] do_empty returned 0 and took 290 ns to execute
> > [280709.907807] do_empty returned 0 and took 290 ns to execute
> > 
> > optprobe:
> > [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> > [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> > [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> > [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> > [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> > [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> > [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> > [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> > [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> > [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> > [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> > [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> > [ 2966.029158] do_empty returned 0 and took 70 ns to execute
> 
> Do we have any examples of where this latency matters in practice?
> 
> > 
> > Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> > 
> > Note:
> > To guarantee the offset between probe point and kprobe pre_handler
> > is smaller than 128MiB, users should set
> > CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
> > optprobe will not work and fall back to normal kprobe.
> 
> Hmm... I don't think that's something we want to recommend, and
> certainly distros *should* use KASLR and
> CONFIG_RANDOMIZE_MODULE_REGION_FULL.
> 
> What happens with defconfig? Do we always get the fallback behaviour?

Yes, in such case, it fails back to normal kprobe.
Anyway, optprobe is a background optimization. User can not specify
which kprobe is optimized. That is automatically done.

Thank you,


-- 
Masami Hiramatsu <mhiramat at kernel.org>


From yulei.sh at bytedance.com  Tue Aug 24 19:14:16 2021
From: yulei.sh at bytedance.com (Lei Yu)
Date: Wed, 25 Aug 2021 10:14:16 +0800
Subject: [Phishing Risk] [External] [PATCH v3] media: aspeed-video: ignore
 interrupts that aren't enabled
In-Reply-To: <20210617220229.7352-1-zev@bewilderbeest.net>
References: <20210617220229.7352-1-zev@bewilderbeest.net>
Message-ID: <CAGm54UEvQG9_AiL_o9R3ZVpF4oT0Te7DC+oHLWsNGrwVuCfJJw@mail.gmail.com>

On Fri, Jun 18, 2021 at 6:02 AM Zev Weiss <zev at bewilderbeest.net> wrote:
>
> As partially addressed in commit 65d270acb2d6 ("media: aspeed: clear
> garbage interrupts"), the ASpeed video engine sometimes asserts
> interrupts that the driver hasn't enabled.  In addition to the
> CAPTURE_COMPLETE and FRAME_COMPLETE interrupts dealt with in that
> patch, COMP_READY has also been observed.  Instead of playing
> whack-a-mole with each one individually, we can instead just blanket
> ignore everything we haven't explicitly enabled.
>
> Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
> ---
>
> Changes since v2 [1]:
>  - minor commit message improvements
>
> Changes since v1 [0]:
>  - dropped error message
>  - switched to a blanket-ignore approach as suggested by Ryan
>
> [0] https://lore.kernel.org/linux-arm-kernel/20201215024542.18888-1-zev at bewilderbeest.net/
> [1] https://lore.kernel.org/openbmc/20210506234048.3214-1-zev at bewilderbeest.net/
>
>  drivers/media/platform/aspeed-video.c | 16 ++++++----------
>  1 file changed, 6 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
> index 7bb6babdcade..77611c296a25 100644
> --- a/drivers/media/platform/aspeed-video.c
> +++ b/drivers/media/platform/aspeed-video.c
> @@ -563,6 +563,12 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg)
>         struct aspeed_video *video = arg;
>         u32 sts = aspeed_video_read(video, VE_INTERRUPT_STATUS);
>
> +       /*
> +        * Hardware sometimes asserts interrupts that we haven't actually
> +        * enabled; ignore them if so.
> +        */
> +       sts &= aspeed_video_read(video, VE_INTERRUPT_CTRL);
> +

Without the patch, the driver gets an unhandled IRQ in a few hours
after the KVM page is opened.
This patch is tested on Bytedance's OpenBMC system and the issue has
not been reproduced anymore.

Tested-by: Lei YU <yulei.sh at bytedance.com>

-- 
BRs,
Lei YU


From haibo.chen at nxp.com  Tue Aug 24 19:16:32 2021
From: haibo.chen at nxp.com (Bough Chen)
Date: Wed, 25 Aug 2021 02:16:32 +0000
Subject: [PATCH 1/6] mmc: sdhci-esdhc-imx: remove redundant code for
 manual tuning
In-Reply-To: <CAPDyKFr2z6t0uefxioLHaszvwrc9Pkf1OJDi=jozjpEZcKP5ng@mail.gmail.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <CAPDyKFr2z6t0uefxioLHaszvwrc9Pkf1OJDi=jozjpEZcKP5ng@mail.gmail.com>
Message-ID: <VI1PR04MB5294D4EE6173C4897ABF496090C69@VI1PR04MB5294.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> Sent: 2021?8?24? 21:53
> To: Bough Chen <haibo.chen at nxp.com>
> Cc: Adrian Hunter <adrian.hunter at intel.com>; Shawn Guo
> <shawnguo at kernel.org>; Rob Herring <robh+dt at kernel.org>; Sascha Hauer
> <s.hauer at pengutronix.de>; Sascha Hauer <kernel at pengutronix.de>; Fabio
> Estevam <festevam at gmail.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> dl-linux-imx <linux-imx at nxp.com>; DTML <devicetree at vger.kernel.org>; Linux
> ARM <linux-arm-kernel at lists.infradead.org>
> Subject: Re: [PATCH 1/6] mmc: sdhci-esdhc-imx: remove redundant code for
> manual tuning
> 
> On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
> >
> > From: Haibo Chen <haibo.chen at nxp.com>
> >
> > For manual tuning method, already call esdhc_prepare_tuning() config
> > the necessary registers, so remove the redundant code in
> > esdhc_writew_le() for SDHCI_HOST_CONTROL2.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> 
> While discussions on the DT binding, etc, continue with Lucas and Rob on patch
> 3 - do you want me to apply patch1 and patch2?

Yes, thanks!
Let's wait comments for patch 3.

Best Regards
Haibo Chen

> 
> Kind regards
> Uffe
> 
> > ---
> >  drivers/mmc/host/sdhci-esdhc-imx.c | 12 +-----------
> >  1 file changed, 1 insertion(+), 11 deletions(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > index 57b19ca1ad6d..a49fac719fca 100644
> > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > @@ -628,17 +628,7 @@ static void esdhc_writew_le(struct sdhci_host
> *host, u16 val, int reg)
> >                 else
> >                         new_val &=
> ~ESDHC_VENDOR_SPEC_VSELECT;
> >                 writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC);
> > -               if (imx_data->socdata->flags &
> ESDHC_FLAG_MAN_TUNING) {
> > -                       new_val = readl(host->ioaddr +
> ESDHC_MIX_CTRL);
> > -                       if (val & SDHCI_CTRL_TUNED_CLK) {
> > -                               new_val |=
> ESDHC_MIX_CTRL_SMPCLK_SEL;
> > -                               new_val |=
> ESDHC_MIX_CTRL_AUTO_TUNE_EN;
> > -                       } else {
> > -                               new_val &=
> ~ESDHC_MIX_CTRL_SMPCLK_SEL;
> > -                               new_val &=
> ~ESDHC_MIX_CTRL_AUTO_TUNE_EN;
> > -                       }
> > -                       writel(new_val , host->ioaddr +
> ESDHC_MIX_CTRL);
> > -               } else if (imx_data->socdata->flags &
> ESDHC_FLAG_STD_TUNING) {
> > +               if (imx_data->socdata->flags &
> ESDHC_FLAG_STD_TUNING)
> > + {
> >                         u32 v = readl(host->ioaddr +
> SDHCI_AUTO_CMD_STATUS);
> >                         u32 m = readl(host->ioaddr +
> ESDHC_MIX_CTRL);
> >                         if (val & SDHCI_CTRL_TUNED_CLK) {
> > --
> > 2.17.1
> >
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 9571 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210825/80e45423/attachment-0001.p7s>

From stevensd at chromium.org  Tue Aug 24 19:50:05 2021
From: stevensd at chromium.org (David Stevens)
Date: Wed, 25 Aug 2021 11:50:05 +0900
Subject: [PATCH v3 0/4] KVM: allow mapping non-refcounted pages
Message-ID: <20210825025009.2081060-1-stevensd@google.com>

From: David Stevens <stevensd at chromium.org>

This patch series adds support for mapping non-refcount VM_IO and
VM_PFNMAP memory into the guest.

Currently, the gfn_to_pfn functions require being able to pin the target
pfn, so they will fail if the pfn returned by follow_pte isn't a
ref-counted page.  However, the KVM secondary MMUs do not require that
the pfn be pinned, since they are integrated with the mmu notifier API.
This series adds a new set of gfn_to_pfn_page functions which parallel
the gfn_to_pfn functions but do not pin the pfn. The new functions
return the page from gup if it was present, so callers can use it and
call put_page when done.

The gfn_to_pfn functions should be depreciated, since as they are unsafe
due to relying on trying to obtain a struct page from a pfn returned by
follow_pte. I added new functions instead of simply adding another
optional parameter to the existing functions to make it easier to track
down users of the deprecated functions.

This series updates x86 and arm64 secondary MMUs to the new API.

v2 -> v3:
 - rebase on kvm next branch
v1 -> v2:
 - Introduce new gfn_to_pfn_page functions instead of modifying the
   behavior of existing gfn_to_pfn functions, to make the change less
   invasive.
 - Drop changes to mmu_audit.c
 - Include Nicholas Piggin's patch to avoid corrupting refcount in the
   follow_pte case, and use it in depreciated gfn_to_pfn functions.
 - Rebase on kvm/next

David Stevens (4):
  KVM: mmu: introduce new gfn_to_pfn_page functions
  KVM: x86/mmu: use gfn_to_pfn_page
  KVM: arm64/mmu: use gfn_to_pfn_page
  KVM: mmu: remove over-aggressive warnings

 arch/arm64/kvm/mmu.c            |  26 +++--
 arch/x86/kvm/mmu/mmu.c          |  50 +++++----
 arch/x86/kvm/mmu/mmu_internal.h |   3 +-
 arch/x86/kvm/mmu/paging_tmpl.h  |  23 ++--
 arch/x86/kvm/mmu/tdp_mmu.c      |   6 +-
 arch/x86/kvm/mmu/tdp_mmu.h      |   4 +-
 arch/x86/kvm/x86.c              |   6 +-
 include/linux/kvm_host.h        |  17 +++
 virt/kvm/kvm_main.c             | 188 +++++++++++++++++++++++---------
 9 files changed, 220 insertions(+), 103 deletions(-)

-- 
2.33.0.rc2.250.ged5fa647cd-goog



From stevensd at chromium.org  Tue Aug 24 19:50:06 2021
From: stevensd at chromium.org (David Stevens)
Date: Wed, 25 Aug 2021 11:50:06 +0900
Subject: [PATCH v3 1/4] KVM: mmu: introduce new gfn_to_pfn_page functions
In-Reply-To: <20210825025009.2081060-1-stevensd@google.com>
References: <20210825025009.2081060-1-stevensd@google.com>
Message-ID: <20210825025009.2081060-2-stevensd@google.com>

From: David Stevens <stevensd at chromium.org>

Introduce new gfn_to_pfn_page functions that parallel existing
gfn_to_pfn functions. The new functions are identical except they take
an additional out parameter that is used to return the struct page if
the hva was resolved by gup. This allows callers to differentiate the
gup and follow_pte cases, which in turn allows callers to only touch the
page refcount when necessitated by gup.

The old gfn_to_pfn functions are depreciated, and all callers should be
migrated to the new gfn_to_pfn_page functions. In the interim, the
gfn_to_pfn functions are reimplemented as wrappers of the corresponding
gfn_to_pfn_page functions. The wrappers take a reference to the pfn's
page that had previously been taken in hva_to_pfn_remapped.

Signed-off-by: David Stevens <stevensd at chromium.org>
---
 include/linux/kvm_host.h |  17 ++++
 virt/kvm/kvm_main.c      | 186 ++++++++++++++++++++++++++++-----------
 2 files changed, 152 insertions(+), 51 deletions(-)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index e4d712e9f760..2e7400ae4982 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -868,6 +868,19 @@ kvm_pfn_t __gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn,
 			       bool atomic, bool *async, bool write_fault,
 			       bool *writable, hva_t *hva);
 
+kvm_pfn_t gfn_to_pfn_page(struct kvm *kvm, gfn_t gfn, struct page **page);
+kvm_pfn_t gfn_to_pfn_page_prot(struct kvm *kvm, gfn_t gfn,
+			       bool write_fault, bool *writable,
+			       struct page **page);
+kvm_pfn_t gfn_to_pfn_page_memslot(struct kvm_memory_slot *slot,
+				  gfn_t gfn, struct page **page);
+kvm_pfn_t gfn_to_pfn_page_memslot_atomic(struct kvm_memory_slot *slot,
+					 gfn_t gfn, struct page **page);
+kvm_pfn_t __gfn_to_pfn_page_memslot(struct kvm_memory_slot *slot,
+				    gfn_t gfn, bool atomic, bool *async,
+				    bool write_fault, bool *writable,
+				    hva_t *hva, struct page **page);
+
 void kvm_release_pfn_clean(kvm_pfn_t pfn);
 void kvm_release_pfn_dirty(kvm_pfn_t pfn);
 void kvm_set_pfn_dirty(kvm_pfn_t pfn);
@@ -949,6 +962,10 @@ struct kvm_memslots *kvm_vcpu_memslots(struct kvm_vcpu *vcpu);
 struct kvm_memory_slot *kvm_vcpu_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn);
 kvm_pfn_t kvm_vcpu_gfn_to_pfn_atomic(struct kvm_vcpu *vcpu, gfn_t gfn);
 kvm_pfn_t kvm_vcpu_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn);
+kvm_pfn_t kvm_vcpu_gfn_to_pfn_page_atomic(struct kvm_vcpu *vcpu, gfn_t gfn,
+					  struct page **page);
+kvm_pfn_t kvm_vcpu_gfn_to_pfn_page(struct kvm_vcpu *vcpu, gfn_t gfn,
+				   struct page **page);
 int kvm_vcpu_map(struct kvm_vcpu *vcpu, gpa_t gpa, struct kvm_host_map *map);
 int kvm_map_gfn(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map,
 		struct gfn_to_pfn_cache *cache, bool atomic);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 3e67c93ca403..5c47ea93df23 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2216,9 +2216,9 @@ static inline int check_user_page_hwpoison(unsigned long addr)
  * only part that runs if we can in atomic context.
  */
 static bool hva_to_pfn_fast(unsigned long addr, bool write_fault,
-			    bool *writable, kvm_pfn_t *pfn)
+			    bool *writable, kvm_pfn_t *pfn,
+			    struct page **page)
 {
-	struct page *page[1];
 
 	/*
 	 * Fast pin a writable pfn only if it is a write fault request
@@ -2229,7 +2229,7 @@ static bool hva_to_pfn_fast(unsigned long addr, bool write_fault,
 		return false;
 
 	if (get_user_page_fast_only(addr, FOLL_WRITE, page)) {
-		*pfn = page_to_pfn(page[0]);
+		*pfn = page_to_pfn(*page);
 
 		if (writable)
 			*writable = true;
@@ -2244,10 +2244,9 @@ static bool hva_to_pfn_fast(unsigned long addr, bool write_fault,
  * 1 indicates success, -errno is returned if error is detected.
  */
 static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
-			   bool *writable, kvm_pfn_t *pfn)
+			   bool *writable, kvm_pfn_t *pfn, struct page **page)
 {
 	unsigned int flags = FOLL_HWPOISON;
-	struct page *page;
 	int npages = 0;
 
 	might_sleep();
@@ -2260,7 +2259,7 @@ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
 	if (async)
 		flags |= FOLL_NOWAIT;
 
-	npages = get_user_pages_unlocked(addr, 1, &page, flags);
+	npages = get_user_pages_unlocked(addr, 1, page, flags);
 	if (npages != 1)
 		return npages;
 
@@ -2270,11 +2269,11 @@ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
 
 		if (get_user_page_fast_only(addr, FOLL_WRITE, &wpage)) {
 			*writable = true;
-			put_page(page);
-			page = wpage;
+			put_page(*page);
+			*page = wpage;
 		}
 	}
-	*pfn = page_to_pfn(page);
+	*pfn = page_to_pfn(*page);
 	return npages;
 }
 
@@ -2289,13 +2288,6 @@ static bool vma_is_valid(struct vm_area_struct *vma, bool write_fault)
 	return true;
 }
 
-static int kvm_try_get_pfn(kvm_pfn_t pfn)
-{
-	if (kvm_is_reserved_pfn(pfn))
-		return 1;
-	return get_page_unless_zero(pfn_to_page(pfn));
-}
-
 static int hva_to_pfn_remapped(struct vm_area_struct *vma,
 			       unsigned long addr, bool *async,
 			       bool write_fault, bool *writable,
@@ -2335,26 +2327,6 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
 		*writable = pte_write(*ptep);
 	pfn = pte_pfn(*ptep);
 
-	/*
-	 * Get a reference here because callers of *hva_to_pfn* and
-	 * *gfn_to_pfn* ultimately call kvm_release_pfn_clean on the
-	 * returned pfn.  This is only needed if the VMA has VM_MIXEDMAP
-	 * set, but the kvm_get_pfn/kvm_release_pfn_clean pair will
-	 * simply do nothing for reserved pfns.
-	 *
-	 * Whoever called remap_pfn_range is also going to call e.g.
-	 * unmap_mapping_range before the underlying pages are freed,
-	 * causing a call to our MMU notifier.
-	 *
-	 * Certain IO or PFNMAP mappings can be backed with valid
-	 * struct pages, but be allocated without refcounting e.g.,
-	 * tail pages of non-compound higher order allocations, which
-	 * would then underflow the refcount when the caller does the
-	 * required put_page. Don't allow those pages here.
-	 */ 
-	if (!kvm_try_get_pfn(pfn))
-		r = -EFAULT;
-
 out:
 	pte_unmap_unlock(ptep, ptl);
 	*p_pfn = pfn;
@@ -2376,8 +2348,9 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
  * 2): @write_fault = false && @writable, @writable will tell the caller
  *     whether the mapping is writable.
  */
-static kvm_pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async,
-			bool write_fault, bool *writable)
+static kvm_pfn_t hva_to_pfn(unsigned long addr, bool atomic,
+			    bool *async, bool write_fault, bool *writable,
+			    struct page **page)
 {
 	struct vm_area_struct *vma;
 	kvm_pfn_t pfn = 0;
@@ -2386,13 +2359,14 @@ static kvm_pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async,
 	/* we can do it either atomically or asynchronously, not both */
 	BUG_ON(atomic && async);
 
-	if (hva_to_pfn_fast(addr, write_fault, writable, &pfn))
+	if (hva_to_pfn_fast(addr, write_fault, writable, &pfn, page))
 		return pfn;
 
 	if (atomic)
 		return KVM_PFN_ERR_FAULT;
 
-	npages = hva_to_pfn_slow(addr, async, write_fault, writable, &pfn);
+	npages = hva_to_pfn_slow(addr, async, write_fault, writable,
+				 &pfn, page);
 	if (npages == 1)
 		return pfn;
 
@@ -2424,12 +2398,14 @@ static kvm_pfn_t hva_to_pfn(unsigned long addr, bool atomic, bool *async,
 	return pfn;
 }
 
-kvm_pfn_t __gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn,
-			       bool atomic, bool *async, bool write_fault,
-			       bool *writable, hva_t *hva)
+kvm_pfn_t __gfn_to_pfn_page_memslot(struct kvm_memory_slot *slot,
+				    gfn_t gfn, bool atomic, bool *async,
+				    bool write_fault, bool *writable,
+				    hva_t *hva, struct page **page)
 {
 	unsigned long addr = __gfn_to_hva_many(slot, gfn, NULL, write_fault);
 
+	*page = NULL;
 	if (hva)
 		*hva = addr;
 
@@ -2452,45 +2428,153 @@ kvm_pfn_t __gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn,
 	}
 
 	return hva_to_pfn(addr, atomic, async, write_fault,
-			  writable);
+			  writable, page);
+}
+EXPORT_SYMBOL_GPL(__gfn_to_pfn_page_memslot);
+
+kvm_pfn_t gfn_to_pfn_page_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
+			       bool *writable, struct page **page)
+{
+	return __gfn_to_pfn_page_memslot(gfn_to_memslot(kvm, gfn), gfn, false,
+					 NULL, write_fault, writable, NULL,
+					 page);
+}
+EXPORT_SYMBOL_GPL(gfn_to_pfn_page_prot);
+
+kvm_pfn_t gfn_to_pfn_page_memslot(struct kvm_memory_slot *slot, gfn_t gfn,
+				  struct page **page)
+{
+	return __gfn_to_pfn_page_memslot(slot, gfn, false, NULL, true,
+					 NULL, NULL, page);
+}
+EXPORT_SYMBOL_GPL(gfn_to_pfn_page_memslot);
+
+kvm_pfn_t gfn_to_pfn_page_memslot_atomic(struct kvm_memory_slot *slot,
+					 gfn_t gfn, struct page **page)
+{
+	return __gfn_to_pfn_page_memslot(slot, gfn, true, NULL, true, NULL,
+					 NULL, page);
+}
+EXPORT_SYMBOL_GPL(gfn_to_pfn_page_memslot_atomic);
+
+kvm_pfn_t kvm_vcpu_gfn_to_pfn_page_atomic(struct kvm_vcpu *vcpu, gfn_t gfn,
+					  struct page **page)
+{
+	return gfn_to_pfn_page_memslot_atomic(
+			kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn, page);
+}
+EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn_page_atomic);
+
+kvm_pfn_t gfn_to_pfn_page(struct kvm *kvm, gfn_t gfn, struct page **page)
+{
+	return gfn_to_pfn_page_memslot(gfn_to_memslot(kvm, gfn), gfn, page);
+}
+EXPORT_SYMBOL_GPL(gfn_to_pfn_page);
+
+kvm_pfn_t kvm_vcpu_gfn_to_pfn_page(struct kvm_vcpu *vcpu, gfn_t gfn,
+				   struct page **page)
+{
+	return gfn_to_pfn_page_memslot(kvm_vcpu_gfn_to_memslot(vcpu, gfn),
+				       gfn, page);
+}
+EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn_page);
+
+static kvm_pfn_t ensure_pfn_ref(struct page *page, kvm_pfn_t pfn)
+{
+	if (page || is_error_pfn(pfn) || kvm_is_reserved_pfn(pfn))
+		return pfn;
+
+	/*
+	 * Certain IO or PFNMAP mappings can be backed with valid
+	 * struct pages, but be allocated without refcounting e.g.,
+	 * tail pages of non-compound higher order allocations, which
+	 * would then underflow the refcount when the caller does the
+	 * required put_page. Don't allow those pages here.
+	 */
+	if (get_page_unless_zero(pfn_to_page(pfn)))
+		return pfn;
+
+	return KVM_PFN_ERR_FAULT;
+}
+
+kvm_pfn_t __gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn,
+			       bool atomic, bool *async, bool write_fault,
+			       bool *writable, hva_t *hva)
+{
+	struct page *page;
+	kvm_pfn_t pfn;
+
+	pfn = __gfn_to_pfn_page_memslot(slot, gfn, atomic, async,
+					write_fault, writable, hva, &page);
+
+	return ensure_pfn_ref(page, pfn);
 }
 EXPORT_SYMBOL_GPL(__gfn_to_pfn_memslot);
 
 kvm_pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
 		      bool *writable)
 {
-	return __gfn_to_pfn_memslot(gfn_to_memslot(kvm, gfn), gfn, false, NULL,
-				    write_fault, writable, NULL);
+	struct page *page;
+	kvm_pfn_t pfn;
+
+	pfn = gfn_to_pfn_page_prot(kvm, gfn, write_fault, writable, &page);
+
+	return ensure_pfn_ref(page, pfn);
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn_prot);
 
 kvm_pfn_t gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
 {
-	return __gfn_to_pfn_memslot(slot, gfn, false, NULL, true, NULL, NULL);
+	struct page *page;
+	kvm_pfn_t pfn;
+
+	pfn = gfn_to_pfn_page_memslot(slot, gfn, &page);
+
+	return ensure_pfn_ref(page, pfn);
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot);
 
 kvm_pfn_t gfn_to_pfn_memslot_atomic(struct kvm_memory_slot *slot, gfn_t gfn)
 {
-	return __gfn_to_pfn_memslot(slot, gfn, true, NULL, true, NULL, NULL);
+	struct page *page;
+	kvm_pfn_t pfn;
+
+	pfn = gfn_to_pfn_page_memslot_atomic(slot, gfn, &page);
+
+	return ensure_pfn_ref(page, pfn);
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn_memslot_atomic);
 
 kvm_pfn_t kvm_vcpu_gfn_to_pfn_atomic(struct kvm_vcpu *vcpu, gfn_t gfn)
 {
-	return gfn_to_pfn_memslot_atomic(kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn);
+	struct page *page;
+	kvm_pfn_t pfn;
+
+	pfn = kvm_vcpu_gfn_to_pfn_page_atomic(vcpu, gfn, &page);
+
+	return ensure_pfn_ref(page, pfn);
 }
 EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn_atomic);
 
 kvm_pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
 {
-	return gfn_to_pfn_memslot(gfn_to_memslot(kvm, gfn), gfn);
+	struct page *page;
+	kvm_pfn_t pfn;
+
+	pfn = gfn_to_pfn_page(kvm, gfn, &page);
+
+	return ensure_pfn_ref(page, pfn);
 }
 EXPORT_SYMBOL_GPL(gfn_to_pfn);
 
 kvm_pfn_t kvm_vcpu_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn)
 {
-	return gfn_to_pfn_memslot(kvm_vcpu_gfn_to_memslot(vcpu, gfn), gfn);
+	struct page *page;
+	kvm_pfn_t pfn;
+
+	pfn = kvm_vcpu_gfn_to_pfn_page(vcpu, gfn, &page);
+
+	return ensure_pfn_ref(page, pfn);
 }
 EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_pfn);
 
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From stevensd at chromium.org  Tue Aug 24 19:50:07 2021
From: stevensd at chromium.org (David Stevens)
Date: Wed, 25 Aug 2021 11:50:07 +0900
Subject: [PATCH v3 2/4] KVM: x86/mmu: use gfn_to_pfn_page
In-Reply-To: <20210825025009.2081060-1-stevensd@google.com>
References: <20210825025009.2081060-1-stevensd@google.com>
Message-ID: <20210825025009.2081060-3-stevensd@google.com>

From: David Stevens <stevensd at chromium.org>

Covert usages of the deprecated gfn_to_pfn functions to the new
gfn_to_pfn_page functions.

Signed-off-by: David Stevens <stevensd at chromium.org>
---
 arch/x86/kvm/mmu/mmu.c          | 43 ++++++++++++++++++++-------------
 arch/x86/kvm/mmu/mmu_internal.h |  3 ++-
 arch/x86/kvm/mmu/paging_tmpl.h  | 23 +++++++++++-------
 arch/x86/kvm/mmu/tdp_mmu.c      |  6 ++---
 arch/x86/kvm/mmu/tdp_mmu.h      |  4 +--
 arch/x86/kvm/x86.c              |  6 +++--
 6 files changed, 51 insertions(+), 34 deletions(-)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index c04e30f6e0db..d2b99c2f7dfa 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -2789,8 +2789,9 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
 	return ret;
 }
 
-static kvm_pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn,
-				     bool no_dirty_log)
+static kvm_pfn_t pte_prefetch_gfn_to_pfn_page(struct kvm_vcpu *vcpu,
+					      gfn_t gfn, bool no_dirty_log,
+					      struct page **page)
 {
 	struct kvm_memory_slot *slot;
 
@@ -2798,7 +2799,7 @@ static kvm_pfn_t pte_prefetch_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn,
 	if (!slot)
 		return KVM_PFN_ERR_FAULT;
 
-	return gfn_to_pfn_memslot_atomic(slot, gfn);
+	return gfn_to_pfn_page_memslot_atomic(slot, gfn, page);
 }
 
 static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu,
@@ -2929,7 +2930,8 @@ int kvm_mmu_max_mapping_level(struct kvm *kvm,
 
 int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn,
 			    int max_level, kvm_pfn_t *pfnp,
-			    bool huge_page_disallowed, int *req_level)
+			    struct page *page, bool huge_page_disallowed,
+			    int *req_level)
 {
 	struct kvm_memory_slot *slot;
 	kvm_pfn_t pfn = *pfnp;
@@ -2941,6 +2943,9 @@ int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn,
 	if (unlikely(max_level == PG_LEVEL_4K))
 		return PG_LEVEL_4K;
 
+	if (!page)
+		return PG_LEVEL_4K;
+
 	if (is_error_noslot_pfn(pfn) || kvm_is_reserved_pfn(pfn))
 		return PG_LEVEL_4K;
 
@@ -2990,7 +2995,8 @@ void disallowed_hugepage_adjust(u64 spte, gfn_t gfn, int cur_level,
 }
 
 static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
-			int map_writable, int max_level, kvm_pfn_t pfn,
+			int map_writable, int max_level,
+			kvm_pfn_t pfn, struct page *page,
 			bool prefault, bool is_tdp)
 {
 	bool nx_huge_page_workaround_enabled = is_nx_huge_page_enabled();
@@ -3003,7 +3009,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
 	gfn_t gfn = gpa >> PAGE_SHIFT;
 	gfn_t base_gfn = gfn;
 
-	level = kvm_mmu_hugepage_adjust(vcpu, gfn, max_level, &pfn,
+	level = kvm_mmu_hugepage_adjust(vcpu, gfn, max_level, &pfn, page,
 					huge_page_disallowed, &req_level);
 
 	trace_kvm_mmu_spte_requested(gpa, level, pfn);
@@ -3899,8 +3905,9 @@ static bool kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
 }
 
 static bool kvm_faultin_pfn(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
-			 gpa_t cr2_or_gpa, kvm_pfn_t *pfn, hva_t *hva,
-			 bool write, bool *writable, int *r)
+			 gpa_t cr2_or_gpa, kvm_pfn_t *pfn,
+			 hva_t *hva, bool write, bool *writable,
+			 struct page **page, int *r)
 {
 	struct kvm_memory_slot *slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
 	bool async;
@@ -3934,8 +3941,8 @@ static bool kvm_faultin_pfn(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
 	}
 
 	async = false;
-	*pfn = __gfn_to_pfn_memslot(slot, gfn, false, &async,
-				    write, writable, hva);
+	*pfn = __gfn_to_pfn_page_memslot(slot, gfn, false, &async,
+					 write, writable, hva, page);
 	if (!async)
 		return false; /* *pfn has correct page already */
 
@@ -3949,8 +3956,8 @@ static bool kvm_faultin_pfn(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
 			goto out_retry;
 	}
 
-	*pfn = __gfn_to_pfn_memslot(slot, gfn, false, NULL,
-				    write, writable, hva);
+	*pfn = __gfn_to_pfn_page_memslot(slot, gfn, false, NULL,
+					 write, writable, hva, page);
 
 out_retry:
 	*r = RET_PF_RETRY;
@@ -3967,6 +3974,7 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
 	gfn_t gfn = gpa >> PAGE_SHIFT;
 	unsigned long mmu_seq;
 	kvm_pfn_t pfn;
+	struct page *page;
 	hva_t hva;
 	int r;
 
@@ -3985,7 +3993,7 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
 	smp_rmb();
 
 	if (kvm_faultin_pfn(vcpu, prefault, gfn, gpa, &pfn, &hva,
-			 write, &map_writable, &r))
+			 write, &map_writable, &page, &r))
 		return r;
 
 	if (handle_abnormal_pfn(vcpu, is_tdp ? 0 : gpa, gfn, pfn, ACC_ALL, &r))
@@ -4006,17 +4014,18 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
 
 	if (is_tdp_mmu_fault)
 		r = kvm_tdp_mmu_map(vcpu, gpa, error_code, map_writable, max_level,
-				    pfn, prefault);
+				    pfn, page, prefault);
 	else
-		r = __direct_map(vcpu, gpa, error_code, map_writable, max_level, pfn,
-				 prefault, is_tdp);
+		r = __direct_map(vcpu, gpa, error_code, map_writable, max_level,
+				 pfn, page, prefault, is_tdp);
 
 out_unlock:
 	if (is_tdp_mmu_fault)
 		read_unlock(&vcpu->kvm->mmu_lock);
 	else
 		write_unlock(&vcpu->kvm->mmu_lock);
-	kvm_release_pfn_clean(pfn);
+	if (page)
+		put_page(page);
 	return r;
 }
 
diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h
index 62bb8f758b3f..bd3cfeb6420f 100644
--- a/arch/x86/kvm/mmu/mmu_internal.h
+++ b/arch/x86/kvm/mmu/mmu_internal.h
@@ -163,7 +163,8 @@ int kvm_mmu_max_mapping_level(struct kvm *kvm,
 			      kvm_pfn_t pfn, int max_level);
 int kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, gfn_t gfn,
 			    int max_level, kvm_pfn_t *pfnp,
-			    bool huge_page_disallowed, int *req_level);
+			    struct page *page, bool huge_page_disallowed,
+			    int *req_level);
 void disallowed_hugepage_adjust(u64 spte, gfn_t gfn, int cur_level,
 				kvm_pfn_t *pfnp, int *goal_levelp);
 
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
index 7d03e9b7ccfa..4a61b96fcdef 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -564,6 +564,7 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
 	unsigned pte_access;
 	gfn_t gfn;
 	kvm_pfn_t pfn;
+	struct page *page;
 
 	if (FNAME(prefetch_invalid_gpte)(vcpu, sp, spte, gpte))
 		return false;
@@ -573,8 +574,8 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
 	gfn = gpte_to_gfn(gpte);
 	pte_access = sp->role.access & FNAME(gpte_access)(gpte);
 	FNAME(protect_clean_gpte)(vcpu->arch.mmu, &pte_access, gpte);
-	pfn = pte_prefetch_gfn_to_pfn(vcpu, gfn,
-			no_dirty_log && (pte_access & ACC_WRITE_MASK));
+	pfn = pte_prefetch_gfn_to_pfn_page(vcpu, gfn,
+			no_dirty_log && (pte_access & ACC_WRITE_MASK), &page);
 	if (is_error_pfn(pfn))
 		return false;
 
@@ -585,7 +586,8 @@ FNAME(prefetch_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
 	mmu_set_spte(vcpu, spte, pte_access, false, PG_LEVEL_4K, gfn, pfn,
 		     true, true);
 
-	kvm_release_pfn_clean(pfn);
+	if (page)
+		put_page(page);
 	return true;
 }
 
@@ -665,8 +667,8 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,
  */
 static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr,
 			 struct guest_walker *gw, u32 error_code,
-			 int max_level, kvm_pfn_t pfn, bool map_writable,
-			 bool prefault)
+			 int max_level, kvm_pfn_t pfn, struct page *page,
+			 bool map_writable, bool prefault)
 {
 	bool nx_huge_page_workaround_enabled = is_nx_huge_page_enabled();
 	bool write_fault = error_code & PFERR_WRITE_MASK;
@@ -723,7 +725,8 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr,
 	}
 
 	level = kvm_mmu_hugepage_adjust(vcpu, gw->gfn, max_level, &pfn,
-					huge_page_disallowed, &req_level);
+					page, huge_page_disallowed,
+					&req_level);
 
 	trace_kvm_mmu_spte_requested(addr, gw->level, pfn);
 
@@ -830,6 +833,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gpa_t addr, u32 error_code,
 	struct guest_walker walker;
 	int r;
 	kvm_pfn_t pfn;
+	struct page *page;
 	hva_t hva;
 	unsigned long mmu_seq;
 	bool map_writable, is_self_change_mapping;
@@ -882,7 +886,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gpa_t addr, u32 error_code,
 	smp_rmb();
 
 	if (kvm_faultin_pfn(vcpu, prefault, walker.gfn, addr, &pfn, &hva,
-			 write_fault, &map_writable, &r))
+			 write_fault, &map_writable, &page, &r))
 		return r;
 
 	if (handle_abnormal_pfn(vcpu, addr, walker.gfn, pfn, walker.pte_access, &r))
@@ -916,13 +920,14 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gpa_t addr, u32 error_code,
 	r = make_mmu_pages_available(vcpu);
 	if (r)
 		goto out_unlock;
-	r = FNAME(fetch)(vcpu, addr, &walker, error_code, max_level, pfn,
+	r = FNAME(fetch)(vcpu, addr, &walker, error_code, max_level, pfn, page,
 			 map_writable, prefault);
 	kvm_mmu_audit(vcpu, AUDIT_POST_PAGE_FAULT);
 
 out_unlock:
 	write_unlock(&vcpu->kvm->mmu_lock);
-	kvm_release_pfn_clean(pfn);
+	if (page)
+		put_page(page);
 	return r;
 }
 
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 64ccfc1fa553..dec735081c5e 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -987,8 +987,8 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write,
  * page tables and SPTEs to translate the faulting guest physical address.
  */
 int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
-		    int map_writable, int max_level, kvm_pfn_t pfn,
-		    bool prefault)
+		    int map_writable, int max_level,
+		    kvm_pfn_t pfn, struct page *page, bool prefault)
 {
 	bool nx_huge_page_workaround_enabled = is_nx_huge_page_enabled();
 	bool write = error_code & PFERR_WRITE_MASK;
@@ -1004,7 +1004,7 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
 	int level;
 	int req_level;
 
-	level = kvm_mmu_hugepage_adjust(vcpu, gfn, max_level, &pfn,
+	level = kvm_mmu_hugepage_adjust(vcpu, gfn, max_level, &pfn, page,
 					huge_page_disallowed, &req_level);
 
 	trace_kvm_mmu_spte_requested(gpa, level, pfn);
diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h
index 358f447d4012..75526618601a 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.h
+++ b/arch/x86/kvm/mmu/tdp_mmu.h
@@ -49,8 +49,8 @@ void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm);
 void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm);
 
 int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code,
-		    int map_writable, int max_level, kvm_pfn_t pfn,
-		    bool prefault);
+		    int map_writable, int max_level,
+		    kvm_pfn_t pfn, struct page *page, bool prefault);
 
 bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range,
 				 bool flush);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1a00af1b076b..9b32ce593f1b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7523,6 +7523,7 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
 {
 	gpa_t gpa = cr2_or_gpa;
 	kvm_pfn_t pfn;
+	struct page *page;
 
 	if (!(emulation_type & EMULTYPE_ALLOW_RETRY_PF))
 		return false;
@@ -7552,7 +7553,7 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
 	 * retry instruction -> write #PF -> emulation fail -> retry
 	 * instruction -> ...
 	 */
-	pfn = gfn_to_pfn(vcpu->kvm, gpa_to_gfn(gpa));
+	pfn = gfn_to_pfn_page(vcpu->kvm, gpa_to_gfn(gpa), &page);
 
 	/*
 	 * If the instruction failed on the error pfn, it can not be fixed,
@@ -7561,7 +7562,8 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
 	if (is_error_noslot_pfn(pfn))
 		return false;
 
-	kvm_release_pfn_clean(pfn);
+	if (page)
+		put_page(page);
 
 	/* The instructions are well-emulated on direct mmu. */
 	if (vcpu->arch.mmu->direct_map) {
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From stevensd at chromium.org  Tue Aug 24 19:50:08 2021
From: stevensd at chromium.org (David Stevens)
Date: Wed, 25 Aug 2021 11:50:08 +0900
Subject: [PATCH v3 3/4] KVM: arm64/mmu: use gfn_to_pfn_page
In-Reply-To: <20210825025009.2081060-1-stevensd@google.com>
References: <20210825025009.2081060-1-stevensd@google.com>
Message-ID: <20210825025009.2081060-4-stevensd@google.com>

From: David Stevens <stevensd at chromium.org>

Covert usages of the deprecated gfn_to_pfn functions to the new
gfn_to_pfn_page functions.

Signed-off-by: David Stevens <stevensd at chromium.org>
---
 arch/arm64/kvm/mmu.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 0625bf2353c2..56859999b211 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -782,7 +782,7 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
 static unsigned long
 transparent_hugepage_adjust(struct kvm_memory_slot *memslot,
 			    unsigned long hva, kvm_pfn_t *pfnp,
-			    phys_addr_t *ipap)
+			    struct page **page, phys_addr_t *ipap)
 {
 	kvm_pfn_t pfn = *pfnp;
 
@@ -791,7 +791,7 @@ transparent_hugepage_adjust(struct kvm_memory_slot *memslot,
 	 * sure that the HVA and IPA are sufficiently aligned and that the
 	 * block map is contained within the memslot.
 	 */
-	if (kvm_is_transparent_hugepage(pfn) &&
+	if (*page && kvm_is_transparent_hugepage(pfn) &&
 	    fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE)) {
 		/*
 		 * The address we faulted on is backed by a transparent huge
@@ -812,10 +812,11 @@ transparent_hugepage_adjust(struct kvm_memory_slot *memslot,
 		 * page accordingly.
 		 */
 		*ipap &= PMD_MASK;
-		kvm_release_pfn_clean(pfn);
+		put_page(*page);
 		pfn &= ~(PTRS_PER_PMD - 1);
-		kvm_get_pfn(pfn);
 		*pfnp = pfn;
+		*page = pfn_to_page(pfn);
+		get_page(*page);
 
 		return PMD_SIZE;
 	}
@@ -908,6 +909,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	short vma_shift;
 	gfn_t gfn;
 	kvm_pfn_t pfn;
+	struct page *page;
 	bool logging_active = memslot_is_logging(memslot);
 	unsigned long fault_level = kvm_vcpu_trap_get_fault_level(vcpu);
 	unsigned long vma_pagesize, fault_granule;
@@ -1009,8 +1011,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 */
 	smp_rmb();
 
-	pfn = __gfn_to_pfn_memslot(memslot, gfn, false, NULL,
-				   write_fault, &writable, NULL);
+	pfn = __gfn_to_pfn_page_memslot(memslot, gfn, false, NULL,
+					write_fault, &writable, NULL, &page);
 	if (pfn == KVM_PFN_ERR_HWPOISON) {
 		kvm_send_hwpoison_signal(hva, vma_shift);
 		return 0;
@@ -1052,7 +1054,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 */
 	if (vma_pagesize == PAGE_SIZE && !(force_pte || device))
 		vma_pagesize = transparent_hugepage_adjust(memslot, hva,
-							   &pfn, &fault_ipa);
+							   &pfn, &page,
+							   &fault_ipa);
 
 	if (fault_status != FSC_PERM && !device && kvm_has_mte(kvm)) {
 		/* Check the VMM hasn't introduced a new VM_SHARED VMA */
@@ -1090,14 +1093,17 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 
 	/* Mark the page dirty only if the fault is handled successfully */
 	if (writable && !ret) {
-		kvm_set_pfn_dirty(pfn);
+		if (page)
+			kvm_set_pfn_dirty(pfn);
 		mark_page_dirty_in_slot(kvm, memslot, gfn);
 	}
 
 out_unlock:
 	spin_unlock(&kvm->mmu_lock);
-	kvm_set_pfn_accessed(pfn);
-	kvm_release_pfn_clean(pfn);
+	if (page) {
+		kvm_set_pfn_accessed(pfn);
+		put_page(page);
+	}
 	return ret != -EAGAIN ? ret : 0;
 }
 
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From stevensd at chromium.org  Tue Aug 24 19:50:09 2021
From: stevensd at chromium.org (David Stevens)
Date: Wed, 25 Aug 2021 11:50:09 +0900
Subject: [PATCH v3 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <20210825025009.2081060-1-stevensd@google.com>
References: <20210825025009.2081060-1-stevensd@google.com>
Message-ID: <20210825025009.2081060-5-stevensd@google.com>

From: David Stevens <stevensd at chromium.org>

Remove two warnings that require ref counts for pages to be non-zero, as
mapped pfns from follow_pfn may not have an initialized ref count.

Signed-off-by: David Stevens <stevensd at chromium.org>
---
 arch/x86/kvm/mmu/mmu.c | 7 -------
 virt/kvm/kvm_main.c    | 2 +-
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index d2b99c2f7dfa..88ceded7f022 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -623,13 +623,6 @@ static int mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep)
 
 	pfn = spte_to_pfn(old_spte);
 
-	/*
-	 * KVM does not hold the refcount of the page used by
-	 * kvm mmu, before reclaiming the page, we should
-	 * unmap it from mmu first.
-	 */
-	WARN_ON(!kvm_is_reserved_pfn(pfn) && !page_count(pfn_to_page(pfn)));
-
 	if (is_accessed_spte(old_spte))
 		kvm_set_pfn_accessed(pfn);
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 5c47ea93df23..e5ddf238ec64 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -168,7 +168,7 @@ bool kvm_is_zone_device_pfn(kvm_pfn_t pfn)
 	 * the device has been pinned, e.g. by get_user_pages().  WARN if the
 	 * page_count() is zero to help detect bad usage of this helper.
 	 */
-	if (!pfn_valid(pfn) || WARN_ON_ONCE(!page_count(pfn_to_page(pfn))))
+	if (!pfn_valid(pfn) || !page_count(pfn_to_page(pfn)))
 		return false;
 
 	return is_zone_device_page(pfn_to_page(pfn));
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:41 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:41 +0800
Subject: [RESEND v4 13/15] iio: adc: aspeed: Add compensation phase.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <202108250006.17P06E93096992@twspam01.aspeedtech.com>

This patch adds a compensation phase to improve the accurate of ADC
measurement. This is the built-in function though input half of the
reference voltage to get the ADC offset.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 54 +++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 4d979dd7fe88..20caf28dff18 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -95,6 +95,7 @@ struct aspeed_adc_data {
 	struct reset_control	*rst;
 	int			vref;
 	u32			sample_period_ns;
+	int			cv;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -104,7 +105,8 @@ struct aspeed_adc_data {
 	.address = (_data_reg_addr),				\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
-				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+				BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
+				BIT(IIO_CHAN_INFO_OFFSET),	\
 }
 
 static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
@@ -126,6 +128,51 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+static int aspeed_adc_compensation(struct iio_dev *indio_dev)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	u32 index, adc_raw = 0;
+	u32 adc_engine_control_reg_val;
+
+	adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+	adc_engine_control_reg_val &= ~ASPEED_ADC_OP_MODE;
+	adc_engine_control_reg_val |=
+		(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
+		 ASPEED_ADC_ENGINE_ENABLE);
+	/*
+	 * Enable compensating sensing:
+	 * After that, the input voltage of ADC will force to half of the reference
+	 * voltage. So the expected reading raw data will become half of the max
+	 * value. We can get compensating value = 0x200 - ADC read raw value.
+	 * It is recommended to average at least 10 samples to get a final CV.
+	 */
+	writel(adc_engine_control_reg_val | ASPEED_ADC_CTRL_COMPENSATION |
+		       ASPEED_ADC_CTRL_CHANNEL_ENABLE(0),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
+	/*
+	 * After enable compensating sensing mode need to wait some time for ADC stable
+	 * Experiment result is 1ms.
+	 */
+	mdelay(1);
+
+	for (index = 0; index < 16; index++) {
+		/*
+		 * Waiting for the sampling period ensures that the value acquired
+		 * is fresh each time.
+		 */
+		ndelay(data->sample_period_ns);
+		adc_raw += readw(data->base + aspeed_adc_iio_channels[0].address);
+	}
+	adc_raw >>= 4;
+	data->cv = BIT(ASPEED_RESOLUTION_BITS - 1) - adc_raw;
+	writel(adc_engine_control_reg_val,
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
+	dev_dbg(data->dev, "Compensating value = %d\n", data->cv);
+
+	return 0;
+}
+
 static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -155,6 +202,10 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		*val = readw(data->base + chan->address);
 		return IIO_VAL_INT;
 
+	case IIO_CHAN_INFO_OFFSET:
+		*val = data->cv;
+		return IIO_VAL_INT;
+
 	case IIO_CHAN_INFO_SCALE:
 		*val = data->vref;
 		*val2 = ASPEED_RESOLUTION_BITS;
@@ -444,6 +495,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			return ret;
 	}
 
+	aspeed_adc_compensation(indio_dev);
 	/* Start all channels in normal mode. */
 	adc_engine_control_reg_val =
 		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:43 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:43 +0800
Subject: [RESEND v4 15/15] iio: adc: aspeed: Get and set trimming data.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <202108250004.17P040gC093711@twspam01.aspeedtech.com>

The adc controller have trimming register for fine-tune the reference
voltage. The trimming value come from the otp register which will be
written before chip product. This patch will read this otp value and
configure it to the adc register when adc controller probe and using dts
property "aspeed,trim-data-valid" to determine whether to execute this
flow.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 68 ++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 0c5d84e82561..bd7fb23f3510 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -25,6 +25,8 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/bitfield.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
@@ -72,6 +74,11 @@
  */
 #define ASPEED_ADC_DEF_SAMPLING_RATE	65000
 
+struct aspeed_adc_trim_locate {
+	const unsigned int offset;
+	const unsigned int field;
+};
+
 struct aspeed_adc_model_data {
 	const char *model_name;
 	unsigned int min_sampling_rate;	// Hz
@@ -82,6 +89,7 @@ struct aspeed_adc_model_data {
 	bool bat_sense_sup;
 	u8 scaler_bit_width;
 	unsigned int num_channels;
+	const struct aspeed_adc_trim_locate *trim_locate;
 };
 
 struct adc_gain {
@@ -136,6 +144,44 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev)
+{
+	struct device_node *syscon;
+	struct regmap *scu;
+	u32 scu_otp, trimming_val;
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	syscon = of_find_node_by_name(NULL, "syscon");
+	if (syscon == NULL) {
+		dev_warn(data->dev, "Couldn't find syscon node\n");
+		return -EOPNOTSUPP;
+	}
+	scu = syscon_node_to_regmap(syscon);
+	if (IS_ERR(scu)) {
+		dev_warn(data->dev, "Failed to get syscon regmap\n");
+		return -EOPNOTSUPP;
+	}
+	if (data->model_data->trim_locate) {
+		if (regmap_read(scu, data->model_data->trim_locate->offset,
+				&scu_otp)) {
+			dev_warn(data->dev,
+				 "Failed to get adc trimming data\n");
+			trimming_val = 0x8;
+		} else {
+			trimming_val =
+				((scu_otp) &
+				 (data->model_data->trim_locate->field)) >>
+				__ffs(data->model_data->trim_locate->field);
+		}
+		dev_dbg(data->dev,
+			"trimming val = %d, offset = %08x, fields = %08x\n",
+			trimming_val, data->model_data->trim_locate->offset,
+			data->model_data->trim_locate->field);
+		writel(trimming_val, data->base + ASPEED_REG_COMPENSATION_TRIM);
+	}
+	return 0;
+}
+
 static int aspeed_adc_compensation(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -506,6 +552,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid",
+			     NULL))
+		aspeed_adc_set_trim_data(indio_dev);
+
 	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
 			     NULL)) {
 		if (data->model_data->bat_sense_sup) {
@@ -579,6 +629,21 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct aspeed_adc_trim_locate ast2500_adc_trim = {
+	.offset = 0x154,
+	.field = GENMASK(31, 28),
+};
+
+static const struct aspeed_adc_trim_locate ast2600_adc0_trim = {
+	.offset = 0x5d0,
+	.field = GENMASK(3, 0),
+};
+
+static const struct aspeed_adc_trim_locate ast2600_adc1_trim = {
+	.offset = 0x5d0,
+	.field = GENMASK(7, 4),
+};
+
 static const struct aspeed_adc_model_data ast2400_model_data = {
 	.model_name = "ast2400-adc",
 	.vref_fixed = 2500, // mV
@@ -598,6 +663,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
 	.need_prescaler = true,
 	.scaler_bit_width = 10,
 	.num_channels = 16,
+	.trim_locate = &ast2500_adc_trim,
 };
 
 static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
@@ -608,6 +674,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
 	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
+	.trim_locate = &ast2600_adc0_trim,
 };
 
 static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
@@ -618,6 +685,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
 	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
+	.trim_locate = &ast2600_adc1_trim,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:37 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:37 +0800
Subject: [RESEND v4 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <202108250008.17P085Ci097521@twspam01.aspeedtech.com>

This patch use devm_add_action_or_reset to handle the error in probe
phase.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 92 +++++++++++++++++++++---------------
 1 file changed, 55 insertions(+), 37 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 52db38be9699..1c87e12a0cab 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -187,6 +187,27 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static void aspeed_adc_unregister_divider(void *data)
+{
+	struct clk_hw *clk = data;
+
+	clk_hw_unregister_divider(clk);
+}
+
+static void aspeed_adc_reset_assert(void *data)
+{
+	struct reset_control *rst = data;
+
+	reset_control_assert(rst);
+}
+
+static void aspeed_adc_clk_disable_unprepare(void *data)
+{
+	struct clk *clk = data;
+
+	clk_disable_unprepare(clk);
+}
+
 static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			&data->clk_lock);
 		if (IS_ERR(data->clk_prescaler))
 			return PTR_ERR(data->clk_prescaler);
+
+		ret = devm_add_action_or_reset(data->dev,
+					       aspeed_adc_unregister_divider,
+					       data->clk_prescaler);
+		if (ret)
+			return ret;
 		snprintf(clk_parent_name, 32, clk_name);
 		scaler_flags = CLK_SET_RATE_PARENT;
 	}
@@ -244,23 +271,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
 		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
 		data->model_data->scaler_bit_width, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_scaler)) {
-		ret = PTR_ERR(data->clk_scaler);
-		goto scaler_error;
-	}
+	if (IS_ERR(data->clk_scaler))
+		return PTR_ERR(data->clk_scaler);
+
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
+				       data->clk_scaler);
+	if (ret)
+		return ret;
 
 	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(data->rst)) {
 		dev_err(&pdev->dev,
 			"invalid or missing reset controller device tree entry");
-		ret = PTR_ERR(data->rst);
-		goto reset_error;
+		return PTR_ERR(data->rst);
 	}
 	reset_control_deassert(data->rst);
 
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
+				       data->rst);
+	if (ret)
+		return ret;
+
 	ret = aspeed_adc_vref_config(indio_dev);
 	if (ret)
-		goto vref_config_error;
+		return ret;
 
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
@@ -277,13 +311,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 					 ASPEED_ADC_INIT_POLLING_TIME,
 					 ASPEED_ADC_INIT_TIMEOUT);
 		if (ret)
-			goto poll_timeout_error;
+			return ret;
 	}
 
 	/* Start all channels in normal mode. */
 	ret = clk_prepare_enable(data->clk_scaler->clk);
 	if (ret)
-		goto clk_enable_error;
+		return ret;
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_clk_disable_unprepare,
+				       data->clk_scaler->clk);
+	if (ret)
+		return ret;
 
 	adc_engine_control_reg_val =
 		ASPEED_ADC_CTRL_CHANNEL |
@@ -299,41 +339,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto iio_register_error;
-
+	if (ret) {
+		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+				  ASPEED_ADC_OP_MODE_PWR_DOWN),
+		       data->base + ASPEED_REG_ENGINE_CONTROL);
+		return ret;
+	}
 	return 0;
-
-iio_register_error:
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-clk_enable_error:
-poll_timeout_error:
-vref_config_error:
-	reset_control_assert(data->rst);
-reset_error:
-	clk_hw_unregister_divider(data->clk_scaler);
-scaler_error:
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-	return ret;
 }
 
 static int aspeed_adc_remove(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-	struct aspeed_adc_data *data = iio_priv(indio_dev);
-
 	iio_device_unregister(indio_dev);
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-	reset_control_assert(data->rst);
-	clk_hw_unregister_divider(data->clk_scaler);
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-
 	return 0;
 }
 
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:36 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:36 +0800
Subject: [RESEND v4 08/15] iio: adc: aspeed: Use model_data to set clk scaler.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <202108250006.17P064s6096708@twspam01.aspeedtech.com>

This patch use need_prescaler and scaler_bit_width to set the adc clock
scaler.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 39 +++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 2d6215a91f99..52db38be9699 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -202,9 +202,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
 	struct aspeed_adc_data *data;
-	const char *clk_parent_name;
 	int ret;
 	u32 adc_engine_control_reg_val;
+	unsigned long scaler_flags = 0;
+	char clk_name[32], clk_parent_name[32];
 
 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
 	if (!indio_dev)
@@ -221,24 +222,28 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	/* Register ADC clock prescaler with source specified by device tree. */
 	spin_lock_init(&data->clk_lock);
-	clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
-
-	data->clk_prescaler = clk_hw_register_divider(
-				&pdev->dev, "prescaler", clk_parent_name, 0,
-				data->base + ASPEED_REG_CLOCK_CONTROL,
-				17, 15, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_prescaler))
-		return PTR_ERR(data->clk_prescaler);
-
+	snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));
+	if (data->model_data->need_prescaler) {
+		snprintf(clk_name, 32, "%s-prescaler",
+			 data->model_data->model_name);
+		data->clk_prescaler = clk_hw_register_divider(
+			&pdev->dev, clk_name, clk_parent_name, 0,
+			data->base + ASPEED_REG_CLOCK_CONTROL, 17, 15, 0,
+			&data->clk_lock);
+		if (IS_ERR(data->clk_prescaler))
+			return PTR_ERR(data->clk_prescaler);
+		snprintf(clk_parent_name, 32, clk_name);
+		scaler_flags = CLK_SET_RATE_PARENT;
+	}
 	/*
 	 * Register ADC clock scaler downstream from the prescaler. Allow rate
 	 * setting to adjust the prescaler as well.
 	 */
+	snprintf(clk_name, 32, "%s-scaler", data->model_data->model_name);
 	data->clk_scaler = clk_hw_register_divider(
-				&pdev->dev, "scaler", "prescaler",
-				CLK_SET_RATE_PARENT,
-				data->base + ASPEED_REG_CLOCK_CONTROL,
-				0, 10, 0, &data->clk_lock);
+		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
+		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
+		data->model_data->scaler_bit_width, 0, &data->clk_lock);
 	if (IS_ERR(data->clk_scaler)) {
 		ret = PTR_ERR(data->clk_scaler);
 		goto scaler_error;
@@ -310,7 +315,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 reset_error:
 	clk_hw_unregister_divider(data->clk_scaler);
 scaler_error:
-	clk_hw_unregister_divider(data->clk_prescaler);
+	if (data->model_data->need_prescaler)
+		clk_hw_unregister_divider(data->clk_prescaler);
 	return ret;
 }
 
@@ -325,7 +331,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
 	clk_hw_unregister_divider(data->clk_scaler);
-	clk_hw_unregister_divider(data->clk_prescaler);
+	if (data->model_data->need_prescaler)
+		clk_hw_unregister_divider(data->clk_prescaler);
 
 	return 0;
 }
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 24 02:12:43 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 24 Aug 2021 17:12:43 +0800
Subject: [RESEND v4 15/15] iio: adc: aspeed: Get and set trimming data.
In-Reply-To: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
Message-ID: <202108250007.17P07A2s097404@twspam01.aspeedtech.com>

The adc controller have trimming register for fine-tune the reference
voltage. The trimming value come from the otp register which will be
written before chip product. This patch will read this otp value and
configure it to the adc register when adc controller probe and using dts
property "aspeed,trim-data-valid" to determine whether to execute this
flow.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 68 ++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 0c5d84e82561..bd7fb23f3510 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -25,6 +25,8 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/bitfield.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
@@ -72,6 +74,11 @@
  */
 #define ASPEED_ADC_DEF_SAMPLING_RATE	65000
 
+struct aspeed_adc_trim_locate {
+	const unsigned int offset;
+	const unsigned int field;
+};
+
 struct aspeed_adc_model_data {
 	const char *model_name;
 	unsigned int min_sampling_rate;	// Hz
@@ -82,6 +89,7 @@ struct aspeed_adc_model_data {
 	bool bat_sense_sup;
 	u8 scaler_bit_width;
 	unsigned int num_channels;
+	const struct aspeed_adc_trim_locate *trim_locate;
 };
 
 struct adc_gain {
@@ -136,6 +144,44 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev)
+{
+	struct device_node *syscon;
+	struct regmap *scu;
+	u32 scu_otp, trimming_val;
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	syscon = of_find_node_by_name(NULL, "syscon");
+	if (syscon == NULL) {
+		dev_warn(data->dev, "Couldn't find syscon node\n");
+		return -EOPNOTSUPP;
+	}
+	scu = syscon_node_to_regmap(syscon);
+	if (IS_ERR(scu)) {
+		dev_warn(data->dev, "Failed to get syscon regmap\n");
+		return -EOPNOTSUPP;
+	}
+	if (data->model_data->trim_locate) {
+		if (regmap_read(scu, data->model_data->trim_locate->offset,
+				&scu_otp)) {
+			dev_warn(data->dev,
+				 "Failed to get adc trimming data\n");
+			trimming_val = 0x8;
+		} else {
+			trimming_val =
+				((scu_otp) &
+				 (data->model_data->trim_locate->field)) >>
+				__ffs(data->model_data->trim_locate->field);
+		}
+		dev_dbg(data->dev,
+			"trimming val = %d, offset = %08x, fields = %08x\n",
+			trimming_val, data->model_data->trim_locate->offset,
+			data->model_data->trim_locate->field);
+		writel(trimming_val, data->base + ASPEED_REG_COMPENSATION_TRIM);
+	}
+	return 0;
+}
+
 static int aspeed_adc_compensation(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -506,6 +552,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid",
+			     NULL))
+		aspeed_adc_set_trim_data(indio_dev);
+
 	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
 			     NULL)) {
 		if (data->model_data->bat_sense_sup) {
@@ -579,6 +629,21 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct aspeed_adc_trim_locate ast2500_adc_trim = {
+	.offset = 0x154,
+	.field = GENMASK(31, 28),
+};
+
+static const struct aspeed_adc_trim_locate ast2600_adc0_trim = {
+	.offset = 0x5d0,
+	.field = GENMASK(3, 0),
+};
+
+static const struct aspeed_adc_trim_locate ast2600_adc1_trim = {
+	.offset = 0x5d0,
+	.field = GENMASK(7, 4),
+};
+
 static const struct aspeed_adc_model_data ast2400_model_data = {
 	.model_name = "ast2400-adc",
 	.vref_fixed = 2500, // mV
@@ -598,6 +663,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
 	.need_prescaler = true,
 	.scaler_bit_width = 10,
 	.num_channels = 16,
+	.trim_locate = &ast2500_adc_trim,
 };
 
 static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
@@ -608,6 +674,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
 	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
+	.trim_locate = &ast2600_adc0_trim,
 };
 
 static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
@@ -618,6 +685,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
 	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
+	.trim_locate = &ast2600_adc1_trim,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
-- 
2.25.1



From 21cnbao at gmail.com  Tue Aug 24 20:12:04 2021
From: 21cnbao at gmail.com (Barry Song)
Date: Wed, 25 Aug 2021 15:12:04 +1200
Subject: [PATCH v4 2/2] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20210825111339.dcf494abb0c27508d2d1f645@kernel.org>
References: <20210818073336.59678-1-liuqi115@huawei.com>
 <20210818073336.59678-3-liuqi115@huawei.com>
 <20210824105001.GA96738@C02TD0UTHF1T.local>
 <20210825111339.dcf494abb0c27508d2d1f645@kernel.org>
Message-ID: <CAGsJ_4ww6wLBHw++qE_29ozC50XE8qc4T5waxn78UHRHjUFunQ@mail.gmail.com>

On Wed, Aug 25, 2021 at 2:15 PM Masami Hiramatsu <mhiramat at kernel.org> wrote:
>
> On Tue, 24 Aug 2021 11:50:01 +0100
> Mark Rutland <mark.rutland at arm.com> wrote:
>
> > Hi,
> >
> > I have a bunch of comments below.
> >
> > At a high-level, I'm not all that keen on adding yet another set of
> > trampolines, especially given we have constraints on how we can branch
> > to them which render this not that useful in common configurations (e.g.
> > where KASLR and module randomization is enabled).
>
> Yes, that makes kprobe jump optimization hard to implement on
> RISC architecture in general. (x86 has 32bit offset jump instruction)
> To solve this issue, something like "intermedate jump area" is needed
> for each module. (Or, overwriting multiple instructions)
>
> >
> > So importantly, do we actually need this? I don't think the sampel is
> > that compelling since we can already use ftrace to measure function
> > latencies.
>
> That depends on what you use it for, as you may know, kprobes allows
> you to put the probes on function body (and inlined function),
> on the other hand, ftrace can put only on the entry of the function.
> I guess Qi may want to use it for improving performance of BPF.
>
> (BTW, as far as I know, Jisheng Zhang once tried to implement
> kprobe on ftrace, that may be more helpful in this example.
> https://lore.kernel.org/linux-arm-kernel/20191225172625.69811b3e at xhacker.debian/T/#m23a7aa55d32d140ee6a92102534446cfd4a43007
> I will pick them up again)
>
> >
> > If we do need this, I think we need to do some more substantial rework
> > to address those branch range limitations. I know that we could permit
> > arbitrary branching if we expand the ftrace-with-regs callsites to ~6
> > instructions, but that interacts rather poorly with stacktracing and
> > will make the kernel a bit bigger.
>
> Would you mean we reuse the ftrace-with-regs callsites for kprobes?
>
> arm32 avoids this limitation partially with reserved text pages
> for trampoline in the kernel. But I think that is also a partial
> solution. It may not work with module randomization at least on
> arm64.
>
> On arm64, I think there are several way to solve it.
>
> - Add optprobe trampoline buffer for each module.
>   This is the simplest way to solve this issue, but requires some
>   pages to be added to each module (and kernel).
>
> - Add intermediate trampoline area for each module. (2-stage jump)
>   This jumps into an intermediate trampoline entry, save a partial
>   registers and jump the actual trampoline using that register.
>   This can reduce the size of trampoline buffer for each module.
>
> - Replace multiple instructions with the above intermediate jump
>   code. (single jump, but replace multiple instructions)
>   This requires to emulate multiple instructions and also the
>   kprobe must decode the instructions in the target function to
>   identify the replaced instructions are in one basic block. But
>   no need to add intermediate trampoline area (page).
>
>
>
> >
> > On Wed, Aug 18, 2021 at 03:33:36PM +0800, Qi Liu wrote:
> > > This patch introduce optprobe for ARM64. In optprobe, probed
> > > instruction is replaced by a branch instruction to detour
> > > buffer. Detour buffer contains trampoline code and a call to
> > > optimized_callback(). optimized_callback() calls opt_pre_handler()
> > > to execute kprobe handler.
> > >
> > > Performance of optprobe on Hip08 platform is test using kprobe
> > > example module[1] to analyze the latency of a kernel function,
> > > and here is the result:
> > >
> > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> > >
> > > kprobe before optimized:
> > > [280709.846380] do_empty returned 0 and took 1530 ns to execute
> > > [280709.852057] do_empty returned 0 and took 550 ns to execute
> > > [280709.857631] do_empty returned 0 and took 440 ns to execute
> > > [280709.863215] do_empty returned 0 and took 380 ns to execute
> > > [280709.868787] do_empty returned 0 and took 360 ns to execute
> > > [280709.874362] do_empty returned 0 and took 340 ns to execute
> > > [280709.879936] do_empty returned 0 and took 320 ns to execute
> > > [280709.885505] do_empty returned 0 and took 300 ns to execute
> > > [280709.891075] do_empty returned 0 and took 280 ns to execute
> > > [280709.896646] do_empty returned 0 and took 290 ns to execute
> > > [280709.902220] do_empty returned 0 and took 290 ns to execute
> > > [280709.907807] do_empty returned 0 and took 290 ns to execute
> > >
> > > optprobe:
> > > [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> > > [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> > > [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> > > [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> > > [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> > > [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> > > [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> > > [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.023779] do_empty returned 0 and took 70 ns to execute
> > > [ 2966.029158] do_empty returned 0 and took 70 ns to execute
> >
> > Do we have any examples of where this latency matters in practice?
> >
> > >
> > > Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> > >
> > > Note:
> > > To guarantee the offset between probe point and kprobe pre_handler
> > > is smaller than 128MiB, users should set
> > > CONFIG_RANDOMIZE_MODULE_REGION_FULL=N or set nokaslr in command line, or
> > > optprobe will not work and fall back to normal kprobe.
> >
> > Hmm... I don't think that's something we want to recommend, and
> > certainly distros *should* use KASLR and
> > CONFIG_RANDOMIZE_MODULE_REGION_FULL.
> >
> > What happens with defconfig? Do we always get the fallback behaviour?
>
> Yes, in such case, it fails back to normal kprobe.

just one minor comment. as Qi pointed out before, bootargs nokaslr
will make kernel built by defconfig
use optprobe:

        nokaslr         [KNL]
                        When CONFIG_RANDOMIZE_BASE is set, this disables
                        kernel and module base offset ASLR (Address Space
                        Layout Randomization).

in lab, while security is not a concern as online, it would be a good option.

> Anyway, optprobe is a background optimization. User can not specify
> which kprobe is optimized. That is automatically done.
>
> Thank you,
>
>
> --
> Masami Hiramatsu <mhiramat at kernel.org>

Thanks
barry


From wenst at chromium.org  Tue Aug 24 20:37:02 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 11:37:02 +0800
Subject: [PATCH 0/2] regulator: vctrl: Avoid lockdep warning in enable/disable
 ops
Message-ID: <20210825033704.3307263-1-wenst@chromium.org>

Hi,

Here are a couple fixes for vctrl-regulator. This driver is only used
RK3399-based Chromebooks.

Patch one fixes a misuse of the regulator API, which was found while
tracing the code to fix the lockdep warning.

Patch two fixes a lockdep warning and actual (not easy to reproduce)
deadlock.

Please have a look. The are no dependencies between the two patches.


Additionally, I believe it would make sense to implement the voltage
stepping feature for all regulators in the core. Then we could move
away from vctrl-regulator. Right now it is only done for coupled
regulators.


Regards
ChenYu


Chen-Yu Tsai (2):
  regulator: vctrl: Use locked regulator_get_voltage in probe path
  regulator: vctrl: Avoid lockdep warning in enable/disable ops

 drivers/regulator/vctrl-regulator.c | 73 +++++++++++++++++------------
 1 file changed, 43 insertions(+), 30 deletions(-)

-- 
2.33.0.rc2.250.ged5fa647cd-goog



From wenst at chromium.org  Tue Aug 24 20:37:03 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 11:37:03 +0800
Subject: [PATCH 1/2] regulator: vctrl: Use locked regulator_get_voltage in
 probe path
In-Reply-To: <20210825033704.3307263-1-wenst@chromium.org>
References: <20210825033704.3307263-1-wenst@chromium.org>
Message-ID: <20210825033704.3307263-2-wenst@chromium.org>

In commit e9153311491d ("regulator: vctrl-regulator: Avoid deadlock getting
and setting the voltage"), all calls to get/set the voltage of the
control regulator were switched to unlocked versions to avoid deadlocks.
However, the call in the probe path is done without regulator locks
held. In this case the locked version should be used.

Switch back to the locked regulator_get_voltage() in the probe path to
avoid any mishaps.

Fixes: e9153311491d ("regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/regulator/vctrl-regulator.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c
index cbadb1c99679..93d33201ffe0 100644
--- a/drivers/regulator/vctrl-regulator.c
+++ b/drivers/regulator/vctrl-regulator.c
@@ -490,7 +490,8 @@ static int vctrl_probe(struct platform_device *pdev)
 		if (ret)
 			return ret;
 
-		ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
+		/* Use locked consumer API when not in regulator framework */
+		ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
 		if (ctrl_uV < 0) {
 			dev_err(&pdev->dev, "failed to get control voltage\n");
 			return ctrl_uV;
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From wenst at chromium.org  Tue Aug 24 20:37:04 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 11:37:04 +0800
Subject: [PATCH 2/2] regulator: vctrl: Avoid lockdep warning in enable/disable
 ops
In-Reply-To: <20210825033704.3307263-1-wenst@chromium.org>
References: <20210825033704.3307263-1-wenst@chromium.org>
Message-ID: <20210825033704.3307263-3-wenst@chromium.org>

vctrl_enable() and vctrl_disable() call regulator_enable() and
regulator_disable(), respectively. However, vctrl_* are regulator ops
and should not be calling the locked regulator APIs. Doing so results in
a lockdep warning.

Instead of exporting more internal regulator ops, model the ctrl supply
as an actual supply to vctrl-regulator. At probe time this driver still
needs to use the consumer API to fetch its constraints, but otherwise
lets the regulator core handle the upstream supply for it.

The enable/disable/is_enabled ops are not removed, but now only track
state internally. This preserves the original behavior with the ops
being available, but one could argue that the original behavior was
already incorrect: the internal state would not match the upstream
supply if that supply had another consumer that enabled the supply,
while vctrl-regulator was not enabled.

The lockdep warning is as follows:

	WARNING: possible circular locking dependency detected
	5.14.0-rc6 #2 Not tainted
	------------------------------------------------------
	swapper/0/1 is trying to acquire lock:
	ffffffc011306d00 (regulator_list_mutex){+.+.}-{3:3}, at:
		regulator_lock_dependent (arch/arm64/include/asm/current.h:19
					  include/linux/ww_mutex.h:111
					  drivers/regulator/core.c:329)

	but task is already holding lock:
	ffffff8004a77160 (regulator_ww_class_mutex){+.+.}-{3:3}, at:
		regulator_lock_recursive (drivers/regulator/core.c:156
					  drivers/regulator/core.c:263)

	which lock already depends on the new lock.

	the existing dependency chain (in reverse order) is:

	-> #2 (regulator_ww_class_mutex){+.+.}-{3:3}:
	__mutex_lock_common (include/asm-generic/atomic-instrumented.h:606
			     include/asm-generic/atomic-long.h:29
			     kernel/locking/mutex.c:103
			     kernel/locking/mutex.c:144
			     kernel/locking/mutex.c:963)
	ww_mutex_lock (kernel/locking/mutex.c:1199)
	regulator_lock_recursive (drivers/regulator/core.c:156
				  drivers/regulator/core.c:263)
	regulator_lock_dependent (drivers/regulator/core.c:343)
	regulator_enable (drivers/regulator/core.c:2808)
	set_machine_constraints (drivers/regulator/core.c:1536)
	regulator_register (drivers/regulator/core.c:5486)
	devm_regulator_register (drivers/regulator/devres.c:196)
	reg_fixed_voltage_probe (drivers/regulator/fixed.c:289)
	platform_probe (drivers/base/platform.c:1427)
	[...]

	-> #1 (regulator_ww_class_acquire){+.+.}-{0:0}:
	regulator_lock_dependent (include/linux/ww_mutex.h:129
				  drivers/regulator/core.c:329)
	regulator_enable (drivers/regulator/core.c:2808)
	set_machine_constraints (drivers/regulator/core.c:1536)
	regulator_register (drivers/regulator/core.c:5486)
	devm_regulator_register (drivers/regulator/devres.c:196)
	reg_fixed_voltage_probe (drivers/regulator/fixed.c:289)
	[...]

	-> #0 (regulator_list_mutex){+.+.}-{3:3}:
	__lock_acquire (kernel/locking/lockdep.c:3052 (discriminator 4)
			kernel/locking/lockdep.c:3174 (discriminator 4)
			kernel/locking/lockdep.c:3789 (discriminator 4)
			kernel/locking/lockdep.c:5015 (discriminator 4))
	lock_acquire (arch/arm64/include/asm/percpu.h:39
		      kernel/locking/lockdep.c:438
		      kernel/locking/lockdep.c:5627)
	__mutex_lock_common (include/asm-generic/atomic-instrumented.h:606
			     include/asm-generic/atomic-long.h:29
			     kernel/locking/mutex.c:103
			     kernel/locking/mutex.c:144
			     kernel/locking/mutex.c:963)
	mutex_lock_nested (kernel/locking/mutex.c:1125)
	regulator_lock_dependent (arch/arm64/include/asm/current.h:19
				  include/linux/ww_mutex.h:111
				  drivers/regulator/core.c:329)
	regulator_enable (drivers/regulator/core.c:2808)
	vctrl_enable (drivers/regulator/vctrl-regulator.c:400)
	_regulator_do_enable (drivers/regulator/core.c:2617)
	_regulator_enable (drivers/regulator/core.c:2764)
	regulator_enable (drivers/regulator/core.c:308
			  drivers/regulator/core.c:2809)
	_set_opp (drivers/opp/core.c:819 drivers/opp/core.c:1072)
	dev_pm_opp_set_rate (drivers/opp/core.c:1164)
	set_target (drivers/cpufreq/cpufreq-dt.c:62)
	__cpufreq_driver_target (drivers/cpufreq/cpufreq.c:2216
				 drivers/cpufreq/cpufreq.c:2271)
	cpufreq_online (drivers/cpufreq/cpufreq.c:1488 (discriminator 2))
	cpufreq_add_dev (drivers/cpufreq/cpufreq.c:1563)
	subsys_interface_register (drivers/base/bus.c:?)
	cpufreq_register_driver (drivers/cpufreq/cpufreq.c:2819)
	dt_cpufreq_probe (drivers/cpufreq/cpufreq-dt.c:344)
	[...]

	other info that might help us debug this:

	Chain exists of:
	  regulator_list_mutex --> regulator_ww_class_acquire --> regulator_ww_class_mutex

	 Possible unsafe locking scenario:

	       CPU0                    CPU1
	       ----                    ----
	  lock(regulator_ww_class_mutex);
				       lock(regulator_ww_class_acquire);
				       lock(regulator_ww_class_mutex);
	  lock(regulator_list_mutex);

	 *** DEADLOCK ***

	6 locks held by swapper/0/1:
	#0: ffffff8002d32188 (&dev->mutex){....}-{3:3}, at:
		__device_driver_lock (drivers/base/dd.c:1030)
	#1: ffffffc0111a0520 (cpu_hotplug_lock){++++}-{0:0}, at:
		cpufreq_register_driver (drivers/cpufreq/cpufreq.c:2792 (discriminator 2))
	#2: ffffff8002a8d918 (subsys mutex#9){+.+.}-{3:3}, at:
		subsys_interface_register (drivers/base/bus.c:1033)
	#3: ffffff800341bb90 (&policy->rwsem){+.+.}-{3:3}, at:
		cpufreq_online (include/linux/bitmap.h:285
				include/linux/cpumask.h:405
				drivers/cpufreq/cpufreq.c:1399)
	#4: ffffffc011f0b7b8 (regulator_ww_class_acquire){+.+.}-{0:0}, at:
		regulator_enable (drivers/regulator/core.c:2808)
	#5: ffffff8004a77160 (regulator_ww_class_mutex){+.+.}-{3:3}, at:
		regulator_lock_recursive (drivers/regulator/core.c:156
		drivers/regulator/core.c:263)

	stack backtrace:
	CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.14.0-rc6 #2 7c8f8996d021ed0f65271e6aeebf7999de74a9fa
	Hardware name: Google Scarlet (DT)
	Call trace:
	dump_backtrace (arch/arm64/kernel/stacktrace.c:161)
	show_stack (arch/arm64/kernel/stacktrace.c:218)
	dump_stack_lvl (lib/dump_stack.c:106 (discriminator 2))
	dump_stack (lib/dump_stack.c:113)
	print_circular_bug (kernel/locking/lockdep.c:?)
	check_noncircular (kernel/locking/lockdep.c:?)
	__lock_acquire (kernel/locking/lockdep.c:3052 (discriminator 4)
			kernel/locking/lockdep.c:3174 (discriminator 4)
			kernel/locking/lockdep.c:3789 (discriminator 4)
			kernel/locking/lockdep.c:5015 (discriminator 4))
	lock_acquire (arch/arm64/include/asm/percpu.h:39
		      kernel/locking/lockdep.c:438
		      kernel/locking/lockdep.c:5627)
	__mutex_lock_common (include/asm-generic/atomic-instrumented.h:606
			     include/asm-generic/atomic-long.h:29
			     kernel/locking/mutex.c:103
			     kernel/locking/mutex.c:144
			     kernel/locking/mutex.c:963)
	mutex_lock_nested (kernel/locking/mutex.c:1125)
	regulator_lock_dependent (arch/arm64/include/asm/current.h:19
				  include/linux/ww_mutex.h:111
				  drivers/regulator/core.c:329)
	regulator_enable (drivers/regulator/core.c:2808)
	vctrl_enable (drivers/regulator/vctrl-regulator.c:400)
	_regulator_do_enable (drivers/regulator/core.c:2617)
	_regulator_enable (drivers/regulator/core.c:2764)
	regulator_enable (drivers/regulator/core.c:308
			  drivers/regulator/core.c:2809)
	_set_opp (drivers/opp/core.c:819 drivers/opp/core.c:1072)
	dev_pm_opp_set_rate (drivers/opp/core.c:1164)
	set_target (drivers/cpufreq/cpufreq-dt.c:62)
	__cpufreq_driver_target (drivers/cpufreq/cpufreq.c:2216
				 drivers/cpufreq/cpufreq.c:2271)
	cpufreq_online (drivers/cpufreq/cpufreq.c:1488 (discriminator 2))
	cpufreq_add_dev (drivers/cpufreq/cpufreq.c:1563)
	subsys_interface_register (drivers/base/bus.c:?)
	cpufreq_register_driver (drivers/cpufreq/cpufreq.c:2819)
	dt_cpufreq_probe (drivers/cpufreq/cpufreq-dt.c:344)
	[...]

Reported-by: Brian Norris <briannorris at chromium.org>
Fixes: f8702f9e4aa7 ("regulator: core: Use ww_mutex for regulators locking")
Fixes: e9153311491d ("regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---

Mark,

checkpatch.pl gives a few style check issues about parenthesis alighment
around regulator_set_voltage_rdev() invocations, which were the result of
the previous switch over from regulator_set_voltage() to
regulator_set_voltage_rdev().

Not sure if you want those fixed up in the same patch, or maybe in a
followup one?

---
 drivers/regulator/vctrl-regulator.c | 72 +++++++++++++++++------------
 1 file changed, 42 insertions(+), 30 deletions(-)

diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c
index 93d33201ffe0..d2a37978fc3a 100644
--- a/drivers/regulator/vctrl-regulator.c
+++ b/drivers/regulator/vctrl-regulator.c
@@ -37,7 +37,6 @@ struct vctrl_voltage_table {
 struct vctrl_data {
 	struct regulator_dev *rdev;
 	struct regulator_desc desc;
-	struct regulator *ctrl_reg;
 	bool enabled;
 	unsigned int min_slew_down_rate;
 	unsigned int ovp_threshold;
@@ -82,7 +81,12 @@ static int vctrl_calc_output_voltage(struct vctrl_data *vctrl, int ctrl_uV)
 static int vctrl_get_voltage(struct regulator_dev *rdev)
 {
 	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
-	int ctrl_uV = regulator_get_voltage_rdev(vctrl->ctrl_reg->rdev);
+	int ctrl_uV;
+
+	if (!rdev->supply)
+		return -EPROBE_DEFER;
+
+	ctrl_uV = regulator_get_voltage_rdev(rdev->supply->rdev);
 
 	return vctrl_calc_output_voltage(vctrl, ctrl_uV);
 }
@@ -92,14 +96,19 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
 			     unsigned int *selector)
 {
 	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
-	struct regulator *ctrl_reg = vctrl->ctrl_reg;
-	int orig_ctrl_uV = regulator_get_voltage_rdev(ctrl_reg->rdev);
-	int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
+	int orig_ctrl_uV;
+	int uV;
 	int ret;
 
+	if (!rdev->supply)
+		return -EPROBE_DEFER;
+
+	orig_ctrl_uV = regulator_get_voltage_rdev(rdev->supply->rdev);
+	uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV);
+
 	if (req_min_uV >= uV || !vctrl->ovp_threshold)
 		/* voltage rising or no OVP */
-		return regulator_set_voltage_rdev(ctrl_reg->rdev,
+		return regulator_set_voltage_rdev(rdev->supply->rdev,
 			vctrl_calc_ctrl_voltage(vctrl, req_min_uV),
 			vctrl_calc_ctrl_voltage(vctrl, req_max_uV),
 			PM_SUSPEND_ON);
@@ -117,7 +126,7 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
 		next_uV = max_t(int, req_min_uV, uV - max_drop_uV);
 		next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV);
 
-		ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
+		ret = regulator_set_voltage_rdev(rdev->supply->rdev,
 					    next_ctrl_uV,
 					    next_ctrl_uV,
 					    PM_SUSPEND_ON);
@@ -134,7 +143,7 @@ static int vctrl_set_voltage(struct regulator_dev *rdev,
 
 err:
 	/* Try to go back to original voltage */
-	regulator_set_voltage_rdev(ctrl_reg->rdev, orig_ctrl_uV, orig_ctrl_uV,
+	regulator_set_voltage_rdev(rdev->supply->rdev, orig_ctrl_uV, orig_ctrl_uV,
 				   PM_SUSPEND_ON);
 
 	return ret;
@@ -151,16 +160,18 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
 				 unsigned int selector)
 {
 	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
-	struct regulator *ctrl_reg = vctrl->ctrl_reg;
 	unsigned int orig_sel = vctrl->sel;
 	int ret;
 
+	if (!rdev->supply)
+		return -EPROBE_DEFER;
+
 	if (selector >= rdev->desc->n_voltages)
 		return -EINVAL;
 
 	if (selector >= vctrl->sel || !vctrl->ovp_threshold) {
 		/* voltage rising or no OVP */
-		ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
+		ret = regulator_set_voltage_rdev(rdev->supply->rdev,
 					    vctrl->vtable[selector].ctrl,
 					    vctrl->vtable[selector].ctrl,
 					    PM_SUSPEND_ON);
@@ -179,7 +190,7 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
 		else
 			next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel;
 
-		ret = regulator_set_voltage_rdev(ctrl_reg->rdev,
+		ret = regulator_set_voltage_rdev(rdev->supply->rdev,
 					    vctrl->vtable[next_sel].ctrl,
 					    vctrl->vtable[next_sel].ctrl,
 					    PM_SUSPEND_ON);
@@ -202,7 +213,7 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev,
 err:
 	if (vctrl->sel != orig_sel) {
 		/* Try to go back to original voltage */
-		if (!regulator_set_voltage_rdev(ctrl_reg->rdev,
+		if (!regulator_set_voltage_rdev(rdev->supply->rdev,
 					   vctrl->vtable[orig_sel].ctrl,
 					   vctrl->vtable[orig_sel].ctrl,
 					   PM_SUSPEND_ON))
@@ -234,10 +245,6 @@ static int vctrl_parse_dt(struct platform_device *pdev,
 	u32 pval;
 	u32 vrange_ctrl[2];
 
-	vctrl->ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl");
-	if (IS_ERR(vctrl->ctrl_reg))
-		return PTR_ERR(vctrl->ctrl_reg);
-
 	ret = of_property_read_u32(np, "ovp-threshold-percent", &pval);
 	if (!ret) {
 		vctrl->ovp_threshold = pval;
@@ -315,11 +322,11 @@ static int vctrl_cmp_ctrl_uV(const void *a, const void *b)
 	return at->ctrl - bt->ctrl;
 }
 
-static int vctrl_init_vtable(struct platform_device *pdev)
+static int vctrl_init_vtable(struct platform_device *pdev,
+			     struct regulator *ctrl_reg)
 {
 	struct vctrl_data *vctrl = platform_get_drvdata(pdev);
 	struct regulator_desc *rdesc = &vctrl->desc;
-	struct regulator *ctrl_reg = vctrl->ctrl_reg;
 	struct vctrl_voltage_range *vrange_ctrl = &vctrl->vrange.ctrl;
 	int n_voltages;
 	int ctrl_uV;
@@ -395,23 +402,19 @@ static int vctrl_init_vtable(struct platform_device *pdev)
 static int vctrl_enable(struct regulator_dev *rdev)
 {
 	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
-	int ret = regulator_enable(vctrl->ctrl_reg);
 
-	if (!ret)
-		vctrl->enabled = true;
+	vctrl->enabled = true;
 
-	return ret;
+	return 0;
 }
 
 static int vctrl_disable(struct regulator_dev *rdev)
 {
 	struct vctrl_data *vctrl = rdev_get_drvdata(rdev);
-	int ret = regulator_disable(vctrl->ctrl_reg);
 
-	if (!ret)
-		vctrl->enabled = false;
+	vctrl->enabled = false;
 
-	return ret;
+	return 0;
 }
 
 static int vctrl_is_enabled(struct regulator_dev *rdev)
@@ -447,6 +450,7 @@ static int vctrl_probe(struct platform_device *pdev)
 	struct regulator_desc *rdesc;
 	struct regulator_config cfg = { };
 	struct vctrl_voltage_range *vrange_ctrl;
+	struct regulator *ctrl_reg;
 	int ctrl_uV;
 	int ret;
 
@@ -461,15 +465,20 @@ static int vctrl_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl");
+	if (IS_ERR(ctrl_reg))
+		return PTR_ERR(ctrl_reg);
+
 	vrange_ctrl = &vctrl->vrange.ctrl;
 
 	rdesc = &vctrl->desc;
 	rdesc->name = "vctrl";
 	rdesc->type = REGULATOR_VOLTAGE;
 	rdesc->owner = THIS_MODULE;
+	rdesc->supply_name = "ctrl";
 
-	if ((regulator_get_linear_step(vctrl->ctrl_reg) == 1) ||
-	    (regulator_count_voltages(vctrl->ctrl_reg) == -EINVAL)) {
+	if ((regulator_get_linear_step(ctrl_reg) == 1) ||
+	    (regulator_count_voltages(ctrl_reg) == -EINVAL)) {
 		rdesc->continuous_voltage_range = true;
 		rdesc->ops = &vctrl_ops_cont;
 	} else {
@@ -486,12 +495,12 @@ static int vctrl_probe(struct platform_device *pdev)
 	cfg.init_data = init_data;
 
 	if (!rdesc->continuous_voltage_range) {
-		ret = vctrl_init_vtable(pdev);
+		ret = vctrl_init_vtable(pdev, ctrl_reg);
 		if (ret)
 			return ret;
 
 		/* Use locked consumer API when not in regulator framework */
-		ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg);
+		ctrl_uV = regulator_get_voltage(ctrl_reg);
 		if (ctrl_uV < 0) {
 			dev_err(&pdev->dev, "failed to get control voltage\n");
 			return ctrl_uV;
@@ -514,6 +523,9 @@ static int vctrl_probe(struct platform_device *pdev)
 		}
 	}
 
+	/* Drop ctrl-supply here in favor of regulator core managed supply */
+	devm_regulator_put(ctrl_reg);
+
 	vctrl->rdev = devm_regulator_register(&pdev->dev, rdesc, &cfg);
 	if (IS_ERR(vctrl->rdev)) {
 		ret = PTR_ERR(vctrl->rdev);
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From palmer at dabbelt.com  Tue Aug 24 20:49:39 2021
From: palmer at dabbelt.com (Palmer Dabbelt)
Date: Tue, 24 Aug 2021 20:49:39 -0700 (PDT)
Subject: [PATCH] arch: vdso: remove if-conditionals of $(c-gettimeofday-y)
In-Reply-To: <20210731055733.12332-1-masahiroy@kernel.org>
Message-ID: <mhng-2a609a54-0d13-4fb3-9966-086357936773@palmerdabbelt-glaptop>

On Fri, 30 Jul 2021 22:57:33 PDT (-0700), masahiroy at kernel.org wrote:
> arm, arm64, mips, powerpc always select GENERIC_GETTIMEOFDAY, hence
> $(gettimeofday-y) never becomes empty.
>
> riscv conditionally selects GENERIC_GETTIMEOFDAY when MMU=y && 64BIT=y,
> but arch/riscv/kernel/vdso/vgettimeofday.o is built only under that
> condition. So, you can always define CFLAGS_vgettimeofday.o
>
> Remove all the meaningless conditionals.
>
> Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> ---
>
>  arch/riscv/kernel/vdso/Makefile     |  5 +----

Acked-by: Palmer Dabbelt <palmerdabbelt at google.com>


From ezequiel at vanguardiasur.com.ar  Tue Aug 24 20:49:41 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 25 Aug 2021 00:49:41 -0300
Subject: [PATCH 1/9] dt-bindings: media: mtk-vcodec: Add binding for
 MT8195 two venc cores
In-Reply-To: <6efbfdbac55c5c8175168be96d3a2e63b4ac0f07.camel@mediatek.com>
References: <20210816105934.28265-1-irui.wang@mediatek.com>
 <20210816105934.28265-2-irui.wang@mediatek.com>
 <CAAEAJfDoSW3F85bFKTRvvGZXTZbCBRpUwZzEyx3zhrA6psiZfA@mail.gmail.com>
 <6efbfdbac55c5c8175168be96d3a2e63b4ac0f07.camel@mediatek.com>
Message-ID: <CAAEAJfBvWDqtb8oqxx9zosEbBhFVMiszG2cu=Y7OXx3-T4gAOQ@mail.gmail.com>

On Tue, 24 Aug 2021 at 23:04, Irui Wang (??) <Irui.Wang at mediatek.com> wrote:
>
> Hi,Ezequiel,
>
> Thanks for your reviewing.
>
> On Tue, 2021-08-24 at 08:02 -0300, Ezequiel Garcia wrote:
> > Hi Irui,
> >
> > On Mon, 16 Aug 2021 at 08:00, Irui Wang <irui.wang at mediatek.com>
> > wrote:
> > >
> > > Enable MT8195 two H.264 venc cores, updates vcodec binding
> > > document.
> > >
> > > Signed-off-by: Irui Wang <irui.wang at mediatek.com>
> > > ---
> > >  Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/media/mediatek-
> > > vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-
> > > vcodec.txt
> > > index de961699ba0a..eb2e24c32426 100644
> > > --- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> > > +++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
> > > @@ -11,6 +11,8 @@ Required properties:
> > >    "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
> > >    "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
> > >    "mediatek,mt8195-vcodec-enc" for MT8195 encoder.
> > > +  "mediatek,mtk-venc-core0" for MT8195 avc core0 device.
> > > +  "mediatek,mtk-venc-core1" for MT8195 avc core1 device.
> >
> > What is the difference between core0 and core1?
> >
> > Thanks,
> > Ezequiel
>
> Both core0 and core1 are H264 encoder hardware, they have their own
> hardware register base, used power-domains/clocks/irqs. We can use any
> of them for H.264 encoding, but the two cores can work together for
> higher performance, it's called "frame racing", a hardware encoding
> mode, control flow just like in the commit messages:
>
> core0 frame#0.frame#2.frame#4...
> core1    frame#1.frame#3.frame#5...
>

If they are two encoder cores, why do you need different compatible strings?

It would be interesting to see a device tree which shows how this should
be used in the real world, but from the looks of it, it seems you don't
need a separate compatible.

It seems this series is somewhat related to Yunfei's "[PATCH v5,
00/15] Using component framework to support multi hardware decode",
but I don't see a device tree patch either in that series.

Given this is a complex architecture, I don't know if it
makes sense to discuss decoder and encoder independently.

If you guys unify the two series, and add the device tree patches for it,
or at least for the most complex cases, maybe that will surface the
architecture more clearly and come up with an easier solution that
doesn't involve
an async framework to pull in the parts together.

Thanks,
Ezequiel


From dqfext at gmail.com  Tue Aug 24 20:55:45 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed, 25 Aug 2021 11:55:45 +0800
Subject: [PATCH net-next] net: dsa: mt7530: manually set up VLAN ID 0
In-Reply-To: <20210824173714.cgpt2addxyjzlbyy@skbuf>
References: <20210824165253.1691315-1-dqfext@gmail.com>
 <20210824165742.xvkb3ke7boryfoj4@skbuf>
 <20210824173237.1691654-1-dqfext@gmail.com>
 <20210824173714.cgpt2addxyjzlbyy@skbuf>
Message-ID: <20210825035545.1836274-1-dqfext@gmail.com>

On Tue, Aug 24, 2021 at 08:37:14PM +0300, Vladimir Oltean wrote:
> On Wed, Aug 25, 2021 at 01:32:37AM +0800, DENG Qingfang wrote:
> > Okay. So the Fixes tag should be 6087175b7991, which initially adds the
> > software fallback support for mt7530.
> 
> Ok. Did the old code not need VLAN 0 for VLAN-unaware ports, or are you
> saying that since the VLAN table lookup was bypassed completely in the
> old code, 'no VLAN 0' was an inconsequential error?
> 
> I think it's the latter. Just wanted to make sure. So that means, either
> this Fixes: tag or the other, the patch still belongs to net-next. From
> my side you shouldn't need to resend.

You're right. The old code does not use VLAN table lookup for VLAN-unaware
ports, and the current code set VLAN-unaware ports to fallback mode so
missing VLAN 0 will only make them fallback to SVL.

> 
> Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From wangkefeng.wang at huawei.com  Tue Aug 24 21:05:13 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 12:05:13 +0800
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
Message-ID: <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>


On 2021/8/25 4:08, Saravana Kannan wrote:
> On Tue, Aug 24, 2021 at 1:05 PM Rob Herring <robh+dt at kernel.org> wrote:
>> +Saravana
>>
>> Saravana mentioned to me there may be some issues with this one...
>>
>>
>> On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>> of_amba_device_create() uses irq_of_parse_and_map() to translate
>>> a DT interrupt specification into a Linux virtual interrupt number.
>>>
>>> But it doesn't properly handle the case where the interrupt controller
>>> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
>>> interrupt controller, because the mbigen initialization is too late,
>>> which will lead to no IRQ due to no IRQ domain found, log is shown below,
>>>    "irq: no irq domain found for uart0 !"
>>>
>>> use of_irq_get() to return -EPROBE_DEFER as above, and in the function
>>> amba_device_try_add()/amba_device_add(), it will properly handle in such
>>> case, also return 0 in other fail cases to be consistent as before.
>>>
>>> Cc: Russell King <linux at armlinux.org.uk>
>>> Cc: Rob Herring <robh+dt at kernel.org>
>>> Cc: Frank Rowand <frowand.list at gmail.com>
>>> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
>>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>>> ---
>>>   drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
>>>   drivers/of/platform.c |  6 +-----
>>>   2 files changed, 28 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
>>> index 36f2f42c8014..720aa6cdd402 100644
>>> --- a/drivers/amba/bus.c
>>> +++ b/drivers/amba/bus.c
>>> @@ -19,6 +19,7 @@
>>>   #include <linux/clk/clk-conf.h>
>>>   #include <linux/platform_device.h>
>>>   #include <linux/reset.h>
>>> +#include <linux/of_irq.h>
>>>
>>>   #include <asm/irq.h>
>>>
>>> @@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
>>>          kfree(d);
>>>   }
>>>
>>> +static int of_amba_device_decode_irq(struct amba_device *dev)
>>> +{
>>> +       struct device_node *node = dev->dev.of_node;
>>> +       int i, irq = 0;
>>> +
>>> +       if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
>>> +               /* Decode the IRQs and address ranges */
>>> +               for (i = 0; i < AMBA_NR_IRQS; i++) {
>>> +                       irq = of_irq_get(node, i);
>>> +                       if (irq < 0) {
>>> +                               if (irq == -EPROBE_DEFER)
>>> +                                       return irq;
>>> +                               irq = 0;
>>> +                       }
>>> +
>>> +                       dev->irq[i] = irq;
>>> +               }
>>> +       }
>>> +
>>> +       return 0;
>>> +}
>>> +
>>>   static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
>>>   {
>>>          u32 size;
>>>          void __iomem *tmp;
>>>          int i, ret;
>>>
>>> +       ret = of_amba_device_decode_irq(dev);
>>> +       if (ret)
>>> +               goto err_out;
>>> +
> Similar to other resources the AMBA bus "gets" for the device, I think
> this should be moved into amba_probe() and not here. There's no reason
> to delay the addition of the device (and loading its module) because
> the IRQ isn't ready yet.

The following code in the amba_device_try_add() will be called, it uses irq[0]
and irq[1], so I put of_amba_device_decode_irq() into amba_device_try_add().

470         if (dev->irq[0])
471                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
472         if (ret == 0 && dev->irq[1])
473                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
474         if (ret == 0)
475                 return ret;

of_amba_device_decode_irq() in amba_device_try_add() won't lead to issue,
only delay the device add, right?

If make it into amba_probe(), the above code should be moved too, could we
make a new patch to move both of them, or don't move them?



From rppt at kernel.org  Tue Aug 24 21:39:00 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Wed, 25 Aug 2021 07:39:00 +0300
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <b37fc109-06d3-0c86-a3c8-e5d7f21f296b@gmail.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <b37fc109-06d3-0c86-a3c8-e5d7f21f296b@gmail.com>
Message-ID: <YSXJZBKeka5U7VN+@kernel.org>

On Tue, Aug 24, 2021 at 10:14:01PM +0200, Alex Bee wrote:
> Hi Mike,
> 
> thanks for your reply
> 
> Am 24.08.21 um 20:28 schrieb Mike Rapoport:
> > On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
> > > Hi Alex,
> > > 
> > > Thanks for the report.
> > > 
> > > On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
> > > > it seems there is a regression in arm64 memory mapping in 5.14, since it
> > > > fails on Rockchip RK3328 when the pl330 dmac tries to map with:
> > > > 
> > > > [??? 8.921909] ------------[ cut here ]------------
> > > > [??? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
> > > > [??? 8.921973] Modules linked in: spi_rockchip(+) fuse
> > > > [??? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
> > > > [??? 8.922004] Hardware name: Pine64 Rock64 (DT)
> > > > [??? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
> > > > [??? 8.922018] pc : dma_map_resource+0x68/0xc0
> > > > [??? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
> > > > [??? 8.922040] sp : ffff800012102ae0
> > > > [??? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
> > > > [??? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
> > > > [??? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
> > > > [??? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
> > > > [??? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> > > > [??? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
> > > > [??? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
> > > > [??? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
> > > > [??? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
> > > > [??? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
> > > > [??? 8.922158] Call trace:
> > > > [??? 8.922163]? dma_map_resource+0x68/0xc0
> > > > [??? 8.922173]? pl330_prep_slave_sg+0x58/0x220
> > > > [??? 8.922181]? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
> > > > [??? 8.922208]? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
> > > [...]
> > > > Note: This does not relate to the spi driver - when disabling this device in
> > > > the device tree it fails for any other (i2s, for instance) which uses dma.
> > > > Commenting out the failing check at [1], however, helps and the mapping
> > > > works again.
> > > Do you know which address dma_map_resource() is trying to map (maybe
> > > add some printk())? It's not supposed to map RAM, hence the warning.
> > > Random guess, the address is 0xff190800 (based on the x1 above but the
> > > regs might as well be mangled).
> > 0xff190800 will cause this warning for sure. It has a memory map, but it is
> > not RAM so old version of pfn_valid() would return 0 and the new one
> > returns 1.
> > > > I tried to follow the recent changes for arm64 mm which could relate to the
> > > > check failing at [1] and reverting
> > > >  ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
> > > > helps and makes it work again, but I'm 100% uncertain if that commit is
> > > > really the culprit.
> > > > 
> > > > Note, that the firmware (legacy u-boot) injects memory configuration in the
> > > > device tree as follows:
> > > > 
> > > > /memreserve/??? 0x00000000fcefc000 0x000000000000d000;
> > > > / {
> > > > ..
> > > >  ??? compatible = "pine64,rock64\0rockchip,rk3328";
> > > > ..
> > > >  ??? memory {
> > > >  ??? ??? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
> > > >  ??? ??? device_type = "memory";
> > > >  ??? };
> > > > 
> > > > ..
> > > > }
> > > Either pfn_valid() gets confused in 5.14 or something is wrong with the
> > > DT. I have a suspicion it's the former since reverting the above commit
> > > makes it disappear.
> > I think pfn_valid() actually behaves as expected but the caller is wrong
> > because pfn_valid != RAM (this applies btw to !arm64 as well).
> > 
> > 	/* Don't allow RAM to be mapped */
> > 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> > 		return DMA_MAPPING_ERROR;
> > 
> > Alex, can you please try this patch:
> > 
> > diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
> > index 2b06a809d0b9..4715e9641a29 100644
> > --- a/kernel/dma/mapping.c
> > +++ b/kernel/dma/mapping.c
> > @@ -232,7 +232,7 @@ dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr,
> >   		return DMA_MAPPING_ERROR;
> >   	/* Don't allow RAM to be mapped */
> > -	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> > +	if (WARN_ON_ONCE(!memblock_is_memory(phys_addr)))
> >   		return DMA_MAPPING_ERROR;
> >   	if (dma_map_direct(dev, ops))
> 
> Nope, doesn't help:
> 
> [??? 8.353879] dma_map_resource Failed to map address 0xff190800
> [??? 8.353886] dma_map_resource pfn_valid(PHYS_PFN(0xff190800)): 1
> [??? 8.353892] dma_map_resource memblock_is_memory(0xff190800): 0
> 
> If understand the comment for that check correct, that we _don't_ want RAM
> to be mapped - shoudn't that be:
> 
> +	if (WARN_ON_ONCE(memblock_is_memory(phys_addr)))
> 
> ?

Right, we don't want RAM to be mapped, the negation was wrong and it should
be 

	if (WARN_ON_ONCE(memblock_is_memory(phys_addr)))
 
-- 
Sincerely yours,
Mike.


From chunfeng.yun at mediatek.com  Tue Aug 24 22:47:57 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 25 Aug 2021 13:47:57 +0800
Subject: [PATCH RESEND v3 1/2] PM / wakeirq: support enabling wake-up irq
 after runtime_suspend called
Message-ID: <1629870478-11813-1-git-send-email-chunfeng.yun@mediatek.com>

When the dedicated wake-irq is level trigger, and it uses the
consumer's sleep status as the wakeup source, that means if the
consumer is not in sleep state, the wake-irq will be triggered
when enable it; For this case, need enable the wake-irq after
invoking the consumer's runtime_suspend() which make the consumer
enter sleep state.

e.g.
Assume the wake-irq is a low level trigger type, and the wakeup
signal comes from the sleep status of consumer.
The wakeup signal is low level at running time (0), and becomes
high level when the consumer enters sleep state (runtime_suspend
(1) is called), a wakeup event at (2) make the consumer exit sleep
state, then the wakeup signal also becomes low level.

                ------------------
               |           ^     ^|
----------------           |     | --------------
 |<---(0)--->|<--(1)--|   (3)   (2)    (4)

if enable the wake-irq before calling runtime_suspend during (0),
an interrupt will arise, it causes resume immediately;
it works if enable wake-irq ( e.g. at (3) or (4)) after calling
runtime_suspend.

This patch introduces a new status WAKE_IRQ_DEDICATED_LATE_ENABLED
to optionally support enabling wake-irq after calling runtime_suspend().

Suggested-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: add new status suggested by Rafael

v2: add more commit message

  Use the falling edge trigger interrupt suggested by Ikjoon [1], it
works well at firstly when only use this related wakeup source, but
encounter issues if use other wakeup sources to wakeup platform as
below steps:
1. use another wakeup source to wake up the suspended system;
2. the consumer's resume() will be called, and exits sleep state;
3. the consumer's wakeup signal will fall into low level, due to
   currently the wakeup irq is disabled, the wake-irq is pending;
4. the consumer tries to enter runtime suspend, but there is a
   pending wakeup irq, so will resume again, this will repeat
   endlessly.

  Send out the patch again for further discussion.

[1]: https://patchwork.kernel.org/patch/12190407

---
 drivers/base/power/power.h   |  7 ++++--
 drivers/base/power/runtime.c |  6 +++--
 drivers/base/power/wakeirq.c | 49 +++++++++++++++++++++++++++++++++---
 include/linux/pm_wakeirq.h   |  5 ++++
 4 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 54292cdd7808..2d5dfc886f0b 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -25,8 +25,10 @@ extern u64 pm_runtime_active_time(struct device *dev);
 
 #define WAKE_IRQ_DEDICATED_ALLOCATED	BIT(0)
 #define WAKE_IRQ_DEDICATED_MANAGED	BIT(1)
+#define WAKE_IRQ_DEDICATED_LATE_ENABLED	BIT(2)
 #define WAKE_IRQ_DEDICATED_MASK		(WAKE_IRQ_DEDICATED_ALLOCATED | \
-					 WAKE_IRQ_DEDICATED_MANAGED)
+					 WAKE_IRQ_DEDICATED_MANAGED | \
+					 WAKE_IRQ_DEDICATED_LATE_ENABLED)
 
 struct wake_irq {
 	struct device *dev;
@@ -39,7 +41,8 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq);
 extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq);
 extern void dev_pm_enable_wake_irq_check(struct device *dev,
 					 bool can_change_status);
-extern void dev_pm_disable_wake_irq_check(struct device *dev);
+extern void dev_pm_disable_wake_irq_check(struct device *dev, bool skip_enable_late);
+extern void dev_pm_enable_wake_irq_complete(struct device *dev);
 
 #ifdef CONFIG_PM_SLEEP
 
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 8a66eaf731e4..97646aa11376 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -645,6 +645,8 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 	if (retval)
 		goto fail;
 
+	dev_pm_enable_wake_irq_complete(dev);
+
  no_callback:
 	__update_runtime_status(dev, RPM_SUSPENDED);
 	pm_runtime_deactivate_timer(dev);
@@ -690,7 +692,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
 	return retval;
 
  fail:
-	dev_pm_disable_wake_irq_check(dev);
+	dev_pm_disable_wake_irq_check(dev, false);
 	__update_runtime_status(dev, RPM_ACTIVE);
 	dev->power.deferred_resume = false;
 	wake_up_all(&dev->power.wait_queue);
@@ -873,7 +875,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
 
 	callback = RPM_GET_CALLBACK(dev, runtime_resume);
 
-	dev_pm_disable_wake_irq_check(dev);
+	dev_pm_disable_wake_irq_check(dev, true);
 	retval = rpm_callback(callback, dev);
 	if (retval) {
 		__update_runtime_status(dev, RPM_SUSPENDED);
diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c
index 3bad3266a2ad..a612f5c26c6c 100644
--- a/drivers/base/power/wakeirq.c
+++ b/drivers/base/power/wakeirq.c
@@ -215,6 +215,24 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq)
 }
 EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq);
 
+/**
+ * dev_pm_wake_irq_set_late_enabled_status - set status WAKE_IRQ_DEDICATED_LATE_ENABLED
+ * @dev: Device
+ *
+ * Set the status of WAKE_IRQ_DEDICATED_LATE_ENABLED to tell rpm_suspend()
+ * to enable dedicated wake-up interrupt after invoking the runtime_suspend(),
+ *
+ * Should be called after setting dedicated wake-up interrupt.
+ */
+void dev_pm_wake_irq_set_late_enabled_status(struct device *dev)
+{
+	struct wake_irq *wirq = dev->power.wakeirq;
+
+	if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED))
+		wirq->status |= WAKE_IRQ_DEDICATED_LATE_ENABLED;
+}
+EXPORT_SYMBOL_GPL(dev_pm_wake_irq_set_late_enabled_status);
+
 /**
  * dev_pm_enable_wake_irq - Enable device wake-up interrupt
  * @dev: Device
@@ -285,27 +303,52 @@ void dev_pm_enable_wake_irq_check(struct device *dev,
 	return;
 
 enable:
-	enable_irq(wirq->irq);
+	if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_LATE_ENABLED))
+		enable_irq(wirq->irq);
 }
 
 /**
  * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt
  * @dev: Device
+ * @skip_late_enabled_status: skip checking WAKE_IRQ_DEDICATED_LATE_ENABLED
  *
  * Disables wake-up interrupt conditionally based on status.
  * Should be only called from rpm_suspend() and rpm_resume() path.
  */
-void dev_pm_disable_wake_irq_check(struct device *dev)
+void dev_pm_disable_wake_irq_check(struct device *dev, bool skip_late_enabled_status)
 {
 	struct wake_irq *wirq = dev->power.wakeirq;
 
 	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
 		return;
 
-	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
+	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
+	    (skip_late_enabled_status ||
+	     !(wirq->status & WAKE_IRQ_DEDICATED_LATE_ENABLED)))
 		disable_irq_nosync(wirq->irq);
 }
 
+/**
+ * dev_pm_enable_wake_irq_complete - enable wake irq based on status
+ * @dev: Device
+ *
+ * Enable wake-up interrupt conditionally based on status, mainly for
+ * enabling wake-up interrupt after runtime_suspend() is called.
+ *
+ * Should be only called from rpm_suspend() path.
+ */
+void dev_pm_enable_wake_irq_complete(struct device *dev)
+{
+	struct wake_irq *wirq = dev->power.wakeirq;
+
+	if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK))
+		return;
+
+	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
+	    wirq->status & WAKE_IRQ_DEDICATED_LATE_ENABLED)
+		enable_irq(wirq->irq);
+}
+
 /**
  * dev_pm_arm_wake_irq - Arm device wake-up
  * @wirq: Device wake-up interrupt
diff --git a/include/linux/pm_wakeirq.h b/include/linux/pm_wakeirq.h
index cd5b62db9084..92f814d583f8 100644
--- a/include/linux/pm_wakeirq.h
+++ b/include/linux/pm_wakeirq.h
@@ -22,6 +22,7 @@ extern int dev_pm_set_dedicated_wake_irq(struct device *dev,
 extern void dev_pm_clear_wake_irq(struct device *dev);
 extern void dev_pm_enable_wake_irq(struct device *dev);
 extern void dev_pm_disable_wake_irq(struct device *dev);
+extern void dev_pm_wake_irq_set_late_enabled_status(struct device *dev);
 
 #else	/* !CONFIG_PM */
 
@@ -47,5 +48,9 @@ static inline void dev_pm_disable_wake_irq(struct device *dev)
 {
 }
 
+static inline void dev_pm_wake_irq_set_late_enabled_status(struct device *dev)
+{
+}
+
 #endif	/* CONFIG_PM */
 #endif	/* _LINUX_PM_WAKEIRQ_H */
-- 
2.25.1

From chunfeng.yun at mediatek.com  Tue Aug 24 22:47:58 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Wed, 25 Aug 2021 13:47:58 +0800
Subject: [PATCH RESEND v3 2/2] usb: xhci-mtk: enable wake-up interrupt after
 runtime_suspend called
In-Reply-To: <1629870478-11813-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1629870478-11813-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1629870478-11813-2-git-send-email-chunfeng.yun@mediatek.com>

Use new function dev_pm_wake_irq_set_late_enabled_status() to enable
dedicated wake-up interrupt after xhci_mtk_runtime_suspend() is called.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: new patch
---
 drivers/usb/host/xhci-mtk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 7ff0cd707ba1..6fb6f6853129 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -611,6 +611,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
 			dev_err(dev, "set wakeup irq %d failed\n", wakeup_irq);
 			goto dealloc_usb3_hcd;
 		}
+		dev_pm_wake_irq_set_late_enabled_status(dev);
 		dev_info(dev, "wakeup irq %d\n", wakeup_irq);
 	}
 
-- 
2.25.1

From yunfei.dong at mediatek.com  Tue Aug 24 22:48:35 2021
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Wed, 25 Aug 2021 13:48:35 +0800
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <6224223ec1ead769f281af54f93bd3142a8e212b.camel@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
 <1b79a67b703d2c894bc4d9458c760e082fc42958.camel@mediatek.com>
 <CAAEAJfCTrKj9AFExN-L-TKww4E=us1VVh8LHtZ8Q0j_eaCD4Eg@mail.gmail.com>
 <1629446378.18871.27.camel@mhfsdcap03>
 <CAAEAJfCdvj4drV+YSbvyR30b0+50RpJcOYdEoNODTdrAoL6+vA@mail.gmail.com>
 <6224223ec1ead769f281af54f93bd3142a8e212b.camel@mediatek.com>
Message-ID: <24aa6baa63408c4cb9809e3f5c82e5f5df8b916f.camel@mediatek.com>

Hi Ezequiel,

You can get the dtsi information from patch 13, it is decoder yaml file
about component architecture:

[PATCH v4, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder dt-
bindings for mt8192

Thanks
Yunfei Dong

On Tue, 2021-08-24 at 18:21 +0800, yunfei.dong at mediatek.com wrote:
> Hi Ezequiel,
> 
> Thanks for your suggestion.
> 
> On Sun, 2021-08-22 at 11:32 -0300, Ezequiel Garcia wrote:
> > On Fri, 20 Aug 2021 at 04:59, yunfei.dong at mediatek.com
> > <yunfei.dong at mediatek.com> wrote:
> > > 
> > > Hi Ezequiel,
> > > 
> > > Thanks for your detail feedback.
> > > 
> > > On Thu, 2021-08-19 at 11:10 -0300, Ezequiel Garcia wrote:
> > > > On Thu, 19 Aug 2021 at 04:13, yunfei.dong at mediatek.com
> > > > <yunfei.dong at mediatek.com> wrote:
> > > > > 
> > > > > Hi Ezequiel,
> > > > > 
> > > > > Thanks for your suggestion.
> > > > > 
> > > > > On Wed, 2021-08-18 at 11:11 -0300, Ezequiel Garcia wrote:
> > > > > > +danvet
> > > > > > 
> > > > > > Hi,
> > > > > > 
> > > > > > On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <
> > > > > > yunfei.dong at mediatek.com>
> > > > > > wrote:
> > > > > > > 
> > > > > > > This series adds support for multi hardware decode into
> > > > > > > mtk-vcodec,
> > > > > > > by first
> > > > > > > adding component framework to manage each hardware
> > > > > > > information:
> > > > > > > interrupt,
> > > > > > > clock, register bases and power. Secondly add core thread
> > > > > > > to deal
> > > > > > > with core
> > > > > > > hardware message, at the same time, add msg queue for
> > > > > > > different
> > > > > > > hardware
> > > > > > > share messages. Lastly, the architecture of different
> > > > > > > specs
> > > > > > > are not
> > > > > > > the same,
> > > > > > > using specs type to separate them.
> > > > > > > 
> > > > > > 
> > > > > > I don't think it's a good idea to introduce the component
> > > > > > API
> > > > > > in the
> > > > > > media subsystem. It doesn't seem to be maintained, IRC
> > > > > > there's not
> > > > > > even
> > > > > > a maintainer for it, and it has some issues that were never
> > > > > > addressed.
> > > > > > 
> > > > > > It would be really important to avoid it. Is it really
> > > > > > needed
> > > > > > in the
> > > > > > first place?
> > > > > > 
> > > > > > Thanks,
> > > > > > Ezequiel
> > > > > 
> > > > > For there are many hardware need to use, mt8192 is three and
> > > > > mt8195 is
> > > > > five. Maybe need more to be used in the feature.
> > > > > 
> > > > > Each hardware has independent clk/power/iommu port/irq.
> > > > > Use component interface in prob to get each component's
> > > > > information.
> > > > > Just enable the hardware when need to use it, very convenient
> > > > > and
> > > > > simple.
> > > > > 
> > > > > I found that there are many modules use component to manage
> > > > > hardware
> > > > > information, such as iommu and drm etc.
> > > > > 
> > > > 
> > > > Many drivers support multiple hardware variants, where each
> > > > variant
> > > > has a different number of clocks or interrupts, see for
> > > > instance
> > > > struct hantro_variant which allows to expose different codec
> > > > cores,
> > > > some having both decoder/encoder, and some having just a
> > > > decoder.
> > > > 
> > > > The component API is mostly used by DRM to aggregate
> > > > independent
> > > > subdevices (called components) into an aggregated driver.
> > > > 
> > > > For instance, a DRM driver needs to glue together the HDMI,
> > > > MIPI,
> > > > and plany controller, or any other hardware arrangement where
> > > > devices can be described independently.
> > > > 
> > > 
> > > The usage scenario is very similar with drm and iommu, So decide
> > > to
> > > use
> > > component framework.
> > > Decode has three/five or more hardwares, these hardware are
> > > independent.
> > > For mt8183 just need core hardware to decode, but mt8192 has
> > > lat,soc and
> > > core hardware to decode. When lat need to use, just enable lat
> > > hardware,
> > > core is the same.And mt8195 will has two cores, each core can
> > > work
> > > well
> > > independent.
> > > 
> > > For each component device just used to open their power/clk/iommu
> > > port/irq when master need to enable it. The main logic is in
> > > master
> > > device.
> > > 
> > > > The component API may look simple but has some issues, it's not
> > > > easy
> > > > to debug, and can cause troubles if not used as expected [1].
> > > > It's worth making sure you actually need a framework
> > > > to glue different devices together.
> > > > 
> > > 
> > > Each hardware has its index, master can get hardware information
> > > according these index, looks not complex. What do you mean about
> > > not
> > > easy to debug?
> > > 
> > > > > Do you have any other suggestion for this architecture?
> > > > > 
> > > > 
> > > > Looking at the different patchsets that are posted, it's not
> > > > clear
> > > > to me what exactly are the different architectures that you
> > > > intend
> > > > to support, can you some documentation which clarifies that?
> > > > 
> > > 
> > > Have five hardwares lat,soc,core0,core1 and main. Lat thread can
> > > use lat
> > > soc and main, core thread can use soc,lat, core0 and core1. Core
> > > thread
> > > can be used or not for different project.
> > 
> > Can you explain what are these lat,soc and core threads for?
> > 
> 
> You can regards lat,soc and core as hardware, each hardware can work
> independent. Lat and core threads used to control hardware to decode.
> > > Also Need to use these
> > > hardware dynamic at the same time. So I use component framework,
> > > just
> > > need to know the used  hardware index according to different
> > > project.Need not to do complex logic to manage these hardwares.
> > > 
> > 
> > I am not thrilled to see the component framework introduced to the
> > media subsystem. Like I said, it has no clear maintainer, and it's
> > not
> > easy to use.
> > 
> 
> How do you think about Deniel Vetter's mail ? It looks that there are
> maintainer for it.
> > The media subsystem has some support which AFAIK does the same
> > thing,
> > see v4l2-async, which is maintained by media people.
> > 
> 
> If component can be used, I prefer to use it. At the other hand, I
> will
> try to use these method as compared.
> > Please push a branch based on media/master containing these
> > changes.
> > I see there are other patch series for this device, but it's hard
> > to
> > track
> > which goes first, etc.
> > 
> 
> I need time to push a branch, or you can get the latest kernel and
> git
> am these patches, maybe much quicker.
> > Thanks,
> > Ezequiel
> 
> Thanks,
> Yunfei Dong

From monstr at monstr.eu  Tue Aug 24 23:21:02 2021
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 25 Aug 2021 08:21:02 +0200
Subject: [PATCH] arm64: zynqmp: Remove not documented is-dual property
In-Reply-To: <876c53b92f99623bae45d5c0c5ae79ee3e24f745.1628239345.git.michal.simek@xilinx.com>
References: <876c53b92f99623bae45d5c0c5ae79ee3e24f745.1628239345.git.michal.simek@xilinx.com>
Message-ID: <CAHTX3dJMN+PVdz8Dx6JnCuSBbQdwF57HXNQT0xaUovz6JivcTg@mail.gmail.com>

p? 6. 8. 2021 v 10:42 odes?latel Michal Simek <michal.simek at xilinx.com> napsal:
>
> Remove is-dual not documented property and also update comment about QSPI
> sizes to reflect dual configuration as 16MB + 16MB.
> Only single configuration is supported now.
>
> Reported-by: Quanyang Wang <quanyang.wang at windriver.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
>  arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts | 3 +--
>  arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts | 3 +--
>  arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts | 3 +--
>  3 files changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> index becfc23a5610..3d8d14ef1ede 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> @@ -937,9 +937,8 @@ &psgtr {
>
>  &qspi {
>         status = "okay";
> -       is-dual = <1>;
>         flash at 0 {
> -               compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
> +               compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
>                 #address-cells = <1>;
>                 #size-cells = <1>;
>                 reg = <0x0>;
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> index d2219373580a..057c04352591 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> @@ -931,9 +931,8 @@ &psgtr {
>
>  &qspi {
>         status = "okay";
> -       is-dual = <1>;
>         flash at 0 {
> -               compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
> +               compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
>                 #address-cells = <1>;
>                 #size-cells = <1>;
>                 reg = <0x0>;
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> index dac5ba67a160..e1fff62a4cd5 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> @@ -773,9 +773,8 @@ &psgtr {
>
>  &qspi {
>         status = "okay";
> -       is-dual = <1>;
>         flash at 0 {
> -               compatible = "m25p80", "jedec,spi-nor"; /* 32MB */
> +               compatible = "m25p80", "jedec,spi-nor"; /* 16MB + 16MB */
>                 #address-cells = <1>;
>                 #size-cells = <1>;
>                 reg = <0x0>;
> --
> 2.32.0
>

Applied.
M

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From monstr at monstr.eu  Tue Aug 24 23:21:27 2021
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 25 Aug 2021 08:21:27 +0200
Subject: [PATCH] arm64: zynqmp: Fix serial compatible string
In-Reply-To: <89b36e0a6187cc6b05b27a035efdf79173bd4486.1628240307.git.michal.simek@xilinx.com>
References: <89b36e0a6187cc6b05b27a035efdf79173bd4486.1628240307.git.michal.simek@xilinx.com>
Message-ID: <CAHTX3d+WoUWPNHpzP41zLgVfagSiM7GxE-EQ22e+H4eeKNUcHQ@mail.gmail.com>

p? 6. 8. 2021 v 10:58 odes?latel Michal Simek <michal.simek at xilinx.com> napsal:
>
> Based on commit 65a2c14d4f00 ("dt-bindings: serial: convert Cadence UART
> bindings to YAML") compatible string should look like differently that's
> why fix it to be aligned with dt binding.
>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 6f0fcec28ae2..b5fde9dddca5 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -786,7 +786,7 @@ ttc3: timer at ff140000 {
>                 };
>
>                 uart0: serial at ff000000 {
> -                       compatible = "cdns,uart-r1p12", "xlnx,xuartps";
> +                       compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12";
>                         status = "disabled";
>                         interrupt-parent = <&gic>;
>                         interrupts = <0 21 4>;
> @@ -796,7 +796,7 @@ uart0: serial at ff000000 {
>                 };
>
>                 uart1: serial at ff010000 {
> -                       compatible = "cdns,uart-r1p12", "xlnx,xuartps";
> +                       compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12";
>                         status = "disabled";
>                         interrupt-parent = <&gic>;
>                         interrupts = <0 22 4>;
> --
> 2.32.0
>

Applied.
M

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From monstr at monstr.eu  Tue Aug 24 23:21:54 2021
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 25 Aug 2021 08:21:54 +0200
Subject: [PATCH] arm64: zynqmp: Enable gpio and qspi for zc1275-revA
In-Reply-To: <839d833133318feeb2755c4431204b0ef4788cce.1628244299.git.michal.simek@xilinx.com>
References: <839d833133318feeb2755c4431204b0ef4788cce.1628244299.git.michal.simek@xilinx.com>
Message-ID: <CAHTX3d+Tan44uNNzbwfc7gYxhagAioms+qVRFD62weS=cHDB4Q@mail.gmail.com>

p? 6. 8. 2021 v 12:05 odes?latel Michal Simek <michal.simek at xilinx.com> napsal:
>
> Add missing gpio and qspio for zc1275-revA board.
>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
>  .../boot/dts/xilinx/zynqmp-zc1275-revA.dts     | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
> index 66a90483b004..e971ba8c1418 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
> @@ -2,7 +2,7 @@
>  /*
>   * dts file for Xilinx ZynqMP ZC1275
>   *
> - * (C) Copyright 2017 - 2019, Xilinx, Inc.
> + * (C) Copyright 2017 - 2021, Xilinx, Inc.
>   *
>   * Michal Simek <michal.simek at xilinx.com>
>   * Siva Durga Prasad Paladugu <sivadur at xilinx.com>
> @@ -20,6 +20,7 @@ / {
>         aliases {
>                 serial0 = &uart0;
>                 serial1 = &dcc;
> +               spi0 = &qspi;
>         };
>
>         chosen {
> @@ -37,6 +38,21 @@ &dcc {
>         status = "okay";
>  };
>
> +&gpio {
> +       status = "okay";
> +};
> +
> +&qspi {
> +       status = "okay";
> +       flash at 0 {
> +               compatible = "m25p80", "jedec,spi-nor";
> +               reg = <0x0>;
> +               spi-tx-bus-width = <1>;
> +               spi-rx-bus-width = <4>;
> +               spi-max-frequency = <108000000>;
> +       };
> +};
> +
>  &uart0 {
>         status = "okay";
>  };
> --
> 2.32.0
>

Applied.
M

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From monstr at monstr.eu  Tue Aug 24 23:22:27 2021
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 25 Aug 2021 08:22:27 +0200
Subject: [PATCH] arm64: zynqmp: Wire psgtr for zc1751-xm013
In-Reply-To: <8c78625f08c16385a4798e0a62d20df7491ac00e.1628244860.git.michal.simek@xilinx.com>
References: <8c78625f08c16385a4798e0a62d20df7491ac00e.1628244860.git.michal.simek@xilinx.com>
Message-ID: <CAHTX3dJUH_DEKsLYNO0Z2StOBcnD5qynraJz_JLY_q_W6-nTTw@mail.gmail.com>

p? 6. 8. 2021 v 12:14 odes?latel Michal Simek <michal.simek at xilinx.com> napsal:
>
> Add psgtr description for SATA and USB.
>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
> Based on https://lore.kernel.org/r/cover.1628244703.git.michal.simek at xilinx.com
> ---
>  .../dts/xilinx/zynqmp-zc1751-xm017-dc3.dts    | 26 +++++++++++++++++++
>  1 file changed, 26 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> index 4394ec3b6a23..381cc682cef9 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> @@ -11,6 +11,7 @@
>
>  #include "zynqmp.dtsi"
>  #include "zynqmp-clk-ccf.dtsi"
> +#include <dt-bindings/phy/phy.h>
>
>  / {
>         model = "ZynqMP zc1751-xm017-dc3 RevA";
> @@ -37,6 +38,18 @@ memory at 0 {
>                 device_type = "memory";
>                 reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
>         };
> +
> +       clock_si5338_2: clk26 {
> +               compatible = "fixed-clock";
> +               #clock-cells = <0>;
> +               clock-frequency = <26000000>;
> +       };
> +
> +       clock_si5338_3: clk125 {
> +               compatible = "fixed-clock";
> +               #clock-cells = <0>;
> +               clock-frequency = <125000000>;
> +       };
>  };
>
>  &fpd_dma_chan1 {
> @@ -116,6 +129,13 @@ &nand0 {
>         num-cs = <2>;
>  };
>
> +&psgtr {
> +       status = "okay";
> +       /* usb3, sata */
> +       clocks = <&clock_si5338_2>, <&clock_si5338_3>;
> +       clock-names = "ref2", "ref3";
> +};
> +
>  &rtc {
>         status = "okay";
>  };
> @@ -131,6 +151,8 @@ &sata {
>         ceva,p1-comwake-params = /bits/ 8 <0x06 0x19 0x08 0x0E>;
>         ceva,p1-burst-params = /bits/ 8 <0x13 0x08 0x4A 0x06>;
>         ceva,p1-retry-params = /bits/ 16 <0x96A4 0x3FFC>;
> +       phy-names = "sata-phy";
> +       phys = <&psgtr 2 PHY_TYPE_SATA 0 3>;
>  };
>
>  &sdhci1 { /* emmc with some settings */
> @@ -149,6 +171,8 @@ &uart1 {
>
>  &usb0 {
>         status = "okay";
> +       phy-names = "usb3-phy";
> +       phys = <&psgtr 0 PHY_TYPE_USB3 0 2>;
>  };
>
>  &dwc3_0 {
> @@ -161,6 +185,8 @@ &dwc3_0 {
>  /* ULPI SMSC USB3320 */
>  &usb1 {
>         status = "okay";
> +       phy-names = "usb3-phy";
> +       phys = <&psgtr 3 PHY_TYPE_USB3 1 2>;
>  };
>
>  &dwc3_1 {
> --
> 2.32.0
>

Applied.
M

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From monstr at monstr.eu  Tue Aug 24 23:24:07 2021
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 25 Aug 2021 08:24:07 +0200
Subject: [PATCH v3 1/2] arm64: zynqmp: Enable xlnx, zynqmp-dwc3 driver for
 xilinx boards
In-Reply-To: <640a3bc0dc3e32560d3e84c2f78b5ae561396eb0.1628244703.git.michal.simek@xilinx.com>
References: <cover.1628244703.git.michal.simek@xilinx.com>
 <640a3bc0dc3e32560d3e84c2f78b5ae561396eb0.1628244703.git.michal.simek@xilinx.com>
Message-ID: <CAHTX3dJ5JYi=8yNNA=F=T16Dmm6pe-RR14m_Ub9058NXa_Z_7Q@mail.gmail.com>

p? 6. 8. 2021 v 12:12 odes?latel Michal Simek <michal.simek at xilinx.com> napsal:
>
> The commit 84770f028fab ("usb: dwc3: Add driver for Xilinx platforms")
> finally add proper support for Xilinx dwc3 driver. This patch is adding DT
> description for it.
>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
> Changes in v3:
> - usb node name fix, remove undocumented properties reported by Michael Tretter
> - Also remove status property from dwc3_0/1 nodes reported by Michael
>   Tretter
> - Move USB3 PHY properties from DWC3 node to USB node - reported by Manish
>   Narani
>
> Changes in v2:
> - New patch in the series
>
>  .../dts/xilinx/zynqmp-zc1751-xm015-dc1.dts    |  8 ++-
>  .../dts/xilinx/zynqmp-zc1751-xm016-dc2.dts    |  7 +++
>  .../dts/xilinx/zynqmp-zc1751-xm017-dc3.dts    | 14 +++++
>  .../boot/dts/xilinx/zynqmp-zcu100-revC.dts    | 14 ++++-
>  .../boot/dts/xilinx/zynqmp-zcu102-revA.dts    |  8 ++-
>  .../boot/dts/xilinx/zynqmp-zcu104-revA.dts    |  8 ++-
>  .../boot/dts/xilinx/zynqmp-zcu104-revC.dts    |  8 ++-
>  .../boot/dts/xilinx/zynqmp-zcu106-revA.dts    |  8 ++-
>  .../boot/dts/xilinx/zynqmp-zcu111-revA.dts    |  8 ++-
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 60 +++++++++++++++----
>  10 files changed, 122 insertions(+), 21 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
> index d93fe2efa39d..b05be2552826 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
> @@ -27,6 +27,7 @@ aliases {
>                 rtc0 = &rtc;
>                 serial0 = &uart0;
>                 spi0 = &qspi;
> +               usb0 = &usb0;
>         };
>
>         chosen {
> @@ -404,9 +405,14 @@ &usb0 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb0_default>;
> -       dr_mode = "host";
>         phy-names = "usb3-phy";
>         phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +       status = "okay";
> +       dr_mode = "host";
> +       snps,usb3_lpm_capable;
>         maximum-speed = "super-speed";
>  };
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
> index cd61550c52e5..938b76bd0527 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
> @@ -26,6 +26,7 @@ aliases {
>                 serial1 = &uart1;
>                 spi0 = &spi0;
>                 spi1 = &spi1;
> +               usb0 = &usb1;
>         };
>
>         chosen {
> @@ -479,7 +480,13 @@ &usb1 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb1_default>;
> +};
> +
> +&dwc3_1 {
> +       status = "okay";
>         dr_mode = "host";
> +       snps,usb3_lpm_capable;
> +       maximum-speed = "super-speed";
>  };
>
>  &uart0 {
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> index ba7f1f21c579..4394ec3b6a23 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
> @@ -24,6 +24,8 @@ aliases {
>                 rtc0 = &rtc;
>                 serial0 = &uart0;
>                 serial1 = &uart1;
> +               usb0 = &usb0;
> +               usb1 = &usb1;
>         };
>
>         chosen {
> @@ -147,11 +149,23 @@ &uart1 {
>
>  &usb0 {
>         status = "okay";
> +};
> +
> +&dwc3_0 {
> +       status = "okay";
>         dr_mode = "host";
> +       snps,usb3_lpm_capable;
> +       maximum-speed = "super-speed";
>  };
>
>  /* ULPI SMSC USB3320 */
>  &usb1 {
>         status = "okay";
> +};
> +
> +&dwc3_1 {
> +       status = "okay";
>         dr_mode = "host";
> +       snps,usb3_lpm_capable;
> +       maximum-speed = "super-speed";
>  };
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> index 80415e202814..f6aad4159ccd 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
> @@ -30,6 +30,8 @@ aliases {
>                 serial2 = &dcc;
>                 spi0 = &spi0;
>                 spi1 = &spi1;
> +               usb0 = &usb0;
> +               usb1 = &usb1;
>                 mmc0 = &sdhci0;
>                 mmc1 = &sdhci1;
>         };
> @@ -537,9 +539,13 @@ &usb0 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb0_default>;
> -       dr_mode = "peripheral";
>         phy-names = "usb3-phy";
>         phys = <&psgtr 2 PHY_TYPE_USB3 0 0>;
> +};
> +
> +&dwc3_0 {
> +       status = "okay";
> +       dr_mode = "peripheral";
>         maximum-speed = "super-speed";
>  };
>
> @@ -548,9 +554,13 @@ &usb1 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb1_default>;
> -       dr_mode = "host";
>         phy-names = "usb3-phy";
>         phys = <&psgtr 3 PHY_TYPE_USB3 1 0>;
> +};
> +
> +&dwc3_1 {
> +       status = "okay";
> +       dr_mode = "host";
>         maximum-speed = "super-speed";
>  };
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> index 3d8d14ef1ede..7b9a88b125d1 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
> @@ -31,6 +31,7 @@ aliases {
>                 serial1 = &uart1;
>                 serial2 = &dcc;
>                 spi0 = &qspi;
> +               usb0 = &usb0;
>         };
>
>         chosen {
> @@ -997,9 +998,14 @@ &usb0 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb0_default>;
> -       dr_mode = "host";
>         phy-names = "usb3-phy";
>         phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +       status = "okay";
> +       dr_mode = "host";
> +       snps,usb3_lpm_capable;
>         maximum-speed = "super-speed";
>  };
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
> index 86fff3632c7d..bd8f20f3223d 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
> @@ -29,6 +29,7 @@ aliases {
>                 serial1 = &uart1;
>                 serial2 = &dcc;
>                 spi0 = &qspi;
> +               usb0 = &usb0;
>         };
>
>         chosen {
> @@ -481,9 +482,14 @@ &usb0 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb0_default>;
> -       dr_mode = "host";
>         phy-names = "usb3-phy";
>         phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +       status = "okay";
> +       dr_mode = "host";
> +       snps,usb3_lpm_capable;
>         maximum-speed = "super-speed";
>  };
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
> index 2a872d439804..96feaad30166 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
> @@ -29,6 +29,7 @@ aliases {
>                 serial1 = &uart1;
>                 serial2 = &dcc;
>                 spi0 = &qspi;
> +               usb0 = &usb0;
>         };
>
>         chosen {
> @@ -493,9 +494,14 @@ &usb0 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb0_default>;
> -       dr_mode = "host";
>         phy-names = "usb3-phy";
>         phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +       status = "okay";
> +       dr_mode = "host";
> +       snps,usb3_lpm_capable;
>         maximum-speed = "super-speed";
>  };
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> index 057c04352591..20b7c75bb1d3 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
> @@ -31,6 +31,7 @@ aliases {
>                 serial1 = &uart1;
>                 serial2 = &dcc;
>                 spi0 = &qspi;
> +               usb0 = &usb0;
>         };
>
>         chosen {
> @@ -990,9 +991,14 @@ &usb0 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb0_default>;
> -       dr_mode = "host";
>         phy-names = "usb3-phy";
>         phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +       status = "okay";
> +       dr_mode = "host";
> +       snps,usb3_lpm_capable;
>         maximum-speed = "super-speed";
>  };
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> index e1fff62a4cd5..e36df6adbeee 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
> @@ -30,6 +30,7 @@ aliases {
>                 serial0 = &uart0;
>                 serial1 = &dcc;
>                 spi0 = &qspi;
> +               usb0 = &usb0;
>         };
>
>         chosen {
> @@ -827,9 +828,14 @@ &usb0 {
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&pinctrl_usb0_default>;
> -       dr_mode = "host";
>         phy-names = "usb3-phy";
>         phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
> +};
> +
> +&dwc3_0 {
> +       status = "okay";
> +       dr_mode = "host";
> +       snps,usb3_lpm_capable;
>         maximum-speed = "super-speed";
>  };
>
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index b5fde9dddca5..74e66443e4ce 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -2,7 +2,7 @@
>  /*
>   * dts file for Xilinx ZynqMP
>   *
> - * (C) Copyright 2014 - 2019, Xilinx, Inc.
> + * (C) Copyright 2014 - 2021, Xilinx, Inc.
>   *
>   * Michal Simek <michal.simek at xilinx.com>
>   *
> @@ -805,24 +805,58 @@ uart1: serial at ff010000 {
>                         power-domains = <&zynqmp_firmware PD_UART_1>;
>                 };
>
> -               usb0: usb at fe200000 {
> -                       compatible = "snps,dwc3";
> +               usb0: usb at ff9d0000 {
> +                       #address-cells = <2>;
> +                       #size-cells = <2>;
>                         status = "disabled";
> -                       interrupt-parent = <&gic>;
> -                       interrupts = <0 65 4>;
> -                       reg = <0x0 0xfe200000 0x0 0x40000>;
> -                       clock-names = "clk_xin", "clk_ahb";
> +                       compatible = "xlnx,zynqmp-dwc3";
> +                       reg = <0x0 0xff9d0000 0x0 0x100>;
> +                       clock-names = "bus_clk", "ref_clk";
>                         power-domains = <&zynqmp_firmware PD_USB_0>;
> +                       resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>,
> +                                <&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>,
> +                                <&zynqmp_reset ZYNQMP_RESET_USB0_APB>;
> +                       reset-names = "usb_crst", "usb_hibrst", "usb_apbrst";
> +                       ranges;
> +
> +                       dwc3_0: usb at fe200000 {
> +                               compatible = "snps,dwc3";
> +                               reg = <0x0 0xfe200000 0x0 0x40000>;
> +                               interrupt-parent = <&gic>;
> +                               interrupt-names = "dwc_usb3", "otg";
> +                               interrupts = <0 65 4>, <0 69 4>;
> +                               #stream-id-cells = <1>;
> +                               iommus = <&smmu 0x860>;
> +                               snps,quirk-frame-length-adjustment = <0x20>;
> +                               /* dma-coherent; */
> +                       };
>                 };
>
> -               usb1: usb at fe300000 {
> -                       compatible = "snps,dwc3";
> +               usb1: usb at ff9e0000 {
> +                       #address-cells = <2>;
> +                       #size-cells = <2>;
>                         status = "disabled";
> -                       interrupt-parent = <&gic>;
> -                       interrupts = <0 70 4>;
> -                       reg = <0x0 0xfe300000 0x0 0x40000>;
> -                       clock-names = "clk_xin", "clk_ahb";
> +                       compatible = "xlnx,zynqmp-dwc3";
> +                       reg = <0x0 0xff9e0000 0x0 0x100>;
> +                       clock-names = "bus_clk", "ref_clk";
>                         power-domains = <&zynqmp_firmware PD_USB_1>;
> +                       resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>,
> +                                <&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>,
> +                                <&zynqmp_reset ZYNQMP_RESET_USB1_APB>;
> +                       reset-names = "usb_crst", "usb_hibrst", "usb_apbrst";
> +                       ranges;
> +
> +                       dwc3_1: usb at fe300000 {
> +                               compatible = "snps,dwc3";
> +                               reg = <0x0 0xfe300000 0x0 0x40000>;
> +                               interrupt-parent = <&gic>;
> +                               interrupt-names = "dwc_usb3", "otg";
> +                               interrupts = <0 70 4>, <0 74 4>;
> +                               #stream-id-cells = <1>;
> +                               iommus = <&smmu 0x861>;
> +                               snps,quirk-frame-length-adjustment = <0x20>;
> +                               /* dma-coherent; */
> +                       };
>                 };
>
>                 watchdog0: watchdog at fd4d0000 {
> --
> 2.32.0
>

Applied but only this patch. For Kria still waiting for Rob's reaction.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs


From caihuoqing at baidu.com  Tue Aug 24 23:25:13 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 25 Aug 2021 14:25:13 +0800
Subject: [PATCH] net: ethernet: actions: Add helper dependency on COMPILE_TEST
Message-ID: <20210825062513.2384-1-caihuoqing@baidu.com>

it's helpful for complie test in other platform(e.g.X86)

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/net/ethernet/actions/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/actions/Kconfig b/drivers/net/ethernet/actions/Kconfig
index ccad6a3f4d6f..dedad1fffdc3 100644
--- a/drivers/net/ethernet/actions/Kconfig
+++ b/drivers/net/ethernet/actions/Kconfig
@@ -2,8 +2,8 @@
 
 config NET_VENDOR_ACTIONS
 	bool "Actions Semi devices"
-	default y
-	depends on ARCH_ACTIONS
+	depends on ARCH_ACTIONS || COMPILE_TEST
+	default ARCH_ACTIONS
 	help
 	  If you have a network (Ethernet) card belonging to this class, say Y.
 
-- 
2.25.1



From eizan at chromium.org  Tue Aug 24 23:33:16 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 25 Aug 2021 16:33:16 +1000
Subject: [PATCH v7 0/7] Refactor MTK MDP driver into core/components
Message-ID: <20210825063323.3607738-1-eizan@chromium.org>


This is an update to
https://patchwork.kernel.org/project/linux-mediatek/list/?series=283075
To address some comments and fixes.

This series has been verified to work on 5.13.


Changes in v7:
- Drop last two changes from this series related to removing the vpu
  property from the mdp_rdma0 device node

Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

Eizan Miyamoto (7):
  mtk-mdp: propagate errors from clock_on
  mtk-mdp: add driver to probe mdp components
  mtk-mdp: use pm_runtime in MDP component driver
  media: mtk-mdp: don't pm_run_time_get/put for master comp in clock_on
  mtk-mdp: make mdp driver to be loadable by platform_device_register*()
  soc: mediatek: mmsys: instantiate mdp virtual device from mmsys
  media: mtk-mdp: use mdp-rdma0 alias to point to MDP master

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 268 +++++++++++++++--
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  34 +--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 282 ++++++++++++------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   3 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |   4 +-
 drivers/soc/mediatek/mtk-mmsys.c              |  20 +-
 6 files changed, 470 insertions(+), 141 deletions(-)

-- 
2.33.0.rc2.250.ged5fa647cd-goog



From eizan at chromium.org  Tue Aug 24 23:33:17 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 25 Aug 2021 16:33:17 +1000
Subject: [PATCH v7 1/7] mtk-mdp: propagate errors from clock_on
In-Reply-To: <20210825063323.3607738-1-eizan@chromium.org>
References: <20210825063323.3607738-1-eizan@chromium.org>
Message-ID: <20210825163247.v7.1.I9db0d408ef79d300672ec0311a6bee9556801631@changeid>

Up until this change, many errors were logged but ignored when powering
on clocks inside mtk_mdp_core. This change tries to do a better job at
propagating errors back to the power management framework.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 25 ++++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 27 ++++++++++++++-----
 3 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index b3426a551bea..76e295c8d9bc 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -13,10 +13,9 @@
 
 #include "mtk_mdp_comp.h"
 
-
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
-	int i, err;
+	int i, err, status;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
@@ -30,11 +29,23 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		if (IS_ERR(comp->clk[i]))
 			continue;
 		err = clk_prepare_enable(comp->clk[i]);
-		if (err)
-			dev_err(dev,
-			"failed to enable clock, err %d. type:%d i:%d\n",
-				err, comp->type, i);
+		if (err) {
+			status = err;
+			dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+			goto err_clk_prepare_enable;
+		}
+	}
+
+	return 0;
+
+err_clk_prepare_enable:
+	for (--i; i >= 0; i--) {
+		if (IS_ERR(comp->clk[i]))
+			continue;
+		clk_disable_unprepare(comp->clk[i]);
 	}
+
+	return status;
 }
 
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 7897766c96bb..92ab5249bcad 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -41,7 +41,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		      struct mtk_mdp_comp *comp,
 		      enum mtk_mdp_comp_type comp_type);
 void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
 
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 976aa1f4829b..412bbec0f735 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -52,13 +52,28 @@ static const struct of_device_id mtk_mdp_of_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_of_ids);
 
-static void mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 {
-	struct device *dev = &mdp->pdev->dev;
 	struct mtk_mdp_comp *comp_node;
+	int status;
+	struct device *dev = &mdp->pdev->dev;
+	int err;
 
-	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_on(dev, comp_node);
+	list_for_each_entry(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_clock_on(dev, comp_node);
+		if (err) {
+			status = err;
+			goto err_mtk_mdp_comp_clock_on;
+		}
+	}
+
+	return 0;
+
+err_mtk_mdp_comp_clock_on:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
+		mtk_mdp_comp_clock_off(dev, comp_node);
+
+	return status;
 }
 
 static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
@@ -274,9 +289,7 @@ static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
 {
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_clock_on(mdp);
-
-	return 0;
+	return mtk_mdp_clock_on(mdp);
 }
 
 static int __maybe_unused mtk_mdp_suspend(struct device *dev)
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From eizan at chromium.org  Tue Aug 24 23:33:18 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 25 Aug 2021 16:33:18 +1000
Subject: [PATCH v7 2/7] mtk-mdp: add driver to probe mdp components
In-Reply-To: <20210825063323.3607738-1-eizan@chromium.org>
References: <20210825063323.3607738-1-eizan@chromium.org>
Message-ID: <20210825163247.v7.2.Ie6d1e6e39cf9b5d6b2108ae1096af34c3d55880b@changeid>

Broadly, this patch (1) adds a driver for various MTK MDP components to
go alongside the main MTK MDP driver, and (2) hooks them all together
using the component framework.

(1) Up until now, the MTK MDP driver controls 8 devices in the device
tree on its own. When running tests for the hardware video decoder, we
found that the iommus and LARBs were not being properly configured. To
configure them, a driver for each be added to mtk_mdp_comp so that
mtk_iommu_add_device() can (eventually) be called from dma_configure()
inside really_probe().

(2) The integration into the component framework allows us to defer the
registration with the v4l2 subsystem until all the MDP-related devices
have been probed, so that the relevant device node does not become
available until initialization of all the components is complete.

Some notes about how the component framework has been integrated:

- The driver for the rdma0 component serves double duty as the "master"
  (aggregate) driver as well as a component driver. This is a non-ideal
  compromise until a better solution is developed. This device is
  differentiated from the rest by checking for a "mediatek,vpu" property
  in the device node.

- The list of mdp components remains hard-coded as mtk_mdp_comp_dt_ids[]
  in mtk_mdp_core.c, and as mtk_mdp_comp_driver_dt_match[] in
  mtk_mdp_comp.c. This unfortunate duplication of information is
  addressed in a following patch in this series.

- The component driver calls component_add() for each device that is
  probed.

- In mtk_mdp_probe (the "master" device), we scan the device tree for
  any matching nodes against mtk_mdp_comp_dt_ids, and add component
  matches for them. The match criteria is a matching device node
  pointer.

- When the set of components devices that have been probed corresponds
  with the list that is generated by the "master", the callback to
  mtk_mdp_master_bind() is made, which then calls the component bind
  functions.

- Inside mtk_mdp_master_bind(), once all the component bind functions
  have been called, we can then register our device to the v4l2
  subsystem.

- The call to pm_runtime_enable() in the master device is called after
  all the components have been registered by their bind() functions
  called by mtk_mtp_master_bind(). As a result, the list of components
  will not change while power management callbacks mtk_mdp_suspend()/
  resume() are accessing the list of components.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 143 ++++++++++++--
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  25 +--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 174 +++++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |   1 +
 4 files changed, 252 insertions(+), 91 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 76e295c8d9bc..7a0e3acffab9 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -5,13 +5,50 @@
  */
 
 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/of.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <soc/mediatek/smi.h>
 
 #include "mtk_mdp_comp.h"
+#include "mtk_mdp_core.h"
+
+/**
+ * enum mtk_mdp_comp_type - the MDP component
+ * @MTK_MDP_RDMA:		Read DMA
+ * @MTK_MDP_RSZ:		Reszer
+ * @MTK_MDP_WDMA:		Write DMA
+ * @MTK_MDP_WROT:		Write DMA with rotation
+ * @MTK_MDP_COMP_TYPE_MAX:	Placeholder for num elems in this enum
+ */
+enum mtk_mdp_comp_type {
+	MTK_MDP_RDMA,
+	MTK_MDP_RSZ,
+	MTK_MDP_WDMA,
+	MTK_MDP_WROT,
+	MTK_MDP_COMP_TYPE_MAX,
+};
+
+static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
+	{
+		.compatible = "mediatek,mt8173-mdp-rdma",
+		.data = (void *)MTK_MDP_RDMA
+	}, {
+		.compatible = "mediatek,mt8173-mdp-rsz",
+		.data = (void *)MTK_MDP_RSZ
+	}, {
+		.compatible = "mediatek,mt8173-mdp-wdma",
+		.data = (void *)MTK_MDP_WDMA
+	}, {
+		.compatible = "mediatek,mt8173-mdp-wrot",
+		.data = (void *)MTK_MDP_WROT
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
 int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
@@ -20,9 +57,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
 		if (err)
-			dev_err(dev,
-				"failed to get larb, err %d. type:%d\n",
-				err, comp->type);
+			dev_err(dev, "failed to get larb, err %d.\n", err);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -62,17 +97,41 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
 		mtk_smi_larb_put(comp->larb_dev);
 }
 
-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-		      struct mtk_mdp_comp *comp,
-		      enum mtk_mdp_comp_type comp_type)
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+{
+	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+	struct mtk_mdp_dev *mdp = data;
+
+	mtk_mdp_register_component(mdp, comp);
+
+	return 0;
+}
+
+static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
+	struct mtk_mdp_dev *mdp = data;
+
+	mtk_mdp_unregister_component(mdp, comp);
+}
+
+static const struct component_ops mtk_mdp_component_ops = {
+	.bind   = mtk_mdp_comp_bind,
+	.unbind = mtk_mdp_comp_unbind,
+};
+
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 {
 	struct device_node *larb_node;
 	struct platform_device *larb_pdev;
 	int ret;
 	int i;
+	struct device_node *node = dev->of_node;
+	enum mtk_mdp_comp_type comp_type =
+		 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
 
-	comp->dev_node = of_node_get(node);
-	comp->type = comp_type;
+	INIT_LIST_HEAD(&comp->node);
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		comp->clk[i] = of_clk_get(node, i);
@@ -80,19 +139,17 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 			if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
 				dev_err(dev, "Failed to get clock\n");
 			ret = PTR_ERR(comp->clk[i]);
-			goto put_dev;
+			goto err;
 		}
 
 		/* Only RDMA needs two clocks */
-		if (comp->type != MTK_MDP_RDMA)
+		if (comp_type != MTK_MDP_RDMA)
 			break;
 	}
 
 	/* Only DMA capable components need the LARB property */
 	comp->larb_dev = NULL;
-	if (comp->type != MTK_MDP_RDMA &&
-	    comp->type != MTK_MDP_WDMA &&
-	    comp->type != MTK_MDP_WROT)
+	if (comp_type != MTK_MDP_RDMA && comp_type != MTK_MDP_WDMA && comp_type != MTK_MDP_WROT)
 		return 0;
 
 	larb_node = of_parse_phandle(node, "mediatek,larb", 0);
@@ -100,7 +157,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		dev_err(dev,
 			"Missing mediadek,larb phandle in %pOF node\n", node);
 		ret = -EINVAL;
-		goto put_dev;
+		goto err;
 	}
 
 	larb_pdev = of_find_device_by_node(larb_node);
@@ -108,7 +165,7 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
 		of_node_put(larb_node);
 		ret = -EPROBE_DEFER;
-		goto put_dev;
+		goto err;
 	}
 	of_node_put(larb_node);
 
@@ -116,13 +173,59 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 
 	return 0;
 
-put_dev:
-	of_node_put(comp->dev_node);
-
+err:
 	return ret;
 }
 
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
+static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
-	of_node_put(comp->dev_node);
+	struct device *dev = &pdev->dev;
+	struct device_node *vpu_node;
+	int status;
+	struct mtk_mdp_comp *comp;
+
+	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+	if (vpu_node) {
+		of_node_put(vpu_node);
+		/*
+		 * The device tree node with a mediatek,vpu property is deemed
+		 * the MDP "master" device, we don't want to add a component
+		 * for it in this function because the initialization for the
+		 * master is done elsewhere.
+		 */
+		dev_info(dev, "vpu node found, not probing\n");
+		return -ENODEV;
+	}
+
+	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+	if (!comp)
+		return -ENOMEM;
+
+	status = mtk_mdp_comp_init(comp, dev);
+	if (status) {
+		dev_err(dev, "Failed to initialize component: %d\n", status);
+		return status;
+	}
+
+	dev_set_drvdata(dev, comp);
+
+	return component_add(dev, &mtk_mdp_component_ops);
 }
+
+static int mtk_mdp_comp_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+
+	component_del(dev, &mtk_mdp_component_ops);
+	return 0;
+}
+
+struct platform_driver mtk_mdp_component_driver = {
+	.probe          = mtk_mdp_comp_probe,
+	.remove         = mtk_mdp_comp_remove,
+	.driver         = {
+		.name   = "mediatek-mdp-comp",
+		.owner  = THIS_MODULE,
+		.of_match_table = mtk_mdp_comp_driver_dt_match,
+	},
+};
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 92ab5249bcad..df5fc4c94f90 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -7,42 +7,23 @@
 #ifndef __MTK_MDP_COMP_H__
 #define __MTK_MDP_COMP_H__
 
-/**
- * enum mtk_mdp_comp_type - the MDP component
- * @MTK_MDP_RDMA:	Read DMA
- * @MTK_MDP_RSZ:	Riszer
- * @MTK_MDP_WDMA:	Write DMA
- * @MTK_MDP_WROT:	Write DMA with rotation
- */
-enum mtk_mdp_comp_type {
-	MTK_MDP_RDMA,
-	MTK_MDP_RSZ,
-	MTK_MDP_WDMA,
-	MTK_MDP_WROT,
-};
-
 /**
  * struct mtk_mdp_comp - the MDP's function component data
  * @node:	list node to track sibing MDP components
- * @dev_node:	component device node
  * @clk:	clocks required for component
  * @larb_dev:	SMI device required for component
- * @type:	component type
  */
 struct mtk_mdp_comp {
 	struct list_head	node;
-	struct device_node	*dev_node;
 	struct clk		*clk[2];
 	struct device		*larb_dev;
-	enum mtk_mdp_comp_type	type;
 };
 
-int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
-		      struct mtk_mdp_comp *comp,
-		      enum mtk_mdp_comp_type comp_type);
-void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
+
 int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
 
+extern struct platform_driver mtk_mdp_component_driver;
 
 #endif /* __MTK_MDP_COMP_H__ */
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 412bbec0f735..b813a822439a 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
@@ -19,6 +20,7 @@
 #include <linux/workqueue.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_mdp_comp.h"
 #include "mtk_mdp_core.h"
 #include "mtk_mdp_m2m.h"
 #include "mtk_vpu.h"
@@ -32,16 +34,12 @@ module_param(mtk_mdp_dbg_level, int, 0644);
 static const struct of_device_id mtk_mdp_comp_dt_ids[] = {
 	{
 		.compatible = "mediatek,mt8173-mdp-rdma",
-		.data = (void *)MTK_MDP_RDMA
 	}, {
 		.compatible = "mediatek,mt8173-mdp-rsz",
-		.data = (void *)MTK_MDP_RSZ
 	}, {
 		.compatible = "mediatek,mt8173-mdp-wdma",
-		.data = (void *)MTK_MDP_WDMA
 	}, {
 		.compatible = "mediatek,mt8173-mdp-wrot",
-		.data = (void *)MTK_MDP_WROT
 	},
 	{ },
 };
@@ -106,6 +104,63 @@ static void mtk_mdp_reset_handler(void *priv)
 	queue_work(mdp->wdt_wq, &mdp->wdt_work);
 }
 
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static void release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
+static int mtk_mdp_master_bind(struct device *dev)
+{
+	int status;
+	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+	mtk_mdp_register_component(mdp, &mdp->comp_self);
+
+	status = component_bind_all(dev, mdp);
+	if (status) {
+		dev_err(dev, "Failed to bind all components: %d\n", status);
+		goto err_component_bind_all;
+	}
+
+	status = mtk_mdp_register_m2m_device(mdp);
+	if (status) {
+		dev_err(dev, "Failed to register m2m device: %d\n", status);
+		goto err_mtk_mdp_register_m2m_device;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+
+err_mtk_mdp_register_m2m_device:
+	component_unbind_all(dev, mdp);
+
+err_component_bind_all:
+	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+
+	return status;
+}
+
+static void mtk_mdp_master_unbind(struct device *dev)
+{
+	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+
+	pm_runtime_disable(dev);
+	mtk_mdp_unregister_m2m_device(mdp);
+	component_unbind_all(dev, mdp);
+	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
+}
+
+static const struct component_master_ops mtk_mdp_com_ops = {
+	.bind		= mtk_mdp_master_bind,
+	.unbind		= mtk_mdp_master_unbind,
+};
+
 void mtk_mdp_register_component(struct mtk_mdp_dev *mdp,
 				struct mtk_mdp_comp *comp)
 {
@@ -123,8 +178,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	struct mtk_mdp_dev *mdp;
 	struct device *dev = &pdev->dev;
 	struct device_node *node, *parent;
-	struct mtk_mdp_comp *comp, *comp_temp;
-	int ret = 0;
+	int i, ret = 0;
+	struct component_match *match = NULL;
 
 	mdp = devm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
 	if (!mdp)
@@ -149,36 +204,43 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	}
 
 	/* Iterate over sibling MDP function blocks */
+	i = 0;
 	for_each_child_of_node(parent, node) {
-		const struct of_device_id *of_id;
-		enum mtk_mdp_comp_type comp_type;
+		struct platform_device *pdev;
 
-		of_id = of_match_node(mtk_mdp_comp_dt_ids, node);
-		if (!of_id)
+		if (!of_match_node(mtk_mdp_comp_dt_ids, node))
 			continue;
 
-		if (!of_device_is_available(node)) {
-			dev_err(dev, "Skipping disabled component %pOF\n",
-				node);
+		if (!of_device_is_available(node))
 			continue;
-		}
-
-		comp_type = (enum mtk_mdp_comp_type)of_id->data;
 
-		comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
-		if (!comp) {
-			ret = -ENOMEM;
-			of_node_put(node);
-			goto err_comp;
+		pdev = of_find_device_by_node(node);
+		if (!pdev) {
+			dev_warn(dev, "Unable to find comp device %s\n",
+				 node->full_name);
+			continue;
 		}
 
-		ret = mtk_mdp_comp_init(dev, node, comp, comp_type);
-		if (ret) {
-			of_node_put(node);
-			goto err_comp;
+		/*
+		 * Do not add a match for my own (rdma0) device node.
+		 * I will be managing it directly instead using comp_self.
+		 */
+		if (&pdev->dev != dev) {
+			dev_dbg(dev, "adding match %d for: %pOF\n", i++, node);
+			component_match_add_release(dev, &match, release_of,
+						    compare_of,
+						    of_node_get(node));
 		}
+	}
 
-		mtk_mdp_register_component(mdp, comp);
+	/*
+	 * Create a component for myself so that clocks can be toggled in
+	 * clock_on().
+	 */
+	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
+	if (ret) {
+		dev_err(dev, "Failed to initialize component\n");
+		goto err_comp;
 	}
 
 	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
@@ -203,18 +265,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		goto err_dev_register;
 	}
 
-	ret = mtk_mdp_register_m2m_device(mdp);
-	if (ret) {
-		v4l2_err(&mdp->v4l2_dev, "Failed to init mem2mem device\n");
-		goto err_m2m_register;
-	}
-
 	mdp->vpu_dev = vpu_get_plat_device(pdev);
 	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
 				  VPU_RST_MDP);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register reset handler\n");
-		goto err_m2m_register;
+		goto err_wdt_reg;
 	}
 
 	platform_set_drvdata(pdev, mdp);
@@ -222,15 +278,25 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-		goto err_m2m_register;
+		goto err_set_max_seg_size;
+	}
+
+	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
+	if (ret) {
+		dev_err(dev, "Component master add failed\n");
+		goto err_component_master_add;
 	}
 
-	pm_runtime_enable(dev);
 	dev_dbg(dev, "mdp-%d registered successfully\n", mdp->id);
 
 	return 0;
 
-err_m2m_register:
+err_component_master_add:
+	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
+
+err_set_max_seg_size:
+
+err_wdt_reg:
 	v4l2_device_unregister(&mdp->v4l2_dev);
 
 err_dev_register:
@@ -242,11 +308,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 err_alloc_job_wq:
 
 err_comp:
-	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-		mtk_mdp_unregister_component(mdp, comp);
-		mtk_mdp_comp_deinit(dev, comp);
-	}
-
 	dev_dbg(dev, "err %d\n", ret);
 	return ret;
 }
@@ -254,11 +315,10 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 static int mtk_mdp_remove(struct platform_device *pdev)
 {
 	struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
-	struct mtk_mdp_comp *comp, *comp_temp;
 
-	pm_runtime_disable(&pdev->dev);
+	component_master_del(&pdev->dev, &mtk_mdp_com_ops);
+
 	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-	mtk_mdp_unregister_m2m_device(mdp);
 	v4l2_device_unregister(&mdp->v4l2_dev);
 
 	flush_workqueue(mdp->wdt_wq);
@@ -267,10 +327,8 @@ static int mtk_mdp_remove(struct platform_device *pdev)
 	flush_workqueue(mdp->job_wq);
 	destroy_workqueue(mdp->job_wq);
 
-	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-		mtk_mdp_unregister_component(mdp, comp);
-		mtk_mdp_comp_deinit(&pdev->dev, comp);
-	}
+	if (!list_empty(&mdp->comp_list))
+		dev_warn(&pdev->dev, "not all components removed\n");
 
 	dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
 	return 0;
@@ -323,7 +381,25 @@ static struct platform_driver mtk_mdp_driver = {
 	}
 };
 
-module_platform_driver(mtk_mdp_driver);
+static struct platform_driver * const mtk_mdp_drivers[] = {
+	&mtk_mdp_driver,
+	&mtk_mdp_component_driver,
+};
+
+static int __init mtk_mdp_init(void)
+{
+	return platform_register_drivers(mtk_mdp_drivers,
+					 ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+static void __exit mtk_mdp_exit(void)
+{
+	platform_unregister_drivers(mtk_mdp_drivers,
+				    ARRAY_SIZE(mtk_mdp_drivers));
+}
+
+module_init(mtk_mdp_init);
+module_exit(mtk_mdp_exit);
 
 MODULE_AUTHOR("Houlong Wei <houlong.wei at mediatek.com>");
 MODULE_DESCRIPTION("Mediatek image processor driver");
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index a6e6dc36307b..8a52539b15d4 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -155,6 +155,7 @@ struct mtk_mdp_dev {
 	struct mtk_mdp_variant		*variant;
 	u16				id;
 	struct list_head		comp_list;
+	struct mtk_mdp_comp		comp_self;
 	struct v4l2_m2m_dev		*m2m_dev;
 	struct list_head		ctx_list;
 	struct video_device		*vdev;
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From eizan at chromium.org  Tue Aug 24 23:33:19 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 25 Aug 2021 16:33:19 +1000
Subject: [PATCH v7 3/7] mtk-mdp: use pm_runtime in MDP component driver
In-Reply-To: <20210825063323.3607738-1-eizan@chromium.org>
References: <20210825063323.3607738-1-eizan@chromium.org>
Message-ID: <20210825163247.v7.3.I909f5375d930f5d0cc877128e30e2a67078b674c@changeid>

Without this change, the MDP components are not fully integrated into
the runtime power management subsystem, and the MDP driver does not
work.

For each of the component device drivers to be able to call
pm_runtime_get/put_sync() a pointer to the component's device struct
had to be added to struct mtk_mdp_comp, set by mtk_mdp_comp_init().

Note that the dev argument to mtk_mdp_comp_clock_on/off() has been
removed. Those functions used to be called from the "master" mdp driver
in mtk_mdp_core.c, but the component's device pointer no longer
corresponds to the mdp master device pointer, which is not the right
device to pass to pm_runtime_put/get_sync() which we had to add to get
the driver to work properly.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 24 +++++++++++++++----
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  6 +++--
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  7 +++---
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7a0e3acffab9..472c261b01e8 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -12,6 +12,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <soc/mediatek/smi.h>
+#include <linux/pm_runtime.h>
 
 #include "mtk_mdp_comp.h"
 #include "mtk_mdp_core.h"
@@ -50,14 +51,22 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
-int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 {
 	int i, err, status;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
 		if (err)
-			dev_err(dev, "failed to get larb, err %d.\n", err);
+			dev_err(comp->dev, "failed to get larb, err %d.\n", err);
+	}
+
+	err = pm_runtime_get_sync(comp->dev);
+	if (err < 0) {
+		dev_err(comp->dev,
+			"failed to runtime get, err %d.\n",
+			err);
+		return err;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
@@ -66,7 +75,7 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		err = clk_prepare_enable(comp->clk[i]);
 		if (err) {
 			status = err;
-			dev_err(dev, "failed to enable clock, err %d. i:%d\n", err, i);
+			dev_err(comp->dev, "failed to enable clock, err %d. i:%d\n", err, i);
 			goto err_clk_prepare_enable;
 		}
 	}
@@ -80,10 +89,12 @@ int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 		clk_disable_unprepare(comp->clk[i]);
 	}
 
+	pm_runtime_put_sync(comp->dev);
+
 	return status;
 }
 
-void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 {
 	int i;
 
@@ -95,6 +106,8 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
 
 	if (comp->larb_dev)
 		mtk_smi_larb_put(comp->larb_dev);
+
+	return pm_runtime_put_sync(comp->dev);
 }
 
 static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
@@ -103,6 +116,7 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 	struct mtk_mdp_dev *mdp = data;
 
 	mtk_mdp_register_component(mdp, comp);
+	pm_runtime_enable(dev);
 
 	return 0;
 }
@@ -113,6 +127,7 @@ static void mtk_mdp_comp_unbind(struct device *dev, struct device *master,
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
 
+	pm_runtime_disable(dev);
 	mtk_mdp_unregister_component(mdp, comp);
 }
 
@@ -132,6 +147,7 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 		 (enum mtk_mdp_comp_type)of_device_get_match_data(dev);
 
 	INIT_LIST_HEAD(&comp->node);
+	comp->dev = dev;
 
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		comp->clk[i] = of_clk_get(node, i);
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index df5fc4c94f90..f2e22e7e7c45 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -12,17 +12,19 @@
  * @node:	list node to track sibing MDP components
  * @clk:	clocks required for component
  * @larb_dev:	SMI device required for component
+ * @dev:	component's device
  */
 struct mtk_mdp_comp {
 	struct list_head	node;
 	struct clk		*clk[2];
+	struct device		*dev;
 	struct device		*larb_dev;
 };
 
 int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
 
-int mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp);
-void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
 
 extern struct platform_driver mtk_mdp_component_driver;
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index b813a822439a..714154450981 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -58,7 +58,7 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 	int err;
 
 	list_for_each_entry(comp_node, &mdp->comp_list, node) {
-		err = mtk_mdp_comp_clock_on(dev, comp_node);
+		err = mtk_mdp_comp_clock_on(comp_node);
 		if (err) {
 			status = err;
 			goto err_mtk_mdp_comp_clock_on;
@@ -69,18 +69,17 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 
 err_mtk_mdp_comp_clock_on:
 	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(dev, comp_node);
+		mtk_mdp_comp_clock_off(comp_node);
 
 	return status;
 }
 
 static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
 {
-	struct device *dev = &mdp->pdev->dev;
 	struct mtk_mdp_comp *comp_node;
 
 	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(dev, comp_node);
+		mtk_mdp_comp_clock_off(comp_node);
 }
 
 static void mtk_mdp_wdt_worker(struct work_struct *work)
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From eizan at chromium.org  Tue Aug 24 23:33:20 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 25 Aug 2021 16:33:20 +1000
Subject: [PATCH v7 4/7] media: mtk-mdp: don't pm_run_time_get/put for master
 comp in clock_on
In-Reply-To: <20210825063323.3607738-1-eizan@chromium.org>
References: <20210825063323.3607738-1-eizan@chromium.org>
Message-ID: <20210825163247.v7.4.Ifd87681955689a08cce4c65e72ee5e8c6d09af95@changeid>

The original intent of commit 86698b9505bbc ("media: mtk-mdp: convert
mtk_mdp_dev.comp array to list") was to create a list to track all the
MDP components that needed to have their clocks enabled/disabled when
calling mtk_mdp_comp_clock_on/off. However, there was a bug inside
mtk_mdp_register_component where the args to a call to list_add were
swapped. The result is that only one component was added to
mtk_mdp_dev.comp_list because comp_list was instead being
repeatedly added to the single element lists headed by each
mtk_mdp_comp.

The order of the args to list_add in mtk_mdp_register_component was
fixed in https://patchwork.kernel.org/patch/11742895/ (Fix Null pointer
dereference when calling list_add).

Then, as a result of https://patchwork.kernel.org/patch/11530769/
(mtk-mdp: use pm_runtime in MDP component driver) if all the components
are added to the component list, the mdp "master" / rdma0 component
ends up having pm_runtime_get_sync() called on it twice recursively:

    rpm_resume+0x694/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_comp_clock_on+0x48/0x104 [mtk_mdp]
    mtk_mdp_pm_resume+0x2c/0x44 [mtk_mdp]
    pm_generic_runtime_resume+0x34/0x48
    __genpd_runtime_resume+0x6c/0x80
    genpd_runtime_resume+0x104/0x1ac
    __rpm_callback+0x120/0x238
    rpm_callback+0x34/0x8c
    rpm_resume+0x7a0/0x8f8
    __pm_runtime_resume+0x7c/0xa0 ***NOTE***
    mtk_mdp_m2m_start_streaming+0x2c/0x3c [mtk_mdp]

(The calls to pm_runtime_get_sync are inlined and correspond to the
calls to __pm_runtime_resume). It is not correct to have
pm_runtime_get_sync called recursively and the second call will block
indefinitely.

As a result of all that, this change factors mtk_mdp_comp_clock_on/off
into mtk_mdp_comp_power_on/off and moves the calls to
pm_runtime_get/put into the power_on/off functions.

This change then special-cases the master/rdma0 MDP component and does
these things:
- the master/rdma0 component is not added to mtk_mdp_dev.comp_list
- the master/rdma0 component has its clocks (*but not power*) toggled
  by mtk_mpd_comp_clock_on/off inside mtk_mdp_clock_on/off.
- the other components have their clocks *and* power toggled with
  mtk_mdp_comp_power_on/off.

This change introduces the assumption that mtk_mdp_pm_resume will
always be called though a callback from pm_runtime_get_sync made on the
master / rdma0 component.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 57 ++++++++++++++---
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  5 +-
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++++++++++-----
 3 files changed, 98 insertions(+), 26 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 472c261b01e8..7b6c8a3f3455 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -51,9 +51,9 @@ static const struct of_device_id mtk_mdp_comp_driver_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, mtk_mdp_comp_driver_dt_match);
 
-int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
+int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp)
 {
-	int i, err, status;
+	int status, err;
 
 	if (comp->larb_dev) {
 		err = mtk_smi_larb_get(comp->larb_dev);
@@ -63,12 +63,54 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 
 	err = pm_runtime_get_sync(comp->dev);
 	if (err < 0) {
-		dev_err(comp->dev,
-			"failed to runtime get, err %d.\n",
-			err);
+		dev_err(comp->dev, "failed to runtime get, err %d.\n", err);
 		return err;
 	}
 
+	err = mtk_mdp_comp_clock_on(comp);
+	if (err) {
+		dev_err(comp->dev, "failed to turn on clock. err=%d", err);
+		status = err;
+		goto err_mtk_mdp_comp_clock_on;
+	}
+
+	return 0;
+
+err_mtk_mdp_comp_clock_on:
+	err = pm_runtime_put_sync(comp->dev);
+	if (err)
+		dev_err(comp->dev, "failed to runtime put in cleanup. err=%d", err);
+
+	return status;
+}
+
+int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp)
+{
+	int status, err;
+
+	mtk_mdp_comp_clock_off(comp);
+
+	err = pm_runtime_put_sync(comp->dev);
+	if (err < 0) {
+		dev_err(comp->dev, "failed to runtime put, err %d.\n", err);
+		status = err;
+		goto err_pm_runtime_put_sync;
+	}
+
+	return 0;
+
+err_pm_runtime_put_sync:
+	err = mtk_mdp_comp_clock_on(comp);
+	if (err)
+		dev_err(comp->dev, "failed to turn on clock in cleanup. err=%d", err);
+
+	return status;
+}
+
+int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
+{
+	int i, err, status;
+
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		if (IS_ERR(comp->clk[i]))
 			continue;
@@ -94,7 +136,8 @@ int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp)
 	return status;
 }
 
-int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
+
+void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 {
 	int i;
 
@@ -106,8 +149,6 @@ int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 
 	if (comp->larb_dev)
 		mtk_smi_larb_put(comp->larb_dev);
-
-	return pm_runtime_put_sync(comp->dev);
 }
 
 static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index f2e22e7e7c45..e3d6aef52869 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -23,8 +23,11 @@ struct mtk_mdp_comp {
 
 int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev);
 
+int mtk_mdp_comp_power_on(struct mtk_mdp_comp *comp);
+int mtk_mdp_comp_power_off(struct mtk_mdp_comp *comp);
+
 int mtk_mdp_comp_clock_on(struct mtk_mdp_comp *comp);
-int mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
+void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp);
 
 extern struct platform_driver mtk_mdp_component_driver;
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 714154450981..a72a9ba41ea6 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -57,29 +57,64 @@ static int mtk_mdp_clock_on(struct mtk_mdp_dev *mdp)
 	struct device *dev = &mdp->pdev->dev;
 	int err;
 
+	/*
+	 * The master / rdma0 component will have pm_runtime_get_sync called
+	 * on it through mtk_mdp_m2m_start_streaming, making it unnecessary to
+	 * have mtk_mdp_comp_power_on called on it.
+	 */
+	err = mtk_mdp_comp_clock_on(&mdp->comp_self);
+	if (err)
+		return err;
+
 	list_for_each_entry(comp_node, &mdp->comp_list, node) {
-		err = mtk_mdp_comp_clock_on(comp_node);
+		err = mtk_mdp_comp_power_on(comp_node);
 		if (err) {
 			status = err;
-			goto err_mtk_mdp_comp_clock_on;
+			goto err_mtk_mdp_comp_power_on;
 		}
 	}
 
 	return 0;
 
-err_mtk_mdp_comp_clock_on:
-	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(comp_node);
-
+err_mtk_mdp_comp_power_on:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_off(comp_node);
+		if (err)
+			dev_err(&mdp->pdev->dev, "failed to power off after error. err=%d", err);
+	}
 	return status;
 }
 
-static void mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
+static int mtk_mdp_clock_off(struct mtk_mdp_dev *mdp)
 {
 	struct mtk_mdp_comp *comp_node;
+	int status, err;
+
+	list_for_each_entry(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_off(comp_node);
+		if (err) {
+			status = err;
+			goto err_mtk_mdp_comp_power_off;
+		}
+	}
 
-	list_for_each_entry(comp_node, &mdp->comp_list, node)
-		mtk_mdp_comp_clock_off(comp_node);
+	/*
+	 * The master / rdma0 component will have pm_runtime_put called
+	 * on it through mtk_mdp_m2m_stop_streaming, making it unnecessary to
+	 * have mtk_mdp_comp_power_off called on it.
+	 */
+	mtk_mdp_comp_clock_off(&mdp->comp_self);
+
+	return 0;
+
+err_mtk_mdp_comp_power_off:
+	list_for_each_entry_continue_reverse(comp_node, &mdp->comp_list, node) {
+		err = mtk_mdp_comp_power_on(comp_node);
+		if (err)
+			dev_err(&mdp->pdev->dev, "failed to power on after error. err=%d", err);
+	}
+
+	return status;
 }
 
 static void mtk_mdp_wdt_worker(struct work_struct *work)
@@ -118,8 +153,6 @@ static int mtk_mdp_master_bind(struct device *dev)
 	int status;
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_register_component(mdp, &mdp->comp_self);
-
 	status = component_bind_all(dev, mdp);
 	if (status) {
 		dev_err(dev, "Failed to bind all components: %d\n", status);
@@ -140,8 +173,6 @@ static int mtk_mdp_master_bind(struct device *dev)
 	component_unbind_all(dev, mdp);
 
 err_component_bind_all:
-	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
-
 	return status;
 }
 
@@ -152,7 +183,6 @@ static void mtk_mdp_master_unbind(struct device *dev)
 	pm_runtime_disable(dev);
 	mtk_mdp_unregister_m2m_device(mdp);
 	component_unbind_all(dev, mdp);
-	mtk_mdp_unregister_component(mdp, &mdp->comp_self);
 }
 
 static const struct component_master_ops mtk_mdp_com_ops = {
@@ -337,9 +367,7 @@ static int __maybe_unused mtk_mdp_pm_suspend(struct device *dev)
 {
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
 
-	mtk_mdp_clock_off(mdp);
-
-	return 0;
+	return mtk_mdp_clock_off(mdp);
 }
 
 static int __maybe_unused mtk_mdp_pm_resume(struct device *dev)
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From eizan at chromium.org  Tue Aug 24 23:33:21 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 25 Aug 2021 16:33:21 +1000
Subject: [PATCH v7 5/7] mtk-mdp: make mdp driver to be loadable by
 platform_device_register*()
In-Reply-To: <20210825063323.3607738-1-eizan@chromium.org>
References: <20210825063323.3607738-1-eizan@chromium.org>
Message-ID: <20210825163247.v7.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>

Rather than hanging the MDP master component driver off of the rdma0
device, make it possible too create a "virtual" device by registering
it with platform_device_register_*() to be probed by the mtk_mdp_core
driver.

Broadly, three interdependent things are done by this change:
- Make it is possible to search for MDP devices in the device tree
  through the grandparent device's of_node.
- v4l-related setup is moved into from the mtk_mdp_core driver to the
  mtk_mdp_comp driver.
- Presence of a mediatek,vpu property in an MDP component device node
  is used to determine what device to use when dispatching DMA ops from
  the relevant ioctl, and also do V4L2 initialization in this case.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
---

Changes in v7:
- Drop last two changes from this series related to removing the vpu
  property from the mdp_rdma0 device node

Changes in v6:
- Don't propagate errors from clock_on/off as an afterthought.
- Split apart modifying mdp driver to be loadable from mmsys from
  actually loading it from mmsys into two changs to make review easier.
- Update devicetree bindings to reflect no longer needing the
  mediatek,vpu property in the mdp_rdma0 device node.
- Some stylistic cleanups.

Changes in v5:
- rebase and test on 5.13-next @ e2f74b13dbe6

Changes in v4:
- rebase and test on 5.13
- don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873

Changes in v3:
- get mdp master from aliases instead of strcmp against of_node->name

Changes in v2:
- rebased onto Linux 5.12
- 100 char line length allowance was utilized in a few places
- Removal of a redundant dev_err() print at the end of
  mtk_mdp_comp_init()
- Instead of printing errors and ignoring them, I've added a patch to
  correctly propagate them.
- Use of C style comments.
- Three additional patches were added to eliminate dependency on the
  mediatek,vpu property inside the mdp_rdma0 device node.

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 51 ++++++++++-----
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++-------------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.h |  2 +
 drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
 4 files changed, 60 insertions(+), 59 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 7b6c8a3f3455..85ef274841a3 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -155,8 +155,45 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
+	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
+
+	/*
+	 * If this component has a "mediatek-vpu" property, it is responsible for
+	 * notifying the mdp master driver about it so it can be further initialized
+	 * later.
+	 */
+	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
+	if (vpu_node) {
+		int ret;
+
+		mdp->vpu_dev = of_find_device_by_node(vpu_node);
+		if (WARN_ON(!mdp->vpu_dev)) {
+			dev_err(dev, "vpu pdev failed\n");
+			of_node_put(vpu_node);
+		}
+
+		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
+		if (ret) {
+			dev_err(dev, "Failed to register v4l2 device\n");
+			return -EINVAL;
+		}
+
+		ret = vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
+		if (ret) {
+			dev_err(dev, "Failed to set vb2 dma mag seg size\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * presence of the "mediatek,vpu" property in a device node
+		 * indicates that it is the primary MDP rdma device and MDP DMA
+		 * ops should be handled by its DMA callbacks.
+		 */
+		mdp->rdma_dev = dev;
+	}
+
 	pm_runtime_enable(dev);
 
 	return 0;
@@ -237,23 +274,9 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
 static int mtk_mdp_comp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *vpu_node;
 	int status;
 	struct mtk_mdp_comp *comp;
 
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
-		of_node_put(vpu_node);
-		/*
-		 * The device tree node with a mediatek,vpu property is deemed
-		 * the MDP "master" device, we don't want to add a component
-		 * for it in this function because the initialization for the
-		 * master is done elsewhere.
-		 */
-		dev_info(dev, "vpu node found, not probing\n");
-		return -ENODEV;
-	}
-
 	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
 	if (!comp)
 		return -ENOMEM;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index a72a9ba41ea6..50eafcc9993d 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -159,6 +159,17 @@ static int mtk_mdp_master_bind(struct device *dev)
 		goto err_component_bind_all;
 	}
 
+	if (mdp->vpu_dev) {
+		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
+					  VPU_RST_MDP);
+		if (ret) {
+			dev_err(dev, "Failed to register reset handler\n");
+			goto err_wdt_reg;
+		}
+	} else {
+		dev_err(dev, "no vpu_dev found\n");
+	}
+
 	status = mtk_mdp_register_m2m_device(mdp);
 	if (status) {
 		dev_err(dev, "Failed to register m2m device: %d\n", status);
@@ -170,6 +181,8 @@ static int mtk_mdp_master_bind(struct device *dev)
 	return 0;
 
 err_mtk_mdp_register_m2m_device:
+
+err_wdt_reg:
 	component_unbind_all(dev, mdp);
 
 err_component_bind_all:
@@ -228,8 +241,13 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		of_node_put(node);
 		parent = dev->of_node;
 		dev_warn(dev, "device tree is out of date\n");
-	} else {
+	} else if (dev->of_node) {
 		parent = dev->of_node->parent;
+	} else if (dev->parent) {
+		/* maybe we were created from a call to platform_device_register_data() */
+		parent = dev->parent->parent->of_node;
+	} else {
+		return -ENODEV;
 	}
 
 	/* Iterate over sibling MDP function blocks */
@@ -262,16 +280,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 		}
 	}
 
-	/*
-	 * Create a component for myself so that clocks can be toggled in
-	 * clock_on().
-	 */
-	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
-	if (ret) {
-		dev_err(dev, "Failed to initialize component\n");
-		goto err_comp;
-	}
-
 	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
 	if (!mdp->job_wq) {
 		dev_err(&pdev->dev, "unable to alloc job workqueue\n");
@@ -287,29 +295,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	}
 	INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker);
 
-	ret = v4l2_device_register(dev, &mdp->v4l2_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
-		ret = -EINVAL;
-		goto err_dev_register;
-	}
-
-	mdp->vpu_dev = vpu_get_plat_device(pdev);
-	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
-				  VPU_RST_MDP);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to register reset handler\n");
-		goto err_wdt_reg;
-	}
-
 	platform_set_drvdata(pdev, mdp);
 
-	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
-		goto err_set_max_seg_size;
-	}
-
 	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
 	if (ret) {
 		dev_err(dev, "Component master add failed\n");
@@ -321,22 +308,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
 	return 0;
 
 err_component_master_add:
-	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-
-err_set_max_seg_size:
-
-err_wdt_reg:
-	v4l2_device_unregister(&mdp->v4l2_dev);
-
-err_dev_register:
 	destroy_workqueue(mdp->wdt_wq);
 
 err_alloc_wdt_wq:
 	destroy_workqueue(mdp->job_wq);
 
 err_alloc_job_wq:
-
-err_comp:
 	dev_dbg(dev, "err %d\n", ret);
 	return ret;
 }
@@ -404,7 +381,6 @@ static struct platform_driver mtk_mdp_driver = {
 	.driver = {
 		.name	= MTK_MDP_MODULE_NAME,
 		.pm	= &mtk_mdp_pm_ops,
-		.of_match_table = mtk_mdp_of_ids,
 	}
 };
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
index 8a52539b15d4..9fcd8b8e7c25 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
@@ -133,6 +133,7 @@ struct mtk_mdp_variant {
  * struct mtk_mdp_dev - abstraction for image processor entity
  * @lock:	the mutex protecting this data structure
  * @vpulock:	the mutex protecting the communication with VPU
+ * @rdma_dev:  device pointer to rdma device for MDP
  * @pdev:	pointer to the image processor platform device
  * @variant:	the IP variant information
  * @id:		image processor device index (0..MTK_MDP_MAX_DEVS)
@@ -151,6 +152,7 @@ struct mtk_mdp_variant {
 struct mtk_mdp_dev {
 	struct mutex			lock;
 	struct mutex			vpulock;
+	struct device			*rdma_dev;
 	struct platform_device		*pdev;
 	struct mtk_mdp_variant		*variant;
 	u16				id;
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
index f14779e7596e..9834d3bbe851 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
@@ -929,7 +929,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
 	src_vq->mem_ops = &vb2_dma_contig_memops;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	src_vq->dev = &ctx->mdp_dev->pdev->dev;
+	src_vq->dev = ctx->mdp_dev->rdma_dev;
 	src_vq->lock = &ctx->mdp_dev->lock;
 
 	ret = vb2_queue_init(src_vq);
@@ -944,7 +944,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
 	dst_vq->mem_ops = &vb2_dma_contig_memops;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	dst_vq->dev = &ctx->mdp_dev->pdev->dev;
+	dst_vq->dev = ctx->mdp_dev->rdma_dev;
 	dst_vq->lock = &ctx->mdp_dev->lock;
 
 	return vb2_queue_init(dst_vq);
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From eizan at chromium.org  Tue Aug 24 23:33:22 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 25 Aug 2021 16:33:22 +1000
Subject: [PATCH v7 6/7] soc: mediatek: mmsys: instantiate mdp virtual device
 from mmsys
In-Reply-To: <20210825063323.3607738-1-eizan@chromium.org>
References: <20210825063323.3607738-1-eizan@chromium.org>
Message-ID: <20210825163247.v7.6.Ie4214d2cc73ab276dd7c41d4f63c98e011fb42d4@changeid>

A virtual device that is probed by the mtk_mdp_core driver is
instantiated by the mtk_mmsys driver.

This better reflects the logical organization of the hardware and
driver: there are a number of hardware blocks that are used by the MDP
that have no strict hierarchy, and the software driver is responsible
for driving them properly.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
---

(no changes since v1)

 drivers/soc/mediatek/mtk-mmsys.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 080660ef11bf..e681029fe804 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -97,6 +97,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 	struct platform_device *clks;
 	struct platform_device *drm;
 	struct mtk_mmsys *mmsys;
+	struct platform_device *mdp;
 	int ret;
 
 	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
@@ -122,10 +123,27 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 					    PLATFORM_DEVID_AUTO, NULL, 0);
 	if (IS_ERR(drm)) {
 		platform_device_unregister(clks);
-		return PTR_ERR(drm);
+		ret = PTR_ERR(drm);
+		goto err_drm;
+	}
+
+	mdp = platform_device_register_data(&pdev->dev, "mtk-mdp",
+					    PLATFORM_DEVID_AUTO, NULL, 0);
+	if (IS_ERR(mdp)) {
+		ret = PTR_ERR(mdp);
+		dev_err(dev, "Failed to register mdp: %d\n", ret);
+		goto err_mdp;
 	}
 
 	return 0;
+
+err_mdp:
+	platform_device_unregister(drm);
+
+err_drm:
+	platform_device_unregister(clks);
+
+	return ret;
 }
 
 static const struct of_device_id of_match_mtk_mmsys[] = {
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From eizan at chromium.org  Tue Aug 24 23:33:23 2021
From: eizan at chromium.org (Eizan Miyamoto)
Date: Wed, 25 Aug 2021 16:33:23 +1000
Subject: [PATCH v7 7/7] media: mtk-mdp: use mdp-rdma0 alias to point to MDP
 master
In-Reply-To: <20210825063323.3607738-1-eizan@chromium.org>
References: <20210825063323.3607738-1-eizan@chromium.org>
Message-ID: <20210825163247.v7.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>

... Instead of depending on the presence of a mediatek,vpu property in
the device node.

That property was originally added to link to the vpu node so that the
mtk_mdp_core driver could pass the right device to
vpu_wdt_reg_handler(). However in a previous patch in this series,
the driver has been modified to search the device tree for that node
instead.

That property was also used to indicate the primary MDP device, so that
it can be passed to the V4L2 subsystem as well as register it to be
used when setting up queues in the open() callback for the filesystem
device node that is created. In this case, assuming that the primary
MDP device is the one with a specific alias seems useable because the
alternative is to add a property to the device tree which doesn't
actually represent any facet of hardware (i.e., this being the primary
MDP device is a software decision). In other words, this solution is
equally as arbitrary, but at least it doesn't add a property to a
device node where said property is unrelated to the hardware present.

Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
---

(no changes since v1)

 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
 2 files changed, 64 insertions(+), 28 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index 85ef274841a3..9527649de98e 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
 		mtk_smi_larb_put(comp->larb_dev);
 }
 
-static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
+/*
+ * The MDP master device node is identified by the device tree alias
+ * "mdp-rdma0".
+ */
+static bool is_mdp_master(struct device *dev)
+{
+	struct device_node *aliases, *mdp_rdma0_node;
+	const char *mdp_rdma0_path;
+
+	if (!dev->of_node)
+		return false;
+
+	aliases = of_find_node_by_path("/aliases");
+	if (!aliases) {
+		dev_err(dev, "no aliases found for mdp-rdma0");
+		return false;
+	}
+
+	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
+	if (!mdp_rdma0_path) {
+		dev_err(dev, "get mdp-rdma0 property of /aliases failed");
+		return false;
+	}
+
+	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
+	if (!mdp_rdma0_node) {
+		dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
+		return false;
+	}
+
+	return dev->of_node == mdp_rdma0_node;
+}
+
+static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
+			void *data)
 {
 	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
 	struct mtk_mdp_dev *mdp = data;
-	struct device_node *vpu_node;
 
 	mtk_mdp_register_component(mdp, comp);
 
-	/*
-	 * If this component has a "mediatek-vpu" property, it is responsible for
-	 * notifying the mdp master driver about it so it can be further initialized
-	 * later.
-	 */
-	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
-	if (vpu_node) {
+	if (is_mdp_master(dev)) {
 		int ret;
 
-		mdp->vpu_dev = of_find_device_by_node(vpu_node);
-		if (WARN_ON(!mdp->vpu_dev)) {
-			dev_err(dev, "vpu pdev failed\n");
-			of_node_put(vpu_node);
-		}
-
 		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
 		if (ret) {
 			dev_err(dev, "Failed to register v4l2 device\n");
@@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
 		}
 
 		/*
-		 * presence of the "mediatek,vpu" property in a device node
-		 * indicates that it is the primary MDP rdma device and MDP DMA
-		 * ops should be handled by its DMA callbacks.
+		 * MDP DMA ops will be handled by the DMA callbacks associated with this
+		 * device;
 		 */
 		mdp->rdma_dev = dev;
 	}
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 50eafcc9993d..6a775463399c 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
 
 static int mtk_mdp_master_bind(struct device *dev)
 {
-	int status;
 	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
+	struct device_node *vpu_node;
+	int status;
 
 	status = component_bind_all(dev, mdp);
 	if (status) {
@@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
 		goto err_component_bind_all;
 	}
 
-	if (mdp->vpu_dev) {
-		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
-					  VPU_RST_MDP);
-		if (ret) {
-			dev_err(dev, "Failed to register reset handler\n");
-			goto err_wdt_reg;
-		}
-	} else {
-		dev_err(dev, "no vpu_dev found\n");
+	if (mdp->rdma_dev == NULL) {
+		dev_err(dev, "Primary MDP device not found");
+		status = -ENODEV;
+		goto err_component_bind_all;
+	}
+
+	vpu_node = of_find_node_by_name(NULL, "vpu");
+	if (!vpu_node) {
+		dev_err(dev, "unable to find vpu node");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	mdp->vpu_dev = of_find_device_by_node(vpu_node);
+	if (!mdp->vpu_dev) {
+		dev_err(dev, "unable to find vpu device");
+		status = -ENODEV;
+		goto err_wdt_reg;
+	}
+
+	status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
+	if (status) {
+		dev_err(dev, "Failed to register reset handler\n");
+		goto err_wdt_reg;
 	}
 
 	status = mtk_mdp_register_m2m_device(mdp);
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From shaolexi at huawei.com  Tue Aug 24 23:46:50 2021
From: shaolexi at huawei.com (Lexi Shao)
Date: Wed, 25 Aug 2021 14:46:50 +0800
Subject: [PATCH] ARM: kasan: Fix __get_user_check failure with kasan
Message-ID: <20210825064650.98162-1-shaolexi@huawei.com>

In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
error code is store in register int __e(r0). When kasan is
enabled, assigning value to kernel address might trigger kasan check,
which unexpectedly overwrites r0 and causes undefined behavior on arm
kasan images.

One example is failure in do_futex and results in process soft lockup.
Log:
watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
Q:Reg:1151]
...
(__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
(futex_wait_setup) from (futex_wait+0x138/0x394)
(futex_wait) from (do_futex+0x164/0xe40)
(do_futex) from (sys_futex_time32+0x178/0x230)
(sys_futex_time32) from (ret_fast_syscall+0x0/0x50)

The soft lockup happens in function futex_wait_setup. The reason is
function get_futex_value_locked always return EINVAL, thus pc jump
back to retry label and causes looping.

The assembly code of get_futex_value_locked in kernel/futex.c:
...
c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
// "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
c01f6dcc:       e1a00007        mov     r0, r7
c01f6dd0:       e1a05002        mov     r5, r2
c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
c01f6dd8:       e5875000        str     r5, [r7]
// save ret value of __get_user(*dest, from), which is dest address now
c01f6ddc:       e1a05000        mov     r5, r0
...
// checking return value of __get_user failed
c01f6e00:       e3550000        cmp     r5, #0
...
c01f6e0c:       01a00005        moveq   r0, r5
// assign return value to EINVAL
c01f6e10:       13e0000d        mvnne   r0, #13

Return value is the destination address of get_user thus certainly
non-zero, so get_futex_value_locked always return EINVAL.

Fix it by using a tmp vairable to store the error code before the
assignment. This fix has no effects to non-kasan images thanks to compiler
optimization. It only affects cases that overwrite r0 due to kasan check.

This should fix bug discussed in link:
[1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c at gmail.com/

Fixes: 421015713b30 ("ARM: 9017/2: Enable KASan for ARM")
Signed-off-by: Lexi Shao <shaolexi at huawei.com>
---
 arch/arm/include/asm/uaccess.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index a13d90206472..a6eb9af74870 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -200,6 +200,7 @@ extern int __get_user_64t_4(void *);
 		register unsigned long __l asm("r1") = __limit;		\
 		register int __e asm("r0");				\
 		unsigned int __ua_flags = uaccess_save_and_enable();	\
+		int __tmp_e;						\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
 			if (sizeof((x)) >= 8)				\
@@ -227,9 +228,10 @@ extern int __get_user_64t_4(void *);
 			break;						\
 		default: __e = __get_user_bad(); break;			\
 		}							\
+		__tmp_e = __e;						\
 		uaccess_restore(__ua_flags);				\
 		x = (typeof(*(p))) __r2;				\
-		__e;							\
+		__e = __tmp_e;						\
 	})
 
 #define get_user(x, p)							\
-- 
2.12.3



From yajun.deng at linux.dev  Wed Aug 25 00:16:12 2021
From: yajun.deng at linux.dev (Yajun Deng)
Date: Wed, 25 Aug 2021 15:16:12 +0800
Subject: [PATCH linux-next] arm64: PCI: Introduce pcibios_free_irq() helper
 function
Message-ID: <20210825071612.21543-1-yajun.deng@linux.dev>

Introduce pcibios_free_irq() to free irq in pci_device_probe() and
pci_device_remove() that in drivers/pci/pci-driver.c.

Signed-off-by: Yajun Deng <yajun.deng at linux.dev>
---
 arch/arm64/kernel/pci.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 1006ed2d7c60..40da5aff4548 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -25,10 +25,18 @@
 int pcibios_alloc_irq(struct pci_dev *dev)
 {
 	if (!acpi_disabled)
-		acpi_pci_irq_enable(dev);
+		return acpi_pci_irq_enable(dev);
 
 	return 0;
 }
+
+void pcibios_free_irq(struct pci_dev *dev)
+{
+	if (!acpi_disabled)
+		acpi_pci_irq_disable(dev);
+
+}
+
 #endif
 
 /*
-- 
2.32.0



From jason-jh.lin at mediatek.com  Wed Aug 25 00:17:41 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 25 Aug 2021 15:17:41 +0800
Subject: [PATCH v5 2/5] dt-bindings: gce: add gce header file for mt8195
In-Reply-To: <1629800083.22373.4.camel@mtksdaap41>
References: <20210818024037.11396-1-jason-jh.lin@mediatek.com>
 <20210818024037.11396-3-jason-jh.lin@mediatek.com>
 <1629800083.22373.4.camel@mtksdaap41>
Message-ID: <72a33d12e45d455ce702f7095d7b290563f3a466.camel@mediatek.com>

Hi CK,

Thanks for the review.

On Tue, 2021-08-24 at 18:14 +0800, CK Hu wrote:
> Hi, Jason:
> 
> On Wed, 2021-08-18 at 10:40 +0800, jason-jh.lin wrote:
> > To define the subsys id and event id, add gce header file for
> > mt8195.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> >  include/dt-bindings/gce/mt8195-gce.h | 920
> > +++++++++++++++++++++++++++
> >  1 file changed, 920 insertions(+)
> >  create mode 100644 include/dt-bindings/gce/mt8195-gce.h
> > 
> > diff --git a/include/dt-bindings/gce/mt8195-gce.h b/include/dt-
> > bindings/gce/mt8195-gce.h
> > new file mode 100644
> > index 000000000000..8c309e59491d
> > --- /dev/null
> > +++ b/include/dt-bindings/gce/mt8195-gce.h
> > @@ -0,0 +1,920 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2018 MediaTek Inc.
> > + *
> > + */
> > +
> > +#ifndef _DT_BINDINGS_GCE_MT8195_H
> > +#define _DT_BINDINGS_GCE_MT8195_H
> > +
> > +/* assign timeout 0 also means default */
> > +#define CMDQ_NO_TIMEOUT		0xffffffff
> > +#define CMDQ_TIMEOUT_DEFAULT	1000
> > +
> > +/* GCE thread priority */
> > +#define CMDQ_THR_PRIO_LOWEST	0
> > +#define CMDQ_THR_PRIO_1		1
> > +#define CMDQ_THR_PRIO_2		2
> > +#define CMDQ_THR_PRIO_3		3
> > +#define CMDQ_THR_PRIO_4		4
> > +#define CMDQ_THR_PRIO_5		5
> > +#define CMDQ_THR_PRIO_6		6
> > +#define CMDQ_THR_PRIO_HIGHEST	7
> > +
> > +/* CPR count in 32bit register */
> > +#define GCE_CPR_COUNT		1312
> > +
> > +/* GCE subsys table */
> > +#define SUBSYS_1400XXXX		0
> > +#define SUBSYS_1401XXXX		1
> > +#define SUBSYS_1402XXXX		2
> > +#define SUBSYS_1c00XXXX		3
> > +#define SUBSYS_1c01XXXX		4
> > +#define SUBSYS_1c02XXXX		5
> > +#define SUBSYS_1c10XXXX		6
> > +#define SUBSYS_1c11XXXX		7
> > +#define SUBSYS_1c12XXXX		8
> > +#define SUBSYS_14f0XXXX		9
> > +#define SUBSYS_14f1XXXX		10
> > +#define SUBSYS_14f2XXXX		11
> > +#define SUBSYS_1800XXXX		12
> > +#define SUBSYS_1801XXXX		13
> > +#define SUBSYS_1802XXXX		14
> > +#define SUBSYS_1803XXXX		15
> > +#define SUBSYS_1032XXXX		16
> > +#define SUBSYS_1033XXXX		17
> > +#define SUBSYS_1600XXXX		18
> > +#define SUBSYS_1601XXXX		19
> > +#define SUBSYS_14e0XXXX		20
> > +#define SUBSYS_1c20XXXX		21
> > +#define SUBSYS_1c30XXXX		22
> > +#define SUBSYS_1c40XXXX		23
> > +#define SUBSYS_1c50XXXX		24
> > +#define SUBSYS_1c60XXXX		25
> > +#define SUBSYS_NO_SUPPORT	99
> 
> Why define SUBSYS_NO_SUPPORT?

It is defined as invalid subsys id, but it is not necessary.
I'll remove it.

> 
> > +
> > +/* GCE General Purpose Register (GPR) support
> > + * Leave note for scenario usage here
> > + */
> > +/* GCE: write mask */
> > +#define GCE_GPR_R00		0x00
> > +#define GCE_GPR_R01		0x01
> > +/* MDP: P1: JPEG dest */
> > +#define GCE_GPR_R02		0x02
> > +#define GCE_GPR_R03		0x03
> > +/* MDP: PQ color */
> > +#define GCE_GPR_R04		0x04
> > +/* MDP: 2D sharpness */
> > +#define GCE_GPR_R05		0x05
> > +/* DISP: poll esd */
> > +#define GCE_GPR_R06		0x06
> > +#define GCE_GPR_R07		0x07
> > +/* MDP: P4: 2D sharpness dst */
> > +#define GCE_GPR_R08		0x08
> > +#define GCE_GPR_R09		0x09
> > +/* VCU: poll with timeout for GPR timer */
> > +#define GCE_GPR_R10		0x0A
> > +#define GCE_GPR_R11		0x0B
> > +/* CMDQ: debug */
> > +#define GCE_GPR_R12		0x0C
> > +#define GCE_GPR_R13		0x0D
> > +/* CMDQ: P7: debug */
> > +#define GCE_GPR_R14		0x0E
> > +#define GCE_GPR_R15		0x0F
> 
> GPR is general purpose register, so do not limit the usage of each
> GPR.

To avoid the same GPR being used by 2 diffenerent client driver at the
same time, we defined the use case that using GPR frequently GPR here
to notify every user.
E.g. MDP use GPR_R10 as temp register whilie VCU is polling the value
in GPR_R10.

But I think we should not limit the usage in the first version, so I'll
remove the scenario here.

> 
> > +
> 
> [snip]
> 
> > +
> > +/* end of hw event */
> > +#define CMDQ_MAX_HW_EVENT				1019
> > +
> > +/* sw token should use the unused event id from 0 to 1023 */
> 
> SW token usage could be changed by different software design. So do
> not
> define in binding document.
> 
> Regards,
> CK
> 
OK, I;ll remove them.

Regards,
Jason-JH.Lin

> > +#define CMDQ_SYNC_TOKEN_INVALID				(-1)
> > +
> > +/* Event for imgsys flow control */
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_EIS			33
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_WPE_TNR			34
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_TRAW			35
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_LTRAW			36
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_DIP			37
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_A			38
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_PQDIP_B			39
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_1			41
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_2			42
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_3			43
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_4			44
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_5			45
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_6			46
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_7			47
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_8			48
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_9			49
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_10			50
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_11			51
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_12			52
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_13			53
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_14			54
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_15			55
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_16			56
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_17			57
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_18			58
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_19			59
> > +#define CMDQ_SYNC_TOKEN_IMGSYS_POOL_20			60
> > +/* Config thread notify trigger thread */
> > +#define CMDQ_SYNC_TOKEN_CONFIG_DIRTY			971
> > +/* Trigger thread notify config thread */
> > +#define CMDQ_SYNC_TOKEN_STREAM_EOF			972
> > +/* Block Trigger thread until the ESD check finishes. */
> > +#define CMDQ_SYNC_TOKEN_ESD_EOF				973
> > +#define CMDQ_SYNC_TOKEN_STREAM_BLOCK			974
> > +/* check CABC setup finish */
> > +#define CMDQ_SYNC_TOKEN_CABC_EOF			975
> > +/* Pass-2 notifies VENC frame is ready to be encoded */
> > +#define CMDQ_SYNC_TOKEN_VENC_INPUT_READY		976
> > +/* VENC notifies Pass-2 encode done so next frame may start */
> > +#define CMDQ_SYNC_TOKEN_VENC_EOF			977
> > +
> > +/* Notify normal CMDQ there are some secure task done
> > + * MUST NOT CHANGE, this token sync with secure world
> > + */
> > +#define CMDQ_SYNC_SECURE_THR_EOF			980
> > +#define CMDQ_SYNC_SECURE_THR_EOF_DBG			995
> > +
> > +/* CMDQ use sw token */
> > +#define CMDQ_SYNC_TOKEN_USER_0				981
> > +#define CMDQ_SYNC_TOKEN_USER_1				982
> > +#define CMDQ_SYNC_TOKEN_POLL_MONITOR			983
> > +#define CMDQ_SYNC_TOKEN_TPR_LOCK			984
> > +
> > +/* ISP sw token */
> > +#define CMDQ_SYNC_TOKEN_MSS				985
> > +#define CMDQ_SYNC_TOKEN_MSF				986
> > +
> > +/* GPR access tokens (for register backup)
> > + * There are 15 32-bit GPR, 3 GPR form a set
> > + * (64-bit for address, 32-bit for value)
> > + * MUST NOT CHANGE, these tokens sync with MDP
> > + */
> > +#define CMDQ_SYNC_TOKEN_GPR_SET_0			987
> > +#define CMDQ_SYNC_TOKEN_GPR_SET_1			988
> > +#define CMDQ_SYNC_TOKEN_GPR_SET_2			989
> > +#define CMDQ_SYNC_TOKEN_GPR_SET_3			990
> > +#define CMDQ_SYNC_TOKEN_GPR_SET_4			991
> > +
> > +/* Resource lock event to control resource in GCE thread */
> > +#define CMDQ_SYNC_RESOURCE_WROT0			992
> > +#define CMDQ_SYNC_RESOURCE_WROT1			993
> > +
> > +/* Event for gpr timer, used in sleep and poll with timeout */
> > +#define CMDQ_TOKEN_GPR_TIMER_R0				996
> > +#define CMDQ_TOKEN_GPR_TIMER_R1				997
> > +#define CMDQ_TOKEN_GPR_TIMER_R2				998
> > +#define CMDQ_TOKEN_GPR_TIMER_R3				999
> > +#define CMDQ_TOKEN_GPR_TIMER_R4				1000
> > +#define CMDQ_TOKEN_GPR_TIMER_R5				1001
> > +#define CMDQ_TOKEN_GPR_TIMER_R6				1002
> > +#define CMDQ_TOKEN_GPR_TIMER_R7				1003
> > +#define CMDQ_TOKEN_GPR_TIMER_R8				1004
> > +#define CMDQ_TOKEN_GPR_TIMER_R9				1005
> > +#define CMDQ_TOKEN_GPR_TIMER_R10			1006
> > +#define CMDQ_TOKEN_GPR_TIMER_R11			1007
> > +#define CMDQ_TOKEN_GPR_TIMER_R12			1008
> > +#define CMDQ_TOKEN_GPR_TIMER_R13			1009
> > +#define CMDQ_TOKEN_GPR_TIMER_R14			1010
> > +#define CMDQ_TOKEN_GPR_TIMER_R15			1011
> > +
> > +/* defined in mtk-cmdq-mailbox.h */
> > +/* #define CMDQ_EVENT_MAX					0x3ff
> > */
> > +
> > +#endif
> 
> 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From michal.simek at xilinx.com  Wed Aug 25 00:23:52 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Wed, 25 Aug 2021 09:23:52 +0200
Subject: [PATCH v3 0/6] Add Xilinx Event Management Driver
In-Reply-To: <20210702105144.28457-1-abhyuday.godhasara@xilinx.com>
References: <20210702105144.28457-1-abhyuday.godhasara@xilinx.com>
Message-ID: <438b398c-a901-7568-11e0-cd9bf302343f@xilinx.com>

Hi,

On 7/2/21 12:51 PM, Abhyuday Godhasara wrote:
> This Linux driver provides support to subscribe error/event notification
> and receive notification from firmware for error/event and forward event
> notification to subscribed driver via registered callback.
> 
> All types of events like power and error will be handled from single place
> as part of event management driver.
> 
> Changes in v3:
> - Update the commit message.
> 
> Changes in v2:
> - Removed updated copyright year from unchanged files.
> - make sgi_num as module parameter for event management driver.
> - Use same object for error detection and printing.
> 
> Abhyuday Godhasara (5):
>   firmware: xilinx: add register notifier in zynqmp firmware
>   firmware: xilinx: add macros of node ids for error event
>   drivers: soc: xilinx: add xilinx event management driver
>   firmware: xilinx: instantiate xilinx event manager driver
>   driver: soc: xilinx: register for power events in zynqmp power driver
> 
> Rajan Vaja (1):
>   firmware: xilinx: export the feature check of zynqmp firmware
> 
>  MAINTAINERS                                 |   6 +
>  drivers/firmware/xilinx/zynqmp.c            |  40 +-
>  drivers/soc/xilinx/Kconfig                  |  10 +
>  drivers/soc/xilinx/Makefile                 |   1 +
>  drivers/soc/xilinx/xlnx_event_manager.c     | 600 ++++++++++++++++++++
>  drivers/soc/xilinx/zynqmp_power.c           |  54 +-
>  include/linux/firmware/xlnx-event-manager.h |  36 ++
>  include/linux/firmware/xlnx-zynqmp.h        |  33 +-
>  8 files changed, 771 insertions(+), 9 deletions(-)
>  create mode 100644 drivers/soc/xilinx/xlnx_event_manager.c
>  create mode 100644 include/linux/firmware/xlnx-event-manager.h
> 

This patch is in conflict with 2b9fc773c31b ("drivers: firmware: Add PDI
load API support") which is in Greg tree.
Can you please rebase it on the top of it and CC Greg on that version?
Would be the best if this will go via his tree because it depends on
that patch.

For the whole series
Acked-by: Michal Simek <michal.simek at xilinx.com>

Thanks,
Michal


From dan.carpenter at oracle.com  Wed Aug 25 00:24:35 2021
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Wed, 25 Aug 2021 10:24:35 +0300
Subject: [PATCH] mxser: use semi-colons instead of commas
Message-ID: <20210825072435.GB13013@kili>

This code works, but it's cleaner to use semi-colons at the end of
a statement instead of a comma.

Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>
---
 drivers/tty/mxser.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 335e4e50d679..1216f3985e18 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -1039,12 +1039,12 @@ static int mxser_get_serial_info(struct tty_struct *tty,
 	if (closing_wait != ASYNC_CLOSING_WAIT_NONE)
 		closing_wait = jiffies_to_msecs(closing_wait) / 10;
 
-	ss->type = info->type,
-	ss->line = tty->index,
-	ss->port = info->ioaddr,
-	ss->irq = info->board->irq,
-	ss->flags = info->port.flags,
-	ss->baud_base = MXSER_BAUD_BASE,
+	ss->type = info->type;
+	ss->line = tty->index;
+	ss->port = info->ioaddr;
+	ss->irq = info->board->irq;
+	ss->flags = info->port.flags;
+	ss->baud_base = MXSER_BAUD_BASE;
 	ss->close_delay = close_delay;
 	ss->closing_wait = closing_wait;
 	ss->custom_divisor = MXSER_CUSTOM_DIVISOR,
-- 
2.20.1



From monstr at monstr.eu  Wed Aug 25 00:28:55 2021
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 25 Aug 2021 09:28:55 +0200
Subject: [GIT PULL] ARM: dts zynq: Xilinx DT changes for v5.15
Message-ID: <f3dc69c8-8a22-e938-4ddf-b1052b8c1437@monstr.eu>

Hi,

please pull these two patches to your tree.

Thanks,
Michal

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://github.com/Xilinx/linux-xlnx.git tags/zynq-dt-for-v5.15

for you to fetch changes up to c387eea58f931fe5d008df88cc75dfc3c704e3bf:

  ARM: dts: ebaz4205: enable NAND support (2021-08-06 12:22:40 +0200)

----------------------------------------------------------------
ARM: dts: Zynq DT changes for v5.15

- Enable nand flash controller for ebaz4205 board

----------------------------------------------------------------
Michael Walle (2):
      ARM: dts: zynq: add NAND flash controller node
      ARM: dts: ebaz4205: enable NAND support

 arch/arm/boot/dts/zynq-7000.dtsi    | 21 +++++++++++++++++++++
 arch/arm/boot/dts/zynq-ebaz4205.dts | 12 ++++++++++++
 2 files changed, 33 insertions(+)

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs



From monstr at monstr.eu  Wed Aug 25 00:31:31 2021
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 25 Aug 2021 09:31:31 +0200
Subject: [GIT PULL] ARM: dts zynq: Xilinx SoC changes for v5.15
Message-ID: <5a25f882-103f-4df0-0d90-868d264c900b@monstr.eu>

Hi,

please pull this one patch to your tree.

Thanks,
Michal

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://github.com/Xilinx/linux-xlnx.git tags/zynq-soc-for-v5.15

for you to fetch changes up to 75b4c5deef011c7d7b1e23b623455185d60e72a2:

  ARM: configs: multi_v7: enable PL35x NAND controller (2021-08-06
12:19:05 +0200)

----------------------------------------------------------------
ARM: dts: Zynq SoC changes for v5.15

- Enable PL35X nand driver in multi_v7_defconfig

----------------------------------------------------------------
Michael Walle (1):
      ARM: configs: multi_v7: enable PL35x NAND controller

 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs



From shengjiu.wang at nxp.com  Wed Aug 25 00:28:35 2021
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Wed, 25 Aug 2021 15:28:35 +0800
Subject: [PATCH v2 1/2] dt-bindings: remoteproc: Add fsl,
 imx-dsp-rproc binding document
Message-ID: <1629876516-16513-1-git-send-email-shengjiu.wang@nxp.com>

Define the compatible string and properties needed by imx_dsp_rproc
driver.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
changes in v2:
- add items for clock-names
- change syscon to fsl,dsp-ctrl 

 .../remoteproc/fsl,imx-dsp-rproc.yaml         | 150 ++++++++++++++++++
 1 file changed, 150 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
new file mode 100644
index 000000000000..edf6e4b8d7bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-dsp-rproc.yaml
@@ -0,0 +1,150 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/fsl,imx-dsp-rproc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX DSP Remoteproc Devices
+
+maintainers:
+  - Shengjiu Wang <shengjiu.wang at nxp.com>
+
+description:
+  This binding provides support for DSP processors found on i.mX family of SoCs
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx8qxp-hifi4
+      - fsl,imx8qm-hifi4
+      - fsl,imx8mp-hifi4
+      - fsl,imx8ulp-hifi4
+
+  clocks:
+    description:
+      Main functional clock for the remote processor
+    minItems: 1
+    maxItems: 32
+
+  clock-names:
+    description: |
+      List of clock names for the remote processor.
+      dsp_clkx for clocks of dsp itself.
+      per_clkx for clocks of peripherals used by dsp.
+    minItems: 1
+    maxItems: 26
+    items:
+      - const: dsp_clk1
+      - const: dsp_clk2
+      - const: dsp_clk3
+      - const: dsp_clk4
+      - const: dsp_clk5
+      - const: dsp_clk6
+      - const: dsp_clk7
+      - const: dsp_clk8
+      - const: per_clk1
+      - const: per_clk2
+      - const: per_clk3
+      - const: per_clk4
+      - const: per_clk5
+      - const: per_clk6
+      - const: per_clk7
+      - const: per_clk8
+      - const: per_clk9
+      - const: per_clk10
+      - const: per_clk11
+      - const: per_clk12
+      - const: per_clk13
+      - const: per_clk14
+      - const: per_clk15
+      - const: per_clk16
+      - const: per_clk17
+      - const: per_clk18
+
+  fsl,dsp-ctrl:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to syscon block which provide access for processor enablement
+
+  mbox-names:
+    items:
+      - const: tx
+      - const: rx
+      - const: rxdb
+
+  mboxes:
+    description:
+      This property is required only if the rpmsg/virtio functionality is used.
+      List of <&phandle type channel> - 1 channel for TX, 1 channel for RX, 1 channel for RXDB.
+      (see mailbox/fsl,mu.yaml)
+    minItems: 1
+    maxItems: 3
+
+  firmware-name:
+    description: |
+      Default name of the firmware to load to the remote processor.
+
+  memory-region:
+    description:
+      If present, a phandle for a reserved memory area that used for vdev buffer,
+      resource table, vring region and others used by remote processor.
+    minItems: 1
+    maxItems: 32
+
+  reg:
+    description: |
+      Address space for any remoteproc memories present on the SoC.
+
+  power-domains:
+    minItems: 1
+    maxItems: 32
+
+required:
+  - compatible
+  - reg
+  - mboxes
+  - mbox-names
+  - clocks
+  - clock-names
+  - firmware-name
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mp-clock.h>
+    dsp_reserved: dsp at 92400000 {
+      reg = <0x92400000 0x1000000>;
+      no-map;
+    };
+    dsp_vdev0vring0: vdev0vring0 at 942f0000 {
+      reg = <0x942f0000 0x8000>;
+      no-map;
+    };
+    dsp_vdev0vring1: vdev0vring1 at 942f8000 {
+      reg = <0x942f8000 0x8000>;
+      no-map;
+    };
+    dsp_vdev0buffer: vdev0buffer at 94300000 {
+      compatible = "shared-dma-pool";
+      reg = <0x94300000 0x100000>;
+      no-map;
+    };
+
+    dsp: dsp at 3b6e8000 {
+      compatible = "fsl,imx8mp-hifi4";
+      reg = <0x3B6E8000 0x88000>;
+      clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG>,
+               <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSP_ROOT>,
+               <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT>;
+      clock-names = "dsp_clk1", "dsp_clk2", "dsp_clk3";
+      firmware-name = "imx/dsp/hifi4.bin";
+      power-domains = <&audiomix_pd>;
+      mbox-names = "tx", "rx", "rxdb";
+      mboxes = <&mu2 0 0>,
+               <&mu2 1 0>,
+               <&mu2 3 0>;
+      memory-region = <&dsp_vdev0buffer>, <&dsp_vdev0vring0>,
+                      <&dsp_vdev0vring1>, <&dsp_reserved>;
+      fsl,dsp-ctrl = <&audio_blk_ctrl>;
+    };
-- 
2.17.1



From shengjiu.wang at nxp.com  Wed Aug 25 00:28:36 2021
From: shengjiu.wang at nxp.com (Shengjiu Wang)
Date: Wed, 25 Aug 2021 15:28:36 +0800
Subject: [PATCH v2 2/2] remoteproc: imx_dsp_rproc: add remoteproc driver for
 dsp on i.MX
In-Reply-To: <1629876516-16513-1-git-send-email-shengjiu.wang@nxp.com>
References: <1629876516-16513-1-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <1629876516-16513-2-git-send-email-shengjiu.wang@nxp.com>

Provide a basic driver to control DSP processor found on NXP i.MX8QM,
i.MX8QXP, i.MX8MP and i.MX8ULP.

Currently it is able to resolve addresses between DSP and main CPU,
start and stop the processor, suspend and resume.

The communication between DSP and main CPU is based on mailbox, there
are three mailbox channels (tx, rx, rxdb).

This driver was tested on NXP i.MX8QM, i.MX8QXP, i.MX8MP and i.MX8ULP.

Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
---
changes in v2:
- change syscon to fsl,dsp-ctrl

 drivers/remoteproc/Kconfig         |   11 +
 drivers/remoteproc/Makefile        |    1 +
 drivers/remoteproc/imx_dsp_rproc.c | 1078 ++++++++++++++++++++++++++++
 3 files changed, 1090 insertions(+)
 create mode 100644 drivers/remoteproc/imx_dsp_rproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 9a6eedc3994a..890a14e6f3f9 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -34,6 +34,17 @@ config IMX_REMOTEPROC
 
 	  It's safe to say N here.
 
+config IMX_DSP_REMOTEPROC
+	tristate "i.MX DSP remoteproc support"
+	depends on ARCH_MXC
+	depends on HAVE_ARM_SMCCC
+	select MAILBOX
+	help
+	  Say y here to support iMX's DSP remote processors via the remote
+	  processor framework.
+
+	  It's safe to say N here.
+
 config INGENIC_VPU_RPROC
 	tristate "Ingenic JZ47xx VPU remoteproc support"
 	depends on MIPS || COMPILE_TEST
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index bb26c9e4ef9c..37d5cb1c04bf 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -12,6 +12,7 @@ remoteproc-y				+= remoteproc_virtio.o
 remoteproc-y				+= remoteproc_elf_loader.o
 obj-$(CONFIG_REMOTEPROC_CDEV)		+= remoteproc_cdev.o
 obj-$(CONFIG_IMX_REMOTEPROC)		+= imx_rproc.o
+obj-$(CONFIG_IMX_DSP_REMOTEPROC)	+= imx_dsp_rproc.o
 obj-$(CONFIG_INGENIC_VPU_RPROC)		+= ingenic_rproc.o
 obj-$(CONFIG_MTK_SCP)			+= mtk_scp.o mtk_scp_ipi.o
 obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
new file mode 100644
index 000000000000..ce0596694122
--- /dev/null
+++ b/drivers/remoteproc/imx_dsp_rproc.c
@@ -0,0 +1,1078 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2021 NXP
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/workqueue.h>
+#include <linux/firmware/imx/sci.h>
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <linux/arm-smccc.h>
+
+#include "remoteproc_internal.h"
+#include "remoteproc_elf_helpers.h"
+
+enum imx_dsp_rp_mbox_messages {
+	RP_MBOX_SUSPEND_SYSTEM  = 0xFF11,
+	RP_MBOX_SUSPEND_ACK     = 0xFF12,
+	RP_MBOX_RESUME_SYSTEM   = 0xFF13,
+	RP_MBOX_RESUME_ACK      = 0xFF14,
+};
+
+#define DSP_RPROC_CLK_MAX 32
+
+#define REMOTE_IS_READY			BIT(0)
+#define REMOTE_READY_WAIT_MAX_RETRIES	500
+
+/* att flags */
+/* DSP own area. Can be mapped at probe */
+#define ATT_OWN		BIT(31)
+#define ATT_IRAM	BIT(30)
+
+/* i.MX8MP */
+/* DAP registers */
+#define IMX8M_DAP_DEBUG                0x28800000
+#define IMX8M_DAP_DEBUG_SIZE           (64 * 1024)
+#define IMX8M_DAP_PWRCTL               (0x4000 + 0x3020)
+#define IMX8M_PWRCTL_CORERESET         BIT(16)
+
+/* DSP audio mix registers */
+#define IMX8M_AudioDSP_REG0   0x100
+#define IMX8M_AudioDSP_REG1   0x104
+#define IMX8M_AudioDSP_REG2   0x108
+#define IMX8M_AudioDSP_REG3   0x10c
+
+#define IMX8M_AudioDSP_REG2_RUNSTALL  BIT(5)
+#define IMX8M_AudioDSP_REG2_PWAITMODE BIT(1)
+
+/* i.MX8ULP */
+#define IMX8ULP_SIM_LPAV_REG_SYSCTRL0       0x8
+#define IMX8ULP_SYSCTRL0_DSP_DBG_RST        BIT(25)
+#define IMX8ULP_SYSCTRL0_DSP_PLAT_CLK_EN    BIT(19)
+#define IMX8ULP_SYSCTRL0_DSP_PBCLK_EN       BIT(18)
+#define IMX8ULP_SYSCTRL0_DSP_CLK_EN         BIT(17)
+#define IMX8ULP_SYSCTRL0_DSP_RST            BIT(16)
+#define IMX8ULP_SYSCTRL0_DSP_OCD_HALT       BIT(14)
+#define IMX8ULP_SYSCTRL0_DSP_STALL          BIT(13)
+
+#define IMX8ULP_SIP_HIFI_XRDC         0xc200000e
+
+/* address translation table */
+struct imx_dsp_rproc_att {
+	u32 da;	/* device address (From Cortex M4 view)*/
+	u32 sa;	/* system bus address */
+	u32 size; /* size of reg range */
+	int flags;
+};
+
+/* Remote core start/stop method */
+enum imx_dsp_rproc_method {
+	/* Through syscon regmap */
+	IMX_DSP_MMIO,
+	IMX_DSP_SCU_API,
+};
+
+struct imx_dsp_rproc {
+	struct device			*dev;
+	struct regmap			*regmap;
+	struct rproc			*rproc;
+	const struct imx_dsp_rproc_dcfg	*dcfg;
+	struct clk			*clks[DSP_RPROC_CLK_MAX];
+	struct mbox_client		cl;
+	struct mbox_client		cl_rxdb;
+	struct mbox_chan		*tx_ch;
+	struct mbox_chan		*rx_ch;
+	struct mbox_chan		*rxdb_ch;
+	struct device			**pd_dev;
+	struct device_link		**pd_dev_link;
+	struct imx_sc_ipc		*ipc_handle;
+	struct work_struct		rproc_work;
+	struct workqueue_struct		*workqueue;
+	struct completion		pm_comp;
+	spinlock_t			mbox_lock;    /* lock for mbox */
+	int				num_domains;
+	u32				flags;
+};
+
+struct imx_dsp_rproc_dcfg {
+	u32				src_reg;
+	u32				src_mask;
+	u32				src_start;
+	u32				src_stop;
+	const struct imx_dsp_rproc_att	*att;
+	size_t				att_size;
+	enum imx_dsp_rproc_method	method;
+	int (*reset)(struct imx_dsp_rproc *priv);
+};
+
+static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8qm[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x596e8000, 0x556e8000, 0x00008000, ATT_OWN },
+	{ 0x596f0000, 0x556f0000, 0x00008000, ATT_OWN },
+	{ 0x596f8000, 0x556f8000, 0x00000800, ATT_OWN | ATT_IRAM},
+	{ 0x55700000, 0x55700000, 0x00070000, ATT_OWN },
+	/* DDR (Data) */
+	{ 0x80000000, 0x80000000, 0x60000000, 0},
+};
+
+static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8qxp[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x596e8000, 0x596e8000, 0x00008000, ATT_OWN },
+	{ 0x596f0000, 0x596f0000, 0x00008000, ATT_OWN },
+	{ 0x596f8000, 0x596f8000, 0x00000800, ATT_OWN | ATT_IRAM},
+	{ 0x59700000, 0x59700000, 0x00070000, ATT_OWN },
+	/* DDR (Data) */
+	{ 0x80000000, 0x80000000, 0x60000000, 0},
+};
+
+static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8mp[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x3b6e8000, 0x3b6e8000, 0x00008000, ATT_OWN },
+	{ 0x3b6f0000, 0x3b6f0000, 0x00008000, ATT_OWN },
+	{ 0x3b6f8000, 0x3b6f8000, 0x00000800, ATT_OWN | ATT_IRAM},
+	{ 0x3b700000, 0x3b700000, 0x00040000, ATT_OWN },
+	/* DDR (Data) */
+	{ 0x40000000, 0x40000000, 0x80000000, 0},
+};
+
+static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8ulp[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x21170000, 0x21170000, 0x00010000, ATT_OWN | ATT_IRAM},
+	{ 0x21180000, 0x21180000, 0x00010000, ATT_OWN },
+	/* DDR (Data) */
+	{ 0x0c000000, 0x80000000, 0x10000000, 0},
+	{ 0x30000000, 0x90000000, 0x10000000, 0},
+};
+
+static int imx8mp_dsp_reset(struct imx_dsp_rproc *priv)
+{
+	void __iomem *dap = ioremap_wc(IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE);
+	int pwrctl;
+
+	/* put DSP into reset and stall */
+	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
+	pwrctl |= IMX8M_PWRCTL_CORERESET;
+	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
+
+	/* keep reset asserted for 10 cycles */
+	usleep_range(1, 2);
+
+	regmap_update_bits(priv->regmap, IMX8M_AudioDSP_REG2,
+			   IMX8M_AudioDSP_REG2_RUNSTALL,
+			   IMX8M_AudioDSP_REG2_RUNSTALL);
+
+	/* take the DSP out of reset and keep stalled for FW loading */
+	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
+	pwrctl &= ~IMX8M_PWRCTL_CORERESET;
+	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
+
+	iounmap(dap);
+	return 0;
+}
+
+static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv)
+{
+	struct arm_smccc_res res;
+
+	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+			   IMX8ULP_SYSCTRL0_DSP_RST, IMX8ULP_SYSCTRL0_DSP_RST);
+	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+			   IMX8ULP_SYSCTRL0_DSP_STALL,
+			   IMX8ULP_SYSCTRL0_DSP_STALL);
+
+	arm_smccc_smc(IMX8ULP_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+			   IMX8ULP_SYSCTRL0_DSP_RST, 0);
+	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+			   IMX8ULP_SYSCTRL0_DSP_DBG_RST, 0);
+
+	return 0;
+}
+
+static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = {
+	.src_reg	= IMX8M_AudioDSP_REG2,
+	.src_mask	= IMX8M_AudioDSP_REG2_RUNSTALL,
+	.src_start	= 0,
+	.src_stop	= IMX8M_AudioDSP_REG2_RUNSTALL,
+	.att		= imx_dsp_rproc_att_imx8mp,
+	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8mp),
+	.method		= IMX_DSP_MMIO,
+	.reset          = imx8mp_dsp_reset,
+};
+
+static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8ulp = {
+	.src_reg	= IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
+	.src_mask	= IMX8ULP_SYSCTRL0_DSP_STALL,
+	.src_start	= 0,
+	.src_stop	= IMX8ULP_SYSCTRL0_DSP_STALL,
+	.att		= imx_dsp_rproc_att_imx8ulp,
+	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8ulp),
+	.method		= IMX_DSP_MMIO,
+	.reset          = imx8ulp_dsp_reset,
+};
+
+static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qxp = {
+	.att		= imx_dsp_rproc_att_imx8qxp,
+	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qxp),
+	.method		= IMX_DSP_SCU_API,
+};
+
+static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qm = {
+	.att		= imx_dsp_rproc_att_imx8qm,
+	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qm),
+	.method		= IMX_DSP_SCU_API,
+};
+
+static int imx_dsp_rproc_ready(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	int i;
+
+	if (!priv->rxdb_ch)
+		return 0;
+
+	for (i = 0; i < REMOTE_READY_WAIT_MAX_RETRIES; i++) {
+		if (priv->flags & REMOTE_IS_READY)
+			return 0;
+		usleep_range(100, 200);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int imx_dsp_rproc_start(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	int ret;
+
+	switch (dcfg->method) {
+	case IMX_DSP_MMIO:
+		ret = regmap_update_bits(priv->regmap,
+					 dcfg->src_reg,
+					 dcfg->src_mask,
+					 dcfg->src_start);
+		break;
+	case IMX_DSP_SCU_API:
+		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
+					  IMX_SC_R_DSP,
+					  true,
+					  rproc->bootaddr);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	if (ret)
+		dev_err(dev, "Failed to enable remote core!\n");
+	else
+		ret = imx_dsp_rproc_ready(rproc);
+
+	return ret;
+}
+
+static int imx_dsp_rproc_stop(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	int ret = 0;
+
+	if (rproc->state == RPROC_CRASHED) {
+		priv->flags &= ~REMOTE_IS_READY;
+		return 0;
+	}
+
+	switch (dcfg->method) {
+	case IMX_DSP_MMIO:
+		ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
+					 dcfg->src_stop);
+		break;
+	case IMX_DSP_SCU_API:
+		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
+					  IMX_SC_R_DSP,
+					  false,
+					  rproc->bootaddr);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	if (ret)
+		dev_err(dev, "Failed to stop remote core\n");
+	else
+		priv->flags &= ~REMOTE_IS_READY;
+
+	return ret;
+}
+
+static int imx_dsp_rproc_sys_to_da(struct imx_dsp_rproc *priv, u64 sys,
+				   size_t len, u64 *da)
+{
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	int i;
+
+	/* parse address translation table */
+	for (i = 0; i < dcfg->att_size; i++) {
+		const struct imx_dsp_rproc_att *att = &dcfg->att[i];
+
+		if (sys >= att->sa && sys + len <= att->sa + att->size) {
+			unsigned int offset = sys - att->sa;
+
+			*da = att->da + offset;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static void imx_dsp_rproc_vq_work(struct work_struct *work)
+{
+	struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
+						  rproc_work);
+
+	rproc_vq_interrupt(priv->rproc, 0);
+	rproc_vq_interrupt(priv->rproc, 1);
+}
+
+static void imx_dsp_rproc_rx_callback(struct mbox_client *cl, void *data)
+{
+	struct rproc *rproc = dev_get_drvdata(cl->dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+	u32 message = (u32)(*(u32 *)data);
+
+	dev_dbg(priv->dev, "mbox msg: 0x%x\n", message);
+
+	switch (message) {
+	case RP_MBOX_SUSPEND_ACK:
+		complete(&priv->pm_comp);
+		break;
+	case RP_MBOX_RESUME_ACK:
+		complete(&priv->pm_comp);
+		break;
+	default:
+		queue_work(priv->workqueue, &priv->rproc_work);
+		break;
+	}
+}
+
+static void imx_dsp_rproc_rxdb_callback(struct mbox_client *cl, void *msg)
+{
+	struct rproc *rproc = dev_get_drvdata(cl->dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->mbox_lock, flags);
+	priv->flags |= REMOTE_IS_READY;
+	spin_unlock_irqrestore(&priv->mbox_lock, flags);
+}
+
+static int imx_dsp_rproc_mbox_init(struct imx_dsp_rproc *priv)
+{
+	struct device *dev = priv->dev;
+	struct mbox_client *cl;
+	int ret;
+
+	if (!of_get_property(dev->of_node, "mbox-names", NULL))
+		return 0;
+
+	spin_lock_init(&priv->mbox_lock);
+
+	cl = &priv->cl;
+	cl->dev = dev;
+	cl->tx_block = true;
+	cl->tx_tout = 100;
+	cl->knows_txdone = false;
+	cl->rx_callback = imx_dsp_rproc_rx_callback;
+
+	priv->tx_ch = mbox_request_channel_byname(cl, "tx");
+	if (IS_ERR(priv->tx_ch)) {
+		ret = PTR_ERR(priv->tx_ch);
+		dev_dbg(cl->dev, "failed to request tx mailbox channel: %d\n",
+			ret);
+		goto err_out;
+	}
+
+	priv->rx_ch = mbox_request_channel_byname(cl, "rx");
+	if (IS_ERR(priv->rx_ch)) {
+		ret = PTR_ERR(priv->rx_ch);
+		dev_dbg(cl->dev, "failed to request rx mailbox channel: %d\n",
+			ret);
+		goto err_out;
+	}
+
+	cl = &priv->cl_rxdb;
+	cl->dev = dev;
+	cl->rx_callback = imx_dsp_rproc_rxdb_callback;
+
+	/*
+	 * RX door bell is used to receive the ready signal from remote
+	 * after the partition reset of A core.
+	 */
+	priv->rxdb_ch = mbox_request_channel_byname(cl, "rxdb");
+	if (IS_ERR(priv->rxdb_ch)) {
+		ret = PTR_ERR(priv->rxdb_ch);
+		dev_dbg(cl->dev, "failed to request mbox chan rxdb, ret %d\n",
+			ret);
+		goto err_out;
+	}
+
+	return 0;
+
+err_out:
+	if (!IS_ERR(priv->tx_ch))
+		mbox_free_channel(priv->tx_ch);
+	if (!IS_ERR(priv->rx_ch))
+		mbox_free_channel(priv->rx_ch);
+	if (!IS_ERR(priv->rxdb_ch))
+		mbox_free_channel(priv->rxdb_ch);
+
+	return ret;
+}
+
+static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv)
+{
+	mbox_free_channel(priv->tx_ch);
+	mbox_free_channel(priv->rx_ch);
+	mbox_free_channel(priv->rxdb_ch);
+}
+
+static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
+{
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	struct rproc *rproc = priv->rproc;
+	struct device *dev = priv->dev;
+	struct device_node *np = dev->of_node;
+	struct of_phandle_iterator it;
+	struct rproc_mem_entry *mem;
+	struct reserved_mem *rmem;
+	void __iomem *cpu_addr;
+	int a;
+	u64 da;
+
+	/* remap required addresses */
+	for (a = 0; a < dcfg->att_size; a++) {
+		const struct imx_dsp_rproc_att *att = &dcfg->att[a];
+
+		if (!(att->flags & ATT_OWN))
+			continue;
+
+		if (imx_dsp_rproc_sys_to_da(priv, att->sa, att->size, &da))
+			return -EINVAL;
+
+		cpu_addr = devm_ioremap_wc(dev, att->sa, att->size);
+
+		/* Register memory region */
+		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)att->sa,
+					   att->size, da,
+					   NULL,
+					   NULL,
+					   "dsp_mem");
+
+		if (mem)
+			rproc_coredump_add_segment(rproc, da, att->size);
+		else
+			return -ENOMEM;
+
+		rproc_add_carveout(rproc, mem);
+	}
+
+	of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
+	while (of_phandle_iterator_next(&it) == 0) {
+		/*
+		 * Ignore the first memory region which will be used vdev buffer.
+		 * No need to do extra handlings, rproc_add_virtio_dev will handle it.
+		 */
+		if (!strcmp(it.node->name, "vdev0buffer"))
+			continue;
+
+		rmem = of_reserved_mem_lookup(it.node);
+		if (!rmem) {
+			dev_err(dev, "unable to acquire memory-region\n");
+			return -EINVAL;
+		}
+
+		if (imx_dsp_rproc_sys_to_da(priv, rmem->base, rmem->size, &da))
+			return -EINVAL;
+
+		cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
+
+		/* Register memory region */
+		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)rmem->base,
+					   rmem->size, da,
+					   NULL,
+					   NULL,
+					   it.node->name);
+
+		if (mem)
+			rproc_coredump_add_segment(rproc, da, rmem->size);
+		else
+			return -ENOMEM;
+
+		rproc_add_carveout(rproc, mem);
+	}
+
+	return 0;
+}
+
+/*
+ * imx_dsp_rproc_elf_load_segments() specially check if memsz is zero
+ * or not.
+ */
+static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc,
+					   const struct firmware *fw)
+{
+	struct device *dev = &rproc->dev;
+	u8 class = fw_elf_get_class(fw);
+	u32 elf_phdr_get_size = elf_size_of_phdr(class);
+	const u8 *elf_data = fw->data;
+	const void *ehdr, *phdr;
+	int i, ret = 0;
+	u16 phnum;
+
+	ehdr = elf_data;
+	phnum = elf_hdr_get_e_phnum(class, ehdr);
+	phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr);
+
+	/* go through the available ELF segments */
+	for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) {
+		u64 da = elf_phdr_get_p_paddr(class, phdr);
+		u64 memsz = elf_phdr_get_p_memsz(class, phdr);
+		u64 filesz = elf_phdr_get_p_filesz(class, phdr);
+		u64 offset = elf_phdr_get_p_offset(class, phdr);
+		u32 type = elf_phdr_get_p_type(class, phdr);
+		void *ptr;
+		bool is_iomem;
+
+		if (type != PT_LOAD || !memsz)
+			continue;
+
+		dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
+			type, da, memsz, filesz);
+
+		if (filesz > memsz) {
+			dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n",
+				filesz, memsz);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (offset + filesz > fw->size) {
+			dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n",
+				offset + filesz, fw->size);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!rproc_u64_fit_in_size_t(memsz)) {
+			dev_err(dev, "size (%llx) does not fit in size_t type\n",
+				memsz);
+			ret = -EOVERFLOW;
+			break;
+		}
+
+		/* grab the kernel address for this device address */
+		ptr = rproc_da_to_va(rproc, da, memsz, &is_iomem);
+		if (!ptr) {
+			dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da,
+				memsz);
+			ret = -EINVAL;
+			break;
+		}
+
+		/* put the segment where the remote processor expects it */
+		if (filesz)
+			memcpy(ptr, elf_data + offset, filesz);
+
+		/*
+		 * Zero out remaining memory for this segment.
+		 *
+		 * This isn't strictly required since dma_alloc_coherent already
+		 * did this for us. albeit harmless, we may consider removing
+		 * this.
+		 */
+		if (memsz > filesz)
+			memset(ptr + filesz, 0, memsz - filesz);
+	}
+
+	return ret;
+}
+
+static int imx_dsp_rproc_prepare(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	struct device *dev = priv->dev;
+	struct rproc_mem_entry *carveout;
+	int ret;
+
+	ret = imx_dsp_rproc_add_carveout(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_add_carveout\n");
+		return ret;
+	}
+
+	pm_runtime_get_sync(dev);
+
+	/* clear buffers */
+	list_for_each_entry(carveout, &rproc->carveouts, node) {
+		if (carveout->va)
+			memset(carveout->va, 0, carveout->len);
+	}
+
+	return  0;
+}
+
+static int imx_dsp_rproc_unprepare(struct rproc *rproc)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+
+	pm_runtime_put_sync(priv->dev);
+
+	return  0;
+}
+
+static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct imx_dsp_rproc *priv = rproc->priv;
+	int err;
+	__u32 mmsg;
+
+	if (!priv->tx_ch) {
+		dev_err(priv->dev, "No initialized mbox tx channel\n");
+		return;
+	}
+
+	/*
+	 * Send the index of the triggered virtqueue as the mu payload.
+	 * Let remote processor know which virtqueue is used.
+	 */
+	mmsg = vqid;
+
+	err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
+	if (err < 0)
+		dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
+			__func__, vqid, err);
+}
+
+static const struct rproc_ops imx_dsp_rproc_ops = {
+	.prepare	= imx_dsp_rproc_prepare,
+	.unprepare	= imx_dsp_rproc_unprepare,
+	.start		= imx_dsp_rproc_start,
+	.stop		= imx_dsp_rproc_stop,
+	.kick		= imx_dsp_rproc_kick,
+	.load		= imx_dsp_rproc_elf_load_segments,
+	.parse_fw	= rproc_elf_load_rsc_table,
+	.sanity_check	= rproc_elf_sanity_check,
+	.get_boot_addr	= rproc_elf_get_boot_addr,
+};
+
+static int imx_dsp_attach_pm_domains(struct imx_dsp_rproc *priv)
+{
+	struct device *dev = priv->dev;
+	int ret, i;
+
+	priv->num_domains = of_count_phandle_with_args(dev->of_node,
+						       "power-domains",
+						       "#power-domain-cells");
+	if (priv->num_domains <= 1)
+		return 0;
+
+	priv->pd_dev = devm_kmalloc_array(dev, priv->num_domains,
+					  sizeof(*priv->pd_dev),
+					  GFP_KERNEL);
+	if (!priv->pd_dev)
+		return -ENOMEM;
+
+	priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_domains,
+					       sizeof(*priv->pd_dev_link),
+					       GFP_KERNEL);
+	if (!priv->pd_dev_link)
+		return -ENOMEM;
+
+	for (i = 0; i < priv->num_domains; i++) {
+		priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
+		if (IS_ERR(priv->pd_dev[i]))
+			return PTR_ERR(priv->pd_dev[i]);
+
+		priv->pd_dev_link[i] = device_link_add(dev,
+						       priv->pd_dev[i],
+						       DL_FLAG_STATELESS |
+						       DL_FLAG_PM_RUNTIME |
+						       DL_FLAG_RPM_ACTIVE);
+		if (IS_ERR(priv->pd_dev_link[i])) {
+			dev_pm_domain_detach(priv->pd_dev[i], false);
+			ret = PTR_ERR(priv->pd_dev_link[i]);
+			goto detach_pm;
+		}
+	}
+
+	return 0;
+
+detach_pm:
+	while (--i >= 0) {
+		device_link_del(priv->pd_dev_link[i]);
+		dev_pm_domain_detach(priv->pd_dev[i], false);
+	}
+
+	return ret;
+}
+
+static int imx_dsp_detach_pm_domains(struct imx_dsp_rproc *priv)
+{
+	int i;
+
+	if (priv->num_domains <= 1)
+		return 0;
+
+	for (i = 0; i < priv->num_domains; i++) {
+		device_link_del(priv->pd_dev_link[i]);
+		dev_pm_domain_detach(priv->pd_dev[i], false);
+	}
+
+	return 0;
+}
+
+static int imx_dsp_rproc_detect_mode(struct imx_dsp_rproc *priv)
+{
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	struct device *dev = priv->dev;
+	struct regmap *regmap;
+	int ret = 0;
+
+	switch (dcfg->method) {
+	case IMX_DSP_SCU_API:
+		ret = imx_scu_get_handle(&priv->ipc_handle);
+		if (ret)
+			return ret;
+		return 0;
+	case IMX_DSP_MMIO:
+		regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,dsp-ctrl");
+		if (IS_ERR(regmap)) {
+			dev_err(dev, "failed to find syscon\n");
+			return PTR_ERR(regmap);
+		}
+
+		priv->regmap = regmap;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static const char *imx_dsp_clks_names[DSP_RPROC_CLK_MAX] = {
+	/* DSP clocks */
+	"dsp_clk1", "dsp_clk2", "dsp_clk3", "dsp_clk4", "dsp_clk5", "dsp_clk6",
+	"dsp_clk7", "dsp_clk8",
+
+	/* Peripheral clocks */
+	"per_clk1", "per_clk2", "per_clk3", "per_clk4", "per_clk5", "per_clk6",
+	"per_clk7", "per_clk8", "per_clk9", "per_clk10", "per_clk11", "per_clk12",
+	"per_clk13", "per_clk14", "per_clk15", "per_clk16", "per_clk17", "per_clk18",
+};
+
+static int imx_dsp_rproc_clk_get(struct imx_dsp_rproc *priv)
+{
+	int i;
+
+	for (i = 0; i < DSP_RPROC_CLK_MAX; i++) {
+		priv->clks[i] = devm_clk_get_optional(priv->dev,
+						      imx_dsp_clks_names[i]);
+		if (IS_ERR(priv->clks[i])) {
+			dev_err(priv->dev, "Failed to get clock %s\n",
+				imx_dsp_clks_names[i]);
+			return PTR_ERR(priv->clks[i]);
+		}
+	}
+
+	return 0;
+}
+
+static int imx_dsp_rproc_clk_enable(struct imx_dsp_rproc *priv)
+{
+	int i, ret;
+
+	for (i = 0; i < DSP_RPROC_CLK_MAX; i++) {
+		ret = clk_prepare_enable(priv->clks[i]);
+		if (ret < 0) {
+			dev_err(priv->dev, "Failed to enable clk %s\n",
+				imx_dsp_clks_names[i]);
+			goto err_dsp_clks;
+		}
+	}
+
+	return 0;
+
+err_dsp_clks:
+	while (--i >= 0)
+		clk_disable_unprepare(priv->clks[i]);
+
+	return ret;
+}
+
+static void imx_dsp_rproc_clk_disable(struct imx_dsp_rproc *priv)
+{
+	int i;
+
+	for (i = 0; i < DSP_RPROC_CLK_MAX; i++)
+		clk_disable_unprepare(priv->clks[i]);
+}
+
+static int imx_dsp_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct imx_dsp_rproc_dcfg *dcfg;
+	struct imx_dsp_rproc *priv;
+	struct rproc *rproc;
+	const char *fw_name;
+	int ret;
+
+	dcfg = of_device_get_match_data(dev);
+	if (!dcfg)
+		return -ENODEV;
+
+	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
+	if (ret) {
+		dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
+			ret);
+		return ret;
+	}
+
+	rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
+			    sizeof(*priv));
+	if (!rproc)
+		return -ENOMEM;
+
+	priv = rproc->priv;
+	priv->rproc = rproc;
+	priv->dcfg = dcfg;
+	priv->dev = dev;
+
+	dev_set_drvdata(dev, rproc);
+
+	priv->workqueue = create_workqueue(dev_name(dev));
+	if (!priv->workqueue) {
+		dev_err(dev, "cannot create workqueue\n");
+		ret = -ENOMEM;
+		goto err_wkq;
+	}
+
+	INIT_WORK(&priv->rproc_work, imx_dsp_rproc_vq_work);
+
+	ret = imx_dsp_rproc_detect_mode(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
+		goto err_detect;
+	}
+
+	ret = imx_dsp_attach_pm_domains(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
+		goto err_pm;
+	}
+
+	ret = imx_dsp_rproc_clk_get(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_clk_get\n");
+		goto err_clk_get;
+	}
+
+	init_completion(&priv->pm_comp);
+	rproc->auto_boot = false;
+	ret = rproc_add(rproc);
+	if (ret) {
+		dev_err(dev, "rproc_add failed\n");
+		goto err_rproc_add;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+
+err_rproc_add:
+err_clk_get:
+	imx_dsp_detach_pm_domains(priv);
+err_pm:
+err_detect:
+	destroy_workqueue(priv->workqueue);
+err_wkq:
+	rproc_free(rproc);
+
+	return ret;
+}
+
+static int imx_dsp_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+
+	pm_runtime_disable(&pdev->dev);
+	rproc_del(rproc);
+	imx_dsp_detach_pm_domains(priv);
+	destroy_workqueue(priv->workqueue);
+	rproc_free(rproc);
+
+	return 0;
+}
+
+/* pm runtime */
+static int imx_dsp_runtime_resume(struct device *dev)
+{
+	struct rproc *rproc = dev_get_drvdata(dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
+	int ret;
+
+	ret = imx_dsp_rproc_mbox_init(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_mbox_init\n");
+		return ret;
+	}
+
+	ret = imx_dsp_rproc_clk_enable(priv);
+	if (ret) {
+		dev_err(dev, "failed on imx_dsp_rproc_clk_enable\n");
+		return ret;
+	}
+
+	/* reset DSP if needed */
+	if (dcfg->reset)
+		dcfg->reset(priv);
+
+	return 0;
+}
+
+static int imx_dsp_runtime_suspend(struct device *dev)
+{
+	struct rproc *rproc = dev_get_drvdata(dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+
+	imx_dsp_rproc_clk_disable(priv);
+
+	imx_dsp_rproc_free_mbox(priv);
+
+	return 0;
+}
+
+static void imx_dsp_load_firmware(const struct firmware *fw, void *context)
+{
+	struct rproc *rproc = context;
+	int ret;
+
+	/* load the ELF segments to memory */
+	ret = rproc_load_segments(rproc, fw);
+	if (ret)
+		goto out;
+
+	/* power up the remote processor */
+	ret = rproc->ops->start(rproc);
+	if (ret)
+		goto out;
+
+	/* same flow as first start */
+	rproc->ops->kick(rproc, 0);
+
+out:
+	release_firmware(fw);
+}
+
+static int imx_dsp_suspend(struct device *dev)
+{
+	struct rproc *rproc = dev_get_drvdata(dev);
+	struct imx_dsp_rproc *priv = rproc->priv;
+	__u32 mmsg = RP_MBOX_SUSPEND_SYSTEM;
+	int ret;
+
+	if (rproc->state == RPROC_RUNNING) {
+		reinit_completion(&priv->pm_comp);
+
+		ret = mbox_send_message(priv->tx_ch, (void *)&mmsg);
+		if (ret < 0) {
+			dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
+			return ret;
+		}
+
+		if (!wait_for_completion_timeout(&priv->pm_comp, msecs_to_jiffies(100)))
+			return -EBUSY;
+	}
+
+	return pm_runtime_force_suspend(dev);
+}
+
+static int imx_dsp_resume(struct device *dev)
+{
+	struct rproc *rproc = dev_get_drvdata(dev);
+	int ret = 0;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret)
+		return ret;
+
+	if (rproc->state == RPROC_RUNNING) {
+		/*TODO: load firmware and start */
+		ret = request_firmware_nowait(THIS_MODULE,
+					      FW_ACTION_UEVENT,
+					      rproc->firmware,
+					      dev,
+					      GFP_KERNEL,
+					      rproc,
+					      imx_dsp_load_firmware);
+		if (ret < 0) {
+			dev_err(dev, "load firmware failed: %d\n", ret);
+			goto err;
+		}
+	}
+
+	return 0;
+
+err:
+	pm_runtime_force_suspend(dev);
+
+	return ret;
+}
+
+static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
+	SET_RUNTIME_PM_OPS(imx_dsp_runtime_suspend,
+			   imx_dsp_runtime_resume, NULL)
+};
+
+static const struct of_device_id imx_dsp_rproc_of_match[] = {
+	{ .compatible = "fsl,imx8qxp-hifi4", .data = &imx_dsp_rproc_cfg_imx8qxp },
+	{ .compatible = "fsl,imx8qm-hifi4",  .data = &imx_dsp_rproc_cfg_imx8qm },
+	{ .compatible = "fsl,imx8mp-hifi4",  .data = &imx_dsp_rproc_cfg_imx8mp },
+	{ .compatible = "fsl,imx8ulp-hifi4", .data = &imx_dsp_rproc_cfg_imx8ulp },
+	{},
+};
+MODULE_DEVICE_TABLE(of, imx_dsp_rproc_of_match);
+
+static struct platform_driver imx_dsp_rproc_driver = {
+	.probe = imx_dsp_rproc_probe,
+	.remove = imx_dsp_rproc_remove,
+	.driver = {
+		.name = "imx-dsp-rproc",
+		.of_match_table = imx_dsp_rproc_of_match,
+		.pm = &imx_dsp_rproc_pm_ops,
+	},
+};
+module_platform_driver(imx_dsp_rproc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("i.MX HiFi Core Remote Processor Control Driver");
+MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang at nxp.com>");
-- 
2.17.1



From saravanak at google.com  Wed Aug 25 01:04:46 2021
From: saravanak at google.com (Saravana Kannan)
Date: Wed, 25 Aug 2021 01:04:46 -0700
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
Message-ID: <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>

On Tue, Aug 24, 2021 at 9:05 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
>
> On 2021/8/25 4:08, Saravana Kannan wrote:
> > On Tue, Aug 24, 2021 at 1:05 PM Rob Herring <robh+dt at kernel.org> wrote:
> >> +Saravana
> >>
> >> Saravana mentioned to me there may be some issues with this one...
> >>
> >>
> >> On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> >>> of_amba_device_create() uses irq_of_parse_and_map() to translate
> >>> a DT interrupt specification into a Linux virtual interrupt number.
> >>>
> >>> But it doesn't properly handle the case where the interrupt controller
> >>> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
> >>> interrupt controller, because the mbigen initialization is too late,
> >>> which will lead to no IRQ due to no IRQ domain found, log is shown below,
> >>>    "irq: no irq domain found for uart0 !"
> >>>
> >>> use of_irq_get() to return -EPROBE_DEFER as above, and in the function
> >>> amba_device_try_add()/amba_device_add(), it will properly handle in such
> >>> case, also return 0 in other fail cases to be consistent as before.
> >>>
> >>> Cc: Russell King <linux at armlinux.org.uk>
> >>> Cc: Rob Herring <robh+dt at kernel.org>
> >>> Cc: Frank Rowand <frowand.list at gmail.com>
> >>> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
> >>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> >>> ---
> >>>   drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
> >>>   drivers/of/platform.c |  6 +-----
> >>>   2 files changed, 28 insertions(+), 5 deletions(-)
> >>>
> >>> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> >>> index 36f2f42c8014..720aa6cdd402 100644
> >>> --- a/drivers/amba/bus.c
> >>> +++ b/drivers/amba/bus.c
> >>> @@ -19,6 +19,7 @@
> >>>   #include <linux/clk/clk-conf.h>
> >>>   #include <linux/platform_device.h>
> >>>   #include <linux/reset.h>
> >>> +#include <linux/of_irq.h>
> >>>
> >>>   #include <asm/irq.h>
> >>>
> >>> @@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
> >>>          kfree(d);
> >>>   }
> >>>
> >>> +static int of_amba_device_decode_irq(struct amba_device *dev)
> >>> +{
> >>> +       struct device_node *node = dev->dev.of_node;
> >>> +       int i, irq = 0;
> >>> +
> >>> +       if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
> >>> +               /* Decode the IRQs and address ranges */
> >>> +               for (i = 0; i < AMBA_NR_IRQS; i++) {
> >>> +                       irq = of_irq_get(node, i);
> >>> +                       if (irq < 0) {
> >>> +                               if (irq == -EPROBE_DEFER)
> >>> +                                       return irq;
> >>> +                               irq = 0;
> >>> +                       }
> >>> +
> >>> +                       dev->irq[i] = irq;
> >>> +               }
> >>> +       }
> >>> +
> >>> +       return 0;
> >>> +}
> >>> +
> >>>   static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
> >>>   {
> >>>          u32 size;
> >>>          void __iomem *tmp;
> >>>          int i, ret;
> >>>
> >>> +       ret = of_amba_device_decode_irq(dev);
> >>> +       if (ret)
> >>> +               goto err_out;
> >>> +
> > Similar to other resources the AMBA bus "gets" for the device, I think
> > this should be moved into amba_probe() and not here. There's no reason
> > to delay the addition of the device (and loading its module) because
> > the IRQ isn't ready yet.
>
> The following code in the amba_device_try_add() will be called, it uses irq[0]
> and irq[1], so I put of_amba_device_decode_irq() into amba_device_try_add().
>
> 470         if (dev->irq[0])
> 471                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
> 472         if (ret == 0 && dev->irq[1])
> 473                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
> 474         if (ret == 0)
> 475                 return ret;
>
> of_amba_device_decode_irq() in amba_device_try_add() won't lead to issue,
> only delay the device add, right?

But delaying the device add is the issue. For example, adding a device
could trigger the loading of the corresponding module using uevents.
But now this change would delay that step. That can have other
unintended consequences -- slowing down boot, what if the driver was
working fine without the IRQ, etc.

> If make it into amba_probe(), the above code should be moved too, could we
> make a new patch to move both of them, or don't move them?

I'd say move them both. If Russell hasn't already picked this up, then
I'd say redo your Patch 3/3.

Btw, I've been working on [1] cleaning up the one-off deferred probe
solution that we have for amba devices. That causes a bunch of other
headaches. Your patch 3/3 takes us further in the wrong direction by
adding more reasons for delaying the addition of the device.

-Saravana

[1] - https://lore.kernel.org/lkml/CAGETcx8b228nDUho3cX9AAQ-pXOfZTMv8cj2vhdx9yc_pk8q+A at mail.gmail.com/


From michael.riesch at wolfvision.net  Wed Aug 25 01:07:48 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed, 25 Aug 2021 10:07:48 +0200
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <20210823094425.78d7a73e@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
 <20210823094425.78d7a73e@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
Message-ID: <60b707af-b138-3c31-726d-d78ac0e1c5f4@wolfvision.net>

Hi Jakub,

On 8/23/21 6:44 PM, Jakub Kicinski wrote:
> On Mon, 23 Aug 2021 16:37:54 +0200 Michael Riesch wrote:
>> In the commit to be reverted, support for power management was
>> introduced to the Rockchip glue code. Later, power management support
>> was introduced to the stmmac core code, resulting in multiple
>> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
> 
> Can we get a Fixes tag? I.e. reference to the earliest commit where 
> the warning can be triggered?

Of course :-)

Fixes: 5ec55823438e850c91c6b92aec93fb04ebde29e2 ("net: stmmac: add
clocks management for gmac driver")

This commit introduces power management support to the stmmac core
(stmmac_{dvr_probe, dvr_remove, suspend, resume}).

Best regards,
Michael

>> The multiple invocations happen in rk_gmac_powerup and
>> stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
>> stmmac_{dvr_remove, suspend}, respectively, which are always called
>> in conjunction.


From houlong.wei at mediatek.com  Wed Aug 25 01:18:18 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Wed, 25 Aug 2021 16:18:18 +0800
Subject: [PATCH v7 5/7] mtk-mdp: make mdp driver to be loadable by
 platform_device_register*()
In-Reply-To: <20210825163247.v7.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>
References: <20210825063323.3607738-1-eizan@chromium.org>
 <20210825163247.v7.5.Iedb6b4f47788548b0cf7bfffae85cac917344c2f@changeid>
Message-ID: <1629879498.12893.8.camel@mhfsdcap03>

Hi Eizan,
I have inline comment below.

Regards,
Houlong

On Wed, 2021-08-25 at 14:33 +0800, Eizan Miyamoto wrote:
> Rather than hanging the MDP master component driver off of the rdma0
> device, make it possible too create a "virtual" device by registering
> it with platform_device_register_*() to be probed by the mtk_mdp_core
> driver.
> 
> Broadly, three interdependent things are done by this change:
> - Make it is possible to search for MDP devices in the device tree
>   through the grandparent device's of_node.
> - v4l-related setup is moved into from the mtk_mdp_core driver to the
>   mtk_mdp_comp driver.
> - Presence of a mediatek,vpu property in an MDP component device node
>   is used to determine what device to use when dispatching DMA ops from
>   the relevant ioctl, and also do V4L2 initialization in this case.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
> ---
> 
> Changes in v7:
> - Drop last two changes from this series related to removing the vpu
>   property from the mdp_rdma0 device node
> 
> Changes in v6:
> - Don't propagate errors from clock_on/off as an afterthought.
> - Split apart modifying mdp driver to be loadable from mmsys from
>   actually loading it from mmsys into two changs to make review easier.
> - Update devicetree bindings to reflect no longer needing the
>   mediatek,vpu property in the mdp_rdma0 device node.
> - Some stylistic cleanups.
> 
> Changes in v5:
> - rebase and test on 5.13-next @ e2f74b13dbe6
> 
> Changes in v4:
> - rebase and test on 5.13
> - don't depend on https://patchwork.kernel.org/project/linux-mediatek/list/?series=464873
> 
> Changes in v3:
> - get mdp master from aliases instead of strcmp against of_node->name
> 
> Changes in v2:
> - rebased onto Linux 5.12
> - 100 char line length allowance was utilized in a few places
> - Removal of a redundant dev_err() print at the end of
>   mtk_mdp_comp_init()
> - Instead of printing errors and ignoring them, I've added a patch to
>   correctly propagate them.
> - Use of C style comments.
> - Three additional patches were added to eliminate dependency on the
>   mediatek,vpu property inside the mdp_rdma0 device node.
> 
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 51 ++++++++++-----
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 62 ++++++-------------
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.h |  2 +
>  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c  |  4 +-
>  4 files changed, 60 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 7b6c8a3f3455..85ef274841a3 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -155,8 +155,45 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
>  {
>  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>  	struct mtk_mdp_dev *mdp = data;
> +	struct device_node *vpu_node;
>  
>  	mtk_mdp_register_component(mdp, comp);
> +
> +	/*
> +	 * If this component has a "mediatek-vpu" property, it is responsible for
> +	 * notifying the mdp master driver about it so it can be further initialized
> +	 * later.
> +	 */
> +	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> +	if (vpu_node) {
> +		int ret;
> +
> +		mdp->vpu_dev = of_find_device_by_node(vpu_node);
> +		if (WARN_ON(!mdp->vpu_dev)) {
> +			dev_err(dev, "vpu pdev failed\n");
> +			of_node_put(vpu_node);
> +		}

The 'vpu_node' should be put when 'mdp->vpu_dev' is valid.

		mdp->vpu_dev = of_find_device_by_node(vpu_node);
		of_node_put(vpu_node);
		if (WARN_ON(!mdp->vpu_dev))
			dev_err(dev, "vpu pdev failed\n");

I commented it before, refer to
http://lists.infradead.org/pipermail/linux-mediatek/2021-August/028370.html

> +		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> +		if (ret) {
> +			dev_err(dev, "Failed to register v4l2 device\n");
> +			return -EINVAL;
> +		}
> +
> +		ret = vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
> +		if (ret) {
> +			dev_err(dev, "Failed to set vb2 dma mag seg size\n");
> +			return -EINVAL;
> +		}
> +
> +		/*
> +		 * presence of the "mediatek,vpu" property in a device node
> +		 * indicates that it is the primary MDP rdma device and MDP DMA
> +		 * ops should be handled by its DMA callbacks.
> +		 */
> +		mdp->rdma_dev = dev;
> +	}
> +
>  	pm_runtime_enable(dev);
>  
>  	return 0;
> @@ -237,23 +274,9 @@ int mtk_mdp_comp_init(struct mtk_mdp_comp *comp, struct device *dev)
>  static int mtk_mdp_comp_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> -	struct device_node *vpu_node;
>  	int status;
>  	struct mtk_mdp_comp *comp;
>  
> -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> -	if (vpu_node) {
> -		of_node_put(vpu_node);
> -		/*
> -		 * The device tree node with a mediatek,vpu property is deemed
> -		 * the MDP "master" device, we don't want to add a component
> -		 * for it in this function because the initialization for the
> -		 * master is done elsewhere.
> -		 */
> -		dev_info(dev, "vpu node found, not probing\n");
> -		return -ENODEV;
> -	}
> -
>  	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
>  	if (!comp)
>  		return -ENOMEM;
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index a72a9ba41ea6..50eafcc9993d 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -159,6 +159,17 @@ static int mtk_mdp_master_bind(struct device *dev)
>  		goto err_component_bind_all;
>  	}
>  
> +	if (mdp->vpu_dev) {
> +		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
> +					  VPU_RST_MDP);
> +		if (ret) {
> +			dev_err(dev, "Failed to register reset handler\n");
> +			goto err_wdt_reg;
> +		}
> +	} else {
> +		dev_err(dev, "no vpu_dev found\n");
> +	}
> +
>  	status = mtk_mdp_register_m2m_device(mdp);
>  	if (status) {
>  		dev_err(dev, "Failed to register m2m device: %d\n", status);
> @@ -170,6 +181,8 @@ static int mtk_mdp_master_bind(struct device *dev)
>  	return 0;
>  
>  err_mtk_mdp_register_m2m_device:
> +
> +err_wdt_reg:
>  	component_unbind_all(dev, mdp);
>  
>  err_component_bind_all:
> @@ -228,8 +241,13 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>  		of_node_put(node);
>  		parent = dev->of_node;
>  		dev_warn(dev, "device tree is out of date\n");
> -	} else {
> +	} else if (dev->of_node) {
>  		parent = dev->of_node->parent;
> +	} else if (dev->parent) {
> +		/* maybe we were created from a call to platform_device_register_data() */
> +		parent = dev->parent->parent->of_node;
> +	} else {
> +		return -ENODEV;
>  	}
>  
>  	/* Iterate over sibling MDP function blocks */
> @@ -262,16 +280,6 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	/*
> -	 * Create a component for myself so that clocks can be toggled in
> -	 * clock_on().
> -	 */
> -	ret = mtk_mdp_comp_init(&mdp->comp_self, dev);
> -	if (ret) {
> -		dev_err(dev, "Failed to initialize component\n");
> -		goto err_comp;
> -	}
> -
>  	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
>  	if (!mdp->job_wq) {
>  		dev_err(&pdev->dev, "unable to alloc job workqueue\n");
> @@ -287,29 +295,8 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>  	}
>  	INIT_WORK(&mdp->wdt_work, mtk_mdp_wdt_worker);
>  
> -	ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
> -		ret = -EINVAL;
> -		goto err_dev_register;
> -	}
> -
> -	mdp->vpu_dev = vpu_get_plat_device(pdev);
> -	ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
> -				  VPU_RST_MDP);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to register reset handler\n");
> -		goto err_wdt_reg;
> -	}
> -
>  	platform_set_drvdata(pdev, mdp);
>  
> -	ret = vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to set vb2 dma mag seg size\n");
> -		goto err_set_max_seg_size;
> -	}
> -
>  	ret = component_master_add_with_match(dev, &mtk_mdp_com_ops, match);
>  	if (ret) {
>  		dev_err(dev, "Component master add failed\n");
> @@ -321,22 +308,12 @@ static int mtk_mdp_probe(struct platform_device *pdev)
>  	return 0;
>  
>  err_component_master_add:
> -	vb2_dma_contig_clear_max_seg_size(&pdev->dev);
> -
> -err_set_max_seg_size:
> -
> -err_wdt_reg:
> -	v4l2_device_unregister(&mdp->v4l2_dev);
> -
> -err_dev_register:
>  	destroy_workqueue(mdp->wdt_wq);
>  
>  err_alloc_wdt_wq:
>  	destroy_workqueue(mdp->job_wq);
>  
>  err_alloc_job_wq:
> -
> -err_comp:
>  	dev_dbg(dev, "err %d\n", ret);
>  	return ret;
>  }
> @@ -404,7 +381,6 @@ static struct platform_driver mtk_mdp_driver = {
>  	.driver = {
>  		.name	= MTK_MDP_MODULE_NAME,
>  		.pm	= &mtk_mdp_pm_ops,
> -		.of_match_table = mtk_mdp_of_ids,
>  	}
>  };
>  
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> index 8a52539b15d4..9fcd8b8e7c25 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.h
> @@ -133,6 +133,7 @@ struct mtk_mdp_variant {
>   * struct mtk_mdp_dev - abstraction for image processor entity
>   * @lock:	the mutex protecting this data structure
>   * @vpulock:	the mutex protecting the communication with VPU
> + * @rdma_dev:  device pointer to rdma device for MDP
>   * @pdev:	pointer to the image processor platform device
>   * @variant:	the IP variant information
>   * @id:		image processor device index (0..MTK_MDP_MAX_DEVS)
> @@ -151,6 +152,7 @@ struct mtk_mdp_variant {
>  struct mtk_mdp_dev {
>  	struct mutex			lock;
>  	struct mutex			vpulock;
> +	struct device			*rdma_dev;
>  	struct platform_device		*pdev;
>  	struct mtk_mdp_variant		*variant;
>  	u16				id;
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> index f14779e7596e..9834d3bbe851 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> @@ -929,7 +929,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
>  	src_vq->mem_ops = &vb2_dma_contig_memops;
>  	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
>  	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> -	src_vq->dev = &ctx->mdp_dev->pdev->dev;
> +	src_vq->dev = ctx->mdp_dev->rdma_dev;
>  	src_vq->lock = &ctx->mdp_dev->lock;
>  
>  	ret = vb2_queue_init(src_vq);
> @@ -944,7 +944,7 @@ static int mtk_mdp_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
>  	dst_vq->mem_ops = &vb2_dma_contig_memops;
>  	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
>  	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> -	dst_vq->dev = &ctx->mdp_dev->pdev->dev;
> +	dst_vq->dev = ctx->mdp_dev->rdma_dev;
>  	dst_vq->lock = &ctx->mdp_dev->lock;
>  
>  	return vb2_queue_init(dst_vq);


From michael.riesch at wolfvision.net  Wed Aug 25 01:19:02 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Wed, 25 Aug 2021 10:19:02 +0200
Subject: [PATCH 1/1] arm64: dts: rockchip: add missing rockchip,grf
 property to rk356x
In-Reply-To: <CAMdYzYpSHkW3NDztmw=CUbYbqQFP+qYdavr6AQZfxwmWJ4eYAw@mail.gmail.com>
References: <20210823123911.12095-1-michael.riesch@wolfvision.net>
 <20210823123911.12095-2-michael.riesch@wolfvision.net>
 <CAMdYzYr4ZTXvfJaeMejuRHBkBAVKcEUseskhEVqLMSYR+Dv4uw@mail.gmail.com>
 <426f77fb-f0ca-9431-45e4-66b885516c76@wolfvision.net>
 <CAMdYzYpSHkW3NDztmw=CUbYbqQFP+qYdavr6AQZfxwmWJ4eYAw@mail.gmail.com>
Message-ID: <fa7e4a0a-8532-dcdf-18ed-ec20bd7411cc@wolfvision.net>

Hi Peter,

On 8/23/21 3:51 PM, Peter Geis wrote:
> On Mon, Aug 23, 2021 at 9:39 AM Michael Riesch
> <michael.riesch at wolfvision.net> wrote:
>>
>> Hi Peter,
>>
>> On 8/23/21 3:12 PM, Peter Geis wrote:
>>> On Mon, Aug 23, 2021 at 8:39 AM Michael Riesch
>>> <michael.riesch at wolfvision.net> wrote:
>>>>
>>>> This commit fixes the error messages
>>>>
>>>>   rockchip_clk_register_muxgrf: regmap not available
>>>>   rockchip_clk_register_branches: failed to register clock clk_ddr1x: -524
>>>>
>>>> during boot by providing the missing rockchip,grf property.
>>>
>>> Good Morning,
>>>
>>> This was fixed by commit: 6fffe52fb336 clk: rockchip: drop GRF
>>> dependency for rk3328/rk3036 pll types
>>> which was merged in -next. I don't believe it's going to be backported
>>> to 5.14 due to 5.14 not being able to fully boot.
>>
>> Unfortunately not, I am afraid. I am working on Heiko's current -next
>> and the commit you mentioned is present. Nevertheless I got these error
>> messages.
>>
>> They can be traced down to "rockchip_clk_register_muxgrf", which fails
>> as the passed argument regmap is invalid due to the missing device tree
>> property. The clock "clk_ddr1x" is added in clk-rk3568.c as "MUXGRF",
>> which leads me to believe that the grf property is actually required.
> 
> Ah, yes it seems you are correct.
> I had inadvertently fixed this a while ago in my own tree.
> Confirmed without the GRF ddr1x clk doesn't register.
> 
> Tested-by: Peter Geis <pgwipeout at gmail.com>

Thanks for testing/your T-B!

> On a related note, are you planning on working on the DVFS driver,
> since it will be the only consumer of this clock?

Until now I was not aware of this, so it is not on my plan. But thanks
for pointing it out, it is definitely something we would like to see
(and maybe could help to implement).

Best regards,
Michael

> 
>>
>> Best regards,
>> Michael
>>
>>>
>>> Very Respectfully,
>>> Peter Geis
>>>
>>>>
>>>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>>>> ---
>>>>  arch/arm64/boot/dts/rockchip/rk356x.dtsi | 1 +
>>>>  1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>>>> index 23949e79d8ce..0a1d07c96b2e 100644
>>>> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>>>> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>>>> @@ -233,6 +233,7 @@
>>>>                 #reset-cells = <1>;
>>>>                 assigned-clocks = <&cru PLL_GPLL>, <&pmucru PLL_PPLL>;
>>>>                 assigned-clock-rates = <1200000000>, <200000000>;
>>>> +               rockchip,grf = <&grf>;
>>>>         };
>>>>
>>>>         i2c0: i2c at fdd40000 {
>>>> --
>>>> 2.17.1
>>>>


From caihuoqing at baidu.com  Wed Aug 25 01:25:36 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 25 Aug 2021 16:25:36 +0800
Subject: [PATCH] pinctrl: nomadik: Kconfig: Remove repeated config dependency
Message-ID: <20210825082536.2547-1-caihuoqing@baidu.com>

remove it because "if (ARCH_U8500 || ARCH_NOMADIK)" is already used

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/pinctrl/nomadik/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/pinctrl/nomadik/Kconfig b/drivers/pinctrl/nomadik/Kconfig
index d6d849e51c74..0fea167c283f 100644
--- a/drivers/pinctrl/nomadik/Kconfig
+++ b/drivers/pinctrl/nomadik/Kconfig
@@ -22,7 +22,6 @@ if (ARCH_U8500 || ARCH_NOMADIK)
 
 config PINCTRL_NOMADIK
 	bool "Nomadik pin controller driver"
-	depends on ARCH_U8500 || ARCH_NOMADIK
 	depends on OF && GPIOLIB
 	select PINMUX
 	select PINCONF
-- 
2.25.1



From dqfext at gmail.com  Wed Aug 25 01:38:29 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed, 25 Aug 2021 16:38:29 +0800
Subject: [RFC net-next 0/2] DSA slave with customise netdev features
Message-ID: <20210825083832.2425886-1-dqfext@gmail.com>

Some taggers, such as tag_dsa.c, combine VLAN tags with DSA tags, which
currently has a few problems:

1. Unnecessary reallocation on TX:

A central TX reallocation has been used since commit a3b0b6479700
("net: dsa: implement a central TX reallocation procedure"), but for
VLAN-tagged frames, the actual headroom required for DSA taggers which
combine with VLAN tags is smaller.

2. Repeated memmoves:

If a both Marvell EDSA and VLAN tagged frame is received, the current
code will move the (DA,SA) twice: the first in dsa_rcv_ll to convert the
frame to a normal 802.1Q frame, and the second to strip off the 802.1Q
tag. The similar thing happens on TX.

For these tags, it is better to handle DSA and VLAN tags at the same time
in DSA taggers.

This patch set allows taggers to add custom netdev features to DSA
slaves so they can advertise VLAN offload, and converts tag_mtk to use
the TX VLAN offload.

DENG Qingfang (2):
  net: dsa: allow taggers to customise netdev features
  net: dsa: tag_mtk: handle VLAN tag insertion on TX

 include/net/dsa.h |  2 ++
 net/dsa/slave.c   |  3 ++-
 net/dsa/tag_mtk.c | 46 ++++++++++++++++++++++------------------------
 3 files changed, 26 insertions(+), 25 deletions(-)

-- 
2.25.1



From dqfext at gmail.com  Wed Aug 25 01:38:30 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed, 25 Aug 2021 16:38:30 +0800
Subject: [RFC net-next 1/2] net: dsa: allow taggers to customise netdev
 features
In-Reply-To: <20210825083832.2425886-1-dqfext@gmail.com>
References: <20210825083832.2425886-1-dqfext@gmail.com>
Message-ID: <20210825083832.2425886-2-dqfext@gmail.com>

Allow taggers to add netdev features, such as VLAN offload, to slave
devices, which will make it possible for taggers to handle VLAN tags
themselves.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 include/net/dsa.h | 2 ++
 net/dsa/slave.c   | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index f9a17145255a..f65442858f71 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -96,6 +96,8 @@ struct dsa_device_ops {
 	 * its RX filter.
 	 */
 	bool promisc_on_master;
+	/* Additional features to be applied to the slave. */
+	netdev_features_t features;
 };
 
 /* This structure defines the control interfaces that are overlayed by the
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 662ff531d4e2..6d6f1aebf1ca 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1885,7 +1885,8 @@ void dsa_slave_setup_tagger(struct net_device *slave)
 
 	p->xmit = cpu_dp->tag_ops->xmit;
 
-	slave->features = master->vlan_features | NETIF_F_HW_TC;
+	slave->features = master->vlan_features | cpu_dp->tag_ops->features |
+			  NETIF_F_HW_TC;
 	slave->hw_features |= NETIF_F_HW_TC;
 	slave->features |= NETIF_F_LLTX;
 	if (slave->needed_tailroom)
-- 
2.25.1



From dqfext at gmail.com  Wed Aug 25 01:38:31 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Wed, 25 Aug 2021 16:38:31 +0800
Subject: [RFC net-next 2/2] net: dsa: tag_mtk: handle VLAN tag insertion on TX
In-Reply-To: <20210825083832.2425886-1-dqfext@gmail.com>
References: <20210825083832.2425886-1-dqfext@gmail.com>
Message-ID: <20210825083832.2425886-3-dqfext@gmail.com>

Advertise TX VLAN offload features, and handle VLAN tag insertion in
the tag_xmit function.

Signed-off-by: DENG Qingfang <dqfext at gmail.com>
---
 net/dsa/tag_mtk.c | 46 ++++++++++++++++++++++------------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index 415d8ece242a..e407abefa06c 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -22,7 +22,6 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
 				    struct net_device *dev)
 {
 	struct dsa_port *dp = dsa_slave_to_port(dev);
-	u8 xmit_tpid;
 	u8 *mtk_tag;
 
 	/* Build the special tag after the MAC Source Address. If VLAN header
@@ -31,33 +30,31 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
 	 * the both special and VLAN tag at the same time and then look up VLAN
 	 * table with VID.
 	 */
-	switch (skb->protocol) {
-	case htons(ETH_P_8021Q):
-		xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_8100;
-		break;
-	case htons(ETH_P_8021AD):
-		xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_88A8;
-		break;
-	default:
-		xmit_tpid = MTK_HDR_XMIT_UNTAGGED;
-		skb_push(skb, MTK_HDR_LEN);
-		dsa_alloc_etype_header(skb, MTK_HDR_LEN);
-	}
-
+	skb_push(skb, MTK_HDR_LEN);
+	dsa_alloc_etype_header(skb, MTK_HDR_LEN);
 	mtk_tag = dsa_etype_header_pos_tx(skb);
 
-	/* Mark tag attribute on special tag insertion to notify hardware
-	 * whether that's a combined special tag with 802.1Q header.
-	 */
-	mtk_tag[0] = xmit_tpid;
-	mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
-
-	/* Tag control information is kept for 802.1Q */
-	if (xmit_tpid == MTK_HDR_XMIT_UNTAGGED) {
-		mtk_tag[2] = 0;
-		mtk_tag[3] = 0;
+	if (skb_vlan_tag_present(skb)) {
+		switch (skb->vlan_proto) {
+		case htons(ETH_P_8021Q):
+			mtk_tag[0] = MTK_HDR_XMIT_TAGGED_TPID_8100;
+			break;
+		case htons(ETH_P_8021AD):
+			mtk_tag[0] = MTK_HDR_XMIT_TAGGED_TPID_88A8;
+			break;
+		default:
+			return NULL;
+		}
+
+		((__be16 *)mtk_tag)[1] = htons(skb_vlan_tag_get(skb));
+		__vlan_hwaccel_clear_tag(skb);
+	} else {
+		mtk_tag[0] = MTK_HDR_XMIT_UNTAGGED;
+		((__be16 *)mtk_tag)[1] = 0;
 	}
 
+	mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
+
 	return skb;
 }
 
@@ -96,6 +93,7 @@ static const struct dsa_device_ops mtk_netdev_ops = {
 	.xmit		= mtk_tag_xmit,
 	.rcv		= mtk_tag_rcv,
 	.needed_headroom = MTK_HDR_LEN,
+	.features	= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX,
 };
 
 MODULE_LICENSE("GPL");
-- 
2.25.1



From wangkefeng.wang at huawei.com  Wed Aug 25 01:39:48 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 16:39:48 +0800
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
 <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
Message-ID: <eb7f0980-f735-dd3b-fd66-63c8cd69cc58@huawei.com>


On 2021/8/25 16:04, Saravana Kannan wrote:
> On Tue, Aug 24, 2021 at 9:05 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>
>> On 2021/8/25 4:08, Saravana Kannan wrote:
>>> On Tue, Aug 24, 2021 at 1:05 PM Rob Herring <robh+dt at kernel.org> wrote:
>>>> +Saravana
>>>>
>>>> Saravana mentioned to me there may be some issues with this one...
>>>>
>>>>
>>>> On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>>>> of_amba_device_create() uses irq_of_parse_and_map() to translate
>>>>> a DT interrupt specification into a Linux virtual interrupt number.
>>>>>
>>>>> But it doesn't properly handle the case where the interrupt controller
>>>>> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
>>>>> interrupt controller, because the mbigen initialization is too late,
>>>>> which will lead to no IRQ due to no IRQ domain found, log is shown below,
>>>>>     "irq: no irq domain found for uart0 !"
>>>>>
>>>>> use of_irq_get() to return -EPROBE_DEFER as above, and in the function
>>>>> amba_device_try_add()/amba_device_add(), it will properly handle in such
>>>>> case, also return 0 in other fail cases to be consistent as before.
>>>>>
>>>>> Cc: Russell King <linux at armlinux.org.uk>
>>>>> Cc: Rob Herring <robh+dt at kernel.org>
>>>>> Cc: Frank Rowand <frowand.list at gmail.com>
>>>>> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
>>>>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>>>>> ---
>>>>>    drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
>>>>>    drivers/of/platform.c |  6 +-----
>>>>>    2 files changed, 28 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
>>>>> index 36f2f42c8014..720aa6cdd402 100644
>>>>> --- a/drivers/amba/bus.c
>>>>> +++ b/drivers/amba/bus.c
>>>>> @@ -19,6 +19,7 @@
>>>>>    #include <linux/clk/clk-conf.h>
>>>>>    #include <linux/platform_device.h>
>>>>>    #include <linux/reset.h>
>>>>> +#include <linux/of_irq.h>
>>>>>
>>>>>    #include <asm/irq.h>
>>>>>
>>>>> @@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
>>>>>           kfree(d);
>>>>>    }
>>>>>
>>>>> +static int of_amba_device_decode_irq(struct amba_device *dev)
>>>>> +{
>>>>> +       struct device_node *node = dev->dev.of_node;
>>>>> +       int i, irq = 0;
>>>>> +
>>>>> +       if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
>>>>> +               /* Decode the IRQs and address ranges */
>>>>> +               for (i = 0; i < AMBA_NR_IRQS; i++) {
>>>>> +                       irq = of_irq_get(node, i);
>>>>> +                       if (irq < 0) {
>>>>> +                               if (irq == -EPROBE_DEFER)
>>>>> +                                       return irq;
>>>>> +                               irq = 0;
>>>>> +                       }
>>>>> +
>>>>> +                       dev->irq[i] = irq;
>>>>> +               }
>>>>> +       }
>>>>> +
>>>>> +       return 0;
>>>>> +}
>>>>> +
>>>>>    static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
>>>>>    {
>>>>>           u32 size;
>>>>>           void __iomem *tmp;
>>>>>           int i, ret;
>>>>>
>>>>> +       ret = of_amba_device_decode_irq(dev);
>>>>> +       if (ret)
>>>>> +               goto err_out;
>>>>> +
>>> Similar to other resources the AMBA bus "gets" for the device, I think
>>> this should be moved into amba_probe() and not here. There's no reason
>>> to delay the addition of the device (and loading its module) because
>>> the IRQ isn't ready yet.
>> The following code in the amba_device_try_add() will be called, it uses irq[0]
>> and irq[1], so I put of_amba_device_decode_irq() into amba_device_try_add().
>>
>> 470         if (dev->irq[0])
>> 471                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
>> 472         if (ret == 0 && dev->irq[1])
>> 473                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
>> 474         if (ret == 0)
>> 475                 return ret;
>>
>> of_amba_device_decode_irq() in amba_device_try_add() won't lead to issue,
>> only delay the device add, right?
> But delaying the device add is the issue. For example, adding a device
> could trigger the loading of the corresponding module using uevents.
> But now this change would delay that step. That can have other
> unintended consequences -- slowing down boot, what if the driver was
> working fine without the IRQ, etc.
>
>> If make it into amba_probe(), the above code should be moved too, could we
>> make a new patch to move both of them, or don't move them?
> I'd say move them both. If Russell hasn't already picked this up, then
> I'd say redo your Patch 3/3.


Sure?I will update it and resend.

>
> Btw, I've been working on [1] cleaning up the one-off deferred probe
> solution that we have for amba devices. That causes a bunch of other
> headaches. Your patch 3/3 takes us further in the wrong direction by
> adding more reasons for delaying the addition of the device.
Thanks for your explanation.
> -Saravana
>
> [1] - https://lore.kernel.org/lkml/CAGETcx8b228nDUho3cX9AAQ-pXOfZTMv8cj2vhdx9yc_pk8q+A at mail.gmail.com/
> .
>


From houlong.wei at mediatek.com  Wed Aug 25 01:43:19 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Wed, 25 Aug 2021 16:43:19 +0800
Subject: [PATCH v7 7/7] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <20210825163247.v7.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
References: <20210825063323.3607738-1-eizan@chromium.org>
 <20210825163247.v7.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
Message-ID: <1629880999.12893.17.camel@mhfsdcap03>

Hi Eizan,

Thanks for you patch. I have inline comment below.

Regards,
Houlong

On Wed, 2021-08-25 at 14:33 +0800, Eizan Miyamoto wrote:
> ... Instead of depending on the presence of a mediatek,vpu property in
> the device node.
> 
> That property was originally added to link to the vpu node so that the
> mtk_mdp_core driver could pass the right device to
> vpu_wdt_reg_handler(). However in a previous patch in this series,
> the driver has been modified to search the device tree for that node
> instead.
> 
> That property was also used to indicate the primary MDP device, so that
> it can be passed to the V4L2 subsystem as well as register it to be
> used when setting up queues in the open() callback for the filesystem
> device node that is created. In this case, assuming that the primary
> MDP device is the one with a specific alias seems useable because the
> alternative is to add a property to the device tree which doesn't
> actually represent any facet of hardware (i.e., this being the primary
> MDP device is a software decision). In other words, this solution is
> equally as arbitrary, but at least it doesn't add a property to a
> device node where said property is unrelated to the hardware present.
> 
> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> ---
> 
> (no changes since v1)
> 
>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
>  2 files changed, 64 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> index 85ef274841a3..9527649de98e 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> @@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
>  		mtk_smi_larb_put(comp->larb_dev);
>  }
>  
> -static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
> +/*
> + * The MDP master device node is identified by the device tree alias
> + * "mdp-rdma0".
> + */
> +static bool is_mdp_master(struct device *dev)
> +{
> +	struct device_node *aliases, *mdp_rdma0_node;
> +	const char *mdp_rdma0_path;
> +
> +	if (!dev->of_node)
> +		return false;
> +
> +	aliases = of_find_node_by_path("/aliases");
> +	if (!aliases) {
> +		dev_err(dev, "no aliases found for mdp-rdma0");
> +		return false;
> +	}
> +
> +	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
> +	if (!mdp_rdma0_path) {
> +		dev_err(dev, "get mdp-rdma0 property of /aliases failed");
> +		return false;
> +	}
> +
> +	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
> +	if (!mdp_rdma0_node) {
> +		dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
> +		return false;
> +	}
> +
> +	return dev->of_node == mdp_rdma0_node;


About how to determine the master mdp driver, we also can
judge the component type. The component type can be gotten by calling
of_device_get_match_data(dev). If the component is MTK_MDP_RDMA, it is
the master driver. No matter it is mdp_rdma0 or mdp_rdma1.
http://lists.infradead.org/pipermail/linux-mediatek/2021-August/028533.html

IMO, judging it by component type is more flexible because it does not
limit to 'mdp_rdma0'.

> +}
> +
> +static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
> +			void *data)
>  {
>  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>  	struct mtk_mdp_dev *mdp = data;
> -	struct device_node *vpu_node;
>  
>  	mtk_mdp_register_component(mdp, comp);
>  
> -	/*
> -	 * If this component has a "mediatek-vpu" property, it is responsible for
> -	 * notifying the mdp master driver about it so it can be further initialized
> -	 * later.
> -	 */
> -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> -	if (vpu_node) {
> +	if (is_mdp_master(dev)) {
>  		int ret;
>  
> -		mdp->vpu_dev = of_find_device_by_node(vpu_node);
> -		if (WARN_ON(!mdp->vpu_dev)) {
> -			dev_err(dev, "vpu pdev failed\n");
> -			of_node_put(vpu_node);
> -		}
> -
>  		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
>  		if (ret) {
>  			dev_err(dev, "Failed to register v4l2 device\n");
> @@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
>  		}
>  
>  		/*
> -		 * presence of the "mediatek,vpu" property in a device node
> -		 * indicates that it is the primary MDP rdma device and MDP DMA
> -		 * ops should be handled by its DMA callbacks.
> +		 * MDP DMA ops will be handled by the DMA callbacks associated with this
> +		 * device;
>  		 */
>  		mdp->rdma_dev = dev;
>  	}
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> index 50eafcc9993d..6a775463399c 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> @@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
>  
>  static int mtk_mdp_master_bind(struct device *dev)
>  {
> -	int status;
>  	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> +	struct device_node *vpu_node;
> +	int status;
>  
>  	status = component_bind_all(dev, mdp);
>  	if (status) {
> @@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
>  		goto err_component_bind_all;
>  	}
>  
> -	if (mdp->vpu_dev) {
> -		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
> -					  VPU_RST_MDP);
> -		if (ret) {
> -			dev_err(dev, "Failed to register reset handler\n");
> -			goto err_wdt_reg;
> -		}
> -	} else {
> -		dev_err(dev, "no vpu_dev found\n");
> +	if (mdp->rdma_dev == NULL) {
> +		dev_err(dev, "Primary MDP device not found");
> +		status = -ENODEV;
> +		goto err_component_bind_all;
> +	}
> +
> +	vpu_node = of_find_node_by_name(NULL, "vpu");
> +	if (!vpu_node) {
> +		dev_err(dev, "unable to find vpu node");
> +		status = -ENODEV;
> +		goto err_wdt_reg;
> +	}
> +
> +	mdp->vpu_dev = of_find_device_by_node(vpu_node);

The 'vpu_node' should be put by calling 'of_node_put(vpu_node)' when it
is not used.

> +	if (!mdp->vpu_dev) {
> +		dev_err(dev, "unable to find vpu device");
> +		status = -ENODEV;
> +		goto err_wdt_reg;
> +	}
> +
> +	status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
> +	if (status) {
> +		dev_err(dev, "Failed to register reset handler\n");
> +		goto err_wdt_reg;
>  	}
>  
>  	status = mtk_mdp_register_m2m_device(mdp);


From diana.craciun at oss.nxp.com  Wed Aug 25 02:05:37 2021
From: diana.craciun at oss.nxp.com (Diana Craciun)
Date: Wed, 25 Aug 2021 12:05:37 +0300
Subject: [PATCH 1/2] bus/fsl-mc: Add generic implementation for
 open/reset/close commands
Message-ID: <20210825090538.4860-1-diana.craciun@oss.nxp.com>

The open/reset/close commands format is similar for all objects.
Currently there are multiple implementations for these commands
scattered through various drivers. The code is cavsi-identical.
Create a generic implementation for the open/reset/close commands.
One of the consumer will be the VFIO driver which needs to
be able to reset a device.

Signed-off-by: Diana Craciun <diana.craciun at oss.nxp.com>
---
 drivers/bus/fsl-mc/Makefile         |   3 +-
 drivers/bus/fsl-mc/fsl-mc-private.h |  39 +++++++++--
 drivers/bus/fsl-mc/obj-api.c        | 104 ++++++++++++++++++++++++++++
 include/linux/fsl/mc.h              |  14 ++++
 4 files changed, 155 insertions(+), 5 deletions(-)
 create mode 100644 drivers/bus/fsl-mc/obj-api.c

diff --git a/drivers/bus/fsl-mc/Makefile b/drivers/bus/fsl-mc/Makefile
index 4ae292a30e53..892946245527 100644
--- a/drivers/bus/fsl-mc/Makefile
+++ b/drivers/bus/fsl-mc/Makefile
@@ -15,7 +15,8 @@ mc-bus-driver-objs := fsl-mc-bus.o \
 		      dprc-driver.o \
 		      fsl-mc-allocator.o \
 		      fsl-mc-msi.o \
-		      dpmcp.o
+		      dpmcp.o \
+		      obj-api.o
 
 # MC userspace support
 obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o
diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
index 1958fa065360..6055ef3e9e02 100644
--- a/drivers/bus/fsl-mc/fsl-mc-private.h
+++ b/drivers/bus/fsl-mc/fsl-mc-private.h
@@ -48,7 +48,6 @@ struct dpmng_rsp_get_version {
 
 /* DPMCP command IDs */
 #define DPMCP_CMDID_CLOSE		DPMCP_CMD(0x800)
-#define DPMCP_CMDID_OPEN		DPMCP_CMD(0x80b)
 #define DPMCP_CMDID_RESET		DPMCP_CMD(0x005)
 
 struct dpmcp_cmd_open {
@@ -91,7 +90,6 @@ int dpmcp_reset(struct fsl_mc_io *mc_io,
 
 /* DPRC command IDs */
 #define DPRC_CMDID_CLOSE                        DPRC_CMD(0x800)
-#define DPRC_CMDID_OPEN                         DPRC_CMD(0x805)
 #define DPRC_CMDID_GET_API_VERSION              DPRC_CMD(0xa05)
 
 #define DPRC_CMDID_GET_ATTR                     DPRC_CMD(0x004)
@@ -453,7 +451,6 @@ int dprc_get_connection(struct fsl_mc_io *mc_io,
 
 /* Command IDs */
 #define DPBP_CMDID_CLOSE		DPBP_CMD(0x800)
-#define DPBP_CMDID_OPEN			DPBP_CMD(0x804)
 
 #define DPBP_CMDID_ENABLE		DPBP_CMD(0x002)
 #define DPBP_CMDID_DISABLE		DPBP_CMD(0x003)
@@ -492,7 +489,6 @@ struct dpbp_rsp_get_attributes {
 
 /* Command IDs */
 #define DPCON_CMDID_CLOSE			DPCON_CMD(0x800)
-#define DPCON_CMDID_OPEN			DPCON_CMD(0x808)
 
 #define DPCON_CMDID_ENABLE			DPCON_CMD(0x002)
 #define DPCON_CMDID_DISABLE			DPCON_CMD(0x003)
@@ -524,6 +520,41 @@ struct dpcon_cmd_set_notification {
 	__le64 user_ctx;
 };
 
+/*
+ * Generic FSL MC API
+ */
+
+/* generic command versioning */
+#define OBJ_CMD_BASE_VERSION		1
+#define OBJ_CMD_ID_OFFSET		4
+
+#define OBJ_CMD(id)	(((id) << OBJ_CMD_ID_OFFSET) | OBJ_CMD_BASE_VERSION)
+
+/* open command codes */
+#define DPRTC_CMDID_OPEN		OBJ_CMD(0x810)
+#define DPNI_CMDID_OPEN		OBJ_CMD(0x801)
+#define DPSW_CMDID_OPEN		OBJ_CMD(0x802)
+#define DPIO_CMDID_OPEN		OBJ_CMD(0x803)
+#define DPBP_CMDID_OPEN		OBJ_CMD(0x804)
+#define DPRC_CMDID_OPEN		OBJ_CMD(0x805)
+#define DPDMUX_CMDID_OPEN		OBJ_CMD(0x806)
+#define DPCI_CMDID_OPEN		OBJ_CMD(0x807)
+#define DPCON_CMDID_OPEN		OBJ_CMD(0x808)
+#define DPSECI_CMDID_OPEN		OBJ_CMD(0x809)
+#define DPAIOP_CMDID_OPEN		OBJ_CMD(0x80a)
+#define DPMCP_CMDID_OPEN		OBJ_CMD(0x80b)
+#define DPMAC_CMDID_OPEN		OBJ_CMD(0x80c)
+#define DPDCEI_CMDID_OPEN		OBJ_CMD(0x80d)
+#define DPDMAI_CMDID_OPEN		OBJ_CMD(0x80e)
+#define DPDBG_CMDID_OPEN		OBJ_CMD(0x80f)
+
+/* Generic object command IDs */
+#define OBJ_CMDID_CLOSE		OBJ_CMD(0x800)
+#define OBJ_CMDID_RESET		OBJ_CMD(0x005)
+
+struct obj_cmd_open {
+	__le32 obj_id;
+};
 
 /**
  * struct fsl_mc_resource_pool - Pool of MC resources of a given
diff --git a/drivers/bus/fsl-mc/obj-api.c b/drivers/bus/fsl-mc/obj-api.c
new file mode 100644
index 000000000000..8eee28c7f86a
--- /dev/null
+++ b/drivers/bus/fsl-mc/obj-api.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2021 NXP
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/fsl/mc.h>
+
+#include "fsl-mc-private.h"
+
+static int fsl_mc_get_open_cmd_id(const char *type)
+{
+	static const struct {
+		int cmd_id;
+		const char *type;
+	} dev_ids[] = {
+		{ DPRTC_CMDID_OPEN, "dprtc" },
+		{ DPRC_CMDID_OPEN, "dprc" },
+		{ DPNI_CMDID_OPEN, "dpni" },
+		{ DPIO_CMDID_OPEN, "dpio" },
+		{ DPSW_CMDID_OPEN, "dpsw" },
+		{ DPBP_CMDID_OPEN, "dpbp" },
+		{ DPCON_CMDID_OPEN, "dpcon" },
+		{ DPMCP_CMDID_OPEN, "dpmcp" },
+		{ DPMAC_CMDID_OPEN, "dpmac" },
+		{ DPSECI_CMDID_OPEN, "dpseci" },
+		{ DPDMUX_CMDID_OPEN, "dpdmux" },
+		{ DPDCEI_CMDID_OPEN, "dpdcei" },
+		{ DPAIOP_CMDID_OPEN, "dpaiop" },
+		{ DPCI_CMDID_OPEN, "dpci" },
+		{ DPDMAI_CMDID_OPEN, "dpdmai" },
+		{ DPDBG_CMDID_OPEN, "dpdbg" },
+		{ 0, NULL }
+	};
+	int i;
+
+	for (i = 0; dev_ids[i].type; i++)
+		if (!strcmp(dev_ids[i].type, type))
+			return dev_ids[i].cmd_id;
+
+	return -1;
+}
+
+int fsl_mc_obj_open(struct fsl_mc_io *mc_io,
+		    u32 cmd_flags,
+		    int obj_id,
+		    char *obj_type,
+		    u16 *token)
+{
+	struct fsl_mc_command cmd = { 0 };
+	struct obj_cmd_open *cmd_params;
+	int err = 0;
+	int cmd_id = fsl_mc_get_open_cmd_id(obj_type);
+
+	if (cmd_id == -1)
+		return -ENODEV;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(cmd_id, cmd_flags, 0);
+	cmd_params = (struct obj_cmd_open *)cmd.params;
+	cmd_params->obj_id = cpu_to_le32(obj_id);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	*token = mc_cmd_hdr_read_token(&cmd);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(fsl_mc_obj_open);
+
+int fsl_mc_obj_close(struct fsl_mc_io *mc_io,
+		     u32 cmd_flags,
+		     u16 token)
+{
+	struct fsl_mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(OBJ_CMDID_CLOSE, cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_obj_close);
+
+int fsl_mc_obj_reset(struct fsl_mc_io *mc_io,
+		     u32 cmd_flags,
+		     u16 token)
+{
+	struct fsl_mc_command cmd = { 0 };
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(OBJ_CMDID_RESET, cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	return mc_send_command(mc_io, &cmd);
+}
+EXPORT_SYMBOL_GPL(fsl_mc_obj_reset);
+
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
index 63b56aba925a..fafea154242d 100644
--- a/include/linux/fsl/mc.h
+++ b/include/linux/fsl/mc.h
@@ -619,6 +619,20 @@ int dpcon_reset(struct fsl_mc_io *mc_io,
 		u32 cmd_flags,
 		u16 token);
 
+int fsl_mc_obj_open(struct fsl_mc_io *mc_io,
+		    u32 cmd_flags,
+		    int obj_id,
+		    char *obj_type,
+		    u16 *token);
+
+int fsl_mc_obj_close(struct fsl_mc_io *mc_io,
+		     u32 cmd_flags,
+		     u16 token);
+
+int fsl_mc_obj_reset(struct fsl_mc_io *mc_io,
+		     u32 cmd_flags,
+		     u16 token);
+
 /**
  * struct dpcon_attr - Structure representing DPCON attributes
  * @id: DPCON object ID
-- 
2.17.1



From diana.craciun at oss.nxp.com  Wed Aug 25 02:05:38 2021
From: diana.craciun at oss.nxp.com (Diana Craciun)
Date: Wed, 25 Aug 2021 12:05:38 +0300
Subject: [PATCH 2/2] vfio/fsl-mc: Add per device reset support
In-Reply-To: <20210825090538.4860-1-diana.craciun@oss.nxp.com>
References: <20210825090538.4860-1-diana.craciun@oss.nxp.com>
Message-ID: <20210825090538.4860-2-diana.craciun@oss.nxp.com>

Currently when a fsl-mc device is reset, the entire DPRC container
is reset which is very inefficient because the devices within a
container will be reset multiple times.
Add support for individually resetting a device.

Signed-off-by: Diana Craciun <diana.craciun at oss.nxp.com>
---
 drivers/vfio/fsl-mc/vfio_fsl_mc.c | 45 ++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
index 90cad109583b..46126d41dc32 100644
--- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
@@ -155,6 +155,33 @@ static int vfio_fsl_mc_open(struct vfio_device *core_vdev)
 	return ret;
 }
 
+static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev)
+{
+	struct fsl_mc_device *mc_dev = vdev->mc_dev;
+	int ret = 0;
+
+	if (is_fsl_mc_bus_dprc(vdev->mc_dev)) {
+		return dprc_reset_container(mc_dev->mc_io, 0,
+					mc_dev->mc_handle,
+					mc_dev->obj_desc.id,
+					DPRC_RESET_OPTION_NON_RECURSIVE);
+	} else {
+		int err;
+		u16 token;
+
+		err = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
+				      mc_dev->obj_desc.type,
+				      &token);
+		if (err)
+			return err;
+		ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token);
+		err = fsl_mc_obj_close(mc_dev->mc_io, 0, token);
+		if (err)
+			return err;
+	}
+	return ret;
+}
+
 static void vfio_fsl_mc_release(struct vfio_device *core_vdev)
 {
 	struct vfio_fsl_mc_device *vdev =
@@ -171,10 +198,7 @@ static void vfio_fsl_mc_release(struct vfio_device *core_vdev)
 		vfio_fsl_mc_regions_cleanup(vdev);
 
 		/* reset the device before cleaning up the interrupts */
-		ret = dprc_reset_container(mc_cont->mc_io, 0,
-		      mc_cont->mc_handle,
-			  mc_cont->obj_desc.id,
-			  DPRC_RESET_OPTION_NON_RECURSIVE);
+		ret = vfio_fsl_mc_reset_device(vdev);
 
 		if (ret) {
 			dev_warn(&mc_cont->dev, "VFIO_FLS_MC: reset device has failed (%d)\n",
@@ -302,18 +326,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev,
 	}
 	case VFIO_DEVICE_RESET:
 	{
-		int ret;
-		struct fsl_mc_device *mc_dev = vdev->mc_dev;
-
-		/* reset is supported only for the DPRC */
-		if (!is_fsl_mc_bus_dprc(mc_dev))
-			return -ENOTTY;
-
-		ret = dprc_reset_container(mc_dev->mc_io, 0,
-					   mc_dev->mc_handle,
-					   mc_dev->obj_desc.id,
-					   DPRC_RESET_OPTION_NON_RECURSIVE);
-		return ret;
+		return vfio_fsl_mc_reset_device(vdev);
 
 	}
 	default:
-- 
2.17.1



From digetx at gmail.com  Wed Aug 25 02:06:48 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Wed, 25 Aug 2021 12:06:48 +0300
Subject: [PATCH] ARM: kasan: Fix __get_user_check failure with kasan
In-Reply-To: <20210825064650.98162-1-shaolexi@huawei.com>
References: <20210825064650.98162-1-shaolexi@huawei.com>
Message-ID: <4a80b83f-bc63-a141-c7c8-7e7d9545eb00@gmail.com>

25.08.2021 09:46, Lexi Shao ?????:
> In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
> error code is store in register int __e(r0). When kasan is
> enabled, assigning value to kernel address might trigger kasan check,
> which unexpectedly overwrites r0 and causes undefined behavior on arm
> kasan images.
> 
> One example is failure in do_futex and results in process soft lockup.
> Log:
> watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
> Q:Reg:1151]
> ...
> (__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
> (futex_wait_setup) from (futex_wait+0x138/0x394)
> (futex_wait) from (do_futex+0x164/0xe40)
> (do_futex) from (sys_futex_time32+0x178/0x230)
> (sys_futex_time32) from (ret_fast_syscall+0x0/0x50)
> 
> The soft lockup happens in function futex_wait_setup. The reason is
> function get_futex_value_locked always return EINVAL, thus pc jump
> back to retry label and causes looping.
> 
> The assembly code of get_futex_value_locked in kernel/futex.c:
> ...
> c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
> // "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
> c01f6dcc:       e1a00007        mov     r0, r7
> c01f6dd0:       e1a05002        mov     r5, r2
> c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
> c01f6dd8:       e5875000        str     r5, [r7]
> // save ret value of __get_user(*dest, from), which is dest address now
> c01f6ddc:       e1a05000        mov     r5, r0
> ...
> // checking return value of __get_user failed
> c01f6e00:       e3550000        cmp     r5, #0
> ...
> c01f6e0c:       01a00005        moveq   r0, r5
> // assign return value to EINVAL
> c01f6e10:       13e0000d        mvnne   r0, #13
> 
> Return value is the destination address of get_user thus certainly
> non-zero, so get_futex_value_locked always return EINVAL.
> 
> Fix it by using a tmp vairable to store the error code before the
> assignment. This fix has no effects to non-kasan images thanks to compiler
> optimization. It only affects cases that overwrite r0 due to kasan check.
> 
> This should fix bug discussed in link:
> [1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c at gmail.com/
> 
> Fixes: 421015713b30 ("ARM: 9017/2: Enable KASan for ARM")
> Signed-off-by: Lexi Shao <shaolexi at huawei.com>
> ---
>  arch/arm/include/asm/uaccess.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
> index a13d90206472..a6eb9af74870 100644
> --- a/arch/arm/include/asm/uaccess.h
> +++ b/arch/arm/include/asm/uaccess.h
> @@ -200,6 +200,7 @@ extern int __get_user_64t_4(void *);
>  		register unsigned long __l asm("r1") = __limit;		\
>  		register int __e asm("r0");				\
>  		unsigned int __ua_flags = uaccess_save_and_enable();	\
> +		int __tmp_e;						\
>  		switch (sizeof(*(__p))) {				\
>  		case 1:							\
>  			if (sizeof((x)) >= 8)				\
> @@ -227,9 +228,10 @@ extern int __get_user_64t_4(void *);
>  			break;						\
>  		default: __e = __get_user_bad(); break;			\
>  		}							\
> +		__tmp_e = __e;						\
>  		uaccess_restore(__ua_flags);				\
>  		x = (typeof(*(p))) __r2;				\
> -		__e;							\
> +		__e = __tmp_e;						\
>  	})
>  
>  #define get_user(x, p)							\
> 

I successfully loaded KDE Plasma with this fix, which was impossible
previously. Thank you!

Is it guaranteed that r2 register won't be clobbered as well?


From maz at kernel.org  Wed Aug 25 02:07:08 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 25 Aug 2021 10:07:08 +0100
Subject: [PATCH] PCI: uniphier: Serialize INTx masking/unmasking
In-Reply-To: <f4d13190-facf-55ca-58c5-cd0d68e377d7@socionext.com>
References: <1629717500-19396-1-git-send-email-hayashi.kunihiko@socionext.com>
 <20210823150927.jhobzfxy6e4s663r@pali>
 <87zgt8p09n.wl-maz@kernel.org>
 <f4d13190-facf-55ca-58c5-cd0d68e377d7@socionext.com>
Message-ID: <87o89lq4eb.wl-maz@kernel.org>

On Wed, 25 Aug 2021 01:01:08 +0100,
Kunihiko Hayashi <hayashi.kunihiko at socionext.com> wrote:
> 
> Hi Marc,
> 
> On 2021/08/24 1:57, Marc Zyngier wrote:
> > On Mon, 23 Aug 2021 16:09:27 +0100,
> > Pali Roh?r <pali at kernel.org> wrote:
> >> 
> >> + Marc (who originally reported this issue)
> >> 
> >> On Monday 23 August 2021 20:18:20 Kunihiko Hayashi wrote:
> >>> The condition register PCI_RCV_INTX is used in irq_mask(), irq_unmask()
> >>> and irq_ack() callbacks. Accesses to register can occur at the same time
> >>> without a lock.
> >>> Add a lock into each callback to prevent the issue.
> >>> 
> >>> Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
> >>> Suggested-by: Pali Roh?r <pali at kernel.org>
> >>> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
> >> 
> >> Acked-by: Pali Roh?r <pali at kernel.org>
> >> 
> >>> ---
> >>>   drivers/pci/controller/dwc/pcie-uniphier.c | 15 +++++++++++++++
> >>>   1 file changed, 15 insertions(+)
> >>> 
> >>> The previous patch is as follows:
> >>> https://lore.kernel.org/linux-pci/1629370566-29984-1-git-send-email-hayashi.kunihiko at socionext.com/
> >>> 
> >>> Changes in the previous patch:
> >>> - Change the subject and commit message
> >>> 
> >>> diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
> >>> index ebe43e9..5075714 100644
> >>> --- a/drivers/pci/controller/dwc/pcie-uniphier.c
> >>> +++ b/drivers/pci/controller/dwc/pcie-uniphier.c
> >>> @@ -186,12 +186,17 @@ static void uniphier_pcie_irq_ack(struct irq_data *d)
> >>>   	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
> >>>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> >>>   	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> >>> +	unsigned long flags;
> >>>   	u32 val;
> >>>   +	raw_spin_lock_irqsave(&pp->lock, flags);
> >>> +
> >>>   	val = readl(priv->base + PCL_RCV_INTX);
> >>>   	val &= ~PCL_RCV_INTX_ALL_STATUS;
> >>>   	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
> >>>   	writel(val, priv->base + PCL_RCV_INTX);
> >>> +
> >>> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
> >>>   }
> >>>     static void uniphier_pcie_irq_mask(struct irq_data *d)
> >>> @@ -199,12 +204,17 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
> >>>   	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
> >>>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> >>>   	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> >>> +	unsigned long flags;
> >>>   	u32 val;
> >>>   +	raw_spin_lock_irqsave(&pp->lock, flags);
> >>> +
> >>>   	val = readl(priv->base + PCL_RCV_INTX);
> >>>   	val &= ~PCL_RCV_INTX_ALL_MASK;
> >>>   	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
> > 
> > This looks extremely suspicious. You clear all the INTX mask bits, and
> > only set the one you need. How about the pre-existing bits?
> 
> Thanks for pointing out. No need to clear all INTX mask bits.
> The pre-existing bits should be preserved.
> 
> > 
> >>>   	writel(val, priv->base + PCL_RCV_INTX);
> >>> +
> >>> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
> >>>   }
> >>>     static void uniphier_pcie_irq_unmask(struct irq_data *d)
> >>> @@ -212,12 +222,17 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
> >>>   	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
> >>>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> >>>   	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> >>> +	unsigned long flags;
> >>>   	u32 val;
> >>>   +	raw_spin_lock_irqsave(&pp->lock, flags);
> >>> +
> >>>   	val = readl(priv->base + PCL_RCV_INTX);
> >>>   	val &= ~PCL_RCV_INTX_ALL_MASK;
> >>>   	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
> > 
> > And by the same token, this second line is totally useless.
> > 
> > I think masking/unmasking is broken in this driver, locking or not.
> 
> Yes, this second line should be removed, too.

You mean the *first* line, right? The one clearing all the INTx
bits. If you remove the second line, you won't fix anything.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From enric.balletbo at collabora.com  Wed Aug 25 02:07:59 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 11:07:59 +0200
Subject: [PATCH v7 7/7] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <1629880999.12893.17.camel@mhfsdcap03>
References: <20210825063323.3607738-1-eizan@chromium.org>
 <20210825163247.v7.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <1629880999.12893.17.camel@mhfsdcap03>
Message-ID: <0c9fa482-57dd-d4ef-c65b-01f137c57359@collabora.com>

Hi Houlong,

Thank you for following up this patchset. I have some questions to try to
understand better the hardware though.

On 25/8/21 10:43, houlong wei wrote:
> Hi Eizan,
> 
> Thanks for you patch. I have inline comment below.
> 
> Regards,
> Houlong
> 
> On Wed, 2021-08-25 at 14:33 +0800, Eizan Miyamoto wrote:
>> ... Instead of depending on the presence of a mediatek,vpu property in
>> the device node.
>>
>> That property was originally added to link to the vpu node so that the
>> mtk_mdp_core driver could pass the right device to
>> vpu_wdt_reg_handler(). However in a previous patch in this series,
>> the driver has been modified to search the device tree for that node
>> instead.
>>
>> That property was also used to indicate the primary MDP device, so that
>> it can be passed to the V4L2 subsystem as well as register it to be
>> used when setting up queues in the open() callback for the filesystem
>> device node that is created. In this case, assuming that the primary
>> MDP device is the one with a specific alias seems useable because the
>> alternative is to add a property to the device tree which doesn't
>> actually represent any facet of hardware (i.e., this being the primary
>> MDP device is a software decision). In other words, this solution is
>> equally as arbitrary, but at least it doesn't add a property to a
>> device node where said property is unrelated to the hardware present.
>>
>> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
>> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
>> ---
>>
>> (no changes since v1)
>>
>>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
>>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
>>  2 files changed, 64 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
>> index 85ef274841a3..9527649de98e 100644
>> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
>> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
>> @@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
>>  		mtk_smi_larb_put(comp->larb_dev);
>>  }
>>  
>> -static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
>> +/*
>> + * The MDP master device node is identified by the device tree alias
>> + * "mdp-rdma0".
>> + */
>> +static bool is_mdp_master(struct device *dev)
>> +{
>> +	struct device_node *aliases, *mdp_rdma0_node;
>> +	const char *mdp_rdma0_path;
>> +
>> +	if (!dev->of_node)
>> +		return false;
>> +
>> +	aliases = of_find_node_by_path("/aliases");
>> +	if (!aliases) {
>> +		dev_err(dev, "no aliases found for mdp-rdma0");
>> +		return false;
>> +	}
>> +
>> +	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
>> +	if (!mdp_rdma0_path) {
>> +		dev_err(dev, "get mdp-rdma0 property of /aliases failed");
>> +		return false;
>> +	}
>> +
>> +	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
>> +	if (!mdp_rdma0_node) {
>> +		dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
>> +		return false;
>> +	}
>> +
>> +	return dev->of_node == mdp_rdma0_node;
> 
> 
> About how to determine the master mdp driver, we also can
> judge the component type. The component type can be gotten by calling
> of_device_get_match_data(dev). If the component is MTK_MDP_RDMA, it is
> the master driver. No matter it is mdp_rdma0 or mdp_rdma1.


I'm confused, you mean that the component type, aka MTK_MDP_RDMA is only set for
mtk_mdp_rdma0? isn't mtk_dmp_rdma1 also a MTK_MDP_RDMA type? Because looks weird
to me that two rdma have diffent types.


> http://lists.infradead.org/pipermail/linux-mediatek/2021-August/028533.html
> 
> IMO, judging it by component type is more flexible because it does not
> limit to 'mdp_rdma0'.
> 

Using an alias like Eizan did is also flexible, you only need to set mdp-rdma0
to point the mdp_rdma1 node.

What I am really interested to know is the differences between the platforms to
understand if this is really a platform hardware property or a software
configurable thing, so would help if you can give use the different use cases
for different SoCs.

For MT8173 which is the master device? is _always_ rdma0 or can also be rdma1?

Or maybe what is not clear here is what exactly means be a master device?

What about MT8183 and other SoCs?

Thanks,
  Enric


>> +}
>> +
>> +static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
>> +			void *data)
>>  {
>>  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>>  	struct mtk_mdp_dev *mdp = data;
>> -	struct device_node *vpu_node;
>>  
>>  	mtk_mdp_register_component(mdp, comp);
>>  
>> -	/*
>> -	 * If this component has a "mediatek-vpu" property, it is responsible for
>> -	 * notifying the mdp master driver about it so it can be further initialized
>> -	 * later.
>> -	 */
>> -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
>> -	if (vpu_node) {
>> +	if (is_mdp_master(dev)) {
>>  		int ret;
>>  
>> -		mdp->vpu_dev = of_find_device_by_node(vpu_node);
>> -		if (WARN_ON(!mdp->vpu_dev)) {
>> -			dev_err(dev, "vpu pdev failed\n");
>> -			of_node_put(vpu_node);
>> -		}
>> -
>>  		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
>>  		if (ret) {
>>  			dev_err(dev, "Failed to register v4l2 device\n");
>> @@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
>>  		}
>>  
>>  		/*
>> -		 * presence of the "mediatek,vpu" property in a device node
>> -		 * indicates that it is the primary MDP rdma device and MDP DMA
>> -		 * ops should be handled by its DMA callbacks.
>> +		 * MDP DMA ops will be handled by the DMA callbacks associated with this
>> +		 * device;
>>  		 */
>>  		mdp->rdma_dev = dev;
>>  	}
>> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
>> index 50eafcc9993d..6a775463399c 100644
>> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
>> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
>> @@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
>>  
>>  static int mtk_mdp_master_bind(struct device *dev)
>>  {
>> -	int status;
>>  	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
>> +	struct device_node *vpu_node;
>> +	int status;
>>  
>>  	status = component_bind_all(dev, mdp);
>>  	if (status) {
>> @@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
>>  		goto err_component_bind_all;
>>  	}
>>  
>> -	if (mdp->vpu_dev) {
>> -		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
>> -					  VPU_RST_MDP);
>> -		if (ret) {
>> -			dev_err(dev, "Failed to register reset handler\n");
>> -			goto err_wdt_reg;
>> -		}
>> -	} else {
>> -		dev_err(dev, "no vpu_dev found\n");
>> +	if (mdp->rdma_dev == NULL) {
>> +		dev_err(dev, "Primary MDP device not found");
>> +		status = -ENODEV;
>> +		goto err_component_bind_all;
>> +	}
>> +
>> +	vpu_node = of_find_node_by_name(NULL, "vpu");
>> +	if (!vpu_node) {
>> +		dev_err(dev, "unable to find vpu node");
>> +		status = -ENODEV;
>> +		goto err_wdt_reg;
>> +	}
>> +
>> +	mdp->vpu_dev = of_find_device_by_node(vpu_node);
> 
> The 'vpu_node' should be put by calling 'of_node_put(vpu_node)' when it
> is not used.
> 
>> +	if (!mdp->vpu_dev) {
>> +		dev_err(dev, "unable to find vpu device");
>> +		status = -ENODEV;
>> +		goto err_wdt_reg;
>> +	}
>> +
>> +	status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
>> +	if (status) {
>> +		dev_err(dev, "Failed to register reset handler\n");
>> +		goto err_wdt_reg;
>>  	}
>>  
>>  	status = mtk_mdp_register_m2m_device(mdp);
> 


From john.garry at huawei.com  Wed Aug 25 02:10:54 2021
From: john.garry at huawei.com (John Garry)
Date: Wed, 25 Aug 2021 17:10:54 +0800
Subject: [PATCH 0/2] Improve build test coverage for perf drivers
Message-ID: <1629882656-217983-1-git-send-email-john.garry@huawei.com>

Improve build test coverage by allowing some more drivers build under
COMPILE_TEST as appropriate.

John Garry (2):
  drivers/perf: thunderx2_pmu: Change data in size
    tx2_uncore_event_update()
  drivers/perf: Improve build test coverage

 drivers/perf/Kconfig         | 12 +++++++-----
 drivers/perf/thunderx2_pmu.c |  2 +-
 2 files changed, 8 insertions(+), 6 deletions(-)

-- 
2.26.2



From john.garry at huawei.com  Wed Aug 25 02:10:55 2021
From: john.garry at huawei.com (John Garry)
Date: Wed, 25 Aug 2021 17:10:55 +0800
Subject: [PATCH 1/2] drivers/perf: thunderx2_pmu: Change data in size
 tx2_uncore_event_update()
In-Reply-To: <1629882656-217983-1-git-send-email-john.garry@huawei.com>
References: <1629882656-217983-1-git-send-email-john.garry@huawei.com>
Message-ID: <1629882656-217983-2-git-send-email-john.garry@huawei.com>

A LSL of 32 requires > 32b value to hold the result. However in
tx2_uncore_event_update(), 1UL << 32 currently only works as unsigned
long is 64b on a 64b system.

If we want to compile test for a 32b system, we need unsigned long long,
whose min size is 64b.

Signed-off-by: John Garry <john.garry at huawei.com>
---
 drivers/perf/thunderx2_pmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
index fc1a376ee906..05378c0fd8f3 100644
--- a/drivers/perf/thunderx2_pmu.c
+++ b/drivers/perf/thunderx2_pmu.c
@@ -487,7 +487,7 @@ static void tx2_uncore_event_update(struct perf_event *event)
 		new = reg_readl(hwc->event_base);
 		prev = local64_xchg(&hwc->prev_count, new);
 		/* handles rollover of 32 bit counter */
-		delta = (u32)(((1UL << 32) - prev) + new);
+		delta = (u32)(((1ULL << 32) - prev) + new);
 	}
 
 	/* DMC event data_transfers granularity is 16 Bytes, convert it to 64 */
-- 
2.26.2



From john.garry at huawei.com  Wed Aug 25 02:10:56 2021
From: john.garry at huawei.com (John Garry)
Date: Wed, 25 Aug 2021 17:10:56 +0800
Subject: [PATCH 2/2] drivers/perf: Improve build test coverage
In-Reply-To: <1629882656-217983-1-git-send-email-john.garry@huawei.com>
References: <1629882656-217983-1-git-send-email-john.garry@huawei.com>
Message-ID: <1629882656-217983-3-git-send-email-john.garry@huawei.com>

Improve build test cover by allowing some drivers to build under
COMPILE_TEST where possible.

Some notes:
- Mostly a dependency on CONFIG_ACPI is not really required for only
  building (but left untouched), but is required for TX2 which uses ACPI
  functions which have no stubs
- XGENE required 64b dependency as it relies on some unsigned long perf
  struct fields being 64b
- I don't see why TX2 requires NUMA to build, but left untouched
- Added an explicit dependency on GENERIC_MSI_IRQ_DOMAIN for
  ARM_SMMU_V3_PMU, which is required for platform MSI functions

Signed-off-by: John Garry <john.garry at huawei.com>
---
 drivers/perf/Kconfig | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 77522e5efe11..4374af292e6d 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -36,7 +36,7 @@ config ARM_CCI5xx_PMU
 
 config ARM_CCN
 	tristate "ARM CCN driver support"
-	depends on ARM || ARM64
+	depends on ARM || ARM64 || COMPILE_TEST
 	help
 	  PMU (perf) driver supporting the ARM CCN (Cache Coherent Network)
 	  interconnect.
@@ -62,7 +62,8 @@ config ARM_PMU_ACPI
 
 config ARM_SMMU_V3_PMU
 	 tristate "ARM SMMUv3 Performance Monitors Extension"
-	 depends on ARM64 && ACPI
+	 depends on (ARM64 && ACPI) || (COMPILE_TEST && 64BIT)
+	 depends on GENERIC_MSI_IRQ_DOMAIN
 	   help
 	   Provides support for the ARM SMMUv3 Performance Monitor Counter
 	   Groups (PMCG), which provide monitoring of transactions passing
@@ -80,7 +81,7 @@ config ARM_DSU_PMU
 
 config FSL_IMX8_DDR_PMU
 	tristate "Freescale i.MX8 DDR perf monitor"
-	depends on ARCH_MXC
+	depends on ARCH_MXC || COMPILE_TEST
 	  help
 	  Provides support for the DDR performance monitor in i.MX8, which
 	  can give information about memory throughput and other related
@@ -108,7 +109,8 @@ config QCOM_L3_PMU
 
 config THUNDERX2_PMU
 	tristate "Cavium ThunderX2 SoC PMU UNCORE"
-	depends on ARCH_THUNDER2 && ARM64 && ACPI && NUMA
+	depends on ARCH_THUNDER2 || COMPILE_TEST
+	depends on NUMA && ACPI
 	default m
 	help
 	   Provides support for ThunderX2 UNCORE events.
@@ -116,7 +118,7 @@ config THUNDERX2_PMU
 	   in the DDR4 Memory Controller (DMC).
 
 config XGENE_PMU
-        depends on ARCH_XGENE
+        depends on ARCH_XGENE || (COMPILE_TEST && 64BIT)
         bool "APM X-Gene SoC PMU"
         default n
         help
-- 
2.26.2



From wangkefeng.wang at huawei.com  Wed Aug 25 02:21:13 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 17:21:13 +0800
Subject: [PATCH 1/4] ARM: mm: Provide set_memory_valid()
In-Reply-To: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
Message-ID: <20210825092116.149975-2-wangkefeng.wang@huawei.com>

This function validates and invalidates PTE entries.

Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 arch/arm/include/asm/set_memory.h |  5 ++++
 arch/arm/mm/pageattr.c            | 41 +++++++++++++++++++++++--------
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/arch/arm/include/asm/set_memory.h b/arch/arm/include/asm/set_memory.h
index ec17fc0fda7a..bf1728e1af1d 100644
--- a/arch/arm/include/asm/set_memory.h
+++ b/arch/arm/include/asm/set_memory.h
@@ -11,11 +11,16 @@ int set_memory_ro(unsigned long addr, int numpages);
 int set_memory_rw(unsigned long addr, int numpages);
 int set_memory_x(unsigned long addr, int numpages);
 int set_memory_nx(unsigned long addr, int numpages);
+int set_memory_valid(unsigned long addr, int numpages, int enable);
 #else
 static inline int set_memory_ro(unsigned long addr, int numpages) { return 0; }
 static inline int set_memory_rw(unsigned long addr, int numpages) { return 0; }
 static inline int set_memory_x(unsigned long addr, int numpages) { return 0; }
 static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
+static inline int set_memory_valid(unsigned long addr, int numpages, int enable)
+{
+	return 0;
+}
 #endif
 
 #endif
diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c
index 9790ae3a8c68..7612a1c6b614 100644
--- a/arch/arm/mm/pageattr.c
+++ b/arch/arm/mm/pageattr.c
@@ -31,6 +31,24 @@ static bool in_range(unsigned long start, unsigned long size,
 	return start >= range_start && start < range_end &&
 		size <= range_end - start;
 }
+/*
+ * This function assumes that the range is mapped with PAGE_SIZE pages.
+ */
+static int __change_memory_common(unsigned long start, unsigned long size,
+				pgprot_t set_mask, pgprot_t clear_mask)
+{
+	struct page_change_data data;
+	int ret;
+
+	data.set_mask = set_mask;
+	data.clear_mask = clear_mask;
+
+	ret = apply_to_page_range(&init_mm, start, size, change_page_range,
+					&data);
+
+	flush_tlb_kernel_range(start, start + size);
+	return ret;
+}
 
 static int change_memory_common(unsigned long addr, int numpages,
 				pgprot_t set_mask, pgprot_t clear_mask)
@@ -38,8 +56,6 @@ static int change_memory_common(unsigned long addr, int numpages,
 	unsigned long start = addr & PAGE_MASK;
 	unsigned long end = PAGE_ALIGN(addr) + numpages * PAGE_SIZE;
 	unsigned long size = end - start;
-	int ret;
-	struct page_change_data data;
 
 	WARN_ON_ONCE(start != addr);
 
@@ -50,14 +66,7 @@ static int change_memory_common(unsigned long addr, int numpages,
 	    !in_range(start, size, VMALLOC_START, VMALLOC_END))
 		return -EINVAL;
 
-	data.set_mask = set_mask;
-	data.clear_mask = clear_mask;
-
-	ret = apply_to_page_range(&init_mm, start, size, change_page_range,
-					&data);
-
-	flush_tlb_kernel_range(start, end);
-	return ret;
+	return __change_memory_common(start, size, set_mask, clear_mask);
 }
 
 int set_memory_ro(unsigned long addr, int numpages)
@@ -87,3 +96,15 @@ int set_memory_x(unsigned long addr, int numpages)
 					__pgprot(0),
 					__pgprot(L_PTE_XN));
 }
+
+int set_memory_valid(unsigned long addr, int numpages, int enable)
+{
+	if (enable)
+		return __change_memory_common(addr, PAGE_SIZE * numpages,
+					__pgprot(L_PTE_VALID),
+					__pgprot(0));
+	else
+		return __change_memory_common(addr, PAGE_SIZE * numpages,
+					__pgprot(0),
+					__pgprot(L_PTE_VALID));
+}
-- 
2.26.2



From wangkefeng.wang at huawei.com  Wed Aug 25 02:21:12 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 17:21:12 +0800
Subject: [PATCH 0/4] ARM: Support KFENCE feature
Message-ID: <20210825092116.149975-1-wangkefeng.wang@huawei.com>

The patch 1~3 is to support KFENCE feature on ARM. 

NOTE: 
The context of patch2/3 changes in arch/arm/mm/fault.c is based on link[1],
which make some refactor and cleanup about page fault.

kfence_test is not useful when kfence is not enabled, skip kfence test
when kfence not enabled in patch4.

I tested the kfence_test on ARM QEMU with or without ARM_LPAE and all passed.

[1] https://lore.kernel.org/linux-arm-kernel/20210610123556.171328-1-wangkefeng.wang at huawei.com/

Kefeng Wang (4):
  ARM: mm: Provide set_memory_valid()
  ARM: mm: Provide is_write_fault()
  ARM: Support KFENCE for ARM
  mm: kfence: Only load kfence_test when kfence is enabled

 arch/arm/Kconfig                  |  1 +
 arch/arm/include/asm/kfence.h     | 52 +++++++++++++++++++++++++++++++
 arch/arm/include/asm/set_memory.h |  5 +++
 arch/arm/mm/fault.c               | 16 ++++++++--
 arch/arm/mm/pageattr.c            | 41 ++++++++++++++++++------
 include/linux/kfence.h            |  2 ++
 mm/kfence/core.c                  |  8 +++++
 mm/kfence/kfence_test.c           |  2 ++
 8 files changed, 114 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm/include/asm/kfence.h

-- 
2.26.2



From wangkefeng.wang at huawei.com  Wed Aug 25 02:21:16 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 17:21:16 +0800
Subject: [PATCH 4/4] mm: kfence: Only load kfence_test when kfence is enabled
In-Reply-To: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
Message-ID: <20210825092116.149975-5-wangkefeng.wang@huawei.com>

Provide kfence_is_enabled() helper, only load kfence_test module
when kfence is enabled.

Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 include/linux/kfence.h  | 2 ++
 mm/kfence/core.c        | 8 ++++++++
 mm/kfence/kfence_test.c | 2 ++
 3 files changed, 12 insertions(+)

diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 3fe6dd8a18c1..f08f24e8a726 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -22,6 +22,8 @@
 #define KFENCE_POOL_SIZE ((CONFIG_KFENCE_NUM_OBJECTS + 1) * 2 * PAGE_SIZE)
 extern char *__kfence_pool;
 
+bool kfence_is_enabled(void);
+
 #ifdef CONFIG_KFENCE_STATIC_KEYS
 #include <linux/static_key.h>
 DECLARE_STATIC_KEY_FALSE(kfence_allocation_key);
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 7a97db8bc8e7..f1aaa7ebdcad 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -51,6 +51,14 @@ static unsigned long kfence_sample_interval __read_mostly = CONFIG_KFENCE_SAMPLE
 #endif
 #define MODULE_PARAM_PREFIX "kfence."
 
+bool kfence_is_enabled(void)
+{
+	if (!kfence_sample_interval || !READ_ONCE(kfence_enabled))
+		return false;
+	return true;
+}
+EXPORT_SYMBOL_GPL(kfence_is_enabled);
+
 static int param_set_sample_interval(const char *val, const struct kernel_param *kp)
 {
 	unsigned long num;
diff --git a/mm/kfence/kfence_test.c b/mm/kfence/kfence_test.c
index eb6307c199ea..4087f9f1497e 100644
--- a/mm/kfence/kfence_test.c
+++ b/mm/kfence/kfence_test.c
@@ -847,6 +847,8 @@ static void unregister_tracepoints(struct tracepoint *tp, void *ignore)
  */
 static int __init kfence_test_init(void)
 {
+	if (!kfence_is_enabled())
+		return 0;
 	/*
 	 * Because we want to be able to build the test as a module, we need to
 	 * iterate through all known tracepoints, since the static registration
-- 
2.26.2



From wangkefeng.wang at huawei.com  Wed Aug 25 02:21:14 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 17:21:14 +0800
Subject: [PATCH 2/4] ARM: mm: Provide is_write_fault()
In-Reply-To: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
Message-ID: <20210825092116.149975-3-wangkefeng.wang@huawei.com>

The function will check whether the fault is caused by a write access.

Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 arch/arm/mm/fault.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index bc8779d54a64..f7ab6dabe89f 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -207,6 +207,11 @@ static inline bool is_permission_fault(unsigned int fsr)
 	return false;
 }
 
+static inline bool is_write_fault(unsigned int fsr)
+{
+	return (fsr & FSR_WRITE) && !(fsr & FSR_CM);
+}
+
 static vm_fault_t __kprobes
 __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int flags,
 		unsigned long vma_flags, struct pt_regs *regs)
@@ -261,7 +266,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	if (user_mode(regs))
 		flags |= FAULT_FLAG_USER;
 
-	if ((fsr & FSR_WRITE) && !(fsr & FSR_CM)) {
+	if (is_write_fault(fsr)) {
 		flags |= FAULT_FLAG_WRITE;
 		vm_flags = VM_WRITE;
 	}
-- 
2.26.2



From wangkefeng.wang at huawei.com  Wed Aug 25 02:21:15 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 17:21:15 +0800
Subject: [PATCH 3/4] ARM: Support KFENCE for ARM
In-Reply-To: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
Message-ID: <20210825092116.149975-4-wangkefeng.wang@huawei.com>

Add architecture specific implementation details for KFENCE and enable
KFENCE on ARM. In particular, this implements the required interface in
 <asm/kfence.h>.

KFENCE requires that attributes for pages from its memory pool can
individually be set. Therefore, force the kfence pool to be mapped
at page granularity.

Testing this patch using the testcases in kfence_test.c and all passed
with or without ARM_LPAE.

Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 arch/arm/Kconfig              |  1 +
 arch/arm/include/asm/kfence.h | 52 +++++++++++++++++++++++++++++++++++
 arch/arm/mm/fault.c           |  9 ++++--
 3 files changed, 60 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/include/asm/kfence.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7a8059ff6bb0..3798f82a0c0d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -73,6 +73,7 @@ config ARM
 	select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
 	select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
 	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
+	select HAVE_ARCH_KFENCE if MMU
 	select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
 	select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
 	select HAVE_ARCH_MMAP_RND_BITS if MMU
diff --git a/arch/arm/include/asm/kfence.h b/arch/arm/include/asm/kfence.h
new file mode 100644
index 000000000000..eae7a12ab2a9
--- /dev/null
+++ b/arch/arm/include/asm/kfence.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_ARM_KFENCE_H
+#define __ASM_ARM_KFENCE_H
+
+#include <linux/kfence.h>
+#include <asm/set_memory.h>
+#include <asm/pgalloc.h>
+
+static inline int split_pmd_page(pmd_t *pmd, unsigned long addr)
+{
+	int i;
+	unsigned long pfn = PFN_DOWN(__pa((addr & PMD_MASK)));
+	pte_t *pte = pte_alloc_one_kernel(&init_mm);
+
+	if (!pte)
+		return -ENOMEM;
+
+	for (i = 0; i < PTRS_PER_PTE; i++)
+		set_pte_ext(pte + i, pfn_pte(pfn + i, PAGE_KERNEL), 0);
+	pmd_populate_kernel(&init_mm, pmd, pte);
+
+	flush_tlb_kernel_range(addr, addr + PMD_SIZE);
+	return 0;
+}
+
+static inline bool arch_kfence_init_pool(void)
+{
+	unsigned long addr;
+	pmd_t *pmd;
+
+	for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr);
+	     addr += PAGE_SIZE) {
+		pmd = pmd_off_k(addr);
+
+		if (pmd_leaf(*pmd)) {
+			if (split_pmd_page(pmd, addr))
+				return false;
+		}
+	}
+
+	return true;
+}
+
+static inline bool kfence_protect_page(unsigned long addr, bool protect)
+{
+	set_memory_valid(addr, 1, !protect);
+
+	return true;
+}
+
+#endif /* __ASM_ARM_KFENCE_H */
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index f7ab6dabe89f..9fa221ffa1b9 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -17,6 +17,7 @@
 #include <linux/sched/debug.h>
 #include <linux/highmem.h>
 #include <linux/perf_event.h>
+#include <linux/kfence.h>
 
 #include <asm/system_misc.h>
 #include <asm/system_info.h>
@@ -131,10 +132,14 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
 	/*
 	 * No handler, we'll have to terminate things with extreme prejudice.
 	 */
-	if (addr < PAGE_SIZE)
+	if (addr < PAGE_SIZE) {
 		msg = "NULL pointer dereference";
-	else
+	} else {
+		if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
+			return;
+
 		msg = "paging request";
+	}
 
 	die_kernel_fault(msg, mm, addr, fsr, regs);
 }
-- 
2.26.2



From ulf.hansson at linaro.org  Wed Aug 25 02:22:33 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 25 Aug 2021 11:22:33 +0200
Subject: [PATCH 1/6] mmc: sdhci-esdhc-imx: remove redundant code for
 manual tuning
In-Reply-To: <VI1PR04MB5294D4EE6173C4897ABF496090C69@VI1PR04MB5294.eurprd04.prod.outlook.com>
References: <1629117508-4886-1-git-send-email-haibo.chen@nxp.com>
 <CAPDyKFr2z6t0uefxioLHaszvwrc9Pkf1OJDi=jozjpEZcKP5ng@mail.gmail.com>
 <VI1PR04MB5294D4EE6173C4897ABF496090C69@VI1PR04MB5294.eurprd04.prod.outlook.com>
Message-ID: <CAPDyKFrA929iRMdZMmA1qYcYtufRzahcP7uc3Vwsw1C1MGeTJA@mail.gmail.com>

On Wed, 25 Aug 2021 at 04:16, Bough Chen <haibo.chen at nxp.com> wrote:
>
> > -----Original Message-----
> > From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> > Sent: 2021?8?24? 21:53
> > To: Bough Chen <haibo.chen at nxp.com>
> > Cc: Adrian Hunter <adrian.hunter at intel.com>; Shawn Guo
> > <shawnguo at kernel.org>; Rob Herring <robh+dt at kernel.org>; Sascha Hauer
> > <s.hauer at pengutronix.de>; Sascha Hauer <kernel at pengutronix.de>; Fabio
> > Estevam <festevam at gmail.com>; linux-mmc <linux-mmc at vger.kernel.org>;
> > dl-linux-imx <linux-imx at nxp.com>; DTML <devicetree at vger.kernel.org>; Linux
> > ARM <linux-arm-kernel at lists.infradead.org>
> > Subject: Re: [PATCH 1/6] mmc: sdhci-esdhc-imx: remove redundant code for
> > manual tuning
> >
> > On Mon, 16 Aug 2021 at 15:00, <haibo.chen at nxp.com> wrote:
> > >
> > > From: Haibo Chen <haibo.chen at nxp.com>
> > >
> > > For manual tuning method, already call esdhc_prepare_tuning() config
> > > the necessary registers, so remove the redundant code in
> > > esdhc_writew_le() for SDHCI_HOST_CONTROL2.
> > >
> > > Signed-off-by: Haibo Chen <haibo.chen at nxp.com>
> >
> > While discussions on the DT binding, etc, continue with Lucas and Rob on patch
> > 3 - do you want me to apply patch1 and patch2?
>
> Yes, thanks!
> Let's wait comments for patch 3.

Alright, patch1 and pacth2 applied for next, thanks!

[...]

Kind regards
Uffe


From maz at kernel.org  Wed Aug 25 02:27:10 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 25 Aug 2021 10:27:10 +0100
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <YSVhV+UIMY12u2PW@google.com>
References: <YSVhV+UIMY12u2PW@google.com>
Message-ID: <87mtp5q3gx.wl-maz@kernel.org>

Hi Oliver,

Adding Andrew and Peter to the discussion.

On Tue, 24 Aug 2021 22:15:03 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> Hey folks,
> 
> Ricardo and I were discussing hypercall support in KVM/arm64 and
> something seems to be a bit problematic. I do not see anywhere that KVM
> requires opt-in from the VMM to expose new hypercalls to the guest. To
> name a few, the TRNG and KVM PTP hypercalls are unconditionally provided
> to the guest.
> 
> Exposing new hypercalls to guests in this manner seems very unsafe to
> me. Suppose an operator is trying to upgrade from kernel N to kernel
> N+1, which brings in the new 'widget' hypercall. Guests are live
> migrated onto the N+1 kernel, but the operator finds a defect that
> warrants a kernel rollback. VMs are then migrated from kernel N+1 -> N.
> Any guests that discovered the 'widget' hypercall are likely going to
> get fussy _very_ quickly on the old kernel.

This goes against what we decided to support for the *only* publicly
available VMM that cares about save/restore, which is that we only
move forward and don't rollback. Hypercalls are the least of your
worries, and there is a whole range of other architectural features
that will have also appeared/disappeared (your own CNTPOFF series is a
glaring example of this).

I appreciate that you may have different considerations, but I felt
that it was important to state *why* this is the way it is.

> 
> Really, we need to ensure that the exposed guest ABI is
> backwards-compatible. Running a VMM that is blissfully unaware of the
> 'widget' hypercall should not implicitly expose it to its guest on a new
> kernel.
> 
> This conversation was in the context of devising a new UAPI that allows
> VMMs to trap hypercalls to userspace. While such an interface would
> easily work around the issue, the onus of ABI compatibility lies with
> the kernel.
> 
> So, this is all a long-winded way of asking: how do we dig ourselves out
> of this situation, and how to we avoid it happening again in the future?
> I believe the answer to both is to have new VM capabilities for sets of
> hypercalls exposed to the guest. Unfortunately, the unconditional
> exposure of TRNG and PTP hypercalls is ABI now, so we'd have to provide
> an opt-out at this point. For anything new, require opt-in from the VMM
> before we give it to the guest.
>
> Have I missed something blatantly obvious, or do others see this as an
> issue as well? I'll reply with an example of adding opt-out for PTP.
> I'm sure other hypercalls could be handled similarly.

Why do we need this? For future hypercalls, we could have some buy-in
capabilities. For existing ones, it is too late, and negative features
are just too horrible.

For KVM-specific hypercalls, we could get the VMM to save/restore the
bitmap of supported functions. That would be "less horrible". This
could be implemented using extra "firmware pseudo-registers" such as
the ones described in Documentation/virt/kvm/arm/psci.rst.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From glider at google.com  Wed Aug 25 02:31:22 2021
From: glider at google.com (Alexander Potapenko)
Date: Wed, 25 Aug 2021 11:31:22 +0200
Subject: [PATCH 4/4] mm: kfence: Only load kfence_test when kfence is
 enabled
In-Reply-To: <20210825092116.149975-5-wangkefeng.wang@huawei.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <20210825092116.149975-5-wangkefeng.wang@huawei.com>
Message-ID: <CAG_fn=X9oaw0zJrcmShNcvd3UsNSFKsH3kSdD5Yx=4Sk_WtNrQ@mail.gmail.com>

On Wed, Aug 25, 2021 at 11:17 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
> Provide kfence_is_enabled() helper, only load kfence_test module
> when kfence is enabled.

What's wrong with the current behavior?
I think we need at least some way to tell the developer that KFENCE
does not work, and a failing test seems to be the perfect one.

> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  include/linux/kfence.h  | 2 ++
>  mm/kfence/core.c        | 8 ++++++++
>  mm/kfence/kfence_test.c | 2 ++
>  3 files changed, 12 insertions(+)
>
> diff --git a/include/linux/kfence.h b/include/linux/kfence.h
> index 3fe6dd8a18c1..f08f24e8a726 100644
> --- a/include/linux/kfence.h
> +++ b/include/linux/kfence.h
> @@ -22,6 +22,8 @@
>  #define KFENCE_POOL_SIZE ((CONFIG_KFENCE_NUM_OBJECTS + 1) * 2 * PAGE_SIZE)
>  extern char *__kfence_pool;
>
> +bool kfence_is_enabled(void);
> +
>  #ifdef CONFIG_KFENCE_STATIC_KEYS
>  #include <linux/static_key.h>
>  DECLARE_STATIC_KEY_FALSE(kfence_allocation_key);
> diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> index 7a97db8bc8e7..f1aaa7ebdcad 100644
> --- a/mm/kfence/core.c
> +++ b/mm/kfence/core.c
> @@ -51,6 +51,14 @@ static unsigned long kfence_sample_interval __read_mostly = CONFIG_KFENCE_SAMPLE
>  #endif
>  #define MODULE_PARAM_PREFIX "kfence."
>
> +bool kfence_is_enabled(void)
> +{
> +       if (!kfence_sample_interval || !READ_ONCE(kfence_enabled))
> +               return false;
> +       return true;
> +}
> +EXPORT_SYMBOL_GPL(kfence_is_enabled);
> +
>  static int param_set_sample_interval(const char *val, const struct kernel_param *kp)
>  {
>         unsigned long num;
> diff --git a/mm/kfence/kfence_test.c b/mm/kfence/kfence_test.c
> index eb6307c199ea..4087f9f1497e 100644
> --- a/mm/kfence/kfence_test.c
> +++ b/mm/kfence/kfence_test.c
> @@ -847,6 +847,8 @@ static void unregister_tracepoints(struct tracepoint *tp, void *ignore)
>   */
>  static int __init kfence_test_init(void)
>  {
> +       if (!kfence_is_enabled())
> +               return 0;
>         /*
>          * Because we want to be able to build the test as a module, we need to
>          * iterate through all known tracepoints, since the static registration
> --
> 2.26.2
>
> --
> You received this message because you are subscribed to the Google Groups "kasan-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to kasan-dev+unsubscribe at googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/kasan-dev/20210825092116.149975-5-wangkefeng.wang%40huawei.com.



-- 
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Stra?e, 33
80636 M?nchen

Gesch?ftsf?hrer: Paul Manicle, Halimah DeLaine Prado
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg


From jason-jh.lin at mediatek.com  Wed Aug 25 02:34:18 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 25 Aug 2021 17:34:18 +0800
Subject: [PATCH v8 12/13] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <CAAOTY_9+2CvcSxZByqxVM18hLQfE0rt5zf2JLxCYrd8O1_UCAg@mail.gmail.com>
References: <20210819022327.13040-1-jason-jh.lin@mediatek.com>
 <20210819022327.13040-13-jason-jh.lin@mediatek.com>
 <CAAOTY_9+2CvcSxZByqxVM18hLQfE0rt5zf2JLxCYrd8O1_UCAg@mail.gmail.com>
Message-ID: <6d376c2d9a616cdb7b4f095d3e6c08dd824cccd7.camel@mediatek.com>

Hi Chun-Kuang,

Thanks for the review.

On Fri, 2021-08-20 at 23:43 +0800, Chun-Kuang Hu wrote:
> Hi, Jason:
> 
> jason-jh.lin <jason-jh.lin at mediatek.com> ? 2021?8?19? ?? ??10:23???
> > 
> > Add MERGE engine file:
> > MERGE module is used to merge two slice-per-line inputs
> > into one side-by-side output.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/Makefile           |   1 +
> >  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
> >  drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 268
> > ++++++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  16 ++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   2 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
> >  7 files changed, 297 insertions(+)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > 
> > diff --git a/drivers/gpu/drm/mediatek/Makefile
> > b/drivers/gpu/drm/mediatek/Makefile
> > index dc54a7a69005..538e0087a44c 100644
> > --- a/drivers/gpu/drm/mediatek/Makefile
> > +++ b/drivers/gpu/drm/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >  mediatek-drm-y := mtk_disp_ccorr.o \
> >                   mtk_disp_color.o \
> >                   mtk_disp_gamma.o \
> > +                 mtk_disp_merge.o \
> >                   mtk_disp_ovl.o \
> >                   mtk_disp_rdma.o \
> >                   mtk_drm_crtc.o \
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > index cafd9df2d63b..f407cd9d873e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > @@ -46,6 +46,14 @@ void mtk_gamma_set_common(void __iomem *regs,
> > struct drm_crtc_state *state);
> >  void mtk_gamma_start(struct device *dev);
> >  void mtk_gamma_stop(struct device *dev);
> > 
> > +int mtk_merge_clk_enable(struct device *dev);
> > +void mtk_merge_clk_disable(struct device *dev);
> > +void mtk_merge_config(struct device *dev, unsigned int width,
> > +                     unsigned int height, unsigned int vrefresh,
> > +                     unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> > +void mtk_merge_start(struct device *dev);
> > +void mtk_merge_stop(struct device *dev);
> > +
> >  void mtk_ovl_bgclr_in_on(struct device *dev);
> >  void mtk_ovl_bgclr_in_off(struct device *dev);
> >  void mtk_ovl_bypass_shadow(struct device *dev);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > new file mode 100644
> > index 000000000000..ebcb646bde9c
> > --- /dev/null
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> > @@ -0,0 +1,268 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/component.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/soc/mediatek/mtk-cmdq.h>
> > +
> > +#include "mtk_drm_ddp_comp.h"
> > +#include "mtk_drm_drv.h"
> > +#include "mtk_disp_drv.h"
> > +
> > +#define DISP_REG_MERGE_CTRL            0x000
> > +#define MERGE_EN                               1
> > +#define DISP_REG_MERGE_CFG_0           0x010
> > +#define DISP_REG_MERGE_CFG_4           0x020
> > +#define DISP_REG_MERGE_CFG_10          0x038
> > +/* no swap */
> > +#define SWAP_MODE                              0
> > +#define FLD_SWAP_MODE                          GENMASK(4, 0)
> > +#define DISP_REG_MERGE_CFG_12          0x040
> > +#define CFG_10_10_1PI_2PO_BUF_MODE             6
> > +#define CFG_10_10_2PI_2PO_BUF_MODE             8
> > +#define FLD_CFG_MERGE_MODE                     GENMASK(4, 0)
> > +#define DISP_REG_MERGE_CFG_24          0x070
> > +#define DISP_REG_MERGE_CFG_25          0x074
> > +#define DISP_REG_MERGE_CFG_36          0x0a0
> > +#define ULTRA_EN                               1
> 
> You could use FLD_ULTRA_EN for this.

OK, I'll use mtk_ddp_write() directly, if the bit width of setting is
always the same as mask.

> 
> > +#define PREULTRA_EN                            1
> > +#define HALT_FOR_DVFS_EN                       0
> 
> You could just not set this.

OK, I'll remove the setting of 0.

> 
> > +#define FLD_ULTRA_EN                           GENMASK(0, 0)
> 
> #define FLD_ULTRA_EN BIT(0)
> 
> Regards,
> Chun-Kuang.
> 
OK, I'll just use BIT(n) instead of GENMASK(n, n).

Regards,
Jason-JH.Lin

> > +#define FLD_PREULTRA_EN                                GENMASK(4,
> > 4)
> > +#define FLD_HALT_FOR_DVFS_EN                   GENMASK(8, 8)
> > +#define DISP_REG_MERGE_CFG_37          0x0a4
> > +/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
> > +#define BUFFER_MODE                            3
> > +#define FLD_BUFFER_MODE                                GENMASK(1,
> > 0)
> > +#define DISP_REG_MERGE_CFG_38                  0x0a8
> > +#define FLD_VDE_BLOCK_ULTRA                    GENMASK(0, 0)
> > +#define FLD_VALID_TH_BLOCK_ULTRA               GENMASK(4, 4)
> > +#define FLD_ULTRA_FIFO_VALID_TH                        GENMASK(31,
> > 16)
> > +#define DISP_REG_MERGE_CFG_39          0x0ac
> > +#define FLD_NVDE_FORCE_PREULTRA                        GENMASK(8,
> > 8)
> > +#define FLD_NVALID_TH_FORCE_PREULTRA           GENMASK(12, 12)
> > +#define FLD_PREULTRA_FIFO_VALID_TH             GENMASK(31, 16)
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>

From will at kernel.org  Wed Aug 25 02:39:11 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 25 Aug 2021 10:39:11 +0100
Subject: [PATCH] arm64: signal32: Drop pointless call to sigdelsetmask()
Message-ID: <20210825093911.24493-1-will@kernel.org>

Commit 77097ae503b1 ("most of set_current_blocked() callers want
SIGKILL/SIGSTOP removed from set") extended set_current_blocked() to
remove SIGKILL and SIGSTOP from the new signal set and updated all
callers accordingly.

Unfortunately, this collided with the merge of the arm64 architecture,
which duly removes these signals when restoring the compat sigframe, as
this was what was previously done by arch/arm/.

Remove the redundant call to sigdelsetmask() from
compat_restore_sigframe().

Cc: Catalin Marinas <catalin.marinas at arm.com>
Reported-by: Al Viro <viro at zeniv.linux.org.uk>
Signed-off-by: Will Deacon <will at kernel.org>
---
 arch/arm64/kernel/signal32.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 2f507f565c48..4850333669fb 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -46,8 +46,6 @@ struct compat_aux_sigframe {
 	unsigned long			end_magic;
 } __attribute__((__aligned__(8)));
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
 static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
 {
 	compat_sigset_t	cset;
@@ -190,10 +188,8 @@ static int compat_restore_sigframe(struct pt_regs *regs,
 	unsigned long psr;
 
 	err = get_sigset_t(&set, &sf->uc.uc_sigmask);
-	if (err == 0) {
-		sigdelsetmask(&set, ~_BLOCKABLE);
+	if (err == 0)
 		set_current_blocked(&set);
-	}
 
 	__get_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
 	__get_user_error(regs->regs[1], &sf->uc.uc_mcontext.arm_r1, err);
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From jason-jh.lin at mediatek.com  Wed Aug 25 02:41:16 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 17:41:16 +0800
Subject: [PATCH v6 1/5] dt-bindings: mailbox: add definition for mt8195
In-Reply-To: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
References: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825094120.5005-2-jason-jh.lin@mediatek.com>

Add definition of compatible and dt-binding header for mt8195.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 Documentation/devicetree/bindings/mailbox/mtk-gce.txt | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 7771ecaac586..a036fb5407bb 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,8 +9,8 @@ CMDQ driver uses mailbox framework for communication. Please refer to
 mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
-- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce" or
-  "mediatek,mt6779-gce".
+- compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce",
+  "mediatek,mt6779-gce" or "mediatek,mt8195-gce".
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -36,8 +36,9 @@ Optional properties for a client device:
   size: the total size of register address that GCE can access.
 
 Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h',
-'dt-binding/gce/mt8183-gce.h' or 'dt-bindings/gce/mt6779-gce.h'. Such as
-sub-system ids, thread priority, event ids.
+'dt-binding/gce/mt8183-gce.h', 'dt-bindings/gce/mt6779-gce.h' or
+'dt-binding/gce/mt8195-gce.h'. Such as sub-system ids, thread priority,
+event ids.
 
 Example:
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 02:41:18 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 17:41:18 +0800
Subject: [PATCH v6 3/5] arm64: dts: mt8195: add gce node
In-Reply-To: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
References: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825094120.5005-4-jason-jh.lin@mediatek.com>

Add gce node and gce alias on mt8195 dts file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is based on [1]
[1] Add Mediatek SoC MT8195 and evaluation board dts and Makefile
    - https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index c146a91c6272..47c44cb77da0 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include <dt-bindings/clock/mt8195-clk.h>
+#include <dt-bindings/gce/mt8195-gce.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/power/mt8195-power.h>
@@ -16,6 +17,11 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		gce0 = &gce0;
+		gce1 = &gce1;
+	};
+
 	clocks {
 		clk26m: oscillator0 {
 			compatible = "fixed-clock";
@@ -699,6 +705,22 @@
 			#clock-cells = <1>;
 		};
 
+		gce0: mdp_mailbox at 10320000 {
+			compatible = "mediatek,mt8195-gce";
+			reg = <0 0x10320000 0 0x4000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_GCE>;
+		};
+
+		gce1: disp_mailbox at 10330000 {
+			compatible = "mediatek,mt8195-gce";
+			reg = <0 0x10330000 0 0x4000>;
+			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_GCE2>;
+		};
+
 		scp_adsp: syscon at 10720000 {
 			compatible = "mediatek,mt8195-scp_adsp", "syscon";
 			reg = <0 0x10720000 0 0x1000>;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 02:41:20 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 17:41:20 +0800
Subject: [PATCH v6 5/5] mailbox: cmdq: add multi-gce clocks support for mt8195
In-Reply-To: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
References: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825094120.5005-6-jason-jh.lin@mediatek.com>

For the design of GCE hardware event signal transportation,
evnet rx will send the event signal to all GCE event merges
after receiving the event signal from the other hardware.

Because GCE event merges need to response to event rx, their
clocks must be enabled at that time.

To make sure all the gce clock is enabled while receiving the
hardware event, each cmdq mailbox should enable or disable
the others gce clk at the same time.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 90 +++++++++++++++++++++++-------
 1 file changed, 70 insertions(+), 20 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 205bde4ed6e6..3839faab68ca 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -19,6 +19,7 @@
 
 #define CMDQ_OP_CODE_MASK		(0xff << CMDQ_OP_CODE_SHIFT)
 #define CMDQ_NUM_CMD(t)			(t->cmd_buf_size / CMDQ_INST_SIZE)
+#define CMDQ_GCE_NUM_MAX		(2)
 
 #define CMDQ_CURR_IRQ_STATUS		0x10
 #define CMDQ_SYNC_TOKEN_UPDATE		0x68
@@ -73,14 +74,16 @@ struct cmdq {
 	u32			thread_nr;
 	u32			irq_mask;
 	struct cmdq_thread	*thread;
-	struct clk		*clock;
+	struct clk_bulk_data	clocks[CMDQ_GCE_NUM_MAX];
 	bool			suspended;
 	u8			shift_pa;
+	u32			gce_num;
 };
 
 struct gce_plat {
 	u32 thread_nr;
 	u8 shift;
+	u32 gce_num;
 };
 
 u8 cmdq_get_shift_pa(struct mbox_chan *chan)
@@ -120,11 +123,13 @@ static void cmdq_init(struct cmdq *cmdq)
 {
 	int i;
 
-	WARN_ON(clk_enable(cmdq->clock) < 0);
+	WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
+
 	writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
 	for (i = 0; i <= CMDQ_MAX_EVENT; i++)
 		writel(i, cmdq->base + CMDQ_SYNC_TOKEN_UPDATE);
-	clk_disable(cmdq->clock);
+
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 }
 
 static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
@@ -262,7 +267,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
 
 	if (list_empty(&thread->task_busy_list)) {
 		cmdq_thread_disable(cmdq, thread);
-		clk_disable(cmdq->clock);
+		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 	}
 }
 
@@ -307,7 +312,7 @@ static int cmdq_suspend(struct device *dev)
 	if (task_running)
 		dev_warn(dev, "exist running task(s) in suspend\n");
 
-	clk_unprepare(cmdq->clock);
+	clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
 
 	return 0;
 }
@@ -316,7 +321,7 @@ static int cmdq_resume(struct device *dev)
 {
 	struct cmdq *cmdq = dev_get_drvdata(dev);
 
-	WARN_ON(clk_prepare(cmdq->clock) < 0);
+	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
 	cmdq->suspended = false;
 	return 0;
 }
@@ -325,8 +330,7 @@ static int cmdq_remove(struct platform_device *pdev)
 {
 	struct cmdq *cmdq = platform_get_drvdata(pdev);
 
-	clk_unprepare(cmdq->clock);
-
+	clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
 	return 0;
 }
 
@@ -352,7 +356,8 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 	task->pkt = pkt;
 
 	if (list_empty(&thread->task_busy_list)) {
-		WARN_ON(clk_enable(cmdq->clock) < 0);
+		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
+
 		/*
 		 * The thread reset will clear thread related register to 0,
 		 * including pc, end, priority, irq, suspend and enable. Thus
@@ -424,7 +429,8 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 	}
 
 	cmdq_thread_disable(cmdq, thread);
-	clk_disable(cmdq->clock);
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+
 done:
 	/*
 	 * The thread->task_busy_list empty means thread already disable. The
@@ -469,7 +475,7 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
 
 	cmdq_thread_resume(thread);
 	cmdq_thread_disable(cmdq, thread);
-	clk_disable(cmdq->clock);
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 
 out:
 	spin_unlock_irqrestore(&thread->chan->lock, flags);
@@ -518,6 +524,10 @@ static int cmdq_probe(struct platform_device *pdev)
 	struct cmdq *cmdq;
 	int err, i;
 	struct gce_plat *plat_data;
+	struct device_node *phandle = dev->of_node;
+	struct device_node *node;
+	int alias_id = 0;
+	char clk_name[4] = "gce";
 
 	cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
 	if (!cmdq)
@@ -540,6 +550,7 @@ static int cmdq_probe(struct platform_device *pdev)
 
 	cmdq->thread_nr = plat_data->thread_nr;
 	cmdq->shift_pa = plat_data->shift;
+	cmdq->gce_num = plat_data->gce_num;
 	cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0);
 	err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
 			       "mtk_cmdq", cmdq);
@@ -551,10 +562,28 @@ static int cmdq_probe(struct platform_device *pdev)
 	dev_dbg(dev, "cmdq device: addr:0x%p, va:0x%p, irq:%d\n",
 		dev, cmdq->base, cmdq->irq);
 
-	cmdq->clock = devm_clk_get(dev, "gce");
-	if (IS_ERR(cmdq->clock)) {
-		dev_err(dev, "failed to get gce clk\n");
-		return PTR_ERR(cmdq->clock);
+	if (cmdq->gce_num > 1) {
+		for_each_child_of_node(phandle->parent, node) {
+			char clk_id[8];
+
+			alias_id = of_alias_get_id(node, clk_name);
+			if (alias_id < cmdq->gce_num) {
+				snprintf(clk_id, sizeof(clk_id), "%s%d", clk_name, alias_id);
+				cmdq->clocks[alias_id].id = clk_id;
+				cmdq->clocks[alias_id].clk = of_clk_get(node, 0);
+				if (IS_ERR(cmdq->clocks[alias_id].clk)) {
+					dev_err(dev, "failed to get gce clk: %d\n", alias_id);
+					return PTR_ERR(cmdq->clocks[alias_id].clk);
+				}
+			}
+		}
+	} else {
+		cmdq->clocks[alias_id].id = clk_name;
+		cmdq->clocks[alias_id].clk = devm_clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(cmdq->clocks[alias_id].clk)) {
+			dev_err(dev, "failed to get gce clk\n");
+			return PTR_ERR(cmdq->clocks[alias_id].clk);
+		}
 	}
 
 	cmdq->mbox.dev = dev;
@@ -590,7 +619,8 @@ static int cmdq_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, cmdq);
-	WARN_ON(clk_prepare(cmdq->clock) < 0);
+
+	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
 
 	cmdq_init(cmdq);
 
@@ -602,15 +632,35 @@ static const struct dev_pm_ops cmdq_pm_ops = {
 	.resume = cmdq_resume,
 };
 
-static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
-static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
-static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
+static const struct gce_plat gce_plat_v2 = {
+	.thread_nr = 16,
+	.shift = 0,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v3 = {
+	.thread_nr = 24,
+	.shift = 0,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v4 = {
+	.thread_nr = 24,
+	.shift = 3,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v5 = {
+	.thread_nr = 24,
+	.shift = 3,
+	.gce_num = 2
+};
 
 static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
 	{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
 	{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
-	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v4},
+	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v5},
 	{}
 };
 
-- 
2.18.0

From claudiu.beznea at microchip.com  Wed Aug 25 02:40:55 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Wed, 25 Aug 2021 12:40:55 +0300
Subject: [PATCH v4] ARM: dts: at91: sama5d27_wlsom1: add wifi device
Message-ID: <20210825094055.642941-1-claudiu.beznea@microchip.com>

From: Eugen Hristev <eugen.hristev at microchip.com>

SAMA5D27 WLSOM1 boards has a WILC3000 device soldered. Add proper
device tree nodes for this.

[eugen.hristev: original author of this code]
Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
[nicolas.ferre: original author of this code]
Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
[claudiu.beznea: adapt such that make dtbs_check is happy, remove status
 for wifi_pwrseq and wifi nodes]
Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---

Changes in v4:
- keep only this patch as the rest from series were applied on mmc tree
- remove status="okay" on wifi node and pwrseq node
- adapt to remove all warnings thown by make dtbs_check

 arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi | 70 +++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
index 025a78310e3a..21c86171e462 100644
--- a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
+++ b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
@@ -30,6 +30,14 @@ main_xtal {
 			clock-frequency = <24000000>;
 		};
 	};
+
+	wifi_pwrseq: wifi_pwrseq {
+		compatible = "mmc-pwrseq-wilc1000";
+		reset-gpios = <&pioA PIN_PA27 GPIO_ACTIVE_HIGH>;
+		powerdown-gpios = <&pioA PIN_PA29 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&pinctrl_wilc_pwrseq>;
+		pinctrl-names = "default";
+	};
 };
 
 &flx1 {
@@ -310,5 +318,67 @@ pinctrl_qspi1_default: qspi1_default {
 			 <PIN_PB10__QSPI1_IO3>;
 		bias-pull-up;
 	};
+
+	pinctrl_sdmmc1_default: sdmmc1_default {
+		cmd-data {
+			pinmux = <PIN_PA28__SDMMC1_CMD>,
+				 <PIN_PA18__SDMMC1_DAT0>,
+				 <PIN_PA19__SDMMC1_DAT1>,
+				 <PIN_PA20__SDMMC1_DAT2>,
+				 <PIN_PA21__SDMMC1_DAT3>;
+			bias-disable;
+		};
+
+		conf-ck {
+			pinmux = <PIN_PA22__SDMMC1_CK>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_wilc_default: wilc_default {
+		conf-irq {
+			pinmux = <PIN_PB25__GPIO>;
+			bias-disable;
+		};
+	};
+
+	pinctrl_wilc_pwrseq: wilc_pwrseq {
+		conf-ce-nrst {
+			pinmux = <PIN_PA27__GPIO>,
+				 <PIN_PA29__GPIO>;
+			bias-disable;
+		};
+
+		conf-rtcclk {
+			pinmux = <PIN_PB13__PCK1>;
+			bias-disable;
+		};
+	};
+};
+
+&sdmmc1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	bus-width = <4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sdmmc1_default>;
+	mmc-pwrseq = <&wifi_pwrseq>;
+	no-1-8-v;
+	non-removable;
+	bus-width = <4>;
+	status = "okay";
+
+	wilc: wifi at 0 {
+		reg = <0>;
+		compatible = "microchip,wilc1000";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_wilc_default>;
+		clocks = <&pmc PMC_TYPE_SYSTEM 9>;
+		clock-names = "rtc";
+		interrupts = <PIN_PB25 IRQ_TYPE_NONE>;
+		interrupt-parent = <&pioA>;
+		assigned-clocks = <&pmc PMC_TYPE_SYSTEM 9>;
+		assigned-clock-rates = <32768>;
+	};
 };
 
-- 
2.25.1



From maz at kernel.org  Wed Aug 25 02:46:37 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 25 Aug 2021 10:46:37 +0100
Subject: [boot-wrapper PATCH 0/5] Misc cleanups
In-Reply-To: <20210824134900.34849-1-mark.rutland@arm.com>
References: <20210824134900.34849-1-mark.rutland@arm.com>
Message-ID: <87k0k9q2ki.wl-maz@kernel.org>

On Tue, 24 Aug 2021 14:48:55 +0100,
Mark Rutland <mark.rutland at arm.com> wrote:
> 
> These are a few cleanup patches I've split out of my ongoing bootwrapper
> rework, and intend to apply by the end of this week.
> 
> My WIP cleanup branch with subsequent patches can be found at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git cleanup
> 
> Thanks,
> Mark.
> 
> Mark Rutland (5):
>   Remove unused Set/Way cache helpers
>   aarch32: simplify _switch_monitor
>   GICv3: initialize without RMW
>   Rename kernel *_RESET values to *_KERNEL
>   Rename `CNTFRQ` -> `COUNTER_FREQ`
> 
>  Makefile.am                       |  4 ++--
>  arch/aarch32/boot.S               | 25 +++++++------------------
>  arch/aarch32/include/asm/cpu.h    | 30 ++----------------------------
>  arch/aarch32/include/asm/gic-v3.h |  7 -------
>  arch/aarch64/boot.S               |  6 +++---
>  arch/aarch64/include/asm/cpu.h    | 32 +++-----------------------------
>  arch/aarch64/include/asm/gic-v3.h |  7 -------
>  common/gic-v3.c                   |  8 +++-----
>  8 files changed, 20 insertions(+), 99 deletions(-)

For the whole series:

Acked-by: Marc Zyngier <maz at kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


From baruch at tkos.co.il  Wed Aug 25 02:48:24 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 12:48:24 +0300
Subject: [PATCH v7 1/4] dt-bindings: mfd: qcom,
 tcsr: document ipq6018 compatible
Message-ID: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/mfd/qcom,tcsr.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt b/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
index e90519d566a3..c5f4f0ddfcc3 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
+++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
@@ -6,6 +6,7 @@ registers via syscon.
 
 Required properties:
 - compatible:	Should contain:
+		"qcom,tcsr-ipq6018", "syscon", "simple-mfd" for IPQ6018
 		"qcom,tcsr-ipq8064", "syscon" for IPQ8064
 		"qcom,tcsr-apq8064", "syscon" for APQ8064
 		"qcom,tcsr-msm8660", "syscon" for MSM8660
-- 
2.32.0



From baruch at tkos.co.il  Wed Aug 25 02:48:27 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 12:48:27 +0300
Subject: [PATCH v7 4/4] arm64: dts: ipq6018: add pwm node
In-Reply-To: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
References: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
Message-ID: <80f5b40bfa3f644b5de41be65f771a0d7fb11d30.1629884907.git.baruch@tkos.co.il>

Describe the PWM block on IPQ6018.

The PWM is in the TCSR area. Make &tcsr "simple-mfd" compatible, and add
&pwm as child of &tcsr.

Add also ipq6018 specific compatible string.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v7:

  Use 'reg' instead of 'offset' (Rob)

  Add qcom,tcsr-ipq6018 (Rob)

  Drop clock-names (Bjorn)

v6:

  Make the PWM node child of TCSR (Rob Herring)

  Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)

v5: Use qcom,pwm-regs for TCSR phandle instead of direct regs

v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
---
 arch/arm64/boot/dts/qcom/ipq6018.dtsi | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index ecadbee53554..6750a920cdb8 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -259,8 +259,20 @@ tcsr_mutex_regs: syscon at 1905000 {
 		};
 
 		tcsr: syscon at 1937000 {
-			compatible = "syscon";
+			compatible = "qcom,tcsr-ipq6018", "syscon", "simple-mfd";
 			reg = <0x0 0x01937000 0x0 0x21000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pwm: pwm at a010 {
+				compatible = "qcom,ipq6018-pwm";
+				reg = <0xa010>;
+				clocks = <&gcc GCC_ADSS_PWM_CLK>;
+				assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
+				assigned-clock-rates = <100000000>;
+				#pwm-cells = <2>;
+				status = "disabled";
+			};
 		};
 
 		blsp_dma: dma-controller at 7884000 {
-- 
2.32.0



From baruch at tkos.co.il  Wed Aug 25 02:48:26 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 12:48:26 +0300
Subject: [PATCH v7 3/4] dt-bindings: pwm: add IPQ6018 binding
In-Reply-To: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
References: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
Message-ID: <dbf064fb60b1654af25f65d89f75bd397162d701.1629884907.git.baruch@tkos.co.il>

DT binding for the PWM block in Qualcomm IPQ6018 SoC.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v7:

  Use 'reg' instead of 'offset' (Rob)

  Drop 'clock-names' and 'assigned-clock*' (Bjorn)

  Use single cell address/size in example node (Bjorn)

  Move '#pwm-cells' lower in example node (Bjorn)

  List 'reg' as required

v6:

  Device node is child of TCSR; remove phandle (Rob Herring)

  Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)

v5: Use qcom,pwm-regs for phandle instead of direct regs (Bjorn
    Andersson, Kathiravan T)

v4: Update the binding example node as well (Rob Herring's bot)

v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)

v2: Make #pwm-cells const (Rob Herring)
---
 .../devicetree/bindings/pwm/ipq-pwm.yaml      | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/ipq-pwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml b/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
new file mode 100644
index 000000000000..edfec41e77e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/ipq-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm IPQ6018 PWM controller
+
+maintainers:
+  - Baruch Siach <baruch at tkos.co.il>
+
+properties:
+  "#pwm-cells":
+    const: 2
+
+  compatible:
+    const: qcom,ipq6018-pwm
+
+  reg:
+    description: Offset of PWM register in the TCSR block.
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#pwm-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-ipq6018.h>
+
+    tcsr: syscon at 1937000 {
+        compatible = "qcom,tcsr-ipq6018", "syscon", "simple-mfd";
+        reg = <0x01937000 0x21000>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pwm: pwm at a010 {
+            compatible = "qcom,ipq6018-pwm";
+            reg = <0xa010>;
+            clocks = <&gcc GCC_ADSS_PWM_CLK>;
+            assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
+            assigned-clock-rates = <100000000>;
+            #pwm-cells = <2>;
+        };
+    };
-- 
2.32.0



From baruch at tkos.co.il  Wed Aug 25 02:48:25 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 12:48:25 +0300
Subject: [PATCH v7 2/4] pwm: driver for qualcomm ipq6018 pwm block
In-Reply-To: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
References: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
Message-ID: <b47f2506fe2a2e803018798c81722d2dcaa520d3.1629884907.git.baruch@tkos.co.il>

Driver for the PWM block in Qualcomm IPQ6018 line of SoCs. Based on
driver from downstream Codeaurora kernel tree. Removed support for older
(V1) variants because I have no access to that hardware.

Tested on IPQ6010 based hardware.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v7:

  Change 'offset' to 'reg' for the tcsr offset (Rob)

  Drop clock name; there is only one clock (Bjorn)

  Simplify probe failure code path (Bjorn)

v6:

Address Uwe Kleine-K?nig review comments:

  Drop IPQ_PWM_MAX_DEVICES

  Rely on assigned-clock-rates; drop IPQ_PWM_CLK_SRC_FREQ

  Simplify register offset calculation

  Calculate duty cycle more precisely

  Refuse to set inverted polarity

  Drop redundant IPQ_PWM_REG1_ENABLE bit clear

  Remove x1000 factor in pwm_div calculation, use rate directly, and round up

  Choose initial pre_div such that pwm_div < IPQ_PWM_MAX_DIV

  Ensure pre_div <= pwm_div

  Rename close_ to best_

  Explain in comment why effective_div doesn't overflow

  Limit pwm_div to IPQ_PWM_MAX_DIV - 1 to allow 100% duty cycle

  Disable clock only after pwmchip_remove()

  const pwm_ops

Other changes:

  Add missing linux/bitfield.h header include (kernel test robot)

  Adjust code for PWM device node under TCSR (Rob Herring)

v5:

Use &tcsr_q6 syscon to access registers (Bjorn Andersson)

Address Uwe Kleine-K?nig review comments:

  Implement .get_state()

  Add IPQ_PWM_ prefix to local macros

  Use GENMASK/BIT/FIELD_PREP for register fields access

  Make type of config_div_and_duty() parameters consistent

  Derive IPQ_PWM_MIN_PERIOD_NS from IPQ_PWM_CLK_SRC_FREQ

  Integrate enable/disable into config_div_and_duty() to save register read,
  and reduce frequency glitch on update

  Use min() instead of min_t()

  Fix comment format

  Use dev_err_probe() to indicate probe step failure

  Add missing clk_disable_unprepare() in .remove

  Don't set .owner

v4:

  Use div64_u64() to fix link for 32-bit targets ((kernel test robot
  <lkp at intel.com>, Uwe Kleine-K?nig)

v3:

  s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)

  Fix integer overflow on 32-bit targets (kernel test robot <lkp at intel.com>)

v2:

Address Uwe Kleine-K?nig review comments:

  Fix period calculation when out of range

  Don't set period larger than requested

  Remove PWM disable on configuration change

  Implement .apply instead of non-atomic .config/.enable/.disable

  Don't modify PWM on .request/.free

  Check pwm_div underflow

  Fix various code and comment formatting issues

Other changes:

  Use u64 divisor safe division

  Remove now empty .request/.free
---
 drivers/pwm/Kconfig   |  12 ++
 drivers/pwm/Makefile  |   1 +
 drivers/pwm/pwm-ipq.c | 275 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 288 insertions(+)
 create mode 100644 drivers/pwm/pwm-ipq.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index c76adedd58c9..08add845596f 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -260,6 +260,18 @@ config PWM_INTEL_LGM
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-intel-lgm.
 
+config PWM_IPQ
+	tristate "IPQ PWM support"
+	depends on ARCH_QCOM || COMPILE_TEST
+	depends on HAVE_CLK && HAS_IOMEM
+	help
+	  Generic PWM framework driver for IPQ PWM block which supports
+	  4 pwm channels. Each of the these channels can be configured
+	  independent of each other.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-ipq.
+
 config PWM_IQS620A
 	tristate "Azoteq IQS620A PWM support"
 	depends on MFD_IQS62X || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 708840b7fba8..7402feae4b36 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_PWM_IMX1)		+= pwm-imx1.o
 obj-$(CONFIG_PWM_IMX27)		+= pwm-imx27.o
 obj-$(CONFIG_PWM_IMX_TPM)	+= pwm-imx-tpm.o
 obj-$(CONFIG_PWM_INTEL_LGM)	+= pwm-intel-lgm.o
+obj-$(CONFIG_PWM_IPQ)		+= pwm-ipq.o
 obj-$(CONFIG_PWM_IQS620A)	+= pwm-iqs620a.o
 obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
 obj-$(CONFIG_PWM_KEEMBAY)	+= pwm-keembay.o
diff --git a/drivers/pwm/pwm-ipq.c b/drivers/pwm/pwm-ipq.c
new file mode 100644
index 000000000000..8405d0554951
--- /dev/null
+++ b/drivers/pwm/pwm-ipq.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/*
+ * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/math64.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/bitfield.h>
+
+/* The frequency range supported is 1 Hz to clock rate */
+#define IPQ_PWM_MAX_PERIOD_NS	((u64)NSEC_PER_SEC)
+
+/*
+ * The max value specified for each field is based on the number of bits
+ * in the pwm control register for that field
+ */
+#define IPQ_PWM_MAX_DIV		0xFFFF
+
+/*
+ * Two 32-bit registers for each PWM: REG0, and REG1.
+ * Base offset for PWM #i is at 8 * #i.
+ */
+#define IPQ_PWM_CFG_REG0 0 /*PWM_DIV PWM_HI*/
+#define IPQ_PWM_REG0_PWM_DIV		GENMASK(15, 0)
+#define IPQ_PWM_REG0_HI_DURATION	GENMASK(31, 16)
+
+#define IPQ_PWM_CFG_REG1 4 /*ENABLE UPDATE PWM_PRE_DIV*/
+#define IPQ_PWM_REG1_PRE_DIV		GENMASK(15, 0)
+/*
+ * Enable bit is set to enable output toggling in pwm device.
+ * Update bit is set to reflect the changed divider and high duration
+ * values in register.
+ */
+#define IPQ_PWM_REG1_UPDATE		BIT(30)
+#define IPQ_PWM_REG1_ENABLE		BIT(31)
+
+
+struct ipq_pwm_chip {
+	struct pwm_chip chip;
+	struct clk *clk;
+	struct regmap *regmap;
+	u32 regmap_off;
+};
+
+static struct ipq_pwm_chip *to_ipq_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct ipq_pwm_chip, chip);
+}
+
+static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned reg)
+{
+	struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
+	unsigned int off = ipq_chip->regmap_off + 8 * pwm->hwpwm + reg;
+	unsigned int val;
+
+	regmap_read(ipq_chip->regmap, off, &val);
+
+	return val;
+}
+
+static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned reg,
+		unsigned val)
+{
+	struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
+	unsigned int off = ipq_chip->regmap_off + 8 * pwm->hwpwm + reg;
+
+	regmap_write(ipq_chip->regmap, off, val);
+}
+
+static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div,
+			unsigned int pwm_div, unsigned long rate, u64 duty_ns,
+			bool enable)
+{
+	unsigned long hi_dur;
+	unsigned long val = 0;
+
+	/*
+	 * high duration = pwm duty * (pwm div + 1)
+	 * pwm duty = duty_ns / period_ns
+	 */
+	hi_dur = div64_u64(duty_ns * rate, (pre_div + 1) * NSEC_PER_SEC);
+
+	val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
+		FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div);
+	ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG0, val);
+
+	val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div);
+	ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG1, val);
+
+	/* Enable needs a separate write to REG1 */
+	val |= IPQ_PWM_REG1_UPDATE;
+	if (enable)
+		val |= IPQ_PWM_REG1_ENABLE;
+	ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG1, val);
+}
+
+static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			 const struct pwm_state *state)
+{
+	struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip);
+	unsigned long freq;
+	unsigned int pre_div, pwm_div, best_pre_div, best_pwm_div;
+	long long diff;
+	unsigned long rate = clk_get_rate(ipq_chip->clk);
+	unsigned long min_diff = rate;
+	u64 period_ns, duty_ns;
+
+	if (state->polarity != PWM_POLARITY_NORMAL)
+		return -EINVAL;
+
+	if (state->period < div64_u64(NSEC_PER_SEC, rate))
+		return -ERANGE;
+
+	period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS);
+	duty_ns = min(state->duty_cycle, period_ns);
+
+	/* freq in Hz for period in nano second */
+	freq = div64_u64(NSEC_PER_SEC, period_ns);
+	best_pre_div = IPQ_PWM_MAX_DIV;
+	best_pwm_div = IPQ_PWM_MAX_DIV;
+	/* Initial pre_div value such that pwm_div < IPQ_PWM_MAX_DIV */
+	pre_div = DIV64_U64_ROUND_UP(period_ns * rate,
+			(u64)NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1));
+
+	for (; pre_div <= IPQ_PWM_MAX_DIV; pre_div++) {
+		pwm_div = DIV64_U64_ROUND_UP(period_ns * rate,
+				(u64)NSEC_PER_SEC * (pre_div + 1));
+		pwm_div--;
+
+		if (pre_div > pwm_div)
+			break;
+
+		/*
+		 * Make sure we can do 100% duty cycle where
+		 * hi_dur == pwm_div + 1
+		 */
+		if (pwm_div > IPQ_PWM_MAX_DIV - 1)
+			continue;
+
+		diff = ((uint64_t)freq * (pre_div + 1) * (pwm_div + 1))
+			- (uint64_t)rate;
+
+		if (diff < 0) /* period larger than requested */
+			continue;
+		if (diff == 0) { /* bingo */
+			best_pre_div = pre_div;
+			best_pwm_div = pwm_div;
+			break;
+		}
+		if (diff < min_diff) {
+			min_diff = diff;
+			best_pre_div = pre_div;
+			best_pwm_div = pwm_div;
+		}
+	}
+
+	/* config divider values for the closest possible frequency */
+	config_div_and_duty(pwm, best_pre_div, best_pwm_div,
+			    rate, duty_ns, state->enabled);
+
+	return 0;
+}
+
+static void ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+			      struct pwm_state *state)
+{
+	struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip);
+	unsigned long rate = clk_get_rate(ipq_chip->clk);
+	unsigned int pre_div, pwm_div, hi_dur;
+	u64 effective_div, hi_div;
+	u32 reg0, reg1;
+
+	reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_CFG_REG0);
+	reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_CFG_REG1);
+
+	state->polarity = PWM_POLARITY_NORMAL;
+	state->enabled = reg1 & IPQ_PWM_REG1_ENABLE;
+
+	pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0);
+	hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0);
+	pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1);
+
+	/* No overflow here, both pre_div and pwm_div <= 0xffff */
+	effective_div = (u64)(pre_div + 1) * (pwm_div + 1);
+	state->period = div64_u64(effective_div * NSEC_PER_SEC, rate);
+
+	hi_div = hi_dur * (pre_div + 1);
+	state->duty_cycle = div64_u64(hi_div * NSEC_PER_SEC, rate);
+}
+
+static const struct pwm_ops ipq_pwm_ops = {
+	.apply = ipq_pwm_apply,
+	.get_state = ipq_pwm_get_state,
+	.owner = THIS_MODULE,
+};
+
+static int ipq_pwm_probe(struct platform_device *pdev)
+{
+	struct ipq_pwm_chip *pwm;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
+	if (!pwm)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pwm);
+
+	pwm->regmap = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(pwm->regmap))
+		return dev_err_probe(dev, PTR_ERR(pwm->regmap),
+				"regs map failed");
+
+	ret = of_property_read_u32(dev->of_node, "reg", &pwm->regmap_off);
+	if (ret)
+		return dev_err_probe(dev, ret, "error reading 'reg'");
+
+	pwm->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(pwm->clk))
+		return dev_err_probe(dev, PTR_ERR(pwm->clk),
+				"failed to get clock");
+
+	ret = clk_prepare_enable(pwm->clk);
+	if (ret)
+		return dev_err_probe(dev, ret, "clock enable failed");
+
+	pwm->chip.dev = dev;
+	pwm->chip.ops = &ipq_pwm_ops;
+	pwm->chip.npwm = 4;
+
+	ret = pwmchip_add(&pwm->chip);
+	if (ret < 0) {
+		dev_err_probe(dev, ret, "pwmchip_add() failed\n");
+		clk_disable_unprepare(pwm->clk);
+	}
+
+	return ret;
+}
+
+static int ipq_pwm_remove(struct platform_device *pdev)
+{
+	struct ipq_pwm_chip *pwm = platform_get_drvdata(pdev);
+
+	pwmchip_remove(&pwm->chip);
+	clk_disable_unprepare(pwm->clk);
+
+	return 0;
+}
+
+static const struct of_device_id pwm_ipq_dt_match[] = {
+	{ .compatible = "qcom,ipq6018-pwm", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, pwm_ipq_dt_match);
+
+static struct platform_driver ipq_pwm_driver = {
+	.driver = {
+		.name = "ipq-pwm",
+		.of_match_table = pwm_ipq_dt_match,
+	},
+	.probe = ipq_pwm_probe,
+	.remove = ipq_pwm_remove,
+};
+
+module_platform_driver(ipq_pwm_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
-- 
2.32.0



From wenst at chromium.org  Wed Aug 25 02:48:58 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 17:48:58 +0800
Subject: [v4 4/5] soc: mediatek: pm-domains: Move power status offset to
 power domain data
In-Reply-To: <20210823092353.3502-5-chun-jie.chen@mediatek.com>
References: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
 <20210823092353.3502-5-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5Fe6tCaYgn7MUY9g1niyFPx1VwNEidpy3BL0o0a9eoq=A@mail.gmail.com>

Hi,

On Mon, Aug 23, 2021 at 5:25 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> MT8195 has more than 32 power domains so it needs
> two set of pwr_sta and pwr_sta2nd registers,
> so move the register offset from soc data into power domain data.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> ---
>  drivers/soc/mediatek/mt8167-pm-domains.h | 16 +++++++--
>  drivers/soc/mediatek/mt8173-pm-domains.h | 22 ++++++++++--
>  drivers/soc/mediatek/mt8183-pm-domains.h | 32 +++++++++++++++--
>  drivers/soc/mediatek/mt8192-pm-domains.h | 44 ++++++++++++++++++++++--
>  drivers/soc/mediatek/mtk-pm-domains.c    |  4 +--
>  drivers/soc/mediatek/mtk-pm-domains.h    |  4 +--
>  6 files changed, 110 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/soc/mediatek/mt8167-pm-domains.h b/drivers/soc/mediatek/mt8167-pm-domains.h
> index 15559ddf26e4..4d6c32759606 100644
> --- a/drivers/soc/mediatek/mt8167-pm-domains.h
> +++ b/drivers/soc/mediatek/mt8167-pm-domains.h

[...]

> @@ -69,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>                 .name = "mfg_async",
>                 .sta_mask = PWR_STATUS_MFG_ASYNC,
>                 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
> +               .pwr_sta_offs = SPM_PWR_STATUS,
> +               .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = 0,
>         },

This hunk no longer applies due to

    http://git.kernel.org/matthias.bgg/c/114956518c85f4e93c298749b35b46b2e78a2ec9

ChenYu


From patchwork-bot+netdevbpf at kernel.org  Wed Aug 25 02:50:05 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 25 Aug 2021 09:50:05 +0000
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <20210823143754.14294-1-michael.riesch@wolfvision.net>
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
Message-ID: <162988500584.26256.659865970373423632.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (refs/heads/master):

On Mon, 23 Aug 2021 16:37:54 +0200 you wrote:
> This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
> "net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
> unbalanced pm_runtime_enable warnings.
> 
> In the commit to be reverted, support for power management was
> introduced to the Rockchip glue code. Later, power management support
> was introduced to the stmmac core code, resulting in multiple
> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
> 
> [...]

Here is the summary with links:
  - net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable warnings
    https://git.kernel.org/netdev/net/c/2d26f6e39afb

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From jason-jh.lin at mediatek.com  Wed Aug 25 02:41:19 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 17:41:19 +0800
Subject: [PATCH v6 4/5] mailbox: cmdq: add mediatek mailbox support for mt8195
In-Reply-To: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
References: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825094120.5005-5-jason-jh.lin@mediatek.com>

Add mt8195 compatible name in the driver data of cmdq mailbox driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 67a42b514429..205bde4ed6e6 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -610,6 +610,7 @@ static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
 	{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
 	{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
+	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v4},
 	{}
 };
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 02:41:15 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 17:41:15 +0800
Subject: [PATCH v6 0/5] Add gce support for mt8195
Message-ID: <20210825094120.5005-1-jason-jh.lin@mediatek.com>

Change in v6:
- remove the unused define in GCE header file.

Change in v5:
- rebase on kernel-5.14-rc1
- remove unused varriable in mtk-cmdq-mailbox.c

Change in v4:
- change clk array to bulk_clk_data array

Change in v3:
- fix #mbox-cless number in dts

Change in v2:
- remove the second clock in dts and add alias id for gce node
- find the other gce node and get it's clock

jason-jh.lin (5):
  dt-bindings: mailbox: add definition for mt8195
  dt-bindings: gce: add gce header file for mt8195
  arm64: dts: mt8195: add gce node
  mailbox: cmdq: add mediatek mailbox support for mt8195
  mailbox: cmdq: add multi-gce clocks support for mt8195

 .../devicetree/bindings/mailbox/mtk-gce.txt   |   9 +-
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      |  22 +
 drivers/mailbox/mtk-cmdq-mailbox.c            |  89 +-
 include/dt-bindings/gce/mt8195-gce.h          | 805 ++++++++++++++++++
 4 files changed, 902 insertions(+), 23 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt8195-gce.h

-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 02:41:17 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 17:41:17 +0800
Subject: [PATCH v6 2/5] dt-bindings: gce: add gce header file for mt8195
In-Reply-To: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
References: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825094120.5005-3-jason-jh.lin@mediatek.com>

To define the subsys id and event id, add gce header file for mt8195.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 include/dt-bindings/gce/mt8195-gce.h | 805 +++++++++++++++++++++++++++
 1 file changed, 805 insertions(+)
 create mode 100644 include/dt-bindings/gce/mt8195-gce.h

diff --git a/include/dt-bindings/gce/mt8195-gce.h b/include/dt-bindings/gce/mt8195-gce.h
new file mode 100644
index 000000000000..ec7008925296
--- /dev/null
+++ b/include/dt-bindings/gce/mt8195-gce.h
@@ -0,0 +1,805 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8195_H
+#define _DT_BINDINGS_GCE_MT8195_H
+
+#define CMDQ_NO_TIMEOUT		0xffffffff
+
+/* GCE thread priority */
+#define CMDQ_THR_PRIO_LOWEST	0
+#define CMDQ_THR_PRIO_1		1
+#define CMDQ_THR_PRIO_2		2
+#define CMDQ_THR_PRIO_3		3
+#define CMDQ_THR_PRIO_4		4
+#define CMDQ_THR_PRIO_5		5
+#define CMDQ_THR_PRIO_6		6
+#define CMDQ_THR_PRIO_HIGHEST	7
+
+/* GCE subsys table */
+#define SUBSYS_1400XXXX		0
+#define SUBSYS_1401XXXX		1
+#define SUBSYS_1402XXXX		2
+#define SUBSYS_1c00XXXX		3
+#define SUBSYS_1c01XXXX		4
+#define SUBSYS_1c02XXXX		5
+#define SUBSYS_1c10XXXX		6
+#define SUBSYS_1c11XXXX		7
+#define SUBSYS_1c12XXXX		8
+#define SUBSYS_14f0XXXX		9
+#define SUBSYS_14f1XXXX		10
+#define SUBSYS_14f2XXXX		11
+#define SUBSYS_1800XXXX		12
+#define SUBSYS_1801XXXX		13
+#define SUBSYS_1802XXXX		14
+#define SUBSYS_1803XXXX		15
+#define SUBSYS_1032XXXX		16
+#define SUBSYS_1033XXXX		17
+#define SUBSYS_1600XXXX		18
+#define SUBSYS_1601XXXX		19
+#define SUBSYS_14e0XXXX		20
+#define SUBSYS_1c20XXXX		21
+#define SUBSYS_1c30XXXX		22
+#define SUBSYS_1c40XXXX		23
+#define SUBSYS_1c50XXXX		24
+#define SUBSYS_1c60XXXX		25
+#define SUBSYS_NO_SUPPORT	99
+
+/* GCE General Purpose Register (GPR) support */
+#define GCE_GPR_R00		0x0
+#define GCE_GPR_R01		0x1
+#define GCE_GPR_R02		0x2
+#define GCE_GPR_R03		0x3
+#define GCE_GPR_R04		0x4
+#define GCE_GPR_R05		0x5
+#define GCE_GPR_R06		0x6
+#define GCE_GPR_R07		0x7
+#define GCE_GPR_R08		0x8
+#define GCE_GPR_R09		0x9
+#define GCE_GPR_R10		0xa
+#define GCE_GPR_R11		0xb
+#define GCE_GPR_R12		0xc
+#define GCE_GPR_R13		0xd
+#define GCE_GPR_R14		0xe
+#define GCE_GPR_R15		0xf
+
+/* GCE hw event id */
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_0	1
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_1	2
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_2	3
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_3	4
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_4	5
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_5	6
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_6	7
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_7	8
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_8	9
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_9	10
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_10	11
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_11	12
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_12	13
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_13	14
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_14	15
+#define CMDQ_EVENT_TRAW0_DMA_ERROR_INT	16
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_0	17
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_1	18
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_2	19
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_3	20
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_4	21
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_5	22
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_6	23
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_7	24
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_8	25
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_9	26
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_10	27
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_11	28
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_12	29
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_13	30
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_14	31
+#define CMDQ_EVENT_TRAW1_DMA_ERROR_INT	32
+
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_0	65
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_1	66
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_2	67
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_3	68
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_4	69
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_5	70
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_6	71
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_7	72
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_8	73
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_9	74
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_10	75
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_11	76
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_12	77
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_13	78
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_14	79
+#define CMDQ_EVENT_DIP0_DMA_ERR	80
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_0	81
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_1	82
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_2	83
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_3	84
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_4	85
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_5	86
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_6	87
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_7	88
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_8	89
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_9	90
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_10	91
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_11	92
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_12	93
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_13	94
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_14	95
+#define CMDQ_EVENT_PQA0_DMA_ERR	96
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_0	97
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_1	98
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_2	99
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_3	100
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_4	101
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_5	102
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_6	103
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_7	104
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_8	105
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_9	106
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_10	107
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_11	108
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_12	109
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_13	110
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_14	111
+#define CMDQ_EVENT_PQB0_DMA_ERR	112
+#define CMDQ_EVENT_DIP0_DUMMY_0	113
+#define CMDQ_EVENT_DIP0_DUMMY_1	114
+#define CMDQ_EVENT_DIP0_DUMMY_2	115
+#define CMDQ_EVENT_DIP0_DUMMY_3	116
+#define CMDQ_EVENT_WPE0_EIS_GCE_FRAME_DONE	117
+#define CMDQ_EVENT_WPE0_EIS_DONE_SYNC_OUT	118
+#define CMDQ_EVENT_WPE0_TNR_GCE_FRAME_DONE	119
+#define CMDQ_EVENT_WPE0_TNR_DONE_SYNC_OUT	120
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_0	121
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_1	122
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_2	123
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_3	124
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_4	125
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_5	126
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_6	127
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_7	128
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_8	129
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_9	130
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_10	131
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_11	132
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_12	133
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_13	134
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_14	135
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_0	136
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_1	137
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_2	138
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_3	139
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_4	140
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_5	141
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_6	142
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_7	143
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_8	144
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_9	145
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_10	146
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_11	147
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_12	148
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_13	149
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_14	150
+#define CMDQ_EVENT_WPE0_DUMMY_0	151
+#define CMDQ_EVENT_IMGSYS_IPE_DUMMY	152
+#define CMDQ_EVENT_IMGSYS_IPE_FDVT_DONE	153
+#define CMDQ_EVENT_IMGSYS_IPE_ME_DONE	154
+#define CMDQ_EVENT_IMGSYS_IPE_DVS_DONE	155
+#define CMDQ_EVENT_IMGSYS_IPE_DVP_DONE	156
+
+#define CMDQ_EVENT_TPR_0	194
+#define CMDQ_EVENT_TPR_1	195
+#define CMDQ_EVENT_TPR_2	196
+#define CMDQ_EVENT_TPR_3	197
+#define CMDQ_EVENT_TPR_4	198
+#define CMDQ_EVENT_TPR_5	199
+#define CMDQ_EVENT_TPR_6	200
+#define CMDQ_EVENT_TPR_7	201
+#define CMDQ_EVENT_TPR_8	202
+#define CMDQ_EVENT_TPR_9	203
+#define CMDQ_EVENT_TPR_10	204
+#define CMDQ_EVENT_TPR_11	205
+#define CMDQ_EVENT_TPR_12	206
+#define CMDQ_EVENT_TPR_13	207
+#define CMDQ_EVENT_TPR_14	208
+#define CMDQ_EVENT_TPR_15	209
+#define CMDQ_EVENT_TPR_16	210
+#define CMDQ_EVENT_TPR_17	211
+#define CMDQ_EVENT_TPR_18	212
+#define CMDQ_EVENT_TPR_19	213
+#define CMDQ_EVENT_TPR_20	214
+#define CMDQ_EVENT_TPR_21	215
+#define CMDQ_EVENT_TPR_22	216
+#define CMDQ_EVENT_TPR_23	217
+#define CMDQ_EVENT_TPR_24	218
+#define CMDQ_EVENT_TPR_25	219
+#define CMDQ_EVENT_TPR_26	220
+#define CMDQ_EVENT_TPR_27	221
+#define CMDQ_EVENT_TPR_28	222
+#define CMDQ_EVENT_TPR_29	223
+#define CMDQ_EVENT_TPR_30	224
+#define CMDQ_EVENT_TPR_31	225
+#define CMDQ_EVENT_TPR_TIMEOUT_0	226
+#define CMDQ_EVENT_TPR_TIMEOUT_1	227
+#define CMDQ_EVENT_TPR_TIMEOUT_2	228
+#define CMDQ_EVENT_TPR_TIMEOUT_3	229
+#define CMDQ_EVENT_TPR_TIMEOUT_4	230
+#define CMDQ_EVENT_TPR_TIMEOUT_5	231
+#define CMDQ_EVENT_TPR_TIMEOUT_6	232
+#define CMDQ_EVENT_TPR_TIMEOUT_7	233
+#define CMDQ_EVENT_TPR_TIMEOUT_8	234
+#define CMDQ_EVENT_TPR_TIMEOUT_9	235
+#define CMDQ_EVENT_TPR_TIMEOUT_10	236
+#define CMDQ_EVENT_TPR_TIMEOUT_11	237
+#define CMDQ_EVENT_TPR_TIMEOUT_12	238
+#define CMDQ_EVENT_TPR_TIMEOUT_13	239
+#define CMDQ_EVENT_TPR_TIMEOUT_14	240
+#define CMDQ_EVENT_TPR_TIMEOUT_15	241
+
+#define CMDQ_EVENT_VPP0_MDP_RDMA_SOF	256
+#define CMDQ_EVENT_VPP0_MDP_FG_SOF	257
+#define CMDQ_EVENT_VPP0_STITCH_SOF	258
+#define CMDQ_EVENT_VPP0_MDP_HDR_SOF	259
+#define CMDQ_EVENT_VPP0_MDP_AAL_SOF	260
+#define CMDQ_EVENT_VPP0_MDP_RSZ_IN_RSZ_SOF	261
+#define CMDQ_EVENT_VPP0_MDP_TDSHP_SOF	262
+#define CMDQ_EVENT_VPP0_DISP_COLOR_SOF	263
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_SOF	264
+#define CMDQ_EVENT_VPP0_VPP_PADDING_IN_PADDING_SOF	265
+#define CMDQ_EVENT_VPP0_MDP_TCC_IN_SOF	266
+#define CMDQ_EVENT_VPP0_MDP_WROT_SOF	267
+
+#define CMDQ_EVENT_VPP0_WARP0_MMSYS_TOP_RELAY_SOF_PRE	269
+#define CMDQ_EVENT_VPP0_WARP1_MMSYS_TOP_RELAY_SOF_PRE	270
+#define CMDQ_EVENT_VPP0_VPP1_MMSYS_TOP_RELAY_SOF	271
+#define CMDQ_EVENT_VPP0_VPP1_IN_MMSYS_TOP_RELAY_SOF_PRE	272
+
+#define CMDQ_EVENT_VPP0_MDP_RDMA_FRAME_DONE	288
+#define CMDQ_EVENT_VPP0_MDP_FG_TILE_DONE	289
+#define CMDQ_EVENT_VPP0_STITCH_FRAME_DONE	290
+#define CMDQ_EVENT_VPP0_MDP_HDR_FRAME_DONE	291
+#define CMDQ_EVENT_VPP0_MDP_AAL_FRAME_DONE	292
+#define CMDQ_EVENT_VPP0_MDP_RSZ_FRAME_DONE	293
+#define CMDQ_EVENT_VPP0_MDP_TDSHP_FRAME_DONE	294
+#define CMDQ_EVENT_VPP0_DISP_COLOR_FRAME_DONE	295
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_FRAME_DONE	296
+#define CMDQ_EVENT_VPP0_VPP_PADDING_IN_PADDING_FRAME_DONE	297
+#define CMDQ_EVENT_VPP0_MDP_TCC_TCC_FRAME_DONE	298
+#define CMDQ_EVENT_VPP0_MDP_WROT_VIDO_WDONE	299
+
+#define CMDQ_EVENT_VPP0_STREAM_DONE_0	320
+#define CMDQ_EVENT_VPP0_STREAM_DONE_1	321
+#define CMDQ_EVENT_VPP0_STREAM_DONE_2	322
+#define CMDQ_EVENT_VPP0_STREAM_DONE_3	323
+#define CMDQ_EVENT_VPP0_STREAM_DONE_4	324
+#define CMDQ_EVENT_VPP0_STREAM_DONE_5	325
+#define CMDQ_EVENT_VPP0_STREAM_DONE_6	326
+#define CMDQ_EVENT_VPP0_STREAM_DONE_7	327
+#define CMDQ_EVENT_VPP0_STREAM_DONE_8	328
+#define CMDQ_EVENT_VPP0_STREAM_DONE_9	329
+#define CMDQ_EVENT_VPP0_STREAM_DONE_10	330
+#define CMDQ_EVENT_VPP0_STREAM_DONE_11	331
+#define CMDQ_EVENT_VPP0_STREAM_DONE_12	332
+#define CMDQ_EVENT_VPP0_STREAM_DONE_13	333
+#define CMDQ_EVENT_VPP0_STREAM_DONE_14	334
+#define CMDQ_EVENT_VPP0_STREAM_DONE_15	335
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_0	336
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_1	337
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_2	338
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_3	339
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_4	340
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_5	341
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_6	342
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_7	343
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_8	344
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_9	345
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_10	346
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_11	347
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_12	348
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_13	349
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_14	350
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_15	351
+#define CMDQ_EVENT_VPP0_MDP_RDMA_SW_RST_DONE	352
+#define CMDQ_EVENT_VPP0_MDP_RDMA_PM_VALID	353
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_FRAME_RESET_DONE_PULSE	354
+#define CMDQ_EVENT_VPP0_MDP_WROT_SW_RST_DONE	355
+
+#define CMDQ_EVENT_VPP1_HDMI_META_SOF		384
+#define CMDQ_EVENT_VPP1_DGI_SOF			385
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_SOF		386
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_TCC_SOF	387
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RDMA_SOF	388
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_SOF	389
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_SOF	390
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_FG_SOF	391
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_FG_SOF	392
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_FG_SOF	393
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_HDR_SOF	394
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_HDR_SOF	395
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_HDR_SOF	396
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_AAL_SOF	397
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_AAL_SOF	398
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_AAL_SOF	399
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RSZ_SOF	400
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RSZ_SOF	401
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RSZ_SOF	402
+#define CMDQ_EVENT_VPP1_SVPP1_TDSHP_SOF		403
+#define CMDQ_EVENT_VPP1_SVPP2_TDSHP_SOF		404
+#define CMDQ_EVENT_VPP1_SVPP3_TDSHP_SOF		405
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_MERGE_SOF	406
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_MERGE_SOF	407
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_COLOR_SOF	408
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_COLOR_SOF	409
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_COLOR_SOF	410
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_OVL_SOF	411
+#define CMDQ_EVENT_VPP1_SVPP1_VPP_PAD_SOF	412
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_PAD_SOF	413
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_PAD_SOF	414
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_SOF	415
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_SOF	416
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_SOF	417
+#define CMDQ_EVENT_VPP1_VPP0_DL_IRLY_SOF	418
+#define CMDQ_EVENT_VPP1_VPP0_DL_ORLY_SOF	419
+#define CMDQ_EVENT_VPP1_VDO0_DL_ORLY_0_SOF	420
+#define CMDQ_EVENT_VPP1_VDO0_DL_ORLY_1_SOF	421
+#define CMDQ_EVENT_VPP1_VDO1_DL_ORLY_0_SOF	422
+#define CMDQ_EVENT_VPP1_VDO1_DL_ORLY_1_SOF	423
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RDMA_FRAME_DONE	424
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_FRAME_DONE	425
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_FRAME_DONE	426
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_FRAME_DONE	427
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_FRAME_DONE	428
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_FRAME_DONE	429
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_OVL_FRAME_DONE	430
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RSZ_FRAME_DONE	431
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RSZ_FRAME_DONE	432
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RSZ_FRAME_DONE	433
+#define CMDQ_EVENT_VPP1_FRAME_DONE_10	434
+#define CMDQ_EVENT_VPP1_FRAME_DONE_11	435
+#define CMDQ_EVENT_VPP1_FRAME_DONE_12	436
+#define CMDQ_EVENT_VPP1_FRAME_DONE_13	437
+#define CMDQ_EVENT_VPP1_FRAME_DONE_14	438
+#define CMDQ_EVENT_VPP1_STREAM_DONE_0	439
+#define CMDQ_EVENT_VPP1_STREAM_DONE_1	440
+#define CMDQ_EVENT_VPP1_STREAM_DONE_2	441
+#define CMDQ_EVENT_VPP1_STREAM_DONE_3	442
+#define CMDQ_EVENT_VPP1_STREAM_DONE_4	443
+#define CMDQ_EVENT_VPP1_STREAM_DONE_5	444
+#define CMDQ_EVENT_VPP1_STREAM_DONE_6	445
+#define CMDQ_EVENT_VPP1_STREAM_DONE_7	446
+#define CMDQ_EVENT_VPP1_STREAM_DONE_8	447
+#define CMDQ_EVENT_VPP1_STREAM_DONE_9	448
+#define CMDQ_EVENT_VPP1_STREAM_DONE_10	449
+#define CMDQ_EVENT_VPP1_STREAM_DONE_11	450
+#define CMDQ_EVENT_VPP1_STREAM_DONE_12	451
+#define CMDQ_EVENT_VPP1_STREAM_DONE_13	452
+#define CMDQ_EVENT_VPP1_STREAM_DONE_14	453
+#define CMDQ_EVENT_VPP1_STREAM_DONE_15	454
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_0	455
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_1	456
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_2	457
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_3	458
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_4	459
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_5	460
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_6	461
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_7	462
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_8	463
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_9	464
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_10	465
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_11	466
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_12	467
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_13	468
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_14	469
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_15	470
+#define CMDQ_EVENT_VPP1_DGI_0	471
+#define CMDQ_EVENT_VPP1_DGI_1	472
+#define CMDQ_EVENT_VPP1_DGI_2	473
+#define CMDQ_EVENT_VPP1_DGI_3	474
+#define CMDQ_EVENT_VPP1_DGI_4	475
+#define CMDQ_EVENT_VPP1_DGI_5	476
+#define CMDQ_EVENT_VPP1_DGI_6	477
+#define CMDQ_EVENT_VPP1_DGI_7	478
+#define CMDQ_EVENT_VPP1_DGI_8	479
+#define CMDQ_EVENT_VPP1_DGI_9	480
+#define CMDQ_EVENT_VPP1_DGI_10	481
+#define CMDQ_EVENT_VPP1_DGI_11	482
+#define CMDQ_EVENT_VPP1_DGI_12	483
+#define CMDQ_EVENT_VPP1_DGI_13	484
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_MERGE	485
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_MERGE	486
+#define CMDQ_EVENT_VPP1_MDP_OVL_FRAME_RESET_DONE_PULSE	487
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_DGI	488
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_HDMI	489
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_SW_RST_DONE	490
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_SW_RST_DONE	491
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_SW_RST_DONE	492
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_FG_TILE_DONE	493
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_FG_TILE_DONE	494
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_FG_TILE_DONE	495
+
+#define CMDQ_EVENT_VDO0_DISP_OVL0_SOF	512
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_SOF	513
+#define CMDQ_EVENT_VDO0_DISP_RDMA0_SOF	514
+#define CMDQ_EVENT_VDO0_DISP_COLOR0_SOF	515
+#define CMDQ_EVENT_VDO0_DISP_CCORR0_SOF	516
+#define CMDQ_EVENT_VDO0_DISP_AAL0_SOF	517
+#define CMDQ_EVENT_VDO0_DISP_GAMMA0_SOF	518
+#define CMDQ_EVENT_VDO0_DISP_DITHER0_SOF	519
+#define CMDQ_EVENT_VDO0_DSI0_SOF	520
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C0_SOF	521
+#define CMDQ_EVENT_VDO0_DISP_OVL1_SOF	522
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_SOF	523
+#define CMDQ_EVENT_VDO0_DISP_RDMA1_SOF	524
+#define CMDQ_EVENT_VDO0_DISP_COLOR1_SOF	525
+#define CMDQ_EVENT_VDO0_DISP_CCORR1_SOF	526
+#define CMDQ_EVENT_VDO0_DISP_AAL1_SOF	527
+#define CMDQ_EVENT_VDO0_DISP_GAMMA1_SOF	528
+#define CMDQ_EVENT_VDO0_DISP_DITHER1_SOF	529
+#define CMDQ_EVENT_VDO0_DSI1_SOF	530
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C1_SOF	531
+#define CMDQ_EVENT_VDO0_VPP_MERGE0_SOF	532
+#define CMDQ_EVENT_VDO0_DP_INTF0_SOF	533
+#define CMDQ_EVENT_VDO0_VPP1_DL_RELAY0_SOF	534
+#define CMDQ_EVENT_VDO0_VPP1_DL_RELAY1_SOF	535
+#define CMDQ_EVENT_VDO0_VDO1_DL_RELAY2_SOF	536
+#define CMDQ_EVENT_VDO0_VDO0_DL_RELAY3_SOF	537
+#define CMDQ_EVENT_VDO0_VDO0_DL_RELAY4_SOF	538
+#define CMDQ_EVENT_VDO0_DISP_PWM0_SOF	539
+#define CMDQ_EVENT_VDO0_DISP_PWM1_SOF	540
+
+#define CMDQ_EVENT_VDO0_DISP_OVL0_FRAME_DONE	544
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_FRAME_DONE	545
+#define CMDQ_EVENT_VDO0_DISP_RDMA0_FRAME_DONE	546
+#define CMDQ_EVENT_VDO0_DISP_COLOR0_FRAME_DONE	547
+#define CMDQ_EVENT_VDO0_DISP_CCORR0_FRAME_DONE	548
+#define CMDQ_EVENT_VDO0_DISP_AAL0_FRAME_DONE	549
+#define CMDQ_EVENT_VDO0_DISP_GAMMA0_FRAME_DONE	550
+#define CMDQ_EVENT_VDO0_DISP_DITHER0_FRAME_DONE	551
+#define CMDQ_EVENT_VDO0_DSI0_FRAME_DONE	552
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C0_FRAME_DONE	553
+#define CMDQ_EVENT_VDO0_DISP_OVL1_FRAME_DONE	554
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_FRAME_DONE	555
+#define CMDQ_EVENT_VDO0_DISP_RDMA1_FRAME_DONE	556
+#define CMDQ_EVENT_VDO0_DISP_COLOR1_FRAME_DONE	557
+#define CMDQ_EVENT_VDO0_DISP_CCORR1_FRAME_DONE	558
+#define CMDQ_EVENT_VDO0_DISP_AAL1_FRAME_DONE	559
+#define CMDQ_EVENT_VDO0_DISP_GAMMA1_FRAME_DONE	560
+#define CMDQ_EVENT_VDO0_DISP_DITHER1_FRAME_DONE	561
+#define CMDQ_EVENT_VDO0_DSI1_FRAME_DONE	562
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C1_FRAME_DONE	563
+
+#define CMDQ_EVENT_VDO0_DP_INTF0_FRAME_DONE	565
+
+#define CMDQ_EVENT_VDO0_DISP_SMIASSERT_ENG	576
+#define CMDQ_EVENT_VDO0_DSI0_IRQ_ENG_EVENT_MM	577
+#define CMDQ_EVENT_VDO0_DSI0_TE_ENG_EVENT_MM	578
+#define CMDQ_EVENT_VDO0_DSI0_DONE_ENG_EVENT_MM	579
+#define CMDQ_EVENT_VDO0_DSI0_SOF_ENG_EVENT_MM	580
+#define CMDQ_EVENT_VDO0_DSI0_VACTL_ENG_EVENT_MM	581
+#define CMDQ_EVENT_VDO0_DSI1_IRQ_ENG_EVENT_MM	582
+#define CMDQ_EVENT_VDO0_DSI1_TE_ENG_EVENT_MM	583
+#define CMDQ_EVENT_VDO0_DSI1_DONE_ENG_EVENT_MM	584
+#define CMDQ_EVENT_VDO0_DSI1_SOF_ENG_EVENT_MM	585
+#define CMDQ_EVENT_VDO0_DSI1_VACTL_ENG_EVENT_MM	586
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_SW_RST_DONE_ENG	587
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_SW_RST_DONE_ENG	588
+#define CMDQ_EVENT_VDO0_DISP_OVL0_RST_DONE_ENG	589
+#define CMDQ_EVENT_VDO0_DISP_OVL1_RST_DONE_ENG	590
+#define CMDQ_EVENT_VDO0_DP_INTF0_VSYNC_START_ENG_EVENT_MM	591
+#define CMDQ_EVENT_VDO0_DP_INTF0_VSYNC_END_ENG_EVENT_MM	592
+#define CMDQ_EVENT_VDO0_DP_INTF0_VDE_START_ENG_EVENT_MM	593
+#define CMDQ_EVENT_VDO0_DP_INTF0_VDE_END_ENG_EVENT_MM	594
+#define CMDQ_EVENT_VDO0_DP_INTF0_TARGET_LINE_ENG_EVENT_MM	595
+#define CMDQ_EVENT_VDO0_VPP_MERGE0_ENG	596
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0	597
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_1	598
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_2	599
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_3	600
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_4	601
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_5	602
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_6	603
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_7	604
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_8	605
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_9	606
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_10	607
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_11	608
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_12	609
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_13	610
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_14	611
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_15	612
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_0	613
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_1	614
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_2	615
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_3	616
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_4	617
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_5	618
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_6	619
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_7	620
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_8	621
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_9	622
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_10	623
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_11	624
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_12	625
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_13	626
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_14	627
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_15	628
+
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_SOF	640
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_SOF	641
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_SOF	642
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_SOF	643
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_SOF	644
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_SOF	645
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_SOF	646
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_SOF	647
+#define CMDQ_EVENT_VDO1_VPP_MERGE0_SOF	648
+#define CMDQ_EVENT_VDO1_VPP_MERGE1_SOF	649
+#define CMDQ_EVENT_VDO1_VPP_MERGE2_SOF	650
+#define CMDQ_EVENT_VDO1_VPP_MERGE3_SOF	651
+#define CMDQ_EVENT_VDO1_VPP_MERGE4_SOF	652
+#define CMDQ_EVENT_VDO1_VPP2_DL_RELAY_SOF	653
+#define CMDQ_EVENT_VDO1_VPP3_DL_RELAY_SOF	654
+#define CMDQ_EVENT_VDO1_VDO0_DSC_DL_ASYNC_SOF	655
+#define CMDQ_EVENT_VDO1_VDO0_MERGE_DL_ASYNC_SOF	656
+#define CMDQ_EVENT_VDO1_OUT_DL_RELAY_SOF	657
+#define CMDQ_EVENT_VDO1_DISP_MIXER_SOF	658
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE0_SOF	659
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_SOF	660
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_SOF	661
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_SOF	662
+#define CMDQ_EVENT_VDO1_HDR_VDO_BE0_SOF	663
+#define CMDQ_EVENT_VDO1_HDR_MLOAD_SOF	664
+
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_FRAME_DONE	672
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_FRAME_DONE	673
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_FRAME_DONE	674
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_FRAME_DONE	675
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_FRAME_DONE	676
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_FRAME_DONE	677
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_FRAME_DONE	678
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_FRAME_DONE	679
+#define CMDQ_EVENT_VDO1_VPP_MERGE0_FRAME_DONE	680
+#define CMDQ_EVENT_VDO1_VPP_MERGE1_FRAME_DONE	681
+#define CMDQ_EVENT_VDO1_VPP_MERGE2_FRAME_DONE	682
+#define CMDQ_EVENT_VDO1_VPP_MERGE3_FRAME_DONE	683
+#define CMDQ_EVENT_VDO1_VPP_MERGE4_FRAME_DONE	684
+#define CMDQ_EVENT_VDO1_DPI0_FRAME_DONE	685
+#define CMDQ_EVENT_VDO1_DPI1_FRAME_DONE	686
+#define CMDQ_EVENT_VDO1_DP_INTF0_FRAME_DONE	687
+#define CMDQ_EVENT_VDO1_DISP_MIXER_FRAME_DONE_MM	688
+
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_0	704
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_1	705
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_2	706
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_3	707
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_4	708
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_5	709
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_6	710
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_7	711
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_8	712
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_9	713
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_10	714
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_11	715
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_12	716
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_13	717
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_14	718
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_15	719
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_0	720
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_1	721
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_2	722
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_3	723
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_4	724
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_5	725
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_6	726
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_7	727
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_8	728
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_9	729
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_10	730
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_11	731
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_12	732
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_13	733
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_14	734
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_15	735
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_SW_RST_DONE	736
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_SW_RST_DONE	737
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_SW_RST_DONE	738
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_SW_RST_DONE	739
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_SW_RST_DONE	740
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_SW_RST_DONE	741
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_SW_RST_DONE	742
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_SW_RST_DONE	743
+
+#define CMDQ_EVENT_VDO1_DP0_VDE_END_ENG_EVENT_MM	745
+#define CMDQ_EVENT_VDO1_DP0_VDE_START_ENG_EVENT_MM	746
+#define CMDQ_EVENT_VDO1_DP0_VSYNC_END_ENG_EVENT_MM	747
+#define CMDQ_EVENT_VDO1_DP0_VSYNC_START_ENG_EVENT_MM	748
+#define CMDQ_EVENT_VDO1_DP0_TARGET_LINE_ENG_EVENT_MM	749
+#define CMDQ_EVENT_VDO1_VPP_MERGE0	750
+#define CMDQ_EVENT_VDO1_VPP_MERGE1	751
+#define CMDQ_EVENT_VDO1_VPP_MERGE2	752
+#define CMDQ_EVENT_VDO1_VPP_MERGE3	753
+#define CMDQ_EVENT_VDO1_VPP_MERGE4	754
+#define CMDQ_EVENT_VDO1_HDMITX	755
+#define CMDQ_EVENT_VDO1_HDR_VDO_BE0_ADL_TRIG_EVENT_MM	756
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_THDR_ADL_TRIG_EVENT_MM	757
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_DM_ADL_TRIG_EVENT_MM	758
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_THDR_ADL_TRIG_EVENT_MM	759
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_DM_ADL_TRIG_EVENT_MM	760
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_ADL_TRIG_EVENT_MM	761
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_AD0_TRIG_EVENT_MM	762
+
+#define CMDQ_EVENT_CAM_A_PASS1_DONE	769
+#define CMDQ_EVENT_CAM_B_PASS1_DONE	770
+#define CMDQ_EVENT_GCAMSV_A_PASS1_DONE	771
+#define CMDQ_EVENT_GCAMSV_B_PASS1_DONE	772
+#define CMDQ_EVENT_MRAW_0_PASS1_DONE	773
+#define CMDQ_EVENT_MRAW_1_PASS1_DONE	774
+#define CMDQ_EVENT_MRAW_2_PASS1_DONE	775
+#define CMDQ_EVENT_MRAW_3_PASS1_DONE	776
+#define CMDQ_EVENT_SENINF_CAM0_FIFO_FULL_X	777
+#define CMDQ_EVENT_SENINF_CAM1_FIFO_FULL_X	778
+#define CMDQ_EVENT_SENINF_CAM2_FIFO_FULL	779
+#define CMDQ_EVENT_SENINF_CAM3_FIFO_FULL	780
+#define CMDQ_EVENT_SENINF_CAM4_FIFO_FULL	781
+#define CMDQ_EVENT_SENINF_CAM5_FIFO_FULL	782
+#define CMDQ_EVENT_SENINF_CAM6_FIFO_FULL	783
+#define CMDQ_EVENT_SENINF_CAM7_FIFO_FULL	784
+#define CMDQ_EVENT_SENINF_CAM8_FIFO_FULL	785
+#define CMDQ_EVENT_SENINF_CAM9_FIFO_FULL	786
+#define CMDQ_EVENT_SENINF_CAM10_FIFO_FULL_X	787
+#define CMDQ_EVENT_SENINF_CAM11_FIFO_FULL_X	788
+#define CMDQ_EVENT_SENINF_CAM12_FIFO_FULL_X	789
+#define CMDQ_EVENT_SENINF_CAM13_FIFO_FULL_X	790
+#define CMDQ_EVENT_TG_OVRUN_MRAW0_INT_X0	791
+#define CMDQ_EVENT_TG_OVRUN_MRAW1_INT_X0	792
+#define CMDQ_EVENT_TG_OVRUN_MRAW2_INT	793
+#define CMDQ_EVENT_TG_OVRUN_MRAW3_INT	794
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW0_INT	795
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW1_INT	796
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW2_INT	797
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW3_INT	798
+#define CMDQ_EVENT_U_CAMSYS_PDA_IRQO_EVENT_DONE_D1	799
+#define CMDQ_EVENT_SUBB_TG_INT4	800
+#define CMDQ_EVENT_SUBB_TG_INT3	801
+#define CMDQ_EVENT_SUBB_TG_INT2	802
+#define CMDQ_EVENT_SUBB_TG_INT1	803
+#define CMDQ_EVENT_SUBA_TG_INT4	804
+#define CMDQ_EVENT_SUBA_TG_INT3	805
+#define CMDQ_EVENT_SUBA_TG_INT2	806
+#define CMDQ_EVENT_SUBA_TG_INT1	807
+#define CMDQ_EVENT_SUBB_DRZS4NO_R1_LOW_LATENCY_LINE_CNT_INT	808
+#define CMDQ_EVENT_SUBB_YUVO_R3_LOW_LATENCY_LINE_CNT_INT	809
+#define CMDQ_EVENT_SUBB_YUVO_R1_LOW_LATENCY_LINE_CNT_INT	810
+#define CMDQ_EVENT_SUBB_IMGO_R1_LOW_LATENCY_LINE_CNT_INT	811
+#define CMDQ_EVENT_SUBA_DRZS4NO_R1_LOW_LATENCY_LINE_CNT_INT	812
+#define CMDQ_EVENT_SUBA_YUVO_R3_LOW_LATENCY_LINE_CNT_INT	813
+#define CMDQ_EVENT_SUBA_YUVO_R1_LOW_LATENCY_LINE_CNT_INT	814
+#define CMDQ_EVENT_SUBA_IMGO_R1_LOW_LATENCY_LINE_CNT_INT	815
+#define CMDQ_EVENT_GCE1_SOF_0	816
+#define CMDQ_EVENT_GCE1_SOF_1	817
+#define CMDQ_EVENT_GCE1_SOF_2	818
+#define CMDQ_EVENT_GCE1_SOF_3	819
+#define CMDQ_EVENT_GCE1_SOF_4	820
+#define CMDQ_EVENT_GCE1_SOF_5	821
+#define CMDQ_EVENT_GCE1_SOF_6	822
+#define CMDQ_EVENT_GCE1_SOF_7	823
+#define CMDQ_EVENT_GCE1_SOF_8	824
+#define CMDQ_EVENT_GCE1_SOF_9	825
+#define CMDQ_EVENT_GCE1_SOF_10	826
+#define CMDQ_EVENT_GCE1_SOF_11	827
+#define CMDQ_EVENT_GCE1_SOF_12	828
+#define CMDQ_EVENT_GCE1_SOF_13	829
+#define CMDQ_EVENT_GCE1_SOF_14	830
+#define CMDQ_EVENT_GCE1_SOF_15	831
+
+#define CMDQ_EVENT_VDEC_LAT_LINE_COUNT_THRESHOLD_INTERRUPT	832
+#define CMDQ_EVENT_VDEC_LAT_VDEC_INT	833
+#define CMDQ_EVENT_VDEC_LAT_VDEC_PAUSE	834
+#define CMDQ_EVENT_VDEC_LAT_VDEC_DEC_ERROR	835
+#define CMDQ_EVENT_VDEC_LAT_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	836
+#define CMDQ_EVENT_VDEC_LAT_VDEC_FRAME_DONE	837
+#define CMDQ_EVENT_VDEC_LAT_INI_FETCH_RDY	838
+#define CMDQ_EVENT_VDEC_LAT_PROCESS_FLAG	839
+#define CMDQ_EVENT_VDEC_LAT_SEARCH_START_CODE_DONE	840
+#define CMDQ_EVENT_VDEC_LAT_REF_REORDER_DONE	841
+#define CMDQ_EVENT_VDEC_LAT_WP_TBLE_DONE	842
+#define CMDQ_EVENT_VDEC_LAT_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	843
+#define CMDQ_EVENT_VDEC_LAT_GCE_CNT_OP_THRESHOLD	847
+
+#define CMDQ_EVENT_VDEC_LAT1_LINE_COUNT_THRESHOLD_INTERRUPT	848
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_INT	849
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_PAUSE	850
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_DEC_ERROR	851
+#define CMDQ_EVENT_VDEC_LAT1_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	852
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_FRAME_DONE	853
+#define CMDQ_EVENT_VDEC_LAT1_INI_FETCH_RDY	854
+#define CMDQ_EVENT_VDEC_LAT1_PROCESS_FLAG	855
+#define CMDQ_EVENT_VDEC_LAT1_SEARCH_START_CODE_DONE	856
+#define CMDQ_EVENT_VDEC_LAT1_REF_REORDER_DONE	857
+#define CMDQ_EVENT_VDEC_LAT1_WP_TBLE_DONE	858
+#define CMDQ_EVENT_VDEC_LAT1_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	859
+#define CMDQ_EVENT_VDEC_LAT1_GCE_CNT_OP_THRESHOLD	863
+
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_0	864
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_1	865
+
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_8	872
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_9	873
+
+#define CMDQ_EVENT_VDEC_CORE_LINE_COUNT_THRESHOLD_INTERRUPT	896
+#define CMDQ_EVENT_VDEC_CORE_VDEC_INT	897
+#define CMDQ_EVENT_VDEC_CORE_VDEC_PAUSE	898
+#define CMDQ_EVENT_VDEC_CORE_VDEC_DEC_ERROR	899
+#define CMDQ_EVENT_VDEC_CORE_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	900
+#define CMDQ_EVENT_VDEC_CORE_VDEC_FRAME_DONE	901
+#define CMDQ_EVENT_VDEC_CORE_INI_FETCH_RDY	902
+#define CMDQ_EVENT_VDEC_CORE_PROCESS_FLAG	903
+#define CMDQ_EVENT_VDEC_CORE_SEARCH_START_CODE_DONE	904
+#define CMDQ_EVENT_VDEC_CORE_REF_REORDER_DONE	905
+#define CMDQ_EVENT_VDEC_CORE_WP_TBLE_DONE	906
+#define CMDQ_EVENT_VDEC_CORE_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	907
+#define CMDQ_EVENT_VDEC_CORE_GCE_CNT_OP_THRESHOLD	911
+
+#define CMDQ_EVENT_VDEC_CORE1_LINE_COUNT_THRESHOLD_INTERRUPT	912
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_INT	913
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_PAUSE	914
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_DEC_ERROR	915
+#define CMDQ_EVENT_VDEC_CORE1_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	916
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_FRAME_DONE	917
+#define CMDQ_EVENT_VDEC_CORE1_INI_FETCH_RDY	918
+#define CMDQ_EVENT_VDEC_CORE1_PROCESS_FLAG	919
+#define CMDQ_EVENT_VDEC_CORE1_SEARCH_START_CODE_DONE	920
+#define CMDQ_EVENT_VDEC_CORE1_REF_REORDER_DONE	921
+#define CMDQ_EVENT_VDEC_CORE1_WP_TBLE_DONE	922
+#define CMDQ_EVENT_VDEC_CORE1_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	923
+#define CMDQ_EVENT_VDEC_CORE1_CNT_OP_THRESHOLD	927
+
+#define CMDQ_EVENT_VENC_TOP_FRAME_DONE	929
+#define CMDQ_EVENT_VENC_TOP_PAUSE_DONE	930
+#define CMDQ_EVENT_VENC_TOP_JPGENC_DONE	931
+#define CMDQ_EVENT_VENC_TOP_MB_DONE	932
+#define CMDQ_EVENT_VENC_TOP_128BYTE_DONE	933
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_DONE	934
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_C1_DONE	935
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_INSUFF_DONE	936
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_C1_INSUFF_DONE	937
+#define CMDQ_EVENT_VENC_TOP_WP_2ND_STAGE_DONE	938
+#define CMDQ_EVENT_VENC_TOP_WP_3RD_STAGE_DONE	939
+#define CMDQ_EVENT_VENC_TOP_PPS_HEADER_DONE	940
+#define CMDQ_EVENT_VENC_TOP_SPS_HEADER_DONE	941
+#define CMDQ_EVENT_VENC_TOP_VPS_HEADER_DONE	942
+
+#define CMDQ_EVENT_VENC_CORE1_TOP_FRAME_DONE	945
+#define CMDQ_EVENT_VENC_CORE1_TOP_PAUSE_DONE	946
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGENC_DONE	947
+#define CMDQ_EVENT_VENC_CORE1_TOP_MB_DONE	948
+#define CMDQ_EVENT_VENC_CORE1_TOP_128BYTE_DONE	949
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_DONE	950
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_C1_DONE	951
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_INSUFF_DONE	952
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_C1_INSUFF_DONE	953
+#define CMDQ_EVENT_VENC_CORE1_TOP_WP_2ND_STAGE_DONE	954
+#define CMDQ_EVENT_VENC_CORE1_TOP_WP_3RD_STAGE_DONE	955
+#define CMDQ_EVENT_VENC_CORE1_TOP_PPS_HEADER_DONE	956
+#define CMDQ_EVENT_VENC_CORE1_TOP_SPS_HEADER_DONE	957
+#define CMDQ_EVENT_VENC_CORE1_TOP_VPS_HEADER_DONE	958
+
+#define CMDQ_EVENT_WPE_VPP0_WPE_GCE_FRAME_DONE	962
+#define CMDQ_EVENT_WPE_VPP0_WPE_DONE_SYNC_OUT	963
+
+#define CMDQ_EVENT_WPE_VPP1_WPE_GCE_FRAME_DONE	969
+#define CMDQ_EVENT_WPE_VPP1_WPE_DONE_SYNC_OUT	970
+
+#define CMDQ_EVENT_DP_TX_VBLANK_FALLING	994
+#define CMDQ_EVENT_DP_TX_VSC_FINISH	995
+
+#define CMDQ_EVENT_OUTPIN_0	1018
+#define CMDQ_EVENT_OUTPIN_1	1019
+
+#endif
-- 
2.18.0

From elver at google.com  Wed Aug 25 02:54:12 2021
From: elver at google.com (Marco Elver)
Date: Wed, 25 Aug 2021 11:54:12 +0200
Subject: [PATCH 4/4] mm: kfence: Only load kfence_test when kfence is
 enabled
In-Reply-To: <CAG_fn=X9oaw0zJrcmShNcvd3UsNSFKsH3kSdD5Yx=4Sk_WtNrQ@mail.gmail.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <20210825092116.149975-5-wangkefeng.wang@huawei.com>
 <CAG_fn=X9oaw0zJrcmShNcvd3UsNSFKsH3kSdD5Yx=4Sk_WtNrQ@mail.gmail.com>
Message-ID: <CANpmjNN4=ckdTcSKJNurmW3BNyU-V4QTJbR0cm4s-whW3ykRHw@mail.gmail.com>

On Wed, 25 Aug 2021 at 11:31, Alexander Potapenko <glider at google.com> wrote:
> On Wed, Aug 25, 2021 at 11:17 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> >
> > Provide kfence_is_enabled() helper, only load kfence_test module
> > when kfence is enabled.
>
> What's wrong with the current behavior?
> I think we need at least some way to tell the developer that KFENCE
> does not work, and a failing test seems to be the perfect one.

Like Alex said, this is working as intended. The KFENCE test verifies
that everything is working as expected, *including* that KFENCE was
enabled, and has already helped us identify issues where we expected
it to be enabled! Trying to run the test when KFENCE was intentionally
disabled is therefore not a useful usecase.

Please drop this patch.


From wangkefeng.wang at huawei.com  Wed Aug 25 02:55:01 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 17:55:01 +0800
Subject: [PATCH 4/4] mm: kfence: Only load kfence_test when kfence is
 enabled
In-Reply-To: <CAG_fn=X9oaw0zJrcmShNcvd3UsNSFKsH3kSdD5Yx=4Sk_WtNrQ@mail.gmail.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <20210825092116.149975-5-wangkefeng.wang@huawei.com>
 <CAG_fn=X9oaw0zJrcmShNcvd3UsNSFKsH3kSdD5Yx=4Sk_WtNrQ@mail.gmail.com>
Message-ID: <99daf260-76af-8316-fa9a-a649c8a8d1ab@huawei.com>


On 2021/8/25 17:31, Alexander Potapenko wrote:
> On Wed, Aug 25, 2021 at 11:17 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>> Provide kfence_is_enabled() helper, only load kfence_test module
>> when kfence is enabled.
> What's wrong with the current behavior?
> I think we need at least some way to tell the developer that KFENCE
> does not work, and a failing test seems to be the perfect one.

If the kfence is not enabled, eg kfence.sample_interval=0, kfence_test 
spend too much time,

and all tests will fails. It is meaningless. so better to just skip it ;)

>> diff --git a/mm/kfence/kfence_test.c b/mm/kfence/kfence_test.c
>> index eb6307c199ea..4087f9f1497e 100644
>> --- a/mm/kfence/kfence_test.c
>> +++ b/mm/kfence/kfence_test.c
>> @@ -847,6 +847,8 @@ static void unregister_tracepoints(struct tracepoint *tp, void *ignore)
>>    */
>>   static int __init kfence_test_init(void)
>>   {
>> +       if (!kfence_is_enabled())

Add a print info here?

>> +               return 0;
>>          /*
>>           * Because we want to be able to build the test as a module, we need to
>>           * iterate through all known tracepoints, since the static registration
>> --
>> 2.26.2
>>
>> --
>> You received this message because you are subscribed to the Google Groups "kasan-dev" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to kasan-dev+unsubscribe at googlegroups.com.
>> To view this discussion on the web visit https://groups.google.com/d/msgid/kasan-dev/20210825092116.149975-5-wangkefeng.wang%40huawei.com.
>
>


From elver at google.com  Wed Aug 25 02:59:04 2021
From: elver at google.com (Marco Elver)
Date: Wed, 25 Aug 2021 11:59:04 +0200
Subject: [PATCH 4/4] mm: kfence: Only load kfence_test when kfence is
 enabled
In-Reply-To: <99daf260-76af-8316-fa9a-a649c8a8d1ab@huawei.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <20210825092116.149975-5-wangkefeng.wang@huawei.com>
 <CAG_fn=X9oaw0zJrcmShNcvd3UsNSFKsH3kSdD5Yx=4Sk_WtNrQ@mail.gmail.com>
 <99daf260-76af-8316-fa9a-a649c8a8d1ab@huawei.com>
Message-ID: <CANpmjNMZ-kNVkCRWDfgEjrR4BT1B0gVNnvao_w3nEM9pA3Epbw@mail.gmail.com>

On Wed, 25 Aug 2021 at 11:55, Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> On 2021/8/25 17:31, Alexander Potapenko wrote:
> > On Wed, Aug 25, 2021 at 11:17 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> >> Provide kfence_is_enabled() helper, only load kfence_test module
> >> when kfence is enabled.
> > What's wrong with the current behavior?
> > I think we need at least some way to tell the developer that KFENCE
> > does not work, and a failing test seems to be the perfect one.
>
> If the kfence is not enabled, eg kfence.sample_interval=0, kfence_test
> spend too much time,
>
> and all tests will fails. It is meaningless. so better to just skip it ;)

But what is your usecase?

I'd like to avoid the export of a new function that is pretty much unused.


From knaerzche at gmail.com  Wed Aug 25 03:00:51 2021
From: knaerzche at gmail.com (Alex Bee)
Date: Wed, 25 Aug 2021 12:00:51 +0200
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <YSXJZBKeka5U7VN+@kernel.org>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <b37fc109-06d3-0c86-a3c8-e5d7f21f296b@gmail.com>
 <YSXJZBKeka5U7VN+@kernel.org>
Message-ID: <3bc0c465-475d-78e8-b742-ef093ebaf47c@gmail.com>


Am 25.08.21 um 06:39 schrieb Mike Rapoport:
> On Tue, Aug 24, 2021 at 10:14:01PM +0200, Alex Bee wrote:
>> Hi Mike,
>>
>> thanks for your reply
>>
>> Am 24.08.21 um 20:28 schrieb Mike Rapoport:
>>> On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
>>>> Hi Alex,
>>>>
>>>> Thanks for the report.
>>>>
>>>> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>>>>> it seems there is a regression in arm64 memory mapping in 5.14, since it
>>>>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>>>>
>>>>> [??? 8.921909] ------------[ cut here ]------------
>>>>> [??? 8.921940] WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>>>>> [??? 8.921973] Modules linked in: spi_rockchip(+) fuse
>>>>> [??? 8.921996] CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>>>>> [??? 8.922004] Hardware name: Pine64 Rock64 (DT)
>>>>> [??? 8.922011] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>>>>> [??? 8.922018] pc : dma_map_resource+0x68/0xc0
>>>>> [??? 8.922026] lr : pl330_prep_slave_fifo+0x78/0xd0
>>>>> [??? 8.922040] sp : ffff800012102ae0
>>>>> [??? 8.922043] x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>>>>> [??? 8.922056] x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>>>>> [??? 8.922067] x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>>>>> [??? 8.922078] x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>>>>> [??? 8.922089] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>>>>> [??? 8.922100] x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>>>>> [??? 8.922111] x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>>>>> [??? 8.922123] x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>>>>> [??? 8.922134] x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>>>>> [??? 8.922145] x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>>>>> [??? 8.922158] Call trace:
>>>>> [??? 8.922163]? dma_map_resource+0x68/0xc0
>>>>> [??? 8.922173]? pl330_prep_slave_sg+0x58/0x220
>>>>> [??? 8.922181]? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>>>>> [??? 8.922208]? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
>>>> [...]
>>>>> Note: This does not relate to the spi driver - when disabling this device in
>>>>> the device tree it fails for any other (i2s, for instance) which uses dma.
>>>>> Commenting out the failing check at [1], however, helps and the mapping
>>>>> works again.
>>>> Do you know which address dma_map_resource() is trying to map (maybe
>>>> add some printk())? It's not supposed to map RAM, hence the warning.
>>>> Random guess, the address is 0xff190800 (based on the x1 above but the
>>>> regs might as well be mangled).
>>> 0xff190800 will cause this warning for sure. It has a memory map, but it is
>>> not RAM so old version of pfn_valid() would return 0 and the new one
>>> returns 1.
>>>>> I tried to follow the recent changes for arm64 mm which could relate to the
>>>>> check failing at [1] and reverting
>>>>>   ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")
>>>>> helps and makes it work again, but I'm 100% uncertain if that commit is
>>>>> really the culprit.
>>>>>
>>>>> Note, that the firmware (legacy u-boot) injects memory configuration in the
>>>>> device tree as follows:
>>>>>
>>>>> /memreserve/??? 0x00000000fcefc000 0x000000000000d000;
>>>>> / {
>>>>> ..
>>>>>   ??? compatible = "pine64,rock64\0rockchip,rk3328";
>>>>> ..
>>>>>   ??? memory {
>>>>>   ??? ??? reg = <0x00 0x200000 0x00 0xfee00000 0x00 0x00 0x00 0x00>;
>>>>>   ??? ??? device_type = "memory";
>>>>>   ??? };
>>>>>
>>>>> ..
>>>>> }
>>>> Either pfn_valid() gets confused in 5.14 or something is wrong with the
>>>> DT. I have a suspicion it's the former since reverting the above commit
>>>> makes it disappear.
>>> I think pfn_valid() actually behaves as expected but the caller is wrong
>>> because pfn_valid != RAM (this applies btw to !arm64 as well).
>>>
>>> 	/* Don't allow RAM to be mapped */
>>> 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
>>> 		return DMA_MAPPING_ERROR;
>>>
>>> Alex, can you please try this patch:
>>>
>>> diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
>>> index 2b06a809d0b9..4715e9641a29 100644
>>> --- a/kernel/dma/mapping.c
>>> +++ b/kernel/dma/mapping.c
>>> @@ -232,7 +232,7 @@ dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr,
>>>    		return DMA_MAPPING_ERROR;
>>>    	/* Don't allow RAM to be mapped */
>>> -	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
>>> +	if (WARN_ON_ONCE(!memblock_is_memory(phys_addr)))
>>>    		return DMA_MAPPING_ERROR;
>>>    	if (dma_map_direct(dev, ops))
>> Nope, doesn't help:
>>
>> [??? 8.353879] dma_map_resource Failed to map address 0xff190800
>> [??? 8.353886] dma_map_resource pfn_valid(PHYS_PFN(0xff190800)): 1
>> [??? 8.353892] dma_map_resource memblock_is_memory(0xff190800): 0
>>
>> If understand the comment for that check correct, that we _don't_ want RAM
>> to be mapped - shoudn't that be:
>>
>> +	if (WARN_ON_ONCE(memblock_is_memory(phys_addr)))
>>
>> ?
> Right, we don't want RAM to be mapped, the negation was wrong and it should
> be
>
> 	if (WARN_ON_ONCE(memblock_is_memory(phys_addr)))
>   

OK, great: that helps with no other complaints - at least on this 
(arm64) SoC.

Since this affects all other archs, I doubt this will be in 5.14 - but 
it would be great if there could be fix for that in 5.14 since at system 
breaking bug. I'm not sure why it wasn't reported yet - is there any 
chance that at least

 ? commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID")

can be reverted in 5.14?

Alex



From wenst at chromium.org  Wed Aug 25 03:01:51 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 18:01:51 +0800
Subject: [v4 5/5] soc: mediatek: pm-domains: Add support for mt8195
In-Reply-To: <20210823092353.3502-6-chun-jie.chen@mediatek.com>
References: <20210823092353.3502-1-chun-jie.chen@mediatek.com>
 <20210823092353.3502-6-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5GxzgHGo87xWbENSA=g+vRLJFbMGTw0u5bAyEc0qLT64Q@mail.gmail.com>

On Mon, Aug 23, 2021 at 5:26 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add domain control data including bus protection data size
> change due to more protection steps in mt8195.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From oupton at google.com  Wed Aug 25 03:02:28 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 25 Aug 2021 03:02:28 -0700
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <87mtp5q3gx.wl-maz@kernel.org>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
Message-ID: <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>

On Wed, Aug 25, 2021 at 2:27 AM Marc Zyngier <maz at kernel.org> wrote:
> > Exposing new hypercalls to guests in this manner seems very unsafe to
> > me. Suppose an operator is trying to upgrade from kernel N to kernel
> > N+1, which brings in the new 'widget' hypercall. Guests are live
> > migrated onto the N+1 kernel, but the operator finds a defect that
> > warrants a kernel rollback. VMs are then migrated from kernel N+1 -> N.
> > Any guests that discovered the 'widget' hypercall are likely going to
> > get fussy _very_ quickly on the old kernel.
>
> This goes against what we decided to support for the *only* publicly
> available VMM that cares about save/restore, which is that we only
> move forward and don't rollback.

Ah, I was definitely missing this context. Current behavior makes much
more sense then.

> Hypercalls are the least of your
> worries, and there is a whole range of other architectural features
> that will have also appeared/disappeared (your own CNTPOFF series is a
> glaring example of this).

Isn't that a tad bit different though? I'll admit, I'm just as guilty
with my own series forgetting to add a KVM_CAP (oops), but it is in my
queue to kick out with the fix for nVHE/ptimer. Nonetheless, if a user
takes up a new KVM UAPI, it is up to the user to run on a new kernel.

My concerns are explicitly with the 'under the nose' changes, where
KVM modifies the guest feature set without userspace opting in. Based
on your comment, though, it would appear that other parts of KVM are
affected too. It doesn't have to be rollback safety, either. There may
simply be a hypercall which an operator doesn't want to give its
guests, and it needs a way to tell KVM to hide it.

> > Have I missed something blatantly obvious, or do others see this as an
> > issue as well? I'll reply with an example of adding opt-out for PTP.
> > I'm sure other hypercalls could be handled similarly.
>
> Why do we need this? For future hypercalls, we could have some buy-in
> capabilities. For existing ones, it is too late, and negative features
> are just too horrible.

Oh, agreed on the nastiness. Lazy hack to realize the intended
functional change..

> For KVM-specific hypercalls, we could get the VMM to save/restore the
> bitmap of supported functions. That would be "less horrible". This
> could be implemented using extra "firmware pseudo-registers" such as
> the ones described in Documentation/virt/kvm/arm/psci.rst.

This seems more reasonable, especially since we do this for migrating
the guest's PSCI version.

Alternatively, I had thought about using a VM attribute, given the
fact that it is non-architectural information and we avoid ABI issues
in KVM_GET_REG_LIST without buy-in through a KVM_CAP.

> Thanks,
>
>         M.
>
> --
> Without deviation from the norm, progress is not possible.


From will at kernel.org  Wed Aug 25 03:05:01 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 25 Aug 2021 11:05:01 +0100
Subject: [PATCH linux-next] arm64: PCI: Introduce pcibios_free_irq()
 helper function
In-Reply-To: <20210825071612.21543-1-yajun.deng@linux.dev>
References: <20210825071612.21543-1-yajun.deng@linux.dev>
Message-ID: <20210825100500.GC24546@willie-the-truck>

[+Lorenzo]

On Wed, Aug 25, 2021 at 03:16:12PM +0800, Yajun Deng wrote:
> Introduce pcibios_free_irq() to free irq in pci_device_probe() and
> pci_device_remove() that in drivers/pci/pci-driver.c.

Please can you describe the problem you're solving?

> Signed-off-by: Yajun Deng <yajun.deng at linux.dev>
> ---
>  arch/arm64/kernel/pci.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> index 1006ed2d7c60..40da5aff4548 100644
> --- a/arch/arm64/kernel/pci.c
> +++ b/arch/arm64/kernel/pci.c
> @@ -25,10 +25,18 @@
>  int pcibios_alloc_irq(struct pci_dev *dev)
>  {
>  	if (!acpi_disabled)
> -		acpi_pci_irq_enable(dev);
> +		return acpi_pci_irq_enable(dev);

This means we'll now fail device probe if we can't enable the GSI. Is that a
problem?

Will


From nancy.lin at mediatek.com  Wed Aug 25 03:05:28 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:28 +0800
Subject: [PATCH v4 14/17] drm/mediatek: add ETHDR support for MT8195
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-15-nancy.lin@mediatek.com>

ETHDR is a part of ovl_adaptor.
ETHDR is designed for HDR video and graphics conversion in the external
display path. It handles multiple HDR input types and performs tone
mapping, color space/color format conversion, and then combine
different layers, output the required HDR or SDR signal to the
subsequent display path.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile    |   1 +
 drivers/gpu/drm/mediatek/mtk_ethdr.c | 424 +++++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_ethdr.h |  25 ++
 3 files changed, 450 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 6e604a933ed0..fb158a1e7f06 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -14,6 +14,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_drm_plane.o \
 		  mtk_dsi.o \
 		  mtk_dpi.o \
+		  mtk_ethdr.o \
 		  mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
new file mode 100644
index 000000000000..c93c881c5a36
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_ethdr.h"
+
+#define MIX_INTEN		0x4
+	#define MIX_FME_CPL_INTEN	BIT(1)
+#define MIX_INTSTA		0x8
+#define MIX_EN			0xc
+#define MIX_RST			0x14
+#define MIX_ROI_SIZE		0x18
+#define MIX_DATAPATH_CON	0x1c
+	#define OUTPUT_NO_RND	BIT(3)
+	#define SOURCE_RGB_SEL	BIT(7)
+	#define BACKGROUND_RELAY	(4 << 9)
+#define MIX_ROI_BGCLR		0x20
+	#define BGCLR_BLACK	0xff000000
+#define MIX_SRC_CON		0x24
+	#define MIX_SRC_L0_EN	BIT(0)
+#define MIX_L_SRC_CON(n)	(0x28 + 0x18 * (n))
+	#define NON_PREMULTI_SOURCE (2 << 12)
+#define MIX_L_SRC_SIZE(n)	(0x30 + 0x18 * (n))
+#define MIX_L_SRC_OFFSET(n)	(0x34 + 0x18 * (n))
+#define MIX_FUNC_DCM0		0x120
+#define MIX_FUNC_DCM1		0x124
+	#define MIX_FUNC_DCM_ENABLE 0xffffffff
+
+#define HDR_VDO_FE_0804_HDR_DM_FE	0x804
+	#define HDR_VDO_FE_0804_BYPASS_ALL	0xfd
+#define HDR_GFX_FE_0204_GFX_HDR_FE	0x204
+	#define HDR_GFX_FE_0204_BYPASS_ALL	0xfd
+#define HDR_VDO_BE_0204_VDO_DM_BE	0x204
+	#define HDR_VDO_BE_0204_BYPASS_ALL	0x7e
+
+#define MIXER_INx_MODE_BYPASS 0
+#define MIXER_INx_MODE_EVEN_EXTEND 1
+#define MIXER_INx_MODE_ODD_EXTEND 2
+#define DEFAULT_9BIT_ALPHA	0x100
+#define	MIXER_ALPHA_AEN		BIT(8)
+#define	MIXER_ALPHA		0xff
+#define ETHDR_CLK_NUM		13
+
+enum mtk_ethdr_comp_id {
+	ETHDR_MIXER,
+	ETHDR_VDO_FE0,
+	ETHDR_VDO_FE1,
+	ETHDR_GFX_FE0,
+	ETHDR_GFX_FE1,
+	ETHDR_VDO_BE,
+	ETHDR_ADL_DS,
+	ETHDR_ID_MAX
+};
+
+struct mtk_ethdr_comp {
+	struct device *dev;
+	void __iomem *regs;
+	struct cmdq_client_reg cmdq_base;
+};
+
+struct mtk_ethdr {
+	struct mtk_ethdr_comp ethdr_comp[ETHDR_ID_MAX];
+	struct clk_bulk_data ethdr_clk[ETHDR_CLK_NUM];
+	struct device *ovl_adaptor_dev;
+	struct device *mmsys_dev;
+	spinlock_t lock; /* protects vblank_cb and vblank_cb_data */
+	void (*vblank_cb)(void *data);
+	void *vblank_cb_data;
+	int irq;
+};
+
+static const char * const ethdr_comp_str[] = {
+	"ETHDR_MIXER",
+	"ETHDR_VDO_FE0",
+	"ETHDR_VDO_FE1",
+	"ETHDR_GFX_FE0",
+	"ETHDR_GFX_FE1",
+	"ETHDR_VDO_BE",
+	"ETHDR_ADL_DS",
+	"ETHDR_ID_MAX"
+};
+
+static const char * const ethdr_clk_str[] = {
+	"ethdr_top",
+	"mixer",
+	"vdo_fe0",
+	"vdo_fe1",
+	"gfx_fe0",
+	"gfx_fe1",
+	"vdo_be",
+	"adl_ds",
+	"vdo_fe0_async",
+	"vdo_fe1_async",
+	"gfx_fe0_async",
+	"gfx_fe1_async",
+	"vdo_be_async",
+};
+
+void mtk_ethdr_enable_vblank(struct device *dev,
+			     void (*vblank_cb)(void *),
+			     void *vblank_cb_data)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->vblank_cb = vblank_cb;
+	priv->vblank_cb_data = vblank_cb_data;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	writel(MIX_FME_CPL_INTEN, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
+}
+
+void mtk_ethdr_disable_vblank(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->vblank_cb = NULL;
+	priv->vblank_cb_data = NULL;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
+}
+
+static irqreturn_t mtk_ethdr_irq_handler(int irq, void *dev_id)
+{
+	struct mtk_ethdr *priv = dev_id;
+	unsigned long flags;
+
+	writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTSTA);
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (!priv->vblank_cb) {
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return IRQ_NONE;
+	}
+
+	priv->vblank_cb(priv->vblank_cb_data);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
+			    struct mtk_plane_state *state,
+			    struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+	struct mtk_plane_pending_state *pending = &state->pending;
+	unsigned int offset = (pending->y << 16) | pending->x;
+	unsigned int mixer_pad_mode = MIXER_INx_MODE_BYPASS;
+	unsigned int alpha_con = 0;
+	unsigned int fmt = 0;
+	bool x_offset_odd = false;
+
+	dev_dbg(dev, "%s+ idx:%d", __func__, idx);
+
+	if (idx >= 4)
+		return;
+
+	if (!pending->enable) {
+		mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_MODE,
+				     idx + 1, MIXER_INx_MODE_BYPASS, cmdq_pkt);
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+				     idx + 1, 0, cmdq_pkt);
+		return;
+	}
+
+	if (pending->x % 2) {
+		x_offset_odd = true;
+		mixer_pad_mode = MIXER_INx_MODE_EVEN_EXTEND;
+	}
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_MODE,
+			     idx + 1, mixer_pad_mode, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+			     idx + 1, pending->width / 2 - 1, cmdq_pkt);
+
+	if (state->base.fb && state->base.fb->format->has_alpha) {
+		alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_ALPHA_SEL,
+				     idx + 1, 0, cmdq_pkt);
+	} else {
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_ALPHA_SEL,
+				     idx + 1, 1, cmdq_pkt);
+	}
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, idx + 1,
+			     DEFAULT_9BIT_ALPHA, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, idx + 1,
+			     DEFAULT_9BIT_ALPHA, cmdq_pkt);
+
+	mtk_ddp_write(cmdq_pkt, (pending->height << 16) | pending->width, &mixer->cmdq_base,
+		      mixer->regs, MIX_L_SRC_SIZE(idx));
+	mtk_ddp_write(cmdq_pkt, (x_offset_odd << 31) | offset, &mixer->cmdq_base,
+		      mixer->regs, MIX_L_SRC_OFFSET(idx));
+	mtk_ddp_write_mask(cmdq_pkt, alpha_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx),
+			   0x1ff);
+	mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs, MIX_SRC_CON,
+			   BIT(idx));
+}
+
+void mtk_ethdr_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *vdo_fe0 = &priv->ethdr_comp[ETHDR_VDO_FE0];
+	struct mtk_ethdr_comp *vdo_fe1 = &priv->ethdr_comp[ETHDR_VDO_FE1];
+	struct mtk_ethdr_comp *gfx_fe0 = &priv->ethdr_comp[ETHDR_GFX_FE0];
+	struct mtk_ethdr_comp *gfx_fe1 = &priv->ethdr_comp[ETHDR_GFX_FE1];
+	struct mtk_ethdr_comp *vdo_be = &priv->ethdr_comp[ETHDR_VDO_BE];
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	dev_dbg(dev, "%s-w:%d, h:%d\n", __func__, w, h);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_FE_0804_BYPASS_ALL, &vdo_fe0->cmdq_base,
+		      vdo_fe0->regs, HDR_VDO_FE_0804_HDR_DM_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_FE_0804_BYPASS_ALL, &vdo_fe1->cmdq_base,
+		      vdo_fe1->regs, HDR_VDO_FE_0804_HDR_DM_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_GFX_FE_0204_BYPASS_ALL, &gfx_fe0->cmdq_base,
+		      gfx_fe0->regs, HDR_GFX_FE_0204_GFX_HDR_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_GFX_FE_0204_BYPASS_ALL, &gfx_fe1->cmdq_base,
+		      gfx_fe1->regs, HDR_GFX_FE_0204_GFX_HDR_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_BE_0204_BYPASS_ALL, &vdo_be->cmdq_base,
+		      vdo_be->regs, HDR_VDO_BE_0204_VDO_DM_BE);
+
+	mtk_ddp_write(cmdq_pkt, MIX_FUNC_DCM_ENABLE, &mixer->cmdq_base, mixer->regs, MIX_FUNC_DCM0);
+	mtk_ddp_write(cmdq_pkt, MIX_FUNC_DCM_ENABLE, &mixer->cmdq_base, mixer->regs, MIX_FUNC_DCM1);
+	mtk_ddp_write(cmdq_pkt, (h << 16 | w), &mixer->cmdq_base, mixer->regs, MIX_ROI_SIZE);
+	mtk_ddp_write(cmdq_pkt, BGCLR_BLACK, &mixer->cmdq_base, mixer->regs, MIX_ROI_BGCLR);
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(0));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(1));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(2));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(3));
+	mtk_ddp_write(cmdq_pkt, 0x0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(0));
+	mtk_ddp_write(cmdq_pkt, OUTPUT_NO_RND | SOURCE_RGB_SEL | BACKGROUND_RELAY,
+		      &mixer->cmdq_base, mixer->regs, MIX_DATAPATH_CON);
+	mtk_ddp_write_mask(cmdq_pkt, MIX_SRC_L0_EN, &mixer->cmdq_base, mixer->regs,
+			   MIX_SRC_CON, MIX_SRC_L0_EN);
+
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0,
+			     w / 2, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0,
+			     h, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, 0, cmdq_pkt);
+}
+
+void mtk_ethdr_start(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	writel(1, mixer->regs + MIX_EN);
+}
+
+void mtk_ethdr_stop(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	writel(0, mixer->regs + MIX_EN);
+	writel(1, mixer->regs + MIX_RST);
+	reset_control_reset(devm_reset_control_array_get(dev, true, true));
+	writel(0, mixer->regs + MIX_RST);
+}
+
+int mtk_ethdr_clk_enable(struct device *dev)
+{
+	int ret;
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	ret = clk_bulk_prepare_enable(ETHDR_CLK_NUM, priv->ethdr_clk);
+	if (ret)
+		dev_err(dev,
+			"ethdr_clk prepare enable failed\n");
+	return ret;
+}
+
+void mtk_ethdr_clk_disable(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(ETHDR_CLK_NUM, priv->ethdr_clk);
+}
+
+static int mtk_ethdr_bind(struct device *dev, struct device *master,
+			  void *data)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct platform_device *ovl_adaptor;
+	struct drm_device *drm_dev = data;
+	struct mtk_drm_private *drm_private = drm_dev->dev_private;
+
+	priv->mmsys_dev = drm_private->mmsys_dev;
+
+	/* Bring up ovl adaptor rdma and merge */
+	ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovl-adaptor",
+						    PLATFORM_DEVID_NONE, (void *)priv->mmsys_dev,
+						    sizeof(*priv->mmsys_dev));
+	if (IS_ERR(ovl_adaptor))
+		return PTR_ERR(ovl_adaptor);
+
+	priv->ovl_adaptor_dev = &ovl_adaptor->dev;
+
+	return 0;
+}
+
+static void mtk_ethdr_unbind(struct device *dev, struct device *master, void *data)
+{
+}
+
+static const struct component_ops mtk_ethdr_component_ops = {
+	.bind	= mtk_ethdr_bind,
+	.unbind = mtk_ethdr_unbind,
+};
+
+static int mtk_ethdr_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_ethdr *priv;
+	int ret;
+	int i;
+
+	dev_info(dev, "%s+\n", __func__);
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	for (i = 0; i < ETHDR_ID_MAX; i++) {
+		priv->ethdr_comp[i].dev = dev;
+		priv->ethdr_comp[i].regs = of_iomap(dev->of_node, i);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+		ret = cmdq_dev_get_client_reg(dev,
+					      &priv->ethdr_comp[i].cmdq_base, i);
+		if (ret)
+			dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+		dev_info(dev, "[DRM]regs:0x%x, node:%s\n",
+			 priv->ethdr_comp[i].regs, ethdr_comp_str[i]);
+	}
+
+	for (i = 0; i < ETHDR_CLK_NUM; i++)
+		priv->ethdr_clk[i].id = ethdr_clk_str[i];
+	ret = devm_clk_bulk_get_optional(dev, ETHDR_CLK_NUM, priv->ethdr_clk);
+	if (ret)
+		return ret;
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (priv->irq < 0)
+		priv->irq = 0;
+
+	if (priv->irq) {
+		ret = devm_request_irq(dev, priv->irq, mtk_ethdr_irq_handler,
+				       IRQF_TRIGGER_NONE, dev_name(dev), priv);
+		if (ret < 0) {
+			dev_err(dev, "Failed to request irq %d: %d\n", priv->irq, ret);
+			return ret;
+		}
+	}
+
+	spin_lock_init(&priv->lock);
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_ethdr_component_ops);
+	if (ret)
+		dev_notice(dev, "Failed to add component: %d\n", ret);
+
+	dev_info(dev, "%s-\n", __func__);
+	pm_runtime_enable(dev);
+
+	return ret;
+}
+
+static int mtk_ethdr_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_ethdr_component_ops);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id mtk_ethdr_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-ethdr"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_ethdr_driver_dt_match);
+
+struct platform_driver mtk_ethdr_driver = {
+	.probe = mtk_ethdr_probe,
+	.remove = mtk_ethdr_remove,
+	.driver = {
+			.name = "mediatek-disp-ethdr",
+			.owner = THIS_MODULE,
+			.of_match_table = mtk_ethdr_driver_dt_match,
+		},
+};
+module_platform_driver(mtk_ethdr_driver);
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.h b/drivers/gpu/drm/mediatek/mtk_ethdr.h
new file mode 100644
index 000000000000..84eb9bf2ede0
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MTK_ETHDR_H__
+#define __MTK_ETHDR_H__
+
+#include <drm/mediatek_drm.h>
+
+void mtk_ethdr_start(struct device *dev);
+void mtk_ethdr_stop(struct device *dev);
+int mtk_ethdr_clk_enable(struct device *dev);
+void mtk_ethdr_clk_disable(struct device *dev);
+void mtk_ethdr_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
+			    struct mtk_plane_state *state,
+			    struct cmdq_pkt *cmdq_pkt);
+void mtk_ethdr_enable_vblank(struct device *dev, void (*vblank_cb)(void *),
+			     void *vblank_cb_data);
+void mtk_ethdr_disable_vblank(struct device *dev);
+#endif
+
-- 
2.18.0

From patchwork-bot+netdevbpf at kernel.org  Wed Aug 25 03:10:06 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 25 Aug 2021 10:10:06 +0000
Subject: [PATCH net v2 1/1] net: stmmac: fix kernel panic due to NULL
 pointer dereference of buf->xdp
In-Reply-To: <20210825005742.980267-1-yoong.siang.song@intel.com>
References: <20210825005742.980267-1-yoong.siang.song@intel.com>
Message-ID: <162988620630.3256.11386363919352017742.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (refs/heads/master):

On Wed, 25 Aug 2021 08:57:42 +0800 you wrote:
> Ensure a valid XSK buffer before proceed to free the xdp buffer.
> 
> The following kernel panic is observed without this patch:
> 
> RIP: 0010:xp_free+0x5/0x40
> Call Trace:
> stmmac_napi_poll_rxtx+0x332/0xb30 [stmmac]
> ? stmmac_tx_timer+0x3c/0xb0 [stmmac]
> net_rx_action+0x13d/0x3d0
> __do_softirq+0xfc/0x2fb
> ? smpboot_register_percpu_thread+0xe0/0xe0
> run_ksoftirqd+0x32/0x70
> smpboot_thread_fn+0x1d8/0x2c0
> kthread+0x169/0x1a0
> ? kthread_park+0x90/0x90
> ret_from_fork+0x1f/0x30
> 
> [...]

Here is the summary with links:
  - [net,v2,1/1] net: stmmac: fix kernel panic due to NULL pointer dereference of buf->xdp
    https://git.kernel.org/netdev/net/c/2b9fff64f032

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Wed Aug 25 03:10:06 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 25 Aug 2021 10:10:06 +0000
Subject: [PATCH net v2 1/1] net: stmmac: fix kernel panic due to NULL
 pointer dereference of xsk_pool
In-Reply-To: <20210825005529.980109-1-yoong.siang.song@intel.com>
References: <20210825005529.980109-1-yoong.siang.song@intel.com>
Message-ID: <162988620641.3256.15807737014421094725.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (refs/heads/master):

On Wed, 25 Aug 2021 08:55:29 +0800 you wrote:
> After free xsk_pool, there is possibility that napi polling is still
> running in the middle, thus causes a kernel crash due to kernel NULL
> pointer dereference of rx_q->xsk_pool and tx_q->xsk_pool.
> 
> Fix this by changing the XDP pool setup sequence to:
>  1. disable napi before free xsk_pool
>  2. enable napi after init xsk_pool
> 
> [...]

Here is the summary with links:
  - [net,v2,1/1] net: stmmac: fix kernel panic due to NULL pointer dereference of xsk_pool
    https://git.kernel.org/netdev/net/c/a6451192da26

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From nancy.lin at mediatek.com  Wed Aug 25 03:05:16 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:16 +0800
Subject: [PATCH v4 02/17] dt-bindings: mediatek: add vdosys1 MERGE property
 for mt8195
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-3-nancy.lin@mediatek.com>

MT8195 vdosys1 merge1 to merge4 have HW mute function.
Add MERGE additional mute property description.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../devicetree/bindings/display/mediatek/mediatek,merge.yaml   | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index b15c6e17b421..5be3715ddc56 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -52,6 +52,9 @@ properties:
       ultra and preulra command to SMI to speed up the data rate.
     type: boolean
 
+  mediatek,merge-mute:
+    description: Support mute function. Mute the content of merge output.
+    type: boolean
 
   mediatek,gce-client-reg:
     description:
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:27 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:27 +0800
Subject: [PATCH v4 13/17] drm/mediatek: add display merge api support for
 MT8195
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-14-nancy.lin@mediatek.com>

Add merge new API.
1. Vdosys1 merge1~merge4 support HW mute function, so add unmute API.
2. Add merge new advance config API. The original merge API is
   mtk_ddp_comp_funcs function prototype. The API interface parameters
   cannot be modified, so add a new config API for extension.
3. Add merge enable/disable API for cmdq support. The ovl_adaptor merges
   are configured with each drm plane update. Need to enable/disable
   merge with cmdq making sure all the settings taken effect in the
   same vblank.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  6 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 74 ++++++++++++++++++++---
 2 files changed, 70 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index b3a372cab0bd..2446ad0a4977 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -63,6 +63,12 @@ void mtk_merge_config(struct device *dev, unsigned int width,
 		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
 void mtk_merge_start(struct device *dev);
 void mtk_merge_stop(struct device *dev);
+void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int r_w,
+			      unsigned int h, unsigned int vrefresh, unsigned int bpc,
+			      struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_unmute(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_enable(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_disable(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index b05e1df79c3d..41bff6d3a8da 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -17,6 +17,7 @@
 #define DISP_REG_MERGE_CTRL		0x000
 #define MERGE_EN				1
 #define DISP_REG_MERGE_CFG_0		0x010
+#define DISP_REG_MERGE_CFG_1		0x014
 #define DISP_REG_MERGE_CFG_4		0x020
 #define DISP_REG_MERGE_CFG_10		0x038
 /* no swap */
@@ -25,9 +26,12 @@
 #define DISP_REG_MERGE_CFG_12		0x040
 #define CFG_10_10_1PI_2PO_BUF_MODE		6
 #define CFG_10_10_2PI_2PO_BUF_MODE		8
+#define CFG_11_10_1PI_2PO_MERGE			18
 #define FLD_CFG_MERGE_MODE			GENMASK(4, 0)
 #define DISP_REG_MERGE_CFG_24		0x070
 #define DISP_REG_MERGE_CFG_25		0x074
+#define DISP_REG_MERGE_CFG_26		0x078
+#define DISP_REG_MERGE_CFG_27		0x07c
 #define DISP_REG_MERGE_CFG_36		0x0a0
 #define ULTRA_EN				BIT(0)
 #define PREULTRA_EN				BIT(4)
@@ -54,26 +58,52 @@
 #define FLD_PREULTRA_TH_LOW			GENMASK(15, 0)
 #define FLD_PREULTRA_TH_HIGH			GENMASK(31, 16)
 
+#define DISP_REG_MERGE_MUTE_0		0xf00
+
 struct mtk_disp_merge {
 	void __iomem *regs;
 	struct clk *clk;
 	struct clk *async_clk;
 	struct cmdq_client_reg		cmdq_reg;
 	bool				fifo_en;
+	bool				mute_support;
 };
 
 void mtk_merge_start(struct device *dev)
+{
+	mtk_merge_enable(dev, NULL);
+}
+
+void mtk_merge_stop(struct device *dev)
 {
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
-	writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+	mtk_merge_disable(dev, NULL);
 }
 
-void mtk_merge_stop(struct device *dev)
+void mtk_merge_enable(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_disable(struct device *dev, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
-	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+	mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_unmute(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	if (priv->mute_support)
+		mtk_ddp_write(cmdq_pkt, 0x0, &priv->cmdq_reg, priv->regs,
+			      DISP_REG_MERGE_MUTE_0);
 }
 
 static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
@@ -98,12 +128,19 @@ static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
 void mtk_merge_config(struct device *dev, unsigned int w,
 		      unsigned int h, unsigned int vrefresh,
 		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	mtk_merge_advance_config(dev, w, 0, h, vrefresh, bpc, cmdq_pkt);
+}
+
+void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int r_w,
+			      unsigned int h, unsigned int vrefresh, unsigned int bpc,
+			      struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 	unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
 
-	if (!h || !w) {
-		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
+	if (!h || !l_w) {
+		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, l_w, h);
 		return;
 	}
 
@@ -112,14 +149,29 @@ void mtk_merge_config(struct device *dev, unsigned int w,
 		mode = CFG_10_10_2PI_2PO_BUF_MODE;
 	}
 
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+	if (r_w)
+		mode = CFG_11_10_1PI_2PO_MERGE;
+
+	mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
 		      DISP_REG_MERGE_CFG_0);
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+	mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_1);
+	mtk_ddp_write(cmdq_pkt, h << 16 | (l_w + r_w), &priv->cmdq_reg, priv->regs,
 		      DISP_REG_MERGE_CFG_4);
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+	mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
 		      DISP_REG_MERGE_CFG_24);
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
-		      DISP_REG_MERGE_CFG_25);
+	if (r_w)
+		mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs,
+			      DISP_REG_MERGE_CFG_25);
+	else
+		mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
+			      DISP_REG_MERGE_CFG_25);
+
+	mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_26);
+	mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_27);
+
 	mtk_ddp_write_mask(cmdq_pkt, SWAP_MODE, &priv->cmdq_reg, priv->regs,
 			   DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
 	mtk_ddp_write_mask(cmdq_pkt, mode, &priv->cmdq_reg, priv->regs,
@@ -205,6 +257,8 @@ static int mtk_disp_merge_probe(struct platform_device *pdev)
 	priv->fifo_en = of_property_read_bool(dev->of_node,
 					      "mediatek,merge-fifo-en");
 
+	priv->mute_support = of_property_read_bool(dev->of_node,
+						   "mediatek,merge-mute");
 	platform_set_drvdata(pdev, priv);
 
 	ret = component_add(dev, &mtk_disp_merge_component_ops);
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:20 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:20 +0800
Subject: [PATCH v4 06/17] arm64: dts: mt8195: add display node for vdosys1
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-7-nancy.lin@mediatek.com>

Add display node for vdosys1.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 221 +++++++++++++++++++++++
 1 file changed, 221 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 4064a92e28a5..6ea6d0c6d840 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -10,6 +10,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/power/mt8195-power.h>
+#include <dt-bindings/reset/mt8195-resets.h>
 
 / {
 	compatible = "mediatek,mt8195";
@@ -20,6 +21,21 @@
 	aliases {
 		gce0 = &gce0;
 		gce1 = &gce1;
+		mutex0 = &mutex;
+		mutex1 = &mutex1;
+		merge1 = &merge1;
+		merge2 = &merge2;
+		merge3 = &merge3;
+		merge4 = &merge4;
+		merge5 = &merge5;
+		vdo1_rdma0 = &vdo1_rdma0;
+		vdo1_rdma1 = &vdo1_rdma1;
+		vdo1_rdma2 = &vdo1_rdma2;
+		vdo1_rdma3 = &vdo1_rdma3;
+		vdo1_rdma4 = &vdo1_rdma4;
+		vdo1_rdma5 = &vdo1_rdma5;
+		vdo1_rdma6 = &vdo1_rdma6;
+		vdo1_rdma7 = &vdo1_rdma7;
 	};
 
 	clocks {
@@ -1272,7 +1288,212 @@
 		vdosys1: syscon at 1c100000 {
 			compatible = "mediatek,mt8195-vdosys1", "syscon";
 			reg = <0 0x1c100000 0 0x1000>;
+			mboxes = <&gce1 1 CMDQ_THR_PRIO_4>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x0000 0x1000>;
 			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		mutex1: disp_mutex0 at 1c101000 {
+			compatible = "mediatek,mt8195-disp-mutex";
+			reg = <0 0x1c101000 0 0x1000>;
+			reg-names = "vdo1_mutex";
+			interrupts = <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>;
+			clock-names = "vdo1_mutex";
+			mediatek,gce-events = <CMDQ_EVENT_VDO1_STREAM_DONE_ENG_0>;
+		};
+
+		vdo1_rdma0: vdo1_rdma at 1c104000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c104000 0 0x1000>;
+			interrupts = <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x4000 0x1000>;
+		};
+
+		vdo1_rdma1: vdo1_rdma at 1c105000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c105000 0 0x1000>;
+			interrupts = <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA1>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x5000 0x1000>;
+		};
+
+		vdo1_rdma2: vdo1_rdma at 1c106000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c106000 0 0x1000>;
+			interrupts = <GIC_SPI 497 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA2>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x6000 0x1000>;
+		};
+
+		vdo1_rdma3: vdo1_rdma at 1c107000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c107000 0 0x1000>;
+			interrupts = <GIC_SPI 498 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA3>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x7000 0x1000>;
+		};
+
+		vdo1_rdma4: vdo1_rdma at 1c108000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c108000 0 0x1000>;
+			interrupts = <GIC_SPI 499 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA4>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA4>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x8000 0x1000>;
+		};
+
+		vdo1_rdma5: vdo1_rdma at 1c109000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c109000 0 0x1000>;
+			interrupts = <GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA5>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA5>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x9000 0x1000>;
+		};
+
+		vdo1_rdma6: vdo1_rdma at 1c10a000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c10a000 0 0x1000>;
+			interrupts = <GIC_SPI 501 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA6>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA6>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xa000 0x1000>;
+		};
+
+		vdo1_rdma7: vdo1_rdma at 1c10b000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c10b000 0 0x1000>;
+			interrupts = <GIC_SPI 502 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA7>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA7>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xb000 0x1000>;
+		};
+
+		merge1: disp_vpp_merge at 1c10c000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c10c000 0 0x1000>;
+			interrupts = <GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE0>,
+				 <&vdosys1 CLK_VDO1_MERGE0_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xc000 0x1000>;
+			mediatek,merge-mute = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC>;
+		};
+
+		merge2: disp_vpp_merge at 1c10d000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c10d000 0 0x1000>;
+			interrupts = <GIC_SPI 504 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE1>,
+				 <&vdosys1 CLK_VDO1_MERGE1_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xd000 0x1000>;
+			mediatek,merge-mute = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC>;
+		};
+
+		merge3: disp_vpp_merge at 1c10e000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c10e000 0 0x1000>;
+			interrupts = <GIC_SPI 505 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE2>,
+				 <&vdosys1 CLK_VDO1_MERGE2_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xe000 0x1000>;
+			mediatek,merge-mute = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC>;
+		};
+
+		merge4: disp_vpp_merge at 1c10f000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c10f000 0 0x1000>;
+			interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE3>,
+				 <&vdosys1 CLK_VDO1_MERGE3_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0xf000 0x1000>;
+			mediatek,merge-mute = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC>;
+		};
+
+		merge5: disp_vpp_merge5 at 1c110000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c110000 0 0x1000>;
+			interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+				 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+			mediatek,merge-fifo-en = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+		};
+
+		disp_ethdr at 1c114000 {
+			compatible = "mediatek,mt8195-disp-ethdr";
+			reg = <0 0x1c114000 0 0x1000>,
+			      <0 0x1c115000 0 0x1000>,
+			      <0 0x1c117000 0 0x1000>,
+			      <0 0x1c119000 0 0x1000>,
+			      <0 0x1c11A000 0 0x1000>,
+			      <0 0x1c11B000 0 0x1000>,
+			      <0 0x1c11C000 0 0x1000>;
+			reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+				    "vdo_be", "adl_ds";
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x4000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0x5000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0x7000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0x9000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0xA000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0xB000 0x1000>,
+						  <&gce1 SUBSYS_1c11XXXX 0xC000 0x1000>;
+			clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_BE>,
+				 <&vdosys1 CLK_VDO1_26M_SLOW>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE0_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE1_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE0_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE1_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_BE_DL_ASYNC>,
+				 <&topckgen CLK_TOP_ETHDR_SEL>;
+			clock-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+				      "vdo_be", "adl_ds", "vdo_fe0_async", "vdo_fe1_async",
+				      "gfx_fe0_async", "gfx_fe1_async","vdo_be_async",
+				      "ethdr_top";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_HDR_DS>,
+				 <&iommu_vpp M4U_PORT_L3_HDR_ADL>;
+			interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>; /* disp mixer */
+			resets = <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC>;
 		};
 	};
 
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:19 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:19 +0800
Subject: [PATCH v4 05/17] dt-bindings: reset: mt8195: add vdosys1 reset
 control bit
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-6-nancy.lin@mediatek.com>

Add vdosys1 reset control bit for MT8195 platform.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 include/dt-bindings/reset/mt8195-resets.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/dt-bindings/reset/mt8195-resets.h b/include/dt-bindings/reset/mt8195-resets.h
index a26bccc8b957..eaaa882c09bd 100644
--- a/include/dt-bindings/reset/mt8195-resets.h
+++ b/include/dt-bindings/reset/mt8195-resets.h
@@ -26,4 +26,16 @@
 
 #define MT8195_TOPRGU_SW_RST_NUM               16
 
+/* VDOSYS1 */
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC 25
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC 26
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC 27
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC 28
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC 29
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC 51
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC 52
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC 53
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC 54
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC 55
+
 #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:18 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:18 +0800
Subject: [PATCH v4 04/17] dt-bindings: mediatek: Add #reset-cells to mmsys
 system controller
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-5-nancy.lin@mediatek.com>

The mmsys system controller exposes a set of memory client resets and
needs to specify the #reset-cells property in order to advertise the
number of cells needed to describe each of the resets

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml       | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 9eae76a2c5f6..e5433612e860 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -66,6 +66,9 @@ properties:
   "#clock-cells":
     const: 1
 
+  "#reset-cells":
+    const: 1
+
 required:
   - compatible
   - reg
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:26 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:26 +0800
Subject: [PATCH v4 12/17] drm/mediatek: add display MDP RDMA support for MT8195
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-13-nancy.lin@mediatek.com>

Add MDP_RDMA driver for MT8195. MDP_RDMA is the DMA engine of
the ovl_adaptor component.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile       |   3 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |   7 +
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 306 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h |  37 +++
 4 files changed, 352 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index a38e88e82d12..6e604a933ed0 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_drm_gem.o \
 		  mtk_drm_plane.o \
 		  mtk_dsi.o \
-		  mtk_dpi.o
+		  mtk_dpi.o \
+		  mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index a33b13fe2b6e..b3a372cab0bd 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -8,6 +8,7 @@
 
 #include <linux/soc/mediatek/mtk-cmdq.h>
 #include "mtk_drm_plane.h"
+#include "mtk_mdp_rdma.h"
 
 int mtk_aal_clk_enable(struct device *dev);
 void mtk_aal_clk_disable(struct device *dev);
@@ -106,4 +107,10 @@ void mtk_rdma_enable_vblank(struct device *dev,
 			    void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_mdp_rdma_clk_enable(struct device *dev);
+void mtk_mdp_rdma_clk_disable(struct device *dev);
+void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
+			 struct cmdq_pkt *cmdq_pkt);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
new file mode 100644
index 000000000000..7a0996253cfc
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -0,0 +1,306 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_drv.h"
+#include "mtk_disp_drv.h"
+#include "mtk_mdp_rdma.h"
+
+#define MDP_RDMA_EN                                            0x000
+	#define FLD_ROT_ENABLE                            BIT(0)
+
+#define MDP_RDMA_RESET                                         0x008
+
+#define MDP_RDMA_CON                                           0x020
+	#define FLD_OUTPUT_10B                            BIT(5)
+	#define FLD_SIMPLE_MODE                           BIT(4)
+
+#define MDP_RDMA_GMCIF_CON                                     0x028
+	#define FLD_COMMAND_DIV                           BIT(0)
+	#define FLD_EXT_PREULTRA_EN                       BIT(3)
+	#define FLD_RD_REQ_TYPE                           GENMASK(7, 4)
+		#define VAL_RD_REQ_TYPE_BURST_8_ACCESS    7
+	#define FLD_ULTRA_EN                              GENMASK(13, 12)
+		#define VAL_ULTRA_EN_ENABLE               1
+	#define FLD_PRE_ULTRA_EN                          GENMASK(17, 16)
+		#define VAL_PRE_ULTRA_EN_ENABLE           1
+	#define FLD_EXT_ULTRA_EN                          BIT(18)
+
+#define MDP_RDMA_SRC_CON                                       0x030
+	#define FLD_OUTPUT_ARGB                           BIT(25)
+	#define FLD_BIT_NUMBER                            GENMASK(19, 18)
+	#define FLD_UNIFORM_CONFIG                        BIT(17)
+	#define FLD_SWAP                                  BIT(14)
+	#define FLD_SRC_FORMAT                            GENMASK(3, 0)
+
+#define MDP_RDMA_COMP_CON                                      0x038
+	#define FLD_AFBC_EN                               BIT(22)
+	#define FLD_AFBC_YUV_TRANSFORM                    BIT(21)
+	#define FLD_UFBDC_EN                              BIT(12)
+
+#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE                          0x060
+	#define FLD_MF_BKGD_WB                            GENMASK(22, 0)
+
+#define MDP_RDMA_MF_SRC_SIZE                                   0x070
+	#define FLD_MF_SRC_H                              GENMASK(30, 16)
+	#define FLD_MF_SRC_W                              GENMASK(14, 0)
+
+#define MDP_RDMA_MF_CLIP_SIZE                                  0x078
+	#define FLD_MF_CLIP_H                             GENMASK(30, 16)
+	#define FLD_MF_CLIP_W                             GENMASK(14, 0)
+
+#define MDP_RDMA_TARGET_LINE                                   0x0a0
+	#define FLD_LINE_THRESHOLD                        GENMASK(31, 17)
+	#define FLD_TARGET_LINE_EN                        BIT(16)
+
+#define MDP_RDMA_SRC_OFFSET_0                                  0x118
+	#define FLD_SRC_OFFSET_0                          GENMASK(31, 0)
+
+#define MDP_RDMA_TRANSFORM_0                                   0x200
+	#define FLD_INT_MATRIX_SEL                        GENMASK(27, 23)
+	#define FLD_TRANS_EN                              BIT(16)
+
+#define MDP_RDMA_SRC_BASE_0                                    0xf00
+	#define FLD_SRC_BASE_0                            GENMASK(31, 0)
+
+#define RDMA_INPUT_SWAP		BIT(14)
+#define RDMA_INPUT_10BIT	BIT(18)
+
+enum rdma_format {
+	RDMA_INPUT_FORMAT_RGB565 = 0,
+	RDMA_INPUT_FORMAT_RGB888 = 1,
+	RDMA_INPUT_FORMAT_RGBA8888 = 2,
+	RDMA_INPUT_FORMAT_ARGB8888 = 3,
+	RDMA_INPUT_FORMAT_UYVY = 4,
+	RDMA_INPUT_FORMAT_YUY2 = 5,
+	RDMA_INPUT_FORMAT_Y8 = 7,
+	RDMA_INPUT_FORMAT_YV12 = 8,
+	RDMA_INPUT_FORMAT_UYVY_3PL = 9,
+	RDMA_INPUT_FORMAT_NV12 = 12,
+	RDMA_INPUT_FORMAT_UYVY_2PL = 13,
+	RDMA_INPUT_FORMAT_Y410 = 14
+};
+
+struct mtk_mdp_rdma {
+	void __iomem *regs;
+	struct clk *clk;
+	struct cmdq_client_reg		cmdq_reg;
+};
+
+static unsigned int rdma_fmt_convert(unsigned int fmt)
+{
+	switch (fmt) {
+	default:
+	case DRM_FORMAT_RGB565:
+		return RDMA_INPUT_FORMAT_RGB565;
+	case DRM_FORMAT_BGR565:
+		return RDMA_INPUT_FORMAT_RGB565 | RDMA_INPUT_SWAP;
+	case DRM_FORMAT_RGB888:
+		return RDMA_INPUT_FORMAT_RGB888;
+	case DRM_FORMAT_BGR888:
+		return RDMA_INPUT_FORMAT_RGB888 | RDMA_INPUT_SWAP;
+	case DRM_FORMAT_RGBX8888:
+	case DRM_FORMAT_RGBA8888:
+		return RDMA_INPUT_FORMAT_ARGB8888;
+	case DRM_FORMAT_BGRX8888:
+	case DRM_FORMAT_BGRA8888:
+		return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_SWAP;
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ARGB8888:
+		return RDMA_INPUT_FORMAT_RGBA8888;
+	case DRM_FORMAT_XBGR8888:
+	case DRM_FORMAT_ABGR8888:
+		return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_SWAP;
+	case DRM_FORMAT_ABGR2101010:
+		return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_SWAP |
+				RDMA_INPUT_10BIT;
+	case DRM_FORMAT_ARGB2101010:
+		return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_10BIT;
+	case DRM_FORMAT_RGBA1010102:
+		return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_SWAP |
+				RDMA_INPUT_10BIT;
+	case DRM_FORMAT_BGRA1010102:
+		return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_10BIT;
+	case DRM_FORMAT_UYVY:
+		return RDMA_INPUT_FORMAT_UYVY;
+	case DRM_FORMAT_YUYV:
+		return RDMA_INPUT_FORMAT_YUY2;
+	}
+}
+
+static void mtk_mdp_rdma_fifo_config(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write_mask(cmdq_pkt, FLD_EXT_ULTRA_EN | VAL_PRE_ULTRA_EN_ENABLE << 16 |
+			   VAL_ULTRA_EN_ENABLE << 12 | VAL_RD_REQ_TYPE_BURST_8_ACCESS << 4 |
+			   FLD_EXT_PREULTRA_EN | FLD_COMMAND_DIV, &priv->cmdq_reg,
+			   priv->regs, MDP_RDMA_GMCIF_CON, FLD_EXT_ULTRA_EN |
+			   FLD_PRE_ULTRA_EN | FLD_ULTRA_EN | FLD_RD_REQ_TYPE |
+			   FLD_EXT_PREULTRA_EN | FLD_COMMAND_DIV);
+}
+
+void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write_mask(cmdq_pkt, FLD_ROT_ENABLE, &priv->cmdq_reg,
+			   priv->regs, MDP_RDMA_EN, FLD_ROT_ENABLE);
+}
+
+void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg,
+			   priv->regs, MDP_RDMA_EN, FLD_ROT_ENABLE);
+	mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs, MDP_RDMA_RESET);
+	mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_RESET);
+}
+
+void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
+			 struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);
+	const struct drm_format_info *fmt_info = drm_format_info(cfg->fmt);
+	unsigned int src_pitch_y = cfg->pitch;
+	unsigned int bpp_y = fmt_info->cpp[0] * 8;
+	unsigned int offset_y = 0;
+
+	mtk_mdp_rdma_fifo_config(dev, cmdq_pkt);
+
+	mtk_ddp_write_mask(cmdq_pkt, FLD_UNIFORM_CONFIG, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_SRC_CON, FLD_UNIFORM_CONFIG);
+	mtk_ddp_write_mask(cmdq_pkt, rdma_fmt_convert(cfg->fmt), &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_SRC_CON, FLD_SWAP | FLD_SRC_FORMAT | FLD_BIT_NUMBER);
+
+	if (!cfg->csc_enable && fmt_info->has_alpha)
+		mtk_ddp_write_mask(cmdq_pkt, FLD_OUTPUT_ARGB, &priv->cmdq_reg,
+				   priv->regs, MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);
+	else
+		mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
+				   MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);
+
+	mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_SRC_BASE_0, FLD_SRC_BASE_0);
+
+	mtk_ddp_write_mask(cmdq_pkt, src_pitch_y, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, FLD_MF_BKGD_WB);
+
+	mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_COMP_CON,
+			   FLD_AFBC_YUV_TRANSFORM);
+	mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_COMP_CON,
+			   FLD_UFBDC_EN);
+	mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_COMP_CON,
+			   FLD_AFBC_EN);
+
+	mtk_ddp_write_mask(cmdq_pkt, FLD_OUTPUT_10B, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_CON, FLD_OUTPUT_10B);
+	mtk_ddp_write_mask(cmdq_pkt, FLD_SIMPLE_MODE, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_CON, FLD_SIMPLE_MODE);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->csc_enable << 16, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_TRANSFORM_0, FLD_TRANS_EN);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->profile << 23, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_TRANSFORM_0, FLD_INT_MATRIX_SEL);
+
+	offset_y  = (cfg->x_left * bpp_y >> 3) + cfg->y_top * src_pitch_y;
+
+	mtk_ddp_write_mask(cmdq_pkt, offset_y, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_SRC_OFFSET_0, FLD_SRC_OFFSET_0);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->width, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_SRC_SIZE, FLD_MF_SRC_W);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->height << 16, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_SRC_SIZE, FLD_MF_SRC_H);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->width, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_W);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->height << 16, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_H);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->height << 17, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_TARGET_LINE, FLD_LINE_THRESHOLD);
+	mtk_ddp_write_mask(cmdq_pkt, FLD_TARGET_LINE_EN, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_TARGET_LINE, FLD_TARGET_LINE_EN);
+}
+
+int mtk_mdp_rdma_clk_enable(struct device *dev)
+{
+	struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);
+
+	pm_runtime_get_sync(dev);
+	clk_prepare_enable(rdma->clk);
+	return 0;
+}
+
+void mtk_mdp_rdma_clk_disable(struct device *dev)
+{
+	struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(rdma->clk);
+	pm_runtime_put(dev);
+}
+
+static int mtk_mdp_rdma_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct mtk_mdp_rdma *priv;
+	int ret = 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap rdma\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get rdma clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+	platform_set_drvdata(pdev, priv);
+
+	pm_runtime_enable(dev);
+	return ret;
+}
+
+static int mtk_mdp_rdma_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id mtk_mdp_rdma_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-vdo1-rdma", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_mdp_rdma_driver_dt_match);
+
+struct platform_driver mtk_mdp_rdma_driver = {
+	.probe = mtk_mdp_rdma_probe,
+	.remove = mtk_mdp_rdma_remove,
+	.driver = {
+		.name = "mediatek-mdp-rdma",
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_mdp_rdma_driver_dt_match,
+	},
+};
+module_platform_driver(mtk_mdp_rdma_driver);
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
new file mode 100644
index 000000000000..df8e28f0e3a4
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MTK_MDP_RDMA_H__
+#define __MTK_MDP_RDMA_H__
+
+enum mtk_mdp_rdma_profile {
+	RDMA_CSC_RGB_TO_JPEG = 0,
+	RDMA_CSC_RGB_TO_FULL709 = 1,
+	RDMA_CSC_RGB_TO_BT601 = 2,
+	RDMA_CSC_RGB_TO_BT709 = 3,
+	RDMA_CSC_JPEG_TO_RGB = 4,
+	RDMA_CSC_FULL709_TO_RGB = 5,
+	RDMA_CSC_BT601_TO_RGB = 6,
+	RDMA_CSC_BT709_TO_RGB = 7,
+	RDMA_CSC_JPEG_TO_BT601 = 8,
+	RDMA_CSC_JPEG_TO_BT709 = 9,
+	RDMA_CSC_BT601_TO_JPEG = 10,
+	RDMA_CSC_BT709_TO_BT601 = 11,
+	RDMA_CSC_BT601_TO_BT709 = 12
+};
+
+struct mtk_mdp_rdma_cfg {
+	enum mtk_mdp_rdma_profile profile;
+	unsigned int pitch;
+	unsigned int addr0;
+	unsigned int width;
+	unsigned int height;
+	unsigned int x_left;
+	unsigned int y_top;
+	bool csc_enable;
+	int fmt;
+};
+
+#endif // __MTK_MDP_RDMA_H__
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:15 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:15 +0800
Subject: [PATCH v4 01/17] dt-bindings: mediatek: add vdosys1 RDMA definition
 for mt8195
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-2-nancy.lin@mediatek.com>

Add vdosys1 RDMA definition.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../display/mediatek/mediatek,mdp-rdma.yaml   | 77 +++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
new file mode 100644
index 000000000000..3610093848e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mdp-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display MDP RDMA
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+
+description: |
+  The mediatek display MDP RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-vdo1-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    vdo1_rdma0: vdo1_rdma at 1c104000 {
+        compatible = "mediatek,mt8195-vdo1-rdma";
+        reg = <0 0x1c104000 0 0x1000>;
+        interrupts = <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c10XXXX 0x4000 0x1000>;
+    };
+
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:21 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:21 +0800
Subject: [PATCH v4 07/17] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys1
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-8-nancy.lin@mediatek.com>

Add mt8195 vdosys1 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 136 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       |  10 ++
 include/linux/soc/mediatek/mtk-mmsys.h |   2 +
 3 files changed, 148 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index 0c97a5f016c1..f19ec72c1243 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -59,6 +59,70 @@
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 << 16)
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(3 << 16)
 
+#define MT8195_VDO1_VPP_MERGE0_P0_SEL_IN			0xf04
+#define MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0		(1 << 0)
+
+#define MT8195_VDO1_VPP_MERGE0_P1_SEL_IN			0xf08
+#define MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1		(1 << 0)
+
+#define MT8195_VDO1_DISP_DPI1_SEL_IN				0xf10
+#define MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT		(0 << 0)
+
+#define MT8195_VDO1_DISP_DP_INTF0_SEL_IN			0xf14
+#define MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT	(0 << 0)
+
+#define MT8195_VDO1_MERGE4_SOUT_SEL				0xf18
+#define MT8195_MERGE4_SOUT_TO_DPI1_SEL				(2 << 0)
+#define MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL			(3 << 0)
+
+#define MT8195_VDO1_MIXER_IN1_SEL_IN				0xf24
+#define MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_IN2_SEL_IN				0xf28
+#define MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_IN3_SEL_IN				0xf2c
+#define MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_IN4_SEL_IN				0xf30
+#define MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_OUT_SOUT_SEL				0xf34
+#define MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL			(1 << 0)
+
+#define MT8195_VDO1_VPP_MERGE1_P0_SEL_IN			0xf3c
+#define MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2		(1 << 0)
+
+#define MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL			0xf40
+#define MT8195_SOUT_TO_MIXER_IN1_SEL				(1 << 0)
+
+#define MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL			0xf44
+#define MT8195_SOUT_TO_MIXER_IN2_SEL				(1 << 0)
+
+#define MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL			0xf48
+#define MT8195_SOUT_TO_MIXER_IN3_SEL				(1 << 0)
+
+#define MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL			0xf4c
+#define MT8195_SOUT_TO_MIXER_IN4_SEL				(1 << 0)
+
+#define MT8195_VDO1_MERGE4_ASYNC_SEL_IN				0xf50
+#define MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT		(1 << 0)
+
+#define MT8195_VDO1_MIXER_IN1_SOUT_SEL				0xf58
+#define MT8195_MIXER_IN1_SOUT_TO_DISP_MIXER			(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN2_SOUT_SEL				0xf5c
+#define MT8195_MIXER_IN2_SOUT_TO_DISP_MIXER			(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN3_SOUT_SEL				0xf60
+#define MT8195_MIXER_IN3_SOUT_TO_DISP_MIXER			(0 << 0)
+
+#define MT8195_VDO1_MIXER_IN4_SOUT_SEL				0xf64
+#define MT8195_MIXER_IN4_SOUT_TO_DISP_MIXER			(0 << 0)
+
+#define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
+#define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER		(0 << 0)
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	{
 		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -108,6 +172,78 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
 		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
 		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE0_P0_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE0_P1_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE1_P0_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN1_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN2_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN3_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN4_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_OUT_SOUT_SEL, GENMASK(0, 0),
+		MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN1_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN2_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN3_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN4_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_SOUT_SEL_IN, GENMASK(2, 0),
+		MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE4_ASYNC_SEL_IN, GENMASK(2, 0),
+		MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
+		MT8195_VDO1_DISP_DPI1_SEL_IN, GENMASK(1, 0),
+		MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
+		MT8195_VDO1_MERGE4_SOUT_SEL, GENMASK(1, 0),
+		MT8195_MERGE4_SOUT_TO_DPI1_SEL
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
+		MT8195_VDO1_DISP_DP_INTF0_SEL_IN, GENMASK(1, 0),
+		MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
+		MT8195_VDO1_MERGE4_SOUT_SEL, GENMASK(1, 0),
+		MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL
 	}
 };
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index ce6cc2f49e7d..7365731c9fd7 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -66,6 +66,12 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
+	.clk_driver = "clk-mt8195-vdo1",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
@@ -182,6 +188,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8195-vdosys0",
 		.data = &mt8195_vdosys0_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys1",
+		.data = &mt8195_vdosys1_driver_data,
+	},
 	{ }
 };
 
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 6d6ece48b61e..619392221a52 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -18,6 +18,7 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
 	DDP_COMPONENT_DP_INTF0,
+	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
 	DDP_COMPONENT_DSC0,
@@ -38,6 +39,7 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_OVL0,
 	DDP_COMPONENT_OVL_2L0,
 	DDP_COMPONENT_OVL_2L1,
+	DDP_COMPONENT_OVL_ADAPTOR,
 	DDP_COMPONENT_OVL1,
 	DDP_COMPONENT_PWM0,
 	DDP_COMPONENT_PWM1,
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:31 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:31 +0800
Subject: [PATCH v4 17/17] drm/mediatek: add mediatek-drm of vdosys1 support
 for MT8195
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-18-nancy.lin@mediatek.com>

Add driver data of mt8195 vdosys1 to mediatek-drm and the sub driver.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   |  4 ++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 15 +++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 17 +++++++++++++++++
 4 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 41bff6d3a8da..13c788f67ced 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -8,6 +8,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_drm_ddp_comp.h"
@@ -79,6 +80,9 @@ void mtk_merge_stop(struct device *dev)
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
 	mtk_merge_disable(dev, NULL);
+
+	if (priv->async_clk)
+		device_reset_optional(dev);
 }
 
 void mtk_merge_enable(struct device *dev, struct cmdq_pkt *cmdq_pkt)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 2885fe83162a..900f9c9f61f3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -345,6 +345,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
 	.start = mtk_ufoe_start,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
+	.clk_enable = mtk_ovl_adaptor_clk_enable,
+	.clk_disable = mtk_ovl_adaptor_clk_disable,
+	.config = mtk_ovl_adaptor_config,
+	.start = mtk_ovl_adaptor_start,
+	.stop = mtk_ovl_adaptor_stop,
+	.layer_nr = mtk_ovl_adaptor_layer_nr,
+	.layer_config = mtk_ovl_adaptor_layer_config,
+	.enable_vblank = mtk_ovl_adaptor_enable_vblank,
+	.disable_vblank = mtk_ovl_adaptor_disable_vblank,
+};
+
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_AAL] = "aal",
 	[MTK_DISP_BLS] = "bls",
@@ -358,6 +370,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
 	[MTK_DISP_OVL_2L] = "ovl-2l",
+	[MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor",
 	[MTK_DISP_PWM] = "pwm",
 	[MTK_DISP_RDMA] = "rdma",
 	[MTK_DISP_UFOE] = "ufoe",
@@ -401,6 +414,7 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_OVL1]	= { MTK_DISP_OVL,	1, &ddp_ovl },
 	[DDP_COMPONENT_OVL_2L0]	= { MTK_DISP_OVL_2L,	0, &ddp_ovl },
 	[DDP_COMPONENT_OVL_2L1]	= { MTK_DISP_OVL_2L,	1, &ddp_ovl },
+	[DDP_COMPONENT_OVL_ADAPTOR] = { MTK_DISP_OVL_ADAPTOR,	0, &ddp_ovl_adaptor },
 	[DDP_COMPONENT_PWM0]	= { MTK_DISP_PWM,	0, NULL },
 	[DDP_COMPONENT_PWM1]	= { MTK_DISP_PWM,	1, NULL },
 	[DDP_COMPONENT_PWM2]	= { MTK_DISP_PWM,	2, NULL },
@@ -529,6 +543,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
+	    type == MTK_DISP_OVL_ADAPTOR ||
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index b42a47c06956..a8e5e770ce2f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -30,6 +30,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
 	MTK_DISP_OVL_2L,
+	MTK_DISP_OVL_ADAPTOR,
 	MTK_DISP_PWM,
 	MTK_DISP_RDMA,
 	MTK_DISP_UFOE,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 782c791b368e..e831175a66f3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -160,6 +160,12 @@ static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
 	DDP_COMPONENT_DP_INTF0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_ext[] = {
+	DDP_COMPONENT_OVL_ADAPTOR,
+	DDP_COMPONENT_MERGE5,
+	DDP_COMPONENT_DP_INTF1,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -216,6 +222,13 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
 	.mmsys_dev_num = 2,
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
+	.ext_path = mt8195_mtk_ddp_ext,
+	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
+	.mmsys_id = 1,
+	.mmsys_dev_num = 2,
+};
+
 static const struct of_device_id mtk_drm_of_ids[] = {
 	{ .compatible = "mediatek,mt2701-mmsys",
 	  .data = &mt2701_mmsys_driver_data},
@@ -691,6 +704,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
+	{ .compatible = "mediatek,mt8195-disp-ethdr",
+	  .data = (void *)MTK_DISP_OVL_ADAPTOR },
 	{ .compatible = "mediatek,mt2701-disp-pwm",
 	  .data = (void *)MTK_DISP_BLS },
 	{ .compatible = "mediatek,mt8173-disp-pwm",
@@ -809,6 +824,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
+		    comp_type == MTK_DISP_OVL_ADAPTOR ||
 		    comp_type == MTK_DISP_RDMA ||
 		    comp_type == MTK_DPI ||
 		    comp_type == MTK_DSI) {
@@ -909,6 +925,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
 	&mtk_disp_merge_driver,
+	&mtk_disp_ovl_adaptor_driver,
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
-- 
2.18.0

From james.clark at arm.com  Wed Aug 25 03:13:34 2021
From: james.clark at arm.com (James Clark)
Date: Wed, 25 Aug 2021 11:13:34 +0100
Subject: [PATCH v2 7/9] perf cs-etm: Create ETE decoder
In-Reply-To: <20210824083305.GE204566@leoy-ThinkPad-X240s>
References: <20210806134109.1182235-1-james.clark@arm.com>
 <20210806134109.1182235-8-james.clark@arm.com>
 <20210824083305.GE204566@leoy-ThinkPad-X240s>
Message-ID: <a677e5b6-ebef-039b-29df-b5ae6608d588@arm.com>



On 24/08/2021 09:33, Leo Yan wrote:
>> +static void cs_etm_decoder__gen_ete_config(struct cs_etm_trace_params *params,
>> +					   ocsd_ete_cfg *config)
>> +{
>> +	config->reg_configr = params->ete.reg_configr;
>> +	config->reg_traceidr = params->ete.reg_traceidr;
>> +	config->reg_idr0 = params->ete.reg_idr0;
>> +	config->reg_idr1 = params->ete.reg_idr1;
>> +	config->reg_idr2 = params->ete.reg_idr2;
>> +	config->reg_idr8 = params->ete.reg_idr8;
>> +	config->reg_devarch = params->ete.reg_devarch;
>> +	config->arch_ver = ARCH_AA64;
> Just a nitpick: if we connect with patch 02, it implement function
> cs_etm_decoder__get_etmv4_arch_ver().  We can extend it to a more
> general function cs_etm_decoder__get_arch_ver(); this can allow us to
> have a central place to calculate 'arch_ver' for different archs.
> 
> I understand your patch doesn't want to mix things between ETMv4 and
> ETE, either way is okay for me:

Hi Leo,

Yes that was one of the previous comments from Mike that the logic only applied
to ETMv4 so I made it v4 specific. The other arch_vers are fixed at the moment.
If we get a new one that needs changing depending on some config we can try to
add a generic function.

> 
> Reviewed-by: Leo Yan <leo.yan at linaro.org>
> 


From nancy.lin at mediatek.com  Wed Aug 25 03:05:23 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:23 +0800
Subject: [PATCH v4 09/17] soc: mediatek: add cmdq support of mtk-mmsys config
 API for mt8195 vdosys1
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-10-nancy.lin@mediatek.com>

Add cmdq support for mtk-mmsys config API.
The mmsys config register settings need to take effect with the other
HW settings(like OVL_ADAPTOR...) at the same vblanking time.

If we use CPU to write the mmsys reg, we can't guarantee all the
settings can be written in the same vblanking time.
Cmdq is used for this purpose. We prepare all the related HW settings
in one cmdq packet. The first command in the packet is "wait stream done",
and then following with all the HW settings. After the cmdq packet is
flush to GCE HW. The GCE waits for the "stream done event" to coming
and then starts flushing all the HW settings. This can guarantee all
the settings flush in the same vblanking.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mmsys.c       | 28 +++++++++++++++++++++-----
 include/linux/soc/mediatek/mtk-mmsys.h |  6 +++++-
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index cd59a4157731..e2bcd701ceb0 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -77,6 +77,7 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
+	struct cmdq_client_reg cmdq_base;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -117,7 +118,7 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
-			  u32 id, u32 val)
+			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
 	const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
@@ -140,10 +141,20 @@ void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
 	mask = mmsys_config[i].mask;
 	reg_val = val << mmsys_config[i].shift;
 
-	u32 tmp = readl(mmsys->regs + offset);
-
-	tmp = (tmp & ~mask) | reg_val;
-	writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	if (cmdq_pkt && mmsys->cmdq_base.size) {
+		cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+				    mmsys->cmdq_base.offset + offset, reg_val,
+				    mask);
+	} else {
+#endif
+		u32 tmp = readl(mmsys->regs + offset);
+
+		tmp = (tmp & ~mask) | reg_val;
+		writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	}
+#endif
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
@@ -167,6 +178,13 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 	}
 
 	mmsys->data = of_device_get_match_data(&pdev->dev);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
+	if (ret)
+		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
+#endif
+
 	platform_set_drvdata(pdev, mmsys);
 
 	clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index ef2a6d9a834b..9705d242849a 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -6,6 +6,10 @@
 #ifndef __MTK_MMSYS_H
 #define __MTK_MMSYS_H
 
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox/mtk-cmdq-mailbox.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
 enum mtk_ddp_comp_id;
 struct device;
 
@@ -75,6 +79,6 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id next);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
-			  u32 id, u32 val);
+			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt);
 
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:29 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:29 +0800
Subject: [PATCH v4 15/17] drm/mediatek: add ovl_adaptor support for MT8195
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-16-nancy.lin@mediatek.com>

Add ovl_adaptor driver for MT8195.
Ovl_adaptor is an encapsulated module and designed for simplified
DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and
an ETHDR. Two RDMAs merge into one layer, so this module support 4
layers.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  16 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 406 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   1 +
 4 files changed, 424 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index fb158a1e7f06..3abd27d7c91d 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -6,6 +6,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_disp_gamma.o \
 		  mtk_disp_merge.o \
 		  mtk_disp_ovl.o \
+		  mtk_disp_ovl_adaptor.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
 		  mtk_drm_ddp_comp.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 2446ad0a4977..6a4f4c42aedb 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -113,6 +113,22 @@ void mtk_rdma_enable_vblank(struct device *dev,
 			    void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_ovl_adaptor_clk_enable(struct device *dev);
+void mtk_ovl_adaptor_clk_disable(struct device *dev);
+void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
+			    unsigned int h, unsigned int vrefresh,
+			    unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
+				  struct mtk_plane_state *state,
+				  struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_adaptor_enable_vblank(struct device *dev,
+				   void (*vblank_cb)(void *),
+				   void *vblank_cb_data);
+void mtk_ovl_adaptor_disable_vblank(struct device *dev);
+void mtk_ovl_adaptor_start(struct device *dev);
+void mtk_ovl_adaptor_stop(struct device *dev);
+unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
+
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
 void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
new file mode 100644
index 000000000000..3b3806a78125
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_disp_drv.h"
+#include "mtk_ethdr.h"
+
+#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
+#define MTK_OVL_ADAPTOR_LAYER_NUM 4
+
+enum mtk_ovl_adaptor_comp_type {
+	OVL_ADAPTOR_TYPE_RDMA = 0,
+	OVL_ADAPTOR_TYPE_MERGE,
+	OVL_ADAPTOR_TYPE_NUM,
+};
+
+enum mtk_ovl_adaptor_comp_id {
+	OVL_ADAPTOR_MDP_RDMA0,
+	OVL_ADAPTOR_MDP_RDMA1,
+	OVL_ADAPTOR_MDP_RDMA2,
+	OVL_ADAPTOR_MDP_RDMA3,
+	OVL_ADAPTOR_MDP_RDMA4,
+	OVL_ADAPTOR_MDP_RDMA5,
+	OVL_ADAPTOR_MDP_RDMA6,
+	OVL_ADAPTOR_MDP_RDMA7,
+	OVL_ADAPTOR_MERGE0,
+	OVL_ADAPTOR_MERGE1,
+	OVL_ADAPTOR_MERGE2,
+	OVL_ADAPTOR_MERGE3,
+	OVL_ADAPTOR_ID_MAX
+};
+
+struct ovl_adaptor_comp_match {
+	enum mtk_ovl_adaptor_comp_type type;
+	int alias_id;
+};
+
+struct mtk_disp_ovl_adaptor {
+	struct device *ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
+	struct device *mmsys_dev;
+};
+
+static const char * const ovl_adaptor_comp_str[] = {
+	"OVL_ADAPTOR_MDP_RDMA0",
+	"OVL_ADAPTOR_MDP_RDMA1",
+	"OVL_ADAPTOR_MDP_RDMA2",
+	"OVL_ADAPTOR_MDP_RDMA3",
+	"OVL_ADAPTOR_MDP_RDMA4",
+	"OVL_ADAPTOR_MDP_RDMA5",
+	"OVL_ADAPTOR_MDP_RDMA6",
+	"OVL_ADAPTOR_MDP_RDMA7",
+	"OVL_ADAPTOR_MERGE0",
+	"OVL_ADAPTOR_MERGE1",
+	"OVL_ADAPTOR_MERGE2",
+	"OVL_ADAPTOR_MERGE3",
+	"OVL_ADAPTOR_ID_MAX"
+};
+
+static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
+	[OVL_ADAPTOR_TYPE_RDMA] = "vdo1_rdma",
+	[OVL_ADAPTOR_TYPE_MERGE] = "merge",
+};
+
+static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
+	[OVL_ADAPTOR_MDP_RDMA0] =	{ OVL_ADAPTOR_TYPE_RDMA, 0 },
+	[OVL_ADAPTOR_MDP_RDMA1] =	{ OVL_ADAPTOR_TYPE_RDMA, 1 },
+	[OVL_ADAPTOR_MDP_RDMA2] =	{ OVL_ADAPTOR_TYPE_RDMA, 2 },
+	[OVL_ADAPTOR_MDP_RDMA3] =	{ OVL_ADAPTOR_TYPE_RDMA, 3 },
+	[OVL_ADAPTOR_MDP_RDMA4] =	{ OVL_ADAPTOR_TYPE_RDMA, 4 },
+	[OVL_ADAPTOR_MDP_RDMA5] =	{ OVL_ADAPTOR_TYPE_RDMA, 5 },
+	[OVL_ADAPTOR_MDP_RDMA6] =	{ OVL_ADAPTOR_TYPE_RDMA, 6 },
+	[OVL_ADAPTOR_MDP_RDMA7] =	{ OVL_ADAPTOR_TYPE_RDMA, 7 },
+	[OVL_ADAPTOR_MERGE0] =	{ OVL_ADAPTOR_TYPE_MERGE, 1 },
+	[OVL_ADAPTOR_MERGE1] =	{ OVL_ADAPTOR_TYPE_MERGE, 2 },
+	[OVL_ADAPTOR_MERGE2] =	{ OVL_ADAPTOR_TYPE_MERGE, 3 },
+	[OVL_ADAPTOR_MERGE3] =	{ OVL_ADAPTOR_TYPE_MERGE, 4 },
+};
+
+static struct device *get_ovl_adaptor(struct device *parent)
+{
+	return device_find_child_by_name(parent, "mediatek-disp-ovl-adaptor");
+}
+
+void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
+				  struct mtk_plane_state *state,
+				  struct cmdq_pkt *cmdq_pkt)
+{
+	struct device *ovl_adaptor_dev = get_ovl_adaptor(dev);
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(ovl_adaptor_dev);
+	struct mtk_plane_pending_state *pending = &state->pending;
+	struct mtk_mdp_rdma_cfg rdma_config = {0};
+	struct device *rdma_l;
+	struct device *rdma_r;
+	struct device *merge;
+	const struct drm_format_info *fmt_info = drm_format_info(pending->format);
+	bool use_dual_pipe = false;
+	unsigned int l_w = 0;
+	unsigned int r_w = 0;
+
+	dev_dbg(dev, "%s+ idx:%d, enable:%d, fmt:0x%x\n", __func__, idx,
+		pending->enable, pending->format);
+	dev_dbg(dev, "addr 0x%lx, fb w:%d, {%d,%d,%d,%d}\n",
+		pending->addr, (pending->pitch / fmt_info->cpp[0]),
+		pending->x, pending->y, pending->width, pending->height);
+
+	rdma_l = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx];
+	rdma_r = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx + 1];
+	merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
+
+	if (!pending->enable) {
+		mtk_merge_disable(merge, cmdq_pkt);
+		mtk_mdp_rdma_stop(rdma_l, cmdq_pkt);
+		mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
+		mtk_ethdr_layer_config(dev, idx, state, cmdq_pkt);
+		return;
+	}
+
+	/* ETHDR is in 1T2P domain, width needs to be 2 pixels align */
+	pending->width = ALIGN_DOWN(pending->width, 2);
+
+	if (pending->width > MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH)
+		use_dual_pipe = true;
+
+	if (use_dual_pipe) {
+		l_w = (pending->width / 2) + ((pending->width / 2) % 2);
+		r_w = pending->width - l_w;
+	} else {
+		l_w = pending->width;
+	}
+	mtk_merge_advance_config(merge, l_w, r_w, pending->height, 0, 0, cmdq_pkt);
+	mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev, MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
+			     idx, pending->width / 2, cmdq_pkt);
+	mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev, MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
+			     idx, pending->height, cmdq_pkt);
+
+	rdma_config.csc_enable = fmt_info->is_yuv ? true : false;
+	rdma_config.profile = RDMA_CSC_FULL709_TO_RGB;
+	rdma_config.width = l_w;
+	rdma_config.height = pending->height;
+	rdma_config.addr0 = pending->addr;
+	rdma_config.pitch = pending->pitch;
+	rdma_config.fmt = pending->format;
+	mtk_mdp_rdma_config(rdma_l, &rdma_config, cmdq_pkt);
+
+	rdma_config.x_left = l_w;
+	rdma_config.width = r_w;
+	mtk_mdp_rdma_config(rdma_r, &rdma_config, cmdq_pkt);
+
+	mtk_merge_enable(merge, cmdq_pkt);
+	mtk_merge_unmute(merge, cmdq_pkt);
+
+	mtk_mdp_rdma_start(rdma_l, cmdq_pkt);
+	if (use_dual_pipe)
+		mtk_mdp_rdma_start(rdma_r, cmdq_pkt);
+	else
+		mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
+
+	mtk_ethdr_layer_config(dev, idx, state, cmdq_pkt);
+}
+
+void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
+			    unsigned int h, unsigned int vrefresh,
+			    unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	mtk_ethdr_config(dev, w, h, vrefresh, bpc, cmdq_pkt);
+}
+
+void mtk_ovl_adaptor_start(struct device *dev)
+{
+	mtk_ethdr_start(dev);
+}
+
+void mtk_ovl_adaptor_stop(struct device *dev)
+{
+	struct device *ovl_adaptor_dev = get_ovl_adaptor(dev);
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(ovl_adaptor_dev);
+	struct device *rdma_l;
+	struct device *rdma_r;
+	struct device *merge;
+	u32 i;
+
+	for (i = 0; i < MTK_OVL_ADAPTOR_LAYER_NUM; i++) {
+		rdma_l = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * i];
+		rdma_r = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * i + 1];
+		merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + i];
+
+		mtk_mdp_rdma_stop(rdma_l, NULL);
+		mtk_mdp_rdma_stop(rdma_r, NULL);
+		mtk_merge_stop(merge);
+	}
+
+	mtk_ethdr_stop(dev);
+}
+
+int mtk_ovl_adaptor_clk_enable(struct device *dev)
+{
+	struct device *ovl_adaptor_dev = get_ovl_adaptor(dev);
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(ovl_adaptor_dev);
+	struct device *comp;
+	int ret;
+	int i;
+
+	for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_ID_MAX; i++) {
+		comp = ovl_adaptor->ovl_adaptor_comp[i];
+
+		if (i < OVL_ADAPTOR_MERGE0)
+			ret = mtk_mdp_rdma_clk_enable(comp);
+		else
+			ret = mtk_merge_clk_enable(comp);
+		if (ret) {
+			dev_err(dev,
+				"Failed to enable clock %d, err %d-%s\n",
+				i, ret, ovl_adaptor_comp_str[i]);
+			goto clk_err;
+		}
+	}
+
+	mtk_ethdr_clk_enable(dev);
+	return ret;
+
+clk_err:
+	while (--i >= 0) {
+		comp = ovl_adaptor->ovl_adaptor_comp[i];
+		if (i < OVL_ADAPTOR_MERGE0)
+			mtk_mdp_rdma_clk_disable(comp);
+		else
+			mtk_merge_clk_disable(comp);
+	}
+	return ret;
+}
+
+void mtk_ovl_adaptor_clk_disable(struct device *dev)
+{
+	struct device *ovl_adaptor_dev = get_ovl_adaptor(dev);
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(ovl_adaptor_dev);
+	struct device *comp;
+	int i;
+
+	for (i = OVL_ADAPTOR_MDP_RDMA0; i < OVL_ADAPTOR_ID_MAX; i++) {
+		comp = ovl_adaptor->ovl_adaptor_comp[i];
+
+		if (i < OVL_ADAPTOR_MERGE0)
+			mtk_mdp_rdma_clk_disable(comp);
+		else
+			mtk_merge_clk_disable(comp);
+	}
+	mtk_ethdr_clk_disable(dev);
+}
+
+unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev)
+{
+	return MTK_OVL_ADAPTOR_LAYER_NUM;
+}
+
+void mtk_ovl_adaptor_enable_vblank(struct device *dev, void (*vblank_cb)(void *),
+				   void *vblank_cb_data)
+{
+	mtk_ethdr_enable_vblank(dev, vblank_cb, vblank_cb_data);
+}
+
+void mtk_ovl_adaptor_disable_vblank(struct device *dev)
+{
+	mtk_ethdr_disable_vblank(dev);
+}
+
+static int ovl_adaptor_comp_get_id(struct device *dev, struct device_node *node,
+				   enum mtk_ovl_adaptor_comp_type type)
+{
+	int alias_id = of_alias_get_id(node, private_comp_stem[type]);
+	int ret;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
+		if (comp_matches[i].type == type &&
+		    comp_matches[i].alias_id == alias_id)
+			return i;
+
+	dev_err(dev, "Failed to get id. type: %d, alias: %d\n", type, alias_id);
+	return -EINVAL;
+}
+
+static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = {
+	{
+		.compatible = "mediatek,mt8195-vdo1-rdma",
+		.data = (void *)OVL_ADAPTOR_TYPE_RDMA,
+	}, {
+		.compatible = "mediatek,mt8195-disp-merge",
+		.data = (void *)OVL_ADAPTOR_TYPE_MERGE,
+	},
+	{},
+};
+
+static int ovl_adaptor_comp_init(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
+	struct device_node *node, *parent;
+	struct platform_device *comp_pdev;
+	int i, ret;
+
+	parent = dev->parent->of_node->parent;
+
+	for_each_child_of_node(parent, node) {
+		const struct of_device_id *of_id;
+		enum mtk_ovl_adaptor_comp_type type;
+		int id;
+
+		of_id = of_match_node(mtk_ovl_adaptor_comp_dt_ids, node);
+		if (!of_id)
+			continue;
+
+		if (!of_device_is_available(node)) {
+			dev_info(dev, "Skipping disabled component %pOF\n",
+				 node);
+			continue;
+		}
+
+		type = (enum mtk_ovl_adaptor_comp_type)of_id->data;
+		id = ovl_adaptor_comp_get_id(dev, node, type);
+		if (id < 0) {
+			dev_warn(dev, "Skipping unknown component %pOF\n",
+				 node);
+			continue;
+		}
+
+		comp_pdev = of_find_device_by_node(node);
+		if (!comp_pdev) {
+			dev_warn(dev, "can't find platform device of node:%s\n",
+				 node->name);
+			return -ENODEV;
+		}
+		priv->ovl_adaptor_comp[id] = &comp_pdev->dev;
+
+		dev_info(dev, "[DRM]dev:%s, node:%s\n", dev_name(priv->ovl_adaptor_comp[id]),
+			 ovl_adaptor_comp_str[id]);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id ovl_adaptor_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-ethdr"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_disp_ovl_adaptor_driver_dt_match);
+
+static int mtk_disp_ovl_adaptor_probe(struct platform_device *pdev)
+{
+	struct mtk_disp_ovl_adaptor *priv;
+	struct device *dev = &pdev->dev;
+	struct device_node *phandle = dev->parent->of_node;
+	const struct of_device_id *of_id;
+	int ret;
+	int i;
+
+	dev_info(dev, "%s+\n", __func__);
+
+	of_id = of_match_node(ovl_adaptor_driver_dt_match, phandle);
+	if (!of_id)
+		return -ENODEV;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mmsys_dev = pdev->dev.platform_data;
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = ovl_adaptor_comp_init(dev);
+	if (ret) {
+		dev_notice(dev, "ovl_adaptor comp init fail\n");
+		return ret;
+	}
+
+	dev_info(dev, "%s-\n", __func__);
+	return ret;
+}
+
+static int mtk_disp_ovl_adaptor_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+struct platform_driver mtk_disp_ovl_adaptor_driver = {
+	.probe = mtk_disp_ovl_adaptor_probe,
+	.remove = mtk_disp_ovl_adaptor_remove,
+	.driver = {
+			.name = "mediatek-disp-ovl-adaptor",
+			.owner = THIS_MODULE,
+		},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index a58cebd01d35..1ad9f7edfcc7 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -51,6 +51,7 @@ extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
 extern struct platform_driver mtk_disp_merge_driver;
+extern struct platform_driver mtk_disp_ovl_adaptor_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:25 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:25 +0800
Subject: [PATCH v4 11/17] soc: mediatek: add mtk-mutex support for mt8195
 vdosys1
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-12-nancy.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys1.
The vdosys1 path component contains ovl_adaptor, merge5,
and dp_intf1. Ovl_adaptor is composed of several sub-elements,
so change it to support multi-bit control.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 270 ++++++++++++++++++-------------
 1 file changed, 162 insertions(+), 108 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index c177156ee2fa..588e378d1855 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -29,101 +29,130 @@
 
 #define INT_MUTEX				BIT(1)
 
-#define MT8167_MUTEX_MOD_DISP_PWM		1
-#define MT8167_MUTEX_MOD_DISP_OVL0		6
-#define MT8167_MUTEX_MOD_DISP_OVL1		7
-#define MT8167_MUTEX_MOD_DISP_RDMA0		8
-#define MT8167_MUTEX_MOD_DISP_RDMA1		9
-#define MT8167_MUTEX_MOD_DISP_WDMA0		10
-#define MT8167_MUTEX_MOD_DISP_CCORR		11
-#define MT8167_MUTEX_MOD_DISP_COLOR		12
-#define MT8167_MUTEX_MOD_DISP_AAL		13
-#define MT8167_MUTEX_MOD_DISP_GAMMA		14
-#define MT8167_MUTEX_MOD_DISP_DITHER		15
-#define MT8167_MUTEX_MOD_DISP_UFOE		16
-
-#define MT8183_MUTEX_MOD_DISP_RDMA0		0
-#define MT8183_MUTEX_MOD_DISP_RDMA1		1
-#define MT8183_MUTEX_MOD_DISP_OVL0		9
-#define MT8183_MUTEX_MOD_DISP_OVL0_2L		10
-#define MT8183_MUTEX_MOD_DISP_OVL1_2L		11
-#define MT8183_MUTEX_MOD_DISP_WDMA0		12
-#define MT8183_MUTEX_MOD_DISP_COLOR0		13
-#define MT8183_MUTEX_MOD_DISP_CCORR0		14
-#define MT8183_MUTEX_MOD_DISP_AAL0		15
-#define MT8183_MUTEX_MOD_DISP_GAMMA0		16
-#define MT8183_MUTEX_MOD_DISP_DITHER0		17
-
-#define MT8173_MUTEX_MOD_DISP_OVL0		11
-#define MT8173_MUTEX_MOD_DISP_OVL1		12
-#define MT8173_MUTEX_MOD_DISP_RDMA0		13
-#define MT8173_MUTEX_MOD_DISP_RDMA1		14
-#define MT8173_MUTEX_MOD_DISP_RDMA2		15
-#define MT8173_MUTEX_MOD_DISP_WDMA0		16
-#define MT8173_MUTEX_MOD_DISP_WDMA1		17
-#define MT8173_MUTEX_MOD_DISP_COLOR0		18
-#define MT8173_MUTEX_MOD_DISP_COLOR1		19
-#define MT8173_MUTEX_MOD_DISP_AAL		20
-#define MT8173_MUTEX_MOD_DISP_GAMMA		21
-#define MT8173_MUTEX_MOD_DISP_UFOE		22
-#define MT8173_MUTEX_MOD_DISP_PWM0		23
-#define MT8173_MUTEX_MOD_DISP_PWM1		24
-#define MT8173_MUTEX_MOD_DISP_OD		25
-
-#define MT8195_MUTEX_MOD_DISP_OVL0		0
-#define MT8195_MUTEX_MOD_DISP_WDMA0		1
-#define MT8195_MUTEX_MOD_DISP_RDMA0		2
-#define MT8195_MUTEX_MOD_DISP_COLOR0		3
-#define MT8195_MUTEX_MOD_DISP_CCORR0		4
-#define MT8195_MUTEX_MOD_DISP_AAL0		5
-#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
-#define MT8195_MUTEX_MOD_DISP_DITHER0		7
-#define MT8195_MUTEX_MOD_DISP_DSI0		8
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
-#define MT8195_MUTEX_MOD_DISP_OVL1		10
-#define MT8195_MUTEX_MOD_DISP_WDMA1		11
-#define MT8195_MUTEX_MOD_DISP_RDMA1		12
-#define MT8195_MUTEX_MOD_DISP_COLOR1		13
-#define MT8195_MUTEX_MOD_DISP_CCORR1		14
-#define MT8195_MUTEX_MOD_DISP_AAL1		15
-#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
-#define MT8195_MUTEX_MOD_DISP_DITHER1		17
-#define MT8195_MUTEX_MOD_DISP_DSI1		18
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
-#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
-#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
-#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
-#define MT8195_MUTEX_MOD_DISP_PWM0		27
-#define MT8195_MUTEX_MOD_DISP_PWM1		28
-
-#define MT2712_MUTEX_MOD_DISP_PWM2		10
-#define MT2712_MUTEX_MOD_DISP_OVL0		11
-#define MT2712_MUTEX_MOD_DISP_OVL1		12
-#define MT2712_MUTEX_MOD_DISP_RDMA0		13
-#define MT2712_MUTEX_MOD_DISP_RDMA1		14
-#define MT2712_MUTEX_MOD_DISP_RDMA2		15
-#define MT2712_MUTEX_MOD_DISP_WDMA0		16
-#define MT2712_MUTEX_MOD_DISP_WDMA1		17
-#define MT2712_MUTEX_MOD_DISP_COLOR0		18
-#define MT2712_MUTEX_MOD_DISP_COLOR1		19
-#define MT2712_MUTEX_MOD_DISP_AAL0		20
-#define MT2712_MUTEX_MOD_DISP_UFOE		22
-#define MT2712_MUTEX_MOD_DISP_PWM0		23
-#define MT2712_MUTEX_MOD_DISP_PWM1		24
-#define MT2712_MUTEX_MOD_DISP_OD0		25
-#define MT2712_MUTEX_MOD2_DISP_AAL1		33
-#define MT2712_MUTEX_MOD2_DISP_OD1		34
-
-#define MT2701_MUTEX_MOD_DISP_OVL		3
-#define MT2701_MUTEX_MOD_DISP_WDMA		6
-#define MT2701_MUTEX_MOD_DISP_COLOR		7
-#define MT2701_MUTEX_MOD_DISP_BLS		9
-#define MT2701_MUTEX_MOD_DISP_RDMA0		10
-#define MT2701_MUTEX_MOD_DISP_RDMA1		12
+#define MT8167_MUTEX_MOD_DISP_PWM		BIT(1)
+#define MT8167_MUTEX_MOD_DISP_OVL0		BIT(6)
+#define MT8167_MUTEX_MOD_DISP_OVL1		BIT(7)
+#define MT8167_MUTEX_MOD_DISP_RDMA0		BIT(8)
+#define MT8167_MUTEX_MOD_DISP_RDMA1		BIT(9)
+#define MT8167_MUTEX_MOD_DISP_WDMA0		BIT(10)
+#define MT8167_MUTEX_MOD_DISP_CCORR		BIT(11)
+#define MT8167_MUTEX_MOD_DISP_COLOR		BIT(12)
+#define MT8167_MUTEX_MOD_DISP_AAL		BIT(13)
+#define MT8167_MUTEX_MOD_DISP_GAMMA		BIT(14)
+#define MT8167_MUTEX_MOD_DISP_DITHER		BIT(15)
+#define MT8167_MUTEX_MOD_DISP_UFOE		BIT(16)
+
+#define MT8183_MUTEX_MOD_DISP_RDMA0		BIT(0)
+#define MT8183_MUTEX_MOD_DISP_RDMA1		BIT(1)
+#define MT8183_MUTEX_MOD_DISP_OVL0		BIT(9)
+#define MT8183_MUTEX_MOD_DISP_OVL0_2L		BIT(10)
+#define MT8183_MUTEX_MOD_DISP_OVL1_2L		BIT(11)
+#define MT8183_MUTEX_MOD_DISP_WDMA0		BIT(12)
+#define MT8183_MUTEX_MOD_DISP_COLOR0		BIT(13)
+#define MT8183_MUTEX_MOD_DISP_CCORR0		BIT(14)
+#define MT8183_MUTEX_MOD_DISP_AAL0		BIT(15)
+#define MT8183_MUTEX_MOD_DISP_GAMMA0		BIT(16)
+#define MT8183_MUTEX_MOD_DISP_DITHER0		BIT(17)
+
+#define MT8173_MUTEX_MOD_DISP_OVL0		BIT(11)
+#define MT8173_MUTEX_MOD_DISP_OVL1		BIT(12)
+#define MT8173_MUTEX_MOD_DISP_RDMA0		BIT(13)
+#define MT8173_MUTEX_MOD_DISP_RDMA1		BIT(14)
+#define MT8173_MUTEX_MOD_DISP_RDMA2		BIT(15)
+#define MT8173_MUTEX_MOD_DISP_WDMA0		BIT(16)
+#define MT8173_MUTEX_MOD_DISP_WDMA1		BIT(17)
+#define MT8173_MUTEX_MOD_DISP_COLOR0		BIT(18)
+#define MT8173_MUTEX_MOD_DISP_COLOR1		BIT(19)
+#define MT8173_MUTEX_MOD_DISP_AAL		BIT(20)
+#define MT8173_MUTEX_MOD_DISP_GAMMA		BIT(21)
+#define MT8173_MUTEX_MOD_DISP_UFOE		BIT(22)
+#define MT8173_MUTEX_MOD_DISP_PWM0		BIT(23)
+#define MT8173_MUTEX_MOD_DISP_PWM1		BIT(24)
+#define MT8173_MUTEX_MOD_DISP_OD		BIT(25)
+
+#define MT8195_MUTEX_MOD_DISP_OVL0		BIT(0)
+#define MT8195_MUTEX_MOD_DISP_WDMA0		BIT(1)
+#define MT8195_MUTEX_MOD_DISP_RDMA0		BIT(2)
+#define MT8195_MUTEX_MOD_DISP_COLOR0		BIT(3)
+#define MT8195_MUTEX_MOD_DISP_CCORR0		BIT(4)
+#define MT8195_MUTEX_MOD_DISP_AAL0		BIT(5)
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		BIT(6)
+#define MT8195_MUTEX_MOD_DISP_DITHER0		BIT(7)
+#define MT8195_MUTEX_MOD_DISP_DSI0		BIT(8)
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	BIT(9)
+#define MT8195_MUTEX_MOD_DISP_OVL1		BIT(10)
+#define MT8195_MUTEX_MOD_DISP_WDMA1		BIT(11)
+#define MT8195_MUTEX_MOD_DISP_RDMA1		BIT(12)
+#define MT8195_MUTEX_MOD_DISP_COLOR1		BIT(13)
+#define MT8195_MUTEX_MOD_DISP_CCORR1		BIT(14)
+#define MT8195_MUTEX_MOD_DISP_AAL1		BIT(15)
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		BIT(16)
+#define MT8195_MUTEX_MOD_DISP_DITHER1		BIT(17)
+#define MT8195_MUTEX_MOD_DISP_DSI1		BIT(18)
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	BIT(19)
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		BIT(20)
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		BIT(21)
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	BIT(22)
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	BIT(23)
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	BIT(24)
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	BIT(25)
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	BIT(26)
+#define MT8195_MUTEX_MOD_DISP_PWM0		BIT(27)
+#define MT8195_MUTEX_MOD_DISP_PWM1		BIT(28)
+
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA0 BIT(0)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA1 BIT(1)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA2 BIT(2)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA3 BIT(3)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA4 BIT(4)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA5 BIT(5)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA6 BIT(6)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA7 BIT(7)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE0 BIT(8)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE1 BIT(9)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE2 BIT(10)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE3 BIT(11)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE4 BIT(12)
+#define MT8195_MUTEX_MOD_DISP1_VPP2_DL_RELAY BIT(13)
+#define MT8195_MUTEX_MOD_DISP1_VPP3_DL_RELAY BIT(14)
+#define MT8195_MUTEX_MOD_DISP1_VDO0_DSC_DL_ASYNC BIT(15)
+#define MT8195_MUTEX_MOD_DISP1_VDO0_MERGE_DL_ASYNC BIT(16)
+#define MT8195_MUTEX_MOD_DISP1_VDO1_OUT_DL_RELAY BIT(17)
+#define MT8195_MUTEX_MOD_DISP1_DISP_MIXER BIT(18)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 BIT(19)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 BIT(20)
+#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 BIT(21)
+#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 BIT(22)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 BIT(23)
+#define MT8195_MUTEX_MOD_DISP1_HDR_MLOAD BIT(24)
+#define MT8195_MUTEX_MOD_DISP1_DPI0 BIT(25)
+#define MT8195_MUTEX_MOD_DISP1_DPI1 BIT(26)
+#define MT8195_MUTEX_MOD_DISP1_DP_INTF0 BIT(27)
+
+#define MT2712_MUTEX_MOD_DISP_PWM2		BIT(10)
+#define MT2712_MUTEX_MOD_DISP_OVL0		BIT(11)
+#define MT2712_MUTEX_MOD_DISP_OVL1		BIT(12)
+#define MT2712_MUTEX_MOD_DISP_RDMA0		BIT(13)
+#define MT2712_MUTEX_MOD_DISP_RDMA1		BIT(14)
+#define MT2712_MUTEX_MOD_DISP_RDMA2		BIT(15)
+#define MT2712_MUTEX_MOD_DISP_WDMA0		BIT(16)
+#define MT2712_MUTEX_MOD_DISP_WDMA1		BIT(17)
+#define MT2712_MUTEX_MOD_DISP_COLOR0		BIT(18)
+#define MT2712_MUTEX_MOD_DISP_COLOR1		BIT(19)
+#define MT2712_MUTEX_MOD_DISP_AAL0		BIT(20)
+#define MT2712_MUTEX_MOD_DISP_UFOE		BIT(22)
+#define MT2712_MUTEX_MOD_DISP_PWM0		BIT(23)
+#define MT2712_MUTEX_MOD_DISP_PWM1		BIT(24)
+#define MT2712_MUTEX_MOD_DISP_OD0		BIT(25)
+#define MT2712_MUTEX_MOD2_DISP_AAL1		BIT(33)
+#define MT2712_MUTEX_MOD2_DISP_OD1		BIT(34)
+
+#define MT2701_MUTEX_MOD_DISP_OVL		BIT(3)
+#define MT2701_MUTEX_MOD_DISP_WDMA		BIT(6)
+#define MT2701_MUTEX_MOD_DISP_COLOR		BIT(7)
+#define MT2701_MUTEX_MOD_DISP_BLS		BIT(9)
+#define MT2701_MUTEX_MOD_DISP_RDMA0		BIT(10)
+#define MT2701_MUTEX_MOD_DISP_RDMA1		BIT(12)
 
 #define MT2712_MUTEX_SOF_SINGLE_MODE		0
 #define MT2712_MUTEX_SOF_DSI0			1
@@ -174,7 +203,7 @@ enum mtk_mutex_sof_id {
 };
 
 struct mtk_mutex_data {
-	const unsigned int *mutex_mod;
+	const unsigned long *mutex_mod;
 	const unsigned int *mutex_sof;
 	const unsigned int mutex_mod_reg;
 	const unsigned int mutex_sof_reg;
@@ -189,7 +218,7 @@ struct mtk_mutex_ctx {
 	const struct mtk_mutex_data	*data;
 };
 
-static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
 	[DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
 	[DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
@@ -198,7 +227,7 @@ static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
 };
 
-static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
 	[DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
@@ -218,7 +247,7 @@ static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1,
 };
 
-static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL,
 	[DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR,
 	[DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR,
@@ -233,7 +262,7 @@ static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL,
 	[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
 	[DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
@@ -251,7 +280,7 @@ static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
 };
 
-static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0,
 	[DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0,
@@ -265,7 +294,7 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
 	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
 	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
@@ -279,6 +308,27 @@ static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
 	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
 	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
+	[DDP_COMPONENT_OVL_ADAPTOR] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA0 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA1 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA2 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA3 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA4 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA5 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA6 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA7 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE0 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE1 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE2 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE3 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_MLOAD |
+				      MT8195_MUTEX_MOD_DISP1_DISP_MIXER,
+	[DDP_COMPONENT_MERGE5] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE4,
+	[DDP_COMPONENT_DP_INTF1] = MT8195_MUTEX_MOD_DISP1_DP_INTF0,
 };
 
 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
@@ -436,17 +486,20 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DP_INTF0:
 		sof_id = MUTEX_SOF_DP_INTF0;
 		break;
+	case DDP_COMPONENT_DP_INTF1:
+		sof_id = MUTEX_SOF_DP_INTF1;
+		break;
 	default:
-		if (mtx->data->mutex_mod[id] < 32) {
+		if (mtx->data->mutex_mod[id] <= BIT(31)) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
 						    mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg |= 1 << mtx->data->mutex_mod[id];
+			reg |= mtx->data->mutex_mod[id];
 			writel_relaxed(reg, mtx->regs + offset);
 		} else {
 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg |= 1 << (mtx->data->mutex_mod[id] - 32);
+			reg |= (mtx->data->mutex_mod[id] >> 32);
 			writel_relaxed(reg, mtx->regs + offset);
 		}
 		return;
@@ -476,22 +529,23 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DPI0:
 	case DDP_COMPONENT_DPI1:
 	case DDP_COMPONENT_DP_INTF0:
+	case DDP_COMPONENT_DP_INTF1:
 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
 			       mtx->regs +
 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
 						  mutex->id));
 		break;
 	default:
-		if (mtx->data->mutex_mod[id] < 32) {
+		if (mtx->data->mutex_mod[id] <= BIT(31)) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
 						    mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg &= ~(1 << mtx->data->mutex_mod[id]);
+			reg &= ~(mtx->data->mutex_mod[id]);
 			writel_relaxed(reg, mtx->regs + offset);
 		} else {
 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg &= ~(1 << (mtx->data->mutex_mod[id] - 32));
+			reg &= ~(mtx->data->mutex_mod[id] >> 32);
 			writel_relaxed(reg, mtx->regs + offset);
 		}
 		break;
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:30 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:30 +0800
Subject: [PATCH v4 16/17] drm/mediatek: modify mediatek-drm for mt8195 multi
 mmsys support
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-17-nancy.lin@mediatek.com>

MT8195 have two mmsys. Modify drm for MT8195 multi-mmsys support.
The two mmsys (vdosys0 and vdosys1) will bring up two drm drivers,
only one drm driver register as the drm device.
Each drm driver binds its own component. The first bind drm driver
will allocate the drm device, and the last bind drm driver registers
the drm device to drm core. Each crtc path is created with the
corresponding drm driver data.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  25 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 360 +++++++++++++++++++-----
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   8 +-
 4 files changed, 320 insertions(+), 76 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 474efb844249..68cb15c38c3f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -737,21 +737,28 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 }
 
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
-			const enum mtk_ddp_comp_id *path, unsigned int path_len)
+			const enum mtk_ddp_comp_id *path, unsigned int path_len,
+			int priv_data_index)
 {
 	struct mtk_drm_private *priv = drm_dev->dev_private;
 	struct device *dev = drm_dev->dev;
 	struct mtk_drm_crtc *mtk_crtc;
 	unsigned int num_comp_planes = 0;
-	int pipe = priv->num_pipes;
 	int ret;
 	int i;
 	bool has_ctm = false;
 	uint gamma_lut_size = 0;
+	struct drm_crtc *tmp;
+	int crtc_i = 0;
 
 	if (!path)
 		return 0;
 
+	priv = priv->all_drm_private[priv_data_index];
+
+	drm_for_each_crtc(tmp, drm_dev)
+		crtc_i++;
+
 	for (i = 0; i < path_len; i++) {
 		enum mtk_ddp_comp_id comp_id = path[i];
 		struct device_node *node;
@@ -760,7 +767,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 		if (!node) {
 			dev_info(dev,
 				 "Not creating crtc %d because component %d is disabled or missing\n",
-				 pipe, comp_id);
+				 crtc_i, comp_id);
 			return 0;
 		}
 	}
@@ -816,25 +823,25 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 		ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
-						    pipe);
+						    crtc_i);
 		if (ret)
 			return ret;
 	}
 
-	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
+	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
 	if (ret < 0)
 		return ret;
 
 	if (gamma_lut_size)
 		drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
 	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
-	priv->num_pipes++;
 	mutex_init(&mtk_crtc->hw_lock);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	i = (priv->data->mmsys_dev_num > 1) ? 0 : drm_crtc_index(&mtk_crtc->base);
+
 	mtk_crtc->cmdq_client =
-			cmdq_mbox_create(mtk_crtc->mmsys_dev,
-					 drm_crtc_index(&mtk_crtc->base));
+			cmdq_mbox_create(mtk_crtc->mmsys_dev, i);
 	if (IS_ERR(mtk_crtc->cmdq_client)) {
 		dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
 			drm_crtc_index(&mtk_crtc->base));
@@ -844,7 +851,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 	if (mtk_crtc->cmdq_client) {
 		ret = of_property_read_u32_index(priv->mutex_node,
 						 "mediatek,gce-events",
-						 drm_crtc_index(&mtk_crtc->base),
+						 i,
 						 &mtk_crtc->cmdq_event);
 		if (ret) {
 			dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index cb9a36c48d4f..a57eb12d7c05 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -17,7 +17,8 @@
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
 			const enum mtk_ddp_comp_id *path,
-			unsigned int path_len);
+			unsigned int path_len,
+			int priv_data_index);
 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 			     struct mtk_plane_state *state);
 void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index ae8df7ecc872..782c791b368e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -166,6 +166,8 @@ static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.ext_path = mt2701_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
 	.shadow_register = true,
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
@@ -174,6 +176,8 @@ static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
 	.ext_path = mt7623_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
 	.shadow_register = true,
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
@@ -183,6 +187,8 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
 	.third_path = mt2712_mtk_ddp_third,
 	.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
@@ -190,6 +196,8 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
 	.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
 	.ext_path = mt8173_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
@@ -197,32 +205,219 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
 	.ext_path = mt8183_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
+	.mmsys_id = 0,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
 	.main_path = mt8195_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+	.mmsys_id = 0,
+	.mmsys_dev_num = 2,
 };
 
+static const struct of_device_id mtk_drm_of_ids[] = {
+	{ .compatible = "mediatek,mt2701-mmsys",
+	  .data = &mt2701_mmsys_driver_data},
+	{ .compatible = "mediatek,mt7623-mmsys",
+	  .data = &mt7623_mmsys_driver_data},
+	{ .compatible = "mediatek,mt2712-mmsys",
+	  .data = &mt2712_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8173-mmsys",
+	  .data = &mt8173_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8183-mmsys",
+	  .data = &mt8183_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
+	{ .compatible = "mediatek,mt8195-vdosys1",
+	  .data = &mt8195_vdosys1_driver_data},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
+
+static int mtk_drm_match(struct device *dev, void *data)
+{
+	if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
+		return true;
+	return false;
+}
+
+static int mtk_drm_get_drm_priv(struct device *dev,
+				struct mtk_drm_private **all_drm_priv,
+				int num)
+{
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct device_node *phandle = dev->parent->of_node;
+	const struct of_device_id *of_id;
+	struct device_node *node;
+	int cnt = 0;
+	struct device *drm_dev;
+
+	for_each_child_of_node(phandle->parent, node) {
+		struct platform_device *pdev;
+
+		of_id = of_match_node(mtk_drm_of_ids, node);
+		if (!of_id)
+			continue;
+
+		pdev = of_find_device_by_node(node);
+		if (!pdev)
+			continue;
+
+		drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
+		if (!drm_dev || !dev_get_drvdata(drm_dev))
+			continue;
+
+		all_drm_priv[cnt++] = dev_get_drvdata(drm_dev);
+		if (cnt == num)
+			break;
+	}
+
+	return 0;
+}
+
+static bool mtk_drm_check_last_drm_bind(struct device *dev)
+{
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
+	int cnt = 0;
+	int i;
+
+	mtk_drm_get_drm_priv(dev, all_drm_priv, drm_priv->data->mmsys_dev_num);
+
+	for (i = 0; i < MAX_CRTC; i++)
+		if (all_drm_priv[i] && all_drm_priv[i]->mtk_drm_bound)
+			cnt++;
+
+	return (drm_priv->data->mmsys_dev_num == cnt);
+}
+
+static bool mtk_drm_find_drm_dev(struct device *dev, struct drm_device **drm)
+{
+	struct device_node *phandle = dev->parent->of_node;
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
+	int i;
+
+	if (!drm_priv->data->mmsys_dev_num)
+		return false;
+
+	mtk_drm_get_drm_priv(dev, all_drm_priv, drm_priv->data->mmsys_dev_num);
+
+	for (i = 0; i < MAX_CRTC; i++) {
+		if (all_drm_priv[i] && all_drm_priv[i]->mtk_drm_bound) {
+			*drm = all_drm_priv[i]->drm;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int mtk_drm_setup_all_drm_private(struct device *dev)
+{
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
+	int mmsys_dev_num = drm_priv->data->mmsys_dev_num;
+	int i;
+	int j;
+
+	mtk_drm_get_drm_priv(dev, all_drm_priv, mmsys_dev_num);
+
+	for (i = 0; i < mmsys_dev_num; i++)
+		for (j = 0; j < mmsys_dev_num; j++)
+			all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
+
+	return 0;
+}
+
+static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
+{
+	const struct mtk_mmsys_driver_data *drv_data = private->data;
+	int ret = false;
+	int i;
+
+	if (drv_data->mmsys_dev_num == 1)
+		return true;
+
+	if (drv_data->main_path) {
+		for (i = 0; i < drv_data->main_len; i++)
+			if (drv_data->main_path[i] == comp_id)
+				ret |= true;
+
+		if (i == drv_data->main_len)
+			ret |= false;
+	}
+
+	if (drv_data->ext_path) {
+		for (i = 0; i < drv_data->ext_len; i++)
+			if (drv_data->ext_path[i] == comp_id)
+				ret |= true;
+
+		if (i == drv_data->ext_len)
+			ret |= false;
+	}
+
+	if (drv_data->third_path) {
+		for (i = 0; i < drv_data->third_len; i++)
+			if (drv_data->third_path[i] == comp_id)
+				ret |= true;
+
+		if (i == drv_data->third_len)
+			ret |= false;
+	}
+
+	return ret;
+}
+
+static int mtk_drm_check_mutex_dev(struct mtk_drm_private *private)
+{
+	struct platform_device *pdev;
+	struct mtk_drm_private *priv_i;
+	int ret;
+	int i;
+
+	for (i = 0; i < private->data->mmsys_dev_num; i++) {
+		priv_i = private->all_drm_private[i];
+
+		pdev = of_find_device_by_node(priv_i->mutex_node);
+		if (!pdev) {
+			dev_err(priv_i->dev, "Waiting for disp-mutex device %pOF\n",
+				priv_i->mutex_node);
+			ret = -EPROBE_DEFER;
+			goto err_put_mutex;
+		}
+		priv_i->mutex_dev = &pdev->dev;
+	}
+
+	return 0;
+
+err_put_mutex:
+	for (i = 0; i < private->data->mmsys_dev_num; i++) {
+		priv_i = private->all_drm_private[i];
+		of_node_put(priv_i->mutex_node);
+	}
+
+	return ret;
+}
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
+	struct mtk_drm_private *priv_n;
 	struct platform_device *pdev;
-	struct device_node *np;
+	struct device_node *np = NULL;
 	struct device *dma_dev;
 	int ret;
+	int i;
+	int j;
 
 	if (!iommu_present(&platform_bus_type))
 		return -EPROBE_DEFER;
 
-	pdev = of_find_device_by_node(private->mutex_node);
-	if (!pdev) {
-		dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
-			private->mutex_node);
-		of_node_put(private->mutex_node);
-		return -EPROBE_DEFER;
-	}
-	private->mutex_dev = &pdev->dev;
+	ret = mtk_drm_check_mutex_dev(private);
+	if (ret)
+		return ret;
 
 	ret = drmm_mode_config_init(drm);
 	if (ret)
@@ -241,33 +436,57 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
 	drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
 
-	ret = component_bind_all(drm->dev, drm);
-	if (ret)
-		goto put_mutex_dev;
+	for (i = 0; i < private->data->mmsys_dev_num; i++) {
+		drm->dev_private = private->all_drm_private[i];
+		ret = component_bind_all(private->all_drm_private[i]->dev, drm);
+		if (ret)
+			goto put_mutex_dev;
+	}
 
 	/*
 	 * We currently support two fixed data streams, each optional,
 	 * and each statically assigned to a crtc:
 	 * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
 	 */
-	ret = mtk_drm_crtc_create(drm, private->data->main_path,
-				  private->data->main_len);
-	if (ret < 0)
-		goto err_component_unbind;
-	/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
-	ret = mtk_drm_crtc_create(drm, private->data->ext_path,
-				  private->data->ext_len);
-	if (ret < 0)
-		goto err_component_unbind;
-
-	ret = mtk_drm_crtc_create(drm, private->data->third_path,
-				  private->data->third_len);
-	if (ret < 0)
-		goto err_component_unbind;
+	for (i = 0; i < MAX_CRTC; i++) {
+		for (j = 0; j < private->data->mmsys_dev_num; j++) {
+			priv_n = private->all_drm_private[j];
+
+			if (i == 0 && priv_n->data->main_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
+							  priv_n->data->main_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->main_path[0]];
+
+				continue;
+			} else if (i == 1 && priv_n->data->ext_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->ext_path,
+							  priv_n->data->ext_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->ext_path[0]];
+
+				continue;
+			} else if (i == 2 && priv_n->data->third_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->third_path,
+							  priv_n->data->third_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->third_path[0]];
+
+				continue;
+			}
+		}
+	}
 
 	/* Use OVL device for all DMA memory allocations */
-	np = private->comp_node[private->data->main_path[0]] ?:
-	     private->comp_node[private->data->ext_path[0]];
 	pdev = of_find_device_by_node(np);
 	if (!pdev) {
 		ret = -ENODEV;
@@ -276,7 +495,8 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	}
 
 	dma_dev = &pdev->dev;
-	private->dma_dev = dma_dev;
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		private->all_drm_private[i]->dma_dev = dma_dev;
 
 	/*
 	 * Configure the DMA segment size to make sure we get contiguous IOVA
@@ -304,9 +524,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	return 0;
 
 err_component_unbind:
-	component_unbind_all(drm->dev, drm);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		component_unbind_all(private->all_drm_private[i]->dev, drm);
 put_mutex_dev:
-	put_device(private->mutex_dev);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		put_device(private->all_drm_private[i]->mutex_dev);
+
 	return ret;
 }
 
@@ -371,12 +594,21 @@ static int mtk_drm_bind(struct device *dev)
 	struct drm_device *drm;
 	int ret;
 
-	drm = drm_dev_alloc(&mtk_drm_driver, dev);
-	if (IS_ERR(drm))
-		return PTR_ERR(drm);
+	if (!mtk_drm_find_drm_dev(dev, &drm)) {
+		drm = drm_dev_alloc(&mtk_drm_driver, dev);
+		if (IS_ERR(drm))
+			return PTR_ERR(drm);
+		drm->dev_private = private;
+	}
 
-	drm->dev_private = private;
+	private->dev = dev;
 	private->drm = drm;
+	private->mtk_drm_bound = true;
+
+	if (!mtk_drm_check_last_drm_bind(dev))
+		return 0;
+
+	mtk_drm_setup_all_drm_private(dev);
 
 	ret = mtk_drm_kms_init(drm);
 	if (ret < 0)
@@ -401,10 +633,13 @@ static void mtk_drm_unbind(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
 
-	drm_dev_unregister(private->drm);
-	mtk_drm_kms_deinit(private->drm);
-	drm_dev_put(private->drm);
-	private->num_pipes = 0;
+	/* for multi mmsys dev, unregister drm dev in mmsys master */
+	if (private->data->mmsys_id == 0) {
+		drm_dev_unregister(private->drm);
+		mtk_drm_kms_deinit(private->drm);
+		drm_dev_put(private->drm);
+	}
+	private->mtk_drm_bound = false;
 	private->drm = NULL;
 }
 
@@ -487,50 +722,40 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	{ }
 };
 
-static const struct of_device_id mtk_drm_of_ids[] = {
-	{ .compatible = "mediatek,mt2701-mmsys",
-	  .data = &mt2701_mmsys_driver_data},
-	{ .compatible = "mediatek,mt7623-mmsys",
-	  .data = &mt7623_mmsys_driver_data},
-	{ .compatible = "mediatek,mt2712-mmsys",
-	  .data = &mt2712_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8173-mmsys",
-	  .data = &mt8173_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8183-mmsys",
-	  .data = &mt8183_mmsys_driver_data},
-	{.compatible = "mediatek,mt8195-vdosys0",
-	  .data = &mt8195_vdosys0_driver_data},
-	{ }
-};
-MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-
 static int mtk_drm_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *phandle = dev->parent->of_node;
 	const struct of_device_id *of_id;
+	const struct mtk_mmsys_driver_data *drv_data;
 	struct mtk_drm_private *private;
 	struct device_node *node;
 	struct component_match *match = NULL;
 	int ret;
 	int i;
 
+	of_id = of_match_node(mtk_drm_of_ids, phandle);
+	if (!of_id)
+		return -ENODEV;
+
+	drv_data = of_id->data;
 	private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
 	if (!private)
 		return -ENOMEM;
 
+	private->all_drm_private = devm_kmalloc_array(dev, drv_data->mmsys_dev_num,
+						      sizeof(*private->all_drm_private),
+						      GFP_KERNEL);
+	if (!private->all_drm_private)
+		return -ENOMEM;
+
+	private->data = drv_data;
 	private->mmsys_dev = dev->parent;
 	if (!private->mmsys_dev) {
 		dev_err(dev, "Failed to get MMSYS device\n");
 		return -ENODEV;
 	}
 
-	of_id = of_match_node(mtk_drm_of_ids, phandle);
-	if (!of_id)
-		return -ENODEV;
-
-	private->data = of_id->data;
-
 	/* Iterate over sibling DISP function blocks */
 	for_each_child_of_node(phandle->parent, node) {
 		const struct of_device_id *of_id;
@@ -550,7 +775,13 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		comp_type = (enum mtk_ddp_comp_type)of_id->data;
 
 		if (comp_type == MTK_DISP_MUTEX) {
-			private->mutex_node = of_node_get(node);
+			int id;
+
+			id = of_alias_get_id(node, "mutex");
+			if (id < 0 || id == drv_data->mmsys_id) {
+				private->mutex_node = of_node_get(node);
+				dev_dbg(dev, "get mutex for mmsys %d", drv_data->mmsys_id);
+			}
 			continue;
 		}
 
@@ -561,6 +792,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
 			continue;
 		}
 
+		if (!mtk_drm_find_mmsys_comp(private, comp_id))
+			continue;
+
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 1ad9f7edfcc7..b87ba900c8e2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -29,14 +29,15 @@ struct mtk_mmsys_driver_data {
 	unsigned int third_len;
 
 	bool shadow_register;
+	unsigned int mmsys_id;
+	unsigned int mmsys_dev_num;
 };
 
 struct mtk_drm_private {
 	struct drm_device *drm;
 	struct device *dma_dev;
-
-	unsigned int num_pipes;
-
+	bool mtk_drm_bound;
+	struct device *dev;
 	struct device_node *mutex_node;
 	struct device *mutex_dev;
 	struct device *mmsys_dev;
@@ -44,6 +45,7 @@ struct mtk_drm_private {
 	struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_ID_MAX];
 	const struct mtk_mmsys_driver_data *data;
 	struct drm_atomic_state *suspend_state;
+	struct mtk_drm_private **all_drm_private;
 };
 
 extern struct platform_driver mtk_disp_aal_driver;
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:17 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:17 +0800
Subject: [PATCH v4 03/17] dt-bindings: mediatek: add ethdr definition for
 mt8195
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-4-nancy.lin@mediatek.com>

Add vdosys1 ETHDR definition.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../display/mediatek/mediatek,ethdr.yaml      | 144 ++++++++++++++++++
 1 file changed, 144 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
new file mode 100644
index 000000000000..64d5349cdf8f
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
@@ -0,0 +1,144 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek ethdr Device Tree Bindings
+
+maintainers:
+  - CK Hu <ck.hu at mediatek.com>
+  - Nancy.Lin <nancy.lin at mediatek.com>
+
+description: |
+  ETHDR is designed for HDR video and graphics conversion in the external display path.
+  It handles multiple HDR input types and performs tone mapping, color space/color
+  format conversion, and then combine different layers, output the required HDR or
+  SDR signal to the subsequent display path. This engine is composed of two video
+  frontends, two graphic frontends, one video backend and a mixer.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-disp-ethdr
+  reg:
+    maxItems: 7
+  reg-names:
+    items:
+      - const: mixer
+      - const: vdo_fe0
+      - const: vdo_fe1
+      - const: gfx_fe0
+      - const: gfx_fe1
+      - const: vdo_be
+      - const: adl_ds
+  interrupts:
+    minItems: 1
+  iommus:
+    description: The compatible property is DMA function blocks.
+      Should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for
+      details.
+    minItems: 1
+    maxItems: 2
+  clocks:
+    items:
+      - description: mixer clock
+      - description: video frontend 0 clock
+      - description: video frontend 1 clock
+      - description: graphic frontend 0 clock
+      - description: graphic frontend 1 clock
+      - description: video backend clock
+      - description: autodownload and menuload clock
+      - description: video frontend 0 async clock
+      - description: video frontend 1 async clock
+      - description: graphic frontend 0 async clock
+      - description: graphic frontend 1 async clock
+      - description: video backend async clock
+      - description: ethdr top clock
+  clock-names:
+    items:
+      - const: mixer
+      - const: vdo_fe0
+      - const: vdo_fe1
+      - const: gfx_fe0
+      - const: gfx_fe1
+      - const: vdo_be
+      - const: adl_ds
+      - const: vdo_fe0_async
+      - const: vdo_fe1_async
+      - const: gfx_fe0_async
+      - const: gfx_fe1_async
+      - const: vdo_be_async
+      - const: ethdr_top
+  power-domains:
+    maxItems: 1
+  resets:
+    maxItems: 5
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: The register of display function block to be set by gce.
+      There are 4 arguments in this property, gce node, subsys id, offset and
+      register size. The subsys id is defined in the gce header of each chips
+      include/include/dt-bindings/gce/<chip>-gce.h, mapping to the register of
+      display function block.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+
+    disp_ethdr at 1c114000 {
+            compatible = "mediatek,mt8195-disp-ethdr";
+            reg = <0 0x1c114000 0 0x1000>,
+                  <0 0x1c115000 0 0x1000>,
+                  <0 0x1c117000 0 0x1000>,
+                  <0 0x1c119000 0 0x1000>,
+                  <0 0x1c11A000 0 0x1000>,
+                  <0 0x1c11B000 0 0x1000>,
+                  <0 0x1c11C000 0 0x1000>;
+            reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+                        "vdo_be", "adl_ds";
+            mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x4000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0x5000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0x7000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0x9000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0xA000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0xB000 0x1000>,
+                                      <&gce1 SUBSYS_1c11XXXX 0xC000 0x1000>;
+            clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_BE>,
+                     <&vdosys1 CLK_VDO1_26M_SLOW>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE0_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE1_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE0_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE1_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_BE_DL_ASYNC>,
+                     <&topckgen CLK_TOP_ETHDR_SEL>;
+            clock-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+                          "vdo_be", "adl_ds", "vdo_fe0_async", "vdo_fe1_async",
+                          "gfx_fe0_async", "gfx_fe1_async","vdo_be_async",
+                          "ethdr_top";
+            power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+            iommus = <&iommu_vpp M4U_PORT_L3_HDR_DS>,
+                     <&iommu_vpp M4U_PORT_L3_HDR_ADL>;
+            interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>; /* disp mixer */
+            resets = <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC>;
+    };
+
+...
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:24 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:24 +0800
Subject: [PATCH v4 10/17] soc: mediatek: mmsys: Add reset controller support
 for MT8195 vdosys1
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-11-nancy.lin@mediatek.com>

Among other features the mmsys driver should implement a reset
controller to be able to reset different bits from their space.

For MT8195 vdosys1, many async modules need to reset after
the display pipe stops and restart.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h |  1 +
 drivers/soc/mediatek/mtk-mmsys.c    | 76 +++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h    |  1 +
 3 files changed, 78 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index 648baaec112b..f67801c42fd9 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -123,6 +123,7 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER		(0 << 0)
 
+#define MT8195_VDO1_SW0_RST_B           0x1d0
 #define MT8195_VDO1_MERGE0_ASYNC_CFG_WD	0xe30
 #define MT8195_VDO1_MERGE1_ASYNC_CFG_WD	0xe40
 #define MT8195_VDO1_MERGE2_ASYNC_CFG_WD	0xe50
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index e2bcd701ceb0..5e6c116e589a 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -4,10 +4,12 @@
  * Author: James Liao <jamesjj.liao at mediatek.com>
  */
 
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/reset-controller.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 
 #include "mtk-mmsys.h"
@@ -16,6 +18,8 @@
 #include "mt8365-mmsys.h"
 #include "mt8195-mmsys.h"
 
+#define MMSYS_SW_RESET_PER_REG 32
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.clk_driver = "clk-mt2701-mm",
 	.routes = mmsys_default_routing_table,
@@ -72,12 +76,15 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
 	.config = mmsys_mt8195_config_table,
 	.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
+	.sw_reset_start = MT8195_VDO1_SW0_RST_B,
 };
 
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
 	struct cmdq_client_reg cmdq_base;
+	spinlock_t lock; /* protects mmsys_sw_rst_b reg */
+	struct reset_controller_dev rcdev;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -158,6 +165,63 @@ void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
+static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
+				  bool assert)
+{
+	struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
+	unsigned long flags;
+	u32 reg;
+	int i;
+	u32 offset;
+
+	offset = (id / MMSYS_SW_RESET_PER_REG) * sizeof(u32);
+	id = id % MMSYS_SW_RESET_PER_REG;
+
+	spin_lock_irqsave(&mmsys->lock, flags);
+
+	reg = readl_relaxed(mmsys->regs + mmsys->data->sw_reset_start + offset);
+
+	if (assert)
+		reg &= ~BIT(id);
+	else
+		reg |= BIT(id);
+
+	writel_relaxed(reg, mmsys->regs + mmsys->data->sw_reset_start + offset);
+
+	spin_unlock_irqrestore(&mmsys->lock, flags);
+
+	return 0;
+}
+
+static int mtk_mmsys_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return mtk_mmsys_reset_update(rcdev, id, true);
+}
+
+static int mtk_mmsys_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return mtk_mmsys_reset_update(rcdev, id, false);
+}
+
+static int mtk_mmsys_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	int ret;
+
+	ret = mtk_mmsys_reset_assert(rcdev, id);
+	if (ret)
+		return ret;
+
+	usleep_range(1000, 1100);
+
+	return mtk_mmsys_reset_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops mtk_mmsys_reset_ops = {
+	.assert = mtk_mmsys_reset_assert,
+	.deassert = mtk_mmsys_reset_deassert,
+	.reset = mtk_mmsys_reset,
+};
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -185,6 +249,18 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
 #endif
 
+	spin_lock_init(&mmsys->lock);
+
+	mmsys->rcdev.owner = THIS_MODULE;
+	mmsys->rcdev.nr_resets = 64;
+	mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
+	mmsys->rcdev.of_node = pdev->dev.of_node;
+	ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Couldn't register mmsys reset controller: %d\n", ret);
+		return ret;
+	}
+
 	platform_set_drvdata(pdev, mmsys);
 
 	clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver,
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 825857d8d7f4..d84f5cb78f8c 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -100,6 +100,7 @@ struct mtk_mmsys_driver_data {
 	const unsigned int num_routes;
 	const struct mtk_mmsys_config *config;
 	const unsigned int num_configs;
+	u32 sw_reset_start;
 };
 
 /*
-- 
2.18.0

From james.clark at arm.com  Wed Aug 25 03:14:20 2021
From: james.clark at arm.com (James Clark)
Date: Wed, 25 Aug 2021 11:14:20 +0100
Subject: [PATCH v2 0/9] Support ETE decoding
In-Reply-To: <20210824084720.GG204566@leoy-ThinkPad-X240s>
References: <20210806134109.1182235-1-james.clark@arm.com>
 <20210824084720.GG204566@leoy-ThinkPad-X240s>
Message-ID: <77fe6cd4-3e2e-aa60-9aa4-8fa03d08e640@arm.com>



On 24/08/2021 09:47, Leo Yan wrote:
> Hi Mathieu, Suzuki, Mike,
> 
> On Fri, Aug 06, 2021 at 02:41:00PM +0100, James Clark wrote:
>> Changes since v1:
>>  * Re-implement with a new magic number instead of piggybacking on ETMv4
>>  * Improve comments and function name around cs_etm_decoder__get_etmv4_arch_ver()
>>  * Add a warning for unrecognised magic numbers
>>  * Split typo fix into new commit
>>  * Add Leo's reviewed-by tags
>>  * Create a new struct for ETE config (cs_ete_trace_params) instead of re-using ETMv4 config
>>
>> Applies to perf/core f3c33cbd922
>> Also available at https://gitlab.arm.com/linux-arm/linux-jc/-/tree/james-ete-v2
> 
> I have finished the review for this patch series and it's good form for
> me.  Since this patch series is to enable new feature for ETE, it's
> good if any of you could review as well before merging.
> 

Thanks for the reviews Leo!

> Thanks,
> Leo
> 


From elver at google.com  Wed Aug 25 03:14:40 2021
From: elver at google.com (Marco Elver)
Date: Wed, 25 Aug 2021 12:14:40 +0200
Subject: [PATCH 0/4] ARM: Support KFENCE feature
In-Reply-To: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
Message-ID: <CANpmjNMnU5P9xsDhgeBKQR7Tg-3cHPkMNx7906yYwEAj85sNWg@mail.gmail.com>

On Wed, 25 Aug 2021 at 11:17, Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> The patch 1~3 is to support KFENCE feature on ARM.
>
> NOTE:
> The context of patch2/3 changes in arch/arm/mm/fault.c is based on link[1],
> which make some refactor and cleanup about page fault.
>
> kfence_test is not useful when kfence is not enabled, skip kfence test
> when kfence not enabled in patch4.
>
> I tested the kfence_test on ARM QEMU with or without ARM_LPAE and all passed.

Thank you for enabling KFENCE on ARM -- I'll leave arch-code review to
an ARM maintainer.

However, as said on the patch, please drop the change to the
kfence_test and associated changes. This is working as intended; while
you claim that it takes a long time to run when disabled, when running
manually you just should not run it when disabled. There are CI
systems that rely on the KUnit test output and the fact that the
various test cases say "not ok" etc. Changing that would mean such CI
systems would no longer fail if KFENCE was accidentally disabled (once
KFENCE is enabled on various CI, which we'd like to do at some point).
There are ways to fail the test faster, but they all complicate the
test for no good reason. (And the addition of a new exported function
that is essentially useless.)

Thanks,
-- Marco


From nancy.lin at mediatek.com  Wed Aug 25 03:05:22 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:22 +0800
Subject: [PATCH v4 08/17] soc: mediatek: add mtk-mmsys config API for mt8195
 vdosys1
In-Reply-To: <20210825100531.5653-1-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
Message-ID: <20210825100531.5653-9-nancy.lin@mediatek.com>

Add mmsys config API. The config API is used for config mmsys reg.
Some mmsys regs need to be setting according to the HW engine binding
to the mmsys simultaneously.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 62 ++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 33 ++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       | 10 +++++
 include/linux/soc/mediatek/mtk-mmsys.h | 16 +++++++
 4 files changed, 121 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index f19ec72c1243..648baaec112b 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -123,6 +123,21 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER		(0 << 0)
 
+#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD	0xe30
+#define MT8195_VDO1_MERGE1_ASYNC_CFG_WD	0xe40
+#define MT8195_VDO1_MERGE2_ASYNC_CFG_WD	0xe50
+#define MT8195_VDO1_MERGE3_ASYNC_CFG_WD	0xe60
+#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD	0xe70
+#define MT8195_VDO1_HDR_TOP_CFG		0xd00
+#define MT8195_VDO1_MIXER_IN1_ALPHA	0xd30
+#define MT8195_VDO1_MIXER_IN2_ALPHA	0xd34
+#define MT8195_VDO1_MIXER_IN3_ALPHA	0xd38
+#define MT8195_VDO1_MIXER_IN4_ALPHA	0xd3c
+#define MT8195_VDO1_MIXER_IN1_PAD	0xd40
+#define MT8195_VDO1_MIXER_IN2_PAD	0xd44
+#define MT8195_VDO1_MIXER_IN3_PAD	0xd48
+#define MT8195_VDO1_MIXER_IN4_PAD	0xd4c
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	{
 		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -247,4 +262,51 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	}
 };
 
+/*
+ * mtk_mmsys_config table is used for config mmsys reg in runtime.
+ * MMSYS_CONFIG_MERGE_ASYNC_WIDTH: config merge async width
+ * MMSYS_CONFIG_MERGE_ASYNC_HEIGHT: config merge async height
+ * MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH: config hdr_be async width
+ * MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT: config hdr_be async height
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_ODD: config mixer odd channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN: config mixer even channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_CH_SWAP: config mixer input RGB channel swap
+ * MMSYS_CONFIG_HDR_ALPHA_SEL: config alpha source
+ * MMSYS_CONFIG_MIXER_IN_MODE: config mixer pad mode(bypass/even extend mode)
+ * MMSYS_CONFIG_MIXER_IN_BIWIDTH: config mixer pad width. formula: width / 2 - 1
+ */
+static const struct mtk_mmsys_config mmsys_mt8195_config_table[] = {
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(4, 4), 4},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 1, MT8195_VDO1_HDR_TOP_CFG, GENMASK(20, 20), 20},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 2, MT8195_VDO1_HDR_TOP_CFG, GENMASK(21, 21), 21},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 3, MT8195_VDO1_HDR_TOP_CFG, GENMASK(22, 22), 22},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 4, MT8195_VDO1_HDR_TOP_CFG, GENMASK(23, 23), 23},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 2, MT8195_VDO1_MIXER_IN2_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 3, MT8195_VDO1_MIXER_IN3_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 2, MT8195_VDO1_MIXER_IN2_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 3, MT8195_VDO1_MIXER_IN3_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(31, 16), 16},
+};
+
 #endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 7365731c9fd7..cd59a4157731 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -70,6 +70,8 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 	.clk_driver = "clk-mt8195-vdo1",
 	.routes = mmsys_mt8195_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+	.config = mmsys_mt8195_config_table,
+	.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
 };
 
 struct mtk_mmsys {
@@ -114,6 +116,37 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
+void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
+			  u32 id, u32 val)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
+	u32 reg_val;
+	u32 mask;
+	u32 offset;
+	int i;
+
+	if (!mmsys->data->num_configs)
+		return;
+
+	for (i = 0; i < mmsys->data->num_configs; i++)
+		if (config == mmsys_config[i].config && id == mmsys_config[i].id)
+			break;
+
+	if (i == mmsys->data->num_configs)
+		return;
+
+	offset = mmsys_config[i].addr;
+	mask = mmsys_config[i].mask;
+	reg_val = val << mmsys_config[i].shift;
+
+	u32 tmp = readl(mmsys->regs + offset);
+
+	tmp = (tmp & ~mask) | reg_val;
+	writel(tmp, mmsys->regs + offset);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 5f3e2bf0c40b..825857d8d7f4 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -86,10 +86,20 @@ struct mtk_mmsys_routes {
 	u32 val;
 };
 
+struct mtk_mmsys_config {
+	enum mtk_mmsys_config_type config;
+	u32 id;
+	u32 addr;
+	u32 mask;
+	u32 shift;
+};
+
 struct mtk_mmsys_driver_data {
 	const char *clk_driver;
 	const struct mtk_mmsys_routes *routes;
 	const unsigned int num_routes;
+	const struct mtk_mmsys_config *config;
+	const unsigned int num_configs;
 };
 
 /*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 619392221a52..ef2a6d9a834b 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -53,6 +53,19 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_ID_MAX,
 };
 
+enum mtk_mmsys_config_type {
+	MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
+	MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
+	MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH,
+	MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT,
+	MMSYS_CONFIG_HDR_ALPHA_SEL,
+	MMSYS_CONFIG_MIXER_IN_ALPHA_ODD,
+	MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN,
+	MMSYS_CONFIG_MIXER_IN_CH_SWAP,
+	MMSYS_CONFIG_MIXER_IN_MODE,
+	MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+};
+
 void mtk_mmsys_ddp_connect(struct device *dev,
 			   enum mtk_ddp_comp_id cur,
 			   enum mtk_ddp_comp_id next);
@@ -61,4 +74,7 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id cur,
 			      enum mtk_ddp_comp_id next);
 
+void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
+			  u32 id, u32 val);
+
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0

From nancy.lin at mediatek.com  Wed Aug 25 03:05:14 2021
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Wed, 25 Aug 2021 18:05:14 +0800
Subject: [PATCH v4 00/17] Add MediaTek SoC DRM (vdosys1) support for mt8195
Message-ID: <20210825100531.5653-1-nancy.lin@mediatek.com>

The hardware path of vdosys1 with DPTx output need to go through by several modules, such as, OVL_ADAPTOR and MERGE.

Add DRM and these modules support by the patches below:

Changes in v4:
- use merge common driver for merge1~4.
- refine ovl_adaptor rdma driver.
- use ovl_adaptor ddp_comp function instead of ethdr.
- modify for reviewer's comment in v3.

Changes in v3:
- modify for reviewer's comment in v2.
- add vdosys1 2 pixels align limit.
- add mixer odd offset support.

Changes in v2:
- Merge PSEUDO_OVL and ETHDR into one DRM component.
- Add mmsys config API for vdosys1 hardware setting.
- Add mmsys reset control using linux reset framework.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

This series are based on the following patch:
[1] arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
[2] arm64: dts: mt8195: add IOMMU and smi nodes
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
[3] [01/24] dt-bindings: mediatek: mt8195: Add binding for MM IOMMU
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210630023504.18177-2-yong.wu at mediatek.com/
[4] Add gce support for mt8195
    https://patchwork.kernel.org/project/linux-mediatek/list/?series=515599
[5] Add MediaTek SoC DRM (vdosys0) support for mt8195
    https://patchwork.kernel.org/project/linux-mediatek/list/?series=531695
[6] [v8,1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header file
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210806023606.16867-2-Christine.Zhu at mediatek.com/

Nancy.Lin (17):
  dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
  dt-bindings: mediatek: add vdosys1 MERGE property for mt8195
  dt-bindings: mediatek: add ethdr definition for mt8195
  dt-bindings: mediatek: Add #reset-cells to mmsys system controller
  dt-bindings: reset: mt8195: add vdosys1 reset control bit
  arm64: dts: mt8195: add display node for vdosys1
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
  soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1
  soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195
    vdosys1
  soc: mediatek: mmsys: Add reset controller support for MT8195 vdosys1
  soc: mediatek: add mtk-mutex support for mt8195 vdosys1
  drm/mediatek: add display MDP RDMA support for MT8195
  drm/mediatek: add display merge api support for MT8195
  drm/mediatek: add ETHDR support for MT8195
  drm/mediatek: add ovl_adaptor support for MT8195
  drm/mediatek: modify mediatek-drm for mt8195 multi mmsys support
  drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |   3 +
 .../display/mediatek/mediatek,ethdr.yaml      | 144 ++++++
 .../display/mediatek/mediatek,mdp-rdma.yaml   |  77 ++++
 .../display/mediatek/mediatek,merge.yaml      |   3 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 221 +++++++++
 drivers/gpu/drm/mediatek/Makefile             |   5 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  29 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     |  78 +++-
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 406 +++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       |  25 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h       |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  15 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        | 377 +++++++++++++---
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   9 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c          | 424 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_ethdr.h          |  25 ++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c       | 306 +++++++++++++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h       |  37 ++
 drivers/soc/mediatek/mt8195-mmsys.h           | 199 ++++++++
 drivers/soc/mediatek/mtk-mmsys.c              | 137 ++++++
 drivers/soc/mediatek/mtk-mmsys.h              |  11 +
 drivers/soc/mediatek/mtk-mutex.c              | 270 ++++++-----
 include/dt-bindings/reset/mt8195-resets.h     |  12 +
 include/linux/soc/mediatek/mtk-mmsys.h        |  22 +
 25 files changed, 2644 insertions(+), 195 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mdp-rdma.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

-- 
2.18.0

From patchwork-bot+netdevbpf at kernel.org  Wed Aug 25 03:20:09 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 25 Aug 2021 10:20:09 +0000
Subject: [PATCH net-next] net: dsa: mt7530: manually set up VLAN ID 0
In-Reply-To: <20210824165253.1691315-1-dqfext@gmail.com>
References: <20210824165253.1691315-1-dqfext@gmail.com>
Message-ID: <162988680906.8958.16937803471017689459.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (refs/heads/master):

On Wed, 25 Aug 2021 00:52:52 +0800 you wrote:
> The driver was relying on dsa_slave_vlan_rx_add_vid to add VLAN ID 0. After
> the blamed commit, VLAN ID 0 won't be set up anymore, breaking software
> bridging fallback on VLAN-unaware bridges.
> 
> Manually set up VLAN ID 0 to fix this.
> 
> Fixes: 06cfb2df7eb0 ("net: dsa: don't advertise 'rx-vlan-filter' when not needed")
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> 
> [...]

Here is the summary with links:
  - [net-next] net: dsa: mt7530: manually set up VLAN ID 0
    https://git.kernel.org/netdev/net-next/c/1ca8a193cade

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From catalin.marinas at arm.com  Wed Aug 25 03:20:46 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 25 Aug 2021 11:20:46 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
Message-ID: <20210825102044.GA3420@arm.com>

+ hch

On Tue, Aug 24, 2021 at 08:59:22PM +0200, David Hildenbrand wrote:
> On 24.08.21 20:46, Robin Murphy wrote:
> > On 2021-08-24 19:28, Mike Rapoport wrote:
> > > On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
> > > > On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
> > > > > it seems there is a regression in arm64 memory mapping in 5.14, since it
> > > > > fails on Rockchip RK3328 when the pl330 dmac tries to map with:
> > > > > 
> > > > >  ------------[ cut here ]------------
> > > > >  WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
> > > > >  Modules linked in: spi_rockchip(+) fuse
> > > > >  CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
> > > > >  Hardware name: Pine64 Rock64 (DT)
> > > > >  pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
> > > > >  pc : dma_map_resource+0x68/0xc0
> > > > >  lr : pl330_prep_slave_fifo+0x78/0xd0
> > > > >  sp : ffff800012102ae0
> > > > >  x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
> > > > >  x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
> > > > >  x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
> > > > >  x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
> > > > >  x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> > > > >  x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
> > > > >  x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
> > > > >  x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
> > > > >  x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
> > > > >  x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
> > > > >  Call trace:
> > > > >    dma_map_resource+0x68/0xc0
> > > > >    pl330_prep_slave_sg+0x58/0x220
> > > > >    rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
> > > > >    rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
> > > > [...]
> > > > > Note: This does not relate to the spi driver - when disabling this device in
> > > > > the device tree it fails for any other (i2s, for instance) which uses dma.
> > > > > Commenting out the failing check at [1], however, helps and the mapping
> > > > > works again.
> > > 
> > > > Do you know which address dma_map_resource() is trying to map (maybe
> > > > add some printk())? It's not supposed to map RAM, hence the warning.
> > > > Random guess, the address is 0xff190800 (based on the x1 above but the
> > > > regs might as well be mangled).
> > > 
> > > 0xff190800 will cause this warning for sure. It has a memory map, but it is
> > > not RAM so old version of pfn_valid() would return 0 and the new one
> > > returns 1.
> > 
> > How does that happen, though? It's not a memory address, and it's not
> > even within the bounds of anywhere there should or could be memory. This
> > SoC has a simple memory map - everything from 0 to 0xfeffffff goes to
> > the DRAM controller (which may not all be populated, and may have pieces
> > carved out by secure firmware), while 0xff000000-0xffffffff is MMIO. Why
> > do we have pages (or at least the assumption of pages) for somewhere
> > which by all rights should not have them?
> 
> Simple: we allocate the vmemmap for whole sections (e.g., 128 MiB) to avoid
> any such hacks. If there is a memory hole, it gets a memmap as well.
> 
> Tricking pfn_valid() into returning "false" where we actually have a memmap
> only makes it look like there is no memmap; but there is one, and
> it's PG_reserved.

I can see the documentation for pfn_valid() does not claim anything more
than the presence of an memmap entry. But I wonder whether the confusion
is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
assumes __va() can be used on pfn_valid(), though I suspect it relies on
the calling function to check that the resource was RAM. The arm64
kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
standard memcpy on it, which wouldn't work for I/O (should we change
this check to pfn_is_map_memory() for arm64?).

> > > > Either pfn_valid() gets confused in 5.14 or something is wrong with the
> > > > DT. I have a suspicion it's the former since reverting the above commit
> > > > makes it disappear.
> > > 
> > > I think pfn_valid() actually behaves as expected but the caller is wrong
> > > because pfn_valid != RAM (this applies btw to !arm64 as well).
> > > 
> > > 	/* Don't allow RAM to be mapped */
> > > 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> > > 		return DMA_MAPPING_ERROR;
> > > 
> > > Alex, can you please try this patch:
> > 
> > That will certainly paper over the issue, but it's avoiding the question
> > of what went wrong with the memory map in the first place. The comment
> > is indeed a bit inaccurate, but ultimately dma_map_resource() exists for
> > addresses that would be wrong to pass to dma_map_page(), so I believe
> > pfn_valid() is still the correct check.
> 
> If we want to check for RAM, pfn_valid() would be wrong. If we want to check
> for "is there a memmap, for whatever lives or does not live there",
> pfn_valid() is the right check.

So what should the DMA code use instead? Last time we needed something
similar, the recommendation was to use pfn_to_online_page(). Mike is
suggesting memblock_is_memory().

Given how later we are in the -rc cycle, I suggest we revert Anshuman's
commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID") and try to
assess the implications in 5.15 (the patch doesn't seem to have the
arm64 maintainers' ack anyway ;)).

Thanks.

-- 
Catalin


From broonie at kernel.org  Wed Aug 25 03:22:39 2021
From: broonie at kernel.org (Mark Brown)
Date: Wed, 25 Aug 2021 11:22:39 +0100
Subject: [PATCH v5 00/11] ASoC: mediatek: Add support for MT8195 SoC
In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
Message-ID: <162988521424.7213.9083414971201440076.b4-ty@kernel.org>

On Thu, 19 Aug 2021 16:41:33 +0800, Trevor Wu wrote:
> This series of patches adds support for Mediatek AFE of MT8195 SoC.
> Patches are based on broonie tree "for-next" branch.
> 
> Changes since v4:
>   - removed sof related code
> 
> Changes since v3:
>   - fixed warnings found by kernel test robot
>   - removed unused critical section
>   - corrected the lock protected sections on etdm driver
>   - added DPTX and HDMITX audio support
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[01/11] ASoC: mediatek: mt8195: update mediatek common driver
        commit: cab2b9e5fc0e868ed8453ef4f433c795bda8bf84
[02/11] ASoC: mediatek: mt8195: support audsys clock control
        commit: d62ad762f67585acfb5e03f71b28a52dc4604cf2
[03/11] ASoC: mediatek: mt8195: support etdm in platform driver
        commit: 1de9a54acafba2f0e3ea2856ad0b22556d59ec45
[04/11] ASoC: mediatek: mt8195: support adda in platform driver
        commit: 3de3eba588bb7f6c39bf12de5761ff75c53b9961
[05/11] ASoC: mediatek: mt8195: support pcm in platform driver
        commit: 1f95c019115cc503c4c47fd7108675a56cdb29b4
[06/11] ASoC: mediatek: mt8195: add platform driver
        commit: 6746cc858259985a945a07075a19ec4d24352407
[07/11] dt-bindings: mediatek: mt8195: add audio afe document
        commit: b5bac34fcfb444e33f532e291ad1394ca05887e8
[08/11] ASoC: mediatek: mt8195: add machine driver with mt6359, rt1019 and rt5682
        commit: 40d605df0a7bf7723ed690f502f364c5320de440
[09/11] ASoC: mediatek: mt8195: add DPTX audio support
        commit: e581e3014cc4acee9025aa5704cf85a36a572b95
[10/11] ASoC: mediatek: mt8195: add HDMITX audio support
        commit: ef46cd42ecf00f0468df3ad1bf0f30db9634a04a
[11/11] dt-bindings: mediatek: mt8195: add mt8195-mt6359-rt1019-rt5682 document
        commit: 5f8c991e8950971cd1f81b61f79c83a511ad9fc8

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From enric.balletbo at collabora.com  Wed Aug 25 03:26:25 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 12:26:25 +0200
Subject: [PATCH v3 0/7] Add support to the mmsys driver to be a reset
 controller
Message-ID: <20210825102632.601614-1-enric.balletbo@collabora.com>

Dear all,

The following patchset is a reimplementation of the patch sent by Jitao
Shi [1] some time ago. As suggested by Chun-Kuang Hu, this time the
reset is done using the reset API, where the mmsys driver is the reset
controller and the mtk_dsi driver is the reset consumer.

Note that the first patch is kind of unrelated change, it's just a
cleanup but is needed if you want to apply all the following patches
cleanly.

This patchset is important in order to have the DSI panel working on some
kukui MT8183 Chromebooks (i.e Lenovo IdeaPad Duet). Without it, you just
get a black screen.

Best regards,
  Enric

[1] https://lore.kernel.org/linux-arm-kernel/20210420132614.150242-4-jitao.shi at mediatek.com/


Changes in v3:
- Based on top of the patch that converts mmsys to schema
- Fix typo in the commit description

Changes in v2:
- Fix build test ERROR Reported-by: kernel test robot <lkp at intel.com>
- Added a new patch to describe the dsi reset optional property.

Enric Balletbo i Serra (7):
  arm64: dts: mediatek: Move reset controller constants into common
    location
  dt-bindings: mediatek: Add #reset-cells to mmsys system controller
  dt-bindings: display: mediatek: add dsi reset optional property
  arm64: dts: mt8173: Add the mmsys reset bit to reset the dsi0
  arm64: dts: mt8183: Add the mmsys reset bit to reset the dsi0
  soc: mediatek: mmsys: Add reset controller support
  drm/mediatek: mtk_dsi: Reset the dsi0 hardware

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |  4 ++
 .../display/mediatek/mediatek,dsi.txt         |  6 ++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi      |  2 +
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  5 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c            |  5 +-
 drivers/soc/mediatek/mtk-mmsys.c              | 69 +++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h              |  2 +
 drivers/watchdog/mtk_wdt.c                    |  6 +-
 .../mt2712-resets.h                           |  0
 include/dt-bindings/reset/mt8173-resets.h     |  2 +
 .../mt8183-resets.h                           |  3 +
 .../mt8192-resets.h                           |  0
 12 files changed, 98 insertions(+), 6 deletions(-)
 rename include/dt-bindings/{reset-controller => reset}/mt2712-resets.h (100%)
 rename include/dt-bindings/{reset-controller => reset}/mt8183-resets.h (98%)
 rename include/dt-bindings/{reset-controller => reset}/mt8192-resets.h (100%)

-- 
2.30.2



From enric.balletbo at collabora.com  Wed Aug 25 03:26:26 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 12:26:26 +0200
Subject: [PATCH v3 1/7] arm64: dts: mediatek: Move reset controller constants
 into common location
In-Reply-To: <20210825102632.601614-1-enric.balletbo@collabora.com>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
Message-ID: <20210825122613.v3.1.I514d9aafff3a062f751b37d3fea7402f67595b86@changeid>

The DT binding includes for reset controllers are located in
include/dt-bindings/reset/. Move the Mediatek reset constants in there.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
---

(no changes since v2)

Changes in v2:
- Fix build test ERROR Reported-by: kernel test robot <lkp at intel.com>

 arch/arm64/boot/dts/mediatek/mt8183.dtsi                    | 2 +-
 drivers/watchdog/mtk_wdt.c                                  | 6 +++---
 .../dt-bindings/{reset-controller => reset}/mt2712-resets.h | 0
 .../dt-bindings/{reset-controller => reset}/mt8183-resets.h | 0
 .../dt-bindings/{reset-controller => reset}/mt8192-resets.h | 0
 5 files changed, 4 insertions(+), 4 deletions(-)
 rename include/dt-bindings/{reset-controller => reset}/mt2712-resets.h (100%)
 rename include/dt-bindings/{reset-controller => reset}/mt8183-resets.h (100%)
 rename include/dt-bindings/{reset-controller => reset}/mt8192-resets.h (100%)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index d1efc4a38a41..9f72701a3b2e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -11,7 +11,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/memory/mt8183-larb-port.h>
 #include <dt-bindings/power/mt8183-power.h>
-#include <dt-bindings/reset-controller/mt8183-resets.h>
+#include <dt-bindings/reset/mt8183-resets.h>
 #include <dt-bindings/phy/phy.h>
 #include <dt-bindings/thermal/thermal.h>
 #include "mt8183-pinfunc.h"
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index 16b6aff324a7..6986bc740465 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -9,9 +9,9 @@
  * Based on sunxi_wdt.c
  */
 
-#include <dt-bindings/reset-controller/mt2712-resets.h>
-#include <dt-bindings/reset-controller/mt8183-resets.h>
-#include <dt-bindings/reset-controller/mt8192-resets.h>
+#include <dt-bindings/reset/mt2712-resets.h>
+#include <dt-bindings/reset/mt8183-resets.h>
+#include <dt-bindings/reset/mt8192-resets.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/init.h>
diff --git a/include/dt-bindings/reset-controller/mt2712-resets.h b/include/dt-bindings/reset/mt2712-resets.h
similarity index 100%
rename from include/dt-bindings/reset-controller/mt2712-resets.h
rename to include/dt-bindings/reset/mt2712-resets.h
diff --git a/include/dt-bindings/reset-controller/mt8183-resets.h b/include/dt-bindings/reset/mt8183-resets.h
similarity index 100%
rename from include/dt-bindings/reset-controller/mt8183-resets.h
rename to include/dt-bindings/reset/mt8183-resets.h
diff --git a/include/dt-bindings/reset-controller/mt8192-resets.h b/include/dt-bindings/reset/mt8192-resets.h
similarity index 100%
rename from include/dt-bindings/reset-controller/mt8192-resets.h
rename to include/dt-bindings/reset/mt8192-resets.h
-- 
2.30.2



From enric.balletbo at collabora.com  Wed Aug 25 03:26:27 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 12:26:27 +0200
Subject: [PATCH v3 2/7] dt-bindings: mediatek: Add #reset-cells to mmsys
 system controller
In-Reply-To: <20210825102632.601614-1-enric.balletbo@collabora.com>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
Message-ID: <20210825122613.v3.2.I3f7f1c9a8e46be07d1757ddf4e0097535f3a7d41@changeid>

The mmsys system controller exposes a set of memory client resets and
needs to specify the #reset-cells property in order to advertise the
number of cells needed to describe each of the resets.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
---

Changes in v3:
- Based on top of the patch that converts mmsys to schema

 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml      | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 2d4ff0ce387b..96ca16927a06 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -42,6 +42,9 @@ properties:
   "#clock-cells":
     const: 1
 
+  '#reset-cells':
+    const: 1
+
 required:
   - compatible
   - reg
@@ -55,4 +58,5 @@ examples:
         compatible = "mediatek,mt8173-mmsys", "syscon";
         reg = <0x14000000 0x1000>;
         #clock-cells = <1>;
+        #reset-cells = <1>;
     };
-- 
2.30.2



From enric.balletbo at collabora.com  Wed Aug 25 03:26:28 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 12:26:28 +0200
Subject: [PATCH v3 3/7] dt-bindings: display: mediatek: add dsi reset optional
 property
In-Reply-To: <20210825102632.601614-1-enric.balletbo@collabora.com>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
Message-ID: <20210825122613.v3.3.Ifec72a83f224b62f24cfc967edfe78c5d276b2e3@changeid>

Update device tree binding documentation for the dsi to add the optional
property to reset the dsi controller.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Acked-by: Rob Herring <robh at kernel.org>
---

(no changes since v2)

Changes in v2:
- Added a new patch to describe the dsi reset optional property.

 .../devicetree/bindings/display/mediatek/mediatek,dsi.txt   | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
index 8238a86686be..3209b700ded6 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
@@ -19,6 +19,11 @@ Required properties:
   Documentation/devicetree/bindings/graph.txt. This port should be connected
   to the input port of an attached DSI panel or DSI-to-eDP encoder chip.
 
+Optional properties:
+- resets: list of phandle + reset specifier pair, as described in [1].
+
+[1] Documentation/devicetree/bindings/reset/reset.txt
+
 MIPI TX Configuration Module
 ============================
 
@@ -45,6 +50,7 @@ dsi0: dsi at 1401b000 {
 	clocks = <&mmsys MM_DSI0_ENGINE>, <&mmsys MM_DSI0_DIGITAL>,
 		 <&mipi_tx0>;
 	clock-names = "engine", "digital", "hs";
+	resets = <&mmsys MT8173_MMSYS_SW0_RST_B_DISP_DSI0>;
 	phys = <&mipi_tx0>;
 	phy-names = "dphy";
 
-- 
2.30.2



From enric.balletbo at collabora.com  Wed Aug 25 03:26:29 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 12:26:29 +0200
Subject: [PATCH v3 4/7] arm64: dts: mt8173: Add the mmsys reset bit to reset
 the dsi0
In-Reply-To: <20210825102632.601614-1-enric.balletbo@collabora.com>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
Message-ID: <20210825122613.v3.4.I7bd7d9a8da5e2894711b700a1127e6902a2b2f1d@changeid>

Reset the DSI hardware is needed to prevent different settings between
the bootloader and the kernel.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Acked-by: Rob Herring <robh at kernel.org>
---

(no changes since v1)

 arch/arm64/boot/dts/mediatek/mt8173.dtsi  | 2 ++
 include/dt-bindings/reset/mt8173-resets.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 17d70e2f5394..97ea3f9960b1 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -1036,6 +1036,7 @@ mmsys: syscon at 14000000 {
 			assigned-clocks = <&topckgen CLK_TOP_MM_SEL>;
 			assigned-clock-rates = <400000000>;
 			#clock-cells = <1>;
+			#reset-cells = <1>;
 			mboxes = <&gce 0 CMDQ_THR_PRIO_HIGHEST>,
 				 <&gce 1 CMDQ_THR_PRIO_HIGHEST>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
@@ -1262,6 +1263,7 @@ dsi0: dsi at 1401b000 {
 				 <&mmsys CLK_MM_DSI0_DIGITAL>,
 				 <&mipi_tx0>;
 			clock-names = "engine", "digital", "hs";
+			resets = <&mmsys MT8173_MMSYS_SW0_RST_B_DISP_DSI0>;
 			phys = <&mipi_tx0>;
 			phy-names = "dphy";
 			status = "disabled";
diff --git a/include/dt-bindings/reset/mt8173-resets.h b/include/dt-bindings/reset/mt8173-resets.h
index ba8636eda5ae..6a60c7cecc4c 100644
--- a/include/dt-bindings/reset/mt8173-resets.h
+++ b/include/dt-bindings/reset/mt8173-resets.h
@@ -27,6 +27,8 @@
 #define MT8173_INFRA_GCE_FAXI_RST       40
 #define MT8173_INFRA_MMIOMMURST         47
 
+/* MMSYS resets */
+#define MT8173_MMSYS_SW0_RST_B_DISP_DSI0	25
 
 /*  PERICFG resets */
 #define MT8173_PERI_UART0_SW_RST        0
-- 
2.30.2



From enric.balletbo at collabora.com  Wed Aug 25 03:26:32 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 12:26:32 +0200
Subject: [PATCH v3 7/7] drm/mediatek: mtk_dsi: Reset the dsi0 hardware
In-Reply-To: <20210825102632.601614-1-enric.balletbo@collabora.com>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
Message-ID: <20210825122613.v3.7.Idbb4727ddf00ba2fe796b630906baff10d994d89@changeid>

Reset dsi0 HW to default when power on. This prevents to have different
settingis between the bootloader and the kernel.

As not all Mediatek boards have the reset consumer configured in their
board description, also is not needed on all of them, the reset is optional,
so the change is compatible with all boards.

Cc: Jitao Shi <jitao.shi at mediatek.com>
Suggested-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
---

Changes in v3:
- Fix typo in the commit description

 drivers/gpu/drm/mediatek/mtk_dsi.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index ae403c67cbd9..d8b81e2ab841 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -11,6 +11,7 @@
 #include <linux/of_platform.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
 
 #include <video/mipi_display.h>
 #include <video/videomode.h>
@@ -980,8 +981,10 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
 	struct mtk_dsi *dsi = dev_get_drvdata(dev);
 
 	ret = mtk_dsi_encoder_init(drm, dsi);
+	if (ret)
+		return ret;
 
-	return ret;
+	return device_reset_optional(dev);
 }
 
 static void mtk_dsi_unbind(struct device *dev, struct device *master,
-- 
2.30.2



From enric.balletbo at collabora.com  Wed Aug 25 03:26:31 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 12:26:31 +0200
Subject: [PATCH v3 6/7] soc: mediatek: mmsys: Add reset controller support
In-Reply-To: <20210825102632.601614-1-enric.balletbo@collabora.com>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
Message-ID: <20210825122613.v3.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d@changeid>

Among other features the mmsys driver should implement a reset
controller to be able to reset different bits from their space.

Cc: Jitao Shi <jitao.shi at mediatek.com>
Suggested-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
---

(no changes since v1)

 drivers/soc/mediatek/mtk-mmsys.c | 69 ++++++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h |  2 +
 2 files changed, 71 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index a78e88f27b62..855a3a50840c 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -4,10 +4,12 @@
  * Author: James Liao <jamesjj.liao at mediatek.com>
  */
 
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/reset-controller.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 
 #include "mtk-mmsys.h"
@@ -62,6 +64,8 @@ static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
+	spinlock_t lock; /* protects mmsys_sw_rst_b reg */
+	struct reset_controller_dev rcdev;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -101,6 +105,59 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
+static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
+				  bool assert)
+{
+	struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
+	unsigned long flags;
+	u32 reg;
+	int i;
+
+	spin_lock_irqsave(&mmsys->lock, flags);
+
+	reg = readl_relaxed(mmsys->regs + MMSYS_SW0_RST_B);
+
+	if (assert)
+		reg &= ~BIT(id);
+	else
+		reg |= BIT(id);
+
+	writel_relaxed(reg, mmsys->regs + MMSYS_SW0_RST_B);
+
+	spin_unlock_irqrestore(&mmsys->lock, flags);
+
+	return 0;
+}
+
+static int mtk_mmsys_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return mtk_mmsys_reset_update(rcdev, id, true);
+}
+
+static int mtk_mmsys_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return mtk_mmsys_reset_update(rcdev, id, false);
+}
+
+static int mtk_mmsys_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	int ret;
+
+	ret = mtk_mmsys_reset_assert(rcdev, id);
+	if (ret)
+		return ret;
+
+	usleep_range(1000, 1100);
+
+	return mtk_mmsys_reset_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops mtk_mmsys_reset_ops = {
+	.assert = mtk_mmsys_reset_assert,
+	.deassert = mtk_mmsys_reset_deassert,
+	.reset = mtk_mmsys_reset,
+};
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -120,6 +177,18 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	spin_lock_init(&mmsys->lock);
+
+	mmsys->rcdev.owner = THIS_MODULE;
+	mmsys->rcdev.nr_resets = 32;
+	mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
+	mmsys->rcdev.of_node = pdev->dev.of_node;
+	ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Couldn't register mmsys reset controller: %d\n", ret);
+		return ret;
+	}
+
 	mmsys->data = of_device_get_match_data(&pdev->dev);
 	platform_set_drvdata(pdev, mmsys);
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 9e2b81bd38db..8b0ed05117ea 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -78,6 +78,8 @@
 #define DSI_SEL_IN_RDMA				0x1
 #define DSI_SEL_IN_MASK				0x1
 
+#define MMSYS_SW0_RST_B				0x140
+
 struct mtk_mmsys_routes {
 	u32 from_comp;
 	u32 to_comp;
-- 
2.30.2



From enric.balletbo at collabora.com  Wed Aug 25 03:26:30 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 12:26:30 +0200
Subject: [PATCH v3 5/7] arm64: dts: mt8183: Add the mmsys reset bit to reset
 the dsi0
In-Reply-To: <20210825102632.601614-1-enric.balletbo@collabora.com>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
Message-ID: <20210825122613.v3.5.I933f1532d7a1b2910843a9644c86a7d94a4b44e1@changeid>

Reset the DSI hardware is needed to prevent different settings between
the bootloader and the kernel.

While here, also remove the undocumented and also not used
'mediatek,syscon-dsi' property.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Acked-by: Rob Herring <robh at kernel.org>
---

(no changes since v1)

 arch/arm64/boot/dts/mediatek/mt8183.dtsi  | 3 ++-
 include/dt-bindings/reset/mt8183-resets.h | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 9f72701a3b2e..7c47a76b3d02 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1251,6 +1251,7 @@ mmsys: syscon at 14000000 {
 			compatible = "mediatek,mt8183-mmsys", "syscon";
 			reg = <0 0x14000000 0 0x1000>;
 			#clock-cells = <1>;
+			#reset-cells = <1>;
 			mboxes = <&gce 0 CMDQ_THR_PRIO_HIGHEST>,
 				 <&gce 1 CMDQ_THR_PRIO_HIGHEST>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
@@ -1365,11 +1366,11 @@ dsi0: dsi at 14014000 {
 			reg = <0 0x14014000 0 0x1000>;
 			interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_LOW>;
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
-			mediatek,syscon-dsi = <&mmsys 0x140>;
 			clocks = <&mmsys CLK_MM_DSI0_MM>,
 				 <&mmsys CLK_MM_DSI0_IF>,
 				 <&mipi_tx0>;
 			clock-names = "engine", "digital", "hs";
+			resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>;
 			phys = <&mipi_tx0>;
 			phy-names = "dphy";
 		};
diff --git a/include/dt-bindings/reset/mt8183-resets.h b/include/dt-bindings/reset/mt8183-resets.h
index a1bbd41e0d12..48c5d2de0a38 100644
--- a/include/dt-bindings/reset/mt8183-resets.h
+++ b/include/dt-bindings/reset/mt8183-resets.h
@@ -80,6 +80,9 @@
 
 #define MT8183_INFRACFG_SW_RST_NUM				128
 
+/* MMSYS resets */
+#define MT8183_MMSYS_SW0_RST_B_DISP_DSI0			25
+
 #define MT8183_TOPRGU_MM_SW_RST					1
 #define MT8183_TOPRGU_MFG_SW_RST				2
 #define MT8183_TOPRGU_VENC_SW_RST				3
-- 
2.30.2



From will at kernel.org  Wed Aug 25 03:28:56 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 25 Aug 2021 11:28:56 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210825102044.GA3420@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
Message-ID: <20210825102856.GD24546@willie-the-truck>

On Wed, Aug 25, 2021 at 11:20:46AM +0100, Catalin Marinas wrote:
> Given how later we are in the -rc cycle, I suggest we revert Anshuman's
> commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID") and try to
> assess the implications in 5.15 (the patch doesn't seem to have the
> arm64 maintainers' ack anyway ;)).

I'll stick the revert (below) into kernelci now so we can get some coverage
in case it breaks something else.

Will

--->8

>From e97ba0e39e486c20d8f76f3e632e4b7d933602cd Mon Sep 17 00:00:00 2001
From: Will Deacon <will at kernel.org>
Date: Wed, 25 Aug 2021 11:10:07 +0100
Subject: [PATCH] Revert "arm64/mm: drop HAVE_ARCH_PFN_VALID"

This reverts commit 16c9afc776608324ca71c0bc354987bab532f51d.

Alex Bee reports a regression in 5.14 on their RK3328 SoC when
configuring the PL330 DMA controller:

 | ------------[ cut here ]------------
 | WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
 | Modules linked in: spi_rockchip(+) fuse
 | CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
 | Hardware name: Pine64 Rock64 (DT)
 | pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
 | pc : dma_map_resource+0x68/0xc0
 | lr : pl330_prep_slave_fifo+0x78/0xd0

This appears to be because dma_map_resource() is being called for a
physical address which does not correspond to a memory address yet does
have a valid 'struct page' due to the way in which the vmemmap is
constructed.

Prior to 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID"), the arm64
implementation of pfn_valid() called memblock_is_memory() to return
'false' for such regions and the DMA mapping request would proceed.
However, now that we are using the generic implementation where only the
presence of the memory map entry is considered, we return 'true' and
erroneously fail with DMA_MAPPING_ERROR because we identify the region
as DRAM.

Although fixing this in the DMA mapping code is arguably the right fix,
it is a risky, cross-architecture change at this stage in the cycle. So
just revert arm64 back to its old pfn_valid() implementation for v5.14.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Robin Murphy <robin.murphy at arm.com>
Cc: Mike Rapoport <rppt at kernel.org>
Cc: Anshuman Khandual <anshuman.khandual at arm.com>
Cc: Christoph Hellwig <hch at lst.de>
Reported-by: Alex Bee <knaerzche at gmail.com>
Link: https://lore.kernel.org/r/d3a3c828-b777-faf8-e901-904995688437 at gmail.com
Signed-off-by: Will Deacon <will at kernel.org>
---
 arch/arm64/Kconfig            |  1 +
 arch/arm64/include/asm/page.h |  1 +
 arch/arm64/mm/init.c          | 37 +++++++++++++++++++++++++++++++++++
 include/linux/mmzone.h        |  9 ---------
 4 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index fdcd54d39c1e..62c3c1d2190f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -156,6 +156,7 @@ config ARM64
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_MMAP_RND_BITS
 	select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
+	select HAVE_ARCH_PFN_VALID
 	select HAVE_ARCH_PREL32_RELOCATIONS
 	select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
 	select HAVE_ARCH_SECCOMP_FILTER
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 993a27ea6f54..f98c91bbd7c1 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -41,6 +41,7 @@ void tag_clear_highpage(struct page *to);
 
 typedef struct page *pgtable_t;
 
+int pfn_valid(unsigned long pfn);
 int pfn_is_map_memory(unsigned long pfn);
 
 #include <asm/memory.h>
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2917ff..1fdb7bb7c198 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -219,6 +219,43 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 	free_area_init(max_zone_pfns);
 }
 
+int pfn_valid(unsigned long pfn)
+{
+	phys_addr_t addr = PFN_PHYS(pfn);
+	struct mem_section *ms;
+
+	/*
+	 * Ensure the upper PAGE_SHIFT bits are clear in the
+	 * pfn. Else it might lead to false positives when
+	 * some of the upper bits are set, but the lower bits
+	 * match a valid pfn.
+	 */
+	if (PHYS_PFN(addr) != pfn)
+		return 0;
+
+	if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
+		return 0;
+
+	ms = __pfn_to_section(pfn);
+	if (!valid_section(ms))
+		return 0;
+
+	/*
+	 * ZONE_DEVICE memory does not have the memblock entries.
+	 * memblock_is_map_memory() check for ZONE_DEVICE based
+	 * addresses will always fail. Even the normal hotplugged
+	 * memory will never have MEMBLOCK_NOMAP flag set in their
+	 * memblock entries. Skip memblock search for all non early
+	 * memory sections covering all of hotplug memory including
+	 * both normal and ZONE_DEVICE based.
+	 */
+	if (!early_section(ms))
+		return pfn_section_valid(ms, pfn);
+
+	return memblock_is_memory(addr);
+}
+EXPORT_SYMBOL(pfn_valid);
+
 int pfn_is_map_memory(unsigned long pfn)
 {
 	phys_addr_t addr = PFN_PHYS(pfn);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index fcb535560028..ee70f21a79d5 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1463,15 +1463,6 @@ static inline int pfn_valid(unsigned long pfn)
 {
 	struct mem_section *ms;
 
-	/*
-	 * Ensure the upper PAGE_SHIFT bits are clear in the
-	 * pfn. Else it might lead to false positives when
-	 * some of the upper bits are set, but the lower bits
-	 * match a valid pfn.
-	 */
-	if (PHYS_PFN(PFN_PHYS(pfn)) != pfn)
-		return 0;
-
 	if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
 		return 0;
 	ms = __nr_to_section(pfn_to_section_nr(pfn));
-- 
2.33.0.rc2.250.ged5fa647cd-goog



From joe at perches.com  Wed Aug 25 03:30:00 2021
From: joe at perches.com (Joe Perches)
Date: Wed, 25 Aug 2021 03:30:00 -0700
Subject: [PATCH] mxser: use semi-colons instead of commas
In-Reply-To: <20210825072435.GB13013@kili>
References: <20210825072435.GB13013@kili>
Message-ID: <53afc244281b6a76aecf4a5565d7e6395e376d4e.camel@perches.com>

On Wed, 2021-08-25 at 10:24 +0300, Dan Carpenter wrote:
> This code works, but it's cleaner to use semi-colons at the end of
> a statement instead of a comma.

There are still multiple dozens of this type of comma use
in the kernel.

Julia Lawall created a cocci script to convert the commas
to semicolons that worked pretty well.

https://lore.kernel.org/lkml/alpine.DEB.2.22.394.2008201856110.2524 at hadrien/

> diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
[]
> @@ -1039,12 +1039,12 @@ static int mxser_get_serial_info(struct tty_struct *tty,
> ?	if (closing_wait != ASYNC_CLOSING_WAIT_NONE)
> ?		closing_wait = jiffies_to_msecs(closing_wait) / 10;
> ?
> 
> -	ss->type = info->type,
> -	ss->line = tty->index,
> -	ss->port = info->ioaddr,
> -	ss->irq = info->board->irq,
> -	ss->flags = info->port.flags,
> -	ss->baud_base = MXSER_BAUD_BASE,
> +	ss->type = info->type;
> +	ss->line = tty->index;
> +	ss->port = info->ioaddr;
> +	ss->irq = info->board->irq;
> +	ss->flags = info->port.flags;
> +	ss->baud_base = MXSER_BAUD_BASE;
> ?	ss->close_delay = close_delay;
> ?	ss->closing_wait = closing_wait;
> ?	ss->custom_divisor = MXSER_CUSTOM_DIVISOR,




From will at kernel.org  Wed Aug 25 03:32:23 2021
From: will at kernel.org (Will Deacon)
Date: Wed, 25 Aug 2021 11:32:23 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210825102856.GD24546@willie-the-truck>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
 <20210825102856.GD24546@willie-the-truck>
Message-ID: <20210825103223.GE24546@willie-the-truck>

On Wed, Aug 25, 2021 at 11:28:56AM +0100, Will Deacon wrote:
> On Wed, Aug 25, 2021 at 11:20:46AM +0100, Catalin Marinas wrote:
> > Given how later we are in the -rc cycle, I suggest we revert Anshuman's
> > commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID") and try to
> > assess the implications in 5.15 (the patch doesn't seem to have the
> > arm64 maintainers' ack anyway ;)).
> 
> I'll stick the revert (below) into kernelci now so we can get some coverage
> in case it breaks something else.

Bah, having said that...

> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index fcb535560028..ee70f21a79d5 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -1463,15 +1463,6 @@ static inline int pfn_valid(unsigned long pfn)
>  {
>  	struct mem_section *ms;
>  
> -	/*
> -	 * Ensure the upper PAGE_SHIFT bits are clear in the
> -	 * pfn. Else it might lead to false positives when
> -	 * some of the upper bits are set, but the lower bits
> -	 * match a valid pfn.
> -	 */
> -	if (PHYS_PFN(PFN_PHYS(pfn)) != pfn)
> -		return 0;
> -

I suppose we should leave this bit as-is, since the whole point here is
trying to minimise the impact on other architectures.

Will


From robin.murphy at arm.com  Wed Aug 25 03:33:41 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 25 Aug 2021 11:33:41 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210825102856.GD24546@willie-the-truck>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com> <20210825102856.GD24546@willie-the-truck>
Message-ID: <244f4b37-2db6-6f9e-b5e2-3ccd6c3136ba@arm.com>

On 2021-08-25 11:28, Will Deacon wrote:
> On Wed, Aug 25, 2021 at 11:20:46AM +0100, Catalin Marinas wrote:
>> Given how later we are in the -rc cycle, I suggest we revert Anshuman's
>> commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID") and try to
>> assess the implications in 5.15 (the patch doesn't seem to have the
>> arm64 maintainers' ack anyway ;)).
> 
> I'll stick the revert (below) into kernelci now so we can get some coverage
> in case it breaks something else.
> 
> Will
> 
> --->8
> 
>  From e97ba0e39e486c20d8f76f3e632e4b7d933602cd Mon Sep 17 00:00:00 2001
> From: Will Deacon <will at kernel.org>
> Date: Wed, 25 Aug 2021 11:10:07 +0100
> Subject: [PATCH] Revert "arm64/mm: drop HAVE_ARCH_PFN_VALID"
> 
> This reverts commit 16c9afc776608324ca71c0bc354987bab532f51d.
> 
> Alex Bee reports a regression in 5.14 on their RK3328 SoC when
> configuring the PL330 DMA controller:
> 
>   | ------------[ cut here ]------------
>   | WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>   | Modules linked in: spi_rockchip(+) fuse
>   | CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>   | Hardware name: Pine64 Rock64 (DT)
>   | pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>   | pc : dma_map_resource+0x68/0xc0
>   | lr : pl330_prep_slave_fifo+0x78/0xd0
> 
> This appears to be because dma_map_resource() is being called for a
> physical address which does not correspond to a memory address yet does
> have a valid 'struct page' due to the way in which the vmemmap is
> constructed.
> 
> Prior to 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID"), the arm64
> implementation of pfn_valid() called memblock_is_memory() to return
> 'false' for such regions and the DMA mapping request would proceed.
> However, now that we are using the generic implementation where only the
> presence of the memory map entry is considered, we return 'true' and
> erroneously fail with DMA_MAPPING_ERROR because we identify the region
> as DRAM.
> 
> Although fixing this in the DMA mapping code is arguably the right fix,
> it is a risky, cross-architecture change at this stage in the cycle. So
> just revert arm64 back to its old pfn_valid() implementation for v5.14.

TBH the offending warning is only meant to be a quick sanity check, so I 
don't think there should be much impact to changing the DMA code; it's 
just a question of figuring out what change to make. I'm digging in now...

Thanks,
Robin.

> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Robin Murphy <robin.murphy at arm.com>
> Cc: Mike Rapoport <rppt at kernel.org>
> Cc: Anshuman Khandual <anshuman.khandual at arm.com>
> Cc: Christoph Hellwig <hch at lst.de>
> Reported-by: Alex Bee <knaerzche at gmail.com>
> Link: https://lore.kernel.org/r/d3a3c828-b777-faf8-e901-904995688437 at gmail.com
> Signed-off-by: Will Deacon <will at kernel.org>
> ---
>   arch/arm64/Kconfig            |  1 +
>   arch/arm64/include/asm/page.h |  1 +
>   arch/arm64/mm/init.c          | 37 +++++++++++++++++++++++++++++++++++
>   include/linux/mmzone.h        |  9 ---------
>   4 files changed, 39 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index fdcd54d39c1e..62c3c1d2190f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -156,6 +156,7 @@ config ARM64
>   	select HAVE_ARCH_KGDB
>   	select HAVE_ARCH_MMAP_RND_BITS
>   	select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
> +	select HAVE_ARCH_PFN_VALID
>   	select HAVE_ARCH_PREL32_RELOCATIONS
>   	select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
>   	select HAVE_ARCH_SECCOMP_FILTER
> diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
> index 993a27ea6f54..f98c91bbd7c1 100644
> --- a/arch/arm64/include/asm/page.h
> +++ b/arch/arm64/include/asm/page.h
> @@ -41,6 +41,7 @@ void tag_clear_highpage(struct page *to);
>   
>   typedef struct page *pgtable_t;
>   
> +int pfn_valid(unsigned long pfn);
>   int pfn_is_map_memory(unsigned long pfn);
>   
>   #include <asm/memory.h>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 8490ed2917ff..1fdb7bb7c198 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -219,6 +219,43 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
>   	free_area_init(max_zone_pfns);
>   }
>   
> +int pfn_valid(unsigned long pfn)
> +{
> +	phys_addr_t addr = PFN_PHYS(pfn);
> +	struct mem_section *ms;
> +
> +	/*
> +	 * Ensure the upper PAGE_SHIFT bits are clear in the
> +	 * pfn. Else it might lead to false positives when
> +	 * some of the upper bits are set, but the lower bits
> +	 * match a valid pfn.
> +	 */
> +	if (PHYS_PFN(addr) != pfn)
> +		return 0;
> +
> +	if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
> +		return 0;
> +
> +	ms = __pfn_to_section(pfn);
> +	if (!valid_section(ms))
> +		return 0;
> +
> +	/*
> +	 * ZONE_DEVICE memory does not have the memblock entries.
> +	 * memblock_is_map_memory() check for ZONE_DEVICE based
> +	 * addresses will always fail. Even the normal hotplugged
> +	 * memory will never have MEMBLOCK_NOMAP flag set in their
> +	 * memblock entries. Skip memblock search for all non early
> +	 * memory sections covering all of hotplug memory including
> +	 * both normal and ZONE_DEVICE based.
> +	 */
> +	if (!early_section(ms))
> +		return pfn_section_valid(ms, pfn);
> +
> +	return memblock_is_memory(addr);
> +}
> +EXPORT_SYMBOL(pfn_valid);
> +
>   int pfn_is_map_memory(unsigned long pfn)
>   {
>   	phys_addr_t addr = PFN_PHYS(pfn);
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index fcb535560028..ee70f21a79d5 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -1463,15 +1463,6 @@ static inline int pfn_valid(unsigned long pfn)
>   {
>   	struct mem_section *ms;
>   
> -	/*
> -	 * Ensure the upper PAGE_SHIFT bits are clear in the
> -	 * pfn. Else it might lead to false positives when
> -	 * some of the upper bits are set, but the lower bits
> -	 * match a valid pfn.
> -	 */
> -	if (PHYS_PFN(PFN_PHYS(pfn)) != pfn)
> -		return 0;
> -
>   	if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
>   		return 0;
>   	ms = __nr_to_section(pfn_to_section_nr(pfn));
> 


From david at redhat.com  Wed Aug 25 03:38:31 2021
From: david at redhat.com (David Hildenbrand)
Date: Wed, 25 Aug 2021 12:38:31 +0200
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210825102044.GA3420@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
Message-ID: <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>

On 25.08.21 12:20, Catalin Marinas wrote:
> + hch
> 
> On Tue, Aug 24, 2021 at 08:59:22PM +0200, David Hildenbrand wrote:
>> On 24.08.21 20:46, Robin Murphy wrote:
>>> On 2021-08-24 19:28, Mike Rapoport wrote:
>>>> On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
>>>>> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>>>>>> it seems there is a regression in arm64 memory mapping in 5.14, since it
>>>>>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>>>>>
>>>>>>   ------------[ cut here ]------------
>>>>>>   WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>>>>>>   Modules linked in: spi_rockchip(+) fuse
>>>>>>   CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>>>>>>   Hardware name: Pine64 Rock64 (DT)
>>>>>>   pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>>>>>>   pc : dma_map_resource+0x68/0xc0
>>>>>>   lr : pl330_prep_slave_fifo+0x78/0xd0
>>>>>>   sp : ffff800012102ae0
>>>>>>   x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>>>>>>   x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>>>>>>   x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>>>>>>   x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>>>>>>   x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>>>>>>   x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>>>>>>   x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>>>>>>   x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>>>>>>   x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>>>>>>   x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>>>>>>   Call trace:
>>>>>>     dma_map_resource+0x68/0xc0
>>>>>>     pl330_prep_slave_sg+0x58/0x220
>>>>>>     rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>>>>>>     rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
>>>>> [...]
>>>>>> Note: This does not relate to the spi driver - when disabling this device in
>>>>>> the device tree it fails for any other (i2s, for instance) which uses dma.
>>>>>> Commenting out the failing check at [1], however, helps and the mapping
>>>>>> works again.
>>>>
>>>>> Do you know which address dma_map_resource() is trying to map (maybe
>>>>> add some printk())? It's not supposed to map RAM, hence the warning.
>>>>> Random guess, the address is 0xff190800 (based on the x1 above but the
>>>>> regs might as well be mangled).
>>>>
>>>> 0xff190800 will cause this warning for sure. It has a memory map, but it is
>>>> not RAM so old version of pfn_valid() would return 0 and the new one
>>>> returns 1.
>>>
>>> How does that happen, though? It's not a memory address, and it's not
>>> even within the bounds of anywhere there should or could be memory. This
>>> SoC has a simple memory map - everything from 0 to 0xfeffffff goes to
>>> the DRAM controller (which may not all be populated, and may have pieces
>>> carved out by secure firmware), while 0xff000000-0xffffffff is MMIO. Why
>>> do we have pages (or at least the assumption of pages) for somewhere
>>> which by all rights should not have them?
>>
>> Simple: we allocate the vmemmap for whole sections (e.g., 128 MiB) to avoid
>> any such hacks. If there is a memory hole, it gets a memmap as well.
>>
>> Tricking pfn_valid() into returning "false" where we actually have a memmap
>> only makes it look like there is no memmap; but there is one, and
>> it's PG_reserved.
> 
> I can see the documentation for pfn_valid() does not claim anything more
> than the presence of an memmap entry. But I wonder whether the confusion
> is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
> assumes __va() can be used on pfn_valid(), though I suspect it relies on
> the calling function to check that the resource was RAM. The arm64
> kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
> standard memcpy on it, which wouldn't work for I/O (should we change
> this check to pfn_is_map_memory() for arm64?).
> 

kern_addr_valid() checks that there is a direct map entry, and that the 
mapped address has a valid mmap. (copied from x86-64)

Would you expect to have a direct map for memory holes and similar (IOW, 
!System RAM)?


>>>>> Either pfn_valid() gets confused in 5.14 or something is wrong with the
>>>>> DT. I have a suspicion it's the former since reverting the above commit
>>>>> makes it disappear.
>>>>
>>>> I think pfn_valid() actually behaves as expected but the caller is wrong
>>>> because pfn_valid != RAM (this applies btw to !arm64 as well).
>>>>
>>>> 	/* Don't allow RAM to be mapped */
>>>> 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
>>>> 		return DMA_MAPPING_ERROR;
>>>>
>>>> Alex, can you please try this patch:
>>>
>>> That will certainly paper over the issue, but it's avoiding the question
>>> of what went wrong with the memory map in the first place. The comment
>>> is indeed a bit inaccurate, but ultimately dma_map_resource() exists for
>>> addresses that would be wrong to pass to dma_map_page(), so I believe
>>> pfn_valid() is still the correct check.
>>
>> If we want to check for RAM, pfn_valid() would be wrong. If we want to check
>> for "is there a memmap, for whatever lives or does not live there",
>> pfn_valid() is the right check.
> 
> So what should the DMA code use instead? Last time we needed something
> similar, the recommendation was to use pfn_to_online_page(). Mike is
> suggesting memblock_is_memory().

We use pfn_to_online_page() when we want to know if it's system RAM and 
that the memmap actually contains something sane (-> memmap content has 
a well defined state).

You can have offline memory blocks where pfn_to_online_page() would 
return "false", memblock_is_memory() would return "true". IOW, there is 
a memmap, it's System RAM, but the memmap is stale and not trustworthy.

If you want to make sure no System RAM (online/offline/...) will get 
mapped, memblock_is_memory() should be the right thing to use. I recall 
that x86 traverse the resource tree instead to exclude system ram 
regions similarly.

> 
> Given how later we are in the -rc cycle, I suggest we revert Anshuman's
> commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID") and try to
> assess the implications in 5.15 (the patch doesn't seem to have the
> arm64 maintainers' ack anyway ;)).

-- 
Thanks,

David / dhildenb



From maz at kernel.org  Wed Aug 25 03:39:34 2021
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 25 Aug 2021 11:39:34 +0100
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
Message-ID: <87fsuxq049.wl-maz@kernel.org>

On Wed, 25 Aug 2021 11:02:28 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Wed, Aug 25, 2021 at 2:27 AM Marc Zyngier <maz at kernel.org> wrote:
> > > Exposing new hypercalls to guests in this manner seems very unsafe to
> > > me. Suppose an operator is trying to upgrade from kernel N to kernel
> > > N+1, which brings in the new 'widget' hypercall. Guests are live
> > > migrated onto the N+1 kernel, but the operator finds a defect that
> > > warrants a kernel rollback. VMs are then migrated from kernel N+1 -> N.
> > > Any guests that discovered the 'widget' hypercall are likely going to
> > > get fussy _very_ quickly on the old kernel.
> >
> > This goes against what we decided to support for the *only* publicly
> > available VMM that cares about save/restore, which is that we only
> > move forward and don't rollback.
> 
> Ah, I was definitely missing this context. Current behavior makes much
> more sense then.
> 
> > Hypercalls are the least of your
> > worries, and there is a whole range of other architectural features
> > that will have also appeared/disappeared (your own CNTPOFF series is a
> > glaring example of this).
> 
> Isn't that a tad bit different though? I'll admit, I'm just as guilty
> with my own series forgetting to add a KVM_CAP (oops), but it is in my
> queue to kick out with the fix for nVHE/ptimer. Nonetheless, if a user
> takes up a new KVM UAPI, it is up to the user to run on a new kernel.

The two are linked. Exposing a new register to userspace and/or guest
result in the same thing: you can't rollback. That's specially true in
the QEMU case, which *learns* from the kernel what registers are
available, and doesn't maintain a fixed list.

> My concerns are explicitly with the 'under the nose' changes, where
> KVM modifies the guest feature set without userspace opting in. Based
> on your comment, though, it would appear that other parts of KVM are
> affected too.

Any new system register that is exposed by a new kernel feature breaks
rollback. And so far, we only consider it a bug if the set of exposed
registers reduces. Anything can be added safely (as checked by one of
the selftests added by Drew).

< It doesn't have to be rollback safety, either. There may
> simply be a hypercall which an operator doesn't want to give its
> guests, and it needs a way to tell KVM to hide it.

Fair enough. But this has to be done in a scalable way, which
individual capability cannot provide.

> > > Have I missed something blatantly obvious, or do others see this as an
> > > issue as well? I'll reply with an example of adding opt-out for PTP.
> > > I'm sure other hypercalls could be handled similarly.
> >
> > Why do we need this? For future hypercalls, we could have some buy-in
> > capabilities. For existing ones, it is too late, and negative features
> > are just too horrible.
> 
> Oh, agreed on the nastiness. Lazy hack to realize the intended
> functional change..

Well, you definitely achieved your goal of attracting my attention :).

> > For KVM-specific hypercalls, we could get the VMM to save/restore the
> > bitmap of supported functions. That would be "less horrible". This
> > could be implemented using extra "firmware pseudo-registers" such as
> > the ones described in Documentation/virt/kvm/arm/psci.rst.
> 
> This seems more reasonable, especially since we do this for migrating
> the guest's PSCI version.
> 
> Alternatively, I had thought about using a VM attribute, given the
> fact that it is non-architectural information and we avoid ABI issues
> in KVM_GET_REG_LIST without buy-in through a KVM_CAP.

The whole point is that these settings get exposed by
KVM_GET_REG_LIST, as this is QEMU's way to dump a VM state. Given that
we already have this for things like the spectre management state, we
can just as well expose the bitmaps that deal with the KVM-specific
hypercalls. After all, this falls into the realm of "KVM as VM
firmware".

For ARM-architected hypercalls (TRNG, stolen time), we may need a
similar extension.

	M.

-- 
Without deviation from the norm, progress is not possible.


From p.zabel at pengutronix.de  Wed Aug 25 03:46:44 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 25 Aug 2021 12:46:44 +0200
Subject: [PATCH v4 10/17] soc: mediatek: mmsys: Add reset controller
 support for MT8195 vdosys1
In-Reply-To: <20210825100531.5653-11-nancy.lin@mediatek.com>
References: <20210825100531.5653-1-nancy.lin@mediatek.com>
 <20210825100531.5653-11-nancy.lin@mediatek.com>
Message-ID: <0cdce7a43a0b74fabc110730d2b2ec9dce5cbbff.camel@pengutronix.de>

Hi,

On Wed, 2021-08-25 at 18:05 +0800, Nancy.Lin wrote:
> Among other features the mmsys driver should implement a reset
> controller to be able to reset different bits from their space.
> 
> For MT8195 vdosys1, many async modules need to reset after
> the display pipe stops and restart.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/soc/mediatek/mt8195-mmsys.h |  1 +
>  drivers/soc/mediatek/mtk-mmsys.c    | 76 +++++++++++++++++++++++++++++

Cc: Enric - this patch clashes with [1], please coordinate.

[1] https://lore.kernel.org/linux-arm-kernel/20210825122613.v3.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d at changeid/

regards
Philipp


From p.zabel at pengutronix.de  Wed Aug 25 03:46:42 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 25 Aug 2021 12:46:42 +0200
Subject: [PATCH v3 6/7] soc: mediatek: mmsys: Add reset controller support
In-Reply-To: <20210825122613.v3.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d@changeid>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
 <20210825122613.v3.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d@changeid>
Message-ID: <ebbe37cb0188a7ea23608569ab083e65e0f95df6.camel@pengutronix.de>

On Wed, 2021-08-25 at 12:26 +0200, Enric Balletbo i Serra wrote:
> Among other features the mmsys driver should implement a reset
> controller to be able to reset different bits from their space.
> 
> Cc: Jitao Shi <jitao.shi at mediatek.com>
> Suggested-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
> ---
> 
> (no changes since v1)
> 
>  drivers/soc/mediatek/mtk-mmsys.c | 69 ++++++++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.h |  2 +

Cc: Nancy - this patch clashes with [1], please coordinate.

[1] https://lore.kernel.org/linux-arm-kernel/20210825100531.5653-11-nancy.lin at mediatek.com/

regards
Philipp


From yajun.deng at linux.dev  Wed Aug 25 03:49:14 2021
From: yajun.deng at linux.dev (yajun.deng at linux.dev)
Date: Wed, 25 Aug 2021 10:49:14 +0000
Subject: [PATCH linux-next] arm64: PCI: Introduce pcibios_free_irq()
 helper function
In-Reply-To: <20210825100500.GC24546@willie-the-truck>
References: <20210825100500.GC24546@willie-the-truck>
 <20210825071612.21543-1-yajun.deng@linux.dev>
Message-ID: <01d7cf96c63c05097ef28789e2e27d6f@linux.dev>

August 25, 2021 6:05 PM, "Will Deacon" <will at kernel.org> wrote:

> [+Lorenzo]
> 
> On Wed, Aug 25, 2021 at 03:16:12PM +0800, Yajun Deng wrote:
> 
>> Introduce pcibios_free_irq() to free irq in pci_device_probe() and
>> pci_device_remove() that in drivers/pci/pci-driver.c.
> 
> Please can you describe the problem you're solving?
> 

pcibios_alloc_irq() will be called in pci_device_probe(), but there hasn't pcibios_free_irq()
in arm64 architecture correspond it. pcibios_free_irq() is an empty function in 
drivers/pci/pci-driver.c.So pcibios_alloc_irq() and pcibios_free_irq() don't correspond.

>> Signed-off-by: Yajun Deng <yajun.deng at linux.dev>
>> ---
>> arch/arm64/kernel/pci.c | 10 +++++++++-
>> 1 file changed, 9 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
>> index 1006ed2d7c60..40da5aff4548 100644
>> --- a/arch/arm64/kernel/pci.c
>> +++ b/arch/arm64/kernel/pci.c
>> @@ -25,10 +25,18 @@
>> int pcibios_alloc_irq(struct pci_dev *dev)
>> {
>> if (!acpi_disabled)
>> - acpi_pci_irq_enable(dev);
>> + return acpi_pci_irq_enable(dev);
> 
> This means we'll now fail device probe if we can't enable the GSI. Is that a
> problem?
> 
Oh, It would be better that hasn't return.
> Will


From wenst at chromium.org  Wed Aug 25 03:52:34 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 18:52:34 +0800
Subject: [v2 17/24] clk: mediatek: Add MT8195 vdosys0 clock support
In-Reply-To: <20210820111504.350-18-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-18-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5FE3teHW+7+Sa+0Ec9_ey1eNr0Z40kgVqtzt8d8c-wXYg@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:30 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 vdosys0 clock controller which providers clock gate
> control in video system.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
> Integrate with mtk-mmsys driver which will pupulate device by
> platform_device_register_data to start vdosys clock driver

This should be part of your commit log, with an explanation of why
this design choice was made.

Code looks good overall.

ChenYu


> ---
>  drivers/clk/mediatek/Makefile          |   2 +-
>  drivers/clk/mediatek/clk-mt8195-vdo0.c | 123 +++++++++++++++++++++++++
>  2 files changed, 124 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-vdo0.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index ac269f6d39e3..d22731316b7c 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -82,6 +82,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
>                                         clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
> -                                       clk-mt8195-vdec.o
> +                                       clk-mt8195-vdec.o clk-mt8195-vdo0.o
>  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
>  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
> new file mode 100644
> index 000000000000..5d8facac3a2b
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
> @@ -0,0 +1,123 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Copyright (c) 2021 MediaTek Inc.
> +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +
> +#include <dt-bindings/clock/mt8195-clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +static const struct mtk_gate_regs vdo0_0_cg_regs = {
> +       .set_ofs = 0x104,
> +       .clr_ofs = 0x108,
> +       .sta_ofs = 0x100,
> +};
> +
> +static const struct mtk_gate_regs vdo0_1_cg_regs = {
> +       .set_ofs = 0x114,
> +       .clr_ofs = 0x118,
> +       .sta_ofs = 0x110,
> +};
> +
> +static const struct mtk_gate_regs vdo0_2_cg_regs = {
> +       .set_ofs = 0x124,
> +       .clr_ofs = 0x128,
> +       .sta_ofs = 0x120,
> +};
> +
> +#define GATE_VDO0_0(_id, _name, _parent, _shift)                       \
> +       GATE_MTK(_id, _name, _parent, &vdo0_0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
> +
> +#define GATE_VDO0_1(_id, _name, _parent, _shift)                       \
> +       GATE_MTK(_id, _name, _parent, &vdo0_1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
> +
> +#define GATE_VDO0_2(_id, _name, _parent, _shift)                       \
> +       GATE_MTK(_id, _name, _parent, &vdo0_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
> +
> +static const struct mtk_gate vdo0_clks[] = {
> +       /* VDO0_0 */
> +       GATE_VDO0_0(CLK_VDO0_DISP_OVL0, "vdo0_disp_ovl0", "top_vpp", 0),
> +       GATE_VDO0_0(CLK_VDO0_DISP_COLOR0, "vdo0_disp_color0", "top_vpp", 2),
> +       GATE_VDO0_0(CLK_VDO0_DISP_COLOR1, "vdo0_disp_color1", "top_vpp", 3),
> +       GATE_VDO0_0(CLK_VDO0_DISP_CCORR0, "vdo0_disp_ccorr0", "top_vpp", 4),
> +       GATE_VDO0_0(CLK_VDO0_DISP_CCORR1, "vdo0_disp_ccorr1", "top_vpp", 5),
> +       GATE_VDO0_0(CLK_VDO0_DISP_AAL0, "vdo0_disp_aal0", "top_vpp", 6),
> +       GATE_VDO0_0(CLK_VDO0_DISP_AAL1, "vdo0_disp_aal1", "top_vpp", 7),
> +       GATE_VDO0_0(CLK_VDO0_DISP_GAMMA0, "vdo0_disp_gamma0", "top_vpp", 8),
> +       GATE_VDO0_0(CLK_VDO0_DISP_GAMMA1, "vdo0_disp_gamma1", "top_vpp", 9),
> +       GATE_VDO0_0(CLK_VDO0_DISP_DITHER0, "vdo0_disp_dither0", "top_vpp", 10),
> +       GATE_VDO0_0(CLK_VDO0_DISP_DITHER1, "vdo0_disp_dither1", "top_vpp", 11),
> +       GATE_VDO0_0(CLK_VDO0_DISP_OVL1, "vdo0_disp_ovl1", "top_vpp", 16),
> +       GATE_VDO0_0(CLK_VDO0_DISP_WDMA0, "vdo0_disp_wdma0", "top_vpp", 17),
> +       GATE_VDO0_0(CLK_VDO0_DISP_WDMA1, "vdo0_disp_wdma1", "top_vpp", 18),
> +       GATE_VDO0_0(CLK_VDO0_DISP_RDMA0, "vdo0_disp_rdma0", "top_vpp", 19),
> +       GATE_VDO0_0(CLK_VDO0_DISP_RDMA1, "vdo0_disp_rdma1", "top_vpp", 20),
> +       GATE_VDO0_0(CLK_VDO0_DSI0, "vdo0_dsi0", "top_vpp", 21),
> +       GATE_VDO0_0(CLK_VDO0_DSI1, "vdo0_dsi1", "top_vpp", 22),
> +       GATE_VDO0_0(CLK_VDO0_DSC_WRAP0, "vdo0_dsc_wrap0", "top_vpp", 23),
> +       GATE_VDO0_0(CLK_VDO0_VPP_MERGE0, "vdo0_vpp_merge0", "top_vpp", 24),
> +       GATE_VDO0_0(CLK_VDO0_DP_INTF0, "vdo0_dp_intf0", "top_vpp", 25),
> +       GATE_VDO0_0(CLK_VDO0_DISP_MUTEX0, "vdo0_disp_mutex0", "top_vpp", 26),
> +       GATE_VDO0_0(CLK_VDO0_DISP_IL_ROT0, "vdo0_disp_il_rot0", "top_vpp", 27),
> +       GATE_VDO0_0(CLK_VDO0_APB_BUS, "vdo0_apb_bus", "top_vpp", 28),
> +       GATE_VDO0_0(CLK_VDO0_FAKE_ENG0, "vdo0_fake_eng0", "top_vpp", 29),
> +       GATE_VDO0_0(CLK_VDO0_FAKE_ENG1, "vdo0_fake_eng1", "top_vpp", 30),
> +       /* VDO0_1 */
> +       GATE_VDO0_1(CLK_VDO0_DL_ASYNC0, "vdo0_dl_async0", "top_vpp", 0),
> +       GATE_VDO0_1(CLK_VDO0_DL_ASYNC1, "vdo0_dl_async1", "top_vpp", 1),
> +       GATE_VDO0_1(CLK_VDO0_DL_ASYNC2, "vdo0_dl_async2", "top_vpp", 2),
> +       GATE_VDO0_1(CLK_VDO0_DL_ASYNC3, "vdo0_dl_async3", "top_vpp", 3),
> +       GATE_VDO0_1(CLK_VDO0_DL_ASYNC4, "vdo0_dl_async4", "top_vpp", 4),
> +       GATE_VDO0_1(CLK_VDO0_DISP_MONITOR0, "vdo0_disp_monitor0", "top_vpp", 5),
> +       GATE_VDO0_1(CLK_VDO0_DISP_MONITOR1, "vdo0_disp_monitor1", "top_vpp", 6),
> +       GATE_VDO0_1(CLK_VDO0_DISP_MONITOR2, "vdo0_disp_monitor2", "top_vpp", 7),
> +       GATE_VDO0_1(CLK_VDO0_DISP_MONITOR3, "vdo0_disp_monitor3", "top_vpp", 8),
> +       GATE_VDO0_1(CLK_VDO0_DISP_MONITOR4, "vdo0_disp_monitor4", "top_vpp", 9),
> +       GATE_VDO0_1(CLK_VDO0_SMI_GALS, "vdo0_smi_gals", "top_vpp", 10),
> +       GATE_VDO0_1(CLK_VDO0_SMI_COMMON, "vdo0_smi_common", "top_vpp", 11),
> +       GATE_VDO0_1(CLK_VDO0_SMI_EMI, "vdo0_smi_emi", "top_vpp", 12),
> +       GATE_VDO0_1(CLK_VDO0_SMI_IOMMU, "vdo0_smi_iommu", "top_vpp", 13),
> +       GATE_VDO0_1(CLK_VDO0_SMI_LARB, "vdo0_smi_larb", "top_vpp", 14),
> +       GATE_VDO0_1(CLK_VDO0_SMI_RSI, "vdo0_smi_rsi", "top_vpp", 15),
> +       /* VDO0_2 */
> +       GATE_VDO0_2(CLK_VDO0_DSI0_DSI, "vdo0_dsi0_dsi", "top_dsi_occ", 0),
> +       GATE_VDO0_2(CLK_VDO0_DSI1_DSI, "vdo0_dsi1_dsi", "top_dsi_occ", 8),
> +       GATE_VDO0_2(CLK_VDO0_DP_INTF0_DP_INTF, "vdo0_dp_intf0_dp_intf", "top_edp", 16),
> +};
> +
> +static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct device_node *node = dev->parent->of_node;
> +       struct clk_onecell_data *clk_data;
> +       int r;
> +
> +       clk_data = mtk_alloc_clk_data(CLK_VDO0_NR_CLK);
> +       if (!clk_data)
> +               return -ENOMEM;
> +
> +       r = mtk_clk_register_gates(node, vdo0_clks, ARRAY_SIZE(vdo0_clks), clk_data);
> +       if (r)
> +               goto free_vdo0_data;
> +
> +       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +       if (r)
> +               goto free_vdo0_data;
> +
> +       return r;
> +
> +free_vdo0_data:
> +       mtk_free_clk_data(clk_data);
> +       return r;
> +}
> +
> +static struct platform_driver clk_mt8195_vdo0_drv = {
> +       .probe = clk_mt8195_vdo0_probe,
> +       .driver = {
> +               .name = "clk-mt8195-vdo0",
> +       },
> +};
> +builtin_platform_driver(clk_mt8195_vdo0_drv);
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From rppt at kernel.org  Wed Aug 25 03:52:45 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Wed, 25 Aug 2021 13:52:45 +0300
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210825102044.GA3420@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
Message-ID: <YSYg/VmWlVh+rKp1@kernel.org>

On Wed, Aug 25, 2021 at 11:20:46AM +0100, Catalin Marinas wrote:
> + hch
> 
> On Tue, Aug 24, 2021 at 08:59:22PM +0200, David Hildenbrand wrote:
> > On 24.08.21 20:46, Robin Murphy wrote:
> > > On 2021-08-24 19:28, Mike Rapoport wrote:
> > > > On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
> > > > > On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
> > > > > > it seems there is a regression in arm64 memory mapping in 5.14, since it
> > > > > > fails on Rockchip RK3328 when the pl330 dmac tries to map with:
> > > > > > 
> > > > > >  ------------[ cut here ]------------
> > > > > >  WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
> > > > > >  Modules linked in: spi_rockchip(+) fuse
> > > > > >  CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
> > > > > >  Hardware name: Pine64 Rock64 (DT)
> > > > > >  pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
> > > > > >  pc : dma_map_resource+0x68/0xc0
> > > > > >  lr : pl330_prep_slave_fifo+0x78/0xd0
> > > > > >  sp : ffff800012102ae0
> > > > > >  x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
> > > > > >  x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
> > > > > >  x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
> > > > > >  x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
> > > > > >  x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> > > > > >  x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
> > > > > >  x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
> > > > > >  x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
> > > > > >  x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
> > > > > >  x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
> > > > > >  Call trace:
> > > > > >    dma_map_resource+0x68/0xc0
> > > > > >    pl330_prep_slave_sg+0x58/0x220
> > > > > >    rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
> > > > > >    rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
> > > > > [...]
> > > > > > Note: This does not relate to the spi driver - when disabling this device in
> > > > > > the device tree it fails for any other (i2s, for instance) which uses dma.
> > > > > > Commenting out the failing check at [1], however, helps and the mapping
> > > > > > works again.
> > > > 
> > > > > Do you know which address dma_map_resource() is trying to map (maybe
> > > > > add some printk())? It's not supposed to map RAM, hence the warning.
> > > > > Random guess, the address is 0xff190800 (based on the x1 above but the
> > > > > regs might as well be mangled).
> > > > 
> > > > 0xff190800 will cause this warning for sure. It has a memory map, but it is
> > > > not RAM so old version of pfn_valid() would return 0 and the new one
> > > > returns 1.
> > > 
> > > How does that happen, though? It's not a memory address, and it's not
> > > even within the bounds of anywhere there should or could be memory. This
> > > SoC has a simple memory map - everything from 0 to 0xfeffffff goes to
> > > the DRAM controller (which may not all be populated, and may have pieces
> > > carved out by secure firmware), while 0xff000000-0xffffffff is MMIO. Why
> > > do we have pages (or at least the assumption of pages) for somewhere
> > > which by all rights should not have them?
> > 
> > Simple: we allocate the vmemmap for whole sections (e.g., 128 MiB) to avoid
> > any such hacks. If there is a memory hole, it gets a memmap as well.
> > 
> > Tricking pfn_valid() into returning "false" where we actually have a memmap
> > only makes it look like there is no memmap; but there is one, and
> > it's PG_reserved.
> 
> I can see the documentation for pfn_valid() does not claim anything more
> than the presence of an memmap entry. But I wonder whether the confusion
> is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
> assumes __va() can be used on pfn_valid(), though I suspect it relies on
> the calling function to check that the resource was RAM. The arm64
> kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
> standard memcpy on it, which wouldn't work for I/O (should we change
> this check to pfn_is_map_memory() for arm64?).

Since for the most cases pfn_valid() would actually mean RAM, the confusion
is really widespread :(

Using pfn_is_map_memory() in kern_addr_valid() seems to me a better choice
that pfn_valid().

> > > > > Either pfn_valid() gets confused in 5.14 or something is wrong with the
> > > > > DT. I have a suspicion it's the former since reverting the above commit
> > > > > makes it disappear.
> > > > 
> > > > I think pfn_valid() actually behaves as expected but the caller is wrong
> > > > because pfn_valid != RAM (this applies btw to !arm64 as well).
> > > > 
> > > > 	/* Don't allow RAM to be mapped */
> > > > 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> > > > 		return DMA_MAPPING_ERROR;
> > > > 
> > > > Alex, can you please try this patch:
> > > 
> > > That will certainly paper over the issue, but it's avoiding the question
> > > of what went wrong with the memory map in the first place. The comment
> > > is indeed a bit inaccurate, but ultimately dma_map_resource() exists for
> > > addresses that would be wrong to pass to dma_map_page(), so I believe
> > > pfn_valid() is still the correct check.
> > 
> > If we want to check for RAM, pfn_valid() would be wrong. If we want to check
> > for "is there a memmap, for whatever lives or does not live there",
> > pfn_valid() is the right check.
> 
> So what should the DMA code use instead? Last time we needed something
> similar, the recommendation was to use pfn_to_online_page(). Mike is
> suggesting memblock_is_memory().

This was a for testing purposes :)
I considered some ugly fix for v5.14 with a __weak check in dma/mapping.c for
backward compatibility and an override in arm64 and then a proper audit for
v5.15.

But as Will went for revert this is not really relevant.
 
> Given how later we are in the -rc cycle, I suggest we revert Anshuman's
> commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID") and try to
> assess the implications in 5.15 (the patch doesn't seem to have the
> arm64 maintainers' ack anyway ;)).
> 
> Thanks.
> 
> -- 
> Catalin

-- 
Sincerely yours,
Mike.


From rppt at kernel.org  Wed Aug 25 03:54:45 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Wed, 25 Aug 2021 13:54:45 +0300
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
 <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
Message-ID: <YSYhdT+fP59b17GE@kernel.org>

On Wed, Aug 25, 2021 at 12:38:31PM +0200, David Hildenbrand wrote:
> On 25.08.21 12:20, Catalin Marinas wrote:
>
> > I can see the documentation for pfn_valid() does not claim anything more
> > than the presence of an memmap entry. But I wonder whether the confusion
> > is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
> > assumes __va() can be used on pfn_valid(), though I suspect it relies on
> > the calling function to check that the resource was RAM. The arm64
> > kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
> > standard memcpy on it, which wouldn't work for I/O (should we change
> > this check to pfn_is_map_memory() for arm64?).
> 
> kern_addr_valid() checks that there is a direct map entry, and that the
> mapped address has a valid mmap. (copied from x86-64)
> 
> Would you expect to have a direct map for memory holes and similar (IOW,
> !System RAM)?

I don't see where will it bail out for an IOMEM mapping before doing the
pfn_valid() check...
 
-- 
Sincerely yours,
Mike.


From catalin.marinas at arm.com  Wed Aug 25 03:55:11 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 25 Aug 2021 11:55:11 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
 <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
Message-ID: <20210825105510.GB3420@arm.com>

On Wed, Aug 25, 2021 at 12:38:31PM +0200, David Hildenbrand wrote:
> On 25.08.21 12:20, Catalin Marinas wrote:
> > On Tue, Aug 24, 2021 at 08:59:22PM +0200, David Hildenbrand wrote:
> > > On 24.08.21 20:46, Robin Murphy wrote:
> > > > On 2021-08-24 19:28, Mike Rapoport wrote:
> > > > > On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
> > > > > > On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
> > > > > > > it seems there is a regression in arm64 memory mapping in 5.14, since it
> > > > > > > fails on Rockchip RK3328 when the pl330 dmac tries to map with:
> > > > > > > 
> > > > > > >   ------------[ cut here ]------------
> > > > > > >   WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
> > > > > > >   Modules linked in: spi_rockchip(+) fuse
> > > > > > >   CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
> > > > > > >   Hardware name: Pine64 Rock64 (DT)
> > > > > > >   pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
> > > > > > >   pc : dma_map_resource+0x68/0xc0
> > > > > > >   lr : pl330_prep_slave_fifo+0x78/0xd0
> > > > > > >   sp : ffff800012102ae0
> > > > > > >   x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
> > > > > > >   x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
> > > > > > >   x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
> > > > > > >   x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
> > > > > > >   x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
> > > > > > >   x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
> > > > > > >   x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
> > > > > > >   x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
> > > > > > >   x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
> > > > > > >   x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
> > > > > > >   Call trace:
> > > > > > >     dma_map_resource+0x68/0xc0
> > > > > > >     pl330_prep_slave_sg+0x58/0x220
> > > > > > >     rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
> > > > > > >     rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
> > > > > > [...]
> > > > > > > Note: This does not relate to the spi driver - when disabling this device in
> > > > > > > the device tree it fails for any other (i2s, for instance) which uses dma.
> > > > > > > Commenting out the failing check at [1], however, helps and the mapping
> > > > > > > works again.
> > > > > 
> > > > > > Do you know which address dma_map_resource() is trying to map (maybe
> > > > > > add some printk())? It's not supposed to map RAM, hence the warning.
> > > > > > Random guess, the address is 0xff190800 (based on the x1 above but the
> > > > > > regs might as well be mangled).
> > > > > 
> > > > > 0xff190800 will cause this warning for sure. It has a memory map, but it is
> > > > > not RAM so old version of pfn_valid() would return 0 and the new one
> > > > > returns 1.
> > > > 
> > > > How does that happen, though? It's not a memory address, and it's not
> > > > even within the bounds of anywhere there should or could be memory. This
> > > > SoC has a simple memory map - everything from 0 to 0xfeffffff goes to
> > > > the DRAM controller (which may not all be populated, and may have pieces
> > > > carved out by secure firmware), while 0xff000000-0xffffffff is MMIO. Why
> > > > do we have pages (or at least the assumption of pages) for somewhere
> > > > which by all rights should not have them?
> > > 
> > > Simple: we allocate the vmemmap for whole sections (e.g., 128 MiB) to avoid
> > > any such hacks. If there is a memory hole, it gets a memmap as well.
> > > 
> > > Tricking pfn_valid() into returning "false" where we actually have a memmap
> > > only makes it look like there is no memmap; but there is one, and
> > > it's PG_reserved.
> > 
> > I can see the documentation for pfn_valid() does not claim anything more
> > than the presence of an memmap entry. But I wonder whether the confusion
> > is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
> > assumes __va() can be used on pfn_valid(), though I suspect it relies on
> > the calling function to check that the resource was RAM. The arm64
> > kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
> > standard memcpy on it, which wouldn't work for I/O (should we change
> > this check to pfn_is_map_memory() for arm64?).
> 
> kern_addr_valid() checks that there is a direct map entry, and that the
> mapped address has a valid mmap. (copied from x86-64)

It checks that there is a va->pa mapping, not necessarily in the linear
map as it walks the page tables. So for some I/O range that happens to
be mapped but which was in close proximity to RAM so that pfn_valid() is
true, kern_addr_valid() would return true. I don't thin that was the
intention.

> Would you expect to have a direct map for memory holes and similar (IOW,
> !System RAM)?

No, but we with the generic pfn_valid(), it may return true for mapped
MMIO (with different attributes than the direct map).

> > > > > > Either pfn_valid() gets confused in 5.14 or something is wrong with the
> > > > > > DT. I have a suspicion it's the former since reverting the above commit
> > > > > > makes it disappear.
> > > > > 
> > > > > I think pfn_valid() actually behaves as expected but the caller is wrong
> > > > > because pfn_valid != RAM (this applies btw to !arm64 as well).
> > > > > 
> > > > > 	/* Don't allow RAM to be mapped */
> > > > > 	if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> > > > > 		return DMA_MAPPING_ERROR;
> > > > > 
> > > > > Alex, can you please try this patch:
> > > > 
> > > > That will certainly paper over the issue, but it's avoiding the question
> > > > of what went wrong with the memory map in the first place. The comment
> > > > is indeed a bit inaccurate, but ultimately dma_map_resource() exists for
> > > > addresses that would be wrong to pass to dma_map_page(), so I believe
> > > > pfn_valid() is still the correct check.
> > > 
> > > If we want to check for RAM, pfn_valid() would be wrong. If we want to check
> > > for "is there a memmap, for whatever lives or does not live there",
> > > pfn_valid() is the right check.
> > 
> > So what should the DMA code use instead? Last time we needed something
> > similar, the recommendation was to use pfn_to_online_page(). Mike is
> > suggesting memblock_is_memory().
> 
> We use pfn_to_online_page() when we want to know if it's system RAM and that
> the memmap actually contains something sane (-> memmap content has a well
> defined state).
> 
> You can have offline memory blocks where pfn_to_online_page() would return
> "false", memblock_is_memory() would return "true". IOW, there is a memmap,
> it's System RAM, but the memmap is stale and not trustworthy.
> 
> If you want to make sure no System RAM (online/offline/...) will get mapped,
> memblock_is_memory() should be the right thing to use. I recall that x86
> traverse the resource tree instead to exclude system ram regions similarly.

Thanks, this makes sense.

-- 
Catalin


From wenst at chromium.org  Wed Aug 25 03:55:26 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 18:55:26 +0800
Subject: [v2 18/24] clk: mediatek: Add MT8195 vdosys1 clock support
In-Reply-To: <20210820111504.350-19-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-19-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5Eu1f+Mp5WE_BDRioqiZ1LPAyE=3SB5D8nNaHfposDHXA@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:31 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 vdosys1 clock controller which provides clock gate
> control for video system.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
> Integrate with mtk-mmsys driver which will pupulate device by
> platform_device_register_data to start vdosys clock driver

Same thing about the commit message. The reason behind such a design
should be documented and shared, so that other people looking at the
code will have the same context.


ChenYu


From elver at google.com  Wed Aug 25 03:57:22 2021
From: elver at google.com (Marco Elver)
Date: Wed, 25 Aug 2021 12:57:22 +0200
Subject: [PATCH 0/4] ARM: Support KFENCE feature
In-Reply-To: <CANpmjNMnU5P9xsDhgeBKQR7Tg-3cHPkMNx7906yYwEAj85sNWg@mail.gmail.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <CANpmjNMnU5P9xsDhgeBKQR7Tg-3cHPkMNx7906yYwEAj85sNWg@mail.gmail.com>
Message-ID: <YSYiEgEcW1Ln3+9P@elver.google.com>

On Wed, Aug 25, 2021 at 12:14PM +0200, Marco Elver wrote:
> On Wed, 25 Aug 2021 at 11:17, Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> > The patch 1~3 is to support KFENCE feature on ARM.
> >
> > NOTE:
> > The context of patch2/3 changes in arch/arm/mm/fault.c is based on link[1],
> > which make some refactor and cleanup about page fault.
> >
> > kfence_test is not useful when kfence is not enabled, skip kfence test
> > when kfence not enabled in patch4.
> >
> > I tested the kfence_test on ARM QEMU with or without ARM_LPAE and all passed.
> 
> Thank you for enabling KFENCE on ARM -- I'll leave arch-code review to
> an ARM maintainer.
> 
> However, as said on the patch, please drop the change to the
> kfence_test and associated changes. This is working as intended; while
> you claim that it takes a long time to run when disabled, when running
> manually you just should not run it when disabled. There are CI
> systems that rely on the KUnit test output and the fact that the
> various test cases say "not ok" etc. Changing that would mean such CI
> systems would no longer fail if KFENCE was accidentally disabled (once
> KFENCE is enabled on various CI, which we'd like to do at some point).
> There are ways to fail the test faster, but they all complicate the
> test for no good reason. (And the addition of a new exported function
> that is essentially useless.)

I spoke too soon -- we export __kfence_pool, and that's good enough to
fail the test fast if KFENCE was disabled at boot:

	https://lkml.kernel.org/r/20210825105533.1247922-1-elver at google.com

will do the trick. So please drop your patch 4/4 here.

Thanks,
-- Marco


From robin.murphy at arm.com  Wed Aug 25 03:58:51 2021
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 25 Aug 2021 11:58:51 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
 <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
Message-ID: <c392a29d-3501-956e-d659-7585831c458f@arm.com>

On 2021-08-25 11:38, David Hildenbrand wrote:
> On 25.08.21 12:20, Catalin Marinas wrote:
>> + hch
>>
>> On Tue, Aug 24, 2021 at 08:59:22PM +0200, David Hildenbrand wrote:
>>> On 24.08.21 20:46, Robin Murphy wrote:
>>>> On 2021-08-24 19:28, Mike Rapoport wrote:
>>>>> On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
>>>>>> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>>>>>>> it seems there is a regression in arm64 memory mapping in 5.14, 
>>>>>>> since it
>>>>>>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>>>>>>
>>>>>>> ? ------------[ cut here ]------------
>>>>>>> ? WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 
>>>>>>> dma_map_resource+0x68/0xc0
>>>>>>> ? Modules linked in: spi_rockchip(+) fuse
>>>>>>> ? CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>>>>>>> ? Hardware name: Pine64 Rock64 (DT)
>>>>>>> ? pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>>>>>>> ? pc : dma_map_resource+0x68/0xc0
>>>>>>> ? lr : pl330_prep_slave_fifo+0x78/0xd0
>>>>>>> ? sp : ffff800012102ae0
>>>>>>> ? x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>>>>>>> ? x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>>>>>>> ? x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>>>>>>> ? x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>>>>>>> ? x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>>>>>>> ? x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>>>>>>> ? x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>>>>>>> ? x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>>>>>>> ? x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>>>>>>> ? x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>>>>>>> ? Call trace:
>>>>>>> ??? dma_map_resource+0x68/0xc0
>>>>>>> ??? pl330_prep_slave_sg+0x58/0x220
>>>>>>> ??? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>>>>>>> ??? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
>>>>>> [...]
>>>>>>> Note: This does not relate to the spi driver - when disabling 
>>>>>>> this device in
>>>>>>> the device tree it fails for any other (i2s, for instance) which 
>>>>>>> uses dma.
>>>>>>> Commenting out the failing check at [1], however, helps and the 
>>>>>>> mapping
>>>>>>> works again.
>>>>>
>>>>>> Do you know which address dma_map_resource() is trying to map (maybe
>>>>>> add some printk())? It's not supposed to map RAM, hence the warning.
>>>>>> Random guess, the address is 0xff190800 (based on the x1 above but 
>>>>>> the
>>>>>> regs might as well be mangled).
>>>>>
>>>>> 0xff190800 will cause this warning for sure. It has a memory map, 
>>>>> but it is
>>>>> not RAM so old version of pfn_valid() would return 0 and the new one
>>>>> returns 1.
>>>>
>>>> How does that happen, though? It's not a memory address, and it's not
>>>> even within the bounds of anywhere there should or could be memory. 
>>>> This
>>>> SoC has a simple memory map - everything from 0 to 0xfeffffff goes to
>>>> the DRAM controller (which may not all be populated, and may have 
>>>> pieces
>>>> carved out by secure firmware), while 0xff000000-0xffffffff is MMIO. 
>>>> Why
>>>> do we have pages (or at least the assumption of pages) for somewhere
>>>> which by all rights should not have them?
>>>
>>> Simple: we allocate the vmemmap for whole sections (e.g., 128 MiB) to 
>>> avoid
>>> any such hacks. If there is a memory hole, it gets a memmap as well.

Urgh, apologies for being slow. This case isn't a memory hole as such, 
but I failed to consider the *ends* of memory not being section-aligned 
and leading to an overlap anyway.

>>> Tricking pfn_valid() into returning "false" where we actually have a 
>>> memmap
>>> only makes it look like there is no memmap; but there is one, and
>>> it's PG_reserved.
>>
>> I can see the documentation for pfn_valid() does not claim anything more
>> than the presence of an memmap entry. But I wonder whether the confusion
>> is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
>> assumes __va() can be used on pfn_valid(), though I suspect it relies on
>> the calling function to check that the resource was RAM. The arm64
>> kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
>> standard memcpy on it, which wouldn't work for I/O (should we change
>> this check to pfn_is_map_memory() for arm64?).
>>
> 
> kern_addr_valid() checks that there is a direct map entry, and that the 
> mapped address has a valid mmap. (copied from x86-64)
> 
> Would you expect to have a direct map for memory holes and similar (IOW, 
> !System RAM)?

Probably - we can have no-map regions for firmware-reserved RAM which I 
believe end up as PG_reserved if they're small enough, for the same 
reasoning as this case.

>>>>>> Either pfn_valid() gets confused in 5.14 or something is wrong 
>>>>>> with the
>>>>>> DT. I have a suspicion it's the former since reverting the above 
>>>>>> commit
>>>>>> makes it disappear.
>>>>>
>>>>> I think pfn_valid() actually behaves as expected but the caller is 
>>>>> wrong
>>>>> because pfn_valid != RAM (this applies btw to !arm64 as well).
>>>>>
>>>>> ????/* Don't allow RAM to be mapped */
>>>>> ????if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
>>>>> ??????? return DMA_MAPPING_ERROR;
>>>>>
>>>>> Alex, can you please try this patch:
>>>>
>>>> That will certainly paper over the issue, but it's avoiding the 
>>>> question
>>>> of what went wrong with the memory map in the first place. The comment
>>>> is indeed a bit inaccurate, but ultimately dma_map_resource() exists 
>>>> for
>>>> addresses that would be wrong to pass to dma_map_page(), so I believe
>>>> pfn_valid() is still the correct check.
>>>
>>> If we want to check for RAM, pfn_valid() would be wrong. If we want 
>>> to check
>>> for "is there a memmap, for whatever lives or does not live there",
>>> pfn_valid() is the right check.
>>
>> So what should the DMA code use instead? Last time we needed something
>> similar, the recommendation was to use pfn_to_online_page(). Mike is
>> suggesting memblock_is_memory().
> 
> We use pfn_to_online_page() when we want to know if it's system RAM and 
> that the memmap actually contains something sane (-> memmap content has 
> a well defined state).
> 
> You can have offline memory blocks where pfn_to_online_page() would 
> return "false", memblock_is_memory() would return "true". IOW, there is 
> a memmap, it's System RAM, but the memmap is stale and not trustworthy.

That's fine - offline memory is doubly-invalid to map as an MMIO resource :)

> If you want to make sure no System RAM (online/offline/...) will get 
> mapped, memblock_is_memory() should be the right thing to use. I recall 
> that x86 traverse the resource tree instead to exclude system ram 
> regions similarly.

I'm thinking that "pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn))" 
might be the closest thing to what I'd like to express - does that seem 
sensible at all? The one thing I'm not quite sure about is the 
interaction with P2P mappings of ZONE_DEVICE, but that's also true of 
the previous behaviour, and I'm not aware that the usage model has been 
fully nailed down yet, so I suspect we have some wiggle room. At worst, 
false negatives in certain situations wouldn't be the end of the world, 
since this is merely a sanity check for something which is expected to 
be a no-op the vast majority of the time, so being unobtrusive is more 
important than being exhaustive.

Thanks,
Robin.

>> Given how later we are in the -rc cycle, I suggest we revert Anshuman's
>> commit 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID") and try to
>> assess the implications in 5.15 (the patch doesn't seem to have the
>> arm64 maintainers' ack anyway ;)).
> 


From wenst at chromium.org  Wed Aug 25 03:59:32 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 18:59:32 +0800
Subject: [v2 20/24] clk: mediatek: Add MT8195 vppsys0 clock support
In-Reply-To: <20210820111504.350-21-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-21-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5GC=3E_Kzes1QKQtJykvGGugUUwjcO0EeDnmoDG0GHFvA@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:33 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 vppsys0 clock controller which provides clock gate
> controller for Video Processor Pipe.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From abel.vesa at nxp.com  Wed Aug 25 03:59:33 2021
From: abel.vesa at nxp.com (Abel Vesa)
Date: Wed, 25 Aug 2021 13:59:33 +0300
Subject: [GIT PULL] clk: imx: Updates for v5.15
Message-ID: <1629889173-5042-1-git-send-email-abel.vesa@nxp.com>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git/ tags/clk-imx-5.15

for you to fetch changes up to 86842d255b45fc2103da1cd202f5064397ed41f8:

  clk: imx8mn: Add M7 core clock (2021-08-24 16:09:07 +0300)

----------------------------------------------------------------
i.MX clock changes for 5.15:

 - Fix CLKOUT clocks on i.MX8MM and i.MX8MN by using imx_clk_hw_mux2
 - Switch from .round_rate to .determine_rate in clk-divider-gate
 - Fix clock tree update for TF-A controlled clocks for all i.MX8M
 - Add missing M7 core clock for i.MX8MN

----------------------------------------------------------------
Ahmad Fatoum (1):
      clk: imx8m: fix clock tree update of TF-A managed clocks

Lucas Stach (2):
      clk: imx8mm: use correct mux type for clkout path
      clk: imx8mn: use correct mux type for clkout path

Marek Vasut (1):
      clk: imx8mn: Add M7 core clock

Martin Blumenstingl (1):
      clk: imx: clk-divider-gate: Switch to clk_divider.determine_rate

 drivers/clk/imx/clk-composite-8m.c       |  3 ++-
 drivers/clk/imx/clk-divider-gate.c       | 10 +++++-----
 drivers/clk/imx/clk-imx8mm.c             | 11 ++++++-----
 drivers/clk/imx/clk-imx8mn.c             | 16 +++++++++++-----
 drivers/clk/imx/clk-imx8mq.c             |  7 ++++---
 drivers/clk/imx/clk.h                    | 16 ++++++++++++++--
 include/dt-bindings/clock/imx8mn-clock.h |  4 +++-
 7 files changed, 45 insertions(+), 22 deletions(-)


From wenst at chromium.org  Wed Aug 25 04:00:00 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 19:00:00 +0800
Subject: [v2 21/24] clk: mediatek: Add MT8195 vppsys1 clock support
In-Reply-To: <20210820111504.350-22-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-22-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5G6wKOZhBRq9J-Jesd1_vHn7Tt4eYo3acTK8-wK8-KjVw@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:33 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 vppsys1 clock controller which provides clock gate
> controller for Video Processor Pipe.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From wenst at chromium.org  Wed Aug 25 04:03:53 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 19:03:53 +0800
Subject: [v2 19/24] clk: mediatek: Add MT8195 vencsys clock support
In-Reply-To: <20210820111504.350-20-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-20-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5FuLTw9jmXEifkfKKYiN-vur3jBbwZWjL5m8vTkoP6VMA@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:31 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 vencsys clock controller which provide clock gate
> control for video encoder.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile          |  2 +-
>  drivers/clk/mediatek/clk-mt8195-venc.c | 69 ++++++++++++++++++++++++++
>  2 files changed, 70 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-venc.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 3c8c8cdbd3ef..82ffcc4f2c52 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -82,6 +82,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
>  obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
>                                         clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
> -                                       clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o
> +                                       clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
>  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> diff --git a/drivers/clk/mediatek/clk-mt8195-venc.c b/drivers/clk/mediatek/clk-mt8195-venc.c
> new file mode 100644
> index 000000000000..10702a4ad5ff
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8195-venc.c
> @@ -0,0 +1,69 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Copyright (c) 2021 MediaTek Inc.
> +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +
> +#include <dt-bindings/clock/mt8195-clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +static const struct mtk_gate_regs venc_cg_regs = {
> +       .set_ofs = 0x4,
> +       .clr_ofs = 0x8,
> +       .sta_ofs = 0x0,
> +};
> +
> +#define GATE_VENC(_id, _name, _parent, _shift)                 \
> +       GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
> +
> +static const struct mtk_gate venc_clks[] = {
> +       GATE_VENC(CLK_VENC_LARB, "venc_larb", "top_venc", 0),
> +       GATE_VENC(CLK_VENC_VENC, "venc_venc", "top_venc", 4),
> +       GATE_VENC(CLK_VENC_JPGENC, "venc_jpgenc", "top_venc", 8),
> +       GATE_VENC(CLK_VENC_JPGDEC, "venc_jpgdec", "top_venc", 12),
> +       GATE_VENC(CLK_VENC_JPGDEC_C1, "venc_jpgdec_c1", "top_venc", 16),
> +       GATE_VENC(CLK_VENC_GALS, "venc_gals", "top_venc", 28),
> +};
> +
> +static const struct mtk_gate venc_core1_clks[] = {
> +       GATE_VENC(CLK_VENC_CORE1_LARB, "venc_core1_larb", "top_venc", 0),
> +       GATE_VENC(CLK_VENC_CORE1_VENC, "venc_core1_venc", "top_venc", 4),
> +       GATE_VENC(CLK_VENC_CORE1_JPGENC, "venc_core1_jpgenc", "top_venc", 8),
> +       GATE_VENC(CLK_VENC_CORE1_JPGDEC, "venc_core1_jpgdec", "top_venc", 12),
> +       GATE_VENC(CLK_VENC_CORE1_JPGDEC_C1, "venc_core1_jpgdec_c1", "top_venc", 16),
> +       GATE_VENC(CLK_VENC_CORE1_GALS, "venc_core1_gals", "top_venc", 28),

The two hardware blocks look the same. Are there any actual differences?
I am somewhat skeptical about using different compatible strings just
to provide different clock names. This is normally handled with
"clock-output-names" properties in the device tree.

ChenYu

> +};
> +
> +static const struct mtk_clk_desc venc_desc = {
> +       .clks = venc_clks,
> +       .num_clks = ARRAY_SIZE(venc_clks),
> +};
> +
> +static const struct mtk_clk_desc venc_core1_desc = {
> +       .clks = venc_core1_clks,
> +       .num_clks = ARRAY_SIZE(venc_core1_clks),
> +};
> +
> +static const struct of_device_id of_match_clk_mt8195_venc[] = {
> +       {
> +               .compatible = "mediatek,mt8195-vencsys",
> +               .data = &venc_desc,
> +       }, {
> +               .compatible = "mediatek,mt8195-vencsys_core1",
> +               .data = &venc_core1_desc,
> +       }, {
> +               /* sentinel */
> +       }
> +};
> +
> +static struct platform_driver clk_mt8195_venc_drv = {
> +       .probe = mtk_clk_simple_probe,
> +       .driver = {
> +               .name = "clk-mt8195-venc",
> +               .of_match_table = of_match_clk_mt8195_venc,
> +       },
> +};
> +builtin_platform_driver(clk_mt8195_venc_drv);
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From patchwork-bot+netdevbpf at kernel.org  Wed Aug 25 04:10:06 2021
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 25 Aug 2021 11:10:06 +0000
Subject: [PATCH] net: ethernet: actions: Add helper dependency on
 COMPILE_TEST
In-Reply-To: <20210825062513.2384-1-caihuoqing@baidu.com>
References: <20210825062513.2384-1-caihuoqing@baidu.com>
Message-ID: <162988980666.32654.13729647254299495727.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (refs/heads/master):

On Wed, 25 Aug 2021 14:25:13 +0800 you wrote:
> it's helpful for complie test in other platform(e.g.X86)
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> ---
>  drivers/net/ethernet/actions/Kconfig | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Here is the summary with links:
  - net: ethernet: actions: Add helper dependency on COMPILE_TEST
    https://git.kernel.org/netdev/net-next/c/fbcf8a340150

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From david at redhat.com  Wed Aug 25 04:12:37 2021
From: david at redhat.com (David Hildenbrand)
Date: Wed, 25 Aug 2021 13:12:37 +0200
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <20210825105510.GB3420@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
 <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
 <20210825105510.GB3420@arm.com>
Message-ID: <547785ff-e02f-df28-7f9c-9ad4f5b3cc77@redhat.com>

On 25.08.21 12:55, Catalin Marinas wrote:
> On Wed, Aug 25, 2021 at 12:38:31PM +0200, David Hildenbrand wrote:
>> On 25.08.21 12:20, Catalin Marinas wrote:
>>> On Tue, Aug 24, 2021 at 08:59:22PM +0200, David Hildenbrand wrote:
>>>> On 24.08.21 20:46, Robin Murphy wrote:
>>>>> On 2021-08-24 19:28, Mike Rapoport wrote:
>>>>>> On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
>>>>>>> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>>>>>>>> it seems there is a regression in arm64 memory mapping in 5.14, since it
>>>>>>>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>>>>>>>
>>>>>>>>    ------------[ cut here ]------------
>>>>>>>>    WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235 dma_map_resource+0x68/0xc0
>>>>>>>>    Modules linked in: spi_rockchip(+) fuse
>>>>>>>>    CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>>>>>>>>    Hardware name: Pine64 Rock64 (DT)
>>>>>>>>    pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>>>>>>>>    pc : dma_map_resource+0x68/0xc0
>>>>>>>>    lr : pl330_prep_slave_fifo+0x78/0xd0
>>>>>>>>    sp : ffff800012102ae0
>>>>>>>>    x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>>>>>>>>    x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>>>>>>>>    x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>>>>>>>>    x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>>>>>>>>    x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>>>>>>>>    x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>>>>>>>>    x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>>>>>>>>    x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>>>>>>>>    x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>>>>>>>>    x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>>>>>>>>    Call trace:
>>>>>>>>      dma_map_resource+0x68/0xc0
>>>>>>>>      pl330_prep_slave_sg+0x58/0x220
>>>>>>>>      rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>>>>>>>>      rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
>>>>>>> [...]
>>>>>>>> Note: This does not relate to the spi driver - when disabling this device in
>>>>>>>> the device tree it fails for any other (i2s, for instance) which uses dma.
>>>>>>>> Commenting out the failing check at [1], however, helps and the mapping
>>>>>>>> works again.
>>>>>>
>>>>>>> Do you know which address dma_map_resource() is trying to map (maybe
>>>>>>> add some printk())? It's not supposed to map RAM, hence the warning.
>>>>>>> Random guess, the address is 0xff190800 (based on the x1 above but the
>>>>>>> regs might as well be mangled).
>>>>>>
>>>>>> 0xff190800 will cause this warning for sure. It has a memory map, but it is
>>>>>> not RAM so old version of pfn_valid() would return 0 and the new one
>>>>>> returns 1.
>>>>>
>>>>> How does that happen, though? It's not a memory address, and it's not
>>>>> even within the bounds of anywhere there should or could be memory. This
>>>>> SoC has a simple memory map - everything from 0 to 0xfeffffff goes to
>>>>> the DRAM controller (which may not all be populated, and may have pieces
>>>>> carved out by secure firmware), while 0xff000000-0xffffffff is MMIO. Why
>>>>> do we have pages (or at least the assumption of pages) for somewhere
>>>>> which by all rights should not have them?
>>>>
>>>> Simple: we allocate the vmemmap for whole sections (e.g., 128 MiB) to avoid
>>>> any such hacks. If there is a memory hole, it gets a memmap as well.
>>>>
>>>> Tricking pfn_valid() into returning "false" where we actually have a memmap
>>>> only makes it look like there is no memmap; but there is one, and
>>>> it's PG_reserved.
>>>
>>> I can see the documentation for pfn_valid() does not claim anything more
>>> than the presence of an memmap entry. But I wonder whether the confusion
>>> is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
>>> assumes __va() can be used on pfn_valid(), though I suspect it relies on
>>> the calling function to check that the resource was RAM. The arm64
>>> kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
>>> standard memcpy on it, which wouldn't work for I/O (should we change
>>> this check to pfn_is_map_memory() for arm64?).
>>
>> kern_addr_valid() checks that there is a direct map entry, and that the
>> mapped address has a valid mmap. (copied from x86-64)
> 
> It checks that there is a va->pa mapping, not necessarily in the linear
> map as it walks the page tables. So for some I/O range that happens to
> be mapped but which was in close proximity to RAM so that pfn_valid() is
> true, kern_addr_valid() would return true. I don't thin that was the
> intention.
> 
>> Would you expect to have a direct map for memory holes and similar (IOW,
>> !System RAM)?
> 
> No, but we with the generic pfn_valid(), it may return true for mapped
> MMIO (with different attributes than the direct map).

Ah, right. But can we actually run into that via kcore?

kcore builds the RAM list via walk_system_ram_range(), IOW the resource 
tree. And we end up calling kern_addr_valid() only on KCORE_RAM, 
KCORE_VMEMMAP and KCORE_TEXT.

Not saying that kern_addr_valid() shouldn't be improved.

-- 
Thanks,

David / dhildenb



From david at redhat.com  Wed Aug 25 04:21:16 2021
From: david at redhat.com (David Hildenbrand)
Date: Wed, 25 Aug 2021 13:21:16 +0200
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <c392a29d-3501-956e-d659-7585831c458f@arm.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
 <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
 <c392a29d-3501-956e-d659-7585831c458f@arm.com>
Message-ID: <aff3942e-b9ce-5bae-8214-0e5d89cd071c@redhat.com>

On 25.08.21 12:58, Robin Murphy wrote:
> On 2021-08-25 11:38, David Hildenbrand wrote:
>> On 25.08.21 12:20, Catalin Marinas wrote:
>>> + hch
>>>
>>> On Tue, Aug 24, 2021 at 08:59:22PM +0200, David Hildenbrand wrote:
>>>> On 24.08.21 20:46, Robin Murphy wrote:
>>>>> On 2021-08-24 19:28, Mike Rapoport wrote:
>>>>>> On Tue, Aug 24, 2021 at 06:37:41PM +0100, Catalin Marinas wrote:
>>>>>>> On Tue, Aug 24, 2021 at 03:40:47PM +0200, Alex Bee wrote:
>>>>>>>> it seems there is a regression in arm64 memory mapping in 5.14,
>>>>>>>> since it
>>>>>>>> fails on Rockchip RK3328 when the pl330 dmac tries to map with:
>>>>>>>>
>>>>>>>>  ? ------------[ cut here ]------------
>>>>>>>>  ? WARNING: CPU: 2 PID: 373 at kernel/dma/mapping.c:235
>>>>>>>> dma_map_resource+0x68/0xc0
>>>>>>>>  ? Modules linked in: spi_rockchip(+) fuse
>>>>>>>>  ? CPU: 2 PID: 373 Comm: systemd-udevd Not tainted 5.14.0-rc7 #1
>>>>>>>>  ? Hardware name: Pine64 Rock64 (DT)
>>>>>>>>  ? pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
>>>>>>>>  ? pc : dma_map_resource+0x68/0xc0
>>>>>>>>  ? lr : pl330_prep_slave_fifo+0x78/0xd0
>>>>>>>>  ? sp : ffff800012102ae0
>>>>>>>>  ? x29: ffff800012102ae0 x28: ffff000005c94800 x27: 0000000000000000
>>>>>>>>  ? x26: ffff000000566bd0 x25: 0000000000000001 x24: 0000000000000001
>>>>>>>>  ? x23: 0000000000000002 x22: ffff000000628c00 x21: 0000000000000001
>>>>>>>>  ? x20: ffff000000566bd0 x19: 0000000000000001 x18: 0000000000000000
>>>>>>>>  ? x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
>>>>>>>>  ? x14: 0000000000000277 x13: 0000000000000001 x12: 0000000000000000
>>>>>>>>  ? x11: 0000000000000001 x10: 00000000000008e0 x9 : ffff800012102a80
>>>>>>>>  ? x8 : ffff000000d14b80 x7 : ffff0000fe7b12f0 x6 : ffff0000fe7b1100
>>>>>>>>  ? x5 : fffffc000000000f x4 : 0000000000000000 x3 : 0000000000000001
>>>>>>>>  ? x2 : 0000000000000001 x1 : 00000000ff190800 x0 : ffff000000628c00
>>>>>>>>  ? Call trace:
>>>>>>>>  ??? dma_map_resource+0x68/0xc0
>>>>>>>>  ??? pl330_prep_slave_sg+0x58/0x220
>>>>>>>>  ??? rockchip_spi_prepare_dma+0xd8/0x2c0 [spi_rockchip]
>>>>>>>>  ??? rockchip_spi_transfer_one+0x294/0x3d8 [spi_rockchip]
>>>>>>> [...]
>>>>>>>> Note: This does not relate to the spi driver - when disabling
>>>>>>>> this device in
>>>>>>>> the device tree it fails for any other (i2s, for instance) which
>>>>>>>> uses dma.
>>>>>>>> Commenting out the failing check at [1], however, helps and the
>>>>>>>> mapping
>>>>>>>> works again.
>>>>>>
>>>>>>> Do you know which address dma_map_resource() is trying to map (maybe
>>>>>>> add some printk())? It's not supposed to map RAM, hence the warning.
>>>>>>> Random guess, the address is 0xff190800 (based on the x1 above but
>>>>>>> the
>>>>>>> regs might as well be mangled).
>>>>>>
>>>>>> 0xff190800 will cause this warning for sure. It has a memory map,
>>>>>> but it is
>>>>>> not RAM so old version of pfn_valid() would return 0 and the new one
>>>>>> returns 1.
>>>>>
>>>>> How does that happen, though? It's not a memory address, and it's not
>>>>> even within the bounds of anywhere there should or could be memory.
>>>>> This
>>>>> SoC has a simple memory map - everything from 0 to 0xfeffffff goes to
>>>>> the DRAM controller (which may not all be populated, and may have
>>>>> pieces
>>>>> carved out by secure firmware), while 0xff000000-0xffffffff is MMIO.
>>>>> Why
>>>>> do we have pages (or at least the assumption of pages) for somewhere
>>>>> which by all rights should not have them?
>>>>
>>>> Simple: we allocate the vmemmap for whole sections (e.g., 128 MiB) to
>>>> avoid
>>>> any such hacks. If there is a memory hole, it gets a memmap as well.
> 
> Urgh, apologies for being slow. This case isn't a memory hole as such,
> but I failed to consider the *ends* of memory not being section-aligned
> and leading to an overlap anyway.
> 
>>>> Tricking pfn_valid() into returning "false" where we actually have a
>>>> memmap
>>>> only makes it look like there is no memmap; but there is one, and
>>>> it's PG_reserved.
>>>
>>> I can see the documentation for pfn_valid() does not claim anything more
>>> than the presence of an memmap entry. But I wonder whether the confusion
>>> is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
>>> assumes __va() can be used on pfn_valid(), though I suspect it relies on
>>> the calling function to check that the resource was RAM. The arm64
>>> kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
>>> standard memcpy on it, which wouldn't work for I/O (should we change
>>> this check to pfn_is_map_memory() for arm64?).
>>>
>>
>> kern_addr_valid() checks that there is a direct map entry, and that the
>> mapped address has a valid mmap. (copied from x86-64)
>>
>> Would you expect to have a direct map for memory holes and similar (IOW,
>> !System RAM)?
> 
> Probably - we can have no-map regions for firmware-reserved RAM which I
> believe end up as PG_reserved if they're small enough, for the same
> reasoning as this case.
> 
>>>>>>> Either pfn_valid() gets confused in 5.14 or something is wrong
>>>>>>> with the
>>>>>>> DT. I have a suspicion it's the former since reverting the above
>>>>>>> commit
>>>>>>> makes it disappear.
>>>>>>
>>>>>> I think pfn_valid() actually behaves as expected but the caller is
>>>>>> wrong
>>>>>> because pfn_valid != RAM (this applies btw to !arm64 as well).
>>>>>>
>>>>>>  ????/* Don't allow RAM to be mapped */
>>>>>>  ????if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
>>>>>>  ??????? return DMA_MAPPING_ERROR;
>>>>>>
>>>>>> Alex, can you please try this patch:
>>>>>
>>>>> That will certainly paper over the issue, but it's avoiding the
>>>>> question
>>>>> of what went wrong with the memory map in the first place. The comment
>>>>> is indeed a bit inaccurate, but ultimately dma_map_resource() exists
>>>>> for
>>>>> addresses that would be wrong to pass to dma_map_page(), so I believe
>>>>> pfn_valid() is still the correct check.
>>>>
>>>> If we want to check for RAM, pfn_valid() would be wrong. If we want
>>>> to check
>>>> for "is there a memmap, for whatever lives or does not live there",
>>>> pfn_valid() is the right check.
>>>
>>> So what should the DMA code use instead? Last time we needed something
>>> similar, the recommendation was to use pfn_to_online_page(). Mike is
>>> suggesting memblock_is_memory().
>>
>> We use pfn_to_online_page() when we want to know if it's system RAM and
>> that the memmap actually contains something sane (-> memmap content has
>> a well defined state).

Sorry that was only partially right: to be more precise 
pfn_to_online_page() might also succeeds on memory holes and similar 
(essentially everywhere where we don't have CONFIG_HAVE_ARCH_PFN_VALID), 
it just means that there is a memmap and that the memmap has a well 
defined. If it's system RAM, it's online and either getting used or 
lying around as free in the buddy.

For example, pfn_to_online_page() won't succeed on ZONE_DEVICE memory, 
while pfn_valid() will.


>>
>> You can have offline memory blocks where pfn_to_online_page() would
>> return "false", memblock_is_memory() would return "true". IOW, there is
>> a memmap, it's System RAM, but the memmap is stale and not trustworthy.
> 
> That's fine - offline memory is doubly-invalid to map as an MMIO resource :)
> 
>> If you want to make sure no System RAM (online/offline/...) will get
>> mapped, memblock_is_memory() should be the right thing to use. I recall
>> that x86 traverse the resource tree instead to exclude system ram
>> regions similarly.
> 
> I'm thinking that "pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn))"

For offline memory blocks or for ZONE_DEVICE memory where pfn_valid() 
succeeds, the memmap might be stale and not contain anything reasonable. 
So the PageReserved() check can be problematic.

Also note that PageReserved() has plenty of different semantics (see 
PG_reserved in include/linux/page-flags.h )

> might be the closest thing to what I'd like to express - does that seem
> sensible at all? The one thing I'm not quite sure about is the
> interaction with P2P mappings of ZONE_DEVICE, but that's also true of
> the previous behaviour, and I'm not aware that the usage model has been
> fully nailed down yet, so I suspect we have some wiggle room. At worst,

Yes.

> false negatives in certain situations wouldn't be the end of the world,
> since this is merely a sanity check for something which is expected to
> be a no-op the vast majority of the time, so being unobtrusive is more
> important than being exhaustive.

Right.

-- 
Thanks,

David / dhildenb



From caihuoqing at baidu.com  Wed Aug 25 04:21:45 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 25 Aug 2021 19:21:45 +0800
Subject: [PATCH 0/2] crypto: stm32 - Add support of COMPILE_TEST
Message-ID: <20210825112147.2669-1-caihuoqing@baidu.com>

it's helpful for complie test in other platform(e.g.X86

Cai Huoqing (2):
  crypto: stm32 - Add support of COMPILE_TEST
  crypto: stm32 - open the configuration for COMPILE_TEST

 drivers/crypto/Makefile      | 2 +-
 drivers/crypto/stm32/Kconfig | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

-- 
2.25.1



From caihuoqing at baidu.com  Wed Aug 25 04:21:46 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 25 Aug 2021 19:21:46 +0800
Subject: [PATCH 1/2] crypto: stm32 - Add support of COMPILE_TEST
In-Reply-To: <20210825112147.2669-1-caihuoqing@baidu.com>
References: <20210825112147.2669-1-caihuoqing@baidu.com>
Message-ID: <20210825112147.2669-2-caihuoqing@baidu.com>

it's helpful for complie test in other platform(e.g.X86)

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/crypto/stm32/Kconfig | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/stm32/Kconfig b/drivers/crypto/stm32/Kconfig
index 4a4c3284ae1f..0fa30260300f 100644
--- a/drivers/crypto/stm32/Kconfig
+++ b/drivers/crypto/stm32/Kconfig
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config CRYPTO_DEV_STM32_CRC
 	tristate "Support for STM32 crc accelerators"
-	depends on ARCH_STM32
+	depends on ARCH_STM32 || (COMPILE_TEST && OF)
 	select CRYPTO_HASH
 	select CRC32
 	help
@@ -10,7 +10,7 @@ config CRYPTO_DEV_STM32_CRC
 
 config CRYPTO_DEV_STM32_HASH
 	tristate "Support for STM32 hash accelerators"
-	depends on ARCH_STM32
+	depends on ARCH_STM32 || (COMPILE_TEST && OF)
 	depends on HAS_DMA
 	select CRYPTO_HASH
 	select CRYPTO_MD5
@@ -23,7 +23,7 @@ config CRYPTO_DEV_STM32_HASH
 
 config CRYPTO_DEV_STM32_CRYP
 	tristate "Support for STM32 cryp accelerators"
-	depends on ARCH_STM32
+	depends on ARCH_STM32 || (COMPILE_TEST && OF)
 	select CRYPTO_HASH
 	select CRYPTO_ENGINE
 	select CRYPTO_LIB_DES
-- 
2.25.1



From caihuoqing at baidu.com  Wed Aug 25 04:21:47 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 25 Aug 2021 19:21:47 +0800
Subject: [PATCH 2/2] crypto: stm32 - open the configuration for COMPILE_TEST
In-Reply-To: <20210825112147.2669-1-caihuoqing@baidu.com>
References: <20210825112147.2669-1-caihuoqing@baidu.com>
Message-ID: <20210825112147.2669-3-caihuoqing@baidu.com>

it could be opened for complie test in other platform(e.g.X86)

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/crypto/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 1fe5120eb966..17b640de1823 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
 obj-$(CONFIG_CRYPTO_DEV_SA2UL) += sa2ul.o
 obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
 obj-$(CONFIG_CRYPTO_DEV_SL3516) += gemini/
-obj-$(CONFIG_ARCH_STM32) += stm32/
+obj-y += stm32/
 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
 obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
 obj-$(CONFIG_CRYPTO_DEV_VIRTIO) += virtio/
-- 
2.25.1



From baruch at tkos.co.il  Wed Aug 25 04:15:38 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 14:15:38 +0300
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
 <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
Message-ID: <87o89lahqp.fsf@tarshish>

Hi Rob,

On Fri, Aug 06 2021, Rob Herring wrote:
> On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
>>
>> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>>
>> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
>> platform.
>>
>> The code is based on downstream Codeaurora kernel v5.4. Split out the
>> DBI registers access part from .init into .post_init. DBI registers are
>> only accessible after phy_power_on().
>>
>> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
>> ---
>> v2:
>>   * Drop ATU configuration; rely on common code instead
>>
>>   * Use more common register macros
>>
>>   * Use bulk clk and reset APIs
>> ---
>>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
>>  drivers/pci/controller/dwc/pcie-qcom.c       | 150 +++++++++++++++++++
>>  2 files changed, 151 insertions(+)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
>> index ceb359b6e6a6..346462c74a3e 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware.h
>> +++ b/drivers/pci/controller/dwc/pcie-designware.h
>> @@ -76,6 +76,7 @@
>>
>>  #define GEN3_RELATED_OFF                       0x890
>>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL   BIT(0)
>> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS    BIT(13)
>>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE       BIT(16)
>>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
>>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK  GENMASK(25, 24)
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index 8a7a300163e5..93766aee3e7c 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -52,6 +52,10 @@
>>  #define PCIE20_PARF_DBI_BASE_ADDR              0x168
>>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16C
>>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL       0x174
>> +#define AHB_CLK_EN                             BIT(0)
>> +#define MSTR_AXI_CLK_EN                                BIT(1)
>> +#define BYPASS                                 BIT(4)
>> +
>>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT      0x178
>>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2   0x1A8
>>  #define PCIE20_PARF_LTSSM                      0x1B0
>> @@ -94,6 +98,12 @@
>>  #define SLV_ADDR_SPACE_SZ                      0x10000000
>>
>>  #define PCIE20_LNK_CONTROL2_LINK_STATUS2       0xa0
>> +#define PCIE_CAP_CURR_DEEMPHASIS               BIT(16)
>
> Isn't this a standard register field?

I don't know. I could not find any reference to this field or the
registers it's part of.
n
>> +#define SPEED_GEN1                             0x1
>> +#define SPEED_GEN2                             0x2
>> +#define SPEED_GEN3                             0x3
>
> And these?
>
> There's already some common DWC code for setting the link speed.

dw_pcie_link_set_max_speed() deals with other registers, as far as I can
see.

>> +#define AXI_CLK_RATE                           200000000
>> +#define RCHNG_CLK_RATE                         100000000
>>
>>  #define DEVICE_TYPE_RC                         0x4

[snip]

>> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +       struct dw_pcie *pci = pcie->pci;
>> +       u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
>> +       u32 val;
>> +       int i;
>> +
>> +       writel(SLV_ADDR_SPACE_SZ,
>> +               pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
>> +
>> +       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
>> +       val &= ~BIT(0);
>> +       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
>> +
>> +       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
>> +
>> +       writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
>> +       writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
>> +               pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
>> +       writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
>> +               | GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
>> +               pci->dbi_base + GEN3_RELATED_OFF);
>> +
>> +       writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
>> +               | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
>> +               AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
>> +               pcie->parf + PCIE20_PARF_SYS_CTRL);
>> +
>> +       writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
>> +
>> +       dw_pcie_dbi_ro_wr_en(pci);
>> +       writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
>> +
>> +       /* Configure PCIe link capabilities for ASPM */
>> +       val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
>> +       val &= ~PCI_EXP_LNKCAP_ASPMS;
>> +       writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
>> +
>> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
>> +                       PCI_EXP_DEVCTL2);
>> +
>> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
>> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);
>
> Doesn't this overwrite the prior register write?

It does. There are two mistakes here. The writel() above should set
PCIE20_DEVICE_CONTROL2_STATUS2 (offset 0x98). This writel() should set
PCIE20_LNK_CONTROL2_LINK_STATUS2 (offset 0xa0). So both are wrong.

>> +
>> +       for (i = 0;i < 256;i++)
>> +               writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
>> +                               + (4 * i));
>> +
>> +       return 0;
>> +}

Thanks,
baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From wenst at chromium.org  Wed Aug 25 04:26:21 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 19:26:21 +0800
Subject: [PATCH 20/22] clk: mediatek: Add MT8195 wpesys clock support
In-Reply-To: <20210616224743.5109-21-chun-jie.chen@mediatek.com>
References: <20210616224743.5109-1-chun-jie.chen@mediatek.com>
 <20210616224743.5109-21-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5GF6e+uo31TaStjsR_baJC2Tug_zkaZpw_Ww76HBV0aSQ@mail.gmail.com>

On Thu, Jun 17, 2021 at 7:12 AM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 wpesys clock providers
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Kconfig          |   6 ++
>  drivers/clk/mediatek/Makefile         |   1 +
>  drivers/clk/mediatek/clk-mt8195-wpe.c | 145 ++++++++++++++++++++++++++
>  3 files changed, 152 insertions(+)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-wpe.c
>
> diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
> index 91b1c19da1ab..5089bacdf0a5 100644
> --- a/drivers/clk/mediatek/Kconfig
> +++ b/drivers/clk/mediatek/Kconfig
> @@ -678,6 +678,12 @@ config COMMON_CLK_MT8195_VPPSYS1
>         help
>           This driver supports MediaTek MT8195 vppsys1 clocks.
>
> +config COMMON_CLK_MT8195_WPESYS
> +       bool "Clock driver for MediaTek MT8195 wpesys"
> +       depends on COMMON_CLK_MT8195
> +       help
> +         This driver supports MediaTek MT8195 wpesys clocks.
> +
>  config COMMON_CLK_MT8516
>         bool "Clock driver for MediaTek MT8516"
>         depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index fbf57473bb91..32cfb0030d92 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -96,5 +96,6 @@ obj-$(CONFIG_COMMON_CLK_MT8195_VDOSYS1) += clk-mt8195-vdo1.o
>  obj-$(CONFIG_COMMON_CLK_MT8195_VENCSYS) += clk-mt8195-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8195_VPPSYS0) += clk-mt8195-vpp0.o
>  obj-$(CONFIG_COMMON_CLK_MT8195_VPPSYS1) += clk-mt8195-vpp1.o
> +obj-$(CONFIG_COMMON_CLK_MT8195_WPESYS) += clk-mt8195-wpe.o
>  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
>  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> diff --git a/drivers/clk/mediatek/clk-mt8195-wpe.c b/drivers/clk/mediatek/clk-mt8195-wpe.c
> new file mode 100644
> index 000000000000..99e8b1297ef7
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8195-wpe.c
> @@ -0,0 +1,145 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +//
> +// Copyright (c) 2021 MediaTek Inc.
> +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-gate.h"
> +
> +#include <dt-bindings/clock/mt8195-clk.h>
> +
> +static const struct mtk_gate_regs wpe_cg_regs = {
> +       .set_ofs = 0x0,
> +       .clr_ofs = 0x0,
> +       .sta_ofs = 0x0,
> +};
> +
> +static const struct mtk_gate_regs wpe_vpp0_cg_regs = {
> +       .set_ofs = 0x58,
> +       .clr_ofs = 0x58,
> +       .sta_ofs = 0x58,
> +};
> +
> +static const struct mtk_gate_regs wpe_vpp1_cg_regs = {
> +       .set_ofs = 0x5c,
> +       .clr_ofs = 0x5c,
> +       .sta_ofs = 0x5c,
> +};
> +
> +#define GATE_WPE(_id, _name, _parent, _shift)                  \
> +       GATE_MTK(_id, _name, _parent, &wpe_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> +
> +#define GATE_WPE_VPP0(_id, _name, _parent, _shift)                     \
> +       GATE_MTK(_id, _name, _parent, &wpe_vpp0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> +
> +#define GATE_WPE_VPP1(_id, _name, _parent, _shift)                     \
> +       GATE_MTK(_id, _name, _parent, &wpe_vpp1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> +
> +static const struct mtk_gate wpe_clks[] = {
> +       GATE_WPE(CLK_WPE_VPP0, "wpe_vpp0", "wpe_vpp_sel", 16),
> +       GATE_WPE(CLK_WPE_VPP1, "wpe_vpp1", "wpe_vpp_sel", 17),
> +       GATE_WPE(CLK_WPE_SMI_LARB7, "wpe_smi_larb7", "wpe_vpp_sel", 18),
> +       GATE_WPE(CLK_WPE_SMI_LARB8, "wpe_smi_larb8", "wpe_vpp_sel", 19),
> +       GATE_WPE(CLK_WPE_EVENT_TX, "wpe_event_tx", "wpe_vpp_sel", 20),
> +       GATE_WPE(CLK_WPE_SMI_LARB7_P, "wpe_smi_larb7_p", "wpe_vpp_sel", 24),
> +       GATE_WPE(CLK_WPE_SMI_LARB8_P, "wpe_smi_larb8_p", "wpe_vpp_sel", 25),
> +};
> +
> +static const struct mtk_gate wpe_vpp0_clks[] = {
> +       /* WPE_VPP0 */
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_VGEN, "wpe_vpp0_vgen", "img_sel", 0),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_EXT, "wpe_vpp0_ext", "img_sel", 1),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_VFC, "wpe_vpp0_vfc", "img_sel", 2),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH0_TOP, "wpe_vpp0_cach0_top", "img_sel", 3),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH0_DMA, "wpe_vpp0_cach0_dma", "img_sel", 4),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH1_TOP, "wpe_vpp0_cach1_top", "img_sel", 5),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH1_DMA, "wpe_vpp0_cach1_dma", "img_sel", 6),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH2_TOP, "wpe_vpp0_cach2_top", "img_sel", 7),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH2_DMA, "wpe_vpp0_cach2_dma", "img_sel", 8),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH3_TOP, "wpe_vpp0_cach3_top", "img_sel", 9),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH3_DMA, "wpe_vpp0_cach3_dma", "img_sel", 10),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_PSP, "wpe_vpp0_psp", "img_sel", 11),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_PSP2, "wpe_vpp0_psp2", "img_sel", 12),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_SYNC, "wpe_vpp0_sync", "img_sel", 13),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_C24, "wpe_vpp0_c24", "img_sel", 14),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_MDP_CROP, "wpe_vpp0_mdp_crop", "img_sel", 15),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_ISP_CROP, "wpe_vpp0_isp_crop", "img_sel", 16),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_TOP, "wpe_vpp0_top", "img_sel", 17),
> +       /* WPE_VPP1 */
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_VECI, "wpe_vpp0_veci", "img_sel", 0),
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_VEC2I, "wpe_vpp0_vec2i", "img_sel", 1),
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_VEC3I, "wpe_vpp0_vec3i", "img_sel", 2),
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_WPEO, "wpe_vpp0_wpeo", "img_sel", 3),
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_MSKO, "wpe_vpp0_msko", "img_sel", 4),
> +};
> +
> +static const struct mtk_gate wpe_vpp1_clks[] = {
> +       /* WPE_VPP0 */
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_VGEN, "wpe_vpp1_vgen", "img_sel", 0),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_EXT, "wpe_vpp1_ext", "img_sel", 1),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_VFC, "wpe_vpp1_vfc", "img_sel", 2),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH0_TOP, "wpe_vpp1_cach0_top", "img_sel", 3),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH0_DMA, "wpe_vpp1_cach0_dma", "img_sel", 4),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH1_TOP, "wpe_vpp1_cach1_top", "img_sel", 5),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH1_DMA, "wpe_vpp1_cach1_dma", "img_sel", 6),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH2_TOP, "wpe_vpp1_cach2_top", "img_sel", 7),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH2_DMA, "wpe_vpp1_cach2_dma", "img_sel", 8),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH3_TOP, "wpe_vpp1_cach3_top", "img_sel", 9),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH3_DMA, "wpe_vpp1_cach3_dma", "img_sel", 10),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_PSP, "wpe_vpp1_psp", "img_sel", 11),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_PSP2, "wpe_vpp1_psp2", "img_sel", 12),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_SYNC, "wpe_vpp1_sync", "img_sel", 13),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_C24, "wpe_vpp1_c24", "img_sel", 14),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_MDP_CROP, "wpe_vpp1_mdp_crop", "img_sel", 15),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_ISP_CROP, "wpe_vpp1_isp_crop", "img_sel", 16),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_TOP, "wpe_vpp1_top", "img_sel", 17),
> +       /* WPE_VPP1 */
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_VECI, "wpe_vpp1_veci", "img_sel", 0),
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_VEC2I, "wpe_vpp1_vec2i", "img_sel", 1),
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_VEC3I, "wpe_vpp1_vec3i", "img_sel", 2),
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_WPEO, "wpe_vpp1_wpeo", "img_sel", 3),
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_MSKO, "wpe_vpp1_msko", "img_sel", 4),
> +};
> +
> +static const struct mtk_clk_desc wpe_desc = {
> +       .clks = wpe_clks,
> +       .num_clks = ARRAY_SIZE(wpe_clks),
> +};
> +
> +static const struct mtk_clk_desc wpe_vpp0_desc = {
> +       .clks = wpe_vpp0_clks,
> +       .num_clks = ARRAY_SIZE(wpe_vpp0_clks),
> +};
> +
> +static const struct mtk_clk_desc wpe_vpp1_desc = {
> +       .clks = wpe_vpp1_clks,
> +       .num_clks = ARRAY_SIZE(wpe_vpp1_clks),
> +};
> +
> +static const struct of_device_id of_match_clk_mt8195_wpe[] = {
> +       {
> +               .compatible = "mediatek,mt8195-wpesys",
> +               .data = &wpe_desc,
> +       }, {
> +               .compatible = "mediatek,mt8195-wpesys_vpp0",
> +               .data = &wpe_vpp0_desc,
> +       }, {
> +               .compatible = "mediatek,mt8195-wpesys_vpp1",
> +               .data = &wpe_vpp1_desc,

Same comment as vencsys patch: wpesys_vpp0 and wpesys_vpp1 look the same.
Are they identical hardware blocks? Are different compatible strings
really needed?

I suggest adding clock-output-names to the device tree, and patching
mtk_clk_register_gates_with_dev() to try to get a clock name from the
device tree, and falling back to the predefined name in the list.
Something like:

<---------------
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 74890759e98c..71e856c22960 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -125,11 +125,15 @@ int mtk_clk_register_gates_with_dev(struct
device_node *node,

        for (i = 0; i < num; i++) {
                const struct mtk_gate *gate = &clks[i];
+               const char *name = gate->name;

                if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
                        continue;

-               clk = mtk_clk_register_gate(gate->name, gate->parent_name,
+               of_property_read_string(node, "clock-output-names", gate->id,
+                                       &name);
+
+               clk = mtk_clk_register_gate(name, gate->parent_name,
                                regmap,
                                gate->regs->set_ofs,
                                gate->regs->clr_ofs,
<---------------
(tabs replaced with spaces, do not apply directly)


ChenYu


> +       }, {
> +               /* sentinel */
> +       }
> +};
> +
> +static struct platform_driver clk_mt8195_wpe_drv = {
> +       .probe = mtk_clk_simple_probe,
> +       .driver = {
> +               .name = "clk-mt8195-wpe",
> +               .of_match_table = of_match_clk_mt8195_wpe,
> +       },
> +};
> +
> +builtin_platform_driver(clk_mt8195_wpe_drv);
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From wenst at chromium.org  Wed Aug 25 04:34:42 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 19:34:42 +0800
Subject: [v2 22/24] clk: mediatek: Add MT8195 wpesys clock support
In-Reply-To: <20210820111504.350-23-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-23-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5Fde-Ka3qzaQR799AYTooKJWMgEkYio4cRLG4_1hasFXg@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:33 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 wpesys clock controllers which provide clock gate
> control in Wrapping Engine.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Makefile         |   2 +-
>  drivers/clk/mediatek/clk-mt8195-wpe.c | 143 ++++++++++++++++++++++++++
>  2 files changed, 144 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-wpe.c
>
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 402a809ff6ac..dfe7047c6795 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -83,6 +83,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
>  obj-$(CONFIG_COMMON_CLK_MT8195) += clk-mt8195-apmixedsys.o clk-mt8195-topckgen.o clk-mt8195-peri_ao.o clk-mt8195-infra_ao.o clk-mt8195-cam.o \
>                                         clk-mt8195-ccu.o clk-mt8195-img.o clk-mt8195-ipe.o clk-mt8195-mfg.o clk-mt8195-scp_adsp.o \
>                                         clk-mt8195-vdec.o clk-mt8195-vdo0.o clk-mt8195-vdo1.o clk-mt8195-venc.o clk-mt8195-vpp0.o \
> -                                       clk-mt8195-vpp1.o
> +                                       clk-mt8195-vpp1.o clk-mt8195-wpe.o
>  obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
>  obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
> diff --git a/drivers/clk/mediatek/clk-mt8195-wpe.c b/drivers/clk/mediatek/clk-mt8195-wpe.c
> new file mode 100644
> index 000000000000..7e92a3cab497
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-mt8195-wpe.c
> @@ -0,0 +1,143 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Copyright (c) 2021 MediaTek Inc.
> +// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +
> +#include <dt-bindings/clock/mt8195-clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +static const struct mtk_gate_regs wpe_cg_regs = {
> +       .set_ofs = 0x0,
> +       .clr_ofs = 0x0,
> +       .sta_ofs = 0x0,
> +};
> +
> +static const struct mtk_gate_regs wpe_vpp0_cg_regs = {
> +       .set_ofs = 0x58,
> +       .clr_ofs = 0x58,
> +       .sta_ofs = 0x58,
> +};
> +
> +static const struct mtk_gate_regs wpe_vpp1_cg_regs = {
> +       .set_ofs = 0x5c,
> +       .clr_ofs = 0x5c,
> +       .sta_ofs = 0x5c,
> +};
> +
> +#define GATE_WPE(_id, _name, _parent, _shift)                  \
> +       GATE_MTK(_id, _name, _parent, &wpe_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> +
> +#define GATE_WPE_VPP0(_id, _name, _parent, _shift)                     \
> +       GATE_MTK(_id, _name, _parent, &wpe_vpp0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> +
> +#define GATE_WPE_VPP1(_id, _name, _parent, _shift)                     \
> +       GATE_MTK(_id, _name, _parent, &wpe_vpp1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
> +
> +static const struct mtk_gate wpe_clks[] = {
> +       GATE_WPE(CLK_WPE_VPP0, "wpe_vpp0", "top_wpe_vpp", 16),
> +       GATE_WPE(CLK_WPE_VPP1, "wpe_vpp1", "top_wpe_vpp", 17),
> +       GATE_WPE(CLK_WPE_SMI_LARB7, "wpe_smi_larb7", "top_wpe_vpp", 18),
> +       GATE_WPE(CLK_WPE_SMI_LARB8, "wpe_smi_larb8", "top_wpe_vpp", 19),
> +       GATE_WPE(CLK_WPE_EVENT_TX, "wpe_event_tx", "top_wpe_vpp", 20),
> +       GATE_WPE(CLK_WPE_SMI_LARB7_P, "wpe_smi_larb7_p", "top_wpe_vpp", 24),
> +       GATE_WPE(CLK_WPE_SMI_LARB8_P, "wpe_smi_larb8_p", "top_wpe_vpp", 25),
> +};
> +
> +static const struct mtk_gate wpe_vpp0_clks[] = {
> +       /* WPE_VPP0 */
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_VGEN, "wpe_vpp0_vgen", "top_img", 0),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_EXT, "wpe_vpp0_ext", "top_img", 1),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_VFC, "wpe_vpp0_vfc", "top_img", 2),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH0_TOP, "wpe_vpp0_cach0_top", "top_img", 3),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH0_DMA, "wpe_vpp0_cach0_dma", "top_img", 4),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH1_TOP, "wpe_vpp0_cach1_top", "top_img", 5),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH1_DMA, "wpe_vpp0_cach1_dma", "top_img", 6),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH2_TOP, "wpe_vpp0_cach2_top", "top_img", 7),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH2_DMA, "wpe_vpp0_cach2_dma", "top_img", 8),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH3_TOP, "wpe_vpp0_cach3_top", "top_img", 9),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_CACH3_DMA, "wpe_vpp0_cach3_dma", "top_img", 10),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_PSP, "wpe_vpp0_psp", "top_img", 11),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_PSP2, "wpe_vpp0_psp2", "top_img", 12),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_SYNC, "wpe_vpp0_sync", "top_img", 13),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_C24, "wpe_vpp0_c24", "top_img", 14),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_MDP_CROP, "wpe_vpp0_mdp_crop", "top_img", 15),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_ISP_CROP, "wpe_vpp0_isp_crop", "top_img", 16),
> +       GATE_WPE_VPP0(CLK_WPE_VPP0_TOP, "wpe_vpp0_top", "top_img", 17),
> +       /* WPE_VPP1 */
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_VECI, "wpe_vpp0_veci", "top_img", 0),
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_VEC2I, "wpe_vpp0_vec2i", "top_img", 1),
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_VEC3I, "wpe_vpp0_vec3i", "top_img", 2),
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_WPEO, "wpe_vpp0_wpeo", "top_img", 3),
> +       GATE_WPE_VPP1(CLK_WPE_VPP0_MSKO, "wpe_vpp0_msko", "top_img", 4),
> +};
> +
> +static const struct mtk_gate wpe_vpp1_clks[] = {
> +       /* WPE_VPP0 */
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_VGEN, "wpe_vpp1_vgen", "top_img", 0),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_EXT, "wpe_vpp1_ext", "top_img", 1),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_VFC, "wpe_vpp1_vfc", "top_img", 2),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH0_TOP, "wpe_vpp1_cach0_top", "top_img", 3),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH0_DMA, "wpe_vpp1_cach0_dma", "top_img", 4),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH1_TOP, "wpe_vpp1_cach1_top", "top_img", 5),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH1_DMA, "wpe_vpp1_cach1_dma", "top_img", 6),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH2_TOP, "wpe_vpp1_cach2_top", "top_img", 7),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH2_DMA, "wpe_vpp1_cach2_dma", "top_img", 8),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH3_TOP, "wpe_vpp1_cach3_top", "top_img", 9),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_CACH3_DMA, "wpe_vpp1_cach3_dma", "top_img", 10),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_PSP, "wpe_vpp1_psp", "top_img", 11),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_PSP2, "wpe_vpp1_psp2", "top_img", 12),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_SYNC, "wpe_vpp1_sync", "top_img", 13),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_C24, "wpe_vpp1_c24", "top_img", 14),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_MDP_CROP, "wpe_vpp1_mdp_crop", "top_img", 15),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_ISP_CROP, "wpe_vpp1_isp_crop", "top_img", 16),
> +       GATE_WPE_VPP0(CLK_WPE_VPP1_TOP, "wpe_vpp1_top", "top_img", 17),
> +       /* WPE_VPP1 */
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_VECI, "wpe_vpp1_veci", "top_img", 0),
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_VEC2I, "wpe_vpp1_vec2i", "top_img", 1),
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_VEC3I, "wpe_vpp1_vec3i", "top_img", 2),
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_WPEO, "wpe_vpp1_wpeo", "top_img", 3),
> +       GATE_WPE_VPP1(CLK_WPE_VPP1_MSKO, "wpe_vpp1_msko", "top_img", 4),

(Reply to correct patch revision...)

Same comment as vencsys patch: wpesys_vpp0 and wpesys_vpp1 look the same.
Are they identical hardware blocks? Are different compatible strings
really needed?

I suggest adding clock-output-names to the device tree, and patching
mtk_clk_register_gates_with_dev() to try to get a clock name from the
device tree, and falling back to the predefined name in the list.
Something like:

<---------------
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 74890759e98c..71e856c22960 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -125,11 +125,15 @@ int mtk_clk_register_gates_with_dev(struct
device_node *node,

        for (i = 0; i < num; i++) {
                const struct mtk_gate *gate = &clks[i];
+               const char *name = gate->name;

                if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
                        continue;

-               clk = mtk_clk_register_gate(gate->name, gate->parent_name,
+               of_property_read_string(node, "clock-output-names", gate->id,
+                                       &name);
+
+               clk = mtk_clk_register_gate(name, gate->parent_name,
                                regmap,
                                gate->regs->set_ofs,
                                gate->regs->clr_ofs,
<---------------
(tabs replaced with spaces, do not apply directly)


ChenYu


> +};
> +
> +static const struct mtk_clk_desc wpe_desc = {
> +       .clks = wpe_clks,
> +       .num_clks = ARRAY_SIZE(wpe_clks),
> +};
> +
> +static const struct mtk_clk_desc wpe_vpp0_desc = {
> +       .clks = wpe_vpp0_clks,
> +       .num_clks = ARRAY_SIZE(wpe_vpp0_clks),
> +};
> +
> +static const struct mtk_clk_desc wpe_vpp1_desc = {
> +       .clks = wpe_vpp1_clks,
> +       .num_clks = ARRAY_SIZE(wpe_vpp1_clks),
> +};
> +
> +static const struct of_device_id of_match_clk_mt8195_wpe[] = {
> +       {
> +               .compatible = "mediatek,mt8195-wpesys",
> +               .data = &wpe_desc,
> +       }, {
> +               .compatible = "mediatek,mt8195-wpesys_vpp0",
> +               .data = &wpe_vpp0_desc,
> +       }, {
> +               .compatible = "mediatek,mt8195-wpesys_vpp1",
> +               .data = &wpe_vpp1_desc,
> +       }, {
> +               /* sentinel */
> +       }
> +};
> +
> +static struct platform_driver clk_mt8195_wpe_drv = {
> +       .probe = mtk_clk_simple_probe,
> +       .driver = {
> +               .name = "clk-mt8195-wpe",
> +               .of_match_table = of_match_clk_mt8195_wpe,
> +       },
> +};
> +builtin_platform_driver(clk_mt8195_wpe_drv);
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From wenst at chromium.org  Wed Aug 25 04:39:54 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 25 Aug 2021 19:39:54 +0800
Subject: [v2 02/24] clk: mediatek: Add dt-bindings of MT8195 clocks
In-Reply-To: <20210820111504.350-3-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-3-chun-jie.chen@mediatek.com>
Message-ID: <CAGXv+5Eb4ZiXZXURvoApSEk_myhNpEugOhr2DrzvkxGfDKJneg@mail.gmail.com>

On Fri, Aug 20, 2021 at 7:17 PM Chun-Jie Chen
<chun-jie.chen at mediatek.com> wrote:
>
> Add MT8195 clock dt-bindings, include topckgen, apmixedsys,
> infracfg_ao, pericfg_ao and subsystem clocks.
>
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  include/dt-bindings/clock/mt8195-clk.h | 864 +++++++++++++++++++++++++
>  1 file changed, 864 insertions(+)
>  create mode 100644 include/dt-bindings/clock/mt8195-clk.h
>
> diff --git a/include/dt-bindings/clock/mt8195-clk.h b/include/dt-bindings/clock/mt8195-clk.h
> new file mode 100644
> index 000000000000..95cf812a0b37
> --- /dev/null
> +++ b/include/dt-bindings/clock/mt8195-clk.h
> @@ -0,0 +1,864 @@

[...]

> +/* WPESYS_VPP0 */
> +
> +#define CLK_WPE_VPP0_VECI              0
> +#define CLK_WPE_VPP0_VEC2I             1
> +#define CLK_WPE_VPP0_VEC3I             2
> +#define CLK_WPE_VPP0_WPEO              3
> +#define CLK_WPE_VPP0_MSKO              4
> +#define CLK_WPE_VPP0_VGEN              5
> +#define CLK_WPE_VPP0_EXT               6
> +#define CLK_WPE_VPP0_VFC               7
> +#define CLK_WPE_VPP0_CACH0_TOP         8
> +#define CLK_WPE_VPP0_CACH0_DMA         9
> +#define CLK_WPE_VPP0_CACH1_TOP         10
> +#define CLK_WPE_VPP0_CACH1_DMA         11
> +#define CLK_WPE_VPP0_CACH2_TOP         12
> +#define CLK_WPE_VPP0_CACH2_DMA         13
> +#define CLK_WPE_VPP0_CACH3_TOP         14
> +#define CLK_WPE_VPP0_CACH3_DMA         15
> +#define CLK_WPE_VPP0_PSP               16
> +#define CLK_WPE_VPP0_PSP2              17
> +#define CLK_WPE_VPP0_SYNC              18
> +#define CLK_WPE_VPP0_C24               19
> +#define CLK_WPE_VPP0_MDP_CROP          20
> +#define CLK_WPE_VPP0_ISP_CROP          21
> +#define CLK_WPE_VPP0_TOP               22
> +#define CLK_WPE_VPP0_NR_CLK            23
> +
> +/* WPESYS_VPP1 */
> +
> +#define CLK_WPE_VPP1_VECI              0
> +#define CLK_WPE_VPP1_VEC2I             1
> +#define CLK_WPE_VPP1_VEC3I             2
> +#define CLK_WPE_VPP1_WPEO              3
> +#define CLK_WPE_VPP1_MSKO              4
> +#define CLK_WPE_VPP1_VGEN              5
> +#define CLK_WPE_VPP1_EXT               6
> +#define CLK_WPE_VPP1_VFC               7
> +#define CLK_WPE_VPP1_CACH0_TOP         8
> +#define CLK_WPE_VPP1_CACH0_DMA         9
> +#define CLK_WPE_VPP1_CACH1_TOP         10
> +#define CLK_WPE_VPP1_CACH1_DMA         11
> +#define CLK_WPE_VPP1_CACH2_TOP         12
> +#define CLK_WPE_VPP1_CACH2_DMA         13
> +#define CLK_WPE_VPP1_CACH3_TOP         14
> +#define CLK_WPE_VPP1_CACH3_DMA         15
> +#define CLK_WPE_VPP1_PSP               16
> +#define CLK_WPE_VPP1_PSP2              17
> +#define CLK_WPE_VPP1_SYNC              18
> +#define CLK_WPE_VPP1_C24               19
> +#define CLK_WPE_VPP1_MDP_CROP          20
> +#define CLK_WPE_VPP1_ISP_CROP          21
> +#define CLK_WPE_VPP1_TOP               22
> +#define CLK_WPE_VPP1_NR_CLK            23

If WPE_VPP0 and WPE_VPP1 end up being identical hardware, then there's
no need to have two separate lists.

[...]

> +/* VENCSYS */
> +
> +#define CLK_VENC_LARB                  0
> +#define CLK_VENC_VENC                  1
> +#define CLK_VENC_JPGENC                        2
> +#define CLK_VENC_JPGDEC                        3
> +#define CLK_VENC_JPGDEC_C1             4
> +#define CLK_VENC_GALS                  5
> +#define CLK_VENC_NR_CLK                        6
> +
> +/* VENCSYS_CORE1 */
> +
> +#define CLK_VENC_CORE1_LARB            0
> +#define CLK_VENC_CORE1_VENC            1
> +#define CLK_VENC_CORE1_JPGENC          2
> +#define CLK_VENC_CORE1_JPGDEC          3
> +#define CLK_VENC_CORE1_JPGDEC_C1       4
> +#define CLK_VENC_CORE1_GALS            5
> +#define CLK_VENC_CORE1_NR_CLK          6

Same for VENC and VENC_CORE1.


ChenYu


From sumit.garg at linaro.org  Wed Aug 25 04:42:45 2021
From: sumit.garg at linaro.org (Sumit Garg)
Date: Wed, 25 Aug 2021 17:12:45 +0530
Subject: [PATCH v4 5/5] optee: add FF-A support
In-Reply-To: <20210819110655.739318-6-jens.wiklander@linaro.org>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
 <20210819110655.739318-6-jens.wiklander@linaro.org>
Message-ID: <CAFA6WYNHrej1_yMZejLpG5u1WjN5XvpmS-zKWdLVZu=DEWd6xA@mail.gmail.com>

On Thu, 19 Aug 2021 at 16:37, Jens Wiklander <jens.wiklander at linaro.org> wrote:
>
> Adds support for using FF-A [1] as transport to the OP-TEE driver.
>
> Introduces struct optee_msg_param_fmem which carries all information
> needed when OP-TEE is calling FFA_MEM_RETRIEVE_REQ to get the shared
> memory reference mapped by the hypervisor in S-EL2. Register usage is
> also updated to include the information needed.
>
> The FF-A part of this driver is enabled if CONFIG_ARM_FFA_TRANSPORT is
> enabled.
>
> [1] https://developer.arm.com/documentation/den0077/latest
> Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> ---
>  drivers/tee/optee/Makefile        |   3 +-
>  drivers/tee/optee/call.c          |  13 +-
>  drivers/tee/optee/core.c          |  16 +-
>  drivers/tee/optee/ffa_abi.c       | 907 ++++++++++++++++++++++++++++++
>  drivers/tee/optee/optee_ffa.h     | 153 +++++
>  drivers/tee/optee/optee_msg.h     |  27 +-
>  drivers/tee/optee/optee_private.h |  43 +-
>  7 files changed, 1148 insertions(+), 14 deletions(-)
>  create mode 100644 drivers/tee/optee/ffa_abi.c
>  create mode 100644 drivers/tee/optee/optee_ffa.h
>
> diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
> index e92f77462f40..dbfd83d3c4ae 100644
> --- a/drivers/tee/optee/Makefile
> +++ b/drivers/tee/optee/Makefile
> @@ -7,7 +7,8 @@ optee-objs += supp.o
>  optee-objs += device.o
>
>  optee-smc-abi-y = smc_abi.o
> -optee-objs += $(optee-ffa-abi-y)
> +optee-ffa-abi-$(CONFIG_ARM_FFA_TRANSPORT) = ffa_abi.o
> +optee-objs += $(optee-smc-abi-y) $(optee-ffa-abi-y)
>
>  # for tracing framework to find optee_trace.h
>  CFLAGS_smc_abi.o := -I$(src)
> diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
> index 3f81c168ed3f..87d739091055 100644
> --- a/drivers/tee/optee/call.c
> +++ b/drivers/tee/optee/call.c
> @@ -107,11 +107,20 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
>  struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params,
>                                   struct optee_msg_arg **msg_arg)
>  {
> +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> +       size_t sz = OPTEE_MSG_GET_ARG_SIZE(num_params);
>         struct tee_shm *shm;
>         struct optee_msg_arg *ma;
>
> -       shm = tee_shm_alloc(ctx, OPTEE_MSG_GET_ARG_SIZE(num_params),
> -                           TEE_SHM_MAPPED);
> +       /*
> +        * rpc_arg_count is set to the number of allocated parameters in
> +        * the RPC argument struct if a second MSG arg struct is expected.
> +        * The second arg struct will then be used for RPC.
> +        */
> +       if (optee->rpc_arg_count)
> +               sz += OPTEE_MSG_GET_ARG_SIZE(optee->rpc_arg_count);
> +
> +       shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED);
>         if (IS_ERR(shm))
>                 return shm;
>
> diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
> index e372ebaff5d6..c22cdf65451b 100644
> --- a/drivers/tee/optee/core.c
> +++ b/drivers/tee/optee/core.c
> @@ -160,15 +160,27 @@ void optee_remove_common(struct optee *optee)
>         mutex_destroy(&optee->call_queue.mutex);
>  }
>
> +static int smc_abi_rc;
> +static int ffa_abi_rc;
> +
>  static int optee_core_init(void)
>  {
> -       return optee_smc_abi_register();
> +       smc_abi_rc = optee_smc_abi_register();
> +       ffa_abi_rc = optee_ffa_abi_register();
> +
> +       /* If both failed there's no point with this module */
> +       if (smc_abi_rc && ffa_abi_rc)
> +               return smc_abi_rc;
> +       return 0;
>  }
>  module_init(optee_core_init);
>
>  static void optee_core_exit(void)
>  {
> -       optee_smc_abi_unregister();
> +       if (!smc_abi_rc)
> +               optee_smc_abi_unregister();
> +       if (!ffa_abi_rc)
> +               optee_ffa_abi_unregister();
>  }
>  module_exit(optee_core_exit);
>
> diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
> new file mode 100644
> index 000000000000..85dca49ac2ce
> --- /dev/null
> +++ b/drivers/tee/optee/ffa_abi.c
> @@ -0,0 +1,907 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2021, Linaro Limited
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/arm_ffa.h>
> +#include <linux/errno.h>
> +#include <linux/scatterlist.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/tee_drv.h>
> +#include <linux/types.h>
> +#include "optee_private.h"
> +#include "optee_ffa.h"
> +#include "optee_rpc_cmd.h"
> +
> +/*
> + * This file implement the FF-A ABI used when communicating with secure world
> + * OP-TEE OS via FF-A.
> + * This file is divided into the follow sections:

s/follow/following/

> + * 1. Maintain a hash table for lookup of a global FF-A memory handle
> + * 2. Convert between struct tee_param and struct optee_msg_param
> + * 3. Low level support functions to register shared memory in secure world
> + * 4. Dynamic shared memory pool based on alloc_pages()
> + * 5. Do a normal scheduled call into secure world
> + * 6. Driver initialization.
> + */
> +
> +/*
> + * 1. Maintain a hash table for lookup of a global FF-A memory handle
> + *
> + * FF-A assigns a global memory handle for each piece shared memory.
> + * This handle is then used when communicating with secure world.
> + *
> + * Main functions are optee_shm_add_ffa_handle() and optee_shm_rem_ffa_handle()
> + */
> +struct shm_rhash {
> +       struct tee_shm *shm;
> +       u64 global_id;
> +       struct rhash_head linkage;
> +};
> +
> +static void rh_free_fn(void *ptr, void *arg)
> +{
> +       kfree(ptr);
> +}
> +
> +static const struct rhashtable_params shm_rhash_params = {
> +       .head_offset = offsetof(struct shm_rhash, linkage),
> +       .key_len     = sizeof(u64),
> +       .key_offset  = offsetof(struct shm_rhash, global_id),
> +       .automatic_shrinking = true,
> +};
> +
> +static struct tee_shm *optee_shm_from_ffa_handle(struct optee *optee,
> +                                                u64 global_id)
> +{
> +       struct tee_shm *shm = NULL;
> +       struct shm_rhash *r;
> +
> +       mutex_lock(&optee->ffa.mutex);
> +       r = rhashtable_lookup_fast(&optee->ffa.global_ids, &global_id,
> +                                  shm_rhash_params);
> +       if (r)
> +               shm = r->shm;
> +       mutex_unlock(&optee->ffa.mutex);
> +
> +       return shm;
> +}
> +
> +static int optee_shm_add_ffa_handle(struct optee *optee, struct tee_shm *shm,
> +                                   u64 global_id)
> +{
> +       struct shm_rhash *r;
> +       int rc;
> +
> +       r = kmalloc(sizeof(*r), GFP_KERNEL);
> +       if (!r)
> +               return -ENOMEM;
> +       r->shm = shm;
> +       r->global_id = global_id;
> +
> +       mutex_lock(&optee->ffa.mutex);
> +       rc = rhashtable_lookup_insert_fast(&optee->ffa.global_ids, &r->linkage,
> +                                          shm_rhash_params);
> +       mutex_unlock(&optee->ffa.mutex);
> +
> +       if (rc)
> +               kfree(r);
> +
> +       return rc;
> +}
> +
> +static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id)
> +{
> +       struct shm_rhash *r;
> +       int rc = -ENOENT;
> +
> +       mutex_lock(&optee->ffa.mutex);
> +       r = rhashtable_lookup_fast(&optee->ffa.global_ids, &global_id,
> +                                  shm_rhash_params);
> +       if (r)
> +               rc = rhashtable_remove_fast(&optee->ffa.global_ids,
> +                                           &r->linkage, shm_rhash_params);
> +       mutex_unlock(&optee->ffa.mutex);
> +
> +       if (!rc)
> +               kfree(r);
> +
> +       return rc;
> +}
> +
> +/*
> + * 2. Convert between struct tee_param and struct optee_msg_param
> + *
> + * optee_ffa_from_msg_param() and optee_ffa_to_msg_param() are the main
> + * functions.
> + */
> +
> +static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
> +                                  u32 attr, const struct optee_msg_param *mp)
> +{
> +       struct tee_shm *shm = NULL;
> +       u64 offs_high = 0;
> +       u64 offs_low = 0;
> +
> +       p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
> +                 attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
> +       p->u.memref.size = mp->u.fmem.size;
> +
> +       if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID)
> +               shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id);
> +       p->u.memref.shm = shm;
> +
> +       if (shm) {
> +               offs_low = mp->u.fmem.offs_low;
> +               offs_high = mp->u.fmem.offs_high;
> +       }
> +       p->u.memref.shm_offs = offs_low | offs_high << 32;
> +}
> +
> +/**
> + * optee_ffa_from_msg_param() - convert from OPTEE_MSG parameters to
> + *                             struct tee_param
> + * @optee:     main service struct
> + * @params:    subsystem internal parameter representation
> + * @num_params:        number of elements in the parameter arrays
> + * @msg_params:        OPTEE_MSG parameters
> + *
> + * Returns 0 on success or <0 on failure
> + */
> +static int optee_ffa_from_msg_param(struct optee *optee,
> +                                   struct tee_param *params, size_t num_params,
> +                                   const struct optee_msg_param *msg_params)
> +{
> +       size_t n;
> +
> +       for (n = 0; n < num_params; n++) {
> +               struct tee_param *p = params + n;
> +               const struct optee_msg_param *mp = msg_params + n;
> +               u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
> +
> +               switch (attr) {
> +               case OPTEE_MSG_ATTR_TYPE_NONE:
> +                       p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> +                       memset(&p->u, 0, sizeof(p->u));
> +                       break;
> +               case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
> +               case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
> +               case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
> +                       optee_from_msg_param_value(p, attr, mp);
> +                       break;
> +               case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
> +               case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
> +               case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
> +                       from_msg_param_ffa_mem(optee, p, attr, mp);
> +                       break;
> +               default:
> +                       return -EINVAL;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
> +                               const struct tee_param *p)
> +{
> +       struct tee_shm *shm = p->u.memref.shm;
> +
> +       mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr -
> +                  TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
> +
> +       if (shm) {
> +               u64 shm_offs = p->u.memref.shm_offs;
> +
> +               mp->u.fmem.internal_offs = shm->offset;
> +
> +               mp->u.fmem.offs_low = shm_offs;
> +               mp->u.fmem.offs_high = shm_offs >> 32;
> +               /* Check that the entire offset could be stored. */
> +               if (mp->u.fmem.offs_high != shm_offs >> 32)
> +                       return -EINVAL;
> +
> +               mp->u.fmem.global_id = shm->sec_world_id;
> +       } else {
> +               memset(&mp->u, 0, sizeof(mp->u));
> +               mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
> +       }
> +       mp->u.fmem.size = p->u.memref.size;
> +
> +       return 0;
> +}
> +
> +/**
> + * optee_ffa_to_msg_param() - convert from struct tee_params to OPTEE_MSG
> + *                           parameters
> + * @optee:     main service struct
> + * @msg_params:        OPTEE_MSG parameters
> + * @num_params:        number of elements in the parameter arrays
> + * @params:    subsystem itnernal parameter representation
> + * Returns 0 on success or <0 on failure
> + */
> +static int optee_ffa_to_msg_param(struct optee *optee,
> +                                 struct optee_msg_param *msg_params,
> +                                 size_t num_params,
> +                                 const struct tee_param *params)
> +{
> +       size_t n;
> +
> +       for (n = 0; n < num_params; n++) {
> +               const struct tee_param *p = params + n;
> +               struct optee_msg_param *mp = msg_params + n;
> +
> +               switch (p->attr) {
> +               case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
> +                       mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
> +                       memset(&mp->u, 0, sizeof(mp->u));
> +                       break;
> +               case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
> +               case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
> +               case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
> +                       optee_to_msg_param_value(mp, p);
> +                       break;
> +               case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
> +               case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
> +               case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
> +                       if (to_msg_param_ffa_mem(mp, p))
> +                               return -EINVAL;
> +                       break;
> +               default:
> +                       return -EINVAL;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +/*
> + * 3. Low level support functions to register shared memory in secure world
> + *
> + * Functions to register and unregister shared memory both for normal
> + * clients and for tee-supplicant.
> + */
> +
> +static int optee_ffa_shm_register(struct tee_context *ctx, struct tee_shm *shm,
> +                                 struct page **pages, size_t num_pages,
> +                                 unsigned long start)
> +{
> +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> +       const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
> +       struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
> +       struct ffa_mem_region_attributes mem_attr = {
> +               .receiver = ffa_dev->vm_id,
> +               .attrs = FFA_MEM_RW,
> +       };
> +       struct ffa_mem_ops_args args = {
> +               .use_txbuf = true,
> +               .attrs = &mem_attr,
> +               .nattrs = 1,
> +       };
> +       struct sg_table sgt;
> +       int rc;
> +
> +       rc = optee_check_mem_type(start, num_pages);
> +       if (rc)
> +               return rc;
> +
> +       rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
> +                                      num_pages * PAGE_SIZE, GFP_KERNEL);
> +       if (rc)
> +               return rc;
> +       args.sg = sgt.sgl;
> +       rc = ffa_ops->memory_share(ffa_dev, &args);
> +       sg_free_table(&sgt);
> +       if (rc)
> +               return rc;
> +
> +       rc = optee_shm_add_ffa_handle(optee, shm, args.g_handle);
> +       if (rc) {
> +               ffa_ops->memory_reclaim(args.g_handle, 0);
> +               return rc;
> +       }
> +
> +       shm->sec_world_id = args.g_handle;
> +
> +       return 0;
> +}
> +
> +static int optee_ffa_shm_unregister(struct tee_context *ctx,
> +                                   struct tee_shm *shm)
> +{
> +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> +       const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
> +       struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
> +       u64 global_handle = shm->sec_world_id;
> +       struct ffa_send_direct_data data = {
> +               .data0 = OPTEE_FFA_UNREGISTER_SHM,
> +               .data1 = (u32)global_handle,
> +               .data2 = (u32)(global_handle >> 32)
> +       };
> +       int rc;
> +
> +       optee_shm_rem_ffa_handle(optee, global_handle);
> +       shm->sec_world_id = 0;
> +
> +       rc = ffa_ops->sync_send_receive(ffa_dev, &data);
> +       if (rc)
> +               pr_err("Unregister SHM id 0x%llx rc %d\n", global_handle, rc);
> +
> +       rc = ffa_ops->memory_reclaim(global_handle, 0);
> +       if (rc)
> +               pr_err("mem_reclain: 0x%llx %d", global_handle, rc);
> +
> +       return rc;
> +}
> +
> +static int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
> +                                        struct tee_shm *shm)
> +{
> +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> +       const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
> +       u64 global_handle = shm->sec_world_id;
> +       int rc;
> +
> +       /*
> +        * We're skipping the OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM call
> +        * since this is OP-TEE freeing via RPC so it has already retired
> +        * this ID.
> +        */
> +
> +       optee_shm_rem_ffa_handle(optee, global_handle);
> +       rc = ffa_ops->memory_reclaim(global_handle, 0);
> +       if (rc)
> +               pr_err("mem_reclain: 0x%llx %d", global_handle, rc);
> +
> +       shm->sec_world_id = 0;
> +
> +       return rc;
> +}
> +
> +/*
> + * 4. Dynamic shared memory pool based on alloc_pages()
> + *
> + * Implements an OP-TEE specific shared memory pool.
> + * The main function is optee_ffa_shm_pool_alloc_pages().
> + */
> +
> +static int pool_ffa_op_alloc(struct tee_shm_pool_mgr *poolm,
> +                            struct tee_shm *shm, size_t size)
> +{
> +       return optee_pool_op_alloc_helper(poolm, shm, size,
> +                                         optee_ffa_shm_register);
> +}
> +
> +static void pool_ffa_op_free(struct tee_shm_pool_mgr *poolm,
> +                            struct tee_shm *shm)
> +{
> +       optee_ffa_shm_unregister(shm->ctx, shm);
> +       free_pages((unsigned long)shm->kaddr, get_order(shm->size));
> +       shm->kaddr = NULL;
> +}
> +
> +static void pool_ffa_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
> +{
> +       kfree(poolm);
> +}
> +
> +static const struct tee_shm_pool_mgr_ops pool_ffa_ops = {
> +       .alloc = pool_ffa_op_alloc,
> +       .free = pool_ffa_op_free,
> +       .destroy_poolmgr = pool_ffa_op_destroy_poolmgr,
> +};
> +
> +/**
> + * optee_ffa_shm_pool_alloc_pages() - create page-based allocator pool
> + *
> + * This pool is used with OP-TEE over FF-A. In this case command buffers
> + * and such are allocated from kernel's own memory.
> + */
> +static struct tee_shm_pool_mgr *optee_ffa_shm_pool_alloc_pages(void)
> +{
> +       struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
> +
> +       if (!mgr)
> +               return ERR_PTR(-ENOMEM);
> +
> +       mgr->ops = &pool_ffa_ops;
> +
> +       return mgr;
> +}
> +
> +/*
> + * 5. Do a normal scheduled call into secure world
> + *
> + * The function optee_ffa_do_call_with_arg() performs a normal scheduled
> + * call into secure world. During this call may normal world request help
> + * from normal world using RPCs, Remote Procedure Calls. This includes
> + * delivery of non-secure interrupts to for instance allow rescheduling of
> + * the current task.
> + */
> +
> +static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
> +                                             struct optee_msg_arg *arg)
> +{
> +       struct tee_shm *shm;
> +
> +       if (arg->num_params != 1 ||
> +           arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
> +               arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> +               return;
> +       }
> +
> +       switch (arg->params[0].u.value.a) {
> +       case OPTEE_RPC_SHM_TYPE_APPL:
> +               shm = optee_rpc_cmd_alloc_suppl(ctx, arg->params[0].u.value.b);
> +               break;
> +       case OPTEE_RPC_SHM_TYPE_KERNEL:
> +               shm = tee_shm_alloc(ctx, arg->params[0].u.value.b,
> +                                   TEE_SHM_MAPPED);
> +               break;
> +       default:
> +               arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> +               return;
> +       }
> +
> +       if (IS_ERR(shm)) {
> +               arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
> +               return;
> +       }
> +
> +       arg->params[0] = (struct optee_msg_param){
> +               .attr = OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT,
> +               .u.fmem.size = tee_shm_get_size(shm),
> +               .u.fmem.global_id = shm->sec_world_id,
> +               .u.fmem.internal_offs = shm->offset,
> +       };
> +
> +       arg->ret = TEEC_SUCCESS;
> +}
> +
> +static void handle_ffa_rpc_func_cmd_shm_free(struct tee_context *ctx,
> +                                            struct optee *optee,
> +                                            struct optee_msg_arg *arg)
> +{
> +       struct tee_shm *shm;
> +
> +       if (arg->num_params != 1 ||
> +           arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
> +               goto err_bad_param;
> +
> +       shm = optee_shm_from_ffa_handle(optee, arg->params[0].u.value.b);
> +       if (!shm)
> +               goto err_bad_param;
> +       switch (arg->params[0].u.value.a) {
> +       case OPTEE_RPC_SHM_TYPE_APPL:
> +               optee_rpc_cmd_free_suppl(ctx, shm);
> +               break;
> +       case OPTEE_RPC_SHM_TYPE_KERNEL:
> +               tee_shm_free(shm);
> +               break;
> +       default:
> +               goto err_bad_param;
> +       }
> +       arg->ret = TEEC_SUCCESS;
> +       return;
> +
> +err_bad_param:
> +       arg->ret = TEEC_ERROR_BAD_PARAMETERS;
> +}
> +
> +static void handle_ffa_rpc_func_cmd(struct tee_context *ctx,
> +                                   struct optee_msg_arg *arg)
> +{
> +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> +
> +       arg->ret_origin = TEEC_ORIGIN_COMMS;
> +       switch (arg->cmd) {
> +       case OPTEE_RPC_CMD_SHM_ALLOC:
> +               handle_ffa_rpc_func_cmd_shm_alloc(ctx, arg);
> +               break;
> +       case OPTEE_RPC_CMD_SHM_FREE:
> +               handle_ffa_rpc_func_cmd_shm_free(ctx, optee, arg);
> +               break;
> +       default:
> +               optee_rpc_cmd(ctx, optee, arg);
> +       }
> +}
> +
> +static void optee_handle_ffa_rpc(struct tee_context *ctx, u32 cmd,
> +                                struct optee_msg_arg *arg)
> +{
> +       switch (cmd) {
> +       case OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD:
> +               handle_ffa_rpc_func_cmd(ctx, arg);
> +               break;
> +       case OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT:
> +               /* Interrupt delivered by now */
> +               break;
> +       default:
> +               pr_warn("Unknown RPC func 0x%x\n", cmd);
> +               break;
> +       }
> +}
> +
> +static int optee_ffa_yielding_call(struct tee_context *ctx,
> +                                  struct ffa_send_direct_data *data,
> +                                  struct optee_msg_arg *rpc_arg)
> +{
> +       struct optee *optee = tee_get_drvdata(ctx->teedev);
> +       const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
> +       struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
> +       struct optee_call_waiter w;
> +       u32 cmd = data->data0;
> +       u32 w4 = data->data1;
> +       u32 w5 = data->data2;
> +       u32 w6 = data->data3;
> +       int rc;
> +
> +       /* Initialize waiter */
> +       optee_cq_wait_init(&optee->call_queue, &w);
> +       while (true) {
> +               rc = ffa_ops->sync_send_receive(ffa_dev, data);
> +               if (rc)
> +                       goto done;
> +
> +               switch ((int)data->data0) {
> +               case TEEC_SUCCESS:
> +                       break;
> +               case TEEC_ERROR_BUSY:
> +                       if (cmd == OPTEE_FFA_YIELDING_CALL_RESUME) {
> +                               rc = -EIO;
> +                               goto done;
> +                       }
> +
> +                       /*
> +                        * Out of threads in secure world, wait for a thread
> +                        * become available.
> +                        */
> +                       optee_cq_wait_for_completion(&optee->call_queue, &w);
> +                       data->data0 = cmd;
> +                       data->data1 = w4;
> +                       data->data2 = w5;
> +                       data->data3 = w6;
> +                       continue;
> +               default:
> +                       rc = -EIO;
> +                       goto done;
> +               }
> +
> +               if (data->data1 == OPTEE_FFA_YIELDING_CALL_RETURN_DONE)
> +                       goto done;
> +
> +               /*
> +                * OP-TEE has returned with a RPC request.
> +                *
> +                * Note that data->data4 (passed in register w7) is already
> +                * filled in by ffa_ops->sync_send_receive() returning
> +                * above.
> +                */
> +               cond_resched();
> +               optee_handle_ffa_rpc(ctx, data->data1, rpc_arg);
> +               cmd = OPTEE_FFA_YIELDING_CALL_RESUME;
> +               data->data0 = cmd;
> +               data->data1 = 0;
> +               data->data2 = 0;
> +               data->data3 = 0;
> +       }
> +done:
> +       /*
> +        * We're done with our thread in secure world, if there's any
> +        * thread waiters wake up one.
> +        */
> +       optee_cq_wait_final(&optee->call_queue, &w);
> +
> +       return rc;
> +}
> +
> +/**
> + * optee_ffa_do_call_with_arg() - Do a FF-A call to enter OP-TEE in secure world
> + * @ctx:       calling context
> + * @shm:       shared memory holding the message to pass to secure world
> + *
> + * Does a FF-A call to OP-TEE in secure world and handles eventual resulting
> + * Remote Procedure Calls (RPC) from OP-TEE.
> + *
> + * Returns return code from FF-A, 0 is OK
> + */
> +
> +static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
> +                                     struct tee_shm *shm)
> +{
> +       struct ffa_send_direct_data data = {
> +               .data0 = OPTEE_FFA_YIELDING_CALL_WITH_ARG,
> +               .data1 = (u32)shm->sec_world_id,
> +               .data2 = (u32)(shm->sec_world_id >> 32),
> +               .data3 = shm->offset,
> +       };
> +       struct optee_msg_arg *arg = tee_shm_get_va(shm, 0);
> +       unsigned int rpc_arg_offs = OPTEE_MSG_GET_ARG_SIZE(arg->num_params);
> +       struct optee_msg_arg *rpc_arg = tee_shm_get_va(shm, rpc_arg_offs);
> +
> +       return optee_ffa_yielding_call(ctx, &data, rpc_arg);
> +}
> +
> +/*
> + * 6. Driver initialization
> + *
> + * During driver inititialization is the OP-TEE Secure Partition is probed
> + * to find out which features it supports so the driver can be initialized
> + * with a matching configuration.
> + */
> +
> +static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev,
> +                                       const struct ffa_dev_ops *ops)
> +{
> +       struct ffa_send_direct_data data = { OPTEE_FFA_GET_API_VERSION };
> +       int rc;
> +
> +       ops->mode_32bit_set(ffa_dev);
> +
> +       rc = ops->sync_send_receive(ffa_dev, &data);
> +       if (rc) {
> +               pr_err("Unexpected error %d\n", rc);
> +               return false;
> +       }
> +       if (data.data0 != OPTEE_FFA_VERSION_MAJOR ||
> +           data.data1 < OPTEE_FFA_VERSION_MINOR) {
> +               pr_err("Incompatible OP-TEE API version %lu.%lu",
> +                      data.data0, data.data1);
> +               return false;
> +       }
> +
> +       data = (struct ffa_send_direct_data){ OPTEE_FFA_GET_OS_VERSION };
> +       rc = ops->sync_send_receive(ffa_dev, &data);
> +       if (rc) {
> +               pr_err("Unexpected error %d\n", rc);
> +               return false;
> +       }
> +       if (data.data2)
> +               pr_info("revision %lu.%lu (%08lx)",
> +                       data.data0, data.data1, data.data2);
> +       else
> +               pr_info("revision %lu.%lu", data.data0, data.data1);
> +
> +       return true;
> +}
> +
> +static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev,
> +                                   const struct ffa_dev_ops *ops,
> +                                   unsigned int *rpc_arg_count)
> +{
> +       struct ffa_send_direct_data data = { OPTEE_FFA_EXCHANGE_CAPABILITIES };
> +       int rc;
> +
> +       rc = ops->sync_send_receive(ffa_dev, &data);
> +       if (rc) {
> +               pr_err("Unexpected error %d", rc);
> +               return false;
> +       }
> +       if (data.data0) {
> +               pr_err("Unexpected exchange error %lu", data.data0);
> +               return false;
> +       }
> +
> +       *rpc_arg_count = (u8)data.data1;

Why is this special capability required in case of FF-A? Is it true
that RPC arguments count will be fixed for all RPC commands?

> +
> +       return true;
> +}
> +
> +static struct tee_shm_pool *optee_ffa_config_dyn_shm(void)
> +{
> +       struct tee_shm_pool_mgr *priv_mgr;
> +       struct tee_shm_pool_mgr *dmabuf_mgr;
> +       void *rc;
> +
> +       rc = optee_ffa_shm_pool_alloc_pages();
> +       if (IS_ERR(rc))
> +               return rc;
> +       priv_mgr = rc;
> +
> +       rc = optee_ffa_shm_pool_alloc_pages();
> +       if (IS_ERR(rc)) {
> +               tee_shm_pool_mgr_destroy(priv_mgr);
> +               return rc;
> +       }
> +       dmabuf_mgr = rc;
> +
> +       rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
> +       if (IS_ERR(rc)) {
> +               tee_shm_pool_mgr_destroy(priv_mgr);
> +               tee_shm_pool_mgr_destroy(dmabuf_mgr);
> +       }
> +
> +       return rc;
> +}
> +
> +static void optee_ffa_get_version(struct tee_device *teedev,
> +                                 struct tee_ioctl_version_data *vers)
> +{
> +       struct tee_ioctl_version_data v = {
> +               .impl_id = TEE_IMPL_ID_OPTEE,
> +               .impl_caps = TEE_OPTEE_CAP_TZ,
> +               .gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM |
> +                           TEE_GEN_CAP_MEMREF_NULL,
> +       };
> +
> +       *vers = v;
> +}
> +
> +static int optee_ffa_open(struct tee_context *ctx)
> +{
> +       return optee_open(ctx, true);
> +}
> +
> +static const struct tee_driver_ops optee_ffa_clnt_ops = {
> +       .get_version = optee_ffa_get_version,
> +       .open = optee_ffa_open,
> +       .release = optee_release,
> +       .open_session = optee_open_session,
> +       .close_session = optee_close_session,
> +       .invoke_func = optee_invoke_func,
> +       .cancel_req = optee_cancel_req,
> +       .shm_register = optee_ffa_shm_register,
> +       .shm_unregister = optee_ffa_shm_unregister,
> +};
> +
> +static const struct tee_desc optee_ffa_clnt_desc = {
> +       .name = DRIVER_NAME "-ffa-clnt",
> +       .ops = &optee_ffa_clnt_ops,
> +       .owner = THIS_MODULE,
> +};
> +
> +static const struct tee_driver_ops optee_ffa_supp_ops = {
> +       .get_version = optee_ffa_get_version,
> +       .open = optee_ffa_open,
> +       .release = optee_release_supp,
> +       .supp_recv = optee_supp_recv,
> +       .supp_send = optee_supp_send,
> +       .shm_register = optee_ffa_shm_register, /* same as for clnt ops */
> +       .shm_unregister = optee_ffa_shm_unregister_supp,
> +};
> +
> +static const struct tee_desc optee_ffa_supp_desc = {
> +       .name = DRIVER_NAME "-ffa-supp",
> +       .ops = &optee_ffa_supp_ops,
> +       .owner = THIS_MODULE,
> +       .flags = TEE_DESC_PRIVILEGED,
> +};
> +
> +static const struct optee_ops optee_ffa_ops = {
> +       .do_call_with_arg = optee_ffa_do_call_with_arg,
> +       .to_msg_param = optee_ffa_to_msg_param,
> +       .from_msg_param = optee_ffa_from_msg_param,
> +};
> +
> +static void optee_ffa_remove(struct ffa_device *ffa_dev)
> +{
> +       struct optee *optee = ffa_dev->dev.driver_data;
> +
> +       optee_remove_common(optee);
> +
> +       mutex_destroy(&optee->ffa.mutex);
> +       rhashtable_free_and_destroy(&optee->ffa.global_ids, rh_free_fn, NULL);
> +
> +       kfree(optee);
> +}
> +
> +static int optee_ffa_probe(struct ffa_device *ffa_dev)
> +{
> +       const struct ffa_dev_ops *ffa_ops;
> +       unsigned int rpc_arg_count;
> +       struct tee_device *teedev;
> +       struct optee *optee;
> +       int rc;
> +
> +       ffa_ops = ffa_dev_ops_get(ffa_dev);
> +       if (!ffa_ops) {
> +               pr_warn("failed \"method\" init: ffa\n");
> +               return -ENOENT;
> +       }
> +
> +       if (!optee_ffa_api_is_compatbile(ffa_dev, ffa_ops))
> +               return -EINVAL;
> +
> +       if (!optee_ffa_exchange_caps(ffa_dev, ffa_ops, &rpc_arg_count))
> +               return -EINVAL;
=> +
> +       optee = kzalloc(sizeof(*optee), GFP_KERNEL);
> +       if (!optee) {
> +               rc = -ENOMEM;
> +               goto err;
> +       }
> +       optee->pool = optee_ffa_config_dyn_shm();
> +       if (IS_ERR(optee->pool)) {
> +               rc = PTR_ERR(optee->pool);
> +               optee->pool = NULL;
> +               goto err;
> +       }

IIUC, with FF-A we will only be supporting dynamic shared memory. So
CFG_CORE_DYN_SHM=y should be enforced in OP-TEE OS when
CFG_CORE_FFA=y, but I don't see that currently. Am I missing
something?

-Sumit

> +
> +       optee->ops = &optee_ffa_ops;
> +       optee->ffa.ffa_dev = ffa_dev;
> +       optee->ffa.ffa_ops = ffa_ops;
> +       optee->rpc_arg_count = rpc_arg_count;
> +
> +       teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool,
> +                                 optee);
> +       if (IS_ERR(teedev)) {
> +               rc = PTR_ERR(teedev);
> +               goto err;
> +       }
> +       optee->teedev = teedev;
> +
> +       teedev = tee_device_alloc(&optee_ffa_supp_desc, NULL, optee->pool,
> +                                 optee);
> +       if (IS_ERR(teedev)) {
> +               rc = PTR_ERR(teedev);
> +               goto err;
> +       }
> +       optee->supp_teedev = teedev;
> +
> +       rc = tee_device_register(optee->teedev);
> +       if (rc)
> +               goto err;
> +
> +       rc = tee_device_register(optee->supp_teedev);
> +       if (rc)
> +               goto err;
> +
> +       rc = rhashtable_init(&optee->ffa.global_ids, &shm_rhash_params);
> +       if (rc)
> +               goto err;
> +       mutex_init(&optee->ffa.mutex);
> +       mutex_init(&optee->call_queue.mutex);
> +       INIT_LIST_HEAD(&optee->call_queue.waiters);
> +       optee_wait_queue_init(&optee->wait_queue);
> +       optee_supp_init(&optee->supp);
> +       ffa_dev_set_drvdata(ffa_dev, optee);
> +
> +       rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
> +       if (rc) {
> +               optee_ffa_remove(ffa_dev);
> +               return rc;
> +       }
> +
> +       pr_info("initialized driver\n");
> +       return 0;
> +err:
> +       /*
> +        * tee_device_unregister() is safe to call even if the
> +        * devices hasn't been registered with
> +        * tee_device_register() yet.
> +        */
> +       tee_device_unregister(optee->supp_teedev);
> +       tee_device_unregister(optee->teedev);
> +       if (optee->pool)
> +               tee_shm_pool_free(optee->pool);
> +       kfree(optee);
> +       return rc;
> +}
> +
> +static const struct ffa_device_id optee_ffa_device_id[] = {
> +       /* 486178e0-e7f8-11e3-bc5e0002a5d5c51b */
> +       { UUID_INIT(0x486178e0, 0xe7f8, 0x11e3,
> +                   0xbc, 0x5e, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b) },
> +       {}
> +};
> +
> +static struct ffa_driver optee_ffa_driver = {
> +       .name = "optee",
> +       .probe = optee_ffa_probe,
> +       .remove = optee_ffa_remove,
> +       .id_table = optee_ffa_device_id,
> +};
> +
> +int optee_ffa_abi_register(void)
> +{
> +       return ffa_register(&optee_ffa_driver);
> +}
> +
> +void optee_ffa_abi_unregister(void)
> +{
> +       ffa_unregister(&optee_ffa_driver);
> +}
> diff --git a/drivers/tee/optee/optee_ffa.h b/drivers/tee/optee/optee_ffa.h
> new file mode 100644
> index 000000000000..ee3a03fc392c
> --- /dev/null
> +++ b/drivers/tee/optee/optee_ffa.h
> @@ -0,0 +1,153 @@
> +/* SPDX-License-Identifier: BSD-2-Clause */
> +/*
> + * Copyright (c) 2019-2021, Linaro Limited
> + */
> +
> +/*
> + * This file is exported by OP-TEE and is kept in sync between secure world
> + * and normal world drivers. We're using ARM FF-A 1.0 specification.
> + */
> +
> +#ifndef __OPTEE_FFA_H
> +#define __OPTEE_FFA_H
> +
> +#include <linux/arm_ffa.h>
> +
> +/*
> + * Normal world sends requests with FFA_MSG_SEND_DIRECT_REQ and
> + * responses are returned with FFA_MSG_SEND_DIRECT_RESP for normal
> + * messages.
> + *
> + * All requests with FFA_MSG_SEND_DIRECT_REQ and FFA_MSG_SEND_DIRECT_RESP
> + * are using the AArch32 SMC calling convention with register usage as
> + * defined in FF-A specification:
> + * w0:    Function ID (0x8400006F or 0x84000070)
> + * w1:    Source/Destination IDs
> + * w2:    Reserved (MBZ)
> + * w3-w7: Implementation defined, free to be used below
> + */
> +
> +#define OPTEE_FFA_VERSION_MAJOR        1
> +#define OPTEE_FFA_VERSION_MINOR        0
> +
> +#define OPTEE_FFA_BLOCKING_CALL(id)    (id)
> +#define OPTEE_FFA_YIELDING_CALL_BIT    31
> +#define OPTEE_FFA_YIELDING_CALL(id)    ((id) | BIT(OPTEE_FFA_YIELDING_CALL_BIT))
> +
> +/*
> + * Returns the API version implemented, currently follows the FF-A version.
> + * Call register usage:
> + * w3:    Service ID, OPTEE_FFA_GET_API_VERSION
> + * w4-w7: Not used (MBZ)
> + *
> + * Return register usage:
> + * w3:    OPTEE_FFA_VERSION_MAJOR
> + * w4:    OPTEE_FFA_VERSION_MINOR
> + * w5-w7: Not used (MBZ)
> + */
> +#define OPTEE_FFA_GET_API_VERSION      OPTEE_FFA_BLOCKING_CALL(0)
> +
> +/*
> + * Returns the revision of OP-TEE.
> + *
> + * Used by non-secure world to figure out which version of the Trusted OS
> + * is installed. Note that the returned revision is the revision of the
> + * Trusted OS, not of the API.
> + *
> + * Call register usage:
> + * w3:    Service ID, OPTEE_FFA_GET_OS_VERSION
> + * w4-w7: Unused (MBZ)
> + *
> + * Return register usage:
> + * w3:    CFG_OPTEE_REVISION_MAJOR
> + * w4:    CFG_OPTEE_REVISION_MINOR
> + * w5:    TEE_IMPL_GIT_SHA1 (or zero if not supported)
> + */
> +#define OPTEE_FFA_GET_OS_VERSION       OPTEE_FFA_BLOCKING_CALL(1)
> +
> +/*
> + * Exchange capabilities between normal world and secure world.
> + *
> + * Currently there are no defined capabilities. When features are added new
> + * capabilities may be added.
> + *
> + * Call register usage:
> + * w3:    Service ID, OPTEE_FFA_EXCHANGE_CAPABILITIES
> + * w4-w7: Note used (MBZ)
> + *
> + * Return register usage:
> + * w3:    Error code, 0 on success
> + * w4:    Bit[7:0]:  Number of parameters needed for RPC to be supplied
> + *                   as the second MSG arg struct for
> + *                   OPTEE_FFA_YIELDING_CALL_WITH_ARG.
> + *        Bit[31:8]: Reserved (MBZ)
> + * w5-w7: Note used (MBZ)
> + */
> +#define OPTEE_FFA_EXCHANGE_CAPABILITIES OPTEE_FFA_BLOCKING_CALL(2)
> +
> +/*
> + * Unregister shared memory
> + *
> + * Call register usage:
> + * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM
> + * w4:    Shared memory handle, lower bits
> + * w5:    Shared memory handle, higher bits
> + * w6-w7: Not used (MBZ)
> + *
> + * Return register usage:
> + * w3:    Error code, 0 on success
> + * w4-w7: Note used (MBZ)
> + */
> +#define OPTEE_FFA_UNREGISTER_SHM       OPTEE_FFA_BLOCKING_CALL(3)
> +
> +/*
> + * Call with struct optee_msg_arg as argument in the supplied shared memory
> + * with a zero internal offset and normal cached memory attributes.
> + * Register usage:
> + * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_WITH_ARG
> + * w4:    Lower 32 bits of a 64-bit Shared memory handle
> + * w5:    Upper 32 bits of a 64-bit Shared memory handle
> + * w6:    Offset into shared memory pointing to a struct optee_msg_arg
> + *       right after the parameters of this struct (at offset
> + *       OPTEE_MSG_GET_ARG_SIZE(num_params) follows a struct optee_msg_arg
> + *       for RPC, this struct has reserved space for the number of RPC
> + *       parameters as returned by OPTEE_FFA_EXCHANGE_CAPABILITIES.
> + * w7:    Not used (MBZ)
> + * Resume from RPC. Register usage:
> + * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_RESUME
> + * w4-w6: Not used (MBZ)
> + * w7:    Resume info
> + *
> + * Normal return (yielding call is completed). Register usage:
> + * w3:    Error code, 0 on success
> + * w4:    OPTEE_FFA_YIELDING_CALL_RETURN_DONE
> + * w5-w7: Not used (MBZ)
> + *
> + * RPC interrupt return (RPC from secure world). Register usage:
> + * w3:    Error code == 0
> + * w4:    Any defined RPC code but OPTEE_FFA_YIELDING_CALL_RETURN_DONE
> + * w5-w6: Not used (MBZ)
> + * w7:    Resume info
> + *
> + * Possible error codes in register w3:
> + * 0:                       Success
> + * FFA_DENIED:              w4 isn't one of OPTEE_FFA_YIELDING_CALL_START
> + *                          OPTEE_FFA_YIELDING_CALL_RESUME
> + *
> + * Possible error codes for OPTEE_FFA_YIELDING_CALL_START,
> + * FFA_BUSY:               Number of OP-TEE OS threads exceeded,
> + *                         try again later
> + * FFA_DENIED:             RPC shared memory object not found
> + * FFA_INVALID_PARAMETER:  Bad shared memory handle or offset into the memory
> + *
> + * Possible error codes for OPTEE_FFA_YIELDING_CALL_RESUME
> + * FFA_INVALID_PARAMETER:  Bad resume info
> + */
> +#define OPTEE_FFA_YIELDING_CALL_WITH_ARG       OPTEE_FFA_YIELDING_CALL(0)
> +#define OPTEE_FFA_YIELDING_CALL_RESUME         OPTEE_FFA_YIELDING_CALL(1)
> +
> +#define OPTEE_FFA_YIELDING_CALL_RETURN_DONE            0
> +#define OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD         1
> +#define OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT       2
> +
> +#endif /*__OPTEE_FFA_H*/
> diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
> index e3d72d09c484..2422e185d400 100644
> --- a/drivers/tee/optee/optee_msg.h
> +++ b/drivers/tee/optee/optee_msg.h
> @@ -28,6 +28,9 @@
>  #define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT         0x5
>  #define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT                0x6
>  #define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT         0x7
> +#define OPTEE_MSG_ATTR_TYPE_FMEM_INPUT         OPTEE_MSG_ATTR_TYPE_RMEM_INPUT
> +#define OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT                OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT
> +#define OPTEE_MSG_ATTR_TYPE_FMEM_INOUT         OPTEE_MSG_ATTR_TYPE_RMEM_INOUT
>  #define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT         0x9
>  #define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT                0xa
>  #define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT         0xb
> @@ -96,6 +99,8 @@
>   */
>  #define OPTEE_MSG_NONCONTIG_PAGE_SIZE          4096
>
> +#define OPTEE_MSG_FMEM_INVALID_GLOBAL_ID       0xffffffffffffffff
> +
>  /**
>   * struct optee_msg_param_tmem - temporary memory reference parameter
>   * @buf_ptr:   Address of the buffer
> @@ -127,6 +132,23 @@ struct optee_msg_param_rmem {
>         u64 shm_ref;
>  };
>
> +/**
> + * struct optee_msg_param_fmem - ffa memory reference parameter
> + * @offs_lower:           Lower bits of offset into shared memory reference
> + * @offs_upper:           Upper bits of offset into shared memory reference
> + * @internal_offs: Internal offset into the first page of shared memory
> + *                reference
> + * @size:         Size of the buffer
> + * @global_id:    Global identifier of Shared memory
> + */
> +struct optee_msg_param_fmem {
> +       u32 offs_low;
> +       u16 offs_high;
> +       u16 internal_offs;
> +       u64 size;
> +       u64 global_id;
> +};
> +
>  /**
>   * struct optee_msg_param_value - opaque value parameter
>   *
> @@ -143,13 +165,15 @@ struct optee_msg_param_value {
>   * @attr:      attributes
>   * @tmem:      parameter by temporary memory reference
>   * @rmem:      parameter by registered memory reference
> + * @fmem:      parameter by ffa registered memory reference
>   * @value:     parameter by opaque value
>   * @octets:    parameter by octet string
>   *
>   * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in
>   * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value or octets,
>   * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and
> - * OPTEE_MSG_ATTR_TYPE_RMEM_* indicates @rmem,
> + * OPTEE_MSG_ATTR_TYPE_RMEM_* or the alias PTEE_MSG_ATTR_TYPE_FMEM_* indicates
> + * @rmem or @fmem depending on the conduit.
>   * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used.
>   */
>  struct optee_msg_param {
> @@ -157,6 +181,7 @@ struct optee_msg_param {
>         union {
>                 struct optee_msg_param_tmem tmem;
>                 struct optee_msg_param_rmem rmem;
> +               struct optee_msg_param_fmem fmem;
>                 struct optee_msg_param_value value;
>                 u8 octets[24];
>         } u;
> diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
> index ca0213e330b5..2593742364da 100644
> --- a/drivers/tee/optee/optee_private.h
> +++ b/drivers/tee/optee/optee_private.h
> @@ -7,6 +7,7 @@
>  #define OPTEE_PRIVATE_H
>
>  #include <linux/arm-smccc.h>
> +#include <linux/rhashtable.h>
>  #include <linux/semaphore.h>
>  #include <linux/tee_drv.h>
>  #include <linux/types.h>
> @@ -22,6 +23,7 @@
>  #define TEEC_ERROR_NOT_SUPPORTED       0xFFFF000A
>  #define TEEC_ERROR_COMMUNICATION       0xFFFF000E
>  #define TEEC_ERROR_OUT_OF_MEMORY       0xFFFF000C
> +#define TEEC_ERROR_BUSY                        0xFFFF000D
>  #define TEEC_ERROR_SHORT_BUFFER                0xFFFF0010
>
>  #define TEEC_ORIGIN_COMMS              0x00000002
> @@ -73,19 +75,28 @@ struct optee_supp {
>         struct completion reqs_c;
>  };
>
> -/**
> - * struct optee_smc - SMC ABI specifics
> - * @invoke_fn:         function to issue smc or hvc
> - * @memremaped_shm     virtual address of memory in shared memory pool
> - * @sec_caps:          secure world capabilities defined by
> - *                     OPTEE_SMC_SEC_CAP_* in optee_smc.h
> - */
>  struct optee_smc {
>         optee_invoke_fn *invoke_fn;
>         void *memremaped_shm;
>         u32 sec_caps;
>  };
>
> +/**
> + * struct optee_ffa_data -  FFA communication struct
> + * @ffa_dev            FFA device, contains the destination id, the id of
> + *                     OP-TEE in secure world
> + * @ffa_ops            FFA operations
> + * @mutex              Serializes access to @global_ids
> + * @global_ids         FF-A shared memory global handle translation
> + */
> +struct optee_ffa {
> +       struct ffa_device *ffa_dev;
> +       const struct ffa_dev_ops *ffa_ops;
> +       /* Serializes access to @global_ids */
> +       struct mutex mutex;
> +       struct rhashtable global_ids;
> +};
> +
>  struct optee;
>
>  /**
> @@ -116,11 +127,13 @@ struct optee_ops {
>   *                     world
>   * @teedev:            client device
>   * @smc:               specific to SMC ABI
> + * @ffa:               specific to FF-A ABI
>   * @call_queue:                queue of threads waiting to call @invoke_fn
>   * @wait_queue:                queue of threads from secure world waiting for a
>   *                     secure world sync object
>   * @supp:              supplicant synchronization struct for RPC to supplicant
>   * @pool:              shared memory pool
> + * @rpc_arg_count:     If > 0 number of RPC parameters to make room for
>   * @scan_bus_done      flag if device registation was already done.
>   * @scan_bus_wq                workqueue to scan optee bus and register optee drivers
>   * @scan_bus_work      workq to scan optee bus and register optee drivers
> @@ -129,11 +142,17 @@ struct optee {
>         struct tee_device *supp_teedev;
>         struct tee_device *teedev;
>         const struct optee_ops *ops;
> -       struct optee_smc smc;
> +       union {
> +               struct optee_smc smc;
> +#ifdef CONFIG_ARM_FFA_TRANSPORT
> +               struct optee_ffa ffa;
> +#endif
> +       };
>         struct optee_call_queue call_queue;
>         struct optee_wait_queue wait_queue;
>         struct optee_supp supp;
>         struct tee_shm_pool *pool;
> +       unsigned int rpc_arg_count;
>         bool   scan_bus_done;
>         struct workqueue_struct *scan_bus_wq;
>         struct work_struct scan_bus_work;
> @@ -266,4 +285,12 @@ static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
>  int optee_smc_abi_register(void);
>  void optee_smc_abi_unregister(void);
>
> +#ifdef CONFIG_ARM_FFA_TRANSPORT
> +int optee_ffa_abi_register(void);
> +void optee_ffa_abi_unregister(void);
> +#else
> +static inline int optee_ffa_abi_register(void) { return -EOPNOTSUPP; }
> +static inline void optee_ffa_abi_unregister(void) {}
> +#endif
> +
>  #endif /*OPTEE_PRIVATE_H*/
> --
> 2.31.1
>


From daniel at 0x0f.com  Wed Aug 25 04:50:18 2021
From: daniel at 0x0f.com (Daniel Palmer)
Date: Wed, 25 Aug 2021 20:50:18 +0900
Subject: [PATCH 00/10] gpio: msc313: Add gpio support for ssd20xd
In-Reply-To: <CACRpkdbE+_DJFhBCmtz5JwJupf7QkkWZhXrgf1KG_3rPqvEm0w@mail.gmail.com>
References: <20210717045627.1739959-1-daniel@0x0f.com>
 <CACRpkdbE+_DJFhBCmtz5JwJupf7QkkWZhXrgf1KG_3rPqvEm0w@mail.gmail.com>
Message-ID: <CAFr9PXmFHanrx4Frg3hQwo-RbAY-UXxC=FOAj++cshSHa99z3g@mail.gmail.com>

+ Bartosz

Hi Linus, Bartosz,

On Fri, 30 Jul 2021 at 19:12, Linus Walleij <linus.walleij at linaro.org> wrote:
> I suppose Bartosz can just merge the 4 first patches into the
> GPIO tree and you can take the rest into the SoC tree?
>
> Yours,
> Linus Walleij

I just noticed I hadn't to'd Bartosz about these. Is there anything I
need to do for the first patches?

Cheers,

Daniel


From liuqi115 at huawei.com  Wed Aug 25 04:52:08 2021
From: liuqi115 at huawei.com (liuqi (BA))
Date: Wed, 25 Aug 2021 19:52:08 +0800
Subject: [PATCH v9 2/2] drivers/perf: hisi: Add driver for HiSilicon PCIe
 PMU
In-Reply-To: <20210824143137.GA23146@willie-the-truck>
References: <20210818051246.29545-1-liuqi115@huawei.com>
 <20210818051246.29545-3-liuqi115@huawei.com>
 <20210824143137.GA23146@willie-the-truck>
Message-ID: <4050af8b-f9a7-6666-4a9d-d1c8f2b212e1@huawei.com>


Hi, Will
On 2021/8/24 22:31, Will Deacon wrote:
> Hi,
> 
> On Wed, Aug 18, 2021 at 01:12:46PM +0800, Qi Liu wrote:
>> PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported
>> to sample bandwidth, latency, buffer occupation etc.
>>
>> Each PMU RCiEP device monitors multiple Root Ports, and each RCiEP is
>> registered as a PMU in /sys/bus/event_source/devices, so users can
>> select target PMU, and use filter to do further sets.
>>
>> Filtering options contains:
>> event     - select the event.
>> port      - select target Root Ports. Information of Root Ports are
>>              shown under sysfs.
>> bdf       - select requester_id of target EP device.
>> trig_len  - set trigger condition for starting event statistics.
>> trig_mode - set trigger mode. 0 means starting to statistic when bigger
>>              than trigger condition, and 1 means smaller.
>> thr_len   - set threshold for statistics.
>> thr_mode  - set threshold mode. 0 means count when bigger than threshold,
>>              and 1 means smaller.
> 
> I think this is getting there now, thanks for sticking with it. Just a
> couple of comments below..
> 
>> +static bool hisi_pcie_pmu_validate_event_group(struct perf_event *event)
>> +{
>> +	struct perf_event *sibling, *leader = event->group_leader;
>> +	int counters = 1;
>> +
>> +	if (!is_software_event(leader)) {
>> +		if (leader->pmu != event->pmu)
>> +			return false;
>> +
>> +		if (leader != event)
>> +			counters++;
>> +	}
>> +
>> +	for_each_sibling_event(sibling, event->group_leader) {
>> +		if (is_software_event(sibling))
>> +			continue;
>> +
>> +		if (sibling->pmu != event->pmu)
>> +			return false;
>> +
>> +		counters++;
>> +	}
>> +
>> +	return counters <= HISI_PCIE_MAX_COUNTERS;
>> +}
> 
> Given that this function doesn't look at the event numbers, doesn't this
> over-provision the counter registers? For example, if I create a group
> containing 4 of the same event, then we'll allocate four counters but only
> use one. Similarly, if I create a group containing two events, one for the
> normal counter and one for the extended counter, then we'll again allocate
> two counters instead of one.
> 

Yes, we should add some check in hisi_pcie_pmu_validate_event_group() 
function to avoid over-provision. I'll use a array to record events and 
do this check.

Thanks for your review, I'll fix this.

> Have I misunderstood?
> 
>> +static int hisi_pcie_pmu_event_init(struct perf_event *event)
>> +{
>> +	struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
>> +	struct hw_perf_event *hwc = &event->hw;
>> +
>> +	event->cpu = pcie_pmu->on_cpu;
>> +
>> +	if (EXT_COUNTER_IS_USED(hisi_pcie_get_event(event)))
>> +		hwc->event_base = HISI_PCIE_EXT_CNT;
>> +	else
>> +		hwc->event_base = HISI_PCIE_CNT;
>> +
>> +	if (event->attr.type != event->pmu->type)
>> +		return -ENOENT;
>> +
>> +	/* Sampling is not supported. */
>> +	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
>> +		return -EOPNOTSUPP;
>> +
>> +	if (!hisi_pcie_pmu_valid_filter(event, pcie_pmu)) {
>> +		pci_err(pcie_pmu->pdev, "Invalid filter!\n");
> 
> Please remove this message, as it's triggerable from userspace.
> 
got it, will remove this.

Thanks,
Qi
> Will
> .
> 



From robh+dt at kernel.org  Wed Aug 25 05:33:40 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 07:33:40 -0500
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
Message-ID: <CAL_Jsq+0rq6u5d7itETOnQWx_V+J3aP1m1Zgehi5QKVoKvdbvQ@mail.gmail.com>

On Tue, Aug 24, 2021 at 11:05 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
>
> On 2021/8/25 4:08, Saravana Kannan wrote:
> > On Tue, Aug 24, 2021 at 1:05 PM Rob Herring <robh+dt at kernel.org> wrote:
> >> +Saravana
> >>
> >> Saravana mentioned to me there may be some issues with this one...
> >>
> >>
> >> On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> >>> of_amba_device_create() uses irq_of_parse_and_map() to translate
> >>> a DT interrupt specification into a Linux virtual interrupt number.
> >>>
> >>> But it doesn't properly handle the case where the interrupt controller
> >>> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
> >>> interrupt controller, because the mbigen initialization is too late,
> >>> which will lead to no IRQ due to no IRQ domain found, log is shown below,
> >>>    "irq: no irq domain found for uart0 !"
> >>>
> >>> use of_irq_get() to return -EPROBE_DEFER as above, and in the function
> >>> amba_device_try_add()/amba_device_add(), it will properly handle in such
> >>> case, also return 0 in other fail cases to be consistent as before.
> >>>
> >>> Cc: Russell King <linux at armlinux.org.uk>
> >>> Cc: Rob Herring <robh+dt at kernel.org>
> >>> Cc: Frank Rowand <frowand.list at gmail.com>
> >>> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
> >>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> >>> ---
> >>>   drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
> >>>   drivers/of/platform.c |  6 +-----
> >>>   2 files changed, 28 insertions(+), 5 deletions(-)
> >>>
> >>> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> >>> index 36f2f42c8014..720aa6cdd402 100644
> >>> --- a/drivers/amba/bus.c
> >>> +++ b/drivers/amba/bus.c
> >>> @@ -19,6 +19,7 @@
> >>>   #include <linux/clk/clk-conf.h>
> >>>   #include <linux/platform_device.h>
> >>>   #include <linux/reset.h>
> >>> +#include <linux/of_irq.h>
> >>>
> >>>   #include <asm/irq.h>
> >>>
> >>> @@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
> >>>          kfree(d);
> >>>   }
> >>>
> >>> +static int of_amba_device_decode_irq(struct amba_device *dev)
> >>> +{
> >>> +       struct device_node *node = dev->dev.of_node;
> >>> +       int i, irq = 0;
> >>> +
> >>> +       if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
> >>> +               /* Decode the IRQs and address ranges */
> >>> +               for (i = 0; i < AMBA_NR_IRQS; i++) {
> >>> +                       irq = of_irq_get(node, i);
> >>> +                       if (irq < 0) {
> >>> +                               if (irq == -EPROBE_DEFER)
> >>> +                                       return irq;
> >>> +                               irq = 0;
> >>> +                       }
> >>> +
> >>> +                       dev->irq[i] = irq;
> >>> +               }
> >>> +       }
> >>> +
> >>> +       return 0;
> >>> +}
> >>> +
> >>>   static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
> >>>   {
> >>>          u32 size;
> >>>          void __iomem *tmp;
> >>>          int i, ret;
> >>>
> >>> +       ret = of_amba_device_decode_irq(dev);
> >>> +       if (ret)
> >>> +               goto err_out;
> >>> +
> > Similar to other resources the AMBA bus "gets" for the device, I think
> > this should be moved into amba_probe() and not here. There's no reason
> > to delay the addition of the device (and loading its module) because
> > the IRQ isn't ready yet.
>
> The following code in the amba_device_try_add() will be called, it uses irq[0]
> and irq[1], so I put of_amba_device_decode_irq() into amba_device_try_add().
>
> 470         if (dev->irq[0])
> 471                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
> 472         if (ret == 0 && dev->irq[1])
> 473                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
> 474         if (ret == 0)
> 475                 return ret;

I wonder if we could just remove these. Why does userspace need them
in the first place? It's only an ABI if someone notices. Looking at
the history, AMBA bus was added in 2003 with just 'irq' and then
changed (ABI break) in 2004 to 'irq0' and 'irq1'.

Rob

[1] https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/log/arch/arm/common/amba.c


From jirislaby at kernel.org  Wed Aug 25 05:57:17 2021
From: jirislaby at kernel.org (Jiri Slaby)
Date: Wed, 25 Aug 2021 14:57:17 +0200
Subject: [PATCH] mxser: use semi-colons instead of commas
In-Reply-To: <20210825072435.GB13013@kili>
References: <20210825072435.GB13013@kili>
Message-ID: <cf2ce3bc-323d-b622-214a-62cd012f29ad@kernel.org>

On 25. 08. 21, 9:24, Dan Carpenter wrote:
> This code works, but it's cleaner to use semi-colons at the end of
> a statement instead of a comma.
> 
> Signed-off-by: Dan Carpenter <dan.carpenter at oracle.com>

Acked-by: Jiri Slaby <jirislaby at kernel.org>

> ---
>   drivers/tty/mxser.c | 12 ++++++------
>   1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
> index 335e4e50d679..1216f3985e18 100644
> --- a/drivers/tty/mxser.c
> +++ b/drivers/tty/mxser.c
> @@ -1039,12 +1039,12 @@ static int mxser_get_serial_info(struct tty_struct *tty,
>   	if (closing_wait != ASYNC_CLOSING_WAIT_NONE)
>   		closing_wait = jiffies_to_msecs(closing_wait) / 10;
>   
> -	ss->type = info->type,
> -	ss->line = tty->index,
> -	ss->port = info->ioaddr,
> -	ss->irq = info->board->irq,
> -	ss->flags = info->port.flags,
> -	ss->baud_base = MXSER_BAUD_BASE,
> +	ss->type = info->type;
> +	ss->line = tty->index;
> +	ss->port = info->ioaddr;
> +	ss->irq = info->board->irq;
> +	ss->flags = info->port.flags;
> +	ss->baud_base = MXSER_BAUD_BASE;
>   	ss->close_delay = close_delay;
>   	ss->closing_wait = closing_wait;
>   	ss->custom_divisor = MXSER_CUSTOM_DIVISOR,
> 


-- 
js
suse labs


From ownia.linux at gmail.com  Wed Aug 25 06:18:49 2021
From: ownia.linux at gmail.com (ownia)
Date: Wed, 25 Aug 2021 21:18:49 +0800
Subject: [PATCH 3/4] ARM: Support KFENCE for ARM
In-Reply-To: <20210825092116.149975-4-wangkefeng.wang@huawei.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <20210825092116.149975-4-wangkefeng.wang@huawei.com>
Message-ID: <51b02ecd-0f3d-99b0-c943-1d4da26174d0@gmail.com>


On 2021/8/25 17:21, Kefeng Wang wrote:
> Add architecture specific implementation details for KFENCE and enable
> KFENCE on ARM. In particular, this implements the required interface in
>  <asm/kfence.h>.
>
> KFENCE requires that attributes for pages from its memory pool can
> individually be set. Therefore, force the kfence pool to be mapped
> at page granularity.
>
> Testing this patch using the testcases in kfence_test.c and all passed
> with or without ARM_LPAE.
>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  arch/arm/Kconfig              |  1 +
>  arch/arm/include/asm/kfence.h | 52 +++++++++++++++++++++++++++++++++++
>  arch/arm/mm/fault.c           |  9 ++++--
>  3 files changed, 60 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/include/asm/kfence.h
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 7a8059ff6bb0..3798f82a0c0d 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -73,6 +73,7 @@ config ARM
>  	select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
>  	select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
>  	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
> +	select HAVE_ARCH_KFENCE if MMU
>  	select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
>  	select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
>  	select HAVE_ARCH_MMAP_RND_BITS if MMU
> diff --git a/arch/arm/include/asm/kfence.h b/arch/arm/include/asm/kfence.h
> new file mode 100644
> index 000000000000..eae7a12ab2a9
> --- /dev/null
> +++ b/arch/arm/include/asm/kfence.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef __ASM_ARM_KFENCE_H
> +#define __ASM_ARM_KFENCE_H
> +
> +#include <linux/kfence.h>
> +#include <asm/set_memory.h>
> +#include <asm/pgalloc.h>
> +
> +static inline int split_pmd_page(pmd_t *pmd, unsigned long addr)
> +{
> +	int i;
> +	unsigned long pfn = PFN_DOWN(__pa((addr & PMD_MASK)));
> +	pte_t *pte = pte_alloc_one_kernel(&init_mm);
> +
> +	if (!pte)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < PTRS_PER_PTE; i++)
> +		set_pte_ext(pte + i, pfn_pte(pfn + i, PAGE_KERNEL), 0);
> +	pmd_populate_kernel(&init_mm, pmd, pte);
> +
> +	flush_tlb_kernel_range(addr, addr + PMD_SIZE);
> +	return 0;
> +}
> +
> +static inline bool arch_kfence_init_pool(void)
> +{
> +	unsigned long addr;
> +	pmd_t *pmd;
> +
> +	for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr);
> +	     addr += PAGE_SIZE) {
> +		pmd = pmd_off_k(addr);
> +
> +		if (pmd_leaf(*pmd)) {
> +			if (split_pmd_page(pmd, addr))
> +				return false;
> +		}
> +	}
> +
> +	return true;
> +}
> +
> +static inline bool kfence_protect_page(unsigned long addr, bool protect)
> +{
> +	set_memory_valid(addr, 1, !protect);
> +
> +	return true;
> +}
> +
> +#endif /* __ASM_ARM_KFENCE_H */
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index f7ab6dabe89f..9fa221ffa1b9 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -17,6 +17,7 @@
>  #include <linux/sched/debug.h>
>  #include <linux/highmem.h>
>  #include <linux/perf_event.h>
> +#include <linux/kfence.h>
>  
>  #include <asm/system_misc.h>
>  #include <asm/system_info.h>
> @@ -131,10 +132,14 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
>  	/*
>  	 * No handler, we'll have to terminate things with extreme prejudice.
>  	 */
> -	if (addr < PAGE_SIZE)
> +	if (addr < PAGE_SIZE) {
>  		msg = "NULL pointer dereference";
> -	else
> +	} else {
> +		if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
> +			return;
> +
>  		msg = "paging request";
> +	}


I think here should do some fixup to follow upstream mainline code.


>  
>  	die_kernel_fault(msg, mm, addr, fsr, regs);
>  }


From lorenzo.pieralisi at arm.com  Wed Aug 25 06:30:35 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 25 Aug 2021 14:30:35 +0100
Subject: [PATCH linux-next] arm64: PCI: Introduce pcibios_free_irq()
 helper function
In-Reply-To: <20210825071612.21543-1-yajun.deng@linux.dev>
References: <20210825071612.21543-1-yajun.deng@linux.dev>
Message-ID: <20210825133035.GA20522@e123427-lin.cambridge.arm.com>

On Wed, Aug 25, 2021 at 03:16:12PM +0800, Yajun Deng wrote:
> Introduce pcibios_free_irq() to free irq in pci_device_probe() and
> pci_device_remove() that in drivers/pci/pci-driver.c.

Add a rationale - it is just code inspection or you are fixing a bug ?

> Signed-off-by: Yajun Deng <yajun.deng at linux.dev>
> ---
>  arch/arm64/kernel/pci.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> index 1006ed2d7c60..40da5aff4548 100644
> --- a/arch/arm64/kernel/pci.c
> +++ b/arch/arm64/kernel/pci.c
> @@ -25,10 +25,18 @@
>  int pcibios_alloc_irq(struct pci_dev *dev)
>  {
>  	if (!acpi_disabled)
> -		acpi_pci_irq_enable(dev);
> +		return acpi_pci_irq_enable(dev);

This is an unrelated change and it is potentially introducing
regressions. I need to page in the reasons why on arm64 we had to resort
to pcibios_alloc_irq() (probe ordering IIRC) - in the meanwhile
this function stays as it is.

>  	return 0;
>  }
> +
> +void pcibios_free_irq(struct pci_dev *dev)
> +{
> +	if (!acpi_disabled)
> +		acpi_pci_irq_disable(dev);
> +
> +}

Adding pcibios_free_irq() makes sense and I believe it is a genuine
"fix".

Please add any information in the commit log that explains the
run-time condition you are fixing.

Thanks,
Lorenzo


From robh+dt at kernel.org  Wed Aug 25 06:38:24 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 08:38:24 -0500
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <87o89lahqp.fsf@tarshish>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
 <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
 <87o89lahqp.fsf@tarshish>
Message-ID: <CAL_Jsq+wkTbGjyk_i-_1Sad80xcJwAFdf5gBTGBR_TORRA-AoQ@mail.gmail.com>

On Wed, Aug 25, 2021 at 6:25 AM Baruch Siach <baruch at tkos.co.il> wrote:
>
> Hi Rob,
>
> On Fri, Aug 06 2021, Rob Herring wrote:
> > On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
> >>
> >> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> >>
> >> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> >> platform.
> >>
> >> The code is based on downstream Codeaurora kernel v5.4. Split out the
> >> DBI registers access part from .init into .post_init. DBI registers are
> >> only accessible after phy_power_on().
> >>
> >> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> >> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> >> ---
> >> v2:
> >>   * Drop ATU configuration; rely on common code instead
> >>
> >>   * Use more common register macros
> >>
> >>   * Use bulk clk and reset APIs
> >> ---
> >>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
> >>  drivers/pci/controller/dwc/pcie-qcom.c       | 150 +++++++++++++++++++
> >>  2 files changed, 151 insertions(+)
> >>
> >> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> >> index ceb359b6e6a6..346462c74a3e 100644
> >> --- a/drivers/pci/controller/dwc/pcie-designware.h
> >> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> >> @@ -76,6 +76,7 @@
> >>
> >>  #define GEN3_RELATED_OFF                       0x890
> >>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL   BIT(0)
> >> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS    BIT(13)
> >>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE       BIT(16)
> >>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24
> >>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK  GENMASK(25, 24)
> >> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> >> index 8a7a300163e5..93766aee3e7c 100644
> >> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> >> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> >> @@ -52,6 +52,10 @@
> >>  #define PCIE20_PARF_DBI_BASE_ADDR              0x168
> >>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16C
> >>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL       0x174
> >> +#define AHB_CLK_EN                             BIT(0)
> >> +#define MSTR_AXI_CLK_EN                                BIT(1)
> >> +#define BYPASS                                 BIT(4)
> >> +
> >>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT      0x178
> >>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2   0x1A8
> >>  #define PCIE20_PARF_LTSSM                      0x1B0
> >> @@ -94,6 +98,12 @@
> >>  #define SLV_ADDR_SPACE_SZ                      0x10000000
> >>
> >>  #define PCIE20_LNK_CONTROL2_LINK_STATUS2       0xa0
> >> +#define PCIE_CAP_CURR_DEEMPHASIS               BIT(16)
> >
> > Isn't this a standard register field?
>
> I don't know. I could not find any reference to this field or the
> registers it's part of.

It is. I found it in the spec. But it's not in pci_reg.h and it is a
read-only status bit (though some in DWC can be written).

> n
> >> +#define SPEED_GEN1                             0x1
> >> +#define SPEED_GEN2                             0x2
> >> +#define SPEED_GEN3                             0x3
> >
> > And these?

#define PCI_EXP_LNKCTL2         48      /* Link Control 2 */
#define  PCI_EXP_LNKCTL2_TLS            0x000f
#define  PCI_EXP_LNKCTL2_TLS_2_5GT      0x0001 /* Supported Speed 2.5GT/s */
#define  PCI_EXP_LNKCTL2_TLS_5_0GT      0x0002 /* Supported Speed 5GT/s */
#define  PCI_EXP_LNKCTL2_TLS_8_0GT      0x0003 /* Supported Speed 8GT/s */
#define  PCI_EXP_LNKCTL2_TLS_16_0GT     0x0004 /* Supported Speed 16GT/s */
#define  PCI_EXP_LNKCTL2_TLS_32_0GT     0x0005 /* Supported Speed 32GT/s */
#define  PCI_EXP_LNKCTL2_TLS_64_0GT     0x0006 /* Supported Speed 64GT/s */
#define  PCI_EXP_LNKCTL2_ENTER_COMP     0x0010 /* Enter Compliance */
#define  PCI_EXP_LNKCTL2_TX_MARGIN      0x0380 /* Transmit Margin */
#define  PCI_EXP_LNKCTL2_HASD           0x0020 /* HW Autonomous Speed Disable */
#define PCI_EXP_LNKSTA2         50      /* Link Status 2 */

> >
> > There's already some common DWC code for setting the link speed.
>
> dw_pcie_link_set_max_speed() deals with other registers, as far as I can
> see.

Link Control2 which is what the above function configures appears to
be the same register to me. Your definition is combining 2 registers.

>
> >> +#define AXI_CLK_RATE                           200000000
> >> +#define RCHNG_CLK_RATE                         100000000
> >>
> >>  #define DEVICE_TYPE_RC                         0x4
>
> [snip]
>
> >> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
> >> +{
> >> +       struct dw_pcie *pci = pcie->pci;
> >> +       u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> >> +       u32 val;
> >> +       int i;
> >> +
> >> +       writel(SLV_ADDR_SPACE_SZ,
> >> +               pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
> >> +
> >> +       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> >> +       val &= ~BIT(0);
> >> +       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> >> +
> >> +       writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> >> +
> >> +       writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
> >> +       writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
> >> +               pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> >> +       writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
> >> +               | GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
> >> +               pci->dbi_base + GEN3_RELATED_OFF);
> >> +
> >> +       writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
> >> +               | SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
> >> +               AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
> >> +               pcie->parf + PCIE20_PARF_SYS_CTRL);
> >> +
> >> +       writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
> >> +
> >> +       dw_pcie_dbi_ro_wr_en(pci);
> >> +       writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
> >> +
> >> +       /* Configure PCIe link capabilities for ASPM */
> >> +       val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
> >> +       val &= ~PCI_EXP_LNKCAP_ASPMS;
> >> +       writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
> >> +
> >> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> >> +                       PCI_EXP_DEVCTL2);
> >> +
> >> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
> >> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);
> >
> > Doesn't this overwrite the prior register write?
>
> It does. There are two mistakes here. The writel() above should set
> PCIE20_DEVICE_CONTROL2_STATUS2 (offset 0x98).

No. Did you check what 'offset' is? PCIE20_DEVICE_CONTROL2_STATUS2 is
PCI_EXP_DEVCTL2 plus the status reg. What's wrong is it should be a
16-bit write.

> This writel() should set
> PCIE20_LNK_CONTROL2_LINK_STATUS2 (offset 0xa0). So both are wrong.
>
> >> +
> >> +       for (i = 0;i < 256;i++)
> >> +               writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
> >> +                               + (4 * i));
> >> +
> >> +       return 0;
> >> +}
>
> Thanks,
> baruch
>
> --
>                                                      ~. .~   Tk Open Systems
> =}------------------------------------------------ooO--U--Ooo------------{=
>    - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:40:48 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:40:48 +0200
Subject: [PATCH v3 0/8] dt-bindings: clock: samsung: convert to dtschema
Message-ID: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>

Hi,

Changes since v2:
1. Add reviews.
2. Split Exynos4 ISP into separate schema.
3. Add maxItems to clocks and power-domains (review feedback).
4. Do not allow samsung,exynos5420-clock and samsung,exynos5800-clock
   without syscon. These clock controllers should always use syscon
   to allow DMC bindings access the registers.
5. Drop assigned-clocks.

Changes since v1:
1. Patch 7/8: include header to fix clock IDs error in example.
2. Combined patchset of separate v1 sets:

https://lore.kernel.org/linux-samsung-soc/20210809120544.56596-1-krzysztof.kozlowski at canonical.com/T/#t
https://lore.kernel.org/linux-samsung-soc/20210809130935.80565-1-krzysztof.kozlowski at canonical.com/T/#t
https://lore.kernel.org/linux-samsung-soc/20210809135942.100744-1-krzysztof.kozlowski at canonical.com/T/#t

Best regards,
Krzysztof

Krzysztof Kozlowski (8):
  dt-bindings: clock: samsung: convert Exynos5250 to dtschema
  dt-bindings: clock: samsung: add bindings for Exynos external clock
  dt-bindings: clock: samsung: convert Exynos542x to dtschema
  dt-bindings: clock: samsung: convert Exynos3250 to dtschema
  dt-bindings: clock: samsung: convert Exynos4 to dtschema
  dt-bindings: clock: samsung: convert Exynos AudSS to dtschema
  dt-bindings: clock: samsung: convert S5Pv210 AudSS to dtschema
  MAINTAINERS: clock: include S3C and S5P in Samsung SoC clock entry

 .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
 .../bindings/clock/clk-s5pv210-audss.txt      |  53 ---------
 .../bindings/clock/exynos3250-clock.txt       |  57 ----------
 .../bindings/clock/exynos4-clock.txt          |  86 ---------------
 .../bindings/clock/exynos5250-clock.txt       |  41 -------
 .../bindings/clock/exynos5420-clock.txt       |  42 -------
 .../clock/samsung,exynos-audss-clock.yaml     |  80 ++++++++++++++
 .../bindings/clock/samsung,exynos-clock.yaml  |  59 ++++++++++
 .../clock/samsung,exynos-ext-clock.yaml       |  46 ++++++++
 .../clock/samsung,exynos4412-isp-clock.yaml   |  64 +++++++++++
 .../clock/samsung,s5pv210-audss-clock.yaml    |  78 +++++++++++++
 MAINTAINERS                                   |   4 +
 12 files changed, 331 insertions(+), 382 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos3250-clock.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml

-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:40:49 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:40:49 +0200
Subject: [PATCH v3 1/8] dt-bindings: clock: samsung: convert Exynos5250 to
 dtschema
In-Reply-To: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210825134056.219884-2-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos5250 clock controller bindings to DT schema format
using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../bindings/clock/exynos5250-clock.txt       | 41 -----------------
 .../bindings/clock/samsung,exynos-clock.yaml  | 46 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 3 files changed, 47 insertions(+), 41 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
deleted file mode 100644
index aff266a12eeb..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-* Samsung Exynos5250 Clock Controller
-
-The Exynos5250 clock controller generates and supplies clock to various
-controllers within the Exynos5250 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5250.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10010000 {
-		compatible = "samsung,exynos5250-clock";
-		reg = <0x10010000 0x30000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
new file mode 100644
index 000000000000..1642f8405ed9
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  dt-bindings/clock/ headers.
+
+properties:
+  compatible:
+    const: samsung,exynos5250-clock
+
+  clocks:
+    maxItems: 4
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5250.h>
+    clock: clock-controller at 10010000 {
+        compatible = "samsung,exynos5250-clock";
+        reg = <0x10010000 0x30000>;
+        #clock-cells = <1>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 64bb17c47bda..a8e1e5d10d1f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16491,6 +16491,7 @@ L:	linux-samsung-soc at vger.kernel.org
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
 F:	Documentation/devicetree/bindings/clock/exynos*.txt
+F:	Documentation/devicetree/bindings/clock/samsung,*.yaml
 F:	Documentation/devicetree/bindings/clock/samsung,s3c*
 F:	Documentation/devicetree/bindings/clock/samsung,s5p*
 F:	drivers/clk/samsung/
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:40:50 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:40:50 +0200
Subject: [PATCH v3 2/8] dt-bindings: clock: samsung: add bindings for Exynos
 external clock
In-Reply-To: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210825134056.219884-3-krzysztof.kozlowski@canonical.com>

Document the bindings for Samsung Exynos external to SoC
(oscclk/XXTI/XusbXTI) clock provided on boards.  The bindings are
already implemented in most of the Exynos clock drivers and DTS files.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../clock/samsung,exynos-ext-clock.yaml       | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
new file mode 100644
index 000000000000..64d027dbe3b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-ext-clock.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-ext-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung SoC external/osc/XXTI/XusbXTI clock
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Samsung SoCs require an external clock supplied through XXTI or XusbXTI pins.
+
+properties:
+  compatible:
+    enum:
+      - samsung,clock-xxti
+      - samsung,clock-xusbxti
+      - samsung,exynos5420-oscclk
+
+  "#clock-cells":
+    const: 0
+
+  clock-frequency: true
+
+  clock-output-names:
+    maxItems: 1
+
+required:
+  - compatible
+  - clock-frequency
+
+additionalProperties: false
+
+examples:
+  - |
+    fixed-rate-clocks {
+        clock {
+            compatible = "samsung,clock-xxti";
+            clock-frequency = <24000000>;
+        };
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:40:51 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:40:51 +0200
Subject: [PATCH v3 3/8] dt-bindings: clock: samsung: convert Exynos542x to
 dtschema
In-Reply-To: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210825134056.219884-4-krzysztof.kozlowski@canonical.com>

Merge Exynos542x clock controller bindings to existing DT schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../bindings/clock/exynos5420-clock.txt       | 42 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  |  9 +++-
 2 files changed, 8 insertions(+), 43 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
deleted file mode 100644
index 717a7b1531c7..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-* Samsung Exynos5420 Clock Controller
-
-The Exynos5420 clock controller generates and supplies clock to various
-controllers within the Exynos5420 SoC and for the Exynos5800 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
-  - "samsung,exynos5800-clock" - controller compatible with Exynos5800 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5420.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10010000 {
-		compatible = "samsung,exynos5420-clock";
-		reg = <0x10010000 0x30000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index 1642f8405ed9..b807ae79e3b7 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -18,7 +18,14 @@ description: |
 
 properties:
   compatible:
-    const: samsung,exynos5250-clock
+    oneOf:
+      - enum:
+          - samsung,exynos5250-clock
+      - items:
+          - enum:
+              - samsung,exynos5420-clock
+              - samsung,exynos5800-clock
+          - const: syscon
 
   clocks:
     maxItems: 4
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:40:52 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:40:52 +0200
Subject: [PATCH v3 4/8] dt-bindings: clock: samsung: convert Exynos3250 to
 dtschema
In-Reply-To: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210825134056.219884-5-krzysztof.kozlowski@canonical.com>

Merge Exynos3250 clock controller bindings to existing DT schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/clock/exynos3250-clock.txt       | 57 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  |  3 +
 2 files changed, 3 insertions(+), 57 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos3250-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/exynos3250-clock.txt b/Documentation/devicetree/bindings/clock/exynos3250-clock.txt
deleted file mode 100644
index 7441ed519f02..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos3250-clock.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-* Samsung Exynos3250 Clock Controller
-
-The Exynos3250 clock controller generates and supplies clock to various
-controllers within the Exynos3250 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos3250-cmu" - controller compatible with Exynos3250 SoC.
-  - "samsung,exynos3250-cmu-dmc" - controller compatible with
-    Exynos3250 SoC for Dynamic Memory Controller domain.
-  - "samsung,exynos3250-cmu-isp" - ISP block clock controller compatible
-     with Exynos3250 SOC
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos3250.h header and can be used in device
-tree sources.
-
-Example 1: Examples of clock controller nodes are listed below.
-
-	cmu: clock-controller at 10030000 {
-		compatible = "samsung,exynos3250-cmu";
-		reg = <0x10030000 0x20000>;
-		#clock-cells = <1>;
-	};
-
-	cmu_dmc: clock-controller at 105c0000 {
-		compatible = "samsung,exynos3250-cmu-dmc";
-		reg = <0x105C0000 0x2000>;
-		#clock-cells = <1>;
-	};
-
-	cmu_isp: clock-controller at 10048000 {
-		compatible = "samsung,exynos3250-cmu-isp";
-		reg = <0x10048000 0x1000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13800000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13800000 0x100>;
-		interrupts = <0 109 0>;
-		clocks = <&cmu CLK_UART0>, <&cmu CLK_SCLK_UART0>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index b807ae79e3b7..9af77bdee12d 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -20,6 +20,9 @@ properties:
   compatible:
     oneOf:
       - enum:
+          - samsung,exynos3250-cmu
+          - samsung,exynos3250-cmu-dmc
+          - samsung,exynos3250-cmu-isp
           - samsung,exynos5250-clock
       - items:
           - enum:
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:40:53 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:40:53 +0200
Subject: [PATCH v3 5/8] dt-bindings: clock: samsung: convert Exynos4 to
 dtschema
In-Reply-To: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>

Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos4-clock.txt          | 86 -------------------
 .../bindings/clock/samsung,exynos-clock.yaml  |  3 +
 .../clock/samsung,exynos4412-isp-clock.yaml   | 64 ++++++++++++++
 3 files changed, 67 insertions(+), 86 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
deleted file mode 100644
index 17bb11365354..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-* Samsung Exynos4 Clock Controller
-
-The Exynos4 clock controller generates and supplies clock to various controllers
-within the Exynos4 SoC. The clock binding described here is applicable to all
-SoC's in the Exynos4 family.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
-  - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos4.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock: clock-controller at 10030000 {
-		compatible = "samsung,exynos4210-clock";
-		reg = <0x10030000 0x20000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 13820000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13820000 0x100>;
-		interrupts = <0 54 0>;
-		clocks = <&clock CLK_UART2>, <&clock CLK_SCLK_UART2>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
-
-Exynos4412 SoC contains some additional clocks for FIMC-ISP (Camera ISP)
-subsystem. Registers for those clocks are located in the ISP power domain.
-Because those registers are also located in a different memory region than
-the main clock controller, a separate clock controller has to be defined for
-handling them.
-
-Required Properties:
-
-- compatible: should be "samsung,exynos4412-isp-clock".
-
-- reg: physical base address of the ISP clock controller and length of memory
-  mapped region.
-
-- #clock-cells: should be 1.
-
-- clocks: list of the clock controller input clock identifiers,
-  from common clock bindings, should point to CLK_ACLK200 and
-  CLK_ACLK400_MCUISP clocks from the main clock controller.
-
-- clock-names: list of the clock controller input clock names,
-  as described in clock-bindings.txt, should be "aclk200" and
-  "aclk400_mcuisp".
-
-- power-domains: a phandle to ISP power domain node as described by
-  generic PM domain bindings.
-
-Example 3: The clock controllers bindings for Exynos4412 SoCs.
-
-	clock: clock-controller at 10030000 {
-		compatible = "samsung,exynos4412-clock";
-		reg = <0x10030000 0x18000>;
-		#clock-cells = <1>;
-	};
-
-	isp_clock: clock-controller at 10048000 {
-		compatible = "samsung,exynos4412-isp-clock";
-		reg = <0x10048000 0x1000>;
-		#clock-cells = <1>;
-		power-domains = <&pd_isp>;
-		clocks = <&clock CLK_ACLK200>, <&clock CLK_ACLK400_MCUISP>;
-		clock-names = "aclk200", "aclk400_mcuisp";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
index 9af77bdee12d..4e8062860986 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
@@ -23,6 +23,8 @@ properties:
           - samsung,exynos3250-cmu
           - samsung,exynos3250-cmu-dmc
           - samsung,exynos3250-cmu-isp
+          - samsung,exynos4210-clock
+          - samsung,exynos4412-clock
           - samsung,exynos5250-clock
       - items:
           - enum:
@@ -31,6 +33,7 @@ properties:
           - const: syscon
 
   clocks:
+    minItems: 1
     maxItems: 4
 
   "#clock-cells":
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml
new file mode 100644
index 000000000000..7b405bcd6fef
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos4412-isp-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos4412 SoC ISP clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Clock controller for Samsung Exynos4412 SoC FIMC-ISP (Camera ISP)
+  All available clocks are defined as preprocessor macros in
+  dt-bindings/clock/ headers.
+
+properties:
+  compatible:
+    const: samsung,exynos4412-isp-clock
+
+  clocks:
+    items:
+      - description: CLK_ACLK200 from the main clock controller
+      - description: CLK_ACLK400_MCUISP from the main clock controller
+
+  clock-names:
+    items:
+      - const: aclk200
+      - const: aclk400_mcuisp
+
+  "#clock-cells":
+    const: 1
+
+  power-domains:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - power-domains
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos4412.h>
+    clock-controller at 10048000 {
+        compatible = "samsung,exynos4412-isp-clock";
+        reg = <0x10048000 0x1000>;
+        #clock-cells = <1>;
+        power-domains = <&pd_isp>;
+        clocks = <&clock CLK_ACLK200>, <&clock CLK_ACLK400_MCUISP>;
+        clock-names = "aclk200", "aclk400_mcuisp";
+    };
+
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:42:49 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:42:49 +0200
Subject: [PATCH v3 6/8] dt-bindings: clock: samsung: convert Exynos AudSS to
 dtschema
In-Reply-To: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
Message-ID: <20210825134251.220098-1-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
 .../clock/samsung,exynos-audss-clock.yaml     |  80 ++++++++++++++
 2 files changed, 80 insertions(+), 103 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
deleted file mode 100644
index 6030afb10b5c..000000000000
--- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-* Samsung Audio Subsystem Clock Controller
-
-The Samsung Audio Subsystem clock controller generates and supplies clocks
-to Audio Subsystem block available in the S5PV210 and Exynos SoCs. The clock
-binding described here is applicable to all SoCs in Exynos family.
-
-Required Properties:
-
-- compatible: should be one of the following:
-  - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
-  - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
-    SoCs.
-  - "samsung,exynos5410-audss-clock" - controller compatible with Exynos5410
-    SoCs.
-  - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
-    SoCs.
-- reg: physical base address and length of the controller's register set.
-
-- #clock-cells: should be 1.
-
-- clocks:
-  - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
-    is used if not specified.
-  - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
-    is used if not specified.
-  - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
-    specified.
-  - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
-    not specified.
-  - sclk_pcm_in: PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not
-    specified.
-
-- clock-names: Aliases for the above clocks. They should be "pll_ref",
-  "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
-
-Optional Properties:
-
-  - power-domains: a phandle to respective power domain node as described by
-    generic PM domain bindings (see power/power_domain.txt for more
-    information).
-
-The following is the list of clocks generated by the controller. Each clock is
-assigned an identifier and client nodes use this identifier to specify the
-clock which they consume. Some of the clocks are available only on a particular
-Exynos4 SoC and this is specified where applicable.
-
-Provided clocks:
-
-Clock           ID      SoC (if specific)
------------------------------------------------
-
-mout_audss      0
-mout_i2s        1
-dout_srp        2
-dout_aud_bus    3
-dout_i2s        4
-srp_clk         5
-i2s_bus         6
-sclk_i2s        7
-pcm_bus         8
-sclk_pcm        9
-adma            10      Exynos5420
-
-Example 1: An example of a clock controller node using the default input
-	   clock names is listed below.
-
-clock_audss: audss-clock-controller at 3810000 {
-	compatible = "samsung,exynos5250-audss-clock";
-	reg = <0x03810000 0x0C>;
-	#clock-cells = <1>;
-};
-
-Example 2: An example of a clock controller node with the input clocks
-           specified.
-
-clock_audss: audss-clock-controller at 3810000 {
-	compatible = "samsung,exynos5250-audss-clock";
-	reg = <0x03810000 0x0C>;
-	#clock-cells = <1>;
-	clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
-		<&ext_i2s_clk>;
-	clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
-};
-
-Example 3: I2S controller node that consumes the clock generated by the clock
-           controller. Refer to the standard clock bindings for information
-           about 'clocks' and 'clock-names' property.
-
-i2s0: i2s at 3830000 {
-	compatible = "samsung,i2s-v5";
-	reg = <0x03830000 0x100>;
-	dmas = <&pdma0 10
-		&pdma0 9
-		&pdma0 8>;
-	dma-names = "tx", "rx", "tx-sec";
-	clocks = <&clock_audss EXYNOS_I2S_BUS>,
-		<&clock_audss EXYNOS_I2S_BUS>,
-		<&clock_audss EXYNOS_SCLK_I2S>,
-		<&clock_audss EXYNOS_MOUT_AUDSS>,
-		<&clock_audss EXYNOS_MOUT_I2S>;
-	clock-names = "iis", "i2s_opclk0", "i2s_opclk1",
-		      "mout_audss", "mout_i2s";
-};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
new file mode 100644
index 000000000000..f14f1d39da36
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos-audss-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC Audio SubSystem clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/exynos-audss-clk.h header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos4210-audss-clock
+      - samsung,exynos5250-audss-clock
+      - samsung,exynos5410-audss-clock
+      - samsung,exynos5420-audss-clock
+
+  clocks:
+    minItems: 2
+    items:
+      - description:
+          Fixed rate PLL reference clock, parent of mout_audss. "fin_pll" is
+          used if not specified.
+      - description:
+          Input PLL to the AudioSS block, parent of mout_audss. "fout_epll" is
+          used if not specified.
+      - description:
+          Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if not
+          specified.
+      - description:
+          PCM clock, parent of sclk_pcm.  "sclk_pcm0" is used if not specified.
+      - description:
+          External i2s clock, parent of mout_i2s. "cdclk0" is used if not
+          specified.
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: pll_ref
+      - const: pll_in
+      - const: sclk_audio
+      - const: sclk_pcm_in
+      - const: cdclk
+
+  "#clock-cells":
+    const: 1
+
+  power-domains:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 3810000 {
+        compatible = "samsung,exynos5250-audss-clock";
+        reg = <0x03810000 0x0c>;
+        #clock-cells = <1>;
+        clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>, <&ext_i2s_clk>;
+        clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:42:50 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:42:50 +0200
Subject: [PATCH v3 7/8] dt-bindings: clock: samsung: convert S5Pv210 AudSS to
 dtschema
In-Reply-To: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
Message-ID: <20210825134251.220098-2-krzysztof.kozlowski@canonical.com>

Convert Samsung S5Pv210 Audio SubSystem clock controller bindings to DT
schema format using json-schema.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

---

Changes since v1:
1. Include header to fix clock IDs error in example.
---
 .../bindings/clock/clk-s5pv210-audss.txt      | 53 -------------
 .../clock/samsung,s5pv210-audss-clock.yaml    | 78 +++++++++++++++++++
 2 files changed, 78 insertions(+), 53 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt b/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
deleted file mode 100644
index f6272dcd96f4..000000000000
--- a/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-* Samsung Audio Subsystem Clock Controller
-
-The Samsung Audio Subsystem clock controller generates and supplies clocks
-to Audio Subsystem block available in the S5PV210 and compatible SoCs.
-
-Required Properties:
-
-- compatible: should be "samsung,s5pv210-audss-clock".
-- reg: physical base address and length of the controller's register set.
-
-- #clock-cells: should be 1.
-
-- clocks:
-  - hclk: AHB bus clock of the Audio Subsystem.
-  - xxti: Optional fixed rate PLL reference clock, parent of mout_audss. If
-    not specified (i.e. xusbxti is used for PLL reference), it is fixed to
-    a clock named "xxti".
-  - fout_epll: Input PLL to the AudioSS block, parent of mout_audss.
-  - iiscdclk0: Optional external i2s clock, parent of mout_i2s. If not
-    specified, it is fixed to a clock named "iiscdclk0".
-  - sclk_audio0: Audio bus clock, parent of mout_i2s.
-
-- clock-names: Aliases for the above clocks. They should be "hclk",
-  "xxti", "fout_epll", "iiscdclk0", and "sclk_audio0" respectively.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/s5pv210-audss-clk.h header and can be used in device
-tree sources.
-
-Example: Clock controller node.
-
-	clk_audss: clock-controller at c0900000 {
-		compatible = "samsung,s5pv210-audss-clock";
-		reg = <0xc0900000 0x1000>;
-		#clock-cells = <1>;
-		clock-names = "hclk", "xxti",
-				"fout_epll", "sclk_audio0";
-		clocks = <&clocks DOUT_HCLKP>, <&xxti>,
-				<&clocks FOUT_EPLL>, <&clocks SCLK_AUDIO0>;
-	};
-
-Example: I2S controller node that consumes the clock generated by the clock
-	 controller. Refer to the standard clock bindings for information
-         about 'clocks' and 'clock-names' property.
-
-	i2s0: i2s at 3830000 {
-		/* ... */
-		clock-names = "iis", "i2s_opclk0",
-				"i2s_opclk1";
-		clocks = <&clk_audss CLK_I2S>, <&clk_audss CLK_I2S>,
-				<&clk_audss CLK_DOUT_AUD_BUS>;
-		/* ... */
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
new file mode 100644
index 000000000000..ae8f8fc93233
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,s5pv210-audss-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S5Pv210 SoC Audio SubSystem clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/s5pv210-audss.h header.
+
+properties:
+  compatible:
+    const: samsung,s5pv210-audss-clock
+
+  clocks:
+    minItems: 4
+    items:
+      - description:
+          AHB bus clock of the Audio Subsystem.
+      - description:
+          Optional fixed rate PLL reference clock, parent of mout_audss. If not
+          specified (i.e. xusbxti is used for PLL reference), it is fixed to a
+          clock named "xxti".
+      - description:
+          Input PLL to the AudioSS block, parent of mout_audss.
+      - description:
+          Audio bus clock, parent of mout_i2s.
+      - description:
+          Optional external i2s clock, parent of mout_i2s. If not specified, it
+          is fixed to a clock named "iiscdclk0".
+
+  clock-names:
+    minItems: 4
+    items:
+      - const: hclk
+      - const: xxti
+      - const: fout_epll
+      - const: sclk_audio0
+      - const: iiscdclk0
+
+  "#clock-cells":
+    const: 1
+
+  power-domains:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/s5pv210.h>
+
+    clock-controller at c0900000 {
+        compatible = "samsung,s5pv210-audss-clock";
+        reg = <0xc0900000 0x1000>;
+        #clock-cells = <1>;
+        clock-names = "hclk", "xxti", "fout_epll", "sclk_audio0";
+        clocks = <&clocks DOUT_HCLKP>, <&xxti>, <&clocks FOUT_EPLL>,
+                 <&clocks SCLK_AUDIO0>;
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Wed Aug 25 06:42:51 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 25 Aug 2021 15:42:51 +0200
Subject: [PATCH v3 8/8] MAINTAINERS: clock: include S3C and S5P in Samsung SoC
 clock entry
In-Reply-To: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
Message-ID: <20210825134251.220098-3-krzysztof.kozlowski@canonical.com>

Cover the S3C and S5Pv210 clock controller binding headers by Samsung
SoC clock controller drivers maintainer entry.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index a8e1e5d10d1f..eb4ada858826 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16496,6 +16496,9 @@ F:	Documentation/devicetree/bindings/clock/samsung,s3c*
 F:	Documentation/devicetree/bindings/clock/samsung,s5p*
 F:	drivers/clk/samsung/
 F:	include/dt-bindings/clock/exynos*.h
+F:	include/dt-bindings/clock/s3c*.h
+F:	include/dt-bindings/clock/s5p*.h
+F:	include/dt-bindings/clock/samsung,*.h
 F:	include/linux/clk/samsung.h
 F:	include/linux/platform_data/clk-s3c2410.h
 
-- 
2.30.2



From robh at kernel.org  Wed Aug 25 07:10:58 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 09:10:58 -0500
Subject: [PATCH v7 3/4] dt-bindings: pwm: add IPQ6018 binding
In-Reply-To: <dbf064fb60b1654af25f65d89f75bd397162d701.1629884907.git.baruch@tkos.co.il>
References: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
 <dbf064fb60b1654af25f65d89f75bd397162d701.1629884907.git.baruch@tkos.co.il>
Message-ID: <1629900658.219829.2719822.nullmailer@robh.at.kernel.org>

On Wed, 25 Aug 2021 12:48:26 +0300, Baruch Siach wrote:
> DT binding for the PWM block in Qualcomm IPQ6018 SoC.
> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
> v7:
> 
>   Use 'reg' instead of 'offset' (Rob)
> 
>   Drop 'clock-names' and 'assigned-clock*' (Bjorn)
> 
>   Use single cell address/size in example node (Bjorn)
> 
>   Move '#pwm-cells' lower in example node (Bjorn)
> 
>   List 'reg' as required
> 
> v6:
> 
>   Device node is child of TCSR; remove phandle (Rob Herring)
> 
>   Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K??nig)
> 
> v5: Use qcom,pwm-regs for phandle instead of direct regs (Bjorn
>     Andersson, Kathiravan T)
> 
> v4: Update the binding example node as well (Rob Herring's bot)
> 
> v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
> 
> v2: Make #pwm-cells const (Rob Herring)
> ---
>  .../devicetree/bindings/pwm/ipq-pwm.yaml      | 52 +++++++++++++++++++
>  1 file changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/pwm/ipq-pwm.example.dt.yaml:0:0: /example-0/syscon at 1937000: failed to match any schema with compatible: ['qcom,tcsr-ipq6018', 'syscon', 'simple-mfd']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1520591

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From wangkefeng.wang at huawei.com  Wed Aug 25 07:15:39 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 22:15:39 +0800
Subject: [PATCH 0/4] ARM: Support KFENCE feature
In-Reply-To: <YSYiEgEcW1Ln3+9P@elver.google.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <CANpmjNMnU5P9xsDhgeBKQR7Tg-3cHPkMNx7906yYwEAj85sNWg@mail.gmail.com>
 <YSYiEgEcW1Ln3+9P@elver.google.com>
Message-ID: <f0cb0ebd-2b4e-7a65-8107-f7e1f23d310f@huawei.com>


On 2021/8/25 18:57, Marco Elver wrote:
> On Wed, Aug 25, 2021 at 12:14PM +0200, Marco Elver wrote:
>> On Wed, 25 Aug 2021 at 11:17, Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>> The patch 1~3 is to support KFENCE feature on ARM.
>>>
>>> NOTE:
>>> The context of patch2/3 changes in arch/arm/mm/fault.c is based on link[1],
>>> which make some refactor and cleanup about page fault.
>>>
>>> kfence_test is not useful when kfence is not enabled, skip kfence test
>>> when kfence not enabled in patch4.
>>>
>>> I tested the kfence_test on ARM QEMU with or without ARM_LPAE and all passed.
>> Thank you for enabling KFENCE on ARM -- I'll leave arch-code review to
>> an ARM maintainer.
>>
>> However, as said on the patch, please drop the change to the
>> kfence_test and associated changes. This is working as intended; while
>> you claim that it takes a long time to run when disabled, when running
>> manually you just should not run it when disabled. There are CI
>> systems that rely on the KUnit test output and the fact that the
>> various test cases say "not ok" etc. Changing that would mean such CI
>> systems would no longer fail if KFENCE was accidentally disabled (once
>> KFENCE is enabled on various CI, which we'd like to do at some point).
>> There are ways to fail the test faster, but they all complicate the
>> test for no good reason. (And the addition of a new exported function
>> that is essentially useless.)
> I spoke too soon -- we export __kfence_pool, and that's good enough to
> fail the test fast if KFENCE was disabled at boot:
>
> 	https://lkml.kernel.org/r/20210825105533.1247922-1-elver at google.com
>
> will do the trick. So please drop your patch 4/4 here.
Sure , please ignore it.
>
> Thanks,
> -- Marco
> .
>


From baruch at tkos.co.il  Wed Aug 25 07:09:49 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 17:09:49 +0300
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <CAL_Jsq+wkTbGjyk_i-_1Sad80xcJwAFdf5gBTGBR_TORRA-AoQ@mail.gmail.com>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
 <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
 <87o89lahqp.fsf@tarshish>
 <CAL_Jsq+wkTbGjyk_i-_1Sad80xcJwAFdf5gBTGBR_TORRA-AoQ@mail.gmail.com>
Message-ID: <87lf4pa9i0.fsf@tarshish>

Hi Rob,

On Wed, Aug 25 2021, Rob Herring wrote:
> On Wed, Aug 25, 2021 at 6:25 AM Baruch Siach <baruch at tkos.co.il> wrote:
>> On Fri, Aug 06 2021, Rob Herring wrote:
>> > On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
>> >> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
>> >> +                       PCI_EXP_DEVCTL2);
>> >> +
>> >> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
>> >> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);
>> >
>> > Doesn't this overwrite the prior register write?
>>
>> It does. There are two mistakes here. The writel() above should set
>> PCIE20_DEVICE_CONTROL2_STATUS2 (offset 0x98).
>
> No. Did you check what 'offset' is? PCIE20_DEVICE_CONTROL2_STATUS2 is
> PCI_EXP_DEVCTL2 plus the status reg. What's wrong is it should be a
> 16-bit write.

Thanks for enlightening me. 'offset' is 0x70 here. So PCI_EXP_DEVCTL2 is
at 0x98, and PCI_EXP_LNKCTL2 is at 0xa0. Only the second writel() is
wrong. But since generic code handles speed, I can drop it entirely.

I see that dw_pcie_link_set_max_speed() uses dw_pcie_writel_dbi() to
write to PCI_EXP_LNKCTL2. Is that 16-bit write?

Why are pci_regs.h register offsets in decimal?

>> This writel() should set
>> PCIE20_LNK_CONTROL2_LINK_STATUS2 (offset 0xa0). So both are wrong.

Thanks,
baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From wangkefeng.wang at huawei.com  Wed Aug 25 07:28:13 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 22:28:13 +0800
Subject: [PATCH 0/4] ARM: Support KFENCE feature
In-Reply-To: <YSYiEgEcW1Ln3+9P@elver.google.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <CANpmjNMnU5P9xsDhgeBKQR7Tg-3cHPkMNx7906yYwEAj85sNWg@mail.gmail.com>
 <YSYiEgEcW1Ln3+9P@elver.google.com>
Message-ID: <7d08a5d8-7637-d109-cbfc-56e6449ae083@huawei.com>


On 2021/8/25 18:57, Marco Elver wrote:
> I spoke too soon -- we export __kfence_pool, and that's good enough to
> fail the test fast if KFENCE was disabled at boot:
>
> 	https://lkml.kernel.org/r/20210825105533.1247922-1-elver at google.com

I haven't received the mail, don't know why.

Whatever,? I tested it, this patch is good and it save a lot of times,? 
so feel free

to add my tested-by, thanks.


>
> will do the trick. So please drop your patch 4/4 here.
>
> Thanks,
> -- Marco
> .
>


From wangkefeng.wang at huawei.com  Wed Aug 25 07:31:45 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 22:31:45 +0800
Subject: [PATCH 3/4] ARM: Support KFENCE for ARM
In-Reply-To: <51b02ecd-0f3d-99b0-c943-1d4da26174d0@gmail.com>
References: <20210825092116.149975-1-wangkefeng.wang@huawei.com>
 <20210825092116.149975-4-wangkefeng.wang@huawei.com>
 <51b02ecd-0f3d-99b0-c943-1d4da26174d0@gmail.com>
Message-ID: <8531455d-3198-96cd-e26b-03156f95ac80@huawei.com>


On 2021/8/25 21:18, ownia wrote:
> On 2021/8/25 17:21, Kefeng Wang wrote:
>> Add architecture specific implementation details for KFENCE and enable
>> KFENCE on ARM. In particular, this implements the required interface in
>>   <asm/kfence.h>.
>>
>> KFENCE requires that attributes for pages from its memory pool can
>> individually be set. Therefore, force the kfence pool to be mapped
>> at page granularity.
>>
>> Testing this patch using the testcases in kfence_test.c and all passed
>> with or without ARM_LPAE.
>>
>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
...
>> +#endif /* __ASM_ARM_KFENCE_H */
>> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
>> index f7ab6dabe89f..9fa221ffa1b9 100644
>> --- a/arch/arm/mm/fault.c
>> +++ b/arch/arm/mm/fault.c
>> @@ -17,6 +17,7 @@
>>   #include <linux/sched/debug.h>
>>   #include <linux/highmem.h>
>>   #include <linux/perf_event.h>
>> +#include <linux/kfence.h>
>>   
>>   #include <asm/system_misc.h>
>>   #include <asm/system_info.h>
>> @@ -131,10 +132,14 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
>>   	/*
>>   	 * No handler, we'll have to terminate things with extreme prejudice.
>>   	 */
>> -	if (addr < PAGE_SIZE)
>> +	if (addr < PAGE_SIZE) {
>>   		msg = "NULL pointer dereference";
>> -	else
>> +	} else {
>> +		if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
>> +			return;
>> +
>>   		msg = "paging request";
>> +	}
>
> I think here should do some fixup to follow upstream mainline code.

Yes, the fixup is still there, as the cover-letter said,

NOTE:
The context of patch2/3 changes in arch/arm/mm/fault.c is based on link[1],
which make some refactor and cleanup about page fault.

...

[1]https://lore.kernel.org/linux-arm-kernel/20210610123556.171328-1-wangkefeng.wang at huawei.com/

>
>>   
>>   	die_kernel_fault(msg, mm, addr, fsr, regs);
>>   }
> .
>


From yann.gautier at foss.st.com  Wed Aug 25 07:34:10 2021
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 25 Aug 2021 16:34:10 +0200
Subject: Question about MMC_PM_KEEP_POWER in MMCI driver
Message-ID: <ccb2dad1-c8c1-9f19-92c4-7faf2b787e6d@foss.st.com>

Hi,

In drivers/mmc/host/mmci.c, MMC_PM_KEEP_POWER is unconditionally enabled.
This prevents correct low-power sequence on STM32MP157C-DK2 board which 
embeds a Wifi chip brcm,bcm4329-fmac (this wifi part has not yet been 
sent upstream).

This MMC_PM_KEEP_POWER can be taken from DT with the property 
keep-power-in-suspend. This is what is done for other MMC drivers.

I wonder what should be the best solution for this.

1) Remove MMC_PM_KEEP_POWER from the driver, and modify all SoC device 
tree files embedding a arm,pl18x with adding keep-power-in-suspend; 
property (except stm32mp151.dtsi file).
This can be easy to do (~10 files to modify). But that could be more 
board dependent, if an SDIO chip is plugged on this MMC IP.
And the name keep-power-in-suspend can be misleading as it only applies 
to SDIO.

2) Remove MMC_PM_KEEP_POWER from the driver, and modify board DT files 
with the property. This could be a difficult task to find all those 
boards. And this should be applied only for SDIO configs.

3) Just modify the driver to apply this capability for all MMCI chips 
but STM32. This could be done in the dedicated file, in 
sdmmc_variant_init() function. But some boards based on STM32MP15 chip 
might want to keep this capability.

All advice is welcome.


Thanks,
Yann


From wangkefeng.wang at huawei.com  Wed Aug 25 07:41:15 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 25 Aug 2021 22:41:15 +0800
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <CAL_Jsq+0rq6u5d7itETOnQWx_V+J3aP1m1Zgehi5QKVoKvdbvQ@mail.gmail.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
 <CAL_Jsq+0rq6u5d7itETOnQWx_V+J3aP1m1Zgehi5QKVoKvdbvQ@mail.gmail.com>
Message-ID: <d7a1d3a8-bda4-7a29-b66d-22ed4926f9c8@huawei.com>


On 2021/8/25 20:33, Rob Herring wrote:
> On Tue, Aug 24, 2021 at 11:05 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:

...

>>> Similar to other resources the AMBA bus "gets" for the device, I think
>>> this should be moved into amba_probe() and not here. There's no reason
>>> to delay the addition of the device (and loading its module) because
>>> the IRQ isn't ready yet.
>> The following code in the amba_device_try_add() will be called, it uses irq[0]
>> and irq[1], so I put of_amba_device_decode_irq() into amba_device_try_add().
>>
>> 470         if (dev->irq[0])
>> 471                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
>> 472         if (ret == 0 && dev->irq[1])
>> 473                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
>> 474         if (ret == 0)
>> 475                 return ret;
> I wonder if we could just remove these. Why does userspace need them
> in the first place? It's only an ABI if someone notices. Looking at
> the history, AMBA bus was added in 2003 with just 'irq' and then
> changed (ABI break) in 2004 to 'irq0' and 'irq1'.
>
> Rob

Ok, I will kill all irq parts,

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 962041148482..c08e8b30e02c 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -20,8 +20,6 @@
 ?#include <linux/platform_device.h>
 ?#include <linux/reset.h>

-#include <asm/irq.h>
-
 ?#define to_amba_driver(d)????? container_of(d, struct amba_driver, drv)

 ?/* called on periphid match and class 0x9 coresight device. */
@@ -135,8 +133,6 @@ static ssize_t name##_show(struct device 
*_dev,???????????????????????????? \
 ?static DEVICE_ATTR_RO(name)

 ?amba_attr_func(id, "%08x\n", dev->periphid);
-amba_attr_func(irq0, "%u\n", dev->irq[0]);
-amba_attr_func(irq1, "%u\n", dev->irq[1]);
 ?amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
 ???????? (unsigned long long)dev->res.start, (unsigned long 
long)dev->res.end,
 ???????? dev->res.flags);
@@ -467,10 +463,6 @@ static int amba_device_try_add(struct amba_device 
*dev, struct resource *parent)
 ??????? if (ret)
 ??????????????? goto err_release;

-?????? if (dev->irq[0])
-?????????????? ret = device_create_file(&dev->dev, &dev_attr_irq0);
-?????? if (ret == 0 && dev->irq[1])
-?????????????? ret = device_create_file(&dev->dev, &dev_attr_irq1);

and do some cleanup about error handling in the next version.

>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/log/arch/arm/common/amba.c
> .
>


From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:20 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:20 +0800
Subject: [PATCH v9 01/14] dt-bindings: arm: mediatek: mmsys: add power and gce
 properties
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-2-jason-jh.lin@mediatek.com>

Power:
1. Add description for power-domains property.

GCE:
1. Add description for mboxes property.
2. Add description for mediatek,gce-client-reg property.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,mmsys.yaml | 28 ++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 2d4ff0ce387b..784207824ce0 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -39,6 +39,28 @@ properties:
   reg:
     maxItems: 1
 
+  power-domains:
+    description:
+      A phandle and PM domain specifier as defined by bindings
+      of the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  mboxes:
+    description:
+      Using mailbox to communicate with GCE, it should have this
+      property and list of phandle, mailbox specifiers. See
+      Documentation/devicetree/bindings/mailbox/mtk-gce.txt for details.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
   "#clock-cells":
     const: 1
 
@@ -53,6 +75,10 @@ examples:
   - |
     mmsys: syscon at 14000000 {
         compatible = "mediatek,mt8173-mmsys", "syscon";
-        reg = <0x14000000 0x1000>;
+        reg = <0 0x14000000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
         #clock-cells = <1>;
+        mboxes = <&gce 0 CMDQ_THR_PRIO_HIGHEST>,
+                 <&gce 1 CMDQ_THR_PRIO_HIGHEST>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
     };
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:22 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:22 +0800
Subject: [PATCH v9 03/14] dt-bindings: mediatek: display: split each block to
 individual yaml
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-4-jason-jh.lin@mediatek.com>

1. Remove mediatek,dislpay.txt
2. Split each display function block to individual yaml file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,aal.yaml        |  75 ++++++
 .../display/mediatek/mediatek,ccorr.yaml      |  69 ++++++
 .../display/mediatek/mediatek,color.yaml      |  84 +++++++
 .../display/mediatek/mediatek,disp.txt        | 219 ------------------
 .../display/mediatek/mediatek,dither.yaml     |  70 ++++++
 .../display/mediatek/mediatek,gamma.yaml      |  71 ++++++
 .../display/mediatek/mediatek,merge.yaml      |  66 ++++++
 .../display/mediatek/mediatek,mutex.yaml      |  77 ++++++
 .../display/mediatek/mediatek,od.yaml         |  52 +++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  86 +++++++
 .../display/mediatek/mediatek,ovl.yaml        |  96 ++++++++
 .../display/mediatek/mediatek,rdma.yaml       | 110 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  56 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  59 +++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
 15 files changed, 1057 insertions(+), 219 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
new file mode 100644
index 000000000000..faa764c12dfc
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display adaptive ambient light processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display adaptive ambient light processor, namely AAL,
+  is responsible for backlight power saving and sunlight visibility improving.
+  AAL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-aal
+      - items:
+          - enum:
+              - mediatek,mt2712-disp-aal
+              - mediatek,mt8183-disp-aal
+          - enum:
+              - mediatek,mt8173-disp-aal
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: AAL Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    aal at 14015000 {
+        compatible = "mediatek,mt8173-disp-aal";
+        reg = <0 0x14015000 0 0x1000>;
+        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_AAL>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..e848879d755c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek Ddsplay color correction
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display color correction, namely CCORR, reproduces correct color
+  on panels with different color gamut.
+  CCORR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ccorr
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: CCORR Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ccorr0: ccorr at 1400f000 {
+        compatible = "mediatek,mt8183-disp-ccorr";
+        reg = <0 0x1400f000 0 0x1000>;
+        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
new file mode 100644
index 000000000000..019fc09bbddd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display color processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek color processor, namely COLOR, provides hue, luma and
+  saturation adjustments to get better picture quality and to have one panel
+  resemble the other in their output characteristics.
+  COLOR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-color
+      - items:
+          - const: mediatek,mt8167-disp-color
+      - items:
+          - const: mediatek,mt8173-disp-color
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-color
+              - mediatek,mt2712-disp-color
+          - enum:
+              - mediatek,mt2701-disp-color
+      - items:
+          - enum:
+              - mediatek,mt8183-disp-color
+          - enum:
+              - mediatek,mt8173-disp-color
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: COLOR Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    color0: color at 14013000 {
+        compatible = "mediatek,mt8173-disp-color";
+        reg = <0 0x14013000 0 0x1000>;
+        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
deleted file mode 100644
index fbb59c9ddda6..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ /dev/null
@@ -1,219 +0,0 @@
-Mediatek display subsystem
-==========================
-
-The Mediatek display subsystem consists of various DISP function blocks in the
-MMSYS register space. The connections between them can be configured by output
-and input selectors in the MMSYS_CONFIG register space. Pixel clock and start
-of frame signal are distributed to the other function blocks by a DISP_MUTEX
-function block.
-
-All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
-For a description of the MMSYS_CONFIG binding, see
-Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt.
-
-DISP function blocks
-====================
-
-A display stream starts at a source function block that reads pixel data from
-memory and ends with a sink function block that drives pixels on a display
-interface, or writes pixels back to memory. All DISP function blocks have
-their own register space, interrupt, and clock gate. The blocks that can
-access memory additionally have to list the IOMMU and local arbiter they are
-connected to.
-
-For a description of the display interface sink function blocks, see
-Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
-Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
-
-Required properties (all function blocks):
-- compatible: "mediatek,<chip>-disp-<function>", one of
-	"mediatek,<chip>-disp-ovl"   		- overlay (4 layers, blending, csc)
-	"mediatek,<chip>-disp-ovl-2l"           - overlay (2 layers, blending, csc)
-	"mediatek,<chip>-disp-rdma"  		- read DMA / line buffer
-	"mediatek,<chip>-disp-wdma"  		- write DMA
-	"mediatek,<chip>-disp-ccorr"            - color correction
-	"mediatek,<chip>-disp-color" 		- color processor
-	"mediatek,<chip>-disp-dither"           - dither
-	"mediatek,<chip>-disp-aal"   		- adaptive ambient light controller
-	"mediatek,<chip>-disp-gamma" 		- gamma correction
-	"mediatek,<chip>-disp-merge" 		- merge streams from two RDMA sources
-	"mediatek,<chip>-disp-postmask" 	- control round corner for display frame
-	"mediatek,<chip>-disp-split" 		- split stream to two encoders
-	"mediatek,<chip>-disp-ufoe"  		- data compression engine
-	"mediatek,<chip>-dsi"        		- DSI controller, see mediatek,dsi.txt
-	"mediatek,<chip>-dpi"        		- DPI controller, see mediatek,dpi.txt
-	"mediatek,<chip>-disp-mutex" 		- display mutex
-	"mediatek,<chip>-disp-od"    		- overdrive
-  the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
-- reg: Physical base address and length of the function block register space
-- interrupts: The interrupt signal from the function block (required, except for
-  merge and split function blocks).
-- clocks: device clocks
-  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-  For most function blocks this is just a single clock input. Only the DSI and
-  DPI controller nodes have multiple clock inputs. These are documented in
-  mediatek,dsi.txt and mediatek,dpi.txt, respectively.
-  An exception is that the mt8183 mutex is always free running with no clocks property.
-
-Required properties (DMA function blocks):
-- compatible: Should be one of
-	"mediatek,<chip>-disp-ovl"
-	"mediatek,<chip>-disp-rdma"
-	"mediatek,<chip>-disp-wdma"
-  the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-- iommus: Should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-
-Optional properties (RDMA function blocks):
-- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
-  property to the corresponding rdma
-  the value is the Max value which defined in hardware data sheet.
-  mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
-  mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
-  mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
-
-Examples:
-
-mmsys: clock-controller at 14000000 {
-	compatible = "mediatek,mt8173-mmsys", "syscon";
-	reg = <0 0x14000000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	#clock-cells = <1>;
-};
-
-ovl0: ovl at 1400c000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400c000 0 0x1000>;
-	interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL0>;
-	iommus = <&iommu M4U_PORT_DISP_OVL0>;
-	mediatek,larb = <&larb0>;
-};
-
-ovl1: ovl at 1400d000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400d000 0 0x1000>;
-	interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL1>;
-	iommus = <&iommu M4U_PORT_DISP_OVL1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma0: rdma at 1400e000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400e000 0 0x1000>;
-	interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-	mediatek,larb = <&larb0>;
-	mediatek,rdma-fifosize = <8192>;
-};
-
-rdma1: rdma at 1400f000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400f000 0 0x1000>;
-	interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma2: rdma at 14010000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x14010000 0 0x1000>;
-	interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA2>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA2>;
-	mediatek,larb = <&larb4>;
-};
-
-wdma0: wdma at 14011000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14011000 0 0x1000>;
-	interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-	mediatek,larb = <&larb0>;
-};
-
-wdma1: wdma at 14012000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14012000 0 0x1000>;
-	interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-color0: color at 14013000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14013000 0 0x1000>;
-	interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR0>;
-};
-
-color1: color at 14014000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14014000 0 0x1000>;
-	interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR1>;
-};
-
-aal at 14015000 {
-	compatible = "mediatek,mt8173-disp-aal";
-	reg = <0 0x14015000 0 0x1000>;
-	interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_AAL>;
-};
-
-gamma at 14016000 {
-	compatible = "mediatek,mt8173-disp-gamma";
-	reg = <0 0x14016000 0 0x1000>;
-	interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_GAMMA>;
-};
-
-ufoe at 1401a000 {
-	compatible = "mediatek,mt8173-disp-ufoe";
-	reg = <0 0x1401a000 0 0x1000>;
-	interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_UFOE>;
-};
-
-dsi0: dsi at 1401b000 {
-	/* See mediatek,dsi.txt for details */
-};
-
-dpi0: dpi at 1401d000 {
-	/* See mediatek,dpi.txt for details */
-};
-
-mutex: mutex at 14020000 {
-	compatible = "mediatek,mt8173-disp-mutex";
-	reg = <0 0x14020000 0 0x1000>;
-	interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_MUTEX_32K>;
-};
-
-od at 14023000 {
-	compatible = "mediatek,mt8173-disp-od";
-	reg = <0 0x14023000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OD>;
-};
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
new file mode 100644
index 000000000000..8e7c87c39f9c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display dither processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display dither processor, namely DITHER, works by approximating
+  unavailable colors with available colors and by mixing and matching available
+  colors to mimic unavailable ones.
+  DITHER device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-dither
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: DITHER Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dither0: dither at 14012000 {
+        compatible = "mediatek,mt8183-disp-dither";
+        reg = <0 0x14012000 0 0x1000>;
+        interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_DITHER0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
new file mode 100644
index 000000000000..8fa1b373a8da
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,gamma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display gamma correction
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display gamma correction, namely GAMMA, provides a nonlinear operation
+  used to adjust luminance in??display system.
+  GAMMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-gamma
+      - items:
+          - const: mediatek,mt8183-disp-gamma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: GAMMA Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    gamma at 14016000 {
+        compatible = "mediatek,mt8173-disp-gamma";
+        reg = <0 0x14016000 0 0x1000>;
+        interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
new file mode 100644
index 000000000000..ca51a4c4a8c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,merge.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display merge
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display merge engine is used to merge two slice-per-line inputs
+  into one side-by-side output.
+  MERGE device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-merge
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MERGE Clock
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    merge at 14017000 {
+        compatible = "mediatek,mt8173-disp-merge";
+        reg = <0 0x14017000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_MERGE>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
new file mode 100644
index 000000000000..939dff14d989
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display mutex
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display mutex is used to send the triggers signals called
+  Start Of Frame (SOF)/ Error Of Frame (EOF) to each sub-modules on the
+  display data path.
+  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-mutex
+      - items:
+          - const: mediatek,mt2712-disp-mutex
+      - items:
+          - const: mediatek,mt8167-disp-mutex
+      - items:
+          - const: mediatek,mt8173-disp-mutex
+      - items:
+          - const: mediatek,mt8183-disp-mutex
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MUTEX Clock
+
+  mediatek,gce-events:
+    description:
+      The event id which is mapping to the specific hardware event signal to gce.
+      The event id is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    mutex: mutex at 14020000 {
+        compatible = "mediatek,mt8173-disp-mutex";
+        reg = <0 0x14020000 0 0x1000>;
+        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_MUTEX_32K>;
+        mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+                              <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
new file mode 100644
index 000000000000..d2e957cf1c61
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,od.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overdirve
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display overdrive, namely OD, increases the transition values
+  of pixels between consecutive frames to make LCD rotate faster.
+  OD device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2712-disp-od
+      - items:
+          - const: mediatek,mt8173-disp-od
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    od at 14023000 {
+        compatible = "mediatek,mt8173-disp-od";
+        reg = <0 0x14023000 0 0x1000>;
+        clocks = <&mmsys CLK_MM_DISP_OD>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
new file mode 100644
index 000000000000..60eb29c79b84
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl-2l.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overlay 2 layer
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display overlay provides 2 more layer for OVL.
+  OVL-2L device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ovl-2l
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL-2L Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl_2l0: ovl at 14009000 {
+        compatible = "mediatek,mt8183-disp-ovl-2l";
+        reg = <0 0x14009000 0 0x1000>;
+        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
+        iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
new file mode 100644
index 000000000000..a0c29cd3377a
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display overlay
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display overlay, namely OVL, can do alpha blending from the memory.
+  OVL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-ovl
+      - items:
+          - const: mediatek,mt8173-disp-ovl
+      - items:
+          - const: mediatek,mt8183-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-ovl
+              - mediatek,mt2712-disp-ovl
+          - enum:
+              - mediatek,mt2701-disp-ovl
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommu
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl0: ovl at 1400c000 {
+        compatible = "mediatek,mt8173-disp-ovl";
+        reg = <0 0x1400c000 0 0x1000>;
+        interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0>;
+        iommus = <&iommu M4U_PORT_DISP_OVL0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
new file mode 100644
index 000000000000..837659ab4ebd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display RDMA
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-rdma
+      - items:
+          - const: mediatek,mt8173-disp-rdma
+      - items:
+          - const: mediatek,mt8183-disp-rdma
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-rdma
+              - mediatek,mt2712-disp-rdma
+          - enum:
+              - mediatek,mt2701-disp-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,rdma-fifo-size:
+    description:
+      rdma fifo size may be different even in same SOC, add this property to the
+      corresponding rdma.
+      The value below is the Max value which defined in hardware data sheet
+      mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
+      mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
+      mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8192, 5120, 2048]
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    rdma0: rdma at 1400e000 {
+        compatible = "mediatek,mt8173-disp-rdma";
+        reg = <0 0x1400e000 0 0x1000>;
+        interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_RDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_RDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,rdma-fifosize = <8192>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
new file mode 100644
index 000000000000..0ab3eaa6d6d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,split.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display split
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display split engine is used to split stream to two encoders.
+  SPLIT device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-split
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: SPLIT Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    split0: split at 14018000 {
+        compatible = "mediatek,mt8173-disp-split";
+        reg = <0 0x14018000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
new file mode 100644
index 000000000000..c50477abfff2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ufoe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display UFOe
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The Mediatek display UFOe stands for Unified Frame Optimization engine.
+  UFOe can cut the data rate for DSI port which may lead to reduce power consumption.
+  UFOe device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-ufoe
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: UFOe Clock
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ufoe at 1401a000 {
+        compatible = "mediatek,mt8173-disp-ufoe";
+        reg = <0 0x1401a000 0 0x1000>;
+        interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_UFOE>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..ecf9549e0e07
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display WDMA
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The mediatek display WDMA stands for Write Direct Memory Access.
+  It can write the data in display pipeline into DRAM.
+  WDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-wdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: WDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter deviceas defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    wdma0: wdma at 14011000 {
+        compatible = "mediatek,mt8173-disp-wdma";
+        reg = <0 0x14011000 0 0x1000>;
+        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+    };
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:21 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:21 +0800
Subject: [PATCH v9 02/14] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC
 binding
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-3-jason-jh.lin@mediatek.com>

There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195.
Each of them is bound to a display pipeline, so add their
definition in mtk-mmsys documentation with 2 compatibles.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
this patch is base on [1][2]

[1] dt-bindings: arm: mediatek: mmsys: convert to YAML format
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-1-fparent at baylibre.com/
[2] dt-bindings: arm: mediatek: mmsys: add MT8365 SoC binding
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-2-fparent at baylibre.com/
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml        | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 784207824ce0..9eae76a2c5f6 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -30,6 +30,8 @@ properties:
               - mediatek,mt8173-mmsys
               - mediatek,mt8183-mmsys
               - mediatek,mt8365-mmsys
+              - mediatek,mt8195-vdosys0
+              - mediatek,mt8195-vdosys1
           - const: syscon
       - items:
           - const: mediatek,mt7623-mmsys
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:28 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:28 +0800
Subject: [PATCH v9 09/14] drm/mediatek: remove unused define in
 mtk_drm_ddp_comp.c
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-10-jason-jh.lin@mediatek.com>

Remove the unsed define in mtk_drm_ddp_comp.c

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
rebase on [1] series
[1] drm/mediatek: Separate aal module
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 99cbf44463e4..484080a0defa 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -21,8 +21,6 @@
 #include "mtk_drm_crtc.h"
 
 #define DISP_OD_EN				0x0000
-#define DISP_OD_INTEN				0x0008
-#define DISP_OD_INTSTA				0x000c
 #define DISP_OD_CFG				0x0020
 #define DISP_OD_SIZE				0x0030
 #define DISP_DITHER_5				0x0114
@@ -39,26 +37,18 @@
 #define DITHER_ENGINE_EN			BIT(1)
 #define DISP_DITHER_SIZE			0x0030
 
-#define LUT_10BIT_MASK				0x03ff
-
 #define OD_RELAYMODE				BIT(0)
 
 #define UFO_BYPASS				BIT(2)
 
 #define DISP_DITHERING				BIT(2)
 #define DITHER_LSB_ERR_SHIFT_R(x)		(((x) & 0x7) << 28)
-#define DITHER_OVFLW_BIT_R(x)			(((x) & 0x7) << 24)
 #define DITHER_ADD_LSHIFT_R(x)			(((x) & 0x7) << 20)
-#define DITHER_ADD_RSHIFT_R(x)			(((x) & 0x7) << 16)
 #define DITHER_NEW_BIT_MODE			BIT(0)
 #define DITHER_LSB_ERR_SHIFT_B(x)		(((x) & 0x7) << 28)
-#define DITHER_OVFLW_BIT_B(x)			(((x) & 0x7) << 24)
 #define DITHER_ADD_LSHIFT_B(x)			(((x) & 0x7) << 20)
-#define DITHER_ADD_RSHIFT_B(x)			(((x) & 0x7) << 16)
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
-#define DITHER_OVFLW_BIT_G(x)			(((x) & 0x7) << 8)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
-#define DITHER_ADD_RSHIFT_G(x)			(((x) & 0x7) << 0)
 
 struct mtk_ddp_comp_dev {
 	struct clk *clk;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:23 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:23 +0800
Subject: [PATCH v9 04/14] dt-bindings: mediatek: add mediatek,
 dsc.yaml for mt8195 SoC binding
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-5-jason-jh.lin@mediatek.com>

1. Add mediatek,dsc.yaml to describe DSC module in details.
2. Add mt8195 SoC binding to mediatek,dsc.yaml.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,dsc.yaml        | 70 +++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
new file mode 100644
index 000000000000..f26e3010d5f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display DSC controller
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The DSC standard is a specification of the algorithms used for
+  compressing and decompressing image display streams, including
+  the specification of the syntax and semantics of the compressed
+  video bit stream. DSC is designed for real-time systems with
+  real-time compression, transmission, decompression and Display.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-disp-dsc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: DSC Wrapper Clock
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments defined
+      in this property, such as phandle of gce, subsys id, register offset and size.
+      Each subsys id is mapping to a base address of display function blocks register
+      which is defined in the gce header include/include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dsc0: disp_dsc_wrap at 1c009000 {
+        compatible = "mediatek,mt8195-disp-dsc";
+        reg = <0 0x1c009000 0 0x1000>;
+        interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+        clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+    };
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:25 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:25 +0800
Subject: [PATCH v9 06/14] arm64: dts: mt8195: add display node for vdosys0
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-7-jason-jh.lin@mediatek.com>

Add display node for vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is based on [1][2][3]

[1]arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
[2]arm64: dts: mt8195: add IOMMU and smi nodes
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
[3]arm64: dts: mt8195: add gce node
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210705053429.4380-4-jason-jh.lin at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 110 +++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 47c44cb77da0..4064a92e28a5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1153,9 +1153,119 @@
 			#clock-cells = <1>;
 		};
 
+		ovl0: disp_ovl at 1c000000 {
+			compatible = "mediatek,mt8195-disp-ovl",
+				     "mediatek,mt8183-disp-ovl";
+			reg = <0 0x1c000000 0 0x1000>;
+			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_OVL0_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x0000 0x1000>;
+		};
+
+		rdma0: disp_rdma at 1c002000 {
+			compatible = "mediatek,mt8195-disp-rdma";
+			reg = <0 0x1c002000 0 0x1000>;
+			interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_RDMA0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x2000 0x1000>;
+		};
+
+		color0: disp_color at 1c003000 {
+			compatible = "mediatek,mt8195-disp-color",
+				     "mediatek,mt8173-disp-color";
+			reg = <0 0x1c003000 0 0x1000>;
+			interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_COLOR0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x3000 0x1000>;
+		};
+
+		ccorr0: disp_ccorr at 1c004000 {
+			compatible = "mediatek,mt8195-disp-ccorr";
+			reg = <0 0x1c004000 0 0x1000>;
+			interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_CCORR0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x4000 0x1000>;
+		};
+
+		aal0: disp_aal at 1c005000 {
+			compatible = "mediatek,mt8195-disp-aal",
+				     "mediatek,mt8173-disp-aal";
+			reg = <0 0x1c005000 0 0x1000>;
+			interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_AAL0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x5000 0x1000>;
+		};
+
+		gamma0: disp_gamma at 1c006000 {
+			compatible = "mediatek,mt8195-disp-gamma",
+				     "mediatek,mt8173-disp-gamma";
+			reg = <0 0x1c006000 0 0x1000>;
+			interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_GAMMA0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x6000 0x1000>;
+		};
+
+		dither0: disp_dither at 1c007000 {
+			compatible = "mediatek,mt8195-disp-dither",
+				     "mediatek,mt8183-disp-dither";
+			reg = <0 0x1c007000 0 0x1000>;
+			interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_DITHER0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x7000 0x1000>;
+		};
+
+		dsc0: disp_dsc_wrap at 1c009000 {
+			compatible = "mediatek,mt8195-disp-dsc";
+			reg = <0 0x1c009000 0 0x1000>;
+			interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+		};
+
+		merge0: disp_vpp_merge0 at 1c014000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c014000 0 0x1000>;
+			interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_VPP_MERGE0>;
+			mediatek,gce-client-reg =
+				 <&gce1 SUBSYS_1c01XXXX 0x4000 0x1000>;
+		};
+
+		mutex: disp_mutex0 at 1c016000 {
+			compatible = "mediatek,mt8195-disp-mutex";
+			reg = <0 0x1c016000 0 0x1000>;
+			reg-names = "vdo0_mutex";
+			interrupts = <GIC_SPI 658 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_MUTEX0>;
+			clock-names = "vdo0_mutex";
+			mediatek,gce-events =
+				 <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;
+		};
+
 		vdosys0: syscon at 1c01a000 {
 			compatible = "mediatek,mt8195-vdosys0", "syscon";
 			reg = <0 0x1c01a000 0 0x1000>;
+			mboxes = <&gce1 0 CMDQ_THR_PRIO_4>;
 			#clock-cells = <1>;
 		};
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:29 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:29 +0800
Subject: [PATCH v9 10/14] drm/mediatek: rename the define of register offset
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-11-jason-jh.lin@mediatek.com>

Add DISP_REG prefix for the define of register offset to
make the difference from the define of register value.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
rebase on [1] series
[1] drm/mediatek: Separate aal module
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 47 +++++++++++----------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 484080a0defa..0b5ca9025b3a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -20,22 +20,22 @@
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_crtc.h"
 
-#define DISP_OD_EN				0x0000
-#define DISP_OD_CFG				0x0020
-#define DISP_OD_SIZE				0x0030
-#define DISP_DITHER_5				0x0114
-#define DISP_DITHER_7				0x011c
-#define DISP_DITHER_15				0x013c
-#define DISP_DITHER_16				0x0140
+#define DISP_REG_OD_EN				0x0000
+#define DISP_REG_OD_CFG				0x0020
+#define DISP_REG_OD_SIZE			0x0030
+#define DISP_REG_DITHER_5			0x0114
+#define DISP_REG_DITHER_7			0x011c
+#define DISP_REG_DITHER_15			0x013c
+#define DISP_REG_DITHER_16			0x0140
 
 #define DISP_REG_UFO_START			0x0000
 
-#define DISP_DITHER_EN				0x0000
+#define DISP_REG_DITHER_EN			0x0000
 #define DITHER_EN				BIT(0)
-#define DISP_DITHER_CFG				0x0020
+#define DISP_REG_DITHER_CFG			0x0020
 #define DITHER_RELAY_MODE			BIT(0)
 #define DITHER_ENGINE_EN			BIT(1)
-#define DISP_DITHER_SIZE			0x0030
+#define DISP_REG_DITHER_SIZE			0x0030
 
 #define OD_RELAYMODE				BIT(0)
 
@@ -124,19 +124,19 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 		return;
 
 	if (bpc >= MTK_MIN_BPC) {
-		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_5);
-		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_DITHER_7);
+		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_5);
+		mtk_ddp_write(cmdq_pkt, 0, cmdq_reg, regs, DISP_REG_DITHER_7);
 		mtk_ddp_write(cmdq_pkt,
 			      DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
 			      DITHER_NEW_BIT_MODE,
-			      cmdq_reg, regs, DISP_DITHER_15);
+			      cmdq_reg, regs, DISP_REG_DITHER_15);
 		mtk_ddp_write(cmdq_pkt,
 			      DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
 			      DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
 			      DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
-			      cmdq_reg, regs, DISP_DITHER_16);
+			      cmdq_reg, regs, DISP_REG_DITHER_16);
 		mtk_ddp_write(cmdq_pkt, dither_en, cmdq_reg, regs, cfg);
 	}
 }
@@ -156,16 +156,16 @@ static void mtk_od_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_OD_SIZE);
-	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_OD_CFG);
-	mtk_dither_set(dev, bpc, DISP_OD_CFG, cmdq_pkt);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
+	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
+	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
 }
 
 static void mtk_od_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(1, priv->regs + DISP_OD_EN);
+	writel(1, priv->regs + DISP_REG_OD_EN);
 }
 
 static void mtk_ufoe_start(struct device *dev)
@@ -181,9 +181,10 @@ static void mtk_dither_config(struct device *dev, unsigned int w,
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_DITHER_SIZE);
-	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs, DISP_DITHER_CFG);
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_DITHER_CFG,
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE);
+	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_DITHER_CFG);
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
 			      DITHER_ENGINE_EN, cmdq_pkt);
 }
 
@@ -191,14 +192,14 @@ static void mtk_dither_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(DITHER_EN, priv->regs + DISP_DITHER_EN);
+	writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
 }
 
 static void mtk_dither_stop(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, priv->regs + DISP_DITHER_EN);
+	writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
 }
 
 static const struct mtk_ddp_comp_funcs ddp_aal = {
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:27 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:27 +0800
Subject: [PATCH v9 08/14] soc: mediatek: add mtk-mutex support for mt8195
 vdosys0
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-9-jason-jh.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 98 +++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2e4bcc300576..c177156ee2fa 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -17,6 +17,9 @@
 #define MT8183_MUTEX0_MOD0			0x30
 #define MT8183_MUTEX0_SOF0			0x2c
 
+#define MT8195_DISP_MUTEX0_MOD0			0x30
+#define MT8195_DISP_MUTEX0_SOF			0x2c
+
 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
@@ -67,6 +70,36 @@
 #define MT8173_MUTEX_MOD_DISP_PWM1		24
 #define MT8173_MUTEX_MOD_DISP_OD		25
 
+#define MT8195_MUTEX_MOD_DISP_OVL0		0
+#define MT8195_MUTEX_MOD_DISP_WDMA0		1
+#define MT8195_MUTEX_MOD_DISP_RDMA0		2
+#define MT8195_MUTEX_MOD_DISP_COLOR0		3
+#define MT8195_MUTEX_MOD_DISP_CCORR0		4
+#define MT8195_MUTEX_MOD_DISP_AAL0		5
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
+#define MT8195_MUTEX_MOD_DISP_DITHER0		7
+#define MT8195_MUTEX_MOD_DISP_DSI0		8
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
+#define MT8195_MUTEX_MOD_DISP_OVL1		10
+#define MT8195_MUTEX_MOD_DISP_WDMA1		11
+#define MT8195_MUTEX_MOD_DISP_RDMA1		12
+#define MT8195_MUTEX_MOD_DISP_COLOR1		13
+#define MT8195_MUTEX_MOD_DISP_CCORR1		14
+#define MT8195_MUTEX_MOD_DISP_AAL1		15
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
+#define MT8195_MUTEX_MOD_DISP_DITHER1		17
+#define MT8195_MUTEX_MOD_DISP_DSI1		18
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
+#define MT8195_MUTEX_MOD_DISP_PWM0		27
+#define MT8195_MUTEX_MOD_DISP_PWM1		28
+
 #define MT2712_MUTEX_MOD_DISP_PWM2		10
 #define MT2712_MUTEX_MOD_DISP_OVL0		11
 #define MT2712_MUTEX_MOD_DISP_OVL1		12
@@ -101,12 +134,27 @@
 #define MT2712_MUTEX_SOF_DSI3			6
 #define MT8167_MUTEX_SOF_DPI0			2
 #define MT8167_MUTEX_SOF_DPI1			3
+
 #define MT8183_MUTEX_SOF_DSI0			1
 #define MT8183_MUTEX_SOF_DPI0			2
 
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
 
+#define MT8195_MUTEX_SOF_DSI0			1
+#define MT8195_MUTEX_SOF_DSI1			2
+#define MT8195_MUTEX_SOF_DP_INTF0		3
+#define MT8195_MUTEX_SOF_DP_INTF1		4
+#define MT8195_MUTEX_SOF_DPI0			6 /* for HDMI_TX */
+#define MT8195_MUTEX_SOF_DPI1			5 /* for digital video out */
+
+#define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_SOF_DSI0 << 7)
+#define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_SOF_DSI1 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_INTF0 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_INTF1 << 7)
+#define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_SOF_DPI0 << 7)
+#define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_SOF_DPI1 << 7)
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -120,6 +168,9 @@ enum mtk_mutex_sof_id {
 	MUTEX_SOF_DPI1,
 	MUTEX_SOF_DSI2,
 	MUTEX_SOF_DSI3,
+	MUTEX_SOF_DP_INTF0,
+	MUTEX_SOF_DP_INTF1,
+	DDP_MUTEX_SOF_MAX,
 };
 
 struct mtk_mutex_data {
@@ -214,7 +265,23 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
+	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
+	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
+	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
+	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
+	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
+	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
+	[DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
+	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
+	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
+	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
+	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
+	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
+};
+
+static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
@@ -224,7 +291,7 @@ static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
 };
 
-static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
@@ -232,12 +299,24 @@ static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 };
 
 /* Add EOF setting so overlay hardware can receive frame done irq */
-static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
 };
 
+static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
+	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
+	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
+	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
+	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
+	[MUTEX_SOF_DP_INTF0] =
+		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
+	[MUTEX_SOF_DP_INTF1] =
+		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -275,6 +354,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.no_clk = true,
 };
 
+static const struct mtk_mutex_data mt8195_mutex_driver_data = {
+	.mutex_mod = mt8195_mutex_mod,
+	.mutex_sof = mt8195_mutex_sof,
+	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
+};
+
 struct mtk_mutex *mtk_mutex_get(struct device *dev)
 {
 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
@@ -347,6 +433,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DPI1:
 		sof_id = MUTEX_SOF_DPI1;
 		break;
+	case DDP_COMPONENT_DP_INTF0:
+		sof_id = MUTEX_SOF_DP_INTF0;
+		break;
 	default:
 		if (mtx->data->mutex_mod[id] < 32) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
@@ -386,6 +475,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DSI3:
 	case DDP_COMPONENT_DPI0:
 	case DDP_COMPONENT_DPI1:
+	case DDP_COMPONENT_DP_INTF0:
 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
 			       mtx->regs +
 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
@@ -507,6 +597,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
 	  .data = &mt8173_mutex_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = &mt8183_mutex_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = &mt8195_mutex_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:19 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:19 +0800
Subject: [PATCH v9 00/14] Add Mediatek Soc DRM (vdosys0) support for mt8195
Message-ID: <20210825144833.7757-1-jason-jh.lin@mediatek.com>

Change in v9:
- seperate power and gce properties of mmsys into another dt-binding patch
- rebase on "Separate aal module" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463
- keep mtk_ddp_clk_enable/disable in the same place
- change mtk_dsc_start config register to mtk_drm_ddp_write_mask
- remove the 0 setting of merge fifo config function
- add CCORR driver data for mt8195

Change in v8:
- add DP_INTF0 mux into mmsys routing table
- add DP_INTF0 mutex mod and enum into add/remove comp funtion
- remove bypass DSC enum in mtk_ddp_comp_init

Change in v7:
- add dt=binding of mmsys and disp path into this series
- separate th modidfication of alphabetic order, remove unused define and
  rename the define of register offset to individual patch
- add comment for MERGE ultra and preultra setting

Change in v6:
- adjust alphabetic order for mediatek-drm
- move the patch that add mt8195 support for mediatek-drm as the lastest patch
- add MERGE define for const varriable 

Change in v5:
- add power-domain property into vdosys0 and vdosys1 dts node.
- add MT8195 prifix and remove unused VDO1 define in mt8195-mmsys.h

Change in v4:
- extract dt-binding patches to another patch series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597
- squash DSC module into mtk_drm_ddp_comp.c
- add coment and simplify MERGE config function

Change in v3:
- change mmsys and display dt-bindings document from txt to yaml
- add MERGE additional description in display dt-bindings document
- fix mboxes-cells number of vdosys0 node in dts
- drop mutex eof convert define
- remove pm_runtime apis in DSC and MERGE
- change DSC and MERGE enum to alphabetic order

Change in v2:
- add DSC yaml file
- add mt8195 drm driver porting parts in to one patch
- remove useless define, variable, structure member and function
- simplify DSC and MERGE file and switch threre order

jason-jh.lin (14):
  dt-bindings: arm: mediatek: mmsys: add power and gce properties
  dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
  dt-bindings: mediatek: display: split each block to individual yaml
  dt-bindings: mediatek: add mediatek,dsc.yaml for mt8195 SoC binding
  dt-bindings: mediatek: display: add mt8195 SoC binding
  arm64: dts: mt8195: add display node for vdosys0
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
  soc: mediatek: add mtk-mutex support for mt8195 vdosys0
  drm/mediatek: remove unused define in mtk_drm_ddp_comp.c
  drm/mediatek: rename the define of register offset
  drm/mediatek: adjust to the alphabetic order for mediatek-drm
  drm/mediatek: add DSC support for mediatek-drm
  drm/mediatek: add MERGE support for mediatek-drm
  drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |  30 ++-
 .../display/mediatek/mediatek,aal.yaml        |  76 ++++++
 .../display/mediatek/mediatek,ccorr.yaml      |  71 ++++++
 .../display/mediatek/mediatek,color.yaml      |  85 +++++++
 .../display/mediatek/mediatek,disp.txt        | 219 ----------------
 .../display/mediatek/mediatek,dither.yaml     |  75 ++++++
 .../display/mediatek/mediatek,dsc.yaml        |  70 +++++
 .../display/mediatek/mediatek,gamma.yaml      |  76 ++++++
 .../display/mediatek/mediatek,merge.yaml      |  98 +++++++
 .../display/mediatek/mediatek,mutex.yaml      |  79 ++++++
 .../display/mediatek/mediatek,od.yaml         |  52 ++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  86 +++++++
 .../display/mediatek/mediatek,ovl.yaml        | 101 ++++++++
 .../display/mediatek/mediatek,rdma.yaml       | 112 ++++++++
 .../display/mediatek/mediatek,split.yaml      |  56 ++++
 .../display/mediatek/mediatek,ufoe.yaml       |  59 +++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 110 ++++++++
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_ccorr.c     |   6 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 239 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |   6 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   | 186 +++++++++-----
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  24 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        | 114 ++++++---
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   1 +
 drivers/soc/mediatek/mt8195-mmsys.h           | 114 +++++++++
 drivers/soc/mediatek/mtk-mmsys.c              |  11 +
 drivers/soc/mediatek/mtk-mutex.c              |  98 ++++++-
 include/linux/soc/mediatek/mtk-mmsys.h        |   9 +
 31 files changed, 2016 insertions(+), 342 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:31 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:31 +0800
Subject: [PATCH v9 12/14] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-13-jason-jh.lin@mediatek.com>

DSC is designed for real-time systems with real-time compression,
transmission, decompression and display.
The DSC standard is a specification of the algorithms used for
compressing and decompressing image display streams, including
the specification of the syntax and semantics of the compressed
video bit stream.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
rebase on [1] series
[1] drm/mediatek: Separate aal module
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 47 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index ef0d2066fae1..0e3ecf97a6fb 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -40,6 +40,12 @@
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_DSC_CON			0x0000
+#define DSC_EN					BIT(0)
+#define DSC_DUAL_INOUT				BIT(2)
+#define DSC_BYPASS				BIT(4)
+#define DSC_UFOE_SEL				BIT(16)
+
 #define DISP_REG_OD_EN				0x0000
 #define DISP_REG_OD_CFG				0x0020
 #define OD_RELAYMODE				BIT(0)
@@ -175,6 +181,36 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc,
 			      DISP_DITHERING, cmdq_pkt);
 }
 
+static void mtk_dsc_config(struct device *dev, unsigned int w,
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* dsc bypass mode */
+	mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_BYPASS);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_UFOE_SEL);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_DUAL_INOUT);
+}
+
+static void mtk_dsc_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* write with mask to reserve the value set in mtk_dsc_config */
+	mtk_ddp_write_mask(NULL, DSC_EN, &priv->cmdq_reg, priv->regs, DISP_REG_DSC_CON, DSC_EN);
+}
+
+static void mtk_dsc_stop(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
+}
+
 static void mtk_od_config(struct device *dev, unsigned int w,
 			  unsigned int h, unsigned int vrefresh,
 			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -238,6 +274,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = {
 	.stop = mtk_dpi_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_dsc = {
+	.clk_enable = mtk_ddp_clk_enable,
+	.clk_disable = mtk_ddp_clk_disable,
+	.config = mtk_dsc_config,
+	.start = mtk_dsc_start,
+	.stop = mtk_dsc_stop,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_dsi = {
 	.start = mtk_dsi_ddp_start,
 	.stop = mtk_dsi_ddp_stop,
@@ -299,6 +343,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_CCORR] = "ccorr",
 	[MTK_DISP_COLOR] = "color",
 	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
@@ -328,6 +373,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DITHER]	= { MTK_DISP_DITHER,	0, &ddp_dither },
 	[DDP_COMPONENT_DPI0]	= { MTK_DPI,		0, &ddp_dpi },
 	[DDP_COMPONENT_DPI1]	= { MTK_DPI,		1, &ddp_dpi },
+	[DDP_COMPONENT_DSC0]	= { MTK_DISP_DSC,	0, &ddp_dsc },
+	[DDP_COMPONENT_DSC1]	= { MTK_DISP_DSC,	1, &ddp_dsc },
 	[DDP_COMPONENT_DSI0]	= { MTK_DSI,		0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]	= { MTK_DSI,		1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]	= { MTK_DSI,		2, &ddp_dsi },
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index d317b944df66..560be6bc9d0e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_CCORR,
 	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
+	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:26 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:26 +0800
Subject: [PATCH v9 07/14] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys0
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-8-jason-jh.lin@mediatek.com>

Add mt8195 vdosys0 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is base on [1][2]
[1] soc: mediatek: mmsys: add MT8365 support
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210519161847.3747352-3-fparent at baylibre.com/
[2] soc: mmsys: mediatek: add mask to mmsys routes
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210729070549.5514-1-linux at fw-web.de/

The vdosys1 impelmentation patch [3] will base on this patch
[3] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210825100531.5653-8-nancy.lin at mediatek.com/
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 114 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       |  11 +++
 include/linux/soc/mediatek/mtk-mmsys.h |   9 ++
 3 files changed, 134 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
new file mode 100644
index 000000000000..0c97a5f016c1
--- /dev/null
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
+#define __SOC_MEDIATEK_MT8195_MMSYS_H
+
+#define MT8195_VDO0_OVL_MOUT_EN					0xf14
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
+
+#define MT8195_VDO0_SEL_IN					0xf34
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		(0 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		(1 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		(2 << 0)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		(0 << 4)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		(1 << 4)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		(0 << 5)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		(1 << 5)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		(0 << 8)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		(1 << 8)
+#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		(0 << 9)
+#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		(0 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			(1 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		(2 << 12)
+#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			(0 << 16)
+#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			(1 << 16)
+#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			(0 << 17)
+#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			(1 << 17)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			(0 << 20)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			(1 << 20)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		(0 << 21)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		(1 << 21)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			(0 << 22)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_VPP_MERGE			(1 << 22)
+
+#define MT8195_VDO0_SEL_OUT					0xf38
+#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		(0 << 0)
+#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			(1 << 0)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		(0 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			(1 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		(2 << 1)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			(0 << 4)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			(1 << 4)
+#define MT8195_SOUT_VPP_MERGE_TO_DSI1				(0 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			(1 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			(2 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(3 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			(4 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			(0 << 11)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA0			(1 << 11)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			(0 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		(1 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			(2 << 12)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			(0 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			(1 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(3 << 16)
+
+static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
+		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
+		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT,
+		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE,
+		MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0,
+		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT,
+		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0,
+		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN,
+		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0,
+		MT8195_SOUT_DISP_DITHER0_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
+	}, {
+		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
+		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+	}
+};
+
+#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index a78e88f27b62..ce6cc2f49e7d 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -14,6 +14,7 @@
 #include "mt8167-mmsys.h"
 #include "mt8183-mmsys.h"
 #include "mt8365-mmsys.h"
+#include "mt8195-mmsys.h"
 
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.clk_driver = "clk-mt2701-mm",
@@ -59,6 +60,12 @@ static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
 	.num_routes = ARRAY_SIZE(mt8365_mmsys_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.clk_driver = "clk-mt8195-vdo0",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 struct mtk_mmsys {
 	void __iomem *regs;
 	const struct mtk_mmsys_driver_data *data;
@@ -171,6 +178,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8365-mmsys",
 		.data = &mt8365_mmsys_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys0",
+		.data = &mt8195_vdosys0_driver_data,
+	},
 	{ }
 };
 
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 2228bf6133da..6d6ece48b61e 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -17,13 +17,22 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DP_INTF0,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_DSC1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
 	DDP_COMPONENT_DSI3,
 	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_MERGE1,
+	DDP_COMPONENT_MERGE2,
+	DDP_COMPONENT_MERGE3,
+	DDP_COMPONENT_MERGE4,
+	DDP_COMPONENT_MERGE5,
 	DDP_COMPONENT_OD0,
 	DDP_COMPONENT_OD1,
 	DDP_COMPONENT_OVL0,
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:30 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:30 +0800
Subject: [PATCH v9 11/14] drm/mediatek: adjust to the alphabetic order for
 mediatek-drm
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-12-jason-jh.lin@mediatek.com>

Adjust to the alphabetic order for the define, function, struct
and array in mediatek-drm driver

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
rebase on [1] series
[1] drm/mediatek: Separate aal module
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 108 ++++++++++----------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  22 ++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  80 +++++++--------
 3 files changed, 104 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 0b5ca9025b3a..ef0d2066fae1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -20,36 +20,34 @@
 #include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_crtc.h"
 
-#define DISP_REG_OD_EN				0x0000
-#define DISP_REG_OD_CFG				0x0020
-#define DISP_REG_OD_SIZE			0x0030
-#define DISP_REG_DITHER_5			0x0114
-#define DISP_REG_DITHER_7			0x011c
-#define DISP_REG_DITHER_15			0x013c
-#define DISP_REG_DITHER_16			0x0140
-
-#define DISP_REG_UFO_START			0x0000
 
 #define DISP_REG_DITHER_EN			0x0000
 #define DITHER_EN				BIT(0)
 #define DISP_REG_DITHER_CFG			0x0020
 #define DITHER_RELAY_MODE			BIT(0)
 #define DITHER_ENGINE_EN			BIT(1)
-#define DISP_REG_DITHER_SIZE			0x0030
-
-#define OD_RELAYMODE				BIT(0)
-
-#define UFO_BYPASS				BIT(2)
-
 #define DISP_DITHERING				BIT(2)
+#define DISP_REG_DITHER_SIZE			0x0030
+#define DISP_REG_DITHER_5			0x0114
+#define DISP_REG_DITHER_7			0x011c
+#define DISP_REG_DITHER_15			0x013c
 #define DITHER_LSB_ERR_SHIFT_R(x)		(((x) & 0x7) << 28)
 #define DITHER_ADD_LSHIFT_R(x)			(((x) & 0x7) << 20)
 #define DITHER_NEW_BIT_MODE			BIT(0)
+#define DISP_REG_DITHER_16			0x0140
 #define DITHER_LSB_ERR_SHIFT_B(x)		(((x) & 0x7) << 28)
 #define DITHER_ADD_LSHIFT_B(x)			(((x) & 0x7) << 20)
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_OD_EN				0x0000
+#define DISP_REG_OD_CFG				0x0020
+#define OD_RELAYMODE				BIT(0)
+#define DISP_REG_OD_SIZE			0x0030
+
+#define DISP_REG_UFO_START			0x0000
+#define UFO_BYPASS				BIT(2)
+
 struct mtk_ddp_comp_dev {
 	struct clk *clk;
 	void __iomem *regs;
@@ -141,65 +139,65 @@ void mtk_dither_set_common(void __iomem *regs, struct cmdq_client_reg *cmdq_reg,
 	}
 }
 
-static void mtk_dither_set(struct device *dev, unsigned int bpc,
-		    unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
+static void mtk_dither_config(struct device *dev, unsigned int w,
+			      unsigned int h, unsigned int vrefresh,
+			      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
-			      DISP_DITHERING, cmdq_pkt);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE);
+	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_DITHER_CFG);
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
+			      DITHER_ENGINE_EN, cmdq_pkt);
 }
 
-static void mtk_od_config(struct device *dev, unsigned int w,
-			  unsigned int h, unsigned int vrefresh,
-			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+static void mtk_dither_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
-	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
-	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
+	writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
 }
 
-static void mtk_od_start(struct device *dev)
+static void mtk_dither_stop(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(1, priv->regs + DISP_REG_OD_EN);
+	writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
 }
 
-static void mtk_ufoe_start(struct device *dev)
+static void mtk_dither_set(struct device *dev, unsigned int bpc,
+			   unsigned int cfg, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
+	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, cfg,
+			      DISP_DITHERING, cmdq_pkt);
 }
 
-static void mtk_dither_config(struct device *dev, unsigned int w,
-			      unsigned int h, unsigned int vrefresh,
-			      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+static void mtk_od_config(struct device *dev, unsigned int w,
+			  unsigned int h, unsigned int vrefresh,
+			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs, DISP_REG_DITHER_SIZE);
-	mtk_ddp_write(cmdq_pkt, DITHER_RELAY_MODE, &priv->cmdq_reg, priv->regs,
-		      DISP_REG_DITHER_CFG);
-	mtk_dither_set_common(priv->regs, &priv->cmdq_reg, bpc, DISP_REG_DITHER_CFG,
-			      DITHER_ENGINE_EN, cmdq_pkt);
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_REG_OD_SIZE);
+	mtk_ddp_write(cmdq_pkt, OD_RELAYMODE, &priv->cmdq_reg, priv->regs, DISP_REG_OD_CFG);
+	mtk_dither_set(dev, bpc, DISP_REG_OD_CFG, cmdq_pkt);
 }
 
-static void mtk_dither_start(struct device *dev)
+static void mtk_od_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel(DITHER_EN, priv->regs + DISP_REG_DITHER_EN);
+	writel(1, priv->regs + DISP_REG_OD_EN);
 }
 
-static void mtk_dither_stop(struct device *dev)
+static void mtk_ufoe_start(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, priv->regs + DISP_REG_DITHER_EN);
+	writel(UFO_BYPASS, priv->regs + DISP_REG_UFO_START);
 }
 
 static const struct mtk_ddp_comp_funcs ddp_aal = {
@@ -296,22 +294,22 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
 };
 
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
+	[MTK_DISP_AAL] = "aal",
+	[MTK_DISP_BLS] = "bls",
+	[MTK_DISP_CCORR] = "ccorr",
+	[MTK_DISP_COLOR] = "color",
+	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MUTEX] = "mutex",
+	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
 	[MTK_DISP_OVL_2L] = "ovl-2l",
+	[MTK_DISP_PWM] = "pwm",
 	[MTK_DISP_RDMA] = "rdma",
-	[MTK_DISP_WDMA] = "wdma",
-	[MTK_DISP_COLOR] = "color",
-	[MTK_DISP_CCORR] = "ccorr",
-	[MTK_DISP_AAL] = "aal",
-	[MTK_DISP_GAMMA] = "gamma",
-	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_UFOE] = "ufoe",
-	[MTK_DSI] = "dsi",
+	[MTK_DISP_WDMA] = "wdma",
 	[MTK_DPI] = "dpi",
-	[MTK_DISP_PWM] = "pwm",
-	[MTK_DISP_MUTEX] = "mutex",
-	[MTK_DISP_OD] = "od",
-	[MTK_DISP_BLS] = "bls",
+	[MTK_DSI] = "dsi",
 };
 
 struct mtk_ddp_comp_match {
@@ -466,12 +464,12 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
-	    type == MTK_DPI ||
-	    type == MTK_DSI ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
-	    type == MTK_DISP_RDMA)
+	    type == MTK_DISP_RDMA ||
+	    type == MTK_DPI ||
+	    type == MTK_DSI)
 		return 0;
 
 	priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index bb914d976cf5..d317b944df66 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -18,22 +18,22 @@ struct mtk_plane_state;
 struct drm_crtc_state;
 
 enum mtk_ddp_comp_type {
-	MTK_DISP_OVL,
-	MTK_DISP_OVL_2L,
-	MTK_DISP_RDMA,
-	MTK_DISP_WDMA,
-	MTK_DISP_COLOR,
+	MTK_DISP_AAL,
+	MTK_DISP_BLS,
 	MTK_DISP_CCORR,
+	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
-	MTK_DISP_AAL,
 	MTK_DISP_GAMMA,
-	MTK_DISP_UFOE,
-	MTK_DSI,
-	MTK_DPI,
-	MTK_DISP_PWM,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-	MTK_DISP_BLS,
+	MTK_DISP_OVL,
+	MTK_DISP_OVL_2L,
+	MTK_DISP_PWM,
+	MTK_DISP_RDMA,
+	MTK_DISP_UFOE,
+	MTK_DISP_WDMA,
+	MTK_DPI,
+	MTK_DSI,
 	MTK_DDP_COMP_TYPE_MAX,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 143ba247c627..22d8f13080f2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -396,52 +396,22 @@ static const struct component_master_ops mtk_drm_ops = {
 };
 
 static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
-	{ .compatible = "mediatek,mt2701-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8173-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8183-disp-ovl",
-	  .data = (void *)MTK_DISP_OVL },
-	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
-	  .data = (void *)MTK_DISP_OVL_2L },
-	{ .compatible = "mediatek,mt2701-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8173-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8183-disp-rdma",
-	  .data = (void *)MTK_DISP_RDMA },
-	{ .compatible = "mediatek,mt8173-disp-wdma",
-	  .data = (void *)MTK_DISP_WDMA },
+	{ .compatible = "mediatek,mt8173-disp-aal",
+	  .data = (void *)MTK_DISP_AAL},
+	{ .compatible = "mediatek,mt8183-disp-aal",
+	  .data = (void *)MTK_DISP_AAL},
 	{ .compatible = "mediatek,mt8183-disp-ccorr",
 	  .data = (void *)MTK_DISP_CCORR },
 	{ .compatible = "mediatek,mt2701-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8173-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
-	{ .compatible = "mediatek,mt8173-disp-aal",
-	  .data = (void *)MTK_DISP_AAL},
-	{ .compatible = "mediatek,mt8183-disp-aal",
-	  .data = (void *)MTK_DISP_AAL},
+	{ .compatible = "mediatek,mt8183-disp-dither",
+	  .data = (void *)MTK_DISP_DITHER },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
-	{ .compatible = "mediatek,mt8183-disp-dither",
-	  .data = (void *)MTK_DISP_DITHER },
-	{ .compatible = "mediatek,mt8173-disp-ufoe",
-	  .data = (void *)MTK_DISP_UFOE },
-	{ .compatible = "mediatek,mt2701-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt8173-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt8183-dsi",
-	  .data = (void *)MTK_DSI },
-	{ .compatible = "mediatek,mt2701-dpi",
-	  .data = (void *)MTK_DPI },
-	{ .compatible = "mediatek,mt8173-dpi",
-	  .data = (void *)MTK_DPI },
-	{ .compatible = "mediatek,mt8183-dpi",
-	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -450,12 +420,42 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8173-disp-od",
+	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt2701-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8173-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8183-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
+	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt2701-disp-pwm",
 	  .data = (void *)MTK_DISP_BLS },
 	{ .compatible = "mediatek,mt8173-disp-pwm",
 	  .data = (void *)MTK_DISP_PWM },
-	{ .compatible = "mediatek,mt8173-disp-od",
-	  .data = (void *)MTK_DISP_OD },
+	{ .compatible = "mediatek,mt2701-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8173-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8183-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8173-disp-ufoe",
+	  .data = (void *)MTK_DISP_UFOE },
+	{ .compatible = "mediatek,mt8173-disp-wdma",
+	  .data = (void *)MTK_DISP_WDMA },
+	{ .compatible = "mediatek,mt2701-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8173-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8183-dpi",
+	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt2701-dsi",
+	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8173-dsi",
+	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8183-dsi",
+	  .data = (void *)MTK_DSI },
 	{ }
 };
 
@@ -545,8 +545,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
-		    comp_type == MTK_DSI ||
-		    comp_type == MTK_DPI) {
+		    comp_type == MTK_DPI ||
+		    comp_type == MTK_DSI) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, compare_of,
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:24 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:24 +0800
Subject: [PATCH v9 05/14] dt-bindings: mediatek: display: add mt8195 SoC
 binding
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-6-jason-jh.lin@mediatek.com>

1. Add mt8195 SoC binding to AAL, CCORR, COLOR, DITHER, GAMMA, MERGE,
   MUTEX, OVL and RDMA yaml schema.

2. Add MERGE additional property description for mt8195
- async clock
- fifo setting enable
- reset controller

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../display/mediatek/mediatek,aal.yaml        |  1 +
 .../display/mediatek/mediatek,ccorr.yaml      |  2 ++
 .../display/mediatek/mediatek,color.yaml      |  1 +
 .../display/mediatek/mediatek,dither.yaml     |  5 +++
 .../display/mediatek/mediatek,gamma.yaml      |  5 +++
 .../display/mediatek/mediatek,merge.yaml      | 32 +++++++++++++++++++
 .../display/mediatek/mediatek,mutex.yaml      |  2 ++
 .../display/mediatek/mediatek,ovl.yaml        |  5 +++
 .../display/mediatek/mediatek,rdma.yaml       |  2 ++
 9 files changed, 55 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
index faa764c12dfc..1599184a4dd1 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -26,6 +26,7 @@ properties:
           - enum:
               - mediatek,mt2712-disp-aal
               - mediatek,mt8183-disp-aal
+              - mediatek,mt8195-disp-aal
           - enum:
               - mediatek,mt8173-disp-aal
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
index e848879d755c..f9b697604ab9 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -22,6 +22,8 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8183-disp-ccorr
+      - items:
+          - const: mediatek,mt8195-disp-ccorr
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
index 019fc09bbddd..563755095a4f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -36,6 +36,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8183-disp-color
+              - mediatek,mt8195-disp-color
           - enum:
               - mediatek,mt8173-disp-color
   reg:
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
index 8e7c87c39f9c..b6f57243270c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -23,6 +23,11 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8183-disp-dither
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-dither
+          - enum:
+              - mediatek,mt8183-disp-dither
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
index 8fa1b373a8da..ab1e18da6bed 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -24,6 +24,11 @@ properties:
           - const: mediatek,mt8173-disp-gamma
       - items:
           - const: mediatek,mt8183-disp-gamma
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-gamma
+          - enum:
+              - mediatek,mt8183-disp-gamma
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index ca51a4c4a8c7..b15c6e17b421 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -22,6 +22,8 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8173-disp-merge
+      - items:
+          - const: mediatek,mt8195-disp-merge
 
   reg:
     maxItems: 1
@@ -37,6 +39,19 @@ properties:
   clocks:
     items:
       - description: MERGE Clock
+      - description: MERGE Async Clock
+          Controlling the synchronous process between MERGE and other display function
+          blocks cross clock domain.
+
+  mediatek,merge-fifo-en:
+    description:
+      The setting of merge fifo is mainly provided for the display latency buffer.
+      to ensure that the back-end panel display data will not be underrun,
+      a little more data is needed in the fifo. According to the merge fifo settings,
+      when the water level is detected to be insufficient, it will trigger RDMA sending
+      ultra and preulra command to SMI to speed up the data rate.
+    type: boolean
+
 
   mediatek,gce-client-reg:
     description:
@@ -47,6 +62,10 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle-array
     maxItems: 1
 
+  resets:
+    description: reset controller
+      See Documentation/devicetree/bindings/reset/reset.txt for details.
+
 required:
   - compatible
   - reg
@@ -64,3 +83,16 @@ examples:
         power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
         clocks = <&mmsys CLK_MM_DISP_MERGE>;
     };
+
+    merge5: disp_vpp_merge5 at 1c110000 {
+        compatible = "mediatek,mt8195-disp-merge";
+        reg = <0 0x1c110000 0 0x1000>;
+        interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+                 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+        clock-names = "merge","merge_async";
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+        mediatek,merge-fifo-en = <1>;
+        resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
index 939dff14d989..db9db182318d 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -31,6 +31,8 @@ properties:
           - const: mediatek,mt8173-disp-mutex
       - items:
           - const: mediatek,mt8183-disp-mutex
+      - items:
+          - const: mediatek,mt8195-disp-mutex
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index a0c29cd3377a..5008f900d81f 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -32,6 +32,11 @@ properties:
               - mediatek,mt2712-disp-ovl
           - enum:
               - mediatek,mt2701-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ovl
+          - enum:
+              - mediatek,mt8183-disp-ovl
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
index 837659ab4ebd..806437166e3c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -28,6 +28,8 @@ properties:
           - const: mediatek,mt8173-disp-rdma
       - items:
           - const: mediatek,mt8183-disp-rdma
+      - items:
+          - const: mediatek,mt8195-disp-rdma
       - items:
           - enum:
               - mediatek,mt7623-disp-rdma
-- 
2.18.0

From maxime at cerno.tech  Wed Aug 25 07:50:27 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 25 Aug 2021 16:50:27 +0200
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <5432230.1UTMcGJKg4@jernej-laptop>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-11-icenowy@sipeed.com>
 <99a74950-fdc0-ecfe-e5f0-ba4a7d8751f0@sholland.org>
 <5432230.1UTMcGJKg4@jernej-laptop>
Message-ID: <20210825145027.ixc7wnh3x5w6wzny@gilmour>

Hi,

On Fri, Aug 20, 2021 at 06:34:38AM +0200, Jernej ?krabec wrote:
> > > +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> > > +{
> > > +	void __iomem *reg;
> > > +	u32 val;
> > > +	int i;
> > > +
> > > +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > > +	if (IS_ERR(reg)) {
> > > +		pr_err("%pOF: Could not map clock registers\n", node);
> > > +		return;
> > > +	}
> > > +
> > > +	/* Enable the lock bits and the output enable bits on all PLLs */
> > > +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> > > +		val = readl(reg + pll_regs[i]);
> > > +		val |= BIT(29) | BIT(27);
> > > +		writel(val, reg + pll_regs[i]);
> > > +	}
> > > +
> > > +	/*
> > > +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> > > +	 *
> > > +	 * See the comment before pll-audio1 definition for the reason.
> > > +	 */
> > > +
> > > +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > +	val &= ~BIT(1);
> > > +	val |= BIT(0);
> > > +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > +
> > > +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> > > +	if (i)
> > > +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> > > +}
> > > +
> > > +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> > > +	       sun50i_r329_r_ccu_setup);
> > 
> > Please make this a platform driver. There is no particular reason why it
> > needs to be an early OF clock provider.
> 
> Why? It's good to have it as early clock provider. It has no dependencies and 
> other drivers that depends on it, like IR, can be deferred, if this is loaded 
> later.

No, Samuel is right, we should make them regular drivers as much as we
can.

The reason we had CLK_OF_DECLARE in the first place is that timers
usually have a parent clock, and you need the timers before the device
model is set up.

Fortunately for us, since the A20, the architected timers don't require
a parent clock from us, and we can thus boot up fine.

Since the dependencies are minimal, it should probe fairly early and
with the on-demand probing from the device links you might not even tell
the difference for most consumers.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210825/5864f871/attachment.sig>

From maxime at cerno.tech  Wed Aug 25 07:54:34 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 25 Aug 2021 16:54:34 +0200
Subject: [PATCH 11/17] clk: sunxi-ng: add support for Allwinner R329 CCU
In-Reply-To: <3e56e53f-e6df-50cf-5545-e9132e521ed1@sholland.org>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-12-icenowy@sipeed.com>
 <3e56e53f-e6df-50cf-5545-e9132e521ed1@sholland.org>
Message-ID: <20210825145434.vdrhgrgblnnmvmve@gilmour>

On Thu, Aug 19, 2021 at 09:41:26PM -0500, Samuel Holland wrote:
> On 8/2/21 1:22 AM, Icenowy Zheng wrote:
> > Allwinner R329 has a CCU that is similar to the H616 one, but it's cut
> > down and have PLLs moved out.
> > 
> > Add support for it.
> > 
> > Signed-off-by: Icenowy Zheng <icenowy at sipeed.com>
> > ---
> >  drivers/clk/sunxi-ng/Kconfig                |   5 +
> >  drivers/clk/sunxi-ng/Makefile               |   1 +
> >  drivers/clk/sunxi-ng/ccu-sun50i-r329.c      | 526 ++++++++++++++++++++
> >  drivers/clk/sunxi-ng/ccu-sun50i-r329.h      |  32 ++
> >  include/dt-bindings/clock/sun50i-r329-ccu.h |  73 +++
> >  include/dt-bindings/reset/sun50i-r329-ccu.h |  45 ++
> >  6 files changed, 682 insertions(+)
> >  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> >  create mode 100644 drivers/clk/sunxi-ng/ccu-sun50i-r329.h
> >  create mode 100644 include/dt-bindings/clock/sun50i-r329-ccu.h
> >  create mode 100644 include/dt-bindings/reset/sun50i-r329-ccu.h
> > 
> > diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> > index e49b2c2fa5b7..4b32d5f81ea8 100644
> > --- a/drivers/clk/sunxi-ng/Kconfig
> > +++ b/drivers/clk/sunxi-ng/Kconfig
> > @@ -42,6 +42,11 @@ config SUN50I_H6_R_CCU
> >  	default ARM64 && ARCH_SUNXI
> >  	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> >  
> > +config SUN50I_R329_CCU
> > +	bool "Support for the Allwinner R329 CCU"
> > +	default ARM64 && ARCH_SUNXI
> > +	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
> > +
> >  config SUN50I_R329_R_CCU
> >  	bool "Support for the Allwinner R329 PRCM CCU"
> >  	default ARM64 && ARCH_SUNXI
> > diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> > index db338a2188fd..62f3c5bf331c 100644
> > --- a/drivers/clk/sunxi-ng/Makefile
> > +++ b/drivers/clk/sunxi-ng/Makefile
> > @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
> >  obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
> >  obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
> >  obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
> > +obj-$(CONFIG_SUN50I_R329_CCU)	+= ccu-sun50i-r329.o
> >  obj-$(CONFIG_SUN50I_R329_R_CCU)	+= ccu-sun50i-r329-r.o
> >  obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
> >  obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
> > diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-r329.c b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> > new file mode 100644
> > index 000000000000..a0b4cfd6e1db
> > --- /dev/null
> > +++ b/drivers/clk/sunxi-ng/ccu-sun50i-r329.c
> > @@ -0,0 +1,526 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Based on the H616 CCU driver, which is:
> > + *   Copyright (c) 2020 Arm Ltd.
> > + */
> > +
> > +#include <linux/clk-provider.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/platform_device.h>
> > +
> > +#include "ccu_common.h"
> > +#include "ccu_reset.h"
> > +
> > +#include "ccu_div.h"
> > +#include "ccu_gate.h"
> > +#include "ccu_mp.h"
> > +#include "ccu_mult.h"
> > +#include "ccu_nk.h"
> > +#include "ccu_nkm.h"
> > +#include "ccu_nkmp.h"
> > +#include "ccu_nm.h"
> > +
> > +#include "ccu-sun50i-r329.h"
> > +
> > +/*
> > + * An external divider of PLL-CPUX is controlled here. As it's similar to
> > + * the external divider of PLL-CPUX on previous SoCs (only usable under
> > + * 288MHz}, ignore it.
> 
> Mismatched (braces} here
> 
> > + */
> > +static const char * const cpux_parents[] = { "osc24M", "osc32k", "iosc",
> > +					     "pll-cpux", "pll-periph",
> > +					     "pll-periph-2x",
> > +					     "pll=periph-800m" };
> 
> = should be a -.
> 
> Now that these PLLs are in a different device, how is this supposed to affect
> the DT binding? Do we put all of them in the clocks property?
> 
> If so, we can use .fw_name at some point. If not, why bother with the clocks
> property at all? This is another part of the "let's get the clock tree right
> from the start" discussion.

Agreed

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210825/7c3e0be6/attachment-0001.sig>

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:32 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:32 +0800
Subject: [PATCH v9 13/14] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-14-jason-jh.lin@mediatek.com>

Add MERGE engine file:
MERGE module is used to merge two slice-per-line inputs
into one side-by-side output.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile           |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 239 ++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  16 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   4 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
 7 files changed, 269 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 29098d7c8307..a38e88e82d12 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -4,6 +4,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_disp_ccorr.o \
 		  mtk_disp_color.o \
 		  mtk_disp_gamma.o \
+		  mtk_disp_merge.o \
 		  mtk_disp_ovl.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 86c3068894b1..a33b13fe2b6e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -55,6 +55,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
 void mtk_gamma_start(struct device *dev);
 void mtk_gamma_stop(struct device *dev);
 
+int mtk_merge_clk_enable(struct device *dev);
+void mtk_merge_clk_disable(struct device *dev);
+void mtk_merge_config(struct device *dev, unsigned int width,
+		      unsigned int height, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start(struct device *dev);
+void mtk_merge_stop(struct device *dev);
+
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
 void mtk_ovl_bypass_shadow(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
new file mode 100644
index 000000000000..b05e1df79c3d
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_disp_drv.h"
+
+#define DISP_REG_MERGE_CTRL		0x000
+#define MERGE_EN				1
+#define DISP_REG_MERGE_CFG_0		0x010
+#define DISP_REG_MERGE_CFG_4		0x020
+#define DISP_REG_MERGE_CFG_10		0x038
+/* no swap */
+#define SWAP_MODE				0
+#define FLD_SWAP_MODE				GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_12		0x040
+#define CFG_10_10_1PI_2PO_BUF_MODE		6
+#define CFG_10_10_2PI_2PO_BUF_MODE		8
+#define FLD_CFG_MERGE_MODE			GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_24		0x070
+#define DISP_REG_MERGE_CFG_25		0x074
+#define DISP_REG_MERGE_CFG_36		0x0a0
+#define ULTRA_EN				BIT(0)
+#define PREULTRA_EN				BIT(4)
+#define DISP_REG_MERGE_CFG_37		0x0a4
+/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
+#define BUFFER_MODE				3
+#define FLD_BUFFER_MODE				GENMASK(1, 0)
+/*
+ * For the ultra and preultra settings, 6us ~ 9us is experience value
+ * and the maximum frequency of mmsys clock is 594MHz.
+ */
+#define DISP_REG_MERGE_CFG_40		0x0b0
+/* 6 us, 594M pixel/sec */
+#define ULTRA_TH_LOW				(6 * 594)
+/* 8 us, 594M pixel/sec */
+#define ULTRA_TH_HIGH				(8 * 594)
+#define FLD_ULTRA_TH_LOW			GENMASK(15, 0)
+#define FLD_ULTRA_TH_HIGH			GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_41		0x0b4
+/* 8 us, 594M pixel/sec */
+#define PREULTRA_TH_LOW				(8 * 594)
+/* 9 us, 594M pixel/sec */
+#define PREULTRA_TH_HIGH			(9 * 594)
+#define FLD_PREULTRA_TH_LOW			GENMASK(15, 0)
+#define FLD_PREULTRA_TH_HIGH			GENMASK(31, 16)
+
+struct mtk_disp_merge {
+	void __iomem *regs;
+	struct clk *clk;
+	struct clk *async_clk;
+	struct cmdq_client_reg		cmdq_reg;
+	bool				fifo_en;
+};
+
+void mtk_merge_start(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
+				   struct cmdq_pkt *cmdq_pkt)
+{
+	mtk_ddp_write(cmdq_pkt, ULTRA_EN | PREULTRA_EN,
+		      &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_36);
+
+	mtk_ddp_write_mask(cmdq_pkt, BUFFER_MODE,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_37,
+			   FLD_BUFFER_MODE);
+
+	mtk_ddp_write_mask(cmdq_pkt, ULTRA_TH_LOW | ULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_40,
+			   FLD_ULTRA_TH_LOW | FLD_ULTRA_TH_HIGH);
+
+	mtk_ddp_write_mask(cmdq_pkt, PREULTRA_TH_LOW | PREULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_41,
+			   FLD_PREULTRA_TH_LOW | FLD_PREULTRA_TH_HIGH);
+}
+
+void mtk_merge_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+	unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
+
+	if (!h || !w) {
+		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
+		return;
+	}
+
+	if (priv->fifo_en) {
+		mtk_merge_fifo_setting(priv, cmdq_pkt);
+		mode = CFG_10_10_2PI_2PO_BUF_MODE;
+	}
+
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_0);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_4);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_24);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_25);
+	mtk_ddp_write_mask(cmdq_pkt, SWAP_MODE, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
+	mtk_ddp_write_mask(cmdq_pkt, mode, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_12, FLD_CFG_MERGE_MODE);
+}
+
+int mtk_merge_clk_enable(struct device *dev)
+{
+	int ret = 0;
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		pr_err("merge clk prepare enable failed\n");
+	ret = clk_prepare_enable(priv->async_clk);
+	if (ret)
+		pr_err("async clk prepare enable failed\n");
+
+	return ret;
+}
+
+void mtk_merge_clk_disable(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(priv->async_clk);
+	clk_disable_unprepare(priv->clk);
+}
+
+static int mtk_disp_merge_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return 0;
+}
+
+static void mtk_disp_merge_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+}
+
+static const struct component_ops mtk_disp_merge_component_ops = {
+	.bind	= mtk_disp_merge_bind,
+	.unbind = mtk_disp_merge_unbind,
+};
+
+static int mtk_disp_merge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct mtk_disp_merge *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap merge\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get merge clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	priv->async_clk = of_clk_get(dev->of_node, 1);
+	if (IS_ERR(priv->async_clk)) {
+		ret = PTR_ERR(priv->async_clk);
+		dev_dbg(dev, "No merge async clock: %d\n", ret);
+		priv->async_clk = NULL;
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+	priv->fifo_en = of_property_read_bool(dev->of_node,
+					      "mediatek,merge-fifo-en");
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_disp_merge_component_ops);
+	if (ret != 0)
+		dev_err(dev, "Failed to add component: %d\n", ret);
+
+	return ret;
+}
+
+static int mtk_disp_merge_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_disp_merge_component_ops);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_disp_merge_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-merge", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
+
+struct platform_driver mtk_disp_merge_driver = {
+	.probe = mtk_disp_merge_probe,
+	.remove = mtk_disp_merge_remove,
+	.driver = {
+		.name = "mediatek-disp-merge",
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_disp_merge_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 0e3ecf97a6fb..2885fe83162a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -296,6 +296,14 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
 	.stop = mtk_gamma_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_merge = {
+	.clk_enable = mtk_merge_clk_enable,
+	.clk_disable = mtk_merge_clk_disable,
+	.start = mtk_merge_start,
+	.stop = mtk_merge_stop,
+	.config = mtk_merge_config,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_od = {
 	.clk_enable = mtk_ddp_clk_enable,
 	.clk_disable = mtk_ddp_clk_disable,
@@ -345,6 +353,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MERGE] = "merge",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
@@ -380,6 +389,12 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DSI2]	= { MTK_DSI,		2, &ddp_dsi },
 	[DDP_COMPONENT_DSI3]	= { MTK_DSI,		3, &ddp_dsi },
 	[DDP_COMPONENT_GAMMA]	= { MTK_DISP_GAMMA,	0, &ddp_gamma },
+	[DDP_COMPONENT_MERGE0]	= { MTK_DISP_MERGE,	0, &ddp_merge },
+	[DDP_COMPONENT_MERGE1]	= { MTK_DISP_MERGE,	1, &ddp_merge },
+	[DDP_COMPONENT_MERGE2]	= { MTK_DISP_MERGE,	2, &ddp_merge },
+	[DDP_COMPONENT_MERGE3]	= { MTK_DISP_MERGE,	3, &ddp_merge },
+	[DDP_COMPONENT_MERGE4]	= { MTK_DISP_MERGE,	4, &ddp_merge },
+	[DDP_COMPONENT_MERGE5]	= { MTK_DISP_MERGE,	5, &ddp_merge },
 	[DDP_COMPONENT_OD0]	= { MTK_DISP_OD,	0, &ddp_od },
 	[DDP_COMPONENT_OD1]	= { MTK_DISP_OD,	1, &ddp_od },
 	[DDP_COMPONENT_OVL0]	= { MTK_DISP_OVL,	0, &ddp_ovl },
@@ -511,6 +526,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
+	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 560be6bc9d0e..b42a47c06956 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -25,6 +25,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_DITHER,
 	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
+	MTK_DISP_MERGE,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 22d8f13080f2..e7f77a16ed16 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -534,7 +534,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
-		 * Currently only the AAL, CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
+		 * Currently only the AAL, CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
 		 * blocks have separate component platform drivers and initialize their own
 		 * DDP component structure. The others are initialized here.
 		 */
@@ -542,6 +542,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_CCORR ||
 		    comp_type == MTK_DISP_COLOR ||
 		    comp_type == MTK_DISP_GAMMA ||
+		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
@@ -643,6 +644,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ccorr_driver,
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
+	&mtk_disp_merge_driver,
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 3e7d1e6fbe01..a58cebd01d35 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -50,6 +50,7 @@ extern struct platform_driver mtk_disp_aal_driver;
 extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
+extern struct platform_driver mtk_disp_merge_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
-- 
2.18.0

From jason-jh.lin at mediatek.com  Wed Aug 25 07:48:33 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 25 Aug 2021 22:48:33 +0800
Subject: [PATCH v9 14/14] drm/mediatek: add mediatek-drm of vdosys0 support
 for mt8195
In-Reply-To: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
References: <20210825144833.7757-1-jason-jh.lin@mediatek.com>
Message-ID: <20210825144833.7757-15-jason-jh.lin@mediatek.com>

Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
rebase on [1] series
[1] drm/mediatek: Separate aal module
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463
---
 drivers/gpu/drm/mediatek/mtk_disp_ccorr.c |  6 +++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c  |  6 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c    | 30 +++++++++++++++++++++++
 3 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
index 141cb36b9c07..ea1d568bdbe7 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
@@ -205,9 +205,15 @@ static const struct mtk_disp_ccorr_data mt8183_ccorr_driver_data = {
 	.matrix_bits = 10,
 };
 
+static const struct mtk_disp_ccorr_data mt8195_ccorr_driver_data = {
+	.matrix_bits = 11,
+};
+
 static const struct of_device_id mtk_disp_ccorr_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt8183-disp-ccorr",
 	  .data = &mt8183_ccorr_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-ccorr",
+	  .data = &mt8183_ccorr_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 705f28ceb4dd..0d3d3c834e0f 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -353,6 +353,10 @@ static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
 	.fifo_size = 5 * SZ_1K,
 };
 
+static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
+	.fifo_size = 1920,
+};
+
 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt2701-disp-rdma",
 	  .data = &mt2701_rdma_driver_data},
@@ -360,6 +364,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	  .data = &mt8173_rdma_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = &mt8183_rdma_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = &mt8195_rdma_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index e7f77a16ed16..ae8df7ecc872 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -147,6 +147,19 @@ static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
 	DDP_COMPONENT_DPI0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
+	DDP_COMPONENT_OVL0,
+	DDP_COMPONENT_RDMA0,
+	DDP_COMPONENT_COLOR0,
+	DDP_COMPONENT_CCORR,
+	DDP_COMPONENT_AAL0,
+	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_DP_INTF0,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -186,6 +199,11 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.main_path = mt8195_mtk_ddp_main,
+	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+};
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
@@ -402,16 +420,22 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_AAL},
 	{ .compatible = "mediatek,mt8183-disp-ccorr",
 	  .data = (void *)MTK_DISP_CCORR },
+	{ .compatible = "mediatek,mt8195-disp-ccorr",
+	  .data = (void *)MTK_DISP_CCORR },
 	{ .compatible = "mediatek,mt2701-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8173-disp-color",
 	  .data = (void *)MTK_DISP_COLOR },
 	{ .compatible = "mediatek,mt8183-disp-dither",
 	  .data = (void *)MTK_DISP_DITHER },
+	{ .compatible = "mediatek,mt8195-disp-dsc",
+	  .data = (void *)MTK_DISP_DSC },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
+	{ .compatible = "mediatek,mt8195-disp-merge",
+	  .data = (void *)MTK_DISP_MERGE },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -420,6 +444,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8173-disp-od",
 	  .data = (void *)MTK_DISP_OD },
 	{ .compatible = "mediatek,mt2701-disp-ovl",
@@ -440,6 +466,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8183-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8173-disp-ufoe",
 	  .data = (void *)MTK_DISP_UFOE },
 	{ .compatible = "mediatek,mt8173-disp-wdma",
@@ -470,6 +498,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
 	  .data = &mt8173_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8183-mmsys",
 	  .data = &mt8183_mmsys_driver_data},
+	{.compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
2.18.0

From maxime at cerno.tech  Wed Aug 25 08:00:46 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 25 Aug 2021 17:00:46 +0200
Subject: [PATCH 15/17] arm64: allwinner: dts: add DTSI file for R329 SoC
In-Reply-To: <8e4a49b8-8f17-d659-0952-0c96b0098139@sholland.org>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-16-icenowy@sipeed.com>
 <20210818090139.rllz4fvvq3pzdkls@gilmour>
 <74F51516-2470-4A49-972B-E19D8EDD9A3D@sipeed.com>
 <75ae9ef8-496b-68ca-214e-e8b270648a50@sholland.org>
 <8e4a49b8-8f17-d659-0952-0c96b0098139@sholland.org>
Message-ID: <20210825150046.dpua45aeqrndxzbu@gilmour>

On Thu, Aug 19, 2021 at 10:06:43PM -0500, Samuel Holland wrote:
> On 8/18/21 9:32 PM, Samuel Holland wrote:
> > On 8/18/21 4:15 AM, Icenowy Zheng wrote:
> >> ? 2021?8?18? GMT+08:00 ??5:01:39, Maxime Ripard <maxime at cerno.tech> ??:
> >>> On Mon, Aug 02, 2021 at 02:22:10PM +0800, Icenowy Zheng wrote:
> >>>> +		ccu: clock at 2001000 {
> >>>> +			compatible = "allwinner,sun50i-r329-ccu";
> >>>> +			reg = <0x02001000 0x1000>;
> >>>> +			clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
> >>>> +			clock-names = "hosc", "losc", "iosc";
> >>>
> >>> Do we have a clock tree for the RTC? Is it the same than the H616?
> >>
> >> Nope, it's the same with H6 because of external LOSC crystal is
> >> possible. (Although production M2A SoMs has it NC for cost control.)
> > 
> > It is not the same as the H6, either. The clock tree _is_ identical to the D1,
> > which has three diagrams on pages 363-364 of its user manual here:
> > 
> > https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf
> > 
> > Compared to the H6, the R329/D1:
> >  - Loses the LOSC calibration circuit
> >  - Gains a third mux input for LOSC (not external 32k) to fanout
> >  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
> >  - Gains an SPI bus clock input divided from the PRCM AHB
> > 
> > Compared to the H616, the R329/D1:
> >  - Has an external 32k crystal input
> >    - Gains the IOSC vs. external 32k crystal mux for LOSC
> >    - Switches fanout mux input #1 from pll_periph0/N to external 32k
> >  - Gains a mux to choose between LOSC and HOSC/750 for the RTC clock
> >  - Gains an SPI bus clock input divided from the PRCM AHB
> > 
> > So the R329/D1 RTC has three^Wfour inputs:
> >  - SPI clock from PRCM
> >  - 24 MHz DCXO crystal
> >  - 32 kHz external crystal (optional)
> 
> Whoops, I missed one here:
>  - Bus clock from PRCM
> 
> The SPI clock is new for R329, but the bus clock has been around since H6.
> 
> > and four outputs:
> >  - 16 MHz "IOSC" RC oscillator
> >  - 32 kHz "LOSC"
> >  - ~1 kHz for RTC timekeeping
> 
> Even though this is internal to the RTC, it is still useful to model, as it can
> be used to correct for known RTC drift. (For example, HOSC/750 is 32000 Hz
> instead of 32768 Hz, so 2.34375% slow. But that is better than IOSC, which has
> unknown error.)

If it's not useful to any other device, there's no real reason to model
it in the clock framework. We should still force the source of the RTC
to the most accurate option we have, but we can do that without the CCF.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210825/43f4972e/attachment.sig>

From m.tretter at pengutronix.de  Wed Aug 25 08:03:11 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 25 Aug 2021 17:03:11 +0200
Subject: [PATCH v2 2/4] soc: xilinx: cleanup debug and error messages
In-Reply-To: <20210825150313.4033156-1-m.tretter@pengutronix.de>
References: <20210825150313.4033156-1-m.tretter@pengutronix.de>
Message-ID: <20210825150313.4033156-3-m.tretter@pengutronix.de>

Use dev_err/dev_dbg instead of pr_err/pr_debug.

Add the PM node ids to supplement the (arbitrary) power domain names to
include information which PM nodes are requested by the driver.

Drop function names from the messages, because they can easily be added
with dynamic debug.

Remove comments explaining that error messages are printed on errors.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
Changelog:

v2:

- fix another debug string that included the function name
---
 drivers/soc/xilinx/zynqmp_pm_domains.c | 45 +++++++++++++-------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/drivers/soc/xilinx/zynqmp_pm_domains.c b/drivers/soc/xilinx/zynqmp_pm_domains.c
index 81e8e10f1092..27c46c68e5cc 100644
--- a/drivers/soc/xilinx/zynqmp_pm_domains.c
+++ b/drivers/soc/xilinx/zynqmp_pm_domains.c
@@ -80,12 +80,15 @@ static int zynqmp_gpd_power_on(struct generic_pm_domain *domain)
 					ZYNQMP_PM_MAX_QOS,
 					ZYNQMP_PM_REQUEST_ACK_BLOCKING);
 	if (ret) {
-		pr_err("%s() %s set requirement for node %d failed: %d\n",
-		       __func__, domain->name, pd->node_id, ret);
+		dev_err(&domain->dev,
+			"failed to set requirement to 0x%x for PM node id %d: %d\n",
+			ZYNQMP_PM_CAPABILITY_ACCESS, pd->node_id, ret);
 		return ret;
 	}
 
-	pr_debug("%s() Powered on %s domain\n", __func__, domain->name);
+	dev_dbg(&domain->dev, "set requirement to 0x%x for PM node id %d\n",
+		ZYNQMP_PM_CAPABILITY_ACCESS, pd->node_id);
+
 	return 0;
 }
 
@@ -110,8 +113,8 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)
 
 	/* If domain is already released there is nothing to be done */
 	if (!(pd->flags & ZYNQMP_PM_DOMAIN_REQUESTED)) {
-		pr_debug("%s() %s domain is already released\n",
-			 __func__, domain->name);
+		dev_dbg(&domain->dev, "PM node id %d is already released\n",
+			pd->node_id);
 		return 0;
 	}
 
@@ -128,17 +131,16 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)
 
 	ret = zynqmp_pm_set_requirement(pd->node_id, capabilities, 0,
 					ZYNQMP_PM_REQUEST_ACK_NO);
-	/**
-	 * If powering down of any node inside this domain fails,
-	 * report and return the error
-	 */
 	if (ret) {
-		pr_err("%s() %s set requirement for node %d failed: %d\n",
-		       __func__, domain->name, pd->node_id, ret);
+		dev_err(&domain->dev,
+			"failed to set requirement to 0x%x for PM node id %d: %d\n",
+			capabilities, pd->node_id, ret);
 		return ret;
 	}
 
-	pr_debug("%s() Powered off %s domain\n", __func__, domain->name);
+	dev_dbg(&domain->dev, "set requirement to 0x%x for PM node id %d\n",
+		capabilities, pd->node_id);
+
 	return 0;
 }
 
@@ -169,17 +171,17 @@ static int zynqmp_gpd_attach_dev(struct generic_pm_domain *domain,
 
 	ret = zynqmp_pm_request_node(pd->node_id, 0, 0,
 				     ZYNQMP_PM_REQUEST_ACK_BLOCKING);
-	/* If requesting a node fails print and return the error */
 	if (ret) {
-		pr_err("%s() %s request failed for node %d: %d\n",
-		       __func__, domain->name, pd->node_id, ret);
+		dev_err(&domain->dev, "%s request failed for node %d: %d\n",
+			domain->name, pd->node_id, ret);
 		return ret;
 	}
 
 	pd->flags |= ZYNQMP_PM_DOMAIN_REQUESTED;
 
-	pr_debug("%s() %s attached to %s domain\n", __func__,
-		 dev_name(dev), domain->name);
+	dev_dbg(&domain->dev, "%s requested PM node id %d\n",
+		dev_name(dev), pd->node_id);
+
 	return 0;
 }
 
@@ -201,17 +203,16 @@ static void zynqmp_gpd_detach_dev(struct generic_pm_domain *domain,
 		return;
 
 	ret = zynqmp_pm_release_node(pd->node_id);
-	/* If releasing a node fails print the error and return */
 	if (ret) {
-		pr_err("%s() %s release failed for node %d: %d\n",
-		       __func__, domain->name, pd->node_id, ret);
+		dev_err(&domain->dev, "failed to release PM node id %d: %d\n",
+			pd->node_id, ret);
 		return;
 	}
 
 	pd->flags &= ~ZYNQMP_PM_DOMAIN_REQUESTED;
 
-	pr_debug("%s() %s detached from %s domain\n", __func__,
-		 dev_name(dev), domain->name);
+	dev_dbg(&domain->dev, "%s released PM node id %d\n",
+		dev_name(dev), pd->node_id);
 }
 
 static struct generic_pm_domain *zynqmp_gpd_xlate
-- 
2.30.2



From m.tretter at pengutronix.de  Wed Aug 25 08:03:13 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 25 Aug 2021 17:03:13 +0200
Subject: [PATCH v2 4/4] soc: xilinx: add a to_zynqmp_pm_domain macro
In-Reply-To: <20210825150313.4033156-1-m.tretter@pengutronix.de>
References: <20210825150313.4033156-1-m.tretter@pengutronix.de>
Message-ID: <20210825150313.4033156-5-m.tretter@pengutronix.de>

Replace container_of for converting a generic_pm_domain to a
zynqmp_pm_domain with a macro definition to simplify the code.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/soc/xilinx/zynqmp_pm_domains.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/xilinx/zynqmp_pm_domains.c b/drivers/soc/xilinx/zynqmp_pm_domains.c
index 53b0041f9fe0..fcce2433bd6d 100644
--- a/drivers/soc/xilinx/zynqmp_pm_domains.c
+++ b/drivers/soc/xilinx/zynqmp_pm_domains.c
@@ -35,6 +35,9 @@ struct zynqmp_pm_domain {
 	bool requested;
 };
 
+#define to_zynqmp_pm_domain(pm_domain) \
+	container_of(pm_domain, struct zynqmp_pm_domain, gpd)
+
 /**
  * zynqmp_gpd_is_active_wakeup_path() - Check if device is in wakeup source
  *					path
@@ -69,10 +72,9 @@ static int zynqmp_gpd_is_active_wakeup_path(struct device *dev, void *not_used)
  */
 static int zynqmp_gpd_power_on(struct generic_pm_domain *domain)
 {
+	struct zynqmp_pm_domain *pd = to_zynqmp_pm_domain(domain);
 	int ret;
-	struct zynqmp_pm_domain *pd;
 
-	pd = container_of(domain, struct zynqmp_pm_domain, gpd);
 	ret = zynqmp_pm_set_requirement(pd->node_id,
 					ZYNQMP_PM_CAPABILITY_ACCESS,
 					ZYNQMP_PM_MAX_QOS,
@@ -101,14 +103,12 @@ static int zynqmp_gpd_power_on(struct generic_pm_domain *domain)
  */
 static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)
 {
+	struct zynqmp_pm_domain *pd = to_zynqmp_pm_domain(domain);
 	int ret;
 	struct pm_domain_data *pdd, *tmp;
-	struct zynqmp_pm_domain *pd;
 	u32 capabilities = min_capability;
 	bool may_wakeup;
 
-	pd = container_of(domain, struct zynqmp_pm_domain, gpd);
-
 	/* If domain is already released there is nothing to be done */
 	if (!pd->requested) {
 		dev_dbg(&domain->dev, "PM node id %d is already released\n",
@@ -152,11 +152,9 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)
 static int zynqmp_gpd_attach_dev(struct generic_pm_domain *domain,
 				 struct device *dev)
 {
+	struct zynqmp_pm_domain *pd = to_zynqmp_pm_domain(domain);
 	struct device_link *link;
 	int ret;
-	struct zynqmp_pm_domain *pd;
-
-	pd = container_of(domain, struct zynqmp_pm_domain, gpd);
 
 	link = device_link_add(dev, &domain->dev, DL_FLAG_SYNC_STATE_ONLY);
 	if (!link)
@@ -191,10 +189,8 @@ static int zynqmp_gpd_attach_dev(struct generic_pm_domain *domain,
 static void zynqmp_gpd_detach_dev(struct generic_pm_domain *domain,
 				  struct device *dev)
 {
+	struct zynqmp_pm_domain *pd = to_zynqmp_pm_domain(domain);
 	int ret;
-	struct zynqmp_pm_domain *pd;
-
-	pd = container_of(domain, struct zynqmp_pm_domain, gpd);
 
 	/* If this is not the last device to detach there is nothing to do */
 	if (domain->device_count)
@@ -220,7 +216,7 @@ static struct generic_pm_domain *zynqmp_gpd_xlate
 	unsigned int i, idx = genpdspec->args[0];
 	struct zynqmp_pm_domain *pd;
 
-	pd = container_of(genpd_data->domains[0], struct zynqmp_pm_domain, gpd);
+	pd = to_zynqmp_pm_domain(genpd_data->domains[0]);
 
 	if (genpdspec->args_count != 1)
 		return ERR_PTR(-EINVAL);
-- 
2.30.2



From m.tretter at pengutronix.de  Wed Aug 25 08:03:12 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 25 Aug 2021 17:03:12 +0200
Subject: [PATCH v2 3/4] soc: xilinx: use a properly named field instead of
 flags
In-Reply-To: <20210825150313.4033156-1-m.tretter@pengutronix.de>
References: <20210825150313.4033156-1-m.tretter@pengutronix.de>
Message-ID: <20210825150313.4033156-4-m.tretter@pengutronix.de>

Instead of defining a flags field and a single bit in this field to
signal that a PM node has been requested, use a boolean field with a
descriptive name.

No functional change, but using a proper name instead of flags makes the
code easier to read.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/soc/xilinx/zynqmp_pm_domains.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/xilinx/zynqmp_pm_domains.c b/drivers/soc/xilinx/zynqmp_pm_domains.c
index 27c46c68e5cc..53b0041f9fe0 100644
--- a/drivers/soc/xilinx/zynqmp_pm_domains.c
+++ b/drivers/soc/xilinx/zynqmp_pm_domains.c
@@ -20,8 +20,6 @@
 #include <linux/firmware/xlnx-zynqmp.h>
 
 #define ZYNQMP_NUM_DOMAINS		(100)
-/* Flag stating if PM nodes mapped to the PM domain has been requested */
-#define ZYNQMP_PM_DOMAIN_REQUESTED	BIT(0)
 
 static int min_capability;
 
@@ -29,12 +27,12 @@ static int min_capability;
  * struct zynqmp_pm_domain - Wrapper around struct generic_pm_domain
  * @gpd:		Generic power domain
  * @node_id:		PM node ID corresponding to device inside PM domain
- * @flags:		ZynqMP PM domain flags
+ * @requested:		The PM node mapped to the PM domain has been requested
  */
 struct zynqmp_pm_domain {
 	struct generic_pm_domain gpd;
 	u32 node_id;
-	u8 flags;
+	bool requested;
 };
 
 /**
@@ -112,7 +110,7 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)
 	pd = container_of(domain, struct zynqmp_pm_domain, gpd);
 
 	/* If domain is already released there is nothing to be done */
-	if (!(pd->flags & ZYNQMP_PM_DOMAIN_REQUESTED)) {
+	if (!pd->requested) {
 		dev_dbg(&domain->dev, "PM node id %d is already released\n",
 			pd->node_id);
 		return 0;
@@ -177,7 +175,7 @@ static int zynqmp_gpd_attach_dev(struct generic_pm_domain *domain,
 		return ret;
 	}
 
-	pd->flags |= ZYNQMP_PM_DOMAIN_REQUESTED;
+	pd->requested = true;
 
 	dev_dbg(&domain->dev, "%s requested PM node id %d\n",
 		dev_name(dev), pd->node_id);
@@ -209,7 +207,7 @@ static void zynqmp_gpd_detach_dev(struct generic_pm_domain *domain,
 		return;
 	}
 
-	pd->flags &= ~ZYNQMP_PM_DOMAIN_REQUESTED;
+	pd->requested = false;
 
 	dev_dbg(&domain->dev, "%s released PM node id %d\n",
 		dev_name(dev), pd->node_id);
-- 
2.30.2



From m.tretter at pengutronix.de  Wed Aug 25 08:03:10 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 25 Aug 2021 17:03:10 +0200
Subject: [PATCH v2 1/4] soc: xilinx: move PM_INIT_FINALIZE to
 zynqmp_pm_domains driver
In-Reply-To: <20210825150313.4033156-1-m.tretter@pengutronix.de>
References: <20210825150313.4033156-1-m.tretter@pengutronix.de>
Message-ID: <20210825150313.4033156-2-m.tretter@pengutronix.de>

PM_INIT_FINALIZE tells the PMU FW that Linux is able to handle the power
management nodes that are provided by the PMU FW. Nodes that are not
requested are shut down after this call.

Calling PM_INIT_FINALIZE from the zynqmp_power driver is wrong. The PM
node request mechanism is implemented in the zynqmp_pm_domains driver,
which must also call PM_INIT_FINALIZE.

Due to the behavior of the PMU FW, all devices must be powered up before
PM_INIT_FINALIZE is called, because otherwise the devices might
misbehave. Calling PM_INIT_FINALIZE from the sync_state device callback
ensures that all users probed successfully before the PMU FW is allowed
to power off unused domains.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
Changelog:

v2:

- move zynqmp_pm_init_finalize to sync_state callback
---
 drivers/soc/xilinx/zynqmp_pm_domains.c | 16 ++++++++++++++++
 drivers/soc/xilinx/zynqmp_power.c      |  1 -
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/xilinx/zynqmp_pm_domains.c b/drivers/soc/xilinx/zynqmp_pm_domains.c
index 226d343f0a6a..81e8e10f1092 100644
--- a/drivers/soc/xilinx/zynqmp_pm_domains.c
+++ b/drivers/soc/xilinx/zynqmp_pm_domains.c
@@ -152,11 +152,17 @@ static int zynqmp_gpd_power_off(struct generic_pm_domain *domain)
 static int zynqmp_gpd_attach_dev(struct generic_pm_domain *domain,
 				 struct device *dev)
 {
+	struct device_link *link;
 	int ret;
 	struct zynqmp_pm_domain *pd;
 
 	pd = container_of(domain, struct zynqmp_pm_domain, gpd);
 
+	link = device_link_add(dev, &domain->dev, DL_FLAG_SYNC_STATE_ONLY);
+	if (!link)
+		dev_dbg(&domain->dev, "failed to create device link for %s\n",
+			dev_name(dev));
+
 	/* If this is not the first device to attach there is nothing to do */
 	if (domain->device_count)
 		return 0;
@@ -299,9 +305,19 @@ static int zynqmp_gpd_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static void zynqmp_gpd_sync_state(struct device *dev)
+{
+	int ret;
+
+	ret = zynqmp_pm_init_finalize();
+	if (ret)
+		dev_warn(dev, "failed to release power management to firmware\n");
+}
+
 static struct platform_driver zynqmp_power_domain_driver = {
 	.driver	= {
 		.name = "zynqmp_power_controller",
+		.sync_state = zynqmp_gpd_sync_state,
 	},
 	.probe = zynqmp_gpd_probe,
 	.remove = zynqmp_gpd_remove,
diff --git a/drivers/soc/xilinx/zynqmp_power.c b/drivers/soc/xilinx/zynqmp_power.c
index c556623dae02..f8c301984d4f 100644
--- a/drivers/soc/xilinx/zynqmp_power.c
+++ b/drivers/soc/xilinx/zynqmp_power.c
@@ -178,7 +178,6 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
 	u32 pm_api_version;
 	struct mbox_client *client;
 
-	zynqmp_pm_init_finalize();
 	zynqmp_pm_get_api_version(&pm_api_version);
 
 	/* Check PM API version number */
-- 
2.30.2



From m.tretter at pengutronix.de  Wed Aug 25 08:03:09 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 25 Aug 2021 17:03:09 +0200
Subject: [PATCH v2 0/4] soc: xilinx: pm_domains: cleanup and fix
 PM_INIT_FINALIZE
Message-ID: <20210825150313.4033156-1-m.tretter@pengutronix.de>

Hi,

This is v2 of the series to cleanup and fix the zynqmp_pm_domains driver [0].

Patch 1 of this series fixes the ZynqMP PMU FW power management
initialization, which was done by the wrong driver. PM_INIT_FINALIZE must be
called from the zynqmp_pm_domains driver, which handles power domains, instead
of the zynmp_power driver, which is responsible for suspend and shutdown. As a
side effect, PM_INIT_FINALIZE powers down all devices that have not been
requested, which might lead to misbehaving devices. Calling it from the
sync_state callback ensures that all consumers have probed and are able to
handle power management themselves.

Patches 2 to 4 are various cleanup patches to improve the readability and
debugging experience of the zynqmp_pm_domains driver.

Michael

[0] https://lore.kernel.org/linux-arm-kernel/20210317160410.2097178-1-m.tretter at pengutronix.de/

Changelog:

v2:

- move PM_INIT_FINALIZE to sync_state callback

Michael Tretter (4):
  soc: xilinx: move PM_INIT_FINALIZE to zynqmp_pm_domains driver
  soc: xilinx: cleanup debug and error messages
  soc: xilinx: use a properly named field instead of flags
  soc: xilinx: add a to_zynqmp_pm_domain macro

 drivers/soc/xilinx/zynqmp_pm_domains.c | 91 +++++++++++++++-----------
 drivers/soc/xilinx/zynqmp_power.c      |  1 -
 2 files changed, 51 insertions(+), 41 deletions(-)

-- 
2.30.2



From jernej.skrabec at gmail.com  Wed Aug 25 08:03:30 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 25 Aug 2021 17:03:30 +0200
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <20210825145027.ixc7wnh3x5w6wzny@gilmour>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <5432230.1UTMcGJKg4@jernej-laptop> <20210825145027.ixc7wnh3x5w6wzny@gilmour>
Message-ID: <3221818.pD4rYpbbZ1@jernej-laptop>

Dne sreda, 25. avgust 2021 ob 16:50:27 CEST je Maxime Ripard napisal(a):
> Hi,
> 
> On Fri, Aug 20, 2021 at 06:34:38AM +0200, Jernej ?krabec wrote:
> > > > +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> > > > +{
> > > > +	void __iomem *reg;
> > > > +	u32 val;
> > > > +	int i;
> > > > +
> > > > +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > > > +	if (IS_ERR(reg)) {
> > > > +		pr_err("%pOF: Could not map clock registers\n", node);
> > > > +		return;
> > > > +	}
> > > > +
> > > > +	/* Enable the lock bits and the output enable bits on all PLLs */
> > > > +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> > > > +		val = readl(reg + pll_regs[i]);
> > > > +		val |= BIT(29) | BIT(27);
> > > > +		writel(val, reg + pll_regs[i]);
> > > > +	}
> > > > +
> > > > +	/*
> > > > +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> > > > +	 *
> > > > +	 * See the comment before pll-audio1 definition for the reason.
> > > > +	 */
> > > > +
> > > > +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > > +	val &= ~BIT(1);
> > > > +	val |= BIT(0);
> > > > +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > > +
> > > > +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> > > > +	if (i)
> > > > +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> > > > +}
> > > > +
> > > > +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> > > > +	       sun50i_r329_r_ccu_setup);
> > > 
> > > Please make this a platform driver. There is no particular reason why it
> > > needs to be an early OF clock provider.
> > 
> > Why? It's good to have it as early clock provider. It has no dependencies
> > and other drivers that depends on it, like IR, can be deferred, if this
> > is loaded later.
> 
> No, Samuel is right, we should make them regular drivers as much as we
> can.
> 
> The reason we had CLK_OF_DECLARE in the first place is that timers
> usually have a parent clock, and you need the timers before the device
> model is set up.
> 
> Fortunately for us, since the A20, the architected timers don't require
> a parent clock from us, and we can thus boot up fine.

There are other timers. A lot of SoCs, newer than A20 (like H6), have High 
Speed Timer, which requires parent clock to be enabled. We just choose not to 
add node for it to DT, even if it's there and driver already exists.

Best regards,
Jernej

> 
> Since the dependencies are minimal, it should probe fairly early and
> with the on-demand probing from the device links you might not even tell
> the difference for most consumers.
> 
> Maxime






From robh+dt at kernel.org  Wed Aug 25 08:03:51 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 10:03:51 -0500
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <87lf4pa9i0.fsf@tarshish>
References: <cover.1620203062.git.baruch@tkos.co.il>
 <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
 <CAL_JsqKOGo4eXKA7FZK7AQQ24MDDbg2-ngUQF9CJK=8eH_pxHQ@mail.gmail.com>
 <87o89lahqp.fsf@tarshish>
 <CAL_Jsq+wkTbGjyk_i-_1Sad80xcJwAFdf5gBTGBR_TORRA-AoQ@mail.gmail.com>
 <87lf4pa9i0.fsf@tarshish>
Message-ID: <CAL_JsqKLijW0H-f0Ptd3EKrE5mRwtQK5StOTzs3b5UesuuVKdg@mail.gmail.com>

On Wed, Aug 25, 2021 at 9:23 AM Baruch Siach <baruch at tkos.co.il> wrote:
>
> Hi Rob,
>
> On Wed, Aug 25 2021, Rob Herring wrote:
> > On Wed, Aug 25, 2021 at 6:25 AM Baruch Siach <baruch at tkos.co.il> wrote:
> >> On Fri, Aug 06 2021, Rob Herring wrote:
> >> > On Wed, May 5, 2021 at 3:18 AM Baruch Siach <baruch at tkos.co.il> wrote:
> >> >> +       writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> >> >> +                       PCI_EXP_DEVCTL2);
> >> >> +
> >> >> +       writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
> >> >> +                       pci->dbi_base + offset + PCI_EXP_DEVCTL2);
> >> >
> >> > Doesn't this overwrite the prior register write?
> >>
> >> It does. There are two mistakes here. The writel() above should set
> >> PCIE20_DEVICE_CONTROL2_STATUS2 (offset 0x98).
> >
> > No. Did you check what 'offset' is? PCIE20_DEVICE_CONTROL2_STATUS2 is
> > PCI_EXP_DEVCTL2 plus the status reg. What's wrong is it should be a
> > 16-bit write.
>
> Thanks for enlightening me. 'offset' is 0x70 here. So PCI_EXP_DEVCTL2 is
> at 0x98, and PCI_EXP_LNKCTL2 is at 0xa0. Only the second writel() is
> wrong. But since generic code handles speed, I can drop it entirely.
>
> I see that dw_pcie_link_set_max_speed() uses dw_pcie_writel_dbi() to
> write to PCI_EXP_LNKCTL2. Is that 16-bit write?

No, that may be because some platforms can only do 32-bit accesses and
dw_pcie_writew_dbi would be a RMW in that case. Or maybe there's some
reliance on clearing the status register.

> Why are pci_regs.h register offsets in decimal?

No idea...

Rob


From lengxujun2007 at 126.com  Wed Aug 25 08:05:26 2021
From: lengxujun2007 at 126.com (Xujun Leng)
Date: Wed, 25 Aug 2021 23:05:26 +0800
Subject: [PATCH] arm64: mm: fix comment typo of pud_offset_phys()
Message-ID: <20210825150526.12582-1-lengxujun2007@126.com>

Fix a typo in the comment of macro pud_offset_phys().

Signed-off-by: Xujun Leng <lengxujun2007 at 126.com>
---
 arch/arm64/include/asm/pgtable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index f09bf5c02891..dfa76afa0ccf 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -715,7 +715,7 @@ static inline pud_t *p4d_pgtable(p4d_t p4d)
 	return (pud_t *)__va(p4d_page_paddr(p4d));
 }
 
-/* Find an entry in the frst-level page table. */
+/* Find an entry in the first-level page table. */
 #define pud_offset_phys(dir, addr)	(p4d_page_paddr(READ_ONCE(*(dir))) + pud_index(addr) * sizeof(pud_t))
 
 #define pud_set_fixmap(addr)		((pud_t *)set_fixmap_offset(FIX_PUD, addr))
-- 
2.25.1



From drjones at redhat.com  Wed Aug 25 08:07:13 2021
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 25 Aug 2021 17:07:13 +0200
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <87fsuxq049.wl-maz@kernel.org>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org>
Message-ID: <20210825150713.5rpwzm4grfn7akcw@gator.home>

On Wed, Aug 25, 2021 at 11:39:34AM +0100, Marc Zyngier wrote:
> On Wed, 25 Aug 2021 11:02:28 +0100,
> Oliver Upton <oupton at google.com> wrote:
> > 
> > On Wed, Aug 25, 2021 at 2:27 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > Exposing new hypercalls to guests in this manner seems very unsafe to
> > > > me. Suppose an operator is trying to upgrade from kernel N to kernel
> > > > N+1, which brings in the new 'widget' hypercall. Guests are live
> > > > migrated onto the N+1 kernel, but the operator finds a defect that
> > > > warrants a kernel rollback. VMs are then migrated from kernel N+1 -> N.
> > > > Any guests that discovered the 'widget' hypercall are likely going to
> > > > get fussy _very_ quickly on the old kernel.
> > >
> > > This goes against what we decided to support for the *only* publicly
> > > available VMM that cares about save/restore, which is that we only
> > > move forward and don't rollback.
> > 
> > Ah, I was definitely missing this context. Current behavior makes much
> > more sense then.
> > 
> > > Hypercalls are the least of your
> > > worries, and there is a whole range of other architectural features
> > > that will have also appeared/disappeared (your own CNTPOFF series is a
> > > glaring example of this).
> > 
> > Isn't that a tad bit different though? I'll admit, I'm just as guilty
> > with my own series forgetting to add a KVM_CAP (oops), but it is in my
> > queue to kick out with the fix for nVHE/ptimer. Nonetheless, if a user
> > takes up a new KVM UAPI, it is up to the user to run on a new kernel.
> 
> The two are linked. Exposing a new register to userspace and/or guest
> result in the same thing: you can't rollback. That's specially true in
> the QEMU case, which *learns* from the kernel what registers are
> available, and doesn't maintain a fixed list.
> 
> > My concerns are explicitly with the 'under the nose' changes, where
> > KVM modifies the guest feature set without userspace opting in. Based
> > on your comment, though, it would appear that other parts of KVM are
> > affected too.
> 
> Any new system register that is exposed by a new kernel feature breaks
> rollback. And so far, we only consider it a bug if the set of exposed
> registers reduces. Anything can be added safely (as checked by one of
> the selftests added by Drew).
> 
> < It doesn't have to be rollback safety, either. There may
> > simply be a hypercall which an operator doesn't want to give its
> > guests, and it needs a way to tell KVM to hide it.
> 
> Fair enough. But this has to be done in a scalable way, which
> individual capability cannot provide.
> 
> > > > Have I missed something blatantly obvious, or do others see this as an
> > > > issue as well? I'll reply with an example of adding opt-out for PTP.
> > > > I'm sure other hypercalls could be handled similarly.
> > >
> > > Why do we need this? For future hypercalls, we could have some buy-in
> > > capabilities. For existing ones, it is too late, and negative features
> > > are just too horrible.
> > 
> > Oh, agreed on the nastiness. Lazy hack to realize the intended
> > functional change..
> 
> Well, you definitely achieved your goal of attracting my attention :).
> 
> > > For KVM-specific hypercalls, we could get the VMM to save/restore the
> > > bitmap of supported functions. That would be "less horrible". This
> > > could be implemented using extra "firmware pseudo-registers" such as
> > > the ones described in Documentation/virt/kvm/arm/psci.rst.
> > 
> > This seems more reasonable, especially since we do this for migrating
> > the guest's PSCI version.
> > 
> > Alternatively, I had thought about using a VM attribute, given the
> > fact that it is non-architectural information and we avoid ABI issues
> > in KVM_GET_REG_LIST without buy-in through a KVM_CAP.
> 
> The whole point is that these settings get exposed by
> KVM_GET_REG_LIST, as this is QEMU's way to dump a VM state. Given that
> we already have this for things like the spectre management state, we
> can just as well expose the bitmaps that deal with the KVM-specific
> hypercalls. After all, this falls into the realm of "KVM as VM
> firmware".
> 
> For ARM-architected hypercalls (TRNG, stolen time), we may need a
> similar extension.
> 

Thanks for including me Marc. I think you've mentioned all the examples
of why we don't generally expect N+1 -> N migrations to work that I
can think of. While some of the examples like get-reg-list could
eventually be eliminated if we had CPU models to tighten our machine type
state, I think N+1 -> N migrations will always be best effort at most.

I agree with giving userspace control over the exposer of the hypercalls
though. Using pseudo-registers for that purpose rather than a pile of
CAPs also seems reasonable to me.

And, while I don't think this patch is going to proceed, I thought I'd
point out that the opt-out approach doesn't help much with expanding
our migration support unless we require the VMM to be upgraded first.
And, even then, the (N_kern, N+1_vmm) -> (N+1_kern, N_vmm) case won't
work as expected, since the source enforce opt-out, but the destination
won't. Also, since the VMM doesn't key off the kernel version, for the
most part N+1 VMMs won't know when they're supposed to opt-out or not,
leaving it to the user to ensure they consider everything. opt-in
usually only needs the user to consider what machine type they want to
launch.

Thanks,
drew



From houlong.wei at mediatek.com  Wed Aug 25 08:18:17 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Wed, 25 Aug 2021 23:18:17 +0800
Subject: [PATCH v7 7/7] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <0c9fa482-57dd-d4ef-c65b-01f137c57359@collabora.com>
References: <20210825063323.3607738-1-eizan@chromium.org>
 <20210825163247.v7.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <1629880999.12893.17.camel@mhfsdcap03>
 <0c9fa482-57dd-d4ef-c65b-01f137c57359@collabora.com>
Message-ID: <1629904697.15752.11.camel@mhfsdcap03>

On Wed, 2021-08-25 at 17:07 +0800, Enric Balletbo i Serra wrote:
> Hi Houlong,
> 
> Thank you for following up this patchset. I have some questions to try to
> understand better the hardware though.
> 
> On 25/8/21 10:43, houlong wei wrote:
> > Hi Eizan,
> > 
> > Thanks for you patch. I have inline comment below.
> > 
> > Regards,
> > Houlong
> > 
> > On Wed, 2021-08-25 at 14:33 +0800, Eizan Miyamoto wrote:
> >> ... Instead of depending on the presence of a mediatek,vpu property in
> >> the device node.
> >>
> >> That property was originally added to link to the vpu node so that the
> >> mtk_mdp_core driver could pass the right device to
> >> vpu_wdt_reg_handler(). However in a previous patch in this series,
> >> the driver has been modified to search the device tree for that node
> >> instead.
> >>
> >> That property was also used to indicate the primary MDP device, so that
> >> it can be passed to the V4L2 subsystem as well as register it to be
> >> used when setting up queues in the open() callback for the filesystem
> >> device node that is created. In this case, assuming that the primary
> >> MDP device is the one with a specific alias seems useable because the
> >> alternative is to add a property to the device tree which doesn't
> >> actually represent any facet of hardware (i.e., this being the primary
> >> MDP device is a software decision). In other words, this solution is
> >> equally as arbitrary, but at least it doesn't add a property to a
> >> device node where said property is unrelated to the hardware present.
> >>
> >> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> >> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> >> ---
> >>
> >> (no changes since v1)
> >>
> >>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
> >>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
> >>  2 files changed, 64 insertions(+), 28 deletions(-)
> >>
> >> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> >> index 85ef274841a3..9527649de98e 100644
> >> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> >> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> >> @@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
> >>  		mtk_smi_larb_put(comp->larb_dev);
> >>  }
> >>  
> >> -static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
> >> +/*
> >> + * The MDP master device node is identified by the device tree alias
> >> + * "mdp-rdma0".
> >> + */
> >> +static bool is_mdp_master(struct device *dev)
> >> +{
> >> +	struct device_node *aliases, *mdp_rdma0_node;
> >> +	const char *mdp_rdma0_path;
> >> +
> >> +	if (!dev->of_node)
> >> +		return false;
> >> +
> >> +	aliases = of_find_node_by_path("/aliases");
> >> +	if (!aliases) {
> >> +		dev_err(dev, "no aliases found for mdp-rdma0");
> >> +		return false;
> >> +	}
> >> +
> >> +	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
> >> +	if (!mdp_rdma0_path) {
> >> +		dev_err(dev, "get mdp-rdma0 property of /aliases failed");
> >> +		return false;
> >> +	}
> >> +
> >> +	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
> >> +	if (!mdp_rdma0_node) {
> >> +		dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
> >> +		return false;
> >> +	}
> >> +
> >> +	return dev->of_node == mdp_rdma0_node;
> > 
> > 
> > About how to determine the master mdp driver, we also can
> > judge the component type. The component type can be gotten by calling
> > of_device_get_match_data(dev). If the component is MTK_MDP_RDMA, it is
> > the master driver. No matter it is mdp_rdma0 or mdp_rdma1.
> 
> 
> I'm confused, you mean that the component type, aka MTK_MDP_RDMA is only set for
> mtk_mdp_rdma0? isn't mtk_dmp_rdma1 also a MTK_MDP_RDMA type? Because looks weird
> to me that two rdma have diffent types.
> 
Hi Enric,

I can understand your doubts. For mtk-mdp dirver, it is really difficult
to understand the relationship among the components. Because the MDP
hardware path is configured and connected in the VPU firmware.
For MT8173, the component type of mtk_mdp_rdma0 and mtk_mdp_rdma1 are
both MTK_MDP_RDMA. Even though the mtk-mdp driver's component list
contains both of them, only one corresponding hardware component takes
effect during the processing of a frame, the VPU decides it.

Regards,
Houlong
> 
> > http://lists.infradead.org/pipermail/linux-mediatek/2021-August/028533.html
> > 
> > IMO, judging it by component type is more flexible because it does not
> > limit to 'mdp_rdma0'.
> > 
> 
> Using an alias like Eizan did is also flexible, you only need to set mdp-rdma0
> to point the mdp_rdma1 node.
> 
> What I am really interested to know is the differences between the platforms to
> understand if this is really a platform hardware property or a software
> configurable thing, so would help if you can give use the different use cases
> for different SoCs.
> 
> For MT8173 which is the master device? is _always_ rdma0 or can also be rdma1?
> 
> Or maybe what is not clear here is what exactly means be a master device?
> 
> What about MT8183 and other SoCs?
> 
> Thanks,
>   Enric
> 
Hi Enric,

Before answer your questions, let's unify the concept of the master
device.If an MDP device-tree node can not only generate a /dev/video
device node, but also can generate a mtk component device node, then
this component device is the master device.
From the perspective of the device tree node, the compatible of a MDP
device tree node contains both "mediatek,mt8173-mdp-rdma" and
"mediatek,mt8173-mdp", then its corresponding mtk component device is
the master device.
Since this concept comes from Eizan's patches, if my understanding is
different from yours, please let me know, thanks.

If there is only one master device, I fully agree with you. For MT8173,
both mdp_rdma0 and mdp_rdma1 can be master device at the same time.
But now only mdp_rdma0 takes this role, perhaps because one MDP hardware
path could meet the project's the requirement six years ago.
In some project, we have two or more MDP hardware paths, we can
configure all the mdp_rdma components as master devices, and there will
be several /dev/video device nodes. The user can control them
concurrently.

Regards,
Houlong

> 
> >> +}
> >> +
> >> +static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
> >> +			void *data)
> >>  {
> >>  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
> >>  	struct mtk_mdp_dev *mdp = data;
> >> -	struct device_node *vpu_node;
> >>  
> >>  	mtk_mdp_register_component(mdp, comp);
> >>  
> >> -	/*
> >> -	 * If this component has a "mediatek-vpu" property, it is responsible for
> >> -	 * notifying the mdp master driver about it so it can be further initialized
> >> -	 * later.
> >> -	 */
> >> -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> >> -	if (vpu_node) {
> >> +	if (is_mdp_master(dev)) {
> >>  		int ret;
> >>  
> >> -		mdp->vpu_dev = of_find_device_by_node(vpu_node);
> >> -		if (WARN_ON(!mdp->vpu_dev)) {
> >> -			dev_err(dev, "vpu pdev failed\n");
> >> -			of_node_put(vpu_node);
> >> -		}
> >> -
> >>  		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> >>  		if (ret) {
> >>  			dev_err(dev, "Failed to register v4l2 device\n");
> >> @@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
> >>  		}
> >>  
> >>  		/*
> >> -		 * presence of the "mediatek,vpu" property in a device node
> >> -		 * indicates that it is the primary MDP rdma device and MDP DMA
> >> -		 * ops should be handled by its DMA callbacks.
> >> +		 * MDP DMA ops will be handled by the DMA callbacks associated with this
> >> +		 * device;
> >>  		 */
> >>  		mdp->rdma_dev = dev;
> >>  	}
> >> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> >> index 50eafcc9993d..6a775463399c 100644
> >> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> >> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> >> @@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
> >>  
> >>  static int mtk_mdp_master_bind(struct device *dev)
> >>  {
> >> -	int status;
> >>  	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> >> +	struct device_node *vpu_node;
> >> +	int status;
> >>  
> >>  	status = component_bind_all(dev, mdp);
> >>  	if (status) {
> >> @@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
> >>  		goto err_component_bind_all;
> >>  	}
> >>  
> >> -	if (mdp->vpu_dev) {
> >> -		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
> >> -					  VPU_RST_MDP);
> >> -		if (ret) {
> >> -			dev_err(dev, "Failed to register reset handler\n");
> >> -			goto err_wdt_reg;
> >> -		}
> >> -	} else {
> >> -		dev_err(dev, "no vpu_dev found\n");
> >> +	if (mdp->rdma_dev == NULL) {
> >> +		dev_err(dev, "Primary MDP device not found");
> >> +		status = -ENODEV;
> >> +		goto err_component_bind_all;
> >> +	}
> >> +
> >> +	vpu_node = of_find_node_by_name(NULL, "vpu");
> >> +	if (!vpu_node) {
> >> +		dev_err(dev, "unable to find vpu node");
> >> +		status = -ENODEV;
> >> +		goto err_wdt_reg;
> >> +	}
> >> +
> >> +	mdp->vpu_dev = of_find_device_by_node(vpu_node);
> > 
> > The 'vpu_node' should be put by calling 'of_node_put(vpu_node)' when it
> > is not used.
> > 
> >> +	if (!mdp->vpu_dev) {
> >> +		dev_err(dev, "unable to find vpu device");
> >> +		status = -ENODEV;
> >> +		goto err_wdt_reg;
> >> +	}
> >> +
> >> +	status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
> >> +	if (status) {
> >> +		dev_err(dev, "Failed to register reset handler\n");
> >> +		goto err_wdt_reg;
> >>  	}
> >>  
> >>  	status = mtk_mdp_register_m2m_device(mdp);
> > 


From broonie at kernel.org  Wed Aug 25 08:18:44 2021
From: broonie at kernel.org (Mark Brown)
Date: Wed, 25 Aug 2021 16:18:44 +0100
Subject: [PATCH 0/2] regulator: vctrl: Avoid lockdep warning in
 enable/disable ops
In-Reply-To: <20210825033704.3307263-1-wenst@chromium.org>
References: <20210825033704.3307263-1-wenst@chromium.org>
Message-ID: <162990416261.56667.17765131822739903662.b4-ty@kernel.org>

On Wed, 25 Aug 2021 11:37:02 +0800, Chen-Yu Tsai wrote:
> Here are a couple fixes for vctrl-regulator. This driver is only used
> RK3399-based Chromebooks.
> 
> Patch one fixes a misuse of the regulator API, which was found while
> tracing the code to fix the lockdep warning.
> 
> Patch two fixes a lockdep warning and actual (not easy to reproduce)
> deadlock.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[1/2] regulator: vctrl: Use locked regulator_get_voltage in probe path
      commit: 98e47570ba985f2310586c80409238200fa3170f
[2/2] regulator: vctrl: Avoid lockdep warning in enable/disable ops
      commit: 21e39809fd7c4b8ff3662f23e0168e87594c8ca8

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Wed Aug 25 08:09:22 2021
From: broonie at kernel.org (Mark Brown)
Date: Wed, 25 Aug 2021 16:09:22 +0100
Subject: [PATCH 0/2] regulator: vctrl: Avoid lockdep warning in
 enable/disable ops
In-Reply-To: <20210825033704.3307263-1-wenst@chromium.org>
References: <20210825033704.3307263-1-wenst@chromium.org>
Message-ID: <162990416261.56667.17765131822739903662.b4-ty@kernel.org>

On Wed, 25 Aug 2021 11:37:02 +0800, Chen-Yu Tsai wrote:
> Here are a couple fixes for vctrl-regulator. This driver is only used
> RK3399-based Chromebooks.
> 
> Patch one fixes a misuse of the regulator API, which was found while
> tracing the code to fix the lockdep warning.
> 
> Patch two fixes a lockdep warning and actual (not easy to reproduce)
> deadlock.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[1/2] regulator: vctrl: Use locked regulator_get_voltage in probe path
      commit: 98e47570ba985f2310586c80409238200fa3170f
[2/2] regulator: vctrl: Avoid lockdep warning in enable/disable ops
      commit: 21e39809fd7c4b8ff3662f23e0168e87594c8ca8

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From maxime at cerno.tech  Wed Aug 25 08:37:34 2021
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 25 Aug 2021 17:37:34 +0200
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <3221818.pD4rYpbbZ1@jernej-laptop>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <5432230.1UTMcGJKg4@jernej-laptop>
 <20210825145027.ixc7wnh3x5w6wzny@gilmour>
 <3221818.pD4rYpbbZ1@jernej-laptop>
Message-ID: <20210825153734.3cwlufietc63ma3m@gilmour>

On Wed, Aug 25, 2021 at 05:03:30PM +0200, Jernej ?krabec wrote:
> Dne sreda, 25. avgust 2021 ob 16:50:27 CEST je Maxime Ripard napisal(a):
> > Hi,
> > 
> > On Fri, Aug 20, 2021 at 06:34:38AM +0200, Jernej ?krabec wrote:
> > > > > +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
> > > > > +{
> > > > > +	void __iomem *reg;
> > > > > +	u32 val;
> > > > > +	int i;
> > > > > +
> > > > > +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> > > > > +	if (IS_ERR(reg)) {
> > > > > +		pr_err("%pOF: Could not map clock registers\n", node);
> > > > > +		return;
> > > > > +	}
> > > > > +
> > > > > +	/* Enable the lock bits and the output enable bits on all PLLs */
> > > > > +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
> > > > > +		val = readl(reg + pll_regs[i]);
> > > > > +		val |= BIT(29) | BIT(27);
> > > > > +		writel(val, reg + pll_regs[i]);
> > > > > +	}
> > > > > +
> > > > > +	/*
> > > > > +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
> > > > > +	 *
> > > > > +	 * See the comment before pll-audio1 definition for the reason.
> > > > > +	 */
> > > > > +
> > > > > +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > > > +	val &= ~BIT(1);
> > > > > +	val |= BIT(0);
> > > > > +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
> > > > > +
> > > > > +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
> > > > > +	if (i)
> > > > > +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
> > > > > +}
> > > > > +
> > > > > +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
> > > > > +	       sun50i_r329_r_ccu_setup);
> > > > 
> > > > Please make this a platform driver. There is no particular reason why it
> > > > needs to be an early OF clock provider.
> > > 
> > > Why? It's good to have it as early clock provider. It has no dependencies
> > > and other drivers that depends on it, like IR, can be deferred, if this
> > > is loaded later.
> > 
> > No, Samuel is right, we should make them regular drivers as much as we
> > can.
> > 
> > The reason we had CLK_OF_DECLARE in the first place is that timers
> > usually have a parent clock, and you need the timers before the device
> > model is set up.
> > 
> > Fortunately for us, since the A20, the architected timers don't require
> > a parent clock from us, and we can thus boot up fine.
> 
> There are other timers. A lot of SoCs, newer than A20 (like H6), have High 
> Speed Timer, which requires parent clock to be enabled. We just choose not to 
> add node for it to DT, even if it's there and driver already exists.

Yeah, I know. The thing is, we just need one timer in order to boot to
the point where the DM is there. We can totally have a timer driver
probing just like any other driver, through the DM, later on.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210825/b06f5828/attachment-0001.sig>

From baruch at tkos.co.il  Wed Aug 25 07:59:45 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 25 Aug 2021 17:59:45 +0300
Subject: [PATCH v7 3/4] dt-bindings: pwm: add IPQ6018 binding
In-Reply-To: <1629900658.219829.2719822.nullmailer@robh.at.kernel.org>
References: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
 <dbf064fb60b1654af25f65d89f75bd397162d701.1629884907.git.baruch@tkos.co.il>
 <1629900658.219829.2719822.nullmailer@robh.at.kernel.org>
Message-ID: <87ilzta5xn.fsf@tarshish>

Hi Rob,

On Wed, Aug 25 2021, Rob Herring wrote:

> On Wed, 25 Aug 2021 12:48:26 +0300, Baruch Siach wrote:
>> DT binding for the PWM block in Qualcomm IPQ6018 SoC.
>> 
>> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
>> ---
>> v7:
>> 
>>   Use 'reg' instead of 'offset' (Rob)
>> 
>>   Drop 'clock-names' and 'assigned-clock*' (Bjorn)
>> 
>>   Use single cell address/size in example node (Bjorn)
>> 
>>   Move '#pwm-cells' lower in example node (Bjorn)
>> 
>>   List 'reg' as required
>> 
>> v6:
>> 
>>   Device node is child of TCSR; remove phandle (Rob Herring)
>> 
>>   Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)
>> 
>> v5: Use qcom,pwm-regs for phandle instead of direct regs (Bjorn
>>     Andersson, Kathiravan T)
>> 
>> v4: Update the binding example node as well (Rob Herring's bot)
>> 
>> v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
>> 
>> v2: Make #pwm-cells const (Rob Herring)
>> ---
>>  .../devicetree/bindings/pwm/ipq-pwm.yaml      | 52 +++++++++++++++++++
>>  1 file changed, 52 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/pwm/ipq-pwm.example.dt.yaml:0:0:
> /example-0/syscon at 1937000: failed to match any schema with compatible:
> ['qcom,tcsr-ipq6018', 'syscon', 'simple-mfd']

What can I do about that? Is it because qcom,tcsr-ipq6018 is documented
in a non-yaml plain .txt file?

Thanks,
baruch

> doc reference errors (make refcheckdocs):
>
> See https://patchwork.ozlabs.org/patch/1520591
>
> This check can fail if there are any dependencies. The base for a patch
> series is generally the most recent rc1.
>
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
>
> pip3 install dtschema --upgrade
>
> Please check and re-submit.

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From joro at 8bytes.org  Wed Aug 25 08:43:51 2021
From: joro at 8bytes.org (Joerg Roedel)
Date: Wed, 25 Aug 2021 17:43:51 +0200
Subject: [PATCH] iommu/io-pgtable: Abstract iommu_iotlb_gather access
In-Reply-To: <ad5ae140-6398-a2d2-ed90-2d59cab01f0f@arm.com>
References: <83672ee76f6405c82845a55c148fa836f56fbbc1.1629465282.git.robin.murphy@arm.com>
 <CAMuHMdXL7ZtY8kBx=RHsRy1JECsGPDe+E3SM=--w7bUHMYHFBQ@mail.gmail.com>
 <ad5ae140-6398-a2d2-ed90-2d59cab01f0f@arm.com>
Message-ID: <YSZlN6vnv77cJPFJ@8bytes.org>

On Tue, Aug 24, 2021 at 04:33:16PM +0100, Robin Murphy wrote:
> > Tested-by: Geert Uytterhoeven <geert+renesas at glider.be>
> 
> Thanks for confirming!

Sorry for the delay, the new tree containing this fix has been pushed
out now.


From robh at kernel.org  Wed Aug 25 08:45:54 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 10:45:54 -0500
Subject: [PATCH v7 3/4] dt-bindings: pwm: add IPQ6018 binding
In-Reply-To: <dbf064fb60b1654af25f65d89f75bd397162d701.1629884907.git.baruch@tkos.co.il>
References: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
 <dbf064fb60b1654af25f65d89f75bd397162d701.1629884907.git.baruch@tkos.co.il>
Message-ID: <YSZlsgRYqDSwnjPw@robh.at.kernel.org>

On Wed, Aug 25, 2021 at 12:48:26PM +0300, Baruch Siach wrote:
> DT binding for the PWM block in Qualcomm IPQ6018 SoC.
> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
> v7:
> 
>   Use 'reg' instead of 'offset' (Rob)
> 
>   Drop 'clock-names' and 'assigned-clock*' (Bjorn)
> 
>   Use single cell address/size in example node (Bjorn)
> 
>   Move '#pwm-cells' lower in example node (Bjorn)
> 
>   List 'reg' as required
> 
> v6:
> 
>   Device node is child of TCSR; remove phandle (Rob Herring)
> 
>   Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)
> 
> v5: Use qcom,pwm-regs for phandle instead of direct regs (Bjorn
>     Andersson, Kathiravan T)
> 
> v4: Update the binding example node as well (Rob Herring's bot)
> 
> v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
> 
> v2: Make #pwm-cells const (Rob Herring)
> ---
>  .../devicetree/bindings/pwm/ipq-pwm.yaml      | 52 +++++++++++++++++++
>  1 file changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml b/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> new file mode 100644
> index 000000000000..edfec41e77e5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> @@ -0,0 +1,52 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pwm/ipq-pwm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm IPQ6018 PWM controller
> +
> +maintainers:
> +  - Baruch Siach <baruch at tkos.co.il>
> +
> +properties:
> +  "#pwm-cells":
> +    const: 2
> +
> +  compatible:
> +    const: qcom,ipq6018-pwm
> +
> +  reg:
> +    description: Offset of PWM register in the TCSR block.
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - "#pwm-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/qcom,gcc-ipq6018.h>
> +
> +    tcsr: syscon at 1937000 {
> +        compatible = "qcom,tcsr-ipq6018", "syscon", "simple-mfd";

This needs to be documented. Some visibility into what else is in this 
block would be nice so we can make some informed decisions as to what 
all this should look like.

> +        reg = <0x01937000 0x21000>;
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        pwm: pwm at a010 {
> +            compatible = "qcom,ipq6018-pwm";
> +            reg = <0xa010>;

There's not a length associated with the PWM registers.

> +            clocks = <&gcc GCC_ADSS_PWM_CLK>;
> +            assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
> +            assigned-clock-rates = <100000000>;
> +            #pwm-cells = <2>;
> +        };
> +    };
> -- 
> 2.32.0
> 
> 


From helgaas at kernel.org  Wed Aug 25 09:05:16 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 25 Aug 2021 11:05:16 -0500
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <CAL_JsqKLijW0H-f0Ptd3EKrE5mRwtQK5StOTzs3b5UesuuVKdg@mail.gmail.com>
Message-ID: <20210825160516.GA3576414@bjorn-Precision-5520>

On Wed, Aug 25, 2021 at 10:03:51AM -0500, Rob Herring wrote:
> On Wed, Aug 25, 2021 at 9:23 AM Baruch Siach <baruch at tkos.co.il> wrote:

> > Why are pci_regs.h register offsets in decimal?
> 
> No idea...

That does seem confusing and error prone.  I'd merge a patch that made
them hex to match the spec.


From cki-project at redhat.com  Wed Aug 25 09:07:38 2021
From: cki-project at redhat.com (CKI Project)
Date: Wed, 25 Aug 2021 16:07:38 -0000
Subject: =?utf-8?b?4pyF?= PASS: Test report for kernel 5.14.0-rc7 (arm-next,
 988c09ad)
Message-ID: <cki.AE52099001.4C2HEPMKTN@redhat.com>


Hello,

We ran automated tests on a recent commit from this kernel tree:

       Kernel repo: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
            Commit: 988c09add519 - Merge branch 'for-next/fixes' into for-kernelci

The results of these automated tests are provided below.

    Overall result: PASSED
             Merge: OK
           Compile: OK
             Tests: OK

All kernel binaries, config files, and logs are available for download here:

  https://arr-cki-prod-datawarehouse-public.s3.amazonaws.com/index.html?prefix=datawarehouse-public/2021/08/25/359182226

Please reply to this email if you have any questions about the tests that we
ran or if you have any suggestions on how to make future tests more effective.

        ,-.   ,-.
       ( C ) ( K )  Continuous
        `-',-.`-'   Kernel
          ( I )     Integration
           `-'
______________________________________________________________________________

Compile testing
---------------

We compiled the kernel for 1 architecture:

    aarch64:
      make options: make -j24 INSTALL_MOD_STRIP=1 targz-pkg



Hardware testing
----------------
We booted each kernel and ran the following tests:

  aarch64:
    Host 1:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ??? ACPI table test
       ??? ACPI enabled test
       ??? LTP
       ??? CIFS Connectathon
       ??? POSIX pjd-fstest suites
       ??? Loopdev Sanity
       ??? jvm - jcstress tests
       ??? Memory: fork_mem
       ??? Memory function: memfd_create
       ??? AMTU (Abstract Machine Test Utility)
       ??? Networking bridge: sanity
       ??? Ethernet drivers sanity
       ??? Networking socket: fuzz
       ??? Networking: igmp conformance test
       ??? Networking route: pmtu
       ??? Networking route_func - local
       ??? Networking route_func - forward
       ??? Networking TCP: keepalive test
       ??? Networking UDP: socket
       ??? Networking cki netfilter test
       ??? Networking tunnel: geneve basic test
       ??? Networking tunnel: gre basic
       ??? L2TP basic test
       ??? Networking tunnel: vxlan basic
       ??? Networking ipsec: basic netns - transport
       ??? Networking ipsec: basic netns - tunnel
       ??? Libkcapi AF_ALG test
       ??? pciutils: update pci ids test
       ??? ALSA PCM loopback test
       ??? ALSA Control (mixer) Userspace Element test
       ??? storage: SCSI VPD
       ??? trace: ftrace/tracer
       ? ??? xarray-idr-radixtree-test
       ? ??? i2c: i2cdetect sanity
       ? ??? NFS Connectathon
       ? ??? Firmware test suite
       ? ??? Memory function: kaslr
       ? ??? audit: audit testsuite test
       ? ??? lvm cache test
       ? ??? lvm snapper test

    Host 2:
       ? Boot test
       ? Reboot test
       ? xfstests - ext4
       ? xfstests - xfs
       ? selinux-policy: serge-testsuite
       ? Storage blktests
       ? storage: software RAID testing
       ? Storage: swraid mdadm raid_module test
       ? ? Podman system integration test - as root
       ? ? Podman system integration test - as user
       ? ? xfstests - btrfs
       ? ? IPMI driver test
       ? ? IPMItool loop stress test
       ? ? Storage block - filesystem fio test
       ? ? Storage block - queue scheduler test
       ? ? Storage nvme - tcp
       ? ? stress: stress-ng

    Host 3:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ??? ACPI table test
       ??? ACPI enabled test
       ??? LTP
       ??? CIFS Connectathon
       ??? POSIX pjd-fstest suites
       ??? Loopdev Sanity
       ??? jvm - jcstress tests
       ??? Memory: fork_mem
       ??? Memory function: memfd_create
       ??? AMTU (Abstract Machine Test Utility)
       ??? Networking bridge: sanity
       ??? Ethernet drivers sanity
       ??? Networking socket: fuzz
       ??? Networking: igmp conformance test
       ??? Networking route: pmtu
       ??? Networking route_func - local
       ??? Networking route_func - forward
       ??? Networking TCP: keepalive test
       ??? Networking UDP: socket
       ??? Networking cki netfilter test
       ??? Networking tunnel: geneve basic test
       ??? Networking tunnel: gre basic
       ??? L2TP basic test
       ??? Networking tunnel: vxlan basic
       ??? Networking ipsec: basic netns - transport
       ??? Networking ipsec: basic netns - tunnel
       ??? Libkcapi AF_ALG test
       ??? pciutils: update pci ids test
       ??? ALSA PCM loopback test
       ??? ALSA Control (mixer) Userspace Element test
       ??? storage: SCSI VPD
       ??? trace: ftrace/tracer
       ? ??? xarray-idr-radixtree-test
       ? ??? i2c: i2cdetect sanity
       ? ??? NFS Connectathon
       ? ??? Firmware test suite
       ? ??? Memory function: kaslr
       ? ??? audit: audit testsuite test
       ? ??? lvm cache test
       ? ??? lvm snapper test

    Host 4:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ??? ACPI table test
       ??? ACPI enabled test
       ??? LTP
       ??? CIFS Connectathon
       ??? POSIX pjd-fstest suites
       ??? Loopdev Sanity
       ??? jvm - jcstress tests
       ??? Memory: fork_mem
       ??? Memory function: memfd_create
       ??? AMTU (Abstract Machine Test Utility)
       ??? Networking bridge: sanity
       ??? Ethernet drivers sanity
       ??? Networking socket: fuzz
       ??? Networking: igmp conformance test
       ??? Networking route: pmtu
       ??? Networking route_func - local
       ??? Networking route_func - forward
       ??? Networking TCP: keepalive test
       ??? Networking UDP: socket
       ??? Networking cki netfilter test
       ??? Networking tunnel: geneve basic test
       ??? Networking tunnel: gre basic
       ??? L2TP basic test
       ??? Networking tunnel: vxlan basic
       ??? Networking ipsec: basic netns - transport
       ??? Networking ipsec: basic netns - tunnel
       ??? Libkcapi AF_ALG test
       ??? pciutils: update pci ids test
       ??? ALSA PCM loopback test
       ??? ALSA Control (mixer) Userspace Element test
       ??? storage: SCSI VPD
       ??? trace: ftrace/tracer
       ? ??? xarray-idr-radixtree-test
       ? ??? i2c: i2cdetect sanity
       ? ??? NFS Connectathon
       ? ??? Firmware test suite
       ? ??? Memory function: kaslr
       ? ??? audit: audit testsuite test
       ? ??? lvm cache test
       ? ??? lvm snapper test

  Test sources: https://gitlab.com/cki-project/kernel-tests
    ? Pull requests are welcome for new tests or improvements to existing tests!

Aborted tests
-------------
Tests that didn't complete running successfully are marked with ???.
If this was caused by an infrastructure issue, we try to mark that
explicitly in the report.

Waived tests
------------
If the test run included waived tests, they are marked with ?. Such tests are
executed but their results are not taken into account. Tests are waived when
their results are not reliable enough, e.g. when they're just introduced or are
being fixed.

Testing timeout
---------------
We aim to provide a report within reasonable timeframe. Tests that haven't
finished running yet are marked with ?.



From robh at kernel.org  Wed Aug 25 09:12:47 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 11:12:47 -0500
Subject: [PATCH v7 3/4] dt-bindings: pwm: add IPQ6018 binding
In-Reply-To: <87ilzta5xn.fsf@tarshish>
References: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
 <dbf064fb60b1654af25f65d89f75bd397162d701.1629884907.git.baruch@tkos.co.il>
 <1629900658.219829.2719822.nullmailer@robh.at.kernel.org>
 <87ilzta5xn.fsf@tarshish>
Message-ID: <YSZr/xo2a60PYTuW@robh.at.kernel.org>

On Wed, Aug 25, 2021 at 05:59:45PM +0300, Baruch Siach wrote:
> Hi Rob,
> 
> On Wed, Aug 25 2021, Rob Herring wrote:
> 
> > On Wed, 25 Aug 2021 12:48:26 +0300, Baruch Siach wrote:
> >> DT binding for the PWM block in Qualcomm IPQ6018 SoC.
> >> 
> >> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> >> ---
> >> v7:
> >> 
> >>   Use 'reg' instead of 'offset' (Rob)
> >> 
> >>   Drop 'clock-names' and 'assigned-clock*' (Bjorn)
> >> 
> >>   Use single cell address/size in example node (Bjorn)
> >> 
> >>   Move '#pwm-cells' lower in example node (Bjorn)
> >> 
> >>   List 'reg' as required
> >> 
> >> v6:
> >> 
> >>   Device node is child of TCSR; remove phandle (Rob Herring)
> >> 
> >>   Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)
> >> 
> >> v5: Use qcom,pwm-regs for phandle instead of direct regs (Bjorn
> >>     Andersson, Kathiravan T)
> >> 
> >> v4: Update the binding example node as well (Rob Herring's bot)
> >> 
> >> v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
> >> 
> >> v2: Make #pwm-cells const (Rob Herring)
> >> ---
> >>  .../devicetree/bindings/pwm/ipq-pwm.yaml      | 52 +++++++++++++++++++
> >>  1 file changed, 52 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> >
> > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> > on your patch (DT_CHECKER_FLAGS is new in v5.13):
> >
> > yamllint warnings/errors:
> >
> > dtschema/dtc warnings/errors:
> > Documentation/devicetree/bindings/pwm/ipq-pwm.example.dt.yaml:0:0:
> > /example-0/syscon at 1937000: failed to match any schema with compatible:
> > ['qcom,tcsr-ipq6018', 'syscon', 'simple-mfd']
> 
> What can I do about that? Is it because qcom,tcsr-ipq6018 is documented
> in a non-yaml plain .txt file?

No, it is not documented at all.

Rob


From nm at ti.com  Wed Aug 25 09:15:02 2021
From: nm at ti.com (Nishanth Menon)
Date: Wed, 25 Aug 2021 11:15:02 -0500
Subject: [PATCH v2] ARM: dts: da850-evm: Change aemif node status from
 "ok" to "okay"
In-Reply-To: <20210824105512.19242-1-rogerq@kernel.org>
References: <20210824105512.19242-1-rogerq@kernel.org>
Message-ID: <20210825161502.ap2clalwfljezoqk@perfume>

On 13:55-20210824, Roger Quadros wrote:
> As per Device Tree Specification [1], the status parameter of nodes can
> be "okay", "disabled", etc. "ok" is not a valid parameter.
> 
> U-boot Driver Model does not recognize status="ok" either and treats
> the node as disabled.

^^ the above comment might be fine to indicate the side effect of
non-compliance

> 
> [1] https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>

Reviewed-by: Nishanth Menon <nm at ti.com>

> ---
> Changelog:
> v2
> -refer to DT spec instead of schema in commit log.
> 
>  arch/arm/boot/dts/da850-evm.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
> index 87c517d65f62..9dc79b5977bf 100644
> --- a/arch/arm/boot/dts/da850-evm.dts
> +++ b/arch/arm/boot/dts/da850-evm.dts
> @@ -415,7 +415,7 @@
>  &aemif {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&nand_pins>;
> -	status = "ok";
> +	status = "okay";
>  	cs3 {
>  		#address-cells = <2>;
>  		#size-cells = <1>;
> -- 
> 2.17.1
> 

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From alexandru.elisei at arm.com  Wed Aug 25 09:17:37 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:37 +0100
Subject: [RFC PATCH v4 01/39] KVM: arm64: Make lock_all_vcpus() available to
 the rest of KVM
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-2-alexandru.elisei@arm.com>

The VGIC code uses the lock_all_vcpus() function to make sure no VCPUs are
run while it fiddles with the global VGIC state. Move the declaration of
lock_all_vcpus() and the corresponding unlock function into asm/kvm_host.h
where it can be reused by other parts of KVM/arm64 and rename the functions
to kvm_{lock,unlock}_all_vcpus() to make them more generic.

Because the scope of the code potentially using the functions has
increased, add a lockdep check that the kvm->lock is held by the caller.
Holding the lock is necessary because otherwise userspace would be able to
create new VCPUs and run them while the existing VCPUs are locked.

No functional change intended.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h     |  3 ++
 arch/arm64/kvm/arm.c                  | 41 ++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic-init.c       |  4 +--
 arch/arm64/kvm/vgic/vgic-its.c        |  8 ++---
 arch/arm64/kvm/vgic/vgic-kvm-device.c | 50 ++++-----------------------
 arch/arm64/kvm/vgic/vgic.h            |  3 --
 6 files changed, 56 insertions(+), 53 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 41911585ae0c..797083203603 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -601,6 +601,9 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
 void kvm_arm_halt_guest(struct kvm *kvm);
 void kvm_arm_resume_guest(struct kvm *kvm);
 
+bool kvm_lock_all_vcpus(struct kvm *kvm);
+void kvm_unlock_all_vcpus(struct kvm *kvm);
+
 #ifndef __KVM_NVHE_HYPERVISOR__
 #define kvm_call_hyp_nvhe(f, ...)						\
 	({								\
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..ddace63528f1 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -647,6 +647,47 @@ void kvm_arm_resume_guest(struct kvm *kvm)
 	}
 }
 
+/* unlocks vcpus from @vcpu_lock_idx and smaller */
+static void unlock_vcpus(struct kvm *kvm, int vcpu_lock_idx)
+{
+	struct kvm_vcpu *tmp_vcpu;
+
+	for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) {
+		tmp_vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx);
+		mutex_unlock(&tmp_vcpu->mutex);
+	}
+}
+
+void kvm_unlock_all_vcpus(struct kvm *kvm)
+{
+	lockdep_assert_held(&kvm->lock);
+	unlock_vcpus(kvm, atomic_read(&kvm->online_vcpus) - 1);
+}
+
+/* Returns true if all vcpus were locked, false otherwise */
+bool kvm_lock_all_vcpus(struct kvm *kvm)
+{
+	struct kvm_vcpu *tmp_vcpu;
+	int c;
+
+	lockdep_assert_held(&kvm->lock);
+
+	/*
+	 * Any time a vcpu is run, vcpu_load is called which tries to grab the
+	 * vcpu->mutex.  By grabbing the vcpu->mutex of all VCPUs we ensure that
+	 * no other VCPUs are run and it is safe to fiddle with KVM global
+	 * state.
+	 */
+	kvm_for_each_vcpu(c, tmp_vcpu, kvm) {
+		if (!mutex_trylock(&tmp_vcpu->mutex)) {
+			unlock_vcpus(kvm, c - 1);
+			return false;
+		}
+	}
+
+	return true;
+}
+
 static void vcpu_req_sleep(struct kvm_vcpu *vcpu)
 {
 	struct rcuwait *wait = kvm_arch_vcpu_get_wait(vcpu);
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index 340c51d87677..6a85aa064a6c 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -87,7 +87,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
 		return -ENODEV;
 
 	ret = -EBUSY;
-	if (!lock_all_vcpus(kvm))
+	if (!kvm_lock_all_vcpus(kvm))
 		return ret;
 
 	kvm_for_each_vcpu(i, vcpu, kvm) {
@@ -117,7 +117,7 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
 		INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions);
 
 out_unlock:
-	unlock_all_vcpus(kvm);
+	kvm_unlock_all_vcpus(kvm);
 	return ret;
 }
 
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 61728c543eb9..3a336a678cb8 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -2005,7 +2005,7 @@ static int vgic_its_attr_regs_access(struct kvm_device *dev,
 		goto out;
 	}
 
-	if (!lock_all_vcpus(dev->kvm)) {
+	if (!kvm_lock_all_vcpus(dev->kvm)) {
 		ret = -EBUSY;
 		goto out;
 	}
@@ -2023,7 +2023,7 @@ static int vgic_its_attr_regs_access(struct kvm_device *dev,
 	} else {
 		*reg = region->its_read(dev->kvm, its, addr, len);
 	}
-	unlock_all_vcpus(dev->kvm);
+	kvm_unlock_all_vcpus(dev->kvm);
 out:
 	mutex_unlock(&dev->kvm->lock);
 	return ret;
@@ -2668,7 +2668,7 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
 	mutex_lock(&kvm->lock);
 	mutex_lock(&its->its_lock);
 
-	if (!lock_all_vcpus(kvm)) {
+	if (!kvm_lock_all_vcpus(kvm)) {
 		mutex_unlock(&its->its_lock);
 		mutex_unlock(&kvm->lock);
 		return -EBUSY;
@@ -2686,7 +2686,7 @@ static int vgic_its_ctrl(struct kvm *kvm, struct vgic_its *its, u64 attr)
 		break;
 	}
 
-	unlock_all_vcpus(kvm);
+	kvm_unlock_all_vcpus(kvm);
 	mutex_unlock(&its->its_lock);
 	mutex_unlock(&kvm->lock);
 	return ret;
diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
index 7740995de982..c2f95d124cbc 100644
--- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
+++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
@@ -298,44 +298,6 @@ int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,
 	return 0;
 }
 
-/* unlocks vcpus from @vcpu_lock_idx and smaller */
-static void unlock_vcpus(struct kvm *kvm, int vcpu_lock_idx)
-{
-	struct kvm_vcpu *tmp_vcpu;
-
-	for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) {
-		tmp_vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx);
-		mutex_unlock(&tmp_vcpu->mutex);
-	}
-}
-
-void unlock_all_vcpus(struct kvm *kvm)
-{
-	unlock_vcpus(kvm, atomic_read(&kvm->online_vcpus) - 1);
-}
-
-/* Returns true if all vcpus were locked, false otherwise */
-bool lock_all_vcpus(struct kvm *kvm)
-{
-	struct kvm_vcpu *tmp_vcpu;
-	int c;
-
-	/*
-	 * Any time a vcpu is run, vcpu_load is called which tries to grab the
-	 * vcpu->mutex.  By grabbing the vcpu->mutex of all VCPUs we ensure
-	 * that no other VCPUs are run and fiddle with the vgic state while we
-	 * access it.
-	 */
-	kvm_for_each_vcpu(c, tmp_vcpu, kvm) {
-		if (!mutex_trylock(&tmp_vcpu->mutex)) {
-			unlock_vcpus(kvm, c - 1);
-			return false;
-		}
-	}
-
-	return true;
-}
-
 /**
  * vgic_v2_attr_regs_access - allows user space to access VGIC v2 state
  *
@@ -366,7 +328,7 @@ static int vgic_v2_attr_regs_access(struct kvm_device *dev,
 	if (ret)
 		goto out;
 
-	if (!lock_all_vcpus(dev->kvm)) {
+	if (!kvm_lock_all_vcpus(dev->kvm)) {
 		ret = -EBUSY;
 		goto out;
 	}
@@ -383,7 +345,7 @@ static int vgic_v2_attr_regs_access(struct kvm_device *dev,
 		break;
 	}
 
-	unlock_all_vcpus(dev->kvm);
+	kvm_unlock_all_vcpus(dev->kvm);
 out:
 	mutex_unlock(&dev->kvm->lock);
 	return ret;
@@ -532,7 +494,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
 		goto out;
 	}
 
-	if (!lock_all_vcpus(dev->kvm)) {
+	if (!kvm_lock_all_vcpus(dev->kvm)) {
 		ret = -EBUSY;
 		goto out;
 	}
@@ -582,7 +544,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
 		break;
 	}
 
-	unlock_all_vcpus(dev->kvm);
+	kvm_unlock_all_vcpus(dev->kvm);
 out:
 	mutex_unlock(&dev->kvm->lock);
 	return ret;
@@ -637,12 +599,12 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
 		case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES:
 			mutex_lock(&dev->kvm->lock);
 
-			if (!lock_all_vcpus(dev->kvm)) {
+			if (!kvm_lock_all_vcpus(dev->kvm)) {
 				mutex_unlock(&dev->kvm->lock);
 				return -EBUSY;
 			}
 			ret = vgic_v3_save_pending_tables(dev->kvm);
-			unlock_all_vcpus(dev->kvm);
+			kvm_unlock_all_vcpus(dev->kvm);
 			mutex_unlock(&dev->kvm->lock);
 			return ret;
 		}
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index dc1f3d1657ee..0511618c89f6 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -252,9 +252,6 @@ int vgic_init(struct kvm *kvm);
 void vgic_debug_init(struct kvm *kvm);
 void vgic_debug_destroy(struct kvm *kvm);
 
-bool lock_all_vcpus(struct kvm *kvm);
-void unlock_all_vcpus(struct kvm *kvm);
-
 static inline int vgic_v3_max_apr_idx(struct kvm_vcpu *vcpu)
 {
 	struct vgic_cpu *cpu_if = &vcpu->arch.vgic_cpu;
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:36 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:36 +0100
Subject: [RFC PATCH v4 00/39] KVM: arm64: Add Statistical Profiling Extension
 (SPE) support
Message-ID: <20210825161815.266051-1-alexandru.elisei@arm.com>

This is v4 of the SPE series posted at [1]. v2 can be found at [2], and the
original series at [3].

Statistical Profiling Extension (SPE) is an optional feature added in
ARMv8.2. It allows sampling at regular intervals of the operations executed
by the PE and storing a record of each operation in a memory buffer. A high
level overview of the extension is presented in an article on arm.com [4].

This is another complete rewrite of the series, and nothing is set in
stone. If you think of a better way to do things, please suggest it.


Features added
==============

The rewrite enabled me to add support for several features not
present in the previous iteration:

- Support for heterogeneous systems, where only some of the CPUs support SPE.
  This is accomplished via the KVM_ARM_VCPU_SUPPORTED_CPUS VCPU ioctl.

- Support for VM migration with the KVM_ARM_VCPU_SPE_CTRL(KVM_ARM_VCPU_SPE_STOP)
  VCPU ioctl.

- The requirement for userspace to mlock() the guest memory has been removed,
  and now userspace can make changes to memory contents after the memory is
  mapped at stage 2.

- Better debugging of guest memory pinning by printing a warning when we
  get an unexpected read or write fault. This helped me catch several bugs
  during development, it has already proven very useful. Many thanks to
  James who suggested when reviewing v3.


Missing features
================

I've tried to keep the series as small as possible to make it easier to review,
while implementing the core functionality needed for the SPE emulation. As such,
I've chosen to not implement several features:

- Host profiling a guest which has the SPE feature bit set (see open
  questions).

- No errata workarounds have been implemented yet, and there are quite a few of
  them for Neoverse N1 and Neoverse V1.

- Disabling CONFIG_NUMA_BALANCING is a hack to get KVM SPE to work and I am
  investigating other ways to get around automatic numa balancing, like
  requiring userspace to disable it via set_mempolicy(). I am also going to
  look at how VFIO gets around it. Suggestions welcome.

- There's plenty of room for optimization. Off the top of my head, using
  block mappings at stage 2, batch pinning of pages (similar to what VFIO
  does), optimize the way KVM keeps track of pinned pages (using a linked
  list triples the memory usage), context-switch the SPE registers on
  vcpu_load/vcpu_put on VHE if the host is not profiling, locking
  optimizations, etc, etc.

- ...and others. I'm sure I'm missing at least a few things which are
  important for someone.


Known issues
============

This is an RFC, so keep in mind that almost definitely there will be scary
bugs. For example, below is a list of known issues which don't affect the
correctness of the emulation, and which I'm planning to fix in a future
iteration:

- With CONFIG_PROVE_LOCKING=y, lockdep complains about lock contention when
  the VCPU executes the dcache clean pending ops.

- With CONFIG_PROVE_LOCKING=y, KVM will hit a BUG at
  kvm_lock_all_vcpus()->mutex_trylock(&vcpu->mutex) with more than 48
  VCPUs.

This BUG statement can also be triggered with mainline. To reproduce it,
compile kvmtool from this branch [5] and follow the instruction in the
kvmtool commit message.

One workaround could be to stop trying to lock all VCPUs when locking a
memslot and document the fact that it is required that no VCPUs are run
before the ioctl completes, otherwise bad things might happen to the VM.


Open questions
==============

1. Implementing support for host profiling a guest with the SPE feature
means setting the profiling buffer owning regime to EL2. While that is in
effect,  PMBIDR_EL1.P will equal 1. This has two consequences: if the guest
probes SPE during this time, the driver will fail; and the guest will be
able to determine when it is profiled. I see two options here:

- Do not allow the host's userspace to profile a guest where at least one
  VCPU has SPE.

- Document the effects somewhere and let userspace do whatever it likes.

No preference for either.

2. Userspace is not allowed to profile a CPU event (not bound to a task) is
!perf_allow_cpu(). It is my understanding that this is because of security
reasons, as we don't want a task to profile another task. Because a VM
will only be able to profile itself, I don't think it's necessary to
restrict the VM in any way based on perf_allow_cpu(), like we do with
perfmon_capable() and physical timer timestamps.

3. How to handle guest triggered SPE SErrors. Right now the Linux SPE drivers
doesn't do anything special SErrors reported by SPE, and I've done the same when
a guest manages to trigger one. Should I do something more? Disabling SPE
emulation for the entire VM is one option.


Summary of the patches
======================

Below is a short summary of the patches. For a more detailed explanation of
how SPE works, please see version 3 of the series [1].

Patches 1-11 implement the memslot locking functionality.

Patch 12 implements the KVM_ARM_VCPU_SUPPORTED_CPUS ioctl.

Patches 13-14 are preparatory for KVM SPE.

Patches 15-19 makes it possible for KVM to deny running a SPE enabled VCPU
on CPUs which don't have the SPE hardware.

Patches 20-22 add the userspace interface to configure SPE.

Patches 23-32 implement context switching of the SPE registers.

Patch 33 allows a guest to use physical timestamps only if the VMM is
perfmon_capable().

Patch 34 add the emulation for the SPE buffer management interrupts.

Patches 35-37 add the userspace API to temprorarily stop profiling so
memory can be unlocked and the VM migrated.

Patch 38 is a hack to get KVM SPE emulation going on NUMA systems (like the
Altra server which I used for testing).

Patch 39 finally enables SPE.


Testing
=======

Testing was done on Altra server with two sockets, both populated.

The Linux patches are based on v5.14-rc5 and can also be found on gitlab
[6].

For testing, I've used an SPE enabled version of kvmtool, which can be
found at [7]; the kvmtool patches will also be sent upstream. To test the
SPE_STOP API, I used a special version of kvmtool which starts the guest in
one of the stopped states; that can be found at [8] (compile from a
different commit if a different state and/or transition is desired).

Finally, in the VM I used defconfig Linux guest compiled from v5.15-rc5 and
some kvm-unit-tests patches which I wrote to test SPE [9].

All tests were run three times: once with VHE enabled, once in NVHE mode
(kvm-arm.mode=nvhe) and once in protected mode (kvm-arm.mode=protected).

The first test that I ran was the kvm-unit-tests test. This is also the
test that I used to check that KVM_ARM_VCPU_SPE_STOP_{TRAP,EXIT,RESUME}
works correctly with kvmtool.

Then I profiled iperf3 in the guest (16 VCPUs to limit the size of perf.data,
32GiB memory), while concurrently profiling in the host. This is the command
that I used:

# perf record -ae arm_spe/ts_enable=1,pa_enable=1,pct_enable=1/ -- iperf3 -c 127.0.0.1 -t 30

Everything looked right to me and I didn't see any kernel warnings or bugs.

[1] https://lore.kernel.org/linux-arm-kernel/20201027172705.15181-1-alexandru.elisei at arm.com/
[2] https://www.spinics.net/lists/arm-kernel/msg776228.html
[3] https://lists.cs.columbia.edu/pipermail/kvmarm/2019-February/034887.html
[4] https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/statistical-profiling-extension-for-armv8-a
[5] https://gitlab.arm.com/linux-arm/kvmtool-ae/-/tree/vgic-lock-all-vcpus-lockdep-bug-v1
[6] https://gitlab.arm.com/linux-arm/linux-ae/-/tree/kvm-spe-v4
[7] https://gitlab.arm.com/linux-arm/kvmtool-ae/-/tree/kvm-spe-v4
[8] https://gitlab.arm.com/linux-arm/kvmtool-ae/-/tree/kvm-spe-v4-spe-stop-tests
[9] https://gitlab.arm.com/linux-arm/kvm-unit-tests-ae/-/tree/kvm-spe-v4

Alexandru Elisei (35):
  KVM: arm64: Make lock_all_vcpus() available to the rest of KVM
  KVM: arm64: Add lock/unlock memslot user API
  KVM: arm64: Implement the memslot lock/unlock functionality
  KVM: arm64: Defer CMOs for locked memslots until a VCPU is run
  KVM: arm64: Perform CMOs on locked memslots when userspace resets
    VCPUs
  KVM: arm64: Delay tag scrubbing for locked memslots until a VCPU runs
  KVM: arm64: Unlock memslots after stage 2 tables are freed
  KVM: arm64: Deny changes to locked memslots
  KVM: Add kvm_warn{,_ratelimited} macros
  KVM: arm64: Print a warning for unexpected faults on locked memslots
  KVM: arm64: Allow userspace to lock and unlock memslots
  KVM: arm64: Add the KVM_ARM_VCPU_SUPPORTED_CPUS VCPU ioctl
  KVM: arm64: Add CONFIG_KVM_ARM_SPE Kconfig option
  KVM: arm64: Add SPE capability and VCPU feature
  drivers/perf: Expose the cpumask of CPUs that support SPE
  KVM: arm64: Make SPE available when at least one CPU supports it
  KVM: arm64: Set the VCPU SPE feature bit when SPE is available
  KVM: arm64: Expose SPE version to guests
  KVM: arm64: Do not emulate SPE on CPUs which don't have SPE
  KVM: arm64: debug: Configure MDCR_EL2 when a VCPU has SPE
  KVM: arm64: Move the write to MDCR_EL2 out of
    __activate_traps_common()
  KVM: arm64: VHE: Change MDCR_EL2 at world switch if VCPU has SPE
  KVM: arm64: Add SPE system registers to VCPU context
  KVM: arm64: nVHE: Save PMSCR_EL1 to the host context
  KVM: arm64: Rename DEBUG_STATE_SAVE_SPE -> DEBUG_SAVE_SPE_BUFFER flags
  KVM: arm64: nVHE: Context switch SPE state if VCPU has SPE
  KVM: arm64: VHE: Context switch SPE state if VCPU has SPE
  KVM: arm64: Save/restore PMSNEVFR_EL1 on VCPU put/load
  KVM: arm64: Allow guest to use physical timestamps if
    perfmon_capable()
  KVM: arm64: Emulate SPE buffer management interrupt
  KVM: arm64: Add an userspace API to stop a VCPU profiling
  KVM: arm64: Implement userspace API to stop a VCPU profiling
  KVM: arm64: Add PMSIDR_EL1 to the SPE register context
  KVM: arm64: Make CONFIG_KVM_ARM_SPE depend on !CONFIG_NUMA_BALANCING
  KVM: arm64: Allow userspace to enable SPE for guests

Sudeep Holla (4):
  KVM: arm64: Add a new VCPU device control group for SPE
  KVM: arm64: Add SPE VCPU device attribute to set the interrupt number
  KVM: arm64: Add SPE VCPU device attribute to initialize SPE
  KVM: arm64: VHE: Clear MDCR_EL2.E2PB in vcpu_put()

 Documentation/virt/kvm/api.rst          |  87 ++++-
 Documentation/virt/kvm/devices/vcpu.rst |  76 ++++
 arch/arm64/include/asm/kvm_arm.h        |   1 +
 arch/arm64/include/asm/kvm_host.h       |  75 +++-
 arch/arm64/include/asm/kvm_hyp.h        |  51 ++-
 arch/arm64/include/asm/kvm_mmu.h        |   8 +
 arch/arm64/include/asm/kvm_spe.h        |  96 ++++++
 arch/arm64/include/asm/sysreg.h         |   3 +
 arch/arm64/include/uapi/asm/kvm.h       |  11 +
 arch/arm64/kvm/Kconfig                  |   8 +
 arch/arm64/kvm/Makefile                 |   1 +
 arch/arm64/kvm/arm.c                    | 140 +++++++-
 arch/arm64/kvm/debug.c                  |  55 ++-
 arch/arm64/kvm/guest.c                  |  10 +
 arch/arm64/kvm/hyp/include/hyp/spe-sr.h |  32 ++
 arch/arm64/kvm/hyp/include/hyp/switch.h |   1 -
 arch/arm64/kvm/hyp/nvhe/Makefile        |   1 +
 arch/arm64/kvm/hyp/nvhe/debug-sr.c      |  24 +-
 arch/arm64/kvm/hyp/nvhe/spe-sr.c        | 133 +++++++
 arch/arm64/kvm/hyp/nvhe/switch.c        |  35 +-
 arch/arm64/kvm/hyp/vhe/Makefile         |   1 +
 arch/arm64/kvm/hyp/vhe/spe-sr.c         | 193 +++++++++++
 arch/arm64/kvm/hyp/vhe/switch.c         |  43 ++-
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c      |   2 +-
 arch/arm64/kvm/mmu.c                    | 441 +++++++++++++++++++++++-
 arch/arm64/kvm/reset.c                  |  23 ++
 arch/arm64/kvm/spe.c                    | 381 ++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c               |  77 ++++-
 arch/arm64/kvm/vgic/vgic-init.c         |   4 +-
 arch/arm64/kvm/vgic/vgic-its.c          |   8 +-
 arch/arm64/kvm/vgic/vgic-kvm-device.c   |  50 +--
 arch/arm64/kvm/vgic/vgic.h              |   3 -
 drivers/perf/arm_spe_pmu.c              |  30 +-
 include/linux/kvm_host.h                |   4 +
 include/linux/perf/arm_pmu.h            |   7 +
 include/uapi/linux/kvm.h                |  13 +
 36 files changed, 1983 insertions(+), 145 deletions(-)
 create mode 100644 arch/arm64/include/asm/kvm_spe.h
 create mode 100644 arch/arm64/kvm/hyp/include/hyp/spe-sr.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/spe-sr.c
 create mode 100644 arch/arm64/kvm/hyp/vhe/spe-sr.c
 create mode 100644 arch/arm64/kvm/spe.c

-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:38 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:38 +0100
Subject: [RFC PATCH v4 02/39] KVM: arm64: Add lock/unlock memslot user API
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-3-alexandru.elisei@arm.com>

Stage 2 faults triggered by the profiling buffer attempting to write to
memory are reported by the SPE hardware by asserting a buffer management
event interrupt. Interrupts are by their nature asynchronous, which means
that the guest might have changed its stage 1 translation tables since the
attempted write. SPE reports the guest virtual address that caused the data
abort, not the IPA, which means that KVM would have to walk the guest's
stage 1 tables to find the IPA. Using the AT instruction to walk the
guest's tables in hardware is not an option because it doesn't report the
IPA in the case of a stage 2 fault on a stage 1 table walk.

Avoid both issues by pre-mapping the guest memory at stage 2. This is being
done by adding a capability that allows the user to pin the memory backing
a memslot. The same capability can be used to unlock a memslot, which
unpins the pages associated with the memslot, but doesn't unmap the IPA
range from stage 2; in this case, the addresses will be unmapped from stage
2 via the MMU notifiers when the process' address space changes.

For now, the capability doesn't actually do anything other than checking
that the usage is correct; the memory operations will be added in future
patches.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/api.rst   | 56 +++++++++++++++++++++++
 arch/arm64/include/asm/kvm_mmu.h |  3 ++
 arch/arm64/kvm/arm.c             | 42 ++++++++++++++++--
 arch/arm64/kvm/mmu.c             | 76 ++++++++++++++++++++++++++++++++
 include/uapi/linux/kvm.h         |  8 ++++
 5 files changed, 181 insertions(+), 4 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index dae68e68ca23..741327ef06b0 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6682,6 +6682,62 @@ MAP_SHARED mmap will result in an -EINVAL return.
 When enabled the VMM may make use of the ``KVM_ARM_MTE_COPY_TAGS`` ioctl to
 perform a bulk copy of tags to/from the guest.
 
+7.29 KVM_CAP_ARM_LOCK_USER_MEMORY_REGION
+----------------------------------------
+
+:Architectures: arm64
+:Target: VM
+:Parameters: flags is one of KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_LOCK or
+                     KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_UNLOCK
+             args[0] is the slot number
+             args[1] specifies the permisions when the memslot is locked or if
+                     all memslots should be unlocked
+
+The presence of this capability indicates that KVM supports locking the memory
+associated with the memslot, and unlocking a previously locked memslot.
+
+The 'flags' parameter is defined as follows:
+
+7.29.1 KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_LOCK
+-------------------------------------------------
+
+:Capability: 'flags' parameter to KVM_CAP_ARM_LOCK_USER_MEMORY_REGION
+:Architectures: arm64
+:Target: VM
+:Parameters: args[0] contains the memory slot number
+             args[1] contains the permissions for the locked memory:
+                     KVM_ARM_LOCK_MEMORY_READ (mandatory) to map it with
+                     read permissions and KVM_ARM_LOCK_MEMORY_WRITE
+                     (optional) with write permissions
+:Returns: 0 on success; negative error code on failure
+
+Enabling this capability causes the memory described by the memslot to be
+pinned in the process address space and the corresponding stage 2 IPA range
+mapped at stage 2. The permissions specified in args[1] apply to both
+mappings. The memory pinned with this capability counts towards the max
+locked memory limit for the current process.
+
+The capability must be enabled before any VCPUs have run. The virtual memory
+range described by the memslot must be mapped in the userspace process without
+any gaps. It is considered an error if write permissions are specified for a
+memslot which logs dirty pages.
+
+7.29.2 KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_UNLOCK
+---------------------------------------------------
+
+:Capability: 'flags' parameter to KVM_CAP_ARM_LOCK_USER_MEMORY_REGION
+:Architectures: arm64
+:Target: VM
+:Parameters: args[0] contains the memory slot number
+             args[1] optionally contains the flag KVM_ARM_UNLOCK_MEM_ALL,
+                     which unlocks all previously locked memslots.
+:Returns: 0 on success; negative error code on failure
+
+Enabling this capability causes the memory pinned when locking the memslot
+specified in args[0] to be unpinned, or, optionally, the memory associated
+with all locked memslots, to be unpinned. The IPA range is not unmapped
+from stage 2.
+
 8. Other capabilities.
 ======================
 
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index b52c5c4b9a3d..ef079b5eb475 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -216,6 +216,9 @@ static inline void __invalidate_icache_guest_page(void *va, size_t size)
 void kvm_set_way_flush(struct kvm_vcpu *vcpu);
 void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
 
+int kvm_mmu_lock_memslot(struct kvm *kvm, u64 slot, u64 flags);
+int kvm_mmu_unlock_memslot(struct kvm *kvm, u64 slot, u64 flags);
+
 static inline unsigned int kvm_get_vmid_bits(void)
 {
 	int reg = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index ddace63528f1..57ac97b30b3d 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -80,16 +80,43 @@ int kvm_arch_check_processor_compat(void *opaque)
 	return 0;
 }
 
+static int kvm_arm_lock_memslot_supported(void)
+{
+	return 0;
+}
+
+static int kvm_lock_user_memory_region_ioctl(struct kvm *kvm,
+					     struct kvm_enable_cap *cap)
+{
+	u64 slot, flags;
+	u32 action;
+
+	if (cap->args[2] || cap->args[3])
+		return -EINVAL;
+
+	slot = cap->args[0];
+	flags = cap->args[1];
+	action = cap->flags;
+
+	switch (action) {
+	case KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_LOCK:
+		return kvm_mmu_lock_memslot(kvm, slot, flags);
+	case KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_UNLOCK:
+		return kvm_mmu_unlock_memslot(kvm, slot, flags);
+	default:
+		return -EINVAL;
+	}
+}
+
 int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 			    struct kvm_enable_cap *cap)
 {
 	int r;
 
-	if (cap->flags)
-		return -EINVAL;
-
 	switch (cap->cap) {
 	case KVM_CAP_ARM_NISV_TO_USER:
+		if (cap->flags)
+			return -EINVAL;
 		r = 0;
 		kvm->arch.return_nisv_io_abort_to_user = true;
 		break;
@@ -99,6 +126,11 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 		r = 0;
 		kvm->arch.mte_enabled = true;
 		break;
+	case KVM_CAP_ARM_LOCK_USER_MEMORY_REGION:
+		if (!kvm_arm_lock_memslot_supported())
+			return -EINVAL;
+		r = kvm_lock_user_memory_region_ioctl(kvm, cap);
+		break;
 	default:
 		r = -EINVAL;
 		break;
@@ -166,7 +198,6 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
 	return VM_FAULT_SIGBUS;
 }
 
-
 /**
  * kvm_arch_destroy_vm - destroy the VM data structure
  * @kvm:	pointer to the KVM struct
@@ -274,6 +305,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_PTRAUTH_GENERIC:
 		r = system_has_full_ptr_auth();
 		break;
+	case KVM_CAP_ARM_LOCK_USER_MEMORY_REGION:
+		r = kvm_arm_lock_memslot_supported();
+		break;
 	default:
 		r = 0;
 	}
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 0625bf2353c2..689b24cb0f10 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1244,6 +1244,82 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	return ret;
 }
 
+int kvm_mmu_lock_memslot(struct kvm *kvm, u64 slot, u64 flags)
+{
+	struct kvm_memory_slot *memslot;
+	struct kvm_vcpu *vcpu;
+	int i, ret;
+
+	if (slot >= KVM_MEM_SLOTS_NUM)
+		return -EINVAL;
+
+	if (!(flags & KVM_ARM_LOCK_MEM_READ))
+		return -EINVAL;
+
+	mutex_lock(&kvm->lock);
+
+	if (!kvm_lock_all_vcpus(kvm)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		if (vcpu->arch.has_run_once) {
+			ret = -EBUSY;
+			goto out_unlock_vcpus;
+		}
+	}
+
+	mutex_lock(&kvm->slots_lock);
+
+	memslot = id_to_memslot(kvm_memslots(kvm), slot);
+	if (!memslot) {
+		ret = -EINVAL;
+		goto out_unlock_slots;
+	}
+	if ((flags & KVM_ARM_LOCK_MEM_WRITE) &&
+	    ((memslot->flags & KVM_MEM_READONLY) || memslot->dirty_bitmap)) {
+		ret = -EPERM;
+		goto out_unlock_slots;
+	}
+
+	ret = -EINVAL;
+
+out_unlock_slots:
+	mutex_unlock(&kvm->slots_lock);
+out_unlock_vcpus:
+	kvm_unlock_all_vcpus(kvm);
+out:
+	mutex_unlock(&kvm->lock);
+	return ret;
+}
+
+int kvm_mmu_unlock_memslot(struct kvm *kvm, u64 slot, u64 flags)
+{
+	struct kvm_memory_slot *memslot;
+	int ret;
+
+	if (flags & KVM_ARM_UNLOCK_MEM_ALL)
+		return -EINVAL;
+
+	if (slot >= KVM_MEM_SLOTS_NUM)
+		return -EINVAL;
+
+	mutex_lock(&kvm->slots_lock);
+
+	memslot = id_to_memslot(kvm_memslots(kvm), slot);
+	if (!memslot) {
+		ret = -EINVAL;
+		goto out_unlock_slots;
+	}
+
+	ret = -EINVAL;
+
+out_unlock_slots:
+	mutex_unlock(&kvm->slots_lock);
+	return ret;
+}
+
 bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
 {
 	if (!kvm->arch.mmu.pgt)
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index d9e4aabcb31a..bcf62c7bdd2d 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1112,6 +1112,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_BINARY_STATS_FD 203
 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
 #define KVM_CAP_ARM_MTE 205
+#define KVM_CAP_ARM_LOCK_USER_MEMORY_REGION 206
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1459,6 +1460,13 @@ struct kvm_s390_ucas_mapping {
 #define KVM_PPC_SVM_OFF		  _IO(KVMIO,  0xb3)
 #define KVM_ARM_MTE_COPY_TAGS	  _IOR(KVMIO,  0xb4, struct kvm_arm_copy_mte_tags)
 
+/* Used by KVM_CAP_ARM_LOCK_USER_MEMORY_REGION */
+#define KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_LOCK	(1 << 0)
+#define   KVM_ARM_LOCK_MEM_READ				(1 << 0)
+#define   KVM_ARM_LOCK_MEM_WRITE			(1 << 1)
+#define KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_UNLOCK	(1 << 1)
+#define   KVM_ARM_UNLOCK_MEM_ALL			(1 << 0)
+
 /* ioctl for vm fd */
 #define KVM_CREATE_DEVICE	  _IOWR(KVMIO,  0xe0, struct kvm_create_device)
 
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:39 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:39 +0100
Subject: [RFC PATCH v4 03/39] KVM: arm64: Implement the memslot lock/unlock
 functionality
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-4-alexandru.elisei@arm.com>

Pin memory in the process address space and map it in the stage 2 tables as
a result of userspace enabling the KVM_CAP_ARM_LOCK_USER_MEMORY_REGION
capability; and unpin it from the process address space when the capability
is used with the KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_UNLOCK flag.

The current implementation has two drawbacks which will be fixed in future
patches:

- The dcache maintenance is done when the memslot is locked, which means
  that it is possible that memory changes made by userspace after the ioctl
  completes won't be visible to a guest running with the MMU off.

- Tag scrubbing is done when the memslot is locked. If the MTE capability
  is enabled after the ioctl, the guest will be able to access unsanitised
  pages. This is prevented by forbidding userspace to enable the MTE
  capability if any memslots are locked.

Only PAGE_SIZE mappings are supported at stage 2.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/api.rst    |   8 +-
 arch/arm64/include/asm/kvm_host.h |  11 ++
 arch/arm64/kvm/arm.c              |  22 ++++
 arch/arm64/kvm/mmu.c              | 211 +++++++++++++++++++++++++++++-
 4 files changed, 245 insertions(+), 7 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 741327ef06b0..5aa251df7077 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6717,10 +6717,10 @@ mapped at stage 2. The permissions specified in args[1] apply to both
 mappings. The memory pinned with this capability counts towards the max
 locked memory limit for the current process.
 
-The capability must be enabled before any VCPUs have run. The virtual memory
-range described by the memslot must be mapped in the userspace process without
-any gaps. It is considered an error if write permissions are specified for a
-memslot which logs dirty pages.
+The capability must be enabled before any VCPUs have run. The entire virtual
+memory range described by the memslot must be mapped by the userspace process.
+It is considered an error if write permissions are specified for a memslot which
+logs dirty pages.
 
 7.29.2 KVM_ARM_LOCK_USER_MEMORY_REGION_FLAGS_UNLOCK
 ---------------------------------------------------
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 797083203603..97ff3ed5d4b7 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -98,7 +98,18 @@ struct kvm_s2_mmu {
 	struct kvm_arch *arch;
 };
 
+#define KVM_MEMSLOT_LOCK_READ		(1 << 0)
+#define KVM_MEMSLOT_LOCK_WRITE		(1 << 1)
+#define KVM_MEMSLOT_LOCK_MASK		0x3
+
+struct kvm_memory_slot_page {
+	struct list_head list;
+	struct page *page;
+};
+
 struct kvm_arch_memory_slot {
+	struct kvm_memory_slot_page pages;
+	u32 flags;
 };
 
 struct kvm_arch {
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 57ac97b30b3d..efb3501c6016 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -108,6 +108,25 @@ static int kvm_lock_user_memory_region_ioctl(struct kvm *kvm,
 	}
 }
 
+static bool kvm_arm_has_locked_memslots(struct kvm *kvm)
+{
+	struct kvm_memslots *slots = kvm_memslots(kvm);
+	struct kvm_memory_slot *memslot;
+	bool has_locked_memslots = false;
+	int idx;
+
+	idx = srcu_read_lock(&kvm->srcu);
+	kvm_for_each_memslot(memslot, slots) {
+		if (memslot->arch.flags & KVM_MEMSLOT_LOCK_MASK) {
+			has_locked_memslots = true;
+			break;
+		}
+	}
+	srcu_read_unlock(&kvm->srcu, idx);
+
+	return has_locked_memslots;
+}
+
 int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 			    struct kvm_enable_cap *cap)
 {
@@ -123,6 +142,9 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 	case KVM_CAP_ARM_MTE:
 		if (!system_supports_mte() || kvm->created_vcpus)
 			return -EINVAL;
+		if (kvm_arm_lock_memslot_supported() &&
+		    kvm_arm_has_locked_memslots(kvm))
+			return -EPERM;
 		r = 0;
 		kvm->arch.mte_enabled = true;
 		break;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 689b24cb0f10..59c2bfef2fd1 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -72,6 +72,11 @@ static bool memslot_is_logging(struct kvm_memory_slot *memslot)
 	return memslot->dirty_bitmap && !(memslot->flags & KVM_MEM_READONLY);
 }
 
+static bool memslot_is_locked(struct kvm_memory_slot *memslot)
+{
+	return memslot->arch.flags & KVM_MEMSLOT_LOCK_MASK;
+}
+
 /**
  * kvm_flush_remote_tlbs() - flush all VM TLB entries for v7/8
  * @kvm:	pointer to kvm structure.
@@ -722,6 +727,10 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
 	if (map_size == PAGE_SIZE)
 		return true;
 
+	/* Allow only PAGE_SIZE mappings for locked memslots */
+	if (memslot_is_locked(memslot))
+		return false;
+
 	size = memslot->npages * PAGE_SIZE;
 
 	gpa_start = memslot->base_gfn << PAGE_SHIFT;
@@ -1244,6 +1253,159 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	return ret;
 }
 
+static int try_rlimit_memlock(unsigned long npages)
+{
+	unsigned long lock_limit;
+	bool has_lock_cap;
+	int ret = 0;
+
+	has_lock_cap = capable(CAP_IPC_LOCK);
+	if (has_lock_cap)
+		goto out;
+
+	lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+
+	mmap_read_lock(current->mm);
+	if (npages + current->mm->locked_vm > lock_limit)
+		ret = -ENOMEM;
+	mmap_read_unlock(current->mm);
+
+out:
+	return ret;
+}
+
+static void unpin_memslot_pages(struct kvm_memory_slot *memslot, bool writable)
+{
+	struct kvm_memory_slot_page *entry, *tmp;
+
+	list_for_each_entry_safe(entry, tmp, &memslot->arch.pages.list, list) {
+		if (writable)
+			set_page_dirty_lock(entry->page);
+		unpin_user_page(entry->page);
+		kfree(entry);
+	}
+}
+
+static int lock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot,
+			u64 flags)
+{
+	struct kvm_mmu_memory_cache cache = { 0, __GFP_ZERO, NULL, };
+	struct kvm_memory_slot_page *page_entry;
+	bool writable = flags & KVM_ARM_LOCK_MEM_WRITE;
+	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
+	struct kvm_pgtable *pgt = kvm->arch.mmu.pgt;
+	struct vm_area_struct *vma;
+	unsigned long npages = memslot->npages;
+	unsigned int pin_flags = FOLL_LONGTERM;
+	unsigned long i, hva, ipa, mmu_seq;
+	int ret;
+
+	ret = try_rlimit_memlock(npages);
+	if (ret)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&memslot->arch.pages.list);
+
+	if (writable) {
+		prot |= KVM_PGTABLE_PROT_W;
+		pin_flags |= FOLL_WRITE;
+	}
+
+	hva = memslot->userspace_addr;
+	ipa = memslot->base_gfn << PAGE_SHIFT;
+
+	mmu_seq = kvm->mmu_notifier_seq;
+	smp_rmb();
+
+	for (i = 0; i < npages; i++) {
+		page_entry = kzalloc(sizeof(*page_entry), GFP_KERNEL);
+		if (!page_entry) {
+			unpin_memslot_pages(memslot, writable);
+			ret = -ENOMEM;
+			goto out_err;
+		}
+
+		mmap_read_lock(current->mm);
+		ret = pin_user_pages(hva, 1, pin_flags, &page_entry->page, &vma);
+		if (ret != 1) {
+			mmap_read_unlock(current->mm);
+			unpin_memslot_pages(memslot, writable);
+			ret = -ENOMEM;
+			goto out_err;
+		}
+		if (kvm_has_mte(kvm)) {
+			if (vma->vm_flags & VM_SHARED) {
+				ret = -EFAULT;
+			} else {
+				ret = sanitise_mte_tags(kvm,
+					page_to_pfn(page_entry->page),
+					PAGE_SIZE);
+			}
+			if (ret) {
+				mmap_read_unlock(current->mm);
+				goto out_err;
+			}
+		}
+		mmap_read_unlock(current->mm);
+
+		ret = kvm_mmu_topup_memory_cache(&cache, kvm_mmu_cache_min_pages(kvm));
+		if (ret) {
+			unpin_memslot_pages(memslot, writable);
+			goto out_err;
+		}
+
+		spin_lock(&kvm->mmu_lock);
+		if (mmu_notifier_retry(kvm, mmu_seq)) {
+			spin_unlock(&kvm->mmu_lock);
+			unpin_memslot_pages(memslot, writable);
+			ret = -EAGAIN;
+			goto out_err;
+		}
+
+		ret = kvm_pgtable_stage2_map(pgt, ipa, PAGE_SIZE,
+					     page_to_phys(page_entry->page),
+					     prot, &cache);
+		spin_unlock(&kvm->mmu_lock);
+
+		if (ret) {
+			kvm_pgtable_stage2_unmap(pgt, memslot->base_gfn << PAGE_SHIFT,
+						 i << PAGE_SHIFT);
+			unpin_memslot_pages(memslot, writable);
+			goto out_err;
+		}
+		list_add(&page_entry->list, &memslot->arch.pages.list);
+
+		hva += PAGE_SIZE;
+		ipa += PAGE_SIZE;
+	}
+
+
+	/*
+	 * Even though we've checked the limit at the start, we can still exceed
+	 * it if userspace locked other pages in the meantime or if the
+	 * CAP_IPC_LOCK capability has been revoked.
+	 */
+	ret = account_locked_vm(current->mm, npages, true);
+	if (ret) {
+		kvm_pgtable_stage2_unmap(pgt, memslot->base_gfn << PAGE_SHIFT,
+					 npages << PAGE_SHIFT);
+		unpin_memslot_pages(memslot, writable);
+		goto out_err;
+	}
+
+	memslot->arch.flags = KVM_MEMSLOT_LOCK_READ;
+	if (writable)
+		memslot->arch.flags |= KVM_MEMSLOT_LOCK_WRITE;
+
+	kvm_mmu_free_memory_cache(&cache);
+
+	return 0;
+
+out_err:
+	kvm_mmu_free_memory_cache(&cache);
+	return ret;
+}
+
 int kvm_mmu_lock_memslot(struct kvm *kvm, u64 slot, u64 flags)
 {
 	struct kvm_memory_slot *memslot;
@@ -1283,7 +1445,12 @@ int kvm_mmu_lock_memslot(struct kvm *kvm, u64 slot, u64 flags)
 		goto out_unlock_slots;
 	}
 
-	ret = -EINVAL;
+	if (memslot_is_locked(memslot)) {
+		ret = -EBUSY;
+		goto out_unlock_slots;
+	}
+
+	ret = lock_memslot(kvm, memslot, flags);
 
 out_unlock_slots:
 	mutex_unlock(&kvm->slots_lock);
@@ -1294,13 +1461,51 @@ int kvm_mmu_lock_memslot(struct kvm *kvm, u64 slot, u64 flags)
 	return ret;
 }
 
+static int unlock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot)
+{
+	bool writable = memslot->arch.flags & KVM_MEMSLOT_LOCK_WRITE;
+	unsigned long npages = memslot->npages;
+
+	unpin_memslot_pages(memslot, writable);
+	account_locked_vm(current->mm, npages, false);
+
+	memslot->arch.flags &= ~KVM_MEMSLOT_LOCK_MASK;
+
+	return 0;
+}
+
+static int unlock_all_memslots(struct kvm *kvm)
+{
+	struct kvm_memory_slot *memslot;
+	int err, ret;
+
+	mutex_lock(&kvm->slots_lock);
+
+	ret = 0;
+	kvm_for_each_memslot(memslot, kvm_memslots(kvm)) {
+		if (!memslot_is_locked(memslot))
+			continue;
+		err = unlock_memslot(kvm, memslot);
+		if (err) {
+			kvm_err("error unlocking memslot %u: %d\n",
+				memslot->id, err);
+			/* Continue to try unlocking the rest of the slots */
+			ret = err;
+		}
+	}
+
+	mutex_unlock(&kvm->slots_lock);
+
+	return ret;
+}
+
 int kvm_mmu_unlock_memslot(struct kvm *kvm, u64 slot, u64 flags)
 {
 	struct kvm_memory_slot *memslot;
 	int ret;
 
 	if (flags & KVM_ARM_UNLOCK_MEM_ALL)
-		return -EINVAL;
+		return unlock_all_memslots(kvm);
 
 	if (slot >= KVM_MEM_SLOTS_NUM)
 		return -EINVAL;
@@ -1313,7 +1518,7 @@ int kvm_mmu_unlock_memslot(struct kvm *kvm, u64 slot, u64 flags)
 		goto out_unlock_slots;
 	}
 
-	ret = -EINVAL;
+	ret = unlock_memslot(kvm, memslot);
 
 out_unlock_slots:
 	mutex_unlock(&kvm->slots_lock);
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:40 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:40 +0100
Subject: [RFC PATCH v4 04/39] KVM: arm64: Defer CMOs for locked memslots until
 a VCPU is run
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-5-alexandru.elisei@arm.com>

KVM relies on doing dcache maintenance on stage 2 faults to present to a
gueste running with the MMU off the same view of memory as userspace. For
locked memslots, KVM so far has done the dcache maintenance when a memslot
is locked, but that leaves KVM in a rather awkward position: what userspace
writes to guest memory after the memslot is locked, but before a VCPU is
run, might not be visible to the guest.

Fix this by deferring the dcache maintenance until the first VCPU is run.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  7 ++++
 arch/arm64/include/asm/kvm_mmu.h  |  5 +++
 arch/arm64/kvm/arm.c              |  3 ++
 arch/arm64/kvm/mmu.c              | 56 ++++++++++++++++++++++++++++---
 4 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 97ff3ed5d4b7..ed67f914d169 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -112,6 +112,10 @@ struct kvm_arch_memory_slot {
 	u32 flags;
 };
 
+/* kvm->arch.mmu_pending_ops flags */
+#define KVM_LOCKED_MEMSLOT_FLUSH_DCACHE	0
+#define KVM_MAX_MMU_PENDING_OPS		1
+
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
@@ -135,6 +139,9 @@ struct kvm_arch {
 	 */
 	bool return_nisv_io_abort_to_user;
 
+	/* Defer MMU operations until a VCPU is run. */
+	unsigned long mmu_pending_ops;
+
 	/*
 	 * VM-wide PMU filter, implemented as a bitmap and big enough for
 	 * up to 2^10 events (ARMv8.0) or 2^16 events (ARMv8.1+).
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index ef079b5eb475..525c223e769f 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -219,6 +219,11 @@ void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
 int kvm_mmu_lock_memslot(struct kvm *kvm, u64 slot, u64 flags);
 int kvm_mmu_unlock_memslot(struct kvm *kvm, u64 slot, u64 flags);
 
+#define kvm_mmu_has_pending_ops(kvm)	\
+	(!bitmap_empty(&(kvm)->arch.mmu_pending_ops, KVM_MAX_MMU_PENDING_OPS))
+
+void kvm_mmu_perform_pending_ops(struct kvm *kvm);
+
 static inline unsigned int kvm_get_vmid_bits(void)
 {
 	int reg = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index efb3501c6016..144c982912d8 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -829,6 +829,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 	if (unlikely(!kvm_vcpu_initialized(vcpu)))
 		return -ENOEXEC;
 
+	if (unlikely(kvm_mmu_has_pending_ops(vcpu->kvm)))
+		kvm_mmu_perform_pending_ops(vcpu->kvm);
+
 	ret = kvm_vcpu_first_run_init(vcpu);
 	if (ret)
 		return ret;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 59c2bfef2fd1..94fa08f3d9d3 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1253,6 +1253,41 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	return ret;
 }
 
+/*
+ * It's safe to do the CMOs when the first VCPU is run because:
+ * - VCPUs cannot run until mmu_cmo_needed is cleared.
+ * - Memslots cannot be modified because we hold the kvm->slots_lock.
+ *
+ * It's safe to periodically release the mmu_lock because:
+ * - VCPUs cannot run.
+ * - Any changes to the stage 2 tables triggered by the MMU notifiers also take
+ *   the mmu_lock, which means accesses will be serialized.
+ * - Stage 2 tables cannot be freed from under us as long as at least one VCPU
+ *   is live, which means that the VM will be live.
+ */
+void kvm_mmu_perform_pending_ops(struct kvm *kvm)
+{
+	struct kvm_memory_slot *memslot;
+
+	mutex_lock(&kvm->slots_lock);
+	if (!kvm_mmu_has_pending_ops(kvm))
+		goto out_unlock;
+
+	if (test_bit(KVM_LOCKED_MEMSLOT_FLUSH_DCACHE, &kvm->arch.mmu_pending_ops)) {
+		kvm_for_each_memslot(memslot, kvm_memslots(kvm)) {
+			if (!memslot_is_locked(memslot))
+				continue;
+			stage2_flush_memslot(kvm, memslot);
+		}
+	}
+
+	bitmap_zero(&kvm->arch.mmu_pending_ops, KVM_MAX_MMU_PENDING_OPS);
+
+out_unlock:
+	mutex_unlock(&kvm->slots_lock);
+	return;
+}
+
 static int try_rlimit_memlock(unsigned long npages)
 {
 	unsigned long lock_limit;
@@ -1293,7 +1328,8 @@ static int lock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot,
 	struct kvm_memory_slot_page *page_entry;
 	bool writable = flags & KVM_ARM_LOCK_MEM_WRITE;
 	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
-	struct kvm_pgtable *pgt = kvm->arch.mmu.pgt;
+	struct kvm_pgtable pgt;
+	struct kvm_pgtable_mm_ops mm_ops;
 	struct vm_area_struct *vma;
 	unsigned long npages = memslot->npages;
 	unsigned int pin_flags = FOLL_LONGTERM;
@@ -1311,6 +1347,16 @@ static int lock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot,
 		pin_flags |= FOLL_WRITE;
 	}
 
+	/*
+	 * Make a copy of the stage 2 translation table struct to remove the
+	 * dcache callback so we can postpone the cache maintenance operations
+	 * until the first VCPU is run.
+	 */
+	mm_ops = *kvm->arch.mmu.pgt->mm_ops;
+	mm_ops.dcache_clean_inval_poc = NULL;
+	pgt = *kvm->arch.mmu.pgt;
+	pgt.mm_ops = &mm_ops;
+
 	hva = memslot->userspace_addr;
 	ipa = memslot->base_gfn << PAGE_SHIFT;
 
@@ -1362,13 +1408,13 @@ static int lock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot,
 			goto out_err;
 		}
 
-		ret = kvm_pgtable_stage2_map(pgt, ipa, PAGE_SIZE,
+		ret = kvm_pgtable_stage2_map(&pgt, ipa, PAGE_SIZE,
 					     page_to_phys(page_entry->page),
 					     prot, &cache);
 		spin_unlock(&kvm->mmu_lock);
 
 		if (ret) {
-			kvm_pgtable_stage2_unmap(pgt, memslot->base_gfn << PAGE_SHIFT,
+			kvm_pgtable_stage2_unmap(&pgt, memslot->base_gfn << PAGE_SHIFT,
 						 i << PAGE_SHIFT);
 			unpin_memslot_pages(memslot, writable);
 			goto out_err;
@@ -1387,7 +1433,7 @@ static int lock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot,
 	 */
 	ret = account_locked_vm(current->mm, npages, true);
 	if (ret) {
-		kvm_pgtable_stage2_unmap(pgt, memslot->base_gfn << PAGE_SHIFT,
+		kvm_pgtable_stage2_unmap(&pgt, memslot->base_gfn << PAGE_SHIFT,
 					 npages << PAGE_SHIFT);
 		unpin_memslot_pages(memslot, writable);
 		goto out_err;
@@ -1397,6 +1443,8 @@ static int lock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot,
 	if (writable)
 		memslot->arch.flags |= KVM_MEMSLOT_LOCK_WRITE;
 
+	set_bit(KVM_LOCKED_MEMSLOT_FLUSH_DCACHE, &kvm->arch.mmu_pending_ops);
+
 	kvm_mmu_free_memory_cache(&cache);
 
 	return 0;
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:41 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:41 +0100
Subject: [RFC PATCH v4 05/39] KVM: arm64: Perform CMOs on locked memslots when
 userspace resets VCPUs
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-6-alexandru.elisei@arm.com>

Userspace resets a VCPU that has already run by means of a
KVM_ARM_VCPU_INIT ioctl. This is usually done after a VM shutdown and
before the same VM is rebooted, and during this interval the VM memory can
be modified by userspace (for example, to copy the original guest kernel
image). In this situation, KVM unmaps the entire stage 2 to trigger stage 2
faults, which ensures that the guest has the same view of memory as the
host's userspace.

Unmapping stage 2 is not an option for locked memslots, so instead do the
cache maintenance the first time a VCPU is run, similar to what KVM does
when a memslot is locked.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  3 ++-
 arch/arm64/kvm/mmu.c              | 13 ++++++++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ed67f914d169..68905bd47f85 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -114,7 +114,8 @@ struct kvm_arch_memory_slot {
 
 /* kvm->arch.mmu_pending_ops flags */
 #define KVM_LOCKED_MEMSLOT_FLUSH_DCACHE	0
-#define KVM_MAX_MMU_PENDING_OPS		1
+#define KVM_LOCKED_MEMSLOT_INVAL_ICACHE	1
+#define KVM_MAX_MMU_PENDING_OPS		2
 
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 94fa08f3d9d3..f1f8a87550d1 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -560,8 +560,16 @@ void stage2_unmap_vm(struct kvm *kvm)
 	spin_lock(&kvm->mmu_lock);
 
 	slots = kvm_memslots(kvm);
-	kvm_for_each_memslot(memslot, slots)
+	kvm_for_each_memslot(memslot, slots) {
+		if (memslot_is_locked(memslot)) {
+			set_bit(KVM_LOCKED_MEMSLOT_FLUSH_DCACHE,
+				&kvm->arch.mmu_pending_ops);
+			set_bit(KVM_LOCKED_MEMSLOT_INVAL_ICACHE,
+				&kvm->arch.mmu_pending_ops);
+			continue;
+		}
 		stage2_unmap_memslot(kvm, memslot);
+	}
 
 	spin_unlock(&kvm->mmu_lock);
 	mmap_read_unlock(current->mm);
@@ -1281,6 +1289,9 @@ void kvm_mmu_perform_pending_ops(struct kvm *kvm)
 		}
 	}
 
+	if (test_bit(KVM_LOCKED_MEMSLOT_INVAL_ICACHE, &kvm->arch.mmu_pending_ops))
+		icache_inval_all_pou();
+
 	bitmap_zero(&kvm->arch.mmu_pending_ops, KVM_MAX_MMU_PENDING_OPS);
 
 out_unlock:
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:42 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:42 +0100
Subject: [RFC PATCH v4 06/39] KVM: arm64: Delay tag scrubbing for locked
 memslots until a VCPU runs
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-7-alexandru.elisei@arm.com>

When an MTE-enabled guest first accesses a physical page, that page must be
scrubbed for tags. This is normally done by KVM on a translation fault, but
with locked memslots we will not get translation faults. So far, this has
been handled by forbidding userspace to enable the MTE capability after
locking a memslot.

Remove this constraint by deferring tag cleaning until the first VCPU is
run, similar to how KVM handles cache maintenance operations.

When userspace resets a VCPU, KVM again performs cache maintenance
operations on locked memslots because userspace might have modified the
guest memory. Clean the tags the next time a VCPU is run for the same
reason.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  7 ++-
 arch/arm64/include/asm/kvm_mmu.h  |  2 +-
 arch/arm64/kvm/arm.c              | 29 ++--------
 arch/arm64/kvm/mmu.c              | 92 ++++++++++++++++++++++++++-----
 4 files changed, 87 insertions(+), 43 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 68905bd47f85..a57f33368a3e 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -113,9 +113,10 @@ struct kvm_arch_memory_slot {
 };
 
 /* kvm->arch.mmu_pending_ops flags */
-#define KVM_LOCKED_MEMSLOT_FLUSH_DCACHE	0
-#define KVM_LOCKED_MEMSLOT_INVAL_ICACHE	1
-#define KVM_MAX_MMU_PENDING_OPS		2
+#define KVM_LOCKED_MEMSLOT_FLUSH_DCACHE		0
+#define KVM_LOCKED_MEMSLOT_INVAL_ICACHE		1
+#define KVM_LOCKED_MEMSLOT_SANITISE_TAGS	2
+#define KVM_MAX_MMU_PENDING_OPS			3
 
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 525c223e769f..9fcdd2580f6e 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -222,7 +222,7 @@ int kvm_mmu_unlock_memslot(struct kvm *kvm, u64 slot, u64 flags);
 #define kvm_mmu_has_pending_ops(kvm)	\
 	(!bitmap_empty(&(kvm)->arch.mmu_pending_ops, KVM_MAX_MMU_PENDING_OPS))
 
-void kvm_mmu_perform_pending_ops(struct kvm *kvm);
+int kvm_mmu_perform_pending_ops(struct kvm *kvm);
 
 static inline unsigned int kvm_get_vmid_bits(void)
 {
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 144c982912d8..c47e96ae4f7c 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -108,25 +108,6 @@ static int kvm_lock_user_memory_region_ioctl(struct kvm *kvm,
 	}
 }
 
-static bool kvm_arm_has_locked_memslots(struct kvm *kvm)
-{
-	struct kvm_memslots *slots = kvm_memslots(kvm);
-	struct kvm_memory_slot *memslot;
-	bool has_locked_memslots = false;
-	int idx;
-
-	idx = srcu_read_lock(&kvm->srcu);
-	kvm_for_each_memslot(memslot, slots) {
-		if (memslot->arch.flags & KVM_MEMSLOT_LOCK_MASK) {
-			has_locked_memslots = true;
-			break;
-		}
-	}
-	srcu_read_unlock(&kvm->srcu, idx);
-
-	return has_locked_memslots;
-}
-
 int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 			    struct kvm_enable_cap *cap)
 {
@@ -142,9 +123,6 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 	case KVM_CAP_ARM_MTE:
 		if (!system_supports_mte() || kvm->created_vcpus)
 			return -EINVAL;
-		if (kvm_arm_lock_memslot_supported() &&
-		    kvm_arm_has_locked_memslots(kvm))
-			return -EPERM;
 		r = 0;
 		kvm->arch.mte_enabled = true;
 		break;
@@ -829,8 +807,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 	if (unlikely(!kvm_vcpu_initialized(vcpu)))
 		return -ENOEXEC;
 
-	if (unlikely(kvm_mmu_has_pending_ops(vcpu->kvm)))
-		kvm_mmu_perform_pending_ops(vcpu->kvm);
+	if (unlikely(kvm_mmu_has_pending_ops(vcpu->kvm))) {
+		ret = kvm_mmu_perform_pending_ops(vcpu->kvm);
+		if (ret)
+			return ret;
+	}
 
 	ret = kvm_vcpu_first_run_init(vcpu);
 	if (ret)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index f1f8a87550d1..cd44b6f2c53e 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -566,6 +566,10 @@ void stage2_unmap_vm(struct kvm *kvm)
 				&kvm->arch.mmu_pending_ops);
 			set_bit(KVM_LOCKED_MEMSLOT_INVAL_ICACHE,
 				&kvm->arch.mmu_pending_ops);
+			if (kvm_has_mte(kvm)) {
+				set_bit(KVM_LOCKED_MEMSLOT_SANITISE_TAGS,
+					&kvm->arch.mmu_pending_ops);
+			}
 			continue;
 		}
 		stage2_unmap_memslot(kvm, memslot);
@@ -909,6 +913,58 @@ static int sanitise_mte_tags(struct kvm *kvm, kvm_pfn_t pfn,
 	return 0;
 }
 
+static int sanitise_mte_tags_memslot(struct kvm *kvm,
+				     struct kvm_memory_slot *memslot)
+{
+	unsigned long hva, slot_size, slot_end;
+	struct kvm_memory_slot_page *entry;
+	struct page *page;
+	int ret = 0;
+
+	if (!kvm_has_mte(kvm))
+		return 0;
+
+	hva = memslot->userspace_addr;
+	slot_size = memslot->npages << PAGE_SHIFT;
+	slot_end = hva + slot_size;
+
+	/* First check that the VMAs spanning the memslot are not shared... */
+	do {
+		struct vm_area_struct *vma;
+
+		vma = find_vma_intersection(current->mm, hva, slot_end);
+		/* The VMAs spanning the memslot must be contiguous. */
+		if (!vma) {
+			ret = -EFAULT;
+			goto out;
+		}
+		/*
+		 * VM_SHARED mappings are not allowed with MTE to avoid races
+		 * when updating the PG_mte_tagged page flag, see
+		 * sanitise_mte_tags for more details.
+		 */
+		if (kvm_has_mte(kvm) && vma->vm_flags & VM_SHARED) {
+			ret = -EFAULT;
+			goto out;
+		}
+		hva = min(slot_end, vma->vm_end);
+	} while (hva < slot_end);
+
+	/* ... then clear the tags. */
+	list_for_each_entry(entry, &memslot->arch.pages.list, list) {
+		page = entry->page;
+		if (!test_bit(PG_mte_tagged, &page->flags)) {
+			mte_clear_page_tags(page_address(page));
+			set_bit(PG_mte_tagged, &page->flags);
+		}
+	}
+
+out:
+	mmap_read_unlock(current->mm);
+
+	return ret;
+}
+
 static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 			  struct kvm_memory_slot *memslot, unsigned long hva,
 			  unsigned long fault_status)
@@ -1273,14 +1329,28 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
  * - Stage 2 tables cannot be freed from under us as long as at least one VCPU
  *   is live, which means that the VM will be live.
  */
-void kvm_mmu_perform_pending_ops(struct kvm *kvm)
+int kvm_mmu_perform_pending_ops(struct kvm *kvm)
 {
 	struct kvm_memory_slot *memslot;
+	int ret = 0;
 
 	mutex_lock(&kvm->slots_lock);
 	if (!kvm_mmu_has_pending_ops(kvm))
 		goto out_unlock;
 
+	if (test_bit(KVM_LOCKED_MEMSLOT_SANITISE_TAGS, &kvm->arch.mmu_pending_ops) &&
+	    kvm_has_mte(kvm)) {
+		kvm_for_each_memslot(memslot, kvm_memslots(kvm)) {
+			if (!memslot_is_locked(memslot))
+				continue;
+			mmap_read_lock(current->mm);
+			ret = sanitise_mte_tags_memslot(kvm, memslot);
+			mmap_read_unlock(current->mm);
+			if (ret)
+				goto out_unlock;
+		}
+	}
+
 	if (test_bit(KVM_LOCKED_MEMSLOT_FLUSH_DCACHE, &kvm->arch.mmu_pending_ops)) {
 		kvm_for_each_memslot(memslot, kvm_memslots(kvm)) {
 			if (!memslot_is_locked(memslot))
@@ -1296,7 +1366,7 @@ void kvm_mmu_perform_pending_ops(struct kvm *kvm)
 
 out_unlock:
 	mutex_unlock(&kvm->slots_lock);
-	return;
+	return ret;
 }
 
 static int try_rlimit_memlock(unsigned long npages)
@@ -1390,19 +1460,6 @@ static int lock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot,
 			ret = -ENOMEM;
 			goto out_err;
 		}
-		if (kvm_has_mte(kvm)) {
-			if (vma->vm_flags & VM_SHARED) {
-				ret = -EFAULT;
-			} else {
-				ret = sanitise_mte_tags(kvm,
-					page_to_pfn(page_entry->page),
-					PAGE_SIZE);
-			}
-			if (ret) {
-				mmap_read_unlock(current->mm);
-				goto out_err;
-			}
-		}
 		mmap_read_unlock(current->mm);
 
 		ret = kvm_mmu_topup_memory_cache(&cache, kvm_mmu_cache_min_pages(kvm));
@@ -1455,6 +1512,11 @@ static int lock_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot,
 		memslot->arch.flags |= KVM_MEMSLOT_LOCK_WRITE;
 
 	set_bit(KVM_LOCKED_MEMSLOT_FLUSH_DCACHE, &kvm->arch.mmu_pending_ops);
+	/*
+	 * MTE might be enabled after we lock the memslot, set it here
+	 * unconditionally.
+	 */
+	set_bit(KVM_LOCKED_MEMSLOT_SANITISE_TAGS, &kvm->arch.mmu_pending_ops);
 
 	kvm_mmu_free_memory_cache(&cache);
 
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:43 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:43 +0100
Subject: [RFC PATCH v4 07/39] KVM: arm64: Unlock memslots after stage 2 tables
 are freed
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-8-alexandru.elisei@arm.com>

Unpin the backing pages mapped at stage 2 after the stage 2 translation
tables are destroyed.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/mmu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index cd44b6f2c53e..27b7befd4fa9 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1907,6 +1907,7 @@ void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen)
 void kvm_arch_flush_shadow_all(struct kvm *kvm)
 {
 	kvm_free_stage2_pgd(&kvm->arch.mmu);
+	unlock_all_memslots(kvm);
 }
 
 void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:45 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:45 +0100
Subject: [RFC PATCH v4 09/39] KVM: Add kvm_warn{,_ratelimited} macros
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-10-alexandru.elisei@arm.com>

Add the kvm_warn() and kvm_warn_ratelimited() macros to print a kernel
warning.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 include/linux/kvm_host.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ae7735b490b4..ada5019ad93d 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -605,6 +605,10 @@ struct kvm {
 
 #define kvm_err(fmt, ...) \
 	pr_err("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__)
+#define kvm_warn(fmt, ...) \
+	pr_warn("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__)
+#define kvm_warn_ratelimited(fmt, ...) \
+	pr_warn_ratelimited("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__)
 #define kvm_info(fmt, ...) \
 	pr_info("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__)
 #define kvm_debug(fmt, ...) \
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:46 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:46 +0100
Subject: [RFC PATCH v4 10/39] KVM: arm64: Print a warning for unexpected
 faults on locked memslots
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-11-alexandru.elisei@arm.com>

When userspace unmaps a VMA backing a memslot, the corresponding stage 2
address range gets unmapped via the MMU notifiers. This makes it possible
to get stage 2 faults on a locked memslot, which might not be what
userspace wants because the purpose of locking a memslot is to avoid stage
2 faults in the first place.

Addresses being unmapped from stage 2 can happen from other reasons too,
like bugs in the implementation of the lock memslot API, however unlikely
that might seem.

Let's try to make debugging easier by printing a warning when this happens.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/mmu.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 3ab8eba808ae..d66d89c18045 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1298,6 +1298,27 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	/* Userspace should not be able to register out-of-bounds IPAs */
 	VM_BUG_ON(fault_ipa >= kvm_phys_size(vcpu->kvm));
 
+	if (memslot_is_locked(memslot)) {
+		const char *fault_type_str;
+
+		if (kvm_vcpu_trap_is_exec_fault(vcpu))
+			goto handle_fault;
+
+		if (fault_status == FSC_ACCESS)
+			fault_type_str = "access";
+		else if (write_fault && (memslot->arch.flags & KVM_MEMSLOT_LOCK_WRITE))
+			fault_type_str = "write";
+		else if (!write_fault)
+			fault_type_str = "read";
+		else
+			goto handle_fault;
+
+		kvm_warn_ratelimited("Unexpected L2 %s fault on locked memslot %d: IPA=%#llx, ESR_EL2=%#08x]\n",
+				     fault_type_str, memslot->id, fault_ipa,
+				     kvm_vcpu_get_esr(vcpu));
+	}
+
+handle_fault:
 	if (fault_status == FSC_ACCESS) {
 		handle_access_fault(vcpu, fault_ipa);
 		ret = 1;
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:47 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:47 +0100
Subject: [RFC PATCH v4 11/39] KVM: arm64: Allow userspace to lock and unlock
 memslots
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-12-alexandru.elisei@arm.com>

The ioctls have been implemented, allow the userspace to lock and unlock
memslots.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/arm.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index c47e96ae4f7c..4bd4b8b082a4 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -80,11 +80,6 @@ int kvm_arch_check_processor_compat(void *opaque)
 	return 0;
 }
 
-static int kvm_arm_lock_memslot_supported(void)
-{
-	return 0;
-}
-
 static int kvm_lock_user_memory_region_ioctl(struct kvm *kvm,
 					     struct kvm_enable_cap *cap)
 {
@@ -127,8 +122,6 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 		kvm->arch.mte_enabled = true;
 		break;
 	case KVM_CAP_ARM_LOCK_USER_MEMORY_REGION:
-		if (!kvm_arm_lock_memslot_supported())
-			return -EINVAL;
 		r = kvm_lock_user_memory_region_ioctl(kvm, cap);
 		break;
 	default:
@@ -306,7 +299,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = system_has_full_ptr_auth();
 		break;
 	case KVM_CAP_ARM_LOCK_USER_MEMORY_REGION:
-		r = kvm_arm_lock_memslot_supported();
+		r = 1;
 		break;
 	default:
 		r = 0;
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:48 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:48 +0100
Subject: [RFC PATCH v4 12/39] KVM: arm64: Add the KVM_ARM_VCPU_SUPPORTED_CPUS
 VCPU ioctl
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-13-alexandru.elisei@arm.com>

The ioctl is used to specify a list of physical CPUs on which the VCPU is
allowed to run. The ioctl introduces no constraints on the VCPU scheduling,
and userspace is expected to manage the VCPU affinity. Attempting to run
the VCPU on a CPU not present in the list will result in KVM_RUN returning
-ENOEXEC.

The expectation is that this ioctl will be used by KVM to prevent errors,
like accesses to undefined registers, when emulating VCPU features for
which hardware support is present only on a subset of the CPUs present in
the system.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/api.rst    | 22 ++++++++++++++++++++--
 arch/arm64/include/asm/kvm_host.h |  3 +++
 arch/arm64/kvm/arm.c              | 31 +++++++++++++++++++++++++++++++
 include/uapi/linux/kvm.h          |  4 ++++
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 5aa251df7077..994faa24690a 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -396,8 +396,10 @@ Errors:
 
   =======    ==============================================================
   EINTR      an unmasked signal is pending
-  ENOEXEC    the vcpu hasn't been initialized or the guest tried to execute
-             instructions from device memory (arm64)
+  ENOEXEC    the vcpu hasn't been initialized, the guest tried to execute
+             instructions from device memory (arm64) or the vcpu has been
+             scheduled on a cpu not in the list specified by
+             KVM_ARM_VCPU_SUPPORTED_CPUS (arm64).
   ENOSYS     data abort outside memslots with no syndrome info and
              KVM_CAP_ARM_NISV_TO_USER not enabled (arm64)
   EPERM      SVE feature set but not finalized (arm64)
@@ -5293,6 +5295,22 @@ the trailing ``'\0'``, is indicated by ``name_size`` in the header.
 The Stats Data block contains an array of 64-bit values in the same order
 as the descriptors in Descriptors block.
 
+4.134 KVM_ARM_VCPU_SUPPORTED_CPUS
+---------------------------------
+
+:Capability: KVM_CAP_ARM_SUPPORTED_CPUS
+:Architectures: arm64
+:Type: vcpu ioctl
+:Parameters: const char * representing a range of supported CPUs
+:Returns: 0 on success, < 0 on error
+
+Specifies a list of physical CPUs on which the VCPU can run. KVM will not make
+any attempts to prevent the VCPU from being scheduled on a CPU which is not
+present in the list; when that happens, KVM_RUN will return -ENOEXEC.
+
+The format for the range of supported CPUs is specified in the comment for
+the function lib/bitmap.c::bitmap_parselist().
+
 5. The kvm_run structure
 ========================
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a57f33368a3e..1f3b46a6df81 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -396,6 +396,9 @@ struct kvm_vcpu_arch {
 	 * see kvm_vcpu_load_sysregs_vhe and kvm_vcpu_put_sysregs_vhe. */
 	bool sysregs_loaded_on_cpu;
 
+	cpumask_t supported_cpus;
+	bool cpu_not_supported;
+
 	/* Guest PV state */
 	struct {
 		u64 last_steal;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 4bd4b8b082a4..e8a7c0c3a086 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -301,6 +301,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_LOCK_USER_MEMORY_REGION:
 		r = 1;
 		break;
+	case KVM_CAP_ARM_VCPU_SUPPORTED_CPUS:
+		r = 1;
+		break;
 	default:
 		r = 0;
 	}
@@ -456,6 +459,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	if (vcpu_has_ptrauth(vcpu))
 		vcpu_ptrauth_disable(vcpu);
 	kvm_arch_vcpu_load_debug_state_flags(vcpu);
+
+	if (!cpumask_empty(&vcpu->arch.supported_cpus) &&
+	    !cpumask_test_cpu(smp_processor_id(), &vcpu->arch.supported_cpus))
+		vcpu->arch.cpu_not_supported = true;
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -844,6 +851,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		 */
 		preempt_disable();
 
+		if (unlikely(vcpu->arch.cpu_not_supported)) {
+			vcpu->arch.cpu_not_supported = false;
+			ret = -ENOEXEC;
+			preempt_enable();
+			continue;
+		}
+
 		kvm_pmu_flush_hwstate(vcpu);
 
 		local_irq_disable();
@@ -1361,6 +1375,23 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 
 		return kvm_arm_vcpu_set_events(vcpu, &events);
 	}
+	case KVM_ARM_VCPU_SUPPORTED_CPUS: {
+		char *cpulist;
+
+		r = -ENOEXEC;
+		if (unlikely(vcpu->arch.has_run_once))
+			break;
+
+		cpulist = strndup_user((const char __user *)argp, PAGE_SIZE);
+		if (IS_ERR(cpulist)) {
+			r = PTR_ERR(cpulist);
+			break;
+		}
+
+		r = cpulist_parse(cpulist, &vcpu->arch.supported_cpus);
+		kfree(cpulist);
+		break;
+	}
 	case KVM_ARM_VCPU_FINALIZE: {
 		int what;
 
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index bcf62c7bdd2d..e5acc925c528 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1113,6 +1113,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
 #define KVM_CAP_ARM_MTE 205
 #define KVM_CAP_ARM_LOCK_USER_MEMORY_REGION 206
+#define KVM_CAP_ARM_VCPU_SUPPORTED_CPUS 207
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1594,6 +1595,9 @@ struct kvm_enc_region {
 #define KVM_S390_NORMAL_RESET	_IO(KVMIO,   0xc3)
 #define KVM_S390_CLEAR_RESET	_IO(KVMIO,   0xc4)
 
+/* Available with KVM_CAP_ARM_VCPU_SUPPORTED_CPUS */
+#define KVM_ARM_VCPU_SUPPORTED_CPUS    _IOW(KVMIO, 0xc5, const char *)
+
 struct kvm_s390_pv_sec_parm {
 	__u64 origin;
 	__u64 length;
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:49 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:49 +0100
Subject: [RFC PATCH v4 13/39] KVM: arm64: Add CONFIG_KVM_ARM_SPE Kconfig option
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-14-alexandru.elisei@arm.com>

Add a new configuration option that will be used for KVM SPE emulation.
CONFIG_KVM_ARM_SPE depends on the SPE driver being builtin because:

1. The cpumask of physical CPUs that support SPE will be used by KVM to
   emulate SPE on heterogeneous systems.

2. KVM will rely on the SPE driver enabling the SPE interrupt at the GIC
   level.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/Kconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index a4eba0908bfa..c6ad5a05efb3 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -46,6 +46,14 @@ if KVM
 
 source "virt/kvm/Kconfig"
 
+config KVM_ARM_SPE
+	bool "Virtual Statistical Profiling Extension (SPE) support"
+	depends on ARM_SPE_PMU=y
+	default y
+	help
+	  Adds support for Statistical Profiling Extension (SPE) in virtual
+	  machines.
+
 endif # KVM
 
 endif # VIRTUALIZATION
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:50 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:50 +0100
Subject: [RFC PATCH v4 14/39] KVM: arm64: Add SPE capability and VCPU feature
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-15-alexandru.elisei@arm.com>

Add the KVM_CAP_ARM_SPE capability which allows userspace to discover if
SPE emulation is available. Add the KVM_ARM_VCPU_SPE feature which
enables the emulation for a VCPU.

Both are disabled for now.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/api.rst    | 9 +++++++++
 arch/arm64/include/uapi/asm/kvm.h | 1 +
 arch/arm64/kvm/arm.c              | 3 +++
 include/uapi/linux/kvm.h          | 1 +
 4 files changed, 14 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 994faa24690a..68fada258b80 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -7315,3 +7315,12 @@ The argument to KVM_ENABLE_CAP is also a bitmask, and must be a subset
 of the result of KVM_CHECK_EXTENSION.  KVM will forward to userspace
 the hypercalls whose corresponding bit is in the argument, and return
 ENOSYS for the others.
+
+8.35 KVM_CAP_ARM_SPE
+--------------------
+
+:Architectures: arm64
+
+This capability indicates that Statistical Profiling Extension (SPE) emulation
+is available in KVM. SPE emulation is enabled for each VCPU which has the
+feature bit KVM_ARM_VCPU_SPE set.
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..9f0a8ea50ea9 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -106,6 +106,7 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_SVE		4 /* enable SVE for this CPU */
 #define KVM_ARM_VCPU_PTRAUTH_ADDRESS	5 /* VCPU uses address authentication */
 #define KVM_ARM_VCPU_PTRAUTH_GENERIC	6 /* VCPU uses generic authentication */
+#define KVM_ARM_VCPU_SPE		7 /* enable SPE for this CPU */
 
 struct kvm_vcpu_init {
 	__u32 target;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e8a7c0c3a086..22544eb367f3 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -304,6 +304,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_VCPU_SUPPORTED_CPUS:
 		r = 1;
 		break;
+	case KVM_CAP_ARM_SPE:
+		r = 0;
+		break;
 	default:
 		r = 0;
 	}
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index e5acc925c528..930ef91f7916 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1114,6 +1114,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_ARM_MTE 205
 #define KVM_CAP_ARM_LOCK_USER_MEMORY_REGION 206
 #define KVM_CAP_ARM_VCPU_SUPPORTED_CPUS 207
+#define KVM_CAP_ARM_SPE 208
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:51 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:51 +0100
Subject: [RFC PATCH v4 15/39] drivers/perf: Expose the cpumask of CPUs that
 support SPE
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-16-alexandru.elisei@arm.com>

KVM SPE emulation will require the list of CPUs that have hardware support
for SPE. Add a function that returns the cpumask of supported CPUs
discovered by the driver during probing.

CC: Will Deacon <will at kernel.org>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 drivers/perf/arm_spe_pmu.c   | 30 ++++++++++++++++++------------
 include/linux/perf/arm_pmu.h |  7 +++++++
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index d44bcc29d99c..40749665f102 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -50,7 +50,6 @@ struct arm_spe_pmu_buf {
 struct arm_spe_pmu {
 	struct pmu				pmu;
 	struct platform_device			*pdev;
-	cpumask_t				supported_cpus;
 	struct hlist_node			hotplug_node;
 
 	int					irq; /* PPI */
@@ -72,6 +71,8 @@ struct arm_spe_pmu {
 	struct perf_output_handle __percpu	*handle;
 };
 
+static cpumask_t supported_cpus;
+
 #define to_spe_pmu(p) (container_of(p, struct arm_spe_pmu, pmu))
 
 /* Convert a free-running index from perf into an SPE buffer offset */
@@ -234,9 +235,7 @@ static const struct attribute_group arm_spe_pmu_format_group = {
 static ssize_t cpumask_show(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 {
-	struct arm_spe_pmu *spe_pmu = dev_get_drvdata(dev);
-
-	return cpumap_print_to_pagebuf(true, buf, &spe_pmu->supported_cpus);
+	return cpumap_print_to_pagebuf(true, buf, &supported_cpus);
 }
 static DEVICE_ATTR_RO(cpumask);
 
@@ -677,7 +676,7 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
 		return -ENOENT;
 
 	if (event->cpu >= 0 &&
-	    !cpumask_test_cpu(event->cpu, &spe_pmu->supported_cpus))
+	    !cpumask_test_cpu(event->cpu, &supported_cpus))
 		return -ENOENT;
 
 	if (arm_spe_event_to_pmsevfr(event) & arm_spe_pmsevfr_res0(spe_pmu->pmsver))
@@ -797,11 +796,10 @@ static void arm_spe_pmu_stop(struct perf_event *event, int flags)
 static int arm_spe_pmu_add(struct perf_event *event, int flags)
 {
 	int ret = 0;
-	struct arm_spe_pmu *spe_pmu = to_spe_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
 	int cpu = event->cpu == -1 ? smp_processor_id() : event->cpu;
 
-	if (!cpumask_test_cpu(cpu, &spe_pmu->supported_cpus))
+	if (!cpumask_test_cpu(cpu, &supported_cpus))
 		return -ENOENT;
 
 	hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
@@ -883,6 +881,13 @@ static void arm_spe_pmu_free_aux(void *aux)
 	kfree(buf);
 }
 
+#if IS_BUILTIN(CONFIG_ARM_SPE_PMU)
+const cpumask_t *arm_spe_pmu_supported_cpus(void)
+{
+	return &supported_cpus;
+}
+#endif
+
 /* Initialisation and teardown functions */
 static int arm_spe_pmu_perf_init(struct arm_spe_pmu *spe_pmu)
 {
@@ -1039,7 +1044,7 @@ static void __arm_spe_pmu_dev_probe(void *info)
 
 	dev_info(dev,
 		 "probed for CPUs %*pbl [max_record_sz %u, align %u, features 0x%llx]\n",
-		 cpumask_pr_args(&spe_pmu->supported_cpus),
+		 cpumask_pr_args(&supported_cpus),
 		 spe_pmu->max_record_sz, spe_pmu->align, spe_pmu->features);
 
 	spe_pmu->features |= SPE_PMU_FEAT_DEV_PROBED;
@@ -1083,7 +1088,7 @@ static int arm_spe_pmu_cpu_startup(unsigned int cpu, struct hlist_node *node)
 	struct arm_spe_pmu *spe_pmu;
 
 	spe_pmu = hlist_entry_safe(node, struct arm_spe_pmu, hotplug_node);
-	if (!cpumask_test_cpu(cpu, &spe_pmu->supported_cpus))
+	if (!cpumask_test_cpu(cpu, &supported_cpus))
 		return 0;
 
 	__arm_spe_pmu_setup_one(spe_pmu);
@@ -1095,7 +1100,7 @@ static int arm_spe_pmu_cpu_teardown(unsigned int cpu, struct hlist_node *node)
 	struct arm_spe_pmu *spe_pmu;
 
 	spe_pmu = hlist_entry_safe(node, struct arm_spe_pmu, hotplug_node);
-	if (!cpumask_test_cpu(cpu, &spe_pmu->supported_cpus))
+	if (!cpumask_test_cpu(cpu, &supported_cpus))
 		return 0;
 
 	__arm_spe_pmu_stop_one(spe_pmu);
@@ -1105,7 +1110,7 @@ static int arm_spe_pmu_cpu_teardown(unsigned int cpu, struct hlist_node *node)
 static int arm_spe_pmu_dev_init(struct arm_spe_pmu *spe_pmu)
 {
 	int ret;
-	cpumask_t *mask = &spe_pmu->supported_cpus;
+	cpumask_t *mask = &supported_cpus;
 
 	/* Make sure we probe the hardware on a relevant CPU */
 	ret = smp_call_function_any(mask,  __arm_spe_pmu_dev_probe, spe_pmu, 1);
@@ -1151,7 +1156,7 @@ static int arm_spe_pmu_irq_probe(struct arm_spe_pmu *spe_pmu)
 		return -EINVAL;
 	}
 
-	if (irq_get_percpu_devid_partition(irq, &spe_pmu->supported_cpus)) {
+	if (irq_get_percpu_devid_partition(irq, &supported_cpus)) {
 		dev_err(&pdev->dev, "failed to get PPI partition (%d)\n", irq);
 		return -EINVAL;
 	}
@@ -1216,6 +1221,7 @@ static int arm_spe_pmu_device_probe(struct platform_device *pdev)
 	arm_spe_pmu_dev_teardown(spe_pmu);
 out_free_handle:
 	free_percpu(spe_pmu->handle);
+	cpumask_clear(&supported_cpus);
 	return ret;
 }
 
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 505480217cf1..3121d95c575b 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -8,6 +8,7 @@
 #ifndef __ARM_PMU_H__
 #define __ARM_PMU_H__
 
+#include <linux/cpumask.h>
 #include <linux/interrupt.h>
 #include <linux/perf_event.h>
 #include <linux/platform_device.h>
@@ -177,4 +178,10 @@ void armpmu_free_irq(int irq, int cpu);
 
 #define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
 
+#if IS_BUILTIN(CONFIG_ARM_SPE_PMU)
+extern const cpumask_t *arm_spe_pmu_supported_cpus(void);
+#else
+static inline const cpumask_t *arm_spe_pmu_supported_cpus(void) { return NULL; };
+#endif
+
 #endif /* __ARM_PMU_H__ */
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:44 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:44 +0100
Subject: [RFC PATCH v4 08/39] KVM: arm64: Deny changes to locked memslots
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-9-alexandru.elisei@arm.com>

Forbid userspace from making changes to a locked memslot. If userspace
wants to modify a locked memslot, then they will need to unlock it.

One special case is allowed: memslots locked for read, but not for write,
can have dirty page logging turned on.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/mmu.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 27b7befd4fa9..3ab8eba808ae 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1842,8 +1842,23 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
 {
 	hva_t hva = mem->userspace_addr;
 	hva_t reg_end = hva + mem->memory_size;
+	struct kvm_memory_slot *old;
 	int ret = 0;
 
+	/*
+	 * Forbid all changes to locked memslots with the exception of turning
+	 * on dirty page logging for memslots locked only for reads.
+	 */
+	old = id_to_memslot(kvm_memslots(kvm), memslot->id);
+	if (old && memslot_is_locked(old)) {
+		if (change == KVM_MR_FLAGS_ONLY &&
+		    memslot_is_logging(memslot) &&
+		    !(old->arch.flags & KVM_MEMSLOT_LOCK_WRITE))
+			memcpy(&memslot->arch, &old->arch, sizeof(old->arch));
+		else
+			return -EBUSY;
+	}
+
 	if (change != KVM_MR_CREATE && change != KVM_MR_MOVE &&
 			change != KVM_MR_FLAGS_ONLY)
 		return 0;
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:52 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:52 +0100
Subject: [RFC PATCH v4 16/39] KVM: arm64: Make SPE available when at least one
 CPU supports it
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-17-alexandru.elisei@arm.com>

KVM SPE emulation requires at least one physical CPU to support SPE.
Initialize the cpumask of PEs that support SPE the first time
KVM_CAP_ARM_SPE is queried or when the first virtual machine is created,
whichever comes first.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_spe.h | 26 ++++++++++++++++++++++++++
 arch/arm64/kvm/Makefile          |  1 +
 arch/arm64/kvm/arm.c             |  4 ++++
 arch/arm64/kvm/spe.c             | 32 ++++++++++++++++++++++++++++++++
 4 files changed, 63 insertions(+)
 create mode 100644 arch/arm64/include/asm/kvm_spe.h
 create mode 100644 arch/arm64/kvm/spe.c

diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
new file mode 100644
index 000000000000..328115ce0b48
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 - ARM Ltd
+ */
+
+#ifndef __ARM64_KVM_SPE_H__
+#define __ARM64_KVM_SPE_H__
+
+#ifdef CONFIG_KVM_ARM_SPE
+DECLARE_STATIC_KEY_FALSE(kvm_spe_available);
+
+static __always_inline bool kvm_supports_spe(void)
+{
+	return static_branch_likely(&kvm_spe_available);
+}
+
+void kvm_spe_init_supported_cpus(void);
+void kvm_spe_vm_init(struct kvm *kvm);
+#else
+#define kvm_supports_spe()	(false)
+
+static inline void kvm_spe_init_supported_cpus(void) {}
+static inline void kvm_spe_vm_init(struct kvm *kvm) {}
+#endif /* CONFIG_KVM_ARM_SPE */
+
+#endif /* __ARM64_KVM_SPE_H__ */
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 989bb5dad2c8..86092a0f8367 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -25,3 +25,4 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
 	 vgic/vgic-its.o vgic/vgic-debug.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o
+kvm-$(CONFIG_KVM_ARM_SPE)     += spe.o
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 22544eb367f3..82cb7b5b3b45 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -35,6 +35,7 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_spe.h>
 #include <asm/kvm_emulate.h>
 #include <asm/sections.h>
 
@@ -180,6 +181,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 
 	set_default_spectre(kvm);
 
+	kvm_spe_vm_init(kvm);
+
 	return ret;
 out_free_stage2_pgd:
 	kvm_free_stage2_pgd(&kvm->arch.mmu);
@@ -305,6 +308,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		r = 1;
 		break;
 	case KVM_CAP_ARM_SPE:
+		kvm_spe_init_supported_cpus();
 		r = 0;
 		break;
 	default:
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
new file mode 100644
index 000000000000..83f92245f881
--- /dev/null
+++ b/arch/arm64/kvm/spe.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 - ARM Ltd
+ */
+
+#include <linux/cpumask.h>
+#include <linux/kvm_host.h>
+#include <linux/perf/arm_pmu.h>
+
+#include <asm/kvm_spe.h>
+
+DEFINE_STATIC_KEY_FALSE(kvm_spe_available);
+
+static const cpumask_t *supported_cpus;
+
+void kvm_spe_init_supported_cpus(void)
+{
+	if (likely(supported_cpus))
+		return;
+
+	supported_cpus = arm_spe_pmu_supported_cpus();
+	BUG_ON(!supported_cpus);
+
+	if (!cpumask_empty(supported_cpus))
+		static_branch_enable(&kvm_spe_available);
+}
+
+void kvm_spe_vm_init(struct kvm *kvm)
+{
+	/* Set supported_cpus if it isn't already initialized. */
+	kvm_spe_init_supported_cpus();
+}
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:53 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:53 +0100
Subject: [RFC PATCH v4 17/39] KVM: arm64: Set the VCPU SPE feature bit when
 SPE is available
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-18-alexandru.elisei@arm.com>

Check that KVM SPE emulation is supported before allowing userspace to set
the KVM_ARM_VCPU_SPE feature.

According to ARM DDI 0487G.a, page D9-2946 the Profiling Buffer is disabled
if the owning Exception level is 32 bit, reject the SPE feature if the
VCPU's execution state at EL1 is aarch32.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  3 +++
 arch/arm64/kvm/reset.c            | 23 +++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 1f3b46a6df81..948adb152104 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -807,6 +807,9 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
 #define kvm_vcpu_has_pmu(vcpu)					\
 	(test_bit(KVM_ARM_VCPU_PMU_V3, (vcpu)->arch.features))
 
+#define kvm_vcpu_has_spe(vcpu)					\
+	(test_bit(KVM_ARM_VCPU_SPE, (vcpu)->arch.features))
+
 int kvm_trng_call(struct kvm_vcpu *vcpu);
 #ifdef CONFIG_KVM
 extern phys_addr_t hyp_mem_base;
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index cba7872d69a8..17b9f1b29c24 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -27,6 +27,7 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_spe.h>
 #include <asm/virt.h>
 
 /* Maximum phys_shift supported for any VM on this host */
@@ -189,6 +190,21 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
 	return true;
 }
 
+static int kvm_vcpu_enable_spe(struct kvm_vcpu *vcpu)
+{
+	if (!kvm_supports_spe())
+		return -EINVAL;
+
+	/*
+	 * The Profiling Buffer is disabled if the owning Exception level is
+	 * aarch32.
+	 */
+	if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT))
+		return -EINVAL;
+
+	return 0;
+}
+
 /**
  * kvm_reset_vcpu - sets core registers and sys_regs to reset value
  * @vcpu: The VCPU pointer
@@ -245,6 +261,13 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 		goto out;
 	}
 
+	if (kvm_vcpu_has_spe(vcpu)) {
+		if (kvm_vcpu_enable_spe(vcpu)) {
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
 	switch (vcpu->arch.target) {
 	default:
 		if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
-- 
2.33.0



From nm at ti.com  Wed Aug 25 09:17:36 2021
From: nm at ti.com (Nishanth Menon)
Date: Wed, 25 Aug 2021 11:17:36 -0500
Subject: [PATCH v2 0/2] ARM: dts: keystone-k2*-evm: Fix mdio and dss node
 status
In-Reply-To: <20210824105858.19496-1-rogerq@kernel.org>
References: <20210824105858.19496-1-rogerq@kernel.org>
Message-ID: <20210825161736.ikx344bxfl5eqzgt@celibate>

On 13:58-20210824, Roger Quadros wrote:
> Hi Santosh,
> 
> This series fixes mdio and dss status nodes from "ok" to "okay"
> 
> As per Device Tree Specification [1], the status parameter of nodes can
> be "okay", "disabled", etc. "ok" is not a valid parameter.
> 
> U-boot Driver Model does not recognize status="ok" either and treats
> the node as disabled.

^^ I suspect the above comment in the patches is to indicate side effect
of non-compliance.

> 
> [1] https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3
> 
> cheers,
> -roger
> 
> Roger Quadros (2):
>   ARM: dts: keystone-k2*-evm: Fix mdio node status to "okay"
>   ARM: dts: keystone-k2g-evm: Fix dss node status to "okay"


Reviewed-by: Nishanth Menon <nm at ti.com>

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From alexandru.elisei at arm.com  Wed Aug 25 09:17:54 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:54 +0100
Subject: [RFC PATCH v4 18/39] KVM: arm64: Expose SPE version to guests
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-19-alexandru.elisei@arm.com>

Set the ID_AA64DFR0_EL1.PMSVer field to a non-zero value if the VCPU SPE
feature is set. SPE version is capped at FEAT_SPEv1p1 because KVM doesn't
yet implement freezing of PMU event counters on a SPE buffer management
event.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/sys_regs.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f6f126eb6ac1..ab7370b7a44b 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1070,8 +1070,10 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 		val = cpuid_feature_cap_perfmon_field(val,
 						      ID_AA64DFR0_PMUVER_SHIFT,
 						      kvm_vcpu_has_pmu(vcpu) ? ID_AA64DFR0_PMUVER_8_4 : 0);
-		/* Hide SPE from guests */
-		val &= ~FEATURE(ID_AA64DFR0_PMSVER);
+		/* Limit guests to SPE for ARMv8.3 */
+		val = cpuid_feature_cap_perfmon_field(val,
+						      ID_AA64DFR0_PMSVER_SHIFT,
+						      kvm_vcpu_has_spe(vcpu) ? ID_AA64DFR0_PMSVER_8_3 : 0);
 		break;
 	case SYS_ID_DFR0_EL1:
 		/* Limit guests to PMUv3 for ARMv8.4 */
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:55 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:55 +0100
Subject: [RFC PATCH v4 19/39] KVM: arm64: Do not emulate SPE on CPUs which
 don't have SPE
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-20-alexandru.elisei@arm.com>

The kernel allows heterogeneous systems where FEAT_SPE is not present on
all CPUs. This presents a challenge for KVM, as it will have to touch the
SPE registers when emulating SPE for a guest, and those accesses will cause
an undefined exception if SPE is not present on the CPU.

Avoid this situation by comparing the cpumask of the physical CPUs that
support SPE with the cpu list provided by userspace via the
KVM_ARM_VCPU_SUPPORTED_CPUS ioctl and refusing the run the VCPU if there is
a mismatch.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_spe.h |  2 ++
 arch/arm64/kvm/arm.c             |  3 +++
 arch/arm64/kvm/spe.c             | 12 ++++++++++++
 3 files changed, 17 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index 328115ce0b48..ed67ddbf8132 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -16,11 +16,13 @@ static __always_inline bool kvm_supports_spe(void)
 
 void kvm_spe_init_supported_cpus(void);
 void kvm_spe_vm_init(struct kvm *kvm);
+int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu);
 #else
 #define kvm_supports_spe()	(false)
 
 static inline void kvm_spe_init_supported_cpus(void) {}
 static inline void kvm_spe_vm_init(struct kvm *kvm) {}
+static inline int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
 #endif /* CONFIG_KVM_ARM_SPE */
 
 #endif /* __ARM64_KVM_SPE_H__ */
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 82cb7b5b3b45..8f7025f2e4a0 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -633,6 +633,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 	if (!kvm_arm_vcpu_is_finalized(vcpu))
 		return -EPERM;
 
+	if (kvm_vcpu_has_spe(vcpu) && kvm_spe_check_supported_cpus(vcpu))
+		return -EPERM;
+
 	vcpu->arch.has_run_once = true;
 
 	kvm_arm_vcpu_init_debug(vcpu);
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 83f92245f881..8d2afc137151 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -30,3 +30,15 @@ void kvm_spe_vm_init(struct kvm *kvm)
 	/* Set supported_cpus if it isn't already initialized. */
 	kvm_spe_init_supported_cpus();
 }
+
+int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu)
+{
+	/* SPE is supported on all CPUs, we don't care about the VCPU mask */
+	if (cpumask_equal(supported_cpus, cpu_possible_mask))
+		return 0;
+
+	if (!cpumask_subset(&vcpu->arch.supported_cpus, supported_cpus))
+		return -ENOEXEC;
+
+	return 0;
+}
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:56 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:56 +0100
Subject: [RFC PATCH v4 20/39] KVM: arm64: Add a new VCPU device control group
 for SPE
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-21-alexandru.elisei@arm.com>

From: Sudeep Holla <sudeep.holla at arm.com>

Add a new VCPU device control group to control various aspects of KVM's SPE
emulation. Functionality will be added in later patches.

[ Alexandru E: Rewrote patch ]

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/devices/vcpu.rst |  5 +++++
 arch/arm64/include/asm/kvm_spe.h        | 20 ++++++++++++++++++++
 arch/arm64/include/uapi/asm/kvm.h       |  1 +
 arch/arm64/kvm/guest.c                  | 10 ++++++++++
 arch/arm64/kvm/spe.c                    | 15 +++++++++++++++
 5 files changed, 51 insertions(+)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 2acec3b9ef65..85399c005197 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -161,3 +161,8 @@ Specifies the base address of the stolen time structure for this VCPU. The
 base address must be 64 byte aligned and exist within a valid guest memory
 region. See Documentation/virt/kvm/arm/pvtime.rst for more information
 including the layout of the stolen time structure.
+
+4. GROUP: KVM_ARM_VCPU_SPE_CTRL
+===============================
+
+:Architectures: ARM64
diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index ed67ddbf8132..ce0f5b3f2027 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -17,12 +17,32 @@ static __always_inline bool kvm_supports_spe(void)
 void kvm_spe_init_supported_cpus(void);
 void kvm_spe_vm_init(struct kvm *kvm);
 int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu);
+
+int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
+int kvm_spe_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
+int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 #else
 #define kvm_supports_spe()	(false)
 
 static inline void kvm_spe_init_supported_cpus(void) {}
 static inline void kvm_spe_vm_init(struct kvm *kvm) {}
 static inline int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
+
+static inline int kvm_spe_set_attr(struct kvm_vcpu *vcpu,
+				   struct kvm_device_attr *attr)
+{
+	return -ENXIO;
+}
+static inline int kvm_spe_get_attr(struct kvm_vcpu *vcpu,
+				   struct kvm_device_attr *attr)
+{
+	return -ENXIO;
+}
+static inline int kvm_spe_has_attr(struct kvm_vcpu *vcpu,
+				   struct kvm_device_attr *attr)
+{
+	return -ENXIO;
+}
 #endif /* CONFIG_KVM_ARM_SPE */
 
 #endif /* __ARM64_KVM_SPE_H__ */
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 9f0a8ea50ea9..7159a1e23da2 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -368,6 +368,7 @@ struct kvm_arm_copy_mte_tags {
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
 #define KVM_ARM_VCPU_PVTIME_CTRL	2
 #define   KVM_ARM_VCPU_PVTIME_IPA	0
+#define KVM_ARM_VCPU_SPE_CTRL		3
 
 /* KVM_IRQ_LINE irq field index values */
 #define KVM_ARM_IRQ_VCPU2_SHIFT		28
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 1dfb83578277..316110b5dd95 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -24,6 +24,7 @@
 #include <asm/fpsimd.h>
 #include <asm/kvm.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_spe.h>
 #include <asm/sigcontext.h>
 
 #include "trace.h"
@@ -962,6 +963,9 @@ int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
 	case KVM_ARM_VCPU_PVTIME_CTRL:
 		ret = kvm_arm_pvtime_set_attr(vcpu, attr);
 		break;
+	case KVM_ARM_VCPU_SPE_CTRL:
+		ret = kvm_spe_set_attr(vcpu, attr);
+		break;
 	default:
 		ret = -ENXIO;
 		break;
@@ -985,6 +989,9 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
 	case KVM_ARM_VCPU_PVTIME_CTRL:
 		ret = kvm_arm_pvtime_get_attr(vcpu, attr);
 		break;
+	case KVM_ARM_VCPU_SPE_CTRL:
+		ret = kvm_spe_get_attr(vcpu, attr);
+		break;
 	default:
 		ret = -ENXIO;
 		break;
@@ -1008,6 +1015,9 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
 	case KVM_ARM_VCPU_PVTIME_CTRL:
 		ret = kvm_arm_pvtime_has_attr(vcpu, attr);
 		break;
+	case KVM_ARM_VCPU_SPE_CTRL:
+		ret = kvm_spe_has_attr(vcpu, attr);
+		break;
 	default:
 		ret = -ENXIO;
 		break;
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 8d2afc137151..56a3fdb35623 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -42,3 +42,18 @@ int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu)
 
 	return 0;
 }
+
+int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+{
+	return -ENXIO;
+}
+
+int kvm_spe_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+{
+	return -ENXIO;
+}
+
+int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
+{
+	return -ENXIO;
+}
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:57 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:57 +0100
Subject: [RFC PATCH v4 21/39] KVM: arm64: Add SPE VCPU device attribute to set
 the interrupt number
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-22-alexandru.elisei@arm.com>

From: Sudeep Holla <sudeep.holla at arm.com>

Add KVM_ARM_VCPU_SPE_CTRL(KVM_ARM_VCPU_SPE_IRQ) to allow the user to set
the interrupt number for the buffer management interrupt.

[ Alexandru E: Split from "KVM: arm64: Add a new VCPU device control group
               for SPE" ]

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/devices/vcpu.rst | 19 ++++++
 arch/arm64/include/asm/kvm_host.h       |  2 +
 arch/arm64/include/asm/kvm_spe.h        | 10 +++
 arch/arm64/include/uapi/asm/kvm.h       |  1 +
 arch/arm64/kvm/spe.c                    | 86 +++++++++++++++++++++++++
 5 files changed, 118 insertions(+)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 85399c005197..05821d40849f 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -166,3 +166,22 @@ including the layout of the stolen time structure.
 ===============================
 
 :Architectures: ARM64
+
+4.1 ATTRIBUTE: KVM_ARM_VCPU_SPE_IRQ
+-----------------------------------
+
+:Parameters: in kvm_device_attr.addr the address for the Profiling Buffer
+             management interrupt number as a pointer to an int
+
+Returns:
+
+	 =======  ======================================================
+	 -EBUSY   Interrupt number already set for this VCPU
+	 -EFAULT  Error accessing the buffer management interrupt number
+	 -EINVAL  Invalid interrupt number
+	 -ENXIO   SPE not supported or not properly configured
+	 =======  ======================================================
+
+Specifies the Profiling Buffer management interrupt number. The interrupt number
+must be a PPI and the interrupt number must be the same for each VCPU. SPE
+emulation requires an in-kernel vGIC implementation.
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 948adb152104..7b957e439b3d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -26,6 +26,7 @@
 #include <asm/fpsimd.h>
 #include <asm/kvm.h>
 #include <asm/kvm_asm.h>
+#include <asm/kvm_spe.h>
 #include <asm/thread_info.h>
 
 #define __KVM_HAVE_ARCH_INTC_INITIALIZED
@@ -353,6 +354,7 @@ struct kvm_vcpu_arch {
 	struct vgic_cpu vgic_cpu;
 	struct arch_timer_cpu timer_cpu;
 	struct kvm_pmu pmu;
+	struct kvm_vcpu_spe spe;
 
 	/*
 	 * Anything that is not used directly from assembly code goes
diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index ce0f5b3f2027..2fe11868719d 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -6,6 +6,8 @@
 #ifndef __ARM64_KVM_SPE_H__
 #define __ARM64_KVM_SPE_H__
 
+#include <linux/kvm.h>
+
 #ifdef CONFIG_KVM_ARM_SPE
 DECLARE_STATIC_KEY_FALSE(kvm_spe_available);
 
@@ -14,6 +16,11 @@ static __always_inline bool kvm_supports_spe(void)
 	return static_branch_likely(&kvm_spe_available);
 }
 
+struct kvm_vcpu_spe {
+	bool initialized;	/* SPE initialized for the VCPU */
+	int irq_num;		/* Buffer management interrut number */
+};
+
 void kvm_spe_init_supported_cpus(void);
 void kvm_spe_vm_init(struct kvm *kvm);
 int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu);
@@ -24,6 +31,9 @@ int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 #else
 #define kvm_supports_spe()	(false)
 
+struct kvm_vcpu_spe {
+};
+
 static inline void kvm_spe_init_supported_cpus(void) {}
 static inline void kvm_spe_vm_init(struct kvm *kvm) {}
 static inline int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 7159a1e23da2..c55d94a1a8f5 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -369,6 +369,7 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_ARM_VCPU_PVTIME_CTRL	2
 #define   KVM_ARM_VCPU_PVTIME_IPA	0
 #define KVM_ARM_VCPU_SPE_CTRL		3
+#define   KVM_ARM_VCPU_SPE_IRQ		0
 
 /* KVM_IRQ_LINE irq field index values */
 #define KVM_ARM_IRQ_VCPU2_SHIFT		28
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 56a3fdb35623..2fdb42e27675 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -43,17 +43,103 @@ int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+static bool kvm_vcpu_supports_spe(struct kvm_vcpu *vcpu)
+{
+	if (!kvm_supports_spe())
+		return false;
+
+	if (!kvm_vcpu_has_spe(vcpu))
+		return false;
+
+	if (!irqchip_in_kernel(vcpu->kvm))
+		return false;
+
+	return true;
+}
+
+static bool kvm_spe_irq_is_valid(struct kvm *kvm, int irq)
+{
+	struct kvm_vcpu *vcpu;
+	int i;
+
+	if (!irq_is_ppi(irq))
+		return -EINVAL;
+
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		if (!vcpu->arch.spe.irq_num)
+			continue;
+
+		if (vcpu->arch.spe.irq_num != irq)
+			return false;
+	}
+
+	return true;
+}
+
 int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 {
+	if (!kvm_vcpu_supports_spe(vcpu))
+		return -ENXIO;
+
+	if (vcpu->arch.spe.initialized)
+		return -EBUSY;
+
+	switch (attr->attr) {
+	case KVM_ARM_VCPU_SPE_IRQ: {
+		int __user *uaddr = (int __user *)(long)attr->addr;
+		int irq;
+
+		if (vcpu->arch.spe.irq_num)
+			return -EBUSY;
+
+		if (get_user(irq, uaddr))
+			return -EFAULT;
+
+		if (!kvm_spe_irq_is_valid(vcpu->kvm, irq))
+			return -EINVAL;
+
+		kvm_debug("Set KVM_ARM_VCPU_SPE_IRQ: %d\n", irq);
+		vcpu->arch.spe.irq_num = irq;
+		return 0;
+	}
+	}
+
 	return -ENXIO;
 }
 
 int kvm_spe_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 {
+	if (!kvm_vcpu_supports_spe(vcpu))
+		return -ENXIO;
+
+	switch (attr->attr) {
+	case KVM_ARM_VCPU_SPE_IRQ: {
+		int __user *uaddr = (int __user *)(long)attr->addr;
+		int irq;
+
+		if (!vcpu->arch.spe.irq_num)
+			return -ENXIO;
+
+		irq = vcpu->arch.spe.irq_num;
+		if (put_user(irq, uaddr))
+			return -EFAULT;
+
+		return 0;
+	}
+	}
+
 	return -ENXIO;
 }
 
 int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 {
+	if (!kvm_vcpu_supports_spe(vcpu))
+		return -ENXIO;
+
+	switch(attr->attr) {
+	case KVM_ARM_VCPU_SPE_IRQ:
+		return 0;
+	}
+
 	return -ENXIO;
 }
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:58 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:58 +0100
Subject: [RFC PATCH v4 22/39] KVM: arm64: Add SPE VCPU device attribute to
 initialize SPE
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-23-alexandru.elisei@arm.com>

From: Sudeep Holla <sudeep.holla at arm.com>

Add KVM_ARM_VCPU_SPE_CTRL(KVM_ARM_VCPU_SPE_INIT) VCPU ioctl to initialize
SPE. Initialization can only be done once for a VCPU. If the feature bit is
set, then SPE must be initialized before the VCPU can be run.

[ Alexandru E: Split from "KVM: arm64: Add a new VCPU device control group
	       for SPE" ]

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/devices/vcpu.rst | 16 ++++++++++++++
 arch/arm64/include/asm/kvm_spe.h        |  4 ++--
 arch/arm64/include/uapi/asm/kvm.h       |  1 +
 arch/arm64/kvm/arm.c                    |  7 ++++--
 arch/arm64/kvm/spe.c                    | 29 ++++++++++++++++++++++++-
 5 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 05821d40849f..c275c320e500 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -185,3 +185,19 @@ Returns:
 Specifies the Profiling Buffer management interrupt number. The interrupt number
 must be a PPI and the interrupt number must be the same for each VCPU. SPE
 emulation requires an in-kernel vGIC implementation.
+
+4.2 ATTRIBUTE: KVM_ARM_VCPU_SPE_INIT
+-----------------------------------
+
+:Parameters: no additional parameter in kvm_device_attr.addr
+
+Returns:
+
+	 =======  ============================================
+	 -EBUSY   SPE already initialized for this VCPU
+	 -ENXIO   SPE not supported or not properly configured
+	 =======  ============================================
+
+Request initialization of the Statistical Profiling Extension for this VCPU.
+Must be done after initializaing the in-kernel irqchip and after setting the
+Profiling Buffer management interrupt number for the VCPU.
diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index 2fe11868719d..2217b821ab37 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -23,7 +23,7 @@ struct kvm_vcpu_spe {
 
 void kvm_spe_init_supported_cpus(void);
 void kvm_spe_vm_init(struct kvm *kvm);
-int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu);
+int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu);
 
 int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 int kvm_spe_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
@@ -36,7 +36,7 @@ struct kvm_vcpu_spe {
 
 static inline void kvm_spe_init_supported_cpus(void) {}
 static inline void kvm_spe_vm_init(struct kvm *kvm) {}
-static inline int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
+static inline int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
 
 static inline int kvm_spe_set_attr(struct kvm_vcpu *vcpu,
 				   struct kvm_device_attr *attr)
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index c55d94a1a8f5..d4c0b53a5fb2 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -370,6 +370,7 @@ struct kvm_arm_copy_mte_tags {
 #define   KVM_ARM_VCPU_PVTIME_IPA	0
 #define KVM_ARM_VCPU_SPE_CTRL		3
 #define   KVM_ARM_VCPU_SPE_IRQ		0
+#define   KVM_ARM_VCPU_SPE_INIT		1
 
 /* KVM_IRQ_LINE irq field index values */
 #define KVM_ARM_IRQ_VCPU2_SHIFT		28
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 8f7025f2e4a0..6af7ef26d2c1 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -633,8 +633,11 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 	if (!kvm_arm_vcpu_is_finalized(vcpu))
 		return -EPERM;
 
-	if (kvm_vcpu_has_spe(vcpu) && kvm_spe_check_supported_cpus(vcpu))
-		return -EPERM;
+	if (kvm_vcpu_has_spe(vcpu)) {
+		ret = kvm_spe_vcpu_first_run_init(vcpu);
+		if (ret)
+			return ret;
+	}
 
 	vcpu->arch.has_run_once = true;
 
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 2fdb42e27675..801ceb66a3d0 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -31,7 +31,7 @@ void kvm_spe_vm_init(struct kvm *kvm)
 	kvm_spe_init_supported_cpus();
 }
 
-int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu)
+static int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu)
 {
 	/* SPE is supported on all CPUs, we don't care about the VCPU mask */
 	if (cpumask_equal(supported_cpus, cpu_possible_mask))
@@ -43,6 +43,20 @@ int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu)
+{
+	int ret;
+
+	ret = kvm_spe_check_supported_cpus(vcpu);
+	if (ret)
+		return ret;
+
+	if (!vcpu->arch.spe.initialized)
+		return -EPERM;
+
+	return 0;
+}
+
 static bool kvm_vcpu_supports_spe(struct kvm_vcpu *vcpu)
 {
 	if (!kvm_supports_spe())
@@ -102,6 +116,18 @@ int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 		vcpu->arch.spe.irq_num = irq;
 		return 0;
 	}
+	case KVM_ARM_VCPU_SPE_INIT:
+		if (!vcpu->arch.spe.irq_num)
+			return -ENXIO;
+
+		if (!vgic_initialized(vcpu->kvm))
+			return -ENXIO;
+
+		if (kvm_vgic_set_owner(vcpu, vcpu->arch.spe.irq_num, &vcpu->arch.spe))
+			return -ENXIO;
+
+		vcpu->arch.spe.initialized = true;
+		return 0;
 	}
 
 	return -ENXIO;
@@ -138,6 +164,7 @@ int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 
 	switch(attr->attr) {
 	case KVM_ARM_VCPU_SPE_IRQ:
+	case KVM_ARM_VCPU_SPE_INIT:
 		return 0;
 	}
 
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:17:59 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:17:59 +0100
Subject: [RFC PATCH v4 23/39] KVM: arm64: VHE: Clear MDCR_EL2.E2PB in
 vcpu_put()
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-24-alexandru.elisei@arm.com>

From: Sudeep Holla <sudeep.holla at arm.com>

On VHE systems, the kernel executes at EL2 and configures the profiling
buffer to use the EL2&0 translation regime and to trap accesses from the
guest by clearing MDCR_EL2.E2PB. In vcpu_put(), KVM does a bitwise or with
the E2PB mask, preserving its value. This has been correct so far, since
MDCR_EL2.E2B has the same value (0b00) for all VMs, as set by
kvm_arm_setup_mdcr_el2().

However, this will change when KVM enables support for SPE in guests. For
such guests KVM will configure the profiling buffer to use the EL1&0
translation regime, a setting that is obviously undesirable to be preserved
for the host running at EL2. Let's avoid this situation by explicitly
clearing E2PB in vcpu_put().

[ Alexandru E: Reworded commit ]

Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index b3229924d243..86d4c8c33f3e 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -95,9 +95,7 @@ void deactivate_traps_vhe_put(void)
 {
 	u64 mdcr_el2 = read_sysreg(mdcr_el2);
 
-	mdcr_el2 &= MDCR_EL2_HPMN_MASK |
-		    MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT |
-		    MDCR_EL2_TPMS;
+	mdcr_el2 &= MDCR_EL2_HPMN_MASK | MDCR_EL2_TPMS;
 
 	write_sysreg(mdcr_el2, mdcr_el2);
 
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:00 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:00 +0100
Subject: [RFC PATCH v4 24/39] KVM: arm64: debug: Configure MDCR_EL2 when a
 VCPU has SPE
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-25-alexandru.elisei@arm.com>

Allow the guest running at EL1 to use SPE when that feature is enabled for
the VCPU by setting the profiling buffer owning translation regime to EL1&0
and disabling traps to the profiling control registers. Keep trapping
accesses to the buffer control registers because that's needed to emulate
the buffer management interrupt.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_arm.h |  1 +
 arch/arm64/kvm/debug.c           | 23 +++++++++++++++++++----
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index d436831dd706..d939da6f54dc 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -285,6 +285,7 @@
 #define MDCR_EL2_TPMS		(1 << 14)
 #define MDCR_EL2_E2PB_MASK	(UL(0x3))
 #define MDCR_EL2_E2PB_SHIFT	(UL(12))
+#define MDCR_EL2_E2PB_EL1_TRAP	(UL(2))
 #define MDCR_EL2_TDRA		(1 << 11)
 #define MDCR_EL2_TDOSA		(1 << 10)
 #define MDCR_EL2_TDA		(1 << 9)
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index d5e79d7ee6e9..64e8211366b6 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -77,24 +77,39 @@ void kvm_arm_init_debug(void)
  *  - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR)
  *  - Debug ROM Address (MDCR_EL2_TDRA)
  *  - OS related registers (MDCR_EL2_TDOSA)
- *  - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB)
  *  - Self-hosted Trace Filter controls (MDCR_EL2_TTRF)
  *  - Self-hosted Trace (MDCR_EL2_TTRF/MDCR_EL2_E2TB)
  */
 static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
 {
 	/*
-	 * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK
-	 * to disable guest access to the profiling and trace buffers
+	 * This also clears MDCR_EL2_E2TB_MASK to disable guest access to the
+	 * trace buffers.
 	 */
 	vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
 	vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
-				MDCR_EL2_TPMS |
 				MDCR_EL2_TTRF |
 				MDCR_EL2_TPMCR |
 				MDCR_EL2_TDRA |
 				MDCR_EL2_TDOSA);
 
+	if (kvm_supports_spe() && kvm_vcpu_has_spe(vcpu)) {
+		/*
+		 * Use EL1&0 for the profiling buffer translation regime and
+		 * trap accesses to the buffer control registers; leave
+		 * MDCR_EL2.TPMS unset and do not trap accesses to the profiling
+		 * control registers.
+		 */
+		vcpu->arch.mdcr_el2 |= MDCR_EL2_E2PB_EL1_TRAP << MDCR_EL2_E2PB_SHIFT;
+	} else {
+		/*
+		 * Trap accesses to the profiling control registers; leave
+		 * MDCR_EL2.E2PB unset and use the EL2&0 translation regime for
+		 * the profiling buffer.
+		 */
+		vcpu->arch.mdcr_el2 |= MDCR_EL2_TPMS;
+	}
+
 	/* Is the VM being debugged by userspace? */
 	if (vcpu->guest_debug)
 		/* Route all software debug exceptions to EL2 */
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:01 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:01 +0100
Subject: [RFC PATCH v4 25/39] KVM: arm64: Move the write to MDCR_EL2 out of
 __activate_traps_common()
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-26-alexandru.elisei@arm.com>

To run a guest with SPE, MDCR_EL2 must be configured such that the buffer
owning regime is EL1&0. With VHE enabled, the guest runs at EL2 and
changing the owning regime to EL1&0 too early in vcpu_put() would mean
creating an extended blackout window for the host.

Move the MDCR_EL2 write out of __activate_traps_common() to prepare for
executing it later in the run loop in the VHE case. This also makes
__activate_traps_common() look more like __deactivate_traps_common(), which
does not touch the register.

No functional change intended.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 1 -
 arch/arm64/kvm/hyp/nvhe/switch.c        | 2 ++
 arch/arm64/kvm/hyp/vhe/switch.c         | 2 ++
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e4a2f295a394..5084a54d012e 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -92,7 +92,6 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
 		write_sysreg(0, pmselr_el0);
 		write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
 	}
-	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
 }
 
 static inline void __deactivate_traps_common(void)
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index f7af9688c1f7..0c70d897a493 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -41,6 +41,8 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 	___activate_traps(vcpu);
 	__activate_traps_common(vcpu);
 
+	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
+
 	val = CPTR_EL2_DEFAULT;
 	val |= CPTR_EL2_TTA | CPTR_EL2_TAM;
 	if (!update_fp_enabled(vcpu)) {
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 86d4c8c33f3e..983ba1570d72 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -89,6 +89,8 @@ NOKPROBE_SYMBOL(__deactivate_traps);
 void activate_traps_vhe_load(struct kvm_vcpu *vcpu)
 {
 	__activate_traps_common(vcpu);
+
+	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
 }
 
 void deactivate_traps_vhe_put(void)
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:02 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:02 +0100
Subject: [RFC PATCH v4 26/39] KVM: arm64: VHE: Change MDCR_EL2 at world switch
 if VCPU has SPE
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-27-alexandru.elisei@arm.com>

When a VCPU has the SPE feature, MDCR_EL2 sets the buffer owning regime to
EL1&0. Write the guest's MDCR_EL2 value as late as possible and restore the
host's value as soon as possible at each world switch to make the profiling
blackout window as small as possible for the host.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_hyp.h   |  2 +-
 arch/arm64/kvm/debug.c             | 14 +++++++++++--
 arch/arm64/kvm/hyp/vhe/switch.c    | 33 +++++++++++++++++++++++-------
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c |  2 +-
 4 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 9d60b3006efc..657d0c94cf82 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -95,7 +95,7 @@ void __sve_restore_state(void *sve_pffr, u32 *fpsr);
 
 #ifndef __KVM_NVHE_HYPERVISOR__
 void activate_traps_vhe_load(struct kvm_vcpu *vcpu);
-void deactivate_traps_vhe_put(void);
+void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu);
 #endif
 
 u64 __guest_enter(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 64e8211366b6..70712cd85f32 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -249,9 +249,19 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 		vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY;
 
 	/* Write mdcr_el2 changes since vcpu_load on VHE systems */
-	if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2)
-		write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
+	if (has_vhe()) {
+		/*
+		 * MDCR_EL2 can modify the SPE buffer owning regime, defer the
+		 * write until the VCPU is run.
+		 */
+		if (kvm_vcpu_has_spe(vcpu))
+			goto out;
+
+		if (orig_mdcr_el2 != vcpu->arch.mdcr_el2)
+			write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
+	}
 
+out:
 	trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1));
 }
 
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 983ba1570d72..ec4e179d56ae 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -31,12 +31,29 @@ DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
 DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
 
+static void __restore_host_mdcr_el2(struct kvm_vcpu *vcpu)
+{
+	u64 mdcr_el2;
+
+	mdcr_el2 = read_sysreg(mdcr_el2);
+	mdcr_el2 &= MDCR_EL2_HPMN_MASK | MDCR_EL2_TPMS;
+	write_sysreg(mdcr_el2, mdcr_el2);
+}
+
+static void __restore_guest_mdcr_el2(struct kvm_vcpu *vcpu)
+{
+	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
+}
+
 static void __activate_traps(struct kvm_vcpu *vcpu)
 {
 	u64 val;
 
 	___activate_traps(vcpu);
 
+	if (kvm_vcpu_has_spe(vcpu))
+		__restore_guest_mdcr_el2(vcpu);
+
 	val = read_sysreg(cpacr_el1);
 	val |= CPACR_EL1_TTA;
 	val &= ~CPACR_EL1_ZEN;
@@ -81,7 +98,11 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 	 */
 	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
 
+	if (kvm_vcpu_has_spe(vcpu))
+		__restore_host_mdcr_el2(vcpu);
+
 	write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
+
 	write_sysreg(vectors, vbar_el1);
 }
 NOKPROBE_SYMBOL(__deactivate_traps);
@@ -90,16 +111,14 @@ void activate_traps_vhe_load(struct kvm_vcpu *vcpu)
 {
 	__activate_traps_common(vcpu);
 
-	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
+	if (!kvm_vcpu_has_spe(vcpu))
+		__restore_guest_mdcr_el2(vcpu);
 }
 
-void deactivate_traps_vhe_put(void)
+void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu)
 {
-	u64 mdcr_el2 = read_sysreg(mdcr_el2);
-
-	mdcr_el2 &= MDCR_EL2_HPMN_MASK | MDCR_EL2_TPMS;
-
-	write_sysreg(mdcr_el2, mdcr_el2);
+	if (!kvm_vcpu_has_spe(vcpu))
+		__restore_host_mdcr_el2(vcpu);
 
 	__deactivate_traps_common();
 }
diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index 2a0b8c88d74f..007a12dd4351 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -101,7 +101,7 @@ void kvm_vcpu_put_sysregs_vhe(struct kvm_vcpu *vcpu)
 	struct kvm_cpu_context *host_ctxt;
 
 	host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
-	deactivate_traps_vhe_put();
+	deactivate_traps_vhe_put(vcpu);
 
 	__sysreg_save_el1_state(guest_ctxt);
 	__sysreg_save_user_state(guest_ctxt);
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:03 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:03 +0100
Subject: [RFC PATCH v4 27/39] KVM: arm64: Add SPE system registers to VCPU
 context
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-28-alexandru.elisei@arm.com>

Add the SPE system registers to the VCPU context. Omitted are
PMBIDR_EL1, which cannot be trapped, and PMSIR_EL1, which is a read-only
register. The registers that KVM traps are stored in the sys_regs array
on a write, and returned on a read; complete emulation and save/restore
for all registers on world switch will be added a future patches.

KVM exposes FEAT_SPEv1p1 to guests in the ID_AA64DFR0_EL1 register and
doesn't trap accesses to the profiling control registers. If the hardware
supports FEAT_SPEv1p2, the guest will be able to access the PMSNEVFR_EL1
register, which is UNDEFINED for FEAT_SPEv1p1. However, that
inconsistency is somewhat consistent with the architecture because
PMBIDR_EL1 behaves similarly: the register is UNDEFINED if SPE is missing,
but a VCPU without the SPE feature can still read the register because
there is no (easy) way for KVM to trap accesses to the register.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 12 +++++++
 arch/arm64/include/asm/kvm_spe.h  |  7 ++++
 arch/arm64/kvm/spe.c              | 10 ++++++
 arch/arm64/kvm/sys_regs.c         | 54 ++++++++++++++++++++++++-------
 4 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7b957e439b3d..4c0d3d5ba285 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -237,6 +237,18 @@ enum vcpu_sysreg {
 	TFSR_EL1,	/* Tag Fault Status Register (EL1) */
 	TFSRE0_EL1,	/* Tag Fault Status Register (EL0) */
 
+       /* Statistical Profiling Extension Registers. */
+	PMSCR_EL1,      /* Statistical Profiling Control Register */
+	PMSICR_EL1,     /* Sampling Interval Counter Register */
+	PMSIRR_EL1,     /* Sampling Interval Reload Register */
+	PMSFCR_EL1,     /* Sampling Filter Control Register */
+	PMSEVFR_EL1,    /* Sampling Event Filter Register */
+	PMSLATFR_EL1,   /* Sampling Latency Filter Register */
+	PMBLIMITR_EL1,  /* Profiling Buffer Limit Address Register */
+	PMBPTR_EL1,     /* Profiling Buffer Write Pointer Register */
+	PMBSR_EL1,      /* Profiling Buffer Status/syndrome Register */
+	PMSCR_EL2,	/* Statistical Profiling Control Register, EL2 */
+
 	/* 32bit specific registers. Keep them at the end of the range */
 	DACR32_EL2,	/* Domain Access Control Register */
 	IFSR32_EL2,	/* Instruction Fault Status Register */
diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index 2217b821ab37..934eedb0de46 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -25,9 +25,13 @@ void kvm_spe_init_supported_cpus(void);
 void kvm_spe_vm_init(struct kvm *kvm);
 int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu);
 
+void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val);
+u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg);
+
 int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 int kvm_spe_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
+
 #else
 #define kvm_supports_spe()	(false)
 
@@ -38,6 +42,9 @@ static inline void kvm_spe_init_supported_cpus(void) {}
 static inline void kvm_spe_vm_init(struct kvm *kvm) {}
 static inline int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
 
+static inline void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val) {}
+static inline u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg) { return 0; }
+
 static inline int kvm_spe_set_attr(struct kvm_vcpu *vcpu,
 				   struct kvm_device_attr *attr)
 {
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 801ceb66a3d0..f760ccd8306a 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -57,6 +57,16 @@ int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val)
+{
+	__vcpu_sys_reg(vcpu, reg) = val;
+}
+
+u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg)
+{
+	return __vcpu_sys_reg(vcpu, reg);
+}
+
 static bool kvm_vcpu_supports_spe(struct kvm_vcpu *vcpu)
 {
 	if (!kvm_supports_spe())
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ab7370b7a44b..843822be5695 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -594,6 +594,33 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 	vcpu_write_sys_reg(vcpu, (1ULL << 31) | mpidr, MPIDR_EL1);
 }
 
+static unsigned int spe_visibility(const struct kvm_vcpu *vcpu,
+				  const struct sys_reg_desc *r)
+{
+	if (kvm_vcpu_has_spe(vcpu))
+		return 0;
+
+	return REG_HIDDEN;
+}
+
+static bool access_spe_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			   const struct sys_reg_desc *r)
+{	int reg = r->reg;
+	u64 val = p->regval;
+
+	if (reg < PMBLIMITR_EL1) {
+		print_sys_reg_msg(p, "Unsupported guest SPE register access at: %lx [%08lx]\n",
+				  *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
+	}
+
+	if (p->is_write)
+		kvm_spe_write_sysreg(vcpu, reg, val);
+	else
+		p->regval = kvm_spe_read_sysreg(vcpu, reg);
+
+	return true;
+}
+
 static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu,
 				   const struct sys_reg_desc *r)
 {
@@ -956,6 +983,10 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 	{ PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)),				\
 	  .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), }
 
+#define SPE_SYS_REG(r)							\
+	SYS_DESC(r), .access = access_spe_reg, .reset = reset_val,	\
+	.val = 0, .visibility = spe_visibility
+
 static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 			 const struct sys_reg_desc *r)
 {
@@ -1530,18 +1561,17 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
 	{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
 
-	{ SYS_DESC(SYS_PMSCR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMSNEVFR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMSICR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMSIRR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMSFCR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMSEVFR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMSLATFR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMSIDR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMBLIMITR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMBPTR_EL1), undef_access },
-	{ SYS_DESC(SYS_PMBSR_EL1), undef_access },
-	/* PMBIDR_EL1 is not trapped */
+	{ SPE_SYS_REG(SYS_PMSCR_EL1), .reg = PMSCR_EL1 },
+	{ SPE_SYS_REG(SYS_PMSICR_EL1), .reg = PMSICR_EL1 },
+	{ SPE_SYS_REG(SYS_PMSIRR_EL1), .reg = PMSIRR_EL1 },
+	{ SPE_SYS_REG(SYS_PMSFCR_EL1), .reg = PMSFCR_EL1 },
+	{ SPE_SYS_REG(SYS_PMSEVFR_EL1), .reg = PMSEVFR_EL1 },
+	{ SPE_SYS_REG(SYS_PMSLATFR_EL1), .reg = PMSLATFR_EL1 },
+	{ SPE_SYS_REG(SYS_PMSIDR_EL1), .reset = NULL },
+	{ SPE_SYS_REG(SYS_PMBLIMITR_EL1), .reg = PMBLIMITR_EL1 },
+	{ SPE_SYS_REG(SYS_PMBPTR_EL1), .reg = PMBPTR_EL1 },
+	{ SPE_SYS_REG(SYS_PMBSR_EL1), .reg = PMBSR_EL1 },
+	/* PMBIDR_EL1 and PMSCR_EL2 are not trapped */
 
 	{ PMU_SYS_REG(SYS_PMINTENSET_EL1),
 	  .access = access_pminten, .reg = PMINTENSET_EL1 },
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:04 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:04 +0100
Subject: [RFC PATCH v4 28/39] KVM: arm64: nVHE: Save PMSCR_EL1 to the host
 context
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-29-alexandru.elisei@arm.com>

The SPE registers are now part of the KVM register context, use the host
context to save the value of PMSCR_EL1 instead of a dedicated field in
host_debug_state.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h  |  2 --
 arch/arm64/include/asm/kvm_hyp.h   |  6 ++++--
 arch/arm64/kvm/hyp/nvhe/debug-sr.c | 10 ++++++----
 arch/arm64/kvm/hyp/nvhe/switch.c   |  4 ++--
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 4c0d3d5ba285..351b77dc7732 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -356,8 +356,6 @@ struct kvm_vcpu_arch {
 	struct {
 		/* {Break,watch}point registers */
 		struct kvm_guest_debug_arch regs;
-		/* Statistical profiling extension */
-		u64 pmscr_el1;
 		/* Self-hosted trace */
 		u64 trfcr_el1;
 	} host_debug_state;
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 657d0c94cf82..48619c2c0dc6 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -84,8 +84,10 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu);
 void __debug_switch_to_host(struct kvm_vcpu *vcpu);
 
 #ifdef __KVM_NVHE_HYPERVISOR__
-void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu);
-void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu);
+void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu,
+				    struct kvm_cpu_context *host_ctxt);
+void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu,
+				       struct kvm_cpu_context *host_ctxt);
 #endif
 
 void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 7d3f25868cae..6db58722f045 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -81,11 +81,12 @@ static void __debug_restore_trace(u64 trfcr_el1)
 	write_sysreg_s(trfcr_el1, SYS_TRFCR_EL1);
 }
 
-void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
+void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu,
+				    struct kvm_cpu_context *host_ctxt)
 {
 	/* Disable and flush SPE data generation */
 	if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE)
-		__debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1);
+		__debug_save_spe(__ctxt_sys_reg(host_ctxt, PMSCR_EL1));
 	/* Disable and flush Self-Hosted Trace generation */
 	if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE)
 		__debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1);
@@ -96,10 +97,11 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
 	__debug_switch_to_guest_common(vcpu);
 }
 
-void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
+void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu,
+				       struct kvm_cpu_context *host_ctxt)
 {
 	if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE)
-		__debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1);
+		__debug_restore_spe(ctxt_sys_reg(host_ctxt, PMSCR_EL1));
 	if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE)
 		__debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1);
 }
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 0c70d897a493..04d654e71a6e 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -200,7 +200,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 	 * translation regime to EL2 (via MDCR_EL2_E2PB == 0) and
 	 * before we load guest Stage1.
 	 */
-	__debug_save_host_buffers_nvhe(vcpu);
+	__debug_save_host_buffers_nvhe(vcpu, host_ctxt);
 
 	__kvm_adjust_pc(vcpu);
 
@@ -248,7 +248,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 	 * This must come after restoring the host sysregs, since a non-VHE
 	 * system may enable SPE here and make use of the TTBRs.
 	 */
-	__debug_restore_host_buffers_nvhe(vcpu);
+	__debug_restore_host_buffers_nvhe(vcpu, host_ctxt);
 
 	if (pmu_switch_needed)
 		__pmu_switch_to_host(host_ctxt);
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:05 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:05 +0100
Subject: [RFC PATCH v4 29/39] KVM: arm64: Rename DEBUG_STATE_SAVE_SPE ->
 DEBUG_SAVE_SPE_BUFFER flags
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-30-alexandru.elisei@arm.com>

Setting the KVM_ARM64_DEBUG_STATE_SAVE_SPE flag will stop profiling to
drain the buffer, if the buffer is enabled when switching to the guest, and
then re-enable profiling on the return to the host. Rename it to
KVM_ARM64_DEBUG_SAVE_SPE_BUFFER to avoid any confusion with what a SPE
enabled VCPU will do, which is to save and restore the full SPE state on a
world switch, and not just part of it, some of the time. This also matches
the name of the function __debug_save_host_buffers_nvhe(), which makes use
of the flag to decide if the buffer should be drained.

Similar treatment was applied to KVM_ARM64_DEBUG_STATE_SAVE_TRBE, which was
renamed to KVM_ARM64_DEBUG_SAVE_TRBE_BUFFER, for consistency and to better
reflect what it is doing.

CC: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h  | 24 ++++++++++++------------
 arch/arm64/kvm/debug.c             | 11 ++++++-----
 arch/arm64/kvm/hyp/nvhe/debug-sr.c |  8 ++++----
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 351b77dc7732..e704847a7645 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -439,18 +439,18 @@ struct kvm_vcpu_arch {
 })
 
 /* vcpu_arch flags field values: */
-#define KVM_ARM64_DEBUG_DIRTY		(1 << 0)
-#define KVM_ARM64_FP_ENABLED		(1 << 1) /* guest FP regs loaded */
-#define KVM_ARM64_FP_HOST		(1 << 2) /* host FP regs loaded */
-#define KVM_ARM64_HOST_SVE_IN_USE	(1 << 3) /* backup for host TIF_SVE */
-#define KVM_ARM64_HOST_SVE_ENABLED	(1 << 4) /* SVE enabled for EL0 */
-#define KVM_ARM64_GUEST_HAS_SVE		(1 << 5) /* SVE exposed to guest */
-#define KVM_ARM64_VCPU_SVE_FINALIZED	(1 << 6) /* SVE config completed */
-#define KVM_ARM64_GUEST_HAS_PTRAUTH	(1 << 7) /* PTRAUTH exposed to guest */
-#define KVM_ARM64_PENDING_EXCEPTION	(1 << 8) /* Exception pending */
-#define KVM_ARM64_EXCEPT_MASK		(7 << 9) /* Target EL/MODE */
-#define KVM_ARM64_DEBUG_STATE_SAVE_SPE	(1 << 12) /* Save SPE context if active  */
-#define KVM_ARM64_DEBUG_STATE_SAVE_TRBE	(1 << 13) /* Save TRBE context if active  */
+#define KVM_ARM64_DEBUG_DIRTY			(1 << 0)
+#define KVM_ARM64_FP_ENABLED			(1 << 1) /* guest FP regs loaded */
+#define KVM_ARM64_FP_HOST			(1 << 2) /* host FP regs loaded */
+#define KVM_ARM64_HOST_SVE_IN_USE		(1 << 3) /* backup for host TIF_SVE */
+#define KVM_ARM64_HOST_SVE_ENABLED		(1 << 4) /* SVE enabled for EL0 */
+#define KVM_ARM64_GUEST_HAS_SVE			(1 << 5) /* SVE exposed to guest */
+#define KVM_ARM64_VCPU_SVE_FINALIZED		(1 << 6) /* SVE config completed */
+#define KVM_ARM64_GUEST_HAS_PTRAUTH		(1 << 7) /* PTRAUTH exposed to guest */
+#define KVM_ARM64_PENDING_EXCEPTION		(1 << 8) /* Exception pending */
+#define KVM_ARM64_EXCEPT_MASK			(7 << 9) /* Target EL/MODE */
+#define KVM_ARM64_DEBUG_SAVE_SPE_BUFFER		(1 << 12) /* Save SPE buffer if active  */
+#define KVM_ARM64_DEBUG_SAVE_TRBE_BUFFER	(1 << 13) /* Save TRBE buffer if active  */
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
 				 KVM_GUESTDBG_USE_SW_BP | \
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 70712cd85f32..6e5fc1887215 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -299,22 +299,23 @@ void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu)
 		return;
 
 	dfr0 = read_sysreg(id_aa64dfr0_el1);
+
 	/*
 	 * If SPE is present on this CPU and is available at current EL,
-	 * we may need to check if the host state needs to be saved.
+	 * we may need to check if the host buffer needs to be drained.
 	 */
 	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_PMSVER_SHIFT) &&
 	    !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(SYS_PMBIDR_EL1_P_SHIFT)))
-		vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_SPE;
+		vcpu->arch.flags |= KVM_ARM64_DEBUG_SAVE_SPE_BUFFER;
 
 	/* Check if we have TRBE implemented and available at the host */
 	if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_TRBE_SHIFT) &&
 	    !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_PROG))
-		vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_TRBE;
+		vcpu->arch.flags |= KVM_ARM64_DEBUG_SAVE_TRBE_BUFFER;
 }
 
 void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu)
 {
-	vcpu->arch.flags &= ~(KVM_ARM64_DEBUG_STATE_SAVE_SPE |
-			      KVM_ARM64_DEBUG_STATE_SAVE_TRBE);
+	vcpu->arch.flags &= ~(KVM_ARM64_DEBUG_SAVE_SPE_BUFFER |
+			      KVM_ARM64_DEBUG_SAVE_TRBE_BUFFER);
 }
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 6db58722f045..186b90b5fd20 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -85,10 +85,10 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu,
 				    struct kvm_cpu_context *host_ctxt)
 {
 	/* Disable and flush SPE data generation */
-	if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE)
+	if (vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_SPE_BUFFER)
 		__debug_save_spe(__ctxt_sys_reg(host_ctxt, PMSCR_EL1));
 	/* Disable and flush Self-Hosted Trace generation */
-	if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE)
+	if (vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_TRBE_BUFFER)
 		__debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1);
 }
 
@@ -100,9 +100,9 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
 void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu,
 				       struct kvm_cpu_context *host_ctxt)
 {
-	if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE)
+	if (vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_SPE_BUFFER)
 		__debug_restore_spe(ctxt_sys_reg(host_ctxt, PMSCR_EL1));
-	if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE)
+	if (vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_TRBE_BUFFER)
 		__debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1);
 }
 
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:06 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:06 +0100
Subject: [RFC PATCH v4 30/39] KVM: arm64: nVHE: Context switch SPE state if
 VCPU has SPE
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-31-alexandru.elisei@arm.com>

For non-VHE systems, make the SPE register state part of the context that
is saved and restored at each world switch. The SPE buffer management
interrupt will be handled in a later patch.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_hyp.h        | 19 ++++++
 arch/arm64/kvm/hyp/include/hyp/spe-sr.h | 32 +++++++++
 arch/arm64/kvm/hyp/nvhe/Makefile        |  1 +
 arch/arm64/kvm/hyp/nvhe/debug-sr.c      |  6 +-
 arch/arm64/kvm/hyp/nvhe/spe-sr.c        | 87 +++++++++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/switch.c        | 29 +++++++--
 6 files changed, 165 insertions(+), 9 deletions(-)
 create mode 100644 arch/arm64/kvm/hyp/include/hyp/spe-sr.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/spe-sr.c

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 48619c2c0dc6..06e77a739458 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -88,6 +88,25 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu,
 				    struct kvm_cpu_context *host_ctxt);
 void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu,
 				       struct kvm_cpu_context *host_ctxt);
+#ifdef CONFIG_KVM_ARM_SPE
+void __spe_save_host_state_nvhe(struct kvm_vcpu *vcpu,
+				struct kvm_cpu_context *host_ctxt);
+void __spe_save_guest_state_nvhe(struct kvm_vcpu *vcpu,
+				 struct kvm_cpu_context *guest_ctxt);
+void __spe_restore_host_state_nvhe(struct kvm_vcpu *vcpu,
+				   struct kvm_cpu_context *host_ctxt);
+void __spe_restore_guest_state_nvhe(struct kvm_vcpu *vcpu,
+				    struct kvm_cpu_context *guest_ctxt);
+#else
+static inline void __spe_save_host_state_nvhe(struct kvm_vcpu *vcpu,
+					struct kvm_cpu_context *host_ctxt) {}
+static inline void __spe_save_guest_state_nvhe(struct kvm_vcpu *vcpu,
+					struct kvm_cpu_context *guest_ctxt) {}
+static inline void __spe_restore_host_state_nvhe(struct kvm_vcpu *vcpu,
+					struct kvm_cpu_context *host_ctxt) {}
+static inline void __spe_restore_guest_state_nvhe(struct kvm_vcpu *vcpu,
+					struct kvm_cpu_context *guest_ctxt) {}
+#endif
 #endif
 
 void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
diff --git a/arch/arm64/kvm/hyp/include/hyp/spe-sr.h b/arch/arm64/kvm/hyp/include/hyp/spe-sr.h
new file mode 100644
index 000000000000..d5f8f3ffc7d4
--- /dev/null
+++ b/arch/arm64/kvm/hyp/include/hyp/spe-sr.h
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 - ARM Ltd
+ * Author: Alexandru Elisei <alexandru.elisei at arm.com>
+ */
+
+#ifndef __ARM64_KVM_HYP_SPE_SR_H__
+#define __ARM64_KVM_HYP_SPE_SR_H__
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_asm.h>
+
+static inline void __spe_save_common_state(struct kvm_cpu_context *ctxt)
+{
+	ctxt_sys_reg(ctxt, PMSICR_EL1) = read_sysreg_s(SYS_PMSICR_EL1);
+	ctxt_sys_reg(ctxt, PMSIRR_EL1) = read_sysreg_s(SYS_PMSIRR_EL1);
+	ctxt_sys_reg(ctxt, PMSFCR_EL1) = read_sysreg_s(SYS_PMSFCR_EL1);
+	ctxt_sys_reg(ctxt, PMSEVFR_EL1) = read_sysreg_s(SYS_PMSEVFR_EL1);
+	ctxt_sys_reg(ctxt, PMSLATFR_EL1) = read_sysreg_s(SYS_PMSLATFR_EL1);
+}
+
+static inline void __spe_restore_common_state(struct kvm_cpu_context *ctxt)
+{
+	write_sysreg_s(ctxt_sys_reg(ctxt, PMSICR_EL1), SYS_PMSICR_EL1);
+	write_sysreg_s(ctxt_sys_reg(ctxt, PMSIRR_EL1), SYS_PMSIRR_EL1);
+	write_sysreg_s(ctxt_sys_reg(ctxt, PMSFCR_EL1), SYS_PMSFCR_EL1);
+	write_sysreg_s(ctxt_sys_reg(ctxt, PMSEVFR_EL1), SYS_PMSEVFR_EL1);
+	write_sysreg_s(ctxt_sys_reg(ctxt, PMSLATFR_EL1), SYS_PMSLATFR_EL1);
+}
+
+#endif /* __ARM64_KVM_HYP_SPE_SR_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 5df6193fc430..37dca45d85d5 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -15,6 +15,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
 obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
 	 hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
 	 cache.o setup.o mm.o mem_protect.o
+obj-$(CONFIG_KVM_ARM_SPE) += spe-sr.o
 obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
 obj-y += $(lib-objs)
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 186b90b5fd20..1622615954b2 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -85,7 +85,8 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu,
 				    struct kvm_cpu_context *host_ctxt)
 {
 	/* Disable and flush SPE data generation */
-	if (vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_SPE_BUFFER)
+	if (!kvm_vcpu_has_spe(vcpu) &&
+	    vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_SPE_BUFFER)
 		__debug_save_spe(__ctxt_sys_reg(host_ctxt, PMSCR_EL1));
 	/* Disable and flush Self-Hosted Trace generation */
 	if (vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_TRBE_BUFFER)
@@ -100,7 +101,8 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
 void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu,
 				       struct kvm_cpu_context *host_ctxt)
 {
-	if (vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_SPE_BUFFER)
+	if (!kvm_vcpu_has_spe(vcpu) &&
+	    vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_SPE_BUFFER)
 		__debug_restore_spe(ctxt_sys_reg(host_ctxt, PMSCR_EL1));
 	if (vcpu->arch.flags & KVM_ARM64_DEBUG_SAVE_TRBE_BUFFER)
 		__debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1);
diff --git a/arch/arm64/kvm/hyp/nvhe/spe-sr.c b/arch/arm64/kvm/hyp/nvhe/spe-sr.c
new file mode 100644
index 000000000000..46e47c9fd08f
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/spe-sr.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 - ARM Ltd
+ * Author: Alexandru Elisei <alexandru.elisei at arm.com>
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_hyp.h>
+
+#include <hyp/spe-sr.h>
+
+/*
+ * The owning exception level remains unchange from EL1 during the world switch,
+ * which means that profiling is disabled for as long as we execute at EL2. KVM
+ * does not need to explicitely disable profiling, like it does when the VCPU
+ * does not have SPE and we change buffer owning exception level, nor does it
+ * need to do any synchronization around sysreg save/restore.
+ */
+
+void __spe_save_host_state_nvhe(struct kvm_vcpu *vcpu,
+				struct kvm_cpu_context *host_ctxt)
+{
+	u64 pmblimitr;
+
+	pmblimitr = read_sysreg_s(SYS_PMBLIMITR_EL1);
+	if (pmblimitr & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)) {
+		psb_csync();
+		dsb(nsh);
+		/*
+		 * The buffer performs indirect writes to system registers, a
+		 * context synchronization event is needed before the new
+		 * PMBPTR_EL1 value is visible to subsequent direct reads.
+		 */
+		isb();
+	}
+
+	ctxt_sys_reg(host_ctxt, PMBPTR_EL1) = read_sysreg_s(SYS_PMBPTR_EL1);
+	ctxt_sys_reg(host_ctxt, PMBSR_EL1) = read_sysreg_s(SYS_PMBSR_EL1);
+	ctxt_sys_reg(host_ctxt, PMBLIMITR_EL1) = pmblimitr;
+	ctxt_sys_reg(host_ctxt, PMSCR_EL1) = read_sysreg_s(SYS_PMSCR_EL1);
+	ctxt_sys_reg(host_ctxt, PMSCR_EL2) = read_sysreg_el2(SYS_PMSCR);
+
+	__spe_save_common_state(host_ctxt);
+}
+
+void __spe_save_guest_state_nvhe(struct kvm_vcpu *vcpu,
+				 struct kvm_cpu_context *guest_ctxt)
+{
+	if (read_sysreg_s(SYS_PMBLIMITR_EL1) & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)) {
+		psb_csync();
+		dsb(nsh);
+		/* Ensure hardware updates to PMBPTR_EL1 are visible. */
+		isb();
+	}
+
+	ctxt_sys_reg(guest_ctxt, PMBPTR_EL1) = read_sysreg_s(SYS_PMBPTR_EL1);
+	ctxt_sys_reg(guest_ctxt, PMBSR_EL1) = read_sysreg_s(SYS_PMBSR_EL1);
+	/* PMBLIMITR_EL1 is updated only on a trapped write. */
+	ctxt_sys_reg(guest_ctxt, PMSCR_EL1) = read_sysreg_s(SYS_PMSCR_EL1);
+
+	__spe_save_common_state(guest_ctxt);
+}
+
+void __spe_restore_host_state_nvhe(struct kvm_vcpu *vcpu,
+				   struct kvm_cpu_context *host_ctxt)
+{
+	__spe_restore_common_state(host_ctxt);
+
+	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
+	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMBSR_EL1), SYS_PMBSR_EL1);
+	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
+	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMSCR_EL1), SYS_PMSCR_EL1);
+	write_sysreg_el2(ctxt_sys_reg(host_ctxt, PMSCR_EL2), SYS_PMSCR);
+}
+
+void __spe_restore_guest_state_nvhe(struct kvm_vcpu *vcpu,
+				    struct kvm_cpu_context *guest_ctxt)
+{
+	__spe_restore_common_state(guest_ctxt);
+
+	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
+	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBSR_EL1), SYS_PMBSR_EL1);
+	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
+	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMSCR_EL1), SYS_PMSCR_EL1);
+	write_sysreg_el2(0, SYS_PMSCR);
+}
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 04d654e71a6e..62ef2a5789ba 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -194,12 +194,16 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 
 	__sysreg_save_state_nvhe(host_ctxt);
 	/*
-	 * We must flush and disable the SPE buffer for nVHE, as
-	 * the translation regime(EL1&0) is going to be loaded with
-	 * that of the guest. And we must do this before we change the
-	 * translation regime to EL2 (via MDCR_EL2_E2PB == 0) and
-	 * before we load guest Stage1.
+	 * If the VCPU has the SPE feature bit set, then we save the host's SPE
+	 * context.
+	 *
+	 * Otherwise, we only flush and disable the SPE buffer for nVHE, as the
+	 * translation regime(EL1&0) is going to be loaded with that of the
+	 * guest. And we must do this before we change the translation regime to
+	 * EL2 (via MDCR_EL2_E2PB == 0) and before we load guest Stage1.
 	 */
+	if (kvm_vcpu_has_spe(vcpu))
+		__spe_save_host_state_nvhe(vcpu, host_ctxt);
 	__debug_save_host_buffers_nvhe(vcpu, host_ctxt);
 
 	__kvm_adjust_pc(vcpu);
@@ -218,6 +222,9 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 	__load_guest_stage2(kern_hyp_va(vcpu->arch.hw_mmu));
 	__activate_traps(vcpu);
 
+	if (kvm_vcpu_has_spe(vcpu))
+		__spe_restore_guest_state_nvhe(vcpu, guest_ctxt);
+
 	__hyp_vgic_restore_state(vcpu);
 	__timer_enable_traps(vcpu);
 
@@ -232,6 +239,10 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 
 	__sysreg_save_state_nvhe(guest_ctxt);
 	__sysreg32_save_state(vcpu);
+
+	if (kvm_vcpu_has_spe(vcpu))
+		__spe_save_guest_state_nvhe(vcpu, guest_ctxt);
+
 	__timer_disable_traps(vcpu);
 	__hyp_vgic_save_state(vcpu);
 
@@ -244,10 +255,14 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 		__fpsimd_save_fpexc32(vcpu);
 
 	__debug_switch_to_host(vcpu);
+
 	/*
-	 * This must come after restoring the host sysregs, since a non-VHE
-	 * system may enable SPE here and make use of the TTBRs.
+	 * Restoring the host context must come after restoring the host
+	 * sysregs, since a non-VHE system may enable SPE here and make use of
+	 * the TTBRs.
 	 */
+	if (kvm_vcpu_has_spe(vcpu))
+		__spe_restore_host_state_nvhe(vcpu, host_ctxt);
 	__debug_restore_host_buffers_nvhe(vcpu, host_ctxt);
 
 	if (pmu_switch_needed)
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:10 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:10 +0100
Subject: [RFC PATCH v4 34/39] KVM: arm64: Emulate SPE buffer management
 interrupt
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-35-alexandru.elisei@arm.com>

A profiling buffer management interrupt is asserted when the buffer fills,
on a fault or on an external abort. The service bit, PMBSR_EL1.S, is set as
long as SPE asserts this interrupt. The interrupt can also be asserted
following a direct write to PMBSR_EL1 that sets the bit. The SPE hardware
stops asserting the interrupt only when the service bit is cleared.

KVM emulates the interrupt by reading the value of the service bit on
each guest exit to determine if the SPE hardware asserted the interrupt
(for example, if the buffer was full). Writes to the buffer registers are
trapped, to determine when the interrupt should be cleared or when the
guest wants to explicitely assert the interrupt by setting the service bit.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_spe.h |  4 ++
 arch/arm64/kvm/arm.c             |  3 ++
 arch/arm64/kvm/hyp/nvhe/spe-sr.c | 28 +++++++++++--
 arch/arm64/kvm/hyp/vhe/spe-sr.c  | 17 ++++++--
 arch/arm64/kvm/spe.c             | 72 ++++++++++++++++++++++++++++++++
 5 files changed, 117 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index 272f1eec64f2..d7d7b9e243de 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -19,6 +19,8 @@ static __always_inline bool kvm_supports_spe(void)
 struct kvm_vcpu_spe {
 	bool initialized;	/* SPE initialized for the VCPU */
 	int irq_num;		/* Buffer management interrut number */
+	bool irq_level;		/* 'true' if the interrupt is asserted at the VGIC */
+	bool hwirq_level;	/* 'true' if the SPE hardware is asserting the interrupt */
 };
 
 struct kvm_spe {
@@ -28,6 +30,7 @@ struct kvm_spe {
 void kvm_spe_init_supported_cpus(void);
 void kvm_spe_vm_init(struct kvm *kvm);
 int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu);
+void kvm_spe_sync_hwstate(struct kvm_vcpu *vcpu);
 
 void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val);
 u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg);
@@ -51,6 +54,7 @@ struct kvm_spe {
 static inline void kvm_spe_init_supported_cpus(void) {}
 static inline void kvm_spe_vm_init(struct kvm *kvm) {}
 static inline int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
+static inline void kvm_spe_sync_hwstate(struct kvm_vcpu *vcpu) {}
 
 static inline void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val) {}
 static inline u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg) { return 0; }
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index cd64894b286e..ec449bc5f811 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -949,6 +949,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		 */
 		kvm_pmu_sync_hwstate(vcpu);
 
+		if (kvm_supports_spe() && kvm_vcpu_has_spe(vcpu))
+			kvm_spe_sync_hwstate(vcpu);
+
 		/*
 		 * Sync the vgic state before syncing the timer state because
 		 * the timer code needs to know if the virtual timer
diff --git a/arch/arm64/kvm/hyp/nvhe/spe-sr.c b/arch/arm64/kvm/hyp/nvhe/spe-sr.c
index 4f6579daddb5..b74131486a75 100644
--- a/arch/arm64/kvm/hyp/nvhe/spe-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/spe-sr.c
@@ -47,6 +47,8 @@ void __spe_save_host_state_nvhe(struct kvm_vcpu *vcpu,
 void __spe_save_guest_state_nvhe(struct kvm_vcpu *vcpu,
 				 struct kvm_cpu_context *guest_ctxt)
 {
+	u64 pmbsr;
+
 	if (read_sysreg_s(SYS_PMBLIMITR_EL1) & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)) {
 		psb_csync();
 		dsb(nsh);
@@ -55,7 +57,22 @@ void __spe_save_guest_state_nvhe(struct kvm_vcpu *vcpu,
 	}
 
 	ctxt_sys_reg(guest_ctxt, PMBPTR_EL1) = read_sysreg_s(SYS_PMBPTR_EL1);
-	ctxt_sys_reg(guest_ctxt, PMBSR_EL1) = read_sysreg_s(SYS_PMBSR_EL1);
+	/*
+	 * We need to differentiate between the hardware asserting the interrupt
+	 * and the guest setting the service bit as a result of a direct
+	 * register write, hence the extra field in the spe struct.
+	 *
+	 * The PMBSR_EL1 register is not directly accessed by the guest, KVM
+	 * needs to update the in-memory copy when the hardware asserts the
+	 * interrupt as that's the only case when KVM will show the guest a
+	 * value which is different from what the guest last wrote to the
+	 * register.
+	 */
+	pmbsr = read_sysreg_s(SYS_PMBSR_EL1);
+	if (pmbsr & BIT(SYS_PMBSR_EL1_S_SHIFT)) {
+		ctxt_sys_reg(guest_ctxt, PMBSR_EL1) = pmbsr;
+		vcpu->arch.spe.hwirq_level = true;
+	}
 	/* PMBLIMITR_EL1 is updated only on a trapped write. */
 	ctxt_sys_reg(guest_ctxt, PMSCR_EL1) = read_sysreg_s(SYS_PMSCR_EL1);
 
@@ -80,8 +97,13 @@ void __spe_restore_guest_state_nvhe(struct kvm_vcpu *vcpu,
 	__spe_restore_common_state(guest_ctxt);
 
 	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
-	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBSR_EL1), SYS_PMBSR_EL1);
-	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
+	/* The buffer management interrupt is virtual. */
+	write_sysreg_s(0, SYS_PMBSR_EL1);
+	/* The buffer is disabled when the interrupt is asserted. */
+	if (vcpu->arch.spe.irq_level)
+		write_sysreg_s(0, SYS_PMBLIMITR_EL1);
+	else
+		write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
 	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMSCR_EL1), SYS_PMSCR_EL1);
 	write_sysreg_el2(ctxt_sys_reg(guest_ctxt, PMSCR_EL2), SYS_PMSCR);
 }
diff --git a/arch/arm64/kvm/hyp/vhe/spe-sr.c b/arch/arm64/kvm/hyp/vhe/spe-sr.c
index f557ac64a1cc..ea4b3b69bb32 100644
--- a/arch/arm64/kvm/hyp/vhe/spe-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/spe-sr.c
@@ -48,7 +48,7 @@ NOKPROBE_SYMBOL(__spe_save_host_state_vhe);
 void __spe_save_guest_state_vhe(struct kvm_vcpu *vcpu,
 				struct kvm_cpu_context *guest_ctxt)
 {
-	u64 pmblimitr;
+	u64 pmblimitr, pmbsr;
 
 	/*
 	 * We're at EL2 and the buffer owning regime is EL1, which means that
@@ -66,7 +66,11 @@ void __spe_save_guest_state_vhe(struct kvm_vcpu *vcpu,
 	}
 
 	ctxt_sys_reg(guest_ctxt, PMBPTR_EL1) = read_sysreg_s(SYS_PMBPTR_EL1);
-	ctxt_sys_reg(guest_ctxt, PMBSR_EL1) = read_sysreg_s(SYS_PMBSR_EL1);
+	pmbsr = read_sysreg_s(SYS_PMBSR_EL1);
+	if (pmbsr & BIT(SYS_PMBSR_EL1_S_SHIFT)) {
+		ctxt_sys_reg(guest_ctxt, PMBSR_EL1) = pmbsr;
+		vcpu->arch.spe.hwirq_level = true;
+	}
 	/* PMBLIMITR_EL1 is updated only on a trapped write. */
 	ctxt_sys_reg(guest_ctxt, PMSCR_EL1) = read_sysreg_el1(SYS_PMSCR);
 
@@ -120,8 +124,13 @@ void __spe_restore_guest_state_vhe(struct kvm_vcpu *vcpu,
 	 */
 
 	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
-	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBSR_EL1), SYS_PMBSR_EL1);
-	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
+	/* The buffer management interrupt is virtual. */
+	write_sysreg_s(0, SYS_PMBSR_EL1);
+	/* The buffer is disabled when the interrupt is asserted. */
+	if (vcpu->arch.spe.irq_level)
+		write_sysreg_s(0, SYS_PMBLIMITR_EL1);
+	else
+		write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
 	write_sysreg_el1(ctxt_sys_reg(guest_ctxt, PMSCR_EL1), SYS_PMSCR);
 	/* PMSCR_EL2 has been cleared when saving the host state. */
 }
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 054bb16bbd79..5b69501dc3da 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -71,9 +71,81 @@ int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
+static void kvm_spe_update_irq(struct kvm_vcpu *vcpu, bool level)
+{
+	struct kvm_vcpu_spe *spe = &vcpu->arch.spe;
+	int ret;
+
+	if (spe->irq_level == level)
+		return;
+
+	spe->irq_level = level;
+	ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, spe->irq_num,
+				  level, spe);
+	WARN_ON(ret);
+}
+
+static __printf(2, 3)
+void print_buf_warn(struct kvm_vcpu *vcpu, char *fmt, ...)
+{
+	va_list va;
+
+	va_start(va, fmt);
+	kvm_warn_ratelimited("%pV [PMBSR=0x%016llx, PMBPTR=0x%016llx, PMBLIMITR=0x%016llx]\n",
+			    &(struct va_format){ fmt, &va },
+			    __vcpu_sys_reg(vcpu, PMBSR_EL1),
+			    __vcpu_sys_reg(vcpu, PMBPTR_EL1),
+			    __vcpu_sys_reg(vcpu, PMBLIMITR_EL1));
+	va_end(va);
+}
+
+static void kvm_spe_inject_ext_abt(struct kvm_vcpu *vcpu)
+{
+	__vcpu_sys_reg(vcpu, PMBSR_EL1) = BIT(SYS_PMBSR_EL1_EA_SHIFT) |
+					  BIT(SYS_PMBSR_EL1_S_SHIFT);
+	__vcpu_sys_reg(vcpu, PMBSR_EL1) |= SYS_PMBSR_EL1_EC_FAULT_S1;
+	/* Synchronous External Abort, not on translation table walk. */
+	__vcpu_sys_reg(vcpu, PMBSR_EL1) |= 0x10 << SYS_PMBSR_EL1_FAULT_FSC_SHIFT;
+}
+
+void kvm_spe_sync_hwstate(struct kvm_vcpu *vcpu)
+{
+	struct kvm_vcpu_spe *spe = &vcpu->arch.spe;
+	u64 pmbsr, pmbsr_ec;
+
+	if (!spe->hwirq_level)
+		return;
+	spe->hwirq_level = false;
+
+	pmbsr = __vcpu_sys_reg(vcpu, PMBSR_EL1);
+	pmbsr_ec = pmbsr & (SYS_PMBSR_EL1_EC_MASK << SYS_PMBSR_EL1_EC_SHIFT);
+
+	switch (pmbsr_ec) {
+	case SYS_PMBSR_EL1_EC_FAULT_S2:
+		print_buf_warn(vcpu, "SPE stage 2 data abort");
+		kvm_spe_inject_ext_abt(vcpu);
+		break;
+	case SYS_PMBSR_EL1_EC_FAULT_S1:
+	case SYS_PMBSR_EL1_EC_BUF:
+		/*
+		 * These two exception syndromes are entirely up to the guest to
+		 * figure out, leave PMBSR_EL1 unchanged.
+		 */
+		break;
+	default:
+		print_buf_warn(vcpu, "SPE unknown buffer syndrome");
+		kvm_spe_inject_ext_abt(vcpu);
+	}
+
+	kvm_spe_update_irq(vcpu, true);
+}
+
 void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val)
 {
 	__vcpu_sys_reg(vcpu, reg) = val;
+
+	if (reg == PMBSR_EL1)
+		kvm_spe_update_irq(vcpu, val & BIT(SYS_PMBSR_EL1_S_SHIFT));
 }
 
 u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg)
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:11 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:11 +0100
Subject: [RFC PATCH v4 35/39] KVM: arm64: Add an userspace API to stop a VCPU
 profiling
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-36-alexandru.elisei@arm.com>

Add the KVM_ARM_VCPU_SPE_CTRL(KVM_ARM_VCPU_SPE_STOP) VCPU attribute to
allow userspace to request that KVM disables profiling for that VCPU. The
ioctl does nothing yet.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/devices/vcpu.rst | 36 +++++++++++++++++++++++++
 arch/arm64/include/uapi/asm/kvm.h       |  4 +++
 arch/arm64/kvm/spe.c                    | 23 +++++++++++++---
 3 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index c275c320e500..b4e38261b00f 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -201,3 +201,39 @@ Returns:
 Request initialization of the Statistical Profiling Extension for this VCPU.
 Must be done after initializaing the in-kernel irqchip and after setting the
 Profiling Buffer management interrupt number for the VCPU.
+
+4.3 ATTRIBUTE: KVM_ARM_VCPU_SPE_STOP
+------------------------------------
+
+:Parameters: in kvm_device_attr.addr the address to the flag that specifies
+             what KVM should do when the guest enables profiling
+
+The flag must be exactly one of:
+
+- KVM_ARM_VCPU_SPE_STOP_TRAP: trap all register accesses and ignore the guest
+  trying to enable profiling.
+- KVM_ARM_VCPU_SPE_STOP_EXIT: exit to userspace when the guest tries to enable
+  profiling.
+- KVM_ARM_VCPU_SPE_RESUME: resume profiling, if it was previously stopped using
+  this attribute.
+
+If KVM detects that a vcpu is trying to run with SPE enabled when
+KVM_ARM_VCPU_STOP_EXIT is set, KVM_RUN will return without entering the guest
+with kvm_run.exit_reason equal to KVM_EXIT_FAIL_ENTRY, and the fail_entry struct
+will be zeroed.
+
+Returns:
+
+	 =======  ============================================
+	 -EAGAIN  SPE not initialized
+	 -EFAULT  Error accessing the flag
+	 -EINVAL  Invalid flag
+	 -ENXIO   SPE not supported or not properly configured
+	 =======  ============================================
+
+Request that KVM disables SPE for the given vcpu. This can be useful for
+migration, which relies on tracking dirty pages by write-protecting memory, but
+breaks SPE in the guest as KVM does not handle buffer stage 2 faults.
+
+The attribute must be set after SPE has been initialized successfully. It can be
+set multiple times, with the latest value overwritting the previous one.
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index d4c0b53a5fb2..75a5113f610e 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -371,6 +371,10 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_ARM_VCPU_SPE_CTRL		3
 #define   KVM_ARM_VCPU_SPE_IRQ		0
 #define   KVM_ARM_VCPU_SPE_INIT		1
+#define   KVM_ARM_VCPU_SPE_STOP		2
+#define     KVM_ARM_VCPU_SPE_STOP_TRAP		(1 << 0)
+#define     KVM_ARM_VCPU_SPE_STOP_EXIT		(1 << 1)
+#define     KVM_ARM_VCPU_SPE_RESUME		(1 << 2)
 
 /* KVM_IRQ_LINE irq field index values */
 #define KVM_ARM_IRQ_VCPU2_SHIFT		28
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 5b69501dc3da..2630e777fe1d 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -220,14 +220,14 @@ int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	if (!kvm_vcpu_supports_spe(vcpu))
 		return -ENXIO;
 
-	if (vcpu->arch.spe.initialized)
-		return -EBUSY;
-
 	switch (attr->attr) {
 	case KVM_ARM_VCPU_SPE_IRQ: {
 		int __user *uaddr = (int __user *)(long)attr->addr;
 		int irq;
 
+		if (vcpu->arch.spe.initialized)
+			return -EBUSY;
+
 		if (vcpu->arch.spe.irq_num)
 			return -EBUSY;
 
@@ -248,11 +248,27 @@ int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 		if (!vgic_initialized(vcpu->kvm))
 			return -ENXIO;
 
+		if (vcpu->arch.spe.initialized)
+			return -EBUSY;
+
 		if (kvm_vgic_set_owner(vcpu, vcpu->arch.spe.irq_num, &vcpu->arch.spe))
 			return -ENXIO;
 
 		vcpu->arch.spe.initialized = true;
 		return 0;
+	case KVM_ARM_VCPU_SPE_STOP: {
+		int __user *uaddr = (int __user *)(long)attr->addr;
+		int flags;
+
+		if (!vcpu->arch.spe.initialized)
+			return -EAGAIN;
+
+		if (get_user(flags, uaddr))
+			return -EFAULT;
+
+		if (!flags)
+			return -EINVAL;
+	}
 	}
 
 	return -ENXIO;
@@ -290,6 +306,7 @@ int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	switch(attr->attr) {
 	case KVM_ARM_VCPU_SPE_IRQ:
 	case KVM_ARM_VCPU_SPE_INIT:
+	case KVM_ARM_VCPU_SPE_STOP:
 		return 0;
 	}
 
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:07 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:07 +0100
Subject: [RFC PATCH v4 31/39] KVM: arm64: VHE: Context switch SPE state if
 VCPU has SPE
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-32-alexandru.elisei@arm.com>

Similar to the non-VHE case, save and restore the SPE register state at
each world switch for VHE enabled systems if the VCPU has the SPE
feature.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_hyp.h |  24 +++++-
 arch/arm64/include/asm/sysreg.h  |   2 +
 arch/arm64/kvm/hyp/vhe/Makefile  |   1 +
 arch/arm64/kvm/hyp/vhe/spe-sr.c  | 128 +++++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/vhe/switch.c  |   8 ++
 5 files changed, 161 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/kvm/hyp/vhe/spe-sr.c

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 06e77a739458..03bc51049996 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -106,8 +106,28 @@ static inline void __spe_restore_host_state_nvhe(struct kvm_vcpu *vcpu,
 					struct kvm_cpu_context *host_ctxt) {}
 static inline void __spe_restore_guest_state_nvhe(struct kvm_vcpu *vcpu,
 					struct kvm_cpu_context *guest_ctxt) {}
-#endif
-#endif
+#endif /* CONFIG_KVM_ARM_SPE */
+#else
+#ifdef CONFIG_KVM_ARM_SPE
+void __spe_save_host_state_vhe(struct kvm_vcpu *vcpu,
+			       struct kvm_cpu_context *host_ctxt);
+void __spe_save_guest_state_vhe(struct kvm_vcpu *vcpu,
+				struct kvm_cpu_context *guest_ctxt);
+void __spe_restore_host_state_vhe(struct kvm_vcpu *vcpu,
+				  struct kvm_cpu_context *host_ctxt);
+void __spe_restore_guest_state_vhe(struct kvm_vcpu *vcpu,
+				   struct kvm_cpu_context *guest_ctxt);
+#else
+static inline void __spe_save_host_state_vhe(struct kvm_vcpu *vcpu,
+					struct kvm_cpu_context *host_ctxt) {}
+static inline void __spe_save_guest_state_vhe(struct kvm_vcpu *vcpu,
+					struct kvm_cpu_context *guest_ctxt) {}
+static inline void __spe_restore_host_state_vhe(struct kvm_vcpu *vcpu,
+					struct kvm_cpu_context *host_ctxt) {}
+static inline void __spe_restore_guest_state_vhe(struct kvm_vcpu *vcpu,
+					struct kvm_cpu_context *guest_ctxt) {}
+#endif /* CONFIG_KVM_ARM_SPE */
+#endif /* __KVM_NVHE_HYPERVISOR__ */
 
 void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
 void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7b9c3acba684..b2d691bc1049 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -267,6 +267,8 @@
 #define SYS_PMSCR_EL1_TS_SHIFT		5
 #define SYS_PMSCR_EL1_PCT_SHIFT		6
 
+#define SYS_PMSCR_EL12			sys_reg(3, 5, 9, 9, 0)
+
 #define SYS_PMSCR_EL2			sys_reg(3, 4, 9, 9, 0)
 #define SYS_PMSCR_EL2_E0HSPE_SHIFT	0
 #define SYS_PMSCR_EL2_E2SPE_SHIFT	1
diff --git a/arch/arm64/kvm/hyp/vhe/Makefile b/arch/arm64/kvm/hyp/vhe/Makefile
index 96bec0ecf9dd..7cb4a9e5ceb0 100644
--- a/arch/arm64/kvm/hyp/vhe/Makefile
+++ b/arch/arm64/kvm/hyp/vhe/Makefile
@@ -7,5 +7,6 @@ asflags-y := -D__KVM_VHE_HYPERVISOR__
 ccflags-y := -D__KVM_VHE_HYPERVISOR__
 
 obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o
+obj-$(CONFIG_KVM_ARM_SPE) += spe-sr.o
 obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o
diff --git a/arch/arm64/kvm/hyp/vhe/spe-sr.c b/arch/arm64/kvm/hyp/vhe/spe-sr.c
new file mode 100644
index 000000000000..00eab9e2ec60
--- /dev/null
+++ b/arch/arm64/kvm/hyp/vhe/spe-sr.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 - ARM Ltd
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_hyp.h>
+#include <asm/kprobes.h>
+
+#include <hyp/spe-sr.h>
+
+/*
+ * Disable host profiling, drain the buffer and save the host SPE context.
+ * Extra care must be taken because profiling might be in progress.
+ */
+void __spe_save_host_state_vhe(struct kvm_vcpu *vcpu,
+			       struct kvm_cpu_context *host_ctxt)
+{
+	u64 pmblimitr, pmscr_el2;
+
+	/* Disable profiling while the SPE context is being switched. */
+	pmscr_el2 = read_sysreg_el2(SYS_PMSCR);
+	write_sysreg_el2(0, SYS_PMSCR);
+	isb();
+
+	pmblimitr = read_sysreg_s(SYS_PMBLIMITR_EL1);
+	if (pmblimitr & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)) {
+		psb_csync();
+		dsb(nsh);
+		/* Ensure hardware updates to PMBPTR_EL1 are visible. */
+		isb();
+	}
+
+	ctxt_sys_reg(host_ctxt, PMBPTR_EL1) = read_sysreg_s(SYS_PMBPTR_EL1);
+	ctxt_sys_reg(host_ctxt, PMBSR_EL1) = read_sysreg_s(SYS_PMBSR_EL1);
+	ctxt_sys_reg(host_ctxt, PMBLIMITR_EL1) = pmblimitr;
+	ctxt_sys_reg(host_ctxt, PMSCR_EL2) = pmscr_el2;
+
+	__spe_save_common_state(host_ctxt);
+}
+NOKPROBE_SYMBOL(__spe_save_host_state_vhe);
+
+/*
+ * Drain the guest's buffer and save the SPE state. Profiling is disabled
+ * because we're at EL2 and the buffer owning exceptions level is EL1.
+ */
+void __spe_save_guest_state_vhe(struct kvm_vcpu *vcpu,
+				struct kvm_cpu_context *guest_ctxt)
+{
+	u64 pmblimitr;
+
+	/*
+	 * We're at EL2 and the buffer owning regime is EL1, which means that
+	 * profiling is disabled. After we disable traps and restore the host's
+	 * MDCR_EL2, profiling will remain disabled because we've disabled it
+	 * via PMSCR_EL2 when we saved the host's SPE state. All it's needed
+	 * here is to drain the buffer.
+	 */
+	pmblimitr = read_sysreg_s(SYS_PMBLIMITR_EL1);
+	if (pmblimitr & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)) {
+		psb_csync();
+		dsb(nsh);
+		/* Ensure hardware updates to PMBPTR_EL1 are visible. */
+		isb();
+	}
+
+	ctxt_sys_reg(guest_ctxt, PMBPTR_EL1) = read_sysreg_s(SYS_PMBPTR_EL1);
+	ctxt_sys_reg(guest_ctxt, PMBSR_EL1) = read_sysreg_s(SYS_PMBSR_EL1);
+	/* PMBLIMITR_EL1 is updated only on a trapped write. */
+	ctxt_sys_reg(guest_ctxt, PMSCR_EL1) = read_sysreg_el1(SYS_PMSCR);
+
+	__spe_save_common_state(guest_ctxt);
+}
+NOKPROBE_SYMBOL(__spe_save_guest_state_vhe);
+
+/*
+ * Restore the host SPE context. Special care must be taken because we're
+ * potentially resuming a profiling session which was stopped when we saved the
+ * host SPE register state.
+ */
+void __spe_restore_host_state_vhe(struct kvm_vcpu *vcpu,
+				  struct kvm_cpu_context *host_ctxt)
+{
+	__spe_restore_common_state(host_ctxt);
+
+	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
+	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
+	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMBSR_EL1), SYS_PMBSR_EL1);
+
+	/*
+	 * Make sure buffer pointer and limit is updated first, so we don't end
+	 * up in a situation where profiling is enabled and the buffer uses the
+	 * values programmed by the guest.
+	 *
+	 * This also serves to make sure the write to MDCR_EL2 which changes the
+	 * buffer owning Exception level is visible.
+	 *
+	 * After the synchronization, profiling is still disabled at EL2,
+	 * because we cleared PMSCR_EL2 when we saved the host context.
+	 */
+	isb();
+
+	write_sysreg_el2(ctxt_sys_reg(host_ctxt, PMSCR_EL2), SYS_PMSCR);
+}
+NOKPROBE_SYMBOL(__spe_restore_host_state_vhe);
+
+/*
+ * Restore the guest SPE context while profiling is disabled at EL2.
+ */
+void __spe_restore_guest_state_vhe(struct kvm_vcpu *vcpu,
+				   struct kvm_cpu_context *guest_ctxt)
+{
+	__spe_restore_common_state(guest_ctxt);
+
+	/*
+	 * No synchronization needed here. Profiling is disabled at EL2 because
+	 * PMSCR_EL2 has been cleared when saving the host's context, and the
+	 * buffer has already been drained.
+	 */
+
+	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
+	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBSR_EL1), SYS_PMBSR_EL1);
+	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
+	write_sysreg_el1(ctxt_sys_reg(guest_ctxt, PMSCR_EL1), SYS_PMSCR);
+	/* PMSCR_EL2 has been cleared when saving the host state. */
+}
+NOKPROBE_SYMBOL(__spe_restore_guest_state_vhe);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index ec4e179d56ae..46da018f4a5a 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -135,6 +135,8 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
 	guest_ctxt = &vcpu->arch.ctxt;
 
 	sysreg_save_host_state_vhe(host_ctxt);
+	if (kvm_vcpu_has_spe(vcpu))
+		__spe_save_host_state_vhe(vcpu, host_ctxt);
 
 	/*
 	 * ARM erratum 1165522 requires us to configure both stage 1 and
@@ -153,6 +155,8 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
 	__kvm_adjust_pc(vcpu);
 
 	sysreg_restore_guest_state_vhe(guest_ctxt);
+	if (kvm_vcpu_has_spe(vcpu))
+		__spe_restore_guest_state_vhe(vcpu, guest_ctxt);
 	__debug_switch_to_guest(vcpu);
 
 	do {
@@ -163,10 +167,14 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
 	} while (fixup_guest_exit(vcpu, &exit_code));
 
 	sysreg_save_guest_state_vhe(guest_ctxt);
+	if (kvm_vcpu_has_spe(vcpu))
+		__spe_save_guest_state_vhe(vcpu, guest_ctxt);
 
 	__deactivate_traps(vcpu);
 
 	sysreg_restore_host_state_vhe(host_ctxt);
+	if (kvm_vcpu_has_spe(vcpu))
+		__spe_restore_host_state_vhe(vcpu, host_ctxt);
 
 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED)
 		__fpsimd_save_fpexc32(vcpu);
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:08 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:08 +0100
Subject: [RFC PATCH v4 32/39] KVM: arm64: Save/restore PMSNEVFR_EL1 on VCPU
 put/load
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-33-alexandru.elisei@arm.com>

FEAT_SPEv1p2 introduced a new register, PMSNEVFR_EL1. The SPE driver is not
using the register, so save the register to the guest context on vcpu_put()
and restore it on vcpu_load() since it will not be touched by the host, and
the value programmed by the guest doesn't affect the host.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/include/asm/kvm_spe.h  |  6 ++++++
 arch/arm64/include/asm/sysreg.h   |  1 +
 arch/arm64/kvm/arm.c              |  2 ++
 arch/arm64/kvm/spe.c              | 29 +++++++++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c         |  1 +
 6 files changed, 40 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e704847a7645..66f0b999cb5f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -239,6 +239,7 @@ enum vcpu_sysreg {
 
        /* Statistical Profiling Extension Registers. */
 	PMSCR_EL1,      /* Statistical Profiling Control Register */
+	PMSNEVFR_EL1,   /* Sampling Inverted Event Filter Register */
 	PMSICR_EL1,     /* Sampling Interval Counter Register */
 	PMSIRR_EL1,     /* Sampling Interval Reload Register */
 	PMSFCR_EL1,     /* Sampling Filter Control Register */
diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index 934eedb0de46..6b8d4cf2cd37 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -28,6 +28,9 @@ int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu);
 void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val);
 u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg);
 
+void kvm_spe_vcpu_load(struct kvm_vcpu *vcpu);
+void kvm_spe_vcpu_put(struct kvm_vcpu *vcpu);
+
 int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 int kvm_spe_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
@@ -45,6 +48,9 @@ static inline int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu) { return -E
 static inline void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val) {}
 static inline u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg) { return 0; }
 
+static inline void kvm_spe_vcpu_load(struct kvm_vcpu *vcpu) {}
+static inline void kvm_spe_vcpu_put(struct kvm_vcpu *vcpu) {}
+
 static inline int kvm_spe_set_attr(struct kvm_vcpu *vcpu,
 				   struct kvm_device_attr *attr)
 {
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index b2d691bc1049..cedab4494a71 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -921,6 +921,7 @@
 
 #define ID_AA64DFR0_PMSVER_8_2		0x1
 #define ID_AA64DFR0_PMSVER_8_3		0x2
+#define ID_AA64DFR0_PMSVER_8_7		0x3
 
 #define ID_DFR0_PERFMON_SHIFT		24
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 6af7ef26d2c1..cd64894b286e 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -466,6 +466,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	if (vcpu_has_ptrauth(vcpu))
 		vcpu_ptrauth_disable(vcpu);
 	kvm_arch_vcpu_load_debug_state_flags(vcpu);
+	kvm_spe_vcpu_load(vcpu);
 
 	if (!cpumask_empty(&vcpu->arch.supported_cpus) &&
 	    !cpumask_test_cpu(smp_processor_id(), &vcpu->arch.supported_cpus))
@@ -474,6 +475,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+	kvm_spe_vcpu_put(vcpu);
 	kvm_arch_vcpu_put_debug_state_flags(vcpu);
 	kvm_arch_vcpu_put_fp(vcpu);
 	if (has_vhe())
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index f760ccd8306a..711736c49f63 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -67,6 +67,35 @@ u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg)
 	return __vcpu_sys_reg(vcpu, reg);
 }
 
+static unsigned int kvm_spe_get_pmsver(void)
+{
+	u64 dfr0 = read_sysreg(id_aa64dfr0_el1);
+
+	return cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_PMSVER_SHIFT);
+}
+
+void kvm_spe_vcpu_load(struct kvm_vcpu *vcpu)
+{
+	if (!kvm_vcpu_has_spe(vcpu))
+		return;
+
+	if (kvm_spe_get_pmsver() < ID_AA64DFR0_PMSVER_8_7)
+		return;
+
+	write_sysreg_s(__vcpu_sys_reg(vcpu, PMSNEVFR_EL1), SYS_PMSNEVFR_EL1);
+}
+
+void kvm_spe_vcpu_put(struct kvm_vcpu *vcpu)
+{
+	if (!kvm_vcpu_has_spe(vcpu))
+		return;
+
+	if (kvm_spe_get_pmsver() < ID_AA64DFR0_PMSVER_8_7)
+		return;
+
+	__vcpu_sys_reg(vcpu, PMSNEVFR_EL1) = read_sysreg_s(SYS_PMSNEVFR_EL1);
+}
+
 static bool kvm_vcpu_supports_spe(struct kvm_vcpu *vcpu)
 {
 	if (!kvm_supports_spe())
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 843822be5695..064742cee425 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1562,6 +1562,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
 
 	{ SPE_SYS_REG(SYS_PMSCR_EL1), .reg = PMSCR_EL1 },
+	{ SPE_SYS_REG(SYS_PMSNEVFR_EL1), .reg = PMSNEVFR_EL1 },
 	{ SPE_SYS_REG(SYS_PMSICR_EL1), .reg = PMSICR_EL1 },
 	{ SPE_SYS_REG(SYS_PMSIRR_EL1), .reg = PMSIRR_EL1 },
 	{ SPE_SYS_REG(SYS_PMSFCR_EL1), .reg = PMSFCR_EL1 },
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:09 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:09 +0100
Subject: [RFC PATCH v4 33/39] KVM: arm64: Allow guest to use physical
 timestamps if perfmon_capable()
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-34-alexandru.elisei@arm.com>

The SPE driver allows userspace to use physical timestamps for records only
if the process if perfmon_capable(). Do the same for a virtual machine with
the SPE feature.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  2 ++
 arch/arm64/include/asm/kvm_spe.h  |  7 +++++++
 arch/arm64/kvm/hyp/nvhe/spe-sr.c  |  2 +-
 arch/arm64/kvm/hyp/vhe/spe-sr.c   |  2 +-
 arch/arm64/kvm/spe.c              | 14 ++++++++++++++
 5 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 66f0b999cb5f..cc46f1406196 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -157,6 +157,8 @@ struct kvm_arch {
 
 	/* Memory Tagging Extension enabled for the guest */
 	bool mte_enabled;
+
+	struct kvm_spe spe;
 };
 
 struct kvm_vcpu_fault_info {
diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index 6b8d4cf2cd37..272f1eec64f2 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -21,6 +21,10 @@ struct kvm_vcpu_spe {
 	int irq_num;		/* Buffer management interrut number */
 };
 
+struct kvm_spe {
+	bool perfmon_capable;	/* Is the VM perfmon_capable()? */
+};
+
 void kvm_spe_init_supported_cpus(void);
 void kvm_spe_vm_init(struct kvm *kvm);
 int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu);
@@ -41,6 +45,9 @@ int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 struct kvm_vcpu_spe {
 };
 
+struct kvm_spe {
+};
+
 static inline void kvm_spe_init_supported_cpus(void) {}
 static inline void kvm_spe_vm_init(struct kvm *kvm) {}
 static inline int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
diff --git a/arch/arm64/kvm/hyp/nvhe/spe-sr.c b/arch/arm64/kvm/hyp/nvhe/spe-sr.c
index 46e47c9fd08f..4f6579daddb5 100644
--- a/arch/arm64/kvm/hyp/nvhe/spe-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/spe-sr.c
@@ -83,5 +83,5 @@ void __spe_restore_guest_state_nvhe(struct kvm_vcpu *vcpu,
 	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBSR_EL1), SYS_PMBSR_EL1);
 	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBLIMITR_EL1), SYS_PMBLIMITR_EL1);
 	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMSCR_EL1), SYS_PMSCR_EL1);
-	write_sysreg_el2(0, SYS_PMSCR);
+	write_sysreg_el2(ctxt_sys_reg(guest_ctxt, PMSCR_EL2), SYS_PMSCR);
 }
diff --git a/arch/arm64/kvm/hyp/vhe/spe-sr.c b/arch/arm64/kvm/hyp/vhe/spe-sr.c
index 00eab9e2ec60..f557ac64a1cc 100644
--- a/arch/arm64/kvm/hyp/vhe/spe-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/spe-sr.c
@@ -21,7 +21,7 @@ void __spe_save_host_state_vhe(struct kvm_vcpu *vcpu,
 
 	/* Disable profiling while the SPE context is being switched. */
 	pmscr_el2 = read_sysreg_el2(SYS_PMSCR);
-	write_sysreg_el2(0, SYS_PMSCR);
+	write_sysreg_el2(__vcpu_sys_reg(vcpu, PMSCR_EL2), SYS_PMSCR);
 	isb();
 
 	pmblimitr = read_sysreg_s(SYS_PMBLIMITR_EL1);
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 711736c49f63..054bb16bbd79 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -3,6 +3,7 @@
  * Copyright (C) 2021 - ARM Ltd
  */
 
+#include <linux/capability.h>
 #include <linux/cpumask.h>
 #include <linux/kvm_host.h>
 #include <linux/perf/arm_pmu.h>
@@ -29,6 +30,16 @@ void kvm_spe_vm_init(struct kvm *kvm)
 {
 	/* Set supported_cpus if it isn't already initialized. */
 	kvm_spe_init_supported_cpus();
+
+	/*
+	 * Allow the guest to use the physical timer for timestamps only if the
+	 * VMM is perfmon_capable(), similar to what the SPE driver allows.
+	 *
+	 * CAP_PERFMON can be changed during the lifetime of the VM, so record
+	 * its value when the VM is created to avoid situations where only some
+	 * VCPUs allow physical timer timestamps, while others don't.
+	 */
+	kvm->arch.spe.perfmon_capable = perfmon_capable();
 }
 
 static int kvm_spe_check_supported_cpus(struct kvm_vcpu *vcpu)
@@ -54,6 +65,9 @@ int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 	if (!vcpu->arch.spe.initialized)
 		return -EPERM;
 
+	if (vcpu->kvm->arch.spe.perfmon_capable)
+		__vcpu_sys_reg(vcpu, PMSCR_EL2) = BIT(SYS_PMSCR_EL1_PCT_SHIFT);
+
 	return 0;
 }
 
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:12 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:12 +0100
Subject: [RFC PATCH v4 36/39] KVM: arm64: Implement userspace API to stop a
 VCPU profiling
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-37-alexandru.elisei@arm.com>

When userspace requests that a VCPU is not allowed to profile anymore via the
KVM_ARM_VCPU_SPE_STOP attribute, keep all the register state in memory and
trap all registers, not just the buffer registers, and don't copy any of
this shadow state on the hardware.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_hyp.h   |  2 +
 arch/arm64/include/asm/kvm_spe.h   | 14 +++++++
 arch/arm64/include/uapi/asm/kvm.h  |  3 ++
 arch/arm64/kvm/arm.c               |  9 ++++
 arch/arm64/kvm/debug.c             | 13 ++++--
 arch/arm64/kvm/hyp/nvhe/debug-sr.c |  4 +-
 arch/arm64/kvm/hyp/nvhe/spe-sr.c   | 24 +++++++++++
 arch/arm64/kvm/hyp/vhe/spe-sr.c    | 56 +++++++++++++++++++++++++
 arch/arm64/kvm/spe.c               | 67 ++++++++++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c          |  2 +-
 10 files changed, 188 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 03bc51049996..ce365427b483 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -86,8 +86,10 @@ void __debug_switch_to_host(struct kvm_vcpu *vcpu);
 #ifdef __KVM_NVHE_HYPERVISOR__
 void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu,
 				    struct kvm_cpu_context *host_ctxt);
+void __debug_save_spe(u64 *pmscr_el1);
 void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu,
 				       struct kvm_cpu_context *host_ctxt);
+void __debug_restore_spe(u64 pmscr_el1);
 #ifdef CONFIG_KVM_ARM_SPE
 void __spe_save_host_state_nvhe(struct kvm_vcpu *vcpu,
 				struct kvm_cpu_context *host_ctxt);
diff --git a/arch/arm64/include/asm/kvm_spe.h b/arch/arm64/include/asm/kvm_spe.h
index d7d7b9e243de..f51561e3b43f 100644
--- a/arch/arm64/include/asm/kvm_spe.h
+++ b/arch/arm64/include/asm/kvm_spe.h
@@ -16,13 +16,23 @@ static __always_inline bool kvm_supports_spe(void)
 	return static_branch_likely(&kvm_spe_available);
 }
 
+/* Guest profiling disabled by the user. */
+#define KVM_VCPU_SPE_STOP_USER		(1 << 0)
+/* Stop profiling and exit to userspace when guest starts profiling. */
+#define KVM_VCPU_SPE_STOP_USER_EXIT	(1 << 1)
+
 struct kvm_vcpu_spe {
 	bool initialized;	/* SPE initialized for the VCPU */
 	int irq_num;		/* Buffer management interrut number */
 	bool irq_level;		/* 'true' if the interrupt is asserted at the VGIC */
 	bool hwirq_level;	/* 'true' if the SPE hardware is asserting the interrupt */
+	u64 flags;
 };
 
+#define kvm_spe_profiling_stopped(vcpu)					\
+	(((vcpu)->arch.spe.flags & KVM_VCPU_SPE_STOP_USER) ||		\
+	 ((vcpu)->arch.spe.flags & KVM_VCPU_SPE_STOP_USER_EXIT))	\
+
 struct kvm_spe {
 	bool perfmon_capable;	/* Is the VM perfmon_capable()? */
 };
@@ -31,6 +41,7 @@ void kvm_spe_init_supported_cpus(void);
 void kvm_spe_vm_init(struct kvm *kvm);
 int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu);
 void kvm_spe_sync_hwstate(struct kvm_vcpu *vcpu);
+bool kvm_spe_exit_to_user(struct kvm_vcpu *vcpu);
 
 void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val);
 u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg);
@@ -48,6 +59,8 @@ int kvm_spe_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
 struct kvm_vcpu_spe {
 };
 
+#define kvm_spe_profiling_stopped(vcpu)		(false)
+
 struct kvm_spe {
 };
 
@@ -55,6 +68,7 @@ static inline void kvm_spe_init_supported_cpus(void) {}
 static inline void kvm_spe_vm_init(struct kvm *kvm) {}
 static inline int kvm_spe_vcpu_first_run_init(struct kvm_vcpu *vcpu) { return -ENOEXEC; }
 static inline void kvm_spe_sync_hwstate(struct kvm_vcpu *vcpu) {}
+static inline bool kvm_spe_exit_to_user(struct kvm_vcpu *vcpu) { return false; }
 
 static inline void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val) {}
 static inline u64 kvm_spe_read_sysreg(struct kvm_vcpu *vcpu, int reg) { return 0; }
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 75a5113f610e..63599ee39a7b 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -376,6 +376,9 @@ struct kvm_arm_copy_mte_tags {
 #define     KVM_ARM_VCPU_SPE_STOP_EXIT		(1 << 1)
 #define     KVM_ARM_VCPU_SPE_RESUME		(1 << 2)
 
+/* run->fail_entry.hardware_entry_failure_reason codes. */
+#define KVM_EXIT_FAIL_ENTRY_SPE		(1 << 0)
+
 /* KVM_IRQ_LINE irq field index values */
 #define KVM_ARM_IRQ_VCPU2_SHIFT		28
 #define KVM_ARM_IRQ_VCPU2_MASK		0xf
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index ec449bc5f811..b7aae25bb9da 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -873,6 +873,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 			continue;
 		}
 
+		if (unlikely(kvm_spe_exit_to_user(vcpu))) {
+			run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+			run->fail_entry.hardware_entry_failure_reason
+				= KVM_EXIT_FAIL_ENTRY_SPE;
+			ret = -EAGAIN;
+			preempt_enable();
+			continue;
+		}
+
 		kvm_pmu_flush_hwstate(vcpu);
 
 		local_irq_disable();
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 6e5fc1887215..6a4277a23bbb 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -96,11 +96,18 @@ static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
 	if (kvm_supports_spe() && kvm_vcpu_has_spe(vcpu)) {
 		/*
 		 * Use EL1&0 for the profiling buffer translation regime and
-		 * trap accesses to the buffer control registers; leave
-		 * MDCR_EL2.TPMS unset and do not trap accesses to the profiling
-		 * control registers.
+		 * trap accesses to the buffer control registers; if profiling
+		 * is stopped, also set MSCR_EL2.TMPS to trap accesses to the
+		 * rest of the registers, otherwise leave it clear.
+		 *
+		 * Leaving MDCR_EL2.E2P unset, like we do when the VCPU does not
+		 * have SPE, means that the PMBIDR_EL1.P (which KVM does not
+		 * trap) will be set and the guest will detect SPE as being
+		 * unavailable.
 		 */
 		vcpu->arch.mdcr_el2 |= MDCR_EL2_E2PB_EL1_TRAP << MDCR_EL2_E2PB_SHIFT;
+		if (kvm_spe_profiling_stopped(vcpu))
+			vcpu->arch.mdcr_el2 |= MDCR_EL2_TPMS;
 	} else {
 		/*
 		 * Trap accesses to the profiling control registers; leave
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 1622615954b2..944972de0944 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -14,7 +14,7 @@
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
 
-static void __debug_save_spe(u64 *pmscr_el1)
+void __debug_save_spe(u64 *pmscr_el1)
 {
 	u64 reg;
 
@@ -40,7 +40,7 @@ static void __debug_save_spe(u64 *pmscr_el1)
 	dsb(nsh);
 }
 
-static void __debug_restore_spe(u64 pmscr_el1)
+void __debug_restore_spe(u64 pmscr_el1)
 {
 	if (!pmscr_el1)
 		return;
diff --git a/arch/arm64/kvm/hyp/nvhe/spe-sr.c b/arch/arm64/kvm/hyp/nvhe/spe-sr.c
index b74131486a75..8ed03aa4f965 100644
--- a/arch/arm64/kvm/hyp/nvhe/spe-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/spe-sr.c
@@ -23,6 +23,11 @@ void __spe_save_host_state_nvhe(struct kvm_vcpu *vcpu,
 {
 	u64 pmblimitr;
 
+	if (kvm_spe_profiling_stopped(vcpu)) {
+		__debug_save_spe(__ctxt_sys_reg(host_ctxt, PMSCR_EL1));
+		return;
+	}
+
 	pmblimitr = read_sysreg_s(SYS_PMBLIMITR_EL1);
 	if (pmblimitr & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)) {
 		psb_csync();
@@ -49,6 +54,13 @@ void __spe_save_guest_state_nvhe(struct kvm_vcpu *vcpu,
 {
 	u64 pmbsr;
 
+	/*
+	 * Profiling is stopped and all register accesses are trapped, nothing
+	 * to save here.
+	 */
+	if (kvm_spe_profiling_stopped(vcpu))
+		return;
+
 	if (read_sysreg_s(SYS_PMBLIMITR_EL1) & BIT(SYS_PMBLIMITR_EL1_E_SHIFT)) {
 		psb_csync();
 		dsb(nsh);
@@ -82,6 +94,11 @@ void __spe_save_guest_state_nvhe(struct kvm_vcpu *vcpu,
 void __spe_restore_host_state_nvhe(struct kvm_vcpu *vcpu,
 				   struct kvm_cpu_context *host_ctxt)
 {
+	if (kvm_spe_profiling_stopped(vcpu)) {
+		__debug_restore_spe(ctxt_sys_reg(host_ctxt, PMSCR_EL1));
+		return;
+	}
+
 	__spe_restore_common_state(host_ctxt);
 
 	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
@@ -94,6 +111,13 @@ void __spe_restore_host_state_nvhe(struct kvm_vcpu *vcpu,
 void __spe_restore_guest_state_nvhe(struct kvm_vcpu *vcpu,
 				    struct kvm_cpu_context *guest_ctxt)
 {
+	/*
+	 * Profiling is stopped and all register accesses are trapped, nothing
+	 * to restore here.
+	 */
+	if (kvm_spe_profiling_stopped(vcpu))
+		return;
+
 	__spe_restore_common_state(guest_ctxt);
 
 	write_sysreg_s(ctxt_sys_reg(guest_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
diff --git a/arch/arm64/kvm/hyp/vhe/spe-sr.c b/arch/arm64/kvm/hyp/vhe/spe-sr.c
index ea4b3b69bb32..024a4c0618cc 100644
--- a/arch/arm64/kvm/hyp/vhe/spe-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/spe-sr.c
@@ -10,6 +10,34 @@
 
 #include <hyp/spe-sr.h>
 
+static void __spe_save_host_buffer(u64 *pmscr_el2)
+{
+	u64 pmblimitr;
+
+	/* Disable guest profiling. */
+	write_sysreg_el1(0, SYS_PMSCR);
+
+	pmblimitr = read_sysreg_s(SYS_PMBLIMITR_EL1);
+	if (!(pmblimitr & BIT(SYS_PMBLIMITR_EL1_E_SHIFT))) {
+		*pmscr_el2 = 0;
+		return;
+	}
+
+	*pmscr_el2 = read_sysreg_el2(SYS_PMSCR);
+
+	/* Disable profiling at EL2 so we can drain the buffer. */
+	write_sysreg_el2(0, SYS_PMSCR);
+	isb();
+
+	/*
+	 * We're going to change the buffer owning exception level when we
+	 * activate traps, drain the buffer now.
+	 */
+	psb_csync();
+	dsb(nsh);
+}
+NOKPROBE_SYMBOL(__spe_save_host_buffer);
+
 /*
  * Disable host profiling, drain the buffer and save the host SPE context.
  * Extra care must be taken because profiling might be in progress.
@@ -19,6 +47,11 @@ void __spe_save_host_state_vhe(struct kvm_vcpu *vcpu,
 {
 	u64 pmblimitr, pmscr_el2;
 
+	if (kvm_spe_profiling_stopped(vcpu)) {
+		__spe_save_host_buffer(__ctxt_sys_reg(host_ctxt, PMSCR_EL2));
+		return;
+	}
+
 	/* Disable profiling while the SPE context is being switched. */
 	pmscr_el2 = read_sysreg_el2(SYS_PMSCR);
 	write_sysreg_el2(__vcpu_sys_reg(vcpu, PMSCR_EL2), SYS_PMSCR);
@@ -50,6 +83,9 @@ void __spe_save_guest_state_vhe(struct kvm_vcpu *vcpu,
 {
 	u64 pmblimitr, pmbsr;
 
+	if (kvm_spe_profiling_stopped(vcpu))
+		return;
+
 	/*
 	 * We're at EL2 and the buffer owning regime is EL1, which means that
 	 * profiling is disabled. After we disable traps and restore the host's
@@ -78,6 +114,18 @@ void __spe_save_guest_state_vhe(struct kvm_vcpu *vcpu,
 }
 NOKPROBE_SYMBOL(__spe_save_guest_state_vhe);
 
+static void __spe_restore_host_buffer(u64 pmscr_el2)
+{
+	if (!pmscr_el2)
+		return;
+
+	/* Synchronize MDCR_EL2 write. */
+	isb();
+
+	write_sysreg_el2(pmscr_el2, SYS_PMSCR);
+}
+NOKPROBE_SYMBOL(__spe_restore_host_buffer);
+
 /*
  * Restore the host SPE context. Special care must be taken because we're
  * potentially resuming a profiling session which was stopped when we saved the
@@ -86,6 +134,11 @@ NOKPROBE_SYMBOL(__spe_save_guest_state_vhe);
 void __spe_restore_host_state_vhe(struct kvm_vcpu *vcpu,
 				  struct kvm_cpu_context *host_ctxt)
 {
+	if (kvm_spe_profiling_stopped(vcpu)) {
+		__spe_restore_host_buffer(ctxt_sys_reg(host_ctxt, PMSCR_EL2));
+		return;
+	}
+
 	__spe_restore_common_state(host_ctxt);
 
 	write_sysreg_s(ctxt_sys_reg(host_ctxt, PMBPTR_EL1), SYS_PMBPTR_EL1);
@@ -115,6 +168,9 @@ NOKPROBE_SYMBOL(__spe_restore_host_state_vhe);
 void __spe_restore_guest_state_vhe(struct kvm_vcpu *vcpu,
 				   struct kvm_cpu_context *guest_ctxt)
 {
+	if (kvm_spe_profiling_stopped(vcpu))
+		return;
+
 	__spe_restore_common_state(guest_ctxt);
 
 	/*
diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
index 2630e777fe1d..69ca731ba9d3 100644
--- a/arch/arm64/kvm/spe.c
+++ b/arch/arm64/kvm/spe.c
@@ -140,6 +140,28 @@ void kvm_spe_sync_hwstate(struct kvm_vcpu *vcpu)
 	kvm_spe_update_irq(vcpu, true);
 }
 
+static bool kvm_spe_buffer_enabled(struct kvm_vcpu *vcpu)
+{
+	return !vcpu->arch.spe.irq_level  &&
+		(__vcpu_sys_reg(vcpu, PMBLIMITR_EL1) & BIT(SYS_PMBLIMITR_EL1_E_SHIFT));
+}
+
+bool kvm_spe_exit_to_user(struct kvm_vcpu *vcpu)
+{
+	u64 pmscr_enabled_mask = BIT(SYS_PMSCR_EL1_E0SPE_SHIFT) |
+				 BIT(SYS_PMSCR_EL1_E1SPE_SHIFT);
+
+	if (!(vcpu->arch.spe.flags & KVM_VCPU_SPE_STOP_USER_EXIT))
+		return false;
+
+	/*
+	 * We don't trap the guest dropping to EL0, so exit even if profiling is
+	 * disabled at EL1, but enabled at EL0.
+	 */
+	return kvm_spe_buffer_enabled(vcpu) &&
+		(__vcpu_sys_reg(vcpu, PMSCR_EL1) & pmscr_enabled_mask);
+}
+
 void kvm_spe_write_sysreg(struct kvm_vcpu *vcpu, int reg, u64 val)
 {
 	__vcpu_sys_reg(vcpu, reg) = val;
@@ -215,6 +237,31 @@ static bool kvm_spe_irq_is_valid(struct kvm *kvm, int irq)
 	return true;
 }
 
+static int kvm_spe_stop_user(struct kvm_vcpu *vcpu, int flags)
+{
+	struct kvm_vcpu_spe *spe = &vcpu->arch.spe;
+
+	if (flags & KVM_ARM_VCPU_SPE_STOP_TRAP) {
+		if (flags & ~KVM_ARM_VCPU_SPE_STOP_TRAP)
+			return -EINVAL;
+		spe->flags = KVM_VCPU_SPE_STOP_USER;
+	}
+
+	if (flags & KVM_ARM_VCPU_SPE_STOP_EXIT) {
+		if (flags & ~KVM_ARM_VCPU_SPE_STOP_EXIT)
+			return -EINVAL;
+		spe->flags = KVM_VCPU_SPE_STOP_USER_EXIT;
+	}
+
+	if (flags & KVM_ARM_VCPU_SPE_RESUME) {
+		if (flags & ~KVM_ARM_VCPU_SPE_RESUME)
+			return -EINVAL;
+		spe->flags = 0;
+	}
+
+	return 0;
+}
+
 int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 {
 	if (!kvm_vcpu_supports_spe(vcpu))
@@ -268,6 +315,8 @@ int kvm_spe_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 
 		if (!flags)
 			return -EINVAL;
+
+		return kvm_spe_stop_user(vcpu, flags);
 	}
 	}
 
@@ -293,6 +342,24 @@ int kvm_spe_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 
 		return 0;
 	}
+	case KVM_ARM_VCPU_SPE_STOP: {
+		int __user *uaddr = (int __user *)(long)attr->addr;
+		struct kvm_vcpu_spe *spe = &vcpu->arch.spe;
+		int flag = 0;
+
+		if (!vcpu->arch.spe.initialized)
+			return -EAGAIN;
+
+		if (spe->flags & KVM_VCPU_SPE_STOP_USER)
+			flag = KVM_ARM_VCPU_SPE_STOP_TRAP;
+		else if (spe->flags & KVM_VCPU_SPE_STOP_USER_EXIT)
+			flag = KVM_ARM_VCPU_SPE_STOP_EXIT;
+
+		if (put_user(flag, uaddr))
+			return -EFAULT;
+
+		return 0;
+	}
 	}
 
 	return -ENXIO;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 064742cee425..cc711b081f31 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -608,7 +608,7 @@ static bool access_spe_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 {	int reg = r->reg;
 	u64 val = p->regval;
 
-	if (reg < PMBLIMITR_EL1) {
+	if (reg < PMBLIMITR_EL1 && !kvm_spe_profiling_stopped(vcpu)) {
 		print_sys_reg_msg(p, "Unsupported guest SPE register access at: %lx [%08lx]\n",
 				  *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
 	}
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:13 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:13 +0100
Subject: [RFC PATCH v4 37/39] KVM: arm64: Add PMSIDR_EL1 to the SPE register
 context
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-38-alexandru.elisei@arm.com>

PMSIDR_EL1 is not part of the VCPU register context because the profiling
control registers were not trapped and the register is read-only. With the
introduction of the KVM_ARM_VCPU_SPE_STOP API, KVM will start trapping
accesses to the profiling control registers, add PMSIDR_EL1 to the VCPU
register context to prevent undefined exceptions in the guest.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/sys_regs.c         | 22 +++++++++++++++++++---
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index cc46f1406196..f866c4556ff9 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -247,6 +247,7 @@ enum vcpu_sysreg {
 	PMSFCR_EL1,     /* Sampling Filter Control Register */
 	PMSEVFR_EL1,    /* Sampling Event Filter Register */
 	PMSLATFR_EL1,   /* Sampling Latency Filter Register */
+	PMSIDR_EL1,	/* Sampling Profiling ID Register */
 	PMBLIMITR_EL1,  /* Profiling Buffer Limit Address Register */
 	PMBPTR_EL1,     /* Profiling Buffer Write Pointer Register */
 	PMBSR_EL1,      /* Profiling Buffer Status/syndrome Register */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index cc711b081f31..1a85a0cedbec 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -603,6 +603,18 @@ static unsigned int spe_visibility(const struct kvm_vcpu *vcpu,
 	return REG_HIDDEN;
 }
 
+static void reset_pmsidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	/*
+	 * When SPE is stopped by userspace, the guest reads the in-memory value
+	 * of the register. When SPE is resumed, accesses to the control
+	 * registers are not trapped and the guest reads the hardware
+	 * value. Reset PMSIDR_EL1 to the hardware value to avoid mistmatches
+	 * between the two.
+	 */
+	vcpu_write_sys_reg(vcpu, read_sysreg_s(SYS_PMSIDR_EL1), PMSIDR_EL1);
+}
+
 static bool access_spe_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 			   const struct sys_reg_desc *r)
 {	int reg = r->reg;
@@ -613,10 +625,14 @@ static bool access_spe_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 				  *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
 	}
 
-	if (p->is_write)
+	if (p->is_write) {
+		if (reg == PMSIDR_EL1)
+			return write_to_read_only(vcpu, p, r);
+
 		kvm_spe_write_sysreg(vcpu, reg, val);
-	else
+	} else {
 		p->regval = kvm_spe_read_sysreg(vcpu, reg);
+	}
 
 	return true;
 }
@@ -1568,7 +1584,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SPE_SYS_REG(SYS_PMSFCR_EL1), .reg = PMSFCR_EL1 },
 	{ SPE_SYS_REG(SYS_PMSEVFR_EL1), .reg = PMSEVFR_EL1 },
 	{ SPE_SYS_REG(SYS_PMSLATFR_EL1), .reg = PMSLATFR_EL1 },
-	{ SPE_SYS_REG(SYS_PMSIDR_EL1), .reset = NULL },
+	{ SPE_SYS_REG(SYS_PMSIDR_EL1), .reset = reset_pmsidr, .reg = PMSIDR_EL1 },
 	{ SPE_SYS_REG(SYS_PMBLIMITR_EL1), .reg = PMBLIMITR_EL1 },
 	{ SPE_SYS_REG(SYS_PMBPTR_EL1), .reg = PMBPTR_EL1 },
 	{ SPE_SYS_REG(SYS_PMBSR_EL1), .reg = PMBSR_EL1 },
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:14 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:14 +0100
Subject: [RFC PATCH v4 38/39] KVM: arm64: Make CONFIG_KVM_ARM_SPE depend on
 !CONFIG_NUMA_BALANCING
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-39-alexandru.elisei@arm.com>

Automatic NUMA balancing is a performance strategy that Linux uses to
reduce the cost associated with memory accesses by having a task use
the memory closest to the NUMA node where the task is executing. This is
accomplished by triggering periodic page faults to examine the memory
location that a task uses, and decide if page migration is necessary.

The periodic page faults that drive automatic NUMA balancing are triggered
by clearing permissions on certain pages from the task's address space.
Clearing the permissions invokes mmu_notifier_invalidate_range_start(),
which causes guest memory from being unmapped from stage 2. As a result,
SPE can start reporting stage 2 faults, which KVM has no way of handling.

Make CONFIG_KVM_ARM_SPE depend on !CONFIG_NUMA_BALANCING to keep SPE usable
for a guest.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index c6ad5a05efb3..1ea34eb29fb4 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -48,7 +48,7 @@ source "virt/kvm/Kconfig"
 
 config KVM_ARM_SPE
 	bool "Virtual Statistical Profiling Extension (SPE) support"
-	depends on ARM_SPE_PMU=y
+	depends on ARM_SPE_PMU=y && !NUMA_BALANCING
 	default y
 	help
 	  Adds support for Statistical Profiling Extension (SPE) in virtual
-- 
2.33.0



From alexandru.elisei at arm.com  Wed Aug 25 09:18:15 2021
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Wed, 25 Aug 2021 17:18:15 +0100
Subject: [RFC PATCH v4 39/39] KVM: arm64: Allow userspace to enable SPE for
 guests
In-Reply-To: <20210825161815.266051-1-alexandru.elisei@arm.com>
References: <20210825161815.266051-1-alexandru.elisei@arm.com>
Message-ID: <20210825161815.266051-40-alexandru.elisei@arm.com>

Everything is in place to emulate SPE for a guest, allow userspace to set
the VCPU feature.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 2 +-
 arch/arm64/kvm/arm.c              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f866c4556ff9..040da3b0cf2b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -39,7 +39,7 @@
 
 #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
 
-#define KVM_VCPU_MAX_FEATURES 7
+#define KVM_VCPU_MAX_FEATURES 8
 
 #define KVM_REQ_SLEEP \
 	KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index b7aae25bb9da..8016b98a8ac3 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -309,7 +309,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 		break;
 	case KVM_CAP_ARM_SPE:
 		kvm_spe_init_supported_cpus();
-		r = 0;
+		r = kvm_supports_spe();
 		break;
 	default:
 		r = 0;
-- 
2.33.0



From james.quinlan at broadcom.com  Wed Aug 25 09:18:31 2021
From: james.quinlan at broadcom.com (Jim Quinlan)
Date: Wed, 25 Aug 2021 12:18:31 -0400
Subject: [PATCH v4 03/12] firmware: arm_scmi: Add support for atomic
 transports
In-Reply-To: <20210824135941.38656-4-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-4-cristian.marussi@arm.com>
Message-ID: <CA+-6iNzTN6UHVX4qRssrqv6YVKeg97+Lz1KDcEcw6saMC0tubw@mail.gmail.com>

Hi Christian,

On Tue, Aug 24, 2021 at 10:00 AM Cristian Marussi
<cristian.marussi at arm.com> wrote:
>
> An SCMI transport can declare itself as .atomic_capable in order to signal
> to the SCMI core that all its transmit path can be executed in atomic
> context: the core as a consequence will take care not to sleep to in the
> corresponding rx path while waiting for a response or a delayed response.
>
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> ---
>  drivers/firmware/arm_scmi/common.h |   3 +
>  drivers/firmware/arm_scmi/driver.c | 167 ++++++++++++++++++++++-------
>  2 files changed, 132 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
> index 67c761141a48..4ab310c2eae5 100644
> --- a/drivers/firmware/arm_scmi/common.h
> +++ b/drivers/firmware/arm_scmi/common.h
> @@ -412,6 +412,8 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
>   * @max_msg_size: Maximum size of data per message that can be handled.
>   * @force_polling: Flag to force this whole transport to use SCMI core polling
>   *                mechanism instead of completion interrupts even if available.
> + * @atomic_capable: Flag to indicate that this transport is assured not to sleep
> + *                 on the TX path.
>   */
>  struct scmi_desc {
>         int (*transport_init)(void);
> @@ -421,6 +423,7 @@ struct scmi_desc {
>         int max_msg;
>         int max_msg_size;
>         bool force_polling;
> +       bool atomic_capable;
>  };
>
>  #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index a3700f49e8ac..2ca1602afd80 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -681,6 +681,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
>                 scmi_clear_channel(info, cinfo);
>                 complete(xfer->async_done);
>         } else {
> +               /*
> +                * This same xfer->done completion is used in atomic mode as a
> +                * flag for polling.
> +                */
>                 complete(&xfer->done);
>         }
>
> @@ -733,8 +737,6 @@ static void xfer_put(const struct scmi_protocol_handle *ph,
>         __scmi_xfer_put(&info->tx_minfo, xfer);
>  }
>
> -#define SCMI_MAX_POLL_TO_NS    (100 * NSEC_PER_USEC)
> -
>  static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
>                                       struct scmi_xfer *xfer, ktime_t stop)
>  {
> @@ -749,6 +751,90 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
>                ktime_after(ktime_get(), stop);
>  }
>
> +static bool xfer_complete_or_timeout(struct completion *done, ktime_t stop)
> +{
> +       return try_wait_for_completion(done) || ktime_after(ktime_get(), stop);
> +}
> +
> +static int spin_for_completion_timeout(struct completion *done, int timeout_ms)
> +{
> +       ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
> +
> +       spin_until_cond(xfer_complete_or_timeout(done, stop));
> +       if (ktime_after(ktime_get(), stop))
> +               return -ETIMEDOUT;
> +
> +       return 0;
> +}
> +
> +/**
> + * scmi_wait_for_message_response  - An helper to group all the possible ways of
> + * waiting for a synchronous message response.
> + *
> + * @cinfo: SCMI channel info
> + * @xfer: Reference to the transfer being waited for.
> + *
> + * Chooses waiting strategy (sleep-waiting vs busy-waiting) depending on flags
> + * configuration like xfer->hdr.poll_completion and scmi_desc.atomic.capable.
> + *
> + * Return: 0 on Success, error otherwise.
> + */
> +static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo,
> +                                         struct scmi_xfer *xfer)
> +{
> +       struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> +       struct device *dev = info->dev;
> +       int ret = 0, timeout_ms = info->desc->max_rx_timeout_ms;
> +
> +       if (!xfer->hdr.poll_completion) {
> +               if (!info->desc->atomic_capable) {
> +                       if (!wait_for_completion_timeout(&xfer->done,
> +                                                        msecs_to_jiffies(timeout_ms))) {
> +                               dev_err(dev, "timed out in resp(caller: %pS)\n",
> +                                       (void *)_RET_IP_);
> +                               ret = -ETIMEDOUT;
> +                       }
> +               } else {
> +                       /* Poll on xfer->done waiting for completion by interrupt */
> +                       ret = spin_for_completion_timeout(&xfer->done,
> +                                                         timeout_ms);
We use the SMC transport with a completion interrupt but would prefer
for the above to use wait_for_completion(...) instead of  using
spin_for_completion().  A few of our SCMI commands can take a while to
complete execution so we do not want to be spinning or polling while
waiting.

We could probably go back to a mailbox-based transport and use delayed
messages here for these "long" SCMI messages,  but we do not have full
control over the platform FW (plus there are backwards compatibility
issues).  FWIW, the platform FW was setup before SCMI on Linux
implemented delayed/async  messages.

Regards,
Jim Quinlan
Broadcom STB


> +                       if (ret)
> +                               dev_err(dev,
> +                                       "timed out in resp(caller: %pS) - atomic\n",
> +                                       (void *)_RET_IP_);
> +               }
> +       } else {
> +               /*
> +                * Poll on xfer using transport provided .poll_done();
> +                * assumes no completion interrupt was available.
> +                */
> +               ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
> +
> +               spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
> +               if (ktime_before(ktime_get(), stop)) {
> +                       unsigned long flags;
> +
> +                       /*
> +                        * Do not fetch_response if an out-of-order
> +                        * delayed response is being processed.
> +                        */
> +                       spin_lock_irqsave(&xfer->lock, flags);
> +                       if (xfer->state == SCMI_XFER_SENT_OK) {
> +                               info->desc->ops->fetch_response(cinfo, xfer);
> +                               xfer->state = SCMI_XFER_RESP_OK;
> +                       }
> +                       spin_unlock_irqrestore(&xfer->lock, flags);
> +               } else {
> +                       dev_err(dev,
> +                               "timed out in resp(caller: %pS) - polling\n",
> +                               (void *)_RET_IP_);
> +                       ret = -ETIMEDOUT;
> +               }
> +       }
> +
> +       return ret;
> +}
> +
>  /**
>   * do_xfer() - Do one transfer
>   *
> @@ -763,7 +849,6 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
>                    struct scmi_xfer *xfer)
>  {
>         int ret;
> -       int timeout;
>         const struct scmi_protocol_instance *pi = ph_to_pi(ph);
>         struct scmi_info *info = handle_to_scmi_info(pi->handle);
>         struct device *dev = info->dev;
> @@ -810,36 +895,7 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
>                 return ret;
>         }
>
> -       if (xfer->hdr.poll_completion) {
> -               ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
> -
> -               spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
> -               if (ktime_before(ktime_get(), stop)) {
> -                       unsigned long flags;
> -
> -                       /*
> -                        * Do not fetch_response if an out-of-order delayed
> -                        * response is being processed.
> -                        */
> -                       spin_lock_irqsave(&xfer->lock, flags);
> -                       if (xfer->state == SCMI_XFER_SENT_OK) {
> -                               info->desc->ops->fetch_response(cinfo, xfer);
> -                               xfer->state = SCMI_XFER_RESP_OK;
> -                       }
> -                       spin_unlock_irqrestore(&xfer->lock, flags);
> -               } else {
> -                       ret = -ETIMEDOUT;
> -               }
> -       } else {
> -               /* And we wait for the response. */
> -               timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
> -               if (!wait_for_completion_timeout(&xfer->done, timeout)) {
> -                       dev_err(dev, "timed out in resp(caller: %pS)\n",
> -                               (void *)_RET_IP_);
> -                       ret = -ETIMEDOUT;
> -               }
> -       }
> -
> +       ret = scmi_wait_for_message_response(cinfo, xfer);
>         if (!ret && xfer->hdr.status)
>                 ret = scmi_to_linux_errno(xfer->hdr.status);
>
> @@ -861,7 +917,7 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph,
>         xfer->rx.len = info->desc->max_msg_size;
>  }
>
> -#define SCMI_MAX_RESPONSE_TIMEOUT      (2 * MSEC_PER_SEC)
> +#define SCMI_DRESP_TIMEOUT     (2 * MSEC_PER_SEC)
>
>  /**
>   * do_xfer_with_response() - Do one transfer and wait until the delayed
> @@ -870,22 +926,57 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph,
>   * @ph: Pointer to SCMI protocol handle
>   * @xfer: Transfer to initiate and wait for response
>   *
> + * Avois sleeping in favour of busy-waiting if the underlying transport was
> + * declared as .atomic_capable.
> + *
> + * Note that using asynchronous commands when running on top of atomic
> + * transports should be avoided since it could cause long busy-waiting here,
> + * but, once a transport is declared atomic, upper layers using the SCMI stack
> + * can freely make assumptions about the 'non-sleeping' nature of the stack
> + * (e.g. Clock framework) and it cannot be excluded that asynchronous commands
> + * could be exposed by the platform and so used.
> + *
> + * The only other option would have been to refrain from using any asynchronous
> + * command even if made available, when an atomic transport is detected, and
> + * instead forcibly use the synchronous version (thing that can be easily
> + * attained at the protocol layer), but this would also have led to longer
> + * stalls of the channel for synchronous commands and possibly timeouts.
> + * (in other words there is usually a good reason if a platform provides an
> + *  asynchronous version of a command and we should prefer to use it)
> + *
>   * Return: -ETIMEDOUT in case of no delayed response, if transmit error,
>   *     return corresponding error, else if all goes well, return 0.
>   */
>  static int do_xfer_with_response(const struct scmi_protocol_handle *ph,
>                                  struct scmi_xfer *xfer)
>  {
> -       int ret, timeout = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT);
> +       int ret, timeout = msecs_to_jiffies(SCMI_DRESP_TIMEOUT);
> +       const struct scmi_protocol_instance *pi = ph_to_pi(ph);
> +       struct scmi_info *info = handle_to_scmi_info(pi->handle);
>         DECLARE_COMPLETION_ONSTACK(async_response);
>
>         xfer->async_done = &async_response;
>
>         ret = do_xfer(ph, xfer);
>         if (!ret) {
> -               if (!wait_for_completion_timeout(xfer->async_done, timeout))
> -                       ret = -ETIMEDOUT;
> -               else if (xfer->hdr.status)
> +               if (!info->desc->atomic_capable) {
> +                       if (!wait_for_completion_timeout(xfer->async_done,
> +                                                        timeout)) {
> +                               dev_err(ph->dev,
> +                                       "timed out in delayed resp(caller: %pS)\n",
> +                                       (void *)_RET_IP_);
> +                               ret = -ETIMEDOUT;
> +                       }
> +               } else {
> +                       ret = spin_for_completion_timeout(xfer->async_done,
> +                                                         SCMI_DRESP_TIMEOUT);
> +                       if (ret)
> +                               dev_err(ph->dev,
> +                                       "timed out in delayed resp(caller: %pS) - atomic\n",
> +                                       (void *)_RET_IP_);
> +               }
> +
> +               if (!ret && xfer->hdr.status)
>                         ret = scmi_to_linux_errno(xfer->hdr.status);
>         }
>
> --
> 2.17.1
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4210 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210825/90f886e6/attachment-0001.p7s>

From robh at kernel.org  Wed Aug 25 09:18:40 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 11:18:40 -0500
Subject: [PATCH v7 3/4] dt-bindings: pwm: add IPQ6018 binding
In-Reply-To: <YSZr/xo2a60PYTuW@robh.at.kernel.org>
References: <3b70f9e757e018d3cd91a882282040c4c0589a93.1629884907.git.baruch@tkos.co.il>
 <dbf064fb60b1654af25f65d89f75bd397162d701.1629884907.git.baruch@tkos.co.il>
 <1629900658.219829.2719822.nullmailer@robh.at.kernel.org>
 <87ilzta5xn.fsf@tarshish> <YSZr/xo2a60PYTuW@robh.at.kernel.org>
Message-ID: <CAL_JsqJsOjmUWkWCzcbSFQO5hDLW0MBKEncOyN4kEE5zY=pbPQ@mail.gmail.com>

On Wed, Aug 25, 2021 at 11:12 AM Rob Herring <robh at kernel.org> wrote:
>
> On Wed, Aug 25, 2021 at 05:59:45PM +0300, Baruch Siach wrote:
> > Hi Rob,
> >
> > On Wed, Aug 25 2021, Rob Herring wrote:
> >
> > > On Wed, 25 Aug 2021 12:48:26 +0300, Baruch Siach wrote:
> > >> DT binding for the PWM block in Qualcomm IPQ6018 SoC.
> > >>
> > >> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> > >> ---
> > >> v7:
> > >>
> > >>   Use 'reg' instead of 'offset' (Rob)
> > >>
> > >>   Drop 'clock-names' and 'assigned-clock*' (Bjorn)
> > >>
> > >>   Use single cell address/size in example node (Bjorn)
> > >>
> > >>   Move '#pwm-cells' lower in example node (Bjorn)
> > >>
> > >>   List 'reg' as required
> > >>
> > >> v6:
> > >>
> > >>   Device node is child of TCSR; remove phandle (Rob Herring)
> > >>
> > >>   Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)
> > >>
> > >> v5: Use qcom,pwm-regs for phandle instead of direct regs (Bjorn
> > >>     Andersson, Kathiravan T)
> > >>
> > >> v4: Update the binding example node as well (Rob Herring's bot)
> > >>
> > >> v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
> > >>
> > >> v2: Make #pwm-cells const (Rob Herring)
> > >> ---
> > >>  .../devicetree/bindings/pwm/ipq-pwm.yaml      | 52 +++++++++++++++++++
> > >>  1 file changed, 52 insertions(+)
> > >>  create mode 100644 Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> > >
> > > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> > > on your patch (DT_CHECKER_FLAGS is new in v5.13):
> > >
> > > yamllint warnings/errors:
> > >
> > > dtschema/dtc warnings/errors:
> > > Documentation/devicetree/bindings/pwm/ipq-pwm.example.dt.yaml:0:0:
> > > /example-0/syscon at 1937000: failed to match any schema with compatible:
> > > ['qcom,tcsr-ipq6018', 'syscon', 'simple-mfd']
> >
> > What can I do about that? Is it because qcom,tcsr-ipq6018 is documented
> > in a non-yaml plain .txt file?
>
> No, it is not documented at all.

Sorry, I should read patch 1 first... Still, before adding new
features to an MFD, the base MFD should be converted.

Rob


From f.fainelli at gmail.com  Wed Aug 25 09:23:47 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:23:47 +0200
Subject: [PATCH v2 3/4] PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
In-Reply-To: <ddffee4b-8136-9ca1-85f7-bfdbac07bfe7@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
 <20210819215655.84866-4-jeremy.linton@arm.com>
 <9796674a-5870-135c-2fdc-fb0d5347d7c7@gmail.com>
 <ddffee4b-8136-9ca1-85f7-bfdbac07bfe7@arm.com>
Message-ID: <0f21622f-2651-d1ca-7b47-4a3060a9539c@gmail.com>



On 8/24/2021 11:39 PM, Jeremy Linton wrote:
> Hi,
> 
> On 8/22/21 3:53 AM, Florian Fainelli wrote:
>>
>>
>> On 8/19/2021 11:56 PM, Jeremy Linton wrote:
>>> Now that there is a bcm2711 quirk, it needs to be enabled when the
>>> MCFG is missing. Use an ACPI namespace _DSD property
>>> "linux-ecam-quirk-id" as an alternative to the MCFG OEM.
>>>
>>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>>> ---
>>> ? drivers/acpi/pci_mcfg.c | 13 +++++++++++++
>>> ? 1 file changed, 13 insertions(+)
>>>
>>> diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
>>> index 53cab975f612..4b991ee5c66c 100644
>>> --- a/drivers/acpi/pci_mcfg.c
>>> +++ b/drivers/acpi/pci_mcfg.c
>>> @@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
>>> ????? ALTRA_ECAM_QUIRK(1, 13),
>>> ????? ALTRA_ECAM_QUIRK(1, 14),
>>> ????? ALTRA_ECAM_QUIRK(1, 15),
>>> +
>>> +??? { "bcm2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
>>> +????? DEFINE_RES_MEM(0xFD500000, 0xA000) },
>>> ? };
>>> ? static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
>>> @@ -198,8 +201,18 @@ static void pci_mcfg_apply_quirks(struct 
>>> acpi_pci_root *root,
>>> ????? u16 segment = root->segment;
>>> ????? struct resource *bus_range = &root->secondary;
>>> ????? struct mcfg_fixup *f;
>>> +??? const char *soc;
>>> ????? int i;
>>> +??? /*
>>> +???? * This may be a machine with a PCI/SMC conduit, which means it 
>>> doesn't
>>> +???? * have an MCFG. Use an ACPI namespace definition instead.
>>> +???? */
>>> +??? if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
>>> +???????????????????? "linux-ecam-quirk-id", &soc)) {
>>> +??????? memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
>>
>> Being super paranoid here, can we use one of the "safe" string copy 
>> routines here just in case?
> 
> Hmm, I went around with this a bit when I first wrote it, because the 
> OEM fields in the ACPI tables are fixed len and don't have null 
> termination. Maybe the right thing to do here is verify the string size 
> is at least as long as the OEM_ID_SIZE and then continue to use the memcpy.

Sure, sounds entirely reasonable to me.
-- 
Florian


From f.fainelli at gmail.com  Wed Aug 25 09:28:14 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:28:14 +0200
Subject: [PATCH v4 01/12] firmware: arm_scmi: Perform earlier cinfo lookup
 call in do_xfer
In-Reply-To: <20210824135941.38656-2-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-2-cristian.marussi@arm.com>
Message-ID: <6344d757-7ef5-f6af-5f27-9c88f5befcbf@gmail.com>



On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> Lookup cinfo data early in do_xfer so as to avoid any further init work
> on xfer structure in case of error.
> 
> No functional change.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From f.fainelli at gmail.com  Wed Aug 25 09:29:31 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:29:31 +0200
Subject: [PATCH v4 02/12] firmware: arm_scmi: Add configurable polling
 mode for transports
In-Reply-To: <20210824135941.38656-3-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-3-cristian.marussi@arm.com>
Message-ID: <3be84c2b-bb86-65c4-4c32-957767ffa577@gmail.com>



On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> SCMI communications along TX channels can optionally be provided of a
> completion interrupt; when such interrupt is not available, command
> transactions should rely on polling, where the SCMI core takes care to
> repeatedly evaluate the transport-specific .poll_done() function to
> determine if and when a request was fully completed or timed out.
> 
> Such mechanism is already present and working on a single transfer base:
> SCMI protocols can indeed enable hdr.poll_completion on specific commands
> ahead of each transfer and cause that transaction to be handled with
> polling.
> 
> Introduce a couple of flags to be able to enforce such polling behaviour
> globally at will:
> 
>   - scmi_desc.force_polling: to statically switch the whole transport to
>     polling mode.
> 
>   - scmi_chan_info.no_completion_irq: to switch a single channel dynamically
>     to polling mode if at runtime is determined that no completion interrupt
>     was available for such channel.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From f.fainelli at gmail.com  Wed Aug 25 09:30:33 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:30:33 +0200
Subject: [PATCH v4 04/12] include: trace: Add new scmi_xfer_response_wait
 event
In-Reply-To: <20210824135941.38656-5-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-5-cristian.marussi@arm.com>
Message-ID: <c108fd89-2b72-33a2-d6b9-13a20773bbe2@gmail.com>



On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> Having a new step to trace SCMI stack while it waits for synchronous
> responses is useful to analyze system performance when changing waiting
> mode between polling and interrupt completion.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From robh at kernel.org  Wed Aug 25 09:31:11 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 11:31:11 -0500
Subject: [PATCH v3 2/7] dt-bindings: mediatek: Add #reset-cells to mmsys
 system controller
In-Reply-To: <20210825122613.v3.2.I3f7f1c9a8e46be07d1757ddf4e0097535f3a7d41@changeid>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
 <20210825122613.v3.2.I3f7f1c9a8e46be07d1757ddf4e0097535f3a7d41@changeid>
Message-ID: <YSZwT8QahCfWE5N3@robh.at.kernel.org>

On Wed, 25 Aug 2021 12:26:27 +0200, Enric Balletbo i Serra wrote:
> The mmsys system controller exposes a set of memory client resets and
> needs to specify the #reset-cells property in order to advertise the
> number of cells needed to describe each of the resets.
> 
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> ---
> 
> Changes in v3:
> - Based on top of the patch that converts mmsys to schema
> 
>  .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml      | 4 ++++
>  1 file changed, 4 insertions(+)
> 

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


From f.fainelli at gmail.com  Wed Aug 25 09:31:13 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:31:13 +0200
Subject: [PATCH v4 05/12] firmware: arm_scmi: Use new trace event
 scmi_xfer_response_wait
In-Reply-To: <20210824135941.38656-6-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-6-cristian.marussi@arm.com>
Message-ID: <2ffa7d65-21ef-433b-8a86-068df13950d2@gmail.com>



On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> Use new trace event to mark start of waiting for response section.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>

Might be worth squashing into patch 4?

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From f.fainelli at gmail.com  Wed Aug 25 09:32:13 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:32:13 +0200
Subject: [PATCH v4 06/12] firmware: arm_scmi: Add is_transport_atomic()
 handle method
In-Reply-To: <20210824135941.38656-7-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-7-cristian.marussi@arm.com>
Message-ID: <aa60f50e-0250-dd4b-69d3-4f42f14166e3@gmail.com>



On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> Add a method to check if the underlying transport configured for an SCMI
> instance is configured to support atomic transaction of SCMI commands.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From f.fainelli at gmail.com  Wed Aug 25 09:33:02 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:33:02 +0200
Subject: [PATCH v4 07/12] clk: scmi: Support atomic enable/disable API
In-Reply-To: <20210824135941.38656-8-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-8-cristian.marussi@arm.com>
Message-ID: <c8e13051-4bab-abb1-5193-b06fe74b4df6@gmail.com>



On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> Support enable/disable clk_ops instead of prepare/unprepare when the
> underlying SCMI transport is configured to support atomic transactions for
> synchronous commands.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From f.fainelli at gmail.com  Wed Aug 25 09:35:53 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:35:53 +0200
Subject: [PATCH v4 09/12] [RFC] firmware: arm_scmi: Make smc transport use
 common completions
In-Reply-To: <20210824135941.38656-10-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-10-cristian.marussi@arm.com>
Message-ID: <2f03630a-0339-1eb6-9b26-170927c4ad86@gmail.com>



On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> When a completion irq is available use it and delegate command completion
> handling to the core SCMI completion mechanism.
> 
> If no completion irq is available revert to polling, using the core common
> polling machinery.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From helgaas at kernel.org  Wed Aug 25 09:37:38 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 25 Aug 2021 11:37:38 -0500
Subject: [PATCH v2 2/6] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <e17461407cf4bb79fed5925ec81196a0b84e7827.1620203062.git.baruch@tkos.co.il>
Message-ID: <20210825163738.GA3576149@bjorn-Precision-5520>

In subject:

s/add support/Add support/ to match previous history.

On Wed, May 05, 2021 at 12:18:30PM +0300, Baruch Siach wrote:
> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> 
> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> platform.
> 
> The code is based on downstream Codeaurora kernel v5.4. Split out the
> DBI registers access part from .init into .post_init. DBI registers are
> only accessible after phy_power_on().

The "downstream Codeaurora kernel v5.4" reference would be more useful
if there were a URL reference to that driver.

> +#define AXI_CLK_RATE				200000000
> +#define RCHNG_CLK_RATE				100000000

These are unused.

> +	for (i = 0;i < 256;i++)

Add spaces after semicolons.


From f.fainelli at gmail.com  Wed Aug 25 09:38:19 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 25 Aug 2021 18:38:19 +0200
Subject: [PATCH v4 11/12] [RFC] firmware: arm_scmi: Add
 sync_cmds_atomic_replies transport flag
In-Reply-To: <20210824135941.38656-12-cristian.marussi@arm.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-12-cristian.marussi@arm.com>
Message-ID: <7a2f972d-fdd0-d0f7-cac2-1989980ed872@gmail.com>



On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> A flag is added to let the transport signal the core that its handling of
> synchronous command messages implies that, after .send_message has returned
> successfully, the requested command can be assumed to be fully and
> completely executed on SCMI platform side so that any possible response
> value is already immediately available to be retrieved by a .fetch_reponse:
> in other words the polling phase can be skipped in such a case and the
> response values accessed straight away.
> 
> Note that all of the above applies only when polling mode of operation was
> selected by the core: if instead a completion IRQ was found to be available
> the normal response processing path based on completions will still be
> followed.

This might actually have to be settable on a per-message basis ideally 
since we may be transporting short lived SCMI messages for which the 
completion can be done at SMC time, and long lived SCMI messages (e.g.: 
involving a voltage change) for which we would prefer a completion 
interrupt. Jim, what do you think?
-- 
Florian


From enric.balletbo at collabora.com  Wed Aug 25 09:54:54 2021
From: enric.balletbo at collabora.com (Enric Balletbo i Serra)
Date: Wed, 25 Aug 2021 18:54:54 +0200
Subject: [PATCH v7 7/7] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <1629904697.15752.11.camel@mhfsdcap03>
References: <20210825063323.3607738-1-eizan@chromium.org>
 <20210825163247.v7.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <1629880999.12893.17.camel@mhfsdcap03>
 <0c9fa482-57dd-d4ef-c65b-01f137c57359@collabora.com>
 <1629904697.15752.11.camel@mhfsdcap03>
Message-ID: <e9020b68-5d20-8e4f-4883-273fe4697d60@collabora.com>

Hi Houlong,

Thank you for your answer, some more questions below :-)

On 25/8/21 17:18, houlong wei wrote:
> On Wed, 2021-08-25 at 17:07 +0800, Enric Balletbo i Serra wrote:
>> Hi Houlong,
>>
>> Thank you for following up this patchset. I have some questions to try to
>> understand better the hardware though.
>>
>> On 25/8/21 10:43, houlong wei wrote:
>>> Hi Eizan,
>>>
>>> Thanks for you patch. I have inline comment below.
>>>
>>> Regards,
>>> Houlong
>>>
>>> On Wed, 2021-08-25 at 14:33 +0800, Eizan Miyamoto wrote:
>>>> ... Instead of depending on the presence of a mediatek,vpu property in
>>>> the device node.
>>>>
>>>> That property was originally added to link to the vpu node so that the
>>>> mtk_mdp_core driver could pass the right device to
>>>> vpu_wdt_reg_handler(). However in a previous patch in this series,
>>>> the driver has been modified to search the device tree for that node
>>>> instead.
>>>>
>>>> That property was also used to indicate the primary MDP device, so that
>>>> it can be passed to the V4L2 subsystem as well as register it to be
>>>> used when setting up queues in the open() callback for the filesystem
>>>> device node that is created. In this case, assuming that the primary
>>>> MDP device is the one with a specific alias seems useable because the
>>>> alternative is to add a property to the device tree which doesn't
>>>> actually represent any facet of hardware (i.e., this being the primary
>>>> MDP device is a software decision). In other words, this solution is
>>>> equally as arbitrary, but at least it doesn't add a property to a
>>>> device node where said property is unrelated to the hardware present.
>>>>
>>>> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
>>>> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
>>>> ---
>>>>
>>>> (no changes since v1)
>>>>
>>>>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
>>>>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
>>>>  2 files changed, 64 insertions(+), 28 deletions(-)
>>>>
>>>> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
>>>> index 85ef274841a3..9527649de98e 100644
>>>> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
>>>> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
>>>> @@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
>>>>  		mtk_smi_larb_put(comp->larb_dev);
>>>>  }
>>>>  
>>>> -static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
>>>> +/*
>>>> + * The MDP master device node is identified by the device tree alias
>>>> + * "mdp-rdma0".
>>>> + */
>>>> +static bool is_mdp_master(struct device *dev)
>>>> +{
>>>> +	struct device_node *aliases, *mdp_rdma0_node;
>>>> +	const char *mdp_rdma0_path;
>>>> +
>>>> +	if (!dev->of_node)
>>>> +		return false;
>>>> +
>>>> +	aliases = of_find_node_by_path("/aliases");
>>>> +	if (!aliases) {
>>>> +		dev_err(dev, "no aliases found for mdp-rdma0");
>>>> +		return false;
>>>> +	}
>>>> +
>>>> +	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
>>>> +	if (!mdp_rdma0_path) {
>>>> +		dev_err(dev, "get mdp-rdma0 property of /aliases failed");
>>>> +		return false;
>>>> +	}
>>>> +
>>>> +	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
>>>> +	if (!mdp_rdma0_node) {
>>>> +		dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
>>>> +		return false;
>>>> +	}
>>>> +
>>>> +	return dev->of_node == mdp_rdma0_node;
>>>
>>>
>>> About how to determine the master mdp driver, we also can
>>> judge the component type. The component type can be gotten by calling
>>> of_device_get_match_data(dev). If the component is MTK_MDP_RDMA, it is
>>> the master driver. No matter it is mdp_rdma0 or mdp_rdma1.
>>
>>
>> I'm confused, you mean that the component type, aka MTK_MDP_RDMA is only set for
>> mtk_mdp_rdma0? isn't mtk_dmp_rdma1 also a MTK_MDP_RDMA type? Because looks weird
>> to me that two rdma have diffent types.
>>
> Hi Enric,
> 
> I can understand your doubts. For mtk-mdp dirver, it is really difficult
> to understand the relationship among the components. Because the MDP
> hardware path is configured and connected in the VPU firmware.

So is fixed by the VPU firmware and can't be changed via, i.e writing some
registers? Can't be platform data then?

If that's the case, can you draw the mdp hardware path for i.e MT8173? (so I
have a better understanding)


> For MT8173, the component type of mtk_mdp_rdma0 and mtk_mdp_rdma1 are
> both MTK_MDP_RDMA. Even though the mtk-mdp driver's component list
> contains both of them, only one corresponding hardware component takes
> effect during the processing of a frame, the VPU decides it.
> 

So IIUC the VPU firmware decides which rdma uses on every frame, right? From hw
point of view, why one of them need to be master?

> Regards,
> Houlong
>>
>>> http://lists.infradead.org/pipermail/linux-mediatek/2021-August/028533.html
>>>
>>> IMO, judging it by component type is more flexible because it does not
>>> limit to 'mdp_rdma0'.
>>>
>>
>> Using an alias like Eizan did is also flexible, you only need to set mdp-rdma0
>> to point the mdp_rdma1 node.
>>
>> What I am really interested to know is the differences between the platforms to
>> understand if this is really a platform hardware property or a software
>> configurable thing, so would help if you can give use the different use cases
>> for different SoCs.
>>
>> For MT8173 which is the master device? is _always_ rdma0 or can also be rdma1?
>>
>> Or maybe what is not clear here is what exactly means be a master device?
>>
>> What about MT8183 and other SoCs?
>>
>> Thanks,
>>   Enric
>>
> Hi Enric,
> 
> Before answer your questions, let's unify the concept of the master
> device.If an MDP device-tree node can not only generate a /dev/video
> device node, but also can generate a mtk component device node, then
> this component device is the master device.

Sorry, what you mean with a mtk component device node?

> From the perspective of the device tree node, the compatible of a MDP
> device tree node contains both "mediatek,mt8173-mdp-rdma" and
> "mediatek,mt8173-mdp", then its corresponding mtk component device is
> the master device.

So that's what's wrong, and Eizan patches get rid of this. In this case you
can't use device-tree to specify such master device. Device-tree is only about
hardware description, can't be used, in this case, as entry point to instantiate
the mdp driver. Hence Eizan patches change this, and mdp is instantiated by the
mmsys driver. Similar to what we do for the drm driver.

For the two hw rdma blocks the compatible should be just
"mediatek,mt8173-mdp-rdma" in this case.

Thanks,
  Enric

> Since this concept comes from Eizan's patches, if my understanding is
> different from yours, please let me know, thanks.
> 
> If there is only one master device, I fully agree with you. For MT8173,
> both mdp_rdma0 and mdp_rdma1 can be master device at the same time.
> But now only mdp_rdma0 takes this role, perhaps because one MDP hardware
> path could meet the project's the requirement six years ago.
> In some project, we have two or more MDP hardware paths, we can
> configure all the mdp_rdma components as master devices, and there will
> be several /dev/video device nodes. The user can control them
> concurrently.
> 
> Regards,
> Houlong
> 
>>
>>>> +}
>>>> +
>>>> +static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
>>>> +			void *data)
>>>>  {
>>>>  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
>>>>  	struct mtk_mdp_dev *mdp = data;
>>>> -	struct device_node *vpu_node;
>>>>  
>>>>  	mtk_mdp_register_component(mdp, comp);
>>>>  
>>>> -	/*
>>>> -	 * If this component has a "mediatek-vpu" property, it is responsible for
>>>> -	 * notifying the mdp master driver about it so it can be further initialized
>>>> -	 * later.
>>>> -	 */
>>>> -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
>>>> -	if (vpu_node) {
>>>> +	if (is_mdp_master(dev)) {
>>>>  		int ret;
>>>>  
>>>> -		mdp->vpu_dev = of_find_device_by_node(vpu_node);
>>>> -		if (WARN_ON(!mdp->vpu_dev)) {
>>>> -			dev_err(dev, "vpu pdev failed\n");
>>>> -			of_node_put(vpu_node);
>>>> -		}
>>>> -
>>>>  		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
>>>>  		if (ret) {
>>>>  			dev_err(dev, "Failed to register v4l2 device\n");
>>>> @@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
>>>>  		}
>>>>  
>>>>  		/*
>>>> -		 * presence of the "mediatek,vpu" property in a device node
>>>> -		 * indicates that it is the primary MDP rdma device and MDP DMA
>>>> -		 * ops should be handled by its DMA callbacks.
>>>> +		 * MDP DMA ops will be handled by the DMA callbacks associated with this
>>>> +		 * device;
>>>>  		 */
>>>>  		mdp->rdma_dev = dev;
>>>>  	}
>>>> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
>>>> index 50eafcc9993d..6a775463399c 100644
>>>> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
>>>> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
>>>> @@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
>>>>  
>>>>  static int mtk_mdp_master_bind(struct device *dev)
>>>>  {
>>>> -	int status;
>>>>  	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
>>>> +	struct device_node *vpu_node;
>>>> +	int status;
>>>>  
>>>>  	status = component_bind_all(dev, mdp);
>>>>  	if (status) {
>>>> @@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
>>>>  		goto err_component_bind_all;
>>>>  	}
>>>>  
>>>> -	if (mdp->vpu_dev) {
>>>> -		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
>>>> -					  VPU_RST_MDP);
>>>> -		if (ret) {
>>>> -			dev_err(dev, "Failed to register reset handler\n");
>>>> -			goto err_wdt_reg;
>>>> -		}
>>>> -	} else {
>>>> -		dev_err(dev, "no vpu_dev found\n");
>>>> +	if (mdp->rdma_dev == NULL) {
>>>> +		dev_err(dev, "Primary MDP device not found");
>>>> +		status = -ENODEV;
>>>> +		goto err_component_bind_all;
>>>> +	}
>>>> +
>>>> +	vpu_node = of_find_node_by_name(NULL, "vpu");
>>>> +	if (!vpu_node) {
>>>> +		dev_err(dev, "unable to find vpu node");
>>>> +		status = -ENODEV;
>>>> +		goto err_wdt_reg;
>>>> +	}
>>>> +
>>>> +	mdp->vpu_dev = of_find_device_by_node(vpu_node);
>>>
>>> The 'vpu_node' should be put by calling 'of_node_put(vpu_node)' when it
>>> is not used.
>>>
>>>> +	if (!mdp->vpu_dev) {
>>>> +		dev_err(dev, "unable to find vpu device");
>>>> +		status = -ENODEV;
>>>> +		goto err_wdt_reg;
>>>> +	}
>>>> +
>>>> +	status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
>>>> +	if (status) {
>>>> +		dev_err(dev, "Failed to register reset handler\n");
>>>> +		goto err_wdt_reg;
>>>>  	}
>>>>  
>>>>  	status = mtk_mdp_register_m2m_device(mdp);
>>>
> 


From mathieu.poirier at linaro.org  Wed Aug 25 10:02:13 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 25 Aug 2021 11:02:13 -0600
Subject: [PATCHv2 2/4] coresight: tmc-etr: Track perf handler.
In-Reply-To: <20210713121532.836244-3-daniel.kiss@arm.com>
References: <20210713121532.836244-1-daniel.kiss@arm.com>
 <20210713121532.836244-3-daniel.kiss@arm.com>
Message-ID: <20210825170213.GA763112@p14s>

Hi Daniel,

On Tue, Jul 13, 2021 at 02:15:30PM +0200, Daniel Kiss wrote:
> Keep track of the perf handler that is registred by the first tracer.
> This will be used by the update call from polling.
> 
> Signed-off-by: Daniel Kiss <daniel.kiss at arm.com>
> Signed-off-by: Branislav Rankov <Branislav.Rankov at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-tmc-etr.c | 6 ++++--
>  drivers/hwtracing/coresight/coresight-tmc.h     | 2 ++
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index 589bb2d56e802..55c9b5fd9f832 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -1503,8 +1503,8 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
>  
>  	spin_lock_irqsave(&drvdata->spinlock, flags);
>  
> -	/* Don't do anything if another tracer is using this sink */
> -	if (atomic_read(csdev->refcnt) != 1) {
> +	/* Serve only the tracer with the leading perf handler */
> +	if (drvdata->perf_handle != handle) {

In CPU wide trace scenarios the first CPU to enable a sink is not
guaranteed to be the same as the last CPU to use it.  As far as I understand the
above assumes the first and last CPUs to use a sink are the same.

>  		spin_unlock_irqrestore(&drvdata->spinlock, flags);
>  		goto out;
>  	}
> @@ -1619,6 +1619,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
>  		drvdata->pid = pid;
>  		drvdata->mode = CS_MODE_PERF;
>  		drvdata->perf_buf = etr_perf->etr_buf;
> +		drvdata->perf_handle = handle;
>  		atomic_inc(csdev->refcnt);
>  	}
>  
> @@ -1666,6 +1667,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
>  	drvdata->mode = CS_MODE_DISABLED;
>  	/* Reset perf specific data */
>  	drvdata->perf_buf = NULL;
> +	drvdata->perf_handle = NULL;
>  
>  	spin_unlock_irqrestore(&drvdata->spinlock, flags);
>  
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index b91ec7dde7bc9..81583ffb973dc 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -184,6 +184,7 @@ struct etr_buf {
>   * @idr_mutex:	Access serialisation for idr.
>   * @sysfs_buf:	SYSFS buffer for ETR.
>   * @perf_buf:	PERF buffer for ETR.
> + * @perf_handle: PERF handle for ETR.
>   */
>  struct tmc_drvdata {
>  	void __iomem		*base;
> @@ -207,6 +208,7 @@ struct tmc_drvdata {
>  	struct mutex		idr_mutex;
>  	struct etr_buf		*sysfs_buf;
>  	struct etr_buf		*perf_buf;
> +	struct perf_output_handle *perf_handle;
>  };
>  
>  struct etr_buf_operations {
> -- 
> 2.25.1
> 


From catalin.marinas at arm.com  Wed Aug 25 10:15:53 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 25 Aug 2021 18:15:53 +0100
Subject: [BUG 5.14] arm64/mm: dma memory mapping fails (in some cases)
In-Reply-To: <547785ff-e02f-df28-7f9c-9ad4f5b3cc77@redhat.com>
References: <d3a3c828-b777-faf8-e901-904995688437@gmail.com>
 <20210824173741.GC623@arm.com> <YSU6NVZ3j0XCurWC@kernel.org>
 <0908ce39-7e30-91fa-68ef-11620f9596ae@arm.com>
 <60a11eba-2910-3b5f-ef96-97d4556c1596@redhat.com>
 <20210825102044.GA3420@arm.com>
 <b720e7c8-ca44-0a25-480b-05bf49d03c35@redhat.com>
 <20210825105510.GB3420@arm.com>
 <547785ff-e02f-df28-7f9c-9ad4f5b3cc77@redhat.com>
Message-ID: <20210825171552.GH3420@arm.com>

On Wed, Aug 25, 2021 at 01:12:37PM +0200, David Hildenbrand wrote:
> On 25.08.21 12:55, Catalin Marinas wrote:
> > On Wed, Aug 25, 2021 at 12:38:31PM +0200, David Hildenbrand wrote:
> > > On 25.08.21 12:20, Catalin Marinas wrote:
> > > > I can see the documentation for pfn_valid() does not claim anything more
> > > > than the presence of an memmap entry. But I wonder whether the confusion
> > > > is wider-spread than just the DMA code. At a quick grep, try_ram_remap()
> > > > assumes __va() can be used on pfn_valid(), though I suspect it relies on
> > > > the calling function to check that the resource was RAM. The arm64
> > > > kern_addr_valid() returns true based on pfn_valid() and kcore.c uses
> > > > standard memcpy on it, which wouldn't work for I/O (should we change
> > > > this check to pfn_is_map_memory() for arm64?).
> > > 
> > > kern_addr_valid() checks that there is a direct map entry, and that the
> > > mapped address has a valid mmap. (copied from x86-64)
> > 
> > It checks that there is a va->pa mapping, not necessarily in the linear
> > map as it walks the page tables. So for some I/O range that happens to
> > be mapped but which was in close proximity to RAM so that pfn_valid() is
> > true, kern_addr_valid() would return true. I don't thin that was the
> > intention.
> > 
> > > Would you expect to have a direct map for memory holes and similar (IOW,
> > > !System RAM)?
> > 
> > No, but we with the generic pfn_valid(), it may return true for mapped
> > MMIO (with different attributes than the direct map).
> 
> Ah, right. But can we actually run into that via kcore?
> 
> kcore builds the RAM list via walk_system_ram_range(), IOW the resource
> tree. And we end up calling kern_addr_valid() only on KCORE_RAM,
> KCORE_VMEMMAP and KCORE_TEXT.

It's probably fine but I'd rather do some check of the other call sites
before attempting to move arm64 to the generic pfn_valid() again.

-- 
Catalin


From james.quinlan at broadcom.com  Wed Aug 25 10:17:47 2021
From: james.quinlan at broadcom.com (Jim Quinlan)
Date: Wed, 25 Aug 2021 13:17:47 -0400
Subject: [PATCH v4 11/12] [RFC] firmware: arm_scmi: Add
 sync_cmds_atomic_replies transport flag
In-Reply-To: <7a2f972d-fdd0-d0f7-cac2-1989980ed872@gmail.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-12-cristian.marussi@arm.com>
 <7a2f972d-fdd0-d0f7-cac2-1989980ed872@gmail.com>
Message-ID: <CA+-6iNw-_VXcntU_UE8kTiPb8Sq28KkZG1__N7rE4ezo=VqQVQ@mail.gmail.com>

On Wed, Aug 25, 2021 at 12:38 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
>
>
>
> On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> > A flag is added to let the transport signal the core that its handling of
> > synchronous command messages implies that, after .send_message has returned
> > successfully, the requested command can be assumed to be fully and
> > completely executed on SCMI platform side so that any possible response
> > value is already immediately available to be retrieved by a .fetch_reponse:
> > in other words the polling phase can be skipped in such a case and the
> > response values accessed straight away.
> >
> > Note that all of the above applies only when polling mode of operation was
> > selected by the core: if instead a completion IRQ was found to be available
> > the normal response processing path based on completions will still be
> > followed.
>
> This might actually have to be settable on a per-message basis ideally
> since we may be transporting short lived SCMI messages for which the
> completion can be done at SMC time, and long lived SCMI messages (e.g.:
> involving a voltage change) for which we would prefer a completion
> interrupt. Jim, what do you think?
Even if the SCMI main driver could be configured this way in an
elegant manner, I'm not sure that there is a clean way of specifying
this  attribute on a per-message basis.  Certainly we could do this
with our own protocols, but  many of our "long lived" messages are the
Perf protocol's set_level command.  At any rate, let me give it some
thought.

Regards,
Jim
> --
> Florian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4210 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210825/a58834c2/attachment-0001.p7s>

From rafael at kernel.org  Wed Aug 25 10:46:19 2021
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Wed, 25 Aug 2021 19:46:19 +0200
Subject: [PATCH RESEND v3] ACPI: Add memory semantics to
 acpi_os_map_memory()
In-Reply-To: <20210823123052.GC8603@arm.com>
References: <20210802152359.12623-1-lorenzo.pieralisi@arm.com>
 <20210823104618.14552-1-lorenzo.pieralisi@arm.com>
 <20210823123052.GC8603@arm.com>
Message-ID: <CAJZ5v0g9_jq4xgHTkxX8WFGwTwmSUUMKkMUF2HadauWqGrLiHA@mail.gmail.com>

On Mon, Aug 23, 2021 at 2:31 PM Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> On Mon, Aug 23, 2021 at 11:46:18AM +0100, Lorenzo Pieralisi wrote:
> > The memory attributes attached to memory regions depend on architecture
> > specific mappings.
> >
> > For some memory regions, the attributes specified by firmware (eg
> > uncached) are not sufficient to determine how a memory region should be
> > mapped by an OS (for instance a region that is define as uncached in
> > firmware can be mapped as Normal or Device memory on arm64) and
> > therefore the OS must be given control on how to map the region to match
> > the expected mapping behaviour (eg if a mapping is requested with memory
> > semantics, it must allow unaligned accesses).
> >
> > Rework acpi_os_map_memory() and acpi_os_ioremap() back-end to split
> > them into two separate code paths:
> >
> > acpi_os_memmap() -> memory semantics
> > acpi_os_ioremap() -> MMIO semantics
> >
> > The split allows the architectural implementation back-ends to detect
> > the default memory attributes required by the mapping in question
> > (ie the mapping API defines the semantics memory vs MMIO) and map the
> > memory accordingly.
> >
> > Link: https://lore.kernel.org/linux-arm-kernel/31ffe8fc-f5ee-2858-26c5-0fd8bdd68702 at arm.com
> > Tested-by: Hanjun Guo <guohanjun at huawei.com>
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Acked-by: Ard Biesheuvel <ardb at kernel.org>
> > Cc: Ard Biesheuvel <ardb at kernel.org>
> > Cc: Will Deacon <will at kernel.org>
> > Cc: Hanjun Guo <guohanjun at huawei.com>
> > Cc: Sudeep Holla <sudeep.holla at arm.com>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>
> > ---
> > Resending with all lists CC'ed.
> >
> > Patch series is a v3 of a previous version[2]:
> >
> > v2->v3:
> >       - Dropped first two-patches following LKML feedback[2]
> > v1->v2
> >       - Added patch 1 and 2 according to feedback received on[1]
> >
> > [1] https://lore.kernel.org/linux-acpi/20210726100026.12538-1-lorenzo.pieralisi at arm.com
> > [2] https://lore.kernel.org/linux-acpi/20210802152359.12623-1-lorenzo.pieralisi at arm.com
> >
> >  arch/arm64/include/asm/acpi.h |  3 +++
> >  arch/arm64/kernel/acpi.c      | 19 ++++++++++++++++---
> >  drivers/acpi/osl.c            | 23 ++++++++++++++++-------
> >  include/acpi/acpi_io.h        |  8 ++++++++
> >  4 files changed, 43 insertions(+), 10 deletions(-)
>
> For arm64:
>
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
>
> I presume this patch would go in via the acpi tree.

Applied as 5.15 material, thanks!


From rafael at kernel.org  Wed Aug 25 10:48:28 2021
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Wed, 25 Aug 2021 19:48:28 +0200
Subject: [PATCH v2 1/3] x86,
 ACPI: rename init_freq_invariance_cppc to arch_init_invariance_cppc
In-Reply-To: <20210824105651.28660-2-ionela.voinescu@arm.com>
References: <20210824105651.28660-1-ionela.voinescu@arm.com>
 <20210824105651.28660-2-ionela.voinescu@arm.com>
Message-ID: <CAJZ5v0jaRaP-+Zxx9NS8OcREEbmcJo1Zs-p3gT9BLNKBtNtqyg@mail.gmail.com>

On Tue, Aug 24, 2021 at 12:57 PM Ionela Voinescu
<ionela.voinescu at arm.com> wrote:
>
> init_freq_invariance_cppc() was called in acpi_cppc_processor_probe(),
> after CPU performance information and controls were populated from the
> per-cpu _CPC objects.
>
> But these _CPC objects provide information that helps with both CPU
> (u-arch) and frequency invariance. Therefore, change the function name
> to a more generic one, while adding the arch_ prefix, as this function
> is expected to be defined differently by different architectures.
>
> Signed-off-by: Ionela Voinescu <ionela.voinescu at arm.com>
> Tested-by: Valentin Schneider <valentin.schneider at arm.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Giovanni Gherdovich <ggherdovich at suse.cz>
> Cc: "Rafael J. Wysocki" <rjw at rjwysocki.net>

Acked-by: Rafael J. Wysocki <rafael at kernel.org>

> ---
>  arch/x86/include/asm/topology.h | 2 +-
>  drivers/acpi/cppc_acpi.c        | 6 +++---
>  2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
> index 9239399e5491..61d73013cab8 100644
> --- a/arch/x86/include/asm/topology.h
> +++ b/arch/x86/include/asm/topology.h
> @@ -220,7 +220,7 @@ static inline void arch_set_max_freq_ratio(bool turbo_disabled)
>
>  #ifdef CONFIG_ACPI_CPPC_LIB
>  void init_freq_invariance_cppc(void);
> -#define init_freq_invariance_cppc init_freq_invariance_cppc
> +#define arch_init_invariance_cppc init_freq_invariance_cppc
>  #endif
>
>  #endif /* _ASM_X86_TOPOLOGY_H */
> diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
> index a4d4eebba1da..c211d77310e8 100644
> --- a/drivers/acpi/cppc_acpi.c
> +++ b/drivers/acpi/cppc_acpi.c
> @@ -660,8 +660,8 @@ static bool is_cppc_supported(int revision, int num_ent)
>   *     }
>   */
>
> -#ifndef init_freq_invariance_cppc
> -static inline void init_freq_invariance_cppc(void) { }
> +#ifndef arch_init_invariance_cppc
> +static inline void arch_init_invariance_cppc(void) { }
>  #endif
>
>  /**
> @@ -826,7 +826,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
>                 goto out_free;
>         }
>
> -       init_freq_invariance_cppc();
> +       arch_init_invariance_cppc();
>
>         kfree(output.pointer);
>         return 0;
> --
> 2.29.2.dirty
>


From cristian.marussi at arm.com  Wed Aug 25 10:50:13 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 25 Aug 2021 18:50:13 +0100
Subject: [PATCH v4 03/12] firmware: arm_scmi: Add support for atomic
 transports
In-Reply-To: <CA+-6iNzTN6UHVX4qRssrqv6YVKeg97+Lz1KDcEcw6saMC0tubw@mail.gmail.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-4-cristian.marussi@arm.com>
 <CA+-6iNzTN6UHVX4qRssrqv6YVKeg97+Lz1KDcEcw6saMC0tubw@mail.gmail.com>
Message-ID: <20210825175013.GG13160@e120937-lin>

On Wed, Aug 25, 2021 at 12:18:31PM -0400, Jim Quinlan wrote:
> Hi Christian,
> 

Hi Jim,

thanks for the review first of all.

> On Tue, Aug 24, 2021 at 10:00 AM Cristian Marussi
> <cristian.marussi at arm.com> wrote:
> >
> > An SCMI transport can declare itself as .atomic_capable in order to signal
> > to the SCMI core that all its transmit path can be executed in atomic
> > context: the core as a consequence will take care not to sleep to in the
> > corresponding rx path while waiting for a response or a delayed response.
> >
> > Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> > ---
> >  drivers/firmware/arm_scmi/common.h |   3 +
> >  drivers/firmware/arm_scmi/driver.c | 167 ++++++++++++++++++++++-------
> >  2 files changed, 132 insertions(+), 38 deletions(-)
> >
> > diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
> > index 67c761141a48..4ab310c2eae5 100644
> > --- a/drivers/firmware/arm_scmi/common.h
> > +++ b/drivers/firmware/arm_scmi/common.h
> > @@ -412,6 +412,8 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
> >   * @max_msg_size: Maximum size of data per message that can be handled.
> >   * @force_polling: Flag to force this whole transport to use SCMI core polling
> >   *                mechanism instead of completion interrupts even if available.
> > + * @atomic_capable: Flag to indicate that this transport is assured not to sleep
> > + *                 on the TX path.
> >   */
> >  struct scmi_desc {
> >         int (*transport_init)(void);
> > @@ -421,6 +423,7 @@ struct scmi_desc {
> >         int max_msg;
> >         int max_msg_size;
> >         bool force_polling;
> > +       bool atomic_capable;
> >  };
> >
> >  #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
> > diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> > index a3700f49e8ac..2ca1602afd80 100644
> > --- a/drivers/firmware/arm_scmi/driver.c
> > +++ b/drivers/firmware/arm_scmi/driver.c
> > @@ -681,6 +681,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
> >                 scmi_clear_channel(info, cinfo);
> >                 complete(xfer->async_done);
> >         } else {
> > +               /*
> > +                * This same xfer->done completion is used in atomic mode as a
> > +                * flag for polling.
> > +                */
> >                 complete(&xfer->done);
> >         }
> >
> > @@ -733,8 +737,6 @@ static void xfer_put(const struct scmi_protocol_handle *ph,
> >         __scmi_xfer_put(&info->tx_minfo, xfer);
> >  }
> >
> > -#define SCMI_MAX_POLL_TO_NS    (100 * NSEC_PER_USEC)
> > -
> >  static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
> >                                       struct scmi_xfer *xfer, ktime_t stop)
> >  {
> > @@ -749,6 +751,90 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
> >                ktime_after(ktime_get(), stop);
> >  }
> >
> > +static bool xfer_complete_or_timeout(struct completion *done, ktime_t stop)
> > +{
> > +       return try_wait_for_completion(done) || ktime_after(ktime_get(), stop);
> > +}
> > +
> > +static int spin_for_completion_timeout(struct completion *done, int timeout_ms)
> > +{
> > +       ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
> > +
> > +       spin_until_cond(xfer_complete_or_timeout(done, stop));
> > +       if (ktime_after(ktime_get(), stop))
> > +               return -ETIMEDOUT;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * scmi_wait_for_message_response  - An helper to group all the possible ways of
> > + * waiting for a synchronous message response.
> > + *
> > + * @cinfo: SCMI channel info
> > + * @xfer: Reference to the transfer being waited for.
> > + *
> > + * Chooses waiting strategy (sleep-waiting vs busy-waiting) depending on flags
> > + * configuration like xfer->hdr.poll_completion and scmi_desc.atomic.capable.
> > + *
> > + * Return: 0 on Success, error otherwise.
> > + */
> > +static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo,
> > +                                         struct scmi_xfer *xfer)
> > +{
> > +       struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
> > +       struct device *dev = info->dev;
> > +       int ret = 0, timeout_ms = info->desc->max_rx_timeout_ms;
> > +
> > +       if (!xfer->hdr.poll_completion) {
> > +               if (!info->desc->atomic_capable) {
> > +                       if (!wait_for_completion_timeout(&xfer->done,
> > +                                                        msecs_to_jiffies(timeout_ms))) {
> > +                               dev_err(dev, "timed out in resp(caller: %pS)\n",
> > +                                       (void *)_RET_IP_);
> > +                               ret = -ETIMEDOUT;
> > +                       }
> > +               } else {
> > +                       /* Poll on xfer->done waiting for completion by interrupt */
> > +                       ret = spin_for_completion_timeout(&xfer->done,
> > +                                                         timeout_ms);
> We use the SMC transport with a completion interrupt but would prefer
> for the above to use wait_for_completion(...) instead of  using
> spin_for_completion().  A few of our SCMI commands can take a while to
> complete execution so we do not want to be spinning or polling while
> waiting.

Busy-waiting when using a completion IRQ is used indeed only if the
transport has been declared .atomic_capable: the idea was that if
the specific transport does not sleep, the core can avoid sleeping too
and so enable users like the clock framework to switch to 'atomic' mode
and being called from atomic context.

So if you drop indeed the SMC patch later in the series that mmake it
atomic

[PATCH v4 10/12] [RFC] firmware: arm_scmi: Make smc transport atomic

you'll end up using the wait_for here when completion IRQ is used.
(instead to avoid any polling while in polling mode (O_o) the idea was
to use the new .sync_cmds_atomic_replies) 

BUT the problem is that some other partner could possibly want to use
instead this same transport in atomic mode, so maybe it could be worth
introducing some sort of configurability so that atomic operations are
enabled only if (say) .atomic_capable && .atomic_enable.

Maybe this could be done on a per-channel base, so you could dedicate a
channel to a protocol and ask only for it to be atomic_enable (if the
whole transport is atomic_capable); mixing atomic/non_atomic behaviour
inside the same protocol/channel across different messages seems a bit
of a hell (...and I think a previous attempt led to a lot of issues in
the past)

Anyway, not sure really where to put this possible configuration bit
though...this not being really a FW config/description seems likely to
be a NACK for a placement in the DT :D

> 
> We could probably go back to a mailbox-based transport and use delayed
> messages here for these "long" SCMI messages,  but we do not have full
> control over the platform FW (plus there are backwards compatibility
> issues).  FWIW, the platform FW was setup before SCMI on Linux
> implemented delayed/async  messages.
> 

Having a completion IRQ couldn't you use it to send delayed responses or
notification even in this smc transport ? (well it'd need FW to be
updated in fact and maybe I'm missing something here)

Thanks a lot for the feedback, may I assume this initial series it sort
of worked (beside noted limitations) in your SMC test setup :D ?

Thanks,
Cristian


From cristian.marussi at arm.com  Wed Aug 25 10:52:33 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 25 Aug 2021 18:52:33 +0100
Subject: [PATCH v4 05/12] firmware: arm_scmi: Use new trace event
 scmi_xfer_response_wait
In-Reply-To: <2ffa7d65-21ef-433b-8a86-068df13950d2@gmail.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-6-cristian.marussi@arm.com>
 <2ffa7d65-21ef-433b-8a86-068df13950d2@gmail.com>
Message-ID: <20210825175233.GH13160@e120937-lin>

On Wed, Aug 25, 2021 at 06:31:13PM +0200, Florian Fainelli wrote:
> 
> 
> On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> > Use new trace event to mark start of waiting for response section.
> > 
> > Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> 
Hi Florian,

Thanks for the review and the feedback across this series.

> Might be worth squashing into patch 4?
> 

Yes indeed I never know for sure when to squash when stuff crosses
subsystems/maintaners boundaries.

Thanks,
Cristian



From rafael at kernel.org  Wed Aug 25 10:54:26 2021
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Wed, 25 Aug 2021 19:54:26 +0200
Subject: [PATCH v2 2/3] arch_topology: obtain cpu capacity using
 information from CPPC
In-Reply-To: <20210824105651.28660-3-ionela.voinescu@arm.com>
References: <20210824105651.28660-1-ionela.voinescu@arm.com>
 <20210824105651.28660-3-ionela.voinescu@arm.com>
Message-ID: <CAJZ5v0hkgWQqOzfdv4kr6rxz9eMsOgHkMYj0cZpO7yC+=SnQfg@mail.gmail.com>

On Tue, Aug 24, 2021 at 12:57 PM Ionela Voinescu
<ionela.voinescu at arm.com> wrote:
>
> Define topology_init_cpu_capacity_cppc() to use highest performance
> values from _CPC objects to obtain and set maximum capacity information
> for each CPU. acpi_cppc_processor_probe() is a good point at which to
> trigger the initialization of CPU (u-arch) capacity values, as at this
> point the highest performance values can be obtained from each CPU's
> _CPC objects. Architectures can therefore use this functionality
> through arch_init_invariance_cppc().
>
> The performance scale used by CPPC is a unified scale for all CPUs in
> the system. Therefore, by obtaining the raw highest performance values
> from the _CPC objects, and normalizing them on the [0, 1024] capacity
> scale, used by the task scheduler, we obtain the CPU capacity of each
> CPU.
>
> While an ACPI Notify(0x85) could alert about a change in the highest
> performance value, which should in turn retrigger the CPU capacity
> computations, this notification is not currently handled by the ACPI
> processor driver. When supported, a call to arch_init_invariance_cppc()
> would perform the update.
>
> Signed-off-by: Ionela Voinescu <ionela.voinescu at arm.com>
> Tested-by: Valentin Schneider <valentin.schneider at arm.com>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> ---
>  drivers/base/arch_topology.c  | 37 +++++++++++++++++++++++++++++++++++
>  include/linux/arch_topology.h |  4 ++++
>  2 files changed, 41 insertions(+)
>
> diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
> index 921312a8d957..358e22cd629e 100644
> --- a/drivers/base/arch_topology.c
> +++ b/drivers/base/arch_topology.c
> @@ -306,6 +306,43 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
>         return !ret;
>  }
>
> +#ifdef CONFIG_ACPI_CPPC_LIB
> +#include <acpi/cppc_acpi.h>
> +
> +void topology_init_cpu_capacity_cppc(void)
> +{
> +       struct cppc_perf_caps perf_caps;
> +       int cpu;
> +
> +       if (likely(acpi_disabled || !acpi_cpc_valid()))
> +               return;
> +
> +       raw_capacity = kcalloc(num_possible_cpus(), sizeof(*raw_capacity),
> +                              GFP_KERNEL);
> +       if (!raw_capacity)
> +               return;
> +
> +       for_each_possible_cpu(cpu) {
> +               if (!cppc_get_perf_caps(cpu, &perf_caps)) {
> +                       raw_capacity[cpu] = perf_caps.highest_perf;

>From experience, I would advise doing some sanity checking on the
per_caps values before using them here.

Also note that highest_perf may not be sustainable, so would using
highest_perf as raw_capacity[] always work as expected?

> +                       pr_debug("cpu_capacity: CPU%d cpu_capacity=%u (raw).\n",
> +                                cpu, raw_capacity[cpu]);
> +               } else {
> +                       pr_err("cpu_capacity: CPU%d missing highest performance.\n", cpu);
> +                       pr_err("cpu_capacity: partial information: fallback to 1024 for all CPUs\n");
> +                       goto exit;
> +               }
> +       }
> +
> +       topology_normalize_cpu_scale();
> +       schedule_work(&update_topology_flags_work);
> +       pr_debug("cpu_capacity: cpu_capacity initialization done\n");
> +
> +exit:
> +       free_raw_capacity();
> +}
> +#endif
> +
>  #ifdef CONFIG_CPU_FREQ
>  static cpumask_var_t cpus_to_visit;
>  static void parsing_done_workfn(struct work_struct *work);
> diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h
> index f180240dc95f..9cf1a17938f0 100644
> --- a/include/linux/arch_topology.h
> +++ b/include/linux/arch_topology.h
> @@ -11,6 +11,10 @@
>  void topology_normalize_cpu_scale(void);
>  int topology_update_cpu_topology(void);
>
> +#ifdef CONFIG_ACPI_CPPC_LIB
> +void topology_init_cpu_capacity_cppc(void);
> +#endif
> +
>  struct device_node;
>  bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu);
>
> --
> 2.29.2.dirty
>


From robh at kernel.org  Wed Aug 25 10:59:37 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 12:59:37 -0500
Subject: [PATCH v3 1/8] dt-bindings: clock: samsung: convert Exynos5250
 to dtschema
In-Reply-To: <20210825134056.219884-2-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-2-krzysztof.kozlowski@canonical.com>
Message-ID: <YSaFCcsNGp9Ut5fS@robh.at.kernel.org>

On Wed, 25 Aug 2021 15:40:49 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos5250 clock controller bindings to DT schema format
> using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  .../bindings/clock/exynos5250-clock.txt       | 41 -----------------
>  .../bindings/clock/samsung,exynos-clock.yaml  | 46 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  3 files changed, 47 insertions(+), 41 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5250-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-clock.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Wed Aug 25 10:59:48 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 12:59:48 -0500
Subject: [PATCH v3 3/8] dt-bindings: clock: samsung: convert Exynos542x
 to dtschema
In-Reply-To: <20210825134056.219884-4-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-4-krzysztof.kozlowski@canonical.com>
Message-ID: <YSaFFEU2/7jTK1VQ@robh.at.kernel.org>

On Wed, 25 Aug 2021 15:40:51 +0200, Krzysztof Kozlowski wrote:
> Merge Exynos542x clock controller bindings to existing DT schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  .../bindings/clock/exynos5420-clock.txt       | 42 -------------------
>  .../bindings/clock/samsung,exynos-clock.yaml  |  9 +++-
>  2 files changed, 8 insertions(+), 43 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From catalin.marinas at arm.com  Wed Aug 25 10:59:53 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 25 Aug 2021 18:59:53 +0100
Subject: [PATCH v3 1/3] vmalloc: Choose a better start address in
 vm_area_register_early()
In-Reply-To: <20210809093750.131091-2-wangkefeng.wang@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <20210809093750.131091-2-wangkefeng.wang@huawei.com>
Message-ID: <20210825175953.GI3420@arm.com>

On Mon, Aug 09, 2021 at 05:37:48PM +0800, Kefeng Wang wrote:
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index d5cd52805149..1e8fe08725b8 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -2238,11 +2238,17 @@ void __init vm_area_add_early(struct vm_struct *vm)
>   */
>  void __init vm_area_register_early(struct vm_struct *vm, size_t align)
>  {
> -	static size_t vm_init_off __initdata;
> -	unsigned long addr;
> -
> -	addr = ALIGN(VMALLOC_START + vm_init_off, align);
> -	vm_init_off = PFN_ALIGN(addr + vm->size) - VMALLOC_START;
> +	struct vm_struct *head = vmlist, *curr, *next;
> +	unsigned long addr = ALIGN(VMALLOC_START, align);
> +
> +	while (head != NULL) {

Nitpick: I'd use the same pattern as in vm_area_add_early(), i.e. a
'for' loop. You might as well insert it directly than calling the add
function and going through the loop again. Not a strong preference
either way.

> +		next = head->next;
> +		curr = head;
> +		head = next;
> +		addr = ALIGN((unsigned long)curr->addr + curr->size, align);
> +		if (next && (unsigned long)next->addr - addr > vm->size)

Is greater or equal sufficient?

> +			break;
> +	}
>  
>  	vm->addr = (void *)addr;

Another nitpick: it's very unlikely on a 64-bit architecture but not
impossible on 32-bit to hit VMALLOC_END here. Maybe some BUG_ON.

-- 
Catalin


From robh at kernel.org  Wed Aug 25 11:00:15 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 13:00:15 -0500
Subject: [PATCH v3 5/8] dt-bindings: clock: samsung: convert Exynos4 to
 dtschema
In-Reply-To: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
Message-ID: <YSaFL6maujTOnSh3@robh.at.kernel.org>

On Wed, 25 Aug 2021 15:40:53 +0200, Krzysztof Kozlowski wrote:
> Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
> schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos4-clock.txt          | 86 -------------------
>  .../bindings/clock/samsung,exynos-clock.yaml  |  3 +
>  .../clock/samsung,exynos4412-isp-clock.yaml   | 64 ++++++++++++++
>  3 files changed, 67 insertions(+), 86 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Wed Aug 25 11:00:43 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 13:00:43 -0500
Subject: [PATCH v3 6/8] dt-bindings: clock: samsung: convert Exynos AudSS
 to dtschema
In-Reply-To: <20210825134251.220098-1-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
 <20210825134251.220098-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YSaFS7W9q798qqq2@robh.at.kernel.org>

On Wed, 25 Aug 2021 15:42:49 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
> schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  .../bindings/clock/clk-exynos-audss.txt       | 103 ------------------
>  .../clock/samsung,exynos-audss-clock.yaml     |  80 ++++++++++++++
>  2 files changed, 80 insertions(+), 103 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos-audss-clock.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Wed Aug 25 11:00:59 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 13:00:59 -0500
Subject: [PATCH v3 7/8] dt-bindings: clock: samsung: convert S5Pv210
 AudSS to dtschema
In-Reply-To: <20210825134251.220098-2-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
 <20210825134251.220098-2-krzysztof.kozlowski@canonical.com>
Message-ID: <YSaFW5s47ss/JE2M@robh.at.kernel.org>

On Wed, 25 Aug 2021 15:42:50 +0200, Krzysztof Kozlowski wrote:
> Convert Samsung S5Pv210 Audio SubSystem clock controller bindings to DT
> schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> 
> ---
> 
> Changes since v1:
> 1. Include header to fix clock IDs error in example.
> ---
>  .../bindings/clock/clk-s5pv210-audss.txt      | 53 -------------
>  .../clock/samsung,s5pv210-audss-clock.yaml    | 78 +++++++++++++++++++
>  2 files changed, 78 insertions(+), 53 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-audss-clock.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From catalin.marinas at arm.com  Wed Aug 25 11:08:33 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 25 Aug 2021 19:08:33 +0100
Subject: [PATCH v3 2/3] arm64: Support page mapping percpu first chunk
 allocator
In-Reply-To: <20210809093750.131091-3-wangkefeng.wang@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <20210809093750.131091-3-wangkefeng.wang@huawei.com>
Message-ID: <20210825180831.GJ3420@arm.com>

On Mon, Aug 09, 2021 at 05:37:49PM +0800, Kefeng Wang wrote:
> Percpu embedded first chunk allocator is the firstly option, but it
> could fails on ARM64, eg,
>   "percpu: max_distance=0x5fcfdc640000 too large for vmalloc space 0x781fefff0000"
>   "percpu: max_distance=0x600000540000 too large for vmalloc space 0x7dffb7ff0000"
>   "percpu: max_distance=0x5fff9adb0000 too large for vmalloc space 0x5dffb7ff0000"
> 
> then we could meet "WARNING: CPU: 15 PID: 461 at vmalloc.c:3087 pcpu_get_vm_areas+0x488/0x838",
> even the system could not boot successfully.
> 
> Let's implement page mapping percpu first chunk allocator as a fallback
> to the embedding allocator to increase the robustness of the system.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Wed Aug 25 11:11:13 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 25 Aug 2021 19:11:13 +0100
Subject: [PATCH v3 0/3] arm64: support page mapping percpu first chunk
 allocator
In-Reply-To: <9b75f4e5-a675-1227-0476-43fc21509086@huawei.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <9b75f4e5-a675-1227-0476-43fc21509086@huawei.com>
Message-ID: <20210825181112.GK3420@arm.com>

On Thu, Aug 12, 2021 at 02:07:36PM +0800, Kefeng Wang wrote:
> The drivers/base/arch_numa.c is only shared by riscv and arm64,
> 
> and the change from patch2 won't broke riscv.
> 
> Could all patches be merged by arm64 tree? or any new comments?

The series touches drivers/ and mm/ but missing acks from both Greg and
Andrew (cc'ing them).

I'm also happy for the series to go in via the mm tree in case Andrew
wants to take it.

-- 
Catalin


From oupton at google.com  Wed Aug 25 11:14:59 2021
From: oupton at google.com (Oliver Upton)
Date: Wed, 25 Aug 2021 11:14:59 -0700
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <20210825150713.5rpwzm4grfn7akcw@gator.home>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org> <20210825150713.5rpwzm4grfn7akcw@gator.home>
Message-ID: <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>

On Wed, Aug 25, 2021 at 8:07 AM Andrew Jones <drjones at redhat.com> wrote:
>
> On Wed, Aug 25, 2021 at 11:39:34AM +0100, Marc Zyngier wrote:
> > On Wed, 25 Aug 2021 11:02:28 +0100,
> > Oliver Upton <oupton at google.com> wrote:
> > >
> > > On Wed, Aug 25, 2021 at 2:27 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > > Exposing new hypercalls to guests in this manner seems very unsafe to
> > > > > me. Suppose an operator is trying to upgrade from kernel N to kernel
> > > > > N+1, which brings in the new 'widget' hypercall. Guests are live
> > > > > migrated onto the N+1 kernel, but the operator finds a defect that
> > > > > warrants a kernel rollback. VMs are then migrated from kernel N+1 -> N.
> > > > > Any guests that discovered the 'widget' hypercall are likely going to
> > > > > get fussy _very_ quickly on the old kernel.
> > > >
> > > > This goes against what we decided to support for the *only* publicly
> > > > available VMM that cares about save/restore, which is that we only
> > > > move forward and don't rollback.
> > >
> > > Ah, I was definitely missing this context. Current behavior makes much
> > > more sense then.
> > >
> > > > Hypercalls are the least of your
> > > > worries, and there is a whole range of other architectural features
> > > > that will have also appeared/disappeared (your own CNTPOFF series is a
> > > > glaring example of this).
> > >
> > > Isn't that a tad bit different though? I'll admit, I'm just as guilty
> > > with my own series forgetting to add a KVM_CAP (oops), but it is in my
> > > queue to kick out with the fix for nVHE/ptimer. Nonetheless, if a user
> > > takes up a new KVM UAPI, it is up to the user to run on a new kernel.
> >
> > The two are linked. Exposing a new register to userspace and/or guest
> > result in the same thing: you can't rollback. That's specially true in
> > the QEMU case, which *learns* from the kernel what registers are
> > available, and doesn't maintain a fixed list.
> >
> > > My concerns are explicitly with the 'under the nose' changes, where
> > > KVM modifies the guest feature set without userspace opting in. Based
> > > on your comment, though, it would appear that other parts of KVM are
> > > affected too.
> >
> > Any new system register that is exposed by a new kernel feature breaks
> > rollback. And so far, we only consider it a bug if the set of exposed
> > registers reduces. Anything can be added safely (as checked by one of
> > the selftests added by Drew).
> >
> > < It doesn't have to be rollback safety, either. There may
> > > simply be a hypercall which an operator doesn't want to give its
> > > guests, and it needs a way to tell KVM to hide it.
> >
> > Fair enough. But this has to be done in a scalable way, which
> > individual capability cannot provide.
> >
> > > > > Have I missed something blatantly obvious, or do others see this as an
> > > > > issue as well? I'll reply with an example of adding opt-out for PTP.
> > > > > I'm sure other hypercalls could be handled similarly.
> > > >
> > > > Why do we need this? For future hypercalls, we could have some buy-in
> > > > capabilities. For existing ones, it is too late, and negative features
> > > > are just too horrible.
> > >
> > > Oh, agreed on the nastiness. Lazy hack to realize the intended
> > > functional change..
> >
> > Well, you definitely achieved your goal of attracting my attention :).
> >
> > > > For KVM-specific hypercalls, we could get the VMM to save/restore the
> > > > bitmap of supported functions. That would be "less horrible". This
> > > > could be implemented using extra "firmware pseudo-registers" such as
> > > > the ones described in Documentation/virt/kvm/arm/psci.rst.
> > >
> > > This seems more reasonable, especially since we do this for migrating
> > > the guest's PSCI version.
> > >
> > > Alternatively, I had thought about using a VM attribute, given the
> > > fact that it is non-architectural information and we avoid ABI issues
> > > in KVM_GET_REG_LIST without buy-in through a KVM_CAP.
> >
> > The whole point is that these settings get exposed by
> > KVM_GET_REG_LIST, as this is QEMU's way to dump a VM state. Given that
> > we already have this for things like the spectre management state, we
> > can just as well expose the bitmaps that deal with the KVM-specific
> > hypercalls. After all, this falls into the realm of "KVM as VM
> > firmware".
> >
> > For ARM-architected hypercalls (TRNG, stolen time), we may need a
> > similar extension.
> >
>
> Thanks for including me Marc. I think you've mentioned all the examples
> of why we don't generally expect N+1 -> N migrations to work that I
> can think of. While some of the examples like get-reg-list could
> eventually be eliminated if we had CPU models to tighten our machine type
> state, I think N+1 -> N migrations will always be best effort at most.
>
> I agree with giving userspace control over the exposer of the hypercalls
> though. Using pseudo-registers for that purpose rather than a pile of
> CAPs also seems reasonable to me.
>
> And, while I don't think this patch is going to proceed, I thought I'd
> point out that the opt-out approach doesn't help much with expanding
> our migration support unless we require the VMM to be upgraded first.
>
> And, even then, the (N_kern, N+1_vmm) -> (N+1_kern, N_vmm) case won't
> work as expected, since the source enforce opt-out, but the destination
> won't.

Right, there's going to need to be a fence in both kernel and VMM
versions. Before the fence, you can't rollback with either component.
Once on the other side of the fence, the user may freely migrate
between kernel + VMM combinations.

> Also, since the VMM doesn't key off the kernel version, for the
> most part N+1 VMMs won't know when they're supposed to opt-out or not,
> leaving it to the user to ensure they consider everything. opt-in
> usually only needs the user to consider what machine type they want to
> launch.

Going the register route will implicitly require opt-out for all old
hypercalls. We exposed them unconditionally to the guest before, and
we must uphold that behavior. The default value for the bitmap will
have those features set. Any hypercalls added after that register
interface will then require explicit opt-in from userspace.

With regards to the pseudoregister interface, how would a VMM discover
new bits? From my perspective, you need to have two bitmaps that the
VMM can get at: the set of supported feature bits and the active
bitmap of features for a running guest.

> Thanks,
> drew
>


From cristian.marussi at arm.com  Wed Aug 25 11:49:15 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 25 Aug 2021 19:49:15 +0100
Subject: [PATCH v4 11/12] [RFC] firmware: arm_scmi: Add
 sync_cmds_atomic_replies transport flag
In-Reply-To: <CA+-6iNw-_VXcntU_UE8kTiPb8Sq28KkZG1__N7rE4ezo=VqQVQ@mail.gmail.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-12-cristian.marussi@arm.com>
 <7a2f972d-fdd0-d0f7-cac2-1989980ed872@gmail.com>
 <CA+-6iNw-_VXcntU_UE8kTiPb8Sq28KkZG1__N7rE4ezo=VqQVQ@mail.gmail.com>
Message-ID: <20210825184915.GI13160@e120937-lin>

On Wed, Aug 25, 2021 at 01:17:47PM -0400, Jim Quinlan wrote:
> On Wed, Aug 25, 2021 at 12:38 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
> >
> >
> >

Hi Florian and Jim,

> > On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> > > A flag is added to let the transport signal the core that its handling of
> > > synchronous command messages implies that, after .send_message has returned
> > > successfully, the requested command can be assumed to be fully and
> > > completely executed on SCMI platform side so that any possible response
> > > value is already immediately available to be retrieved by a .fetch_reponse:
> > > in other words the polling phase can be skipped in such a case and the
> > > response values accessed straight away.
> > >
> > > Note that all of the above applies only when polling mode of operation was
> > > selected by the core: if instead a completion IRQ was found to be available
> > > the normal response processing path based on completions will still be
> > > followed.
> >
> > This might actually have to be settable on a per-message basis ideally
> > since we may be transporting short lived SCMI messages for which the
> > completion can be done at SMC time, and long lived SCMI messages (e.g.:
> > involving a voltage change) for which we would prefer a completion
> > interrupt. Jim, what do you think?
> Even if the SCMI main driver could be configured this way in an
> elegant manner, I'm not sure that there is a clean way of specifying
> this  attribute on a per-message basis.  Certainly we could do this
> with our own protocols, but  many of our "long lived" messages are the
> Perf protocol's set_level command.  At any rate, let me give it some
> thought.
> 

The new flag .sync_cmds_atomic_replies applies only when polling mode
has been selected for a specific cmd transaction, which means when no
completion IRQ was found available OR if xfer.poll_completion was
excplicitly set for a specific command.

At the moment in this series (unknown bugs apart :D), if you have a
channel configured with a completion IRQ and the .sync_cmds_atomic_replies
set for the transport, this latter flag would be generally ignored and a
wait_for_completion() will be normally used upon reception of the
completionIRQ, UNLESS you specify that one specific command has to be
polled using the per message xfer.poll_completion flag: so you should be
already able to selectively use a polling which immediately returns after
the smc by setting xfer.poll_completion for that specific short lived
message (since sync_cmds_atomic_replies is set and applies to pollmode).
On the other side any other LONG lived message will be naturally handled
via completionIRQ + wait_for_completion. (at least that was the aim..)

!!! NOTE that you'll have also to drop

 [PATCH v4 10/12] [RFC] firmware: arm_scmi: Make smc transport atomic

from this series for the wait_completion to happen as you wish.

As said I'm not sure that this whole mixing of polling and IRQs on the
same channel on a regular won't cause any issues: any feedback on this
from your setup is much appreciated.
(maybe it's fine for SMC transport, but it led to a bit of hell in the
past with mboxes AFAIK...)

Thanks a lot again for your feedback, I'll have to chat with Sudeep
about the various issues/configs possibility that we discussed and I'll
keep you in the loop.

Thanks,
Cristian

P.S.: I'll be off for a few weeks, so even though I'll keep an eye on
the mail, I cannot guarantee any responsiveness :D


From mathieu.poirier at linaro.org  Wed Aug 25 12:09:34 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 25 Aug 2021 13:09:34 -0600
Subject: [PATCHv2 2/4] coresight: tmc-etr: Track perf handler.
In-Reply-To: <20210825170213.GA763112@p14s>
References: <20210713121532.836244-1-daniel.kiss@arm.com>
 <20210713121532.836244-3-daniel.kiss@arm.com>
 <20210825170213.GA763112@p14s>
Message-ID: <20210825190934.GB763112@p14s>

On Wed, Aug 25, 2021 at 11:02:13AM -0600, Mathieu Poirier wrote:
> Hi Daniel,
> 
> On Tue, Jul 13, 2021 at 02:15:30PM +0200, Daniel Kiss wrote:
> > Keep track of the perf handler that is registred by the first tracer.
> > This will be used by the update call from polling.
> > 
> > Signed-off-by: Daniel Kiss <daniel.kiss at arm.com>
> > Signed-off-by: Branislav Rankov <Branislav.Rankov at arm.com>
> > ---
> >  drivers/hwtracing/coresight/coresight-tmc-etr.c | 6 ++++--
> >  drivers/hwtracing/coresight/coresight-tmc.h     | 2 ++
> >  2 files changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > index 589bb2d56e802..55c9b5fd9f832 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > @@ -1503,8 +1503,8 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
> >  
> >  	spin_lock_irqsave(&drvdata->spinlock, flags);
> >  
> > -	/* Don't do anything if another tracer is using this sink */
> > -	if (atomic_read(csdev->refcnt) != 1) {
> > +	/* Serve only the tracer with the leading perf handler */
> > +	if (drvdata->perf_handle != handle) {
> 
> In CPU wide trace scenarios the first CPU to enable a sink is not
> guaranteed to be the same as the last CPU to use it.  As far as I understand the
> above assumes the first and last CPUs to use a sink are the same.

I want to take a little more time to ponder about the rest of this patchset.
More comments to come tomorrow.

Thanks,
Mathieu

> 
> >  		spin_unlock_irqrestore(&drvdata->spinlock, flags);
> >  		goto out;
> >  	}
> > @@ -1619,6 +1619,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
> >  		drvdata->pid = pid;
> >  		drvdata->mode = CS_MODE_PERF;
> >  		drvdata->perf_buf = etr_perf->etr_buf;
> > +		drvdata->perf_handle = handle;
> >  		atomic_inc(csdev->refcnt);
> >  	}
> >  
> > @@ -1666,6 +1667,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
> >  	drvdata->mode = CS_MODE_DISABLED;
> >  	/* Reset perf specific data */
> >  	drvdata->perf_buf = NULL;
> > +	drvdata->perf_handle = NULL;
> >  
> >  	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> >  
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> > index b91ec7dde7bc9..81583ffb973dc 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc.h
> > +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> > @@ -184,6 +184,7 @@ struct etr_buf {
> >   * @idr_mutex:	Access serialisation for idr.
> >   * @sysfs_buf:	SYSFS buffer for ETR.
> >   * @perf_buf:	PERF buffer for ETR.
> > + * @perf_handle: PERF handle for ETR.
> >   */
> >  struct tmc_drvdata {
> >  	void __iomem		*base;
> > @@ -207,6 +208,7 @@ struct tmc_drvdata {
> >  	struct mutex		idr_mutex;
> >  	struct etr_buf		*sysfs_buf;
> >  	struct etr_buf		*perf_buf;
> > +	struct perf_output_handle *perf_handle;
> >  };
> >  
> >  struct etr_buf_operations {
> > -- 
> > 2.25.1
> > 


From robh at kernel.org  Wed Aug 25 12:59:19 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 25 Aug 2021 14:59:19 -0500
Subject: [PATCH v9 2/3] arm64: perf: Enable PMU counter userspace access
 for perf event
In-Reply-To: <CAL_Jsq+HY8o=DPf0Yhbjhu1=_yBwoV7rBL7gK2MJCpezwi7vwQ@mail.gmail.com>
References: <20210806225123.1958497-1-robh@kernel.org>
 <20210806225123.1958497-3-robh@kernel.org>
 <20210824152720.GC23146@willie-the-truck>
 <CAL_Jsq+HY8o=DPf0Yhbjhu1=_yBwoV7rBL7gK2MJCpezwi7vwQ@mail.gmail.com>
Message-ID: <CAL_JsqLpGpLv+NFfLkLG6A3-oYf-ERxyG0j3cxr44MxKMryf_A@mail.gmail.com>

On Tue, Aug 24, 2021 at 4:58 PM Rob Herring <robh at kernel.org> wrote:
>
> On Tue, Aug 24, 2021 at 10:27 AM Will Deacon <will at kernel.org> wrote:
> >
> > On Fri, Aug 06, 2021 at 04:51:22PM -0600, Rob Herring wrote:
> > > Arm PMUs can support direct userspace access of counters which allows for
> > > low overhead (i.e. no syscall) self-monitoring of tasks. The same feature
> > > exists on x86 called 'rdpmc'. Unlike x86, userspace access will only be
> > > enabled for thread bound events. This could be extended if needed, but
> > > simplifies the implementation and reduces the chances for any
> > > information leaks (which the x86 implementation suffers from).
> > >
> > > When an event is capable of userspace access and has been mmapped, userspace
> > > access is enabled when the event is scheduled on a CPU's PMU. There's some
> > > additional overhead clearing counters when disabled in order to prevent
> > > leaking disabled counter data from other tasks.
> > >
> > > Unlike x86, enabling of userspace access must be requested with a new
> > > attr bit: config1:1. If the user requests userspace access and 64-bit
> > > counters, then chaining will be disabled and the user will get the
> > > maximum size counter the underlying h/w can support. The modes for
> > > config1 are as follows:
> > >
> > > config1 = 0 : user access disabled and always 32-bit
> > > config1 = 1 : user access disabled and always 64-bit (using chaining if needed)
> > > config1 = 2 : user access enabled and always 32-bit
> > > config1 = 3 : user access enabled and counter size matches underlying counter.
> > >
> > > Based on work by Raphael Gault <raphael.gault at arm.com>, but has been
> > > completely re-written.
> > >
> > > Cc: Will Deacon <will at kernel.org>
> > > Cc: Mark Rutland <mark.rutland at arm.com>
> > > Cc: Peter Zijlstra <peterz at infradead.org>
> > > Cc: Ingo Molnar <mingo at redhat.com>
> > > Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> > > Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
> > > Cc: Jiri Olsa <jolsa at redhat.com>
> > > Cc: Namhyung Kim <namhyung at kernel.org>
> > > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > > Cc: linux-arm-kernel at lists.infradead.org
> > > Cc: linux-perf-users at vger.kernel.org
> > > Signed-off-by: Rob Herring <robh at kernel.org>
> > >
> > > ---
> > > v9:
> > >  - Enabling/disabling of user access is now controlled in .start() and
> > >    mmap hooks which are now called on CPUs that the event is on.
> > >    Depends on rework of perf core and x86 RDPMC code posted here:
> > >    https://lore.kernel.org/lkml/20210728230230.1911468-1-robh at kernel.org/
> > >
> > > v8:
> > >  - Rework user access tracking and enabling to be done on task
> > >    context changes using sched_task() hook. This avoids the need for any
> > >    IPIs, mm_switch hooks or undef instr handler.
> > >  - Only support user access when explicitly requested on open and
> > >    only for a thread bound events. This avoids some of the information
> > >    leaks x86 has and simplifies the implementation.
> > >
> > > v7:
> > >  - Clear disabled counters when user access is enabled for a task to
> > >    avoid leaking other tasks counter data.
> > >  - Rework context switch handling utilizing sched_task callback
> > >  - Add armv8pmu_event_can_chain() helper
> > >  - Rework config1 flags handling structure
> > >  - Use ARMV8_IDX_CYCLE_COUNTER_USER define for remapped user cycle
> > >    counter index
> > >
> > > v6:
> > >  - Add new attr.config1 rdpmc bit for userspace to hint it wants
> > >    userspace access when also requesting 64-bit counters.
> > >
> > > v5:
> > >  - Only set cap_user_rdpmc if event is on current cpu
> > >  - Limit enabling/disabling access to CPUs associated with the PMU
> > >    (supported_cpus) and with the mm_struct matching current->active_mm.
> > >
> > > v2:
> > >  - Move mapped/unmapped into arm64 code. Fixes arm32.
> > >  - Rebase on cap_user_time_short changes
> > >
> > > Changes from Raphael's v4:
> > >   - Drop homogeneous check
> > >   - Disable access for chained counters
> > >   - Set pmc_width in user page
> > > ---
> > >  arch/arm64/kernel/perf_event.c | 137 +++++++++++++++++++++++++++++++--
> > >  include/linux/perf/arm_pmu.h   |   6 ++
> > >  2 files changed, 135 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > > index 74f77b68f5f0..66d8bf62e99c 100644
> > > --- a/arch/arm64/kernel/perf_event.c
> > > +++ b/arch/arm64/kernel/perf_event.c
> > > @@ -285,6 +285,7 @@ static const struct attribute_group armv8_pmuv3_events_attr_group = {
> > >
> > >  PMU_FORMAT_ATTR(event, "config:0-15");
> > >  PMU_FORMAT_ATTR(long, "config1:0");
> > > +PMU_FORMAT_ATTR(rdpmc, "config1:1");
> > >
> > >  static int sysctl_perf_user_access __read_mostly;
> > >
> > > @@ -306,9 +307,15 @@ static inline bool armv8pmu_event_is_64bit(struct perf_event *event)
> > >       return event->attr.config1 & 0x1;
> > >  }
> > >
> > > +static inline bool armv8pmu_event_want_user_access(struct perf_event *event)
> > > +{
> > > +     return event->attr.config1 & 0x2;
> > > +}
> > > +
> > >  static struct attribute *armv8_pmuv3_format_attrs[] = {
> > >       &format_attr_event.attr,
> > >       &format_attr_long.attr,
> > > +     &format_attr_rdpmc.attr,
> > >       NULL,
> > >  };
> > >
> > > @@ -377,7 +384,7 @@ static const struct attribute_group armv8_pmuv3_caps_attr_group = {
> > >   */
> > >  #define      ARMV8_IDX_CYCLE_COUNTER 0
> > >  #define      ARMV8_IDX_COUNTER0      1
> > > -
> > > +#define      ARMV8_IDX_CYCLE_COUNTER_USER    32
> > >
> > >  /*
> > >   * We unconditionally enable ARMv8.5-PMU long event counter support
> > > @@ -389,6 +396,15 @@ static bool armv8pmu_has_long_event(struct arm_pmu *cpu_pmu)
> > >       return (cpu_pmu->pmuver >= ID_AA64DFR0_PMUVER_8_5);
> > >  }
> > >
> > > +static inline bool armv8pmu_event_can_chain(struct perf_event *event)
> > > +{
> > > +     struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
> > > +
> > > +     return !(event->hw.flags & PERF_EVENT_FLAG_USER_READ_CNT) &&
> > > +            armv8pmu_event_is_64bit(event) &&
> > > +            !armv8pmu_has_long_event(cpu_pmu);
> >
> > Could check against ARMV8_IDX_CYCLE_COUNTER here...
> >
> > > +}
> > > +
> > >  /*
> > >   * We must chain two programmable counters for 64 bit events,
> > >   * except when we have allocated the 64bit cycle counter (for CPU
> > > @@ -398,11 +414,9 @@ static bool armv8pmu_has_long_event(struct arm_pmu *cpu_pmu)
> > >  static inline bool armv8pmu_event_is_chained(struct perf_event *event)
> > >  {
> > >       int idx = event->hw.idx;
> > > -     struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
> > >
> > >       return !WARN_ON(idx < 0) &&
> > > -            armv8pmu_event_is_64bit(event) &&
> > > -            !armv8pmu_has_long_event(cpu_pmu) &&
> > > +            armv8pmu_event_can_chain(event) &&
> > >              (idx != ARMV8_IDX_CYCLE_COUNTER);
> >
> > ... then we wouldn't need to here.
>
> Hum, well armv8pmu_event_can_chain() is supposed to answer is there
> any possibility that the event will ever be chained regardless of
> whether it's assigned or not. Changing it would mostly work for idx<0,
> but it could return the wrong answer if idx ==
> ARMV8_IDX_CYCLE_COUNTER. However, that won't happen in the current
> code (just as the WARN_ON won't). If we're going to smear the meaning,
> then we only need one function here if we get rid of the WARN_ON. We
> can call it armv8pmu_event_is_chained_or_might_be_chained() to make it
> clear... JK (on the name)
>
> >
> > >  }
> > >
> > > @@ -733,6 +747,35 @@ static inline u32 armv8pmu_getreset_flags(void)
> > >       return value;
> > >  }
> > >
> > > +static void armv8pmu_disable_user_access(void)
> > > +{
> > > +     write_sysreg(0, pmuserenr_el0);
> > > +}
> > > +
> > > +static void armv8pmu_enable_user_access(struct arm_pmu *cpu_pmu)
> > > +{
> > > +     struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
> > > +
> > > +     if (!sysctl_perf_user_access)
> > > +             return;
> > > +
> > > +     if (!bitmap_empty(cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS)) {
> > > +             int i;
> > > +             /* Don't need to clear assigned counters. */
> > > +             bitmap_xor(cpuc->dirty_mask, cpuc->dirty_mask, cpuc->used_mask, ARMPMU_MAX_HWEVENTS);
> > > +
> > > +             for_each_set_bit(i, cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS) {
> > > +                     if (i == ARMV8_IDX_CYCLE_COUNTER)
> > > +                             write_sysreg(0, pmccntr_el0);
> > > +                     else
> > > +                             armv8pmu_write_evcntr(i, 0);
> > > +             }
> >
> > Given that we can't expose individual counters, why isn't this just:
> >
> >         for_each_clear_bit(i, cpuc->used_mask, ARMPMU_MAX_HWEVENTS)
> >                 ...
> >
> > and we could get rid of the dirty_mask altogether? i.e. just zero everything
> > that isn't assigned.
>
> Sure. It's just an optimization following what x86 did.
>
> Though we'd want to limit it to num_events, not ARMPMU_MAX_HWEVENTS.
> No point in clearing nonexistent counters.
>
> >
> > > +             bitmap_zero(cpuc->dirty_mask, ARMPMU_MAX_HWEVENTS);
> > > +     }
> > > +
> > > +     write_sysreg(ARMV8_PMU_USERENR_ER | ARMV8_PMU_USERENR_CR, pmuserenr_el0);
> > > +}
> > > +
> > >  static void armv8pmu_enable_event(struct perf_event *event)
> > >  {
> > >       /*
> > > @@ -776,6 +819,16 @@ static void armv8pmu_disable_event(struct perf_event *event)
> > >
> > >  static void armv8pmu_start(struct arm_pmu *cpu_pmu)
> > >  {
> > > +     if (sysctl_perf_user_access) {
> >
> > armv8pmu_enable_user_access() already checks this.
>
> Yes, because not all callers (event_mapped) check it. I put it here so
> we check it first and avoid checking all the subsequent conditions
> when the feature is disabled. Though I guess the ordering here is not
> guaranteed.

It also serves to avoid writing pmuserenr_el0 when user access is
disabled. However, there is a problem here when the sysctl is changed
from enabled to disabled. We stop touching pmuserenr_el0, so it may
get left enabled. So either we need an IPI in the sysctl to disable
access everywhere (like x86) or we need to do something like this:

struct perf_cpu_context *cpuctx = this_cpu_ptr(cpu_pmu->pmu.pmu_cpu_context);
struct perf_event_context *task_ctx = cpuctx->task_ctx;
if (sysctl_perf_user_access && task_ctx && atomic_read(&task_ctx->nr_user))
        armv8pmu_enable_user_access(cpu_pmu);
else
        armv8pmu_disable_user_access();

I guess a third option is make the sysctl sticky. Once it gets
enabled, it stays enabled.

Rob


From pali at kernel.org  Wed Aug 25 12:59:53 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Wed, 25 Aug 2021 21:59:53 +0200
Subject: [RESEND PATCH 5/5] PCI: aardvark: Implement workaround for PCIe
 Completion Timeout
In-Reply-To: <20210624222621.4776-6-pali@kernel.org>
References: <20210624222621.4776-1-pali@kernel.org>
 <20210624222621.4776-6-pali@kernel.org>
Message-ID: <20210825195953.7ylfnplurhfixabg@pali>

On Friday 25 June 2021 00:26:21 Pali Roh?r wrote:
> Marvell Armada 3700 Functional Errata, Guidelines, and Restrictions
> document describes in erratum 3.12 PCIe Completion Timeout (Ref #: 251),
> that PCIe IP does not support a strong-ordered model for inbound posted vs.
> outbound completion.
> 
> As a workaround for this erratum, DIS_ORD_CHK flag in Debug Mux Control
> register must be set. It disables the ordering check in the core between
> Completions and Posted requests received from the link.
> 
> It was reported that enabling this workaround fixes instability issues and
> "Unhandled fault" errors when using 60 GHz WiFi 802.11ad card with Qualcomm
> QCA6335 chip under significant load which were caused by interrupt status
> stuck in the outbound CMPLT queue traced back to this erratum.
> 
> This workaround fixes also kernel panic triggered after some minutes of
> usage 5 GHz WiFi 802.11ax card with Mediatek MT7915 chip:
> 
>     Internal error: synchronous external abort: 96000210 [#1] SMP
>     Kernel panic - not syncing: Fatal exception in interrupt
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Cc: stable at vger.kernel.org
> ---
> Patch was originally written by Thomas and is already for a long time part
> of Marvell SDK. I have just re-written/re-applied it on top of mainline
> kernel and also wrote a new updated commit message.
> 
> Please note that this patch is questionable as Bjorn has some objections
> and nobody, including Marvell, was not able to explain erratum nor what
> is workaround exactly doing. Documentation about this topic is basically
> missing.

See also https://lore.kernel.org/linux-pci/20210723221710.wtztsrddudnxeoj3 at pali/

> We just know that it fixes real kernel crashes when using WiFi cards.
> ---
>  drivers/pci/controller/pci-aardvark.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
> index 9ff68abd8d1e..231f4469d87e 100644
> --- a/drivers/pci/controller/pci-aardvark.c
> +++ b/drivers/pci/controller/pci-aardvark.c
> @@ -167,6 +167,8 @@
>  #define     LTSSM_L0				0x10
>  #define     RC_BAR_CONFIG			0x300
>  #define VENDOR_ID_REG				(LMI_BASE_ADDR + 0x44)
> +#define DEBUG_MUX_CTRL_REG			(LMI_BASE_ADDR + 0x208)
> +#define     DIS_ORD_CHK				BIT(30)
>  
>  /* PCIe core controller registers */
>  #define CTRL_CORE_BASE_ADDR			0x18000
> @@ -450,6 +452,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
>  		PCIE_CORE_CTRL2_TD_ENABLE;
>  	advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
>  
> +	/* Disable ordering checks, workaround for erratum 3.12 "PCIe completion timeout" */
> +	reg = advk_readl(pcie, DEBUG_MUX_CTRL_REG);
> +	reg |= DIS_ORD_CHK;
> +	advk_writel(pcie, reg, DEBUG_MUX_CTRL_REG);
> +
>  	/* Set lane X1 */
>  	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
>  	reg &= ~LANE_CNT_MSK;
> -- 
> 2.20.1
> 


From skhan at linuxfoundation.org  Wed Aug 25 13:04:13 2021
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Wed, 25 Aug 2021 14:04:13 -0600
Subject: [PATCH linux-next] tools:signal: fix boolreturn.cocci warnings
In-Reply-To: <16561a4f-6043-cc5b-7a50-5be1ff10bfa5@linuxfoundation.org>
References: <20210824065131.60346-1-deng.changcheng@zte.com.cn>
 <16561a4f-6043-cc5b-7a50-5be1ff10bfa5@linuxfoundation.org>
Message-ID: <de79e084-705e-c23d-08cc-c102af6b2dae@linuxfoundation.org>

On 8/24/21 8:39 AM, Shuah Khan wrote:
> On 8/24/21 12:51 AM, CGEL wrote:
>> From: Jing Yangyang <jing.yangyang at zte.com.cn>
>>
>> ./tools/testing/selftests/arm64/signal/test_signals_utils.h:112:9-10
>> WARNING: return of 0/1 in function 'get_current_context' with
>> return type bool
>>
>> Return statements in functions returning bool should use true/false
>> instead of 1/0.
>>
>> Generated by: scripts/coccinelle/misc/boolreturn.cocci
>>
>> Reported-by: Zeal Robot <zealci at zte.com.cn>
>> Signed-off-by: Jing Yangyang <jing.yangyang at zte.com.cn>
>> ---
>> ? tools/testing/selftests/arm64/signal/test_signals_utils.h | 2 +-
>> ? 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
>> index 6772b5c..66122e6 100644
>> --- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
>> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
>> @@ -109,7 +109,7 @@ static __always_inline bool get_current_context(struct tdescr *td,
>> ????? if (seen_already) {
>> ????????? fprintf(stdout,
>> ????????????? "Unexpected successful sigreturn detected: live_uc is stale !\n");
>> -??????? return 0;
>> +??????? return false;

The change is fine. However, the function doc references to return 1/0
needs updates as well.

  * 1. grab a valid sigcontext into td->live_uc for result analysis: in
  * such case it returns 1.
  *
  * 2. detect if, somehow, a previously grabbed live_uc context has been
  * used actively with a sigreturn: in such a case the execution would have
  * magically resumed in the middle of this function itself (seen_already==1):
  * in such a case return 0, since in fact we have not just simply grabbed
  * the context.

thanks,
-- Shuah


From lkp at intel.com  Wed Aug 25 13:27:44 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 26 Aug 2021 04:27:44 +0800
Subject: [xlnx:master 11230/12418] drivers/remoteproc/imx_rproc.c:247:20:
 error: incompatible function pointer types initializing 'void *(*)(struct
 rproc *, u64, int)' (aka 'void *(*)(struct rproc *, unsigned long long,
 int)') with an expression of type 'void *(struct rproc *, u64, size_t)...
Message-ID: <202108260436.6FDw9PCr-lkp@intel.com>

Hi Wendy,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx master
head:   45cd0074cdf1ddd710b28848e6a860b442babfcc
commit: a324889a971b8e827c53deaffe630b420bde4067 [11230/12418] remoteproc: Add support for peek from remote and acking kick from remote
config: arm64-buildonly-randconfig-r005-20210825 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/a324889a971b8e827c53deaffe630b420bde4067
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx master
        git checkout a324889a971b8e827c53deaffe630b420bde4067
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/remoteproc/imx_rproc.c:247:20: error: incompatible function pointer types initializing 'void *(*)(struct rproc *, u64, int)' (aka 'void *(*)(struct rproc *, unsigned long long, int)') with an expression of type 'void *(struct rproc *, u64, size_t)' (aka 'void *(struct rproc *, unsigned long long, unsigned long)') [-Werror,-Wincompatible-function-pointer-types]
           .da_to_va       = imx_rproc_da_to_va,
                             ^~~~~~~~~~~~~~~~~~
   1 error generated.


vim +247 drivers/remoteproc/imx_rproc.c

a0ff4aa6f01080 Oleksij Rempel 2017-08-17  243  
a0ff4aa6f01080 Oleksij Rempel 2017-08-17  244  static const struct rproc_ops imx_rproc_ops = {
a0ff4aa6f01080 Oleksij Rempel 2017-08-17  245  	.start		= imx_rproc_start,
a0ff4aa6f01080 Oleksij Rempel 2017-08-17  246  	.stop		= imx_rproc_stop,
a0ff4aa6f01080 Oleksij Rempel 2017-08-17 @247  	.da_to_va       = imx_rproc_da_to_va,
a0ff4aa6f01080 Oleksij Rempel 2017-08-17  248  };
a0ff4aa6f01080 Oleksij Rempel 2017-08-17  249  

:::::: The code at line 247 was first introduced by commit
:::::: a0ff4aa6f010801b2a61c203c6e09d01b110fddf remoteproc: imx_rproc: add a NXP/Freescale imx_rproc driver

:::::: TO: Oleksij Rempel <o.rempel at pengutronix.de>
:::::: CC: Bjorn Andersson <bjorn.andersson at linaro.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 35414 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210826/76eac2a5/attachment-0001.gz>

From wsa at kernel.org  Wed Aug 25 14:00:59 2021
From: wsa at kernel.org (Wolfram Sang)
Date: Wed, 25 Aug 2021 23:00:59 +0200
Subject: [PATCH v2 2/5] i2c: mt65xx: fix IRQ check
In-Reply-To: <bab29007-8d74-0a68-2378-9db6ba0bc576@omp.ru>
References: <3712e871-bf2f-32c5-f9c2-2968c42087f8@omp.ru>
 <bab29007-8d74-0a68-2378-9db6ba0bc576@omp.ru>
Message-ID: <YSavi8ZKhi/a0TR9@kunai>

On Sun, Jul 04, 2021 at 05:38:45PM +0300, Sergey Shtylyov wrote:
> Iff platform_get_irq() returns 0, the driver's probe() method will return 0
> early (as if the method's call was successful).  Let's consider IRQ0 valid
> for simplicity -- devm_request_irq() can always override that decision...
> 
> Fixes: ce38815d39ea ("I2C: mediatek: Add driver for MediaTek I2C controller")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omprussia.ru>
> 

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210825/1297df38/attachment.sig>

From jiancai at google.com  Wed Aug 25 15:20:51 2021
From: jiancai at google.com (Jian Cai)
Date: Wed, 25 Aug 2021 15:20:51 -0700
Subject: [PATCH] coresight: syscfg: Add initial configfs support
Message-ID: <20210825222051.2106481-1-jiancai@google.com>

This fixes build failures with -Wimplicit-function-declaration, e.g.

^[[1m/mnt/host/source/src/third_party/kernel/v5.4/drivers/hwtracing/coresight/coresight-syscfg.c:455:15: ^[[0m^[[0;1;31merror: ^[[0m^[[1mimplicit declaration of function 'kzalloc' [-Werror,-Wimplicit-function-declaration]^[[0m
        csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
^[[0;1;32m                     ^

Signed-off-by: Jian Cai <jiancai at google.com>
---
 drivers/hwtracing/coresight/coresight-syscfg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index fc0760f55c53..43054568430f 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "coresight-config.h"
 #include "coresight-etm-perf.h"
-- 
2.33.0.259.gc128427fd7-goog



From jiancai at google.com  Wed Aug 25 15:25:14 2021
From: jiancai at google.com (Jian Cai)
Date: Wed, 25 Aug 2021 15:25:14 -0700
Subject: [PATCH] coresight: syscfg: fix compiler warnings
Message-ID: <20210825222514.2107728-1-jiancai@google.com>

This fixes warnings with -Wimplicit-function-declaration, e.g.

^[[1m/mnt/host/source/src/third_party/kernel/v5.4/drivers/hwtracing/coresight/coresight-syscfg.c:455:15: ^[[0m^[[0;1;31merror: ^[[0m^[[1mimplicit declaration of function 'kzalloc' [-Werror,-Wimplicit-function-declaration]^[[0m
        csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
^[[0;1;32m                     ^

Signed-off-by: Jian Cai <jiancai at google.com>
---
 drivers/hwtracing/coresight/coresight-syscfg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index fc0760f55c53..43054568430f 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "coresight-config.h"
 #include "coresight-etm-perf.h"
-- 
2.33.0.259.gc128427fd7-goog



From jiancai at google.com  Wed Aug 25 15:32:27 2021
From: jiancai at google.com (Jian Cai)
Date: Wed, 25 Aug 2021 15:32:27 -0700
Subject: [PATCH] coresight: syscfg: Add initial configfs support
In-Reply-To: <20210825222051.2106481-1-jiancai@google.com>
References: <20210825222051.2106481-1-jiancai@google.com>
Message-ID: <CA+SOCLLxWxwpMO_JP2p2FfNRdrH-82mR8ZcDGmPAkRnqxeYZPg@mail.gmail.com>

Please ignore this patch. The title is incorrect, I've updated and
resented it at https://lore.kernel.org/lkml/20210825222514.2107728-1-jiancai at google.com/.
Sorry for any inconveniences.

Jian



On Wed, Aug 25, 2021 at 3:20 PM Jian Cai <jiancai at google.com> wrote:
>
> This fixes build failures with -Wimplicit-function-declaration, e.g.
>
> ^[[1m/mnt/host/source/src/third_party/kernel/v5.4/drivers/hwtracing/coresight/coresight-syscfg.c:455:15: ^[[0m^[[0;1;31merror: ^[[0m^[[1mimplicit declaration of function 'kzalloc' [-Werror,-Wimplicit-function-declaration]^[[0m
>         csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
> ^[[0;1;32m                     ^
>
> Signed-off-by: Jian Cai <jiancai at google.com>
> ---
>  drivers/hwtracing/coresight/coresight-syscfg.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> index fc0760f55c53..43054568430f 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> @@ -5,6 +5,7 @@
>   */
>
>  #include <linux/platform_device.h>
> +#include <linux/slab.h>
>
>  #include "coresight-config.h"
>  #include "coresight-etm-perf.h"
> --
> 2.33.0.259.gc128427fd7-goog
>


From jiancai at google.com  Wed Aug 25 15:33:06 2021
From: jiancai at google.com (Jian Cai)
Date: Wed, 25 Aug 2021 15:33:06 -0700
Subject: [PATCH] coresight: syscfg: fix compiler warnings
In-Reply-To: <CA+SOCLLyKaEmCSrSNUKfpgPmUxcu8RyZLqZxpmw87BiO=m84Mg@mail.gmail.com>
References: <20210825222514.2107728-1-jiancai@google.com>
 <CA+SOCLLyKaEmCSrSNUKfpgPmUxcu8RyZLqZxpmw87BiO=m84Mg@mail.gmail.com>
Message-ID: <CA+SOCLKS=C6rNHXbbro+qHE2P-_M+nGg9kCdAuZPuZq0-VMLMQ@mail.gmail.com>

The last message was meant for the wrong patch. Please ignore. Sorry
for the noise.

On Wed, Aug 25, 2021 at 3:27 PM Jian Cai <jiancai at google.com> wrote:
>
> Please ignore this patch. The title is incorrect, I've updated and resented it at https://lore.kernel.org/lkml/20210825222514.2107728-1-jiancai at google.com/. Sorry for any inconvenience.
>
> On Wed, Aug 25, 2021 at 3:25 PM Jian Cai <jiancai at google.com> wrote:
>>
>> This fixes warnings with -Wimplicit-function-declaration, e.g.
>>
>> ^[[1m/mnt/host/source/src/third_party/kernel/v5.4/drivers/hwtracing/coresight/coresight-syscfg.c:455:15: ^[[0m^[[0;1;31merror: ^[[0m^[[1mimplicit declaration of function 'kzalloc' [-Werror,-Wimplicit-function-declaration]^[[0m
>>         csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
>> ^[[0;1;32m                     ^
>>
>> Signed-off-by: Jian Cai <jiancai at google.com>
>> ---
>>  drivers/hwtracing/coresight/coresight-syscfg.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
>> index fc0760f55c53..43054568430f 100644
>> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
>> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
>> @@ -5,6 +5,7 @@
>>   */
>>
>>  #include <linux/platform_device.h>
>> +#include <linux/slab.h>
>>
>>  #include "coresight-config.h"
>>  #include "coresight-etm-perf.h"
>> --
>> 2.33.0.259.gc128427fd7-goog
>>


From dan.j.williams at intel.com  Wed Aug 25 15:58:53 2021
From: dan.j.williams at intel.com (Dan Williams)
Date: Wed, 25 Aug 2021 15:58:53 -0700
Subject: [PATCH v2 06/15] peci: Add core infrastructure
In-Reply-To: <20210803113134.2262882-7-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-7-iwona.winiarska@intel.com>
Message-ID: <CAPcyv4giVBjZWjXO2H+vYSR29Vapi6_FvMwO7nvts-JXmCHcOA@mail.gmail.com>

On Tue, Aug 3, 2021 at 4:35 AM Iwona Winiarska
<iwona.winiarska at intel.com> wrote:
>
> Intel processors provide access for various services designed to support
> processor and DRAM thermal management, platform manageability and
> processor interface tuning and diagnostics.
> Those services are available via the Platform Environment Control
> Interface (PECI) that provides a communication channel between the
> processor and the Baseboard Management Controller (BMC) or other
> platform management device.
>
> This change introduces PECI subsystem by adding the initial core module
> and API for controller drivers.
>
> Co-developed-by: Jason M Bills <jason.m.bills at linux.intel.com>
> Signed-off-by: Jason M Bills <jason.m.bills at linux.intel.com>
> Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> ---
>  MAINTAINERS             |   9 +++
>  drivers/Kconfig         |   3 +
>  drivers/Makefile        |   1 +
>  drivers/peci/Kconfig    |  15 ++++
>  drivers/peci/Makefile   |   5 ++
>  drivers/peci/core.c     | 155 ++++++++++++++++++++++++++++++++++++++++
>  drivers/peci/internal.h |  16 +++++
>  include/linux/peci.h    |  99 +++++++++++++++++++++++++
>  8 files changed, 303 insertions(+)
>  create mode 100644 drivers/peci/Kconfig
>  create mode 100644 drivers/peci/Makefile
>  create mode 100644 drivers/peci/core.c
>  create mode 100644 drivers/peci/internal.h
>  create mode 100644 include/linux/peci.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7cdab7229651..d411974aaa5e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14503,6 +14503,15 @@ L:     platform-driver-x86 at vger.kernel.org
>  S:     Maintained
>  F:     drivers/platform/x86/peaq-wmi.c
>
> +PECI SUBSYSTEM
> +M:     Iwona Winiarska <iwona.winiarska at intel.com>
> +R:     Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> +L:     openbmc at lists.ozlabs.org (moderated for non-subscribers)
> +S:     Supported
> +F:     Documentation/devicetree/bindings/peci/
> +F:     drivers/peci/
> +F:     include/linux/peci.h
> +
>  PENSANDO ETHERNET DRIVERS
>  M:     Shannon Nelson <snelson at pensando.io>
>  M:     drivers at pensando.io
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index 8bad63417a50..f472b3d972b3 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -236,4 +236,7 @@ source "drivers/interconnect/Kconfig"
>  source "drivers/counter/Kconfig"
>
>  source "drivers/most/Kconfig"
> +
> +source "drivers/peci/Kconfig"
> +
>  endmenu
> diff --git a/drivers/Makefile b/drivers/Makefile
> index 27c018bdf4de..8d96f0c3dde5 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -189,3 +189,4 @@ obj-$(CONFIG_GNSS)          += gnss/
>  obj-$(CONFIG_INTERCONNECT)     += interconnect/
>  obj-$(CONFIG_COUNTER)          += counter/
>  obj-$(CONFIG_MOST)             += most/
> +obj-$(CONFIG_PECI)             += peci/
> diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
> new file mode 100644
> index 000000000000..71a4ad81225a
> --- /dev/null
> +++ b/drivers/peci/Kconfig
> @@ -0,0 +1,15 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +menuconfig PECI
> +       tristate "PECI support"
> +       help
> +         The Platform Environment Control Interface (PECI) is an interface
> +         that provides a communication channel to Intel processors and
> +         chipset components from external monitoring or control devices.
> +
> +         If you are building a Baseboard Management Controller (BMC) kernel
> +         for Intel platform say Y here and also to the specific driver for
> +         your adapter(s) below. If unsure say N.
> +
> +         This support is also available as a module. If so, the module
> +         will be called peci.
> diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
> new file mode 100644
> index 000000000000..e789a354e842
> --- /dev/null
> +++ b/drivers/peci/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +# Core functionality
> +peci-y := core.o
> +obj-$(CONFIG_PECI) += peci.o
> diff --git a/drivers/peci/core.c b/drivers/peci/core.c
> new file mode 100644
> index 000000000000..7b3938af0396
> --- /dev/null
> +++ b/drivers/peci/core.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2018-2021 Intel Corporation
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

This looks like overkill for only one print statement in this module,
especially when the dev_ print helpers offer more detail.

> +
> +#include <linux/bug.h>
> +#include <linux/device.h>
> +#include <linux/export.h>
> +#include <linux/idr.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/peci.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/property.h>
> +#include <linux/slab.h>
> +
> +#include "internal.h"
> +
> +static DEFINE_IDA(peci_controller_ida);
> +
> +static void peci_controller_dev_release(struct device *dev)
> +{
> +       struct peci_controller *controller = to_peci_controller(dev);
> +
> +       pm_runtime_disable(&controller->dev);

This seems late to be disabling power management, the device is about
to be freed. Keep in mind the lifetime of the this object can be
artificially prolonged. I expect this to be done when the device is
unregistered from the bus.

> +
> +       mutex_destroy(&controller->bus_lock);
> +       ida_free(&peci_controller_ida, controller->id);
> +       fwnode_handle_put(controller->dev.fwnode);

Shouldn't the get / put of this handle reference be bound to specific
accesses not held for the entire lifetime of the object? At a minimum
it seems to be a reference that can taken at registration and dropped
at unregistration.

> +       kfree(controller);
> +}
> +
> +struct device_type peci_controller_type = {
> +       .release        = peci_controller_dev_release,
> +};
> +
> +static struct peci_controller *peci_controller_alloc(struct device *dev,
> +                                                    struct peci_controller_ops *ops)
> +{
> +       struct fwnode_handle *node = fwnode_handle_get(dev_fwnode(dev));
> +       struct peci_controller *controller;
> +       int ret;
> +
> +       if (!ops->xfer)
> +               return ERR_PTR(-EINVAL);
> +
> +       controller = kzalloc(sizeof(*controller), GFP_KERNEL);
> +       if (!controller)
> +               return ERR_PTR(-ENOMEM);
> +
> +       ret = ida_alloc_max(&peci_controller_ida, U8_MAX, GFP_KERNEL);
> +       if (ret < 0)
> +               goto err;
> +       controller->id = ret;
> +
> +       controller->ops = ops;
> +
> +       controller->dev.parent = dev;
> +       controller->dev.bus = &peci_bus_type;
> +       controller->dev.type = &peci_controller_type;
> +       controller->dev.fwnode = node;
> +       controller->dev.of_node = to_of_node(node);
> +
> +       device_initialize(&controller->dev);
> +
> +       mutex_init(&controller->bus_lock);
> +
> +       pm_runtime_no_callbacks(&controller->dev);
> +       pm_suspend_ignore_children(&controller->dev, true);
> +       pm_runtime_enable(&controller->dev);

Per above, are you sure unregistered devices need pm_runtime enabled?

Rest looks ok to me.


From olteanv at gmail.com  Wed Aug 25 17:00:30 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 26 Aug 2021 03:00:30 +0300
Subject: [RFC net-next 0/2] DSA slave with customise netdev features
In-Reply-To: <20210825083832.2425886-1-dqfext@gmail.com>
References: <20210825083832.2425886-1-dqfext@gmail.com>
Message-ID: <20210826000030.dhiwv4puqiqyh3re@skbuf>

On Wed, Aug 25, 2021 at 04:38:29PM +0800, DENG Qingfang wrote:
> Some taggers, such as tag_dsa.c, combine VLAN tags with DSA tags, which
> currently has a few problems:
>
> 1. Unnecessary reallocation on TX:
>
> A central TX reallocation has been used since commit a3b0b6479700
> ("net: dsa: implement a central TX reallocation procedure"), but for
> VLAN-tagged frames, the actual headroom required for DSA taggers which
> combine with VLAN tags is smaller.

If true, this would be a major failure of the central TX reallocation idea.

However, for this to fail, it would mean that there is a code path in
the network stack that routinely allocates skbs with skb_needed_headroom(skb)
smaller than dev->needed_headroom. That's the only thing that would trigger
reallocs (beside cloned skbs).

The fact that we ask for a dev->needed_headroom that is a bit larger
than what is needed in some cases is not an issue. We should declare the
largest dev->needed_headroom that should cover all cases.

Would you please let me know what is the stack trace when you apply this
patch?

-----------------------------[ cut here ]-----------------------------
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 6d6f1aebf1ca..1924025ac136 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -600,6 +600,10 @@ static int dsa_realloc_skb(struct sk_buff *skb, struct net_device *dev)
 		/* No reallocation needed, yay! */
 		return 0;
 
+	netdev_err(dev, "%s: skb realloc: headroom %u, tailroom %u, cloned %d, needed_headroom %d, needed_tailroom %d\n",
+		  __func__, skb_headroom(skb), skb_tailroom(skb), skb_cloned(skb), needed_headroom, needed_tailroom);
+	WARN_ON(!skb_cloned(skb));
+
 	return pskb_expand_head(skb, needed_headroom, needed_tailroom,
 				GFP_ATOMIC);
 }
-----------------------------[ cut here ]-----------------------------

>
> 2. Repeated memmoves:
>
> If a both Marvell EDSA and VLAN tagged frame is received, the current
> code will move the (DA,SA) twice: the first in dsa_rcv_ll to convert the
> frame to a normal 802.1Q frame, and the second to strip off the 802.1Q
> tag. The similar thing happens on TX.

I don't think a lot of people use 8021q uppers with mv88e6xxx. At least
the error messages I've seen during the few times when I've booted the
Turris Mox would seem to suggest that.

The code that converts DSA 'tagged' frames to VLAN tags originates from
Lennert Buytenhek himself.

>
> For these tags, it is better to handle DSA and VLAN tags at the same time
> in DSA taggers.

No objection there.

>
> This patch set allows taggers to add custom netdev features to DSA
> slaves so they can advertise VLAN offload, and converts tag_mtk to use
> the TX VLAN offload.
>
> DENG Qingfang (2):
>   net: dsa: allow taggers to customise netdev features
>   net: dsa: tag_mtk: handle VLAN tag insertion on TX
>
>  include/net/dsa.h |  2 ++
>  net/dsa/slave.c   |  3 ++-
>  net/dsa/tag_mtk.c | 46 ++++++++++++++++++++++------------------------
>  3 files changed, 26 insertions(+), 25 deletions(-)
>
> --
> 2.25.1
>


From olteanv at gmail.com  Wed Aug 25 17:01:20 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 26 Aug 2021 03:01:20 +0300
Subject: [RFC net-next 1/2] net: dsa: allow taggers to customise netdev
 features
In-Reply-To: <20210825083832.2425886-2-dqfext@gmail.com>
References: <20210825083832.2425886-1-dqfext@gmail.com>
 <20210825083832.2425886-2-dqfext@gmail.com>
Message-ID: <20210826000120.isvbsdjwpvyszglb@skbuf>

On Wed, Aug 25, 2021 at 04:38:30PM +0800, DENG Qingfang wrote:
> Allow taggers to add netdev features, such as VLAN offload, to slave
> devices, which will make it possible for taggers to handle VLAN tags
> themselves.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---

Reviewed-by: Vladimir Oltean <olteanv at gmail.com>


From olteanv at gmail.com  Wed Aug 25 17:03:49 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 26 Aug 2021 03:03:49 +0300
Subject: [RFC net-next 2/2] net: dsa: tag_mtk: handle VLAN tag insertion
 on TX
In-Reply-To: <20210825083832.2425886-3-dqfext@gmail.com>
References: <20210825083832.2425886-1-dqfext@gmail.com>
 <20210825083832.2425886-3-dqfext@gmail.com>
Message-ID: <20210826000349.q3s5gjuworxtbcna@skbuf>

On Wed, Aug 25, 2021 at 04:38:31PM +0800, DENG Qingfang wrote:
> Advertise TX VLAN offload features, and handle VLAN tag insertion in
> the tag_xmit function.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>
> ---
>  net/dsa/tag_mtk.c | 46 ++++++++++++++++++++++------------------------
>  1 file changed, 22 insertions(+), 24 deletions(-)
> 
> diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
> index 415d8ece242a..e407abefa06c 100644
> --- a/net/dsa/tag_mtk.c
> +++ b/net/dsa/tag_mtk.c
> @@ -22,7 +22,6 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
>  				    struct net_device *dev)
>  {
>  	struct dsa_port *dp = dsa_slave_to_port(dev);
> -	u8 xmit_tpid;
>  	u8 *mtk_tag;
>  
>  	/* Build the special tag after the MAC Source Address. If VLAN header
> @@ -31,33 +30,31 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
>  	 * the both special and VLAN tag at the same time and then look up VLAN
>  	 * table with VID.
>  	 */
> -	switch (skb->protocol) {
> -	case htons(ETH_P_8021Q):
> -		xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_8100;
> -		break;
> -	case htons(ETH_P_8021AD):
> -		xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_88A8;
> -		break;
> -	default:
> -		xmit_tpid = MTK_HDR_XMIT_UNTAGGED;
> -		skb_push(skb, MTK_HDR_LEN);
> -		dsa_alloc_etype_header(skb, MTK_HDR_LEN);
> -	}
> -

You cannot just remove the old code. Only things like 8021q uppers will
send packets with the VLAN in the hwaccel area.

If you have an application that puts the VLAN in the actual AF_PACKET
payload, like:

https://github.com/vladimiroltean/tsn-scripts/blob/master/isochron/send.c

then you need to handle the VLAN being in the skb payload.


From samuel at sholland.org  Wed Aug 25 17:20:54 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed, 25 Aug 2021 19:20:54 -0500
Subject: [PATCH 10/17] clk: sunxi=ng: add support for R329 R-CCU
In-Reply-To: <5432230.1UTMcGJKg4@jernej-laptop>
References: <20210802062212.73220-1-icenowy@sipeed.com>
 <20210802062212.73220-11-icenowy@sipeed.com>
 <99a74950-fdc0-ecfe-e5f0-ba4a7d8751f0@sholland.org>
 <5432230.1UTMcGJKg4@jernej-laptop>
Message-ID: <5d0489ac-0693-f1f0-17d5-bfe9ca5df0ff@sholland.org>

On 8/19/21 11:34 PM, Jernej ?krabec wrote:
>>> +static void __init sun50i_r329_r_ccu_setup(struct device_node *node)
>>> +{
>>> +	void __iomem *reg;
>>> +	u32 val;
>>> +	int i;
>>> +
>>> +	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
>>> +	if (IS_ERR(reg)) {
>>> +		pr_err("%pOF: Could not map clock registers\n", node);
>>> +		return;
>>> +	}
>>> +
>>> +	/* Enable the lock bits and the output enable bits on all PLLs */
>>> +	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
>>> +		val = readl(reg + pll_regs[i]);
>>> +		val |= BIT(29) | BIT(27);
>>> +		writel(val, reg + pll_regs[i]);
>>> +	}
>>> +
>>> +	/*
>>> +	 * Force the I/O dividers of PLL-AUDIO1 to reset default value
>>> +	 *
>>> +	 * See the comment before pll-audio1 definition for the reason.
>>> +	 */
>>> +
>>> +	val = readl(reg + SUN50I_R329_PLL_AUDIO1_REG);
>>> +	val &= ~BIT(1);
>>> +	val |= BIT(0);
>>> +	writel(val, reg + SUN50I_R329_PLL_AUDIO1_REG);
>>> +
>>> +	i = sunxi_ccu_probe(node, reg, &sun50i_r329_r_ccu_desc);
>>> +	if (i)
>>> +		pr_err("%pOF: probing clocks fails: %d\n", node, i);
>>> +}
>>> +
>>> +CLK_OF_DECLARE(sun50i_r329_r_ccu, "allwinner,sun50i-r329-r-ccu",
>>> +	       sun50i_r329_r_ccu_setup);
>>
>> Please make this a platform driver. There is no particular reason why it
>> needs to be an early OF clock provider.
> 
> Why? It's good to have it as early clock provider. It has no dependencies and 
> other drivers that depends on it, like IR, can be deferred, if this is loaded 
> later.

Another reason is so the driver can be built as a module. Each of these
CCU drivers has 30k-70k of data in it (lots of pointers, plus lots of
relocations). So it saves some RAM to only load the ones you need,
especially if that is none of them.

Regards,
Samuel


From chunkuang.hu at kernel.org  Wed Aug 25 17:31:08 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 26 Aug 2021 08:31:08 +0800
Subject: [PATCH v3 3/7] dt-bindings: display: mediatek: add dsi reset
 optional property
In-Reply-To: <20210825122613.v3.3.Ifec72a83f224b62f24cfc967edfe78c5d276b2e3@changeid>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
 <20210825122613.v3.3.Ifec72a83f224b62f24cfc967edfe78c5d276b2e3@changeid>
Message-ID: <CAAOTY_9anqUZ-um4bP8Gzf4HZT5+j+yVpTq6pQzESpamrGLM8Q@mail.gmail.com>

Hi, Enric:

Enric Balletbo i Serra <enric.balletbo at collabora.com> ? 2021?8?25? ?? ??6:26???
>
> Update device tree binding documentation for the dsi to add the optional
> property to reset the dsi controller.

Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Added a new patch to describe the dsi reset optional property.
>
>  .../devicetree/bindings/display/mediatek/mediatek,dsi.txt   | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> index 8238a86686be..3209b700ded6 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> @@ -19,6 +19,11 @@ Required properties:
>    Documentation/devicetree/bindings/graph.txt. This port should be connected
>    to the input port of an attached DSI panel or DSI-to-eDP encoder chip.
>
> +Optional properties:
> +- resets: list of phandle + reset specifier pair, as described in [1].
> +
> +[1] Documentation/devicetree/bindings/reset/reset.txt
> +
>  MIPI TX Configuration Module
>  ============================
>
> @@ -45,6 +50,7 @@ dsi0: dsi at 1401b000 {
>         clocks = <&mmsys MM_DSI0_ENGINE>, <&mmsys MM_DSI0_DIGITAL>,
>                  <&mipi_tx0>;
>         clock-names = "engine", "digital", "hs";
> +       resets = <&mmsys MT8173_MMSYS_SW0_RST_B_DISP_DSI0>;
>         phys = <&mipi_tx0>;
>         phy-names = "dphy";
>
> --
> 2.30.2
>


From chunkuang.hu at kernel.org  Wed Aug 25 17:33:02 2021
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 26 Aug 2021 08:33:02 +0800
Subject: [PATCH v3 6/7] soc: mediatek: mmsys: Add reset controller support
In-Reply-To: <ebbe37cb0188a7ea23608569ab083e65e0f95df6.camel@pengutronix.de>
References: <20210825102632.601614-1-enric.balletbo@collabora.com>
 <20210825122613.v3.6.I15e2419141a69b2e5c7e700c34d92a69df47e04d@changeid>
 <ebbe37cb0188a7ea23608569ab083e65e0f95df6.camel@pengutronix.de>
Message-ID: <CAAOTY__wg+dWi-4v4evyuWp1EVfj2bap3xtsHZdGET4Jf-MgEw@mail.gmail.com>

Philipp Zabel <p.zabel at pengutronix.de> ? 2021?8?25? ?? ??6:46???
>
> On Wed, 2021-08-25 at 12:26 +0200, Enric Balletbo i Serra wrote:
> > Among other features the mmsys driver should implement a reset
> > controller to be able to reset different bits from their space.
> >
> > Cc: Jitao Shi <jitao.shi at mediatek.com>
> > Suggested-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> > Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> > Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
> > ---
> >
> > (no changes since v1)
> >
> >  drivers/soc/mediatek/mtk-mmsys.c | 69 ++++++++++++++++++++++++++++++++
> >  drivers/soc/mediatek/mtk-mmsys.h |  2 +
>
> Cc: Nancy - this patch clashes with [1], please coordinate.
>
> [1] https://lore.kernel.org/linux-arm-kernel/20210825100531.5653-11-nancy.lin at mediatek.com/

Enric's series is all reviewed or acked, so I think Nancy's series
should base on Enric's series.

Regards,
Chun-Kuang.

>
> regards
> Philipp


From seanjc at google.com  Wed Aug 25 17:51:54 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 00:51:54 +0000
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <282257549.21721.1629732017655.JavaMail.zimbra@efficios.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-5-seanjc@google.com>
 <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>
 <282257549.21721.1629732017655.JavaMail.zimbra@efficios.com>
Message-ID: <YSblqrrpKcORzilX@google.com>

On Mon, Aug 23, 2021, Mathieu Desnoyers wrote:
> [ re-send to Darren Hart ]
> 
> ----- On Aug 23, 2021, at 11:18 AM, Mathieu Desnoyers mathieu.desnoyers at efficios.com wrote:
> 
> > ----- On Aug 20, 2021, at 6:50 PM, Sean Christopherson seanjc at google.com wrote:
> > 
> >> Add a test to verify an rseq's CPU ID is updated correctly if the task is
> >> migrated while the kernel is handling KVM_RUN.  This is a regression test
> >> for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
> >> to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
> >> without updating rseq, leading to a stale CPU ID and other badness.
> >> 
> > 
> > [...]
> > 
> > +#define RSEQ_SIG 0xdeadbeef
> > 
> > Is there any reason for defining a custom signature rather than including
> > tools/testing/selftests/rseq/rseq.h ? This should take care of including
> > the proper architecture header which will define the appropriate signature.
> > 
> > Arguably you don't define rseq critical sections in this test per se, but
> > I'm wondering why the custom signature here.

Partly to avoid taking a dependency on rseq.h, and partly to try to call out that
the test doesn't actually do any rseq critical sections.

> > [...]
> > 
> >> +
> >> +static void *migration_worker(void *ign)
> >> +{
> >> +	cpu_set_t allowed_mask;
> >> +	int r, i, nr_cpus, cpu;
> >> +
> >> +	CPU_ZERO(&allowed_mask);
> >> +
> >> +	nr_cpus = CPU_COUNT(&possible_mask);
> >> +
> >> +	for (i = 0; i < 20000; i++) {
> >> +		cpu = i % nr_cpus;
> >> +		if (!CPU_ISSET(cpu, &possible_mask))
> >> +			continue;
> >> +
> >> +		CPU_SET(cpu, &allowed_mask);
> >> +
> >> +		/*
> >> +		 * Bump the sequence count twice to allow the reader to detect
> >> +		 * that a migration may have occurred in between rseq and sched
> >> +		 * CPU ID reads.  An odd sequence count indicates a migration
> >> +		 * is in-progress, while a completely different count indicates
> >> +		 * a migration occurred since the count was last read.
> >> +		 */
> >> +		atomic_inc(&seq_cnt);
> > 
> > So technically this atomic_inc contains the required barriers because the
> > selftests implementation uses "__sync_add_and_fetch(&addr->val, 1)". But
> > it's rather odd that the semantic differs from the kernel implementation in
> > terms of memory barriers: the kernel implementation of atomic_inc
> > guarantees no memory barriers, but this one happens to provide full
> > barriers pretty much by accident (selftests futex/include/atomic.h
> > documents no such guarantee).

Yeah, I got quite lost trying to figure out what atomics the test would actually
end up with.

> > If this full barrier guarantee is indeed provided by the selftests atomic.h
> > header, I would really like a comment stating that in the atomic.h header
> > so the carpet is not pulled from under our feet by a future optimization.
> > 
> > 
> >> +		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
> >> +		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)",
> >> +			    errno, strerror(errno));
> >> +		atomic_inc(&seq_cnt);
> >> +
> >> +		CPU_CLR(cpu, &allowed_mask);
> >> +
> >> +		/*
> >> +		 * Let the read-side get back into KVM_RUN to improve the odds
> >> +		 * of task migration coinciding with KVM's run loop.
> > 
> > This comment should be about increasing the odds of letting the seqlock
> > read-side complete. Otherwise, the delay between the two back-to-back
> > atomic_inc is so small that the seqlock read-side may never have time to
> > complete the reading the rseq cpu id and the sched_getcpu() call, and can
> > retry forever.

Hmm, but that's not why there's a delay.  I'm not arguing that a livelock isn't
possible (though that syscall would have to be screaming fast), but the primary
motivation is very much to allow the read-side enough time to get back into KVM
proper.

To encounter the bug, TIF_NOTIFY_RESUME has to be recognized by KVM in its run
loop, i.e. sched_setaffinity() must induce task migration after the read-side has
invoked ioctl(KVM_RUN).

> > I'm wondering if 1 microsecond is sufficient on other architectures as
> > well.

I'm definitely wondering that as well :-)

> > One alternative way to make this depend less on the architecture's
> > implementation of sched_getcpu (whether it's a vDSO, or goes through a
> > syscall) would be to read the rseq cpu id and call sched_getcpu a few times
> > (e.g. 3 times) in the migration thread rather than use usleep, and throw
> > away the value read. This would ensure the delay is appropriate on all
> > architectures.

As above, I think an arbitrary delay is required regardless of how fast
sched_getcpu() can execute.  One thought would be to do sched_getcpu() _and_
usleep() to account for sched_getcpu() overhead and to satisfy the KVM_RUN part,
but I don't know that that adds meaningful value.

The real test is if someone could see if the bug repros on non-x86 hardware...


From quanyang.wang at windriver.com  Wed Aug 25 17:59:30 2021
From: quanyang.wang at windriver.com (quanyang.wang at windriver.com)
Date: Thu, 26 Aug 2021 08:59:30 +0800
Subject: [RESEND][PATCH] spi: spi-zynq-qspi: use wait_for_completion_timeout
 to make zynq_qspi_exec_mem_op not interruptible
Message-ID: <20210826005930.20572-1-quanyang.wang@windriver.com>

From: Quanyang Wang <quanyang.wang at windriver.com>

The function wait_for_completion_interruptible_timeout will return
-ERESTARTSYS immediately when receiving SIGKILL signal which is sent
by "jffs2_gcd_mtd" during umounting jffs2. This will break the SPI memory
operation because the data transmitting may begin before the command or
address transmitting completes. Use wait_for_completion_timeout to prevent
the process from being interruptible.

Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller")
Signed-off-by: Quanyang Wang <quanyang.wang at windriver.com>
---
 drivers/spi/spi-zynq-qspi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
index 9262c6418463..cfa222c9bd5e 100644
--- a/drivers/spi/spi-zynq-qspi.c
+++ b/drivers/spi/spi-zynq-qspi.c
@@ -545,7 +545,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
 		zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
 		zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
 				ZYNQ_QSPI_IXR_RXTX_MASK);
-		if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion,
+		if (!wait_for_completion_timeout(&xqspi->data_completion,
 							       msecs_to_jiffies(1000)))
 			err = -ETIMEDOUT;
 	}
@@ -563,7 +563,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
 		zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
 		zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
 				ZYNQ_QSPI_IXR_RXTX_MASK);
-		if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion,
+		if (!wait_for_completion_timeout(&xqspi->data_completion,
 							       msecs_to_jiffies(1000)))
 			err = -ETIMEDOUT;
 	}
@@ -579,7 +579,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
 		zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
 		zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
 				ZYNQ_QSPI_IXR_RXTX_MASK);
-		if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion,
+		if (!wait_for_completion_timeout(&xqspi->data_completion,
 							       msecs_to_jiffies(1000)))
 			err = -ETIMEDOUT;
 
@@ -603,7 +603,7 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
 		zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true);
 		zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET,
 				ZYNQ_QSPI_IXR_RXTX_MASK);
-		if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion,
+		if (!wait_for_completion_timeout(&xqspi->data_completion,
 							       msecs_to_jiffies(1000)))
 			err = -ETIMEDOUT;
 	}
-- 
2.25.1



From dan.j.williams at intel.com  Wed Aug 25 18:35:53 2021
From: dan.j.williams at intel.com (Dan Williams)
Date: Wed, 25 Aug 2021 18:35:53 -0700
Subject: [PATCH v2 07/15] peci: Add peci-aspeed controller driver
In-Reply-To: <20210803113134.2262882-8-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-8-iwona.winiarska@intel.com>
Message-ID: <CAPcyv4jPVSt9Wr2TkDActFVLP+ygaDwBnsKG410Nf1qfP_MB9A@mail.gmail.com>

On Tue, Aug 3, 2021 at 4:35 AM Iwona Winiarska
<iwona.winiarska at intel.com> wrote:
>
> From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>
> ASPEED AST24xx/AST25xx/AST26xx SoCs supports the PECI electrical
> interface (a.k.a PECI wire).

Maybe a one sentence blurb here and in the Kconfig reminding people
why they should care if they have a PECI driver or not?

>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> ---
>  MAINTAINERS                           |   9 +
>  drivers/peci/Kconfig                  |   6 +
>  drivers/peci/Makefile                 |   3 +
>  drivers/peci/controller/Kconfig       |  16 +
>  drivers/peci/controller/Makefile      |   3 +
>  drivers/peci/controller/peci-aspeed.c | 445 ++++++++++++++++++++++++++
>  6 files changed, 482 insertions(+)
>  create mode 100644 drivers/peci/controller/Kconfig
>  create mode 100644 drivers/peci/controller/Makefile
>  create mode 100644 drivers/peci/controller/peci-aspeed.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d411974aaa5e..6e9d53ff68ab 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2866,6 +2866,15 @@ S:       Maintained
>  F:     Documentation/hwmon/asc7621.rst
>  F:     drivers/hwmon/asc7621.c
>
> +ASPEED PECI CONTROLLER
> +M:     Iwona Winiarska <iwona.winiarska at intel.com>
> +M:     Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> +L:     linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
> +L:     openbmc at lists.ozlabs.org (moderated for non-subscribers)
> +S:     Supported
> +F:     Documentation/devicetree/bindings/peci/peci-aspeed.yaml
> +F:     drivers/peci/controller/peci-aspeed.c
> +
>  ASPEED PINCTRL DRIVERS
>  M:     Andrew Jeffery <andrew at aj.id.au>
>  L:     linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
> diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
> index 71a4ad81225a..99279df97a78 100644
> --- a/drivers/peci/Kconfig
> +++ b/drivers/peci/Kconfig
> @@ -13,3 +13,9 @@ menuconfig PECI
>
>           This support is also available as a module. If so, the module
>           will be called peci.
> +
> +if PECI
> +
> +source "drivers/peci/controller/Kconfig"
> +
> +endif # PECI
> diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
> index e789a354e842..926d8df15cbd 100644
> --- a/drivers/peci/Makefile
> +++ b/drivers/peci/Makefile
> @@ -3,3 +3,6 @@
>  # Core functionality
>  peci-y := core.o
>  obj-$(CONFIG_PECI) += peci.o
> +
> +# Hardware specific bus drivers
> +obj-y += controller/
> diff --git a/drivers/peci/controller/Kconfig b/drivers/peci/controller/Kconfig
> new file mode 100644
> index 000000000000..6d48df08db1c
> --- /dev/null
> +++ b/drivers/peci/controller/Kconfig
> @@ -0,0 +1,16 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +config PECI_ASPEED
> +       tristate "ASPEED PECI support"
> +       depends on ARCH_ASPEED || COMPILE_TEST
> +       depends on OF
> +       depends on HAS_IOMEM
> +       help
> +         This option enables PECI controller driver for ASPEED AST2400,
> +         AST2500 and AST2600 SoCs.
> +
> +         Say Y here if your system runs on ASPEED SoC and you are using it
> +         as BMC for Intel platform.
> +
> +         This driver can also be built as a module. If so, the module will
> +         be called peci-aspeed.
> diff --git a/drivers/peci/controller/Makefile b/drivers/peci/controller/Makefile
> new file mode 100644
> index 000000000000..022c28ef1bf0
> --- /dev/null
> +++ b/drivers/peci/controller/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +
> +obj-$(CONFIG_PECI_ASPEED)      += peci-aspeed.o
> diff --git a/drivers/peci/controller/peci-aspeed.c b/drivers/peci/controller/peci-aspeed.c
> new file mode 100644
> index 000000000000..1d708c983749
> --- /dev/null
> +++ b/drivers/peci/controller/peci-aspeed.c
> @@ -0,0 +1,445 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (C) 2012-2017 ASPEED Technology Inc.
> +// Copyright (c) 2018-2021 Intel Corporation

Why different copyright capitalization?

> +
> +#include <linux/bitfield.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/jiffies.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/peci.h>
> +#include <linux/platform_device.h>
> +#include <linux/reset.h>
> +
> +#include <asm/unaligned.h>

Why is this included?

> +
> +/* ASPEED PECI Registers */
> +/* Control Register */
> +#define ASPEED_PECI_CTRL                       0x00
> +#define   ASPEED_PECI_CTRL_SAMPLING_MASK       GENMASK(19, 16)
> +#define   ASPEED_PECI_CTRL_RD_MODE_MASK                GENMASK(13, 12)
> +#define     ASPEED_PECI_CTRL_RD_MODE_DBG       BIT(13)
> +#define     ASPEED_PECI_CTRL_RD_MODE_COUNT     BIT(12)
> +#define   ASPEED_PECI_CTRL_CLK_SOURCE          BIT(11)
> +#define   ASPEED_PECI_CTRL_CLK_DIV_MASK                GENMASK(10, 8)
> +#define   ASPEED_PECI_CTRL_INVERT_OUT          BIT(7)
> +#define   ASPEED_PECI_CTRL_INVERT_IN           BIT(6)
> +#define   ASPEED_PECI_CTRL_BUS_CONTENTION_EN   BIT(5)
> +#define   ASPEED_PECI_CTRL_PECI_EN             BIT(4)
> +#define   ASPEED_PECI_CTRL_PECI_CLK_EN         BIT(0)
> +
> +/* Timing Negotiation Register */
> +#define ASPEED_PECI_TIMING_NEGOTIATION         0x04
> +#define   ASPEED_PECI_T_NEGO_MSG_MASK          GENMASK(15, 8)
> +#define   ASPEED_PECI_T_NEGO_ADDR_MASK         GENMASK(7, 0)
> +
> +/* Command Register */
> +#define ASPEED_PECI_CMD                                0x08
> +#define   ASPEED_PECI_CMD_PIN_MONITORING       BIT(31)
> +#define   ASPEED_PECI_CMD_STS_MASK             GENMASK(27, 24)
> +#define     ASPEED_PECI_CMD_STS_ADDR_T_NEGO    0x3
> +#define   ASPEED_PECI_CMD_IDLE_MASK            \
> +         (ASPEED_PECI_CMD_STS_MASK | ASPEED_PECI_CMD_PIN_MONITORING)
> +#define   ASPEED_PECI_CMD_FIRE                 BIT(0)
> +
> +/* Read/Write Length Register */
> +#define ASPEED_PECI_RW_LENGTH                  0x0c
> +#define   ASPEED_PECI_AW_FCS_EN                        BIT(31)
> +#define   ASPEED_PECI_RD_LEN_MASK              GENMASK(23, 16)
> +#define   ASPEED_PECI_WR_LEN_MASK              GENMASK(15, 8)
> +#define   ASPEED_PECI_TARGET_ADDR_MASK         GENMASK(7, 0)
> +
> +/* Expected FCS Data Register */
> +#define ASPEED_PECI_EXPECTED_FCS               0x10
> +#define   ASPEED_PECI_EXPECTED_RD_FCS_MASK     GENMASK(23, 16)
> +#define   ASPEED_PECI_EXPECTED_AW_FCS_AUTO_MASK        GENMASK(15, 8)
> +#define   ASPEED_PECI_EXPECTED_WR_FCS_MASK     GENMASK(7, 0)
> +
> +/* Captured FCS Data Register */
> +#define ASPEED_PECI_CAPTURED_FCS               0x14
> +#define   ASPEED_PECI_CAPTURED_RD_FCS_MASK     GENMASK(23, 16)
> +#define   ASPEED_PECI_CAPTURED_WR_FCS_MASK     GENMASK(7, 0)
> +
> +/* Interrupt Register */
> +#define ASPEED_PECI_INT_CTRL                   0x18
> +#define   ASPEED_PECI_TIMING_NEGO_SEL_MASK     GENMASK(31, 30)
> +#define     ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO   0
> +#define     ASPEED_PECI_2ND_BIT_OF_ADDR_NEGO   1
> +#define     ASPEED_PECI_MESSAGE_NEGO           2
> +#define   ASPEED_PECI_INT_MASK                 GENMASK(4, 0)
> +#define     ASPEED_PECI_INT_BUS_TIMEOUT                BIT(4)
> +#define     ASPEED_PECI_INT_BUS_CONTENTION     BIT(3)
> +#define     ASPEED_PECI_INT_WR_FCS_BAD         BIT(2)
> +#define     ASPEED_PECI_INT_WR_FCS_ABORT       BIT(1)
> +#define     ASPEED_PECI_INT_CMD_DONE           BIT(0)
> +
> +/* Interrupt Status Register */
> +#define ASPEED_PECI_INT_STS                    0x1c
> +#define   ASPEED_PECI_INT_TIMING_RESULT_MASK   GENMASK(29, 16)
> +         /* bits[4..0]: Same bit fields in the 'Interrupt Register' */
> +
> +/* Rx/Tx Data Buffer Registers */
> +#define ASPEED_PECI_WR_DATA0                   0x20
> +#define ASPEED_PECI_WR_DATA1                   0x24
> +#define ASPEED_PECI_WR_DATA2                   0x28
> +#define ASPEED_PECI_WR_DATA3                   0x2c
> +#define ASPEED_PECI_RD_DATA0                   0x30
> +#define ASPEED_PECI_RD_DATA1                   0x34
> +#define ASPEED_PECI_RD_DATA2                   0x38
> +#define ASPEED_PECI_RD_DATA3                   0x3c
> +#define ASPEED_PECI_WR_DATA4                   0x40
> +#define ASPEED_PECI_WR_DATA5                   0x44
> +#define ASPEED_PECI_WR_DATA6                   0x48
> +#define ASPEED_PECI_WR_DATA7                   0x4c
> +#define ASPEED_PECI_RD_DATA4                   0x50
> +#define ASPEED_PECI_RD_DATA5                   0x54
> +#define ASPEED_PECI_RD_DATA6                   0x58
> +#define ASPEED_PECI_RD_DATA7                   0x5c
> +#define   ASPEED_PECI_DATA_BUF_SIZE_MAX                32
> +
> +/* Timing Negotiation */
> +#define ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT  8
> +#define ASPEED_PECI_RD_SAMPLING_POINT_MAX      (BIT(4) - 1)
> +#define ASPEED_PECI_CLK_DIV_DEFAULT            0
> +#define ASPEED_PECI_CLK_DIV_MAX                        (BIT(3) - 1)
> +#define ASPEED_PECI_MSG_TIMING_DEFAULT         1
> +#define ASPEED_PECI_MSG_TIMING_MAX             (BIT(8) - 1)
> +#define ASPEED_PECI_ADDR_TIMING_DEFAULT                1
> +#define ASPEED_PECI_ADDR_TIMING_MAX            (BIT(8) - 1)
> +
> +/* Timeout */
> +#define ASPEED_PECI_IDLE_CHECK_TIMEOUT_US      (50 * USEC_PER_MSEC)
> +#define ASPEED_PECI_IDLE_CHECK_INTERVAL_US     (10 * USEC_PER_MSEC)
> +#define ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT     (1000)
> +#define ASPEED_PECI_CMD_TIMEOUT_MS_MAX         (1000)
> +
> +struct aspeed_peci {
> +       struct peci_controller *controller;
> +       struct device *dev;
> +       void __iomem *base;
> +       struct clk *clk;
> +       struct reset_control *rst;
> +       int irq;
> +       spinlock_t lock; /* to sync completion status handling */
> +       struct completion xfer_complete;
> +       u32 status;
> +       u32 cmd_timeout_ms;
> +       u32 msg_timing;
> +       u32 addr_timing;
> +       u32 rd_sampling_point;
> +       u32 clk_div;
> +};
> +
> +static void aspeed_peci_init_regs(struct aspeed_peci *priv)
> +{
> +       u32 val;
> +
> +       val = FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK, ASPEED_PECI_CLK_DIV_DEFAULT);
> +       val |= ASPEED_PECI_CTRL_PECI_CLK_EN;
> +       writel(val, priv->base + ASPEED_PECI_CTRL);
> +       /*
> +        * Timing negotiation period setting.
> +        * The unit of the programmed value is 4 times of PECI clock period.
> +        */
> +       val = FIELD_PREP(ASPEED_PECI_T_NEGO_MSG_MASK, priv->msg_timing);
> +       val |= FIELD_PREP(ASPEED_PECI_T_NEGO_ADDR_MASK, priv->addr_timing);
> +       writel(val, priv->base + ASPEED_PECI_TIMING_NEGOTIATION);
> +
> +       /* Clear interrupts */
> +       val = readl(priv->base + ASPEED_PECI_INT_STS) | ASPEED_PECI_INT_MASK;
> +       writel(val, priv->base + ASPEED_PECI_INT_STS);
> +
> +       /* Set timing negotiation mode and enable interrupts */
> +       val = FIELD_PREP(ASPEED_PECI_TIMING_NEGO_SEL_MASK, ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO);
> +       val |= ASPEED_PECI_INT_MASK;
> +       writel(val, priv->base + ASPEED_PECI_INT_CTRL);
> +
> +       val = FIELD_PREP(ASPEED_PECI_CTRL_SAMPLING_MASK, priv->rd_sampling_point);
> +       val |= FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK, priv->clk_div);
> +       val |= ASPEED_PECI_CTRL_PECI_EN;
> +       val |= ASPEED_PECI_CTRL_PECI_CLK_EN;
> +       writel(val, priv->base + ASPEED_PECI_CTRL);
> +}
> +
> +static inline int aspeed_peci_check_idle(struct aspeed_peci *priv)
> +{
> +       u32 cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
> +
> +       if (FIELD_GET(ASPEED_PECI_CMD_STS_MASK, cmd_sts) == ASPEED_PECI_CMD_STS_ADDR_T_NEGO)
> +               aspeed_peci_init_regs(priv);
> +
> +       return readl_poll_timeout(priv->base + ASPEED_PECI_CMD,
> +                                 cmd_sts,
> +                                 !(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK),
> +                                 ASPEED_PECI_IDLE_CHECK_INTERVAL_US,
> +                                 ASPEED_PECI_IDLE_CHECK_TIMEOUT_US);
> +}
> +
> +static int aspeed_peci_xfer(struct peci_controller *controller,
> +                           u8 addr, struct peci_request *req)
> +{
> +       struct aspeed_peci *priv = dev_get_drvdata(controller->dev.parent);
> +       unsigned long flags, timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
> +       u32 peci_head;
> +       int ret;
> +
> +       if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
> +           req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
> +               return -EINVAL;
> +
> +       /* Check command sts and bus idle state */
> +       ret = aspeed_peci_check_idle(priv);
> +       if (ret)
> +               return ret; /* -ETIMEDOUT */
> +
> +       spin_lock_irqsave(&priv->lock, flags);
> +       reinit_completion(&priv->xfer_complete);
> +
> +       peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
> +                   FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
> +                   FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
> +
> +       writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
> +
> +       memcpy_toio(priv->base + ASPEED_PECI_WR_DATA0, req->tx.buf, min_t(u8, req->tx.len, 16));
> +       if (req->tx.len > 16)
> +               memcpy_toio(priv->base + ASPEED_PECI_WR_DATA4, req->tx.buf + 16,
> +                           req->tx.len - 16);
> +
> +       dev_dbg(priv->dev, "HEAD : 0x%08x\n", peci_head);
> +       print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf, req->tx.len);

On CONFIG_DYNAMIC_DEBUG=n builds the kernel will do all the work of
reading through this buffer, but skip emitting it. Are you sure you
want to pay that overhead for every transaction?

> +
> +       priv->status = 0;
> +       writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
> +       spin_unlock_irqrestore(&priv->lock, flags);
> +
> +       ret = wait_for_completion_interruptible_timeout(&priv->xfer_complete, timeout);

spin_lock_irqsave() says "I don't know if interrupts are disabled
already, so I'll save the state, whatever it is, and restore later"

wait_for_completion_interruptible_timeout() says "I know I am in a
sleepable context where interrupts are enabled"

So, one of those is wrong, i.e. should it be spin_{lock,unlock}_irq()?


> +       if (ret < 0)
> +               return ret;
> +
> +       if (ret == 0) {
> +               dev_dbg(priv->dev, "Timeout waiting for a response!\n");
> +               return -ETIMEDOUT;
> +       }
> +
> +       spin_lock_irqsave(&priv->lock, flags);
> +
> +       writel(0, priv->base + ASPEED_PECI_CMD);
> +
> +       if (priv->status != ASPEED_PECI_INT_CMD_DONE) {
> +               spin_unlock_irqrestore(&priv->lock, flags);
> +               dev_dbg(priv->dev, "No valid response!\n");
> +               return -EIO;
> +       }
> +
> +       spin_unlock_irqrestore(&priv->lock, flags);
> +
> +       memcpy_fromio(req->rx.buf, priv->base + ASPEED_PECI_RD_DATA0, min_t(u8, req->rx.len, 16));
> +       if (req->rx.len > 16)
> +               memcpy_fromio(req->rx.buf + 16, priv->base + ASPEED_PECI_RD_DATA4,
> +                             req->rx.len - 16);
> +
> +       print_hex_dump_bytes("RX : ", DUMP_PREFIX_NONE, req->rx.buf, req->rx.len);
> +
> +       return 0;
> +}
> +
> +static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
> +{
> +       struct aspeed_peci *priv = arg;
> +       u32 status;
> +
> +       spin_lock(&priv->lock);
> +       status = readl(priv->base + ASPEED_PECI_INT_STS);
> +       writel(status, priv->base + ASPEED_PECI_INT_STS);
> +       priv->status |= (status & ASPEED_PECI_INT_MASK);
> +
> +       /*
> +        * In most cases, interrupt bits will be set one by one but also note
> +        * that multiple interrupt bits could be set at the same time.
> +        */
> +       if (status & ASPEED_PECI_INT_BUS_TIMEOUT)
> +               dev_dbg_ratelimited(priv->dev, "ASPEED_PECI_INT_BUS_TIMEOUT\n");
> +
> +       if (status & ASPEED_PECI_INT_BUS_CONTENTION)
> +               dev_dbg_ratelimited(priv->dev, "ASPEED_PECI_INT_BUS_CONTENTION\n");
> +
> +       if (status & ASPEED_PECI_INT_WR_FCS_BAD)
> +               dev_dbg_ratelimited(priv->dev, "ASPEED_PECI_INT_WR_FCS_BAD\n");
> +
> +       if (status & ASPEED_PECI_INT_WR_FCS_ABORT)
> +               dev_dbg_ratelimited(priv->dev, "ASPEED_PECI_INT_WR_FCS_ABORT\n");

Are you sure these would not be better as tracepoints? If you're
debugging an interrupt related failure, the ratelimiting might get in
your way when you really need to know when one of these error
interrupts fire relative to another event.

> +
> +       /*
> +        * All commands should be ended up with a ASPEED_PECI_INT_CMD_DONE bit
> +        * set even in an error case.
> +        */
> +       if (status & ASPEED_PECI_INT_CMD_DONE)
> +               complete(&priv->xfer_complete);

Hmm, no need to check if there was a sequencing error, like a command
was never submitted?

> +
> +       spin_unlock(&priv->lock);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static void aspeed_peci_property_sanitize(struct device *dev, const char *propname,
> +                                         u32 min, u32 max, u32 default_val, u32 *propval)
> +{
> +       u32 val;
> +       int ret;
> +
> +       ret = device_property_read_u32(dev, propname, &val);
> +       if (ret) {
> +               val = default_val;
> +       } else if (val > max || val < min) {
> +               dev_warn(dev, "Invalid %s: %u, falling back to: %u\n",
> +                        propname, val, default_val);
> +
> +               val = default_val;
> +       }
> +
> +       *propval = val;
> +}
> +
> +static void aspeed_peci_property_setup(struct aspeed_peci *priv)
> +{
> +       aspeed_peci_property_sanitize(priv->dev, "aspeed,clock-divider",
> +                                     0, ASPEED_PECI_CLK_DIV_MAX,
> +                                     ASPEED_PECI_CLK_DIV_DEFAULT, &priv->clk_div);
> +       aspeed_peci_property_sanitize(priv->dev, "aspeed,msg-timing",
> +                                     0, ASPEED_PECI_MSG_TIMING_MAX,
> +                                     ASPEED_PECI_MSG_TIMING_DEFAULT, &priv->msg_timing);
> +       aspeed_peci_property_sanitize(priv->dev, "aspeed,addr-timing",
> +                                     0, ASPEED_PECI_ADDR_TIMING_MAX,
> +                                     ASPEED_PECI_ADDR_TIMING_DEFAULT, &priv->addr_timing);
> +       aspeed_peci_property_sanitize(priv->dev, "aspeed,rd-sampling-point",
> +                                     0, ASPEED_PECI_RD_SAMPLING_POINT_MAX,
> +                                     ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT,
> +                                     &priv->rd_sampling_point);
> +       aspeed_peci_property_sanitize(priv->dev, "cmd-timeout-ms",
> +                                     1, ASPEED_PECI_CMD_TIMEOUT_MS_MAX,
> +                                     ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT, &priv->cmd_timeout_ms);
> +}
> +
> +static struct peci_controller_ops aspeed_ops = {
> +       .xfer = aspeed_peci_xfer,
> +};
> +
> +static void aspeed_peci_reset_control_release(void *data)
> +{
> +       reset_control_assert(data);
> +}
> +
> +int aspeed_peci_reset_control_deassert(struct device *dev, struct reset_control *rst)

I'd recommend naming this devm_aspeed_peci_reset_control_deassert(),
because I came looking here from reading probe for why there was no
reassertion of reset on driver ->remove().

> +{
> +       int ret;
> +
> +       ret = reset_control_deassert(rst);
> +       if (ret)
> +               return ret;
> +
> +       return devm_add_action_or_reset(dev, aspeed_peci_reset_control_release, rst);
> +}
> +
> +static void aspeed_peci_clk_release(void *data)
> +{
> +       clk_disable_unprepare(data);
> +}
> +
> +static int aspeed_peci_clk_enable(struct device *dev, struct clk *clk)

...ditto on the devm prefix, just to speed readability.

> +{
> +       int ret;
> +
> +       ret = clk_prepare_enable(clk);
> +       if (ret)
> +               return ret;
> +
> +       return devm_add_action_or_reset(dev, aspeed_peci_clk_release, clk);
> +}
> +
> +static int aspeed_peci_probe(struct platform_device *pdev)
> +{
> +       struct peci_controller *controller;
> +       struct aspeed_peci *priv;
> +       int ret;
> +
> +       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       priv->dev = &pdev->dev;
> +       dev_set_drvdata(priv->dev, priv);
> +
> +       priv->base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(priv->base))
> +               return PTR_ERR(priv->base);
> +
> +       priv->irq = platform_get_irq(pdev, 0);
> +       if (!priv->irq)
> +               return priv->irq;
> +
> +       ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_peci_irq_handler,
> +                              0, "peci-aspeed", priv);
> +       if (ret)
> +               return ret;
> +
> +       init_completion(&priv->xfer_complete);
> +       spin_lock_init(&priv->lock);
> +
> +       priv->rst = devm_reset_control_get(&pdev->dev, NULL);
> +       if (IS_ERR(priv->rst))
> +               return dev_err_probe(priv->dev, PTR_ERR(priv->rst),
> +                                    "failed to get reset control\n");
> +
> +       ret = aspeed_peci_reset_control_deassert(priv->dev, priv->rst);
> +       if (ret)
> +               return dev_err_probe(priv->dev, ret, "cannot deassert reset control\n");
> +
> +       priv->clk = devm_clk_get(priv->dev, NULL);
> +       if (IS_ERR(priv->clk))
> +               return dev_err_probe(priv->dev, PTR_ERR(priv->clk), "failed to get clk\n");
> +
> +       ret = aspeed_peci_clk_enable(priv->dev, priv->clk);
> +       if (ret)
> +               return dev_err_probe(priv->dev, ret, "failed to enable clock\n");
> +
> +       aspeed_peci_property_setup(priv);
> +
> +       aspeed_peci_init_regs(priv);
> +
> +       controller = devm_peci_controller_add(priv->dev, &aspeed_ops);
> +       if (IS_ERR(controller))
> +               return dev_err_probe(priv->dev, PTR_ERR(controller),
> +                                    "failed to add aspeed peci controller\n");
> +
> +       priv->controller = controller;
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id aspeed_peci_of_table[] = {
> +       { .compatible = "aspeed,ast2400-peci", },
> +       { .compatible = "aspeed,ast2500-peci", },
> +       { .compatible = "aspeed,ast2600-peci", },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, aspeed_peci_of_table);
> +
> +static struct platform_driver aspeed_peci_driver = {
> +       .probe  = aspeed_peci_probe,
> +       .driver = {
> +               .name           = "peci-aspeed",
> +               .of_match_table = aspeed_peci_of_table,
> +       },
> +};
> +module_platform_driver(aspeed_peci_driver);
> +
> +MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
> +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
> +MODULE_DESCRIPTION("ASPEED PECI driver");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS(PECI);
> --
> 2.31.1
>


From wangkefeng.wang at huawei.com  Wed Aug 25 19:45:22 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Thu, 26 Aug 2021 10:45:22 +0800
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
 <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
Message-ID: <b5eb935f-26e1-6475-63af-e7f6101eb017@huawei.com>


On 2021/8/25 16:04, Saravana Kannan wrote:
> On Tue, Aug 24, 2021 at 9:05 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>
>> On 2021/8/25 4:08, Saravana Kannan wrote:
>>> On Tue, Aug 24, 2021 at 1:05 PM Rob Herring <robh+dt at kernel.org> wrote:
>>>> +Saravana
>>>>
>>>> Saravana mentioned to me there may be some issues with this one...
>>>>
>>>>
>>>> On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>>>> of_amba_device_create() uses irq_of_parse_and_map() to translate
>>>>> a DT interrupt specification into a Linux virtual interrupt number.
>>>>>
>>>>> But it doesn't properly handle the case where the interrupt controller
>>>>> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
>>>>> interrupt controller, because the mbigen initialization is too late,
>>>>> which will lead to no IRQ due to no IRQ domain found, log is shown below,
>>>>>     "irq: no irq domain found for uart0 !"
>>>>>
>>>>> use of_irq_get() to return -EPROBE_DEFER as above, and in the function
>>>>> amba_device_try_add()/amba_device_add(), it will properly handle in such
>>>>> case, also return 0 in other fail cases to be consistent as before.
>>>>>
>>>>> Cc: Russell King <linux at armlinux.org.uk>
>>>>> Cc: Rob Herring <robh+dt at kernel.org>
>>>>> Cc: Frank Rowand <frowand.list at gmail.com>
>>>>> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
>>>>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>>>>> ---
>>>>>    drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
>>>>>    drivers/of/platform.c |  6 +-----
>>>>>    2 files changed, 28 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
>>>>> index 36f2f42c8014..720aa6cdd402 100644
>>>>> --- a/drivers/amba/bus.c
>>>>> +++ b/drivers/amba/bus.c
>>>>> @@ -19,6 +19,7 @@
>>>>>    #include <linux/clk/clk-conf.h>
>>>>>    #include <linux/platform_device.h>
>>>>>    #include <linux/reset.h>
>>>>> +#include <linux/of_irq.h>
>>>>>
>>>>>    #include <asm/irq.h>
>>>>>
>>>>> @@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
>>>>>           kfree(d);
>>>>>    }
>>>>>
>>>>> +static int of_amba_device_decode_irq(struct amba_device *dev)
>>>>> +{
>>>>> +       struct device_node *node = dev->dev.of_node;
>>>>> +       int i, irq = 0;
>>>>> +
>>>>> +       if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
>>>>> +               /* Decode the IRQs and address ranges */
>>>>> +               for (i = 0; i < AMBA_NR_IRQS; i++) {
>>>>> +                       irq = of_irq_get(node, i);
>>>>> +                       if (irq < 0) {
>>>>> +                               if (irq == -EPROBE_DEFER)
>>>>> +                                       return irq;
>>>>> +                               irq = 0;
>>>>> +                       }
>>>>> +
>>>>> +                       dev->irq[i] = irq;
>>>>> +               }
>>>>> +       }
>>>>> +
>>>>> +       return 0;
>>>>> +}
>>>>> +
>>>>>    static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
>>>>>    {
>>>>>           u32 size;
>>>>>           void __iomem *tmp;
>>>>>           int i, ret;
>>>>>
>>>>> +       ret = of_amba_device_decode_irq(dev);
>>>>> +       if (ret)
>>>>> +               goto err_out;
>>>>> +
>>> Similar to other resources the AMBA bus "gets" for the device, I think
>>> this should be moved into amba_probe() and not here. There's no reason
>>> to delay the addition of the device (and loading its module) because
>>> the IRQ isn't ready yet.
>> The following code in the amba_device_try_add() will be called, it uses irq[0]
>> and irq[1], so I put of_amba_device_decode_irq() into amba_device_try_add().
>>
>> 470         if (dev->irq[0])
>> 471                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
>> 472         if (ret == 0 && dev->irq[1])
>> 473                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
>> 474         if (ret == 0)
>> 475                 return ret;
>>
>> of_amba_device_decode_irq() in amba_device_try_add() won't lead to issue,
>> only delay the device add, right?
> But delaying the device add is the issue. For example, adding a device
> could trigger the loading of the corresponding module using uevents.
> But now this change would delay that step. That can have other
> unintended consequences -- slowing down boot, what if the driver was
> working fine without the IRQ, etc.
>
>> If make it into amba_probe(), the above code should be moved too, could we
>> make a new patch to move both of them, or don't move them?
> I'd say move them both. If Russell hasn't already picked this up, then
> I'd say redo your Patch 3/3.
I will resend with put it into amba_probe.
>
> Btw, I've been working on [1] cleaning up the one-off deferred probe
> solution that we have for amba devices. That causes a bunch of other
> headaches. Your patch 3/3 takes us further in the wrong direction by
> adding more reasons for delaying the addition of the device.

Got it,? and I could resend all combine your patch(due to context conflict

when changing same function) if you no object.


>
> -Saravana
>
> [1] - https://lore.kernel.org/lkml/CAGETcx8b228nDUho3cX9AAQ-pXOfZTMv8cj2vhdx9yc_pk8q+A at mail.gmail.com/
> .
>


From chunfeng.yun at mediatek.com  Wed Aug 25 19:51:44 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 26 Aug 2021 10:51:44 +0800
Subject: [PATCH next v2 6/6] usb: xhci-mtk: allow bandwidth table rollover
In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
Message-ID: <20210826025144.51992-6-chunfeng.yun@mediatek.com>

xhci-mtk has 64 slots for periodic bandwidth calculations and each
slot represents byte budgets on a microframe. When an endpoint's
allocation sits on the boundary of the table, byte budgets' slot
can be rolled over but the current implementation doesn't.

This patch allows the microframe index rollover and prevent
out-of-bounds array access.

Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: new patch
---
 drivers/usb/host/xhci-mtk-sch.c | 51 +++++++++++----------------------
 drivers/usb/host/xhci-mtk.h     |  3 +-
 2 files changed, 18 insertions(+), 36 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index f3c6f078f82d..134f4789bd89 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -416,15 +416,14 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 {
 	u32 max_bw = 0;
 	u32 bw;
-	int i;
-	int j;
+	int i, j, k;
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		u32 base = offset + i * sch_ep->esit;
 
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
-			bw = sch_bw->bus_bw[base + j] +
-					sch_ep->bw_budget_table[j];
+			k = XHCI_MTK_BW_INDEX(base + j);
+			bw = sch_bw->bus_bw[k] + sch_ep->bw_budget_table[j];
 			if (bw > max_bw)
 				max_bw = bw;
 		}
@@ -436,18 +435,16 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	u32 base;
-	int i;
-	int j;
+	int i, j, k;
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			k = XHCI_MTK_BW_INDEX(base + j);
 			if (used)
-				sch_bw->bus_bw[base + j] +=
-					sch_ep->bw_budget_table[j];
+				sch_bw->bus_bw[k] += sch_ep->bw_budget_table[j];
 			else
-				sch_bw->bus_bw[base + j] -=
-					sch_ep->bw_budget_table[j];
+				sch_bw->bus_bw[k] -= sch_ep->bw_budget_table[j];
 		}
 	}
 }
@@ -457,7 +454,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
 	u32 tmp;
 	int base;
-	int i, j;
+	int i, j, k;
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = offset + i * sch_ep->esit;
@@ -467,7 +464,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 		 * the hub will always delay one uframe to send data
 		 */
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
-			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j];
+			k = XHCI_MTK_BW_INDEX(base + j);
+			tmp = tt->fs_bus_bw[k] + sch_ep->bw_budget_table[j];
 			if (tmp > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
 		}
@@ -542,16 +540,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
 	u32 base;
-	int i, j;
+	int i, j, k;
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 
-		for (j = 0; j < sch_ep->num_budget_microframes; j++)
+		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			k = XHCI_MTK_BW_INDEX(base + j);
 			if (used)
-				tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j];
+				tt->fs_bus_bw[k] += sch_ep->bw_budget_table[j];
 			else
-				tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j];
+				tt->fs_bus_bw[k] -= sch_ep->bw_budget_table[j];
+		}
 	}
 
 	if (used)
@@ -573,25 +573,9 @@ static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw,
 	return 0;
 }
 
-static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
-{
-	u32 boundary = sch_ep->esit;
-
-	if (sch_ep->sch_tt) { /* LS/FS with TT */
-		/* tune for CS */
-		if (sch_ep->ep_type != ISOC_OUT_EP)
-			boundary++;
-		else if (boundary > 1) /* normally esit >= 8 for FS/LS */
-			boundary--;
-	}
-
-	return boundary;
-}
-
 static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 {
 	struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info;
-	const u32 esit_boundary = get_esit_boundary(sch_ep);
 	const u32 bw_boundary = get_bw_boundary(sch_ep->speed);
 	u32 offset;
 	u32 worst_bw;
@@ -608,9 +592,6 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 		if (ret)
 			continue;
 
-		if ((offset + sch_ep->num_budget_microframes) > esit_boundary)
-			break;
-
 		worst_bw = get_max_bw(sch_bw, sch_ep, offset);
 		if (worst_bw > bw_boundary)
 			continue;
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index dc5e83f5c5cc..7cc0123eada0 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -25,7 +25,8 @@
  * round down to the limit value, that means allocating more
  * bandwidth to it.
  */
-#define XHCI_MTK_MAX_ESIT	64
+#define XHCI_MTK_MAX_ESIT	(1 << 6)
+#define XHCI_MTK_BW_INDEX(x)	((x) & (XHCI_MTK_MAX_ESIT - 1))
 
 /**
  * @fs_bus_bw: array to keep track of bandwidth already used for FS
-- 
2.18.0

From chunfeng.yun at mediatek.com  Wed Aug 25 19:51:41 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 26 Aug 2021 10:51:41 +0800
Subject: [PATCH next v2 3/6] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
Message-ID: <20210826025144.51992-3-chunfeng.yun@mediatek.com>

Use @bw_budget_table[] to update fs bus bandwidth due to
not all microframes consume @bw_cost_per_microframe, see
setup_sch_info().

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: new patch, move from another series
---
 drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index cffcaf4dfa9f..83abd28269ca 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 		 * Compared with hs bus, no matter what ep type,
 		 * the hub will always delay one uframe to send data
 		 */
-		for (j = 0; j < sch_ep->cs_count; j++) {
-			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
+		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j];
 			if (tmp > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
 		}
@@ -534,21 +534,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
 	u32 base, num_esit;
-	int bw_updated;
 	int i, j;
 
 	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
 
-	if (used)
-		bw_updated = sch_ep->bw_cost_per_microframe;
-	else
-		bw_updated = -sch_ep->bw_cost_per_microframe;
-
 	for (i = 0; i < num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 
-		for (j = 0; j < sch_ep->cs_count; j++)
-			tt->fs_bus_bw[base + j] += bw_updated;
+		for (j = 0; j < sch_ep->num_budget_microframes; j++)
+			if (used)
+				tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j];
+			else
+				tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j];
 	}
 
 	if (used)
-- 
2.18.0

From chunfeng.yun at mediatek.com  Wed Aug 25 19:51:43 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 26 Aug 2021 10:51:43 +0800
Subject: [PATCH next v2 5/6] usb: xhci-mtk: Do not use xhci's virt_dev in
 drop_endpoint
In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
Message-ID: <20210826025144.51992-5-chunfeng.yun@mediatek.com>

xhci-mtk depends on xhci's internal virt_dev when it retrieves its
internal data from usb_host_endpoint both in add_endpoint and
drop_endpoint callbacks. But when setup packet was retired by
transaction errors in xhci_setup_device() path, a virt_dev for the slot
is newly created with real_port 0. This leads to xhci-mtks's NULL pointer
dereference from drop_endpoint callback as xhci-mtk assumes that virt_dev's
real_port is always started from one. The similar problems were addressed
by [1] but that can't cover the failure cases from setup_device.

This patch drops the usages of xhci's virt_dev in xhci-mtk's drop_endpoint
callback by adopting hashtable for searching mtk's schedule entity
from a given usb_host_endpoint pointer instead of searching a linked list.
So mtk's drop_endpoint callback doesn't have to rely on virt_dev at all.

[1] f351f4b63dac ("usb: xhci-mtk: fix oops when unbind driver")

Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: use fixed size hash table instead of rhashtable;
    fix some issues as described in this series [2/6]
---
 drivers/usb/host/xhci-mtk-sch.c | 100 ++++++++++++++++----------------
 drivers/usb/host/xhci-mtk.h     |  11 +++-
 2 files changed, 60 insertions(+), 51 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 54c521524bfc..f3c6f078f82d 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -80,7 +80,7 @@ decode_ep(struct usb_host_endpoint *ep, enum usb_device_speed speed)
 		interval /= 1000;
 	}
 
-	snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s\n",
+	snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s",
 		 usb_speed_string(speed), usb_endpoint_num(epd),
 		 usb_endpoint_dir_in(epd) ? "in" : "out",
 		 usb_ep_type_string(usb_endpoint_type(epd)),
@@ -129,6 +129,10 @@ get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
 	int bw_index;
 
 	virt_dev = xhci->devs[udev->slot_id];
+	if (!virt_dev->real_port) {
+		WARN_ONCE(1, "%s invalid real_port\n", dev_name(&udev->dev));
+		return NULL;
+	}
 
 	if (udev->speed >= USB_SPEED_SUPER) {
 		if (usb_endpoint_dir_out(&ep->desc))
@@ -236,14 +240,20 @@ static void drop_tt(struct usb_device *udev)
 	}
 }
 
-static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
-	struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
+static struct mu3h_sch_ep_info *
+create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
+	      struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
 {
 	struct mu3h_sch_ep_info *sch_ep;
+	struct mu3h_sch_bw_info *bw_info;
 	struct mu3h_sch_tt *tt = NULL;
 	u32 len_bw_budget_table;
 	size_t mem_size;
 
+	bw_info = get_bw_info(mtk, udev, ep);
+	if (!bw_info)
+		return ERR_PTR(-ENODEV);
+
 	if (is_fs_or_ls(udev->speed))
 		len_bw_budget_table = TT_MICROFRAMES_MAX;
 	else if ((udev->speed >= USB_SPEED_SUPER)
@@ -266,11 +276,13 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
 		}
 	}
 
+	sch_ep->bw_info = bw_info;
 	sch_ep->sch_tt = tt;
 	sch_ep->ep = ep;
 	sch_ep->speed = udev->speed;
 	INIT_LIST_HEAD(&sch_ep->endpoint);
 	INIT_LIST_HEAD(&sch_ep->tt_endpoint);
+	INIT_HLIST_NODE(&sch_ep->hentry);
 
 	return sch_ep;
 }
@@ -576,9 +588,9 @@ static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
 	return boundary;
 }
 
-static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
-			struct mu3h_sch_ep_info *sch_ep)
+static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 {
+	struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info;
 	const u32 esit_boundary = get_esit_boundary(sch_ep);
 	const u32 bw_boundary = get_bw_boundary(sch_ep->speed);
 	u32 offset;
@@ -624,23 +636,26 @@ static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
 	return load_ep_bw(sch_bw, sch_ep, true);
 }
 
-static void destroy_sch_ep(struct usb_device *udev,
-	struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
+static void destroy_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
+			   struct mu3h_sch_ep_info *sch_ep)
 {
 	/* only release ep bw check passed by check_sch_bw() */
 	if (sch_ep->allocated)
-		load_ep_bw(sch_bw, sch_ep, false);
+		load_ep_bw(sch_ep->bw_info, sch_ep, false);
 
 	if (sch_ep->sch_tt)
 		drop_tt(udev);
 
 	list_del(&sch_ep->endpoint);
+	hlist_del(&sch_ep->hentry);
 	kfree(sch_ep);
 }
 
-static bool need_bw_sch(struct usb_host_endpoint *ep,
-	enum usb_device_speed speed, int has_tt)
+static bool need_bw_sch(struct usb_device *udev,
+			struct usb_host_endpoint *ep)
 {
+	bool has_tt = udev->tt && udev->tt->hub->parent;
+
 	/* only for periodic endpoints */
 	if (usb_endpoint_xfer_control(&ep->desc)
 		|| usb_endpoint_xfer_bulk(&ep->desc))
@@ -651,7 +666,7 @@ static bool need_bw_sch(struct usb_host_endpoint *ep,
 	 * a TT are also ignored, root-hub will schedule them directly,
 	 * but need set @bpkts field of endpoint context to 1.
 	 */
-	if (is_fs_or_ls(speed) && !has_tt)
+	if (is_fs_or_ls(udev->speed) && !has_tt)
 		return false;
 
 	/* skip endpoint with zero maxpkt */
@@ -666,7 +681,6 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 	struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd);
 	struct mu3h_sch_bw_info *sch_array;
 	int num_usb_bus;
-	int i;
 
 	/* ss IN and OUT are separated */
 	num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports;
@@ -675,12 +689,10 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 	if (sch_array == NULL)
 		return -ENOMEM;
 
-	for (i = 0; i < num_usb_bus; i++)
-		INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
-
 	mtk->sch_array = sch_array;
 
 	INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
+	hash_init(mtk->sch_ep_hash);
 
 	return 0;
 }
@@ -704,9 +716,7 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 	ep_index = xhci_get_endpoint_index(&ep->desc);
 	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
 
-	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
-
-	if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info)) {
+	if (!need_bw_sch(udev, ep)) {
 		/*
 		 * set @bpkts to 1 if it is LS or FS periodic endpoint, and its
 		 * device does not connected through an external HS hub
@@ -718,13 +728,16 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 		return 0;
 	}
 
-	sch_ep = create_sch_ep(udev, ep, ep_ctx);
+	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
+
+	sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx);
 	if (IS_ERR_OR_NULL(sch_ep))
 		return -ENOMEM;
 
 	setup_sch_info(ep_ctx, sch_ep);
 
 	list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list);
+	hash_add(mtk->sch_ep_hash, &sch_ep->hentry, (unsigned long)ep);
 
 	return 0;
 }
@@ -734,22 +747,18 @@ static void drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 {
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct xhci_virt_device *virt_dev;
-	struct mu3h_sch_bw_info *sch_bw;
-	struct mu3h_sch_ep_info *sch_ep, *tmp;
-
-	virt_dev = xhci->devs[udev->slot_id];
-
-	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
+	struct mu3h_sch_ep_info *sch_ep;
+	struct hlist_node *hn;
 
-	if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info))
+	if (!need_bw_sch(udev, ep))
 		return;
 
-	sch_bw = get_bw_info(mtk, udev, ep);
+	xhci_err(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
 
-	list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) {
+	hash_for_each_possible_safe(mtk->sch_ep_hash, sch_ep,
+				    hn, hentry, (unsigned long)ep) {
 		if (sch_ep->ep == ep) {
-			destroy_sch_ep(udev, sch_bw, sch_ep);
+			destroy_sch_ep(mtk, udev, sch_ep);
 			break;
 		}
 	}
@@ -760,30 +769,22 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 	struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
-	struct mu3h_sch_bw_info *sch_bw;
-	struct mu3h_sch_ep_info *sch_ep, *tmp;
+	struct mu3h_sch_ep_info *sch_ep;
 	int ret;
 
 	xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
 
 	list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) {
-		sch_bw = get_bw_info(mtk, udev, sch_ep->ep);
+		struct xhci_ep_ctx *ep_ctx;
+		struct usb_host_endpoint *ep = sch_ep->ep;
+		unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
 
-		ret = check_sch_bw(sch_bw, sch_ep);
+		ret = check_sch_bw(sch_ep);
 		if (ret) {
 			xhci_err(xhci, "Not enough bandwidth! (%s)\n",
 				 sch_error_string(-ret));
 			return -ENOSPC;
 		}
-	}
-
-	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
-		struct xhci_ep_ctx *ep_ctx;
-		struct usb_host_endpoint *ep = sch_ep->ep;
-		unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
-
-		sch_bw = get_bw_info(mtk, udev, ep);
-		list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
 
 		ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
 		ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(sch_ep->pkts)
@@ -797,22 +798,23 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 			sch_ep->offset, sch_ep->repeat);
 	}
 
-	return xhci_check_bandwidth(hcd, udev);
+	ret = xhci_check_bandwidth(hcd, udev);
+	if (!ret)
+		INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
+
+	return ret;
 }
 
 void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 {
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct mu3h_sch_bw_info *sch_bw;
 	struct mu3h_sch_ep_info *sch_ep, *tmp;
 
 	xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
 
-	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
-		sch_bw = get_bw_info(mtk, udev, sch_ep->ep);
-		destroy_sch_ep(udev, sch_bw, sch_ep);
-	}
+	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint)
+		destroy_sch_ep(mtk, udev, sch_ep);
 
 	xhci_reset_bandwidth(hcd, udev);
 }
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index eb05aaf6edbe..dc5e83f5c5cc 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -10,11 +10,15 @@
 #define _XHCI_MTK_H_
 
 #include <linux/clk.h>
+#include <linux/hashtable.h>
 
 #include "xhci.h"
 
 #define BULK_CLKS_NUM	5
 
+/* support at most 64 ep, use 32 size hash table */
+#define SCH_EP_HASH_BITS	5
+
 /**
  * To simplify scheduler algorithm, set a upper limit for ESIT,
  * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT,
@@ -36,14 +40,12 @@ struct mu3h_sch_tt {
  * struct mu3h_sch_bw_info: schedule information for bandwidth domain
  *
  * @bus_bw: array to keep track of bandwidth already used at each uframes
- * @bw_ep_list: eps in the bandwidth domain
  *
  * treat a HS root port as a bandwidth domain, but treat a SS root port as
  * two bandwidth domains, one for IN eps and another for OUT eps.
  */
 struct mu3h_sch_bw_info {
 	u32 bus_bw[XHCI_MTK_MAX_ESIT];
-	struct list_head bw_ep_list;
 };
 
 /**
@@ -54,8 +56,10 @@ struct mu3h_sch_bw_info {
  * @num_budget_microframes: number of continuous uframes
  *		(@repeat==1) scheduled within the interval
  * @bw_cost_per_microframe: bandwidth cost per microframe
+ * @hentry: hash table entry
  * @endpoint: linked into bandwidth domain which it belongs to
  * @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to
+ * @bw_info: bandwidth domain which this endpoint belongs
  * @sch_tt: mu3h_sch_tt linked into
  * @ep_type: endpoint type
  * @maxpkt: max packet size of endpoint
@@ -84,7 +88,9 @@ struct mu3h_sch_ep_info {
 	u32 num_budget_microframes;
 	u32 bw_cost_per_microframe;
 	struct list_head endpoint;
+	struct hlist_node hentry;
 	struct list_head tt_endpoint;
+	struct mu3h_sch_bw_info *bw_info;
 	struct mu3h_sch_tt *sch_tt;
 	u32 ep_type;
 	u32 maxpkt;
@@ -137,6 +143,7 @@ struct xhci_hcd_mtk {
 	struct usb_hcd *hcd;
 	struct mu3h_sch_bw_info *sch_array;
 	struct list_head bw_ep_chk_list;
+	DECLARE_HASHTABLE(sch_ep_hash, SCH_EP_HASH_BITS);
 	struct mu3c_ippc_regs __iomem *ippc_regs;
 	int num_u2_ports;
 	int num_u3_ports;
-- 
2.18.0

From chunfeng.yun at mediatek.com  Wed Aug 25 19:51:42 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 26 Aug 2021 10:51:42 +0800
Subject: [PATCH next v2 4/6] usb: xhci-mtk: add a member of num_esit
In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
Message-ID: <20210826025144.51992-4-chunfeng.yun@mediatek.com>

Add a member num_esit to save the number of esit, then no need
caculate it in some functions.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: new patch, move from another series
---
 drivers/usb/host/xhci-mtk-sch.c | 20 +++++++-------------
 drivers/usb/host/xhci-mtk.h     |  2 ++
 2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 83abd28269ca..54c521524bfc 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -297,6 +297,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 		 CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info));
 
 	sch_ep->esit = get_esit(ep_ctx);
+	sch_ep->num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
 	sch_ep->ep_type = ep_type;
 	sch_ep->maxpkt = maxpkt;
 	sch_ep->offset = 0;
@@ -401,14 +402,12 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx,
 static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, u32 offset)
 {
-	u32 num_esit;
 	u32 max_bw = 0;
 	u32 bw;
 	int i;
 	int j;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-	for (i = 0; i < num_esit; i++) {
+	for (i = 0; i < sch_ep->num_esit; i++) {
 		u32 base = offset + i * sch_ep->esit;
 
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
@@ -424,13 +423,11 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, bool used)
 {
-	u32 num_esit;
 	u32 base;
 	int i;
 	int j;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-	for (i = 0; i < num_esit; i++) {
+	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
 			if (used)
@@ -446,12 +443,11 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
-	u32 num_esit, tmp;
+	u32 tmp;
 	int base;
 	int i, j;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-	for (i = 0; i < num_esit; i++) {
+	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = offset + i * sch_ep->esit;
 
 		/*
@@ -533,12 +529,10 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset)
 static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
-	u32 base, num_esit;
+	u32 base;
 	int i, j;
 
-	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-
-	for (i = 0; i < num_esit; i++) {
+	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 
 		for (j = 0; j < sch_ep->num_budget_microframes; j++)
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index ace432356c41..eb05aaf6edbe 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -50,6 +50,7 @@ struct mu3h_sch_bw_info {
  * struct mu3h_sch_ep_info: schedule information for endpoint
  *
  * @esit: unit is 125us, equal to 2 << Interval field in ep-context
+ * @num_esit: number of @esit in a period
  * @num_budget_microframes: number of continuous uframes
  *		(@repeat==1) scheduled within the interval
  * @bw_cost_per_microframe: bandwidth cost per microframe
@@ -79,6 +80,7 @@ struct mu3h_sch_bw_info {
  */
 struct mu3h_sch_ep_info {
 	u32 esit;
+	u32 num_esit;
 	u32 num_budget_microframes;
 	u32 bw_cost_per_microframe;
 	struct list_head endpoint;
-- 
2.18.0

From chunfeng.yun at mediatek.com  Wed Aug 25 19:51:39 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 26 Aug 2021 10:51:39 +0800
Subject: [PATCH next v2 1/6] Revert "usb: xhci-mtk: relax TT periodic
 bandwidth allocation"
Message-ID: <20210826025144.51992-1-chunfeng.yun@mediatek.com>

As discussed in following patch:
https://patchwork.kernel.org/patch/12420339

No need calculate number of uframes again, but should use value
form check_sch_tt(), if we plan to remove extra CS, also can do
it in check_sch_tt(). So revert this patch, and prepare to send
new patch for it.

This reverts commit 548011957d1d72e0b662300c8b32b81d593b796e.

Cc: Ikjoon Jang <ikjn at chromium.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: no changes
---
 drivers/usb/host/xhci-mtk-sch.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index 46cbf5d54f4f..f9b4d27ce449 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -459,17 +459,16 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 	u32 num_esit, tmp;
 	int base;
 	int i, j;
-	u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
 
 	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
-
-	if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
-		offset++;
-
 	for (i = 0; i < num_esit; i++) {
 		base = offset + i * sch_ep->esit;
 
-		for (j = 0; j < uframes; j++) {
+		/*
+		 * Compared with hs bus, no matter what ep type,
+		 * the hub will always delay one uframe to send data
+		 */
+		for (j = 0; j < sch_ep->cs_count; j++) {
 			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
 			if (tmp > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
@@ -547,8 +546,6 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	u32 base, num_esit;
 	int bw_updated;
 	int i, j;
-	int offset = sch_ep->offset;
-	u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
 
 	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
 
@@ -557,13 +554,10 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	else
 		bw_updated = -sch_ep->bw_cost_per_microframe;
 
-	if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP)
-		offset++;
-
 	for (i = 0; i < num_esit; i++) {
-		base = offset + i * sch_ep->esit;
+		base = sch_ep->offset + i * sch_ep->esit;
 
-		for (j = 0; j < uframes; j++)
+		for (j = 0; j < sch_ep->cs_count; j++)
 			tt->fs_bus_bw[base + j] += bw_updated;
 	}
 
-- 
2.18.0

From chunfeng.yun at mediatek.com  Wed Aug 25 19:51:40 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 26 Aug 2021 10:51:40 +0800
Subject: [PATCH next v2 2/6] Revert "usb: xhci-mtk: Do not use xhci's virt_dev
 in drop_endpoint"
In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
Message-ID: <20210826025144.51992-2-chunfeng.yun@mediatek.com>

I find the patch introduce some issues, e.g.
1. oops happens when xhci_gen_setup() failed, and hash is not init
   but try to destroy it;
2. memory leakage happens when fail to insert ep, need free sch_ep,
   or insert ep after insert int list;
3. memory leakage happens when fail to allocate sch_array, need destroy
   rhashtable;
4. it's better to check ep->hcpriv when drop ep;

so prefer to revert this patch, and resend it after the issues are fixed.

This reverts commit b8731209958a1dffccc2888121f4c0280c990550.

Cc: Ikjoon Jang <ikjn at chromium.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: append new version patch of this one [5/6] suggested by Ikjoon
---
 drivers/usb/host/xhci-mtk-sch.c | 140 ++++++++++++++------------------
 drivers/usb/host/xhci-mtk.h     |  15 ++--
 2 files changed, 69 insertions(+), 86 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index f9b4d27ce449..cffcaf4dfa9f 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -80,7 +80,7 @@ decode_ep(struct usb_host_endpoint *ep, enum usb_device_speed speed)
 		interval /= 1000;
 	}
 
-	snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s",
+	snprintf(buf, DBG_BUF_EN, "%s ep%d%s %s, mpkt:%d, interval:%d/%d%s\n",
 		 usb_speed_string(speed), usb_endpoint_num(epd),
 		 usb_endpoint_dir_in(epd) ? "in" : "out",
 		 usb_ep_type_string(usb_endpoint_type(epd)),
@@ -129,12 +129,6 @@ get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
 	int bw_index;
 
 	virt_dev = xhci->devs[udev->slot_id];
-	if (WARN_ONCE(!virt_dev, "xhci-mtk: usb %s has no virt_dev\n",
-				dev_name(&udev->dev)))
-		return NULL;
-	if (WARN_ONCE(!virt_dev->real_port, "xhci-mtk: usb %s has invalid port number\n",
-			dev_name(&udev->dev)))
-		return NULL;
 
 	if (udev->speed >= USB_SPEED_SUPER) {
 		if (usb_endpoint_dir_out(&ep->desc))
@@ -200,6 +194,7 @@ static struct mu3h_sch_tt *find_tt(struct usb_device *udev)
 			}
 			return ERR_PTR(-ENOMEM);
 		}
+		INIT_LIST_HEAD(&tt->ep_list);
 		*ptt = tt;
 	}
 
@@ -229,7 +224,7 @@ static void drop_tt(struct usb_device *udev)
 	}
 
 	tt = *ptt;
-	if (!tt || tt->nr_eps > 0)
+	if (!tt || !list_empty(&tt->ep_list))
 		return;		/* never allocated , or still in use*/
 
 	*ptt = NULL;
@@ -241,19 +236,13 @@ static void drop_tt(struct usb_device *udev)
 	}
 }
 
-static struct mu3h_sch_ep_info *create_sch_ep(struct xhci_hcd_mtk *mtk,
-		struct usb_device *udev, struct usb_host_endpoint *ep,
-		struct xhci_ep_ctx *ep_ctx)
+static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
+	struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
 {
 	struct mu3h_sch_ep_info *sch_ep;
 	struct mu3h_sch_tt *tt = NULL;
 	u32 len_bw_budget_table;
 	size_t mem_size;
-	struct mu3h_sch_bw_info *bw_info;
-
-	bw_info = get_bw_info(mtk, udev, ep);
-	if (!bw_info)
-		return ERR_PTR(-ENODEV);
 
 	if (is_fs_or_ls(udev->speed))
 		len_bw_budget_table = TT_MICROFRAMES_MAX;
@@ -277,10 +266,11 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct xhci_hcd_mtk *mtk,
 		}
 	}
 
-	sch_ep->bw_info = bw_info;
 	sch_ep->sch_tt = tt;
 	sch_ep->ep = ep;
 	sch_ep->speed = udev->speed;
+	INIT_LIST_HEAD(&sch_ep->endpoint);
+	INIT_LIST_HEAD(&sch_ep->tt_endpoint);
 
 	return sch_ep;
 }
@@ -562,9 +552,9 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 	}
 
 	if (used)
-		tt->nr_eps++;
-	else if (!WARN_ONCE(tt->nr_eps < 1, "unbalanced sch_tt's ep count"))
-		tt->nr_eps--;
+		list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list);
+	else
+		list_del(&sch_ep->tt_endpoint);
 }
 
 static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw,
@@ -595,9 +585,9 @@ static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
 	return boundary;
 }
 
-static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
+static int check_sch_bw(struct mu3h_sch_bw_info *sch_bw,
+			struct mu3h_sch_ep_info *sch_ep)
 {
-	struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info;
 	const u32 esit_boundary = get_esit_boundary(sch_ep);
 	const u32 bw_boundary = get_bw_boundary(sch_ep->speed);
 	u32 offset;
@@ -643,33 +633,23 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 	return load_ep_bw(sch_bw, sch_ep, true);
 }
 
-static const struct rhashtable_params sch_ep_table_param = {
-	.key_len	= sizeof(struct usb_host_endpoint *),
-	.key_offset	= offsetof(struct mu3h_sch_ep_info, ep),
-	.head_offset	= offsetof(struct mu3h_sch_ep_info, ep_link),
-};
-
-static void destroy_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
-			   struct mu3h_sch_ep_info *sch_ep)
+static void destroy_sch_ep(struct usb_device *udev,
+	struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
 {
 	/* only release ep bw check passed by check_sch_bw() */
 	if (sch_ep->allocated)
-		load_ep_bw(sch_ep->bw_info, sch_ep, false);
+		load_ep_bw(sch_bw, sch_ep, false);
 
 	if (sch_ep->sch_tt)
 		drop_tt(udev);
 
 	list_del(&sch_ep->endpoint);
-	rhashtable_remove_fast(&mtk->sch_ep_table, &sch_ep->ep_link,
-				sch_ep_table_param);
 	kfree(sch_ep);
 }
 
-static bool need_bw_sch(struct usb_device *udev,
-			struct usb_host_endpoint *ep)
+static bool need_bw_sch(struct usb_host_endpoint *ep,
+	enum usb_device_speed speed, int has_tt)
 {
-	bool has_tt = udev->tt && udev->tt->hub->parent;
-
 	/* only for periodic endpoints */
 	if (usb_endpoint_xfer_control(&ep->desc)
 		|| usb_endpoint_xfer_bulk(&ep->desc))
@@ -680,7 +660,7 @@ static bool need_bw_sch(struct usb_device *udev,
 	 * a TT are also ignored, root-hub will schedule them directly,
 	 * but need set @bpkts field of endpoint context to 1.
 	 */
-	if (is_fs_or_ls(udev->speed) && !has_tt)
+	if (is_fs_or_ls(speed) && !has_tt)
 		return false;
 
 	/* skip endpoint with zero maxpkt */
@@ -695,12 +675,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 	struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd);
 	struct mu3h_sch_bw_info *sch_array;
 	int num_usb_bus;
-	int ret;
-
-	/* mu3h_sch_ep_info table, 'usb_host_endpoint*' as a key */
-	ret = rhashtable_init(&mtk->sch_ep_table, &sch_ep_table_param);
-	if (ret)
-		return ret;
+	int i;
 
 	/* ss IN and OUT are separated */
 	num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports;
@@ -709,6 +684,9 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 	if (sch_array == NULL)
 		return -ENOMEM;
 
+	for (i = 0; i < num_usb_bus; i++)
+		INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
+
 	mtk->sch_array = sch_array;
 
 	INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
@@ -718,7 +696,6 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
 
 void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk)
 {
-	rhashtable_destroy(&mtk->sch_ep_table);
 	kfree(mtk->sch_array);
 }
 
@@ -736,7 +713,9 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 	ep_index = xhci_get_endpoint_index(&ep->desc);
 	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
 
-	if (!need_bw_sch(udev, ep)) {
+	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
+
+	if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info)) {
 		/*
 		 * set @bpkts to 1 if it is LS or FS periodic endpoint, and its
 		 * device does not connected through an external HS hub
@@ -748,22 +727,14 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 		return 0;
 	}
 
-	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
-
-	sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx);
+	sch_ep = create_sch_ep(udev, ep, ep_ctx);
 	if (IS_ERR_OR_NULL(sch_ep))
 		return -ENOMEM;
 
-	if (rhashtable_insert_fast(&mtk->sch_ep_table, &sch_ep->ep_link,
-				   sch_ep_table_param))
-		return -EEXIST;
-
 	setup_sch_info(ep_ctx, sch_ep);
 
 	list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list);
 
-	xhci_dbg(xhci, "added sch_ep %p : %p\n", sch_ep, ep);
-
 	return 0;
 }
 
@@ -772,20 +743,25 @@ static void drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
 {
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
-	struct mu3h_sch_ep_info *sch_ep;
-	void *key = ep;
+	struct xhci_virt_device *virt_dev;
+	struct mu3h_sch_bw_info *sch_bw;
+	struct mu3h_sch_ep_info *sch_ep, *tmp;
 
-	if (!need_bw_sch(udev, ep))
-		return;
+	virt_dev = xhci->devs[udev->slot_id];
 
 	xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed));
 
-	sch_ep = rhashtable_lookup_fast(&mtk->sch_ep_table, &key,
-					sch_ep_table_param);
-	if (sch_ep)
-		destroy_sch_ep(mtk, udev, sch_ep);
-	else
-		xhci_dbg(xhci, "ep %p is not on the bw table\n", ep);
+	if (!need_bw_sch(ep, udev->speed, !!virt_dev->tt_info))
+		return;
+
+	sch_bw = get_bw_info(mtk, udev, ep);
+
+	list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) {
+		if (sch_ep->ep == ep) {
+			destroy_sch_ep(udev, sch_bw, sch_ep);
+			break;
+		}
+	}
 }
 
 int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
@@ -793,22 +769,30 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
 	struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];
-	struct mu3h_sch_ep_info *sch_ep;
+	struct mu3h_sch_bw_info *sch_bw;
+	struct mu3h_sch_ep_info *sch_ep, *tmp;
 	int ret;
 
 	xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
 
 	list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) {
-		struct xhci_ep_ctx *ep_ctx;
-		struct usb_host_endpoint *ep = sch_ep->ep;
-		unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
+		sch_bw = get_bw_info(mtk, udev, sch_ep->ep);
 
-		ret = check_sch_bw(sch_ep);
+		ret = check_sch_bw(sch_bw, sch_ep);
 		if (ret) {
 			xhci_err(xhci, "Not enough bandwidth! (%s)\n",
 				 sch_error_string(-ret));
 			return -ENOSPC;
 		}
+	}
+
+	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
+		struct xhci_ep_ctx *ep_ctx;
+		struct usb_host_endpoint *ep = sch_ep->ep;
+		unsigned int ep_index = xhci_get_endpoint_index(&ep->desc);
+
+		sch_bw = get_bw_info(mtk, udev, ep);
+		list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
 
 		ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
 		ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(sch_ep->pkts)
@@ -822,23 +806,22 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 			sch_ep->offset, sch_ep->repeat);
 	}
 
-	ret = xhci_check_bandwidth(hcd, udev);
-	if (!ret)
-		INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
-
-	return ret;
+	return xhci_check_bandwidth(hcd, udev);
 }
 
 void xhci_mtk_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
 {
 	struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+	struct mu3h_sch_bw_info *sch_bw;
 	struct mu3h_sch_ep_info *sch_ep, *tmp;
 
 	xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev));
 
-	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint)
-		destroy_sch_ep(mtk, udev, sch_ep);
+	list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) {
+		sch_bw = get_bw_info(mtk, udev, sch_ep->ep);
+		destroy_sch_ep(udev, sch_bw, sch_ep);
+	}
 
 	xhci_reset_bandwidth(hcd, udev);
 }
@@ -867,7 +850,8 @@ int xhci_mtk_drop_ep(struct usb_hcd *hcd, struct usb_device *udev,
 	if (ret)
 		return ret;
 
-	drop_ep_quirk(hcd, udev, ep);
+	if (ep->hcpriv)
+		drop_ep_quirk(hcd, udev, ep);
 
 	return 0;
 }
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index ddcf25524f67..ace432356c41 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -10,7 +10,6 @@
 #define _XHCI_MTK_H_
 
 #include <linux/clk.h>
-#include <linux/rhashtable.h>
 
 #include "xhci.h"
 
@@ -26,34 +25,36 @@
 
 /**
  * @fs_bus_bw: array to keep track of bandwidth already used for FS
- * @nr_eps: number of endpoints using this TT
+ * @ep_list: Endpoints using this TT
  */
 struct mu3h_sch_tt {
 	u32 fs_bus_bw[XHCI_MTK_MAX_ESIT];
-	int nr_eps;
+	struct list_head ep_list;
 };
 
 /**
  * struct mu3h_sch_bw_info: schedule information for bandwidth domain
  *
  * @bus_bw: array to keep track of bandwidth already used at each uframes
+ * @bw_ep_list: eps in the bandwidth domain
  *
  * treat a HS root port as a bandwidth domain, but treat a SS root port as
  * two bandwidth domains, one for IN eps and another for OUT eps.
  */
 struct mu3h_sch_bw_info {
 	u32 bus_bw[XHCI_MTK_MAX_ESIT];
+	struct list_head bw_ep_list;
 };
 
 /**
  * struct mu3h_sch_ep_info: schedule information for endpoint
  *
- * @bw_info: bandwidth domain which this endpoint belongs
  * @esit: unit is 125us, equal to 2 << Interval field in ep-context
  * @num_budget_microframes: number of continuous uframes
  *		(@repeat==1) scheduled within the interval
  * @bw_cost_per_microframe: bandwidth cost per microframe
- * @endpoint: linked into bw_ep_chk_list, used by check_bandwidth hook
+ * @endpoint: linked into bandwidth domain which it belongs to
+ * @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to
  * @sch_tt: mu3h_sch_tt linked into
  * @ep_type: endpoint type
  * @maxpkt: max packet size of endpoint
@@ -81,12 +82,11 @@ struct mu3h_sch_ep_info {
 	u32 num_budget_microframes;
 	u32 bw_cost_per_microframe;
 	struct list_head endpoint;
-	struct mu3h_sch_bw_info *bw_info;
+	struct list_head tt_endpoint;
 	struct mu3h_sch_tt *sch_tt;
 	u32 ep_type;
 	u32 maxpkt;
 	struct usb_host_endpoint *ep;
-	struct rhash_head ep_link;
 	enum usb_device_speed speed;
 	bool allocated;
 	/*
@@ -134,7 +134,6 @@ struct xhci_hcd_mtk {
 	struct device *dev;
 	struct usb_hcd *hcd;
 	struct mu3h_sch_bw_info *sch_array;
-	struct rhashtable sch_ep_table;
 	struct list_head bw_ep_chk_list;
 	struct mu3c_ippc_regs __iomem *ippc_regs;
 	int num_u2_ports;
-- 
2.18.0

From tobetter at gmail.com  Wed Aug 25 20:28:32 2021
From: tobetter at gmail.com (Dongjin Kim)
Date: Thu, 26 Aug 2021 12:28:32 +0900
Subject: [PATCH] arm64: dts: meson: sm1: add Ethernet PHY reset line for
 ODROID-C4/HC4
Message-ID: <YScKYFWlYymgGw3l@anyang-linuxfactory-or-kr>

This patch is to fix an issue that the ethernet link doesn't come up
when using ip link set down/up:
   [   11.428114] meson8b-dwmac ff3f0000.ethernet eth0: Link is Down
   [   14.428595] meson8b-dwmac ff3f0000.ethernet eth0: PHY [0.0:00] driver [RTL8211F Gigabit Ethernet] (irq=31)
   [   14.428610] meson8b-dwmac ff3f0000.ethernet: Failed to reset the dma
   [   14.428974] meson8b-dwmac ff3f0000.ethernet eth0: stmmac_hw_setup: DMA engine initialization failed
   [   14.711185] meson8b-dwmac ff3f0000.ethernet eth0: stmmac_open: Hw setup failed

This fix has been referred two commits applied for ODROID-N2 (G12B).
    commit 658e4129bb81 ("arm64: dts: meson: g12b: odroid-n2: add the Ethernet PHY reset line")
    commit 1c7412530d5d0 ("arm64: dts: meson: g12b: odroid-n2: fix PHY deassert timing requirements")

Signed-off-by: Dongjin Kim <tobetter at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index d14716b3d0f1..1230beba04aa 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -256,6 +256,10 @@ external_phy: ethernet-phy at 0 {
 		reg = <0>;
 		max-speed = <1000>;
 
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
 		interrupt-parent = <&gpio_intc>;
 		/* MAC_INTR on GPIOZ_14 */
 		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
-- 
2.30.2



From nobuhiro1.iwamatsu at toshiba.co.jp  Wed Aug 25 21:25:28 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (nobuhiro1.iwamatsu at toshiba.co.jp)
Date: Thu, 26 Aug 2021 04:25:28 +0000
Subject: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <TYAPR01MB625257B58932922E355C988292C79@TYAPR01MB6252.jpnprd01.prod.outlook.com>

Hi,

Do you have any comments on this patch series?
If there is no problem, please apply it into the pci tree.

Best regards,
  Nobuhiro

> -----Original Message-----
> From: Nobuhiro Iwamatsu [mailto:nobuhiro1.iwamatsu at toshiba.co.jp]
> Sent: Wednesday, August 11, 2021 5:38 PM
> To: Bjorn Helgaas <bhelgaas at google.com>; Rob Herring <robh+dt at kernel.org>; Lorenzo Pieralisi
> <lorenzo.pieralisi at arm.com>
> Cc: linux-pci at vger.kernel.org; Krzysztof Wilczy?ski <kw at linux.com>; Kishon Vijay Abraham I <kishon at ti.com>;
> devicetree at vger.kernel.org; agrawal punit(????? ??? ????????) <punit1.agrawal at toshiba.co.jp>;
> ishikawa yuji(?? ?? ?????????????) <yuji2.ishikawa at toshiba.co.jp>;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; iwamatsu nobuhiro(?? ?? ????????)
> <nobuhiro1.iwamatsu at toshiba.co.jp>
> Subject: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host controller driver
> 
> Hi,
> 
> This series is the PCIe driver for Toshiba's ARM SoC, Visconti[0].
> This provides DT binding documentation, device driver, MAINTAINER files.
> 
> Best regards,
>   Nobuhiro
> 
> [0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html
> 
>   dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
>     v5 -> v6:
>       - No update.
>     v4 -> v5:
>       - No update.
>     v3 -> v4:
>      - Changed the redundant clock name.
>     v2 -> v3:
>       - No update.
>     v1 -> v2:
>       - Remove white space.
>       - Drop num-viewport and bus-range from required.
>       - Drop status line from example.
>       - Drop bus-range from required.
>       - Removed lines defined in pci-bus.yaml from required.
> 
>   PCI: visconti: Add Toshiba Visconti PCIe host controller driver
>     v5 -> v6:
> - Remove unnecessary commit log.
> - Fix split line of visconti_add_pcie_port()
>     v4 -> v5:
>       - Remove PCIE_BUS_OFFSET
>       - Change link_up confirmation function of visconti_pcie_link_up().
>       - Move setting event mask before dw_pcie_link_up().
>       - Move the contents of visconti_pcie_power_on() to visconti_pcie_host_init().
>       - Remove code for link_gen.
>     v3 -> v4:
>       - Change variable from pci_addr to cpu_addr in visconti_pcie_cpu_addr_fixup().
>       - Change the calculation method of CPU addres from subtraction to mask, and
>         add comment.
>       - Drop dma_set_mask_and_coherent().
>       - Drop set MAX_MSI_IRQS.
>       - Drop dev_dbg for Link speed.
>       - Use use the dev_err_probe() to handle the devm_clk_get() failed.
>       - Changed the redundant clock name.
>     v2 -> v3:
>       - Update subject.
>       - Wrap description in 75 columns.
>       - Change config name to PCIE_VISCONTI_HOST.
>       - Update Kconfig text.
>       - Drop empty lines.
>       - Adjusted to 80 columns.
>       - Drop inline from functions for register access.
>       - Changed function name from visconti_pcie_check_link_status to
>         visconti_pcie_link_up.
>       - Update to using dw_pcie_host_init().
>       - Reorder these in the order of use in visconti_pcie_establish_link().
>       - Rewrite visconti_pcie_host_init() without dw_pcie_setup_rc().
>       - Change function name from  visconti_device_turnon() to
>         visconti_pcie_power_on().
>       - Unify formats such as dev_err().
>       - Drop error label in visconti_add_pcie_port().
>     v1 -> v2:
>       - Fix typo in commit message.
>       - Drop "depends on OF && HAS_IOMEM" from Kconfig.
>       - Stop using the pointer of struct dw_pcie.
>       - Use _relaxed variant.
>       - Drop dw_pcie_wait_for_link.
>       - Drop dbi resource processing.
>       - Drop MSI IRQ initialization processing.
> 
>   MAINTAINERS: Add entries for Toshiba Visconti PCIe controller
>     v5 -> v6:
>       - No update.
>     v4 -> v5:
>       - No update.
>     v3 -> v4:
>       - No update.
>     v2 -> v3:
>       - No update.
>     v1 -> v2:
>       - No update.
> 
> Nobuhiro Iwamatsu (3):
>   dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
>   PCI: visconti: Add Toshiba Visconti PCIe host controller driver
>   MAINTAINERS: Add entries for Toshiba Visconti PCIe controller
> 
>  .../bindings/pci/toshiba,visconti-pcie.yaml   | 110 ++++++
>  MAINTAINERS                                   |   2 +
>  drivers/pci/controller/dwc/Kconfig            |   9 +
>  drivers/pci/controller/dwc/Makefile           |   1 +
>  drivers/pci/controller/dwc/pcie-visconti.c    | 333 ++++++++++++++++++
>  5 files changed, 455 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
>  create mode 100644 drivers/pci/controller/dwc/pcie-visconti.c
> 
> --
> 2.32.0

From saravanak at google.com  Wed Aug 25 21:45:40 2021
From: saravanak at google.com (Saravana Kannan)
Date: Wed, 25 Aug 2021 21:45:40 -0700
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <b5eb935f-26e1-6475-63af-e7f6101eb017@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
 <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
 <b5eb935f-26e1-6475-63af-e7f6101eb017@huawei.com>
Message-ID: <CAGETcx9yaWZOzt=gcyNAshoHdPoYizhmrKS-kU9c2QM2+HqeEw@mail.gmail.com>

On Wed, Aug 25, 2021 at 7:45 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
>
> On 2021/8/25 16:04, Saravana Kannan wrote:
> > On Tue, Aug 24, 2021 at 9:05 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> >>
> >> On 2021/8/25 4:08, Saravana Kannan wrote:
> >>> On Tue, Aug 24, 2021 at 1:05 PM Rob Herring <robh+dt at kernel.org> wrote:
> >>>> +Saravana
> >>>>
> >>>> Saravana mentioned to me there may be some issues with this one...
> >>>>
> >>>>
> >>>> On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> >>>>> of_amba_device_create() uses irq_of_parse_and_map() to translate
> >>>>> a DT interrupt specification into a Linux virtual interrupt number.
> >>>>>
> >>>>> But it doesn't properly handle the case where the interrupt controller
> >>>>> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
> >>>>> interrupt controller, because the mbigen initialization is too late,
> >>>>> which will lead to no IRQ due to no IRQ domain found, log is shown below,
> >>>>>     "irq: no irq domain found for uart0 !"
> >>>>>
> >>>>> use of_irq_get() to return -EPROBE_DEFER as above, and in the function
> >>>>> amba_device_try_add()/amba_device_add(), it will properly handle in such
> >>>>> case, also return 0 in other fail cases to be consistent as before.
> >>>>>
> >>>>> Cc: Russell King <linux at armlinux.org.uk>
> >>>>> Cc: Rob Herring <robh+dt at kernel.org>
> >>>>> Cc: Frank Rowand <frowand.list at gmail.com>
> >>>>> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
> >>>>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> >>>>> ---
> >>>>>    drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
> >>>>>    drivers/of/platform.c |  6 +-----
> >>>>>    2 files changed, 28 insertions(+), 5 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> >>>>> index 36f2f42c8014..720aa6cdd402 100644
> >>>>> --- a/drivers/amba/bus.c
> >>>>> +++ b/drivers/amba/bus.c
> >>>>> @@ -19,6 +19,7 @@
> >>>>>    #include <linux/clk/clk-conf.h>
> >>>>>    #include <linux/platform_device.h>
> >>>>>    #include <linux/reset.h>
> >>>>> +#include <linux/of_irq.h>
> >>>>>
> >>>>>    #include <asm/irq.h>
> >>>>>
> >>>>> @@ -371,12 +372,38 @@ static void amba_device_release(struct device *dev)
> >>>>>           kfree(d);
> >>>>>    }
> >>>>>
> >>>>> +static int of_amba_device_decode_irq(struct amba_device *dev)
> >>>>> +{
> >>>>> +       struct device_node *node = dev->dev.of_node;
> >>>>> +       int i, irq = 0;
> >>>>> +
> >>>>> +       if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
> >>>>> +               /* Decode the IRQs and address ranges */
> >>>>> +               for (i = 0; i < AMBA_NR_IRQS; i++) {
> >>>>> +                       irq = of_irq_get(node, i);
> >>>>> +                       if (irq < 0) {
> >>>>> +                               if (irq == -EPROBE_DEFER)
> >>>>> +                                       return irq;
> >>>>> +                               irq = 0;
> >>>>> +                       }
> >>>>> +
> >>>>> +                       dev->irq[i] = irq;
> >>>>> +               }
> >>>>> +       }
> >>>>> +
> >>>>> +       return 0;
> >>>>> +}
> >>>>> +
> >>>>>    static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
> >>>>>    {
> >>>>>           u32 size;
> >>>>>           void __iomem *tmp;
> >>>>>           int i, ret;
> >>>>>
> >>>>> +       ret = of_amba_device_decode_irq(dev);
> >>>>> +       if (ret)
> >>>>> +               goto err_out;
> >>>>> +
> >>> Similar to other resources the AMBA bus "gets" for the device, I think
> >>> this should be moved into amba_probe() and not here. There's no reason
> >>> to delay the addition of the device (and loading its module) because
> >>> the IRQ isn't ready yet.
> >> The following code in the amba_device_try_add() will be called, it uses irq[0]
> >> and irq[1], so I put of_amba_device_decode_irq() into amba_device_try_add().
> >>
> >> 470         if (dev->irq[0])
> >> 471                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
> >> 472         if (ret == 0 && dev->irq[1])
> >> 473                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
> >> 474         if (ret == 0)
> >> 475                 return ret;
> >>
> >> of_amba_device_decode_irq() in amba_device_try_add() won't lead to issue,
> >> only delay the device add, right?
> > But delaying the device add is the issue. For example, adding a device
> > could trigger the loading of the corresponding module using uevents.
> > But now this change would delay that step. That can have other
> > unintended consequences -- slowing down boot, what if the driver was
> > working fine without the IRQ, etc.
> >
> >> If make it into amba_probe(), the above code should be moved too, could we
> >> make a new patch to move both of them, or don't move them?
> > I'd say move them both. If Russell hasn't already picked this up, then
> > I'd say redo your Patch 3/3.
> I will resend with put it into amba_probe.
> >
> > Btw, I've been working on [1] cleaning up the one-off deferred probe
> > solution that we have for amba devices. That causes a bunch of other
> > headaches. Your patch 3/3 takes us further in the wrong direction by
> > adding more reasons for delaying the addition of the device.
>
> Got it,  and I could resend all combine your patch(due to context conflict
>
> when changing same function) if you no object.

If you want to resolve the conflict with my patch and resend it while
keeping me as the author, I would definitely appreciate it.

-Saravana
>
>
> >
> > -Saravana
> >
> > [1] - https://lore.kernel.org/lkml/CAGETcx8b228nDUho3cX9AAQ-pXOfZTMv8cj2vhdx9yc_pk8q+A at mail.gmail.com/
> > .
> >


From madvenka at linux.microsoft.com  Wed Aug 25 21:52:42 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Wed, 25 Aug 2021 23:52:42 -0500
Subject: [RFC PATCH v8 1/4] arm64: Make all stack walking functions use
 arch_stack_walk()
In-Reply-To: <20210824131344.GE96738@C02TD0UTHF1T.local>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-2-madvenka@linux.microsoft.com>
 <20210824131344.GE96738@C02TD0UTHF1T.local>
Message-ID: <406f7960-b7d8-f058-d055-7ca373689fba@linux.microsoft.com>

Hi Mark Rutland, Mark Brown,

Do you have any comments on the reliability part of the patch series?

Madhavan

On 8/24/21 8:13 AM, Mark Rutland wrote:
> On Thu, Aug 12, 2021 at 02:06:00PM -0500, madvenka at linux.microsoft.com wrote:
>> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
>>
>> Currently, there are multiple functions in ARM64 code that walk the
>> stack using start_backtrace() and unwind_frame(). Convert all of
>> them to use arch_stack_walk(). This makes maintenance easier.
> 
> It would be good to split this into a series of patches as Mark Brown
> suggested in v7.
> 
>> Here is the list of functions:
>>
>> 	perf_callchain_kernel()
>> 	get_wchan()
>> 	return_address()
>> 	dump_backtrace()
>> 	profile_pc()
> 
> Note that arch_stack_walk() depends on CONFIG_STACKTRACE (which is not in
> defconfig), so we'll need to reorganise things such that it's always defined,
> or factor out the core of that function and add a wrapper such that we
> can always use it.
> 
>> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
>> ---
>>  arch/arm64/include/asm/stacktrace.h |  3 ---
>>  arch/arm64/kernel/perf_callchain.c  |  5 +---
>>  arch/arm64/kernel/process.c         | 39 ++++++++++++++++++-----------
>>  arch/arm64/kernel/return_address.c  |  6 +----
>>  arch/arm64/kernel/stacktrace.c      | 38 +++-------------------------
>>  arch/arm64/kernel/time.c            | 22 +++++++++-------
>>  6 files changed, 43 insertions(+), 70 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
>> index 8aebc00c1718..e43dea1c6b41 100644
>> --- a/arch/arm64/include/asm/stacktrace.h
>> +++ b/arch/arm64/include/asm/stacktrace.h
>> @@ -61,9 +61,6 @@ struct stackframe {
>>  #endif
>>  };
>>  
>> -extern int unwind_frame(struct task_struct *tsk, struct stackframe *frame);
>> -extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
>> -			    bool (*fn)(void *, unsigned long), void *data);
>>  extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>>  			   const char *loglvl);
>>  
>> diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
>> index 4a72c2727309..2f289013c9c9 100644
>> --- a/arch/arm64/kernel/perf_callchain.c
>> +++ b/arch/arm64/kernel/perf_callchain.c
>> @@ -147,15 +147,12 @@ static bool callchain_trace(void *data, unsigned long pc)
>>  void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
>>  			   struct pt_regs *regs)
>>  {
>> -	struct stackframe frame;
>> -
>>  	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
>>  		/* We don't support guest os callchain now */
>>  		return;
>>  	}
>>  
>> -	start_backtrace(&frame, regs->regs[29], regs->pc);
>> -	walk_stackframe(current, &frame, callchain_trace, entry);
>> +	arch_stack_walk(callchain_trace, entry, current, regs);
>>  }
> 
> We can also update callchain_trace take the return value of
> perf_callchain_store into acount, e.g.
> 
> | static bool callchain_trace(void *data, unsigned long pc) 
> | {
> | 	struct perf_callchain_entry_ctx *entry = data;
> | 	return perf_callchain_store(entry, pc) == 0;
> | }
> 
>>  
>>  unsigned long perf_instruction_pointer(struct pt_regs *regs)
>> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
>> index c8989b999250..52c12fd26407 100644
>> --- a/arch/arm64/kernel/process.c
>> +++ b/arch/arm64/kernel/process.c
>> @@ -544,11 +544,28 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
>>  	return last;
>>  }
>>  
>> +struct wchan_info {
>> +	unsigned long	pc;
>> +	int		count;
>> +};
>> +
>> +static bool get_wchan_cb(void *arg, unsigned long pc)
>> +{
>> +	struct wchan_info *wchan_info = arg;
>> +
>> +	if (!in_sched_functions(pc)) {
>> +		wchan_info->pc = pc;
>> +		return false;
>> +	}
>> +	wchan_info->count--;
>> +	return !!wchan_info->count;
>> +}
> 
> This will terminate one entry earlier than the old logic since we used
> to use a post-increment (testing the prior value), and now we're
> effectively using a pre-decrement (testing the new value).
> 
> I don't think that matters all that much in practice, but it might be
> best to keep the original logic, e.g. initialize `count` to 0 and here
> do:
> 
> 	return wchan_info->count++ < 16;
> 
>> +
>>  unsigned long get_wchan(struct task_struct *p)
>>  {
>> -	struct stackframe frame;
>> -	unsigned long stack_page, ret = 0;
>> -	int count = 0;
>> +	unsigned long stack_page;
>> +	struct wchan_info wchan_info;
>> +
>>  	if (!p || p == current || task_is_running(p))
>>  		return 0;
>>  
>> @@ -556,20 +573,12 @@ unsigned long get_wchan(struct task_struct *p)
>>  	if (!stack_page)
>>  		return 0;
>>  
>> -	start_backtrace(&frame, thread_saved_fp(p), thread_saved_pc(p));
>> +	wchan_info.pc = 0;
>> +	wchan_info.count = 16;
>> +	arch_stack_walk(get_wchan_cb, &wchan_info, p, NULL);
>>  
>> -	do {
>> -		if (unwind_frame(p, &frame))
>> -			goto out;
>> -		if (!in_sched_functions(frame.pc)) {
>> -			ret = frame.pc;
>> -			goto out;
>> -		}
>> -	} while (count++ < 16);
>> -
>> -out:
>>  	put_task_stack(p);
>> -	return ret;
>> +	return wchan_info.pc;
>>  }
> 
> Other than the comment above, this looks good to me.
> 
>>  unsigned long arch_align_stack(unsigned long sp)
>> diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c
>> index a6d18755652f..92a0f4d434e4 100644
>> --- a/arch/arm64/kernel/return_address.c
>> +++ b/arch/arm64/kernel/return_address.c
>> @@ -35,15 +35,11 @@ NOKPROBE_SYMBOL(save_return_addr);
>>  void *return_address(unsigned int level)
>>  {
>>  	struct return_address_data data;
>> -	struct stackframe frame;
>>  
>>  	data.level = level + 2;
>>  	data.addr = NULL;
>>  
>> -	start_backtrace(&frame,
>> -			(unsigned long)__builtin_frame_address(0),
>> -			(unsigned long)return_address);
>> -	walk_stackframe(current, &frame, save_return_addr, &data);
>> +	arch_stack_walk(save_return_addr, &data, current, NULL);
>>  
>>  	if (!data.level)
>>  		return data.addr;
> 
> Nor that arch_stack_walk() will start with it's caller, so
> return_address() will be included in the trace where it wasn't
> previously, which implies we need to skip an additional level.
> 
> That said, I'm not entirely sure why we need to skip 2 levels today; it
> might be worth checking that's correct.
> 
> We should also mark return_address() as noinline to avoid surprises with
> LTO.
> 
>> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
>> index 8982a2b78acf..1800310f92be 100644
>> --- a/arch/arm64/kernel/stacktrace.c
>> +++ b/arch/arm64/kernel/stacktrace.c
>> @@ -151,23 +151,21 @@ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
>>  }
>>  NOKPROBE_SYMBOL(walk_stackframe);
>>  
>> -static void dump_backtrace_entry(unsigned long where, const char *loglvl)
>> +static bool dump_backtrace_entry(void *arg, unsigned long where)
>>  {
>> +	char *loglvl = arg;
>>  	printk("%s %pSb\n", loglvl, (void *)where);
>> +	return true;
>>  }
>>  
>>  void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>>  		    const char *loglvl)
>>  {
>> -	struct stackframe frame;
>> -	int skip = 0;
>> -
>>  	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
>>  
>>  	if (regs) {
>>  		if (user_mode(regs))
>>  			return;
>> -		skip = 1;
>>  	}
> 
> We can simplifiy this to:
> 
> 	if (regs && user_mode(regs))
> 		return;
> 
>>  
>>  	if (!tsk)
>> @@ -176,36 +174,8 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>>  	if (!try_get_task_stack(tsk))
>>  		return;
>>  
>> -	if (tsk == current) {
>> -		start_backtrace(&frame,
>> -				(unsigned long)__builtin_frame_address(0),
>> -				(unsigned long)dump_backtrace);
>> -	} else {
>> -		/*
>> -		 * task blocked in __switch_to
>> -		 */
>> -		start_backtrace(&frame,
>> -				thread_saved_fp(tsk),
>> -				thread_saved_pc(tsk));
>> -	}
>> -
>>  	printk("%sCall trace:\n", loglvl);
>> -	do {
>> -		/* skip until specified stack frame */
>> -		if (!skip) {
>> -			dump_backtrace_entry(frame.pc, loglvl);
>> -		} else if (frame.fp == regs->regs[29]) {
>> -			skip = 0;
>> -			/*
>> -			 * Mostly, this is the case where this function is
>> -			 * called in panic/abort. As exception handler's
>> -			 * stack frame does not contain the corresponding pc
>> -			 * at which an exception has taken place, use regs->pc
>> -			 * instead.
>> -			 */
>> -			dump_backtrace_entry(regs->pc, loglvl);
>> -		}
>> -	} while (!unwind_frame(tsk, &frame));
>> +	arch_stack_walk(dump_backtrace_entry, (void *)loglvl, tsk, regs);
> 
> It turns out we currently need this skipping to get the balance the
> ftrace call stack, and arch_stack_walk() doesn't currently do the right
> thing when starting from regs. That balancing isn't quite right, and
> will be wrong in some case when unwinding across exception boundaries;
> we could implement HAVE_FUNCTION_GRAPH_RET_ADDR_PTR using the FP to
> solve that.
> 
>>  
>>  	put_task_stack(tsk);
>>  }
>> diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
>> index eebbc8d7123e..671b3038a772 100644
>> --- a/arch/arm64/kernel/time.c
>> +++ b/arch/arm64/kernel/time.c
>> @@ -32,22 +32,26 @@
>>  #include <asm/stacktrace.h>
>>  #include <asm/paravirt.h>
>>  
>> +static bool profile_pc_cb(void *arg, unsigned long pc)
>> +{
>> +	unsigned long *prof_pc = arg;
>> +
>> +	if (in_lock_functions(pc))
>> +		return true;
>> +	*prof_pc = pc;
>> +	return false;
>> +}
>> +
>>  unsigned long profile_pc(struct pt_regs *regs)
>>  {
>> -	struct stackframe frame;
>> +	unsigned long prof_pc = 0;
>>  
>>  	if (!in_lock_functions(regs->pc))
>>  		return regs->pc;
>>  
>> -	start_backtrace(&frame, regs->regs[29], regs->pc);
>> -
>> -	do {
>> -		int ret = unwind_frame(NULL, &frame);
>> -		if (ret < 0)
>> -			return 0;
>> -	} while (in_lock_functions(frame.pc));
>> +	arch_stack_walk(profile_pc_cb, &prof_pc, current, regs);
>>  
>> -	return frame.pc;
>> +	return prof_pc;
>>  }
>>  EXPORT_SYMBOL(profile_pc);
> 
> Mdoulo the problem above w.r.t. unwinding from regs, this looks good.
> 
> Thanks,
> Mark.
> 
>>  
>> -- 
>> 2.25.1
>>


From dqfext at gmail.com  Wed Aug 25 22:29:56 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Thu, 26 Aug 2021 13:29:56 +0800
Subject: [RFC net-next 2/2] net: dsa: tag_mtk: handle VLAN tag insertion
 on TX
In-Reply-To: <20210826000349.q3s5gjuworxtbcna@skbuf>
References: <20210825083832.2425886-1-dqfext@gmail.com>
 <20210825083832.2425886-3-dqfext@gmail.com>
 <20210826000349.q3s5gjuworxtbcna@skbuf>
Message-ID: <20210826052956.3101243-1-dqfext@gmail.com>

On Thu, Aug 26, 2021 at 03:03:49AM +0300, Vladimir Oltean wrote:
> 
> You cannot just remove the old code. Only things like 8021q uppers will
> send packets with the VLAN in the hwaccel area.
> 
> If you have an application that puts the VLAN in the actual AF_PACKET
> payload, like:
> 
> https://github.com/vladimiroltean/tsn-scripts/blob/master/isochron/send.c
> 
> then you need to handle the VLAN being in the skb payload.

I've actually tested this (only apply patch 2 without .features) and it
still worked.

The comment says the VLAN tag need to be combined with the special tag in
order to perform VLAN table lookup, so we can set its destination port
vector to all zeroes and the switch will forward it like a data frame
(TX forward offload), but as we allow multiple bridges which are either
VLAN-unaware or VLAN-aware with the same VID, there is no way to determine
the destination bridge unless we maintain some VLAN translation mapping.


From yajun.deng at linux.dev  Wed Aug 25 23:04:06 2021
From: yajun.deng at linux.dev (Yajun Deng)
Date: Thu, 26 Aug 2021 14:04:06 +0800
Subject: [PATCH linux-next v2] arm64: PCI: Introduce pcibios_free_irq() helper
 function
Message-ID: <20210826060406.12571-1-yajun.deng@linux.dev>

pcibios_alloc_irq() will be called in pci_device_probe(), but there
hasn't pcibios_free_irq() in arm64 architecture correspond it.
pcibios_free_irq() is an empty weak function in drivers/pci/pci-driver.c.
So add pcibios_free_irq() for correspond it. This will be called
in pci_device_remove().

====================
v2: remove the change in pcibios_alloc_irq(), and modify the commit log.
====================

Signed-off-by: Yajun Deng <yajun.deng at linux.dev>
---
 arch/arm64/kernel/pci.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 2276689b5411..6ffd92126f65 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -29,6 +29,13 @@ int pcibios_alloc_irq(struct pci_dev *dev)
 
 	return 0;
 }
+
+void pcibios_free_irq(struct pci_dev *dev)
+{
+	if (!acpi_disabled)
+		acpi_pci_irq_disable(dev);
+}
+
 #endif
 
 /*
-- 
2.32.0



From wangkefeng.wang at huawei.com  Wed Aug 25 23:22:20 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Thu, 26 Aug 2021 14:22:20 +0800
Subject: [PATCH 3/3] amba: Properly handle device probe without IRQ domain
In-Reply-To: <CAGETcx9yaWZOzt=gcyNAshoHdPoYizhmrKS-kU9c2QM2+HqeEw@mail.gmail.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
 <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
 <b5eb935f-26e1-6475-63af-e7f6101eb017@huawei.com>
 <CAGETcx9yaWZOzt=gcyNAshoHdPoYizhmrKS-kU9c2QM2+HqeEw@mail.gmail.com>
Message-ID: <245f3ce5-1d8b-79c2-31af-4dc13536505d@huawei.com>


On 2021/8/26 12:45, Saravana Kannan wrote:
> On Wed, Aug 25, 2021 at 7:45 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>
>> On 2021/8/25 16:04, Saravana Kannan wrote:
>>> On Tue, Aug 24, 2021 at 9:05 PM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>>> On 2021/8/25 4:08, Saravana Kannan wrote:
>>>>> On Tue, Aug 24, 2021 at 1:05 PM Rob Herring <robh+dt at kernel.org> wrote:
>>>>>> +Saravana
>>>>>>
>>>>>> Saravana mentioned to me there may be some issues with this one...
>>>>>>
>>>>>>
>>>>>> On Mon, Aug 16, 2021 at 2:43 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>>>>>> of_amba_device_create() uses irq_of_parse_and_map() to translate
>>>>>>> a DT interrupt specification into a Linux virtual interrupt number.
>>>>>>>
>>>>>>> But it doesn't properly handle the case where the interrupt controller
>>>>>>> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
>>>>>>> interrupt controller, because the mbigen initialization is too late,
>>>>>>> which will lead to no IRQ due to no IRQ domain found, log is shown below,
>>>>>>>      "irq: no irq domain found for uart0 !"
>>>>>>>
>>>>>>> use of_irq_get() to return -EPROBE_DEFER as above, and in the function
>>>>>>> amba_device_try_add()/amba_device_add(), it will properly handle in such
>>>>>>> case, also return 0 in other fail cases to be consistent as before.
>>>>>>>
>>>>>>> Cc: Russell King <linux at armlinux.org.uk>
>>>>>>> Cc: Rob Herring <robh+dt at kernel.org>
>>>>>>> Cc: Frank Rowand <frowand.list at gmail.com>
>>>>>>> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
>>>>>>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>>>>>>> ---
...
>>>>> Similar to other resources the AMBA bus "gets" for the device, I think
>>>>> this should be moved into amba_probe() and not here. There's no reason
>>>>> to delay the addition of the device (and loading its module) because
>>>>> the IRQ isn't ready yet.
>>>> The following code in the amba_device_try_add() will be called, it uses irq[0]
>>>> and irq[1], so I put of_amba_device_decode_irq() into amba_device_try_add().
>>>>
>>>> 470         if (dev->irq[0])
>>>> 471                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
>>>> 472         if (ret == 0 && dev->irq[1])
>>>> 473                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
>>>> 474         if (ret == 0)
>>>> 475                 return ret;
>>>>
>>>> of_amba_device_decode_irq() in amba_device_try_add() won't lead to issue,
>>>> only delay the device add, right?
>>> But delaying the device add is the issue. For example, adding a device
>>> could trigger the loading of the corresponding module using uevents.
>>> But now this change would delay that step. That can have other
>>> unintended consequences -- slowing down boot, what if the driver was
>>> working fine without the IRQ, etc.
>>>
>>>> If make it into amba_probe(), the above code should be moved too, could we
>>>> make a new patch to move both of them, or don't move them?
>>> I'd say move them both. If Russell hasn't already picked this up, then
>>> I'd say redo your Patch 3/3.
>> I will resend with put it into amba_probe.
>>> Btw, I've been working on [1] cleaning up the one-off deferred probe
>>> solution that we have for amba devices. That causes a bunch of other
>>> headaches. Your patch 3/3 takes us further in the wrong direction by
>>> adding more reasons for delaying the addition of the device.
>> Got it,  and I could resend all combine your patch(due to context conflict
>>
>> when changing same function) if you no object.
> If you want to resolve the conflict with my patch and resend it while
> keeping me as the author, I would definitely appreciate it.
Yes, I will keep it, and rebase my patch based on it.
>
> -Saravana
>>
>>> -Saravana
>>>
>>> [1] - https://lore.kernel.org/lkml/CAGETcx8b228nDUho3cX9AAQ-pXOfZTMv8cj2vhdx9yc_pk8q+A at mail.gmail.com/
>>> .
>>>
> .
>


From jeremy.linton at arm.com  Wed Aug 25 23:36:00 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 26 Aug 2021 01:36:00 -0500
Subject: [PATCH V2 05/10] mmc: sdhci-iproc: Set
 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711
In-Reply-To: <1628334401-6577-6-git-send-email-stefan.wahren@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
 <1628334401-6577-6-git-send-email-stefan.wahren@i2se.com>
Message-ID: <3e8bfa67-e3fe-bcfd-1941-90cae7ed0176@arm.com>

Hi,


On 8/7/21 6:06 AM, Stefan Wahren wrote:
> From: Nicolas Saenz Julienne <nsaenz at kernel.org>
> 
> The controller doesn't seem to pick-up on clock changes, so set the
> SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN flag to query the clock frequency
> directly from the clock.
> 
> Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
> Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> ---
>   drivers/mmc/host/sdhci-iproc.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
> index 032bf85..e7565c6 100644
> --- a/drivers/mmc/host/sdhci-iproc.c
> +++ b/drivers/mmc/host/sdhci-iproc.c
> @@ -295,7 +295,8 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
>   };
>   
>   static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
> -	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
> +	.quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
> +		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
>   	.ops = &sdhci_iproc_bcm2711_ops,
>   };

I just noticed that this got merged to rc7, and it breaks the ACPI based 
rpi's because it causes the 100Mhz max clock to be overridden to the 
return from sdhci_iproc_get_max_clock() which is 0 because there isn't a 
OF/DT based clock device.




From rogerq at kernel.org  Wed Aug 25 23:46:12 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 26 Aug 2021 09:46:12 +0300
Subject: [PATCH v16 4/7] arm64: defconfig: Explicitly enable
 USB_XHCI_PLATFORM
In-Reply-To: <20210813125146.v16.4.Id45138610b749ff775186ac10b3d01c504ddf4f3@changeid>
References: <20210813195228.2003500-1-mka@chromium.org>
 <20210813125146.v16.4.Id45138610b749ff775186ac10b3d01c504ddf4f3@changeid>
Message-ID: <dcea8257-f2f5-58f1-618c-a61545c5f9e7@kernel.org>



On 13/08/2021 22:52, Matthias Kaehlcke wrote:
> The dependency of USB_DWC3 on USB_XHCI_PLATFORM is being changed
> from 'select' to 'depends on' by another patch. The defconfig selects
> USB_DWC3 and implicitly USB_DWC3_DUAL_ROLE, to keep this unchanged
> USB_XHCI_PLATFORM now needs to be selected explicitly.
> 
> Signed-off-by: Matthias Kaehlcke <mka at chromium.org>
> Reviewed-by: Douglas Anderson <dianders at chromium.org>

Reviewed-by: Roger Quadros <rogerq at kernel.org>

cheers,
-roger
> ---
> 
> Changes in v16:
> - none
> 
> Changes in v15:
> - none
> 
> Changes in v14:
> - rebased on v5.14-rc1 (with the rest of the series)
> - added 'Reviewed-by' tag from Doug
> 
> Changes in v13:
> - patch added to the series
> 
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index f423d08b9a71..b243bd11a4ed 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -802,6 +802,7 @@ CONFIG_USB_OTG=y
>  CONFIG_USB_XHCI_HCD=y
>  CONFIG_USB_XHCI_PCI=m
>  CONFIG_USB_XHCI_PCI_RENESAS=m
> +CONFIG_USB_XHCI_PLATFORM=y
>  CONFIG_USB_XHCI_TEGRA=y
>  CONFIG_USB_EHCI_HCD=y
>  CONFIG_USB_EHCI_EXYNOS=y
> 


From rocco.yue at mediatek.com  Wed Aug 25 23:46:03 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Thu, 26 Aug 2021 14:46:03 +0800
Subject: [PATCH net-next v5] ipv6: add IFLA_INET6_RA_MTU to expose mtu value
Message-ID: <20210826064603.5242-1-rocco.yue@mediatek.com>

The kernel provides a "/proc/sys/net/ipv6/conf/<iface>/mtu"
file, which can temporarily record the mtu value of the last
received RA message when the RA mtu value is lower than the
interface mtu, but this proc has following limitations:

(1) when the interface mtu (/sys/class/net/<iface>/mtu) is
updeated, mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) will
be updated to the value of interface mtu;
(2) mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) only affect
ipv6 connection, and not affect ipv4.

Therefore, when the mtu option is carried in the RA message,
there will be a problem that the user sometimes cannot obtain
RA mtu value correctly by reading mtu6.

After this patch set, if a RA message carries the mtu option,
you can send a netlink msg which nlmsg_type is RTM_GETLINK,
and then by parsing the attribute of IFLA_INET6_RA_MTU to
get the mtu value carried in the RA message received on the
inet6 device. In addition, you can also get a link notification
when ra_mtu is updated so it doesn't have to poll.

In this way, if the MTU values that the device receives from
the network in the PCO IPv4 and the RA IPv6 procedures are
different, the user can obtain the correct ipv6 ra_mtu value
and compare the value of ra_mtu and ipv4 mtu, then the device
can use the lower MTU value for both IPv4 and IPv6.

Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
---
 include/net/if_inet6.h             |  2 ++
 include/uapi/linux/if_link.h       |  1 +
 net/ipv6/addrconf.c                |  9 +++++++++
 net/ipv6/ndisc.c                   | 17 +++++++++++------
 tools/include/uapi/linux/if_link.h |  1 +
 5 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 42235c178b06..653e7d0f65cb 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -210,6 +210,8 @@ struct inet6_dev {
 
 	unsigned long		tstamp; /* ipv6InterfaceTable update timestamp */
 	struct rcu_head		rcu;
+
+	unsigned int		ra_mtu;
 };
 
 static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 8aad65b69054..eebd3894fe89 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -417,6 +417,7 @@ enum {
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
 	IFLA_INET6_TOKEN,	/* device token			*/
 	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	IFLA_INET6_RA_MTU,	/* mtu carried in the RA message */
 	__IFLA_INET6_MAX
 };
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8381288a0d6e..2ceeb93b6008 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -394,6 +394,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
 		ndev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
 
 	ndev->cnf.mtu6 = dev->mtu;
+	ndev->ra_mtu = U32_MIN;
 	ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
 	if (!ndev->nd_parms) {
 		kfree(ndev);
@@ -3849,6 +3850,7 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister)
 	}
 
 	idev->tstamp = jiffies;
+	idev->ra_mtu = U32_MIN;
 
 	/* Last: Shot the device (if unregistered) */
 	if (unregister) {
@@ -5543,6 +5545,7 @@ static inline size_t inet6_ifla6_size(void)
 	     + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
 	     + nla_total_size(sizeof(struct in6_addr)) /* IFLA_INET6_TOKEN */
 	     + nla_total_size(1) /* IFLA_INET6_ADDR_GEN_MODE */
+	     + nla_total_size(4) /* IFLA_INET6_RA_MTU */
 	     + 0;
 }
 
@@ -5651,6 +5654,9 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
 	if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
 		goto nla_put_failure;
 
+	if (nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))
+		goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
@@ -5767,6 +5773,9 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token,
 static const struct nla_policy inet6_af_policy[IFLA_INET6_MAX + 1] = {
 	[IFLA_INET6_ADDR_GEN_MODE]	= { .type = NLA_U8 },
 	[IFLA_INET6_TOKEN]		= { .len = sizeof(struct in6_addr) },
+	[IFLA_INET6_RA_MTU]		= { .type = NLA_REJECT,
+					    .reject_message =
+						"IFLA_INET6_RA_MTU can not be set" },
 };
 
 static int check_addr_gen_mode(int mode)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c467c6419893..4b098521a44c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1391,12 +1391,6 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		}
 	}
 
-	/*
-	 *	Send a notify if RA changed managed/otherconf flags or timer settings
-	 */
-	if (send_ifinfo_notify)
-		inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
-
 skip_linkparms:
 
 	/*
@@ -1496,6 +1490,11 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
 		mtu = ntohl(n);
 
+		if (in6_dev->ra_mtu != mtu) {
+			in6_dev->ra_mtu = mtu;
+			send_ifinfo_notify = true;
+		}
+
 		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
 			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
 		} else if (in6_dev->cnf.mtu6 != mtu) {
@@ -1519,6 +1518,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		ND_PRINTK(2, warn, "RA: invalid RA options\n");
 	}
 out:
+	/* Send a notify if RA changed managed/otherconf flags or
+	 * timer settings or ra_mtu value
+	 */
+	if (send_ifinfo_notify)
+		inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
+
 	fib6_info_release(rt);
 	if (neigh)
 		neigh_release(neigh);
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index eb15f319aa57..b3610fdd1fee 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -230,6 +230,7 @@ enum {
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
 	IFLA_INET6_TOKEN,	/* device token			*/
 	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	IFLA_INET6_RA_MTU,	/* mtu carried in the RA message */
 	__IFLA_INET6_MAX
 };
 
-- 
2.18.0

From guangming.cao at mediatek.com  Wed Aug 25 23:42:33 2021
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Thu, 26 Aug 2021 14:42:33 +0800
Subject: [PATCH] dma-buf: Add support for mapping buffers with DMA attributes
In-Reply-To: <20210810020254.103134-1-guangming.cao@mediatek.com>
References: <20210810020254.103134-1-guangming.cao@mediatek.com>
Message-ID: <20210826064233.69217-1-guangming.cao@mediatek.com>

From: Guangming Cao <Guangming.Cao at mediatek.com>

When mapping the memory represented by a dma-buf into a device's
address space, it might be desireable to map the memory with
certain DMA attributes. Thus, introduce the dma_mapping_attrs
field in the dma_buf_attachment structure so that when
the memory is mapped with dma_buf_map_attachment, it is mapped
with the desired DMA attributes.

Signed-off-by: Isaac J. Manjarres <isaacm at codeaurora.org>
Signed-off-by: Sandeep Patil <sspatil at google.com>
Signed-off-by: Guangming Cao <Guangming.Cao at mediatek.com>
---
 drivers/dma-buf/heaps/cma_heap.c    | 6 ++++--
 drivers/dma-buf/heaps/system_heap.c | 6 ++++--
 include/linux/dma-buf.h             | 3 +++
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index 0c05b79870f9..2c9feb3bfc3e 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -99,9 +99,10 @@ static struct sg_table *cma_heap_map_dma_buf(struct dma_buf_attachment *attachme
 {
 	struct dma_heap_attachment *a = attachment->priv;
 	struct sg_table *table = &a->table;
+	int attrs = attachment->dma_map_attrs;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
 	if (ret)
 		return ERR_PTR(-ENOMEM);
 	a->mapped = true;
@@ -113,9 +114,10 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   enum dma_data_direction direction)
 {
 	struct dma_heap_attachment *a = attachment->priv;
+	int attrs = attachment->dma_map_attrs;
 
 	a->mapped = false;
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(attachment->dev, table, direction, attrs);
 }
 
 static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 23a7e74ef966..fc7b1e02988e 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -130,9 +130,10 @@ static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attac
 {
 	struct dma_heap_attachment *a = attachment->priv;
 	struct sg_table *table = a->table;
+	int attrs = attachment->dma_map_attrs;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
 	if (ret)
 		return ERR_PTR(ret);
 
@@ -145,9 +146,10 @@ static void system_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				      enum dma_data_direction direction)
 {
 	struct dma_heap_attachment *a = attachment->priv;
+	int attrs = attachment->dma_map_attrs;
 
 	a->mapped = false;
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(attachment->dev, table, direction, attrs);
 }
 
 static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index efdc56b9d95f..4d650731766e 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -379,6 +379,8 @@ struct dma_buf_attach_ops {
  * @importer_ops: importer operations for this attachment, if provided
  * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
  * @importer_priv: importer specific attachment data.
+ * @dma_map_attrs: DMA attributes to be used when the exporter maps the buffer
+ * through dma_buf_map_attachment.
  *
  * This structure holds the attachment information between the dma_buf buffer
  * and its user device(s). The list contains one attachment struct per device
@@ -399,6 +401,7 @@ struct dma_buf_attachment {
 	const struct dma_buf_attach_ops *importer_ops;
 	void *importer_priv;
 	void *priv;
+	unsigned long dma_map_attrs;
 };
 
 /**
-- 
2.17.1

From rogerq at kernel.org  Wed Aug 25 23:46:29 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 26 Aug 2021 09:46:29 +0300
Subject: [PATCH v16 5/7] usb: Specify dependencies on USB_XHCI_PLATFORM
 with 'depends on'
In-Reply-To: <20210813125146.v16.5.If248f05613bbb06a44eb0b0909be5d97218f417b@changeid>
References: <20210813195228.2003500-1-mka@chromium.org>
 <20210813125146.v16.5.If248f05613bbb06a44eb0b0909be5d97218f417b@changeid>
Message-ID: <ad5a2b81-3ecb-e1d8-9bcb-b5b3a8d0385e@kernel.org>



On 13/08/2021 22:52, Matthias Kaehlcke wrote:
> Some USB controller drivers that depend on the xhci-plat driver
> specify this dependency using 'select' in Kconfig. This is not
> recommended for symbols that have other dependencies as it may
> lead to invalid configurations. Use 'depends on' to specify the
> dependency instead of 'select'.
> 
> For dwc3 specify the dependency on USB_XHCI_PLATFORM in
> USB_DWC3_HOST and USB_DWC3_DUAL_ROLE. Also adjust the
> dependencies of USB_DWC3_CORE to make sure that at least one
> of USB_DWC3_HOST, USB_DWC3_GADGET or USB_DWC3_DUAL_ROLE can be
> selected.
> 
> Signed-off-by: Matthias Kaehlcke <mka at chromium.org>

Reviewed-by: Roger Quadros <rogerq at kernel.org>

cheers,
-roger

> ---
> 
> Changes in v16:
> - none
> 
> Changes in v15:
> - adjusted dependencies of USB_DWC3_CORE to make sure it can only
>   be enabled when at least one of USB_DWC3_HOST, USB_DWC3_GADGET
>   or USB_DWC3_DUAL_ROLE is selectable
> - updated commit message
> 
> Changes in v14:
> - none
> 
> Changes in v13:
> - patch added to the series
> 
>  drivers/usb/cdns3/Kconfig | 2 +-
>  drivers/usb/dwc3/Kconfig  | 5 +++--
>  drivers/usb/host/Kconfig  | 4 ++--
>  3 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig
> index b98ca0a1352a..07e12f786d48 100644
> --- a/drivers/usb/cdns3/Kconfig
> +++ b/drivers/usb/cdns3/Kconfig
> @@ -1,7 +1,7 @@
>  config USB_CDNS_SUPPORT
>  	tristate "Cadence USB Support"
>  	depends on USB_SUPPORT && (USB || USB_GADGET) && HAS_DMA
> -	select USB_XHCI_PLATFORM if USB_XHCI_HCD
> +	depends on !USB_XHCI_HCD || USB_XHCI_PLATFORM
>  	select USB_ROLE_SWITCH
>  	help
>  	  Say Y here if your system has a Cadence USBSS or USBSSP
> diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
> index 66b1454c4db2..870f2251350a 100644
> --- a/drivers/usb/dwc3/Kconfig
> +++ b/drivers/usb/dwc3/Kconfig
> @@ -2,8 +2,7 @@
>  
>  config USB_DWC3
>  	tristate "DesignWare USB3 DRD Core Support"
> -	depends on (USB || USB_GADGET) && HAS_DMA
> -	select USB_XHCI_PLATFORM if USB_XHCI_HCD
> +	depends on ((USB && USB_XHCI_PLATFORM) || USB_GADGET) && HAS_DMA
>  	select USB_ROLE_SWITCH if USB_DWC3_DUAL_ROLE
>  	help
>  	  Say Y or M here if your system has a Dual Role SuperSpeed
> @@ -30,6 +29,7 @@ choice
>  config USB_DWC3_HOST
>  	bool "Host only mode"
>  	depends on USB=y || USB=USB_DWC3
> +	depends on USB_XHCI_PLATFORM
>  	help
>  	  Select this when you want to use DWC3 in host mode only,
>  	  thereby the gadget feature will be regressed.
> @@ -44,6 +44,7 @@ config USB_DWC3_GADGET
>  config USB_DWC3_DUAL_ROLE
>  	bool "Dual Role mode"
>  	depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3))
> +	depends on USB_XHCI_PLATFORM
>  	depends on (EXTCON=y || EXTCON=USB_DWC3)
>  	help
>  	  This is the default mode of working of DWC3 controller where
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index df9428f1dc5e..518c2312ef0c 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -80,7 +80,7 @@ config USB_XHCI_MTK
>  
>  config USB_XHCI_MVEBU
>  	tristate "xHCI support for Marvell Armada 375/38x/37xx"
> -	select USB_XHCI_PLATFORM
> +	depends on USB_XHCI_PLATFORM
>  	depends on HAS_IOMEM
>  	depends on ARCH_MVEBU || COMPILE_TEST
>  	help
> @@ -112,9 +112,9 @@ config USB_EHCI_BRCMSTB
>  config USB_BRCMSTB
>  	tristate "Broadcom STB USB support"
>  	depends on (ARCH_BRCMSTB && PHY_BRCM_USB) || COMPILE_TEST
> +	depends on !USB_XHCI_HCD || USB_XHCI_PLATFORM
>  	select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
>  	select USB_EHCI_BRCMSTB if USB_EHCI_HCD
> -	select USB_XHCI_PLATFORM if USB_XHCI_HCD
>  	help
>  	  Enables support for XHCI, EHCI and OHCI host controllers
>  	  found in Broadcom STB SoC's.
> 


From nobuhiro1.iwamatsu at toshiba.co.jp  Thu Aug 26 00:03:36 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Thu, 26 Aug 2021 16:03:36 +0900
Subject: clk: visconti: Initial support Visconti SoC for v5.15
Message-ID: <20210826070336.wr3gskwsgeuwii5d@toshiba.co.jp>

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/iwamatsu/linux-visconti.git
tags/clk-visconti-5.15

for you to fetch changes up to a2bb51ea38e5551dcc84695aaf6e1b5a3aea9efa:

  MAINTAINERS: Add entries for Toshiba Visconti PLL and clock controller (2021-08-26 15:23:16 +0900)

----------------------------------------------------------------
Visconti clock changes for 5.15:

- Add DT bindings for PLL of Toshiba Visconti TMPV770x SoC
- Add DT bindings for SMU of Toshiba Visconti TMPV770x SoC
- Add support common clock driver and reset driver
- Add entries for Toshiba Visconti PLL and clock controller

----------------------------------------------------------------
Nobuhiro Iwamatsu (4):
      dt-bindings: clock: Add DT bindings for PLL of Toshiba Visconti TMPV770x SoC
      dt-bindings: clock: Add DT bindings for SMU of Toshiba Visconti TMPV770x SoC
      clk: visconti: Add support common clock driver and reset driver
      MAINTAINERS: Add entries for Toshiba Visconti PLL and clock controller

 .../bindings/clock/toshiba,tmpv770x-pipllct.yaml   |  57 ++++
 .../bindings/clock/toshiba,tmpv770x-pismu.yaml     |  50 +++
 MAINTAINERS                                        |   3 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/visconti/Makefile                      |   5 +
 drivers/clk/visconti/clkc-tmpv770x.c               | 232 +++++++++++++
 drivers/clk/visconti/clkc.c                        | 220 ++++++++++++
 drivers/clk/visconti/clkc.h                        |  75 +++++
 drivers/clk/visconti/pll-tmpv770x.c                |  85 +++++
 drivers/clk/visconti/pll.c                         | 369 +++++++++++++++++++++
 drivers/clk/visconti/pll.h                         |  63 ++++
 drivers/clk/visconti/reset.c                       | 111 +++++++
 drivers/clk/visconti/reset.h                       |  35 ++
 include/dt-bindings/clock/toshiba,tmpv770x.h       | 181 ++++++++++
 include/dt-bindings/reset/toshiba,tmpv770x.h       |  41 +++
 15 files changed, 1528 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pismu.yaml
 create mode 100644 drivers/clk/visconti/Makefile
 create mode 100644 drivers/clk/visconti/clkc-tmpv770x.c
 create mode 100644 drivers/clk/visconti/clkc.c
 create mode 100644 drivers/clk/visconti/clkc.h
 create mode 100644 drivers/clk/visconti/pll-tmpv770x.c
 create mode 100644 drivers/clk/visconti/pll.c
 create mode 100644 drivers/clk/visconti/pll.h
 create mode 100644 drivers/clk/visconti/reset.c
 create mode 100644 drivers/clk/visconti/reset.h
 create mode 100644 include/dt-bindings/clock/toshiba,tmpv770x.h
 create mode 100644 include/dt-bindings/reset/toshiba,tmpv770x.h




From neal_liu at aspeedtech.com  Thu Aug 26 00:15:25 2021
From: neal_liu at aspeedtech.com (neal_liu)
Date: Thu, 26 Aug 2021 15:15:25 +0800
Subject: [PATCH] usb: host: ehci: skip STS_HALT check for aspeed platform
Message-ID: <20210826071525.27651-1-neal_liu@aspeedtech.com>

STS_HALT also depends on ASS/PSS status for apseed.
Skip this check on startup.

Signed-off-by: neal_liu <neal_liu at aspeedtech.com>
---
 drivers/usb/host/ehci-hcd.c      | 10 +++++++++-
 drivers/usb/host/ehci-platform.c |  6 ++++++
 drivers/usb/host/ehci.h          |  1 +
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 10b0365f3439..a539e11502ef 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -634,7 +634,15 @@ static int ehci_run (struct usb_hcd *hcd)
 	/* Wait until HC become operational */
 	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
 	msleep(5);
-	rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000);
+
+	/* For Aspeed, STS_HALT also depends on ASS/PSS status.
+	 * Skip this check on startup.
+	 */
+	if (ehci->is_aspeed)
+		rc = 0;
+	else
+		rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT,
+				    0, 100 * 1000);
 
 	up_write(&ehci_cf_port_reset_rwsem);
 
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index c70f2d0b4aaf..c3dc906274d9 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -297,6 +297,12 @@ static int ehci_platform_probe(struct platform_device *dev)
 					  "has-transaction-translator"))
 			hcd->has_tt = 1;
 
+		if (of_device_is_compatible(dev->dev.of_node,
+					    "aspeed,ast2500-ehci") ||
+		    of_device_is_compatible(dev->dev.of_node,
+					    "aspeed,ast2600-ehci"))
+			ehci->is_aspeed = 1;
+
 		if (soc_device_match(quirk_poll_match))
 			priv->quirk_poll = true;
 
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 80bb823aa9fe..fdd073cc053b 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -219,6 +219,7 @@ struct ehci_hcd {			/* one per controller */
 	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */
 	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */
 	unsigned		spurious_oc:1;
+	unsigned		is_aspeed:1;
 
 	/* required for usb32 quirk */
 	#define OHCI_CTRL_HCFS          (3 << 6)
-- 
2.17.1



From jeremy.linton at arm.com  Thu Aug 26 00:15:53 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 26 Aug 2021 02:15:53 -0500
Subject: [PATCH v3 0/4] CM4 ACPI PCIe quirk
Message-ID: <20210826071557.29239-1-jeremy.linton@arm.com>

The PFTF CM4 is an ACPI platform that is following the Arm PCIe SMC
(DEN0115) standard because its PCIe config space isn't ECAM compliant
since it is split into two parts. One part describes the root port
registers, and another contains a moveable window pointing at a given
device's 4K config space. Thus it doesn't have an MCFG table. As
Linux doesn't support the PCI/SMC, a host bridge specific _DSD is
added and associated with custom ECAM ops and cfgres.  The custom cfg
op selects between those two regions, as well as disallowing
problematic accesses.

V2->V3:
	Rebase to -next to pickup new MAINTAINERS entries that
	       needed updating.
	Enforce _DSD property is exactly the same len as the
		MCFG OEM field it is overriding.
	More commit/comment tweaks.
	
V1->V2:
	Only move register definitions to new .h file, add
	     include guards.
	Change quirk namespace identifier.
	Update Maintainers file.
	A number of whitespace, grammar, etc fixes.

Jeremy Linton (4):
  PCI: brcmstb: Break register definitions into separate header
  PCI: brcmstb: Add ACPI config space quirk
  PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
  MAINTAINERS: Widen brcmstb PCIe file scope

 MAINTAINERS                                |   6 +-
 drivers/acpi/pci_mcfg.c                    |  17 +++
 drivers/pci/controller/Makefile            |   1 +
 drivers/pci/controller/pcie-brcmstb-acpi.c |  79 +++++++++++
 drivers/pci/controller/pcie-brcmstb.c      | 149 +-------------------
 drivers/pci/controller/pcie-brcmstb.h      | 155 +++++++++++++++++++++
 include/linux/pci-ecam.h                   |   1 +
 7 files changed, 257 insertions(+), 151 deletions(-)
 create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
 create mode 100644 drivers/pci/controller/pcie-brcmstb.h

-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug 26 00:15:55 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 26 Aug 2021 02:15:55 -0500
Subject: [PATCH v3 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210826071557.29239-1-jeremy.linton@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
Message-ID: <20210826071557.29239-3-jeremy.linton@arm.com>

The Pi Firmware Task Force (PFTF: https://github.com/pftf) Compute
Module 4 (CM4: an embedded form factor RPi4) is an ACPI platform that
isn't ECAM compliant. Its config space is in two parts. One part is for
the root port registers and a second moveable window pointing at a
device's 4K config space. Thus it doesn't have an MCFG, and any MCFG
provided would be nonsense anyway.

Instead, a custom pci_ecam_ops quirk is created. The custom ops override
the .init and .map_bus functions. The former to assure that cfg->win
points at a single mapping that contains the root port registers and the
device config window, as well as disabling MSIs due to lack of a
GICv2M. map_bus() then provides the address of either the standard
portion of the root port registers or to the device config window after
it has been moved.

Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/controller/Makefile            |  1 +
 drivers/pci/controller/pcie-brcmstb-acpi.c | 79 ++++++++++++++++++++++
 include/linux/pci-ecam.h                   |  1 +
 3 files changed, 81 insertions(+)
 create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c

diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index aaf30b3dcc14..65aa6fd3ed89 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
 obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
 obj-$(CONFIG_ARM64) += pci-thunder-pem.o
 obj-$(CONFIG_ARM64) += pci-xgene.o
+obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
 endif
 endif
diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
new file mode 100644
index 000000000000..528b2b3ffbd2
--- /dev/null
+++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * ACPI quirks for Brcm2711 PCIe host controller
+ * As used on the Raspberry Pi Compute Module 4
+ *
+ * Copyright (C) 2021 Arm Ltd.
+ */
+
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/pci-ecam.h>
+#include "../pci.h"
+#include "pcie-brcmstb.h"
+
+static int brcm_acpi_init(struct pci_config_window *cfg)
+{
+	/*
+	 * This platform doesn't technically have anything that could be called
+	 * ECAM. Its config region has root port specific registers between
+	 * standard PCIe defined config registers. Thus the region setup by the
+	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
+	 * but the footprint isn't a nice power of 2 (40k). For purposes of
+	 * mapping the config region we are just going to squash the standard
+	 * and nonstandard registers together rather than mapping them separately.
+	 */
+	iounmap(cfg->win);
+	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
+	if (!cfg->win)
+		goto err_exit;
+
+	/* MSI is nonstandard as well */
+	pci_no_msi();
+
+	return 0;
+err_exit:
+	dev_err(cfg->parent, "PCI: Failed to remap config\n");
+	return -ENOMEM;
+}
+
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
+					unsigned int devfn, int where)
+{
+	struct pci_config_window *cfg = bus->sysdata;
+	void __iomem *base = cfg->win;
+	int idx;
+	u32 up;
+
+	/* Accesses to the RC go right to the RC registers if slot==0 */
+	if (pci_is_root_bus(bus))
+		return PCI_SLOT(devfn) ? NULL : base + where;
+
+	/*
+	 * Assure the link is up before sending requests downstream. This is done
+	 * to avoid sending transactions to EPs that don't exist. Link flap
+	 * conditions/etc make this race more probable. The resulting unrecoverable
+	 * SERRORs will result in the machine crashing.
+	 */
+	up = readl(base + PCIE_MISC_PCIE_STATUS);
+	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+		return NULL;
+
+	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+		return NULL;
+
+	/* For devices, write to the config space index register */
+	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
+	writel(idx, base + PCIE_EXT_CFG_INDEX);
+	return base + PCIE_EXT_CFG_DATA + where;
+}
+
+const struct pci_ecam_ops bcm2711_pcie_ops = {
+	.init		= brcm_acpi_init,
+	.bus_shift	= 1,
+	.pci_ops	= {
+		.map_bus	= brcm_pcie_map_conf2,
+		.read		= pci_generic_config_read,
+		.write		= pci_generic_config_write,
+	}
+};
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index adea5a4771cf..a5de0285bb7f 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
 extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
 extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
 extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
+extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
 #endif
 
 #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug 26 00:15:54 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 26 Aug 2021 02:15:54 -0500
Subject: [PATCH v3 1/4] PCI: brcmstb: Break register definitions into separate
 header
In-Reply-To: <20210826071557.29239-1-jeremy.linton@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
Message-ID: <20210826071557.29239-2-jeremy.linton@arm.com>

We are about to create a standalone ACPI quirk module for the
bcmstb controller. Lets move the register definitions into a separate
file so they can be shared between the APCI quirk and the normal
host bridge driver.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 149 +------------------------
 drivers/pci/controller/pcie-brcmstb.h | 155 ++++++++++++++++++++++++++
 2 files changed, 156 insertions(+), 148 deletions(-)
 create mode 100644 drivers/pci/controller/pcie-brcmstb.h

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index cc30215f5a43..2517735101ba 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -31,159 +31,12 @@
 #include <linux/types.h>
 
 #include "../pci.h"
-
-/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
-#define BRCM_PCIE_CAP_REGS				0x00ac
-
-/* Broadcom STB PCIe Register Offsets */
-#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1				0x0188
-#define  PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK	0xc
-#define  PCIE_RC_CFG_VENDOR_SPCIFIC_REG1_LITTLE_ENDIAN			0x0
-
-#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
-#define  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK	0xffffff
-
-#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY			0x04dc
-#define  PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK	0xc00
-
-#define PCIE_RC_DL_MDIO_ADDR				0x1100
-#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
-#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
-
-#define PCIE_MISC_MISC_CTRL				0x4008
-#define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK		0x1000
-#define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK	0x2000
-#define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK	0x300000
-
-#define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK		0xf8000000
-#define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK		0x07c00000
-#define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK		0x0000001f
-#define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
-#define PCIE_MEM_WIN0_LO(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
-#define PCIE_MEM_WIN0_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 8)
-
-#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
-#define  PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK		0x1f
-
-#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
-#define  PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK		0x1f
-#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
-
-#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
-#define  PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK		0x1f
-
-#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
-#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
-
-#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
-#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_32		0xffe06540
-#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_8		0xfff86540
-
-#define PCIE_MISC_PCIE_CTRL				0x4064
-#define  PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK	0x1
-#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK		0x4
-
-#define PCIE_MISC_PCIE_STATUS				0x4068
-#define  PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK		0x80
-#define  PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK	0x20
-#define  PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK	0x10
-#define  PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK	0x40
-
-#define PCIE_MISC_REVISION				0x406c
-#define  BRCM_PCIE_HW_REV_33				0x0303
-#define  BRCM_PCIE_HW_REV_3_20				0x0320
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT		0x4070
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK	0xfff00000
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK	0xfff0
-#define PCIE_MEM_WIN0_BASE_LIMIT(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI			0x4080
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK	0xff
-#define PCIE_MEM_WIN0_BASE_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
-
-#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI			0x4084
-#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK	0xff
-#define PCIE_MEM_WIN0_LIMIT_HI(win)	\
-		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
-
-#define PCIE_MISC_HARD_PCIE_HARD_DEBUG					0x4204
-#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
-#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
-
-
-#define PCIE_INTR2_CPU_BASE		0x4300
-#define PCIE_MSI_INTR2_BASE		0x4500
-/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
-#define  MSI_INT_STATUS			0x0
-#define  MSI_INT_CLR			0x8
-#define  MSI_INT_MASK_SET		0x10
-#define  MSI_INT_MASK_CLR		0x14
-
-#define PCIE_EXT_CFG_DATA				0x8000
-#define PCIE_EXT_CFG_INDEX				0x9000
-
-#define  PCIE_RGR1_SW_INIT_1_PERST_MASK			0x1
-#define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT		0x0
-
-#define RGR1_SW_INIT_1_INIT_GENERIC_MASK		0x2
-#define RGR1_SW_INIT_1_INIT_GENERIC_SHIFT		0x1
-#define RGR1_SW_INIT_1_INIT_7278_MASK			0x1
-#define RGR1_SW_INIT_1_INIT_7278_SHIFT			0x0
-
-/* PCIe parameters */
-#define BRCM_NUM_PCIE_OUT_WINS		0x4
-#define BRCM_INT_PCI_MSI_NR		32
-#define BRCM_INT_PCI_MSI_LEGACY_NR	8
-#define BRCM_INT_PCI_MSI_SHIFT		0
-
-/* MSI target adresses */
-#define BRCM_MSI_TARGET_ADDR_LT_4GB	0x0fffffffcULL
-#define BRCM_MSI_TARGET_ADDR_GT_4GB	0xffffffffcULL
-
-/* MDIO registers */
-#define MDIO_PORT0			0x0
-#define MDIO_DATA_MASK			0x7fffffff
-#define MDIO_PORT_MASK			0xf0000
-#define MDIO_REGAD_MASK			0xffff
-#define MDIO_CMD_MASK			0xfff00000
-#define MDIO_CMD_READ			0x1
-#define MDIO_CMD_WRITE			0x0
-#define MDIO_DATA_DONE_MASK		0x80000000
-#define MDIO_RD_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 1 : 0)
-#define MDIO_WT_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 0 : 1)
-#define SSC_REGS_ADDR			0x1100
-#define SET_ADDR_OFFSET			0x1f
-#define SSC_CNTL_OFFSET			0x2
-#define SSC_CNTL_OVRD_EN_MASK		0x8000
-#define SSC_CNTL_OVRD_VAL_MASK		0x4000
-#define SSC_STATUS_OFFSET		0x1
-#define SSC_STATUS_SSC_MASK		0x400
-#define SSC_STATUS_PLL_LOCK_MASK	0x800
-#define PCIE_BRCM_MAX_MEMC		3
+#include "pcie-brcmstb.h"
 
 #define IDX_ADDR(pcie)			(pcie->reg_offsets[EXT_CFG_INDEX])
 #define DATA_ADDR(pcie)			(pcie->reg_offsets[EXT_CFG_DATA])
 #define PCIE_RGR1_SW_INIT_1(pcie)	(pcie->reg_offsets[RGR1_SW_INIT_1])
 
-/* Rescal registers */
-#define PCIE_DVT_PMU_PCIE_PHY_CTRL				0xc700
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS			0x3
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK		0x4
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT	0x2
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK		0x2
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT		0x1
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK		0x1
-#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT		0x0
-
 /* Forward declarations */
 struct brcm_pcie;
 static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val);
diff --git a/drivers/pci/controller/pcie-brcmstb.h b/drivers/pci/controller/pcie-brcmstb.h
new file mode 100644
index 000000000000..fc20cc7ae02f
--- /dev/null
+++ b/drivers/pci/controller/pcie-brcmstb.h
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (C) 2009 - 2021 Broadcom */
+
+#ifndef _PCIE_BRCMSTB_H
+#define _PCIE_BRCMSTB_H
+
+/* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */
+#define BRCM_PCIE_CAP_REGS				0x00ac
+
+/* Broadcom STB PCIe Register Offsets */
+#define PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1				0x0188
+#define  PCIE_RC_CFG_VENDOR_VENDOR_SPECIFIC_REG1_ENDIAN_MODE_BAR2_MASK	0xc
+#define  PCIE_RC_CFG_VENDOR_SPCIFIC_REG1_LITTLE_ENDIAN			0x0
+
+#define PCIE_RC_CFG_PRIV1_ID_VAL3			0x043c
+#define  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK	0xffffff
+
+#define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY			0x04dc
+#define  PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK	0xc00
+
+#define PCIE_RC_DL_MDIO_ADDR				0x1100
+#define PCIE_RC_DL_MDIO_WR_DATA				0x1104
+#define PCIE_RC_DL_MDIO_RD_DATA				0x1108
+
+#define PCIE_MISC_MISC_CTRL				0x4008
+#define  PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK		0x1000
+#define  PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK	0x2000
+#define  PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK	0x300000
+
+#define  PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK		0xf8000000
+#define  PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK		0x07c00000
+#define  PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK		0x0000001f
+#define  SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO		0x400c
+#define PCIE_MEM_WIN0_LO(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO + ((win) * 8)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI		0x4010
+#define PCIE_MEM_WIN0_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_HI + ((win) * 8)
+
+#define PCIE_MISC_RC_BAR1_CONFIG_LO			0x402c
+#define  PCIE_MISC_RC_BAR1_CONFIG_LO_SIZE_MASK		0x1f
+
+#define PCIE_MISC_RC_BAR2_CONFIG_LO			0x4034
+#define  PCIE_MISC_RC_BAR2_CONFIG_LO_SIZE_MASK		0x1f
+#define PCIE_MISC_RC_BAR2_CONFIG_HI			0x4038
+
+#define PCIE_MISC_RC_BAR3_CONFIG_LO			0x403c
+#define  PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK		0x1f
+
+#define PCIE_MISC_MSI_BAR_CONFIG_LO			0x4044
+#define PCIE_MISC_MSI_BAR_CONFIG_HI			0x4048
+
+#define PCIE_MISC_MSI_DATA_CONFIG			0x404c
+#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_32		0xffe06540
+#define  PCIE_MISC_MSI_DATA_CONFIG_VAL_8		0xfff86540
+
+#define PCIE_MISC_PCIE_CTRL				0x4064
+#define  PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK	0x1
+#define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK		0x4
+
+#define PCIE_MISC_PCIE_STATUS				0x4068
+#define  PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK		0x80
+#define  PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK	0x20
+#define  PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK	0x10
+#define  PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK	0x40
+
+#define PCIE_MISC_REVISION				0x406c
+#define  BRCM_PCIE_HW_REV_33				0x0303
+#define  BRCM_PCIE_HW_REV_3_20				0x0320
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT		0x4070
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK	0xfff00000
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK	0xfff0
+#define PCIE_MEM_WIN0_BASE_LIMIT(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT + ((win) * 4)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI			0x4080
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI_BASE_MASK	0xff
+#define PCIE_MEM_WIN0_BASE_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_HI + ((win) * 8)
+
+#define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI			0x4084
+#define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI_LIMIT_MASK	0xff
+#define PCIE_MEM_WIN0_LIMIT_HI(win)	\
+		PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
+
+#define PCIE_MISC_HARD_PCIE_HARD_DEBUG					0x4204
+#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK	0x2
+#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK		0x08000000
+
+
+#define PCIE_INTR2_CPU_BASE		0x4300
+#define PCIE_MSI_INTR2_BASE		0x4500
+/* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */
+#define  MSI_INT_STATUS			0x0
+#define  MSI_INT_CLR			0x8
+#define  MSI_INT_MASK_SET		0x10
+#define  MSI_INT_MASK_CLR		0x14
+
+#define PCIE_EXT_CFG_DATA				0x8000
+#define PCIE_EXT_CFG_INDEX				0x9000
+
+#define  PCIE_RGR1_SW_INIT_1_PERST_MASK			0x1
+#define  PCIE_RGR1_SW_INIT_1_PERST_SHIFT		0x0
+
+#define RGR1_SW_INIT_1_INIT_GENERIC_MASK		0x2
+#define RGR1_SW_INIT_1_INIT_GENERIC_SHIFT		0x1
+#define RGR1_SW_INIT_1_INIT_7278_MASK			0x1
+#define RGR1_SW_INIT_1_INIT_7278_SHIFT			0x0
+
+/* PCIe parameters */
+#define BRCM_NUM_PCIE_OUT_WINS		0x4
+#define BRCM_INT_PCI_MSI_NR		32
+#define BRCM_INT_PCI_MSI_LEGACY_NR	8
+#define BRCM_INT_PCI_MSI_SHIFT		0
+
+/* MSI target addresses */
+#define BRCM_MSI_TARGET_ADDR_LT_4GB	0x0fffffffcULL
+#define BRCM_MSI_TARGET_ADDR_GT_4GB	0xffffffffcULL
+
+/* MDIO registers */
+#define MDIO_PORT0			0x0
+#define MDIO_DATA_MASK			0x7fffffff
+#define MDIO_PORT_MASK			0xf0000
+#define MDIO_REGAD_MASK			0xffff
+#define MDIO_CMD_MASK			0xfff00000
+#define MDIO_CMD_READ			0x1
+#define MDIO_CMD_WRITE			0x0
+#define MDIO_DATA_DONE_MASK		0x80000000
+#define MDIO_RD_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 1 : 0)
+#define MDIO_WT_DONE(x)			(((x) & MDIO_DATA_DONE_MASK) ? 0 : 1)
+#define SSC_REGS_ADDR			0x1100
+#define SET_ADDR_OFFSET			0x1f
+#define SSC_CNTL_OFFSET			0x2
+#define SSC_CNTL_OVRD_EN_MASK		0x8000
+#define SSC_CNTL_OVRD_VAL_MASK		0x4000
+#define SSC_STATUS_OFFSET		0x1
+#define SSC_STATUS_SSC_MASK		0x400
+#define SSC_STATUS_PLL_LOCK_MASK	0x800
+#define PCIE_BRCM_MAX_MEMC		3
+
+/* Rescal registers */
+#define PCIE_DVT_PMU_PCIE_PHY_CTRL				0xc700
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS			0x3
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK		0x4
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT	0x2
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK		0x2
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT		0x1
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK		0x1
+#define  PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT		0x0
+
+#endif /* _PCIE_BRCMSTB_H */
-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug 26 00:15:57 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 26 Aug 2021 02:15:57 -0500
Subject: [PATCH v3 4/4] MAINTAINERS: Widen brcmstb PCIe file scope
In-Reply-To: <20210826071557.29239-1-jeremy.linton@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
Message-ID: <20210826071557.29239-5-jeremy.linton@arm.com>

The brcmstb PCI hardware is now split across multiple files. Include
them in the maintainers block.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas at google.com>
---
 MAINTAINERS | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index eee4c926003b..ec2c7a294495 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3514,7 +3514,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nsaenz/linux-rpi.git
 F:	Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
-F:	drivers/pci/controller/pcie-brcmstb.c
+F:	drivers/pci/controller/pcie-brcmstb*
 F:	drivers/staging/vc04_services
 N:	bcm2711
 N:	bcm283*
@@ -3595,7 +3595,7 @@ F:	arch/arm/include/asm/hardware/cache-b15-rac.h
 F:	arch/arm/mach-bcm/*brcmstb*
 F:	arch/arm/mm/cache-b15-rac.c
 F:	drivers/bus/brcmstb_gisb.c
-F:	drivers/pci/controller/pcie-brcmstb.c
+F:	drivers/pci/controller/pcie-brcmstb*
 N:	brcmstb
 
 BROADCOM BDC DRIVER
@@ -3888,7 +3888,7 @@ M:	bcm-kernel-feedback-list at broadcom.com
 L:	linux-pci at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
-F:	drivers/pci/controller/pcie-brcmstb.c
+F:	drivers/pci/controller/pcie-brcmstb*
 
 BROADCOM SYSTEMPORT ETHERNET DRIVER
 M:	Florian Fainelli <f.fainelli at gmail.com>
-- 
2.31.1



From jeremy.linton at arm.com  Thu Aug 26 00:15:56 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 26 Aug 2021 02:15:56 -0500
Subject: [PATCH v3 3/4] PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
In-Reply-To: <20210826071557.29239-1-jeremy.linton@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
Message-ID: <20210826071557.29239-4-jeremy.linton@arm.com>

Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/acpi/pci_mcfg.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c
index 53cab975f612..04c517418365 100644
--- a/drivers/acpi/pci_mcfg.c
+++ b/drivers/acpi/pci_mcfg.c
@@ -169,6 +169,9 @@ static struct mcfg_fixup mcfg_quirks[] = {
 	ALTRA_ECAM_QUIRK(1, 13),
 	ALTRA_ECAM_QUIRK(1, 14),
 	ALTRA_ECAM_QUIRK(1, 15),
+
+	{ "bc2711", "", 0, 0, MCFG_BUS_ANY, &bcm2711_pcie_ops,
+	  DEFINE_RES_MEM(0xFD500000, 0xA000) },
 };
 
 static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
@@ -198,8 +201,22 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
 	u16 segment = root->segment;
 	struct resource *bus_range = &root->secondary;
 	struct mcfg_fixup *f;
+	const char *soc;
 	int i;
 
+	/*
+	 * This may be a machine with a PCI/SMC conduit, which means it doesn't
+	 * have an MCFG. Use an ACPI namespace definition instead.
+	 */
+	if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),
+					 "linux-ecam-quirk-id", &soc)) {
+		if (strlen(soc) != ACPI_OEM_ID_SIZE)
+			dev_err(&root->device->dev, "ECAM quirk should be %d characters\n",
+				ACPI_OEM_ID_SIZE);
+		else
+			memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
+	}
+
 	for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
 		if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
 			if (f->cfgres.start)
-- 
2.31.1



From chiawei_wang at aspeedtech.com  Wed Aug 25 23:16:22 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 26 Aug 2021 14:16:22 +0800
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>

The Aspeed eSPI controller is slave device to communicate with
the master through the Enhanced Serial Peripheral Interface (eSPI).
All of the four eSPI channels, namely peripheral, virtual wire,
out-of-band, and flash are supported.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 drivers/soc/aspeed/Kconfig             |  11 +
 drivers/soc/aspeed/Makefile            |   1 +
 drivers/soc/aspeed/aspeed-espi-ctrl.c  | 205 +++++++++
 drivers/soc/aspeed/aspeed-espi-ctrl.h  | 304 ++++++++++++
 drivers/soc/aspeed/aspeed-espi-flash.h | 380 +++++++++++++++
 drivers/soc/aspeed/aspeed-espi-ioc.h   | 153 +++++++
 drivers/soc/aspeed/aspeed-espi-oob.h   | 611 +++++++++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-perif.h | 539 ++++++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-vw.h    | 142 ++++++
 9 files changed, 2346 insertions(+)
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-flash.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ioc.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-oob.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-perif.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-vw.h

diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
index 243ca196e6ad..7617a02df5cf 100644
--- a/drivers/soc/aspeed/Kconfig
+++ b/drivers/soc/aspeed/Kconfig
@@ -42,6 +42,17 @@ config ASPEED_SOCINFO
 	help
 	  Say yes to support decoding of ASPEED BMC information.
 
+config ASPEED_ESPI
+	bool "ASPEED eSPI slave driver"
+	select REGMAP
+	select MFD_SYSCON
+	default n
+	help
+	  Enable driver support for the Aspeed eSPI engine. The eSPI engine
+	  plays as a slave device in BMC to communicate with the Host over
+	  the eSPI interface. The four eSPI channels, namely peripheral,
+	  virtual wire, out-of-band, and flash are supported.
+
 endmenu
 
 endif
diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
index fcab7192e1a4..650d8de2875d 100644
--- a/drivers/soc/aspeed/Makefile
+++ b/drivers/soc/aspeed/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_ASPEED_LPC_CTRL)	+= aspeed-lpc-ctrl.o
 obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
 obj-$(CONFIG_ASPEED_P2A_CTRL)	+= aspeed-p2a-ctrl.o
 obj-$(CONFIG_ASPEED_SOCINFO)	+= aspeed-socinfo.o
+obj-$(CONFIG_ASPEED_ESPI)	+= aspeed-espi-ctrl.o
diff --git a/drivers/soc/aspeed/aspeed-espi-ctrl.c b/drivers/soc/aspeed/aspeed-espi-ctrl.c
new file mode 100644
index 000000000000..2b95967d9d30
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ctrl.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include "aspeed-espi-ioc.h"
+#include "aspeed-espi-ctrl.h"
+
+/* include alloc/free/event/ioctl handlers of the eSPI 4 channels */
+#include "aspeed-espi-perif.h"
+#include "aspeed-espi-vw.h"
+#include "aspeed-espi-oob.h"
+#include "aspeed-espi-flash.h"
+
+#define DEVICE_NAME "aspeed-espi-ctrl"
+
+static irqreturn_t aspeed_espi_ctrl_isr(int irq, void *arg)
+{
+	uint32_t sts;
+	struct aspeed_espi_ctrl *espi_ctrl = (struct aspeed_espi_ctrl *)arg;
+
+	regmap_read(espi_ctrl->map, ESPI_INT_STS, &sts);
+
+	if (sts & ESPI_INT_STS_PERIF_BITS) {
+		aspeed_espi_perif_event(sts, espi_ctrl->perif);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_PERIF_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_VW_BITS) {
+		aspeed_espi_vw_event(sts, espi_ctrl->vw);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_VW_BITS);
+	}
+
+	if (sts & (ESPI_INT_STS_OOB_BITS)) {
+		aspeed_espi_oob_event(sts, espi_ctrl->oob);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_OOB_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_FLASH_BITS) {
+		aspeed_espi_flash_event(sts, espi_ctrl->flash);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_FLASH_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_HW_RST_DEASSERT) {
+		aspeed_espi_perif_enable(espi_ctrl->perif);
+		aspeed_espi_vw_enable(espi_ctrl->vw);
+		aspeed_espi_oob_enable(espi_ctrl->oob);
+		aspeed_espi_flash_enable(espi_ctrl->flash);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
+
+		if (espi_ctrl->version == ESPI_AST2500)
+			regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T2,
+				     ESPI_SYSEVT_INT_T2_HOST_RST_WARN |
+				     ESPI_SYSEVT_INT_T2_OOB_RST_WARN);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+				   ESPI_INT_EN_HW_RST_DEASSERT,
+				   ESPI_INT_EN_HW_RST_DEASSERT);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+				   ESPI_SYSEVT_SLV_BOOT_STS | ESPI_SYSEVT_SLV_BOOT_DONE,
+				   ESPI_SYSEVT_SLV_BOOT_STS | ESPI_SYSEVT_SLV_BOOT_DONE);
+
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, ESPI_INT_STS_HW_RST_DEASSERT);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int aspeed_espi_ctrl_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct aspeed_espi_ctrl *espi_ctrl;
+	struct device *dev = &pdev->dev;
+
+	espi_ctrl = devm_kzalloc(dev, sizeof(*espi_ctrl), GFP_KERNEL);
+	if (!espi_ctrl)
+		return -ENOMEM;
+
+	espi_ctrl->version = (uint32_t)of_device_get_match_data(dev);
+
+	espi_ctrl->map = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(espi_ctrl->map)) {
+		dev_err(dev, "cannot get remap\n");
+		return -ENODEV;
+	}
+
+	espi_ctrl->irq = platform_get_irq(pdev, 0);
+	if (espi_ctrl->irq < 0)
+		return espi_ctrl->irq;
+
+	espi_ctrl->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(espi_ctrl->clk)) {
+		dev_err(dev, "cannot get clock\n");
+		return -ENODEV;
+	}
+
+	rc = clk_prepare_enable(espi_ctrl->clk);
+	if (rc) {
+		dev_err(dev, "cannot enable clock\n");
+		return rc;
+	}
+
+	espi_ctrl->perif = aspeed_espi_perif_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->perif)) {
+		dev_err(dev, "failed to allocate peripheral channel\n");
+		return PTR_ERR(espi_ctrl->perif);
+	}
+
+	espi_ctrl->vw = aspeed_espi_vw_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->vw)) {
+		dev_err(dev, "failed to allocate virtual wire channel\n");
+		return PTR_ERR(espi_ctrl->vw);
+	}
+
+	espi_ctrl->oob = aspeed_espi_oob_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->oob)) {
+		dev_err(dev, "failed to allocate out-of-band channel\n");
+		return PTR_ERR(espi_ctrl->oob);
+	}
+
+	espi_ctrl->flash = aspeed_espi_flash_alloc(dev, espi_ctrl);
+	if (rc) {
+		dev_err(dev, "failed to allocate flash channel\n");
+		return PTR_ERR(espi_ctrl->flash);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
+
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
+
+	rc = devm_request_irq(dev, espi_ctrl->irq,
+			      aspeed_espi_ctrl_isr,
+			      0, DEVICE_NAME, espi_ctrl);
+	if (rc) {
+		dev_err(dev, "failed to request IRQ\n");
+		return rc;
+	}
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_HW_RST_DEASSERT,
+			   ESPI_INT_EN_HW_RST_DEASSERT);
+
+	dev_set_drvdata(dev, espi_ctrl);
+
+	dev_info(dev, "module loaded\n");
+
+	return 0;
+}
+
+static int aspeed_espi_ctrl_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct aspeed_espi_ctrl *espi_ctrl = dev_get_drvdata(dev);
+
+	aspeed_espi_perif_free(dev, espi_ctrl->perif);
+	aspeed_espi_vw_free(dev, espi_ctrl->vw);
+	aspeed_espi_oob_free(dev, espi_ctrl->oob);
+	aspeed_espi_flash_free(dev, espi_ctrl->flash);
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_espi_ctrl_of_matches[] = {
+	{ .compatible = "aspeed,ast2500-espi-ctrl", .data = (void *)ESPI_AST2500 },
+	{ .compatible = "aspeed,ast2600-espi-ctrl", .data = (void *)ESPI_AST2600 },
+	{ },
+};
+
+static struct platform_driver aspeed_espi_ctrl_driver = {
+	.driver = {
+		.name = DEVICE_NAME,
+		.of_match_table = aspeed_espi_ctrl_of_matches,
+	},
+	.probe = aspeed_espi_ctrl_probe,
+	.remove = aspeed_espi_ctrl_remove,
+};
+
+module_platform_driver(aspeed_espi_ctrl_driver);
+
+MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang at aspeedtech.com>");
+MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
+MODULE_DESCRIPTION("Control of Aspeed eSPI Slave Device");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/aspeed/aspeed-espi-ctrl.h b/drivers/soc/aspeed/aspeed-espi-ctrl.h
new file mode 100644
index 000000000000..44b93698fd0f
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ctrl.h
@@ -0,0 +1,304 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_CTRL_H_
+#define _ASPEED_ESPI_CTRL_H_
+
+#include <linux/bits.h>
+
+enum aspeed_espi_version {
+	ESPI_AST2500,
+	ESPI_AST2600,
+};
+
+struct aspeed_espi_ctrl {
+	struct device *dev;
+
+	struct regmap *map;
+	struct clk *clk;
+
+	int irq;
+
+	struct aspeed_espi_perif *perif;
+	struct aspeed_espi_vw *vw;
+	struct aspeed_espi_oob *oob;
+	struct aspeed_espi_flash *flash;
+
+	uint32_t version;
+};
+
+/* eSPI register offset */
+#define ESPI_CTRL		0x000
+#define   ESPI_CTRL_OOB_RX_SW_RST		BIT(28)
+#define   ESPI_CTRL_FLASH_TX_DMA_EN		BIT(23)
+#define   ESPI_CTRL_FLASH_RX_DMA_EN		BIT(22)
+#define   ESPI_CTRL_OOB_TX_DMA_EN		BIT(21)
+#define   ESPI_CTRL_OOB_RX_DMA_EN		BIT(20)
+#define   ESPI_CTRL_PERIF_NP_TX_DMA_EN		BIT(19)
+#define   ESPI_CTRL_PERIF_PC_TX_DMA_EN		BIT(17)
+#define   ESPI_CTRL_PERIF_PC_RX_DMA_EN		BIT(16)
+#define   ESPI_CTRL_FLASH_SW_MODE_MASK		GENMASK(11, 10)
+#define   ESPI_CTRL_FLASH_SW_MODE_SHIFT		10
+#define   ESPI_CTRL_PERIF_PC_RX_DMA_EN		BIT(16)
+#define   ESPI_CTRL_FLASH_SW_RDY		BIT(7)
+#define   ESPI_CTRL_OOB_SW_RDY			BIT(4)
+#define   ESPI_CTRL_VW_SW_RDY			BIT(3)
+#define   ESPI_CTRL_PERIF_SW_RDY		BIT(1)
+#define ESPI_STS		0x004
+#define ESPI_INT_STS		0x008
+#define   ESPI_INT_STS_HW_RST_DEASSERT		BIT(31)
+#define   ESPI_INT_STS_OOB_RX_TMOUT		BIT(23)
+#define   ESPI_INT_STS_VW_SYSEVT1		BIT(22)
+#define   ESPI_INT_STS_FLASH_TX_ERR		BIT(21)
+#define   ESPI_INT_STS_OOB_TX_ERR		BIT(20)
+#define   ESPI_INT_STS_FLASH_TX_ABT		BIT(19)
+#define   ESPI_INT_STS_OOB_TX_ABT		BIT(18)
+#define   ESPI_INT_STS_PERIF_NP_TX_ABT		BIT(17)
+#define   ESPI_INT_STS_PERIF_PC_TX_ABT		BIT(16)
+#define   ESPI_INT_STS_FLASH_RX_ABT		BIT(15)
+#define   ESPI_INT_STS_OOB_RX_ABT		BIT(14)
+#define   ESPI_INT_STS_PERIF_NP_RX_ABT		BIT(13)
+#define   ESPI_INT_STS_PERIF_PC_RX_ABT		BIT(12)
+#define   ESPI_INT_STS_PERIF_NP_TX_ERR		BIT(11)
+#define   ESPI_INT_STS_PERIF_PC_TX_ERR		BIT(10)
+#define   ESPI_INT_STS_VW_GPIOEVT		BIT(9)
+#define   ESPI_INT_STS_VW_SYSEVT		BIT(8)
+#define   ESPI_INT_STS_FLASH_TX_CMPLT		BIT(7)
+#define   ESPI_INT_STS_FLASH_RX_CMPLT		BIT(6)
+#define   ESPI_INT_STS_OOB_TX_CMPLT		BIT(5)
+#define   ESPI_INT_STS_OOB_RX_CMPLT		BIT(4)
+#define   ESPI_INT_STS_PERIF_NP_TX_CMPLT	BIT(3)
+#define   ESPI_INT_STS_PERIF_PC_TX_CMPLT	BIT(1)
+#define   ESPI_INT_STS_PERIF_PC_RX_CMPLT	BIT(0)
+#define ESPI_INT_EN		0x00c
+#define   ESPI_INT_EN_HW_RST_DEASSERT		BIT(31)
+#define   ESPI_INT_EN_OOB_RX_TMOUT		BIT(23)
+#define   ESPI_INT_EN_VW_SYSEVT1		BIT(22)
+#define   ESPI_INT_EN_FLASH_TX_ERR		BIT(21)
+#define   ESPI_INT_EN_OOB_TX_ERR		BIT(20)
+#define   ESPI_INT_EN_FLASH_TX_ABT		BIT(19)
+#define   ESPI_INT_EN_OOB_TX_ABT		BIT(18)
+#define   ESPI_INT_EN_PERIF_NP_TX_ABT		BIT(17)
+#define   ESPI_INT_EN_PERIF_PC_TX_ABT		BIT(16)
+#define   ESPI_INT_EN_FLASH_RX_ABT		BIT(15)
+#define   ESPI_INT_EN_OOB_RX_ABT		BIT(14)
+#define   ESPI_INT_EN_PERIF_NP_RX_ABT		BIT(13)
+#define   ESPI_INT_EN_PERIF_PC_RX_ABT		BIT(12)
+#define   ESPI_INT_EN_PERIF_NP_TX_ERR		BIT(11)
+#define   ESPI_INT_EN_PERIF_PC_TX_ERR		BIT(10)
+#define   ESPI_INT_EN_VW_GPIOEVT		BIT(9)
+#define   ESPI_INT_EN_VW_SYSEVT			BIT(8)
+#define   ESPI_INT_EN_FLASH_TX_CMPLT		BIT(7)
+#define   ESPI_INT_EN_FLASH_RX_CMPLT		BIT(6)
+#define   ESPI_INT_EN_OOB_TX_CMPLT		BIT(5)
+#define   ESPI_INT_EN_OOB_RX_CMPLT		BIT(4)
+#define   ESPI_INT_EN_PERIF_NP_TX_CMPLT		BIT(3)
+#define   ESPI_INT_EN_PERIF_PC_TX_CMPLT		BIT(1)
+#define   ESPI_INT_EN_PERIF_PC_RX_CMPLT		BIT(0)
+#define ESPI_PERIF_PC_RX_DMA	0x010
+#define ESPI_PERIF_PC_RX_CTRL	0x014
+#define   ESPI_PERIF_PC_RX_CTRL_PEND_SERV	BIT(31)
+#define   ESPI_PERIF_PC_RX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define   ESPI_PERIF_PC_RX_CTRL_LEN_SHIFT	12
+#define   ESPI_PERIF_PC_RX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define   ESPI_PERIF_PC_RX_CTRL_TAG_SHIFT	8
+#define   ESPI_PERIF_PC_RX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define   ESPI_PERIF_PC_RX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_PC_RX_PORT	0x018
+#define ESPI_PERIF_PC_TX_DMA	0x020
+#define ESPI_PERIF_PC_TX_CTRL	0x024
+#define	  ESPI_PERIF_PC_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_PERIF_PC_TX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define	  ESPI_PERIF_PC_TX_CTRL_LEN_SHIFT	12
+#define	  ESPI_PERIF_PC_TX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define	  ESPI_PERIF_PC_TX_CTRL_TAG_SHIFT	8
+#define	  ESPI_PERIF_PC_TX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define	  ESPI_PERIF_PC_TX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_PC_TX_PORT	0x028
+#define ESPI_PERIF_NP_TX_DMA	0x030
+#define ESPI_PERIF_NP_TX_CTRL	0x034
+#define   ESPI_PERIF_NP_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_PERIF_NP_TX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define	  ESPI_PERIF_NP_TX_CTRL_LEN_SHIFT	12
+#define	  ESPI_PERIF_NP_TX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define	  ESPI_PERIF_NP_TX_CTRL_TAG_SHIFT	8
+#define	  ESPI_PERIF_NP_TX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define	  ESPI_PERIF_NP_TX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_NP_TX_PORT	0x038
+#define ESPI_OOB_RX_DMA		0x040
+#define ESPI_OOB_RX_CTRL	0x044
+#define	  ESPI_OOB_RX_CTRL_PEND_SERV		BIT(31)
+#define	  ESPI_OOB_RX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_OOB_RX_CTRL_LEN_SHIFT		12
+#define	  ESPI_OOB_RX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_OOB_RX_CTRL_TAG_SHIFT		8
+#define	  ESPI_OOB_RX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_OOB_RX_CTRL_CYC_SHIFT		0
+#define ESPI_OOB_RX_PORT	0x048
+#define ESPI_OOB_TX_DMA		0x050
+#define ESPI_OOB_TX_CTRL	0x054
+#define	  ESPI_OOB_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_OOB_TX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_OOB_TX_CTRL_LEN_SHIFT		12
+#define	  ESPI_OOB_TX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_OOB_TX_CTRL_TAG_SHIFT		8
+#define	  ESPI_OOB_TX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_OOB_TX_CTRL_CYC_SHIFT		0
+#define ESPI_OOB_TX_PORT	0x058
+#define ESPI_FLASH_RX_DMA	0x060
+#define ESPI_FLASH_RX_CTRL	0x064
+#define	  ESPI_FLASH_RX_CTRL_PEND_SERV		BIT(31)
+#define	  ESPI_FLASH_RX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_FLASH_RX_CTRL_LEN_SHIFT		12
+#define	  ESPI_FLASH_RX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_FLASH_RX_CTRL_TAG_SHIFT		8
+#define	  ESPI_FLASH_RX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_FLASH_RX_CTRL_CYC_SHIFT		0
+#define ESPI_FLASH_RX_PORT	0x068
+#define ESPI_FLASH_TX_DMA	0x070
+#define ESPI_FLASH_TX_CTRL	0x074
+#define	  ESPI_FLASH_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_FLASH_TX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_FLASH_TX_CTRL_LEN_SHIFT		12
+#define	  ESPI_FLASH_TX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_FLASH_TX_CTRL_TAG_SHIFT		8
+#define	  ESPI_FLASH_TX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_FLASH_TX_CTRL_CYC_SHIFT		0
+#define ESPI_FLASH_TX_PORT	0x078
+#define ESPI_CTRL2		0x080
+#define   ESPI_CTRL2_MEMCYC_RD_DIS		BIT(6)
+#define   ESPI_CTRL2_MEMCYC_WR_DIS		BIT(4)
+#define ESPI_PERIF_PC_RX_SADDR	0x084
+#define ESPI_PERIF_PC_RX_TADDR	0x088
+#define ESPI_PERIF_PC_RX_MASK	0x08c
+#define   ESPI_PERIF_PC_RX_MASK_CFG_WP		BIT(0)
+#define ESPI_SYSEVT_INT_EN	0x094
+#define ESPI_SYSEVT		0x098
+#define   ESPI_SYSEVT_HOST_RST_ACK		BIT(27)
+#define   ESPI_SYSEVT_RST_CPU_INIT		BIT(26)
+#define   ESPI_SYSEVT_SLV_BOOT_STS		BIT(23)
+#define   ESPI_SYSEVT_NON_FATAL_ERR		BIT(22)
+#define   ESPI_SYSEVT_FATAL_ERR			BIT(21)
+#define   ESPI_SYSEVT_SLV_BOOT_DONE		BIT(20)
+#define   ESPI_SYSEVT_OOB_RST_ACK		BIT(16)
+#define   ESPI_SYSEVT_NMI_OUT			BIT(10)
+#define   ESPI_SYSEVT_SMI_OUT			BIT(9)
+#define   ESPI_SYSEVT_HOST_RST_WARN		BIT(8)
+#define   ESPI_SYSEVT_OOB_RST_WARN		BIT(6)
+#define   ESPI_SYSEVT_PLTRSTN			BIT(5)
+#define   ESPI_SYSEVT_SUSPEND			BIT(4)
+#define   ESPI_SYSEVT_S5_SLEEP			BIT(2)
+#define   ESPI_SYSEVT_S4_SLEEP			BIT(1)
+#define   ESPI_SYSEVT_S3_SLEEP			BIT(0)
+#define ESPI_VW_GPIO_VAL	0x09c
+#define ESPI_GEN_CAP_N_CONF	0x0a0
+#define ESPI_CH0_CAP_N_CONF	0x0a4
+#define ESPI_CH1_CAP_N_CONF	0x0a8
+#define ESPI_CH2_CAP_N_CONF	0x0ac
+#define ESPI_CH3_CAP_N_CONF	0x0b0
+#define ESPI_CH3_CAP_N_CONF2	0x0b4
+#define ESPI_SYSEVT1_INT_EN	0x100
+#define ESPI_SYSEVT1		0x104
+#define   ESPI_SYSEVT1_SUSPEND_ACK		BIT(20)
+#define   ESPI_SYSEVT1_SUSPEND_WARN		BIT(0)
+#define ESPI_SYSEVT_INT_T0	0x110
+#define ESPI_SYSEVT_INT_T1	0x114
+#define ESPI_SYSEVT_INT_T2	0x118
+#define   ESPI_SYSEVT_INT_T2_HOST_RST_WARN	ESPI_SYSEVT_HOST_RST_WARN
+#define   ESPI_SYSEVT_INT_T2_OOB_RST_WARN	ESPI_SYSEVT_OOB_RST_WARN
+#define ESPI_SYSEVT_INT_STS	0x11c
+#define   ESPI_SYSEVT_INT_STS_NMI_OUT		ESPI_SYSEVT_NMI_OUT
+#define   ESPI_SYSEVT_INT_STS_SMI_OUT		ESPI_SYSEVT_SMI_OUT
+#define   ESPI_SYSEVT_INT_STS_HOST_RST_WARN	ESPI_SYSEVT_HOST_RST_WARN
+#define   ESPI_SYSEVT_INT_STS_OOB_RST_WARN	ESPI_SYSEVT_OOB_RST_WARN
+#define   ESPI_SYSEVT_INT_STS_PLTRSTN		ESPI_SYSEVT_PLTRSTN
+#define   ESPI_SYSEVT_INT_STS_SUSPEND		ESPI_SYSEVT_SUSPEND
+#define   ESPI_SYSEVT_INT_STS_S5_SLEEP		ESPI_SYSEVT_INT_S5_SLEEP
+#define   ESPI_SYSEVT_INT_STS_S4_SLEEP		ESPI_SYSEVT_INT_S4_SLEEP
+#define   ESPI_SYSEVT_INT_STS_S3_SLEEP		ESPI_SYSEVT_INT_S3_SLEEP
+#define ESPI_SYSEVT1_INT_T0	0x120
+#define ESPI_SYSEVT1_INT_T1	0x124
+#define ESPI_SYSEVT1_INT_T2	0x128
+#define ESPI_SYSEVT1_INT_STS	0x12c
+#define   ESPI_SYSEVT1_INT_STS_SUSPEND_WARN	ESPI_SYSEVT1_SUSPEND_WARN
+#define ESPI_OOB_RX_DMA_RB_SIZE	0x130
+#define ESPI_OOB_RX_DMA_RD_PTR	0x134
+#define	  ESPI_OOB_RX_DMA_RD_PTR_UPDATE		BIT(31)
+#define ESPI_OOB_RX_DMA_WS_PTR	0x138
+#define   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN	BIT(31)
+#define   ESPI_OOB_RX_DMA_WS_PTR_SP_MASK	GENMASK(27, 16)
+#define   ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT	16
+#define   ESPI_OOB_RX_DMA_WS_PTR_WP_MASK	GENMASK(11, 0)
+#define   ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT	0
+#define ESPI_OOB_TX_DMA_RB_SIZE	0x140
+#define ESPI_OOB_TX_DMA_RD_PTR	0x144
+#define	  ESPI_OOB_TX_DMA_RD_PTR_UPDATE		BIT(31)
+#define ESPI_OOB_TX_DMA_WR_PTR	0x148
+#define	  ESPI_OOB_TX_DMA_WR_PTR_SEND_EN	BIT(31)
+
+/* collect ESPI_INT_STS bits of eSPI channels for convenience */
+#define ESPI_INT_STS_PERIF_BITS			\
+	(ESPI_INT_STS_PERIF_NP_TX_ABT |		\
+	 ESPI_INT_STS_PERIF_PC_TX_ABT |		\
+	 ESPI_INT_STS_PERIF_NP_RX_ABT |		\
+	 ESPI_INT_STS_PERIF_PC_RX_ABT |		\
+	 ESPI_INT_STS_PERIF_NP_TX_ERR |		\
+	 ESPI_INT_STS_PERIF_PC_TX_ERR |		\
+	 ESPI_INT_STS_PERIF_NP_TX_CMPLT |	\
+	 ESPI_INT_STS_PERIF_PC_TX_CMPLT |	\
+	 ESPI_INT_STS_PERIF_PC_RX_CMPLT)
+
+#define ESPI_INT_STS_VW_BITS		\
+	(ESPI_INT_STS_VW_SYSEVT1 |	\
+	 ESPI_INT_STS_VW_GPIOEVT |	\
+	 ESPI_INT_STS_VW_SYSEVT)
+
+#define ESPI_INT_STS_OOB_BITS		\
+	(ESPI_INT_STS_OOB_RX_TMOUT |	\
+	 ESPI_INT_STS_OOB_TX_ERR |	\
+	 ESPI_INT_STS_OOB_TX_ABT |	\
+	 ESPI_INT_STS_OOB_RX_ABT |	\
+	 ESPI_INT_STS_OOB_TX_CMPLT |	\
+	 ESPI_INT_STS_OOB_RX_CMPLT)
+
+#define ESPI_INT_STS_FLASH_BITS		\
+	(ESPI_INT_STS_FLASH_TX_ERR |	\
+	 ESPI_INT_STS_FLASH_TX_ABT |	\
+	 ESPI_INT_STS_FLASH_RX_ABT |	\
+	 ESPI_INT_STS_FLASH_TX_CMPLT |	\
+	 ESPI_INT_STS_FLASH_RX_CMPLT)
+
+/* collect ESPI_INT_EN bits of eSPI channels for convenience */
+#define ESPI_INT_EN_PERIF_BITS			\
+	(ESPI_INT_EN_PERIF_NP_TX_ABT |		\
+	 ESPI_INT_EN_PERIF_PC_TX_ABT |		\
+	 ESPI_INT_EN_PERIF_NP_RX_ABT |		\
+	 ESPI_INT_EN_PERIF_PC_RX_ABT |		\
+	 ESPI_INT_EN_PERIF_NP_TX_ERR |		\
+	 ESPI_INT_EN_PERIF_PC_TX_ERR |		\
+	 ESPI_INT_EN_PERIF_NP_TX_CMPLT |	\
+	 ESPI_INT_EN_PERIF_PC_TX_CMPLT |	\
+	 ESPI_INT_EN_PERIF_PC_RX_CMPLT)
+
+#define ESPI_INT_EN_VW_BITS		\
+	(ESPI_INT_EN_VW_SYSEVT1 |	\
+	 ESPI_INT_EN_VW_GPIOEVT |	\
+	 ESPI_INT_EN_VW_SYSEVT)
+
+#define ESPI_INT_EN_OOB_BITS		\
+	(ESPI_INT_EN_OOB_RX_TMOUT |	\
+	 ESPI_INT_EN_OOB_TX_ERR |	\
+	 ESPI_INT_EN_OOB_TX_ABT |	\
+	 ESPI_INT_EN_OOB_RX_ABT |	\
+	 ESPI_INT_EN_OOB_TX_CMPLT |	\
+	 ESPI_INT_EN_OOB_RX_CMPLT)
+
+#define ESPI_INT_EN_FLASH_BITS		\
+	(ESPI_INT_EN_FLASH_TX_ERR |	\
+	 ESPI_INT_EN_FLASH_TX_ABT |	\
+	 ESPI_INT_EN_FLASH_RX_ABT |	\
+	 ESPI_INT_EN_FLASH_TX_CMPLT |	\
+	 ESPI_INT_EN_FLASH_RX_CMPLT)
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-flash.h b/drivers/soc/aspeed/aspeed-espi-flash.h
new file mode 100644
index 000000000000..1acb9877cb2c
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-flash.h
@@ -0,0 +1,380 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ *
+ * This header includes the data strcuture and the handler
+ * for eSPI flash channel. It is part of Aspeed eSPI slave
+ * driver implementation
+ */
+#ifndef _ASPEED_ESPI_FLASH_H_
+#define _ASPEED_ESPI_FLASH_H_
+
+#define FLASH_MDEV_NAME	"aspeed-espi-flash"
+
+enum aspeed_espi_flash_safs_mode {
+	SAFS_MODE_MIX,
+	SAFS_MODE_SW,
+	SAFS_MODE_HW,
+	SAFS_MODES,
+};
+
+struct aspeed_espi_flash_dma {
+	void *tx_virt;
+	dma_addr_t tx_addr;
+	void *rx_virt;
+	dma_addr_t rx_addr;
+};
+
+struct aspeed_espi_flash {
+	uint32_t safs_mode;
+
+	uint32_t dma_mode;
+	struct aspeed_espi_flash_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	struct mutex get_rx_mtx;
+	struct mutex put_tx_mtx;
+
+	spinlock_t lock;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+static long aspeed_espi_flash_get_rx(struct file *fp,
+				     struct aspeed_espi_ioc *ioc,
+				     struct aspeed_espi_flash *espi_flash)
+{
+	int i, rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	if (fp->f_flags & O_NONBLOCK) {
+		if (mutex_trylock(&espi_flash->get_rx_mtx))
+			return -EBUSY;
+
+		if (!espi_flash->rx_ready) {
+			rc = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+	} else {
+		mutex_lock(&espi_flash->get_rx_mtx);
+
+		if (!espi_flash->rx_ready) {
+			rc = wait_event_interruptible(espi_flash->wq,
+						      espi_flash->rx_ready);
+			if (rc == -ERESTARTSYS) {
+				rc = -EINTR;
+				goto unlock_mtx_n_out;
+			}
+		}
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_FLASH_RX_CTRL, &reg);
+	cyc = (reg & ESPI_FLASH_RX_CTRL_CYC_MASK) >> ESPI_FLASH_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_FLASH_RX_CTRL_TAG_MASK) >> ESPI_FLASH_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_FLASH_RX_CTRL_LEN_MASK) >> ESPI_FLASH_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	switch (cyc) {
+	case ESPI_FLASH_READ:
+	case ESPI_FLASH_WRITE:
+	case ESPI_FLASH_ERASE:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_flash_rwe);
+		break;
+	case ESPI_FLASH_SUC_CMPLT_D_MIDDLE:
+	case ESPI_FLASH_SUC_CMPLT_D_FIRST:
+	case ESPI_FLASH_SUC_CMPLT_D_LAST:
+	case ESPI_FLASH_SUC_CMPLT_D_ONLY:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_flash_cmplt);
+		break;
+	case ESPI_FLASH_SUC_CMPLT:
+	case ESPI_FLASH_UNSUC_CMPLT:
+		pkt_len = len + sizeof(struct espi_flash_cmplt);
+		break;
+	default:
+		rc = -EFAULT;
+		goto unlock_mtx_n_out;
+	}
+
+	if (ioc->pkt_len < pkt_len) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_flash->dma_mode) {
+		memcpy(hdr + 1, espi_flash->dma.rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_FLASH_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_flash->lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_FLASH_RX_CTRL,
+			  ESPI_FLASH_RX_CTRL_PEND_SERV,
+			  ESPI_FLASH_RX_CTRL_PEND_SERV);
+
+	espi_flash->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_flash->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_flash->get_rx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_flash_put_tx(struct file *fp,
+				     struct aspeed_espi_ioc *ioc,
+				     struct aspeed_espi_flash *espi_flash)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	if (!mutex_trylock(&espi_flash->put_tx_mtx))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_FLASH_TX_CTRL, &reg);
+	if (reg & ESPI_FLASH_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_flash->dma_mode) {
+		memcpy(espi_flash->dma.tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_FLASH_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_FLASH_TX_CTRL_CYC_SHIFT) & ESPI_FLASH_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_FLASH_TX_CTRL_TAG_SHIFT) & ESPI_FLASH_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_FLASH_TX_CTRL_LEN_SHIFT) & ESPI_FLASH_TX_CTRL_LEN_MASK)
+		| ESPI_FLASH_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_FLASH_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_flash->put_tx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_flash_ioctl(struct file *fp, unsigned int cmd,
+				    unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_flash *espi_flash = container_of(
+			fp->private_data,
+			struct aspeed_espi_flash,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_FLASH_GET_RX:
+		return aspeed_espi_flash_get_rx(fp, &ioc, espi_flash);
+	case ASPEED_ESPI_FLASH_PUT_TX:
+		return aspeed_espi_flash_put_tx(fp, &ioc, espi_flash);
+	};
+
+	return -EINVAL;
+}
+
+static const struct file_operations aspeed_espi_flash_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_flash_ioctl,
+};
+
+static void aspeed_espi_flash_event(uint32_t sts, struct aspeed_espi_flash *espi_flash)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_FLASH_RX_CMPLT) {
+		spin_lock_irqsave(&espi_flash->lock, flags);
+		espi_flash->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_flash->lock, flags);
+		wake_up_interruptible(&espi_flash->wq);
+	}
+}
+
+static void aspeed_espi_flash_enable(struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_flash_dma *dma = &espi_flash->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_FLASH_SW_MODE_MASK,
+			   (espi_flash->safs_mode << ESPI_CTRL_FLASH_SW_MODE_SHIFT));
+
+	if (espi_flash->dma_mode) {
+		regmap_write(espi_ctrl->map, ESPI_FLASH_TX_DMA, dma->tx_addr);
+		regmap_write(espi_ctrl->map, ESPI_FLASH_RX_DMA, dma->rx_addr);
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_FLASH_TX_DMA_EN | ESPI_CTRL_FLASH_RX_DMA_EN,
+				   ESPI_CTRL_FLASH_TX_DMA_EN | ESPI_CTRL_FLASH_RX_DMA_EN);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_FLASH_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_FLASH_BITS,
+			   ESPI_INT_EN_FLASH_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_FLASH_SW_RDY,
+			   ESPI_CTRL_FLASH_SW_RDY);
+}
+
+static void *aspeed_espi_flash_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc = 0;
+	struct aspeed_espi_flash *espi_flash;
+	struct aspeed_espi_flash_dma *dma;
+
+	espi_flash = devm_kzalloc(dev, sizeof(*espi_flash), GFP_KERNEL);
+	if (!espi_flash)
+		return ERR_PTR(-ENOMEM);
+
+	espi_flash->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_flash->wq);
+
+	spin_lock_init(&espi_flash->lock);
+
+	mutex_init(&espi_flash->put_tx_mtx);
+	mutex_init(&espi_flash->get_rx_mtx);
+
+	if (of_property_read_bool(dev->of_node, "flash,dma-mode"))
+		espi_flash->dma_mode = 1;
+
+	of_property_read_u32(dev->of_node, "flash,safs-mode", &espi_flash->safs_mode);
+	if (espi_flash->safs_mode >= SAFS_MODES) {
+		dev_err(dev, "invalid SAFS mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (espi_flash->dma_mode) {
+		dma = &espi_flash->dma;
+
+		dma->tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						  &dma->tx_addr, GFP_KERNEL);
+		if (!dma->tx_virt) {
+			dev_err(dev, "cannot allocate DMA TX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->rx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						  &dma->rx_addr, GFP_KERNEL);
+		if (!dma->rx_virt) {
+			dev_err(dev, "cannot allocate DMA RX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	espi_flash->mdev.parent = dev;
+	espi_flash->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_flash->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", FLASH_MDEV_NAME);
+	espi_flash->mdev.fops = &aspeed_espi_flash_fops;
+	rc = misc_register(&espi_flash->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_flash_enable(espi_flash);
+
+	return espi_flash;
+}
+
+static void aspeed_espi_flash_free(struct device *dev, struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_flash_dma *dma = &espi_flash->dma;
+
+	if (espi_flash->dma_mode) {
+		dma_free_coherent(dev, PAGE_SIZE, dma->tx_virt, dma->tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->rx_virt, dma->rx_addr);
+	}
+
+	mutex_destroy(&espi_flash->put_tx_mtx);
+	mutex_destroy(&espi_flash->get_rx_mtx);
+
+	misc_deregister(&espi_flash->mdev);
+}
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-ioc.h b/drivers/soc/aspeed/aspeed-espi-ioc.h
new file mode 100644
index 000000000000..e93739c80b5f
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ioc.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_IOC_H
+#define _ASPEED_ESPI_IOC_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * eSPI cycle type encoding
+ *
+ * Section 5.1 Cycle Types and Packet Format,
+ * Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ */
+#define ESPI_PERIF_MEMRD32		0x00
+#define ESPI_PERIF_MEMRD64		0x02
+#define ESPI_PERIF_MEMWR32		0x01
+#define ESPI_PERIF_MEMWR64		0x03
+#define ESPI_PERIF_MSG			0x10
+#define ESPI_PERIF_MSG_D		0x11
+#define ESPI_PERIF_SUC_CMPLT		0x06
+#define ESPI_PERIF_SUC_CMPLT_D_MIDDLE	0x09
+#define ESPI_PERIF_SUC_CMPLT_D_FIRST	0x0b
+#define ESPI_PERIF_SUC_CMPLT_D_LAST	0x0d
+#define ESPI_PERIF_SUC_CMPLT_D_ONLY	0x0f
+#define ESPI_PERIF_UNSUC_CMPLT		0x0c
+#define ESPI_OOB_MSG			0x21
+#define ESPI_FLASH_READ			0x00
+#define ESPI_FLASH_WRITE		0x01
+#define ESPI_FLASH_ERASE		0x02
+#define ESPI_FLASH_SUC_CMPLT		0x06
+#define ESPI_FLASH_SUC_CMPLT_D_MIDDLE	0x09
+#define ESPI_FLASH_SUC_CMPLT_D_FIRST	0x0b
+#define ESPI_FLASH_SUC_CMPLT_D_LAST	0x0d
+#define ESPI_FLASH_SUC_CMPLT_D_ONLY	0x0f
+#define ESPI_FLASH_UNSUC_CMPLT		0x0c
+
+/*
+ * eSPI packet format structure
+ *
+ * Section 5.1 Cycle Types and Packet Format,
+ * Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ */
+struct espi_comm_hdr {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+};
+
+struct espi_perif_mem32 {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_mem64 {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_msg {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t msg_code;
+	uint8_t msg_byte[4];
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_cmplt {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+} __packed;
+
+struct espi_oob_msg {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+};
+
+struct espi_flash_rwe {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_flash_cmplt {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+} __packed;
+
+struct aspeed_espi_ioc {
+	uint32_t pkt_len;
+	uint8_t *pkt;
+};
+
+/*
+ * we choose the longest header and the max payload size
+ * based on the Intel specification to define the maximum
+ * eSPI packet length
+ */
+#define ESPI_PLD_LEN_MIN	(1UL << 6)
+#define ESPI_PLD_LEN_MAX	(1UL << 12)
+#define ESPI_PKT_LEN_MAX	(sizeof(struct espi_perif_msg) + ESPI_PLD_LEN_MAX)
+
+#define __ASPEED_ESPI_IOCTL_MAGIC	0xb8
+
+/* peripheral channel (ch0) */
+#define ASPEED_ESPI_PERIF_PC_GET_RX	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x00, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_PERIF_PC_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x01, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_PERIF_NP_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x02, struct aspeed_espi_ioc)
+/* peripheral channel (ch1) */
+#define ASPEED_ESPI_VW_GET_GPIO_VAL	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x10, uint8_t)
+#define ASPEED_ESPI_VW_PUT_GPIO_VAL	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x11, uint8_t)
+/* out-of-band channel (ch2) */
+#define ASPEED_ESPI_OOB_GET_RX		_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x20, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_OOB_PUT_TX		_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x21, struct aspeed_espi_ioc)
+/* flash channel (ch3) */
+#define ASPEED_ESPI_FLASH_GET_RX	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x30, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_FLASH_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x31, struct aspeed_espi_ioc)
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-oob.h b/drivers/soc/aspeed/aspeed-espi-oob.h
new file mode 100644
index 000000000000..182a9ca1e4cc
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-oob.h
@@ -0,0 +1,611 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ *
+ * This header includes the data strcuture and the handler
+ * for eSPI out-of-band channel. It is part of Aspeed eSPI
+ * slave driver implementation
+ */
+#ifndef _ASPEED_ESPI_OOB_H_
+#define _ASPEED_ESPI_OOB_H_
+
+#define OOB_MDEV_NAME	"aspeed-espi-oob"
+
+/* DMA descriptor is supported since AST2600 */
+#define OOB_DMA_DESC_MAX_NUM	1024
+
+/* DMA TX descriptor type */
+#define OOB_DMA_TX_DESC_CUST	0x04
+
+struct oob_tx_dma_desc {
+	uint32_t data_addr;
+	uint8_t cyc;
+	uint16_t tag : 4;
+	uint16_t len : 12;
+	uint8_t msg_type : 3;
+	uint8_t raz0 : 1;
+	uint8_t pec : 1;
+	uint8_t int_en : 1;
+	uint8_t pause : 1;
+	uint8_t raz1 : 1;
+	uint32_t raz2;
+	uint32_t raz3;
+} __packed;
+
+struct oob_rx_dma_desc {
+	uint32_t data_addr;
+	uint8_t cyc;
+	uint16_t tag : 4;
+	uint16_t len : 12;
+	uint8_t raz : 7;
+	uint8_t dirty : 1;
+} __packed;
+
+struct aspeed_espi_oob_dma {
+	uint32_t tx_desc_num;
+	uint32_t rx_desc_num;
+
+	struct oob_tx_dma_desc *tx_desc;
+	dma_addr_t tx_desc_addr;
+
+	struct oob_rx_dma_desc *rx_desc;
+	dma_addr_t rx_desc_addr;
+
+	void *tx_virt;
+	dma_addr_t tx_addr;
+
+	void *rx_virt;
+	dma_addr_t rx_addr;
+};
+
+struct aspeed_espi_oob {
+	uint32_t dma_mode;
+	struct aspeed_espi_oob_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	struct mutex get_rx_mtx;
+	struct mutex put_tx_mtx;
+
+	spinlock_t lock;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+/* descriptor-based RX DMA handling */
+static long aspeed_espi_oob_dma_desc_get_rx(struct file *fp,
+					    struct aspeed_espi_ioc *ioc,
+					    struct aspeed_espi_oob *espi_oob)
+{
+	int rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t wptr, sptr;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct oob_rx_dma_desc *d;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR, &reg);
+	wptr = (reg & ESPI_OOB_RX_DMA_WS_PTR_WP_MASK) >> ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT;
+	sptr = (reg & ESPI_OOB_RX_DMA_WS_PTR_SP_MASK) >> ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT;
+
+	d = &espi_oob->dma.rx_desc[sptr];
+
+	if (!d->dirty)
+		return -EFAULT;
+
+	pkt_len = ((d->len) ? d->len : 0x1000) + sizeof(struct espi_comm_hdr);
+
+	if (ioc->pkt_len < pkt_len)
+		return -EINVAL;
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt)
+		return -ENOMEM;
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = d->cyc;
+	hdr->tag = d->tag;
+	hdr->len_h = d->len >> 8;
+	hdr->len_l = d->len & 0xff;
+	memcpy(hdr + 1, espi_oob->dma.rx_virt + (PAGE_SIZE * sptr), pkt_len - sizeof(*hdr));
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_oob->lock, flags);
+
+	/* make current descriptor available again */
+	d->dirty = 0;
+
+	sptr = (sptr + 1) % espi_oob->dma.rx_desc_num;
+	wptr = (wptr + 1) % espi_oob->dma.rx_desc_num;
+
+	reg = ((wptr << ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT) & ESPI_OOB_RX_DMA_WS_PTR_WP_MASK)
+		| ((sptr << ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT) & ESPI_OOB_RX_DMA_WS_PTR_SP_MASK)
+		| ESPI_OOB_RX_DMA_WS_PTR_RECV_EN;
+	regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR, reg);
+
+	/* set ready flag base on the next RX descriptor */
+	espi_oob->rx_ready = espi_oob->dma.rx_desc[sptr].dirty;
+
+	spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_get_rx(struct file *fp,
+				   struct aspeed_espi_ioc *ioc,
+				   struct aspeed_espi_oob *espi_oob)
+{
+	int i, rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	if (fp->f_flags & O_NONBLOCK) {
+		if (mutex_trylock(&espi_oob->get_rx_mtx))
+			return -EBUSY;
+
+		if (!espi_oob->rx_ready) {
+			rc = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+	} else {
+		mutex_lock(&espi_oob->get_rx_mtx);
+
+		if (!espi_oob->rx_ready) {
+			rc = wait_event_interruptible(espi_oob->wq,
+						      espi_oob->rx_ready);
+			if (rc == -ERESTARTSYS) {
+				rc = -EINTR;
+				goto unlock_mtx_n_out;
+			}
+		}
+	}
+
+	if (espi_oob->dma_mode && espi_ctrl->version != ESPI_AST2500) {
+		rc = aspeed_espi_oob_dma_desc_get_rx(fp, ioc, espi_oob);
+		goto unlock_mtx_n_out;
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_OOB_RX_CTRL, &reg);
+	cyc = (reg & ESPI_OOB_RX_CTRL_CYC_MASK) >> ESPI_OOB_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_OOB_RX_CTRL_TAG_MASK) >> ESPI_OOB_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_OOB_RX_CTRL_LEN_MASK) >> ESPI_OOB_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) + sizeof(struct espi_comm_hdr);
+
+	if (ioc->pkt_len < pkt_len) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_oob->dma_mode) {
+		memcpy(hdr + 1, espi_oob->dma.rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_OOB_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_oob->lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_OOB_RX_CTRL,
+			  ESPI_OOB_RX_CTRL_PEND_SERV,
+			  ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	espi_oob->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_oob->get_rx_mtx);
+
+	return rc;
+}
+
+/* descriptor-based TX DMA handling */
+static long aspeed_espi_oob_dma_desc_put_tx(struct file *fp,
+					    struct aspeed_espi_ioc *ioc,
+					    struct aspeed_espi_oob *espi_oob)
+{
+	int rc = 0;
+	uint32_t rptr, wptr;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct oob_tx_dma_desc *d;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	pkt = vzalloc(ioc->pkt_len);
+	if (!pkt)
+		return -ENOMEM;
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/* kick HW to reflect the up-to-date read/write pointer */
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_RD_PTR,
+		     ESPI_OOB_TX_DMA_RD_PTR_UPDATE);
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_DMA_RD_PTR, &rptr);
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_DMA_WR_PTR, &wptr);
+
+	if (((wptr + 1) % espi_oob->dma.tx_desc_num) == rptr)
+		return -EBUSY;
+
+	d = &espi_oob->dma.tx_desc[wptr];
+	d->cyc = hdr->cyc;
+	d->tag = hdr->tag;
+	d->len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+	d->msg_type = OOB_DMA_TX_DESC_CUST;
+
+	memcpy(espi_oob->dma.tx_virt + (PAGE_SIZE * wptr), hdr + 1,
+	       ioc->pkt_len - sizeof(*hdr));
+
+	dma_wmb();
+
+	wptr = (wptr + 1) % espi_oob->dma.tx_desc_num;
+	wptr |= ESPI_OOB_TX_DMA_WR_PTR_SEND_EN;
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_WR_PTR, wptr);
+
+free_n_out:
+	vfree(pkt);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_put_tx(struct file *fp,
+				   struct aspeed_espi_ioc *ioc,
+				   struct aspeed_espi_oob *espi_oob)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	if (!mutex_trylock(&espi_oob->put_tx_mtx))
+		return -EBUSY;
+
+	if (espi_oob->dma_mode && espi_ctrl->version != ESPI_AST2500) {
+		rc = aspeed_espi_oob_dma_desc_put_tx(fp, ioc, espi_oob);
+		goto unlock_mtx_n_out;
+	}
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_CTRL, &reg);
+	if (reg & ESPI_OOB_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_mtx_n_out;
+	}
+
+	if (ioc->pkt_len > ESPI_PKT_LEN_MAX) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_oob->dma_mode) {
+		memcpy(espi_oob->dma.tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_OOB_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_OOB_TX_CTRL_CYC_SHIFT) & ESPI_OOB_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_OOB_TX_CTRL_TAG_SHIFT) & ESPI_OOB_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_OOB_TX_CTRL_LEN_SHIFT) & ESPI_OOB_TX_CTRL_LEN_MASK)
+		| ESPI_OOB_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_oob->put_tx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_ioctl(struct file *fp, unsigned int cmd,
+				    unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_oob *espi_oob = container_of(
+			fp->private_data,
+			struct aspeed_espi_oob,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_OOB_GET_RX:
+		return aspeed_espi_oob_get_rx(fp, &ioc, espi_oob);
+	case ASPEED_ESPI_OOB_PUT_TX:
+		return aspeed_espi_oob_put_tx(fp, &ioc, espi_oob);
+	};
+
+	return -EINVAL;
+}
+
+static const struct file_operations aspeed_espi_oob_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_oob_ioctl,
+};
+
+static void aspeed_espi_oob_event(uint32_t sts, struct aspeed_espi_oob *espi_oob)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_OOB_RX_CMPLT) {
+		spin_lock_irqsave(&espi_oob->lock, flags);
+		espi_oob->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+		wake_up_interruptible(&espi_oob->wq);
+	}
+}
+
+static void aspeed_espi_oob_enable(struct aspeed_espi_oob *espi_oob)
+{
+	int i;
+	struct aspeed_espi_oob_dma *dma = &espi_oob->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_SW_RDY | ESPI_CTRL_OOB_RX_SW_RST, 0);
+
+	if (espi_oob->dma_mode)
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN, 0);
+	else
+		regmap_write(espi_ctrl->map, ESPI_OOB_RX_CTRL, ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	/*
+	 * cleanup OOB RX FIFO to get rid of the data
+	 * of OOB early init side-effect
+	 */
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_RX_SW_RST, ESPI_CTRL_OOB_RX_SW_RST);
+
+	regmap_write(espi_ctrl->map, ESPI_OOB_RX_CTRL,
+		     ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	if (espi_oob->dma_mode) {
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN);
+
+		if (espi_ctrl->version == ESPI_AST2500) {
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA, dma->tx_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA, dma->rx_addr);
+		} else {
+			for (i = 0; i < dma->tx_desc_num; ++i)
+				dma->tx_desc[i].data_addr = dma->tx_addr + (i * PAGE_SIZE);
+
+			for (i = 0; i < dma->rx_desc_num; ++i) {
+				dma->rx_desc[i].data_addr = dma->rx_addr + (i * PAGE_SIZE);
+				dma->rx_desc[i].dirty = 0;
+			}
+
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA, dma->tx_desc_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_RB_SIZE, dma->tx_desc_num);
+
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA, dma->rx_desc_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA_RB_SIZE, dma->rx_desc_num);
+			regmap_update_bits(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR,
+					   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN,
+					   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN);
+		}
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_OOB_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_OOB_BITS,
+			   ESPI_INT_EN_OOB_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_SW_RDY,
+			   ESPI_CTRL_OOB_SW_RDY);
+}
+
+static void *aspeed_espi_oob_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc = 0;
+	struct aspeed_espi_oob *espi_oob;
+	struct aspeed_espi_oob_dma *dma;
+
+	espi_oob = devm_kzalloc(dev, sizeof(*espi_oob), GFP_KERNEL);
+	if (!espi_oob)
+		return ERR_PTR(-ENOMEM);
+
+	espi_oob->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_oob->wq);
+
+	spin_lock_init(&espi_oob->lock);
+
+	mutex_init(&espi_oob->put_tx_mtx);
+	mutex_init(&espi_oob->get_rx_mtx);
+
+	if (of_property_read_bool(dev->of_node, "oob,dma-mode"))
+		espi_oob->dma_mode = 1;
+
+	if (espi_oob->dma_mode) {
+		dma = &espi_oob->dma;
+
+		/* Descriptor based OOB DMA is supported since AST2600 */
+		if (espi_ctrl->version != ESPI_AST2500) {
+			of_property_read_u32(dev->of_node, "oob,dma-tx-desc-num",
+					     &dma->tx_desc_num);
+			of_property_read_u32(dev->of_node, "oob,dma-rx-desc-num",
+					     &dma->rx_desc_num);
+
+			if (!dma->tx_desc_num || !dma->rx_desc_num) {
+				dev_err(dev, "invalid zero number of DMA channels\n");
+				return ERR_PTR(-EINVAL);
+			}
+
+			if (dma->tx_desc_num >= OOB_DMA_DESC_MAX_NUM ||
+			    dma->rx_desc_num >= OOB_DMA_DESC_MAX_NUM) {
+				dev_err(dev, "too many number of DMA channels\n");
+				return ERR_PTR(-EINVAL);
+			}
+
+			dma->tx_desc = dma_alloc_coherent(dev,
+							  sizeof(*dma->tx_desc) * dma->tx_desc_num,
+							  &dma->tx_desc_addr, GFP_KERNEL);
+			if (!dma->tx_desc) {
+				dev_err(dev, "cannot allocate DMA TX descriptor\n");
+				return ERR_PTR(-ENOMEM);
+			}
+
+			dma->rx_desc = dma_alloc_coherent(dev,
+							  sizeof(*dma->rx_desc) * dma->rx_desc_num,
+							  &dma->rx_desc_addr, GFP_KERNEL);
+			if (!dma->rx_desc) {
+				dev_err(dev, "cannot allocate DMA RX descriptor\n");
+				return ERR_PTR(-ENOMEM);
+			}
+		}
+
+		/*
+		 * DMA descriptors are consumed in the circular
+		 * queue paradigm. Therefore, one dummy slot is
+		 * reserved to detect the full condition.
+		 *
+		 * For AST2500 without DMA descriptors supported,
+		 * the number of the queue slot should be 1 here.
+		 */
+		dma->tx_desc_num += 1;
+		dma->rx_desc_num += 1;
+
+		dma->tx_virt = dma_alloc_coherent(dev, PAGE_SIZE * dma->tx_desc_num,
+						  &dma->tx_addr, GFP_KERNEL);
+		if (!dma->tx_virt) {
+			dev_err(dev, "cannot allocate DMA TX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->rx_virt = dma_alloc_coherent(dev, PAGE_SIZE * dma->rx_desc_num,
+						  &dma->rx_addr, GFP_KERNEL);
+		if (!dma->rx_virt) {
+			dev_err(dev, "cannot allocate DMA RX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	espi_oob->mdev.parent = dev;
+	espi_oob->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_oob->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", OOB_MDEV_NAME);
+	espi_oob->mdev.fops = &aspeed_espi_oob_fops;
+	rc = misc_register(&espi_oob->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_oob_enable(espi_oob);
+
+	return espi_oob;
+}
+
+static void aspeed_espi_oob_free(struct device *dev, struct aspeed_espi_oob *espi_oob)
+{
+	struct aspeed_espi_oob_dma *dma = &espi_oob->dma;
+
+	if (espi_oob->dma_mode) {
+		dma_free_coherent(dev, sizeof(*dma->tx_desc) * dma->tx_desc_num,
+				  dma->tx_desc, dma->tx_desc_addr);
+		dma_free_coherent(dev, sizeof(*dma->rx_desc) * dma->rx_desc_num,
+				  dma->rx_desc, dma->rx_desc_addr);
+		dma_free_coherent(dev, PAGE_SIZE * dma->tx_desc_num,
+				  dma->tx_virt, dma->tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE * dma->rx_desc_num,
+				  dma->rx_virt, dma->rx_addr);
+	}
+
+	mutex_destroy(&espi_oob->put_tx_mtx);
+	mutex_destroy(&espi_oob->get_rx_mtx);
+
+	misc_deregister(&espi_oob->mdev);
+}
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-perif.h b/drivers/soc/aspeed/aspeed-espi-perif.h
new file mode 100644
index 000000000000..0bdd71ee828a
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-perif.h
@@ -0,0 +1,539 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ *
+ * This header includes the data strcuture and the handler
+ * for eSPI peripheral channel. It is part of Aspeed eSPI
+ * slave driver implementation
+ */
+#ifndef _ASPEED_ESPI_PERIF_H_
+#define _ASPEED_ESPI_PERIF_H_
+
+#define PERIF_MDEV_NAME		"aspeed-espi-peripheral"
+#define PERIF_MEMCYC_UNLOCK_KEY	0xfedc756e
+#define PERIF_MEMCYC_SIZE_MIN	0x10000
+
+struct aspeed_espi_perif_dma {
+	void *pc_tx_virt;
+	dma_addr_t pc_tx_addr;
+	void *pc_rx_virt;
+	dma_addr_t pc_rx_addr;
+	void *np_tx_virt;
+	dma_addr_t np_tx_addr;
+};
+
+struct aspeed_espi_perif {
+	uint32_t mcyc_enable;
+	void *mcyc_virt;
+	phys_addr_t mcyc_saddr;
+	phys_addr_t mcyc_taddr;
+	uint32_t mcyc_size;
+	uint32_t mcyc_mask;
+
+	uint32_t dma_mode;
+	struct aspeed_espi_perif_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	spinlock_t lock;
+	struct mutex pc_rx_mtx;
+	struct mutex pc_tx_mtx;
+	struct mutex np_tx_mtx;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+static long aspeed_espi_perif_pc_get_rx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	unsigned long flags;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (fp->f_flags & O_NONBLOCK) {
+		if (mutex_trylock(&espi_perif->pc_rx_mtx))
+			return -EBUSY;
+
+		if (!espi_perif->rx_ready) {
+			rc = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+	} else {
+		mutex_lock(&espi_perif->pc_rx_mtx);
+
+		if (!espi_perif->rx_ready) {
+			rc = wait_event_interruptible(espi_perif->wq,
+						      espi_perif->rx_ready);
+			if (rc == -ERESTARTSYS) {
+				rc = -EINTR;
+				goto unlock_mtx_n_out;
+			}
+		}
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_PERIF_PC_RX_CTRL, &reg);
+	cyc = (reg & ESPI_PERIF_PC_RX_CTRL_CYC_MASK) >> ESPI_PERIF_PC_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_PERIF_PC_RX_CTRL_TAG_MASK) >> ESPI_PERIF_PC_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_PERIF_PC_RX_CTRL_LEN_MASK) >> ESPI_PERIF_PC_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	switch (cyc) {
+	case ESPI_PERIF_MSG:
+		pkt_len = len + sizeof(struct espi_perif_msg);
+		break;
+	case ESPI_PERIF_MSG_D:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_perif_msg);
+		break;
+	case ESPI_PERIF_SUC_CMPLT_D_MIDDLE:
+	case ESPI_PERIF_SUC_CMPLT_D_FIRST:
+	case ESPI_PERIF_SUC_CMPLT_D_LAST:
+	case ESPI_PERIF_SUC_CMPLT_D_ONLY:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_perif_cmplt);
+		break;
+	case ESPI_PERIF_SUC_CMPLT:
+	case ESPI_PERIF_UNSUC_CMPLT:
+		pkt_len = len + sizeof(struct espi_perif_cmplt);
+		break;
+	default:
+		rc = -EFAULT;
+		goto unlock_mtx_n_out;
+	}
+
+	if (ioc->pkt_len < pkt_len) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_perif->dma_mode) {
+		memcpy(hdr + 1, espi_perif->dma.pc_rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_PERIF_PC_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_perif->lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_PERIF_PC_RX_CTRL,
+			  ESPI_PERIF_PC_RX_CTRL_PEND_SERV,
+			  ESPI_PERIF_PC_RX_CTRL_PEND_SERV);
+
+	espi_perif->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_perif->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_perif->pc_rx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_perif_pc_put_tx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (!mutex_trylock(&espi_perif->pc_tx_mtx))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_PERIF_PC_TX_CTRL, &reg);
+	if (reg & ESPI_PERIF_PC_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_perif->dma_mode) {
+		memcpy(espi_perif->dma.pc_tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_PERIF_PC_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_PERIF_PC_TX_CTRL_CYC_SHIFT) & ESPI_PERIF_PC_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_PERIF_PC_TX_CTRL_TAG_SHIFT) & ESPI_PERIF_PC_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_PERIF_PC_TX_CTRL_LEN_SHIFT) & ESPI_PERIF_PC_TX_CTRL_LEN_MASK)
+		| ESPI_PERIF_PC_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_PERIF_PC_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_n_out:
+	mutex_unlock(&espi_perif->pc_tx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_perif_np_put_tx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (!mutex_trylock(&espi_perif->np_tx_mtx))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_PERIF_NP_TX_CTRL, &reg);
+	if (reg & ESPI_PERIF_NP_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_perif->dma_mode) {
+		memcpy(espi_perif->dma.np_tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_PERIF_NP_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_PERIF_NP_TX_CTRL_CYC_SHIFT) & ESPI_PERIF_NP_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_PERIF_NP_TX_CTRL_TAG_SHIFT) & ESPI_PERIF_NP_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_PERIF_NP_TX_CTRL_LEN_SHIFT) & ESPI_PERIF_NP_TX_CTRL_LEN_MASK)
+		| ESPI_PERIF_NP_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_PERIF_NP_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_n_out:
+	mutex_unlock(&espi_perif->np_tx_mtx);
+
+	return rc;
+
+}
+
+static long aspeed_espi_perif_ioctl(struct file *fp, unsigned int cmd,
+				    unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_perif *espi_perif = container_of(
+			fp->private_data,
+			struct aspeed_espi_perif,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_PERIF_PC_GET_RX:
+		return aspeed_espi_perif_pc_get_rx(fp, &ioc, espi_perif);
+	case ASPEED_ESPI_PERIF_PC_PUT_TX:
+		return aspeed_espi_perif_pc_put_tx(fp, &ioc, espi_perif);
+	case ASPEED_ESPI_PERIF_NP_PUT_TX:
+		return aspeed_espi_perif_np_put_tx(fp, &ioc, espi_perif);
+	};
+
+	return -EINVAL;
+}
+
+static int aspeed_espi_perif_mmap(struct file *fp, struct vm_area_struct *vma)
+{
+	struct aspeed_espi_perif *espi_perif = container_of(
+			fp->private_data,
+			struct aspeed_espi_perif,
+			mdev);
+	unsigned long vm_size = vma->vm_end - vma->vm_start;
+	pgprot_t prot = vma->vm_page_prot;
+
+	if (!espi_perif->mcyc_enable)
+		return -EPERM;
+
+	if (((vma->vm_pgoff << PAGE_SHIFT) + vm_size) > espi_perif->mcyc_size)
+		return -EINVAL;
+
+	prot = pgprot_noncached(prot);
+
+	if (remap_pfn_range(vma, vma->vm_start,
+			    (espi_perif->mcyc_taddr >> PAGE_SHIFT) + vma->vm_pgoff,
+			    vm_size, prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static const struct file_operations aspeed_espi_perif_fops = {
+	.owner = THIS_MODULE,
+	.mmap = aspeed_espi_perif_mmap,
+	.unlocked_ioctl = aspeed_espi_perif_ioctl,
+};
+
+static void aspeed_espi_perif_event(uint32_t sts, struct aspeed_espi_perif *espi_perif)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_PERIF_PC_RX_CMPLT) {
+		spin_lock_irqsave(&espi_perif->lock, flags);
+		espi_perif->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_perif->lock, flags);
+
+		wake_up_interruptible(&espi_perif->wq);
+	}
+}
+
+static void aspeed_espi_perif_enable(struct aspeed_espi_perif *espi_perif)
+{
+	struct aspeed_espi_perif_dma *dma = &espi_perif->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (espi_perif->mcyc_enable) {
+		if (espi_ctrl->version == ESPI_AST2500) {
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     PERIF_MEMCYC_UNLOCK_KEY);
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     espi_perif->mcyc_mask);
+		} else {
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     espi_perif->mcyc_mask | ESPI_PERIF_PC_RX_MASK_CFG_WP);
+			regmap_update_bits(espi_ctrl->map, ESPI_CTRL2,
+					   ESPI_CTRL2_MEMCYC_RD_DIS | ESPI_CTRL2_MEMCYC_WR_DIS, 0);
+		}
+
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_SADDR, espi_perif->mcyc_saddr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_TADDR, espi_perif->mcyc_taddr);
+	}
+
+	if (espi_perif->dma_mode) {
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_DMA, dma->pc_rx_addr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_TX_DMA, dma->pc_tx_addr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_NP_TX_DMA, dma->np_tx_addr);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_PERIF_NP_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_RX_DMA_EN,
+				   ESPI_CTRL_PERIF_NP_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_RX_DMA_EN);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_PERIF_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_PERIF_BITS,
+			   ESPI_INT_EN_PERIF_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_PERIF_SW_RDY,
+			   ESPI_CTRL_PERIF_SW_RDY);
+}
+
+static void *aspeed_espi_perif_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc;
+	struct aspeed_espi_perif *espi_perif;
+	struct aspeed_espi_perif_dma *dma;
+
+	espi_perif = devm_kzalloc(dev, sizeof(*espi_perif), GFP_KERNEL);
+	if (!espi_perif)
+		return ERR_PTR(-ENOMEM);
+
+	espi_perif->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_perif->wq);
+
+	spin_lock_init(&espi_perif->lock);
+
+	mutex_init(&espi_perif->pc_rx_mtx);
+	mutex_init(&espi_perif->pc_tx_mtx);
+	mutex_init(&espi_perif->np_tx_mtx);
+
+	espi_perif->mcyc_enable = of_property_read_bool(dev->of_node, "perif,memcyc-enable");
+	if (espi_perif->mcyc_enable) {
+		rc = of_property_read_u32(dev->of_node, "perif,memcyc-src-addr",
+					  &espi_perif->mcyc_saddr);
+		if (rc) {
+			dev_err(dev, "cannot get Host source address for memory cycle\n");
+			return ERR_PTR(-ENODEV);
+		}
+
+		rc = of_property_read_u32(dev->of_node, "perif,memcyc-size",
+					  &espi_perif->mcyc_size);
+		if (rc) {
+			dev_err(dev, "cannot get size for memory cycle\n");
+			return ERR_PTR(-ENODEV);
+		}
+
+		if (espi_perif->mcyc_size < PERIF_MEMCYC_SIZE_MIN)
+			espi_perif->mcyc_size = PERIF_MEMCYC_SIZE_MIN;
+		else
+			espi_perif->mcyc_size = roundup_pow_of_two(espi_perif->mcyc_size);
+
+		espi_perif->mcyc_mask = ~(espi_perif->mcyc_size - 1);
+		espi_perif->mcyc_virt = dma_alloc_coherent(dev, espi_perif->mcyc_size,
+							   &espi_perif->mcyc_taddr, GFP_KERNEL);
+		if (!espi_perif->mcyc_virt) {
+			dev_err(dev, "cannot allocate memory cycle region\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	if (of_property_read_bool(dev->of_node, "perif,dma-mode")) {
+		dma = &espi_perif->dma;
+
+		dma->pc_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						     &dma->pc_tx_addr, GFP_KERNEL);
+		if (!dma->pc_tx_virt) {
+			dev_err(dev, "cannot allocate posted TX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->pc_rx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						     &dma->pc_rx_addr, GFP_KERNEL);
+		if (!dma->pc_rx_virt) {
+			dev_err(dev, "cannot allocate posted RX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->np_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+				&dma->np_tx_addr, GFP_KERNEL);
+		if (!dma->np_tx_virt) {
+			dev_err(dev, "cannot allocate non-posted TX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		espi_perif->dma_mode = 1;
+	}
+
+	espi_perif->mdev.parent = dev;
+	espi_perif->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_perif->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", PERIF_MDEV_NAME);
+	espi_perif->mdev.fops = &aspeed_espi_perif_fops;
+	rc = misc_register(&espi_perif->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_perif_enable(espi_perif);
+
+	return espi_perif;
+}
+
+static void aspeed_espi_perif_free(struct device *dev, struct aspeed_espi_perif *espi_perif)
+{
+	struct aspeed_espi_perif_dma *dma = &espi_perif->dma;
+
+	if (espi_perif->mcyc_virt)
+		dma_free_coherent(dev, espi_perif->mcyc_size,
+				  espi_perif->mcyc_virt,
+				  espi_perif->mcyc_taddr);
+
+	if (espi_perif->dma_mode) {
+		dma_free_coherent(dev, PAGE_SIZE, dma->pc_tx_virt,
+				  dma->pc_tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->pc_rx_virt,
+				  dma->pc_rx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->np_tx_virt,
+				  dma->np_tx_addr);
+	}
+
+	mutex_destroy(&espi_perif->pc_tx_mtx);
+	mutex_destroy(&espi_perif->np_tx_mtx);
+
+	misc_deregister(&espi_perif->mdev);
+}
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-vw.h b/drivers/soc/aspeed/aspeed-espi-vw.h
new file mode 100644
index 000000000000..3d49366c912e
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-vw.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ *
+ * This header includes the data strcuture and the handler
+ * for eSPI virtual wire channel. It is part of Aspeed eSPI
+ * slave driver implementation
+ */
+#ifndef _ASPEED_ESPI_VW_H_
+#define _ASPEED_ESPI_VW_H_
+
+#define VW_MDEV_NAME	"aspeed-espi-vw"
+
+struct aspeed_espi_vw {
+	int irq;
+	int irq_reset;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+static long aspeed_espi_vw_ioctl(struct file *fp, unsigned int cmd,
+				    unsigned long arg)
+{
+	uint32_t val;
+
+	struct aspeed_espi_vw *espi_vw = container_of(
+			fp->private_data,
+			struct aspeed_espi_vw,
+			mdev);
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	switch (cmd) {
+	case ASPEED_ESPI_VW_GET_GPIO_VAL:
+		regmap_read(espi_ctrl->map, ESPI_VW_GPIO_VAL, &val);
+		if (put_user(val, (uint32_t __user *)arg))
+			return -EFAULT;
+		break;
+
+	case ASPEED_ESPI_VW_PUT_GPIO_VAL:
+		if (get_user(val, (uint32_t __user *)arg))
+			return -EFAULT;
+		regmap_write(espi_ctrl->map, ESPI_VW_GPIO_VAL, val);
+		break;
+
+	default:
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
+static const struct file_operations aspeed_espi_vw_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_vw_ioctl,
+};
+
+static void aspeed_espi_vw_event(uint32_t sts, struct aspeed_espi_vw *espi_vw)
+{
+	uint32_t sysevt_sts;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	regmap_read(espi_ctrl->map, ESPI_INT_STS, &sts);
+
+	if (sts & ESPI_INT_STS_VW_SYSEVT) {
+		regmap_read(espi_ctrl->map, ESPI_SYSEVT_INT_STS, &sysevt_sts);
+
+		if (espi_ctrl->version == ESPI_AST2500) {
+			if (sysevt_sts & ESPI_SYSEVT_INT_STS_HOST_RST_WARN)
+				regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+						   ESPI_SYSEVT_HOST_RST_ACK,
+						   ESPI_SYSEVT_HOST_RST_ACK);
+
+			if (sysevt_sts & ESPI_SYSEVT_INT_STS_OOB_RST_WARN)
+				regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+						   ESPI_SYSEVT_OOB_RST_ACK,
+						   ESPI_SYSEVT_OOB_RST_ACK);
+		}
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_STS, sysevt_sts);
+	}
+
+	if (sts & ESPI_INT_STS_VW_SYSEVT1) {
+		regmap_read(espi_ctrl->map, ESPI_SYSEVT1_INT_STS, &sysevt_sts);
+
+		if (sysevt_sts & ESPI_SYSEVT1_INT_STS_SUSPEND_WARN)
+			regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT1,
+					   ESPI_SYSEVT1_SUSPEND_ACK,
+					   ESPI_SYSEVT1_SUSPEND_ACK);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_STS, sysevt_sts);
+	}
+}
+
+static void aspeed_espi_vw_enable(struct aspeed_espi_vw *espi_vw)
+{
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_VW_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_VW_BITS,
+			   ESPI_INT_EN_VW_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_VW_SW_RDY,
+			   ESPI_CTRL_VW_SW_RDY);
+}
+
+static void *aspeed_espi_vw_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc;
+	struct aspeed_espi_vw *espi_vw;
+
+	espi_vw = devm_kzalloc(dev, sizeof(*espi_vw), GFP_KERNEL);
+	if (!espi_vw)
+		return ERR_PTR(-ENOMEM);
+
+	espi_vw->ctrl = espi_ctrl;
+
+	espi_vw->mdev.parent = dev;
+	espi_vw->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_vw->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", VW_MDEV_NAME);
+	espi_vw->mdev.fops = &aspeed_espi_vw_fops;
+	rc = misc_register(&espi_vw->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_vw_enable(espi_vw);
+
+	return espi_vw;
+}
+
+static void aspeed_espi_vw_free(struct device *dev, struct aspeed_espi_vw *espi_vw)
+{
+	misc_deregister(&espi_vw->mdev);
+}
+
+#endif
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Wed Aug 25 23:16:23 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 26 Aug 2021 14:16:23 +0800
Subject: [PATCH v3 4/4] ARM: dts: aspeed: Add eSPI node
In-Reply-To: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210826061623.6352-5-chiawei_wang@aspeedtech.com>

Add eSPI to the device tree for Aspeed 5/6th generation SoCs.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 arch/arm/boot/dts/aspeed-g6.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index f96607b7b4e2..47dc0b3993d1 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -364,6 +364,23 @@
 				status = "disabled";
 			};
 
+			espi: espi at 1e6ee000 {
+				compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
+				reg = <0x1e6ee000 0x1000>;
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1e6ee000 0x1000>;
+
+				espi_ctrl: espi-ctrl at 0 {
+					compatible = "aspeed,ast2600-espi-ctrl";
+					reg = <0x0 0x800>;
+					interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
+					status = "disabled";
+				};
+			};
+
 			gpio0: gpio at 1e780000 {
 				#gpio-cells = <2>;
 				gpio-controller;
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Wed Aug 25 23:16:20 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 26 Aug 2021 14:16:20 +0800
Subject: [PATCH v3 1/4] dt-bindings: aspeed: Add eSPI controller
In-Reply-To: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210826061623.6352-2-chiawei_wang@aspeedtech.com>

Add dt-bindings for Aspeed eSPI controller

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 .../devicetree/bindings/soc/aspeed/espi.yaml  | 157 ++++++++++++++++++
 1 file changed, 157 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml

diff --git a/Documentation/devicetree/bindings/soc/aspeed/espi.yaml b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
new file mode 100644
index 000000000000..f8948efde379
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
@@ -0,0 +1,157 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# # Copyright (c) 2021 Aspeed Technology Inc.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/aspeed/espi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Aspeed eSPI Controller
+
+maintainers:
+  - Chia-Wei Wang <chiawei_wang at aspeedtech.com>
+  - Ryan Chen <ryan_chen at aspeedtech.com>
+
+description:
+  Aspeed eSPI controller implements a slave side eSPI endpoint device
+  supporting the four eSPI channels, namely peripheral, virtual wire,
+  out-of-band, and flash.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - aspeed,ast2500-espi
+          - aspeed,ast2600-espi
+      - const: simple-mfd
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+  espi-ctrl:
+    type: object
+
+    properties:
+      compatible:
+        items:
+          - enum:
+              - aspeed,ast2500-espi-ctrl
+              - aspeed,ast2600-espi-ctrl
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      perif,memcyc-enable:
+        type: boolean
+        description: Enable memory cycle over eSPI peripheral channel
+
+      perif,memcyc-src-addr:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: The Host side address to be decoded into the memory cycle over eSPI peripheral channel
+
+      perif,memcyc-size:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: The size of the memory region allocated for the memory cycle over eSPI peripheral channel
+        minimum: 65536
+
+      perif,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI peripheral channel
+
+      oob,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI out-of-band channel
+
+      oob,dma-tx-desc-num:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 2
+        maximum: 1023
+        description: The number of TX descriptors available for eSPI OOB DMA engine
+
+      oob,dma-rx-desc-num:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 2
+        maximum: 1023
+        description: The number of RX descriptors available for eSPI OOB DMA engine
+
+      flash,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI flash channel
+
+      flash,safs-mode:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [ 0, 1, 2 ]
+        default: 0
+        description: Slave-Attached-Sharing-Flash mode, 0->Mix, 1->SW, 2->HW
+
+    dependencies:
+      perif,memcyc-src-addr: [ "perif,memcyc-enable" ]
+      perif,memcyc-size: [ "perif,memcyc-enable" ]
+      oob,dma-tx-desc-num: [ "oob,dma-mode" ]
+      oob,dma-rx-desc-num: [ "oob,dma-mode" ]
+
+    required:
+      - compatible
+      - interrupts
+      - clocks
+
+  espi-mmbi:
+    type: object
+
+    properties:
+      compatible:
+        const: aspeed,ast2600-espi-mmbi
+
+      interrupts:
+        maxItems: 1
+
+    required:
+      - compatible
+      - interrupts
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+
+    espi: espi at 1e6ee000 {
+        compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
+        reg = <0x1e6ee000 0x1000>;
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0x0 0x1e6ee000 0x1000>;
+
+        espi_ctrl: espi-ctrl at 0 {
+            compatible = "aspeed,ast2600-espi-ctrl";
+            reg = <0x0 0x800>;
+            interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
+        };
+
+        espi_mmbi: espi-mmbi at 800 {
+            compatible = "aspeed,ast2600-espi-mmbi";
+            reg = <0x800 0x50>;
+            interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+        };
+    };
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Wed Aug 25 23:16:21 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 26 Aug 2021 14:16:21 +0800
Subject: [PATCH v3 2/4] MAINTAINER: Add ASPEED eSPI driver entry
In-Reply-To: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210826061623.6352-3-chiawei_wang@aspeedtech.com>

Add Ryan Chen and myself as the maintainer of Aspeed eSPI
driver. Joel Stanley is added as the reviewer.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fd25e4ecf0b9..b21bcb46692e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1713,6 +1713,15 @@ F:	drivers/crypto/axis
 F:	drivers/mmc/host/usdhi6rol0.c
 F:	drivers/pinctrl/pinctrl-artpec*
 
+ARM/ASPEED ESPI DRIVER
+M:	Chia-Wei Wang <chiawei_wang at aspeedtech.com>
+M:	Ryan Chen <ryan_chen at aspeedtech.com>
+R:	Joel Stanley <joel at jms.id.au>
+L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/soc/aspeed/espi.yaml
+
 ARM/ASPEED I2C DRIVER
 M:	Brendan Higgins <brendanhiggins at google.com>
 R:	Benjamin Herrenschmidt <benh at kernel.crashing.org>
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Wed Aug 25 23:16:19 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Thu, 26 Aug 2021 14:16:19 +0800
Subject: [PATCH v3 0/4] arm: aspeed: Add eSPI support
Message-ID: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>

This patch series add the driver support for the eSPI controller
of Aspeed 5/6th generation SoCs. This controller is a slave device
communicating with a master over Enhanced Serial Peripheral Interface (eSPI).
It supports all of the 4 eSPI channels, namely peripheral, virtual wire,
out-of-band, and flash, and operates at max frequency of 66MHz.

v3:
 - remove the redundant patch "clk: aspeed: Add eSPI reset bit"
 - fix missing header inclusion reported by test bot
 - fix dt-bindings error reported by yamllint

v2:
 - remove irqchip implementation
 - merge per-channel drivers into single one to avoid the racing issue
   among eSPI handshake process and driver probing.

Chia-Wei Wang (4):
  dt-bindings: aspeed: Add eSPI controller
  MAINTAINER: Add ASPEED eSPI driver entry
  soc: aspeed: Add eSPI driver
  ARM: dts: aspeed: Add eSPI node

 .../devicetree/bindings/soc/aspeed/espi.yaml  | 157 +++++
 MAINTAINERS                                   |   9 +
 arch/arm/boot/dts/aspeed-g6.dtsi              |  17 +
 drivers/soc/aspeed/Kconfig                    |  11 +
 drivers/soc/aspeed/Makefile                   |   1 +
 drivers/soc/aspeed/aspeed-espi-ctrl.c         | 205 ++++++
 drivers/soc/aspeed/aspeed-espi-ctrl.h         | 304 +++++++++
 drivers/soc/aspeed/aspeed-espi-flash.h        | 380 +++++++++++
 drivers/soc/aspeed/aspeed-espi-ioc.h          | 153 +++++
 drivers/soc/aspeed/aspeed-espi-oob.h          | 611 ++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-perif.h        | 539 +++++++++++++++
 drivers/soc/aspeed/aspeed-espi-vw.h           | 142 ++++
 12 files changed, 2529 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-flash.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ioc.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-oob.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-perif.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-vw.h

-- 
2.17.1



From chunfeng.yun at mediatek.com  Thu Aug 26 01:36:36 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 26 Aug 2021 16:36:36 +0800
Subject: [PATCH next 1/2] usb: mtu3: return successful suspend status
Message-ID: <20210826083637.33237-1-chunfeng.yun@mediatek.com>

Forgot 'return 0;' when suspend successfully, make the mistake
when I split patches.

Fixes: 6b587394c65c ("usb: mtu3: support suspend/resume for dual-role mode")
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/mtu3/mtu3_plat.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index 81266f34986f..5b3f7f73cb40 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -502,6 +502,7 @@ static int mtu3_suspend_common(struct device *dev, pm_message_t msg)
 	ssusb_phy_power_off(ssusb);
 	clk_bulk_disable_unprepare(BULK_CLKS_CNT, ssusb->clks);
 	ssusb_wakeup_set(ssusb, true);
+	return 0;
 
 sleep_err:
 	resume_ip_and_ports(ssusb, msg);
-- 
2.18.0

From chunfeng.yun at mediatek.com  Thu Aug 26 01:36:37 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 26 Aug 2021 16:36:37 +0800
Subject: [PATCH next 2/2] usb: mtu3: fix random remote wakeup
In-Reply-To: <20210826083637.33237-1-chunfeng.yun@mediatek.com>
References: <20210826083637.33237-1-chunfeng.yun@mediatek.com>
Message-ID: <20210826083637.33237-2-chunfeng.yun@mediatek.com>

Some platforms, e.g. 8183/8192, use low level latch way to keep
wakeup signal, it may latch a wrong signal if debounce more time,
and enable wakeup earlier.
                   ____________________
ip_sleep      ____/                    \__________
                           ___________________
wakeup_signal ____________/                   \______
                      _______________________________
wakeup_en     _______/
                      ^     ^
                      |(1)  |(2)
latch wakeup_signal mistakenly at (1), should latch it at (2);

Workaround: delay about 100us to enable wakeup, meanwhile decrease
debounce time.

Fixes: b1a344589eea ("usb: mtu3: support ip-sleep wakeup for MT8183")
Cc: stable at vger.kernel.org
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/mtu3/mtu3_host.c | 2 +-
 drivers/usb/mtu3/mtu3_plat.c | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c
index 7d528f3c2482..f3903367a6a0 100644
--- a/drivers/usb/mtu3/mtu3_host.c
+++ b/drivers/usb/mtu3/mtu3_host.c
@@ -62,7 +62,7 @@ static void ssusb_wakeup_ip_sleep_set(struct ssusb_mtk *ssusb, bool enable)
 	case SSUSB_UWK_V1_1:
 		reg = ssusb->uwk_reg_base + PERI_WK_CTRL0;
 		msk = WC0_IS_EN | WC0_IS_C(0xf) | WC0_IS_P;
-		val = enable ? (WC0_IS_EN | WC0_IS_C(0x8)) : 0;
+		val = enable ? (WC0_IS_EN | WC0_IS_C(0x1)) : 0;
 		break;
 	case SSUSB_UWK_V1_2:
 		reg = ssusb->uwk_reg_base + PERI_WK_CTRL0;
diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index 5b3f7f73cb40..f13531022f4a 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -63,6 +63,9 @@ static int wait_for_ip_sleep(struct ssusb_mtk *ssusb)
 	if (ret) {
 		dev_err(ssusb->dev, "ip sleep failed!!!\n");
 		ret = -EBUSY;
+	} else {
+		/* workaround: avoid wrong wakeup signal latch for some soc */
+		usleep_range(100, 200);
 	}
 
 	return ret;
-- 
2.18.0

From maz at kernel.org  Thu Aug 26 01:37:42 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 26 Aug 2021 09:37:42 +0100
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org>
 <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
Message-ID: <877dg8ppnt.wl-maz@kernel.org>

On Wed, 25 Aug 2021 19:14:59 +0100,
Oliver Upton <oupton at google.com> wrote:
> 
> On Wed, Aug 25, 2021 at 8:07 AM Andrew Jones <drjones at redhat.com> wrote:

[...]

> > Thanks for including me Marc. I think you've mentioned all the examples
> > of why we don't generally expect N+1 -> N migrations to work that I
> > can think of. While some of the examples like get-reg-list could
> > eventually be eliminated if we had CPU models to tighten our machine type
> > state, I think N+1 -> N migrations will always be best effort at most.
> >
> > I agree with giving userspace control over the exposer of the hypercalls
> > though. Using pseudo-registers for that purpose rather than a pile of
> > CAPs also seems reasonable to me.
> >
> > And, while I don't think this patch is going to proceed, I thought I'd
> > point out that the opt-out approach doesn't help much with expanding
> > our migration support unless we require the VMM to be upgraded first.
> >
> > And, even then, the (N_kern, N+1_vmm) -> (N+1_kern, N_vmm) case won't
> > work as expected, since the source enforce opt-out, but the destination
> > won't.
> 
> Right, there's going to need to be a fence in both kernel and VMM
> versions. Before the fence, you can't rollback with either component.
> Once on the other side of the fence, the user may freely migrate
> between kernel + VMM combinations.
>
> > Also, since the VMM doesn't key off the kernel version, for the
> > most part N+1 VMMs won't know when they're supposed to opt-out or not,
> > leaving it to the user to ensure they consider everything. opt-in
> > usually only needs the user to consider what machine type they want to
> > launch.
> 
> Going the register route will implicitly require opt-out for all old
> hypercalls. We exposed them unconditionally to the guest before, and
> we must uphold that behavior. The default value for the bitmap will
> have those features set. Any hypercalls added after that register
> interface will then require explicit opt-in from userspace.

I disagree here. This makes the ABI inconsistent, and means that no
feature can be implemented without changing userspace. If you can deal
with the existing features, you should be able to deal with the next
lot.

> With regards to the pseudoregister interface, how would a VMM discover
> new bits? From my perspective, you need to have two bitmaps that the
> VMM can get at: the set of supported feature bits and the active
> bitmap of features for a running guest.

My proposal is that we have a single pseudo-register exposing the list
of implemented by the kernel. Clear the bits you don't want, and write
back the result. As long as you haven't written anything, you have the
full feature set. That's pretty similar to the virtio feature
negotiation.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From drjones at redhat.com  Thu Aug 26 01:49:45 2021
From: drjones at redhat.com (Andrew Jones)
Date: Thu, 26 Aug 2021 10:49:45 +0200
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org>
 <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
Message-ID: <20210826084945.yknl64gklxtygwal@gator.home>

On Wed, Aug 25, 2021 at 11:14:59AM -0700, Oliver Upton wrote:
> On Wed, Aug 25, 2021 at 8:07 AM Andrew Jones <drjones at redhat.com> wrote:
> >
> > On Wed, Aug 25, 2021 at 11:39:34AM +0100, Marc Zyngier wrote:
> > > On Wed, 25 Aug 2021 11:02:28 +0100,
> > > Oliver Upton <oupton at google.com> wrote:
> > > >
> > > > On Wed, Aug 25, 2021 at 2:27 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > > > Exposing new hypercalls to guests in this manner seems very unsafe to
> > > > > > me. Suppose an operator is trying to upgrade from kernel N to kernel
> > > > > > N+1, which brings in the new 'widget' hypercall. Guests are live
> > > > > > migrated onto the N+1 kernel, but the operator finds a defect that
> > > > > > warrants a kernel rollback. VMs are then migrated from kernel N+1 -> N.
> > > > > > Any guests that discovered the 'widget' hypercall are likely going to
> > > > > > get fussy _very_ quickly on the old kernel.
> > > > >
> > > > > This goes against what we decided to support for the *only* publicly
> > > > > available VMM that cares about save/restore, which is that we only
> > > > > move forward and don't rollback.
> > > >
> > > > Ah, I was definitely missing this context. Current behavior makes much
> > > > more sense then.
> > > >
> > > > > Hypercalls are the least of your
> > > > > worries, and there is a whole range of other architectural features
> > > > > that will have also appeared/disappeared (your own CNTPOFF series is a
> > > > > glaring example of this).
> > > >
> > > > Isn't that a tad bit different though? I'll admit, I'm just as guilty
> > > > with my own series forgetting to add a KVM_CAP (oops), but it is in my
> > > > queue to kick out with the fix for nVHE/ptimer. Nonetheless, if a user
> > > > takes up a new KVM UAPI, it is up to the user to run on a new kernel.
> > >
> > > The two are linked. Exposing a new register to userspace and/or guest
> > > result in the same thing: you can't rollback. That's specially true in
> > > the QEMU case, which *learns* from the kernel what registers are
> > > available, and doesn't maintain a fixed list.
> > >
> > > > My concerns are explicitly with the 'under the nose' changes, where
> > > > KVM modifies the guest feature set without userspace opting in. Based
> > > > on your comment, though, it would appear that other parts of KVM are
> > > > affected too.
> > >
> > > Any new system register that is exposed by a new kernel feature breaks
> > > rollback. And so far, we only consider it a bug if the set of exposed
> > > registers reduces. Anything can be added safely (as checked by one of
> > > the selftests added by Drew).
> > >
> > > < It doesn't have to be rollback safety, either. There may
> > > > simply be a hypercall which an operator doesn't want to give its
> > > > guests, and it needs a way to tell KVM to hide it.
> > >
> > > Fair enough. But this has to be done in a scalable way, which
> > > individual capability cannot provide.
> > >
> > > > > > Have I missed something blatantly obvious, or do others see this as an
> > > > > > issue as well? I'll reply with an example of adding opt-out for PTP.
> > > > > > I'm sure other hypercalls could be handled similarly.
> > > > >
> > > > > Why do we need this? For future hypercalls, we could have some buy-in
> > > > > capabilities. For existing ones, it is too late, and negative features
> > > > > are just too horrible.
> > > >
> > > > Oh, agreed on the nastiness. Lazy hack to realize the intended
> > > > functional change..
> > >
> > > Well, you definitely achieved your goal of attracting my attention :).
> > >
> > > > > For KVM-specific hypercalls, we could get the VMM to save/restore the
> > > > > bitmap of supported functions. That would be "less horrible". This
> > > > > could be implemented using extra "firmware pseudo-registers" such as
> > > > > the ones described in Documentation/virt/kvm/arm/psci.rst.
> > > >
> > > > This seems more reasonable, especially since we do this for migrating
> > > > the guest's PSCI version.
> > > >
> > > > Alternatively, I had thought about using a VM attribute, given the
> > > > fact that it is non-architectural information and we avoid ABI issues
> > > > in KVM_GET_REG_LIST without buy-in through a KVM_CAP.
> > >
> > > The whole point is that these settings get exposed by
> > > KVM_GET_REG_LIST, as this is QEMU's way to dump a VM state. Given that
> > > we already have this for things like the spectre management state, we
> > > can just as well expose the bitmaps that deal with the KVM-specific
> > > hypercalls. After all, this falls into the realm of "KVM as VM
> > > firmware".
> > >
> > > For ARM-architected hypercalls (TRNG, stolen time), we may need a
> > > similar extension.
> > >
> >
> > Thanks for including me Marc. I think you've mentioned all the examples
> > of why we don't generally expect N+1 -> N migrations to work that I
> > can think of. While some of the examples like get-reg-list could
> > eventually be eliminated if we had CPU models to tighten our machine type
> > state, I think N+1 -> N migrations will always be best effort at most.
> >
> > I agree with giving userspace control over the exposer of the hypercalls
> > though. Using pseudo-registers for that purpose rather than a pile of
> > CAPs also seems reasonable to me.
> >
> > And, while I don't think this patch is going to proceed, I thought I'd
> > point out that the opt-out approach doesn't help much with expanding
> > our migration support unless we require the VMM to be upgraded first.
> >
> > And, even then, the (N_kern, N+1_vmm) -> (N+1_kern, N_vmm) case won't
> > work as expected, since the source enforce opt-out, but the destination
> > won't.
> 
> Right, there's going to need to be a fence in both kernel and VMM
> versions. Before the fence, you can't rollback with either component.
> Once on the other side of the fence, the user may freely migrate
> between kernel + VMM combinations.
> 
> > Also, since the VMM doesn't key off the kernel version, for the
> > most part N+1 VMMs won't know when they're supposed to opt-out or not,
> > leaving it to the user to ensure they consider everything. opt-in
> > usually only needs the user to consider what machine type they want to
> > launch.
> 
> Going the register route will implicitly require opt-out for all old
> hypercalls. We exposed them unconditionally to the guest before, and
> we must uphold that behavior. The default value for the bitmap will
> have those features set. Any hypercalls added after that register
> interface will then require explicit opt-in from userspace.
> 
> With regards to the pseudoregister interface, how would a VMM discover
> new bits? From my perspective, you need to have two bitmaps that the
> VMM can get at: the set of supported feature bits and the active
> bitmap of features for a running guest.
>

I think we should model the pseudo-register approach off of x86's
CPUID approach. x86 has specific get/set ioctls for CPUIDs
(KVM_GET/SET_CPUID2), but I think we should get by with just
get/set-one-reg. However, it might be nice/necessary to have something
like x86's KVM_GET_SUPPORTED_CPUID which returns all the registers
at once as a bitmap and the set bits would inform userspace of what's
supported by the hardware and KVM.

So a new ioctl similar to KVM_GET_SUPPORTED_CPUID would be your
first bitmap that shows what's supported and then userpace can
determine what it wants to change and calculate the appropriate
pseudo-registers to set/clear bits on with set-one-reg, as x86
would do with kvm-set-cpuid2.

Thanks,
drew



From maz at kernel.org  Thu Aug 26 01:51:05 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 26 Aug 2021 09:51:05 +0100
Subject: [PATCH v2] arm64: Do not trap PMSNEVFR_EL1
In-Reply-To: <20210824154523.906270-1-alexandru.elisei@arm.com>
References: <20210824154523.906270-1-alexandru.elisei@arm.com>
Message-ID: <875yvspp1i.wl-maz@kernel.org>

On Tue, 24 Aug 2021 16:45:23 +0100,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed
> the fine grained trap registers to prevent unwanted register traps from
> occuring. However, for the PMSNEVFR_EL1 register, the corresponding
> HDFG{R,W}TR_EL2.nPMSNEVFR_EL1 fields must be 1 to disable trapping. Set
> both fields to 1 if FEAT_SPEv1p2 is detected to disable read and write
> traps.
> 
> Fixes: 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot")
> Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> ---
> Based on v5.14-rc7. Tested on the model, using boot-wrapper built from
> commit 5cd6238ec4ef ("aarch32: fix .globl replacement"). Without this
> patch, in NVHE mode, the model freezes when I try to access PMSNEVFR_EL1.
> With this patch, the model doesn't hang anymore.
> 
> Changes since v1:
> 
> * Set the corresponding bit in HDFGWRTR_EL2 to also disable write traps. My
>   thanks to Mark for pointing it out.
> 
>  arch/arm64/include/asm/el2_setup.h | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
> index b83fb24954b7..3198acb2aad8 100644
> --- a/arch/arm64/include/asm/el2_setup.h
> +++ b/arch/arm64/include/asm/el2_setup.h
> @@ -149,8 +149,17 @@
>  	ubfx	x1, x1, #ID_AA64MMFR0_FGT_SHIFT, #4
>  	cbz	x1, .Lskip_fgt_\@
>  
> -	msr_s	SYS_HDFGRTR_EL2, xzr
> -	msr_s	SYS_HDFGWTR_EL2, xzr
> +	mov	x0, xzr
> +	mrs	x1, id_aa64dfr0_el1
> +	ubfx	x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4
> +	cmp	x1, #3
> +	b.lt	.Lset_fgt_\@
> +	/* Disable PMSNEVFR_EL1 read and write traps */
> +	orr	x0, x0, #(1 << 62)
> +
> +.Lset_fgt_\@:
> +	msr_s	SYS_HDFGRTR_EL2, x0
> +	msr_s	SYS_HDFGWTR_EL2, x0
>  	msr_s	SYS_HFGRTR_EL2, xzr
>  	msr_s	SYS_HFGWTR_EL2, xzr
>  	msr_s	SYS_HFGITR_EL2, xzr

The beauty of negative trap bits... Thankfully this seems to be the
only one.

Acked-by: Marc Zyngier <maz at kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


From drjones at redhat.com  Thu Aug 26 01:54:29 2021
From: drjones at redhat.com (Andrew Jones)
Date: Thu, 26 Aug 2021 10:54:29 +0200
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <20210826084945.yknl64gklxtygwal@gator.home>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org>
 <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
 <20210826084945.yknl64gklxtygwal@gator.home>
Message-ID: <20210826085429.b67fzkshhl3s2vfr@gator.home>

On Thu, Aug 26, 2021 at 10:49:45AM +0200, Andrew Jones wrote:
> On Wed, Aug 25, 2021 at 11:14:59AM -0700, Oliver Upton wrote:
> > On Wed, Aug 25, 2021 at 8:07 AM Andrew Jones <drjones at redhat.com> wrote:
> > >
> > > On Wed, Aug 25, 2021 at 11:39:34AM +0100, Marc Zyngier wrote:
> > > > On Wed, 25 Aug 2021 11:02:28 +0100,
> > > > Oliver Upton <oupton at google.com> wrote:
> > > > >
> > > > > On Wed, Aug 25, 2021 at 2:27 AM Marc Zyngier <maz at kernel.org> wrote:
> > > > > > > Exposing new hypercalls to guests in this manner seems very unsafe to
> > > > > > > me. Suppose an operator is trying to upgrade from kernel N to kernel
> > > > > > > N+1, which brings in the new 'widget' hypercall. Guests are live
> > > > > > > migrated onto the N+1 kernel, but the operator finds a defect that
> > > > > > > warrants a kernel rollback. VMs are then migrated from kernel N+1 -> N.
> > > > > > > Any guests that discovered the 'widget' hypercall are likely going to
> > > > > > > get fussy _very_ quickly on the old kernel.
> > > > > >
> > > > > > This goes against what we decided to support for the *only* publicly
> > > > > > available VMM that cares about save/restore, which is that we only
> > > > > > move forward and don't rollback.
> > > > >
> > > > > Ah, I was definitely missing this context. Current behavior makes much
> > > > > more sense then.
> > > > >
> > > > > > Hypercalls are the least of your
> > > > > > worries, and there is a whole range of other architectural features
> > > > > > that will have also appeared/disappeared (your own CNTPOFF series is a
> > > > > > glaring example of this).
> > > > >
> > > > > Isn't that a tad bit different though? I'll admit, I'm just as guilty
> > > > > with my own series forgetting to add a KVM_CAP (oops), but it is in my
> > > > > queue to kick out with the fix for nVHE/ptimer. Nonetheless, if a user
> > > > > takes up a new KVM UAPI, it is up to the user to run on a new kernel.
> > > >
> > > > The two are linked. Exposing a new register to userspace and/or guest
> > > > result in the same thing: you can't rollback. That's specially true in
> > > > the QEMU case, which *learns* from the kernel what registers are
> > > > available, and doesn't maintain a fixed list.
> > > >
> > > > > My concerns are explicitly with the 'under the nose' changes, where
> > > > > KVM modifies the guest feature set without userspace opting in. Based
> > > > > on your comment, though, it would appear that other parts of KVM are
> > > > > affected too.
> > > >
> > > > Any new system register that is exposed by a new kernel feature breaks
> > > > rollback. And so far, we only consider it a bug if the set of exposed
> > > > registers reduces. Anything can be added safely (as checked by one of
> > > > the selftests added by Drew).
> > > >
> > > > < It doesn't have to be rollback safety, either. There may
> > > > > simply be a hypercall which an operator doesn't want to give its
> > > > > guests, and it needs a way to tell KVM to hide it.
> > > >
> > > > Fair enough. But this has to be done in a scalable way, which
> > > > individual capability cannot provide.
> > > >
> > > > > > > Have I missed something blatantly obvious, or do others see this as an
> > > > > > > issue as well? I'll reply with an example of adding opt-out for PTP.
> > > > > > > I'm sure other hypercalls could be handled similarly.
> > > > > >
> > > > > > Why do we need this? For future hypercalls, we could have some buy-in
> > > > > > capabilities. For existing ones, it is too late, and negative features
> > > > > > are just too horrible.
> > > > >
> > > > > Oh, agreed on the nastiness. Lazy hack to realize the intended
> > > > > functional change..
> > > >
> > > > Well, you definitely achieved your goal of attracting my attention :).
> > > >
> > > > > > For KVM-specific hypercalls, we could get the VMM to save/restore the
> > > > > > bitmap of supported functions. That would be "less horrible". This
> > > > > > could be implemented using extra "firmware pseudo-registers" such as
> > > > > > the ones described in Documentation/virt/kvm/arm/psci.rst.
> > > > >
> > > > > This seems more reasonable, especially since we do this for migrating
> > > > > the guest's PSCI version.
> > > > >
> > > > > Alternatively, I had thought about using a VM attribute, given the
> > > > > fact that it is non-architectural information and we avoid ABI issues
> > > > > in KVM_GET_REG_LIST without buy-in through a KVM_CAP.
> > > >
> > > > The whole point is that these settings get exposed by
> > > > KVM_GET_REG_LIST, as this is QEMU's way to dump a VM state. Given that
> > > > we already have this for things like the spectre management state, we
> > > > can just as well expose the bitmaps that deal with the KVM-specific
> > > > hypercalls. After all, this falls into the realm of "KVM as VM
> > > > firmware".
> > > >
> > > > For ARM-architected hypercalls (TRNG, stolen time), we may need a
> > > > similar extension.
> > > >
> > >
> > > Thanks for including me Marc. I think you've mentioned all the examples
> > > of why we don't generally expect N+1 -> N migrations to work that I
> > > can think of. While some of the examples like get-reg-list could
> > > eventually be eliminated if we had CPU models to tighten our machine type
> > > state, I think N+1 -> N migrations will always be best effort at most.
> > >
> > > I agree with giving userspace control over the exposer of the hypercalls
> > > though. Using pseudo-registers for that purpose rather than a pile of
> > > CAPs also seems reasonable to me.
> > >
> > > And, while I don't think this patch is going to proceed, I thought I'd
> > > point out that the opt-out approach doesn't help much with expanding
> > > our migration support unless we require the VMM to be upgraded first.
> > >
> > > And, even then, the (N_kern, N+1_vmm) -> (N+1_kern, N_vmm) case won't
> > > work as expected, since the source enforce opt-out, but the destination
> > > won't.
> > 
> > Right, there's going to need to be a fence in both kernel and VMM
> > versions. Before the fence, you can't rollback with either component.
> > Once on the other side of the fence, the user may freely migrate
> > between kernel + VMM combinations.
> > 
> > > Also, since the VMM doesn't key off the kernel version, for the
> > > most part N+1 VMMs won't know when they're supposed to opt-out or not,
> > > leaving it to the user to ensure they consider everything. opt-in
> > > usually only needs the user to consider what machine type they want to
> > > launch.
> > 
> > Going the register route will implicitly require opt-out for all old
> > hypercalls. We exposed them unconditionally to the guest before, and
> > we must uphold that behavior. The default value for the bitmap will
> > have those features set. Any hypercalls added after that register
> > interface will then require explicit opt-in from userspace.
> > 
> > With regards to the pseudoregister interface, how would a VMM discover
> > new bits? From my perspective, you need to have two bitmaps that the
> > VMM can get at: the set of supported feature bits and the active
> > bitmap of features for a running guest.
> >
> 
> I think we should model the pseudo-register approach off of x86's
> CPUID approach. x86 has specific get/set ioctls for CPUIDs
> (KVM_GET/SET_CPUID2), but I think we should get by with just
> get/set-one-reg. However, it might be nice/necessary to have something
> like x86's KVM_GET_SUPPORTED_CPUID which returns all the registers
> at once as a bitmap and the set bits would inform userspace of what's
> supported by the hardware and KVM.
> 
> So a new ioctl similar to KVM_GET_SUPPORTED_CPUID would be your
> first bitmap that shows what's supported and then userpace can
> determine what it wants to change and calculate the appropriate
> pseudo-registers to set/clear bits on with set-one-reg, as x86
> would do with kvm-set-cpuid2.
>

I see Marc just replied stating we'll probably just have a single
register. The KVM_GET_SUPPORTED_CPUID type of ioctl would be
overkill in that case (get-one_reg is enough). Anyway it can
always be added later if we expand into more registers.

Thanks,
drew



From daniel at ffwll.ch  Thu Aug 26 02:14:07 2021
From: daniel at ffwll.ch (Daniel Vetter)
Date: Thu, 26 Aug 2021 11:14:07 +0200
Subject: [PATCH v5, 00/15] Using component framework to support multi
 hardware decode
In-Reply-To: <CAAEAJfB3CoTU7bZe08wYEfTTm6=6UPOae9u39AtdbJ9saYknBA@mail.gmail.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <CAAEAJfDWOzCJxZFNtxeT7Cvr2pWbYrfz-YnA81sVNs-rM=8n4Q@mail.gmail.com>
 <CAKMK7uFW3Z=Up=OCJO4dNR9ffaTdFjHwoND9CrUw6LHmQ4t_AQ@mail.gmail.com>
 <CAAEAJfB3CoTU7bZe08wYEfTTm6=6UPOae9u39AtdbJ9saYknBA@mail.gmail.com>
Message-ID: <YSdbXzCJRsj/jsnl@phenom.ffwll.local>

On Sun, Aug 22, 2021 at 02:57:15PM -0300, Ezequiel Garcia wrote:
> On Sun, 22 Aug 2021 at 13:50, Daniel Vetter <daniel at ffwll.ch> wrote:
> >
> > On Wed, Aug 18, 2021 at 4:12 PM Ezequiel Garcia
> > <ezequiel at vanguardiasur.com.ar> wrote:
> > >
> > > +danvet
> > >
> > > Hi,
> > >
> > > On Tue, 10 Aug 2021 at 23:58, Yunfei Dong <yunfei.dong at mediatek.com> wrote:
> > > >
> > > > This series adds support for multi hardware decode into mtk-vcodec, by first
> > > > adding component framework to manage each hardware information: interrupt,
> > > > clock, register bases and power. Secondly add core thread to deal with core
> > > > hardware message, at the same time, add msg queue for different hardware
> > > > share messages. Lastly, the architecture of different specs are not the same,
> > > > using specs type to separate them.
> > > >
> > >
> > > I don't think it's a good idea to introduce the component API in the
> > > media subsystem. It doesn't seem to be maintained, IRC there's not even
> > > a maintainer for it, and it has some issues that were never addressed.
> >
> > Defacto dri-devel folks are maintainer component.c, but also I'm not
> > aware of anything missing there?
> >
> 
> A while ago, I tried to fix a crash in the Rockchip DRM driver
> (I was then told there can be similar issues on the IMX driver too,
> but I forgot the details of that).
> 
> I sent a patchset trying to address it and got total silence back.
> Although you could argue the issue is in how drivers use the component
> API, AFAICR the abuse is spreaded across a few drivers, so it felt
> more reasonable to improve the component API itself, instead of changing
> all the drivers.
> 
> See below:
> 
> https://patchwork.kernel.org/project/linux-rockchip/cover/20200120170602.3832-1-ezequiel at collabora.com/

Patches get lost on the mailing list, and rockchip is one of the lesser
maintained drivers. You need to ping this stuff.

For bridge/panel I still think we should work towards removing component.c
use from them.

> > There has been discussions that in various drm subsystems like
> > drm_bridge or drm_panel a few things are missing, which prevent
> > drivers from moving _away_ from component.c to the more specific
> > solutions for panel/bridges. But nothing that's preventing them from
> > using component.c itself.
> >
> > I'm happy to merge a MAINTAINERS patch to clarify the situation if
> > that's needed.
> 
> Indeed, that would be good.

Ok I'm going to type something.
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From daniel at ffwll.ch  Thu Aug 26 02:18:56 2021
From: daniel at ffwll.ch (Daniel Vetter)
Date: Thu, 26 Aug 2021 11:18:56 +0200
Subject: [PATCH v2 5/5] drm: omap: remove obsolete selection of OMAP2_DSS
 in config DRM_OMAP
In-Reply-To: <20210819112253.16484-6-lukas.bulwahn@gmail.com>
References: <20210819112253.16484-1-lukas.bulwahn@gmail.com>
 <20210819112253.16484-6-lukas.bulwahn@gmail.com>
Message-ID: <YSdcgLcD2hOZks6l@phenom.ffwll.local>

On Thu, Aug 19, 2021 at 01:22:53PM +0200, Lukas Bulwahn wrote:
> Commit 55b68fb856b5 ("drm/omap: squash omapdrm sub-modules into one")
> removes the config OMAP2_DSS in ./drivers/gpu/drm/omapdrm/dss/Kconfig,
> while moving the other configs into./drivers/gpu/drm/omapdrm/Kconfig, but
> misses to remove an obsolete selection of OMAP2_DSS in config DRM_OMAP.
> 
> Hence, ./scripts/checkkconfigsymbols.py warns:
> 
> OMAP2_DSS
> Referencing files: drivers/gpu/drm/omapdrm/Kconfig
> 
> Remove this reference in an obsolete selection.
> 
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>

Except the amdgpu patch all merged to drm-misc-next. amdgpu should get
picked up by Alex.
-Daniel

> ---
>  drivers/gpu/drm/omapdrm/Kconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
> index e7281da5bc6a..d6e4df291d6f 100644
> --- a/drivers/gpu/drm/omapdrm/Kconfig
> +++ b/drivers/gpu/drm/omapdrm/Kconfig
> @@ -3,7 +3,6 @@ config DRM_OMAP
>  	tristate "OMAP DRM"
>  	depends on DRM
>  	depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
> -	select OMAP2_DSS
>  	select DRM_KMS_HELPER
>  	select VIDEOMODE_HELPERS
>  	select HDMI
> -- 
> 2.26.2
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From ulf.hansson at linaro.org  Thu Aug 26 02:22:02 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Thu, 26 Aug 2021 11:22:02 +0200
Subject: [PATCH V2 05/10] mmc: sdhci-iproc: Set
 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711
In-Reply-To: <3e8bfa67-e3fe-bcfd-1941-90cae7ed0176@arm.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
 <1628334401-6577-6-git-send-email-stefan.wahren@i2se.com>
 <3e8bfa67-e3fe-bcfd-1941-90cae7ed0176@arm.com>
Message-ID: <CAPDyKFpGoMVywNFMskTTYYOvLZMK-1u2+5V_q1uW2H5AZJ_W7Q@mail.gmail.com>

On Thu, 26 Aug 2021 at 08:36, Jeremy Linton <jeremy.linton at arm.com> wrote:
>
> Hi,
>
>
> On 8/7/21 6:06 AM, Stefan Wahren wrote:
> > From: Nicolas Saenz Julienne <nsaenz at kernel.org>
> >
> > The controller doesn't seem to pick-up on clock changes, so set the
> > SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN flag to query the clock frequency
> > directly from the clock.
> >
> > Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
> > Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
> > Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> > ---
> >   drivers/mmc/host/sdhci-iproc.c | 3 ++-
> >   1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
> > index 032bf85..e7565c6 100644
> > --- a/drivers/mmc/host/sdhci-iproc.c
> > +++ b/drivers/mmc/host/sdhci-iproc.c
> > @@ -295,7 +295,8 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
> >   };
> >
> >   static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
> > -     .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
> > +     .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
> > +               SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
> >       .ops = &sdhci_iproc_bcm2711_ops,
> >   };
>
> I just noticed that this got merged to rc7, and it breaks the ACPI based
> rpi's because it causes the 100Mhz max clock to be overridden to the
> return from sdhci_iproc_get_max_clock() which is 0 because there isn't a
> OF/DT based clock device.

Thanks for reporting! I allow Stefan to respond in a day or two,
before I do a revert of it.

Kind regards
Uffe


From arnd at kernel.org  Thu Aug 26 02:35:03 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 26 Aug 2021 11:35:03 +0200
Subject: [GIT PULL] Rockchip driver changes for 5.15
In-Reply-To: <9718620.EvYhyI6sBW@phil>
References: <9718620.EvYhyI6sBW@phil>
Message-ID: <162997049860.837527.581297114646598072.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sun, 22 Aug 2021 12:15:43 +0200, Heiko Stuebner wrote:
> please find below (and in the next mails) changes for
> Rockchip platforms for 5.15.
> 
> Please pull
> 
> Thanks
> Heiko
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 9b3878a99ad606fe76a50a290273d7b801f0f895

       Arnd


From arnd at kernel.org  Thu Aug 26 02:35:04 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 26 Aug 2021 11:35:04 +0200
Subject: [GIT PULL] Reset controller updates for v5.15
In-Reply-To: <d42a75fc17ce718ef1b3fa4c5d3f5c7fb0bd2bc2.camel@pengutronix.de>
References: <d42a75fc17ce718ef1b3fa4c5d3f5c7fb0bd2bc2.camel@pengutronix.de>
Message-ID: <162997049869.837527.9579735591959657618.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Mon, 23 Aug 2021 18:12:55 +0200, Philipp Zabel wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.pengutronix.de/pza/linux tags/reset-for-v5.15
> 
> [...]

Merged into arm/drivers, thanks!

merge commit: 06779631d18ff2901af604eadea0d7b2193db7a1

       Arnd


From arnd at kernel.org  Thu Aug 26 02:35:54 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 26 Aug 2021 11:35:54 +0200
Subject: [GIT PULL] ARM: dts zynq: Xilinx SoC changes for v5.15
In-Reply-To: <5a25f882-103f-4df0-0d90-868d264c900b@monstr.eu>
References: <5a25f882-103f-4df0-0d90-868d264c900b@monstr.eu>
Message-ID: <162997054034.837715.8900575474065288793.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 25 Aug 2021 09:31:31 +0200, Michal Simek wrote:
> please pull this one patch to your tree.
> 
> Thanks,
> Michal
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> [...]

Merged into arm/defconfig, thanks!

merge commit: 79cd0bb66e359f5f9398de9d2e86eac776947691

       Arnd


From maz at kernel.org  Thu Aug 26 02:43:45 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 26 Aug 2021 10:43:45 +0100
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <20210826085429.b67fzkshhl3s2vfr@gator.home>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org>
 <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
 <20210826084945.yknl64gklxtygwal@gator.home>
 <20210826085429.b67fzkshhl3s2vfr@gator.home>
Message-ID: <874kbcpmlq.wl-maz@kernel.org>

On Thu, 26 Aug 2021 09:54:29 +0100,
Andrew Jones <drjones at redhat.com> wrote:

[...]

> I see Marc just replied stating we'll probably just have a single
> register. The KVM_GET_SUPPORTED_CPUID type of ioctl would be
> overkill in that case (get-one_reg is enough). Anyway it can
> always be added later if we expand into more registers.

Here's what I propose for the KVM-specific hypercalls. Compile tested
only, plenty of nits to sort out. But you'll get the general idea.
Something similar could be implemented for ARM-architected hypercalls
such as TRNG.

	M.

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f8be56d5342b..3fcca7cc9668 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -136,6 +136,9 @@ struct kvm_arch {
 
 	/* Memory Tagging Extension enabled for the guest */
 	bool mte_enabled;
+
+	/* Bitmap of enabled hypercalls */
+	unsigned long hc_bmap;
 };
 
 struct kvm_vcpu_fault_info {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..8d7a1a93f12c 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -281,6 +281,9 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED	3
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED     	(1U << 4)
 
+#define KVM_REG_ARM_KVM_SPECIFIC_HYPERCALLS_0	KVM_REG_ARM_FW_REG(3)
+#define KVM_REG_ARM_KVM_SPECIFIC_HYPERCALLS_1	KVM_REG_ARM_FW_REG(4)
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index fe102cd2e518..dbc136675b02 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -130,6 +130,13 @@ static void set_default_spectre(struct kvm *kvm)
 		kvm->arch.pfr0_csv3 = 1;
 }
 
+
+static void set_default_vendor_hypercalls(struct kvm *kvm)
+{
+	kvm->arch.hc_bmap = (BIT(ARM_SMCCC_KVM_FUNC_FEATURES) |
+			     BIT(ARM_SMCCC_KVM_FUNC_PTP));
+}
+
 /**
  * kvm_arch_init_vm - initializes a VM data structure
  * @kvm:	pointer to the KVM struct
@@ -156,6 +163,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
 
 	set_default_spectre(kvm);
+	set_default_vendor_hypercalls(kvm);
 
 	return ret;
 out_free_stage2_pgd:
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 30da78f72b3b..11f79e790f7d 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -127,8 +127,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 		val[3] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3;
 		break;
 	case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
-		val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
-		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP);
+		val[0] = vcpu->kvm->arch.hc_bmap;
 		break;
 	case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
 		kvm_ptp_get_time(vcpu, val);
diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c
index 74c47d420253..ceef0c706d50 100644
--- a/arch/arm64/kvm/psci.c
+++ b/arch/arm64/kvm/psci.c
@@ -404,21 +404,26 @@ int kvm_psci_call(struct kvm_vcpu *vcpu)
 	};
 }
 
+static const u64 fw_reg_ids[] = {
+	KVM_REG_ARM_PSCI_VERSION,
+	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1,
+	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
+	KVM_REG_ARM_KVM_SPECIFIC_HYPERCALLS_0,
+};
+
 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
 {
-	return 3;		/* PSCI version and two workaround registers */
+	return ARRAY_SIZE(fw_reg_ids);
 }
 
 int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 {
-	if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices++))
-		return -EFAULT;
-
-	if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, uindices++))
-		return -EFAULT;
+	int i;
 
-	if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++))
-		return -EFAULT;
+	for (i = 0; i < ARRAY_SIZE(fw_reg_ids); i++) {
+		if (put_user(fw_reg_ids[i], uindices++))
+			return -EFAULT;
+	}
 
 	return 0;
 }
@@ -477,6 +482,10 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
 		val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
 		break;
+	case KVM_REG_ARM_KVM_SPECIFIC_HYPERCALLS_0:
+		val = vcpu->kvm->arch.hc_bmap;
+		break;
+	case KVM_REG_ARM_KVM_SPECIFIC_HYPERCALLS_1:
 	default:
 		return -ENOENT;
 	}
@@ -515,8 +524,9 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 				return -EINVAL;
 			vcpu->kvm->arch.psci_version = val;
 			return 0;
+		default:
+			return -EINVAL;
 		}
-		break;
 	}
 
 	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
@@ -563,9 +573,16 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 			return -EINVAL;
 
 		return 0;
+	case KVM_REG_ARM_KVM_SPECIFIC_HYPERCALLS_0:
+		/* FIXME: no vcpu should have run */
+		/* Exclude any unknown bit */
+		if (val & ~(BIT(ARM_SMCCC_KVM_FUNC_FEATURES) |
+			    BIT(ARM_SMCCC_KVM_FUNC_PTP)))
+			return -EINVAL;
+		vcpu->kvm->arch.hc_bmap = val;
+		return 0;
+	case KVM_REG_ARM_KVM_SPECIFIC_HYPERCALLS_1:
 	default:
 		return -ENOENT;
 	}
-
-	return -EINVAL;
 }

-- 
Without deviation from the norm, progress is not possible.


From arnd at kernel.org  Thu Aug 26 02:46:47 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 26 Aug 2021 11:46:47 +0200
Subject: [GIT PULL] Rockchip dts32 changes for 5.15
In-Reply-To: <4142796.VLH7GnMWUR@phil>
References: <4142796.VLH7GnMWUR@phil>
Message-ID: <162997120229.839533.16666800980996064954.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Sun, 22 Aug 2021 12:17:36 +0200, Heiko Stuebner wrote:
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v5.15-rockchip-dts32-1
> 
> [...]

Merged into arm/dt, thanks!

merge commit: bb4544c6d415d42018ecd67826c0ac714bf86b7d

       Arnd


From arnd at kernel.org  Thu Aug 26 02:46:48 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 26 Aug 2021 11:46:48 +0200
Subject: [GIT PULL] ARM: dts zynq: Xilinx DT changes for v5.15
In-Reply-To: <f3dc69c8-8a22-e938-4ddf-b1052b8c1437@monstr.eu>
References: <f3dc69c8-8a22-e938-4ddf-b1052b8c1437@monstr.eu>
Message-ID: <162997120238.839533.17091999406711694821.b4-ty@arndb.de>

From: Arnd Bergmann <arnd at arndb.de>

On Wed, 25 Aug 2021 09:28:55 +0200, Michal Simek wrote:
> please pull these two patches to your tree.
> 
> Thanks,
> Michal
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> [...]

Merged into arm/dt, thanks!

merge commit: 9fdbbe8443a372088c809eb8f2cf4488a41333e8

       Arnd


From m.tretter at pengutronix.de  Thu Aug 26 02:47:36 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 26 Aug 2021 11:47:36 +0200
Subject: [PATCH 1/7] dmaengine: zynqmp_dma: simplify with dev_err_probe
In-Reply-To: <20210826094742.1302009-1-m.tretter@pengutronix.de>
References: <20210826094742.1302009-1-m.tretter@pengutronix.de>
Message-ID: <20210826094742.1302009-2-m.tretter@pengutronix.de>

The clocks are provided by the ZynqMP firmware driver and are deferred
until the firmware driver has probed. This leads to misleading error
messages during probe of the zynqmp_dma driver.

Use dev_err_probe for printing errors during probe to avoid error
messages for -EPROBE_DEFER.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/dma/xilinx/zynqmp_dma.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
index 5fecf5aa6e85..8423fbfc20c7 100644
--- a/drivers/dma/xilinx/zynqmp_dma.c
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -1062,16 +1062,14 @@ static int zynqmp_dma_probe(struct platform_device *pdev)
 	p->dev = &pdev->dev;
 
 	zdev->clk_main = devm_clk_get(&pdev->dev, "clk_main");
-	if (IS_ERR(zdev->clk_main)) {
-		dev_err(&pdev->dev, "main clock not found.\n");
-		return PTR_ERR(zdev->clk_main);
-	}
+	if (IS_ERR(zdev->clk_main))
+		return dev_err_probe(&pdev->dev, PTR_ERR(zdev->clk_main),
+				     "main clock not found.\n");
 
 	zdev->clk_apb = devm_clk_get(&pdev->dev, "clk_apb");
-	if (IS_ERR(zdev->clk_apb)) {
-		dev_err(&pdev->dev, "apb clock not found.\n");
-		return PTR_ERR(zdev->clk_apb);
-	}
+	if (IS_ERR(zdev->clk_apb))
+		return dev_err_probe(&pdev->dev, PTR_ERR(zdev->clk_apb),
+				     "apb clock not found.\n");
 
 	platform_set_drvdata(pdev, zdev);
 	pm_runtime_set_autosuspend_delay(zdev->dev, ZDMA_PM_TIMEOUT);
@@ -1086,7 +1084,7 @@ static int zynqmp_dma_probe(struct platform_device *pdev)
 
 	ret = zynqmp_dma_chan_probe(zdev, pdev);
 	if (ret) {
-		dev_err(&pdev->dev, "Probing channel failed\n");
+		dev_err_probe(&pdev->dev, ret, "Probing channel failed\n");
 		goto err_disable_pm;
 	}
 
@@ -1098,7 +1096,7 @@ static int zynqmp_dma_probe(struct platform_device *pdev)
 	ret = of_dma_controller_register(pdev->dev.of_node,
 					 of_zynqmp_dma_xlate, zdev);
 	if (ret) {
-		dev_err(&pdev->dev, "Unable to register DMA to DT\n");
+		dev_err_probe(&pdev->dev, ret, "Unable to register DMA to DT\n");
 		dma_async_device_unregister(&zdev->common);
 		goto free_chan_resources;
 	}
-- 
2.30.2



From m.tretter at pengutronix.de  Thu Aug 26 02:47:38 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 26 Aug 2021 11:47:38 +0200
Subject: [PATCH 3/7] dmaengine: zynqmp_dma: enable COMPILE_TEST
In-Reply-To: <20210826094742.1302009-1-m.tretter@pengutronix.de>
References: <20210826094742.1302009-1-m.tretter@pengutronix.de>
Message-ID: <20210826094742.1302009-4-m.tretter@pengutronix.de>

The driver doesn't use anything architecture specific. Allow the
compilation on other architectures as well.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/dma/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 39b5b46e880f..20cab9612916 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -695,7 +695,7 @@ config XILINX_DMA
 
 config XILINX_ZYNQMP_DMA
 	tristate "Xilinx ZynqMP DMA Engine"
-	depends on (ARCH_ZYNQ || MICROBLAZE || ARM64)
+	depends on ARCH_ZYNQ || MICROBLAZE || ARM64 || COMPILE_TEST
 	select DMA_ENGINE
 	help
 	  Enable support for Xilinx ZynqMP DMA controller.
-- 
2.30.2



From m.tretter at pengutronix.de  Thu Aug 26 02:47:37 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 26 Aug 2021 11:47:37 +0200
Subject: [PATCH 2/7] dmaengine: zynqmp_dma: drop message on probe success
In-Reply-To: <20210826094742.1302009-1-m.tretter@pengutronix.de>
References: <20210826094742.1302009-1-m.tretter@pengutronix.de>
Message-ID: <20210826094742.1302009-3-m.tretter@pengutronix.de>

There is no need to print a message that the ZynqMP DMA driver probed
successfully, since it carries no additional information. Drop the
message.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/dma/xilinx/zynqmp_dma.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
index 8423fbfc20c7..2a8938806b91 100644
--- a/drivers/dma/xilinx/zynqmp_dma.c
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -1104,8 +1104,6 @@ static int zynqmp_dma_probe(struct platform_device *pdev)
 	pm_runtime_mark_last_busy(zdev->dev);
 	pm_runtime_put_sync_autosuspend(zdev->dev);
 
-	dev_info(&pdev->dev, "ZynqMP DMA driver Probe success\n");
-
 	return 0;
 
 free_chan_resources:
-- 
2.30.2



From m.tretter at pengutronix.de  Thu Aug 26 02:47:39 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 26 Aug 2021 11:47:39 +0200
Subject: [PATCH 4/7] dmaengine: zynqmp_dma: cleanup includes
In-Reply-To: <20210826094742.1302009-1-m.tretter@pengutronix.de>
References: <20210826094742.1302009-1-m.tretter@pengutronix.de>
Message-ID: <20210826094742.1302009-5-m.tretter@pengutronix.de>

The driver includes a few headers that are not actually used, but are
probably copy paste errors. Remove them.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/dma/xilinx/zynqmp_dma.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
index 2a8938806b91..61bb1d7f6ec0 100644
--- a/drivers/dma/xilinx/zynqmp_dma.c
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -6,15 +6,12 @@
  */
 
 #include <linux/bitops.h>
-#include <linux/dmapool.h>
-#include <linux/dma/xilinx_dma.h>
+#include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/of_address.h>
 #include <linux/of_dma.h>
-#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
-- 
2.30.2



From m.tretter at pengutronix.de  Thu Aug 26 02:47:40 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 26 Aug 2021 11:47:40 +0200
Subject: [PATCH 5/7] dmaengine: zynqmp_dma: cleanup after completing all
 descriptors
In-Reply-To: <20210826094742.1302009-1-m.tretter@pengutronix.de>
References: <20210826094742.1302009-1-m.tretter@pengutronix.de>
Message-ID: <20210826094742.1302009-6-m.tretter@pengutronix.de>

The current implementation iterates the entire done list for each
completed dma descriptor even if there are multiple completed
descriptors.

Avoid this by first moving all completed descriptors to the done list
and afterwards iterating the done list and finishing the descriptors.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/dma/xilinx/zynqmp_dma.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
index 61bb1d7f6ec0..f98ef5fe4902 100644
--- a/drivers/dma/xilinx/zynqmp_dma.c
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -759,10 +759,11 @@ static void zynqmp_dma_do_tasklet(struct tasklet_struct *t)
 
 	while (count) {
 		zynqmp_dma_complete_descriptor(chan);
-		zynqmp_dma_chan_desc_cleanup(chan);
 		count--;
 	}
 
+	zynqmp_dma_chan_desc_cleanup(chan);
+
 	if (chan->idle)
 		zynqmp_dma_start_transfer(chan);
 
-- 
2.30.2



From m.tretter at pengutronix.de  Thu Aug 26 02:47:35 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 26 Aug 2021 11:47:35 +0200
Subject: [PATCH 0/7] dmaengine: zynqmp_dma: fix lockdep warning and cleanup
Message-ID: <20210826094742.1302009-1-m.tretter@pengutronix.de>

Hi,

I reported a lockdep warning in the ZynqMP DMA driver a few weeks ago [0].
This series fixes the reported warning and performs some cleanup that I found
while looking at the driver more closely.

Patches 1-4 are the cleanups. They affect the log output of the driver, allow
to compile the driver on other platforms when COMPILE_TEST is enabled, and
remove unused included header files from the driver.

Patches 5-7 aim to fix the lockdep warning. Patch 5 and 6 restructure the
locking in the driver to make it more fine-grained instead of holding the lock
for the entire tasklet. Patch 7 finally fixes the warning.

Michael

[0] https://lore.kernel.org/linux-arm-kernel/20210601130108.GA12967 at pengutronix.de/

Michael Tretter (7):
  dmaengine: zynqmp_dma: simplify with dev_err_probe
  dmaengine: zynqmp_dma: drop message on probe success
  dmaengine: zynqmp_dma: enable COMPILE_TEST
  dmaengine: zynqmp_dma: cleanup includes
  dmaengine: zynqmp_dma: cleanup after completing all descriptors
  dmaengine: zynqmp_dma: refine dma descriptor locking
  dmaengine: zynqmp_dma: fix lockdep warning in tasklet

 drivers/dma/Kconfig             |  2 +-
 drivers/dma/xilinx/zynqmp_dma.c | 67 +++++++++++++++++----------------
 2 files changed, 35 insertions(+), 34 deletions(-)

-- 
2.30.2



From m.tretter at pengutronix.de  Thu Aug 26 02:47:42 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 26 Aug 2021 11:47:42 +0200
Subject: [PATCH 7/7] dmaengine: zynqmp_dma: fix lockdep warning in tasklet
In-Reply-To: <20210826094742.1302009-1-m.tretter@pengutronix.de>
References: <20210826094742.1302009-1-m.tretter@pengutronix.de>
Message-ID: <20210826094742.1302009-8-m.tretter@pengutronix.de>

The tasklet that handles the completed dma transfers uses spin_unlock
for unlocking a spin lock that was previously locked with
spin_lock_irqsave.

This caused the following lockdep warning about an inconsistent lock
state:

	inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.

We must use spin_lock_irqsave, because it is possible to queue DMA
transfers from an irq handler.

Replace the spin_unlock and spin_lock by spin_unlock_irqrestore and
spin_lock_irqsave.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/dma/xilinx/zynqmp_dma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
index ef32f7519e0a..5f5f9e244ec6 100644
--- a/drivers/dma/xilinx/zynqmp_dma.c
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -612,9 +612,9 @@ static void zynqmp_dma_chan_desc_cleanup(struct zynqmp_dma_chan *chan)
 		callback = desc->async_tx.callback;
 		callback_param = desc->async_tx.callback_param;
 		if (callback) {
-			spin_unlock(&chan->lock);
+			spin_unlock_irqrestore(&chan->lock, irqflags);
 			callback(callback_param);
-			spin_lock(&chan->lock);
+			spin_lock_irqsave(&chan->lock, irqflags);
 		}
 
 		/* Run any dependencies, then free the descriptor */
-- 
2.30.2



From m.tretter at pengutronix.de  Thu Aug 26 02:47:41 2021
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Thu, 26 Aug 2021 11:47:41 +0200
Subject: [PATCH 6/7] dmaengine: zynqmp_dma: refine dma descriptor locking
In-Reply-To: <20210826094742.1302009-1-m.tretter@pengutronix.de>
References: <20210826094742.1302009-1-m.tretter@pengutronix.de>
Message-ID: <20210826094742.1302009-7-m.tretter@pengutronix.de>

The descriptor lists are locked for the entire tasklet that completes
the descriptors. This is not necessary, because the lock actually only
protects the descriptor lists.

Make the spin lock more fine-grained and only protect functions that
actually operate on the descriptor lists. This decreases the time when
the lock is held.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/dma/xilinx/zynqmp_dma.c | 35 ++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
index f98ef5fe4902..ef32f7519e0a 100644
--- a/drivers/dma/xilinx/zynqmp_dma.c
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -601,6 +601,9 @@ static void zynqmp_dma_start_transfer(struct zynqmp_dma_chan *chan)
 static void zynqmp_dma_chan_desc_cleanup(struct zynqmp_dma_chan *chan)
 {
 	struct zynqmp_dma_desc_sw *desc, *next;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&chan->lock, irqflags);
 
 	list_for_each_entry_safe(desc, next, &chan->done_list, node) {
 		dma_async_tx_callback callback;
@@ -617,6 +620,8 @@ static void zynqmp_dma_chan_desc_cleanup(struct zynqmp_dma_chan *chan)
 		/* Run any dependencies, then free the descriptor */
 		zynqmp_dma_free_descriptor(chan, desc);
 	}
+
+	spin_unlock_irqrestore(&chan->lock, irqflags);
 }
 
 /**
@@ -656,9 +661,13 @@ static void zynqmp_dma_issue_pending(struct dma_chan *dchan)
  */
 static void zynqmp_dma_free_descriptors(struct zynqmp_dma_chan *chan)
 {
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&chan->lock, irqflags);
 	zynqmp_dma_free_desc_list(chan, &chan->active_list);
 	zynqmp_dma_free_desc_list(chan, &chan->pending_list);
 	zynqmp_dma_free_desc_list(chan, &chan->done_list);
+	spin_unlock_irqrestore(&chan->lock, irqflags);
 }
 
 /**
@@ -668,11 +677,8 @@ static void zynqmp_dma_free_descriptors(struct zynqmp_dma_chan *chan)
 static void zynqmp_dma_free_chan_resources(struct dma_chan *dchan)
 {
 	struct zynqmp_dma_chan *chan = to_chan(dchan);
-	unsigned long irqflags;
 
-	spin_lock_irqsave(&chan->lock, irqflags);
 	zynqmp_dma_free_descriptors(chan);
-	spin_unlock_irqrestore(&chan->lock, irqflags);
 	dma_free_coherent(chan->dev,
 		(2 * ZYNQMP_DMA_DESC_SIZE(chan) * ZYNQMP_DMA_NUM_DESCS),
 		chan->desc_pool_v, chan->desc_pool_p);
@@ -687,11 +693,16 @@ static void zynqmp_dma_free_chan_resources(struct dma_chan *dchan)
  */
 static void zynqmp_dma_reset(struct zynqmp_dma_chan *chan)
 {
+	unsigned long irqflags;
+
 	writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS);
 
+	spin_lock_irqsave(&chan->lock, irqflags);
 	zynqmp_dma_complete_descriptor(chan);
+	spin_unlock_irqrestore(&chan->lock, irqflags);
 	zynqmp_dma_chan_desc_cleanup(chan);
 	zynqmp_dma_free_descriptors(chan);
+
 	zynqmp_dma_init(chan);
 }
 
@@ -747,28 +758,27 @@ static void zynqmp_dma_do_tasklet(struct tasklet_struct *t)
 	u32 count;
 	unsigned long irqflags;
 
-	spin_lock_irqsave(&chan->lock, irqflags);
-
 	if (chan->err) {
 		zynqmp_dma_reset(chan);
 		chan->err = false;
-		goto unlock;
+		return;
 	}
 
+	spin_lock_irqsave(&chan->lock, irqflags);
 	count = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT);
-
 	while (count) {
 		zynqmp_dma_complete_descriptor(chan);
 		count--;
 	}
+	spin_unlock_irqrestore(&chan->lock, irqflags);
 
 	zynqmp_dma_chan_desc_cleanup(chan);
 
-	if (chan->idle)
+	if (chan->idle) {
+		spin_lock_irqsave(&chan->lock, irqflags);
 		zynqmp_dma_start_transfer(chan);
-
-unlock:
-	spin_unlock_irqrestore(&chan->lock, irqflags);
+		spin_unlock_irqrestore(&chan->lock, irqflags);
+	}
 }
 
 /**
@@ -780,12 +790,9 @@ static void zynqmp_dma_do_tasklet(struct tasklet_struct *t)
 static int zynqmp_dma_device_terminate_all(struct dma_chan *dchan)
 {
 	struct zynqmp_dma_chan *chan = to_chan(dchan);
-	unsigned long irqflags;
 
-	spin_lock_irqsave(&chan->lock, irqflags);
 	writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS);
 	zynqmp_dma_free_descriptors(chan);
-	spin_unlock_irqrestore(&chan->lock, irqflags);
 
 	return 0;
 }
-- 
2.30.2



From hayashi.kunihiko at socionext.com  Thu Aug 26 03:02:11 2021
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Thu, 26 Aug 2021 19:02:11 +0900
Subject: [PATCH] PCI: uniphier: Serialize INTx masking/unmasking
In-Reply-To: <87o89lq4eb.wl-maz@kernel.org>
References: <1629717500-19396-1-git-send-email-hayashi.kunihiko@socionext.com>
 <20210823150927.jhobzfxy6e4s663r@pali> <87zgt8p09n.wl-maz@kernel.org>
 <f4d13190-facf-55ca-58c5-cd0d68e377d7@socionext.com>
 <87o89lq4eb.wl-maz@kernel.org>
Message-ID: <7a7ed6c9-53b6-0bd9-c8e2-5eea7b5c1c24@socionext.com>

Hi Marc,

On 2021/08/25 18:07, Marc Zyngier wrote:
> On Wed, 25 Aug 2021 01:01:08 +0100,
> Kunihiko Hayashi <hayashi.kunihiko at socionext.com> wrote:
>>
>> Hi Marc,
>>
>> On 2021/08/24 1:57, Marc Zyngier wrote:
>>> On Mon, 23 Aug 2021 16:09:27 +0100,
>>> Pali Roh?r <pali at kernel.org> wrote:
>>>>
>>>> + Marc (who originally reported this issue)
>>>>
>>>> On Monday 23 August 2021 20:18:20 Kunihiko Hayashi wrote:
>>>>> The condition register PCI_RCV_INTX is used in irq_mask(), irq_unmask()
>>>>> and irq_ack() callbacks. Accesses to register can occur at the same time
>>>>> without a lock.
>>>>> Add a lock into each callback to prevent the issue.
>>>>>
>>>>> Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
>>>>> Suggested-by: Pali Roh?r <pali at kernel.org>
>>>>> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
>>>>
>>>> Acked-by: Pali Roh?r <pali at kernel.org>
>>>>
>>>>> ---
>>>>>    drivers/pci/controller/dwc/pcie-uniphier.c | 15 +++++++++++++++
>>>>>    1 file changed, 15 insertions(+)
>>>>>
>>>>> The previous patch is as follows:
>>>>> https://lore.kernel.org/linux-pci/1629370566-29984-1-git-send-email-hayashi.kunihiko at socionext.com/
>>>>>
>>>>> Changes in the previous patch:
>>>>> - Change the subject and commit message
>>>>>
>>>>> diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
>>>>> index ebe43e9..5075714 100644
>>>>> --- a/drivers/pci/controller/dwc/pcie-uniphier.c
>>>>> +++ b/drivers/pci/controller/dwc/pcie-uniphier.c
>>>>> @@ -186,12 +186,17 @@ static void uniphier_pcie_irq_ack(struct irq_data *d)
>>>>>    	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>>>>>    	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>>>>    	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
>>>>> +	unsigned long flags;
>>>>>    	u32 val;
>>>>>    +	raw_spin_lock_irqsave(&pp->lock, flags);
>>>>> +
>>>>>    	val = readl(priv->base + PCL_RCV_INTX);
>>>>>    	val &= ~PCL_RCV_INTX_ALL_STATUS;
>>>>>    	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
>>>>>    	writel(val, priv->base + PCL_RCV_INTX);
>>>>> +
>>>>> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>>>>>    }
>>>>>      static void uniphier_pcie_irq_mask(struct irq_data *d)
>>>>> @@ -199,12 +204,17 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
>>>>>    	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>>>>>    	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>>>>    	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
>>>>> +	unsigned long flags;
>>>>>    	u32 val;
>>>>>    +	raw_spin_lock_irqsave(&pp->lock, flags);
>>>>> +
>>>>>    	val = readl(priv->base + PCL_RCV_INTX);
>>>>>    	val &= ~PCL_RCV_INTX_ALL_MASK;
>>>>>    	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
>>>
>>> This looks extremely suspicious. You clear all the INTX mask bits, and
>>> only set the one you need. How about the pre-existing bits?
>>
>> Thanks for pointing out. No need to clear all INTX mask bits.
>> The pre-existing bits should be preserved.
>>
>>>
>>>>>    	writel(val, priv->base + PCL_RCV_INTX);
>>>>> +
>>>>> +	raw_spin_unlock_irqrestore(&pp->lock, flags);
>>>>>    }
>>>>>      static void uniphier_pcie_irq_unmask(struct irq_data *d)
>>>>> @@ -212,12 +222,17 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
>>>>>    	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
>>>>>    	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>>>>>    	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
>>>>> +	unsigned long flags;
>>>>>    	u32 val;
>>>>>    +	raw_spin_lock_irqsave(&pp->lock, flags);
>>>>> +
>>>>>    	val = readl(priv->base + PCL_RCV_INTX);
>>>>>    	val &= ~PCL_RCV_INTX_ALL_MASK;
>>>>>    	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
>>>
>>> And by the same token, this second line is totally useless.
>>>
>>> I think masking/unmasking is broken in this driver, locking or not.
>>
>> Yes, this second line should be removed, too.
> 
> You mean the *first* line, right? The one clearing all the INTx
> bits. If you remove the second line, you won't fix anything.
This is ambiguous. I mean that I will remove the following line:

     	val &= ~PCL_RCV_INTX_ALL_MASK;

So the fixed unmasking code is as follows.

     	val = readl(priv->base + PCL_RCV_INTX);
     	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
     	writel(val, priv->base + PCL_RCV_INTX);

Thank you,

---
Best Regards
Kunihiko Hayashi


From maz at kernel.org  Thu Aug 26 03:37:46 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 26 Aug 2021 11:37:46 +0100
Subject: [PATCH] KVM: arm64: Trim guest debug exception handling
In-Reply-To: <20210823223940.1878930-1-rananta@google.com>
References: <20210823223940.1878930-1-rananta@google.com>
Message-ID: <162997424183.1640651.9657746284386330796.b4-ty@kernel.org>

On Mon, 23 Aug 2021 22:39:40 +0000, Raghavendra Rao Ananta wrote:
> The switch-case for handling guest debug exception covers
> all the debug exception classes, but functionally, doesn't
> do anything with them other than ESR_ELx_EC_WATCHPT_LOW.
> Moreover, even though handled well, the 'default' case
> could be confusing from a security point of view, stating
> that the guests' actions can potentially flood the syslog.
> But in reality, the code is unreachable.
> 
> [...]

Applied to next, thanks!

[1/1] KVM: arm64: Trim guest debug exception handling
      commit: 8ce8a6fce9bfd3fcabe230ad104e2caf08b2e58d

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From catalin.marinas at arm.com  Thu Aug 26 04:07:12 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 26 Aug 2021 12:07:12 +0100
Subject: [PATCH v2] arm64: Do not trap PMSNEVFR_EL1
In-Reply-To: <20210824154523.906270-1-alexandru.elisei@arm.com>
References: <20210824154523.906270-1-alexandru.elisei@arm.com>
Message-ID: <162997601443.30374.2606931123548634826.b4-ty@arm.com>

On Tue, 24 Aug 2021 16:45:23 +0100, Alexandru Elisei wrote:
> Commit 31c00d2aeaa2 ("arm64: Disable fine grained traps on boot") zeroed
> the fine grained trap registers to prevent unwanted register traps from
> occuring. However, for the PMSNEVFR_EL1 register, the corresponding
> HDFG{R,W}TR_EL2.nPMSNEVFR_EL1 fields must be 1 to disable trapping. Set
> both fields to 1 if FEAT_SPEv1p2 is detected to disable read and write
> traps.

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: Do not trap PMSNEVFR_EL1
      https://git.kernel.org/arm64/c/50cb99fa89aa

-- 
Catalin



From catalin.marinas at arm.com  Thu Aug 26 04:07:29 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 26 Aug 2021 12:07:29 +0100
Subject: [PATCH] arm64: mm: fix comment typo of pud_offset_phys()
In-Reply-To: <20210825150526.12582-1-lengxujun2007@126.com>
References: <20210825150526.12582-1-lengxujun2007@126.com>
Message-ID: <162997601443.30374.4843361649013969123.b4-ty@arm.com>

On Wed, 25 Aug 2021 23:05:26 +0800, Xujun Leng wrote:
> Fix a typo in the comment of macro pud_offset_phys().

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: mm: fix comment typo of pud_offset_phys()
      https://git.kernel.org/arm64/c/5845e703f9b5

-- 
Catalin



From catalin.marinas at arm.com  Thu Aug 26 04:07:39 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 26 Aug 2021 12:07:39 +0100
Subject: [PATCH] arm64: signal32: Drop pointless call to sigdelsetmask()
In-Reply-To: <20210825093911.24493-1-will@kernel.org>
References: <20210825093911.24493-1-will@kernel.org>
Message-ID: <162997601443.30374.525425511591184271.b4-ty@arm.com>

On Wed, 25 Aug 2021 10:39:11 +0100, Will Deacon wrote:
> Commit 77097ae503b1 ("most of set_current_blocked() callers want
> SIGKILL/SIGSTOP removed from set") extended set_current_blocked() to
> remove SIGKILL and SIGSTOP from the new signal set and updated all
> callers accordingly.
> 
> Unfortunately, this collided with the merge of the arm64 architecture,
> which duly removes these signals when restoring the compat sigframe, as
> this was what was previously done by arch/arm/.
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: signal32: Drop pointless call to sigdelsetmask()
      https://git.kernel.org/arm64/c/24de5838db70

-- 
Catalin



From stefan.wahren at i2se.com  Thu Aug 26 04:18:38 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Thu, 26 Aug 2021 13:18:38 +0200
Subject: [PATCH V2 05/10] mmc: sdhci-iproc: Set
 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711
In-Reply-To: <CAPDyKFpGoMVywNFMskTTYYOvLZMK-1u2+5V_q1uW2H5AZJ_W7Q@mail.gmail.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
 <1628334401-6577-6-git-send-email-stefan.wahren@i2se.com>
 <3e8bfa67-e3fe-bcfd-1941-90cae7ed0176@arm.com>
 <CAPDyKFpGoMVywNFMskTTYYOvLZMK-1u2+5V_q1uW2H5AZJ_W7Q@mail.gmail.com>
Message-ID: <127aeb73-528d-9118-3f84-6ad6c6debe84@i2se.com>

Am 26.08.21 um 11:22 schrieb Ulf Hansson:
> On Thu, 26 Aug 2021 at 08:36, Jeremy Linton <jeremy.linton at arm.com> wrote:
>> Hi,
>>
>>
>> On 8/7/21 6:06 AM, Stefan Wahren wrote:
>>> From: Nicolas Saenz Julienne <nsaenz at kernel.org>
>>>
>>> The controller doesn't seem to pick-up on clock changes, so set the
>>> SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN flag to query the clock frequency
>>> directly from the clock.
>>>
>>> Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
>>> Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
>>> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
>>> ---
>>>   drivers/mmc/host/sdhci-iproc.c | 3 ++-
>>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
>>> index 032bf85..e7565c6 100644
>>> --- a/drivers/mmc/host/sdhci-iproc.c
>>> +++ b/drivers/mmc/host/sdhci-iproc.c
>>> @@ -295,7 +295,8 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
>>>   };
>>>
>>>   static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
>>> -     .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
>>> +     .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
>>> +               SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
>>>       .ops = &sdhci_iproc_bcm2711_ops,
>>>   };
>> I just noticed that this got merged to rc7, and it breaks the ACPI based
>> rpi's because it causes the 100Mhz max clock to be overridden to the
>> return from sdhci_iproc_get_max_clock() which is 0 because there isn't a
>> OF/DT based clock device.
> Thanks for reporting! I allow Stefan to respond in a day or two,
> before I do a revert of it.

I'm fine with a revert.

Thanks

>
> Kind regards
> Uffe


From sudeep.holla at arm.com  Thu Aug 26 04:26:00 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 26 Aug 2021 12:26:00 +0100
Subject: [PATCH V3 7/9] cpufreq: scpi: Use .register_em() to register
 with energy model
In-Reply-To: <a214649dfcbc812ddf6b3906315da166caf01964.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
 <a214649dfcbc812ddf6b3906315da166caf01964.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <20210826112451.jax5w347hz77sww4@bogus>

On Thu, Aug 12, 2021 at 10:05:20AM +0530, Viresh Kumar wrote:
> Set the newly added .register_em() callback with
> cpufreq_register_em_with_opp() to register with the EM core.
> 

If not too late,

Acked-by: Sudeep Holla <sudeep.holla at arm.com>

-- 
Regards,
Sudeep


From colin.king at canonical.com  Thu Aug 26 04:26:11 2021
From: colin.king at canonical.com (Colin King)
Date: Thu, 26 Aug 2021 12:26:11 +0100
Subject: [PATCH][next] ASoC: mediatek: mt8195: Fix spelling mistake "bitwiedh"
 -> "bitwidth"
Message-ID: <20210826112611.10356-1-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

There is a spelling mistake in a dev_dbg message. Fix it.

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 sound/soc/mediatek/mt8195/mt8195-dai-etdm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
index bd9876cf02c8..7378e42f2766 100644
--- a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
+++ b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c
@@ -1909,7 +1909,7 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 		__func__, etdm_data->format, etdm_data->data_mode,
 		etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv,
 		etdm_data->clock_mode, etdm_data->slave_mode);
-	dev_dbg(afe->dev, "%s rate %u channels %u bitwiedh %u, id %d\n",
+	dev_dbg(afe->dev, "%s rate %u channels %u bitwidth %u, id %d\n",
 		__func__, rate, channels, bit_width, dai_id);
 
 	etdm_channels = (etdm_data->data_mode == MTK_DAI_ETDM_DATA_ONE_PIN) ?
-- 
2.32.0



From sudeep.holla at arm.com  Thu Aug 26 04:27:27 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 26 Aug 2021 12:27:27 +0100
Subject: [PATCH V3 9/9] cpufreq: scmi: Use .register_em() to register
 with energy model
In-Reply-To: <8158488baa1ea1aebd09c8d256db7420051d05ac.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
 <8158488baa1ea1aebd09c8d256db7420051d05ac.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <20210826112727.67iz5lpawk6muo5u@bogus>

On Thu, Aug 12, 2021 at 10:05:22AM +0530, Viresh Kumar wrote:
> Set the newly added .register_em() callback to register with the EM
> after the cpufreq policy is properly initialized.
> 

Acked-by: Sudeep Holla <sudeep.holla at arm.com>

-- 
Regards,
Sudeep


From gregkh at linuxfoundation.org  Thu Aug 26 04:27:53 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 26 Aug 2021 13:27:53 +0200
Subject: [PATCH] usb: host: ehci: skip STS_HALT check for aspeed platform
In-Reply-To: <20210826071525.27651-1-neal_liu@aspeedtech.com>
References: <20210826071525.27651-1-neal_liu@aspeedtech.com>
Message-ID: <YSd6uSfjlqmaN+us@kroah.com>

On Thu, Aug 26, 2021 at 03:15:25PM +0800, neal_liu wrote:
> STS_HALT also depends on ASS/PSS status for apseed.
> Skip this check on startup.
> 
> Signed-off-by: neal_liu <neal_liu at aspeedtech.com>
> ---
>  drivers/usb/host/ehci-hcd.c      | 10 +++++++++-
>  drivers/usb/host/ehci-platform.c |  6 ++++++
>  drivers/usb/host/ehci.h          |  1 +
>  3 files changed, 16 insertions(+), 1 deletion(-)
> 

Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- Your patch contains warnings and/or errors noticed by the
  scripts/checkpatch.pl tool.

- You did not specify a description of why the patch is needed, or
  possibly, any description at all, in the email body.  Please read the
  section entitled "The canonical patch format" in the kernel file,
  Documentation/SubmittingPatches for what is needed in order to
  properly describe the change.

- It looks like you did not use your "real" name for the patch on either
  the Signed-off-by: line, or the From: line (both of which have to
  match).  Please read the kernel file, Documentation/SubmittingPatches
  for how to do this correctly.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot


From f.fainelli at gmail.com  Thu Aug 26 04:28:29 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 26 Aug 2021 13:28:29 +0200
Subject: [RFC net-next 1/2] net: dsa: allow taggers to customise netdev
 features
In-Reply-To: <20210825083832.2425886-2-dqfext@gmail.com>
References: <20210825083832.2425886-1-dqfext@gmail.com>
 <20210825083832.2425886-2-dqfext@gmail.com>
Message-ID: <4b61ce72-87ec-cf8b-9f71-67eb329a9ce6@gmail.com>



On 8/25/2021 10:38 AM, DENG Qingfang wrote:
> Allow taggers to add netdev features, such as VLAN offload, to slave
> devices, which will make it possible for taggers to handle VLAN tags
> themselves.
> 
> Signed-off-by: DENG Qingfang <dqfext at gmail.com>

Besides transmit VLAN tag offload, do you think there are other netdev 
feature bits that would warrant something like this as opposed to a more 
structured approach with adding a specific boolean/flag that is specific 
to the netdev feature you want to propagate towards the DSA slave_dev?

Still:

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From sudeep.holla at arm.com  Thu Aug 26 04:28:37 2021
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 26 Aug 2021 12:28:37 +0100
Subject: [PATCH V3 8/9] cpufreq: vexpress: Use .register_em() to register
 with energy model
In-Reply-To: <b64eea485feb5cfb18e74e100dea49c917d4474a.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
 <b64eea485feb5cfb18e74e100dea49c917d4474a.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <20210826112837.63tcvpz76esez3hr@bogus>

On Thu, Aug 12, 2021 at 10:05:21AM +0530, Viresh Kumar wrote:
> Set the newly added .register_em() callback with
> cpufreq_register_em_with_opp() to register with the EM core.
>

Acked-by: Sudeep Holla <sudeep.holla at arm.com>

-- 
Regards,
Sudeep


From krzysztof.kozlowski at canonical.com  Thu Aug 26 04:30:47 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 26 Aug 2021 13:30:47 +0200
Subject: [PATCH 1/3] dt-bindings: memory: fsl: convert DDR controller to
 dtschema
Message-ID: <20210826113049.92962-1-krzysztof.kozlowski@canonical.com>

Convert Freescale/NXP DDR memory controller bindings to DT schema format
using json-schema.

Previous bindings were not listing all compatibles, so scan through
devicetree sources and drivers to get these.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/memory-controllers/fsl/ddr.txt   | 29 -------
 .../memory-controllers/fsl/fsl,ddr.yaml       | 83 +++++++++++++++++++
 2 files changed, 83 insertions(+), 29 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/ddr.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ddr.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/ddr.txt b/Documentation/devicetree/bindings/memory-controllers/fsl/ddr.txt
deleted file mode 100644
index dde6d837083a..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/fsl/ddr.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Freescale DDR memory controller
-
-Properties:
-
-- compatible	: Should include "fsl,chip-memory-controller" where
-		  chip is the processor (bsc9132, mpc8572 etc.), or
-		  "fsl,qoriq-memory-controller".
-- reg		: Address and size of DDR controller registers
-- interrupts	: Error interrupt of DDR controller
-- little-endian	: Specifies little-endian access to registers
-		  If omitted, big-endian will be used.
-
-Example 1:
-
-	memory-controller at 2000 {
-		compatible = "fsl,bsc9132-memory-controller";
-		reg = <0x2000 0x1000>;
-		interrupts = <16 2 1 8>;
-	};
-
-
-Example 2:
-
-	ddr1: memory-controller at 8000 {
-		compatible = "fsl,qoriq-memory-controller-v4.7",
-				"fsl,qoriq-memory-controller";
-		reg = <0x8000 0x1000>;
-		interrupts = <16 2 1 23>;
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ddr.yaml b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ddr.yaml
new file mode 100644
index 000000000000..af5147f9da72
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ddr.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,ddr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale DDR memory controller
+
+maintainers:
+  - Borislav Petkov <bp at alien8.de>
+  - York Sun <york.sun at nxp.com>
+
+properties:
+  $nodename:
+    pattern: "^memory-controller@[0-9a-f]+$"
+
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - fsl,qoriq-memory-controller-v4.4
+              - fsl,qoriq-memory-controller-v4.5
+              - fsl,qoriq-memory-controller-v4.7
+              - fsl,qoriq-memory-controller-v5.0
+          - const: fsl,qoriq-memory-controller
+      - enum:
+          - fsl,bsc9132-memory-controller
+          - fsl,8540-memory-controller
+          - fsl,8541-memory-controller
+          - fsl,8544-memory-controller
+          - fsl,8548-memory-controller
+          - fsl,8555-memory-controller
+          - fsl,8568-memory-controller
+          - fsl,mpc8536-memory-controller
+          - fsl,mpc8540-memory-controller
+          - fsl,mpc8541-memory-controller
+          - fsl,mpc8544-memory-controller
+          - fsl,mpc8548-memory-controller
+          - fsl,mpc8555-memory-controller
+          - fsl,mpc8560-memory-controller
+          - fsl,mpc8568-memory-controller
+          - fsl,mpc8569-memory-controller
+          - fsl,mpc8572-memory-controller
+          - fsl,mpc8349-memory-controller
+          - fsl,p1020-memory-controller
+          - fsl,p1021-memory-controller
+          - fsl,p2020-memory-controller
+          - fsl,qoriq-memory-controller
+
+  interrupts:
+    maxItems: 1
+
+  little-endian:
+    description:
+      Specifies little-endian access to registers. If omitted, big-endian will
+      be used.
+    type: boolean
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - interrupts
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    memory-controller at 2000 {
+        compatible = "fsl,bsc9132-memory-controller";
+        reg = <0x2000 0x1000>;
+        interrupts = <16 2 1 8>;
+    };
+
+  - |
+    memory-controller at 8000 {
+        compatible = "fsl,qoriq-memory-controller-v4.7",
+                     "fsl,qoriq-memory-controller";
+        reg = <0x8000 0x1000>;
+        interrupts = <16 2 1 23>;
+    };
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Thu Aug 26 04:30:48 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 26 Aug 2021 13:30:48 +0200
Subject: [PATCH 2/3] ARM: dts: ls1021a: drop unused big-endian property from
 DDR controller
In-Reply-To: <20210826113049.92962-1-krzysztof.kozlowski@canonical.com>
References: <20210826113049.92962-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210826113049.92962-2-krzysztof.kozlowski@canonical.com>

The big-endian is default setting for DDR controller as expressed in
bindings and such property was never documented for Freescale DDR memory
controller.  The driver also does not parse this property at all.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 4fce81422943..0f759bc81239 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -136,7 +136,6 @@ ddr: memory-controller at 1080000 {
 			compatible = "fsl,qoriq-memory-controller";
 			reg = <0x0 0x1080000 0x0 0x1000>;
 			interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
-			big-endian;
 		};
 
 		gic: interrupt-controller at 1400000 {
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Thu Aug 26 04:32:31 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 26 Aug 2021 13:32:31 +0200
Subject: [PATCH 3/3] arm64: dts: freescale: ls1046a: drop unused big-endian
 property from DDR controller
In-Reply-To: <20210826113049.92962-1-krzysztof.kozlowski@canonical.com>
References: <20210826113049.92962-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210826113231.93232-1-krzysztof.kozlowski@canonical.com>

The big-endian is default setting for DDR controller as expressed in
bindings and such property was never documented for Freescale DDR memory
controller.  The driver also does not parse this property at all.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 687fea6d8afa..b06c285b6534 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -277,7 +277,6 @@ ddr: memory-controller at 1080000 {
 			compatible = "fsl,qoriq-memory-controller";
 			reg = <0x0 0x1080000 0x0 0x1000>;
 			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
-			big-endian;
 		};
 
 		ifc: ifc at 1530000 {
-- 
2.30.2



From f.fainelli at gmail.com  Thu Aug 26 04:37:22 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 26 Aug 2021 13:37:22 +0200
Subject: [RFC net-next 2/2] net: dsa: tag_mtk: handle VLAN tag insertion
 on TX
In-Reply-To: <20210826052956.3101243-1-dqfext@gmail.com>
References: <20210825083832.2425886-1-dqfext@gmail.com>
 <20210825083832.2425886-3-dqfext@gmail.com>
 <20210826000349.q3s5gjuworxtbcna@skbuf>
 <20210826052956.3101243-1-dqfext@gmail.com>
Message-ID: <109fb944-e310-4cdd-82e8-367217bfd2f2@gmail.com>



On 8/26/2021 7:29 AM, DENG Qingfang wrote:
> On Thu, Aug 26, 2021 at 03:03:49AM +0300, Vladimir Oltean wrote:
>>
>> You cannot just remove the old code. Only things like 8021q uppers will
>> send packets with the VLAN in the hwaccel area.
>>
>> If you have an application that puts the VLAN in the actual AF_PACKET
>> payload, like:
>>
>> https://github.com/vladimiroltean/tsn-scripts/blob/master/isochron/send.c
>>
>> then you need to handle the VLAN being in the skb payload.
> 
> I've actually tested this (only apply patch 2 without .features) and it
> still worked.

OK and this works because now you always push a MTK_HDR_LEN tag which 
you were not doing before for VLAN-tagged frames, right?

You don't seem to be clearing mtk_tag[2] and mtk_tag[3] anymore, is that 
intended?

> 
> The comment says the VLAN tag need to be combined with the special tag in
> order to perform VLAN table lookup, so we can set its destination port
> vector to all zeroes and the switch will forward it like a data frame
> (TX forward offload), but as we allow multiple bridges which are either
> VLAN-unaware or VLAN-aware with the same VID, there is no way to determine
> the destination bridge unless we maintain some VLAN translation mapping.

There is no "bridge" on the other side from the CPU port's perspective 
on egress, only physical ports, so how does that comment apply?
-- 
Florian


From gregkh at linuxfoundation.org  Thu Aug 26 04:41:19 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 26 Aug 2021 13:41:19 +0200
Subject: [PATCH next v2 1/6] Revert "usb: xhci-mtk: relax TT periodic
 bandwidth allocation"
In-Reply-To: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
Message-ID: <YSd93+3D/PbacgsP@kroah.com>

On Thu, Aug 26, 2021 at 10:51:39AM +0800, Chunfeng Yun wrote:
> As discussed in following patch:
> https://patchwork.kernel.org/patch/12420339
> 
> No need calculate number of uframes again, but should use value
> form check_sch_tt(), if we plan to remove extra CS, also can do
> it in check_sch_tt(). So revert this patch, and prepare to send
> new patch for it.
> 
> This reverts commit 548011957d1d72e0b662300c8b32b81d593b796e.
> 
> Cc: Ikjoon Jang <ikjn at chromium.org>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
> v2: no changes

This series does not apply to my tree at all now, can you please rebase
and resend?

thanks,

greg k-h


From vee.khee.wong at linux.intel.com  Thu Aug 26 04:50:14 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Thu, 26 Aug 2021 19:50:14 +0800
Subject: [PATCH net-next 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <YRPcyHTc2FJeEoqk@lunn.ch>
References: <20210809102229.933748-1-vee.khee.wong@linux.intel.com>
 <20210809102229.933748-2-vee.khee.wong@linux.intel.com>
 <YREvDRkiuScyN8Ws@lunn.ch> <20210810235529.GB30818@linux.intel.com>
 <f2a1f135-b77a-403d-5d2e-c497efc99df7@gmail.com>
 <YRPcyHTc2FJeEoqk@lunn.ch>
Message-ID: <20210826115014.GA5112@linux.intel.com>

On Wed, Aug 11, 2021 at 04:20:56PM +0200, Andrew Lunn wrote:
> > > BIOS does configured the SerDes. The problem here is that all the
> > > configurations done by BIOS are being reset at xpcs_create().
> > > 
> > > We would want user of the pcs-xpcs module (stmmac, sja1105) to have
> > > control whether or not we need to perform to the soft reset in the
> > > xpcs_create() call.
> > 
> > I understood Andrew's response as suggesting to introduce the ability for
> > xpcs_create() to make a BIOS call which would configure the SerDes after
> > xpcs_soft_reset().
> 
> Yes. Exactly. That is what ACPI is for, so we should use it for this.
> 
>      Andrew

Thanks Florian for the explaination.

I have checked with the BIOS developers and they did not implmenet a
method to this at the kernel level.

Also, Intel AlderLake has both UEFI BIOS and Slim Bootloader which
make it least feasible to go for the ACPI method as per suggested.


Regards,
  VK


From ikjn at chromium.org  Thu Aug 26 04:54:04 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Thu, 26 Aug 2021 19:54:04 +0800
Subject: [PATCH next v2 3/6] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <20210826025144.51992-3-chunfeng.yun@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
 <20210826025144.51992-3-chunfeng.yun@mediatek.com>
Message-ID: <CAATdQgBD+dTtBie-cNKRJbfxEpc3haqjfUu1k26mTk8pCSOEww@mail.gmail.com>

Hi Chunfeng,

On Thu, Aug 26, 2021 at 10:52 AM Chunfeng Yun <chunfeng.yun at mediatek.com> wrote:
>
> Use @bw_budget_table[] to update fs bus bandwidth due to
> not all microframes consume @bw_cost_per_microframe, see
> setup_sch_info().
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
> v2: new patch, move from another series
> ---
>  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
>  1 file changed, 7 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
> index cffcaf4dfa9f..83abd28269ca 100644
> --- a/drivers/usb/host/xhci-mtk-sch.c
> +++ b/drivers/usb/host/xhci-mtk-sch.c
> @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
>                  * Compared with hs bus, no matter what ep type,
>                  * the hub will always delay one uframe to send data
>                  */
> -               for (j = 0; j < sch_ep->cs_count; j++) {
> -                       tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe;
> +               for (j = 0; j < sch_ep->num_budget_microframes; j++) {
> +                       tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j];

I'm worrying about this case with two endpoints,
* EP1OUT: isochronous, maxpacket=192: bw_budget_table[] = { 188, 188, 0, ... }
* EP2IN: interrupt, maxpacket=64: bw_budget_table[] = { 0, 0, 64, 64, ... }
(Is this correct bw_budget_table contents for those eps?)

I'm not sure if it's okay for those two endpoints to be allocated
on the same u-frame slot.
Can you please check if this is okay for xhci-mtk?
(I feel like I already asked the same questions many times.)


>                         if (tmp > FS_PAYLOAD_MAX)
>                                 return -ESCH_BW_OVERFLOW;
>                 }
> @@ -534,21 +534,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
>  {
>         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
>         u32 base, num_esit;
> -       int bw_updated;
>         int i, j;
>
>         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
>
> -       if (used)
> -               bw_updated = sch_ep->bw_cost_per_microframe;
> -       else
> -               bw_updated = -sch_ep->bw_cost_per_microframe;
> -
>         for (i = 0; i < num_esit; i++) {
>                 base = sch_ep->offset + i * sch_ep->esit;
>
> -               for (j = 0; j < sch_ep->cs_count; j++)
> -                       tt->fs_bus_bw[base + j] += bw_updated;
> +               for (j = 0; j < sch_ep->num_budget_microframes; j++)
> +                       if (used)
> +                               tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j];
> +                       else
> +                               tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j];
>         }
>
>         if (used)
> --
> 2.18.0
>


From maz at kernel.org  Thu Aug 26 04:56:49 2021
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 26 Aug 2021 12:56:49 +0100
Subject: [GIT PULL] KVM/arm64 updates for 5.15
Message-ID: <20210826115649.2641468-1-maz@kernel.org>

Hi Paolo,

Here's the KVM/arm64 pull request for 5.15. This round is all over the
map, with plenty of updates around the MM subsystem (page tables, page
ownership, small fixes), PMU (reset state, perf improvements), PSCI,
the move to the generic entry code, and a lot of cleanups all over the
shop, probably owing to having a few more eyes looking at the code.

A few things to note:

- the kvmarm-fixes-5.14-2 tag was brought in to allow the merge of
  some patches

- the arm64/for-next/sysreg was merged to resolve couple of conflicts

Please pull,

	M.

The following changes since commit c500bee1c5b2f1d59b1081ac879d73268ab0ff17:

  Linux 5.14-rc4 (2021-08-01 17:04:17 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-5.15

for you to fetch changes up to 419025b3b4190ee867ef4fc48fb3bd7da2e67a0c:

  Merge branch kvm-arm64/misc-5.15 into kvmarm-master/next (2021-08-26 11:36:12 +0100)

----------------------------------------------------------------
KVM/arm64 updates for 5.15

- Page ownership tracking between host EL1 and EL2

- Rely on userspace page tables to create large stage-2 mappings

- Fix incompatibility between pKVM and kmemleak

- Fix the PMU reset state, and improve the performance of the virtual PMU

- Move over to the generic KVM entry code

- Address PSCI reset issues w.r.t. save/restore

- Preliminary rework for the upcoming pKVM fixed feature

- A bunch of MM cleanups

- a vGIC fix for timer spurious interrupts

- Various cleanups

----------------------------------------------------------------
Alexandre Chartre (1):
      KVM: arm64: Disabling disabled PMU counters wastes a lot of time

Anshuman Khandual (9):
      arm64/kexec: Test page size support with new TGRAN range values
      KVM: arm64: perf: Replace '0xf' instances with ID_AA64DFR0_PMUVER_IMP_DEF
      arm64/mm: Define ID_AA64MMFR0_TGRAN_2_SHIFT
      KVM: arm64: Restrict IPA size to maximum 48 bits on 4K and 16K page size
      arm64/mm: Add remaining ID_AA64MMFR0_PARANGE_ macros
      KVM: arm64: Use ARM64_MIN_PARANGE_BITS as the minimum supported IPA
      KVM: arm64: Drop init_common_resources()
      KVM: arm64: Drop check_kvm_target_cpu() based percpu probe
      KVM: arm64: Drop unused REQUIRES_VIRT

David Brazdil (2):
      KVM: arm64: Fix off-by-one in range_is_memory
      KVM: arm64: Minor optimization of range_is_memory

Fuad Tabba (10):
      KVM: arm64: placeholder to check if VM is protected
      KVM: arm64: Remove trailing whitespace in comment
      KVM: arm64: MDCR_EL2 is a 64-bit register
      KVM: arm64: Fix names of config register fields
      KVM: arm64: Refactor sys_regs.h,c for nVHE reuse
      KVM: arm64: Restore mdcr_el2 from vcpu
      KVM: arm64: Keep mdcr_el2's value as set by __init_el2_debug
      KVM: arm64: Track value of cptr_el2 in struct kvm_vcpu_arch
      KVM: arm64: Add feature register flag definitions
      KVM: arm64: Add config register bit definitions

Jason Wang (1):
      KVM: arm64: Fix comments related to GICv2 PMR reporting

Marc Zyngier (28):
      KVM: arm64: Walk userspace page tables to compute the THP mapping size
      KVM: arm64: Avoid mapping size adjustment on permission fault
      KVM: Remove kvm_is_transparent_hugepage() and PageTransCompoundMap()
      KVM: arm64: Use get_page() instead of kvm_get_pfn()
      KVM: arm64: Introduce helper to retrieve a PTE and its level
      KVM: Get rid of kvm_get_pfn()
      KVM: arm64: Narrow PMU sysreg reset values to architectural requirements
      KVM: arm64: Drop unnecessary masking of PMU registers
      KVM: arm64: Remove PMSWINC_EL0 shadow register
      arm64: Move .hyp.rodata outside of the _sdata.._edata range
      KVM: arm64: Unregister HYP sections from kmemleak in protected mode
      KVM: arm64: vgic: Resample HW pending state on deactivation
      KVM: arm64: Move kern_hyp_va() usage in __load_guest_stage2() into the callers
      KVM: arm64: Unify stage-2 programming behind __load_stage2()
      KVM: arm64: Upgrade VMID accesses to {READ,WRITE}_ONCE
      KVM: arm64: Upgrade trace_kvm_arm_set_dreg32() to 64bit
      Merge branch arm64/for-next/sysreg into kvm-arm64/misc-5.15
      Merge tag 'kvmarm-fixes-5.14-2' into kvm-arm64/mmu/el2-tracking
      Merge branch kvm-arm64/pmu/reset-values into kvmarm-master/next
      Merge branch kvm-arm64/mmu/mapping-levels into kvmarm-master/next
      Merge branch kvm-arm64/misc-5.15 into kvmarm-master/next
      Merge branch kvm-arm64/mmu/kmemleak-pkvm into kvmarm-master/next
      Merge branch kvm-arm64/mmu/el2-tracking into kvmarm-master/next
      Merge branch kvm-arm64/psci/cpu_on into kvmarm-master/next
      Merge branch kvm-arm64/generic-entry into kvmarm-master/next
      Merge branch kvm-arm64/mmu/vmid-cleanups into kvmarm-master/next
      Merge branch kvm-arm64/pkvm-fixed-features-prologue into kvmarm-master/next
      Merge branch kvm-arm64/misc-5.15 into kvmarm-master/next

Oliver Upton (7):
      KVM: arm64: Fix read-side race on updates to vcpu reset state
      KVM: arm64: Handle PSCI resets before userspace touches vCPU state
      KVM: arm64: Enforce reserved bits for PSCI target affinities
      selftests: KVM: Introduce psci_cpu_on_test
      KVM: arm64: Record number of signal exits as a vCPU stat
      entry: KVM: Allow use of generic KVM entry w/o full generic support
      KVM: arm64: Use generic KVM xfer to guest work function

Paolo Bonzini (1):
      KVM: arm64: Count VMID-wide TLB invalidations

Quentin Perret (20):
      KVM: arm64: Introduce hyp_assert_lock_held()
      KVM: arm64: Provide the host_stage2_try() helper macro
      KVM: arm64: Expose page-table helpers
      KVM: arm64: Optimize host memory aborts
      KVM: arm64: Rename KVM_PTE_LEAF_ATTR_S2_IGNORED
      KVM: arm64: Don't overwrite software bits with owner id
      KVM: arm64: Tolerate re-creating hyp mappings to set software bits
      KVM: arm64: Enable forcing page-level stage-2 mappings
      KVM: arm64: Allow populating software bits
      KVM: arm64: Add helpers to tag shared pages in SW bits
      KVM: arm64: Expose host stage-2 manipulation helpers
      KVM: arm64: Expose pkvm_hyp_id
      KVM: arm64: Introduce addr_is_memory()
      KVM: arm64: Enable retrieving protections attributes of PTEs
      KVM: arm64: Mark host bss and rodata section as shared
      KVM: arm64: Remove __pkvm_mark_hyp
      KVM: arm64: Refactor protected nVHE stage-1 locking
      KVM: arm64: Restrict EL2 stage-1 changes in protected mode
      KVM: arm64: Make __pkvm_create_mappings static
      KVM: arm64: Return -EPERM from __pkvm_host_share_hyp()

Raghavendra Rao Ananta (1):
      KVM: arm64: Trim guest debug exception handling

Ricardo Koller (1):
      KVM: arm64: vgic: Drop WARN from vgic_get_irq

Steven Price (1):
      KVM: arm64: Fix race when enabling KVM_ARM_CAP_MTE

Will Deacon (2):
      KVM: arm64: Add hyp_spin_is_locked() for basic locking assertions at EL2
      KVM: arm64: Make hyp_panic() more robust when protected mode is enabled

 arch/arm64/include/asm/cpufeature.h                |  27 ++-
 arch/arm64/include/asm/kvm_arm.h                   |  54 +++--
 arch/arm64/include/asm/kvm_asm.h                   |   7 +-
 arch/arm64/include/asm/kvm_host.h                  |  17 +-
 arch/arm64/include/asm/kvm_hyp.h                   |   2 +-
 arch/arm64/include/asm/kvm_mmu.h                   |  17 +-
 arch/arm64/include/asm/kvm_pgtable.h               | 168 ++++++++++----
 arch/arm64/include/asm/sysreg.h                    |  54 +++--
 arch/arm64/kernel/cpufeature.c                     |   8 +-
 arch/arm64/kernel/vmlinux.lds.S                    |   4 +-
 arch/arm64/kvm/Kconfig                             |  10 +
 arch/arm64/kvm/arm.c                               | 173 ++++++---------
 arch/arm64/kvm/debug.c                             |   2 +-
 arch/arm64/kvm/guest.c                             |   5 +-
 arch/arm64/kvm/handle_exit.c                       |  43 ++--
 arch/arm64/kvm/hyp/include/hyp/switch.h            |   6 +-
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h      |  35 ++-
 arch/arm64/kvm/hyp/include/nvhe/mm.h               |   3 +-
 arch/arm64/kvm/hyp/include/nvhe/spinlock.h         |  25 +++
 arch/arm64/kvm/hyp/nvhe/debug-sr.c                 |   2 +-
 arch/arm64/kvm/hyp/nvhe/host.S                     |  21 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c                 |  20 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c              | 244 ++++++++++++++++----
 arch/arm64/kvm/hyp/nvhe/mm.c                       |  22 +-
 arch/arm64/kvm/hyp/nvhe/setup.c                    |  82 ++++++-
 arch/arm64/kvm/hyp/nvhe/switch.c                   |  17 +-
 arch/arm64/kvm/hyp/nvhe/tlb.c                      |   4 +-
 arch/arm64/kvm/hyp/pgtable.c                       | 247 +++++++++++----------
 arch/arm64/kvm/hyp/vhe/debug-sr.c                  |   2 +-
 arch/arm64/kvm/hyp/vhe/switch.c                    |  18 +-
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c                 |   2 +-
 arch/arm64/kvm/hyp/vhe/tlb.c                       |   4 +-
 arch/arm64/kvm/mmu.c                               |  76 ++++++-
 arch/arm64/kvm/perf.c                              |   2 +-
 arch/arm64/kvm/pmu-emul.c                          |  14 +-
 arch/arm64/kvm/psci.c                              |  15 +-
 arch/arm64/kvm/reset.c                             |  43 ++--
 arch/arm64/kvm/sys_regs.c                          | 134 ++++++-----
 arch/arm64/kvm/sys_regs.h                          |  31 +++
 arch/arm64/kvm/trace_handle_exit.h                 |  10 +-
 arch/arm64/kvm/vgic/vgic-mmio-v2.c                 |   4 +-
 arch/arm64/kvm/vgic/vgic-v2.c                      |  36 +--
 arch/arm64/kvm/vgic/vgic-v3.c                      |  36 +--
 arch/arm64/kvm/vgic/vgic.c                         |  39 +++-
 arch/arm64/kvm/vgic/vgic.h                         |   2 +
 include/linux/entry-kvm.h                          |   6 +-
 include/linux/kvm_host.h                           |   1 -
 include/linux/page-flags.h                         |  37 ---
 tools/testing/selftests/kvm/.gitignore             |   1 +
 tools/testing/selftests/kvm/Makefile               |   1 +
 .../selftests/kvm/aarch64/psci_cpu_on_test.c       | 121 ++++++++++
 .../selftests/kvm/include/aarch64/processor.h      |   3 +
 virt/kvm/kvm_main.c                                |  19 +-
 53 files changed, 1279 insertions(+), 697 deletions(-)
 create mode 100644 tools/testing/selftests/kvm/aarch64/psci_cpu_on_test.c


From robh+dt at kernel.org  Thu Aug 26 05:11:21 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Thu, 26 Aug 2021 07:11:21 -0500
Subject: [PATCH v6 2/3] PCI: visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <20210811083830.784065-3-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210811083830.784065-3-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <CAL_Jsq+tGAOo-9oKGF=B=3hCjiECBwxDujQu9drwCXK6u8J0BA@mail.gmail.com>

On Wed, Aug 11, 2021 at 3:38 AM Nobuhiro Iwamatsu
<nobuhiro1.iwamatsu at toshiba.co.jp> wrote:
>
> Add support to PCIe RC controller on Toshiba Visconti ARM SoCs. PCIe
> controller is based of Synopsys DesignWare PCIe core.
>
> Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
>
> v5 -> v6:
>   - Remove unnecessary commit log.
>   - Fix split line of visconti_add_pcie_port()
>
> v4 -> v5:
>   - Remove PCIE_BUS_OFFSET
>   - Change link_up confirmation function of visconti_pcie_link_up().
>   - Move setting event mask before dw_pcie_link_up().
>   - Move the contents of visconti_pcie_power_on() to visconti_pcie_host_init().
>   - Remove code for link_gen.
>
> v3 -> v4:
>   - Change variable from pci_addr to cpu_addr in visconti_pcie_cpu_addr_fixup().
>   - Change the calculation method of CPU addres from subtraction to mask, and
>     add comment.
>   - Drop dma_set_mask_and_coherent().
>   - Drop set MAX_MSI_IRQS.
>   - Drop dev_dbg for Link speed.
>   - Use use the dev_err_probe() to handle the devm_clk_get() failed.
>   - Changed the redundant clock name.
>
> v2 -> v3:
>   - Update subject.
>   - Wrap description in 75 columns.
>   - Change config name to PCIE_VISCONTI_HOST.
>   - Update Kconfig text.
>   - Drop blank lines.
>   - Adjusted to 80 columns.
>   - Drop inline from functions for register access.
>   - Changed function name from visconti_pcie_check_link_status to
>     visconti_pcie_link_up.
>   - Update to using dw_pcie_host_init().
>   - Reorder these in the order of use in visconti_pcie_establish_link.
>   - Rewrite visconti_pcie_host_init() without dw_pcie_setup_rc().
>   - Change function name from  visconti_device_turnon() to
>     visconti_pcie_power_on().
>   - Unify formats such as dev_err().
>   - Drop error label in visconti_add_pcie_port().
>
> v1 -> v2:
>   - Fix typo in commit message.
>   - Drop "depends on OF && HAS_IOMEM" from Kconfig.
>   - Stop using the pointer of struct dw_pcie.
>   - Use _relaxed variant.
>   - Drop dw_pcie_wait_for_link.
>   - Drop dbi resource processing.
>   - Drop MSI IRQ initialization processing.
> ---
>  drivers/pci/controller/dwc/Kconfig         |   9 +
>  drivers/pci/controller/dwc/Makefile        |   1 +
>  drivers/pci/controller/dwc/pcie-visconti.c | 333 +++++++++++++++++++++
>  3 files changed, 343 insertions(+)
>  create mode 100644 drivers/pci/controller/dwc/pcie-visconti.c

Reviewed-by: Rob Herring <robh at kernel.org>


From catalin.marinas at arm.com  Thu Aug 26 05:16:24 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 26 Aug 2021 13:16:24 +0100
Subject: [RFC PATCH] arm64: mm: limit linear region to 51 bits for KVM in
 nVHE mode
In-Reply-To: <CAMj1kXHKvUng_z5Gfd0bsFgbnpVPA-JjPLCRTa=87yVa4j7kHA@mail.gmail.com>
References: <20210810161244.84231-1-ardb@kernel.org>
 <20210824105920.GB22752@willie-the-truck>
 <CAMj1kXHKvUng_z5Gfd0bsFgbnpVPA-JjPLCRTa=87yVa4j7kHA@mail.gmail.com>
Message-ID: <20210826121623.GB30910@arm.com>

On Tue, Aug 24, 2021 at 02:56:22PM +0200, Ard Biesheuvel wrote:
> On Tue, 24 Aug 2021 at 12:59, Will Deacon <will at kernel.org> wrote:
> > On Tue, Aug 10, 2021 at 06:12:44PM +0200, Ard Biesheuvel wrote:
> > > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > > index 8490ed2917ff..542dad13e2fc 100644
> > > --- a/arch/arm64/mm/init.c
> > > +++ b/arch/arm64/mm/init.c
> > > @@ -282,7 +282,21 @@ static void __init fdt_enforce_memory_region(void)
> > >
> > >  void __init arm64_memblock_init(void)
> > >  {
> > > -     const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > > +     s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > > +
> > > +     /*
> > > +      * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
> > > +      * be limited in their ability to support a linear map that exceeds 51
> > > +      * bits of VA space, depending on the placement of the ID map. Given
> > > +      * that the placement of the ID map may be randomized, let's simply
> > > +      * limit the kernel's linear map to 51 bits as well if we detect this
> > > +      * configuration.
> > > +      */
> > > +     if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 &&
> > > +         !is_kernel_in_hyp_mode()) {
> > > +             pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n");
> > > +             linear_region_size = BIT(51);
> > > +     }
> >
> > Slight nit, but to avoid having to think about PAGE_END I think this would
> > be a little clearer as:
> >
> >         if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode())
> >                 linear_region_size = min_t(u64, linear_region_size, BIT(51));
> >
> 
> Fair enough.

Ard, do you plan to post a new version? I can make the change myself
locally as well.

-- 
Catalin


From ardb at kernel.org  Thu Aug 26 05:23:40 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 26 Aug 2021 14:23:40 +0200
Subject: [RFC PATCH] arm64: mm: limit linear region to 51 bits for KVM in
 nVHE mode
In-Reply-To: <20210826121623.GB30910@arm.com>
References: <20210810161244.84231-1-ardb@kernel.org>
 <20210824105920.GB22752@willie-the-truck>
 <CAMj1kXHKvUng_z5Gfd0bsFgbnpVPA-JjPLCRTa=87yVa4j7kHA@mail.gmail.com>
 <20210826121623.GB30910@arm.com>
Message-ID: <CAMj1kXFOAai73mJ62Rshb7iZTHKgfqU30wDQCekmMunR5AMM3g@mail.gmail.com>

On Thu, 26 Aug 2021 at 14:16, Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> On Tue, Aug 24, 2021 at 02:56:22PM +0200, Ard Biesheuvel wrote:
> > On Tue, 24 Aug 2021 at 12:59, Will Deacon <will at kernel.org> wrote:
> > > On Tue, Aug 10, 2021 at 06:12:44PM +0200, Ard Biesheuvel wrote:
> > > > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > > > index 8490ed2917ff..542dad13e2fc 100644
> > > > --- a/arch/arm64/mm/init.c
> > > > +++ b/arch/arm64/mm/init.c
> > > > @@ -282,7 +282,21 @@ static void __init fdt_enforce_memory_region(void)
> > > >
> > > >  void __init arm64_memblock_init(void)
> > > >  {
> > > > -     const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > > > +     s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > > > +
> > > > +     /*
> > > > +      * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
> > > > +      * be limited in their ability to support a linear map that exceeds 51
> > > > +      * bits of VA space, depending on the placement of the ID map. Given
> > > > +      * that the placement of the ID map may be randomized, let's simply
> > > > +      * limit the kernel's linear map to 51 bits as well if we detect this
> > > > +      * configuration.
> > > > +      */
> > > > +     if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 &&
> > > > +         !is_kernel_in_hyp_mode()) {
> > > > +             pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n");
> > > > +             linear_region_size = BIT(51);
> > > > +     }
> > >
> > > Slight nit, but to avoid having to think about PAGE_END I think this would
> > > be a little clearer as:
> > >
> > >         if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode())
> > >                 linear_region_size = min_t(u64, linear_region_size, BIT(51));
> > >
> >
> > Fair enough.
>
> Ard, do you plan to post a new version? I can make the change myself
> locally as well.
>

If you don't mind doing so, please go ahead.


From jens.wiklander at linaro.org  Thu Aug 26 05:30:26 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 26 Aug 2021 14:30:26 +0200
Subject: [PATCH v5 0/6] Asynchronous notifications from secure world
Message-ID: <20210826123032.1732926-1-jens.wiklander@linaro.org>

Hi all,

This adds support for asynchronous notifications from OP-TEE in secure
world to the OP-TEE driver. This allows a design with a top half and bottom
half type of driver where the top half runs in secure interrupt context and
a notifications tells normal world to schedule a yielding call to do the
bottom half processing.

An edge-triggered interrupt is used to notify the driver that there are
asynchronous notifications pending.

The documentation and DT bindings patches are now well reviewed, but
the patches with code would do with some more attention.

v4->v5:
* Rebased on v5.14-rc7
* Updated documentation to clarify that one interrupt may represent multiple
  notifications as requested.
* Applied Marc's and Rob's tags

v3->v4:
* Clarfied the expected type of interrypt is edge-triggered, both in
  the normal documentation and in the DT bindings as requested.

v2->v3:
* Rebased on v5.14-rc2 which made the patch "dt-bindings: arm: Convert
  optee binding to json-schema" from the V2 patch set obsolete.
* Applied Ard's Acked-by on "optee: add asynchronous notifications"

v1->v2:
* Added documentation
* Converted optee bindings to json-schema and added interrupt property
* Configure notification interrupt from DT instead of getting it
  from secure world, suggested by Ard Biesheuvel <ardb at kernel.org>.

Thanks,
Jens

Jens Wiklander (6):
  docs: staging/tee.rst: add a section on OP-TEE notifications
  dt-bindings: arm: optee: add interrupt property
  tee: fix put order in teedev_close_context()
  tee: add tee_dev_open_helper() primitive
  optee: separate notification functions
  optee: add asynchronous notifications

 .../arm/firmware/linaro,optee-tz.yaml         |   7 +
 Documentation/staging/tee.rst                 |  30 +++
 drivers/tee/optee/Makefile                    |   1 +
 drivers/tee/optee/call.c                      |  27 +++
 drivers/tee/optee/core.c                      |  87 +++++--
 drivers/tee/optee/notif.c                     | 226 ++++++++++++++++++
 drivers/tee/optee/optee_msg.h                 |   9 +
 drivers/tee/optee/optee_private.h             |  23 +-
 drivers/tee/optee/optee_rpc_cmd.h             |  31 +--
 drivers/tee/optee/optee_smc.h                 |  75 +++++-
 drivers/tee/optee/rpc.c                       |  73 +-----
 drivers/tee/tee_core.c                        |  37 ++-
 include/linux/tee_drv.h                       |  27 +++
 13 files changed, 529 insertions(+), 124 deletions(-)
 create mode 100644 drivers/tee/optee/notif.c

-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 26 05:30:27 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 26 Aug 2021 14:30:27 +0200
Subject: [PATCH v5 1/6] docs: staging/tee.rst: add a section on OP-TEE
 notifications
In-Reply-To: <20210826123032.1732926-1-jens.wiklander@linaro.org>
References: <20210826123032.1732926-1-jens.wiklander@linaro.org>
Message-ID: <20210826123032.1732926-2-jens.wiklander@linaro.org>

Adds a section on notifications used by OP-TEE, synchronous and
asynchronous.

Acked-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 Documentation/staging/tee.rst | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/Documentation/staging/tee.rst b/Documentation/staging/tee.rst
index 4d4b5f889603..3c63d8dcd61e 100644
--- a/Documentation/staging/tee.rst
+++ b/Documentation/staging/tee.rst
@@ -184,6 +184,36 @@ order to support device enumeration. In other words, OP-TEE driver invokes this
 application to retrieve a list of Trusted Applications which can be registered
 as devices on the TEE bus.
 
+OP-TEE notifications
+--------------------
+
+There are two kinds of notifications that secure world can use to make
+normal world aware of some event.
+
+1. Synchronous notifications delivered with ``OPTEE_RPC_CMD_NOTIFICATION``
+   using the ``OPTEE_RPC_NOTIFICATION_SEND`` parameter.
+2. Asynchronous notifications delivered with a combination of a non-secure
+   edge-triggered interrupt and a fast call from the non-secure interrupt
+   handler.
+
+Synchronous notifications are limited by depending on RPC for delivery,
+this is only usable when secure world is entered with a yielding call via
+``OPTEE_SMC_CALL_WITH_ARG``. This excludes such notifications from secure
+world interrupt handlers.
+
+An asynchronous notification is delivered via a non-secure edge-triggered
+interrupt to an interrupt handler registered in the OP-TEE driver. The
+actual notification value are retrieved with the fast call
+``OPTEE_SMC_GET_ASYNC_NOTIF_VALUE``. Note that one interrupt can represent
+multiple notifications.
+
+One notification value ``OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF`` has a
+special meaning. When this value is received it means that normal world is
+supposed to make a yielding call ``OPTEE_MSG_CMD_DO_BOTTOM_HALF``. This
+call is done from the thread assisting the interrupt handler. This is a
+building block for OP-TEE OS in secure world to implement the top half and
+bottom half style of device drivers.
+
 AMD-TEE driver
 ==============
 
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 26 05:30:28 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 26 Aug 2021 14:30:28 +0200
Subject: [PATCH v5 2/6] dt-bindings: arm: optee: add interrupt property
In-Reply-To: <20210826123032.1732926-1-jens.wiklander@linaro.org>
References: <20210826123032.1732926-1-jens.wiklander@linaro.org>
Message-ID: <20210826123032.1732926-3-jens.wiklander@linaro.org>

Adds an optional interrupt property to the optee binding.

Reviewed-by: Rob Herring <robh at kernel.org>
Acked-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 .../devicetree/bindings/arm/firmware/linaro,optee-tz.yaml  | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
index c24047c1fdd5..40c9f1901e3f 100644
--- a/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
+++ b/Documentation/devicetree/bindings/arm/firmware/linaro,optee-tz.yaml
@@ -24,6 +24,12 @@ properties:
   compatible:
     const: linaro,optee-tz
 
+  interrupts:
+    maxItems: 1
+    description: |
+      This interrupt which is used to signal an event by the secure world
+      software is expected to be edge-triggered.
+
   method:
     enum: [smc, hvc]
     description: |
@@ -46,6 +52,7 @@ examples:
         optee  {
             compatible = "linaro,optee-tz";
             method = "smc";
+            interrupts = <0 187 1>;
         };
     };
 
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 26 05:30:30 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 26 Aug 2021 14:30:30 +0200
Subject: [PATCH v5 4/6] tee: add tee_dev_open_helper() primitive
In-Reply-To: <20210826123032.1732926-1-jens.wiklander@linaro.org>
References: <20210826123032.1732926-1-jens.wiklander@linaro.org>
Message-ID: <20210826123032.1732926-5-jens.wiklander@linaro.org>

Adds tee_dev_open_helper() and tee_dev_ctx_put() to make it easier to
create a driver internal struct tee_context without the usual
tee_device_get() on the struct tee_device as that adds a circular
reference counter dependency and would prevent the struct tee_device
from ever being released again.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/tee_core.c  | 33 ++++++++++++++++++++++++---------
 include/linux/tee_drv.h | 27 +++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index 85102d12d716..3beb682684a8 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -43,14 +43,11 @@ static DEFINE_SPINLOCK(driver_lock);
 static struct class *tee_class;
 static dev_t tee_devt;
 
-static struct tee_context *teedev_open(struct tee_device *teedev)
+struct tee_context *tee_dev_open_helper(struct tee_device *teedev)
 {
 	int rc;
 	struct tee_context *ctx;
 
-	if (!tee_device_get(teedev))
-		return ERR_PTR(-EINVAL);
-
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx) {
 		rc = -ENOMEM;
@@ -66,10 +63,30 @@ static struct tee_context *teedev_open(struct tee_device *teedev)
 	return ctx;
 err:
 	kfree(ctx);
-	tee_device_put(teedev);
 	return ERR_PTR(rc);
 
 }
+EXPORT_SYMBOL_GPL(tee_dev_open_helper);
+
+void tee_dev_ctx_put(struct tee_context *ctx)
+{
+	teedev_ctx_put(ctx);
+}
+EXPORT_SYMBOL_GPL(tee_dev_ctx_put);
+
+static struct tee_context *teedev_open(struct tee_device *teedev)
+{
+	struct tee_context *ctx;
+
+	if (!tee_device_get(teedev))
+		return ERR_PTR(-EINVAL);
+
+	ctx = tee_dev_open_helper(teedev);
+	if (IS_ERR(ctx))
+		tee_device_put(teedev);
+
+	return ctx;
+}
 
 void teedev_ctx_get(struct tee_context *ctx)
 {
@@ -90,10 +107,8 @@ static void teedev_ctx_release(struct kref *ref)
 
 void teedev_ctx_put(struct tee_context *ctx)
 {
-	if (ctx->releasing)
-		return;
-
-	kref_put(&ctx->refcount, teedev_ctx_release);
+	if (ctx && !ctx->releasing)
+		kref_put(&ctx->refcount, teedev_ctx_release);
 }
 
 static void teedev_close_context(struct tee_context *ctx)
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index 3ebfea0781f1..00a31ff03049 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -458,6 +458,33 @@ static inline int tee_shm_get_id(struct tee_shm *shm)
  */
 struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
 
+/**
+ * tee_dev_open_helper() - helper function to make a struct tee_context
+ * @teedev:	Device to open
+ *
+ * Creates the struct tee_context without increasing the reference counter
+ * on @teedev. This is needed for instance when a driver need an internal
+ * struct tee_context to operate on. By skipping the reference counter
+ * the circular dependency is broken.
+ *
+ * Note that this struct tee_context need special care when freeing in
+ * order to avoid the normal put on the struct tee_device.
+ * tee_dev_ctx_put() is the best choice for this.
+ *
+ * @returns a pointer 'struct tee_context' on success or an ERR_PTR on failure
+ */
+struct tee_context *tee_dev_open_helper(struct tee_device *teedev);
+
+/**
+ * tee_dev_ctx_put() - helper function to release a struct tee_context
+ * @ctx:	The struct tee_context to release
+ *
+ * Note that this function doesn't do a tee_device_put() on the internal
+ * struct tee_device so this function should normal only be used when
+ * releasing a struct tee_context obtained with tee_dev_open_helper().
+ */
+void tee_dev_ctx_put(struct tee_context *ctx);
+
 /**
  * tee_client_open_context() - Open a TEE context
  * @start:	if not NULL, continue search after this context
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 26 05:30:29 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 26 Aug 2021 14:30:29 +0200
Subject: [PATCH v5 3/6] tee: fix put order in teedev_close_context()
In-Reply-To: <20210826123032.1732926-1-jens.wiklander@linaro.org>
References: <20210826123032.1732926-1-jens.wiklander@linaro.org>
Message-ID: <20210826123032.1732926-4-jens.wiklander@linaro.org>

Prior to this patch was teedev_close_context() calling tee_device_put()
before teedev_ctx_put() leading to teedev_ctx_release() accessing
ctx->teedev just after the reference counter was decreased on the
teedev. Fix this by calling teedev_ctx_put() before tee_device_put().

Fixes: 217e0250cccb ("tee: use reference counting for tee_context")
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/tee_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
index 2b37bc408fc3..85102d12d716 100644
--- a/drivers/tee/tee_core.c
+++ b/drivers/tee/tee_core.c
@@ -98,8 +98,10 @@ void teedev_ctx_put(struct tee_context *ctx)
 
 static void teedev_close_context(struct tee_context *ctx)
 {
-	tee_device_put(ctx->teedev);
+	struct tee_device *teedev = ctx->teedev;
+
 	teedev_ctx_put(ctx);
+	tee_device_put(teedev);
 }
 
 static int tee_open(struct inode *inode, struct file *filp)
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 26 05:30:31 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 26 Aug 2021 14:30:31 +0200
Subject: [PATCH v5 5/6] optee: separate notification functions
In-Reply-To: <20210826123032.1732926-1-jens.wiklander@linaro.org>
References: <20210826123032.1732926-1-jens.wiklander@linaro.org>
Message-ID: <20210826123032.1732926-6-jens.wiklander@linaro.org>

Renames struct optee_wait_queue to struct optee_notif and all related
functions to optee_notif_*().

The implementation is changed to allow sending a notification from an
atomic state, that is from the top half of an interrupt handler.

Waiting for keys is currently only used when secure world is waiting for
a mutex or condition variable. The old implementation could handle any
32-bit key while this new implementation is restricted to only 8 bits or
the maximum value 255. A upper value is needed since a bitmap is
allocated to allow an interrupt handler to only set a bit in case the
waiter hasn't had the time yet to allocate and register a completion.

The keys are currently only representing secure world threads which
number usually are never even close to 255 so it should be safe for now.
In future ABI updates the maximum value of the key will be communicated
while the driver is initializing.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/Makefile        |   1 +
 drivers/tee/optee/core.c          |  12 ++-
 drivers/tee/optee/notif.c         | 125 ++++++++++++++++++++++++++++++
 drivers/tee/optee/optee_private.h |  19 +++--
 drivers/tee/optee/optee_rpc_cmd.h |  31 ++++----
 drivers/tee/optee/rpc.c           |  73 ++---------------
 6 files changed, 170 insertions(+), 91 deletions(-)
 create mode 100644 drivers/tee/optee/notif.c

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 3aa33ea9e6a6..df55e4ad5370 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_OPTEE) += optee.o
 optee-objs += core.o
 optee-objs += call.o
+optee-objs += notif.o
 optee-objs += rpc.o
 optee-objs += supp.o
 optee-objs += shm_pool.o
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 5ce13b099d7d..8531184f98f4 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -592,6 +592,7 @@ static int optee_remove(struct platform_device *pdev)
 	 */
 	optee_disable_shm_cache(optee);
 
+	optee_notif_uninit(optee);
 	/*
 	 * The two devices have to be unregistered before we can free the
 	 * other resources.
@@ -602,7 +603,6 @@ static int optee_remove(struct platform_device *pdev)
 	tee_shm_pool_free(optee->pool);
 	if (optee->memremaped_shm)
 		memunmap(optee->memremaped_shm);
-	optee_wait_queue_exit(&optee->wait_queue);
 	optee_supp_uninit(&optee->supp);
 	mutex_destroy(&optee->call_queue.mutex);
 
@@ -712,11 +712,17 @@ static int optee_probe(struct platform_device *pdev)
 
 	mutex_init(&optee->call_queue.mutex);
 	INIT_LIST_HEAD(&optee->call_queue.waiters);
-	optee_wait_queue_init(&optee->wait_queue);
 	optee_supp_init(&optee->supp);
 	optee->memremaped_shm = memremaped_shm;
 	optee->pool = pool;
 
+	platform_set_drvdata(pdev, optee);
+	rc = optee_notif_init(optee, 255);
+	if (rc) {
+		optee_remove(pdev);
+		return rc;
+	}
+
 	/*
 	 * Ensure that there are no pre-existing shm objects before enabling
 	 * the shm cache so that there's no chance of receiving an invalid
@@ -731,8 +737,6 @@ static int optee_probe(struct platform_device *pdev)
 	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
 		pr_info("dynamic shared memory is enabled\n");
 
-	platform_set_drvdata(pdev, optee);
-
 	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
 	if (rc) {
 		optee_remove(pdev);
diff --git a/drivers/tee/optee/notif.c b/drivers/tee/optee/notif.c
new file mode 100644
index 000000000000..a28fa03dcd0e
--- /dev/null
+++ b/drivers/tee/optee/notif.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015-2021, Linaro Limited
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/arm-smccc.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/tee_drv.h>
+#include "optee_private.h"
+
+struct notif_entry {
+	struct list_head link;
+	struct completion c;
+	u_int key;
+};
+
+static bool have_key(struct optee *optee, u_int key)
+{
+	struct notif_entry *entry;
+
+	list_for_each_entry(entry, &optee->notif.db, link)
+		if (entry->key == key)
+			return true;
+
+	return false;
+}
+
+int optee_notif_wait(struct optee *optee, u_int key)
+{
+	unsigned long flags;
+	struct notif_entry *entry;
+	int rc = 0;
+
+	if (key > optee->notif.max_key)
+		return -EINVAL;
+
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+	init_completion(&entry->c);
+	entry->key = key;
+
+	spin_lock_irqsave(&optee->notif.lock, flags);
+
+	/*
+	 * If the bit is already set it means that the key has already
+	 * been posted and we must not wait.
+	 */
+	if (test_bit(key, optee->notif.bitmap)) {
+		clear_bit(key, optee->notif.bitmap);
+		goto out;
+	}
+
+	/*
+	 * Check if someone is already waiting for this key. If there is
+	 * it's a programming error.
+	 */
+	if (have_key(optee, key)) {
+		rc = -EBUSY;
+		goto out;
+	}
+
+	list_add_tail(&entry->link, &optee->notif.db);
+
+	/*
+	 * Unlock temporarily and wait for completion.
+	 */
+	spin_unlock_irqrestore(&optee->notif.lock, flags);
+	wait_for_completion(&entry->c);
+	spin_lock_irqsave(&optee->notif.lock, flags);
+
+	list_del(&entry->link);
+out:
+	spin_unlock_irqrestore(&optee->notif.lock, flags);
+
+	kfree(entry);
+
+	return rc;
+}
+
+int optee_notif_send(struct optee *optee, u_int key)
+{
+	unsigned long flags;
+	struct notif_entry *entry;
+
+	if (key > optee->notif.max_key)
+		return -EINVAL;
+
+	spin_lock_irqsave(&optee->notif.lock, flags);
+
+	list_for_each_entry(entry, &optee->notif.db, link)
+		if (entry->key == key) {
+			complete(&entry->c);
+			goto out;
+		}
+
+	/* Only set the bit in case there where nobody waiting */
+	set_bit(key, optee->notif.bitmap);
+out:
+	spin_unlock_irqrestore(&optee->notif.lock, flags);
+
+	return 0;
+}
+
+int optee_notif_init(struct optee *optee, u_int max_key)
+{
+	spin_lock_init(&optee->notif.lock);
+	INIT_LIST_HEAD(&optee->notif.db);
+	optee->notif.bitmap = bitmap_zalloc(max_key, GFP_KERNEL);
+	if (!optee->notif.bitmap)
+		return -ENOMEM;
+
+	optee->notif.max_key = max_key;
+
+	return 0;
+}
+
+void optee_notif_uninit(struct optee *optee)
+{
+	kfree(optee->notif.bitmap);
+}
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index dbdd367be156..76a16d9b6cf4 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -35,10 +35,12 @@ struct optee_call_queue {
 	struct list_head waiters;
 };
 
-struct optee_wait_queue {
-	/* Serializes access to this struct */
-	struct mutex mu;
+struct optee_notif {
+	u_int max_key;
+	/* Serializes access to the elements below in this struct */
+	spinlock_t lock;
 	struct list_head db;
+	u_long *bitmap;
 };
 
 /**
@@ -72,8 +74,7 @@ struct optee_supp {
  * @teedev:		client device
  * @invoke_fn:		function to issue smc or hvc
  * @call_queue:		queue of threads waiting to call @invoke_fn
- * @wait_queue:		queue of threads from secure world waiting for a
- *			secure world sync object
+ * @notif:		notification synchronization struct
  * @supp:		supplicant synchronization struct for RPC to supplicant
  * @pool:		shared memory pool
  * @memremaped_shm	virtual address of memory in shared memory pool
@@ -88,7 +89,7 @@ struct optee {
 	struct tee_device *teedev;
 	optee_invoke_fn *invoke_fn;
 	struct optee_call_queue call_queue;
-	struct optee_wait_queue wait_queue;
+	struct optee_notif notif;
 	struct optee_supp supp;
 	struct tee_shm_pool *pool;
 	void *memremaped_shm;
@@ -131,8 +132,10 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
 		      struct optee_call_ctx *call_ctx);
 void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx);
 
-void optee_wait_queue_init(struct optee_wait_queue *wq);
-void optee_wait_queue_exit(struct optee_wait_queue *wq);
+int optee_notif_init(struct optee *optee, u_int max_key);
+void optee_notif_uninit(struct optee *optee);
+int optee_notif_wait(struct optee *optee, u_int key);
+int optee_notif_send(struct optee *optee, u_int key);
 
 u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
 			struct tee_param *param);
diff --git a/drivers/tee/optee/optee_rpc_cmd.h b/drivers/tee/optee/optee_rpc_cmd.h
index b8275140cef8..f3f06e0994a7 100644
--- a/drivers/tee/optee/optee_rpc_cmd.h
+++ b/drivers/tee/optee/optee_rpc_cmd.h
@@ -28,24 +28,27 @@
 #define OPTEE_RPC_CMD_GET_TIME		3
 
 /*
- * Wait queue primitive, helper for secure world to implement a wait queue.
+ * Notification from/to secure world.
  *
- * If secure world needs to wait for a secure world mutex it issues a sleep
- * request instead of spinning in secure world. Conversely is a wakeup
- * request issued when a secure world mutex with a thread waiting thread is
- * unlocked.
+ * If secure world needs to wait for something, for instance a mutex, it
+ * does a notification wait request instead of spinning in secure world.
+ * Conversely can a synchronous notification can be sent when a secure
+ * world mutex with a thread waiting thread is unlocked.
  *
- * Waiting on a key
- * [in]    value[0].a	    OPTEE_RPC_WAIT_QUEUE_SLEEP
- * [in]    value[0].b	    Wait key
+ * This interface can also be used to wait for a asynchronous notification
+ * which instead is sent via a non-secure interrupt.
  *
- * Waking up a key
- * [in]    value[0].a	    OPTEE_RPC_WAIT_QUEUE_WAKEUP
- * [in]    value[0].b	    Wakeup key
+ * Waiting on notification
+ * [in]    value[0].a	    OPTEE_RPC_NOTIFICATION_WAIT
+ * [in]    value[0].b	    notification value
+ *
+ * Sending a synchronous notification
+ * [in]    value[0].a	    OPTEE_RPC_NOTIFICATION_SEND
+ * [in]    value[0].b	    notification value
  */
-#define OPTEE_RPC_CMD_WAIT_QUEUE	4
-#define OPTEE_RPC_WAIT_QUEUE_SLEEP	0
-#define OPTEE_RPC_WAIT_QUEUE_WAKEUP	1
+#define OPTEE_RPC_CMD_NOTIFICATION	4
+#define OPTEE_RPC_NOTIFICATION_WAIT	0
+#define OPTEE_RPC_NOTIFICATION_SEND	1
 
 /*
  * Suspend execution
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index efbaff7ad7e5..fa492655843a 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2016, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -14,23 +14,6 @@
 #include "optee_smc.h"
 #include "optee_rpc_cmd.h"
 
-struct wq_entry {
-	struct list_head link;
-	struct completion c;
-	u32 key;
-};
-
-void optee_wait_queue_init(struct optee_wait_queue *priv)
-{
-	mutex_init(&priv->mu);
-	INIT_LIST_HEAD(&priv->db);
-}
-
-void optee_wait_queue_exit(struct optee_wait_queue *priv)
-{
-	mutex_destroy(&priv->mu);
-}
-
 static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
 {
 	struct timespec64 ts;
@@ -143,48 +126,6 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 }
 #endif
 
-static struct wq_entry *wq_entry_get(struct optee_wait_queue *wq, u32 key)
-{
-	struct wq_entry *w;
-
-	mutex_lock(&wq->mu);
-
-	list_for_each_entry(w, &wq->db, link)
-		if (w->key == key)
-			goto out;
-
-	w = kmalloc(sizeof(*w), GFP_KERNEL);
-	if (w) {
-		init_completion(&w->c);
-		w->key = key;
-		list_add_tail(&w->link, &wq->db);
-	}
-out:
-	mutex_unlock(&wq->mu);
-	return w;
-}
-
-static void wq_sleep(struct optee_wait_queue *wq, u32 key)
-{
-	struct wq_entry *w = wq_entry_get(wq, key);
-
-	if (w) {
-		wait_for_completion(&w->c);
-		mutex_lock(&wq->mu);
-		list_del(&w->link);
-		mutex_unlock(&wq->mu);
-		kfree(w);
-	}
-}
-
-static void wq_wakeup(struct optee_wait_queue *wq, u32 key)
-{
-	struct wq_entry *w = wq_entry_get(wq, key);
-
-	if (w)
-		complete(&w->c);
-}
-
 static void handle_rpc_func_cmd_wq(struct optee *optee,
 				   struct optee_msg_arg *arg)
 {
@@ -196,11 +137,13 @@ static void handle_rpc_func_cmd_wq(struct optee *optee,
 		goto bad;
 
 	switch (arg->params[0].u.value.a) {
-	case OPTEE_RPC_WAIT_QUEUE_SLEEP:
-		wq_sleep(&optee->wait_queue, arg->params[0].u.value.b);
+	case OPTEE_RPC_NOTIFICATION_WAIT:
+		if (optee_notif_wait(optee, arg->params[0].u.value.b))
+			goto bad;
 		break;
-	case OPTEE_RPC_WAIT_QUEUE_WAKEUP:
-		wq_wakeup(&optee->wait_queue, arg->params[0].u.value.b);
+	case OPTEE_RPC_NOTIFICATION_SEND:
+		if (optee_notif_send(optee, arg->params[0].u.value.b))
+			goto bad;
 		break;
 	default:
 		goto bad;
@@ -463,7 +406,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
 	case OPTEE_RPC_CMD_GET_TIME:
 		handle_rpc_func_cmd_get_time(arg);
 		break;
-	case OPTEE_RPC_CMD_WAIT_QUEUE:
+	case OPTEE_RPC_CMD_NOTIFICATION:
 		handle_rpc_func_cmd_wq(optee, arg);
 		break;
 	case OPTEE_RPC_CMD_SUSPEND:
-- 
2.31.1



From jens.wiklander at linaro.org  Thu Aug 26 05:30:32 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 26 Aug 2021 14:30:32 +0200
Subject: [PATCH v5 6/6] optee: add asynchronous notifications
In-Reply-To: <20210826123032.1732926-1-jens.wiklander@linaro.org>
References: <20210826123032.1732926-1-jens.wiklander@linaro.org>
Message-ID: <20210826123032.1732926-7-jens.wiklander@linaro.org>

Adds support for asynchronous notifications from secure world to normal
world. This allows a design with a top half and bottom half type of
driver where the top half runs in secure interrupt context and a
notifications tells normal world to schedule a yielding call to do the
bottom half processing.

The protocol is defined in optee_msg.h optee_rpc_cmd.h and optee_smc.h.

A notification consists of a 32-bit value which normal world can
retrieve using a fastcall into secure world. The value
OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF (0) has a special meaning.
When this value is sent it means that normal world is supposed to make a
yielding call OPTEE_MSG_CMD_DO_BOTTOM_HALF.

Notification capability is negotiated while the driver is initialized.
If both sides supports these notifications then they are enabled.

An interrupt is used to notify the driver that there are asynchronous
notifications pending.  The maximum needed notification value is
communicated at this stage. This allows scaling up when needed.

Acked-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/call.c          |  27 ++++++++
 drivers/tee/optee/core.c          |  83 ++++++++++++++++-------
 drivers/tee/optee/notif.c         | 109 ++++++++++++++++++++++++++++--
 drivers/tee/optee/optee_msg.h     |   9 +++
 drivers/tee/optee/optee_private.h |   6 +-
 drivers/tee/optee/optee_smc.h     |  75 +++++++++++++++++++-
 6 files changed, 277 insertions(+), 32 deletions(-)

diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 945f03da0223..e428e0e9a3af 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -392,6 +392,33 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 	return 0;
 }
 
+static int simple_call_with_arg(struct tee_context *ctx, u32 cmd)
+{
+	struct optee_msg_arg *msg_arg;
+	phys_addr_t msg_parg;
+	struct tee_shm *shm;
+
+	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+
+	msg_arg->cmd = cmd;
+	optee_do_call_with_arg(ctx, msg_parg);
+
+	tee_shm_free(shm);
+	return 0;
+}
+
+int optee_do_bottom_half(struct tee_context *ctx)
+{
+	return simple_call_with_arg(ctx, OPTEE_MSG_CMD_DO_BOTTOM_HALF);
+}
+
+int optee_stop_async_notif(struct tee_context *ctx)
+{
+	return simple_call_with_arg(ctx, OPTEE_MSG_CMD_STOP_ASYNC_NOTIF);
+}
+
 /**
  * optee_enable_shm_cache() - Enables caching of some shared memory allocation
  *			      in OP-TEE
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 8531184f98f4..ccafd7151b45 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -8,9 +8,12 @@
 #include <linux/arm-smccc.h>
 #include <linux/crash_dump.h>
 #include <linux/errno.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -355,6 +358,17 @@ static const struct tee_desc optee_supp_desc = {
 	.flags = TEE_DESC_PRIVILEGED,
 };
 
+static int enable_async_notif(optee_invoke_fn *invoke_fn)
+{
+	struct arm_smccc_res res;
+
+	invoke_fn(OPTEE_SMC_ENABLE_ASYNC_NOTIF, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0)
+		return -EINVAL;
+	return 0;
+}
+
 static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
 {
 	struct arm_smccc_res res;
@@ -404,7 +418,7 @@ static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
 }
 
 static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
-					    u32 *sec_caps)
+					    u32 *sec_caps, u32 *max_notif_value)
 {
 	union {
 		struct arm_smccc_res smccc;
@@ -427,6 +441,7 @@ static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
 		return false;
 
 	*sec_caps = res.result.capabilities;
+	*max_notif_value = res.result.max_notif_value;
 	return true;
 }
 
@@ -630,6 +645,7 @@ static int optee_probe(struct platform_device *pdev)
 	struct optee *optee = NULL;
 	void *memremaped_shm = NULL;
 	struct tee_device *teedev;
+	u32 max_notif_value;
 	u32 sec_caps;
 	int rc;
 
@@ -659,7 +675,8 @@ static int optee_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
+	if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps,
+					     &max_notif_value)) {
 		pr_warn("capabilities mismatch\n");
 		return -EINVAL;
 	}
@@ -682,7 +699,7 @@ static int optee_probe(struct platform_device *pdev)
 	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
 	if (!optee) {
 		rc = -ENOMEM;
-		goto err;
+		goto err_free_pool;
 	}
 
 	optee->invoke_fn = invoke_fn;
@@ -691,24 +708,24 @@ static int optee_probe(struct platform_device *pdev)
 	teedev = tee_device_alloc(&optee_desc, NULL, pool, optee);
 	if (IS_ERR(teedev)) {
 		rc = PTR_ERR(teedev);
-		goto err;
+		goto err_free_optee;
 	}
 	optee->teedev = teedev;
 
 	teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee);
 	if (IS_ERR(teedev)) {
 		rc = PTR_ERR(teedev);
-		goto err;
+		goto err_unreg_teedev;
 	}
 	optee->supp_teedev = teedev;
 
 	rc = tee_device_register(optee->teedev);
 	if (rc)
-		goto err;
+		goto err_unreg_supp_teedev;
 
 	rc = tee_device_register(optee->supp_teedev);
 	if (rc)
-		goto err;
+		goto err_unreg_supp_teedev;
 
 	mutex_init(&optee->call_queue.mutex);
 	INIT_LIST_HEAD(&optee->call_queue.waiters);
@@ -717,10 +734,31 @@ static int optee_probe(struct platform_device *pdev)
 	optee->pool = pool;
 
 	platform_set_drvdata(pdev, optee);
-	rc = optee_notif_init(optee, 255);
-	if (rc) {
-		optee_remove(pdev);
-		return rc;
+
+	if (sec_caps & OPTEE_SMC_SEC_CAP_ASYNC_NOTIF) {
+		unsigned int irq;
+
+		rc = platform_get_irq(pdev, 0);
+		if (rc < 0) {
+			pr_err("platform_get_irq: ret %d\n", rc);
+			goto err_unreg_supp_teedev;
+		}
+		irq = rc;
+
+		rc = optee_notif_init(optee, max_notif_value, irq);
+		if (rc) {
+			irq_dispose_mapping(irq);
+			optee_remove(pdev);
+			return rc;
+		}
+		enable_async_notif(optee->invoke_fn);
+		pr_info("Asynchronous notifications enabled\n");
+	} else {
+		rc = optee_notif_init(optee, 255, 0);
+		if (rc) {
+			optee_remove(pdev);
+			return rc;
+		}
 	}
 
 	/*
@@ -745,20 +783,15 @@ static int optee_probe(struct platform_device *pdev)
 
 	pr_info("initialized driver\n");
 	return 0;
-err:
-	if (optee) {
-		/*
-		 * tee_device_unregister() is safe to call even if the
-		 * devices hasn't been registered with
-		 * tee_device_register() yet.
-		 */
-		tee_device_unregister(optee->supp_teedev);
-		tee_device_unregister(optee->teedev);
-		kfree(optee);
-	}
-	if (pool)
-		tee_shm_pool_free(pool);
-	if (memremaped_shm)
+err_unreg_supp_teedev:
+	tee_device_unregister(optee->supp_teedev);
+err_unreg_teedev:
+	tee_device_unregister(optee->teedev);
+err_free_optee:
+	kfree(optee);
+err_free_pool:
+	tee_shm_pool_free(pool);
+	if (optee->memremaped_shm)
 		memunmap(memremaped_shm);
 	return rc;
 }
diff --git a/drivers/tee/optee/notif.c b/drivers/tee/optee/notif.c
index a28fa03dcd0e..ecfa82797695 100644
--- a/drivers/tee/optee/notif.c
+++ b/drivers/tee/optee/notif.c
@@ -7,10 +7,14 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/tee_drv.h>
 #include "optee_private.h"
+#include "optee_smc.h"
+#include "optee_rpc_cmd.h"
 
 struct notif_entry {
 	struct list_head link;
@@ -18,6 +22,54 @@ struct notif_entry {
 	u_int key;
 };
 
+static u32 get_async_notif_value(optee_invoke_fn *invoke_fn, bool *value_valid,
+				 bool *value_pending)
+{
+	struct arm_smccc_res res;
+
+	invoke_fn(OPTEE_SMC_GET_ASYNC_NOTIF_VALUE, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0)
+		return 0;
+	*value_valid = (res.a2 & OPTEE_SMC_ASYNC_NOTIF_VALUE_VALID);
+	*value_pending = (res.a2 & OPTEE_SMC_ASYNC_NOTIF_VALUE_PENDING);
+	return res.a1;
+}
+
+static irqreturn_t notif_irq_handler(int irq, void *dev_id)
+{
+	struct optee *optee = dev_id;
+	bool do_bottom_half = false;
+	bool value_valid;
+	bool value_pending;
+	u32 value;
+
+	do {
+		value = get_async_notif_value(optee->invoke_fn, &value_valid,
+					      &value_pending);
+		if (!value_valid)
+			break;
+
+		if (value == OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF)
+			do_bottom_half = true;
+		else
+			optee_notif_send(optee, value);
+	} while (value_pending);
+
+	if (do_bottom_half)
+		return IRQ_WAKE_THREAD;
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t notif_irq_thread_fn(int irq, void *dev_id)
+{
+	struct optee *optee = dev_id;
+
+	optee_do_bottom_half(optee->notif.ctx);
+
+	return IRQ_HANDLED;
+}
+
 static bool have_key(struct optee *optee, u_int key)
 {
 	struct notif_entry *entry;
@@ -106,20 +158,69 @@ int optee_notif_send(struct optee *optee, u_int key)
 	return 0;
 }
 
-int optee_notif_init(struct optee *optee, u_int max_key)
+int optee_notif_init(struct optee *optee, u_int max_key, u_int irq)
 {
+	struct tee_context *ctx;
+	int rc;
+
+	if (irq) {
+		ctx = tee_dev_open_helper(optee->teedev);
+		if (IS_ERR(ctx))
+			return PTR_ERR(ctx);
+
+		optee->notif.ctx = ctx;
+	}
+
 	spin_lock_init(&optee->notif.lock);
 	INIT_LIST_HEAD(&optee->notif.db);
 	optee->notif.bitmap = bitmap_zalloc(max_key, GFP_KERNEL);
-	if (!optee->notif.bitmap)
-		return -ENOMEM;
-
+	if (!optee->notif.bitmap) {
+		rc = -ENOMEM;
+		goto err_put_ctx;
+	}
 	optee->notif.max_key = max_key;
 
+	if (irq) {
+		rc = request_threaded_irq(irq, notif_irq_handler,
+					  notif_irq_thread_fn,
+					  0, "optee_notification", optee);
+		if (rc)
+			goto err_free_bitmap;
+
+		optee->notif.irq = irq;
+	}
+
 	return 0;
+
+err_free_bitmap:
+	kfree(optee->notif.bitmap);
+err_put_ctx:
+	tee_dev_ctx_put(optee->notif.ctx);
+	optee->notif.ctx = NULL;
+
+	return rc;
 }
 
 void optee_notif_uninit(struct optee *optee)
 {
+	if (optee->notif.ctx) {
+		optee_stop_async_notif(optee->notif.ctx);
+		if (optee->notif.irq) {
+			free_irq(optee->notif.irq, optee);
+			irq_dispose_mapping(optee->notif.irq);
+		}
+
+		/*
+		 * The thread normally working with optee->notif.ctx was
+		 * stopped with free_irq() above.
+		 *
+		 * Note we're not using teedev_close_context() or
+		 * tee_client_close_context() since we have already called
+		 * tee_device_put() while initializing to avoid a circular
+		 * reference counting.
+		 */
+		tee_dev_ctx_put(optee->notif.ctx);
+	}
+
 	kfree(optee->notif.bitmap);
 }
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index e3d72d09c484..3e09c8386e46 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -293,6 +293,13 @@ struct optee_msg_arg {
  * [in] param[0].u.rmem.shm_ref		holds shared memory reference
  * [in] param[0].u.rmem.offs		0
  * [in] param[0].u.rmem.size		0
+ *
+ * OPTEE_MSG_CMD_DO_BOTTOM_HALF does the scheduled bottom half processing
+ * of a driver.
+ *
+ * OPTEE_MSG_CMD_STOP_ASYNC_NOTIF informs secure world that from now is
+ * normal world unable to process asynchronous notifications. Typically
+ * used when the driver is shut down.
  */
 #define OPTEE_MSG_CMD_OPEN_SESSION	0
 #define OPTEE_MSG_CMD_INVOKE_COMMAND	1
@@ -300,6 +307,8 @@ struct optee_msg_arg {
 #define OPTEE_MSG_CMD_CANCEL		3
 #define OPTEE_MSG_CMD_REGISTER_SHM	4
 #define OPTEE_MSG_CMD_UNREGISTER_SHM	5
+#define OPTEE_MSG_CMD_DO_BOTTOM_HALF	6
+#define OPTEE_MSG_CMD_STOP_ASYNC_NOTIF	7
 #define OPTEE_MSG_FUNCID_CALL_WITH_ARG	0x0004
 
 #endif /* _OPTEE_MSG_H */
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 76a16d9b6cf4..f62a16935c49 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -37,6 +37,8 @@ struct optee_call_queue {
 
 struct optee_notif {
 	u_int max_key;
+	unsigned int irq;
+	struct tee_context *ctx;
 	/* Serializes access to the elements below in this struct */
 	spinlock_t lock;
 	struct list_head db;
@@ -132,7 +134,7 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
 		      struct optee_call_ctx *call_ctx);
 void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx);
 
-int optee_notif_init(struct optee *optee, u_int max_key);
+int optee_notif_init(struct optee *optee, u_int max_key, u_int irq);
 void optee_notif_uninit(struct optee *optee);
 int optee_notif_wait(struct optee *optee, u_int key);
 int optee_notif_send(struct optee *optee, u_int key);
@@ -159,6 +161,8 @@ int optee_close_session(struct tee_context *ctx, u32 session);
 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 		      struct tee_param *param);
 int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
+int optee_do_bottom_half(struct tee_context *ctx);
+int optee_stop_async_notif(struct tee_context *ctx);
 
 void optee_enable_shm_cache(struct optee *optee);
 void optee_disable_shm_cache(struct optee *optee);
diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h
index 80eb763a8a80..c6eec6b6febf 100644
--- a/drivers/tee/optee/optee_smc.h
+++ b/drivers/tee/optee/optee_smc.h
@@ -107,6 +107,12 @@ struct optee_smc_call_get_os_revision_result {
 /*
  * Call with struct optee_msg_arg as argument
  *
+ * When calling this function normal world has a few responsibilities:
+ * 1. It must be able to handle eventual RPCs
+ * 2. Non-secure interrupts should not be masked
+ * 3. If asynchronous notifications has be negotiated successfully, then
+ *    asynchronous notifications should be unmasked during this call.
+ *
  * Call register usage:
  * a0	SMC Function ID, OPTEE_SMC*CALL_WITH_ARG
  * a1	Upper 32 bits of a 64-bit physical pointer to a struct optee_msg_arg
@@ -195,7 +201,8 @@ struct optee_smc_get_shm_config_result {
  * Normal return register usage:
  * a0	OPTEE_SMC_RETURN_OK
  * a1	bitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*
- * a2-7	Preserved
+ * a2	The maximum secure world notification number
+ * a3-7	Preserved
  *
  * Error return register usage:
  * a0	OPTEE_SMC_RETURN_ENOTAVAIL, can't use the capabilities from normal world
@@ -218,6 +225,8 @@ struct optee_smc_get_shm_config_result {
 #define OPTEE_SMC_SEC_CAP_VIRTUALIZATION	BIT(3)
 /* Secure world supports Shared Memory with a NULL reference */
 #define OPTEE_SMC_SEC_CAP_MEMREF_NULL		BIT(4)
+/* Secure world supports asynchronous notification of normal world */
+#define OPTEE_SMC_SEC_CAP_ASYNC_NOTIF		BIT(5)
 
 #define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES	9
 #define OPTEE_SMC_EXCHANGE_CAPABILITIES \
@@ -226,8 +235,8 @@ struct optee_smc_get_shm_config_result {
 struct optee_smc_exchange_capabilities_result {
 	unsigned long status;
 	unsigned long capabilities;
+	unsigned long max_notif_value;
 	unsigned long reserved0;
-	unsigned long reserved1;
 };
 
 /*
@@ -319,6 +328,68 @@ struct optee_smc_disable_shm_cache_result {
 #define OPTEE_SMC_GET_THREAD_COUNT \
 	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_THREAD_COUNT)
 
+/*
+ * Inform OP-TEE that normal world is able to receive asynchronous
+ * notifications.
+ *
+ * Call requests usage:
+ * a0	SMC Function ID, OPTEE_SMC_ENABLE_ASYNC_NOTIF
+ * a1-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Normal return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1-7	Preserved
+ *
+ * Not supported return register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL
+ * a1-7	Preserved
+ */
+#define OPTEE_SMC_FUNCID_ENABLE_ASYNC_NOTIF	16
+#define OPTEE_SMC_ENABLE_ASYNC_NOTIF \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_ASYNC_NOTIF)
+
+/*
+ * Retrieve a value of notifications pended since the last call of this
+ * function.
+ *
+ * OP-TEE keeps a records of all posted values. When an interrupts is
+ * received which indicates that there are posed values this function
+ * should be called until all pended values has been retrieved. When a
+ * value is retrieved it's cleared from the record in secure world.
+ *
+ * Call requests usage:
+ * a0	SMC Function ID, OPTEE_SMC_GET_ASYNC_NOTIF_VALUE
+ * a1-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Normal return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1	value
+ * a2	Bit[0]: OPTEE_SMC_ASYNC_NOTIF_VALUE_VALID if the value in a1 is
+ *		valid, else 0 if no values where pending
+ * a2	Bit[1]: OPTEE_SMC_ASYNC_NOTIF_VALUE_PENDING if another value is
+ *		pending, else 0.
+ *	Bit[31:2]: MBZ
+ * a3-7	Preserved
+ *
+ * Not supported return register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL
+ * a1-7	Preserved
+ */
+#define OPTEE_SMC_ASYNC_NOTIF_VALUE_VALID	BIT(0)
+#define OPTEE_SMC_ASYNC_NOTIF_VALUE_PENDING	BIT(1)
+
+/*
+ * Notification that OP-TEE expects a yielding call to do some bottom half
+ * work in a driver.
+ */
+#define OPTEE_SMC_ASYNC_NOTIF_VALUE_DO_BOTTOM_HALF	0
+
+#define OPTEE_SMC_FUNCID_GET_ASYNC_NOTIF_VALUE	17
+#define OPTEE_SMC_GET_ASYNC_NOTIF_VALUE \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_ASYNC_NOTIF_VALUE)
+
 /*
  * Resume from RPC (for example after processing a foreign interrupt)
  *
-- 
2.31.1



From colin.king at canonical.com  Thu Aug 26 05:35:16 2021
From: colin.king at canonical.com (Colin King)
Date: Thu, 26 Aug 2021 13:35:16 +0100
Subject: [PATCH] pinctrl: Fix spelling mistake "atleast" -> "at least"
Message-ID: <20210826123516.14441-1-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

There is a spelling mistake in a dev_err message. Fix it.

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 drivers/pinctrl/pinctrl-st.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
index fa3edb4b898a..1482a01dfec7 100644
--- a/drivers/pinctrl/pinctrl-st.c
+++ b/drivers/pinctrl/pinctrl-st.c
@@ -1588,7 +1588,7 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
 
 	st_pctl_dt_child_count(info, np);
 	if (!info->nbanks) {
-		dev_err(&pdev->dev, "you need atleast one gpio bank\n");
+		dev_err(&pdev->dev, "you need at least one gpio bank\n");
 		return -EINVAL;
 	}
 
-- 
2.32.0



From michael at walle.cc  Thu Aug 26 05:35:29 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 26 Aug 2021 14:35:29 +0200
Subject: [PATCH 2/2] arm64: dts: hisilicon: fix arm,sp805 compatible string
In-Reply-To: <20210826123529.737398-1-michael@walle.cc>
References: <20210826123529.737398-1-michael@walle.cc>
Message-ID: <20210826123529.737398-2-michael@walle.cc>

According to Documentation/devicetree/bindings/watchdog/arm,sp805.yaml
the compatible is:
  compatible = "arm,sp805", "arm,primecell";

The current compatible string doesn't exist at all. Fix it.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 4 ++--
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index 2d5c1a348716..6eabec2602e2 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -1087,7 +1087,7 @@ dwmmc2: dwmmc2 at ff3ff000 {
 		};
 
 		watchdog0: watchdog at e8a06000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xe8a06000 0x0 0x1000>;
 			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&crg_ctrl HI3660_OSC32K>,
@@ -1096,7 +1096,7 @@ watchdog0: watchdog at e8a06000 {
 		};
 
 		watchdog1: watchdog at e8a07000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xe8a07000 0x0 0x1000>;
 			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&crg_ctrl HI3660_OSC32K>,
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index dde9371dc545..e4860b8a638e 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -840,7 +840,7 @@ dwmmc_2: dwmmc2 at f723f000 {
 		};
 
 		watchdog0: watchdog at f8005000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xf8005000 0x0 0x1000>;
 			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&ao_ctrl HI6220_WDT0_PCLK>,
-- 
2.30.2



From michael at walle.cc  Thu Aug 26 05:35:28 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 26 Aug 2021 14:35:28 +0200
Subject: [PATCH 1/2] arm64: dts: freescale: fix arm,sp805 compatible string
Message-ID: <20210826123529.737398-1-michael@walle.cc>

According to Documentation/devicetree/bindings/watchdog/arm,sp805.yaml
the compatible is:
  compatible = "arm,sp805", "arm,primecell";

The current compatible string doesn't exist at all. Fix it.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 16 ++++++++--------
 arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 16 ++++++++--------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index f85e437f80b7..605072317243 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -847,7 +847,7 @@ pcs7_3: ethernet-phy at 3 {
 		};
 
 		cluster1_core0_watchdog: wdt at c000000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc000000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -857,7 +857,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster1_core1_watchdog: wdt at c010000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc010000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -867,7 +867,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster1_core2_watchdog: wdt at c020000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc020000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -877,7 +877,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster1_core3_watchdog: wdt at c030000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc030000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -887,7 +887,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster2_core0_watchdog: wdt at c100000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc100000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -897,7 +897,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster2_core1_watchdog: wdt at c110000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc110000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -907,7 +907,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster2_core2_watchdog: wdt at c120000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc120000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -917,7 +917,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster2_core3_watchdog: wdt at c130000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc130000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
index 801ba9612d36..1282b61da8a5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
@@ -387,7 +387,7 @@ serial3: serial at 21d0600 {
 		};
 
 		cluster1_core0_watchdog: wdt at c000000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc000000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -397,7 +397,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster1_core1_watchdog: wdt at c010000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc010000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -407,7 +407,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster2_core0_watchdog: wdt at c100000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc100000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -417,7 +417,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster2_core1_watchdog: wdt at c110000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc110000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -427,7 +427,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster3_core0_watchdog: wdt at c200000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc200000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -437,7 +437,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster3_core1_watchdog: wdt at c210000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc210000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -447,7 +447,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster4_core0_watchdog: wdt at c300000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc300000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -457,7 +457,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster4_core1_watchdog: wdt at c310000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc310000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
-- 
2.30.2



From yifeng.zhao at rock-chips.com  Thu Aug 26 05:38:41 2021
From: yifeng.zhao at rock-chips.com (Yifeng Zhao)
Date: Thu, 26 Aug 2021 20:38:41 +0800
Subject: [PATCH v1 0/3] 
Message-ID: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>

Add Naneng combo PHY support for RK3568

This phy can be used as pcie-phy, usb3-phy, sata-phy or sgmii-phy.



Yifeng Zhao (3):
  dt-bindings: phy: rockchip: Add Naneng combo PHY bindings
  phy/rockchip: add naneng combo phy for RK3568
  arm64: dts: rockchip: add naneng combo phy nodes for rk3568

 .../phy/phy-rockchip-naneng-combphy.yaml      | 100 +++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |  68 ++
 drivers/phy/rockchip/Kconfig                  |   8 +
 drivers/phy/rockchip/Makefile                 |   1 +
 .../rockchip/phy-rockchip-naneng-combphy.c    | 646 ++++++++++++++++++
 5 files changed, 823 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
 create mode 100644 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c

-- 
2.17.1





From yifeng.zhao at rock-chips.com  Thu Aug 26 05:38:44 2021
From: yifeng.zhao at rock-chips.com (Yifeng Zhao)
Date: Thu, 26 Aug 2021 20:38:44 +0800
Subject: [PATCH v1 3/3] arm64: dts: rockchip: add naneng combo phy nodes for
 rk3568
In-Reply-To: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
References: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
Message-ID: <20210826123844.8464-4-yifeng.zhao@rock-chips.com>

Add the core dt-node for the rk3568's naneng combo phys.

Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
---

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

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index d89831bee1eb..b421e3d52412 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -214,11 +214,31 @@
 		};
 	};
 
+	pipegrf: syscon at fdc50000 {
+		compatible = "rockchip,rk3568-pipegrf", "syscon";
+		reg = <0x0 0xfdc50000 0x0 0x1000>;
+	};
+
 	grf: syscon at fdc60000 {
 		compatible = "rockchip,rk3568-grf", "syscon", "simple-mfd";
 		reg = <0x0 0xfdc60000 0x0 0x10000>;
 	};
 
+	pipe_phy_grf0: syscon at fdc70000 {
+		compatible = "rockchip,pipe-phy-grf", "syscon";
+		reg = <0x0 0xfdc70000 0x0 0x1000>;
+	};
+
+	pipe_phy_grf1: syscon at fdc80000 {
+		compatible = "rockchip,pipe-phy-grf", "syscon";
+		reg = <0x0 0xfdc80000 0x0 0x1000>;
+	};
+
+	pipe_phy_grf2: syscon at fdc90000 {
+		compatible = "rockchip,pipe-phy-grf", "syscon";
+		reg = <0x0 0xfdc90000 0x0 0x1000>;
+	};
+
 	pmucru: clock-controller at fdd00000 {
 		compatible = "rockchip,rk3568-pmucru";
 		reg = <0x0 0xfdd00000 0x0 0x1000>;
@@ -862,6 +882,54 @@
 		status = "disabled";
 	};
 
+	combphy0_us: phy at fe820000 {
+		compatible = "rockchip,rk3568-naneng-combphy";
+		reg = <0x0 0xfe820000 0x0 0x100>;
+		#phy-cells = <1>;
+		clocks = <&pmucru CLK_PCIEPHY0_REF>, <&cru PCLK_PIPEPHY0>,
+			 <&cru PCLK_PIPE>;
+		clock-names = "ref", "apb", "pipe";
+		assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>;
+		assigned-clock-rates = <100000000>;
+		resets = <&cru SRST_P_PIPEPHY0>, <&cru SRST_PIPEPHY0>;
+		reset-names = "combphy-apb", "combphy";
+		rockchip,pipe-grf = <&pipegrf>;
+		rockchip,pipe-phy-grf = <&pipe_phy_grf0>;
+		status = "disabled";
+	};
+
+	combphy1_usq: phy at fe830000 {
+		compatible = "rockchip,rk3568-naneng-combphy";
+		reg = <0x0 0xfe830000 0x0 0x100>;
+		#phy-cells = <1>;
+		clocks = <&pmucru CLK_PCIEPHY1_REF>, <&cru PCLK_PIPEPHY1>,
+			 <&cru PCLK_PIPE>;
+		clock-names = "ref", "apb", "pipe";
+		assigned-clocks = <&pmucru CLK_PCIEPHY1_REF>;
+		assigned-clock-rates = <100000000>;
+		resets = <&cru SRST_P_PIPEPHY1>, <&cru SRST_PIPEPHY1>;
+		reset-names = "combphy-apb", "combphy";
+		rockchip,pipe-grf = <&pipegrf>;
+		rockchip,pipe-phy-grf = <&pipe_phy_grf1>;
+		status = "disabled";
+	};
+
+	combphy2_psq: phy at fe840000 {
+		compatible = "rockchip,rk3568-naneng-combphy";
+		reg = <0x0 0xfe840000 0x0 0x100>;
+		#phy-cells = <1>;
+		clocks = <&pmucru CLK_PCIEPHY2_REF>, <&cru PCLK_PIPEPHY2>,
+			 <&cru PCLK_PIPE>;
+		clock-names = "ref", "apb", "pipe";
+		assigned-clocks = <&pmucru CLK_PCIEPHY2_REF>;
+		assigned-clock-rates = <100000000>;
+		resets = <&cru SRST_P_PIPEPHY2>, <&cru SRST_PIPEPHY2>;
+		reset-names = "combphy-apb", "combphy";
+		rockchip,pipe-grf = <&pipegrf>;
+		rockchip,pipe-phy-grf = <&pipe_phy_grf2>;
+		status = "disabled";
+	};
+
 	pinctrl: pinctrl {
 		compatible = "rockchip,rk3568-pinctrl";
 		rockchip,grf = <&grf>;
-- 
2.17.1





From yifeng.zhao at rock-chips.com  Thu Aug 26 05:38:42 2021
From: yifeng.zhao at rock-chips.com (Yifeng Zhao)
Date: Thu, 26 Aug 2021 20:38:42 +0800
Subject: [PATCH v1 1/3] dt-bindings: phy: rockchip: Add Naneng combo PHY
 bindings
In-Reply-To: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
References: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
Message-ID: <20210826123844.8464-2-yifeng.zhao@rock-chips.com>

Add the compatible strings for the Naneng combo PHY found on rockchip SoC.

Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
---

 .../phy/phy-rockchip-naneng-combphy.yaml      | 100 ++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
new file mode 100644
index 000000000000..69908614609c
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/phy-rockchip-naneng-combphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC Naneng Combo Phy Device Tree Bindings
+
+maintainers:
+  - Heiko Stuebner <heiko at sntech.de>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3568-naneng-combphy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    items:
+      - description: reference clock
+      - description: apb clock
+      - description: pipe clock
+
+  clock-names:
+    minItems: 1
+    items:
+      - const: ref
+      - const: apb
+      - const: pipe
+
+  '#phy-cells':
+    const: 1
+
+  resets:
+    minItems: 1
+    items:
+      - description: exclusive apb reset line
+      - description: exclusive PHY reset line
+
+  reset-names:
+    minItems: 1
+    items:
+      - const: combphy-apb
+      - const: combphy
+
+  rockchip,pipe-grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Some additional phy settings are access through GRF regs.
+
+  rockchip,pipe-phy-grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Some additional pipe settings are access through GRF regs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#phy-cells'
+  - resets
+  - reset-names
+  - rockchip,pipe-grf
+  - rockchip,pipe-phy-grf
+
+additionalProperties: false
+
+examples:
+  - |
+
+    #include <dt-bindings/clock/rk3568-cru.h>
+
+    pipegrf: syscon at fdc50000 {
+      compatible = "rockchip,rk3568-pipegrf", "syscon";
+      reg = <0xfdc50000 0x1000>;
+    };
+
+    pipe_phy_grf0: syscon at fdc70000 {
+      compatible = "rockchip,pipe-phy-grf", "syscon";
+      reg = <0xfdc70000 0x1000>;
+    };
+
+    combphy0_us: phy at fe820000 {
+      compatible = "rockchip,rk3568-naneng-combphy";
+      reg = <0xfe820000 0x100>;
+      #phy-cells = <1>;
+      clocks = <&pmucru CLK_PCIEPHY0_REF>, <&cru PCLK_PIPEPHY0>,
+        <&cru PCLK_PIPE>;
+      clock-names = "ref", "apb", "pipe";
+      assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>;
+      assigned-clock-rates = <100000000>;
+      resets = <&cru SRST_P_PIPEPHY0>, <&cru SRST_PIPEPHY0>;
+      reset-names = "combphy-apb", "combphy";
+      rockchip,pipe-grf = <&pipegrf>;
+      rockchip,pipe-phy-grf = <&pipe_phy_grf0>;
+    };
-- 
2.17.1





From lorenzo.pieralisi at arm.com  Thu Aug 26 05:42:55 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 26 Aug 2021 13:42:55 +0100
Subject: [PATCH] PCI: aardvark: Fix masking and unmasking legacy INTx
 interrupts
In-Reply-To: <20210820155020.3000-1-pali@kernel.org>
References: <20210820155020.3000-1-pali@kernel.org>
Message-ID: <162998176149.21706.5126859600262914131.b4-ty@arm.com>

On Fri, 20 Aug 2021 17:50:20 +0200, Pali Roh?r wrote:
> irq_mask and irq_unmask callbacks need to be properly guarded by raw spin
> locks as masking/unmasking procedure needs atomic read-modify-write
> operation on hardware register.

Applied to pci/aardvark, thanks!

[1/1] PCI: aardvark: Fix masking and unmasking legacy INTx interrupts
      https://git.kernel.org/lpieralisi/pci/c/d212dcee27

Thanks,
Lorenzo


From mtosatti at redhat.com  Thu Aug 26 05:48:36 2021
From: mtosatti at redhat.com (Marcelo Tosatti)
Date: Thu, 26 Aug 2021 09:48:36 -0300
Subject: [PATCH v7 6/6] KVM: x86: Expose TSC offset controls to userspace
In-Reply-To: <CAOQ_Qsj_MfRNRRSK1UswsfBw4c9ugSW6tKXNua=3O78sHEonvA@mail.gmail.com>
References: <20210816001130.3059564-1-oupton@google.com>
 <20210816001130.3059564-7-oupton@google.com>
 <CAOQ_Qsj_MfRNRRSK1UswsfBw4c9ugSW6tKXNua=3O78sHEonvA@mail.gmail.com>
Message-ID: <20210826124836.GA155749@fuller.cnet>

On Mon, Aug 23, 2021 at 01:56:30PM -0700, Oliver Upton wrote:
> Paolo,
> 
> On Sun, Aug 15, 2021 at 5:11 PM Oliver Upton <oupton at google.com> wrote:
> >
> > To date, VMM-directed TSC synchronization and migration has been a bit
> > messy. KVM has some baked-in heuristics around TSC writes to infer if
> > the VMM is attempting to synchronize. This is problematic, as it depends
> > on host userspace writing to the guest's TSC within 1 second of the last
> > write.
> >
> > A much cleaner approach to configuring the guest's views of the TSC is to
> > simply migrate the TSC offset for every vCPU. Offsets are idempotent,
> > and thus not subject to change depending on when the VMM actually
> > reads/writes values from/to KVM. The VMM can then read the TSC once with
> > KVM_GET_CLOCK to capture a (realtime, host_tsc) pair at the instant when
> > the guest is paused.
> >
> > Cc: David Matlack <dmatlack at google.com>
> > Cc: Sean Christopherson <seanjc at google.com>
> > Signed-off-by: Oliver Upton <oupton at google.com>
> 
> Could you please squash the following into this patch? We need to
> advertise KVM_CAP_VCPU_ATTRIBUTES to userspace. Otherwise, happy to
> resend.
> 
> Thanks,
> Oliver

Oliver,

Is there QEMU support for this, or are you using your own
userspace with this?



From lorenzo.pieralisi at arm.com  Thu Aug 26 05:53:12 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 26 Aug 2021 13:53:12 +0100
Subject: [PATCH v12 0/6] PCI: mediatek: Spilt PCIe node to comply with
 hardware design
In-Reply-To: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
References: <20210823032800.1660-1-chuanjia.liu@mediatek.com>
Message-ID: <162998235864.26306.15150607621994016843.b4-ty@arm.com>

On Mon, 23 Aug 2021 11:27:54 +0800, Chuanjia Liu wrote:
> There are two independent PCIe controllers in MT2712 and MT7622 platform.
> Each of them should contain an independent MSI domain.
> 
> In old dts architecture, MSI domain will be inherited from the root
> bridge, and all of the devices will share the same MSI domain.Hence that,
> the PCIe devices will not work properly if the irq number which required
> is more than 32.
> 
> [...]

Applied to pci/mediatek, thanks!

[1/4] dt-bindings: PCI: mediatek: Update the Device tree bindings
      https://git.kernel.org/lpieralisi/pci/c/aa6eca5b81
[2/4] PCI: mediatek: Add new method to get shared pcie-cfg base address
      https://git.kernel.org/lpieralisi/pci/c/87e8657ba9
[3/4] PCI: mediatek: Add new method to get irq number
      https://git.kernel.org/lpieralisi/pci/c/436960bb00
[4/4] PCI: mediatek: Use PCI domain to handle ports detection
      https://git.kernel.org/lpieralisi/pci/c/77216702c8

Thanks,
Lorenzo


From lorenzo.pieralisi at arm.com  Thu Aug 26 06:01:19 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 26 Aug 2021 14:01:19 +0100
Subject: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <162998285902.30814.11206633831020646086.b4-ty@arm.com>

On Wed, 11 Aug 2021 17:38:27 +0900, Nobuhiro Iwamatsu wrote:
> This series is the PCIe driver for Toshiba's ARM SoC, Visconti[0].
> This provides DT binding documentation, device driver, MAINTAINER files.
> 
> Best regards,
>   Nobuhiro
> 
> [0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html
> 
> [...]

Applied to pci/dwc, thanks!

[1/3] dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
      https://git.kernel.org/lpieralisi/pci/c/a655ce4000
[2/3] PCI: visconti: Add Toshiba Visconti PCIe host controller driver
      https://git.kernel.org/lpieralisi/pci/c/09436f819c
[3/3] MAINTAINERS: Add entries for Toshiba Visconti PCIe controller
      https://git.kernel.org/lpieralisi/pci/c/34af7aace1

Thanks,
Lorenzo


From bot at kernelci.org  Thu Aug 26 06:08:15 2021
From: bot at kernelci.org (kernelci.org bot)
Date: Thu, 26 Aug 2021 06:08:15 -0700 (PDT)
Subject: arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 2 errors,
 1 warning (v5.14-rc7-2-g988c09add519)
Message-ID: <6127923f.1c69fb81.2cf3d.8a6e@mx.google.com>

arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 2 errors, 1 warning (v5.14-rc7-2-g988c09add519)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v5.14-rc7-2-g988c09add519/

Tree: arm64
Branch: for-kernelci
Git Describe: v5.14-rc7-2-g988c09add519
Git Commit: 988c09add519a446ccc0d261c2c9d3f3405eea81
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Build Failure Detected:

arm64:
    allmodconfig: (gcc-8) FAIL

Errors and Warnings Detected:

arm64:
    allmodconfig (gcc-8): 2 errors, 1 warning

Errors summary:

    1    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1861? declared with attribute error: FIELD_PREP: value too large for the field
    1    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1854? declared with attribute error: FIELD_PREP: value too large for the field

Warnings summary:

    1    kernel/trace/trace_osnoise.c:1515:8: warning: ?main? is usually a function [-Wmain]

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
allmodconfig (arm64, gcc-8) ? FAIL, 2 errors, 1 warning, 0 section mismatches

Errors:
    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1854? declared with attribute error: FIELD_PREP: value too large for the field
    ./../include/linux/compiler_types.h:328:38: error: call to ?__compiletime_assert_1861? declared with attribute error: FIELD_PREP: value too large for the field

Warnings:
    kernel/trace/trace_osnoise.c:1515:8: warning: ?main? is usually a function [-Wmain]

--------------------------------------------------------------------------------
defconfig (arm64, gcc-8) ? PASS, 0 errors, 0 warnings, 0 section mismatches

---
For more info write to <info at kernelci.org>


From will at kernel.org  Thu Aug 26 06:17:48 2021
From: will at kernel.org (Will Deacon)
Date: Thu, 26 Aug 2021 14:17:48 +0100
Subject: [GIT PULL] arm64 fix for 5.14
Message-ID: <20210826131747.GE26318@willie-the-truck>

Hi Linus,

Please pull this single arm64 fix for 5.14. We received a report this week
that the generic version of pfn_valid(), which we switched to this merge
window in 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID"), interacts
badly with dma_map_resource() due to the following check:

        /* Don't allow RAM to be mapped */
        if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
                return DMA_MAPPING_ERROR;

Since the ongoing saga to determine the semantics of pfn_valid() is
unlikely to be resolved this week (does it indicate valid memory, or
just the presence of a struct page, or whether that struct page has been
initialised?), just revert back to our old version of pfn_valid() for
5.14.

Thanks,

Will

--->8

The following changes since commit bde8fff82e4a4b0f000dbf4d5eadab2079be0b56:

  arm64: initialize all of CNTHCTL_EL2 (2021-08-19 10:02:10 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to 3eb9cdffb39701743973382860f214026f4d7825:

  Partially revert "arm64/mm: drop HAVE_ARCH_PFN_VALID" (2021-08-25 11:33:24 +0100)

----------------------------------------------------------------
arm64 fix for 5.14

- Fix dma_map_resource() by reverting back to old pfn_valid() code

----------------------------------------------------------------
Will Deacon (1):
      Partially revert "arm64/mm: drop HAVE_ARCH_PFN_VALID"

 arch/arm64/Kconfig            |  1 +
 arch/arm64/include/asm/page.h |  1 +
 arch/arm64/mm/init.c          | 37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 39 insertions(+)


From robh at kernel.org  Thu Aug 26 06:26:01 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 26 Aug 2021 08:26:01 -0500
Subject: [PATCH v3 1/4] dt-bindings: aspeed: Add eSPI controller
In-Reply-To: <20210826061623.6352-2-chiawei_wang@aspeedtech.com>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
 <20210826061623.6352-2-chiawei_wang@aspeedtech.com>
Message-ID: <1629984361.334223.1033382.nullmailer@robh.at.kernel.org>

On Thu, 26 Aug 2021 14:16:20 +0800, Chia-Wei Wang wrote:
> Add dt-bindings for Aspeed eSPI controller
> 
> Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
> ---
>  .../devicetree/bindings/soc/aspeed/espi.yaml  | 157 ++++++++++++++++++
>  1 file changed, 157 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/aspeed/espi.example.dt.yaml: espi at 1e6ee000: 'espi-ctrl at 0', 'espi-mmbi at 800' do not match any of the regexes: 'pinctrl-[0-9]+'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/aspeed/espi.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1520968

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Thu Aug 26 06:26:01 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 26 Aug 2021 08:26:01 -0500
Subject: [PATCH v1 1/3] dt-bindings: phy: rockchip: Add Naneng combo PHY
 bindings
In-Reply-To: <20210826123844.8464-2-yifeng.zhao@rock-chips.com>
References: <20210826123844.8464-1-yifeng.zhao@rock-chips.com>
 <20210826123844.8464-2-yifeng.zhao@rock-chips.com>
Message-ID: <1629984361.449016.1033391.nullmailer@robh.at.kernel.org>

On Thu, 26 Aug 2021 20:38:42 +0800, Yifeng Zhao wrote:
> Add the compatible strings for the Naneng combo PHY found on rockchip SoC.
> 
> Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> ---
> 
>  .../phy/phy-rockchip-naneng-combphy.yaml      | 100 ++++++++++++++++++
>  1 file changed, 100 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.example.dt.yaml:0:0: /example-0/syscon at fdc50000: failed to match any schema with compatible: ['rockchip,rk3568-pipegrf', 'syscon']
Documentation/devicetree/bindings/phy/phy-rockchip-naneng-combphy.example.dt.yaml:0:0: /example-0/syscon at fdc70000: failed to match any schema with compatible: ['rockchip,pipe-phy-grf', 'syscon']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1521096

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From catalin.marinas at arm.com  Thu Aug 26 06:31:20 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 26 Aug 2021 14:31:20 +0100
Subject: [RFC PATCH] arm64: mm: limit linear region to 51 bits for KVM in
 nVHE mode
In-Reply-To: <20210824105920.GB22752@willie-the-truck>
References: <20210810161244.84231-1-ardb@kernel.org>
 <20210824105920.GB22752@willie-the-truck>
Message-ID: <20210826133118.GC30910@arm.com>

On Tue, Aug 24, 2021 at 11:59:20AM +0100, Will Deacon wrote:
> On Tue, Aug 10, 2021 at 06:12:44PM +0200, Ard Biesheuvel wrote:
> > KVM in nVHE mode divides up its VA space into two equal halves, and
> > picks the half that does not conflict with the HYP ID map to map its
> > linear region. This worked fine when the kernel's linear map itself was
> > guaranteed to cover precisely as many bits of VA space, but this was
> > changed by commit f4693c2716b35d08 ("arm64: mm: extend linear region for
> > 52-bit VA configurations").
> > 
> > The result is that, depending on the placement of the ID map, kernel-VA
> > to hyp-VA translations may produce addresses that either conflict with
> > other HYP mappings (including the ID map itself) or generate addresses
> > outside of the 52-bit addressable range, neither of which is likely to
> > lead to anything useful.
> > 
> > Given that 52-bit capable cores are guaranteed to implement VHE, this
> > only affects configurations such as pKVM where we opt into non-VHE mode
> > even if the hardware is VHE capable. So just for these configurations,
> > let's limit the kernel linear map to 51 bits and work around the
> > problem.
> > 
> > Fixes:f4693c2716b35d08 ("arm64: mm: extend linear region for 52-bit VA configurations")
> > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> > ---
> > NOTE: build tested only
> > 
> >  arch/arm64/mm/init.c | 16 +++++++++++++++-
> >  1 file changed, 15 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > index 8490ed2917ff..542dad13e2fc 100644
> > --- a/arch/arm64/mm/init.c
> > +++ b/arch/arm64/mm/init.c
> > @@ -282,7 +282,21 @@ static void __init fdt_enforce_memory_region(void)
> >  
> >  void __init arm64_memblock_init(void)
> >  {
> > -	const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > +	s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > +
> > +	/*
> > +	 * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
> > +	 * be limited in their ability to support a linear map that exceeds 51
> > +	 * bits of VA space, depending on the placement of the ID map. Given
> > +	 * that the placement of the ID map may be randomized, let's simply
> > +	 * limit the kernel's linear map to 51 bits as well if we detect this
> > +	 * configuration.
> > +	 */
> > +	if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 &&
> > +	    !is_kernel_in_hyp_mode()) {
> > +		pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n");
> > +		linear_region_size = BIT(51);
> > +	}
> 
> Slight nit, but to avoid having to think about PAGE_END I think this would
> be a little clearer as:
> 
> 	if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode())
> 		linear_region_size = min_t(u64, linear_region_size, BIT(51));

BTW, do we also need to check is_hyp_mode_available() (instead of just
CONFIG_KVM)? We don't need this reduction for a guest.

-- 
Catalin


From bot at kernelci.org  Thu Aug 26 06:51:28 2021
From: bot at kernelci.org (kernelci.org bot)
Date: Thu, 26 Aug 2021 06:51:28 -0700 (PDT)
Subject: arm64/for-kernelci baseline: 48 runs,
 4 regressions (v5.14-rc7-2-g988c09add519)
Message-ID: <61279c60.1c69fb81.2da75.9bfd@mx.google.com>

arm64/for-kernelci baseline: 48 runs, 4 regressions (v5.14-rc7-2-g988c09add519)

Regressions Summary
-------------------

platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
bcm2837-rpi-3-b  | arm64 | lab-baylibre  | gcc-8    | defconfig | 1          
imx8mp-evk       | arm64 | lab-nxp       | gcc-8    | defconfig | 1          
rk3399-gru-kevin | arm64 | lab-collabora | gcc-8    | defconfig | 2          

  Details:  https://kernelci.org/test/job/arm64/branch/for-kernelci/kernel/v5.14-rc7-2-g988c09add519/plan/baseline/

  Test:     baseline
  Tree:     arm64
  Branch:   for-kernelci
  Describe: v5.14-rc7-2-g988c09add519
  URL:      https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  SHA:      988c09add519a446ccc0d261c2c9d3f3405eea81 


Test Regressions
---------------- 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
bcm2837-rpi-3-b  | arm64 | lab-baylibre  | gcc-8    | defconfig | 1          

  Details:     https://kernelci.org/test/plan/id/61278ff34ba2af730e8e2cb1

  Results:     0 PASS, 1 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc7-2-g988c09add519/arm64/defconfig/gcc-8/lab-baylibre/baseline-bcm2837-rpi-3-b.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc7-2-g988c09add519/arm64/defconfig/gcc-8/lab-baylibre/baseline-bcm2837-rpi-3-b.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.login: https://kernelci.org/test/case/id/61278ff34ba2af730e8e2cb2
        failing since 44 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1) 
 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
imx8mp-evk       | arm64 | lab-nxp       | gcc-8    | defconfig | 1          

  Details:     https://kernelci.org/test/plan/id/612797e523b15b7d408e2de3

  Results:     0 PASS, 1 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc7-2-g988c09add519/arm64/defconfig/gcc-8/lab-nxp/baseline-imx8mp-evk.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc7-2-g988c09add519/arm64/defconfig/gcc-8/lab-nxp/baseline-imx8mp-evk.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.login: https://kernelci.org/test/case/id/612797e523b15b7d408e2de4
        new failure (last pass: v5.14-rc6-3-g4a8d882022c7) 
 


platform         | arch  | lab           | compiler | defconfig | regressions
-----------------+-------+---------------+----------+-----------+------------
rk3399-gru-kevin | arm64 | lab-collabora | gcc-8    | defconfig | 2          

  Details:     https://kernelci.org/test/plan/id/61279075df5f99f9b88e2c77

  Results:     89 PASS, 2 FAIL, 0 SKIP
  Full config: defconfig
  Compiler:    gcc-8 (aarch64-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0)
  Plain log:   https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc7-2-g988c09add519/arm64/defconfig/gcc-8/lab-collabora/baseline-rk3399-gru-kevin.txt
  HTML log:    https://storage.kernelci.org//arm64/for-kernelci/v5.14-rc7-2-g988c09add519/arm64/defconfig/gcc-8/lab-collabora/baseline-rk3399-gru-kevin.html
  Rootfs:      http://storage.kernelci.org/images/rootfs/buildroot/kci-2020.05-6-g8983f3b738df/arm64/baseline/rootfs.cpio.gz 


  * baseline.bootrr.rockchip-usb2phy1-probed: https://kernelci.org/test/case/id/61279075df5f99f9b88e2c7d
        failing since 44 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1)

    2021-08-26T13:00:32.534165  <8>[   23.664248] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=rockchip-usb2phy0-probed RESULT=fail>
    2021-08-26T13:00:33.552593  /lava-4416901/1/../bin/lava-test-case
    2021-08-26T13:00:33.564398  <8>[   24.698835] <LAVA_SIGNAL_TESTCASE TEST_CASE_ID=rockchip-usb2phy1-probed RESULT=fail>   

  * baseline.bootrr.rockchip-usb2phy0-probed: https://kernelci.org/test/case/id/61279075df5f99f9b88e2c7e
        failing since 44 days (last pass: v5.13-13-g68ddb29c953a, first fail: v5.14-rc1)

    2021-08-26T13:00:32.519137  /lava-4416901/1/../bin/lava-test-case   
  


From liviu.dudau at arm.com  Thu Aug 26 07:09:50 2021
From: liviu.dudau at arm.com (Liviu Dudau)
Date: Thu, 26 Aug 2021 15:09:50 +0100
Subject: [PATCH 1/3] arm64: dts: arm: align watchdog and mmc node names
 with dtschema
In-Reply-To: <20210820081733.83976-1-krzysztof.kozlowski@canonical.com>
References: <20210820081733.83976-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YSegrnil/5rn/EVH@e110455-lin.cambridge.arm.com>

On Fri, Aug 20, 2021 at 10:17:31AM +0200, Krzysztof Kozlowski wrote:
> Align the watchdog and mmc device node names with the schema to fix
> warnings like:
> 
>   mmci at 50000: $nodename:0: 'mmci at 50000' does not match '^mmc(@.*)?$'
>   wdt at f0000: $nodename:0: 'wdt at f0000' does not match '^watchdog(@.*|-[0-9a-f])?$'
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

For the whole series: Acked-by: Liviu Dudau <liviu.dudau at arm.com>

Many thanks,
Liviu

> ---
>  arch/arm64/boot/dts/arm/juno-motherboard.dtsi    | 4 ++--
>  arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
> index 40d95c58b55e..f45c912b2806 100644
> --- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
> +++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
> @@ -218,7 +218,7 @@ led7 {
>  					};
>  				};
>  
> -				mmci at 50000 {
> +				mmc at 50000 {
>  					compatible = "arm,pl180", "arm,primecell";
>  					reg = <0x050000 0x1000>;
>  					interrupts = <5>;
> @@ -246,7 +246,7 @@ kmi at 70000 {
>  					clock-names = "KMIREFCLK", "apb_pclk";
>  				};
>  
> -				wdt at f0000 {
> +				watchdog at f0000 {
>  					compatible = "arm,sp805", "arm,primecell";
>  					reg = <0x0f0000 0x10000>;
>  					interrupts = <7>;
> diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
> index 4c4a381d2c75..7260bcf4b2ab 100644
> --- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
> +++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
> @@ -130,7 +130,7 @@ aaci at 40000 {
>  					clock-names = "apb_pclk";
>  				};
>  
> -				mmci at 50000 {
> +				mmc at 50000 {
>  					compatible = "arm,pl180", "arm,primecell";
>  					reg = <0x050000 0x1000>;
>  					interrupts = <9>, <10>;
> @@ -190,7 +190,7 @@ v2m_serial3: serial at c0000 {
>  					clock-names = "uartclk", "apb_pclk";
>  				};
>  
> -				wdt at f0000 {
> +				watchdog at f0000 {
>  					compatible = "arm,sp805", "arm,primecell";
>  					reg = <0x0f0000 0x1000>;
>  					interrupts = <0>;
> -- 
> 2.30.2
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?


From olteanv at gmail.com  Thu Aug 26 07:13:26 2021
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 26 Aug 2021 17:13:26 +0300
Subject: [RFC net-next 2/2] net: dsa: tag_mtk: handle VLAN tag insertion
 on TX
In-Reply-To: <20210826052956.3101243-1-dqfext@gmail.com>
References: <20210825083832.2425886-1-dqfext@gmail.com>
 <20210825083832.2425886-3-dqfext@gmail.com>
 <20210826000349.q3s5gjuworxtbcna@skbuf>
 <20210826052956.3101243-1-dqfext@gmail.com>
Message-ID: <20210826141326.xa52776uh3r3jpg4@skbuf>

On Thu, Aug 26, 2021 at 01:29:56PM +0800, DENG Qingfang wrote:
> On Thu, Aug 26, 2021 at 03:03:49AM +0300, Vladimir Oltean wrote:
> > 
> > You cannot just remove the old code. Only things like 8021q uppers will
> > send packets with the VLAN in the hwaccel area.
> > 
> > If you have an application that puts the VLAN in the actual AF_PACKET
> > payload, like:
> > 
> > https://github.com/vladimiroltean/tsn-scripts/blob/master/isochron/send.c
> > 
> > then you need to handle the VLAN being in the skb payload.
> 
> I've actually tested this (only apply patch 2 without .features) and it
> still worked.
> 
> The comment says the VLAN tag need to be combined with the special tag in
> order to perform VLAN table lookup,

It does say this.

> so we can set its destination port vector to all zeroes and the switch
> will forward it like a data frame (TX forward offload),

And it does not say this. So this is supported after all with mt7530?
Are you looking to add support for that?

> but as we allow multiple bridges which are either VLAN-unaware or
> VLAN-aware with the same VID, there is no way to determine the
> destination bridge unless we maintain some VLAN translation mapping.

What does "VLAN translation mapping" mean, practically?
Other drivers which cannot remap VIDs to internal VLANs just restrict a
single VLAN-aware bridge, and potentially multiple VLAN-unaware ones.


From broonie at kernel.org  Thu Aug 26 07:15:42 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 26 Aug 2021 15:15:42 +0100
Subject: [RESEND][PATCH] spi: spi-zynq-qspi: use
 wait_for_completion_timeout to make zynq_qspi_exec_mem_op not interruptible
In-Reply-To: <20210826005930.20572-1-quanyang.wang@windriver.com>
References: <20210826005930.20572-1-quanyang.wang@windriver.com>
Message-ID: <162998730427.6164.15239399096939120382.b4-ty@kernel.org>

On Thu, 26 Aug 2021 08:59:30 +0800, quanyang.wang at windriver.com wrote:
> From: Quanyang Wang <quanyang.wang at windriver.com>
> 
> The function wait_for_completion_interruptible_timeout will return
> -ERESTARTSYS immediately when receiving SIGKILL signal which is sent
> by "jffs2_gcd_mtd" during umounting jffs2. This will break the SPI memory
> operation because the data transmitting may begin before the command or
> address transmitting completes. Use wait_for_completion_timeout to prevent
> the process from being interruptible.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: spi-zynq-qspi: use wait_for_completion_timeout to make zynq_qspi_exec_mem_op not interruptible
      commit: 26cfc0dbe43aae60dc03af27077775244f26c167

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Thu Aug 26 07:15:43 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 26 Aug 2021 15:15:43 +0100
Subject: [PATCH v1 0/4] Patches to update for rockchip spdif
In-Reply-To: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
References: <1629800162-12824-1-git-send-email-sugar.zhang@rock-chips.com>
Message-ID: <162998707937.5647.10936208575135633257.b4-ty@kernel.org>

On Tue, 24 Aug 2021 18:15:58 +0800, Sugar Zhang wrote:
> These patches fixup or update for rockchip spdif.
> 
> 
> Sugar Zhang (4):
>   ASoC: rockchip: spdif: Mark SPDIF_SMPDR as volatile
>   ASoC: rockchip: spdif: Fix some coding style
>   ASoC: rockchip: spdif: Add support for rk3568 spdif
>   ASoC: dt-bindings: rockchip: Add compatible for rk3568 spdif
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/4] ASoC: rockchip: spdif: Mark SPDIF_SMPDR as volatile
      commit: 023a3f3a1c4f9be9cc1ae92579ba816120fb5807
[2/4] ASoC: rockchip: spdif: Fix some coding style
      commit: acc8b9d117912c2d5952868fba0d4fca49cde3c8
[3/4] ASoC: rockchip: spdif: Add support for rk3568 spdif
      commit: c5d4f09feb9f74e704d87a304f0c20001488fe10
[4/4] ASoC: dt-bindings: rockchip: Add compatible for rk3568 spdif
      commit: e79ef3c2cfe0b39878496eac87450698a2e84e3f

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Thu Aug 26 07:15:45 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 26 Aug 2021 15:15:45 +0100
Subject: [PATCH][next] ASoC: mediatek: mt8195: Fix spelling mistake
 "bitwiedh" -> "bitwidth"
In-Reply-To: <20210826112611.10356-1-colin.king@canonical.com>
References: <20210826112611.10356-1-colin.king@canonical.com>
Message-ID: <162998707936.5647.1881702741528479360.b4-ty@kernel.org>

On Thu, 26 Aug 2021 12:26:11 +0100, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
> 
> There is a spelling mistake in a dev_dbg message. Fix it.
> 
> 
> 
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: mediatek: mt8195: Fix spelling mistake "bitwiedh" -> "bitwidth"
      commit: 11a08e05079a9328023d236b82bd7981bcde0852

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From lkp at intel.com  Thu Aug 26 07:23:59 2021
From: lkp at intel.com (kernel test robot)
Date: Thu, 26 Aug 2021 22:23:59 +0800
Subject: [xlnx:xlnx_rebase_v5.10 251/1762]
 drivers/gpu/drm/xlnx/xlnx_scaler.c:866:3: warning: variable 'nr_rds' is
 uninitialized when used here
Message-ID: <202108262251.AwRnaFVw-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   09a4215f61493584f4410cab3477003e4046dab9
commit: 9c2aaea5d2da626727258703b85f52281b8673bb [251/1762] drm: xlnx: scaler: Adding vpss-scaler driver
config: riscv-randconfig-r022-20210826 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/9c2aaea5d2da626727258703b85f52281b8673bb
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx xlnx_rebase_v5.10
        git checkout 9c2aaea5d2da626727258703b85f52281b8673bb
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/xlnx/xlnx_scaler.c:866:3: warning: variable 'nr_rds' is uninitialized when used here [-Wuninitialized]
                   nr_rds += nr_rds_clck;
                   ^~~~~~
   drivers/gpu/drm/xlnx/xlnx_scaler.c:821:12: note: initialize the variable 'nr_rds' to silence this warning
           int nr_rds;
                     ^
                      = 0
   drivers/gpu/drm/xlnx/xlnx_scaler.c:1394:14: warning: variable 'fmt_out' set but not used [-Wunused-but-set-variable]
           u32 fmt_in, fmt_out;
                       ^
   drivers/gpu/drm/xlnx/xlnx_scaler.c:1394:6: warning: variable 'fmt_in' set but not used [-Wunused-but-set-variable]
           u32 fmt_in, fmt_out;
               ^
   3 warnings generated.


vim +/nr_rds +866 drivers/gpu/drm/xlnx/xlnx_scaler.c

   800	
   801	/**
   802	 * xv_hscaler_calculate_phases - Calculates h-scaler phases
   803	 * @scaler: Pointer to scaler registers base
   804	 * @width_in: input width
   805	 * @width_out: output width
   806	 * @pixel_rate: pixel rate
   807	 *
   808	 */
   809	static void
   810	xv_hscaler_calculate_phases(struct xilinx_scaler *scaler,
   811				    u32 width_in, u32 width_out, u32 pixel_rate)
   812	{
   813		unsigned int loop_width;
   814		unsigned int x, s;
   815		int offset = 0;
   816		int xwrite_pos = 0;
   817		bool output_write_en;
   818		bool get_new_pix;
   819		u64 phaseH;
   820		u32 array_idx = 0;
   821		int nr_rds;
   822		int nr_rds_clck;
   823		unsigned int nphases = scaler->max_num_phases;
   824		unsigned int nppc = scaler->pix_per_clk;
   825		unsigned int shift = XHSC_STEP_PRECISION_SHIFT - ilog2(nphases);
   826	
   827		loop_width = max_t(u32, width_in, width_out);
   828		loop_width = ALIGN(loop_width + nppc - 1, nppc);
   829	
   830		for (x = 0; x < loop_width; x++) {
   831			nr_rds_clck = 0;
   832			for (s = 0; s < nppc; s++) {
   833				phaseH = (offset >> shift) & (nphases - 1);
   834				get_new_pix = false;
   835				output_write_en = false;
   836				if ((offset >> XHSC_STEP_PRECISION_SHIFT) != 0) {
   837					get_new_pix = true;
   838					offset -= (1 << XHSC_STEP_PRECISION_SHIFT);
   839					array_idx++;
   840				}
   841	
   842				if (((offset >> XHSC_STEP_PRECISION_SHIFT) == 0) &&
   843				    xwrite_pos < width_out) {
   844					offset += pixel_rate;
   845					output_write_en = true;
   846					xwrite_pos++;
   847				}
   848	
   849				scaler->H_phases[x] |= (phaseH <<
   850							(s * XHSC_HPHASE_MULTIPLIER));
   851				scaler->H_phases[x] |= (array_idx <<
   852							(XHSC_HPHASE_SHIFT_BY_6 +
   853							(s * XHSC_HPHASE_MULTIPLIER)));
   854				if (output_write_en) {
   855					scaler->H_phases[x] |=
   856					(XV_HSCALER_PHASESH_V_OUTPUT_WR_EN <<
   857					(s * XHSC_HPHASE_MULTIPLIER));
   858				}
   859	
   860				if (get_new_pix)
   861					nr_rds_clck++;
   862			}
   863			if (array_idx >= nppc)
   864				array_idx &= (nppc - 1);
   865	
 > 866			nr_rds += nr_rds_clck;
   867			if (nr_rds >= nppc)
   868				nr_rds -= nppc;
   869		}
   870	}
   871	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 28809 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210826/017168ea/attachment-0001.gz>

From monstr at monstr.eu  Thu Aug 26 07:36:21 2021
From: monstr at monstr.eu (Michal Simek)
Date: Thu, 26 Aug 2021 16:36:21 +0200
Subject: [GIT PULL] arm64: dts: ZynqMP DT changes for v5.15
Message-ID: <cec98151-d7a9-3fdb-ba5c-dc1fd182c2c4@monstr.eu>

Hi,

please pull these patches to your tree. I have one more patch for adding
new Xilinx Kria platform but that discussion about compatible nodes in
overlay is not finished yes. That's why I am sending this pull request
without it.
A lot patches are coming from dtbs_check fixing and synchronization
among boards to better see differences. But also couple of drivers were
already merged that's why make sense to enable it.

Thanks,
Michal



The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  https://github.com/Xilinx/linux-xlnx.git tags/zynqmp-dt-for-v5.15

for you to fetch changes up to 479c46133c0573b6549e437165bff1422634f45f:

  arm64: zynqmp: Wire psgtr for zc1751-xm013 (2021-08-25 08:29:27 +0200)

----------------------------------------------------------------
arm64: dts: ZynqMP DT changes for v5.13

- Fix issues reported by dtbs_check
- Enable DMAs, DP, USB, NAND on various boards
- Add description for irps5401
- Add pinctrl description
- Add psgtr description for usb3, sata and DP
- Start to use nvmem alias for eeprom reference
- Clean up aliases list
- Wire qspi and usb3.0
- Add support for zcu102-rev1.1
- Couple of minor fixes and sync patches

----------------------------------------------------------------
Amit Kumar Mahapatra (1):
      arm64: zynqmp: Do not duplicate flash partition label property

Michal Simek (32):
      arm64: zynqmp: Disable CCI by default
      arm64: zynqmp: Enable fpd_dma for zcu104 platforms
      arm64: zynqmp: Fix irps5401 device nodes
      arm64: zynqmp: Add pinctrl description for all boards
      arm64: zynqmp: Correct zcu111 psgtr description
      arm64: zynqmp: Wire psgtr for zc1751-xm015
      arm64: zynqmp: Correct psgtr description for zcu100-revC
      arm64: zynqmp: Add phy description for usb3.0
      arm64: zynqmp: Disable WP on zcu111
      arm64: zynqmp: Add missing mio-bank properties to dc1 and dc5
      arm64: zynqmp: Wire DP and DPDMA for dc1/dc4
      arm64: zynqmp: Enable nand driver for dc2 and dc3
      arm64: zynqmp: Remove additional newline
      arm64: zynqmp: Move clock node to zynqmp-clk-ccf.dtsi
      arm64: zynqmp: Add nvmem alises for eeproms
      arm64: zynqmp: List reset property for ethernet phy
      arm64: zynqmp: Remove can aliases from zc1751
      arm64: zynqmp: Move DP nodes to the end of file on zcu106
      arm64: zynqmp: Add note about UHS mode on some boards
      arm64: zynqmp: Remove information about dma clock on zcu106
      arm64: zynqmp: Wire qspi on multiple boards
      arm64: zynqmp: Move rtc to different location on zcu104-revA
      arm64: zynqmp: Add reset description for sata
      arm64: zynqmp: Sync psgtr node location with zcu104-revA
      arm64: zynqmp: Remove description for 8T49N287 and si5382 chips
      arm64: zynqmp: Add support for zcu102-rev1.1 board
      arm64: zynqmp: Add psgtr description to zc1751 dc1 board
      arm64: zynqmp: Remove not documented is-dual property
      arm64: zynqmp: Fix serial compatible string
      arm64: zynqmp: Enable gpio and qspi for zc1275-revA
      arm64: zynqmp: Enable xlnx,zynqmp-dwc3 driver for xilinx boards
      arm64: zynqmp: Wire psgtr for zc1751-xm013

Mounika Grace Akula (1):
      arm64: zynqmp: Add reset-on-timeout to all boards and modify
default timeout value

Srinivas Neeli (1):
      arm64: zynqmp: Update rtc calibration value

Stefano Stabellini (1):
      arm64: zynqmp: Add missing SMID for pcie to zynqmp.dtsi

 Documentation/devicetree/bindings/arm/xilinx.yaml      |   1 +
 arch/arm64/boot/dts/xilinx/Makefile                    |   1 +
 arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi         |  13 ++++++++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1232-revA.dts      |  16
+++++++++++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1254-revA.dts      |  16
+++++++++++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts      |  18
+++++++++++++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts | 298
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts | 342
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts |  49
++++++++++++++++++++++++++++++++++++++++++++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm018-dc4.dts |  24
+++++++++++++++++++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts | 330
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts      | 264
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.1.dts    |  15
+++++++++++++++
 arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts      | 320
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revB.dts      |   3 ++-
 arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts      | 292
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts      | 250
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts      | 340
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
 arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts      | 274
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi                 |  93
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
 20 files changed, 2861 insertions(+), 98 deletions(-)
 create mode 100644 arch/arm64/boot/dts/xilinx/zynqmp-zcu102-rev1.1.dts

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs



From dafna.hirschfeld at collabora.com  Thu Aug 26 07:45:16 2021
From: dafna.hirschfeld at collabora.com (Dafna Hirschfeld)
Date: Thu, 26 Aug 2021 16:45:16 +0200
Subject: [PATCH] arm64: defconfig: Enable media drivers of mediatek
Message-ID: <20210826144516.6359-1-dafna.hirschfeld@collabora.com>

add as modules:
VIDEO_MEDIATEK_VPU
VIDEO_MEDIATEK_MDP
VIDEO_MEDIATEK_VCODEC

Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f423d08b9a71..f97da10a21ea 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -669,6 +669,9 @@ CONFIG_VIDEO_RCAR_DRIF=m
 CONFIG_VIDEO_IMX219=m
 CONFIG_VIDEO_OV5645=m
 CONFIG_VIDEO_QCOM_CAMSS=m
+CONFIG_VIDEO_MEDIATEK_VPU=m
+CONFIG_VIDEO_MEDIATEK_MDP=m
+CONFIG_VIDEO_MEDIATEK_VCODEC=m
 CONFIG_DRM=m
 CONFIG_DRM_I2C_NXP_TDA998X=m
 CONFIG_DRM_MALI_DISPLAY=m
-- 
2.17.1



From gszymaszek at short.pl  Thu Aug 26 07:45:43 2021
From: gszymaszek at short.pl (Grzegorz Szymaszek)
Date: Thu, 26 Aug 2021 16:45:43 +0200
Subject: [PATCH] ARM: dts: stm32: set the DCMI pins on stm32mp157c-odyssey
Message-ID: <YSepFyt8o+5lAsrA@nx64de-df6d00>

The Seeed Odyssey-STM32MP157C board has a 20-pin DVP camera output. The
DCMI pins used on this output are defined in the pin state definition
&pinctrl/dcmi-1, AKA &dcmi_pins_b (added in mainline commit
02814a41529a55dbfb9fbb2a3728e78e70646ea6). Set these pins as the default
pinctrl of the DCMI peripheral in the board device tree.

The pins are not used for any other purpose, so it seems safe to assume
most users will not need to override (delete) what this patch provides.
status defaults to "disabled", so the peripheral will not be
unnecessarily started. And the users who actually intend to make use of
a camera on the DVP port will have this little part of the configuration
ready.

Signed-off-by: Grzegorz Szymaszek <gszymaszek at short.pl>
---
 arch/arm/boot/dts/stm32mp157c-odyssey.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts
index be1dd5e9e744..554f5d3bcdc3 100644
--- a/arch/arm/boot/dts/stm32mp157c-odyssey.dts
+++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts
@@ -22,6 +22,12 @@ chosen {
 	};
 };
 
+&dcmi {
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&dcmi_pins_b>;
+	pinctrl-1 = <&dcmi_sleep_pins_b>;
+};
+
 &ethernet0 {
 	status = "okay";
 	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
-- 
2.30.2



From a.fatoum at pengutronix.de  Thu Aug 26 07:50:17 2021
From: a.fatoum at pengutronix.de (Ahmad Fatoum)
Date: Thu, 26 Aug 2021 16:50:17 +0200
Subject: [PATCH] ARM: dts: stm32: set the DCMI pins on stm32mp157c-odyssey
In-Reply-To: <YSepFyt8o+5lAsrA@nx64de-df6d00>
References: <YSepFyt8o+5lAsrA@nx64de-df6d00>
Message-ID: <6e6f91ab-d2b7-69d2-ccfb-6282945e5ab6@pengutronix.de>

On 26.08.21 16:45, Grzegorz Szymaszek wrote:
> The Seeed Odyssey-STM32MP157C board has a 20-pin DVP camera output. The
> DCMI pins used on this output are defined in the pin state definition
> &pinctrl/dcmi-1, AKA &dcmi_pins_b (added in mainline commit
> 02814a41529a55dbfb9fbb2a3728e78e70646ea6). Set these pins as the default
> pinctrl of the DCMI peripheral in the board device tree.
> 
> The pins are not used for any other purpose, so it seems safe to assume
> most users will not need to override (delete) what this patch provides.
> status defaults to "disabled", so the peripheral will not be
> unnecessarily started. And the users who actually intend to make use of
> a camera on the DVP port will have this little part of the configuration
> ready.
> 
> Signed-off-by: Grzegorz Szymaszek <gszymaszek at short.pl>

Reviewed-by: Ahmad Fatoum <a.fatoum at pengutronix.de>

> ---
>  arch/arm/boot/dts/stm32mp157c-odyssey.dts | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts
> index be1dd5e9e744..554f5d3bcdc3 100644
> --- a/arch/arm/boot/dts/stm32mp157c-odyssey.dts
> +++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts
> @@ -22,6 +22,12 @@ chosen {
>  	};
>  };
>  
> +&dcmi {
> +	pinctrl-names = "default", "sleep";
> +	pinctrl-0 = <&dcmi_pins_b>;
> +	pinctrl-1 = <&dcmi_sleep_pins_b>;
> +};
> +
>  &ethernet0 {
>  	status = "okay";
>  	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
> 


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jens.wiklander at linaro.org  Thu Aug 26 07:52:13 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 26 Aug 2021 16:52:13 +0200
Subject: [PATCH v4 5/5] optee: add FF-A support
In-Reply-To: <CAFA6WYNHrej1_yMZejLpG5u1WjN5XvpmS-zKWdLVZu=DEWd6xA@mail.gmail.com>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
 <20210819110655.739318-6-jens.wiklander@linaro.org>
 <CAFA6WYNHrej1_yMZejLpG5u1WjN5XvpmS-zKWdLVZu=DEWd6xA@mail.gmail.com>
Message-ID: <20210826145213.GA1739293@jade>

On Wed, Aug 25, 2021 at 05:12:45PM +0530, Sumit Garg wrote:
> On Thu, 19 Aug 2021 at 16:37, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> >
> > Adds support for using FF-A [1] as transport to the OP-TEE driver.
> >
> > Introduces struct optee_msg_param_fmem which carries all information
> > needed when OP-TEE is calling FFA_MEM_RETRIEVE_REQ to get the shared
> > memory reference mapped by the hypervisor in S-EL2. Register usage is
> > also updated to include the information needed.
> >
> > The FF-A part of this driver is enabled if CONFIG_ARM_FFA_TRANSPORT is
> > enabled.
> >
> > [1] https://developer.arm.com/documentation/den0077/latest
> > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > ---
> >  drivers/tee/optee/Makefile        |   3 +-
> >  drivers/tee/optee/call.c          |  13 +-
> >  drivers/tee/optee/core.c          |  16 +-
> >  drivers/tee/optee/ffa_abi.c       | 907 ++++++++++++++++++++++++++++++
> >  drivers/tee/optee/optee_ffa.h     | 153 +++++
> >  drivers/tee/optee/optee_msg.h     |  27 +-
> >  drivers/tee/optee/optee_private.h |  43 +-
> >  7 files changed, 1148 insertions(+), 14 deletions(-)
> >  create mode 100644 drivers/tee/optee/ffa_abi.c
> >  create mode 100644 drivers/tee/optee/optee_ffa.h
> >
[snip]
> > --- /dev/null
> > +++ b/drivers/tee/optee/ffa_abi.c
> > @@ -0,0 +1,907 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (c) 2021, Linaro Limited
> > + */
> > +
> > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > +
> > +#include <linux/arm_ffa.h>
> > +#include <linux/errno.h>
> > +#include <linux/scatterlist.h>
> > +#include <linux/sched.h>
> > +#include <linux/slab.h>
> > +#include <linux/string.h>
> > +#include <linux/tee_drv.h>
> > +#include <linux/types.h>
> > +#include "optee_private.h"
> > +#include "optee_ffa.h"
> > +#include "optee_rpc_cmd.h"
> > +
> > +/*
> > + * This file implement the FF-A ABI used when communicating with secure world
> > + * OP-TEE OS via FF-A.
> > + * This file is divided into the follow sections:
> 
> s/follow/following/

Thanks, I'll fix.

[snip]
> > +static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev,
> > +                                   const struct ffa_dev_ops *ops,
> > +                                   unsigned int *rpc_arg_count)
> > +{
> > +       struct ffa_send_direct_data data = { OPTEE_FFA_EXCHANGE_CAPABILITIES };
> > +       int rc;
> > +
> > +       rc = ops->sync_send_receive(ffa_dev, &data);
> > +       if (rc) {
> > +               pr_err("Unexpected error %d", rc);
> > +               return false;
> > +       }
> > +       if (data.data0) {
> > +               pr_err("Unexpected exchange error %lu", data.data0);
> > +               return false;
> > +       }
> > +
> > +       *rpc_arg_count = (u8)data.data1;
> 
> Why is this special capability required in case of FF-A? Is it true
> that RPC arguments count will be fixed for all RPC commands?

It's to allow this driver to preallocate the argument struct used when
doing RPC. That way we can avoid the chicken and egg problem of allocating
an RPC argumet struct just before doing the real RPC.

This is the maximum number of arguments needed by secure world. In case
a larger value ever is needed, secure world will be able to supply the
needed value.

I plan to update the SMC based ABI with this also, but not in the patch
set.

> 
> > +
> > +       return true;
> > +}

[snip]
> > +static int optee_ffa_probe(struct ffa_device *ffa_dev)
> > +{
> > +       const struct ffa_dev_ops *ffa_ops;
> > +       unsigned int rpc_arg_count;
> > +       struct tee_device *teedev;
> > +       struct optee *optee;
> > +       int rc;
> > +
> > +       ffa_ops = ffa_dev_ops_get(ffa_dev);
> > +       if (!ffa_ops) {
> > +               pr_warn("failed \"method\" init: ffa\n");
> > +               return -ENOENT;
> > +       }
> > +
> > +       if (!optee_ffa_api_is_compatbile(ffa_dev, ffa_ops))
> > +               return -EINVAL;
> > +
> > +       if (!optee_ffa_exchange_caps(ffa_dev, ffa_ops, &rpc_arg_count))
> > +               return -EINVAL;
> => +
> > +       optee = kzalloc(sizeof(*optee), GFP_KERNEL);
> > +       if (!optee) {
> > +               rc = -ENOMEM;
> > +               goto err;
> > +       }
> > +       optee->pool = optee_ffa_config_dyn_shm();
> > +       if (IS_ERR(optee->pool)) {
> > +               rc = PTR_ERR(optee->pool);
> > +               optee->pool = NULL;
> > +               goto err;
> > +       }
> 
> IIUC, with FF-A we will only be supporting dynamic shared memory. So
> CFG_CORE_DYN_SHM=y should be enforced in OP-TEE OS when
> CFG_CORE_FFA=y, but I don't see that currently. Am I missing
> something?

You mean in optee_os.git? With FF-A dynamic shared memory is always
handled, so that flag in irrelevant in that case. However, feel free to
start a discussion on that topic at github.

Thanks,
Jens


From pasha.tatashin at soleen.com  Thu Aug 26 08:03:21 2021
From: pasha.tatashin at soleen.com (Pavel Tatashin)
Date: Thu, 26 Aug 2021 11:03:21 -0400
Subject: [PATCH v16 00/15] arm64: MMU enabled kexec relocation
In-Reply-To: <20210824180555.GD623@arm.com>
References: <20210802215408.804942-1-pasha.tatashin@soleen.com>
 <20210824180555.GD623@arm.com>
Message-ID: <CA+CK2bCakwsqS1RqXPJr+ewe=gsO98cOxhXye8-AcRLwtqhZ+g@mail.gmail.com>

On Tue, Aug 24, 2021 at 2:06 PM Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> Hi Pavel,
>
> This series is still missing reviews from those who understand kexec
> better than me.

Hi Catalin,

Yes, I am looking for reviewers.

>
> On Mon, Aug 02, 2021 at 05:53:53PM -0400, Pavel Tatashin wrote:
> > Enable MMU during kexec relocation in order to improve reboot performance.
> >
> > If kexec functionality is used for a fast system update, with a minimal
> > downtime, the relocation of kernel + initramfs takes a significant portion
> > of reboot.
> >
> > The reason for slow relocation is because it is done without MMU, and thus
> > not benefiting from D-Cache.
>
> The performance improvements are indeed significant on some platforms
> (going from 7s to ~40ms), so I think the merging the series is worth it.
> Some general questions so I better understand the impact:
>
> - Is the kdump path affected in any way? IIUC that doesn't need any
>   relocation but we should also make sure we don't create the additional
>   page table unnecessarily (should keep as much memory intact as
>   possible). Maybe that's already handled.

Because kdump does not need relocation, we do not reserve pages for
the page table in the kdump reboot case. In fact, with this series,
kdump reboot becomes more straightforward as we skip the relocation
function entirely, and jump directly into the crash kernel (or
purgatory if kexec tools loaded them).

>
> - What happens if trans_pgd_create_copy() fails to allocate memory. Does
>   it fall back to an MMU-off relocation?

In case we are so low on memory that trans_pgd_create_copy() fails to
allocate the linear map that uses the large pages (the size of the
page table is tiny) the kexec fails during kexec load time (not during
reboot time), as out of memory. The MMU enabled kexec reboot is always
on, and we should not have several ways to do kexec reboot as it makes
the kexec reboot unpredictable in terms of performance, and also prone
to bugs by having a common MMU enabled path and less common path when
we are low on memory which is never tested.

>
> And I presume this series does not introduce any changes to the kexec
> tools ABI.

Correct.

Thanks for taking a look at this series.

Pasha


From s.riedmueller at phytec.de  Thu Aug 26 08:20:49 2021
From: s.riedmueller at phytec.de (Stefan Riedmueller)
Date: Thu, 26 Aug 2021 17:20:49 +0200
Subject: [PATCH 2/2] clk: imx: imx6ul: Fix csi clk gate register
In-Reply-To: <20210826152049.4175381-1-s.riedmueller@phytec.de>
References: <20210826152049.4175381-1-s.riedmueller@phytec.de>
Message-ID: <20210826152049.4175381-2-s.riedmueller@phytec.de>

According to the imx6ul Reference Manual the csi clk gate register is
CCM_CCGR3 (offset 0x74) bit 0/1. For the imx6ull on the other hand the
Reference Manual lists register CCM_CCGR2 (offset 0x70) bit 2/3 as the
csi clk gate which is the current setting.

Tests have shown though that the correct csi clk gate register for the
imx6ull is actually CCM_CCGR3 bit 0/1 as well. Thus set the correct
register for both platforms.

Signed-off-by: Stefan Riedmueller <s.riedmueller at phytec.de>
---
 drivers/clk/imx/clk-imx6ul.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index 206e4c43f68f..5dd222fab01b 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -380,7 +380,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 		hws[IMX6ULL_CLK_ESAI_IPG]	= imx_clk_hw_gate2_shared("esai_ipg",	"ahb",		base + 0x70,	0, &share_count_esai);
 		hws[IMX6ULL_CLK_ESAI_MEM]	= imx_clk_hw_gate2_shared("esai_mem",	"ahb",		base + 0x70,	0, &share_count_esai);
 	}
-	hws[IMX6UL_CLK_CSI]		= imx_clk_hw_gate2("csi",		"csi_podf",		base + 0x70,	2);
 	hws[IMX6UL_CLK_I2C1]		= imx_clk_hw_gate2("i2c1",		"perclk",	base + 0x70,	6);
 	hws[IMX6UL_CLK_I2C2]		= imx_clk_hw_gate2("i2c2",		"perclk",	base + 0x70,	8);
 	hws[IMX6UL_CLK_I2C3]		= imx_clk_hw_gate2("i2c3",		"perclk",	base + 0x70,	10);
@@ -391,6 +390,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	hws[IMX6UL_CLK_PXP]		= imx_clk_hw_gate2("pxp",		"axi",		base + 0x70,	30);
 
 	/* CCGR3 */
+	hws[IMX6UL_CLK_CSI]		= imx_clk_hw_gate2("csi",	"csi_podf",	base + 0x74,	0);
 	hws[IMX6UL_CLK_UART5_IPG]	= imx_clk_hw_gate2("uart5_ipg",	"ipg",		base + 0x74,	2);
 	hws[IMX6UL_CLK_UART5_SERIAL]	= imx_clk_hw_gate2("uart5_serial",	"uart_podf",	base + 0x74,	2);
 	if (clk_on_imx6ul()) {
-- 
2.25.1



From s.riedmueller at phytec.de  Thu Aug 26 08:20:48 2021
From: s.riedmueller at phytec.de (Stefan Riedmueller)
Date: Thu, 26 Aug 2021 17:20:48 +0200
Subject: [PATCH 1/2] clk: imx: imx6ul: Move csi_sel mux to correct base
 register
Message-ID: <20210826152049.4175381-1-s.riedmueller@phytec.de>

The csi_sel mux register is located in the CCM register base and not the
CCM_ANALOG register base. So move it to the correct position in code.

Otherwise changing the parent of the csi clock can lead to a complete
system failure due to the CCM_ANALOG_PLL_SYS_TOG register being falsely
modified.

Also remove the SET_RATE_PARENT flag since one possible supply for the
csi_sel mux is the system PLL which we don't want to modify.

Signed-off-by: Stefan Riedmueller <s.riedmueller at phytec.de>
---
 drivers/clk/imx/clk-imx6ul.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index 5dbb6a937732..206e4c43f68f 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -161,7 +161,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	hws[IMX6UL_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX6UL_PLL6_BYPASS] = imx_clk_hw_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT);
 	hws[IMX6UL_PLL7_BYPASS] = imx_clk_hw_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT);
-	hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels), CLK_SET_RATE_PARENT);
 
 	/* Do not bypass PLLs initially */
 	clk_set_parent(hws[IMX6UL_PLL1_BYPASS]->clk, hws[IMX6UL_CLK_PLL1]->clk);
@@ -270,6 +269,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	hws[IMX6UL_CLK_ECSPI_SEL]	  = imx_clk_hw_mux("ecspi_sel",	base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
 	hws[IMX6UL_CLK_LCDIF_PRE_SEL]	  = imx_clk_hw_mux_flags("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels), CLK_SET_RATE_PARENT);
 	hws[IMX6UL_CLK_LCDIF_SEL]	  = imx_clk_hw_mux("lcdif_sel",	base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels));
+	hws[IMX6UL_CLK_CSI_SEL]		  = imx_clk_hw_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
 
 	hws[IMX6UL_CLK_LDB_DI0_DIV_SEL]  = imx_clk_hw_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels));
 	hws[IMX6UL_CLK_LDB_DI1_DIV_SEL]  = imx_clk_hw_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
-- 
2.25.1



From dqfext at gmail.com  Thu Aug 26 08:27:37 2021
From: dqfext at gmail.com (DENG Qingfang)
Date: Thu, 26 Aug 2021 23:27:37 +0800
Subject: [RFC net-next 2/2] net: dsa: tag_mtk: handle VLAN tag insertion
 on TX
In-Reply-To: <20210826141326.xa52776uh3r3jpg4@skbuf>
References: <20210825083832.2425886-1-dqfext@gmail.com>
 <20210825083832.2425886-3-dqfext@gmail.com>
 <20210826000349.q3s5gjuworxtbcna@skbuf>
 <20210826052956.3101243-1-dqfext@gmail.com>
 <20210826141326.xa52776uh3r3jpg4@skbuf>
Message-ID: <20210826152737.3280662-1-dqfext@gmail.com>

On Thu, Aug 26, 2021 at 05:13:26PM +0300, Vladimir Oltean wrote:
> On Thu, Aug 26, 2021 at 01:29:56PM +0800, DENG Qingfang wrote:
> > 
> > The comment says the VLAN tag need to be combined with the special tag in
> > order to perform VLAN table lookup,
> 
> It does say this.
> 
> > so we can set its destination port vector to all zeroes and the switch
> > will forward it like a data frame (TX forward offload),
> 
> And it does not say this. So this is supported after all with mt7530?
> Are you looking to add support for that?

I already run-tested that, it works, as long as there is only one bridge.

> 
> > but as we allow multiple bridges which are either VLAN-unaware or
> > VLAN-aware with the same VID, there is no way to determine the
> > destination bridge unless we maintain some VLAN translation mapping.
> 
> What does "VLAN translation mapping" mean, practically?

It's just VLAN remapping, as you stated below.

> Other drivers which cannot remap VIDs to internal VLANs just restrict a
> single VLAN-aware bridge, and potentially multiple VLAN-unaware ones.


From stern at rowland.harvard.edu  Thu Aug 26 08:28:24 2021
From: stern at rowland.harvard.edu (Alan Stern)
Date: Thu, 26 Aug 2021 11:28:24 -0400
Subject: [PATCH] usb: host: ehci: skip STS_HALT check for aspeed platform
In-Reply-To: <20210826071525.27651-1-neal_liu@aspeedtech.com>
References: <20210826071525.27651-1-neal_liu@aspeedtech.com>
Message-ID: <20210826152824.GC228824@rowland.harvard.edu>

On Thu, Aug 26, 2021 at 03:15:25PM +0800, neal_liu wrote:
> STS_HALT also depends on ASS/PSS status for apseed.
> Skip this check on startup.
> 
> Signed-off-by: neal_liu <neal_liu at aspeedtech.com>
> ---
>  drivers/usb/host/ehci-hcd.c      | 10 +++++++++-
>  drivers/usb/host/ehci-platform.c |  6 ++++++
>  drivers/usb/host/ehci.h          |  1 +
>  3 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index 10b0365f3439..a539e11502ef 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -634,7 +634,15 @@ static int ehci_run (struct usb_hcd *hcd)
>  	/* Wait until HC become operational */
>  	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
>  	msleep(5);
> -	rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000);
> +
> +	/* For Aspeed, STS_HALT also depends on ASS/PSS status.
> +	 * Skip this check on startup.
> +	 */
> +	if (ehci->is_aspeed)
> +		rc = 0;
> +	else
> +		rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT,
> +				    0, 100 * 1000);

You must not do this.  You are assuming the controller will always begin 
operating within 5 ms of the time it is told to start.  What happens if you are 
wrong?

There must be some way for the aspeed controller's host computer to tell when 
the controller has started running.  Find out what it is and use it.

Alan Stern


From linux at roeck-us.net  Thu Aug 26 08:49:03 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 26 Aug 2021 08:49:03 -0700
Subject: [PATCH] coresight: syscfg: fix compiler warnings
In-Reply-To: <20210825222514.2107728-1-jiancai@google.com>
References: <20210825222514.2107728-1-jiancai@google.com>
Message-ID: <20210826154903.GA4082743@roeck-us.net>

On Wed, Aug 25, 2021 at 03:25:14PM -0700, Jian Cai wrote:
> This fixes warnings with -Wimplicit-function-declaration, e.g.
> 
> ^[[1m/mnt/host/source/src/third_party/kernel/v5.4/drivers/hwtracing/coresight/coresight-syscfg.c:455:15: ^[[0m^[[0;1;31merror: ^[[0m^[[1mimplicit declaration of function 'kzalloc' [-Werror,-Wimplicit-function-declaration]^[[0m
>         csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
> ^[[0;1;32m                     ^

You might want to split this into multiple lines and remove the ANSI
escape codes. Otherwise

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

Guenter

> 
> Signed-off-by: Jian Cai <jiancai at google.com>
> ---
>  drivers/hwtracing/coresight/coresight-syscfg.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> index fc0760f55c53..43054568430f 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> @@ -5,6 +5,7 @@
>   */
>  
>  #include <linux/platform_device.h>
> +#include <linux/slab.h>
>  
>  #include "coresight-config.h"
>  #include "coresight-etm-perf.h"
> -- 
> 2.33.0.259.gc128427fd7-goog
> 


From broonie at kernel.org  Thu Aug 26 08:46:34 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 26 Aug 2021 16:46:34 +0100
Subject: [RFC PATCH v8 2/4] arm64: Reorganize the unwinder code for
 better consistency and maintenance
In-Reply-To: <20210812190603.25326-3-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-3-madvenka@linux.microsoft.com>
Message-ID: <YSe3WogpFIu97i/7@sirena.org.uk>

On Thu, Aug 12, 2021 at 02:06:01PM -0500, madvenka at linux.microsoft.com wrote:

> Renaming of unwinder functions
> ==============================

> Rename unwinder functions to unwind_*() similar to other architectures
> for naming consistency. More on this below.

This feels like it could probably do with splitting up a bit for
reviewability, several of these headers you've got in the commit
logs look like they could be separate commits.  Splitting things
up does help with reviewability, having only one change to keep
in mind at once is a lot less cognative load.

> Replace walk_stackframe() with unwind()
> =======================================
> 
> walk_stackframe() contains the unwinder loop that walks the stack
> frames. Currently, start_backtrace() and walk_stackframe() are called
> separately. They should be combined in the same function. Also, the
> loop in walk_stackframe() should be simplified and should look like
> the unwind loops in other architectures such as X86 and S390.

This definitely seems like a separate change.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210826/6c3c15db/attachment.sig>

From broonie at kernel.org  Thu Aug 26 08:57:04 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 26 Aug 2021 16:57:04 +0100
Subject: [RFC PATCH v8 3/4] arm64: Introduce stack trace reliability
 checks in the unwinder
In-Reply-To: <20210812190603.25326-4-madvenka@linux.microsoft.com>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-4-madvenka@linux.microsoft.com>
Message-ID: <YSe50PuWM/mjNwAj@sirena.org.uk>

On Thu, Aug 12, 2021 at 02:06:02PM -0500, madvenka at linux.microsoft.com wrote:

> +	if (frame->need_reliable && !unwind_is_reliable(frame)) {
> +		/* Cannot unwind to the next frame reliably. */
> +		frame->failed = true;
> +		return false;
> +	}

This means we only collect reliability information in the case
where we're specifically doing a reliable stacktrace.  For
example when printing stack traces on the console it might be
useful to print a ? or something if the frame is unreliable as a
hint to the reader that the information might be misleading.
Could we therefore change the flag here to a reliability one and
our need_reliable check so that we always run
unwind_is_reliable()?

I'm not sure if we need to abandon the trace on first error when
doing a reliable trace but I can see it's a bit safer so perhaps
better to do so.  If we don't abandon then we don't require the
need_reliable check at all.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210826/7f122cca/attachment.sig>

From dianders at chromium.org  Thu Aug 26 09:19:44 2021
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 26 Aug 2021 09:19:44 -0700
Subject: [PATCH] coresight: syscfg: fix compiler warnings
In-Reply-To: <20210825222514.2107728-1-jiancai@google.com>
References: <20210825222514.2107728-1-jiancai@google.com>
Message-ID: <CAD=FV=VAkWz0QSN7GivNrkv9uv3JKisush4C+Tb-PMpNokt8Wg@mail.gmail.com>

Hi,

On Wed, Aug 25, 2021 at 3:25 PM Jian Cai <jiancai at google.com> wrote:
>
> This fixes warnings with -Wimplicit-function-declaration, e.g.
>
> ^[[1m/mnt/host/source/src/third_party/kernel/v5.4/drivers/hwtracing/coresight/coresight-syscfg.c:455:15: ^[[0m^[[0;1;31merror: ^[[0m^[[1mimplicit declaration of function 'kzalloc' [-Werror,-Wimplicit-function-declaration]^[[0m
>         csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
> ^[[0;1;32m                     ^
>
> Signed-off-by: Jian Cai <jiancai at google.com>
> ---
>  drivers/hwtracing/coresight/coresight-syscfg.c | 1 +
>  1 file changed, 1 insertion(+)

Can you figure out which patch introduced these warnings and add a "Fixes" tag?

-Doug


From linux at roeck-us.net  Thu Aug 26 09:30:07 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 26 Aug 2021 09:30:07 -0700
Subject: [PATCH] coresight: syscfg: fix compiler warnings
In-Reply-To: <CAD=FV=VAkWz0QSN7GivNrkv9uv3JKisush4C+Tb-PMpNokt8Wg@mail.gmail.com>
References: <20210825222514.2107728-1-jiancai@google.com>
 <CAD=FV=VAkWz0QSN7GivNrkv9uv3JKisush4C+Tb-PMpNokt8Wg@mail.gmail.com>
Message-ID: <a9aa266a-7481-a991-508b-8c32cd03f519@roeck-us.net>

On 8/26/21 9:19 AM, Doug Anderson wrote:
> Hi,
> 
> On Wed, Aug 25, 2021 at 3:25 PM Jian Cai <jiancai at google.com> wrote:
>>
>> This fixes warnings with -Wimplicit-function-declaration, e.g.
>>
>> ^[[1m/mnt/host/source/src/third_party/kernel/v5.4/drivers/hwtracing/coresight/coresight-syscfg.c:455:15: ^[[0m^[[0;1;31merror: ^[[0m^[[1mimplicit declaration of function 'kzalloc' [-Werror,-Wimplicit-function-declaration]^[[0m
>>          csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL);
>> ^[[0;1;32m                     ^
>>
>> Signed-off-by: Jian Cai <jiancai at google.com>
>> ---
>>   drivers/hwtracing/coresight/coresight-syscfg.c | 1 +
>>   1 file changed, 1 insertion(+)
> 
> Can you figure out which patch introduced these warnings and add a "Fixes" tag?
> 

Assuming the SHA is stable, that would be commit 85e2414c518a
("coresight: syscfg: Initial coresight system configuration")

Guenter


From ardb at kernel.org  Thu Aug 26 09:34:40 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 26 Aug 2021 18:34:40 +0200
Subject: [RFC PATCH] arm64: mm: limit linear region to 51 bits for KVM in
 nVHE mode
In-Reply-To: <20210826133118.GC30910@arm.com>
References: <20210810161244.84231-1-ardb@kernel.org>
 <20210824105920.GB22752@willie-the-truck>
 <20210826133118.GC30910@arm.com>
Message-ID: <CAMj1kXH9XswHUHZgZYjomaPHFOFQHJBOAuU9OndAt0tfORFVQw@mail.gmail.com>

On Thu, 26 Aug 2021 at 15:31, Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> On Tue, Aug 24, 2021 at 11:59:20AM +0100, Will Deacon wrote:
> > On Tue, Aug 10, 2021 at 06:12:44PM +0200, Ard Biesheuvel wrote:
> > > KVM in nVHE mode divides up its VA space into two equal halves, and
> > > picks the half that does not conflict with the HYP ID map to map its
> > > linear region. This worked fine when the kernel's linear map itself was
> > > guaranteed to cover precisely as many bits of VA space, but this was
> > > changed by commit f4693c2716b35d08 ("arm64: mm: extend linear region for
> > > 52-bit VA configurations").
> > >
> > > The result is that, depending on the placement of the ID map, kernel-VA
> > > to hyp-VA translations may produce addresses that either conflict with
> > > other HYP mappings (including the ID map itself) or generate addresses
> > > outside of the 52-bit addressable range, neither of which is likely to
> > > lead to anything useful.
> > >
> > > Given that 52-bit capable cores are guaranteed to implement VHE, this
> > > only affects configurations such as pKVM where we opt into non-VHE mode
> > > even if the hardware is VHE capable. So just for these configurations,
> > > let's limit the kernel linear map to 51 bits and work around the
> > > problem.
> > >
> > > Fixes:f4693c2716b35d08 ("arm64: mm: extend linear region for 52-bit VA configurations")
> > > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> > > ---
> > > NOTE: build tested only
> > >
> > >  arch/arm64/mm/init.c | 16 +++++++++++++++-
> > >  1 file changed, 15 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> > > index 8490ed2917ff..542dad13e2fc 100644
> > > --- a/arch/arm64/mm/init.c
> > > +++ b/arch/arm64/mm/init.c
> > > @@ -282,7 +282,21 @@ static void __init fdt_enforce_memory_region(void)
> > >
> > >  void __init arm64_memblock_init(void)
> > >  {
> > > -   const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > > +   s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
> > > +
> > > +   /*
> > > +    * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
> > > +    * be limited in their ability to support a linear map that exceeds 51
> > > +    * bits of VA space, depending on the placement of the ID map. Given
> > > +    * that the placement of the ID map may be randomized, let's simply
> > > +    * limit the kernel's linear map to 51 bits as well if we detect this
> > > +    * configuration.
> > > +    */
> > > +   if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 &&
> > > +       !is_kernel_in_hyp_mode()) {
> > > +           pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n");
> > > +           linear_region_size = BIT(51);
> > > +   }
> >
> > Slight nit, but to avoid having to think about PAGE_END I think this would
> > be a little clearer as:
> >
> >       if (IS_ENABLED(CONFIG_KVM) && !is_kernel_in_hyp_mode())
> >               linear_region_size = min_t(u64, linear_region_size, BIT(51));
>
> BTW, do we also need to check is_hyp_mode_available() (instead of just
> CONFIG_KVM)? We don't need this reduction for a guest.
>

Hmm, good point. I'll respin with both suggestions incorporated.


From mathieu.poirier at linaro.org  Thu Aug 26 09:41:31 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 26 Aug 2021 10:41:31 -0600
Subject: [PATCHv2 4/4] coresight: Add ETR-PERF polling.
In-Reply-To: <20210713121532.836244-5-daniel.kiss@arm.com>
References: <20210713121532.836244-1-daniel.kiss@arm.com>
 <20210713121532.836244-5-daniel.kiss@arm.com>
Message-ID: <20210826164131.GA808387@p14s>

Good day,

On Tue, Jul 13, 2021 at 02:15:32PM +0200, Daniel Kiss wrote:
> ETR might fill up the buffer sooner than an event makes perf to trigger
> the synchronisation especially in system wide trace. Polling runs
> periodically to sync the ETR buffer. Period is configurable via sysfs,
> disabled by default.
> 
> Signed-off-by: Daniel Kiss <daniel.kiss at arm.com>
> Signed-off-by: Branislav Rankov <Branislav.Rankov at arm.com>
> Tested-by: Denis Nikitin <denik at chromium.org>
> ---
>  .../testing/sysfs-bus-coresight-devices-tmc   |   8 +
>  drivers/hwtracing/coresight/Kconfig           |  12 +
>  drivers/hwtracing/coresight/Makefile          |   1 +
>  .../hwtracing/coresight/coresight-etm-perf.c  |   8 +
>  .../coresight/coresight-etr-perf-polling.c    | 275 ++++++++++++++++++
>  .../coresight/coresight-etr-perf-polling.h    |  38 +++
>  .../hwtracing/coresight/coresight-tmc-core.c  |   4 +
>  .../hwtracing/coresight/coresight-tmc-etr.c   |  13 +
>  8 files changed, 359 insertions(+)
>  create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> index 6aa527296c710..3b411e8a6f417 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> @@ -91,3 +91,11 @@ Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
>  Description:	(RW) Size of the trace buffer for TMC-ETR when used in SYSFS
>  		mode. Writable only for TMC-ETR configurations. The value
>  		should be aligned to the kernel pagesize.
> +
> +What:		/sys/bus/coresight/devices/<memory_map>.tmc/polling/period
> +Date:		July 2021
> +KernelVersion:	5.14
> +Contact:	Daniel Kiss <daniel.kiss at arm.com>
> +Description:	(RW) Time in milliseconds when the TMC-ETR is synced.
> +		Default value is 0, means the feature is disabled.
> +		Writable only for TMC-ETR configurations.

The problem with the current implementation is that period is global to all
tracing sessions.  Moreover it seems possible to change the value of a period
while a session is ongoing, which is guaranteed to confuse users.

A better way to proceed is to make the period a perf configurable option the
same way timestamp and ccyacc are.  Look at the top of coresight-etm-perf.c for
examples.  This might be the last time we use configuration attributes, after
that we should start using Mike Leach's new system configuration feature.

> diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
> index 84530fd80998c..4e91fb98849f4 100644
> --- a/drivers/hwtracing/coresight/Kconfig
> +++ b/drivers/hwtracing/coresight/Kconfig
> @@ -44,6 +44,18 @@ config CORESIGHT_LINK_AND_SINK_TMC
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called coresight-tmc.
>  
> +
> +config CORESIGHT_ETR_PERF_POLL
> +	bool "Coresight ETR Perf Polling"
> +
> +	depends on CORESIGHT_LINK_AND_SINK_TMC
> +	help
> +	  Enable the support for software periodic synchronization of the ETR buffer.
> +	  ETR might fill up the buffer sooner than an event makes perf to trigger
> +	  the synchronization especially in system wide trace. Polling runs
> +	  periodically to sync the ETR buffer. Period is configurable via sysfs,
> +	  disabled by default.
> +

Polling should be part of the core and not a configurable option.

More comments to come...

>  config CORESIGHT_CATU
>  	tristate "Coresight Address Translation Unit (CATU) driver"
>  	depends on CORESIGHT_LINK_AND_SINK_TMC
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index d60816509755c..6baac328eea87 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -5,6 +5,7 @@
>  obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
>  		coresight-sysfs.o
> +coresight-$(CONFIG_CORESIGHT_ETR_PERF_POLL) += coresight-etr-perf-polling.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
>  		      coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index a3f4c07f5bf8b..3095840a567c4 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -19,6 +19,7 @@
>  #include <linux/workqueue.h>
>  
>  #include "coresight-etm-perf.h"
> +#include "coresight-etr-perf-polling.h"
>  #include "coresight-priv.h"
>  
>  static struct pmu etm_pmu;
> @@ -438,6 +439,8 @@ static void etm_event_start(struct perf_event *event, int flags)
>  	/* Tell the perf core the event is alive */
>  	event->hw.state = 0;
>  
> +	etr_perf_polling_event_start(event, event_data, handle);
> +
>  	/* Finally enable the tracer */
>  	if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF))
>  		goto fail_disable_path;
> @@ -497,6 +500,8 @@ static void etm_event_stop(struct perf_event *event, int mode)
>  	if (!sink)
>  		return;
>  
> +	etr_perf_polling_event_stop(event, event_data);
> +
>  	/* stop tracer */
>  	source_ops(csdev)->disable(csdev, event);
>  
> @@ -741,6 +746,8 @@ int __init etm_perf_init(void)
>  	etm_pmu.addr_filters_validate	= etm_addr_filters_validate;
>  	etm_pmu.nr_addr_filters		= ETM_ADDR_CMP_MAX;
>  
> +	etr_perf_polling_init();
> +
>  	ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
>  	if (ret == 0)
>  		etm_perf_up = true;
> @@ -750,5 +757,6 @@ int __init etm_perf_init(void)
>  
>  void __exit etm_perf_exit(void)
>  {
> +	etr_perf_polling_exit();
>  	perf_pmu_unregister(&etm_pmu);
>  }
> diff --git a/drivers/hwtracing/coresight/coresight-etr-perf-polling.c b/drivers/hwtracing/coresight/coresight-etr-perf-polling.c
> new file mode 100644
> index 0000000000000..87e6bc42a62de
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-etr-perf-polling.c
> @@ -0,0 +1,275 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(C) 2021 Arm Limited. All rights reserved.
> + * Author: Daniel Kiss <daniel.kiss at arm.com>
> + */
> +
> +#include <linux/coresight.h>
> +#include <linux/coresight-pmu.h>
> +#include <linux/cpumask.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/list.h>
> +#include <linux/percpu-defs.h>
> +#include <linux/perf_event.h>
> +#include <linux/slab.h>
> +#include <linux/stringhash.h>
> +#include <linux/types.h>
> +#include <linux/workqueue.h>
> +
> +#include "coresight-etr-perf-polling.h"
> +#include "coresight-priv.h"
> +#include "coresight-tmc.h"
> +
> +struct polling_event_list {
> +	struct perf_event *perf_event;
> +	struct etm_event_data *etm_event_data;
> +	struct perf_output_handle *ctx_handle;
> +	void (*tmc_etr_reset_hw)(struct tmc_drvdata *data);
> +	struct list_head list;
> +};
> +
> +struct polling {
> +	int cpu;
> +	struct polling_event_list *polled_event;
> +	struct delayed_work delayed_work;
> +};
> +
> +static atomic_t period;
> +static spinlock_t spinlock_re;
> +static struct list_head registered_events;
> +
> +static DEFINE_PER_CPU(struct polling, polling);
> +
> +static ssize_t period_show(struct device *dev, struct device_attribute *attr,
> +			   char *buf)
> +{
> +	int temp;
> +
> +	temp = atomic_read(&period);
> +	return sprintf(buf, "%i\n", temp);
> +}
> +
> +static ssize_t period_store(struct device *dev, struct device_attribute *attr,
> +			    const char *buf, size_t count)
> +{
> +	int temp = 0;
> +
> +	if (!kstrtoint(buf, 10, &temp) && (temp >= 0))
> +		atomic_set(&period, temp);
> +	return count;
> +}
> +
> +static DEVICE_ATTR_RW(period);
> +
> +static struct attribute *coresight_tmc_polling_attrs[] = {
> +	&dev_attr_period.attr,
> +	NULL,
> +};
> +const struct attribute_group coresight_tmc_polling_group = {
> +	.attrs = coresight_tmc_polling_attrs,
> +	.name = "polling",
> +};
> +EXPORT_SYMBOL_GPL(coresight_tmc_polling_group);
> +
> +static inline void polling_sched_worker(struct polling *p)
> +{
> +	int tickrate = atomic_read(&period);
> +
> +	if (tickrate > 0)
> +		schedule_delayed_work_on(p->cpu, &p->delayed_work,
> +					 msecs_to_jiffies(tickrate));
> +}
> +
> +static inline bool is_etr_related(struct etm_event_data *etm_event_data, int cpu)
> +{
> +	struct list_head *path;
> +	struct coresight_device *sink;
> +	struct tmc_drvdata *drvdata;
> +
> +	path = etm_event_cpu_path(etm_event_data, cpu);
> +	if (WARN_ON(!path))
> +		return false;
> +	sink = coresight_get_sink(path);
> +	if (WARN_ON(!sink))
> +		return false;
> +	drvdata = dev_get_drvdata(sink->dev.parent);
> +	if (drvdata->config_type != TMC_CONFIG_TYPE_ETR)
> +		return false;
> +	return true;
> +}
> +
> +/*
> + * Adds the event to the polled events list.
> + */
> +void etr_perf_polling_event_start(struct perf_event *event,
> +				  struct etm_event_data *etm_event_data,
> +				  struct perf_output_handle *ctx_handle)
> +{
> +	int cpu = smp_processor_id();
> +	struct polling *p = per_cpu_ptr(&polling, cpu);
> +	struct polling_event_list *element, *tmp;
> +
> +	if (!is_etr_related(etm_event_data, cpu))
> +		return;
> +
> +	spin_lock(&spinlock_re);
> +	list_for_each_entry_safe(element, tmp, &registered_events, list) {
> +		if (element->ctx_handle == ctx_handle) {
> +			element->perf_event = event;
> +			element->etm_event_data = etm_event_data;
> +			spin_unlock(&spinlock_re);
> +			p->polled_event = element;
> +			polling_sched_worker(p);
> +			return;
> +		}
> +	}
> +	spin_unlock(&spinlock_re);
> +}
> +
> +/*
> + * Removes the event from the to be polled events list.
> + */
> +void etr_perf_polling_event_stop(struct perf_event *event,
> +				 struct etm_event_data *etm_event_data)
> +{
> +	int cpu = smp_processor_id();
> +	struct polling *p = per_cpu_ptr(&polling, cpu);
> +
> +	if (!is_etr_related(etm_event_data, cpu))
> +		return;
> +
> +	if (p->polled_event) {
> +		struct polling_event_list *element = p->polled_event;
> +
> +		if (element->perf_event == event) {
> +			p->polled_event = NULL;
> +			element->perf_event = NULL;
> +			element->etm_event_data = NULL;
> +			cancel_delayed_work(&p->delayed_work);
> +			return;
> +		}
> +	}
> +}
> +
> +/*
> + * The polling worker is a workqueue job which is periodically
> + * woken up to update the perf aux buffer from the etr shrink.
> + */
> +static void etr_perf_polling_worker(struct work_struct *work)
> +{
> +	unsigned long flags;
> +	struct list_head *path;
> +	struct coresight_device *sink;
> +	int size;
> +	int cpu = smp_processor_id();
> +	struct polling *p = per_cpu_ptr(&polling, cpu);
> +
> +	if (!atomic_read(&period))
> +		return;
> +
> +	if (!p->polled_event)
> +		return;
> +	/*
> +	 * Scheduling would do the same from the perf hooks,
> +	 * this should be done in one go.
> +	 */
> +	local_irq_save(flags);
> +
> +	polling_sched_worker(p);
> +
> +	path = etm_event_cpu_path(p->polled_event->etm_event_data, cpu);
> +	sink = coresight_get_sink(path);
> +	size = sink_ops(sink)->update_buffer(
> +		sink, p->polled_event->ctx_handle,
> +		p->polled_event->etm_event_data->snk_config);
> +
> +	/*
> +	 * Restart the trace.
> +	 */
> +	if (p->polled_event->tmc_etr_reset_hw)
> +		p->polled_event->tmc_etr_reset_hw(dev_get_drvdata(sink->dev.parent));
> +
> +	WARN_ON(size < 0);
> +	if (size > 0) {
> +		struct etm_event_data *new_event_data;
> +
> +		perf_aux_output_end(p->polled_event->ctx_handle, size);
> +		new_event_data = perf_aux_output_begin(
> +			p->polled_event->ctx_handle,
> +			p->polled_event->perf_event);
> +		if (WARN_ON(new_event_data == NULL)) {
> +			local_irq_restore(flags);
> +			return;
> +		}
> +
> +		p->polled_event->etm_event_data = new_event_data;
> +		WARN_ON(new_event_data->snk_config !=
> +			p->polled_event->etm_event_data->snk_config);
> +	}
> +
> +	local_irq_restore(flags);
> +}
> +
> +void etr_perf_polling_handle_register(struct perf_output_handle *handle,
> +				      void (*tmc_etr_reset_hw)(struct tmc_drvdata *drvdata))
> +{
> +	struct polling_event_list *element;
> +
> +	element = kmalloc(sizeof(*element), GFP_ATOMIC);
> +	if (WARN_ON(!element))
> +		return;
> +	memset(element, 0, sizeof(*element));
> +	element->ctx_handle = handle;
> +	element->tmc_etr_reset_hw = tmc_etr_reset_hw;
> +	spin_lock(&spinlock_re);
> +	list_add(&element->list, &registered_events);
> +	spin_unlock(&spinlock_re);
> +}
> +EXPORT_SYMBOL_GPL(etr_perf_polling_handle_register);
> +
> +void etr_perf_polling_handle_deregister(struct perf_output_handle *handle)
> +{
> +	struct polling_event_list *element, *tmp;
> +
> +	spin_lock(&spinlock_re);
> +	list_for_each_entry_safe(element, tmp, &registered_events, list) {
> +		if (element->ctx_handle == handle) {
> +			list_del(&element->list);
> +			spin_unlock(&spinlock_re);
> +			kfree(element);
> +			return;
> +		}
> +	}
> +	spin_unlock(&spinlock_re);
> +}
> +EXPORT_SYMBOL_GPL(etr_perf_polling_handle_deregister);
> +
> +void etr_perf_polling_init(void)
> +{
> +	int cpu;
> +
> +	spin_lock_init(&spinlock_re);
> +	INIT_LIST_HEAD(&registered_events);
> +	atomic_set(&period, 0);
> +	for_each_possible_cpu(cpu) {
> +		struct polling *p = per_cpu_ptr(&polling, cpu);
> +
> +		p->cpu = cpu;
> +		p->polled_event = NULL;
> +		INIT_DELAYED_WORK(&p->delayed_work, etr_perf_polling_worker);
> +	}
> +}
> +
> +void etr_perf_polling_exit(void)
> +{
> +	int cpu;
> +
> +	for_each_possible_cpu(cpu) {
> +		struct polling *p = per_cpu_ptr(&polling, cpu);
> +
> +		cancel_delayed_work_sync(&p->delayed_work);
> +		WARN_ON(p->polled_event);
> +	}
> +	WARN_ON(!list_empty(&registered_events));
> +}
> diff --git a/drivers/hwtracing/coresight/coresight-etr-perf-polling.h b/drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> new file mode 100644
> index 0000000000000..d47b4424594e6
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright(C) 2021 Arm Limited. All rights reserved.
> + * Author: Daniel Kiss <daniel.kiss at arm.com>
> + */
> +
> +#ifndef _CORESIGHT_ETM_PERF_POLLING_H
> +#define _CORESIGHT_ETM_PERF_POLLING_H
> +
> +#include <linux/coresight.h>
> +#include <linux/perf_event.h>
> +#include "coresight-etm-perf.h"
> +#include "coresight-tmc.h"
> +
> +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> +void etr_perf_polling_init(void);
> +void etr_perf_polling_exit(void);
> +void etr_perf_polling_handle_register(struct perf_output_handle *handle,
> +				      void (*tmc_etr_reset_hw)(struct tmc_drvdata *drvdata));
> +void etr_perf_polling_handle_deregister(struct perf_output_handle *handle);
> +void etr_perf_polling_event_start(struct perf_event *event,
> +				  struct etm_event_data *etm_event_data,
> +				  struct perf_output_handle *ctx_handle);
> +void etr_perf_polling_event_stop(struct perf_event *event,
> +				 struct etm_event_data *etm_event_data);
> +
> +extern const struct attribute_group coresight_tmc_polling_group;
> +
> +#else /* !CONFIG_CORESIGHT_ETR_PERF_POLL */
> +#define etr_perf_polling_init()
> +#define etr_perf_polling_exit()
> +#define etr_perf_polling_handle_register(...)
> +#define etr_perf_polling_handle_deregister(...)
> +#define etr_perf_polling_event_start(...)
> +#define etr_perf_polling_event_stop(...)
> +#endif
> +
> +#endif
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index 74c6323d4d6ab..dbcdba162bd38 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -26,6 +26,7 @@
>  
>  #include "coresight-priv.h"
>  #include "coresight-tmc.h"
> +#include "coresight-etr-perf-polling.h"
>  
>  DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>  DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
> @@ -365,6 +366,9 @@ static const struct attribute_group coresight_tmc_mgmt_group = {
>  static const struct attribute_group *coresight_tmc_groups[] = {
>  	&coresight_tmc_group,
>  	&coresight_tmc_mgmt_group,
> +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> +	&coresight_tmc_polling_group,
> +#endif
>  	NULL,
>  };
>  
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index 55c9b5fd9f832..67cd4bdcda71b 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -16,6 +16,7 @@
>  #include <linux/vmalloc.h>
>  #include "coresight-catu.h"
>  #include "coresight-etm-perf.h"
> +#include "coresight-etr-perf-polling.h"
>  #include "coresight-priv.h"
>  #include "coresight-tmc.h"
>  
> @@ -1137,6 +1138,16 @@ void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
>  	drvdata->etr_buf = NULL;
>  }
>  
> +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> +
> +static void tmc_etr_reset_hw(struct tmc_drvdata *drvdata)
> +{
> +	__tmc_etr_disable_hw(drvdata);
> +	__tmc_etr_enable_hw(drvdata);
> +}
> +
> +#endif
> +
>  static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>  {
>  	int ret = 0;
> @@ -1620,6 +1631,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
>  		drvdata->mode = CS_MODE_PERF;
>  		drvdata->perf_buf = etr_perf->etr_buf;
>  		drvdata->perf_handle = handle;
> +		etr_perf_polling_handle_register(handle, tmc_etr_reset_hw);
>  		atomic_inc(csdev->refcnt);
>  	}
>  
> @@ -1667,6 +1679,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
>  	drvdata->mode = CS_MODE_DISABLED;
>  	/* Reset perf specific data */
>  	drvdata->perf_buf = NULL;
> +	etr_perf_polling_handle_deregister(drvdata->perf_handle);
>  	drvdata->perf_handle = NULL;
>  
>  	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> -- 
> 2.25.1
> 


From ardb at kernel.org  Thu Aug 26 09:56:13 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 26 Aug 2021 18:56:13 +0200
Subject: [PATCH v2] arm64: mm: limit linear region to 51 bits for KVM in nVHE
 mode
Message-ID: <20210826165613.60774-1-ardb@kernel.org>

KVM in nVHE mode divides up its VA space into two equal halves, and
picks the half that does not conflict with the HYP ID map to map its
linear region. This worked fine when the kernel's linear map itself was
guaranteed to cover precisely as many bits of VA space, but this was
changed by commit f4693c2716b35d08 ("arm64: mm: extend linear region for
52-bit VA configurations").

The result is that, depending on the placement of the ID map, kernel-VA
to hyp-VA translations may produce addresses that either conflict with
other HYP mappings (including the ID map itself) or generate addresses
outside of the 52-bit addressable range, neither of which is likely to
lead to anything useful.

Given that 52-bit capable cores are guaranteed to implement VHE, this
only affects configurations such as pKVM where we opt into non-VHE mode
even if the hardware is VHE capable. So just for these configurations,
let's limit the kernel linear map to 51 bits and work around the
problem.

Fixes:f4693c2716b35d08 ("arm64: mm: extend linear region for 52-bit VA configurations")
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
v2: - take min() of prior value of linear_region_size and BIT(51) to
      avoid surprises
    - check is_hyp_mode_available() so that the exception is only
      applied to KVM hosts

 arch/arm64/mm/init.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 8490ed2917ff..2b28d77e29a0 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -282,7 +282,21 @@ static void __init fdt_enforce_memory_region(void)
 
 void __init arm64_memblock_init(void)
 {
-	const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
+	s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
+
+	/*
+	 * Corner case: 52-bit VA capable systems running KVM in nVHE mode may
+	 * be limited in their ability to support a linear map that exceeds 51
+	 * bits of VA space, depending on the placement of the ID map. Given
+	 * that the placement of the ID map may be randomized, let's simply
+	 * limit the kernel's linear map to 51 bits as well if we detect this
+	 * configuration.
+	 */
+	if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 &&
+	    is_hyp_mode_available() && !is_kernel_in_hyp_mode()) {
+		pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n");
+		linear_region_size = min_t(u64, linear_region_size, BIT(51));
+	}
 
 	/* Handle linux,usable-memory-range property */
 	fdt_enforce_memory_region();
-- 
2.30.2



From mathieu.poirier at linaro.org  Thu Aug 26 10:32:48 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 26 Aug 2021 11:32:48 -0600
Subject: [PATCHv2 4/4] coresight: Add ETR-PERF polling.
In-Reply-To: <20210713121532.836244-5-daniel.kiss@arm.com>
References: <20210713121532.836244-1-daniel.kiss@arm.com>
 <20210713121532.836244-5-daniel.kiss@arm.com>
Message-ID: <20210826173248.GB808387@p14s>

On Tue, Jul 13, 2021 at 02:15:32PM +0200, Daniel Kiss wrote:
> ETR might fill up the buffer sooner than an event makes perf to trigger
> the synchronisation especially in system wide trace. Polling runs
> periodically to sync the ETR buffer. Period is configurable via sysfs,
> disabled by default.
> 
> Signed-off-by: Daniel Kiss <daniel.kiss at arm.com>
> Signed-off-by: Branislav Rankov <Branislav.Rankov at arm.com>
> Tested-by: Denis Nikitin <denik at chromium.org>
> ---
>  .../testing/sysfs-bus-coresight-devices-tmc   |   8 +
>  drivers/hwtracing/coresight/Kconfig           |  12 +
>  drivers/hwtracing/coresight/Makefile          |   1 +
>  .../hwtracing/coresight/coresight-etm-perf.c  |   8 +
>  .../coresight/coresight-etr-perf-polling.c    | 275 ++++++++++++++++++
>  .../coresight/coresight-etr-perf-polling.h    |  38 +++
>  .../hwtracing/coresight/coresight-tmc-core.c  |   4 +
>  .../hwtracing/coresight/coresight-tmc-etr.c   |  13 +
>  8 files changed, 359 insertions(+)
>  create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> index 6aa527296c710..3b411e8a6f417 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> @@ -91,3 +91,11 @@ Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
>  Description:	(RW) Size of the trace buffer for TMC-ETR when used in SYSFS
>  		mode. Writable only for TMC-ETR configurations. The value
>  		should be aligned to the kernel pagesize.
> +
> +What:		/sys/bus/coresight/devices/<memory_map>.tmc/polling/period
> +Date:		July 2021
> +KernelVersion:	5.14
> +Contact:	Daniel Kiss <daniel.kiss at arm.com>
> +Description:	(RW) Time in milliseconds when the TMC-ETR is synced.
> +		Default value is 0, means the feature is disabled.
> +		Writable only for TMC-ETR configurations.
> diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
> index 84530fd80998c..4e91fb98849f4 100644
> --- a/drivers/hwtracing/coresight/Kconfig
> +++ b/drivers/hwtracing/coresight/Kconfig
> @@ -44,6 +44,18 @@ config CORESIGHT_LINK_AND_SINK_TMC
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called coresight-tmc.
>  
> +
> +config CORESIGHT_ETR_PERF_POLL
> +	bool "Coresight ETR Perf Polling"
> +
> +	depends on CORESIGHT_LINK_AND_SINK_TMC
> +	help
> +	  Enable the support for software periodic synchronization of the ETR buffer.
> +	  ETR might fill up the buffer sooner than an event makes perf to trigger
> +	  the synchronization especially in system wide trace. Polling runs
> +	  periodically to sync the ETR buffer. Period is configurable via sysfs,
> +	  disabled by default.
> +
>  config CORESIGHT_CATU
>  	tristate "Coresight Address Translation Unit (CATU) driver"
>  	depends on CORESIGHT_LINK_AND_SINK_TMC
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index d60816509755c..6baac328eea87 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -5,6 +5,7 @@
>  obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
>  		coresight-sysfs.o
> +coresight-$(CONFIG_CORESIGHT_ETR_PERF_POLL) += coresight-etr-perf-polling.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
>  		      coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index a3f4c07f5bf8b..3095840a567c4 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -19,6 +19,7 @@
>  #include <linux/workqueue.h>
>  
>  #include "coresight-etm-perf.h"
> +#include "coresight-etr-perf-polling.h"
>  #include "coresight-priv.h"
>  
>  static struct pmu etm_pmu;
> @@ -438,6 +439,8 @@ static void etm_event_start(struct perf_event *event, int flags)
>  	/* Tell the perf core the event is alive */
>  	event->hw.state = 0;
>  
> +	etr_perf_polling_event_start(event, event_data, handle);
> +
>  	/* Finally enable the tracer */
>  	if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF))
>  		goto fail_disable_path;
> @@ -497,6 +500,8 @@ static void etm_event_stop(struct perf_event *event, int mode)
>  	if (!sink)
>  		return;
>  
> +	etr_perf_polling_event_stop(event, event_data);
> +
>  	/* stop tracer */
>  	source_ops(csdev)->disable(csdev, event);
>  
> @@ -741,6 +746,8 @@ int __init etm_perf_init(void)
>  	etm_pmu.addr_filters_validate	= etm_addr_filters_validate;
>  	etm_pmu.nr_addr_filters		= ETM_ADDR_CMP_MAX;
>  
> +	etr_perf_polling_init();

The problem here is that a function specific to an ETR is inserted in code that
should be generic.  So if we want to do the same for ETB, ETF and any kind of
sink that's out there, we'd have to duplicate code and it would quickly get
messy.  What is needed is a generic solution.

Moreover what is proposed here is centered on sinks, while the entire coresight
framework is centered on sources.  The polling function, although specific to
sinks, should emanate from and be driven by the generic code that handles
sources.  There should also be a single event responsible for doing the polling
rather than all of them as it is the case in this patchset.  In per-thread mode
where a single thread is traced it isn't a problem.  In CPU-wide scenarios the
first event should do the polling.  There will be a gap between the time that
event stops and all the other events in the trace session stop but that is a
limitation we will have to live with.  

That leaves us with per-thread sessions where child threads are spun off.  You
will have to look into how events are handle in that case.  Suzuki has done work
in that area and might remember a few things. 

There are other design problems with this set that I won't get into since it 
needs a refactoring anyway.

Regards,
Mathieu

> +
>  	ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
>  	if (ret == 0)
>  		etm_perf_up = true;
> @@ -750,5 +757,6 @@ int __init etm_perf_init(void)
>  
>  void __exit etm_perf_exit(void)
>  {
> +	etr_perf_polling_exit();
>  	perf_pmu_unregister(&etm_pmu);
>  }
> diff --git a/drivers/hwtracing/coresight/coresight-etr-perf-polling.c b/drivers/hwtracing/coresight/coresight-etr-perf-polling.c
> new file mode 100644
> index 0000000000000..87e6bc42a62de
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-etr-perf-polling.c
> @@ -0,0 +1,275 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(C) 2021 Arm Limited. All rights reserved.
> + * Author: Daniel Kiss <daniel.kiss at arm.com>
> + */
> +
> +#include <linux/coresight.h>
> +#include <linux/coresight-pmu.h>
> +#include <linux/cpumask.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/list.h>
> +#include <linux/percpu-defs.h>
> +#include <linux/perf_event.h>
> +#include <linux/slab.h>
> +#include <linux/stringhash.h>
> +#include <linux/types.h>
> +#include <linux/workqueue.h>
> +
> +#include "coresight-etr-perf-polling.h"
> +#include "coresight-priv.h"
> +#include "coresight-tmc.h"
> +
> +struct polling_event_list {
> +	struct perf_event *perf_event;
> +	struct etm_event_data *etm_event_data;
> +	struct perf_output_handle *ctx_handle;
> +	void (*tmc_etr_reset_hw)(struct tmc_drvdata *data);
> +	struct list_head list;
> +};
> +
> +struct polling {
> +	int cpu;
> +	struct polling_event_list *polled_event;
> +	struct delayed_work delayed_work;
> +};
> +
> +static atomic_t period;
> +static spinlock_t spinlock_re;
> +static struct list_head registered_events;
> +
> +static DEFINE_PER_CPU(struct polling, polling);
> +
> +static ssize_t period_show(struct device *dev, struct device_attribute *attr,
> +			   char *buf)
> +{
> +	int temp;
> +
> +	temp = atomic_read(&period);
> +	return sprintf(buf, "%i\n", temp);
> +}
> +
> +static ssize_t period_store(struct device *dev, struct device_attribute *attr,
> +			    const char *buf, size_t count)
> +{
> +	int temp = 0;
> +
> +	if (!kstrtoint(buf, 10, &temp) && (temp >= 0))
> +		atomic_set(&period, temp);
> +	return count;
> +}
> +
> +static DEVICE_ATTR_RW(period);
> +
> +static struct attribute *coresight_tmc_polling_attrs[] = {
> +	&dev_attr_period.attr,
> +	NULL,
> +};
> +const struct attribute_group coresight_tmc_polling_group = {
> +	.attrs = coresight_tmc_polling_attrs,
> +	.name = "polling",
> +};
> +EXPORT_SYMBOL_GPL(coresight_tmc_polling_group);
> +
> +static inline void polling_sched_worker(struct polling *p)
> +{
> +	int tickrate = atomic_read(&period);
> +
> +	if (tickrate > 0)
> +		schedule_delayed_work_on(p->cpu, &p->delayed_work,
> +					 msecs_to_jiffies(tickrate));
> +}
> +
> +static inline bool is_etr_related(struct etm_event_data *etm_event_data, int cpu)
> +{
> +	struct list_head *path;
> +	struct coresight_device *sink;
> +	struct tmc_drvdata *drvdata;
> +
> +	path = etm_event_cpu_path(etm_event_data, cpu);
> +	if (WARN_ON(!path))
> +		return false;
> +	sink = coresight_get_sink(path);
> +	if (WARN_ON(!sink))
> +		return false;
> +	drvdata = dev_get_drvdata(sink->dev.parent);
> +	if (drvdata->config_type != TMC_CONFIG_TYPE_ETR)
> +		return false;
> +	return true;
> +}
> +
> +/*
> + * Adds the event to the polled events list.
> + */
> +void etr_perf_polling_event_start(struct perf_event *event,
> +				  struct etm_event_data *etm_event_data,
> +				  struct perf_output_handle *ctx_handle)
> +{
> +	int cpu = smp_processor_id();
> +	struct polling *p = per_cpu_ptr(&polling, cpu);
> +	struct polling_event_list *element, *tmp;
> +
> +	if (!is_etr_related(etm_event_data, cpu))
> +		return;
> +
> +	spin_lock(&spinlock_re);
> +	list_for_each_entry_safe(element, tmp, &registered_events, list) {
> +		if (element->ctx_handle == ctx_handle) {
> +			element->perf_event = event;
> +			element->etm_event_data = etm_event_data;
> +			spin_unlock(&spinlock_re);
> +			p->polled_event = element;
> +			polling_sched_worker(p);
> +			return;
> +		}
> +	}
> +	spin_unlock(&spinlock_re);
> +}
> +
> +/*
> + * Removes the event from the to be polled events list.
> + */
> +void etr_perf_polling_event_stop(struct perf_event *event,
> +				 struct etm_event_data *etm_event_data)
> +{
> +	int cpu = smp_processor_id();
> +	struct polling *p = per_cpu_ptr(&polling, cpu);
> +
> +	if (!is_etr_related(etm_event_data, cpu))
> +		return;
> +
> +	if (p->polled_event) {
> +		struct polling_event_list *element = p->polled_event;
> +
> +		if (element->perf_event == event) {
> +			p->polled_event = NULL;
> +			element->perf_event = NULL;
> +			element->etm_event_data = NULL;
> +			cancel_delayed_work(&p->delayed_work);
> +			return;
> +		}
> +	}
> +}
> +
> +/*
> + * The polling worker is a workqueue job which is periodically
> + * woken up to update the perf aux buffer from the etr shrink.
> + */
> +static void etr_perf_polling_worker(struct work_struct *work)
> +{
> +	unsigned long flags;
> +	struct list_head *path;
> +	struct coresight_device *sink;
> +	int size;
> +	int cpu = smp_processor_id();
> +	struct polling *p = per_cpu_ptr(&polling, cpu);
> +
> +	if (!atomic_read(&period))
> +		return;
> +
> +	if (!p->polled_event)
> +		return;
> +	/*
> +	 * Scheduling would do the same from the perf hooks,
> +	 * this should be done in one go.
> +	 */
> +	local_irq_save(flags);
> +
> +	polling_sched_worker(p);
> +
> +	path = etm_event_cpu_path(p->polled_event->etm_event_data, cpu);
> +	sink = coresight_get_sink(path);
> +	size = sink_ops(sink)->update_buffer(
> +		sink, p->polled_event->ctx_handle,
> +		p->polled_event->etm_event_data->snk_config);
> +
> +	/*
> +	 * Restart the trace.
> +	 */
> +	if (p->polled_event->tmc_etr_reset_hw)
> +		p->polled_event->tmc_etr_reset_hw(dev_get_drvdata(sink->dev.parent));
> +
> +	WARN_ON(size < 0);
> +	if (size > 0) {
> +		struct etm_event_data *new_event_data;
> +
> +		perf_aux_output_end(p->polled_event->ctx_handle, size);
> +		new_event_data = perf_aux_output_begin(
> +			p->polled_event->ctx_handle,
> +			p->polled_event->perf_event);
> +		if (WARN_ON(new_event_data == NULL)) {
> +			local_irq_restore(flags);
> +			return;
> +		}
> +
> +		p->polled_event->etm_event_data = new_event_data;
> +		WARN_ON(new_event_data->snk_config !=
> +			p->polled_event->etm_event_data->snk_config);
> +	}
> +
> +	local_irq_restore(flags);
> +}
> +
> +void etr_perf_polling_handle_register(struct perf_output_handle *handle,
> +				      void (*tmc_etr_reset_hw)(struct tmc_drvdata *drvdata))
> +{
> +	struct polling_event_list *element;
> +
> +	element = kmalloc(sizeof(*element), GFP_ATOMIC);
> +	if (WARN_ON(!element))
> +		return;
> +	memset(element, 0, sizeof(*element));
> +	element->ctx_handle = handle;
> +	element->tmc_etr_reset_hw = tmc_etr_reset_hw;
> +	spin_lock(&spinlock_re);
> +	list_add(&element->list, &registered_events);
> +	spin_unlock(&spinlock_re);
> +}
> +EXPORT_SYMBOL_GPL(etr_perf_polling_handle_register);
> +
> +void etr_perf_polling_handle_deregister(struct perf_output_handle *handle)
> +{
> +	struct polling_event_list *element, *tmp;
> +
> +	spin_lock(&spinlock_re);
> +	list_for_each_entry_safe(element, tmp, &registered_events, list) {
> +		if (element->ctx_handle == handle) {
> +			list_del(&element->list);
> +			spin_unlock(&spinlock_re);
> +			kfree(element);
> +			return;
> +		}
> +	}
> +	spin_unlock(&spinlock_re);
> +}
> +EXPORT_SYMBOL_GPL(etr_perf_polling_handle_deregister);
> +
> +void etr_perf_polling_init(void)
> +{
> +	int cpu;
> +
> +	spin_lock_init(&spinlock_re);
> +	INIT_LIST_HEAD(&registered_events);
> +	atomic_set(&period, 0);
> +	for_each_possible_cpu(cpu) {
> +		struct polling *p = per_cpu_ptr(&polling, cpu);
> +
> +		p->cpu = cpu;
> +		p->polled_event = NULL;
> +		INIT_DELAYED_WORK(&p->delayed_work, etr_perf_polling_worker);
> +	}
> +}
> +
> +void etr_perf_polling_exit(void)
> +{
> +	int cpu;
> +
> +	for_each_possible_cpu(cpu) {
> +		struct polling *p = per_cpu_ptr(&polling, cpu);
> +
> +		cancel_delayed_work_sync(&p->delayed_work);
> +		WARN_ON(p->polled_event);
> +	}
> +	WARN_ON(!list_empty(&registered_events));
> +}
> diff --git a/drivers/hwtracing/coresight/coresight-etr-perf-polling.h b/drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> new file mode 100644
> index 0000000000000..d47b4424594e6
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright(C) 2021 Arm Limited. All rights reserved.
> + * Author: Daniel Kiss <daniel.kiss at arm.com>
> + */
> +
> +#ifndef _CORESIGHT_ETM_PERF_POLLING_H
> +#define _CORESIGHT_ETM_PERF_POLLING_H
> +
> +#include <linux/coresight.h>
> +#include <linux/perf_event.h>
> +#include "coresight-etm-perf.h"
> +#include "coresight-tmc.h"
> +
> +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> +void etr_perf_polling_init(void);
> +void etr_perf_polling_exit(void);
> +void etr_perf_polling_handle_register(struct perf_output_handle *handle,
> +				      void (*tmc_etr_reset_hw)(struct tmc_drvdata *drvdata));
> +void etr_perf_polling_handle_deregister(struct perf_output_handle *handle);
> +void etr_perf_polling_event_start(struct perf_event *event,
> +				  struct etm_event_data *etm_event_data,
> +				  struct perf_output_handle *ctx_handle);
> +void etr_perf_polling_event_stop(struct perf_event *event,
> +				 struct etm_event_data *etm_event_data);
> +
> +extern const struct attribute_group coresight_tmc_polling_group;
> +
> +#else /* !CONFIG_CORESIGHT_ETR_PERF_POLL */
> +#define etr_perf_polling_init()
> +#define etr_perf_polling_exit()
> +#define etr_perf_polling_handle_register(...)
> +#define etr_perf_polling_handle_deregister(...)
> +#define etr_perf_polling_event_start(...)
> +#define etr_perf_polling_event_stop(...)
> +#endif
> +
> +#endif
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index 74c6323d4d6ab..dbcdba162bd38 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -26,6 +26,7 @@
>  
>  #include "coresight-priv.h"
>  #include "coresight-tmc.h"
> +#include "coresight-etr-perf-polling.h"
>  
>  DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>  DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
> @@ -365,6 +366,9 @@ static const struct attribute_group coresight_tmc_mgmt_group = {
>  static const struct attribute_group *coresight_tmc_groups[] = {
>  	&coresight_tmc_group,
>  	&coresight_tmc_mgmt_group,
> +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> +	&coresight_tmc_polling_group,
> +#endif
>  	NULL,
>  };
>  
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index 55c9b5fd9f832..67cd4bdcda71b 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -16,6 +16,7 @@
>  #include <linux/vmalloc.h>
>  #include "coresight-catu.h"
>  #include "coresight-etm-perf.h"
> +#include "coresight-etr-perf-polling.h"
>  #include "coresight-priv.h"
>  #include "coresight-tmc.h"
>  
> @@ -1137,6 +1138,16 @@ void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
>  	drvdata->etr_buf = NULL;
>  }
>  
> +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> +
> +static void tmc_etr_reset_hw(struct tmc_drvdata *drvdata)
> +{
> +	__tmc_etr_disable_hw(drvdata);
> +	__tmc_etr_enable_hw(drvdata);
> +}
> +
> +#endif
> +
>  static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>  {
>  	int ret = 0;
> @@ -1620,6 +1631,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
>  		drvdata->mode = CS_MODE_PERF;
>  		drvdata->perf_buf = etr_perf->etr_buf;
>  		drvdata->perf_handle = handle;
> +		etr_perf_polling_handle_register(handle, tmc_etr_reset_hw);
>  		atomic_inc(csdev->refcnt);
>  	}
>  
> @@ -1667,6 +1679,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
>  	drvdata->mode = CS_MODE_DISABLED;
>  	/* Reset perf specific data */
>  	drvdata->perf_buf = NULL;
> +	etr_perf_polling_handle_deregister(drvdata->perf_handle);
>  	drvdata->perf_handle = NULL;
>  
>  	spin_unlock_irqrestore(&drvdata->spinlock, flags);
> -- 
> 2.25.1
> 


From t.schramm at manjaro.org  Thu Aug 26 10:46:32 2021
From: t.schramm at manjaro.org (Tobias Schramm)
Date: Thu, 26 Aug 2021 19:46:32 +0200
Subject: [PATCH] i2c: rk3x: disable and reenable I2C after timeouts to fix
 stuck low SDA
Message-ID: <20210826174632.91887-1-t.schramm@manjaro.org>

Previously the SDA line sometimes remained stuck low after timeouts
rendering the I2C bus unusable. Testing has shown that disabling and
reenabling the I2C peripheral after sending the stop condition seems to
unstick SDA reliably.
Disable and reenable the I2C controller on timeout after sending stop
condition to unstick SDA.

Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
---
 drivers/i2c/busses/i2c-rk3x.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index 819ab4ee517e..fc330cc3686a 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -1108,6 +1108,16 @@ static int rk3x_i2c_xfer_common(struct i2c_adapter *adap,
 			val |= REG_CON_EN | REG_CON_STOP;
 			i2c_writel(i2c, val, REG_CON);
 
+			/*
+			 * Sometimes SDA remains stuck low after timeouts.
+			 * Disable and reenable the I2C peripheral to unstick
+			 * SDA.
+			 */
+			val &= ~REG_CON_EN;
+			i2c_writel(i2c, val, REG_CON);
+			val |= REG_CON_EN;
+			i2c_writel(i2c, val, REG_CON);
+
 			i2c->state = STATE_IDLE;
 
 			ret = -ETIMEDOUT;
-- 
2.31.1



From ionela.voinescu at arm.com  Thu Aug 26 10:51:38 2021
From: ionela.voinescu at arm.com (Ionela Voinescu)
Date: Thu, 26 Aug 2021 18:51:38 +0100
Subject: [PATCH v2 2/3] arch_topology: obtain cpu capacity using
 information from CPPC
In-Reply-To: <CAJZ5v0hkgWQqOzfdv4kr6rxz9eMsOgHkMYj0cZpO7yC+=SnQfg@mail.gmail.com>
References: <20210824105651.28660-1-ionela.voinescu@arm.com>
 <20210824105651.28660-3-ionela.voinescu@arm.com>
 <CAJZ5v0hkgWQqOzfdv4kr6rxz9eMsOgHkMYj0cZpO7yC+=SnQfg@mail.gmail.com>
Message-ID: <20210826175138.GA22165@arm.com>

Thanks for the review, Rafael!

On Wednesday 25 Aug 2021 at 19:54:26 (+0200), Rafael J. Wysocki wrote:
> On Tue, Aug 24, 2021 at 12:57 PM Ionela Voinescu
> <ionela.voinescu at arm.com> wrote:
> >
> > Define topology_init_cpu_capacity_cppc() to use highest performance
> > values from _CPC objects to obtain and set maximum capacity information
> > for each CPU. acpi_cppc_processor_probe() is a good point at which to
> > trigger the initialization of CPU (u-arch) capacity values, as at this
> > point the highest performance values can be obtained from each CPU's
> > _CPC objects. Architectures can therefore use this functionality
> > through arch_init_invariance_cppc().
> >
> > The performance scale used by CPPC is a unified scale for all CPUs in
> > the system. Therefore, by obtaining the raw highest performance values
> > from the _CPC objects, and normalizing them on the [0, 1024] capacity
> > scale, used by the task scheduler, we obtain the CPU capacity of each
> > CPU.
> >
> > While an ACPI Notify(0x85) could alert about a change in the highest
> > performance value, which should in turn retrigger the CPU capacity
> > computations, this notification is not currently handled by the ACPI
> > processor driver. When supported, a call to arch_init_invariance_cppc()
> > would perform the update.
> >
> > Signed-off-by: Ionela Voinescu <ionela.voinescu at arm.com>
> > Tested-by: Valentin Schneider <valentin.schneider at arm.com>
> > Cc: Sudeep Holla <sudeep.holla at arm.com>
> > ---
> >  drivers/base/arch_topology.c  | 37 +++++++++++++++++++++++++++++++++++
> >  include/linux/arch_topology.h |  4 ++++
> >  2 files changed, 41 insertions(+)
> >
> > diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
> > index 921312a8d957..358e22cd629e 100644
> > --- a/drivers/base/arch_topology.c
> > +++ b/drivers/base/arch_topology.c
> > @@ -306,6 +306,43 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
> >         return !ret;
> >  }
> >
> > +#ifdef CONFIG_ACPI_CPPC_LIB
> > +#include <acpi/cppc_acpi.h>
> > +
> > +void topology_init_cpu_capacity_cppc(void)
> > +{
> > +       struct cppc_perf_caps perf_caps;
> > +       int cpu;
> > +
> > +       if (likely(acpi_disabled || !acpi_cpc_valid()))
> > +               return;
> > +
> > +       raw_capacity = kcalloc(num_possible_cpus(), sizeof(*raw_capacity),
> > +                              GFP_KERNEL);
> > +       if (!raw_capacity)
> > +               return;
> > +
> > +       for_each_possible_cpu(cpu) {
> > +               if (!cppc_get_perf_caps(cpu, &perf_caps)) {
> > +                       raw_capacity[cpu] = perf_caps.highest_perf;
> 
> From experience, I would advise doing some sanity checking on the
> per_caps values before using them here.
> 

cppc_get_perf_caps() already returns -EFAULT if highest_perf is 0, and
I'm not sure if I can make any other assumptions about what a sane
highest_perf value would need to be here.

Did you have anything else in mind for sanity checking?

> Also note that highest_perf may not be sustainable, so would using
> highest_perf as raw_capacity[] always work as expected?
> 

Yes, in my opinion using it is better than the alternative, using the
nominal performance value. This highest performance value helps obtain
the maximum capacity of a CPU on a scale [0, 1024] when referenced to
the highest performance of the biggest CPU in the system. There is no
assumption in the task scheduler that this capacity is sustainable.
Using lower values (nominal performance) would shorten the scale and
make smaller CPUs seem bigger than they are. Also, using highest
performance gives a better indication of micro-architectural
differences in performance between CPUs, which plays a role in scaling
utilization, even if some of the performance levels are not sustainable
(which is platform dependent).

Thanks,
Ionela.

> > +                       pr_debug("cpu_capacity: CPU%d cpu_capacity=%u (raw).\n",
> > +                                cpu, raw_capacity[cpu]);
> > +               } else {
> > +                       pr_err("cpu_capacity: CPU%d missing highest performance.\n", cpu);
> > +                       pr_err("cpu_capacity: partial information: fallback to 1024 for all CPUs\n");
> > +                       goto exit;
> > +               }
> > +       }
> > +
> > +       topology_normalize_cpu_scale();
> > +       schedule_work(&update_topology_flags_work);
> > +       pr_debug("cpu_capacity: cpu_capacity initialization done\n");
> > +
> > +exit:
> > +       free_raw_capacity();
> > +}
> > +#endif
> > +
> >  #ifdef CONFIG_CPU_FREQ
> >  static cpumask_var_t cpus_to_visit;
> >  static void parsing_done_workfn(struct work_struct *work);
> > diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h
> > index f180240dc95f..9cf1a17938f0 100644
> > --- a/include/linux/arch_topology.h
> > +++ b/include/linux/arch_topology.h
> > @@ -11,6 +11,10 @@
> >  void topology_normalize_cpu_scale(void);
> >  int topology_update_cpu_topology(void);
> >
> > +#ifdef CONFIG_ACPI_CPPC_LIB
> > +void topology_init_cpu_capacity_cppc(void);
> > +#endif
> > +
> >  struct device_node;
> >  bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu);
> >
> > --
> > 2.29.2.dirty
> >


From james.quinlan at broadcom.com  Thu Aug 26 11:29:21 2021
From: james.quinlan at broadcom.com (Jim Quinlan)
Date: Thu, 26 Aug 2021 14:29:21 -0400
Subject: [PATCH v4 11/12] [RFC] firmware: arm_scmi: Add
 sync_cmds_atomic_replies transport flag
In-Reply-To: <20210825184915.GI13160@e120937-lin>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-12-cristian.marussi@arm.com>
 <7a2f972d-fdd0-d0f7-cac2-1989980ed872@gmail.com>
 <CA+-6iNw-_VXcntU_UE8kTiPb8Sq28KkZG1__N7rE4ezo=VqQVQ@mail.gmail.com>
 <20210825184915.GI13160@e120937-lin>
Message-ID: <CA+-6iNwjQ1SogxdyrjwqEwLosscUyvrioqFKmesifM_nmCpJAw@mail.gmail.com>

On Wed, Aug 25, 2021 at 2:49 PM Cristian Marussi
<cristian.marussi at arm.com> wrote:
>
> On Wed, Aug 25, 2021 at 01:17:47PM -0400, Jim Quinlan wrote:
> > On Wed, Aug 25, 2021 at 12:38 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
> > >
> > >
> > >
>
> Hi Florian and Jim,
>
> > > On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> > > > A flag is added to let the transport signal the core that its handling of
> > > > synchronous command messages implies that, after .send_message has returned
> > > > successfully, the requested command can be assumed to be fully and
> > > > completely executed on SCMI platform side so that any possible response
> > > > value is already immediately available to be retrieved by a .fetch_reponse:
> > > > in other words the polling phase can be skipped in such a case and the
> > > > response values accessed straight away.
> > > >
> > > > Note that all of the above applies only when polling mode of operation was
> > > > selected by the core: if instead a completion IRQ was found to be available
> > > > the normal response processing path based on completions will still be
> > > > followed.
> > >
> > > This might actually have to be settable on a per-message basis ideally
> > > since we may be transporting short lived SCMI messages for which the
> > > completion can be done at SMC time, and long lived SCMI messages (e.g.:
> > > involving a voltage change) for which we would prefer a completion
> > > interrupt. Jim, what do you think?
> > Even if the SCMI main driver could be configured this way in an
> > elegant manner, I'm not sure that there is a clean way of specifying
> > this  attribute on a per-message basis.  Certainly we could do this
> > with our own protocols, but  many of our "long lived" messages are the
> > Perf protocol's set_level command.  At any rate, let me give it some
> > thought.
> >
>
> The new flag .sync_cmds_atomic_replies applies only when polling mode
> has been selected for a specific cmd transaction, which means when no
> completion IRQ was found available OR if xfer.poll_completion was
> excplicitly set for a specific command.
>
> At the moment in this series (unknown bugs apart :D), if you have a
> channel configured with a completion IRQ and the .sync_cmds_atomic_replies
> set for the transport, this latter flag would be generally ignored and a
> wait_for_completion() will be normally used upon reception of the
> completionIRQ, UNLESS you specify that one specific command has to be
> polled using the per message xfer.poll_completion flag: so you should be
> already able to selectively use a polling which immediately returns after
> the smc by setting xfer.poll_completion for that specific short lived
> message (since sync_cmds_atomic_replies is set and applies to pollmode).
> On the other side any other LONG lived message will be naturally handled
> via completionIRQ + wait_for_completion. (at least that was the aim..)
>
> !!! NOTE that you'll have also to drop
>
>  [PATCH v4 10/12] [RFC] firmware: arm_scmi: Make smc transport atomic
>
> from this series for the wait_completion to happen as you wish.

Hi Cristian,

I've tested all commits on our SMC-based system.  I also tested all commits
minus  "10/12 [RFC] firmware: arm_scmi: Make smc transport atomic".
This was a basic stress test, not a comprehensive one.  So

Tested-by: Jim Quinlan <james.quinlan at broadcom.com>

Of course I have a strong preference for omitting  "10/12 [RFC]" :-).
FWIW, if you are not planning on dropping this commit, perhaps there
could be a transport
node in the DT, and that could contain the  a bool  property
"smc-atomic-capable"?

Regards,
Jim Quinlan
Broadcom STB

>
> As said I'm not sure that this whole mixing of polling and IRQs on the
> same channel on a regular won't cause any issues: any feedback on this
> from your setup is much appreciated.
> (maybe it's fine for SMC transport, but it led to a bit of hell in the
> past with mboxes AFAIK...)
>
> Thanks a lot again for your feedback, I'll have to chat with Sudeep
> about the various issues/configs possibility that we discussed and I'll
> keep you in the loop.
>
> Thanks,
> Cristian
>
> P.S.: I'll be off for a few weeks, so even though I'll keep an eye on
> the mail, I cannot guarantee any responsiveness :D
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4210 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210826/39b08f75/attachment.p7s>

From rafael at kernel.org  Thu Aug 26 11:32:52 2021
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 26 Aug 2021 20:32:52 +0200
Subject: [PATCH v2 2/3] arch_topology: obtain cpu capacity using
 information from CPPC
In-Reply-To: <20210826175138.GA22165@arm.com>
References: <20210824105651.28660-1-ionela.voinescu@arm.com>
 <20210824105651.28660-3-ionela.voinescu@arm.com>
 <CAJZ5v0hkgWQqOzfdv4kr6rxz9eMsOgHkMYj0cZpO7yC+=SnQfg@mail.gmail.com>
 <20210826175138.GA22165@arm.com>
Message-ID: <CAJZ5v0i9Ys67E8TvWzJG+NaODKsEMsJiHrF9KM77Lk4L-3OOsA@mail.gmail.com>

On Thu, Aug 26, 2021 at 7:51 PM Ionela Voinescu <ionela.voinescu at arm.com> wrote:
>
> Thanks for the review, Rafael!
>
> On Wednesday 25 Aug 2021 at 19:54:26 (+0200), Rafael J. Wysocki wrote:
> > On Tue, Aug 24, 2021 at 12:57 PM Ionela Voinescu
> > <ionela.voinescu at arm.com> wrote:
> > >
> > > Define topology_init_cpu_capacity_cppc() to use highest performance
> > > values from _CPC objects to obtain and set maximum capacity information
> > > for each CPU. acpi_cppc_processor_probe() is a good point at which to
> > > trigger the initialization of CPU (u-arch) capacity values, as at this
> > > point the highest performance values can be obtained from each CPU's
> > > _CPC objects. Architectures can therefore use this functionality
> > > through arch_init_invariance_cppc().
> > >
> > > The performance scale used by CPPC is a unified scale for all CPUs in
> > > the system. Therefore, by obtaining the raw highest performance values
> > > from the _CPC objects, and normalizing them on the [0, 1024] capacity
> > > scale, used by the task scheduler, we obtain the CPU capacity of each
> > > CPU.
> > >
> > > While an ACPI Notify(0x85) could alert about a change in the highest
> > > performance value, which should in turn retrigger the CPU capacity
> > > computations, this notification is not currently handled by the ACPI
> > > processor driver. When supported, a call to arch_init_invariance_cppc()
> > > would perform the update.
> > >
> > > Signed-off-by: Ionela Voinescu <ionela.voinescu at arm.com>
> > > Tested-by: Valentin Schneider <valentin.schneider at arm.com>
> > > Cc: Sudeep Holla <sudeep.holla at arm.com>
> > > ---
> > >  drivers/base/arch_topology.c  | 37 +++++++++++++++++++++++++++++++++++
> > >  include/linux/arch_topology.h |  4 ++++
> > >  2 files changed, 41 insertions(+)
> > >
> > > diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
> > > index 921312a8d957..358e22cd629e 100644
> > > --- a/drivers/base/arch_topology.c
> > > +++ b/drivers/base/arch_topology.c
> > > @@ -306,6 +306,43 @@ bool __init topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu)
> > >         return !ret;
> > >  }
> > >
> > > +#ifdef CONFIG_ACPI_CPPC_LIB
> > > +#include <acpi/cppc_acpi.h>
> > > +
> > > +void topology_init_cpu_capacity_cppc(void)
> > > +{
> > > +       struct cppc_perf_caps perf_caps;
> > > +       int cpu;
> > > +
> > > +       if (likely(acpi_disabled || !acpi_cpc_valid()))
> > > +               return;
> > > +
> > > +       raw_capacity = kcalloc(num_possible_cpus(), sizeof(*raw_capacity),
> > > +                              GFP_KERNEL);
> > > +       if (!raw_capacity)
> > > +               return;
> > > +
> > > +       for_each_possible_cpu(cpu) {
> > > +               if (!cppc_get_perf_caps(cpu, &perf_caps)) {
> > > +                       raw_capacity[cpu] = perf_caps.highest_perf;
> >
> > From experience, I would advise doing some sanity checking on the
> > per_caps values before using them here.
> >
>
> cppc_get_perf_caps() already returns -EFAULT if highest_perf is 0, and
> I'm not sure if I can make any other assumptions about what a sane
> highest_perf value would need to be here.

Well, it cannot be less than lowest_perf or nominal_perf or
guaranteed_perf, for instance.

> Did you have anything else in mind for sanity checking?
>
> > Also note that highest_perf may not be sustainable, so would using
> > highest_perf as raw_capacity[] always work as expected?
> >
>
> Yes, in my opinion using it is better than the alternative, using the
> nominal performance value. This highest performance value helps obtain
> the maximum capacity of a CPU on a scale [0, 1024] when referenced to
> the highest performance of the biggest CPU in the system. There is no
> assumption in the task scheduler that this capacity is sustainable.

That's true, but there are consequences if it is the case.  Namely,
you may find that the big CPUs run at the highest performance for a
small fraction of time, so most of the time they may appear to be
underutilized no matter how many tasks are packed on them, which then
will influence the utilization metrics of those tasks.

It may be better to use guaranteed_perf or some value between it at
the highest for this reason.

> Using lower values (nominal performance) would shorten the scale and
> make smaller CPUs seem bigger than they are. Also, using highest
> performance gives a better indication of micro-architectural
> differences in performance between CPUs, which plays a role in scaling
> utilization, even if some of the performance levels are not sustainable
> (which is platform dependent).


From torvalds at linux-foundation.org  Thu Aug 26 11:41:34 2021
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Thu, 26 Aug 2021 11:41:34 -0700
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <20210826131747.GE26318@willie-the-truck>
References: <20210826131747.GE26318@willie-the-truck>
Message-ID: <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>

On Thu, Aug 26, 2021 at 6:17 AM Will Deacon <will at kernel.org> wrote:
>
> Please pull this single arm64 fix for 5.14.

Pulled.

But adding Christoph to the cc, since I do think the eventual fix
needs to be in the DMA mapping code:

> We received a report this week
> that the generic version of pfn_valid(), which we switched to this merge
> window in 16c9afc77660 ("arm64/mm: drop HAVE_ARCH_PFN_VALID"), interacts
> badly with dma_map_resource() due to the following check:
>
>         /* Don't allow RAM to be mapped */
>         if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
>                 return DMA_MAPPING_ERROR;
>
> Since the ongoing saga to determine the semantics of pfn_valid() is
> unlikely to be resolved this week (does it indicate valid memory, or
> just the presence of a struct page, or whether that struct page has been
> initialised?), just revert back to our old version of pfn_valid() for
> 5.14.

I think that's the right thing for now, but yeah, that condition for
WARN_ON_ONCE() seems very questionable.

"pfn_valid()" is more about whether you can do a "pfn_to_page()" lookup on it.

II get the feeling that the dma-mapping code should allow pages that
are PageReserved() to be mapped - they aren't "ram" in the kernel
sense.

Perhaps also make sure it's not the zero page (which is
PageReserved(), but most definitely RAM).

In a PC world that would be (for example) the legacy PCI space at
0xa0000-0xfffff, but I could easily imagine other platforms having
other situations.

              Linus


From mathieu.desnoyers at efficios.com  Thu Aug 26 11:42:12 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Thu, 26 Aug 2021 14:42:12 -0400 (EDT)
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <YSblqrrpKcORzilX@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-5-seanjc@google.com>
 <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>
 <282257549.21721.1629732017655.JavaMail.zimbra@efficios.com>
 <YSblqrrpKcORzilX@google.com>
Message-ID: <1700758714.29394.1630003332081.JavaMail.zimbra@efficios.com>

----- On Aug 25, 2021, at 8:51 PM, Sean Christopherson seanjc at google.com wrote:

> On Mon, Aug 23, 2021, Mathieu Desnoyers wrote:
>> [ re-send to Darren Hart ]
>> 
>> ----- On Aug 23, 2021, at 11:18 AM, Mathieu Desnoyers
>> mathieu.desnoyers at efficios.com wrote:
>> 
>> > ----- On Aug 20, 2021, at 6:50 PM, Sean Christopherson seanjc at google.com wrote:
>> > 
>> >> Add a test to verify an rseq's CPU ID is updated correctly if the task is
>> >> migrated while the kernel is handling KVM_RUN.  This is a regression test
>> >> for a bug introduced by commit 72c3c0fe54a3 ("x86/kvm: Use generic xfer
>> >> to guest work function"), where TIF_NOTIFY_RESUME would be cleared by KVM
>> >> without updating rseq, leading to a stale CPU ID and other badness.
>> >> 
>> > 
>> > [...]
>> > 
>> > +#define RSEQ_SIG 0xdeadbeef
>> > 
>> > Is there any reason for defining a custom signature rather than including
>> > tools/testing/selftests/rseq/rseq.h ? This should take care of including
>> > the proper architecture header which will define the appropriate signature.
>> > 
>> > Arguably you don't define rseq critical sections in this test per se, but
>> > I'm wondering why the custom signature here.
> 
> Partly to avoid taking a dependency on rseq.h, and partly to try to call out
> that
> the test doesn't actually do any rseq critical sections.

It might be good to add a comment near this define stating this then, so nobody
attempts to copy this as an example.

> 
>> > [...]
>> > 
>> >> +
>> >> +static void *migration_worker(void *ign)
>> >> +{
>> >> +	cpu_set_t allowed_mask;
>> >> +	int r, i, nr_cpus, cpu;
>> >> +
>> >> +	CPU_ZERO(&allowed_mask);
>> >> +
>> >> +	nr_cpus = CPU_COUNT(&possible_mask);
>> >> +
>> >> +	for (i = 0; i < 20000; i++) {
>> >> +		cpu = i % nr_cpus;
>> >> +		if (!CPU_ISSET(cpu, &possible_mask))
>> >> +			continue;
>> >> +
>> >> +		CPU_SET(cpu, &allowed_mask);
>> >> +
>> >> +		/*
>> >> +		 * Bump the sequence count twice to allow the reader to detect
>> >> +		 * that a migration may have occurred in between rseq and sched
>> >> +		 * CPU ID reads.  An odd sequence count indicates a migration
>> >> +		 * is in-progress, while a completely different count indicates
>> >> +		 * a migration occurred since the count was last read.
>> >> +		 */
>> >> +		atomic_inc(&seq_cnt);
>> > 
>> > So technically this atomic_inc contains the required barriers because the
>> > selftests implementation uses "__sync_add_and_fetch(&addr->val, 1)". But
>> > it's rather odd that the semantic differs from the kernel implementation in
>> > terms of memory barriers: the kernel implementation of atomic_inc
>> > guarantees no memory barriers, but this one happens to provide full
>> > barriers pretty much by accident (selftests futex/include/atomic.h
>> > documents no such guarantee).
> 
> Yeah, I got quite lost trying to figure out what atomics the test would actually
> end up with.

At the very least, until things are clarified in the selftests atomic header, I would
recommend adding a comment stating which memory barriers are required alongside each
use of atomic_inc here. I would even prefer that we add extra (currently unneeded)
write barriers to make extra sure that this stays documented. Performance of the write-side
does not matter much here.

> 
>> > If this full barrier guarantee is indeed provided by the selftests atomic.h
>> > header, I would really like a comment stating that in the atomic.h header
>> > so the carpet is not pulled from under our feet by a future optimization.
>> > 
>> > 
>> >> +		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
>> >> +		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)",
>> >> +			    errno, strerror(errno));
>> >> +		atomic_inc(&seq_cnt);
>> >> +
>> >> +		CPU_CLR(cpu, &allowed_mask);
>> >> +
>> >> +		/*
>> >> +		 * Let the read-side get back into KVM_RUN to improve the odds
>> >> +		 * of task migration coinciding with KVM's run loop.
>> > 
>> > This comment should be about increasing the odds of letting the seqlock
>> > read-side complete. Otherwise, the delay between the two back-to-back
>> > atomic_inc is so small that the seqlock read-side may never have time to
>> > complete the reading the rseq cpu id and the sched_getcpu() call, and can
>> > retry forever.
> 
> Hmm, but that's not why there's a delay.  I'm not arguing that a livelock isn't
> possible (though that syscall would have to be screaming fast),

I don't think we have the same understanding of the livelock scenario. AFAIU the livelock
would be caused by a too-small delay between the two consecutive atomic_inc() from one
loop iteration to the next compared to the time it takes to perform a read-side critical
section of the seqlock. Back-to-back atomic_inc can be performed very quickly, so I
doubt that the sched_getcpu implementation have good odds to be fast enough to complete
in that narrow window, leading to lots of read seqlock retry.

> but the primary
> motivation is very much to allow the read-side enough time to get back into KVM
> proper.

I'm puzzled by your statement. AFAIU, let's say we don't have the delay, then we
have:

migration thread                             KVM_RUN/read-side thread
-----------------------------------------------------------------------------------
                                             - ioctl(KVM_RUN)
- atomic_inc_seq_cst(&seqcnt)
- sched_setaffinity
- atomic_inc_seq_cst(&seqcnt)
                                             - a = atomic_load(&seqcnt) & ~1
                                             - smp_rmb()
                                             - b = LOAD_ONCE(__rseq_abi->cpu_id);
                                             - sched_getcpu()
                                             - smp_rmb()
                                             - re-load seqcnt/compare (succeeds)
                                               - Can only succeed if entire read-side happens while the seqcnt
                                                 is in an even numbered state.
                                             - if (a != b) abort()
  /* no delay. Even counter state is very
     short. */
- atomic_inc_seq_cst(&seqcnt)
  /* Let's suppose the lack of delay causes the
     setaffinity to complete too early compared
     with KVM_RUN ioctl */
- sched_setaffinity
- atomic_inc_seq_cst(&seqcnt)

  /* no delay. Even counter state is very
     short. */
- atomic_inc_seq_cst(&seqcnt)
  /* Then a setaffinity from a following
     migration thread loop will run
     concurrently with KVM_RUN */
                                             - ioctl(KVM_RUN)
- sched_setaffinity
- atomic_inc_seq_cst(&seqcnt)

As pointed out here, if the first setaffinity runs too early compared with KVM_RUN,
a following setaffinity will run concurrently with it. However, the fact that 
the even counter state is very short may very well hurt progress of the read seqlock.

> 
> To encounter the bug, TIF_NOTIFY_RESUME has to be recognized by KVM in its run
> loop, i.e. sched_setaffinity() must induce task migration after the read-side
> has
> invoked ioctl(KVM_RUN).

No argument here.

> 
>> > I'm wondering if 1 microsecond is sufficient on other architectures as
>> > well.
> 
> I'm definitely wondering that as well :-)
> 
>> > One alternative way to make this depend less on the architecture's
>> > implementation of sched_getcpu (whether it's a vDSO, or goes through a
>> > syscall) would be to read the rseq cpu id and call sched_getcpu a few times
>> > (e.g. 3 times) in the migration thread rather than use usleep, and throw
>> > away the value read. This would ensure the delay is appropriate on all
>> > architectures.
> 
> As above, I think an arbitrary delay is required regardless of how fast
> sched_getcpu() can execute.  One thought would be to do sched_getcpu() _and_
> usleep() to account for sched_getcpu() overhead and to satisfy the KVM_RUN part,
> but I don't know that that adds meaningful value.
> 
> The real test is if someone could see if the bug repros on non-x86 hardware...

As I explain in the scenario above, I don't think we agree on the reason why the
delay is required. One way to confirm this would be to run the code without delay,
and count how many seqcnt read-side succeed vs fail. We can then compare that with
a run with a 1us delay between the migration thread loops. This data should help us
come to a common understanding of the delay's role.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From oupton at google.com  Thu Aug 26 11:49:27 2021
From: oupton at google.com (Oliver Upton)
Date: Thu, 26 Aug 2021 18:49:27 +0000
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <877dg8ppnt.wl-maz@kernel.org>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org>
 <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
 <877dg8ppnt.wl-maz@kernel.org>
Message-ID: <YSfiN3Xq1vUzHeap@google.com>

On Thu, Aug 26, 2021 at 09:37:42AM +0100, Marc Zyngier wrote:
> On Wed, 25 Aug 2021 19:14:59 +0100,
> Oliver Upton <oupton at google.com> wrote:
> > 
> > On Wed, Aug 25, 2021 at 8:07 AM Andrew Jones <drjones at redhat.com> wrote:
> 
> [...]
> 
> > > Thanks for including me Marc. I think you've mentioned all the examples
> > > of why we don't generally expect N+1 -> N migrations to work that I
> > > can think of. While some of the examples like get-reg-list could
> > > eventually be eliminated if we had CPU models to tighten our machine type
> > > state, I think N+1 -> N migrations will always be best effort at most.
> > >
> > > I agree with giving userspace control over the exposer of the hypercalls
> > > though. Using pseudo-registers for that purpose rather than a pile of
> > > CAPs also seems reasonable to me.
> > >
> > > And, while I don't think this patch is going to proceed, I thought I'd
> > > point out that the opt-out approach doesn't help much with expanding
> > > our migration support unless we require the VMM to be upgraded first.
> > >
> > > And, even then, the (N_kern, N+1_vmm) -> (N+1_kern, N_vmm) case won't
> > > work as expected, since the source enforce opt-out, but the destination
> > > won't.
> > 
> > Right, there's going to need to be a fence in both kernel and VMM
> > versions. Before the fence, you can't rollback with either component.
> > Once on the other side of the fence, the user may freely migrate
> > between kernel + VMM combinations.
> >
> > > Also, since the VMM doesn't key off the kernel version, for the
> > > most part N+1 VMMs won't know when they're supposed to opt-out or not,
> > > leaving it to the user to ensure they consider everything. opt-in
> > > usually only needs the user to consider what machine type they want to
> > > launch.
> > 
> > Going the register route will implicitly require opt-out for all old
> > hypercalls. We exposed them unconditionally to the guest before, and
> > we must uphold that behavior. The default value for the bitmap will
> > have those features set. Any hypercalls added after that register
> > interface will then require explicit opt-in from userspace.
> 
> I disagree here. This makes the ABI inconsistent, and means that no
> feature can be implemented without changing userspace. If you can deal
> with the existing features, you should be able to deal with the next
> lot.
>
> > With regards to the pseudoregister interface, how would a VMM discover
> > new bits? From my perspective, you need to have two bitmaps that the
> > VMM can get at: the set of supported feature bits and the active
> > bitmap of features for a running guest.
> 
> My proposal is that we have a single pseudo-register exposing the list
> of implemented by the kernel. Clear the bits you don't want, and write
> back the result. As long as you haven't written anything, you have the
> full feature set. That's pretty similar to the virtio feature
> negotiation.

Ah, yes I agree. Thinking about it more we will not need something
similar to KVM_GET_SUPPORTED_CPUID.

So then, for any register where userspace/KVM need to negotiate
features, the default value will return the maximum feature set that is
supported. If userspace wants to constrain features, read out the
register, make sure everything you want is there, and write it back
blowing away the superfluous bits. Given this should we enforce ordering
on feature registers, such that a VMM can only write to the registers
before a VM is started?

Also, Reiji is working on making the identity registers writable for the
sake of feature restriction. The suggested negotiation interface would
be applicable there too, IMO.

Many thanks to both you and Drew for working this out with me.

--
Best,
Oliver


From pr-tracker-bot at kernel.org  Thu Aug 26 11:52:57 2021
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Thu, 26 Aug 2021 18:52:57 +0000
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <20210826131747.GE26318@willie-the-truck>
References: <20210826131747.GE26318@willie-the-truck>
Message-ID: <163000397717.15844.5138355230241347117.pr-tracker-bot@kernel.org>

The pull request you sent on Thu, 26 Aug 2021 14:17:48 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/1a6d80ff2419e8ad627b4bf4775a8b4c70af535d

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From festevam at gmail.com  Thu Aug 26 12:03:32 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 26 Aug 2021 16:03:32 -0300
Subject: [PATCH v1 2/7] ARM: imx_v6_v7_defconfig: enable fb
In-Reply-To: <20210819140345.357167-3-marcel@ziswiler.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
 <20210819140345.357167-3-marcel@ziswiler.com>
Message-ID: <CAOMZO5B9Tb+1d1eU1huCZKNH6BjdnmvBUnkY_242L1yub=2Q9g@mail.gmail.com>

Hi Marcel,

On Thu, Aug 19, 2021 at 11:04 AM Marcel Ziswiler <marcel at ziswiler.com> wrote:
>
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>
> Enable CONFIG_FB which is nowadays required for CONFIG_DRM_PANEL_LVDS,
> CONFIG_DRM_PANEL_SIMPLE, CONFIG_DRM_PANEL_SEIKO_43WVF1G,
> CONFIG_FB_MODE_HELPERS, CONFIG_BACKLIGHT_PWM, CONFIG_BACKLIGHT_GPIO,
> CONFIG_FRAMEBUFFER_CONSOLE, CONFIG_LOGO, CONFIG_FONTS, CONFIG_FONT_8x8
> and CONFIG_FONT_8x16.
>
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Yes, I noticed that I had no LCD output on an imx6ull-evk board and
after selecting CONFIG_FB it works again.

For the entire series:

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From seanjc at google.com  Thu Aug 26 12:59:13 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 19:59:13 +0000
Subject: [PATCH V10 01/18] perf/core: Use static_call to optimize
 perf_guest_info_callbacks
In-Reply-To: <20210806133802.3528-2-lingshan.zhu@intel.com>
References: <20210806133802.3528-1-lingshan.zhu@intel.com>
 <20210806133802.3528-2-lingshan.zhu@intel.com>
Message-ID: <YSfykbECnC6J02Yk@google.com>

TL;DR: Please don't merge this patch, it's broken and is also built on a shoddy
       foundation that I would like to fix.

On Fri, Aug 06, 2021, Zhu Lingshan wrote:
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 464917096e73..e466fc8176e1 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6489,9 +6489,18 @@ static void perf_pending_event(struct irq_work *entry)
>   */
>  struct perf_guest_info_callbacks *perf_guest_cbs;
>  
> +/* explicitly use __weak to fix duplicate symbol error */
> +void __weak arch_perf_update_guest_cbs(void)
> +{
> +}
> +
>  int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
>  {
> +	if (WARN_ON_ONCE(perf_guest_cbs))
> +		return -EBUSY;
> +
>  	perf_guest_cbs = cbs;
> +	arch_perf_update_guest_cbs();

This is horribly broken, it fails to cleanup the static calls when KVM unregisters
the callbacks, which happens when the vendor module, e.g. kvm_intel, is unloaded.
The explosion doesn't happen until 'kvm' is unloaded because the functions are
implemented in 'kvm', i.e. the use-after-free is deferred a bit.

  BUG: unable to handle page fault for address: ffffffffa011bb90
  #PF: supervisor instruction fetch in kernel mode
  #PF: error_code(0x0010) - not-present page
  PGD 6211067 P4D 6211067 PUD 6212063 PMD 102b99067 PTE 0
  Oops: 0010 [#1] PREEMPT SMP
  CPU: 0 PID: 1047 Comm: rmmod Not tainted 5.14.0-rc2+ #460
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:0xffffffffa011bb90
  Code: Unable to access opcode bytes at RIP 0xffffffffa011bb66.
  Call Trace:
   <NMI>
   ? perf_misc_flags+0xe/0x50
   ? perf_prepare_sample+0x53/0x6b0
   ? perf_event_output_forward+0x67/0x160
   ? kvm_clock_read+0x14/0x30
   ? kvm_sched_clock_read+0x5/0x10
   ? sched_clock_cpu+0xd/0xd0
   ? __perf_event_overflow+0x52/0xf0
   ? handle_pmi_common+0x1f2/0x2d0
   ? __flush_tlb_all+0x30/0x30
   ? intel_pmu_handle_irq+0xcf/0x410
   ? nmi_handle+0x5/0x260
   ? perf_event_nmi_handler+0x28/0x50
   ? nmi_handle+0xc7/0x260
   ? lock_release+0x2b0/0x2b0
   ? default_do_nmi+0x6b/0x170
   ? exc_nmi+0x103/0x130
   ? end_repeat_nmi+0x16/0x1f
   ? lock_release+0x2b0/0x2b0
   ? lock_release+0x2b0/0x2b0
   ? lock_release+0x2b0/0x2b0
   </NMI>
  Modules linked in: irqbypass [last unloaded: kvm]

Even more fun, the existing perf_guest_cbs framework is also broken, though it's
much harder to get it to fail, and probably impossible to get it to fail without
some help.  The issue is that perf_guest_cbs is global, which means that it can
be nullified by KVM (during module unload) while the callbacks are being accessed
by a PMI handler on a different CPU.

The bug has escaped notice because all dererfences of perf_guest_cbs follow the
same "perf_guest_cbs && perf_guest_cbs->is_in_guest()" pattern, and AFAICT the
compiler never reload perf_guest_cbs in this sequence.  The compiler does reload
perf_guest_cbs for any future dereferences, but the ->is_in_guest() guard all but
guarantees the PMI handler will win the race, e.g. to nullify perf_guest_cbs,
KVM has to completely exit the guest and teardown down all VMs before it can be
unloaded.

But with a help, e.g. RAED_ONCE(perf_guest_cbs), unloading kvm_intel can trigger
a NULL pointer derference, e.g. this tweak

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 1eb45139fcc6..202e5ad97f82 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2954,7 +2954,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
 {
        int misc = 0;

-       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+       if (READ_ONCE(perf_guest_cbs) && READ_ONCE(perf_guest_cbs)->is_in_guest()) {
                if (perf_guest_cbs->is_user_mode())
                        misc |= PERF_RECORD_MISC_GUEST_USER;
                else


while spamming module load/unload leads to:

  BUG: kernel NULL pointer dereference, address: 0000000000000000
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: 0000 [#1] PREEMPT SMP
  CPU: 6 PID: 1825 Comm: stress Not tainted 5.14.0-rc2+ #459
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:perf_misc_flags+0x1c/0x70
  Call Trace:
   perf_prepare_sample+0x53/0x6b0
   perf_event_output_forward+0x67/0x160
   __perf_event_overflow+0x52/0xf0
   handle_pmi_common+0x207/0x300
   intel_pmu_handle_irq+0xcf/0x410
   perf_event_nmi_handler+0x28/0x50
   nmi_handle+0xc7/0x260
   default_do_nmi+0x6b/0x170
   exc_nmi+0x103/0x130
   asm_exc_nmi+0x76/0xbf


The good news is that I have a series that should fix both the existing NULL pointer
bug and mostly obviate the need for static calls.  The bad news is that my approach,
making perf_guest_cbs per-CPU, likely complicates turning these into static calls,
though I'm guessing it's still a solvable problem.

Tangentially related, IMO we should make architectures opt-in to getting
perf_guest_cbs and nuke all of the code in the below files.  Except for arm,
which recently lost KVM support, it's all a bunch of useless copy-paste code that
serves no purpose and just complicates cleanups like this.

>  arch/arm/kernel/perf_callchain.c   | 16 +++++++-----
>  arch/csky/kernel/perf_callchain.c  |  4 +--
>  arch/nds32/kernel/perf_event_cpu.c | 16 +++++++-----
>  arch/riscv/kernel/perf_callchain.c |  4 +--


From lkp at intel.com  Thu Aug 26 13:05:57 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 04:05:57 +0800
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
References: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
Message-ID: <202108270339.2LOAeemT-lkp@intel.com>

Hi Chia-Wei,

I love your patch! Perhaps something to improve:

[auto build test WARNING on robh/for-next]
[also build test WARNING on arm/for-next keystone/next soc/for-next rockchip/for-next arm64/for-next/core linus/master joel-aspeed/for-next v5.14-rc7 next-20210826]
[cannot apply to xlnx/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chia-Wei-Wang/arm-aspeed-Add-eSPI-support/20210826-141737
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm64-randconfig-r025-20210826 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/2980a1777c50754fe145f2e73ded8739931c0712
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chia-Wei-Wang/arm-aspeed-Add-eSPI-support/20210826-141737
        git checkout 2980a1777c50754fe145f2e73ded8739931c0712
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/soc/aspeed/aspeed-espi-ctrl.c:22:
   drivers/soc/aspeed/aspeed-espi-perif.h:446:8: error: incompatible pointer types passing 'phys_addr_t *' (aka 'unsigned long long *') to parameter of type 'u32 *' (aka 'unsigned int *') [-Werror,-Wincompatible-pointer-types]
                                             &espi_perif->mcyc_saddr);
                                             ^~~~~~~~~~~~~~~~~~~~~~~
   include/linux/of.h:1249:17: note: passing argument to parameter 'out_value' here
                                          u32 *out_value)
                                               ^
>> drivers/soc/aspeed/aspeed-espi-ctrl.c:98:23: warning: cast to smaller integer type 'uint32_t' (aka 'unsigned int') from 'const void *' [-Wvoid-pointer-to-int-cast]
           espi_ctrl->version = (uint32_t)of_device_get_match_data(dev);
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning and 1 error generated.


vim +98 drivers/soc/aspeed/aspeed-espi-ctrl.c

    87	
    88	static int aspeed_espi_ctrl_probe(struct platform_device *pdev)
    89	{
    90		int rc = 0;
    91		struct aspeed_espi_ctrl *espi_ctrl;
    92		struct device *dev = &pdev->dev;
    93	
    94		espi_ctrl = devm_kzalloc(dev, sizeof(*espi_ctrl), GFP_KERNEL);
    95		if (!espi_ctrl)
    96			return -ENOMEM;
    97	
  > 98		espi_ctrl->version = (uint32_t)of_device_get_match_data(dev);
    99	
   100		espi_ctrl->map = syscon_node_to_regmap(dev->parent->of_node);
   101		if (IS_ERR(espi_ctrl->map)) {
   102			dev_err(dev, "cannot get remap\n");
   103			return -ENODEV;
   104		}
   105	
   106		espi_ctrl->irq = platform_get_irq(pdev, 0);
   107		if (espi_ctrl->irq < 0)
   108			return espi_ctrl->irq;
   109	
   110		espi_ctrl->clk = devm_clk_get(dev, NULL);
   111		if (IS_ERR(espi_ctrl->clk)) {
   112			dev_err(dev, "cannot get clock\n");
   113			return -ENODEV;
   114		}
   115	
   116		rc = clk_prepare_enable(espi_ctrl->clk);
   117		if (rc) {
   118			dev_err(dev, "cannot enable clock\n");
   119			return rc;
   120		}
   121	
   122		espi_ctrl->perif = aspeed_espi_perif_alloc(dev, espi_ctrl);
   123		if (IS_ERR(espi_ctrl->perif)) {
   124			dev_err(dev, "failed to allocate peripheral channel\n");
   125			return PTR_ERR(espi_ctrl->perif);
   126		}
   127	
   128		espi_ctrl->vw = aspeed_espi_vw_alloc(dev, espi_ctrl);
   129		if (IS_ERR(espi_ctrl->vw)) {
   130			dev_err(dev, "failed to allocate virtual wire channel\n");
   131			return PTR_ERR(espi_ctrl->vw);
   132		}
   133	
   134		espi_ctrl->oob = aspeed_espi_oob_alloc(dev, espi_ctrl);
   135		if (IS_ERR(espi_ctrl->oob)) {
   136			dev_err(dev, "failed to allocate out-of-band channel\n");
   137			return PTR_ERR(espi_ctrl->oob);
   138		}
   139	
   140		espi_ctrl->flash = aspeed_espi_flash_alloc(dev, espi_ctrl);
   141		if (rc) {
   142			dev_err(dev, "failed to allocate flash channel\n");
   143			return PTR_ERR(espi_ctrl->flash);
   144		}
   145	
   146		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
   147		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
   148		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
   149	
   150		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
   151		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
   152	
   153		rc = devm_request_irq(dev, espi_ctrl->irq,
   154				      aspeed_espi_ctrl_isr,
   155				      0, DEVICE_NAME, espi_ctrl);
   156		if (rc) {
   157			dev_err(dev, "failed to request IRQ\n");
   158			return rc;
   159		}
   160	
   161		regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
   162				   ESPI_INT_EN_HW_RST_DEASSERT,
   163				   ESPI_INT_EN_HW_RST_DEASSERT);
   164	
   165		dev_set_drvdata(dev, espi_ctrl);
   166	
   167		dev_info(dev, "module loaded\n");
   168	
   169		return 0;
   170	}
   171	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 35430 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210827/0435282b/attachment-0001.gz>

From lkp at intel.com  Thu Aug 26 13:07:24 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 04:07:24 +0800
Subject: [PATCH 2/2] crypto: stm32 - open the configuration for
 COMPILE_TEST
In-Reply-To: <20210825112147.2669-3-caihuoqing@baidu.com>
References: <20210825112147.2669-3-caihuoqing@baidu.com>
Message-ID: <202108270336.4KCayWNU-lkp@intel.com>

Hi Cai,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on cryptodev/master]
[also build test ERROR on crypto/master stm32/stm32-next v5.14-rc7 next-20210826]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Cai-Huoqing/crypto-stm32-Add-support-of-COMPILE_TEST/20210825-192234
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: parisc-randconfig-r035-20210827 (attached as .config)
compiler: hppa64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/ee7c38e84d0080bed97a670609a489b42494c16f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Cai-Huoqing/crypto-stm32-Add-support-of-COMPILE_TEST/20210825-192234
        git checkout ee7c38e84d0080bed97a670609a489b42494c16f
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=parisc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/crypto/stm32/stm32-hash.c: In function 'stm32_hash_dma_send':
>> drivers/crypto/stm32/stm32-hash.c:617:25: error: implicit declaration of function 'writesl'; did you mean 'writel'? [-Werror=implicit-function-declaration]
     617 |                         writesl(hdev->io_base + HASH_DIN, buffer,
         |                         ^~~~~~~
         |                         writel
   cc1: some warnings being treated as errors


vim +617 drivers/crypto/stm32/stm32-hash.c

8a1012d3f2abce lionel.debieve at st.com 2017-07-13  542  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  543  static int stm32_hash_dma_send(struct stm32_hash_dev *hdev)
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  544  {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  545  	struct stm32_hash_request_ctx *rctx = ahash_request_ctx(hdev->req);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  546  	struct scatterlist sg[1], *tsg;
532f419cde077f Arnd Bergmann         2017-09-12  547  	int err = 0, len = 0, reg, ncp = 0;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  548  	unsigned int i;
532f419cde077f Arnd Bergmann         2017-09-12  549  	u32 *buffer = (void *)rctx->buffer;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  550  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  551  	rctx->sg = hdev->req->src;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  552  	rctx->total = hdev->req->nbytes;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  553  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  554  	rctx->nents = sg_nents(rctx->sg);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  555  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  556  	if (rctx->nents < 0)
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  557  		return -EINVAL;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  558  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  559  	stm32_hash_write_ctrl(hdev);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  560  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  561  	if (hdev->flags & HASH_FLAGS_HMAC) {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  562  		err = stm32_hash_hmac_dma_send(hdev);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  563  		if (err != -EINPROGRESS)
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  564  			return err;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  565  	}
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  566  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  567  	for_each_sg(rctx->sg, tsg, rctx->nents, i) {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  568  		len = sg->length;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  569  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  570  		sg[0] = *tsg;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  571  		if (sg_is_last(sg)) {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  572  			if (hdev->dma_mode == 1) {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  573  				len = (ALIGN(sg->length, 16) - 16);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  574  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  575  				ncp = sg_pcopy_to_buffer(
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  576  					rctx->sg, rctx->nents,
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  577  					rctx->buffer, sg->length - len,
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  578  					rctx->total - sg->length + len);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  579  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  580  				sg->length = len;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  581  			} else {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  582  				if (!(IS_ALIGNED(sg->length, sizeof(u32)))) {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  583  					len = sg->length;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  584  					sg->length = ALIGN(sg->length,
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  585  							   sizeof(u32));
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  586  				}
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  587  			}
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  588  		}
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  589  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  590  		rctx->dma_ct = dma_map_sg(hdev->dev, sg, 1,
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  591  					  DMA_TO_DEVICE);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  592  		if (rctx->dma_ct == 0) {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  593  			dev_err(hdev->dev, "dma_map_sg error\n");
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  594  			return -ENOMEM;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  595  		}
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  596  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  597  		err = stm32_hash_xmit_dma(hdev, sg, len,
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  598  					  !sg_is_last(sg));
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  599  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  600  		dma_unmap_sg(hdev->dev, sg, 1, DMA_TO_DEVICE);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  601  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  602  		if (err == -ENOMEM)
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  603  			return err;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  604  	}
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  605  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  606  	if (hdev->dma_mode == 1) {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  607  		if (stm32_hash_wait_busy(hdev))
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  608  			return -ETIMEDOUT;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  609  		reg = stm32_hash_read(hdev, HASH_CR);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  610  		reg &= ~HASH_CR_DMAE;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  611  		reg |= HASH_CR_DMAA;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  612  		stm32_hash_write(hdev, HASH_CR, reg);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  613  
532f419cde077f Arnd Bergmann         2017-09-12  614  		if (ncp) {
532f419cde077f Arnd Bergmann         2017-09-12  615  			memset(buffer + ncp, 0,
532f419cde077f Arnd Bergmann         2017-09-12  616  			       DIV_ROUND_UP(ncp, sizeof(u32)) - ncp);
532f419cde077f Arnd Bergmann         2017-09-12 @617  			writesl(hdev->io_base + HASH_DIN, buffer,
532f419cde077f Arnd Bergmann         2017-09-12  618  				DIV_ROUND_UP(ncp, sizeof(u32)));
532f419cde077f Arnd Bergmann         2017-09-12  619  		}
d03d29bd1857b2 Lionel Debieve        2018-01-29  620  		stm32_hash_set_nblw(hdev, ncp);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  621  		reg = stm32_hash_read(hdev, HASH_STR);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  622  		reg |= HASH_STR_DCAL;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  623  		stm32_hash_write(hdev, HASH_STR, reg);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  624  		err = -EINPROGRESS;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  625  	}
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  626  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  627  	if (hdev->flags & HASH_FLAGS_HMAC) {
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  628  		if (stm32_hash_wait_busy(hdev))
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  629  			return -ETIMEDOUT;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  630  		err = stm32_hash_hmac_dma_send(hdev);
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  631  	}
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  632  
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  633  	return err;
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  634  }
8a1012d3f2abce lionel.debieve at st.com 2017-07-13  635  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 38181 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210827/ab93c040/attachment-0001.gz>

From festevam at gmail.com  Thu Aug 26 13:10:58 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 26 Aug 2021 17:10:58 -0300
Subject: [PATCH 2/2] clk: imx: imx6ul: Fix csi clk gate register
In-Reply-To: <20210826152049.4175381-2-s.riedmueller@phytec.de>
References: <20210826152049.4175381-1-s.riedmueller@phytec.de>
 <20210826152049.4175381-2-s.riedmueller@phytec.de>
Message-ID: <CAOMZO5DR7awy7mxr3=qXiEmSG10MX15hc2MJCSajN+gW8=ryuw@mail.gmail.com>

Hi Stefan,

On Thu, Aug 26, 2021 at 12:20 PM Stefan Riedmueller
<s.riedmueller at phytec.de> wrote:
>
> According to the imx6ul Reference Manual the csi clk gate register is
> CCM_CCGR3 (offset 0x74) bit 0/1. For the imx6ull on the other hand the
> Reference Manual lists register CCM_CCGR2 (offset 0x70) bit 2/3 as the
> csi clk gate which is the current setting.
>
> Tests have shown though that the correct csi clk gate register for the
> imx6ull is actually CCM_CCGR3 bit 0/1 as well. Thus set the correct
> register for both platforms.
>
> Signed-off-by: Stefan Riedmueller <s.riedmueller at phytec.de>

I tested the series on an imx6ull-evk with an OV5640 sensor:

Tested-by: Fabio Estevam <festevam at gmail.com>

but in my case, I did not see the problem even without your patch.

Most likely because the bootloader turned on the CSI clock.

> ---
>  drivers/clk/imx/clk-imx6ul.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
> index 206e4c43f68f..5dd222fab01b 100644
> --- a/drivers/clk/imx/clk-imx6ul.c
> +++ b/drivers/clk/imx/clk-imx6ul.c
> @@ -380,7 +380,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
>                 hws[IMX6ULL_CLK_ESAI_IPG]       = imx_clk_hw_gate2_shared("esai_ipg",   "ahb",          base + 0x70,    0, &share_count_esai);
>                 hws[IMX6ULL_CLK_ESAI_MEM]       = imx_clk_hw_gate2_shared("esai_mem",   "ahb",          base + 0x70,    0, &share_count_esai);
>         }
> -       hws[IMX6UL_CLK_CSI]             = imx_clk_hw_gate2("csi",               "csi_podf",             base + 0x70,    2);
>         hws[IMX6UL_CLK_I2C1]            = imx_clk_hw_gate2("i2c1",              "perclk",       base + 0x70,    6);
>         hws[IMX6UL_CLK_I2C2]            = imx_clk_hw_gate2("i2c2",              "perclk",       base + 0x70,    8);
>         hws[IMX6UL_CLK_I2C3]            = imx_clk_hw_gate2("i2c3",              "perclk",       base + 0x70,    10);
> @@ -391,6 +390,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
>         hws[IMX6UL_CLK_PXP]             = imx_clk_hw_gate2("pxp",               "axi",          base + 0x70,    30);
>
>         /* CCGR3 */

It would be nice to put a comment here explaining the imx6ull
Reference Manual mismatch.

Maybe Abel could help to check internally at NXP?

> +       hws[IMX6UL_CLK_CSI]             = imx_clk_hw_gate2("csi",       "csi_podf",     base + 0x74,    0);

Thanks


From oupton at google.com  Thu Aug 26 13:27:53 2021
From: oupton at google.com (Oliver Upton)
Date: Thu, 26 Aug 2021 20:27:53 +0000
Subject: [PATCH v7 6/6] KVM: x86: Expose TSC offset controls to userspace
In-Reply-To: <20210826124836.GA155749@fuller.cnet>
References: <20210816001130.3059564-1-oupton@google.com>
 <20210816001130.3059564-7-oupton@google.com>
 <CAOQ_Qsj_MfRNRRSK1UswsfBw4c9ugSW6tKXNua=3O78sHEonvA@mail.gmail.com>
 <20210826124836.GA155749@fuller.cnet>
Message-ID: <YSf5SV0AZMvfIEib@google.com>

Marcelo,

On Thu, Aug 26, 2021 at 09:48:36AM -0300, Marcelo Tosatti wrote:
> On Mon, Aug 23, 2021 at 01:56:30PM -0700, Oliver Upton wrote:
> > Paolo,
> > 
> > On Sun, Aug 15, 2021 at 5:11 PM Oliver Upton <oupton at google.com> wrote:
> > >
> > > To date, VMM-directed TSC synchronization and migration has been a bit
> > > messy. KVM has some baked-in heuristics around TSC writes to infer if
> > > the VMM is attempting to synchronize. This is problematic, as it depends
> > > on host userspace writing to the guest's TSC within 1 second of the last
> > > write.
> > >
> > > A much cleaner approach to configuring the guest's views of the TSC is to
> > > simply migrate the TSC offset for every vCPU. Offsets are idempotent,
> > > and thus not subject to change depending on when the VMM actually
> > > reads/writes values from/to KVM. The VMM can then read the TSC once with
> > > KVM_GET_CLOCK to capture a (realtime, host_tsc) pair at the instant when
> > > the guest is paused.
> > >
> > > Cc: David Matlack <dmatlack at google.com>
> > > Cc: Sean Christopherson <seanjc at google.com>
> > > Signed-off-by: Oliver Upton <oupton at google.com>
> > 
> > Could you please squash the following into this patch? We need to
> > advertise KVM_CAP_VCPU_ATTRIBUTES to userspace. Otherwise, happy to
> > resend.
> > 
> > Thanks,
> > Oliver
> 
> Oliver,
> 
> Is there QEMU support for this, or are you using your own
> userspace with this?

Apologies for not getting back to you on your first mail. Sadly, I am
using our own userspace for this. That being said, adding support to
QEMU shouldn't be too challenging. I can take a stab at it if it makes
the series more amenable to upstream, with the giant disclaimer that I
haven't done work in QEMU before. Otherwise, happy to review someone
else's implementation.

--
Thanks,
Oliver


From sean.anderson at seco.com  Thu Aug 26 14:18:28 2021
From: sean.anderson at seco.com (Sean Anderson)
Date: Thu, 26 Aug 2021 17:18:28 -0400
Subject: [PATCH v6 1/3] dt-bindings: pwm: Add Xilinx AXI Timer
Message-ID: <20210826211830.3311140-1-sean.anderson@seco.com>

This adds a binding for the Xilinx LogiCORE IP AXI Timer. This device is a
"soft" block, so it has some parameters which would not be configurable in
most hardware. This binding is usually automatically generated by Xilinx's
tools, so the names and values of some properties should be kept as they
are, if possible. In addition, this binding is already in the kernel at
arch/microblaze/boot/dts/system.dts, and in user software such as QEMU.

The existing driver uses the clock-frequency property, or alternatively the
/cpus/timebase-frequency property as its frequency input. Because these
properties are deprecated, they have not been included with this schema.
All new bindings should use the clocks/clock-names properties to specify
the parent clock.

Because we need to init timer devices so early in boot, we determine if we
should use the PWM driver or the clocksource/clockevent driver by the
presence/absence, respectively, of #pwm-cells. Because both counters are
used by the PWM, there is no need for a separate property specifying which
counters are to be used for the PWM.

Signed-off-by: Sean Anderson <sean.anderson at seco.com>
---

Changes in v6:
- Fix incorrect schema id
- Enumerate possible counter widths

Changes in v5:
- Update commit message to reflect revisions
- Fix indentation lint
- Add example for timer binding
- Remove xlnx,axi-timer-2.0 compatible string
- Move schema into the timer directory

Changes in v4:
- Remove references to generate polarity so this can get merged
- Predicate PWM driver on the presence of #pwm-cells
- Make some properties optional for clocksource drivers

Changes in v3:
- Mark all boolean-as-int properties as deprecated
- Add xlnx,pwm and xlnx,gen?-active-low properties.
- Make newer replacement properties mutually-exclusive with what they
  replace
- Add an example with non-deprecated properties only.

Changes in v2:
- Use 32-bit addresses for example binding

 .../bindings/timer/xlnx,xps-timer.yaml        | 90 +++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml

diff --git a/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml b/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml
new file mode 100644
index 000000000000..5be353a642aa
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/timer/xlnx,xps-timer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx LogiCORE IP AXI Timer Device Tree Binding
+
+maintainers:
+  - Sean Anderson <sean.anderson at seco.com>
+
+properties:
+  compatible:
+    contains:
+      const: xlnx,xps-timer-1.00.a
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: s_axi_aclk
+
+  interrupts:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+  xlnx,count-width:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8, 16, 32]
+    default: 32
+    description:
+      The width of the counter(s), in bits.
+
+  xlnx,one-timer-only:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [ 0, 1 ]
+    description:
+      Whether only one timer is present in this block.
+
+required:
+  - compatible
+  - reg
+  - xlnx,one-timer-only
+
+allOf:
+  - if:
+      required:
+        - '#pwm-cells'
+    then:
+      allOf:
+        - required:
+            - clocks
+        - properties:
+            xlnx,one-timer-only:
+              const: 0
+    else:
+      required:
+        - interrupts
+  - if:
+      required:
+        - clocks
+    then:
+      required:
+        - clock-names
+
+additionalProperties: true
+
+examples:
+  - |
+    timer at 800e0000 {
+        clock-names = "s_axi_aclk";
+        clocks = <&zynqmp_clk 71>;
+        compatible = "xlnx,xps-timer-1.00.a";
+        reg = <0x800e0000 0x10000>;
+        interrupts = <0 39 2>;
+        xlnx,count-width = <16>;
+        xlnx,one-timer-only = <0x0>;
+    };
+
+    timer at 800f0000 {
+        #pwm-cells = <0>;
+        clock-names = "s_axi_aclk";
+        clocks = <&zynqmp_clk 71>;
+        compatible = "xlnx,xps-timer-1.00.a";
+        reg = <0x800e0000 0x10000>;
+        xlnx,count-width = <32>;
+        xlnx,one-timer-only = <0x0>;
+    };
-- 
2.25.1



From sean.anderson at seco.com  Thu Aug 26 14:18:29 2021
From: sean.anderson at seco.com (Sean Anderson)
Date: Thu, 26 Aug 2021 17:18:29 -0400
Subject: [PATCH v6 2/3] clocksource: Rewrite Xilinx AXI timer driver
In-Reply-To: <20210826211830.3311140-1-sean.anderson@seco.com>
References: <20210826211830.3311140-1-sean.anderson@seco.com>
Message-ID: <20210826211830.3311140-2-sean.anderson@seco.com>

This rewrites the Xilinx AXI timer driver to be more platform agnostic.
Some common code has been split off so it can be reused. These routines
currently live in drivers/mfd. The largest changes are summarized below:

- We now support any number of timer devices, possibly with only one
  counter each. The first counter will be used as a clocksource. Every
  other counter will be used as a clockevent. This allocation scheme was
  chosen arbitrarily.
- We do not use timer_of_init because we need to perform some tasks in
  between different stages. For example, we must ensure that ->read and
  ->write are initialized before registering the irq. This can only happen
  after we have gotten the register base (to detect endianness). We also
  have a rather unusual clock initialization sequence in order to remain
  backwards compatible. Due to this, it's ok for the initial clock request
  to fail, and we do not want other initialization to be undone. Lastly, it
  is more convenient to do one allocation for xilinx_clockevent_device than
  to do one for timer_of and one for xilinx_timer_priv.
- We now pay attention to xlnx,count-width and handle smaller width timers.
  The default remains 32.
- We access registers using regmap. This automatically deals with
  endianness issues, so we no longer have to use our own wrappers. It
  also provides locking for clockevents which have to worry about being
  interrupted in the middle of a read/modify/write.

Note that while the existing timer driver always sets the cpumask to cpu
0, this version sets it to all possible CPUs. I believe this is correct
for multiprocessor systems where the timer is not physically wired to a
particular CPU's interrupt line. For uniprocessor systems (like most
microblaze systems) this makes no difference.

Signed-off-by: Sean Anderson <sean.anderson at seco.com>
---
This has been tested on microblaze qemu.

Changes in v6:
- Add __init* attributes
- Remove duplicate regmap_config
- Export common symbols
- Fix goto'ing incorrect label for cleanup
- Round to closest period in xilinx_timer_get_period to ensure proper
  semantics for xilinx_pwm_get_state

Changes in v5:
- Remove duplicate register definitions
- Remove xilinx_timer_tlr_period
- Require that callers check arguments to xilinx_timer_tlr_cycles
- Remove xlnx,axi-timer-2.0 compatible string
- Use regmap to deal with endianness issues as suggested by Lee
- Fix some overflows when setting the max value for clockevent and
  sched_clock
- Just use clk_register_fixed_rate instead of the "private" version

Changes in v4:
- Break out clock* drivers into their own file

 MAINTAINERS                               |   6 +
 arch/microblaze/kernel/Makefile           |   3 +-
 arch/microblaze/kernel/timer.c            | 326 ----------------------
 drivers/clocksource/Kconfig               |  12 +
 drivers/clocksource/Makefile              |   1 +
 drivers/clocksource/timer-xilinx-common.c |  71 +++++
 drivers/clocksource/timer-xilinx.c        | 323 +++++++++++++++++++++
 include/clocksource/timer-xilinx.h        |  91 ++++++
 8 files changed, 505 insertions(+), 328 deletions(-)
 delete mode 100644 arch/microblaze/kernel/timer.c
 create mode 100644 drivers/clocksource/timer-xilinx-common.c
 create mode 100644 drivers/clocksource/timer-xilinx.c
 create mode 100644 include/clocksource/timer-xilinx.h

diff --git a/MAINTAINERS b/MAINTAINERS
index bd7aff0c120f..252d71addd18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20046,6 +20046,12 @@ F:	drivers/misc/Makefile
 F:	drivers/misc/xilinx_sdfec.c
 F:	include/uapi/misc/xilinx_sdfec.h
 
+XILINX TIMER/PWM DRIVER
+M:	Sean Anderson <sean.anderson at seco.com>
+S:	Maintained
+F:	drivers/clocksource/timer-xilinx*
+F:	include/clocksource/timer-xilinx.h
+
 XILINX UARTLITE SERIAL DRIVER
 M:	Peter Korsgaard <jacmet at sunsite.dk>
 L:	linux-serial at vger.kernel.org
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index 15a20eb814ce..3b6d725398f8 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -5,7 +5,6 @@
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace early boot code and low level code
-CFLAGS_REMOVE_timer.o = -pg
 CFLAGS_REMOVE_intc.o = -pg
 CFLAGS_REMOVE_early_printk.o = -pg
 CFLAGS_REMOVE_ftrace.o = -pg
@@ -17,7 +16,7 @@ extra-y := head.o vmlinux.lds
 obj-y += dma.o exceptions.o \
 	hw_exception_handler.o irq.o \
 	process.o prom.o ptrace.o \
-	reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
+	reset.o setup.o signal.o sys_microblaze.o traps.o unwind.o
 
 obj-y += cpu/
 
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
deleted file mode 100644
index f8832cf49384..000000000000
--- a/arch/microblaze/kernel/timer.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2007-2013 Michal Simek <monstr at monstr.eu>
- * Copyright (C) 2012-2013 Xilinx, Inc.
- * Copyright (C) 2007-2009 PetaLogix
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/sched/clock.h>
-#include <linux/sched_clock.h>
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/timecounter.h>
-#include <asm/cpuinfo.h>
-
-static void __iomem *timer_baseaddr;
-
-static unsigned int freq_div_hz;
-static unsigned int timer_clock_freq;
-
-#define TCSR0	(0x00)
-#define TLR0	(0x04)
-#define TCR0	(0x08)
-#define TCSR1	(0x10)
-#define TLR1	(0x14)
-#define TCR1	(0x18)
-
-#define TCSR_MDT	(1<<0)
-#define TCSR_UDT	(1<<1)
-#define TCSR_GENT	(1<<2)
-#define TCSR_CAPT	(1<<3)
-#define TCSR_ARHT	(1<<4)
-#define TCSR_LOAD	(1<<5)
-#define TCSR_ENIT	(1<<6)
-#define TCSR_ENT	(1<<7)
-#define TCSR_TINT	(1<<8)
-#define TCSR_PWMA	(1<<9)
-#define TCSR_ENALL	(1<<10)
-
-static unsigned int (*read_fn)(void __iomem *);
-static void (*write_fn)(u32, void __iomem *);
-
-static void timer_write32(u32 val, void __iomem *addr)
-{
-	iowrite32(val, addr);
-}
-
-static unsigned int timer_read32(void __iomem *addr)
-{
-	return ioread32(addr);
-}
-
-static void timer_write32_be(u32 val, void __iomem *addr)
-{
-	iowrite32be(val, addr);
-}
-
-static unsigned int timer_read32_be(void __iomem *addr)
-{
-	return ioread32be(addr);
-}
-
-static inline void xilinx_timer0_stop(void)
-{
-	write_fn(read_fn(timer_baseaddr + TCSR0) & ~TCSR_ENT,
-		 timer_baseaddr + TCSR0);
-}
-
-static inline void xilinx_timer0_start_periodic(unsigned long load_val)
-{
-	if (!load_val)
-		load_val = 1;
-	/* loading value to timer reg */
-	write_fn(load_val, timer_baseaddr + TLR0);
-
-	/* load the initial value */
-	write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
-
-	/* see timer data sheet for detail
-	 * !ENALL - don't enable 'em all
-	 * !PWMA - disable pwm
-	 * TINT - clear interrupt status
-	 * ENT- enable timer itself
-	 * ENIT - enable interrupt
-	 * !LOAD - clear the bit to let go
-	 * ARHT - auto reload
-	 * !CAPT - no external trigger
-	 * !GENT - no external signal
-	 * UDT - set the timer as down counter
-	 * !MDT0 - generate mode
-	 */
-	write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
-		 timer_baseaddr + TCSR0);
-}
-
-static inline void xilinx_timer0_start_oneshot(unsigned long load_val)
-{
-	if (!load_val)
-		load_val = 1;
-	/* loading value to timer reg */
-	write_fn(load_val, timer_baseaddr + TLR0);
-
-	/* load the initial value */
-	write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
-
-	write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
-		 timer_baseaddr + TCSR0);
-}
-
-static int xilinx_timer_set_next_event(unsigned long delta,
-					struct clock_event_device *dev)
-{
-	pr_debug("%s: next event, delta %x\n", __func__, (u32)delta);
-	xilinx_timer0_start_oneshot(delta);
-	return 0;
-}
-
-static int xilinx_timer_shutdown(struct clock_event_device *evt)
-{
-	pr_info("%s\n", __func__);
-	xilinx_timer0_stop();
-	return 0;
-}
-
-static int xilinx_timer_set_periodic(struct clock_event_device *evt)
-{
-	pr_info("%s\n", __func__);
-	xilinx_timer0_start_periodic(freq_div_hz);
-	return 0;
-}
-
-static struct clock_event_device clockevent_xilinx_timer = {
-	.name			= "xilinx_clockevent",
-	.features		= CLOCK_EVT_FEAT_ONESHOT |
-				  CLOCK_EVT_FEAT_PERIODIC,
-	.shift			= 8,
-	.rating			= 300,
-	.set_next_event		= xilinx_timer_set_next_event,
-	.set_state_shutdown	= xilinx_timer_shutdown,
-	.set_state_periodic	= xilinx_timer_set_periodic,
-};
-
-static inline void timer_ack(void)
-{
-	write_fn(read_fn(timer_baseaddr + TCSR0), timer_baseaddr + TCSR0);
-}
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = &clockevent_xilinx_timer;
-	timer_ack();
-	evt->event_handler(evt);
-	return IRQ_HANDLED;
-}
-
-static __init int xilinx_clockevent_init(void)
-{
-	clockevent_xilinx_timer.mult =
-		div_sc(timer_clock_freq, NSEC_PER_SEC,
-				clockevent_xilinx_timer.shift);
-	clockevent_xilinx_timer.max_delta_ns =
-		clockevent_delta2ns((u32)~0, &clockevent_xilinx_timer);
-	clockevent_xilinx_timer.max_delta_ticks = (u32)~0;
-	clockevent_xilinx_timer.min_delta_ns =
-		clockevent_delta2ns(1, &clockevent_xilinx_timer);
-	clockevent_xilinx_timer.min_delta_ticks = 1;
-	clockevent_xilinx_timer.cpumask = cpumask_of(0);
-	clockevents_register_device(&clockevent_xilinx_timer);
-
-	return 0;
-}
-
-static u64 xilinx_clock_read(void)
-{
-	return read_fn(timer_baseaddr + TCR1);
-}
-
-static u64 xilinx_read(struct clocksource *cs)
-{
-	/* reading actual value of timer 1 */
-	return (u64)xilinx_clock_read();
-}
-
-static struct timecounter xilinx_tc = {
-	.cc = NULL,
-};
-
-static u64 xilinx_cc_read(const struct cyclecounter *cc)
-{
-	return xilinx_read(NULL);
-}
-
-static struct cyclecounter xilinx_cc = {
-	.read = xilinx_cc_read,
-	.mask = CLOCKSOURCE_MASK(32),
-	.shift = 8,
-};
-
-static int __init init_xilinx_timecounter(void)
-{
-	xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
-				xilinx_cc.shift);
-
-	timecounter_init(&xilinx_tc, &xilinx_cc, sched_clock());
-
-	return 0;
-}
-
-static struct clocksource clocksource_microblaze = {
-	.name		= "xilinx_clocksource",
-	.rating		= 300,
-	.read		= xilinx_read,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static int __init xilinx_clocksource_init(void)
-{
-	int ret;
-
-	ret = clocksource_register_hz(&clocksource_microblaze,
-				      timer_clock_freq);
-	if (ret) {
-		pr_err("failed to register clocksource");
-		return ret;
-	}
-
-	/* stop timer1 */
-	write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT,
-		 timer_baseaddr + TCSR1);
-	/* start timer1 - up counting without interrupt */
-	write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1);
-
-	/* register timecounter - for ftrace support */
-	return init_xilinx_timecounter();
-}
-
-static int __init xilinx_timer_init(struct device_node *timer)
-{
-	struct clk *clk;
-	static int initialized;
-	u32 irq;
-	u32 timer_num = 1;
-	int ret;
-
-	if (initialized)
-		return -EINVAL;
-
-	initialized = 1;
-
-	timer_baseaddr = of_iomap(timer, 0);
-	if (!timer_baseaddr) {
-		pr_err("ERROR: invalid timer base address\n");
-		return -ENXIO;
-	}
-
-	write_fn = timer_write32;
-	read_fn = timer_read32;
-
-	write_fn(TCSR_MDT, timer_baseaddr + TCSR0);
-	if (!(read_fn(timer_baseaddr + TCSR0) & TCSR_MDT)) {
-		write_fn = timer_write32_be;
-		read_fn = timer_read32_be;
-	}
-
-	irq = irq_of_parse_and_map(timer, 0);
-	if (irq <= 0) {
-		pr_err("Failed to parse and map irq");
-		return -EINVAL;
-	}
-
-	of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num);
-	if (timer_num) {
-		pr_err("Please enable two timers in HW\n");
-		return -EINVAL;
-	}
-
-	pr_info("%pOF: irq=%d\n", timer, irq);
-
-	clk = of_clk_get(timer, 0);
-	if (IS_ERR(clk)) {
-		pr_err("ERROR: timer CCF input clock not found\n");
-		/* If there is clock-frequency property than use it */
-		of_property_read_u32(timer, "clock-frequency",
-				    &timer_clock_freq);
-	} else {
-		timer_clock_freq = clk_get_rate(clk);
-	}
-
-	if (!timer_clock_freq) {
-		pr_err("ERROR: Using CPU clock frequency\n");
-		timer_clock_freq = cpuinfo.cpu_clock_freq;
-	}
-
-	freq_div_hz = timer_clock_freq / HZ;
-
-	ret = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer",
-			  &clockevent_xilinx_timer);
-	if (ret) {
-		pr_err("Failed to setup IRQ");
-		return ret;
-	}
-
-	ret = xilinx_clocksource_init();
-	if (ret)
-		return ret;
-
-	ret = xilinx_clockevent_init();
-	if (ret)
-		return ret;
-
-	sched_clock_register(xilinx_clock_read, 32, timer_clock_freq);
-
-	return 0;
-}
-
-TIMER_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a",
-		       xilinx_timer_init);
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 39aa21d01e05..daa9d55927ec 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -693,4 +693,16 @@ config MICROCHIP_PIT64B
 	  modes and high resolution. It is used as a clocksource
 	  and a clockevent.
 
+config XILINX_TIMER
+	bool "Xilinx AXI Timer support"
+	depends on COMMON_CLK
+	select REGMAP_MMIO
+	default y if MICROBLAZE
+	help
+	  Clocksource/clockevent driver for Xilinx LogiCORE IP AXI
+	  timers. This timer is typically a soft core which may be
+	  present in Xilinx FPGAs. This device may also be present in
+	  Microblaze soft processors. If you don't have this IP in your
+	  design, choose N.
+
 endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c17ee32a7151..a7cba6ef5782 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -88,3 +88,4 @@ obj-$(CONFIG_CSKY_MP_TIMER)		+= timer-mp-csky.o
 obj-$(CONFIG_GX6605S_TIMER)		+= timer-gx6605s.o
 obj-$(CONFIG_HYPERV_TIMER)		+= hyperv_timer.o
 obj-$(CONFIG_MICROCHIP_PIT64B)		+= timer-microchip-pit64b.o
+obj-$(CONFIG_XILINX_TIMER)		+= timer-xilinx.o timer-xilinx-common.o
diff --git a/drivers/clocksource/timer-xilinx-common.c b/drivers/clocksource/timer-xilinx-common.c
new file mode 100644
index 000000000000..b07156faba4e
--- /dev/null
+++ b/drivers/clocksource/timer-xilinx-common.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Sean Anderson <sean.anderson at seco.com>
+ *
+ * For Xilinx LogiCORE IP AXI Timer documentation, refer to DS764:
+ * https://www.xilinx.com/support/documentation/ip_documentation/axi_timer/v1_03_a/axi_timer_ds764.pdf
+ */
+
+#include <clocksource/timer-xilinx.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+
+u32 xilinx_timer_tlr_cycles(struct xilinx_timer_priv *priv, u32 tcsr,
+			    u64 cycles)
+{
+	WARN_ON(cycles < 2 || cycles - 2 > priv->max);
+
+	if (tcsr & TCSR_UDT)
+		return cycles - 2;
+	else
+		return priv->max - cycles + 2;
+}
+EXPORT_SYMBOL_GPL(xilinx_timer_tlr_cycles);
+
+unsigned int xilinx_timer_get_period(struct xilinx_timer_priv *priv,
+				     u32 tlr, u32 tcsr)
+{
+	u64 cycles;
+
+	if (tcsr & TCSR_UDT)
+		cycles = tlr + 2;
+	else
+		cycles = (u64)priv->max - tlr + 2;
+
+	/* cycles has a max of 2^32 + 2 */
+	return DIV64_U64_ROUND_CLOSEST(cycles * NSEC_PER_SEC,
+				       clk_get_rate(priv->clk));
+}
+EXPORT_SYMBOL_GPL(xilinx_timer_get_period);
+
+int xilinx_timer_common_init(struct device_node *np,
+			     struct xilinx_timer_priv *priv,
+			     u32 *one_timer)
+{
+	int ret;
+	u32 width;
+
+	ret = of_property_read_u32(np, "xlnx,one-timer-only", one_timer);
+	if (ret) {
+		pr_err("%pOF: err %d: xlnx,one-timer-only\n", np, ret);
+		return ret;
+	} else if (*one_timer && *one_timer != 1) {
+		pr_err("%pOF: xlnx,one-timer-only must be 0 or 1\n", np);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32(np, "xlnx,count-width", &width);
+	if (ret == -EINVAL) {
+		width = 32;
+	} else if (ret) {
+		pr_err("%pOF: err %d: xlnx,count-width\n", np, ret);
+		return ret;
+	} else if (width < 8 || width > 32) {
+		pr_err("%pOF: invalid counter width\n", np);
+		return -EINVAL;
+	}
+	priv->max = BIT_ULL(width) - 1;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xilinx_timer_common_init);
diff --git a/drivers/clocksource/timer-xilinx.c b/drivers/clocksource/timer-xilinx.c
new file mode 100644
index 000000000000..142949a69502
--- /dev/null
+++ b/drivers/clocksource/timer-xilinx.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Sean Anderson <sean.anderson at seco.com>
+ *
+ * Limitations:
+ * - When in cascade mode we cannot read the full 64-bit counter in one go
+ */
+
+#include <clocksource/timer-xilinx.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/log2.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/sched_clock.h>
+#if IS_ENABLED(CONFIG_MICROBLAZE)
+#include <asm/cpuinfo.h>
+#endif
+
+struct xilinx_clocksource_device {
+	struct clocksource cs;
+	struct xilinx_timer_priv priv;
+};
+
+static inline struct xilinx_timer_priv
+*xilinx_clocksource_to_priv(struct clocksource *cs)
+{
+	return &container_of(cs, struct xilinx_clocksource_device, cs)->priv;
+}
+
+static u64 xilinx_clocksource_read(struct clocksource *cs)
+{
+	struct xilinx_timer_priv *priv = xilinx_clocksource_to_priv(cs);
+	unsigned int ret;
+
+	regmap_read(priv->map, TCR0, &ret);
+	return ret;
+}
+
+static struct xilinx_clocksource_device xilinx_clocksource = {
+	.cs = {
+		.name = "xilinx_clocksource",
+		.rating = 300,
+		.read = xilinx_clocksource_read,
+		.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+		.owner = THIS_MODULE,
+	},
+};
+
+static u64 xilinx_sched_read(void)
+{
+	return xilinx_clocksource_read(&xilinx_clocksource.cs);
+}
+
+static int __init xilinx_clocksource_init(struct device_node *np)
+{
+	int ret;
+	struct xilinx_timer_priv *priv = &xilinx_clocksource.priv;
+	static const struct reg_sequence init[] = {
+		REG_SEQ0(TLR0, 0),
+		REG_SEQ0(TCSR0, TCSR_LOAD | TCSR_TINT),
+		REG_SEQ0(TCSR0, TCSR_ARHT | TCSR_ENT),
+	};
+
+	ret = regmap_multi_reg_write(priv->map, init, ARRAY_SIZE(init));
+	if (ret)
+		return ret;
+
+	xilinx_clocksource.cs.mask = priv->max;
+	ret = clocksource_register_hz(&xilinx_clocksource.cs,
+				      clk_get_rate(priv->clk));
+	if (!ret)
+		sched_clock_register(xilinx_sched_read,
+				     ilog2((u64)priv->max + 1),
+				     clk_get_rate(priv->clk));
+	else
+		pr_err("%pOF: err %d: could not register clocksource\n",
+		       np, ret);
+	return ret;
+}
+
+struct xilinx_clockevent_device {
+	struct clock_event_device ce;
+	struct xilinx_timer_priv priv;
+};
+
+static inline struct xilinx_timer_priv
+*xilinx_clockevent_to_priv(struct clock_event_device *ce)
+{
+	return &container_of(ce, struct xilinx_clockevent_device, ce)->priv;
+}
+
+static irqreturn_t xilinx_timer_handler(int irq, void *p)
+{
+	struct xilinx_clockevent_device *dev = p;
+
+	if (regmap_test_bits(dev->priv.map, TCSR0, TCSR_TINT) <= 0)
+		return IRQ_NONE;
+
+	regmap_clear_bits(dev->priv.map, TCSR0, TCSR_TINT);
+	dev->ce.event_handler(&dev->ce);
+	return IRQ_HANDLED;
+}
+
+static int xilinx_clockevent_next_event(unsigned long evt,
+					struct clock_event_device *ce)
+{
+	struct xilinx_timer_priv *priv = xilinx_clockevent_to_priv(ce);
+	struct reg_sequence next[] = {
+		REG_SEQ0(TLR0, evt - 2),
+		REG_SEQ0(TCSR0, TCSR_LOAD),
+		REG_SEQ0(TCSR0, TCSR_ENIT | TCSR_ENT),
+	};
+
+	return regmap_multi_reg_write(priv->map, next, ARRAY_SIZE(next));
+}
+
+static int xilinx_clockevent_state_periodic(struct clock_event_device *ce)
+{
+	struct xilinx_timer_priv *priv = xilinx_clockevent_to_priv(ce);
+	struct reg_sequence periodic[] = {
+		REG_SEQ0(TLR0, 0),
+		REG_SEQ0(TCSR0, TCSR_LOAD),
+		REG_SEQ0(TCSR0, TCSR_ARHT | TCSR_ENIT | TCSR_ENT),
+	};
+	unsigned long cycles = clk_get_rate(priv->clk) / HZ;
+
+	if (cycles < 2 || cycles - 2 > priv->max)
+		return -ERANGE;
+	periodic[0].def = xilinx_timer_tlr_cycles(priv, 0, cycles);
+
+	return regmap_multi_reg_write(priv->map, periodic, ARRAY_SIZE(periodic));
+}
+
+static int xilinx_clockevent_shutdown(struct clock_event_device *ce)
+{
+	struct xilinx_timer_priv *priv = xilinx_clockevent_to_priv(ce);
+
+	return regmap_write(priv->map, TCSR0, 0);
+}
+
+static const struct clock_event_device xilinx_clockevent_base __initconst = {
+	.rating = 300,
+	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_next_event = xilinx_clockevent_next_event,
+	.set_state_periodic = xilinx_clockevent_state_periodic,
+	.set_state_shutdown = xilinx_clockevent_shutdown,
+	.cpumask = cpu_possible_mask,
+	.owner = THIS_MODULE,
+};
+
+static int __init xilinx_clockevent_init(struct device_node *np,
+					 struct xilinx_clockevent_device *dev)
+{
+	int irq, ret;
+
+	irq = ret = of_irq_get(np, 0);
+	if (ret < 0) {
+		pr_err("%pOF: err %d: could not get irq\n", np, ret);
+		return ret;
+	}
+
+	ret = request_irq(irq, xilinx_timer_handler, IRQF_TIMER,
+			  of_node_full_name(np), dev);
+	if (ret) {
+		pr_err("%pOF: err %d: could not request irq\n", np, ret);
+		return ret;
+	}
+
+	memcpy(&dev->ce, &xilinx_clockevent_base, sizeof(dev->ce));
+	dev->ce.name = of_node_full_name(np);
+	clockevents_config_and_register(&dev->ce, clk_get_rate(dev->priv.clk), 2,
+					min_t(u64, (u64)dev->priv.max + 2,
+					      ULONG_MAX));
+	return 0;
+}
+
+static const struct regmap_config xilinx_timer_regmap_config __initconst = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.val_format_endian = REGMAP_ENDIAN_LITTLE,
+	.max_register = TCR0,
+};
+
+static bool clocksource_uninitialized __initdata = true;
+
+static int __init xilinx_timer_init(struct device_node *np)
+{
+	bool artificial_clock = false;
+	int ret;
+	struct xilinx_timer_priv *priv;
+	struct xilinx_clockevent_device *dev;
+	u32 one_timer;
+	void __iomem *regs;
+
+	if (of_property_read_bool(np, "#pwm-cells"))
+		return 0;
+
+	regs = of_iomap(np, 0);
+	if (IS_ERR(regs)) {
+		ret = PTR_ERR(regs);
+		pr_err("%pOF: err %d: failed to map regs\n", np, ret);
+		return ret;
+	}
+
+	if (clocksource_uninitialized) {
+		priv = &xilinx_clocksource.priv;
+	} else {
+		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+		if (!dev) {
+			ret = -ENOMEM;
+			goto err_regs;
+		}
+		priv = &dev->priv;
+	}
+
+	priv->map = regmap_init_mmio(NULL, regs, &xilinx_timer_regmap_config);
+	if (IS_ERR(priv->map)) {
+		ret = PTR_ERR(priv->map);
+		goto err_priv;
+	}
+
+	ret = xilinx_timer_common_init(np, priv, &one_timer);
+	if (ret)
+		goto err_regmap;
+
+	priv->clk = of_clk_get_by_name(np, "s_axi_aclk");
+	if (IS_ERR(priv->clk)) {
+		u32 freq;
+
+		ret = PTR_ERR(priv->clk);
+		if (ret == -EPROBE_DEFER)
+			goto err_regs;
+
+		pr_warn("%pOF: missing s_axi_aclk, falling back to clock-frequency\n",
+			np);
+		ret = of_property_read_u32(np, "clock-frequency", &freq);
+		if (ret) {
+#if IS_ENABLED(CONFIG_MICROBLAZE)
+			pr_warn("%pOF: missing clock-frequency, falling back to /cpus/timebase-frequency\n",
+				np);
+			freq = cpuinfo.cpu_clock_freq;
+#else
+			goto err_regmap;
+#endif
+		}
+
+		priv->clk = clk_register_fixed_rate(NULL, of_node_full_name(np),
+						    NULL, 0, freq);
+		if (IS_ERR(priv->clk)) {
+			ret = PTR_ERR(priv->clk);
+			goto err_regmap;
+		}
+		artificial_clock = true;
+	}
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		pr_err("%pOF: err %d: clock enable failed\n", np, ret);
+		goto err_clk_init;
+	}
+	clk_rate_exclusive_get(priv->clk);
+
+	if (clocksource_uninitialized) {
+		ret = xilinx_clocksource_init(np);
+		if (ret)
+			goto err_clk_enable;
+		clocksource_uninitialized = false;
+	} else {
+		ret = xilinx_clockevent_init(np, dev);
+		if (ret)
+			goto err_clk_enable;
+	}
+	of_node_set_flag(np, OF_POPULATED);
+
+	if (!one_timer) {
+		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+		if (!dev)
+			return -ENOMEM;
+
+		/*
+		 * We don't support removal, so don't bother enabling
+		 * the clock twice.
+		 */
+		memcpy(&dev->priv, priv, sizeof(dev->priv));
+		dev->priv.map = regmap_init_mmio(NULL, regs + TCSR1,
+						 &xilinx_timer_regmap_config);
+		if (!IS_ERR(dev->priv.map)) {
+			ret = xilinx_clockevent_init(np, dev);
+			if (!ret)
+				return 0;
+			regmap_exit(dev->priv.map);
+		} else {
+			ret = PTR_ERR(dev->priv.map);
+		}
+		kfree(dev);
+	}
+	return ret;
+
+err_clk_enable:
+	clk_rate_exclusive_put(priv->clk);
+	clk_disable_unprepare(priv->clk);
+err_clk_init:
+	if (artificial_clock)
+		clk_unregister_fixed_rate(priv->clk);
+	else
+		clk_put(priv->clk);
+err_regmap:
+	regmap_exit(priv->map);
+err_priv:
+	if (!clocksource_uninitialized)
+		kfree(dev);
+err_regs:
+	iounmap(regs);
+	return ret;
+}
+
+TIMER_OF_DECLARE(xilinx_xps_timer, "xlnx,xps-timer-1.00.a", xilinx_timer_init);
diff --git a/include/clocksource/timer-xilinx.h b/include/clocksource/timer-xilinx.h
new file mode 100644
index 000000000000..1f7757b84a5e
--- /dev/null
+++ b/include/clocksource/timer-xilinx.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021 Sean Anderson <sean.anderson at seco.com>
+ */
+
+#ifndef XILINX_TIMER_H
+#define XILINX_TIMER_H
+
+#include <linux/compiler.h>
+
+#define TCSR0	0x00
+#define TLR0	0x04
+#define TCR0	0x08
+#define TCSR1	0x10
+#define TLR1	0x14
+#define TCR1	0x18
+
+#define TCSR_MDT	BIT(0)
+#define TCSR_UDT	BIT(1)
+#define TCSR_GENT	BIT(2)
+#define TCSR_CAPT	BIT(3)
+#define TCSR_ARHT	BIT(4)
+#define TCSR_LOAD	BIT(5)
+#define TCSR_ENIT	BIT(6)
+#define TCSR_ENT	BIT(7)
+#define TCSR_TINT	BIT(8)
+#define TCSR_PWMA	BIT(9)
+#define TCSR_ENALL	BIT(10)
+#define TCSR_CASC	BIT(11)
+
+struct clk;
+struct device_node;
+struct regmap;
+
+/**
+ * struct xilinx_timer_priv - Private data for Xilinx AXI timer drivers
+ * @map: Regmap of the device, possibly with an offset
+ * @clk: Parent clock
+ * @max: Maximum value of the counters
+ */
+struct xilinx_timer_priv {
+	struct regmap *map;
+	struct clk *clk;
+	u32 max;
+};
+
+/**
+ * xilinx_timer_tlr_cycles() - Calculate the TLR for a period specified
+ *                             in clock cycles
+ * @priv: The timer's private data
+ * @tcsr: The value of the TCSR register for this counter
+ * @cycles: The number of cycles in this period
+ *
+ * Callers of this function MUST ensure that @cycles is representable as
+ * a TLR.
+ *
+ * Return: The calculated value for TLR
+ */
+u32 xilinx_timer_tlr_cycles(struct xilinx_timer_priv *priv, u32 tcsr,
+			    u64 cycles);
+
+/**
+ * xilinx_timer_get_period() - Get the current period of a counter
+ * @priv: The timer's private data
+ * @tlr: The value of TLR for this counter
+ * @tcsr: The value of TCSR for this counter
+ *
+ * Return: The period, in ns
+ */
+unsigned int xilinx_timer_get_period(struct xilinx_timer_priv *priv,
+				     u32 tlr, u32 tcsr);
+
+/**
+ * xilinx_timer_common_init() - Perform common initialization for Xilinx
+ *                              AXI timer drivers.
+ * @priv: The timer's private data
+ * @np: The devicetree node for the timer
+ * @one_timer: Set to %1 if there is only one timer
+ *
+ * This performs common initialization, such as detecting endianness,
+ * and parsing devicetree properties. @priv->regs must be initialized
+ * before calling this function. This function initializes @priv->read,
+ * @priv->write, and @priv->width.
+ *
+ * Return: 0, or negative errno
+ */
+int xilinx_timer_common_init(struct device_node *np,
+			     struct xilinx_timer_priv *priv,
+			     u32 *one_timer);
+
+#endif /* XILINX_TIMER_H */
-- 
2.25.1



From sean.anderson at seco.com  Thu Aug 26 14:18:30 2021
From: sean.anderson at seco.com (Sean Anderson)
Date: Thu, 26 Aug 2021 17:18:30 -0400
Subject: [PATCH v6 3/3] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <20210826211830.3311140-1-sean.anderson@seco.com>
References: <20210826211830.3311140-1-sean.anderson@seco.com>
Message-ID: <20210826211830.3311140-3-sean.anderson@seco.com>

This adds PWM support for Xilinx LogiCORE IP AXI soft timers commonly
found on Xilinx FPGAs. At the moment clock control is very basic: we
just enable the clock during probe and pin the frequency. In the future,
someone could add support for disabling the clock when not in use.

This driver was written with reference to Xilinx DS764 for v1.03.a [1].

[1] https://www.xilinx.com/support/documentation/ip_documentation/axi_timer/v1_03_a/axi_timer_ds764.pdf

Signed-off-by: Sean Anderson <sean.anderson at seco.com>
---

Changes in v6:
- Prevent overflow when calculating period_cycles
- Swap order of period_cycle range comparisons
- Remove enabled variable from xilinx_pwm_apply
- Capitalize error messages
- Don't disable regmap locking to allow inspection of registers via
  debugfs

Changes in v5:
- Elaborate on limitation section
- Rework duty-cycle and period calculations with feedback from Uwe
- Use more verbose error messages
- Allow non-zero #pwm-cells
- Remove xlnx,axi-timer-2.0 compatible string
- Correctly set duty_cycle in get_state when TLR0=TLR1
- Perform some additional checks/rounding in apply_state
- Switch to regmap to abstract endianness issues

Changes in v4:
- Remove references to properties which are not good enough for Linux.
- Don't use volatile in read/write replacements. Some arches have it and
  some don't.
- Put common timer properties into their own struct to better reuse
  code.

Changes in v3:
- Add clockevent and clocksource support
- Rewrite probe to only use a device_node, since timers may need to be
  initialized before we have proper devices. This does bloat the code a bit
  since we can no longer rely on helpers such as dev_err_probe. We also
  cannot rely on device resources being free'd on failure, so we must free
  them manually.
- We now access registers through xilinx_timer_(read|write). This allows us
  to deal with endianness issues, as originally seen in the microblaze
  driver. CAVEAT EMPTOR: I have not tested this on big-endian!
- Remove old microblaze driver

Changes in v2:
- Don't compile this module by default for arm64
- Add dependencies on COMMON_CLK and HAS_IOMEM
- Add comment explaining why we depend on !MICROBLAZE
- Add comment describing device
- Rename TCSR_(SET|CLEAR) to TCSR_RUN_(SET|CLEAR)
- Use NSEC_TO_SEC instead of defining our own
- Use TCSR_RUN_MASK to check if the PWM is enabled, as suggested by Uwe
- Cast dividends to u64 to avoid overflow
- Check for over- and underflow when calculating TLR
- Set xilinx_pwm_ops.owner
- Don't set pwmchip.base to -1
- Check range of xlnx,count-width
- Ensure the clock is always running when the pwm is registered
- Remove debugfs file :l
- Report errors with dev_error_probe

 MAINTAINERS                  |   1 +
 drivers/clocksource/Makefile |   5 +-
 drivers/pwm/Kconfig          |  13 ++
 drivers/pwm/Makefile         |   1 +
 drivers/pwm/pwm-xilinx.c     | 267 +++++++++++++++++++++++++++++++++++
 5 files changed, 286 insertions(+), 1 deletion(-)
 create mode 100644 drivers/pwm/pwm-xilinx.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 252d71addd18..6adafd3e7a09 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20050,6 +20050,7 @@ XILINX TIMER/PWM DRIVER
 M:	Sean Anderson <sean.anderson at seco.com>
 S:	Maintained
 F:	drivers/clocksource/timer-xilinx*
+F:	drivers/pwm/pwm-xilinx.c
 F:	include/clocksource/timer-xilinx.h
 
 XILINX UARTLITE SERIAL DRIVER
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index a7cba6ef5782..36aa2e5ac1d5 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -88,4 +88,7 @@ obj-$(CONFIG_CSKY_MP_TIMER)		+= timer-mp-csky.o
 obj-$(CONFIG_GX6605S_TIMER)		+= timer-gx6605s.o
 obj-$(CONFIG_HYPERV_TIMER)		+= hyperv_timer.o
 obj-$(CONFIG_MICROCHIP_PIT64B)		+= timer-microchip-pit64b.o
-obj-$(CONFIG_XILINX_TIMER)		+= timer-xilinx.o timer-xilinx-common.o
+obj-$(CONFIG_XILINX_TIMER)		+= timer-xilinx.o
+ifneq ($(CONFIG_XILINX_TIMER)$(CONFIG_PWM_XILINX),)
+obj-y					+= timer-xilinx-common.o
+endif
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index c76adedd58c9..974774b7c987 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -637,4 +637,17 @@ config PWM_VT8500
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-vt8500.
 
+config PWM_XILINX
+	tristate "Xilinx AXI Timer PWM support"
+	depends on COMMON_CLK
+	select REGMAP_MMIO
+	help
+	  PWM driver for Xilinx LogiCORE IP AXI timers. This timer is
+	  typically a soft core which may be present in Xilinx FPGAs.
+	  This device may also be present in Microblaze soft processors.
+	  If you don't have this IP in your design, choose N.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-xilinx.
+
 endif
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 708840b7fba8..ea785480359b 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -60,3 +60,4 @@ obj-$(CONFIG_PWM_TWL)		+= pwm-twl.o
 obj-$(CONFIG_PWM_TWL_LED)	+= pwm-twl-led.o
 obj-$(CONFIG_PWM_VISCONTI)	+= pwm-visconti.o
 obj-$(CONFIG_PWM_VT8500)	+= pwm-vt8500.o
+obj-$(CONFIG_PWM_XILINX)	+= pwm-xilinx.o
diff --git a/drivers/pwm/pwm-xilinx.c b/drivers/pwm/pwm-xilinx.c
new file mode 100644
index 000000000000..d1857f638cd7
--- /dev/null
+++ b/drivers/pwm/pwm-xilinx.c
@@ -0,0 +1,267 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Sean Anderson <sean.anderson at seco.com>
+ *
+ * Limitations:
+ * - When changing both duty cycle and period, we may end up with one cycle
+ *   with the old duty cycle and the new period. This is because the counters
+ *   may only be reloaded by first stopping them, or by letting them be
+ *   automatically reloaded at the end of a cycle. If this automatic reload
+ *   happens after we set TLR0 but before we set TLR1 then we will will have a
+ *   bad cycle. This could probably be fixed by reading TCR0 just before
+ *   reprogramming, but I think it would add complexity for little gain.
+ * - Cannot produce 100% duty cycle by configuring the TLRs. This might be
+ *   possible by stopping the counters at an appropriate point in the cycle,
+ *   but this is not (yet) implemented.
+ * - Only produces "normal" output.
+ * - Always produces low output if disabled.
+ */
+
+#include <clocksource/timer-xilinx.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+
+/*
+ * The idea here is to capture whether the PWM is actually running (e.g.
+ * because we or the bootloader set it up) and we need to be careful to ensure
+ * we don't cause a glitch. According to the data sheet, to enable the PWM we
+ * need to
+ *
+ * - Set both timers to generate mode (MDT=1)
+ * - Set both timers to PWM mode (PWMA=1)
+ * - Enable the generate out signals (GENT=1)
+ *
+ * In addition,
+ *
+ * - The timer must be running (ENT=1)
+ * - The timer must auto-reload TLR into TCR (ARHT=1)
+ * - We must not be in the process of loading TLR into TCR (LOAD=0)
+ * - Cascade mode must be disabled (CASC=0)
+ *
+ * If any of these differ from usual, then the PWM is either disabled, or is
+ * running in a mode that this driver does not support.
+ */
+#define TCSR_PWM_SET (TCSR_GENT | TCSR_ARHT | TCSR_ENT | TCSR_PWMA)
+#define TCSR_PWM_CLEAR (TCSR_MDT | TCSR_LOAD)
+#define TCSR_PWM_MASK (TCSR_PWM_SET | TCSR_PWM_CLEAR)
+
+struct xilinx_pwm_device {
+	struct pwm_chip chip;
+	struct xilinx_timer_priv priv;
+};
+
+static inline struct xilinx_timer_priv
+*xilinx_pwm_chip_to_priv(struct pwm_chip *chip)
+{
+	return &container_of(chip, struct xilinx_pwm_device, chip)->priv;
+}
+
+static bool xilinx_timer_pwm_enabled(u32 tcsr0, u32 tcsr1)
+{
+	return ((TCSR_PWM_MASK | TCSR_CASC) & tcsr0) == TCSR_PWM_SET &&
+		(TCSR_PWM_MASK & tcsr1) == TCSR_PWM_SET;
+}
+
+static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
+			    const struct pwm_state *state)
+{
+	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
+	u32 tlr0, tlr1, tcsr0, tcsr1;
+	u64 period_cycles, duty_cycles;
+	unsigned long rate;
+
+	if (state->polarity != PWM_POLARITY_NORMAL)
+		return -EINVAL;
+
+	/*
+	 * To be representable by TLR, cycles must be between 2 and
+	 * priv->max + 2. To enforce this we can reduce the duty
+	 * cycle, but we may not increase it.
+	 */
+	rate = clk_get_rate(priv->clk);
+	/* Prevent overflow by clamping to the worst case of rate */
+	period_cycles = min_t(u64, state->period, ULONG_MAX * NSEC_PER_SEC);
+	period_cycles = mul_u64_u32_div(state->period, rate, NSEC_PER_SEC);
+	if (period_cycles < 2 || period_cycles - 2 > priv->max)
+		return -ERANGE;
+	duty_cycles = mul_u64_u32_div(state->duty_cycle, rate, NSEC_PER_SEC);
+
+	/*
+	 * If we specify 100% duty cycle, we will get 0% instead, so decrease
+	 * the duty cycle count by one.
+	 */
+	if (period_cycles == duty_cycles)
+		duty_cycles--;
+
+	/* Round down to 0% duty cycle for unrepresentable duty cycles */
+	if (duty_cycles < 2)
+		duty_cycles = period_cycles;
+
+	regmap_read(priv->map, TCSR0, &tcsr0);
+	regmap_read(priv->map, TCSR1, &tcsr1);
+	tlr0 = xilinx_timer_tlr_cycles(priv, tcsr0, period_cycles);
+	tlr1 = xilinx_timer_tlr_cycles(priv, tcsr1, duty_cycles);
+	regmap_write(priv->map, TLR0, tlr0);
+	regmap_write(priv->map, TLR1, tlr1);
+
+	if (state->enabled) {
+		/*
+		 * If the PWM is already running, then the counters will be
+		 * reloaded at the end of the current cycle.
+		 */
+		if (!xilinx_timer_pwm_enabled(tcsr0, tcsr1)) {
+			/* Load TLR into TCR */
+			regmap_write(priv->map, TCSR0, tcsr0 | TCSR_LOAD);
+			regmap_write(priv->map, TCSR1, tcsr1 | TCSR_LOAD);
+			/* Enable timers all at once with ENALL */
+			tcsr0 = (TCSR_PWM_SET & ~TCSR_ENT) | (tcsr0 & TCSR_UDT);
+			tcsr1 = TCSR_PWM_SET | TCSR_ENALL | (tcsr1 & TCSR_UDT);
+			regmap_write(priv->map, TCSR0, tcsr0);
+			regmap_write(priv->map, TCSR1, tcsr1);
+		}
+	} else {
+		regmap_write(priv->map, TCSR0, 0);
+		regmap_write(priv->map, TCSR1, 0);
+	}
+
+	return 0;
+}
+
+static void xilinx_pwm_get_state(struct pwm_chip *chip,
+				 struct pwm_device *unused,
+				 struct pwm_state *state)
+{
+	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
+	u32 tlr0, tlr1, tcsr0, tcsr1;
+
+	regmap_read(priv->map, TLR0, &tlr0);
+	regmap_read(priv->map, TLR1, &tlr1);
+	regmap_read(priv->map, TCSR0, &tcsr0);
+	regmap_read(priv->map, TCSR1, &tcsr1);
+	state->period = xilinx_timer_get_period(priv, tlr0, tcsr0);
+	state->duty_cycle = xilinx_timer_get_period(priv, tlr1, tcsr1);
+	state->enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1);
+	state->polarity = PWM_POLARITY_NORMAL;
+
+	/* 100% duty cycle results in constant low output */
+	if (state->period == state->duty_cycle)
+		state->duty_cycle = 0;
+}
+
+static const struct pwm_ops xilinx_pwm_ops = {
+	.apply = xilinx_pwm_apply,
+	.get_state = xilinx_pwm_get_state,
+	.owner = THIS_MODULE,
+};
+
+static const struct regmap_config xilinx_pwm_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.val_format_endian = REGMAP_ENDIAN_LITTLE,
+	.max_register = TCR1,
+};
+
+static int xilinx_timer_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct xilinx_timer_priv *priv;
+	struct xilinx_pwm_device *pwm;
+	u32 pwm_cells, one_timer;
+	void __iomem *regs;
+
+	ret = of_property_read_u32(np, "#pwm-cells", &pwm_cells);
+	if (ret == -EINVAL)
+		return -ENODEV;
+	else if (ret)
+		return dev_err_probe(dev, ret, "could not read #pwm-cells\n");
+
+	pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
+	if (!pwm)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, pwm);
+	priv = &pwm->priv;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	priv->map = devm_regmap_init_mmio(dev, regs,
+					  &xilinx_pwm_regmap_config);
+	if (IS_ERR(priv->map))
+		return dev_err_probe(dev, PTR_ERR(priv->map),
+				     "Could not create regmap\n");
+
+	ret = xilinx_timer_common_init(np, priv, &one_timer);
+	if (ret)
+		return ret;
+
+	if (one_timer)
+		return dev_err_probe(dev, -EINVAL,
+				     "Two timers required for PWM mode\n");
+
+	/*
+	 * The polarity of the generate outputs must be active high for PWM
+	 * mode to work. We could determine this from the device tree, but
+	 * alas, such properties are not allowed to be used.
+	 */
+
+	priv->clk = devm_clk_get(dev, "s_axi_aclk");
+	if (IS_ERR(priv->clk))
+		return dev_err_probe(dev, PTR_ERR(priv->clk),
+				     "Could not get clock\n");
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret)
+		return dev_err_probe(dev, ret, "Clock enable failed\n");
+	clk_rate_exclusive_get(priv->clk);
+
+	pwm->chip.dev = dev;
+	pwm->chip.ops = &xilinx_pwm_ops;
+	pwm->chip.npwm = 1;
+	ret = pwmchip_add(&pwm->chip);
+	if (ret) {
+		clk_rate_exclusive_put(priv->clk);
+		clk_disable_unprepare(priv->clk);
+		return dev_err_probe(dev, ret, "Could not register PWM chip\n");
+	}
+
+	return 0;
+}
+
+static int xilinx_timer_remove(struct platform_device *pdev)
+{
+	struct xilinx_pwm_device *pwm = platform_get_drvdata(pdev);
+
+	pwmchip_remove(&pwm->chip);
+	clk_rate_exclusive_put(pwm->priv.clk);
+	clk_disable_unprepare(pwm->priv.clk);
+	return 0;
+}
+
+static const struct of_device_id xilinx_timer_of_match[] = {
+	{ .compatible = "xlnx,xps-timer-1.00.a", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, xilinx_timer_of_match);
+
+static struct platform_driver xilinx_timer_driver = {
+	.probe = xilinx_timer_probe,
+	.remove = xilinx_timer_remove,
+	.driver = {
+		.name = "xilinx-timer",
+		.of_match_table = of_match_ptr(xilinx_timer_of_match),
+	},
+};
+module_platform_driver(xilinx_timer_driver);
+
+MODULE_ALIAS("platform:xilinx-timer");
+MODULE_DESCRIPTION("Xilinx LogiCORE IP AXI Timer driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From lkp at intel.com  Thu Aug 26 14:31:50 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 05:31:50 +0800
Subject: [xlnx:master 11230/12418] drivers/remoteproc/mtk_scp.c:463:27:
 error: initialization of 'void * (*)(struct rproc *, u64,  int)' {aka 'void
 * (*)(struct rproc *, long long unsigned int,  int)'} from incompatible
 pointer type 'void * (*)(struct rproc *, u64,  size_t)' {aka 'void * (...
Message-ID: <202108270543.sbGKSuOi-lkp@intel.com>

Hi Wendy,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx master
head:   45cd0074cdf1ddd710b28848e6a860b442babfcc
commit: a324889a971b8e827c53deaffe630b420bde4067 [11230/12418] remoteproc: Add support for peek from remote and acking kick from remote
config: parisc-randconfig-r023-20210826 (attached as .config)
compiler: hppa-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/a324889a971b8e827c53deaffe630b420bde4067
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx master
        git checkout a324889a971b8e827c53deaffe630b420bde4067
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=parisc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/remoteproc/mtk_scp.c:463:27: error: initialization of 'void * (*)(struct rproc *, u64,  int)' {aka 'void * (*)(struct rproc *, long long unsigned int,  int)'} from incompatible pointer type 'void * (*)(struct rproc *, u64,  size_t)' {aka 'void * (*)(struct rproc *, long long unsigned int,  unsigned int)'} [-Werror=incompatible-pointer-types]
     463 |         .da_to_va       = scp_da_to_va,
         |                           ^~~~~~~~~~~~
   drivers/remoteproc/mtk_scp.c:463:27: note: (near initialization for 'scp_ops.da_to_va')
   cc1: some warnings being treated as errors


vim +463 drivers/remoteproc/mtk_scp.c

63c13d61eafe46 Erin Lo 2019-11-12  458  
63c13d61eafe46 Erin Lo 2019-11-12  459  static const struct rproc_ops scp_ops = {
63c13d61eafe46 Erin Lo 2019-11-12  460  	.start		= scp_start,
63c13d61eafe46 Erin Lo 2019-11-12  461  	.stop		= scp_stop,
63c13d61eafe46 Erin Lo 2019-11-12  462  	.load		= scp_load,
63c13d61eafe46 Erin Lo 2019-11-12 @463  	.da_to_va	= scp_da_to_va,
63c13d61eafe46 Erin Lo 2019-11-12  464  };
63c13d61eafe46 Erin Lo 2019-11-12  465  

:::::: The code at line 463 was first introduced by commit
:::::: 63c13d61eafe4606f1c16c54da40c4eee78e9edf remoteproc/mediatek: add SCP support for mt8183

:::::: TO: Erin Lo <erin.lo at mediatek.com>
:::::: CC: Bjorn Andersson <bjorn.andersson at linaro.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 37434 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210827/8776264b/attachment-0001.gz>

From iwona.winiarska at intel.com  Thu Aug 26 15:40:43 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Thu, 26 Aug 2021 22:40:43 +0000
Subject: [PATCH v2 06/15] peci: Add core infrastructure
In-Reply-To: <CAPcyv4giVBjZWjXO2H+vYSR29Vapi6_FvMwO7nvts-JXmCHcOA@mail.gmail.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-7-iwona.winiarska@intel.com>
 <CAPcyv4giVBjZWjXO2H+vYSR29Vapi6_FvMwO7nvts-JXmCHcOA@mail.gmail.com>
Message-ID: <4aa3fac69a92b175beb59d2678eb914c35ea98b7.camel@intel.com>

On Wed, 2021-08-25 at 15:58 -0700, Dan Williams wrote:
> On Tue, Aug 3, 2021 at 4:35 AM Iwona Winiarska
> <iwona.winiarska at intel.com> wrote:
> > 
> > Intel processors provide access for various services designed to support
> > processor and DRAM thermal management, platform manageability and
> > processor interface tuning and diagnostics.
> > Those services are available via the Platform Environment Control
> > Interface (PECI) that provides a communication channel between the
> > processor and the Baseboard Management Controller (BMC) or other
> > platform management device.
> > 
> > This change introduces PECI subsystem by adding the initial core module
> > and API for controller drivers.
> > 
> > Co-developed-by: Jason M Bills <jason.m.bills at linux.intel.com>
> > Signed-off-by: Jason M Bills <jason.m.bills at linux.intel.com>
> > Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> > ---
> > ?MAINTAINERS???????????? |?? 9 +++
> > ?drivers/Kconfig???????? |?? 3 +
> > ?drivers/Makefile??????? |?? 1 +
> > ?drivers/peci/Kconfig??? |? 15 ++++
> > ?drivers/peci/Makefile?? |?? 5 ++
> > ?drivers/peci/core.c???? | 155 ++++++++++++++++++++++++++++++++++++++++
> > ?drivers/peci/internal.h |? 16 +++++
> > ?include/linux/peci.h??? |? 99 +++++++++++++++++++++++++
> > ?8 files changed, 303 insertions(+)
> > ?create mode 100644 drivers/peci/Kconfig
> > ?create mode 100644 drivers/peci/Makefile
> > ?create mode 100644 drivers/peci/core.c
> > ?create mode 100644 drivers/peci/internal.h
> > ?create mode 100644 include/linux/peci.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 7cdab7229651..d411974aaa5e 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -14503,6 +14503,15 @@ L:???? platform-driver-x86 at vger.kernel.org
> > ?S:???? Maintained
> > ?F:???? drivers/platform/x86/peaq-wmi.c
> > 
> > +PECI SUBSYSTEM
> > +M:???? Iwona Winiarska <iwona.winiarska at intel.com>
> > +R:???? Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > +L:???? openbmc at lists.ozlabs.org?(moderated for non-subscribers)
> > +S:???? Supported
> > +F:???? Documentation/devicetree/bindings/peci/
> > +F:???? drivers/peci/
> > +F:???? include/linux/peci.h
> > +
> > ?PENSANDO ETHERNET DRIVERS
> > ?M:???? Shannon Nelson <snelson at pensando.io>
> > ?M:???? drivers at pensando.io
> > diff --git a/drivers/Kconfig b/drivers/Kconfig
> > index 8bad63417a50..f472b3d972b3 100644
> > --- a/drivers/Kconfig
> > +++ b/drivers/Kconfig
> > @@ -236,4 +236,7 @@ source "drivers/interconnect/Kconfig"
> > ?source "drivers/counter/Kconfig"
> > 
> > ?source "drivers/most/Kconfig"
> > +
> > +source "drivers/peci/Kconfig"
> > +
> > ?endmenu
> > diff --git a/drivers/Makefile b/drivers/Makefile
> > index 27c018bdf4de..8d96f0c3dde5 100644
> > --- a/drivers/Makefile
> > +++ b/drivers/Makefile
> > @@ -189,3 +189,4 @@ obj-$(CONFIG_GNSS)????????? += gnss/
> > ?obj-$(CONFIG_INTERCONNECT)???? += interconnect/
> > ?obj-$(CONFIG_COUNTER)????????? += counter/
> > ?obj-$(CONFIG_MOST)???????????? += most/
> > +obj-$(CONFIG_PECI)???????????? += peci/
> > diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
> > new file mode 100644
> > index 000000000000..71a4ad81225a
> > --- /dev/null
> > +++ b/drivers/peci/Kconfig
> > @@ -0,0 +1,15 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +
> > +menuconfig PECI
> > +?????? tristate "PECI support"
> > +?????? help
> > +???????? The Platform Environment Control Interface (PECI) is an interface
> > +???????? that provides a communication channel to Intel processors and
> > +???????? chipset components from external monitoring or control devices.
> > +
> > +???????? If you are building a Baseboard Management Controller (BMC) kernel
> > +???????? for Intel platform say Y here and also to the specific driver for
> > +???????? your adapter(s) below. If unsure say N.
> > +
> > +???????? This support is also available as a module. If so, the module
> > +???????? will be called peci.
> > diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
> > new file mode 100644
> > index 000000000000..e789a354e842
> > --- /dev/null
> > +++ b/drivers/peci/Makefile
> > @@ -0,0 +1,5 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +
> > +# Core functionality
> > +peci-y := core.o
> > +obj-$(CONFIG_PECI) += peci.o
> > diff --git a/drivers/peci/core.c b/drivers/peci/core.c
> > new file mode 100644
> > index 000000000000..7b3938af0396
> > --- /dev/null
> > +++ b/drivers/peci/core.c
> > @@ -0,0 +1,155 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +// Copyright (c) 2018-2021 Intel Corporation
> > +
> > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> 
> This looks like overkill for only one print statement in this module,
> especially when the dev_ print helpers offer more detail.

Ok, I'll remove it.

> 
> > +
> > +#include <linux/bug.h>
> > +#include <linux/device.h>
> > +#include <linux/export.h>
> > +#include <linux/idr.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/peci.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/property.h>
> > +#include <linux/slab.h>
> > +
> > +#include "internal.h"
> > +
> > +static DEFINE_IDA(peci_controller_ida);
> > +
> > +static void peci_controller_dev_release(struct device *dev)
> > +{
> > +?????? struct peci_controller *controller = to_peci_controller(dev);
> > +
> > +?????? pm_runtime_disable(&controller->dev);
> 
> This seems late to be disabling power management, the device is about
> to be freed. Keep in mind the lifetime of the this object can be
> artificially prolonged. I expect this to be done when the device is
> unregistered from the bus.

Makes sense.

> 
> > +
> > +?????? mutex_destroy(&controller->bus_lock);
> > +?????? ida_free(&peci_controller_ida, controller->id);
> > +?????? fwnode_handle_put(controller->dev.fwnode);
> 
> Shouldn't the get / put of this handle reference be bound to specific
> accesses not held for the entire lifetime of the object? At a minimum
> it seems to be a reference that can taken at registration and dropped
> at unregistration.

I'll move it to take ref at registration and to drop it at unregistration.

> 
> > +?????? kfree(controller);
> > +}
> > +
> > +struct device_type peci_controller_type = {
> > +?????? .release??????? = peci_controller_dev_release,
> > +};
> > +
> > +static struct peci_controller *peci_controller_alloc(struct device *dev,
> > +??????????????????????????????????????????????????? struct
> > peci_controller_ops *ops)
> > +{
> > +?????? struct fwnode_handle *node = fwnode_handle_get(dev_fwnode(dev));
> > +?????? struct peci_controller *controller;
> > +?????? int ret;
> > +
> > +?????? if (!ops->xfer)
> > +?????????????? return ERR_PTR(-EINVAL);
> > +
> > +?????? controller = kzalloc(sizeof(*controller), GFP_KERNEL);
> > +?????? if (!controller)
> > +?????????????? return ERR_PTR(-ENOMEM);
> > +
> > +?????? ret = ida_alloc_max(&peci_controller_ida, U8_MAX, GFP_KERNEL);
> > +?????? if (ret < 0)
> > +?????????????? goto err;
> > +?????? controller->id = ret;
> > +
> > +?????? controller->ops = ops;
> > +
> > +?????? controller->dev.parent = dev;
> > +?????? controller->dev.bus = &peci_bus_type;
> > +?????? controller->dev.type = &peci_controller_type;
> > +?????? controller->dev.fwnode = node;
> > +?????? controller->dev.of_node = to_of_node(node);
> > +
> > +?????? device_initialize(&controller->dev);
> > +
> > +?????? mutex_init(&controller->bus_lock);
> > +
> > +?????? pm_runtime_no_callbacks(&controller->dev);
> > +?????? pm_suspend_ignore_children(&controller->dev, true);
> > +?????? pm_runtime_enable(&controller->dev);
> 
> Per above, are you sure unregistered devices need pm_runtime enabled?
> 
> Rest looks ok to me.

Thanks
-Iwona


From lkp at intel.com  Thu Aug 26 16:08:54 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 07:08:54 +0800
Subject: [xlnx:master 11894/12418] drivers/spi/spi-cadence-quadspi.c:1317:26:
 warning: implicit conversion from 'enum dma_transfer_direction' to
 'enum dma_data_direction'
Message-ID: <202108270747.747hGRef-lkp@intel.com>

Hi Sai,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx master
head:   45cd0074cdf1ddd710b28848e6a860b442babfcc
commit: 4acfecc9eff4ac3ca4f0e9583ff253c95cd8172d [11894/12418] spi: spi-cadence-quadspi: Added support for DMA read
config: parisc-randconfig-r023-20210826 (attached as .config)
compiler: hppa-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/4acfecc9eff4ac3ca4f0e9583ff253c95cd8172d
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx master
        git checkout 4acfecc9eff4ac3ca4f0e9583ff253c95cd8172d
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=parisc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/spi/spi-cadence-quadspi.c:12:
   drivers/spi/spi-cadence-quadspi.c: In function 'cqspi_versal_indirect_read_dma':
>> drivers/spi/spi-cadence-quadspi.c:1317:26: warning: implicit conversion from 'enum dma_transfer_direction' to 'enum dma_data_direction' [-Wenum-conversion]
    1317 |                          DMA_DEV_TO_MEM);
         |                          ^~~~~~~~~~~~~~
   include/linux/dma-mapping.h:384:70: note: in definition of macro 'dma_unmap_single'
     384 | #define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
         |                                                                      ^


vim +1317 drivers/spi/spi-cadence-quadspi.c

  1241	
  1242	static int cqspi_versal_indirect_read_dma(struct cqspi_flash_pdata *f_pdata,
  1243						  u_char *rxbuf, loff_t from_addr,
  1244						  size_t n_rx)
  1245	{
  1246		struct cqspi_st *cqspi = f_pdata->cqspi;
  1247		struct device *dev = &cqspi->pdev->dev;
  1248		void __iomem *reg_base = cqspi->iobase;
  1249		unsigned int rx_rem;
  1250		int ret = 0;
  1251		u32 reg;
  1252	
  1253		rx_rem = n_rx % 4;
  1254		cqspi->bytes_to_rx = n_rx;
  1255		cqspi->bytes_to_dma = (n_rx - rx_rem);
  1256		cqspi->addr = from_addr;
  1257		cqspi->rxbuf = rxbuf;
  1258	
  1259		reg = readl(cqspi->iobase + CQSPI_REG_CONFIG);
  1260		reg |= CQSPI_REG_CONFIG_DMA_MASK;
  1261		writel(reg, cqspi->iobase + CQSPI_REG_CONFIG);
  1262	
  1263		writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
  1264		writel(cqspi->bytes_to_dma, reg_base + CQSPI_REG_INDIRECTRDBYTES);
  1265		writel(CQSPI_REG_INDTRIG_ADDRRANGE_WIDTH,
  1266		       reg_base + CQSPI_REG_INDTRIG_ADDRRANGE);
  1267	
  1268		/* Clear all interrupts. */
  1269		writel(CQSPI_IRQ_STATUS_MASK, reg_base + CQSPI_REG_IRQSTATUS);
  1270	
  1271		/* Enable DMA done interrupt */
  1272		writel(CQSPI_REG_DMA_DST_I_EN_DONE,
  1273		       reg_base + CQSPI_REG_DMA_DST_I_EN);
  1274	
  1275		/* Default DMA periph configuration */
  1276		writel(CQSPI_REG_DMA_VAL, reg_base + CQSPI_REG_DMA);
  1277	
  1278		cqspi->dma_addr = dma_map_single(dev, rxbuf, cqspi->bytes_to_dma,
  1279						 DMA_FROM_DEVICE);
  1280		if (dma_mapping_error(dev, cqspi->dma_addr)) {
  1281			dev_err(dev, "ERR:rxdma:memory not mapped\n");
  1282			goto failrd;
  1283		}
  1284		/* Configure DMA Dst address */
  1285		writel(lower_32_bits(cqspi->dma_addr),
  1286		       reg_base + CQSPI_REG_DMA_DST_ADDR);
  1287		writel(upper_32_bits(cqspi->dma_addr),
  1288		       reg_base + CQSPI_REG_DMA_DST_ADDR_MSB);
  1289	
  1290		/* Configure DMA Src read address */
  1291		writel(cqspi->trigger_address, reg_base + CQSPI_REG_DMA_SRC_ADDR);
  1292	
  1293		/* Set DMA destination size */
  1294		writel(cqspi->bytes_to_dma, reg_base + CQSPI_REG_DMA_DST_SIZE);
  1295	
  1296		/* Set DMA destination control */
  1297		writel(CQSPI_REG_DMA_DST_CTRL_VAL, reg_base + CQSPI_REG_DMA_DST_CTRL);
  1298	
  1299		writel(CQSPI_REG_INDIRECTRD_START_MASK,
  1300		       reg_base + CQSPI_REG_INDIRECTRD);
  1301	
  1302		reinit_completion(&cqspi->transfer_complete);
  1303	
  1304		if (!wait_for_completion_timeout(&cqspi->transfer_complete,
  1305				msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) {
  1306			ret = -ETIMEDOUT;
  1307			goto failrd;
  1308		}
  1309	
  1310		return 0;
  1311	
  1312	failrd:
  1313		/* Disable DMA interrupt */
  1314		writel(0x0, reg_base + CQSPI_REG_DMA_DST_I_DIS);
  1315	
  1316		dma_unmap_single(dev, cqspi->dma_addr, cqspi->bytes_to_dma,
> 1317				 DMA_DEV_TO_MEM);
  1318	
  1319		/* Cancel the indirect read */
  1320		writel(CQSPI_REG_INDIRECTWR_CANCEL_MASK,
  1321		       reg_base + CQSPI_REG_INDIRECTRD);
  1322	
  1323		return ret;
  1324	}
  1325	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 37507 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210827/a580e2f4/attachment-0001.gz>

From madvenka at linux.microsoft.com  Thu Aug 26 16:19:07 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Thu, 26 Aug 2021 18:19:07 -0500
Subject: [RFC PATCH v8 2/4] arm64: Reorganize the unwinder code for better
 consistency and maintenance
In-Reply-To: <YSe3WogpFIu97i/7@sirena.org.uk>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-3-madvenka@linux.microsoft.com>
 <YSe3WogpFIu97i/7@sirena.org.uk>
Message-ID: <ecf0e4d1-7c47-426e-1350-fe5dc8bd88a5@linux.microsoft.com>



On 8/26/21 10:46 AM, Mark Brown wrote:
> On Thu, Aug 12, 2021 at 02:06:01PM -0500, madvenka at linux.microsoft.com wrote:
> 
>> Renaming of unwinder functions
>> ==============================
> 
>> Rename unwinder functions to unwind_*() similar to other architectures
>> for naming consistency. More on this below.
> 
> This feels like it could probably do with splitting up a bit for
> reviewability, several of these headers you've got in the commit
> logs look like they could be separate commits.  Splitting things
> up does help with reviewability, having only one change to keep
> in mind at once is a lot less cognative load.
> 
>> Replace walk_stackframe() with unwind()
>> =======================================
>>
>> walk_stackframe() contains the unwinder loop that walks the stack
>> frames. Currently, start_backtrace() and walk_stackframe() are called
>> separately. They should be combined in the same function. Also, the
>> loop in walk_stackframe() should be simplified and should look like
>> the unwind loops in other architectures such as X86 and S390.
> 
> This definitely seems like a separate change.
> 

OK. I will take a look at splitting the patch.

I am also requesting a review of the sym_code special section approach.
I know that you have already approved it. I wanted one more vote. Then,
I can remove the "RFC" word from the title and then it will be just a
code review of the patch series.

Mark Rutland,

Do you also approve the idea of placing unreliable functions (from an unwind
perspective) in a special section and using that in the unwinder for
reliable stack trace?

Thanks.

Madhavan


From lkp at intel.com  Thu Aug 26 16:29:41 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 07:29:41 +0800
Subject: [soc:arm/drivers] BUILD SUCCESS
 06779631d18ff2901af604eadea0d7b2193db7a1
Message-ID: <612823e5.eiqCkkPMS3zLPAmP%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/drivers
branch HEAD: 06779631d18ff2901af604eadea0d7b2193db7a1  Merge tag 'reset-for-v5.15' of git://git.pengutronix.de/pza/linux into arm/drivers

elapsed time: 741m

configs tested: 185
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210826
arm                          gemini_defconfig
mips                      fuloong2e_defconfig
powerpc                       holly_defconfig
m68k                            mac_defconfig
powerpc                 mpc836x_mds_defconfig
sh                           se7722_defconfig
powerpc                     powernv_defconfig
powerpc                        warp_defconfig
mips                      loongson3_defconfig
powerpc                 mpc834x_itx_defconfig
sh                         microdev_defconfig
arm                       netwinder_defconfig
arm                         mv78xx0_defconfig
ia64                      gensparse_defconfig
powerpc                         ps3_defconfig
sh                               alldefconfig
arm                            lart_defconfig
sh                         apsh4a3a_defconfig
arm                           viper_defconfig
powerpc                    amigaone_defconfig
m68k                       m5249evb_defconfig
arm                            mmp2_defconfig
powerpc                       eiger_defconfig
powerpc                 canyonlands_defconfig
mips                     loongson1b_defconfig
arc                 nsimosci_hs_smp_defconfig
arm                        keystone_defconfig
xtensa                           alldefconfig
arm                        oxnas_v6_defconfig
nds32                            alldefconfig
powerpc                    ge_imp3a_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc837x_mds_defconfig
arm                      integrator_defconfig
m68k                            q40_defconfig
x86_64                           allyesconfig
sh                             sh03_defconfig
arm                           spitz_defconfig
arm                       multi_v4t_defconfig
arm                            zeus_defconfig
h8300                     edosk2674_defconfig
powerpc                     pq2fads_defconfig
arm                         bcm2835_defconfig
mips                        jmr3927_defconfig
mips                       bmips_be_defconfig
sh                                  defconfig
openrisc                            defconfig
powerpc                     asp8347_defconfig
sparc                       sparc64_defconfig
sh                            shmin_defconfig
s390                          debug_defconfig
powerpc                 mpc8272_ads_defconfig
arc                            hsdk_defconfig
arm                           h5000_defconfig
arm                            mps2_defconfig
xtensa                generic_kc705_defconfig
arm                         lpc18xx_defconfig
powerpc                          g5_defconfig
xtensa                          iss_defconfig
sh                   secureedge5410_defconfig
sh                     magicpanelr2_defconfig
h8300                       h8s-sim_defconfig
sh                          urquell_defconfig
riscv                    nommu_k210_defconfig
sh                          landisk_defconfig
arm                           corgi_defconfig
sh                ecovec24-romimage_defconfig
mips                            e55_defconfig
sh                          sdk7780_defconfig
mips                          malta_defconfig
arm                          ep93xx_defconfig
powerpc                        icon_defconfig
xtensa                    xip_kc705_defconfig
mips                        qi_lb60_defconfig
powerpc                         wii_defconfig
mips                           ci20_defconfig
mips                   sb1250_swarm_defconfig
mips                         tb0287_defconfig
sh                      rts7751r2d1_defconfig
nios2                         3c120_defconfig
sh                            hp6xx_defconfig
mips                      maltasmvp_defconfig
arm                         shannon_defconfig
arm                             pxa_defconfig
powerpc                   lite5200b_defconfig
powerpc                      pmac32_defconfig
mips                        vocore2_defconfig
powerpc                     pseries_defconfig
arm                           omap1_defconfig
powerpc                  storcenter_defconfig
arm                       spear13xx_defconfig
ia64                             alldefconfig
powerpc                 mpc832x_rdb_defconfig
arm                           h3600_defconfig
mips                         tb0226_defconfig
m68k                           sun3_defconfig
arm                          ixp4xx_defconfig
arm                    vt8500_v6_v7_defconfig
arm                          pcm027_defconfig
microblaze                      mmu_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210826
x86_64               randconfig-a006-20210826
x86_64               randconfig-a001-20210826
x86_64               randconfig-a003-20210826
x86_64               randconfig-a004-20210826
x86_64               randconfig-a002-20210826
i386                 randconfig-a006-20210826
i386                 randconfig-a001-20210826
i386                 randconfig-a002-20210826
i386                 randconfig-a005-20210826
i386                 randconfig-a003-20210826
i386                 randconfig-a004-20210826
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210826
s390                 randconfig-c005-20210826
arm                  randconfig-c002-20210826
riscv                randconfig-c006-20210826
powerpc              randconfig-c003-20210826
x86_64               randconfig-c007-20210826
mips                 randconfig-c004-20210826
x86_64               randconfig-a014-20210826
x86_64               randconfig-a015-20210826
x86_64               randconfig-a016-20210826
x86_64               randconfig-a013-20210826
x86_64               randconfig-a012-20210826
x86_64               randconfig-a011-20210826
i386                 randconfig-a011-20210826
i386                 randconfig-a016-20210826
i386                 randconfig-a012-20210826
i386                 randconfig-a014-20210826
i386                 randconfig-a013-20210826
i386                 randconfig-a015-20210826
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Thu Aug 26 16:30:33 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 07:30:33 +0800
Subject: [soc:drivers/reset] BUILD SUCCESS
 09f3824342f665d222fb7ac17c91f8334779630b
Message-ID: <61282419.DI9QANdciTXxUELP%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git drivers/reset
branch HEAD: 09f3824342f665d222fb7ac17c91f8334779630b  reset: simple: remove ZTE details in Kconfig help

elapsed time: 5014m

configs tested: 336
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210824
i386                 randconfig-c001-20210826
arm                          gemini_defconfig
mips                      fuloong2e_defconfig
powerpc                       holly_defconfig
m68k                            mac_defconfig
powerpc                 mpc836x_mds_defconfig
sh                           se7722_defconfig
powerpc                     powernv_defconfig
powerpc                        warp_defconfig
mips                      loongson3_defconfig
powerpc                 mpc834x_itx_defconfig
sh                         microdev_defconfig
arm                       netwinder_defconfig
arm                         mv78xx0_defconfig
ia64                      gensparse_defconfig
arm                        clps711x_defconfig
sh                   sh7724_generic_defconfig
arm                       cns3420vb_defconfig
ia64                        generic_defconfig
m68k                        m5272c3_defconfig
powerpc                    amigaone_defconfig
m68k                       m5249evb_defconfig
arm                            mmp2_defconfig
powerpc                       eiger_defconfig
powerpc                 canyonlands_defconfig
xtensa                         virt_defconfig
mips                      bmips_stb_defconfig
sh                   secureedge5410_defconfig
sparc                       sparc32_defconfig
mips                      maltasmvp_defconfig
arm                        spear6xx_defconfig
mips                malta_qemu_32r6_defconfig
xtensa                       common_defconfig
mips                             allyesconfig
sh                          sdk7786_defconfig
um                             i386_defconfig
mips                     loongson1b_defconfig
arc                 nsimosci_hs_smp_defconfig
arm                        keystone_defconfig
xtensa                           alldefconfig
arm                        oxnas_v6_defconfig
nds32                            alldefconfig
powerpc                    ge_imp3a_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc837x_mds_defconfig
arm                      integrator_defconfig
m68k                            q40_defconfig
x86_64                           allyesconfig
sh                             sh03_defconfig
arm                           spitz_defconfig
arm                       multi_v4t_defconfig
powerpc                     akebono_defconfig
powerpc                      tqm8xx_defconfig
mips                         db1xxx_defconfig
mips                          ath25_defconfig
m68k                           sun3_defconfig
arm                         bcm2835_defconfig
mips                           rs90_defconfig
powerpc                       ppc64_defconfig
arm                       versatile_defconfig
sh                             shx3_defconfig
arm                          collie_defconfig
powerpc                     redwood_defconfig
mips                  maltasmvp_eva_defconfig
mips                     cu1000-neo_defconfig
mips                         rt305x_defconfig
mips                           ip28_defconfig
powerpc                    adder875_defconfig
arm                      footbridge_defconfig
arm                        cerfcube_defconfig
arm                        trizeps4_defconfig
arm                     davinci_all_defconfig
mips                           ip32_defconfig
arm                        multi_v7_defconfig
riscv                            alldefconfig
mips                            gpr_defconfig
h8300                               defconfig
powerpc                     stx_gp3_defconfig
arm                            mps2_defconfig
powerpc                     tqm8541_defconfig
sh                        edosk7760_defconfig
sh                   rts7751r2dplus_defconfig
arc                          axs101_defconfig
sh                 kfr2r09-romimage_defconfig
sh                         ap325rxa_defconfig
mips                          rm200_defconfig
openrisc                    or1ksim_defconfig
mips                     loongson2k_defconfig
powerpc                      ep88xc_defconfig
mips                         bigsur_defconfig
arm                            zeus_defconfig
h8300                     edosk2674_defconfig
powerpc                     pq2fads_defconfig
mips                        jmr3927_defconfig
mips                       bmips_be_defconfig
powerpc                  mpc866_ads_defconfig
mips                           gcw0_defconfig
powerpc64                           defconfig
mips                           mtx1_defconfig
m68k                         amcore_defconfig
powerpc                      katmai_defconfig
sh                               j2_defconfig
powerpc                      arches_defconfig
arc                            hsdk_defconfig
mips                         tb0226_defconfig
arm                        neponset_defconfig
arm                             mxs_defconfig
x86_64                           alldefconfig
sh                          rsk7201_defconfig
sh                           se7750_defconfig
arc                              alldefconfig
arm                          simpad_defconfig
arm                          imote2_defconfig
ia64                          tiger_defconfig
arm                         s5pv210_defconfig
arm                        mini2440_defconfig
xtensa                  cadence_csp_defconfig
powerpc                      ppc44x_defconfig
powerpc                      pasemi_defconfig
arm                           tegra_defconfig
openrisc                 simple_smp_defconfig
powerpc                        icon_defconfig
m68k                          multi_defconfig
m68k                       m5275evb_defconfig
arm                  colibri_pxa270_defconfig
arc                        vdk_hs38_defconfig
alpha                            alldefconfig
powerpc                 mpc8313_rdb_defconfig
mips                          rb532_defconfig
mips                         cobalt_defconfig
sh                      rts7751r2d1_defconfig
powerpc                      mgcoge_defconfig
arm                          pcm027_defconfig
arm                   milbeaut_m10v_defconfig
sh                          lboxre2_defconfig
powerpc                 mpc8540_ads_defconfig
nios2                            allyesconfig
arc                         haps_hs_defconfig
arm                       aspeed_g5_defconfig
powerpc                     mpc5200_defconfig
powerpc                      chrp32_defconfig
s390                          debug_defconfig
mips                        qi_lb60_defconfig
arm                       spear13xx_defconfig
h8300                       h8s-sim_defconfig
sh                          urquell_defconfig
riscv                    nommu_k210_defconfig
sh                          landisk_defconfig
arm                           corgi_defconfig
sh                ecovec24-romimage_defconfig
mips                            e55_defconfig
sh                           se7705_defconfig
sh                               allmodconfig
riscv             nommu_k210_sdcard_defconfig
sh                        dreamcast_defconfig
sh                          sdk7780_defconfig
mips                          malta_defconfig
arm                          ep93xx_defconfig
powerpc                 mpc832x_rdb_defconfig
arm                             rpc_defconfig
sparc64                          alldefconfig
arm                          iop32x_defconfig
mips                      pistachio_defconfig
mips                        workpad_defconfig
sh                          r7780mp_defconfig
powerpc                 mpc832x_mds_defconfig
m68k                             allmodconfig
xtensa                    xip_kc705_defconfig
powerpc                          g5_defconfig
powerpc                         wii_defconfig
mips                           ci20_defconfig
mips                   sb1250_swarm_defconfig
arc                        nsim_700_defconfig
powerpc                     tqm8555_defconfig
arm                           viper_defconfig
powerpc                     ppa8548_defconfig
arm                         shannon_defconfig
arm                             pxa_defconfig
powerpc                   lite5200b_defconfig
powerpc                      pmac32_defconfig
mips                        vocore2_defconfig
sh                          rsk7203_defconfig
sh                               alldefconfig
arm64                            alldefconfig
powerpc                      ppc64e_defconfig
mips                        bcm47xx_defconfig
powerpc                      ppc40x_defconfig
arm                        multi_v5_defconfig
powerpc                     pseries_defconfig
arm                           omap1_defconfig
powerpc                  storcenter_defconfig
ia64                             alldefconfig
powerpc                 linkstation_defconfig
mips                  decstation_64_defconfig
microblaze                      mmu_defconfig
powerpc               mpc834x_itxgp_defconfig
s390                             alldefconfig
arm                    vt8500_v6_v7_defconfig
sparc                       sparc64_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210826
x86_64               randconfig-a006-20210826
x86_64               randconfig-a001-20210826
x86_64               randconfig-a003-20210826
x86_64               randconfig-a004-20210826
x86_64               randconfig-a002-20210826
x86_64               randconfig-a005-20210822
x86_64               randconfig-a006-20210822
x86_64               randconfig-a001-20210822
x86_64               randconfig-a003-20210822
x86_64               randconfig-a004-20210822
x86_64               randconfig-a002-20210822
i386                 randconfig-a006-20210822
i386                 randconfig-a001-20210822
i386                 randconfig-a002-20210822
i386                 randconfig-a005-20210822
i386                 randconfig-a003-20210822
i386                 randconfig-a004-20210822
i386                 randconfig-a006-20210826
i386                 randconfig-a001-20210826
i386                 randconfig-a002-20210826
i386                 randconfig-a005-20210826
i386                 randconfig-a003-20210826
i386                 randconfig-a004-20210826
i386                 randconfig-a006-20210824
i386                 randconfig-a001-20210824
i386                 randconfig-a002-20210824
i386                 randconfig-a005-20210824
i386                 randconfig-a003-20210824
i386                 randconfig-a004-20210824
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
s390                 randconfig-c005-20210825
i386                 randconfig-c001-20210825
arm                  randconfig-c002-20210825
riscv                randconfig-c006-20210825
powerpc              randconfig-c003-20210825
x86_64               randconfig-c007-20210825
mips                 randconfig-c004-20210825
i386                 randconfig-c001-20210824
s390                 randconfig-c005-20210824
arm                  randconfig-c002-20210824
riscv                randconfig-c006-20210824
powerpc              randconfig-c003-20210824
x86_64               randconfig-c007-20210824
mips                 randconfig-c004-20210824
i386                 randconfig-c001-20210826
s390                 randconfig-c005-20210826
arm                  randconfig-c002-20210826
riscv                randconfig-c006-20210826
powerpc              randconfig-c003-20210826
x86_64               randconfig-c007-20210826
mips                 randconfig-c004-20210826
i386                 randconfig-c001-20210822
s390                 randconfig-c005-20210822
arm                  randconfig-c002-20210822
riscv                randconfig-c006-20210822
powerpc              randconfig-c003-20210822
x86_64               randconfig-c007-20210822
mips                 randconfig-c004-20210822
x86_64               randconfig-a014-20210822
x86_64               randconfig-a016-20210822
x86_64               randconfig-a015-20210822
x86_64               randconfig-a013-20210822
x86_64               randconfig-a012-20210822
x86_64               randconfig-a011-20210822
x86_64               randconfig-a014-20210826
x86_64               randconfig-a015-20210826
x86_64               randconfig-a016-20210826
x86_64               randconfig-a013-20210826
x86_64               randconfig-a012-20210826
x86_64               randconfig-a011-20210826
i386                 randconfig-a011-20210826
i386                 randconfig-a016-20210826
i386                 randconfig-a012-20210826
i386                 randconfig-a014-20210826
i386                 randconfig-a013-20210826
i386                 randconfig-a015-20210826
i386                 randconfig-a011-20210822
i386                 randconfig-a016-20210822
i386                 randconfig-a012-20210822
i386                 randconfig-a014-20210822
i386                 randconfig-a013-20210822
i386                 randconfig-a015-20210822
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826
hexagon              randconfig-r041-20210822
hexagon              randconfig-r045-20210822
riscv                randconfig-r042-20210822
s390                 randconfig-r044-20210822

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Thu Aug 26 16:29:58 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 07:29:58 +0800
Subject: [soc:rockchip/dt] BUILD SUCCESS
 9d508827c7939242e8ed6b06f66aa87d9f7ea832
Message-ID: <612823f6.nOCXEsAnm7dHzvd2%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git rockchip/dt
branch HEAD: 9d508827c7939242e8ed6b06f66aa87d9f7ea832  ARM: dts: rockchip: Add SFC to RV1108

elapsed time: 11591m

configs tested: 280
configs skipped: 125

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210826
i386                 randconfig-c001-20210818
arm                          gemini_defconfig
mips                      fuloong2e_defconfig
powerpc                       holly_defconfig
m68k                            mac_defconfig
powerpc                 mpc836x_mds_defconfig
sh                           se7722_defconfig
powerpc                     powernv_defconfig
powerpc                        warp_defconfig
mips                      loongson3_defconfig
powerpc                 mpc834x_itx_defconfig
sh                         microdev_defconfig
arm                       netwinder_defconfig
arm                         mv78xx0_defconfig
ia64                      gensparse_defconfig
h8300                       h8s-sim_defconfig
powerpc                       maple_defconfig
sh                           se7751_defconfig
arm                        realview_defconfig
s390                                defconfig
powerpc                         ps3_defconfig
sh                               alldefconfig
arm                            lart_defconfig
sh                         apsh4a3a_defconfig
arm                           viper_defconfig
mips                         rt305x_defconfig
arc                              allyesconfig
powerpc                 linkstation_defconfig
powerpc                    amigaone_defconfig
m68k                       m5249evb_defconfig
arm                            mmp2_defconfig
powerpc                       eiger_defconfig
powerpc                 canyonlands_defconfig
mips                     loongson1b_defconfig
arc                 nsimosci_hs_smp_defconfig
arm                        keystone_defconfig
xtensa                           alldefconfig
arm                        oxnas_v6_defconfig
nds32                            alldefconfig
powerpc                    ge_imp3a_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc837x_mds_defconfig
arm                      integrator_defconfig
m68k                            q40_defconfig
x86_64                           allyesconfig
sh                             sh03_defconfig
arm                           spitz_defconfig
arm                       multi_v4t_defconfig
powerpc                    adder875_defconfig
arm                        spear6xx_defconfig
powerpc                       ppc64_defconfig
mips                      maltaaprp_defconfig
mips                           ip28_defconfig
sh                          urquell_defconfig
arm                      tct_hammer_defconfig
csky                             alldefconfig
mips                     loongson2k_defconfig
powerpc                      ep88xc_defconfig
mips                         bigsur_defconfig
arm                            zeus_defconfig
h8300                     edosk2674_defconfig
powerpc                     pq2fads_defconfig
arm                         bcm2835_defconfig
mips                        jmr3927_defconfig
mips                       bmips_be_defconfig
arm                             mxs_defconfig
x86_64                           alldefconfig
sh                          rsk7201_defconfig
s390                          debug_defconfig
powerpc                 mpc8272_ads_defconfig
arc                            hsdk_defconfig
arm                           h5000_defconfig
arm                            mps2_defconfig
sh                      rts7751r2d1_defconfig
powerpc                      mgcoge_defconfig
arm                          pcm027_defconfig
arm                   milbeaut_m10v_defconfig
sh                          lboxre2_defconfig
sh                   secureedge5410_defconfig
sh                     magicpanelr2_defconfig
arm                         at91_dt_defconfig
xtensa                  audio_kc705_defconfig
powerpc                   microwatt_defconfig
riscv                    nommu_k210_defconfig
sh                          landisk_defconfig
arm                           corgi_defconfig
sh                ecovec24-romimage_defconfig
mips                            e55_defconfig
powerpc                   currituck_defconfig
sh                  sh7785lcr_32bit_defconfig
arm                          lpd270_defconfig
powerpc                 mpc8315_rdb_defconfig
sh                          sdk7780_defconfig
mips                          malta_defconfig
arm                          ep93xx_defconfig
ia64                             alldefconfig
powerpc                        icon_defconfig
xtensa                    xip_kc705_defconfig
powerpc                          g5_defconfig
mips                        qi_lb60_defconfig
powerpc                         wii_defconfig
mips                           ci20_defconfig
mips                   sb1250_swarm_defconfig
mips                         tb0287_defconfig
nios2                         3c120_defconfig
sh                            hp6xx_defconfig
mips                      maltasmvp_defconfig
powerpc                 mpc8540_ads_defconfig
powerpc                     mpc83xx_defconfig
arc                        nsim_700_defconfig
powerpc                     tqm8555_defconfig
sparc64                          alldefconfig
powerpc                     ppa8548_defconfig
arm                         shannon_defconfig
arm                             pxa_defconfig
powerpc                   lite5200b_defconfig
powerpc                      pmac32_defconfig
mips                        vocore2_defconfig
sh                        edosk7760_defconfig
arm64                            alldefconfig
powerpc                      ppc64e_defconfig
mips                        bcm47xx_defconfig
powerpc                      ppc40x_defconfig
arm                        multi_v5_defconfig
powerpc                     pseries_defconfig
arm                           omap1_defconfig
powerpc                  storcenter_defconfig
arm                       spear13xx_defconfig
powerpc                     asp8347_defconfig
m68k                        m5272c3_defconfig
arm                    vt8500_v6_v7_defconfig
sparc                       sparc64_defconfig
microblaze                      mmu_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210826
x86_64               randconfig-a006-20210826
x86_64               randconfig-a001-20210826
x86_64               randconfig-a003-20210826
x86_64               randconfig-a004-20210826
x86_64               randconfig-a002-20210826
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a006-20210826
i386                 randconfig-a001-20210826
i386                 randconfig-a002-20210826
i386                 randconfig-a005-20210826
i386                 randconfig-a003-20210826
i386                 randconfig-a004-20210826
i386                 randconfig-a004-20210818
i386                 randconfig-a006-20210818
i386                 randconfig-a002-20210818
i386                 randconfig-a001-20210818
i386                 randconfig-a003-20210818
i386                 randconfig-a005-20210818
x86_64               randconfig-a013-20210819
x86_64               randconfig-a011-20210819
x86_64               randconfig-a012-20210819
x86_64               randconfig-a016-20210819
x86_64               randconfig-a014-20210819
x86_64               randconfig-a015-20210819
i386                 randconfig-a015-20210819
i386                 randconfig-a011-20210819
i386                 randconfig-a014-20210819
i386                 randconfig-a013-20210819
i386                 randconfig-a016-20210819
i386                 randconfig-a012-20210819
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210826
s390                 randconfig-c005-20210826
arm                  randconfig-c002-20210826
riscv                randconfig-c006-20210826
powerpc              randconfig-c003-20210826
x86_64               randconfig-c007-20210826
mips                 randconfig-c004-20210826
riscv                randconfig-c006-20210818
s390                 randconfig-c005-20210818
powerpc              randconfig-c003-20210818
mips                 randconfig-c004-20210818
x86_64               randconfig-c007-20210818
i386                 randconfig-c001-20210818
arm                  randconfig-c002-20210818
riscv                randconfig-c006-20210819
s390                 randconfig-c005-20210819
powerpc              randconfig-c003-20210819
mips                 randconfig-c004-20210819
i386                 randconfig-c001-20210819
x86_64               randconfig-c007-20210819
arm                  randconfig-c002-20210819
x86_64               randconfig-a004-20210819
x86_64               randconfig-a006-20210819
x86_64               randconfig-a003-20210819
x86_64               randconfig-a002-20210819
x86_64               randconfig-a005-20210819
x86_64               randconfig-a001-20210819
i386                 randconfig-a004-20210819
i386                 randconfig-a006-20210819
i386                 randconfig-a001-20210819
i386                 randconfig-a002-20210819
i386                 randconfig-a003-20210819
i386                 randconfig-a005-20210819
x86_64               randconfig-a014-20210826
x86_64               randconfig-a015-20210826
x86_64               randconfig-a016-20210826
x86_64               randconfig-a013-20210826
x86_64               randconfig-a012-20210826
x86_64               randconfig-a011-20210826
x86_64               randconfig-a013-20210818
x86_64               randconfig-a011-20210818
x86_64               randconfig-a012-20210818
x86_64               randconfig-a016-20210818
x86_64               randconfig-a014-20210818
x86_64               randconfig-a015-20210818
i386                 randconfig-a011-20210826
i386                 randconfig-a016-20210826
i386                 randconfig-a012-20210826
i386                 randconfig-a014-20210826
i386                 randconfig-a013-20210826
i386                 randconfig-a015-20210826
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826
hexagon              randconfig-r041-20210818
riscv                randconfig-r042-20210818
s390                 randconfig-r044-20210818
hexagon              randconfig-r045-20210818
hexagon              randconfig-r041-20210819
hexagon              randconfig-r045-20210819

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Thu Aug 26 16:30:18 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 07:30:18 +0800
Subject: [soc:arm/soc] BUILD SUCCESS 51e321fed0ff8d64eff809a4ee0547254cdcc4a1
Message-ID: <6128240a.u8NFObAXjxrB4jLL%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/soc
branch HEAD: 51e321fed0ff8d64eff809a4ee0547254cdcc4a1  soc: aspeed-lpc-ctrl: Fix clock cleanup in error path

elapsed time: 742m

configs tested: 201
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210826
arm                          gemini_defconfig
mips                      fuloong2e_defconfig
powerpc                       holly_defconfig
m68k                            mac_defconfig
powerpc                 mpc836x_mds_defconfig
sh                           se7722_defconfig
powerpc                     powernv_defconfig
powerpc                        warp_defconfig
mips                      loongson3_defconfig
powerpc                 mpc834x_itx_defconfig
sh                         microdev_defconfig
arm                       netwinder_defconfig
arm                         mv78xx0_defconfig
ia64                      gensparse_defconfig
powerpc                         ps3_defconfig
sh                               alldefconfig
arm                            lart_defconfig
sh                         apsh4a3a_defconfig
arm                           viper_defconfig
powerpc                    amigaone_defconfig
m68k                       m5249evb_defconfig
arm                            mmp2_defconfig
powerpc                       eiger_defconfig
powerpc                 canyonlands_defconfig
mips                     loongson1b_defconfig
arc                 nsimosci_hs_smp_defconfig
arm                        keystone_defconfig
xtensa                           alldefconfig
arm                        oxnas_v6_defconfig
nds32                            alldefconfig
powerpc                    ge_imp3a_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc837x_mds_defconfig
arm                      integrator_defconfig
m68k                            q40_defconfig
x86_64                           allyesconfig
sh                             sh03_defconfig
arm                           spitz_defconfig
arm                       multi_v4t_defconfig
powerpc                     redwood_defconfig
mips                  maltasmvp_eva_defconfig
mips                     cu1000-neo_defconfig
mips                     loongson2k_defconfig
powerpc                      ep88xc_defconfig
mips                         bigsur_defconfig
arm                            zeus_defconfig
h8300                     edosk2674_defconfig
powerpc                     pq2fads_defconfig
arm                         bcm2835_defconfig
mips                        jmr3927_defconfig
mips                       bmips_be_defconfig
arm                             mxs_defconfig
x86_64                           alldefconfig
sh                          rsk7201_defconfig
sh                                  defconfig
openrisc                            defconfig
powerpc                     asp8347_defconfig
sparc                       sparc64_defconfig
sh                            shmin_defconfig
s390                          debug_defconfig
powerpc                 mpc8272_ads_defconfig
arc                            hsdk_defconfig
arm                           h5000_defconfig
arm                            mps2_defconfig
sh                      rts7751r2d1_defconfig
powerpc                      mgcoge_defconfig
arm                          pcm027_defconfig
arm                   milbeaut_m10v_defconfig
sh                          lboxre2_defconfig
arc                          axs101_defconfig
nios2                         10m50_defconfig
mips                           xway_defconfig
mips                          ath79_defconfig
arm                          collie_defconfig
h8300                       h8s-sim_defconfig
sh                          urquell_defconfig
riscv                    nommu_k210_defconfig
sh                          landisk_defconfig
arm                           corgi_defconfig
sh                ecovec24-romimage_defconfig
mips                            e55_defconfig
sh                          sdk7780_defconfig
mips                          malta_defconfig
arm                          ep93xx_defconfig
powerpc                        icon_defconfig
xtensa                    xip_kc705_defconfig
powerpc                          g5_defconfig
mips                        qi_lb60_defconfig
powerpc                         wii_defconfig
mips                           ci20_defconfig
mips                   sb1250_swarm_defconfig
arc                        nsim_700_defconfig
powerpc                     tqm8555_defconfig
sparc64                          alldefconfig
powerpc                     ppa8548_defconfig
arm                         shannon_defconfig
arm                             pxa_defconfig
powerpc                   lite5200b_defconfig
powerpc                      pmac32_defconfig
mips                        vocore2_defconfig
sh                        edosk7760_defconfig
arm64                            alldefconfig
powerpc                      ppc64e_defconfig
mips                        bcm47xx_defconfig
powerpc                      ppc40x_defconfig
arm                        multi_v5_defconfig
powerpc                     pseries_defconfig
arm                           omap1_defconfig
powerpc                  storcenter_defconfig
arm                       spear13xx_defconfig
ia64                             alldefconfig
arm                    vt8500_v6_v7_defconfig
microblaze                      mmu_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210826
x86_64               randconfig-a006-20210826
x86_64               randconfig-a001-20210826
x86_64               randconfig-a003-20210826
x86_64               randconfig-a004-20210826
x86_64               randconfig-a002-20210826
i386                 randconfig-a006-20210826
i386                 randconfig-a001-20210826
i386                 randconfig-a002-20210826
i386                 randconfig-a005-20210826
i386                 randconfig-a003-20210826
i386                 randconfig-a004-20210826
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210826
s390                 randconfig-c005-20210826
arm                  randconfig-c002-20210826
riscv                randconfig-c006-20210826
powerpc              randconfig-c003-20210826
x86_64               randconfig-c007-20210826
mips                 randconfig-c004-20210826
x86_64               randconfig-a014-20210826
x86_64               randconfig-a015-20210826
x86_64               randconfig-a016-20210826
x86_64               randconfig-a013-20210826
x86_64               randconfig-a012-20210826
x86_64               randconfig-a011-20210826
i386                 randconfig-a011-20210826
i386                 randconfig-a016-20210826
i386                 randconfig-a012-20210826
i386                 randconfig-a014-20210826
i386                 randconfig-a013-20210826
i386                 randconfig-a015-20210826
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Thu Aug 26 16:30:11 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 07:30:11 +0800
Subject: [soc:rockchip/driver] BUILD SUCCESS
 9e5747c57807ad8a04c356340190cfdd0bd54111
Message-ID: <61282403.dNRlRxc9SSbrAWBQ%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git rockchip/driver
branch HEAD: 9e5747c57807ad8a04c356340190cfdd0bd54111  soc: rockchip: io-domain: Remove unneeded semicolon

elapsed time: 10079m

configs tested: 345
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210826
i386                 randconfig-c001-20210821
powerpc              randconfig-c003-20210826
i386                 randconfig-c001-20210820
mips                 randconfig-c004-20210820
arm                          gemini_defconfig
mips                      fuloong2e_defconfig
powerpc                       holly_defconfig
m68k                            mac_defconfig
powerpc                 mpc836x_mds_defconfig
sh                           se7722_defconfig
powerpc                     powernv_defconfig
powerpc                        warp_defconfig
mips                      loongson3_defconfig
powerpc                 mpc834x_itx_defconfig
sh                         microdev_defconfig
arm                       netwinder_defconfig
arm                         mv78xx0_defconfig
ia64                      gensparse_defconfig
powerpc                         ps3_defconfig
sh                               alldefconfig
arm                            lart_defconfig
sh                         apsh4a3a_defconfig
arm                           viper_defconfig
powerpc                    amigaone_defconfig
m68k                       m5249evb_defconfig
arm                            mmp2_defconfig
powerpc                       eiger_defconfig
powerpc                 canyonlands_defconfig
powerpc                   bluestone_defconfig
arm                         lpc18xx_defconfig
arm                       multi_v4t_defconfig
s390                                defconfig
mips                        bcm63xx_defconfig
mips                     loongson1b_defconfig
arc                 nsimosci_hs_smp_defconfig
arm                        keystone_defconfig
xtensa                           alldefconfig
arm                        oxnas_v6_defconfig
nds32                            alldefconfig
powerpc                    ge_imp3a_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc837x_mds_defconfig
arm                      integrator_defconfig
m68k                            q40_defconfig
x86_64                           allyesconfig
sh                             sh03_defconfig
arm                           spitz_defconfig
sh                          urquell_defconfig
openrisc                         alldefconfig
powerpc                   lite5200b_defconfig
xtensa                  nommu_kc705_defconfig
powerpc                     redwood_defconfig
mips                  maltasmvp_eva_defconfig
mips                     cu1000-neo_defconfig
mips                         rt305x_defconfig
mips                           ip28_defconfig
powerpc                    adder875_defconfig
arm                      footbridge_defconfig
arm                        cerfcube_defconfig
arm                        trizeps4_defconfig
riscv                            alldefconfig
powerpc                     asp8347_defconfig
arc                     nsimosci_hs_defconfig
m68k                        mvme16x_defconfig
arm                            xcep_defconfig
sh                           se7780_defconfig
arm                          imote2_defconfig
powerpc                     tqm8541_defconfig
arm                           h3600_defconfig
parisc                generic-64bit_defconfig
riscv                    nommu_virt_defconfig
mips                     loongson2k_defconfig
powerpc                      ep88xc_defconfig
mips                         bigsur_defconfig
arm                            zeus_defconfig
h8300                     edosk2674_defconfig
powerpc                     pq2fads_defconfig
arm                         bcm2835_defconfig
mips                        jmr3927_defconfig
mips                       bmips_be_defconfig
arm                       imx_v4_v5_defconfig
x86_64                           alldefconfig
arm                          exynos_defconfig
arm                             mxs_defconfig
sh                          rsk7201_defconfig
powerpc                      pasemi_defconfig
mips                           ip32_defconfig
arm                           tegra_defconfig
openrisc                 simple_smp_defconfig
powerpc                        icon_defconfig
m68k                          multi_defconfig
s390                          debug_defconfig
powerpc                 mpc8272_ads_defconfig
arc                            hsdk_defconfig
arm                           h5000_defconfig
arm                            mps2_defconfig
arc                        vdk_hs38_defconfig
alpha                            alldefconfig
powerpc                 mpc8313_rdb_defconfig
mips                          rb532_defconfig
mips                         cobalt_defconfig
sh                      rts7751r2d1_defconfig
powerpc                      mgcoge_defconfig
arm                          pcm027_defconfig
arm                   milbeaut_m10v_defconfig
sh                          lboxre2_defconfig
arc                          axs101_defconfig
nios2                         10m50_defconfig
mips                           xway_defconfig
mips                          ath79_defconfig
arm                          collie_defconfig
m68k                          hp300_defconfig
sh                          sdk7786_defconfig
powerpc                 mpc8540_ads_defconfig
arc                         haps_hs_defconfig
arm                       aspeed_g5_defconfig
arm                         s5pv210_defconfig
h8300                       h8s-sim_defconfig
riscv                    nommu_k210_defconfig
sh                          landisk_defconfig
arm                           corgi_defconfig
sh                ecovec24-romimage_defconfig
mips                            e55_defconfig
powerpc                  mpc866_ads_defconfig
arc                      axs103_smp_defconfig
arm                          badge4_defconfig
sh                     sh7710voipgw_defconfig
sh                          sdk7780_defconfig
mips                          malta_defconfig
arm                          ep93xx_defconfig
ia64                             alldefconfig
mips                         tb0287_defconfig
i386                             alldefconfig
arm                        spear6xx_defconfig
arm                         orion5x_defconfig
xtensa                    xip_kc705_defconfig
powerpc                          g5_defconfig
mips                        qi_lb60_defconfig
powerpc                         wii_defconfig
mips                           ci20_defconfig
mips                   sb1250_swarm_defconfig
arc                        nsim_700_defconfig
powerpc                     tqm8555_defconfig
sparc64                          alldefconfig
powerpc                     ppa8548_defconfig
arm                         shannon_defconfig
arm                             pxa_defconfig
powerpc                      pmac32_defconfig
mips                        vocore2_defconfig
powerpc                     akebono_defconfig
sh                          rsk7203_defconfig
sh                               j2_defconfig
sh                        edosk7760_defconfig
arm64                            alldefconfig
powerpc                      ppc64e_defconfig
mips                        bcm47xx_defconfig
powerpc                      ppc40x_defconfig
arm                        multi_v5_defconfig
powerpc                     pseries_defconfig
arm                           omap1_defconfig
powerpc                  storcenter_defconfig
arm                       spear13xx_defconfig
arm                        clps711x_defconfig
powerpc                 linkstation_defconfig
mips                  decstation_64_defconfig
microblaze                      mmu_defconfig
arm                    vt8500_v6_v7_defconfig
sparc                       sparc64_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210826
x86_64               randconfig-a006-20210826
x86_64               randconfig-a001-20210826
x86_64               randconfig-a003-20210826
x86_64               randconfig-a004-20210826
x86_64               randconfig-a002-20210826
x86_64               randconfig-a005-20210820
x86_64               randconfig-a006-20210820
x86_64               randconfig-a001-20210820
x86_64               randconfig-a003-20210820
x86_64               randconfig-a004-20210820
x86_64               randconfig-a002-20210820
i386                 randconfig-a006-20210820
i386                 randconfig-a001-20210820
i386                 randconfig-a002-20210820
i386                 randconfig-a005-20210820
i386                 randconfig-a003-20210820
i386                 randconfig-a004-20210820
i386                 randconfig-a006-20210826
i386                 randconfig-a001-20210826
i386                 randconfig-a002-20210826
i386                 randconfig-a005-20210826
i386                 randconfig-a003-20210826
i386                 randconfig-a004-20210826
x86_64               randconfig-a014-20210821
x86_64               randconfig-a016-20210821
x86_64               randconfig-a015-20210821
x86_64               randconfig-a013-20210821
x86_64               randconfig-a012-20210821
x86_64               randconfig-a011-20210821
x86_64               randconfig-a004-20210818
x86_64               randconfig-a006-20210818
x86_64               randconfig-a003-20210818
x86_64               randconfig-a005-20210818
x86_64               randconfig-a002-20210818
x86_64               randconfig-a001-20210818
i386                 randconfig-a011-20210821
i386                 randconfig-a016-20210821
i386                 randconfig-a012-20210821
i386                 randconfig-a014-20210821
i386                 randconfig-a013-20210821
i386                 randconfig-a015-20210821
arc                  randconfig-r043-20210821
riscv                randconfig-r042-20210821
s390                 randconfig-r044-20210821
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                            allyesconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210822
s390                 randconfig-c005-20210822
arm                  randconfig-c002-20210822
riscv                randconfig-c006-20210822
powerpc              randconfig-c003-20210822
x86_64               randconfig-c007-20210822
mips                 randconfig-c004-20210822
i386                 randconfig-c001-20210826
s390                 randconfig-c005-20210826
arm                  randconfig-c002-20210826
riscv                randconfig-c006-20210826
powerpc              randconfig-c003-20210826
x86_64               randconfig-c007-20210826
mips                 randconfig-c004-20210826
s390                 randconfig-c005-20210821
i386                 randconfig-c001-20210821
arm                  randconfig-c002-20210821
riscv                randconfig-c006-20210821
powerpc              randconfig-c003-20210821
x86_64               randconfig-c007-20210821
mips                 randconfig-c004-20210821
i386                 randconfig-c001-20210820
s390                 randconfig-c005-20210820
arm                  randconfig-c002-20210820
riscv                randconfig-c006-20210820
powerpc              randconfig-c003-20210820
x86_64               randconfig-c007-20210820
mips                 randconfig-c004-20210820
riscv                randconfig-c006-20210818
s390                 randconfig-c005-20210818
powerpc              randconfig-c003-20210818
mips                 randconfig-c004-20210818
x86_64               randconfig-c007-20210818
i386                 randconfig-c001-20210818
arm                  randconfig-c002-20210818
x86_64               randconfig-a005-20210821
x86_64               randconfig-a001-20210821
x86_64               randconfig-a006-20210821
x86_64               randconfig-a003-20210821
x86_64               randconfig-a004-20210821
x86_64               randconfig-a002-20210821
i386                 randconfig-a006-20210821
i386                 randconfig-a001-20210821
i386                 randconfig-a002-20210821
i386                 randconfig-a005-20210821
i386                 randconfig-a004-20210821
i386                 randconfig-a003-20210821
x86_64               randconfig-a014-20210820
x86_64               randconfig-a016-20210820
x86_64               randconfig-a015-20210820
x86_64               randconfig-a013-20210820
x86_64               randconfig-a012-20210820
x86_64               randconfig-a011-20210820
x86_64               randconfig-a014-20210826
x86_64               randconfig-a015-20210826
x86_64               randconfig-a016-20210826
x86_64               randconfig-a013-20210826
x86_64               randconfig-a012-20210826
x86_64               randconfig-a011-20210826
i386                 randconfig-a011-20210826
i386                 randconfig-a016-20210826
i386                 randconfig-a012-20210826
i386                 randconfig-a014-20210826
i386                 randconfig-a013-20210826
i386                 randconfig-a015-20210826
i386                 randconfig-a015-20210818
i386                 randconfig-a011-20210818
i386                 randconfig-a013-20210818
i386                 randconfig-a014-20210818
i386                 randconfig-a016-20210818
i386                 randconfig-a012-20210818
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826
hexagon              randconfig-r041-20210819
hexagon              randconfig-r045-20210819
hexagon              randconfig-r041-20210820
hexagon              randconfig-r045-20210820
riscv                randconfig-r042-20210820
s390                 randconfig-r044-20210820
hexagon              randconfig-r041-20210818
riscv                randconfig-r042-20210818
s390                 randconfig-r044-20210818
hexagon              randconfig-r045-20210818

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Thu Aug 26 16:30:21 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 07:30:21 +0800
Subject: [soc:arm/defconfig] BUILD SUCCESS
 79cd0bb66e359f5f9398de9d2e86eac776947691
Message-ID: <6128240d.WS4jxsI7e+TLB4Q0%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/defconfig
branch HEAD: 79cd0bb66e359f5f9398de9d2e86eac776947691  Merge tag 'zynq-soc-for-v5.15' of https://github.com/Xilinx/linux-xlnx into arm/defconfig

elapsed time: 742m

configs tested: 199
configs skipped: 95

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210826
arm                          gemini_defconfig
mips                      fuloong2e_defconfig
powerpc                       holly_defconfig
m68k                            mac_defconfig
powerpc                 mpc836x_mds_defconfig
sh                           se7722_defconfig
powerpc                     powernv_defconfig
powerpc                        warp_defconfig
mips                      loongson3_defconfig
powerpc                 mpc834x_itx_defconfig
sh                         microdev_defconfig
arm                       netwinder_defconfig
arm                         mv78xx0_defconfig
ia64                      gensparse_defconfig
powerpc                         ps3_defconfig
sh                               alldefconfig
arm                            lart_defconfig
sh                         apsh4a3a_defconfig
arm                           viper_defconfig
powerpc                    amigaone_defconfig
m68k                       m5249evb_defconfig
arm                            mmp2_defconfig
powerpc                       eiger_defconfig
powerpc                 canyonlands_defconfig
mips                     loongson1b_defconfig
arc                 nsimosci_hs_smp_defconfig
arm                        keystone_defconfig
xtensa                           alldefconfig
arm                        oxnas_v6_defconfig
nds32                            alldefconfig
powerpc                    ge_imp3a_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc837x_mds_defconfig
arm                      integrator_defconfig
m68k                            q40_defconfig
x86_64                           allyesconfig
sh                             sh03_defconfig
arm                           spitz_defconfig
arm                       multi_v4t_defconfig
mips                     loongson2k_defconfig
powerpc                      ep88xc_defconfig
mips                         bigsur_defconfig
arm                            zeus_defconfig
h8300                     edosk2674_defconfig
powerpc                     pq2fads_defconfig
arm                         bcm2835_defconfig
mips                        jmr3927_defconfig
mips                       bmips_be_defconfig
arm                             mxs_defconfig
x86_64                           alldefconfig
sh                          rsk7201_defconfig
sh                                  defconfig
openrisc                            defconfig
powerpc                     asp8347_defconfig
sparc                       sparc64_defconfig
sh                            shmin_defconfig
s390                          debug_defconfig
powerpc                 mpc8272_ads_defconfig
arc                            hsdk_defconfig
arm                           h5000_defconfig
arm                            mps2_defconfig
xtensa                generic_kc705_defconfig
arm                         lpc18xx_defconfig
powerpc                          g5_defconfig
xtensa                          iss_defconfig
sh                      rts7751r2d1_defconfig
powerpc                      mgcoge_defconfig
arm                          pcm027_defconfig
arm                   milbeaut_m10v_defconfig
sh                          lboxre2_defconfig
arc                          axs101_defconfig
nios2                         10m50_defconfig
mips                           xway_defconfig
mips                          ath79_defconfig
arm                          collie_defconfig
riscv                    nommu_k210_defconfig
sh                          landisk_defconfig
arm                           corgi_defconfig
sh                ecovec24-romimage_defconfig
mips                            e55_defconfig
sh                          sdk7780_defconfig
mips                          malta_defconfig
arm                          ep93xx_defconfig
powerpc                        icon_defconfig
xtensa                    xip_kc705_defconfig
mips                        qi_lb60_defconfig
powerpc                         wii_defconfig
mips                           ci20_defconfig
mips                   sb1250_swarm_defconfig
arc                        nsim_700_defconfig
powerpc                     tqm8555_defconfig
sparc64                          alldefconfig
powerpc                     ppa8548_defconfig
arm                         shannon_defconfig
arm                             pxa_defconfig
powerpc                   lite5200b_defconfig
powerpc                      pmac32_defconfig
mips                        vocore2_defconfig
sh                        edosk7760_defconfig
arm64                            alldefconfig
powerpc                      ppc64e_defconfig
mips                        bcm47xx_defconfig
powerpc                      ppc40x_defconfig
arm                        multi_v5_defconfig
powerpc                     pseries_defconfig
arm                           omap1_defconfig
powerpc                  storcenter_defconfig
arm                       spear13xx_defconfig
ia64                             alldefconfig
arm                    vt8500_v6_v7_defconfig
microblaze                      mmu_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210826
x86_64               randconfig-a006-20210826
x86_64               randconfig-a001-20210826
x86_64               randconfig-a003-20210826
x86_64               randconfig-a004-20210826
x86_64               randconfig-a002-20210826
i386                 randconfig-a006-20210826
i386                 randconfig-a001-20210826
i386                 randconfig-a002-20210826
i386                 randconfig-a005-20210826
i386                 randconfig-a003-20210826
i386                 randconfig-a004-20210826
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210826
s390                 randconfig-c005-20210826
arm                  randconfig-c002-20210826
riscv                randconfig-c006-20210826
powerpc              randconfig-c003-20210826
x86_64               randconfig-c007-20210826
mips                 randconfig-c004-20210826
x86_64               randconfig-a014-20210826
x86_64               randconfig-a015-20210826
x86_64               randconfig-a016-20210826
x86_64               randconfig-a013-20210826
x86_64               randconfig-a012-20210826
x86_64               randconfig-a011-20210826
i386                 randconfig-a011-20210826
i386                 randconfig-a016-20210826
i386                 randconfig-a012-20210826
i386                 randconfig-a014-20210826
i386                 randconfig-a013-20210826
i386                 randconfig-a015-20210826
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Thu Aug 26 16:30:06 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 07:30:06 +0800
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
References: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
Message-ID: <202108270732.OvBQ4K3D-lkp@intel.com>

Hi Chia-Wei,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on arm/for-next keystone/next soc/for-next rockchip/for-next arm64/for-next/core linus/master joel-aspeed/for-next v5.14-rc7 next-20210826]
[cannot apply to xlnx/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chia-Wei-Wang/arm-aspeed-Add-eSPI-support/20210826-141737
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm64-randconfig-r002-20210826 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/2980a1777c50754fe145f2e73ded8739931c0712
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chia-Wei-Wang/arm-aspeed-Add-eSPI-support/20210826-141737
        git checkout 2980a1777c50754fe145f2e73ded8739931c0712
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/soc/aspeed/aspeed-espi-ctrl.c:22:
   drivers/soc/aspeed/aspeed-espi-perif.h: In function 'aspeed_espi_perif_alloc':
>> drivers/soc/aspeed/aspeed-espi-perif.h:446:43: error: passing argument 3 of 'of_property_read_u32' from incompatible pointer type [-Werror=incompatible-pointer-types]
     446 |                                           &espi_perif->mcyc_saddr);
         |                                           ^~~~~~~~~~~~~~~~~~~~~~~
         |                                           |
         |                                           phys_addr_t * {aka long long unsigned int *}
   In file included from include/linux/of_device.h:9,
                    from drivers/soc/aspeed/aspeed-espi-ctrl.c:9:
   include/linux/of.h:1249:45: note: expected 'u32 *' {aka 'unsigned int *'} but argument is of type 'phys_addr_t *' {aka 'long long unsigned int *'}
    1249 |                                        u32 *out_value)
         |                                        ~~~~~^~~~~~~~~
   drivers/soc/aspeed/aspeed-espi-ctrl.c: In function 'aspeed_espi_ctrl_probe':
   drivers/soc/aspeed/aspeed-espi-ctrl.c:98:30: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
      98 |         espi_ctrl->version = (uint32_t)of_device_get_match_data(dev);
         |                              ^
   cc1: some warnings being treated as errors


vim +/of_property_read_u32 +446 drivers/soc/aspeed/aspeed-espi-perif.h

   422	
   423	static void *aspeed_espi_perif_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
   424	{
   425		int rc;
   426		struct aspeed_espi_perif *espi_perif;
   427		struct aspeed_espi_perif_dma *dma;
   428	
   429		espi_perif = devm_kzalloc(dev, sizeof(*espi_perif), GFP_KERNEL);
   430		if (!espi_perif)
   431			return ERR_PTR(-ENOMEM);
   432	
   433		espi_perif->ctrl = espi_ctrl;
   434	
   435		init_waitqueue_head(&espi_perif->wq);
   436	
   437		spin_lock_init(&espi_perif->lock);
   438	
   439		mutex_init(&espi_perif->pc_rx_mtx);
   440		mutex_init(&espi_perif->pc_tx_mtx);
   441		mutex_init(&espi_perif->np_tx_mtx);
   442	
   443		espi_perif->mcyc_enable = of_property_read_bool(dev->of_node, "perif,memcyc-enable");
   444		if (espi_perif->mcyc_enable) {
   445			rc = of_property_read_u32(dev->of_node, "perif,memcyc-src-addr",
 > 446						  &espi_perif->mcyc_saddr);
   447			if (rc) {
   448				dev_err(dev, "cannot get Host source address for memory cycle\n");
   449				return ERR_PTR(-ENODEV);
   450			}
   451	
   452			rc = of_property_read_u32(dev->of_node, "perif,memcyc-size",
   453						  &espi_perif->mcyc_size);
   454			if (rc) {
   455				dev_err(dev, "cannot get size for memory cycle\n");
   456				return ERR_PTR(-ENODEV);
   457			}
   458	
   459			if (espi_perif->mcyc_size < PERIF_MEMCYC_SIZE_MIN)
   460				espi_perif->mcyc_size = PERIF_MEMCYC_SIZE_MIN;
   461			else
   462				espi_perif->mcyc_size = roundup_pow_of_two(espi_perif->mcyc_size);
   463	
   464			espi_perif->mcyc_mask = ~(espi_perif->mcyc_size - 1);
   465			espi_perif->mcyc_virt = dma_alloc_coherent(dev, espi_perif->mcyc_size,
   466								   &espi_perif->mcyc_taddr, GFP_KERNEL);
   467			if (!espi_perif->mcyc_virt) {
   468				dev_err(dev, "cannot allocate memory cycle region\n");
   469				return ERR_PTR(-ENOMEM);
   470			}
   471		}
   472	
   473		if (of_property_read_bool(dev->of_node, "perif,dma-mode")) {
   474			dma = &espi_perif->dma;
   475	
   476			dma->pc_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
   477							     &dma->pc_tx_addr, GFP_KERNEL);
   478			if (!dma->pc_tx_virt) {
   479				dev_err(dev, "cannot allocate posted TX DMA buffer\n");
   480				return ERR_PTR(-ENOMEM);
   481			}
   482	
   483			dma->pc_rx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
   484							     &dma->pc_rx_addr, GFP_KERNEL);
   485			if (!dma->pc_rx_virt) {
   486				dev_err(dev, "cannot allocate posted RX DMA buffer\n");
   487				return ERR_PTR(-ENOMEM);
   488			}
   489	
   490			dma->np_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
   491					&dma->np_tx_addr, GFP_KERNEL);
   492			if (!dma->np_tx_virt) {
   493				dev_err(dev, "cannot allocate non-posted TX DMA buffer\n");
   494				return ERR_PTR(-ENOMEM);
   495			}
   496	
   497			espi_perif->dma_mode = 1;
   498		}
   499	
   500		espi_perif->mdev.parent = dev;
   501		espi_perif->mdev.minor = MISC_DYNAMIC_MINOR;
   502		espi_perif->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", PERIF_MDEV_NAME);
   503		espi_perif->mdev.fops = &aspeed_espi_perif_fops;
   504		rc = misc_register(&espi_perif->mdev);
   505		if (rc) {
   506			dev_err(dev, "cannot register device\n");
   507			return ERR_PTR(rc);
   508		}
   509	
   510		aspeed_espi_perif_enable(espi_perif);
   511	
   512		return espi_perif;
   513	}
   514	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 42142 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210827/b00a950a/attachment-0001.gz>

From madvenka at linux.microsoft.com  Thu Aug 26 16:31:26 2021
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Thu, 26 Aug 2021 18:31:26 -0500
Subject: [RFC PATCH v8 3/4] arm64: Introduce stack trace reliability
 checks in the unwinder
In-Reply-To: <YSe50PuWM/mjNwAj@sirena.org.uk>
References: <b45aac2843f16ca759e065ea547ab0afff8c0f01>
 <20210812190603.25326-1-madvenka@linux.microsoft.com>
 <20210812190603.25326-4-madvenka@linux.microsoft.com>
 <YSe50PuWM/mjNwAj@sirena.org.uk>
Message-ID: <77c43173-95c9-6ce5-ad11-219d38a66e34@linux.microsoft.com>



On 8/26/21 10:57 AM, Mark Brown wrote:
> On Thu, Aug 12, 2021 at 02:06:02PM -0500, madvenka at linux.microsoft.com wrote:
> 
>> +	if (frame->need_reliable && !unwind_is_reliable(frame)) {
>> +		/* Cannot unwind to the next frame reliably. */
>> +		frame->failed = true;
>> +		return false;
>> +	}
> 
> This means we only collect reliability information in the case
> where we're specifically doing a reliable stacktrace.  For
> example when printing stack traces on the console it might be
> useful to print a ? or something if the frame is unreliable as a
> hint to the reader that the information might be misleading.
> Could we therefore change the flag here to a reliability one and
> our need_reliable check so that we always run
> unwind_is_reliable()?
> 
> I'm not sure if we need to abandon the trace on first error when
> doing a reliable trace but I can see it's a bit safer so perhaps
> better to do so.  If we don't abandon then we don't require the
> need_reliable check at all.
> 

I think that the caller should be able to specify that the stack trace
should be abandoned. Like Livepatch.

So, we could always do the reliability check. But keep need_reliable.

Thanks.

Madhavan
	


From vee.khee.wong at linux.intel.com  Thu Aug 26 16:51:32 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Fri, 27 Aug 2021 07:51:32 +0800
Subject: [PATCH net-next v2 1/2] net: pcs: xpcs: enable skip xPCS soft reset
Message-ID: <20210826235134.4051310-1-vee.khee.wong@linux.intel.com>

Unlike any other platforms, Intel AlderLake-S uses Synopsys SerDes where
all the SerDes PLL configurations are controlled by the xPCS at the BIOS
level. If the driver perform a xPCS soft reset on initialization, these
settings will be switched back to the power on reset values.

This patch introduced a new xpcs_reset() function for drivers such as
sja1105 and stmmac to decide whether or not to perform a xPCS soft
reset.

Suggested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Cc: Vladimir Oltean <vladimir.oltean at nxp.com>
Signed-off-by: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>
Signed-off-by: Wong Vee Khee <vee.khee.wong at linux.intel.com>
---
 drivers/net/dsa/sja1105/sja1105_mdio.c        |  6 ++-
 .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 15 +++++++-
 drivers/net/pcs/pcs-xpcs.c                    | 37 ++++++++++---------
 include/linux/pcs/pcs-xpcs.h                  |  4 +-
 include/linux/stmmac.h                        |  1 +
 5 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
index 705d3900e43a..6f8cc1358ac0 100644
--- a/drivers/net/dsa/sja1105/sja1105_mdio.c
+++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
@@ -435,13 +435,17 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
 			goto out_pcs_free;
 		}
 
-		xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
+		xpcs = xpcs_create(mdiodev);
 		if (IS_ERR(xpcs)) {
 			rc = PTR_ERR(xpcs);
 			goto out_pcs_free;
 		}
 
 		priv->xpcs[port] = xpcs;
+
+		rc = xpcs_reset(xpcs, priv->phy_mode[port]);
+		if (rc)
+			goto out_pcs_free;
 	}
 
 	priv->mdio_pcs = bus;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index a5d150c5f3d8..50f0e6dccb85 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -401,12 +401,15 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
 {
 	struct net_device *ndev = bus->priv;
 	struct mdio_device *mdiodev;
+	bool skip_xpcs_soft_reset;
 	struct stmmac_priv *priv;
 	struct dw_xpcs *xpcs;
 	int mode, addr;
+	int err;
 
 	priv = netdev_priv(ndev);
 	mode = priv->plat->phy_interface;
+	skip_xpcs_soft_reset = priv->plat->skip_xpcs_soft_reset;
 
 	/* Try to probe the XPCS by scanning all addresses. */
 	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
@@ -414,12 +417,20 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
 		if (IS_ERR(mdiodev))
 			continue;
 
-		xpcs = xpcs_create(mdiodev, mode);
-		if (IS_ERR_OR_NULL(xpcs)) {
+		xpcs = xpcs_create(mdiodev);
+		if (IS_ERR(xpcs)) {
 			mdio_device_free(mdiodev);
 			continue;
 		}
 
+		if (!skip_xpcs_soft_reset) {
+			err = xpcs_reset(xpcs, mode);
+			if (err) {
+				mdio_device_free(mdiodev);
+				continue;
+			}
+		}
+
 		priv->hw->xpcs = xpcs;
 		break;
 	}
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index fb0a83dc09ac..e4961884dd96 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -252,6 +252,18 @@ static int xpcs_soft_reset(struct dw_xpcs *xpcs,
 	return xpcs_poll_reset(xpcs, dev);
 }
 
+int xpcs_reset(struct dw_xpcs *xpcs, phy_interface_t interface)
+{
+	const struct xpcs_compat *compat;
+
+	compat = xpcs_find_compat(xpcs->id, interface);
+	if (!compat)
+		return -ENODEV;
+
+	return xpcs_soft_reset(xpcs, compat);
+}
+EXPORT_SYMBOL_GPL(xpcs_reset);
+
 #define xpcs_warn(__xpcs, __state, __args...) \
 ({ \
 	if ((__state)->link) \
@@ -1084,12 +1096,11 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = {
 	.pcs_link_up = xpcs_link_up,
 };
 
-struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-			    phy_interface_t interface)
+struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
 {
 	struct dw_xpcs *xpcs;
 	u32 xpcs_id;
-	int i, ret;
+	int i;
 
 	xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
 	if (!xpcs)
@@ -1099,37 +1110,27 @@ struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
 
 	xpcs_id = xpcs_get_id(xpcs);
 
+	/* If Device ID are all ones, there is no device found */
+	if (xpcs_id == 0xffffffff)
+		goto out;
+
 	for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
 		const struct xpcs_id *entry = &xpcs_id_list[i];
-		const struct xpcs_compat *compat;
 
 		if ((xpcs_id & entry->mask) != entry->id)
 			continue;
 
 		xpcs->id = entry;
-
-		compat = xpcs_find_compat(entry, interface);
-		if (!compat) {
-			ret = -ENODEV;
-			goto out;
-		}
-
 		xpcs->pcs.ops = &xpcs_phylink_ops;
 		xpcs->pcs.poll = true;
 
-		ret = xpcs_soft_reset(xpcs, compat);
-		if (ret)
-			goto out;
-
 		return xpcs;
 	}
 
-	ret = -ENODEV;
-
 out:
 	kfree(xpcs);
 
-	return ERR_PTR(ret);
+	return ERR_PTR(-ENODEV);
 }
 EXPORT_SYMBOL_GPL(xpcs_create);
 
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index add077a81b21..d841f55f12cc 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -35,8 +35,8 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
 		   struct phylink_link_state *state);
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
-struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-			    phy_interface_t interface);
+int xpcs_reset(struct dw_xpcs *xpcs, phy_interface_t interface);
+struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev);
 void xpcs_destroy(struct dw_xpcs *xpcs);
 
 #endif /* __LINUX_PCS_XPCS_H */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..0f901773c5e4 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -268,5 +268,6 @@ struct plat_stmmacenet_data {
 	int msi_rx_base_vec;
 	int msi_tx_base_vec;
 	bool use_phy_wol;
+	bool skip_xpcs_soft_reset;
 };
 #endif
-- 
2.25.1



From vee.khee.wong at linux.intel.com  Thu Aug 26 16:51:33 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Fri, 27 Aug 2021 07:51:33 +0800
Subject: [PATCH net-next v2 1/2] net: pcs: xpcs: enable skip xPCS soft reset
In-Reply-To: <20210826235134.4051310-1-vee.khee.wong@linux.intel.com>
References: <20210826235134.4051310-1-vee.khee.wong@linux.intel.com>
Message-ID: <20210826235134.4051310-2-vee.khee.wong@linux.intel.com>

Unlike any other platforms, Intel AlderLake-S uses Synopsys SerDes where
all the SerDes PLL configurations are controlled by the xPCS at the BIOS
level. If the driver perform a xPCS soft reset on initialization, these
settings will be switched back to the power on reset values.

This patch introduced a new xpcs_reset() function for drivers such as
sja1105 and stmmac to decide whether or not to perform a xPCS soft
reset.

Suggested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Cc: Vladimir Oltean <vladimir.oltean at nxp.com>
Signed-off-by: Michael Sit Wei Hong <michael.wei.hong.sit at intel.com>
Signed-off-by: Wong Vee Khee <vee.khee.wong at linux.intel.com>
---
 drivers/net/dsa/sja1105/sja1105_mdio.c        |  6 ++-
 .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 15 +++++++-
 drivers/net/pcs/pcs-xpcs.c                    | 37 ++++++++++---------
 include/linux/pcs/pcs-xpcs.h                  |  4 +-
 include/linux/stmmac.h                        |  1 +
 5 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
index 705d3900e43a..6f8cc1358ac0 100644
--- a/drivers/net/dsa/sja1105/sja1105_mdio.c
+++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
@@ -435,13 +435,17 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv)
 			goto out_pcs_free;
 		}
 
-		xpcs = xpcs_create(mdiodev, priv->phy_mode[port]);
+		xpcs = xpcs_create(mdiodev);
 		if (IS_ERR(xpcs)) {
 			rc = PTR_ERR(xpcs);
 			goto out_pcs_free;
 		}
 
 		priv->xpcs[port] = xpcs;
+
+		rc = xpcs_reset(xpcs, priv->phy_mode[port]);
+		if (rc)
+			goto out_pcs_free;
 	}
 
 	priv->mdio_pcs = bus;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index a5d150c5f3d8..50f0e6dccb85 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -401,12 +401,15 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
 {
 	struct net_device *ndev = bus->priv;
 	struct mdio_device *mdiodev;
+	bool skip_xpcs_soft_reset;
 	struct stmmac_priv *priv;
 	struct dw_xpcs *xpcs;
 	int mode, addr;
+	int err;
 
 	priv = netdev_priv(ndev);
 	mode = priv->plat->phy_interface;
+	skip_xpcs_soft_reset = priv->plat->skip_xpcs_soft_reset;
 
 	/* Try to probe the XPCS by scanning all addresses. */
 	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
@@ -414,12 +417,20 @@ int stmmac_xpcs_setup(struct mii_bus *bus)
 		if (IS_ERR(mdiodev))
 			continue;
 
-		xpcs = xpcs_create(mdiodev, mode);
-		if (IS_ERR_OR_NULL(xpcs)) {
+		xpcs = xpcs_create(mdiodev);
+		if (IS_ERR(xpcs)) {
 			mdio_device_free(mdiodev);
 			continue;
 		}
 
+		if (!skip_xpcs_soft_reset) {
+			err = xpcs_reset(xpcs, mode);
+			if (err) {
+				mdio_device_free(mdiodev);
+				continue;
+			}
+		}
+
 		priv->hw->xpcs = xpcs;
 		break;
 	}
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index fb0a83dc09ac..e4961884dd96 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -252,6 +252,18 @@ static int xpcs_soft_reset(struct dw_xpcs *xpcs,
 	return xpcs_poll_reset(xpcs, dev);
 }
 
+int xpcs_reset(struct dw_xpcs *xpcs, phy_interface_t interface)
+{
+	const struct xpcs_compat *compat;
+
+	compat = xpcs_find_compat(xpcs->id, interface);
+	if (!compat)
+		return -ENODEV;
+
+	return xpcs_soft_reset(xpcs, compat);
+}
+EXPORT_SYMBOL_GPL(xpcs_reset);
+
 #define xpcs_warn(__xpcs, __state, __args...) \
 ({ \
 	if ((__state)->link) \
@@ -1084,12 +1096,11 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = {
 	.pcs_link_up = xpcs_link_up,
 };
 
-struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-			    phy_interface_t interface)
+struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
 {
 	struct dw_xpcs *xpcs;
 	u32 xpcs_id;
-	int i, ret;
+	int i;
 
 	xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
 	if (!xpcs)
@@ -1099,37 +1110,27 @@ struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
 
 	xpcs_id = xpcs_get_id(xpcs);
 
+	/* If Device ID are all ones, there is no device found */
+	if (xpcs_id == 0xffffffff)
+		goto out;
+
 	for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
 		const struct xpcs_id *entry = &xpcs_id_list[i];
-		const struct xpcs_compat *compat;
 
 		if ((xpcs_id & entry->mask) != entry->id)
 			continue;
 
 		xpcs->id = entry;
-
-		compat = xpcs_find_compat(entry, interface);
-		if (!compat) {
-			ret = -ENODEV;
-			goto out;
-		}
-
 		xpcs->pcs.ops = &xpcs_phylink_ops;
 		xpcs->pcs.poll = true;
 
-		ret = xpcs_soft_reset(xpcs, compat);
-		if (ret)
-			goto out;
-
 		return xpcs;
 	}
 
-	ret = -ENODEV;
-
 out:
 	kfree(xpcs);
 
-	return ERR_PTR(ret);
+	return ERR_PTR(-ENODEV);
 }
 EXPORT_SYMBOL_GPL(xpcs_create);
 
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index add077a81b21..d841f55f12cc 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -35,8 +35,8 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
 		   struct phylink_link_state *state);
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
-struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-			    phy_interface_t interface);
+int xpcs_reset(struct dw_xpcs *xpcs, phy_interface_t interface);
+struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev);
 void xpcs_destroy(struct dw_xpcs *xpcs);
 
 #endif /* __LINUX_PCS_XPCS_H */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..0f901773c5e4 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -268,5 +268,6 @@ struct plat_stmmacenet_data {
 	int msi_rx_base_vec;
 	int msi_tx_base_vec;
 	bool use_phy_wol;
+	bool skip_xpcs_soft_reset;
 };
 #endif
-- 
2.25.1



From vee.khee.wong at linux.intel.com  Thu Aug 26 16:51:34 2021
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Fri, 27 Aug 2021 07:51:34 +0800
Subject: [PATCH net-next v2 2/2] stmmac: intel: Enable 2.5Gbps on Intel
 AlderLake-S
In-Reply-To: <20210826235134.4051310-1-vee.khee.wong@linux.intel.com>
References: <20210826235134.4051310-1-vee.khee.wong@linux.intel.com>
Message-ID: <20210826235134.4051310-3-vee.khee.wong@linux.intel.com>

Intel AlderLake-S platform is capable of 2.5Gbps link speed.

This patch enables the 2.5Gbps link speed by adding the callback
function in the AlderLake-S PCI info struct.

Signed-off-by: Wong Vee Khee <vee.khee.wong at linux.intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 8e8778cfbbad..c1db7e53e78f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -770,6 +770,8 @@ static int adls_sgmii_phy0_data(struct pci_dev *pdev,
 {
 	plat->bus_id = 1;
 	plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+	plat->speed_mode_2500 = intel_speed_mode_2500;
+	plat->skip_xpcs_soft_reset = 1;
 
 	/* SerDes power up and power down are done in BIOS for ADL */
 
@@ -785,6 +787,8 @@ static int adls_sgmii_phy1_data(struct pci_dev *pdev,
 {
 	plat->bus_id = 2;
 	plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+	plat->speed_mode_2500 = intel_speed_mode_2500;
+	plat->skip_xpcs_soft_reset = 1;
 
 	/* SerDes power up and power down are done in BIOS for ADL */
 
-- 
2.25.1



From nobuhiro1.iwamatsu at toshiba.co.jp  Thu Aug 26 16:49:04 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (nobuhiro1.iwamatsu at toshiba.co.jp)
Date: Thu, 26 Aug 2021 23:49:04 +0000
Subject: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <162998285902.30814.11206633831020646086.b4-ty@arm.com>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <162998285902.30814.11206633831020646086.b4-ty@arm.com>
Message-ID: <TYAPR01MB6252A29B56BBF8921822824F92C79@TYAPR01MB6252.jpnprd01.prod.outlook.com>

Hi,

> -----Original Message-----
> From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
> Sent: Thursday, August 26, 2021 10:01 PM
> To: iwamatsu nobuhiro(?? ?? ????????) <nobuhiro1.iwamatsu at toshiba.co.jp>; Rob Herring
> <robh+dt at kernel.org>; Bjorn Helgaas <bhelgaas at google.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>; Kishon Vijay Abraham I <kishon at ti.com>; ishikawa yuji(?? ??
> ?????????????) <yuji2.ishikawa at toshiba.co.jp>; linux-arm-kernel at lists.infradead.org;
> linux-pci at vger.kernel.org; Krzysztof Wilczy?ski <kw at linux.com>; agrawal punit(????? ??? ????????)
> <punit1.agrawal at toshiba.co.jp>; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host controller driver
> 
> On Wed, 11 Aug 2021 17:38:27 +0900, Nobuhiro Iwamatsu wrote:
> > This series is the PCIe driver for Toshiba's ARM SoC, Visconti[0].
> > This provides DT binding documentation, device driver, MAINTAINER files.
> >
> > Best regards,
> >   Nobuhiro
> >
> > [0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html
> >
> > [...]
> 
> Applied to pci/dwc, thanks!

Thanks! But...
> 
> [1/3] dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
>       https://git.kernel.org/lpieralisi/pci/c/a655ce4000
> [2/3] PCI: visconti: Add Toshiba Visconti PCIe host controller driver
>       https://git.kernel.org/lpieralisi/pci/c/09436f819c

Only drivers/pci/controller/dwc/Makefile is applied. Could you check this?	

> [3/3] MAINTAINERS: Add entries for Toshiba Visconti PCIe controller
>       https://git.kernel.org/lpieralisi/pci/c/34af7aace1
> 
> Thanks,
> Lorenzo

Best regards,
  Nobuhiro

From seanjc at google.com  Thu Aug 26 16:54:51 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 23:54:51 +0000
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <1700758714.29394.1630003332081.JavaMail.zimbra@efficios.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-5-seanjc@google.com>
 <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>
 <282257549.21721.1629732017655.JavaMail.zimbra@efficios.com>
 <YSblqrrpKcORzilX@google.com>
 <1700758714.29394.1630003332081.JavaMail.zimbra@efficios.com>
Message-ID: <YSgpy8iXXXUQ+b/k@google.com>

On Thu, Aug 26, 2021, Mathieu Desnoyers wrote:
> ----- On Aug 25, 2021, at 8:51 PM, Sean Christopherson seanjc at google.com wrote:
> >> >> +		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
> >> >> +		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)",
> >> >> +			    errno, strerror(errno));
> >> >> +		atomic_inc(&seq_cnt);
> >> >> +
> >> >> +		CPU_CLR(cpu, &allowed_mask);
> >> >> +
> >> >> +		/*
> >> >> +		 * Let the read-side get back into KVM_RUN to improve the odds
> >> >> +		 * of task migration coinciding with KVM's run loop.
> >> > 
> >> > This comment should be about increasing the odds of letting the seqlock
> >> > read-side complete. Otherwise, the delay between the two back-to-back
> >> > atomic_inc is so small that the seqlock read-side may never have time to
> >> > complete the reading the rseq cpu id and the sched_getcpu() call, and can
> >> > retry forever.
> > 
> > Hmm, but that's not why there's a delay.  I'm not arguing that a livelock isn't
> > possible (though that syscall would have to be screaming fast),
> 
> I don't think we have the same understanding of the livelock scenario. AFAIU the livelock
> would be caused by a too-small delay between the two consecutive atomic_inc() from one
> loop iteration to the next compared to the time it takes to perform a read-side critical
> section of the seqlock. Back-to-back atomic_inc can be performed very quickly, so I
> doubt that the sched_getcpu implementation have good odds to be fast enough to complete
> in that narrow window, leading to lots of read seqlock retry.

Ooooh, yeah, brain fart on my side.  I was thinking of the two atomic_inc() in the
same loop iteration and completely ignoring the next iteration.  Yes, I 100% agree
that a delay to ensure forward progress is needed.  An assertion in main() that the
reader complete at least some reasonable number of KVM_RUNs is also probably a good
idea, e.g. to rule out a false pass due to the reader never making forward progress.

FWIW, the do-while loop does make forward progress without a delay, but at ~50% 
throughput, give or take.

> > but the primary motivation is very much to allow the read-side enough time
> > to get back into KVM proper.
> 
> I'm puzzled by your statement. AFAIU, let's say we don't have the delay, then we
> have:
> 
> migration thread                             KVM_RUN/read-side thread
> -----------------------------------------------------------------------------------
>                                              - ioctl(KVM_RUN)
> - atomic_inc_seq_cst(&seqcnt)
> - sched_setaffinity
> - atomic_inc_seq_cst(&seqcnt)
>                                              - a = atomic_load(&seqcnt) & ~1
>                                              - smp_rmb()
>                                              - b = LOAD_ONCE(__rseq_abi->cpu_id);
>                                              - sched_getcpu()
>                                              - smp_rmb()
>                                              - re-load seqcnt/compare (succeeds)
>                                                - Can only succeed if entire read-side happens while the seqcnt
>                                                  is in an even numbered state.
>                                              - if (a != b) abort()
>   /* no delay. Even counter state is very
>      short. */
> - atomic_inc_seq_cst(&seqcnt)
>   /* Let's suppose the lack of delay causes the
>      setaffinity to complete too early compared
>      with KVM_RUN ioctl */
> - sched_setaffinity
> - atomic_inc_seq_cst(&seqcnt)
> 
>   /* no delay. Even counter state is very
>      short. */
> - atomic_inc_seq_cst(&seqcnt)
>   /* Then a setaffinity from a following
>      migration thread loop will run
>      concurrently with KVM_RUN */
>                                              - ioctl(KVM_RUN)
> - sched_setaffinity
> - atomic_inc_seq_cst(&seqcnt)
> 
> As pointed out here, if the first setaffinity runs too early compared with KVM_RUN,
> a following setaffinity will run concurrently with it. However, the fact that 
> the even counter state is very short may very well hurt progress of the read seqlock.

*sigh*

Several hours later, I think I finally have my head wrapped around everything.

Due to the way the test is written and because of how KVM's run loop works,
TIF_NOTIFY_RESUME or TIF_NEED_RESCHED effectively has to be set before KVM actually
enters the guest, otherwise KVM will exit to userspace without touching the flag,
i.e. it will be handled by the normal exit_to_user_mode_loop().

Where I got lost was trying to figure out why I couldn't make the bug reproduce by
causing the guest to exit to KVM, but not userspace, in which case KVM should
easily trigger the problematic flow as the window for sched_getcpu() to collide
with KVM would be enormous.  The reason I didn't go down this route for the
"official" test is that, unless there's something clever I'm overlooking, it
requires arch specific guest code, and ialso I don't know that forcing an exit
would even be necessary/sufficient on other architectures.

Anyways, I was trying to confirm that the bug was being hit without a delay, while
still retaining the sequence retry in the test.  The test doesn't fail because the
back-to-back atomic_inc() changes seqcnt too fast.  The read-side makes forward
progress, but it never observes failure because the do-while loop only ever
completes after another sched_setaffinity(), never after the one that collides
with KVM because it takes too long to get out of ioctl(KVM_RUN) and back to the
test.  I.e. the atomic_inc() in the next loop iteration (makes seq_cnt odd) always
completes before the check, and so the check ends up spinning until another
migration, which correctly updates rseq.  This was expected and didn't confuse me.

What confused me is that I was trying to confirm the bug was being hit from within
the kernel by confirming KVM observed TIF_NOTIFY_RESUME, but I misunderstood when
TIF_NOTIFY_RESUME would get set.  KVM can observe TIF_NOTIFY_RESUME directly, but
it's rare, and I suspect happens iff sched_setaffinity() hits the small window where
it collides with KVM_RUN before KVM enters the guest.

More commonly, the bug occurs when KVM sees TIF_NEED_RESCHED.  In that case, KVM
calls xfer_to_guest_mode_work(), which does schedule() and _that_ sets
TIF_NOTIFY_RESUME.  xfer_to_guest_mode_work() then mishandles TIF_NOTIFY_RESUME
and the bug is hit, but my confirmation logic in KVM never fired.

So there are effectively three reasons we want a delay:

  1. To allow sched_setaffinity() to coincide with ioctl(KVM_RUN) before KVM can
     enter the guest so that the guest doesn't need an arch-specific VM-Exit source.

  2. To let ioctl(KVM_RUN) make its way back to the test before the next round
     of migration.

  3. To ensure the read-side can make forward progress, e.g. if sched_getcpu()
     involves a syscall.


After looking at KVM for arm64 and s390, #1 is a bit tenuous because x86 is the
only arch that currently uses xfer_to_guest_mode_work(), i.e. the test could be
tweaked to be overtly x86-specific.  But since a delay is needed for #2 and #3,
I'd prefer to rely on it for #1 as well in the hopes that this test provides
coverage for arm64 and/or s390 if they're ever converted to use the common
xfer_to_guest_mode_work().


From iwona.winiarska at intel.com  Thu Aug 26 16:54:56 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Thu, 26 Aug 2021 23:54:56 +0000
Subject: [PATCH v2 07/15] peci: Add peci-aspeed controller driver
In-Reply-To: <CAPcyv4jPVSt9Wr2TkDActFVLP+ygaDwBnsKG410Nf1qfP_MB9A@mail.gmail.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-8-iwona.winiarska@intel.com>
 <CAPcyv4jPVSt9Wr2TkDActFVLP+ygaDwBnsKG410Nf1qfP_MB9A@mail.gmail.com>
Message-ID: <b26ee278838698289869964fe59578f0d5f7b19c.camel@intel.com>

On Wed, 2021-08-25 at 18:35 -0700, Dan Williams wrote:
> On Tue, Aug 3, 2021 at 4:35 AM Iwona Winiarska
> <iwona.winiarska at intel.com> wrote:
> > 
> > From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > 
> > ASPEED AST24xx/AST25xx/AST26xx SoCs supports the PECI electrical
> > interface (a.k.a PECI wire).
> 
> Maybe a one sentence blurb here and in the Kconfig reminding people
> why they should care if they have a PECI driver or not?

Ok, I'll expand it a bit.

> 
> > 
> > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> > ---
> > ?MAINTAINERS?????????????????????????? |?? 9 +
> > ?drivers/peci/Kconfig????????????????? |?? 6 +
> > ?drivers/peci/Makefile???????????????? |?? 3 +
> > ?drivers/peci/controller/Kconfig?????? |? 16 +
> > ?drivers/peci/controller/Makefile????? |?? 3 +
> > ?drivers/peci/controller/peci-aspeed.c | 445 ++++++++++++++++++++++++++
> > ?6 files changed, 482 insertions(+)
> > ?create mode 100644 drivers/peci/controller/Kconfig
> > ?create mode 100644 drivers/peci/controller/Makefile
> > ?create mode 100644 drivers/peci/controller/peci-aspeed.c
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index d411974aaa5e..6e9d53ff68ab 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2866,6 +2866,15 @@ S:?????? Maintained
> > ?F:???? Documentation/hwmon/asc7621.rst
> > ?F:???? drivers/hwmon/asc7621.c
> > 
> > +ASPEED PECI CONTROLLER
> > +M:???? Iwona Winiarska <iwona.winiarska at intel.com>
> > +M:???? Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > +L:???? linux-aspeed at lists.ozlabs.org?(moderated for non-subscribers)
> > +L:???? openbmc at lists.ozlabs.org?(moderated for non-subscribers)
> > +S:???? Supported
> > +F:???? Documentation/devicetree/bindings/peci/peci-aspeed.yaml
> > +F:???? drivers/peci/controller/peci-aspeed.c
> > +
> > ?ASPEED PINCTRL DRIVERS
> > ?M:???? Andrew Jeffery <andrew at aj.id.au>
> > ?L:???? linux-aspeed at lists.ozlabs.org?(moderated for non-subscribers)
> > diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
> > index 71a4ad81225a..99279df97a78 100644
> > --- a/drivers/peci/Kconfig
> > +++ b/drivers/peci/Kconfig
> > @@ -13,3 +13,9 @@ menuconfig PECI
> > 
> > ????????? This support is also available as a module. If so, the module
> > ????????? will be called peci.
> > +
> > +if PECI
> > +
> > +source "drivers/peci/controller/Kconfig"
> > +
> > +endif # PECI
> > diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
> > index e789a354e842..926d8df15cbd 100644
> > --- a/drivers/peci/Makefile
> > +++ b/drivers/peci/Makefile
> > @@ -3,3 +3,6 @@
> > ?# Core functionality
> > ?peci-y := core.o
> > ?obj-$(CONFIG_PECI) += peci.o
> > +
> > +# Hardware specific bus drivers
> > +obj-y += controller/
> > diff --git a/drivers/peci/controller/Kconfig
> > b/drivers/peci/controller/Kconfig
> > new file mode 100644
> > index 000000000000..6d48df08db1c
> > --- /dev/null
> > +++ b/drivers/peci/controller/Kconfig
> > @@ -0,0 +1,16 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +
> > +config PECI_ASPEED
> > +?????? tristate "ASPEED PECI support"
> > +?????? depends on ARCH_ASPEED || COMPILE_TEST
> > +?????? depends on OF
> > +?????? depends on HAS_IOMEM
> > +?????? help
> > +???????? This option enables PECI controller driver for ASPEED AST2400,
> > +???????? AST2500 and AST2600 SoCs.
> > +
> > +???????? Say Y here if your system runs on ASPEED SoC and you are using it
> > +???????? as BMC for Intel platform.
> > +
> > +???????? This driver can also be built as a module. If so, the module will
> > +???????? be called peci-aspeed.
> > diff --git a/drivers/peci/controller/Makefile
> > b/drivers/peci/controller/Makefile
> > new file mode 100644
> > index 000000000000..022c28ef1bf0
> > --- /dev/null
> > +++ b/drivers/peci/controller/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +
> > +obj-$(CONFIG_PECI_ASPEED)????? += peci-aspeed.o
> > diff --git a/drivers/peci/controller/peci-aspeed.c
> > b/drivers/peci/controller/peci-aspeed.c
> > new file mode 100644
> > index 000000000000..1d708c983749
> > --- /dev/null
> > +++ b/drivers/peci/controller/peci-aspeed.c
> > @@ -0,0 +1,445 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +// Copyright (C) 2012-2017 ASPEED Technology Inc.
> > +// Copyright (c) 2018-2021 Intel Corporation
> 
> Why different copyright capitalization?

I'll make them consistent.

> 
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/jiffies.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/peci.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/reset.h>
> > +
> > +#include <asm/unaligned.h>
> 
> Why is this included?

Leftover - I'll remove it.

> 
> > +
> > +/* ASPEED PECI Registers */
> > +/* Control Register */
> > +#define ASPEED_PECI_CTRL?????????????????????? 0x00
> > +#define?? ASPEED_PECI_CTRL_SAMPLING_MASK?????? GENMASK(19, 16)
> > +#define?? ASPEED_PECI_CTRL_RD_MODE_MASK??????????????? GENMASK(13, 12)
> > +#define???? ASPEED_PECI_CTRL_RD_MODE_DBG?????? BIT(13)
> > +#define???? ASPEED_PECI_CTRL_RD_MODE_COUNT???? BIT(12)
> > +#define?? ASPEED_PECI_CTRL_CLK_SOURCE????????? BIT(11)
> > +#define?? ASPEED_PECI_CTRL_CLK_DIV_MASK??????????????? GENMASK(10, 8)
> > +#define?? ASPEED_PECI_CTRL_INVERT_OUT????????? BIT(7)
> > +#define?? ASPEED_PECI_CTRL_INVERT_IN?????????? BIT(6)
> > +#define?? ASPEED_PECI_CTRL_BUS_CONTENTION_EN?? BIT(5)
> > +#define?? ASPEED_PECI_CTRL_PECI_EN???????????? BIT(4)
> > +#define?? ASPEED_PECI_CTRL_PECI_CLK_EN???????? BIT(0)
> > +
> > +/* Timing Negotiation Register */
> > +#define ASPEED_PECI_TIMING_NEGOTIATION???????? 0x04
> > +#define?? ASPEED_PECI_T_NEGO_MSG_MASK????????? GENMASK(15, 8)
> > +#define?? ASPEED_PECI_T_NEGO_ADDR_MASK???????? GENMASK(7, 0)
> > +
> > +/* Command Register */
> > +#define ASPEED_PECI_CMD??????????????????????????????? 0x08
> > +#define?? ASPEED_PECI_CMD_PIN_MONITORING?????? BIT(31)
> > +#define?? ASPEED_PECI_CMD_STS_MASK???????????? GENMASK(27, 24)
> > +#define???? ASPEED_PECI_CMD_STS_ADDR_T_NEGO??? 0x3
> > +#define?? ASPEED_PECI_CMD_IDLE_MASK??????????? \
> > +???????? (ASPEED_PECI_CMD_STS_MASK | ASPEED_PECI_CMD_PIN_MONITORING)
> > +#define?? ASPEED_PECI_CMD_FIRE???????????????? BIT(0)
> > +
> > +/* Read/Write Length Register */
> > +#define ASPEED_PECI_RW_LENGTH????????????????? 0x0c
> > +#define?? ASPEED_PECI_AW_FCS_EN??????????????????????? BIT(31)
> > +#define?? ASPEED_PECI_RD_LEN_MASK????????????? GENMASK(23, 16)
> > +#define?? ASPEED_PECI_WR_LEN_MASK????????????? GENMASK(15, 8)
> > +#define?? ASPEED_PECI_TARGET_ADDR_MASK???????? GENMASK(7, 0)
> > +
> > +/* Expected FCS Data Register */
> > +#define ASPEED_PECI_EXPECTED_FCS?????????????? 0x10
> > +#define?? ASPEED_PECI_EXPECTED_RD_FCS_MASK???? GENMASK(23, 16)
> > +#define?? ASPEED_PECI_EXPECTED_AW_FCS_AUTO_MASK??????? GENMASK(15, 8)
> > +#define?? ASPEED_PECI_EXPECTED_WR_FCS_MASK???? GENMASK(7, 0)
> > +
> > +/* Captured FCS Data Register */
> > +#define ASPEED_PECI_CAPTURED_FCS?????????????? 0x14
> > +#define?? ASPEED_PECI_CAPTURED_RD_FCS_MASK???? GENMASK(23, 16)
> > +#define?? ASPEED_PECI_CAPTURED_WR_FCS_MASK???? GENMASK(7, 0)
> > +
> > +/* Interrupt Register */
> > +#define ASPEED_PECI_INT_CTRL?????????????????? 0x18
> > +#define?? ASPEED_PECI_TIMING_NEGO_SEL_MASK???? GENMASK(31, 30)
> > +#define???? ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO?? 0
> > +#define???? ASPEED_PECI_2ND_BIT_OF_ADDR_NEGO?? 1
> > +#define???? ASPEED_PECI_MESSAGE_NEGO?????????? 2
> > +#define?? ASPEED_PECI_INT_MASK???????????????? GENMASK(4, 0)
> > +#define???? ASPEED_PECI_INT_BUS_TIMEOUT??????????????? BIT(4)
> > +#define???? ASPEED_PECI_INT_BUS_CONTENTION???? BIT(3)
> > +#define???? ASPEED_PECI_INT_WR_FCS_BAD???????? BIT(2)
> > +#define???? ASPEED_PECI_INT_WR_FCS_ABORT?????? BIT(1)
> > +#define???? ASPEED_PECI_INT_CMD_DONE?????????? BIT(0)
> > +
> > +/* Interrupt Status Register */
> > +#define ASPEED_PECI_INT_STS??????????????????? 0x1c
> > +#define?? ASPEED_PECI_INT_TIMING_RESULT_MASK?? GENMASK(29, 16)
> > +???????? /* bits[4..0]: Same bit fields in the 'Interrupt Register' */
> > +
> > +/* Rx/Tx Data Buffer Registers */
> > +#define ASPEED_PECI_WR_DATA0?????????????????? 0x20
> > +#define ASPEED_PECI_WR_DATA1?????????????????? 0x24
> > +#define ASPEED_PECI_WR_DATA2?????????????????? 0x28
> > +#define ASPEED_PECI_WR_DATA3?????????????????? 0x2c
> > +#define ASPEED_PECI_RD_DATA0?????????????????? 0x30
> > +#define ASPEED_PECI_RD_DATA1?????????????????? 0x34
> > +#define ASPEED_PECI_RD_DATA2?????????????????? 0x38
> > +#define ASPEED_PECI_RD_DATA3?????????????????? 0x3c
> > +#define ASPEED_PECI_WR_DATA4?????????????????? 0x40
> > +#define ASPEED_PECI_WR_DATA5?????????????????? 0x44
> > +#define ASPEED_PECI_WR_DATA6?????????????????? 0x48
> > +#define ASPEED_PECI_WR_DATA7?????????????????? 0x4c
> > +#define ASPEED_PECI_RD_DATA4?????????????????? 0x50
> > +#define ASPEED_PECI_RD_DATA5?????????????????? 0x54
> > +#define ASPEED_PECI_RD_DATA6?????????????????? 0x58
> > +#define ASPEED_PECI_RD_DATA7?????????????????? 0x5c
> > +#define?? ASPEED_PECI_DATA_BUF_SIZE_MAX??????????????? 32
> > +
> > +/* Timing Negotiation */
> > +#define ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT? 8
> > +#define ASPEED_PECI_RD_SAMPLING_POINT_MAX????? (BIT(4) - 1)
> > +#define ASPEED_PECI_CLK_DIV_DEFAULT??????????? 0
> > +#define ASPEED_PECI_CLK_DIV_MAX??????????????????????? (BIT(3) - 1)
> > +#define ASPEED_PECI_MSG_TIMING_DEFAULT???????? 1
> > +#define ASPEED_PECI_MSG_TIMING_MAX???????????? (BIT(8) - 1)
> > +#define ASPEED_PECI_ADDR_TIMING_DEFAULT??????????????? 1
> > +#define ASPEED_PECI_ADDR_TIMING_MAX??????????? (BIT(8) - 1)
> > +
> > +/* Timeout */
> > +#define ASPEED_PECI_IDLE_CHECK_TIMEOUT_US????? (50 * USEC_PER_MSEC)
> > +#define ASPEED_PECI_IDLE_CHECK_INTERVAL_US???? (10 * USEC_PER_MSEC)
> > +#define ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT???? (1000)
> > +#define ASPEED_PECI_CMD_TIMEOUT_MS_MAX???????? (1000)
> > +
> > +struct aspeed_peci {
> > +?????? struct peci_controller *controller;
> > +?????? struct device *dev;
> > +?????? void __iomem *base;
> > +?????? struct clk *clk;
> > +?????? struct reset_control *rst;
> > +?????? int irq;
> > +?????? spinlock_t lock; /* to sync completion status handling */
> > +?????? struct completion xfer_complete;
> > +?????? u32 status;
> > +?????? u32 cmd_timeout_ms;
> > +?????? u32 msg_timing;
> > +?????? u32 addr_timing;
> > +?????? u32 rd_sampling_point;
> > +?????? u32 clk_div;
> > +};
> > +
> > +static void aspeed_peci_init_regs(struct aspeed_peci *priv)
> > +{
> > +?????? u32 val;
> > +
> > +?????? val = FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK,
> > ASPEED_PECI_CLK_DIV_DEFAULT);
> > +?????? val |= ASPEED_PECI_CTRL_PECI_CLK_EN;
> > +?????? writel(val, priv->base + ASPEED_PECI_CTRL);
> > +?????? /*
> > +??????? * Timing negotiation period setting.
> > +??????? * The unit of the programmed value is 4 times of PECI clock period.
> > +??????? */
> > +?????? val = FIELD_PREP(ASPEED_PECI_T_NEGO_MSG_MASK, priv->msg_timing);
> > +?????? val |= FIELD_PREP(ASPEED_PECI_T_NEGO_ADDR_MASK, priv->addr_timing);
> > +?????? writel(val, priv->base + ASPEED_PECI_TIMING_NEGOTIATION);
> > +
> > +?????? /* Clear interrupts */
> > +?????? val = readl(priv->base + ASPEED_PECI_INT_STS) |
> > ASPEED_PECI_INT_MASK;
> > +?????? writel(val, priv->base + ASPEED_PECI_INT_STS);
> > +
> > +?????? /* Set timing negotiation mode and enable interrupts */
> > +?????? val = FIELD_PREP(ASPEED_PECI_TIMING_NEGO_SEL_MASK,
> > ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO);
> > +?????? val |= ASPEED_PECI_INT_MASK;
> > +?????? writel(val, priv->base + ASPEED_PECI_INT_CTRL);
> > +
> > +?????? val = FIELD_PREP(ASPEED_PECI_CTRL_SAMPLING_MASK, priv-
> > >rd_sampling_point);
> > +?????? val |= FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK, priv->clk_div);
> > +?????? val |= ASPEED_PECI_CTRL_PECI_EN;
> > +?????? val |= ASPEED_PECI_CTRL_PECI_CLK_EN;
> > +?????? writel(val, priv->base + ASPEED_PECI_CTRL);
> > +}
> > +
> > +static inline int aspeed_peci_check_idle(struct aspeed_peci *priv)
> > +{
> > +?????? u32 cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
> > +
> > +?????? if (FIELD_GET(ASPEED_PECI_CMD_STS_MASK, cmd_sts) ==
> > ASPEED_PECI_CMD_STS_ADDR_T_NEGO)
> > +?????????????? aspeed_peci_init_regs(priv);
> > +
> > +?????? return readl_poll_timeout(priv->base + ASPEED_PECI_CMD,
> > +???????????????????????????????? cmd_sts,
> > +???????????????????????????????? !(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK),
> > +???????????????????????????????? ASPEED_PECI_IDLE_CHECK_INTERVAL_US,
> > +???????????????????????????????? ASPEED_PECI_IDLE_CHECK_TIMEOUT_US);
> > +}
> > +
> > +static int aspeed_peci_xfer(struct peci_controller *controller,
> > +?????????????????????????? u8 addr, struct peci_request *req)
> > +{
> > +?????? struct aspeed_peci *priv = dev_get_drvdata(controller->dev.parent);
> > +?????? unsigned long flags, timeout = msecs_to_jiffies(priv-
> > >cmd_timeout_ms);
> > +?????? u32 peci_head;
> > +?????? int ret;
> > +
> > +?????? if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
> > +?????????? req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
> > +?????????????? return -EINVAL;
> > +
> > +?????? /* Check command sts and bus idle state */
> > +?????? ret = aspeed_peci_check_idle(priv);
> > +?????? if (ret)
> > +?????????????? return ret; /* -ETIMEDOUT */
> > +
> > +?????? spin_lock_irqsave(&priv->lock, flags);
> > +?????? reinit_completion(&priv->xfer_complete);
> > +
> > +?????? peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
> > +?????????????????? FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
> > +?????????????????? FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
> > +
> > +?????? writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
> > +
> > +?????? memcpy_toio(priv->base + ASPEED_PECI_WR_DATA0, req->tx.buf,
> > min_t(u8, req->tx.len, 16));
> > +?????? if (req->tx.len > 16)
> > +?????????????? memcpy_toio(priv->base + ASPEED_PECI_WR_DATA4, req->tx.buf +
> > 16,
> > +?????????????????????????? req->tx.len - 16);
> > +
> > +?????? dev_dbg(priv->dev, "HEAD : 0x%08x\n", peci_head);
> > +?????? print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf, req-
> > >tx.len);
> 
> On CONFIG_DYNAMIC_DEBUG=n builds the kernel will do all the work of
> reading through this buffer, but skip emitting it. Are you sure you
> want to pay that overhead for every transaction?

I can remove it or I can add something like:

#if IS_ENABLED(CONFIG_PECI_DEBUG)
#define peci_debug(fmt, ...) pr_debug(fmt, ##__VA_ARGS__)
#else
#define peci_debug(...) do { } while (0)
#endif

(and similar peci_trace with trace_printk for usage in IRQ handlers and such).

What do you think?

> 
> > +
> > +?????? priv->status = 0;
> > +?????? writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
> > +?????? spin_unlock_irqrestore(&priv->lock, flags);
> > +
> > +?????? ret = wait_for_completion_interruptible_timeout(&priv-
> > >xfer_complete, timeout);
> 
> spin_lock_irqsave() says "I don't know if interrupts are disabled
> already, so I'll save the state, whatever it is, and restore later"
> 
> wait_for_completion_interruptible_timeout() says "I know I am in a
> sleepable context where interrupts are enabled"
> 
> So, one of those is wrong, i.e. should it be spin_{lock,unlock}_irq()?

You're right - I'll fix it.

> 
> 
> > +?????? if (ret < 0)
> > +?????????????? return ret;
> > +
> > +?????? if (ret == 0) {
> > +?????????????? dev_dbg(priv->dev, "Timeout waiting for a response!\n");
> > +?????????????? return -ETIMEDOUT;
> > +?????? }
> > +
> > +?????? spin_lock_irqsave(&priv->lock, flags);
> > +
> > +?????? writel(0, priv->base + ASPEED_PECI_CMD);
> > +
> > +?????? if (priv->status != ASPEED_PECI_INT_CMD_DONE) {
> > +?????????????? spin_unlock_irqrestore(&priv->lock, flags);
> > +?????????????? dev_dbg(priv->dev, "No valid response!\n");
> > +?????????????? return -EIO;
> > +?????? }
> > +
> > +?????? spin_unlock_irqrestore(&priv->lock, flags);
> > +
> > +?????? memcpy_fromio(req->rx.buf, priv->base + ASPEED_PECI_RD_DATA0,
> > min_t(u8, req->rx.len, 16));
> > +?????? if (req->rx.len > 16)
> > +?????????????? memcpy_fromio(req->rx.buf + 16, priv->base +
> > ASPEED_PECI_RD_DATA4,
> > +???????????????????????????? req->rx.len - 16);
> > +
> > +?????? print_hex_dump_bytes("RX : ", DUMP_PREFIX_NONE, req->rx.buf, req-
> > >rx.len);
> > +
> > +?????? return 0;
> > +}
> > +
> > +static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
> > +{
> > +?????? struct aspeed_peci *priv = arg;
> > +?????? u32 status;
> > +
> > +?????? spin_lock(&priv->lock);
> > +?????? status = readl(priv->base + ASPEED_PECI_INT_STS);
> > +?????? writel(status, priv->base + ASPEED_PECI_INT_STS);
> > +?????? priv->status |= (status & ASPEED_PECI_INT_MASK);
> > +
> > +?????? /*
> > +??????? * In most cases, interrupt bits will be set one by one but also
> > note
> > +??????? * that multiple interrupt bits could be set at the same time.
> > +??????? */
> > +?????? if (status & ASPEED_PECI_INT_BUS_TIMEOUT)
> > +?????????????? dev_dbg_ratelimited(priv->dev,
> > "ASPEED_PECI_INT_BUS_TIMEOUT\n");
> > +
> > +?????? if (status & ASPEED_PECI_INT_BUS_CONTENTION)
> > +?????????????? dev_dbg_ratelimited(priv->dev,
> > "ASPEED_PECI_INT_BUS_CONTENTION\n");
> > +
> > +?????? if (status & ASPEED_PECI_INT_WR_FCS_BAD)
> > +?????????????? dev_dbg_ratelimited(priv->dev,
> > "ASPEED_PECI_INT_WR_FCS_BAD\n");
> > +
> > +?????? if (status & ASPEED_PECI_INT_WR_FCS_ABORT)
> > +?????????????? dev_dbg_ratelimited(priv->dev,
> > "ASPEED_PECI_INT_WR_FCS_ABORT\n");
> 
> Are you sure these would not be better as tracepoints? If you're
> debugging an interrupt related failure, the ratelimiting might get in
> your way when you really need to know when one of these error
> interrupts fire relative to another event.

Tracepoints are ABI(ish), and using a full blown tracepoint just for IRQ status
would probably be too much.
I was thinking about something like trace_printk hidden under a
"CONFIG_PECI_DEBUG" (see above), but perhaps that's something for the future
improvement?

> 
> > +
> > +?????? /*
> > +??????? * All commands should be ended up with a ASPEED_PECI_INT_CMD_DONE
> > bit
> > +??????? * set even in an error case.
> > +??????? */
> > +?????? if (status & ASPEED_PECI_INT_CMD_DONE)
> > +?????????????? complete(&priv->xfer_complete);
> 
> Hmm, no need to check if there was a sequencing error, like a command
> was never submitted?

It's handled by checking if HW is idle in xfer before a command is sent, where
we just expect a single interrupt per command.

> 
> > +
> > +?????? spin_unlock(&priv->lock);
> > +
> > +?????? return IRQ_HANDLED;
> > +}
> > +
> > +static void aspeed_peci_property_sanitize(struct device *dev, const char
> > *propname,
> > +???????????????????????????????????????? u32 min, u32 max, u32 default_val,
> > u32 *propval)
> > +{
> > +?????? u32 val;
> > +?????? int ret;
> > +
> > +?????? ret = device_property_read_u32(dev, propname, &val);
> > +?????? if (ret) {
> > +?????????????? val = default_val;
> > +?????? } else if (val > max || val < min) {
> > +?????????????? dev_warn(dev, "Invalid %s: %u, falling back to: %u\n",
> > +??????????????????????? propname, val, default_val);
> > +
> > +?????????????? val = default_val;
> > +?????? }
> > +
> > +?????? *propval = val;
> > +}
> > +
> > +static void aspeed_peci_property_setup(struct aspeed_peci *priv)
> > +{
> > +?????? aspeed_peci_property_sanitize(priv->dev, "aspeed,clock-divider",
> > +???????????????????????????????????? 0, ASPEED_PECI_CLK_DIV_MAX,
> > +???????????????????????????????????? ASPEED_PECI_CLK_DIV_DEFAULT, &priv-
> > >clk_div);
> > +?????? aspeed_peci_property_sanitize(priv->dev, "aspeed,msg-timing",
> > +???????????????????????????????????? 0, ASPEED_PECI_MSG_TIMING_MAX,
> > +???????????????????????????????????? ASPEED_PECI_MSG_TIMING_DEFAULT, &priv-
> > >msg_timing);
> > +?????? aspeed_peci_property_sanitize(priv->dev, "aspeed,addr-timing",
> > +???????????????????????????????????? 0, ASPEED_PECI_ADDR_TIMING_MAX,
> > +???????????????????????????????????? ASPEED_PECI_ADDR_TIMING_DEFAULT,
> > &priv->addr_timing);
> > +?????? aspeed_peci_property_sanitize(priv->dev, "aspeed,rd-sampling-point",
> > +???????????????????????????????????? 0, ASPEED_PECI_RD_SAMPLING_POINT_MAX,
> > +???????????????????????????????????? ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT,
> > +???????????????????????????????????? &priv->rd_sampling_point);
> > +?????? aspeed_peci_property_sanitize(priv->dev, "cmd-timeout-ms",
> > +???????????????????????????????????? 1, ASPEED_PECI_CMD_TIMEOUT_MS_MAX,
> > +???????????????????????????????????? ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT,
> > &priv->cmd_timeout_ms);
> > +}
> > +
> > +static struct peci_controller_ops aspeed_ops = {
> > +?????? .xfer = aspeed_peci_xfer,
> > +};
> > +
> > +static void aspeed_peci_reset_control_release(void *data)
> > +{
> > +?????? reset_control_assert(data);
> > +}
> > +
> > +int aspeed_peci_reset_control_deassert(struct device *dev, struct
> > reset_control *rst)
> 
> I'd recommend naming this devm_aspeed_peci_reset_control_deassert(),
> because I came looking here from reading probe for why there was no
> reassertion of reset on driver ->remove().

Ok.

> 
> > +{
> > +?????? int ret;
> > +
> > +?????? ret = reset_control_deassert(rst);
> > +?????? if (ret)
> > +?????????????? return ret;
> > +
> > +?????? return devm_add_action_or_reset(dev,
> > aspeed_peci_reset_control_release, rst);
> > +}
> > +
> > +static void aspeed_peci_clk_release(void *data)
> > +{
> > +?????? clk_disable_unprepare(data);
> > +}
> > +
> > +static int aspeed_peci_clk_enable(struct device *dev, struct clk *clk)
> 
> ...ditto on the devm prefix, just to speed readability.

Ok.

Thanks
-Iwona

> 
> > +{
> > +?????? int ret;
> > +
> > +?????? ret = clk_prepare_enable(clk);
> > +?????? if (ret)
> > +?????????????? return ret;
> > +
> > +?????? return devm_add_action_or_reset(dev, aspeed_peci_clk_release, clk);
> > +}
> > +
> > +static int aspeed_peci_probe(struct platform_device *pdev)
> > +{
> > +?????? struct peci_controller *controller;
> > +?????? struct aspeed_peci *priv;
> > +?????? int ret;
> > +
> > +?????? priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> > +?????? if (!priv)
> > +?????????????? return -ENOMEM;
> > +
> > +?????? priv->dev = &pdev->dev;
> > +?????? dev_set_drvdata(priv->dev, priv);
> > +
> > +?????? priv->base = devm_platform_ioremap_resource(pdev, 0);
> > +?????? if (IS_ERR(priv->base))
> > +?????????????? return PTR_ERR(priv->base);
> > +
> > +?????? priv->irq = platform_get_irq(pdev, 0);
> > +?????? if (!priv->irq)
> > +?????????????? return priv->irq;
> > +
> > +?????? ret = devm_request_irq(&pdev->dev, priv->irq,
> > aspeed_peci_irq_handler,
> > +????????????????????????????? 0, "peci-aspeed", priv);
> > +?????? if (ret)
> > +?????????????? return ret;
> > +
> > +?????? init_completion(&priv->xfer_complete);
> > +?????? spin_lock_init(&priv->lock);
> > +
> > +?????? priv->rst = devm_reset_control_get(&pdev->dev, NULL);
> > +?????? if (IS_ERR(priv->rst))
> > +?????????????? return dev_err_probe(priv->dev, PTR_ERR(priv->rst),
> > +??????????????????????????????????? "failed to get reset control\n");
> > +
> > +?????? ret = aspeed_peci_reset_control_deassert(priv->dev, priv->rst);
> > +?????? if (ret)
> > +?????????????? return dev_err_probe(priv->dev, ret, "cannot deassert reset
> > control\n");
> > +
> > +?????? priv->clk = devm_clk_get(priv->dev, NULL);
> > +?????? if (IS_ERR(priv->clk))
> > +?????????????? return dev_err_probe(priv->dev, PTR_ERR(priv->clk), "failed
> > to get clk\n");
> > +
> > +?????? ret = aspeed_peci_clk_enable(priv->dev, priv->clk);
> > +?????? if (ret)
> > +?????????????? return dev_err_probe(priv->dev, ret, "failed to enable
> > clock\n");
> > +
> > +?????? aspeed_peci_property_setup(priv);
> > +
> > +?????? aspeed_peci_init_regs(priv);
> > +
> > +?????? controller = devm_peci_controller_add(priv->dev, &aspeed_ops);
> > +?????? if (IS_ERR(controller))
> > +?????????????? return dev_err_probe(priv->dev, PTR_ERR(controller),
> > +??????????????????????????????????? "failed to add aspeed peci
> > controller\n");
> > +
> > +?????? priv->controller = controller;
> > +
> > +?????? return 0;
> > +}
> > +
> > +static const struct of_device_id aspeed_peci_of_table[] = {
> > +?????? { .compatible = "aspeed,ast2400-peci", },
> > +?????? { .compatible = "aspeed,ast2500-peci", },
> > +?????? { .compatible = "aspeed,ast2600-peci", },
> > +?????? { }
> > +};
> > +MODULE_DEVICE_TABLE(of, aspeed_peci_of_table);
> > +
> > +static struct platform_driver aspeed_peci_driver = {
> > +?????? .probe? = aspeed_peci_probe,
> > +?????? .driver = {
> > +?????????????? .name?????????? = "peci-aspeed",
> > +?????????????? .of_match_table = aspeed_peci_of_table,
> > +?????? },
> > +};
> > +module_platform_driver(aspeed_peci_driver);
> > +
> > +MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
> > +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
> > +MODULE_DESCRIPTION("ASPEED PECI driver");
> > +MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS(PECI);
> > --
> > 2.31.1
> > 


From saravanak at google.com  Thu Aug 26 17:04:16 2021
From: saravanak at google.com (Saravana Kannan)
Date: Thu, 26 Aug 2021 17:04:16 -0700
Subject: [BUG] amba: Remove deferred device addition
In-Reply-To: <df8e7756-8b0d-d7de-a9ff-3f6eb0ffa8a5@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
 <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
 <b5eb935f-26e1-6475-63af-e7f6101eb017@huawei.com>
 <CAGETcx9yaWZOzt=gcyNAshoHdPoYizhmrKS-kU9c2QM2+HqeEw@mail.gmail.com>
 <df8e7756-8b0d-d7de-a9ff-3f6eb0ffa8a5@huawei.com>
Message-ID: <CAGETcx-47yRUcBjEdWFBtroSEkHXRNrJ4zaD8WpE0DPEPp9NxQ@mail.gmail.com>

On Thu, Aug 26, 2021 at 1:22 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
>
> >>> Btw, I've been working on [1] cleaning up the one-off deferred probe
> >>> solution that we have for amba devices. That causes a bunch of other
> >>> headaches. Your patch 3/3 takes us further in the wrong direction by
> >>> adding more reasons for delaying the addition of the device.
>
> Hi Saravana, I try the link[1], but with it, there is a crash when boot
> (qemu-system-arm -M vexpress-a15),

Hi,

It's hard to make sense of the logs. Looks like two different threads
might be printing to the log at the same time? Can you please enable
the config that prints the thread ID (forgot what it's called) and
collect this again? With what I could tell the crash seems to be
happening somewhere in platform_match(), but that's not related to
this patch at all?

-Saravana

>
> without it, boot successfully.
>
> [    2.246057] aaci-pl041 1c040000.aaci: ARM AC'97 Interface PL041 rev0
> at 0x1c040000, irq 36
> [    2.246357] aaci-pl041 1c040000.aaci: FIFO 512 entries
> [    2.248617] NET: Registered PF_PACKET protocol family
> [    2.250481] 9pnet: Installing 9P2000 support
> [    2.251474] Registering SWP/SWPB emulation handler
> [    2.284374] 1c090000.serial: ttyAMA0 at MMIO 0x1c090000 (irq = 41,
> base_baud = 0) is a PL011 rev1
> [    2.287797] printk: console [ttyAMA0] enabled
> [    2.287797] printk: console [ttyAMA0] enabled
> [    2.288262] input: AT Raw Set 2 keyboard as
> /devices/platform/bus at 8000000/bus at 8000000:motherboard-bus/bus at 8000000:motherboard-bus:iofpga-bus at 300000000/1c060000.kmi/serio0/input/input0
> [    2.288262] input: AT Raw Set 2 keyboard as
> /devices/platform/bus at 8000000/bus at 8000000:motherboard-bus/bus at 8000000:motherboard-bus:iofpga-bus at 300000000/1c060000.kmi/serio0/input/input0
> [    2.288755] printk: bootconsole [earlycon0] disabled
> [    2.288755] printk: bootconsole [earlycon0] disabled
> [    2.294507] 1c0a0000.serial: ttyAMA1 at MMIO 0x1c0a0000 (irq = 42,
> base_baud = 0) is a PL011 rev1
> [    2.296950] 1c0b0000.serial: ttyAMA2 at MMIO 0x1c0b0000 (irq = 43,
> base_baud = 0) is a PL011 rev1
> [    2.298636] 1c0c0000.serial: ttyAMA3 at MMIO 0x1c0c0000 (irq = 44,
> base_baud = 0) is a PL011 rev1
> [    2.300496] 8<--- cut here ---
> [    2.300775] ------------[ cut here ]------------
> [    2.301260] Unable to handle kernel NULL pointer dereference at
> virtual address 00000000
> [    2.300928] WARNING: CPU: 1 PID: 27 at
> /home/wkf/work/hulk/lib/refcount.c:25 refcount_warn_saturate+0x108/0x174
> [    2.301700] pgd = (ptrval)
> [    2.302002] refcount_t: addition on 0; use-after-free.
> [    2.302184] [00000000] *pgd=00000000
> [    2.302363] Modules linked in:
> [    2.302384]
> [    2.302753]
> [    2.303501] CPU: 1 PID: 27 Comm: kworker/u4:1 Not tainted 5.14.0-rc7+
> #193
> [    2.303990] Hardware name: ARM-Versatile Express
> [    2.304198] Internal error: Oops: 5 [#1] SMP ARM
> [    2.304537] Workqueue: events_unbound deferred_probe_work_func
> [    2.304829] Modules linked in:
> [    2.304865]
> [    2.305133]
> [    2.305401] Backtrace:
> [    2.305562] CPU: 0 PID: 41 Comm: kworker/0:2 Not tainted 5.14.0-rc7+ #193
> [    2.305614] Hardware name: ARM-Versatile Express
> [    2.305576]
> [    2.305781] [<c010c780>] (dump_backtrace) from [<c010cacc>]
> (show_stack+0x20/0x24)
> [    2.306266] Workqueue: events_long serio_handle_event
> [    2.306732]  r7:00000009 r6:00000000 r5:c0b1efb8 r4:600b0093
> [    2.306889] PC is at strcmp+0x18/0x44
> [    2.307115] [<c010caac>] (show_stack) from [<c091eba4>]
> (dump_stack_lvl+0x48/0x54)
> [    2.307263] LR is at platform_match+0xb8/0xcc
> [    2.307498] [<c091eb5c>] (dump_stack_lvl) from [<c091ebc8>]
> (dump_stack+0x18/0x1c)
> [    2.307739] pc : [<c0560aec>]    lr : [<c064626c>]    psr: 60000013
> [    2.307988]  r5:c0b4ef98 r4:c165ddc4
> [    2.308317] sp : c1675d70  ip : c1675d80  fp : c1675d7c
> [    2.308433] [<c091ebb0>] (dump_stack) from [<c01289c4>]
> (__warn+0x110/0x114)
> [    2.308743] r10: 00000000  r9 : 00000000  r8 : 00000001
> [    2.308961] [<c01288b4>] (__warn) from [<c0128a4c>]
> (warn_slowpath_fmt+0x84/0xc0)
> [    2.309252] r7 : c0d04d08  r6 : c13aed18  r5 : c1090fc0  r4 : c13aed18
> [    2.309547]  r9:00000009 r8:c0504f10 r7:00000019 r6:c0b4ef98
> r5:c0b4efbc r4:c0d04d08
> [    2.309975] [<c01289cc>] (warn_slowpath_fmt) from [<c0504f10>]
> (refcount_warn_saturate+0x108/0x174)
> [    2.310531] r3 : c0a5e1c0  r2 : 00000002  r1 : c0b82860  r0 : 00000000
> [    2.311263] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
> Segment none
> [    2.311298]  r9:600b0013 r8:00000000 r7:00000000 r6:c1787eb8
> r5:c165de3c r4:c1702b38
> [    2.311899] Control: 10c5387d  Table: 8000406a  DAC: 00000051
> [    2.312117] [<c0504e08>] (refcount_warn_saturate) from [<c055657c>]
> (klist_next+0x134/0x138)
> [    2.312755] Register r0 information:
> [    2.312964] [<c0556448>] (klist_next) from [<c06411dc>]
> (bus_for_each_drv+0x74/0xc8)
> [    2.313345]  NULL pointer
> [    2.313690] Register r1 information:
> [    2.313736]  r9:00000000 r8:00000001 r7:c0d04d08 r6:c064373c
> r5:c165de6c r4:00000000
> [    2.313933]  non-slab/vmalloc memory
> [    2.314172] [<c0641168>] (bus_for_each_drv) from [<c0642f38>]
> (__device_attach+0xf0/0x15c)
> [    2.315042]  r7:c10846b8 r6:c13ae444 r5:c13ae400 r4:c0d04d08
> [    2.315060] Register r2 information:
> [    2.315243] [<c0642e48>] (__device_attach) from [<c064390c>]
> (device_initial_probe+0x1c/0x20)
> [    2.315276]  non-paged memory
> [    2.315569]  r8:00000000 r7:c10846b8 r6:c13ae400 r5:c107d690 r4:c13ae400
> [    2.315593] [<c06438f0>] (device_initial_probe) from [<c0642080>]
> (bus_probe_device+0x94/0x9c)
> [    2.316192] [<c0641fec>] (bus_probe_device) from [<c064259c>]
> (deferred_probe_work_func+0x8c/0xb8)
> [    2.316939]  r7:c10846b8 r6:c10846a4 r5:c10846a4 r4:c13ae400
> [    2.317573] [<c0642510>] (deferred_probe_work_func) from [<c01475a4>]
> (process_one_work+0x238/0x594)
> [    2.318513]  r9:00000000 r8:00000000 r7:c1225b00 r6:c1206200
> r5:c16b6f80 r4:c10846d4
> [    2.318931] Register r3 information: non-slab/vmalloc memory
> [    2.319218] [<c014736c>] (process_one_work) from [<c0147bc4>]
> (worker_thread+0x2c4/0x5f4)
> [    2.320001]  r10:c0d03d00 r9:00000088 r8:ffffe000 r7:c1206218
> r6:c16b6f94 r5:c1206200
> [    2.320280] Register r4 information:
> [    2.320614]  r4:c16b6f80
> [    2.320942] [<c0147900>] (worker_thread) from [<c014feb4>]
> (kthread+0x178/0x194)
> [    2.321111]  slab kmalloc-1k
> [    2.321403]  r10:c165c000 r9:c1313e74 r8:00000000 r7:c16b6f80
> r6:c0147900 r5:c16b5580
> [    2.321391]  start c13aec00 pointer offset 280
> [    2.321993]  r4:c13d4980
> [    2.322006]  size 1024
> [    2.322176] [<c014fd3c>] (kthread) from [<c0100150>]
> (ret_from_fork+0x14/0x24)
> [    2.323165] Exception stack(0xc165dfb0 to 0xc165dff8)
> [    2.323187]
> [    2.323371] Register r5 information: non-slab/vmalloc memory
> [    2.323535] Register r6 information: slab kmalloc-1k start c13aec00
> pointer offset 280 size 1024
> [    2.324594] Register r7 information:
> [    2.324597] dfa0:                                     00000000
> 00000000 00000000 00000000
> [    2.325507]  non-slab/vmalloc memory
> [    2.325830] Register r8 information: non-paged memory
> [    2.326267] Register r9 information:
> [    2.326274] dfc0: 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000
> [    2.326453]  NULL pointer
> [    2.326942] Register r10 information: NULL pointer
> [    2.327159] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [    2.327258] Register r11 information: non-slab/vmalloc memory
> [    2.327904] Register r12 information:
> [    2.327928]  r10:00000000 r9:00000000 r8:00000000 r7:00000000
> r6:00000000 r5:c014fd3c
> [    2.327937]  non-slab/vmalloc memory
> [    2.328057] Process kworker/0:2 (pid: 41, stack limit = 0x(ptrval))
> [    2.328204] Stack: (0xc1675d70 to 0xc1676000)
> [    2.328479]  r4:c16b5580
> [    2.329851] ---[ end trace f293b13f591ee203 ]---
> [    2.330027] 5d60:                                     c1675d9c
> c1675d80 c064626c c0560ae0
> [    2.331070] 5d80: c1090fc0 c1675df4 c13aed18 c0d04d08 c1675dbc
> c1675da0 c0643778 c06461c0
> [    2.331120] 8<--- cut here ---
> [    2.331739] Unhandled fault: page domain fault (0x01b) at 0x00000010
> [    2.331915] 5da0: 00000000 c1675df4 c064373c c0d04d08 c1675dec
> c1675dc0 c06411d0 c0643748
> [    2.332379] pgd = (ptrval)
> [    2.332408] 5dc0: c1675dec c16bf06c c1787eb8 76076098 c0d04d08
> c13aed18 c13aed5c c13aa800
> [    2.332889] [00000010] *pgd=00000000
> [    2.332951] 5de0: c1675e24 c1675df0 c0642f38 c0641174 c1675e44
> c13aed18 00000001 76076098
> [    2.333535] 5e00: 00000000 c13aed18 c108ea84 c13aed18 c13aa800
> c10843a0 c1675e34 c1675e28
> [    2.334201] 5e20: c064390c c0642e54 c1675e54 c1675e38 c0642080
> c06438fc c13aed18 00000000
> [    2.334845] 5e40: c0d04d08 c13aa800 c1675eb4 c1675e58 c063fa1c
> c0641ff8 c13a5180 c1706380
> [    2.335464] 5e60: eee2e0c0 c1201180 c071c008 c11ea558 c0b7f260
> c0b7f28c c1675eb4 c1675e88
> [    2.336088] 5e80: c02e6368 76076098 00000001 c1706f4c c13aec00
> c108ea54 c1706f40 c11ea558
> [    2.336758] 5ea0: c0b7f260 c0b7f28c c1675ef4 c1675eb8 c071c0e4
> c063f620 c0923300 c0158300
> [    2.337399] 5ec0: 00000000 c13aed18 c1675ef4 c108ea70 c1702e80
> effc4400 effc7700 00000000
> [    2.338025] 5ee0: 00000000 c10b2580 c1675f34 c1675ef8 c01475a4
> c071bf38 c13a5100 ffffe000
> [    2.338663] 5f00: c1675f1c c1675f10 c0149250 c1702e80 effc4400
> c1702e94 effc4418 ffffe000
> [    2.339296] 5f20: 00000008 c0d03d00 c1675f74 c1675f38 c014795c
> c0147378 c130fe74 c0b0c2c4
> [    2.340102] 5f40: c10b1d2a effc4400 c1675f74 c1706000 c1706880
> c0147900 c1702e80 00000000
> [    2.340736] 5f60: c130fe74 c1674000 c1675fac c1675f78 c014feb4
> c014790c c1706024 c1706024
> [    2.341315] 5f80: c1675fac c1706880 c014fd3c 00000000 00000000
> 00000000 00000000 00000000
> [    2.341852] 5fa0: 00000000 c1675fb0 c0100150 c014fd48 00000000
> 00000000 00000000 00000000
> [    2.342407] 5fc0: 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000
> [    2.342957] 5fe0: 00000000 00000000 00000000 00000000 00000013
> 00000000 00000000 00000000
> [    2.343361] Backtrace:
> [    2.343573] [<c0560ad4>] (strcmp) from [<c064626c>]
> (platform_match+0xb8/0xcc)
> [    2.343954] [<c06461b4>] (platform_match) from [<c0643778>]
> (__device_attach_driver+0x3c/0xc4)
> [    2.344369]  r7:c0d04d08 r6:c13aed18 r5:c1675df4 r4:c1090fc0
> [    2.344615] [<c064373c>] (__device_attach_driver) from [<c06411d0>]
> (bus_for_each_drv+0x68/0xc8)
> [    2.345015]  r7:c0d04d08 r6:c064373c r5:c1675df4 r4:00000000
> [    2.345283] [<c0641168>] (bus_for_each_drv) from [<c0642f38>]
> (__device_attach+0xf0/0x15c)
> [    2.345654]  r7:c13aa800 r6:c13aed5c r5:c13aed18 r4:c0d04d08
> [    2.345903] [<c0642e48>] (__device_attach) from [<c064390c>]
> (device_initial_probe+0x1c/0x20)
> [    2.346325]  r8:c10843a0 r7:c13aa800 r6:c13aed18 r5:c108ea84 r4:c13aed18
> [    2.346635] [<c06438f0>] (device_initial_probe) from [<c0642080>]
> (bus_probe_device+0x94/0x9c)
> [    2.347038] [<c0641fec>] (bus_probe_device) from [<c063fa1c>]
> (device_add+0x408/0x8b8)
> [    2.347419]  r7:c13aa800 r6:c0d04d08 r5:00000000 r4:c13aed18
> [    2.347695] [<c063f614>] (device_add) from [<c071c0e4>]
> (serio_handle_event+0x1b8/0x234)
> [    2.348094]  r10:c0b7f28c r9:c0b7f260 r8:c11ea558 r7:c1706f40
> r6:c108ea54 r5:c13aec00
> [    2.348453]  r4:c1706f4c
> [    2.348604] [<c071bf2c>] (serio_handle_event) from [<c01475a4>]
> (process_one_work+0x238/0x594)
> [    2.348968]  r10:c10b2580 r9:00000000 r8:00000000 r7:effc7700
> r6:effc4400 r5:c1702e80
> [    2.349315]  r4:c108ea70
> [    2.349468] [<c014736c>] (process_one_work) from [<c014795c>]
> (worker_thread+0x5c/0x5f4)
> [    2.349875]  r10:c0d03d00 r9:00000008 r8:ffffe000 r7:effc4418
> r6:c1702e94 r5:effc4400
> [    2.350169]  r4:c1702e80
> [    2.350315] [<c0147900>] (worker_thread) from [<c014feb4>]
> (kthread+0x178/0x194)
> [    2.350687]  r10:c1674000 r9:c130fe74 r8:00000000 r7:c1702e80
> r6:c0147900 r5:c1706880
> [    2.351038]  r4:c1706000
> [    2.351182] [<c014fd3c>] (kthread) from [<c0100150>]
> (ret_from_fork+0x14/0x24)
> [    2.351500] Exception stack(0xc1675fb0 to 0xc1675ff8)
> [    2.351855] 5fa0:                                     00000000
> 00000000 00000000 00000000
> [    2.352415] 5fc0: 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000
> [    2.352923] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [    2.353283]  r10:00000000 r9:00000000 r8:00000000 r7:00000000
> r6:00000000 r5:c014fd3c
> [    2.353618]  r4:c1706880
> [    2.354146] Code: e24cb004 ea000001 e3530000 0a000006 (e4d03001)
> [    2.354860] Internal error: : 1b [#2] SMP ARM
> [    2.355172] Modules linked in:
> [    2.355254] ---[ end trace f293b13f591ee204 ]---
> [    2.355650] CPU: 1 PID: 27 Comm: kworker/u4:1 Tainted: G      D
> W         5.14.0-rc7+ #193
> [    2.355888] Kernel panic - not syncing: Fatal exception
> [    2.355990] Hardware name: ARM-Versatile Express
> [    2.356735] Workqueue: events_unbound deferred_probe_work_func
> [    2.357217] PC is at klist_put+0x20/0xa4
> [    2.357537] LR is at klist_iter_exit+0x24/0x30
> [    2.357872] pc : [<c0556280>]    lr : [<c0556340>]    psr: a00b0013
> [    2.358299] sp : c165de00  ip : c165de20  fp : c165de1c
> [    2.358655] r10: c10b2580  r9 : 00000000  r8 : 00000001
> [    2.359009] r7 : c1702b38  r6 : 00000000  r5 : c165de6c  r4 : 00000000
> [    2.359440] r3 : 00000000  r2 : 76076098  r1 : 00000000  r0 : 00000000
> [    2.359893] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
> Segment none
> [    2.360368] Control: 10c5387d  Table: 8177806a  DAC: 00000051
> [    2.360759] Register r0 information: NULL pointer
> [    2.361126] Register r1 information: NULL pointer
> [    2.361477] Register r2 information: non-paged memory
> [    2.361835] Register r3 information: NULL pointer
> [    2.362162] Register r4 information: NULL pointer
> [    2.362486] Register r5 information: non-slab/vmalloc memory
> [    2.362887] Register r6 information: NULL pointer
> [    2.363226] Register r7 information: slab kmalloc-128 start c1702b00
> pointer offset 56 size 128
> [    2.363919] Register r8 information: non-paged memory
> [    2.364299] Register r9 information: NULL pointer
> [    2.364668] Register r10 information: non-slab/vmalloc memory
> [    2.365089] Register r11 information: non-slab/vmalloc memory
> [    2.365466] Register r12 information: non-slab/vmalloc memory
> [    2.365872] Process kworker/u4:1 (pid: 27, stack limit = 0x(ptrval))
> [    2.366297] Stack: (0xc165de00 to 0xc165e000)
> [    2.366769] de00: c165de3c c165de6c c064373c c0d04d08 c165de34
> c165de20 c0556340 c055626c
> [    2.367478] de20: 00000000 c165de6c c165de64 c165de38 c0641208
> c0556328 c165de64 c136996c
> [    2.368192] de40: c1702b38 76076098 c0d04d08 c13ae400 c13ae444
> c10846b8 c165de9c c165de68
> [    2.368934] de60: c0642f38 c0641174 c063c4c4 c13ae400 00000001
> 76076098 00000000 c13ae400
> [    2.369654] de80: c107d690 c13ae400 c10846b8 00000000 c165deac
> c165dea0 c064390c c0642e54
> [    2.370367] dea0: c165decc c165deb0 c0642080 c06438fc c13ae400
> c10846a4 c10846a4 c10846b8
> [    2.371046] dec0: c165def4 c165ded0 c064259c c0641ff8 c10846d4
> c16b6f80 c1206200 c1225b00
> [    2.371774] dee0: 00000000 00000000 c165df34 c165def8 c01475a4
> c064251c c13906c0 ffffe000
> [    2.372470] df00: c165df1c c165df10 c0149250 c16b6f80 c1206200
> c16b6f94 c1206218 ffffe000
> [    2.373189] df20: 00000088 c0d03d00 c165df74 c165df38 c0147bc4
> c0147378 c1313e74 c0b0c2c4
> [    2.373925] df40: c10b1d2a c1206200 c165df74 c13d4980 c16b5580
> c0147900 c16b6f80 00000000
> [    2.374628] df60: c1313e74 c165c000 c165dfac c165df78 c014feb4
> c014790c c13d49a4 c13d49a4
> [    2.375345] df80: c165dfac c16b5580 c014fd3c 00000000 00000000
> 00000000 00000000 00000000
> [    2.376080] dfa0: 00000000 c165dfb0 c0100150 c014fd48 00000000
> 00000000 00000000 00000000
> [    2.376807] dfc0: 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000
> [    2.377534] dfe0: 00000000 00000000 00000000 00000000 00000013
> 00000000 00000000 00000000
> [    2.378080] Backtrace:
> [    2.378297] [<c0556260>] (klist_put) from [<c0556340>]
> (klist_iter_exit+0x24/0x30)
> [    2.378819]  r7:c0d04d08 r6:c064373c r5:c165de6c r4:c165de3c
> [    2.379199] [<c055631c>] (klist_iter_exit) from [<c0641208>]
> (bus_for_each_drv+0xa0/0xc8)
> [    2.379701]  r5:c165de6c r4:00000000
> [    2.379932] [<c0641168>] (bus_for_each_drv) from [<c0642f38>]
> (__device_attach+0xf0/0x15c)
> [    2.380482]  r7:c10846b8 r6:c13ae444 r5:c13ae400 r4:c0d04d08
> [    2.380871] [<c0642e48>] (__device_attach) from [<c064390c>]
> (device_initial_probe+0x1c/0x20)
> [    2.381453]  r8:00000000 r7:c10846b8 r6:c13ae400 r5:c107d690 r4:c13ae400
> [    2.381851] [<c06438f0>] (device_initial_probe) from [<c0642080>]
> (bus_probe_device+0x94/0x9c)
> [    2.382364] [<c0641fec>] (bus_probe_device) from [<c064259c>]
> (deferred_probe_work_func+0x8c/0xb8)
> [    2.382936]  r7:c10846b8 r6:c10846a4 r5:c10846a4 r4:c13ae400
> [    2.383266] [<c0642510>] (deferred_probe_work_func) from [<c01475a4>]
> (process_one_work+0x238/0x594)
> [    2.383885]  r9:00000000 r8:00000000 r7:c1225b00 r6:c1206200
> r5:c16b6f80 r4:c10846d4
> [    2.384344] [<c014736c>] (process_one_work) from [<c0147bc4>]
> (worker_thread+0x2c4/0x5f4)
> [    2.384893]  r10:c0d03d00 r9:00000088 r8:ffffe000 r7:c1206218
> r6:c16b6f94 r5:c1206200
> [    2.385341]  r4:c16b6f80
> [    2.385536] [<c0147900>] (worker_thread) from [<c014feb4>]
> (kthread+0x178/0x194)
> [    2.386030]  r10:c165c000 r9:c1313e74 r8:00000000 r7:c16b6f80
> r6:c0147900 r5:c16b5580
> [    2.386540]  r4:c13d4980
> [    2.386742] [<c014fd3c>] (kthread) from [<c0100150>]
> (ret_from_fork+0x14/0x24)
> [    2.387211] Exception stack(0xc165dfb0 to 0xc165dff8)
> [    2.387653] dfa0:                                     00000000
> 00000000 00000000 00000000
> [    2.388374] dfc0: 00000000 00000000 00000000 00000000 00000000
> 00000000 00000000 00000000
> [    2.389071] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [    2.389546]  r10:00000000 r9:00000000 r8:00000000 r7:00000000
> r6:00000000 r5:c014fd3c
> [    2.390037]  r4:c16b5580
> [    2.390376] Code: e1a07000 e1a06001 e3c44001 e1a00004 (e5945010)
> [    2.390836] ---[ end trace f293b13f591ee205 ]---
> [    2.391580] ---[ end Kernel panic - not syncing: Fatal exception ]---
>
>
> >>> -Saravana
> >>>
> >>> [1] - https://lore.kernel.org/lkml/CAGETcx8b228nDUho3cX9AAQ-pXOfZTMv8cj2vhdx9yc_pk8q+A at mail.gmail.com/
> >>> .
> >>>
> > .
> >


From seanjc at google.com  Thu Aug 26 17:57:03 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:03 -0700
Subject: [PATCH 00/15] perf: KVM: Fix, optimize, and clean up callbacks
Message-ID: <20210827005718.585190-1-seanjc@google.com>

This started out as a small series[1] to fix a KVM bug related to Intel PT
interrupt handling and snowballed horribly.

The main problem being addressed is that the perf_guest_cbs are shared by
all CPUs, can be nullified by KVM during module unload, and are not
protected against concurrent access from NMI context.

The bug has escaped notice because all dereferences of perf_guest_cbs
follow the same "perf_guest_cbs && perf_guest_cbs->is_in_guest()" pattern,
and AFAICT the compiler never reloads perf_guest_cbs in this sequence.
The compiler does reload perf_guest_cbs for any future dereferences, but
the ->is_in_guest() guard all but guarantees the PMI handler will win the
race, e.g. to nullify perf_guest_cbs, KVM has to completely exit the guest
and teardown down all VMs before it can be unloaded.

But with help, e.g. READ_ONCE(perf_guest_cbs), unloading kvm_intel can
trigger a NULL pointer derference (see below).  Manual intervention aside,
the bug is a bit of a time bomb, e.g. my patch 3 from the original PT
handling series would have omitted the ->is_in_guest() guard.

This series fixes the problem by making the callbacks per-CPU, and
registering/unregistering the callbacks only with preemption disabled
(except for the Xen case, which doesn't unregister).

This approach also allows for several nice cleanups in this series.
KVM x86 and arm64 can share callbacks, KVM x86 drops its somewhat
redundant current_vcpu, and the retpoline that is currently hit when KVM
is loaded (due to always checking ->is_in_guest()) goes away (it's still
there when running as Xen Dom0).

Changing to per-CPU callbacks also provides a good excuse to excise
copy+paste code from architectures that can't possibly have guest
callbacks.

This series conflicts horribly with a proposed patch[2] to use static
calls for perf_guest_cbs.  But that patch is broken as it completely
fails to handle unregister, and it's not clear to me whether or not
it can correctly handle unregister without fixing the underlying race
(I don't know enough about the code patching for static calls).

This tweak

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 1eb45139fcc6..202e5ad97f82 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2954,7 +2954,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
 {
        int misc = 0;

-       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+       if (READ_ONCE(perf_guest_cbs) && READ_ONCE(perf_guest_cbs)->is_in_guest()) {
                if (perf_guest_cbs->is_user_mode())
                        misc |= PERF_RECORD_MISC_GUEST_USER;
                else

while spamming module load/unload leads to:

  BUG: kernel NULL pointer dereference, address: 0000000000000000
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: 0000 [#1] PREEMPT SMP
  CPU: 6 PID: 1825 Comm: stress Not tainted 5.14.0-rc2+ #459
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:perf_misc_flags+0x1c/0x70
  Call Trace:
   perf_prepare_sample+0x53/0x6b0
   perf_event_output_forward+0x67/0x160
   __perf_event_overflow+0x52/0xf0
   handle_pmi_common+0x207/0x300
   intel_pmu_handle_irq+0xcf/0x410
   perf_event_nmi_handler+0x28/0x50
   nmi_handle+0xc7/0x260
   default_do_nmi+0x6b/0x170
   exc_nmi+0x103/0x130
   asm_exc_nmi+0x76/0xbf

[1] https://lkml.kernel.org/r/20210823193709.55886-1-seanjc at google.com
[2] https://lkml.kernel.org/r/20210806133802.3528-2-lingshan.zhu at intel.com

Sean Christopherson (15):
  KVM: x86: Register perf callbacks after calling vendor's
    hardware_setup()
  KVM: x86: Register Processor Trace interrupt hook iff PT enabled in
    guest
  perf: Stop pretending that perf can handle multiple guest callbacks
  perf: Force architectures to opt-in to guest callbacks
  perf: Track guest callbacks on a per-CPU basis
  KVM: x86: Register perf callbacks only when actively handling
    interrupt
  KVM: Use dedicated flag to track if KVM is handling an NMI from guest
  KVM: x86: Drop current_vcpu in favor of kvm_running_vcpu
  KVM: arm64: Register/unregister perf callbacks at vcpu load/put
  KVM: Move x86's perf guest info callbacks to generic KVM
  KVM: x86: Move Intel Processor Trace interrupt handler to vmx.c
  KVM: arm64: Convert to the generic perf callbacks
  KVM: arm64: Drop perf.c and fold its tiny bit of code into pmu.c
  perf: Disallow bulk unregistering of guest callbacks and do cleanup
  perf: KVM: Indicate "in guest" via NULL ->is_in_guest callback

 arch/arm/kernel/perf_callchain.c   | 28 ++------------
 arch/arm64/Kconfig                 |  1 +
 arch/arm64/include/asm/kvm_host.h  |  8 +++-
 arch/arm64/kernel/perf_callchain.c | 18 ++++++---
 arch/arm64/kvm/Makefile            |  2 +-
 arch/arm64/kvm/arm.c               | 13 ++++++-
 arch/arm64/kvm/perf.c              | 62 ------------------------------
 arch/arm64/kvm/pmu.c               |  8 ++++
 arch/csky/kernel/perf_callchain.c  | 10 -----
 arch/nds32/kernel/perf_event_cpu.c | 29 ++------------
 arch/riscv/kernel/perf_callchain.c | 10 -----
 arch/x86/Kconfig                   |  1 +
 arch/x86/events/core.c             | 17 +++++---
 arch/x86/events/intel/core.c       |  7 ++--
 arch/x86/include/asm/kvm_host.h    |  4 +-
 arch/x86/kvm/pmu.c                 |  2 +-
 arch/x86/kvm/pmu.h                 |  1 +
 arch/x86/kvm/svm/svm.c             |  2 +-
 arch/x86/kvm/vmx/vmx.c             | 25 ++++++++++--
 arch/x86/kvm/x86.c                 | 54 +++-----------------------
 arch/x86/kvm/x86.h                 | 12 +++---
 arch/x86/xen/pmu.c                 |  2 +-
 include/kvm/arm_pmu.h              |  1 +
 include/linux/kvm_host.h           | 12 ++++++
 include/linux/perf_event.h         | 33 ++++++++++++----
 init/Kconfig                       |  3 ++
 kernel/events/core.c               | 28 ++++++++------
 virt/kvm/kvm_main.c                | 42 ++++++++++++++++++++
 28 files changed, 204 insertions(+), 231 deletions(-)
 delete mode 100644 arch/arm64/kvm/perf.c

-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:04 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:04 -0700
Subject: [PATCH 01/15] KVM: x86: Register perf callbacks after calling
 vendor's hardware_setup()
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-2-seanjc@google.com>

Wait to register perf callbacks until after doing vendor hardaware setup.
VMX's hardware_setup() configures Intel Processor Trace (PT) mode, and a
future fix to register the Intel PT guest interrupt hook if and only if
Intel PT is exposed to the guest will consume the configured PT mode.

Delaying registration to hardware setup is effectively a nop as KVM's perf
hooks all pivot on the per-CPU current_vcpu, which is non-NULL only when
KVM is handling an IRQ/NMI in a VM-Exit path.  I.e. current_vcpu will be
NULL throughout both kvm_arch_init() and kvm_arch_hardware_setup().

Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Artem Kashkanov <artem.kashkanov at intel.com>
Cc: stable at vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/kvm/x86.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 86539c1686fa..fb6015f97f9e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8426,8 +8426,6 @@ int kvm_arch_init(void *opaque)
 
 	kvm_timer_init();
 
-	perf_register_guest_info_callbacks(&kvm_guest_cbs);
-
 	if (boot_cpu_has(X86_FEATURE_XSAVE)) {
 		host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
 		supported_xcr0 = host_xcr0 & KVM_SUPPORTED_XCR0;
@@ -8461,7 +8459,6 @@ void kvm_arch_exit(void)
 		clear_hv_tscchange_cb();
 #endif
 	kvm_lapic_exit();
-	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
 
 	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
 		cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
@@ -11064,6 +11061,8 @@ int kvm_arch_hardware_setup(void *opaque)
 	memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
 	kvm_ops_static_call_update();
 
+	perf_register_guest_info_callbacks(&kvm_guest_cbs);
+
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
 		supported_xss = 0;
 
@@ -11091,6 +11090,8 @@ int kvm_arch_hardware_setup(void *opaque)
 
 void kvm_arch_hardware_unsetup(void)
 {
+	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+
 	static_call(kvm_x86_hardware_unsetup)();
 }
 
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:05 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:05 -0700
Subject: [PATCH 02/15] KVM: x86: Register Processor Trace interrupt hook iff
 PT enabled in guest
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-3-seanjc@google.com>

Override the Processor Trace (PT) interrupt handler for guest mode if and
only if PT is configured for host+guest mode, i.e. is being used
independently by both host and guest.  If PT is configured for system
mode, the host fully controls PT and must handle all events.

Fixes: 8479e04e7d6b ("KVM: x86: Inject PMI for KVM guest")
Cc: stable at vger.kernel.org
Cc: Like Xu <like.xu.linux at gmail.com>
Reported-by: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Reported-by: Artem Kashkanov <artem.kashkanov at intel.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/include/asm/kvm_host.h | 1 +
 arch/x86/kvm/pmu.h              | 1 +
 arch/x86/kvm/vmx/vmx.c          | 1 +
 arch/x86/kvm/x86.c              | 5 ++++-
 4 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 09b256db394a..1ea4943a73d7 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1494,6 +1494,7 @@ struct kvm_x86_init_ops {
 	int (*disabled_by_bios)(void);
 	int (*check_processor_compatibility)(void);
 	int (*hardware_setup)(void);
+	bool (*intel_pt_intr_in_guest)(void);
 
 	struct kvm_x86_ops *runtime_ops;
 };
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 0e4f2b1fa9fb..b06dbbd7eeeb 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -41,6 +41,7 @@ struct kvm_pmu_ops {
 	void (*reset)(struct kvm_vcpu *vcpu);
 	void (*deliver_pmi)(struct kvm_vcpu *vcpu);
 	void (*cleanup)(struct kvm_vcpu *vcpu);
+	void (*handle_intel_pt_intr)(void);
 };
 
 static inline u64 pmc_bitmask(struct kvm_pmc *pmc)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index fada1055f325..f19d72136f77 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7896,6 +7896,7 @@ static struct kvm_x86_init_ops vmx_init_ops __initdata = {
 	.disabled_by_bios = vmx_disabled_by_bios,
 	.check_processor_compatibility = vmx_check_processor_compat,
 	.hardware_setup = hardware_setup,
+	.intel_pt_intr_in_guest = vmx_pt_mode_is_host_guest,
 
 	.runtime_ops = &vmx_x86_ops,
 };
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fb6015f97f9e..ffc6c2d73508 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8305,7 +8305,7 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
 	.is_in_guest		= kvm_is_in_guest,
 	.is_user_mode		= kvm_is_user_mode,
 	.get_guest_ip		= kvm_get_guest_ip,
-	.handle_intel_pt_intr	= kvm_handle_intel_pt_intr,
+	.handle_intel_pt_intr	= NULL,
 };
 
 #ifdef CONFIG_X86_64
@@ -11061,6 +11061,8 @@ int kvm_arch_hardware_setup(void *opaque)
 	memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
 	kvm_ops_static_call_update();
 
+	if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest())
+		kvm_guest_cbs.handle_intel_pt_intr = kvm_handle_intel_pt_intr;
 	perf_register_guest_info_callbacks(&kvm_guest_cbs);
 
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
@@ -11091,6 +11093,7 @@ int kvm_arch_hardware_setup(void *opaque)
 void kvm_arch_hardware_unsetup(void)
 {
 	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+	kvm_guest_cbs.handle_intel_pt_intr = NULL;
 
 	static_call(kvm_x86_hardware_unsetup)();
 }
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:06 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:06 -0700
Subject: [PATCH 03/15] perf: Stop pretending that perf can handle multiple
 guest callbacks
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-4-seanjc@google.com>

Drop the 'int' return value from the perf (un)register callbacks helpers
and stop pretending perf can support multiple callbacks.  The 'int'
returns are not future proofing anything as none of the callers take
action on an error.  It's also not obvious that there will ever be
cotenant hypervisors, and if there are, that allowing multiple callbacks
to be registered is desirable or even correct.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  4 ++--
 arch/arm64/kvm/perf.c             |  8 ++++----
 arch/x86/kvm/x86.c                |  2 +-
 include/linux/perf_event.h        | 11 +++++------
 kernel/events/core.c              | 11 ++---------
 5 files changed, 14 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 41911585ae0c..ed940aec89e0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -670,8 +670,8 @@ unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
 int kvm_handle_mmio_return(struct kvm_vcpu *vcpu);
 int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
 
-int kvm_perf_init(void);
-int kvm_perf_teardown(void);
+void kvm_perf_init(void);
+void kvm_perf_teardown(void);
 
 long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
 gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 151c31fb9860..039fe59399a2 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -48,15 +48,15 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
 	.get_guest_ip	= kvm_get_guest_ip,
 };
 
-int kvm_perf_init(void)
+void kvm_perf_init(void)
 {
 	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
 		static_branch_enable(&kvm_arm_pmu_available);
 
-	return perf_register_guest_info_callbacks(&kvm_guest_cbs);
+	perf_register_guest_info_callbacks(&kvm_guest_cbs);
 }
 
-int kvm_perf_teardown(void)
+void kvm_perf_teardown(void)
 {
-	return perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+	perf_unregister_guest_info_callbacks();
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ffc6c2d73508..bae951344e28 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -11092,7 +11092,7 @@ int kvm_arch_hardware_setup(void *opaque)
 
 void kvm_arch_hardware_unsetup(void)
 {
-	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+	perf_unregister_guest_info_callbacks();
 	kvm_guest_cbs.handle_intel_pt_intr = NULL;
 
 	static_call(kvm_x86_hardware_unsetup)();
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2d510ad750ed..05c0efba3cd1 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1237,8 +1237,8 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 				 u16 flags);
 
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
-extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
-extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+extern void perf_unregister_guest_info_callbacks(void);
 
 extern void perf_event_exec(void);
 extern void perf_event_comm(struct task_struct *tsk, bool exec);
@@ -1481,10 +1481,9 @@ perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr)	{ }
 static inline void
 perf_bp_event(struct perf_event *event, void *data)			{ }
 
-static inline int perf_register_guest_info_callbacks
-(struct perf_guest_info_callbacks *callbacks)				{ return 0; }
-static inline int perf_unregister_guest_info_callbacks
-(struct perf_guest_info_callbacks *callbacks)				{ return 0; }
+static inline void perf_register_guest_info_callbacks
+(struct perf_guest_info_callbacks *callbacks)				{ }
+static inline void perf_unregister_guest_info_callbacks(void)		{ }
 
 static inline void perf_event_mmap(struct vm_area_struct *vma)		{ }
 
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 464917096e73..baae796612b9 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6482,24 +6482,17 @@ static void perf_pending_event(struct irq_work *entry)
 		perf_swevent_put_recursion_context(rctx);
 }
 
-/*
- * We assume there is only KVM supporting the callbacks.
- * Later on, we might change it to a list if there is
- * another virtualization implementation supporting the callbacks.
- */
 struct perf_guest_info_callbacks *perf_guest_cbs;
 
-int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
 	perf_guest_cbs = cbs;
-	return 0;
 }
 EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
 
-int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+void perf_unregister_guest_info_callbacks(void)
 {
 	perf_guest_cbs = NULL;
-	return 0;
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
 
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:07 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:07 -0700
Subject: [PATCH 04/15] perf: Force architectures to opt-in to guest callbacks
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-5-seanjc@google.com>

Introduce HAVE_GUEST_PERF_EVENTS and require architectures to select it
to allow register guest callbacks in perf.  Future patches will convert
the callbacks to per-CPU definitions.  Rather than churn a bunch of arch
code (that was presumably copy+pasted from x86), remove it wholesale as
it's useless and at best wasting cycles.

Wrap even the stubs with an #ifdef to avoid an arch sneaking in a bogus
registration with CONFIG_PERF_EVENTS=n.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm/kernel/perf_callchain.c   | 28 ++++------------------------
 arch/arm64/Kconfig                 |  1 +
 arch/csky/kernel/perf_callchain.c  | 10 ----------
 arch/nds32/kernel/perf_event_cpu.c | 29 ++++-------------------------
 arch/riscv/kernel/perf_callchain.c | 10 ----------
 arch/x86/Kconfig                   |  1 +
 include/linux/perf_event.h         |  4 ++++
 init/Kconfig                       |  3 +++
 kernel/events/core.c               |  2 ++
 9 files changed, 19 insertions(+), 69 deletions(-)

diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c
index 3b69a76d341e..bc6b246ab55e 100644
--- a/arch/arm/kernel/perf_callchain.c
+++ b/arch/arm/kernel/perf_callchain.c
@@ -64,11 +64,6 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 {
 	struct frame_tail __user *tail;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		/* We don't support guest os callchain now */
-		return;
-	}
-
 	perf_callchain_store(entry, regs->ARM_pc);
 
 	if (!current->mm)
@@ -100,20 +95,12 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
 {
 	struct stackframe fr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		/* We don't support guest os callchain now */
-		return;
-	}
-
 	arm_get_current_stackframe(regs, &fr);
 	walk_stackframe(&fr, callchain_trace, entry);
 }
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
-
 	return instruction_pointer(regs);
 }
 
@@ -121,17 +108,10 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
 {
 	int misc = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
-			misc |= PERF_RECORD_MISC_GUEST_USER;
-		else
-			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
-	} else {
-		if (user_mode(regs))
-			misc |= PERF_RECORD_MISC_USER;
-		else
-			misc |= PERF_RECORD_MISC_KERNEL;
-	}
+	if (user_mode(regs))
+		misc |= PERF_RECORD_MISC_USER;
+	else
+		misc |= PERF_RECORD_MISC_KERNEL;
 
 	return misc;
 }
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5b13a932561..72a201a686c5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -190,6 +190,7 @@ config ARM64
 	select HAVE_NMI
 	select HAVE_PATA_PLATFORM
 	select HAVE_PERF_EVENTS
+	select HAVE_GUEST_PERF_EVENTS
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_REGS_AND_STACK_ACCESS_API
diff --git a/arch/csky/kernel/perf_callchain.c b/arch/csky/kernel/perf_callchain.c
index ab55e98ee8f6..92057de08f4f 100644
--- a/arch/csky/kernel/perf_callchain.c
+++ b/arch/csky/kernel/perf_callchain.c
@@ -88,10 +88,6 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 {
 	unsigned long fp = 0;
 
-	/* C-SKY does not support virtualization. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return;
-
 	fp = regs->regs[4];
 	perf_callchain_store(entry, regs->pc);
 
@@ -112,12 +108,6 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 {
 	struct stackframe fr;
 
-	/* C-SKY does not support virtualization. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		pr_warn("C-SKY does not support perf in guest mode!");
-		return;
-	}
-
 	fr.fp = regs->regs[4];
 	fr.lr = regs->lr;
 	walk_stackframe(&fr, entry);
diff --git a/arch/nds32/kernel/perf_event_cpu.c b/arch/nds32/kernel/perf_event_cpu.c
index 0ce6f9f307e6..a78a879e7ef1 100644
--- a/arch/nds32/kernel/perf_event_cpu.c
+++ b/arch/nds32/kernel/perf_event_cpu.c
@@ -1371,11 +1371,6 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 
 	leaf_fp = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		/* We don't support guest os callchain now */
-		return;
-	}
-
 	perf_callchain_store(entry, regs->ipc);
 	fp = regs->fp;
 	gp = regs->gp;
@@ -1481,10 +1476,6 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 {
 	struct stackframe fr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		/* We don't support guest os callchain now */
-		return;
-	}
 	fr.fp = regs->fp;
 	fr.lp = regs->lp;
 	fr.sp = regs->sp;
@@ -1493,10 +1484,6 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	/* However, NDS32 does not support virtualization */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
-
 	return instruction_pointer(regs);
 }
 
@@ -1504,18 +1491,10 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
 {
 	int misc = 0;
 
-	/* However, NDS32 does not support virtualization */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
-			misc |= PERF_RECORD_MISC_GUEST_USER;
-		else
-			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
-	} else {
-		if (user_mode(regs))
-			misc |= PERF_RECORD_MISC_USER;
-		else
-			misc |= PERF_RECORD_MISC_KERNEL;
-	}
+	if (user_mode(regs))
+		misc |= PERF_RECORD_MISC_USER;
+	else
+		misc |= PERF_RECORD_MISC_KERNEL;
 
 	return misc;
 }
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
index 0bb1854dce83..1fc075b8f764 100644
--- a/arch/riscv/kernel/perf_callchain.c
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -58,10 +58,6 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 {
 	unsigned long fp = 0;
 
-	/* RISC-V does not support perf in guest mode. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return;
-
 	fp = regs->s0;
 	perf_callchain_store(entry, regs->epc);
 
@@ -78,11 +74,5 @@ static bool fill_callchain(void *entry, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
-	/* RISC-V does not support perf in guest mode. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		pr_warn("RISC-V does not support perf in guest mode!");
-		return;
-	}
-
 	walk_stackframe(NULL, regs, fill_callchain, entry);
 }
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 49270655e827..a4de4aa7a3df 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -229,6 +229,7 @@ config X86
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_EVENTS_NMI
 	select HAVE_HARDLOCKUP_DETECTOR_PERF	if PERF_EVENTS && HAVE_PERF_EVENTS_NMI
+	select HAVE_GUEST_PERF_EVENTS
 	select HAVE_PCI
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 05c0efba3cd1..5eab690622ca 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1236,9 +1236,11 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 				 enum perf_bpf_event_type type,
 				 u16 flags);
 
+#ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
 extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 extern void perf_unregister_guest_info_callbacks(void);
+#endif /* CONFIG_HAVE_GUEST_PERF_EVENTS */
 
 extern void perf_event_exec(void);
 extern void perf_event_comm(struct task_struct *tsk, bool exec);
@@ -1481,9 +1483,11 @@ perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr)	{ }
 static inline void
 perf_bp_event(struct perf_event *event, void *data)			{ }
 
+#ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 static inline void perf_register_guest_info_callbacks
 (struct perf_guest_info_callbacks *callbacks)				{ }
 static inline void perf_unregister_guest_info_callbacks(void)		{ }
+#endif
 
 static inline void perf_event_mmap(struct vm_area_struct *vma)		{ }
 
diff --git a/init/Kconfig b/init/Kconfig
index 55f9f7738ebb..9ef51ae53977 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1776,6 +1776,9 @@ config HAVE_PERF_EVENTS
 	help
 	  See tools/perf/design.txt for details.
 
+config HAVE_GUEST_PERF_EVENTS
+	bool
+
 config PERF_USE_VMALLOC
 	bool
 	help
diff --git a/kernel/events/core.c b/kernel/events/core.c
index baae796612b9..9820df7ee455 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6482,6 +6482,7 @@ static void perf_pending_event(struct irq_work *entry)
 		perf_swevent_put_recursion_context(rctx);
 }
 
+#ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 struct perf_guest_info_callbacks *perf_guest_cbs;
 
 void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
@@ -6495,6 +6496,7 @@ void perf_unregister_guest_info_callbacks(void)
 	perf_guest_cbs = NULL;
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
+#endif
 
 static void
 perf_output_sample_regs(struct perf_output_handle *handle,
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:08 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:08 -0700
Subject: [PATCH 05/15] perf: Track guest callbacks on a per-CPU basis
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-6-seanjc@google.com>

Use a per-CPU pointer to track perf's guest callbacks so that KVM can set
the callbacks more precisely and avoid a lurking NULL pointer dereference.
On x86, KVM supports being built as a module and thus can be unloaded.
And because the shared callbacks are referenced from IRQ/NMI context,
unloading KVM can run concurrently with perf, and thus all of perf's
checks for a NULL perf_guest_cbs are flawed as perf_guest_cbs could be
nullified between the check and dereference.

In practice, this has not been problematic because the callbacks are
always guarded with a "perf_guest_cbs && perf_guest_cbs->is_in_guest()"
pattern, and it's extremely unlikely the compiler will choost to reload
perf_guest_cbs in that particular sequence.  Because is_in_guest() is
obviously true only when KVM is running a guest, perf always wins the
race to the guarded code (which does often reload perf_guest_cbs) as KVM
has to stop running all guests and do a heavy teardown before unloading.

Cc: Zhu Lingshan <lingshan.zhu at intel.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/kernel/perf_callchain.c | 18 ++++++++++++------
 arch/x86/events/core.c             | 17 +++++++++++------
 arch/x86/events/intel/core.c       |  8 +++++---
 include/linux/perf_event.h         |  2 +-
 kernel/events/core.c               | 12 +++++++++---
 5 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 4a72c2727309..38555275c6a2 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -102,7 +102,9 @@ compat_user_backtrace(struct compat_frame_tail __user *tail,
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
+
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -147,9 +149,10 @@ static bool callchain_trace(void *data, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
 	struct stackframe frame;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -160,18 +163,21 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
+
+	if (guest_cbs && guest_cbs->is_in_guest())
+		return guest_cbs->get_guest_ip();
 
 	return instruction_pointer(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
 	int misc = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (guest_cbs && guest_cbs->is_in_guest()) {
+		if (guest_cbs->is_user_mode())
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 1eb45139fcc6..34155a52e498 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2761,10 +2761,11 @@ static bool perf_hw_regs(struct pt_regs *regs)
 void
 perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
 	struct unwind_state state;
 	unsigned long addr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2864,10 +2865,11 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
 void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
 	struct stack_frame frame;
 	const struct stack_frame __user *fp;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2944,18 +2946,21 @@ static unsigned long code_segment_base(struct pt_regs *regs)
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
+
+	if (guest_cbs && guest_cbs->is_in_guest())
+		return guest_cbs->get_guest_ip();
 
 	return regs->ip + code_segment_base(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
 	int misc = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (guest_cbs && guest_cbs->is_in_guest()) {
+		if (guest_cbs->is_user_mode())
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index fca7a6e2242f..96001962c24d 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2784,6 +2784,7 @@ static void intel_pmu_reset(void)
 
 static int handle_pmi_common(struct pt_regs *regs, u64 status)
 {
+	struct perf_guest_info_callbacks *guest_cbs;
 	struct perf_sample_data data;
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 	int bit;
@@ -2852,9 +2853,10 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
 	 */
 	if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) {
 		handled++;
-		if (unlikely(perf_guest_cbs && perf_guest_cbs->is_in_guest() &&
-			perf_guest_cbs->handle_intel_pt_intr))
-			perf_guest_cbs->handle_intel_pt_intr();
+		guest_cbs = this_cpu_read(perf_guest_cbs);
+		if (unlikely(guest_cbs && guest_cbs->is_in_guest() &&
+			     guest_cbs->handle_intel_pt_intr))
+			guest_cbs->handle_intel_pt_intr();
 		else
 			intel_pt_interrupt();
 	}
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 5eab690622ca..c98253dae037 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1237,7 +1237,7 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 				 u16 flags);
 
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
-extern struct perf_guest_info_callbacks *perf_guest_cbs;
+DECLARE_PER_CPU(struct perf_guest_info_callbacks *, perf_guest_cbs);
 extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 extern void perf_unregister_guest_info_callbacks(void);
 #endif /* CONFIG_HAVE_GUEST_PERF_EVENTS */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 9820df7ee455..9bc1375d6ed9 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6483,17 +6483,23 @@ static void perf_pending_event(struct irq_work *entry)
 }
 
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
-struct perf_guest_info_callbacks *perf_guest_cbs;
+DEFINE_PER_CPU(struct perf_guest_info_callbacks *, perf_guest_cbs);
 
 void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
-	perf_guest_cbs = cbs;
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		per_cpu(perf_guest_cbs, cpu) = cbs;
 }
 EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
 
 void perf_unregister_guest_info_callbacks(void)
 {
-	perf_guest_cbs = NULL;
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		per_cpu(perf_guest_cbs, cpu) = NULL;
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
 #endif
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:10 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:10 -0700
Subject: [PATCH 07/15] KVM: Use dedicated flag to track if KVM is handling an
 NMI from guest
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-8-seanjc@google.com>

Add a dedicated flag to detect the case where KVM's PMC overflow
callback was originally invoked in response to an NMI that arrived while
the guest was running.  Using current_vcpu is less precise as IRQs also
set current_vcpu (though presumably KVM's callback should not be reached
in that case), and more importantly, this will allow dropping
current_vcpu as the perf callbacks can switch to kvm_running_vcpu now
that the perf callbacks are precisely registered, i.e. kvm_running_vcpu
doesn't need to be used to detect if a PMI arrived in the guest.

Fixes: dd60d217062f ("KVM: x86: Fix perf timer mode IP reporting")
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/include/asm/kvm_host.h | 3 +--
 arch/x86/kvm/pmu.c              | 2 +-
 arch/x86/kvm/svm/svm.c          | 2 +-
 arch/x86/kvm/vmx/vmx.c          | 2 +-
 arch/x86/kvm/x86.c              | 4 ++--
 arch/x86/kvm/x86.h              | 4 +++-
 6 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 1ea4943a73d7..465b35736d9b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -763,6 +763,7 @@ struct kvm_vcpu_arch {
 	unsigned nmi_pending; /* NMI queued after currently running handler */
 	bool nmi_injected;    /* Trying to inject an NMI this entry */
 	bool smi_pending;    /* SMI queued after currently running handler */
+	bool handling_nmi_from_guest;
 
 	struct kvm_mtrr mtrr_state;
 	u64 pat;
@@ -1874,8 +1875,6 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu);
 int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
 void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu);
 
-int kvm_is_in_guest(void);
-
 void __user *__x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa,
 				     u32 size);
 bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 0772bad9165c..2b8934b452ea 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -87,7 +87,7 @@ static void kvm_perf_overflow_intr(struct perf_event *perf_event,
 		 * woken up. So we should wake it, but this is impossible from
 		 * NMI context. Do it from irq work instead.
 		 */
-		if (!kvm_is_in_guest())
+		if (!pmc->vcpu->arch.handling_nmi_from_guest)
 			irq_work_queue(&pmc_to_pmu(pmc)->irq_work);
 		else
 			kvm_make_request(KVM_REQ_PMI, pmc->vcpu);
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 1a70e11f0487..3fc6767e5fd8 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3843,7 +3843,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
 	}
 
 	if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI))
-		kvm_before_interrupt(vcpu);
+		kvm_before_interrupt(vcpu, true);
 
 	kvm_load_host_xsave_state(vcpu);
 	stgi();
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index f19d72136f77..f08980ef7c44 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6344,7 +6344,7 @@ void vmx_do_interrupt_nmi_irqoff(unsigned long entry);
 static void handle_interrupt_nmi_irqoff(struct kvm_vcpu *vcpu,
 					unsigned long entry)
 {
-	kvm_before_interrupt(vcpu);
+	kvm_before_interrupt(vcpu, entry == (unsigned long)asm_exc_nmi_noist);
 	vmx_do_interrupt_nmi_irqoff(entry);
 	kvm_after_interrupt(vcpu);
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bc4ee6ea7752..d4d91944fde7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8267,7 +8267,7 @@ static void kvm_timer_init(void)
 DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
 EXPORT_PER_CPU_SYMBOL_GPL(current_vcpu);
 
-int kvm_is_in_guest(void)
+static int kvm_is_in_guest(void)
 {
 	return __this_cpu_read(current_vcpu) != NULL;
 }
@@ -9678,7 +9678,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 	 * interrupts on processors that implement an interrupt shadow, the
 	 * stat.exits increment will do nicely.
 	 */
-	kvm_before_interrupt(vcpu);
+	kvm_before_interrupt(vcpu, false);
 	local_irq_enable();
 	++vcpu->stat.exits;
 	local_irq_disable();
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 5cedc0e8a5d5..4c5ba4128b38 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -395,9 +395,10 @@ static inline void kvm_unregister_perf_callbacks(void)
 
 DECLARE_PER_CPU(struct kvm_vcpu *, current_vcpu);
 
-static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu)
+static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu, bool is_nmi)
 {
 	__this_cpu_write(current_vcpu, vcpu);
+	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, is_nmi);
 
 	kvm_register_perf_callbacks();
 }
@@ -406,6 +407,7 @@ static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
 {
 	kvm_unregister_perf_callbacks();
 
+	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, false);
 	__this_cpu_write(current_vcpu, NULL);
 }
 
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:11 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:11 -0700
Subject: [PATCH 08/15] KVM: x86: Drop current_vcpu in favor of kvm_running_vcpu
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-9-seanjc@google.com>

Now that KVM registers perf callbacks only when the CPU is "in guest",
use kvm_running_vcpu instead of current_vcpu to retrieve the associated
vCPU and drop current_vcpu.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/kvm/x86.c | 12 +++++-------
 arch/x86/kvm/x86.h |  4 ----
 2 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d4d91944fde7..e337aef60793 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8264,17 +8264,15 @@ static void kvm_timer_init(void)
 			  kvmclock_cpu_online, kvmclock_cpu_down_prep);
 }
 
-DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
-EXPORT_PER_CPU_SYMBOL_GPL(current_vcpu);
-
 static int kvm_is_in_guest(void)
 {
-	return __this_cpu_read(current_vcpu) != NULL;
+	/* x86's callbacks are registered only when handling a guest NMI. */
+	return true;
 }
 
 static int kvm_is_user_mode(void)
 {
-	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
 	if (WARN_ON_ONCE(!vcpu))
 		return 0;
@@ -8284,7 +8282,7 @@ static int kvm_is_user_mode(void)
 
 static unsigned long kvm_get_guest_ip(void)
 {
-	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
 	if (WARN_ON_ONCE(!vcpu))
 		return 0;
@@ -8294,7 +8292,7 @@ static unsigned long kvm_get_guest_ip(void)
 
 static void kvm_handle_intel_pt_intr(void)
 {
-	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
 	if (WARN_ON_ONCE(!vcpu))
 		return;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 4c5ba4128b38..f13f15d2fab8 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -393,11 +393,8 @@ static inline void kvm_unregister_perf_callbacks(void)
 	__perf_unregister_guest_info_callbacks();
 }
 
-DECLARE_PER_CPU(struct kvm_vcpu *, current_vcpu);
-
 static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu, bool is_nmi)
 {
-	__this_cpu_write(current_vcpu, vcpu);
 	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, is_nmi);
 
 	kvm_register_perf_callbacks();
@@ -408,7 +405,6 @@ static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
 	kvm_unregister_perf_callbacks();
 
 	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, false);
-	__this_cpu_write(current_vcpu, NULL);
 }
 
 
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:12 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:12 -0700
Subject: [PATCH 09/15] KVM: arm64: Register/unregister perf callbacks at vcpu
 load/put
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-10-seanjc@google.com>

Register/unregister perf callbacks at vcpu_load()/vcpu_put() instead of
keeping the callbacks registered for all eternity after loading KVM.
This will allow future cleanups and optimizations as the registration
of the callbacks signifies "in guest".  This will also allow moving the
callbacks into common KVM as they arm64 and x86 now have semantically
identical callback implementations.

Note, KVM could likely be more precise in its registration, but that's a
cleanup for the future.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/include/asm/kvm_host.h | 12 ++++++++++-
 arch/arm64/kvm/arm.c              |  5 ++++-
 arch/arm64/kvm/perf.c             | 36 ++++++++++++++-----------------
 3 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ed940aec89e0..007c38d77fd9 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -671,7 +671,17 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu);
 int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
 
 void kvm_perf_init(void);
-void kvm_perf_teardown(void);
+
+#ifdef CONFIG_PERF_EVENTS
+void kvm_register_perf_callbacks(void);
+static inline void kvm_unregister_perf_callbacks(void)
+{
+	__perf_unregister_guest_info_callbacks();
+}
+#else
+static inline void kvm_register_perf_callbacks(void) {}
+static inline void kvm_unregister_perf_callbacks(void) {}
+#endif
 
 long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
 gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..ec386971030d 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -429,10 +429,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	if (vcpu_has_ptrauth(vcpu))
 		vcpu_ptrauth_disable(vcpu);
 	kvm_arch_vcpu_load_debug_state_flags(vcpu);
+
+	kvm_register_perf_callbacks();
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
+	kvm_unregister_perf_callbacks();
 	kvm_arch_vcpu_put_debug_state_flags(vcpu);
 	kvm_arch_vcpu_put_fp(vcpu);
 	if (has_vhe())
@@ -2155,7 +2158,7 @@ int kvm_arch_init(void *opaque)
 /* NOP: Compiling as a module not supported */
 void kvm_arch_exit(void)
 {
-	kvm_perf_teardown();
+
 }
 
 static int __init early_kvm_mode_cfg(char *arg)
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 039fe59399a2..2556b0a3b096 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -13,33 +13,30 @@
 
 DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
 
+#ifdef CONFIG_PERF_EVENTS
 static int kvm_is_in_guest(void)
 {
-        return kvm_get_running_vcpu() != NULL;
+	return true;
 }
 
 static int kvm_is_user_mode(void)
 {
-	struct kvm_vcpu *vcpu;
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
-	vcpu = kvm_get_running_vcpu();
+	if (WARN_ON_ONCE(!vcpu))
+		return 0;
 
-	if (vcpu)
-		return !vcpu_mode_priv(vcpu);
-
-	return 0;
+	return !vcpu_mode_priv(vcpu);
 }
 
 static unsigned long kvm_get_guest_ip(void)
 {
-	struct kvm_vcpu *vcpu;
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
-	vcpu = kvm_get_running_vcpu();
+	if (WARN_ON_ONCE(!vcpu))
+		return 0;
 
-	if (vcpu)
-		return *vcpu_pc(vcpu);
-
-	return 0;
+	return *vcpu_pc(vcpu);
 }
 
 static struct perf_guest_info_callbacks kvm_guest_cbs = {
@@ -48,15 +45,14 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
 	.get_guest_ip	= kvm_get_guest_ip,
 };
 
+void kvm_register_perf_callbacks(void)
+{
+	__perf_register_guest_info_callbacks(&kvm_guest_cbs);
+}
+#endif /* CONFIG_PERF_EVENTS*/
+
 void kvm_perf_init(void)
 {
 	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
 		static_branch_enable(&kvm_arm_pmu_available);
-
-	perf_register_guest_info_callbacks(&kvm_guest_cbs);
-}
-
-void kvm_perf_teardown(void)
-{
-	perf_unregister_guest_info_callbacks();
 }
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:13 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:13 -0700
Subject: [PATCH 10/15] KVM: Move x86's perf guest info callbacks to generic KVM
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-11-seanjc@google.com>

Move x86's perf guest callbacks into common KVM, as they are semantically
identical to arm64's callbacks (the only other such KVM callbacks).
arm64 will convert to the common versions in a future patch.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/x86.c              | 48 +++++----------------------------
 arch/x86/kvm/x86.h              |  6 -----
 include/linux/kvm_host.h        | 12 +++++++++
 virt/kvm/kvm_main.c             | 46 +++++++++++++++++++++++++++++++
 5 files changed, 66 insertions(+), 47 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 465b35736d9b..63553a1f43ee 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -36,6 +36,7 @@
 #include <asm/hyperv-tlfs.h>
 
 #define __KVM_HAVE_ARCH_VCPU_DEBUGFS
+#define __KVM_WANT_PERF_CALLBACKS
 
 #define KVM_MAX_VCPUS 288
 #define KVM_SOFT_MAX_VCPUS 240
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e337aef60793..7cb0f04e24ee 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8264,32 +8264,6 @@ static void kvm_timer_init(void)
 			  kvmclock_cpu_online, kvmclock_cpu_down_prep);
 }
 
-static int kvm_is_in_guest(void)
-{
-	/* x86's callbacks are registered only when handling a guest NMI. */
-	return true;
-}
-
-static int kvm_is_user_mode(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-
-	if (WARN_ON_ONCE(!vcpu))
-		return 0;
-
-	return static_call(kvm_x86_get_cpl)(vcpu) != 0;
-}
-
-static unsigned long kvm_get_guest_ip(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-
-	if (WARN_ON_ONCE(!vcpu))
-		return 0;
-
-	return kvm_rip_read(vcpu);
-}
-
 static void kvm_handle_intel_pt_intr(void)
 {
 	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
@@ -8302,19 +8276,6 @@ static void kvm_handle_intel_pt_intr(void)
 			(unsigned long *)&vcpu->arch.pmu.global_status);
 }
 
-static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.is_in_guest		= kvm_is_in_guest,
-	.is_user_mode		= kvm_is_user_mode,
-	.get_guest_ip		= kvm_get_guest_ip,
-	.handle_intel_pt_intr	= NULL,
-};
-
-void kvm_register_perf_callbacks(void)
-{
-	__perf_register_guest_info_callbacks(&kvm_guest_cbs);
-}
-EXPORT_SYMBOL_GPL(kvm_register_perf_callbacks);
-
 #ifdef CONFIG_X86_64
 static void pvclock_gtod_update_fn(struct work_struct *work)
 {
@@ -11069,7 +11030,7 @@ int kvm_arch_hardware_setup(void *opaque)
 	kvm_ops_static_call_update();
 
 	if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest())
-		kvm_guest_cbs.handle_intel_pt_intr = kvm_handle_intel_pt_intr;
+		kvm_set_intel_pt_intr_handler(kvm_handle_intel_pt_intr);
 
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
 		supported_xss = 0;
@@ -11098,7 +11059,7 @@ int kvm_arch_hardware_setup(void *opaque)
 
 void kvm_arch_hardware_unsetup(void)
 {
-	kvm_guest_cbs.handle_intel_pt_intr = NULL;
+	kvm_set_intel_pt_intr_handler(NULL);
 
 	static_call(kvm_x86_hardware_unsetup)();
 }
@@ -11725,6 +11686,11 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
 	return vcpu->arch.preempted_in_kernel;
 }
 
+unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
+{
+	return kvm_rip_read(vcpu);
+}
+
 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
 {
 	return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index f13f15d2fab8..e1fe738c3827 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -387,12 +387,6 @@ static inline bool kvm_cstate_in_guest(struct kvm *kvm)
 	return kvm->arch.cstate_in_guest;
 }
 
-void kvm_register_perf_callbacks(void);
-static inline void kvm_unregister_perf_callbacks(void)
-{
-	__perf_unregister_guest_info_callbacks();
-}
-
 static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu, bool is_nmi)
 {
 	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, is_nmi);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index e4d712e9f760..0db9af0b628c 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1163,6 +1163,18 @@ static inline bool kvm_arch_intc_initialized(struct kvm *kvm)
 }
 #endif
 
+#ifdef __KVM_WANT_PERF_CALLBACKS
+
+void kvm_set_intel_pt_intr_handler(void (*handler)(void));
+unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu);
+
+void kvm_register_perf_callbacks(void);
+static inline void kvm_unregister_perf_callbacks(void)
+{
+	__perf_unregister_guest_info_callbacks();
+}
+#endif
+
 int kvm_arch_init_vm(struct kvm *kvm, unsigned long type);
 void kvm_arch_destroy_vm(struct kvm *kvm);
 void kvm_arch_sync_events(struct kvm *kvm);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 3e67c93ca403..13c4f58a75e5 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -5460,6 +5460,52 @@ struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void)
         return &kvm_running_vcpu;
 }
 
+#ifdef __KVM_WANT_PERF_CALLBACKS
+static int kvm_is_in_guest(void)
+{
+	/* Registration of KVM's callback signifies "in guest". */
+	return true;
+}
+
+static int kvm_is_user_mode(void)
+{
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
+
+	if (WARN_ON_ONCE(!vcpu))
+		return 0;
+
+	return !kvm_arch_vcpu_in_kernel(vcpu);
+}
+
+static unsigned long kvm_get_guest_ip(void)
+{
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
+
+	if (WARN_ON_ONCE(!vcpu))
+		return 0;
+
+	return kvm_arch_vcpu_get_ip(vcpu);
+}
+
+static struct perf_guest_info_callbacks kvm_guest_cbs = {
+	.is_in_guest		= kvm_is_in_guest,
+	.is_user_mode		= kvm_is_user_mode,
+	.get_guest_ip		= kvm_get_guest_ip,
+	.handle_intel_pt_intr	= NULL,
+};
+
+void kvm_set_intel_pt_intr_handler(void (*handler)(void))
+{
+	kvm_guest_cbs.handle_intel_pt_intr = handler;
+}
+
+void kvm_register_perf_callbacks(void)
+{
+	__perf_register_guest_info_callbacks(&kvm_guest_cbs);
+}
+EXPORT_SYMBOL_GPL(kvm_register_perf_callbacks);
+#endif
+
 struct kvm_cpu_compat_check {
 	void *opaque;
 	int *ret;
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:09 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:09 -0700
Subject: [PATCH 06/15] KVM: x86: Register perf callbacks only when actively
 handling interrupt
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-7-seanjc@google.com>

Register KVM's perf callback only when handling an interrupt that may be
a PMI (sadly this includes IRQs), and unregister the callback immediately
after handling the interrupt (or closing the window).  Registering the
callback on a per-CPU basis (with preemption disabled!), fixes a mostly
theoretical bug where perf could dereference a NULL pointer due to KVM
unloading and unregistering the callbacks in between perf queries of the
callback functions.  The precise registration will also allow for future
cleanups and optimizations, e.g. the existence of the callbacks can serve
as the "in guest" check.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/kvm/x86.c         | 27 +++++++++++++++++----------
 arch/x86/kvm/x86.h         | 10 ++++++++++
 include/linux/perf_event.h |  2 ++
 kernel/events/core.c       | 12 ++++++++++++
 4 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bae951344e28..bc4ee6ea7752 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8274,28 +8274,31 @@ int kvm_is_in_guest(void)
 
 static int kvm_is_user_mode(void)
 {
-	int user_mode = 3;
+	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
 
-	if (__this_cpu_read(current_vcpu))
-		user_mode = static_call(kvm_x86_get_cpl)(__this_cpu_read(current_vcpu));
+	if (WARN_ON_ONCE(!vcpu))
+		return 0;
 
-	return user_mode != 0;
+	return static_call(kvm_x86_get_cpl)(vcpu) != 0;
 }
 
 static unsigned long kvm_get_guest_ip(void)
 {
-	unsigned long ip = 0;
+	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
 
-	if (__this_cpu_read(current_vcpu))
-		ip = kvm_rip_read(__this_cpu_read(current_vcpu));
+	if (WARN_ON_ONCE(!vcpu))
+		return 0;
 
-	return ip;
+	return kvm_rip_read(vcpu);
 }
 
 static void kvm_handle_intel_pt_intr(void)
 {
 	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
 
+	if (WARN_ON_ONCE(!vcpu))
+		return;
+
 	kvm_make_request(KVM_REQ_PMI, vcpu);
 	__set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT,
 			(unsigned long *)&vcpu->arch.pmu.global_status);
@@ -8308,6 +8311,12 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
 	.handle_intel_pt_intr	= NULL,
 };
 
+void kvm_register_perf_callbacks(void)
+{
+	__perf_register_guest_info_callbacks(&kvm_guest_cbs);
+}
+EXPORT_SYMBOL_GPL(kvm_register_perf_callbacks);
+
 #ifdef CONFIG_X86_64
 static void pvclock_gtod_update_fn(struct work_struct *work)
 {
@@ -11063,7 +11072,6 @@ int kvm_arch_hardware_setup(void *opaque)
 
 	if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest())
 		kvm_guest_cbs.handle_intel_pt_intr = kvm_handle_intel_pt_intr;
-	perf_register_guest_info_callbacks(&kvm_guest_cbs);
 
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
 		supported_xss = 0;
@@ -11092,7 +11100,6 @@ int kvm_arch_hardware_setup(void *opaque)
 
 void kvm_arch_hardware_unsetup(void)
 {
-	perf_unregister_guest_info_callbacks();
 	kvm_guest_cbs.handle_intel_pt_intr = NULL;
 
 	static_call(kvm_x86_hardware_unsetup)();
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 7d66d63dc55a..5cedc0e8a5d5 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -387,15 +387,25 @@ static inline bool kvm_cstate_in_guest(struct kvm *kvm)
 	return kvm->arch.cstate_in_guest;
 }
 
+void kvm_register_perf_callbacks(void);
+static inline void kvm_unregister_perf_callbacks(void)
+{
+	__perf_unregister_guest_info_callbacks();
+}
+
 DECLARE_PER_CPU(struct kvm_vcpu *, current_vcpu);
 
 static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu)
 {
 	__this_cpu_write(current_vcpu, vcpu);
+
+	kvm_register_perf_callbacks();
 }
 
 static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
 {
+	kvm_unregister_perf_callbacks();
+
 	__this_cpu_write(current_vcpu, NULL);
 }
 
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index c98253dae037..7a367bf1b78d 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1238,6 +1238,8 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 DECLARE_PER_CPU(struct perf_guest_info_callbacks *, perf_guest_cbs);
+extern void __perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs);
+extern void __perf_unregister_guest_info_callbacks(void);
 extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 extern void perf_unregister_guest_info_callbacks(void);
 #endif /* CONFIG_HAVE_GUEST_PERF_EVENTS */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 9bc1375d6ed9..2f28d9d8dc94 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6485,6 +6485,18 @@ static void perf_pending_event(struct irq_work *entry)
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 DEFINE_PER_CPU(struct perf_guest_info_callbacks *, perf_guest_cbs);
 
+void __perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+{
+	__this_cpu_write(perf_guest_cbs, cbs);
+}
+EXPORT_SYMBOL_GPL(__perf_register_guest_info_callbacks);
+
+void __perf_unregister_guest_info_callbacks(void)
+{
+	__this_cpu_write(perf_guest_cbs, NULL);
+}
+EXPORT_SYMBOL_GPL(__perf_unregister_guest_info_callbacks);
+
 void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
 	int cpu;
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:14 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:14 -0700
Subject: [PATCH 11/15] KVM: x86: Move Intel Processor Trace interrupt handler
 to vmx.c
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-12-seanjc@google.com>

Now that all state needed for VMX's PT interrupt handler is exposed to
vmx.c (specifically the currently running vCPU), move the handler into
vmx.c where it belongs.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/include/asm/kvm_host.h |  1 -
 arch/x86/kvm/vmx/vmx.c          | 24 +++++++++++++++++++++---
 arch/x86/kvm/x86.c              | 17 -----------------
 virt/kvm/kvm_main.c             |  1 +
 4 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 63553a1f43ee..daa33147650a 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1496,7 +1496,6 @@ struct kvm_x86_init_ops {
 	int (*disabled_by_bios)(void);
 	int (*check_processor_compatibility)(void);
 	int (*hardware_setup)(void);
-	bool (*intel_pt_intr_in_guest)(void);
 
 	struct kvm_x86_ops *runtime_ops;
 };
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index f08980ef7c44..4665a272249a 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7535,6 +7535,8 @@ static void vmx_migrate_timers(struct kvm_vcpu *vcpu)
 
 static void hardware_unsetup(void)
 {
+	kvm_set_intel_pt_intr_handler(NULL);
+
 	if (nested)
 		nested_vmx_hardware_unsetup();
 
@@ -7685,6 +7687,18 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
 	.vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector,
 };
 
+static void vmx_handle_intel_pt_intr(void)
+{
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
+
+	if (WARN_ON_ONCE(!vcpu))
+		return;
+
+	kvm_make_request(KVM_REQ_PMI, vcpu);
+	__set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT,
+			(unsigned long *)&vcpu->arch.pmu.global_status);
+}
+
 static __init void vmx_setup_user_return_msrs(void)
 {
 
@@ -7886,9 +7900,14 @@ static __init int hardware_setup(void)
 	vmx_set_cpu_caps();
 
 	r = alloc_kvm_area();
-	if (r)
+	if (r) {
 		nested_vmx_hardware_unsetup();
-	return r;
+		return r;
+	}
+
+	if (pt_mode == PT_MODE_HOST_GUEST)
+		kvm_set_intel_pt_intr_handler(vmx_handle_intel_pt_intr);
+	return 0;
 }
 
 static struct kvm_x86_init_ops vmx_init_ops __initdata = {
@@ -7896,7 +7915,6 @@ static struct kvm_x86_init_ops vmx_init_ops __initdata = {
 	.disabled_by_bios = vmx_disabled_by_bios,
 	.check_processor_compatibility = vmx_check_processor_compat,
 	.hardware_setup = hardware_setup,
-	.intel_pt_intr_in_guest = vmx_pt_mode_is_host_guest,
 
 	.runtime_ops = &vmx_x86_ops,
 };
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7cb0f04e24ee..11c7a02f839c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8264,18 +8264,6 @@ static void kvm_timer_init(void)
 			  kvmclock_cpu_online, kvmclock_cpu_down_prep);
 }
 
-static void kvm_handle_intel_pt_intr(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-
-	if (WARN_ON_ONCE(!vcpu))
-		return;
-
-	kvm_make_request(KVM_REQ_PMI, vcpu);
-	__set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT,
-			(unsigned long *)&vcpu->arch.pmu.global_status);
-}
-
 #ifdef CONFIG_X86_64
 static void pvclock_gtod_update_fn(struct work_struct *work)
 {
@@ -11029,9 +11017,6 @@ int kvm_arch_hardware_setup(void *opaque)
 	memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
 	kvm_ops_static_call_update();
 
-	if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest())
-		kvm_set_intel_pt_intr_handler(kvm_handle_intel_pt_intr);
-
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
 		supported_xss = 0;
 
@@ -11059,8 +11044,6 @@ int kvm_arch_hardware_setup(void *opaque)
 
 void kvm_arch_hardware_unsetup(void)
 {
-	kvm_set_intel_pt_intr_handler(NULL);
-
 	static_call(kvm_x86_hardware_unsetup)();
 }
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 13c4f58a75e5..e0b1c9386926 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -5498,6 +5498,7 @@ void kvm_set_intel_pt_intr_handler(void (*handler)(void))
 {
 	kvm_guest_cbs.handle_intel_pt_intr = handler;
 }
+EXPORT_SYMBOL_GPL(kvm_set_intel_pt_intr_handler);
 
 void kvm_register_perf_callbacks(void)
 {
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:15 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:15 -0700
Subject: [PATCH 12/15] KVM: arm64: Convert to the generic perf callbacks
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-13-seanjc@google.com>

Drop arm64's version of the callbacks in favor of the callbacks provided
by generic KVM, which are semantically identical.  Implement the "get ip"
hook as needed.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  6 +----
 arch/arm64/kvm/arm.c              |  5 ++++
 arch/arm64/kvm/perf.c             | 38 -------------------------------
 3 files changed, 6 insertions(+), 43 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 007c38d77fd9..12e8d789e1ac 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -673,11 +673,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
 void kvm_perf_init(void);
 
 #ifdef CONFIG_PERF_EVENTS
-void kvm_register_perf_callbacks(void);
-static inline void kvm_unregister_perf_callbacks(void)
-{
-	__perf_unregister_guest_info_callbacks();
-}
+#define __KVM_WANT_PERF_CALLBACKS
 #else
 static inline void kvm_register_perf_callbacks(void) {}
 static inline void kvm_unregister_perf_callbacks(void) {}
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index ec386971030d..dfc8078dd4f9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -503,6 +503,11 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
 	return vcpu_mode_priv(vcpu);
 }
 
+unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
+{
+	return *vcpu_pc(vcpu);
+}
+
 /* Just ensure a guest exit from a particular CPU */
 static void exit_vm_noop(void *info)
 {
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 2556b0a3b096..ad9fdc2f2f70 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -13,44 +13,6 @@
 
 DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
 
-#ifdef CONFIG_PERF_EVENTS
-static int kvm_is_in_guest(void)
-{
-	return true;
-}
-
-static int kvm_is_user_mode(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-
-	if (WARN_ON_ONCE(!vcpu))
-		return 0;
-
-	return !vcpu_mode_priv(vcpu);
-}
-
-static unsigned long kvm_get_guest_ip(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-
-	if (WARN_ON_ONCE(!vcpu))
-		return 0;
-
-	return *vcpu_pc(vcpu);
-}
-
-static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.is_in_guest	= kvm_is_in_guest,
-	.is_user_mode	= kvm_is_user_mode,
-	.get_guest_ip	= kvm_get_guest_ip,
-};
-
-void kvm_register_perf_callbacks(void)
-{
-	__perf_register_guest_info_callbacks(&kvm_guest_cbs);
-}
-#endif /* CONFIG_PERF_EVENTS*/
-
 void kvm_perf_init(void)
 {
 	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:16 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:16 -0700
Subject: [PATCH 13/15] KVM: arm64: Drop perf.c and fold its tiny bit of code
 into pmu.c
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-14-seanjc@google.com>

Fold that last few remnants of perf.c into pmu.c and rename the init
helper as appropriate.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  2 --
 arch/arm64/kvm/Makefile           |  2 +-
 arch/arm64/kvm/arm.c              |  3 ++-
 arch/arm64/kvm/perf.c             | 20 --------------------
 arch/arm64/kvm/pmu.c              |  8 ++++++++
 include/kvm/arm_pmu.h             |  1 +
 6 files changed, 12 insertions(+), 24 deletions(-)
 delete mode 100644 arch/arm64/kvm/perf.c

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 12e8d789e1ac..86c0fdd11ad2 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -670,8 +670,6 @@ unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
 int kvm_handle_mmio_return(struct kvm_vcpu *vcpu);
 int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
 
-void kvm_perf_init(void);
-
 #ifdef CONFIG_PERF_EVENTS
 #define __KVM_WANT_PERF_CALLBACKS
 #else
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 989bb5dad2c8..0bcc378b7961 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_KVM) += hyp/
 
 kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
 	 $(KVM)/vfio.o $(KVM)/irqchip.o $(KVM)/binary_stats.o \
-	 arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \
+	 arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 inject_fault.o va_layout.o handle_exit.o \
 	 guest.o debug.o reset.o sys_regs.o \
 	 vgic-sys-reg-v3.o fpsimd.o pmu.o \
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index dfc8078dd4f9..57e637dee71d 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1747,7 +1747,8 @@ static int init_subsystems(void)
 	if (err)
 		goto out;
 
-	kvm_perf_init();
+	kvm_pmu_init();
+
 	kvm_sys_reg_table_init();
 
 out:
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
deleted file mode 100644
index ad9fdc2f2f70..000000000000
--- a/arch/arm64/kvm/perf.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Based on the x86 implementation.
- *
- * Copyright (C) 2012 ARM Ltd.
- * Author: Marc Zyngier <marc.zyngier at arm.com>
- */
-
-#include <linux/perf_event.h>
-#include <linux/kvm_host.h>
-
-#include <asm/kvm_emulate.h>
-
-DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
-
-void kvm_perf_init(void)
-{
-	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
-		static_branch_enable(&kvm_arm_pmu_available);
-}
diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
index 03a6c1f4a09a..d98b57a17043 100644
--- a/arch/arm64/kvm/pmu.c
+++ b/arch/arm64/kvm/pmu.c
@@ -7,6 +7,14 @@
 #include <linux/perf_event.h>
 #include <asm/kvm_hyp.h>
 
+DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
+
+void kvm_pmu_init(void)
+{
+	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
+		static_branch_enable(&kvm_arm_pmu_available);
+}
+
 /*
  * Given the perf event attributes and system type, determine
  * if we are going to need to switch counters at guest entry/exit.
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 864b9997efb2..42270676498d 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -14,6 +14,7 @@
 #define ARMV8_PMU_MAX_COUNTER_PAIRS	((ARMV8_PMU_MAX_COUNTERS + 1) >> 1)
 
 DECLARE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
+void kvm_pmu_init(void);
 
 static __always_inline bool kvm_arm_support_pmu_v3(void)
 {
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:17 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:17 -0700
Subject: [PATCH 14/15] perf: Disallow bulk unregistering of guest callbacks
 and do cleanup
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-15-seanjc@google.com>

Drop the helper that allows bulk unregistering of the per-CPU callbacks
now that KVM, the only entity that actually unregisters callbacks, uses
the per-CPU helpers.  Bulk unregistering is inherently unsafe as there
are no protections against nullifying a pointer for a CPU that is using
said pointer in a PMI handler.

Opportunistically tweak names to better reflect reality.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/xen/pmu.c         |  2 +-
 include/linux/kvm_host.h   |  2 +-
 include/linux/perf_event.h |  9 +++------
 kernel/events/core.c       | 31 +++++++++++--------------------
 virt/kvm/kvm_main.c        |  2 +-
 5 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
index e13b0b49fcdf..57834de043c3 100644
--- a/arch/x86/xen/pmu.c
+++ b/arch/x86/xen/pmu.c
@@ -548,7 +548,7 @@ void xen_pmu_init(int cpu)
 	per_cpu(xenpmu_shared, cpu).flags = 0;
 
 	if (cpu == 0) {
-		perf_register_guest_info_callbacks(&xen_guest_cbs);
+		perf_register_guest_info_callbacks_all_cpus(&xen_guest_cbs);
 		xen_pmu_arch_init();
 	}
 
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 0db9af0b628c..d68a49d5fc53 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1171,7 +1171,7 @@ unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu);
 void kvm_register_perf_callbacks(void);
 static inline void kvm_unregister_perf_callbacks(void)
 {
-	__perf_unregister_guest_info_callbacks();
+	perf_unregister_guest_info_callbacks();
 }
 #endif
 
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 7a367bf1b78d..db701409a62f 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1238,10 +1238,9 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 DECLARE_PER_CPU(struct perf_guest_info_callbacks *, perf_guest_cbs);
-extern void __perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs);
-extern void __perf_unregister_guest_info_callbacks(void);
-extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs);
 extern void perf_unregister_guest_info_callbacks(void);
+extern void perf_register_guest_info_callbacks_all_cpus(struct perf_guest_info_callbacks *cbs);
 #endif /* CONFIG_HAVE_GUEST_PERF_EVENTS */
 
 extern void perf_event_exec(void);
@@ -1486,9 +1485,7 @@ static inline void
 perf_bp_event(struct perf_event *event, void *data)			{ }
 
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
-static inline void perf_register_guest_info_callbacks
-(struct perf_guest_info_callbacks *callbacks)				{ }
-static inline void perf_unregister_guest_info_callbacks(void)		{ }
+extern void perf_register_guest_info_callbacks_all_cpus(struct perf_guest_info_callbacks *cbs);
 #endif
 
 static inline void perf_event_mmap(struct vm_area_struct *vma)		{ }
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2f28d9d8dc94..f1964096c4c2 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6485,35 +6485,26 @@ static void perf_pending_event(struct irq_work *entry)
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 DEFINE_PER_CPU(struct perf_guest_info_callbacks *, perf_guest_cbs);
 
-void __perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
-{
-	__this_cpu_write(perf_guest_cbs, cbs);
-}
-EXPORT_SYMBOL_GPL(__perf_register_guest_info_callbacks);
-
-void __perf_unregister_guest_info_callbacks(void)
-{
-	__this_cpu_write(perf_guest_cbs, NULL);
-}
-EXPORT_SYMBOL_GPL(__perf_unregister_guest_info_callbacks);
-
 void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
-	int cpu;
-
-	for_each_possible_cpu(cpu)
-		per_cpu(perf_guest_cbs, cpu) = cbs;
+	__this_cpu_write(perf_guest_cbs, cbs);
 }
 EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
 
 void perf_unregister_guest_info_callbacks(void)
 {
-	int cpu;
-
-	for_each_possible_cpu(cpu)
-		per_cpu(perf_guest_cbs, cpu) = NULL;
+	__this_cpu_write(perf_guest_cbs, NULL);
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
+
+void perf_register_guest_info_callbacks_all_cpus(struct perf_guest_info_callbacks *cbs)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		per_cpu(perf_guest_cbs, cpu) = cbs;
+}
+EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks_all_cpus);
 #endif
 
 static void
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index e0b1c9386926..1bcc3eab510b 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -5502,7 +5502,7 @@ EXPORT_SYMBOL_GPL(kvm_set_intel_pt_intr_handler);
 
 void kvm_register_perf_callbacks(void)
 {
-	__perf_register_guest_info_callbacks(&kvm_guest_cbs);
+	perf_register_guest_info_callbacks(&kvm_guest_cbs);
 }
 EXPORT_SYMBOL_GPL(kvm_register_perf_callbacks);
 #endif
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Thu Aug 26 17:57:18 2021
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 26 Aug 2021 17:57:18 -0700
Subject: [PATCH 15/15] perf: KVM: Indicate "in guest" via NULL ->is_in_guest
 callback
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <20210827005718.585190-16-seanjc@google.com>

Interpret a null ->is_in_guest callback as meaning "in guest" and use
the new semantics in KVM, which currently returns 'true' unconditionally
in its implementation of ->is_in_guest().  This avoids a retpoline on
the indirect call for PMIs that arrive in a KVM guest, and also provides
a handy excuse for a wrapper around retrieval of perf_get_guest_cbs,
e.g. to reduce the probability of an errant direct read of perf_guest_cbs.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/events/core.c       | 16 ++++++++--------
 arch/x86/events/intel/core.c |  5 ++---
 include/linux/perf_event.h   | 17 +++++++++++++++++
 virt/kvm/kvm_main.c          |  9 ++-------
 4 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 34155a52e498..b60c339ae06b 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2761,11 +2761,11 @@ static bool perf_hw_regs(struct pt_regs *regs)
 void
 perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct unwind_state state;
 	unsigned long addr;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
+	if (guest_cbs) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2865,11 +2865,11 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
 void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stack_frame frame;
 	const struct stack_frame __user *fp;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
+	if (guest_cbs) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2946,9 +2946,9 @@ static unsigned long code_segment_base(struct pt_regs *regs)
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 
-	if (guest_cbs && guest_cbs->is_in_guest())
+	if (guest_cbs)
 		return guest_cbs->get_guest_ip();
 
 	return regs->ip + code_segment_base(regs);
@@ -2956,10 +2956,10 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	int misc = 0;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
+	if (guest_cbs) {
 		if (guest_cbs->is_user_mode())
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 96001962c24d..9a8c18b51a96 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2853,9 +2853,8 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
 	 */
 	if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) {
 		handled++;
-		guest_cbs = this_cpu_read(perf_guest_cbs);
-		if (unlikely(guest_cbs && guest_cbs->is_in_guest() &&
-			     guest_cbs->handle_intel_pt_intr))
+		guest_cbs = perf_get_guest_cbs();
+		if (unlikely(guest_cbs && guest_cbs->handle_intel_pt_intr))
 			guest_cbs->handle_intel_pt_intr();
 		else
 			intel_pt_interrupt();
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index db701409a62f..6e3a10784d24 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1241,6 +1241,23 @@ DECLARE_PER_CPU(struct perf_guest_info_callbacks *, perf_guest_cbs);
 extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs);
 extern void perf_unregister_guest_info_callbacks(void);
 extern void perf_register_guest_info_callbacks_all_cpus(struct perf_guest_info_callbacks *cbs);
+/*
+ * Returns guest callbacks for the current CPU if callbacks are registered and
+ * the PMI fired while a guest was running, otherwise returns NULL.
+ */
+static inline struct perf_guest_info_callbacks *perf_get_guest_cbs(void)
+{
+	struct perf_guest_info_callbacks *guest_cbs = this_cpu_read(perf_guest_cbs);
+
+	/*
+	 * Implementing is_in_guest is optional if the callbacks are registered
+	 * only when "in guest".
+	 */
+	if (guest_cbs && (!guest_cbs->is_in_guest || guest_cbs->is_in_guest()))
+		return guest_cbs;
+
+	return NULL;
+}
 #endif /* CONFIG_HAVE_GUEST_PERF_EVENTS */
 
 extern void perf_event_exec(void);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 1bcc3eab510b..fa83d3846785 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -5461,12 +5461,6 @@ struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void)
 }
 
 #ifdef __KVM_WANT_PERF_CALLBACKS
-static int kvm_is_in_guest(void)
-{
-	/* Registration of KVM's callback signifies "in guest". */
-	return true;
-}
-
 static int kvm_is_user_mode(void)
 {
 	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
@@ -5488,7 +5482,8 @@ static unsigned long kvm_get_guest_ip(void)
 }
 
 static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.is_in_guest		= kvm_is_in_guest,
+	/* Registration of KVM's callback signifies "in guest". */
+	.is_in_guest		= NULL,
 	.is_user_mode		= kvm_is_user_mode,
 	.get_guest_ip		= kvm_get_guest_ip,
 	.handle_intel_pt_intr	= NULL,
-- 
2.33.0.259.gc128427fd7-goog



From lkp at intel.com  Thu Aug 26 18:01:47 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 09:01:47 +0800
Subject: [soc:arm/dt] BUILD SUCCESS
 9e62ec0e661ca7161e5830bdbf8e69831b41e866
Message-ID: <6128397b.Vw3e62Dg13c0ZCDi%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/dt
branch HEAD: 9e62ec0e661ca7161e5830bdbf8e69831b41e866  arm/arm64: dts: Fix remaining dtc 'unit_address_format' warnings

elapsed time: 732m

configs tested: 123
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210826
sh                           se7722_defconfig
powerpc                     powernv_defconfig
powerpc                        warp_defconfig
mips                      loongson3_defconfig
powerpc                         ps3_defconfig
sh                               alldefconfig
arm                            lart_defconfig
sh                         apsh4a3a_defconfig
arm                           viper_defconfig
nds32                            alldefconfig
powerpc                    ge_imp3a_defconfig
sh                          rsk7269_defconfig
powerpc                 mpc837x_mds_defconfig
arm                      integrator_defconfig
sh                                  defconfig
openrisc                            defconfig
powerpc                     asp8347_defconfig
sparc                       sparc64_defconfig
sh                            shmin_defconfig
xtensa                    xip_kc705_defconfig
powerpc                          g5_defconfig
mips                        qi_lb60_defconfig
powerpc                         wii_defconfig
mips                           ci20_defconfig
mips                   sb1250_swarm_defconfig
arm                    vt8500_v6_v7_defconfig
arm                         shannon_defconfig
arm                          pcm027_defconfig
microblaze                      mmu_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210826
x86_64               randconfig-a006-20210826
x86_64               randconfig-a001-20210826
x86_64               randconfig-a003-20210826
x86_64               randconfig-a004-20210826
x86_64               randconfig-a002-20210826
i386                 randconfig-a006-20210826
i386                 randconfig-a001-20210826
i386                 randconfig-a002-20210826
i386                 randconfig-a005-20210826
i386                 randconfig-a003-20210826
i386                 randconfig-a004-20210826
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
s390                 randconfig-c005-20210827
i386                 randconfig-c001-20210827
arm                  randconfig-c002-20210827
riscv                randconfig-c006-20210827
powerpc              randconfig-c003-20210827
x86_64               randconfig-c007-20210827
mips                 randconfig-c004-20210827
i386                 randconfig-c001-20210826
s390                 randconfig-c005-20210826
arm                  randconfig-c002-20210826
riscv                randconfig-c006-20210826
powerpc              randconfig-c003-20210826
x86_64               randconfig-c007-20210826
mips                 randconfig-c004-20210826
x86_64               randconfig-a014-20210826
x86_64               randconfig-a015-20210826
x86_64               randconfig-a016-20210826
x86_64               randconfig-a013-20210826
x86_64               randconfig-a012-20210826
x86_64               randconfig-a011-20210826
i386                 randconfig-a011-20210826
i386                 randconfig-a016-20210826
i386                 randconfig-a012-20210826
i386                 randconfig-a014-20210826
i386                 randconfig-a013-20210826
i386                 randconfig-a015-20210826
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From andrew at lunn.ch  Thu Aug 26 18:58:02 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 27 Aug 2021 03:58:02 +0200
Subject: [PATCH net-next v2 1/2] net: pcs: xpcs: enable skip xPCS soft
 reset
In-Reply-To: <20210826235134.4051310-2-vee.khee.wong@linux.intel.com>
References: <20210826235134.4051310-1-vee.khee.wong@linux.intel.com>
 <20210826235134.4051310-2-vee.khee.wong@linux.intel.com>
Message-ID: <YShGqldtThS2z0eI@lunn.ch>

On Fri, Aug 27, 2021 at 07:51:33AM +0800, Wong Vee Khee wrote:
> Unlike any other platforms, Intel AlderLake-S uses Synopsys SerDes where
> all the SerDes PLL configurations are controlled by the xPCS at the BIOS
> level. If the driver perform a xPCS soft reset on initialization, these
> settings will be switched back to the power on reset values.
> 
> This patch introduced a new xpcs_reset() function for drivers such as
> sja1105 and stmmac to decide whether or not to perform a xPCS soft
> reset.
> 
> +	/* If Device ID are all ones, there is no device found */
> +	if (xpcs_id == 0xffffffff)
> +		goto out;
> +

This does not look like plain refactoring. It is not code moved from
somewhere else. At minimum, it needs explaining in the commit message,
but it probably should be a commit of its own.

    Andrew


From andrew at lunn.ch  Thu Aug 26 19:03:31 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 27 Aug 2021 04:03:31 +0200
Subject: [PATCH net-next v2 1/2] net: pcs: xpcs: enable skip xPCS soft
 reset
In-Reply-To: <20210826235134.4051310-1-vee.khee.wong@linux.intel.com>
References: <20210826235134.4051310-1-vee.khee.wong@linux.intel.com>
Message-ID: <YShH84C9gFtL1LcJ@lunn.ch>

On Fri, Aug 27, 2021 at 07:51:32AM +0800, Wong Vee Khee wrote:
> Unlike any other platforms, Intel AlderLake-S uses Synopsys SerDes where
> all the SerDes PLL configurations are controlled by the xPCS at the BIOS
> level. If the driver perform a xPCS soft reset on initialization, these
> settings will be switched back to the power on reset values.

So you have given up on the idea of calling into the BIOS to do this?
ACPI is too difficult to use? Can you at least copy the code from the
BIOS into the driver? It might then also be possible to fix your
inability to swap link speeds?

	  Andrew


From jianjun.wang at mediatek.com  Thu Aug 26 19:26:38 2021
From: jianjun.wang at mediatek.com (Jianjun Wang)
Date: Fri, 27 Aug 2021 10:26:38 +0800
Subject: [PATCH v2] dt-bindings: PCI: mediatek-gen3: Add support for MT8195
Message-ID: <20210827022638.3573-1-jianjun.wang@mediatek.com>

MT8195 is an ARM platform SoC which has the same PCIe IP with MT8192.

Signed-off-by: Jianjun Wang <jianjun.wang at mediatek.com>
---
 Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
index 742206dbd965..93e09c3029b7 100644
--- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
@@ -48,7 +48,9 @@ allOf:
 
 properties:
   compatible:
-    const: mediatek,mt8192-pcie
+    enum:
+      - mediatek,mt8192-pcie
+      - mediatek,mt8195-pcie
 
   reg:
     maxItems: 1
-- 
2.18.0

From marcan at marcan.st  Thu Aug 26 20:00:15 2021
From: marcan at marcan.st (Hector Martin)
Date: Fri, 27 Aug 2021 12:00:15 +0900
Subject: [PATCH] maintainers: Add Alyssa Rosenzweig as M1 reviewer
In-Reply-To: <20210823151738.6273-1-alyssa@rosenzweig.io>
References: <20210823151738.6273-1-alyssa@rosenzweig.io>
Message-ID: <3112bc2c-7c6a-3190-26cd-a873b4029429@marcan.st>

On 24/08/2021 00.17, Alyssa Rosenzweig wrote:
> Add myself as a reviewer for Asahi Linux (Apple M1) patches.
> 
> I would like to be CC'ed on Asahi Linux patches for review and testing.
> I am also collecting Asahi Linux patches downstream, rebasing on
> linux-next periodically, and would like to be notified of what to
> cherry-pick from lists.
> 
> Signed-off-by: Alyssa Rosenzweig <alyssa at rosenzweig.io>
> Cc: Hector Martin <marcan at marcan.st>
> Cc: Sven Peter <sven at svenpeter.dev>
> ---
>   MAINTAINERS | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b63403793c81..399e536bf629 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1264,6 +1264,7 @@ F:	drivers/input/mouse/bcm5974.c
>   
>   APPLE DART IOMMU DRIVER
>   M:	Sven Peter <sven at svenpeter.dev>
> +R:	Alyssa Rosenzweig <alyssa at rosenzweig.io>
>   L:	iommu at lists.linux-foundation.org
>   S:	Maintained
>   F:	Documentation/devicetree/bindings/iommu/apple,dart.yaml
> @@ -1693,6 +1694,7 @@ F:	drivers/*/*alpine*
>   
>   ARM/APPLE MACHINE SUPPORT
>   M:	Hector Martin <marcan at marcan.st>
> +R:	Alyssa Rosenzweig <alyssa at rosenzweig.io>
>   L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>   S:	Maintained
>   W:	https://asahilinux.org
> 

Acked-by: Hector Martin <marcan at marcan.st>

P.S. fix your mail server, I had to pull this from the list and I doubt 
I'm the only one ;)

-- 
Hector Martin (marcan at marcan.st)
Public Key: https://mrcn.st/pub


From pcc at google.com  Thu Aug 26 20:07:48 2021
From: pcc at google.com (Peter Collingbourne)
Date: Thu, 26 Aug 2021 20:07:48 -0700
Subject: [PATCH] arm64: kasan: mte: move GCR_EL1 switch to task switch when
 KASAN disabled
Message-ID: <20210827030748.587710-1-pcc@google.com>

It is not necessary to write to GCR_EL1 on every kernel entry and
exit when HW tag-based KASAN is disabled because the kernel will not
execute any IRG instructions in that mode. Since accessing GCR_EL1
can be expensive on some microarchitectures, avoid doing so by moving
the access to task switch when HW tag-based KASAN is disabled.

Signed-off-by: Peter Collingbourne <pcc at google.com>
---
 arch/arm64/kernel/entry.S | 10 +++++-----
 arch/arm64/kernel/mte.c   | 24 +++++++++++++++++++++---
 include/linux/kasan.h     |  9 +++++++--
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 923ee2ac85fd..e12ed892cde8 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -178,9 +178,9 @@ alternative_else_nop_endif
 
 	.macro mte_set_kernel_gcr, tmp, tmp2
 #ifdef CONFIG_KASAN_HW_TAGS
-alternative_if_not ARM64_MTE
+alternative_cb	kasan_hw_tags_enable
 	b	1f
-alternative_else_nop_endif
+alternative_cb_end
 	mov	\tmp, KERNEL_GCR_EL1
 	msr_s	SYS_GCR_EL1, \tmp
 1:
@@ -188,10 +188,10 @@ alternative_else_nop_endif
 	.endm
 
 	.macro mte_set_user_gcr, tsk, tmp, tmp2
-#ifdef CONFIG_ARM64_MTE
-alternative_if_not ARM64_MTE
+#ifdef CONFIG_KASAN_HW_TAGS
+alternative_cb	kasan_hw_tags_enable
 	b	1f
-alternative_else_nop_endif
+alternative_cb_end
 	ldr	\tmp, [\tsk, #THREAD_MTE_CTRL]
 
 	mte_set_gcr \tmp, \tmp2
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index 9d314a3bad3b..0e8edb5d5861 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -162,7 +162,7 @@ void mte_check_tfsr_el1(void)
 }
 #endif
 
-static void mte_update_sctlr_user(struct task_struct *task)
+static void mte_update_sctlr_user_and_gcr_excl(struct task_struct *task)
 {
 	/*
 	 * This must be called with preemption disabled and can only be called
@@ -182,6 +182,24 @@ static void mte_update_sctlr_user(struct task_struct *task)
 	else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
 		sctlr |= SCTLR_EL1_TCF0_SYNC;
 	task->thread.sctlr_user = sctlr;
+
+	/*
+	 * SYS_GCR_EL1 will be set to current->thread.mte_ctrl value by
+	 * mte_set_user_gcr() in kernel_exit, but only if KASAN is enabled.
+	 */
+	if (!kasan_hw_tags_enabled())
+		write_sysreg_s(((mte_ctrl >> MTE_CTRL_GCR_USER_EXCL_SHIFT) &
+				SYS_GCR_EL1_EXCL_MASK) | SYS_GCR_EL1_RRND,
+			       SYS_GCR_EL1);
+}
+
+void __init kasan_hw_tags_enable(struct alt_instr *alt, __le32 *origptr,
+				 __le32 *updptr, int nr_inst)
+{
+	BUG_ON(nr_inst != 1); /* Branch -> NOP */
+
+	if (kasan_hw_tags_enabled())
+		*updptr = cpu_to_le32(aarch64_insn_gen_nop());
 }
 
 void mte_thread_init_user(void)
@@ -199,7 +217,7 @@ void mte_thread_init_user(void)
 
 void mte_thread_switch(struct task_struct *next)
 {
-	mte_update_sctlr_user(next);
+	mte_update_sctlr_user_and_gcr_excl(next);
 
 	/*
 	 * Check if an async tag exception occurred at EL1.
@@ -244,7 +262,7 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
 	task->thread.mte_ctrl = mte_ctrl;
 	if (task == current) {
 		preempt_disable();
-		mte_update_sctlr_user(task);
+		mte_update_sctlr_user_and_gcr_excl(task);
 		update_sctlr_el1(task->thread.sctlr_user);
 		preempt_enable();
 	}
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index dd874a1ee862..de5f5913374d 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -89,7 +89,7 @@ static __always_inline bool kasan_enabled(void)
 	return static_branch_likely(&kasan_flag_enabled);
 }
 
-static inline bool kasan_has_integrated_init(void)
+static inline bool kasan_hw_tags_enabled(void)
 {
 	return kasan_enabled();
 }
@@ -104,7 +104,7 @@ static inline bool kasan_enabled(void)
 	return IS_ENABLED(CONFIG_KASAN);
 }
 
-static inline bool kasan_has_integrated_init(void)
+static inline bool kasan_hw_tags_enabled(void)
 {
 	return false;
 }
@@ -125,6 +125,11 @@ static __always_inline void kasan_free_pages(struct page *page,
 
 #endif /* CONFIG_KASAN_HW_TAGS */
 
+static inline bool kasan_has_integrated_init(void)
+{
+	return kasan_hw_tags_enabled();
+}
+
 #ifdef CONFIG_KASAN
 
 struct kasan_cache {
-- 
2.33.0.259.gc128427fd7-goog



From rdunlap at infradead.org  Thu Aug 26 20:17:11 2021
From: rdunlap at infradead.org (Randy Dunlap)
Date: Thu, 26 Aug 2021 20:17:11 -0700
Subject: [PATCH] maintainers: Add Alyssa Rosenzweig as M1 reviewer
In-Reply-To: <3112bc2c-7c6a-3190-26cd-a873b4029429@marcan.st>
References: <20210823151738.6273-1-alyssa@rosenzweig.io>
 <3112bc2c-7c6a-3190-26cd-a873b4029429@marcan.st>
Message-ID: <c60b3e06-1a59-927b-d567-52e9b009133a@infradead.org>

On 8/26/21 8:00 PM, Hector Martin wrote:
> On 24/08/2021 00.17, Alyssa Rosenzweig wrote:
>> Add myself as a reviewer for Asahi Linux (Apple M1) patches.
>>
>> I would like to be CC'ed on Asahi Linux patches for review and testing.
>> I am also collecting Asahi Linux patches downstream, rebasing on
>> linux-next periodically, and would like to be notified of what to
>> cherry-pick from lists.
>>
>> Signed-off-by: Alyssa Rosenzweig <alyssa at rosenzweig.io>
>> Cc: Hector Martin <marcan at marcan.st>
>> Cc: Sven Peter <sven at svenpeter.dev>
>> ---
>> ? MAINTAINERS | 2 ++
>> ? 1 file changed, 2 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index b63403793c81..399e536bf629 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1264,6 +1264,7 @@ F:??? drivers/input/mouse/bcm5974.c
>> ? APPLE DART IOMMU DRIVER
>> ? M:??? Sven Peter <sven at svenpeter.dev>
>> +R:??? Alyssa Rosenzweig <alyssa at rosenzweig.io>
>> ? L:??? iommu at lists.linux-foundation.org
>> ? S:??? Maintained
>> ? F:??? Documentation/devicetree/bindings/iommu/apple,dart.yaml
>> @@ -1693,6 +1694,7 @@ F:??? drivers/*/*alpine*
>> ? ARM/APPLE MACHINE SUPPORT
>> ? M:??? Hector Martin <marcan at marcan.st>
>> +R:??? Alyssa Rosenzweig <alyssa at rosenzweig.io>
>> ? L:??? linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>> ? S:??? Maintained
>> ? W:??? https://asahilinux.org
>>
> 
> Acked-by: Hector Martin <marcan at marcan.st>
> 
> P.S. fix your mail server, I had to pull this from the list and I doubt I'm the only one ;)

I recall seeing it, so do you have any suggestions or points
about what needs to be fixed?

thanks.
-- 
~Randy



From Chunfeng.Yun at mediatek.com  Thu Aug 26 20:23:03 2021
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Fri, 27 Aug 2021 03:23:03 +0000
Subject: [PATCH next v2 1/6] Revert "usb: xhci-mtk: relax TT periodic
 bandwidth allocation"
In-Reply-To: <YSd93+3D/PbacgsP@kroah.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
 <YSd93+3D/PbacgsP@kroah.com>
Message-ID: <a806a06ae1eea932240ff98291cca2a9c7739b16.camel@mediatek.com>

Hi Greg,
On Thu, 2021-08-26 at 13:41 +0200, Greg Kroah-Hartman wrote:
> On Thu, Aug 26, 2021 at 10:51:39AM +0800, Chunfeng Yun wrote:
> > As discussed in following patch:
> > https://patchwork.kernel.org/patch/12420339
> > 
> > No need calculate number of uframes again, but should use value
> > form check_sch_tt(), if we plan to remove extra CS, also can do
> > it in check_sch_tt(). So revert this patch, and prepare to send
> > new patch for it.
> > 
> > This reverts commit 548011957d1d72e0b662300c8b32b81d593b796e.
> > 
> > Cc: Ikjoon Jang <ikjn at chromium.org>
> > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > ---
> > v2: no changes
> 
> This series does not apply to my tree at all now, can you please
> rebase
> and resend?
Very sorry, I send out two series [1][2] for xhci-mtk, but don't take
care of conflicts, suppose that series [1] will be applied firstly, due
to one binding patch [3] of series [2] is not acked/reviewed by Rob (I
think only need modify some misleading commit message).

anyway, I find that only one patch [4] of series [1] is not applied, so
I'll fix conficts and resend it based on usb-testing branch.

Sorry again.


[1]: Series = [next,v2,1/6] Revert "usb: xhci-mtk: relax TT periodic
bandwidth allocation"
https://patchwork.kernel.org/project/linux-mediatek/list/?series=537471

[2]: Series = [RESEND,1/9] dt-bindings: usb: mtk-xhci: add optional
property to disable usb2 ports
https://patchwork.kernel.org/project/linux-mediatek/list/?series=532595

[3]:

https://patchwork.kernel.org/project/linux-mediatek/patch/1629189389-18779-2-git-send-email-chunfeng.yun at mediatek.com/
[RESEND,2/9] dt-bindings: usb: mtk-xhci: add compatible for mt8195

[4]:

https://patchwork.kernel.org/project/linux-mediatek/patch/20210826025144.51992-6-chunfeng.yun at mediatek.com/
[next,v2,6/6] usb: xhci-mtk: allow bandwidth table rollover

> 
> thanks,
> 
> greg k-h

From jk at codeconstruct.com.au  Thu Aug 26 20:20:05 2021
From: jk at codeconstruct.com.au (Jeremy Kerr)
Date: Fri, 27 Aug 2021 11:20:05 +0800
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
 <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
Message-ID: <7e7378c49ecfb21fef6a0640f92c1b3a7a5878d0.camel@codeconstruct.com.au>

Hi Chia-Wei,

[apologies for the re-send, dropping HTML part...]

> The Aspeed eSPI controller is slave device to communicate with
> the master through the Enhanced Serial Peripheral Interface (eSPI).
> All of the four eSPI channels, namely peripheral, virtual wire,
> out-of-band, and flash are supported.

Great to have this added submitted upstream! A few comments though:

> ---
> ?drivers/soc/aspeed/Kconfig???????????? |? 11 +
> ?drivers/soc/aspeed/Makefile??????????? |?? 1 +
> ?drivers/soc/aspeed/aspeed-espi-ctrl.c? | 205 +++++++++
> ?drivers/soc/aspeed/aspeed-espi-ctrl.h? | 304 ++++++++++++
> ?drivers/soc/aspeed/aspeed-espi-flash.h | 380 +++++++++++++++
> ?drivers/soc/aspeed/aspeed-espi-ioc.h?? | 153 +++++++
> ?drivers/soc/aspeed/aspeed-espi-oob.h?? | 611 +++++++++++++++++++++++++
> ?drivers/soc/aspeed/aspeed-espi-perif.h | 539 ++++++++++++++++++++++
> ?drivers/soc/aspeed/aspeed-espi-vw.h??? | 142 ++++++

This structure is a bit odd - you have the one -crtl.c file, which
defines the actual driver, but then a bunch of headers that contain more
code than header-type definitions.

Is there any reason that -flash, -ioc, -oob, -perif and -vw components
can't be standard .c files?

Then, for the userspace ABI: it looks like you're exposing everything
through new device-specific ioctls. Would it not make more sense to use
existing interfaces? For example, the virtual wire bits could be regular
GPIOs; the flash interface could be a mtd or block device.

I understand that we'll likely still need some level of custom device
control, but the more we can use generic interfaces for, the less custom
code (and interfaces) we'll need on the userspace side.

Cheers,


Jeremy




From chunfeng.yun at mediatek.com  Thu Aug 26 20:31:05 2021
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 27 Aug 2021 11:31:05 +0800
Subject: [PATCH next v3] usb: xhci-mtk: allow bandwidth table rollover
Message-ID: <20210827033105.26595-1-chunfeng.yun@mediatek.com>

xhci-mtk has 64 slots for periodic bandwidth calculations and each
slot represents byte budgets on a microframe. When an endpoint's
allocation sits on the boundary of the table, byte budgets' slot
can be rolled over but the current implementation doesn't.

This patch allows the microframe index rollover and prevent
out-of-bounds array access.

Signed-off-by: Ikjoon Jang <ikjn at chromium.org>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v3: fix conficts with usb-testing branch
v2: new patch
---
 drivers/usb/host/xhci-mtk-sch.c | 54 ++++++++++-----------------------
 drivers/usb/host/xhci-mtk.h     |  3 +-
 2 files changed, 18 insertions(+), 39 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index f0ceede85ea5..134f4789bd89 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -416,15 +416,14 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
 {
 	u32 max_bw = 0;
 	u32 bw;
-	int i;
-	int j;
+	int i, j, k;
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		u32 base = offset + i * sch_ep->esit;
 
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
-			bw = sch_bw->bus_bw[base + j] +
-					sch_ep->bw_budget_table[j];
+			k = XHCI_MTK_BW_INDEX(base + j);
+			bw = sch_bw->bus_bw[k] + sch_ep->bw_budget_table[j];
 			if (bw > max_bw)
 				max_bw = bw;
 		}
@@ -436,18 +435,16 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
 	struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	u32 base;
-	int i;
-	int j;
+	int i, j, k;
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			k = XHCI_MTK_BW_INDEX(base + j);
 			if (used)
-				sch_bw->bus_bw[base + j] +=
-					sch_ep->bw_budget_table[j];
+				sch_bw->bus_bw[k] += sch_ep->bw_budget_table[j];
 			else
-				sch_bw->bus_bw[base + j] -=
-					sch_ep->bw_budget_table[j];
+				sch_bw->bus_bw[k] -= sch_ep->bw_budget_table[j];
 		}
 	}
 }
@@ -457,7 +454,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
 	u32 tmp;
 	int base;
-	int i, j;
+	int i, j, k;
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = offset + i * sch_ep->esit;
@@ -467,7 +464,8 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset)
 		 * the hub will always delay one uframe to send data
 		 */
 		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
-			tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_budget_table[j];
+			k = XHCI_MTK_BW_INDEX(base + j);
+			tmp = tt->fs_bus_bw[k] + sch_ep->bw_budget_table[j];
 			if (tmp > FS_PAYLOAD_MAX)
 				return -ESCH_BW_OVERFLOW;
 		}
@@ -542,16 +540,18 @@ static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used)
 {
 	struct mu3h_sch_tt *tt = sch_ep->sch_tt;
 	u32 base;
-	int i, j;
+	int i, j, k;
 
 	for (i = 0; i < sch_ep->num_esit; i++) {
 		base = sch_ep->offset + i * sch_ep->esit;
 
-		for (j = 0; j < sch_ep->num_budget_microframes; j++)
+		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			k = XHCI_MTK_BW_INDEX(base + j);
 			if (used)
-				tt->fs_bus_bw[base + j] += sch_ep->bw_budget_table[j];
+				tt->fs_bus_bw[k] += sch_ep->bw_budget_table[j];
 			else
-				tt->fs_bus_bw[base + j] -= sch_ep->bw_budget_table[j];
+				tt->fs_bus_bw[k] -= sch_ep->bw_budget_table[j];
+		}
 	}
 
 	if (used)
@@ -573,27 +573,9 @@ static int load_ep_bw(struct mu3h_sch_bw_info *sch_bw,
 	return 0;
 }
 
-static u32 get_esit_boundary(struct mu3h_sch_ep_info *sch_ep)
-{
-	u32 boundary = sch_ep->esit;
-
-	if (sch_ep->sch_tt) { /* LS/FS with TT */
-		/*
-		 * tune for CS, normally esit >= 8 for FS/LS,
-		 * not add one for other types to avoid access array
-		 * out of boundary
-		 */
-		if (sch_ep->ep_type == ISOC_OUT_EP && boundary > 1)
-			boundary--;
-	}
-
-	return boundary;
-}
-
 static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 {
 	struct mu3h_sch_bw_info *sch_bw = sch_ep->bw_info;
-	const u32 esit_boundary = get_esit_boundary(sch_ep);
 	const u32 bw_boundary = get_bw_boundary(sch_ep->speed);
 	u32 offset;
 	u32 worst_bw;
@@ -606,10 +588,6 @@ static int check_sch_bw(struct mu3h_sch_ep_info *sch_ep)
 	 * and find a microframe where its worst bandwidth is minimum.
 	 */
 	for (offset = 0; offset < sch_ep->esit; offset++) {
-
-		if ((offset + sch_ep->num_budget_microframes) > esit_boundary)
-			break;
-
 		ret = check_sch_tt(sch_ep, offset);
 		if (ret)
 			continue;
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index 9c54a597e66b..4b1ea89f959a 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -25,7 +25,8 @@
  * round down to the limit value, that means allocating more
  * bandwidth to it.
  */
-#define XHCI_MTK_MAX_ESIT	64
+#define XHCI_MTK_MAX_ESIT	(1 << 6)
+#define XHCI_MTK_BW_INDEX(x)	((x) & (XHCI_MTK_MAX_ESIT - 1))
 
 /**
  * @fs_bus_bw: array to keep track of bandwidth already used for FS
-- 
2.18.0

From marcan at marcan.st  Thu Aug 26 20:47:40 2021
From: marcan at marcan.st (Hector Martin)
Date: Fri, 27 Aug 2021 12:47:40 +0900
Subject: [PATCH] maintainers: Add Alyssa Rosenzweig as M1 reviewer
In-Reply-To: <c60b3e06-1a59-927b-d567-52e9b009133a@infradead.org>
References: <20210823151738.6273-1-alyssa@rosenzweig.io>
 <3112bc2c-7c6a-3190-26cd-a873b4029429@marcan.st>
 <c60b3e06-1a59-927b-d567-52e9b009133a@infradead.org>
Message-ID: <a5bfe1ac-62c0-6b21-b37c-6e6cb667f2f7@marcan.st>

On 27/08/2021 12.17, Randy Dunlap wrote:
> On 8/26/21 8:00 PM, Hector Martin wrote:
>> P.S. fix your mail server, I had to pull this from the list and I doubt I'm the only one ;)
> 
> I recall seeing it, so do you have any suggestions or points
> about what needs to be fixed?

I already sent her the details in private, but tl;dr it has no reverse 
DNS set, which is a pretty big no-no in mail server land.

-- 
Hector Martin (marcan at marcan.st)
Public Key: https://mrcn.st/pub


From vilhelm.gray at gmail.com  Thu Aug 26 20:47:44 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:44 +0900
Subject: [PATCH v16 00/14] Introduce the Counter character device interface
Message-ID: <cover.1630031207.git.vilhelm.gray@gmail.com>

Changes in v16:
 - Define magic numbers for stm32-lptimer-cnt clock polarities
 - Define magic numbers for stm32-timer-cnt encoder modes
 - Bump KernelVersion to 5.16 in sysfs-bus-counter ABI documentation
 - Fix typos in driver API generic-counter.rst documentation file

For convenience, this patchset is also available on my personal git
repo: https://gitlab.com/vilhelmgray/iio/-/tree/counter_chrdev_v16

The patches preceding "counter: Internalize sysfs interface code" are
primarily cleanup and fixes that can be picked up and applied now to the
IIO tree if so desired. The "counter: Internalize sysfs interface code"
patch as well may be considered for pickup because it is relatively safe
and makes no changes to the userspace interface.

To summarize the main points of this patchset: there are no changes to
the existing Counter sysfs userspace interface; a Counter character
device interface is introduced that allows Counter events and associated
data to be read() by userspace; the events_configure() and
watch_validate() driver callbacks are introduced to support Counter
events; and IRQ support is added to the 104-QUAD-8 driver, serving as an
example of how to support the new Counter events functionality.

William Breathitt Gray (14):
  counter: stm32-lptimer-cnt: Provide defines for clock polarities
  counter: stm32-timer-cnt: Provide defines for slave mode selection
  counter: Internalize sysfs interface code
  counter: Update counter.h comments to reflect sysfs internalization
  docs: counter: Update to reflect sysfs internalization
  counter: Move counter enums to uapi header
  counter: Add character device interface
  docs: counter: Document character device interface
  tools/counter: Create Counter tools
  counter: Implement signalZ_action_component_id sysfs attribute
  counter: Implement *_component_id sysfs attributes
  counter: Implement events_queue_size sysfs attribute
  counter: 104-quad-8: Replace mutex with spinlock
  counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8

 Documentation/ABI/testing/sysfs-bus-counter   |   38 +-
 Documentation/driver-api/generic-counter.rst  |  358 +++-
 .../userspace-api/ioctl/ioctl-number.rst      |    1 +
 MAINTAINERS                                   |    3 +-
 drivers/counter/104-quad-8.c                  |  699 ++++----
 drivers/counter/Kconfig                       |    6 +-
 drivers/counter/Makefile                      |    1 +
 drivers/counter/counter-chrdev.c              |  553 ++++++
 drivers/counter/counter-chrdev.h              |   14 +
 drivers/counter/counter-core.c                |  191 +++
 drivers/counter/counter-sysfs.c               |  960 +++++++++++
 drivers/counter/counter-sysfs.h               |   13 +
 drivers/counter/counter.c                     | 1496 -----------------
 drivers/counter/ftm-quaddec.c                 |   60 +-
 drivers/counter/intel-qep.c                   |  144 +-
 drivers/counter/interrupt-cnt.c               |   62 +-
 drivers/counter/microchip-tcb-capture.c       |   91 +-
 drivers/counter/stm32-lptimer-cnt.c           |  212 ++-
 drivers/counter/stm32-timer-cnt.c             |  195 +--
 drivers/counter/ti-eqep.c                     |  180 +-
 include/linux/counter.h                       |  715 ++++----
 include/linux/counter_enum.h                  |   45 -
 include/linux/mfd/stm32-lptimer.h             |    5 +
 include/linux/mfd/stm32-timers.h              |    4 +
 include/uapi/linux/counter.h                  |  154 ++
 tools/Makefile                                |   13 +-
 tools/counter/Build                           |    1 +
 tools/counter/Makefile                        |   53 +
 tools/counter/counter_example.c               |   93 +
 29 files changed, 3569 insertions(+), 2791 deletions(-)
 create mode 100644 drivers/counter/counter-chrdev.c
 create mode 100644 drivers/counter/counter-chrdev.h
 create mode 100644 drivers/counter/counter-core.c
 create mode 100644 drivers/counter/counter-sysfs.c
 create mode 100644 drivers/counter/counter-sysfs.h
 delete mode 100644 drivers/counter/counter.c
 delete mode 100644 include/linux/counter_enum.h
 create mode 100644 include/uapi/linux/counter.h
 create mode 100644 tools/counter/Build
 create mode 100644 tools/counter/Makefile
 create mode 100644 tools/counter/counter_example.c


base-commit: 5ffeb17c0d3dd44704b4aee83e297ec07666e4d6
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:45 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:45 +0900
Subject: [PATCH v16 01/14] counter: stm32-lptimer-cnt: Provide defines for
 clock polarities
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <a111c8905c467805ca530728f88189b59430f27e.1630031207.git.vilhelm.gray@gmail.com>

The STM32 low-power timer permits configuration of the clock polarity
via the LPTIMX_CFGR register CKPOL bits. This patch provides
preprocessor defines for the supported clock polarities.

Cc: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/stm32-lptimer-cnt.c | 6 +++---
 include/linux/mfd/stm32-lptimer.h   | 5 +++++
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index 13656957c45f..7367f46c6f91 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -140,9 +140,9 @@ static const enum counter_function stm32_lptim_cnt_functions[] = {
 };
 
 enum stm32_lptim_synapse_action {
-	STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE,
-	STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE,
-	STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES,
+	STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE = STM32_LPTIM_CKPOL_RISING_EDGE,
+	STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE = STM32_LPTIM_CKPOL_FALLING_EDGE,
+	STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES = STM32_LPTIM_CKPOL_BOTH_EDGES,
 	STM32_LPTIM_SYNAPSE_ACTION_NONE,
 };
 
diff --git a/include/linux/mfd/stm32-lptimer.h b/include/linux/mfd/stm32-lptimer.h
index 90b20550c1c8..06d3f11dc3c9 100644
--- a/include/linux/mfd/stm32-lptimer.h
+++ b/include/linux/mfd/stm32-lptimer.h
@@ -45,6 +45,11 @@
 #define STM32_LPTIM_PRESC	GENMASK(11, 9)
 #define STM32_LPTIM_CKPOL	GENMASK(2, 1)
 
+/* STM32_LPTIM_CKPOL */
+#define STM32_LPTIM_CKPOL_RISING_EDGE	0
+#define STM32_LPTIM_CKPOL_FALLING_EDGE	1
+#define STM32_LPTIM_CKPOL_BOTH_EDGES	2
+
 /* STM32_LPTIM_ARR */
 #define STM32_LPTIM_MAX_ARR	0xFFFF
 
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:46 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:46 +0900
Subject: [PATCH v16 02/14] counter: stm32-timer-cnt: Provide defines for slave
 mode selection
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <ad3d9cd7af580d586316d368f74964cbc394f981.1630031207.git.vilhelm.gray@gmail.com>

The STM32 timer permits configuration of the counter encoder mode via
the slave mode control register (SMCR) slave mode selection (SMS) bits.
This patch provides preprocessor defines for the supported encoder
modes.

Cc: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/stm32-timer-cnt.c | 16 ++++++++--------
 include/linux/mfd/stm32-timers.h  |  4 ++++
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
index 3fb0debd7425..1fbc46f4ee66 100644
--- a/drivers/counter/stm32-timer-cnt.c
+++ b/drivers/counter/stm32-timer-cnt.c
@@ -93,16 +93,16 @@ static int stm32_count_function_get(struct counter_device *counter,
 	regmap_read(priv->regmap, TIM_SMCR, &smcr);
 
 	switch (smcr & TIM_SMCR_SMS) {
-	case 0:
+	case TIM_SMCR_SMS_SLAVE_MODE_DISABLED:
 		*function = STM32_COUNT_SLAVE_MODE_DISABLED;
 		return 0;
-	case 1:
+	case TIM_SMCR_SMS_ENCODER_MODE_1:
 		*function = STM32_COUNT_ENCODER_MODE_1;
 		return 0;
-	case 2:
+	case TIM_SMCR_SMS_ENCODER_MODE_2:
 		*function = STM32_COUNT_ENCODER_MODE_2;
 		return 0;
-	case 3:
+	case TIM_SMCR_SMS_ENCODER_MODE_3:
 		*function = STM32_COUNT_ENCODER_MODE_3;
 		return 0;
 	default:
@@ -119,16 +119,16 @@ static int stm32_count_function_set(struct counter_device *counter,
 
 	switch (function) {
 	case STM32_COUNT_SLAVE_MODE_DISABLED:
-		sms = 0;
+		sms = TIM_SMCR_SMS_SLAVE_MODE_DISABLED;
 		break;
 	case STM32_COUNT_ENCODER_MODE_1:
-		sms = 1;
+		sms = TIM_SMCR_SMS_ENCODER_MODE_1;
 		break;
 	case STM32_COUNT_ENCODER_MODE_2:
-		sms = 2;
+		sms = TIM_SMCR_SMS_ENCODER_MODE_2;
 		break;
 	case STM32_COUNT_ENCODER_MODE_3:
-		sms = 3;
+		sms = TIM_SMCR_SMS_ENCODER_MODE_3;
 		break;
 	default:
 		return -EINVAL;
diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
index f8db83aedb2b..5f5c43fd69dd 100644
--- a/include/linux/mfd/stm32-timers.h
+++ b/include/linux/mfd/stm32-timers.h
@@ -82,6 +82,10 @@
 #define MAX_TIM_ICPSC		0x3
 #define TIM_CR2_MMS_SHIFT	4
 #define TIM_CR2_MMS2_SHIFT	20
+#define TIM_SMCR_SMS_SLAVE_MODE_DISABLED	0 /* counts on internal clock when CEN=1 */
+#define TIM_SMCR_SMS_ENCODER_MODE_1		1 /* counts TI1FP1 edges, depending on TI2FP2 level */
+#define TIM_SMCR_SMS_ENCODER_MODE_2		2 /* counts TI2FP2 edges, depending on TI1FP1 level */
+#define TIM_SMCR_SMS_ENCODER_MODE_3		3 /* counts on both TI1FP1 and TI2FP2 edges */
 #define TIM_SMCR_TS_SHIFT	4
 #define TIM_BDTR_BKF_MASK	0xF
 #define TIM_BDTR_BKF_SHIFT(x)	(16 + (x) * 4)
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:48 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:48 +0900
Subject: [PATCH v16 04/14] counter: Update counter.h comments to reflect sysfs
 internalization
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <19da8ae0c05381b0967c8a334b67f86b814eb880.1630031207.git.vilhelm.gray@gmail.com>

The Counter subsystem architecture and driver implementations have
changed in order to handle Counter sysfs interactions in a more
consistent way. This patch updates the Generic Counter interface
header file comments to reflect the changes.

Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/counter-core.c |  3 ++
 include/linux/counter.h        | 62 ++++++++++++++++------------------
 2 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
index c533a6ff12cf..3cda2c47bacb 100644
--- a/drivers/counter/counter-core.c
+++ b/drivers/counter/counter-core.c
@@ -38,6 +38,9 @@ static struct bus_type counter_bus_type = {
  * This function registers a Counter to the system. A sysfs "counter" directory
  * will be created and populated with sysfs attributes correlating with the
  * Counter Signals, Synapses, and Counts respectively.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
  */
 int counter_register(struct counter_device *const counter)
 {
diff --git a/include/linux/counter.h b/include/linux/counter.h
index b69277f5c4c5..445f22d8bfe2 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -188,11 +188,10 @@ struct counter_comp {
 
 /**
  * struct counter_signal - Counter Signal node
- * @id:		unique ID used to identify signal
- * @name:	device-specific Signal name; ideally, this should match the name
- *		as it appears in the datasheet documentation
- * @ext:	optional array of Counter Signal extensions
- * @num_ext:	number of Counter Signal extensions specified in @ext
+ * @id:		unique ID used to identify the Signal
+ * @name:	device-specific Signal name
+ * @ext:	optional array of Signal extensions
+ * @num_ext:	number of Signal extensions specified in @ext
  */
 struct counter_signal {
 	int id;
@@ -206,7 +205,7 @@ struct counter_signal {
  * struct counter_synapse - Counter Synapse node
  * @actions_list:	array of available action modes
  * @num_actions:	number of action modes specified in @actions_list
- * @signal:		pointer to associated signal
+ * @signal:		pointer to the associated Signal
  */
 struct counter_synapse {
 	const enum counter_synapse_action *actions_list;
@@ -217,15 +216,14 @@ struct counter_synapse {
 
 /**
  * struct counter_count - Counter Count node
- * @id:			unique ID used to identify Count
- * @name:		device-specific Count name; ideally, this should match
- *			the name as it appears in the datasheet documentation
- * @functions_list:	array available function modes
+ * @id:			unique ID used to identify the Count
+ * @name:		device-specific Count name
+ * @functions_list:	array of available function modes
  * @num_functions:	number of function modes specified in @functions_list
- * @synapses:		array of synapses for initialization
- * @num_synapses:	number of synapses specified in @synapses
- * @ext:		optional array of Counter Count extensions
- * @num_ext:		number of Counter Count extensions specified in @ext
+ * @synapses:		array of Synapses for initialization
+ * @num_synapses:	number of Synapses specified in @synapses
+ * @ext:		optional array of Count extensions
+ * @num_ext:		number of Count extensions specified in @ext
  */
 struct counter_count {
 	int id;
@@ -243,27 +241,27 @@ struct counter_count {
 
 /**
  * struct counter_ops - Callbacks from driver
- * @signal_read:	optional read callback for Signal attribute. The read
- *			level of the respective Signal should be passed back via
- *			the level parameter.
- * @count_read:		optional read callback for Count attribute. The read
- *			value of the respective Count should be passed back via
- *			the val parameter.
- * @count_write:	optional write callback for Count attribute. The write
- *			value for the respective Count is passed in via the val
+ * @signal_read:	optional read callback for Signals. The read level of
+ *			the respective Signal should be passed back via the
+ *			level parameter.
+ * @count_read:		read callback for Counts. The read value of the
+ *			respective Count should be passed back via the value
+ *			parameter.
+ * @count_write:	optional write callback for Counts. The write value for
+ *			the respective Count is passed in via the value
  *			parameter.
  * @function_read:	read callback the Count function modes. The read
  *			function mode of the respective Count should be passed
  *			back via the function parameter.
- * @function_write:	write callback for Count function modes. The function
- *			mode to write for the respective Count is passed in via
- *			the function parameter.
- * @action_read:	read callback the Synapse action modes. The read action
- *			mode of the respective Synapse should be passed back via
- *			the action parameter.
- * @action_write:	write callback for Synapse action modes. The action mode
- *			to write for the respective Synapse is passed in via the
- *			action parameter.
+ * @function_write:	optional write callback for Count function modes. The
+ *			function mode to write for the respective Count is
+ *			passed in via the function parameter.
+ * @action_read:	optional read callback the Synapse action modes. The
+ *			read action mode of the respective Synapse should be
+ *			passed back via the action parameter.
+ * @action_write:	optional write callback for Synapse action modes. The
+ *			action mode to write for the respective Synapse is
+ *			passed in via the action parameter.
  */
 struct counter_ops {
 	int (*signal_read)(struct counter_device *counter,
@@ -291,7 +289,7 @@ struct counter_ops {
 
 /**
  * struct counter_device - Counter data structure
- * @name:		name of the device as it appears in the datasheet
+ * @name:		name of the device
  * @parent:		optional parent device providing the counters
  * @ops:		callbacks from driver
  * @signals:		array of Signals
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:49 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:49 +0900
Subject: [PATCH v16 05/14] docs: counter: Update to reflect sysfs
 internalization
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <91cded13c0145c0d3d0acfe765a2ccb6c9af7c3b.1630031207.git.vilhelm.gray@gmail.com>

The Counter subsystem architecture and driver implementations have
changed in order to handle Counter sysfs interactions in a more
consistent way. This patch updates the Generic Counter interface
documentation to reflect the changes.

Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter  |   9 +-
 Documentation/driver-api/generic-counter.rst | 243 ++++++++++++++-----
 2 files changed, 185 insertions(+), 67 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index 20fe5afd4f9e..dee79b606847 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -286,7 +286,14 @@ What:		/sys/bus/counter/devices/counterX/signalY/signal
 KernelVersion:	5.2
 Contact:	linux-iio at vger.kernel.org
 Description:
-		Signal data of Signal Y represented as a string.
+		Signal level state of Signal Y. The following signal level
+		states are available:
+
+		low:
+			Low level state.
+
+		high:
+			High level state.
 
 What:		/sys/bus/counter/devices/counterX/signalY/synchronous_mode
 KernelVersion:	5.2
diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
index 64fe7db080e5..f6397218aa4c 100644
--- a/Documentation/driver-api/generic-counter.rst
+++ b/Documentation/driver-api/generic-counter.rst
@@ -250,8 +250,8 @@ for defining a counter device.
 .. kernel-doc:: drivers/counter/counter.c
    :export:
 
-Implementation
-==============
+Driver Implementation
+=====================
 
 To support a counter device, a driver must first allocate the available
 Counter Signals via counter_signal structures. These Signals should
@@ -267,25 +267,61 @@ respective counter_count structure. These counter_count structures are
 set to the counts array member of an allocated counter_device structure
 before the Counter is registered to the system.
 
-Driver callbacks should be provided to the counter_device structure via
-a constant counter_ops structure in order to communicate with the
-device: to read and write various Signals and Counts, and to set and get
-the "action mode" and "function mode" for various Synapses and Counts
-respectively.
+Driver callbacks must be provided to the counter_device structure in
+order to communicate with the device: to read and write various Signals
+and Counts, and to set and get the "action mode" and "function mode" for
+various Synapses and Counts respectively.
 
 A defined counter_device structure may be registered to the system by
 passing it to the counter_register function, and unregistered by passing
 it to the counter_unregister function. Similarly, the
-devm_counter_register and devm_counter_unregister functions may be used
-if device memory-managed registration is desired.
-
-Extension sysfs attributes can be created for auxiliary functionality
-and data by passing in defined counter_device_ext, counter_count_ext,
-and counter_signal_ext structures. In these cases, the
-counter_device_ext structure is used for global/miscellaneous exposure
-and configuration of the respective Counter device, while the
-counter_count_ext and counter_signal_ext structures allow for auxiliary
-exposure and configuration of a specific Count or Signal respectively.
+devm_counter_register function may be used if device memory-managed
+registration is desired.
+
+The struct counter_comp structure is used to define counter extensions
+for Signals, Synapses, and Counts.
+
+The "type" member specifies the type of high-level data (e.g. BOOL,
+COUNT_DIRECTION, etc.) handled by this extension. The "``*_read``" and
+"``*_write``" members can then be set by the counter device driver with
+callbacks to handle that data using native C data types (i.e. u8, u64,
+etc.).
+
+Convenience macros such as ``COUNTER_COMP_COUNT_U64`` are provided for
+use by driver authors. In particular, driver authors are expected to use
+the provided macros for standard Counter subsystem attributes in order
+to maintain a consistent interface for userspace. For example, a counter
+device driver may define several standard attributes like so::
+
+        struct counter_comp count_ext[] = {
+                COUNTER_COMP_DIRECTION(count_direction_read),
+                COUNTER_COMP_ENABLE(count_enable_read, count_enable_write),
+                COUNTER_COMP_CEILING(count_ceiling_read, count_ceiling_write),
+        };
+
+This makes it simple to see, add, and modify the attributes that are
+supported by this driver ("direction", "enable", and "ceiling") and to
+maintain this code without getting lost in a web of struct braces.
+
+Callbacks must match the function type expected for the respective
+component or extension. These function types are defined in the struct
+counter_comp structure as the "``*_read``" and "``*_write``" union
+members.
+
+The corresponding callback prototypes for the extensions mentioned in
+the previous example above would be::
+
+        int count_direction_read(struct counter_device *counter,
+                                 struct counter_count *count,
+                                 enum counter_count_direction *direction);
+        int count_enable_read(struct counter_device *counter,
+                              struct counter_count *count, u8 *enable);
+        int count_enable_write(struct counter_device *counter,
+                               struct counter_count *count, u8 enable);
+        int count_ceiling_read(struct counter_device *counter,
+                               struct counter_count *count, u64 *ceiling);
+        int count_ceiling_write(struct counter_device *counter,
+                                struct counter_count *count, u64 ceiling);
 
 Determining the type of extension to create is a matter of scope.
 
@@ -313,52 +349,127 @@ Determining the type of extension to create is a matter of scope.
   chip overheated via a device extension called "error_overtemp":
   /sys/bus/counter/devices/counterX/error_overtemp
 
-Architecture
-============
-
-When the Generic Counter interface counter module is loaded, the
-counter_init function is called which registers a bus_type named
-"counter" to the system. Subsequently, when the module is unloaded, the
-counter_exit function is called which unregisters the bus_type named
-"counter" from the system.
-
-Counter devices are registered to the system via the counter_register
-function, and later removed via the counter_unregister function. The
-counter_register function establishes a unique ID for the Counter
-device and creates a respective sysfs directory, where X is the
-mentioned unique ID:
-
-    /sys/bus/counter/devices/counterX
-
-Sysfs attributes are created within the counterX directory to expose
-functionality, configurations, and data relating to the Counts, Signals,
-and Synapses of the Counter device, as well as options and information
-for the Counter device itself.
-
-Each Signal has a directory created to house its relevant sysfs
-attributes, where Y is the unique ID of the respective Signal:
-
-    /sys/bus/counter/devices/counterX/signalY
-
-Similarly, each Count has a directory created to house its relevant
-sysfs attributes, where Y is the unique ID of the respective Count:
-
-    /sys/bus/counter/devices/counterX/countY
-
-For a more detailed breakdown of the available Generic Counter interface
-sysfs attributes, please refer to the
-Documentation/ABI/testing/sysfs-bus-counter file.
-
-The Signals and Counts associated with the Counter device are registered
-to the system as well by the counter_register function. The
-signal_read/signal_write driver callbacks are associated with their
-respective Signal attributes, while the count_read/count_write and
-function_get/function_set driver callbacks are associated with their
-respective Count attributes; similarly, the same is true for the
-action_get/action_set driver callbacks and their respective Synapse
-attributes. If a driver callback is left undefined, then the respective
-read/write permission is left disabled for the relevant attributes.
-
-Similarly, extension sysfs attributes are created for the defined
-counter_device_ext, counter_count_ext, and counter_signal_ext
-structures that are passed in.
+Subsystem Architecture
+======================
+
+Counter drivers pass and take data natively (i.e. ``u8``, ``u64``, etc.)
+and the shared counter module handles the translation between the sysfs
+interface. This guarantees a standard userspace interface for all
+counter drivers, and enables a Generic Counter chrdev interface via a
+generalized device driver ABI.
+
+A high-level view of how a count value is passed down from a counter
+driver is exemplified by the following. The driver callbacks are first
+registered to the Counter core component for use by the Counter
+userspace interface components::
+
+        Driver callbacks registration:
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        +----------------------------+
+                        | Counter device driver      |
+                        +----------------------------+
+                        | Processes data from device |
+                        +----------------------------+
+                                |
+                         -------------------
+                        / driver callbacks /
+                        -------------------
+                                |
+                                V
+                        +----------------------+
+                        | Counter core         |
+                        +----------------------+
+                        | Routes device driver |
+                        | callbacks to the     |
+                        | userspace interfaces |
+                        +----------------------+
+                                |
+                         -------------------
+                        / driver callbacks /
+                        -------------------
+                                |
+                +---------------+
+                |
+                V
+        +--------------------+
+        | Counter sysfs      |
+        +--------------------+
+        | Translates to the  |
+        | standard Counter   |
+        | sysfs output       |
+        +--------------------+
+
+Thereafter, data can be transferred directly between the Counter device
+driver and Counter userspace interface::
+
+        Count data request:
+        ~~~~~~~~~~~~~~~~~~~
+                         ----------------------
+                        / Counter device       \
+                        +----------------------+
+                        | Count register: 0x28 |
+                        +----------------------+
+                                |
+                         -----------------
+                        / raw count data /
+                        -----------------
+                                |
+                                V
+                        +----------------------------+
+                        | Counter device driver      |
+                        +----------------------------+
+                        | Processes data from device |
+                        |----------------------------|
+                        | Type: u64                  |
+                        | Value: 42                  |
+                        +----------------------------+
+                                |
+                         ----------
+                        / u64     /
+                        ----------
+                                |
+                +---------------+
+                |
+                V
+        +--------------------+
+        | Counter sysfs      |
+        +--------------------+
+        | Translates to the  |
+        | standard Counter   |
+        | sysfs output       |
+        |--------------------|
+        | Type: const char * |
+        | Value: "42"        |
+        +--------------------+
+                |
+         ---------------
+        / const char * /
+        ---------------
+                |
+                V
+        +--------------------------------------------------+
+        | `/sys/bus/counter/devices/counterX/countY/count` |
+        +--------------------------------------------------+
+        \ Count: "42"                                      /
+         --------------------------------------------------
+
+There are three primary components involved:
+
+Counter device driver
+---------------------
+Communicates with the hardware device to read/write data; e.g. counter
+drivers for quadrature encoders, timers, etc.
+
+Counter core
+------------
+Registers the counter device driver to the system so that the respective
+callbacks are called during userspace interaction.
+
+Counter sysfs
+-------------
+Translates counter data to the standard Counter sysfs interface format
+and vice versa.
+
+Please refer to the ``Documentation/ABI/testing/sysfs-bus-counter`` file
+for a detailed breakdown of the available Generic Counter interface
+sysfs attributes.
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:50 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:50 +0900
Subject: [PATCH v16 06/14] counter: Move counter enums to uapi header
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <2d854e54adf08f72b3ff6312882e7735dc597349.1630031207.git.vilhelm.gray@gmail.com>

This is in preparation for a subsequent patch implementing a character
device interface for the Counter subsystem.

Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 MAINTAINERS                  |  1 +
 include/linux/counter.h      | 42 +--------------------------
 include/uapi/linux/counter.h | 56 ++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 41 deletions(-)
 create mode 100644 include/uapi/linux/counter.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b0cdb9aaca85..f2fdd2202605 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4781,6 +4781,7 @@ F:	Documentation/ABI/testing/sysfs-bus-counter
 F:	Documentation/driver-api/generic-counter.rst
 F:	drivers/counter/
 F:	include/linux/counter.h
+F:	include/uapi/linux/counter.h
 
 CP2615 I2C DRIVER
 M:	Bence Cs?k?s <bence98 at sch.bme.hu>
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 445f22d8bfe2..7c9f7e23953a 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -9,6 +9,7 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <uapi/linux/counter.h>
 
 struct counter_device;
 struct counter_count;
@@ -27,47 +28,6 @@ enum counter_comp_type {
 	COUNTER_COMP_COUNT_MODE,
 };
 
-enum counter_scope {
-	COUNTER_SCOPE_DEVICE,
-	COUNTER_SCOPE_SIGNAL,
-	COUNTER_SCOPE_COUNT,
-};
-
-enum counter_count_direction {
-	COUNTER_COUNT_DIRECTION_FORWARD,
-	COUNTER_COUNT_DIRECTION_BACKWARD,
-};
-
-enum counter_count_mode {
-	COUNTER_COUNT_MODE_NORMAL,
-	COUNTER_COUNT_MODE_RANGE_LIMIT,
-	COUNTER_COUNT_MODE_NON_RECYCLE,
-	COUNTER_COUNT_MODE_MODULO_N,
-};
-
-enum counter_function {
-	COUNTER_FUNCTION_INCREASE,
-	COUNTER_FUNCTION_DECREASE,
-	COUNTER_FUNCTION_PULSE_DIRECTION,
-	COUNTER_FUNCTION_QUADRATURE_X1_A,
-	COUNTER_FUNCTION_QUADRATURE_X1_B,
-	COUNTER_FUNCTION_QUADRATURE_X2_A,
-	COUNTER_FUNCTION_QUADRATURE_X2_B,
-	COUNTER_FUNCTION_QUADRATURE_X4,
-};
-
-enum counter_signal_level {
-	COUNTER_SIGNAL_LEVEL_LOW,
-	COUNTER_SIGNAL_LEVEL_HIGH,
-};
-
-enum counter_synapse_action {
-	COUNTER_SYNAPSE_ACTION_NONE,
-	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
-	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
-	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
-};
-
 /**
  * struct counter_comp - Counter component node
  * @type:		Counter component data type
diff --git a/include/uapi/linux/counter.h b/include/uapi/linux/counter.h
new file mode 100644
index 000000000000..6113938a6044
--- /dev/null
+++ b/include/uapi/linux/counter.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Userspace ABI for Counter character devices
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#ifndef _UAPI_COUNTER_H_
+#define _UAPI_COUNTER_H_
+
+/* Component scope definitions */
+enum counter_scope {
+	COUNTER_SCOPE_DEVICE,
+	COUNTER_SCOPE_SIGNAL,
+	COUNTER_SCOPE_COUNT,
+};
+
+/* Count direction values */
+enum counter_count_direction {
+	COUNTER_COUNT_DIRECTION_FORWARD,
+	COUNTER_COUNT_DIRECTION_BACKWARD,
+};
+
+/* Count mode values */
+enum counter_count_mode {
+	COUNTER_COUNT_MODE_NORMAL,
+	COUNTER_COUNT_MODE_RANGE_LIMIT,
+	COUNTER_COUNT_MODE_NON_RECYCLE,
+	COUNTER_COUNT_MODE_MODULO_N,
+};
+
+/* Count function values */
+enum counter_function {
+	COUNTER_FUNCTION_INCREASE,
+	COUNTER_FUNCTION_DECREASE,
+	COUNTER_FUNCTION_PULSE_DIRECTION,
+	COUNTER_FUNCTION_QUADRATURE_X1_A,
+	COUNTER_FUNCTION_QUADRATURE_X1_B,
+	COUNTER_FUNCTION_QUADRATURE_X2_A,
+	COUNTER_FUNCTION_QUADRATURE_X2_B,
+	COUNTER_FUNCTION_QUADRATURE_X4,
+};
+
+/* Signal values */
+enum counter_signal_level {
+	COUNTER_SIGNAL_LEVEL_LOW,
+	COUNTER_SIGNAL_LEVEL_HIGH,
+};
+
+/* Action mode values */
+enum counter_synapse_action {
+	COUNTER_SYNAPSE_ACTION_NONE,
+	COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+	COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
+	COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
+};
+
+#endif /* _UAPI_COUNTER_H_ */
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:51 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:51 +0900
Subject: [PATCH v16 07/14] counter: Add character device interface
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <422c765c91d060cdebc4f17f7aeb255d9c1a4e16.1630031207.git.vilhelm.gray@gmail.com>

This patch introduces a character device interface for the Counter
subsystem. Device data is exposed through standard character device read
operations. Device data is gathered when a Counter event is pushed by
the respective Counter device driver. Configuration is handled via ioctl
operations on the respective Counter character device node.

Cc: David Lechner <david at lechnology.com>
Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/Makefile         |   2 +-
 drivers/counter/counter-chrdev.c | 553 +++++++++++++++++++++++++++++++
 drivers/counter/counter-chrdev.h |  14 +
 drivers/counter/counter-core.c   |  60 +++-
 include/linux/counter.h          |  51 +++
 include/uapi/linux/counter.h     |  98 ++++++
 6 files changed, 770 insertions(+), 8 deletions(-)
 create mode 100644 drivers/counter/counter-chrdev.c
 create mode 100644 drivers/counter/counter-chrdev.h

diff --git a/drivers/counter/Makefile b/drivers/counter/Makefile
index 1ab7e087fdc2..8fde6c100ebc 100644
--- a/drivers/counter/Makefile
+++ b/drivers/counter/Makefile
@@ -4,7 +4,7 @@
 #
 
 obj-$(CONFIG_COUNTER) += counter.o
-counter-y := counter-core.o counter-sysfs.o
+counter-y := counter-core.o counter-sysfs.o counter-chrdev.o
 
 obj-$(CONFIG_104_QUAD_8)	+= 104-quad-8.o
 obj-$(CONFIG_INTERRUPT_CNT)		+= interrupt-cnt.o
diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c
new file mode 100644
index 000000000000..30659b67d8f3
--- /dev/null
+++ b/drivers/counter/counter-chrdev.c
@@ -0,0 +1,553 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Generic Counter character device interface
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#include <linux/bitops.h>
+#include <linux/cdev.h>
+#include <linux/counter.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/kfifo.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/nospec.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/timekeeping.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+
+#include "counter-chrdev.h"
+
+struct counter_comp_node {
+	struct list_head l;
+	struct counter_component component;
+	struct counter_comp comp;
+	void *parent;
+};
+
+static ssize_t counter_chrdev_read(struct file *filp, char __user *buf,
+				   size_t len, loff_t *f_ps)
+{
+	struct counter_device *const counter = filp->private_data;
+	int err;
+	unsigned int copied;
+
+	if (!counter->ops)
+		return -ENODEV;
+
+	if (len < sizeof(struct counter_event))
+		return -EINVAL;
+
+	do {
+		if (kfifo_is_empty(&counter->events)) {
+			if (filp->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+
+			err = wait_event_interruptible(counter->events_wait,
+					!kfifo_is_empty(&counter->events) ||
+					!counter->ops);
+			if (err < 0)
+				return err;
+			if (!counter->ops)
+				return -ENODEV;
+		}
+
+		if (mutex_lock_interruptible(&counter->events_lock))
+			return -ERESTARTSYS;
+		err = kfifo_to_user(&counter->events, buf, len, &copied);
+		mutex_unlock(&counter->events_lock);
+		if (err < 0)
+			return err;
+	} while (!copied);
+
+	return copied;
+}
+
+static __poll_t counter_chrdev_poll(struct file *filp,
+				    struct poll_table_struct *pollt)
+{
+	struct counter_device *const counter = filp->private_data;
+	__poll_t events = 0;
+
+	if (!counter->ops)
+		return events;
+
+	poll_wait(filp, &counter->events_wait, pollt);
+
+	if (!kfifo_is_empty(&counter->events))
+		events = EPOLLIN | EPOLLRDNORM;
+
+	return events;
+}
+
+static void counter_events_list_free(struct list_head *const events_list)
+{
+	struct counter_event_node *p, *n;
+	struct counter_comp_node *q, *o;
+
+	list_for_each_entry_safe(p, n, events_list, l) {
+		/* Free associated component nodes */
+		list_for_each_entry_safe(q, o, &p->comp_list, l) {
+			list_del(&q->l);
+			kfree(q);
+		}
+
+		/* Free event node */
+		list_del(&p->l);
+		kfree(p);
+	}
+}
+
+static int counter_set_event_node(struct counter_device *const counter,
+				  struct counter_watch *const watch,
+				  const struct counter_comp_node *const cfg)
+{
+	struct counter_event_node *event_node;
+	int err = 0;
+	struct counter_comp_node *comp_node;
+
+	/* Search for event in the list */
+	list_for_each_entry(event_node, &counter->next_events_list, l)
+		if (event_node->event == watch->event &&
+		    event_node->channel == watch->channel)
+			break;
+
+	/* If event is not already in the list */
+	if (&event_node->l == &counter->next_events_list) {
+		/* Allocate new event node */
+		event_node = kmalloc(sizeof(*event_node), GFP_KERNEL);
+		if (!event_node)
+			return -ENOMEM;
+
+		/* Configure event node and add to the list */
+		event_node->event = watch->event;
+		event_node->channel = watch->channel;
+		INIT_LIST_HEAD(&event_node->comp_list);
+		list_add(&event_node->l, &counter->next_events_list);
+	}
+
+	/* Check if component watch has already been set before */
+	list_for_each_entry(comp_node, &event_node->comp_list, l)
+		if (comp_node->parent == cfg->parent &&
+		    comp_node->comp.count_u8_read == cfg->comp.count_u8_read) {
+			err = -EINVAL;
+			goto exit_free_event_node;
+		}
+
+	/* Allocate component node */
+	comp_node = kmalloc(sizeof(*comp_node), GFP_KERNEL);
+	if (!comp_node) {
+		err = -ENOMEM;
+		goto exit_free_event_node;
+	}
+	*comp_node = *cfg;
+
+	/* Add component node to event node */
+	list_add_tail(&comp_node->l, &event_node->comp_list);
+
+exit_free_event_node:
+	/* Free event node if no one else is watching */
+	if (list_empty(&event_node->comp_list)) {
+		list_del(&event_node->l);
+		kfree(event_node);
+	}
+
+	return err;
+}
+
+static int counter_enable_events(struct counter_device *const counter)
+{
+	unsigned long flags;
+	int err = 0;
+
+	mutex_lock(&counter->n_events_list_lock);
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	counter_events_list_free(&counter->events_list);
+	list_replace_init(&counter->next_events_list,
+			  &counter->events_list);
+
+	if (counter->ops->events_configure)
+		err = counter->ops->events_configure(counter);
+
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static int counter_disable_events(struct counter_device *const counter)
+{
+	unsigned long flags;
+	int err = 0;
+
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	counter_events_list_free(&counter->events_list);
+
+	if (counter->ops->events_configure)
+		err = counter->ops->events_configure(counter);
+
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+
+	mutex_lock(&counter->n_events_list_lock);
+
+	counter_events_list_free(&counter->next_events_list);
+
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static int counter_add_watch(struct counter_device *const counter,
+			     const unsigned long arg)
+{
+	void __user *const uwatch = (void __user *)arg;
+	struct counter_watch watch;
+	struct counter_comp_node comp_node = {};
+	size_t parent, id;
+	struct counter_comp *ext;
+	size_t num_ext;
+	int err = 0;
+
+	if (copy_from_user(&watch, uwatch, sizeof(watch)))
+		return -EFAULT;
+
+	if (watch.component.type == COUNTER_COMPONENT_NONE)
+		goto no_component;
+
+	parent = watch.component.parent;
+
+	/* Configure parent component info for comp node */
+	switch (watch.component.scope) {
+	case COUNTER_SCOPE_DEVICE:
+		ext = counter->ext;
+		num_ext = counter->num_ext;
+		break;
+	case COUNTER_SCOPE_SIGNAL:
+		if (parent >= counter->num_signals)
+			return -EINVAL;
+		parent = array_index_nospec(parent, counter->num_signals);
+
+		comp_node.parent = counter->signals + parent;
+
+		ext = counter->signals[parent].ext;
+		num_ext = counter->signals[parent].num_ext;
+		break;
+	case COUNTER_SCOPE_COUNT:
+		if (parent >= counter->num_counts)
+			return -EINVAL;
+		parent = array_index_nospec(parent, counter->num_counts);
+
+		comp_node.parent = counter->counts + parent;
+
+		ext = counter->counts[parent].ext;
+		num_ext = counter->counts[parent].num_ext;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	id = watch.component.id;
+
+	/* Configure component info for comp node */
+	switch (watch.component.type) {
+	case COUNTER_COMPONENT_SIGNAL:
+		if (watch.component.scope != COUNTER_SCOPE_SIGNAL)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_SIGNAL_LEVEL;
+		comp_node.comp.signal_u32_read = counter->ops->signal_read;
+		break;
+	case COUNTER_COMPONENT_COUNT:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_U64;
+		comp_node.comp.count_u64_read = counter->ops->count_read;
+		break;
+	case COUNTER_COMPONENT_FUNCTION:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+
+		comp_node.comp.type = COUNTER_COMP_FUNCTION;
+		comp_node.comp.count_u32_read = counter->ops->function_read;
+		break;
+	case COUNTER_COMPONENT_SYNAPSE_ACTION:
+		if (watch.component.scope != COUNTER_SCOPE_COUNT)
+			return -EINVAL;
+		if (id >= counter->counts[parent].num_synapses)
+			return -EINVAL;
+		id = array_index_nospec(id, counter->counts[parent].num_synapses);
+
+		comp_node.comp.type = COUNTER_COMP_SYNAPSE_ACTION;
+		comp_node.comp.action_read = counter->ops->action_read;
+		comp_node.comp.priv = counter->counts[parent].synapses + id;
+		break;
+	case COUNTER_COMPONENT_EXTENSION:
+		if (id >= num_ext)
+			return -EINVAL;
+		id = array_index_nospec(id, num_ext);
+
+		comp_node.comp = ext[id];
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* Check if any read callback is set; this is part of a union */
+	if (!comp_node.comp.count_u8_read)
+		return -EOPNOTSUPP;
+
+no_component:
+	mutex_lock(&counter->n_events_list_lock);
+
+	if (counter->ops->watch_validate) {
+		err = counter->ops->watch_validate(counter, &watch);
+		if (err < 0)
+			goto err_exit;
+	}
+
+	comp_node.component = watch.component;
+
+	err = counter_set_event_node(counter, &watch, &comp_node);
+
+err_exit:
+	mutex_unlock(&counter->n_events_list_lock);
+
+	return err;
+}
+
+static long counter_chrdev_ioctl(struct file *filp, unsigned int cmd,
+				 unsigned long arg)
+{
+	struct counter_device *const counter = filp->private_data;
+	int ret = -ENODEV;
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	if (!counter->ops)
+		goto out_unlock;
+
+	switch (cmd) {
+	case COUNTER_ADD_WATCH_IOCTL:
+		ret = counter_add_watch(counter, arg);
+		break;
+	case COUNTER_ENABLE_EVENTS_IOCTL:
+		ret = counter_enable_events(counter);
+		break;
+	case COUNTER_DISABLE_EVENTS_IOCTL:
+		ret = counter_disable_events(counter);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+out_unlock:
+	mutex_unlock(&counter->ops_exist_lock);
+
+	return ret;
+}
+
+static int counter_chrdev_open(struct inode *inode, struct file *filp)
+{
+	struct counter_device *const counter = container_of(inode->i_cdev,
+							    typeof(*counter),
+							    chrdev);
+
+	if (test_and_set_bit_lock(0, counter->chrdev_lock))
+		return -EBUSY;
+
+	get_device(&counter->dev);
+	filp->private_data = counter;
+
+	return nonseekable_open(inode, filp);
+}
+
+static int counter_chrdev_release(struct inode *inode, struct file *filp)
+{
+	struct counter_device *const counter = filp->private_data;
+	int ret = 0;
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	if (!counter->ops) {
+		counter_events_list_free(&counter->events_list);
+		counter_events_list_free(&counter->next_events_list);
+		ret = -ENODEV;
+		goto out_unlock;
+	}
+
+	ret = counter_disable_events(counter);
+	if (ret < 0) {
+		mutex_unlock(&counter->ops_exist_lock);
+		return ret;
+	}
+
+out_unlock:
+	mutex_unlock(&counter->ops_exist_lock);
+
+	put_device(&counter->dev);
+	clear_bit_unlock(0, counter->chrdev_lock);
+
+	return ret;
+}
+
+static const struct file_operations counter_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.read = counter_chrdev_read,
+	.poll = counter_chrdev_poll,
+	.unlocked_ioctl = counter_chrdev_ioctl,
+	.open = counter_chrdev_open,
+	.release = counter_chrdev_release,
+};
+
+int counter_chrdev_add(struct counter_device *const counter)
+{
+	/* Initialize Counter events lists */
+	INIT_LIST_HEAD(&counter->events_list);
+	INIT_LIST_HEAD(&counter->next_events_list);
+	spin_lock_init(&counter->events_list_lock);
+	mutex_init(&counter->n_events_list_lock);
+	init_waitqueue_head(&counter->events_wait);
+	mutex_init(&counter->events_lock);
+
+	/* Initialize character device */
+	clear_bit(0, counter->chrdev_lock);
+	cdev_init(&counter->chrdev, &counter_fops);
+
+	/* Allocate Counter events queue */
+	return kfifo_alloc(&counter->events, 64, GFP_KERNEL);
+}
+
+void counter_chrdev_remove(struct counter_device *const counter)
+{
+	kfifo_free(&counter->events);
+}
+
+static int counter_get_data(struct counter_device *const counter,
+			    const struct counter_comp_node *const comp_node,
+			    u64 *const value)
+{
+	const struct counter_comp *const comp = &comp_node->comp;
+	void *const parent = comp_node->parent;
+	u8 value_u8 = 0;
+	u32 value_u32 = 0;
+	int ret;
+
+	if (comp_node->component.type == COUNTER_COMPONENT_NONE)
+		return 0;
+
+	switch (comp->type) {
+	case COUNTER_COMP_U8:
+	case COUNTER_COMP_BOOL:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			ret = comp->device_u8_read(counter, &value_u8);
+			break;
+		case COUNTER_SCOPE_SIGNAL:
+			ret = comp->signal_u8_read(counter, parent, &value_u8);
+			break;
+		case COUNTER_SCOPE_COUNT:
+			ret = comp->count_u8_read(counter, parent, &value_u8);
+			break;
+		}
+		*value = value_u8;
+		return ret;
+	case COUNTER_COMP_SIGNAL_LEVEL:
+	case COUNTER_COMP_FUNCTION:
+	case COUNTER_COMP_ENUM:
+	case COUNTER_COMP_COUNT_DIRECTION:
+	case COUNTER_COMP_COUNT_MODE:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			ret = comp->device_u32_read(counter, &value_u32);
+			break;
+		case COUNTER_SCOPE_SIGNAL:
+			ret = comp->signal_u32_read(counter, parent,
+						    &value_u32);
+			break;
+		case COUNTER_SCOPE_COUNT:
+			ret = comp->count_u32_read(counter, parent, &value_u32);
+			break;
+		}
+		*value = value_u32;
+		return ret;
+	case COUNTER_COMP_U64:
+		switch (comp_node->component.scope) {
+		case COUNTER_SCOPE_DEVICE:
+			return comp->device_u64_read(counter, value);
+		case COUNTER_SCOPE_SIGNAL:
+			return comp->signal_u64_read(counter, parent, value);
+		case COUNTER_SCOPE_COUNT:
+			return comp->count_u64_read(counter, parent, value);
+		default:
+			return -EINVAL;
+		}
+	case COUNTER_COMP_SYNAPSE_ACTION:
+		ret = comp->action_read(counter, parent, comp->priv,
+					&value_u32);
+		*value = value_u32;
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ * counter_push_event - queue event for userspace reading
+ * @counter:	pointer to Counter structure
+ * @event:	triggered event
+ * @channel:	event channel
+ *
+ * Note: If no one is watching for the respective event, it is silently
+ * discarded.
+ */
+void counter_push_event(struct counter_device *const counter, const u8 event,
+			const u8 channel)
+{
+	struct counter_event ev;
+	unsigned int copied = 0;
+	unsigned long flags;
+	struct counter_event_node *event_node;
+	struct counter_comp_node *comp_node;
+
+	ev.timestamp = ktime_get_ns();
+	ev.watch.event = event;
+	ev.watch.channel = channel;
+
+	/* Could be in an interrupt context, so use a spin lock */
+	spin_lock_irqsave(&counter->events_list_lock, flags);
+
+	/* Search for event in the list */
+	list_for_each_entry(event_node, &counter->events_list, l)
+		if (event_node->event == event &&
+		    event_node->channel == channel)
+			break;
+
+	/* If event is not in the list */
+	if (&event_node->l == &counter->events_list)
+		goto exit_early;
+
+	/* Read and queue relevant comp for userspace */
+	list_for_each_entry(comp_node, &event_node->comp_list, l) {
+		ev.watch.component = comp_node->component;
+		ev.status = -counter_get_data(counter, comp_node, &ev.value);
+
+		copied += kfifo_in(&counter->events, &ev, 1);
+	}
+
+exit_early:
+	spin_unlock_irqrestore(&counter->events_list_lock, flags);
+
+	if (copied)
+		wake_up_poll(&counter->events_wait, EPOLLIN);
+}
+EXPORT_SYMBOL_GPL(counter_push_event);
diff --git a/drivers/counter/counter-chrdev.h b/drivers/counter/counter-chrdev.h
new file mode 100644
index 000000000000..5529d16703c4
--- /dev/null
+++ b/drivers/counter/counter-chrdev.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Counter character device interface
+ * Copyright (C) 2020 William Breathitt Gray
+ */
+#ifndef _COUNTER_CHRDEV_H_
+#define _COUNTER_CHRDEV_H_
+
+#include <linux/counter.h>
+
+int counter_chrdev_add(struct counter_device *const counter);
+void counter_chrdev_remove(struct counter_device *const counter);
+
+#endif /* _COUNTER_CHRDEV_H_ */
diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c
index 3cda2c47bacb..28dc1ff63c94 100644
--- a/drivers/counter/counter-core.c
+++ b/drivers/counter/counter-core.c
@@ -3,14 +3,22 @@
  * Generic Counter interface
  * Copyright (C) 2020 William Breathitt Gray
  */
+#include <linux/cdev.h>
 #include <linux/counter.h>
 #include <linux/device.h>
+#include <linux/device/bus.h>
 #include <linux/export.h>
+#include <linux/fs.h>
 #include <linux/gfp.h>
 #include <linux/idr.h>
 #include <linux/init.h>
+#include <linux/kdev_t.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/wait.h>
 
+#include "counter-chrdev.h"
 #include "counter-sysfs.h"
 
 /* Provides a unique ID for each counter device */
@@ -18,6 +26,9 @@ static DEFINE_IDA(counter_ida);
 
 static void counter_device_release(struct device *dev)
 {
+	struct counter_device *const counter = dev_get_drvdata(dev);
+
+	counter_chrdev_remove(counter);
 	ida_free(&counter_ida, dev->id);
 }
 
@@ -31,6 +42,8 @@ static struct bus_type counter_bus_type = {
 	.dev_name = "counter",
 };
 
+static dev_t counter_devt;
+
 /**
  * counter_register - register Counter to the system
  * @counter:	pointer to Counter to register
@@ -53,10 +66,13 @@ int counter_register(struct counter_device *const counter)
 	if (id < 0)
 		return id;
 
+	mutex_init(&counter->ops_exist_lock);
+
 	/* Configure device structure for Counter */
 	dev->id = id;
 	dev->type = &counter_device_type;
 	dev->bus = &counter_bus_type;
+	dev->devt = MKDEV(MAJOR(counter_devt), id);
 	if (counter->parent) {
 		dev->parent = counter->parent;
 		dev->of_node = counter->parent->of_node;
@@ -64,18 +80,22 @@ int counter_register(struct counter_device *const counter)
 	device_initialize(dev);
 	dev_set_drvdata(dev, counter);
 
-	/* Add Counter sysfs attributes */
-	err = counter_sysfs_add(counter);
+	err = counter_chrdev_add(counter);
 	if (err < 0)
 		goto err_free_id;
 
-	/* Add device to system */
-	err = device_add(dev);
+	err = counter_sysfs_add(counter);
 	if (err < 0)
-		goto err_free_id;
+		goto err_remove_chrdev;
+
+	err = cdev_device_add(&counter->chrdev, dev);
+	if (err < 0)
+		goto err_remove_chrdev;
 
 	return 0;
 
+err_remove_chrdev:
+	counter_chrdev_remove(counter);
 err_free_id:
 	put_device(dev);
 	return err;
@@ -93,7 +113,16 @@ void counter_unregister(struct counter_device *const counter)
 	if (!counter)
 		return;
 
-	device_unregister(&counter->dev);
+	cdev_device_del(&counter->chrdev, &counter->dev);
+
+	mutex_lock(&counter->ops_exist_lock);
+
+	counter->ops = NULL;
+	wake_up(&counter->events_wait);
+
+	mutex_unlock(&counter->ops_exist_lock);
+
+	put_device(&counter->dev);
 }
 EXPORT_SYMBOL_GPL(counter_unregister);
 
@@ -127,13 +156,30 @@ int devm_counter_register(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_counter_register);
 
+#define COUNTER_DEV_MAX 256
+
 static int __init counter_init(void)
 {
-	return bus_register(&counter_bus_type);
+	int err;
+
+	err = bus_register(&counter_bus_type);
+	if (err < 0)
+		return err;
+
+	err = alloc_chrdev_region(&counter_devt, 0, COUNTER_DEV_MAX, "counter");
+	if (err < 0)
+		goto err_unregister_bus;
+
+	return 0;
+
+err_unregister_bus:
+	bus_unregister(&counter_bus_type);
+	return err;
 }
 
 static void __exit counter_exit(void)
 {
+	unregister_chrdev_region(counter_devt, COUNTER_DEV_MAX);
 	bus_unregister(&counter_bus_type);
 }
 
diff --git a/include/linux/counter.h b/include/linux/counter.h
index 7c9f7e23953a..9c9984655f8c 100644
--- a/include/linux/counter.h
+++ b/include/linux/counter.h
@@ -6,9 +6,14 @@
 #ifndef _COUNTER_H_
 #define _COUNTER_H_
 
+#include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/kfifo.h>
+#include <linux/mutex.h>
+#include <linux/spinlock_types.h>
 #include <linux/types.h>
+#include <linux/wait.h>
 #include <uapi/linux/counter.h>
 
 struct counter_device;
@@ -199,6 +204,20 @@ struct counter_count {
 	size_t num_ext;
 };
 
+/**
+ * struct counter_event_node - Counter Event node
+ * @l:		list of current watching Counter events
+ * @event:	event that triggers
+ * @channel:	event channel
+ * @comp_list:	list of components to watch when event triggers
+ */
+struct counter_event_node {
+	struct list_head l;
+	u8 event;
+	u8 channel;
+	struct list_head comp_list;
+};
+
 /**
  * struct counter_ops - Callbacks from driver
  * @signal_read:	optional read callback for Signals. The read level of
@@ -222,6 +241,13 @@ struct counter_count {
  * @action_write:	optional write callback for Synapse action modes. The
  *			action mode to write for the respective Synapse is
  *			passed in via the action parameter.
+ * @events_configure:	optional write callback to configure events. The list of
+ *			struct counter_event_node may be accessed via the
+ *			events_list member of the counter parameter.
+ * @watch_validate:	optional callback to validate a watch. The Counter
+ *			component watch configuration is passed in via the watch
+ *			parameter. A return value of 0 indicates a valid Counter
+ *			component watch configuration.
  */
 struct counter_ops {
 	int (*signal_read)(struct counter_device *counter,
@@ -245,6 +271,9 @@ struct counter_ops {
 			    struct counter_count *count,
 			    struct counter_synapse *synapse,
 			    enum counter_synapse_action action);
+	int (*events_configure)(struct counter_device *counter);
+	int (*watch_validate)(struct counter_device *counter,
+			      const struct counter_watch *watch);
 };
 
 /**
@@ -260,6 +289,16 @@ struct counter_ops {
  * @num_ext:		number of Counter device extensions specified in @ext
  * @priv:		optional private data supplied by driver
  * @dev:		internal device structure
+ * @chrdev:		internal character device structure
+ * @events_list:	list of current watching Counter events
+ * @events_list_lock:	lock to protect Counter events list operations
+ * @next_events_list:	list of next watching Counter events
+ * @n_events_list_lock:	lock to protect Counter next events list operations
+ * @events:		queue of detected Counter events
+ * @events_wait:	wait queue to allow blocking reads of Counter events
+ * @events_lock:	lock to protect Counter events queue read operations
+ * @chrdev_lock:	lock to limit chrdev to a single open at a time
+ * @ops_exist_lock:	lock to prevent use during removal
  */
 struct counter_device {
 	const char *name;
@@ -278,12 +317,24 @@ struct counter_device {
 	void *priv;
 
 	struct device dev;
+	struct cdev chrdev;
+	struct list_head events_list;
+	spinlock_t events_list_lock;
+	struct list_head next_events_list;
+	struct mutex n_events_list_lock;
+	DECLARE_KFIFO_PTR(events, struct counter_event);
+	wait_queue_head_t events_wait;
+	struct mutex events_lock;
+	DECLARE_BITMAP(chrdev_lock, 1);
+	struct mutex ops_exist_lock;
 };
 
 int counter_register(struct counter_device *const counter);
 void counter_unregister(struct counter_device *const counter);
 int devm_counter_register(struct device *dev,
 			  struct counter_device *const counter);
+void counter_push_event(struct counter_device *const counter, const u8 event,
+			const u8 channel);
 
 #define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \
 { \
diff --git a/include/uapi/linux/counter.h b/include/uapi/linux/counter.h
index 6113938a6044..d0aa95aeff7b 100644
--- a/include/uapi/linux/counter.h
+++ b/include/uapi/linux/counter.h
@@ -6,6 +6,19 @@
 #ifndef _UAPI_COUNTER_H_
 #define _UAPI_COUNTER_H_
 
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/* Component type definitions */
+enum counter_component_type {
+	COUNTER_COMPONENT_NONE,
+	COUNTER_COMPONENT_SIGNAL,
+	COUNTER_COMPONENT_COUNT,
+	COUNTER_COMPONENT_FUNCTION,
+	COUNTER_COMPONENT_SYNAPSE_ACTION,
+	COUNTER_COMPONENT_EXTENSION,
+};
+
 /* Component scope definitions */
 enum counter_scope {
 	COUNTER_SCOPE_DEVICE,
@@ -13,6 +26,91 @@ enum counter_scope {
 	COUNTER_SCOPE_COUNT,
 };
 
+/**
+ * struct counter_component - Counter component identification
+ * @type: component type (one of enum counter_component_type)
+ * @scope: component scope (one of enum counter_scope)
+ * @parent: parent ID (matching the ID suffix of the respective parent sysfs
+ *          path as described by the ABI documentation file
+ *          Documentation/ABI/testing/sysfs-bus-counter)
+ * @id: component ID (matching the ID provided by the respective *_component_id
+ *      sysfs attribute of the desired component)
+ *
+ * For example, if the Count 2 ceiling extension of Counter device 4 is desired,
+ * set type equal to COUNTER_COMPONENT_EXTENSION, scope equal to
+ * COUNTER_COUNT_SCOPE, parent equal to 2, and id equal to the value provided by
+ * the respective /sys/bus/counter/devices/counter4/count2/ceiling_component_id
+ * sysfs attribute.
+ */
+struct counter_component {
+	__u8 type;
+	__u8 scope;
+	__u8 parent;
+	__u8 id;
+};
+
+/* Event type definitions */
+enum counter_event_type {
+	/* Count value increased past ceiling */
+	COUNTER_EVENT_OVERFLOW,
+	/* Count value decreased past floor */
+	COUNTER_EVENT_UNDERFLOW,
+	/* Count value increased past ceiling, or decreased past floor */
+	COUNTER_EVENT_OVERFLOW_UNDERFLOW,
+	/* Count value reached threshold */
+	COUNTER_EVENT_THRESHOLD,
+	/* Index signal detected */
+	COUNTER_EVENT_INDEX,
+};
+
+/**
+ * struct counter_watch - Counter component watch configuration
+ * @component: component to watch when event triggers
+ * @event: event that triggers (one of enum counter_event_type)
+ * @channel: event channel (typically 0 unless the device supports concurrent
+ *	     events of the same type)
+ */
+struct counter_watch {
+	struct counter_component component;
+	__u8 event;
+	__u8 channel;
+};
+
+/*
+ * Queues a Counter watch for the specified event.
+ *
+ * The queued watches will not be applied until COUNTER_ENABLE_EVENTS_IOCTL is
+ * called.
+ */
+#define COUNTER_ADD_WATCH_IOCTL _IOW(0x3E, 0x00, struct counter_watch)
+/*
+ * Enables monitoring the events specified by the Counter watches that were
+ * queued by COUNTER_ADD_WATCH_IOCTL.
+ *
+ * If events are already enabled, the new set of watches replaces the old one.
+ * Calling this ioctl also has the effect of clearing the queue of watches added
+ * by COUNTER_ADD_WATCH_IOCTL.
+ */
+#define COUNTER_ENABLE_EVENTS_IOCTL _IO(0x3E, 0x01)
+/*
+ * Stops monitoring the previously enabled events.
+ */
+#define COUNTER_DISABLE_EVENTS_IOCTL _IO(0x3E, 0x02)
+
+/**
+ * struct counter_event - Counter event data
+ * @timestamp: best estimate of time of event occurrence, in nanoseconds
+ * @value: component value
+ * @watch: component watch configuration
+ * @status: return status (system error number)
+ */
+struct counter_event {
+	__aligned_u64 timestamp;
+	__aligned_u64 value;
+	struct counter_watch watch;
+	__u8 status;
+};
+
 /* Count direction values */
 enum counter_count_direction {
 	COUNTER_COUNT_DIRECTION_FORWARD,
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:52 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:52 +0900
Subject: [PATCH v16 08/14] docs: counter: Document character device interface
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <532bd59e88d9bc6e4d1c323744b78ce137ff5c6a.1630031207.git.vilhelm.gray@gmail.com>

This patch adds high-level documentation about the Counter subsystem
character device interface.

Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/driver-api/generic-counter.rst  | 177 ++++++++++++++----
 .../userspace-api/ioctl/ioctl-number.rst      |   1 +
 2 files changed, 137 insertions(+), 41 deletions(-)

diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
index f6397218aa4c..6ecb5d1942c7 100644
--- a/Documentation/driver-api/generic-counter.rst
+++ b/Documentation/driver-api/generic-counter.rst
@@ -223,19 +223,6 @@ whether an input line is differential or single-ended) and instead focus
 on the core idea of what the data and process represent (e.g. position
 as interpreted from quadrature encoding data).
 
-Userspace Interface
-===================
-
-Several sysfs attributes are generated by the Generic Counter interface,
-and reside under the /sys/bus/counter/devices/counterX directory, where
-counterX refers to the respective counter device. Please see
-Documentation/ABI/testing/sysfs-bus-counter for detailed
-information on each Generic Counter interface sysfs attribute.
-
-Through these sysfs attributes, programs and scripts may interact with
-the Generic Counter paradigm Counts, Signals, and Synapses of respective
-counter devices.
-
 Driver API
 ==========
 
@@ -388,16 +375,16 @@ userspace interface components::
                         / driver callbacks /
                         -------------------
                                 |
-                +---------------+
-                |
-                V
-        +--------------------+
-        | Counter sysfs      |
-        +--------------------+
-        | Translates to the  |
-        | standard Counter   |
-        | sysfs output       |
-        +--------------------+
+                +---------------+---------------+
+                |                               |
+                V                               V
+        +--------------------+          +---------------------+
+        | Counter sysfs      |          | Counter chrdev      |
+        +--------------------+          +---------------------+
+        | Translates to the  |          | Translates to the   |
+        | standard Counter   |          | standard Counter    |
+        | sysfs output       |          | character device    |
+        +--------------------+          +---------------------+
 
 Thereafter, data can be transferred directly between the Counter device
 driver and Counter userspace interface::
@@ -428,23 +415,30 @@ driver and Counter userspace interface::
                         / u64     /
                         ----------
                                 |
-                +---------------+
-                |
-                V
-        +--------------------+
-        | Counter sysfs      |
-        +--------------------+
-        | Translates to the  |
-        | standard Counter   |
-        | sysfs output       |
-        |--------------------|
-        | Type: const char * |
-        | Value: "42"        |
-        +--------------------+
-                |
-         ---------------
-        / const char * /
-        ---------------
+                +---------------+---------------+
+                |                               |
+                V                               V
+        +--------------------+          +---------------------+
+        | Counter sysfs      |          | Counter chrdev      |
+        +--------------------+          +---------------------+
+        | Translates to the  |          | Translates to the   |
+        | standard Counter   |          | standard Counter    |
+        | sysfs output       |          | character device    |
+        |--------------------|          |---------------------|
+        | Type: const char * |          | Type: u64           |
+        | Value: "42"        |          | Value: 42           |
+        +--------------------+          +---------------------+
+                |                               |
+         ---------------                 -----------------------
+        / const char * /                / struct counter_event /
+        ---------------                 -----------------------
+                |                               |
+                |                               V
+                |                       +-----------+
+                |                       | read      |
+                |                       +-----------+
+                |                       \ Count: 42 /
+                |                        -----------
                 |
                 V
         +--------------------------------------------------+
@@ -453,7 +447,7 @@ driver and Counter userspace interface::
         \ Count: "42"                                      /
          --------------------------------------------------
 
-There are three primary components involved:
+There are four primary components involved:
 
 Counter device driver
 ---------------------
@@ -473,3 +467,104 @@ and vice versa.
 Please refer to the ``Documentation/ABI/testing/sysfs-bus-counter`` file
 for a detailed breakdown of the available Generic Counter interface
 sysfs attributes.
+
+Counter chrdev
+--------------
+Translates counter data to the standard Counter character device; data
+is transferred via standard character device read calls, while Counter
+events are configured via ioctl calls.
+
+Sysfs Interface
+===============
+
+Several sysfs attributes are generated by the Generic Counter interface,
+and reside under the ``/sys/bus/counter/devices/counterX`` directory,
+where ``X`` is to the respective counter device id. Please see
+``Documentation/ABI/testing/sysfs-bus-counter`` for detailed information
+on each Generic Counter interface sysfs attribute.
+
+Through these sysfs attributes, programs and scripts may interact with
+the Generic Counter paradigm Counts, Signals, and Synapses of respective
+counter devices.
+
+Counter Character Device
+========================
+
+Counter character device nodes are created under the ``/dev`` directory
+as ``counterX``, where ``X`` is the respective counter device id.
+Defines for the standard Counter data types are exposed via the
+userspace ``include/uapi/linux/counter.h`` file.
+
+Counter events
+--------------
+Counter device drivers can support Counter events by utilizing the
+``counter_push_event`` function::
+
+        void counter_push_event(struct counter_device *const counter, const u8 event,
+                                const u8 channel);
+
+The event id is specified by the ``event`` parameter; the event channel
+id is specified by the ``channel`` parameter. When this function is
+called, the Counter data associated with the respective event is
+gathered, and a ``struct counter_event`` is generated for each datum and
+pushed to userspace.
+
+Counter events can be configured by users to report various Counter
+data of interest. This can be conceptualized as a list of Counter
+component read calls to perform. For example:
+
+        +------------------------+------------------------+
+        | COUNTER_EVENT_OVERFLOW | COUNTER_EVENT_INDEX    |
+        +========================+========================+
+        | Channel 0              | Channel 0              |
+        +------------------------+------------------------+
+        | * Count 0              | * Signal 0             |
+        | * Count 1              | * Signal 0 Extension 0 |
+        | * Signal 3             | * Extension 4          |
+        | * Count 4 Extension 2  +------------------------+
+        | * Signal 5 Extension 0 | Channel 1              |
+        |                        +------------------------+
+        |                        | * Signal 4             |
+        |                        | * Signal 4 Extension 0 |
+        |                        | * Count 7              |
+        +------------------------+------------------------+
+
+When ``counter_push_event(counter, COUNTER_EVENT_INDEX, 1)`` is called
+for example, it will go down the list for the ``COUNTER_EVENT_INDEX``
+event channel 1 and execute the read callbacks for Signal 4, Signal 4
+Extension 0, and Count 7 -- the data returned for each is pushed to a
+kfifo as a ``struct counter_event``, which userspace can retrieve via a
+standard read operation on the respective character device node.
+
+Userspace
+---------
+Userspace applications can configure Counter events via ioctl operations
+on the Counter character device node. There following ioctl codes are
+supported and provided by the ``linux/counter.h`` userspace header file:
+
+* :c:macro:`COUNTER_ADD_WATCH_IOCTL`
+
+* :c:macro:`COUNTER_ENABLE_EVENTS_IOCTL`
+
+* :c:macro:`COUNTER_DISABLE_EVENTS_IOCTL`
+
+To configure events to gather Counter data, users first populate a
+``struct counter_watch`` with the relevant event id, event channel id,
+and the information for the desired Counter component from which to
+read, and then pass it via the ``COUNTER_ADD_WATCH_IOCTL`` ioctl
+command.
+
+Note that an event can be watched without gathering Counter data by
+setting the ``component.type`` member equal to
+``COUNTER_COMPONENT_NONE``. With this configuration the Counter
+character device will simply populate the event timestamps for those
+respective ``struct counter_event`` elements and ignore the component
+value.
+
+The ``COUNTER_ADD_WATCH_IOCTL`` command will buffer these Counter
+watches. When ready, the ``COUNTER_ENABLE_EVENTS_IOCTL`` ioctl command
+may be used to activate these Counter watches.
+
+Userspace applications can then execute a ``read`` operation (optionally
+calling ``poll`` first) on the Counter character device node to retrieve
+``struct counter_event`` elements with the desired data.
diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
index 1409e40e6345..fc4ccc79b1b8 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -88,6 +88,7 @@ Code  Seq#    Include File                                           Comments
                                                                      <http://infiniband.sourceforge.net/>
 0x20  all    drivers/cdrom/cm206.h
 0x22  all    scsi/sg.h
+0x3E  00-0F  linux/counter.h                                         <mailto:linux-iio at vger.kernel.org>
 '!'   00-1F  uapi/linux/seccomp.h
 '#'   00-3F                                                          IEEE 1394 Subsystem
                                                                      Block for the entire subsystem
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:53 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:53 +0900
Subject: [PATCH v16 09/14] tools/counter: Create Counter tools
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <7fb22281fde0874614a87b0a000b2bf27e17043e.1630031207.git.vilhelm.gray@gmail.com>

This creates an example Counter program under tools/counter/*
to exemplify the Counter character device interface.

Cc: Pavel Machek <pavel at ucw.cz>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 MAINTAINERS                     |  1 +
 tools/Makefile                  | 13 ++---
 tools/counter/Build             |  1 +
 tools/counter/Makefile          | 53 +++++++++++++++++++
 tools/counter/counter_example.c | 93 +++++++++++++++++++++++++++++++++
 5 files changed, 155 insertions(+), 6 deletions(-)
 create mode 100644 tools/counter/Build
 create mode 100644 tools/counter/Makefile
 create mode 100644 tools/counter/counter_example.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f2fdd2202605..57dc9b6ff82a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4782,6 +4782,7 @@ F:	Documentation/driver-api/generic-counter.rst
 F:	drivers/counter/
 F:	include/linux/counter.h
 F:	include/uapi/linux/counter.h
+F:	tools/counter/
 
 CP2615 I2C DRIVER
 M:	Bence Cs?k?s <bence98 at sch.bme.hu>
diff --git a/tools/Makefile b/tools/Makefile
index 7e9d34ddd74c..5da1fde03a9a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -12,6 +12,7 @@ help:
 	@echo '  acpi                   - ACPI tools'
 	@echo '  bpf                    - misc BPF tools'
 	@echo '  cgroup                 - cgroup tools'
+	@echo '  counter                - counter tools'
 	@echo '  cpupower               - a tool for all things x86 CPU power'
 	@echo '  debugging              - tools for debugging'
 	@echo '  firewire               - the userspace part of nosy, an IEEE-1394 traffic sniffer'
@@ -65,7 +66,7 @@ acpi: FORCE
 cpupower: FORCE
 	$(call descend,power/$@)
 
-cgroup firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
+cgroup counter firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
 	$(call descend,$@)
 
 bpf/%: FORCE
@@ -100,7 +101,7 @@ freefall: FORCE
 kvm_stat: FORCE
 	$(call descend,kvm/$@)
 
-all: acpi cgroup cpupower gpio hv firewire liblockdep \
+all: acpi cgroup counter cpupower gpio hv firewire liblockdep \
 		perf selftests bootconfig spi turbostat usb \
 		virtio vm bpf x86_energy_perf_policy \
 		tmon freefall iio objtool kvm_stat wmi \
@@ -112,7 +113,7 @@ acpi_install:
 cpupower_install:
 	$(call descend,power/$(@:_install=),install)
 
-cgroup_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
+cgroup_install counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
 	$(call descend,$(@:_install=),install)
 
 liblockdep_install:
@@ -133,7 +134,7 @@ freefall_install:
 kvm_stat_install:
 	$(call descend,kvm/$(@:_install=),install)
 
-install: acpi_install cgroup_install cpupower_install gpio_install \
+install: acpi_install cgroup_install counter_install cpupower_install gpio_install \
 		hv_install firewire_install iio_install liblockdep_install \
 		perf_install selftests_install turbostat_install usb_install \
 		virtio_install vm_install bpf_install x86_energy_perf_policy_install \
@@ -147,7 +148,7 @@ acpi_clean:
 cpupower_clean:
 	$(call descend,power/cpupower,clean)
 
-cgroup_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
+cgroup_clean counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
 	$(call descend,$(@:_clean=),clean)
 
 liblockdep_clean:
@@ -181,7 +182,7 @@ freefall_clean:
 build_clean:
 	$(call descend,build,clean)
 
-clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
+clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_clean \
 		perf_clean selftests_clean turbostat_clean bootconfig_clean spi_clean usb_clean virtio_clean \
 		vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
 		freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \
diff --git a/tools/counter/Build b/tools/counter/Build
new file mode 100644
index 000000000000..33f4a51d715e
--- /dev/null
+++ b/tools/counter/Build
@@ -0,0 +1 @@
+counter_example-y += counter_example.o
diff --git a/tools/counter/Makefile b/tools/counter/Makefile
new file mode 100644
index 000000000000..5ebc195fd9c0
--- /dev/null
+++ b/tools/counter/Makefile
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: GPL-2.0
+include ../scripts/Makefile.include
+
+bindir ?= /usr/bin
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+endif
+
+# Do not use make's built-in rules
+# (this improves performance and avoids hard-to-debug behaviour);
+MAKEFLAGS += -r
+
+override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
+
+ALL_TARGETS := counter_example
+ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
+
+all: $(ALL_PROGRAMS)
+
+export srctree OUTPUT CC LD CFLAGS
+include $(srctree)/tools/build/Makefile.include
+
+#
+# We need the following to be outside of kernel tree
+#
+$(OUTPUT)include/linux/counter.h: ../../include/uapi/linux/counter.h
+	mkdir -p $(OUTPUT)include/linux 2>&1 || true
+	ln -sf $(CURDIR)/../../include/uapi/linux/counter.h $@
+
+prepare: $(OUTPUT)include/linux/counter.h
+
+COUNTER_EXAMPLE := $(OUTPUT)counter_example.o
+$(COUNTER_EXAMPLE): prepare FORCE
+	$(Q)$(MAKE) $(build)=counter_example
+$(OUTPUT)counter_example: $(COUNTER_EXAMPLE)
+	$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+
+clean:
+	rm -f $(ALL_PROGRAMS)
+	rm -rf $(OUTPUT)include/linux/counter.h
+	find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
+
+install: $(ALL_PROGRAMS)
+	install -d -m 755 $(DESTDIR)$(bindir);		\
+	for program in $(ALL_PROGRAMS); do		\
+		install $$program $(DESTDIR)$(bindir);	\
+	done
+
+FORCE:
+
+.PHONY: all install clean FORCE prepare
diff --git a/tools/counter/counter_example.c b/tools/counter/counter_example.c
new file mode 100644
index 000000000000..90d69fb9463b
--- /dev/null
+++ b/tools/counter/counter_example.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Counter - example userspace application
+ *
+ * The userspace application opens /dev/counter0, configures the
+ * COUNTER_EVENT_INDEX event channel 0 to gather Count 0 count and Count
+ * 1 count, and prints out the data as it becomes available on the
+ * character device node.
+ *
+ * Copyright (C) 2021 William Breathitt Gray
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/counter.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+static struct counter_watch watches[2] = {
+	{
+		/* Component data: Count 0 count */
+		.component.type = COUNTER_COMPONENT_COUNT,
+		.component.scope = COUNTER_SCOPE_COUNT,
+		.component.parent = 0,
+		/* Event type: Index */
+		.event = COUNTER_EVENT_INDEX,
+		/* Device event channel 0 */
+		.channel = 0,
+	},
+	{
+		/* Component data: Count 1 count */
+		.component.type = COUNTER_COMPONENT_COUNT,
+		.component.scope = COUNTER_SCOPE_COUNT,
+		.component.parent = 1,
+		/* Event type: Index */
+		.event = COUNTER_EVENT_INDEX,
+		/* Device event channel 0 */
+		.channel = 0,
+	},
+};
+
+int main(void)
+{
+	int fd;
+	int ret;
+	struct counter_event event_data[2];
+
+	fd = open("/dev/counter0", O_RDWR);
+	if (fd == -1) {
+		perror("Unable to open /dev/counter0");
+		return -errno;
+	}
+
+	ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches);
+	if (ret == -1) {
+		perror("Error adding watches[0]");
+		return -errno;
+	}
+	ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + 1);
+	if (ret == -1) {
+		perror("Error adding watches[1]");
+		return -errno;
+	}
+	ret = ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
+	if (ret == -1) {
+		perror("Error enabling events");
+		return -errno;
+	}
+
+	for (;;) {
+		ret = read(fd, event_data, sizeof(event_data));
+		if (ret == -1) {
+			perror("Failed to read event data");
+			return 1;
+		}
+
+		if (ret != sizeof(event_data)) {
+			fprintf(stderr, "Failed to read event data\n");
+			return -EIO;
+		}
+
+		printf("Timestamp 0: %llu\tCount 0: %llu\n"
+		       "Error Message 0: %s\n"
+		       "Timestamp 1: %llu\tCount 1: %llu\n"
+		       "Error Message 1: %s\n",
+		       event_data[0].timestamp, event_data[0].value,
+		       strerror(event_data[0].status),
+		       event_data[1].timestamp, event_data[1].value,
+		       strerror(event_data[1].status));
+	}
+
+	return 0;
+}
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:54 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:54 +0900
Subject: [PATCH v16 10/14] counter: Implement signalZ_action_component_id
 sysfs attribute
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <e87de8c56bd9cb5c204c12866de6c04199dee9fa.1630031207.git.vilhelm.gray@gmail.com>

The Generic Counter chrdev interface expects users to supply component
IDs in order to select Synapses for requests. In order for users to know
what component ID belongs to which Synapse this information must be
exposed. The signalZ_action_component_id attribute provides a way for
users to discover what component ID belongs to the respective Synapse.

Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Reviewed-by: David Lechner <david at lechnology.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter |  7 ++++
 drivers/counter/counter-sysfs.c             | 45 +++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index dee79b606847..aa2cd3c10d74 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -203,6 +203,13 @@ Description:
 		both edges:
 			Any state transition.
 
+What:		/sys/bus/counter/devices/counterX/countY/signalZ_action_component_id
+KernelVersion:	5.16
+Contact:	linux-iio at vger.kernel.org
+Description:
+		Read-only attribute that indicates the component ID of the
+		respective Synapse of Count Y for Signal Z.
+
 What:		/sys/bus/counter/devices/counterX/countY/spike_filter_ns
 KernelVersion:	5.14
 Contact:	linux-iio at vger.kernel.org
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index 108cbd838eb9..ee7ff1cde454 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -532,6 +532,46 @@ static int counter_name_attr_create(struct device *const dev,
 	return 0;
 }
 
+static ssize_t counter_comp_id_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	const size_t id = (size_t)to_counter_attribute(attr)->comp.priv;
+
+	return sprintf(buf, "%zu\n", id);
+}
+
+static int counter_comp_id_attr_create(struct device *const dev,
+				       struct counter_attribute_group *const group,
+				       const char *name, const size_t id)
+{
+	struct counter_attribute *counter_attr;
+
+	/* Allocate Counter attribute */
+	counter_attr = devm_kzalloc(dev, sizeof(*counter_attr), GFP_KERNEL);
+	if (!counter_attr)
+		return -ENOMEM;
+
+	/* Generate component ID name */
+	name = devm_kasprintf(dev, GFP_KERNEL, "%s_component_id", name);
+	if (!name)
+		return -ENOMEM;
+
+	/* Configure Counter attribute */
+	counter_attr->comp.priv = (void *)id;
+
+	/* Configure device attribute */
+	sysfs_attr_init(&counter_attr->dev_attr.attr);
+	counter_attr->dev_attr.attr.name = name;
+	counter_attr->dev_attr.attr.mode = 0444;
+	counter_attr->dev_attr.show = counter_comp_id_show;
+
+	/* Store list node */
+	list_add(&counter_attr->l, &group->attr_list);
+	group->num_attr++;
+
+	return 0;
+}
+
 static struct counter_comp counter_signal_comp = {
 	.type = COUNTER_COMP_SIGNAL_LEVEL,
 	.name = "signal",
@@ -626,6 +666,11 @@ static int counter_sysfs_synapses_add(struct counter_device *const counter,
 					  COUNTER_SCOPE_COUNT, count);
 		if (err < 0)
 			return err;
+
+		/* Create Synapse component ID attribute */
+		err = counter_comp_id_attr_create(dev, group, comp.name, i);
+		if (err < 0)
+			return err;
 	}
 
 	return 0;
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:55 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:55 +0900
Subject: [PATCH v16 11/14] counter: Implement *_component_id sysfs attributes
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <86be841f8149b6be20cfff6a050ef64b167e37a8.1630031207.git.vilhelm.gray@gmail.com>

The Generic Counter chrdev interface expects users to supply component
IDs in order to select extensions for requests. In order for users to
know what component ID belongs to which extension this information must
be exposed. The *_component_id attribute provides a way for users to
discover what component ID belongs to which respective extension.

Cc: David Lechner <david at lechnology.com>
Cc: Gwendal Grignou <gwendal at chromium.org>
Cc: Dan Carpenter <dan.carpenter at oracle.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter | 16 +++++++++-
 drivers/counter/counter-sysfs.c             | 33 +++++++++++++++++----
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index aa2cd3c10d74..0ce16669157e 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -203,12 +203,26 @@ Description:
 		both edges:
 			Any state transition.
 
+What:		/sys/bus/counter/devices/counterX/countY/ceiling_component_id
+What:		/sys/bus/counter/devices/counterX/countY/floor_component_id
+What:		/sys/bus/counter/devices/counterX/countY/count_mode_component_id
+What:		/sys/bus/counter/devices/counterX/countY/direction_component_id
+What:		/sys/bus/counter/devices/counterX/countY/enable_component_id
+What:		/sys/bus/counter/devices/counterX/countY/error_noise_component_id
+What:		/sys/bus/counter/devices/counterX/countY/prescaler_component_id
+What:		/sys/bus/counter/devices/counterX/countY/preset_component_id
+What:		/sys/bus/counter/devices/counterX/countY/preset_enable_component_id
 What:		/sys/bus/counter/devices/counterX/countY/signalZ_action_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/cable_fault_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/cable_fault_enable_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/filter_clock_prescaler_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/index_polarity_component_id
+What:		/sys/bus/counter/devices/counterX/signalY/synchronous_mode_component_id
 KernelVersion:	5.16
 Contact:	linux-iio at vger.kernel.org
 Description:
 		Read-only attribute that indicates the component ID of the
-		respective Synapse of Count Y for Signal Z.
+		respective extension or Synapse.
 
 What:		/sys/bus/counter/devices/counterX/countY/spike_filter_ns
 KernelVersion:	5.14
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index ee7ff1cde454..97d8d7c2a2b6 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -586,6 +586,7 @@ static int counter_signal_attrs_create(struct counter_device *const counter,
 	int err;
 	struct counter_comp comp;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Create main Signal attribute */
 	comp = counter_signal_comp;
@@ -601,8 +602,14 @@ static int counter_signal_attrs_create(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < signal->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, signal->ext + i,
-					  scope, signal);
+		ext = &signal->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, signal);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
@@ -693,6 +700,7 @@ static int counter_count_attrs_create(struct counter_device *const counter,
 	int err;
 	struct counter_comp comp;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Create main Count attribute */
 	comp = counter_count_comp;
@@ -717,8 +725,14 @@ static int counter_count_attrs_create(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < count->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, count->ext + i,
-					  scope, count);
+		ext = &count->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, count);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
@@ -782,6 +796,7 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 	struct device *const dev = &counter->dev;
 	int err;
 	size_t i;
+	struct counter_comp *ext;
 
 	/* Add Signals sysfs attributes */
 	err = counter_sysfs_signals_add(counter, cattr_group);
@@ -814,8 +829,14 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 
 	/* Create an attribute for each extension */
 	for (i = 0; i < counter->num_ext; i++) {
-		err = counter_attr_create(dev, cattr_group, counter->ext + i,
-					  scope, NULL);
+		ext = &counter->ext[i];
+
+		err = counter_attr_create(dev, cattr_group, ext, scope, NULL);
+		if (err < 0)
+			return err;
+
+		err = counter_comp_id_attr_create(dev, cattr_group, ext->name,
+						  i);
 		if (err < 0)
 			return err;
 	}
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:56 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:56 +0900
Subject: [PATCH v16 12/14] counter: Implement events_queue_size sysfs attribute
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <b159f45c8f9dd383e44cdd5629573f28895bea47.1630031207.git.vilhelm.gray@gmail.com>

The events_queue_size sysfs attribute provides a way for users to
dynamically configure the Counter events queue size for the Counter
character device interface. The size is in number of struct
counter_event data structures. The number of elements will be rounded-up
to a power of 2 due to a requirement of the kfifo_alloc function called
during reallocation of the queue.

Cc: Oleksij Rempel <o.rempel at pengutronix.de>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 Documentation/ABI/testing/sysfs-bus-counter |  8 ++++
 drivers/counter/counter-sysfs.c             | 45 +++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-counter b/Documentation/ABI/testing/sysfs-bus-counter
index 0ce16669157e..06c2b3e27e0b 100644
--- a/Documentation/ABI/testing/sysfs-bus-counter
+++ b/Documentation/ABI/testing/sysfs-bus-counter
@@ -233,6 +233,14 @@ Description:
 		shorter or equal to configured value are ignored. Value 0 means
 		filter is disabled.
 
+What:		/sys/bus/counter/devices/counterX/events_queue_size
+KernelVersion:	5.16
+Contact:	linux-iio at vger.kernel.org
+Description:
+		Size of the Counter events queue in number of struct
+		counter_event data structures. The number of elements will be
+		rounded-up to a power of 2.
+
 What:		/sys/bus/counter/devices/counterX/name
 KernelVersion:	5.2
 Contact:	linux-iio at vger.kernel.org
diff --git a/drivers/counter/counter-sysfs.c b/drivers/counter/counter-sysfs.c
index 97d8d7c2a2b6..b90f404b1fa1 100644
--- a/drivers/counter/counter-sysfs.c
+++ b/drivers/counter/counter-sysfs.c
@@ -3,11 +3,13 @@
  * Generic Counter sysfs interface
  * Copyright (C) 2020 William Breathitt Gray
  */
+#include <linux/bitops.h>
 #include <linux/counter.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/gfp.h>
 #include <linux/kernel.h>
+#include <linux/kfifo.h>
 #include <linux/kstrtox.h>
 #include <linux/list.h>
 #include <linux/string.h>
@@ -783,12 +785,49 @@ static int counter_num_counts_read(struct counter_device *counter, u8 *val)
 	return 0;
 }
 
+static int counter_events_queue_size_read(struct counter_device *counter,
+					  u64 *val)
+{
+	*val = kfifo_size(&counter->events);
+	return 0;
+}
+
+static int counter_events_queue_size_write(struct counter_device *counter,
+					   u64 val)
+{
+	DECLARE_KFIFO_PTR(events, struct counter_event);
+	int err = 0;
+
+	/* Verify chrdev is not currently being used */
+	if (test_and_set_bit_lock(0, counter->chrdev_lock))
+		return -EBUSY;
+
+	/* Allocate new events queue */
+	err = kfifo_alloc(&events, val, GFP_KERNEL);
+	if (err)
+		goto exit_early;
+
+	/* Swap in new events queue */
+	kfifo_free(&counter->events);
+	counter->events.kfifo = events.kfifo;
+
+exit_early:
+	clear_bit_unlock(0, counter->chrdev_lock);
+
+	return err;
+}
+
 static struct counter_comp counter_num_signals_comp =
 	COUNTER_COMP_DEVICE_U8("num_signals", counter_num_signals_read, NULL);
 
 static struct counter_comp counter_num_counts_comp =
 	COUNTER_COMP_DEVICE_U8("num_counts", counter_num_counts_read, NULL);
 
+static struct counter_comp counter_events_queue_size_comp =
+	COUNTER_COMP_DEVICE_U64("events_queue_size",
+				counter_events_queue_size_read,
+				counter_events_queue_size_write);
+
 static int counter_sysfs_attr_add(struct counter_device *const counter,
 				  struct counter_attribute_group *cattr_group)
 {
@@ -827,6 +866,12 @@ static int counter_sysfs_attr_add(struct counter_device *const counter,
 	if (err < 0)
 		return err;
 
+	/* Create events_queue_size attribute */
+	err = counter_attr_create(dev, cattr_group,
+				  &counter_events_queue_size_comp, scope, NULL);
+	if (err < 0)
+		return err;
+
 	/* Create an attribute for each extension */
 	for (i = 0; i < counter->num_ext; i++) {
 		ext = &counter->ext[i];
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:57 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:57 +0900
Subject: [PATCH v16 13/14] counter: 104-quad-8: Replace mutex with spinlock
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <eb21d25c7bce01bf938c434604fad1482a47f273.1630031207.git.vilhelm.gray@gmail.com>

This patch replaces the mutex I/O lock with a spinlock. This is in
preparation for a subsequent patch adding IRQ support for 104-QUAD-8
devices; we can't sleep in an interrupt context, so we'll need to use a
spinlock instead.

Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c | 89 +++++++++++++++++++++---------------
 1 file changed, 52 insertions(+), 37 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index c587f295d720..a56751bf1e9b 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/types.h>
+#include <linux/spinlock.h>
 
 #define QUAD8_EXTENT 32
 
@@ -43,7 +44,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
  * @base:		base port address of the device
  */
 struct quad8 {
-	struct mutex lock;
+	spinlock_t lock;
 	struct counter_device counter;
 	unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
 	unsigned int preset[QUAD8_NUM_COUNTERS];
@@ -124,6 +125,7 @@ static int quad8_count_read(struct counter_device *counter,
 	unsigned int flags;
 	unsigned int borrow;
 	unsigned int carry;
+	unsigned long irqflags;
 	int i;
 
 	flags = inb(base_offset + 1);
@@ -133,7 +135,7 @@ static int quad8_count_read(struct counter_device *counter,
 	/* Borrow XOR Carry effectively doubles count range */
 	*val = (unsigned long)(borrow ^ carry) << 24;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Reset Byte Pointer; transfer Counter to Output Latch */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
@@ -142,7 +144,7 @@ static int quad8_count_read(struct counter_device *counter,
 	for (i = 0; i < 3; i++)
 		*val |= (unsigned long)inb(base_offset) << (8 * i);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -152,13 +154,14 @@ static int quad8_count_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
+	unsigned long irqflags;
 	int i;
 
 	/* Only 24-bit values are supported */
 	if (val > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Reset Byte Pointer */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
@@ -183,7 +186,7 @@ static int quad8_count_write(struct counter_device *counter,
 	/* Reset Error flag */
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -201,8 +204,9 @@ static int quad8_function_read(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int id = count->id;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	if (priv->quadrature_mode[id])
 		switch (priv->quadrature_scale[id]) {
@@ -219,7 +223,7 @@ static int quad8_function_read(struct counter_device *counter,
 	else
 		*function = COUNTER_FUNCTION_PULSE_DIRECTION;
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -234,10 +238,11 @@ static int quad8_function_write(struct counter_device *counter,
 	unsigned int *const scale = priv->quadrature_scale + id;
 	unsigned int *const synchronous_mode = priv->synchronous_mode + id;
 	const int base_offset = priv->base + 2 * id + 1;
+	unsigned long irqflags;
 	unsigned int mode_cfg;
 	unsigned int idr_cfg;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	mode_cfg = priv->count_mode[id] << 1;
 	idr_cfg = priv->index_polarity[id] << 1;
@@ -272,7 +277,7 @@ static int quad8_function_write(struct counter_device *counter,
 			break;
 		default:
 			/* should never reach this path */
-			mutex_unlock(&priv->lock);
+			spin_unlock_irqrestore(&priv->lock, irqflags);
 			return -EINVAL;
 		}
 	}
@@ -280,7 +285,7 @@ static int quad8_function_write(struct counter_device *counter,
 	/* Load mode configuration to Counter Mode Register */
 	outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -406,9 +411,10 @@ static int quad8_index_polarity_set(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 	const int base_offset = priv->base + 2 * channel_id + 1;
+	unsigned long irqflags;
 	unsigned int idr_cfg = index_polarity << 1;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	idr_cfg |= priv->synchronous_mode[channel_id];
 
@@ -417,7 +423,7 @@ static int quad8_index_polarity_set(struct counter_device *counter,
 	/* Load Index Control configuration to Index Control Register */
 	outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -446,15 +452,16 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id - 16;
 	const int base_offset = priv->base + 2 * channel_id + 1;
+	unsigned long irqflags;
 	unsigned int idr_cfg = synchronous_mode;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	idr_cfg |= priv->index_polarity[channel_id] << 1;
 
 	/* Index function must be non-synchronous in non-quadrature mode */
 	if (synchronous_mode && !priv->quadrature_mode[channel_id]) {
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return -EINVAL;
 	}
 
@@ -463,7 +470,7 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
 	/* Load Index Control configuration to Index Control Register */
 	outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -510,6 +517,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 	unsigned int count_mode;
 	unsigned int mode_cfg;
 	const int base_offset = priv->base + 2 * count->id + 1;
+	unsigned long irqflags;
 
 	/* Map Generic Counter count mode to 104-QUAD-8 count mode */
 	switch (cnt_mode) {
@@ -530,7 +538,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 		return -EINVAL;
 	}
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->count_mode[count->id] = count_mode;
 
@@ -544,7 +552,7 @@ static int quad8_count_mode_write(struct counter_device *counter,
 	/* Load mode configuration to Counter Mode Register */
 	outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -564,9 +572,10 @@ static int quad8_count_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id;
+	unsigned long irqflags;
 	unsigned int ior_cfg;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->ab_enable[count->id] = enable;
 
@@ -575,7 +584,7 @@ static int quad8_count_enable_write(struct counter_device *counter,
 	/* Load I/O control configuration */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -626,16 +635,17 @@ static int quad8_count_preset_write(struct counter_device *counter,
 				    struct counter_count *count, u64 preset)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
 	/* Only 24-bit values are supported */
 	if (preset > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	quad8_preset_register_set(priv, count->id, preset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -644,8 +654,9 @@ static int quad8_count_ceiling_read(struct counter_device *counter,
 				    struct counter_count *count, u64 *ceiling)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Range Limit and Modulo-N count modes use preset value as ceiling */
 	switch (priv->count_mode[count->id]) {
@@ -659,7 +670,7 @@ static int quad8_count_ceiling_read(struct counter_device *counter,
 		break;
 	}
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -668,23 +679,24 @@ static int quad8_count_ceiling_write(struct counter_device *counter,
 				     struct counter_count *count, u64 ceiling)
 {
 	struct quad8 *const priv = counter->priv;
+	unsigned long irqflags;
 
 	/* Only 24-bit values are supported */
 	if (ceiling > 0xFFFFFF)
 		return -ERANGE;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	/* Range Limit and Modulo-N count modes use preset value as ceiling */
 	switch (priv->count_mode[count->id]) {
 	case 1:
 	case 3:
 		quad8_preset_register_set(priv, count->id, ceiling);
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return 0;
 	}
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return -EINVAL;
 }
@@ -706,12 +718,13 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const int base_offset = priv->base + 2 * count->id + 1;
+	unsigned long irqflags;
 	unsigned int ior_cfg;
 
 	/* Preset enable is active low in Input/Output Control register */
 	preset_enable = !preset_enable;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->preset_enable[count->id] = preset_enable;
 
@@ -720,7 +733,7 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 	/* Load I/O control configuration to Input / Output Control Register */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -731,22 +744,23 @@ static int quad8_signal_cable_fault_read(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
+	unsigned long irqflags;
 	bool disabled;
 	unsigned int status;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	disabled = !(priv->cable_fault_enable & BIT(channel_id));
 
 	if (disabled) {
-		mutex_unlock(&priv->lock);
+		spin_unlock_irqrestore(&priv->lock, irqflags);
 		return -EINVAL;
 	}
 
 	/* Logic 0 = cable fault */
 	status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	/* Mask respective channel and invert logic */
 	*cable_fault = !(status & BIT(channel_id));
@@ -772,9 +786,10 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
 {
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
+	unsigned long irqflags;
 	unsigned int cable_fault_enable;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	if (enable)
 		priv->cable_fault_enable |= BIT(channel_id);
@@ -786,7 +801,7 @@ static int quad8_signal_cable_fault_enable_write(struct counter_device *counter,
 
 	outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -809,8 +824,9 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
 	struct quad8 *const priv = counter->priv;
 	const size_t channel_id = signal->id / 2;
 	const int base_offset = priv->base + 2 * channel_id;
+	unsigned long irqflags;
 
-	mutex_lock(&priv->lock);
+	spin_lock_irqsave(&priv->lock, irqflags);
 
 	priv->fck_prescaler[channel_id] = prescaler;
 
@@ -822,7 +838,7 @@ static int quad8_signal_fck_prescaler_write(struct counter_device *counter,
 	outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
 	     base_offset + 1);
 
-	mutex_unlock(&priv->lock);
+	spin_unlock_irqrestore(&priv->lock, irqflags);
 
 	return 0;
 }
@@ -991,8 +1007,7 @@ static int quad8_probe(struct device *dev, unsigned int id)
 	priv->counter.priv = priv;
 	priv->base = base[id];
 
-	/* Initialize mutex */
-	mutex_init(&priv->lock);
+	spin_lock_init(&priv->lock);
 
 	/* Reset all counters and disable interrupt function */
 	outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
-- 
2.32.0



From vilhelm.gray at gmail.com  Thu Aug 26 20:47:58 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Fri, 27 Aug 2021 12:47:58 +0900
Subject: [PATCH v16 14/14] counter: 104-quad-8: Add IRQ support for the ACCES
 104-QUAD-8
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <c73960bc4545b11f6be105cf5b62bc47e027394d.1630031207.git.vilhelm.gray@gmail.com>

The LSI/CSI LS7266R1 chip provides programmable output via the FLG pins.
When interrupts are enabled on the ACCES 104-QUAD-8, they occur whenever
FLG1 is active. Four functions are available for the FLG1 signal: Carry,
Compare, Carry-Borrow, and Index.

	Carry:
		Interrupt generated on active low Carry signal. Carry
		signal toggles every time the respective channel's
		counter overflows.

	Compare:
		Interrupt generated on active low Compare signal.
		Compare signal toggles every time respective channel's
		preset register is equal to the respective channel's
		counter.

	Carry-Borrow:
		Interrupt generated on active low Carry signal and
		active low Borrow signal. Carry signal toggles every
		time the respective channel's counter overflows. Borrow
		signal toggles every time the respective channel's
		counter underflows.

	Index:
		Interrupt generated on active high Index signal.

These four functions correspond respectivefly to the following four
Counter event types: COUNTER_EVENT_OVERFLOW, COUNTER_EVENT_THRESHOLD,
COUNTER_EVENT_OVERFLOW_UNDERFLOW, and COUNTER_EVENT_INDEX. Interrupts
push Counter events to event channel X, where 'X' is the respective
channel whose FLG1 activated.

This patch adds IRQ support for the ACCES 104-QUAD-8. The interrupt line
numbers for the devices may be configured via the irq array module
parameter.

Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
---
 drivers/counter/104-quad-8.c | 167 +++++++++++++++++++++++++++++++++--
 drivers/counter/Kconfig      |   6 +-
 2 files changed, 164 insertions(+), 9 deletions(-)

diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
index a56751bf1e9b..1cbd60aaed69 100644
--- a/drivers/counter/104-quad-8.c
+++ b/drivers/counter/104-quad-8.c
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
+#include <linux/interrupt.h>
 #include <linux/isa.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -25,6 +26,10 @@ static unsigned int num_quad8;
 module_param_hw_array(base, uint, ioport, &num_quad8, 0);
 MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
 
+static unsigned int irq[max_num_isa_dev(QUAD8_EXTENT)];
+module_param_hw_array(irq, uint, irq, NULL, 0);
+MODULE_PARM_DESC(irq, "ACCES 104-QUAD-8 interrupt line numbers");
+
 #define QUAD8_NUM_COUNTERS 8
 
 /**
@@ -38,6 +43,8 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
  * @quadrature_scale:	array of quadrature mode scale configurations
  * @ab_enable:		array of A and B inputs enable configurations
  * @preset_enable:	array of set_to_preset_on_index attribute configurations
+ * @irq_trigger:	array of current IRQ trigger function configurations
+ * @next_irq_trigger:	array of next IRQ trigger function configurations
  * @synchronous_mode:	array of index function synchronous mode configurations
  * @index_polarity:	array of index function polarity configurations
  * @cable_fault_enable:	differential encoder cable status enable configurations
@@ -53,13 +60,17 @@ struct quad8 {
 	unsigned int quadrature_scale[QUAD8_NUM_COUNTERS];
 	unsigned int ab_enable[QUAD8_NUM_COUNTERS];
 	unsigned int preset_enable[QUAD8_NUM_COUNTERS];
+	unsigned int irq_trigger[QUAD8_NUM_COUNTERS];
+	unsigned int next_irq_trigger[QUAD8_NUM_COUNTERS];
 	unsigned int synchronous_mode[QUAD8_NUM_COUNTERS];
 	unsigned int index_polarity[QUAD8_NUM_COUNTERS];
 	unsigned int cable_fault_enable;
 	unsigned int base;
 };
 
+#define QUAD8_REG_INTERRUPT_STATUS 0x10
 #define QUAD8_REG_CHAN_OP 0x11
+#define QUAD8_REG_INDEX_INTERRUPT 0x12
 #define QUAD8_REG_INDEX_INPUT_LEVELS 0x16
 #define QUAD8_DIFF_ENCODER_CABLE_STATUS 0x17
 /* Borrow Toggle flip-flop */
@@ -92,8 +103,8 @@ struct quad8 {
 #define QUAD8_RLD_CNTR_OUT 0x10
 /* Transfer Preset Register LSB to FCK Prescaler */
 #define QUAD8_RLD_PRESET_PSC 0x18
-#define QUAD8_CHAN_OP_ENABLE_COUNTERS 0x00
 #define QUAD8_CHAN_OP_RESET_COUNTERS 0x01
+#define QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC 0x04
 #define QUAD8_CMR_QUADRATURE_X1 0x08
 #define QUAD8_CMR_QUADRATURE_X2 0x10
 #define QUAD8_CMR_QUADRATURE_X4 0x18
@@ -378,13 +389,103 @@ static int quad8_action_read(struct counter_device *counter,
 	}
 }
 
+enum {
+	QUAD8_EVENT_NONE = -1,
+	QUAD8_EVENT_CARRY = 0,
+	QUAD8_EVENT_COMPARE = 1,
+	QUAD8_EVENT_CARRY_BORROW = 2,
+	QUAD8_EVENT_INDEX = 3,
+};
+
+static int quad8_events_configure(struct counter_device *counter)
+{
+	struct quad8 *const priv = counter->priv;
+	unsigned long irq_enabled = 0;
+	unsigned long irqflags;
+	size_t channel;
+	unsigned long ior_cfg;
+	unsigned long base_offset;
+
+	spin_lock_irqsave(&priv->lock, irqflags);
+
+	/* Enable interrupts for the requested channels, disable for the rest */
+	for (channel = 0; channel < QUAD8_NUM_COUNTERS; channel++) {
+		if (priv->next_irq_trigger[channel] == QUAD8_EVENT_NONE)
+			continue;
+
+		if (priv->irq_trigger[channel] != priv->next_irq_trigger[channel]) {
+			/* Save new IRQ function configuration */
+			priv->irq_trigger[channel] = priv->next_irq_trigger[channel];
+
+			/* Load configuration to I/O Control Register */
+			ior_cfg = priv->ab_enable[channel] |
+				  priv->preset_enable[channel] << 1 |
+				  priv->irq_trigger[channel] << 3;
+			base_offset = priv->base + 2 * channel + 1;
+			outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
+		}
+
+		/* Reset next IRQ trigger function configuration */
+		priv->next_irq_trigger[channel] = QUAD8_EVENT_NONE;
+
+		/* Enable IRQ line */
+		irq_enabled |= BIT(channel);
+	}
+
+	outb(irq_enabled, priv->base + QUAD8_REG_INDEX_INTERRUPT);
+
+	spin_unlock_irqrestore(&priv->lock, irqflags);
+
+	return 0;
+}
+
+static int quad8_watch_validate(struct counter_device *counter,
+				const struct counter_watch *watch)
+{
+	struct quad8 *const priv = counter->priv;
+
+	if (watch->channel > QUAD8_NUM_COUNTERS - 1)
+		return -EINVAL;
+
+	switch (watch->event) {
+	case COUNTER_EVENT_OVERFLOW:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_CARRY;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_CARRY)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_THRESHOLD:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_COMPARE;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_COMPARE)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_OVERFLOW_UNDERFLOW:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_CARRY_BORROW;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_CARRY_BORROW)
+			return -EINVAL;
+		return 0;
+	case COUNTER_EVENT_INDEX:
+		if (priv->next_irq_trigger[watch->channel] == QUAD8_EVENT_NONE)
+			priv->next_irq_trigger[watch->channel] = QUAD8_EVENT_INDEX;
+		else if (priv->next_irq_trigger[watch->channel] != QUAD8_EVENT_INDEX)
+			return -EINVAL;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 static const struct counter_ops quad8_ops = {
 	.signal_read = quad8_signal_read,
 	.count_read = quad8_count_read,
 	.count_write = quad8_count_write,
 	.function_read = quad8_function_read,
 	.function_write = quad8_function_write,
-	.action_read = quad8_action_read
+	.action_read = quad8_action_read,
+	.events_configure = quad8_events_configure,
+	.watch_validate = quad8_watch_validate,
 };
 
 static const char *const quad8_index_polarity_modes[] = {
@@ -579,7 +680,8 @@ static int quad8_count_enable_write(struct counter_device *counter,
 
 	priv->ab_enable[count->id] = enable;
 
-	ior_cfg = enable | priv->preset_enable[count->id] << 1;
+	ior_cfg = enable | priv->preset_enable[count->id] << 1 |
+		  priv->irq_trigger[count->id] << 3;
 
 	/* Load I/O control configuration */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
@@ -728,7 +830,8 @@ static int quad8_count_preset_enable_write(struct counter_device *counter,
 
 	priv->preset_enable[count->id] = preset_enable;
 
-	ior_cfg = priv->ab_enable[count->id] | preset_enable << 1;
+	ior_cfg = priv->ab_enable[count->id] | preset_enable << 1 |
+		  priv->irq_trigger[count->id] << 3;
 
 	/* Load I/O control configuration to Input / Output Control Register */
 	outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
@@ -980,11 +1083,54 @@ static struct counter_count quad8_counts[] = {
 	QUAD8_COUNT(7, "Channel 8 Count")
 };
 
+static irqreturn_t quad8_irq_handler(int irq, void *private)
+{
+	struct quad8 *const priv = private;
+	const unsigned long base = priv->base;
+	unsigned long irq_status;
+	unsigned long channel;
+	u8 event;
+
+	irq_status = inb(base + QUAD8_REG_INTERRUPT_STATUS);
+	if (!irq_status)
+		return IRQ_NONE;
+
+	for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) {
+		switch (priv->irq_trigger[channel]) {
+		case QUAD8_EVENT_CARRY:
+			event = COUNTER_EVENT_OVERFLOW;
+				break;
+		case QUAD8_EVENT_COMPARE:
+			event = COUNTER_EVENT_THRESHOLD;
+				break;
+		case QUAD8_EVENT_CARRY_BORROW:
+			event = COUNTER_EVENT_OVERFLOW_UNDERFLOW;
+				break;
+		case QUAD8_EVENT_INDEX:
+			event = COUNTER_EVENT_INDEX;
+				break;
+		default:
+			/* should never reach this path */
+			WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
+				  priv->irq_trigger[channel], channel);
+			continue;
+		}
+
+		counter_push_event(&priv->counter, event, channel);
+	}
+
+	/* Clear pending interrupts on device */
+	outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
+
+	return IRQ_HANDLED;
+}
+
 static int quad8_probe(struct device *dev, unsigned int id)
 {
 	struct quad8 *priv;
 	int i, j;
 	unsigned int base_offset;
+	int err;
 
 	if (!devm_request_region(dev, base[id], QUAD8_EXTENT, dev_name(dev))) {
 		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
@@ -1009,6 +1155,8 @@ static int quad8_probe(struct device *dev, unsigned int id)
 
 	spin_lock_init(&priv->lock);
 
+	/* Reset Index/Interrupt Register */
+	outb(0x00, base[id] + QUAD8_REG_INDEX_INTERRUPT);
 	/* Reset all counters and disable interrupt function */
 	outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
 	/* Set initial configuration for all counters */
@@ -1035,11 +1183,18 @@ static int quad8_probe(struct device *dev, unsigned int id)
 		outb(QUAD8_CTR_IOR, base_offset + 1);
 		/* Disable index function; negative index polarity */
 		outb(QUAD8_CTR_IDR, base_offset + 1);
+		/* Initialize next IRQ trigger function configuration */
+		priv->next_irq_trigger[i] = QUAD8_EVENT_NONE;
 	}
 	/* Disable Differential Encoder Cable Status for all channels */
 	outb(0xFF, base[id] + QUAD8_DIFF_ENCODER_CABLE_STATUS);
-	/* Enable all counters */
-	outb(QUAD8_CHAN_OP_ENABLE_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
+	/* Enable all counters and enable interrupt function */
+	outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base[id] + QUAD8_REG_CHAN_OP);
+
+	err = devm_request_irq(dev, irq[id], quad8_irq_handler, IRQF_SHARED,
+			       priv->counter.name, priv);
+	if (err)
+		return err;
 
 	return devm_counter_register(dev, &priv->counter);
 }
diff --git a/drivers/counter/Kconfig b/drivers/counter/Kconfig
index d5d2540b30c2..3dcdb681c4e4 100644
--- a/drivers/counter/Kconfig
+++ b/drivers/counter/Kconfig
@@ -23,11 +23,11 @@ config 104_QUAD_8
 	  A counter's respective error flag may be cleared by performing a write
 	  operation on the respective count value attribute. Although the
 	  104-QUAD-8 counters have a 25-bit range, only the lower 24 bits may be
-	  set, either directly or via the counter's preset attribute. Interrupts
-	  are not supported by this driver.
+	  set, either directly or via the counter's preset attribute.
 
 	  The base port addresses for the devices may be configured via the base
-	  array module parameter.
+	  array module parameter. The interrupt line numbers for the devices may
+	  be configured via the irq array module parameter.
 
 config INTERRUPT_CNT
 	tristate "Interrupt counter driver"
-- 
2.32.0



From jk at codeconstruct.com.au  Thu Aug 26 21:36:37 2021
From: jk at codeconstruct.com.au (Jeremy Kerr)
Date: Fri, 27 Aug 2021 12:36:37 +0800
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <HK0PR06MB377997422D9508894936E39691C89@HK0PR06MB3779.apcprd06.prod.outlook.com>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
 <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
 <7e7378c49ecfb21fef6a0640f92c1b3a7a5878d0.camel@codeconstruct.com.au>
 <HK0PR06MB377997422D9508894936E39691C89@HK0PR06MB3779.apcprd06.prod.outlook.com>
Message-ID: <3f2feea6c2fb21c2fdcb419cdc7ceddf3ade06ee.camel@codeconstruct.com.au>

Hi Chiawei,

> The eSPI slave device comprises four channels, where each of them has
> individual functionality.  Putting the four channels driver code into a
> single file makes it hard to maintain and trace.

Yep, understood.

> We did consider to make them standard .c files.
> But it requires to export channel functions into kernel space
> although they are dedicated only to this eSPI driver.

What do you mean by "export into kernel space" here? The function
prototypes need to be available to your main (-ctrl.c) file, regardless
of whether you're putting the entire functions in a header file, or just
the prototype. There's doesn't need to be any difference in visibility
outside of your own module if you were to do this the usual way.

> As espi-ctrl needs to invoke corresponding channel functions when it
> is interrupted by eSPI events.
> 
> To avoid polluting kernel space, we decided to put driver code in
> header files and make the channel functions 'static'.
> 
> BTW, I once encountered .c file inclusion in other projects. Is it
> proper for Linux driver development?

It can be, just that in this case it's a bit unusual, and I can't see a
good reason for doing so. This could just be a standard
multiple-source-file module.

> eSPI communication is based on the its cycle packet format.
> We intended to let userspace decided how to interpret and compose
> TX/RX packets including header, tag, length (encoded), and data.
> IOCTL comes to our first mind as it also works in the 'packet' like
> paradigm.

But you're not always exposing a packet-like interface for this. For
example, your virtual-wire interface just has a get/set interface for
bits in a register (plus some PCH event handling, which may not be
applicable to all platforms...).

The other channels do look like more of a packet interface though, but
in that case I'm not convinced that an ioctl interface is the best way
to go for that. You're essentially sending a (length, pointer) pair
over the ioctls there, which sounds more like a write() than an ioctl().

Regardless of the choice of interface though, this will definitely need
some documentation or description of the API, and the ioc header to be
somewhere useful for userspace to consume.

With that documented, we'd have a better idea of how the new ABI is
supposed to work.

Cheers,


Jeremy



From lkp at intel.com  Thu Aug 26 22:03:18 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 13:03:18 +0800
Subject: [PATCH v6 2/3] clocksource: Rewrite Xilinx AXI timer driver
In-Reply-To: <20210826211830.3311140-2-sean.anderson@seco.com>
References: <20210826211830.3311140-2-sean.anderson@seco.com>
Message-ID: <202108271251.ebYBxG8I-lkp@intel.com>

Hi Sean,

I love your patch! Yet something to improve:

[auto build test ERROR on tip/timers/core]
[also build test ERROR on pwm/for-next linus/master v5.14-rc7 next-20210826]
[cannot apply to xlnx/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Sean-Anderson/dt-bindings-pwm-Add-Xilinx-AXI-Timer/20210827-052011
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 127c92feb74a6721f62587f1b89128808f049cf1
config: s390-allmodconfig (attached as .config)
compiler: s390-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/f36eeb054cb36e73651539fddae480083ce799e4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Sean-Anderson/dt-bindings-pwm-Add-Xilinx-AXI-Timer/20210827-052011
        git checkout f36eeb054cb36e73651539fddae480083ce799e4
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=s390 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   s390-linux-ld: kernel/dma/coherent.o: in function `dma_init_coherent_memory':
   coherent.c:(.text+0xdc): undefined reference to `memremap'
   s390-linux-ld: coherent.c:(.text+0x1c2): undefined reference to `memunmap'
   s390-linux-ld: kernel/dma/coherent.o: in function `dma_declare_coherent_memory':
   coherent.c:(.text+0x6be): undefined reference to `memunmap'
   s390-linux-ld: drivers/irqchip/irq-al-fic.o: in function `al_fic_init_dt':
   irq-al-fic.c:(.init.text+0x62): undefined reference to `of_iomap'
   s390-linux-ld: irq-al-fic.c:(.init.text+0x368): undefined reference to `iounmap'
   s390-linux-ld: drivers/clk/clk-fixed-mmio.o: in function `fixed_mmio_clk_setup':
   clk-fixed-mmio.c:(.text+0x3c): undefined reference to `of_iomap'
   s390-linux-ld: clk-fixed-mmio.c:(.text+0x7e): undefined reference to `iounmap'
   s390-linux-ld: drivers/clocksource/timer-of.o: in function `timer_of_init':
   timer-of.c:(.init.text+0xc4): undefined reference to `of_iomap'
   s390-linux-ld: timer-of.c:(.init.text+0x5aa): undefined reference to `iounmap'
   s390-linux-ld: drivers/clocksource/timer-of.o: in function `timer_of_cleanup':
   timer-of.c:(.init.text+0x71a): undefined reference to `iounmap'
   s390-linux-ld: drivers/clocksource/timer-microchip-pit64b.o: in function `mchp_pit64b_dt_init_timer':
   timer-microchip-pit64b.c:(.init.text+0x52c): undefined reference to `of_iomap'
   s390-linux-ld: timer-microchip-pit64b.c:(.init.text+0xa0e): undefined reference to `iounmap'
   s390-linux-ld: drivers/clocksource/timer-xilinx.o: in function `xilinx_timer_init':
>> timer-xilinx.c:(.init.text+0x1ca): undefined reference to `of_iomap'
>> s390-linux-ld: timer-xilinx.c:(.init.text+0x804): undefined reference to `iounmap'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 28340 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210827/d3f96afb/attachment-0001.gz>

From t.schramm at manjaro.org  Thu Aug 26 22:03:57 2021
From: t.schramm at manjaro.org (Tobias Schramm)
Date: Fri, 27 Aug 2021 07:03:57 +0200
Subject: [PATCH] spi: rockchip: handle zero length transfers without timing out
Message-ID: <20210827050357.165409-1-t.schramm@manjaro.org>

Previously zero length transfers submitted to the Rokchip SPI driver would
time out in the SPI layer. This happens because the SPI peripheral does
not trigger a transfer completion interrupt for zero length transfers.

Fix that by completing zero length transfers immediately at start of
transfer.

Signed-off-by: Tobias Schramm <t.schramm at manjaro.org>
---
 drivers/spi/spi-rockchip.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 540861ca2ba3..553b6b9d0222 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -600,6 +600,12 @@ static int rockchip_spi_transfer_one(
 	int ret;
 	bool use_dma;
 
+	/* Zero length transfers won't trigger an interrupt on completion */
+	if (!xfer->len) {
+		spi_finalize_current_transfer(ctlr);
+		return 1;
+	}
+
 	WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
 		(readl_relaxed(rs->regs + ROCKCHIP_SPI_SR) & SR_BUSY));
 
-- 
2.33.0



From chiawei_wang at aspeedtech.com  Thu Aug 26 20:48:39 2021
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Fri, 27 Aug 2021 03:48:39 +0000
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <7e7378c49ecfb21fef6a0640f92c1b3a7a5878d0.camel@codeconstruct.com.au>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
 <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
 <7e7378c49ecfb21fef6a0640f92c1b3a7a5878d0.camel@codeconstruct.com.au>
Message-ID: <HK0PR06MB377997422D9508894936E39691C89@HK0PR06MB3779.apcprd06.prod.outlook.com>

Hi Jeremy,

Thanks for reviewing the patch.

> From: Jeremy Kerr <jk at codeconstruct.com.au>
> Sent: Friday, August 27, 2021 11:20 AM
> 
> Hi Chia-Wei,
> 
> [apologies for the re-send, dropping HTML part...]
> 
> > The Aspeed eSPI controller is slave device to communicate with the
> > master through the Enhanced Serial Peripheral Interface (eSPI).
> > All of the four eSPI channels, namely peripheral, virtual wire,
> > out-of-band, and flash are supported.
> 
> Great to have this added submitted upstream! A few comments though:
> 
> > ---
> > ?drivers/soc/aspeed/Kconfig???????????? |? 11 +
> > ?drivers/soc/aspeed/Makefile??????????? |?? 1 +
> > ?drivers/soc/aspeed/aspeed-espi-ctrl.c? | 205 +++++++++
> > ?drivers/soc/aspeed/aspeed-espi-ctrl.h? | 304 ++++++++++++
> > ?drivers/soc/aspeed/aspeed-espi-flash.h | 380 +++++++++++++++
> > ?drivers/soc/aspeed/aspeed-espi-ioc.h?? | 153 +++++++
> > ?drivers/soc/aspeed/aspeed-espi-oob.h?? | 611
> > +++++++++++++++++++++++++
> > ?drivers/soc/aspeed/aspeed-espi-perif.h | 539 ++++++++++++++++++++++
> > ?drivers/soc/aspeed/aspeed-espi-vw.h??? | 142 ++++++
> 
> This structure is a bit odd - you have the one -crtl.c file, which defines the
> actual driver, but then a bunch of headers that contain more code than
> header-type definitions.
> 
> Is there any reason that -flash, -ioc, -oob, -perif and -vw components can't be
> standard .c files?

The eSPI slave device comprises four channels, where each of them has individual functionality.
Putting the four channels driver code into a single file makes it hard to maintain and trace.

We did consider to make them standard .c files.
But it requires to export channel functions into kernel space although they are dedicated only to this eSPI driver.
As espi-ctrl needs to invoke corresponding channel functions when it is interrupted by eSPI events.

To avoid polluting kernel space, we decided to put driver code in header files and make the channel functions 'static'.

BTW, I once encountered .c file inclusion in other projects. Is it proper for Linux driver development?

> 
> Then, for the userspace ABI: it looks like you're exposing everything through
> new device-specific ioctls. Would it not make more sense to use existing
> interfaces? For example, the virtual wire bits could be regular GPIOs; the flash
> interface could be a mtd or block device.
> 
> I understand that we'll likely still need some level of custom device control, but
> the more we can use generic interfaces for, the less custom code (and
> interfaces) we'll need on the userspace side.
> 

eSPI communication is based on the its cycle packet format.
We intended to let userspace decided how to interpret and compose TX/RX packets including header, tag, length (encoded), and data.
IOCTL comes to our first mind as it also works in the 'packet' like paradigm.

Chiawei

From chiawei_wang at aspeedtech.com  Thu Aug 26 20:52:03 2021
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Fri, 27 Aug 2021 03:52:03 +0000
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <202108270732.OvBQ4K3D-lkp@intel.com>
References: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
 <202108270732.OvBQ4K3D-lkp@intel.com>
Message-ID: <HK0PR06MB377927BDCA9CC79B598251B291C89@HK0PR06MB3779.apcprd06.prod.outlook.com>

Aspeed 5th and 6th generation SoCs are based on the ARM 32-bits architecture.
Should we follow the report to make the driver 64-bits compatible?
Or revise the driver to use more specific data types?

Thanks.

Chiawei

> From: kernel test robot <lkp at intel.com>
> Sent: Friday, August 27, 2021 7:30 AM
> 
> Hi Chia-Wei,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on robh/for-next] [also build test ERROR on
> arm/for-next keystone/next soc/for-next rockchip/for-next
> arm64/for-next/core linus/master joel-aspeed/for-next v5.14-rc7
> next-20210826] [cannot apply to xlnx/master] [If your patch is applied to the
> wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:
> https://github.com/0day-ci/linux/commits/Chia-Wei-Wang/arm-aspeed-Add-e
> SPI-support/20210826-141737
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
> config: arm64-randconfig-r002-20210826 (attached as .config)
> compiler: aarch64-linux-gcc (GCC) 11.2.0 reproduce (this is a W=1 build):
>         wget
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O
> ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         #
> https://github.com/0day-ci/linux/commit/2980a1777c50754fe145f2e73ded873
> 9931c0712
>         git remote add linux-review https://github.com/0day-ci/linux
>         git fetch --no-tags linux-review
> Chia-Wei-Wang/arm-aspeed-Add-eSPI-support/20210826-141737
>         git checkout 2980a1777c50754fe145f2e73ded8739931c0712
>         # save the attached .config to linux build tree
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0
> make.cross ARCH=arm64
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp at intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>    In file included from drivers/soc/aspeed/aspeed-espi-ctrl.c:22:
>    drivers/soc/aspeed/aspeed-espi-perif.h: In function
> 'aspeed_espi_perif_alloc':
> >> drivers/soc/aspeed/aspeed-espi-perif.h:446:43: error: passing
> >> argument 3 of 'of_property_read_u32' from incompatible pointer type
> >> [-Werror=incompatible-pointer-types]
>      446 |
> &espi_perif->mcyc_saddr);
>          |
> ^~~~~~~~~~~~~~~~~~~~~~~
>          |                                           |
>          |                                           phys_addr_t
> * {aka long long unsigned int *}
>    In file included from include/linux/of_device.h:9,
>                     from drivers/soc/aspeed/aspeed-espi-ctrl.c:9:
>    include/linux/of.h:1249:45: note: expected 'u32 *' {aka 'unsigned int *'} but
> argument is of type 'phys_addr_t *' {aka 'long long unsigned int *'}
>     1249 |                                        u32 *out_value)
>          |                                        ~~~~~^~~~~~~~~
>    drivers/soc/aspeed/aspeed-espi-ctrl.c: In function
> 'aspeed_espi_ctrl_probe':
>    drivers/soc/aspeed/aspeed-espi-ctrl.c:98:30: warning: cast from pointer to
> integer of different size [-Wpointer-to-int-cast]
>       98 |         espi_ctrl->version =
> (uint32_t)of_device_get_match_data(dev);
>          |                              ^
>    cc1: some warnings being treated as errors
> 
> 
> vim +/of_property_read_u32 +446 drivers/soc/aspeed/aspeed-espi-perif.h
> 
>    422
>    423	static void *aspeed_espi_perif_alloc(struct device *dev, struct
> aspeed_espi_ctrl *espi_ctrl)
>    424	{
>    425		int rc;
>    426		struct aspeed_espi_perif *espi_perif;
>    427		struct aspeed_espi_perif_dma *dma;
>    428
>    429		espi_perif = devm_kzalloc(dev, sizeof(*espi_perif),
> GFP_KERNEL);
>    430		if (!espi_perif)
>    431			return ERR_PTR(-ENOMEM);
>    432
>    433		espi_perif->ctrl = espi_ctrl;
>    434
>    435		init_waitqueue_head(&espi_perif->wq);
>    436
>    437		spin_lock_init(&espi_perif->lock);
>    438
>    439		mutex_init(&espi_perif->pc_rx_mtx);
>    440		mutex_init(&espi_perif->pc_tx_mtx);
>    441		mutex_init(&espi_perif->np_tx_mtx);
>    442
>    443		espi_perif->mcyc_enable =
> of_property_read_bool(dev->of_node, "perif,memcyc-enable");
>    444		if (espi_perif->mcyc_enable) {
>    445			rc = of_property_read_u32(dev->of_node,
> "perif,memcyc-src-addr",
>  > 446						  &espi_perif->mcyc_saddr);
>    447			if (rc) {
>    448				dev_err(dev, "cannot get Host source address for
> memory cycle\n");
>    449				return ERR_PTR(-ENODEV);
>    450			}
>    451
>    452			rc = of_property_read_u32(dev->of_node,
> "perif,memcyc-size",
>    453						  &espi_perif->mcyc_size);
>    454			if (rc) {
>    455				dev_err(dev, "cannot get size for memory cycle\n");
>    456				return ERR_PTR(-ENODEV);
>    457			}
>    458
>    459			if (espi_perif->mcyc_size < PERIF_MEMCYC_SIZE_MIN)
>    460				espi_perif->mcyc_size = PERIF_MEMCYC_SIZE_MIN;
>    461			else
>    462				espi_perif->mcyc_size =
> roundup_pow_of_two(espi_perif->mcyc_size);
>    463
>    464			espi_perif->mcyc_mask = ~(espi_perif->mcyc_size - 1);
>    465			espi_perif->mcyc_virt = dma_alloc_coherent(dev,
> espi_perif->mcyc_size,
>    466								   &espi_perif->mcyc_taddr,
> GFP_KERNEL);
>    467			if (!espi_perif->mcyc_virt) {
>    468				dev_err(dev, "cannot allocate memory cycle
> region\n");
>    469				return ERR_PTR(-ENOMEM);
>    470			}
>    471		}
>    472
>    473		if (of_property_read_bool(dev->of_node, "perif,dma-mode")) {
>    474			dma = &espi_perif->dma;
>    475
>    476			dma->pc_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
>    477							     &dma->pc_tx_addr,
> GFP_KERNEL);
>    478			if (!dma->pc_tx_virt) {
>    479				dev_err(dev, "cannot allocate posted TX DMA
> buffer\n");
>    480				return ERR_PTR(-ENOMEM);
>    481			}
>    482
>    483			dma->pc_rx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
>    484							     &dma->pc_rx_addr,
> GFP_KERNEL);
>    485			if (!dma->pc_rx_virt) {
>    486				dev_err(dev, "cannot allocate posted RX DMA
> buffer\n");
>    487				return ERR_PTR(-ENOMEM);
>    488			}
>    489
>    490			dma->np_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
>    491					&dma->np_tx_addr, GFP_KERNEL);
>    492			if (!dma->np_tx_virt) {
>    493				dev_err(dev, "cannot allocate non-posted TX DMA
> buffer\n");
>    494				return ERR_PTR(-ENOMEM);
>    495			}
>    496
>    497			espi_perif->dma_mode = 1;
>    498		}
>    499
>    500		espi_perif->mdev.parent = dev;
>    501		espi_perif->mdev.minor = MISC_DYNAMIC_MINOR;
>    502		espi_perif->mdev.name = devm_kasprintf(dev, GFP_KERNEL,
> "%s", PERIF_MDEV_NAME);
>    503		espi_perif->mdev.fops = &aspeed_espi_perif_fops;
>    504		rc = misc_register(&espi_perif->mdev);
>    505		if (rc) {
>    506			dev_err(dev, "cannot register device\n");
>    507			return ERR_PTR(rc);
>    508		}
>    509
>    510		aspeed_espi_perif_enable(espi_perif);
>    511
>    512		return espi_perif;
>    513	}
>    514
> 
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From sumit.garg at linaro.org  Thu Aug 26 22:27:00 2021
From: sumit.garg at linaro.org (Sumit Garg)
Date: Fri, 27 Aug 2021 10:57:00 +0530
Subject: [PATCH v4 5/5] optee: add FF-A support
In-Reply-To: <20210826145213.GA1739293@jade>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
 <20210819110655.739318-6-jens.wiklander@linaro.org>
 <CAFA6WYNHrej1_yMZejLpG5u1WjN5XvpmS-zKWdLVZu=DEWd6xA@mail.gmail.com>
 <20210826145213.GA1739293@jade>
Message-ID: <CAFA6WYMuAgL0D7oQYoK_zaJ+2hjtyeeVHOgA4tfkurzGuQi6=g@mail.gmail.com>

 On Thu, 26 Aug 2021 at 20:22, Jens Wiklander <jens.wiklander at linaro.org> wrote:
>
> On Wed, Aug 25, 2021 at 05:12:45PM +0530, Sumit Garg wrote:
> > On Thu, 19 Aug 2021 at 16:37, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> > >
> > > Adds support for using FF-A [1] as transport to the OP-TEE driver.
> > >
> > > Introduces struct optee_msg_param_fmem which carries all information
> > > needed when OP-TEE is calling FFA_MEM_RETRIEVE_REQ to get the shared
> > > memory reference mapped by the hypervisor in S-EL2. Register usage is
> > > also updated to include the information needed.
> > >
> > > The FF-A part of this driver is enabled if CONFIG_ARM_FFA_TRANSPORT is
> > > enabled.
> > >
> > > [1] https://developer.arm.com/documentation/den0077/latest
> > > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > > ---
> > >  drivers/tee/optee/Makefile        |   3 +-
> > >  drivers/tee/optee/call.c          |  13 +-
> > >  drivers/tee/optee/core.c          |  16 +-
> > >  drivers/tee/optee/ffa_abi.c       | 907 ++++++++++++++++++++++++++++++
> > >  drivers/tee/optee/optee_ffa.h     | 153 +++++
> > >  drivers/tee/optee/optee_msg.h     |  27 +-
> > >  drivers/tee/optee/optee_private.h |  43 +-
> > >  7 files changed, 1148 insertions(+), 14 deletions(-)
> > >  create mode 100644 drivers/tee/optee/ffa_abi.c
> > >  create mode 100644 drivers/tee/optee/optee_ffa.h
> > >
> [snip]
> > > --- /dev/null
> > > +++ b/drivers/tee/optee/ffa_abi.c
> > > @@ -0,0 +1,907 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/*
> > > + * Copyright (c) 2021, Linaro Limited
> > > + */
> > > +
> > > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > > +
> > > +#include <linux/arm_ffa.h>
> > > +#include <linux/errno.h>
> > > +#include <linux/scatterlist.h>
> > > +#include <linux/sched.h>
> > > +#include <linux/slab.h>
> > > +#include <linux/string.h>
> > > +#include <linux/tee_drv.h>
> > > +#include <linux/types.h>
> > > +#include "optee_private.h"
> > > +#include "optee_ffa.h"
> > > +#include "optee_rpc_cmd.h"
> > > +
> > > +/*
> > > + * This file implement the FF-A ABI used when communicating with secure world
> > > + * OP-TEE OS via FF-A.
> > > + * This file is divided into the follow sections:
> >
> > s/follow/following/
>
> Thanks, I'll fix.
>
> [snip]
> > > +static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev,
> > > +                                   const struct ffa_dev_ops *ops,
> > > +                                   unsigned int *rpc_arg_count)
> > > +{
> > > +       struct ffa_send_direct_data data = { OPTEE_FFA_EXCHANGE_CAPABILITIES };
> > > +       int rc;
> > > +
> > > +       rc = ops->sync_send_receive(ffa_dev, &data);
> > > +       if (rc) {
> > > +               pr_err("Unexpected error %d", rc);
> > > +               return false;
> > > +       }
> > > +       if (data.data0) {
> > > +               pr_err("Unexpected exchange error %lu", data.data0);
> > > +               return false;
> > > +       }
> > > +
> > > +       *rpc_arg_count = (u8)data.data1;
> >
> > Why is this special capability required in case of FF-A? Is it true
> > that RPC arguments count will be fixed for all RPC commands?
>
> It's to allow this driver to preallocate the argument struct used when
> doing RPC. That way we can avoid the chicken and egg problem of allocating
> an RPC argumet struct just before doing the real RPC.
>
> This is the maximum number of arguments needed by secure world. In case
> a larger value ever is needed, secure world will be able to supply the
> needed value.
>
> I plan to update the SMC based ABI with this also, but not in the patch
> set.
>

Okay, I see the requirement with FF-A ABI that we need to pass memory
reference to "struct thread_rpc_arg" while in case of SMC ABI we
directly pass the RPC commands in registers which allows it to work
without pre-allocation.

So I am fine with this approach as well given that the pre-allocated
memory for RPC arguments may be left unused in some cases but that's
fine when compared with the overhead of extra RPC calls with SMC ABI.

> >
> > > +
> > > +       return true;
> > > +}
>
> [snip]
> > > +static int optee_ffa_probe(struct ffa_device *ffa_dev)
> > > +{
> > > +       const struct ffa_dev_ops *ffa_ops;
> > > +       unsigned int rpc_arg_count;
> > > +       struct tee_device *teedev;
> > > +       struct optee *optee;
> > > +       int rc;
> > > +
> > > +       ffa_ops = ffa_dev_ops_get(ffa_dev);
> > > +       if (!ffa_ops) {
> > > +               pr_warn("failed \"method\" init: ffa\n");
> > > +               return -ENOENT;
> > > +       }
> > > +
> > > +       if (!optee_ffa_api_is_compatbile(ffa_dev, ffa_ops))
> > > +               return -EINVAL;
> > > +
> > > +       if (!optee_ffa_exchange_caps(ffa_dev, ffa_ops, &rpc_arg_count))
> > > +               return -EINVAL;
> > => +
> > > +       optee = kzalloc(sizeof(*optee), GFP_KERNEL);
> > > +       if (!optee) {
> > > +               rc = -ENOMEM;
> > > +               goto err;
> > > +       }
> > > +       optee->pool = optee_ffa_config_dyn_shm();
> > > +       if (IS_ERR(optee->pool)) {
> > > +               rc = PTR_ERR(optee->pool);
> > > +               optee->pool = NULL;
> > > +               goto err;
> > > +       }
> >
> > IIUC, with FF-A we will only be supporting dynamic shared memory. So
> > CFG_CORE_DYN_SHM=y should be enforced in OP-TEE OS when
> > CFG_CORE_FFA=y, but I don't see that currently. Am I missing
> > something?
>
> You mean in optee_os.git? With FF-A dynamic shared memory is always
> handled, so that flag in irrelevant in that case. However, feel free to
> start a discussion on that topic at github.

Ah, I see. You are correct that FF-A enables dynamic shared memory by default.

FWIW, feel free to add:

Acked-by: Sumit Garg <sumit.garg at linaro.org>

-Sumit

>
> Thanks,
> Jens


From dsahern at gmail.com  Thu Aug 26 22:28:29 2021
From: dsahern at gmail.com (David Ahern)
Date: Thu, 26 Aug 2021 22:28:29 -0700
Subject: [PATCH net-next v5] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value
In-Reply-To: <20210826064603.5242-1-rocco.yue@mediatek.com>
References: <20210826064603.5242-1-rocco.yue@mediatek.com>
Message-ID: <6a870141-089d-5e2b-48a7-448695e26238@gmail.com>

On 8/25/21 11:46 PM, Rocco Yue wrote:
> @@ -5651,6 +5654,9 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
>  	if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
>  		goto nla_put_failure;
>  
> +	if (nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))

I should have seen this earlier. The intent here is to only notify
userspace if the RA contains an MTU in which case this should be

	if (idev->ra_mtu &&
	    nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))

and in which case idev->ra_mtu should be initialized to 0 explicitly,
not U32_MIN.



From chiawei_wang at aspeedtech.com  Thu Aug 26 20:08:19 2021
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Fri, 27 Aug 2021 03:08:19 +0000
Subject: [PATCH v3 1/4] dt-bindings: aspeed: Add eSPI controller
In-Reply-To: <1629984361.334223.1033382.nullmailer@robh.at.kernel.org>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
 <20210826061623.6352-2-chiawei_wang@aspeedtech.com>
 <1629984361.334223.1033382.nullmailer@robh.at.kernel.org>
Message-ID: <HK0PR06MB3779F7F75D24326E6F0DB23591C89@HK0PR06MB3779.apcprd06.prod.outlook.com>

> From: Rob Herring <robh at kernel.org>
> Sent: Thursday, August 26, 2021 9:26 PM
> 
> On Thu, 26 Aug 2021 14:16:20 +0800, Chia-Wei Wang wrote:
> > Add dt-bindings for Aspeed eSPI controller
> >
> > Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
> > ---
> >  .../devicetree/bindings/soc/aspeed/espi.yaml  | 157
> > ++++++++++++++++++
> >  1 file changed, 157 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/soc/aspeed/espi.yaml
> >
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m
> dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/as
> peed/espi.example.dt.yaml: espi at 1e6ee000: 'espi-ctrl at 0', 'espi-mmbi at 800'
> do not match any of the regexes: 'pinctrl-[0-9]+'
> 	From schema:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/as
> peed/espi.yaml
> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/patch/1520968
> 
> This check can fail if there are any dependencies. The base for a patch series is
> generally the most recent rc1.
> 
> If you already ran 'make dt_binding_check' and didn't see the above error(s),
> then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.

The warning has been fixed by using patternProperties to define the espi-ctrl and the espi-mmbi child nodes.
The updated version will be submitted soon. Thanks.

Chiawei


From joel at jms.id.au  Thu Aug 26 22:48:50 2021
From: joel at jms.id.au (Joel Stanley)
Date: Fri, 27 Aug 2021 05:48:50 +0000
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <HK0PR06MB377927BDCA9CC79B598251B291C89@HK0PR06MB3779.apcprd06.prod.outlook.com>
References: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
 <202108270732.OvBQ4K3D-lkp@intel.com>
 <HK0PR06MB377927BDCA9CC79B598251B291C89@HK0PR06MB3779.apcprd06.prod.outlook.com>
Message-ID: <CACPK8Xf1g2fp5X3ELBUyjzP6Fmvt1XWLU_UgCKdZaDVjdyKryQ@mail.gmail.com>

On Fri, 27 Aug 2021 at 03:52, ChiaWei Wang <chiawei_wang at aspeedtech.com> wrote:
>
> Aspeed 5th and 6th generation SoCs are based on the ARM 32-bits architecture.
> Should we follow the report to make the driver 64-bits compatible?
> Or revise the driver to use more specific data types?

Yes, in general it's expected your driver will compile cleanly for
64-bit architectures. This helps with testing and static analysis,
where CI builds all the drivers for x86.

Cheers,

Joel


From sumit.garg at linaro.org  Thu Aug 26 23:23:12 2021
From: sumit.garg at linaro.org (Sumit Garg)
Date: Fri, 27 Aug 2021 11:53:12 +0530
Subject: [PATCH v5 4/6] tee: add tee_dev_open_helper() primitive
In-Reply-To: <20210826123032.1732926-5-jens.wiklander@linaro.org>
References: <20210826123032.1732926-1-jens.wiklander@linaro.org>
 <20210826123032.1732926-5-jens.wiklander@linaro.org>
Message-ID: <CAFA6WYM_zaVsWzP-sDuD6_xf3qgv-sQsbEAebZG6vtFrKfRpag@mail.gmail.com>

On Thu, 26 Aug 2021 at 18:00, Jens Wiklander <jens.wiklander at linaro.org> wrote:
>
> Adds tee_dev_open_helper() and tee_dev_ctx_put() to make it easier to
> create a driver internal struct tee_context without the usual
> tee_device_get() on the struct tee_device as that adds a circular
> reference counter dependency and would prevent the struct tee_device
> from ever being released again.

Can you elaborate regarding the circular dependency issue you are
referring to? IIUC, lifespan for struct tee_device would look like
below with normal teedev_open():

optee_probe() {
  ...
  tee_device_alloc()            <- teedev->num_users = 1
  tee_device_register()
  optee_notif_init()               <- tee_device_get()
  ...
}

optee_remove() {
  ...
  optee_notif_uninit()           <- tee_device_put()
  tee_device_unregister()    <- tee_device_put()
  ...
}

-Sumit

>
> Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> ---
>  drivers/tee/tee_core.c  | 33 ++++++++++++++++++++++++---------
>  include/linux/tee_drv.h | 27 +++++++++++++++++++++++++++
>  2 files changed, 51 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
> index 85102d12d716..3beb682684a8 100644
> --- a/drivers/tee/tee_core.c
> +++ b/drivers/tee/tee_core.c
> @@ -43,14 +43,11 @@ static DEFINE_SPINLOCK(driver_lock);
>  static struct class *tee_class;
>  static dev_t tee_devt;
>
> -static struct tee_context *teedev_open(struct tee_device *teedev)
> +struct tee_context *tee_dev_open_helper(struct tee_device *teedev)
>  {
>         int rc;
>         struct tee_context *ctx;
>
> -       if (!tee_device_get(teedev))
> -               return ERR_PTR(-EINVAL);
> -
>         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
>         if (!ctx) {
>                 rc = -ENOMEM;
> @@ -66,10 +63,30 @@ static struct tee_context *teedev_open(struct tee_device *teedev)
>         return ctx;
>  err:
>         kfree(ctx);
> -       tee_device_put(teedev);
>         return ERR_PTR(rc);
>
>  }
> +EXPORT_SYMBOL_GPL(tee_dev_open_helper);
> +
> +void tee_dev_ctx_put(struct tee_context *ctx)
> +{
> +       teedev_ctx_put(ctx);
> +}
> +EXPORT_SYMBOL_GPL(tee_dev_ctx_put);
> +
> +static struct tee_context *teedev_open(struct tee_device *teedev)
> +{
> +       struct tee_context *ctx;
> +
> +       if (!tee_device_get(teedev))
> +               return ERR_PTR(-EINVAL);
> +
> +       ctx = tee_dev_open_helper(teedev);
> +       if (IS_ERR(ctx))
> +               tee_device_put(teedev);
> +
> +       return ctx;
> +}
>
>  void teedev_ctx_get(struct tee_context *ctx)
>  {
> @@ -90,10 +107,8 @@ static void teedev_ctx_release(struct kref *ref)
>
>  void teedev_ctx_put(struct tee_context *ctx)
>  {
> -       if (ctx->releasing)
> -               return;
> -
> -       kref_put(&ctx->refcount, teedev_ctx_release);
> +       if (ctx && !ctx->releasing)
> +               kref_put(&ctx->refcount, teedev_ctx_release);
>  }
>
>  static void teedev_close_context(struct tee_context *ctx)
> diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
> index 3ebfea0781f1..00a31ff03049 100644
> --- a/include/linux/tee_drv.h
> +++ b/include/linux/tee_drv.h
> @@ -458,6 +458,33 @@ static inline int tee_shm_get_id(struct tee_shm *shm)
>   */
>  struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
>
> +/**
> + * tee_dev_open_helper() - helper function to make a struct tee_context
> + * @teedev:    Device to open
> + *
> + * Creates the struct tee_context without increasing the reference counter
> + * on @teedev. This is needed for instance when a driver need an internal
> + * struct tee_context to operate on. By skipping the reference counter
> + * the circular dependency is broken.
> + *
> + * Note that this struct tee_context need special care when freeing in
> + * order to avoid the normal put on the struct tee_device.
> + * tee_dev_ctx_put() is the best choice for this.
> + *
> + * @returns a pointer 'struct tee_context' on success or an ERR_PTR on failure
> + */
> +struct tee_context *tee_dev_open_helper(struct tee_device *teedev);
> +
> +/**
> + * tee_dev_ctx_put() - helper function to release a struct tee_context
> + * @ctx:       The struct tee_context to release
> + *
> + * Note that this function doesn't do a tee_device_put() on the internal
> + * struct tee_device so this function should normal only be used when
> + * releasing a struct tee_context obtained with tee_dev_open_helper().
> + */
> +void tee_dev_ctx_put(struct tee_context *ctx);
> +
>  /**
>   * tee_client_open_context() - Open a TEE context
>   * @start:     if not NULL, continue search after this context
> --
> 2.31.1
>


From like.xu.linux at gmail.com  Thu Aug 26 23:31:43 2021
From: like.xu.linux at gmail.com (Like Xu)
Date: Fri, 27 Aug 2021 14:31:43 +0800
Subject: [PATCH V10 01/18] perf/core: Use static_call to optimize
 perf_guest_info_callbacks
In-Reply-To: <YSfykbECnC6J02Yk@google.com>
References: <20210806133802.3528-1-lingshan.zhu@intel.com>
 <20210806133802.3528-2-lingshan.zhu@intel.com> <YSfykbECnC6J02Yk@google.com>
Message-ID: <2f3d9676-3f49-3963-20d5-7aaf81ce996e@gmail.com>

On 27/8/2021 3:59 am, Sean Christopherson wrote:
> TL;DR: Please don't merge this patch, it's broken and is also built on a shoddy
>         foundation that I would like to fix.

Obviously, this patch is not closely related to the guest PEBS feature enabling,
and we can certainly put this issue in another discussion thread [1].

[1] https://lore.kernel.org/kvm/20210827005718.585190-1-seanjc at google.com/

> 
> On Fri, Aug 06, 2021, Zhu Lingshan wrote:
>> diff --git a/kernel/events/core.c b/kernel/events/core.c
>> index 464917096e73..e466fc8176e1 100644
>> --- a/kernel/events/core.c
>> +++ b/kernel/events/core.c
>> @@ -6489,9 +6489,18 @@ static void perf_pending_event(struct irq_work *entry)
>>    */
>>   struct perf_guest_info_callbacks *perf_guest_cbs;
>>   
>> +/* explicitly use __weak to fix duplicate symbol error */
>> +void __weak arch_perf_update_guest_cbs(void)
>> +{
>> +}
>> +
>>   int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
>>   {
>> +	if (WARN_ON_ONCE(perf_guest_cbs))
>> +		return -EBUSY;
>> +
>>   	perf_guest_cbs = cbs;
>> +	arch_perf_update_guest_cbs();
> 
> This is horribly broken, it fails to cleanup the static calls when KVM unregisters
> the callbacks, which happens when the vendor module, e.g. kvm_intel, is unloaded.
> The explosion doesn't happen until 'kvm' is unloaded because the functions are
> implemented in 'kvm', i.e. the use-after-free is deferred a bit.
> 
>    BUG: unable to handle page fault for address: ffffffffa011bb90
>    #PF: supervisor instruction fetch in kernel mode
>    #PF: error_code(0x0010) - not-present page
>    PGD 6211067 P4D 6211067 PUD 6212063 PMD 102b99067 PTE 0
>    Oops: 0010 [#1] PREEMPT SMP
>    CPU: 0 PID: 1047 Comm: rmmod Not tainted 5.14.0-rc2+ #460
>    Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
>    RIP: 0010:0xffffffffa011bb90
>    Code: Unable to access opcode bytes at RIP 0xffffffffa011bb66.
>    Call Trace:
>     <NMI>
>     ? perf_misc_flags+0xe/0x50
>     ? perf_prepare_sample+0x53/0x6b0
>     ? perf_event_output_forward+0x67/0x160
>     ? kvm_clock_read+0x14/0x30
>     ? kvm_sched_clock_read+0x5/0x10
>     ? sched_clock_cpu+0xd/0xd0
>     ? __perf_event_overflow+0x52/0xf0
>     ? handle_pmi_common+0x1f2/0x2d0
>     ? __flush_tlb_all+0x30/0x30
>     ? intel_pmu_handle_irq+0xcf/0x410
>     ? nmi_handle+0x5/0x260
>     ? perf_event_nmi_handler+0x28/0x50
>     ? nmi_handle+0xc7/0x260
>     ? lock_release+0x2b0/0x2b0
>     ? default_do_nmi+0x6b/0x170
>     ? exc_nmi+0x103/0x130
>     ? end_repeat_nmi+0x16/0x1f
>     ? lock_release+0x2b0/0x2b0
>     ? lock_release+0x2b0/0x2b0
>     ? lock_release+0x2b0/0x2b0
>     </NMI>
>    Modules linked in: irqbypass [last unloaded: kvm]
> 
> Even more fun, the existing perf_guest_cbs framework is also broken, though it's
> much harder to get it to fail, and probably impossible to get it to fail without
> some help.  The issue is that perf_guest_cbs is global, which means that it can
> be nullified by KVM (during module unload) while the callbacks are being accessed
> by a PMI handler on a different CPU.
> 
> The bug has escaped notice because all dererfences of perf_guest_cbs follow the
> same "perf_guest_cbs && perf_guest_cbs->is_in_guest()" pattern, and AFAICT the
> compiler never reload perf_guest_cbs in this sequence.  The compiler does reload
> perf_guest_cbs for any future dereferences, but the ->is_in_guest() guard all but
> guarantees the PMI handler will win the race, e.g. to nullify perf_guest_cbs,
> KVM has to completely exit the guest and teardown down all VMs before it can be
> unloaded.
> 
> But with a help, e.g. RAED_ONCE(perf_guest_cbs), unloading kvm_intel can trigger
> a NULL pointer derference, e.g. this tweak
> 
> diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
> index 1eb45139fcc6..202e5ad97f82 100644
> --- a/arch/x86/events/core.c
> +++ b/arch/x86/events/core.c
> @@ -2954,7 +2954,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
>   {
>          int misc = 0;
> 
> -       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
> +       if (READ_ONCE(perf_guest_cbs) && READ_ONCE(perf_guest_cbs)->is_in_guest()) {
>                  if (perf_guest_cbs->is_user_mode())
>                          misc |= PERF_RECORD_MISC_GUEST_USER;
>                  else
> 
> 
> while spamming module load/unload leads to:
> 
>    BUG: kernel NULL pointer dereference, address: 0000000000000000
>    #PF: supervisor read access in kernel mode
>    #PF: error_code(0x0000) - not-present page
>    PGD 0 P4D 0
>    Oops: 0000 [#1] PREEMPT SMP
>    CPU: 6 PID: 1825 Comm: stress Not tainted 5.14.0-rc2+ #459
>    Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
>    RIP: 0010:perf_misc_flags+0x1c/0x70
>    Call Trace:
>     perf_prepare_sample+0x53/0x6b0
>     perf_event_output_forward+0x67/0x160
>     __perf_event_overflow+0x52/0xf0
>     handle_pmi_common+0x207/0x300
>     intel_pmu_handle_irq+0xcf/0x410
>     perf_event_nmi_handler+0x28/0x50
>     nmi_handle+0xc7/0x260
>     default_do_nmi+0x6b/0x170
>     exc_nmi+0x103/0x130
>     asm_exc_nmi+0x76/0xbf
> 
> 
> The good news is that I have a series that should fix both the existing NULL pointer
> bug and mostly obviate the need for static calls.  The bad news is that my approach,
> making perf_guest_cbs per-CPU, likely complicates turning these into static calls,
> though I'm guessing it's still a solvable problem.
> 
> Tangentially related, IMO we should make architectures opt-in to getting
> perf_guest_cbs and nuke all of the code in the below files.  Except for arm,
> which recently lost KVM support, it's all a bunch of useless copy-paste code that
> serves no purpose and just complicates cleanups like this.
> 
>>   arch/arm/kernel/perf_callchain.c   | 16 +++++++-----
>>   arch/csky/kernel/perf_callchain.c  |  4 +--
>>   arch/nds32/kernel/perf_event_cpu.c | 16 +++++++-----
>>   arch/riscv/kernel/perf_callchain.c |  4 +--


From S.Riedmueller at phytec.de  Thu Aug 26 23:43:06 2021
From: S.Riedmueller at phytec.de (=?utf-8?B?U3RlZmFuIFJpZWRtw7xsbGVy?=)
Date: Fri, 27 Aug 2021 06:43:06 +0000
Subject: [PATCH 2/2] clk: imx: imx6ul: Fix csi clk gate register
In-Reply-To: <CAOMZO5DR7awy7mxr3=qXiEmSG10MX15hc2MJCSajN+gW8=ryuw@mail.gmail.com>
References: <20210826152049.4175381-1-s.riedmueller@phytec.de>
 <20210826152049.4175381-2-s.riedmueller@phytec.de>
 <CAOMZO5DR7awy7mxr3=qXiEmSG10MX15hc2MJCSajN+gW8=ryuw@mail.gmail.com>
Message-ID: <1f1b90c7d2dfa2e80f9a0a7c4bc20d99e7177389.camel@phytec.de>

Hi Fabio,

On Thu, 2021-08-26 at 17:10 -0300, Fabio Estevam wrote:
> Hi Stefan,
> 
> On Thu, Aug 26, 2021 at 12:20 PM Stefan Riedmueller
> <s.riedmueller at phytec.de> wrote:
> > According to the imx6ul Reference Manual the csi clk gate register is
> > CCM_CCGR3 (offset 0x74) bit 0/1. For the imx6ull on the other hand the
> > Reference Manual lists register CCM_CCGR2 (offset 0x70) bit 2/3 as the
> > csi clk gate which is the current setting.
> > 
> > Tests have shown though that the correct csi clk gate register for the
> > imx6ull is actually CCM_CCGR3 bit 0/1 as well. Thus set the correct
> > register for both platforms.
> > 
> > Signed-off-by: Stefan Riedmueller <s.riedmueller at phytec.de>
> 
> I tested the series on an imx6ull-evk with an OV5640 sensor:
> 
> Tested-by: Fabio Estevam <festevam at gmail.com>
> 
> but in my case, I did not see the problem even without your patch.
> 
> Most likely because the bootloader turned on the CSI clock.

thanks for your testing and review.

You're right, the csi clock is enabled by default and thus the issue only
arises when you try to disable the clock e.g. to save power on a connected
sensor.

> 
> > ---
> >  drivers/clk/imx/clk-imx6ul.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
> > index 206e4c43f68f..5dd222fab01b 100644
> > --- a/drivers/clk/imx/clk-imx6ul.c
> > +++ b/drivers/clk/imx/clk-imx6ul.c
> > @@ -380,7 +380,6 @@ static void __init imx6ul_clocks_init(struct
> > device_node *ccm_node)
> >                 hws[IMX6ULL_CLK_ESAI_IPG]       =
> > imx_clk_hw_gate2_shared("esai_ipg",   "ahb",          base + 0x70,    0,
> > &share_count_esai);
> >                 hws[IMX6ULL_CLK_ESAI_MEM]       =
> > imx_clk_hw_gate2_shared("esai_mem",   "ahb",          base + 0x70,    0,
> > &share_count_esai);
> >         }
> > -       hws[IMX6UL_CLK_CSI]             =
> > imx_clk_hw_gate2("csi",               "csi_podf",             base +
> > 0x70,    2);
> >         hws[IMX6UL_CLK_I2C1]            =
> > imx_clk_hw_gate2("i2c1",              "perclk",       base + 0x70,    6);
> >         hws[IMX6UL_CLK_I2C2]            =
> > imx_clk_hw_gate2("i2c2",              "perclk",       base + 0x70,    8);
> >         hws[IMX6UL_CLK_I2C3]            =
> > imx_clk_hw_gate2("i2c3",              "perclk",       base + 0x70,    10);
> > @@ -391,6 +390,7 @@ static void __init imx6ul_clocks_init(struct
> > device_node *ccm_node)
> >         hws[IMX6UL_CLK_PXP]             =
> > imx_clk_hw_gate2("pxp",               "axi",          base + 0x70,    30);
> > 
> >         /* CCGR3 */
> 
> It would be nice to put a comment here explaining the imx6ull
> Reference Manual mismatch.

Sure I will prepare something.

> 
> Maybe Abel could help to check internally at NXP?

Yes, that would be nice!

Regards,
Stefan

> 
> > +       hws[IMX6UL_CLK_CSI]             =
> > imx_clk_hw_gate2("csi",       "csi_podf",     base + 0x74,    0);
> 
> Thanks

From like.xu.linux at gmail.com  Thu Aug 26 23:52:25 2021
From: like.xu.linux at gmail.com (Like Xu)
Date: Fri, 27 Aug 2021 14:52:25 +0800
Subject: [PATCH 00/15] perf: KVM: Fix, optimize, and clean up callbacks
In-Reply-To: <20210827005718.585190-1-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
Message-ID: <fd3dcd6c-b3d5-4453-93fb-b46d0595534e@gmail.com>

+ STATIC BRANCH/CALL friends.

On 27/8/2021 8:57 am, Sean Christopherson wrote:
> This started out as a small series[1] to fix a KVM bug related to Intel PT
> interrupt handling and snowballed horribly.
> 
> The main problem being addressed is that the perf_guest_cbs are shared by
> all CPUs, can be nullified by KVM during module unload, and are not
> protected against concurrent access from NMI context.

Shouldn't this be a generic issue of the static_call() usage ?

At the beginning, we set up the static entry assuming perf_guest_cbs != NULL:

	if (perf_guest_cbs && perf_guest_cbs->handle_intel_pt_intr) {
		static_call_update(x86_guest_handle_intel_pt_intr,
				   perf_guest_cbs->handle_intel_pt_intr);
	}

and then we unset the perf_guest_cbs and do the static function call like this:

DECLARE_STATIC_CALL(x86_guest_handle_intel_pt_intr, 
*(perf_guest_cbs->handle_intel_pt_intr));
static int handle_pmi_common(struct pt_regs *regs, u64 status)
{
		...
		if (!static_call(x86_guest_handle_intel_pt_intr)())
			intel_pt_interrupt();
		...
}

Can we make static_call() back to the original "(void *)&__static_call_return0" 
in this case ?

> 
> The bug has escaped notice because all dereferences of perf_guest_cbs
> follow the same "perf_guest_cbs && perf_guest_cbs->is_in_guest()" pattern,
> and AFAICT the compiler never reloads perf_guest_cbs in this sequence.
> The compiler does reload perf_guest_cbs for any future dereferences, but
> the ->is_in_guest() guard all but guarantees the PMI handler will win the
> race, e.g. to nullify perf_guest_cbs, KVM has to completely exit the guest
> and teardown down all VMs before it can be unloaded.
> 
> But with help, e.g. READ_ONCE(perf_guest_cbs), unloading kvm_intel can
> trigger a NULL pointer derference (see below).  Manual intervention aside,
> the bug is a bit of a time bomb, e.g. my patch 3 from the original PT
> handling series would have omitted the ->is_in_guest() guard.
> 
> This series fixes the problem by making the callbacks per-CPU, and
> registering/unregistering the callbacks only with preemption disabled
> (except for the Xen case, which doesn't unregister).
> 
> This approach also allows for several nice cleanups in this series.
> KVM x86 and arm64 can share callbacks, KVM x86 drops its somewhat
> redundant current_vcpu, and the retpoline that is currently hit when KVM
> is loaded (due to always checking ->is_in_guest()) goes away (it's still
> there when running as Xen Dom0).
> 
> Changing to per-CPU callbacks also provides a good excuse to excise
> copy+paste code from architectures that can't possibly have guest
> callbacks.
> 
> This series conflicts horribly with a proposed patch[2] to use static
> calls for perf_guest_cbs.  But that patch is broken as it completely
> fails to handle unregister, and it's not clear to me whether or not
> it can correctly handle unregister without fixing the underlying race
> (I don't know enough about the code patching for static calls).
> 
> This tweak
> 
> diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
> index 1eb45139fcc6..202e5ad97f82 100644
> --- a/arch/x86/events/core.c
> +++ b/arch/x86/events/core.c
> @@ -2954,7 +2954,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
>   {
>          int misc = 0;
> 
> -       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
> +       if (READ_ONCE(perf_guest_cbs) && READ_ONCE(perf_guest_cbs)->is_in_guest()) {
>                  if (perf_guest_cbs->is_user_mode())
>                          misc |= PERF_RECORD_MISC_GUEST_USER;
>                  else
> 
> while spamming module load/unload leads to:
> 
>    BUG: kernel NULL pointer dereference, address: 0000000000000000
>    #PF: supervisor read access in kernel mode
>    #PF: error_code(0x0000) - not-present page
>    PGD 0 P4D 0
>    Oops: 0000 [#1] PREEMPT SMP
>    CPU: 6 PID: 1825 Comm: stress Not tainted 5.14.0-rc2+ #459
>    Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
>    RIP: 0010:perf_misc_flags+0x1c/0x70
>    Call Trace:
>     perf_prepare_sample+0x53/0x6b0
>     perf_event_output_forward+0x67/0x160
>     __perf_event_overflow+0x52/0xf0
>     handle_pmi_common+0x207/0x300
>     intel_pmu_handle_irq+0xcf/0x410
>     perf_event_nmi_handler+0x28/0x50
>     nmi_handle+0xc7/0x260
>     default_do_nmi+0x6b/0x170
>     exc_nmi+0x103/0x130
>     asm_exc_nmi+0x76/0xbf
> 
> [1] https://lkml.kernel.org/r/20210823193709.55886-1-seanjc at google.com
> [2] https://lkml.kernel.org/r/20210806133802.3528-2-lingshan.zhu at intel.com
> 
> Sean Christopherson (15):
>    KVM: x86: Register perf callbacks after calling vendor's
>      hardware_setup()
>    KVM: x86: Register Processor Trace interrupt hook iff PT enabled in
>      guest
>    perf: Stop pretending that perf can handle multiple guest callbacks
>    perf: Force architectures to opt-in to guest callbacks
>    perf: Track guest callbacks on a per-CPU basis
>    KVM: x86: Register perf callbacks only when actively handling
>      interrupt
>    KVM: Use dedicated flag to track if KVM is handling an NMI from guest
>    KVM: x86: Drop current_vcpu in favor of kvm_running_vcpu
>    KVM: arm64: Register/unregister perf callbacks at vcpu load/put
>    KVM: Move x86's perf guest info callbacks to generic KVM
>    KVM: x86: Move Intel Processor Trace interrupt handler to vmx.c
>    KVM: arm64: Convert to the generic perf callbacks
>    KVM: arm64: Drop perf.c and fold its tiny bit of code into pmu.c
>    perf: Disallow bulk unregistering of guest callbacks and do cleanup
>    perf: KVM: Indicate "in guest" via NULL ->is_in_guest callback
> 
>   arch/arm/kernel/perf_callchain.c   | 28 ++------------
>   arch/arm64/Kconfig                 |  1 +
>   arch/arm64/include/asm/kvm_host.h  |  8 +++-
>   arch/arm64/kernel/perf_callchain.c | 18 ++++++---
>   arch/arm64/kvm/Makefile            |  2 +-
>   arch/arm64/kvm/arm.c               | 13 ++++++-
>   arch/arm64/kvm/perf.c              | 62 ------------------------------
>   arch/arm64/kvm/pmu.c               |  8 ++++
>   arch/csky/kernel/perf_callchain.c  | 10 -----
>   arch/nds32/kernel/perf_event_cpu.c | 29 ++------------
>   arch/riscv/kernel/perf_callchain.c | 10 -----
>   arch/x86/Kconfig                   |  1 +
>   arch/x86/events/core.c             | 17 +++++---
>   arch/x86/events/intel/core.c       |  7 ++--
>   arch/x86/include/asm/kvm_host.h    |  4 +-
>   arch/x86/kvm/pmu.c                 |  2 +-
>   arch/x86/kvm/pmu.h                 |  1 +
>   arch/x86/kvm/svm/svm.c             |  2 +-
>   arch/x86/kvm/vmx/vmx.c             | 25 ++++++++++--
>   arch/x86/kvm/x86.c                 | 54 +++-----------------------
>   arch/x86/kvm/x86.h                 | 12 +++---
>   arch/x86/xen/pmu.c                 |  2 +-
>   include/kvm/arm_pmu.h              |  1 +
>   include/linux/kvm_host.h           | 12 ++++++
>   include/linux/perf_event.h         | 33 ++++++++++++----
>   init/Kconfig                       |  3 ++
>   kernel/events/core.c               | 28 ++++++++------
>   virt/kvm/kvm_main.c                | 42 ++++++++++++++++++++
>   28 files changed, 204 insertions(+), 231 deletions(-)
>   delete mode 100644 arch/arm64/kvm/perf.c
> 


From Chunfeng.Yun at mediatek.com  Thu Aug 26 23:49:27 2021
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Fri, 27 Aug 2021 06:49:27 +0000
Subject: [PATCH next v2 3/6] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <CAATdQgBD+dTtBie-cNKRJbfxEpc3haqjfUu1k26mTk8pCSOEww@mail.gmail.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
 <20210826025144.51992-3-chunfeng.yun@mediatek.com>
 <CAATdQgBD+dTtBie-cNKRJbfxEpc3haqjfUu1k26mTk8pCSOEww@mail.gmail.com>
Message-ID: <72ee7a203d8a49e6e43a954b45133470ee6d5c16.camel@mediatek.com>

On Thu, 2021-08-26 at 19:54 +0800, Ikjoon Jang wrote:
> Hi Chunfeng,
> 
> On Thu, Aug 26, 2021 at 10:52 AM Chunfeng Yun <
> chunfeng.yun at mediatek.com> wrote:
> > 
> > Use @bw_budget_table[] to update fs bus bandwidth due to
> > not all microframes consume @bw_cost_per_microframe, see
> > setup_sch_info().
> > 
> > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > ---
> > v2: new patch, move from another series
> > ---
> >  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
> >  1 file changed, 7 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/usb/host/xhci-mtk-sch.c
> > b/drivers/usb/host/xhci-mtk-sch.c
> > index cffcaf4dfa9f..83abd28269ca 100644
> > --- a/drivers/usb/host/xhci-mtk-sch.c
> > +++ b/drivers/usb/host/xhci-mtk-sch.c
> > @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct
> > mu3h_sch_ep_info *sch_ep, int offset)
> >                  * Compared with hs bus, no matter what ep type,
> >                  * the hub will always delay one uframe to send
> > data
> >                  */
> > -               for (j = 0; j < sch_ep->cs_count; j++) {
> > -                       tmp = tt->fs_bus_bw[base + j] + sch_ep-
> > >bw_cost_per_microframe;
> > +               for (j = 0; j < sch_ep->num_budget_microframes;
> > j++) {
> > +                       tmp = tt->fs_bus_bw[base + j] + sch_ep-
> > >bw_budget_table[j];
> 
> I'm worrying about this case with two endpoints,
> * EP1OUT: isochronous, maxpacket=192: bw_budget_table[] = { 188, 188,
> 0, ... }
> * EP2IN: interrupt, maxpacket=64: bw_budget_table[] = { 0, 0, 64, 64,
> ... }
> (Is this correct bw_budget_table contents for those eps?)
Yes, ep1out isoc use two uframe, ep2in intr use a extra cs;
> 
> I'm not sure if it's okay for those two endpoints to be allocated
> on the same u-frame slot.
> Can you please check if this is okay for xhci-mtk?
Already test it this afternoon, can transfer data rightly on our dvt
env.

> (I feel like I already asked the same questions many times.)
Yes, as said before, prefer to use bw_budget_table[], if there is
issue, we can fix it by building this table.

Thanks
> 
> 
> >                         if (tmp > FS_PAYLOAD_MAX)
> >                                 return -ESCH_BW_OVERFLOW;
> >                 }
> > @@ -534,21 +534,18 @@ static void update_sch_tt(struct
> > mu3h_sch_ep_info *sch_ep, bool used)
> >  {
> >         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
> >         u32 base, num_esit;
> > -       int bw_updated;
> >         int i, j;
> > 
> >         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> > 
> > -       if (used)
> > -               bw_updated = sch_ep->bw_cost_per_microframe;
> > -       else
> > -               bw_updated = -sch_ep->bw_cost_per_microframe;
> > -
> >         for (i = 0; i < num_esit; i++) {
> >                 base = sch_ep->offset + i * sch_ep->esit;
> > 
> > -               for (j = 0; j < sch_ep->cs_count; j++)
> > -                       tt->fs_bus_bw[base + j] += bw_updated;
> > +               for (j = 0; j < sch_ep->num_budget_microframes;
> > j++)
> > +                       if (used)
> > +                               tt->fs_bus_bw[base + j] += sch_ep-
> > >bw_budget_table[j];
> > +                       else
> > +                               tt->fs_bus_bw[base + j] -= sch_ep-
> > >bw_budget_table[j];
> >         }
> > 
> >         if (used)
> > --
> > 2.18.0
> > 

From ardb at kernel.org  Fri Aug 27 00:03:35 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 27 Aug 2021 09:03:35 +0200
Subject: [PATCH v7 0/7] running kernel mode SIMD with softirqs disabled
Message-ID: <20210827070342.218276-1-ardb@kernel.org>

This is a follow-up to [0], but given that the arm64 architectural
pieces have been merged for arm64, the only remaining changes are crypto
specific. Therefore, the audience has been reduced to those people who
are somewhat more likely to care about these specifics.

The AEAD and skcipher APIs may only be called from task or softirq
context. This permits the arm64 AEAD and skcipher code to get rid of all
scalar fallbacks, given that on this architecture, softirqs are now no
longer served while the SIMD unit is being used in kernel mode, which
means that the scalar fallbacks are never needed. These are removed in
this series.

Changes since v6:
- add patch to yield the NEON every 4k of input when processing the AAD
- add some more acks from Eric

Changes since v5:
- add Eric's R-b to patches #1 to #3
- split CCM changes into 3 separate patches

Changes since v4:
- drop skcipher_walk layer change to deal with zero sized walks
- drop aead/skcipher layer sanity checks on invocations from hardirq
  context
- add patch to clean up CCM a bit more after removing the SIMD code path

Changes since v3:
- clarify the nature of the issue addressed by patch #1, and apply the
  same fix to the skcipher walker
- update patches #2 and #3 so that the failures can be observed by the
  crypto stats code

[0] https://lore.kernel.org/linux-arm-kernel/20210302090118.30666-1-ardb at kernel.org/

Ard Biesheuvel (7):
  crypto: arm64/gcm-aes-ce - remove non-SIMD fallback path
  crypto: arm64/aes-neonbs - stop using SIMD helper for skciphers
  crypto: arm64/aes-ce - stop using SIMD helper for skciphers
  crypto: arm64/aes-ccm - yield NEON when processing auth-only data
  crypto: arm64/aes-ccm - remove non-SIMD fallback path
  crypto: arm64/aes-ccm - reduce NEON begin/end calls for common case
  crypto: arm64/aes-ccm - avoid by-ref argument for ce_aes_ccm_auth_data

 arch/arm64/crypto/Kconfig           |   6 -
 arch/arm64/crypto/aes-ce-ccm-core.S |  24 +--
 arch/arm64/crypto/aes-ce-ccm-glue.c | 203 ++++++-------------
 arch/arm64/crypto/aes-glue.c        | 102 ++--------
 arch/arm64/crypto/aes-neonbs-glue.c | 122 +-----------
 arch/arm64/crypto/ghash-ce-glue.c   | 209 +++++---------------
 6 files changed, 148 insertions(+), 518 deletions(-)

-- 
2.30.2



From ardb at kernel.org  Fri Aug 27 00:03:36 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 27 Aug 2021 09:03:36 +0200
Subject: [PATCH v7 1/7] crypto: arm64/gcm-aes-ce - remove non-SIMD fallback
 path
In-Reply-To: <20210827070342.218276-1-ardb@kernel.org>
References: <20210827070342.218276-1-ardb@kernel.org>
Message-ID: <20210827070342.218276-2-ardb@kernel.org>

Now that kernel mode SIMD is guaranteed to be available when executing
in task or softirq context, we no longer need scalar fallbacks to use
when the NEON is unavailable. So get rid of them.

Reviewed-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/crypto/ghash-ce-glue.c | 209 +++++---------------
 1 file changed, 51 insertions(+), 158 deletions(-)

diff --git a/arch/arm64/crypto/ghash-ce-glue.c b/arch/arm64/crypto/ghash-ce-glue.c
index 720cd3a58da3..15794fe21a0b 100644
--- a/arch/arm64/crypto/ghash-ce-glue.c
+++ b/arch/arm64/crypto/ghash-ce-glue.c
@@ -362,84 +362,36 @@ static int gcm_encrypt(struct aead_request *req)
 
 	err = skcipher_walk_aead_encrypt(&walk, req, false);
 
-	if (likely(crypto_simd_usable())) {
-		do {
-			const u8 *src = walk.src.virt.addr;
-			u8 *dst = walk.dst.virt.addr;
-			int nbytes = walk.nbytes;
-
-			tag = (u8 *)&lengths;
-
-			if (unlikely(nbytes > 0 && nbytes < AES_BLOCK_SIZE)) {
-				src = dst = memcpy(buf + sizeof(buf) - nbytes,
-						   src, nbytes);
-			} else if (nbytes < walk.total) {
-				nbytes &= ~(AES_BLOCK_SIZE - 1);
-				tag = NULL;
-			}
-
-			kernel_neon_begin();
-			pmull_gcm_encrypt(nbytes, dst, src, ctx->ghash_key.h,
-					  dg, iv, ctx->aes_key.key_enc, nrounds,
-					  tag);
-			kernel_neon_end();
-
-			if (unlikely(!nbytes))
-				break;
-
-			if (unlikely(nbytes > 0 && nbytes < AES_BLOCK_SIZE))
-				memcpy(walk.dst.virt.addr,
-				       buf + sizeof(buf) - nbytes, nbytes);
-
-			err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
-		} while (walk.nbytes);
-	} else {
-		while (walk.nbytes >= AES_BLOCK_SIZE) {
-			int blocks = walk.nbytes / AES_BLOCK_SIZE;
-			const u8 *src = walk.src.virt.addr;
-			u8 *dst = walk.dst.virt.addr;
-			int remaining = blocks;
-
-			do {
-				aes_encrypt(&ctx->aes_key, buf, iv);
-				crypto_xor_cpy(dst, src, buf, AES_BLOCK_SIZE);
-				crypto_inc(iv, AES_BLOCK_SIZE);
-
-				dst += AES_BLOCK_SIZE;
-				src += AES_BLOCK_SIZE;
-			} while (--remaining > 0);
-
-			ghash_do_update(blocks, dg, walk.dst.virt.addr,
-					&ctx->ghash_key, NULL);
-
-			err = skcipher_walk_done(&walk,
-						 walk.nbytes % AES_BLOCK_SIZE);
-		}
-
-		/* handle the tail */
-		if (walk.nbytes) {
-			aes_encrypt(&ctx->aes_key, buf, iv);
+	do {
+		const u8 *src = walk.src.virt.addr;
+		u8 *dst = walk.dst.virt.addr;
+		int nbytes = walk.nbytes;
 
-			crypto_xor_cpy(walk.dst.virt.addr, walk.src.virt.addr,
-				       buf, walk.nbytes);
+		tag = (u8 *)&lengths;
 
-			memcpy(buf, walk.dst.virt.addr, walk.nbytes);
-			memset(buf + walk.nbytes, 0, sizeof(buf) - walk.nbytes);
+		if (unlikely(nbytes > 0 && nbytes < AES_BLOCK_SIZE)) {
+			src = dst = memcpy(buf + sizeof(buf) - nbytes,
+					   src, nbytes);
+		} else if (nbytes < walk.total) {
+			nbytes &= ~(AES_BLOCK_SIZE - 1);
+			tag = NULL;
 		}
 
-		tag = (u8 *)&lengths;
-		ghash_do_update(1, dg, tag, &ctx->ghash_key,
-				walk.nbytes ? buf : NULL);
+		kernel_neon_begin();
+		pmull_gcm_encrypt(nbytes, dst, src, ctx->ghash_key.h,
+				  dg, iv, ctx->aes_key.key_enc, nrounds,
+				  tag);
+		kernel_neon_end();
 
-		if (walk.nbytes)
-			err = skcipher_walk_done(&walk, 0);
+		if (unlikely(!nbytes))
+			break;
 
-		put_unaligned_be64(dg[1], tag);
-		put_unaligned_be64(dg[0], tag + 8);
-		put_unaligned_be32(1, iv + GCM_IV_SIZE);
-		aes_encrypt(&ctx->aes_key, iv, iv);
-		crypto_xor(tag, iv, AES_BLOCK_SIZE);
-	}
+		if (unlikely(nbytes > 0 && nbytes < AES_BLOCK_SIZE))
+			memcpy(walk.dst.virt.addr,
+			       buf + sizeof(buf) - nbytes, nbytes);
+
+		err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
+	} while (walk.nbytes);
 
 	if (err)
 		return err;
@@ -464,6 +416,7 @@ static int gcm_decrypt(struct aead_request *req)
 	u64 dg[2] = {};
 	be128 lengths;
 	u8 *tag;
+	int ret;
 	int err;
 
 	lengths.a = cpu_to_be64(req->assoclen * 8);
@@ -481,101 +434,41 @@ static int gcm_decrypt(struct aead_request *req)
 
 	err = skcipher_walk_aead_decrypt(&walk, req, false);
 
-	if (likely(crypto_simd_usable())) {
-		int ret;
-
-		do {
-			const u8 *src = walk.src.virt.addr;
-			u8 *dst = walk.dst.virt.addr;
-			int nbytes = walk.nbytes;
-
-			tag = (u8 *)&lengths;
-
-			if (unlikely(nbytes > 0 && nbytes < AES_BLOCK_SIZE)) {
-				src = dst = memcpy(buf + sizeof(buf) - nbytes,
-						   src, nbytes);
-			} else if (nbytes < walk.total) {
-				nbytes &= ~(AES_BLOCK_SIZE - 1);
-				tag = NULL;
-			}
-
-			kernel_neon_begin();
-			ret = pmull_gcm_decrypt(nbytes, dst, src,
-						ctx->ghash_key.h,
-						dg, iv, ctx->aes_key.key_enc,
-						nrounds, tag, otag, authsize);
-			kernel_neon_end();
-
-			if (unlikely(!nbytes))
-				break;
-
-			if (unlikely(nbytes > 0 && nbytes < AES_BLOCK_SIZE))
-				memcpy(walk.dst.virt.addr,
-				       buf + sizeof(buf) - nbytes, nbytes);
-
-			err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
-		} while (walk.nbytes);
-
-		if (err)
-			return err;
-		if (ret)
-			return -EBADMSG;
-	} else {
-		while (walk.nbytes >= AES_BLOCK_SIZE) {
-			int blocks = walk.nbytes / AES_BLOCK_SIZE;
-			const u8 *src = walk.src.virt.addr;
-			u8 *dst = walk.dst.virt.addr;
-
-			ghash_do_update(blocks, dg, walk.src.virt.addr,
-					&ctx->ghash_key, NULL);
-
-			do {
-				aes_encrypt(&ctx->aes_key, buf, iv);
-				crypto_xor_cpy(dst, src, buf, AES_BLOCK_SIZE);
-				crypto_inc(iv, AES_BLOCK_SIZE);
-
-				dst += AES_BLOCK_SIZE;
-				src += AES_BLOCK_SIZE;
-			} while (--blocks > 0);
+	do {
+		const u8 *src = walk.src.virt.addr;
+		u8 *dst = walk.dst.virt.addr;
+		int nbytes = walk.nbytes;
 
-			err = skcipher_walk_done(&walk,
-						 walk.nbytes % AES_BLOCK_SIZE);
-		}
+		tag = (u8 *)&lengths;
 
-		/* handle the tail */
-		if (walk.nbytes) {
-			memcpy(buf, walk.src.virt.addr, walk.nbytes);
-			memset(buf + walk.nbytes, 0, sizeof(buf) - walk.nbytes);
+		if (unlikely(nbytes > 0 && nbytes < AES_BLOCK_SIZE)) {
+			src = dst = memcpy(buf + sizeof(buf) - nbytes,
+					   src, nbytes);
+		} else if (nbytes < walk.total) {
+			nbytes &= ~(AES_BLOCK_SIZE - 1);
+			tag = NULL;
 		}
 
-		tag = (u8 *)&lengths;
-		ghash_do_update(1, dg, tag, &ctx->ghash_key,
-				walk.nbytes ? buf : NULL);
-
-		if (walk.nbytes) {
-			aes_encrypt(&ctx->aes_key, buf, iv);
+		kernel_neon_begin();
+		ret = pmull_gcm_decrypt(nbytes, dst, src, ctx->ghash_key.h,
+					dg, iv, ctx->aes_key.key_enc,
+					nrounds, tag, otag, authsize);
+		kernel_neon_end();
 
-			crypto_xor_cpy(walk.dst.virt.addr, walk.src.virt.addr,
-				       buf, walk.nbytes);
+		if (unlikely(!nbytes))
+			break;
 
-			err = skcipher_walk_done(&walk, 0);
-		}
+		if (unlikely(nbytes > 0 && nbytes < AES_BLOCK_SIZE))
+			memcpy(walk.dst.virt.addr,
+			       buf + sizeof(buf) - nbytes, nbytes);
 
-		if (err)
-			return err;
+		err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
+	} while (walk.nbytes);
 
-		put_unaligned_be64(dg[1], tag);
-		put_unaligned_be64(dg[0], tag + 8);
-		put_unaligned_be32(1, iv + GCM_IV_SIZE);
-		aes_encrypt(&ctx->aes_key, iv, iv);
-		crypto_xor(tag, iv, AES_BLOCK_SIZE);
+	if (err)
+		return err;
 
-		if (crypto_memneq(tag, otag, authsize)) {
-			memzero_explicit(tag, AES_BLOCK_SIZE);
-			return -EBADMSG;
-		}
-	}
-	return 0;
+	return ret ? -EBADMSG : 0;
 }
 
 static struct aead_alg gcm_aes_alg = {
-- 
2.30.2



From ardb at kernel.org  Fri Aug 27 00:03:37 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 27 Aug 2021 09:03:37 +0200
Subject: [PATCH v7 2/7] crypto: arm64/aes-neonbs - stop using SIMD helper for
 skciphers
In-Reply-To: <20210827070342.218276-1-ardb@kernel.org>
References: <20210827070342.218276-1-ardb@kernel.org>
Message-ID: <20210827070342.218276-3-ardb@kernel.org>

Calls into the skcipher API can only occur from contexts where the SIMD
unit is available, so there is no need for the SIMD helper.

Reviewed-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/crypto/Kconfig           |   2 -
 arch/arm64/crypto/aes-neonbs-glue.c | 122 ++------------------
 2 files changed, 9 insertions(+), 115 deletions(-)

diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index 55f19450091b..4b70aaab0f35 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -122,8 +122,6 @@ config CRYPTO_AES_ARM64_BS
 	depends on KERNEL_MODE_NEON
 	select CRYPTO_SKCIPHER
 	select CRYPTO_AES_ARM64_NEON_BLK
-	select CRYPTO_AES_ARM64
 	select CRYPTO_LIB_AES
-	select CRYPTO_SIMD
 
 endif
diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c
index fb507d569922..8df6ad8cb09d 100644
--- a/arch/arm64/crypto/aes-neonbs-glue.c
+++ b/arch/arm64/crypto/aes-neonbs-glue.c
@@ -63,11 +63,6 @@ struct aesbs_cbc_ctx {
 	u32			enc[AES_MAX_KEYLENGTH_U32];
 };
 
-struct aesbs_ctr_ctx {
-	struct aesbs_ctx	key;		/* must be first member */
-	struct crypto_aes_ctx	fallback;
-};
-
 struct aesbs_xts_ctx {
 	struct aesbs_ctx	key;
 	u32			twkey[AES_MAX_KEYLENGTH_U32];
@@ -207,25 +202,6 @@ static int cbc_decrypt(struct skcipher_request *req)
 	return err;
 }
 
-static int aesbs_ctr_setkey_sync(struct crypto_skcipher *tfm, const u8 *in_key,
-				 unsigned int key_len)
-{
-	struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
-	int err;
-
-	err = aes_expandkey(&ctx->fallback, in_key, key_len);
-	if (err)
-		return err;
-
-	ctx->key.rounds = 6 + key_len / 4;
-
-	kernel_neon_begin();
-	aesbs_convert_key(ctx->key.rk, ctx->fallback.key_enc, ctx->key.rounds);
-	kernel_neon_end();
-
-	return 0;
-}
-
 static int ctr_encrypt(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
@@ -292,29 +268,6 @@ static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
 	return aesbs_setkey(tfm, in_key, key_len);
 }
 
-static void ctr_encrypt_one(struct crypto_skcipher *tfm, const u8 *src, u8 *dst)
-{
-	struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
-	unsigned long flags;
-
-	/*
-	 * Temporarily disable interrupts to avoid races where
-	 * cachelines are evicted when the CPU is interrupted
-	 * to do something else.
-	 */
-	local_irq_save(flags);
-	aes_encrypt(&ctx->fallback, dst, src);
-	local_irq_restore(flags);
-}
-
-static int ctr_encrypt_sync(struct skcipher_request *req)
-{
-	if (!crypto_simd_usable())
-		return crypto_ctr_encrypt_walk(req, ctr_encrypt_one);
-
-	return ctr_encrypt(req);
-}
-
 static int __xts_crypt(struct skcipher_request *req, bool encrypt,
 		       void (*fn)(u8 out[], u8 const in[], u8 const rk[],
 				  int rounds, int blocks, u8 iv[]))
@@ -431,13 +384,12 @@ static int xts_decrypt(struct skcipher_request *req)
 }
 
 static struct skcipher_alg aes_algs[] = { {
-	.base.cra_name		= "__ecb(aes)",
-	.base.cra_driver_name	= "__ecb-aes-neonbs",
+	.base.cra_name		= "ecb(aes)",
+	.base.cra_driver_name	= "ecb-aes-neonbs",
 	.base.cra_priority	= 250,
 	.base.cra_blocksize	= AES_BLOCK_SIZE,
 	.base.cra_ctxsize	= sizeof(struct aesbs_ctx),
 	.base.cra_module	= THIS_MODULE,
-	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
 
 	.min_keysize		= AES_MIN_KEY_SIZE,
 	.max_keysize		= AES_MAX_KEY_SIZE,
@@ -446,13 +398,12 @@ static struct skcipher_alg aes_algs[] = { {
 	.encrypt		= ecb_encrypt,
 	.decrypt		= ecb_decrypt,
 }, {
-	.base.cra_name		= "__cbc(aes)",
-	.base.cra_driver_name	= "__cbc-aes-neonbs",
+	.base.cra_name		= "cbc(aes)",
+	.base.cra_driver_name	= "cbc-aes-neonbs",
 	.base.cra_priority	= 250,
 	.base.cra_blocksize	= AES_BLOCK_SIZE,
 	.base.cra_ctxsize	= sizeof(struct aesbs_cbc_ctx),
 	.base.cra_module	= THIS_MODULE,
-	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
 
 	.min_keysize		= AES_MIN_KEY_SIZE,
 	.max_keysize		= AES_MAX_KEY_SIZE,
@@ -462,13 +413,12 @@ static struct skcipher_alg aes_algs[] = { {
 	.encrypt		= cbc_encrypt,
 	.decrypt		= cbc_decrypt,
 }, {
-	.base.cra_name		= "__ctr(aes)",
-	.base.cra_driver_name	= "__ctr-aes-neonbs",
+	.base.cra_name		= "ctr(aes)",
+	.base.cra_driver_name	= "ctr-aes-neonbs",
 	.base.cra_priority	= 250,
 	.base.cra_blocksize	= 1,
 	.base.cra_ctxsize	= sizeof(struct aesbs_ctx),
 	.base.cra_module	= THIS_MODULE,
-	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
 
 	.min_keysize		= AES_MIN_KEY_SIZE,
 	.max_keysize		= AES_MAX_KEY_SIZE,
@@ -479,29 +429,12 @@ static struct skcipher_alg aes_algs[] = { {
 	.encrypt		= ctr_encrypt,
 	.decrypt		= ctr_encrypt,
 }, {
-	.base.cra_name		= "ctr(aes)",
-	.base.cra_driver_name	= "ctr-aes-neonbs",
-	.base.cra_priority	= 250 - 1,
-	.base.cra_blocksize	= 1,
-	.base.cra_ctxsize	= sizeof(struct aesbs_ctr_ctx),
-	.base.cra_module	= THIS_MODULE,
-
-	.min_keysize		= AES_MIN_KEY_SIZE,
-	.max_keysize		= AES_MAX_KEY_SIZE,
-	.chunksize		= AES_BLOCK_SIZE,
-	.walksize		= 8 * AES_BLOCK_SIZE,
-	.ivsize			= AES_BLOCK_SIZE,
-	.setkey			= aesbs_ctr_setkey_sync,
-	.encrypt		= ctr_encrypt_sync,
-	.decrypt		= ctr_encrypt_sync,
-}, {
-	.base.cra_name		= "__xts(aes)",
-	.base.cra_driver_name	= "__xts-aes-neonbs",
+	.base.cra_name		= "xts(aes)",
+	.base.cra_driver_name	= "xts-aes-neonbs",
 	.base.cra_priority	= 250,
 	.base.cra_blocksize	= AES_BLOCK_SIZE,
 	.base.cra_ctxsize	= sizeof(struct aesbs_xts_ctx),
 	.base.cra_module	= THIS_MODULE,
-	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
 
 	.min_keysize		= 2 * AES_MIN_KEY_SIZE,
 	.max_keysize		= 2 * AES_MAX_KEY_SIZE,
@@ -512,54 +445,17 @@ static struct skcipher_alg aes_algs[] = { {
 	.decrypt		= xts_decrypt,
 } };
 
-static struct simd_skcipher_alg *aes_simd_algs[ARRAY_SIZE(aes_algs)];
-
 static void aes_exit(void)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(aes_simd_algs); i++)
-		if (aes_simd_algs[i])
-			simd_skcipher_free(aes_simd_algs[i]);
-
 	crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
 }
 
 static int __init aes_init(void)
 {
-	struct simd_skcipher_alg *simd;
-	const char *basename;
-	const char *algname;
-	const char *drvname;
-	int err;
-	int i;
-
 	if (!cpu_have_named_feature(ASIMD))
 		return -ENODEV;
 
-	err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
-	if (err)
-		return err;
-
-	for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
-		if (!(aes_algs[i].base.cra_flags & CRYPTO_ALG_INTERNAL))
-			continue;
-
-		algname = aes_algs[i].base.cra_name + 2;
-		drvname = aes_algs[i].base.cra_driver_name + 2;
-		basename = aes_algs[i].base.cra_driver_name;
-		simd = simd_skcipher_create_compat(algname, drvname, basename);
-		err = PTR_ERR(simd);
-		if (IS_ERR(simd))
-			goto unregister_simds;
-
-		aes_simd_algs[i] = simd;
-	}
-	return 0;
-
-unregister_simds:
-	aes_exit();
-	return err;
+	return crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
 }
 
 module_init(aes_init);
-- 
2.30.2



From ardb at kernel.org  Fri Aug 27 00:03:38 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 27 Aug 2021 09:03:38 +0200
Subject: [PATCH v7 3/7] crypto: arm64/aes-ce - stop using SIMD helper for
 skciphers
In-Reply-To: <20210827070342.218276-1-ardb@kernel.org>
References: <20210827070342.218276-1-ardb@kernel.org>
Message-ID: <20210827070342.218276-4-ardb@kernel.org>

Calls into the skcipher API can only occur from contexts where the SIMD
unit is available, so there is no need for the SIMD helper.

Reviewed-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/crypto/Kconfig    |   4 -
 arch/arm64/crypto/aes-glue.c | 102 +++-----------------
 2 files changed, 13 insertions(+), 93 deletions(-)

diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index 4b70aaab0f35..addfa413650b 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -88,16 +88,12 @@ config CRYPTO_AES_ARM64_CE_BLK
 	depends on KERNEL_MODE_NEON
 	select CRYPTO_SKCIPHER
 	select CRYPTO_AES_ARM64_CE
-	select CRYPTO_AES_ARM64
-	select CRYPTO_SIMD
 
 config CRYPTO_AES_ARM64_NEON_BLK
 	tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions"
 	depends on KERNEL_MODE_NEON
 	select CRYPTO_SKCIPHER
-	select CRYPTO_AES_ARM64
 	select CRYPTO_LIB_AES
-	select CRYPTO_SIMD
 
 config CRYPTO_CHACHA20_NEON
 	tristate "ChaCha20, XChaCha20, and XChaCha12 stream ciphers using NEON instructions"
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
index 17e735931a0c..30b7cc6a7079 100644
--- a/arch/arm64/crypto/aes-glue.c
+++ b/arch/arm64/crypto/aes-glue.c
@@ -444,7 +444,7 @@ static int __maybe_unused essiv_cbc_decrypt(struct skcipher_request *req)
 	return err ?: cbc_decrypt_walk(req, &walk);
 }
 
-static int ctr_encrypt(struct skcipher_request *req)
+static int __maybe_unused ctr_encrypt(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
 	struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
@@ -485,29 +485,6 @@ static int ctr_encrypt(struct skcipher_request *req)
 	return err;
 }
 
-static void ctr_encrypt_one(struct crypto_skcipher *tfm, const u8 *src, u8 *dst)
-{
-	const struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
-	unsigned long flags;
-
-	/*
-	 * Temporarily disable interrupts to avoid races where
-	 * cachelines are evicted when the CPU is interrupted
-	 * to do something else.
-	 */
-	local_irq_save(flags);
-	aes_encrypt(ctx, dst, src);
-	local_irq_restore(flags);
-}
-
-static int __maybe_unused ctr_encrypt_sync(struct skcipher_request *req)
-{
-	if (!crypto_simd_usable())
-		return crypto_ctr_encrypt_walk(req, ctr_encrypt_one);
-
-	return ctr_encrypt(req);
-}
-
 static int __maybe_unused xts_encrypt(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
@@ -656,10 +633,9 @@ static int __maybe_unused xts_decrypt(struct skcipher_request *req)
 static struct skcipher_alg aes_algs[] = { {
 #if defined(USE_V8_CRYPTO_EXTENSIONS) || !IS_ENABLED(CONFIG_CRYPTO_AES_ARM64_BS)
 	.base = {
-		.cra_name		= "__ecb(aes)",
-		.cra_driver_name	= "__ecb-aes-" MODE,
+		.cra_name		= "ecb(aes)",
+		.cra_driver_name	= "ecb-aes-" MODE,
 		.cra_priority		= PRIO,
-		.cra_flags		= CRYPTO_ALG_INTERNAL,
 		.cra_blocksize		= AES_BLOCK_SIZE,
 		.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
 		.cra_module		= THIS_MODULE,
@@ -671,10 +647,9 @@ static struct skcipher_alg aes_algs[] = { {
 	.decrypt	= ecb_decrypt,
 }, {
 	.base = {
-		.cra_name		= "__cbc(aes)",
-		.cra_driver_name	= "__cbc-aes-" MODE,
+		.cra_name		= "cbc(aes)",
+		.cra_driver_name	= "cbc-aes-" MODE,
 		.cra_priority		= PRIO,
-		.cra_flags		= CRYPTO_ALG_INTERNAL,
 		.cra_blocksize		= AES_BLOCK_SIZE,
 		.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
 		.cra_module		= THIS_MODULE,
@@ -687,10 +662,9 @@ static struct skcipher_alg aes_algs[] = { {
 	.decrypt	= cbc_decrypt,
 }, {
 	.base = {
-		.cra_name		= "__ctr(aes)",
-		.cra_driver_name	= "__ctr-aes-" MODE,
+		.cra_name		= "ctr(aes)",
+		.cra_driver_name	= "ctr-aes-" MODE,
 		.cra_priority		= PRIO,
-		.cra_flags		= CRYPTO_ALG_INTERNAL,
 		.cra_blocksize		= 1,
 		.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
 		.cra_module		= THIS_MODULE,
@@ -704,26 +678,9 @@ static struct skcipher_alg aes_algs[] = { {
 	.decrypt	= ctr_encrypt,
 }, {
 	.base = {
-		.cra_name		= "ctr(aes)",
-		.cra_driver_name	= "ctr-aes-" MODE,
-		.cra_priority		= PRIO - 1,
-		.cra_blocksize		= 1,
-		.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
-		.cra_module		= THIS_MODULE,
-	},
-	.min_keysize	= AES_MIN_KEY_SIZE,
-	.max_keysize	= AES_MAX_KEY_SIZE,
-	.ivsize		= AES_BLOCK_SIZE,
-	.chunksize	= AES_BLOCK_SIZE,
-	.setkey		= skcipher_aes_setkey,
-	.encrypt	= ctr_encrypt_sync,
-	.decrypt	= ctr_encrypt_sync,
-}, {
-	.base = {
-		.cra_name		= "__xts(aes)",
-		.cra_driver_name	= "__xts-aes-" MODE,
+		.cra_name		= "xts(aes)",
+		.cra_driver_name	= "xts-aes-" MODE,
 		.cra_priority		= PRIO,
-		.cra_flags		= CRYPTO_ALG_INTERNAL,
 		.cra_blocksize		= AES_BLOCK_SIZE,
 		.cra_ctxsize		= sizeof(struct crypto_aes_xts_ctx),
 		.cra_module		= THIS_MODULE,
@@ -738,10 +695,9 @@ static struct skcipher_alg aes_algs[] = { {
 }, {
 #endif
 	.base = {
-		.cra_name		= "__cts(cbc(aes))",
-		.cra_driver_name	= "__cts-cbc-aes-" MODE,
+		.cra_name		= "cts(cbc(aes))",
+		.cra_driver_name	= "cts-cbc-aes-" MODE,
 		.cra_priority		= PRIO,
-		.cra_flags		= CRYPTO_ALG_INTERNAL,
 		.cra_blocksize		= AES_BLOCK_SIZE,
 		.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
 		.cra_module		= THIS_MODULE,
@@ -755,10 +711,9 @@ static struct skcipher_alg aes_algs[] = { {
 	.decrypt	= cts_cbc_decrypt,
 }, {
 	.base = {
-		.cra_name		= "__essiv(cbc(aes),sha256)",
-		.cra_driver_name	= "__essiv-cbc-aes-sha256-" MODE,
+		.cra_name		= "essiv(cbc(aes),sha256)",
+		.cra_driver_name	= "essiv-cbc-aes-sha256-" MODE,
 		.cra_priority		= PRIO + 1,
-		.cra_flags		= CRYPTO_ALG_INTERNAL,
 		.cra_blocksize		= AES_BLOCK_SIZE,
 		.cra_ctxsize		= sizeof(struct crypto_aes_essiv_cbc_ctx),
 		.cra_module		= THIS_MODULE,
@@ -997,28 +952,15 @@ static struct shash_alg mac_algs[] = { {
 	.descsize		= sizeof(struct mac_desc_ctx),
 } };
 
-static struct simd_skcipher_alg *aes_simd_algs[ARRAY_SIZE(aes_algs)];
-
 static void aes_exit(void)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(aes_simd_algs); i++)
-		if (aes_simd_algs[i])
-			simd_skcipher_free(aes_simd_algs[i]);
-
 	crypto_unregister_shashes(mac_algs, ARRAY_SIZE(mac_algs));
 	crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
 }
 
 static int __init aes_init(void)
 {
-	struct simd_skcipher_alg *simd;
-	const char *basename;
-	const char *algname;
-	const char *drvname;
 	int err;
-	int i;
 
 	err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
 	if (err)
@@ -1028,26 +970,8 @@ static int __init aes_init(void)
 	if (err)
 		goto unregister_ciphers;
 
-	for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
-		if (!(aes_algs[i].base.cra_flags & CRYPTO_ALG_INTERNAL))
-			continue;
-
-		algname = aes_algs[i].base.cra_name + 2;
-		drvname = aes_algs[i].base.cra_driver_name + 2;
-		basename = aes_algs[i].base.cra_driver_name;
-		simd = simd_skcipher_create_compat(algname, drvname, basename);
-		err = PTR_ERR(simd);
-		if (IS_ERR(simd))
-			goto unregister_simds;
-
-		aes_simd_algs[i] = simd;
-	}
-
 	return 0;
 
-unregister_simds:
-	aes_exit();
-	return err;
 unregister_ciphers:
 	crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
 	return err;
-- 
2.30.2



From ardb at kernel.org  Fri Aug 27 00:03:39 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 27 Aug 2021 09:03:39 +0200
Subject: [PATCH v7 4/7] crypto: arm64/aes-ccm - yield NEON when processing
 auth-only data
In-Reply-To: <20210827070342.218276-1-ardb@kernel.org>
References: <20210827070342.218276-1-ardb@kernel.org>
Message-ID: <20210827070342.218276-5-ardb@kernel.org>

In SIMD accelerated crypto drivers, we typically yield the SIMD unit
after processing 4 KiB of input, to avoid scheduling blackouts caused by
the fact that claiming the SIMD unit disables preemption as well as
softirq processing.

The arm64 CCM driver does this implicitly for the ciphertext, due to the
fact that the skcipher API never processes more than a single page at a
time. However, the scatterwalk performed by this driver when processing
the authenticate-only data will keep the SIMD unit occupied until it
completes.

So cap the scatterwalk steps to 4 KiB.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/crypto/aes-ce-ccm-glue.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
index f6d19b0dc893..fe9c837ac4b9 100644
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
@@ -161,6 +161,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
 			scatterwalk_start(&walk, sg_next(walk.sg));
 			n = scatterwalk_clamp(&walk, len);
 		}
+		n = min_t(u32, n, SZ_4K); /* yield NEON at least every 4k */
 		p = scatterwalk_map(&walk);
 		ccm_update_mac(ctx, mac, p, n, &macp);
 		len -= n;
-- 
2.30.2



From ardb at kernel.org  Fri Aug 27 00:03:40 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 27 Aug 2021 09:03:40 +0200
Subject: [PATCH v7 5/7] crypto: arm64/aes-ccm - remove non-SIMD fallback path
In-Reply-To: <20210827070342.218276-1-ardb@kernel.org>
References: <20210827070342.218276-1-ardb@kernel.org>
Message-ID: <20210827070342.218276-6-ardb@kernel.org>

AES/CCM on arm64 is implemented as a synchronous AEAD, and so it is
guaranteed by the API that it is only invoked in task or softirq
context. Since softirqs are now only handled when the SIMD is not
being used in the task context that was interrupted to service the
softirq, we no longer need a fallback path. Let's remove it.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/crypto/aes-ce-ccm-glue.c | 153 ++++----------------
 1 file changed, 32 insertions(+), 121 deletions(-)

diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
index fe9c837ac4b9..c1f221a181a5 100644
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
@@ -6,12 +6,10 @@
  */
 
 #include <asm/neon.h>
-#include <asm/simd.h>
 #include <asm/unaligned.h>
 #include <crypto/aes.h>
 #include <crypto/scatterwalk.h>
 #include <crypto/internal/aead.h>
-#include <crypto/internal/simd.h>
 #include <crypto/internal/skcipher.h>
 #include <linux/module.h>
 
@@ -99,36 +97,10 @@ static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
 static void ccm_update_mac(struct crypto_aes_ctx *key, u8 mac[], u8 const in[],
 			   u32 abytes, u32 *macp)
 {
-	if (crypto_simd_usable()) {
-		kernel_neon_begin();
-		ce_aes_ccm_auth_data(mac, in, abytes, macp, key->key_enc,
-				     num_rounds(key));
-		kernel_neon_end();
-	} else {
-		if (*macp > 0 && *macp < AES_BLOCK_SIZE) {
-			int added = min(abytes, AES_BLOCK_SIZE - *macp);
-
-			crypto_xor(&mac[*macp], in, added);
-
-			*macp += added;
-			in += added;
-			abytes -= added;
-		}
-
-		while (abytes >= AES_BLOCK_SIZE) {
-			aes_encrypt(key, mac, mac);
-			crypto_xor(mac, in, AES_BLOCK_SIZE);
-
-			in += AES_BLOCK_SIZE;
-			abytes -= AES_BLOCK_SIZE;
-		}
-
-		if (abytes > 0) {
-			aes_encrypt(key, mac, mac);
-			crypto_xor(mac, in, abytes);
-			*macp = abytes;
-		}
-	}
+	kernel_neon_begin();
+	ce_aes_ccm_auth_data(mac, in, abytes, macp, key->key_enc,
+			     num_rounds(key));
+	kernel_neon_end();
 }
 
 static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
@@ -172,54 +144,6 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
 	} while (len);
 }
 
-static int ccm_crypt_fallback(struct skcipher_walk *walk, u8 mac[], u8 iv0[],
-			      struct crypto_aes_ctx *ctx, bool enc)
-{
-	u8 buf[AES_BLOCK_SIZE];
-	int err = 0;
-
-	while (walk->nbytes) {
-		int blocks = walk->nbytes / AES_BLOCK_SIZE;
-		u32 tail = walk->nbytes % AES_BLOCK_SIZE;
-		u8 *dst = walk->dst.virt.addr;
-		u8 *src = walk->src.virt.addr;
-		u32 nbytes = walk->nbytes;
-
-		if (nbytes == walk->total && tail > 0) {
-			blocks++;
-			tail = 0;
-		}
-
-		do {
-			u32 bsize = AES_BLOCK_SIZE;
-
-			if (nbytes < AES_BLOCK_SIZE)
-				bsize = nbytes;
-
-			crypto_inc(walk->iv, AES_BLOCK_SIZE);
-			aes_encrypt(ctx, buf, walk->iv);
-			aes_encrypt(ctx, mac, mac);
-			if (enc)
-				crypto_xor(mac, src, bsize);
-			crypto_xor_cpy(dst, src, buf, bsize);
-			if (!enc)
-				crypto_xor(mac, dst, bsize);
-			dst += bsize;
-			src += bsize;
-			nbytes -= bsize;
-		} while (--blocks);
-
-		err = skcipher_walk_done(walk, tail);
-	}
-
-	if (!err) {
-		aes_encrypt(ctx, buf, iv0);
-		aes_encrypt(ctx, mac, mac);
-		crypto_xor(mac, buf, AES_BLOCK_SIZE);
-	}
-	return err;
-}
-
 static int ccm_encrypt(struct aead_request *req)
 {
 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
@@ -242,30 +166,24 @@ static int ccm_encrypt(struct aead_request *req)
 
 	err = skcipher_walk_aead_encrypt(&walk, req, false);
 
-	if (crypto_simd_usable()) {
-		while (walk.nbytes) {
-			u32 tail = walk.nbytes % AES_BLOCK_SIZE;
+	while (walk.nbytes) {
+		u32 tail = walk.nbytes % AES_BLOCK_SIZE;
 
-			if (walk.nbytes == walk.total)
-				tail = 0;
+		if (walk.nbytes == walk.total)
+			tail = 0;
 
-			kernel_neon_begin();
-			ce_aes_ccm_encrypt(walk.dst.virt.addr,
-					   walk.src.virt.addr,
-					   walk.nbytes - tail, ctx->key_enc,
-					   num_rounds(ctx), mac, walk.iv);
-			kernel_neon_end();
+		kernel_neon_begin();
+		ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
+				   walk.nbytes - tail, ctx->key_enc,
+				   num_rounds(ctx), mac, walk.iv);
+		kernel_neon_end();
 
-			err = skcipher_walk_done(&walk, tail);
-		}
-		if (!err) {
-			kernel_neon_begin();
-			ce_aes_ccm_final(mac, buf, ctx->key_enc,
-					 num_rounds(ctx));
-			kernel_neon_end();
-		}
-	} else {
-		err = ccm_crypt_fallback(&walk, mac, buf, ctx, true);
+		err = skcipher_walk_done(&walk, tail);
+	}
+	if (!err) {
+		kernel_neon_begin();
+		ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
+		kernel_neon_end();
 	}
 	if (err)
 		return err;
@@ -300,32 +218,25 @@ static int ccm_decrypt(struct aead_request *req)
 
 	err = skcipher_walk_aead_decrypt(&walk, req, false);
 
-	if (crypto_simd_usable()) {
-		while (walk.nbytes) {
-			u32 tail = walk.nbytes % AES_BLOCK_SIZE;
+	while (walk.nbytes) {
+		u32 tail = walk.nbytes % AES_BLOCK_SIZE;
 
-			if (walk.nbytes == walk.total)
-				tail = 0;
+		if (walk.nbytes == walk.total)
+			tail = 0;
 
-			kernel_neon_begin();
-			ce_aes_ccm_decrypt(walk.dst.virt.addr,
-					   walk.src.virt.addr,
+		kernel_neon_begin();
+		ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
 					   walk.nbytes - tail, ctx->key_enc,
 					   num_rounds(ctx), mac, walk.iv);
-			kernel_neon_end();
+		kernel_neon_end();
 
-			err = skcipher_walk_done(&walk, tail);
-		}
-		if (!err) {
-			kernel_neon_begin();
-			ce_aes_ccm_final(mac, buf, ctx->key_enc,
-					 num_rounds(ctx));
-			kernel_neon_end();
-		}
-	} else {
-		err = ccm_crypt_fallback(&walk, mac, buf, ctx, false);
+		err = skcipher_walk_done(&walk, tail);
+	}
+	if (!err) {
+		kernel_neon_begin();
+		ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
+		kernel_neon_end();
 	}
-
 	if (err)
 		return err;
 
-- 
2.30.2



From ardb at kernel.org  Fri Aug 27 00:03:41 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 27 Aug 2021 09:03:41 +0200
Subject: [PATCH v7 6/7] crypto: arm64/aes-ccm - reduce NEON begin/end calls
 for common case
In-Reply-To: <20210827070342.218276-1-ardb@kernel.org>
References: <20210827070342.218276-1-ardb@kernel.org>
Message-ID: <20210827070342.218276-7-ardb@kernel.org>

AES-CCM (as used in WPA2 CCMP, for instance) typically involves
authenticate-only data, and operates on a single network packet, and so
the common case is for the authenticate, en/decrypt and finalize SIMD
helpers to all be called exactly once in sequence. Since
kernel_neon_end() now involves manipulation of the preemption state as
well as the softirq mask state, let's reduce the number of times we are
forced to call it to only once if we are handling this common case.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/crypto/aes-ce-ccm-core.S |  1 +
 arch/arm64/crypto/aes-ce-ccm-glue.c | 80 ++++++++++++--------
 2 files changed, 49 insertions(+), 32 deletions(-)

diff --git a/arch/arm64/crypto/aes-ce-ccm-core.S b/arch/arm64/crypto/aes-ce-ccm-core.S
index 99a028e298ed..8adff299fcd3 100644
--- a/arch/arm64/crypto/aes-ce-ccm-core.S
+++ b/arch/arm64/crypto/aes-ce-ccm-core.S
@@ -124,6 +124,7 @@ SYM_FUNC_START(ce_aes_ccm_final)
 SYM_FUNC_END(ce_aes_ccm_final)
 
 	.macro	aes_ccm_do_crypt,enc
+	cbz	x2, 5f
 	ldr	x8, [x6, #8]			/* load lower ctr */
 	ld1	{v0.16b}, [x5]			/* load mac */
 CPU_LE(	rev	x8, x8			)	/* keep swabbed ctr in reg */
diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
index c1f221a181a5..d973655fab7e 100644
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
@@ -97,10 +97,8 @@ static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
 static void ccm_update_mac(struct crypto_aes_ctx *key, u8 mac[], u8 const in[],
 			   u32 abytes, u32 *macp)
 {
-	kernel_neon_begin();
 	ce_aes_ccm_auth_data(mac, in, abytes, macp, key->key_enc,
 			     num_rounds(key));
-	kernel_neon_end();
 }
 
 static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
@@ -136,6 +134,12 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
 		n = min_t(u32, n, SZ_4K); /* yield NEON at least every 4k */
 		p = scatterwalk_map(&walk);
 		ccm_update_mac(ctx, mac, p, n, &macp);
+
+		if (len / SZ_4K > (len - n) / SZ_4K) {
+			kernel_neon_end();
+			kernel_neon_begin();
+		}
+
 		len -= n;
 
 		scatterwalk_unmap(p);
@@ -158,35 +162,41 @@ static int ccm_encrypt(struct aead_request *req)
 	if (err)
 		return err;
 
-	if (req->assoclen)
-		ccm_calculate_auth_mac(req, mac);
-
 	/* preserve the original iv for the final round */
 	memcpy(buf, req->iv, AES_BLOCK_SIZE);
 
 	err = skcipher_walk_aead_encrypt(&walk, req, false);
+	if (unlikely(err))
+		return err;
+
+	kernel_neon_begin();
+
+	if (req->assoclen)
+		ccm_calculate_auth_mac(req, mac);
 
-	while (walk.nbytes) {
+	do {
 		u32 tail = walk.nbytes % AES_BLOCK_SIZE;
 
 		if (walk.nbytes == walk.total)
 			tail = 0;
 
-		kernel_neon_begin();
 		ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
 				   walk.nbytes - tail, ctx->key_enc,
 				   num_rounds(ctx), mac, walk.iv);
-		kernel_neon_end();
 
-		err = skcipher_walk_done(&walk, tail);
-	}
-	if (!err) {
-		kernel_neon_begin();
-		ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
+		if (walk.nbytes == walk.total)
+			ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
+
 		kernel_neon_end();
-	}
-	if (err)
-		return err;
+
+		if (walk.nbytes) {
+			err = skcipher_walk_done(&walk, tail);
+			if (unlikely(err))
+				return err;
+			if (unlikely(walk.nbytes))
+				kernel_neon_begin();
+		}
+	} while (walk.nbytes);
 
 	/* copy authtag to end of dst */
 	scatterwalk_map_and_copy(mac, req->dst, req->assoclen + req->cryptlen,
@@ -210,35 +220,41 @@ static int ccm_decrypt(struct aead_request *req)
 	if (err)
 		return err;
 
-	if (req->assoclen)
-		ccm_calculate_auth_mac(req, mac);
-
 	/* preserve the original iv for the final round */
 	memcpy(buf, req->iv, AES_BLOCK_SIZE);
 
 	err = skcipher_walk_aead_decrypt(&walk, req, false);
+	if (unlikely(err))
+		return err;
 
-	while (walk.nbytes) {
+	kernel_neon_begin();
+
+	if (req->assoclen)
+		ccm_calculate_auth_mac(req, mac);
+
+	do {
 		u32 tail = walk.nbytes % AES_BLOCK_SIZE;
 
 		if (walk.nbytes == walk.total)
 			tail = 0;
 
-		kernel_neon_begin();
 		ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
-					   walk.nbytes - tail, ctx->key_enc,
-					   num_rounds(ctx), mac, walk.iv);
-		kernel_neon_end();
+				   walk.nbytes - tail, ctx->key_enc,
+				   num_rounds(ctx), mac, walk.iv);
+
+		if (walk.nbytes == walk.total)
+			ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
 
-		err = skcipher_walk_done(&walk, tail);
-	}
-	if (!err) {
-		kernel_neon_begin();
-		ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
 		kernel_neon_end();
-	}
-	if (err)
-		return err;
+
+		if (walk.nbytes) {
+			err = skcipher_walk_done(&walk, tail);
+			if (unlikely(err))
+				return err;
+			if (unlikely(walk.nbytes))
+				kernel_neon_begin();
+		}
+	} while (walk.nbytes);
 
 	/* compare calculated auth tag with the stored one */
 	scatterwalk_map_and_copy(buf, req->src,
-- 
2.30.2



From ardb at kernel.org  Fri Aug 27 00:03:42 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 27 Aug 2021 09:03:42 +0200
Subject: [PATCH v7 7/7] crypto: arm64/aes-ccm - avoid by-ref argument for
 ce_aes_ccm_auth_data
In-Reply-To: <20210827070342.218276-1-ardb@kernel.org>
References: <20210827070342.218276-1-ardb@kernel.org>
Message-ID: <20210827070342.218276-8-ardb@kernel.org>

With the SIMD code path removed, we can clean up the CCM auth-only path
a bit further, by passing the 'macp' input buffer pointer by value,
rather than by reference, and taking the output value from the
function's return value.

This way, the compiler is no longer forced to allocate macp on the
stack. This is not expected to make any difference in practice, it just
makes for slightly cleaner code.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Eric Biggers <ebiggers at google.com>
---
 arch/arm64/crypto/aes-ce-ccm-core.S | 23 ++++++++++----------
 arch/arm64/crypto/aes-ce-ccm-glue.c | 19 ++++++----------
 2 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/crypto/aes-ce-ccm-core.S b/arch/arm64/crypto/aes-ce-ccm-core.S
index 8adff299fcd3..b03f7f71f893 100644
--- a/arch/arm64/crypto/aes-ce-ccm-core.S
+++ b/arch/arm64/crypto/aes-ce-ccm-core.S
@@ -12,22 +12,21 @@
 	.arch	armv8-a+crypto
 
 	/*
-	 * void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
-	 *			     u32 *macp, u8 const rk[], u32 rounds);
+	 * u32 ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
+	 *			    u32 macp, u8 const rk[], u32 rounds);
 	 */
 SYM_FUNC_START(ce_aes_ccm_auth_data)
-	ldr	w8, [x3]			/* leftover from prev round? */
 	ld1	{v0.16b}, [x0]			/* load mac */
-	cbz	w8, 1f
-	sub	w8, w8, #16
+	cbz	w3, 1f
+	sub	w3, w3, #16
 	eor	v1.16b, v1.16b, v1.16b
 0:	ldrb	w7, [x1], #1			/* get 1 byte of input */
 	subs	w2, w2, #1
-	add	w8, w8, #1
+	add	w3, w3, #1
 	ins	v1.b[0], w7
 	ext	v1.16b, v1.16b, v1.16b, #1	/* rotate in the input bytes */
 	beq	8f				/* out of input? */
-	cbnz	w8, 0b
+	cbnz	w3, 0b
 	eor	v0.16b, v0.16b, v1.16b
 1:	ld1	{v3.4s}, [x4]			/* load first round key */
 	prfm	pldl1strm, [x1]
@@ -62,7 +61,7 @@ SYM_FUNC_START(ce_aes_ccm_auth_data)
 	beq	10f
 	adds	w2, w2, #16
 	beq	10f
-	mov	w8, w2
+	mov	w3, w2
 7:	ldrb	w7, [x1], #1
 	umov	w6, v0.b[0]
 	eor	w6, w6, w7
@@ -71,15 +70,15 @@ SYM_FUNC_START(ce_aes_ccm_auth_data)
 	beq	10f
 	ext	v0.16b, v0.16b, v0.16b, #1	/* rotate out the mac bytes */
 	b	7b
-8:	cbz	w8, 91f
-	mov	w7, w8
-	add	w8, w8, #16
+8:	cbz	w3, 91f
+	mov	w7, w3
+	add	w3, w3, #16
 9:	ext	v1.16b, v1.16b, v1.16b, #1
 	adds	w7, w7, #1
 	bne	9b
 91:	eor	v0.16b, v0.16b, v1.16b
 	st1	{v0.16b}, [x0]
-10:	str	w8, [x3]
+10:	mov	w0, w3
 	ret
 SYM_FUNC_END(ce_aes_ccm_auth_data)
 
diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
index d973655fab7e..c4f14415f5f0 100644
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
@@ -27,8 +27,8 @@ static int num_rounds(struct crypto_aes_ctx *ctx)
 	return 6 + ctx->key_length / 4;
 }
 
-asmlinkage void ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
-				     u32 *macp, u32 const rk[], u32 rounds);
+asmlinkage u32 ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
+				    u32 macp, u32 const rk[], u32 rounds);
 
 asmlinkage void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
 				   u32 const rk[], u32 rounds, u8 mac[],
@@ -94,13 +94,6 @@ static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
 	return 0;
 }
 
-static void ccm_update_mac(struct crypto_aes_ctx *key, u8 mac[], u8 const in[],
-			   u32 abytes, u32 *macp)
-{
-	ce_aes_ccm_auth_data(mac, in, abytes, macp, key->key_enc,
-			     num_rounds(key));
-}
-
 static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
 {
 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
@@ -120,7 +113,8 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
 		ltag.len = 6;
 	}
 
-	ccm_update_mac(ctx, mac, (u8 *)&ltag, ltag.len, &macp);
+	macp = ce_aes_ccm_auth_data(mac, (u8 *)&ltag, ltag.len, macp,
+				    ctx->key_enc, num_rounds(ctx));
 	scatterwalk_start(&walk, req->src);
 
 	do {
@@ -133,13 +127,14 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
 		}
 		n = min_t(u32, n, SZ_4K); /* yield NEON at least every 4k */
 		p = scatterwalk_map(&walk);
-		ccm_update_mac(ctx, mac, p, n, &macp);
+
+		macp = ce_aes_ccm_auth_data(mac, p, n, macp, ctx->key_enc,
+					    num_rounds(ctx));
 
 		if (len / SZ_4K > (len - n) / SZ_4K) {
 			kernel_neon_end();
 			kernel_neon_begin();
 		}
-
 		len -= n;
 
 		scatterwalk_unmap(p);
-- 
2.30.2



From hongxing.zhu at nxp.com  Thu Aug 26 23:42:57 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Fri, 27 Aug 2021 14:42:57 +0800
Subject: [PATCH v2 0/3] dt-bindings: PCI: imx6: convert the imx pcie
Message-ID: <1630046580-19282-1-git-send-email-hongxing.zhu@nxp.com>

Changes V1 --> V2:
- Add "Reviewed-by: Lucas Stach <l.stach at pengutronix.de>" and update
  the commit message.
- Apply changes refer to Rob's review comments.
  - remove num-viewport totally, since it's not required anymore, and so on.

This patch-set aims to convert the imx pcie controller bindings from
fsl,imx6q-pcie.txt to json schema file fsl,imx6q-pcie.yaml.

And fix according errors on imx6qdl.dtsi, imx6qp.dtsi, imx6sx.dtsi,
imx7d.dtsi and imx8mq.dtsi found by dt_binding_check and dtbs_check.

Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt  | 100 -----------------------------------------
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MAINTAINERS                                               |   2 +-
arch/arm/boot/dts/imx6qdl.dtsi                            |   7 ++-
arch/arm/boot/dts/imx6qp.dtsi                             |   2 +-
arch/arm/boot/dts/imx6sx.dtsi                             |   6 +--
arch/arm/boot/dts/imx7d.dtsi                              |   7 ++-
arch/arm64/boot/dts/freescale/imx8mq.dtsi                 |  10 ++---
8 files changed, 217 insertions(+), 119 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml

[PATCH v2 1/3] dt-bindings: PCI: imx6: convert the imx pcie
[PATCH v2 2/3] arm: dts: imx: fix the schema check errors
[PATCH v2 3/3] arm64: dts: imx8mq: fix the schema check errors


From hongxing.zhu at nxp.com  Thu Aug 26 23:42:59 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Fri, 27 Aug 2021 14:42:59 +0800
Subject: [PATCH v2 2/3] arm: dts: imx: fix the schema check errors
In-Reply-To: <1630046580-19282-1-git-send-email-hongxing.zhu@nxp.com>
References: <1630046580-19282-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1630046580-19282-3-git-send-email-hongxing.zhu@nxp.com>

- ranges property should be grouped by region, with no functional
  changes. Otherwise, schema dtbs_check would report the following errors.
"linux-imx/arch/arm/boot/dts/imx6qp-vicutp.dt.yaml: pcie at 1ffc000: ranges: 'oneOf' conditional failed, one must be fixed:
        linux-imx/arch/arm/boot/dts/imx6qp-vicutp.dt.yaml: pcie at 1ffc000: ranges: 'oneOf' conditional failed, one must be fixed:
                [[2164260864, 0, 0, 33030144, 0, 65536, 2181038080, 0, 16777216, 16777216, 0, 15728640]] is not of type 'boolean'
                True was expected
                [[2164260864, 0, 0, 33030144, 0, 65536, 2181038080, 0, 16777216, 16777216, 0, 15728640]] is not of type 'null'
        [2164260864, 0, 0, 33030144, 0, 65536, 2181038080, 0, 16777216, 16777216, 0, 15728640] is too long
        From schema: linux-imx/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml"
- refer to commit 281f1f99cf3a ("PCI: dwc: Detect number of iATU windows").
  The num-viewport is not required anymore, remove them totally.
- dt_binding_check complains "compatible: ['fsl,imx6qp-pcie', 'snps,dw-pcie']
  is too long", remove "snps,dw-pcie" from the compatible string.

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
Reviewed-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 7 +++----
 arch/arm/boot/dts/imx6qp.dtsi  | 2 +-
 arch/arm/boot/dts/imx6sx.dtsi  | 6 +++---
 arch/arm/boot/dts/imx7d.dtsi   | 7 +++----
 4 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 82e01ce026ea..d5477406401a 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -264,7 +264,7 @@ L2: cache-controller at a02000 {
 		};
 
 		pcie: pcie at 1ffc000 {
-			compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
+			compatible = "fsl,imx6q-pcie";
 			reg = <0x01ffc000 0x04000>,
 			      <0x01f00000 0x80000>;
 			reg-names = "dbi", "config";
@@ -272,10 +272,9 @@ pcie: pcie at 1ffc000 {
 			#size-cells = <2>;
 			device_type = "pci";
 			bus-range = <0x00 0xff>;
-			ranges = <0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
-				  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0 0          0x01f80000 0 0x00010000>, /* downstream I/O */
+				 <0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
-			num-viewport = <4>;
 			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
 			#interrupt-cells = <1>;
diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi
index b310f13a53f2..050365513836 100644
--- a/arch/arm/boot/dts/imx6qp.dtsi
+++ b/arch/arm/boot/dts/imx6qp.dtsi
@@ -110,5 +110,5 @@ &mmdc0 {
 };
 
 &pcie {
-	compatible = "fsl,imx6qp-pcie", "snps,dw-pcie";
+	compatible = "fsl,imx6qp-pcie";
 };
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 8516730778df..fc6334336b3d 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -1395,15 +1395,15 @@ pwm8: pwm at 22b0000 {
 		};
 
 		pcie: pcie at 8ffc000 {
-			compatible = "fsl,imx6sx-pcie", "snps,dw-pcie";
+			compatible = "fsl,imx6sx-pcie";
 			reg = <0x08ffc000 0x04000>, <0x08f00000 0x80000>;
 			reg-names = "dbi", "config";
 			#address-cells = <3>;
 			#size-cells = <2>;
 			device_type = "pci";
 			bus-range = <0x00 0xff>;
-			ranges = <0x81000000 0 0          0x08f80000 0 0x00010000 /* downstream I/O */
-				  0x82000000 0 0x08000000 0x08000000 0 0x00f00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0 0          0x08f80000 0 0x00010000>, /* downstream I/O */
+				 <0x82000000 0 0x08000000 0x08000000 0 0x00f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
 			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index b0bcfa9094a3..b7735979b7e4 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -164,7 +164,7 @@ fec2: ethernet at 30bf0000 {
 	};
 
 	pcie: pcie at 33800000 {
-		compatible = "fsl,imx7d-pcie", "snps,dw-pcie";
+		compatible = "fsl,imx7d-pcie";
 		reg = <0x33800000 0x4000>,
 		      <0x4ff00000 0x80000>;
 		reg-names = "dbi", "config";
@@ -172,10 +172,9 @@ pcie: pcie at 33800000 {
 		#size-cells = <2>;
 		device_type = "pci";
 		bus-range = <0x00 0xff>;
-		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
+		ranges = <0x81000000 0 0          0x4ff80000 0 0x00010000>, /* downstream I/O */
+			 <0x82000000 0 0x40000000 0x40000000 0 0x0ff00000>; /* non-prefetchable memory */
 		num-lanes = <1>;
-		num-viewport = <4>;
 		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "msi";
 		#interrupt-cells = <1>;
-- 
2.25.1



From hongxing.zhu at nxp.com  Thu Aug 26 23:42:58 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Fri, 27 Aug 2021 14:42:58 +0800
Subject: [PATCH v2 1/3] dt-bindings: PCI: imx6: convert the imx pcie
 controller to dtschema
In-Reply-To: <1630046580-19282-1-git-send-email-hongxing.zhu@nxp.com>
References: <1630046580-19282-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1630046580-19282-2-git-send-email-hongxing.zhu@nxp.com>

Convert the fsl,imx6q-pcie.txt into a schema.
- ranges property should be grouped by region, with no functional
  changes.
- only one propert is allowed in the compatible string, remove
  "snps,dw-pcie".

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
---
 .../bindings/pci/fsl,imx6q-pcie.txt           | 100 ---------
 .../bindings/pci/fsl,imx6q-pcie.yaml          | 202 ++++++++++++++++++
 MAINTAINERS                                   |   2 +-
 3 files changed, 203 insertions(+), 101 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
deleted file mode 100644
index d8971ab99274..000000000000
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-* Freescale i.MX6 PCIe interface
-
-This PCIe host controller is based on the Synopsys DesignWare PCIe IP
-and thus inherits all the common properties defined in designware-pcie.txt.
-
-Required properties:
-- compatible:
-	- "fsl,imx6q-pcie"
-	- "fsl,imx6sx-pcie",
-	- "fsl,imx6qp-pcie"
-	- "fsl,imx7d-pcie"
-	- "fsl,imx8mq-pcie"
-- reg: base address and length of the PCIe controller
-- interrupts: A list of interrupt outputs of the controller. Must contain an
-  entry for each entry in the interrupt-names property.
-- interrupt-names: Must include the following entries:
-	- "msi": The interrupt that is asserted when an MSI is received
-- clock-names: Must include the following additional entries:
-	- "pcie_phy"
-
-Optional properties:
-- fsl,tx-deemph-gen1: Gen1 De-emphasis value. Default: 0
-- fsl,tx-deemph-gen2-3p5db: Gen2 (3.5db) De-emphasis value. Default: 0
-- fsl,tx-deemph-gen2-6db: Gen2 (6db) De-emphasis value. Default: 20
-- fsl,tx-swing-full: Gen2 TX SWING FULL value. Default: 127
-- fsl,tx-swing-low: TX launch amplitude swing_low value. Default: 127
-- fsl,max-link-speed: Specify PCI gen for link capability. Must be '2' for
-  gen2, otherwise will default to gen1. Note that the IMX6 LVDS clock outputs
-  do not meet gen2 jitter requirements and thus for gen2 capability a gen2
-  compliant clock generator should be used and configured.
-- reset-gpio: Should specify the GPIO for controlling the PCI bus device reset
-  signal. It's not polarity aware and defaults to active-low reset sequence
-  (L=reset state, H=operation state).
-- reset-gpio-active-high: If present then the reset sequence using the GPIO
-  specified in the "reset-gpio" property is reversed (H=reset state,
-  L=operation state).
-- vpcie-supply: Should specify the regulator in charge of PCIe port power.
-  The regulator will be enabled when initializing the PCIe host and
-  disabled either as part of the init process or when shutting down the
-  host.
-- vph-supply: Should specify the regulator in charge of VPH one of the three
-  PCIe PHY powers. This regulator can be supplied by both 1.8v and 3.3v voltage
-  supplies.
-
-Additional required properties for imx6sx-pcie:
-- clock names: Must include the following additional entries:
-	- "pcie_inbound_axi"
-- power-domains: Must be set to phandles pointing to the DISPLAY and
-  PCIE_PHY power domains
-- power-domain-names: Must be "pcie", "pcie_phy"
-
-Additional required properties for imx7d-pcie and imx8mq-pcie:
-- power-domains: Must be set to a phandle pointing to PCIE_PHY power domain
-- resets: Must contain phandles to PCIe-related reset lines exposed by SRC
-  IP block
-- reset-names: Must contain the following entries:
-	       - "pciephy"
-	       - "apps"
-	       - "turnoff"
-- fsl,imx7d-pcie-phy: A phandle to an fsl,imx7d-pcie-phy node.
-
-Additional required properties for imx8mq-pcie:
-- clock-names: Must include the following additional entries:
-	- "pcie_aux"
-
-Example:
-
-	pcie at 01000000 {
-		compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
-		reg = <0x01ffc000 0x04000>,
-		      <0x01f00000 0x80000>;
-		reg-names = "dbi", "config";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000
-			  0x81000000 0 0          0x01f80000 0 0x00010000
-			  0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
-		num-lanes = <1>;
-		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "msi";
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0x7>;
-		interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-		                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-		                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-		                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&clks 144>, <&clks 206>, <&clks 189>;
-		clock-names = "pcie", "pcie_bus", "pcie_phy";
-	};
-
-* Freescale i.MX7d PCIe PHY
-
-This is the PHY associated with the IMX7d PCIe controller.  It's used by the
-PCI-e controller via the fsl,imx7d-pcie-phy phandle.
-
-Required properties:
-- compatible:
-	- "fsl,imx7d-pcie-phy"
-- reg: base address and length of the PCIe PHY controller
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
new file mode 100644
index 000000000000..2911e565b260
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
@@ -0,0 +1,202 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/fsl,imx6q-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX6 PCIe host controller
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+  - Richard Zhu <hongxing.zhu at nxp.com>
+
+description: |+
+  This PCIe host controller is based on the Synopsys DesignWare PCIe IP
+  and thus inherits all the common properties defined in snps,dw-pcie.yaml.
+
+allOf:
+  - $ref: /schemas/pci/snps,dw-pcie.yaml#
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx6q-pcie
+      - fsl,imx6sx-pcie
+      - fsl,imx6qp-pcie
+      - fsl,imx7d-pcie
+      - fsl,imx8mq-pcie
+
+  reg:
+    items:
+      - description: Data Bus Interface (DBI) registers.
+      - description: PCIe configuration space region.
+
+  reg-names:
+    items:
+      - const: dbi
+      - const: config
+
+  interrupts:
+    items:
+      - description: builtin MSI controller.
+
+  interrupt-names:
+    minItems: 1
+    items:
+      - const: msi
+
+  clocks:
+    minItems: 3
+    items:
+      - description: PCIe bridge clock.
+      - description: PCIe bus clock.
+      - description: PCIe PHY clock.
+      - description: Additional required clock entry for imx6sx-pcie,
+          imx8mq-pcie.
+
+  clock-names:
+    minItems: 3
+    items:
+      - const: pcie
+      - const: pcie_bus
+      - const: pcie_phy
+      - const: pcie_inbound_axi for imx6sx-pcie, pcie_aux for imx8mq-pcie
+
+  num-lanes:
+    const: 1
+
+  fsl,imx7d-pcie-phy:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: A phandle to an fsl,imx7d-pcie-phy node. Additional
+      required properties for imx7d-pcie and imx8mq-pcie.
+
+  power-domains:
+    items:
+      - description: The phandle pointing to the DISPLAY domain for
+          imx6sx-pcie, to PCIE_PHY power domain for imx7d-pcie and
+          imx8mq-pcie.
+      - description: The phandle pointing to the PCIE_PHY power domains
+          for imx6sx-pcie.
+
+  power-domain-names:
+    items:
+      - const: pcie
+      - const: pcie_phy
+
+  resets:
+    maxItems: 3
+    description: Phandles to PCIe-related reset lines exposed by SRC
+      IP block. Additional required by imx7d-pcie and imx8mq-pcie.
+
+  reset-names:
+    items:
+      - const: pciephy
+      - const: apps
+      - const: turnoff
+
+  fsl,tx-deemph-gen1:
+    description: Gen1 De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  fsl,tx-deemph-gen2-3p5db:
+    description: Gen2 (3.5db) De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  fsl,tx-deemph-gen2-6db:
+    description: Gen2 (6db) De-emphasis value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 20
+
+  fsl,tx-swing-full:
+    description: Gen2 TX SWING FULL value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 127
+
+  fsl,tx-swing-low:
+    description: TX launch amplitude swing_low value (optional required).
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 127
+
+  fsl,max-link-speed:
+    description: Specify PCI Gen for link capability (optional required).
+      Note that the IMX6 LVDS clock outputs do not meet gen2 jitter
+      requirements and thus for gen2 capability a gen2 compliant clock
+      generator should be used and configured.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3, 4]
+    default: 1
+
+  reset-gpio:
+    description: Should specify the GPIO for controlling the PCI bus device
+      reset signal. It's not polarity aware and defaults to active-low reset
+      sequence (L=reset state, H=operation state) (optional required).
+
+  reset-gpio-active-high:
+    description: If present then the reset sequence using the GPIO
+      specified in the "reset-gpio" property is reversed (H=reset state,
+      L=operation state) (optional required).
+
+  vpcie-supply:
+    description: Should specify the regulator in charge of PCIe port power.
+      The regulator will be enabled when initializing the PCIe host and
+      disabled either as part of the init process or when shutting down
+      the host (optional required).
+
+  vph-supply:
+    description: Should specify the regulator in charge of VPH one of
+      the three PCIe PHY powers. This regulator can be supplied by both
+      1.8v and 3.3v voltage supplies (optional required).
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#address-cells"
+  - "#size-cells"
+  - device_type
+  - bus-range
+  - ranges
+  - num-lanes
+  - interrupts
+  - interrupt-names
+  - "#interrupt-cells"
+  - interrupt-map-mask
+  - interrupt-map
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx6qdl-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    pcie: pcie at 1ffc000 {
+        compatible = "fsl,imx6q-pcie";
+        reg = <0x01ffc000 0x04000>,
+              <0x01f00000 0x80000>;
+        reg-names = "dbi", "config";
+        #address-cells = <3>;
+        #size-cells = <2>;
+        device_type = "pci";
+        bus-range = <0x00 0xff>;
+        ranges = <0x81000000 0 0          0x01f80000 0 0x00010000>,
+                 <0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
+        num-lanes = <1>;
+        interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "msi";
+        #interrupt-cells = <1>;
+        interrupt-map-mask = <0 0 0 0x7>;
+        interrupt-map = <0 0 0 1 &gpc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                        <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                        <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                        <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
+                <&clks IMX6QDL_CLK_LVDS1_GATE>,
+                <&clks IMX6QDL_CLK_PCIE_REF_125M>;
+        clock-names = "pcie", "pcie_bus", "pcie_phy";
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index f73fef615702..a1e2cc0be9e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14187,7 +14187,7 @@ M:	Lucas Stach <l.stach at pengutronix.de>
 L:	linux-pci at vger.kernel.org
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
-F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+F:	Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
 F:	drivers/pci/controller/dwc/*imx6*
 
 PCI DRIVER FOR FU740
-- 
2.25.1



From hongxing.zhu at nxp.com  Thu Aug 26 23:43:00 2021
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Fri, 27 Aug 2021 14:43:00 +0800
Subject: [PATCH v2 3/3] arm64: dts: imx8mq: fix the schema check errors
In-Reply-To: <1630046580-19282-1-git-send-email-hongxing.zhu@nxp.com>
References: <1630046580-19282-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1630046580-19282-4-git-send-email-hongxing.zhu@nxp.com>

No functional changes, but the ranges should be grouped by region.
Otherwise, schema dtbs_check would report the following errors.

"/linux-imx/arch/arm64/boot/dts/freescale/imx8mq-evk.dt.yaml: pcie at 33800000: ranges: 'oneOf' conditional failed, one must be fixed:
        /linux-imx/arch/arm64/boot/dts/freescale/imx8mq-evk.dt.yaml: pcie at 33800000: ranges: 'oneOf' conditional failed, one must be fixed:
                [[2164260864, 0, 0, 536346624, 0, 65536, 2181038080, 0, 402653184, 402653184, 0, 133169152]] is not of type 'boolean'
                True was expected
                [[2164260864, 0, 0, 536346624, 0, 65536, 2181038080, 0, 402653184, 402653184, 0, 133169152]] is not of type 'null'
        [2164260864, 0, 0, 536346624, 0, 65536, 2181038080, 0, 402653184, 402653184, 0, 133169152] is too long
        From schema: //linux-imx/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml"

Refer to commit 281f1f99cf3a ("PCI: dwc: Detect number of iATU windows").
The num-viewport is not required anymore, remove them totally.

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
Reviewed-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 91df9c5350ae..c6dba9b92edd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1364,10 +1364,9 @@ pcie0: pcie at 33800000 {
 			#size-cells = <2>;
 			device_type = "pci";
 			bus-range = <0x00 0xff>;
-			ranges = <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000 /* downstream I/O 64KB */
-			          0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
+			ranges = <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000>, /* downstream I/O 64KB */
+				 <0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
-			num-viewport = <4>;
 			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
 			#interrupt-cells = <1>;
@@ -1402,10 +1401,9 @@ pcie1: pcie at 33c00000 {
 			#address-cells = <3>;
 			#size-cells = <2>;
 			device_type = "pci";
-			ranges =  <0x81000000 0 0x00000000 0x27f80000 0 0x00010000 /* downstream I/O 64KB */
-				   0x82000000 0 0x20000000 0x20000000 0 0x07f00000>; /* non-prefetchable memory */
+			ranges =  <0x81000000 0 0x00000000 0x27f80000 0 0x00010000>, /* downstream I/O 64KB */
+				  <0x82000000 0 0x20000000 0x20000000 0 0x07f00000>; /* non-prefetchable memory */
 			num-lanes = <1>;
-			num-viewport = <4>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
 			#interrupt-cells = <1>;
-- 
2.25.1



From peterz at infradead.org  Fri Aug 27 00:15:17 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Fri, 27 Aug 2021 09:15:17 +0200
Subject: [PATCH 05/15] perf: Track guest callbacks on a per-CPU basis
In-Reply-To: <20210827005718.585190-6-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
 <20210827005718.585190-6-seanjc@google.com>
Message-ID: <YSiRBQQE7md7ZrNC@hirez.programming.kicks-ass.net>

On Thu, Aug 26, 2021 at 05:57:08PM -0700, Sean Christopherson wrote:
> Use a per-CPU pointer to track perf's guest callbacks so that KVM can set
> the callbacks more precisely and avoid a lurking NULL pointer dereference.

I'm completely failing to see how per-cpu helps anything here...

> On x86, KVM supports being built as a module and thus can be unloaded.
> And because the shared callbacks are referenced from IRQ/NMI context,
> unloading KVM can run concurrently with perf, and thus all of perf's
> checks for a NULL perf_guest_cbs are flawed as perf_guest_cbs could be
> nullified between the check and dereference.

No longer allowing KVM to be a module would be *AWESOME*. I detest how
much we have to export for KVM :/

Still, what stops KVM from doing a coherent unreg? Even the
static_call() proposed in the other patch, unreg can do
static_call_update() + synchronize_rcu() to ensure everybody sees the
updated pointer (would require a quick audit to see all users are with
preempt disabled, but I think your using per-cpu here already imposes
the same).




From jens.wiklander at linaro.org  Fri Aug 27 00:18:22 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Fri, 27 Aug 2021 09:18:22 +0200
Subject: [PATCH v4 4/5] optee: isolate smc abi
In-Reply-To: <CAFA6WYOZsZKfG0ZO8LGMcvQG8-pV0Z=hGF2nDFg7OW2DQO0esw@mail.gmail.com>
References: <20210819110655.739318-1-jens.wiklander@linaro.org>
 <20210819110655.739318-5-jens.wiklander@linaro.org>
 <CAFA6WYOZsZKfG0ZO8LGMcvQG8-pV0Z=hGF2nDFg7OW2DQO0esw@mail.gmail.com>
Message-ID: <20210827071822.GA1748471@jade>

On Wed, Aug 25, 2021 at 05:11:00PM +0530, Sumit Garg wrote:
> On Thu, 19 Aug 2021 at 16:37, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> >
> > Isolate the ABI based on raw SMCs. Code specific to the raw SMC ABI is
> > moved into smc_abi.c. This makes room for other ABIs with a clear
> > separation.
> >
> > The driver changes to use module_init()/module_exit() instead of
> > module_platform_driver(). The platform_driver_register() and
> > platform_driver_unregister() functions called directly to keep the same
> > behavior. This is needed because module_platform_driver() is based on
> > module_driver() which can only be used once in a module.
> >
> > A function optee_rpc_cmd() is factored out from the function
> > handle_rpc_func_cmd() to handle the ABI independent part of RPC
> > processing.
> >
> > This patch is not supposed to change the driver behavior, it's only a
> > matter of reorganizing the code.
> >
> > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > ---
> >  drivers/tee/optee/Makefile        |    6 +-
> >  drivers/tee/optee/call.c          |  339 +-------
> >  drivers/tee/optee/core.c          |  688 +--------------
> >  drivers/tee/optee/optee_private.h |  103 ++-
> >  drivers/tee/optee/rpc.c           |  217 +----
> >  drivers/tee/optee/shm_pool.c      |   89 --
> >  drivers/tee/optee/shm_pool.h      |   14 -
> >  drivers/tee/optee/smc_abi.c       | 1299 +++++++++++++++++++++++++++++
> >  8 files changed, 1439 insertions(+), 1316 deletions(-)
> >  delete mode 100644 drivers/tee/optee/shm_pool.c
> >  delete mode 100644 drivers/tee/optee/shm_pool.h
> >  create mode 100644 drivers/tee/optee/smc_abi.c
> >
> 
> Apart from minor comments below including one related to rebase, this
> looks good to me. So feel free to add:
> 
> Reviewed-by: Sumit Garg <sumit.garg at linaro.org>
> 
> > diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
> > index 3aa33ea9e6a6..e92f77462f40 100644
> > --- a/drivers/tee/optee/Makefile
> > +++ b/drivers/tee/optee/Makefile
> > @@ -4,8 +4,10 @@ optee-objs += core.o
> >  optee-objs += call.o
> >  optee-objs += rpc.o
> >  optee-objs += supp.o
> > -optee-objs += shm_pool.o
> >  optee-objs += device.o
> >
> > +optee-smc-abi-y = smc_abi.o
> > +optee-objs += $(optee-ffa-abi-y)
> 
> Did you mean optee-smc-abi-y here?

Yes, I'll fix, thanks.

[snip]
> > index d767eebf30bd..000000000000
> > --- a/drivers/tee/optee/shm_pool.c
> > +++ /dev/null
> > @@ -1,89 +0,0 @@
> > -// SPDX-License-Identifier: GPL-2.0-only
> > -/*
> > - * Copyright (c) 2015, Linaro Limited
> > - * Copyright (c) 2017, EPAM Systems
> > - */
> > -#include <linux/device.h>
> > -#include <linux/dma-buf.h>
> > -#include <linux/genalloc.h>
> > -#include <linux/slab.h>
> > -#include <linux/tee_drv.h>
> > -#include "optee_private.h"
> > -#include "optee_smc.h"
> > -#include "shm_pool.h"
> > -
> > -static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
> > -                        struct tee_shm *shm, size_t size)
> > -{
> > -       unsigned int order = get_order(size);
> > -       struct page *page;
> > -       int rc = 0;
> > -
> > -       page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
> > -       if (!page)
> > -               return -ENOMEM;
> > -
> > -       shm->kaddr = page_address(page);
> > -       shm->paddr = page_to_phys(page);
> > -       shm->size = PAGE_SIZE << order;
> > -
> > -       if (shm->flags & TEE_SHM_DMA_BUF) {
> 
> I guess this series needs to be rebased on top of mainline, since now
> we have TEE_SHM_PRIV flag here [1]?
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/tee/optee/shm_pool.c

Right, I'll take care of that in the next patchset.

[snip]
> > --- /dev/null
> > +++ b/drivers/tee/optee/smc_abi.c
> > @@ -0,0 +1,1299 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (c) 2015-2021, Linaro Limited
> > + * Copyright (c) 2016, EPAM Systems
> > + */
> > +
> > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > +
> > +#include <linux/arm-smccc.h>
> > +#include <linux/errno.h>
> > +#include <linux/io.h>
> > +#include <linux/sched.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/slab.h>
> > +#include <linux/string.h>
> > +#include <linux/tee_drv.h>
> > +#include <linux/types.h>
> > +#include <linux/workqueue.h>
> > +#include "optee_private.h"
> > +#include "optee_smc.h"
> > +#include "optee_rpc_cmd.h"
> > +#define CREATE_TRACE_POINTS
> > +#include "optee_trace.h"
> > +
> > +/*
> > + * This file implement the SMC ABI used when communicating with secure world
> > + * OP-TEE OS via raw SMCs.
> > + * This file is divided into the follow sections:
> 
> s/follow/following/

I'll fix.

Thanks,
Jens


From lkp at intel.com  Fri Aug 27 00:16:57 2021
From: lkp at intel.com (kernel test robot)
Date: Fri, 27 Aug 2021 15:16:57 +0800
Subject: [PATCH v6 3/3] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <20210826211830.3311140-3-sean.anderson@seco.com>
References: <20210826211830.3311140-3-sean.anderson@seco.com>
Message-ID: <202108271550.btqnrtGU-lkp@intel.com>

Hi Sean,

I love your patch! Perhaps something to improve:

[auto build test WARNING on tip/timers/core]
[also build test WARNING on pwm/for-next linus/master v5.14-rc7 next-20210826]
[cannot apply to xlnx/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Sean-Anderson/dt-bindings-pwm-Add-Xilinx-AXI-Timer/20210827-052011
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 127c92feb74a6721f62587f1b89128808f049cf1
config: mips-randconfig-r025-20210827 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 1076082a0d97bd5c16a25ee7cf3dbb6ee4b5a9fe)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install mips cross compiling tool for clang build
        # apt-get install binutils-mips-linux-gnu
        # https://github.com/0day-ci/linux/commit/eab56f0b0c5a62e40c04916eb1b4f21f478cec3a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Sean-Anderson/dt-bindings-pwm-Add-Xilinx-AXI-Timer/20210827-052011
        git checkout eab56f0b0c5a62e40c04916eb1b4f21f478cec3a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/pwm/pwm-xilinx.c:249:34: warning: unused variable 'xilinx_timer_of_match' [-Wunused-const-variable]
   static const struct of_device_id xilinx_timer_of_match[] = {
                                    ^
   1 warning generated.


vim +/xilinx_timer_of_match +249 drivers/pwm/pwm-xilinx.c

   248	
 > 249	static const struct of_device_id xilinx_timer_of_match[] = {
   250		{ .compatible = "xlnx,xps-timer-1.00.a", },
   251		{},
   252	};
   253	MODULE_DEVICE_TABLE(of, xilinx_timer_of_match);
   254	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 30008 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210827/29fdf7d1/attachment-0001.gz>

From peterz at infradead.org  Fri Aug 27 00:21:43 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Fri, 27 Aug 2021 09:21:43 +0200
Subject: [PATCH 06/15] KVM: x86: Register perf callbacks only when
 actively handling interrupt
In-Reply-To: <20210827005718.585190-7-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
 <20210827005718.585190-7-seanjc@google.com>
Message-ID: <YSiShwJeBvAVPVKe@hirez.programming.kicks-ass.net>

On Thu, Aug 26, 2021 at 05:57:09PM -0700, Sean Christopherson wrote:
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 9bc1375d6ed9..2f28d9d8dc94 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6485,6 +6485,18 @@ static void perf_pending_event(struct irq_work *entry)
>  #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
>  DEFINE_PER_CPU(struct perf_guest_info_callbacks *, perf_guest_cbs);
>  
> +void __perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
> +{
> +	__this_cpu_write(perf_guest_cbs, cbs);
> +}
> +EXPORT_SYMBOL_GPL(__perf_register_guest_info_callbacks);
> +
> +void __perf_unregister_guest_info_callbacks(void)
> +{
> +	__this_cpu_write(perf_guest_cbs, NULL);
> +}
> +EXPORT_SYMBOL_GPL(__perf_unregister_guest_info_callbacks);

This is 100% broken, and a prime example of why I hate modules.

It provides an interface for all modules, and completely fails to
validate even the most basic usage.

By using __this_cpu*() it omits the preemption checks, so you can call
this with preemption enabled, no problem.

By not checking the previous state, multiple modules can call this
interleaved without issue.

Basically assume any EXPORTed function is hostile, binary modules and
out-of-tree modules *are* just that. It's a cesspit out there.


From peterz at infradead.org  Fri Aug 27 00:30:36 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Fri, 27 Aug 2021 09:30:36 +0200
Subject: [PATCH 07/15] KVM: Use dedicated flag to track if KVM is
 handling an NMI from guest
In-Reply-To: <20210827005718.585190-8-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
 <20210827005718.585190-8-seanjc@google.com>
Message-ID: <YSiUnDbi/aZ3nunT@hirez.programming.kicks-ass.net>

On Thu, Aug 26, 2021 at 05:57:10PM -0700, Sean Christopherson wrote:
> diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
> index 5cedc0e8a5d5..4c5ba4128b38 100644
> --- a/arch/x86/kvm/x86.h
> +++ b/arch/x86/kvm/x86.h
> @@ -395,9 +395,10 @@ static inline void kvm_unregister_perf_callbacks(void)
>  
>  DECLARE_PER_CPU(struct kvm_vcpu *, current_vcpu);
>  
> -static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu)
> +static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu, bool is_nmi)
>  {
>  	__this_cpu_write(current_vcpu, vcpu);
> +	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, is_nmi);
>  
>  	kvm_register_perf_callbacks();
>  }
> @@ -406,6 +407,7 @@ static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
>  {
>  	kvm_unregister_perf_callbacks();
>  
> +	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, false);
>  	__this_cpu_write(current_vcpu, NULL);
>  }

Does this rely on kvm_{,un}register_perf_callback() being a function
call and thus implying a sequence point to order the stores? 


From peterz at infradead.org  Fri Aug 27 00:34:35 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Fri, 27 Aug 2021 09:34:35 +0200
Subject: [PATCH 11/15] KVM: x86: Move Intel Processor Trace interrupt
 handler to vmx.c
In-Reply-To: <20210827005718.585190-12-seanjc@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
 <20210827005718.585190-12-seanjc@google.com>
Message-ID: <YSiVi+jxNpFLE4gn@hirez.programming.kicks-ass.net>

On Thu, Aug 26, 2021 at 05:57:14PM -0700, Sean Christopherson wrote:
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 13c4f58a75e5..e0b1c9386926 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -5498,6 +5498,7 @@ void kvm_set_intel_pt_intr_handler(void (*handler)(void))
>  {
>  	kvm_guest_cbs.handle_intel_pt_intr = handler;
>  }
> +EXPORT_SYMBOL_GPL(kvm_set_intel_pt_intr_handler);

This is another one of those broken exports.


From drjones at redhat.com  Fri Aug 27 00:40:11 2021
From: drjones at redhat.com (Andrew Jones)
Date: Fri, 27 Aug 2021 09:40:11 +0200
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <YSfiN3Xq1vUzHeap@google.com>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org>
 <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
 <877dg8ppnt.wl-maz@kernel.org> <YSfiN3Xq1vUzHeap@google.com>
Message-ID: <20210827074011.ci2kzo4cnlp3qz7h@gator.home>

On Thu, Aug 26, 2021 at 06:49:27PM +0000, Oliver Upton wrote:
> On Thu, Aug 26, 2021 at 09:37:42AM +0100, Marc Zyngier wrote:
> > On Wed, 25 Aug 2021 19:14:59 +0100,
> > Oliver Upton <oupton at google.com> wrote:
> > > 
> > > On Wed, Aug 25, 2021 at 8:07 AM Andrew Jones <drjones at redhat.com> wrote:
> > 
> > [...]
> > 
> > > > Thanks for including me Marc. I think you've mentioned all the examples
> > > > of why we don't generally expect N+1 -> N migrations to work that I
> > > > can think of. While some of the examples like get-reg-list could
> > > > eventually be eliminated if we had CPU models to tighten our machine type
> > > > state, I think N+1 -> N migrations will always be best effort at most.
> > > >
> > > > I agree with giving userspace control over the exposer of the hypercalls
> > > > though. Using pseudo-registers for that purpose rather than a pile of
> > > > CAPs also seems reasonable to me.
> > > >
> > > > And, while I don't think this patch is going to proceed, I thought I'd
> > > > point out that the opt-out approach doesn't help much with expanding
> > > > our migration support unless we require the VMM to be upgraded first.
> > > >
> > > > And, even then, the (N_kern, N+1_vmm) -> (N+1_kern, N_vmm) case won't
> > > > work as expected, since the source enforce opt-out, but the destination
> > > > won't.
> > > 
> > > Right, there's going to need to be a fence in both kernel and VMM
> > > versions. Before the fence, you can't rollback with either component.
> > > Once on the other side of the fence, the user may freely migrate
> > > between kernel + VMM combinations.
> > >
> > > > Also, since the VMM doesn't key off the kernel version, for the
> > > > most part N+1 VMMs won't know when they're supposed to opt-out or not,
> > > > leaving it to the user to ensure they consider everything. opt-in
> > > > usually only needs the user to consider what machine type they want to
> > > > launch.
> > > 
> > > Going the register route will implicitly require opt-out for all old
> > > hypercalls. We exposed them unconditionally to the guest before, and
> > > we must uphold that behavior. The default value for the bitmap will
> > > have those features set. Any hypercalls added after that register
> > > interface will then require explicit opt-in from userspace.
> > 
> > I disagree here. This makes the ABI inconsistent, and means that no
> > feature can be implemented without changing userspace. If you can deal
> > with the existing features, you should be able to deal with the next
> > lot.
> >
> > > With regards to the pseudoregister interface, how would a VMM discover
> > > new bits? From my perspective, you need to have two bitmaps that the
> > > VMM can get at: the set of supported feature bits and the active
> > > bitmap of features for a running guest.
> > 
> > My proposal is that we have a single pseudo-register exposing the list
> > of implemented by the kernel. Clear the bits you don't want, and write
> > back the result. As long as you haven't written anything, you have the
> > full feature set. That's pretty similar to the virtio feature
> > negotiation.
> 
> Ah, yes I agree. Thinking about it more we will not need something
> similar to KVM_GET_SUPPORTED_CPUID.
> 
> So then, for any register where userspace/KVM need to negotiate
> features, the default value will return the maximum feature set that is
> supported. If userspace wants to constrain features, read out the
> register, make sure everything you want is there, and write it back
> blowing away the superfluous bits. Given this should we enforce ordering
> on feature registers, such that a VMM can only write to the registers
> before a VM is started?

That's a good idea. KVM_REG_ARM64_SVE_VLS has this type of constraint so
we can model the feature register control off that.

> 
> Also, Reiji is working on making the identity registers writable for the
> sake of feature restriction. The suggested negotiation interface would
> be applicable there too, IMO.

This this interesting news. I'll look forward to the posting.

> 
> Many thanks to both you and Drew for working this out with me.
>

Thanks,
drew 



From hch at lst.de  Fri Aug 27 00:40:41 2021
From: hch at lst.de (Christoph Hellwig)
Date: Fri, 27 Aug 2021 09:40:41 +0200
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>
References: <20210826131747.GE26318@willie-the-truck>
 <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>
Message-ID: <20210827074041.GA24309@lst.de>

On Thu, Aug 26, 2021 at 11:41:34AM -0700, Linus Torvalds wrote:
> "pfn_valid()" is more about whether you can do a "pfn_to_page()" lookup on it.
> 
> II get the feeling that the dma-mapping code should allow pages that
> are PageReserved() to be mapped - they aren't "ram" in the kernel
> sense.
> 
> Perhaps also make sure it's not the zero page (which is
> PageReserved(), but most definitely RAM).
> 
> In a PC world that would be (for example) the legacy PCI space at
> 0xa0000-0xfffff, but I could easily imagine other platforms having
> other situations.

So what would be the correct check for "this is not actually page backed
normal RAM"?


From peterz at infradead.org  Fri Aug 27 00:44:52 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Fri, 27 Aug 2021 09:44:52 +0200
Subject: [PATCH 00/15] perf: KVM: Fix, optimize, and clean up callbacks
In-Reply-To: <fd3dcd6c-b3d5-4453-93fb-b46d0595534e@gmail.com>
References: <20210827005718.585190-1-seanjc@google.com>
 <fd3dcd6c-b3d5-4453-93fb-b46d0595534e@gmail.com>
Message-ID: <YSiX9OPcrDsr3P4C@hirez.programming.kicks-ass.net>

On Fri, Aug 27, 2021 at 02:52:25PM +0800, Like Xu wrote:
> + STATIC BRANCH/CALL friends.
> 
> On 27/8/2021 8:57 am, Sean Christopherson wrote:
> > This started out as a small series[1] to fix a KVM bug related to Intel PT
> > interrupt handling and snowballed horribly.
> > 
> > The main problem being addressed is that the perf_guest_cbs are shared by
> > all CPUs, can be nullified by KVM during module unload, and are not
> > protected against concurrent access from NMI context.
> 
> Shouldn't this be a generic issue of the static_call() usage ?
> 
> At the beginning, we set up the static entry assuming perf_guest_cbs != NULL:
> 
> 	if (perf_guest_cbs && perf_guest_cbs->handle_intel_pt_intr) {
> 		static_call_update(x86_guest_handle_intel_pt_intr,
> 				   perf_guest_cbs->handle_intel_pt_intr);
> 	}
> 
> and then we unset the perf_guest_cbs and do the static function call like this:
> 
> DECLARE_STATIC_CALL(x86_guest_handle_intel_pt_intr,
> *(perf_guest_cbs->handle_intel_pt_intr));
> static int handle_pmi_common(struct pt_regs *regs, u64 status)
> {
> 		...
> 		if (!static_call(x86_guest_handle_intel_pt_intr)())
> 			intel_pt_interrupt();
> 		...
> }

You just have to make sure all static_call() invocations that started
before unreg are finished before continuing with the unload.
synchronize_rcu() can help with that.

This is module unload 101. Nothing specific to static_call().


From kenchappa.demakkanavar at intel.com  Fri Aug 27 00:55:05 2021
From: kenchappa.demakkanavar at intel.com (Demakkanavar, Kenchappa)
Date: Fri, 27 Aug 2021 07:55:05 +0000
Subject: [PATCH V2 3/3] arm64: dts: add initial device tree for Thunder
 Bay SoC
In-Reply-To: <YQMHNX5cCBFdm7YK@robh.at.kernel.org>
References: <1626758569-27176-1-git-send-email-kenchappa.demakkanavar@intel.com>
 <1626758569-27176-4-git-send-email-kenchappa.demakkanavar@intel.com>
 <YQMHNX5cCBFdm7YK@robh.at.kernel.org>
Message-ID: <BYAPR11MB2661594B0F0B87CE35CCB08E8CC89@BYAPR11MB2661.namprd11.prod.outlook.com>

Hi Rob,

Thanks for your time in providing feedback. 

Please find my reply in-lined below.

Thanks & Regards,
Kenchappa S. D.

> -----Original Message-----
> From: Rob Herring <robh at kernel.org>
> Sent: Friday, July 30, 2021 1:23 AM
> To: Demakkanavar, Kenchappa <kenchappa.demakkanavar at intel.com>
> Cc: will at kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; devicetree at vger.kernel.org; dinguyen at kernel.org;
> Zhou, Furong <furong.zhou at intel.com>; kris.pan at linux.intel.com; Pan, Kris
> <kris.pan at intel.com>; mgross at linux.intel.com; Gross, Mark
> <mark.gross at intel.com>
> Subject: Re: [PATCH V2 3/3] arm64: dts: add initial device tree for Thunder Bay
> SoC
> 
> On Tue, Jul 20, 2021 at 10:52:49AM +0530,
> kenchappa.demakkanavar at intel.com wrote:
> > From: "Demakkanavar, Kenchappa" <kenchappa.demakkanavar at intel.com>
> >
> > Add initial device tree for Intel Movidius SoC code-named Thunder Bay.
> >
> > This initial DT includes nodes for 4 CPU clusters with 4 Cortex-A53
> > cores per cluster, UARTs, GIC, ARM Timer and PSCI.
> 
> Make sure you run 'make dtbs_check' on these.
Sure. Will post clean patches in next version.

> 
> There shouldn't be any dtc warnings and or undocumented compatible warnings
> at a minimum.
Sure. Will post clean patches in next version.

> 
> > thunderbay-soc.dtsi   - Thunder Bay SoC dtsi file
> > hddl_hybrid_4s.dts    - Thunder Bay full configuration board dts
> > 			with 4 VPU processors
> > hddl_hybrid_2s_02.dts - Thunder Bay prime configuration board dts with
> > 			2 VPU processors (slice 0 and slice 2 enabled)
> > hddl_hybrid_2s_03.dts - Thunder Bay prime configuration board dts with
> > 			2 VPU processors (slice 0 and slice 3 enabled)
> > hddl_hybrid_2s_12.dts - Thunder Bay prime configuration board dts with
> > 			2 VPU processors (slice 1 and slice 2 enabled)
> > hddl_hybrid_2s_13.dts - Thunder Bay prime configuration board dts with
> > 			2 VPU processors (slice 1 and slice 3 enabled)
> >
> > Signed-off-by: Demakkanavar, Kenchappa
> > <kenchappa.demakkanavar at intel.com>
> > ---
> >  MAINTAINERS                                     |   2 +
> >  arch/arm64/boot/dts/intel/Makefile              |   6 +
> >  arch/arm64/boot/dts/intel/hddl_hybrid_2s_02.dts |  43 +++++
> > arch/arm64/boot/dts/intel/hddl_hybrid_2s_03.dts |  43 +++++
> > arch/arm64/boot/dts/intel/hddl_hybrid_2s_12.dts |  43 +++++
> > arch/arm64/boot/dts/intel/hddl_hybrid_2s_13.dts |  43 +++++
> >  arch/arm64/boot/dts/intel/hddl_hybrid_4s.dts    |  54 ++++++
> >  arch/arm64/boot/dts/intel/thunderbay-soc.dtsi   | 243
> ++++++++++++++++++++++++
> >  8 files changed, 477 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/intel/hddl_hybrid_2s_02.dts
> >  create mode 100644 arch/arm64/boot/dts/intel/hddl_hybrid_2s_03.dts
> >  create mode 100644 arch/arm64/boot/dts/intel/hddl_hybrid_2s_12.dts
> >  create mode 100644 arch/arm64/boot/dts/intel/hddl_hybrid_2s_13.dts
> >  create mode 100644 arch/arm64/boot/dts/intel/hddl_hybrid_4s.dts
> >  create mode 100644 arch/arm64/boot/dts/intel/thunderbay-soc.dtsi
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS index 041f9a0..68317f0 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1996,6 +1996,8 @@ ARM/INTEL THUNDERBAY ARCHITECTURE
> >  M:	Demakkanavar, Kenchappa <kenchappa.demakkanavar at intel.com>
> >  S:	Maintained
> >  F:	Documentation/devicetree/bindings/arm/intel,thunderbay.yaml
> > +F:	arch/arm64/boot/dts/intel/hddl*
> > +F:	arch/arm64/boot/dts/intel/thunderbay-soc.dtsi
> >
> >  ARM/INTEL XSC3 (MANZANO) ARM CORE
> >  M:	Lennert Buytenhek <kernel at wantstofly.org>
> > diff --git a/arch/arm64/boot/dts/intel/Makefile
> > b/arch/arm64/boot/dts/intel/Makefile
> > index 0b54774..767b74b 100644
> > --- a/arch/arm64/boot/dts/intel/Makefile
> > +++ b/arch/arm64/boot/dts/intel/Makefile
> > @@ -3,3 +3,9 @@ dtb-$(CONFIG_ARCH_INTEL_SOCFPGA) +=
> socfpga_agilex_socdk.dtb \
> >  				socfpga_agilex_socdk_nand.dtb \
> >  				socfpga_n5x_socdk.dtb
> >  dtb-$(CONFIG_ARCH_KEEMBAY) += keembay-evm.dtb
> > +
> > +dtb-$(CONFIG_ARCH_THUNDERBAY) += hddl_hybrid_4s.dtb \
> > +				 hddl_hybrid_2s_02.dtb \
> > +				 hddl_hybrid_2s_03.dtb \
> > +				 hddl_hybrid_2s_12.dtb \
> > +				 hddl_hybrid_2s_13.dtb
> > diff --git a/arch/arm64/boot/dts/intel/hddl_hybrid_2s_02.dts
> > b/arch/arm64/boot/dts/intel/hddl_hybrid_2s_02.dts
> > new file mode 100644
> > index 0000000..f907ddd
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/intel/hddl_hybrid_2s_02.dts
> > @@ -0,0 +1,43 @@
> > +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
> > +/*
> > + * Copyright (c) 2021 Intel Corporation.
> > + *
> > + * Device tree describing Intel Thunder Bay Hybrid HDDL Prime
> > +configuration
> > + * board.
> > + *
> > + * DDR 8GB + 4GB with vpu slice 0 and vpu slice 2  */
> > +
> > +/dts-v1/;
> > +
> > +#include "thunderbay-soc.dtsi"
> > +
> > +/ {
> > +	model = "Intel Thunder Bay Hybrid HDDL Prime Board";
> > +	compatible = "intel,thunderbay";
> > +
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> > +
> > +	aliases {
> > +		serial0 = &uart0;
> > +		serial1 = &uart1;
> 
> Why do you have an alias to a disabled node?
Ok. Will remove this. 

> 
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	memory at 100A000000 {
> 
> Lowercase hex on unit-addresses.
Ok.

> 
> > +		device_type = "memory";
> > +		/* 8GB of DDR memory */
> > +		reg = <0x10 0x0A000000 0x2 0x0>;
> > +	};
> > +
> > +	memory at 1200000000 {
> > +		device_type = "memory";
> > +		/* 4GB of DDR memory */
> > +		reg = <0x12 0x0 0x1 0x0>;
> > +	};
> > +
> > +};
> > diff --git a/arch/arm64/boot/dts/intel/hddl_hybrid_2s_03.dts
> > b/arch/arm64/boot/dts/intel/hddl_hybrid_2s_03.dts
> > new file mode 100644
> > index 0000000..01a3d4c
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/intel/hddl_hybrid_2s_03.dts
> > @@ -0,0 +1,43 @@
> > +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
> > +/*
> > + * Copyright (c) 2021 Intel Corporation.
> > + *
> > + * Device tree describing Intel Thunder Bay Hybrid HDDL Prime
> > +configuration
> > + * board
> > + *
> > + * DDR 8GB + 4GB with vpu slice 0 and vpu slice 3  */
> > +
> > +/dts-v1/;
> > +
> > +#include "thunderbay-soc.dtsi"
> > +
> > +/ {
> > +	model = "Intel Thunder Bay Hybrid HDDL Prime Board";
> > +	compatible = "intel,thunderbay";
> 
> This should have a board specific compatible. Not sure if you need 1 or
> 4 though. If the VPU slice stuff is determined elsewhere then 1 is enough.
Since minimum dts will boot for both 4 slice VPU SoC and 2 slice VPU SoC, I will start with single compatible string now. 
Also minimum dts for 2 VPU slices are same, I will submit common single dts for 2 VPU slice boards in next version.

> 
> > +
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> > +
> > +	aliases {
> > +		serial0 = &uart0;
> > +		serial1 = &uart1;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	memory at 100A000000 {
> > +		device_type = "memory";
> > +		/* 8GB of DDR memory */
> > +		reg = <0x10 0x0A000000 0x2 0x0>;
> > +	};
> > +
> > +	memory at 1200000000 {
> > +		device_type = "memory";
> > +		/* 4GB of DDR memory */
> > +		reg = <0x12 0x0 0x1 0x0>;
> > +	};
> > +
> > +};
> > diff --git a/arch/arm64/boot/dts/intel/hddl_hybrid_2s_12.dts
> > b/arch/arm64/boot/dts/intel/hddl_hybrid_2s_12.dts
> > new file mode 100644
> > index 0000000..e31db16
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/intel/hddl_hybrid_2s_12.dts
> > @@ -0,0 +1,43 @@
> > +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
> > +/*
> > + * Copyright (c) 2021 Intel Corporation.
> > + *
> > + * Device tree describing Intel Thunder Bay Hybrid HDDL Prime
> > +configuration
> > + * board
> > + *
> > + * DDR 8GB + 4GB with vpu slice 1 and vpu slice 2  */
> > +
> > +/dts-v1/;
> > +
> > +#include "thunderbay-soc.dtsi"
> > +
> > +/ {
> > +	model = "Intel Thunder Bay Hybrid HDDL Prime Board";
> > +	compatible = "intel,thunderbay";
> > +
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> > +
> > +	aliases {
> > +		serial0 = &uart0;
> > +		serial1 = &uart1;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	memory at 100A000000 {
> > +		device_type = "memory";
> > +		/* 8GB of DDR memory */
> > +		reg = <0x10 0x0A000000 0x2 0x0>;
> > +	};
> > +
> > +	memory at 1200000000 {
> > +		device_type = "memory";
> > +		/* 4GB of DDR memory */
> > +		reg = <0x12 0x0 0x1 0x0>;
> > +	};
> > +
> > +};
> > diff --git a/arch/arm64/boot/dts/intel/hddl_hybrid_2s_13.dts
> > b/arch/arm64/boot/dts/intel/hddl_hybrid_2s_13.dts
> > new file mode 100644
> > index 0000000..6529664
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/intel/hddl_hybrid_2s_13.dts
> > @@ -0,0 +1,43 @@
> > +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
> > +/*
> > + * Copyright (c) 2021 Intel Corporation.
> > + *
> > + * Device tree describing Intel Thunder Bay Hybrid HDDL Prime
> > +configuration
> > + * board
> > + *
> > + * DDR 8GB + 4GB with vpu slice 1 and vpu slice 3  */
> > +
> > +/dts-v1/;
> > +
> > +#include "thunderbay-soc.dtsi"
> > +
> > +/ {
> > +	model = "Intel Thunder Bay Hybrid HDDL Prime Board";
> > +	compatible = "intel,thunderbay";
> > +
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> > +
> > +	aliases {
> > +		serial0 = &uart0;
> > +		serial1 = &uart1;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	memory at 100A000000 {
> > +		device_type = "memory";
> > +		/* 8GB of DDR memory */
> > +		reg = <0x10 0x0A000000 0x2 0x0>;
> > +	};
> > +
> > +	memory at 1200000000 {
> > +		device_type = "memory";
> > +		/* 4GB of DDR memory */
> > +		reg = <0x12 0x0 0x1 0x0>;
> > +	};
> > +
> > +};
> 
> These all look the same, why do we need 4 copies?
Full dts will have VPU slice specific dts nodes. Since minimum dts for 2 VPU slices are same, I will submit common single dts for 2 VPU slice boards in next version.

> 
> > diff --git a/arch/arm64/boot/dts/intel/hddl_hybrid_4s.dts
> > b/arch/arm64/boot/dts/intel/hddl_hybrid_4s.dts
> > new file mode 100644
> > index 0000000..561ecea
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/intel/hddl_hybrid_4s.dts
> > @@ -0,0 +1,54 @@
> > +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
> > +/*
> > + * Copyright (c) 2021 Intel Corporation.
> > + *
> > + * Device tree describing Intel Thunder Bay Hybrid HDDL Full
> > +configuration
> > + * board
> > + *
> > + * DDR 8GB + 8GB + 4GB + 4GB with four vpu slices  */
> > +
> > +/dts-v1/;
> > +
> > +#include "thunderbay-soc.dtsi"
> > +
> > +/ {
> > +	model = "Intel Thunder Bay Hybrid HDDL Full Board";
> > +	compatible = "intel,thunderbay";
> > +
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> > +
> > +	aliases {
> > +		serial0 = &uart0;
> > +		serial1 = &uart1;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	memory at 100A000000 {
> > +		device_type = "memory";
> > +		/* 8GB of DDR memory */
> > +		reg = <0x10 0x0A000000 0x2 0x0>;
> > +	};
> > +
> > +	memory at 1200000000 {
> > +		device_type = "memory";
> > +		/* 8GB of DDR memory */
> > +		reg = <0x12 0x0 0x2 0x0>;
> > +	};
> > +
> > +	memory at 1400000000 {
> > +		device_type = "memory";
> > +		/* 4GB of DDR memory */
> > +		reg = <0x14 0x0 0x1 0x0>;
> > +	};
> > +
> > +	memory at 1500000000 {
> > +		device_type = "memory";
> > +		/* 4GB of DDR memory */
> > +		reg = <0x15 0x0 0x1 0x0>;
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/intel/thunderbay-soc.dtsi
> > b/arch/arm64/boot/dts/intel/thunderbay-soc.dtsi
> > new file mode 100644
> > index 0000000..834200d
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/intel/thunderbay-soc.dtsi
> > @@ -0,0 +1,243 @@
> > +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
> > +/*
> > + * Copyright (c) 2021 Intel Corporation.
> > + *
> > + * Device tree describing Thunder Bay SoC  */
> > +
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +
> > +/ {
> > +
> > +	compatible = "intel,thunderbay";
> > +	#address-cells = <2>;
> > +	#size-cells = <2>;
> > +	interrupt-parent = <&gic>;
> > +
> > +	cpus {
> > +		#address-cells = <2>;
> > +		#size-cells = <0>;
> > +
> > +		cpu-map {
> > +			cluster0 {
> > +				core0 {
> > +					cpu = <&CPU0>;
> > +				};
> > +				core1 {
> > +					cpu = <&CPU1>;
> > +				};
> > +				core2 {
> > +					cpu = <&CPU2>;
> > +				};
> > +				core3 {
> > +					cpu = <&CPU3>;
> > +				};
> > +			};
> > +			cluster1 {
> > +				core0 {
> > +					cpu = <&CPU4>;
> > +				};
> > +				core1 {
> > +					cpu = <&CPU5>;
> > +				};
> > +				core2 {
> > +					cpu = <&CPU6>;
> > +				};
> > +				core3 {
> > +					cpu = <&CPU7>;
> > +				};
> > +			};
> > +			cluster2 {
> > +				core0 {
> > +					cpu = <&CPU8>;
> > +				};
> > +				core1 {
> > +					cpu = <&CPU9>;
> > +				};
> > +				core2 {
> > +					cpu = <&CPU10>;
> > +				};
> > +				core3 {
> > +					cpu = <&CPU11>;
> > +				};
> > +			};
> > +			cluster3 {
> > +				core0 {
> > +					cpu = <&CPU12>;
> > +				};
> > +				core1 {
> > +					cpu = <&CPU13>;
> > +				};
> > +				core2 {
> > +					cpu = <&CPU14>;
> > +				};
> > +				core3 {
> > +					cpu = <&CPU15>;
> > +				};
> > +			};
> > +		};
> > +
> > +		CPU0: cpu at 0 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x0>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU1: cpu at 1 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x1>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU2: cpu at 2 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x2>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU3: cpu at 3 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x3>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU4: cpu at 100 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x100>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU5: cpu at 101 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x101>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU6: cpu at 102 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x102>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU7: cpu at 103 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x103>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU8: cpu at 200 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x200>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU9: cpu at 201 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x201>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU10: cpu at 202 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x202>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU11: cpu at 203 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x203>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU12: cpu at 300 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x300>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU13: cpu at 301 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x301>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU14: cpu at 302 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x302>;
> > +			enable-method = "psci";
> > +		};
> > +
> > +		CPU15: cpu at 303 {
> > +			compatible = "arm,cortex-a53";
> > +			device_type = "cpu";
> > +			reg = <0x0 0x303>;
> > +			enable-method = "psci";
> > +		};
> > +	};
> > +
> > +	psci {
> > +		compatible = "arm,psci-0.2";
> 
> PSCI 1.0 has been out for 6 years...
I will update this after verifying our ATF supported PSCI version
 
> 
> > +		method = "smc";
> > +	};
> > +
> > +	gic: interrupt-controller at 88400000 {
> > +		compatible = "arm,gic-v3";
> > +		interrupt-controller;
> > +		#interrupt-cells = <3>;
> > +		reg = <0x0 0x88400000 0x0 0x200000>,	/* GICD */
> > +		      <0x0 0x88600000 0x0 0x200000>;	/* GICR */
> > +		/* VGIC maintenance interrupt */
> > +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > +	};
> > +
> > +	timer {
> > +		compatible = "arm,armv8-timer";
> > +		/* Secure, non-secure, virtual, and hypervisor */
> > +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>,
> > +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>,
> > +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>,
> > +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>;
> > +	};
> > +
> > +	soc {
> > +		compatible = "simple-bus";
> > +		#address-cells = <2>;
> > +		#size-cells = <2>;
> > +		ranges;
> > +		dma-ranges;
> > +
> > +		uart0: serial at 80460000 {
> > +			compatible = "snps,dw-apb-uart";
> > +			reg = <0x0 0x80460000 0x0 0x100>;
> > +			interrupts = <GIC_SPI 725 IRQ_TYPE_LEVEL_HIGH>;
> > +			clock-frequency = <50000000>;
> > +			reg-shift = <2>;
> > +			reg-io-width = <4>;
> > +		};
> > +
> > +		uart1: serial at 80470000 {
> > +			compatible = "snps,dw-apb-uart";
> > +			reg = <0x0 0x80470000 0x0 0x100>;
> > +			interrupts = <GIC_SPI 724 IRQ_TYPE_LEVEL_HIGH>;
> > +			clock-frequency = <50000000>;
> > +			reg-shift = <2>;
> > +			reg-io-width = <4>;
> > +			status = "disabled";
> > +		};
> > +	};
> > +};
> > --
> > 2.7.4
> >
> >


From michal.simek at xilinx.com  Fri Aug 27 01:00:59 2021
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri, 27 Aug 2021 10:00:59 +0200
Subject: [PATCH v2 0/4] soc: xilinx: pm_domains: cleanup and fix
 PM_INIT_FINALIZE
In-Reply-To: <20210825150313.4033156-1-m.tretter@pengutronix.de>
References: <20210825150313.4033156-1-m.tretter@pengutronix.de>
Message-ID: <36fee5a7-6c6e-9f93-0ab9-a96967b70919@xilinx.com>

Hi,

On 8/25/21 5:03 PM, Michael Tretter wrote:
> Hi,
> 
> This is v2 of the series to cleanup and fix the zynqmp_pm_domains driver [0].
> 
> Patch 1 of this series fixes the ZynqMP PMU FW power management
> initialization, which was done by the wrong driver. PM_INIT_FINALIZE must be
> called from the zynqmp_pm_domains driver, which handles power domains, instead
> of the zynmp_power driver, which is responsible for suspend and shutdown. As a
> side effect, PM_INIT_FINALIZE powers down all devices that have not been
> requested, which might lead to misbehaving devices. Calling it from the
> sync_state callback ensures that all consumers have probed and are able to
> handle power management themselves.
> 
> Patches 2 to 4 are various cleanup patches to improve the readability and
> debugging experience of the zynqmp_pm_domains driver.
> 
> Michael
> 
> [0] https://lore.kernel.org/linux-arm-kernel/20210317160410.2097178-1-m.tretter at pengutronix.de/
> 
> Changelog:
> 
> v2:
> 
> - move PM_INIT_FINALIZE to sync_state callback
> 
> Michael Tretter (4):
>   soc: xilinx: move PM_INIT_FINALIZE to zynqmp_pm_domains driver
>   soc: xilinx: cleanup debug and error messages
>   soc: xilinx: use a properly named field instead of flags
>   soc: xilinx: add a to_zynqmp_pm_domain macro
> 
>  drivers/soc/xilinx/zynqmp_pm_domains.c | 91 +++++++++++++++-----------
>  drivers/soc/xilinx/zynqmp_power.c      |  1 -
>  2 files changed, 51 insertions(+), 41 deletions(-)
> 

Rajan: Please test and ack.

It looks good to me.
Acked-by: Michal Simek <michal.simek at xilinx.com>

Thanks,
Michal


From like.xu.linux at gmail.com  Fri Aug 27 01:01:45 2021
From: like.xu.linux at gmail.com (Like Xu)
Date: Fri, 27 Aug 2021 16:01:45 +0800
Subject: [PATCH 00/15] perf: KVM: Fix, optimize, and clean up callbacks
In-Reply-To: <YSiX9OPcrDsr3P4C@hirez.programming.kicks-ass.net>
References: <20210827005718.585190-1-seanjc@google.com>
 <fd3dcd6c-b3d5-4453-93fb-b46d0595534e@gmail.com>
 <YSiX9OPcrDsr3P4C@hirez.programming.kicks-ass.net>
Message-ID: <3bd4955a-1219-20b0-058b-d23f1e30aa77@gmail.com>

On 27/8/2021 3:44 pm, Peter Zijlstra wrote:
> On Fri, Aug 27, 2021 at 02:52:25PM +0800, Like Xu wrote:
>> + STATIC BRANCH/CALL friends.
>>
>> On 27/8/2021 8:57 am, Sean Christopherson wrote:
>>> This started out as a small series[1] to fix a KVM bug related to Intel PT
>>> interrupt handling and snowballed horribly.
>>>
>>> The main problem being addressed is that the perf_guest_cbs are shared by
>>> all CPUs, can be nullified by KVM during module unload, and are not
>>> protected against concurrent access from NMI context.
>>
>> Shouldn't this be a generic issue of the static_call() usage ?
>>
>> At the beginning, we set up the static entry assuming perf_guest_cbs != NULL:
>>
>> 	if (perf_guest_cbs && perf_guest_cbs->handle_intel_pt_intr) {
>> 		static_call_update(x86_guest_handle_intel_pt_intr,
>> 				   perf_guest_cbs->handle_intel_pt_intr);
>> 	}
>>
>> and then we unset the perf_guest_cbs and do the static function call like this:
>>
>> DECLARE_STATIC_CALL(x86_guest_handle_intel_pt_intr,
>> *(perf_guest_cbs->handle_intel_pt_intr));
>> static int handle_pmi_common(struct pt_regs *regs, u64 status)
>> {
>> 		...
>> 		if (!static_call(x86_guest_handle_intel_pt_intr)())
>> 			intel_pt_interrupt();
>> 		...
>> }
> 
> You just have to make sure all static_call() invocations that started
> before unreg are finished before continuing with the unload.
> synchronize_rcu() can help with that.

Do you mean something like that:

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 64e310ff4f3a..e7d310af7509 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8465,6 +8465,7 @@ void kvm_arch_exit(void)
  #endif
  	kvm_lapic_exit();
  	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+	synchronize_rcu();

  	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
  		cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index e466fc8176e1..63ae56c5d133 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6508,6 +6508,7 @@ EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
  int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
  {
  	perf_guest_cbs = NULL;
+	arch_perf_update_guest_cbs();
  	return 0;
  }
  EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);

> 
> This is module unload 101. Nothing specific to static_call().
> 


From wangkefeng.wang at huawei.com  Fri Aug 27 01:36:28 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Fri, 27 Aug 2021 16:36:28 +0800
Subject: [PATCH v3 1/3] vmalloc: Choose a better start address in
 vm_area_register_early()
In-Reply-To: <20210825175953.GI3420@arm.com>
References: <20210809093750.131091-1-wangkefeng.wang@huawei.com>
 <20210809093750.131091-2-wangkefeng.wang@huawei.com>
 <20210825175953.GI3420@arm.com>
Message-ID: <587a3a75-bbee-2ae4-8e69-563b9f277306@huawei.com>


On 2021/8/26 1:59, Catalin Marinas wrote:
> On Mon, Aug 09, 2021 at 05:37:48PM +0800, Kefeng Wang wrote:
>> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
>> index d5cd52805149..1e8fe08725b8 100644
>> --- a/mm/vmalloc.c
>> +++ b/mm/vmalloc.c
>> @@ -2238,11 +2238,17 @@ void __init vm_area_add_early(struct vm_struct *vm)
>>    */
>>   void __init vm_area_register_early(struct vm_struct *vm, size_t align)
>>   {
>> -	static size_t vm_init_off __initdata;
>> -	unsigned long addr;
>> -
>> -	addr = ALIGN(VMALLOC_START + vm_init_off, align);
>> -	vm_init_off = PFN_ALIGN(addr + vm->size) - VMALLOC_START;
>> +	struct vm_struct *head = vmlist, *curr, *next;
>> +	unsigned long addr = ALIGN(VMALLOC_START, align);
>> +
>> +	while (head != NULL) {
> Nitpick: I'd use the same pattern as in vm_area_add_early(), i.e. a
> 'for' loop. You might as well insert it directly than calling the add
> function and going through the loop again. Not a strong preference
> either way.
>
>> +		next = head->next;
>> +		curr = head;
>> +		head = next;
>> +		addr = ALIGN((unsigned long)curr->addr + curr->size, align);
>> +		if (next && (unsigned long)next->addr - addr > vm->size)
> Is greater or equal sufficient?
>
>> +			break;
>> +	}
>>   
>>   	vm->addr = (void *)addr;
> Another nitpick: it's very unlikely on a 64-bit architecture but not
> impossible on 32-bit to hit VMALLOC_END here. Maybe some BUG_ON.

Hi Catalin, thank for your review, I will update in the next version,

Could you take a look the following change, is it OK?

void __init vm_area_register_early(struct vm_struct *vm, size_t align)

{

 ???????? struct vm_struct *next, *cur, **p;
 ???????? unsigned long addr = ALIGN(VMALLOC_START, align);
BUG_ON(vmap_initialized);

 ???????? for (p = &vmlist; (cur = *p) != NULL, next = cur->next; p = 
&next) {
 ???????????????? addr = ALIGN((unsigned long)cur->addr + cur->size, 
align);
 ???????????????? if (next && (unsigned long)next->addr - addr >= 
vm->size) {
 ???????????????????????? p = &next;
break;
}
}

 ???????? BUG_ON(addr > VMALLOC_END - vm->size);
 ???????? vm->addr = (void *)addr;
 ???????? vm->next = *p;
 ???????? *p = vm;
}


>


From chiawei_wang at aspeedtech.com  Fri Aug 27 01:49:13 2021
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Fri, 27 Aug 2021 08:49:13 +0000
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <3f2feea6c2fb21c2fdcb419cdc7ceddf3ade06ee.camel@codeconstruct.com.au>
References: <20210826061623.6352-1-chiawei_wang@aspeedtech.com>
 <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
 <7e7378c49ecfb21fef6a0640f92c1b3a7a5878d0.camel@codeconstruct.com.au>
 <HK0PR06MB377997422D9508894936E39691C89@HK0PR06MB3779.apcprd06.prod.outlook.com>
 <3f2feea6c2fb21c2fdcb419cdc7ceddf3ade06ee.camel@codeconstruct.com.au>
Message-ID: <HK0PR06MB3779859F4193D2F34759AFEC91C89@HK0PR06MB3779.apcprd06.prod.outlook.com>

Hi Jeremy

> From: Jeremy Kerr <jk at codeconstruct.com.au>
> Sent: Friday, August 27, 2021 12:37 PM
> 
> Hi Chiawei,
> 
> > The eSPI slave device comprises four channels, where each of them has
> > individual functionality.  Putting the four channels driver code into
> > a single file makes it hard to maintain and trace.
> 
> Yep, understood.
> 
> > We did consider to make them standard .c files.
> > But it requires to export channel functions into kernel space although
> > they are dedicated only to this eSPI driver.
> 
> What do you mean by "export into kernel space" here? The function prototypes

The channel functions will be visible to all kernel driver files.

> need to be available to your main (-ctrl.c) file, regardless of whether you're
> putting the entire functions in a header file, or just the prototype. There's
> doesn't need to be any difference in visibility outside of your own module if
> you were to do this the usual way.

Maybe I was trying to make channels function visible only to espi-ctrl.c too far.
I will revise the driver to present in the usual .c way.

> 
> > As espi-ctrl needs to invoke corresponding channel functions when it
> > is interrupted by eSPI events.
> >
> > To avoid polluting kernel space, we decided to put driver code in
> > header files and make the channel functions 'static'.
> >
> > BTW, I once encountered .c file inclusion in other projects. Is it
> > proper for Linux driver development?
> 
> It can be, just that in this case it's a bit unusual, and I can't see a good reason
> for doing so. This could just be a standard multiple-source-file module.
> 
> > eSPI communication is based on the its cycle packet format.
> > We intended to let userspace decided how to interpret and compose
> > TX/RX packets including header, tag, length (encoded), and data.
> > IOCTL comes to our first mind as it also works in the 'packet' like
> > paradigm.
> 
> But you're not always exposing a packet-like interface for this. For example,
> your virtual-wire interface just has a get/set interface for bits in a register
> (plus some PCH event handling, which may not be applicable to all
> platforms...).
> 
> The other channels do look like more of a packet interface though, but in that
> case I'm not convinced that an ioctl interface is the best way to go for that.
> You're essentially sending a (length, pointer) pair over the ioctls there, which
> sounds more like a write() than an ioctl().

In most cases, yes. 
Currently only the peripheral channel has more than the 2 (put tx/get rx) IOCTL code.
We think it might be a good idea to make the user interfaces of all channels consistent using IOCTL.

> 
> Regardless of the choice of interface though, this will definitely need some
> documentation or description of the API, and the ioc header to be somewhere
> useful for userspace to consume.
> 
> With that documented, we'd have a better idea of how the new ABI is
> supposed to work.

Sure. more comments will be added in aspeed-espi-ioc.h to describe the usage and the purpose.

Thanks for your feedback.

Chiawei


From chiawei_wang at aspeedtech.com  Fri Aug 27 01:49:16 2021
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Fri, 27 Aug 2021 08:49:16 +0000
Subject: [PATCH v3 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <CACPK8Xf1g2fp5X3ELBUyjzP6Fmvt1XWLU_UgCKdZaDVjdyKryQ@mail.gmail.com>
References: <20210826061623.6352-4-chiawei_wang@aspeedtech.com>
 <202108270732.OvBQ4K3D-lkp@intel.com>
 <HK0PR06MB377927BDCA9CC79B598251B291C89@HK0PR06MB3779.apcprd06.prod.outlook.com>
 <CACPK8Xf1g2fp5X3ELBUyjzP6Fmvt1XWLU_UgCKdZaDVjdyKryQ@mail.gmail.com>
Message-ID: <HK0PR06MB3779B6CD28A84D3DC651211191C89@HK0PR06MB3779.apcprd06.prod.outlook.com>

> From: Joel Stanley <joel at jms.id.au>
> Sent: Friday, August 27, 2021 1:49 PM
> 
> On Fri, 27 Aug 2021 at 03:52, ChiaWei Wang
> <chiawei_wang at aspeedtech.com> wrote:
> >
> > Aspeed 5th and 6th generation SoCs are based on the ARM 32-bits
> architecture.
> > Should we follow the report to make the driver 64-bits compatible?
> > Or revise the driver to use more specific data types?
> 
> Yes, in general it's expected your driver will compile cleanly for 64-bit
> architectures. This helps with testing and static analysis, where CI builds all the
> drivers for x86.

Understood. Will fix the data type issue in the next submission.
Thanks.

Chiawei

From zhaoxiao at uniontech.com  Fri Aug 27 01:55:50 2021
From: zhaoxiao at uniontech.com (zhaoxiao)
Date: Fri, 27 Aug 2021 16:55:50 +0800
Subject: [PATCH] stmmac: dwmac-loongson: change the pr_info() to dev_err() in
 loongson_dwmac_probe()
Message-ID: <20210827085550.13519-1-zhaoxiao@uniontech.com>

- Change the pr_info/dev_info to dev_err.
- Add the dev_err to improve readability.

Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-loongson.c  | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
index 4c9a37dd0d3f..495c94e7929f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
@@ -54,20 +54,21 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 	bool mdio = false;
 
 	np = dev_of_node(&pdev->dev);
-
 	if (!np) {
-		pr_info("dwmac_loongson_pci: No OF node\n");
+		dev_err(&pdev->dev, "dwmac_loongson_pci: No OF node\n");
 		return -ENODEV;
 	}
 
 	if (!of_device_is_compatible(np, "loongson, pci-gmac")) {
-		pr_info("dwmac_loongson_pci: Incompatible OF node\n");
+		dev_err(&pdev->dev, "dwmac_loongson_pci: Incompatible OF node\n");
 		return -ENODEV;
 	}
 
 	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
-	if (!plat)
+	if (!plat) {
+		dev_err(&pdev->dev, "memory allocation failed\n");
 		return -ENOMEM;
+	}
 
 	if (plat->mdio_node) {
 		dev_err(&pdev->dev, "Found MDIO subnode\n");
@@ -109,8 +110,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 		plat->bus_id = pci_dev_id(pdev);
 
 	phy_mode = device_get_phy_mode(&pdev->dev);
-	if (phy_mode < 0)
+	if (phy_mode < 0) {
 		dev_err(&pdev->dev, "phy_mode not found\n");
+		return phy_mode;
+	}
 
 	plat->phy_interface = phy_mode;
 	plat->interface = PHY_INTERFACE_MODE_GMII;
@@ -130,7 +133,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 
 	res.wol_irq = of_irq_get_byname(np, "eth_wake_irq");
 	if (res.wol_irq < 0) {
-		dev_info(&pdev->dev, "IRQ eth_wake_irq not found, using macirq\n");
+		dev_err(&pdev->dev, "IRQ eth_wake_irq not found, using macirq\n");
 		res.wol_irq = res.irq;
 	}
 
-- 
2.20.1





From ikjn at chromium.org  Fri Aug 27 02:14:17 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Fri, 27 Aug 2021 17:14:17 +0800
Subject: [PATCH next v2 3/6] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <72ee7a203d8a49e6e43a954b45133470ee6d5c16.camel@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
 <20210826025144.51992-3-chunfeng.yun@mediatek.com>
 <CAATdQgBD+dTtBie-cNKRJbfxEpc3haqjfUu1k26mTk8pCSOEww@mail.gmail.com>
 <72ee7a203d8a49e6e43a954b45133470ee6d5c16.camel@mediatek.com>
Message-ID: <CAATdQgA+4VC7J1LMZYOZMV-OTjMGjO=9bJZ7uaCu_MMF-20T1w@mail.gmail.com>

On Fri, Aug 27, 2021 at 2:49 PM Chunfeng Yun (???)
<Chunfeng.Yun at mediatek.com> wrote:
>
> On Thu, 2021-08-26 at 19:54 +0800, Ikjoon Jang wrote:
> > Hi Chunfeng,
> >
> > On Thu, Aug 26, 2021 at 10:52 AM Chunfeng Yun <
> > chunfeng.yun at mediatek.com> wrote:
> > >
> > > Use @bw_budget_table[] to update fs bus bandwidth due to
> > > not all microframes consume @bw_cost_per_microframe, see
> > > setup_sch_info().
> > >
> > > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > > ---
> > > v2: new patch, move from another series
> > > ---
> > >  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
> > >  1 file changed, 7 insertions(+), 10 deletions(-)
> > >
> > > diff --git a/drivers/usb/host/xhci-mtk-sch.c
> > > b/drivers/usb/host/xhci-mtk-sch.c
> > > index cffcaf4dfa9f..83abd28269ca 100644
> > > --- a/drivers/usb/host/xhci-mtk-sch.c
> > > +++ b/drivers/usb/host/xhci-mtk-sch.c
> > > @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct
> > > mu3h_sch_ep_info *sch_ep, int offset)
> > >                  * Compared with hs bus, no matter what ep type,
> > >                  * the hub will always delay one uframe to send
> > > data
> > >                  */
> > > -               for (j = 0; j < sch_ep->cs_count; j++) {
> > > -                       tmp = tt->fs_bus_bw[base + j] + sch_ep-
> > > >bw_cost_per_microframe;
> > > +               for (j = 0; j < sch_ep->num_budget_microframes;
> > > j++) {
> > > +                       tmp = tt->fs_bus_bw[base + j] + sch_ep-
> > > >bw_budget_table[j];
> >
> > I'm worrying about this case with two endpoints,
> > * EP1OUT: isochronous, maxpacket=192: bw_budget_table[] = { 188, 188,
> > 0, ... }
> > * EP2IN: interrupt, maxpacket=64: bw_budget_table[] = { 0, 0, 64, 64,
> > ... }
> > (Is this correct bw_budget_table contents for those eps?)
> Yes, ep1out isoc use two uframe, ep2in intr use a extra cs;
> >
> > I'm not sure if it's okay for those two endpoints to be allocated
> > on the same u-frame slot.
> > Can you please check if this is okay for xhci-mtk?
> Already test it this afternoon, can transfer data rightly on our dvt
> env.
>
> > (I feel like I already asked the same questions many times.)
> Yes, as said before, prefer to use bw_budget_table[], if there is
> issue, we can fix it by building this table.

So do you mean such an allocation shouldn't be a problem by IP design?

This patch starts to allow such an allocation (again).
But i remember my earlier tests showed that when those two eps
in the above example are allocated on the same u-frame slot,
xhci-mtk puts "SSPLIT for EP2" between
"SSPLIT-start and SSPLIT-end for EP1OUT transaction",
which is a spec violation. Hub will generate bit stuffing errors on the
full-speed bus.


>
> Thanks
> >
> >
> > >                         if (tmp > FS_PAYLOAD_MAX)
> > >                                 return -ESCH_BW_OVERFLOW;
> > >                 }
> > > @@ -534,21 +534,18 @@ static void update_sch_tt(struct
> > > mu3h_sch_ep_info *sch_ep, bool used)
> > >  {
> > >         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
> > >         u32 base, num_esit;
> > > -       int bw_updated;
> > >         int i, j;
> > >
> > >         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> > >
> > > -       if (used)
> > > -               bw_updated = sch_ep->bw_cost_per_microframe;
> > > -       else
> > > -               bw_updated = -sch_ep->bw_cost_per_microframe;
> > > -
> > >         for (i = 0; i < num_esit; i++) {
> > >                 base = sch_ep->offset + i * sch_ep->esit;
> > >
> > > -               for (j = 0; j < sch_ep->cs_count; j++)
> > > -                       tt->fs_bus_bw[base + j] += bw_updated;
> > > +               for (j = 0; j < sch_ep->num_budget_microframes;
> > > j++)
> > > +                       if (used)
> > > +                               tt->fs_bus_bw[base + j] += sch_ep-
> > > >bw_budget_table[j];
> > > +                       else
> > > +                               tt->fs_bus_bw[base + j] -= sch_ep-
> > > >bw_budget_table[j];
> > >         }
> > >
> > >         if (used)
> > > --
> > > 2.18.0
> > >


From chenwandun at huawei.com  Fri Aug 27 02:22:46 2021
From: chenwandun at huawei.com (Chen Wandun)
Date: Fri, 27 Aug 2021 17:22:46 +0800
Subject: [PATCH] arm64: kdump: Skip kmemleak scan reserved memory for kdump
Message-ID: <20210827092246.3565437-1-chenwandun@huawei.com>

Trying to boot with kdump + kmemleak, command will result in a crash:
"echo scan > /sys/kernel/debug/kmemleak"

crashkernel reserved: 0x0000000007c00000 - 0x0000000027c00000 (512 MB)
Kernel command line: BOOT_IMAGE=(hd1,gpt2)/vmlinuz-5.14.0-rc5-next-20210809+ root=/dev/mapper/ao-root ro rd.lvm.lv=ao/root rd.lvm.lv=ao/swap crashkernel=512M
Unable to handle kernel paging request at virtual address ffff000007c00000
Mem abort info:
  ESR = 0x96000007
  EC = 0x25: DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
  FSC = 0x07: level 3 translation fault
Data abort info:
  ISV = 0, ISS = 0x00000007
  CM = 0, WnR = 0
swapper pgtable: 64k pages, 48-bit VAs, pgdp=00002024f0d80000
[ffff000007c00000] pgd=1800205ffffd0003, p4d=1800205ffffd0003, pud=1800205ffffd0003, pmd=1800205ffffc0003, pte=0068000007c00f06
Internal error: Oops: 96000007 [#1] SMP
pstate: 804000c9 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : scan_block+0x98/0x230
lr : scan_block+0x94/0x230
sp : ffff80008d6cfb70
x29: ffff80008d6cfb70 x28: 0000000000000000 x27: 0000000000000000
x26: 00000000000000c0 x25: 0000000000000001 x24: 0000000000000000
x23: ffffa88a6b18b398 x22: ffff000007c00ff9 x21: ffffa88a6ac7fc40
x20: ffffa88a6af6a830 x19: ffff000007c00000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000 x15: ffffffffffffffff
x14: ffffffff00000000 x13: ffffffffffffffff x12: 0000000000000020
x11: 0000000000000000 x10: 0000000001080000 x9 : ffffa88a6951c77c
x8 : ffffa88a6a893988 x7 : ffff203ff6cfb3c0 x6 : ffffa88a6a52b3c0
x5 : ffff203ff6cfb3c0 x4 : 0000000000000000 x3 : 0000000000000000
x2 : 0000000000000001 x1 : ffff20226cb56a40 x0 : 0000000000000000
Call trace:
 scan_block+0x98/0x230
 scan_gray_list+0x120/0x270
 kmemleak_scan+0x3a0/0x648
 kmemleak_write+0x3ac/0x4c8
 full_proxy_write+0x6c/0xa0
 vfs_write+0xc8/0x2b8
 ksys_write+0x70/0xf8
 __arm64_sys_write+0x24/0x30
 invoke_syscall+0x4c/0x110
 el0_svc_common+0x9c/0x190
 do_el0_svc+0x30/0x98
 el0_svc+0x28/0xd8
 el0t_64_sync_handler+0x90/0xb8
 el0t_64_sync+0x180/0x184

The reserved memory for kdump will be looked up by kmemleak, this area
will be set invalid when kdump service is bring up. That will result in
crash when kmemleak scan this area.

Fixes: 461ef12c4375 ("memblock: make memblock_find_in_range method private")
Signed-off-by: Chen Wandun <chenwandun at huawei.com>
---
 arch/arm64/mm/init.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index b16be52233c6..dc0c44622bfd 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -30,6 +30,7 @@
 #include <linux/crash_dump.h>
 #include <linux/hugetlb.h>
 #include <linux/acpi_iort.h>
+#include <linux/kmemleak.h>
 
 #include <asm/boot.h>
 #include <asm/fixmap.h>
@@ -101,6 +102,7 @@ static void __init reserve_crashkernel(void)
 	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
 
+	kmemleak_ignore_phys(crash_base);
 	crashk_res.start = crash_base;
 	crashk_res.end = crash_base + crash_size - 1;
 }
-- 
2.18.0.huawei.25



From jens.wiklander at linaro.org  Fri Aug 27 02:26:16 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Fri, 27 Aug 2021 11:26:16 +0200
Subject: [PATCH v5 4/6] tee: add tee_dev_open_helper() primitive
In-Reply-To: <CAFA6WYM_zaVsWzP-sDuD6_xf3qgv-sQsbEAebZG6vtFrKfRpag@mail.gmail.com>
References: <20210826123032.1732926-1-jens.wiklander@linaro.org>
 <20210826123032.1732926-5-jens.wiklander@linaro.org>
 <CAFA6WYM_zaVsWzP-sDuD6_xf3qgv-sQsbEAebZG6vtFrKfRpag@mail.gmail.com>
Message-ID: <CAHUa44FWM-QRfeEb5rreN4J9yJjQJQrh3XEm-YLBQmZMvBLC0g@mail.gmail.com>

On Fri, Aug 27, 2021 at 8:23 AM Sumit Garg <sumit.garg at linaro.org> wrote:
>
> On Thu, 26 Aug 2021 at 18:00, Jens Wiklander <jens.wiklander at linaro.org> wrote:
> >
> > Adds tee_dev_open_helper() and tee_dev_ctx_put() to make it easier to
> > create a driver internal struct tee_context without the usual
> > tee_device_get() on the struct tee_device as that adds a circular
> > reference counter dependency and would prevent the struct tee_device
> > from ever being released again.
>
> Can you elaborate regarding the circular dependency issue you are
> referring to? IIUC, lifespan for struct tee_device would look like
> below with normal teedev_open():
>
> optee_probe() {
>   ...
>   tee_device_alloc()            <- teedev->num_users = 1
>   tee_device_register()
>   optee_notif_init()               <- tee_device_get()
>   ...
> }
>
> optee_remove() {
>   ...
>   optee_notif_uninit()           <- tee_device_put()
>   tee_device_unregister()    <- tee_device_put()
>   ...
> }

You're right, it works just as well without this patch.
teedev_close_context() and teedev_open() must be exported in another
patch though. I'll replace this patch with such a patch in the next
patch set.


Thanks,
Jens

>
> -Sumit
>
> >
> > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
> > ---
> >  drivers/tee/tee_core.c  | 33 ++++++++++++++++++++++++---------
> >  include/linux/tee_drv.h | 27 +++++++++++++++++++++++++++
> >  2 files changed, 51 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
> > index 85102d12d716..3beb682684a8 100644
> > --- a/drivers/tee/tee_core.c
> > +++ b/drivers/tee/tee_core.c
> > @@ -43,14 +43,11 @@ static DEFINE_SPINLOCK(driver_lock);
> >  static struct class *tee_class;
> >  static dev_t tee_devt;
> >
> > -static struct tee_context *teedev_open(struct tee_device *teedev)
> > +struct tee_context *tee_dev_open_helper(struct tee_device *teedev)
> >  {
> >         int rc;
> >         struct tee_context *ctx;
> >
> > -       if (!tee_device_get(teedev))
> > -               return ERR_PTR(-EINVAL);
> > -
> >         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
> >         if (!ctx) {
> >                 rc = -ENOMEM;
> > @@ -66,10 +63,30 @@ static struct tee_context *teedev_open(struct tee_device *teedev)
> >         return ctx;
> >  err:
> >         kfree(ctx);
> > -       tee_device_put(teedev);
> >         return ERR_PTR(rc);
> >
> >  }
> > +EXPORT_SYMBOL_GPL(tee_dev_open_helper);
> > +
> > +void tee_dev_ctx_put(struct tee_context *ctx)
> > +{
> > +       teedev_ctx_put(ctx);
> > +}
> > +EXPORT_SYMBOL_GPL(tee_dev_ctx_put);
> > +
> > +static struct tee_context *teedev_open(struct tee_device *teedev)
> > +{
> > +       struct tee_context *ctx;
> > +
> > +       if (!tee_device_get(teedev))
> > +               return ERR_PTR(-EINVAL);
> > +
> > +       ctx = tee_dev_open_helper(teedev);
> > +       if (IS_ERR(ctx))
> > +               tee_device_put(teedev);
> > +
> > +       return ctx;
> > +}
> >
> >  void teedev_ctx_get(struct tee_context *ctx)
> >  {
> > @@ -90,10 +107,8 @@ static void teedev_ctx_release(struct kref *ref)
> >
> >  void teedev_ctx_put(struct tee_context *ctx)
> >  {
> > -       if (ctx->releasing)
> > -               return;
> > -
> > -       kref_put(&ctx->refcount, teedev_ctx_release);
> > +       if (ctx && !ctx->releasing)
> > +               kref_put(&ctx->refcount, teedev_ctx_release);
> >  }
> >
> >  static void teedev_close_context(struct tee_context *ctx)
> > diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
> > index 3ebfea0781f1..00a31ff03049 100644
> > --- a/include/linux/tee_drv.h
> > +++ b/include/linux/tee_drv.h
> > @@ -458,6 +458,33 @@ static inline int tee_shm_get_id(struct tee_shm *shm)
> >   */
> >  struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
> >
> > +/**
> > + * tee_dev_open_helper() - helper function to make a struct tee_context
> > + * @teedev:    Device to open
> > + *
> > + * Creates the struct tee_context without increasing the reference counter
> > + * on @teedev. This is needed for instance when a driver need an internal
> > + * struct tee_context to operate on. By skipping the reference counter
> > + * the circular dependency is broken.
> > + *
> > + * Note that this struct tee_context need special care when freeing in
> > + * order to avoid the normal put on the struct tee_device.
> > + * tee_dev_ctx_put() is the best choice for this.
> > + *
> > + * @returns a pointer 'struct tee_context' on success or an ERR_PTR on failure
> > + */
> > +struct tee_context *tee_dev_open_helper(struct tee_device *teedev);
> > +
> > +/**
> > + * tee_dev_ctx_put() - helper function to release a struct tee_context
> > + * @ctx:       The struct tee_context to release
> > + *
> > + * Note that this function doesn't do a tee_device_put() on the internal
> > + * struct tee_device so this function should normal only be used when
> > + * releasing a struct tee_context obtained with tee_dev_open_helper().
> > + */
> > +void tee_dev_ctx_put(struct tee_context *ctx);
> > +
> >  /**
> >   * tee_client_open_context() - Open a TEE context
> >   * @start:     if not NULL, continue search after this context
> > --
> > 2.31.1
> >


From kavyasree.kotagiri at microchip.com  Fri Aug 27 02:26:23 2021
From: kavyasree.kotagiri at microchip.com (kavyasree.kotagiri at microchip.com)
Date: Fri, 27 Aug 2021 14:56:23 +0530
Subject: [PATCH] ARM: at91: add basic support for new SoC lan966x
Message-ID: <20210827092623.10677-1-kavyasree.kotagiri@microchip.com>

From: Kavyasree Kotagiri <Kavyasree.Kotagiri at microchip.com>

This patch introduces Microchip LAN966X ARMv7 based SoC family
of multiport gigabit AVB/TSN-capable ethernet switches.
It supports two SKUs: 4-port LAN9662 with multiprotocol
processing support and 8-port LAN9668 switch.

LAN966X includes copper and serial ethernet interfaces,
peripheral interfaces such as PCIe, USB, TWI, SPI, UART, QSPI,
SD/eMMC, Parallel Interface (PI) as well as synchronization
and trigger inputs/outputs.

Signed-off-by: Kavya Sree Kotagiri <kavyasree.kotagiri at microchip.com>
---
 arch/arm/mach-at91/Kconfig   | 13 +++++++++++++
 arch/arm/mach-at91/Makefile  |  1 +
 arch/arm/mach-at91/lan966x.c | 31 +++++++++++++++++++++++++++++++
 3 files changed, 45 insertions(+)
 create mode 100644 arch/arm/mach-at91/lan966x.c

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index ccd7e80ce943..06cb425af761 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -122,6 +122,14 @@ config SOC_SAM9X60
 	help
 	  Select this if you are using Microchip's SAM9X60 SoC

+config SOC_LAN966X
+	bool "ARMv7 based Microchip LAN966X SoC family"
+	depends on ARCH_MULTI_V7
+	select SOC_LAN966
+	select DW_APB_TIMER_OF
+	help
+	  This enables support for ARMv7 based Microchip LAN966X SoC family.
+
 comment "Clocksource driver selection"

 config ATMEL_CLOCKSOURCE_PIT
@@ -188,6 +196,11 @@ config SOC_SAMA5
 	select SOC_SAM_V7
 	select SRAM if PM

+config SOC_LAN966
+	bool
+	select ARM_GIC
+	select MEMORY
+
 config ATMEL_PM
 	bool

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index f565490f1b70..93cfd5b4e6d4 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -6,6 +6,7 @@
 # CPU-specific support
 obj-$(CONFIG_SOC_AT91RM9200)	+= at91rm9200.o
 obj-$(CONFIG_SOC_AT91SAM9)	+= at91sam9.o
+obj-$(CONFIG_SOC_LAN966X)	+= lan966x.o
 obj-$(CONFIG_SOC_SAM9X60)	+= sam9x60.o
 obj-$(CONFIG_SOC_SAMA5)		+= sama5.o
 obj-$(CONFIG_SOC_SAMV7)		+= samv7.o
diff --git a/arch/arm/mach-at91/lan966x.c b/arch/arm/mach-at91/lan966x.c
new file mode 100644
index 000000000000..de689f854068
--- /dev/null
+++ b/arch/arm/mach-at91/lan966x.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Setup code for LAN966X
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ *
+ */
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/system_misc.h>
+
+#include "generic.h"
+
+static void __init lan966x_dt_device_init(void)
+{
+	of_platform_default_populate(NULL, NULL, NULL);
+}
+
+static const char *const lan966x_dt_board_compat[] __initconst = {
+	"microchip,lan966x",
+	NULL
+};
+
+DT_MACHINE_START(lan966x_dt, "Microchip LAN966X")
+	/* Maintainer: Microchip */
+	.init_machine	= lan966x_dt_device_init,
+	.dt_compat	= lan966x_dt_board_compat,
+MACHINE_END
--
2.17.1



From spujar at nvidia.com  Fri Aug 27 02:33:46 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:46 +0530
Subject: [PATCH 00/13] Extend AHUB audio support for Tegra210 and later
Message-ID: <1630056839-6562-1-git-send-email-spujar@nvidia.com>

Earlier as part of series [0], support for ADMAIF and I/O modules (such
as I2S, DMIC and DSPK) was added. This series aims at exposing some of
the AHUB internal modules (listed below), which can be used for audio
pre or post processing.

  * SFC (Sampling Frequency Converter)
  * MVC (Master Volume Control)
  * AMX (Audio Multiplexer)
  * ADX (Audio Demultiplexer)
  * Mixer

These modules can be plugged into audio paths and relevant processing
can be done. The MUX routes are extended to allow add or remove above
modules in the path via mixer controls. This is similar to how specific
ADMAIF channels are connected to relevant I/O module instances at the
moment.

Some of these modules can alter PCM parameters. Consider example of
resampler (44.1 -> 48 kHz) in the path.

  aplay(44.1 kHz) -> ADMAIF -> SFC -> (48 kHz) I2S -> (48kHz) Codec

The modules following SFC should be using converted sample rate and DAIs
need to be configured accordingly. The audio-graph driver provides a
mechanism to fixup the new parameters which can be specified in DT for a
given DAI. Then core uses these new values via fixup callback and then
pass it to respective DAIs hw_param() callback. The "convert-rate",
described in [1], property can be used when there is rate conversion in
the audio path. Similarly "convert-channels" can be used when there is
channel conversion in the path. There is no "convert-xxx" property for
sample size conversions. It can be added if necessary.

[0] https://www.lkml.org/lkml/2020/7/21/1357
[1] Documentation/devicetree/bindings/sound/audio-graph-port.yaml 

Sameer Pujar (13):
  ASoC: soc-pcm: Don't reconnect an already active BE
  ASoC: simple-card-utils: Increase maximum DAI links limit to 512
  ASoC: audio-graph: Fixup CPU endpoint hw_params in a BE<->BE link
  ASoC: dt-bindings: tegra: Few more Tegra210 AHUB modules
  ASoC: tegra: Add routes for few AHUB modules
  ASoC: tegra: Add Tegra210 based MVC driver
  ASoC: tegra: Add Tegra210 based SFC driver
  ASoC: tegra: Add Tegra210 based AMX driver
  ASoC: tegra: Add Tegra210 based ADX driver
  ASoC: tegra: Add Tegra210 based Mixer driver
  arm64: defconfig: Enable few Tegra210 based AHUB drivers
  arm64: tegra: Add few AHUB devices for Tegra210 and later
  arm64: tegra: Extend APE audio support on Jetson platforms

 .../bindings/sound/nvidia,tegra210-adx.yaml        |   74 +
 .../bindings/sound/nvidia,tegra210-ahub.yaml       |   20 +
 .../bindings/sound/nvidia,tegra210-amx.yaml        |   72 +
 .../bindings/sound/nvidia,tegra210-mixer.yaml      |   67 +
 .../bindings/sound/nvidia,tegra210-mvc.yaml        |   79 +
 .../bindings/sound/nvidia,tegra210-sfc.yaml        |   76 +
 arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts | 1554 ++++++++-
 arch/arm64/boot/dts/nvidia/tegra186.dtsi           |  120 +
 arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts | 1493 ++++++++-
 .../arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi | 1520 ++++++++-
 arch/arm64/boot/dts/nvidia/tegra194.dtsi           |  116 +
 arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts |  876 +++++
 arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts |  876 +++++
 arch/arm64/boot/dts/nvidia/tegra210.dtsi           |   77 +
 arch/arm64/configs/defconfig                       |    5 +
 include/sound/simple_card_utils.h                  |    2 +-
 sound/soc/generic/audio-graph-card.c               |    4 +-
 sound/soc/soc-pcm.c                                |    4 +
 sound/soc/tegra/Kconfig                            |   48 +
 sound/soc/tegra/Makefile                           |   10 +
 sound/soc/tegra/tegra210_adx.c                     |  527 +++
 sound/soc/tegra/tegra210_adx.h                     |   72 +
 sound/soc/tegra/tegra210_ahub.c                    |  511 ++-
 sound/soc/tegra/tegra210_amx.c                     |  595 ++++
 sound/soc/tegra/tegra210_amx.h                     |   93 +
 sound/soc/tegra/tegra210_mixer.c                   |  667 ++++
 sound/soc/tegra/tegra210_mixer.h                   |  100 +
 sound/soc/tegra/tegra210_mvc.c                     |  629 ++++
 sound/soc/tegra/tegra210_mvc.h                     |  117 +
 sound/soc/tegra/tegra210_sfc.c                     | 3542 ++++++++++++++++++++
 sound/soc/tegra/tegra210_sfc.h                     |   78 +
 31 files changed, 13601 insertions(+), 423 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
 create mode 100644 sound/soc/tegra/tegra210_adx.c
 create mode 100644 sound/soc/tegra/tegra210_adx.h
 create mode 100644 sound/soc/tegra/tegra210_amx.c
 create mode 100644 sound/soc/tegra/tegra210_amx.h
 create mode 100644 sound/soc/tegra/tegra210_mixer.c
 create mode 100644 sound/soc/tegra/tegra210_mixer.h
 create mode 100644 sound/soc/tegra/tegra210_mvc.c
 create mode 100644 sound/soc/tegra/tegra210_mvc.h
 create mode 100644 sound/soc/tegra/tegra210_sfc.c
 create mode 100644 sound/soc/tegra/tegra210_sfc.h

-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:47 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:47 +0530
Subject: [PATCH 01/13] ASoC: soc-pcm: Don't reconnect an already active BE
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-2-git-send-email-spujar@nvidia.com>

In some cases, multiple FE components have the same BE component in their
respective DPCM paths. One such example would be a mixer component, which
can receive two or more inputs and sends a mixed output. In such cases,
to avoid reconfiguration of already active DAI (mixer output DAI in this
case), check the BE stream state to filter out the redundancy.

In summary, allow connection of BE if the respective current stream state
is either NEW or CLOSED.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 sound/soc/soc-pcm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 48f71bb..e30cb5a 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1395,6 +1395,10 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
 		if (!fe->dpcm[stream].runtime && !fe->fe_compr)
 			continue;
 
+		if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) &&
+		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
+			continue;
+
 		/* newly connected FE and BE */
 		err = dpcm_be_connect(fe, be, stream);
 		if (err < 0) {
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:48 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:48 +0530
Subject: [PATCH 02/13] ASoC: simple-card-utils: Increase maximum DAI links
 limit to 512
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-3-git-send-email-spujar@nvidia.com>

The current limit of 128 is not sufficient when more components are
added to the audio map on Tegra210 and later platforms. Thus it is
resulting in probe failure.

The requirement is of nearly ~200 DAI links. To give sufficient room
for future additions the maximum limit is increased to 512 DAI links.
This is a preparatory patch to add more components like resampler,
mixer, multiplexers, demultiplexers and volume controllers to Tegra210
and later platforms.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
Cc: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 include/sound/simple_card_utils.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 51b3b48..6b78034 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -115,7 +115,7 @@ struct asoc_simple_priv {
 		     ((codec) = simple_props_to_dai_codec(props, i));	\
 	     (i)++)
 
-#define SNDRV_MAX_LINKS 128
+#define SNDRV_MAX_LINKS 512
 
 struct link_info {
 	int link; /* number of link */
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:49 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:49 +0530
Subject: [PATCH 03/13] ASoC: audio-graph: Fixup CPU endpoint hw_params in a
 BE<->BE link
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-4-git-send-email-spujar@nvidia.com>

When multiple components are connected back to back in an audio path,
hw_param fixup may be required for CPU or Codec endpoint of BE<->BE
DAI links. Currently fixup support is available for Codec and this
commit adds similar feature for CPU endpoint of a BE<->BE link.

For example a resampler component can be plugged into an audio path.
  [ FE -> BE1 -> ... -> resampler -> ... BEn ]

The resampler DAI links can be:
  BEx (CPU)              -> resampler input (Codec)
  resampler output (CPU) -> BEy (Codec)

Thus input and output sample rate parameters for resampler can be
fixed up as per the resample requirement.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
Cc: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
 sound/soc/generic/audio-graph-card.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 5e71382..7439122 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -309,8 +309,10 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
 		 * For example: FE <-> BE1 <-> BE2 <-> ... <-> BEn where
 		 * there are 'n' BE components in the path.
 		 */
-		if (card->component_chaining && !soc_component_is_pcm(cpus))
+		if (card->component_chaining && !soc_component_is_pcm(cpus)) {
 			dai_link->no_pcm = 1;
+			dai_link->be_hw_params_fixup = asoc_simple_be_hw_params_fixup;
+		}
 
 		asoc_simple_canonicalize_cpu(cpus, is_single_links);
 	} else {
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:50 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:50 +0530
Subject: [PATCH 04/13] ASoC: dt-bindings: tegra: Few more Tegra210 AHUB modules
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-5-git-send-email-spujar@nvidia.com>

This patch adds YAML schema for DT bindings of few AHUB modules.
These devices will be registered as ASoC components and bindings
will be used on Tegra210 and later chips. The bindings for below
mentioned modules are added:

 * SFC (Sampling Frequency Converter)
 * MVC (Master Volume Control)
 * AMX (Audio Multiplexer)
 * ADX (Audio Demultiplexer)
 * Mixer

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
Cc: Rob Herring <robh+dt at kernel.org> 
---
 .../bindings/sound/nvidia,tegra210-adx.yaml        | 74 ++++++++++++++++++++
 .../bindings/sound/nvidia,tegra210-ahub.yaml       | 20 ++++++
 .../bindings/sound/nvidia,tegra210-amx.yaml        | 72 ++++++++++++++++++++
 .../bindings/sound/nvidia,tegra210-mixer.yaml      | 67 ++++++++++++++++++
 .../bindings/sound/nvidia,tegra210-mvc.yaml        | 79 ++++++++++++++++++++++
 .../bindings/sound/nvidia,tegra210-sfc.yaml        | 76 +++++++++++++++++++++
 6 files changed, 388 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml

diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
new file mode 100644
index 0000000..9950585
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/nvidia,tegra210-adx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra210 ADX Device Tree Bindings
+
+description: |
+  The Audio Demultiplexer (ADX) block takes an input stream with   up to
+  16 channels and demultiplexes it into four output streams of up to 16
+  channels each. A byte RAM helps to form output frames by any combination
+  of bytes from the input frame. Its design is identical to that of byte
+  RAM in the AMX except that the data flow direction is reversed.
+
+maintainers:
+  - Jon Hunter <jonathanh at nvidia.com>
+  - Mohan Kumar <mkumard at nvidia.com>
+  - Sameer Pujar <spujar at nvidia.com>
+
+properties:
+  $nodename:
+    pattern: "^adx@[0-9a-f]*$"
+
+  compatible:
+    oneOf:
+      - const: nvidia,tegra210-adx
+      - items:
+          - enum:
+              - nvidia,tegra194-adx
+              - nvidia,tegra186-adx
+          - const: nvidia,tegra210-adx
+
+  reg:
+    maxItems: 1
+
+  sound-name-prefix:
+    pattern: "^ADX[1-9]$"
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      used as prefix for sink/source names of the component. Must be a
+      unique string among multiple instances of the same component.
+      The name can be "ADX1" or "ADX2" ... "ADXx", where x depends on
+      the maximum available instances on a Tegra SoC.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    description: |
+      ADX has one input and four output. Accordingly ACIF (Audio Client
+      Interface) RX and TX port nodes are defined to represent ADX inputs
+      and output respectively. These are connected to corresponding ports
+      on AHUB.
+
+    patternProperties:
+      '^port@[0-9]':
+        $ref: audio-graph-port.yaml#
+        unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+
+    adx at 702d3800 {
+        compatible = "nvidia,tegra210-adx";
+        reg = <0x702d3800 0x100>;
+        sound-name-prefix = "ADX1";
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
index 1118a94..4087eeb 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
@@ -85,6 +85,26 @@ patternProperties:
     type: object
     $ref: nvidia,tegra186-dspk.yaml#
 
+  '^mvc@[0-9a-f]+$':
+    type: object
+    $ref: nvidia,tegra210-mvc.yaml#
+
+  '^sfc@[0-9a-f]+$':
+    type: object
+    $ref: nvidia,tegra210-sfc.yaml#
+
+  '^amx@[0-9a-f]+$':
+    type: object
+    $ref: nvidia,tegra210-amx.yaml#
+
+  '^adx@[0-9a-f]+$':
+    type: object
+    $ref: nvidia,tegra210-adx.yaml#
+
+  '^mixer@[0-9a-f]+$':
+    type: object
+    $ref: nvidia,tegra210-mixer.yaml#
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
new file mode 100644
index 0000000..e6b365b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/nvidia,tegra210-amx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra210 AMX Device Tree Bindings
+
+description: |
+  The Audio Multiplexer (AMX) block can multiplex up to four input streams
+  each of which can have maximum 16 channels and generate an output stream
+  with maximum 16 channels. A byte RAM helps to form an output frame by
+  any combination of bytes from the input frames.
+
+maintainers:
+  - Jon Hunter <jonathanh at nvidia.com>
+  - Mohan Kumar <mkumard at nvidia.com>
+  - Sameer Pujar <spujar at nvidia.com>
+
+properties:
+  $nodename:
+    pattern: "^amx@[0-9a-f]*$"
+
+  compatible:
+    oneOf:
+      - const: nvidia,tegra210-amx
+      - items:
+          - const: nvidia,tegra186-amx
+          - const: nvidia,tegra210-amx
+      - const: nvidia,tegra194-amx
+
+  reg:
+    maxItems: 1
+
+  sound-name-prefix:
+    pattern: "^AMX[1-9]$"
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      used as prefix for sink/source names of the component. Must be a
+      unique string among multiple instances of the same component.
+      The name can be "AMX1" or "AMX2" ... "AMXx", where x depends on
+      the maximum available instances on a Tegra SoC.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    description: |
+      AMX has four inputs and one output. Accordingly ACIF (Audio Client
+      Interfaces) RX and TX port nodes are defined to represent AMX inputs
+      and output respectively. These are connected to corresponding ports
+      on AHUB.
+
+    patternProperties:
+      '^port@[0-9]':
+        $ref: audio-graph-port.yaml#
+        unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+
+    amx at 702d3000 {
+        compatible = "nvidia,tegra210-amx";
+        reg = <0x702d3000 0x100>;
+        sound-name-prefix = "AMX1";
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
new file mode 100644
index 0000000..0808355
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/nvidia,tegra210-mixer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra210 Mixer Device Tree Bindings
+
+description: |
+  The Mixer supports mixing of up to ten 7.1 audio input streams and
+  generate five outputs (each of which can be any combination of the
+  ten input streams).
+
+maintainers:
+  - Jon Hunter <jonathanh at nvidia.com>
+  - Mohan Kumar <mkumard at nvidia.com>
+  - Sameer Pujar <spujar at nvidia.com>
+
+properties:
+  $nodename:
+    pattern: "^mixer@[0-9a-f]*$"
+
+  compatible:
+    oneOf:
+      - const: nvidia,tegra210-amixer
+      - items:
+          - enum:
+              - nvidia,tegra194-amixer
+              - nvidia,tegra186-amixer
+          - const: nvidia,tegra210-amixer
+
+  reg:
+    maxItems: 1
+
+  sound-name-prefix:
+    const: "MIXER"
+    $ref: /schemas/types.yaml#/definitions/string
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    description: |
+      Mixer has ten inputs and five outputs. Accordingly ACIF (Audio Client
+      Interfaces) RX and TX port nodes are defined to represent MIXER inputs
+      and outputs respectively. These are connected to corresponding ports
+      on AHUB.
+
+    patternProperties:
+      '^port@[0-9]':
+        $ref: audio-graph-port.yaml#
+        unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+
+    mixer at 702dbb00 {
+        compatible = "nvidia,tegra210-amixer";
+        reg = <0x702dbb00 0x800>;
+        sound-name-prefix = "MIXER";
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
new file mode 100644
index 0000000..7d81b11
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/nvidia,tegra210-mvc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra210 MVC Device Tree Bindings
+
+description: |
+  The Master Volume Control (MVC) provides gain or attenuation to a digital
+  signal path. It can be used in input or output signal path for per-stream
+  volume control or it can be used as master volume control. The MVC block
+  has one input and one output. The input digital stream can be mono or
+  multi-channel (up to 7.1 channels) stream. An independent mute control is
+  also included in the MVC block.
+
+maintainers:
+  - Jon Hunter <jonathanh at nvidia.com>
+  - Mohan Kumar <mkumard at nvidia.com>
+  - Sameer Pujar <spujar at nvidia.com>
+
+properties:
+  $nodename:
+    pattern: "^mvc@[0-9a-f]*$"
+
+  compatible:
+    oneOf:
+      - const: nvidia,tegra210-mvc
+      - items:
+          - enum:
+              - nvidia,tegra194-mvc
+              - nvidia,tegra186-mvc
+          - const: nvidia,tegra210-mvc
+
+  reg:
+    maxItems: 1
+
+  sound-name-prefix:
+    pattern: "^MVC[1-9]$"
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      used as prefix for sink/source names of the component. Must be a
+      unique string among multiple instances of the same component.
+      The name can be "MVC1" or "MVC2" ... "MVCx", where x depends on
+      the maximum available instances on a Tegra SoC.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    properties:
+      port at 0:
+        $ref: audio-graph-port.yaml#
+        unevaluatedProperties: false
+        description: |
+          ACIF (Audio Client Interface) acting as MVC input (RX) port.
+          This is connected to corresponding ACIF port on AHUB.
+
+      port at 1:
+        $ref: audio-graph-port.yaml#
+        unevaluatedProperties: false
+        description: |
+          ACIF (Audio Client Interface) acting as MVC output (TX) port.
+          This is connected to corresponding ACIF port on AHUB.
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+
+    mvc at 702da000 {
+        compatible = "nvidia,tegra210-mvc";
+        reg = <0x702da000 0x200>;
+        sound-name-prefix = "MVC1";
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
new file mode 100644
index 0000000..5f05e2a
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/nvidia,tegra210-sfc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tegra210 SFC Device Tree Bindings
+
+description: |
+  The Sampling Frequency Converter (SFC) converts the sampling frequency
+  of the input signal from one frequency to another. It supports sampling
+  frequency conversions of streams of up to two channels (stereo).
+
+maintainers:
+  - Jon Hunter <jonathanh at nvidia.com>
+  - Mohan Kumar <mkumard at nvidia.com>
+  - Sameer Pujar <spujar at nvidia.com>
+
+properties:
+  $nodename:
+    pattern: "^sfc@[0-9a-f]*$"
+
+  compatible:
+    oneOf:
+      - const: nvidia,tegra210-sfc
+      - items:
+          - enum:
+              - nvidia,tegra194-sfc
+              - nvidia,tegra186-sfc
+          - const: nvidia,tegra210-sfc
+
+  reg:
+    maxItems: 1
+
+  sound-name-prefix:
+    pattern: "^SFC[1-9]$"
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      used as prefix for sink/source names of the component. Must be a
+      unique string among multiple instances of the same component.
+      The name can be "SFC1" or "SFC2" ... "SFCx", where x depends on
+      the maximum available instances on a Tegra SoC.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+    properties:
+      port at 0:
+        $ref: audio-graph-port.yaml#
+        unevaluatedProperties: false
+        description: |
+          ACIF (Audio Client Interface) acting as SFC input (RX) port.
+          This is connected to corresponding ACIF port on AHUB.
+
+      port at 1:
+        $ref: audio-graph-port.yaml#
+        unevaluatedProperties: false
+        description: |
+          ACIF (Audio Client Interface) acting as SFC output (TX) port.
+          This is connected to corresponding ACIF port on AHUB.
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+
+    sfc at 702d2000 {
+        compatible = "nvidia,tegra210-sfc";
+        reg = <0x702d2000 0x200>;
+        sound-name-prefix = "SFC1";
+    };
+
+...
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:51 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:51 +0530
Subject: [PATCH 05/13] ASoC: tegra: Add routes for few AHUB modules
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-6-git-send-email-spujar@nvidia.com>

Add routing support for following modules of AHUB:
 * SFC (Sampling Frequency Converter)
 * MVC (Master Volume Control)
 * AMX (Audio Multiplexer)
 * ADX (Audio Demultiplexer)
 * Mixer

These modules can be plugged into audio path as per the need using
routing controls similar to the already existing routes to I/O modules
such as I2S, DMIC and DSPK.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 sound/soc/tegra/tegra210_ahub.c | 511 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 509 insertions(+), 2 deletions(-)

diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c
index 66287a7..44a1ee0 100644
--- a/sound/soc/tegra/tegra210_ahub.c
+++ b/sound/soc/tegra/tegra210_ahub.c
@@ -105,14 +105,68 @@ static struct snd_soc_dai_driver tegra210_ahub_dais[] = {
 	DAI(ADMAIF8),
 	DAI(ADMAIF9),
 	DAI(ADMAIF10),
+	/* XBAR <-> I2S <-> Codec */
 	DAI(I2S1),
 	DAI(I2S2),
 	DAI(I2S3),
 	DAI(I2S4),
 	DAI(I2S5),
+	/* XBAR <- DMIC <- Codec */
 	DAI(DMIC1),
 	DAI(DMIC2),
 	DAI(DMIC3),
+	/* XBAR -> SFC -> XBAR */
+	DAI(SFC1 RX),
+	DAI(SFC1 TX),
+	DAI(SFC2 RX),
+	DAI(SFC2 TX),
+	DAI(SFC3 RX),
+	DAI(SFC3 TX),
+	DAI(SFC4 RX),
+	DAI(SFC4 TX),
+	/* XBAR -> MVC -> XBAR */
+	DAI(MVC1 RX),
+	DAI(MVC1 TX),
+	DAI(MVC2 RX),
+	DAI(MVC2 TX),
+	/* XBAR -> AMX(4:1) -> XBAR */
+	DAI(AMX1 RX1),
+	DAI(AMX1 RX2),
+	DAI(AMX1 RX3),
+	DAI(AMX1 RX4),
+	DAI(AMX1),
+	DAI(AMX2 RX1),
+	DAI(AMX2 RX2),
+	DAI(AMX2 RX3),
+	DAI(AMX2 RX4),
+	DAI(AMX2),
+	/* XBAR -> ADX(1:4) -> XBAR */
+	DAI(ADX1),
+	DAI(ADX1 TX1),
+	DAI(ADX1 TX2),
+	DAI(ADX1 TX3),
+	DAI(ADX1 TX4),
+	DAI(ADX2),
+	DAI(ADX2 TX1),
+	DAI(ADX2 TX2),
+	DAI(ADX2 TX3),
+	DAI(ADX2 TX4),
+	/* XBAR -> MIXER(10:5) -> XBAR */
+	DAI(MIXER RX1),
+	DAI(MIXER RX2),
+	DAI(MIXER RX3),
+	DAI(MIXER RX4),
+	DAI(MIXER RX5),
+	DAI(MIXER RX6),
+	DAI(MIXER RX7),
+	DAI(MIXER RX8),
+	DAI(MIXER RX9),
+	DAI(MIXER RX10),
+	DAI(MIXER TX1),
+	DAI(MIXER TX2),
+	DAI(MIXER TX3),
+	DAI(MIXER TX4),
+	DAI(MIXER TX5),
 };
 
 static struct snd_soc_dai_driver tegra186_ahub_dais[] = {
@@ -136,18 +190,93 @@ static struct snd_soc_dai_driver tegra186_ahub_dais[] = {
 	DAI(ADMAIF18),
 	DAI(ADMAIF19),
 	DAI(ADMAIF20),
+	/* XBAR <-> I2S <-> Codec */
 	DAI(I2S1),
 	DAI(I2S2),
 	DAI(I2S3),
 	DAI(I2S4),
 	DAI(I2S5),
 	DAI(I2S6),
+	/* XBAR <- DMIC <- Codec */
 	DAI(DMIC1),
 	DAI(DMIC2),
 	DAI(DMIC3),
 	DAI(DMIC4),
+	/* XBAR -> DSPK -> Codec */
 	DAI(DSPK1),
 	DAI(DSPK2),
+	/* XBAR -> SFC -> XBAR */
+	DAI(SFC1 RX),
+	DAI(SFC1 TX),
+	DAI(SFC2 RX),
+	DAI(SFC2 TX),
+	DAI(SFC3 RX),
+	DAI(SFC3 TX),
+	DAI(SFC4 RX),
+	DAI(SFC4 TX),
+	/* XBAR -> MVC -> XBAR */
+	DAI(MVC1 RX),
+	DAI(MVC1 TX),
+	DAI(MVC2 RX),
+	DAI(MVC2 TX),
+	/* XBAR -> AMX(4:1) -> XBAR */
+	DAI(AMX1 RX1),
+	DAI(AMX1 RX2),
+	DAI(AMX1 RX3),
+	DAI(AMX1 RX4),
+	DAI(AMX1),
+	DAI(AMX2 RX1),
+	DAI(AMX2 RX2),
+	DAI(AMX2 RX3),
+	DAI(AMX2 RX4),
+	DAI(AMX2),
+	DAI(AMX3 RX1),
+	DAI(AMX3 RX2),
+	DAI(AMX3 RX3),
+	DAI(AMX3 RX4),
+	DAI(AMX3),
+	DAI(AMX4 RX1),
+	DAI(AMX4 RX2),
+	DAI(AMX4 RX3),
+	DAI(AMX4 RX4),
+	DAI(AMX4),
+	/* XBAR -> ADX(1:4) -> XBAR */
+	DAI(ADX1),
+	DAI(ADX1 TX1),
+	DAI(ADX1 TX2),
+	DAI(ADX1 TX3),
+	DAI(ADX1 TX4),
+	DAI(ADX2),
+	DAI(ADX2 TX1),
+	DAI(ADX2 TX2),
+	DAI(ADX2 TX3),
+	DAI(ADX2 TX4),
+	DAI(ADX3),
+	DAI(ADX3 TX1),
+	DAI(ADX3 TX2),
+	DAI(ADX3 TX3),
+	DAI(ADX3 TX4),
+	DAI(ADX4),
+	DAI(ADX4 TX1),
+	DAI(ADX4 TX2),
+	DAI(ADX4 TX3),
+	DAI(ADX4 TX4),
+	/* XBAR -> MIXER(10:5) -> XBAR */
+	DAI(MIXER RX1),
+	DAI(MIXER RX2),
+	DAI(MIXER RX3),
+	DAI(MIXER RX4),
+	DAI(MIXER RX5),
+	DAI(MIXER RX6),
+	DAI(MIXER RX7),
+	DAI(MIXER RX8),
+	DAI(MIXER RX9),
+	DAI(MIXER RX10),
+	DAI(MIXER TX1),
+	DAI(MIXER TX2),
+	DAI(MIXER TX3),
+	DAI(MIXER TX4),
+	DAI(MIXER TX5),
 };
 
 static const char * const tegra210_ahub_mux_texts[] = {
@@ -170,6 +299,27 @@ static const char * const tegra210_ahub_mux_texts[] = {
 	"DMIC1",
 	"DMIC2",
 	"DMIC3",
+	"SFC1",
+	"SFC2",
+	"SFC3",
+	"SFC4",
+	"MVC1",
+	"MVC2",
+	"AMX1",
+	"AMX2",
+	"ADX1 TX1",
+	"ADX1 TX2",
+	"ADX1 TX3",
+	"ADX1 TX4",
+	"ADX2 TX1",
+	"ADX2 TX2",
+	"ADX2 TX3",
+	"ADX2 TX4",
+	"MIXER TX1",
+	"MIXER TX2",
+	"MIXER TX3",
+	"MIXER TX4",
+	"MIXER TX5",
 };
 
 static const char * const tegra186_ahub_mux_texts[] = {
@@ -204,10 +354,42 @@ static const char * const tegra186_ahub_mux_texts[] = {
 	"DMIC2",
 	"DMIC3",
 	"DMIC4",
+	"SFC1",
+	"SFC2",
+	"SFC3",
+	"SFC4",
+	"MVC1",
+	"MVC2",
+	"AMX1",
+	"AMX2",
+	"AMX3",
+	"AMX4",
+	"ADX1 TX1",
+	"ADX1 TX2",
+	"ADX1 TX3",
+	"ADX1 TX4",
+	"ADX2 TX1",
+	"ADX2 TX2",
+	"ADX2 TX3",
+	"ADX2 TX4",
+	"ADX3 TX1",
+	"ADX3 TX2",
+	"ADX3 TX3",
+	"ADX3 TX4",
+	"ADX4 TX1",
+	"ADX4 TX2",
+	"ADX4 TX3",
+	"ADX4 TX4",
+	"MIXER TX1",
+	"MIXER TX2",
+	"MIXER TX3",
+	"MIXER TX4",
+	"MIXER TX5",
 };
 
 static const unsigned int tegra210_ahub_mux_values[] = {
 	0,
+	/* ADMAIF */
 	MUX_VALUE(0, 0),
 	MUX_VALUE(0, 1),
 	MUX_VALUE(0, 2),
@@ -218,18 +400,47 @@ static const unsigned int tegra210_ahub_mux_values[] = {
 	MUX_VALUE(0, 7),
 	MUX_VALUE(0, 8),
 	MUX_VALUE(0, 9),
+	/* I2S */
 	MUX_VALUE(0, 16),
 	MUX_VALUE(0, 17),
 	MUX_VALUE(0, 18),
 	MUX_VALUE(0, 19),
 	MUX_VALUE(0, 20),
+	/* DMIC */
 	MUX_VALUE(2, 18),
 	MUX_VALUE(2, 19),
 	MUX_VALUE(2, 20),
+	/* SFC */
+	MUX_VALUE(0, 24),
+	MUX_VALUE(0, 25),
+	MUX_VALUE(0, 26),
+	MUX_VALUE(0, 27),
+	/* MVC */
+	MUX_VALUE(2, 8),
+	MUX_VALUE(2, 9),
+	/* AMX */
+	MUX_VALUE(1, 8),
+	MUX_VALUE(1, 9),
+	/* ADX */
+	MUX_VALUE(2, 24),
+	MUX_VALUE(2, 25),
+	MUX_VALUE(2, 26),
+	MUX_VALUE(2, 27),
+	MUX_VALUE(2, 28),
+	MUX_VALUE(2, 29),
+	MUX_VALUE(2, 30),
+	MUX_VALUE(2, 31),
+	/* MIXER */
+	MUX_VALUE(1, 0),
+	MUX_VALUE(1, 1),
+	MUX_VALUE(1, 2),
+	MUX_VALUE(1, 3),
+	MUX_VALUE(1, 4),
 };
 
 static const unsigned int tegra186_ahub_mux_values[] = {
 	0,
+	/* ADMAIF */
 	MUX_VALUE(0, 0),
 	MUX_VALUE(0, 1),
 	MUX_VALUE(0, 2),
@@ -246,20 +457,59 @@ static const unsigned int tegra186_ahub_mux_values[] = {
 	MUX_VALUE(0, 13),
 	MUX_VALUE(0, 14),
 	MUX_VALUE(0, 15),
+	/* I2S */
 	MUX_VALUE(0, 16),
 	MUX_VALUE(0, 17),
 	MUX_VALUE(0, 18),
 	MUX_VALUE(0, 19),
 	MUX_VALUE(0, 20),
 	MUX_VALUE(0, 21),
+	/* ADMAIF */
 	MUX_VALUE(3, 16),
 	MUX_VALUE(3, 17),
 	MUX_VALUE(3, 18),
 	MUX_VALUE(3, 19),
+	/* DMIC */
 	MUX_VALUE(2, 18),
 	MUX_VALUE(2, 19),
 	MUX_VALUE(2, 20),
 	MUX_VALUE(2, 21),
+	/* SFC */
+	MUX_VALUE(0, 24),
+	MUX_VALUE(0, 25),
+	MUX_VALUE(0, 26),
+	MUX_VALUE(0, 27),
+	/* MVC */
+	MUX_VALUE(2, 8),
+	MUX_VALUE(2, 9),
+	/* AMX */
+	MUX_VALUE(1, 8),
+	MUX_VALUE(1, 9),
+	MUX_VALUE(1, 10),
+	MUX_VALUE(1, 11),
+	/* ADX */
+	MUX_VALUE(2, 24),
+	MUX_VALUE(2, 25),
+	MUX_VALUE(2, 26),
+	MUX_VALUE(2, 27),
+	MUX_VALUE(2, 28),
+	MUX_VALUE(2, 29),
+	MUX_VALUE(2, 30),
+	MUX_VALUE(2, 31),
+	MUX_VALUE(3, 0),
+	MUX_VALUE(3, 1),
+	MUX_VALUE(3, 2),
+	MUX_VALUE(3, 3),
+	MUX_VALUE(3, 4),
+	MUX_VALUE(3, 5),
+	MUX_VALUE(3, 6),
+	MUX_VALUE(3, 7),
+	/* MIXER */
+	MUX_VALUE(1, 0),
+	MUX_VALUE(1, 1),
+	MUX_VALUE(1, 2),
+	MUX_VALUE(1, 3),
+	MUX_VALUE(1, 4),
 };
 
 /* Controls for t210 */
@@ -278,6 +528,32 @@ MUX_ENUM_CTRL_DECL(t210_i2s2_tx, 0x11);
 MUX_ENUM_CTRL_DECL(t210_i2s3_tx, 0x12);
 MUX_ENUM_CTRL_DECL(t210_i2s4_tx, 0x13);
 MUX_ENUM_CTRL_DECL(t210_i2s5_tx, 0x14);
+MUX_ENUM_CTRL_DECL(t210_sfc1_tx, 0x18);
+MUX_ENUM_CTRL_DECL(t210_sfc2_tx, 0x19);
+MUX_ENUM_CTRL_DECL(t210_sfc3_tx, 0x1a);
+MUX_ENUM_CTRL_DECL(t210_sfc4_tx, 0x1b);
+MUX_ENUM_CTRL_DECL(t210_mvc1_tx, 0x48);
+MUX_ENUM_CTRL_DECL(t210_mvc2_tx, 0x49);
+MUX_ENUM_CTRL_DECL(t210_amx11_tx, 0x50);
+MUX_ENUM_CTRL_DECL(t210_amx12_tx, 0x51);
+MUX_ENUM_CTRL_DECL(t210_amx13_tx, 0x52);
+MUX_ENUM_CTRL_DECL(t210_amx14_tx, 0x53);
+MUX_ENUM_CTRL_DECL(t210_amx21_tx, 0x54);
+MUX_ENUM_CTRL_DECL(t210_amx22_tx, 0x55);
+MUX_ENUM_CTRL_DECL(t210_amx23_tx, 0x56);
+MUX_ENUM_CTRL_DECL(t210_amx24_tx, 0x57);
+MUX_ENUM_CTRL_DECL(t210_adx1_tx, 0x58);
+MUX_ENUM_CTRL_DECL(t210_adx2_tx, 0x59);
+MUX_ENUM_CTRL_DECL(t210_mixer11_tx, 0x20);
+MUX_ENUM_CTRL_DECL(t210_mixer12_tx, 0x21);
+MUX_ENUM_CTRL_DECL(t210_mixer13_tx, 0x22);
+MUX_ENUM_CTRL_DECL(t210_mixer14_tx, 0x23);
+MUX_ENUM_CTRL_DECL(t210_mixer15_tx, 0x24);
+MUX_ENUM_CTRL_DECL(t210_mixer16_tx, 0x25);
+MUX_ENUM_CTRL_DECL(t210_mixer17_tx, 0x26);
+MUX_ENUM_CTRL_DECL(t210_mixer18_tx, 0x27);
+MUX_ENUM_CTRL_DECL(t210_mixer19_tx, 0x28);
+MUX_ENUM_CTRL_DECL(t210_mixer110_tx, 0x29);
 
 /* Controls for t186 */
 MUX_ENUM_CTRL_DECL_186(t186_admaif1_tx, 0x00);
@@ -308,6 +584,42 @@ MUX_ENUM_CTRL_DECL_186(t186_admaif17_tx, 0x68);
 MUX_ENUM_CTRL_DECL_186(t186_admaif18_tx, 0x69);
 MUX_ENUM_CTRL_DECL_186(t186_admaif19_tx, 0x6a);
 MUX_ENUM_CTRL_DECL_186(t186_admaif20_tx, 0x6b);
+MUX_ENUM_CTRL_DECL_186(t186_sfc1_tx, 0x18);
+MUX_ENUM_CTRL_DECL_186(t186_sfc2_tx, 0x19);
+MUX_ENUM_CTRL_DECL_186(t186_sfc3_tx, 0x1a);
+MUX_ENUM_CTRL_DECL_186(t186_sfc4_tx, 0x1b);
+MUX_ENUM_CTRL_DECL_186(t186_mvc1_tx, 0x48);
+MUX_ENUM_CTRL_DECL_186(t186_mvc2_tx, 0x49);
+MUX_ENUM_CTRL_DECL_186(t186_amx11_tx, 0x50);
+MUX_ENUM_CTRL_DECL_186(t186_amx12_tx, 0x51);
+MUX_ENUM_CTRL_DECL_186(t186_amx13_tx, 0x52);
+MUX_ENUM_CTRL_DECL_186(t186_amx14_tx, 0x53);
+MUX_ENUM_CTRL_DECL_186(t186_amx21_tx, 0x54);
+MUX_ENUM_CTRL_DECL_186(t186_amx22_tx, 0x55);
+MUX_ENUM_CTRL_DECL_186(t186_amx23_tx, 0x56);
+MUX_ENUM_CTRL_DECL_186(t186_amx24_tx, 0x57);
+MUX_ENUM_CTRL_DECL_186(t186_amx31_tx, 0x58);
+MUX_ENUM_CTRL_DECL_186(t186_amx32_tx, 0x59);
+MUX_ENUM_CTRL_DECL_186(t186_amx33_tx, 0x5a);
+MUX_ENUM_CTRL_DECL_186(t186_amx34_tx, 0x5b);
+MUX_ENUM_CTRL_DECL_186(t186_amx41_tx, 0x64);
+MUX_ENUM_CTRL_DECL_186(t186_amx42_tx, 0x65);
+MUX_ENUM_CTRL_DECL_186(t186_amx43_tx, 0x66);
+MUX_ENUM_CTRL_DECL_186(t186_amx44_tx, 0x67);
+MUX_ENUM_CTRL_DECL_186(t186_adx1_tx, 0x60);
+MUX_ENUM_CTRL_DECL_186(t186_adx2_tx, 0x61);
+MUX_ENUM_CTRL_DECL_186(t186_adx3_tx, 0x62);
+MUX_ENUM_CTRL_DECL_186(t186_adx4_tx, 0x63);
+MUX_ENUM_CTRL_DECL_186(t186_mixer11_tx, 0x20);
+MUX_ENUM_CTRL_DECL_186(t186_mixer12_tx, 0x21);
+MUX_ENUM_CTRL_DECL_186(t186_mixer13_tx, 0x22);
+MUX_ENUM_CTRL_DECL_186(t186_mixer14_tx, 0x23);
+MUX_ENUM_CTRL_DECL_186(t186_mixer15_tx, 0x24);
+MUX_ENUM_CTRL_DECL_186(t186_mixer16_tx, 0x25);
+MUX_ENUM_CTRL_DECL_186(t186_mixer17_tx, 0x26);
+MUX_ENUM_CTRL_DECL_186(t186_mixer18_tx, 0x27);
+MUX_ENUM_CTRL_DECL_186(t186_mixer19_tx, 0x28);
+MUX_ENUM_CTRL_DECL_186(t186_mixer110_tx, 0x29);
 
 /*
  * The number of entries in, and order of, this array is closely tied to the
@@ -333,6 +645,47 @@ static const struct snd_soc_dapm_widget tegra210_ahub_widgets[] = {
 	TX_WIDGETS("DMIC1"),
 	TX_WIDGETS("DMIC2"),
 	TX_WIDGETS("DMIC3"),
+	WIDGETS("SFC1", t210_sfc1_tx),
+	WIDGETS("SFC2", t210_sfc2_tx),
+	WIDGETS("SFC3", t210_sfc3_tx),
+	WIDGETS("SFC4", t210_sfc4_tx),
+	WIDGETS("MVC1", t210_mvc1_tx),
+	WIDGETS("MVC2", t210_mvc2_tx),
+	WIDGETS("AMX1 RX1", t210_amx11_tx),
+	WIDGETS("AMX1 RX2", t210_amx12_tx),
+	WIDGETS("AMX1 RX3", t210_amx13_tx),
+	WIDGETS("AMX1 RX4", t210_amx14_tx),
+	WIDGETS("AMX2 RX1", t210_amx21_tx),
+	WIDGETS("AMX2 RX2", t210_amx22_tx),
+	WIDGETS("AMX2 RX3", t210_amx23_tx),
+	WIDGETS("AMX2 RX4", t210_amx24_tx),
+	TX_WIDGETS("AMX1"),
+	TX_WIDGETS("AMX2"),
+	WIDGETS("ADX1", t210_adx1_tx),
+	WIDGETS("ADX2", t210_adx2_tx),
+	TX_WIDGETS("ADX1 TX1"),
+	TX_WIDGETS("ADX1 TX2"),
+	TX_WIDGETS("ADX1 TX3"),
+	TX_WIDGETS("ADX1 TX4"),
+	TX_WIDGETS("ADX2 TX1"),
+	TX_WIDGETS("ADX2 TX2"),
+	TX_WIDGETS("ADX2 TX3"),
+	TX_WIDGETS("ADX2 TX4"),
+	WIDGETS("MIXER RX1", t210_mixer11_tx),
+	WIDGETS("MIXER RX2", t210_mixer12_tx),
+	WIDGETS("MIXER RX3", t210_mixer13_tx),
+	WIDGETS("MIXER RX4", t210_mixer14_tx),
+	WIDGETS("MIXER RX5", t210_mixer15_tx),
+	WIDGETS("MIXER RX6", t210_mixer16_tx),
+	WIDGETS("MIXER RX7", t210_mixer17_tx),
+	WIDGETS("MIXER RX8", t210_mixer18_tx),
+	WIDGETS("MIXER RX9", t210_mixer19_tx),
+	WIDGETS("MIXER RX10", t210_mixer110_tx),
+	TX_WIDGETS("MIXER TX1"),
+	TX_WIDGETS("MIXER TX2"),
+	TX_WIDGETS("MIXER TX3"),
+	TX_WIDGETS("MIXER TX4"),
+	TX_WIDGETS("MIXER TX5"),
 };
 
 static const struct snd_soc_dapm_widget tegra186_ahub_widgets[] = {
@@ -368,6 +721,67 @@ static const struct snd_soc_dapm_widget tegra186_ahub_widgets[] = {
 	TX_WIDGETS("DMIC4"),
 	WIDGETS("DSPK1", t186_dspk1_tx),
 	WIDGETS("DSPK2", t186_dspk2_tx),
+	WIDGETS("SFC1", t186_sfc1_tx),
+	WIDGETS("SFC2", t186_sfc2_tx),
+	WIDGETS("SFC3", t186_sfc3_tx),
+	WIDGETS("SFC4", t186_sfc4_tx),
+	WIDGETS("MVC1", t186_mvc1_tx),
+	WIDGETS("MVC2", t186_mvc2_tx),
+	WIDGETS("AMX1 RX1", t186_amx11_tx),
+	WIDGETS("AMX1 RX2", t186_amx12_tx),
+	WIDGETS("AMX1 RX3", t186_amx13_tx),
+	WIDGETS("AMX1 RX4", t186_amx14_tx),
+	WIDGETS("AMX2 RX1", t186_amx21_tx),
+	WIDGETS("AMX2 RX2", t186_amx22_tx),
+	WIDGETS("AMX2 RX3", t186_amx23_tx),
+	WIDGETS("AMX2 RX4", t186_amx24_tx),
+	WIDGETS("AMX3 RX1", t186_amx31_tx),
+	WIDGETS("AMX3 RX2", t186_amx32_tx),
+	WIDGETS("AMX3 RX3", t186_amx33_tx),
+	WIDGETS("AMX3 RX4", t186_amx34_tx),
+	WIDGETS("AMX4 RX1", t186_amx41_tx),
+	WIDGETS("AMX4 RX2", t186_amx42_tx),
+	WIDGETS("AMX4 RX3", t186_amx43_tx),
+	WIDGETS("AMX4 RX4", t186_amx44_tx),
+	TX_WIDGETS("AMX1"),
+	TX_WIDGETS("AMX2"),
+	TX_WIDGETS("AMX3"),
+	TX_WIDGETS("AMX4"),
+	WIDGETS("ADX1", t186_adx1_tx),
+	WIDGETS("ADX2", t186_adx2_tx),
+	WIDGETS("ADX3", t186_adx3_tx),
+	WIDGETS("ADX4", t186_adx4_tx),
+	TX_WIDGETS("ADX1 TX1"),
+	TX_WIDGETS("ADX1 TX2"),
+	TX_WIDGETS("ADX1 TX3"),
+	TX_WIDGETS("ADX1 TX4"),
+	TX_WIDGETS("ADX2 TX1"),
+	TX_WIDGETS("ADX2 TX2"),
+	TX_WIDGETS("ADX2 TX3"),
+	TX_WIDGETS("ADX2 TX4"),
+	TX_WIDGETS("ADX3 TX1"),
+	TX_WIDGETS("ADX3 TX2"),
+	TX_WIDGETS("ADX3 TX3"),
+	TX_WIDGETS("ADX3 TX4"),
+	TX_WIDGETS("ADX4 TX1"),
+	TX_WIDGETS("ADX4 TX2"),
+	TX_WIDGETS("ADX4 TX3"),
+	TX_WIDGETS("ADX4 TX4"),
+	WIDGETS("MIXER RX1", t186_mixer11_tx),
+	WIDGETS("MIXER RX2", t186_mixer12_tx),
+	WIDGETS("MIXER RX3", t186_mixer13_tx),
+	WIDGETS("MIXER RX4", t186_mixer14_tx),
+	WIDGETS("MIXER RX5", t186_mixer15_tx),
+	WIDGETS("MIXER RX6", t186_mixer16_tx),
+	WIDGETS("MIXER RX7", t186_mixer17_tx),
+	WIDGETS("MIXER RX8", t186_mixer18_tx),
+	WIDGETS("MIXER RX9", t186_mixer19_tx),
+	WIDGETS("MIXER RX10", t186_mixer110_tx),
+	TX_WIDGETS("MIXER TX1"),
+	TX_WIDGETS("MIXER TX2"),
+	TX_WIDGETS("MIXER TX3"),
+	TX_WIDGETS("MIXER TX4"),
+	TX_WIDGETS("MIXER TX5"),
 };
 
 #define TEGRA_COMMON_MUX_ROUTES(name)					\
@@ -389,7 +803,28 @@ static const struct snd_soc_dapm_widget tegra186_ahub_widgets[] = {
 	{ name " Mux",		"I2S5",		"I2S5 XBAR-RX" },	\
 	{ name " Mux",		"DMIC1",	"DMIC1 XBAR-RX" },	\
 	{ name " Mux",		"DMIC2",	"DMIC2 XBAR-RX" },	\
-	{ name " Mux",		"DMIC3",	"DMIC3 XBAR-RX" },
+	{ name " Mux",		"DMIC3",	"DMIC3 XBAR-RX" },	\
+	{ name " Mux",		"SFC1",		"SFC1 XBAR-RX" },	\
+	{ name " Mux",		"SFC2",		"SFC2 XBAR-RX" },	\
+	{ name " Mux",		"SFC3",		"SFC3 XBAR-RX" },	\
+	{ name " Mux",		"SFC4",		"SFC4 XBAR-RX" },	\
+	{ name " Mux",		"MVC1",		"MVC1 XBAR-RX" },	\
+	{ name " Mux",		"MVC2",		"MVC2 XBAR-RX" },	\
+	{ name " Mux",		"AMX1",		"AMX1 XBAR-RX" },	\
+	{ name " Mux",		"AMX2",		"AMX2 XBAR-RX" },	\
+	{ name " Mux",		"ADX1 TX1",	"ADX1 TX1 XBAR-RX" },	\
+	{ name " Mux",		"ADX1 TX2",	"ADX1 TX2 XBAR-RX" },	\
+	{ name " Mux",		"ADX1 TX3",	"ADX1 TX3 XBAR-RX" },	\
+	{ name " Mux",		"ADX1 TX4",	"ADX1 TX4 XBAR-RX" },	\
+	{ name " Mux",		"ADX2 TX1",	"ADX2 TX1 XBAR-RX" },	\
+	{ name " Mux",		"ADX2 TX2",	"ADX2 TX2 XBAR-RX" },	\
+	{ name " Mux",		"ADX2 TX3",	"ADX2 TX3 XBAR-RX" },	\
+	{ name " Mux",		"ADX2 TX4",	"ADX2 TX4 XBAR-RX" },	\
+	{ name " Mux",		"MIXER TX1",	"MIXER TX1 XBAR-RX" },	\
+	{ name " Mux",		"MIXER TX2",	"MIXER TX2 XBAR-RX" },	\
+	{ name " Mux",		"MIXER TX3",	"MIXER TX3 XBAR-RX" },	\
+	{ name " Mux",		"MIXER TX4",	"MIXER TX4 XBAR-RX" },	\
+	{ name " Mux",		"MIXER TX5",	"MIXER TX5 XBAR-RX" },
 
 #define TEGRA186_ONLY_MUX_ROUTES(name)					\
 	{ name " Mux",		"ADMAIF11",	"ADMAIF11 XBAR-RX" },	\
@@ -403,7 +838,17 @@ static const struct snd_soc_dapm_widget tegra186_ahub_widgets[] = {
 	{ name " Mux",		"ADMAIF19",	"ADMAIF19 XBAR-RX" },	\
 	{ name " Mux",		"ADMAIF20",	"ADMAIF20 XBAR-RX" },	\
 	{ name " Mux",		"I2S6",		"I2S6 XBAR-RX" },	\
-	{ name " Mux",		"DMIC4",	"DMIC4 XBAR-RX" },
+	{ name " Mux",		"DMIC4",	"DMIC4 XBAR-RX" },	\
+	{ name " Mux",		"AMX3",		"AMX3 XBAR-RX" },	\
+	{ name " Mux",		"AMX4",		"AMX4 XBAR-RX" },	\
+	{ name " Mux",		"ADX3 TX1",	"ADX3 TX1 XBAR-RX" },	\
+	{ name " Mux",		"ADX3 TX2",	"ADX3 TX2 XBAR-RX" },	\
+	{ name " Mux",		"ADX3 TX3",	"ADX3 TX3 XBAR-RX" },	\
+	{ name " Mux",		"ADX3 TX4",	"ADX3 TX4 XBAR-RX" },	\
+	{ name " Mux",		"ADX4 TX1",	"ADX4 TX1 XBAR-RX" },	\
+	{ name " Mux",		"ADX4 TX2",	"ADX4 TX2 XBAR-RX" },	\
+	{ name " Mux",		"ADX4 TX3",	"ADX4 TX3 XBAR-RX" },	\
+	{ name " Mux",		"ADX4 TX4",	"ADX4 TX4 XBAR-RX" },
 
 #define TEGRA210_MUX_ROUTES(name)						\
 	TEGRA_COMMON_MUX_ROUTES(name)
@@ -450,6 +895,32 @@ static const struct snd_soc_dapm_route tegra210_ahub_routes[] = {
 	TEGRA210_MUX_ROUTES("I2S3")
 	TEGRA210_MUX_ROUTES("I2S4")
 	TEGRA210_MUX_ROUTES("I2S5")
+	TEGRA210_MUX_ROUTES("SFC1")
+	TEGRA210_MUX_ROUTES("SFC2")
+	TEGRA210_MUX_ROUTES("SFC3")
+	TEGRA210_MUX_ROUTES("SFC4")
+	TEGRA210_MUX_ROUTES("MVC1")
+	TEGRA210_MUX_ROUTES("MVC2")
+	TEGRA210_MUX_ROUTES("AMX1 RX1")
+	TEGRA210_MUX_ROUTES("AMX1 RX2")
+	TEGRA210_MUX_ROUTES("AMX1 RX3")
+	TEGRA210_MUX_ROUTES("AMX1 RX4")
+	TEGRA210_MUX_ROUTES("AMX2 RX1")
+	TEGRA210_MUX_ROUTES("AMX2 RX2")
+	TEGRA210_MUX_ROUTES("AMX2 RX3")
+	TEGRA210_MUX_ROUTES("AMX2 RX4")
+	TEGRA210_MUX_ROUTES("ADX1")
+	TEGRA210_MUX_ROUTES("ADX2")
+	TEGRA210_MUX_ROUTES("MIXER RX1")
+	TEGRA210_MUX_ROUTES("MIXER RX2")
+	TEGRA210_MUX_ROUTES("MIXER RX3")
+	TEGRA210_MUX_ROUTES("MIXER RX4")
+	TEGRA210_MUX_ROUTES("MIXER RX5")
+	TEGRA210_MUX_ROUTES("MIXER RX6")
+	TEGRA210_MUX_ROUTES("MIXER RX7")
+	TEGRA210_MUX_ROUTES("MIXER RX8")
+	TEGRA210_MUX_ROUTES("MIXER RX9")
+	TEGRA210_MUX_ROUTES("MIXER RX10")
 };
 
 static const struct snd_soc_dapm_route tegra186_ahub_routes[] = {
@@ -501,6 +972,42 @@ static const struct snd_soc_dapm_route tegra186_ahub_routes[] = {
 	TEGRA186_MUX_ROUTES("I2S6")
 	TEGRA186_MUX_ROUTES("DSPK1")
 	TEGRA186_MUX_ROUTES("DSPK2")
+	TEGRA186_MUX_ROUTES("SFC1")
+	TEGRA186_MUX_ROUTES("SFC2")
+	TEGRA186_MUX_ROUTES("SFC3")
+	TEGRA186_MUX_ROUTES("SFC4")
+	TEGRA186_MUX_ROUTES("MVC1")
+	TEGRA186_MUX_ROUTES("MVC2")
+	TEGRA186_MUX_ROUTES("AMX1 RX1")
+	TEGRA186_MUX_ROUTES("AMX1 RX2")
+	TEGRA186_MUX_ROUTES("AMX1 RX3")
+	TEGRA186_MUX_ROUTES("AMX1 RX4")
+	TEGRA186_MUX_ROUTES("AMX2 RX1")
+	TEGRA186_MUX_ROUTES("AMX2 RX2")
+	TEGRA186_MUX_ROUTES("AMX2 RX3")
+	TEGRA186_MUX_ROUTES("AMX2 RX4")
+	TEGRA186_MUX_ROUTES("AMX3 RX1")
+	TEGRA186_MUX_ROUTES("AMX3 RX2")
+	TEGRA186_MUX_ROUTES("AMX3 RX3")
+	TEGRA186_MUX_ROUTES("AMX3 RX4")
+	TEGRA186_MUX_ROUTES("AMX4 RX1")
+	TEGRA186_MUX_ROUTES("AMX4 RX2")
+	TEGRA186_MUX_ROUTES("AMX4 RX3")
+	TEGRA186_MUX_ROUTES("AMX4 RX4")
+	TEGRA186_MUX_ROUTES("ADX1")
+	TEGRA186_MUX_ROUTES("ADX2")
+	TEGRA186_MUX_ROUTES("ADX3")
+	TEGRA186_MUX_ROUTES("ADX4")
+	TEGRA186_MUX_ROUTES("MIXER RX1")
+	TEGRA186_MUX_ROUTES("MIXER RX2")
+	TEGRA186_MUX_ROUTES("MIXER RX3")
+	TEGRA186_MUX_ROUTES("MIXER RX4")
+	TEGRA186_MUX_ROUTES("MIXER RX5")
+	TEGRA186_MUX_ROUTES("MIXER RX6")
+	TEGRA186_MUX_ROUTES("MIXER RX7")
+	TEGRA186_MUX_ROUTES("MIXER RX8")
+	TEGRA186_MUX_ROUTES("MIXER RX9")
+	TEGRA186_MUX_ROUTES("MIXER RX10")
 };
 
 static const struct snd_soc_component_driver tegra210_ahub_component = {
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:52 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:52 +0530
Subject: [PATCH 06/13] ASoC: tegra: Add Tegra210 based MVC driver
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-7-git-send-email-spujar@nvidia.com>

The Master Volume Control (MVC) provides gain or attenuation to a digital
signal path. It can be used in input or output signal path for per-stream
volume control or it can be used as master volume control. The MVC block
has one input and one output. The input digital stream can be mono or
multi-channel (up to 7.1 channels) stream. An independent mute control is
also included in the MVC block.

This patch registers MVC driver with ASoC framework. The component driver
exposes DAPM widgets, routes and kcontrols for the device. The DAI driver
exposes MVC interfaces, which can be used to connect different components
in the ASoC layer. Makefile and Kconfig support is added to allow build
the driver. It can be enabled in the DT via "nvidia,tegra210-mvc"
compatible binding.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 sound/soc/tegra/Kconfig        |   9 +
 sound/soc/tegra/Makefile       |   2 +
 sound/soc/tegra/tegra210_mvc.c | 629 +++++++++++++++++++++++++++++++++++++++++
 sound/soc/tegra/tegra210_mvc.h | 117 ++++++++
 4 files changed, 757 insertions(+)
 create mode 100644 sound/soc/tegra/tegra210_mvc.c
 create mode 100644 sound/soc/tegra/tegra210_mvc.h

diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 83c87f3..b8825e9 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -108,6 +108,15 @@ config SND_SOC_TEGRA210_ADMAIF
 	  channel. Buffer size is configurable for each ADMAIIF channel.
 	  Say Y or M if you want to add support for Tegra210 ADMAIF module.
 
+config SND_SOC_TEGRA210_MVC
+	tristate "Tegra210 MVC module"
+	help
+	  Config to enable the digital Master Volume Controller (MVC) which
+	  provides gain or attenuation to a digital signal path. It can be
+	  used in input or output signal path. It can be used either for
+	  per-stream volume control or for master volume control.
+	  Say Y or M if you want to add support for Tegra210 MVC module.
+
 config SND_SOC_TEGRA_AUDIO_GRAPH_CARD
 	tristate "Audio Graph Card based Tegra driver"
 	depends on SND_AUDIO_GRAPH_CARD
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index e2cec9a..b58d041 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -13,6 +13,7 @@ snd-soc-tegra210-dmic-objs := tegra210_dmic.o
 snd-soc-tegra210-i2s-objs := tegra210_i2s.o
 snd-soc-tegra186-dspk-objs := tegra186_dspk.o
 snd-soc-tegra210-admaif-objs := tegra210_admaif.o
+snd-soc-tegra210-mvc-objs := tegra210_mvc.o
 
 obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
 obj-$(CONFIG_SND_SOC_TEGRA20_AC97) += snd-soc-tegra20-ac97.o
@@ -26,6 +27,7 @@ obj-$(CONFIG_SND_SOC_TEGRA210_AHUB) += snd-soc-tegra210-ahub.o
 obj-$(CONFIG_SND_SOC_TEGRA210_I2S) += snd-soc-tegra210-i2s.o
 obj-$(CONFIG_SND_SOC_TEGRA186_DSPK) += snd-soc-tegra186-dspk.o
 obj-$(CONFIG_SND_SOC_TEGRA210_ADMAIF) += snd-soc-tegra210-admaif.o
+obj-$(CONFIG_SND_SOC_TEGRA210_MVC) += snd-soc-tegra210-mvc.o
 
 # Tegra machine Support
 snd-soc-tegra-wm8903-objs := tegra_wm8903.o
diff --git a/sound/soc/tegra/tegra210_mvc.c b/sound/soc/tegra/tegra210_mvc.c
new file mode 100644
index 0000000..4942813
--- /dev/null
+++ b/sound/soc/tegra/tegra210_mvc.c
@@ -0,0 +1,629 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// tegra210_mvc.c - Tegra210 MVC driver
+//
+// Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "tegra210_mvc.h"
+#include "tegra_cif.h"
+
+static const struct reg_default tegra210_mvc_reg_defaults[] = {
+	{ TEGRA210_MVC_RX_INT_MASK, 0x00000001},
+	{ TEGRA210_MVC_RX_CIF_CTRL, 0x00007700},
+	{ TEGRA210_MVC_TX_INT_MASK, 0x00000001},
+	{ TEGRA210_MVC_TX_CIF_CTRL, 0x00007700},
+	{ TEGRA210_MVC_CG, 0x1},
+	{ TEGRA210_MVC_CTRL, TEGRA210_MVC_CTRL_DEFAULT},
+	{ TEGRA210_MVC_INIT_VOL, 0x00800000},
+	{ TEGRA210_MVC_TARGET_VOL, 0x00800000},
+	{ TEGRA210_MVC_DURATION, 0x000012c0},
+	{ TEGRA210_MVC_DURATION_INV, 0x0006d3a0},
+	{ TEGRA210_MVC_POLY_N1, 0x0000007d},
+	{ TEGRA210_MVC_POLY_N2, 0x00000271},
+	{ TEGRA210_MVC_PEAK_CTRL, 0x000012c0},
+	{ TEGRA210_MVC_CFG_RAM_CTRL, 0x00004000},
+};
+
+static const struct tegra210_mvc_gain_params gain_params = {
+	.poly_coeff = { 23738319, 659403, -3680,
+			15546680, 2530732, -120985,
+			12048422, 5527252, -785042 },
+	.poly_n1 = 16,
+	.poly_n2 = 63,
+	.duration = 150,
+	.duration_inv = 14316558,
+};
+
+static int __maybe_unused tegra210_mvc_runtime_suspend(struct device *dev)
+{
+	struct tegra210_mvc *mvc = dev_get_drvdata(dev);
+
+	regmap_read(mvc->regmap, TEGRA210_MVC_CTRL, &(mvc->ctrl_value));
+
+	regcache_cache_only(mvc->regmap, true);
+	regcache_mark_dirty(mvc->regmap);
+
+	return 0;
+}
+
+static int __maybe_unused tegra210_mvc_runtime_resume(struct device *dev)
+{
+	struct tegra210_mvc *mvc = dev_get_drvdata(dev);
+
+	regcache_cache_only(mvc->regmap, false);
+	regcache_sync(mvc->regmap);
+
+	regmap_write(mvc->regmap, TEGRA210_MVC_CTRL, mvc->ctrl_value);
+	regmap_update_bits(mvc->regmap,
+			   TEGRA210_MVC_SWITCH,
+			   TEGRA210_MVC_VOLUME_SWITCH_MASK,
+			   TEGRA210_MVC_VOLUME_SWITCH_TRIGGER);
+
+	return 0;
+}
+
+static int tegra210_mvc_write_ram(struct tegra210_mvc *mvc,
+				  unsigned int addr, unsigned int coef)
+{
+	unsigned int reg, val;
+	int err;
+
+	err = regmap_read_poll_timeout(mvc->regmap,
+				       TEGRA210_MVC_CFG_RAM_CTRL,
+				       val, !(val & 0x80000000), 10, 10000);
+	if (err < 0)
+		return err;
+
+	reg = (addr << TEGRA210_MVC_CFG_RAM_CTRL_ADDR_SHIFT) &
+	      TEGRA210_MVC_CFG_RAM_CTRL_ADDR_MASK;
+	reg |= TEGRA210_MVC_CFG_RAM_CTRL_ADDR_INIT_EN;
+	reg |= TEGRA210_MVC_CFG_RAM_CTRL_RW_WRITE;
+	reg |= TEGRA210_MVC_CFG_RAM_CTRL_SEQ_ACCESS_EN;
+
+	regmap_write(mvc->regmap, TEGRA210_MVC_CFG_RAM_CTRL, reg);
+	regmap_write(mvc->regmap, TEGRA210_MVC_CFG_RAM_DATA,
+		     coef);
+
+	return 0;
+}
+
+static int tegra210_mvc_get_vol(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt);
+	unsigned int reg = mc->reg;
+
+	if (reg == TEGRA210_MVC_CTRL) {
+		u32 val;
+		u8 mute_mask;
+
+		pm_runtime_get_sync(cmpnt->dev);
+		regmap_read(mvc->regmap, TEGRA210_MVC_CTRL, &val);
+		pm_runtime_put(cmpnt->dev);
+
+		mute_mask = (val >>  TEGRA210_MVC_MUTE_SHIFT) &
+			TEGRA210_MUTE_MASK_EN;
+
+		ucontrol->value.integer.value[0] = mute_mask;
+	} else {
+		u8 chan = (reg - TEGRA210_MVC_TARGET_VOL) / REG_SIZE;
+		s32 val = mvc->volume[chan];
+
+		if (mvc->curve_type == CURVE_POLY)
+			val = ((val >> 16) * 100) >> 8;
+		else {
+			val = (val * 100) >> 8;
+			val += 12000;
+		}
+
+		ucontrol->value.integer.value[0] = val;
+	}
+
+	return 0;
+}
+
+static void tegra210_mvc_conv_vol(struct tegra210_mvc *mvc, u8 chan, s32 val)
+{
+	/*
+	 * Volume control read from mixer control is with
+	 * 100x scaling; for CURVE_POLY the reg range
+	 * is 0-100 (linear, Q24) and for CURVE_LINEAR
+	 * it is -120dB to +40dB (Q8)
+	 */
+	if (mvc->curve_type == CURVE_POLY) {
+		if (val > 10000)
+			val = 10000;
+		mvc->volume[chan] = ((val * (1<<8)) / 100) << 16;
+	} else {
+		val -= 12000;
+		mvc->volume[chan] = (val * (1<<8)) / 100;
+	}
+}
+
+static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt);
+	unsigned int reg = mc->reg;
+	unsigned int value;
+	int err;
+
+	pm_runtime_get_sync(cmpnt->dev);
+
+	/* Check if VOLUME_SWITCH is triggered */
+	err = regmap_read_poll_timeout(mvc->regmap, TEGRA210_MVC_SWITCH,
+			value, !(value & TEGRA210_MVC_VOLUME_SWITCH_MASK),
+			10, 10000);
+	if (err < 0)
+		goto end;
+
+	if (reg == TEGRA210_MVC_CTRL) {
+		u8 mute_mask;
+
+		mute_mask = ucontrol->value.integer.value[0];
+
+		err = regmap_update_bits(mvc->regmap, reg,
+					 TEGRA210_MVC_MUTE_MASK,
+					 mute_mask << TEGRA210_MVC_MUTE_SHIFT);
+	} else {
+		u8 chan;
+
+		chan = (reg - TEGRA210_MVC_TARGET_VOL) / REG_SIZE;
+
+		tegra210_mvc_conv_vol(mvc, chan,
+				      ucontrol->value.integer.value[0]);
+
+		/* Configure init volume same as target volume */
+		regmap_write(mvc->regmap,
+			TEGRA210_MVC_REG_OFFSET(TEGRA210_MVC_INIT_VOL, chan),
+			mvc->volume[chan]);
+
+		err = regmap_write(mvc->regmap, reg, mvc->volume[chan]);
+	}
+
+	err |= regmap_update_bits(mvc->regmap, TEGRA210_MVC_SWITCH,
+			TEGRA210_MVC_VOLUME_SWITCH_MASK,
+			TEGRA210_MVC_VOLUME_SWITCH_TRIGGER);
+
+end:
+	pm_runtime_put(cmpnt->dev);
+	return err;
+}
+
+static void tegra210_mvc_reset_vol_settings(struct tegra210_mvc *mvc,
+					    struct device *dev)
+{
+	int i;
+
+	/* Change volume to default init for new curve type */
+	if (mvc->curve_type == CURVE_POLY) {
+		for (i = 0; i < TEGRA210_MVC_MAX_CHAN_COUNT; i++)
+			mvc->volume[i] = TEGRA210_MVC_INIT_VOL_DEFAULT_POLY;
+	} else {
+		for (i = 0; i < TEGRA210_MVC_MAX_CHAN_COUNT; i++)
+			mvc->volume[i] = TEGRA210_MVC_INIT_VOL_DEFAULT_LINEAR;
+	}
+
+	pm_runtime_get_sync(dev);
+
+	/* Program curve type */
+	regmap_update_bits(mvc->regmap, TEGRA210_MVC_CTRL,
+			   TEGRA210_MVC_CURVE_TYPE_MASK,
+			   mvc->curve_type <<
+			   TEGRA210_MVC_CURVE_TYPE_SHIFT);
+
+	/* Init volume for all channels */
+	for (i = 0; i < TEGRA210_MVC_MAX_CHAN_COUNT; i++) {
+		regmap_write(mvc->regmap,
+			TEGRA210_MVC_REG_OFFSET(TEGRA210_MVC_INIT_VOL, i),
+			mvc->volume[i]);
+		regmap_write(mvc->regmap,
+			TEGRA210_MVC_REG_OFFSET(TEGRA210_MVC_TARGET_VOL, i),
+			mvc->volume[i]);
+	}
+
+	/* Trigger volume switch */
+	regmap_update_bits(mvc->regmap, TEGRA210_MVC_SWITCH,
+			   TEGRA210_MVC_VOLUME_SWITCH_MASK,
+			   TEGRA210_MVC_VOLUME_SWITCH_TRIGGER);
+
+	pm_runtime_put(dev);
+}
+
+static int tegra210_mvc_get_curve_type(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt);
+
+	ucontrol->value.integer.value[0] = mvc->curve_type;
+
+	return 0;
+}
+
+static int tegra210_mvc_put_curve_type(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt);
+	int value;
+
+	regmap_read(mvc->regmap, TEGRA210_MVC_ENABLE, &value);
+	if (value & TEGRA210_MVC_EN) {
+		dev_err(cmpnt->dev,
+			"Curve type can't be set when MVC is running\n");
+		return -EINVAL;
+	}
+
+	if (mvc->curve_type == ucontrol->value.integer.value[0])
+		return 0;
+
+	mvc->curve_type = ucontrol->value.integer.value[0];
+
+	tegra210_mvc_reset_vol_settings(mvc, cmpnt->dev);
+
+	return 0;
+}
+
+static int tegra210_mvc_set_audio_cif(struct tegra210_mvc *mvc,
+				      struct snd_pcm_hw_params *params,
+				      unsigned int reg)
+{
+	unsigned int channels, audio_bits;
+	struct tegra_cif_conf cif_conf;
+
+	memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
+
+	channels = params_channels(params);
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		audio_bits = TEGRA_ACIF_BITS_16;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		audio_bits = TEGRA_ACIF_BITS_32;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	cif_conf.audio_ch = channels;
+	cif_conf.client_ch = channels;
+	cif_conf.audio_bits = audio_bits;
+	cif_conf.client_bits = audio_bits;
+
+	tegra_set_cif(mvc->regmap, reg, &cif_conf);
+
+	return 0;
+}
+
+static int tegra210_mvc_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	struct device *dev = dai->dev;
+	struct tegra210_mvc *mvc = snd_soc_dai_get_drvdata(dai);
+	int i, err, val;
+
+	/* SW reset */
+	regmap_write(mvc->regmap, TEGRA210_MVC_SOFT_RESET, 1);
+
+	err = regmap_read_poll_timeout(mvc->regmap, TEGRA210_MVC_SOFT_RESET,
+				       val, !val, 10, 10000);
+	if (err < 0) {
+		dev_err(dev, "SW reset failed, err = %d\n", err);
+		return err;
+	}
+
+	/* Set RX CIF */
+	err = tegra210_mvc_set_audio_cif(mvc, params, TEGRA210_MVC_RX_CIF_CTRL);
+	if (err) {
+		dev_err(dev, "Can't set MVC RX CIF: %d\n", err);
+		return err;
+	}
+
+	/* Set TX CIF */
+	err = tegra210_mvc_set_audio_cif(mvc, params, TEGRA210_MVC_TX_CIF_CTRL);
+	if (err) {
+		dev_err(dev, "Can't set MVC TX CIF: %d\n", err);
+		return err;
+	}
+
+	/* Program the poly coefficients */
+	for (i = 0; i < NUM_GAIN_POLY_COEFFS; i++) {
+		err = tegra210_mvc_write_ram(mvc, i, gain_params.poly_coeff[i]);
+		if (err < 0) {
+			dev_err(dai->dev, "failed to write coefs, err = %d\n",
+				err);
+			return err;
+		}
+	}
+
+	/* Program poly_n1, poly_n2, duration */
+	regmap_write(mvc->regmap, TEGRA210_MVC_POLY_N1, gain_params.poly_n1);
+	regmap_write(mvc->regmap, TEGRA210_MVC_POLY_N2, gain_params.poly_n2);
+	regmap_write(mvc->regmap, TEGRA210_MVC_DURATION, gain_params.duration);
+
+	/* Program duration_inv */
+	regmap_write(mvc->regmap, TEGRA210_MVC_DURATION_INV,
+		     gain_params.duration_inv);
+
+	return 0;
+}
+
+static struct snd_soc_dai_ops tegra210_mvc_dai_ops = {
+	.hw_params	= tegra210_mvc_hw_params,
+};
+
+static const char * const tegra210_mvc_curve_type_text[] = {
+	"Poly",
+	"Linear",
+};
+
+static const struct soc_enum tegra210_mvc_curve_type_ctrl =
+	SOC_ENUM_SINGLE_EXT(2, tegra210_mvc_curve_type_text);
+
+#define TEGRA210_MVC_VOL_CTRL(chan)					\
+	SOC_SINGLE_EXT("Channel" #chan " Volume",			\
+		       TEGRA210_MVC_REG_OFFSET(TEGRA210_MVC_TARGET_VOL, \
+					       (chan - 1)),		\
+		       0, 16000, 0, tegra210_mvc_get_vol,		\
+		       tegra210_mvc_put_vol)
+
+static const struct snd_kcontrol_new tegra210_mvc_vol_ctrl[] = {
+	/* Per channel volume control */
+	TEGRA210_MVC_VOL_CTRL(1),
+	TEGRA210_MVC_VOL_CTRL(2),
+	TEGRA210_MVC_VOL_CTRL(3),
+	TEGRA210_MVC_VOL_CTRL(4),
+	TEGRA210_MVC_VOL_CTRL(5),
+	TEGRA210_MVC_VOL_CTRL(6),
+	TEGRA210_MVC_VOL_CTRL(7),
+	TEGRA210_MVC_VOL_CTRL(8),
+
+	/* Per channel mute */
+	SOC_SINGLE_EXT("Per Chan Mute Mask",
+		       TEGRA210_MVC_CTRL, 0, TEGRA210_MUTE_MASK_EN, 0,
+		       tegra210_mvc_get_vol, tegra210_mvc_put_vol),
+
+	SOC_ENUM_EXT("Curve Type", tegra210_mvc_curve_type_ctrl,
+		     tegra210_mvc_get_curve_type, tegra210_mvc_put_curve_type),
+};
+
+static struct snd_soc_dai_driver tegra210_mvc_dais[] = {
+	/* Input */
+	{
+		.name = "MVC-RX-CIF",
+		.playback = {
+			.stream_name = "RX-CIF-Playback",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.capture = {
+			.stream_name = "RX-CIF-Capture",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S32_LE,
+		},
+	},
+
+	/* Output */
+	{
+		.name = "MVC-TX-CIF",
+		.playback = {
+			.stream_name = "TX-CIF-Playback",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.capture = {
+			.stream_name = "TX-CIF-Capture",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.ops = &tegra210_mvc_dai_ops,
+	}
+};
+
+static const struct snd_soc_dapm_widget tegra210_mvc_widgets[] = {
+	SND_SOC_DAPM_AIF_IN("RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("TX", NULL, 0, TEGRA210_MVC_ENABLE,
+			     TEGRA210_MVC_EN_SHIFT, 0),
+};
+
+#define MVC_ROUTES(sname)					\
+	{ "RX XBAR-" sname,	NULL,	"XBAR-TX" },		\
+	{ "RX-CIF-" sname,	NULL,	"RX XBAR-" sname },	\
+	{ "RX",			NULL,	"RX-CIF-" sname },	\
+	{ "TX-CIF-" sname,	NULL,	"TX" },			\
+	{ "TX XBAR-" sname,	NULL,	"TX-CIF-" sname },	\
+	{ "XBAR-RX",            NULL,   "TX XBAR-" sname }
+
+static const struct snd_soc_dapm_route tegra210_mvc_routes[] = {
+	{ "TX", NULL, "RX" },
+	MVC_ROUTES("Playback"),
+	MVC_ROUTES("Capture"),
+};
+
+static const struct snd_soc_component_driver tegra210_mvc_cmpnt = {
+	.dapm_widgets		= tegra210_mvc_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tegra210_mvc_widgets),
+	.dapm_routes		= tegra210_mvc_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tegra210_mvc_routes),
+	.controls		= tegra210_mvc_vol_ctrl,
+	.num_controls		= ARRAY_SIZE(tegra210_mvc_vol_ctrl),
+};
+
+static bool tegra210_mvc_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_MVC_RX_STATUS ... TEGRA210_MVC_CONFIG_ERR_TYPE:
+		return true;
+	default:
+		return false;
+	};
+}
+
+static bool tegra210_mvc_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_MVC_RX_INT_MASK ... TEGRA210_MVC_RX_CIF_CTRL:
+	case TEGRA210_MVC_TX_INT_MASK ... TEGRA210_MVC_TX_CIF_CTRL:
+	case TEGRA210_MVC_ENABLE ... TEGRA210_MVC_CG:
+	case TEGRA210_MVC_CTRL ... TEGRA210_MVC_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_mvc_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_MVC_RX_STATUS:
+	case TEGRA210_MVC_RX_INT_STATUS:
+	case TEGRA210_MVC_RX_INT_SET:
+
+	case TEGRA210_MVC_TX_STATUS:
+	case TEGRA210_MVC_TX_INT_STATUS:
+	case TEGRA210_MVC_TX_INT_SET:
+
+	case TEGRA210_MVC_SOFT_RESET:
+	case TEGRA210_MVC_STATUS:
+	case TEGRA210_MVC_INT_STATUS:
+	case TEGRA210_MVC_SWITCH:
+	case TEGRA210_MVC_CFG_RAM_CTRL:
+	case TEGRA210_MVC_CFG_RAM_DATA:
+	case TEGRA210_MVC_PEAK_VALUE:
+	case TEGRA210_MVC_CTRL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_config tegra210_mvc_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+	.max_register		= TEGRA210_MVC_CONFIG_ERR_TYPE,
+	.writeable_reg		= tegra210_mvc_wr_reg,
+	.readable_reg		= tegra210_mvc_rd_reg,
+	.volatile_reg		= tegra210_mvc_volatile_reg,
+	.reg_defaults		= tegra210_mvc_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(tegra210_mvc_reg_defaults),
+	.cache_type		= REGCACHE_FLAT,
+};
+
+static const struct of_device_id tegra210_mvc_of_match[] = {
+	{ .compatible = "nvidia,tegra210-mvc" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, tegra210_mvc_of_match);
+
+static int tegra210_mvc_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct tegra210_mvc *mvc;
+	void __iomem *regs;
+	int err;
+
+	mvc = devm_kzalloc(dev, sizeof(*mvc), GFP_KERNEL);
+	if (!mvc)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, mvc);
+
+	mvc->curve_type = CURVE_LINEAR;
+	mvc->ctrl_value = TEGRA210_MVC_CTRL_DEFAULT;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	mvc->regmap = devm_regmap_init_mmio(dev, regs,
+					    &tegra210_mvc_regmap_config);
+	if (IS_ERR(mvc->regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(mvc->regmap);
+	}
+
+	regcache_cache_only(mvc->regmap, true);
+
+	err = devm_snd_soc_register_component(dev, &tegra210_mvc_cmpnt,
+					      tegra210_mvc_dais,
+					      ARRAY_SIZE(tegra210_mvc_dais));
+	if (err) {
+		dev_err(dev, "can't register MVC component, err: %d\n", err);
+		return err;
+	}
+
+	pm_runtime_enable(dev);
+
+	tegra210_mvc_reset_vol_settings(mvc, &pdev->dev);
+
+	return 0;
+}
+
+static int tegra210_mvc_platform_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct dev_pm_ops tegra210_mvc_pm_ops = {
+	SET_RUNTIME_PM_OPS(tegra210_mvc_runtime_suspend,
+			   tegra210_mvc_runtime_resume, NULL)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
+};
+
+static struct platform_driver tegra210_mvc_driver = {
+	.driver = {
+		.name = "tegra210-mvc",
+		.of_match_table = tegra210_mvc_of_match,
+		.pm = &tegra210_mvc_pm_ops,
+	},
+	.probe = tegra210_mvc_platform_probe,
+	.remove = tegra210_mvc_platform_remove,
+};
+module_platform_driver(tegra210_mvc_driver)
+
+MODULE_AUTHOR("Arun Shamanna Lakshmi <aruns at nvidia.com>");
+MODULE_DESCRIPTION("Tegra210 MVC ASoC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/tegra/tegra210_mvc.h b/sound/soc/tegra/tegra210_mvc.h
new file mode 100644
index 0000000..def29c4
--- /dev/null
+++ b/sound/soc/tegra/tegra210_mvc.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * tegra210_mvc.h - Definitions for Tegra210 MVC driver
+ *
+ * Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
+ *
+ */
+
+#ifndef __TEGRA210_MVC_H__
+#define __TEGRA210_MVC_H__
+
+/*
+ * MVC_RX registers are with respect to XBAR.
+ * The data comes from XBAR to MVC.
+ */
+#define TEGRA210_MVC_RX_STATUS			0x0c
+#define TEGRA210_MVC_RX_INT_STATUS		0x10
+#define TEGRA210_MVC_RX_INT_MASK		0x14
+#define TEGRA210_MVC_RX_INT_SET			0x18
+#define TEGRA210_MVC_RX_INT_CLEAR		0x1c
+#define TEGRA210_MVC_RX_CIF_CTRL		0x20
+
+/*
+ * MVC_TX registers are with respect to XBAR.
+ * The data goes out of MVC.
+ */
+#define TEGRA210_MVC_TX_STATUS			0x4c
+#define TEGRA210_MVC_TX_INT_STATUS		0x50
+#define TEGRA210_MVC_TX_INT_MASK		0x54
+#define TEGRA210_MVC_TX_INT_SET			0x58
+#define TEGRA210_MVC_TX_INT_CLEAR		0x5c
+#define TEGRA210_MVC_TX_CIF_CTRL		0x60
+
+/* Register offsets from TEGRA210_MVC*_BASE */
+#define TEGRA210_MVC_ENABLE			0x80
+#define TEGRA210_MVC_SOFT_RESET			0x84
+#define TEGRA210_MVC_CG				0x88
+#define TEGRA210_MVC_STATUS			0x90
+#define TEGRA210_MVC_INT_STATUS			0x94
+#define TEGRA210_MVC_CTRL			0xa8
+#define TEGRA210_MVC_SWITCH			0xac
+#define TEGRA210_MVC_INIT_VOL			0xb0
+#define TEGRA210_MVC_TARGET_VOL			0xd0
+#define TEGRA210_MVC_DURATION			0xf0
+#define TEGRA210_MVC_DURATION_INV		0xf4
+#define TEGRA210_MVC_POLY_N1			0xf8
+#define TEGRA210_MVC_POLY_N2			0xfc
+#define TEGRA210_MVC_PEAK_CTRL			0x100
+#define TEGRA210_MVC_CFG_RAM_CTRL		0x104
+#define TEGRA210_MVC_CFG_RAM_DATA		0x108
+#define TEGRA210_MVC_PEAK_VALUE			0x10c
+#define TEGRA210_MVC_CONFIG_ERR_TYPE		0x12c
+
+/* Fields in TEGRA210_MVC_ENABLE */
+#define TEGRA210_MVC_EN_SHIFT			0
+#define TEGRA210_MVC_EN				(1 << TEGRA210_MVC_EN_SHIFT)
+
+#define TEGRA210_MVC_MUTE_SHIFT			8
+#define TEGRA210_MUTE_MASK_EN			0xff
+#define TEGRA210_MVC_MUTE_MASK			(TEGRA210_MUTE_MASK_EN << TEGRA210_MVC_MUTE_SHIFT)
+#define TEGRA210_MVC_MUTE_EN			(TEGRA210_MUTE_MASK_EN << TEGRA210_MVC_MUTE_SHIFT)
+
+#define TEGRA210_MVC_PER_CHAN_CTRL_EN_SHIFT	30
+#define TEGRA210_MVC_PER_CHAN_CTRL_EN_MASK	(1 << TEGRA210_MVC_PER_CHAN_CTRL_EN_SHIFT)
+#define TEGRA210_MVC_PER_CHAN_CTRL_EN		(1 << TEGRA210_MVC_PER_CHAN_CTRL_EN_SHIFT)
+
+#define TEGRA210_MVC_CURVE_TYPE_SHIFT		1
+#define TEGRA210_MVC_CURVE_TYPE_MASK		(1 << TEGRA210_MVC_CURVE_TYPE_SHIFT)
+
+#define TEGRA210_MVC_VOLUME_SWITCH_SHIFT	2
+#define TEGRA210_MVC_VOLUME_SWITCH_MASK		(1 << TEGRA210_MVC_VOLUME_SWITCH_SHIFT)
+#define TEGRA210_MVC_VOLUME_SWITCH_TRIGGER	(1 << TEGRA210_MVC_VOLUME_SWITCH_SHIFT)
+#define TEGRA210_MVC_CTRL_DEFAULT	0x40000003
+
+#define TEGRA210_MVC_INIT_VOL_DEFAULT_POLY	0x01000000
+#define TEGRA210_MVC_INIT_VOL_DEFAULT_LINEAR	0x00000000
+
+/* Fields in TEGRA210_MVC ram ctrl */
+#define TEGRA210_MVC_CFG_RAM_CTRL_RW_SHIFT		14
+#define TEGRA210_MVC_CFG_RAM_CTRL_RW_WRITE		(1 << TEGRA210_MVC_CFG_RAM_CTRL_RW_SHIFT)
+
+#define TEGRA210_MVC_CFG_RAM_CTRL_ADDR_INIT_EN_SHIFT	13
+#define TEGRA210_MVC_CFG_RAM_CTRL_ADDR_INIT_EN		(1 << TEGRA210_MVC_CFG_RAM_CTRL_ADDR_INIT_EN_SHIFT)
+
+#define TEGRA210_MVC_CFG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT	12
+#define TEGRA210_MVC_CFG_RAM_CTRL_SEQ_ACCESS_EN		(1 << TEGRA210_MVC_CFG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT)
+
+#define TEGRA210_MVC_CFG_RAM_CTRL_ADDR_SHIFT		0
+#define TEGRA210_MVC_CFG_RAM_CTRL_ADDR_MASK		(0x1ff << TEGRA210_MVC_CFG_RAM_CTRL_ADDR_SHIFT)
+
+#define REG_SIZE 4
+#define TEGRA210_MVC_MAX_CHAN_COUNT 8
+#define TEGRA210_MVC_REG_OFFSET(reg, i) (reg + (REG_SIZE * i))
+
+#define NUM_GAIN_POLY_COEFFS 9
+
+enum {
+	CURVE_POLY,
+	CURVE_LINEAR,
+};
+
+struct tegra210_mvc_gain_params {
+	int poly_coeff[NUM_GAIN_POLY_COEFFS];
+	int poly_n1;
+	int poly_n2;
+	int duration;
+	int duration_inv;
+};
+
+struct tegra210_mvc {
+	int volume[TEGRA210_MVC_MAX_CHAN_COUNT];
+	unsigned int curve_type;
+	unsigned int ctrl_value;
+	struct regmap *regmap;
+};
+
+#endif
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:55 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:55 +0530
Subject: [PATCH 09/13] ASoC: tegra: Add Tegra210 based ADX driver
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-10-git-send-email-spujar@nvidia.com>

The Audio Demultiplexer (ADX) block takes an input stream with up to
16 channels and demultiplexes it into four output streams of up to 16
channels each. A byte RAM helps to form output frames by any combination
of bytes from the input frame. Its design is identical to that of byte
RAM in the AMX except that the data flow direction is reversed.

This patch registers ADX driver with ASoC framework. The component driver
exposes DAPM widgets, routes and kcontrols for the device. The DAI driver
exposes ADX interfaces, which can be used to connect different components
in the ASoC layer. Makefile and Kconfig support is added to allow build
the driver. It can be enabled in the DT via "nvidia,tegra210-adx"
compatible binding.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 sound/soc/tegra/Kconfig        |  11 +
 sound/soc/tegra/Makefile       |   2 +
 sound/soc/tegra/tegra210_adx.c | 527 +++++++++++++++++++++++++++++++++++++++++
 sound/soc/tegra/tegra210_adx.h |  72 ++++++
 4 files changed, 612 insertions(+)
 create mode 100644 sound/soc/tegra/tegra210_adx.c
 create mode 100644 sound/soc/tegra/tegra210_adx.h

diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 54d8342..fd4a8d6 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -135,6 +135,17 @@ config SND_SOC_TEGRA210_AMX
 	  output frame by any combination of bytes from the input frames.
 	  Say Y or M if you want to add support for Tegra210 AMX module.
 
+config SND_SOC_TEGRA210_ADX
+	tristate "Tegra210 ADX module"
+	help
+	  Config to enable the Audio Demultiplexer (ADX) which takes an
+	  input stream (up to 16 channels) and demultiplexes it into four
+	  output streams (each of up to 16 channels). A byte RAM helps to
+	  form output frames by any combination of bytes from the input
+	  frame. Its design is identical to that of byte RAM in the AMX
+	  except that the data flow direction is reversed.
+	  Say Y or M if you want to add support for Tegra210 ADX module.
+
 config SND_SOC_TEGRA_AUDIO_GRAPH_CARD
 	tristate "Audio Graph Card based Tegra driver"
 	depends on SND_AUDIO_GRAPH_CARD
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 549162b..8eb17ad 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -16,6 +16,7 @@ snd-soc-tegra210-admaif-objs := tegra210_admaif.o
 snd-soc-tegra210-mvc-objs := tegra210_mvc.o
 snd-soc-tegra210-sfc-objs := tegra210_sfc.o
 snd-soc-tegra210-amx-objs := tegra210_amx.o
+snd-soc-tegra210-adx-objs := tegra210_adx.o
 
 obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
 obj-$(CONFIG_SND_SOC_TEGRA20_AC97) += snd-soc-tegra20-ac97.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_SND_SOC_TEGRA210_ADMAIF) += snd-soc-tegra210-admaif.o
 obj-$(CONFIG_SND_SOC_TEGRA210_MVC) += snd-soc-tegra210-mvc.o
 obj-$(CONFIG_SND_SOC_TEGRA210_SFC) += snd-soc-tegra210-sfc.o
 obj-$(CONFIG_SND_SOC_TEGRA210_AMX) += snd-soc-tegra210-amx.o
+obj-$(CONFIG_SND_SOC_TEGRA210_ADX) += snd-soc-tegra210-adx.o
 
 # Tegra machine Support
 snd-soc-tegra-wm8903-objs := tegra_wm8903.o
diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c
new file mode 100644
index 0000000..5effafc
--- /dev/null
+++ b/sound/soc/tegra/tegra210_adx.c
@@ -0,0 +1,527 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// tegra210_adx.c - Tegra210 ADX driver
+//
+// Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "tegra210_adx.h"
+#include "tegra_cif.h"
+
+static const struct reg_default tegra210_adx_reg_defaults[] = {
+	{ TEGRA210_ADX_RX_INT_MASK, 0x00000001},
+	{ TEGRA210_ADX_RX_CIF_CTRL, 0x00007000},
+	{ TEGRA210_ADX_TX_INT_MASK, 0x0000000f },
+	{ TEGRA210_ADX_TX1_CIF_CTRL, 0x00007000},
+	{ TEGRA210_ADX_TX2_CIF_CTRL, 0x00007000},
+	{ TEGRA210_ADX_TX3_CIF_CTRL, 0x00007000},
+	{ TEGRA210_ADX_TX4_CIF_CTRL, 0x00007000},
+	{ TEGRA210_ADX_CG, 0x1},
+	{ TEGRA210_ADX_CFG_RAM_CTRL, 0x00004000},
+};
+
+static void tegra210_adx_write_map_ram(struct tegra210_adx *adx)
+{
+	int i;
+
+	regmap_write(adx->regmap, TEGRA210_ADX_CFG_RAM_CTRL,
+		     TEGRA210_ADX_CFG_RAM_CTRL_SEQ_ACCESS_EN |
+		     TEGRA210_ADX_CFG_RAM_CTRL_ADDR_INIT_EN |
+		     TEGRA210_ADX_CFG_RAM_CTRL_RW_WRITE);
+
+	for (i = 0; i < TEGRA210_ADX_RAM_DEPTH; i++)
+		regmap_write(adx->regmap, TEGRA210_ADX_CFG_RAM_DATA,
+			     adx->map[i]);
+
+	regmap_write(adx->regmap, TEGRA210_ADX_IN_BYTE_EN0, adx->byte_mask[0]);
+	regmap_write(adx->regmap, TEGRA210_ADX_IN_BYTE_EN1, adx->byte_mask[1]);
+}
+
+static int tegra210_adx_startup(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct tegra210_adx *adx = snd_soc_dai_get_drvdata(dai);
+	unsigned int val;
+	int err;
+
+	/* Ensure if ADX status is disabled */
+	err = regmap_read_poll_timeout_atomic(adx->regmap, TEGRA210_ADX_STATUS,
+					      val, !(val & 0x1), 10, 10000);
+	if (err < 0) {
+		dev_err(dai->dev, "failed to stop ADX, err = %d\n", err);
+		return err;
+	}
+
+	/* SW reset */
+	regmap_update_bits(adx->regmap, TEGRA210_ADX_SOFT_RESET,
+			   TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK,
+			   TEGRA210_ADX_SOFT_RESET_SOFT_EN);
+
+	err = regmap_read_poll_timeout(adx->regmap, TEGRA210_ADX_SOFT_RESET,
+				       val, !(val & 0x1), 10, 10000);
+	if (err < 0) {
+		dev_err(dai->dev, "failed to reset ADX, err = %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused tegra210_adx_runtime_suspend(struct device *dev)
+{
+	struct tegra210_adx *adx = dev_get_drvdata(dev);
+
+	regcache_cache_only(adx->regmap, true);
+	regcache_mark_dirty(adx->regmap);
+
+	return 0;
+}
+
+static int __maybe_unused tegra210_adx_runtime_resume(struct device *dev)
+{
+	struct tegra210_adx *adx = dev_get_drvdata(dev);
+
+	regcache_cache_only(adx->regmap, false);
+	regcache_sync(adx->regmap);
+
+	tegra210_adx_write_map_ram(adx);
+
+	return 0;
+}
+
+static int tegra210_adx_set_audio_cif(struct snd_soc_dai *dai,
+				      unsigned int channels,
+				      unsigned int format,
+				      unsigned int reg)
+{
+	struct tegra210_adx *adx = snd_soc_dai_get_drvdata(dai);
+	struct tegra_cif_conf cif_conf;
+	int audio_bits;
+
+	memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
+
+	if (channels < 1 || channels > 16)
+		return -EINVAL;
+
+	switch (format) {
+	case SNDRV_PCM_FORMAT_S8:
+		audio_bits = TEGRA_ACIF_BITS_8;
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+		audio_bits = TEGRA_ACIF_BITS_16;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		audio_bits = TEGRA_ACIF_BITS_32;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	cif_conf.audio_ch = channels;
+	cif_conf.client_ch = channels;
+	cif_conf.audio_bits = audio_bits;
+	cif_conf.client_bits = audio_bits;
+
+	tegra_set_cif(adx->regmap, reg, &cif_conf);
+
+	return 0;
+}
+
+static int tegra210_adx_out_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params,
+				      struct snd_soc_dai *dai)
+{
+	return tegra210_adx_set_audio_cif(dai, params_channels(params),
+			params_format(params),
+			TEGRA210_ADX_TX1_CIF_CTRL + ((dai->id - 1) * TEGRA210_ADX_AUDIOCIF_CH_STRIDE));
+}
+
+static int tegra210_adx_in_hw_params(struct snd_pcm_substream *substream,
+				     struct snd_pcm_hw_params *params,
+				     struct snd_soc_dai *dai)
+{
+	return tegra210_adx_set_audio_cif(dai, params_channels(params),
+					  params_format(params),
+					  TEGRA210_ADX_RX_CIF_CTRL);
+}
+
+static int tegra210_adx_get_byte_map(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_adx *adx = snd_soc_component_get_drvdata(cmpnt);
+	struct soc_mixer_control *mc;
+	unsigned char *bytes_map = (unsigned char *)&adx->map;
+	int enabled;
+
+	mc = (struct soc_mixer_control *)kcontrol->private_value;
+	enabled = adx->byte_mask[mc->reg / 32] & (1 << (mc->reg % 32));
+
+	if (enabled)
+		ucontrol->value.integer.value[0] = bytes_map[mc->reg];
+	else
+		ucontrol->value.integer.value[0] = 0;
+
+	return 0;
+}
+
+static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_adx *adx = snd_soc_component_get_drvdata(cmpnt);
+	struct soc_mixer_control *mc;
+	unsigned char *bytes_map = (unsigned char *)&adx->map;
+	int value = ucontrol->value.integer.value[0];
+
+	mc = (struct soc_mixer_control *)kcontrol->private_value;
+
+	if (value >= 0 && value <= 255) {
+		/* update byte map and enable slot */
+		bytes_map[mc->reg] = value;
+		adx->byte_mask[mc->reg / 32] |= (1 << (mc->reg % 32));
+	} else {
+		/* reset byte map and disable slot */
+		bytes_map[mc->reg] = 0;
+		adx->byte_mask[mc->reg / 32] &= ~(1 << (mc->reg % 32));
+	}
+
+	return 0;
+}
+
+static struct snd_soc_dai_ops tegra210_adx_in_dai_ops = {
+	.hw_params	= tegra210_adx_in_hw_params,
+	.startup	= tegra210_adx_startup,
+};
+
+static struct snd_soc_dai_ops tegra210_adx_out_dai_ops = {
+	.hw_params	= tegra210_adx_out_hw_params,
+};
+
+#define IN_DAI							\
+	{							\
+		.name = "ADX-RX-CIF",				\
+		.playback = {					\
+			.stream_name = "RX-CIF-Playback",	\
+			.channels_min = 1,			\
+			.channels_max = 16,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				   SNDRV_PCM_FMTBIT_S16_LE |	\
+				   SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.capture = {					\
+			.stream_name = "RX-CIF-Capture",	\
+			.channels_min = 1,			\
+			.channels_max = 16,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				   SNDRV_PCM_FMTBIT_S16_LE |	\
+				   SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.ops = &tegra210_adx_in_dai_ops,		\
+	}
+
+#define OUT_DAI(id)						\
+	{							\
+		.name = "ADX-TX" #id "-CIF",			\
+		.playback = {					\
+			.stream_name = "TX" #id "-CIF-Playback",\
+			.channels_min = 1,			\
+			.channels_max = 16,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				   SNDRV_PCM_FMTBIT_S16_LE |	\
+				   SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.capture = {					\
+			.stream_name = "TX" #id "-CIF-Capture",	\
+			.channels_min = 1,			\
+			.channels_max = 16,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				   SNDRV_PCM_FMTBIT_S16_LE |	\
+				   SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.ops = &tegra210_adx_out_dai_ops,		\
+	}
+
+static struct snd_soc_dai_driver tegra210_adx_dais[] = {
+	IN_DAI,
+	OUT_DAI(1),
+	OUT_DAI(2),
+	OUT_DAI(3),
+	OUT_DAI(4),
+};
+
+static const struct snd_soc_dapm_widget tegra210_adx_widgets[] = {
+	SND_SOC_DAPM_AIF_IN("RX", NULL, 0, TEGRA210_ADX_ENABLE,
+			    TEGRA210_ADX_ENABLE_SHIFT, 0),
+	SND_SOC_DAPM_AIF_OUT("TX1", NULL, 0, TEGRA210_ADX_CTRL, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("TX2", NULL, 0, TEGRA210_ADX_CTRL, 1, 0),
+	SND_SOC_DAPM_AIF_OUT("TX3", NULL, 0, TEGRA210_ADX_CTRL, 2, 0),
+	SND_SOC_DAPM_AIF_OUT("TX4", NULL, 0, TEGRA210_ADX_CTRL, 3, 0),
+};
+
+#define STREAM_ROUTES(id, sname)					  \
+	{ "XBAR-" sname,		NULL,	"XBAR-TX" },		  \
+	{ "RX-CIF-" sname,		NULL,	"XBAR-" sname },	  \
+	{ "RX",				NULL,	"RX-CIF-" sname },	  \
+	{ "TX" #id,			NULL,	"RX" },			  \
+	{ "TX" #id "-CIF-" sname,	NULL,	"TX" #id },		  \
+	{ "TX" #id " XBAR-" sname,	NULL,	"TX" #id "-CIF-" sname }, \
+	{ "TX" #id " XBAR-RX",		NULL,	"TX" #id " XBAR-" sname }
+
+#define ADX_ROUTES(id)			\
+	STREAM_ROUTES(id, "Playback"),	\
+	STREAM_ROUTES(id, "Capture")
+
+#define STREAM_ROUTES(id, sname)					  \
+	{ "XBAR-" sname,		NULL,	"XBAR-TX" },		  \
+	{ "RX-CIF-" sname,		NULL,	"XBAR-" sname },	  \
+	{ "RX",				NULL,	"RX-CIF-" sname },	  \
+	{ "TX" #id,			NULL,	"RX" },			  \
+	{ "TX" #id "-CIF-" sname,	NULL,	"TX" #id },		  \
+	{ "TX" #id " XBAR-" sname,	NULL,	"TX" #id "-CIF-" sname }, \
+	{ "TX" #id " XBAR-RX",		NULL,	"TX" #id " XBAR-" sname }
+
+#define ADX_ROUTES(id)			\
+	STREAM_ROUTES(id, "Playback"),	\
+	STREAM_ROUTES(id, "Capture")
+
+static const struct snd_soc_dapm_route tegra210_adx_routes[] = {
+	ADX_ROUTES(1),
+	ADX_ROUTES(2),
+	ADX_ROUTES(3),
+	ADX_ROUTES(4),
+};
+
+#define TEGRA210_ADX_BYTE_MAP_CTRL(reg)			 \
+	SOC_SINGLE_EXT("Byte Map " #reg, reg, 0, 256, 0, \
+		       tegra210_adx_get_byte_map,	 \
+		       tegra210_adx_put_byte_map)
+
+static struct snd_kcontrol_new tegra210_adx_controls[] = {
+	TEGRA210_ADX_BYTE_MAP_CTRL(0),
+	TEGRA210_ADX_BYTE_MAP_CTRL(1),
+	TEGRA210_ADX_BYTE_MAP_CTRL(2),
+	TEGRA210_ADX_BYTE_MAP_CTRL(3),
+	TEGRA210_ADX_BYTE_MAP_CTRL(4),
+	TEGRA210_ADX_BYTE_MAP_CTRL(5),
+	TEGRA210_ADX_BYTE_MAP_CTRL(6),
+	TEGRA210_ADX_BYTE_MAP_CTRL(7),
+	TEGRA210_ADX_BYTE_MAP_CTRL(8),
+	TEGRA210_ADX_BYTE_MAP_CTRL(9),
+	TEGRA210_ADX_BYTE_MAP_CTRL(10),
+	TEGRA210_ADX_BYTE_MAP_CTRL(11),
+	TEGRA210_ADX_BYTE_MAP_CTRL(12),
+	TEGRA210_ADX_BYTE_MAP_CTRL(13),
+	TEGRA210_ADX_BYTE_MAP_CTRL(14),
+	TEGRA210_ADX_BYTE_MAP_CTRL(15),
+	TEGRA210_ADX_BYTE_MAP_CTRL(16),
+	TEGRA210_ADX_BYTE_MAP_CTRL(17),
+	TEGRA210_ADX_BYTE_MAP_CTRL(18),
+	TEGRA210_ADX_BYTE_MAP_CTRL(19),
+	TEGRA210_ADX_BYTE_MAP_CTRL(20),
+	TEGRA210_ADX_BYTE_MAP_CTRL(21),
+	TEGRA210_ADX_BYTE_MAP_CTRL(22),
+	TEGRA210_ADX_BYTE_MAP_CTRL(23),
+	TEGRA210_ADX_BYTE_MAP_CTRL(24),
+	TEGRA210_ADX_BYTE_MAP_CTRL(25),
+	TEGRA210_ADX_BYTE_MAP_CTRL(26),
+	TEGRA210_ADX_BYTE_MAP_CTRL(27),
+	TEGRA210_ADX_BYTE_MAP_CTRL(28),
+	TEGRA210_ADX_BYTE_MAP_CTRL(29),
+	TEGRA210_ADX_BYTE_MAP_CTRL(30),
+	TEGRA210_ADX_BYTE_MAP_CTRL(31),
+	TEGRA210_ADX_BYTE_MAP_CTRL(32),
+	TEGRA210_ADX_BYTE_MAP_CTRL(33),
+	TEGRA210_ADX_BYTE_MAP_CTRL(34),
+	TEGRA210_ADX_BYTE_MAP_CTRL(35),
+	TEGRA210_ADX_BYTE_MAP_CTRL(36),
+	TEGRA210_ADX_BYTE_MAP_CTRL(37),
+	TEGRA210_ADX_BYTE_MAP_CTRL(38),
+	TEGRA210_ADX_BYTE_MAP_CTRL(39),
+	TEGRA210_ADX_BYTE_MAP_CTRL(40),
+	TEGRA210_ADX_BYTE_MAP_CTRL(41),
+	TEGRA210_ADX_BYTE_MAP_CTRL(42),
+	TEGRA210_ADX_BYTE_MAP_CTRL(43),
+	TEGRA210_ADX_BYTE_MAP_CTRL(44),
+	TEGRA210_ADX_BYTE_MAP_CTRL(45),
+	TEGRA210_ADX_BYTE_MAP_CTRL(46),
+	TEGRA210_ADX_BYTE_MAP_CTRL(47),
+	TEGRA210_ADX_BYTE_MAP_CTRL(48),
+	TEGRA210_ADX_BYTE_MAP_CTRL(49),
+	TEGRA210_ADX_BYTE_MAP_CTRL(50),
+	TEGRA210_ADX_BYTE_MAP_CTRL(51),
+	TEGRA210_ADX_BYTE_MAP_CTRL(52),
+	TEGRA210_ADX_BYTE_MAP_CTRL(53),
+	TEGRA210_ADX_BYTE_MAP_CTRL(54),
+	TEGRA210_ADX_BYTE_MAP_CTRL(55),
+	TEGRA210_ADX_BYTE_MAP_CTRL(56),
+	TEGRA210_ADX_BYTE_MAP_CTRL(57),
+	TEGRA210_ADX_BYTE_MAP_CTRL(58),
+	TEGRA210_ADX_BYTE_MAP_CTRL(59),
+	TEGRA210_ADX_BYTE_MAP_CTRL(60),
+	TEGRA210_ADX_BYTE_MAP_CTRL(61),
+	TEGRA210_ADX_BYTE_MAP_CTRL(62),
+	TEGRA210_ADX_BYTE_MAP_CTRL(63),
+};
+
+static const struct snd_soc_component_driver tegra210_adx_cmpnt = {
+	.dapm_widgets		= tegra210_adx_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tegra210_adx_widgets),
+	.dapm_routes		= tegra210_adx_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tegra210_adx_routes),
+	.controls		= tegra210_adx_controls,
+	.num_controls		= ARRAY_SIZE(tegra210_adx_controls),
+};
+
+static bool tegra210_adx_wr_reg(struct device *dev,
+				unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_ADX_TX_INT_MASK ... TEGRA210_ADX_TX4_CIF_CTRL:
+	case TEGRA210_ADX_RX_INT_MASK ... TEGRA210_ADX_RX_CIF_CTRL:
+	case TEGRA210_ADX_ENABLE ... TEGRA210_ADX_CG:
+	case TEGRA210_ADX_CTRL ... TEGRA210_ADX_IN_BYTE_EN1:
+	case TEGRA210_ADX_CFG_RAM_CTRL ... TEGRA210_ADX_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_adx_rd_reg(struct device *dev,
+				unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_ADX_RX_STATUS ... TEGRA210_ADX_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_adx_volatile_reg(struct device *dev,
+				unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_ADX_RX_STATUS:
+	case TEGRA210_ADX_RX_INT_STATUS:
+	case TEGRA210_ADX_RX_INT_SET:
+	case TEGRA210_ADX_TX_STATUS:
+	case TEGRA210_ADX_TX_INT_STATUS:
+	case TEGRA210_ADX_TX_INT_SET:
+	case TEGRA210_ADX_SOFT_RESET:
+	case TEGRA210_ADX_STATUS:
+	case TEGRA210_ADX_INT_STATUS:
+	case TEGRA210_ADX_CFG_RAM_CTRL:
+	case TEGRA210_ADX_CFG_RAM_DATA:
+		return true;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+static const struct regmap_config tegra210_adx_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+	.max_register		= TEGRA210_ADX_CFG_RAM_DATA,
+	.writeable_reg		= tegra210_adx_wr_reg,
+	.readable_reg		= tegra210_adx_rd_reg,
+	.volatile_reg		= tegra210_adx_volatile_reg,
+	.reg_defaults		= tegra210_adx_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(tegra210_adx_reg_defaults),
+	.cache_type		= REGCACHE_FLAT,
+};
+
+static const struct of_device_id tegra210_adx_of_match[] = {
+	{ .compatible = "nvidia,tegra210-adx" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, tegra210_adx_of_match);
+
+static int tegra210_adx_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct tegra210_adx *adx;
+	void __iomem *regs;
+	int err;
+
+	adx = devm_kzalloc(dev, sizeof(*adx), GFP_KERNEL);
+	if (!adx)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, adx);
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	adx->regmap = devm_regmap_init_mmio(dev, regs,
+					    &tegra210_adx_regmap_config);
+	if (IS_ERR(adx->regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(adx->regmap);
+	}
+
+	regcache_cache_only(adx->regmap, true);
+
+	err = devm_snd_soc_register_component(dev, &tegra210_adx_cmpnt,
+					      tegra210_adx_dais,
+					      ARRAY_SIZE(tegra210_adx_dais));
+	if (err) {
+		dev_err(dev, "can't register ADX component, err: %d\n", err);
+		return err;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+}
+
+static int tegra210_adx_platform_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct dev_pm_ops tegra210_adx_pm_ops = {
+	SET_RUNTIME_PM_OPS(tegra210_adx_runtime_suspend,
+			   tegra210_adx_runtime_resume, NULL)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
+};
+
+static struct platform_driver tegra210_adx_driver = {
+	.driver = {
+		.name = "tegra210-adx",
+		.of_match_table = tegra210_adx_of_match,
+		.pm = &tegra210_adx_pm_ops,
+	},
+	.probe = tegra210_adx_platform_probe,
+	.remove = tegra210_adx_platform_remove,
+};
+module_platform_driver(tegra210_adx_driver);
+
+MODULE_AUTHOR("Arun Shamanna Lakshmi <aruns at nvidia.com>");
+MODULE_DESCRIPTION("Tegra210 ADX ASoC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/tegra/tegra210_adx.h b/sound/soc/tegra/tegra210_adx.h
new file mode 100644
index 0000000..d7dcb64
--- /dev/null
+++ b/sound/soc/tegra/tegra210_adx.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * tegra210_adx.h - Definitions for Tegra210 ADX driver
+ *
+ * Copyright (c) 2021, NVIDIA CORPORATION.  All rights reserved.
+ *
+ */
+
+#ifndef __TEGRA210_ADX_H__
+#define __TEGRA210_ADX_H__
+
+/* Register offsets from TEGRA210_ADX*_BASE */
+#define TEGRA210_ADX_RX_STATUS		0x0c
+#define TEGRA210_ADX_RX_INT_STATUS	0x10
+#define TEGRA210_ADX_RX_INT_MASK	0x14
+#define TEGRA210_ADX_RX_INT_SET		0x18
+#define TEGRA210_ADX_RX_INT_CLEAR	0x1c
+#define TEGRA210_ADX_RX_CIF_CTRL	0x20
+#define TEGRA210_ADX_TX_STATUS		0x4c
+#define TEGRA210_ADX_TX_INT_STATUS	0x50
+#define TEGRA210_ADX_TX_INT_MASK	0x54
+#define TEGRA210_ADX_TX_INT_SET		0x58
+#define TEGRA210_ADX_TX_INT_CLEAR	0x5c
+#define TEGRA210_ADX_TX1_CIF_CTRL	0x60
+#define TEGRA210_ADX_TX2_CIF_CTRL	0x64
+#define TEGRA210_ADX_TX3_CIF_CTRL	0x68
+#define TEGRA210_ADX_TX4_CIF_CTRL	0x6c
+#define TEGRA210_ADX_ENABLE		0x80
+#define TEGRA210_ADX_SOFT_RESET		0x84
+#define TEGRA210_ADX_CG			0x88
+#define TEGRA210_ADX_STATUS		0x8c
+#define TEGRA210_ADX_INT_STATUS		0x90
+#define TEGRA210_ADX_CTRL		0xa4
+#define TEGRA210_ADX_IN_BYTE_EN0	0xa8
+#define TEGRA210_ADX_IN_BYTE_EN1	0xac
+#define TEGRA210_ADX_CFG_RAM_CTRL	0xb8
+#define TEGRA210_ADX_CFG_RAM_DATA	0xbc
+
+/* Fields in TEGRA210_ADX_ENABLE */
+#define TEGRA210_ADX_ENABLE_SHIFT			0
+
+/* Fields in TEGRA210_ADX_CFG_RAM_CTRL */
+#define TEGRA210_ADX_CFG_RAM_CTRL_RAM_ADDR_SHIFT	0
+
+#define TEGRA210_ADX_CFG_RAM_CTRL_RW_SHIFT		14
+#define TEGRA210_ADX_CFG_RAM_CTRL_RW_WRITE		(1 << TEGRA210_ADX_CFG_RAM_CTRL_RW_SHIFT)
+
+#define TEGRA210_ADX_CFG_RAM_CTRL_ADDR_INIT_EN_SHIFT	13
+#define TEGRA210_ADX_CFG_RAM_CTRL_ADDR_INIT_EN		(1 << TEGRA210_ADX_CFG_RAM_CTRL_ADDR_INIT_EN_SHIFT)
+
+#define TEGRA210_ADX_CFG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT	12
+#define TEGRA210_ADX_CFG_RAM_CTRL_SEQ_ACCESS_EN		(1 << TEGRA210_ADX_CFG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT)
+
+/* Fields in TEGRA210_ADX_SOFT_RESET */
+#define TEGRA210_ADX_SOFT_RESET_SOFT_RESET_SHIFT	0
+#define TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK		(1 << TEGRA210_ADX_SOFT_RESET_SOFT_RESET_SHIFT)
+#define TEGRA210_ADX_SOFT_RESET_SOFT_EN			(1 << TEGRA210_ADX_SOFT_RESET_SOFT_RESET_SHIFT)
+#define TEGRA210_ADX_SOFT_RESET_SOFT_DEFAULT		(0 << TEGRA210_ADX_SOFT_RESET_SOFT_RESET_SHIFT)
+
+#define TEGRA210_ADX_AUDIOCIF_CH_STRIDE		4
+#define TEGRA210_ADX_RAM_DEPTH			16
+#define TEGRA210_ADX_MAP_STREAM_NUMBER_SHIFT	6
+#define TEGRA210_ADX_MAP_WORD_NUMBER_SHIFT	2
+#define TEGRA210_ADX_MAP_BYTE_NUMBER_SHIFT	0
+
+struct tegra210_adx {
+	struct regmap *regmap;
+	unsigned int map[TEGRA210_ADX_RAM_DEPTH];
+	unsigned int byte_mask[2];
+};
+
+#endif
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:54 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:54 +0530
Subject: [PATCH 08/13] ASoC: tegra: Add Tegra210 based AMX driver
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-9-git-send-email-spujar@nvidia.com>

The Audio Multiplexer (AMX) block can multiplex up to four input streams
each of which can have maximum 16 channels and generate an output stream
with maximum 16 channels. A byte RAM helps to form an output frame by
any combination of bytes from the input frames.

This patch registers AMX driver with ASoC framework. The component driver
exposes DAPM widgets, routes and kcontrols for the device. The DAI driver
exposes AMX interfaces, which can be used to connect different components
in the ASoC layer. Makefile and Kconfig support is added to allow build
the driver. It can be enabled in the DT via "nvidia,tegra210-amx" for
Tegra210 and Tegra186. For Tegra194 and later, "nvidia,tegra194-amx" can
be used.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 sound/soc/tegra/Kconfig        |   9 +
 sound/soc/tegra/Makefile       |   2 +
 sound/soc/tegra/tegra210_amx.c | 595 +++++++++++++++++++++++++++++++++++++++++
 sound/soc/tegra/tegra210_amx.h |  93 +++++++
 4 files changed, 699 insertions(+)
 create mode 100644 sound/soc/tegra/tegra210_amx.c
 create mode 100644 sound/soc/tegra/tegra210_amx.h

diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 102564e..54d8342 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -126,6 +126,15 @@ config SND_SOC_TEGRA210_SFC
 	  upto 2 channels (stereo).
 	  Say Y or M if you want to add support for Tegra210 SFC module.
 
+config SND_SOC_TEGRA210_AMX
+	tristate "Tegra210 AMX module"
+	help
+	  Config to enable the Audio Multiplexer (AMX) which can multiplex
+	  four input streams (each of up to 16 channels) and generate
+	  output stream (of up to 16 channels). A byte RAM helps to form an
+	  output frame by any combination of bytes from the input frames.
+	  Say Y or M if you want to add support for Tegra210 AMX module.
+
 config SND_SOC_TEGRA_AUDIO_GRAPH_CARD
 	tristate "Audio Graph Card based Tegra driver"
 	depends on SND_AUDIO_GRAPH_CARD
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index bb0cf3a..549162b 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -15,6 +15,7 @@ snd-soc-tegra186-dspk-objs := tegra186_dspk.o
 snd-soc-tegra210-admaif-objs := tegra210_admaif.o
 snd-soc-tegra210-mvc-objs := tegra210_mvc.o
 snd-soc-tegra210-sfc-objs := tegra210_sfc.o
+snd-soc-tegra210-amx-objs := tegra210_amx.o
 
 obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
 obj-$(CONFIG_SND_SOC_TEGRA20_AC97) += snd-soc-tegra20-ac97.o
@@ -30,6 +31,7 @@ obj-$(CONFIG_SND_SOC_TEGRA186_DSPK) += snd-soc-tegra186-dspk.o
 obj-$(CONFIG_SND_SOC_TEGRA210_ADMAIF) += snd-soc-tegra210-admaif.o
 obj-$(CONFIG_SND_SOC_TEGRA210_MVC) += snd-soc-tegra210-mvc.o
 obj-$(CONFIG_SND_SOC_TEGRA210_SFC) += snd-soc-tegra210-sfc.o
+obj-$(CONFIG_SND_SOC_TEGRA210_AMX) += snd-soc-tegra210-amx.o
 
 # Tegra machine Support
 snd-soc-tegra-wm8903-objs := tegra_wm8903.o
diff --git a/sound/soc/tegra/tegra210_amx.c b/sound/soc/tegra/tegra210_amx.c
new file mode 100644
index 0000000..a6aa4f5
--- /dev/null
+++ b/sound/soc/tegra/tegra210_amx.c
@@ -0,0 +1,595 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// tegra210_amx.c - Tegra210 AMX driver
+//
+// Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "tegra210_amx.h"
+#include "tegra_cif.h"
+
+/*
+ * The counter is in terms of AHUB clock cycles. If a frame is not
+ * received within these clock cycles, the AMX input channel gets
+ * automatically disabled. For now the counter is calculated as a
+ * function of sample rate (8 kHz) and AHUB clock (49.152 MHz).
+ * If later an accurate number is needed, the counter needs to be
+ * calculated at runtime.
+ *
+ *     count = ahub_clk / sample_rate
+ */
+#define TEGRA194_MAX_FRAME_IDLE_COUNT	0x1800
+
+#define AMX_CH_REG(id, reg) ((reg) + ((id) * TEGRA210_AMX_AUDIOCIF_CH_STRIDE))
+
+static const struct reg_default tegra210_amx_reg_defaults[] = {
+	{ TEGRA210_AMX_RX_INT_MASK, 0x0000000f},
+	{ TEGRA210_AMX_RX1_CIF_CTRL, 0x00007000},
+	{ TEGRA210_AMX_RX2_CIF_CTRL, 0x00007000},
+	{ TEGRA210_AMX_RX3_CIF_CTRL, 0x00007000},
+	{ TEGRA210_AMX_RX4_CIF_CTRL, 0x00007000},
+	{ TEGRA210_AMX_TX_INT_MASK, 0x00000001},
+	{ TEGRA210_AMX_TX_CIF_CTRL, 0x00007000},
+	{ TEGRA210_AMX_CG, 0x1},
+	{ TEGRA210_AMX_CFG_RAM_CTRL, 0x00004000},
+};
+
+static void tegra210_amx_write_map_ram(struct tegra210_amx *amx)
+{
+	int i;
+
+	regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_CTRL,
+		     TEGRA210_AMX_CFG_RAM_CTRL_SEQ_ACCESS_EN |
+		     TEGRA210_AMX_CFG_RAM_CTRL_ADDR_INIT_EN |
+		     TEGRA210_AMX_CFG_RAM_CTRL_RW_WRITE);
+
+	for (i = 0; i < TEGRA210_AMX_RAM_DEPTH; i++)
+		regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_DATA,
+			     amx->map[i]);
+
+	regmap_write(amx->regmap, TEGRA210_AMX_OUT_BYTE_EN0, amx->byte_mask[0]);
+	regmap_write(amx->regmap, TEGRA210_AMX_OUT_BYTE_EN1, amx->byte_mask[1]);
+}
+
+static int tegra210_amx_startup(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct tegra210_amx *amx = snd_soc_dai_get_drvdata(dai);
+	unsigned int val;
+	int err;
+
+	/* Ensure if AMX is disabled */
+	err = regmap_read_poll_timeout(amx->regmap, TEGRA210_AMX_STATUS, val,
+				       !(val & 0x1), 10, 10000);
+	if (err < 0) {
+		dev_err(dai->dev, "failed to stop AMX, err = %d\n", err);
+		return err;
+	}
+
+	/* SW reset */
+	regmap_update_bits(amx->regmap, TEGRA210_AMX_SOFT_RESET,
+			   TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK,
+			   TEGRA210_AMX_SOFT_RESET_SOFT_EN);
+
+	err = regmap_read_poll_timeout(amx->regmap, TEGRA210_AMX_SOFT_RESET,
+				       val, !(val & 0x1), 10, 10000);
+	if (err < 0) {
+		dev_err(dai->dev, "failed to reset AMX, err = %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused tegra210_amx_runtime_suspend(struct device *dev)
+{
+	struct tegra210_amx *amx = dev_get_drvdata(dev);
+
+	regcache_cache_only(amx->regmap, true);
+	regcache_mark_dirty(amx->regmap);
+
+	return 0;
+}
+
+static int __maybe_unused tegra210_amx_runtime_resume(struct device *dev)
+{
+	struct tegra210_amx *amx = dev_get_drvdata(dev);
+
+	regcache_cache_only(amx->regmap, false);
+	regcache_sync(amx->regmap);
+
+	regmap_update_bits(amx->regmap,
+		TEGRA210_AMX_CTRL,
+		TEGRA210_AMX_CTRL_RX_DEP_MASK,
+		TEGRA210_AMX_WAIT_ON_ANY << TEGRA210_AMX_CTRL_RX_DEP_SHIFT);
+
+	tegra210_amx_write_map_ram(amx);
+
+	return 0;
+}
+
+static int tegra210_amx_set_audio_cif(struct snd_soc_dai *dai,
+				      struct snd_pcm_hw_params *params,
+				      unsigned int reg)
+{
+	struct tegra210_amx *amx = snd_soc_dai_get_drvdata(dai);
+	int channels, audio_bits;
+	struct tegra_cif_conf cif_conf;
+
+	memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
+
+	channels = params_channels(params);
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S8:
+		audio_bits = TEGRA_ACIF_BITS_8;
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+		audio_bits = TEGRA_ACIF_BITS_16;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		audio_bits = TEGRA_ACIF_BITS_32;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	cif_conf.audio_ch = channels;
+	cif_conf.client_ch = channels;
+	cif_conf.audio_bits = audio_bits;
+	cif_conf.client_bits = audio_bits;
+
+	tegra_set_cif(amx->regmap, reg, &cif_conf);
+
+	return 0;
+}
+
+static int tegra210_amx_in_hw_params(struct snd_pcm_substream *substream,
+				     struct snd_pcm_hw_params *params,
+				     struct snd_soc_dai *dai)
+{
+	struct tegra210_amx *amx = snd_soc_dai_get_drvdata(dai);
+
+	if (amx->soc_data->auto_disable) {
+		regmap_write(amx->regmap,
+			     AMX_CH_REG(dai->id, TEGRA194_AMX_RX1_FRAME_PERIOD),
+			     TEGRA194_MAX_FRAME_IDLE_COUNT);
+		regmap_write(amx->regmap, TEGRA210_AMX_CYA, 1);
+	}
+
+	return tegra210_amx_set_audio_cif(dai, params,
+			AMX_CH_REG(dai->id, TEGRA210_AMX_RX1_CIF_CTRL));
+}
+
+static int tegra210_amx_out_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params,
+				      struct snd_soc_dai *dai)
+{
+	return tegra210_amx_set_audio_cif(dai, params,
+					  TEGRA210_AMX_TX_CIF_CTRL);
+}
+
+static int tegra210_amx_get_byte_map(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct tegra210_amx *amx = snd_soc_component_get_drvdata(cmpnt);
+	unsigned char *bytes_map = (unsigned char *)&amx->map;
+	int reg = mc->reg;
+	int enabled;
+
+	if (reg > 31)
+		enabled = amx->byte_mask[1] & (1 << (reg - 32));
+	else
+		enabled = amx->byte_mask[0] & (1 << reg);
+
+	if (enabled)
+		ucontrol->value.integer.value[0] = bytes_map[reg];
+	else
+		ucontrol->value.integer.value[0] = 0;
+
+	return 0;
+}
+
+static int tegra210_amx_put_byte_map(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_amx *amx = snd_soc_component_get_drvdata(cmpnt);
+	unsigned char *bytes_map = (unsigned char *)&amx->map;
+	int reg = mc->reg;
+	int value = ucontrol->value.integer.value[0];
+
+	if (value >= 0 && value <= 255) {
+		/* Update byte map and enable slot */
+		bytes_map[reg] = value;
+		if (reg > 31)
+			amx->byte_mask[1] |= (1 << (reg - 32));
+		else
+			amx->byte_mask[0] |= (1 << reg);
+	} else {
+		/* Reset byte map and disable slot */
+		bytes_map[reg] = 0;
+		if (reg > 31)
+			amx->byte_mask[1] &= ~(1 << (reg - 32));
+		else
+			amx->byte_mask[0] &= ~(1 << reg);
+	}
+
+	return 0;
+}
+
+static struct snd_soc_dai_ops tegra210_amx_out_dai_ops = {
+	.hw_params	= tegra210_amx_out_hw_params,
+	.startup	= tegra210_amx_startup,
+};
+
+static struct snd_soc_dai_ops tegra210_amx_in_dai_ops = {
+	.hw_params	= tegra210_amx_in_hw_params,
+};
+
+#define IN_DAI(id)						\
+	{							\
+		.name = "AMX-RX-CIF" #id,			\
+		.playback = {					\
+			.stream_name = "RX" #id "-CIF-Playback",\
+			.channels_min = 1,			\
+			.channels_max = 16,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				   SNDRV_PCM_FMTBIT_S16_LE |	\
+				   SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.capture = {					\
+			.stream_name = "RX" #id "-CIF-Capture",	\
+			.channels_min = 1,			\
+			.channels_max = 16,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				   SNDRV_PCM_FMTBIT_S16_LE |	\
+				   SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.ops = &tegra210_amx_in_dai_ops,		\
+	}
+
+#define OUT_DAI							\
+	{							\
+		.name = "AMX-TX-CIF",				\
+		.playback = {					\
+			.stream_name = "TX-CIF-Playback",	\
+			.channels_min = 1,			\
+			.channels_max = 16,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				   SNDRV_PCM_FMTBIT_S16_LE |	\
+				   SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.capture = {					\
+			.stream_name = "TX-CIF-Capture",	\
+			.channels_min = 1,			\
+			.channels_max = 16,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				   SNDRV_PCM_FMTBIT_S16_LE |	\
+				   SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.ops = &tegra210_amx_out_dai_ops,		\
+	}
+
+static struct snd_soc_dai_driver tegra210_amx_dais[] = {
+	IN_DAI(1),
+	IN_DAI(2),
+	IN_DAI(3),
+	IN_DAI(4),
+	OUT_DAI,
+};
+
+static const struct snd_soc_dapm_widget tegra210_amx_widgets[] = {
+	SND_SOC_DAPM_AIF_IN("RX1", NULL, 0, TEGRA210_AMX_CTRL, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX2", NULL, 0, TEGRA210_AMX_CTRL, 1, 0),
+	SND_SOC_DAPM_AIF_IN("RX3", NULL, 0, TEGRA210_AMX_CTRL, 2, 0),
+	SND_SOC_DAPM_AIF_IN("RX4", NULL, 0, TEGRA210_AMX_CTRL, 3, 0),
+	SND_SOC_DAPM_AIF_OUT("TX", NULL, 0, TEGRA210_AMX_ENABLE,
+			     TEGRA210_AMX_ENABLE_SHIFT, 0),
+};
+
+#define STREAM_ROUTES(id, sname)					  \
+	{ "RX" #id " XBAR-" sname,	NULL,	"RX" #id " XBAR-TX" },	  \
+	{ "RX" #id "-CIF-" sname,	NULL,	"RX" #id " XBAR-" sname },\
+	{ "RX" #id,			NULL,	"RX" #id "-CIF-" sname }, \
+	{ "TX",				NULL,	"RX" #id },		  \
+	{ "TX-CIF-" sname,		NULL,	"TX" },			  \
+	{ "XBAR-" sname,		NULL,	"TX-CIF-" sname },	  \
+	{ "XBAR-RX",			NULL,	"XBAR-" sname }
+
+#define AMX_ROUTES(id)			\
+	STREAM_ROUTES(id, "Playback"),	\
+	STREAM_ROUTES(id, "Capture")
+
+static const struct snd_soc_dapm_route tegra210_amx_routes[] = {
+	AMX_ROUTES(1),
+	AMX_ROUTES(2),
+	AMX_ROUTES(3),
+	AMX_ROUTES(4),
+};
+
+#define TEGRA210_AMX_BYTE_MAP_CTRL(reg)					\
+	SOC_SINGLE_EXT("Byte Map " #reg, reg, 0, 256, 0,		\
+		       tegra210_amx_get_byte_map,			\
+		       tegra210_amx_put_byte_map)
+
+static struct snd_kcontrol_new tegra210_amx_controls[] = {
+	TEGRA210_AMX_BYTE_MAP_CTRL(0),
+	TEGRA210_AMX_BYTE_MAP_CTRL(1),
+	TEGRA210_AMX_BYTE_MAP_CTRL(2),
+	TEGRA210_AMX_BYTE_MAP_CTRL(3),
+	TEGRA210_AMX_BYTE_MAP_CTRL(4),
+	TEGRA210_AMX_BYTE_MAP_CTRL(5),
+	TEGRA210_AMX_BYTE_MAP_CTRL(6),
+	TEGRA210_AMX_BYTE_MAP_CTRL(7),
+	TEGRA210_AMX_BYTE_MAP_CTRL(8),
+	TEGRA210_AMX_BYTE_MAP_CTRL(9),
+	TEGRA210_AMX_BYTE_MAP_CTRL(10),
+	TEGRA210_AMX_BYTE_MAP_CTRL(11),
+	TEGRA210_AMX_BYTE_MAP_CTRL(12),
+	TEGRA210_AMX_BYTE_MAP_CTRL(13),
+	TEGRA210_AMX_BYTE_MAP_CTRL(14),
+	TEGRA210_AMX_BYTE_MAP_CTRL(15),
+	TEGRA210_AMX_BYTE_MAP_CTRL(16),
+	TEGRA210_AMX_BYTE_MAP_CTRL(17),
+	TEGRA210_AMX_BYTE_MAP_CTRL(18),
+	TEGRA210_AMX_BYTE_MAP_CTRL(19),
+	TEGRA210_AMX_BYTE_MAP_CTRL(20),
+	TEGRA210_AMX_BYTE_MAP_CTRL(21),
+	TEGRA210_AMX_BYTE_MAP_CTRL(22),
+	TEGRA210_AMX_BYTE_MAP_CTRL(23),
+	TEGRA210_AMX_BYTE_MAP_CTRL(24),
+	TEGRA210_AMX_BYTE_MAP_CTRL(25),
+	TEGRA210_AMX_BYTE_MAP_CTRL(26),
+	TEGRA210_AMX_BYTE_MAP_CTRL(27),
+	TEGRA210_AMX_BYTE_MAP_CTRL(28),
+	TEGRA210_AMX_BYTE_MAP_CTRL(29),
+	TEGRA210_AMX_BYTE_MAP_CTRL(30),
+	TEGRA210_AMX_BYTE_MAP_CTRL(31),
+	TEGRA210_AMX_BYTE_MAP_CTRL(32),
+	TEGRA210_AMX_BYTE_MAP_CTRL(33),
+	TEGRA210_AMX_BYTE_MAP_CTRL(34),
+	TEGRA210_AMX_BYTE_MAP_CTRL(35),
+	TEGRA210_AMX_BYTE_MAP_CTRL(36),
+	TEGRA210_AMX_BYTE_MAP_CTRL(37),
+	TEGRA210_AMX_BYTE_MAP_CTRL(38),
+	TEGRA210_AMX_BYTE_MAP_CTRL(39),
+	TEGRA210_AMX_BYTE_MAP_CTRL(40),
+	TEGRA210_AMX_BYTE_MAP_CTRL(41),
+	TEGRA210_AMX_BYTE_MAP_CTRL(42),
+	TEGRA210_AMX_BYTE_MAP_CTRL(43),
+	TEGRA210_AMX_BYTE_MAP_CTRL(44),
+	TEGRA210_AMX_BYTE_MAP_CTRL(45),
+	TEGRA210_AMX_BYTE_MAP_CTRL(46),
+	TEGRA210_AMX_BYTE_MAP_CTRL(47),
+	TEGRA210_AMX_BYTE_MAP_CTRL(48),
+	TEGRA210_AMX_BYTE_MAP_CTRL(49),
+	TEGRA210_AMX_BYTE_MAP_CTRL(50),
+	TEGRA210_AMX_BYTE_MAP_CTRL(51),
+	TEGRA210_AMX_BYTE_MAP_CTRL(52),
+	TEGRA210_AMX_BYTE_MAP_CTRL(53),
+	TEGRA210_AMX_BYTE_MAP_CTRL(54),
+	TEGRA210_AMX_BYTE_MAP_CTRL(55),
+	TEGRA210_AMX_BYTE_MAP_CTRL(56),
+	TEGRA210_AMX_BYTE_MAP_CTRL(57),
+	TEGRA210_AMX_BYTE_MAP_CTRL(58),
+	TEGRA210_AMX_BYTE_MAP_CTRL(59),
+	TEGRA210_AMX_BYTE_MAP_CTRL(60),
+	TEGRA210_AMX_BYTE_MAP_CTRL(61),
+	TEGRA210_AMX_BYTE_MAP_CTRL(62),
+	TEGRA210_AMX_BYTE_MAP_CTRL(63),
+};
+
+static const struct snd_soc_component_driver tegra210_amx_cmpnt = {
+	.dapm_widgets		= tegra210_amx_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tegra210_amx_widgets),
+	.dapm_routes		= tegra210_amx_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tegra210_amx_routes),
+	.controls		= tegra210_amx_controls,
+	.num_controls		= ARRAY_SIZE(tegra210_amx_controls),
+};
+
+static bool tegra210_amx_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_AMX_RX_INT_MASK ... TEGRA210_AMX_RX4_CIF_CTRL:
+	case TEGRA210_AMX_TX_INT_MASK ... TEGRA210_AMX_CG:
+	case TEGRA210_AMX_CTRL ... TEGRA210_AMX_CYA:
+	case TEGRA210_AMX_CFG_RAM_CTRL ... TEGRA210_AMX_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra194_amx_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA194_AMX_RX1_FRAME_PERIOD ... TEGRA194_AMX_RX4_FRAME_PERIOD:
+		return true;
+	default:
+		return tegra210_amx_wr_reg(dev, reg);
+	}
+}
+
+static bool tegra210_amx_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_AMX_RX_STATUS ... TEGRA210_AMX_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra194_amx_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA194_AMX_RX1_FRAME_PERIOD ... TEGRA194_AMX_RX4_FRAME_PERIOD:
+		return true;
+	default:
+		return tegra210_amx_rd_reg(dev, reg);
+	}
+}
+
+static bool tegra210_amx_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_AMX_RX_STATUS:
+	case TEGRA210_AMX_RX_INT_STATUS:
+	case TEGRA210_AMX_RX_INT_SET:
+	case TEGRA210_AMX_TX_STATUS:
+	case TEGRA210_AMX_TX_INT_STATUS:
+	case TEGRA210_AMX_TX_INT_SET:
+	case TEGRA210_AMX_SOFT_RESET:
+	case TEGRA210_AMX_STATUS:
+	case TEGRA210_AMX_INT_STATUS:
+	case TEGRA210_AMX_CFG_RAM_CTRL:
+	case TEGRA210_AMX_CFG_RAM_DATA:
+		return true;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+static const struct regmap_config tegra210_amx_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+	.max_register		= TEGRA210_AMX_CFG_RAM_DATA,
+	.writeable_reg		= tegra210_amx_wr_reg,
+	.readable_reg		= tegra210_amx_rd_reg,
+	.volatile_reg		= tegra210_amx_volatile_reg,
+	.reg_defaults		= tegra210_amx_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(tegra210_amx_reg_defaults),
+	.cache_type		= REGCACHE_FLAT,
+};
+
+static const struct regmap_config tegra194_amx_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+	.max_register		= TEGRA194_AMX_RX4_LAST_FRAME_PERIOD,
+	.writeable_reg		= tegra194_amx_wr_reg,
+	.readable_reg		= tegra194_amx_rd_reg,
+	.volatile_reg		= tegra210_amx_volatile_reg,
+	.reg_defaults		= tegra210_amx_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(tegra210_amx_reg_defaults),
+	.cache_type		= REGCACHE_FLAT,
+};
+
+static const struct tegra210_amx_soc_data soc_data_tegra210 = {
+	.regmap_conf	= &tegra210_amx_regmap_config,
+};
+
+static const struct tegra210_amx_soc_data soc_data_tegra194 = {
+	.regmap_conf	= &tegra194_amx_regmap_config,
+	.auto_disable	= true,
+};
+
+static const struct of_device_id tegra210_amx_of_match[] = {
+	{ .compatible = "nvidia,tegra210-amx", .data = &soc_data_tegra210 },
+	{ .compatible = "nvidia,tegra194-amx", .data = &soc_data_tegra194 },
+	{},
+};
+MODULE_DEVICE_TABLE(of, tegra210_amx_of_match);
+
+static int tegra210_amx_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct tegra210_amx *amx;
+	void __iomem *regs;
+	int err;
+	const struct of_device_id *match;
+	struct tegra210_amx_soc_data *soc_data;
+
+	match = of_match_device(tegra210_amx_of_match, dev);
+
+	soc_data = (struct tegra210_amx_soc_data *)match->data;
+
+	amx = devm_kzalloc(dev, sizeof(*amx), GFP_KERNEL);
+	if (!amx)
+		return -ENOMEM;
+
+	amx->soc_data = soc_data;
+
+	dev_set_drvdata(dev, amx);
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	amx->regmap = devm_regmap_init_mmio(dev, regs,
+					    soc_data->regmap_conf);
+	if (IS_ERR(amx->regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(amx->regmap);
+	}
+
+	regcache_cache_only(amx->regmap, true);
+
+	err = devm_snd_soc_register_component(dev, &tegra210_amx_cmpnt,
+					      tegra210_amx_dais,
+					      ARRAY_SIZE(tegra210_amx_dais));
+	if (err) {
+		dev_err(dev, "can't register AMX component, err: %d\n", err);
+		return err;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+}
+
+static int tegra210_amx_platform_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct dev_pm_ops tegra210_amx_pm_ops = {
+	SET_RUNTIME_PM_OPS(tegra210_amx_runtime_suspend,
+			   tegra210_amx_runtime_resume, NULL)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
+};
+
+static struct platform_driver tegra210_amx_driver = {
+	.driver = {
+		.name = "tegra210-amx",
+		.of_match_table = tegra210_amx_of_match,
+		.pm = &tegra210_amx_pm_ops,
+	},
+	.probe = tegra210_amx_platform_probe,
+	.remove = tegra210_amx_platform_remove,
+};
+module_platform_driver(tegra210_amx_driver);
+
+MODULE_AUTHOR("Songhee Baek <sbaek at nvidia.com>");
+MODULE_DESCRIPTION("Tegra210 AMX ASoC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/tegra/tegra210_amx.h b/sound/soc/tegra/tegra210_amx.h
new file mode 100644
index 0000000..e277741
--- /dev/null
+++ b/sound/soc/tegra/tegra210_amx.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * tegra210_amx.h - Definitions for Tegra210 AMX driver
+ *
+ * Copyright (c) 2021, NVIDIA CORPORATION.  All rights reserved.
+ *
+ */
+
+#ifndef __TEGRA210_AMX_H__
+#define __TEGRA210_AMX_H__
+
+/* Register offsets from TEGRA210_AMX*_BASE */
+#define TEGRA210_AMX_RX_STATUS			0x0c
+#define TEGRA210_AMX_RX_INT_STATUS		0x10
+#define TEGRA210_AMX_RX_INT_MASK		0x14
+#define TEGRA210_AMX_RX_INT_SET			0x18
+#define TEGRA210_AMX_RX_INT_CLEAR		0x1c
+#define TEGRA210_AMX_RX1_CIF_CTRL		0x20
+#define TEGRA210_AMX_RX2_CIF_CTRL		0x24
+#define TEGRA210_AMX_RX3_CIF_CTRL		0x28
+#define TEGRA210_AMX_RX4_CIF_CTRL		0x2c
+#define TEGRA210_AMX_TX_STATUS			0x4c
+#define TEGRA210_AMX_TX_INT_STATUS		0x50
+#define TEGRA210_AMX_TX_INT_MASK		0x54
+#define TEGRA210_AMX_TX_INT_SET			0x58
+#define TEGRA210_AMX_TX_INT_CLEAR		0x5c
+#define TEGRA210_AMX_TX_CIF_CTRL		0x60
+#define TEGRA210_AMX_ENABLE			0x80
+#define TEGRA210_AMX_SOFT_RESET			0x84
+#define TEGRA210_AMX_CG				0x88
+#define TEGRA210_AMX_STATUS			0x8c
+#define TEGRA210_AMX_INT_STATUS			0x90
+#define TEGRA210_AMX_CTRL			0xa4
+#define TEGRA210_AMX_OUT_BYTE_EN0		0xa8
+#define TEGRA210_AMX_OUT_BYTE_EN1		0xac
+#define TEGRA210_AMX_CYA			0xb0
+#define TEGRA210_AMX_CFG_RAM_CTRL		0xb8
+#define TEGRA210_AMX_CFG_RAM_DATA		0xbc
+
+#define TEGRA194_AMX_RX1_FRAME_PERIOD		0xc0
+#define TEGRA194_AMX_RX4_FRAME_PERIOD		0xcc
+#define TEGRA194_AMX_RX4_LAST_FRAME_PERIOD	0xdc
+
+/* Fields in TEGRA210_AMX_ENABLE */
+#define TEGRA210_AMX_ENABLE_SHIFT			0
+
+/* Fields in TEGRA210_AMX_CTRL */
+#define TEGRA210_AMX_CTRL_MSTR_RX_NUM_SHIFT		14
+#define TEGRA210_AMX_CTRL_MSTR_RX_NUM_MASK		(3 << TEGRA210_AMX_CTRL_MSTR_RX_NUM_SHIFT)
+
+#define TEGRA210_AMX_CTRL_RX_DEP_SHIFT			12
+#define TEGRA210_AMX_CTRL_RX_DEP_MASK			(3 << TEGRA210_AMX_CTRL_RX_DEP_SHIFT)
+
+/* Fields in TEGRA210_AMX_CFG_RAM_CTRL */
+#define TEGRA210_AMX_CFG_RAM_CTRL_RW_SHIFT		14
+#define TEGRA210_AMX_CFG_RAM_CTRL_RW_WRITE		(1 << TEGRA210_AMX_CFG_RAM_CTRL_RW_SHIFT)
+
+#define TEGRA210_AMX_CFG_RAM_CTRL_ADDR_INIT_EN_SHIFT	13
+#define TEGRA210_AMX_CFG_RAM_CTRL_ADDR_INIT_EN		(1 << TEGRA210_AMX_CFG_RAM_CTRL_ADDR_INIT_EN_SHIFT)
+
+#define TEGRA210_AMX_CFG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT	12
+#define TEGRA210_AMX_CFG_RAM_CTRL_SEQ_ACCESS_EN		(1 << TEGRA210_AMX_CFG_RAM_CTRL_SEQ_ACCESS_EN_SHIFT)
+
+#define TEGRA210_AMX_CFG_CTRL_RAM_ADDR_SHIFT		0
+
+/* Fields in TEGRA210_AMX_SOFT_RESET */
+#define TEGRA210_AMX_SOFT_RESET_SOFT_EN			1
+#define TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK		TEGRA210_AMX_SOFT_RESET_SOFT_EN
+
+#define TEGRA210_AMX_AUDIOCIF_CH_STRIDE		4
+#define TEGRA210_AMX_RAM_DEPTH			16
+#define TEGRA210_AMX_MAP_STREAM_NUM_SHIFT	6
+#define TEGRA210_AMX_MAP_WORD_NUM_SHIFT		2
+#define TEGRA210_AMX_MAP_BYTE_NUM_SHIFT		0
+
+enum {
+	TEGRA210_AMX_WAIT_ON_ALL,
+	TEGRA210_AMX_WAIT_ON_ANY,
+};
+
+struct tegra210_amx_soc_data {
+	const struct regmap_config *regmap_conf;
+	bool auto_disable;
+};
+
+struct tegra210_amx {
+	const struct tegra210_amx_soc_data *soc_data;
+	unsigned int map[TEGRA210_AMX_RAM_DEPTH];
+	struct regmap *regmap;
+	unsigned int byte_mask[2];
+};
+
+#endif
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:53 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:53 +0530
Subject: [PATCH 07/13] ASoC: tegra: Add Tegra210 based SFC driver
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-8-git-send-email-spujar@nvidia.com>

The Sampling Frequency Converter (SFC) converts the sampling frequency
of the input signal from one frequency to another. It supports sampling
frequency conversions of streams of up to two channels (stereo).

This patch registers SFC driver with ASoC framework. The component driver
exposes DAPM widgets, routes and kcontrols for the device. The DAI driver
exposes SFC interfaces, which can be used to connect different components
in the ASoC layer. Makefile and Kconfig support is added to allow build
the driver. It can be enabled in the DT via "nvidia,tegra210-sfc"
compatible binding.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 sound/soc/tegra/Kconfig        |    9 +
 sound/soc/tegra/Makefile       |    2 +
 sound/soc/tegra/tegra210_sfc.c | 3542 ++++++++++++++++++++++++++++++++++++++++
 sound/soc/tegra/tegra210_sfc.h |   78 +
 4 files changed, 3631 insertions(+)
 create mode 100644 sound/soc/tegra/tegra210_sfc.c
 create mode 100644 sound/soc/tegra/tegra210_sfc.h

diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index b8825e9..102564e 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -117,6 +117,15 @@ config SND_SOC_TEGRA210_MVC
 	  per-stream volume control or for master volume control.
 	  Say Y or M if you want to add support for Tegra210 MVC module.
 
+config SND_SOC_TEGRA210_SFC
+	tristate "Tegra210 SFC module"
+	help
+	  Config to enable the Sampling Frequency Converter (SFC) which
+	  converts the sampling frequency of input signal to another
+	  frequency. It supports sampling frequency conversion of streams
+	  upto 2 channels (stereo).
+	  Say Y or M if you want to add support for Tegra210 SFC module.
+
 config SND_SOC_TEGRA_AUDIO_GRAPH_CARD
 	tristate "Audio Graph Card based Tegra driver"
 	depends on SND_AUDIO_GRAPH_CARD
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index b58d041..bb0cf3a 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -14,6 +14,7 @@ snd-soc-tegra210-i2s-objs := tegra210_i2s.o
 snd-soc-tegra186-dspk-objs := tegra186_dspk.o
 snd-soc-tegra210-admaif-objs := tegra210_admaif.o
 snd-soc-tegra210-mvc-objs := tegra210_mvc.o
+snd-soc-tegra210-sfc-objs := tegra210_sfc.o
 
 obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
 obj-$(CONFIG_SND_SOC_TEGRA20_AC97) += snd-soc-tegra20-ac97.o
@@ -28,6 +29,7 @@ obj-$(CONFIG_SND_SOC_TEGRA210_I2S) += snd-soc-tegra210-i2s.o
 obj-$(CONFIG_SND_SOC_TEGRA186_DSPK) += snd-soc-tegra186-dspk.o
 obj-$(CONFIG_SND_SOC_TEGRA210_ADMAIF) += snd-soc-tegra210-admaif.o
 obj-$(CONFIG_SND_SOC_TEGRA210_MVC) += snd-soc-tegra210-mvc.o
+obj-$(CONFIG_SND_SOC_TEGRA210_SFC) += snd-soc-tegra210-sfc.o
 
 # Tegra machine Support
 snd-soc-tegra-wm8903-objs := tegra_wm8903.o
diff --git a/sound/soc/tegra/tegra210_sfc.c b/sound/soc/tegra/tegra210_sfc.c
new file mode 100644
index 0000000..a23e8fd1
--- /dev/null
+++ b/sound/soc/tegra/tegra210_sfc.c
@@ -0,0 +1,3542 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// tegra210_sfc.c - Tegra210 SFC driver
+//
+// Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "tegra210_sfc.h"
+#include "tegra_cif.h"
+
+#define UNSUPP_CONV ((void *)(-EOPNOTSUPP))
+#define BYPASS_CONV NULL
+
+static const struct reg_default tegra210_sfc_reg_defaults[] = {
+	{ TEGRA210_SFC_RX_INT_MASK, 0x00000001},
+	{ TEGRA210_SFC_RX_CIF_CTRL, 0x00007700},
+	{ TEGRA210_SFC_TX_INT_MASK, 0x00000001},
+	{ TEGRA210_SFC_TX_CIF_CTRL, 0x00007700},
+	{ TEGRA210_SFC_CG, 0x1},
+	{ TEGRA210_SFC_CFG_RAM_CTRL, 0x00004000},
+};
+
+static const int tegra210_sfc_rates[TEGRA210_SFC_NUM_RATES] = {
+	8000,
+	11025,
+	16000,
+	22050,
+	24000,
+	32000,
+	44100,
+	48000,
+	88200,
+	96000,
+	176400,
+	192000,
+};
+
+/* coeff RAM tables required for SFC */
+static u32 coef_8to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0018a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003,//output gain
+	0x00235204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0000015f,//input gain
+	0x00a7909c, 0xff241c71, 0x005f5e00,
+	0xffca77f4, 0xff20dd50, 0x006855eb,
+	0xff86c552, 0xff18137a, 0x00773648,
+	0x00000001//output gain
+};
+
+static u32 coef_8to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002//output gain
+};
+
+static u32 coef_8to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0018a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003,//output gain
+	0x00230204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000001//output gain
+};
+
+static u32 coef_8to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x0000a105,//header
+	0x000005e1,//input gain
+	0x00dca92f, 0xff45647a, 0x0046b59c,
+	0x00429d1e, 0xff4fec62, 0x00516d30,
+	0xffdea779, 0xff5e08ba, 0x0060185e,
+	0xffafbab2, 0xff698d5a, 0x006ce3ae,
+	0xff9a82d2, 0xff704674, 0x007633c5,
+	0xff923433, 0xff721128, 0x007cff42,
+	0x00000003//output gain
+};
+
+static u32 coef_8to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002//output gain
+};
+
+static u32 coef_8to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x0156105,//interpolation + IIR filter
+	0x0000d649,//input gain
+	0x00e87afb, 0xff5f69d0, 0x003df3cf,
+	0x007ce488, 0xff99a5c8, 0x0056a6a0,
+	0x00344928, 0xffcba3e5, 0x006be470,
+	0x00137aa7, 0xffe60276, 0x00773410,
+	0x0005fa2a, 0xfff1ac11, 0x007c795b,
+	0x00012d36, 0xfff5eca2, 0x007f10ef,
+	0x00000002,//ouptut gain
+	0x0021a102,//interpolation + IIR filter
+	0x00000e00,//input gain
+	0x00e2e000, 0xff6e1a00, 0x002aaa00,
+	0x00610a00, 0xff5dda00, 0x003ccc00,
+	0x00163a00, 0xff3c0400, 0x00633200,
+	0x00000003,//Output gain
+	0x00000204,//Farrow filter
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_8to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00156105,//interpolation + IIR Filter
+	0x0000d649,//input gain
+	0x00e87afb, 0xff5f69d0, 0x003df3cf,
+	0x007ce488, 0xff99a5c8, 0x0056a6a0,
+	0x00344928, 0xffcba3e5, 0x006be470,
+	0x00137aa7, 0xffe60276, 0x00773410,
+	0x0005fa2a, 0xfff1ac11, 0x007c795b,
+	0x00012d36, 0xfff5eca2, 0x007f10ef,
+	0x00000002,//ouptut gain
+	0x0000a102,//interpolation + IIR filter
+	0x00000e00,//input gain
+	0x00e2e000, 0xff6e1a00, 0x002aaa00,
+	0x00610a00, 0xff5dda00, 0x003ccc00,
+	0x00163a00, 0xff3c0400, 0x00633200,
+	0x00000003//output gain
+};
+
+static u32 coef_8to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x0024a102,//header
+	0x0000007d,//input gain
+	0x007d1f20, 0xff1a540e, 0x00678bf9,
+	0xff916625, 0xff16b0ff, 0x006e433a,
+	0xff5af660, 0xff0eb91f, 0x00797356,
+	0x00000003,//output gain
+	0x00000204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_8to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x0000a102,//header
+	0x0000007d,//input gain
+	0x007d1f20, 0xff1a540e, 0x00678bf9,
+	0xff916625, 0xff16b0ff, 0x006e433a,
+	0xff5af660, 0xff0eb91f, 0x00797356,
+	0x00000003//output gain
+};
+
+static u32 coef_11to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0000015f,//input gain
+	0x00a7909c, 0xff241c71, 0x005f5e00,
+	0xffca77f4, 0xff20dd50, 0x006855eb,
+	0xff86c552, 0xff18137a, 0x00773648,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000002,//output gain
+	0x00239204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_11to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00009204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_11to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002//output gain
+};
+
+static u32 coef_11to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_11to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00009204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_11to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002//output gain
+};
+
+static u32 coef_11to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_11to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002//output gain
+};
+
+static u32 coef_11to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00000204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_16to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_16to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000fa103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000003,//output gain
+	0x001a5204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_16to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0018a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003,//output gain
+	0x00235204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0000015f,//input gain
+	0x00a7909c, 0xff241c71, 0x005f5e00,
+	0xffca77f4, 0xff20dd50, 0x006855eb,
+	0xff86c552, 0xff18137a, 0x00773648,
+	0x00000001//output gain
+};
+
+static u32 coef_16to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x0015a105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000003,//output gain
+	0x00005105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000001//output gain
+};
+
+static u32 coef_16to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002//output gain
+};
+
+static u32 coef_16to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00156105,//interpolation + IIR filter
+	0x0000d649,//input gain
+	0x00e87afb, 0xff5f69d0, 0x003df3cf,
+	0x007ce488, 0xff99a5c8, 0x0056a6a0,
+	0x00344928, 0xffcba3e5, 0x006be470,
+	0x00137aa7, 0xffe60276, 0x00773410,
+	0x0005fa2a, 0xfff1ac11, 0x007c795b,
+	0x00012d36, 0xfff5eca2, 0x007f10ef,
+	0x00000002,//output gain
+	0x0021a102,//interpolation + IIR filter
+	0x00000e00,//input gain
+	0x00e2e000, 0xff6e1a00, 0x002aaa00,
+	0x00610a00, 0xff5dda00, 0x003ccc00,
+	0x00163a00, 0xff3c0400, 0x00633200,
+	0x00000003,//output gain
+	0x002c0204,//Farrow Filter
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005101,//IIR Filter + Decimator
+	0x0000203c,//input gain
+	0x00f52d35, 0xff2e2162, 0x005a21e0,
+	0x00c6f0f0, 0xff2ecd69, 0x006fa78d,
+	0x00000001//output gain
+};
+
+static u32 coef_16to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x0000a105,//interpolation + IIR Filter
+	0x00000784,//input gain
+	0x00cc516e, 0xff2c9639, 0x005ad5b3,
+	0x0013ad0d, 0xff3d4799, 0x0063ce75,
+	0xffb6f398, 0xff5138d1, 0x006e9e1f,
+	0xff9186e5, 0xff5f96a4, 0x0076a86e,
+	0xff82089c, 0xff676b81, 0x007b9f8a,
+	0xff7c48a5, 0xff6a31e7, 0x007ebb7b,
+	0x00000003//output gain
+};
+
+static u32 coef_16to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0018a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003,//output gain
+	0x00000204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_16to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0000a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003//output gain
+};
+
+static u32 coef_16to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x0024a102,//header
+	0x0000007d,//input gain
+	0x007d1f20, 0xff1a540e, 0x00678bf9,
+	0xff916625, 0xff16b0ff, 0x006e433a,
+	0xff5af660, 0xff0eb91f, 0x00797356,
+	0x00000003,//output gain
+	0x00000204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_16to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x0000a102,//header
+	0x0000007d,//input gain
+	0x007d1f20, 0xff1a540e, 0x00678bf9,
+	0xff916625, 0xff16b0ff, 0x006e433a,
+	0xff5af660, 0xff0eb91f, 0x00797356,
+	0x00000003//output gain
+};
+
+static u32 coef_22to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000002,//output gain
+	0x00179204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_22to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_22to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0000015f,//input gain
+	0x00a7909c, 0xff241c71, 0x005f5e00,
+	0xffca77f4, 0xff20dd50, 0x006855eb,
+	0xff86c552, 0xff18137a, 0x00773648,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000002,//output gain
+	0x00239204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_22to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00235204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d029,//input gain
+	0x00f2a98b, 0xff92aa71, 0x001fcd16,
+	0x00ae9004, 0xffb85140, 0x0041813a,
+	0x007f8ed1, 0xffd585fc, 0x006a69e6,
+	0x00000001//output gain
+};
+
+static u32 coef_22to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00009204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_22to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002//output gain
+};
+
+static u32 coef_22to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_22to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002//output gain
+};
+
+static u32 coef_22to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_22to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002//output gain
+};
+
+static u32 coef_22to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00000204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_24to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00009105,//header
+	0x000005e1,//input gain
+	0x00dca92f, 0xff45647a, 0x0046b59c,
+	0x00429d1e, 0xff4fec62, 0x00516d30,
+	0xffdea779, 0xff5e08ba, 0x0060185e,
+	0xffafbab2, 0xff698d5a, 0x006ce3ae,
+	0xff9a82d2, 0xff704674, 0x007633c5,
+	0xff923433, 0xff721128, 0x007cff42,
+	0x00000001//output gain
+};
+
+static u32 coef_24to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000f6103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000002,//output gain
+	0x001a5204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_24to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00156105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000002,//output gain
+	0x00009105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000001//output gain
+};
+
+static u32 coef_24to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d029,//input gain
+	0x00f2a98b, 0xff92aa71, 0x001fcd16,
+	0x00ae9004, 0xffb85140, 0x0041813a,
+	0x007f8ed1, 0xffd585fc, 0x006a69e6,
+	0x00000002,//output gain
+	0x001b6103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000002,//output gain
+	0x00265204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_24to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00009102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001//output gain
+};
+
+static u32 coef_24to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00230204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x00001685,//input gain
+	0x00f53ae9, 0xff52f196, 0x003e3e08,
+	0x00b9f857, 0xff5d8985, 0x0050070a,
+	0x008c3e86, 0xff6053f0, 0x006d98ef,
+	0x00000001//output gain
+};
+
+static u32 coef_24to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002//output gain
+};
+
+static u32 coef_24to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x002f0204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x00000138,//input gain
+	0x00d5d232, 0xff2a3bf8, 0x005a785c,
+	0x0034001b, 0xff283109, 0x006462a6,
+	0xffe6746a, 0xff1fb09c, 0x00758a91,
+	0x00000001//output gain
+};
+
+static u32 coef_24to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002//output gain
+};
+
+static u32 coef_24to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00000204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_24to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002//output gain
+};
+
+static u32 coef_32to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_32to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000ca102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000003,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x0000d102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001//output gain
+};
+
+static u32 coef_32to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_32to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000fa103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000003,//output gain
+	0x001a5204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_32to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000ca102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000003,//output gain
+	0x0000d102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001//output gain
+};
+
+static u32 coef_32to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0018a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003,//output gain
+	0x00235204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0000015f,//input gain
+	0x00a7909c, 0xff241c71, 0x005f5e00,
+	0xffca77f4, 0xff20dd50, 0x006855eb,
+	0xff86c552, 0xff18137a, 0x00773648,
+	0x00000001//output gain
+};
+
+static u32 coef_32to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x0015a105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000003,//output gain
+	0x00005105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000001//output gain
+};
+
+static u32 coef_32to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0018a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003,//output gain
+	0x00230204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000001//output gain
+};
+
+static u32 coef_32to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x0000a105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000003//output gain
+};
+
+static u32 coef_32to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0018a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003,//output gain
+	0x00000204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_32to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x0000a102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000003//output gain
+};
+
+static u32 coef_44to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00120104,//IIR Filter
+	0x00000af2,//input gain
+	0x0057eebe, 0xff1e9863, 0x00652604,
+	0xff7206ea, 0xff22ad7e, 0x006d47e1,
+	0xff42a4d7, 0xff26e722, 0x0075fd83,
+	0xff352f66, 0xff29312b, 0x007b986b,
+	0xff310a07, 0xff296f51, 0x007eca7c,
+	0x00000001,//output gain
+	0x001d9204,//Farrow Filter + decimation
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005105,//IIR Filter + Decimator
+	0x0000d649,//input gain
+	0x00e87afb, 0xff5f69d0, 0x003df3cf,
+	0x007ce488, 0xff99a5c8, 0x0056a6a0,
+	0x00344928, 0xffcba3e5, 0x006be470,
+	0x00137aa7, 0xffe60276, 0x00773410,
+	0x0005fa2a, 0xfff1ac11, 0x007c795b,
+	0x00012d36, 0xfff5eca2, 0x007f10ef,
+	0x00000001//output gain
+};
+
+static u32 coef_44to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_44to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00126104,//IIR Filter + interpolation
+	0x00000af2,//input gain
+	0x0057eebe, 0xff1e9863, 0x00652604,
+	0xff7206ea, 0xff22ad7e, 0x006d47e1,
+	0xff42a4d7, 0xff26e722, 0x0075fd83,
+	0xff352f66, 0xff29312b, 0x007b986b,
+	0xff310a07, 0xff296f51, 0x007eca7c,
+	0x00000002,//output gain
+	0x001d9204,//Farrow Filter + decimation
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005105,//IIR Filter + Decimator
+	0x0000d649,//input gain
+	0x00e87afb, 0xff5f69d0, 0x003df3cf,
+	0x007ce488, 0xff99a5c8, 0x0056a6a0,
+	0x00344928, 0xffcba3e5, 0x006be470,
+	0x00137aa7, 0xffe60276, 0x00773410,
+	0x0005fa2a, 0xfff1ac11, 0x007c795b,
+	0x00012d36, 0xfff5eca2, 0x007f10ef,
+	0x00000001//output gain
+};
+
+static u32 coef_44to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_44to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x00001685,//input gain
+	0x00f53ae9, 0xff52f196, 0x003e3e08,
+	0x00b9f857, 0xff5d8985, 0x0050070a,
+	0x008c3e86, 0xff6053f0, 0x006d98ef,
+	0x00000002,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_44to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0000015f,//input gain
+	0x00a7909c, 0xff241c71, 0x005f5e00,
+	0xffca77f4, 0xff20dd50, 0x006855eb,
+	0xff86c552, 0xff18137a, 0x00773648,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000002,//output gain
+	0x00239204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_44to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00235204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d029,//input gain
+	0x00f2a98b, 0xff92aa71, 0x001fcd16,
+	0x00ae9004, 0xffb85140, 0x0041813a,
+	0x007f8ed1, 0xffd585fc, 0x006a69e6,
+	0x00000001//output gain
+};
+
+static u32 coef_44to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002//output gain
+};
+
+static u32 coef_44to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_44to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002//output gain
+};
+
+static u32 coef_44to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_48to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c9102,//IIR Filter + Decimator
+	0x00000e00,//input gain
+	0x00e2e000, 0xff6e1a00, 0x002aaa00,
+	0x00610a00, 0xff5dda00, 0x003ccc00,
+	0x00163a00, 0xff3c0400, 0x00633200,
+	0x00000001,//output gain
+	0x00005105,//IIR Filter + Decimator
+	0x0000d649,//input gain
+	0x00e87afb, 0xff5f69d0, 0x003df3cf,
+	0x007ce488, 0xff99a5c8, 0x0056a6a0,
+	0x00344928, 0xffcba3e5, 0x006be470,
+	0x00137aa7, 0xffe60276, 0x00773410,
+	0x0005fa2a, 0xfff1ac11, 0x007c795b,
+	0x00012d36, 0xfff5eca2, 0x007f10ef,
+	0x00000001//output gain
+};
+
+static u32 coef_48to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000002,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00235102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_48to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00009105,//IIR Filter + Decimator
+	0x00000784,//input gain
+	0x00cc516e, 0xff2c9639, 0x005ad5b3,
+	0x0013ad0d, 0xff3d4799, 0x0063ce75,
+	0xffb6f398, 0xff5138d1, 0x006e9e1f,
+	0xff9186e5, 0xff5f96a4, 0x0076a86e,
+	0xff82089c, 0xff676b81, 0x007b9f8a,
+	0xff7c48a5, 0xff6a31e7, 0x007ebb7b,
+	0x00000001//output gain
+};
+
+static u32 coef_48to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000f6103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000002,//output gain
+	0x001a5204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_48to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_48to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00156105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000002,//output gain
+	0x00009105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000001//output gain
+};
+
+static u32 coef_48to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d029,//input gain
+	0x00f2a98b, 0xff92aa71, 0x001fcd16,
+	0x00ae9004, 0xffb85140, 0x0041813a,
+	0x007f8ed1, 0xffd585fc, 0x006a69e6,
+	0x00000002,//output gain
+	0x001b6103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000002,//output gain
+	0x00265204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_48to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00230204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x00001685,//input gain
+	0x00f53ae9, 0xff52f196, 0x003e3e08,
+	0x00b9f857, 0xff5d8985, 0x0050070a,
+	0x008c3e86, 0xff6053f0, 0x006d98ef,
+	0x00000001//output gain
+};
+
+static u32 coef_48to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002//output gain
+};
+
+static u32 coef_48to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00246102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x002f0204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x00000138,//input gain
+	0x00d5d232, 0xff2a3bf8, 0x005a785c,
+	0x0034001b, 0xff283109, 0x006462a6,
+	0xffe6746a, 0xff1fb09c, 0x00758a91,
+	0x00000001//output gain
+};
+
+static u32 coef_48to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000002,//output gain
+	0x00006102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002//output gain
+};
+
+static u32 coef_88to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x00000057,//input gain
+	0x00a8e717, 0xff1c748d, 0x0065b976,
+	0xffcbccab, 0xff190aff, 0x006cc1cf,
+	0xff871ce1, 0xff10d878, 0x0078cfc5,
+	0x00000001,//output gain
+	0x00179204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00235102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_88to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000001,//output gain
+	0x00185102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_88to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000001,//output gain
+	0x00179204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_88to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_88to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x00001685,//input gain
+	0x00f53ae9, 0xff52f196, 0x003e3e08,
+	0x00b9f857, 0xff5d8985, 0x0050070a,
+	0x008c3e86, 0xff6053f0, 0x006d98ef,
+	0x00000001,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_88to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000002,//output gain
+	0x00179204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_88to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_88to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x00001685,//input gain
+	0x00f53ae9, 0xff52f196, 0x003e3e08,
+	0x00b9f857, 0xff5d8985, 0x0050070a,
+	0x008c3e86, 0xff6053f0, 0x006d98ef,
+	0x00000002,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_88to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_88to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002//output gain
+};
+
+static u32 coef_88to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000002,//output gain
+	0x00186102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_96to8[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c9102,//header
+	0x0000007d,//input gain
+	0x007d1f20, 0xff1a540e, 0x00678bf9,
+	0xff916625, 0xff16b0ff, 0x006e433a,
+	0xff5af660, 0xff0eb91f, 0x00797356,
+	0x00000001,//output gain
+	0x00185102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_96to11[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000001,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00235102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_96to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c9102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_96to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000002,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00235102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_96to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_96to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00009105,//header
+	0x00000292,//input gain
+	0x00e4320a, 0xff41d2d9, 0x004911ac,
+	0x005dd9e3, 0xff4c7d80, 0x0052103e,
+	0xfff8ebef, 0xff5b6fab, 0x005f0a0d,
+	0xffc4b414, 0xff68582c, 0x006b38e5,
+	0xffabb861, 0xff704bec, 0x0074de52,
+	0xffa19f4c, 0xff729059, 0x007c7e90,
+	0x00000001//output gain
+};
+
+static u32 coef_96to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000f6103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000002,//output gain
+	0x001a5204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_96to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_96to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000f6103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000002,//output gain
+	0x001a0204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001//output gain
+};
+
+static u32 coef_96to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000f6103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000002,//output gain
+	0x001b6102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000002,//output gain
+	0x00260204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000001//output gain
+};
+
+static u32 coef_96to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00006103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000002//output gain
+};
+
+static u32 coef_176to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x00000057,//input gain
+	0x00a8e717, 0xff1c748d, 0x0065b976,
+	0xffcbccab, 0xff190aff, 0x006cc1cf,
+	0xff871ce1, 0xff10d878, 0x0078cfc5,
+	0x00000001,//output gain
+	0x00179204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00235102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_176to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000001,//output gain
+	0x00185102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_176to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x00000138,//input gain
+	0x00d5d232, 0xff2a3bf8, 0x005a785c,
+	0x0034001b, 0xff283109, 0x006462a6,
+	0xffe6746a, 0xff1fb09c, 0x00758a91,
+	0x00000001,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00235102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_176to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x000005f3,//input gain
+	0x00d816d6, 0xff385383, 0x004fe566,
+	0x003c548d, 0xff38c23d, 0x005d0b1c,
+	0xfff02f7d, 0xff31e983, 0x0072d65d,
+	0x00000001,//output gain
+	0x00179204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_176to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_176to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x00001685,//input gain
+	0x00f53ae9, 0xff52f196, 0x003e3e08,
+	0x00b9f857, 0xff5d8985, 0x0050070a,
+	0x008c3e86, 0xff6053f0, 0x006d98ef,
+	0x00000001,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_176to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001//output gain
+};
+
+static u32 coef_176to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000001//output gain
+};
+
+static u32 coef_176to192[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000002,//output gain
+	0x00005204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000
+};
+
+static u32 coef_192to16[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c9102,//header
+	0x0000007d,//input gain
+	0x007d1f20, 0xff1a540e, 0x00678bf9,
+	0xff916625, 0xff16b0ff, 0x006e433a,
+	0xff5af660, 0xff0eb91f, 0x00797356,
+	0x00000001,//output gain
+	0x00185102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_192to22[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c0102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000001,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00235102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_192to24[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000001,//output gain
+	0x00185102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_192to32[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c9102,//header
+	0x000005d6,//input gain
+	0x00c6543e, 0xff342935, 0x0052f116,
+	0x000a1d78, 0xff3330c0, 0x005f88a3,
+	0xffbee7c0, 0xff2b5ba5, 0x0073eb26,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_192to44[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000002,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00235102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_192to48[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c5102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001,//output gain
+	0x00005102,//header
+	0x0001d727,//input gain
+	0x00fc2fc7, 0xff9bb27b, 0x001c564c,
+	0x00e55557, 0xffcadd5b, 0x003d80ba,
+	0x00d13397, 0xfff232f8, 0x00683337,
+	0x00000001//output gain
+};
+
+static u32 coef_192to88[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000002,//output gain
+	0x00175204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x000013d9,//input gain
+	0x00ebd477, 0xff4ce383, 0x0042049d,
+	0x0089c278, 0xff54414d, 0x00531ded,
+	0x004a5e07, 0xff53cf41, 0x006efbdc,
+	0x00000001//output gain
+};
+
+static u32 coef_192to96[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x00005103,//header
+	0x000001e0,//input gain
+	0x00de44c0, 0xff380b7f, 0x004ffc73,
+	0x00494b44, 0xff3d493a, 0x005908bf,
+	0xffe9a3c8, 0xff425647, 0x006745f7,
+	0xffc42d61, 0xff40a6c7, 0x00776709,
+	0x00000001//output gain
+};
+
+static u32 coef_192to176[TEGRA210_SFC_COEF_RAM_DEPTH] = {
+	0x000c6102,//header
+	0x000000af,//input gain
+	0x00c65663, 0xff23d2ce, 0x005f97d6,
+	0x00086ad6, 0xff20ec4f, 0x00683201,
+	0xffbbbef6, 0xff184447, 0x00770963,
+	0x00000002,//output gain
+	0x00170204,//farrow
+	0x000aaaab,
+	0xffaaaaab,
+	0xfffaaaab,
+	0x00555555,
+	0xff600000,
+	0xfff55555,
+	0x00155555,
+	0x00055555,
+	0xffeaaaab,
+	0x00200000,
+	0x00005102,//header
+	0x0000010a,//input gain
+	0x00c93dc4, 0xff26f5f6, 0x005d1041,
+	0x001002c4, 0xff245b76, 0x00666002,
+	0xffc30a45, 0xff1baecd, 0x00765921,
+	0x00000001//output gain
+};
+
+/*
+ * Coefficient table for various sample rate conversions. The sample
+ * rates available are as per tegra210_sfc_rates[].
+ */
+static s32 *coef_addr_table[TEGRA210_SFC_NUM_RATES][TEGRA210_SFC_NUM_RATES] = {
+	/* Convertions from 8 kHz */
+	{
+		BYPASS_CONV,
+		coef_8to11,
+		coef_8to16,
+		coef_8to22,
+		coef_8to24,
+		coef_8to32,
+		coef_8to44,
+		coef_8to48,
+		coef_8to88,
+		coef_8to96,
+		UNSUPP_CONV,
+		UNSUPP_CONV,
+	},
+	/* Convertions from 11.025 kHz */
+	{
+		coef_11to8,
+		BYPASS_CONV,
+		coef_11to16,
+		coef_11to22,
+		coef_11to24,
+		coef_11to32,
+		coef_11to44,
+		coef_11to48,
+		coef_11to88,
+		coef_11to96,
+		UNSUPP_CONV,
+		UNSUPP_CONV,
+	},
+	/* Convertions from 16 kHz */
+	{
+		coef_16to8,
+		coef_16to11,
+		BYPASS_CONV,
+		coef_16to22,
+		coef_16to24,
+		coef_16to32,
+		coef_16to44,
+		coef_16to48,
+		coef_16to88,
+		coef_16to96,
+		coef_16to176,
+		coef_16to192,
+	},
+	/* Convertions from 22.05 kHz */
+	{
+		coef_22to8,
+		coef_22to11,
+		coef_22to16,
+		BYPASS_CONV,
+		coef_22to24,
+		coef_22to32,
+		coef_22to44,
+		coef_22to48,
+		coef_22to88,
+		coef_22to96,
+		coef_22to176,
+		coef_22to192,
+	},
+	/* Convertions from 24 kHz */
+	{
+		coef_24to8,
+		coef_24to11,
+		coef_24to16,
+		coef_24to22,
+		BYPASS_CONV,
+		coef_24to32,
+		coef_24to44,
+		coef_24to48,
+		coef_24to88,
+		coef_24to96,
+		coef_24to176,
+		coef_24to192,
+	},
+	/* Convertions from 32 kHz */
+	{
+		coef_32to8,
+		coef_32to11,
+		coef_32to16,
+		coef_32to22,
+		coef_32to24,
+		BYPASS_CONV,
+		coef_32to44,
+		coef_32to48,
+		coef_32to88,
+		coef_32to96,
+		coef_32to176,
+		coef_32to192,
+	},
+	/* Convertions from 44.1 kHz */
+	{
+		coef_44to8,
+		coef_44to11,
+		coef_44to16,
+		coef_44to22,
+		coef_44to24,
+		coef_44to32,
+		BYPASS_CONV,
+		coef_44to48,
+		coef_44to88,
+		coef_44to96,
+		coef_44to176,
+		coef_44to192,
+	},
+	/* Convertions from 48 kHz */
+	{
+		coef_48to8,
+		coef_48to11,
+		coef_48to16,
+		coef_48to22,
+		coef_48to24,
+		coef_48to32,
+		coef_48to44,
+		BYPASS_CONV,
+		coef_48to88,
+		coef_48to96,
+		coef_48to176,
+		coef_48to192,
+	},
+	/* Convertions from 88.2 kHz */
+	{
+		coef_88to8,
+		coef_88to11,
+		coef_88to16,
+		coef_88to22,
+		coef_88to24,
+		coef_88to32,
+		coef_88to44,
+		coef_88to48,
+		BYPASS_CONV,
+		coef_88to96,
+		coef_88to176,
+		coef_88to192,
+	},
+	/* Convertions from 96 kHz */
+	{	coef_96to8,
+		coef_96to11,
+		coef_96to16,
+		coef_96to22,
+		coef_96to24,
+		coef_96to32,
+		coef_96to44,
+		coef_96to48,
+		coef_96to88,
+		BYPASS_CONV,
+		coef_96to176,
+		coef_96to192,
+	},
+	/* Convertions from 176.4 kHz */
+	{
+		UNSUPP_CONV,
+		UNSUPP_CONV,
+		coef_176to16,
+		coef_176to22,
+		coef_176to24,
+		coef_176to32,
+		coef_176to44,
+		coef_176to48,
+		coef_176to88,
+		coef_176to96,
+		BYPASS_CONV,
+		coef_176to192,
+	},
+	/* Convertions from 192 kHz */
+	{
+		UNSUPP_CONV,
+		UNSUPP_CONV,
+		coef_192to16,
+		coef_192to22,
+		coef_192to24,
+		coef_192to32,
+		coef_192to44,
+		coef_192to48,
+		coef_192to88,
+		coef_192to96,
+		coef_192to176,
+		BYPASS_CONV,
+	},
+};
+
+static int __maybe_unused tegra210_sfc_runtime_suspend(struct device *dev)
+{
+	struct tegra210_sfc *sfc = dev_get_drvdata(dev);
+
+	regcache_cache_only(sfc->regmap, true);
+	regcache_mark_dirty(sfc->regmap);
+
+	return 0;
+}
+
+static int __maybe_unused tegra210_sfc_runtime_resume(struct device *dev)
+{
+	struct tegra210_sfc *sfc = dev_get_drvdata(dev);
+
+	regcache_cache_only(sfc->regmap, false);
+	regcache_sync(sfc->regmap);
+
+	return 0;
+}
+
+static inline void tegra210_sfc_write_ram(struct regmap *regmap,
+					  s32 *data)
+{
+	int i;
+
+	regmap_write(regmap, TEGRA210_SFC_CFG_RAM_CTRL,
+		     TEGRA210_SFC_RAM_CTRL_SEQ_ACCESS_EN |
+		     TEGRA210_SFC_RAM_CTRL_ADDR_INIT_EN |
+		     TEGRA210_SFC_RAM_CTRL_RW_WRITE);
+
+	for (i = 0; i < TEGRA210_SFC_COEF_RAM_DEPTH; i++)
+		regmap_write(regmap, TEGRA210_SFC_CFG_RAM_DATA, data[i]);
+}
+
+static int tegra210_sfc_write_coeff_ram(struct snd_soc_component *cmpnt)
+{
+	struct tegra210_sfc *sfc = dev_get_drvdata(cmpnt->dev);
+	s32 *coeff_ram;
+
+	/* Bypass */
+	if (sfc->srate_in == sfc->srate_out)
+		return 0;
+
+	coeff_ram = coef_addr_table[sfc->srate_in][sfc->srate_out];
+	if (IS_ERR_OR_NULL(coeff_ram)) {
+		dev_err(cmpnt->dev,
+			"Conversion from %d to %d Hz is not supported\n",
+			sfc->srate_in, sfc->srate_out);
+
+		return PTR_ERR_OR_ZERO(coeff_ram);
+	}
+
+	tegra210_sfc_write_ram(sfc->regmap, coeff_ram);
+
+	regmap_update_bits(sfc->regmap,
+			   TEGRA210_SFC_COEF_RAM,
+			   TEGRA210_SFC_COEF_RAM_EN,
+			   TEGRA210_SFC_COEF_RAM_EN);
+
+	return 0;
+}
+
+static int tegra210_sfc_set_audio_cif(struct tegra210_sfc *sfc,
+				      struct snd_pcm_hw_params *params,
+				      unsigned int reg)
+{
+	unsigned int channels, audio_bits, path;
+	struct tegra_cif_conf cif_conf;
+
+	memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
+
+	channels = params_channels(params);
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		audio_bits = TEGRA_ACIF_BITS_16;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		audio_bits = TEGRA_ACIF_BITS_32;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	cif_conf.audio_ch = channels;
+	cif_conf.client_ch = channels;
+	cif_conf.audio_bits = audio_bits;
+	cif_conf.client_bits = TEGRA_ACIF_BITS_32;
+
+	if (reg == TEGRA210_SFC_RX_CIF_CTRL)
+		path = SFC_RX_PATH;
+	else
+		path = SFC_TX_PATH;
+
+	cif_conf.stereo_conv = sfc->stereo_to_mono[path];
+	cif_conf.mono_conv = sfc->mono_to_stereo[path];
+
+	tegra_set_cif(sfc->regmap, reg, &cif_conf);
+
+	return 0;
+}
+
+static int tegra210_sfc_soft_reset(struct tegra210_sfc *sfc)
+{
+	u32 val;
+
+	/* SW reset */
+	regmap_update_bits(sfc->regmap, TEGRA210_SFC_SOFT_RESET,
+			   TEGRA210_SFC_SOFT_RESET_EN, 1);
+
+	return regmap_read_poll_timeout(sfc->regmap,
+					TEGRA210_SFC_SOFT_RESET,
+					val,
+					!(val & TEGRA210_SFC_SOFT_RESET_EN),
+					10, 10000);
+}
+
+static int tegra210_sfc_rate_to_idx(struct device *dev, int rate,
+				    int *rate_idx)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tegra210_sfc_rates); i++) {
+		if (rate == tegra210_sfc_rates[i]) {
+			*rate_idx = i;
+
+			return 0;
+		}
+	}
+
+	dev_err(dev, "Sample rate %d Hz is not supported\n", rate);
+
+	return -EOPNOTSUPP;
+}
+
+static int tegra210_sfc_startup(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
+	int err;
+
+	regmap_update_bits(sfc->regmap, TEGRA210_SFC_COEF_RAM,
+			   TEGRA210_SFC_COEF_RAM_EN, 0);
+
+	err = tegra210_sfc_soft_reset(sfc);
+	if (err < 0) {
+		dev_err(dai->dev, "Failed to reset SFC in %s, err = %d\n",
+			__func__, err);
+
+		return err;
+	}
+
+	return 0;
+}
+
+static int tegra210_sfc_in_hw_params(struct snd_pcm_substream *substream,
+				     struct snd_pcm_hw_params *params,
+				     struct snd_soc_dai *dai)
+{
+	struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
+	struct device *dev = dai->dev;
+	int err;
+
+	err = tegra210_sfc_rate_to_idx(dev, params_rate(params),
+				       &sfc->srate_in);
+	if (err < 0)
+		return err;
+
+	err = tegra210_sfc_set_audio_cif(sfc, params, TEGRA210_SFC_RX_CIF_CTRL);
+	if (err < 0) {
+		dev_err(dev, "Can't set SFC RX CIF: %d\n", err);
+		return err;
+	}
+
+	regmap_write(sfc->regmap, TEGRA210_SFC_RX_FREQ, sfc->srate_in);
+
+	return err;
+}
+
+static int tegra210_sfc_out_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params,
+				      struct snd_soc_dai *dai)
+{
+	struct tegra210_sfc *sfc = snd_soc_dai_get_drvdata(dai);
+	struct device *dev = dai->dev;
+	int err;
+
+	err = tegra210_sfc_rate_to_idx(dev, params_rate(params),
+				       &sfc->srate_out);
+	if (err < 0)
+		return err;
+
+	err = tegra210_sfc_set_audio_cif(sfc, params, TEGRA210_SFC_TX_CIF_CTRL);
+	if (err < 0) {
+		dev_err(dev, "Can't set SFC TX CIF: %d\n", err);
+		return err;
+	}
+
+	regmap_write(sfc->regmap, TEGRA210_SFC_TX_FREQ, sfc->srate_out);
+
+	return 0;
+}
+
+static int tegra210_sfc_init(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+
+	return tegra210_sfc_write_coeff_ram(cmpnt);
+}
+
+static int tegra210_sfc_get_control(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
+
+	if (strstr(kcontrol->id.name, "Input Stereo To Mono"))
+		ucontrol->value.integer.value[0] =
+			sfc->stereo_to_mono[SFC_RX_PATH];
+	else if (strstr(kcontrol->id.name, "Input Mono To Stereo"))
+		ucontrol->value.integer.value[0] =
+			sfc->mono_to_stereo[SFC_RX_PATH];
+	else if (strstr(kcontrol->id.name, "Output Stereo To Mono"))
+		ucontrol->value.integer.value[0] =
+			sfc->stereo_to_mono[SFC_TX_PATH];
+	else if (strstr(kcontrol->id.name, "Output Mono To Stereo"))
+		ucontrol->value.integer.value[0] =
+			sfc->mono_to_stereo[SFC_TX_PATH];
+
+	return 0;
+}
+
+static int tegra210_sfc_put_control(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
+	int value = ucontrol->value.integer.value[0];
+
+	if (strstr(kcontrol->id.name, "Input Stereo To Mono"))
+		sfc->stereo_to_mono[SFC_RX_PATH] = value;
+	else if (strstr(kcontrol->id.name, "Input Mono To Stereo"))
+		sfc->mono_to_stereo[SFC_RX_PATH] = value;
+	else if (strstr(kcontrol->id.name, "Output Stereo To Mono"))
+		sfc->stereo_to_mono[SFC_TX_PATH] = value;
+	else if (strstr(kcontrol->id.name, "Output Mono To Stereo"))
+		sfc->mono_to_stereo[SFC_TX_PATH] = value;
+
+	return 0;
+}
+
+static struct snd_soc_dai_ops tegra210_sfc_in_dai_ops = {
+	.hw_params	= tegra210_sfc_in_hw_params,
+	.startup	= tegra210_sfc_startup,
+};
+
+static struct snd_soc_dai_ops tegra210_sfc_out_dai_ops = {
+	.hw_params	= tegra210_sfc_out_hw_params,
+};
+
+static struct snd_soc_dai_driver tegra210_sfc_dais[] = {
+	{
+		.name = "SFC-RX-CIF",
+		.playback = {
+			.stream_name = "RX-CIF-Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.capture = {
+			.stream_name = "RX-CIF-Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.ops = &tegra210_sfc_in_dai_ops,
+	},
+	{
+		.name = "SFC-TX-CIF",
+		.playback = {
+			.stream_name = "TX-CIF-Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.capture = {
+			.stream_name = "TX-CIF-Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.ops = &tegra210_sfc_out_dai_ops,
+	},
+};
+
+static const struct snd_soc_dapm_widget tegra210_sfc_widgets[] = {
+	SND_SOC_DAPM_AIF_IN("RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_OUT_E("TX", NULL, 0, TEGRA210_SFC_ENABLE,
+			       TEGRA210_SFC_EN_SHIFT, 0,
+			       tegra210_sfc_init, SND_SOC_DAPM_PRE_PMU),
+};
+
+#define RESAMPLE_ROUTE(sname)					\
+	{ "RX XBAR-" sname,	NULL,	"XBAR-TX" },		\
+	{ "RX-CIF-" sname,	NULL,	"RX XBAR-" sname },	\
+	{ "RX",			NULL,	"RX-CIF-" sname },	\
+	{ "TX-CIF-" sname,	NULL,	"TX" },			\
+	{ "TX XBAR-" sname,	NULL,	"TX-CIF-" sname },	\
+	{ "XBAR-RX",		NULL,	"TX XBAR-" sname }
+
+static const struct snd_soc_dapm_route tegra210_sfc_routes[] = {
+	{ "TX", NULL, "RX" },
+	RESAMPLE_ROUTE("Playback"),
+	RESAMPLE_ROUTE("Capture"),
+};
+
+static const char * const tegra210_sfc_stereo_conv_text[] = {
+	"CH0", "CH1", "AVG",
+};
+
+static const char * const tegra210_sfc_mono_conv_text[] = {
+	"Zero", "Copy",
+};
+
+static const struct soc_enum tegra210_sfc_stereo_conv_enum =
+	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
+			ARRAY_SIZE(tegra210_sfc_stereo_conv_text),
+			tegra210_sfc_stereo_conv_text);
+
+static const struct soc_enum tegra210_sfc_mono_conv_enum =
+	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
+			ARRAY_SIZE(tegra210_sfc_mono_conv_text),
+			tegra210_sfc_mono_conv_text);
+
+static const struct snd_kcontrol_new tegra210_sfc_controls[] = {
+	SOC_ENUM_EXT("Input Stereo To Mono", tegra210_sfc_stereo_conv_enum,
+		tegra210_sfc_get_control, tegra210_sfc_put_control),
+	SOC_ENUM_EXT("Input Mono To Stereo", tegra210_sfc_mono_conv_enum,
+		tegra210_sfc_get_control, tegra210_sfc_put_control),
+	SOC_ENUM_EXT("Output Stereo To Mono", tegra210_sfc_stereo_conv_enum,
+		tegra210_sfc_get_control, tegra210_sfc_put_control),
+	SOC_ENUM_EXT("Output Mono To Stereo", tegra210_sfc_mono_conv_enum,
+		tegra210_sfc_get_control, tegra210_sfc_put_control),
+};
+
+static const struct snd_soc_component_driver tegra210_sfc_cmpnt = {
+	.dapm_widgets		= tegra210_sfc_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tegra210_sfc_widgets),
+	.dapm_routes		= tegra210_sfc_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tegra210_sfc_routes),
+	.controls		= tegra210_sfc_controls,
+	.num_controls		= ARRAY_SIZE(tegra210_sfc_controls),
+};
+
+static bool tegra210_sfc_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_SFC_RX_INT_MASK ... TEGRA210_SFC_RX_FREQ:
+	case TEGRA210_SFC_TX_INT_MASK ... TEGRA210_SFC_TX_FREQ:
+	case TEGRA210_SFC_ENABLE ... TEGRA210_SFC_CG:
+	case TEGRA210_SFC_COEF_RAM ... TEGRA210_SFC_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_sfc_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_SFC_RX_STATUS ... TEGRA210_SFC_RX_FREQ:
+	case TEGRA210_SFC_TX_STATUS ... TEGRA210_SFC_TX_FREQ:
+	case TEGRA210_SFC_ENABLE ... TEGRA210_SFC_INT_STATUS:
+	case TEGRA210_SFC_COEF_RAM ... TEGRA210_SFC_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_sfc_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_SFC_RX_STATUS:
+	case TEGRA210_SFC_RX_INT_STATUS:
+	case TEGRA210_SFC_RX_INT_SET:
+
+	case TEGRA210_SFC_TX_STATUS:
+	case TEGRA210_SFC_TX_INT_STATUS:
+	case TEGRA210_SFC_TX_INT_SET:
+
+	case TEGRA210_SFC_SOFT_RESET:
+	case TEGRA210_SFC_STATUS:
+	case TEGRA210_SFC_INT_STATUS:
+	case TEGRA210_SFC_CFG_RAM_CTRL:
+	case TEGRA210_SFC_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_sfc_precious_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_SFC_CFG_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_config tegra210_sfc_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+	.max_register		= TEGRA210_SFC_CFG_RAM_DATA,
+	.writeable_reg		= tegra210_sfc_wr_reg,
+	.readable_reg		= tegra210_sfc_rd_reg,
+	.volatile_reg		= tegra210_sfc_volatile_reg,
+	.precious_reg		= tegra210_sfc_precious_reg,
+	.reg_defaults		= tegra210_sfc_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(tegra210_sfc_reg_defaults),
+	.cache_type		= REGCACHE_FLAT,
+};
+
+static const struct of_device_id tegra210_sfc_of_match[] = {
+	{ .compatible = "nvidia,tegra210-sfc" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, tegra210_sfc_of_match);
+
+static int tegra210_sfc_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct tegra210_sfc *sfc;
+	void __iomem *regs;
+	int err;
+
+	sfc = devm_kzalloc(dev, sizeof(*sfc), GFP_KERNEL);
+	if (!sfc)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, sfc);
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	sfc->regmap = devm_regmap_init_mmio(dev, regs,
+					    &tegra210_sfc_regmap_config);
+	if (IS_ERR(sfc->regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(sfc->regmap);
+	}
+
+	regcache_cache_only(sfc->regmap, true);
+
+	err = devm_snd_soc_register_component(dev, &tegra210_sfc_cmpnt,
+					      tegra210_sfc_dais,
+					      ARRAY_SIZE(tegra210_sfc_dais));
+	if (err) {
+		dev_err(dev, "can't register SFC component, err: %d\n", err);
+		return err;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+}
+
+static int tegra210_sfc_platform_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct dev_pm_ops tegra210_sfc_pm_ops = {
+	SET_RUNTIME_PM_OPS(tegra210_sfc_runtime_suspend,
+			   tegra210_sfc_runtime_resume, NULL)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
+};
+
+static struct platform_driver tegra210_sfc_driver = {
+	.driver = {
+		.name = "tegra210-sfc",
+		.of_match_table = tegra210_sfc_of_match,
+		.pm = &tegra210_sfc_pm_ops,
+	},
+	.probe = tegra210_sfc_platform_probe,
+	.remove = tegra210_sfc_platform_remove,
+};
+module_platform_driver(tegra210_sfc_driver)
+
+MODULE_AUTHOR("Arun Shamanna Lakshmi <aruns at nvidia.com>");
+MODULE_DESCRIPTION("Tegra210 SFC ASoC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/tegra/tegra210_sfc.h b/sound/soc/tegra/tegra210_sfc.h
new file mode 100644
index 0000000..5a6b66e
--- /dev/null
+++ b/sound/soc/tegra/tegra210_sfc.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * tegra210_sfc.h - Definitions for Tegra210 SFC driver
+ *
+ * Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
+ *
+ */
+
+#ifndef __TEGRA210_SFC_H__
+#define __TEGRA210_SFC_H__
+
+/*
+ * SFC_RX registers are with respect to XBAR.
+ * The data comes from XBAR to SFC.
+ */
+#define TEGRA210_SFC_RX_STATUS			0x0c
+#define TEGRA210_SFC_RX_INT_STATUS		0x10
+#define TEGRA210_SFC_RX_INT_MASK		0x14
+#define TEGRA210_SFC_RX_INT_SET			0x18
+#define TEGRA210_SFC_RX_INT_CLEAR		0x1c
+#define TEGRA210_SFC_RX_CIF_CTRL		0x20
+#define TEGRA210_SFC_RX_FREQ			0x24
+
+/*
+ * SFC_TX registers are with respect to XBAR.
+ * The data goes out of SFC.
+ */
+#define TEGRA210_SFC_TX_STATUS			0x4c
+#define TEGRA210_SFC_TX_INT_STATUS		0x50
+#define TEGRA210_SFC_TX_INT_MASK		0x54
+#define TEGRA210_SFC_TX_INT_SET			0x58
+#define TEGRA210_SFC_TX_INT_CLEAR		0x5c
+#define TEGRA210_SFC_TX_CIF_CTRL		0x60
+#define TEGRA210_SFC_TX_FREQ			0x64
+
+/* Register offsets from TEGRA210_SFC*_BASE */
+#define TEGRA210_SFC_ENABLE			0x80
+#define TEGRA210_SFC_SOFT_RESET			0x84
+#define TEGRA210_SFC_CG				0x88
+#define TEGRA210_SFC_STATUS			0x8c
+#define TEGRA210_SFC_INT_STATUS			0x90
+#define TEGRA210_SFC_COEF_RAM			0xbc
+#define TEGRA210_SFC_CFG_RAM_CTRL		0xc0
+#define TEGRA210_SFC_CFG_RAM_DATA		0xc4
+
+/* Fields in TEGRA210_SFC_ENABLE */
+#define TEGRA210_SFC_EN_SHIFT			0
+#define TEGRA210_SFC_EN				(1 << TEGRA210_SFC_EN_SHIFT)
+
+#define TEGRA210_SFC_NUM_RATES 12
+
+/* Fields in TEGRA210_SFC_COEF_RAM */
+#define TEGRA210_SFC_COEF_RAM_EN		BIT(0)
+
+#define TEGRA210_SFC_SOFT_RESET_EN              BIT(0)
+
+/* Coefficients */
+#define TEGRA210_SFC_COEF_RAM_DEPTH		64
+#define TEGRA210_SFC_RAM_CTRL_RW_WRITE		(1 << 14)
+#define TEGRA210_SFC_RAM_CTRL_ADDR_INIT_EN	(1 << 13)
+#define TEGRA210_SFC_RAM_CTRL_SEQ_ACCESS_EN	(1 << 12)
+
+
+enum tegra210_sfc_path {
+	SFC_RX_PATH,
+	SFC_TX_PATH,
+	SFC_PATHS,
+};
+
+struct tegra210_sfc {
+	unsigned int mono_to_stereo[SFC_PATHS];
+	unsigned int stereo_to_mono[SFC_PATHS];
+	unsigned int srate_out;
+	unsigned int srate_in;
+	struct regmap *regmap;
+};
+
+#endif
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:56 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:56 +0530
Subject: [PATCH 10/13] ASoC: tegra: Add Tegra210 based Mixer driver
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-11-git-send-email-spujar@nvidia.com>

The Mixer supports mixing of up to ten 7.1 audio input streams and
generate five outputs (each of which can be any combination of the
ten input streams)

This patch registers Mixer driver with ASoC framework. The component
driver exposes DAPM widgets, routes and kcontrols for the device.
The DAI driver exposes Mixer interfaces, which can be used to connect
different components in the ASoC layer. Makefile and Kconfig support
is added to allow build the driver. It can be enabled in the DT via
"nvidia,tegra210-amixer" compatible binding.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 sound/soc/tegra/Kconfig          |  10 +
 sound/soc/tegra/Makefile         |   2 +
 sound/soc/tegra/tegra210_mixer.c | 667 +++++++++++++++++++++++++++++++++++++++
 sound/soc/tegra/tegra210_mixer.h | 100 ++++++
 4 files changed, 779 insertions(+)
 create mode 100644 sound/soc/tegra/tegra210_mixer.c
 create mode 100644 sound/soc/tegra/tegra210_mixer.h

diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index fd4a8d6..cd45487 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -146,6 +146,16 @@ config SND_SOC_TEGRA210_ADX
 	  except that the data flow direction is reversed.
 	  Say Y or M if you want to add support for Tegra210 ADX module.
 
+config SND_SOC_TEGRA210_MIXER
+	tristate "Tegra210 Mixer module"
+	help
+	  Config to enable the Mixer module which can help to mix multiple
+	  audio streams. It supports mixing of upto 10 input streams,
+	  where each stream can contain maximum of 8 channels. It supports
+	  5 output each of which can be a mix of any combination of 10
+	  input streams.
+	  Say Y or M if you want to add support for Tegra210 Mixer module.
+
 config SND_SOC_TEGRA_AUDIO_GRAPH_CARD
 	tristate "Audio Graph Card based Tegra driver"
 	depends on SND_AUDIO_GRAPH_CARD
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 8eb17ad..f19d566 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -17,6 +17,7 @@ snd-soc-tegra210-mvc-objs := tegra210_mvc.o
 snd-soc-tegra210-sfc-objs := tegra210_sfc.o
 snd-soc-tegra210-amx-objs := tegra210_amx.o
 snd-soc-tegra210-adx-objs := tegra210_adx.o
+snd-soc-tegra210-mixer-objs := tegra210_mixer.o
 
 obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
 obj-$(CONFIG_SND_SOC_TEGRA20_AC97) += snd-soc-tegra20-ac97.o
@@ -34,6 +35,7 @@ obj-$(CONFIG_SND_SOC_TEGRA210_MVC) += snd-soc-tegra210-mvc.o
 obj-$(CONFIG_SND_SOC_TEGRA210_SFC) += snd-soc-tegra210-sfc.o
 obj-$(CONFIG_SND_SOC_TEGRA210_AMX) += snd-soc-tegra210-amx.o
 obj-$(CONFIG_SND_SOC_TEGRA210_ADX) += snd-soc-tegra210-adx.o
+obj-$(CONFIG_SND_SOC_TEGRA210_MIXER) += snd-soc-tegra210-mixer.o
 
 # Tegra machine Support
 snd-soc-tegra-wm8903-objs := tegra_wm8903.o
diff --git a/sound/soc/tegra/tegra210_mixer.c b/sound/soc/tegra/tegra210_mixer.c
new file mode 100644
index 0000000..54a0d38
--- /dev/null
+++ b/sound/soc/tegra/tegra210_mixer.c
@@ -0,0 +1,667 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// tegra210_mixer.c - Tegra210 MIXER driver
+//
+// Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "tegra210_mixer.h"
+#include "tegra_cif.h"
+
+#define MIXER_REG(reg, id)	((reg) + ((id) * TEGRA210_MIXER_REG_STRIDE))
+#define MIXER_REG_BASE(reg)	((reg) % TEGRA210_MIXER_REG_STRIDE)
+
+#define MIXER_GAIN_CFG_RAM_ADDR(id)					\
+	(TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_0 +				\
+	 ((id) * TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_STRIDE))
+
+#define MIXER_RX_REG_DEFAULTS(id)					\
+	{ MIXER_REG(TEGRA210_MIXER_RX1_CIF_CTRL, id), 0x00007700},	\
+	{ MIXER_REG(TEGRA210_MIXER_RX1_CTRL, id), 0x00010823},	\
+	{ MIXER_REG(TEGRA210_MIXER_RX1_PEAK_CTRL, id), 0x000012c0}
+
+#define MIXER_TX_REG_DEFAULTS(id)					\
+	{ MIXER_REG(TEGRA210_MIXER_TX1_INT_MASK, (id)), 0x00000001},	\
+	{ MIXER_REG(TEGRA210_MIXER_TX1_CIF_CTRL, (id)), 0x00007700}
+
+#define REG_DURATION_PARAM(reg, i) ((reg) + NUM_GAIN_POLY_COEFFS + 1 + (i))
+
+static const struct reg_default tegra210_mixer_reg_defaults[] = {
+	/* Inputs */
+	MIXER_RX_REG_DEFAULTS(0),
+	MIXER_RX_REG_DEFAULTS(1),
+	MIXER_RX_REG_DEFAULTS(2),
+	MIXER_RX_REG_DEFAULTS(3),
+	MIXER_RX_REG_DEFAULTS(4),
+	MIXER_RX_REG_DEFAULTS(5),
+	MIXER_RX_REG_DEFAULTS(6),
+	MIXER_RX_REG_DEFAULTS(7),
+	MIXER_RX_REG_DEFAULTS(8),
+	MIXER_RX_REG_DEFAULTS(9),
+	/* Outputs */
+	MIXER_TX_REG_DEFAULTS(0),
+	MIXER_TX_REG_DEFAULTS(1),
+	MIXER_TX_REG_DEFAULTS(2),
+	MIXER_TX_REG_DEFAULTS(3),
+	MIXER_TX_REG_DEFAULTS(4),
+
+	{ TEGRA210_MIXER_CG, 0x00000001},
+	{ TEGRA210_MIXER_GAIN_CFG_RAM_CTRL, 0x00004000},
+	{ TEGRA210_MIXER_PEAKM_RAM_CTRL, 0x00004000},
+	{ TEGRA210_MIXER_ENABLE, 0x1 },
+};
+
+/* Default gain parameters */
+static const struct tegra210_mixer_gain_params gain_params = {
+	/* Polynomial coefficients */
+	{ 0, 0, 0, 0, 0, 0, 0, 0x1000000, 0 },
+	/* Gain value */
+	0x10000,
+	/* Duration Parameters */
+	{ 0, 0, 0x400, 0x8000000 },
+};
+
+static int __maybe_unused tegra210_mixer_runtime_suspend(struct device *dev)
+{
+	struct tegra210_mixer *mixer = dev_get_drvdata(dev);
+
+	regcache_cache_only(mixer->regmap, true);
+	regcache_mark_dirty(mixer->regmap);
+
+	return 0;
+}
+
+static int __maybe_unused tegra210_mixer_runtime_resume(struct device *dev)
+{
+	struct tegra210_mixer *mixer = dev_get_drvdata(dev);
+
+	regcache_cache_only(mixer->regmap, false);
+	regcache_sync(mixer->regmap);
+
+	return 0;
+}
+
+static int tegra210_mixer_write_ram(struct tegra210_mixer *mixer,
+				    unsigned int addr,
+				    unsigned int coef)
+{
+	unsigned int reg, val;
+	int err;
+
+	/* Check if busy */
+	err = regmap_read_poll_timeout(mixer->regmap,
+				       TEGRA210_MIXER_GAIN_CFG_RAM_CTRL,
+				       val, !(val & 0x80000000), 10, 10000);
+	if (err < 0)
+		return err;
+
+	reg = (addr << TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_SHIFT) &
+	      TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_MASK;
+	reg |= TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_INIT_EN;
+	reg |= TEGRA210_MIXER_GAIN_CFG_RAM_RW_WRITE;
+	reg |= TEGRA210_MIXER_GAIN_CFG_RAM_SEQ_ACCESS_EN;
+
+	regmap_write(mixer->regmap,
+		     TEGRA210_MIXER_GAIN_CFG_RAM_CTRL,
+		     reg);
+	regmap_write(mixer->regmap,
+		     TEGRA210_MIXER_GAIN_CFG_RAM_DATA,
+		     coef);
+
+	return 0;
+}
+
+static int tegra210_mixer_configure_gain(struct snd_soc_component *cmpnt,
+					 unsigned int id, bool instant_gain)
+{
+	struct tegra210_mixer *mixer = snd_soc_component_get_drvdata(cmpnt);
+	unsigned int reg = MIXER_GAIN_CFG_RAM_ADDR(id);
+	int err, i;
+
+	pm_runtime_get_sync(cmpnt->dev);
+
+	/* Write default gain poly coefficients */
+	for (i = 0; i < NUM_GAIN_POLY_COEFFS; i++) {
+		err = tegra210_mixer_write_ram(mixer, reg + i,
+					       gain_params.poly_coeff[i]);
+
+		if (err < 0)
+			goto rpm_put;
+	}
+
+	/* Write stored gain value */
+	err = tegra210_mixer_write_ram(mixer, reg + NUM_GAIN_POLY_COEFFS,
+				       mixer->gain_value[id]);
+	if (err < 0)
+		goto rpm_put;
+
+	/* Write duration parameters */
+	for (i = 0; i < NUM_DURATION_PARMS; i++) {
+		int val;
+
+		if (instant_gain)
+			val = 1;
+		else
+			val = gain_params.duration[i];
+
+		err = tegra210_mixer_write_ram(mixer,
+					       REG_DURATION_PARAM(reg, i),
+					       val);
+		if (err < 0)
+			goto rpm_put;
+	}
+
+	/* Trigger to apply gain configurations */
+	err = tegra210_mixer_write_ram(mixer, reg + REG_CFG_DONE_TRIGGER,
+				       VAL_CFG_DONE_TRIGGER);
+
+rpm_put:
+	pm_runtime_put(cmpnt->dev);
+
+	return err;
+}
+
+static int tegra210_mixer_get_gain(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_mixer *mixer = snd_soc_component_get_drvdata(cmpnt);
+	unsigned int reg = mc->reg;
+	unsigned int i;
+
+	i = (reg - TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_0) /
+	    TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_STRIDE;
+
+	ucontrol->value.integer.value[0] = mixer->gain_value[i];
+
+	return 0;
+}
+
+static int tegra210_mixer_put_gain(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+	struct tegra210_mixer *mixer = snd_soc_component_get_drvdata(cmpnt);
+	unsigned int reg = mc->reg, id;
+	bool instant_gain = false;
+
+	if (strstr(kcontrol->id.name, "Instant Gain Volume"))
+		instant_gain = true;
+
+	/* Save gain value for specific MIXER input */
+	id = (reg - TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_0) /
+	     TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_STRIDE;
+
+	mixer->gain_value[id] = ucontrol->value.integer.value[0];
+
+	return tegra210_mixer_configure_gain(cmpnt, id, instant_gain);
+}
+
+static int tegra210_mixer_set_audio_cif(struct tegra210_mixer *mixer,
+					struct snd_pcm_hw_params *params,
+					unsigned int reg,
+					unsigned int id)
+{
+	unsigned int channels, audio_bits;
+	struct tegra_cif_conf cif_conf;
+
+	memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
+
+	channels = params_channels(params);
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		audio_bits = TEGRA_ACIF_BITS_16;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		audio_bits = TEGRA_ACIF_BITS_32;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	cif_conf.audio_ch = channels;
+	cif_conf.client_ch = channels;
+	cif_conf.audio_bits = audio_bits;
+	cif_conf.client_bits = audio_bits;
+
+	tegra_set_cif(mixer->regmap,
+		      reg + (id * TEGRA210_MIXER_REG_STRIDE),
+		      &cif_conf);
+
+	return 0;
+}
+
+static int tegra210_mixer_in_hw_params(struct snd_pcm_substream *substream,
+				       struct snd_pcm_hw_params *params,
+				       struct snd_soc_dai *dai)
+{
+	struct tegra210_mixer *mixer = snd_soc_dai_get_drvdata(dai);
+	int err;
+
+	err = tegra210_mixer_set_audio_cif(mixer, params,
+					   TEGRA210_MIXER_RX1_CIF_CTRL,
+					   dai->id);
+	if (err < 0)
+		return err;
+
+	return tegra210_mixer_configure_gain(dai->component, dai->id, false);
+}
+
+static int tegra210_mixer_out_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *params,
+					struct snd_soc_dai *dai)
+{
+	struct tegra210_mixer *mixer = snd_soc_dai_get_drvdata(dai);
+
+	return tegra210_mixer_set_audio_cif(mixer, params,
+					    TEGRA210_MIXER_TX1_CIF_CTRL,
+					    dai->id - TEGRA210_MIXER_RX_MAX);
+}
+
+static struct snd_soc_dai_ops tegra210_mixer_out_dai_ops = {
+	.hw_params	= tegra210_mixer_out_hw_params,
+};
+
+static struct snd_soc_dai_ops tegra210_mixer_in_dai_ops = {
+	.hw_params	= tegra210_mixer_in_hw_params,
+};
+
+#define IN_DAI(id)						\
+	{							\
+		.name = "MIXER-RX-CIF"#id,			\
+		.playback = {					\
+			.stream_name = "RX" #id "-CIF-Playback",\
+			.channels_min = 1,			\
+			.channels_max = 8,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				SNDRV_PCM_FMTBIT_S16_LE |	\
+				SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.capture = {					\
+			.stream_name = "RX" #id "-CIF-Capture",	\
+			.channels_min = 1,			\
+			.channels_max = 8,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				SNDRV_PCM_FMTBIT_S16_LE |	\
+				SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.ops = &tegra210_mixer_in_dai_ops,		\
+	}
+
+#define OUT_DAI(id)						\
+	{							\
+		.name = "MIXER-TX-CIF" #id,			\
+		.playback = {					\
+			.stream_name = "TX" #id "-CIF-Playback",\
+			.channels_min = 1,			\
+			.channels_max = 8,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				SNDRV_PCM_FMTBIT_S16_LE |	\
+				SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.capture = {					\
+			.stream_name = "TX" #id "-CIF-Capture",	\
+			.channels_min = 1,			\
+			.channels_max = 8,			\
+			.rates = SNDRV_PCM_RATE_8000_192000,	\
+			.formats = SNDRV_PCM_FMTBIT_S8 |	\
+				SNDRV_PCM_FMTBIT_S16_LE |	\
+				SNDRV_PCM_FMTBIT_S32_LE,	\
+		},						\
+		.ops = &tegra210_mixer_out_dai_ops,		\
+	}
+
+static struct snd_soc_dai_driver tegra210_mixer_dais[] = {
+	/* Mixer Input */
+	IN_DAI(1),
+	IN_DAI(2),
+	IN_DAI(3),
+	IN_DAI(4),
+	IN_DAI(5),
+	IN_DAI(6),
+	IN_DAI(7),
+	IN_DAI(8),
+	IN_DAI(9),
+	IN_DAI(10),
+
+	/* Mixer Output */
+	OUT_DAI(1),
+	OUT_DAI(2),
+	OUT_DAI(3),
+	OUT_DAI(4),
+	OUT_DAI(5),
+};
+
+#define ADDER_CTRL_DECL(name, reg)			\
+	static const struct snd_kcontrol_new name[] = {	\
+		SOC_DAPM_SINGLE("RX1", reg, 0, 1, 0),	\
+		SOC_DAPM_SINGLE("RX2", reg, 1, 1, 0),	\
+		SOC_DAPM_SINGLE("RX3", reg, 2, 1, 0),	\
+		SOC_DAPM_SINGLE("RX4", reg, 3, 1, 0),	\
+		SOC_DAPM_SINGLE("RX5", reg, 4, 1, 0),	\
+		SOC_DAPM_SINGLE("RX6", reg, 5, 1, 0),	\
+		SOC_DAPM_SINGLE("RX7", reg, 6, 1, 0),	\
+		SOC_DAPM_SINGLE("RX8", reg, 7, 1, 0),	\
+		SOC_DAPM_SINGLE("RX9", reg, 8, 1, 0),	\
+		SOC_DAPM_SINGLE("RX10", reg, 9, 1, 0),	\
+	}
+
+ADDER_CTRL_DECL(adder1, TEGRA210_MIXER_TX1_ADDER_CONFIG);
+ADDER_CTRL_DECL(adder2, TEGRA210_MIXER_TX2_ADDER_CONFIG);
+ADDER_CTRL_DECL(adder3, TEGRA210_MIXER_TX3_ADDER_CONFIG);
+ADDER_CTRL_DECL(adder4, TEGRA210_MIXER_TX4_ADDER_CONFIG);
+ADDER_CTRL_DECL(adder5, TEGRA210_MIXER_TX5_ADDER_CONFIG);
+
+#define GAIN_CTRL(id)	\
+	SOC_SINGLE_EXT("RX" #id " Gain Volume",			\
+		       MIXER_GAIN_CFG_RAM_ADDR((id) - 1), 0,	\
+		       0x20000, 0, tegra210_mixer_get_gain,	\
+		       tegra210_mixer_put_gain),		\
+	SOC_SINGLE_EXT("RX" #id " Instant Gain Volume",		\
+		       MIXER_GAIN_CFG_RAM_ADDR((id) - 1), 0,	\
+		       0x20000, 0, tegra210_mixer_get_gain,	\
+		       tegra210_mixer_put_gain),
+
+/* Volume controls for all MIXER inputs */
+static const struct snd_kcontrol_new tegra210_mixer_gain_ctls[] = {
+	GAIN_CTRL(1)
+	GAIN_CTRL(2)
+	GAIN_CTRL(3)
+	GAIN_CTRL(4)
+	GAIN_CTRL(5)
+	GAIN_CTRL(6)
+	GAIN_CTRL(7)
+	GAIN_CTRL(8)
+	GAIN_CTRL(9)
+	GAIN_CTRL(10)
+};
+
+static const struct snd_soc_dapm_widget tegra210_mixer_widgets[] = {
+	SND_SOC_DAPM_AIF_IN("RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX2", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX3", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX4", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX5", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX6", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX7", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX8", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX9", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("RX10", NULL, 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("TX1", NULL, 0, TEGRA210_MIXER_TX1_ENABLE, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("TX2", NULL, 0, TEGRA210_MIXER_TX2_ENABLE, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("TX3", NULL, 0, TEGRA210_MIXER_TX3_ENABLE, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("TX4", NULL, 0, TEGRA210_MIXER_TX4_ENABLE, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("TX5", NULL, 0, TEGRA210_MIXER_TX5_ENABLE, 0, 0),
+	SND_SOC_DAPM_MIXER("Adder1", SND_SOC_NOPM, 1, 0, adder1,
+			   ARRAY_SIZE(adder1)),
+	SND_SOC_DAPM_MIXER("Adder2", SND_SOC_NOPM, 1, 0, adder2,
+			   ARRAY_SIZE(adder2)),
+	SND_SOC_DAPM_MIXER("Adder3", SND_SOC_NOPM, 1, 0, adder3,
+			   ARRAY_SIZE(adder3)),
+	SND_SOC_DAPM_MIXER("Adder4", SND_SOC_NOPM, 1, 0, adder4,
+			   ARRAY_SIZE(adder4)),
+	SND_SOC_DAPM_MIXER("Adder5", SND_SOC_NOPM, 1, 0, adder5,
+			   ARRAY_SIZE(adder5)),
+};
+
+#define RX_ROUTES(id, sname)						   \
+	{ "RX" #id " XBAR-" sname,	NULL,	"RX" #id " XBAR-TX" },	   \
+	{ "RX" #id "-CIF-" sname,	NULL,	"RX" #id " XBAR-" sname }, \
+	{ "RX" #id,			NULL,	"RX" #id "-CIF-" sname }
+
+#define MIXER_RX_ROUTES(id)		\
+	RX_ROUTES(id, "Playback"),	\
+	RX_ROUTES(id, "Capture")
+
+#define ADDER_ROUTES(id, sname)						  \
+	{ "Adder" #id,			"RX1",	"RX1" },		  \
+	{ "Adder" #id,			"RX2",	"RX2" },		  \
+	{ "Adder" #id,			"RX3",	"RX3" },		  \
+	{ "Adder" #id,			"RX4",	"RX4" },		  \
+	{ "Adder" #id,			"RX5",	"RX5" },		  \
+	{ "Adder" #id,			"RX6",	"RX6" },		  \
+	{ "Adder" #id,			"RX7",	"RX7" },		  \
+	{ "Adder" #id,			"RX8",	"RX8" },		  \
+	{ "Adder" #id,			"RX9",	"RX9" },		  \
+	{ "Adder" #id,			"RX10",	"RX10" },		  \
+	{ "TX" #id,			NULL,	"Adder" #id },		  \
+	{ "TX" #id "-CIF-" sname,	NULL,	"TX" #id },		  \
+	{ "TX" #id " XBAR-" sname,	NULL,	"TX" #id "-CIF-" sname }, \
+	{ "TX" #id " XBAR-RX",		NULL,	"TX" #id " XBAR-" sname } \
+
+#define TX_ROUTES(id, sname)		\
+	ADDER_ROUTES(1, sname),		\
+	ADDER_ROUTES(2, sname),		\
+	ADDER_ROUTES(3, sname),		\
+	ADDER_ROUTES(4, sname),		\
+	ADDER_ROUTES(5, sname)
+
+#define MIXER_TX_ROUTES(id)		\
+	TX_ROUTES(id, "Playback"),	\
+	TX_ROUTES(id, "Capture")
+
+static const struct snd_soc_dapm_route tegra210_mixer_routes[] = {
+	/* Input */
+	MIXER_RX_ROUTES(1),
+	MIXER_RX_ROUTES(2),
+	MIXER_RX_ROUTES(3),
+	MIXER_RX_ROUTES(4),
+	MIXER_RX_ROUTES(5),
+	MIXER_RX_ROUTES(6),
+	MIXER_RX_ROUTES(7),
+	MIXER_RX_ROUTES(8),
+	MIXER_RX_ROUTES(9),
+	MIXER_RX_ROUTES(10),
+	/* Output */
+	MIXER_TX_ROUTES(1),
+	MIXER_TX_ROUTES(2),
+	MIXER_TX_ROUTES(3),
+	MIXER_TX_ROUTES(4),
+	MIXER_TX_ROUTES(5),
+};
+
+static const struct snd_soc_component_driver tegra210_mixer_cmpnt = {
+	.dapm_widgets		= tegra210_mixer_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(tegra210_mixer_widgets),
+	.dapm_routes		= tegra210_mixer_routes,
+	.num_dapm_routes	= ARRAY_SIZE(tegra210_mixer_routes),
+	.controls		= tegra210_mixer_gain_ctls,
+	.num_controls		= ARRAY_SIZE(tegra210_mixer_gain_ctls),
+};
+
+static bool tegra210_mixer_wr_reg(struct device *dev,
+				unsigned int reg)
+{
+	if (reg < TEGRA210_MIXER_RX_LIMIT)
+		reg = MIXER_REG_BASE(reg);
+	else if (reg < TEGRA210_MIXER_TX_LIMIT)
+		reg = MIXER_REG_BASE(reg) + TEGRA210_MIXER_TX1_ENABLE;
+
+	switch (reg) {
+	case TEGRA210_MIXER_RX1_SOFT_RESET:
+	case TEGRA210_MIXER_RX1_CIF_CTRL ... TEGRA210_MIXER_RX1_PEAK_CTRL:
+
+	case TEGRA210_MIXER_TX1_ENABLE:
+	case TEGRA210_MIXER_TX1_SOFT_RESET:
+	case TEGRA210_MIXER_TX1_INT_MASK ... TEGRA210_MIXER_TX1_ADDER_CONFIG:
+
+	case TEGRA210_MIXER_ENABLE ... TEGRA210_MIXER_CG:
+	case TEGRA210_MIXER_GAIN_CFG_RAM_CTRL ... TEGRA210_MIXER_CTRL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_mixer_rd_reg(struct device *dev,
+				unsigned int reg)
+{
+	if (reg < TEGRA210_MIXER_RX_LIMIT)
+		reg = MIXER_REG_BASE(reg);
+	else if (reg < TEGRA210_MIXER_TX_LIMIT)
+		reg = MIXER_REG_BASE(reg) + TEGRA210_MIXER_TX1_ENABLE;
+
+	switch (reg) {
+	case TEGRA210_MIXER_RX1_SOFT_RESET ... TEGRA210_MIXER_RX1_SAMPLE_COUNT:
+	case TEGRA210_MIXER_TX1_ENABLE ... TEGRA210_MIXER_TX1_ADDER_CONFIG:
+	case TEGRA210_MIXER_ENABLE ... TEGRA210_MIXER_CTRL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_mixer_volatile_reg(struct device *dev,
+				unsigned int reg)
+{
+	if (reg < TEGRA210_MIXER_RX_LIMIT)
+		reg = MIXER_REG_BASE(reg);
+	else if (reg < TEGRA210_MIXER_TX_LIMIT)
+		reg = MIXER_REG_BASE(reg) + TEGRA210_MIXER_TX1_ENABLE;
+
+	switch (reg) {
+	case TEGRA210_MIXER_RX1_SOFT_RESET:
+	case TEGRA210_MIXER_RX1_STATUS:
+
+	case TEGRA210_MIXER_TX1_SOFT_RESET:
+	case TEGRA210_MIXER_TX1_STATUS:
+	case TEGRA210_MIXER_TX1_INT_STATUS:
+	case TEGRA210_MIXER_TX1_INT_SET:
+
+	case TEGRA210_MIXER_SOFT_RESET:
+	case TEGRA210_MIXER_STATUS:
+	case TEGRA210_MIXER_INT_STATUS:
+	case TEGRA210_MIXER_GAIN_CFG_RAM_CTRL:
+	case TEGRA210_MIXER_GAIN_CFG_RAM_DATA:
+	case TEGRA210_MIXER_PEAKM_RAM_CTRL:
+	case TEGRA210_MIXER_PEAKM_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool tegra210_mixer_precious_reg(struct device *dev,
+				unsigned int reg)
+{
+	switch (reg) {
+	case TEGRA210_MIXER_GAIN_CFG_RAM_DATA:
+	case TEGRA210_MIXER_PEAKM_RAM_DATA:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_config tegra210_mixer_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+	.max_register		= TEGRA210_MIXER_CTRL,
+	.writeable_reg		= tegra210_mixer_wr_reg,
+	.readable_reg		= tegra210_mixer_rd_reg,
+	.volatile_reg		= tegra210_mixer_volatile_reg,
+	.precious_reg		= tegra210_mixer_precious_reg,
+	.reg_defaults		= tegra210_mixer_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(tegra210_mixer_reg_defaults),
+	.cache_type		= REGCACHE_FLAT,
+};
+
+static const struct of_device_id tegra210_mixer_of_match[] = {
+	{ .compatible = "nvidia,tegra210-amixer" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, tegra210_mixer_of_match);
+
+static int tegra210_mixer_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct tegra210_mixer *mixer;
+	void __iomem *regs;
+	int err, i;
+
+	mixer = devm_kzalloc(dev, sizeof(*mixer), GFP_KERNEL);
+	if (!mixer)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, mixer);
+
+	/* Use default gain value for all MIXER inputs */
+	for (i = 0; i < TEGRA210_MIXER_RX_MAX; i++)
+		mixer->gain_value[i] = gain_params.gain_value;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	mixer->regmap = devm_regmap_init_mmio(dev, regs,
+					      &tegra210_mixer_regmap_config);
+	if (IS_ERR(mixer->regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(mixer->regmap);
+	}
+
+	regcache_cache_only(mixer->regmap, true);
+
+	err = devm_snd_soc_register_component(dev, &tegra210_mixer_cmpnt,
+					      tegra210_mixer_dais,
+					      ARRAY_SIZE(tegra210_mixer_dais));
+	if (err) {
+		dev_err(dev, "can't register MIXER component, err: %d\n", err);
+		return err;
+	}
+
+	pm_runtime_enable(dev);
+
+	return 0;
+}
+
+static int tegra210_mixer_platform_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct dev_pm_ops tegra210_mixer_pm_ops = {
+	SET_RUNTIME_PM_OPS(tegra210_mixer_runtime_suspend,
+			   tegra210_mixer_runtime_resume, NULL)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
+};
+
+static struct platform_driver tegra210_mixer_driver = {
+	.driver = {
+		.name = "tegra210_mixer",
+		.of_match_table = tegra210_mixer_of_match,
+		.pm = &tegra210_mixer_pm_ops,
+	},
+	.probe = tegra210_mixer_platform_probe,
+	.remove = tegra210_mixer_platform_remove,
+};
+module_platform_driver(tegra210_mixer_driver);
+
+MODULE_AUTHOR("Arun Shamanna Lakshmi <aruns at nvidia.com>");
+MODULE_DESCRIPTION("Tegra210 MIXER ASoC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/tegra/tegra210_mixer.h b/sound/soc/tegra/tegra210_mixer.h
new file mode 100644
index 0000000..a330530
--- /dev/null
+++ b/sound/soc/tegra/tegra210_mixer.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * tegra210_mixer.h - Definitions for Tegra210 MIXER driver
+ *
+ * Copyright (c) 2021, NVIDIA CORPORATION.  All rights reserved.
+ *
+ */
+
+#ifndef __TEGRA210_MIXER_H__
+#define __TEGRA210_MIXER_H__
+
+/* XBAR_RX related MIXER offsets */
+#define TEGRA210_MIXER_RX1_SOFT_RESET	0x04
+#define TEGRA210_MIXER_RX1_STATUS	0x10
+#define TEGRA210_MIXER_RX1_CIF_CTRL	0x24
+#define TEGRA210_MIXER_RX1_CTRL		0x28
+#define TEGRA210_MIXER_RX1_PEAK_CTRL	0x2c
+#define TEGRA210_MIXER_RX1_SAMPLE_COUNT	0x30
+
+/* XBAR_TX related MIXER offsets */
+#define TEGRA210_MIXER_TX1_ENABLE	0x280
+#define TEGRA210_MIXER_TX1_SOFT_RESET	0x284
+#define TEGRA210_MIXER_TX1_STATUS	0x290
+#define TEGRA210_MIXER_TX1_INT_STATUS	0x294
+#define TEGRA210_MIXER_TX1_INT_MASK	0x298
+#define TEGRA210_MIXER_TX1_INT_SET	0x29c
+#define TEGRA210_MIXER_TX1_INT_CLEAR	0x2a0
+#define TEGRA210_MIXER_TX1_CIF_CTRL	0x2a4
+#define TEGRA210_MIXER_TX1_ADDER_CONFIG	0x2a8
+
+/* MIXER related offsets */
+#define TEGRA210_MIXER_ENABLE			0x400
+#define TEGRA210_MIXER_SOFT_RESET		0x404
+#define TEGRA210_MIXER_CG			0x408
+#define TEGRA210_MIXER_STATUS			0x410
+#define TEGRA210_MIXER_INT_STATUS		0x414
+#define TEGRA210_MIXER_GAIN_CFG_RAM_CTRL	0x42c
+#define TEGRA210_MIXER_GAIN_CFG_RAM_DATA	0x430
+#define TEGRA210_MIXER_PEAKM_RAM_CTRL		0x434
+#define TEGRA210_MIXER_PEAKM_RAM_DATA		0x438
+#define TEGRA210_MIXER_CTRL			0x43c
+
+#define TEGRA210_MIXER_TX2_ADDER_CONFIG	(TEGRA210_MIXER_TX1_ADDER_CONFIG + TEGRA210_MIXER_REG_STRIDE)
+#define TEGRA210_MIXER_TX3_ADDER_CONFIG	(TEGRA210_MIXER_TX2_ADDER_CONFIG + TEGRA210_MIXER_REG_STRIDE)
+#define TEGRA210_MIXER_TX4_ADDER_CONFIG	(TEGRA210_MIXER_TX3_ADDER_CONFIG + TEGRA210_MIXER_REG_STRIDE)
+#define TEGRA210_MIXER_TX5_ADDER_CONFIG	(TEGRA210_MIXER_TX4_ADDER_CONFIG + TEGRA210_MIXER_REG_STRIDE)
+
+#define TEGRA210_MIXER_TX2_ENABLE	(TEGRA210_MIXER_TX1_ENABLE + TEGRA210_MIXER_REG_STRIDE)
+#define TEGRA210_MIXER_TX3_ENABLE	(TEGRA210_MIXER_TX2_ENABLE + TEGRA210_MIXER_REG_STRIDE)
+#define TEGRA210_MIXER_TX4_ENABLE	(TEGRA210_MIXER_TX3_ENABLE + TEGRA210_MIXER_REG_STRIDE)
+#define TEGRA210_MIXER_TX5_ENABLE	(TEGRA210_MIXER_TX4_ENABLE + TEGRA210_MIXER_REG_STRIDE)
+
+/* Fields in TEGRA210_MIXER_ENABLE */
+#define TEGRA210_MIXER_ENABLE_SHIFT	0
+#define TEGRA210_MIXER_ENABLE_MASK	(1 << TEGRA210_MIXER_ENABLE_SHIFT)
+#define TEGRA210_MIXER_EN		(1 << TEGRA210_MIXER_ENABLE_SHIFT)
+
+/* Fields in TEGRA210_MIXER_GAIN_CFG_RAM_CTRL */
+#define TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_0		0x0
+#define TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_STRIDE		0x10
+
+#define TEGRA210_MIXER_GAIN_CFG_RAM_RW_SHIFT		14
+#define TEGRA210_MIXER_GAIN_CFG_RAM_RW_MASK		(1 << TEGRA210_MIXER_GAIN_CFG_RAM_RW_SHIFT)
+#define TEGRA210_MIXER_GAIN_CFG_RAM_RW_WRITE		(1 << TEGRA210_MIXER_GAIN_CFG_RAM_RW_SHIFT)
+
+#define TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_INIT_EN_SHIFT	13
+#define TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_INIT_EN_MASK	(1 << TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_INIT_EN_SHIFT)
+#define TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_INIT_EN	(1 << TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_INIT_EN_SHIFT)
+
+#define TEGRA210_MIXER_GAIN_CFG_RAM_SEQ_ACCESS_EN_SHIFT	12
+#define TEGRA210_MIXER_GAIN_CFG_RAM_SEQ_ACCESS_EN_MASK	(1 << TEGRA210_MIXER_GAIN_CFG_RAM_SEQ_ACCESS_EN_SHIFT)
+#define TEGRA210_MIXER_GAIN_CFG_RAM_SEQ_ACCESS_EN	(1 << TEGRA210_MIXER_GAIN_CFG_RAM_SEQ_ACCESS_EN_SHIFT)
+
+#define TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_SHIFT		0
+#define TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_MASK		(0x1ff << TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_SHIFT)
+
+#define TEGRA210_MIXER_REG_STRIDE	0x40
+#define TEGRA210_MIXER_RX_MAX		10
+#define TEGRA210_MIXER_RX_LIMIT		(TEGRA210_MIXER_RX_MAX * TEGRA210_MIXER_REG_STRIDE)
+#define TEGRA210_MIXER_TX_MAX		5
+#define TEGRA210_MIXER_TX_LIMIT		(TEGRA210_MIXER_RX_LIMIT + (TEGRA210_MIXER_TX_MAX * TEGRA210_MIXER_REG_STRIDE))
+
+#define REG_CFG_DONE_TRIGGER	0xf
+#define VAL_CFG_DONE_TRIGGER	0x1
+
+#define NUM_GAIN_POLY_COEFFS 9
+#define NUM_DURATION_PARMS 4
+
+struct tegra210_mixer_gain_params {
+	int poly_coeff[NUM_GAIN_POLY_COEFFS];
+	int gain_value;
+	int duration[NUM_DURATION_PARMS];
+};
+
+struct tegra210_mixer {
+	int gain_value[TEGRA210_MIXER_RX_MAX];
+	struct regmap *regmap;
+};
+
+#endif
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:57 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:57 +0530
Subject: [PATCH 11/13] arm64: defconfig: Enable few Tegra210 based AHUB drivers
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-12-git-send-email-spujar@nvidia.com>

Enable configs for following modules:
 * SFC (Sampling Frequency Converter)
 * MVC (Master Volume Control)
 * AMX (Audio Multiplexer)
 * ADX (Audio Demultiplexer)
 * Mixer

These configs are used on Tegra186 and later SoCs as well.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 arch/arm64/configs/defconfig | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 3bf6f8a..b936a23 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -773,6 +773,11 @@ CONFIG_SND_SOC_TEGRA210_DMIC=m
 CONFIG_SND_SOC_TEGRA210_I2S=m
 CONFIG_SND_SOC_TEGRA186_DSPK=m
 CONFIG_SND_SOC_TEGRA210_ADMAIF=m
+CONFIG_SND_SOC_TEGRA210_MVC=m
+CONFIG_SND_SOC_TEGRA210_SFC=m
+CONFIG_SND_SOC_TEGRA210_AMX=m
+CONFIG_SND_SOC_TEGRA210_ADX=m
+CONFIG_SND_SOC_TEGRA210_MIXER=m
 CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD=m
 CONFIG_SND_SOC_AK4613=m
 CONFIG_SND_SOC_ES7134=m
-- 
2.7.4



From spujar at nvidia.com  Fri Aug 27 02:33:58 2021
From: spujar at nvidia.com (Sameer Pujar)
Date: Fri, 27 Aug 2021 15:03:58 +0530
Subject: [PATCH 12/13] arm64: tegra: Add few AHUB devices for Tegra210 and
 later
In-Reply-To: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
Message-ID: <1630056839-6562-13-git-send-email-spujar@nvidia.com>

Add DT nodes for following AHUB devices:
 * SFC (Sampling Frequency Converter)
 * MVC (Master Volume Control)
 * AMX (Audio Multiplexer)
 * ADX (Audio Demultiplexer)
 * Mixer

Above devices are added for Tegra210, Tegra186 and Tegra194 generations
of Tegra SoC.

Signed-off-by: Sameer Pujar <spujar at nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 120 +++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 116 ++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/nvidia/tegra210.dtsi |  77 ++++++++++++++++++++
 3 files changed, 313 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index e94f8ad..0d0ada5 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -354,6 +354,126 @@
 				sound-name-prefix = "DSPK2";
 				status = "disabled";
 			};
+
+			tegra_sfc1: sfc at 2902000 {
+				compatible = "nvidia,tegra186-sfc",
+					     "nvidia,tegra210-sfc";
+				reg = <0x2902000 0x200>;
+				sound-name-prefix = "SFC1";
+				status = "disabled";
+			};
+
+			tegra_sfc2: sfc at 2902200 {
+				compatible = "nvidia,tegra186-sfc",
+					     "nvidia,tegra210-sfc";
+				reg = <0x2902200 0x200>;
+				sound-name-prefix = "SFC2";
+				status = "disabled";
+			};
+
+			tegra_sfc3: sfc at 2902400 {
+				compatible = "nvidia,tegra186-sfc",
+					     "nvidia,tegra210-sfc";
+				reg = <0x2902400 0x200>;
+				sound-name-prefix = "SFC3";
+				status = "disabled";
+			};
+
+			tegra_sfc4: sfc at 2902600 {
+				compatible = "nvidia,tegra186-sfc",
+					     "nvidia,tegra210-sfc";
+				reg = <0x2902600 0x200>;
+				sound-name-prefix = "SFC4";
+				status = "disabled";
+			};
+
+			tegra_mvc1: mvc at 290a000 {
+				compatible = "nvidia,tegra186-mvc",
+					     "nvidia,tegra210-mvc";
+				reg = <0x290a000 0x200>;
+				sound-name-prefix = "MVC1";
+				status = "disabled";
+			};
+
+			tegra_mvc2: mvc at 290a200 {
+				compatible = "nvidia,tegra186-mvc",
+					     "nvidia,tegra210-mvc";
+				reg = <0x290a200 0x200>;
+				sound-name-prefix = "MVC2";
+				status = "disabled";
+			};
+
+			tegra_amx1: amx at 2903000 {
+				compatible = "nvidia,tegra186-amx",
+					     "nvidia,tegra210-amx";
+				reg = <0x2903000 0x100>;
+				sound-name-prefix = "AMX1";
+				status = "disabled";
+			};
+
+			tegra_amx2: amx at 2903100 {
+				compatible = "nvidia,tegra186-amx",
+					     "nvidia,tegra210-amx";
+				reg = <0x2903100 0x100>;
+				sound-name-prefix = "AMX2";
+				status = "disabled";
+			};
+
+			tegra_amx3: amx at 2903200 {
+				compatible = "nvidia,tegra186-amx",
+					     "nvidia,tegra210-amx";
+				reg = <0x2903200 0x100>;
+				sound-name-prefix = "AMX3";
+				status = "disabled";
+			};
+
+			tegra_amx4: amx at 2903300 {
+				compatible = "nvidia,tegra186-amx",
+					     "nvidia,tegra210-amx";
+				reg = <0x2903300 0x100>;
+				sound-name-prefix = "AMX4";
+				status = "disabled";
+			};
+
+			tegra_adx1: adx at 2903800 {
+				compatible = "nvidia,tegra186-adx",
+					     "nvidia,tegra210-adx";
+				reg = <0x2903800 0x100>;
+				sound-name-prefix = "ADX1";
+				status = "disabled";
+			};
+
+			tegra_adx2: adx at 2903900 {
+				compatible = "nvidia,tegra186-adx",
+					     "nvidia,tegra210-adx";
+				reg = <0x2903900 0x100>;
+				sound-name-prefix = "ADX2";
+				status = "disabled";
+			};
+
+			tegra_adx3: adx at 2903a00 {
+				compatible = "nvidia,tegra186-adx",
+					     "nvidia,tegra210-adx";
+				reg = <0x2903a00 0x100>;
+				sound-name-prefix = "ADX3";
+				status = "disabled";
+			};
+
+			tegra_adx4: adx at 2903b00 {
+				compatible = "nvidia,tegra186-adx",
+					     "nvidia,tegra210-adx";
+				reg = <0x2903b00 0x100>;
+				sound-name-prefix = "ADX4";
+				status = "disabled";
+			};
+
+			tegra_amixer: amixer at 290bb00 {
+				compatible = "nvidia,tegra186-amixer",
+					     "nvidia,tegra210-amixer";
+				reg = <0x290bb00 0x800>;
+				sound-name-prefix = "MIXER";
+				status = "disabled";
+			};
 		};
 	};
 
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index c8250a3..6027d84 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -363,6 +363,122 @@
 					sound-name-prefix = "DSPK2";
 					status = "disabled";
 				};
+
+				tegra_sfc1: sfc at 2902000 {
+					compatible = "nvidia,tegra194-sfc",
+						     "nvidia,tegra210-sfc";
+					reg = <0x2902000 0x200>;
+					sound-name-prefix = "SFC1";
+					status = "disabled";
+				};
+
+				tegra_sfc2: sfc at 2902200 {
+					compatible = "nvidia,tegra194-sfc",
+						     "nvidia,tegra210-sfc";
+					reg = <0x2902200 0x200>;
+					sound-name-prefix = "SFC2";
+					status = "disabled";
+				};
+
+				tegra_sfc3: sfc at 2902400 {
+					compatible = "nvidia,tegra194-sfc",
+						     "nvidia,tegra210-sfc";
+					reg = <0x2902400 0x200>;
+					sound-name-prefix = "SFC3";
+					status = "disabled";
+				};
+
+				tegra_sfc4: sfc at 2902600 {
+					compatible = "nvidia,tegra194-sfc",
+						     "nvidia,tegra210-sfc";
+					reg = <0x2902600 0x200>;
+					sound-name-prefix = "SFC4";
+					status = "disabled";
+				};
+
+				tegra_mvc1: mvc at 290a000 {
+					compatible = "nvidia,tegra194-mvc",
+						     "nvidia,tegra210-mvc";
+					reg = <0x290a000 0x200>;
+					sound-name-prefix = "MVC1";
+					status = "disabled";
+				};
+
+				tegra_mvc2: mvc at 290a200 {
+					compatible = "nvidia,tegra194-mvc",
+						     "nvidia,tegra210-mvc";
+					reg = <0x290a200 0x200>;
+					sound-name-prefix = "MVC2";
+					status = "disabled";
+				};
+
+				tegra_amx1: amx at 2903000 {
+					compatible = "nvidia,tegra194-amx";
+					reg = <0x2903000 0x100>;
+					sound-name-prefix = "AMX1";
+					status = "disabled";
+				};
+
+				tegra_amx2: amx at 2903100 {
+					compatible = "nvidia,tegra194-amx";
+					reg = <0x2903100 0x100>;
+					sound-name-prefix = "AMX2";
+					status = "disabled";
+				};
+
+				tegra_amx3: amx at 2903200 {
+					compatible = "nvidia,tegra194-amx";
+					reg = <0x2903200 0x100>;
+					sound-name-prefix = "AMX3";
+					status = "disabled";
+				};
+
+				tegra_amx4: amx at 2903300 {
+					compatible = "nvidia,tegra194-amx";
+					reg = <0x2903300 0x100>;
+					sound-name-prefix = "AMX4";
+					status = "disabled";
+				};
+
+				tegra_adx1: adx at 2903800 {
+					compatible = "nvidia,tegra194-adx",
+						     "nvidia,tegra210-adx";
+					reg = <0x2903800 0x100>;
+					sound-name-prefix = "ADX1";
+					status = "disabled";
+				};
+
+				tegra_adx2: adx at 2903900 {
+					compatible = "nvidia,tegra194-adx",
+						     "nvidia,tegra210-adx";
+					reg = <0x2903900 0x100>;
+					sound-name-prefix = "ADX2";
+					status = "disabled";
+				};
+
+				tegra_adx3: adx at 2903a00 {
+					compatible = "nvidia,tegra194-adx",
+						     "nvidia,tegra210-adx";
+					reg = <0x2903a00 0x100>;
+					sound-name-prefix = "ADX3";
+					status = "disabled";
+				};
+
+				tegra_adx4: adx at 2903b00 {
+					compatible = "nvidia,tegra194-adx",
+						     "nvidia,tegra210-adx";
+					reg = <0x2903b00 0x100>;
+					sound-name-prefix = "ADX4";
+					status = "disabled";
+				};
+
+				tegra_amixer: amixer at 290bb00 {
+					compatible = "nvidia,tegra194-amixer",
+						     "nvidia,tegra210-amixer";
+					reg = <0x290bb00 0x800>;
+					sound-name-prefix = "MIXER";
+					status = "disabled";
+				};
 			};
 		};
 
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 26b3f98a..b84c963 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1641,6 +1641,83 @@
 				status = "disabled";
 			};
 
+			tegra_sfc1: sfc at 702d2000 {
+				compatible = "nvidia,tegra210-sfc";
+				reg = <0x702d2000 0x200>;
+				sound-name-prefix = "SFC1";
+				status = "disabled";
+			};
+
+			tegra_sfc2: sfc at 702d2200 {
+				compatible = "nvidia,tegra210-sfc";
+				reg = <0x702d2200 0x200>;
+				sound-name-prefix = "SFC2";
+				status = "disabled";
+			};
+
+			tegra_sfc3: sfc at 702d2400 {
+				compatible = "nvidia,tegra210-sfc";
+				reg = <0x702d2400 0x200>;
+				sound-name-prefix = "SFC3";
+				status = "disabled";
+			};
+
+			tegra_sfc4: sfc at 702d2600 {
+				compatible = "nvidia,tegra210-sfc";
+				reg = <0x702d2600 0x200>;
+				sound-name-prefix = "SFC4";
+				status = "disabled";
+			};
+
+			tegra_mvc1: mvc at 702da000 {
+				compatible = "nvidia,tegra210-mvc";
+				reg = <0x702da000 0x200>;
+				sound-name-prefix = "MVC1";
+				status = "disabled";
+			};
+
+			tegra_mvc2: mvc at 702da200 {
+				compatible = "nvidia,tegra210-mvc";
+				reg = <0x702da200 0x200>;
+				sound-name-prefix = "MVC2";
+				status = "disabled";
+			};
+
+			tegra_amx1: amx at 702d3000 {
+				compatible = "nvidia,tegra210-amx";
+				reg = <0x702d3000 0x100>;
+				sound-name-prefix = "AMX1";
+				status = "disabled";
+			};
+
+			tegra_amx2: amx at 702d3100 {
+				compatible = "nvidia,tegra210-amx";
+				reg = <0x702d3100 0x100>;
+				sound-name-prefix = "AMX2";
+				status = "disabled";
+			};
+
+			tegra_adx1: adx at 702d3800 {
+				compatible = "nvidia,tegra210-adx";
+				reg = <0x702d3800 0x100>;
+				sound-name-prefix = "ADX1";
+				status = "disabled";
+			};
+
+			tegra_adx2: adx at 702d3900 {
+				compatible = "nvidia,tegra210-adx";
+				reg = <0x702d3900 0x100>;
+				sound-name-prefix = "ADX2";
+				status = "disabled";
+			};
+
+			tegra_amixer: amixer at 702dbb00 {
+				compatible = "nvidia,tegra210-amixer";
+				reg = <0x702dbb00 0x800>;
+				sound-name-prefix = "MIXER";
+				status = "disabled";
+			};
+
 			ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
-- 
2.7.4



From cw9316.lee at samsung.com  Fri Aug 27 02:31:19 2021
From: cw9316.lee at samsung.com (Chanwoo Lee)
Date: Fri, 27 Aug 2021 18:31:19 +0900
Subject: [PATCH] mmc: mtk-sd: Remove unused parameters(mrq)
References: <CGME20210827093855epcas1p4ac8e34d779fe30de3e03bcadedcb66c8@epcas1p4.samsung.com>
Message-ID: <20210827093119.32481-1-cw9316.lee@samsung.com>

From: ChanWoo Lee <cw9316.lee at samsung.com>

The mmc_request structure(*mrq) is not used. //msdc_cmd_find_resp
I remove the unnecessary code related to the mmc_request structure.

Signed-off-by: ChanWoo Lee <cw9316.lee at samsung.com>
---
 drivers/mmc/host/mtk-sd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 4dfc246c5f95..813f57f6d9cc 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -961,7 +961,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 }
 
 static inline u32 msdc_cmd_find_resp(struct msdc_host *host,
-		struct mmc_request *mrq, struct mmc_command *cmd)
+		struct mmc_command *cmd)
 {
 	u32 resp;
 
@@ -997,7 +997,7 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host,
 	 * stop << 14 | rw << 13 | dtype << 11 | rsptyp << 7 | brk << 6 | opcode
 	 */
 	u32 opcode = cmd->opcode;
-	u32 resp = msdc_cmd_find_resp(host, mrq, cmd);
+	u32 resp = msdc_cmd_find_resp(host, cmd);
 	u32 rawcmd = (opcode & 0x3f) | ((resp & 0x7) << 7);
 
 	host->cmd_rsp = resp;
-- 
2.29.0



From Chunfeng.Yun at mediatek.com  Fri Aug 27 02:46:27 2021
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Fri, 27 Aug 2021 09:46:27 +0000
Subject: [PATCH next v2 1/6] Revert "usb: xhci-mtk: relax TT periodic
 bandwidth allocation"
In-Reply-To: <YSd93+3D/PbacgsP@kroah.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
 <YSd93+3D/PbacgsP@kroah.com>
Message-ID: <d13ece6a1b050092affd0c67f19ef69887ae0c3c.camel@mediatek.com>

Hi Greg,
On Thu, 2021-08-26 at 13:41 +0200, Greg Kroah-Hartman wrote:
> On Thu, Aug 26, 2021 at 10:51:39AM +0800, Chunfeng Yun wrote:
> > As discussed in following patch:
> > https://patchwork.kernel.org/patch/12420339
> > 
> > No need calculate number of uframes again, but should use value
> > form check_sch_tt(), if we plan to remove extra CS, also can do
> > it in check_sch_tt(). So revert this patch, and prepare to send
> > new patch for it.
> > 
> > This reverts commit 548011957d1d72e0b662300c8b32b81d593b796e.
> > 
> > Cc: Ikjoon Jang <ikjn at chromium.org>
> > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > ---
> > v2: no changes
> 
> This series does not apply to my tree at all now, can you please
> rebase
> and resend?
Very sorry, I send two series [1][2] for xhci-mtk, but don't take care
of conficts:

I suppose you will apply [1] firstly, due to [3] is not acked or
reviewed by Rob (I think, only need modify commit message).

Anyway, only one patch [4] is not in usb-testing branch due to
conflicts, I'll fix it and send out, sorry again.


[1]. Series = [next,v2,1/6] Revert "usb: xhci-mtk: relax TT periodic
bandwidth allocation"
https://patchwork.kernel.org/project/linux-mediatek/list/?series=537471


[2]. Series = [RESEND,1/9] dt-bindings: usb: mtk-xhci: add optional
property to disable usb2 ports
https://patchwork.kernel.org/project/linux-mediatek/list/?series=532595


[3]:

https://patchwork.kernel.org/project/linux-mediatek/patch/1629189389-18779-2-git-send-email-chunfeng.yun at mediatek.com/
[RESEND,2/9] dt-bindings: usb: mtk-xhci: add compatible for mt8195

[4]:

https://patchwork.kernel.org/project/linux-mediatek/patch/20210826025144.51992-6-chunfeng.yun at mediatek.com/
[next,v2,6/6] usb: xhci-mtk: allow bandwidth table rollover


> 
> thanks,
> 
> greg k-h

From lorenzo.pieralisi at arm.com  Fri Aug 27 02:48:15 2021
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 27 Aug 2021 10:48:15 +0100
Subject: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <TYAPR01MB6252A29B56BBF8921822824F92C79@TYAPR01MB6252.jpnprd01.prod.outlook.com>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <162998285902.30814.11206633831020646086.b4-ty@arm.com>
 <TYAPR01MB6252A29B56BBF8921822824F92C79@TYAPR01MB6252.jpnprd01.prod.outlook.com>
Message-ID: <20210827094815.GA13112@lpieralisi>

On Thu, Aug 26, 2021 at 11:49:04PM +0000, nobuhiro1.iwamatsu at toshiba.co.jp wrote:
> Hi,
> 
> > -----Original Message-----
> > From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
> > Sent: Thursday, August 26, 2021 10:01 PM
> > To: iwamatsu nobuhiro(?? ?? ????????) <nobuhiro1.iwamatsu at toshiba.co.jp>; Rob Herring
> > <robh+dt at kernel.org>; Bjorn Helgaas <bhelgaas at google.com>
> > Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>; Kishon Vijay Abraham I <kishon at ti.com>; ishikawa yuji(?? ??
> > ?????????????) <yuji2.ishikawa at toshiba.co.jp>; linux-arm-kernel at lists.infradead.org;
> > linux-pci at vger.kernel.org; Krzysztof Wilczy?ski <kw at linux.com>; agrawal punit(????? ??? ????????)
> > <punit1.agrawal at toshiba.co.jp>; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org
> > Subject: Re: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host controller driver
> > 
> > On Wed, 11 Aug 2021 17:38:27 +0900, Nobuhiro Iwamatsu wrote:
> > > This series is the PCIe driver for Toshiba's ARM SoC, Visconti[0].
> > > This provides DT binding documentation, device driver, MAINTAINER files.
> > >
> > > Best regards,
> > >   Nobuhiro
> > >
> > > [0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html
> > >
> > > [...]
> > 
> > Applied to pci/dwc, thanks!
> 
> Thanks! But...
> > 
> > [1/3] dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
> >       https://git.kernel.org/lpieralisi/pci/c/a655ce4000
> > [2/3] PCI: visconti: Add Toshiba Visconti PCIe host controller driver
> >       https://git.kernel.org/lpieralisi/pci/c/09436f819c
> 
> Only drivers/pci/controller/dwc/Makefile is applied. Could you check this?	

I fixed this. Please don't write patch versions changes in the commit
log - I had to delete those myself, I did not notice while applying
them.

Please let me know if the branch looks OK now.

Lorenzo

> > [3/3] MAINTAINERS: Add entries for Toshiba Visconti PCIe controller
> >       https://git.kernel.org/lpieralisi/pci/c/34af7aace1
> > 
> > Thanks,
> > Lorenzo
> 
> Best regards,
>   Nobuhiro


From rocco.yue at mediatek.com  Fri Aug 27 02:43:33 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Fri, 27 Aug 2021 17:43:33 +0800
Subject: [PATCH net-next v5] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value
In-Reply-To: <6a870141-089d-5e2b-48a7-448695e26238@gmail.com>
References: <6a870141-089d-5e2b-48a7-448695e26238@gmail.com>
Message-ID: <20210827094333.4669-1-rocco.yue@mediatek.com>

On Fri, 2021-08-27 at 13:28 +0800, David Ahern wrote:
> On 8/25/21 11:46 PM, Rocco Yue wrote:
>> @@ -5651,6 +5654,9 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
>>  	if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
>>  		goto nla_put_failure;
>>  
>> +	if (nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))
> 
> I should have seen this earlier. The intent here is to only notify
> userspace if the RA contains an MTU in which case this should be
> 
> 	if (idev->ra_mtu &&
> 	    nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))
> 

Hi David,

Thanks for your pretty suggestion.

When ra_mtu = 0, notify userspace is really unnecessary. At first
I did this because when userspace get ra_mtu = 0 through getlink,
then the corresponding operation can be performed.

After adding the restriction of "idev->ra_mtu", I think userspace can
judge whether the mtu option is carried in the RA by judging whether it
can be parsed to IFLA_INET6_RA_MTU after getlink, and perform the
corresponding operation.

I will push the next version.

> and in which case idev->ra_mtu should be initialized to 0 explicitly,
> not U32_MIN.

will do.

Thanks

From Chunfeng.Yun at mediatek.com  Fri Aug 27 02:48:53 2021
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Fri, 27 Aug 2021 09:48:53 +0000
Subject: [PATCH next v2 3/6] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <CAATdQgA+4VC7J1LMZYOZMV-OTjMGjO=9bJZ7uaCu_MMF-20T1w@mail.gmail.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
 <20210826025144.51992-3-chunfeng.yun@mediatek.com>
 <CAATdQgBD+dTtBie-cNKRJbfxEpc3haqjfUu1k26mTk8pCSOEww@mail.gmail.com>
 <72ee7a203d8a49e6e43a954b45133470ee6d5c16.camel@mediatek.com>
 <CAATdQgA+4VC7J1LMZYOZMV-OTjMGjO=9bJZ7uaCu_MMF-20T1w@mail.gmail.com>
Message-ID: <18cb18d7d0ea4a3bb46921aca88c53646f1b3764.camel@mediatek.com>

On Fri, 2021-08-27 at 17:14 +0800, Ikjoon Jang wrote:
> On Fri, Aug 27, 2021 at 2:49 PM Chunfeng Yun (???)
> <Chunfeng.Yun at mediatek.com> wrote:
> > 
> > On Thu, 2021-08-26 at 19:54 +0800, Ikjoon Jang wrote:
> > > Hi Chunfeng,
> > > 
> > > On Thu, Aug 26, 2021 at 10:52 AM Chunfeng Yun <
> > > chunfeng.yun at mediatek.com> wrote:
> > > > 
> > > > Use @bw_budget_table[] to update fs bus bandwidth due to
> > > > not all microframes consume @bw_cost_per_microframe, see
> > > > setup_sch_info().
> > > > 
> > > > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > > > ---
> > > > v2: new patch, move from another series
> > > > ---
> > > >  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
> > > >  1 file changed, 7 insertions(+), 10 deletions(-)
> > > > 
> > > > diff --git a/drivers/usb/host/xhci-mtk-sch.c
> > > > b/drivers/usb/host/xhci-mtk-sch.c
> > > > index cffcaf4dfa9f..83abd28269ca 100644
> > > > --- a/drivers/usb/host/xhci-mtk-sch.c
> > > > +++ b/drivers/usb/host/xhci-mtk-sch.c
> > > > @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct
> > > > mu3h_sch_ep_info *sch_ep, int offset)
> > > >                  * Compared with hs bus, no matter what ep
> > > > type,
> > > >                  * the hub will always delay one uframe to send
> > > > data
> > > >                  */
> > > > -               for (j = 0; j < sch_ep->cs_count; j++) {
> > > > -                       tmp = tt->fs_bus_bw[base + j] + sch_ep-
> > > > > bw_cost_per_microframe;
> > > > 
> > > > +               for (j = 0; j < sch_ep->num_budget_microframes;
> > > > j++) {
> > > > +                       tmp = tt->fs_bus_bw[base + j] + sch_ep-
> > > > > bw_budget_table[j];
> > > 
> > > I'm worrying about this case with two endpoints,
> > > * EP1OUT: isochronous, maxpacket=192: bw_budget_table[] = { 188,
> > > 188,
> > > 0, ... }
> > > * EP2IN: interrupt, maxpacket=64: bw_budget_table[] = { 0, 0, 64,
> > > 64,
> > > ... }
> > > (Is this correct bw_budget_table contents for those eps?)
> > 
> > Yes, ep1out isoc use two uframe, ep2in intr use a extra cs;
> > > 
> > > I'm not sure if it's okay for those two endpoints to be allocated
> > > on the same u-frame slot.
> > > Can you please check if this is okay for xhci-mtk?
> > 
> > Already test it this afternoon, can transfer data rightly on our
> > dvt
> > env.
> > 
> > > (I feel like I already asked the same questions many times.)
> > 
> > Yes, as said before, prefer to use bw_budget_table[], if there is
> > issue, we can fix it by building this table.
> 
> So do you mean such an allocation shouldn't be a problem by IP
> design?
Yes, at least on our dvt platform

> 
> This patch starts to allow such an allocation (again).
> But i remember my earlier tests showed that when those two eps
> in the above example are allocated on the same u-frame slot,
> xhci-mtk puts "SSPLIT for EP2" between
> "SSPLIT-start and SSPLIT-end for EP1OUT transaction",
> which is a spec violation. 

Which section in usb2.0 spec?

> Hub will generate bit stuffing errors on the
> full-speed bus.
which platform?

> 
> 
> > 
> > Thanks
> > > 
> > > 
> > > >                         if (tmp > FS_PAYLOAD_MAX)
> > > >                                 return -ESCH_BW_OVERFLOW;
> > > >                 }
> > > > @@ -534,21 +534,18 @@ static void update_sch_tt(struct
> > > > mu3h_sch_ep_info *sch_ep, bool used)
> > > >  {
> > > >         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
> > > >         u32 base, num_esit;
> > > > -       int bw_updated;
> > > >         int i, j;
> > > > 
> > > >         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> > > > 
> > > > -       if (used)
> > > > -               bw_updated = sch_ep->bw_cost_per_microframe;
> > > > -       else
> > > > -               bw_updated = -sch_ep->bw_cost_per_microframe;
> > > > -
> > > >         for (i = 0; i < num_esit; i++) {
> > > >                 base = sch_ep->offset + i * sch_ep->esit;
> > > > 
> > > > -               for (j = 0; j < sch_ep->cs_count; j++)
> > > > -                       tt->fs_bus_bw[base + j] += bw_updated;
> > > > +               for (j = 0; j < sch_ep->num_budget_microframes;
> > > > j++)
> > > > +                       if (used)
> > > > +                               tt->fs_bus_bw[base + j] +=
> > > > sch_ep-
> > > > > bw_budget_table[j];
> > > > 
> > > > +                       else
> > > > +                               tt->fs_bus_bw[base + j] -=
> > > > sch_ep-
> > > > > bw_budget_table[j];
> > > > 
> > > >         }
> > > > 
> > > >         if (used)
> > > > --
> > > > 2.18.0
> > > > 

From tabba at google.com  Fri Aug 27 03:16:01 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:01 +0100
Subject: [PATCH v5 0/8] KVM: arm64: Fixed features for protected VMs
Message-ID: <20210827101609.2808181-1-tabba@google.com>

Hi,

Changes since v4 [1]:
- Calculating feature id register values takes into account features
  supported/enabled in KVM.
- Handle all AArch64 feature ID registers, with sanitized copies at EL2 if
  necessary, rather than trusting the host, even if the value is the same.
- Trap registers are set based on the exposed value of the feature id
  registers, rather than the masks to allow/restrict.
- Move code for settings trap registers for protected guests to EL2.
- Refactoring and fixes.
- Dropped Will's ack for "KVM: arm64: Trap access to pVM restricted features"
- Rebase on Marc's pkvm-fixed-features branch [2].

Changes since v3 [3]:
- Redid calculating restricted values of feature register fields, ensuring that
  the code distinguishes between unsigned and (potentially in the future)
  signed fields (Will)
- Refactoring and fixes (Drew, Will)
- More documentation and comments (Oliver, Will)
- Dropped patch "Restrict protected VM capabilities", since it should come with
  or after the user ABI series for pKVM (Will)
- Carried Will's acks

Changes since v2 [4]:
- Both trapping and setting of feature id registers are toggled by an allowed
  features bitmap of the feature id registers (Will)
- Documentation explaining the rationale behind allowed/blocked features (Drew)
- Restrict protected VM features by checking and restricting VM capabilities
- Misc small fixes and tidying up (mostly Will)
- Remove dependency on Will's protected VM user ABI series [5]
- Rebase on 5.14-rc2
- Carried Will's acks

Changes since v1 [6]:
- Restrict protected VM features based on an allowed features rather than
  rejected ones (Drew)
- Add more background describing protected KVM to the cover letter (Alex)

This patch series adds support for restricting CPU features for protected VMs
in KVM (pKVM) [7].

Various VM feature configurations are allowed in KVM/arm64, each requiring
specific handling logic to deal with traps, context-switching and potentially
emulation. Achieving feature parity in pKVM therefore requires either elevating
this logic to EL2 (and substantially increasing the TCB) or continuing to trust
the host handlers at EL1. Since neither of these options are especially
appealing, pKVM instead limits the CPU features exposed to a guest to a fixed
configuration based on the underlying hardware and which can mostly be provided
straightforwardly by EL2.

This series approaches that by restricting CPU features exposed to protected
guests. Features advertised through feature registers are limited, which pKVM
enforces by trapping register accesses and instructions associated with these
features.

This series is based on 5.14-rc2. You can find the applied series here [8].

Cheers,
/fuad

[1] https://lore.kernel.org/kvmarm/20210817081134.2918285-1-tabba at google.com/

[2] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/pkvm-fixed-features

[3] https://lore.kernel.org/kvmarm/20210719160346.609914-1-tabba at google.com/

[4] https://lore.kernel.org/kvmarm/20210615133950.693489-1-tabba at google.com/

[5] https://lore.kernel.org/kvmarm/20210603183347.1695-1-will at kernel.org/

[6] https://lore.kernel.org/kvmarm/20210608141141.997398-1-tabba at google.com/

[7] Once complete, protected KVM adds the ability to create protected VMs.
These protected VMs are protected from the host Linux kernel (and from other
VMs), where the host does not have access to guest memory,even if compromised.
Normal (nVHE) guests can still be created and run in parallel with protected
VMs. Their functionality should not be affected.

For protected VMs, the host should not even have access to a protected guest's
state or anything that would enable it to manipulate it (e.g., vcpu register
context and el2 system registers); only hyp would have that access. If the host
could access that state, then it might be able to get around the protection
provided.  Therefore, anything that is sensitive and that would require such
access needs to happen at hyp, hence the code in nvhe running only at hyp.

For more details about pKVM, please refer to Will's talk at KVM Forum 2020:
https://mirrors.edge.kernel.org/pub/linux/kernel/people/will/slides/kvmforum-2020-edited.pdf
https://www.youtube.com/watch?v=edqJSzsDRxk

[8] https://android-kvm.googlesource.com/linux/+/refs/heads/tabba/el2_fixed_feature_v5

Fuad Tabba (8):
  KVM: arm64: Pass struct kvm to per-EC handlers
  KVM: arm64: Add missing field descriptor for MDCR_EL2
  KVM: arm64: Simplify masking out MTE in feature id reg
  KVM: arm64: Add trap handlers for protected VMs
  KVM: arm64: Initialize trap registers for protected VMs
  KVM: arm64: Move sanitized copies of CPU features
  KVM: arm64: Trap access to pVM restricted features
  KVM: arm64: Handle protected guests at 32 bits

 arch/arm64/include/asm/kvm_arm.h           |   1 +
 arch/arm64/include/asm/kvm_asm.h           |   1 +
 arch/arm64/include/asm/kvm_fixed_config.h  | 164 +++++++
 arch/arm64/include/asm/kvm_host.h          |   2 +
 arch/arm64/include/asm/kvm_hyp.h           |   5 +
 arch/arm64/kvm/arm.c                       |  13 +
 arch/arm64/kvm/hyp/include/hyp/switch.h    |  16 +-
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h     |  14 +
 arch/arm64/kvm/hyp/include/nvhe/sys_regs.h |  29 ++
 arch/arm64/kvm/hyp/nvhe/Makefile           |   2 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c         |  10 +
 arch/arm64/kvm/hyp/nvhe/mem_protect.c      |   6 -
 arch/arm64/kvm/hyp/nvhe/pkvm.c             | 186 ++++++++
 arch/arm64/kvm/hyp/nvhe/switch.c           |  59 ++-
 arch/arm64/kvm/hyp/nvhe/sys_regs.c         | 525 +++++++++++++++++++++
 arch/arm64/kvm/hyp/vhe/switch.c            |   2 +-
 arch/arm64/kvm/sys_regs.c                  |  10 +-
 17 files changed, 1020 insertions(+), 25 deletions(-)
 create mode 100644 arch/arm64/include/asm/kvm_fixed_config.h
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/pkvm.h
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/sys_regs.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/pkvm.c
 create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c


base-commit: cc3ef75c796e58acec8f64a9acf47fc18645f194
-- 
2.33.0.259.gc128427fd7-goog



From tabba at google.com  Fri Aug 27 03:16:02 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:02 +0100
Subject: [PATCH v5 1/8] KVM: arm64: Pass struct kvm to per-EC handlers
In-Reply-To: <20210827101609.2808181-1-tabba@google.com>
References: <20210827101609.2808181-1-tabba@google.com>
Message-ID: <20210827101609.2808181-2-tabba@google.com>

We need struct kvm to check for protected VMs to be able to pick
the right handlers for them.

Mark the handler functions inline, since some handlers will be
called in future code from the protected VM handlers.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 16 ++++++++--------
 arch/arm64/kvm/hyp/nvhe/switch.c        |  2 +-
 arch/arm64/kvm/hyp/vhe/switch.c         |  2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 0397606c0951..7cbff0ee59a5 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -163,7 +163,7 @@ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
  * If FP/SIMD is not implemented, handle the trap and inject an undefined
  * instruction exception to the guest. Similarly for trapped SVE accesses.
  */
-static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	bool sve_guest, sve_host;
 	u8 esr_ec;
@@ -318,7 +318,7 @@ static inline bool esr_is_ptrauth_trap(u32 esr)
 
 DECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 
-static bool kvm_hyp_handle_ptrauth(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_ptrauth(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	struct kvm_cpu_context *ctxt;
 	u64 val;
@@ -343,7 +343,7 @@ static bool kvm_hyp_handle_ptrauth(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return true;
 }
 
-static bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) &&
 	    handle_tx2_tvm(vcpu))
@@ -356,7 +356,7 @@ static bool kvm_hyp_handle_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return false;
 }
 
-static bool kvm_hyp_handle_cp15(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_cp15(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	if (static_branch_unlikely(&vgic_v3_cpuif_trap) &&
 	    __vgic_v3_perform_cpuif_access(vcpu) == 1)
@@ -365,7 +365,7 @@ static bool kvm_hyp_handle_cp15(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return false;
 }
 
-static bool kvm_hyp_handle_iabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_iabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	if (!__populate_fault_info(vcpu))
 		return true;
@@ -373,7 +373,7 @@ static bool kvm_hyp_handle_iabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return false;
 }
 
-static bool kvm_hyp_handle_dabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
+static inline bool kvm_hyp_handle_dabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	if (!__populate_fault_info(vcpu))
 		return true;
@@ -403,7 +403,7 @@ static bool kvm_hyp_handle_dabt_low(struct kvm_vcpu *vcpu, u64 *exit_code)
 
 typedef bool (*exit_handler_fn)(struct kvm_vcpu *, u64 *);
 
-static const exit_handler_fn *kvm_get_exit_handler_array(void);
+const exit_handler_fn *kvm_get_exit_handler_array(struct kvm *kvm);
 
 /*
  * Allow the hypervisor to handle the exit with an exit handler if it has one.
@@ -413,7 +413,7 @@ static const exit_handler_fn *kvm_get_exit_handler_array(void);
  */
 static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
-	const exit_handler_fn *handlers = kvm_get_exit_handler_array();
+	const exit_handler_fn *handlers = kvm_get_exit_handler_array(kern_hyp_va(vcpu->kvm));
 	exit_handler_fn fn;
 
 	fn = handlers[kvm_vcpu_trap_get_class(vcpu)];
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index c52d580708e0..ebc0a5a4dd6a 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -170,7 +170,7 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_PAC]		= kvm_hyp_handle_ptrauth,
 };
 
-static const exit_handler_fn *kvm_get_exit_handler_array(void)
+const exit_handler_fn *kvm_get_exit_handler_array(struct kvm *kvm)
 {
 	return hyp_exit_handlers;
 }
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 0e0d342358f7..d823b089d3e9 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -108,7 +108,7 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_PAC]		= kvm_hyp_handle_ptrauth,
 };
 
-static const exit_handler_fn *kvm_get_exit_handler_array(void)
+const exit_handler_fn *kvm_get_exit_handler_array(struct kvm *kvm)
 {
 	return hyp_exit_handlers;
 }
-- 
2.33.0.259.gc128427fd7-goog



From tabba at google.com  Fri Aug 27 03:16:03 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:03 +0100
Subject: [PATCH v5 2/8] KVM: arm64: Add missing field descriptor for MDCR_EL2
In-Reply-To: <20210827101609.2808181-1-tabba@google.com>
References: <20210827101609.2808181-1-tabba@google.com>
Message-ID: <20210827101609.2808181-3-tabba@google.com>

It's not currently used. Added for completeness.

No functional change intended.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_arm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 327120c0089f..a39fcf318c77 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -295,6 +295,7 @@
 #define MDCR_EL2_HPMFZO		(UL(1) << 29)
 #define MDCR_EL2_MTPME		(UL(1) << 28)
 #define MDCR_EL2_TDCC		(UL(1) << 27)
+#define MDCR_EL2_HLP		(UL(1) << 26)
 #define MDCR_EL2_HCCD		(UL(1) << 23)
 #define MDCR_EL2_TTRF		(UL(1) << 19)
 #define MDCR_EL2_HPMD		(UL(1) << 17)
-- 
2.33.0.259.gc128427fd7-goog



From tabba at google.com  Fri Aug 27 03:16:04 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:04 +0100
Subject: [PATCH v5 3/8] KVM: arm64: Simplify masking out MTE in feature id reg
In-Reply-To: <20210827101609.2808181-1-tabba@google.com>
References: <20210827101609.2808181-1-tabba@google.com>
Message-ID: <20210827101609.2808181-4-tabba@google.com>

Simplify code for hiding MTE support in feature id register when
MTE is not enabled/supported by KVM.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/sys_regs.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1d46e185f31e..447acce9ca84 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1077,14 +1077,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 		val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3);
 		break;
 	case SYS_ID_AA64PFR1_EL1:
-		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
-		if (kvm_has_mte(vcpu->kvm)) {
-			u64 pfr, mte;
-
-			pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
-			mte = cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR1_MTE_SHIFT);
-			val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR1_MTE), mte);
-		}
+		if (!kvm_has_mte(vcpu->kvm))
+			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
 		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
-- 
2.33.0.259.gc128427fd7-goog



From tabba at google.com  Fri Aug 27 03:16:05 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:05 +0100
Subject: [PATCH v5 4/8] KVM: arm64: Add trap handlers for protected VMs
In-Reply-To: <20210827101609.2808181-1-tabba@google.com>
References: <20210827101609.2808181-1-tabba@google.com>
Message-ID: <20210827101609.2808181-5-tabba@google.com>

Add trap handlers for protected VMs. These are mainly for Sys64
and debug traps.

No functional change intended as these are not hooked in yet to
the guest exit handlers introduced earlier. So even when trapping
is triggered, the exit handlers would let the host handle it, as
before.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_fixed_config.h  | 164 +++++++
 arch/arm64/include/asm/kvm_hyp.h           |   5 +
 arch/arm64/kvm/arm.c                       |   5 +
 arch/arm64/kvm/hyp/include/nvhe/sys_regs.h |  29 ++
 arch/arm64/kvm/hyp/nvhe/Makefile           |   2 +-
 arch/arm64/kvm/hyp/nvhe/switch.c           |   1 +
 arch/arm64/kvm/hyp/nvhe/sys_regs.c         | 523 +++++++++++++++++++++
 7 files changed, 728 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/include/asm/kvm_fixed_config.h
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/sys_regs.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/sys_regs.c

diff --git a/arch/arm64/include/asm/kvm_fixed_config.h b/arch/arm64/include/asm/kvm_fixed_config.h
new file mode 100644
index 000000000000..9085301d159e
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_fixed_config.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba at google.com>
+ */
+
+#ifndef __ARM64_KVM_FIXED_CONFIG_H__
+#define __ARM64_KVM_FIXED_CONFIG_H__
+
+#include <asm/sysreg.h>
+
+/*
+ * This file contains definitions for features to be allowed or restricted for
+ * guest virtual machines, depending on the mode KVM is running in and on the
+ * type of guest that is running.
+ *
+ * The ALLOW masks represent a bitmask of feature fields that are allowed
+ * without any restrictions as long as they are supported by the system.
+ *
+ * The RESTRICT_UNSIGNED masks, if present, represent unsigned fields for
+ * features that are restricted to support at most the specified feature.
+ *
+ * If a feature field is not present in either, than it is not supported.
+ *
+ * The approach taken for protected VMs is to allow features that are:
+ * - Needed by common Linux distributions (e.g., floating point)
+ * - Trivial to support, e.g., supporting the feature does not introduce or
+ * require tracking of additional state in KVM
+ * - Cannot be trapped or prevent the guest from using anyway
+ */
+
+/*
+ * Allow for protected VMs:
+ * - Floating-point and Advanced SIMD
+ * - Data Independent Timing
+ */
+#define PVM_ID_AA64PFR0_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64PFR0_FP) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_ASIMD) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR0_DIT) \
+	)
+
+/*
+ * Restrict to the following *unsigned* features for protected VMs:
+ * - AArch64 guests only (no support for AArch32 guests):
+ *	AArch32 adds complexity in trap handling, emulation, condition codes,
+ *	etc...
+ * - RAS (v1)
+ *	Supported by KVM
+ */
+#define PVM_ID_AA64PFR0_RESTRICT_UNSIGNED (\
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0), ID_AA64PFR0_ELx_64BIT_ONLY) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1), ID_AA64PFR0_ELx_64BIT_ONLY) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL2), ID_AA64PFR0_ELx_64BIT_ONLY) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL3), ID_AA64PFR0_ELx_64BIT_ONLY) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_RAS), ID_AA64PFR0_RAS_V1) \
+	)
+
+/*
+ * Allow for protected VMs:
+ * - Branch Target Identification
+ * - Speculative Store Bypassing
+ */
+#define PVM_ID_AA64PFR1_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64PFR1_BT) | \
+	ARM64_FEATURE_MASK(ID_AA64PFR1_SSBS) \
+	)
+
+/*
+ * Allow for protected VMs:
+ * - Mixed-endian
+ * - Distinction between Secure and Non-secure Memory
+ * - Mixed-endian at EL0 only
+ * - Non-context synchronizing exception entry and exit
+ */
+#define PVM_ID_AA64MMFR0_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_BIGENDEL) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_SNSMEM) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_BIGENDEL0) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR0_EXS) \
+	)
+
+/*
+ * Restrict to the following *unsigned* features for protected VMs:
+ * - 40-bit IPA
+ * - 16-bit ASID
+ */
+#define PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED (\
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_PARANGE), ID_AA64MMFR0_PARANGE_40) | \
+	FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64MMFR0_ASID), ID_AA64MMFR0_ASID_16) \
+	)
+
+/*
+ * Allow for protected VMs:
+ * - Hardware translation table updates to Access flag and Dirty state
+ * - Number of VMID bits from CPU
+ * - Hierarchical Permission Disables
+ * - Privileged Access Never
+ * - SError interrupt exceptions from speculative reads
+ * - Enhanced Translation Synchronization
+ */
+#define PVM_ID_AA64MMFR1_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_HADBS) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_VMIDBITS) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_HPD) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_PAN) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_SPECSEI) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR1_ETS) \
+	)
+
+/*
+ * Allow for protected VMs:
+ * - Common not Private translations
+ * - User Access Override
+ * - IESB bit in the SCTLR_ELx registers
+ * - Unaligned single-copy atomicity and atomic functions
+ * - ESR_ELx.EC value on an exception by read access to feature ID space
+ * - TTL field in address operations.
+ * - Break-before-make sequences when changing translation block size
+ * - E0PDx mechanism
+ */
+#define PVM_ID_AA64MMFR2_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_CNP) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_UAO) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_IESB) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_AT) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_IDS) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_TTL) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_BBM) | \
+	ARM64_FEATURE_MASK(ID_AA64MMFR2_E0PD) \
+	)
+
+/*
+ * No support for Scalable Vectors for protected VMs:
+ *	Requires additional support from KVM, e.g., context-switching and
+ *	trapping at EL2
+ */
+#define PVM_ID_AA64ZFR0_ALLOW (0ULL)
+
+/*
+ * No support for debug, including breakpoints, and watchpoints for protected
+ * VMs:
+ *	The Arm architecture mandates support for at least the Armv8 debug
+ *	architecture, which would include at least 2 hardware breakpoints and
+ *	watchpoints. Providing that support to protected guests adds
+ *	considerable state and complexity. Therefore, the reserved value of 0 is
+ *	used for debug-related fields.
+ */
+#define PVM_ID_AA64DFR0_ALLOW (0ULL)
+#define PVM_ID_AA64DFR1_ALLOW (0ULL)
+
+/*
+ * No support for implementation defined features.
+ */
+#define PVM_ID_AA64AFR0_ALLOW (0ULL)
+#define PVM_ID_AA64AFR1_ALLOW (0ULL)
+
+/*
+ * No restrictions on instructions implemented in AArch64.
+ */
+#define PVM_ID_AA64ISAR0_ALLOW (~0ULL)
+#define PVM_ID_AA64ISAR1_ALLOW (~0ULL)
+
+#endif /* __ARM64_KVM_FIXED_CONFIG_H__ */
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 657d0c94cf82..5afd14ab15b9 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -115,7 +115,12 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
 void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
 #endif
 
+extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64isar0_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64isar1_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
 
 #endif /* __ARM64_KVM_HYP_H__ */
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index fe102cd2e518..6aa7b0c5bf21 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1802,8 +1802,13 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
 	void *addr = phys_to_virt(hyp_mem_base);
 	int ret;
 
+	kvm_nvhe_sym(id_aa64pfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+	kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
+	kvm_nvhe_sym(id_aa64isar0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1);
+	kvm_nvhe_sym(id_aa64isar1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR1_EL1);
 	kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 	kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+	kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
 
 	ret = create_hyp_mappings(addr, addr + hyp_mem_size, PAGE_HYP);
 	if (ret)
diff --git a/arch/arm64/kvm/hyp/include/nvhe/sys_regs.h b/arch/arm64/kvm/hyp/include/nvhe/sys_regs.h
new file mode 100644
index 000000000000..f5c94a46bc74
--- /dev/null
+++ b/arch/arm64/kvm/hyp/include/nvhe/sys_regs.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba at google.com>
+ */
+
+#ifndef __ARM64_KVM_NVHE_SYS_REGS_H__
+#define __ARM64_KVM_NVHE_SYS_REGS_H__
+
+#include <asm/kvm_host.h>
+
+bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
+bool kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu, u64 *exit_code);
+bool kvm_handle_pvm_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code);
+
+u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64pfr1(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64zfr0(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64dfr0(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64dfr1(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64afr0(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64afr1(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64isar0(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64isar1(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64mmfr1(const struct kvm_vcpu *vcpu);
+u64 get_pvm_id_aa64mmfr2(const struct kvm_vcpu *vcpu);
+
+#endif /* __ARM64_KVM_NVHE_SYS_REGS_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 5df6193fc430..a23f417a0c20 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -14,7 +14,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
 
 obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
 	 hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
-	 cache.o setup.o mm.o mem_protect.o
+	 cache.o setup.o mm.o mem_protect.o sys_regs.o
 obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
 obj-y += $(lib-objs)
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index ebc0a5a4dd6a..41f05bf88f61 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -28,6 +28,7 @@
 #include <asm/thread_info.h>
 
 #include <nvhe/mem_protect.h>
+#include <nvhe/sys_regs.h>
 
 /* Non-VHE specific context */
 DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data);
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
new file mode 100644
index 000000000000..a7e836537154
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -0,0 +1,523 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba at google.com>
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_fixed_config.h>
+#include <asm/kvm_mmu.h>
+
+#include <hyp/adjust_pc.h>
+#include <hyp/switch.h>
+
+#include "../../sys_regs.h"
+
+/*
+ * Copies of the host's CPU features registers holding sanitized values at hyp.
+ */
+u64 id_aa64pfr0_el1_sys_val;
+u64 id_aa64pfr1_el1_sys_val;
+u64 id_aa64isar0_el1_sys_val;
+u64 id_aa64isar1_el1_sys_val;
+u64 id_aa64mmfr2_el1_sys_val;
+
+static inline void inject_undef(struct kvm_vcpu *vcpu)
+{
+	u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+
+	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1 |
+			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+			     KVM_ARM64_PENDING_EXCEPTION);
+
+	__kvm_adjust_pc(vcpu);
+
+	write_sysreg_el1(esr, SYS_ESR);
+	write_sysreg_el1(read_sysreg_el2(SYS_ELR), SYS_ELR);
+}
+
+/*
+ * Inject an unknown/undefined exception to the guest while most of its sysregs
+ * are live.
+ */
+static inline void __inject_undef(struct kvm_vcpu *vcpu)
+{
+	*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
+	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
+
+	inject_undef(vcpu);
+
+	write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
+	write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
+}
+
+/*
+ * Accessor for undefined accesses.
+ */
+static bool undef_access(struct kvm_vcpu *vcpu,
+			 struct sys_reg_params *p,
+			 const struct sys_reg_desc *r)
+{
+	__inject_undef(vcpu);
+	return false;
+}
+
+/*
+ * Returns the restricted features values of the feature register based on the
+ * limitations in restrict_fields.
+ * A feature id field value of 0b0000 does not impose any restrictions.
+ * Note: Use only for unsigned feature field values.
+ */
+static u64 get_restricted_features_unsigned(u64 sys_reg_val,
+					    u64 restrict_fields)
+{
+	u64 value = 0UL;
+	u64 mask = GENMASK_ULL(ARM64_FEATURE_FIELD_BITS - 1, 0);
+
+	/*
+	 * According to the Arm Architecture Reference Manual, feature fields
+	 * use increasing values to indicate increases in functionality.
+	 * Iterate over the restricted feature fields and calculate the minimum
+	 * unsigned value between the one supported by the system, and what the
+	 * value is being restricted to.
+	 */
+	while (sys_reg_val && restrict_fields) {
+		value |= min(sys_reg_val & mask, restrict_fields & mask);
+		sys_reg_val &= ~mask;
+		restrict_fields &= ~mask;
+		mask <<= ARM64_FEATURE_FIELD_BITS;
+	}
+
+	return value;
+}
+
+/*
+ * Functions that return the value of feature id registers for protected VMs
+ * based on allowed features, system features, and KVM support.
+ */
+
+u64 get_pvm_id_aa64pfr0(const struct kvm_vcpu *vcpu)
+{
+	const struct kvm *kvm = (const struct kvm *) kern_hyp_va(vcpu->kvm);
+	u64 set_mask = 0;
+	u64 allow_mask = PVM_ID_AA64PFR0_ALLOW;
+
+	if (!vcpu_has_sve(vcpu))
+		allow_mask &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
+
+	set_mask |= get_restricted_features_unsigned(id_aa64pfr0_el1_sys_val,
+		PVM_ID_AA64PFR0_RESTRICT_UNSIGNED);
+
+	/* Spectre and Meltdown mitigation in KVM */
+	set_mask |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2),
+			       (u64)kvm->arch.pfr0_csv2);
+	set_mask |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3),
+			       (u64)kvm->arch.pfr0_csv3);
+
+	return (id_aa64pfr0_el1_sys_val & allow_mask) | set_mask;
+}
+
+u64 get_pvm_id_aa64pfr1(const struct kvm_vcpu *vcpu)
+{
+	const struct kvm *kvm = (const struct kvm *) kern_hyp_va(vcpu->kvm);
+	u64 allow_mask = PVM_ID_AA64PFR1_ALLOW;
+
+	if (!kvm_has_mte(kvm))
+		allow_mask &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
+
+	return id_aa64pfr1_el1_sys_val & allow_mask;
+}
+
+u64 get_pvm_id_aa64zfr0(const struct kvm_vcpu *vcpu)
+{
+	/*
+	 * No support for Scalable Vectors, therefore, hyp has no sanitized
+	 * copy of the feature id register.
+	 */
+	BUILD_BUG_ON(PVM_ID_AA64ZFR0_ALLOW != 0ULL);
+	return 0;
+}
+
+u64 get_pvm_id_aa64dfr0(const struct kvm_vcpu *vcpu)
+{
+	/*
+	 * No support for debug, including breakpoints, and watchpoints,
+	 * therefore, pKVM has no sanitized copy of the feature id register.
+	 */
+	BUILD_BUG_ON(PVM_ID_AA64DFR0_ALLOW != 0ULL);
+	return 0;
+}
+
+u64 get_pvm_id_aa64dfr1(const struct kvm_vcpu *vcpu)
+{
+	/*
+	 * No support for debug, therefore, hyp has no sanitized copy of the
+	 * feature id register.
+	 */
+	BUILD_BUG_ON(PVM_ID_AA64DFR1_ALLOW != 0ULL);
+	return 0;
+}
+
+u64 get_pvm_id_aa64afr0(const struct kvm_vcpu *vcpu)
+{
+	/*
+	 * No support for implementation defined features, therefore, hyp has no
+	 * sanitized copy of the feature id register.
+	 */
+	BUILD_BUG_ON(PVM_ID_AA64AFR0_ALLOW != 0ULL);
+	return 0;
+}
+
+u64 get_pvm_id_aa64afr1(const struct kvm_vcpu *vcpu)
+{
+	/*
+	 * No support for implementation defined features, therefore, hyp has no
+	 * sanitized copy of the feature id register.
+	 */
+	BUILD_BUG_ON(PVM_ID_AA64AFR1_ALLOW != 0ULL);
+	return 0;
+}
+
+u64 get_pvm_id_aa64isar0(const struct kvm_vcpu *vcpu)
+{
+	return id_aa64isar0_el1_sys_val & PVM_ID_AA64ISAR0_ALLOW;
+}
+
+u64 get_pvm_id_aa64isar1(const struct kvm_vcpu *vcpu)
+{
+	u64 allow_mask = PVM_ID_AA64ISAR1_ALLOW;
+
+	if (!vcpu_has_ptrauth(vcpu))
+		allow_mask &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) |
+				ARM64_FEATURE_MASK(ID_AA64ISAR1_API) |
+				ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) |
+				ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI));
+
+	return id_aa64isar1_el1_sys_val & allow_mask;
+}
+
+u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
+{
+	u64 set_mask =
+		get_restricted_features_unsigned(id_aa64mmfr0_el1_sys_val,
+		PVM_ID_AA64MMFR0_RESTRICT_UNSIGNED);
+
+	return (id_aa64mmfr0_el1_sys_val & PVM_ID_AA64MMFR0_ALLOW) | set_mask;
+}
+
+u64 get_pvm_id_aa64mmfr1(const struct kvm_vcpu *vcpu)
+{
+	return id_aa64mmfr1_el1_sys_val & PVM_ID_AA64MMFR1_ALLOW;
+}
+
+u64 get_pvm_id_aa64mmfr2(const struct kvm_vcpu *vcpu)
+{
+	return id_aa64mmfr2_el1_sys_val & PVM_ID_AA64MMFR2_ALLOW;
+}
+
+/* Read a sanitized cpufeature ID register by its sys_reg_desc. */
+static u64 read_id_reg(const struct kvm_vcpu *vcpu,
+		       struct sys_reg_desc const *r)
+{
+	u32 id = reg_to_encoding(r);
+
+	switch (id) {
+	case SYS_ID_AA64PFR0_EL1:
+		return get_pvm_id_aa64pfr0(vcpu);
+	case SYS_ID_AA64PFR1_EL1:
+		return get_pvm_id_aa64pfr1(vcpu);
+	case SYS_ID_AA64ZFR0_EL1:
+		return get_pvm_id_aa64zfr0(vcpu);
+	case SYS_ID_AA64DFR0_EL1:
+		return get_pvm_id_aa64dfr0(vcpu);
+	case SYS_ID_AA64DFR1_EL1:
+		return get_pvm_id_aa64dfr1(vcpu);
+	case SYS_ID_AA64AFR0_EL1:
+		return get_pvm_id_aa64afr0(vcpu);
+	case SYS_ID_AA64AFR1_EL1:
+		return get_pvm_id_aa64afr1(vcpu);
+	case SYS_ID_AA64ISAR0_EL1:
+		return get_pvm_id_aa64isar0(vcpu);
+	case SYS_ID_AA64ISAR1_EL1:
+		return get_pvm_id_aa64isar1(vcpu);
+	case SYS_ID_AA64MMFR0_EL1:
+		return get_pvm_id_aa64mmfr0(vcpu);
+	case SYS_ID_AA64MMFR1_EL1:
+		return get_pvm_id_aa64mmfr1(vcpu);
+	case SYS_ID_AA64MMFR2_EL1:
+		return get_pvm_id_aa64mmfr2(vcpu);
+	default:
+		/*
+		 * Should never happen because all cases are covered in
+		 * pvm_sys_reg_descs[] below.
+		 */
+		BUG();
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * Accessor for AArch32 feature id registers.
+ *
+ * The value of these registers is "unknown" according to the spec if AArch32
+ * isn't supported.
+ */
+static bool pvm_access_id_aarch32(struct kvm_vcpu *vcpu,
+				  struct sys_reg_params *p,
+				  const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	/*
+	 * No support for AArch32 guests, therefore, pKVM has no sanitized copy
+	 * of AArch32 feature id registers.
+	 */
+	BUILD_BUG_ON(FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1),
+		     PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) >
+			ID_AA64PFR0_ELx_64BIT_ONLY);
+
+	/* Use 0 for architecturally "unknown" values. */
+	p->regval = 0;
+	return true;
+}
+
+/*
+ * Accessor for AArch64 feature id registers.
+ *
+ * If access is allowed, set the regval to the protected VM's view of the
+ * register and return true.
+ * Otherwise, inject an undefined exception and return false.
+ */
+static bool pvm_access_id_aarch64(struct kvm_vcpu *vcpu,
+				  struct sys_reg_params *p,
+				  const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return undef_access(vcpu, p, r);
+
+	p->regval = read_id_reg(vcpu, r);
+	return true;
+}
+
+/* Mark the specified system register as an AArch32 feature id register. */
+#define AARCH32(REG) { SYS_DESC(REG), .access = pvm_access_id_aarch32 }
+
+/* Mark the specified system register as an AArch64 feature id register. */
+#define AARCH64(REG) { SYS_DESC(REG), .access = pvm_access_id_aarch64 }
+
+/* Mark the specified system register as not being handled in hyp. */
+#define HOST_HANDLED(REG) { SYS_DESC(REG), .access = NULL }
+
+/*
+ * Architected system registers.
+ * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
+ *
+ * NOTE: Anything not explicitly listed here is *restricted by default*, i.e.,
+ * it will lead to injecting an exception into the guest.
+ */
+static const struct sys_reg_desc pvm_sys_reg_descs[] = {
+	/* Cache maintenance by set/way operations are restricted. */
+
+	/* Debug and Trace Registers are restricted. */
+
+	/* AArch64 mappings of the AArch32 ID registers */
+	/* CRm=1 */
+	AARCH32(SYS_ID_PFR0_EL1),
+	AARCH32(SYS_ID_PFR1_EL1),
+	AARCH32(SYS_ID_DFR0_EL1),
+	AARCH32(SYS_ID_AFR0_EL1),
+	AARCH32(SYS_ID_MMFR0_EL1),
+	AARCH32(SYS_ID_MMFR1_EL1),
+	AARCH32(SYS_ID_MMFR2_EL1),
+	AARCH32(SYS_ID_MMFR3_EL1),
+
+	/* CRm=2 */
+	AARCH32(SYS_ID_ISAR0_EL1),
+	AARCH32(SYS_ID_ISAR1_EL1),
+	AARCH32(SYS_ID_ISAR2_EL1),
+	AARCH32(SYS_ID_ISAR3_EL1),
+	AARCH32(SYS_ID_ISAR4_EL1),
+	AARCH32(SYS_ID_ISAR5_EL1),
+	AARCH32(SYS_ID_MMFR4_EL1),
+	AARCH32(SYS_ID_ISAR6_EL1),
+
+	/* CRm=3 */
+	AARCH32(SYS_MVFR0_EL1),
+	AARCH32(SYS_MVFR1_EL1),
+	AARCH32(SYS_MVFR2_EL1),
+	AARCH32(SYS_ID_PFR2_EL1),
+	AARCH32(SYS_ID_DFR1_EL1),
+	AARCH32(SYS_ID_MMFR5_EL1),
+
+	/* AArch64 ID registers */
+	/* CRm=4 */
+	AARCH64(SYS_ID_AA64PFR0_EL1),
+	AARCH64(SYS_ID_AA64PFR1_EL1),
+	AARCH64(SYS_ID_AA64ZFR0_EL1),
+	AARCH64(SYS_ID_AA64DFR0_EL1),
+	AARCH64(SYS_ID_AA64DFR1_EL1),
+	AARCH64(SYS_ID_AA64AFR0_EL1),
+	AARCH64(SYS_ID_AA64AFR1_EL1),
+	AARCH64(SYS_ID_AA64ISAR0_EL1),
+	AARCH64(SYS_ID_AA64ISAR1_EL1),
+	AARCH64(SYS_ID_AA64MMFR0_EL1),
+	AARCH64(SYS_ID_AA64MMFR1_EL1),
+	AARCH64(SYS_ID_AA64MMFR2_EL1),
+
+	HOST_HANDLED(SYS_SCTLR_EL1),
+	HOST_HANDLED(SYS_ACTLR_EL1),
+	HOST_HANDLED(SYS_CPACR_EL1),
+
+	HOST_HANDLED(SYS_RGSR_EL1),
+	HOST_HANDLED(SYS_GCR_EL1),
+
+	/* Scalable Vector Registers are restricted. */
+
+	HOST_HANDLED(SYS_TTBR0_EL1),
+	HOST_HANDLED(SYS_TTBR1_EL1),
+	HOST_HANDLED(SYS_TCR_EL1),
+
+	HOST_HANDLED(SYS_APIAKEYLO_EL1),
+	HOST_HANDLED(SYS_APIAKEYHI_EL1),
+	HOST_HANDLED(SYS_APIBKEYLO_EL1),
+	HOST_HANDLED(SYS_APIBKEYHI_EL1),
+	HOST_HANDLED(SYS_APDAKEYLO_EL1),
+	HOST_HANDLED(SYS_APDAKEYHI_EL1),
+	HOST_HANDLED(SYS_APDBKEYLO_EL1),
+	HOST_HANDLED(SYS_APDBKEYHI_EL1),
+	HOST_HANDLED(SYS_APGAKEYLO_EL1),
+	HOST_HANDLED(SYS_APGAKEYHI_EL1),
+
+	HOST_HANDLED(SYS_AFSR0_EL1),
+	HOST_HANDLED(SYS_AFSR1_EL1),
+	HOST_HANDLED(SYS_ESR_EL1),
+
+	HOST_HANDLED(SYS_ERRIDR_EL1),
+	HOST_HANDLED(SYS_ERRSELR_EL1),
+	HOST_HANDLED(SYS_ERXFR_EL1),
+	HOST_HANDLED(SYS_ERXCTLR_EL1),
+	HOST_HANDLED(SYS_ERXSTATUS_EL1),
+	HOST_HANDLED(SYS_ERXADDR_EL1),
+	HOST_HANDLED(SYS_ERXMISC0_EL1),
+	HOST_HANDLED(SYS_ERXMISC1_EL1),
+
+	HOST_HANDLED(SYS_TFSR_EL1),
+	HOST_HANDLED(SYS_TFSRE0_EL1),
+
+	HOST_HANDLED(SYS_FAR_EL1),
+	HOST_HANDLED(SYS_PAR_EL1),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_MAIR_EL1),
+	HOST_HANDLED(SYS_AMAIR_EL1),
+
+	/* Limited Ordering Regions Registers are restricted. */
+
+	HOST_HANDLED(SYS_VBAR_EL1),
+	HOST_HANDLED(SYS_DISR_EL1),
+
+	/* GIC CPU Interface registers are restricted. */
+
+	HOST_HANDLED(SYS_CONTEXTIDR_EL1),
+	HOST_HANDLED(SYS_TPIDR_EL1),
+
+	HOST_HANDLED(SYS_SCXTNUM_EL1),
+
+	HOST_HANDLED(SYS_CNTKCTL_EL1),
+
+	HOST_HANDLED(SYS_CCSIDR_EL1),
+	HOST_HANDLED(SYS_CLIDR_EL1),
+	HOST_HANDLED(SYS_CSSELR_EL1),
+	HOST_HANDLED(SYS_CTR_EL0),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_TPIDR_EL0),
+	HOST_HANDLED(SYS_TPIDRRO_EL0),
+
+	HOST_HANDLED(SYS_SCXTNUM_EL0),
+
+	/* Activity Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_CNTP_TVAL_EL0),
+	HOST_HANDLED(SYS_CNTP_CTL_EL0),
+	HOST_HANDLED(SYS_CNTP_CVAL_EL0),
+
+	/* Performance Monitoring Registers are restricted. */
+
+	HOST_HANDLED(SYS_DACR32_EL2),
+	HOST_HANDLED(SYS_IFSR32_EL2),
+	HOST_HANDLED(SYS_FPEXC32_EL2),
+};
+
+/*
+ * Handler for protected VM restricted exceptions.
+ *
+ * Inject an undefined exception into the guest and return true to indicate that
+ * the hypervisor has handled the exit, and control should go back to the guest.
+ */
+bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	__inject_undef(vcpu);
+	return true;
+}
+
+/*
+ * Handler for protected VM MSR, MRS or System instruction execution in AArch64.
+ *
+ * Returns true if the hypervisor has handled the exit, and control should go
+ * back to the guest, or false if it hasn't.
+ */
+bool kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	const struct sys_reg_desc *r;
+	struct sys_reg_params params;
+	unsigned long esr = kvm_vcpu_get_esr(vcpu);
+	int Rt = kvm_vcpu_sys_get_rt(vcpu);
+
+	params = esr_sys64_to_params(esr);
+	params.regval = vcpu_get_reg(vcpu, Rt);
+
+	r = find_reg(&params, pvm_sys_reg_descs, ARRAY_SIZE(pvm_sys_reg_descs));
+
+	/* Undefined access (RESTRICTED). */
+	if (r == NULL)
+		return kvm_handle_pvm_restricted(vcpu, exit_code);
+
+	/* Handled by the host (HOST_HANDLED) */
+	if (r->access == NULL)
+		return kvm_hyp_handle_sysreg(vcpu, exit_code);
+
+	/* Handled by hyp: skip instruction if instructed to do so. */
+	if (r->access(vcpu, &params, r))
+		__kvm_skip_instr(vcpu);
+
+	if (!params.is_write)
+		vcpu_set_reg(vcpu, Rt, params.regval);
+
+	return true;
+}
+
+/*
+ * Handler for protected floating-point and Advanced SIMD accesses.
+ *
+ * Returns true if the hypervisor has handled the exit, and control should go
+ * back to the guest, or false if it hasn't.
+ */
+bool kvm_handle_pvm_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	/* Linux guests assume support for floating-point and Advanced SIMD. */
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_FP),
+				PVM_ID_AA64PFR0_ALLOW));
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_ASIMD),
+				PVM_ID_AA64PFR0_ALLOW));
+
+	return kvm_hyp_handle_fpsimd(vcpu, exit_code);
+}
-- 
2.33.0.259.gc128427fd7-goog



From tabba at google.com  Fri Aug 27 03:16:06 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:06 +0100
Subject: [PATCH v5 5/8] KVM: arm64: Initialize trap registers for protected VMs
In-Reply-To: <20210827101609.2808181-1-tabba@google.com>
References: <20210827101609.2808181-1-tabba@google.com>
Message-ID: <20210827101609.2808181-6-tabba@google.com>

Protected VMs have more restricted features that need to be
trapped. Moreover, the host should not be trusted to set the
appropriate trapping registers and their values.

Initialize the trapping registers, i.e., hcr_el2, mdcr_el2, and
cptr_el2 at EL2 for protected guests, based on the values of the
guest's feature id registers.

No functional change intended as trap handlers introduced in the
previous patch are still not hooked in to the guest exit
handlers.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/include/asm/kvm_asm.h       |   1 +
 arch/arm64/include/asm/kvm_host.h      |   2 +
 arch/arm64/kvm/arm.c                   |   8 ++
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  14 ++
 arch/arm64/kvm/hyp/nvhe/Makefile       |   2 +-
 arch/arm64/kvm/hyp/nvhe/hyp-main.c     |  10 ++
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 186 +++++++++++++++++++++++++
 7 files changed, 222 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/kvm/hyp/include/nvhe/pkvm.h
 create mode 100644 arch/arm64/kvm/hyp/nvhe/pkvm.c

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index e86045ac43ba..a460e1243cef 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -64,6 +64,7 @@
 #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector		18
 #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize		19
 #define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc			20
+#define __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_init_traps		21
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f8be56d5342b..4a323aa27a6b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -780,6 +780,8 @@ static inline bool kvm_vm_is_protected(struct kvm *kvm)
 	return false;
 }
 
+void kvm_init_protected_traps(struct kvm_vcpu *vcpu);
+
 int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu, int feature);
 bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 6aa7b0c5bf21..3af6d59d1919 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -620,6 +620,14 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 
 	ret = kvm_arm_pmu_v3_enable(vcpu);
 
+	/*
+	 * Initialize traps for protected VMs.
+	 * NOTE: Move to run in EL2 directly, rather than via a hypercall, once
+	 * the code is in place for first run initialization at EL2.
+	 */
+	if (kvm_vm_is_protected(kvm))
+		kvm_call_hyp_nvhe(__pkvm_vcpu_init_traps, vcpu);
+
 	return ret;
 }
 
diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
new file mode 100644
index 000000000000..e6c259db6719
--- /dev/null
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba at google.com>
+ */
+
+#ifndef __ARM64_KVM_NVHE_PKVM_H__
+#define __ARM64_KVM_NVHE_PKVM_H__
+
+#include <asm/kvm_host.h>
+
+void __pkvm_vcpu_init_traps(struct kvm_vcpu *vcpu);
+
+#endif /* __ARM64_KVM_NVHE_PKVM_H__ */
diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index a23f417a0c20..8f13855eb1b6 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -14,7 +14,7 @@ lib-objs := $(addprefix ../../../lib/, $(lib-objs))
 
 obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o \
 	 hyp-main.o hyp-smp.o psci-relay.o early_alloc.o stub.o page_alloc.o \
-	 cache.o setup.o mm.o mem_protect.o sys_regs.o
+	 cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o
 obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \
 	 ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o
 obj-y += $(lib-objs)
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 8ca1104f4774..f59e0870c343 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -15,6 +15,7 @@
 
 #include <nvhe/mem_protect.h>
 #include <nvhe/mm.h>
+#include <nvhe/pkvm.h>
 #include <nvhe/trap_handler.h>
 
 DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
@@ -160,6 +161,14 @@ static void handle___pkvm_prot_finalize(struct kvm_cpu_context *host_ctxt)
 {
 	cpu_reg(host_ctxt, 1) = __pkvm_prot_finalize();
 }
+
+static void handle___pkvm_vcpu_init_traps(struct kvm_cpu_context *host_ctxt)
+{
+	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
+
+	__pkvm_vcpu_init_traps(kern_hyp_va(vcpu));
+}
+
 typedef void (*hcall_t)(struct kvm_cpu_context *);
 
 #define HANDLE_FUNC(x)	[__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x
@@ -185,6 +194,7 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_create_private_mapping),
 	HANDLE_FUNC(__pkvm_prot_finalize),
+	HANDLE_FUNC(__pkvm_vcpu_init_traps),
 };
 
 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
new file mode 100644
index 000000000000..cc6139631dc4
--- /dev/null
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Google LLC
+ * Author: Fuad Tabba <tabba at google.com>
+ */
+
+#include <linux/kvm_host.h>
+#include <linux/mm.h>
+#include <asm/kvm_fixed_config.h>
+#include <nvhe/sys_regs.h>
+
+/*
+ * Set trap register values based on features in ID_AA64PFR0.
+ */
+static void pvm_init_traps_aa64pfr0(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = get_pvm_id_aa64pfr0(vcpu);
+	u64 hcr_set = 0;
+	u64 hcr_clear = 0;
+	u64 cptr_set = 0;
+
+	/* Trap AArch32 guests */
+	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0), feature_ids) <
+		    ID_AA64PFR0_ELx_32BIT_64BIT ||
+	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1), feature_ids) <
+		    ID_AA64PFR0_ELx_32BIT_64BIT)
+		hcr_set |= HCR_RW | HCR_TID0;
+
+	/* Trap RAS unless all current versions are supported */
+	if (FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_RAS), feature_ids) <
+	    ID_AA64PFR0_RAS_V1P1) {
+		hcr_set |= HCR_TERR | HCR_TEA;
+		hcr_clear |= HCR_FIEN;
+	}
+
+	/* Trap AMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_AMU), feature_ids)) {
+		hcr_clear |= HCR_AMVOFFEN;
+		cptr_set |= CPTR_EL2_TAM;
+	}
+
+	/*
+	 * Linux guests assume support for floating-point and Advanced SIMD. Do
+	 * not change the trapping behavior for these from the KVM default.
+	 */
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_FP),
+				PVM_ID_AA64PFR0_ALLOW));
+	BUILD_BUG_ON(!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_ASIMD),
+				PVM_ID_AA64PFR0_ALLOW));
+
+	/* Trap SVE */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_SVE), feature_ids))
+		cptr_set |= CPTR_EL2_TZ;
+
+	vcpu->arch.hcr_el2 |= hcr_set;
+	vcpu->arch.hcr_el2 &= ~hcr_clear;
+	vcpu->arch.cptr_el2 |= cptr_set;
+}
+
+/*
+ * Set trap register values based on features in ID_AA64PFR1.
+ */
+static void pvm_init_traps_aa64pfr1(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = get_pvm_id_aa64pfr1(vcpu);
+	u64 hcr_set = 0;
+	u64 hcr_clear = 0;
+
+	/* Memory Tagging: Trap and Treat as Untagged if not supported. */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR1_MTE), feature_ids)) {
+		hcr_set |= HCR_TID5;
+		hcr_clear |= HCR_DCT | HCR_ATA;
+	}
+
+	vcpu->arch.hcr_el2 |= hcr_set;
+	vcpu->arch.hcr_el2 &= ~hcr_clear;
+}
+
+/*
+ * Set trap register values based on features in ID_AA64DFR0.
+ */
+static void pvm_init_traps_aa64dfr0(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = get_pvm_id_aa64dfr0(vcpu);
+	u64 mdcr_set = 0;
+	u64 mdcr_clear = 0;
+	u64 cptr_set = 0;
+
+	/* Trap/constrain PMU */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_PMUVER), feature_ids)) {
+		mdcr_set |= MDCR_EL2_TPM | MDCR_EL2_TPMCR;
+		mdcr_clear |= MDCR_EL2_HPME | MDCR_EL2_MTPME |
+			      MDCR_EL2_HPMN_MASK;
+	}
+
+	/* Trap Debug */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), feature_ids))
+		mdcr_set |= MDCR_EL2_TDRA | MDCR_EL2_TDA | MDCR_EL2_TDE;
+
+	/* Trap OS Double Lock */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_DOUBLELOCK), feature_ids))
+		mdcr_set |= MDCR_EL2_TDOSA;
+
+	/* Trap SPE */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER), feature_ids)) {
+		mdcr_set |= MDCR_EL2_TPMS;
+		mdcr_clear |= MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT;
+	}
+
+	/* Trap Trace Filter */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_TRACE_FILT), feature_ids))
+		mdcr_set |= MDCR_EL2_TTRF;
+
+	/* Trap Trace */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64DFR0_TRACEVER), feature_ids))
+		cptr_set |= CPTR_EL2_TTA;
+
+	vcpu->arch.mdcr_el2 |= mdcr_set;
+	vcpu->arch.mdcr_el2 &= ~mdcr_clear;
+	vcpu->arch.cptr_el2 |= cptr_set;
+}
+
+/*
+ * Set trap register values based on features in ID_AA64MMFR0.
+ */
+static void pvm_init_traps_aa64mmfr0(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = get_pvm_id_aa64mmfr0(vcpu);
+	u64 mdcr_set = 0;
+
+	/* Trap Debug Communications Channel registers */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_FGT), feature_ids))
+		mdcr_set |= MDCR_EL2_TDCC;
+
+	vcpu->arch.mdcr_el2 |= mdcr_set;
+}
+
+/*
+ * Set trap register values based on features in ID_AA64MMFR1.
+ */
+static void pvm_init_traps_aa64mmfr1(struct kvm_vcpu *vcpu)
+{
+	const u64 feature_ids = get_pvm_id_aa64mmfr1(vcpu);
+	u64 hcr_set = 0;
+
+	/* Trap LOR */
+	if (!FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR1_LOR), feature_ids))
+		hcr_set |= HCR_TLOR;
+
+	vcpu->arch.hcr_el2 |= hcr_set;
+}
+
+/*
+ * Set baseline trap register values.
+ */
+static void pvm_init_trap_regs(struct kvm_vcpu *vcpu)
+{
+	const u64 hcr_trap_feat_regs = HCR_TID3;
+	const u64 hcr_trap_impdef = HCR_TACR | HCR_TIDCP | HCR_TID1;
+
+	/*
+	 * Always trap:
+	 * - Feature id registers: to control features exposed to guests
+	 * - Implementation-defined features
+	 */
+	vcpu->arch.hcr_el2 |= hcr_trap_feat_regs | hcr_trap_impdef;
+
+	/* Clear res0 and set res1 bits to trap potential new features. */
+	vcpu->arch.hcr_el2 &= ~(HCR_RES0);
+	vcpu->arch.mdcr_el2 &= ~(MDCR_EL2_RES0);
+	vcpu->arch.cptr_el2 |= CPTR_NVHE_EL2_RES1;
+	vcpu->arch.cptr_el2 &= ~(CPTR_NVHE_EL2_RES0);
+}
+
+/*
+ * Initialize trap register values for protected VMs.
+ */
+void __pkvm_vcpu_init_traps(struct kvm_vcpu *vcpu)
+{
+	pvm_init_trap_regs(vcpu);
+	pvm_init_traps_aa64pfr0(vcpu);
+	pvm_init_traps_aa64pfr1(vcpu);
+	pvm_init_traps_aa64dfr0(vcpu);
+	pvm_init_traps_aa64mmfr0(vcpu);
+	pvm_init_traps_aa64mmfr1(vcpu);
+}
-- 
2.33.0.259.gc128427fd7-goog



From tabba at google.com  Fri Aug 27 03:16:07 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:07 +0100
Subject: [PATCH v5 6/8] KVM: arm64: Move sanitized copies of CPU features
In-Reply-To: <20210827101609.2808181-1-tabba@google.com>
References: <20210827101609.2808181-1-tabba@google.com>
Message-ID: <20210827101609.2808181-7-tabba@google.com>

Move the sanitized copies of the CPU feature registers to the
recently created sys_regs.c. This consolidates all copies in a
more relevant file.

No functional change intended.

Acked-by: Will Deacon <will at kernel.org>
Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/mem_protect.c | 6 ------
 arch/arm64/kvm/hyp/nvhe/sys_regs.c    | 2 ++
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 2a07d63b8498..f6d96e60b323 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -25,12 +25,6 @@ struct host_kvm host_kvm;
 
 static struct hyp_pool host_s2_pool;
 
-/*
- * Copies of the host's CPU features registers holding sanitized values.
- */
-u64 id_aa64mmfr0_el1_sys_val;
-u64 id_aa64mmfr1_el1_sys_val;
-
 const u8 pkvm_hyp_id = 1;
 
 static void *host_s2_zalloc_pages_exact(size_t size)
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index a7e836537154..4a9868ec1f0f 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -23,6 +23,8 @@ u64 id_aa64pfr0_el1_sys_val;
 u64 id_aa64pfr1_el1_sys_val;
 u64 id_aa64isar0_el1_sys_val;
 u64 id_aa64isar1_el1_sys_val;
+u64 id_aa64mmfr0_el1_sys_val;
+u64 id_aa64mmfr1_el1_sys_val;
 u64 id_aa64mmfr2_el1_sys_val;
 
 static inline void inject_undef(struct kvm_vcpu *vcpu)
-- 
2.33.0.259.gc128427fd7-goog



From tabba at google.com  Fri Aug 27 03:16:08 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:08 +0100
Subject: [PATCH v5 7/8] KVM: arm64: Trap access to pVM restricted features
In-Reply-To: <20210827101609.2808181-1-tabba@google.com>
References: <20210827101609.2808181-1-tabba@google.com>
Message-ID: <20210827101609.2808181-8-tabba@google.com>

Trap accesses to restricted features for VMs running in protected
mode.

Access to feature registers are emulated, and only supported
features are exposed to protected VMs.

Accesses to restricted registers as well as restricted
instructions are trapped, and an undefined exception is injected
into the protected guests, i.e., with EC = 0x0 (unknown reason).
This EC is the one used, according to the Arm Architecture
Reference Manual, for unallocated or undefined system registers
or instructions.

Only affects the functionality of protected VMs. Otherwise,
should not affect non-protected VMs when KVM is running in
protected mode.

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 41f05bf88f61..fe0c3833ec66 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -171,8 +171,23 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_PAC]		= kvm_hyp_handle_ptrauth,
 };
 
+static const exit_handler_fn pvm_exit_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_CP15_32]		= kvm_hyp_handle_cp15,
+	[ESR_ELx_EC_CP15_64]		= kvm_hyp_handle_cp15,
+	[ESR_ELx_EC_SYS64]		= kvm_handle_pvm_sys64,
+	[ESR_ELx_EC_SVE]		= kvm_handle_pvm_restricted,
+	[ESR_ELx_EC_FP_ASIMD]		= kvm_handle_pvm_fpsimd,
+	[ESR_ELx_EC_IABT_LOW]		= kvm_hyp_handle_iabt_low,
+	[ESR_ELx_EC_DABT_LOW]		= kvm_hyp_handle_dabt_low,
+	[ESR_ELx_EC_PAC]		= kvm_hyp_handle_ptrauth,
+};
+
 const exit_handler_fn *kvm_get_exit_handler_array(struct kvm *kvm)
 {
+	if (unlikely(kvm_vm_is_protected(kvm)))
+		return pvm_exit_handlers;
+
 	return hyp_exit_handlers;
 }
 
-- 
2.33.0.259.gc128427fd7-goog



From tabba at google.com  Fri Aug 27 03:16:09 2021
From: tabba at google.com (Fuad Tabba)
Date: Fri, 27 Aug 2021 11:16:09 +0100
Subject: [PATCH v5 8/8] KVM: arm64: Handle protected guests at 32 bits
In-Reply-To: <20210827101609.2808181-1-tabba@google.com>
References: <20210827101609.2808181-1-tabba@google.com>
Message-ID: <20210827101609.2808181-9-tabba@google.com>

Protected KVM does not support protected AArch32 guests. However,
it is possible for the guest to force run AArch32, potentially
causing problems. Add an extra check so that if the hypervisor
catches the guest doing that, it can prevent the guest from
running again by resetting vcpu->arch.target and returning
ARM_EXCEPTION_IL.

If this were to happen, The VMM can try and fix it by re-
initializing the vcpu with KVM_ARM_VCPU_INIT, however, this is
likely not possible for protected VMs.

Adapted from commit 22f553842b14 ("KVM: arm64: Handle Asymmetric
AArch32 systems")

Signed-off-by: Fuad Tabba <tabba at google.com>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 41 ++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index fe0c3833ec66..8fbb94fb8588 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -20,6 +20,7 @@
 #include <asm/kprobes.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_fixed_config.h>
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
 #include <asm/fpsimd.h>
@@ -191,6 +192,43 @@ const exit_handler_fn *kvm_get_exit_handler_array(struct kvm *kvm)
 	return hyp_exit_handlers;
 }
 
+/*
+ * Some guests (e.g., protected VMs) might not be allowed to run in AArch32.
+ * The ARMv8 architecture does not give the hypervisor a mechanism to prevent a
+ * guest from dropping to AArch32 EL0 if implemented by the CPU. If the
+ * hypervisor spots a guest in such a state ensure it is handled, and don't
+ * trust the host to spot or fix it.  The check below is based on the one in
+ * kvm_arch_vcpu_ioctl_run().
+ *
+ * Returns false if the guest ran in AArch32 when it shouldn't have, and
+ * thus should exit to the host, or true if a the guest run loop can continue.
+ */
+static bool handle_aarch32_guest(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	const struct kvm *kvm = (const struct kvm *) kern_hyp_va(vcpu->kvm);
+	bool is_aarch32_allowed =
+		FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0),
+			  get_pvm_id_aa64pfr0(vcpu)) >=
+				ID_AA64PFR0_ELx_32BIT_64BIT;
+
+	if (kvm_vm_is_protected(kvm) &&
+	    vcpu_mode_is_32bit(vcpu) &&
+	    !is_aarch32_allowed) {
+		/*
+		 * As we have caught the guest red-handed, decide that it isn't
+		 * fit for purpose anymore by making the vcpu invalid. The VMM
+		 * can try and fix it by re-initializing the vcpu with
+		 * KVM_ARM_VCPU_INIT, however, this is likely not possible for
+		 * protected VMs.
+		 */
+		vcpu->arch.target = -1;
+		*exit_code = ARM_EXCEPTION_IL;
+		return false;
+	}
+
+	return true;
+}
+
 /* Switch to the guest for legacy non-VHE systems */
 int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 {
@@ -253,6 +291,9 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 		/* Jump in the fire! */
 		exit_code = __guest_enter(vcpu);
 
+		if (unlikely(!handle_aarch32_guest(vcpu, &exit_code)))
+			break;
+
 		/* And we're baaack! */
 	} while (fixup_guest_exit(vcpu, &exit_code));
 
-- 
2.33.0.259.gc128427fd7-goog



From gregkh at linuxfoundation.org  Fri Aug 27 03:19:23 2021
From: gregkh at linuxfoundation.org (Greg KH)
Date: Fri, 27 Aug 2021 12:19:23 +0200
Subject: [PATCH 4.19.y] net: dsa: mt7530: disable learning on standalone
 ports
In-Reply-To: <CALW65ja3hYGmEqcWZzifP2-0WsJOnxcUXsey2ZH5vDbD0-nDeQ@mail.gmail.com>
References: <20210824055509.1316124-1-dqfext@gmail.com>
 <YSUQV3jhfbhbf5Ct@sashalap>
 <CALW65ja3hYGmEqcWZzifP2-0WsJOnxcUXsey2ZH5vDbD0-nDeQ@mail.gmail.com>
Message-ID: <YSi8Ky3GqBjnxbhC@kroah.com>

On Tue, Aug 24, 2021 at 11:57:53PM +0800, DENG Qingfang wrote:
> Hi Sasha,
> 
> On Tue, Aug 24, 2021 at 11:29 PM Sasha Levin <sashal at kernel.org> wrote:
> > What's the reasoning behind:
> >
> > 1. Backporting this patch?
> 
> Standalone ports should have address learning disabled, according to
> the documentation:
> https://www.kernel.org/doc/html/v5.14-rc7/networking/dsa/dsa.html#bridge-layer
> dsa_switch_ops on 5.10 or earlier does not have .port_bridge_flags
> function so it has to be done differently.
> 
> I've identified an issue related to this.

What issue is that?  Where was it reported?

> > 2. A partial backport of this patch?
> 
> The other part does not actually fix anything.

Then why is it not ok to just take the whole thing?

When backporting not-identical-patches, something almost always goes
wrong, so we prefer to take the original commit when ever possible.

thanks,

greg k-h


From peterz at infradead.org  Fri Aug 27 03:47:25 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Fri, 27 Aug 2021 12:47:25 +0200
Subject: [PATCH 00/15] perf: KVM: Fix, optimize, and clean up callbacks
In-Reply-To: <3bd4955a-1219-20b0-058b-d23f1e30aa77@gmail.com>
References: <20210827005718.585190-1-seanjc@google.com>
 <fd3dcd6c-b3d5-4453-93fb-b46d0595534e@gmail.com>
 <YSiX9OPcrDsr3P4C@hirez.programming.kicks-ass.net>
 <3bd4955a-1219-20b0-058b-d23f1e30aa77@gmail.com>
Message-ID: <YSjCvbWE6sZ29dPr@hirez.programming.kicks-ass.net>

On Fri, Aug 27, 2021 at 04:01:45PM +0800, Like Xu wrote:
> On 27/8/2021 3:44 pm, Peter Zijlstra wrote:

> > You just have to make sure all static_call() invocations that started
> > before unreg are finished before continuing with the unload.
> > synchronize_rcu() can help with that.
> 
> Do you mean something like that:
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 64e310ff4f3a..e7d310af7509 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -8465,6 +8465,7 @@ void kvm_arch_exit(void)
>  #endif
>  	kvm_lapic_exit();
>  	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
> +	synchronize_rcu();
> 
>  	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
>  		cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index e466fc8176e1..63ae56c5d133 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6508,6 +6508,7 @@ EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
>  int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
>  {
>  	perf_guest_cbs = NULL;
> +	arch_perf_update_guest_cbs();

I'm thinking the synchronize_rcu() should go here, and access to
perf_guest_cbs should be wrapped to yell when called with preemption
enabled.

But yes..

>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
> 
> > 
> > This is module unload 101. Nothing specific to static_call().
> > 


From wenbin.mei at mediatek.com  Fri Aug 27 04:53:23 2021
From: wenbin.mei at mediatek.com (Wenbin Mei)
Date: Fri, 27 Aug 2021 19:53:23 +0800
Subject: [PATCH v1] mmc: mediatek: Add HS400 online tuning support
Message-ID: <1630065205-7618-1-git-send-email-wenbin.mei@mediatek.com>

Wenbin Mei (2):
  dt-bindings: mmc: mtk-sd: add hs400 dly3 setting
  mmc: mediatek: Add HS400 online tuning support

 .../devicetree/bindings/mmc/mtk-sd.yaml       |   7 ++
 drivers/mmc/core/mmc.c                        |   8 ++
 drivers/mmc/host/mtk-sd.c                     | 118 +++++++++++++++++-
 include/linux/mmc/host.h                      |   3 +
 4 files changed, 134 insertions(+), 2 deletions(-)

--
2.17.1

From wenbin.mei at mediatek.com  Fri Aug 27 04:53:24 2021
From: wenbin.mei at mediatek.com (Wenbin Mei)
Date: Fri, 27 Aug 2021 19:53:24 +0800
Subject: [PATCH v1 1/2] dt-bindings: mmc: mtk-sd: add hs400 dly3 setting
In-Reply-To: <1630065205-7618-1-git-send-email-wenbin.mei@mediatek.com>
References: <1630065205-7618-1-git-send-email-wenbin.mei@mediatek.com>
Message-ID: <1630065205-7618-2-git-send-email-wenbin.mei@mediatek.com>

Add hs400 dly3 setting for mtk-sd yaml

Signed-off-by: Wenbin Mei <wenbin.mei at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
index e866e98..08aaa4aa 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
@@ -119,6 +119,13 @@ properties:
       If present, HS400 command responses are sampled on rising edges.
       If not present, HS400 command responses are sampled on falling edges.
 
+  mediatek,hs400-ds-dly3:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      HS400 DS dly3 delay setting.
+    minimum: 0
+    maximum: 31
+
   mediatek,latch-ck:
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
-- 
1.9.1

From wenbin.mei at mediatek.com  Fri Aug 27 04:53:25 2021
From: wenbin.mei at mediatek.com (Wenbin Mei)
Date: Fri, 27 Aug 2021 19:53:25 +0800
Subject: [PATCH v1 2/2] mmc: mediatek: Add HS400 online tuning support
In-Reply-To: <1630065205-7618-1-git-send-email-wenbin.mei@mediatek.com>
References: <1630065205-7618-1-git-send-email-wenbin.mei@mediatek.com>
Message-ID: <1630065205-7618-3-git-send-email-wenbin.mei@mediatek.com>

Due to the influence of the corner IC and vcore voltage, for the stability
of HS400 mode, we Add HS400 mode online tuning support for mediatek mmc
host.

Signed-off-by: Wenbin Mei <wenbin.mei at mediatek.com>
---
 drivers/mmc/core/mmc.c    |   8 ++++
 drivers/mmc/host/mtk-sd.c | 118 +++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/mmc/host.h  |   3 ++
 3 files changed, 127 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 838726b..f06be7f 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1222,6 +1222,14 @@ static int mmc_select_hs400(struct mmc_card *card)
 	mmc_set_timing(host, MMC_TIMING_MMC_HS400);
 	mmc_set_bus_speed(card);
 
+	if (host->ops->execute_hs400_tuning && mmc_can_ext_csd(card)) {
+		mmc_retune_disable(host);
+		err = host->ops->execute_hs400_tuning(host, card);
+		mmc_retune_enable(host);
+		if (err)
+			goto out_err;
+	}
+
 	if (host->ops->hs400_complete)
 		host->ops->hs400_complete(host);
 
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 4dfc246..f5ac711 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -258,6 +258,7 @@
 #define MSDC_PAD_TUNE_RD_SEL	  (0x1 << 13)   /* RW */
 #define MSDC_PAD_TUNE_CMD_SEL	  (0x1 << 21)   /* RW */
 
+#define PAD_DS_TUNE_DLY_SEL       (0x1 << 0)	/* RW */
 #define PAD_DS_TUNE_DLY1	  (0x1f << 2)   /* RW */
 #define PAD_DS_TUNE_DLY2	  (0x1f << 7)   /* RW */
 #define PAD_DS_TUNE_DLY3	  (0x1f << 12)  /* RW */
@@ -301,6 +302,11 @@
 #define PAD_CMD_RD_RXDLY_SEL    (0x1 << 11)     /* RW */
 #define PAD_CMD_TX_DLY          (0x1f << 12)    /* RW */
 
+/* EMMC50_PAD_DS_TUNE mask */
+#define PAD_DS_DLY_SEL		(0x1 << 16)	/* RW */
+#define PAD_DS_DLY1		(0x1f << 10)	/* RW */
+#define PAD_DS_DLY3		(0x1f << 0)	/* RW */
+
 #define REQ_CMD_EIO  (0x1 << 0)
 #define REQ_CMD_TMO  (0x1 << 1)
 #define REQ_DAT_ERR  (0x1 << 2)
@@ -448,11 +454,13 @@ struct msdc_host {
 	bool vqmmc_enabled;
 	u32 latch_ck;
 	u32 hs400_ds_delay;
+	u32 hs400_ds_dly3;
 	u32 hs200_cmd_int_delay; /* cmd internal delay for HS200/SDR104 */
 	u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */
 	bool hs400_cmd_resp_sel_rising;
 				 /* cmd response sample selection for HS400 */
 	bool hs400_mode;	/* current eMMC will run at hs400 mode */
+	bool hs400_tuning;	/* hs400 mode online tuning */
 	bool internal_cd;	/* Use internal card-detect logic */
 	bool cqhci;		/* support eMMC hw cmdq */
 	struct msdc_save_para save_para; /* used when gate HCLK */
@@ -1190,7 +1198,8 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
 	if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
 		if (events & MSDC_INT_CMDTMO ||
 		    (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
-		     cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200))
+		     cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
+		     (host->hs400_tuning && cmd->opcode != MMC_SEND_EXT_CSD)))
 			/*
 			 * should not clear fifo/interrupt as the tune data
 			 * may have alreay come when cmd19/cmd21 gets response
@@ -1287,7 +1296,8 @@ static void msdc_cmd_next(struct msdc_host *host,
 	if ((cmd->error &&
 	    !(cmd->error == -EILSEQ &&
 	      (cmd->opcode == MMC_SEND_TUNING_BLOCK ||
-	       cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200))) ||
+	       cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200 ||
+	       (host->hs400_tuning && cmd->opcode != MMC_SEND_EXT_CSD)))) ||
 	    (mrq->sbc && mrq->sbc->error))
 		msdc_request_done(host, mrq);
 	else if (cmd == mrq->sbc)
@@ -2251,6 +2261,106 @@ static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
 	return 0;
 }
 
+static int msdc_send_cxd_data(struct mmc_card *card, struct mmc_host *host)
+{
+	struct mmc_request mrq = {};
+	struct mmc_command cmd = {};
+	struct mmc_data data = {};
+	unsigned int len = 512;
+	struct scatterlist sg;
+	u8 *ext_csd;
+
+	ext_csd = kzalloc(len, GFP_KERNEL);
+	if (!ext_csd)
+		return -ENOMEM;
+
+	mrq.cmd = &cmd;
+	mrq.data = &data;
+
+	cmd.opcode = MMC_SEND_EXT_CSD;
+	cmd.arg = 0;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+
+	data.blksz = len;
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+	data.sg = &sg;
+	data.sg_len = 1;
+
+	sg_init_one(&sg, ext_csd, len);
+	mmc_set_data_timeout(&data, card);
+	mmc_wait_for_req(host, &mrq);
+
+	kfree(ext_csd);
+
+	if (cmd.error)
+		return cmd.error;
+	if (data.error)
+		return data.error;
+
+	return 0;
+}
+
+static int msdc_execute_hs400_tuning(struct mmc_host *mmc, struct mmc_card *card)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	struct msdc_delay_phase dly1_delay;
+	u32 val, result_dly1 = 0;
+	int i, ret;
+
+	if (host->top_base) {
+		sdr_set_bits(host->top_base + EMMC50_PAD_DS_TUNE,
+			     PAD_DS_DLY_SEL);
+		if (host->hs400_ds_dly3)
+			sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE,
+				      PAD_DS_DLY3, host->hs400_ds_dly3);
+	} else {
+		sdr_set_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY_SEL);
+		if (host->hs400_ds_dly3)
+			sdr_set_field(host->base + PAD_DS_TUNE,
+				      PAD_DS_TUNE_DLY3, host->hs400_ds_dly3);
+	}
+
+	host->hs400_tuning = true;
+	for (i = 0; i < PAD_DELAY_MAX; i++) {
+		if (host->top_base)
+			sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE,
+				      PAD_DS_DLY1, i);
+		else
+			sdr_set_field(host->base + PAD_DS_TUNE,
+				      PAD_DS_TUNE_DLY1, i);
+		ret = msdc_send_cxd_data(card, mmc);
+		if (!ret)
+			result_dly1 |= (1 << i);
+	}
+	host->hs400_tuning = false;
+
+	dly1_delay = get_best_delay(host, result_dly1);
+	if (dly1_delay.maxlen == 0) {
+		dev_err(host->dev, "Failed to get DLY1 delay!\n");
+		goto fail;
+	}
+	if (host->top_base)
+		sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE,
+			      PAD_DS_DLY1, dly1_delay.final_phase);
+	else
+		sdr_set_field(host->base + PAD_DS_TUNE,
+			      PAD_DS_TUNE_DLY1, dly1_delay.final_phase);
+
+	if (host->top_base)
+		val = readl(host->top_base + EMMC50_PAD_DS_TUNE);
+	else
+		val = readl(host->base + PAD_DS_TUNE);
+
+	dev_info(host->dev, "Fianl PAD_DS_TUNE: 0x%x\n", val);
+
+	return 0;
+
+fail:
+	dev_err(host->dev, "Failed to tuning DS pin delay!\n");
+	return -ERANGE;
+}
+
 static void msdc_hw_reset(struct mmc_host *mmc)
 {
 	struct msdc_host *host = mmc_priv(mmc);
@@ -2377,6 +2487,7 @@ static void msdc_cqe_post_disable(struct mmc_host *mmc)
 	.card_busy = msdc_card_busy,
 	.execute_tuning = msdc_execute_tuning,
 	.prepare_hs400_tuning = msdc_prepare_hs400_tuning,
+	.execute_hs400_tuning = msdc_execute_hs400_tuning,
 	.hw_reset = msdc_hw_reset,
 };
 
@@ -2396,6 +2507,9 @@ static void msdc_of_property_parse(struct platform_device *pdev,
 	of_property_read_u32(pdev->dev.of_node, "hs400-ds-delay",
 			     &host->hs400_ds_delay);
 
+	of_property_read_u32(pdev->dev.of_node, "mediatek,hs400-ds-dly3",
+			     &host->hs400_ds_dly3);
+
 	of_property_read_u32(pdev->dev.of_node, "mediatek,hs200-cmd-int-delay",
 			     &host->hs200_cmd_int_delay);
 
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index ff1a251..7552d5e 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -162,6 +162,9 @@ struct mmc_host_ops {
 	/* Prepare HS400 target operating frequency depending host driver */
 	int	(*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
 
+	/* Execute HS400 tuning depending host driver */
+	int	(*execute_hs400_tuning)(struct mmc_host *host, struct mmc_card *card);
+
 	/* Prepare switch to DDR during the HS400 init sequence */
 	int	(*hs400_prepare_ddr)(struct mmc_host *host);
 
-- 
1.9.1

From wangkefeng.wang at huawei.com  Fri Aug 27 05:39:48 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Fri, 27 Aug 2021 20:39:48 +0800
Subject: [PATCH] ARM: kasan: Fix __get_user_check failure with kasan
In-Reply-To: <20210825064650.98162-1-shaolexi@huawei.com>
References: <20210825064650.98162-1-shaolexi@huawei.com>
Message-ID: <3b14762f-9aea-086e-68c8-2eb68891edb5@huawei.com>


On 2021/8/25 14:46, Lexi Shao wrote:
> In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
> error code is store in register int __e(r0). When kasan is
> enabled, assigning value to kernel address might trigger kasan check,
> which unexpectedly overwrites r0 and causes undefined behavior on arm
> kasan images.
>
> One example is failure in do_futex and results in process soft lockup.
> Log:
> watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
> Q:Reg:1151]
> ...
> (__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
> (futex_wait_setup) from (futex_wait+0x138/0x394)
> (futex_wait) from (do_futex+0x164/0xe40)
> (do_futex) from (sys_futex_time32+0x178/0x230)
> (sys_futex_time32) from (ret_fast_syscall+0x0/0x50)
>
> The soft lockup happens in function futex_wait_setup. The reason is
> function get_futex_value_locked always return EINVAL, thus pc jump
> back to retry label and causes looping.
>
> The assembly code of get_futex_value_locked in kernel/futex.c:
> ...
> c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
> // "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
> c01f6dcc:       e1a00007        mov     r0, r7
> c01f6dd0:       e1a05002        mov     r5, r2
> c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
> c01f6dd8:       e5875000        str     r5, [r7]
> // save ret value of __get_user(*dest, from), which is dest address now
> c01f6ddc:       e1a05000        mov     r5, r0
> ...
> // checking return value of __get_user failed
> c01f6e00:       e3550000        cmp     r5, #0
> ...
> c01f6e0c:       01a00005        moveq   r0, r5
> // assign return value to EINVAL
> c01f6e10:       13e0000d        mvnne   r0, #13
>
> Return value is the destination address of get_user thus certainly
> non-zero, so get_futex_value_locked always return EINVAL.
>
> Fix it by using a tmp vairable to store the error code before the
> assignment. This fix has no effects to non-kasan images thanks to compiler
> optimization. It only affects cases that overwrite r0 due to kasan check.
>
> This should fix bug discussed in link:
> [1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c at gmail.com/
>
> Fixes: 421015713b30 ("ARM: 9017/2: Enable KASan for ARM")
> Signed-off-by: Lexi Shao <shaolexi at huawei.com>
> ---
Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>


From linux at armlinux.org.uk  Fri Aug 27 05:56:01 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 27 Aug 2021 13:56:01 +0100
Subject: [PATCH] ARM: kasan: Fix __get_user_check failure with kasan
In-Reply-To: <20210825064650.98162-1-shaolexi@huawei.com>
References: <20210825064650.98162-1-shaolexi@huawei.com>
Message-ID: <20210827125601.GT22278@shell.armlinux.org.uk>

On Wed, Aug 25, 2021 at 02:46:50PM +0800, Lexi Shao wrote:
> In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
> error code is store in register int __e(r0). When kasan is
> enabled, assigning value to kernel address might trigger kasan check,
> which unexpectedly overwrites r0 and causes undefined behavior on arm
> kasan images.
> 
> One example is failure in do_futex and results in process soft lockup.
> Log:
> watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
> Q:Reg:1151]
> ...
> (__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
> (futex_wait_setup) from (futex_wait+0x138/0x394)
> (futex_wait) from (do_futex+0x164/0xe40)
> (do_futex) from (sys_futex_time32+0x178/0x230)
> (sys_futex_time32) from (ret_fast_syscall+0x0/0x50)
> 
> The soft lockup happens in function futex_wait_setup. The reason is
> function get_futex_value_locked always return EINVAL, thus pc jump
> back to retry label and causes looping.
> 
> The assembly code of get_futex_value_locked in kernel/futex.c:
> ...
> c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
> // "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
> c01f6dcc:       e1a00007        mov     r0, r7
> c01f6dd0:       e1a05002        mov     r5, r2
> c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
> c01f6dd8:       e5875000        str     r5, [r7]
> // save ret value of __get_user(*dest, from), which is dest address now
> c01f6ddc:       e1a05000        mov     r5, r0
> ...
> // checking return value of __get_user failed
> c01f6e00:       e3550000        cmp     r5, #0
> ...
> c01f6e0c:       01a00005        moveq   r0, r5
> // assign return value to EINVAL
> c01f6e10:       13e0000d        mvnne   r0, #13
> 
> Return value is the destination address of get_user thus certainly
> non-zero, so get_futex_value_locked always return EINVAL.

This description doesn't actually make it clear why this is failing in
this case, until one looks at get_futex_value_locked() and realises
that what is actually going on here is:

	*dest = (typeof(*(p))) __r2;

which is why we end up with the store there.

> Fix it by using a tmp vairable to store the error code before the
> assignment. This fix has no effects to non-kasan images thanks to compiler
> optimization. It only affects cases that overwrite r0 due to kasan check.
> 
> This should fix bug discussed in link:
> [1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c at gmail.com/
> 
> Fixes: 421015713b30 ("ARM: 9017/2: Enable KASan for ARM")
> Signed-off-by: Lexi Shao <shaolexi at huawei.com>
> ---
>  arch/arm/include/asm/uaccess.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
> index a13d90206472..a6eb9af74870 100644
> --- a/arch/arm/include/asm/uaccess.h
> +++ b/arch/arm/include/asm/uaccess.h
> @@ -200,6 +200,7 @@ extern int __get_user_64t_4(void *);
>  		register unsigned long __l asm("r1") = __limit;		\
>  		register int __e asm("r0");				\
>  		unsigned int __ua_flags = uaccess_save_and_enable();	\
> +		int __tmp_e;						\
>  		switch (sizeof(*(__p))) {				\
>  		case 1:							\
>  			if (sizeof((x)) >= 8)				\
> @@ -227,9 +228,10 @@ extern int __get_user_64t_4(void *);
>  			break;						\
>  		default: __e = __get_user_bad(); break;			\
>  		}							\
> +		__tmp_e = __e;						\
>  		uaccess_restore(__ua_flags);				\
>  		x = (typeof(*(p))) __r2;				\
> -		__e;							\
> +		__e = __tmp_e;						\

There is no need to re-assign __tmp_e back to __e - you can just return
__tmp_e here.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From kuba at kernel.org  Fri Aug 27 07:02:38 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 27 Aug 2021 07:02:38 -0700
Subject: [PATCH] stmmac: dwmac-loongson: change the pr_info() to
 dev_err() in loongson_dwmac_probe()
In-Reply-To: <20210827085550.13519-1-zhaoxiao@uniontech.com>
References: <20210827085550.13519-1-zhaoxiao@uniontech.com>
Message-ID: <20210827070238.7586fb11@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Fri, 27 Aug 2021 16:55:50 +0800 zhaoxiao wrote:
> - Change the pr_info/dev_info to dev_err.
> - Add the dev_err to improve readability.
> 
> Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
> ---
>  .../net/ethernet/stmicro/stmmac/dwmac-loongson.c  | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> index 4c9a37dd0d3f..495c94e7929f 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> @@ -54,20 +54,21 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>  	bool mdio = false;
>  
>  	np = dev_of_node(&pdev->dev);
> -
>  	if (!np) {
> -		pr_info("dwmac_loongson_pci: No OF node\n");
> +		dev_err(&pdev->dev, "dwmac_loongson_pci: No OF node\n");
>  		return -ENODEV;
>  	}
>  
>  	if (!of_device_is_compatible(np, "loongson, pci-gmac")) {
> -		pr_info("dwmac_loongson_pci: Incompatible OF node\n");
> +		dev_err(&pdev->dev, "dwmac_loongson_pci: Incompatible OF node\n");
>  		return -ENODEV;
>  	}
>  
>  	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
> -	if (!plat)
> +	if (!plat) {
> +		dev_err(&pdev->dev, "memory allocation failed\n");

Please don't add error messages after allocation failures. OOM will
produce a lot of kernel messages and a stack trace already.

>  		return -ENOMEM;
> +	}
>  
>  	if (plat->mdio_node) {
>  		dev_err(&pdev->dev, "Found MDIO subnode\n");
> @@ -109,8 +110,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>  		plat->bus_id = pci_dev_id(pdev);
>  
>  	phy_mode = device_get_phy_mode(&pdev->dev);
> -	if (phy_mode < 0)
> +	if (phy_mode < 0) {
>  		dev_err(&pdev->dev, "phy_mode not found\n");
> +		return phy_mode;

You're adding a return here, it should be a separate patch with its own
justification.

> +	}
>  
>  	plat->phy_interface = phy_mode;
>  	plat->interface = PHY_INTERFACE_MODE_GMII;
> @@ -130,7 +133,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>  
>  	res.wol_irq = of_irq_get_byname(np, "eth_wake_irq");
>  	if (res.wol_irq < 0) {
> -		dev_info(&pdev->dev, "IRQ eth_wake_irq not found, using macirq\n");
> +		dev_err(&pdev->dev, "IRQ eth_wake_irq not found, using macirq\n");

Why upgrade to an error, isn't wol_irq optional?

>  		res.wol_irq = res.irq;
>  	}
>  



From ulf.hansson at linaro.org  Fri Aug 27 07:44:28 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Fri, 27 Aug 2021 16:44:28 +0200
Subject: [PATCH V2 05/10] mmc: sdhci-iproc: Set
 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN on BCM2711
In-Reply-To: <127aeb73-528d-9118-3f84-6ad6c6debe84@i2se.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
 <1628334401-6577-6-git-send-email-stefan.wahren@i2se.com>
 <3e8bfa67-e3fe-bcfd-1941-90cae7ed0176@arm.com>
 <CAPDyKFpGoMVywNFMskTTYYOvLZMK-1u2+5V_q1uW2H5AZJ_W7Q@mail.gmail.com>
 <127aeb73-528d-9118-3f84-6ad6c6debe84@i2se.com>
Message-ID: <CAPDyKFqo+cxBN2MkYYuDYr2rT1He8dHObZogvmMQX3fqhpNB-g@mail.gmail.com>

On Thu, 26 Aug 2021 at 13:18, Stefan Wahren <stefan.wahren at i2se.com> wrote:
>
> Am 26.08.21 um 11:22 schrieb Ulf Hansson:
> > On Thu, 26 Aug 2021 at 08:36, Jeremy Linton <jeremy.linton at arm.com> wrote:
> >> Hi,
> >>
> >>
> >> On 8/7/21 6:06 AM, Stefan Wahren wrote:
> >>> From: Nicolas Saenz Julienne <nsaenz at kernel.org>
> >>>
> >>> The controller doesn't seem to pick-up on clock changes, so set the
> >>> SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN flag to query the clock frequency
> >>> directly from the clock.
> >>>
> >>> Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711")
> >>> Signed-off-by: Nicolas Saenz Julienne <nsaenz at kernel.org>
> >>> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> >>> ---
> >>>   drivers/mmc/host/sdhci-iproc.c | 3 ++-
> >>>   1 file changed, 2 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
> >>> index 032bf85..e7565c6 100644
> >>> --- a/drivers/mmc/host/sdhci-iproc.c
> >>> +++ b/drivers/mmc/host/sdhci-iproc.c
> >>> @@ -295,7 +295,8 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
> >>>   };
> >>>
> >>>   static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
> >>> -     .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12,
> >>> +     .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 |
> >>> +               SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
> >>>       .ops = &sdhci_iproc_bcm2711_ops,
> >>>   };
> >> I just noticed that this got merged to rc7, and it breaks the ACPI based
> >> rpi's because it causes the 100Mhz max clock to be overridden to the
> >> return from sdhci_iproc_get_max_clock() which is 0 because there isn't a
> >> OF/DT based clock device.
> > Thanks for reporting! I allow Stefan to respond in a day or two,
> > before I do a revert of it.
>
> I'm fine with a revert.
>
> Thanks

Patch reverted and applied for fixes, thanks!

Kind regards
Uffe


From seanjc at google.com  Fri Aug 27 07:49:50 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 14:49:50 +0000
Subject: [PATCH 05/15] perf: Track guest callbacks on a per-CPU basis
In-Reply-To: <YSiRBQQE7md7ZrNC@hirez.programming.kicks-ass.net>
References: <20210827005718.585190-1-seanjc@google.com>
 <20210827005718.585190-6-seanjc@google.com>
 <YSiRBQQE7md7ZrNC@hirez.programming.kicks-ass.net>
Message-ID: <YSj7jq32U8Euf38o@google.com>

On Fri, Aug 27, 2021, Peter Zijlstra wrote:
> On Thu, Aug 26, 2021 at 05:57:08PM -0700, Sean Christopherson wrote:
> > Use a per-CPU pointer to track perf's guest callbacks so that KVM can set
> > the callbacks more precisely and avoid a lurking NULL pointer dereference.
> 
> I'm completely failing to see how per-cpu helps anything here...

It doesn't help until KVM is converted to set the per-cpu pointer in flows that
are protected against preemption, and more specifically when KVM only writes to
the pointer from the owning CPU.  

> > On x86, KVM supports being built as a module and thus can be unloaded.
> > And because the shared callbacks are referenced from IRQ/NMI context,
> > unloading KVM can run concurrently with perf, and thus all of perf's
> > checks for a NULL perf_guest_cbs are flawed as perf_guest_cbs could be
> > nullified between the check and dereference.
> 
> No longer allowing KVM to be a module would be *AWESOME*. I detest how
> much we have to export for KVM :/
> 
> Still, what stops KVM from doing a coherent unreg? Even the
> static_call() proposed in the other patch, unreg can do
> static_call_update() + synchronize_rcu() to ensure everybody sees the
> updated pointer (would require a quick audit to see all users are with
> preempt disabled, but I think your using per-cpu here already imposes
> the same).

Ignoring static call for the moment, I don't see how the unreg side can be safe
using a bare single global pointer.  There is no way for KVM to prevent an NMI
from running in parallel on a different CPU.  If there's a more elegant solution,
especially something that can be backported, e.g. an rcu-protected pointer, I'm
all for it.  I went down the per-cpu path because it allowed for cleanups in KVM,
but similar cleanups can be done without per-cpu perf callbacks.

As for static calls, I certainly have no objection to employing static calls for
the callbacks, but IMO we should not be relying on static call for correctness,
i.e. the existing bug needs to be fixed first.


From john.garry at huawei.com  Fri Aug 27 07:55:05 2021
From: john.garry at huawei.com (John Garry)
Date: Fri, 27 Aug 2021 15:55:05 +0100
Subject: arm scsi drivers
In-Reply-To: <5a72842f-99db-8787-120b-6d85e7884e2d@huawei.com>
References: <5a72842f-99db-8787-120b-6d85e7884e2d@huawei.com>
Message-ID: <9552a506-e53a-3fd3-b38e-3cec81e713a6@huawei.com>

Hi Russell,

Have you had a chance to consider the below?

Thanks


> 
> Recently we tried to remove scsi_cmnd.tags struct member [0].
> 
> However it now shows that some of the arm SCSI drivers continue to use 
> this [1]. I think any other driver usage of this member had been found 
> and removed.
> 
> The impression is that the usage of scsi_cmnd.tag in those drivers is 
> quite dubious.
> 
> Now checking [2], it appears that you may have had some patches for 
> these drivers locally.
> 
> So is that the case? Is this HW still used with bleeding edge kernels? 
> If so, can we fix up this tag management?
> 
> [0] 
> https://lore.kernel.org/linux-scsi/6c83bd7f-9fd2-1b43-627f-615467fa55d4 at huawei.com/T/#mb47909f38f35837686734369600051b278d124af 
> 
> 
> [1] 
> https://lore.kernel.org/linux-scsi/6c83bd7f-9fd2-1b43-627f-615467fa55d4 at huawei.com/T/#md5d786e5753083b2f3e8e761b1c69809f82c7485 
> 
> 
> [2] 
> https://lore.kernel.org/lkml/20210109174357.GB1551 at shell.armlinux.org.uk/
> 
> Thanks,
> John



From peterz at infradead.org  Fri Aug 27 07:56:45 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Fri, 27 Aug 2021 16:56:45 +0200
Subject: [PATCH 05/15] perf: Track guest callbacks on a per-CPU basis
In-Reply-To: <YSj7jq32U8Euf38o@google.com>
References: <20210827005718.585190-1-seanjc@google.com>
 <20210827005718.585190-6-seanjc@google.com>
 <YSiRBQQE7md7ZrNC@hirez.programming.kicks-ass.net>
 <YSj7jq32U8Euf38o@google.com>
Message-ID: <YSj9LQfbKxOhxqcP@hirez.programming.kicks-ass.net>

On Fri, Aug 27, 2021 at 02:49:50PM +0000, Sean Christopherson wrote:
> On Fri, Aug 27, 2021, Peter Zijlstra wrote:
> > On Thu, Aug 26, 2021 at 05:57:08PM -0700, Sean Christopherson wrote:
> > > Use a per-CPU pointer to track perf's guest callbacks so that KVM can set
> > > the callbacks more precisely and avoid a lurking NULL pointer dereference.
> > 
> > I'm completely failing to see how per-cpu helps anything here...
> 
> It doesn't help until KVM is converted to set the per-cpu pointer in flows that
> are protected against preemption, and more specifically when KVM only writes to
> the pointer from the owning CPU.  

So the 'problem' I have with this is that sane (!KVM using) people, will
still have to suffer that load, whereas with the static_call() we patch
in an 'xor %rax,%rax' and only have immediate code flow.

> Ignoring static call for the moment, I don't see how the unreg side can be safe
> using a bare single global pointer.  There is no way for KVM to prevent an NMI
> from running in parallel on a different CPU.  If there's a more elegant solution,
> especially something that can be backported, e.g. an rcu-protected pointer, I'm
> all for it.  I went down the per-cpu path because it allowed for cleanups in KVM,
> but similar cleanups can be done without per-cpu perf callbacks.

If all the perf_guest_cbs dereferences are with preemption disabled
(IRQs disabled, IRQ context, NMI context included), then the sequence:

	WRITE_ONCE(perf_guest_cbs, NULL);
	synchronize_rcu();

Ensures that all prior observers of perf_guest_csb will have completed
and future observes must observe the NULL value.



From seanjc at google.com  Fri Aug 27 07:58:35 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 14:58:35 +0000
Subject: [PATCH 07/15] KVM: Use dedicated flag to track if KVM is
 handling an NMI from guest
In-Reply-To: <YSiUnDbi/aZ3nunT@hirez.programming.kicks-ass.net>
References: <20210827005718.585190-1-seanjc@google.com>
 <20210827005718.585190-8-seanjc@google.com>
 <YSiUnDbi/aZ3nunT@hirez.programming.kicks-ass.net>
Message-ID: <YSj9mz4F2NDSKaas@google.com>

On Fri, Aug 27, 2021, Peter Zijlstra wrote:
> On Thu, Aug 26, 2021 at 05:57:10PM -0700, Sean Christopherson wrote:
> > diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
> > index 5cedc0e8a5d5..4c5ba4128b38 100644
> > --- a/arch/x86/kvm/x86.h
> > +++ b/arch/x86/kvm/x86.h
> > @@ -395,9 +395,10 @@ static inline void kvm_unregister_perf_callbacks(void)
> >  
> >  DECLARE_PER_CPU(struct kvm_vcpu *, current_vcpu);
> >  
> > -static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu)
> > +static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu, bool is_nmi)
> >  {
> >  	__this_cpu_write(current_vcpu, vcpu);
> > +	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, is_nmi);
> >  
> >  	kvm_register_perf_callbacks();
> >  }
> > @@ -406,6 +407,7 @@ static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
> >  {
> >  	kvm_unregister_perf_callbacks();
> >  
> > +	WRITE_ONCE(vcpu->arch.handling_nmi_from_guest, false);
> >  	__this_cpu_write(current_vcpu, NULL);
> >  }
> 
> Does this rely on kvm_{,un}register_perf_callback() being a function
> call and thus implying a sequence point to order the stores? 

No, I'm just terrible at remembering which macros provide what ordering guarantees,
i.e. I was thinking WRITE_ONCE provided guarantees against compiler reordering.


From wangkefeng.wang at huawei.com  Fri Aug 27 08:05:58 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Fri, 27 Aug 2021 23:05:58 +0800
Subject: [PATCH v2 2/4] Revert "ARM: amba: make use of -1 IRQs warn"
In-Reply-To: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
References: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
Message-ID: <20210827150600.78811-3-wangkefeng.wang@huawei.com>

After commit 77a7300abad7 ("of/irq: Get rid of NO_IRQ usage"),
no irq case has been removed, irq_of_parse_and_map() will return
0 in all cases when get error from parse and map an interrupt into
linux virq space.

amba_device_register() is only used on no-DT initialization, see
  s3c64xx_pl080_init()		arch/arm/mach-s3c/pl080.c
  ep93xx_init_devices()		arch/arm/mach-ep93xx/core.c

They won't set -1 to irq[0], so no need the warn.

This reverts commit 2eac58d5026e4ec8b17ff8b62877fea9e1d2f1b3.

Cc: Russell King <linux at armlinux.org.uk>
Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 drivers/amba/bus.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index c96fdef92fe1..37fcd5592c6f 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -379,9 +379,6 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
 	void __iomem *tmp;
 	int i, ret;
 
-	WARN_ON(dev->irq[0] == (unsigned int)-1);
-	WARN_ON(dev->irq[1] == (unsigned int)-1);
-
 	ret = request_resource(parent, &dev->res);
 	if (ret)
 		goto err_out;
-- 
2.18.0.huawei.25



From wangkefeng.wang at huawei.com  Fri Aug 27 08:05:57 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Fri, 27 Aug 2021 23:05:57 +0800
Subject: [PATCH v2 1/4] amba: Drop unused functions about APB/AHB devices add
In-Reply-To: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
References: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
Message-ID: <20210827150600.78811-2-wangkefeng.wang@huawei.com>

No one use the following functions, kill them.

  amba_aphb_device_add()
  amba_apb_device_add()
  amba_apb_device_add_res()
  amba_ahb_device_add()
  amba_ahb_device_add_res()

Cc: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 drivers/amba/bus.c       | 72 ----------------------------------------
 include/linux/amba/bus.h | 18 ----------
 2 files changed, 90 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 939ca220bf78..c96fdef92fe1 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -581,78 +581,6 @@ int amba_device_add(struct amba_device *dev, struct resource *parent)
 }
 EXPORT_SYMBOL_GPL(amba_device_add);
 
-static struct amba_device *
-amba_aphb_device_add(struct device *parent, const char *name,
-		     resource_size_t base, size_t size, int irq1, int irq2,
-		     void *pdata, unsigned int periphid, u64 dma_mask,
-		     struct resource *resbase)
-{
-	struct amba_device *dev;
-	int ret;
-
-	dev = amba_device_alloc(name, base, size);
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	dev->dev.coherent_dma_mask = dma_mask;
-	dev->irq[0] = irq1;
-	dev->irq[1] = irq2;
-	dev->periphid = periphid;
-	dev->dev.platform_data = pdata;
-	dev->dev.parent = parent;
-
-	ret = amba_device_add(dev, resbase);
-	if (ret) {
-		amba_device_put(dev);
-		return ERR_PTR(ret);
-	}
-
-	return dev;
-}
-
-struct amba_device *
-amba_apb_device_add(struct device *parent, const char *name,
-		    resource_size_t base, size_t size, int irq1, int irq2,
-		    void *pdata, unsigned int periphid)
-{
-	return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
-				    periphid, 0, &iomem_resource);
-}
-EXPORT_SYMBOL_GPL(amba_apb_device_add);
-
-struct amba_device *
-amba_ahb_device_add(struct device *parent, const char *name,
-		    resource_size_t base, size_t size, int irq1, int irq2,
-		    void *pdata, unsigned int periphid)
-{
-	return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
-				    periphid, ~0ULL, &iomem_resource);
-}
-EXPORT_SYMBOL_GPL(amba_ahb_device_add);
-
-struct amba_device *
-amba_apb_device_add_res(struct device *parent, const char *name,
-			resource_size_t base, size_t size, int irq1,
-			int irq2, void *pdata, unsigned int periphid,
-			struct resource *resbase)
-{
-	return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
-				    periphid, 0, resbase);
-}
-EXPORT_SYMBOL_GPL(amba_apb_device_add_res);
-
-struct amba_device *
-amba_ahb_device_add_res(struct device *parent, const char *name,
-			resource_size_t base, size_t size, int irq1,
-			int irq2, void *pdata, unsigned int periphid,
-			struct resource *resbase)
-{
-	return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
-				    periphid, ~0ULL, resbase);
-}
-EXPORT_SYMBOL_GPL(amba_ahb_device_add_res);
-
-
 static void amba_device_initialize(struct amba_device *dev, const char *name)
 {
 	device_initialize(&dev->dev);
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index c68d87b87283..edfcf7a14dcd 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -122,24 +122,6 @@ struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t);
 void amba_device_put(struct amba_device *);
 int amba_device_add(struct amba_device *, struct resource *);
 int amba_device_register(struct amba_device *, struct resource *);
-struct amba_device *amba_apb_device_add(struct device *parent, const char *name,
-					resource_size_t base, size_t size,
-					int irq1, int irq2, void *pdata,
-					unsigned int periphid);
-struct amba_device *amba_ahb_device_add(struct device *parent, const char *name,
-					resource_size_t base, size_t size,
-					int irq1, int irq2, void *pdata,
-					unsigned int periphid);
-struct amba_device *
-amba_apb_device_add_res(struct device *parent, const char *name,
-			resource_size_t base, size_t size, int irq1,
-			int irq2, void *pdata, unsigned int periphid,
-			struct resource *resbase);
-struct amba_device *
-amba_ahb_device_add_res(struct device *parent, const char *name,
-			resource_size_t base, size_t size, int irq1,
-			int irq2, void *pdata, unsigned int periphid,
-			struct resource *resbase);
 void amba_device_unregister(struct amba_device *);
 struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int);
 int amba_request_regions(struct amba_device *, const char *);
-- 
2.18.0.huawei.25



From wangkefeng.wang at huawei.com  Fri Aug 27 08:06:00 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Fri, 27 Aug 2021 23:06:00 +0800
Subject: [PATCH v2 4/4] amba: Properly handle device probe without IRQ domain
In-Reply-To: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
References: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
Message-ID: <20210827150600.78811-5-wangkefeng.wang@huawei.com>

of_amba_device_create() uses irq_of_parse_and_map() to translate
a DT interrupt specification into a Linux virtual interrupt number.

But it doesn't properly handle the case where the interrupt controller
is not yet available, eg, when pl011 interrupt is connected to MBIGEN
interrupt controller, because the mbigen initialization is too late,
which will lead to no IRQ due to no IRQ domain found, log is shown below,
  "irq: no irq domain found for uart0 !"

use of_irq_get() to return -EPROBE_DEFER as above, and in the driver
deferred probe, it will properly handle in such case, also return 0
in other fail cases to be consistent as before.

Cc: Russell King <linux at armlinux.org.uk>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Frank Rowand <frowand.list at gmail.com>
Reported-by: Ruizhe Lin <linruizhe at huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
 drivers/of/platform.c |  6 +-----
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 4d3a565ca079..96e84ce66e9a 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -19,6 +19,7 @@
 #include <linux/clk/clk-conf.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
+#include <linux/of_irq.h>
 
 #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
 
@@ -170,6 +171,28 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
 	return retval;
 }
 
+static int of_amba_device_decode_irq(struct amba_device *dev)
+{
+	struct device_node *node = dev->dev.of_node;
+	int i, irq;
+
+	if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
+		/* Decode the IRQs and address ranges */
+		for (i = 0; i < AMBA_NR_IRQS; i++) {
+			irq = of_irq_get(node, i);
+			if (irq < 0) {
+				if (irq == -EPROBE_DEFER)
+					return irq;
+				irq = 0;
+			}
+
+			dev->irq[i] = irq;
+		}
+	}
+
+	return 0;
+}
+
 /*
  * These are the device model conversion veneers; they convert the
  * device model structures to our more specific structures.
@@ -182,6 +205,10 @@ static int amba_probe(struct device *dev)
 	int ret;
 
 	do {
+		ret = of_amba_device_decode_irq(pcdev);
+		if (ret)
+			break;
+
 		ret = of_clk_set_defaults(dev->of_node, false);
 		if (ret < 0)
 			break;
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 74afbb7a4f5e..32d5ff8df747 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -222,7 +222,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 {
 	struct amba_device *dev;
 	const void *prop;
-	int i, ret;
+	int ret;
 
 	pr_debug("Creating amba device %pOF\n", node);
 
@@ -253,10 +253,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 	if (prop)
 		dev->periphid = of_read_ulong(prop, 1);
 
-	/* Decode the IRQs and address ranges */
-	for (i = 0; i < AMBA_NR_IRQS; i++)
-		dev->irq[i] = irq_of_parse_and_map(node, i);
-
 	ret = of_address_to_resource(node, 0, &dev->res);
 	if (ret) {
 		pr_err("amba: of_address_to_resource() failed (%d) for %pOF\n",
-- 
2.18.0.huawei.25



From wangkefeng.wang at huawei.com  Fri Aug 27 08:05:56 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Fri, 27 Aug 2021 23:05:56 +0800
Subject: [PATCH v2 0/4] amba: Properly handle device probe without IRQ domain
Message-ID: <20210827150600.78811-1-wangkefeng.wang@huawei.com>

Patch 1~3 make some cleanup, and patch 4 use of_irq_get() instead of 
irq_of_parse_and_map() to get irq number, return -EPROBE_DEFER if the irq
domain is not yet created, and move irq obtain into amba_probe, the driver 
defer probe will properly to handle this error.

V2:
- add new patch to kill irq sysfs file, suggested by Rob.
- move irq obtain from amba_device_add() to amba_probe(), suggested by Saravana.
  (As Saravana said, it will use a new mechanism to deal with the defer probe
   when amba device add and drop the amba specific deferring code, see[1])
- add Rob Reviewed-by to patch 1/2, no patch4 due to patch4 is changed

[1] https://lore.kernel.org/lkml/20210304195101.3843496-1-saravanak at google.com/

Kefeng Wang (4):
  amba: Drop unused functions about APB/AHB devices add
  Revert "ARM: amba: make use of -1 IRQs warn"
  amba: Kill sysfs attribute file of irq
  amba: Properly handle device probe without IRQ domain

 drivers/amba/bus.c       | 120 ++++++++++-----------------------------
 drivers/of/platform.c    |   6 +-
 include/linux/amba/bus.h |  18 ------
 3 files changed, 30 insertions(+), 114 deletions(-)

-- 
2.18.0.huawei.25



From wangkefeng.wang at huawei.com  Fri Aug 27 08:05:59 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Fri, 27 Aug 2021 23:05:59 +0800
Subject: [PATCH v2 3/4] amba: Kill sysfs attribute file of irq
In-Reply-To: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
References: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
Message-ID: <20210827150600.78811-4-wangkefeng.wang@huawei.com>

As Rob said[1], there doesn't seem to be any users about the sysfs
attribute file of irq[0] and irq[1]. And we don't need to include
<asm/irq.h> as NO_IRQ has gone. Let's kill both of them.

[1] https://lkml.org/lkml/2021/8/25/461

Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 drivers/amba/bus.c | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 37fcd5592c6f..4d3a565ca079 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -20,8 +20,6 @@
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
-#include <asm/irq.h>
-
 #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
 
 /* called on periphid match and class 0x9 coresight device. */
@@ -135,8 +133,6 @@ static ssize_t name##_show(struct device *_dev,				\
 static DEVICE_ATTR_RO(name)
 
 amba_attr_func(id, "%08x\n", dev->periphid);
-amba_attr_func(irq0, "%u\n", dev->irq[0]);
-amba_attr_func(irq1, "%u\n", dev->irq[1]);
 amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
 	 (unsigned long long)dev->res.start, (unsigned long long)dev->res.end,
 	 dev->res.flags);
@@ -463,20 +459,10 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
 
  skip_probe:
 	ret = device_add(&dev->dev);
-	if (ret)
-		goto err_release;
-
-	if (dev->irq[0])
-		ret = device_create_file(&dev->dev, &dev_attr_irq0);
-	if (ret == 0 && dev->irq[1])
-		ret = device_create_file(&dev->dev, &dev_attr_irq1);
-	if (ret == 0)
-		return ret;
-
-	device_unregister(&dev->dev);
 
  err_release:
-	release_resource(&dev->res);
+	if (ret)
+		release_resource(&dev->res);
  err_out:
 	return ret;
 
-- 
2.18.0.huawei.25



From rocco.yue at mediatek.com  Fri Aug 27 08:04:12 2021
From: rocco.yue at mediatek.com (Rocco Yue)
Date: Fri, 27 Aug 2021 23:04:12 +0800
Subject: [PATCH net-next v6] ipv6: add IFLA_INET6_RA_MTU to expose mtu value
Message-ID: <20210827150412.9267-1-rocco.yue@mediatek.com>

The kernel provides a "/proc/sys/net/ipv6/conf/<iface>/mtu"
file, which can temporarily record the mtu value of the last
received RA message when the RA mtu value is lower than the
interface mtu, but this proc has following limitations:

(1) when the interface mtu (/sys/class/net/<iface>/mtu) is
updeated, mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) will
be updated to the value of interface mtu;
(2) mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) only affect
ipv6 connection, and not affect ipv4.

Therefore, when the mtu option is carried in the RA message,
there will be a problem that the user sometimes cannot obtain
RA mtu value correctly by reading mtu6.

After this patch set, if a RA message carries the mtu option,
you can send a netlink msg which nlmsg_type is RTM_GETLINK,
and then by parsing the attribute of IFLA_INET6_RA_MTU to
get the mtu value carried in the RA message received on the
inet6 device. In addition, you can also get a link notification
when ra_mtu is updated so it doesn't have to poll.

In this way, if the MTU values that the device receives from
the network in the PCO IPv4 and the RA IPv6 procedures are
different, the user can obtain the correct ipv6 ra_mtu value
and compare the value of ra_mtu and ipv4 mtu, then the device
can use the lower MTU value for both IPv4 and IPv6.

Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
---
 include/net/if_inet6.h             |  2 ++
 include/uapi/linux/if_link.h       |  1 +
 net/ipv6/addrconf.c                | 10 ++++++++++
 net/ipv6/ndisc.c                   | 17 +++++++++++------
 tools/include/uapi/linux/if_link.h |  1 +
 5 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 42235c178b06..653e7d0f65cb 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -210,6 +210,8 @@ struct inet6_dev {
 
 	unsigned long		tstamp; /* ipv6InterfaceTable update timestamp */
 	struct rcu_head		rcu;
+
+	unsigned int		ra_mtu;
 };
 
 static inline void ipv6_eth_mc_map(const struct in6_addr *addr, char *buf)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 8aad65b69054..eebd3894fe89 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -417,6 +417,7 @@ enum {
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
 	IFLA_INET6_TOKEN,	/* device token			*/
 	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	IFLA_INET6_RA_MTU,	/* mtu carried in the RA message */
 	__IFLA_INET6_MAX
 };
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 8381288a0d6e..17756f3ed33b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -394,6 +394,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
 		ndev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
 
 	ndev->cnf.mtu6 = dev->mtu;
+	ndev->ra_mtu = 0;
 	ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
 	if (!ndev->nd_parms) {
 		kfree(ndev);
@@ -3849,6 +3850,7 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister)
 	}
 
 	idev->tstamp = jiffies;
+	idev->ra_mtu = 0;
 
 	/* Last: Shot the device (if unregistered) */
 	if (unregister) {
@@ -5543,6 +5545,7 @@ static inline size_t inet6_ifla6_size(void)
 	     + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
 	     + nla_total_size(sizeof(struct in6_addr)) /* IFLA_INET6_TOKEN */
 	     + nla_total_size(1) /* IFLA_INET6_ADDR_GEN_MODE */
+	     + nla_total_size(4) /* IFLA_INET6_RA_MTU */
 	     + 0;
 }
 
@@ -5651,6 +5654,10 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
 	if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
 		goto nla_put_failure;
 
+	if (idev->ra_mtu &&
+	    nla_put_u32(skb, IFLA_INET6_RA_MTU, idev->ra_mtu))
+		goto nla_put_failure;
+
 	return 0;
 
 nla_put_failure:
@@ -5767,6 +5774,9 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token,
 static const struct nla_policy inet6_af_policy[IFLA_INET6_MAX + 1] = {
 	[IFLA_INET6_ADDR_GEN_MODE]	= { .type = NLA_U8 },
 	[IFLA_INET6_TOKEN]		= { .len = sizeof(struct in6_addr) },
+	[IFLA_INET6_RA_MTU]		= { .type = NLA_REJECT,
+					    .reject_message =
+						"IFLA_INET6_RA_MTU can not be set" },
 };
 
 static int check_addr_gen_mode(int mode)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c467c6419893..4b098521a44c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1391,12 +1391,6 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		}
 	}
 
-	/*
-	 *	Send a notify if RA changed managed/otherconf flags or timer settings
-	 */
-	if (send_ifinfo_notify)
-		inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
-
 skip_linkparms:
 
 	/*
@@ -1496,6 +1490,11 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
 		mtu = ntohl(n);
 
+		if (in6_dev->ra_mtu != mtu) {
+			in6_dev->ra_mtu = mtu;
+			send_ifinfo_notify = true;
+		}
+
 		if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
 			ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
 		} else if (in6_dev->cnf.mtu6 != mtu) {
@@ -1519,6 +1518,12 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		ND_PRINTK(2, warn, "RA: invalid RA options\n");
 	}
 out:
+	/* Send a notify if RA changed managed/otherconf flags or
+	 * timer settings or ra_mtu value
+	 */
+	if (send_ifinfo_notify)
+		inet6_ifinfo_notify(RTM_NEWLINK, in6_dev);
+
 	fib6_info_release(rt);
 	if (neigh)
 		neigh_release(neigh);
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
index eb15f319aa57..b3610fdd1fee 100644
--- a/tools/include/uapi/linux/if_link.h
+++ b/tools/include/uapi/linux/if_link.h
@@ -230,6 +230,7 @@ enum {
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
 	IFLA_INET6_TOKEN,	/* device token			*/
 	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	IFLA_INET6_RA_MTU,	/* mtu carried in the RA message */
 	__IFLA_INET6_MAX
 };
 
-- 
2.18.0

From linux at armlinux.org.uk  Fri Aug 27 08:09:39 2021
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 27 Aug 2021 16:09:39 +0100
Subject: arm scsi drivers
In-Reply-To: <9552a506-e53a-3fd3-b38e-3cec81e713a6@huawei.com>
References: <5a72842f-99db-8787-120b-6d85e7884e2d@huawei.com>
 <9552a506-e53a-3fd3-b38e-3cec81e713a6@huawei.com>
Message-ID: <20210827150938.GU22278@shell.armlinux.org.uk>

I haven't, sorry.

I have run 5.x kernels on the hardware, and do have a set of patches
kicking around for the SCSI drivers that do some cleanups. It looks
like the fixup is pretty simple from the links you've sent - using
scsi_cmd_to_rq() to get the tag.

That said, I think I may only had one SCSI drive that came anywhere
close to supported tagged queuing, so I never put much effort into
tagged command support. Both acornscsi and fas216 have it disabled
for this reason, so it's probably easier just to rip the tag code
out of these drivers.

Russell.

On Fri, Aug 27, 2021 at 03:55:05PM +0100, John Garry wrote:
> Hi Russell,
> 
> Have you had a chance to consider the below?
> 
> Thanks
> 
> 
> > 
> > Recently we tried to remove scsi_cmnd.tags struct member [0].
> > 
> > However it now shows that some of the arm SCSI drivers continue to use
> > this [1]. I think any other driver usage of this member had been found
> > and removed.
> > 
> > The impression is that the usage of scsi_cmnd.tag in those drivers is
> > quite dubious.
> > 
> > Now checking [2], it appears that you may have had some patches for
> > these drivers locally.
> > 
> > So is that the case? Is this HW still used with bleeding edge kernels?
> > If so, can we fix up this tag management?
> > 
> > [0] https://lore.kernel.org/linux-scsi/6c83bd7f-9fd2-1b43-627f-615467fa55d4 at huawei.com/T/#mb47909f38f35837686734369600051b278d124af
> > 
> > 
> > [1] https://lore.kernel.org/linux-scsi/6c83bd7f-9fd2-1b43-627f-615467fa55d4 at huawei.com/T/#md5d786e5753083b2f3e8e761b1c69809f82c7485
> > 
> > 
> > [2]
> > https://lore.kernel.org/lkml/20210109174357.GB1551 at shell.armlinux.org.uk/
> > 
> > Thanks,
> > John
> 
> 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From seanjc at google.com  Fri Aug 27 08:22:33 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 15:22:33 +0000
Subject: [PATCH 05/15] perf: Track guest callbacks on a per-CPU basis
In-Reply-To: <YSj9LQfbKxOhxqcP@hirez.programming.kicks-ass.net>
References: <20210827005718.585190-1-seanjc@google.com>
 <20210827005718.585190-6-seanjc@google.com>
 <YSiRBQQE7md7ZrNC@hirez.programming.kicks-ass.net>
 <YSj7jq32U8Euf38o@google.com>
 <YSj9LQfbKxOhxqcP@hirez.programming.kicks-ass.net>
Message-ID: <YSkDOWze5dBHkJnA@google.com>

On Fri, Aug 27, 2021, Peter Zijlstra wrote:
> On Fri, Aug 27, 2021 at 02:49:50PM +0000, Sean Christopherson wrote:
> > On Fri, Aug 27, 2021, Peter Zijlstra wrote:
> > > On Thu, Aug 26, 2021 at 05:57:08PM -0700, Sean Christopherson wrote:
> > > > Use a per-CPU pointer to track perf's guest callbacks so that KVM can set
> > > > the callbacks more precisely and avoid a lurking NULL pointer dereference.
> > > 
> > > I'm completely failing to see how per-cpu helps anything here...
> > 
> > It doesn't help until KVM is converted to set the per-cpu pointer in flows that
> > are protected against preemption, and more specifically when KVM only writes to
> > the pointer from the owning CPU.  
> 
> So the 'problem' I have with this is that sane (!KVM using) people, will
> still have to suffer that load, whereas with the static_call() we patch
> in an 'xor %rax,%rax' and only have immediate code flow.

Again, I've no objection to the static_call() approach.  I didn't even see the
patch until I had finished testing my series :-/

> > Ignoring static call for the moment, I don't see how the unreg side can be safe
> > using a bare single global pointer.  There is no way for KVM to prevent an NMI
> > from running in parallel on a different CPU.  If there's a more elegant solution,
> > especially something that can be backported, e.g. an rcu-protected pointer, I'm
> > all for it.  I went down the per-cpu path because it allowed for cleanups in KVM,
> > but similar cleanups can be done without per-cpu perf callbacks.
> 
> If all the perf_guest_cbs dereferences are with preemption disabled
> (IRQs disabled, IRQ context, NMI context included), then the sequence:
> 
> 	WRITE_ONCE(perf_guest_cbs, NULL);
> 	synchronize_rcu();
> 
> Ensures that all prior observers of perf_guest_csb will have completed
> and future observes must observe the NULL value.

That alone won't be sufficient, as the read side also needs to ensure it doesn't
reload perf_guest_cbs between NULL checks and dereferences.  But that's easy
enough to solve with a READ_ONCE and maybe a helper to make it more cumbersome
to use perf_guest_cbs directly.

How about this for a series?

  1. Use READ_ONCE/WRITE_ONCE + synchronize_rcu() to fix the underlying bug
  2. Fix KVM PT interrupt handler bug
  3. Kill off perf_guest_cbs usage in architectures that don't need the callbacks
  4. Replace ->is_in_guest()/->is_user_mode() with ->state(), and s/get_guest_ip/get_ip
  5. Implement static_call() support
  6. Cleanups, if there are any
  6..N KVM cleanups, e.g. to eliminate current_vcpu and share x86+arm64 callbacks


From hare at suse.de  Fri Aug 27 08:23:50 2021
From: hare at suse.de (Hannes Reinecke)
Date: Fri, 27 Aug 2021 17:23:50 +0200
Subject: arm scsi drivers
In-Reply-To: <20210827150938.GU22278@shell.armlinux.org.uk>
References: <5a72842f-99db-8787-120b-6d85e7884e2d@huawei.com>
 <9552a506-e53a-3fd3-b38e-3cec81e713a6@huawei.com>
 <20210827150938.GU22278@shell.armlinux.org.uk>
Message-ID: <087d1fa0-8796-5b97-36fc-379498f53380@suse.de>

On 8/27/21 5:09 PM, Russell King (Oracle) wrote:
> I haven't, sorry.
> 
> I have run 5.x kernels on the hardware, and do have a set of patches
> kicking around for the SCSI drivers that do some cleanups. It looks
> like the fixup is pretty simple from the links you've sent - using
> scsi_cmd_to_rq() to get the tag.
> 
> That said, I think I may only had one SCSI drive that came anywhere
> close to supported tagged queuing, so I never put much effort into
> tagged command support. Both acornscsi and fas216 have it disabled
> for this reason, so it's probably easier just to rip the tag code
> out of these drivers.
> 
That's what I figured, too.
And that's what my patches do, killing the tag support from arm drivers 
which had them disabled since the dawn of git history.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke                Kernel Storage Architect
hare at suse.de                              +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 N?rnberg
HRB 36809 (AG N?rnberg), Gesch?ftsf?hrer: Felix Imend?rffer


From stefan.wahren at i2se.com  Fri Aug 27 08:33:21 2021
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Fri, 27 Aug 2021 17:33:21 +0200
Subject: [PATCH v1 2/7] ARM: imx_v6_v7_defconfig: enable fb
In-Reply-To: <CAOMZO5B9Tb+1d1eU1huCZKNH6BjdnmvBUnkY_242L1yub=2Q9g@mail.gmail.com>
References: <20210819140345.357167-1-marcel@ziswiler.com>
 <20210819140345.357167-3-marcel@ziswiler.com>
 <CAOMZO5B9Tb+1d1eU1huCZKNH6BjdnmvBUnkY_242L1yub=2Q9g@mail.gmail.com>
Message-ID: <4eafec9e-cb67-8194-9219-cc6d7df99fdd@i2se.com>

Hi,

Am 26.08.21 um 21:03 schrieb Fabio Estevam:
> Hi Marcel,
>
> On Thu, Aug 19, 2021 at 11:04 AM Marcel Ziswiler <marcel at ziswiler.com> wrote:
>> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>>
>> Enable CONFIG_FB which is nowadays required for CONFIG_DRM_PANEL_LVDS,
>> CONFIG_DRM_PANEL_SIMPLE, CONFIG_DRM_PANEL_SEIKO_43WVF1G,
>> CONFIG_FB_MODE_HELPERS, CONFIG_BACKLIGHT_PWM, CONFIG_BACKLIGHT_GPIO,
>> CONFIG_FRAMEBUFFER_CONSOLE, CONFIG_LOGO, CONFIG_FONTS, CONFIG_FONT_8x8
>> and CONFIG_FONT_8x16.
>>
>> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> Yes, I noticed that I had no LCD output on an imx6ull-evk board and
> after selecting CONFIG_FB it works again.

this was caused by:

f611b1e7624c ("drm: Avoid circular dependencies for CONFIG_FB")

Best regards

>
> For the entire series:
>
> Reviewed-by: Fabio Estevam <festevam at gmail.com>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From dan.j.williams at intel.com  Fri Aug 27 09:24:49 2021
From: dan.j.williams at intel.com (Dan Williams)
Date: Fri, 27 Aug 2021 09:24:49 -0700
Subject: [PATCH v2 07/15] peci: Add peci-aspeed controller driver
In-Reply-To: <b26ee278838698289869964fe59578f0d5f7b19c.camel@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-8-iwona.winiarska@intel.com>
 <CAPcyv4jPVSt9Wr2TkDActFVLP+ygaDwBnsKG410Nf1qfP_MB9A@mail.gmail.com>
 <b26ee278838698289869964fe59578f0d5f7b19c.camel@intel.com>
Message-ID: <CAPcyv4hUm0Ec1+_n0PZ+S0A9Tt1=8oLdeYtEiEnAmntm8PtmKQ@mail.gmail.com>

On Thu, Aug 26, 2021 at 4:55 PM Winiarska, Iwona
<iwona.winiarska at intel.com> wrote:
>
> On Wed, 2021-08-25 at 18:35 -0700, Dan Williams wrote:
> > On Tue, Aug 3, 2021 at 4:35 AM Iwona Winiarska
> > <iwona.winiarska at intel.com> wrote:
> > >
> > > From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > >
> > > ASPEED AST24xx/AST25xx/AST26xx SoCs supports the PECI electrical
> > > interface (a.k.a PECI wire).
> >
> > Maybe a one sentence blurb here and in the Kconfig reminding people
> > why they should care if they have a PECI driver or not?
>
> Ok, I'll expand it a bit.
[..]
> > > +static int aspeed_peci_xfer(struct peci_controller *controller,
> > > +                           u8 addr, struct peci_request *req)
> > > +{
> > > +       struct aspeed_peci *priv = dev_get_drvdata(controller->dev.parent);
> > > +       unsigned long flags, timeout = msecs_to_jiffies(priv-
> > > >cmd_timeout_ms);
> > > +       u32 peci_head;
> > > +       int ret;
> > > +
> > > +       if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
> > > +           req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
> > > +               return -EINVAL;
> > > +
> > > +       /* Check command sts and bus idle state */
> > > +       ret = aspeed_peci_check_idle(priv);
> > > +       if (ret)
> > > +               return ret; /* -ETIMEDOUT */
> > > +
> > > +       spin_lock_irqsave(&priv->lock, flags);
> > > +       reinit_completion(&priv->xfer_complete);
> > > +
> > > +       peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
> > > +                   FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
> > > +                   FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
> > > +
> > > +       writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
> > > +
> > > +       memcpy_toio(priv->base + ASPEED_PECI_WR_DATA0, req->tx.buf,
> > > min_t(u8, req->tx.len, 16));
> > > +       if (req->tx.len > 16)
> > > +               memcpy_toio(priv->base + ASPEED_PECI_WR_DATA4, req->tx.buf +
> > > 16,
> > > +                           req->tx.len - 16);
> > > +
> > > +       dev_dbg(priv->dev, "HEAD : 0x%08x\n", peci_head);
> > > +       print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf, req-
> > > >tx.len);
> >
> > On CONFIG_DYNAMIC_DEBUG=n builds the kernel will do all the work of
> > reading through this buffer, but skip emitting it. Are you sure you
> > want to pay that overhead for every transaction?
>
> I can remove it or I can add something like:
>
> #if IS_ENABLED(CONFIG_PECI_DEBUG)
> #define peci_debug(fmt, ...) pr_debug(fmt, ##__VA_ARGS__)
> #else
> #define peci_debug(...) do { } while (0)
> #endif

It's the hex dump I'm worried about, not the debug statements as much.

I think the choices are remove the print_hex_dump_bytes(), put it
behind an IS_ENABLED(CONFIG_DYNAMIC_DEBUG) to ensure the overhead is
skipped in the CONFIG_DYNAMIC_DEBUG=n case, or live with the overhead
if this is not a fast path / infrequently used.

>
> (and similar peci_trace with trace_printk for usage in IRQ handlers and such).
>
> What do you think?

In general, no, don't wrap the base level print routines with
driver-specific ones. Also, trace_printk() is only for debug builds.
Note that trace points are built to be even less overhead than
dev_dbg(), so there's no overhead concern with disabled tracepoints,
they literally translate to nops when disabled.

>
> >
> > > +
> > > +       priv->status = 0;
> > > +       writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
> > > +       spin_unlock_irqrestore(&priv->lock, flags);
> > > +
> > > +       ret = wait_for_completion_interruptible_timeout(&priv-
> > > >xfer_complete, timeout);
> >
> > spin_lock_irqsave() says "I don't know if interrupts are disabled
> > already, so I'll save the state, whatever it is, and restore later"
> >
> > wait_for_completion_interruptible_timeout() says "I know I am in a
> > sleepable context where interrupts are enabled"
> >
> > So, one of those is wrong, i.e. should it be spin_{lock,unlock}_irq()?
>
> You're right - I'll fix it.
>
> >
> >
> > > +       if (ret < 0)
> > > +               return ret;
> > > +
> > > +       if (ret == 0) {
> > > +               dev_dbg(priv->dev, "Timeout waiting for a response!\n");
> > > +               return -ETIMEDOUT;
> > > +       }
> > > +
> > > +       spin_lock_irqsave(&priv->lock, flags);
> > > +
> > > +       writel(0, priv->base + ASPEED_PECI_CMD);
> > > +
> > > +       if (priv->status != ASPEED_PECI_INT_CMD_DONE) {
> > > +               spin_unlock_irqrestore(&priv->lock, flags);
> > > +               dev_dbg(priv->dev, "No valid response!\n");
> > > +               return -EIO;
> > > +       }
> > > +
> > > +       spin_unlock_irqrestore(&priv->lock, flags);
> > > +
> > > +       memcpy_fromio(req->rx.buf, priv->base + ASPEED_PECI_RD_DATA0,
> > > min_t(u8, req->rx.len, 16));
> > > +       if (req->rx.len > 16)
> > > +               memcpy_fromio(req->rx.buf + 16, priv->base +
> > > ASPEED_PECI_RD_DATA4,
> > > +                             req->rx.len - 16);
> > > +
> > > +       print_hex_dump_bytes("RX : ", DUMP_PREFIX_NONE, req->rx.buf, req-
> > > >rx.len);
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
> > > +{
> > > +       struct aspeed_peci *priv = arg;
> > > +       u32 status;
> > > +
> > > +       spin_lock(&priv->lock);
> > > +       status = readl(priv->base + ASPEED_PECI_INT_STS);
> > > +       writel(status, priv->base + ASPEED_PECI_INT_STS);
> > > +       priv->status |= (status & ASPEED_PECI_INT_MASK);
> > > +
> > > +       /*
> > > +        * In most cases, interrupt bits will be set one by one but also
> > > note
> > > +        * that multiple interrupt bits could be set at the same time.
> > > +        */
> > > +       if (status & ASPEED_PECI_INT_BUS_TIMEOUT)
> > > +               dev_dbg_ratelimited(priv->dev,
> > > "ASPEED_PECI_INT_BUS_TIMEOUT\n");
> > > +
> > > +       if (status & ASPEED_PECI_INT_BUS_CONTENTION)
> > > +               dev_dbg_ratelimited(priv->dev,
> > > "ASPEED_PECI_INT_BUS_CONTENTION\n");
> > > +
> > > +       if (status & ASPEED_PECI_INT_WR_FCS_BAD)
> > > +               dev_dbg_ratelimited(priv->dev,
> > > "ASPEED_PECI_INT_WR_FCS_BAD\n");
> > > +
> > > +       if (status & ASPEED_PECI_INT_WR_FCS_ABORT)
> > > +               dev_dbg_ratelimited(priv->dev,
> > > "ASPEED_PECI_INT_WR_FCS_ABORT\n");
> >
> > Are you sure these would not be better as tracepoints? If you're
> > debugging an interrupt related failure, the ratelimiting might get in
> > your way when you really need to know when one of these error
> > interrupts fire relative to another event.
>
> Tracepoints are ABI(ish), and using a full blown tracepoint just for IRQ status
> would probably be too much.

Tracepoints become ABI once someone ships tooling that depends on them
being there. These don't look  attractive for a tool, and they don't
look difficult to maintain if the interrupt handler needs to be
reworked. I.e. it would be trivial to keep a dead tracepoint around if
worse came to worse to keep a tool from failing to load.

> I was thinking about something like trace_printk hidden under a
> "CONFIG_PECI_DEBUG" (see above), but perhaps that's something for the future
> improvement?

Again trace_printk() is only for private builds.

>
> >
> > > +
> > > +       /*
> > > +        * All commands should be ended up with a ASPEED_PECI_INT_CMD_DONE
> > > bit
> > > +        * set even in an error case.
> > > +        */
> > > +       if (status & ASPEED_PECI_INT_CMD_DONE)
> > > +               complete(&priv->xfer_complete);
> >
> > Hmm, no need to check if there was a sequencing error, like a command
> > was never submitted?
>
> It's handled by checking if HW is idle in xfer before a command is sent, where
> we just expect a single interrupt per command.

I'm asking how do you determine if this status was spurious, or there
was a sequencing error in the driver?


From sean.anderson at seco.com  Fri Aug 27 09:29:40 2021
From: sean.anderson at seco.com (Sean Anderson)
Date: Fri, 27 Aug 2021 12:29:40 -0400
Subject: [PATCH v6 3/3] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <202108271550.btqnrtGU-lkp@intel.com>
References: <20210826211830.3311140-3-sean.anderson@seco.com>
 <202108271550.btqnrtGU-lkp@intel.com>
Message-ID: <c57c4b16-dc8c-76c7-3ac4-63a5b62144d3@seco.com>



On 8/27/21 3:16 AM, kernel test robot wrote:
> Hi Sean,
> 
> I love your patch! Perhaps something to improve:
> 
> [auto build test WARNING on tip/timers/core]
> [also build test WARNING on pwm/for-next linus/master v5.14-rc7 next-20210826]
> [cannot apply to xlnx/master]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:    https://github.com/0day-ci/linux/commits/Sean-Anderson/dt-bindings-pwm-Add-Xilinx-AXI-Timer/20210827-052011
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 127c92feb74a6721f62587f1b89128808f049cf1
> config: mips-randconfig-r025-20210827 (attached as .config)
> compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 1076082a0d97bd5c16a25ee7cf3dbb6ee4b5a9fe)
> reproduce (this is a W=1 build):
>          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>          chmod +x ~/bin/make.cross
>          # install mips cross compiling tool for clang build
>          # apt-get install binutils-mips-linux-gnu
>          # https://github.com/0day-ci/linux/commit/eab56f0b0c5a62e40c04916eb1b4f21f478cec3a
>          git remote add linux-review https://github.com/0day-ci/linux
>          git fetch --no-tags linux-review Sean-Anderson/dt-bindings-pwm-Add-Xilinx-AXI-Timer/20210827-052011
>          git checkout eab56f0b0c5a62e40c04916eb1b4f21f478cec3a
>          # save the attached .config to linux build tree
>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=mips
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp at intel.com>
> 
> All warnings (new ones prefixed by >>):
> 
>>> drivers/pwm/pwm-xilinx.c:249:34: warning: unused variable 'xilinx_timer_of_match' [-Wunused-const-variable]
>     static const struct of_device_id xilinx_timer_of_match[] = {
>                                      ^
>     1 warning generated.
> 
> 
> vim +/xilinx_timer_of_match +249 drivers/pwm/pwm-xilinx.c
> 
>     248	
>   > 249	static const struct of_device_id xilinx_timer_of_match[] = {
>     250		{ .compatible = "xlnx,xps-timer-1.00.a", },
>     251		{},
>     252	};
>     253	MODULE_DEVICE_TABLE(of, xilinx_timer_of_match);
>     254	

For this and the error on the previous patch it looks like I am missing a dependency on OF_ADDR. Will add.

--Sean


From dsahern at gmail.com  Fri Aug 27 09:41:53 2021
From: dsahern at gmail.com (David Ahern)
Date: Fri, 27 Aug 2021 09:41:53 -0700
Subject: [PATCH net-next v6] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value
In-Reply-To: <20210827150412.9267-1-rocco.yue@mediatek.com>
References: <20210827150412.9267-1-rocco.yue@mediatek.com>
Message-ID: <88523c38-f0b4-8a63-6ca6-68a3122bef79@gmail.com>

On 8/27/21 8:04 AM, Rocco Yue wrote:
> The kernel provides a "/proc/sys/net/ipv6/conf/<iface>/mtu"
> file, which can temporarily record the mtu value of the last
> received RA message when the RA mtu value is lower than the
> interface mtu, but this proc has following limitations:
> 
> (1) when the interface mtu (/sys/class/net/<iface>/mtu) is
> updeated, mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) will
> be updated to the value of interface mtu;
> (2) mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) only affect
> ipv6 connection, and not affect ipv4.
> 
> Therefore, when the mtu option is carried in the RA message,
> there will be a problem that the user sometimes cannot obtain
> RA mtu value correctly by reading mtu6.
> 
> After this patch set, if a RA message carries the mtu option,
> you can send a netlink msg which nlmsg_type is RTM_GETLINK,
> and then by parsing the attribute of IFLA_INET6_RA_MTU to
> get the mtu value carried in the RA message received on the
> inet6 device. In addition, you can also get a link notification
> when ra_mtu is updated so it doesn't have to poll.
> 
> In this way, if the MTU values that the device receives from
> the network in the PCO IPv4 and the RA IPv6 procedures are
> different, the user can obtain the correct ipv6 ra_mtu value
> and compare the value of ra_mtu and ipv4 mtu, then the device
> can use the lower MTU value for both IPv4 and IPv6.
> 
> Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
> ---
>  include/net/if_inet6.h             |  2 ++
>  include/uapi/linux/if_link.h       |  1 +
>  net/ipv6/addrconf.c                | 10 ++++++++++
>  net/ipv6/ndisc.c                   | 17 +++++++++++------
>  tools/include/uapi/linux/if_link.h |  1 +
>  5 files changed, 25 insertions(+), 6 deletions(-)
> 

Reviewed-by: David Ahern <dsahern at kernel.org>




From helgaas at kernel.org  Fri Aug 27 09:46:34 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 27 Aug 2021 11:46:34 -0500
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared
 pcie-cfg base address
In-Reply-To: <20210823032800.1660-3-chuanjia.liu@mediatek.com>
Message-ID: <20210827164634.GA3779223@bjorn-Precision-5520>

On Mon, Aug 23, 2021 at 11:27:56AM +0800, Chuanjia Liu wrote:
> For the new dts format, add a new method to get
> shared pcie-cfg base address and use it to configure
> the PCIECFG controller

Rewrap this to fill 75 columns.

> Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> ---
>  drivers/pci/controller/pcie-mediatek.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> index 25bee693834f..4296d9e04240 100644
> --- a/drivers/pci/controller/pcie-mediatek.c
> +++ b/drivers/pci/controller/pcie-mediatek.c
> @@ -14,6 +14,7 @@
>  #include <linux/irqchip/chained_irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/msi.h>
>  #include <linux/module.h>
>  #include <linux/of_address.h>
> @@ -23,6 +24,7 @@
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
>  #include <linux/reset.h>
>  
>  #include "../pci.h"
> @@ -207,6 +209,7 @@ struct mtk_pcie_port {
>   * struct mtk_pcie - PCIe host information
>   * @dev: pointer to PCIe device
>   * @base: IO mapped register base
> + * @cfg: IO mapped register map for PCIe config
>   * @free_ck: free-run reference clock
>   * @mem: non-prefetchable memory resource
>   * @ports: pointer to PCIe port information
> @@ -215,6 +218,7 @@ struct mtk_pcie_port {
>  struct mtk_pcie {
>  	struct device *dev;
>  	void __iomem *base;
> +	struct regmap *cfg;
>  	struct clk *free_ck;
>  
>  	struct list_head ports;
> @@ -682,6 +686,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
>  		val |= PCIE_CSR_LTSSM_EN(port->slot) |
>  		       PCIE_CSR_ASPM_L1_EN(port->slot);
>  		writel(val, pcie->base + PCIE_SYS_CFG_V2);
> +	} else if (pcie->cfg) {
> +		val = PCIE_CSR_LTSSM_EN(port->slot) |
> +		      PCIE_CSR_ASPM_L1_EN(port->slot);
> +		regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
>  	}
>  
>  	/* Assert all reset signals */
> @@ -985,6 +993,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct resource *regs;
> +	struct device_node *cfg_node;
>  	int err;
>  
>  	/* get shared registers, which are optional */
> @@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
>  			return PTR_ERR(pcie->base);
>  	}
>  
> +	cfg_node = of_find_compatible_node(NULL, NULL,
> +					   "mediatek,generic-pciecfg");

This looks wrong to me.  IIUC, since we start at NULL, this searches
the entire device tree for any node with

  compatible = "mediatek,generic-pciecfg"

but we should only care about the specific device/node this driver
claimed.

Should this be part of the match data, i.e., struct mtk_pcie_soc?

> +	if (cfg_node) {
> +		pcie->cfg = syscon_node_to_regmap(cfg_node);

Other drivers in drivers/pci/controller/ use
syscon_regmap_lookup_by_phandle() (j721e, dra7xx, keystone,
layerscape, artpec6) or syscon_regmap_lookup_by_compatible() (imx6,
kirin, v3-semi).

You should do it the same way unless there's a need to be different.
It's also nice if you can use the same struct member name
("mtk_pcie.cfg") as other drivers.  They're not all consistent, but I
don't see any other "cfg".

> +		if (IS_ERR(pcie->cfg))
> +			return PTR_ERR(pcie->cfg);
> +	}
> +
>  	pcie->free_ck = devm_clk_get(dev, "free_ck");
>  	if (IS_ERR(pcie->free_ck)) {
>  		if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
> -- 
> 2.18.0
> 


From torvalds at linux-foundation.org  Fri Aug 27 10:03:29 2021
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Fri, 27 Aug 2021 10:03:29 -0700
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <20210827074041.GA24309@lst.de>
References: <20210826131747.GE26318@willie-the-truck>
 <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>
 <20210827074041.GA24309@lst.de>
Message-ID: <CAHk-=wjd28sN9khO=1j6zmBk+2n4_e+SY1URjW9hzsHSAZU+7Q@mail.gmail.com>

On Fri, Aug 27, 2021 at 12:40 AM Christoph Hellwig <hch at lst.de> wrote:
>
> > In a PC world that would be (for example) the legacy PCI space at
> > 0xa0000-0xfffff, but I could easily imagine other platforms having
> > other situations.
>
> So what would be the correct check for "this is not actually page backed
> normal RAM"?

It would probably be interesting to have the arm people explain the
call chain for the warning that caused that revert, so we'd have a
very concrete example of the situation that goes wrong, but taking a
wild stab at it, the code might be something like

            /* Don't allow RAM to be mapped */
            if (WARN_ON_ONCE(phys_addr_is_ram(phys_addr)))
                    return DMA_MAPPING_ERROR;

and then having something like

  static inline bool phys_addr_is_ram(phys_addr_t phys_addr)
  {
        unsigned long pfn = PHYS_PFN(phys_addr);

        if (!pfn_valid(pfn))
                return false;
        return is_zero_pfn(pfn) || !PageReserved(pfn_to_page(pfn));
  }

might be close to right.

The ARM code actually uses that complex pfn_to_section_nr() and
memblock_is_memory() etc. That seems a bit of an overkill, since the
memblock code should have translated all that into being reserved.

But again, I don't actually know exactly what triggered the issue on
ARM, so the above is just my "this seems to be a more proper check"
suggestion.

Will?

                   Linus


From hch at lst.de  Fri Aug 27 10:10:41 2021
From: hch at lst.de (Christoph Hellwig)
Date: Fri, 27 Aug 2021 19:10:41 +0200
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <CAHk-=wjd28sN9khO=1j6zmBk+2n4_e+SY1URjW9hzsHSAZU+7Q@mail.gmail.com>
References: <20210826131747.GE26318@willie-the-truck>
 <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>
 <20210827074041.GA24309@lst.de>
 <CAHk-=wjd28sN9khO=1j6zmBk+2n4_e+SY1URjW9hzsHSAZU+7Q@mail.gmail.com>
Message-ID: <20210827171041.GA28149@lst.de>

On Fri, Aug 27, 2021 at 10:03:29AM -0700, Linus Torvalds wrote:
> The ARM code actually uses that complex pfn_to_section_nr() and
> memblock_is_memory() etc. That seems a bit of an overkill, since the
> memblock code should have translated all that into being reserved.
> 
> But again, I don't actually know exactly what triggered the issue on
> ARM, so the above is just my "this seems to be a more proper check"
> suggestion.

They CCed me on their earlier discussion, but I did not catch up on it
until you responded to the pull request  If I understood it correct it
was about a platform device mapping a MMIO region (like a PCI bar),
but something about section alignment cause pfn_valid to mistrigger.


From mark.kettenis at xs4all.nl  Fri Aug 27 10:15:25 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 27 Aug 2021 19:15:25 +0200
Subject: [PATCH v4 0/4] Apple M1 PCIe DT bindings
Message-ID: <20210827171534.62380-1-mark.kettenis@xs4all.nl>

From: Mark Kettenis <kettenis at openbsd.org>

This small series adds bindings for the PCIe controller found on the
Apple M1 SoC.

At this point, the primary consumer for these bindings is U-Boot.
With these bindings U-Boot can bring up the links for the root ports
of the PCIe root complex.  A simple OS driver can then provide
standard ECAM access and manage MSI interrupts to provide access
to the built-in Ethernet and XHCI controllers of the Mac mini.

The Apple controller incorporates Synopsys Designware PCIe logic
to implement its root port.  But unlike other hardware currently
supported by U-Boot and the Linux kernel the Apple hardware
integrates multiple root ports.  As such the existing bindings
for the DWC PCIe interface can't be used.  There is a single ECAM
space for all root space, but separate GPIOs to take the PCI devices
on those ports out of reset.  Therefore the standard "reset-gpio" and
"max-link-speed" properties appear on the child nodes representing
the PCI devices that correspond to the individual root ports.

MSIs are handled by the PCIe controller and translated into "regular
interrupts".  A range of 32 MSIs is provided.  These 32 MSIs can be
distributed over the root ports as the OS sees fit by programming the
PCIe controller port registers.

This now adds an MSI controller binding schema and uses the generic
msi-ranges property to specify how the MSIs are mapped to interrupts
on the AIC.  I copied some of the description text in the MSI
controller binding schema from msi.txt but it may need some further
tweaks to make sense.

Patch 2/2 of this series depends on the pinctrl series I sent earlier
and will probably go through Hector Martin's Apple M1 SoC tree.


Changelog:

v4: - Convert MSI controller binding to YAML
    - Add generic msi-ranges property to MSI controller binding
    - Fix typos/formatting in apple,pcie binding
    - Use generic MSI controller binding in apple,pcie

v3: - Remove unneeded include in example

v2: - Adjust name for ECAM in "reg-names"
    - Drop "phy" registers
    - Expand description
    - Add description for "interrupts"
    - Fix incorrect minItems for "interrupts"
    - Fix incorrect MaxItems for "reg-names"
    - Document the use of "msi-controller", "msi-parent", "iommu-map" and
      "iommu-map-mask"
    - Fix "bus-range" and "iommu-map" properties in the example

Mark Kettenis (4):
  dt-bindings: interrupt-controller: Convert MSI controller to
    json-schema
  dt-bindings: interrupt-controller: msi: Add msi-ranges property
  dt-bindings: pci: Add DT bindings for apple,pcie
  arm64: apple: Add PCIe node

 .../interrupt-controller/msi-controller.yaml  |  42 +++++
 .../devicetree/bindings/pci/apple,pcie.yaml   | 165 ++++++++++++++++++
 .../bindings/pci/brcm,stb-pcie.yaml           |   1 +
 .../bindings/pci/microchip,pcie-host.yaml     |   1 +
 MAINTAINERS                                   |   1 +
 arch/arm64/boot/dts/apple/t8103.dtsi          |  63 +++++++
 6 files changed, 273 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
 create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml

-- 
2.32.0



From mark.kettenis at xs4all.nl  Fri Aug 27 10:15:26 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 27 Aug 2021 19:15:26 +0200
Subject: [PATCH v4 1/4] dt-bindings: interrupt-controller: Convert MSI
 controller to json-schema
In-Reply-To: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
Message-ID: <20210827171534.62380-2-mark.kettenis@xs4all.nl>

From: Mark Kettenis <kettenis at openbsd.org>

Split the MSI controller bindings from the MSI binding document
into DT schema format using json-schema.

Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
---
 .../interrupt-controller/msi-controller.yaml  | 34 +++++++++++++++++++
 .../bindings/pci/brcm,stb-pcie.yaml           |  1 +
 .../bindings/pci/microchip,pcie-host.yaml     |  1 +
 3 files changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
new file mode 100644
index 000000000000..5ed6cd46e2e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/msi-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MSI controller
+
+maintainers:
+  - Marc Zyngier <marc.zyngier at arm.com>
+
+description: |
+  An MSI controller signals interrupts to a CPU when a write is made
+  to an MMIO address by some master. An MSI controller may feature a
+  number of doorbells.
+
+properties:
+  "#msi-cells":
+    description: |
+      The number of cells in an msi-specifier, required if not zero.
+
+      Typically this will encode information related to sideband data,
+      and will not encode doorbells or payloads as these can be
+      configured dynamically.
+
+      The meaning of the msi-specifier is defined by the device tree
+      binding of the specific MSI controller.
+
+  msi-controller:
+    description:
+      Identifies the node as an MSI controller.
+    $ref: /schemas/types.yaml#/definitions/flag
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
index b9589a0daa5c..5c67976a8dc2 100644
--- a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
@@ -88,6 +88,7 @@ required:
 
 allOf:
   - $ref: /schemas/pci/pci-bus.yaml#
+  - $ref: ../interrupt-controller/msi-controller.yaml#
   - if:
       properties:
         compatible:
diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
index fb95c276a986..684d9d036f48 100644
--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
+++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
@@ -11,6 +11,7 @@ maintainers:
 
 allOf:
   - $ref: /schemas/pci/pci-bus.yaml#
+  - $ref: ../interrupt-controller/msi-controller.yaml#
 
 properties:
   compatible:
-- 
2.32.0



From mark.kettenis at xs4all.nl  Fri Aug 27 10:15:27 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 27 Aug 2021 19:15:27 +0200
Subject: [PATCH v4 2/4] dt-bindings: interrupt-controller: msi: Add msi-ranges
 property
In-Reply-To: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
Message-ID: <20210827171534.62380-3-mark.kettenis@xs4all.nl>

From: Mark Kettenis <kettenis at openbsd.org>

Update the MSI controller binding to add an msi-ranges property
that specifies how MSIs map onto regular interrupts on some other
interrupt controller.

Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
---
 .../bindings/interrupt-controller/msi-controller.yaml     | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
index 5ed6cd46e2e0..bf8b8a7dba09 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
@@ -31,4 +31,12 @@ properties:
       Identifies the node as an MSI controller.
     $ref: /schemas/types.yaml#/definitions/flag
 
+  msi-ranges:
+    description:
+      A list of pairs <intid span>, where "intid" is the specification
+      of the first interrupt (including the phandle for the interrupt
+      controller) that can be used as an MSI, and "span" the size of
+      that range. Multiple ranges can be provided.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
 additionalProperties: true
-- 
2.32.0



From mark.kettenis at xs4all.nl  Fri Aug 27 10:15:28 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 27 Aug 2021 19:15:28 +0200
Subject: [PATCH v4 3/4] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
Message-ID: <20210827171534.62380-4-mark.kettenis@xs4all.nl>

From: Mark Kettenis <kettenis at openbsd.org>

The Apple PCIe host controller is a PCIe host controller with
multiple root ports present in Apple ARM SoC platforms, including
various iPhone and iPad devices and the "Apple Silicon" Macs.

Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
---
 .../devicetree/bindings/pci/apple,pcie.yaml   | 165 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 2 files changed, 166 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
new file mode 100644
index 000000000000..97a126db935a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
@@ -0,0 +1,165 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple PCIe host controller
+
+maintainers:
+  - Mark Kettenis <kettenis at openbsd.org>
+
+description: |
+  The Apple PCIe host controller is a PCIe host controller with
+  multiple root ports present in Apple ARM SoC platforms, including
+  various iPhone and iPad devices and the "Apple Silicon" Macs.
+  The controller incorporates Synopsys DesigWare PCIe logic to
+  implements its root ports.  But the ATU found on most DesignWare
+  PCIe host bridges is absent.
+
+  All root ports share a single ECAM space, but separate GPIOs are
+  used to take the PCI devices on those ports out of reset.  Therefore
+  the standard "reset-gpios" and "max-link-speed" properties appear on
+  the child nodes that represent the PCI bridges that correspond to
+  the individual root ports.
+
+  MSIs are handled by the PCIe controller and translated into regular
+  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
+  distributed over the root ports as the OS sees fit by programming
+  the PCIe controller's port registers.
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+  - $ref: ../interrupt-controller/msi-controller.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: apple,t8103-pcie
+      - const: apple,pcie
+
+  reg:
+    minItems: 3
+    maxItems: 5
+
+  reg-names:
+    minItems: 3
+    maxItems: 5
+    items:
+      - const: config
+      - const: rc
+      - const: port0
+      - const: port1
+      - const: port2
+
+  ranges:
+    minItems: 2
+    maxItems: 2
+
+  interrupts:
+    description:
+      Interrupt specifiers, one for each root port.
+    minItems: 1
+    maxItems: 3
+
+  msi-parent: true
+
+#  msi-ranges:
+#    description:
+#      A list of pairs <intid span>, where "intid" is the first
+#      interrupt number that can be used as an MSI, and "span" the size
+#      of that range.
+#    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+  iommu-map: true
+  iommu-map-mask: true
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - bus-range
+  - interrupts
+  - msi-controller
+  - msi-parent
+  - msi-ranges
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/apple-aic.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      pcie0: pcie at 690000000 {
+        compatible = "apple,t8103-pcie", "apple,pcie";
+        device_type = "pci";
+
+        reg = <0x6 0x90000000 0x0 0x1000000>,
+              <0x6 0x80000000 0x0 0x4000>,
+              <0x6 0x81000000 0x0 0x8000>,
+              <0x6 0x82000000 0x0 0x8000>,
+              <0x6 0x83000000 0x0 0x8000>;
+        reg-names = "config", "rc", "port0", "port1", "port2";
+
+        interrupt-parent = <&aic>;
+        interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
+                     <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
+                     <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
+
+        msi-controller;
+        msi-parent = <&pcie0>;
+        msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
+
+        iommu-map = <0x100 &dart0 1 1>,
+                    <0x200 &dart1 1 1>,
+                    <0x300 &dart2 1 1>;
+        iommu-map-mask = <0xff00>;
+
+        bus-range = <0 3>;
+        #address-cells = <3>;
+        #size-cells = <2>;
+        ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 0x0 0x20000000>,
+                 <0x02000000 0x0 0xc0000000 0x6 0xc0000000 0x0 0x40000000>;
+
+        clocks = <&pcie_core_clk>, <&pcie_aux_clk>, <&pcie_ref_clk>;
+        pinctrl-0 = <&pcie_pins>;
+        pinctrl-names = "default";
+
+        pci at 0,0 {
+          device_type = "pci";
+          reg = <0x0 0x0 0x0 0x0 0x0>;
+          reset-gpios = <&pinctrl_ap 152 0>;
+          max-link-speed = <2>;
+
+          #address-cells = <3>;
+          #size-cells = <2>;
+          ranges;
+        };
+
+        pci at 1,0 {
+          device_type = "pci";
+          reg = <0x800 0x0 0x0 0x0 0x0>;
+          reset-gpios = <&pinctrl_ap 153 0>;
+          max-link-speed = <2>;
+
+          #address-cells = <3>;
+          #size-cells = <2>;
+          ranges;
+        };
+
+        pci at 2,0 {
+          device_type = "pci";
+          reg = <0x1000 0x0 0x0 0x0 0x0>;
+          reset-gpios = <&pinctrl_ap 33 0>;
+          max-link-speed = <1>;
+
+          #address-cells = <3>;
+          #size-cells = <2>;
+          ranges;
+        };
+      };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index c6b8a720c0bc..30bea4042e7e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1694,6 +1694,7 @@ C:	irc://chat.freenode.net/asahi-dev
 T:	git https://github.com/AsahiLinux/linux.git
 F:	Documentation/devicetree/bindings/arm/apple.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
+F:	Documentation/devicetree/bindings/pci/apple,pcie.yaml
 F:	Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
 F:	arch/arm64/boot/dts/apple/
 F:	drivers/irqchip/irq-apple-aic.c
-- 
2.32.0



From mark.kettenis at xs4all.nl  Fri Aug 27 10:15:29 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 27 Aug 2021 19:15:29 +0200
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
Message-ID: <20210827171534.62380-5-mark.kettenis@xs4all.nl>

From: Mark Kettenis <kettenis at openbsd.org>

Add node corresponding to the apcie,t8103 node in the
Apple device tree for the Mac mini (M1, 2020).

Clock references and DART (IOMMU) references are left out at the
moment and will be added once the appropriate bindings have been
settled upon.

Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
---
 arch/arm64/boot/dts/apple/t8103.dtsi | 63 ++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
index 503a76fc30e6..6e4677bdef44 100644
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
@@ -214,5 +214,68 @@ pinctrl_smc: pinctrl at 23e820000 {
 				     <AIC_IRQ 396 IRQ_TYPE_LEVEL_HIGH>,
 				     <AIC_IRQ 397 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
+		pcie0: pcie at 690000000 {
+			compatible = "apple,t8103-pcie", "apple,pcie";
+			device_type = "pci";
+
+			reg = <0x6 0x90000000 0x0 0x1000000>,
+			      <0x6 0x80000000 0x0 0x4000>,
+			      <0x6 0x81000000 0x0 0x8000>,
+			      <0x6 0x82000000 0x0 0x8000>,
+			      <0x6 0x83000000 0x0 0x8000>;
+			reg-names = "config", "rc", "port0", "port1", "port2";
+
+			interrupt-parent = <&aic>;
+			interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
+				     <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
+
+			msi-controller;
+			msi-parent = <&pcie0>;
+			msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
+
+			bus-range = <0 3>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 0x0 0x20000000>,
+				 <0x02000000 0x0 0xc0000000 0x6 0xc0000000 0x0 0x40000000>;
+
+			pinctrl-0 = <&pcie_pins>;
+			pinctrl-names = "default";
+
+			pci at 0,0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				reset-gpios = <&pinctrl_ap 152 0>;
+				max-link-speed = <2>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
+
+			pci at 1,0 {
+				device_type = "pci";
+				reg = <0x800 0x0 0x0 0x0 0x0>;
+				reset-gpios = <&pinctrl_ap 153 0>;
+				max-link-speed = <2>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
+
+			pci at 2,0 {
+				device_type = "pci";
+				reg = <0x1000 0x0 0x0 0x0 0x0>;
+				reset-gpios = <&pinctrl_ap 33 0>;
+				max-link-speed = <1>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+			};
+		};
 	};
 };
-- 
2.32.0



From torvalds at linux-foundation.org  Fri Aug 27 10:16:27 2021
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Fri, 27 Aug 2021 10:16:27 -0700
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <20210827171041.GA28149@lst.de>
References: <20210826131747.GE26318@willie-the-truck>
 <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>
 <20210827074041.GA24309@lst.de>
 <CAHk-=wjd28sN9khO=1j6zmBk+2n4_e+SY1URjW9hzsHSAZU+7Q@mail.gmail.com>
 <20210827171041.GA28149@lst.de>
Message-ID: <CAHk-=wg=+P1+HQXhrszxN_BgWtLc-=dWiT61KzogcJU3hnLrtQ@mail.gmail.com>

On Fri, Aug 27, 2021 at 10:10 AM Christoph Hellwig <hch at lst.de> wrote:
>
> They CCed me on their earlier discussion, but I did not catch up on it
> until you responded to the pull request  If I understood it correct it
> was about a platform device mapping a MMIO region (like a PCI bar),
> but something about section alignment cause pfn_valid to mistrigger.

Yeah, so I can easily see the maxpfn numbers can easily end up being
rounded up to a whole memory section etc.

I think my suggested solution should JustWork(tm) - exactly because if
the area is then in that "this pfn is valid" area, it will
double-check the actual underlying page.

That said, I think x86 avoids the problem another way - by just making
sure max_pfn is exact. That works too, as long as there are no holes
in the RAM map that might be used for PCI BAR's.

So I think arm could fix it that way too, depending on their memory layout.

(x86 has that traditional hole at A0000-FFFFF, but it's special enough
that it presumably is never an issue).

                  Linus


From seanjc at google.com  Fri Aug 27 10:23:05 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:23:05 +0000
Subject: [PATCH V10 01/18] perf/core: Use static_call to optimize
 perf_guest_info_callbacks
In-Reply-To: <20210806133802.3528-2-lingshan.zhu@intel.com>
References: <20210806133802.3528-1-lingshan.zhu@intel.com>
 <20210806133802.3528-2-lingshan.zhu@intel.com>
Message-ID: <YSkfeXcd6nUT3AOJ@google.com>

On Fri, Aug 06, 2021, Zhu Lingshan wrote:
> @@ -2944,18 +2966,21 @@ static unsigned long code_segment_base(struct pt_regs *regs)
>  
>  unsigned long perf_instruction_pointer(struct pt_regs *regs)
>  {
> -	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
> -		return perf_guest_cbs->get_guest_ip();
> +	unsigned long ip = static_call(x86_guest_get_ip)();
> +
> +	if (likely(!ip))

Pivoting on ip==0 isn't correct, it's perfectly legal for a guest to execute
from %rip=0.  Unless there's some static_call() magic that supports this with a
default function:
	
	if (unlikely(!static_call(x86_guest_get_ip)(&ip)))
		regs->ip + code_segment_base(regs)

	return ip;

The easiest thing is keep the existing:

	if (unlikely(static_call(x86_guest_state)()))
		return static_call(x86_guest_get_ip)();

	return regs->ip + code_segment_base(regs);

It's an extra call for PMIs in guest, but I don't think any of the KVM folks care
_that_ much about the performance in this case.

> +		ip = regs->ip + code_segment_base(regs);
>  
> -	return regs->ip + code_segment_base(regs);
> +	return ip;
>  }


From alyssa at rosenzweig.io  Fri Aug 27 10:58:45 2021
From: alyssa at rosenzweig.io (Alyssa Rosenzweig)
Date: Fri, 27 Aug 2021 17:58:45 +0000
Subject: [PATCH v4 3/4] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <20210827171534.62380-4-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-4-mark.kettenis@xs4all.nl>
Message-ID: <YSkn1bMU/xkl2P7e@rosenzweig.io>

> +#  msi-ranges:
> +#    description:
> +#      A list of pairs <intid span>, where "intid" is the first
> +#      interrupt number that can be used as an MSI, and "span" the size
> +#      of that range.
> +#    $ref: /schemas/types.yaml#/definitions/phandle-array

Comment intended?


From alyssa at rosenzweig.io  Fri Aug 27 10:59:59 2021
From: alyssa at rosenzweig.io (Alyssa Rosenzweig)
Date: Fri, 27 Aug 2021 17:59:59 +0000
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <20210827171534.62380-5-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-5-mark.kettenis@xs4all.nl>
Message-ID: <YSkoHw3dZrW5Qnjf@rosenzweig.io>

> Clock references and DART (IOMMU) references are left out at the
> moment and will be added once the appropriate bindings have been
> settled upon.
> 

DART is in mainline .... is there a PCIe specific issue?


From mark.kettenis at xs4all.nl  Fri Aug 27 11:22:17 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 27 Aug 2021 20:22:17 +0200 (CEST)
Subject: [PATCH v4 3/4] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <YSkn1bMU/xkl2P7e@rosenzweig.io> (message from Alyssa Rosenzweig
 on Fri, 27 Aug 2021 17:58:45 +0000)
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-4-mark.kettenis@xs4all.nl>
 <YSkn1bMU/xkl2P7e@rosenzweig.io>
Message-ID: <5614206085195f47@bloch.sibelius.xs4all.nl>

> Date: Fri, 27 Aug 2021 17:58:45 +0000
> From: Alyssa Rosenzweig <alyssa at rosenzweig.io>
> 
> > +#  msi-ranges:
> > +#    description:
> > +#      A list of pairs <intid span>, where "intid" is the first
> > +#      interrupt number that can be used as an MSI, and "span" the size
> > +#      of that range.
> > +#    $ref: /schemas/types.yaml#/definitions/phandle-array
> 
> Comment intended?

Hmm, no.  I commented it out here in the process of moving it to the
new MSI controller binding schema.  And then forgot about it.  I
suspect I'll need a v5 of the series anyway so I'll fix it there.


From mark.kettenis at xs4all.nl  Fri Aug 27 11:24:14 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 27 Aug 2021 20:24:14 +0200 (CEST)
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <YSkoHw3dZrW5Qnjf@rosenzweig.io> (message from Alyssa Rosenzweig
 on Fri, 27 Aug 2021 17:59:59 +0000)
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-5-mark.kettenis@xs4all.nl>
 <YSkoHw3dZrW5Qnjf@rosenzweig.io>
Message-ID: <56142087154d4d9e@bloch.sibelius.xs4all.nl>

> Date: Fri, 27 Aug 2021 17:59:59 +0000
> From: Alyssa Rosenzweig <alyssa at rosenzweig.io>
> 
> > Clock references and DART (IOMMU) references are left out at the
> > moment and will be added once the appropriate bindings have been
> > settled upon.
> > 
> 
> DART is in mainline .... is there a PCIe specific issue?

True.  I don't expect 4/4 to be merged as part of this series though
as it will need to go through marcan's tree.  It is mostly there to
show what the device tree will look like.


From dan.j.williams at intel.com  Fri Aug 27 12:01:06 2021
From: dan.j.williams at intel.com (Dan Williams)
Date: Fri, 27 Aug 2021 12:01:06 -0700
Subject: [PATCH v2 08/15] peci: Add device detection
In-Reply-To: <20210803113134.2262882-9-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-9-iwona.winiarska@intel.com>
Message-ID: <CAPcyv4hPLReB6wGTDBM_tnqRUXxNASFCtgCw0=aDW+PPfSJ57A@mail.gmail.com>

On Tue, Aug 3, 2021 at 4:35 AM Iwona Winiarska
<iwona.winiarska at intel.com> wrote:
>
> Since PECI devices are discoverable, we can dynamically detect devices
> that are actually available in the system.
>
> This change complements the earlier implementation by rescanning PECI
> bus to detect available devices. For this purpose, it also introduces the
> minimal API for PECI requests.
>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> ---
>  drivers/peci/Makefile   |   2 +-
>  drivers/peci/core.c     |  33 ++++++++++++
>  drivers/peci/device.c   | 114 ++++++++++++++++++++++++++++++++++++++++
>  drivers/peci/internal.h |  14 +++++
>  drivers/peci/request.c  |  50 ++++++++++++++++++
>  5 files changed, 212 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/peci/device.c
>  create mode 100644 drivers/peci/request.c
>
> diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
> index 926d8df15cbd..c5f9d3fe21bb 100644
> --- a/drivers/peci/Makefile
> +++ b/drivers/peci/Makefile
> @@ -1,7 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>
>  # Core functionality
> -peci-y := core.o
> +peci-y := core.o request.o device.o
>  obj-$(CONFIG_PECI) += peci.o
>
>  # Hardware specific bus drivers
> diff --git a/drivers/peci/core.c b/drivers/peci/core.c
> index 7b3938af0396..d143f1a7fe98 100644
> --- a/drivers/peci/core.c
> +++ b/drivers/peci/core.c
> @@ -34,6 +34,20 @@ struct device_type peci_controller_type = {
>         .release        = peci_controller_dev_release,
>  };
>
> +static int peci_controller_scan_devices(struct peci_controller *controller)
> +{
> +       int ret;
> +       u8 addr;
> +
> +       for (addr = PECI_BASE_ADDR; addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX; addr++) {
> +               ret = peci_device_create(controller, addr);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       return 0;
> +}
> +
>  static struct peci_controller *peci_controller_alloc(struct device *dev,
>                                                      struct peci_controller_ops *ops)
>  {
> @@ -76,10 +90,23 @@ static struct peci_controller *peci_controller_alloc(struct device *dev,
>         return ERR_PTR(ret);
>  }
>
> +static int unregister_child(struct device *dev, void *dummy)
> +{
> +       peci_device_destroy(to_peci_device(dev));
> +
> +       return 0;
> +}
> +
>  static void unregister_controller(void *_controller)
>  {
>         struct peci_controller *controller = _controller;
>
> +       /*
> +        * Detach any active PECI devices. This can't fail, thus we do not
> +        * check the returned value.
> +        */
> +       device_for_each_child_reverse(&controller->dev, NULL, unregister_child);
> +
>         device_unregister(&controller->dev);
>  }
>
> @@ -115,6 +142,12 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
>         if (ret)
>                 return ERR_PTR(ret);
>
> +       /*
> +        * Ignoring retval since failures during scan are non-critical for
> +        * controller itself.
> +        */
> +       peci_controller_scan_devices(controller);
> +
>         return controller;
>
>  err:
> diff --git a/drivers/peci/device.c b/drivers/peci/device.c
> new file mode 100644
> index 000000000000..32811248997b
> --- /dev/null
> +++ b/drivers/peci/device.c
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2018-2021 Intel Corporation
> +
> +#include <linux/peci.h>
> +#include <linux/slab.h>
> +
> +#include "internal.h"
> +
> +static int peci_detect(struct peci_controller *controller, u8 addr)
> +{
> +       struct peci_request *req;
> +       int ret;
> +
> +       /*
> +        * PECI Ping is a command encoded by tx_len = 0, rx_len = 0.
> +        * We expect correct Write FCS if the device at the target address
> +        * is able to respond.
> +        */
> +       req = peci_request_alloc(NULL, 0, 0);
> +       if (!req)
> +               return -ENOMEM;

Seems a waste to do a heap allocation for this routine. Why not:

       /*
        * PECI Ping is a command encoded by tx_len = 0, rx_len = 0.
        * We expect correct Write FCS if the device at the target address
        * is able to respond.
        */
       struct peci_request req = { 0 };

> +
> +       mutex_lock(&controller->bus_lock);
> +       ret = controller->ops->xfer(controller, addr, req);
> +       mutex_unlock(&controller->bus_lock);
> +
> +       peci_request_free(req);
> +
> +       return ret;
> +}
> +
> +static bool peci_addr_valid(u8 addr)
> +{
> +       return addr >= PECI_BASE_ADDR && addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX;
> +}
> +
> +static int peci_dev_exists(struct device *dev, void *data)
> +{
> +       struct peci_device *device = to_peci_device(dev);
> +       u8 *addr = data;
> +
> +       if (device->addr == *addr)
> +               return -EBUSY;
> +
> +       return 0;
> +}
> +
> +int peci_device_create(struct peci_controller *controller, u8 addr)
> +{
> +       struct peci_device *device;
> +       int ret;
> +
> +       if (WARN_ON(!peci_addr_valid(addr)))

The WARN_ON is overkill, especially as there is only one caller of
this and it loops through valid addresses.

> +               return -EINVAL;
> +
> +       /* Check if we have already detected this device before. */
> +       ret = device_for_each_child(&controller->dev, &addr, peci_dev_exists);
> +       if (ret)
> +               return 0;
> +
> +       ret = peci_detect(controller, addr);
> +       if (ret) {
> +               /*
> +                * Device not present or host state doesn't allow successful
> +                * detection at this time.
> +                */
> +               if (ret == -EIO || ret == -ETIMEDOUT)
> +                       return 0;
> +
> +               return ret;
> +       }
> +
> +       device = kzalloc(sizeof(*device), GFP_KERNEL);
> +       if (!device)
> +               return -ENOMEM;
> +
> +       device->addr = addr;
> +       device->dev.parent = &controller->dev;
> +       device->dev.bus = &peci_bus_type;
> +       device->dev.type = &peci_device_type;
> +
> +       ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
> +       if (ret)
> +               goto err_free;

It's cleaner to just have one unified error exit using put_device().
Use the device_initialize() + device_add() pattern, not
device_register().


> +
> +       ret = device_register(&device->dev);
> +       if (ret)
> +               goto err_put;
> +
> +       return 0;
> +
> +err_put:
> +       put_device(&device->dev);
> +err_free:
> +       kfree(device);
> +
> +       return ret;
> +}
> +
> +void peci_device_destroy(struct peci_device *device)
> +{
> +       device_unregister(&device->dev);

No clear value for this wrapper, in fact in one caller it causes it to
do a to_peci_device() just this helper can undo that up-cast.

> +}
> +
> +static void peci_device_release(struct device *dev)
> +{
> +       struct peci_device *device = to_peci_device(dev);
> +
> +       kfree(device);
> +}
> +
> +struct device_type peci_device_type = {
> +       .release        = peci_device_release,
> +};
> diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
> index 918dea745a86..57d11a902c5d 100644
> --- a/drivers/peci/internal.h
> +++ b/drivers/peci/internal.h
> @@ -8,6 +8,20 @@
>  #include <linux/types.h>
>
>  struct peci_controller;
> +struct peci_device;
> +struct peci_request;
> +
> +/* PECI CPU address range 0x30-0x37 */
> +#define PECI_BASE_ADDR         0x30
> +#define PECI_DEVICE_NUM_MAX    8
> +
> +struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len);
> +void peci_request_free(struct peci_request *req);
> +
> +extern struct device_type peci_device_type;
> +
> +int peci_device_create(struct peci_controller *controller, u8 addr);
> +void peci_device_destroy(struct peci_device *device);
>
>  extern struct bus_type peci_bus_type;
>
> diff --git a/drivers/peci/request.c b/drivers/peci/request.c
> new file mode 100644
> index 000000000000..81b567bc7b87
> --- /dev/null
> +++ b/drivers/peci/request.c
> @@ -0,0 +1,50 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2021 Intel Corporation
> +
> +#include <linux/export.h>
> +#include <linux/peci.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +#include "internal.h"
> +
> +/**
> + * peci_request_alloc() - allocate &struct peci_requests
> + * @device: PECI device to which request is going to be sent
> + * @tx_len: TX length
> + * @rx_len: RX length
> + *
> + * Return: A pointer to a newly allocated &struct peci_request on success or NULL otherwise.
> + */
> +struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len)
> +{
> +       struct peci_request *req;
> +
> +       if (WARN_ON_ONCE(tx_len > PECI_REQUEST_MAX_BUF_SIZE || rx_len > PECI_REQUEST_MAX_BUF_SIZE))

WARN_ON_ONCE() should only be here to help other kernel developers not
make this mistake However, another way to enforce this is to stop
exporting peci_request_alloc() and instead export helpers for specific
command types, and keep this detail internal to the core. If you keep
this, it needs a comment that it is only here to warn other
peci-client developers of their bug before it goes upstream.


From mathieu.desnoyers at efficios.com  Fri Aug 27 12:09:34 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Fri, 27 Aug 2021 15:09:34 -0400 (EDT)
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <YSgpy8iXXXUQ+b/k@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-5-seanjc@google.com>
 <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>
 <282257549.21721.1629732017655.JavaMail.zimbra@efficios.com>
 <YSblqrrpKcORzilX@google.com>
 <1700758714.29394.1630003332081.JavaMail.zimbra@efficios.com>
 <YSgpy8iXXXUQ+b/k@google.com>
Message-ID: <339641531.29941.1630091374065.JavaMail.zimbra@efficios.com>



----- On Aug 26, 2021, at 7:54 PM, Sean Christopherson seanjc at google.com wrote:

> On Thu, Aug 26, 2021, Mathieu Desnoyers wrote:
>> ----- On Aug 25, 2021, at 8:51 PM, Sean Christopherson seanjc at google.com wrote:
>> >> >> +		r = sched_setaffinity(0, sizeof(allowed_mask), &allowed_mask);
>> >> >> +		TEST_ASSERT(!r, "sched_setaffinity failed, errno = %d (%s)",
>> >> >> +			    errno, strerror(errno));
>> >> >> +		atomic_inc(&seq_cnt);
>> >> >> +
>> >> >> +		CPU_CLR(cpu, &allowed_mask);
>> >> >> +
>> >> >> +		/*
>> >> >> +		 * Let the read-side get back into KVM_RUN to improve the odds
>> >> >> +		 * of task migration coinciding with KVM's run loop.
>> >> > 
>> >> > This comment should be about increasing the odds of letting the seqlock
>> >> > read-side complete. Otherwise, the delay between the two back-to-back
>> >> > atomic_inc is so small that the seqlock read-side may never have time to
>> >> > complete the reading the rseq cpu id and the sched_getcpu() call, and can
>> >> > retry forever.
>> > 
>> > Hmm, but that's not why there's a delay.  I'm not arguing that a livelock isn't
>> > possible (though that syscall would have to be screaming fast),
>> 
>> I don't think we have the same understanding of the livelock scenario. AFAIU the
>> livelock
>> would be caused by a too-small delay between the two consecutive atomic_inc()
>> from one
>> loop iteration to the next compared to the time it takes to perform a read-side
>> critical
>> section of the seqlock. Back-to-back atomic_inc can be performed very quickly,
>> so I
>> doubt that the sched_getcpu implementation have good odds to be fast enough to
>> complete
>> in that narrow window, leading to lots of read seqlock retry.
> 
> Ooooh, yeah, brain fart on my side.  I was thinking of the two atomic_inc() in
> the
> same loop iteration and completely ignoring the next iteration.  Yes, I 100%
> agree
> that a delay to ensure forward progress is needed.  An assertion in main() that
> the
> reader complete at least some reasonable number of KVM_RUNs is also probably a
> good
> idea, e.g. to rule out a false pass due to the reader never making forward
> progress.

Agreed.

> 
> FWIW, the do-while loop does make forward progress without a delay, but at ~50%
> throughput, give or take.

I did not expect absolutely no progress, but a significant slow down of
the read-side.

> 
>> > but the primary motivation is very much to allow the read-side enough time
>> > to get back into KVM proper.
>> 
>> I'm puzzled by your statement. AFAIU, let's say we don't have the delay, then we
>> have:
>> 
>> migration thread                             KVM_RUN/read-side thread
>> -----------------------------------------------------------------------------------
>>                                              - ioctl(KVM_RUN)
>> - atomic_inc_seq_cst(&seqcnt)
>> - sched_setaffinity
>> - atomic_inc_seq_cst(&seqcnt)
>>                                              - a = atomic_load(&seqcnt) & ~1
>>                                              - smp_rmb()
>>                                              - b = LOAD_ONCE(__rseq_abi->cpu_id);
>>                                              - sched_getcpu()
>>                                              - smp_rmb()
>>                                              - re-load seqcnt/compare (succeeds)
>>                                                - Can only succeed if entire read-side happens while the seqcnt
>>                                                  is in an even numbered state.
>>                                              - if (a != b) abort()
>>   /* no delay. Even counter state is very
>>      short. */
>> - atomic_inc_seq_cst(&seqcnt)
>>   /* Let's suppose the lack of delay causes the
>>      setaffinity to complete too early compared
>>      with KVM_RUN ioctl */
>> - sched_setaffinity
>> - atomic_inc_seq_cst(&seqcnt)
>> 
>>   /* no delay. Even counter state is very
>>      short. */
>> - atomic_inc_seq_cst(&seqcnt)
>>   /* Then a setaffinity from a following
>>      migration thread loop will run
>>      concurrently with KVM_RUN */
>>                                              - ioctl(KVM_RUN)
>> - sched_setaffinity
>> - atomic_inc_seq_cst(&seqcnt)
>> 
>> As pointed out here, if the first setaffinity runs too early compared with
>> KVM_RUN,
>> a following setaffinity will run concurrently with it. However, the fact that
>> the even counter state is very short may very well hurt progress of the read
>> seqlock.
> 
> *sigh*
> 
> Several hours later, I think I finally have my head wrapped around everything.
> 
> Due to the way the test is written and because of how KVM's run loop works,
> TIF_NOTIFY_RESUME or TIF_NEED_RESCHED effectively has to be set before KVM
> actually
> enters the guest, otherwise KVM will exit to userspace without touching the
> flag,
> i.e. it will be handled by the normal exit_to_user_mode_loop().
> 
> Where I got lost was trying to figure out why I couldn't make the bug reproduce
> by
> causing the guest to exit to KVM, but not userspace, in which case KVM should
> easily trigger the problematic flow as the window for sched_getcpu() to collide
> with KVM would be enormous.  The reason I didn't go down this route for the
> "official" test is that, unless there's something clever I'm overlooking, it
> requires arch specific guest code, and ialso I don't know that forcing an exit
> would even be necessary/sufficient on other architectures.
> 
> Anyways, I was trying to confirm that the bug was being hit without a delay,
> while
> still retaining the sequence retry in the test.  The test doesn't fail because
> the
> back-to-back atomic_inc() changes seqcnt too fast.  The read-side makes forward
> progress, but it never observes failure because the do-while loop only ever
> completes after another sched_setaffinity(), never after the one that collides
> with KVM because it takes too long to get out of ioctl(KVM_RUN) and back to the
> test.  I.e. the atomic_inc() in the next loop iteration (makes seq_cnt odd)
> always
> completes before the check, and so the check ends up spinning until another
> migration, which correctly updates rseq.  This was expected and didn't confuse
> me.
> 
> What confused me is that I was trying to confirm the bug was being hit from
> within
> the kernel by confirming KVM observed TIF_NOTIFY_RESUME, but I misunderstood
> when
> TIF_NOTIFY_RESUME would get set.  KVM can observe TIF_NOTIFY_RESUME directly,
> but
> it's rare, and I suspect happens iff sched_setaffinity() hits the small window
> where
> it collides with KVM_RUN before KVM enters the guest.
> 
> More commonly, the bug occurs when KVM sees TIF_NEED_RESCHED.  In that case, KVM
> calls xfer_to_guest_mode_work(), which does schedule() and _that_ sets
> TIF_NOTIFY_RESUME.  xfer_to_guest_mode_work() then mishandles TIF_NOTIFY_RESUME
> and the bug is hit, but my confirmation logic in KVM never fired.
> 
> So there are effectively three reasons we want a delay:
> 
>  1. To allow sched_setaffinity() to coincide with ioctl(KVM_RUN) before KVM can
>     enter the guest so that the guest doesn't need an arch-specific VM-Exit source.
> 
>  2. To let ioctl(KVM_RUN) make its way back to the test before the next round
>     of migration.
> 
>  3. To ensure the read-side can make forward progress, e.g. if sched_getcpu()
>     involves a syscall.
> 
> 
> After looking at KVM for arm64 and s390, #1 is a bit tenuous because x86 is the
> only arch that currently uses xfer_to_guest_mode_work(), i.e. the test could be
> tweaked to be overtly x86-specific.  But since a delay is needed for #2 and #3,
> I'd prefer to rely on it for #1 as well in the hopes that this test provides
> coverage for arm64 and/or s390 if they're ever converted to use the common
> xfer_to_guest_mode_work().

Now that we have this understanding of why we need the delay, it would be good to
write this down in a comment within the test.

Does it reproduce if we randomize the delay to have it picked randomly from 0us
to 100us (with 1us step) ? It would remove a lot of the needs for arch-specific
magic delay value.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From saravanak at google.com  Fri Aug 27 12:09:22 2021
From: saravanak at google.com (Saravana Kannan)
Date: Fri, 27 Aug 2021 12:09:22 -0700
Subject: [BUG] amba: Remove deferred device addition
In-Reply-To: <85b28900-5f42-b997-2ded-0b952bc2a03e@huawei.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
 <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
 <b5eb935f-26e1-6475-63af-e7f6101eb017@huawei.com>
 <CAGETcx9yaWZOzt=gcyNAshoHdPoYizhmrKS-kU9c2QM2+HqeEw@mail.gmail.com>
 <df8e7756-8b0d-d7de-a9ff-3f6eb0ffa8a5@huawei.com>
 <CAGETcx-47yRUcBjEdWFBtroSEkHXRNrJ4zaD8WpE0DPEPp9NxQ@mail.gmail.com>
 <85b28900-5f42-b997-2ded-0b952bc2a03e@huawei.com>
Message-ID: <CAGETcx-N4+u0iw9n5ncx_9MNnTa3ViyesxsDD7xN3jtEPT-uBw@mail.gmail.com>

On Fri, Aug 27, 2021 at 7:38 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>
>
> On 2021/8/27 8:04, Saravana Kannan wrote:
> > On Thu, Aug 26, 2021 at 1:22 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
> >>
> >>>>> Btw, I've been working on [1] cleaning up the one-off deferred probe
> >>>>> solution that we have for amba devices. That causes a bunch of other
> >>>>> headaches. Your patch 3/3 takes us further in the wrong direction by
> >>>>> adding more reasons for delaying the addition of the device.
> >> Hi Saravana, I try the link[1], but with it, there is a crash when boot
> >> (qemu-system-arm -M vexpress-a15),

I'm assuming it's this one?
arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts

> > Hi,
> >
> > It's hard to make sense of the logs. Looks like two different threads
> > might be printing to the log at the same time? Can you please enable
> > the config that prints the thread ID (forgot what it's called) and
> > collect this again? With what I could tell the crash seems to be
> > happening somewhere in platform_match(), but that's not related to
> > this patch at all?
>
> Can you reproduce it? it is very likely related(without your patch, the
> boot is fine),

Sorry, I haven't ever setup qemu and booted vexpress. Thanks for your help.

> the NULL ptr is about serio, it is registed from amba driver.
>
> ambakmi_driver_init
>
>   -- amba_kmi_probe
>
>     -- __serio_register_port

Thanks for the pointer. I took a look at the logs and the code. It's
very strange. As you can see from the backtrace, platform_match() is
being called for the device_add() from serio_handle_event(). But the
device that gets added there is on the serio_bus which obviously
should be using the serio_bus_match.

>
> +Dmitry and input maillist, is there some known issue about serio ?
>
> I add some debug, the full log is attached.
>
> [    2.958355][   T41] input: AT Raw Set 2 keyboard as
> /devices/platform/bus at 8000000/bus at 8000000:motherboard-bus/bus at 8000000:motherboard-bus:iofpga-bus at 300000000/1c060000.kmi/serio0/input/input0
> [    2.977441][   T41] serio serio1: pdev c1e05508, pdev->name (null),
> drv c1090fc0, drv->name vexpress-reset

Based on the logs you added, it's pretty clear we are getting to
platform_match(). It's also strange that the drv->name is
vexpress-reset

> [    2.977928][   T41] 8<--- cut here ---
> [    2.978162][   T41] Unhandled fault: page domain fault (0x01b) at
> 0x00000000
> [    2.978494][   T41] pgd = (ptrval)
> [    2.978819][   T41] [00000000] *pgd=00000000
> [    2.979881][   T41] Internal error: : 1b [#1] SMP ARM
> [    2.980385][   T41] Modules linked in:
> [    2.980810][   T41] CPU: 0 PID: 41 Comm: kworker/0:2 Not tainted
> 5.14.0-rc7+ #213
> [    2.981229][   T41] Hardware name: ARM-Versatile Express
> [    2.981780][   T41] Workqueue: events_long serio_handle_event
> [    2.982737][   T41] PC is at strcmp+0x18/0x44
> [    2.983030][   T41] LR is at platform_match+0xdc/0xf0
> [    2.983283][   T41] pc : [<c0560bcc>]    lr : [<c0646358>]    psr:
> 600b0013
> [    2.983572][   T41] sp : c1675d68  ip : c1675d78  fp : c1675d74
> [    2.983832][   T41] r10: 00000000  r9 : 00000000  r8 : 00000001
> [    2.984095][   T41] r7 : c1e05518  r6 : c1675df4  r5 : c1e05518  r4 :
> c1090fc0
> [    2.984395][   T41] r3 : c0a5e180  r2 : 6bede3db  r1 : c0b82a04  r0 :
> 00000000
> [    2.984906][   T41] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32 ISA
> ARM  Segment none

---- 8< ---- cleaning up a bunch of register dumps

> [    3.003113][   T41] Backtrace:
> [    3.003451][   T41] [<c0560bb4>] (strcmp) from [<c0646358>] (platform_match+0xdc/0xf0)
> [    3.003963][   T41] [<c064627c>] (platform_match) from [<c06437d4>] (__device_attach_driver+0x3c/0xf4)
> [    3.004769][   T41] [<c0643798>] (__device_attach_driver) from [<c0641180>] (bus_for_each_drv+0x68/0xc8)
> [    3.005481][   T41] [<c0641118>] (bus_for_each_drv) from [<c0642f40>] (__device_attach+0xf0/0x16c)
> [    3.006152][   T41] [<c0642e50>] (__device_attach) from [<c06439d4>] (device_initial_probe+0x1c/0x20)
> [    3.006853][   T41] [<c06439b8>] (device_initial_probe) from [<c0642030>] (bus_probe_device+0x94/0x9c)
> [    3.007259][   T41] [<c0641f9c>] (bus_probe_device) from [<c063f9cc>] (device_add+0x408/0x8b8)
> [    3.007900][   T41] [<c063f5c4>] (device_add) from [<c071c1cc>] (serio_handle_event+0x1b8/0x234)
> [    3.008824][   T41] [<c071c014>] (serio_handle_event) from [<c01475a4>] (process_one_work+0x238/0x594)
> [    3.009737][   T41] [<c014736c>] (process_one_work) from [<c014795c>] (worker_thread+0x5c/0x5f4)
> [    3.010638][   T41] [<c0147900>] (worker_thread) from [<c014feb4>] (kthread+0x178/0x194)
> [    3.011496][   T41] [<c014fd3c>] (kthread) from [<c0100150>] (ret_from_fork+0x14/0x24)
> [    3.011860][   T41] Exception stack(0xc1675fb0 to 0xc1675ff8)

But the platform_match() is happening for the device_add() from
serio_event_handle() that's adding a device to the serio_bus and it
should be using serio_bus_match().

I haven't reached any conclusion yet, but my current thought process
is that it's either:
1. My patch is somehow causing list corruption. But I don't directly
touch any list in my change (other than deleting a list entirely), so
it's not clear how that would be happening.
2. Without my patch, these AMBA device's probe would be delayed at
least until 5 seconds or possibly later. I'm wondering if my patch is
catching some bad timing assumptions in other code.

You might be able to test out theory (2) by DEFERRED_DEVICE_TIMEOUT to
a much smaller number. Say 500ms or 100ms. If it doesn't crash, it
doesn't mean it's not (2), but if it does, then we know for sure it's
(2).

I'll continue debugging further.

-Saravana

>
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index 836d6d23bba3..883a58c658c2 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -237,6 +237,7 @@ static int amba_match(struct device *dev, struct
> device_driver *drv)
>
>          if (!pcdev->periphid) {
>                  int ret = amba_read_periphid(pcdev);
> +               dev_info(dev, "%s, amba_read_periphid ret = %d\n",
> __func__, ret);
>
>                  if (ret)
>                          return ret;
> @@ -522,6 +523,7 @@ int amba_device_add(struct amba_device *dev, struct
> resource *parent)
>          /* If primecell ID isn't hard-coded, figure it out */
>          if (!dev->periphid) {
>                  ret = amba_read_periphid(dev);
> +               dev_info(&dev->dev, "%s, amba_read_periphid ret = %d\n",
> __func__, ret);
>                  if (ret && ret != -EPROBE_DEFER)
>                          goto err_release;
>                  /*
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 8640578f45e9..f7c1933c56b5 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -1360,6 +1360,7 @@ static int platform_match(struct device *dev,
> struct device_driver *drv)
>          struct platform_device *pdev = to_platform_device(dev);
>          struct platform_driver *pdrv = to_platform_driver(drv);
>
> +       dev_info(dev, "pdev %px, pdev->name %s, drv %px, drv->name %s",
> pdev, pdev->name, drv, drv->name);
>          /* When driver_override is set, only bind to the matching driver */
>          if (pdev->driver_override)
>                  return !strcmp(pdev->driver_override, drv->name);
>
>
> > [1] - https://lore.kernel.org/lkml/CAGETcx8b228nDUho3cX9AAQ-pXOfZTMv8cj2vhdx9yc_pk8q+A at mail.gmail.com/
> > .
> >
> >>> .
> >>>
> > .
> >


From dan.j.williams at intel.com  Fri Aug 27 12:11:00 2021
From: dan.j.williams at intel.com (Dan Williams)
Date: Fri, 27 Aug 2021 12:11:00 -0700
Subject: [PATCH v2 09/15] peci: Add sysfs interface for PECI bus
In-Reply-To: <20210803113134.2262882-10-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-10-iwona.winiarska@intel.com>
Message-ID: <CAPcyv4hhtTi+dKspjoamYj53GxT4Ot_1pG5-eavUJdihD8iAEg@mail.gmail.com>

On Tue, Aug 3, 2021 at 4:35 AM Iwona Winiarska
<iwona.winiarska at intel.com> wrote:
>
> PECI devices may not be discoverable at the time when PECI controller is
> being added (e.g. BMC can boot up when the Host system is still in S5).
> Since we currently don't have the capabilities to figure out the Host
> system state inside the PECI subsystem itself, we have to rely on
> userspace to do it for us.
>
> In the future, PECI subsystem may be expanded with mechanisms that allow
> us to avoid depending on userspace interaction (e.g. CPU presence could
> be detected using GPIO, and the information on whether it's discoverable
> could be obtained over IPMI).

Thanks for this detail.

> Unfortunately, those methods may ultimately not be available (support
> will vary from platform to platform), which means that we still need
> platform independent method triggered by userspace.
>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> ---
>  Documentation/ABI/testing/sysfs-bus-peci | 16 +++++
>  drivers/peci/Makefile                    |  2 +-
>  drivers/peci/core.c                      |  3 +-
>  drivers/peci/device.c                    |  1 +
>  drivers/peci/internal.h                  |  5 ++
>  drivers/peci/sysfs.c                     | 82 ++++++++++++++++++++++++
>  6 files changed, 107 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-peci
>  create mode 100644 drivers/peci/sysfs.c
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-peci b/Documentation/ABI/testing/sysfs-bus-peci
> new file mode 100644
> index 000000000000..56c2b2216bbd
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-peci
> @@ -0,0 +1,16 @@
> +What:          /sys/bus/peci/rescan
> +Date:          July 2021
> +KernelVersion: 5.15
> +Contact:       Iwona Winiarska <iwona.winiarska at intel.com>
> +Description:
> +               Writing a non-zero value to this attribute will
> +               initiate scan for PECI devices on all PECI controllers
> +               in the system.
> +
> +What:          /sys/bus/peci/devices/<controller_id>-<device_addr>/remove
> +Date:          July 2021
> +KernelVersion: 5.15
> +Contact:       Iwona Winiarska <iwona.winiarska at intel.com>
> +Description:
> +               Writing a non-zero value to this attribute will
> +               remove the PECI device and any of its children.
> diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
> index c5f9d3fe21bb..917f689e147a 100644
> --- a/drivers/peci/Makefile
> +++ b/drivers/peci/Makefile
> @@ -1,7 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>
>  # Core functionality
> -peci-y := core.o request.o device.o
> +peci-y := core.o request.o device.o sysfs.o
>  obj-$(CONFIG_PECI) += peci.o
>
>  # Hardware specific bus drivers
> diff --git a/drivers/peci/core.c b/drivers/peci/core.c
> index d143f1a7fe98..c473acb3c2a0 100644
> --- a/drivers/peci/core.c
> +++ b/drivers/peci/core.c
> @@ -34,7 +34,7 @@ struct device_type peci_controller_type = {
>         .release        = peci_controller_dev_release,
>  };
>
> -static int peci_controller_scan_devices(struct peci_controller *controller)
> +int peci_controller_scan_devices(struct peci_controller *controller)
>  {
>         int ret;
>         u8 addr;
> @@ -159,6 +159,7 @@ EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
>
>  struct bus_type peci_bus_type = {
>         .name           = "peci",
> +       .bus_groups     = peci_bus_groups,
>  };
>
>  static int __init peci_init(void)
> diff --git a/drivers/peci/device.c b/drivers/peci/device.c
> index 32811248997b..d77d9dabd51e 100644
> --- a/drivers/peci/device.c
> +++ b/drivers/peci/device.c
> @@ -110,5 +110,6 @@ static void peci_device_release(struct device *dev)
>  }
>
>  struct device_type peci_device_type = {
> +       .groups         = peci_device_groups,
>         .release        = peci_device_release,
>  };
> diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
> index 57d11a902c5d..978e12c8e1d3 100644
> --- a/drivers/peci/internal.h
> +++ b/drivers/peci/internal.h
> @@ -8,6 +8,7 @@
>  #include <linux/types.h>
>
>  struct peci_controller;
> +struct attribute_group;
>  struct peci_device;
>  struct peci_request;
>
> @@ -19,12 +20,16 @@ struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u
>  void peci_request_free(struct peci_request *req);
>
>  extern struct device_type peci_device_type;
> +extern const struct attribute_group *peci_device_groups[];
>
>  int peci_device_create(struct peci_controller *controller, u8 addr);
>  void peci_device_destroy(struct peci_device *device);
>
>  extern struct bus_type peci_bus_type;
> +extern const struct attribute_group *peci_bus_groups[];

To me, sysfs.c is small enough to just fold into core.c, then no need
to declare public attribute arrays like this, but up to you if you
prefer the sysfs.c split.

>
>  extern struct device_type peci_controller_type;
>
> +int peci_controller_scan_devices(struct peci_controller *controller);
> +
>  #endif /* __PECI_INTERNAL_H */
> diff --git a/drivers/peci/sysfs.c b/drivers/peci/sysfs.c
> new file mode 100644
> index 000000000000..db9ef05776e3
> --- /dev/null
> +++ b/drivers/peci/sysfs.c
> @@ -0,0 +1,82 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2021 Intel Corporation
> +
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/peci.h>
> +
> +#include "internal.h"
> +
> +static int rescan_controller(struct device *dev, void *data)
> +{
> +       if (dev->type != &peci_controller_type)
> +               return 0;
> +
> +       return peci_controller_scan_devices(to_peci_controller(dev));
> +}
> +
> +static ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count)
> +{
> +       bool res;
> +       int ret;
> +
> +       ret = kstrtobool(buf, &res);
> +       if (ret)
> +               return ret;
> +
> +       if (!res)
> +               return count;
> +
> +       ret = bus_for_each_dev(&peci_bus_type, NULL, NULL, rescan_controller);
> +       if (ret)
> +               return ret;
> +
> +       return count;
> +}
> +static BUS_ATTR_WO(rescan);
> +
> +static struct attribute *peci_bus_attrs[] = {
> +       &bus_attr_rescan.attr,
> +       NULL
> +};
> +
> +static const struct attribute_group peci_bus_group = {
> +       .attrs = peci_bus_attrs,
> +};
> +
> +const struct attribute_group *peci_bus_groups[] = {
> +       &peci_bus_group,
> +       NULL
> +};
> +
> +static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
> +                           const char *buf, size_t count)
> +{
> +       struct peci_device *device = to_peci_device(dev);
> +       bool res;
> +       int ret;
> +
> +       ret = kstrtobool(buf, &res);
> +       if (ret)
> +               return ret;
> +
> +       if (res && device_remove_file_self(dev, attr))
> +               peci_device_destroy(device);

How do you solve races between sysfs device remove and controller
device remove? Looks like double-free at first glance. Have a look at
the  kill_device() helper as one way to resolve this double-delete
race..

> +
> +       return count;
> +}
> +static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0200, NULL, remove_store);
> +
> +static struct attribute *peci_device_attrs[] = {
> +       &dev_attr_remove.attr,
> +       NULL
> +};
> +
> +static const struct attribute_group peci_device_group = {
> +       .attrs = peci_device_attrs,
> +};
> +
> +const struct attribute_group *peci_device_groups[] = {
> +       &peci_device_group,
> +       NULL
> +};
> --
> 2.31.1
>


From mark.kettenis at xs4all.nl  Fri Aug 27 12:15:11 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 27 Aug 2021 21:15:11 +0200 (CEST)
Subject: [PATCH v4 1/4] dt-bindings: interrupt-controller: Convert MSI
 controller to json-schema
In-Reply-To: <20210827171534.62380-2-mark.kettenis@xs4all.nl> (message from
 Mark Kettenis on Fri, 27 Aug 2021 19:15:26 +0200)
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-2-mark.kettenis@xs4all.nl>
Message-ID: <561420d562d3e421@bloch.sibelius.xs4all.nl>

> From: Mark Kettenis <mark.kettenis at xs4all.nl>
> Date: Fri, 27 Aug 2021 19:15:26 +0200
> 
> From: Mark Kettenis <kettenis at openbsd.org>
> 
> Split the MSI controller bindings from the MSI binding document
> into DT schema format using json-schema.
> 
> Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> ---
>  .../interrupt-controller/msi-controller.yaml  | 34 +++++++++++++++++++
>  .../bindings/pci/brcm,stb-pcie.yaml           |  1 +
>  .../bindings/pci/microchip,pcie-host.yaml     |  1 +
>  3 files changed, 36 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> new file mode 100644
> index 000000000000..5ed6cd46e2e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> @@ -0,0 +1,34 @@
> +# SPDX-License-Identifier: BSD-2-Clause

Noticed that checkpatch complains that the preferred license for new
binding schemas is (GPL-2.0-only OR BSD-2-Clause) so I'll fix that in
the next version.

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/msi-controller.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MSI controller
> +
> +maintainers:
> +  - Marc Zyngier <marc.zyngier at arm.com>
> +
> +description: |
> +  An MSI controller signals interrupts to a CPU when a write is made
> +  to an MMIO address by some master. An MSI controller may feature a
> +  number of doorbells.
> +
> +properties:
> +  "#msi-cells":
> +    description: |
> +      The number of cells in an msi-specifier, required if not zero.
> +
> +      Typically this will encode information related to sideband data,
> +      and will not encode doorbells or payloads as these can be
> +      configured dynamically.
> +
> +      The meaning of the msi-specifier is defined by the device tree
> +      binding of the specific MSI controller.
> +
> +  msi-controller:
> +    description:
> +      Identifies the node as an MSI controller.
> +    $ref: /schemas/types.yaml#/definitions/flag
> +
> +additionalProperties: true
> diff --git a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> index b9589a0daa5c..5c67976a8dc2 100644
> --- a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> @@ -88,6 +88,7 @@ required:
>  
>  allOf:
>    - $ref: /schemas/pci/pci-bus.yaml#
> +  - $ref: ../interrupt-controller/msi-controller.yaml#
>    - if:
>        properties:
>          compatible:
> diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> index fb95c276a986..684d9d036f48 100644
> --- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> +++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> @@ -11,6 +11,7 @@ maintainers:
>  
>  allOf:
>    - $ref: /schemas/pci/pci-bus.yaml#
> +  - $ref: ../interrupt-controller/msi-controller.yaml#
>  
>  properties:
>    compatible:
> -- 
> 2.32.0
> 
> 


From alexandre.belloni at bootlin.com  Fri Aug 27 13:17:45 2021
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Fri, 27 Aug 2021 22:17:45 +0200
Subject: [PATCH] ARM: at91: add basic support for new SoC lan966x
In-Reply-To: <20210827092623.10677-1-kavyasree.kotagiri@microchip.com>
References: <20210827092623.10677-1-kavyasree.kotagiri@microchip.com>
Message-ID: <YSlIaUMt0nS7MFoP@piout.net>

Hello Kavya,

Thank you for the patch and the upstreaming effort!

On 27/08/2021 14:56:23+0530, kavyasree.kotagiri at microchip.com wrote:
> From: Kavyasree Kotagiri <Kavyasree.Kotagiri at microchip.com>
> 
> This patch introduces Microchip LAN966X ARMv7 based SoC family
> of multiport gigabit AVB/TSN-capable ethernet switches.
> It supports two SKUs: 4-port LAN9662 with multiprotocol
> processing support and 8-port LAN9668 switch.
> 
> LAN966X includes copper and serial ethernet interfaces,
> peripheral interfaces such as PCIe, USB, TWI, SPI, UART, QSPI,
> SD/eMMC, Parallel Interface (PI) as well as synchronization
> and trigger inputs/outputs.
> 
> Signed-off-by: Kavya Sree Kotagiri <kavyasree.kotagiri at microchip.com>
> ---
>  arch/arm/mach-at91/Kconfig   | 13 +++++++++++++
>  arch/arm/mach-at91/Makefile  |  1 +
>  arch/arm/mach-at91/lan966x.c | 31 +++++++++++++++++++++++++++++++
>  3 files changed, 45 insertions(+)
>  create mode 100644 arch/arm/mach-at91/lan966x.c
> 
> diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
> index ccd7e80ce943..06cb425af761 100644
> --- a/arch/arm/mach-at91/Kconfig
> +++ b/arch/arm/mach-at91/Kconfig
> @@ -122,6 +122,14 @@ config SOC_SAM9X60
>  	help
>  	  Select this if you are using Microchip's SAM9X60 SoC
> 
> +config SOC_LAN966X
> +	bool "ARMv7 based Microchip LAN966X SoC family"
> +	depends on ARCH_MULTI_V7
> +	select SOC_LAN966
> +	select DW_APB_TIMER_OF
> +	help
> +	  This enables support for ARMv7 based Microchip LAN966X SoC family.
> +
>  comment "Clocksource driver selection"
> 
>  config ATMEL_CLOCKSOURCE_PIT
> @@ -188,6 +196,11 @@ config SOC_SAMA5
>  	select SOC_SAM_V7
>  	select SRAM if PM
> 
> +config SOC_LAN966
> +	bool
> +	select ARM_GIC
> +	select MEMORY
> +
>  config ATMEL_PM
>  	bool
> 
> diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
> index f565490f1b70..93cfd5b4e6d4 100644
> --- a/arch/arm/mach-at91/Makefile
> +++ b/arch/arm/mach-at91/Makefile
> @@ -6,6 +6,7 @@
>  # CPU-specific support
>  obj-$(CONFIG_SOC_AT91RM9200)	+= at91rm9200.o
>  obj-$(CONFIG_SOC_AT91SAM9)	+= at91sam9.o
> +obj-$(CONFIG_SOC_LAN966X)	+= lan966x.o
>  obj-$(CONFIG_SOC_SAM9X60)	+= sam9x60.o
>  obj-$(CONFIG_SOC_SAMA5)		+= sama5.o
>  obj-$(CONFIG_SOC_SAMV7)		+= samv7.o
> diff --git a/arch/arm/mach-at91/lan966x.c b/arch/arm/mach-at91/lan966x.c
> new file mode 100644
> index 000000000000..de689f854068
> --- /dev/null
> +++ b/arch/arm/mach-at91/lan966x.c
> @@ -0,0 +1,31 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Setup code for LAN966X
> + *
> + * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
> + *
> + */
> +
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +
> +#include <asm/mach/arch.h>
> +#include <asm/system_misc.h>
> +
> +#include "generic.h"
> +
> +static void __init lan966x_dt_device_init(void)
> +{
> +	of_platform_default_populate(NULL, NULL, NULL);

Are you sure this is needed? This is a workaround that is there on the
other platforms because of the at91 pinctrl driver. Ideally, you should
be able to boot without that. Can you confirm?

> +}
> +
> +static const char *const lan966x_dt_board_compat[] __initconst = {
> +	"microchip,lan966x",
> +	NULL
> +};
> +
> +DT_MACHINE_START(lan966x_dt, "Microchip LAN966X")
> +	/* Maintainer: Microchip */
> +	.init_machine	= lan966x_dt_device_init,
> +	.dt_compat	= lan966x_dt_board_compat,
> +MACHINE_END
> --
> 2.17.1
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From vladimir.oltean at nxp.com  Fri Aug 27 13:27:21 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Fri, 27 Aug 2021 23:27:21 +0300
Subject: [PATCH devicetree 1/2] dt-bindings: arm: fsl: document the LX2160A
 BlueBox 3 boards
Message-ID: <20210827202722.2567687-1-vladimir.oltean@nxp.com>

Document the compatible string for the LX2160A system that is part of
the BlueBox 3. Also add a separate compatible string for Rev A, since
technically it uses a different device tree.

Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 60f4862ba15e..d31464df987d 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -979,6 +979,8 @@ properties:
           - enum:
               - fsl,lx2160a-qds
               - fsl,lx2160a-rdb
+              - fsl,lx2160a-bluebox3
+              - fsl,lx2160a-bluebox3-rev-a
               - fsl,lx2162a-qds
           - const: fsl,lx2160a
 
-- 
2.25.1



From vladimir.oltean at nxp.com  Fri Aug 27 13:27:22 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Fri, 27 Aug 2021 23:27:22 +0300
Subject: [PATCH devicetree 2/2] arm64: dts: add device tree for the LX2160A on
 the NXP BlueBox3 board
In-Reply-To: <20210827202722.2567687-1-vladimir.oltean@nxp.com>
References: <20210827202722.2567687-1-vladimir.oltean@nxp.com>
Message-ID: <20210827202722.2567687-2-vladimir.oltean@nxp.com>

From: Wasim Khan <wasim.khan at nxp.com>

The NXP BlueBox3 is a prototyping board for high-performance autonomous
driving systems. It contains two Linux systems, on running on the
LX2160A and the other on the S32G2 SoC. This patch adds the device tree
support for the LX2160A SoC.

In terms of networking from the LX2160A's perspective, there are:

- 4 RJ45 10G ports using Aquantia copper PHYs which are attached
  directly to DPAA2 ports on the LX2160A

- 3 NXP SJA1110 automotive Ethernet switches. First two are managed by
  the LX2160A (each switch has a host port towards a dpmac), the third
  switch is managed by the S32G2. All 3 switches are interconnected
  through on-board SERDES lanes. The cascade ports between the 2
  switches managed by LX2160A form a DSA link, the cascade ports between
  the LX2160A and the S32G2 domain form user ports (the "to_sw3" net
  device).

- 2 RJ45 1G ports using Atheros copper PHYs which are attached directly
  to NXP SJA1110 switches

- 12 automotive 100base-T1 single-pair Ethernet ports routed from the
  SJA1110 internal PHY ports (TJA1103)

- One SGMII SERDES lane towards an internal connector, attached to one
  of the SJA1110 switch ports

On board rev A, the AR8035 RGMII PHY addresses were different than on
rev B and later. This patch introduces a separate device tree for rev A.
The main device tree is supposed to cover rev B and later.

Signed-off-by: Wasim Khan <wasim.khan at nxp.com>
Co-developed-by: Vabhav Sharma <vabhav.sharma at nxp.com>
Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>
Co-developed-by: Kuldeep Singh <kuldeep.singh at nxp.com>
Signed-off-by: Kuldeep Singh <kuldeep.singh at nxp.com>
Co-developed-by: Florin Chiculita <florinlaurentiu.chiculita at nxp.com>
Signed-off-by: Florin Chiculita <florinlaurentiu.chiculita at nxp.com>
Co-developed-by: Biwen Li <biwen.li at nxp.com>
Signed-off-by: Biwen Li <biwen.li at nxp.com>
Co-developed-by: Heinz Wrobel <Heinz.Wrobel at nxp.com>
Signed-off-by: Heinz Wrobel <Heinz.Wrobel at nxp.com>
Co-developed-by: Yangbo Lu <yangbo.lu at nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu at nxp.com>
Co-developed-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |   2 +
 .../freescale/fsl-lx2160a-bluebox3-rev-a.dts  |  34 +
 .../dts/freescale/fsl-lx2160a-bluebox3.dts    | 658 ++++++++++++++++++
 3 files changed, 694 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3-rev-a.dts
 create mode 100644 arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index db9e36ebe932..ecf74464705f 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -25,6 +25,8 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-bluebox3.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-bluebox3-rev-a.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-clearfog-cx.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-honeycomb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3-rev-a.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3-rev-a.dts
new file mode 100644
index 000000000000..15d273c93154
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3-rev-a.dts
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Device Tree file for LX2160A BLUEBOX3
+//
+// Copyright 2020-2021 NXP
+
+/dts-v1/;
+
+#include "fsl-lx2160a-bluebox3.dts"
+
+/ {
+	compatible = "fsl,lx2160a-bluebox3-rev-a", "fsl,lx2160a";
+};
+
+/* The RGMII PHYs have a different MDIO address */
+&emdio1 {
+	/delete-node/ ethernet-phy at 5;
+
+	sw1_mii3_phy: ethernet-phy at 1 {
+		/* AR8035 */
+		compatible = "ethernet-phy-id004d.d072";
+		reg = <0x1>;
+		interrupts-extended = <&extirq 6 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	/delete-node/ ethernet-phy at 6;
+
+	sw2_mii3_phy: ethernet-phy at 2 {
+		/* AR8035 */
+		compatible = "ethernet-phy-id004d.d072";
+		reg = <0x2>;
+		interrupts-extended = <&extirq 7 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts
new file mode 100644
index 000000000000..be7d01630a6f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts
@@ -0,0 +1,658 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Device Tree file for LX2160A BLUEBOX3
+//
+// Copyright 2020-2021 NXP
+
+/dts-v1/;
+
+#include "fsl-lx2160a.dtsi"
+
+/ {
+	model = "NXP Layerscape LX2160ABLUEBOX3";
+	compatible = "fsl,lx2160a-bluebox3", "fsl,lx2160a";
+
+	aliases {
+		crypto = &crypto;
+		serial0 = &uart0;
+		mmc0 = &esdhc0;
+		mmc1 = &esdhc1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	sb_3v3: regulator-sb3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "MC34717-3.3VSB";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&can0 {
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <5000000>;
+	};
+};
+
+&can1 {
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <5000000>;
+	};
+};
+
+&crypto {
+	status = "okay";
+};
+
+&dpmac5 {
+	phy-handle = <&aqr113c_phy1>;
+	phy-mode = "usxgmii";
+	managed = "in-band-status";
+};
+
+&dpmac6 {
+	phy-handle = <&aqr113c_phy2>;
+	phy-mode = "usxgmii";
+	managed = "in-band-status";
+};
+
+&dpmac9 {
+	phy-handle = <&aqr113c_phy3>;
+	phy-mode = "usxgmii";
+	managed = "in-band-status";
+};
+
+&dpmac10 {
+	phy-handle = <&aqr113c_phy4>;
+	phy-mode = "usxgmii";
+	managed = "in-band-status";
+};
+
+&dpmac17 {
+	phy-mode = "rgmii";
+	status = "okay";
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&dpmac18 {
+	phy-mode = "rgmii";
+	status = "okay";
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&emdio1 {
+	status = "okay";
+
+	aqr113c_phy2: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c45";
+		reg = <0x0>;
+		/* IRQ_10G_PHY2 */
+		interrupts-extended = <&extirq 3 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	aqr113c_phy1: ethernet-phy at 8 {
+		compatible = "ethernet-phy-ieee802.3-c45";
+		reg = <0x8>;
+		/* IRQ_10G_PHY1 */
+		interrupts-extended = <&extirq 2 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	sw1_mii3_phy: ethernet-phy at 5 {
+		/* AR8035 */
+		compatible = "ethernet-phy-id004d.d072";
+		reg = <0x5>;
+		interrupts-extended = <&extirq 6 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	sw2_mii3_phy: ethernet-phy at 6 {
+		/* AR8035 */
+		compatible = "ethernet-phy-id004d.d072";
+		reg = <0x6>;
+		interrupts-extended = <&extirq 7 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&emdio2 {
+	status = "okay";
+
+	aqr113c_phy4: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c45";
+		reg = <0x0>;
+		/* IRQ_10G_PHY4 */
+		interrupts-extended = <&extirq 5 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	aqr113c_phy3: ethernet-phy at 8 {
+		compatible = "ethernet-phy-ieee802.3-c45";
+		reg = <0x8>;
+		/* IRQ_10G_PHY3 */
+		interrupts-extended = <&extirq 4 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&esdhc0 {
+	sd-uhs-sdr104;
+	sd-uhs-sdr50;
+	sd-uhs-sdr25;
+	sd-uhs-sdr12;
+	status = "okay";
+};
+
+&esdhc1 {
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	bus-width = <8>;
+	status = "okay";
+};
+
+&fspi {
+	status = "okay";
+
+	mt35xu512aba0: flash at 0 {
+		compatible = "jedec,spi-nor";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0>;
+		m25p,fast-read;
+		spi-max-frequency = <50000000>;
+		spi-rx-bus-width = <8>;
+		spi-tx-bus-width = <8>;
+	};
+
+	mt35xu512aba1: flash at 1 {
+		compatible = "jedec,spi-nor";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <1>;
+		m25p,fast-read;
+		spi-max-frequency = <50000000>;
+		spi-rx-bus-width = <8>;
+		spi-tx-bus-width = <8>;
+	};
+};
+
+&i2c0 {
+	status = "okay";
+
+	i2c-mux at 77 {
+		compatible = "nxp,pca9547";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c at 2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x2>;
+
+			power-monitor at 40 {
+				compatible = "ti,ina220";
+				reg = <0x40>;
+				shunt-resistor = <500>;
+			};
+		};
+
+		i2c at 3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x3>;
+
+			temp2: temperature-sensor at 48 {
+				compatible = "nxp,sa56004";
+				reg = <0x48>;
+				vcc-supply = <&sb_3v3>;
+				#thermal-sensor-cells = <1>;
+			};
+
+			temp1: temperature-sensor at 4c {
+				compatible = "nxp,sa56004";
+				reg = <0x4c>;
+				vcc-supply = <&sb_3v3>;
+				#thermal-sensor-cells = <1>;
+			};
+		};
+
+		i2c at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x4>;
+
+			rtc at 51 {
+				compatible = "nxp,pcf2129";
+				reg = <0x51>;
+				interrupts-extended = <&extirq 11 IRQ_TYPE_LEVEL_LOW>;
+			};
+		};
+
+		i2c at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x7>;
+
+			i2c-mux at 75 {
+				compatible = "nxp,pca9547";
+				reg = <0x75>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				i2c at 0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x0>;
+
+					spi_bridge: spi at 28 {
+						compatible = "nxp,sc18is602b";
+						reg = <0x28>;
+						#address-cells = <1>;
+						#size-cells = <0>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&i2c5 {
+	status = "okay";
+
+	i2c-mux at 77 {
+		compatible = "nxp,pca9846";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c at 1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x1>;
+
+			/* The I2C multiplexer and temperature sensors are on
+			 * the T6 riser card.
+			 */
+			i2c-mux at 70 {
+				compatible = "nxp,pca9548";
+				reg = <0x70>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				i2c at 6 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x6>;
+
+					q12: temperature-sensor at 4c {
+						compatible = "nxp,sa56004";
+						reg = <0x4c>;
+						vcc-supply = <&sb_3v3>;
+						#thermal-sensor-cells = <1>;
+					};
+				};
+
+				i2c at 7 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x7>;
+
+					q11: temperature-sensor at 4c {
+						compatible = "nxp,sa56004";
+						reg = <0x4c>;
+						vcc-supply = <&sb_3v3>;
+						#thermal-sensor-cells = <1>;
+					};
+
+					q13: temperature-sensor at 48 {
+						compatible = "nxp,sa56004";
+						reg = <0x48>;
+						vcc-supply = <&sb_3v3>;
+						#thermal-sensor-cells = <1>;
+					};
+
+					q14: temperature-sensor at 4a {
+						compatible = "nxp,sa56004";
+						reg = <0x4a>;
+						vcc-supply = <&sb_3v3>;
+						#thermal-sensor-cells = <1>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&pcs_mdio5 {
+	status = "okay";
+};
+
+&pcs_mdio6 {
+	status = "okay";
+};
+
+&pcs_mdio9 {
+	status = "okay";
+};
+
+&pcs_mdio10 {
+	status = "okay";
+};
+
+&spi_bridge {
+	sw1: ethernet-switch at 0 {
+		compatible = "nxp,sja1110a";
+		reg = <0>;
+		spi-max-frequency = <4000000>;
+		spi-cpol;
+		dsa,member = <0 0>;
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* Microcontroller port */
+			port at 0 {
+				reg = <0>;
+				status = "disabled";
+			};
+
+			/* SW1_P1 */
+			port at 1 {
+				reg = <1>;
+				label = "con_2x20";
+				phy-mode = "sgmii";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			port at 2 {
+				reg = <2>;
+				ethernet = <&dpmac17>;
+				phy-mode = "rgmii-id";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			port at 3 {
+				reg = <3>;
+				label = "1ge_p1";
+				phy-mode = "rgmii-id";
+				phy-handle = <&sw1_mii3_phy>;
+			};
+
+			sw1p4: port at 4 {
+				reg = <4>;
+				link = <&sw2p1>;
+				phy-mode = "sgmii";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			port at 5 {
+				reg = <5>;
+				label = "trx1";
+				phy-mode = "internal";
+				phy-handle = <&sw1_port5_base_t1_phy>;
+			};
+
+			port at 6 {
+				reg = <6>;
+				label = "trx2";
+				phy-mode = "internal";
+				phy-handle = <&sw1_port6_base_t1_phy>;
+			};
+
+			port at 7 {
+				reg = <7>;
+				label = "trx3";
+				phy-mode = "internal";
+				phy-handle = <&sw1_port7_base_t1_phy>;
+			};
+
+			port at 8 {
+				reg = <8>;
+				label = "trx4";
+				phy-mode = "internal";
+				phy-handle = <&sw1_port8_base_t1_phy>;
+			};
+
+			port at 9 {
+				reg = <9>;
+				label = "trx5";
+				phy-mode = "internal";
+				phy-handle = <&sw1_port9_base_t1_phy>;
+			};
+
+			port at a {
+				reg = <10>;
+				label = "trx6";
+				phy-mode = "internal";
+				phy-handle = <&sw1_port10_base_t1_phy>;
+			};
+		};
+
+		mdios {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mdio at 0 {
+				compatible = "nxp,sja1110-base-t1-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+
+				sw1_port5_base_t1_phy: ethernet-phy at 1 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x1>;
+				};
+
+				sw1_port6_base_t1_phy: ethernet-phy at 2 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x2>;
+				};
+
+				sw1_port7_base_t1_phy: ethernet-phy at 3 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x3>;
+				};
+
+				sw1_port8_base_t1_phy: ethernet-phy at 4 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x4>;
+				};
+
+				sw1_port9_base_t1_phy: ethernet-phy at 5 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x5>;
+				};
+
+				sw1_port10_base_t1_phy: ethernet-phy at 6 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x6>;
+				};
+			};
+		};
+	};
+
+	sw2: ethernet-switch at 2 {
+		compatible = "nxp,sja1110a";
+		reg = <2>;
+		spi-max-frequency = <4000000>;
+		spi-cpol;
+		dsa,member = <0 1>;
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* Microcontroller port */
+			port at 0 {
+				reg = <0>;
+				status = "disabled";
+			};
+
+			sw2p1: port at 1 {
+				reg = <1>;
+				link = <&sw1p4>;
+				phy-mode = "sgmii";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			port at 2 {
+				reg = <2>;
+				ethernet = <&dpmac18>;
+				phy-mode = "rgmii-id";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+
+			port at 3 {
+				reg = <3>;
+				label = "1ge_p2";
+				phy-mode = "rgmii-id";
+				phy-handle = <&sw2_mii3_phy>;
+			};
+
+			port at 4 {
+				reg = <4>;
+				label = "to_sw3";
+				phy-mode = "2500base-x";
+
+				fixed-link {
+					speed = <2500>;
+					full-duplex;
+				};
+			};
+
+			port at 5 {
+				reg = <5>;
+				label = "trx7";
+				phy-mode = "internal";
+				phy-handle = <&sw2_port5_base_t1_phy>;
+			};
+
+			port at 6 {
+				reg = <6>;
+				label = "trx8";
+				phy-mode = "internal";
+				phy-handle = <&sw2_port6_base_t1_phy>;
+			};
+
+			port at 7 {
+				reg = <7>;
+				label = "trx9";
+				phy-mode = "internal";
+				phy-handle = <&sw2_port7_base_t1_phy>;
+			};
+
+			port at 8 {
+				reg = <8>;
+				label = "trx10";
+				phy-mode = "internal";
+				phy-handle = <&sw2_port8_base_t1_phy>;
+			};
+
+			port at 9 {
+				reg = <9>;
+				label = "trx11";
+				phy-mode = "internal";
+				phy-handle = <&sw2_port9_base_t1_phy>;
+			};
+
+			port at a {
+				reg = <10>;
+				label = "trx12";
+				phy-mode = "internal";
+				phy-handle = <&sw2_port10_base_t1_phy>;
+			};
+		};
+
+		mdios {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mdio at 0 {
+				compatible = "nxp,sja1110-base-t1-mdio";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0>;
+
+				sw2_port5_base_t1_phy: ethernet-phy at 1 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x1>;
+				};
+
+				sw2_port6_base_t1_phy: ethernet-phy at 2 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x2>;
+				};
+
+				sw2_port7_base_t1_phy: ethernet-phy at 3 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x3>;
+				};
+
+				sw2_port8_base_t1_phy: ethernet-phy at 4 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x4>;
+				};
+
+				sw2_port9_base_t1_phy: ethernet-phy at 5 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x5>;
+				};
+
+				sw2_port10_base_t1_phy: ethernet-phy at 6 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x6>;
+				};
+			};
+		};
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
-- 
2.25.1



From alyssa at rosenzweig.io  Fri Aug 27 13:09:13 2021
From: alyssa at rosenzweig.io (Alyssa Rosenzweig)
Date: Fri, 27 Aug 2021 16:09:13 -0400
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <56142087154d4d9e@bloch.sibelius.xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-5-mark.kettenis@xs4all.nl>
 <YSkoHw3dZrW5Qnjf@rosenzweig.io>
 <56142087154d4d9e@bloch.sibelius.xs4all.nl>
Message-ID: <YSlGaVSaqphqXbBr@sunset>

> > > Clock references and DART (IOMMU) references are left out at the
> > > moment and will be added once the appropriate bindings have been
> > > settled upon.
> > > 
> > 
> > DART is in mainline .... is there a PCIe specific issue?
> 
> True.  I don't expect 4/4 to be merged as part of this series though
> as it will need to go through marcan's tree.  It is mostly there to
> show what the device tree will look like.

Fair enough. When it does get merged it'll need the updates from my my
PCIe series (v2). It looks like the only change needed for the commit
proposed there is updating the msi-ranges format. Hopefully the solution
proposed here is acceptable to both robh and maz so we can move forward
with this :-)


From dan.j.williams at intel.com  Fri Aug 27 14:19:59 2021
From: dan.j.williams at intel.com (Dan Williams)
Date: Fri, 27 Aug 2021 14:19:59 -0700
Subject: [PATCH v2 10/15] peci: Add support for PECI device drivers
In-Reply-To: <20210803113134.2262882-11-iwona.winiarska@intel.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-11-iwona.winiarska@intel.com>
Message-ID: <CAPcyv4iUeCcBuMk8WskLnP6K_FRKPSN3N45cyey=H-R5X08M4g@mail.gmail.com>

On Tue, Aug 3, 2021 at 4:36 AM Iwona Winiarska
<iwona.winiarska at intel.com> wrote:
>
> Here we're adding support for PECI device drivers, which unlike PECI

s/Here we're adding/Add/

> controller drivers are actually able to provide functionalities to
> userspace.

>
> We're also extending peci_request API to allow querying more details

s/We're also extending/Also, extend/

...for the most part imperative tense is the preferred tense, by
upstream maintainers, for changelogs.

> about PECI device (e.g. model/family), that's going to be used to find
> a compatible peci_driver.
>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> ---
>  drivers/peci/Kconfig    |   1 +
>  drivers/peci/core.c     |  49 +++++++++
>  drivers/peci/device.c   | 105 ++++++++++++++++++++
>  drivers/peci/internal.h |  75 ++++++++++++++
>  drivers/peci/request.c  | 214 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/peci.h    |  19 ++++
>  lib/Kconfig             |   2 +-
>  7 files changed, 464 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
> index 99279df97a78..1d0532e3a801 100644
> --- a/drivers/peci/Kconfig
> +++ b/drivers/peci/Kconfig
> @@ -2,6 +2,7 @@
>
>  menuconfig PECI
>         tristate "PECI support"
> +       select GENERIC_LIB_X86

GENERIC_LIB_X86 has dependencies, so this 'select' will make kbuild
unhappy when that dependency is not met. Given that this symbol
already selected by X86, it seems this just wants a "depends on
GENERIC_LIB_X86".

>         help
>           The Platform Environment Control Interface (PECI) is an interface
>           that provides a communication channel to Intel processors and
> diff --git a/drivers/peci/core.c b/drivers/peci/core.c
> index c473acb3c2a0..33c07920493d 100644
> --- a/drivers/peci/core.c
> +++ b/drivers/peci/core.c
> @@ -157,8 +157,57 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
>  }
>  EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
>
> +static const struct peci_device_id *
> +peci_bus_match_device_id(const struct peci_device_id *id, struct peci_device *device)
> +{
> +       while (id->family != 0) {
> +               if (id->family == device->info.family &&
> +                   id->model == device->info.model)
> +                       return id;
> +               id++;
> +       }
> +
> +       return NULL;
> +}
> +
> +static int peci_bus_device_match(struct device *dev, struct device_driver *drv)
> +{
> +       struct peci_device *device = to_peci_device(dev);
> +       struct peci_driver *peci_drv = to_peci_driver(drv);
> +
> +       if (dev->type != &peci_device_type)
> +               return 0;
> +
> +       if (peci_bus_match_device_id(peci_drv->id_table, device))
> +               return 1;

Save a couple lines and do:

    return peci_bus_match_device_id(...)

> +
> +       return 0;
> +}
> +
> +static int peci_bus_device_probe(struct device *dev)
> +{
> +       struct peci_device *device = to_peci_device(dev);
> +       struct peci_driver *driver = to_peci_driver(dev->driver);
> +
> +       return driver->probe(device, peci_bus_match_device_id(driver->id_table, device));
> +}
> +
> +static int peci_bus_device_remove(struct device *dev)

Note, in linux-next this prototype has changed to:

    void (*remove)(struct device *dev);

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/include/linux/device/bus.h


> +{
> +       struct peci_device *device = to_peci_device(dev);
> +       struct peci_driver *driver = to_peci_driver(dev->driver);
> +
> +       if (driver->remove)
> +               driver->remove(device);
> +
> +       return 0;
> +}
> +
>  struct bus_type peci_bus_type = {
>         .name           = "peci",
> +       .match          = peci_bus_device_match,
> +       .probe          = peci_bus_device_probe,
> +       .remove         = peci_bus_device_remove,
>         .bus_groups     = peci_bus_groups,
>  };
>
> diff --git a/drivers/peci/device.c b/drivers/peci/device.c
> index d77d9dabd51e..a78c02399574 100644
> --- a/drivers/peci/device.c
> +++ b/drivers/peci/device.c
> @@ -1,11 +1,85 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  // Copyright (c) 2018-2021 Intel Corporation
>
> +#include <linux/bitfield.h>
>  #include <linux/peci.h>
>  #include <linux/slab.h>
> +#include <linux/x86/cpu.h>
>
>  #include "internal.h"
>
> +#define REVISION_NUM_MASK GENMASK(15, 8)
> +static int peci_get_revision(struct peci_device *device, u8 *revision)
> +{
> +       struct peci_request *req;
> +       u64 dib;
> +
> +       req = peci_get_dib(device);

I would expect peci_get_dib() to return @dib.

> +       if (IS_ERR(req))
> +               return PTR_ERR(req);
> +
> +       /*
> +        * PECI device may be in a state where it is unable to return a proper
> +        * DIB, in which case it returns 0 as DIB value.
> +        * Let's treat this as an error to avoid carrying on with the detection
> +        * using invalid revision.
> +        */
> +       dib = peci_request_data_dib(req);

I would expect peci_request_data_dib() to make a request.

A stack allocated peci_request passed to peci_get_dib() that returns
an error code would seem to be cleaner than this current organization.

> +       if (dib == 0) {
> +               peci_request_free(req);
> +               return -EIO;
> +       }
> +
> +       *revision = FIELD_GET(REVISION_NUM_MASK, dib);
> +
> +       peci_request_free(req);
> +
> +       return 0;
> +}
> +
> +static int peci_get_cpu_id(struct peci_device *device, u32 *cpu_id)
> +{
> +       struct peci_request *req;
> +       int ret;
> +
> +       req = peci_pkg_cfg_readl(device, PECI_PCS_PKG_ID, PECI_PKG_ID_CPU_ID);
> +       if (IS_ERR(req))
> +               return PTR_ERR(req);
> +
> +       ret = peci_request_status(req);
> +       if (ret)
> +               goto out_req_free;
> +
> +       *cpu_id = peci_request_data_readl(req);
> +out_req_free:
> +       peci_request_free(req);
> +
> +       return ret;
> +}
> +
> +static int peci_device_info_init(struct peci_device *device)
> +{
> +       u8 revision;
> +       u32 cpu_id;
> +       int ret;
> +
> +       ret = peci_get_cpu_id(device, &cpu_id);
> +       if (ret)
> +               return ret;
> +
> +       device->info.family = x86_family(cpu_id);
> +       device->info.model = x86_model(cpu_id);
> +
> +       ret = peci_get_revision(device, &revision);
> +       if (ret)
> +               return ret;
> +       device->info.peci_revision = revision;
> +
> +       device->info.socket_id = device->addr - PECI_BASE_ADDR;
> +
> +       return 0;
> +}
> +
>  static int peci_detect(struct peci_controller *controller, u8 addr)
>  {
>         struct peci_request *req;
> @@ -79,6 +153,10 @@ int peci_device_create(struct peci_controller *controller, u8 addr)
>         device->dev.bus = &peci_bus_type;
>         device->dev.type = &peci_device_type;
>
> +       ret = peci_device_info_init(device);
> +       if (ret)
> +               goto err_free;
> +
>         ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
>         if (ret)
>                 goto err_free;
> @@ -102,6 +180,33 @@ void peci_device_destroy(struct peci_device *device)
>         device_unregister(&device->dev);
>  }
>
> +int __peci_driver_register(struct peci_driver *driver, struct module *owner,
> +                          const char *mod_name)
> +{
> +       driver->driver.bus = &peci_bus_type;
> +       driver->driver.owner = owner;
> +       driver->driver.mod_name = mod_name;
> +
> +       if (!driver->probe) {
> +               pr_err("peci: trying to register driver without probe callback\n");
> +               return -EINVAL;
> +       }
> +
> +       if (!driver->id_table) {
> +               pr_err("peci: trying to register driver without device id table\n");
> +               return -EINVAL;
> +       }
> +
> +       return driver_register(&driver->driver);
> +}
> +EXPORT_SYMBOL_NS_GPL(__peci_driver_register, PECI);
> +
> +void peci_driver_unregister(struct peci_driver *driver)
> +{
> +       driver_unregister(&driver->driver);
> +}
> +EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, PECI);
> +
>  static void peci_device_release(struct device *dev)
>  {
>         struct peci_device *device = to_peci_device(dev);
> diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
> index 978e12c8e1d3..d661e1b65694 100644
> --- a/drivers/peci/internal.h
> +++ b/drivers/peci/internal.h
> @@ -19,6 +19,34 @@ struct peci_request;
>  struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len);
>  void peci_request_free(struct peci_request *req);
>
> +int peci_request_status(struct peci_request *req);
> +u64 peci_request_data_dib(struct peci_request *req);
> +
> +u8 peci_request_data_readb(struct peci_request *req);
> +u16 peci_request_data_readw(struct peci_request *req);
> +u32 peci_request_data_readl(struct peci_request *req);
> +u64 peci_request_data_readq(struct peci_request *req);
> +
> +struct peci_request *peci_get_dib(struct peci_device *device);
> +struct peci_request *peci_get_temp(struct peci_device *device);
> +
> +struct peci_request *peci_pkg_cfg_readb(struct peci_device *device, u8 index, u16 param);
> +struct peci_request *peci_pkg_cfg_readw(struct peci_device *device, u8 index, u16 param);
> +struct peci_request *peci_pkg_cfg_readl(struct peci_device *device, u8 index, u16 param);
> +struct peci_request *peci_pkg_cfg_readq(struct peci_device *device, u8 index, u16 param);
> +
> +/**
> + * struct peci_device_id - PECI device data to match
> + * @data: pointer to driver private data specific to device
> + * @family: device family
> + * @model: device model
> + */
> +struct peci_device_id {
> +       const void *data;
> +       u16 family;
> +       u8 model;
> +};
> +
>  extern struct device_type peci_device_type;
>  extern const struct attribute_group *peci_device_groups[];
>
> @@ -28,6 +56,53 @@ void peci_device_destroy(struct peci_device *device);
>  extern struct bus_type peci_bus_type;
>  extern const struct attribute_group *peci_bus_groups[];
>
> +/**
> + * struct peci_driver - PECI driver
> + * @driver: inherit device driver
> + * @probe: probe callback
> + * @remove: remove callback
> + * @id_table: PECI device match table to decide which device to bind
> + */
> +struct peci_driver {
> +       struct device_driver driver;
> +       int (*probe)(struct peci_device *device, const struct peci_device_id *id);
> +       void (*remove)(struct peci_device *device);
> +       const struct peci_device_id *id_table;
> +};
> +
> +static inline struct peci_driver *to_peci_driver(struct device_driver *d)
> +{
> +       return container_of(d, struct peci_driver, driver);
> +}
> +
> +int __peci_driver_register(struct peci_driver *driver, struct module *owner,
> +                          const char *mod_name);
> +/**
> + * peci_driver_register() - register PECI driver
> + * @driver: the driver to be registered
> + * @owner: owner module of the driver being registered
> + * @mod_name: module name string
> + *
> + * PECI drivers that don't need to do anything special in module init should
> + * use the convenience "module_peci_driver" macro instead
> + *
> + * Return: zero on success, else a negative error code.
> + */
> +#define peci_driver_register(driver) \
> +       __peci_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
> +void peci_driver_unregister(struct peci_driver *driver);
> +
> +/**
> + * module_peci_driver() - helper macro for registering a modular PECI driver
> + * @__peci_driver: peci_driver struct
> + *
> + * Helper macro for PECI drivers which do not do anything special in module
> + * init/exit. This eliminates a lot of boilerplate. Each module may only
> + * use this macro once, and calling it replaces module_init() and module_exit()
> + */
> +#define module_peci_driver(__peci_driver) \
> +       module_driver(__peci_driver, peci_driver_register, peci_driver_unregister)
> +
>  extern struct device_type peci_controller_type;
>
>  int peci_controller_scan_devices(struct peci_controller *controller);
> diff --git a/drivers/peci/request.c b/drivers/peci/request.c
> index 81b567bc7b87..fe032d5a5e1b 100644
> --- a/drivers/peci/request.c
> +++ b/drivers/peci/request.c
> @@ -1,13 +1,140 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  // Copyright (c) 2021 Intel Corporation
>
> +#include <linux/bug.h>
>  #include <linux/export.h>
>  #include <linux/peci.h>
>  #include <linux/slab.h>
>  #include <linux/types.h>
>
> +#include <asm/unaligned.h>
> +
>  #include "internal.h"
>
> +#define PECI_GET_DIB_CMD               0xf7
> +#define  PECI_GET_DIB_WR_LEN           1
> +#define  PECI_GET_DIB_RD_LEN           8
> +
> +#define PECI_RDPKGCFG_CMD              0xa1
> +#define  PECI_RDPKGCFG_WR_LEN          5
> +#define  PECI_RDPKGCFG_RD_LEN_BASE     1
> +#define PECI_WRPKGCFG_CMD              0xa5
> +#define  PECI_WRPKGCFG_WR_LEN_BASE     6
> +#define  PECI_WRPKGCFG_RD_LEN          1
> +
> +/* Device Specific Completion Code (CC) Definition */
> +#define PECI_CC_SUCCESS                                0x40
> +#define PECI_CC_NEED_RETRY                     0x80
> +#define PECI_CC_OUT_OF_RESOURCE                        0x81
> +#define PECI_CC_UNAVAIL_RESOURCE               0x82
> +#define PECI_CC_INVALID_REQ                    0x90
> +#define PECI_CC_MCA_ERROR                      0x91
> +#define PECI_CC_CATASTROPHIC_MCA_ERROR         0x93
> +#define PECI_CC_FATAL_MCA_ERROR                        0x94
> +#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB                0x98
> +#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB_IERR   0x9B
> +#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB_MCA    0x9C
> +
> +#define PECI_RETRY_BIT                 BIT(0)
> +
> +#define PECI_RETRY_TIMEOUT             msecs_to_jiffies(700)
> +#define PECI_RETRY_INTERVAL_MIN                msecs_to_jiffies(1)
> +#define PECI_RETRY_INTERVAL_MAX                msecs_to_jiffies(128)
> +
> +static u8 peci_request_data_cc(struct peci_request *req)
> +{
> +       return req->rx.buf[0];
> +}
> +
> +/**
> + * peci_request_status() - return -errno based on PECI completion code
> + * @req: the PECI request that contains response data with completion code
> + *
> + * It can't be used for Ping(), GetDIB() and GetTemp() - for those commands we
> + * don't expect completion code in the response.
> + *
> + * Return: -errno
> + */
> +int peci_request_status(struct peci_request *req)
> +{
> +       u8 cc = peci_request_data_cc(req);
> +
> +       if (cc != PECI_CC_SUCCESS)
> +               dev_dbg(&req->device->dev, "ret: %#02x\n", cc);
> +
> +       switch (cc) {
> +       case PECI_CC_SUCCESS:
> +               return 0;
> +       case PECI_CC_NEED_RETRY:
> +       case PECI_CC_OUT_OF_RESOURCE:
> +       case PECI_CC_UNAVAIL_RESOURCE:
> +               return -EAGAIN;
> +       case PECI_CC_INVALID_REQ:
> +               return -EINVAL;
> +       case PECI_CC_MCA_ERROR:
> +       case PECI_CC_CATASTROPHIC_MCA_ERROR:
> +       case PECI_CC_FATAL_MCA_ERROR:
> +       case PECI_CC_PARITY_ERR_GPSB_OR_PMSB:
> +       case PECI_CC_PARITY_ERR_GPSB_OR_PMSB_IERR:
> +       case PECI_CC_PARITY_ERR_GPSB_OR_PMSB_MCA:
> +               return -EIO;
> +       }
> +
> +       WARN_ONCE(1, "Unknown PECI completion code: %#02x\n", cc);
> +
> +       return -EIO;
> +}
> +EXPORT_SYMBOL_NS_GPL(peci_request_status, PECI);
> +
> +static int peci_request_xfer(struct peci_request *req)
> +{
> +       struct peci_device *device = req->device;
> +       struct peci_controller *controller = to_peci_controller(device->dev.parent);
> +       int ret;
> +
> +       mutex_lock(&controller->bus_lock);
> +       ret = controller->ops->xfer(controller, device->addr, req);
> +       mutex_unlock(&controller->bus_lock);
> +
> +       return ret;
> +}
> +
> +static int peci_request_xfer_retry(struct peci_request *req)
> +{
> +       long wait_interval = PECI_RETRY_INTERVAL_MIN;
> +       struct peci_device *device = req->device;
> +       struct peci_controller *controller = to_peci_controller(device->dev.parent);
> +       unsigned long start = jiffies;
> +       int ret;
> +
> +       /* Don't try to use it for ping */
> +       if (WARN_ON(!req->rx.buf))
> +               return 0;
> +
> +       do {
> +               ret = peci_request_xfer(req);
> +               if (ret) {
> +                       dev_dbg(&controller->dev, "xfer error: %d\n", ret);
> +                       return ret;
> +               }
> +
> +               if (peci_request_status(req) != -EAGAIN)
> +                       return 0;
> +
> +               /* Set the retry bit to indicate a retry attempt */
> +               req->tx.buf[1] |= PECI_RETRY_BIT;
> +
> +               if (schedule_timeout_interruptible(wait_interval))
> +                       return -ERESTARTSYS;
> +
> +               wait_interval = min_t(long, wait_interval * 2, PECI_RETRY_INTERVAL_MAX);
> +       } while (time_before(jiffies, start + PECI_RETRY_TIMEOUT));
> +
> +       dev_dbg(&controller->dev, "request timed out\n");
> +
> +       return -ETIMEDOUT;
> +}
> +
>  /**
>   * peci_request_alloc() - allocate &struct peci_requests
>   * @device: PECI device to which request is going to be sent
> @@ -48,3 +175,90 @@ void peci_request_free(struct peci_request *req)
>         kfree(req);
>  }
>  EXPORT_SYMBOL_NS_GPL(peci_request_free, PECI);
> +
> +struct peci_request *peci_get_dib(struct peci_device *device)
> +{
> +       struct peci_request *req;
> +       int ret;
> +
> +       req = peci_request_alloc(device, PECI_GET_DIB_WR_LEN, PECI_GET_DIB_RD_LEN);
> +       if (!req)
> +               return ERR_PTR(-ENOMEM);
> +
> +       req->tx.buf[0] = PECI_GET_DIB_CMD;
> +
> +       ret = peci_request_xfer(req);
> +       if (ret) {
> +               peci_request_free(req);
> +               return ERR_PTR(ret);
> +       }
> +
> +       return req;
> +}
> +EXPORT_SYMBOL_NS_GPL(peci_get_dib, PECI);
> +
> +static struct peci_request *
> +__pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
> +{
> +       struct peci_request *req;
> +       int ret;
> +
> +       req = peci_request_alloc(device, PECI_RDPKGCFG_WR_LEN, PECI_RDPKGCFG_RD_LEN_BASE + len);
> +       if (!req)
> +               return ERR_PTR(-ENOMEM);
> +
> +       req->tx.buf[0] = PECI_RDPKGCFG_CMD;
> +       req->tx.buf[1] = 0;
> +       req->tx.buf[2] = index;
> +       put_unaligned_le16(param, &req->tx.buf[3]);
> +
> +       ret = peci_request_xfer_retry(req);
> +       if (ret) {
> +               peci_request_free(req);
> +               return ERR_PTR(ret);
> +       }
> +
> +       return req;
> +}
> +
> +u8 peci_request_data_readb(struct peci_request *req)
> +{
> +       return req->rx.buf[1];
> +}
> +EXPORT_SYMBOL_NS_GPL(peci_request_data_readb, PECI);
> +
> +u16 peci_request_data_readw(struct peci_request *req)
> +{
> +       return get_unaligned_le16(&req->rx.buf[1]);
> +}
> +EXPORT_SYMBOL_NS_GPL(peci_request_data_readw, PECI);
> +
> +u32 peci_request_data_readl(struct peci_request *req)
> +{
> +       return get_unaligned_le32(&req->rx.buf[1]);
> +}
> +EXPORT_SYMBOL_NS_GPL(peci_request_data_readl, PECI);
> +
> +u64 peci_request_data_readq(struct peci_request *req)
> +{
> +       return get_unaligned_le64(&req->rx.buf[1]);
> +}
> +EXPORT_SYMBOL_NS_GPL(peci_request_data_readq, PECI);
> +
> +u64 peci_request_data_dib(struct peci_request *req)
> +{
> +       return get_unaligned_le64(&req->rx.buf[0]);
> +}
> +EXPORT_SYMBOL_NS_GPL(peci_request_data_dib, PECI);
> +
> +#define __read_pkg_config(x, type) \
> +struct peci_request *peci_pkg_cfg_##x(struct peci_device *device, u8 index, u16 param) \
> +{ \
> +       return __pkg_cfg_read(device, index, param, sizeof(type)); \
> +} \
> +EXPORT_SYMBOL_NS_GPL(peci_pkg_cfg_##x, PECI)
> +
> +__read_pkg_config(readb, u8);
> +__read_pkg_config(readw, u16);
> +__read_pkg_config(readl, u32);
> +__read_pkg_config(readq, u64);
> diff --git a/include/linux/peci.h b/include/linux/peci.h
> index 26e0a4e73b50..dcf1c53f4e40 100644
> --- a/include/linux/peci.h
> +++ b/include/linux/peci.h
> @@ -14,6 +14,14 @@
>   */
>  #define PECI_REQUEST_MAX_BUF_SIZE 32
>
> +#define PECI_PCS_PKG_ID                        0  /* Package Identifier Read */
> +#define  PECI_PKG_ID_CPU_ID            0x0000  /* CPUID Info */
> +#define  PECI_PKG_ID_PLATFORM_ID       0x0001  /* Platform ID */
> +#define  PECI_PKG_ID_DEVICE_ID         0x0002  /* Uncore Device ID */
> +#define  PECI_PKG_ID_MAX_THREAD_ID     0x0003  /* Max Thread ID */
> +#define  PECI_PKG_ID_MICROCODE_REV     0x0004  /* CPU Microcode Update Revision */
> +#define  PECI_PKG_ID_MCA_ERROR_LOG     0x0005  /* Machine Check Status */
> +
>  struct peci_controller;
>  struct peci_request;
>
> @@ -59,6 +67,11 @@ static inline struct peci_controller *to_peci_controller(void *d)
>   * struct peci_device - PECI device
>   * @dev: device object to register PECI device to the device model
>   * @controller: manages the bus segment hosting this PECI device
> + * @info: PECI device characteristics
> + * @info.family: device family
> + * @info.model: device model
> + * @info.peci_revision: PECI revision supported by the PECI device
> + * @info.socket_id: the socket ID represented by the PECI device
>   * @addr: address used on the PECI bus connected to the parent controller
>   *
>   * A peci_device identifies a single device (i.e. CPU) connected to a PECI bus.
> @@ -67,6 +80,12 @@ static inline struct peci_controller *to_peci_controller(void *d)
>   */
>  struct peci_device {
>         struct device dev;
> +       struct {
> +               u16 family;
> +               u8 model;
> +               u8 peci_revision;
> +               u8 socket_id;
> +       } info;
>         u8 addr;
>  };
>
> diff --git a/lib/Kconfig b/lib/Kconfig
> index e538d4d773bd..7f7972d357c2 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -718,4 +718,4 @@ config ASN1_ENCODER
>
>  config GENERIC_LIB_X86
>         bool
> -       depends on X86
> +       depends on X86 || PECI

This looks broken, what in the GENERIC_LIB_X86 implementation depends on peci?


From arnd at kernel.org  Fri Aug 27 15:11:20 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Sat, 28 Aug 2021 00:11:20 +0200
Subject: [GIT PULL] ARM: SoC fixes for 5.14, part 4
Message-ID: <CAK8P3a3wuNeoxDucwTPQvganekRSt4H708AX5pUfj=aYzo_Yog@mail.gmail.com>

The following changes since commit e22ce8eb631bdc47a4a4ea7ecf4e4ba499db4f93:

  Linux 5.14-rc7 (2021-08-22 14:24:56 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git
tags/soc-fixes-5.14-4

for you to fetch changes up to 6c35ca06974105d929f25f487c6ae7a47fffa128:

  Merge tag 'reset-fixes-for-v5.14' of
git://git.pengutronix.de/pza/linux into arm/fixes (2021-08-26 13:47:45
+0200)

----------------------------------------------------------------
ARM: SoC fixes for 5.14, part 4

Just two trivial fixes from the reset driver tree, nothing else came up
since the last soc fixes.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>

----------------------------------------------------------------
Arnd Bergmann (1):
      Merge tag 'reset-fixes-for-v5.14' of
git://git.pengutronix.de/pza/linux into arm/fixes

Geert Uytterhoeven (1):
      reset: RESET_MCHP_SPARX5 should depend on ARCH_SPARX5

Sai Krishna Potthuri (1):
      reset: reset-zynqmp: Fixed the argument data type

 drivers/reset/Kconfig        | 2 +-
 drivers/reset/reset-zynqmp.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)


From seanjc at google.com  Fri Aug 27 16:23:30 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 23:23:30 +0000
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <339641531.29941.1630091374065.JavaMail.zimbra@efficios.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <20210820225002.310652-5-seanjc@google.com>
 <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>
 <282257549.21721.1629732017655.JavaMail.zimbra@efficios.com>
 <YSblqrrpKcORzilX@google.com>
 <1700758714.29394.1630003332081.JavaMail.zimbra@efficios.com>
 <YSgpy8iXXXUQ+b/k@google.com>
 <339641531.29941.1630091374065.JavaMail.zimbra@efficios.com>
Message-ID: <YSlz8h9SWgeuicak@google.com>

On Fri, Aug 27, 2021, Mathieu Desnoyers wrote:
> > So there are effectively three reasons we want a delay:
> > 
> >  1. To allow sched_setaffinity() to coincide with ioctl(KVM_RUN) before KVM can
> >     enter the guest so that the guest doesn't need an arch-specific VM-Exit source.
> > 
> >  2. To let ioctl(KVM_RUN) make its way back to the test before the next round
> >     of migration.
> > 
> >  3. To ensure the read-side can make forward progress, e.g. if sched_getcpu()
> >     involves a syscall.
> > 
> > 
> > After looking at KVM for arm64 and s390, #1 is a bit tenuous because x86 is the
> > only arch that currently uses xfer_to_guest_mode_work(), i.e. the test could be
> > tweaked to be overtly x86-specific.  But since a delay is needed for #2 and #3,
> > I'd prefer to rely on it for #1 as well in the hopes that this test provides
> > coverage for arm64 and/or s390 if they're ever converted to use the common
> > xfer_to_guest_mode_work().
> 
> Now that we have this understanding of why we need the delay, it would be good to
> write this down in a comment within the test.

Ya, I'll get a new version out next week.

> Does it reproduce if we randomize the delay to have it picked randomly from 0us
> to 100us (with 1us step) ? It would remove a lot of the needs for arch-specific
> magic delay value.

My less-than-scientific testing shows that it can reproduce at delays up to ~500us,
but above ~10us the reproducibility starts to drop.  The bug still reproduces
reliably, it just takes more iterations, and obviously the test runs a bit slower.

Any objection to using a 1-10us delay, e.g. a simple usleep((i % 10) + 1)?


From pr-tracker-bot at kernel.org  Fri Aug 27 16:26:57 2021
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Fri, 27 Aug 2021 23:26:57 +0000
Subject: [GIT PULL] ARM: SoC fixes for 5.14, part 4
In-Reply-To: <CAK8P3a3wuNeoxDucwTPQvganekRSt4H708AX5pUfj=aYzo_Yog@mail.gmail.com>
References: <CAK8P3a3wuNeoxDucwTPQvganekRSt4H708AX5pUfj=aYzo_Yog@mail.gmail.com>
Message-ID: <163010681790.22639.14568450580407515339.pr-tracker-bot@kernel.org>

The pull request you sent on Sat, 28 Aug 2021 00:11:20 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-5.14-4

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/6f18b82b41147ee15b0b5bf7c9ae0464dda287f9

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From mathieu.desnoyers at efficios.com  Fri Aug 27 17:06:20 2021
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Fri, 27 Aug 2021 20:06:20 -0400 (EDT)
Subject: [PATCH v2 4/5] KVM: selftests: Add a test for KVM_RUN+rseq to
 detect task migration bugs
In-Reply-To: <YSlz8h9SWgeuicak@google.com>
References: <20210820225002.310652-1-seanjc@google.com>
 <766990430.21713.1629731934069.JavaMail.zimbra@efficios.com>
 <282257549.21721.1629732017655.JavaMail.zimbra@efficios.com>
 <YSblqrrpKcORzilX@google.com>
 <1700758714.29394.1630003332081.JavaMail.zimbra@efficios.com>
 <YSgpy8iXXXUQ+b/k@google.com>
 <339641531.29941.1630091374065.JavaMail.zimbra@efficios.com>
 <YSlz8h9SWgeuicak@google.com>
Message-ID: <1054916754.30218.1630109180443.JavaMail.zimbra@efficios.com>

----- On Aug 27, 2021, at 7:23 PM, Sean Christopherson seanjc at google.com wrote:

> On Fri, Aug 27, 2021, Mathieu Desnoyers wrote:
[...]
>> Does it reproduce if we randomize the delay to have it picked randomly from 0us
>> to 100us (with 1us step) ? It would remove a lot of the needs for arch-specific
>> magic delay value.
> 
> My less-than-scientific testing shows that it can reproduce at delays up to
> ~500us,
> but above ~10us the reproducibility starts to drop.  The bug still reproduces
> reliably, it just takes more iterations, and obviously the test runs a bit
> slower.
> 
> Any objection to using a 1-10us delay, e.g. a simple usleep((i % 10) + 1)?

Works for me, thanks!

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From seanjc at google.com  Fri Aug 27 17:35:45 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:45 -0700
Subject: [PATCH v2 00/13] perf: KVM: Fix, optimize, and clean up callbacks
Message-ID: <20210828003558.713983-1-seanjc@google.com>

This is a combination of ~2 series to fix bugs in the perf+KVM callbacks,
optimize the callbacks by employing static_call, and do a variety of
cleanup in both perf and KVM.

Patch 1 fixes a mostly-theoretical bug where perf can deref a NULL
pointer if KVM unregisters its callbacks while they're being accessed.
In practice, compilers tend to avoid problematic reloads of the pointer
and the PMI handler doesn't lose the race against module unloading,
i.e doesn't hit a use-after-free.

Patches 2 and 3 fix an Intel PT handling bug where KVM incorrectly
eats PT interrupts when PT is supposed to be owned entirely by the host.

Patches 4-7 clean up perf's callback infrastructure and switch to
static_call for arm64 and x86 (the only survivors).

Patches 8-13 clean up related KVM code and unify the arm64/x86 callbacks.

Based on "git://git.kernel.org/pub/scm/virt/kvm/kvm.git queue", commit
680c7e3be6a3 ("KVM: x86: Exit to userspace ...").

v2 (relatively to static_call v10)
  - Split the patch into the semantic change (multiplexed ->state) and
    introduction of static_call.
  - Don't use '0' for "not a guest RIP".
  - Handle unregister path.
  - Drop changes for architectures that can be culled entirely.

v2 (relative to v1)
  - Drop per-cpu approach. [Peter]
  - Fix mostly-theoretical reload and use-after-free with READ_ONCE(),
    WRITE_ONCE(), and synchronize_rcu(). [Peter]
  - Avoid new exports like the plague. [Peter]

v1:
  - https://lkml.kernel.org/r/20210827005718.585190-1-seanjc at google.com

v10 static_call:
  - https://lkml.kernel.org/r/20210806133802.3528-2-lingshan.zhu at intel.com

Like Xu (2):
  perf/core: Rework guest callbacks to prepare for static_call support
  perf/core: Use static_call to optimize perf_guest_info_callbacks

Sean Christopherson (11):
  perf: Ensure perf_guest_cbs aren't reloaded between !NULL check and
    deref
  KVM: x86: Register perf callbacks after calling vendor's
    hardware_setup()
  KVM: x86: Register Processor Trace interrupt hook iff PT enabled in
    guest
  perf: Stop pretending that perf can handle multiple guest callbacks
  perf: Force architectures to opt-in to guest callbacks
  KVM: x86: Drop current_vcpu for kvm_running_vcpu + kvm_arch_vcpu
    variable
  KVM: x86: More precisely identify NMI from guest when handling PMI
  KVM: Move x86's perf guest info callbacks to generic KVM
  KVM: x86: Move Intel Processor Trace interrupt handler to vmx.c
  KVM: arm64: Convert to the generic perf callbacks
  KVM: arm64: Drop perf.c and fold its tiny bits of code into arm.c /
    pmu.c

 arch/arm/kernel/perf_callchain.c   | 28 ++------------
 arch/arm64/Kconfig                 |  1 +
 arch/arm64/include/asm/kvm_host.h  | 13 ++++++-
 arch/arm64/kernel/perf_callchain.c | 28 +++++++++++---
 arch/arm64/kvm/Makefile            |  2 +-
 arch/arm64/kvm/arm.c               | 11 +++++-
 arch/arm64/kvm/perf.c              | 62 ------------------------------
 arch/arm64/kvm/pmu.c               |  8 ++++
 arch/csky/kernel/perf_callchain.c  | 10 -----
 arch/nds32/kernel/perf_event_cpu.c | 29 ++------------
 arch/riscv/kernel/perf_callchain.c | 10 -----
 arch/x86/Kconfig                   |  1 +
 arch/x86/events/core.c             | 36 ++++++++++++++---
 arch/x86/events/intel/core.c       |  7 ++--
 arch/x86/include/asm/kvm_host.h    |  8 +++-
 arch/x86/kvm/pmu.c                 |  2 +-
 arch/x86/kvm/svm/svm.c             |  2 +-
 arch/x86/kvm/vmx/vmx.c             | 25 +++++++++++-
 arch/x86/kvm/x86.c                 | 58 +++++-----------------------
 arch/x86/kvm/x86.h                 | 17 ++++++--
 arch/x86/xen/pmu.c                 | 32 +++++++--------
 include/kvm/arm_pmu.h              |  1 +
 include/linux/kvm_host.h           | 10 +++++
 include/linux/perf_event.h         | 26 ++++++++-----
 init/Kconfig                       |  3 ++
 kernel/events/core.c               | 24 ++++++------
 virt/kvm/kvm_main.c                | 40 +++++++++++++++++++
 27 files changed, 245 insertions(+), 249 deletions(-)
 delete mode 100644 arch/arm64/kvm/perf.c

-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:47 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:47 -0700
Subject: [PATCH v2 02/13] KVM: x86: Register perf callbacks after calling
 vendor's hardware_setup()
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-3-seanjc@google.com>

Wait to register perf callbacks until after doing vendor hardaware setup.
VMX's hardware_setup() configures Intel Processor Trace (PT) mode, and a
future fix to register the Intel PT guest interrupt hook if and only if
Intel PT is exposed to the guest will consume the configured PT mode.

Delaying registration to hardware setup is effectively a nop as KVM's perf
hooks all pivot on the per-CPU current_vcpu, which is non-NULL only when
KVM is handling an IRQ/NMI in a VM-Exit path.  I.e. current_vcpu will be
NULL throughout both kvm_arch_init() and kvm_arch_hardware_setup().

Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Artem Kashkanov <artem.kashkanov at intel.com>
Cc: stable at vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/kvm/x86.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 86539c1686fa..fb6015f97f9e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8426,8 +8426,6 @@ int kvm_arch_init(void *opaque)
 
 	kvm_timer_init();
 
-	perf_register_guest_info_callbacks(&kvm_guest_cbs);
-
 	if (boot_cpu_has(X86_FEATURE_XSAVE)) {
 		host_xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
 		supported_xcr0 = host_xcr0 & KVM_SUPPORTED_XCR0;
@@ -8461,7 +8459,6 @@ void kvm_arch_exit(void)
 		clear_hv_tscchange_cb();
 #endif
 	kvm_lapic_exit();
-	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
 
 	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
 		cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
@@ -11064,6 +11061,8 @@ int kvm_arch_hardware_setup(void *opaque)
 	memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
 	kvm_ops_static_call_update();
 
+	perf_register_guest_info_callbacks(&kvm_guest_cbs);
+
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
 		supported_xss = 0;
 
@@ -11091,6 +11090,8 @@ int kvm_arch_hardware_setup(void *opaque)
 
 void kvm_arch_hardware_unsetup(void)
 {
+	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+
 	static_call(kvm_x86_hardware_unsetup)();
 }
 
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:46 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:46 -0700
Subject: [PATCH v2 01/13] perf: Ensure perf_guest_cbs aren't reloaded between
 !NULL check and deref
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-2-seanjc@google.com>

Protect perf_guest_cbs with READ_ONCE/WRITE_ONCE to ensure it's not
reloaded between a !NULL check and a dereference, and wait for all
readers via syncrhonize_rcu() to prevent use-after-free, e.g. if the
callbacks are being unregistered during module unload.  Because the
callbacks are global, it's possible for readers to run in parallel with
an unregister operation.

The bug has escaped notice because all dereferences of perf_guest_cbs
follow the same "perf_guest_cbs && perf_guest_cbs->is_in_guest()" pattern,
and it's extremely unlikely a compiler will reload perf_guest_cbs in this
sequence.  Compilers do reload perf_guest_cbs for future derefs, e.g. for
->is_user_mode(), but the ->is_in_guest() guard all but guarantees the
PMI handler will win the race, e.g. to nullify perf_guest_cbs, KVM has to
completely exit the guest and teardown down all VMs before KVM start its
module unload / unregister sequence.

But with help, unloading kvm_intel can trigger a NULL pointer derference,
e.g. wrapping perf_guest_cbs with READ_ONCE in perf_misc_flags() while
spamming kvm_intel module load/unload leads to:

  BUG: kernel NULL pointer dereference, address: 0000000000000000
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 0 P4D 0
  Oops: 0000 [#1] PREEMPT SMP
  CPU: 6 PID: 1825 Comm: stress Not tainted 5.14.0-rc2+ #459
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:perf_misc_flags+0x1c/0x70
  Call Trace:
   perf_prepare_sample+0x53/0x6b0
   perf_event_output_forward+0x67/0x160
   __perf_event_overflow+0x52/0xf0
   handle_pmi_common+0x207/0x300
   intel_pmu_handle_irq+0xcf/0x410
   perf_event_nmi_handler+0x28/0x50
   nmi_handle+0xc7/0x260
   default_do_nmi+0x6b/0x170
   exc_nmi+0x103/0x130
   asm_exc_nmi+0x76/0xbf

Fixes: 39447b386c84 ("perf: Enhance perf to allow for guest statistic collection from host")
Cc: stable at vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm/kernel/perf_callchain.c   | 17 +++++++++++------
 arch/arm64/kernel/perf_callchain.c | 18 ++++++++++++------
 arch/csky/kernel/perf_callchain.c  |  6 ++++--
 arch/nds32/kernel/perf_event_cpu.c | 17 +++++++++++------
 arch/riscv/kernel/perf_callchain.c |  7 +++++--
 arch/x86/events/core.c             | 17 +++++++++++------
 arch/x86/events/intel/core.c       |  9 ++++++---
 include/linux/perf_event.h         |  8 ++++++++
 kernel/events/core.c               |  9 +++++++--
 9 files changed, 75 insertions(+), 33 deletions(-)

diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c
index 3b69a76d341e..1626dfc6f6ce 100644
--- a/arch/arm/kernel/perf_callchain.c
+++ b/arch/arm/kernel/perf_callchain.c
@@ -62,9 +62,10 @@ user_backtrace(struct frame_tail __user *tail,
 void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct frame_tail __user *tail;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -98,9 +99,10 @@ callchain_trace(struct stackframe *fr,
 void
 perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe fr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -111,18 +113,21 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
+
+	if (guest_cbs && guest_cbs->is_in_guest())
+		return guest_cbs->get_guest_ip();
 
 	return instruction_pointer(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	int misc = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (guest_cbs && guest_cbs->is_in_guest()) {
+		if (guest_cbs->is_user_mode())
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 4a72c2727309..86d9f2013172 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -102,7 +102,9 @@ compat_user_backtrace(struct compat_frame_tail __user *tail,
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
+
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -147,9 +149,10 @@ static bool callchain_trace(void *data, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe frame;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -160,18 +163,21 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
+
+	if (guest_cbs && guest_cbs->is_in_guest())
+		return guest_cbs->get_guest_ip();
 
 	return instruction_pointer(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	int misc = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (guest_cbs && guest_cbs->is_in_guest()) {
+		if (guest_cbs->is_user_mode())
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/csky/kernel/perf_callchain.c b/arch/csky/kernel/perf_callchain.c
index ab55e98ee8f6..35318a635a5f 100644
--- a/arch/csky/kernel/perf_callchain.c
+++ b/arch/csky/kernel/perf_callchain.c
@@ -86,10 +86,11 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	unsigned long fp = 0;
 
 	/* C-SKY does not support virtualization. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+	if (guest_cbs && guest_cbs->is_in_guest())
 		return;
 
 	fp = regs->regs[4];
@@ -110,10 +111,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe fr;
 
 	/* C-SKY does not support virtualization. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		pr_warn("C-SKY does not support perf in guest mode!");
 		return;
 	}
diff --git a/arch/nds32/kernel/perf_event_cpu.c b/arch/nds32/kernel/perf_event_cpu.c
index 0ce6f9f307e6..f38791960781 100644
--- a/arch/nds32/kernel/perf_event_cpu.c
+++ b/arch/nds32/kernel/perf_event_cpu.c
@@ -1363,6 +1363,7 @@ void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 		    struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	unsigned long fp = 0;
 	unsigned long gp = 0;
 	unsigned long lp = 0;
@@ -1371,7 +1372,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 
 	leaf_fp = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -1479,9 +1480,10 @@ void
 perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 		      struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe fr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -1493,20 +1495,23 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
+
 	/* However, NDS32 does not support virtualization */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	if (guest_cbs && guest_cbs->is_in_guest())
+		return guest_cbs->get_guest_ip();
 
 	return instruction_pointer(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	int misc = 0;
 
 	/* However, NDS32 does not support virtualization */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (guest_cbs && guest_cbs->is_in_guest()) {
+		if (guest_cbs->is_user_mode())
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
index 0bb1854dce83..8ecfc4c128bc 100644
--- a/arch/riscv/kernel/perf_callchain.c
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -56,10 +56,11 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	unsigned long fp = 0;
 
 	/* RISC-V does not support perf in guest mode. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+	if (guest_cbs && guest_cbs->is_in_guest())
 		return;
 
 	fp = regs->s0;
@@ -78,8 +79,10 @@ static bool fill_callchain(void *entry, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
+
 	/* RISC-V does not support perf in guest mode. */
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		pr_warn("RISC-V does not support perf in guest mode!");
 		return;
 	}
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 1eb45139fcc6..ffb3e6c0d367 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2761,10 +2761,11 @@ static bool perf_hw_regs(struct pt_regs *regs)
 void
 perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct unwind_state state;
 	unsigned long addr;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2864,10 +2865,11 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
 void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stack_frame frame;
 	const struct stack_frame __user *fp;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->is_in_guest()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2944,18 +2946,21 @@ static unsigned long code_segment_base(struct pt_regs *regs)
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
-		return perf_guest_cbs->get_guest_ip();
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
+
+	if (guest_cbs && guest_cbs->is_in_guest())
+		return guest_cbs->get_guest_ip();
 
 	return regs->ip + code_segment_base(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
+	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	int misc = 0;
 
-	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
-		if (perf_guest_cbs->is_user_mode())
+	if (guest_cbs && guest_cbs->is_in_guest()) {
+		if (guest_cbs->is_user_mode())
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index fca7a6e2242f..9baa46185d94 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2786,6 +2786,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
 {
 	struct perf_sample_data data;
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	struct perf_guest_info_callbacks *guest_cbs;
 	int bit;
 	int handled = 0;
 	u64 intel_ctrl = hybrid(cpuc->pmu, intel_ctrl);
@@ -2852,9 +2853,11 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
 	 */
 	if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) {
 		handled++;
-		if (unlikely(perf_guest_cbs && perf_guest_cbs->is_in_guest() &&
-			perf_guest_cbs->handle_intel_pt_intr))
-			perf_guest_cbs->handle_intel_pt_intr();
+
+		guest_cbs = perf_get_guest_cbs();
+		if (unlikely(guest_cbs && guest_cbs->is_in_guest() &&
+			     guest_cbs->handle_intel_pt_intr))
+			guest_cbs->handle_intel_pt_intr();
 		else
 			intel_pt_interrupt();
 	}
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2d510ad750ed..6b0405e578c1 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1237,6 +1237,14 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 				 u16 flags);
 
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
+static inline struct perf_guest_info_callbacks *perf_get_guest_cbs(void)
+{
+	/* Reg/unreg perf_guest_cbs waits for readers via synchronize_rcu(). */
+	lockdep_assert_preemption_disabled();
+
+	/* Prevent reloading between a !NULL check and dereferences. */
+	return READ_ONCE(perf_guest_cbs);
+}
 extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 464917096e73..2126f6327321 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6491,14 +6491,19 @@ struct perf_guest_info_callbacks *perf_guest_cbs;
 
 int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
-	perf_guest_cbs = cbs;
+	if (WARN_ON_ONCE(perf_guest_cbs))
+		return -EBUSY;
+
+	WRITE_ONCE(perf_guest_cbs, cbs);
+	synchronize_rcu();
 	return 0;
 }
 EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
 
 int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
-	perf_guest_cbs = NULL;
+	WRITE_ONCE(perf_guest_cbs, NULL);
+	synchronize_rcu();
 	return 0;
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:48 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:48 -0700
Subject: [PATCH v2 03/13] KVM: x86: Register Processor Trace interrupt hook
 iff PT enabled in guest
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-4-seanjc@google.com>

Override the Processor Trace (PT) interrupt handler for guest mode if and
only if PT is configured for host+guest mode, i.e. is being used
independently by both host and guest.  If PT is configured for system
mode, the host fully controls PT and must handle all events.

Fixes: 8479e04e7d6b ("KVM: x86: Inject PMI for KVM guest")
Cc: stable at vger.kernel.org
Cc: Like Xu <like.xu.linux at gmail.com>
Reported-by: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Reported-by: Artem Kashkanov <artem.kashkanov at intel.com>
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/include/asm/kvm_host.h | 1 +
 arch/x86/kvm/vmx/vmx.c          | 1 +
 arch/x86/kvm/x86.c              | 5 ++++-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 09b256db394a..1ea4943a73d7 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1494,6 +1494,7 @@ struct kvm_x86_init_ops {
 	int (*disabled_by_bios)(void);
 	int (*check_processor_compatibility)(void);
 	int (*hardware_setup)(void);
+	bool (*intel_pt_intr_in_guest)(void);
 
 	struct kvm_x86_ops *runtime_ops;
 };
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index fada1055f325..f19d72136f77 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7896,6 +7896,7 @@ static struct kvm_x86_init_ops vmx_init_ops __initdata = {
 	.disabled_by_bios = vmx_disabled_by_bios,
 	.check_processor_compatibility = vmx_check_processor_compat,
 	.hardware_setup = hardware_setup,
+	.intel_pt_intr_in_guest = vmx_pt_mode_is_host_guest,
 
 	.runtime_ops = &vmx_x86_ops,
 };
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fb6015f97f9e..ffc6c2d73508 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8305,7 +8305,7 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
 	.is_in_guest		= kvm_is_in_guest,
 	.is_user_mode		= kvm_is_user_mode,
 	.get_guest_ip		= kvm_get_guest_ip,
-	.handle_intel_pt_intr	= kvm_handle_intel_pt_intr,
+	.handle_intel_pt_intr	= NULL,
 };
 
 #ifdef CONFIG_X86_64
@@ -11061,6 +11061,8 @@ int kvm_arch_hardware_setup(void *opaque)
 	memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
 	kvm_ops_static_call_update();
 
+	if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest())
+		kvm_guest_cbs.handle_intel_pt_intr = kvm_handle_intel_pt_intr;
 	perf_register_guest_info_callbacks(&kvm_guest_cbs);
 
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
@@ -11091,6 +11093,7 @@ int kvm_arch_hardware_setup(void *opaque)
 void kvm_arch_hardware_unsetup(void)
 {
 	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+	kvm_guest_cbs.handle_intel_pt_intr = NULL;
 
 	static_call(kvm_x86_hardware_unsetup)();
 }
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:49 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:49 -0700
Subject: [PATCH v2 04/13] perf: Stop pretending that perf can handle multiple
 guest callbacks
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-5-seanjc@google.com>

Drop the 'int' return value from the perf (un)register callbacks helpers
and stop pretending perf can support multiple callbacks.  The 'int'
returns are not future proofing anything as none of the callers take
action on an error.  It's also not obvious that there will ever be
co-tenant hypervisors, and if there are, that allowing multiple callbacks
to be registered is desirable or even correct.

No functional change intended.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  4 ++--
 arch/arm64/kvm/perf.c             |  8 ++++----
 arch/x86/kvm/x86.c                |  2 +-
 include/linux/perf_event.h        | 11 +++++------
 kernel/events/core.c              | 14 +++-----------
 5 files changed, 15 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 41911585ae0c..ed940aec89e0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -670,8 +670,8 @@ unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
 int kvm_handle_mmio_return(struct kvm_vcpu *vcpu);
 int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
 
-int kvm_perf_init(void);
-int kvm_perf_teardown(void);
+void kvm_perf_init(void);
+void kvm_perf_teardown(void);
 
 long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
 gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 151c31fb9860..039fe59399a2 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -48,15 +48,15 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
 	.get_guest_ip	= kvm_get_guest_ip,
 };
 
-int kvm_perf_init(void)
+void kvm_perf_init(void)
 {
 	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
 		static_branch_enable(&kvm_arm_pmu_available);
 
-	return perf_register_guest_info_callbacks(&kvm_guest_cbs);
+	perf_register_guest_info_callbacks(&kvm_guest_cbs);
 }
 
-int kvm_perf_teardown(void)
+void kvm_perf_teardown(void)
 {
-	return perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+	perf_unregister_guest_info_callbacks();
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ffc6c2d73508..bae951344e28 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -11092,7 +11092,7 @@ int kvm_arch_hardware_setup(void *opaque)
 
 void kvm_arch_hardware_unsetup(void)
 {
-	perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+	perf_unregister_guest_info_callbacks();
 	kvm_guest_cbs.handle_intel_pt_intr = NULL;
 
 	static_call(kvm_x86_hardware_unsetup)();
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 6b0405e578c1..2b77e2154b61 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1245,8 +1245,8 @@ static inline struct perf_guest_info_callbacks *perf_get_guest_cbs(void)
 	/* Prevent reloading between a !NULL check and dereferences. */
 	return READ_ONCE(perf_guest_cbs);
 }
-extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
-extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+extern void perf_unregister_guest_info_callbacks(void);
 
 extern void perf_event_exec(void);
 extern void perf_event_comm(struct task_struct *tsk, bool exec);
@@ -1489,10 +1489,9 @@ perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr)	{ }
 static inline void
 perf_bp_event(struct perf_event *event, void *data)			{ }
 
-static inline int perf_register_guest_info_callbacks
-(struct perf_guest_info_callbacks *callbacks)				{ return 0; }
-static inline int perf_unregister_guest_info_callbacks
-(struct perf_guest_info_callbacks *callbacks)				{ return 0; }
+static inline void perf_register_guest_info_callbacks
+(struct perf_guest_info_callbacks *callbacks)				{ }
+static inline void perf_unregister_guest_info_callbacks(void)		{ }
 
 static inline void perf_event_mmap(struct vm_area_struct *vma)		{ }
 
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2126f6327321..1be95d9ace46 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6482,29 +6482,21 @@ static void perf_pending_event(struct irq_work *entry)
 		perf_swevent_put_recursion_context(rctx);
 }
 
-/*
- * We assume there is only KVM supporting the callbacks.
- * Later on, we might change it to a list if there is
- * another virtualization implementation supporting the callbacks.
- */
 struct perf_guest_info_callbacks *perf_guest_cbs;
-
-int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
 	if (WARN_ON_ONCE(perf_guest_cbs))
-		return -EBUSY;
+		return;
 
 	WRITE_ONCE(perf_guest_cbs, cbs);
 	synchronize_rcu();
-	return 0;
 }
 EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
 
-int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+void perf_unregister_guest_info_callbacks(void)
 {
 	WRITE_ONCE(perf_guest_cbs, NULL);
 	synchronize_rcu();
-	return 0;
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
 
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:51 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:51 -0700
Subject: [PATCH v2 06/13] perf/core: Rework guest callbacks to prepare for
 static_call support
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-7-seanjc@google.com>

From: Like Xu <like.xu at linux.intel.com>

To prepare for using static_calls to optimize perf's guest callbacks,
replace ->is_in_guest and ->is_user_mode with a new multiplexed hook
->state, tweak ->handle_intel_pt_intr to play nice with being called when
there is no active guest, and drop "guest" from ->is_in_guest.

Return '0' from ->state and ->handle_intel_pt_intr to indicate "not in
guest" so that DEFINE_STATIC_CALL_RET0 can be used to define the static
calls, i.e. no callback == !guest.

Suggested-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Originally-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Signed-off-by: Like Xu <like.xu at linux.intel.com>
Signed-off-by: Zhu Lingshan <lingshan.zhu at intel.com>
[sean: extracted from static_call patch, fixed get_ip() bug, wrote changelog]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/kernel/perf_callchain.c | 13 +++++-----
 arch/arm64/kvm/perf.c              | 35 +++++++++++---------------
 arch/x86/events/core.c             | 13 +++++-----
 arch/x86/events/intel/core.c       |  5 +---
 arch/x86/include/asm/kvm_host.h    |  2 +-
 arch/x86/kvm/pmu.c                 |  2 +-
 arch/x86/kvm/x86.c                 | 40 ++++++++++++++++--------------
 arch/x86/xen/pmu.c                 | 32 ++++++++++--------------
 include/linux/perf_event.h         | 10 +++++---
 kernel/events/core.c               |  1 +
 10 files changed, 74 insertions(+), 79 deletions(-)

diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 86d9f2013172..274dc3e11b6d 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -104,7 +104,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 {
 	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->state()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -152,7 +152,7 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe frame;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->state()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -165,8 +165,8 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
 	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 
-	if (guest_cbs && guest_cbs->is_in_guest())
-		return guest_cbs->get_guest_ip();
+	if (guest_cbs && guest_cbs->state())
+		return guest_cbs->get_ip();
 
 	return instruction_pointer(regs);
 }
@@ -174,10 +174,11 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
 	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
+	unsigned int guest_state = guest_cbs ? guest_cbs->state() : 0;
 	int misc = 0;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		if (guest_cbs->is_user_mode())
+	if (guest_state) {
+		if (guest_state & PERF_GUEST_USER)
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 039fe59399a2..893de1a51fea 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -13,39 +13,34 @@
 
 DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
 
-static int kvm_is_in_guest(void)
+static unsigned int kvm_guest_state(void)
 {
-        return kvm_get_running_vcpu() != NULL;
-}
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
+	unsigned int state;
 
-static int kvm_is_user_mode(void)
-{
-	struct kvm_vcpu *vcpu;
-
-	vcpu = kvm_get_running_vcpu();
+	if (!vcpu)
+		return 0;
 
-	if (vcpu)
-		return !vcpu_mode_priv(vcpu);
+	state = PERF_GUEST_ACTIVE;
+	if (!vcpu_mode_priv(vcpu))
+		state |= PERF_GUEST_USER;
 
-	return 0;
+	return state;
 }
 
 static unsigned long kvm_get_guest_ip(void)
 {
-	struct kvm_vcpu *vcpu;
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
-	vcpu = kvm_get_running_vcpu();
+	if (WARN_ON_ONCE(!vcpu))
+		return 0;
 
-	if (vcpu)
-		return *vcpu_pc(vcpu);
-
-	return 0;
+	return *vcpu_pc(vcpu);
 }
 
 static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.is_in_guest	= kvm_is_in_guest,
-	.is_user_mode	= kvm_is_user_mode,
-	.get_guest_ip	= kvm_get_guest_ip,
+	.state		= kvm_guest_state,
+	.get_ip		= kvm_get_guest_ip,
 };
 
 void kvm_perf_init(void)
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index ffb3e6c0d367..3a7630fdd340 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2765,7 +2765,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
 	struct unwind_state state;
 	unsigned long addr;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->state()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2869,7 +2869,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
 	struct stack_frame frame;
 	const struct stack_frame __user *fp;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
+	if (guest_cbs && guest_cbs->state()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2948,8 +2948,8 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
 	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 
-	if (guest_cbs && guest_cbs->is_in_guest())
-		return guest_cbs->get_guest_ip();
+	if (guest_cbs && guest_cbs->state())
+		return guest_cbs->get_ip();
 
 	return regs->ip + code_segment_base(regs);
 }
@@ -2957,10 +2957,11 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
 	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
+	unsigned int guest_state = guest_cbs ? guest_cbs->state() : 0;
 	int misc = 0;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		if (guest_cbs->is_user_mode())
+	if (guest_state) {
+		if (guest_state & PERF_GUEST_USER)
 			misc |= PERF_RECORD_MISC_GUEST_USER;
 		else
 			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 9baa46185d94..524ad1f747bd 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2855,10 +2855,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
 		handled++;
 
 		guest_cbs = perf_get_guest_cbs();
-		if (unlikely(guest_cbs && guest_cbs->is_in_guest() &&
-			     guest_cbs->handle_intel_pt_intr))
-			guest_cbs->handle_intel_pt_intr();
-		else
+		if (likely(!guest_cbs || !guest_cbs->handle_intel_pt_intr()))
 			intel_pt_interrupt();
 	}
 
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 1ea4943a73d7..1080166fc0cf 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1874,7 +1874,7 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu);
 int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
 void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu);
 
-int kvm_is_in_guest(void);
+unsigned int kvm_guest_state(void);
 
 void __user *__x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa,
 				     u32 size);
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 0772bad9165c..5b68d4188de0 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -87,7 +87,7 @@ static void kvm_perf_overflow_intr(struct perf_event *perf_event,
 		 * woken up. So we should wake it, but this is impossible from
 		 * NMI context. Do it from irq work instead.
 		 */
-		if (!kvm_is_in_guest())
+		if (!kvm_guest_state())
 			irq_work_queue(&pmc_to_pmu(pmc)->irq_work);
 		else
 			kvm_make_request(KVM_REQ_PMI, pmc->vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bae951344e28..b2a4d085aa4f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8267,44 +8267,48 @@ static void kvm_timer_init(void)
 DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
 EXPORT_PER_CPU_SYMBOL_GPL(current_vcpu);
 
-int kvm_is_in_guest(void)
+unsigned int kvm_guest_state(void)
 {
-	return __this_cpu_read(current_vcpu) != NULL;
-}
+	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
+	unsigned int state;
 
-static int kvm_is_user_mode(void)
-{
-	int user_mode = 3;
+	if (!vcpu)
+		return 0;
 
-	if (__this_cpu_read(current_vcpu))
-		user_mode = static_call(kvm_x86_get_cpl)(__this_cpu_read(current_vcpu));
+	state = PERF_GUEST_ACTIVE;
+	if (static_call(kvm_x86_get_cpl)(vcpu))
+		state |= PERF_GUEST_USER;
 
-	return user_mode != 0;
+	return state;
 }
 
-static unsigned long kvm_get_guest_ip(void)
+static unsigned long kvm_guest_get_ip(void)
 {
-	unsigned long ip = 0;
+	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
 
-	if (__this_cpu_read(current_vcpu))
-		ip = kvm_rip_read(__this_cpu_read(current_vcpu));
+	if (WARN_ON_ONCE(!vcpu))
+		return 0;
 
-	return ip;
+	return kvm_rip_read(vcpu);
 }
 
-static void kvm_handle_intel_pt_intr(void)
+static unsigned int kvm_handle_intel_pt_intr(void)
 {
 	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
 
+	/* '0' on failure so that the !PT case can use a RET0 static call. */
+	if (!vcpu)
+		return 0;
+
 	kvm_make_request(KVM_REQ_PMI, vcpu);
 	__set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT,
 			(unsigned long *)&vcpu->arch.pmu.global_status);
+	return 1;
 }
 
 static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.is_in_guest		= kvm_is_in_guest,
-	.is_user_mode		= kvm_is_user_mode,
-	.get_guest_ip		= kvm_get_guest_ip,
+	.state			= kvm_guest_state,
+	.get_ip			= kvm_guest_get_ip,
 	.handle_intel_pt_intr	= NULL,
 };
 
diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
index e13b0b49fcdf..89dd6b1708b0 100644
--- a/arch/x86/xen/pmu.c
+++ b/arch/x86/xen/pmu.c
@@ -413,34 +413,29 @@ int pmu_apic_update(uint32_t val)
 }
 
 /* perf callbacks */
-static int xen_is_in_guest(void)
+static unsigned int xen_guest_state(void)
 {
 	const struct xen_pmu_data *xenpmu_data = get_xenpmu_data();
+	unsigned int state = 0;
 
 	if (!xenpmu_data) {
 		pr_warn_once("%s: pmudata not initialized\n", __func__);
-		return 0;
+		return state;
 	}
 
 	if (!xen_initial_domain() || (xenpmu_data->domain_id >= DOMID_SELF))
-		return 0;
+		return state;
 
-	return 1;
-}
+	state |= PERF_GUEST_ACTIVE;
 
-static int xen_is_user_mode(void)
-{
-	const struct xen_pmu_data *xenpmu_data = get_xenpmu_data();
-
-	if (!xenpmu_data) {
-		pr_warn_once("%s: pmudata not initialized\n", __func__);
-		return 0;
+	if (xenpmu_data->pmu.pmu_flags & PMU_SAMPLE_PV) {
+		if (xenpmu_data->pmu.pmu_flags & PMU_SAMPLE_USER)
+			state |= PERF_GUEST_USER;
+	} else if (xenpmu_data->pmu.r.regs.cpl & 3) {
+		state |= PERF_GUEST_USER;
 	}
 
-	if (xenpmu_data->pmu.pmu_flags & PMU_SAMPLE_PV)
-		return (xenpmu_data->pmu.pmu_flags & PMU_SAMPLE_USER);
-	else
-		return !!(xenpmu_data->pmu.r.regs.cpl & 3);
+	return state;
 }
 
 static unsigned long xen_get_guest_ip(void)
@@ -456,9 +451,8 @@ static unsigned long xen_get_guest_ip(void)
 }
 
 static struct perf_guest_info_callbacks xen_guest_cbs = {
-	.is_in_guest            = xen_is_in_guest,
-	.is_user_mode           = xen_is_user_mode,
-	.get_guest_ip           = xen_get_guest_ip,
+	.state                  = xen_guest_state,
+	.get_ip			= xen_get_guest_ip,
 };
 
 /* Convert registers from Xen's format to Linux' */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index e75971f85cc8..a5d5893b80b0 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -26,11 +26,13 @@
 # include <asm/local64.h>
 #endif
 
+#define PERF_GUEST_ACTIVE	0x01
+#define PERF_GUEST_USER	0x02
+
 struct perf_guest_info_callbacks {
-	int				(*is_in_guest)(void);
-	int				(*is_user_mode)(void);
-	unsigned long			(*get_guest_ip)(void);
-	void				(*handle_intel_pt_intr)(void);
+	unsigned int			(*state)(void);
+	unsigned long			(*get_ip)(void);
+	unsigned int			(*handle_intel_pt_intr)(void);
 };
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
diff --git a/kernel/events/core.c b/kernel/events/core.c
index d7f606e06446..ec36e7aded89 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6484,6 +6484,7 @@ static void perf_pending_event(struct irq_work *entry)
 
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 struct perf_guest_info_callbacks *perf_guest_cbs;
+
 void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
 	if (WARN_ON_ONCE(perf_guest_cbs))
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:50 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:50 -0700
Subject: [PATCH v2 05/13] perf: Force architectures to opt-in to guest
 callbacks
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-6-seanjc@google.com>

Introduce HAVE_GUEST_PERF_EVENTS and require architectures to select it
to allow registering guest callbacks in perf.  Future patches will convert
the callbacks to static_call.  Rather than churn a bunch of arch code (that
was presumably copy+pasted from x86), remove it wholesale as it's useless
and at best wasting cycles.

Wrap even the stubs with an #ifdef to avoid an arch sneaking in a bogus
registration with CONFIG_PERF_EVENTS=n.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm/kernel/perf_callchain.c   | 33 ++++-------------------------
 arch/arm64/Kconfig                 |  1 +
 arch/csky/kernel/perf_callchain.c  | 12 -----------
 arch/nds32/kernel/perf_event_cpu.c | 34 ++++--------------------------
 arch/riscv/kernel/perf_callchain.c | 13 ------------
 arch/x86/Kconfig                   |  1 +
 include/linux/perf_event.h         |  4 ++++
 init/Kconfig                       |  3 +++
 kernel/events/core.c               |  2 ++
 9 files changed, 19 insertions(+), 84 deletions(-)

diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c
index 1626dfc6f6ce..bc6b246ab55e 100644
--- a/arch/arm/kernel/perf_callchain.c
+++ b/arch/arm/kernel/perf_callchain.c
@@ -62,14 +62,8 @@ user_backtrace(struct frame_tail __user *tail,
 void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct frame_tail __user *tail;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		/* We don't support guest os callchain now */
-		return;
-	}
-
 	perf_callchain_store(entry, regs->ARM_pc);
 
 	if (!current->mm)
@@ -99,44 +93,25 @@ callchain_trace(struct stackframe *fr,
 void
 perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe fr;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		/* We don't support guest os callchain now */
-		return;
-	}
-
 	arm_get_current_stackframe(regs, &fr);
 	walk_stackframe(&fr, callchain_trace, entry);
 }
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
-
-	if (guest_cbs && guest_cbs->is_in_guest())
-		return guest_cbs->get_guest_ip();
-
 	return instruction_pointer(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	int misc = 0;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		if (guest_cbs->is_user_mode())
-			misc |= PERF_RECORD_MISC_GUEST_USER;
-		else
-			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
-	} else {
-		if (user_mode(regs))
-			misc |= PERF_RECORD_MISC_USER;
-		else
-			misc |= PERF_RECORD_MISC_KERNEL;
-	}
+	if (user_mode(regs))
+		misc |= PERF_RECORD_MISC_USER;
+	else
+		misc |= PERF_RECORD_MISC_KERNEL;
 
 	return misc;
 }
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b5b13a932561..72a201a686c5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -190,6 +190,7 @@ config ARM64
 	select HAVE_NMI
 	select HAVE_PATA_PLATFORM
 	select HAVE_PERF_EVENTS
+	select HAVE_GUEST_PERF_EVENTS
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_REGS_AND_STACK_ACCESS_API
diff --git a/arch/csky/kernel/perf_callchain.c b/arch/csky/kernel/perf_callchain.c
index 35318a635a5f..92057de08f4f 100644
--- a/arch/csky/kernel/perf_callchain.c
+++ b/arch/csky/kernel/perf_callchain.c
@@ -86,13 +86,8 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	unsigned long fp = 0;
 
-	/* C-SKY does not support virtualization. */
-	if (guest_cbs && guest_cbs->is_in_guest())
-		return;
-
 	fp = regs->regs[4];
 	perf_callchain_store(entry, regs->pc);
 
@@ -111,15 +106,8 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe fr;
 
-	/* C-SKY does not support virtualization. */
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		pr_warn("C-SKY does not support perf in guest mode!");
-		return;
-	}
-
 	fr.fp = regs->regs[4];
 	fr.lr = regs->lr;
 	walk_stackframe(&fr, entry);
diff --git a/arch/nds32/kernel/perf_event_cpu.c b/arch/nds32/kernel/perf_event_cpu.c
index f38791960781..a78a879e7ef1 100644
--- a/arch/nds32/kernel/perf_event_cpu.c
+++ b/arch/nds32/kernel/perf_event_cpu.c
@@ -1363,7 +1363,6 @@ void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 		    struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	unsigned long fp = 0;
 	unsigned long gp = 0;
 	unsigned long lp = 0;
@@ -1372,11 +1371,6 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 
 	leaf_fp = 0;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		/* We don't support guest os callchain now */
-		return;
-	}
-
 	perf_callchain_store(entry, regs->ipc);
 	fp = regs->fp;
 	gp = regs->gp;
@@ -1480,13 +1474,8 @@ void
 perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 		      struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe fr;
 
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		/* We don't support guest os callchain now */
-		return;
-	}
 	fr.fp = regs->fp;
 	fr.lp = regs->lp;
 	fr.sp = regs->sp;
@@ -1495,32 +1484,17 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
-
-	/* However, NDS32 does not support virtualization */
-	if (guest_cbs && guest_cbs->is_in_guest())
-		return guest_cbs->get_guest_ip();
-
 	return instruction_pointer(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	int misc = 0;
 
-	/* However, NDS32 does not support virtualization */
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		if (guest_cbs->is_user_mode())
-			misc |= PERF_RECORD_MISC_GUEST_USER;
-		else
-			misc |= PERF_RECORD_MISC_GUEST_KERNEL;
-	} else {
-		if (user_mode(regs))
-			misc |= PERF_RECORD_MISC_USER;
-		else
-			misc |= PERF_RECORD_MISC_KERNEL;
-	}
+	if (user_mode(regs))
+		misc |= PERF_RECORD_MISC_USER;
+	else
+		misc |= PERF_RECORD_MISC_KERNEL;
 
 	return misc;
 }
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
index 8ecfc4c128bc..1fc075b8f764 100644
--- a/arch/riscv/kernel/perf_callchain.c
+++ b/arch/riscv/kernel/perf_callchain.c
@@ -56,13 +56,8 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	unsigned long fp = 0;
 
-	/* RISC-V does not support perf in guest mode. */
-	if (guest_cbs && guest_cbs->is_in_guest())
-		return;
-
 	fp = regs->s0;
 	perf_callchain_store(entry, regs->epc);
 
@@ -79,13 +74,5 @@ static bool fill_callchain(void *entry, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
-
-	/* RISC-V does not support perf in guest mode. */
-	if (guest_cbs && guest_cbs->is_in_guest()) {
-		pr_warn("RISC-V does not support perf in guest mode!");
-		return;
-	}
-
 	walk_stackframe(NULL, regs, fill_callchain, entry);
 }
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 49270655e827..a4de4aa7a3df 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -229,6 +229,7 @@ config X86
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_EVENTS_NMI
 	select HAVE_HARDLOCKUP_DETECTOR_PERF	if PERF_EVENTS && HAVE_PERF_EVENTS_NMI
+	select HAVE_GUEST_PERF_EVENTS
 	select HAVE_PCI
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2b77e2154b61..e75971f85cc8 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1236,6 +1236,7 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 				 enum perf_bpf_event_type type,
 				 u16 flags);
 
+#ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
 static inline struct perf_guest_info_callbacks *perf_get_guest_cbs(void)
 {
@@ -1247,6 +1248,7 @@ static inline struct perf_guest_info_callbacks *perf_get_guest_cbs(void)
 }
 extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 extern void perf_unregister_guest_info_callbacks(void);
+#endif /* CONFIG_HAVE_GUEST_PERF_EVENTS */
 
 extern void perf_event_exec(void);
 extern void perf_event_comm(struct task_struct *tsk, bool exec);
@@ -1489,9 +1491,11 @@ perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr)	{ }
 static inline void
 perf_bp_event(struct perf_event *event, void *data)			{ }
 
+#ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 static inline void perf_register_guest_info_callbacks
 (struct perf_guest_info_callbacks *callbacks)				{ }
 static inline void perf_unregister_guest_info_callbacks(void)		{ }
+#endif
 
 static inline void perf_event_mmap(struct vm_area_struct *vma)		{ }
 
diff --git a/init/Kconfig b/init/Kconfig
index 55f9f7738ebb..9ef51ae53977 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1776,6 +1776,9 @@ config HAVE_PERF_EVENTS
 	help
 	  See tools/perf/design.txt for details.
 
+config HAVE_GUEST_PERF_EVENTS
+	bool
+
 config PERF_USE_VMALLOC
 	bool
 	help
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1be95d9ace46..d7f606e06446 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6482,6 +6482,7 @@ static void perf_pending_event(struct irq_work *entry)
 		perf_swevent_put_recursion_context(rctx);
 }
 
+#ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 struct perf_guest_info_callbacks *perf_guest_cbs;
 void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 {
@@ -6499,6 +6500,7 @@ void perf_unregister_guest_info_callbacks(void)
 	synchronize_rcu();
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
+#endif
 
 static void
 perf_output_sample_regs(struct perf_output_handle *handle,
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:53 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:53 -0700
Subject: [PATCH v2 08/13] KVM: x86: Drop current_vcpu for kvm_running_vcpu +
 kvm_arch_vcpu variable
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-9-seanjc@google.com>

Use the generic kvm_running_vcpu plus a new 'handling_intr_from_guest'
variable in kvm_arch_vcpu instead of the semi-redundant current_vcpu.
kvm_before/after_interrupt() must be called while the vCPU is loaded,
(which protects against preemption), thus kvm_running_vcpu is guaranteed
to be non-NULL when handling_intr_from_guest is non-zero.

Switching to kvm_get_running_vcpu() will allows moving KVM's perf
callbacks to generic code, and the new flag will be used in a future
patch to more precisely identify the "NMI from guest" case.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/include/asm/kvm_host.h |  3 +--
 arch/x86/kvm/pmu.c              |  2 +-
 arch/x86/kvm/x86.c              | 21 ++++++++++++---------
 arch/x86/kvm/x86.h              | 10 ++++++----
 4 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 1080166fc0cf..2d86a2dfc775 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -763,6 +763,7 @@ struct kvm_vcpu_arch {
 	unsigned nmi_pending; /* NMI queued after currently running handler */
 	bool nmi_injected;    /* Trying to inject an NMI this entry */
 	bool smi_pending;    /* SMI queued after currently running handler */
+	u8 handling_intr_from_guest;
 
 	struct kvm_mtrr mtrr_state;
 	u64 pat;
@@ -1874,8 +1875,6 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu);
 int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
 void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu);
 
-unsigned int kvm_guest_state(void);
-
 void __user *__x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa,
 				     u32 size);
 bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 5b68d4188de0..eef48258e50f 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -87,7 +87,7 @@ static void kvm_perf_overflow_intr(struct perf_event *perf_event,
 		 * woken up. So we should wake it, but this is impossible from
 		 * NMI context. Do it from irq work instead.
 		 */
-		if (!kvm_guest_state())
+		if (!kvm_handling_nmi_from_guest(pmc->vcpu))
 			irq_work_queue(&pmc_to_pmu(pmc)->irq_work);
 		else
 			kvm_make_request(KVM_REQ_PMI, pmc->vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b2a4d085aa4f..6df300c55461 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8264,15 +8264,17 @@ static void kvm_timer_init(void)
 			  kvmclock_cpu_online, kvmclock_cpu_down_prep);
 }
 
-DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
-EXPORT_PER_CPU_SYMBOL_GPL(current_vcpu);
+static inline bool kvm_pmi_in_guest(struct kvm_vcpu *vcpu)
+{
+	return vcpu && vcpu->arch.handling_intr_from_guest;
+}
 
-unsigned int kvm_guest_state(void)
+static unsigned int kvm_guest_state(void)
 {
-	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 	unsigned int state;
 
-	if (!vcpu)
+	if (!kvm_pmi_in_guest(vcpu))
 		return 0;
 
 	state = PERF_GUEST_ACTIVE;
@@ -8284,9 +8286,10 @@ unsigned int kvm_guest_state(void)
 
 static unsigned long kvm_guest_get_ip(void)
 {
-	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
-	if (WARN_ON_ONCE(!vcpu))
+	/* Retrieving the IP must be guarded by a call to kvm_guest_state(). */
+	if (WARN_ON_ONCE(!kvm_pmi_in_guest(vcpu)))
 		return 0;
 
 	return kvm_rip_read(vcpu);
@@ -8294,10 +8297,10 @@ static unsigned long kvm_guest_get_ip(void)
 
 static unsigned int kvm_handle_intel_pt_intr(void)
 {
-	struct kvm_vcpu *vcpu = __this_cpu_read(current_vcpu);
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
 	/* '0' on failure so that the !PT case can use a RET0 static call. */
-	if (!vcpu)
+	if (!kvm_pmi_in_guest(vcpu))
 		return 0;
 
 	kvm_make_request(KVM_REQ_PMI, vcpu);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 7d66d63dc55a..a9c107e7c907 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -387,18 +387,20 @@ static inline bool kvm_cstate_in_guest(struct kvm *kvm)
 	return kvm->arch.cstate_in_guest;
 }
 
-DECLARE_PER_CPU(struct kvm_vcpu *, current_vcpu);
-
 static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu)
 {
-	__this_cpu_write(current_vcpu, vcpu);
+	WRITE_ONCE(vcpu->arch.handling_intr_from_guest, 1);
 }
 
 static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
 {
-	__this_cpu_write(current_vcpu, NULL);
+	WRITE_ONCE(vcpu->arch.handling_intr_from_guest, 0);
 }
 
+static inline bool kvm_handling_nmi_from_guest(struct kvm_vcpu *vcpu)
+{
+	return !!vcpu->arch.handling_intr_from_guest;
+}
 
 static inline bool kvm_pat_valid(u64 data)
 {
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:54 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:54 -0700
Subject: [PATCH v2 09/13] KVM: x86: More precisely identify NMI from guest
 when handling PMI
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-10-seanjc@google.com>

Differntiate between IRQ and NMI for KVM's PMC overflow callback, which
was originally invoked in response to an NMI that arrived while the guest
was running, but was inadvertantly changed to fire on IRQs as well when
support for perf without PMU/NMI was added to KVM.  In practice, this
should be a nop as the PMC overflow callback shouldn't be reached, but
it's a cheap and easy fix that also better documents the situation.

Note, this also doesn't completely prevent false positives if perf
somehow ends up calling into KVM, e.g. an NMI can arrive in host after
KVM sets its flag.

Fixes: dd60d217062f ("KVM: x86: Fix perf timer mode IP reporting")
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/kvm/svm/svm.c |  2 +-
 arch/x86/kvm/vmx/vmx.c |  4 +++-
 arch/x86/kvm/x86.c     |  2 +-
 arch/x86/kvm/x86.h     | 13 ++++++++++---
 4 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 1a70e11f0487..0a0c01744b63 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3843,7 +3843,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
 	}
 
 	if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI))
-		kvm_before_interrupt(vcpu);
+		kvm_before_interrupt(vcpu, KVM_HANDLING_NMI);
 
 	kvm_load_host_xsave_state(vcpu);
 	stgi();
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index f19d72136f77..61a4f5ff2acd 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6344,7 +6344,9 @@ void vmx_do_interrupt_nmi_irqoff(unsigned long entry);
 static void handle_interrupt_nmi_irqoff(struct kvm_vcpu *vcpu,
 					unsigned long entry)
 {
-	kvm_before_interrupt(vcpu);
+	bool is_nmi = entry == (unsigned long)asm_exc_nmi_noist;
+
+	kvm_before_interrupt(vcpu, is_nmi ? KVM_HANDLING_NMI : KVM_HANDLING_IRQ);
 	vmx_do_interrupt_nmi_irqoff(entry);
 	kvm_after_interrupt(vcpu);
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6df300c55461..1427ac1fc1f2 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9676,7 +9676,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 	 * interrupts on processors that implement an interrupt shadow, the
 	 * stat.exits increment will do nicely.
 	 */
-	kvm_before_interrupt(vcpu);
+	kvm_before_interrupt(vcpu, KVM_HANDLING_IRQ);
 	local_irq_enable();
 	++vcpu->stat.exits;
 	local_irq_disable();
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index a9c107e7c907..9b26f9b09d2a 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -387,9 +387,16 @@ static inline bool kvm_cstate_in_guest(struct kvm *kvm)
 	return kvm->arch.cstate_in_guest;
 }
 
-static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu)
+enum kvm_intr_type {
+	/* Values are arbitrary, but must be non-zero. */
+	KVM_HANDLING_IRQ = 1,
+	KVM_HANDLING_NMI,
+};
+
+static inline void kvm_before_interrupt(struct kvm_vcpu *vcpu,
+					enum kvm_intr_type intr)
 {
-	WRITE_ONCE(vcpu->arch.handling_intr_from_guest, 1);
+	WRITE_ONCE(vcpu->arch.handling_intr_from_guest, (u8)intr);
 }
 
 static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
@@ -399,7 +406,7 @@ static inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
 
 static inline bool kvm_handling_nmi_from_guest(struct kvm_vcpu *vcpu)
 {
-	return !!vcpu->arch.handling_intr_from_guest;
+	return vcpu->arch.handling_intr_from_guest == KVM_HANDLING_NMI;
 }
 
 static inline bool kvm_pat_valid(u64 data)
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:55 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:55 -0700
Subject: [PATCH v2 10/13] KVM: Move x86's perf guest info callbacks to generic
 KVM
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-11-seanjc@google.com>

Move x86's perf guest callbacks into common KVM, as they are semantically
identical to arm64's callbacks (the only other such KVM callbacks).
arm64 will convert to the common versions in a future patch.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/include/asm/kvm_host.h |  4 +++
 arch/x86/kvm/x86.c              | 53 +++++++--------------------------
 include/linux/kvm_host.h        | 12 ++++++++
 virt/kvm/kvm_main.c             | 40 +++++++++++++++++++++++++
 4 files changed, 67 insertions(+), 42 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2d86a2dfc775..a98c7907110c 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1543,6 +1543,10 @@ static inline int kvm_arch_flush_remote_tlb(struct kvm *kvm)
 		return -ENOTSUPP;
 }
 
+#define __KVM_WANT_PERF_CALLBACKS
+#define kvm_arch_pmi_in_guest(vcpu) \
+	((vcpu) && (vcpu)->arch.handling_intr_from_guest)
+
 int kvm_mmu_module_init(void);
 void kvm_mmu_module_exit(void);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1427ac1fc1f2..1bea616402e6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8264,43 +8264,12 @@ static void kvm_timer_init(void)
 			  kvmclock_cpu_online, kvmclock_cpu_down_prep);
 }
 
-static inline bool kvm_pmi_in_guest(struct kvm_vcpu *vcpu)
-{
-	return vcpu && vcpu->arch.handling_intr_from_guest;
-}
-
-static unsigned int kvm_guest_state(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-	unsigned int state;
-
-	if (!kvm_pmi_in_guest(vcpu))
-		return 0;
-
-	state = PERF_GUEST_ACTIVE;
-	if (static_call(kvm_x86_get_cpl)(vcpu))
-		state |= PERF_GUEST_USER;
-
-	return state;
-}
-
-static unsigned long kvm_guest_get_ip(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-
-	/* Retrieving the IP must be guarded by a call to kvm_guest_state(). */
-	if (WARN_ON_ONCE(!kvm_pmi_in_guest(vcpu)))
-		return 0;
-
-	return kvm_rip_read(vcpu);
-}
-
 static unsigned int kvm_handle_intel_pt_intr(void)
 {
 	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 
 	/* '0' on failure so that the !PT case can use a RET0 static call. */
-	if (!kvm_pmi_in_guest(vcpu))
+	if (!kvm_arch_pmi_in_guest(vcpu))
 		return 0;
 
 	kvm_make_request(KVM_REQ_PMI, vcpu);
@@ -8309,12 +8278,6 @@ static unsigned int kvm_handle_intel_pt_intr(void)
 	return 1;
 }
 
-static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.state			= kvm_guest_state,
-	.get_ip			= kvm_guest_get_ip,
-	.handle_intel_pt_intr	= NULL,
-};
-
 #ifdef CONFIG_X86_64
 static void pvclock_gtod_update_fn(struct work_struct *work)
 {
@@ -11068,9 +11031,11 @@ int kvm_arch_hardware_setup(void *opaque)
 	memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
 	kvm_ops_static_call_update();
 
+	/* Temporary ugliness. */
 	if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest())
-		kvm_guest_cbs.handle_intel_pt_intr = kvm_handle_intel_pt_intr;
-	perf_register_guest_info_callbacks(&kvm_guest_cbs);
+		kvm_register_perf_callbacks(kvm_handle_intel_pt_intr);
+	else
+		kvm_register_perf_callbacks(NULL);
 
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
 		supported_xss = 0;
@@ -11099,8 +11064,7 @@ int kvm_arch_hardware_setup(void *opaque)
 
 void kvm_arch_hardware_unsetup(void)
 {
-	perf_unregister_guest_info_callbacks();
-	kvm_guest_cbs.handle_intel_pt_intr = NULL;
+	kvm_unregister_perf_callbacks();
 
 	static_call(kvm_x86_hardware_unsetup)();
 }
@@ -11727,6 +11691,11 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
 	return vcpu->arch.preempted_in_kernel;
 }
 
+unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
+{
+	return kvm_rip_read(vcpu);
+}
+
 int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
 {
 	return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index e4d712e9f760..34d99034852f 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1163,6 +1163,18 @@ static inline bool kvm_arch_intc_initialized(struct kvm *kvm)
 }
 #endif
 
+#ifdef __KVM_WANT_PERF_CALLBACKS
+
+void kvm_set_intel_pt_intr_handler(unsigned int (*handler)(void));
+unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu);
+
+void kvm_register_perf_callbacks(unsigned int (*pt_intr_handler)(void));
+static inline void kvm_unregister_perf_callbacks(void)
+{
+	perf_unregister_guest_info_callbacks();
+}
+#endif
+
 int kvm_arch_init_vm(struct kvm *kvm, unsigned long type);
 void kvm_arch_destroy_vm(struct kvm *kvm);
 void kvm_arch_sync_events(struct kvm *kvm);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 3e67c93ca403..2c61db39b501 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -5460,6 +5460,46 @@ struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void)
         return &kvm_running_vcpu;
 }
 
+#ifdef __KVM_WANT_PERF_CALLBACKS
+static unsigned int kvm_guest_state(void)
+{
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
+	unsigned int state;
+
+	if (!kvm_arch_pmi_in_guest(vcpu))
+		return 0;
+
+	state = PERF_GUEST_ACTIVE;
+	if (!kvm_arch_vcpu_in_kernel(vcpu))
+		state |= PERF_GUEST_USER;
+
+	return state;
+}
+
+static unsigned long kvm_guest_get_ip(void)
+{
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
+
+	/* Retrieving the IP must be guarded by a call to kvm_guest_state(). */
+	if (WARN_ON_ONCE(!kvm_arch_pmi_in_guest(vcpu)))
+		return 0;
+
+	return kvm_arch_vcpu_get_ip(vcpu);
+}
+
+static struct perf_guest_info_callbacks kvm_guest_cbs = {
+	.state			= kvm_guest_state,
+	.get_ip			= kvm_guest_get_ip,
+	.handle_intel_pt_intr	= NULL,
+};
+
+void kvm_register_perf_callbacks(unsigned int (*pt_intr_handler)(void))
+{
+	kvm_guest_cbs.handle_intel_pt_intr = pt_intr_handler;
+	perf_register_guest_info_callbacks(&kvm_guest_cbs);
+}
+#endif
+
 struct kvm_cpu_compat_check {
 	void *opaque;
 	int *ret;
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:56 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:56 -0700
Subject: [PATCH v2 11/13] KVM: x86: Move Intel Processor Trace interrupt
 handler to vmx.c
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-12-seanjc@google.com>

Now that all state needed for VMX's PT interrupt handler is exposed to
vmx.c (specifically the currently running vCPU), move the handler into
vmx.c where it belongs.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/x86/include/asm/kvm_host.h |  2 +-
 arch/x86/kvm/vmx/vmx.c          | 22 +++++++++++++++++++++-
 arch/x86/kvm/x86.c              | 20 +-------------------
 include/linux/kvm_host.h        |  2 --
 4 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a98c7907110c..7a3d1dcfef39 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1495,7 +1495,7 @@ struct kvm_x86_init_ops {
 	int (*disabled_by_bios)(void);
 	int (*check_processor_compatibility)(void);
 	int (*hardware_setup)(void);
-	bool (*intel_pt_intr_in_guest)(void);
+	unsigned int (*handle_intel_pt_intr)(void);
 
 	struct kvm_x86_ops *runtime_ops;
 };
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 61a4f5ff2acd..33f92febe3ce 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7687,6 +7687,20 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
 	.vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector,
 };
 
+static unsigned int vmx_handle_intel_pt_intr(void)
+{
+	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
+
+	/* '0' on failure so that the !PT case can use a RET0 static call. */
+	if (!kvm_arch_pmi_in_guest(vcpu))
+		return 0;
+
+	kvm_make_request(KVM_REQ_PMI, vcpu);
+	__set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT,
+		  (unsigned long *)&vcpu->arch.pmu.global_status);
+	return 1;
+}
+
 static __init void vmx_setup_user_return_msrs(void)
 {
 
@@ -7713,6 +7727,8 @@ static __init void vmx_setup_user_return_msrs(void)
 		kvm_add_user_return_msr(vmx_uret_msrs_list[i]);
 }
 
+static struct kvm_x86_init_ops vmx_init_ops __initdata;
+
 static __init int hardware_setup(void)
 {
 	unsigned long host_bndcfgs;
@@ -7873,6 +7889,10 @@ static __init int hardware_setup(void)
 		return -EINVAL;
 	if (!enable_ept || !cpu_has_vmx_intel_pt())
 		pt_mode = PT_MODE_SYSTEM;
+	if (pt_mode == PT_MODE_HOST_GUEST)
+		vmx_init_ops.handle_intel_pt_intr = vmx_handle_intel_pt_intr;
+	else
+		vmx_init_ops.handle_intel_pt_intr = NULL;
 
 	setup_default_sgx_lepubkeyhash();
 
@@ -7898,7 +7918,7 @@ static struct kvm_x86_init_ops vmx_init_ops __initdata = {
 	.disabled_by_bios = vmx_disabled_by_bios,
 	.check_processor_compatibility = vmx_check_processor_compat,
 	.hardware_setup = hardware_setup,
-	.intel_pt_intr_in_guest = vmx_pt_mode_is_host_guest,
+	.handle_intel_pt_intr = NULL,
 
 	.runtime_ops = &vmx_x86_ops,
 };
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1bea616402e6..b79b2d29260d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -8264,20 +8264,6 @@ static void kvm_timer_init(void)
 			  kvmclock_cpu_online, kvmclock_cpu_down_prep);
 }
 
-static unsigned int kvm_handle_intel_pt_intr(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-
-	/* '0' on failure so that the !PT case can use a RET0 static call. */
-	if (!kvm_arch_pmi_in_guest(vcpu))
-		return 0;
-
-	kvm_make_request(KVM_REQ_PMI, vcpu);
-	__set_bit(MSR_CORE_PERF_GLOBAL_OVF_CTRL_TRACE_TOPA_PMI_BIT,
-			(unsigned long *)&vcpu->arch.pmu.global_status);
-	return 1;
-}
-
 #ifdef CONFIG_X86_64
 static void pvclock_gtod_update_fn(struct work_struct *work)
 {
@@ -11031,11 +11017,7 @@ int kvm_arch_hardware_setup(void *opaque)
 	memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
 	kvm_ops_static_call_update();
 
-	/* Temporary ugliness. */
-	if (ops->intel_pt_intr_in_guest && ops->intel_pt_intr_in_guest())
-		kvm_register_perf_callbacks(kvm_handle_intel_pt_intr);
-	else
-		kvm_register_perf_callbacks(NULL);
+	kvm_register_perf_callbacks(ops->handle_intel_pt_intr);
 
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
 		supported_xss = 0;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 34d99034852f..b9235c3ac6af 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1164,8 +1164,6 @@ static inline bool kvm_arch_intc_initialized(struct kvm *kvm)
 #endif
 
 #ifdef __KVM_WANT_PERF_CALLBACKS
-
-void kvm_set_intel_pt_intr_handler(unsigned int (*handler)(void));
 unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu);
 
 void kvm_register_perf_callbacks(unsigned int (*pt_intr_handler)(void));
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:57 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:57 -0700
Subject: [PATCH v2 12/13] KVM: arm64: Convert to the generic perf callbacks
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-13-seanjc@google.com>

Drop arm64's version of the callbacks in favor of the callbacks provided
by generic KVM, which are semantically identical.  Implement the "get ip"
hook as needed.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/include/asm/kvm_host.h | 12 +++++++++++
 arch/arm64/kvm/arm.c              |  5 +++++
 arch/arm64/kvm/perf.c             | 34 ++-----------------------------
 3 files changed, 19 insertions(+), 32 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index ed940aec89e0..73dc402ded1f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -673,6 +673,18 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
 void kvm_perf_init(void);
 void kvm_perf_teardown(void);
 
+#ifdef CONFIG_PERF_EVENTS
+#define __KVM_WANT_PERF_CALLBACKS
+static inline bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu)
+{
+	/* Any callback while a vCPU is loaded is considered to be in guest. */
+	return !!vcpu;
+}
+#else
+static inline void kvm_register_perf_callbacks(void) {}
+static inline void kvm_unregister_perf_callbacks(void) {}
+#endif
+
 long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
 gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu);
 void kvm_update_stolen_time(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e9a2b8f27792..2b542fdc237e 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -500,6 +500,11 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
 	return vcpu_mode_priv(vcpu);
 }
 
+unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
+{
+	return *vcpu_pc(vcpu);
+}
+
 /* Just ensure a guest exit from a particular CPU */
 static void exit_vm_noop(void *info)
 {
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
index 893de1a51fea..0b902e0d5b5d 100644
--- a/arch/arm64/kvm/perf.c
+++ b/arch/arm64/kvm/perf.c
@@ -13,45 +13,15 @@
 
 DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
 
-static unsigned int kvm_guest_state(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-	unsigned int state;
-
-	if (!vcpu)
-		return 0;
-
-	state = PERF_GUEST_ACTIVE;
-	if (!vcpu_mode_priv(vcpu))
-		state |= PERF_GUEST_USER;
-
-	return state;
-}
-
-static unsigned long kvm_get_guest_ip(void)
-{
-	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
-
-	if (WARN_ON_ONCE(!vcpu))
-		return 0;
-
-	return *vcpu_pc(vcpu);
-}
-
-static struct perf_guest_info_callbacks kvm_guest_cbs = {
-	.state		= kvm_guest_state,
-	.get_ip		= kvm_get_guest_ip,
-};
-
 void kvm_perf_init(void)
 {
 	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
 		static_branch_enable(&kvm_arm_pmu_available);
 
-	perf_register_guest_info_callbacks(&kvm_guest_cbs);
+	kvm_register_perf_callbacks(NULL);
 }
 
 void kvm_perf_teardown(void)
 {
-	perf_unregister_guest_info_callbacks();
+	kvm_unregister_perf_callbacks();
 }
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:52 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:52 -0700
Subject: [PATCH v2 07/13] perf/core: Use static_call to optimize
 perf_guest_info_callbacks
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-8-seanjc@google.com>

From: Like Xu <like.xu at linux.intel.com>

Use static_call to optimize perf's guest callbacks on arm64 and x86,
which are now the only architectures that define the callbacks.  Use
DEFINE_STATIC_CALL_RET0 as the default/NULL for all guest callbacks, as
the callback semantics are that a return value '0' means "not in guest".

static_call obviously avoids the overhead of CONFIG_RETPOLINE=y, but is
also advantageous versus other solutions, e.g. per-cpu callbacks, in that
a per-cpu memory load is not needed to detect the !guest case.

Suggested-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Originally-by: Peter Zijlstra (Intel) <peterz at infradead.org>
Signed-off-by: Like Xu <like.xu at linux.intel.com>
Signed-off-by: Zhu Lingshan <lingshan.zhu at intel.com>
[sean: split out patch, drop __weak, tweak updaters, rewrite changelog]
Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/kernel/perf_callchain.c | 31 +++++++++++++++---------
 arch/x86/events/core.c             | 38 ++++++++++++++++++++++--------
 arch/x86/events/intel/core.c       |  7 +++---
 include/linux/perf_event.h         |  9 +------
 kernel/events/core.c               |  2 ++
 5 files changed, 54 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c
index 274dc3e11b6d..18cf6e608778 100644
--- a/arch/arm64/kernel/perf_callchain.c
+++ b/arch/arm64/kernel/perf_callchain.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2015 ARM Limited
  */
 #include <linux/perf_event.h>
+#include <linux/static_call.h>
 #include <linux/uaccess.h>
 
 #include <asm/pointer_auth.h>
@@ -99,12 +100,24 @@ compat_user_backtrace(struct compat_frame_tail __user *tail,
 }
 #endif /* CONFIG_COMPAT */
 
+DEFINE_STATIC_CALL_RET0(arm64_guest_state, *(perf_guest_cbs->state));
+DEFINE_STATIC_CALL_RET0(arm64_guest_get_ip, *(perf_guest_cbs->get_ip));
+
+void arch_perf_update_guest_cbs(struct perf_guest_info_callbacks *guest_cbs)
+{
+	if (guest_cbs) {
+		static_call_update(arm64_guest_state, guest_cbs->state);
+		static_call_update(arm64_guest_get_ip, guest_cbs->get_ip);
+	} else {
+		static_call_update(arm64_guest_state, (void *)&__static_call_return0);
+		static_call_update(arm64_guest_get_ip, (void *)&__static_call_return0);
+	}
+}
+
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
-
-	if (guest_cbs && guest_cbs->state()) {
+	if (static_call(arm64_guest_state)()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -149,10 +162,9 @@ static bool callchain_trace(void *data, unsigned long pc)
 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 			   struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stackframe frame;
 
-	if (guest_cbs && guest_cbs->state()) {
+	if (static_call(arm64_guest_state)()) {
 		/* We don't support guest os callchain now */
 		return;
 	}
@@ -163,18 +175,15 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
-
-	if (guest_cbs && guest_cbs->state())
-		return guest_cbs->get_ip();
+	if (static_call(arm64_guest_state)())
+		return static_call(arm64_guest_get_ip)();
 
 	return instruction_pointer(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
-	unsigned int guest_state = guest_cbs ? guest_cbs->state() : 0;
+	unsigned int guest_state = static_call(arm64_guest_state)();
 	int misc = 0;
 
 	if (guest_state) {
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 3a7630fdd340..508a677edd8c 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -90,6 +90,29 @@ DEFINE_STATIC_CALL_NULL(x86_pmu_pebs_aliases, *x86_pmu.pebs_aliases);
  */
 DEFINE_STATIC_CALL_RET0(x86_pmu_guest_get_msrs, *x86_pmu.guest_get_msrs);
 
+DEFINE_STATIC_CALL_RET0(x86_guest_state, *(perf_guest_cbs->state));
+DEFINE_STATIC_CALL_RET0(x86_guest_get_ip, *(perf_guest_cbs->get_ip));
+DEFINE_STATIC_CALL_RET0(x86_guest_handle_intel_pt_intr, *(perf_guest_cbs->handle_intel_pt_intr));
+
+void arch_perf_update_guest_cbs(struct perf_guest_info_callbacks *guest_cbs)
+{
+	if (guest_cbs) {
+		static_call_update(x86_guest_state, guest_cbs->state);
+		static_call_update(x86_guest_get_ip, guest_cbs->get_ip);
+	} else {
+		static_call_update(x86_guest_state, (void *)&__static_call_return0);
+		static_call_update(x86_guest_get_ip, (void *)&__static_call_return0);
+	}
+
+	/* Implementing ->handle_intel_pt_intr is optional. */
+	if (guest_cbs && guest_cbs->handle_intel_pt_intr)
+		static_call_update(x86_guest_handle_intel_pt_intr,
+				   guest_cbs->handle_intel_pt_intr);
+	else
+		static_call_update(x86_guest_handle_intel_pt_intr,
+				   (void *)&__static_call_return0);
+}
+
 u64 __read_mostly hw_cache_event_ids
 				[PERF_COUNT_HW_CACHE_MAX]
 				[PERF_COUNT_HW_CACHE_OP_MAX]
@@ -2761,11 +2784,10 @@ static bool perf_hw_regs(struct pt_regs *regs)
 void
 perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct unwind_state state;
 	unsigned long addr;
 
-	if (guest_cbs && guest_cbs->state()) {
+	if (static_call(x86_guest_state)()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2865,11 +2887,10 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
 void
 perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
 	struct stack_frame frame;
 	const struct stack_frame __user *fp;
 
-	if (guest_cbs && guest_cbs->state()) {
+	if (static_call(x86_guest_state)()) {
 		/* TODO: We don't support guest os callchain now */
 		return;
 	}
@@ -2946,18 +2967,15 @@ static unsigned long code_segment_base(struct pt_regs *regs)
 
 unsigned long perf_instruction_pointer(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
-
-	if (guest_cbs && guest_cbs->state())
-		return guest_cbs->get_ip();
+	if (static_call(x86_guest_state)())
+		return static_call(x86_guest_get_ip)();
 
 	return regs->ip + code_segment_base(regs);
 }
 
 unsigned long perf_misc_flags(struct pt_regs *regs)
 {
-	struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs();
-	unsigned int guest_state = guest_cbs ? guest_cbs->state() : 0;
+	unsigned int guest_state = static_call(x86_guest_state)();
 	int misc = 0;
 
 	if (guest_state) {
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 524ad1f747bd..fb1bd7a0e1a6 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2782,11 +2782,12 @@ static void intel_pmu_reset(void)
 	local_irq_restore(flags);
 }
 
+DECLARE_STATIC_CALL(x86_guest_handle_intel_pt_intr, *(perf_guest_cbs->handle_intel_pt_intr));
+
 static int handle_pmi_common(struct pt_regs *regs, u64 status)
 {
 	struct perf_sample_data data;
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	struct perf_guest_info_callbacks *guest_cbs;
 	int bit;
 	int handled = 0;
 	u64 intel_ctrl = hybrid(cpuc->pmu, intel_ctrl);
@@ -2853,9 +2854,7 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
 	 */
 	if (__test_and_clear_bit(GLOBAL_STATUS_TRACE_TOPAPMI_BIT, (unsigned long *)&status)) {
 		handled++;
-
-		guest_cbs = perf_get_guest_cbs();
-		if (likely(!guest_cbs || !guest_cbs->handle_intel_pt_intr()))
+		if (!static_call(x86_guest_handle_intel_pt_intr)())
 			intel_pt_interrupt();
 	}
 
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index a5d5893b80b0..3fa1014218f4 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1240,14 +1240,7 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
 
 #ifdef CONFIG_HAVE_GUEST_PERF_EVENTS
 extern struct perf_guest_info_callbacks *perf_guest_cbs;
-static inline struct perf_guest_info_callbacks *perf_get_guest_cbs(void)
-{
-	/* Reg/unreg perf_guest_cbs waits for readers via synchronize_rcu(). */
-	lockdep_assert_preemption_disabled();
-
-	/* Prevent reloading between a !NULL check and dereferences. */
-	return READ_ONCE(perf_guest_cbs);
-}
+extern void arch_perf_update_guest_cbs(struct perf_guest_info_callbacks *guest_cbs);
 extern void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
 extern void perf_unregister_guest_info_callbacks(void);
 #endif /* CONFIG_HAVE_GUEST_PERF_EVENTS */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index ec36e7aded89..fb0fd670ab23 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6491,6 +6491,7 @@ void perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
 		return;
 
 	WRITE_ONCE(perf_guest_cbs, cbs);
+	arch_perf_update_guest_cbs(cbs);
 	synchronize_rcu();
 }
 EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
@@ -6498,6 +6499,7 @@ EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
 void perf_unregister_guest_info_callbacks(void)
 {
 	WRITE_ONCE(perf_guest_cbs, NULL);
+	arch_perf_update_guest_cbs(NULL);
 	synchronize_rcu();
 }
 EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
-- 
2.33.0.259.gc128427fd7-goog



From seanjc at google.com  Fri Aug 27 17:35:58 2021
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 27 Aug 2021 17:35:58 -0700
Subject: [PATCH v2 13/13] KVM: arm64: Drop perf.c and fold its tiny bits of
 code into arm.c / pmu.c
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828003558.713983-14-seanjc@google.com>

Call KVM's (un)register perf callbacks helpers directly from arm.c, and
move the PMU bits into pmu.c and rename the related helper accordingly.

Signed-off-by: Sean Christopherson <seanjc at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  3 ---
 arch/arm64/kvm/Makefile           |  2 +-
 arch/arm64/kvm/arm.c              |  6 ++++--
 arch/arm64/kvm/perf.c             | 27 ---------------------------
 arch/arm64/kvm/pmu.c              |  8 ++++++++
 include/kvm/arm_pmu.h             |  1 +
 6 files changed, 14 insertions(+), 33 deletions(-)
 delete mode 100644 arch/arm64/kvm/perf.c

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 73dc402ded1f..d549b58120bc 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -670,9 +670,6 @@ unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
 int kvm_handle_mmio_return(struct kvm_vcpu *vcpu);
 int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
 
-void kvm_perf_init(void);
-void kvm_perf_teardown(void);
-
 #ifdef CONFIG_PERF_EVENTS
 #define __KVM_WANT_PERF_CALLBACKS
 static inline bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 989bb5dad2c8..0bcc378b7961 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_KVM) += hyp/
 
 kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
 	 $(KVM)/vfio.o $(KVM)/irqchip.o $(KVM)/binary_stats.o \
-	 arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \
+	 arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 inject_fault.o va_layout.o handle_exit.o \
 	 guest.o debug.o reset.o sys_regs.o \
 	 vgic-sys-reg-v3.o fpsimd.o pmu.o \
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 2b542fdc237e..48f89d80f464 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1744,7 +1744,9 @@ static int init_subsystems(void)
 	if (err)
 		goto out;
 
-	kvm_perf_init();
+	kvm_pmu_init();
+	kvm_register_perf_callbacks(NULL);
+
 	kvm_sys_reg_table_init();
 
 out:
@@ -2160,7 +2162,7 @@ int kvm_arch_init(void *opaque)
 /* NOP: Compiling as a module not supported */
 void kvm_arch_exit(void)
 {
-	kvm_perf_teardown();
+	kvm_unregister_perf_callbacks();
 }
 
 static int __init early_kvm_mode_cfg(char *arg)
diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
deleted file mode 100644
index 0b902e0d5b5d..000000000000
--- a/arch/arm64/kvm/perf.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Based on the x86 implementation.
- *
- * Copyright (C) 2012 ARM Ltd.
- * Author: Marc Zyngier <marc.zyngier at arm.com>
- */
-
-#include <linux/perf_event.h>
-#include <linux/kvm_host.h>
-
-#include <asm/kvm_emulate.h>
-
-DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
-
-void kvm_perf_init(void)
-{
-	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
-		static_branch_enable(&kvm_arm_pmu_available);
-
-	kvm_register_perf_callbacks(NULL);
-}
-
-void kvm_perf_teardown(void)
-{
-	kvm_unregister_perf_callbacks();
-}
diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
index 03a6c1f4a09a..d98b57a17043 100644
--- a/arch/arm64/kvm/pmu.c
+++ b/arch/arm64/kvm/pmu.c
@@ -7,6 +7,14 @@
 #include <linux/perf_event.h>
 #include <asm/kvm_hyp.h>
 
+DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
+
+void kvm_pmu_init(void)
+{
+	if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled())
+		static_branch_enable(&kvm_arm_pmu_available);
+}
+
 /*
  * Given the perf event attributes and system type, determine
  * if we are going to need to switch counters at guest entry/exit.
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index 864b9997efb2..42270676498d 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -14,6 +14,7 @@
 #define ARMV8_PMU_MAX_COUNTER_PAIRS	((ARMV8_PMU_MAX_COUNTERS + 1) >> 1)
 
 DECLARE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
+void kvm_pmu_init(void);
 
 static __always_inline bool kvm_arm_support_pmu_v3(void)
 {
-- 
2.33.0.259.gc128427fd7-goog



From wangkefeng.wang at huawei.com  Fri Aug 27 18:09:08 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Sat, 28 Aug 2021 09:09:08 +0800
Subject: [BUG] amba: Remove deferred device addition
In-Reply-To: <CAGETcx-N4+u0iw9n5ncx_9MNnTa3ViyesxsDD7xN3jtEPT-uBw@mail.gmail.com>
References: <20210816074619.177383-1-wangkefeng.wang@huawei.com>
 <20210816074619.177383-4-wangkefeng.wang@huawei.com>
 <CAL_JsqLBddXVeP-t++wqPNp=xYF7tvEcnCbjFnK9CUBLK2+9JA@mail.gmail.com>
 <CAGETcx8SY14rcd7g=Gdwmw7sUMb=jdEV+ffuNpg6btDoL1jmWw@mail.gmail.com>
 <ee649111-dc07-d6db-8872-dcb692802236@huawei.com>
 <CAGETcx9drOdE_vfn-nhDZM9MbgxGxYJN6ydiAVxo_Ltqve9eTg@mail.gmail.com>
 <b5eb935f-26e1-6475-63af-e7f6101eb017@huawei.com>
 <CAGETcx9yaWZOzt=gcyNAshoHdPoYizhmrKS-kU9c2QM2+HqeEw@mail.gmail.com>
 <df8e7756-8b0d-d7de-a9ff-3f6eb0ffa8a5@huawei.com>
 <CAGETcx-47yRUcBjEdWFBtroSEkHXRNrJ4zaD8WpE0DPEPp9NxQ@mail.gmail.com>
 <85b28900-5f42-b997-2ded-0b952bc2a03e@huawei.com>
 <CAGETcx-N4+u0iw9n5ncx_9MNnTa3ViyesxsDD7xN3jtEPT-uBw@mail.gmail.com>
Message-ID: <265bb783-10da-a7c1-2625-055dec5643a3@huawei.com>


On 2021/8/28 3:09, Saravana Kannan wrote:
> On Fri, Aug 27, 2021 at 7:38 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>
>> On 2021/8/27 8:04, Saravana Kannan wrote:
>>> On Thu, Aug 26, 2021 at 1:22 AM Kefeng Wang <wangkefeng.wang at huawei.com> wrote:
>>>>>>> Btw, I've been working on [1] cleaning up the one-off deferred probe
>>>>>>> solution that we have for amba devices. That causes a bunch of other
>>>>>>> headaches. Your patch 3/3 takes us further in the wrong direction by
>>>>>>> adding more reasons for delaying the addition of the device.
>>>> Hi Saravana, I try the link[1], but with it, there is a crash when boot
>>>> (qemu-system-arm -M vexpress-a15),
> I'm assuming it's this one?
> arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts

I use arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts.

qemu-system-arm -M vexpress-a15 -dtb vexpress-v2p-ca15-tc1.dtb -cpu 
cortex-a15 -smp 2 -m size=3G -kernel zImage -rtc base=localtime -initrd 
initrd-arm32 -append 'console=ttyAMA0 cma=0 kfence.sample_interval=0 
earlyprintk debug ' -device virtio-net-device,netdev=net8 -netdev 
type=tap,id=net8,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown 
-nographic

>
>>> Hi,
>>>
>>> It's hard to make sense of the logs. Looks like two different threads
>>> might be printing to the log at the same time? Can you please enable
>>> the config that prints the thread ID (forgot what it's called) and
>>> collect this again? With what I could tell the crash seems to be
>>> happening somewhere in platform_match(), but that's not related to
>>> this patch at all?
>> Can you reproduce it? it is very likely related(without your patch, the
>> boot is fine),
> Sorry, I haven't ever setup qemu and booted vexpress. Thanks for your help.
>
>> the NULL ptr is about serio, it is registed from amba driver.
>>
>> ambakmi_driver_init
>>
>>    -- amba_kmi_probe
>>
>>      -- __serio_register_port
> Thanks for the pointer. I took a look at the logs and the code. It's
> very strange. As you can see from the backtrace, platform_match() is
> being called for the device_add() from serio_handle_event(). But the
> device that gets added there is on the serio_bus which obviously
> should be using the serio_bus_match.
Yes, I am confused too.
>
>> +Dmitry and input maillist, is there some known issue about serio ?
>>
>> I add some debug, the full log is attached.
>>
>> [    2.958355][   T41] input: AT Raw Set 2 keyboard as
>> /devices/platform/bus at 8000000/bus at 8000000:motherboard-bus/bus at 8000000:motherboard-bus:iofpga-bus at 300000000/1c060000.kmi/serio0/input/input0
>> [    2.977441][   T41] serio serio1: pdev c1e05508, pdev->name (null),
>> drv c1090fc0, drv->name vexpress-reset
> Based on the logs you added, it's pretty clear we are getting to
> platform_match(). It's also strange that the drv->name is
> vexpress-reset
...
>
>> [    3.003113][   T41] Backtrace:
>> [    3.003451][   T41] [<c0560bb4>] (strcmp) from [<c0646358>] (platform_match+0xdc/0xf0)
>> [    3.003963][   T41] [<c064627c>] (platform_match) from [<c06437d4>] (__device_attach_driver+0x3c/0xf4)
>> [    3.004769][   T41] [<c0643798>] (__device_attach_driver) from [<c0641180>] (bus_for_each_drv+0x68/0xc8)
>> [    3.005481][   T41] [<c0641118>] (bus_for_each_drv) from [<c0642f40>] (__device_attach+0xf0/0x16c)
>> [    3.006152][   T41] [<c0642e50>] (__device_attach) from [<c06439d4>] (device_initial_probe+0x1c/0x20)
>> [    3.006853][   T41] [<c06439b8>] (device_initial_probe) from [<c0642030>] (bus_probe_device+0x94/0x9c)
>> [    3.007259][   T41] [<c0641f9c>] (bus_probe_device) from [<c063f9cc>] (device_add+0x408/0x8b8)
>> [    3.007900][   T41] [<c063f5c4>] (device_add) from [<c071c1cc>] (serio_handle_event+0x1b8/0x234)
>> [    3.008824][   T41] [<c071c014>] (serio_handle_event) from [<c01475a4>] (process_one_work+0x238/0x594)
>> [    3.009737][   T41] [<c014736c>] (process_one_work) from [<c014795c>] (worker_thread+0x5c/0x5f4)
>> [    3.010638][   T41] [<c0147900>] (worker_thread) from [<c014feb4>] (kthread+0x178/0x194)
>> [    3.011496][   T41] [<c014fd3c>] (kthread) from [<c0100150>] (ret_from_fork+0x14/0x24)
>> [    3.011860][   T41] Exception stack(0xc1675fb0 to 0xc1675ff8)
> But the platform_match() is happening for the device_add() from
> serio_event_handle() that's adding a device to the serio_bus and it
> should be using serio_bus_match().
>
> I haven't reached any conclusion yet, but my current thought process
> is that it's either:
> 1. My patch is somehow causing list corruption. But I don't directly
> touch any list in my change (other than deleting a list entirely), so
> it's not clear how that would be happening.

Maybe some concurrent driver load?

> 2. Without my patch, these AMBA device's probe would be delayed at
> least until 5 seconds or possibly later. I'm wondering if my patch is
> catching some bad timing assumptions in other code.

After Rob's patch, It will retry soon.

commit 039599c92d3b2e73689e8b6e519d653fd4770abb
Author: Rob Herring <robh at kernel.org>
Date:?? Wed Apr 29 15:58:12 2020 -0500

 ??? amba: Retry adding deferred devices at late_initcall

 ??? If amba bus devices defer when adding, the amba bus code simply retries
 ??? adding the devices every 5 seconds. This doesn't work well as it
 ??? completely unsynchronized with starting the init process which can
 ??? happen in less than 5 secs. Add a retry during late_initcall. If the
 ??? amba devices are added, then deferred probe takes over. If the
 ??? dependencies have not probed at this point, then there's no improvement
 ??? over previous behavior. To completely solve this, we'd need to retry
 ??? after every successful probe as deferred probe does.

 ??? The list_empty() check now happens outside the mutex, but the mutex
 ??? wasn't necessary in the first place.

 ??? This needed to use deferred probe instead of fragile initcall ordering
 ??? on 32-bit VExpress systems where the apb_pclk has a number of probe
 ??? dependencies (vexpress-sysregs, vexpress-config).


>
> You might be able to test out theory (2) by DEFERRED_DEVICE_TIMEOUT to
> a much smaller number. Say 500ms or 100ms. If it doesn't crash, it
> doesn't mean it's not (2), but if it does, then we know for sure it's
> (2).
ok, I will try this one, but due to above patch, it may not work.

>
> I'll continue debugging further.
>
> -Saravana


From nobuhiro1.iwamatsu at toshiba.co.jp  Fri Aug 27 18:14:43 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Sat, 28 Aug 2021 10:14:43 +0900
Subject: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <20210827094815.GA13112@lpieralisi>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <162998285902.30814.11206633831020646086.b4-ty@arm.com>
 <TYAPR01MB6252A29B56BBF8921822824F92C79@TYAPR01MB6252.jpnprd01.prod.outlook.com>
 <20210827094815.GA13112@lpieralisi>
Message-ID: <20210828011443.njafshmejojm7t5t@toshiba.co.jp>

Hi,

On Fri, Aug 27, 2021 at 10:48:15AM +0100, Lorenzo Pieralisi wrote:
> On Thu, Aug 26, 2021 at 11:49:04PM +0000, nobuhiro1.iwamatsu at toshiba.co.jp wrote:
> > Hi,
> > 
> > > -----Original Message-----
> > > From: Lorenzo Pieralisi [mailto:lorenzo.pieralisi at arm.com]
> > > Sent: Thursday, August 26, 2021 10:01 PM
> > > To: iwamatsu nobuhiro(?? ?? ????????) <nobuhiro1.iwamatsu at toshiba.co.jp>; Rob Herring
> > > <robh+dt at kernel.org>; Bjorn Helgaas <bhelgaas at google.com>
> > > Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>; Kishon Vijay Abraham I <kishon at ti.com>; ishikawa yuji(?? ??
> > > ?????????????) <yuji2.ishikawa at toshiba.co.jp>; linux-arm-kernel at lists.infradead.org;
> > > linux-pci at vger.kernel.org; Krzysztof Wilczy?ski <kw at linux.com>; agrawal punit(????? ??? ????????)
> > > <punit1.agrawal at toshiba.co.jp>; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org
> > > Subject: Re: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host controller driver
> > > 
> > > On Wed, 11 Aug 2021 17:38:27 +0900, Nobuhiro Iwamatsu wrote:
> > > > This series is the PCIe driver for Toshiba's ARM SoC, Visconti[0].
> > > > This provides DT binding documentation, device driver, MAINTAINER files.
> > > >
> > > > Best regards,
> > > >   Nobuhiro
> > > >
> > > > [0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html
> > > >
> > > > [...]
> > > 
> > > Applied to pci/dwc, thanks!
> > 
> > Thanks! But...
> > > 
> > > [1/3] dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
> > >       https://git.kernel.org/lpieralisi/pci/c/a655ce4000
> > > [2/3] PCI: visconti: Add Toshiba Visconti PCIe host controller driver
> > >       https://git.kernel.org/lpieralisi/pci/c/09436f819c
> > 
> > Only drivers/pci/controller/dwc/Makefile is applied. Could you check this?	
> 
> I fixed this. Please don't write patch versions changes in the commit
> log - I had to delete those myself, I did not notice while applying
> them.

Sorry about this.

> 
> Please let me know if the branch looks OK now.
> 

Looks good to me.
Thanks for your work.

> Lorenzo
> 
> > > [3/3] MAINTAINERS: Add entries for Toshiba Visconti PCIe controller
> > >       https://git.kernel.org/lpieralisi/pci/c/34af7aace1
> > > 
> > > Thanks,
> > > Lorenzo
> > 

Best regards,
  Nobuhiro




From leoyang.li at nxp.com  Fri Aug 27 18:38:02 2021
From: leoyang.li at nxp.com (Li Yang)
Date: Fri, 27 Aug 2021 20:38:02 -0500
Subject: [PATCH devicetree 2/2] arm64: dts: add device tree for the
 LX2160A on the NXP BlueBox3 board
In-Reply-To: <20210827202722.2567687-2-vladimir.oltean@nxp.com>
References: <20210827202722.2567687-1-vladimir.oltean@nxp.com>
 <20210827202722.2567687-2-vladimir.oltean@nxp.com>
Message-ID: <CADRPPNQg052Nradvyoiw9Yqe4HiRtWs8-yna87R2VUwwH8GPeg@mail.gmail.com>

On Fri, Aug 27, 2021 at 3:28 PM Vladimir Oltean <vladimir.oltean at nxp.com> wrote:
>
> From: Wasim Khan <wasim.khan at nxp.com>
>
> The NXP BlueBox3 is a prototyping board for high-performance autonomous
> driving systems. It contains two Linux systems, on running on the
> LX2160A and the other on the S32G2 SoC. This patch adds the device tree
> support for the LX2160A SoC.
>
> In terms of networking from the LX2160A's perspective, there are:
>
> - 4 RJ45 10G ports using Aquantia copper PHYs which are attached
>   directly to DPAA2 ports on the LX2160A
>
> - 3 NXP SJA1110 automotive Ethernet switches. First two are managed by
>   the LX2160A (each switch has a host port towards a dpmac), the third
>   switch is managed by the S32G2. All 3 switches are interconnected
>   through on-board SERDES lanes. The cascade ports between the 2
>   switches managed by LX2160A form a DSA link, the cascade ports between
>   the LX2160A and the S32G2 domain form user ports (the "to_sw3" net
>   device).
>
> - 2 RJ45 1G ports using Atheros copper PHYs which are attached directly
>   to NXP SJA1110 switches
>
> - 12 automotive 100base-T1 single-pair Ethernet ports routed from the
>   SJA1110 internal PHY ports (TJA1103)
>
> - One SGMII SERDES lane towards an internal connector, attached to one
>   of the SJA1110 switch ports
>
> On board rev A, the AR8035 RGMII PHY addresses were different than on
> rev B and later. This patch introduces a separate device tree for rev A.
> The main device tree is supposed to cover rev B and later.
>
> Signed-off-by: Wasim Khan <wasim.khan at nxp.com>
> Co-developed-by: Vabhav Sharma <vabhav.sharma at nxp.com>
> Signed-off-by: Vabhav Sharma <vabhav.sharma at nxp.com>
> Co-developed-by: Kuldeep Singh <kuldeep.singh at nxp.com>
> Signed-off-by: Kuldeep Singh <kuldeep.singh at nxp.com>
> Co-developed-by: Florin Chiculita <florinlaurentiu.chiculita at nxp.com>
> Signed-off-by: Florin Chiculita <florinlaurentiu.chiculita at nxp.com>
> Co-developed-by: Biwen Li <biwen.li at nxp.com>
> Signed-off-by: Biwen Li <biwen.li at nxp.com>
> Co-developed-by: Heinz Wrobel <Heinz.Wrobel at nxp.com>
> Signed-off-by: Heinz Wrobel <Heinz.Wrobel at nxp.com>
> Co-developed-by: Yangbo Lu <yangbo.lu at nxp.com>
> Signed-off-by: Yangbo Lu <yangbo.lu at nxp.com>
> Co-developed-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>

Acked-by: Li Yang <leoyang.li at nxp.com>

> ---
>  arch/arm64/boot/dts/freescale/Makefile        |   2 +
>  .../freescale/fsl-lx2160a-bluebox3-rev-a.dts  |  34 +
>  .../dts/freescale/fsl-lx2160a-bluebox3.dts    | 658 ++++++++++++++++++
>  3 files changed, 694 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3-rev-a.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts
>
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index db9e36ebe932..ecf74464705f 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -25,6 +25,8 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-bluebox3.dtb
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-bluebox3-rev-a.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-clearfog-cx.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-honeycomb.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3-rev-a.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3-rev-a.dts
> new file mode 100644
> index 000000000000..15d273c93154
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3-rev-a.dts
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Device Tree file for LX2160A BLUEBOX3
> +//
> +// Copyright 2020-2021 NXP
> +
> +/dts-v1/;
> +
> +#include "fsl-lx2160a-bluebox3.dts"
> +
> +/ {
> +       compatible = "fsl,lx2160a-bluebox3-rev-a", "fsl,lx2160a";
> +};
> +
> +/* The RGMII PHYs have a different MDIO address */
> +&emdio1 {
> +       /delete-node/ ethernet-phy at 5;
> +
> +       sw1_mii3_phy: ethernet-phy at 1 {
> +               /* AR8035 */
> +               compatible = "ethernet-phy-id004d.d072";
> +               reg = <0x1>;
> +               interrupts-extended = <&extirq 6 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +
> +       /delete-node/ ethernet-phy at 6;
> +
> +       sw2_mii3_phy: ethernet-phy at 2 {
> +               /* AR8035 */
> +               compatible = "ethernet-phy-id004d.d072";
> +               reg = <0x2>;
> +               interrupts-extended = <&extirq 7 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +};
> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts
> new file mode 100644
> index 000000000000..be7d01630a6f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-bluebox3.dts
> @@ -0,0 +1,658 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Device Tree file for LX2160A BLUEBOX3
> +//
> +// Copyright 2020-2021 NXP
> +
> +/dts-v1/;
> +
> +#include "fsl-lx2160a.dtsi"
> +
> +/ {
> +       model = "NXP Layerscape LX2160ABLUEBOX3";
> +       compatible = "fsl,lx2160a-bluebox3", "fsl,lx2160a";
> +
> +       aliases {
> +               crypto = &crypto;
> +               serial0 = &uart0;
> +               mmc0 = &esdhc0;
> +               mmc1 = &esdhc1;
> +       };
> +
> +       chosen {
> +               stdout-path = "serial0:115200n8";
> +       };
> +
> +       sb_3v3: regulator-sb3v3 {
> +               compatible = "regulator-fixed";
> +               regulator-name = "MC34717-3.3VSB";
> +               regulator-min-microvolt = <3300000>;
> +               regulator-max-microvolt = <3300000>;
> +               regulator-boot-on;
> +               regulator-always-on;
> +       };
> +};
> +
> +&can0 {
> +       status = "okay";
> +
> +       can-transceiver {
> +               max-bitrate = <5000000>;
> +       };
> +};
> +
> +&can1 {
> +       status = "okay";
> +
> +       can-transceiver {
> +               max-bitrate = <5000000>;
> +       };
> +};
> +
> +&crypto {
> +       status = "okay";
> +};
> +
> +&dpmac5 {
> +       phy-handle = <&aqr113c_phy1>;
> +       phy-mode = "usxgmii";
> +       managed = "in-band-status";
> +};
> +
> +&dpmac6 {
> +       phy-handle = <&aqr113c_phy2>;
> +       phy-mode = "usxgmii";
> +       managed = "in-band-status";
> +};
> +
> +&dpmac9 {
> +       phy-handle = <&aqr113c_phy3>;
> +       phy-mode = "usxgmii";
> +       managed = "in-band-status";
> +};
> +
> +&dpmac10 {
> +       phy-handle = <&aqr113c_phy4>;
> +       phy-mode = "usxgmii";
> +       managed = "in-band-status";
> +};
> +
> +&dpmac17 {
> +       phy-mode = "rgmii";
> +       status = "okay";
> +
> +       fixed-link {
> +               speed = <1000>;
> +               full-duplex;
> +       };
> +};
> +
> +&dpmac18 {
> +       phy-mode = "rgmii";
> +       status = "okay";
> +
> +       fixed-link {
> +               speed = <1000>;
> +               full-duplex;
> +       };
> +};
> +
> +&emdio1 {
> +       status = "okay";
> +
> +       aqr113c_phy2: ethernet-phy at 0 {
> +               compatible = "ethernet-phy-ieee802.3-c45";
> +               reg = <0x0>;
> +               /* IRQ_10G_PHY2 */
> +               interrupts-extended = <&extirq 3 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +
> +       aqr113c_phy1: ethernet-phy at 8 {
> +               compatible = "ethernet-phy-ieee802.3-c45";
> +               reg = <0x8>;
> +               /* IRQ_10G_PHY1 */
> +               interrupts-extended = <&extirq 2 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +
> +       sw1_mii3_phy: ethernet-phy at 5 {
> +               /* AR8035 */
> +               compatible = "ethernet-phy-id004d.d072";
> +               reg = <0x5>;
> +               interrupts-extended = <&extirq 6 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +
> +       sw2_mii3_phy: ethernet-phy at 6 {
> +               /* AR8035 */
> +               compatible = "ethernet-phy-id004d.d072";
> +               reg = <0x6>;
> +               interrupts-extended = <&extirq 7 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +};
> +
> +&emdio2 {
> +       status = "okay";
> +
> +       aqr113c_phy4: ethernet-phy at 0 {
> +               compatible = "ethernet-phy-ieee802.3-c45";
> +               reg = <0x0>;
> +               /* IRQ_10G_PHY4 */
> +               interrupts-extended = <&extirq 5 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +
> +       aqr113c_phy3: ethernet-phy at 8 {
> +               compatible = "ethernet-phy-ieee802.3-c45";
> +               reg = <0x8>;
> +               /* IRQ_10G_PHY3 */
> +               interrupts-extended = <&extirq 4 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +};
> +
> +&esdhc0 {
> +       sd-uhs-sdr104;
> +       sd-uhs-sdr50;
> +       sd-uhs-sdr25;
> +       sd-uhs-sdr12;
> +       status = "okay";
> +};
> +
> +&esdhc1 {
> +       mmc-hs200-1_8v;
> +       mmc-hs400-1_8v;
> +       bus-width = <8>;
> +       status = "okay";
> +};
> +
> +&fspi {
> +       status = "okay";
> +
> +       mt35xu512aba0: flash at 0 {
> +               compatible = "jedec,spi-nor";
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               reg = <0>;
> +               m25p,fast-read;
> +               spi-max-frequency = <50000000>;
> +               spi-rx-bus-width = <8>;
> +               spi-tx-bus-width = <8>;
> +       };
> +
> +       mt35xu512aba1: flash at 1 {
> +               compatible = "jedec,spi-nor";
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               reg = <1>;
> +               m25p,fast-read;
> +               spi-max-frequency = <50000000>;
> +               spi-rx-bus-width = <8>;
> +               spi-tx-bus-width = <8>;
> +       };
> +};
> +
> +&i2c0 {
> +       status = "okay";
> +
> +       i2c-mux at 77 {
> +               compatible = "nxp,pca9547";
> +               reg = <0x77>;
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               i2c at 2 {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       reg = <0x2>;
> +
> +                       power-monitor at 40 {
> +                               compatible = "ti,ina220";
> +                               reg = <0x40>;
> +                               shunt-resistor = <500>;
> +                       };
> +               };
> +
> +               i2c at 3 {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       reg = <0x3>;
> +
> +                       temp2: temperature-sensor at 48 {
> +                               compatible = "nxp,sa56004";
> +                               reg = <0x48>;
> +                               vcc-supply = <&sb_3v3>;
> +                               #thermal-sensor-cells = <1>;
> +                       };
> +
> +                       temp1: temperature-sensor at 4c {
> +                               compatible = "nxp,sa56004";
> +                               reg = <0x4c>;
> +                               vcc-supply = <&sb_3v3>;
> +                               #thermal-sensor-cells = <1>;
> +                       };
> +               };
> +
> +               i2c at 4 {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       reg = <0x4>;
> +
> +                       rtc at 51 {
> +                               compatible = "nxp,pcf2129";
> +                               reg = <0x51>;
> +                               interrupts-extended = <&extirq 11 IRQ_TYPE_LEVEL_LOW>;
> +                       };
> +               };
> +
> +               i2c at 7 {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       reg = <0x7>;
> +
> +                       i2c-mux at 75 {
> +                               compatible = "nxp,pca9547";
> +                               reg = <0x75>;
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +
> +                               i2c at 0 {
> +                                       #address-cells = <1>;
> +                                       #size-cells = <0>;
> +                                       reg = <0x0>;
> +
> +                                       spi_bridge: spi at 28 {
> +                                               compatible = "nxp,sc18is602b";
> +                                               reg = <0x28>;
> +                                               #address-cells = <1>;
> +                                               #size-cells = <0>;
> +                                       };
> +                               };
> +                       };
> +               };
> +       };
> +};
> +
> +&i2c5 {
> +       status = "okay";
> +
> +       i2c-mux at 77 {
> +               compatible = "nxp,pca9846";
> +               reg = <0x77>;
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               i2c at 1 {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       reg = <0x1>;
> +
> +                       /* The I2C multiplexer and temperature sensors are on
> +                        * the T6 riser card.
> +                        */
> +                       i2c-mux at 70 {
> +                               compatible = "nxp,pca9548";
> +                               reg = <0x70>;
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +
> +                               i2c at 6 {
> +                                       #address-cells = <1>;
> +                                       #size-cells = <0>;
> +                                       reg = <0x6>;
> +
> +                                       q12: temperature-sensor at 4c {
> +                                               compatible = "nxp,sa56004";
> +                                               reg = <0x4c>;
> +                                               vcc-supply = <&sb_3v3>;
> +                                               #thermal-sensor-cells = <1>;
> +                                       };
> +                               };
> +
> +                               i2c at 7 {
> +                                       #address-cells = <1>;
> +                                       #size-cells = <0>;
> +                                       reg = <0x7>;
> +
> +                                       q11: temperature-sensor at 4c {
> +                                               compatible = "nxp,sa56004";
> +                                               reg = <0x4c>;
> +                                               vcc-supply = <&sb_3v3>;
> +                                               #thermal-sensor-cells = <1>;
> +                                       };
> +
> +                                       q13: temperature-sensor at 48 {
> +                                               compatible = "nxp,sa56004";
> +                                               reg = <0x48>;
> +                                               vcc-supply = <&sb_3v3>;
> +                                               #thermal-sensor-cells = <1>;
> +                                       };
> +
> +                                       q14: temperature-sensor at 4a {
> +                                               compatible = "nxp,sa56004";
> +                                               reg = <0x4a>;
> +                                               vcc-supply = <&sb_3v3>;
> +                                               #thermal-sensor-cells = <1>;
> +                                       };
> +                               };
> +                       };
> +               };
> +       };
> +};
> +
> +&pcs_mdio5 {
> +       status = "okay";
> +};
> +
> +&pcs_mdio6 {
> +       status = "okay";
> +};
> +
> +&pcs_mdio9 {
> +       status = "okay";
> +};
> +
> +&pcs_mdio10 {
> +       status = "okay";
> +};
> +
> +&spi_bridge {
> +       sw1: ethernet-switch at 0 {
> +               compatible = "nxp,sja1110a";
> +               reg = <0>;
> +               spi-max-frequency = <4000000>;
> +               spi-cpol;
> +               dsa,member = <0 0>;
> +
> +               ethernet-ports {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       /* Microcontroller port */
> +                       port at 0 {
> +                               reg = <0>;
> +                               status = "disabled";
> +                       };
> +
> +                       /* SW1_P1 */
> +                       port at 1 {
> +                               reg = <1>;
> +                               label = "con_2x20";
> +                               phy-mode = "sgmii";
> +
> +                               fixed-link {
> +                                       speed = <1000>;
> +                                       full-duplex;
> +                               };
> +                       };
> +
> +                       port at 2 {
> +                               reg = <2>;
> +                               ethernet = <&dpmac17>;
> +                               phy-mode = "rgmii-id";
> +
> +                               fixed-link {
> +                                       speed = <1000>;
> +                                       full-duplex;
> +                               };
> +                       };
> +
> +                       port at 3 {
> +                               reg = <3>;
> +                               label = "1ge_p1";
> +                               phy-mode = "rgmii-id";
> +                               phy-handle = <&sw1_mii3_phy>;
> +                       };
> +
> +                       sw1p4: port at 4 {
> +                               reg = <4>;
> +                               link = <&sw2p1>;
> +                               phy-mode = "sgmii";
> +
> +                               fixed-link {
> +                                       speed = <1000>;
> +                                       full-duplex;
> +                               };
> +                       };
> +
> +                       port at 5 {
> +                               reg = <5>;
> +                               label = "trx1";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw1_port5_base_t1_phy>;
> +                       };
> +
> +                       port at 6 {
> +                               reg = <6>;
> +                               label = "trx2";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw1_port6_base_t1_phy>;
> +                       };
> +
> +                       port at 7 {
> +                               reg = <7>;
> +                               label = "trx3";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw1_port7_base_t1_phy>;
> +                       };
> +
> +                       port at 8 {
> +                               reg = <8>;
> +                               label = "trx4";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw1_port8_base_t1_phy>;
> +                       };
> +
> +                       port at 9 {
> +                               reg = <9>;
> +                               label = "trx5";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw1_port9_base_t1_phy>;
> +                       };
> +
> +                       port at a {
> +                               reg = <10>;
> +                               label = "trx6";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw1_port10_base_t1_phy>;
> +                       };
> +               };
> +
> +               mdios {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       mdio at 0 {
> +                               compatible = "nxp,sja1110-base-t1-mdio";
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +                               reg = <0>;
> +
> +                               sw1_port5_base_t1_phy: ethernet-phy at 1 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x1>;
> +                               };
> +
> +                               sw1_port6_base_t1_phy: ethernet-phy at 2 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x2>;
> +                               };
> +
> +                               sw1_port7_base_t1_phy: ethernet-phy at 3 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x3>;
> +                               };
> +
> +                               sw1_port8_base_t1_phy: ethernet-phy at 4 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x4>;
> +                               };
> +
> +                               sw1_port9_base_t1_phy: ethernet-phy at 5 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x5>;
> +                               };
> +
> +                               sw1_port10_base_t1_phy: ethernet-phy at 6 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x6>;
> +                               };
> +                       };
> +               };
> +       };
> +
> +       sw2: ethernet-switch at 2 {
> +               compatible = "nxp,sja1110a";
> +               reg = <2>;
> +               spi-max-frequency = <4000000>;
> +               spi-cpol;
> +               dsa,member = <0 1>;
> +
> +               ethernet-ports {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       /* Microcontroller port */
> +                       port at 0 {
> +                               reg = <0>;
> +                               status = "disabled";
> +                       };
> +
> +                       sw2p1: port at 1 {
> +                               reg = <1>;
> +                               link = <&sw1p4>;
> +                               phy-mode = "sgmii";
> +
> +                               fixed-link {
> +                                       speed = <1000>;
> +                                       full-duplex;
> +                               };
> +                       };
> +
> +                       port at 2 {
> +                               reg = <2>;
> +                               ethernet = <&dpmac18>;
> +                               phy-mode = "rgmii-id";
> +
> +                               fixed-link {
> +                                       speed = <1000>;
> +                                       full-duplex;
> +                               };
> +                       };
> +
> +                       port at 3 {
> +                               reg = <3>;
> +                               label = "1ge_p2";
> +                               phy-mode = "rgmii-id";
> +                               phy-handle = <&sw2_mii3_phy>;
> +                       };
> +
> +                       port at 4 {
> +                               reg = <4>;
> +                               label = "to_sw3";
> +                               phy-mode = "2500base-x";
> +
> +                               fixed-link {
> +                                       speed = <2500>;
> +                                       full-duplex;
> +                               };
> +                       };
> +
> +                       port at 5 {
> +                               reg = <5>;
> +                               label = "trx7";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw2_port5_base_t1_phy>;
> +                       };
> +
> +                       port at 6 {
> +                               reg = <6>;
> +                               label = "trx8";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw2_port6_base_t1_phy>;
> +                       };
> +
> +                       port at 7 {
> +                               reg = <7>;
> +                               label = "trx9";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw2_port7_base_t1_phy>;
> +                       };
> +
> +                       port at 8 {
> +                               reg = <8>;
> +                               label = "trx10";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw2_port8_base_t1_phy>;
> +                       };
> +
> +                       port at 9 {
> +                               reg = <9>;
> +                               label = "trx11";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw2_port9_base_t1_phy>;
> +                       };
> +
> +                       port at a {
> +                               reg = <10>;
> +                               label = "trx12";
> +                               phy-mode = "internal";
> +                               phy-handle = <&sw2_port10_base_t1_phy>;
> +                       };
> +               };
> +
> +               mdios {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       mdio at 0 {
> +                               compatible = "nxp,sja1110-base-t1-mdio";
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +                               reg = <0>;
> +
> +                               sw2_port5_base_t1_phy: ethernet-phy at 1 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x1>;
> +                               };
> +
> +                               sw2_port6_base_t1_phy: ethernet-phy at 2 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x2>;
> +                               };
> +
> +                               sw2_port7_base_t1_phy: ethernet-phy at 3 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x3>;
> +                               };
> +
> +                               sw2_port8_base_t1_phy: ethernet-phy at 4 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x4>;
> +                               };
> +
> +                               sw2_port9_base_t1_phy: ethernet-phy at 5 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x5>;
> +                               };
> +
> +                               sw2_port10_base_t1_phy: ethernet-phy at 6 {
> +                                       compatible = "ethernet-phy-ieee802.3-c45";
> +                                       reg = <0x6>;
> +                               };
> +                       };
> +               };
> +       };
> +};
> +
> +&uart0 {
> +       status = "okay";
> +};
> +
> +&uart1 {
> +       status = "okay";
> +};
> +
> +&usb0 {
> +       status = "okay";
> +};
> +
> +&usb1 {
> +       status = "okay";
> +};
> --
> 2.25.1
>


From shaolexi at huawei.com  Fri Aug 27 19:21:31 2021
From: shaolexi at huawei.com (Lexi Shao)
Date: Sat, 28 Aug 2021 10:21:31 +0800
Subject: [PATCH] ARM: kasan: Fix __get_user_check failure with kasan
In-Reply-To: <20210827125601.GT22278@shell.armlinux.org.uk>
References: <20210827125601.GT22278@shell.armlinux.org.uk>
Message-ID: <20210828022131.45042-1-shaolexi@huawei.com>

>On Wed, Aug 25, 2021 at 02:46:50PM +0800, Lexi Shao wrote:
>> In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
>> error code is store in register int __e(r0). When kasan is
>> enabled, assigning value to kernel address might trigger kasan check,
>> which unexpectedly overwrites r0 and causes undefined behavior on arm
>> kasan images.
>> 
>> One example is failure in do_futex and results in process soft lockup.
>> Log:
>> watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
>> Q:Reg:1151]
>> ...
>> (__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
>> (futex_wait_setup) from (futex_wait+0x138/0x394)
>> (futex_wait) from (do_futex+0x164/0xe40)
>> (do_futex) from (sys_futex_time32+0x178/0x230)
>> (sys_futex_time32) from (ret_fast_syscall+0x0/0x50)
>> 
>> The soft lockup happens in function futex_wait_setup. The reason is
>> function get_futex_value_locked always return EINVAL, thus pc jump
>> back to retry label and causes looping.
>> 
>> The assembly code of get_futex_value_locked in kernel/futex.c:
>> ...
>> c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
>> // "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
>> c01f6dcc:       e1a00007        mov     r0, r7
>> c01f6dd0:       e1a05002        mov     r5, r2
>> c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
>> c01f6dd8:       e5875000        str     r5, [r7]
>> // save ret value of __get_user(*dest, from), which is dest address now
>> c01f6ddc:       e1a05000        mov     r5, r0
>> ...
>> // checking return value of __get_user failed
>> c01f6e00:       e3550000        cmp     r5, #0
>> ...
>> c01f6e0c:       01a00005        moveq   r0, r5
>> // assign return value to EINVAL
>> c01f6e10:       13e0000d        mvnne   r0, #13
>> 
>> Return value is the destination address of get_user thus certainly
>> non-zero, so get_futex_value_locked always return EINVAL.
>
>This description doesn't actually make it clear why this is failing in
>this case, until one looks at get_futex_value_locked() and realises
>that what is actually going on here is:
>
>	*dest = (typeof(*(p))) __r2;
>
>which is why we end up with the store there.
>
>> Fix it by using a tmp vairable to store the error code before the
>> assignment. This fix has no effects to non-kasan images thanks to compiler
>> optimization. It only affects cases that overwrite r0 due to kasan check.
>> 
>> This should fix bug discussed in link:
>> [1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c at gmail.com/
>> 
>> Fixes: 421015713b30 ("ARM: 9017/2: Enable KASan for ARM")
>> Signed-off-by: Lexi Shao <shaolexi at huawei.com>
>> ---
>>  arch/arm/include/asm/uaccess.h | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
>> index a13d90206472..a6eb9af74870 100644
>> --- a/arch/arm/include/asm/uaccess.h
>> +++ b/arch/arm/include/asm/uaccess.h
>> @@ -200,6 +200,7 @@ extern int __get_user_64t_4(void *);
>>  		register unsigned long __l asm("r1") = __limit;		\
>>  		register int __e asm("r0");				\
>>  		unsigned int __ua_flags = uaccess_save_and_enable();	\
>> +		int __tmp_e;						\
>>  		switch (sizeof(*(__p))) {				\
>>  		case 1:							\
>>  			if (sizeof((x)) >= 8)				\
>> @@ -227,9 +228,10 @@ extern int __get_user_64t_4(void *);
>>  			break;						\
>>  		default: __e = __get_user_bad(); break;			\
>>  		}							\
>> +		__tmp_e = __e;						\
>>  		uaccess_restore(__ua_flags);				\
>>  		x = (typeof(*(p))) __r2;				\
>> -		__e;							\
>> +		__e = __tmp_e;						\
>
>There is no need to re-assign __tmp_e back to __e - you can just return
>__tmp_e here.

Yes you are right, will send the updated patch in the next email.

Lexi



From shaolexi at huawei.com  Fri Aug 27 19:25:52 2021
From: shaolexi at huawei.com (Lexi Shao)
Date: Sat, 28 Aug 2021 10:25:52 +0800
Subject: [PATCH v2] ARM: kasan: Fix __get_user_check failure with kasan
In-Reply-To: <20210827125601.GT22278@shell.armlinux.org.uk>
References: <20210827125601.GT22278@shell.armlinux.org.uk>
Message-ID: <20210828022552.45221-1-shaolexi@huawei.com>

In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
error code is store in register int __e(r0). When kasan is
enabled, assigning value to kernel address might trigger kasan check,
which unexpectedly overwrites r0 and causes undefined behavior on arm
kasan images.

One example is failure in do_futex and results in process soft lockup.
Log:
watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
Q:Reg:1151]
...
(__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
(futex_wait_setup) from (futex_wait+0x138/0x394)
(futex_wait) from (do_futex+0x164/0xe40)
(do_futex) from (sys_futex_time32+0x178/0x230)
(sys_futex_time32) from (ret_fast_syscall+0x0/0x50)

The soft lockup happens in function futex_wait_setup. The reason is
function get_futex_value_locked always return EINVAL, thus pc jump
back to retry label and causes looping.

This line in function get_futex_value_locked
	ret = __get_user(*dest, from);
is expanded to
	*dest = (typeof(*(p))) __r2; ,
in macro __get_user_check. Writing to pointer dest triggers kasan check
and overwrites the return value of __get_user_x function.
The assembly code of get_futex_value_locked in kernel/futex.c:
...
c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
// "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
c01f6dcc:       e1a00007        mov     r0, r7
c01f6dd0:       e1a05002        mov     r5, r2
c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
c01f6dd8:       e5875000        str     r5, [r7]
// save ret value of __get_user(*dest, from), which is dest address now
c01f6ddc:       e1a05000        mov     r5, r0
...
// checking return value of __get_user failed
c01f6e00:       e3550000        cmp     r5, #0
...
c01f6e0c:       01a00005        moveq   r0, r5
// assign return value to EINVAL
c01f6e10:       13e0000d        mvnne   r0, #13

Return value is the destination address of get_user thus certainly
non-zero, so get_futex_value_locked always return EINVAL.

Fix it by using a tmp vairable to store the error code before the
assignment. This fix has no effects to non-kasan images thanks to compiler
optimization. It only affects cases that overwrite r0 due to kasan check.

This should fix bug discussed in link:
[1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c at gmail.com/

Fixes: 421015713b30 ("ARM: 9017/2: Enable KASan for ARM")
Signed-off-by: Lexi Shao <shaolexi at huawei.com>
---
 arch/arm/include/asm/uaccess.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index a13d90206472..d9db752c51fe 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -200,6 +200,7 @@ extern int __get_user_64t_4(void *);
 		register unsigned long __l asm("r1") = __limit;		\
 		register int __e asm("r0");				\
 		unsigned int __ua_flags = uaccess_save_and_enable();	\
+		int __tmp_e;						\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
 			if (sizeof((x)) >= 8)				\
@@ -227,9 +228,10 @@ extern int __get_user_64t_4(void *);
 			break;						\
 		default: __e = __get_user_bad(); break;			\
 		}							\
+		__tmp_e = __e;						\
 		uaccess_restore(__ua_flags);				\
 		x = (typeof(*(p))) __r2;				\
-		__e;							\
+		__tmp_e;						\
 	})
 
 #define get_user(x, p)							\
-- 
2.12.3



From shaolexi at huawei.com  Fri Aug 27 20:26:24 2021
From: shaolexi at huawei.com (Lexi Shao)
Date: Sat, 28 Aug 2021 11:26:24 +0800
Subject: [PATCH] ARM: kasan: Fix __get_user_check failure with kasan
In-Reply-To: <4a80b83f-bc63-a141-c7c8-7e7d9545eb00@gmail.com>
References: <4a80b83f-bc63-a141-c7c8-7e7d9545eb00@gmail.com>
Message-ID: <20210828032624.46767-1-shaolexi@huawei.com>

>25.08.2021 09:46, Lexi Shao ?????:
>> In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
>> error code is store in register int __e(r0). When kasan is
>> enabled, assigning value to kernel address might trigger kasan check,
>> which unexpectedly overwrites r0 and causes undefined behavior on arm
>> kasan images.
>> 
>> One example is failure in do_futex and results in process soft lockup.
>> Log:
>> watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
>> Q:Reg:1151]
>> ...
>> (__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
>> (futex_wait_setup) from (futex_wait+0x138/0x394)
>> (futex_wait) from (do_futex+0x164/0xe40)
>> (do_futex) from (sys_futex_time32+0x178/0x230)
>> (sys_futex_time32) from (ret_fast_syscall+0x0/0x50)
>> 
>> The soft lockup happens in function futex_wait_setup. The reason is
>> function get_futex_value_locked always return EINVAL, thus pc jump
>> back to retry label and causes looping.
>> 
>> The assembly code of get_futex_value_locked in kernel/futex.c:
>> ...
>> c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
>> // "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
>> c01f6dcc:       e1a00007        mov     r0, r7
>> c01f6dd0:       e1a05002        mov     r5, r2
>> c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
>> c01f6dd8:       e5875000        str     r5, [r7]
>> // save ret value of __get_user(*dest, from), which is dest address now
>> c01f6ddc:       e1a05000        mov     r5, r0
>> ...
>> // checking return value of __get_user failed
>> c01f6e00:       e3550000        cmp     r5, #0
>> ...
>> c01f6e0c:       01a00005        moveq   r0, r5
>> // assign return value to EINVAL
>> c01f6e10:       13e0000d        mvnne   r0, #13
>> 
>> Return value is the destination address of get_user thus certainly
>> non-zero, so get_futex_value_locked always return EINVAL.
>> 
>> Fix it by using a tmp vairable to store the error code before the
>> assignment. This fix has no effects to non-kasan images thanks to compiler
>> optimization. It only affects cases that overwrite r0 due to kasan check.
>> 
>> This should fix bug discussed in link:
>> [1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c at gmail.com/
>> 
>> Fixes: 421015713b30 ("ARM: 9017/2: Enable KASan for ARM")
>> Signed-off-by: Lexi Shao <shaolexi at huawei.com>
>> ---
>>  arch/arm/include/asm/uaccess.h | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
>> index a13d90206472..a6eb9af74870 100644
>> --- a/arch/arm/include/asm/uaccess.h
>> +++ b/arch/arm/include/asm/uaccess.h
>> @@ -200,6 +200,7 @@ extern int __get_user_64t_4(void *);
>>  		register unsigned long __l asm("r1") = __limit;		\
>>  		register int __e asm("r0");				\
>>  		unsigned int __ua_flags = uaccess_save_and_enable();	\
>> +		int __tmp_e;						\
>>  		switch (sizeof(*(__p))) {				\
>>  		case 1:							\
>>  			if (sizeof((x)) >= 8)				\
>> @@ -227,9 +228,10 @@ extern int __get_user_64t_4(void *);
>>  			break;						\
>>  		default: __e = __get_user_bad(); break;			\
>>  		}							\
>> +		__tmp_e = __e;						\
>>  		uaccess_restore(__ua_flags);				\
>>  		x = (typeof(*(p))) __r2;				\
>> -		__e;							\
>> +		__e = __tmp_e;						\
>>  	})
>>  
>>  #define get_user(x, p)							\
>> 
>
>I successfully loaded KDE Plasma with this fix, which was impossible
>previously. Thank you!
>
>Is it guaranteed that r2 register won't be clobbered as well?

Value of r2 is saved before calling __asan_store4:

c01f6dbc:       e5951008        ldr     r1, [r5, #8]
c01f6dc0:       e1a00008        mov     r0, r8
c01f6dc4:       e2411001        sub     r1, r1, #1
c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
c01f6dcc:       e1a00007        mov     r0, r7
// move value of r2 to r5
c01f6dd0:       e1a05002        mov     r5, r2
c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
// the assignment, saving r5(orig r2) to dest
c01f6dd8:       e5875000        str     r5, [r7]
c01f6ddc:       e1a05000        mov     r5, r0

I can't explain it clearly why the compiler save r2 but not r0 though...



From kuba at kernel.org  Fri Aug 27 21:06:29 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 27 Aug 2021 21:06:29 -0700
Subject: [PATCH net-next v6] ipv6: add IFLA_INET6_RA_MTU to expose mtu
 value
In-Reply-To: <88523c38-f0b4-8a63-6ca6-68a3122bef79@gmail.com>
References: <20210827150412.9267-1-rocco.yue@mediatek.com>
 <88523c38-f0b4-8a63-6ca6-68a3122bef79@gmail.com>
Message-ID: <20210827210629.6858ceb9@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Fri, 27 Aug 2021 09:41:53 -0700 David Ahern wrote:
> On 8/27/21 8:04 AM, Rocco Yue wrote:
> > The kernel provides a "/proc/sys/net/ipv6/conf/<iface>/mtu"
> > file, which can temporarily record the mtu value of the last
> > received RA message when the RA mtu value is lower than the
> > interface mtu, but this proc has following limitations:
> > 
> > (1) when the interface mtu (/sys/class/net/<iface>/mtu) is
> > updeated, mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) will
> > be updated to the value of interface mtu;
> > (2) mtu6 (/proc/sys/net/ipv6/conf/<iface>/mtu) only affect
> > ipv6 connection, and not affect ipv4.
> > 
> > Therefore, when the mtu option is carried in the RA message,
> > there will be a problem that the user sometimes cannot obtain
> > RA mtu value correctly by reading mtu6.
> > 
> > After this patch set, if a RA message carries the mtu option,
> > you can send a netlink msg which nlmsg_type is RTM_GETLINK,
> > and then by parsing the attribute of IFLA_INET6_RA_MTU to
> > get the mtu value carried in the RA message received on the
> > inet6 device. In addition, you can also get a link notification
> > when ra_mtu is updated so it doesn't have to poll.
> > 
> > In this way, if the MTU values that the device receives from
> > the network in the PCO IPv4 and the RA IPv6 procedures are
> > different, the user can obtain the correct ipv6 ra_mtu value
> > and compare the value of ra_mtu and ipv4 mtu, then the device
> > can use the lower MTU value for both IPv4 and IPv6.
> > 
> > Signed-off-by: Rocco Yue <rocco.yue at mediatek.com>
>
> Reviewed-by: David Ahern <dsahern at kernel.org>

Applied, thank you!


From lkp at intel.com  Fri Aug 27 22:44:05 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 28 Aug 2021 13:44:05 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS 6c35ca06974105d929f25f487c6ae7a47fffa128
Message-ID: <6129cd25.aViis+idCSvnTBTN%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 6c35ca06974105d929f25f487c6ae7a47fffa128  Merge tag 'reset-fixes-for-v5.14' of git://git.pengutronix.de/pza/linux into arm/fixes

elapsed time: 2454m

configs tested: 94
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210827
arc                            hsdk_defconfig
arm                         lpc32xx_defconfig
sh                           sh2007_defconfig
powerpc                      bamboo_defconfig
powerpc                      ppc64e_defconfig
arm                  colibri_pxa270_defconfig
microblaze                          defconfig
powerpc                      makalu_defconfig
sh                          rsk7201_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a014-20210827
x86_64               randconfig-a015-20210827
x86_64               randconfig-a016-20210827
x86_64               randconfig-a013-20210827
x86_64               randconfig-a012-20210827
x86_64               randconfig-a011-20210827
i386                 randconfig-a011-20210827
i386                 randconfig-a016-20210827
i386                 randconfig-a012-20210827
i386                 randconfig-a014-20210827
i386                 randconfig-a013-20210827
i386                 randconfig-a015-20210827
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
arc                  randconfig-r043-20210826
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-a006-20210827
i386                 randconfig-a001-20210827
i386                 randconfig-a002-20210827
i386                 randconfig-a005-20210827
i386                 randconfig-a004-20210827
i386                 randconfig-a003-20210827
x86_64               randconfig-a005-20210827
x86_64               randconfig-a001-20210827
x86_64               randconfig-a006-20210827
x86_64               randconfig-a003-20210827
x86_64               randconfig-a004-20210827
x86_64               randconfig-a002-20210827
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From cuibixuan at huawei.com  Fri Aug 27 23:39:15 2021
From: cuibixuan at huawei.com (Bixuan Cui)
Date: Sat, 28 Aug 2021 14:39:15 +0800
Subject: [PATCH -next v3 2/2] iommu/arm-smmu-v3: Add suspend and resume support
In-Reply-To: <20210828063916.39633-1-cuibixuan@huawei.com>
References: <20210828063916.39633-1-cuibixuan@huawei.com>
Message-ID: <20210828063916.39633-2-cuibixuan@huawei.com>

Add suspend and resume support for arm-smmu-v3 by low-power mode.

When the smmu is suspended, it is powered off and the registers are
cleared. So saves the msi_msg context during msi interrupt initialization
of smmu. When resume happens it calls arm_smmu_device_reset() to restore
the registers.

Signed-off-by: Bixuan Cui <cuibixuan at huawei.com>
---
Changes in v3:
* Move the code of save msg context into msi platform (A new patch: "platform-msi: Save the msg context to desc in platform_msi_write_msg()").

* Add bypass member to the struct arm_smmu_device for per-SMMU bypass control(used by resume mode).

* Separate interrupt requests and register operations in arm_smmu_device_reset(). The arm_smmu_setup_irqs() is added to request interrupts and is called before arm_smmu_device_reset(). The arm_smmu_device_reset() resets irq registers (can also be called in resume mode).

Changes in v2:
* Using get_cached_msi_msg() instead of the descriptor to resume msi_msg
  in arm_smmu_resume_msis();

* Move arm_smmu_resume_msis() from arm_smmu_setup_unique_irqs() into
  arm_smmu_setup_irqs() and rename it to arm_smmu_resume_unique_irqs();

  Call arm_smmu_setup_unique_irqs() to configure the IRQ during probe and
  call arm_smmu_resume_unique_irqs() in resume mode to restore the IRQ
  registers to make the code more reasonable.

* Call arm_smmu_device_disable() to disable smmu and clear CR0_SMMUEN on
  suspend. Then the warning about CR0_SMMUEN being enabled can be cleared
  on resume.

* Using SET_SYSTEM_SLEEP_PM_OPS();

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 99 +++++++++++++++++++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 +
 2 files changed, 93 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index a388e318f86e..95a1c2689685 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3282,6 +3282,61 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 	return 0;
 }
 
+static void arm_smmu_reset_unique_irqs(struct arm_smmu_device *smmu)
+{
+	struct msi_desc *desc;
+	struct msi_msg msg;
+
+	desc = irq_get_msi_desc(smmu->evtq.q.irq);
+	if (desc) {
+		get_cached_msi_msg(smmu->evtq.q.irq, &msg);
+		arm_smmu_write_msi_msg(desc, &msg);
+	}
+
+	desc = irq_get_msi_desc(smmu->gerr_irq);
+	if (desc) {
+		get_cached_msi_msg(smmu->gerr_irq, &msg);
+		arm_smmu_write_msi_msg(desc, &msg);
+	}
+
+	if (smmu->features & ARM_SMMU_FEAT_PRI) {
+		desc = irq_get_msi_desc(smmu->priq.q.irq);
+		if (desc) {
+			get_cached_msi_msg(smmu->priq.q.irq, &msg);
+			arm_smmu_write_msi_msg(desc, &msg);
+		}
+	}
+}
+
+static int arm_smmu_reset_irqs(struct arm_smmu_device *smmu)
+{
+	int ret, irq;
+	u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN;
+
+	/* Disable IRQs first */
+	ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL,
+				      ARM_SMMU_IRQ_CTRLACK);
+	if (ret) {
+		dev_err(smmu->dev, "failed to disable irqs\n");
+		return ret;
+	}
+
+	irq = smmu->combined_irq;
+	if (!irq)
+		arm_smmu_reset_unique_irqs(smmu);
+
+	if (smmu->features & ARM_SMMU_FEAT_PRI)
+		irqen_flags |= IRQ_CTRL_PRIQ_IRQEN;
+
+	/* Enable interrupt generation on the SMMU */
+	ret = arm_smmu_write_reg_sync(smmu, irqen_flags,
+				      ARM_SMMU_IRQ_CTRL, ARM_SMMU_IRQ_CTRLACK);
+	if (ret)
+		dev_warn(smmu->dev, "failed to reset irqs\n");
+
+	return 0;
+}
+
 static int arm_smmu_device_disable(struct arm_smmu_device *smmu)
 {
 	int ret;
@@ -3293,7 +3348,7 @@ static int arm_smmu_device_disable(struct arm_smmu_device *smmu)
 	return ret;
 }
 
-static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
+static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
 {
 	int ret;
 	u32 reg, enables;
@@ -3401,9 +3456,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 		}
 	}
 
-	ret = arm_smmu_setup_irqs(smmu);
+	ret = arm_smmu_reset_irqs(smmu);
 	if (ret) {
-		dev_err(smmu->dev, "failed to setup irqs\n");
+		dev_err(smmu->dev, "failed to reset irqs\n");
 		return ret;
 	}
 
@@ -3411,7 +3466,7 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 		enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
 
 	/* Enable the SMMU interface, or ensure bypass */
-	if (!bypass || disable_bypass) {
+	if (!smmu->bypass || disable_bypass) {
 		enables |= CR0_SMMUEN;
 	} else {
 		ret = arm_smmu_update_gbpa(smmu, 0, GBPA_ABORT);
@@ -3758,6 +3813,25 @@ static void __iomem *arm_smmu_ioremap(struct device *dev, resource_size_t start,
 	return devm_ioremap_resource(dev, &res);
 }
 
+static int __maybe_unused arm_smmu_suspend(struct device *dev)
+{
+	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+	/* disable smmu to clear CR0 */
+	arm_smmu_device_disable(smmu);
+
+	return 0;
+}
+
+static int __maybe_unused arm_smmu_resume(struct device *dev)
+{
+	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+	arm_smmu_device_reset(smmu);
+
+	return 0;
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	int irq, ret;
@@ -3765,7 +3839,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	resource_size_t ioaddr;
 	struct arm_smmu_device *smmu;
 	struct device *dev = &pdev->dev;
-	bool bypass;
 
 	smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
 	if (!smmu)
@@ -3781,7 +3854,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	}
 
 	/* Set bypass mode according to firmware probing result */
-	bypass = !!ret;
+	smmu->bypass = !!ret;
 
 	/* Base address */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -3839,8 +3912,15 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Record our private device structure */
 	platform_set_drvdata(pdev, smmu);
 
+	/* Setup irqs */
+	ret = arm_smmu_setup_irqs(smmu);
+	if (ret) {
+		dev_err(smmu->dev, "failed to setup irqs\n");
+		return ret;
+	}
+
 	/* Reset the device */
-	ret = arm_smmu_device_reset(smmu, bypass);
+	ret = arm_smmu_device_reset(smmu);
 	if (ret)
 		return ret;
 
@@ -3893,6 +3973,10 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static const struct dev_pm_ops arm_smmu_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(arm_smmu_suspend, arm_smmu_resume)
+};
+
 static void arm_smmu_driver_unregister(struct platform_driver *drv)
 {
 	arm_smmu_sva_notifier_synchronize();
@@ -3904,6 +3988,7 @@ static struct platform_driver arm_smmu_driver = {
 		.name			= "arm-smmu-v3",
 		.of_match_table		= arm_smmu_of_match,
 		.suppress_bind_attrs	= true,
+		.pm			= &arm_smmu_pm_ops,
 	},
 	.probe	= arm_smmu_device_probe,
 	.remove	= arm_smmu_device_remove,
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 4cb136f07914..7777a7445bc2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -675,6 +675,7 @@ struct arm_smmu_device {
 
 	struct rb_root			streams;
 	struct mutex			streams_mutex;
+	bool				bypass;
 };
 
 struct arm_smmu_stream {
-- 
2.17.1



From cuibixuan at huawei.com  Fri Aug 27 23:39:14 2021
From: cuibixuan at huawei.com (Bixuan Cui)
Date: Sat, 28 Aug 2021 14:39:14 +0800
Subject: [PATCH -next v3 1/2] platform-msi: Save the msg context to desc in
 platform_msi_write_msg()
Message-ID: <20210828063916.39633-1-cuibixuan@huawei.com>

Save the msg context to desc when the msi interrupt is requested.
The drivers can use it in special scenarios(such as resume).

Signed-off-by: Bixuan Cui <cuibixuan at huawei.com>
---
 drivers/base/platform-msi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index 3d6c8f9caf43..60962a224fcc 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -90,6 +90,9 @@ static void platform_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
 
 	priv_data = desc->platform.msi_priv_data;
 
+	desc->msg.address_lo = msg->address_lo;
+	desc->msg.address_hi = msg->address_hi;
+	desc->msg.data = msg->data;
 	priv_data->write_msg(desc, msg);
 }
 
-- 
2.17.1



From jbx6244 at gmail.com  Sat Aug 28 02:12:33 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 11:12:33 +0200
Subject: [PATCH] ARM: dts: rockchip: rk3066a: add more angle brackets to
 operating-points property
Message-ID: <20210828091233.19992-1-jbx6244@gmail.com>

After the conversion to YAML of the Operating Performance Points(OPP)
binding the operating-points property expects values in
a uint32-matrix with 2 items, so fix the notifications by adding
angle brackets.

make ARCH=arm dtbs_check
DT_SCHEMA_FILES=Documentation/devicetree/bindings/opp/opp-v1.yaml

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm/boot/dts/rk3066a.dtsi | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
index ae4055428..cc701a4e0 100644
--- a/arch/arm/boot/dts/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -23,16 +23,15 @@
 			compatible = "arm,cortex-a9";
 			next-level-cache = <&L2>;
 			reg = <0x0>;
-			operating-points = <
+			operating-points =
 				/* kHz    uV */
-				1416000 1300000
-				1200000 1175000
-				1008000 1125000
-				816000  1125000
-				600000  1100000
-				504000  1100000
-				312000  1075000
-			>;
+				<1416000 1300000>,
+				<1200000 1175000>,
+				<1008000 1125000>,
+				<816000  1125000>,
+				<600000  1100000>,
+				<504000  1100000>,
+				<312000  1075000>;
 			clock-latency = <40000>;
 			clocks = <&cru ARMCLK>;
 		};
-- 
2.20.1



From jbx6244 at gmail.com  Sat Aug 28 02:27:55 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 11:27:55 +0200
Subject: [PATCH] ARM: dts: rockchip: add adc-keys node to rk3066a-mk808.dts
Message-ID: <20210828092755.24560-1-jbx6244@gmail.com>

The MK808 has a button inside the cover for the boot loader to do
some action. Add the adc-keys node to the rk3066a-mk808.dts file.
The rk3066 has a higher maximum DC supply voltage for the analog part of
SAR-ADC VDDA_SARADC of 2.75V then other Rockchip SoCs.
For the "rockchip,saradc" node is a vref-supply property required,
so add a regulator for it as well.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm/boot/dts/rk3066a-mk808.dts | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts
index 9790bc63b..667d57a4f 100644
--- a/arch/arm/boot/dts/rk3066a-mk808.dts
+++ b/arch/arm/boot/dts/rk3066a-mk808.dts
@@ -4,6 +4,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/input/input.h>
 #include "rk3066a.dtsi"
 
 / {
@@ -24,6 +25,20 @@
 		device_type = "memory";
 	};
 
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <2500000>;
+		poll-interval = <100>;
+
+		recovery {
+			label = "recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
 	gpio-leds {
 		compatible = "gpio-leds";
 
@@ -46,6 +61,13 @@
 		};
 	};
 
+	vcc_2v5: vcc-2v5 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_2v5";
+		regulator-min-microvolt = <2500000>;
+		regulator-max-microvolt = <2500000>;
+	};
+
 	vcc_io: vcc-io {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_io";
@@ -164,6 +186,11 @@
 	};
 };
 
+&saradc {
+	vref-supply = <&vcc_2v5>;
+	status = "okay";
+};
+
 &uart2 {
 	status = "okay";
 };
-- 
2.20.1



From jbx6244 at gmail.com  Sat Aug 28 02:45:12 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 11:45:12 +0200
Subject: [PATCH] ARM: dts: rockchip: rename opp-table node names
Message-ID: <20210828094512.26862-1-jbx6244@gmail.com>

After the conversion to YAML of the Operating Performance Points(OPP)
binding the operating-points-v2 property expects the nodename to have
the '^opp-table(-[a-z0-9]+)?$' format, so rename all Rockchip ARM dts
opp-table node names.

make ARCH=arm dtbs_check
DT_SCHEMA_FILES=Documentation/devicetree/bindings/opp/opp-v2.yaml

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm/boot/dts/rk3188.dtsi | 2 +-
 arch/arm/boot/dts/rk3229.dtsi | 2 +-
 arch/arm/boot/dts/rk322x.dtsi | 2 +-
 arch/arm/boot/dts/rk3288.dtsi | 4 ++--
 arch/arm/boot/dts/rv1108.dtsi | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 2c606494b..d6a946a2a 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -54,7 +54,7 @@
 		};
 	};
 
-	cpu0_opp_table: opp_table0 {
+	cpu0_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
diff --git a/arch/arm/boot/dts/rk3229.dtsi b/arch/arm/boot/dts/rk3229.dtsi
index cb7d3fad8..c340fb30e 100644
--- a/arch/arm/boot/dts/rk3229.dtsi
+++ b/arch/arm/boot/dts/rk3229.dtsi
@@ -10,7 +10,7 @@
 
 	/delete-node/ opp-table0;
 
-	cpu0_opp_table: opp_table0 {
+	cpu0_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 75af99c76..4021e92e0 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -68,7 +68,7 @@
 		};
 	};
 
-	cpu0_opp_table: opp_table0 {
+	cpu0_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 4dcdcf17c..1ded2aabe 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -100,7 +100,7 @@
 		};
 	};
 
-	cpu_opp_table: cpu-opp-table {
+	cpu_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 		opp-shared;
 
@@ -1278,7 +1278,7 @@
 		status = "disabled";
 	};
 
-	gpu_opp_table: gpu-opp-table {
+	gpu_opp_table: opp-table-1 {
 		compatible = "operating-points-v2";
 
 		opp-100000000 {
diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi
index 24d56849a..7d96a0d02 100644
--- a/arch/arm/boot/dts/rv1108.dtsi
+++ b/arch/arm/boot/dts/rv1108.dtsi
@@ -40,7 +40,7 @@
 		};
 	};
 
-	cpu_opp_table: opp_table {
+	cpu_opp_table: opp-table-0 {
 		compatible = "operating-points-v2";
 
 		opp-408000000 {
-- 
2.20.1



From jbx6244 at gmail.com  Sat Aug 28 03:26:59 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 12:26:59 +0200
Subject: [PATCH] ARM: dts: rockchip: swap timer clock-names
Message-ID: <20210828102659.7348-1-jbx6244@gmail.com>

With the conversion of rockchip,rk-timer.yaml the clock-names order
was set to "pclk", "timer", but nothing was fixed in the ARM dts section
of the mainline kernel, so the swap timer clock-names that don't fit.

make ARCH=arm dtbs_check
DT_SCHEMA_FILES=Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm/boot/dts/rk3036.dtsi | 4 ++--
 arch/arm/boot/dts/rk322x.dtsi | 4 ++--
 arch/arm/boot/dts/rv1108.dtsi | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi
index ffa9bc7ed..6864b8668 100644
--- a/arch/arm/boot/dts/rk3036.dtsi
+++ b/arch/arm/boot/dts/rk3036.dtsi
@@ -416,8 +416,8 @@
 		compatible = "rockchip,rk3036-timer", "rockchip,rk3288-timer";
 		reg = <0x20044000 0x20>;
 		interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&xin24m>, <&cru PCLK_TIMER>;
-		clock-names = "timer", "pclk";
+		clocks = <&cru PCLK_TIMER>, <&xin24m>;
+		clock-names = "pclk", "timer";
 	};
 
 	pwm0: pwm at 20050000 {
diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 4021e92e0..dea025a64 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -477,8 +477,8 @@
 		compatible = "rockchip,rk3228-timer", "rockchip,rk3288-timer";
 		reg = <0x110c0000 0x20>;
 		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&xin24m>, <&cru PCLK_TIMER>;
-		clock-names = "timer", "pclk";
+		clocks = <&cru PCLK_TIMER>, <&xin24m>;
+		clock-names = "pclk", "timer";
 	};
 
 	cru: clock-controller at 110e0000 {
diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi
index 7d96a0d02..140434384 100644
--- a/arch/arm/boot/dts/rv1108.dtsi
+++ b/arch/arm/boot/dts/rv1108.dtsi
@@ -300,8 +300,8 @@
 		compatible = "rockchip,rv1108-timer", "rockchip,rk3288-timer";
 		reg = <0x10350000 0x20>;
 		interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&xin24m>, <&cru PCLK_TIMER>;
-		clock-names = "timer", "pclk";
+		clocks = <&cru PCLK_TIMER>, <&xin24m>;
+		clock-names = "pclk", "timer";
 	};
 
 	watchdog: watchdog at 10360000 {
-- 
2.20.1



From kewei.xu at mediatek.com  Sat Aug 28 03:50:52 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 28 Aug 2021 18:50:52 +0800
Subject: [PATCH v6 0/7] Introducing an attribute to select the time setting
Message-ID: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>

v6:
Add the judgment condition, clear the handshake signal between dma and
i2c when multiple msgs are transmitted.

v5:
1. Replace the previous variable name "default_timing_adjust" with "use-default-timing"
2. Added waiting for dma reset mechanism
3. Remove received patch(dt-bindings: i2c: update bindings for MT8195 SOC)

v4:
1. Remove the repeated assignment of the inter_clk_div parameter
2. Modify the wrong assignment of OFFSET_MULTI_DMA
3. Unify the log print format of the i2c_dump_register() and drop the extra outer parentheses
4. Place the fixes at the very least
5. Add fixed tags 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183")
6. Add "i2c: mediatek: modify bus speed calculation formula"
7. Fix single line characters exceeding 80 characters
8. Combine two different series of patches.

v3:
1. Fix code errors caused by v2 modification

v2:
1. Add "dt-bindings: i2c: add attribute default-timing-adjust"
2. Split the fix into sepatate patch.

Kewei Xu (7):
  i2c: mediatek: fixing the incorrect register offset
  i2c: mediatek: Reset the handshake signal between i2c and dma
  i2c: mediatek: Dump i2c/dma register when a timeout occurs
  dt-bindings: i2c: add attribute use-default-timing
  i2c: mediatek: Add OFFSET_EXT_CONF setting back
  i2c: mediatek: Isolate speed setting via dts for special devices
  i2c: mediatek: modify bus speed calculation formula

 .../devicetree/bindings/i2c/i2c-mt65xx.txt    |   2 +
 drivers/i2c/busses/i2c-mt65xx.c               | 207 ++++++++++++++++--
 2 files changed, 192 insertions(+), 17 deletions(-)

-- 
2.18.0

From kewei.xu at mediatek.com  Sat Aug 28 03:50:56 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 28 Aug 2021 18:50:56 +0800
Subject: [PATCH v6 4/7] dt-bindings: i2c: add attribute use-default-timing
In-Reply-To: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
References: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1630147859-17031-5-git-send-email-kewei.xu@mediatek.com>

Add attribute use-default-timing for DT-binding document.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
index 5ea216a..4dbb697 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
@@ -34,6 +34,8 @@ Optional properties:
     Only mt6589 and mt8135 support this feature.
   - mediatek,use-push-pull: IO config use push-pull mode.
   - vbus-supply: phandle to the regulator that provides power to SCL/SDA.
+  - mediatek,use-default-timing: use default timing calculation, no timing
+    adjustment.
 
 Example:
 
-- 
1.9.1

From kewei.xu at mediatek.com  Sat Aug 28 03:50:53 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 28 Aug 2021 18:50:53 +0800
Subject: [PATCH v6 1/7] i2c: mediatek: fixing the incorrect register offset
In-Reply-To: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
References: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1630147859-17031-2-git-send-email-kewei.xu@mediatek.com>

The reason for the modification here is that the previous
offset information is incorrect, OFFSET_DEBUGSTAT = 0xE4 is
the correct value.

Fixes: 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/i2c/busses/i2c-mt65xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 4ca716e..2661ed0 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -193,7 +193,7 @@ enum I2C_REGS_OFFSET {
 	[OFFSET_CLOCK_DIV] = 0x48,
 	[OFFSET_SOFTRESET] = 0x50,
 	[OFFSET_SCL_MIS_COMP_POINT] = 0x90,
-	[OFFSET_DEBUGSTAT] = 0xe0,
+	[OFFSET_DEBUGSTAT] = 0xe4,
 	[OFFSET_DEBUGCTRL] = 0xe8,
 	[OFFSET_FIFO_STAT] = 0xf4,
 	[OFFSET_FIFO_THRESH] = 0xf8,
-- 
1.9.1

From kewei.xu at mediatek.com  Sat Aug 28 03:50:57 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 28 Aug 2021 18:50:57 +0800
Subject: [PATCH v6 5/7] i2c: mediatek: Add OFFSET_EXT_CONF setting back
In-Reply-To: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
References: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1630147859-17031-6-git-send-email-kewei.xu@mediatek.com>

In the commit be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust
support"), we miss setting OFFSET_EXT_CONF register if
i2c->dev_comp->timing_adjust is false, now add it back.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 1aa0ba3..6ded82e 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -42,6 +42,8 @@
 #define I2C_HANDSHAKE_RST		0x0020
 #define I2C_FIFO_ADDR_CLR		0x0001
 #define I2C_DELAY_LEN			0x0002
+#define I2C_ST_START_CON		0x8001
+#define I2C_FS_START_CON		0x1800
 #define I2C_TIME_CLR_VALUE		0x0000
 #define I2C_TIME_DEFAULT_VALUE		0x0003
 #define I2C_WRRD_TRANAC_VALUE		0x0002
@@ -486,6 +488,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 {
 	u16 control_reg;
 	u16 intr_stat_reg;
+	u16 ext_conf_val;
 
 	mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_START);
 	intr_stat_reg = mtk_i2c_readw(i2c, OFFSET_INTR_STAT);
@@ -524,8 +527,13 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 	if (i2c->dev_comp->ltiming_adjust)
 		mtk_i2c_writew(i2c, i2c->ltiming_reg, OFFSET_LTIMING);
 
+	if (i2c->speed_hz <= I2C_MAX_STANDARD_MODE_FREQ)
+		ext_conf_val = I2C_ST_START_CON;
+	else
+		ext_conf_val = I2C_FS_START_CON;
+
 	if (i2c->dev_comp->timing_adjust) {
-		mtk_i2c_writew(i2c, i2c->ac_timing.ext, OFFSET_EXT_CONF);
+		ext_conf_val = i2c->ac_timing.ext;
 		mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
 			       OFFSET_CLOCK_DIV);
 		mtk_i2c_writew(i2c, I2C_SCL_MIS_COMP_VALUE,
@@ -550,6 +558,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 				       OFFSET_HS_STA_STO_AC_TIMING);
 		}
 	}
+	mtk_i2c_writew(i2c, ext_conf_val, OFFSET_EXT_CONF);
 
 	/* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */
 	if (i2c->have_pmic)
-- 
1.9.1

From kewei.xu at mediatek.com  Sat Aug 28 03:50:54 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 28 Aug 2021 18:50:54 +0800
Subject: [PATCH v6 2/7] i2c: mediatek: Reset the handshake signal between i2c
 and dma
In-Reply-To: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
References: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1630147859-17031-3-git-send-email-kewei.xu@mediatek.com>

Due to changes in the hardware design of the handshaking signal
between i2c and dma, it is necessary to reset the handshaking
signal before each transfer to ensure that the multi-msgs can
be transferred correctly.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 2661ed0..7a1c538 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/module.h>
@@ -47,6 +48,9 @@
 #define I2C_RD_TRANAC_VALUE		0x0001
 #define I2C_SCL_MIS_COMP_VALUE		0x0000
 #define I2C_CHN_CLR_FLAG		0x0000
+#define I2C_CLR_DEBUGCTR		0x0000
+#define I2C_RELIABILITY			0x0010
+#define I2C_DMAACK_ENABLE		0x0008
 
 #define I2C_DMA_CON_TX			0x0000
 #define I2C_DMA_CON_RX			0x0001
@@ -842,6 +846,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 	u16 restart_flag = 0;
 	u16 dma_sync = 0;
 	u32 reg_4g_mode;
+	u32 reg_dma_reset;
 	u8 *dma_rd_buf = NULL;
 	u8 *dma_wr_buf = NULL;
 	dma_addr_t rpaddr = 0;
@@ -855,6 +860,27 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 
 	reinit_completion(&i2c->msg_complete);
 
+	if (i2c->dev_comp->apdma_sync && i2c->op != I2C_MASTER_WRRD && num > 1) {
+		mtk_i2c_writew(i2c, I2C_CLR_DEBUGCTR, OFFSET_DEBUGCTRL);
+		writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_WARM_RST,
+		       i2c->pdmabase + OFFSET_RST);
+
+		ret = readw_poll_timeout(i2c->pdmabase + OFFSET_RST,
+					 reg_dma_reset,
+					 !(reg_dma_reset & I2C_DMA_WARM_RST),
+					 0, 100);
+		if (ret) {
+			dev_err(i2c->dev, "DMA warm reset timeout\n");
+			return -ETIMEDOUT;
+		}
+
+		writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
+		mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST, OFFSET_SOFTRESET);
+		mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET);
+		mtk_i2c_writew(i2c, I2C_RELIABILITY | I2C_DMAACK_ENABLE,
+			       OFFSET_DEBUGCTRL);
+	}
+
 	control_reg = mtk_i2c_readw(i2c, OFFSET_CONTROL) &
 			~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
 	if ((i2c->speed_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) || (left_num >= 1))
-- 
1.9.1

From kewei.xu at mediatek.com  Sat Aug 28 03:50:55 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 28 Aug 2021 18:50:55 +0800
Subject: [PATCH v6 3/7] i2c: mediatek: Dump i2c/dma register when a timeout
 occurs
In-Reply-To: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
References: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1630147859-17031-4-git-send-email-kewei.xu@mediatek.com>

When a timeout error occurs in i2c transter, it is usually related
to the i2c/dma IP hardware configuration. Therefore, the purpose of
this patch is to dump the key register values of i2c/dma when a
timeout occurs in i2c for debugging.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 56 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 7a1c538..1aa0ba3 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -129,6 +129,7 @@ enum I2C_REGS_OFFSET {
 	OFFSET_HS,
 	OFFSET_SOFTRESET,
 	OFFSET_DCM_EN,
+	OFFSET_MULTI_DMA,
 	OFFSET_PATH_DIR,
 	OFFSET_DEBUGSTAT,
 	OFFSET_DEBUGCTRL,
@@ -196,6 +197,7 @@ enum I2C_REGS_OFFSET {
 	[OFFSET_TRANSFER_LEN_AUX] = 0x44,
 	[OFFSET_CLOCK_DIV] = 0x48,
 	[OFFSET_SOFTRESET] = 0x50,
+	[OFFSET_MULTI_DMA] = 0x8c,
 	[OFFSET_SCL_MIS_COMP_POINT] = 0x90,
 	[OFFSET_DEBUGSTAT] = 0xe4,
 	[OFFSET_DEBUGCTRL] = 0xe8,
@@ -837,6 +839,57 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
 	return 0;
 }
 
+static void i2c_dump_register(struct mtk_i2c *i2c)
+{
+	dev_err(i2c->dev, "SLAVE_ADDR: 0x%x, INTR_MASK: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_SLAVE_ADDR),
+		mtk_i2c_readw(i2c, OFFSET_INTR_MASK));
+	dev_err(i2c->dev, "INTR_STAT: 0x%x, CONTROL: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_INTR_STAT),
+		mtk_i2c_readw(i2c, OFFSET_CONTROL));
+	dev_err(i2c->dev, "TRANSFER_LEN: 0x%x, TRANSAC_LEN: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN),
+		mtk_i2c_readw(i2c, OFFSET_TRANSAC_LEN));
+	dev_err(i2c->dev, "DELAY_LEN: 0x%x, HTIMING: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DELAY_LEN),
+		mtk_i2c_readw(i2c, OFFSET_TIMING));
+	dev_err(i2c->dev, "START: 0x%x, EXT_CONF: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_START),
+		mtk_i2c_readw(i2c, OFFSET_EXT_CONF));
+	dev_err(i2c->dev, "HS: 0x%x, IO_CONFIG: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_HS),
+		mtk_i2c_readw(i2c, OFFSET_IO_CONFIG));
+	dev_err(i2c->dev, "DCM_EN: 0x%x, TRANSFER_LEN_AUX: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DCM_EN),
+		mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN_AUX));
+	dev_err(i2c->dev, "CLOCK_DIV: 0x%x, FIFO_STAT: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_CLOCK_DIV),
+		mtk_i2c_readw(i2c, OFFSET_FIFO_STAT));
+	dev_err(i2c->dev, "DEBUGCTRL : 0x%x, DEBUGSTAT: 0x%x\n",
+		mtk_i2c_readw(i2c, OFFSET_DEBUGCTRL),
+		mtk_i2c_readw(i2c, OFFSET_DEBUGSTAT));
+	if (i2c->dev_comp->regs == mt_i2c_regs_v2) {
+		dev_err(i2c->dev, "LTIMING: 0x%x, MULTI_DMA: 0x%x\n",
+			mtk_i2c_readw(i2c, OFFSET_LTIMING),
+			mtk_i2c_readw(i2c, OFFSET_MULTI_DMA));
+	}
+	dev_err(i2c->dev, "\nDMA_INT_FLAG: 0x%x, DMA_INT_EN: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_INT_FLAG),
+		readl(i2c->pdmabase + OFFSET_INT_EN));
+	dev_err(i2c->dev, "DMA_EN: 0x%x, DMA_CON: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_EN),
+		readl(i2c->pdmabase + OFFSET_CON));
+	dev_err(i2c->dev, "DMA_TX_MEM_ADDR: 0x%x, DMA_RX_MEM_ADDR: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_TX_MEM_ADDR),
+		readl(i2c->pdmabase + OFFSET_RX_MEM_ADDR));
+	dev_err(i2c->dev, "DMA_TX_LEN: 0x%x, DMA_RX_LEN: 0x%x\n",
+		readl(i2c->pdmabase + OFFSET_TX_LEN),
+		readl(i2c->pdmabase + OFFSET_RX_LEN));
+	dev_err(i2c->dev, "DMA_TX_4G_MODE: 0x%x, DMA_RX_4G_MODE: 0x%x",
+		readl(i2c->pdmabase + OFFSET_TX_4G_MODE),
+		readl(i2c->pdmabase + OFFSET_RX_4G_MODE));
+}
+
 static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 			       int num, int left_num)
 {
@@ -1065,7 +1118,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
 	}
 
 	if (ret == 0) {
-		dev_dbg(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
+		dev_err(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
+		i2c_dump_register(i2c);
 		mtk_i2c_init_hw(i2c);
 		return -ETIMEDOUT;
 	}
-- 
1.9.1

From kewei.xu at mediatek.com  Sat Aug 28 03:50:58 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 28 Aug 2021 18:50:58 +0800
Subject: [PATCH v6 6/7] i2c: mediatek: Isolate speed setting via dts for
 special devices
In-Reply-To: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
References: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1630147859-17031-7-git-send-email-kewei.xu@mediatek.com>

In the commit be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust
support"), the I2C timing calculation has been revised to support
ac-timing adjustment, however that will break on some I2C components.
As a result we want to introduce a new setting "default-adjust-timing"
so those components can choose to use the old (default) timing algorithm.

Fixes: be5ce0e97cc7 ("i2c: mediatek: Add i2c ac-timing adjust support")
Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 77 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 6ded82e..0cf130b 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -66,6 +66,7 @@
 #define I2C_DMA_HARD_RST		0x0002
 #define I2C_DMA_HANDSHAKE_RST		0x0004
 
+#define I2C_DEFAULT_CLK_DIV		5
 #define MAX_SAMPLE_CNT_DIV		8
 #define MAX_STEP_CNT_DIV		64
 #define MAX_CLOCK_DIV			256
@@ -250,6 +251,7 @@ struct mtk_i2c {
 	struct clk *clk_arb;		/* Arbitrator clock for i2c */
 	bool have_pmic;			/* can use i2c pins from PMIC */
 	bool use_push_pull;		/* IO config push-pull mode */
+	bool use_default_timing;	/* no timing adjust mode */
 
 	u16 irq_stat;			/* interrupt status */
 	unsigned int clk_src_div;
@@ -532,7 +534,11 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 	else
 		ext_conf_val = I2C_FS_START_CON;
 
-	if (i2c->dev_comp->timing_adjust) {
+	if (i2c->use_default_timing) {
+		if (i2c->dev_comp->timing_adjust)
+			mtk_i2c_writew(i2c, I2C_DEFAULT_CLK_DIV - 1,
+				       OFFSET_CLOCK_DIV);
+	} else if (i2c->dev_comp->timing_adjust) {
 		ext_conf_val = i2c->ac_timing.ext;
 		mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
 			       OFFSET_CLOCK_DIV);
@@ -615,7 +621,7 @@ static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c,
 	unsigned int sample_ns = div_u64(1000000000ULL * (sample_cnt + 1),
 					 clk_src);
 
-	if (!i2c->dev_comp->timing_adjust)
+	if (i2c->use_default_timing || !i2c->dev_comp->timing_adjust)
 		return 0;
 
 	if (i2c->dev_comp->ltiming_adjust)
@@ -775,7 +781,65 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	return 0;
 }
 
-static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
+static int mtk_i2c_set_speed_default_timing(struct mtk_i2c *i2c,
+					    unsigned int parent_clk)
+{
+	unsigned int clk_src;
+	unsigned int step_cnt;
+	unsigned int sample_cnt;
+	unsigned int l_step_cnt;
+	unsigned int l_sample_cnt;
+	unsigned int target_speed;
+	int ret;
+
+	if (i2c->dev_comp->timing_adjust)
+		i2c->clk_src_div *= I2C_DEFAULT_CLK_DIV;
+
+	clk_src = parent_clk / i2c->clk_src_div;
+	target_speed = i2c->speed_hz;
+
+	if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) {
+		/* Set master code speed register */
+		ret = mtk_i2c_calculate_speed(i2c, clk_src,
+					      I2C_MAX_FAST_MODE_FREQ,
+					      &l_step_cnt, &l_sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->timing_reg = (l_sample_cnt << 8) | l_step_cnt;
+
+		/* Set the high speed mode register */
+		ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->high_speed_reg = I2C_TIME_DEFAULT_VALUE |
+			(sample_cnt << 12) | (step_cnt << 8);
+
+		if (i2c->dev_comp->ltiming_adjust)
+			i2c->ltiming_reg = (l_sample_cnt << 6) | l_step_cnt |
+					   (sample_cnt << 12) | (step_cnt << 9);
+	} else {
+		ret = mtk_i2c_calculate_speed(i2c, clk_src, target_speed,
+					      &step_cnt, &sample_cnt);
+		if (ret < 0)
+			return ret;
+
+		i2c->timing_reg = (sample_cnt << 8) | step_cnt;
+
+		/* Disable the high speed transaction */
+		i2c->high_speed_reg = I2C_TIME_CLR_VALUE;
+
+		if (i2c->dev_comp->ltiming_adjust)
+			i2c->ltiming_reg = (sample_cnt << 6) | step_cnt;
+	}
+
+	return 0;
+}
+
+static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
+					   unsigned int parent_clk)
 {
 	unsigned int clk_src;
 	unsigned int step_cnt;
@@ -1271,6 +1335,8 @@ static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c)
 	i2c->have_pmic = of_property_read_bool(np, "mediatek,have-pmic");
 	i2c->use_push_pull =
 		of_property_read_bool(np, "mediatek,use-push-pull");
+	i2c->use_default_timing =
+		of_property_read_bool(np, "mediatek,use-default-timing");
 
 	i2c_parse_fw_timings(i2c->dev, &i2c->timing_info, true);
 
@@ -1357,7 +1423,10 @@ static int mtk_i2c_probe(struct platform_device *pdev)
 
 	strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
 
-	ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk));
+	if (i2c->use_default_timing)
+		ret = mtk_i2c_set_speed_default_timing(i2c, clk_get_rate(clk));
+	else
+		ret = mtk_i2c_set_speed_adjust_timing(i2c, clk_get_rate(clk));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to set the speed.\n");
 		return -EINVAL;
-- 
1.9.1

From kewei.xu at mediatek.com  Sat Aug 28 03:50:59 2021
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 28 Aug 2021 18:50:59 +0800
Subject: [PATCH v6 7/7] i2c: mediatek: modify bus speed calculation formula
In-Reply-To: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
References: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1630147859-17031-8-git-send-email-kewei.xu@mediatek.com>

When clock-div is 0 or greater than 1, the bus speed
calculated by the old speed calculation formula will be
larger than the target speed. So we update the formula.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 0cf130b..b2dcdc3f 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -69,11 +69,12 @@
 #define I2C_DEFAULT_CLK_DIV		5
 #define MAX_SAMPLE_CNT_DIV		8
 #define MAX_STEP_CNT_DIV		64
-#define MAX_CLOCK_DIV			256
+#define MAX_CLOCK_DIV_8BITS		256
+#define MAX_CLOCK_DIV_5BITS		32
 #define MAX_HS_STEP_CNT_DIV		8
-#define I2C_STANDARD_MODE_BUFFER	(1000 / 2)
-#define I2C_FAST_MODE_BUFFER		(300 / 2)
-#define I2C_FAST_MODE_PLUS_BUFFER	(20 / 2)
+#define I2C_STANDARD_MODE_BUFFER	(1000 / 3)
+#define I2C_FAST_MODE_BUFFER		(300 / 3)
+#define I2C_FAST_MODE_PLUS_BUFFER	(20 / 3)
 
 #define I2C_CONTROL_RS                  (0x1 << 1)
 #define I2C_CONTROL_DMA_EN              (0x1 << 2)
@@ -725,14 +726,26 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	unsigned int best_mul;
 	unsigned int cnt_mul;
 	int ret = -EINVAL;
+	int clock_div_constraint = 0;
 
 	if (target_speed > I2C_MAX_HIGH_SPEED_MODE_FREQ)
 		target_speed = I2C_MAX_HIGH_SPEED_MODE_FREQ;
 
+	if (i2c->use_default_timing) {
+		clock_div_constraint = 0;
+	} else if (i2c->dev_comp->ltiming_adjust &&
+		   i2c->ac_timing.inter_clk_div > 1) {
+		clock_div_constraint = 1;
+	} else if (i2c->dev_comp->ltiming_adjust &&
+		   i2c->ac_timing.inter_clk_div == 0) {
+		clock_div_constraint = -1;
+	}
+
 	max_step_cnt = mtk_i2c_max_step_cnt(target_speed);
 	base_step_cnt = max_step_cnt;
 	/* Find the best combination */
-	opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
+	opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed) +
+		  clock_div_constraint;
 	best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
 
 	/* Search for the best pair (sample_cnt, step_cnt) with
@@ -767,7 +780,8 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
 	sample_cnt = base_sample_cnt;
 	step_cnt = base_step_cnt;
 
-	if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
+	if ((clk_src / (2 * (sample_cnt * step_cnt - clock_div_constraint))) >
+		 target_speed) {
 		/* In this case, hardware can't support such
 		 * low i2c_bus_freq
 		 */
@@ -854,13 +868,16 @@ static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
 	target_speed = i2c->speed_hz;
 	parent_clk /= i2c->clk_src_div;
 
-	if (i2c->dev_comp->timing_adjust)
-		max_clk_div = MAX_CLOCK_DIV;
+	if (i2c->dev_comp->timing_adjust && i2c->dev_comp->ltiming_adjust)
+		max_clk_div = MAX_CLOCK_DIV_5BITS;
+	else if (i2c->dev_comp->timing_adjust)
+		max_clk_div = MAX_CLOCK_DIV_8BITS;
 	else
 		max_clk_div = 1;
 
 	for (clk_div = 1; clk_div <= max_clk_div; clk_div++) {
 		clk_src = parent_clk / clk_div;
+		i2c->ac_timing.inter_clk_div = clk_div - 1;
 
 		if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) {
 			/* Set master code speed register */
@@ -907,8 +924,6 @@ static int mtk_i2c_set_speed_adjust_timing(struct mtk_i2c *i2c,
 		break;
 	}
 
-	i2c->ac_timing.inter_clk_div = clk_div - 1;
-
 	return 0;
 }
 
-- 
1.9.1

From julia.lawall at inria.fr  Sat Aug 28 04:04:54 2021
From: julia.lawall at inria.fr (Julia Lawall)
Date: Sat, 28 Aug 2021 13:04:54 +0200 (CEST)
Subject: [PATCH] v4l: xilinx-vpss-csc: fix for_each_child.cocci warnings
Message-ID: <alpine.DEB.2.22.394.2108281302310.10588@hadrien>

From: kernel test robot <lkp at intel.com>

for_each_child_of_node should have of_node_put() before return.

Generated by: scripts/coccinelle/iterators/for_each_child.cocci

CC: Rohit Athavale <rohit.athavale at xilinx.com>
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: kernel test robot <lkp at intel.com>
Signed-off-by: Julia Lawall <julia.lawall at inria.fr>

---

tree:   https://github.com/Xilinx/linux-xlnx master
head:   45cd0074cdf1ddd710b28848e6a860b442babfcc
commit: 7d47a653da2e81cb73f43e507664d36305819ea1 [10741/12418] v4l: xilinx-vpss-csc: driver support for xilinx vpss csc
:::::: branch date: 5 days ago
:::::: commit date: 5 months ago

Please take the patch only if it's a positive warning. Thanks!

 xilinx-vpss-csc.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/media/platform/xilinx/xilinx-vpss-csc.c
+++ b/drivers/media/platform/xilinx/xilinx-vpss-csc.c
@@ -749,17 +749,20 @@ static int xcsc_parse_of(struct xcsc_dev
 			vip_format = xvip_of_get_format(port);
 			if (IS_ERR(vip_format)) {
 				dev_err(dev, "Invalid media pad format in DT");
+				of_node_put(port);
 				return PTR_ERR(vip_format);
 			}

 			rval = of_property_read_u32(port, "reg", &port_id);
 			if (rval < 0) {
 				dev_err(dev, "No reg in DT to specify pad");
+				of_node_put(port);
 				return rval;
 			}

 			if (port_id != 0 && port_id != 1) {
 				dev_err(dev, "Invalid reg in DT");
+				of_node_put(port);
 				return -EINVAL;
 			}
 			xcsc->vip_formats[port_id] = vip_format;


From lkp at intel.com  Sat Aug 28 04:07:08 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 28 Aug 2021 19:07:08 +0800
Subject: [soc:rockchips/dt64-late] BUILD SUCCESS
 9a35fd01f4abc3974e12539448038307acf27f16
Message-ID: <612a18dc.KgagCKQPy0eiVTcS%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git rockchips/dt64-late
branch HEAD: 9a35fd01f4abc3974e12539448038307acf27f16  arm64: dts: rockchip: add RK3399 Gru gpio-line-names

elapsed time: 9761m

configs tested: 224
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210827
powerpc              randconfig-c003-20210827
i386                 randconfig-c001-20210821
sh                           se7722_defconfig
arm64                            alldefconfig
powerpc                mpc7448_hpc2_defconfig
mips                      maltasmvp_defconfig
arm                         cm_x300_defconfig
alpha                            alldefconfig
m68k                         apollo_defconfig
powerpc                      pmac32_defconfig
nios2                               defconfig
mips                           xway_defconfig
x86_64                           alldefconfig
arm                  colibri_pxa270_defconfig
arm                         at91_dt_defconfig
riscv             nommu_k210_sdcard_defconfig
sh                             shx3_defconfig
powerpc                 mpc837x_mds_defconfig
riscv                            alldefconfig
powerpc                     asp8347_defconfig
csky                                defconfig
arc                     nsimosci_hs_defconfig
m68k                        mvme16x_defconfig
arm                            xcep_defconfig
sh                           se7780_defconfig
arm                          imote2_defconfig
mips                            gpr_defconfig
h8300                               defconfig
powerpc                     stx_gp3_defconfig
arm                            mps2_defconfig
powerpc                  mpc866_ads_defconfig
mips                           gcw0_defconfig
powerpc64                           defconfig
mips                           mtx1_defconfig
m68k                         amcore_defconfig
powerpc                      katmai_defconfig
sh                           se7751_defconfig
ia64                        generic_defconfig
sh                          rsk7201_defconfig
sh                           se7750_defconfig
powerpc                 mpc8540_ads_defconfig
powerpc                       ppc64_defconfig
microblaze                      mmu_defconfig
nds32                             allnoconfig
sh                         apsh4a3a_defconfig
arm                        keystone_defconfig
sh                           sh2007_defconfig
sh                        edosk7705_defconfig
xtensa                generic_kc705_defconfig
arm                         lpc32xx_defconfig
sh                           se7343_defconfig
powerpc                     tqm8540_defconfig
powerpc                     akebono_defconfig
nios2                         3c120_defconfig
arc                        vdk_hs38_defconfig
sh                         ap325rxa_defconfig
sh                        sh7763rdp_defconfig
sh                   rts7751r2dplus_defconfig
powerpc                    mvme5100_defconfig
powerpc                   microwatt_defconfig
arm                           viper_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                 mpc8272_ads_defconfig
arc                      axs103_smp_defconfig
sh                ecovec24-romimage_defconfig
arm                          badge4_defconfig
sh                     sh7710voipgw_defconfig
powerpc                      tqm8xx_defconfig
mips                           ip27_defconfig
powerpc                       eiger_defconfig
mips                          ath79_defconfig
powerpc                 mpc836x_rdk_defconfig
arm                         s3c6400_defconfig
powerpc                       holly_defconfig
powerpc                 mpc834x_itx_defconfig
arm                           stm32_defconfig
powerpc                  storcenter_defconfig
sh                            migor_defconfig
sh                        sh7785lcr_defconfig
arm                         bcm2835_defconfig
powerpc                      ppc6xx_defconfig
arm                         nhk8815_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210822
x86_64               randconfig-a006-20210822
x86_64               randconfig-a001-20210822
x86_64               randconfig-a003-20210822
x86_64               randconfig-a004-20210822
x86_64               randconfig-a002-20210822
i386                 randconfig-a001-20210828
i386                 randconfig-a006-20210828
i386                 randconfig-a002-20210828
i386                 randconfig-a005-20210828
i386                 randconfig-a003-20210828
i386                 randconfig-a004-20210828
i386                 randconfig-a006-20210822
i386                 randconfig-a001-20210822
i386                 randconfig-a002-20210822
i386                 randconfig-a005-20210822
i386                 randconfig-a003-20210822
i386                 randconfig-a004-20210822
x86_64               randconfig-a014-20210827
x86_64               randconfig-a015-20210827
x86_64               randconfig-a016-20210827
x86_64               randconfig-a013-20210827
x86_64               randconfig-a012-20210827
x86_64               randconfig-a011-20210827
x86_64               randconfig-a014-20210821
x86_64               randconfig-a016-20210821
x86_64               randconfig-a015-20210821
x86_64               randconfig-a013-20210821
x86_64               randconfig-a012-20210821
x86_64               randconfig-a011-20210821
i386                 randconfig-a011-20210827
i386                 randconfig-a016-20210827
i386                 randconfig-a012-20210827
i386                 randconfig-a014-20210827
i386                 randconfig-a013-20210827
i386                 randconfig-a015-20210827
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210822
s390                 randconfig-c005-20210822
arm                  randconfig-c002-20210822
riscv                randconfig-c006-20210822
powerpc              randconfig-c003-20210822
x86_64               randconfig-c007-20210822
mips                 randconfig-c004-20210822
x86_64               randconfig-a005-20210827
x86_64               randconfig-a001-20210827
x86_64               randconfig-a006-20210827
x86_64               randconfig-a003-20210827
x86_64               randconfig-a004-20210827
x86_64               randconfig-a002-20210827
x86_64               randconfig-a005-20210821
x86_64               randconfig-a001-20210821
x86_64               randconfig-a006-20210821
x86_64               randconfig-a003-20210821
x86_64               randconfig-a004-20210821
x86_64               randconfig-a002-20210821
i386                 randconfig-a006-20210827
i386                 randconfig-a001-20210827
i386                 randconfig-a002-20210827
i386                 randconfig-a005-20210827
i386                 randconfig-a004-20210827
i386                 randconfig-a003-20210827
i386                 randconfig-a006-20210821
i386                 randconfig-a001-20210821
i386                 randconfig-a002-20210821
i386                 randconfig-a005-20210821
i386                 randconfig-a004-20210821
i386                 randconfig-a003-20210821
x86_64               randconfig-a014-20210822
x86_64               randconfig-a016-20210822
x86_64               randconfig-a015-20210822
x86_64               randconfig-a013-20210822
x86_64               randconfig-a012-20210822
x86_64               randconfig-a011-20210822
i386                 randconfig-a011-20210822
i386                 randconfig-a016-20210822
i386                 randconfig-a012-20210822
i386                 randconfig-a014-20210822
i386                 randconfig-a013-20210822
i386                 randconfig-a015-20210822
i386                 randconfig-a011-20210828
i386                 randconfig-a016-20210828
i386                 randconfig-a012-20210828
i386                 randconfig-a014-20210828
i386                 randconfig-a013-20210828
i386                 randconfig-a015-20210828
hexagon              randconfig-r041-20210822
hexagon              randconfig-r045-20210822
riscv                randconfig-r042-20210822
s390                 randconfig-r044-20210822

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sat Aug 28 04:06:49 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 28 Aug 2021 19:06:49 +0800
Subject: [soc:rockchips/dt64-late-2] BUILD SUCCESS
 b12a5946f5ea7a54b8b983c42f0812152e3122de
Message-ID: <612a18c9.24K4GPnSCY7o3IB/%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git rockchips/dt64-late-2
branch HEAD: b12a5946f5ea7a54b8b983c42f0812152e3122de  arm64: dts: rockchip: add saradc to rk3568-evb1-v10

elapsed time: 6714m

configs tested: 267
configs skipped: 5

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210824
i386                 randconfig-c001-20210827
powerpc              randconfig-c003-20210827
arc                            hsdk_defconfig
arm                         lpc32xx_defconfig
alpha                            allyesconfig
sh                           sh2007_defconfig
arm                        clps711x_defconfig
sh                   sh7724_generic_defconfig
arm                       cns3420vb_defconfig
ia64                        generic_defconfig
m68k                        m5272c3_defconfig
m68k                             allyesconfig
nios2                               defconfig
mips                           xway_defconfig
x86_64                           alldefconfig
arm                  colibri_pxa270_defconfig
arm                        spear6xx_defconfig
mips                malta_qemu_32r6_defconfig
sh                          sdk7786_defconfig
xtensa                       common_defconfig
powerpc                    adder875_defconfig
m68k                         apollo_defconfig
openrisc                            defconfig
powerpc                      bamboo_defconfig
powerpc                     skiroot_defconfig
arm                         lpc18xx_defconfig
m68k                       m5275evb_defconfig
mips                         mpc30x_defconfig
mips                           ip32_defconfig
powerpc                   lite5200b_defconfig
riscv                    nommu_virt_defconfig
arm                         vf610m4_defconfig
arm                          collie_defconfig
arm                       imx_v4_v5_defconfig
mips                        maltaup_defconfig
arm                         palmz72_defconfig
nds32                            alldefconfig
powerpc                     tqm8541_defconfig
sh                        edosk7760_defconfig
m68k                       m5249evb_defconfig
sh                   rts7751r2dplus_defconfig
arc                          axs101_defconfig
sh                 kfr2r09-romimage_defconfig
sh                         ap325rxa_defconfig
mips                          rm200_defconfig
arm                       netwinder_defconfig
openrisc                    or1ksim_defconfig
ia64                          tiger_defconfig
mips                        jmr3927_defconfig
arm                         s5pv210_defconfig
arm                        mini2440_defconfig
xtensa                  cadence_csp_defconfig
powerpc                      ppc44x_defconfig
sh                           se7722_defconfig
sh                           se7751_defconfig
sh                          rsk7201_defconfig
sh                           se7780_defconfig
sh                                  defconfig
arm                           stm32_defconfig
sh                           se7721_defconfig
mips                     loongson2k_defconfig
mips                           mtx1_defconfig
powerpc                        warp_defconfig
m68k                        mvme147_defconfig
arm                          badge4_defconfig
powerpc                  mpc866_ads_defconfig
powerpc                 mpc834x_itx_defconfig
powerpc                     pq2fads_defconfig
powerpc                      arches_defconfig
arm                             rpc_defconfig
ia64                             allyesconfig
powerpc                      makalu_defconfig
m68k                          multi_defconfig
arc                         haps_hs_defconfig
sh                   sh7770_generic_defconfig
xtensa                  audio_kc705_defconfig
mips                   sb1250_swarm_defconfig
arm                       aspeed_g4_defconfig
sh                            titan_defconfig
sparc                       sparc64_defconfig
sh                          lboxre2_defconfig
nds32                             allnoconfig
sh                         apsh4a3a_defconfig
arm                        keystone_defconfig
sh                        edosk7705_defconfig
powerpc                     akebono_defconfig
nios2                         3c120_defconfig
arc                        vdk_hs38_defconfig
sh                        sh7763rdp_defconfig
powerpc                      ppc64e_defconfig
sh                           se7705_defconfig
sh                               allmodconfig
arm                        cerfcube_defconfig
riscv             nommu_k210_sdcard_defconfig
sh                        dreamcast_defconfig
powerpc                 mpc836x_rdk_defconfig
arm                         s3c6400_defconfig
powerpc                       holly_defconfig
arm                         bcm2835_defconfig
powerpc                      ppc6xx_defconfig
sh                           se7343_defconfig
arm                         nhk8815_defconfig
arm                            zeus_defconfig
powerpc               mpc834x_itxgp_defconfig
powerpc                  storcenter_defconfig
s390                             alldefconfig
arm                        multi_v7_defconfig
x86_64                            allnoconfig
ia64                             allmodconfig
ia64                                defconfig
m68k                             allmodconfig
m68k                                defconfig
arc                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20210822
x86_64               randconfig-a006-20210822
x86_64               randconfig-a001-20210822
x86_64               randconfig-a003-20210822
x86_64               randconfig-a004-20210822
x86_64               randconfig-a002-20210822
x86_64               randconfig-a005-20210824
x86_64               randconfig-a006-20210824
x86_64               randconfig-a001-20210824
x86_64               randconfig-a003-20210824
x86_64               randconfig-a004-20210824
x86_64               randconfig-a002-20210824
i386                 randconfig-a006-20210824
i386                 randconfig-a001-20210824
i386                 randconfig-a002-20210824
i386                 randconfig-a005-20210824
i386                 randconfig-a003-20210824
i386                 randconfig-a004-20210824
i386                 randconfig-a001-20210828
i386                 randconfig-a006-20210828
i386                 randconfig-a002-20210828
i386                 randconfig-a005-20210828
i386                 randconfig-a003-20210828
i386                 randconfig-a004-20210828
i386                 randconfig-a006-20210822
i386                 randconfig-a001-20210822
i386                 randconfig-a002-20210822
i386                 randconfig-a005-20210822
i386                 randconfig-a003-20210822
i386                 randconfig-a004-20210822
x86_64               randconfig-a014-20210827
x86_64               randconfig-a015-20210827
x86_64               randconfig-a016-20210827
x86_64               randconfig-a013-20210827
x86_64               randconfig-a012-20210827
x86_64               randconfig-a011-20210827
i386                 randconfig-a011-20210827
i386                 randconfig-a016-20210827
i386                 randconfig-a012-20210827
i386                 randconfig-a014-20210827
i386                 randconfig-a013-20210827
i386                 randconfig-a015-20210827
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210822
s390                 randconfig-c005-20210822
arm                  randconfig-c002-20210822
riscv                randconfig-c006-20210822
powerpc              randconfig-c003-20210822
x86_64               randconfig-c007-20210822
mips                 randconfig-c004-20210822
s390                 randconfig-c005-20210825
i386                 randconfig-c001-20210825
arm                  randconfig-c002-20210825
riscv                randconfig-c006-20210825
powerpc              randconfig-c003-20210825
x86_64               randconfig-c007-20210825
mips                 randconfig-c004-20210825
s390                 randconfig-c005-20210827
i386                 randconfig-c001-20210827
arm                  randconfig-c002-20210827
riscv                randconfig-c006-20210827
powerpc              randconfig-c003-20210827
x86_64               randconfig-c007-20210827
mips                 randconfig-c004-20210827
x86_64               randconfig-a005-20210827
x86_64               randconfig-a001-20210827
x86_64               randconfig-a006-20210827
x86_64               randconfig-a003-20210827
x86_64               randconfig-a004-20210827
x86_64               randconfig-a002-20210827
i386                 randconfig-a006-20210827
i386                 randconfig-a001-20210827
i386                 randconfig-a002-20210827
i386                 randconfig-a005-20210827
i386                 randconfig-a004-20210827
i386                 randconfig-a003-20210827
x86_64               randconfig-a014-20210822
x86_64               randconfig-a016-20210822
x86_64               randconfig-a015-20210822
x86_64               randconfig-a013-20210822
x86_64               randconfig-a012-20210822
x86_64               randconfig-a011-20210822
x86_64               randconfig-a014-20210824
x86_64               randconfig-a015-20210824
x86_64               randconfig-a016-20210824
x86_64               randconfig-a013-20210824
x86_64               randconfig-a012-20210824
x86_64               randconfig-a011-20210824
i386                 randconfig-a011-20210828
i386                 randconfig-a016-20210828
i386                 randconfig-a012-20210828
i386                 randconfig-a014-20210828
i386                 randconfig-a013-20210828
i386                 randconfig-a015-20210828
i386                 randconfig-a011-20210822
i386                 randconfig-a016-20210822
i386                 randconfig-a012-20210822
i386                 randconfig-a014-20210822
i386                 randconfig-a013-20210822
i386                 randconfig-a015-20210822
i386                 randconfig-a011-20210824
i386                 randconfig-a016-20210824
i386                 randconfig-a012-20210824
i386                 randconfig-a014-20210824
i386                 randconfig-a013-20210824
i386                 randconfig-a015-20210824
hexagon              randconfig-r041-20210824
hexagon              randconfig-r045-20210824
riscv                randconfig-r042-20210824
s390                 randconfig-r044-20210824
hexagon              randconfig-r041-20210822
hexagon              randconfig-r045-20210822
riscv                randconfig-r042-20210822
s390                 randconfig-r044-20210822

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sat Aug 28 04:07:01 2021
From: lkp at intel.com (kernel test robot)
Date: Sat, 28 Aug 2021 19:07:01 +0800
Subject: [soc:zynqmp/dt-late] BUILD SUCCESS
 479c46133c0573b6549e437165bff1422634f45f
Message-ID: <612a18d5.WHW3Ry9fyYL3eYcR%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git zynqmp/dt-late
branch HEAD: 479c46133c0573b6549e437165bff1422634f45f  arm64: zynqmp: Wire psgtr for zc1751-xm013

elapsed time: 4507m

configs tested: 458
configs skipped: 5

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210825
i386                 randconfig-c001-20210826
i386                 randconfig-c001-20210827
powerpc              randconfig-c003-20210827
powerpc              randconfig-c003-20210826
sh                          rsk7269_defconfig
powerpc                      cm5200_defconfig
arm                           u8500_defconfig
powerpc                     mpc512x_defconfig
parisc                              defconfig
nios2                            allyesconfig
arm                          gemini_defconfig
mips                      fuloong2e_defconfig
powerpc                       holly_defconfig
m68k                            mac_defconfig
powerpc                 mpc836x_mds_defconfig
sh                           se7722_defconfig
powerpc                     powernv_defconfig
powerpc                        warp_defconfig
mips                      loongson3_defconfig
um                             i386_defconfig
powerpc                       ebony_defconfig
arm                           sama5_defconfig
m68k                          amiga_defconfig
m68k                          sun3x_defconfig
xtensa                       common_defconfig
h8300                               defconfig
xtensa                generic_kc705_defconfig
mips                         bigsur_defconfig
arm                      footbridge_defconfig
ia64                         bigsur_defconfig
ia64                            zx1_defconfig
powerpc                 mpc85xx_cds_defconfig
powerpc                 mpc834x_itx_defconfig
sh                         microdev_defconfig
arm                       netwinder_defconfig
arm                         mv78xx0_defconfig
ia64                      gensparse_defconfig
mips                     cu1000-neo_defconfig
powerpc                 mpc832x_mds_defconfig
arm                         vf610m4_defconfig
sh                     sh7710voipgw_defconfig
x86_64                           allyesconfig
powerpc                      bamboo_defconfig
arm                          badge4_defconfig
arc                          axs103_defconfig
arm                    vt8500_v6_v7_defconfig
xtensa                    xip_kc705_defconfig
mips                     loongson1b_defconfig
powerpc                      ppc64e_defconfig
parisc                generic-32bit_defconfig
arm                          ep93xx_defconfig
arc                            hsdk_defconfig
arm                         lpc32xx_defconfig
sh                           sh2007_defconfig
powerpc                         ps3_defconfig
sh                               alldefconfig
arm                            lart_defconfig
sh                         apsh4a3a_defconfig
arm                           viper_defconfig
powerpc                     akebono_defconfig
powerpc                   lite5200b_defconfig
mips                    maltaup_xpa_defconfig
powerpc                      ppc40x_defconfig
mips                           ip32_defconfig
arm                       aspeed_g4_defconfig
mips                      bmips_stb_defconfig
arm                            xcep_defconfig
arm                            mps2_defconfig
arm                        keystone_defconfig
mips                        vocore2_defconfig
sh                           se7721_defconfig
arm                         nhk8815_defconfig
powerpc                    amigaone_defconfig
m68k                       m5249evb_defconfig
arm                            mmp2_defconfig
powerpc                       eiger_defconfig
powerpc                 canyonlands_defconfig
arm                         cm_x300_defconfig
mips                           ip27_defconfig
powerpc                 mpc8313_rdb_defconfig
s390                             alldefconfig
nios2                               defconfig
mips                           xway_defconfig
x86_64                           alldefconfig
arm                  colibri_pxa270_defconfig
sparc                            alldefconfig
mips                        jmr3927_defconfig
arc                        nsim_700_defconfig
powerpc                   currituck_defconfig
arm                            dove_defconfig
powerpc                     ep8248e_defconfig
powerpc                      katmai_defconfig
xtensa                  audio_kc705_defconfig
powerpc                    gamecube_defconfig
mips                      maltasmvp_defconfig
arc                 nsimosci_hs_smp_defconfig
xtensa                           alldefconfig
arm                        oxnas_v6_defconfig
nds32                            alldefconfig
powerpc                    ge_imp3a_defconfig
powerpc                 mpc837x_mds_defconfig
arm                      integrator_defconfig
sh                           se7206_defconfig
powerpc                      mgcoge_defconfig
mips                             allyesconfig
powerpc                     tqm8555_defconfig
arm                        multi_v5_defconfig
arm                         hackkit_defconfig
mips                        nlm_xlr_defconfig
xtensa                  nommu_kc705_defconfig
m68k                            q40_defconfig
sh                             sh03_defconfig
arm                           spitz_defconfig
arm                       multi_v4t_defconfig
powerpc                 mpc836x_rdk_defconfig
mips                       capcella_defconfig
x86_64                              defconfig
arm                         lpc18xx_defconfig
m68k                       m5275evb_defconfig
mips                         mpc30x_defconfig
m68k                        m5272c3_defconfig
powerpc                   microwatt_defconfig
sh                           se7343_defconfig
arm                         assabet_defconfig
powerpc                     redwood_defconfig
mips                  maltasmvp_eva_defconfig
ia64                                defconfig
arc                                 defconfig
powerpc                      ppc44x_defconfig
arm                         at91_dt_defconfig
sh                ecovec24-romimage_defconfig
powerpc                          g5_defconfig
sh                         ecovec24_defconfig
arc                        vdk_hs38_defconfig
sh                        edosk7760_defconfig
powerpc                    klondike_defconfig
powerpc                     mpc83xx_defconfig
powerpc                  mpc885_ads_defconfig
powerpc                      ep88xc_defconfig
alpha                            alldefconfig
sh                          r7780mp_defconfig
powerpc                     tqm5200_defconfig
arm                           tegra_defconfig
arm                   milbeaut_m10v_defconfig
powerpc                     tqm8548_defconfig
sh                        sh7785lcr_defconfig
um                           x86_64_defconfig
riscv                    nommu_virt_defconfig
arm                          collie_defconfig
sh                        sh7763rdp_defconfig
sh                          sdk7786_defconfig
powerpc                 mpc837x_rdb_defconfig
arm                         axm55xx_defconfig
mips                         tb0219_defconfig
arm                          moxart_defconfig
mips                     decstation_defconfig
powerpc                 mpc8560_ads_defconfig
sh                            migor_defconfig
ia64                        generic_defconfig
arm                       imx_v4_v5_defconfig
mips                        maltaup_defconfig
arm                         palmz72_defconfig
powerpc                      acadia_defconfig
powerpc                     stx_gp3_defconfig
sh                          landisk_defconfig
sh                          rsk7264_defconfig
arm                      pxa255-idp_defconfig
arm                        spear3xx_defconfig
arc                    vdk_hs38_smp_defconfig
openrisc                 simple_smp_defconfig
powerpc                     mpc5200_defconfig
m68k                        m5407c3_defconfig
arm                            pleb_defconfig
sh                   secureedge5410_defconfig
powerpc                         wii_defconfig
arm                         shannon_defconfig
riscv                               defconfig
arm                          pcm027_defconfig
mips                        nlm_xlp_defconfig
m68k                                defconfig
h8300                     edosk2674_defconfig
powerpc                 mpc8540_ads_defconfig
arm                             mxs_defconfig
sh                            shmin_defconfig
mips                     loongson2k_defconfig
arm                            zeus_defconfig
powerpc                     pq2fads_defconfig
arm                         bcm2835_defconfig
mips                       bmips_be_defconfig
powerpc                      tqm8xx_defconfig
arm                         s5pv210_defconfig
sh                        edosk7705_defconfig
sh                 kfr2r09-romimage_defconfig
s390                             allmodconfig
mips                           ci20_defconfig
sh                               j2_defconfig
powerpc                      arches_defconfig
mips                         tb0226_defconfig
arm                        neponset_defconfig
sh                          rsk7201_defconfig
ia64                          tiger_defconfig
mips                          malta_defconfig
mips                           rs90_defconfig
mips                   sb1250_swarm_defconfig
mips                         rt305x_defconfig
openrisc                  or1klitex_defconfig
powerpc               mpc834x_itxgp_defconfig
xtensa                         virt_defconfig
arm                          lpd270_defconfig
riscv                             allnoconfig
sh                           se7751_defconfig
sh                           se7780_defconfig
m68k                        mvme16x_defconfig
i386                                defconfig
powerpc                      pcm030_defconfig
arm                          ixp4xx_defconfig
arm                       spear13xx_defconfig
sh                           se7705_defconfig
mips                           ip22_defconfig
sh                                  defconfig
openrisc                            defconfig
powerpc                     asp8347_defconfig
sparc                       sparc64_defconfig
s390                          debug_defconfig
powerpc                 mpc8272_ads_defconfig
arm                           h5000_defconfig
sh                           se7712_defconfig
xtensa                  cadence_csp_defconfig
m68k                        mvme147_defconfig
m68k                           sun3_defconfig
powerpc                           allnoconfig
arm                        spear6xx_defconfig
mips                         db1xxx_defconfig
xtensa                              defconfig
um                                  defconfig
powerpc                    socrates_defconfig
xtensa                    smp_lx200_defconfig
mips                          ath25_defconfig
powerpc                     ksi8560_defconfig
riscv                          rv32_defconfig
xtensa                          iss_defconfig
arm                             ezx_defconfig
powerpc                      makalu_defconfig
m68k                          multi_defconfig
arm                        trizeps4_defconfig
sh                            titan_defconfig
arm                             rpc_defconfig
sh                          lboxre2_defconfig
sparc                       sparc32_defconfig
powerpc                 mpc8315_rdb_defconfig
sh                      rts7751r2d1_defconfig
m68k                          atari_defconfig
mips                malta_qemu_32r6_defconfig
nds32                             allnoconfig
arc                          axs101_defconfig
nios2                         10m50_defconfig
mips                          ath79_defconfig
arm                           stm32_defconfig
sh                             shx3_defconfig
sparc                               defconfig
arm                             pxa_defconfig
powerpc                     tqm8540_defconfig
microblaze                      mmu_defconfig
h8300                       h8s-sim_defconfig
sh                          urquell_defconfig
riscv                    nommu_k210_defconfig
arm                           corgi_defconfig
mips                            e55_defconfig
nios2                         3c120_defconfig
sh                         ap325rxa_defconfig
sh                   rts7751r2dplus_defconfig
mips                          rb532_defconfig
m68k                          hp300_defconfig
arm                          pxa3xx_defconfig
mips                      pic32mzda_defconfig
arm64                            alldefconfig
mips                        omega2p_defconfig
sh                          sdk7780_defconfig
ia64                             alldefconfig
powerpc                        icon_defconfig
ia64                             allyesconfig
arm                          imote2_defconfig
powerpc                     taishan_defconfig
mips                        qi_lb60_defconfig
powerpc                        fsp2_defconfig
arm                        multi_v7_defconfig
mips                     loongson1c_defconfig
powerpc                    adder875_defconfig
arm                          pxa910_defconfig
powerpc                     tqm8541_defconfig
sh                   sh7770_generic_defconfig
mips                         tb0287_defconfig
sh                            hp6xx_defconfig
arm                       imx_v6_v7_defconfig
sh                           se7619_defconfig
arm                        vexpress_defconfig
powerpc64                        alldefconfig
powerpc                      pasemi_defconfig
sparc64                          alldefconfig
powerpc                     ppa8548_defconfig
powerpc                       ppc64_defconfig
arm                            hisi_defconfig
sh                              ul2_defconfig
openrisc                    or1ksim_defconfig
powerpc                      pmac32_defconfig
arm                         s3c6400_defconfig
mips                        bcm47xx_defconfig
powerpc                     pseries_defconfig
arm                           omap1_defconfig
powerpc                  storcenter_defconfig
powerpc                      ppc6xx_defconfig
um                               alldefconfig
arm                        magician_defconfig
arm                      jornada720_defconfig
riscv             nommu_k210_sdcard_defconfig
arm                          pxa168_defconfig
microblaze                          defconfig
powerpc                          allmodconfig
x86_64                            allnoconfig
ia64                             allmodconfig
m68k                             allmodconfig
m68k                             allyesconfig
arc                              allyesconfig
nds32                               defconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
sh                               allmodconfig
s390                             allyesconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
x86_64               randconfig-a005-20210826
x86_64               randconfig-a006-20210826
x86_64               randconfig-a001-20210826
x86_64               randconfig-a003-20210826
x86_64               randconfig-a004-20210826
x86_64               randconfig-a002-20210826
i386                 randconfig-a006-20210826
i386                 randconfig-a001-20210826
i386                 randconfig-a002-20210826
i386                 randconfig-a005-20210826
i386                 randconfig-a003-20210826
i386                 randconfig-a004-20210826
i386                 randconfig-a001-20210828
i386                 randconfig-a006-20210828
i386                 randconfig-a002-20210828
i386                 randconfig-a005-20210828
i386                 randconfig-a003-20210828
i386                 randconfig-a004-20210828
x86_64               randconfig-a014-20210825
x86_64               randconfig-a015-20210825
x86_64               randconfig-a016-20210825
x86_64               randconfig-a013-20210825
x86_64               randconfig-a012-20210825
x86_64               randconfig-a011-20210825
x86_64               randconfig-a014-20210827
x86_64               randconfig-a015-20210827
x86_64               randconfig-a016-20210827
x86_64               randconfig-a012-20210827
x86_64               randconfig-a011-20210827
x86_64               randconfig-a013-20210827
i386                 randconfig-a011-20210825
i386                 randconfig-a016-20210825
i386                 randconfig-a012-20210825
i386                 randconfig-a014-20210825
i386                 randconfig-a013-20210825
i386                 randconfig-a015-20210825
i386                 randconfig-a011-20210827
i386                 randconfig-a016-20210827
i386                 randconfig-a012-20210827
i386                 randconfig-a014-20210827
i386                 randconfig-a013-20210827
i386                 randconfig-a015-20210827
arc                  randconfig-r043-20210825
riscv                randconfig-r042-20210825
s390                 randconfig-r044-20210825
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                            allyesconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
i386                 randconfig-c001-20210826
s390                 randconfig-c005-20210826
arm                  randconfig-c002-20210826
riscv                randconfig-c006-20210826
powerpc              randconfig-c003-20210826
x86_64               randconfig-c007-20210826
mips                 randconfig-c004-20210826
s390                 randconfig-c005-20210827
i386                 randconfig-c001-20210827
arm                  randconfig-c002-20210827
riscv                randconfig-c006-20210827
powerpc              randconfig-c003-20210827
x86_64               randconfig-c007-20210827
mips                 randconfig-c004-20210827
s390                 randconfig-c005-20210825
i386                 randconfig-c001-20210825
arm                  randconfig-c002-20210825
riscv                randconfig-c006-20210825
powerpc              randconfig-c003-20210825
x86_64               randconfig-c007-20210825
mips                 randconfig-c004-20210825
x86_64               randconfig-a005-20210825
x86_64               randconfig-a001-20210825
x86_64               randconfig-a006-20210825
x86_64               randconfig-a003-20210825
x86_64               randconfig-a004-20210825
x86_64               randconfig-a002-20210825
x86_64               randconfig-a005-20210827
x86_64               randconfig-a001-20210827
x86_64               randconfig-a006-20210827
x86_64               randconfig-a003-20210827
x86_64               randconfig-a004-20210827
x86_64               randconfig-a002-20210827
i386                 randconfig-a006-20210825
i386                 randconfig-a001-20210825
i386                 randconfig-a002-20210825
i386                 randconfig-a005-20210825
i386                 randconfig-a004-20210825
i386                 randconfig-a003-20210825
i386                 randconfig-a006-20210827
i386                 randconfig-a001-20210827
i386                 randconfig-a002-20210827
i386                 randconfig-a005-20210827
i386                 randconfig-a004-20210827
i386                 randconfig-a003-20210827
x86_64               randconfig-a014-20210826
x86_64               randconfig-a015-20210826
x86_64               randconfig-a016-20210826
x86_64               randconfig-a013-20210826
x86_64               randconfig-a012-20210826
x86_64               randconfig-a011-20210826
i386                 randconfig-a011-20210826
i386                 randconfig-a016-20210826
i386                 randconfig-a012-20210826
i386                 randconfig-a014-20210826
i386                 randconfig-a013-20210826
i386                 randconfig-a015-20210826
i386                 randconfig-a011-20210828
i386                 randconfig-a016-20210828
i386                 randconfig-a012-20210828
i386                 randconfig-a014-20210828
i386                 randconfig-a013-20210828
i386                 randconfig-a015-20210828
hexagon              randconfig-r041-20210826
hexagon              randconfig-r045-20210826
riscv                randconfig-r042-20210826
s390                 randconfig-r044-20210826

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From julia.lawall at inria.fr  Sat Aug 28 04:12:14 2021
From: julia.lawall at inria.fr (Julia Lawall)
Date: Sat, 28 Aug 2021 13:12:14 +0200 (CEST)
Subject: [xlnx:master 10763/12418]
 drivers/gpu/drm/xlnx/xlnx_pl_disp.c:47:19-22:
 WARNING use flexible-array member instead
 (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)
 (fwd)
Message-ID: <alpine.DEB.2.22.394.2108281311120.10588@hadrien>

Please check line 47.

---------- Forwarded message ----------
Date: Wed, 25 Aug 2021 22:49:02 +0800
From: kernel test robot <lkp at intel.com>
To: kbuild at lists.01.org
Cc: lkp at intel.com, Julia Lawall <julia.lawall at lip6.fr>
Subject: [xlnx:master 10763/12418] drivers/gpu/drm/xlnx/xlnx_pl_disp.c:47:19-22:
     WARNING use flexible-array member instead
    (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-
    and-one-element-arrays)

CC: kbuild-all at lists.01.org
CC: linux-arm-kernel at lists.infradead.org
TO: Saurabh Sengar <saurabh.singh at xilinx.com>
CC: Michal Simek <monstr at monstr.eu>
CC: Hyun Kwon <hyun.kwon at xilinx.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   45cd0074cdf1ddd710b28848e6a860b442babfcc
commit: f74536b5ee8056ab562f04c81e1a34e6c4779025 [10763/12418] drm: xlnx: DRM KMS driver for xilinx display pipeline
:::::: branch date: 2 days ago
:::::: commit date: 5 months ago
config: arm64-randconfig-c024-20210825 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 11.2.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>
Reported-by: Julia Lawall <julia.lawall at lip6.fr>


cocci warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/xlnx/xlnx_pl_disp.c:47:19-22: WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)

vim +47 drivers/gpu/drm/xlnx/xlnx_pl_disp.c

f74536b5ee8056 Saurabh Sengar 2018-02-07  27
f74536b5ee8056 Saurabh Sengar 2018-02-07  28  /*
f74536b5ee8056 Saurabh Sengar 2018-02-07  29   * Overview
f74536b5ee8056 Saurabh Sengar 2018-02-07  30   * --------
f74536b5ee8056 Saurabh Sengar 2018-02-07  31   *
f74536b5ee8056 Saurabh Sengar 2018-02-07  32   * This driver intends to support the display pipeline with DMA engine
f74536b5ee8056 Saurabh Sengar 2018-02-07  33   * driver by initializing DRM crtc and plane objects. The driver makes
f74536b5ee8056 Saurabh Sengar 2018-02-07  34   * an assumption that it's single plane pipeline, as multi-plane pipeline
f74536b5ee8056 Saurabh Sengar 2018-02-07  35   * would require programing beyond the DMA engine interface.
f74536b5ee8056 Saurabh Sengar 2018-02-07  36   */
f74536b5ee8056 Saurabh Sengar 2018-02-07  37
f74536b5ee8056 Saurabh Sengar 2018-02-07  38  /**
f74536b5ee8056 Saurabh Sengar 2018-02-07  39   * struct xlnx_dma_chan - struct for DMA engine
f74536b5ee8056 Saurabh Sengar 2018-02-07  40   * @dma_chan: DMA channel
f74536b5ee8056 Saurabh Sengar 2018-02-07  41   * @xt: Interleaved desc config container
f74536b5ee8056 Saurabh Sengar 2018-02-07  42   * @sgl: Data chunk for dma_interleaved_template
f74536b5ee8056 Saurabh Sengar 2018-02-07  43   */
f74536b5ee8056 Saurabh Sengar 2018-02-07  44  struct xlnx_dma_chan {
f74536b5ee8056 Saurabh Sengar 2018-02-07  45  	struct dma_chan *dma_chan;
f74536b5ee8056 Saurabh Sengar 2018-02-07  46  	struct dma_interleaved_template xt;
f74536b5ee8056 Saurabh Sengar 2018-02-07 @47  	struct data_chunk sgl[1];
f74536b5ee8056 Saurabh Sengar 2018-02-07  48  };
f74536b5ee8056 Saurabh Sengar 2018-02-07  49

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 31078 bytes
Desc: 
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210828/5b384f09/attachment-0001.gz>

From jbx6244 at gmail.com  Sat Aug 28 04:12:17 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 13:12:17 +0200
Subject: [PATCH 1/2] dt-bindings: phy: rockchip: remove usb-phy fallback
 string for rk3066a/rk3188
Message-ID: <20210828111218.10026-1-jbx6244@gmail.com>

With the conversion of rockchip-usb-phy.yaml a long time used fallback
string for rk3066a/rk3188 was added. The linux driver doesn't do much with
the GRF phy address range, however the u-boot driver rockchip_usb2_phy.c
does. The bits in GRF_UOC0_CON2 for rk3066a/rk3188 and rk3288 for example
don't match. Remove the usb-phy fallback string for rk3066a/rk3188
to prevent possible strange side effects.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 .../devicetree/bindings/phy/rockchip-usb-phy.yaml     | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml
index f0fc8275d..499d55131 100644
--- a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.yaml
@@ -11,13 +11,10 @@ maintainers:
 
 properties:
   compatible:
-    oneOf:
-      - const: rockchip,rk3288-usb-phy
-      - items:
-          - enum:
-              - rockchip,rk3066a-usb-phy
-              - rockchip,rk3188-usb-phy
-          - const: rockchip,rk3288-usb-phy
+    enum:
+      - rockchip,rk3066a-usb-phy
+      - rockchip,rk3188-usb-phy
+      - rockchip,rk3288-usb-phy
 
   "#address-cells":
     const: 1
-- 
2.20.1



From jbx6244 at gmail.com  Sat Aug 28 04:12:18 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 13:12:18 +0200
Subject: [PATCH 2/2] ARM: dts: rockchip: remove usb-phy fallback string for
 rk3066a/rk3188
In-Reply-To: <20210828111218.10026-1-jbx6244@gmail.com>
References: <20210828111218.10026-1-jbx6244@gmail.com>
Message-ID: <20210828111218.10026-2-jbx6244@gmail.com>

With the conversion of rockchip-usb-phy.yaml a long time used fallback
string for rk3066a/rk3188 was added. The linux driver doesn't do much with
the GRF phy address range, however the u-boot driver rockchip_usb2_phy.c
does. The bits in GRF_UOC0_CON2 for rk3066a/rk3188 and rk3288 for example
don't match. Remove the usb-phy fallback string for rk3066a/rk3188
to prevent possible strange side effects.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm/boot/dts/rk3066a.dtsi | 3 +--
 arch/arm/boot/dts/rk3188.dtsi  | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
index cc701a4e0..10392e096 100644
--- a/arch/arm/boot/dts/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -681,8 +681,7 @@
 	compatible = "rockchip,rk3066-grf", "syscon", "simple-mfd";
 
 	usbphy: usbphy {
-		compatible = "rockchip,rk3066a-usb-phy",
-			     "rockchip,rk3288-usb-phy";
+		compatible = "rockchip,rk3066a-usb-phy";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index d6a946a2a..922290892 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -647,8 +647,7 @@
 	};
 
 	usbphy: usbphy {
-		compatible = "rockchip,rk3188-usb-phy",
-			     "rockchip,rk3288-usb-phy";
+		compatible = "rockchip,rk3188-usb-phy";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
-- 
2.20.1



From mnhagan88 at gmail.com  Sat Aug 28 04:26:59 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sat, 28 Aug 2021 11:26:59 +0000
Subject: [PATCH 1/5] ARM: dts: NSP: Add bcm958623hr board name to dts
Message-ID: <20210828112704.2283805-1-mnhagan88@gmail.com>

This board was added to
Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml. This patch
corrects bcm958623hr.dts by adding the board name to the compatible.

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm958623hr.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm958623hr.dts b/arch/arm/boot/dts/bcm958623hr.dts
index 80556882951f..c06871915a1c 100644
--- a/arch/arm/boot/dts/bcm958623hr.dts
+++ b/arch/arm/boot/dts/bcm958623hr.dts
@@ -37,7 +37,7 @@
 
 / {
 	model = "NorthStar Plus SVK (BCM958623HR)";
-	compatible = "brcm,bcm58623", "brcm,nsp";
+	compatible = "brcm,bcm958623hr", "brcm,bcm58623", "brcm,nsp";
 
 	chosen {
 		stdout-path = "serial0:115200n8";
-- 
2.27.0



From mnhagan88 at gmail.com  Sat Aug 28 04:27:00 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sat, 28 Aug 2021 11:27:00 +0000
Subject: [PATCH 2/5] ARM: dts: NSP: Fix mpcore, mmc node names
In-Reply-To: <20210828112704.2283805-1-mnhagan88@gmail.com>
References: <20210828112704.2283805-1-mnhagan88@gmail.com>
Message-ID: <20210828112704.2283805-2-mnhagan88@gmail.com>

This fixes the following message by appending "-bus" to mpcore node name:
mpcore at 19000000: $nodename:0: 'mpcore at 19000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'

Secondly this fixes the mmc node name. Leave the label name as is.
sdhci at 21000: $nodename:0: 'sdhci at 21000' does not match '^mmc(@.*)?$'

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm-nsp.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 745d1d9d7414..6f2ccd059e73 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -77,7 +77,7 @@ pmu {
 		interrupt-affinity = <&cpu0>, <&cpu1>;
 	};
 
-	mpcore at 19000000 {
+	mpcore-bus at 19000000 {
 		compatible = "simple-bus";
 		ranges = <0x00000000 0x19000000 0x00023000>;
 		#address-cells = <1>;
@@ -219,7 +219,7 @@ dma: dma at 20000 {
 			status = "disabled";
 		};
 
-		sdio: sdhci at 21000 {
+		sdio: mmc at 21000 {
 			compatible = "brcm,sdhci-iproc-cygnus";
 			reg = <0x21000 0x100>;
 			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.27.0



From mnhagan88 at gmail.com  Sat Aug 28 04:27:01 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sat, 28 Aug 2021 11:27:01 +0000
Subject: [PATCH 3/5] ARM: dts: NSP: Fix MDIO mux node names
In-Reply-To: <20210828112704.2283805-1-mnhagan88@gmail.com>
References: <20210828112704.2283805-1-mnhagan88@gmail.com>
Message-ID: <20210828112704.2283805-3-mnhagan88@gmail.com>

This patch fixes the following message by adding "mdio-mux" compatible:
compatible: ['mdio-mux-mmioreg'] is too short

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm-nsp.dtsi                | 2 +-
 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 6f2ccd059e73..180827500f25 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -371,7 +371,7 @@ mdio: mdio at 32000 {
 		};
 
 		mdio-mux at 32000 {
-			compatible = "mdio-mux-mmioreg";
+			compatible = "mdio-mux-mmioreg", "mdio-mux";
 			reg = <0x32000 0x4>;
 			mux-mask = <0x200>;
 			#address-cells = <1>;
diff --git a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
index 8860f2fefc63..57d0c5eb9749 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
@@ -72,7 +72,7 @@ led-5 {
 	};
 
 	mdio-mii-mux {
-		compatible = "mdio-mux-mmioreg";
+		compatible = "mdio-mux-mmioreg", "mdio-mux";
 		reg = <0x1803f1c0 0x4>;
 		mux-mask = <0x2000>;
 		mdio-parent-bus = <&mdio_ext>;
-- 
2.27.0



From mnhagan88 at gmail.com  Sat Aug 28 04:27:02 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sat, 28 Aug 2021 11:27:02 +0000
Subject: [PATCH 4/5] ARM: dts: NSP: Fix MX64/MX65 eeprom node name
In-Reply-To: <20210828112704.2283805-1-mnhagan88@gmail.com>
References: <20210828112704.2283805-1-mnhagan88@gmail.com>
Message-ID: <20210828112704.2283805-4-mnhagan88@gmail.com>

This fixes the following issue by renaming the node appropriately:
at24 at 50: $nodename:0: 'at24 at 50' does not match '^eeprom@[0-9a-f]{1,2}$'

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
index bcdd38954f1d..6519b7c61af1 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
@@ -48,7 +48,7 @@ &ehci0 {
 &i2c0 {
 	status = "okay";
 
-	at24 at 50 {
+	eeprom at 50 {
 		compatible = "atmel,24c64";
 		reg = <0x50>;
 		pagesize = <32>;
-- 
2.27.0



From mnhagan88 at gmail.com  Sat Aug 28 04:27:03 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sat, 28 Aug 2021 11:27:03 +0000
Subject: [PATCH 5/5] ARM: dts: NSP: Fix MX65 MDIO mux warnings
In-Reply-To: <20210828112704.2283805-1-mnhagan88@gmail.com>
References: <20210828112704.2283805-1-mnhagan88@gmail.com>
Message-ID: <20210828112704.2283805-5-mnhagan88@gmail.com>

Firstly this fixes the following message:
mdio-mii-mux: $nodename:0: 'mdio-mii-mux' does not match '^mdio-mux[\\-@]?'

Secondly, move the mdio-mux to within the axi node and add the unit
address. This requires exposing the axi node via a label in bcm-nsp.dtsi.
This fixes the following warning:
Warning (unit_address_vs_reg): /mdio-mii-mux: node has a reg or ranges property, but no unit name

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm-nsp.dtsi                | 2 +-
 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 6 ++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 180827500f25..1c08daa18858 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -166,7 +166,7 @@ periph_clk: periph_clk {
 		};
 	};
 
-	axi at 18000000 {
+	axi: axi at 18000000 {
 		compatible = "simple-bus";
 		ranges = <0x00000000 0x18000000 0x0011c40c>;
 		#address-cells = <1>;
diff --git a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
index 57d0c5eb9749..102acd85fab2 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
@@ -70,10 +70,12 @@ led-5 {
 			gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
 		};
 	};
+};
 
-	mdio-mii-mux {
+&axi {
+	mdio-mux at 3f1c0 {
 		compatible = "mdio-mux-mmioreg", "mdio-mux";
-		reg = <0x1803f1c0 0x4>;
+		reg = <0x3f1c0 0x4>;
 		mux-mask = <0x2000>;
 		mdio-parent-bus = <&mdio_ext>;
 		#address-cells = <1>;
-- 
2.27.0



From jbx6244 at gmail.com  Sat Aug 28 04:42:40 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 13:42:40 +0200
Subject: [PATCH] ARM: dts: rockchip: change rv1108 gmac nodename
Message-ID: <20210828114240.12231-1-jbx6244@gmail.com>

The rv1108 gmac node is checked with rockchip-dwmac.yaml,
snps,dwmac.yaml and ethernet-controller.yaml.
The nodename should have a pattern: "^ethernet(@.*)?$",
so change to nodename.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 arch/arm/boot/dts/rv1108.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi
index 140434384..668fb1513 100644
--- a/arch/arm/boot/dts/rv1108.dtsi
+++ b/arch/arm/boot/dts/rv1108.dtsi
@@ -557,7 +557,7 @@
 		status = "disabled";
 	};
 
-	gmac: eth at 30200000 {
+	gmac: ethernet at 30200000 {
 		compatible = "rockchip,rv1108-gmac";
 		reg = <0x30200000 0x10000>;
 		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.20.1



From jbx6244 at gmail.com  Sat Aug 28 05:10:07 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 28 Aug 2021 14:10:07 +0200
Subject: [PATCH] dt-bindings: gpio: add gpio-line-names to rockchip,
 gpio-bank.yaml
Message-ID: <20210828121007.14865-1-jbx6244@gmail.com>

Some people and companies may want to add more description
to there gpio pins. Add a gpio-line-names property to the
rockchip,gpio-bank.yaml file to reduce the notifications
from the existing mainline DT.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---
 Documentation/devicetree/bindings/gpio/rockchip,gpio-bank.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/gpio/rockchip,gpio-bank.yaml b/Documentation/devicetree/bindings/gpio/rockchip,gpio-bank.yaml
index 0d62c28fb..d4e42c2b9 100644
--- a/Documentation/devicetree/bindings/gpio/rockchip,gpio-bank.yaml
+++ b/Documentation/devicetree/bindings/gpio/rockchip,gpio-bank.yaml
@@ -29,6 +29,8 @@ properties:
 
   gpio-controller: true
 
+  gpio-line-names: true
+
   "#gpio-cells":
     const: 2
 
-- 
2.20.1



From frattaroli.nicolas at gmail.com  Sat Aug 28 07:02:00 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Sat, 28 Aug 2021 16:02:00 +0200
Subject: [PATCH v3 0/4] Rockchip I2S/TDM controller
Message-ID: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>

Hello,

this is version 3 of the I2S/TDM driver patchset. A big thanks
to everyone who has provided their valuable feedback so far.

I've decided to omit the original cover letter for this version,
as it got quite long and had some things that are outdated or
weren't the case as I've discovered from better understanding
the driver code.

I've decided not to remove the synced reset code. The udelay
matter has been settled, and it is code that most likely works,
even if I cannot test it right now. The implementation of half
a reset controller is ugly, but specifying a generalised n-reset
synchronised reset is a bit more complex to do than just doing it
for 2, so I'd prefer putting that work off until later.

Changes in v3:
 driver:
 - alphabetically sort includes
 - check pm_runtime_get_sync return value, act on it
 - remove unnecessary initialisers in set_fmt
 - use udelay(15) in retry code: 10 retries * 15 = 150, so at worst
   we wait the full i2s register access delay
 - fix some weird returns to return directly
 - use __maybe_unused instead of #ifdef CONFIG_PM_SLEEP, also put
   __maybe_unused on the runtime callbacks
 - use (foo) instead of foo in header macros for precedence reasons
 - when using mclk-calibrate, also turn off/on those clocks during
   suspend and resume operations
 - remove mclk_tx and mclk_rx reenablement code in remove
 - move hclk enablement further down the probe, and disable it
   on probe failure
 - make reset controls mandatory, since the bindings state this too
 - use _exclusive for getting the reset controls
 - change reset assert/deassert delays to both be 10 usec
   (thank you Sugar Zhang!)
 - properly prepare and enable all mclks in probe, especially before
   calling clk_get_rate on them
 - if registering PCM fails, also use the cleanup error path instead of
   returning directly
 - bring back playback and capture only but in the way Sugar Zhang
   suggested it: set those modes depending on dma-names
 - rework clock enablement in general. Probe now always enables these,
   instead of relying on the pm resume thing
 - add myself to MAINTAINERS for this driver
 dt bindings:
 - fix a description still mentioning clk-trcm in the schema
 - document rockchip,io-multiplex, a property that describes the
   hardware as having multiplexed I2S GPIOs so direction needs to
   be changed dynamically
 - document rockchip,mclk-calibrate, which allows specifying
   different clocks for the two sample rate bases and switch between
   them as needed
 - dma-names now doesn't have a set order and items can be absent to
   indicate that the controller doesn't support this mode
 - add myself to MAINTAINERS for these bindings

Changes in v2:
 - remove ad-hoc writeq and needless (and broken) optimisation in
   reset assert/deassert. This wouldn't have worked on Big Endian,
   and would've been pointless on any other platform, as the
   overhead for saving one write was comparatively big
 - fix various checkpatch issues
 - get rid of leftover clk-trcm in schema
 - set status = "okay" in example in schema instead of "disabled"
 - change dma-names so rx is first, adjust device trees as necessary
 - properly reference uint32-array for rx-route and tx-route
   instead of uint32
 - replace trcm-sync with two boolean properties, adjust DT changes
   accordingly and also get rid of the header file
 - get rid of rockchip,no-dmaengine. This was only needed for
   some downstream driver and shouldn't be in the DT
 - get rid of rockchip,capture-only/playback-only. Rationale being
   that I have no way to test whether they're needed, and
   unconditionally setting channels_min to 0 breaks everything
 - change hclk description in "clocks"

Nicolas Frattaroli (4):
  ASoC: rockchip: add support for i2s-tdm controller
  dt-bindings: sound: add rockchip i2s-tdm binding
  arm64: dts: rockchip: add i2s1 on rk356x
  arm64: dts: rockchip: add analog audio on Quartz64

 .../bindings/sound/rockchip,i2s-tdm.yaml      |  218 ++
 MAINTAINERS                                   |    7 +
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   |   35 +-
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |   26 +
 sound/soc/rockchip/Kconfig                    |   11 +
 sound/soc/rockchip/Makefile                   |    2 +
 sound/soc/rockchip/rockchip_i2s_tdm.c         | 1845 +++++++++++++++++
 sound/soc/rockchip/rockchip_i2s_tdm.h         |  398 ++++
 8 files changed, 2541 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.c
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.h

-- 
2.33.0



From frattaroli.nicolas at gmail.com  Sat Aug 28 07:02:01 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Sat, 28 Aug 2021 16:02:01 +0200
Subject: [PATCH v3 1/4] ASoC: rockchip: add support for i2s-tdm controller
In-Reply-To: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
References: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210828140205.21973-2-frattaroli.nicolas@gmail.com>

This commit adds support for the rockchip i2s-tdm controller,
which enables audio output on the following rockchip SoCs:
- px30
- rk1808
- rk3308
- rk3566
- rk3568
- rv1126

This is a cleaned up version of the downstream vendor kernel's
driver. It can be enabled through the SND_SOC_ROCKCHIP_I2S_TDM
configuration option.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 MAINTAINERS                           |    6 +
 sound/soc/rockchip/Kconfig            |   11 +
 sound/soc/rockchip/Makefile           |    2 +
 sound/soc/rockchip/rockchip_i2s_tdm.c | 1845 +++++++++++++++++++++++++
 sound/soc/rockchip/rockchip_i2s_tdm.h |  398 ++++++
 5 files changed, 2262 insertions(+)
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.c
 create mode 100644 sound/soc/rockchip/rockchip_i2s_tdm.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 3f1843204567..5d459d42672c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16049,6 +16049,12 @@ F:	Documentation/ABI/*/sysfs-driver-hid-roccat*
 F:	drivers/hid/hid-roccat*
 F:	include/linux/hid-roccat*
 
+ROCKCHIP I2S TDM DRIVER
+M:	Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
+L:	linux-rockchip at lists.infradead.org
+S:	Maintained
+F:	sound/soc/rockchip/rockchip_i2s_tdm.*
+
 ROCKCHIP ISP V1 DRIVER
 M:	Helen Koike <helen.koike at collabora.com>
 M:	Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index 053097b73e28..42f76bc0fb02 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -16,6 +16,17 @@ config SND_SOC_ROCKCHIP_I2S
 	  Rockchip I2S device. The device supports upto maximum of
 	  8 channels each for play and record.
 
+config SND_SOC_ROCKCHIP_I2S_TDM
+	tristate "Rockchip I2S/TDM Device Driver"
+	depends on HAVE_CLK && SND_SOC_ROCKCHIP
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	help
+	  Say Y or M if you want to add support for the I2S/TDM driver for
+	  Rockchip I2S/TDM devices, found in Rockchip SoCs. These devices
+	  interface between the AHB bus and the I2S bus, and support up to a
+	  maximum of 8 channels each for playback and recording.
+
+
 config SND_SOC_ROCKCHIP_PDM
 	tristate "Rockchip PDM Controller Driver"
 	depends on HAVE_CLK && SND_SOC_ROCKCHIP
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 65e814d46006..b10f5e7b136d 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -1,11 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0
 # ROCKCHIP Platform Support
 snd-soc-rockchip-i2s-objs := rockchip_i2s.o
+snd-soc-rockchip-i2s-tdm-objs := rockchip_i2s_tdm.o
 snd-soc-rockchip-pcm-objs := rockchip_pcm.o
 snd-soc-rockchip-pdm-objs := rockchip_pdm.o
 snd-soc-rockchip-spdif-objs := rockchip_spdif.o
 
 obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o snd-soc-rockchip-pcm.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S_TDM) += snd-soc-rockchip-i2s-tdm.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_PDM) += snd-soc-rockchip-pdm.o
 obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
 
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
new file mode 100644
index 000000000000..f31a987feecf
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
@@ -0,0 +1,1845 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
+ *
+ * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
+ * Author: Sugar Zhang <sugar.zhang at rock-chips.com>
+ * Author: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/pcm_params.h>
+
+#include "rockchip_i2s_tdm.h"
+
+#define DRV_NAME "rockchip-i2s-tdm"
+
+#define DEFAULT_MCLK_FS				256
+#define CH_GRP_MAX				4  /* The max channel 8 / 2 */
+#define MULTIPLEX_CH_MAX			10
+#define CLK_PPM_MIN				(-1000)
+#define CLK_PPM_MAX				(1000)
+
+#define TRCM_TXRX 0
+#define TRCM_TX 1
+#define TRCM_RX 2
+
+struct txrx_config {
+	u32 addr;
+	u32 reg;
+	u32 txonly;
+	u32 rxonly;
+};
+
+struct rk_i2s_soc_data {
+	u32 softrst_offset;
+	u32 grf_reg_offset;
+	u32 grf_shift;
+	int config_count;
+	const struct txrx_config *configs;
+	int (*init)(struct device *dev, u32 addr);
+};
+
+struct rk_i2s_tdm_dev {
+	struct device *dev;
+	struct clk *hclk;
+	struct clk *mclk_tx;
+	struct clk *mclk_rx;
+	/* The mclk_tx_src is parent of mclk_tx */
+	struct clk *mclk_tx_src;
+	/* The mclk_rx_src is parent of mclk_rx */
+	struct clk *mclk_rx_src;
+	/*
+	 * The mclk_root0 and mclk_root1 are root parent and supplies for
+	 * the different FS.
+	 *
+	 * e.g:
+	 * mclk_root0 is VPLL0, used for FS=48000Hz
+	 * mclk_root1 is VPLL1, used for FS=44100Hz
+	 */
+	struct clk *mclk_root0;
+	struct clk *mclk_root1;
+	struct regmap *regmap;
+	struct regmap *grf;
+	struct snd_dmaengine_dai_dma_data capture_dma_data;
+	struct snd_dmaengine_dai_dma_data playback_dma_data;
+	struct reset_control *tx_reset;
+	struct reset_control *rx_reset;
+	struct rk_i2s_soc_data *soc_data;
+	void __iomem *cru_base;
+	bool is_master_mode;
+	bool io_multiplex;
+	bool mclk_calibrate;
+	bool tdm_mode;
+	bool tdm_fsync_half_frame;
+	unsigned int mclk_rx_freq;
+	unsigned int mclk_tx_freq;
+	unsigned int mclk_root0_freq;
+	unsigned int mclk_root1_freq;
+	unsigned int mclk_root0_initial_freq;
+	unsigned int mclk_root1_initial_freq;
+	unsigned int frame_width;
+	unsigned int clk_trcm;
+	unsigned int i2s_sdis[CH_GRP_MAX];
+	unsigned int i2s_sdos[CH_GRP_MAX];
+	int clk_ppm;
+	int tx_reset_id;
+	int rx_reset_id;
+	atomic_t refcount;
+	spinlock_t lock; /* xfer lock */
+	bool has_playback;
+	bool has_capture;
+};
+
+static int to_ch_num(unsigned int val)
+{
+	switch (val) {
+	case I2S_CHN_4:
+		return 4;
+	case I2S_CHN_6:
+		return 6;
+	case I2S_CHN_8:
+		return 8;
+	default:
+		return 2;
+	}
+}
+
+static void i2s_tdm_disable_unprepare_mclk(struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	if (!IS_ERR(i2s_tdm->mclk_tx))
+		clk_disable_unprepare(i2s_tdm->mclk_tx);
+	if (!IS_ERR(i2s_tdm->mclk_rx))
+		clk_disable_unprepare(i2s_tdm->mclk_rx);
+	if (i2s_tdm->mclk_calibrate) {
+		if (!IS_ERR(i2s_tdm->mclk_tx_src))
+			clk_disable_unprepare(i2s_tdm->mclk_tx_src);
+		if (!IS_ERR(i2s_tdm->mclk_rx_src))
+			clk_disable_unprepare(i2s_tdm->mclk_rx_src);
+		if (!IS_ERR(i2s_tdm->mclk_root0))
+			clk_disable_unprepare(i2s_tdm->mclk_root0);
+		if (!IS_ERR(i2s_tdm->mclk_root1))
+			clk_disable_unprepare(i2s_tdm->mclk_root1);
+	}
+}
+
+/**
+ * i2s_tdm_prepare_enable_mclk - prepare to enable all mclks, disable them on
+ *				 failure.
+ * @i2s_tdm: rk_i2s_tdm_dev struct
+ *
+ * This function attempts to enable all mclk clocks, but cleans up after
+ * itself on failure. Guarantees to balance its calls.
+ *
+ * Returns success (0) or negative errno.
+ */
+static int i2s_tdm_prepare_enable_mclk(struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int ret = 0;
+
+	if (!IS_ERR(i2s_tdm->mclk_tx)) {
+		ret = clk_prepare_enable(i2s_tdm->mclk_tx);
+		if (ret)
+			goto err_mclk_tx;
+	}
+	if (!IS_ERR(i2s_tdm->mclk_rx)) {
+		ret = clk_prepare_enable(i2s_tdm->mclk_rx);
+		if (ret)
+			goto err_mclk_rx;
+	}
+	if (i2s_tdm->mclk_calibrate) {
+		if (!IS_ERR(i2s_tdm->mclk_tx_src)) {
+			ret = clk_prepare_enable(i2s_tdm->mclk_tx_src);
+			if (ret)
+				goto err_mclk_rx;
+		}
+		if (!IS_ERR(i2s_tdm->mclk_rx_src)) {
+			ret = clk_prepare_enable(i2s_tdm->mclk_rx_src);
+			if (ret)
+				goto err_mclk_rx_src;
+		}
+		if (!IS_ERR(i2s_tdm->mclk_root0)) {
+			ret = clk_prepare_enable(i2s_tdm->mclk_root0);
+			if (ret)
+				goto err_mclk_root0;
+		}
+		if (!IS_ERR(i2s_tdm->mclk_root1)) {
+			ret = clk_prepare_enable(i2s_tdm->mclk_root1);
+			if (ret)
+				goto err_mclk_root1;
+		}
+	}
+
+	return 0;
+
+err_mclk_root1:
+	clk_disable_unprepare(i2s_tdm->mclk_root0);
+err_mclk_root0:
+	clk_disable_unprepare(i2s_tdm->mclk_rx_src);
+err_mclk_rx_src:
+	clk_disable_unprepare(i2s_tdm->mclk_tx_src);
+err_mclk_rx:
+	clk_disable_unprepare(i2s_tdm->mclk_tx);
+err_mclk_tx:
+	return ret;
+}
+
+static int __maybe_unused i2s_tdm_runtime_suspend(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+
+	regcache_cache_only(i2s_tdm->regmap, true);
+	i2s_tdm_disable_unprepare_mclk(i2s_tdm);
+
+	if (!IS_ERR(i2s_tdm->hclk))
+		clk_disable_unprepare(i2s_tdm->hclk);
+
+	return 0;
+}
+
+static int __maybe_unused i2s_tdm_runtime_resume(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	int ret;
+
+	if (!IS_ERR(i2s_tdm->hclk)) {
+		ret = clk_prepare_enable(i2s_tdm->hclk);
+		if (ret)
+			goto err_hclk;
+	}
+
+	ret = i2s_tdm_prepare_enable_mclk(i2s_tdm);
+	if (ret)
+		goto err_mclk;
+
+	regcache_cache_only(i2s_tdm->regmap, false);
+	regcache_mark_dirty(i2s_tdm->regmap);
+
+	ret = regcache_sync(i2s_tdm->regmap);
+	if (ret)
+		goto err_regcache;
+
+	return 0;
+
+err_regcache:
+	i2s_tdm_disable_unprepare_mclk(i2s_tdm);
+err_mclk:
+	if (!IS_ERR(i2s_tdm->hclk))
+		clk_disable_unprepare(i2s_tdm->hclk);
+err_hclk:
+	return ret;
+}
+
+static inline struct rk_i2s_tdm_dev *to_info(struct snd_soc_dai *dai)
+{
+	return snd_soc_dai_get_drvdata(dai);
+}
+
+static void rockchip_snd_xfer_reset_assert(struct rk_i2s_tdm_dev *i2s_tdm,
+					   int tx_bank, int tx_offset,
+					   int rx_bank, int rx_offset)
+{
+	void __iomem *cru_reset;
+	unsigned long flags;
+
+	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
+
+	if (tx_bank == rx_bank) {
+		writel(BIT(tx_offset) | BIT(rx_offset) |
+		       (BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+	} else {
+		local_irq_save(flags);
+		writel(BIT(tx_offset) | (BIT(tx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+		writel(BIT(rx_offset) | (BIT(rx_offset) << 16),
+		       cru_reset + (rx_bank * 4));
+		local_irq_restore(flags);
+	}
+}
+
+static void rockchip_snd_xfer_reset_deassert(struct rk_i2s_tdm_dev *i2s_tdm,
+					     int tx_bank, int tx_offset,
+					     int rx_bank, int rx_offset)
+{
+	void __iomem *cru_reset;
+	unsigned long flags;
+
+	cru_reset = i2s_tdm->cru_base + i2s_tdm->soc_data->softrst_offset;
+
+	if (tx_bank == rx_bank) {
+		writel((BIT(tx_offset) << 16) | (BIT(rx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+	} else {
+		local_irq_save(flags);
+		writel((BIT(tx_offset) << 16),
+		       cru_reset + (tx_bank * 4));
+		writel((BIT(rx_offset) << 16),
+		       cru_reset + (rx_bank * 4));
+		local_irq_restore(flags);
+	}
+}
+
+/*
+ * Makes sure that both tx and rx are reset at the same time to sync lrck
+ * when clk_trcm > 0.
+ */
+static void rockchip_snd_xfer_sync_reset(struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int tx_id, rx_id;
+	int tx_bank, rx_bank, tx_offset, rx_offset;
+
+	if (!i2s_tdm->cru_base || !i2s_tdm->soc_data)
+		return;
+
+	tx_id = i2s_tdm->tx_reset_id;
+	rx_id = i2s_tdm->rx_reset_id;
+	if (tx_id < 0 || rx_id < 0)
+		return;
+
+	tx_bank = tx_id / 16;
+	tx_offset = tx_id % 16;
+	rx_bank = rx_id / 16;
+	rx_offset = rx_id % 16;
+	dev_dbg(i2s_tdm->dev,
+		"tx_bank: %d, rx_bank: %d, tx_offset: %d, rx_offset: %d\n",
+		tx_bank, rx_bank, tx_offset, rx_offset);
+
+	rockchip_snd_xfer_reset_assert(i2s_tdm, tx_bank, tx_offset,
+				       rx_bank, rx_offset);
+
+	udelay(10);
+
+	rockchip_snd_xfer_reset_deassert(i2s_tdm, tx_bank, tx_offset,
+					 rx_bank, rx_offset);
+	udelay(10);
+}
+
+static void rockchip_snd_reset(struct reset_control *rc)
+{
+	reset_control_assert(rc);
+	udelay(10);
+	reset_control_deassert(rc);
+	udelay(10);
+}
+
+static void rockchip_snd_xfer_clear(struct rk_i2s_tdm_dev *i2s_tdm,
+				    unsigned int clr)
+{
+	unsigned int xfer_mask;
+	unsigned int xfer_val;
+	unsigned int val;
+	int retry = 10;
+	bool tx = clr & I2S_CLR_TXC;
+	bool rx = clr & I2S_CLR_RXC;
+
+	if (!(rx || tx))
+		return;
+
+	xfer_mask = (tx ? I2S_XFER_TXS_START : 0) |
+		    (rx ? I2S_XFER_RXS_START : 0);
+	xfer_val = (tx ? I2S_XFER_TXS_STOP : 0) |
+		   (rx ? I2S_XFER_RXS_STOP : 0);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_XFER, xfer_mask, xfer_val);
+	udelay(150);
+	regmap_update_bits(i2s_tdm->regmap, I2S_CLR, clr, clr);
+
+	regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
+	/* Wait on the clear operation to finish */
+	while (val) {
+		udelay(15);
+		regmap_read(i2s_tdm->regmap, I2S_CLR, &val);
+		retry--;
+		if (!retry) {
+			dev_warn(i2s_tdm->dev, "clear failed, reset %s%s\n",
+				 tx ? "tx" : "", rx ? "rx" : "");
+			if (rx && tx)
+				rockchip_snd_xfer_sync_reset(i2s_tdm);
+			else if (tx)
+				rockchip_snd_reset(i2s_tdm->tx_reset);
+			else if (rx)
+				rockchip_snd_reset(i2s_tdm->rx_reset);
+			break;
+		}
+	}
+}
+
+/* only used when clk_trcm > 0 */
+static void rockchip_snd_txrxctrl(struct snd_pcm_substream *substream,
+				  struct snd_soc_dai *dai, int on)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	spin_lock(&i2s_tdm->lock);
+	if (on) {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_TDE_ENABLE,
+					   I2S_DMACR_TDE_ENABLE);
+		else
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_RDE_ENABLE,
+					   I2S_DMACR_RDE_ENABLE);
+
+		if (atomic_inc_return(&i2s_tdm->refcount) == 1) {
+			rockchip_snd_xfer_sync_reset(i2s_tdm);
+			regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+					   I2S_XFER_TXS_START |
+					   I2S_XFER_RXS_START,
+					   I2S_XFER_TXS_START |
+					   I2S_XFER_RXS_START);
+		}
+	} else {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_TDE_ENABLE,
+					   I2S_DMACR_TDE_DISABLE);
+		else
+			regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+					   I2S_DMACR_RDE_ENABLE,
+					   I2S_DMACR_RDE_DISABLE);
+
+		if (atomic_dec_and_test(&i2s_tdm->refcount)) {
+			rockchip_snd_xfer_clear(i2s_tdm,
+						I2S_CLR_TXC | I2S_CLR_RXC);
+		}
+	}
+	spin_unlock(&i2s_tdm->lock);
+}
+
+static void rockchip_snd_txctrl(struct rk_i2s_tdm_dev *i2s_tdm, int on)
+{
+	if (on) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
+
+		regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+				   I2S_XFER_TXS_START,
+				   I2S_XFER_TXS_START);
+	} else {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
+
+		rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_TXC);
+	}
+}
+
+static void rockchip_snd_rxctrl(struct rk_i2s_tdm_dev *i2s_tdm, int on)
+{
+	if (on) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
+
+		regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+				   I2S_XFER_RXS_START,
+				   I2S_XFER_RXS_START);
+	} else {
+		rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_RXC);
+	}
+}
+
+static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai,
+				    unsigned int fmt)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
+	unsigned int mask, val, tdm_val, txcr_val, rxcr_val;
+	int ret;
+	bool is_tdm = i2s_tdm->tdm_mode;
+
+	ret = pm_runtime_get_sync(cpu_dai->dev);
+	if (ret < 0 && ret != -EACCES) {
+		pm_runtime_put_noidle(cpu_dai->dev);
+		return ret;
+	}
+
+	mask = I2S_CKR_MSS_MASK;
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		val = I2S_CKR_MSS_MASTER;
+		i2s_tdm->is_master_mode = true;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		val = I2S_CKR_MSS_SLAVE;
+		i2s_tdm->is_master_mode = false;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val);
+
+	mask = I2S_CKR_CKP_MASK | I2S_CKR_TLP_MASK | I2S_CKR_RLP_MASK;
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		val = I2S_CKR_CKP_NORMAL |
+		      I2S_CKR_TLP_NORMAL |
+		      I2S_CKR_RLP_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		val = I2S_CKR_CKP_NORMAL |
+		      I2S_CKR_TLP_INVERTED |
+		      I2S_CKR_RLP_INVERTED;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		val = I2S_CKR_CKP_INVERTED |
+		      I2S_CKR_TLP_NORMAL |
+		      I2S_CKR_RLP_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		val = I2S_CKR_CKP_INVERTED |
+		      I2S_CKR_TLP_INVERTED |
+		      I2S_CKR_RLP_INVERTED;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val);
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_RIGHT_J:
+		txcr_val = I2S_TXCR_IBM_RSJM;
+		rxcr_val = I2S_RXCR_IBM_RSJM;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		txcr_val = I2S_TXCR_IBM_LSJM;
+		rxcr_val = I2S_RXCR_IBM_LSJM;
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		txcr_val = I2S_TXCR_IBM_NORMAL;
+		rxcr_val = I2S_RXCR_IBM_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */
+		txcr_val = I2S_TXCR_TFS_PCM;
+		rxcr_val = I2S_RXCR_TFS_PCM;
+		break;
+	case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */
+		txcr_val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);
+		rxcr_val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_pm_put;
+	}
+
+	mask = I2S_TXCR_IBM_MASK | I2S_TXCR_TFS_MASK | I2S_TXCR_PBM_MASK;
+	regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, txcr_val);
+
+	mask = I2S_RXCR_IBM_MASK | I2S_RXCR_TFS_MASK | I2S_RXCR_PBM_MASK;
+	regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, rxcr_val);
+
+	if (is_tdm) {
+		switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+		case SND_SOC_DAIFMT_RIGHT_J:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(2);
+			break;
+		case SND_SOC_DAIFMT_LEFT_J:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(1);
+			break;
+		case SND_SOC_DAIFMT_I2S:
+			val = I2S_TXCR_TFS_TDM_I2S;
+			tdm_val = TDM_SHIFT_CTRL(0);
+			break;
+		case SND_SOC_DAIFMT_DSP_A:
+			val = I2S_TXCR_TFS_TDM_PCM;
+			tdm_val = TDM_SHIFT_CTRL(0);
+			break;
+		case SND_SOC_DAIFMT_DSP_B:
+			val = I2S_TXCR_TFS_TDM_PCM;
+			tdm_val = TDM_SHIFT_CTRL(2);
+			break;
+		default:
+			ret = -EINVAL;
+			goto err_pm_put;
+		}
+
+		tdm_val |= TDM_FSYNC_WIDTH_SEL1(1);
+		if (i2s_tdm->tdm_fsync_half_frame)
+			tdm_val |= TDM_FSYNC_WIDTH_HALF_FRAME;
+		else
+			tdm_val |= TDM_FSYNC_WIDTH_ONE_FRAME;
+
+		mask = I2S_TXCR_TFS_MASK;
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, val);
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, val);
+
+		mask = TDM_FSYNC_WIDTH_SEL1_MSK | TDM_FSYNC_WIDTH_SEL0_MSK |
+		       TDM_SHIFT_CTRL_MSK;
+		regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR,
+				   mask, tdm_val);
+		regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR,
+				   mask, tdm_val);
+	}
+
+err_pm_put:
+	pm_runtime_put(cpu_dai->dev);
+
+	return ret;
+}
+
+static void rockchip_i2s_tdm_xfer_pause(struct snd_pcm_substream *substream,
+					struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int stream;
+
+	stream = SNDRV_PCM_STREAM_LAST - substream->stream;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE,
+				   I2S_DMACR_TDE_DISABLE);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE,
+				   I2S_DMACR_RDE_DISABLE);
+
+	rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_TXC | I2S_CLR_RXC);
+}
+
+static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream *substream,
+					 struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	int stream;
+
+	stream = SNDRV_PCM_STREAM_LAST - substream->stream;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_TDE_ENABLE,
+				   I2S_DMACR_TDE_ENABLE);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_DMACR,
+				   I2S_DMACR_RDE_ENABLE,
+				   I2S_DMACR_RDE_ENABLE);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
+			   I2S_XFER_TXS_START |
+			   I2S_XFER_RXS_START,
+			   I2S_XFER_TXS_START |
+			   I2S_XFER_RXS_START);
+}
+
+static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm,
+					 struct clk *clk, unsigned long rate,
+					 int ppm)
+{
+	unsigned long rate_target;
+	int delta, ret;
+
+	if (ppm == i2s_tdm->clk_ppm)
+		return 0;
+
+	delta = (ppm < 0) ? -1 : 1;
+	delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000,
+				1000000);
+
+	rate_target = rate + delta;
+
+	if (!rate_target)
+		return -EINVAL;
+
+	ret = clk_set_rate(clk, rate_target);
+	if (ret)
+		return ret;
+
+	i2s_tdm->clk_ppm = ppm;
+
+	return ret;
+}
+
+static int rockchip_i2s_tdm_calibrate_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
+					   struct snd_pcm_substream *substream,
+					   unsigned int lrck_freq)
+{
+	struct clk *mclk_root;
+	struct clk *mclk_parent;
+	unsigned int mclk_root_freq;
+	unsigned int mclk_root_initial_freq;
+	unsigned int mclk_parent_freq;
+	unsigned int div, delta;
+	u64 ppm;
+	int ret;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		mclk_parent = i2s_tdm->mclk_tx_src;
+	else
+		mclk_parent = i2s_tdm->mclk_rx_src;
+
+	switch (lrck_freq) {
+	case 8000:
+	case 16000:
+	case 24000:
+	case 32000:
+	case 48000:
+	case 64000:
+	case 96000:
+	case 192000:
+		mclk_root = i2s_tdm->mclk_root0;
+		mclk_root_freq = i2s_tdm->mclk_root0_freq;
+		mclk_root_initial_freq = i2s_tdm->mclk_root0_initial_freq;
+		mclk_parent_freq = DEFAULT_MCLK_FS * 192000;
+		break;
+	case 11025:
+	case 22050:
+	case 44100:
+	case 88200:
+	case 176400:
+		mclk_root = i2s_tdm->mclk_root1;
+		mclk_root_freq = i2s_tdm->mclk_root1_freq;
+		mclk_root_initial_freq = i2s_tdm->mclk_root1_initial_freq;
+		mclk_parent_freq = DEFAULT_MCLK_FS * 176400;
+		break;
+	default:
+		dev_err(i2s_tdm->dev, "Invalid LRCK freq: %u Hz\n",
+			lrck_freq);
+		return -EINVAL;
+	}
+
+	ret = clk_set_parent(mclk_parent, mclk_root);
+	if (ret)
+		return ret;
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, mclk_root,
+					    mclk_root_freq, 0);
+	if (ret)
+		return ret;
+
+	delta = abs(mclk_root_freq % mclk_parent_freq - mclk_parent_freq);
+	ppm = div64_u64((uint64_t)delta * 1000000, (uint64_t)mclk_root_freq);
+
+	if (ppm) {
+		div = DIV_ROUND_CLOSEST(mclk_root_initial_freq, mclk_parent_freq);
+		if (!div)
+			return -EINVAL;
+
+		mclk_root_freq = mclk_parent_freq * round_up(div, 2);
+
+		ret = clk_set_rate(mclk_root, mclk_root_freq);
+		if (ret)
+			return ret;
+
+		i2s_tdm->mclk_root0_freq = clk_get_rate(i2s_tdm->mclk_root0);
+		i2s_tdm->mclk_root1_freq = clk_get_rate(i2s_tdm->mclk_root1);
+	}
+
+	return clk_set_rate(mclk_parent, mclk_parent_freq);
+}
+
+static int rockchip_i2s_tdm_set_mclk(struct rk_i2s_tdm_dev *i2s_tdm,
+				     struct snd_pcm_substream *substream,
+				     struct clk **mclk)
+{
+	unsigned int mclk_freq;
+	int ret;
+
+	if (i2s_tdm->clk_trcm) {
+		if (i2s_tdm->mclk_tx_freq != i2s_tdm->mclk_rx_freq) {
+			dev_err(i2s_tdm->dev,
+				"clk_trcm, tx: %d and rx: %d should be same\n",
+				i2s_tdm->mclk_tx_freq,
+				i2s_tdm->mclk_rx_freq);
+			return -EINVAL;
+		}
+
+		ret = clk_set_rate(i2s_tdm->mclk_tx, i2s_tdm->mclk_tx_freq);
+		if (ret)
+			return ret;
+
+		ret = clk_set_rate(i2s_tdm->mclk_rx, i2s_tdm->mclk_rx_freq);
+		if (ret)
+			return ret;
+
+		/* mclk_rx is also ok. */
+		*mclk = i2s_tdm->mclk_tx;
+	} else {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			*mclk = i2s_tdm->mclk_tx;
+			mclk_freq = i2s_tdm->mclk_tx_freq;
+		} else {
+			*mclk = i2s_tdm->mclk_rx;
+			mclk_freq = i2s_tdm->mclk_rx_freq;
+		}
+
+		ret = clk_set_rate(*mclk, mclk_freq);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_i2s_io_multiplex(struct snd_pcm_substream *substream,
+				     struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+	int usable_chs = MULTIPLEX_CH_MAX;
+	unsigned int val = 0;
+
+	if (!i2s_tdm->io_multiplex)
+		return 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		struct snd_pcm_str *playback_str =
+			&substream->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
+
+		if (playback_str->substream_opened) {
+			regmap_read(i2s_tdm->regmap, I2S_TXCR, &val);
+			val &= I2S_TXCR_CSR_MASK;
+			usable_chs = MULTIPLEX_CH_MAX - to_ch_num(val);
+		}
+
+		regmap_read(i2s_tdm->regmap, I2S_RXCR, &val);
+		val &= I2S_RXCR_CSR_MASK;
+
+		if (to_ch_num(val) > usable_chs) {
+			dev_err(i2s_tdm->dev,
+				"Capture chs(%d) > usable chs(%d)\n",
+				to_ch_num(val), usable_chs);
+			return -EINVAL;
+		}
+
+		switch (val) {
+		case I2S_CHN_4:
+			val = I2S_IO_6CH_OUT_4CH_IN;
+			break;
+		case I2S_CHN_6:
+			val = I2S_IO_4CH_OUT_6CH_IN;
+			break;
+		case I2S_CHN_8:
+			val = I2S_IO_2CH_OUT_8CH_IN;
+			break;
+		default:
+			val = I2S_IO_8CH_OUT_2CH_IN;
+			break;
+		}
+	} else {
+		struct snd_pcm_str *capture_str =
+			&substream->pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
+
+		if (capture_str->substream_opened) {
+			regmap_read(i2s_tdm->regmap, I2S_RXCR, &val);
+			val &= I2S_RXCR_CSR_MASK;
+			usable_chs = MULTIPLEX_CH_MAX - to_ch_num(val);
+		}
+
+		regmap_read(i2s_tdm->regmap, I2S_TXCR, &val);
+		val &= I2S_TXCR_CSR_MASK;
+
+		if (to_ch_num(val) > usable_chs) {
+			dev_err(i2s_tdm->dev,
+				"Playback chs(%d) > usable chs(%d)\n",
+				to_ch_num(val), usable_chs);
+			return -EINVAL;
+		}
+
+		switch (val) {
+		case I2S_CHN_4:
+			val = I2S_IO_4CH_OUT_6CH_IN;
+			break;
+		case I2S_CHN_6:
+			val = I2S_IO_6CH_OUT_4CH_IN;
+			break;
+		case I2S_CHN_8:
+			val = I2S_IO_8CH_OUT_2CH_IN;
+			break;
+		default:
+			val = I2S_IO_2CH_OUT_8CH_IN;
+			break;
+		}
+	}
+
+	val <<= i2s_tdm->soc_data->grf_shift;
+	val |= (I2S_IO_DIRECTION_MASK << i2s_tdm->soc_data->grf_shift) << 16;
+	regmap_write(i2s_tdm->grf, i2s_tdm->soc_data->grf_reg_offset, val);
+
+	return 0;
+}
+
+static int rockchip_i2s_trcm_mode(struct snd_pcm_substream *substream,
+				  struct snd_soc_dai *dai,
+				  unsigned int div_bclk,
+				  unsigned int div_lrck,
+				  unsigned int fmt)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	if (!i2s_tdm->clk_trcm)
+		return 0;
+
+	spin_lock(&i2s_tdm->lock);
+	if (atomic_read(&i2s_tdm->refcount))
+		rockchip_i2s_tdm_xfer_pause(substream, i2s_tdm);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+			   I2S_CLKDIV_TXM_MASK | I2S_CLKDIV_RXM_MASK,
+			   I2S_CLKDIV_TXM(div_bclk) | I2S_CLKDIV_RXM(div_bclk));
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+			   I2S_CKR_TSD_MASK | I2S_CKR_RSD_MASK,
+			   I2S_CKR_TSD(div_lrck) | I2S_CKR_RSD(div_lrck));
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
+				   fmt);
+	else
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
+				   fmt);
+
+	if (atomic_read(&i2s_tdm->refcount))
+		rockchip_i2s_tdm_xfer_resume(substream, i2s_tdm);
+	spin_unlock(&i2s_tdm->lock);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *params,
+				      struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+	struct clk *mclk;
+	int ret = 0;
+	unsigned int val = 0;
+	unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64;
+
+	if (i2s_tdm->is_master_mode) {
+		if (i2s_tdm->mclk_calibrate)
+			rockchip_i2s_tdm_calibrate_mclk(i2s_tdm, substream,
+							params_rate(params));
+
+		ret = rockchip_i2s_tdm_set_mclk(i2s_tdm, substream, &mclk);
+		if (ret)
+			return ret;
+
+		mclk_rate = clk_get_rate(mclk);
+		bclk_rate = i2s_tdm->frame_width * params_rate(params);
+		if (!bclk_rate)
+			return -EINVAL;
+
+		div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
+		div_lrck = bclk_rate / params_rate(params);
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S8:
+		val |= I2S_TXCR_VDW(8);
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+		val |= I2S_TXCR_VDW(16);
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		val |= I2S_TXCR_VDW(20);
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		val |= I2S_TXCR_VDW(24);
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		val |= I2S_TXCR_VDW(32);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (params_channels(params)) {
+	case 8:
+		val |= I2S_CHN_8;
+		break;
+	case 6:
+		val |= I2S_CHN_6;
+		break;
+	case 4:
+		val |= I2S_CHN_4;
+		break;
+	case 2:
+		val |= I2S_CHN_2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (i2s_tdm->clk_trcm) {
+		rockchip_i2s_trcm_mode(substream, dai, div_bclk, div_lrck, val);
+	} else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+				   I2S_CLKDIV_TXM_MASK,
+				   I2S_CLKDIV_TXM(div_bclk));
+		regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+				   I2S_CKR_TSD_MASK,
+				   I2S_CKR_TSD(div_lrck));
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
+				   val);
+	} else {
+		regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
+				   I2S_CLKDIV_RXM_MASK,
+				   I2S_CLKDIV_RXM(div_bclk));
+		regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
+				   I2S_CKR_RSD_MASK,
+				   I2S_CKR_RSD(div_lrck));
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
+				   val);
+	}
+
+	return rockchip_i2s_io_multiplex(substream, dai);
+}
+
+static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream,
+				    int cmd, struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		if (i2s_tdm->clk_trcm)
+			rockchip_snd_txrxctrl(substream, dai, 1);
+		else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			rockchip_snd_rxctrl(i2s_tdm, 1);
+		else
+			rockchip_snd_txctrl(i2s_tdm, 1);
+		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (i2s_tdm->clk_trcm)
+			rockchip_snd_txrxctrl(substream, dai, 0);
+		else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			rockchip_snd_rxctrl(i2s_tdm, 0);
+		else
+			rockchip_snd_txctrl(i2s_tdm, 0);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream,
+				       unsigned int freq, int dir)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
+
+	/* Put set mclk rate into rockchip_i2s_tdm_set_mclk() */
+	if (i2s_tdm->clk_trcm) {
+		i2s_tdm->mclk_tx_freq = freq;
+		i2s_tdm->mclk_rx_freq = freq;
+	} else {
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			i2s_tdm->mclk_tx_freq = freq;
+		else
+			i2s_tdm->mclk_rx_freq = freq;
+	}
+
+	dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n",
+		stream ? "rx" : "tx", freq);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
+						  struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = CLK_PPM_MIN;
+	uinfo->value.integer.max = CLK_PPM_MAX;
+	uinfo->value.integer.step = 1;
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
+						 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+
+	ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm;
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
+						 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+	int ret = 0, ppm = 0;
+
+	if (ucontrol->value.integer.value[0] < CLK_PPM_MIN ||
+	    ucontrol->value.integer.value[0] > CLK_PPM_MAX)
+		return -EINVAL;
+
+	ppm = ucontrol->value.integer.value[0];
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root0,
+					    i2s_tdm->mclk_root0_freq, ppm);
+	if (ret)
+		return ret;
+
+	if (clk_is_match(i2s_tdm->mclk_root0, i2s_tdm->mclk_root1))
+		return 0;
+
+	ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root1,
+					    i2s_tdm->mclk_root1_freq, ppm);
+
+	return ret;
+}
+
+static struct snd_kcontrol_new rockchip_i2s_tdm_compensation_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+	.name = "PCM Clk Compensation In PPM",
+	.info = rockchip_i2s_tdm_clk_compensation_info,
+	.get = rockchip_i2s_tdm_clk_compensation_get,
+	.put = rockchip_i2s_tdm_clk_compensation_put,
+};
+
+static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+
+	if (i2s_tdm->has_capture)
+		dai->capture_dma_data = &i2s_tdm->capture_dma_data;
+	if (i2s_tdm->has_playback)
+		dai->playback_dma_data = &i2s_tdm->playback_dma_data;
+
+	if (i2s_tdm->mclk_calibrate)
+		snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1);
+
+	return 0;
+}
+
+static int rockchip_dai_tdm_slot(struct snd_soc_dai *dai,
+				 unsigned int tx_mask, unsigned int rx_mask,
+				 int slots, int slot_width)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
+	unsigned int mask, val;
+
+	i2s_tdm->tdm_mode = true;
+	i2s_tdm->frame_width = slots * slot_width;
+	mask = TDM_SLOT_BIT_WIDTH_MSK | TDM_FRAME_WIDTH_MSK;
+	val = TDM_SLOT_BIT_WIDTH(slot_width) |
+	      TDM_FRAME_WIDTH(slots * slot_width);
+	regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR,
+			   mask, val);
+	regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR,
+			   mask, val);
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = {
+	.hw_params = rockchip_i2s_tdm_hw_params,
+	.set_sysclk = rockchip_i2s_tdm_set_sysclk,
+	.set_fmt = rockchip_i2s_tdm_set_fmt,
+	.set_tdm_slot = rockchip_dai_tdm_slot,
+	.trigger = rockchip_i2s_tdm_trigger,
+};
+
+static const struct snd_soc_component_driver rockchip_i2s_tdm_component = {
+	.name = DRV_NAME,
+};
+
+static bool rockchip_i2s_tdm_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXCR:
+	case I2S_RXCR:
+	case I2S_CKR:
+	case I2S_DMACR:
+	case I2S_INTCR:
+	case I2S_XFER:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_TDM_TXCR:
+	case I2S_TDM_RXCR:
+	case I2S_CLKDIV:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXCR:
+	case I2S_RXCR:
+	case I2S_CKR:
+	case I2S_DMACR:
+	case I2S_INTCR:
+	case I2S_XFER:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_RXDR:
+	case I2S_TXFIFOLR:
+	case I2S_INTSR:
+	case I2S_RXFIFOLR:
+	case I2S_TDM_TXCR:
+	case I2S_TDM_RXCR:
+	case I2S_CLKDIV:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_TXFIFOLR:
+	case I2S_INTSR:
+	case I2S_CLR:
+	case I2S_TXDR:
+	case I2S_RXDR:
+	case I2S_RXFIFOLR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rockchip_i2s_tdm_precious_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case I2S_RXDR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct reg_default rockchip_i2s_tdm_reg_defaults[] = {
+	{0x00, 0x7200000f},
+	{0x04, 0x01c8000f},
+	{0x08, 0x00001f1f},
+	{0x10, 0x001f0000},
+	{0x14, 0x01f00000},
+	{0x30, 0x00003eff},
+	{0x34, 0x00003eff},
+	{0x38, 0x00000707},
+};
+
+static const struct regmap_config rockchip_i2s_tdm_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = I2S_CLKDIV,
+	.reg_defaults = rockchip_i2s_tdm_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(rockchip_i2s_tdm_reg_defaults),
+	.writeable_reg = rockchip_i2s_tdm_wr_reg,
+	.readable_reg = rockchip_i2s_tdm_rd_reg,
+	.volatile_reg = rockchip_i2s_tdm_volatile_reg,
+	.precious_reg = rockchip_i2s_tdm_precious_reg,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static int common_soc_init(struct device *dev, u32 addr)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	const struct txrx_config *configs = i2s_tdm->soc_data->configs;
+	u32 reg = 0, val = 0, trcm = i2s_tdm->clk_trcm;
+	int i;
+
+	if (trcm == TRCM_TXRX)
+		return 0;
+
+	for (i = 0; i < i2s_tdm->soc_data->config_count; i++) {
+		if (addr != configs[i].addr)
+			continue;
+		reg = configs[i].reg;
+		if (trcm == TRCM_TX)
+			val = configs[i].txonly;
+		else
+			val = configs[i].rxonly;
+
+		if (reg)
+			regmap_write(i2s_tdm->grf, reg, val);
+	}
+
+	return 0;
+}
+
+static const struct txrx_config px30_txrx_config[] = {
+	{ 0xff060000, 0x184, PX30_I2S0_CLK_TXONLY, PX30_I2S0_CLK_RXONLY },
+};
+
+static const struct txrx_config rk1808_txrx_config[] = {
+	{ 0xff7e0000, 0x190, RK1808_I2S0_CLK_TXONLY, RK1808_I2S0_CLK_RXONLY },
+};
+
+static const struct txrx_config rk3308_txrx_config[] = {
+	{ 0xff300000, 0x308, RK3308_I2S0_CLK_TXONLY, RK3308_I2S0_CLK_RXONLY },
+	{ 0xff310000, 0x308, RK3308_I2S1_CLK_TXONLY, RK3308_I2S1_CLK_RXONLY },
+};
+
+static const struct txrx_config rk3568_txrx_config[] = {
+	{ 0xfe410000, 0x504, RK3568_I2S1_CLK_TXONLY, RK3568_I2S1_CLK_RXONLY },
+	{ 0xfe410000, 0x508, RK3568_I2S1_MCLK_TX_OE, RK3568_I2S1_MCLK_RX_OE },
+	{ 0xfe420000, 0x508, RK3568_I2S2_MCLK_OE, RK3568_I2S2_MCLK_OE },
+	{ 0xfe430000, 0x504, RK3568_I2S3_CLK_TXONLY, RK3568_I2S3_CLK_RXONLY },
+	{ 0xfe430000, 0x508, RK3568_I2S3_MCLK_TXONLY, RK3568_I2S3_MCLK_RXONLY },
+	{ 0xfe430000, 0x508, RK3568_I2S3_MCLK_OE, RK3568_I2S3_MCLK_OE },
+};
+
+static const struct txrx_config rv1126_txrx_config[] = {
+	{ 0xff800000, 0x10260, RV1126_I2S0_CLK_TXONLY, RV1126_I2S0_CLK_RXONLY },
+};
+
+static struct rk_i2s_soc_data px30_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = px30_txrx_config,
+	.config_count = ARRAY_SIZE(px30_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk1808_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = rk1808_txrx_config,
+	.config_count = ARRAY_SIZE(rk1808_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk3308_i2s_soc_data = {
+	.softrst_offset = 0x0400,
+	.grf_reg_offset = 0x0308,
+	.grf_shift = 5,
+	.configs = rk3308_txrx_config,
+	.config_count = ARRAY_SIZE(rk3308_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rk3568_i2s_soc_data = {
+	.softrst_offset = 0x0400,
+	.configs = rk3568_txrx_config,
+	.config_count = ARRAY_SIZE(rk3568_txrx_config),
+	.init = common_soc_init,
+};
+
+static struct rk_i2s_soc_data rv1126_i2s_soc_data = {
+	.softrst_offset = 0x0300,
+	.configs = rv1126_txrx_config,
+	.config_count = ARRAY_SIZE(rv1126_txrx_config),
+	.init = common_soc_init,
+};
+
+static const struct of_device_id rockchip_i2s_tdm_match[] = {
+	{ .compatible = "rockchip,px30-i2s-tdm", .data = &px30_i2s_soc_data },
+	{ .compatible = "rockchip,rk1808-i2s-tdm", .data = &rk1808_i2s_soc_data },
+	{ .compatible = "rockchip,rk3308-i2s-tdm", .data = &rk3308_i2s_soc_data },
+	{ .compatible = "rockchip,rk3568-i2s-tdm", .data = &rk3568_i2s_soc_data },
+	{ .compatible = "rockchip,rv1126-i2s-tdm", .data = &rv1126_i2s_soc_data },
+	{},
+};
+
+static int of_i2s_resetid_get(struct device_node *node,
+			      const char *id)
+{
+	struct of_phandle_args args;
+	int index = 0;
+	int ret;
+
+	if (id)
+		index = of_property_match_string(node,
+						 "reset-names", id);
+	ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
+					 index, &args);
+	if (ret)
+		return ret;
+
+	return args.args[0];
+}
+
+static struct snd_soc_dai_driver i2s_tdm_dai = {
+	.probe = rockchip_i2s_tdm_dai_probe,
+	.playback = {
+		.stream_name  = "Playback",
+	},
+	.capture = {
+		.stream_name  = "Capture",
+	},
+	.ops = &rockchip_i2s_tdm_dai_ops,
+};
+
+static void rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev *i2s_tdm)
+{
+	struct property *dma_names;
+	const char *dma_name;
+	u64 formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |
+		       SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |
+		       SNDRV_PCM_FMTBIT_S32_LE);
+	struct device_node *node = i2s_tdm->dev->of_node;
+
+	of_property_for_each_string(node, "dma-names", dma_names, dma_name) {
+		if (!strcmp(dma_name, "tx"))
+			i2s_tdm->has_playback = true;
+		if (!strcmp(dma_name, "rx"))
+			i2s_tdm->has_capture = true;
+	}
+
+	if (i2s_tdm->has_playback) {
+		i2s_tdm_dai.playback.channels_min = 2;
+		i2s_tdm_dai.playback.channels_max = 8;
+		i2s_tdm_dai.playback.rates = SNDRV_PCM_RATE_8000_192000;
+		i2s_tdm_dai.playback.formats = formats;
+	}
+
+	if (i2s_tdm->has_capture) {
+		i2s_tdm_dai.capture.channels_min = 2;
+		i2s_tdm_dai.capture.channels_max = 8;
+		i2s_tdm_dai.capture.rates = SNDRV_PCM_RATE_8000_192000;
+		i2s_tdm_dai.capture.formats = formats;
+	}
+}
+
+static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev *i2s_tdm,
+				       int num,
+				       bool is_rx_path)
+{
+	unsigned int *i2s_data;
+	int i, j;
+
+	if (is_rx_path)
+		i2s_data = i2s_tdm->i2s_sdis;
+	else
+		i2s_data = i2s_tdm->i2s_sdos;
+
+	for (i = 0; i < num; i++) {
+		if (i2s_data[i] > CH_GRP_MAX - 1) {
+			dev_err(i2s_tdm->dev,
+				"%s path i2s_data[%d]: %d is overflow, max is: %d\n",
+				is_rx_path ? "RX" : "TX",
+				i, i2s_data[i], CH_GRP_MAX);
+			return -EINVAL;
+		}
+
+		for (j = 0; j < num; j++) {
+			if (i == j)
+				continue;
+
+			if (i2s_data[i] == i2s_data[j]) {
+				dev_err(i2s_tdm->dev,
+					"%s path invalid routed i2s_data: [%d]%d == [%d]%d\n",
+					is_rx_path ? "RX" : "TX",
+					i, i2s_data[i],
+					j, i2s_data[j]);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void rockchip_i2s_tdm_tx_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					    int num)
+{
+	int idx;
+
+	for (idx = 0; idx < num; idx++) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_TXCR,
+				   I2S_TXCR_PATH_MASK(idx),
+				   I2S_TXCR_PATH(idx, i2s_tdm->i2s_sdos[idx]));
+	}
+}
+
+static void rockchip_i2s_tdm_rx_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					    int num)
+{
+	int idx;
+
+	for (idx = 0; idx < num; idx++) {
+		regmap_update_bits(i2s_tdm->regmap, I2S_RXCR,
+				   I2S_RXCR_PATH_MASK(idx),
+				   I2S_RXCR_PATH(idx, i2s_tdm->i2s_sdis[idx]));
+	}
+}
+
+static void rockchip_i2s_tdm_path_config(struct rk_i2s_tdm_dev *i2s_tdm,
+					 int num, bool is_rx_path)
+{
+	if (is_rx_path)
+		rockchip_i2s_tdm_rx_path_config(i2s_tdm, num);
+	else
+		rockchip_i2s_tdm_tx_path_config(i2s_tdm, num);
+}
+
+static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					 struct device_node *np,
+					 bool is_rx_path)
+{
+	char *i2s_tx_path_prop = "rockchip,i2s-tx-route";
+	char *i2s_rx_path_prop = "rockchip,i2s-rx-route";
+	char *i2s_path_prop;
+	unsigned int *i2s_data;
+	int num, ret = 0;
+
+	if (is_rx_path) {
+		i2s_path_prop = i2s_rx_path_prop;
+		i2s_data = i2s_tdm->i2s_sdis;
+	} else {
+		i2s_path_prop = i2s_tx_path_prop;
+		i2s_data = i2s_tdm->i2s_sdos;
+	}
+
+	num = of_count_phandle_with_args(np, i2s_path_prop, NULL);
+	if (num < 0) {
+		if (num != -ENOENT) {
+			dev_err(i2s_tdm->dev,
+				"Failed to read '%s' num: %d\n",
+				i2s_path_prop, num);
+			ret = num;
+		}
+		return ret;
+	} else if (num != CH_GRP_MAX) {
+		dev_err(i2s_tdm->dev,
+			"The num: %d should be: %d\n", num, CH_GRP_MAX);
+		return -EINVAL;
+	}
+
+	ret = of_property_read_u32_array(np, i2s_path_prop,
+					 i2s_data, num);
+	if (ret < 0) {
+		dev_err(i2s_tdm->dev,
+			"Failed to read '%s': %d\n",
+			i2s_path_prop, ret);
+		return ret;
+	}
+
+	ret = rockchip_i2s_tdm_path_check(i2s_tdm, num, is_rx_path);
+	if (ret < 0) {
+		dev_err(i2s_tdm->dev,
+			"Failed to check i2s data bus: %d\n", ret);
+		return ret;
+	}
+
+	rockchip_i2s_tdm_path_config(i2s_tdm, num, is_rx_path);
+
+	return 0;
+}
+
+static int rockchip_i2s_tdm_tx_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					    struct device_node *np)
+{
+	return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 0);
+}
+
+static int rockchip_i2s_tdm_rx_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm,
+					    struct device_node *np)
+{
+	return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 1);
+}
+
+static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *cru_node;
+	const struct of_device_id *of_id;
+	struct rk_i2s_tdm_dev *i2s_tdm;
+	struct resource *res;
+	void __iomem *regs;
+	int ret;
+	int val;
+
+	i2s_tdm = devm_kzalloc(&pdev->dev, sizeof(*i2s_tdm), GFP_KERNEL);
+	if (!i2s_tdm)
+		return -ENOMEM;
+
+	i2s_tdm->dev = &pdev->dev;
+
+	of_id = of_match_device(rockchip_i2s_tdm_match, &pdev->dev);
+	if (!of_id || !of_id->data)
+		return -EINVAL;
+
+	spin_lock_init(&i2s_tdm->lock);
+	i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data;
+
+	rockchip_i2s_tdm_init_dai(i2s_tdm);
+
+	i2s_tdm->frame_width = 64;
+	if (!of_property_read_u32(node, "rockchip,frame-width", &val)) {
+		if (val >= 32 && (val % 2 == 0) && val <= 512) {
+			i2s_tdm->frame_width = val;
+		} else {
+			dev_err(i2s_tdm->dev, "unsupported frame width: '%d'\n",
+				val);
+			return -EINVAL;
+		}
+	}
+
+	i2s_tdm->clk_trcm = TRCM_TXRX;
+	if (of_property_read_bool(node, "rockchip,trcm-sync-tx-only"))
+		i2s_tdm->clk_trcm = TRCM_TX;
+	if (of_property_read_bool(node, "rockchip,trcm-sync-rx-only")) {
+		if (i2s_tdm->clk_trcm) {
+			dev_err(i2s_tdm->dev, "invalid trcm-sync configuration\n");
+			return -EINVAL;
+		}
+		i2s_tdm->clk_trcm = TRCM_RX;
+	}
+	if (i2s_tdm->clk_trcm != TRCM_TXRX)
+		i2s_tdm_dai.symmetric_rate = 1;
+
+	i2s_tdm->tdm_fsync_half_frame =
+		of_property_read_bool(node, "rockchip,tdm-fsync-half-frame");
+
+	i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
+	if (IS_ERR(i2s_tdm->grf))
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->grf),
+				     "Error in rockchip,grf\n");
+
+	if (i2s_tdm->clk_trcm != TRCM_TXRX) {
+		cru_node = of_parse_phandle(node, "rockchip,cru", 0);
+		i2s_tdm->cru_base = of_iomap(cru_node, 0);
+		of_node_put(cru_node);
+		if (!i2s_tdm->cru_base) {
+			dev_err(i2s_tdm->dev,
+				"Missing or unsupported rockchip,cru node\n");
+			return -ENOENT;
+		}
+
+		i2s_tdm->tx_reset_id = of_i2s_resetid_get(node, "tx-m");
+		i2s_tdm->rx_reset_id = of_i2s_resetid_get(node, "rx-m");
+	}
+
+	i2s_tdm->tx_reset = devm_reset_control_get_exclusive(&pdev->dev,
+							     "tx-m");
+	if (IS_ERR(i2s_tdm->tx_reset)) {
+		ret = PTR_ERR(i2s_tdm->tx_reset);
+		return dev_err_probe(i2s_tdm->dev, ret,
+				     "Error in tx-m reset control\n");
+	}
+
+	i2s_tdm->rx_reset = devm_reset_control_get_exclusive(&pdev->dev,
+							     "rx-m");
+	if (IS_ERR(i2s_tdm->rx_reset)) {
+		ret = PTR_ERR(i2s_tdm->rx_reset);
+		return dev_err_probe(i2s_tdm->dev, ret,
+				     "Error in rx-m reset control\n");
+	}
+
+	i2s_tdm->hclk = devm_clk_get(&pdev->dev, "hclk");
+	if (IS_ERR(i2s_tdm->hclk)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->hclk),
+				     "Failed to get clock hclk\n");
+	}
+
+	i2s_tdm->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx");
+	if (IS_ERR(i2s_tdm->mclk_tx)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->mclk_tx),
+				     "Failed to get clock mclk_tx\n");
+	}
+
+	i2s_tdm->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx");
+	if (IS_ERR(i2s_tdm->mclk_rx)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->mclk_rx),
+				     "Failed to get clock mclk_rx\n");
+	}
+
+	i2s_tdm->io_multiplex =
+		of_property_read_bool(node, "rockchip,io-multiplex");
+
+	i2s_tdm->mclk_calibrate =
+		of_property_read_bool(node, "rockchip,mclk-calibrate");
+	if (i2s_tdm->mclk_calibrate) {
+		i2s_tdm->mclk_tx_src = devm_clk_get(&pdev->dev, "mclk_tx_src");
+		if (IS_ERR(i2s_tdm->mclk_tx_src)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_tx_src),
+					     "Failed to get clock mclk_tx_src\n");
+		}
+		i2s_tdm->mclk_rx_src = devm_clk_get(&pdev->dev, "mclk_rx_src");
+		if (IS_ERR(i2s_tdm->mclk_rx_src)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_rx_src),
+					     "Failed to get clock mclk_rx_src\n");
+		}
+		i2s_tdm->mclk_root0 = devm_clk_get(&pdev->dev, "mclk_root0");
+		if (IS_ERR(i2s_tdm->mclk_root0)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_root0),
+					     "Failed to get clock mclk_root0\n");
+		}
+		i2s_tdm->mclk_root1 = devm_clk_get(&pdev->dev, "mclk_root1");
+		if (IS_ERR(i2s_tdm->mclk_root1)) {
+			return dev_err_probe(i2s_tdm->dev,
+					     PTR_ERR(i2s_tdm->mclk_root1),
+					     "Failed to get clock mclk_root1\n");
+		}
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(regs),
+				     "Failed to get resource IORESOURCE_MEM\n");
+	}
+
+	i2s_tdm->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+					    &rockchip_i2s_tdm_regmap_config);
+	if (IS_ERR(i2s_tdm->regmap)) {
+		return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->regmap),
+				     "Failed to initialise regmap\n");
+	}
+
+	i2s_tdm->playback_dma_data.addr = res->start + I2S_TXDR;
+	i2s_tdm->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	i2s_tdm->playback_dma_data.maxburst = 8;
+
+	i2s_tdm->capture_dma_data.addr = res->start + I2S_RXDR;
+	i2s_tdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	i2s_tdm->capture_dma_data.maxburst = 8;
+
+	ret = rockchip_i2s_tdm_tx_path_prepare(i2s_tdm, node);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "I2S TX path prepare failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_i2s_tdm_rx_path_prepare(i2s_tdm, node);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "I2S RX path prepare failed: %d\n", ret);
+		return ret;
+	}
+
+	atomic_set(&i2s_tdm->refcount, 0);
+	dev_set_drvdata(&pdev->dev, i2s_tdm);
+
+	ret = clk_prepare_enable(i2s_tdm->hclk);
+	if (ret) {
+		return dev_err_probe(i2s_tdm->dev, ret,
+				     "Failed to enable clock hclk\n");
+	}
+
+	ret = i2s_tdm_prepare_enable_mclk(i2s_tdm);
+	if (ret) {
+		return dev_err_probe(i2s_tdm->dev, ret,
+				     "Failed to enable one or more mclks\n");
+		goto err_disable_hclk;
+	}
+
+	if (i2s_tdm->mclk_calibrate) {
+		i2s_tdm->mclk_root0_initial_freq = clk_get_rate(i2s_tdm->mclk_root0);
+		i2s_tdm->mclk_root1_initial_freq = clk_get_rate(i2s_tdm->mclk_root1);
+		i2s_tdm->mclk_root0_freq = i2s_tdm->mclk_root0_initial_freq;
+		i2s_tdm->mclk_root1_freq = i2s_tdm->mclk_root1_initial_freq;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
+			   I2S_DMACR_TDL(16));
+	regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
+			   I2S_DMACR_RDL(16));
+	regmap_update_bits(i2s_tdm->regmap, I2S_CKR, I2S_CKR_TRCM_MASK,
+			   i2s_tdm->clk_trcm << I2S_CKR_TRCM_SHIFT);
+
+	if (i2s_tdm->soc_data && i2s_tdm->soc_data->init)
+		i2s_tdm->soc_data->init(&pdev->dev, res->start);
+
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &rockchip_i2s_tdm_component,
+					      &i2s_tdm_dai, 1);
+
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register DAI\n");
+		goto err_suspend;
+	}
+
+	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register PCM\n");
+		goto err_suspend;
+	}
+
+	return 0;
+
+err_suspend:
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		i2s_tdm_runtime_suspend(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+err_disable_hclk:
+	if (!IS_ERR(i2s_tdm->hclk))
+		clk_disable_unprepare(i2s_tdm->hclk);
+
+	return ret;
+}
+
+static int rockchip_i2s_tdm_remove(struct platform_device *pdev)
+{
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		i2s_tdm_runtime_suspend(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static int __maybe_unused rockchip_i2s_tdm_suspend(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+
+	regcache_mark_dirty(i2s_tdm->regmap);
+
+	return 0;
+}
+
+static int __maybe_unused rockchip_i2s_tdm_resume(struct device *dev)
+{
+	struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0)
+		return ret;
+	ret = regcache_sync(i2s_tdm->regmap);
+	pm_runtime_put(dev);
+
+	return ret;
+}
+
+static const struct dev_pm_ops rockchip_i2s_tdm_pm_ops = {
+	SET_RUNTIME_PM_OPS(i2s_tdm_runtime_suspend, i2s_tdm_runtime_resume,
+			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend,
+				rockchip_i2s_tdm_resume)
+};
+
+static struct platform_driver rockchip_i2s_tdm_driver = {
+	.probe = rockchip_i2s_tdm_probe,
+	.remove = rockchip_i2s_tdm_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table = of_match_ptr(rockchip_i2s_tdm_match),
+		.pm = &rockchip_i2s_tdm_pm_ops,
+	},
+};
+module_platform_driver(rockchip_i2s_tdm_driver);
+
+MODULE_DESCRIPTION("ROCKCHIP I2S/TDM ASoC Interface");
+MODULE_AUTHOR("Sugar Zhang <sugar.zhang at rock-chips.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, rockchip_i2s_tdm_match);
diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.h b/sound/soc/rockchip/rockchip_i2s_tdm.h
new file mode 100644
index 000000000000..0aa1c6da1e2c
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_i2s_tdm.h
@@ -0,0 +1,398 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver
+ *
+ * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
+ * Author: Sugar Zhang <sugar.zhang at rock-chips.com>
+ *
+ */
+
+#ifndef _ROCKCHIP_I2S_TDM_H
+#define _ROCKCHIP_I2S_TDM_H
+
+/*
+ * TXCR
+ * transmit operation control register
+ */
+#define I2S_TXCR_PATH_SHIFT(x)	(23 + (x) * 2)
+#define I2S_TXCR_PATH_MASK(x)	(0x3 << I2S_TXCR_PATH_SHIFT(x))
+#define I2S_TXCR_PATH(x, v)	((v) << I2S_TXCR_PATH_SHIFT(x))
+#define I2S_TXCR_RCNT_SHIFT	17
+#define I2S_TXCR_RCNT_MASK	(0x3f << I2S_TXCR_RCNT_SHIFT)
+#define I2S_TXCR_CSR_SHIFT	15
+#define I2S_TXCR_CSR(x)		((x) << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_CSR_MASK	(3 << I2S_TXCR_CSR_SHIFT)
+#define I2S_TXCR_HWT		BIT(14)
+#define I2S_TXCR_SJM_SHIFT	12
+#define I2S_TXCR_SJM_R		(0 << I2S_TXCR_SJM_SHIFT)
+#define I2S_TXCR_SJM_L		(1 << I2S_TXCR_SJM_SHIFT)
+#define I2S_TXCR_FBM_SHIFT	11
+#define I2S_TXCR_FBM_MSB	(0 << I2S_TXCR_FBM_SHIFT)
+#define I2S_TXCR_FBM_LSB	(1 << I2S_TXCR_FBM_SHIFT)
+#define I2S_TXCR_IBM_SHIFT	9
+#define I2S_TXCR_IBM_NORMAL	(0 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_LSJM	(1 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_RSJM	(2 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_IBM_MASK	(3 << I2S_TXCR_IBM_SHIFT)
+#define I2S_TXCR_PBM_SHIFT	7
+#define I2S_TXCR_PBM_MODE(x)	((x) << I2S_TXCR_PBM_SHIFT)
+#define I2S_TXCR_PBM_MASK	(3 << I2S_TXCR_PBM_SHIFT)
+#define I2S_TXCR_TFS_SHIFT	5
+#define I2S_TXCR_TFS_I2S	(0 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_PCM	(1 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_TDM_PCM	(2 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_TDM_I2S	(3 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_TFS_MASK	(3 << I2S_TXCR_TFS_SHIFT)
+#define I2S_TXCR_VDW_SHIFT	0
+#define I2S_TXCR_VDW(x)		(((x) - 1) << I2S_TXCR_VDW_SHIFT)
+#define I2S_TXCR_VDW_MASK	(0x1f << I2S_TXCR_VDW_SHIFT)
+
+/*
+ * RXCR
+ * receive operation control register
+ */
+#define I2S_RXCR_PATH_SHIFT(x)	(17 + (x) * 2)
+#define I2S_RXCR_PATH_MASK(x)	(0x3 << I2S_RXCR_PATH_SHIFT(x))
+#define I2S_RXCR_PATH(x, v)	((v) << I2S_RXCR_PATH_SHIFT(x))
+#define I2S_RXCR_CSR_SHIFT	15
+#define I2S_RXCR_CSR(x)		((x) << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_CSR_MASK	(3 << I2S_RXCR_CSR_SHIFT)
+#define I2S_RXCR_HWT		BIT(14)
+#define I2S_RXCR_SJM_SHIFT	12
+#define I2S_RXCR_SJM_R		(0 << I2S_RXCR_SJM_SHIFT)
+#define I2S_RXCR_SJM_L		(1 << I2S_RXCR_SJM_SHIFT)
+#define I2S_RXCR_FBM_SHIFT	11
+#define I2S_RXCR_FBM_MSB	(0 << I2S_RXCR_FBM_SHIFT)
+#define I2S_RXCR_FBM_LSB	(1 << I2S_RXCR_FBM_SHIFT)
+#define I2S_RXCR_IBM_SHIFT	9
+#define I2S_RXCR_IBM_NORMAL	(0 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_LSJM	(1 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_RSJM	(2 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_IBM_MASK	(3 << I2S_RXCR_IBM_SHIFT)
+#define I2S_RXCR_PBM_SHIFT	7
+#define I2S_RXCR_PBM_MODE(x)	((x) << I2S_RXCR_PBM_SHIFT)
+#define I2S_RXCR_PBM_MASK	(3 << I2S_RXCR_PBM_SHIFT)
+#define I2S_RXCR_TFS_SHIFT	5
+#define I2S_RXCR_TFS_I2S	(0 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_PCM	(1 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_TDM_PCM	(2 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_TDM_I2S	(3 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_TFS_MASK	(3 << I2S_RXCR_TFS_SHIFT)
+#define I2S_RXCR_VDW_SHIFT	0
+#define I2S_RXCR_VDW(x)		(((x) - 1) << I2S_RXCR_VDW_SHIFT)
+#define I2S_RXCR_VDW_MASK	(0x1f << I2S_RXCR_VDW_SHIFT)
+
+/*
+ * CKR
+ * clock generation register
+ */
+#define I2S_CKR_TRCM_SHIFT	28
+#define I2S_CKR_TRCM(x)	((x) << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_TXRX	(0 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_TXONLY	(1 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_RXONLY	(2 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_TRCM_MASK	(3 << I2S_CKR_TRCM_SHIFT)
+#define I2S_CKR_MSS_SHIFT	27
+#define I2S_CKR_MSS_MASTER	(0 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_MSS_SLAVE	(1 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_MSS_MASK	(1 << I2S_CKR_MSS_SHIFT)
+#define I2S_CKR_CKP_SHIFT	26
+#define I2S_CKR_CKP_NORMAL	(0 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_CKP_INVERTED	(1 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_CKP_MASK	(1 << I2S_CKR_CKP_SHIFT)
+#define I2S_CKR_RLP_SHIFT	25
+#define I2S_CKR_RLP_NORMAL	(0 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_RLP_INVERTED	(1 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_RLP_MASK	(1 << I2S_CKR_RLP_SHIFT)
+#define I2S_CKR_TLP_SHIFT	24
+#define I2S_CKR_TLP_NORMAL	(0 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_TLP_INVERTED	(1 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_TLP_MASK	(1 << I2S_CKR_TLP_SHIFT)
+#define I2S_CKR_MDIV_SHIFT	16
+#define I2S_CKR_MDIV(x)		(((x) - 1) << I2S_CKR_MDIV_SHIFT)
+#define I2S_CKR_MDIV_MASK	(0xff << I2S_CKR_MDIV_SHIFT)
+#define I2S_CKR_RSD_SHIFT	8
+#define I2S_CKR_RSD(x)		(((x) - 1) << I2S_CKR_RSD_SHIFT)
+#define I2S_CKR_RSD_MASK	(0xff << I2S_CKR_RSD_SHIFT)
+#define I2S_CKR_TSD_SHIFT	0
+#define I2S_CKR_TSD(x)		(((x) - 1) << I2S_CKR_TSD_SHIFT)
+#define I2S_CKR_TSD_MASK	(0xff << I2S_CKR_TSD_SHIFT)
+
+/*
+ * FIFOLR
+ * FIFO level register
+ */
+#define I2S_FIFOLR_RFL_SHIFT	24
+#define I2S_FIFOLR_RFL_MASK	(0x3f << I2S_FIFOLR_RFL_SHIFT)
+#define I2S_FIFOLR_TFL3_SHIFT	18
+#define I2S_FIFOLR_TFL3_MASK	(0x3f << I2S_FIFOLR_TFL3_SHIFT)
+#define I2S_FIFOLR_TFL2_SHIFT	12
+#define I2S_FIFOLR_TFL2_MASK	(0x3f << I2S_FIFOLR_TFL2_SHIFT)
+#define I2S_FIFOLR_TFL1_SHIFT	6
+#define I2S_FIFOLR_TFL1_MASK	(0x3f << I2S_FIFOLR_TFL1_SHIFT)
+#define I2S_FIFOLR_TFL0_SHIFT	0
+#define I2S_FIFOLR_TFL0_MASK	(0x3f << I2S_FIFOLR_TFL0_SHIFT)
+
+/*
+ * DMACR
+ * DMA control register
+ */
+#define I2S_DMACR_RDE_SHIFT	24
+#define I2S_DMACR_RDE_DISABLE	(0 << I2S_DMACR_RDE_SHIFT)
+#define I2S_DMACR_RDE_ENABLE	(1 << I2S_DMACR_RDE_SHIFT)
+#define I2S_DMACR_RDL_SHIFT	16
+#define I2S_DMACR_RDL(x)	(((x) - 1) << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_RDL_MASK	(0x1f << I2S_DMACR_RDL_SHIFT)
+#define I2S_DMACR_TDE_SHIFT	8
+#define I2S_DMACR_TDE_DISABLE	(0 << I2S_DMACR_TDE_SHIFT)
+#define I2S_DMACR_TDE_ENABLE	(1 << I2S_DMACR_TDE_SHIFT)
+#define I2S_DMACR_TDL_SHIFT	0
+#define I2S_DMACR_TDL(x)	((x) << I2S_DMACR_TDL_SHIFT)
+#define I2S_DMACR_TDL_MASK	(0x1f << I2S_DMACR_TDL_SHIFT)
+
+/*
+ * INTCR
+ * interrupt control register
+ */
+#define I2S_INTCR_RFT_SHIFT	20
+#define I2S_INTCR_RFT(x)	(((x) - 1) << I2S_INTCR_RFT_SHIFT)
+#define I2S_INTCR_RXOIC		BIT(18)
+#define I2S_INTCR_RXOIE_SHIFT	17
+#define I2S_INTCR_RXOIE_DISABLE	(0 << I2S_INTCR_RXOIE_SHIFT)
+#define I2S_INTCR_RXOIE_ENABLE	(1 << I2S_INTCR_RXOIE_SHIFT)
+#define I2S_INTCR_RXFIE_SHIFT	16
+#define I2S_INTCR_RXFIE_DISABLE	(0 << I2S_INTCR_RXFIE_SHIFT)
+#define I2S_INTCR_RXFIE_ENABLE	(1 << I2S_INTCR_RXFIE_SHIFT)
+#define I2S_INTCR_TFT_SHIFT	4
+#define I2S_INTCR_TFT(x)	(((x) - 1) << I2S_INTCR_TFT_SHIFT)
+#define I2S_INTCR_TFT_MASK	(0x1f << I2S_INTCR_TFT_SHIFT)
+#define I2S_INTCR_TXUIC		BIT(2)
+#define I2S_INTCR_TXUIE_SHIFT	1
+#define I2S_INTCR_TXUIE_DISABLE	(0 << I2S_INTCR_TXUIE_SHIFT)
+#define I2S_INTCR_TXUIE_ENABLE	(1 << I2S_INTCR_TXUIE_SHIFT)
+
+/*
+ * INTSR
+ * interrupt status register
+ */
+#define I2S_INTSR_TXEIE_SHIFT	0
+#define I2S_INTSR_TXEIE_DISABLE	(0 << I2S_INTSR_TXEIE_SHIFT)
+#define I2S_INTSR_TXEIE_ENABLE	(1 << I2S_INTSR_TXEIE_SHIFT)
+#define I2S_INTSR_RXOI_SHIFT	17
+#define I2S_INTSR_RXOI_INA	(0 << I2S_INTSR_RXOI_SHIFT)
+#define I2S_INTSR_RXOI_ACT	(1 << I2S_INTSR_RXOI_SHIFT)
+#define I2S_INTSR_RXFI_SHIFT	16
+#define I2S_INTSR_RXFI_INA	(0 << I2S_INTSR_RXFI_SHIFT)
+#define I2S_INTSR_RXFI_ACT	(1 << I2S_INTSR_RXFI_SHIFT)
+#define I2S_INTSR_TXUI_SHIFT	1
+#define I2S_INTSR_TXUI_INA	(0 << I2S_INTSR_TXUI_SHIFT)
+#define I2S_INTSR_TXUI_ACT	(1 << I2S_INTSR_TXUI_SHIFT)
+#define I2S_INTSR_TXEI_SHIFT	0
+#define I2S_INTSR_TXEI_INA	(0 << I2S_INTSR_TXEI_SHIFT)
+#define I2S_INTSR_TXEI_ACT	(1 << I2S_INTSR_TXEI_SHIFT)
+
+/*
+ * XFER
+ * Transfer start register
+ */
+#define I2S_XFER_RXS_SHIFT	1
+#define I2S_XFER_RXS_STOP	(0 << I2S_XFER_RXS_SHIFT)
+#define I2S_XFER_RXS_START	(1 << I2S_XFER_RXS_SHIFT)
+#define I2S_XFER_TXS_SHIFT	0
+#define I2S_XFER_TXS_STOP	(0 << I2S_XFER_TXS_SHIFT)
+#define I2S_XFER_TXS_START	(1 << I2S_XFER_TXS_SHIFT)
+
+/*
+ * CLR
+ * clear SCLK domain logic register
+ */
+#define I2S_CLR_RXC	BIT(1)
+#define I2S_CLR_TXC	BIT(0)
+
+/*
+ * TXDR
+ * Transimt FIFO data register, write only.
+ */
+#define I2S_TXDR_MASK	(0xff)
+
+/*
+ * RXDR
+ * Receive FIFO data register, write only.
+ */
+#define I2S_RXDR_MASK	(0xff)
+
+/*
+ * TDM_CTRL
+ * TDM ctrl register
+ */
+#define TDM_FSYNC_WIDTH_SEL1_MSK	GENMASK(20, 18)
+#define TDM_FSYNC_WIDTH_SEL1(x)		(((x) - 1) << 18)
+#define TDM_FSYNC_WIDTH_SEL0_MSK	BIT(17)
+#define TDM_FSYNC_WIDTH_HALF_FRAME	0
+#define TDM_FSYNC_WIDTH_ONE_FRAME	BIT(17)
+#define TDM_SHIFT_CTRL_MSK		GENMASK(16, 14)
+#define TDM_SHIFT_CTRL(x)		((x) << 14)
+#define TDM_SLOT_BIT_WIDTH_MSK		GENMASK(13, 9)
+#define TDM_SLOT_BIT_WIDTH(x)		(((x) - 1) << 9)
+#define TDM_FRAME_WIDTH_MSK		GENMASK(8, 0)
+#define TDM_FRAME_WIDTH(x)		(((x) - 1) << 0)
+
+/*
+ * CLKDIV
+ * Mclk div register
+ */
+#define I2S_CLKDIV_TXM_SHIFT	0
+#define I2S_CLKDIV_TXM(x)		(((x) - 1) << I2S_CLKDIV_TXM_SHIFT)
+#define I2S_CLKDIV_TXM_MASK	(0xff << I2S_CLKDIV_TXM_SHIFT)
+#define I2S_CLKDIV_RXM_SHIFT	8
+#define I2S_CLKDIV_RXM(x)		(((x) - 1) << I2S_CLKDIV_RXM_SHIFT)
+#define I2S_CLKDIV_RXM_MASK	(0xff << I2S_CLKDIV_RXM_SHIFT)
+
+/* Clock divider id */
+enum {
+	ROCKCHIP_DIV_MCLK = 0,
+	ROCKCHIP_DIV_BCLK,
+};
+
+/* channel select */
+#define I2S_CSR_SHIFT	15
+#define I2S_CHN_2	(0 << I2S_CSR_SHIFT)
+#define I2S_CHN_4	(1 << I2S_CSR_SHIFT)
+#define I2S_CHN_6	(2 << I2S_CSR_SHIFT)
+#define I2S_CHN_8	(3 << I2S_CSR_SHIFT)
+
+/* io direction cfg register */
+#define I2S_IO_DIRECTION_MASK	(7)
+#define I2S_IO_8CH_OUT_2CH_IN	(7)
+#define I2S_IO_6CH_OUT_4CH_IN	(3)
+#define I2S_IO_4CH_OUT_6CH_IN	(1)
+#define I2S_IO_2CH_OUT_8CH_IN	(0)
+
+/* I2S REGS */
+#define I2S_TXCR	(0x0000)
+#define I2S_RXCR	(0x0004)
+#define I2S_CKR		(0x0008)
+#define I2S_TXFIFOLR	(0x000c)
+#define I2S_DMACR	(0x0010)
+#define I2S_INTCR	(0x0014)
+#define I2S_INTSR	(0x0018)
+#define I2S_XFER	(0x001c)
+#define I2S_CLR		(0x0020)
+#define I2S_TXDR	(0x0024)
+#define I2S_RXDR	(0x0028)
+#define I2S_RXFIFOLR	(0x002c)
+#define I2S_TDM_TXCR	(0x0030)
+#define I2S_TDM_RXCR	(0x0034)
+#define I2S_CLKDIV	(0x0038)
+
+#define HIWORD_UPDATE(v, h, l)	(((v) << (l)) | (GENMASK((h), (l)) << 16))
+
+/* PX30 GRF CONFIGS */
+#define PX30_I2S0_CLK_IN_SRC_FROM_TX		HIWORD_UPDATE(1, 13, 12)
+#define PX30_I2S0_CLK_IN_SRC_FROM_RX		HIWORD_UPDATE(2, 13, 12)
+#define PX30_I2S0_MCLK_OUT_SRC_FROM_TX		HIWORD_UPDATE(1, 5, 5)
+#define PX30_I2S0_MCLK_OUT_SRC_FROM_RX		HIWORD_UPDATE(0, 5, 5)
+
+#define PX30_I2S0_CLK_TXONLY \
+	(PX30_I2S0_MCLK_OUT_SRC_FROM_TX | PX30_I2S0_CLK_IN_SRC_FROM_TX)
+
+#define PX30_I2S0_CLK_RXONLY \
+	(PX30_I2S0_MCLK_OUT_SRC_FROM_RX | PX30_I2S0_CLK_IN_SRC_FROM_RX)
+
+/* RK1808 GRF CONFIGS */
+#define RK1808_I2S0_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 2, 2)
+#define RK1808_I2S0_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 2, 2)
+#define RK1808_I2S0_CLK_IN_SRC_FROM_TX		HIWORD_UPDATE(1, 1, 0)
+#define RK1808_I2S0_CLK_IN_SRC_FROM_RX		HIWORD_UPDATE(2, 1, 0)
+
+#define RK1808_I2S0_CLK_TXONLY \
+	(RK1808_I2S0_MCLK_OUT_SRC_FROM_TX | RK1808_I2S0_CLK_IN_SRC_FROM_TX)
+
+#define RK1808_I2S0_CLK_RXONLY \
+	(RK1808_I2S0_MCLK_OUT_SRC_FROM_RX | RK1808_I2S0_CLK_IN_SRC_FROM_RX)
+
+/* RK3308 GRF CONFIGS */
+#define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 10, 10)
+#define RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 10, 10)
+#define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX	HIWORD_UPDATE(1, 9, 9)
+#define RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_RX	HIWORD_UPDATE(0, 9, 9)
+#define RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_RX	HIWORD_UPDATE(1, 8, 8)
+#define RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_TX	HIWORD_UPDATE(0, 8, 8)
+#define RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 2, 2)
+#define RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 2, 2)
+#define RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_TX	HIWORD_UPDATE(1, 1, 1)
+#define RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_RX	HIWORD_UPDATE(0, 1, 1)
+#define RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_RX	HIWORD_UPDATE(1, 0, 0)
+#define RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_TX	HIWORD_UPDATE(0, 0, 0)
+
+#define RK3308_I2S0_CLK_TXONLY \
+	(RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_TX | \
+	RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_TX | \
+	RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_TX)
+
+#define RK3308_I2S0_CLK_RXONLY \
+	(RK3308_I2S0_8CH_MCLK_OUT_SRC_FROM_RX | \
+	RK3308_I2S0_8CH_CLK_IN_RX_SRC_FROM_RX | \
+	RK3308_I2S0_8CH_CLK_IN_TX_SRC_FROM_RX)
+
+#define RK3308_I2S1_CLK_TXONLY \
+	(RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_TX | \
+	RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_TX | \
+	RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_TX)
+
+#define RK3308_I2S1_CLK_RXONLY \
+	(RK3308_I2S1_8CH_MCLK_OUT_SRC_FROM_RX | \
+	RK3308_I2S1_8CH_CLK_IN_RX_SRC_FROM_RX | \
+	RK3308_I2S1_8CH_CLK_IN_TX_SRC_FROM_RX)
+
+/* RK3568 GRF CONFIGS */
+#define RK3568_I2S1_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(1, 5, 5)
+#define RK3568_I2S1_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(0, 5, 5)
+
+#define RK3568_I2S1_CLK_TXONLY \
+	RK3568_I2S1_MCLK_OUT_SRC_FROM_TX
+
+#define RK3568_I2S1_CLK_RXONLY \
+	RK3568_I2S1_MCLK_OUT_SRC_FROM_RX
+
+#define RK3568_I2S3_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(1, 15, 15)
+#define RK3568_I2S3_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(0, 15, 15)
+#define RK3568_I2S3_SCLK_SRC_FROM_TX		HIWORD_UPDATE(1, 7, 7)
+#define RK3568_I2S3_SCLK_SRC_FROM_RX		HIWORD_UPDATE(0, 7, 7)
+#define RK3568_I2S3_LRCK_SRC_FROM_TX		HIWORD_UPDATE(1, 6, 6)
+#define RK3568_I2S3_LRCK_SRC_FROM_RX		HIWORD_UPDATE(0, 6, 6)
+
+#define RK3568_I2S3_MCLK_TXONLY \
+	RK3568_I2S3_MCLK_OUT_SRC_FROM_TX
+
+#define RK3568_I2S3_CLK_TXONLY \
+	(RK3568_I2S3_SCLK_SRC_FROM_TX | \
+	RK3568_I2S3_LRCK_SRC_FROM_TX)
+
+#define RK3568_I2S3_MCLK_RXONLY \
+	RK3568_I2S3_MCLK_OUT_SRC_FROM_RX
+
+#define RK3568_I2S3_CLK_RXONLY \
+	(RK3568_I2S3_SCLK_SRC_FROM_RX | \
+	RK3568_I2S3_LRCK_SRC_FROM_RX)
+
+#define RK3568_I2S3_MCLK_IE			HIWORD_UPDATE(0, 3, 3)
+#define RK3568_I2S3_MCLK_OE			HIWORD_UPDATE(1, 3, 3)
+#define RK3568_I2S2_MCLK_IE			HIWORD_UPDATE(0, 2, 2)
+#define RK3568_I2S2_MCLK_OE			HIWORD_UPDATE(1, 2, 2)
+#define RK3568_I2S1_MCLK_TX_IE			HIWORD_UPDATE(0, 1, 1)
+#define RK3568_I2S1_MCLK_TX_OE			HIWORD_UPDATE(1, 1, 1)
+#define RK3568_I2S1_MCLK_RX_IE			HIWORD_UPDATE(0, 0, 0)
+#define RK3568_I2S1_MCLK_RX_OE			HIWORD_UPDATE(1, 0, 0)
+
+/* RV1126 GRF CONFIGS */
+#define RV1126_I2S0_MCLK_OUT_SRC_FROM_TX	HIWORD_UPDATE(0, 9, 9)
+#define RV1126_I2S0_MCLK_OUT_SRC_FROM_RX	HIWORD_UPDATE(1, 9, 9)
+
+#define RV1126_I2S0_CLK_TXONLY \
+	RV1126_I2S0_MCLK_OUT_SRC_FROM_TX
+
+#define RV1126_I2S0_CLK_RXONLY \
+	RV1126_I2S0_MCLK_OUT_SRC_FROM_RX
+
+#endif /* _ROCKCHIP_I2S_TDM_H */
-- 
2.33.0



From frattaroli.nicolas at gmail.com  Sat Aug 28 07:02:02 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Sat, 28 Aug 2021 16:02:02 +0200
Subject: [PATCH v3 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
References: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210828140205.21973-3-frattaroli.nicolas@gmail.com>

This adds the YAML bindings for the Rockchip I2S/TDM audio driver.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 .../bindings/sound/rockchip,i2s-tdm.yaml      | 218 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 2 files changed, 219 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml

diff --git a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
new file mode 100644
index 000000000000..ab8731779805
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
@@ -0,0 +1,218 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip I2S/TDM Controller
+
+description:
+  The Rockchip I2S/TDM Controller is a Time Division Multiplexed
+  audio interface found in various Rockchip SoCs, allowing up
+  to 8 channels of audio over a serial interface.
+
+maintainers:
+  - Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,px30-i2s-tdm
+      - rockchip,rk1808-i2s-tdm
+      - rockchip,rk3308-i2s-tdm
+      - rockchip,rk3568-i2s-tdm
+      - rockchip,rv1126-i2s-tdm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  dmas:
+    minItems: 1
+    maxItems: 2
+
+  dma-names:
+    minItems: 1
+    maxItems: 2
+    items:
+      enum:
+        - rx
+        - tx
+
+  clocks:
+    minItems: 3
+    items:
+      - description: clock for TX
+      - description: clock for RX
+      - description: AHB clock driving the interface
+      - description:
+          Parent clock for mclk_tx (only required when using mclk-calibrate)
+      - description:
+          Parent clock for mclk_rx (only required when using mclk-calibrate)
+      - description:
+          Clock for sample rates that are an integer multiple of 8000
+          (only required when using mclk-calibrate)
+      - description:
+          Clock for sample rates that are an integer multiple of 11025
+          (only required when using mclk-calibrate)
+
+  clock-names:
+    minItems: 3
+    items:
+      - const: mclk_tx
+      - const: mclk_rx
+      - const: hclk
+      - const: mclk_tx_src
+      - const: mclk_rx_src
+      - const: mclk_root0
+      - const: mclk_root1
+
+  rockchip,frame-width:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 64
+    minimum: 32
+    maximum: 512
+    description:
+      Width of a frame, usually slot width multiplied by number of slots.
+      Must be even.
+
+  resets:
+    items:
+      - description: reset for TX
+      - description: reset for RX
+
+  reset-names:
+    items:
+      - const: tx-m
+      - const: rx-m
+
+  rockchip,cru:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the cru.
+      Required if neither trcm-sync-tx-only nor trcm-sync-rx-only are specified.
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the GRF register.
+
+  rockchip,mclk-calibrate:
+    description:
+      Switch between two root clocks depending on the audio sample rate.
+      For integer multiples of 8000 (e.g. 48000 Hz), mclk_root0 is used.
+      For integer multiples of 11025 (e.g. 44100 Hz), mclk_root1 is used.
+    type: boolean
+
+  rockchip,trcm-sync-tx-only:
+    type: boolean
+    description: Use TX BCLK/LRCK for both TX and RX.
+
+  rockchip,trcm-sync-rx-only:
+    type: boolean
+    description: Use RX BCLK/LRCK for both TX and RX.
+
+  "#sound-dai-cells":
+    const: 0
+
+  rockchip,i2s-rx-route:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Defines the mapping of I2S RX sdis to I2S data bus lines.
+      By default, they are mapped one-to-one.
+    items:
+      - description: which sdi to connect to data line 0
+      - description: which sdi to connect to data line 1
+      - description: which sdi to connect to data line 2
+      - description: which sdi to connect to data line 3
+
+  rockchip,i2s-tx-route:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Defines the mapping of I2S TX sdos to I2S data bus lines.
+      By default, they are mapped one-to-one.
+    items:
+      - description: which sdo to connect to data line 0
+      - description: which sdo to connect to data line 1
+      - description: which sdo to connect to data line 2
+      - description: which sdo to connect to data line 3
+
+  rockchip,tdm-fsync-half-frame:
+    description: Whether to use half frame fsync.
+    type: boolean
+
+  rockchip,io-multiplex:
+    description:
+      Specify that the GPIO lines on the I2S bus are multiplexed such that
+      the direction (input/output) needs to be dynamically adjusted.
+    type: boolean
+
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - dmas
+  - dma-names
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - rockchip,grf
+  - "#sound-dai-cells"
+
+allOf:
+  - if:
+      properties:
+        rockchip,trcm-sync-tx-only: false
+        rockchip,trcm-sync-rx-only: false
+    then:
+      required:
+        - rockchip,cru
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3568-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/pinctrl/rockchip.h>
+
+    foo {
+        #address-cells = <2>;
+        #size-cells = <2>;
+        i2s at fe410000 {
+            compatible = "rockchip,rk3568-i2s-tdm";
+            reg = <0x0 0xfe410000 0x0 0x1000>;
+            interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
+                     <&cru HCLK_I2S1_8CH>;
+            clock-names = "mclk_tx", "mclk_rx", "hclk";
+            dmas = <&dmac1 3>, <&dmac1 2>;
+            dma-names = "rx", "tx";
+            resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+            reset-names = "tx-m", "rx-m";
+            rockchip,trcm-sync-tx-only;
+            rockchip,cru = <&cru>;
+            rockchip,grf = <&grf>;
+            #sound-dai-cells = <0>;
+            pinctrl-names = "default";
+            pinctrl-0 =
+                <&i2s1m0_sclktx
+                &i2s1m0_sclkrx
+                &i2s1m0_lrcktx
+                &i2s1m0_lrckrx
+                &i2s1m0_sdi0
+                &i2s1m0_sdi1
+                &i2s1m0_sdi2
+                &i2s1m0_sdi3
+                &i2s1m0_sdo0
+                &i2s1m0_sdo1
+                &i2s1m0_sdo2
+                &i2s1m0_sdo3>;
+            status = "okay";
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 5d459d42672c..d2be16a85009 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16053,6 +16053,7 @@ ROCKCHIP I2S TDM DRIVER
 M:	Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
 L:	linux-rockchip at lists.infradead.org
 S:	Maintained
+F:	Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
 F:	sound/soc/rockchip/rockchip_i2s_tdm.*
 
 ROCKCHIP ISP V1 DRIVER
-- 
2.33.0



From frattaroli.nicolas at gmail.com  Sat Aug 28 07:02:03 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Sat, 28 Aug 2021 16:02:03 +0200
Subject: [PATCH v3 3/4] arm64: dts: rockchip: add i2s1 on rk356x
In-Reply-To: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
References: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210828140205.21973-4-frattaroli.nicolas@gmail.com>

This adds the necessary device tree node on rk3566 and rk3568
to enable the I2S1 TDM audio controller.

I2S0 has not been added, as it is connected to HDMI and there is
no way to test that it's working without a functioning video
clock (read: VOP2 driver).

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 26 ++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 13b185e1dc5f..fce760996a64 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -559,6 +559,32 @@ sdhci: mmc at fe310000 {
 		status = "disabled";
 	};
 
+	i2s1_8ch: i2s at fe410000 {
+		compatible = "rockchip,rk3568-i2s-tdm";
+		reg = <0x0 0xfe410000 0x0 0x1000>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+		assigned-clocks = <&cru CLK_I2S1_8CH_TX_SRC>, <&cru CLK_I2S1_8CH_RX_SRC>;
+		assigned-clock-rates = <1188000000>, <1188000000>;
+		clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
+		<&cru HCLK_I2S1_8CH>;
+		clock-names = "mclk_tx", "mclk_rx", "hclk";
+		dmas = <&dmac1 3>, <&dmac1 2>;
+		dma-names = "rx", "tx";
+		resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+		reset-names = "tx-m", "rx-m";
+		rockchip,cru = <&cru>;
+		rockchip,grf = <&grf>;
+		#sound-dai-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_sclkrx
+			     &i2s1m0_lrcktx &i2s1m0_lrckrx
+			     &i2s1m0_sdi0   &i2s1m0_sdi1
+			     &i2s1m0_sdi2   &i2s1m0_sdi3
+			     &i2s1m0_sdo0   &i2s1m0_sdo1
+			     &i2s1m0_sdo2   &i2s1m0_sdo3>;
+		status = "disabled";
+	};
+
 	dmac0: dmac at fe530000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xfe530000 0x0 0x4000>;
-- 
2.33.0



From frattaroli.nicolas at gmail.com  Sat Aug 28 07:02:04 2021
From: frattaroli.nicolas at gmail.com (Nicolas Frattaroli)
Date: Sat, 28 Aug 2021 16:02:04 +0200
Subject: [PATCH v3 4/4] arm64: dts: rockchip: add analog audio on Quartz64
In-Reply-To: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
References: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
Message-ID: <20210828140205.21973-5-frattaroli.nicolas@gmail.com>

On the Quartz64 Model A, the I2S1 TDM controller is connected
to the rk817 codec in I2S mode. Enabling it and adding the
necessary simple-sound-card and codec nodes allows for analog
audio output on the PINE64 Quartz64 Model A SBC.

Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 35 ++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index b239f314b38a..c974b0e22ac0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -50,6 +50,20 @@ led-diy {
 		};
 	};
 
+	rk817-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,name = "Analog RK817";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s1_8ch>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&rk817>;
+		};
+	};
+
 	vcc12v_dcin: vcc12v_dcin {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc12v_dcin";
@@ -174,8 +188,13 @@ rk817: pmic at 20 {
 		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
 		clock-output-names = "rk808-clkout1", "rk808-clkout2";
 
+		#sound-dai-cells = <0>;
+		clock-names = "mclk";
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&pmic_int_l>;
+		pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
 		rockchip,system-power-controller;
 		wakeup-source;
 		#clock-cells = <1>;
@@ -364,9 +383,23 @@ regulator-state-mem {
 				};
 			};
 		};
+
+		rk817_codec: codec {
+		};
+
 	};
 };
 
+&i2s1_8ch {
+	status = "okay";
+	rockchip,trcm-sync-tx-only;
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s1m0_sclktx
+		     &i2s1m0_lrcktx
+		     &i2s1m0_sdi0
+		     &i2s1m0_sdo0>;
+};
+
 &mdio1 {
 	rgmii_phy1: ethernet-phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
-- 
2.33.0



From hector.yuan at mediatek.com  Sat Aug 28 08:01:11 2021
From: hector.yuan at mediatek.com (Hector Yuan)
Date: Sat, 28 Aug 2021 23:01:11 +0800
Subject: [PATCH v14 2/3] cpufreq: Add of_perf_domain_get_sharing_cpumask
In-Reply-To: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
References: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
Message-ID: <1630162872-25452-3-git-send-email-hector.yuan@mediatek.com>

From: "Hector.Yuan" <hector.yuan at mediatek.com>

Add of_perf_domain_get_sharing_cpumask function to group cpu
to specific performance domain.

Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
---
 include/linux/cpufreq.h |   39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 9fd7194..4916d70 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -13,6 +13,8 @@
 #include <linux/completion.h>
 #include <linux/kobject.h>
 #include <linux/notifier.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/pm_qos.h>
 #include <linux/spinlock.h>
 #include <linux/sysfs.h>
@@ -1036,6 +1038,43 @@ void arch_set_freq_scale(const struct cpumask *cpus,
 }
 #endif
 
+#ifdef CONFIG_CPU_FREQ
+static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name,
+						     const char *cell_name,
+						     struct cpumask *cpumask)
+{
+	struct device_node *cpu_np;
+	struct of_phandle_args args;
+	int cpu, ret;
+
+	for_each_possible_cpu(cpu) {
+		cpu_np = of_cpu_device_node_get(cpu);
+		if (!cpu_np)
+			continue;
+
+		ret = of_parse_phandle_with_args(cpu_np, list_name,
+						 cell_name, 0,
+						 &args);
+
+		of_node_put(cpu_np);
+		if (ret < 0)
+			continue;
+
+		if (index == args.args[0])
+			cpumask_set_cpu(cpu, cpumask);
+	}
+
+	return 0;
+}
+#else
+static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name,
+						     const char *cell_name,
+						     struct cpumask *cpumask)
+{
+	return 0;
+}
+#endif
+
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
 extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
-- 
1.7.9.5

From hector.yuan at mediatek.com  Sat Aug 28 08:01:10 2021
From: hector.yuan at mediatek.com (Hector Yuan)
Date: Sat, 28 Aug 2021 23:01:10 +0800
Subject: [PATCH v14 1/3] ndings: cpufreq: add bindings for MediaTek cpufreq HW
In-Reply-To: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
References: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
Message-ID: <1630162872-25452-2-git-send-email-hector.yuan@mediatek.com>

From: "Hector.Yuan" <hector.yuan at mediatek.com>

Add devicetree bindings for MediaTek HW driver.

Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
---
 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml      |   70 ++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml

diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
new file mode 100644
index 0000000..9cd42a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek's CPUFREQ Bindings
+
+maintainers:
+  - Hector Yuan <hector.yuan at mediatek.com>
+
+description:
+  CPUFREQ HW is a hardware engine used by MediaTek SoCs to
+  manage frequency in hardware. It is capable of controlling
+  frequency for multiple clusters.
+
+properties:
+  compatible:
+    const: mediatek,cpufreq-hw
+
+  reg:
+    minItems: 1
+    maxItems: 2
+    description:
+      Addresses and sizes for the memory of the HW bases in
+      each frequency domain. Each entry corresponds to
+      a register bank for each frequency domain present.
+
+  "#performance-domain-cells":
+    description:
+      Number of cells in a performance domain specifier.
+      Set const to 1 here for nodes providing multiple
+      performance domains.
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - "#performance-domain-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    cpus {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            cpu0: cpu at 0 {
+                device_type = "cpu";
+                compatible = "arm,cortex-a55";
+                enable-method = "psci";
+                performance-domains = <&performance 0>;
+                reg = <0x000>;
+            };
+    };
+
+    /* ... */
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        performance: performance-controller at 11bc00 {
+            compatible = "mediatek,cpufreq-hw";
+            reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>;
+
+            #performance-domain-cells = <1>;
+        };
+    };
-- 
1.7.9.5

From hector.yuan at mediatek.com  Sat Aug 28 08:01:12 2021
From: hector.yuan at mediatek.com (Hector Yuan)
Date: Sat, 28 Aug 2021 23:01:12 +0800
Subject: [PATCH v14 3/3] cpufreq: mediatek-hw: Add support for CPUFREQ HW
In-Reply-To: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
References: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
Message-ID: <1630162872-25452-4-git-send-email-hector.yuan@mediatek.com>

From: "Hector.Yuan" <hector.yuan at mediatek.com>

Introduce cpufreq HW driver which can support
CPU frequency adjust in MT6779 platform.

Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
---
 drivers/cpufreq/Kconfig.arm           |   12 ++
 drivers/cpufreq/Makefile              |    1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c |  319 +++++++++++++++++++++++++++++++++
 3 files changed, 332 insertions(+)
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index a5c5f70..954749a 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -133,6 +133,18 @@ config ARM_MEDIATEK_CPUFREQ
 	help
 	  This adds the CPUFreq driver support for MediaTek SoCs.
 
+config ARM_MEDIATEK_CPUFREQ_HW
+	tristate "MediaTek CPUFreq HW driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	default m
+	help
+	  Support for the CPUFreq HW driver.
+	  Some MediaTek chipsets have a HW engine to offload the steps
+	  necessary for changing the frequency of the CPUs. Firmware loaded
+	  in this engine exposes a programming interface to the OS.
+	  The driver implements the cpufreq interface for this HW engine.
+	  Say Y if you want to support CPUFreq HW.
+
 config ARM_OMAP2PLUS_CPUFREQ
 	bool "TI OMAP2+"
 	depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 27d3bd7..48ee585 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6q-cpufreq.o
 obj-$(CONFIG_ARM_IMX_CPUFREQ_DT)	+= imx-cpufreq-dt.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)	+= kirkwood-cpufreq.o
 obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ)	+= mediatek-cpufreq.o
+obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW)	+= mediatek-cpufreq-hw.o
 obj-$(CONFIG_MACH_MVEBU_V7)		+= mvebu-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)	+= pxa2xx-cpufreq.o
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
new file mode 100644
index 0000000..79862a5
--- /dev/null
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 MediaTek Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/cpufreq.h>
+#include <linux/energy_model.h>
+#include <linux/init.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/pm_qos.h>
+#include <linux/slab.h>
+
+#define LUT_MAX_ENTRIES			32U
+#define LUT_FREQ			GENMASK(11, 0)
+#define LUT_ROW_SIZE			0x4
+#define CPUFREQ_HW_STATUS		BIT(0)
+#define SVS_HW_STATUS			BIT(1)
+#define POLL_USEC			1000
+#define TIMEOUT_USEC			300000
+
+enum {
+	REG_FREQ_LUT_TABLE,
+	REG_FREQ_ENABLE,
+	REG_FREQ_PERF_STATE,
+	REG_FREQ_HW_STATE,
+	REG_EM_POWER_TBL,
+	REG_FREQ_LATENCY,
+
+	REG_ARRAY_SIZE,
+};
+
+struct mtk_cpufreq_data {
+	struct cpufreq_frequency_table *table;
+	void __iomem *reg_bases[REG_ARRAY_SIZE];
+	int nr_opp;
+};
+
+static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
+	[REG_FREQ_LUT_TABLE]	= 0x0,
+	[REG_FREQ_ENABLE]	= 0x84,
+	[REG_FREQ_PERF_STATE]	= 0x88,
+	[REG_FREQ_HW_STATE]	= 0x8c,
+	[REG_EM_POWER_TBL]	= 0x90,
+	[REG_FREQ_LATENCY]	= 0x110,
+};
+
+static int __maybe_unused
+mtk_cpufreq_get_cpu_power(unsigned long *mW,
+			  unsigned long *KHz, struct device *cpu_dev)
+{
+	struct mtk_cpufreq_data *data;
+	struct cpufreq_policy *policy;
+	int i;
+
+	policy = cpufreq_cpu_get_raw(cpu_dev->id);
+	if (!policy)
+		return 0;
+
+	data = policy->driver_data;
+
+	for (i = 0; i < data->nr_opp; i++) {
+		if (data->table[i].frequency < *KHz)
+			break;
+	}
+	i--;
+
+	*KHz = data->table[i].frequency;
+	*mW = readl_relaxed(data->reg_bases[REG_EM_POWER_TBL] +
+			    i * LUT_ROW_SIZE) / 1000;
+
+	return 0;
+}
+
+static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+				       unsigned int index)
+{
+	struct mtk_cpufreq_data *data = policy->driver_data;
+
+	writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);
+
+	return 0;
+}
+
+static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
+{
+	struct mtk_cpufreq_data *data;
+	struct cpufreq_policy *policy;
+	unsigned int index;
+
+	policy = cpufreq_cpu_get_raw(cpu);
+	if (!policy)
+		return 0;
+
+	data = policy->driver_data;
+
+	index = readl_relaxed(data->reg_bases[REG_FREQ_PERF_STATE]);
+	index = min(index, LUT_MAX_ENTRIES - 1);
+
+	return data->table[index].frequency;
+}
+
+static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
+					       unsigned int target_freq)
+{
+	struct mtk_cpufreq_data *data = policy->driver_data;
+	unsigned int index;
+
+	index = cpufreq_table_find_index_dl(policy, target_freq);
+
+	writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);
+
+	return policy->freq_table[index].frequency;
+}
+
+static int mtk_cpu_create_freq_table(struct platform_device *pdev,
+				     struct mtk_cpufreq_data *data)
+{
+	struct device *dev = &pdev->dev;
+	void __iomem *base_table;
+	u32 temp, i, freq, prev_freq = 0;
+
+	data->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
+				   sizeof(*data->table), GFP_KERNEL);
+	if (!data->table)
+		return -ENOMEM;
+
+	base_table = data->reg_bases[REG_FREQ_LUT_TABLE];
+
+	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
+		temp = readl_relaxed(base_table + (i * LUT_ROW_SIZE));
+		freq = FIELD_GET(LUT_FREQ, temp) * 1000;
+
+		if (freq == prev_freq)
+			break;
+
+		data->table[i].frequency = freq;
+
+		dev_dbg(dev, "index=%d freq=%d\n", i, data->table[i].frequency);
+
+		prev_freq = freq;
+	}
+
+	data->table[i].frequency = CPUFREQ_TABLE_END;
+	data->nr_opp = i;
+
+	return 0;
+}
+
+static int mtk_cpu_resources_init(struct platform_device *pdev,
+				  struct cpufreq_policy *policy,
+				  const u16 *offsets)
+{
+	struct mtk_cpufreq_data *data;
+	struct device *dev = &pdev->dev;
+	void __iomem *base;
+	int ret, i;
+	int index;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	index = of_perf_domain_get_sharing_cpumask(policy->cpu, "performance-domains",
+						   "#performance-domain-cells",
+						   policy->cpus);
+
+	base = devm_platform_ioremap_resource(pdev, index);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
+		data->reg_bases[i] = base + offsets[i];
+
+	ret = mtk_cpu_create_freq_table(pdev, data);
+	if (ret) {
+		dev_info(dev, "Domain-%d failed to create freq table\n", index);
+		return ret;
+	}
+
+	policy->freq_table = data->table;
+	policy->driver_data = data;
+
+	return 0;
+}
+
+static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
+{
+	struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
+	struct platform_device *pdev = cpufreq_get_driver_data();
+	int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;
+	struct mtk_cpufreq_data *data;
+	struct device *cpu_dev;
+	unsigned int latency;
+	const u16 *offsets;
+	int ret;
+
+	offsets = of_device_get_match_data(&pdev->dev);
+	if (!offsets)
+		return -EINVAL;
+
+	/* Get the bases of cpufreq for domains */
+	ret = mtk_cpu_resources_init(pdev, policy, offsets);
+	if (ret) {
+		dev_info(&pdev->dev, "CPUFreq resource init failed\n");
+		return ret;
+	}
+
+	data = policy->driver_data;
+
+	latency = readl_relaxed(data->reg_bases[REG_FREQ_LATENCY]) * 1000;
+	if (!latency)
+		latency = CPUFREQ_ETERNAL;
+
+	/* us convert to ns */
+	policy->cpuinfo.transition_latency = latency;
+
+	policy->fast_switch_possible = true;
+
+	/* HW should be in enabled state to proceed now */
+	writel_relaxed(0x1, data->reg_bases[REG_FREQ_ENABLE]);
+	if (readl_poll_timeout(data->reg_bases[REG_FREQ_HW_STATE], sig,
+			       (sig & pwr_hw) == pwr_hw, POLL_USEC,
+			       TIMEOUT_USEC)) {
+		if (!(sig & CPUFREQ_HW_STATUS)) {
+			pr_info("cpufreq hardware of CPU%d is not enabled\n",
+				policy->cpu);
+			return -ENODEV;
+		}
+
+		pr_info("SVS of CPU%d is not enabled\n", policy->cpu);
+	}
+
+	cpu_dev = get_cpu_device(policy->cpu);
+	if (!cpu_dev) {
+		pr_info("failed to get cpu%d device\n", policy->cpu);
+		return -ENODEV;
+	}
+
+	em_dev_register_perf_domain(cpu_dev, data->nr_opp, &em_cb, policy->cpus,
+				    true);
+
+	return 0;
+}
+
+static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
+{
+	struct mtk_cpufreq_data *data = policy->driver_data;
+	void __iomem *base;
+	int i;
+
+	/* HW should be in paused state now */
+	writel_relaxed(0x0, data->reg_bases[REG_FREQ_ENABLE]);
+
+	for (i = 0; i < REG_ARRAY_SIZE; i++) {
+		base = data->reg_bases[i];
+		iounmap(base);
+	}
+
+	kfree(data->table);
+	kfree(data);
+
+	return 0;
+}
+
+static struct cpufreq_driver cpufreq_mtk_hw_driver = {
+	.flags		= CPUFREQ_NEED_INITIAL_FREQ_CHECK |
+			  CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
+			  CPUFREQ_IS_COOLING_DEV,
+	.verify		= cpufreq_generic_frequency_table_verify,
+	.target_index	= mtk_cpufreq_hw_target_index,
+	.get		= mtk_cpufreq_hw_get,
+	.init		= mtk_cpufreq_hw_cpu_init,
+	.exit		= mtk_cpufreq_hw_cpu_exit,
+	.fast_switch	= mtk_cpufreq_hw_fast_switch,
+	.name		= "mtk-cpufreq-hw",
+	.attr		= cpufreq_generic_attr,
+};
+
+static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	cpufreq_mtk_hw_driver.driver_data = pdev;
+
+	ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver);
+	if (ret)
+		dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");
+
+	return ret;
+}
+
+static int mtk_cpufreq_hw_driver_remove(struct platform_device *pdev)
+{
+	return cpufreq_unregister_driver(&cpufreq_mtk_hw_driver);
+}
+
+static const struct of_device_id mtk_cpufreq_hw_match[] = {
+	{ .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_offsets },
+	{}
+};
+
+static struct platform_driver mtk_cpufreq_hw_driver = {
+	.probe = mtk_cpufreq_hw_driver_probe,
+	.remove = mtk_cpufreq_hw_driver_remove,
+	.driver = {
+		.name = "mtk-cpufreq-hw",
+		.of_match_table = mtk_cpufreq_hw_match,
+	},
+};
+module_platform_driver(mtk_cpufreq_hw_driver);
+
+MODULE_AUTHOR("Hector Yuan <hector.yuan at mediatek.com>");
+MODULE_DESCRIPTION("Mediatek cpufreq-hw driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5

From hector.yuan at mediatek.com  Sat Aug 28 08:01:09 2021
From: hector.yuan at mediatek.com (Hector Yuan)
Date: Sat, 28 Aug 2021 23:01:09 +0800
Subject: [PATCH v14] cpufreq: mediatek-hw: Add support for Mediatek cpufreq HW
 driver
Message-ID: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>

The CPUfreq HW present in some Mediatek chipsets offloads the steps necessary for changing the frequency of CPUs. 
The driver implements the cpufreq driver interface for this hardware engine. 

From v13 to v14, there are three modifications.
1. Replace cpu domain map to policy driver data 
2. Remove dummy performance-domain parsing
3. Separate modification in cpufreq.h to another patch

From v12 to v13, there are two modifications.
1. Move related_cpus function to common place, so all performance-domain cpufreq driver can refer.
2. Make cpu resource init to each policy rather than per-cpu

From v11 to v12, there are two modifications.
1. Based on patchset[1], align binding with scmi for performance domain(latest version).
2. Shrink binding example wording. 

From v8 to v9, there are three more modifications.
1. Based on patchset[2], align binding with scmi for performance domain.
2. Add the CPUFREQ fast switch function support and define DVFS latency.
3. Based on patchser[3], add energy model API parameter for mW.

From v7 to v8, there are three more patches based on patchset v8[4].
This patchset is about to register power table to Energy model for EAS and thermal usage.
1. EM CPU power table
- Register energy model table for EAS and thermal cooling device usage.
- Read the coresponding LUT for power table.
2. SVS initialization
- The SVS(Smart Voltage Scaling) engine is a hardware which is
  used to calculate optimized voltage values for CPU power domain.
  DVFS driver could apply those optimized voltage values to reduce power consumption.
- Driver will polling if HW engine is done for SVS initialization.
  After that, driver will read power table and register it to EAS.
- CPUs must be in power on state when doing SVS. Use pm_qos to block cpu-idle state for SVS initializing.
3. Cooling device flag
- Add cooling device flag for thermal
[1]  https://lore.kernel.org/linux-devicetree/20210517155458.1016707-1-sudeep.holla at arm.com/
[2]  https://lore.kernel.org/lkml/20201116181356.804590-1-sudeep.holla at arm.com/
[3]  https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/commit/?h=linux-next&id=c250d50fe2ce627ca9805d9c8ac11cbbf922a4a6
[4]  https://lkml.org/lkml/2020/9/23/384


Hector.Yuan (3):
  ndings: cpufreq: add bindings for MediaTek cpufreq HW
  cpufreq: Add of_perf_domain_get_sharing_cpumask
  cpufreq: mediatek-hw: Add support for CPUFREQ HW

 .../bindings/cpufreq/cpufreq-mediatek-hw.yaml |  70 ++++
 drivers/cpufreq/Kconfig.arm                   |  12 +
 drivers/cpufreq/Makefile                      |   1 +
 drivers/cpufreq/mediatek-cpufreq-hw.c         | 319 ++++++++++++++++++
 include/linux/cpufreq.h                       |  39 +++
 5 files changed, 441 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
 create mode 100644 drivers/cpufreq/mediatek-cpufreq-hw.c

From martin.blumenstingl at googlemail.com  Sat Aug 28 08:53:54 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 17:53:54 +0200
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <20210817041548.1276-2-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
Message-ID: <CAFBinCBnH1UqaiuHgTXZTH+RPOwCWiWLVheU=bydS4mfkxTP3g@mail.gmail.com>

Hi Anand,

sorry for the late reply
I have three very small comments below, apart from these, this is looking good!

On Tue, Aug 17, 2021 at 6:17 AM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Add missing usb phy power node for usb node fix below warning.
> P5V0 regulator supply input voltage range to USB host controller.
> As described in the C1+ schematics, GPIO GPIOAO_5 is used to
> enable input power to USB ports, set it to Active Low.
I would phrase this last sentence as:
"enable USB VBUS on the Micro-USB port using an active high signal"
My idea here is to 1) clarify that it's about enabling USB VBUS only
on the Micro-USB port and 2) use "active high" like the changes inside
the patch itself

> [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
> [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
>                 mode /soc/usb at c90c0000 failed
>
> Fixes: 2eb79a4d15ff (ARM: dts: meson: enabling the USB Host
>                 controller on Odroid-C1/C1+ board)
>
please drop this empty line

[...]
> @@ -119,7 +136,6 @@ vcc_3v3: regulator-vcc-3v3 {
>                 regulator-name = "VCC3V3";
>                 regulator-min-microvolt = <3300000>;
>                 regulator-max-microvolt = <3300000>;
> -
I don't think that we should make any VCC3V3 regulator changes in this patch
so please keep this empty line as-is.


Best regards,
Martin


From martin.blumenstingl at googlemail.com  Sat Aug 28 08:56:08 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 17:56:08 +0200
Subject: [PATCHv3 2/6] ARM: dts: meson8b: odroidc1: Set usb power source
 to always on
In-Reply-To: <20210817041548.1276-3-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-3-linux.amoon@gmail.com>
Message-ID: <CAFBinCB8CK8Bn2xKpiAToQQ4K1_W1XZjND9pOGZRZeMp-grs3Q@mail.gmail.com>

Hi Anand,

On Tue, Aug 17, 2021 at 6:17 AM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Set P5V0 and vcc_3v3 power source to USB to always on
> so that regulator should not enter in suspend state.
Neither of these two regulators can be controlled by Linux in any way
(there's no GPIO to turn them off, no PWM signal to change the output
voltage, etc.).
So can you please explain what this patch changes from a functional perspective?


Best regards,
Martin


From martin.blumenstingl at googlemail.com  Sat Aug 28 09:00:28 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 18:00:28 +0200
Subject: [PATCHv3 3/6] arm64: dts: amlogic: odroidc2: Fix the chip enable
 signal for usb power
In-Reply-To: <20210817041548.1276-4-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-4-linux.amoon@gmail.com>
Message-ID: <CAFBinCAx33SnuL8n1GF8nz2Q4giNR8tsWxjU32X0wsb6kR_nhw@mail.gmail.com>

Hi Anand,

On Tue, Aug 17, 2021 at 6:17 AM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Fix the chip enable signal changing from Active High to Active Low
> to enable input power to USB power. Also updated signal name as per
> the schematics.
according to [0] (page 12) Odroid-C2 uses an "RT9715EGB" for USB OTG power
The datasheet for that power switch [1] mentions on page page 1 that
the "E" stands for "E : 1.1A/Active High"

Can you please elaborate how you have tested this to confirm that
active low is the correct polarity?


Best regards,
Martin


[0] https://dn.odroid.com/S905/Schematic/odroid-c2_rev0.1_20150930.pdf
[1] https://www.richtek.com/assets/product_file/RT9715/DS9715-03.pdf


From martin.blumenstingl at googlemail.com  Sat Aug 28 09:06:55 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 18:06:55 +0200
Subject: [PATCHv3 4/6] arm64: dts: amlogic: odroidc2: use vbus-supply for
 power source for usb nodes
In-Reply-To: <20210817041548.1276-5-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-5-linux.amoon@gmail.com>
Message-ID: <CAFBinCDDASbbwBWdPnzq4352yepamD-ziG09Ki=BvjZ9xMLXdQ@mail.gmail.com>

Hi Anand,

On Tue, Aug 17, 2021 at 6:18 AM Anand Moon <linux.amoon at gmail.com> wrote:
>
> Use vbus-supply instead of phy-supply as power source for dwc2
> nodes. Drop vbus-supply for usb0 node, as it will handle later.
This is more of a question than a review comment:
Do you think that the USB power setup on Odroid-C1 and Odroid-C2 is
different or the same?
On Odroid-C1 we know that only the PWREN signal which goes to the
Micro-USB connector is configurable while VBUS for the USB host ports
is always enabled.

> Fixes: e841ec956e53 ("ARM64: dts: meson-gxbb-odroidc2:
>        fix usb1 power supply")
>
most Linux commits which I have seen don't use a blank line here
Also I think it's recommended not to break the "Fixes" tag into
multiple lines, even if the text is long
see [0] for example


Best regards,
Martin


[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=425bec0032f59eeee12520085cd054fac09cc66e


From martin.blumenstingl at googlemail.com  Sat Aug 28 09:11:59 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 28 Aug 2021 18:11:59 +0200
Subject: [PATCH] arm64: dts: meson: sm1: add Ethernet PHY reset line for
 ODROID-C4/HC4
In-Reply-To: <YScKYFWlYymgGw3l@anyang-linuxfactory-or-kr>
References: <YScKYFWlYymgGw3l@anyang-linuxfactory-or-kr>
Message-ID: <CAFBinCDLmmtKztpoj5xvhwdagrH_7nJK7qUA+LOg7CWB5eCFRQ@mail.gmail.com>

Hi,

Thanks for this patch!

my first suggestion is about the patch subject (first line):
arm64: dts: meson-sm1-odroid: add Ethernet PHY reset for ODROID-C4/HC4

This makes it match the pattern of the most recent commits there:
45d736ab17b4 arm64: dts: meson-sm1-odroid: add 5v regulator gpio
7881df513680 arm64: dts: meson-sm1-odroid: set tf_io regulator gpio as
open source

On Thu, Aug 26, 2021 at 5:29 AM Dongjin Kim <tobetter at gmail.com> wrote:
>
> This patch is to fix an issue that the ethernet link doesn't come up
> when using ip link set down/up:
>    [   11.428114] meson8b-dwmac ff3f0000.ethernet eth0: Link is Down
>    [   14.428595] meson8b-dwmac ff3f0000.ethernet eth0: PHY [0.0:00] driver [RTL8211F Gigabit Ethernet] (irq=31)
>    [   14.428610] meson8b-dwmac ff3f0000.ethernet: Failed to reset the dma
>    [   14.428974] meson8b-dwmac ff3f0000.ethernet eth0: stmmac_hw_setup: DMA engine initialization failed
>    [   14.711185] meson8b-dwmac ff3f0000.ethernet eth0: stmmac_open: Hw setup failed
>
> This fix has been referred two commits applied for ODROID-N2 (G12B).
>     commit 658e4129bb81 ("arm64: dts: meson: g12b: odroid-n2: add the Ethernet PHY reset line")
>     commit 1c7412530d5d0 ("arm64: dts: meson: g12b: odroid-n2: fix PHY deassert timing requirements")
I am not 100% sure but I think you can just add two "Fixes: ..." tags here
That way this patch is also backported automatically

> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From linux at roeck-us.net  Sat Aug 28 09:23:49 2021
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 28 Aug 2021 09:23:49 -0700
Subject: [PATCH v2 2/3] dt-bindings: watchdog: sunxi: Add compatible for D1
In-Reply-To: <20210805045716.46141-2-samuel@sholland.org>
References: <20210805045716.46141-1-samuel@sholland.org>
 <20210805045716.46141-2-samuel@sholland.org>
Message-ID: <20210828162349.GA824322@roeck-us.net>

On Wed, Aug 04, 2021 at 11:57:15PM -0500, Samuel Holland wrote:
> D1 keeps the same register layout and clock sources as the R329, but it
> adds a key field which must be set to update the watchdog's "CFG" and
> "MODE" registers. Therefore it is not backward-compatible.
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Samuel Holland <samuel at sholland.org>
> Acked-by: Maxime Ripard <maxime at cerno.tech>

Acked-by: Guenter Roeck <linux at roeck-us.net>

> ---
> Changes v1 to v2:
>  - None.
> 
>  .../devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml   | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> index 8fa5b0d32381..6ef5e7caae80 100644
> --- a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> +++ b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml
> @@ -29,6 +29,7 @@ properties:
>        - items:
>            - const: allwinner,suniv-f1c100s-wdt
>            - const: allwinner,sun4i-a10-wdt
> +      - const: allwinner,sun20i-d1-wdt
>  
>    reg:
>      maxItems: 1
> @@ -61,6 +62,7 @@ if:
>      compatible:
>        contains:
>          enum:
> +          - allwinner,sun20i-d1-wdt
>            - allwinner,sun50i-r329-wdt
>  
>  then:


From andrew at lunn.ch  Sat Aug 28 10:07:08 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Sat, 28 Aug 2021 19:07:08 +0200
Subject: [PATCH 3/5] ARM: dts: NSP: Fix MDIO mux node names
In-Reply-To: <20210828112704.2283805-3-mnhagan88@gmail.com>
References: <20210828112704.2283805-1-mnhagan88@gmail.com>
 <20210828112704.2283805-3-mnhagan88@gmail.com>
Message-ID: <YSptPF8MKNahkMbm@lunn.ch>

On Sat, Aug 28, 2021 at 11:27:01AM +0000, Matthew Hagan wrote:
> This patch fixes the following message by adding "mdio-mux" compatible:
> compatible: ['mdio-mux-mmioreg'] is too short
 
Err, what? This sounds like a workaround for a tool problem, not a
real fix. 

What is actually wrong with:

compatible = "mdio-mux-mmioreg";

	   Andrew


From peterz at infradead.org  Sat Aug 28 12:44:21 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Sat, 28 Aug 2021 21:44:21 +0200
Subject: [PATCH v2 01/13] perf: Ensure perf_guest_cbs aren't reloaded
 between !NULL check and deref
In-Reply-To: <20210828003558.713983-2-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
 <20210828003558.713983-2-seanjc@google.com>
Message-ID: <20210828194421.GB4353@worktop.programming.kicks-ass.net>

On Fri, Aug 27, 2021 at 05:35:46PM -0700, Sean Christopherson wrote:

> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 2d510ad750ed..6b0405e578c1 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -1237,6 +1237,14 @@ extern void perf_event_bpf_event(struct bpf_prog *prog,
>  				 u16 flags);
>  
>  extern struct perf_guest_info_callbacks *perf_guest_cbs;
> +static inline struct perf_guest_info_callbacks *perf_get_guest_cbs(void)
> +{
> +	/* Reg/unreg perf_guest_cbs waits for readers via synchronize_rcu(). */
> +	lockdep_assert_preemption_disabled();
> +
> +	/* Prevent reloading between a !NULL check and dereferences. */
> +	return READ_ONCE(perf_guest_cbs);
> +}

Nice..

>  extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
>  extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
>  
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 464917096e73..2126f6327321 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6491,14 +6491,19 @@ struct perf_guest_info_callbacks *perf_guest_cbs;
>  
>  int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
>  {
> -	perf_guest_cbs = cbs;
> +	if (WARN_ON_ONCE(perf_guest_cbs))
> +		return -EBUSY;
> +
> +	WRITE_ONCE(perf_guest_cbs, cbs);
> +	synchronize_rcu();

You're waiting for all NULL users to go away? :-) IOW, we can do without
this synchronize_rcu() call.

>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
>  
>  int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
>  {
> -	perf_guest_cbs = NULL;

	if (WARN_ON_ONCE(perf_guest_cbs != cbs))
		return -EBUSY;

?

> +	WRITE_ONCE(perf_guest_cbs, NULL);
> +	synchronize_rcu();
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);

Yes, this ought to work fine.


From peterz at infradead.org  Sat Aug 28 12:47:52 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Sat, 28 Aug 2021 21:47:52 +0200
Subject: [PATCH v2 05/13] perf: Force architectures to opt-in to guest
 callbacks
In-Reply-To: <20210828003558.713983-6-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
 <20210828003558.713983-6-seanjc@google.com>
Message-ID: <20210828194752.GC4353@worktop.programming.kicks-ass.net>

On Fri, Aug 27, 2021 at 05:35:50PM -0700, Sean Christopherson wrote:
> diff --git a/init/Kconfig b/init/Kconfig
> index 55f9f7738ebb..9ef51ae53977 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1776,6 +1776,9 @@ config HAVE_PERF_EVENTS
>  	help
>  	  See tools/perf/design.txt for details.
>  
> +config HAVE_GUEST_PERF_EVENTS
> +	bool
	depends on HAVE_KVM

?

> +
>  config PERF_USE_VMALLOC
>  	bool
>  	help


From lkp at intel.com  Sat Aug 28 12:49:28 2021
From: lkp at intel.com (kernel test robot)
Date: Sun, 29 Aug 2021 03:49:28 +0800
Subject: [xlnx:master 368/407]
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c:2650:5: sparse: sparse:
 symbol 'axienet_ethtools_sset_count' was not declared. Should it be static?
Message-ID: <202108290302.uGuXaGi7-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   959c29b000f2d8576c7b56b53e559db140ee3952
commit: 0605a36e057480f3a83ae401e7ff59739da78e82 [368/407] net: xilinx: Ethtool statistics support
config: arm-randconfig-s032-20210827 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-348-gf0e6938b-dirty
        # https://github.com/Xilinx/linux-xlnx/commit/0605a36e057480f3a83ae401e7ff59739da78e82
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx master
        git checkout 0605a36e057480f3a83ae401e7ff59739da78e82
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>


sparse warnings: (new ones prefixed by >>)
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:37: sparse: sparse: cast to restricted __be32
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:37: sparse: sparse: cast to restricted __be32
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:37: sparse: sparse: cast to restricted __be32
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:37: sparse: sparse: cast to restricted __be32
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:37: sparse: sparse: cast to restricted __be32
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:37: sparse: sparse: cast to restricted __be32
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:35: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __wsum [usertype] csum @@     got unsigned int @@
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:35: sparse:     expected restricted __wsum [usertype] csum
   drivers/net/ethernet/xilinx/xilinx_axienet_main.c:1572:35: sparse:     got unsigned int
>> drivers/net/ethernet/xilinx/xilinx_axienet_main.c:2650:5: sparse: sparse: symbol 'axienet_ethtools_sset_count' was not declared. Should it be static?
>> drivers/net/ethernet/xilinx/xilinx_axienet_main.c:2673:6: sparse: sparse: symbol 'axienet_ethtools_get_stats' was not declared. Should it be static?
>> drivers/net/ethernet/xilinx/xilinx_axienet_main.c:2700:6: sparse: sparse: symbol 'axienet_ethtools_strings' was not declared. Should it be static?

vim +/axienet_ethtools_sset_count +2650 drivers/net/ethernet/xilinx/xilinx_axienet_main.c

  2640	
  2641	/**
  2642	 * axienet_ethtools_sset_count - Get number of strings that
  2643	 *				 get_strings will write.
  2644	 * @ndev:	Pointer to net_device structure
  2645	 * @sset:	Get the set strings
  2646	 *
  2647	 * Return: number of strings, on success, Non-zero error value on
  2648	 *	   failure.
  2649	 */
> 2650	int axienet_ethtools_sset_count(struct net_device *ndev, int sset)
  2651	{
  2652		switch (sset) {
  2653		case ETH_SS_STATS:
  2654	#ifdef CONFIG_AXIENET_HAS_MCDMA
  2655			return axienet_sset_count(ndev, sset);
  2656	#else
  2657			return AXIENET_ETHTOOLS_SSTATS_LEN;
  2658	#endif
  2659		default:
  2660			return -EOPNOTSUPP;
  2661		}
  2662	}
  2663	
  2664	/**
  2665	 * axienet_ethtools_get_stats - Get the extended statistics
  2666	 *				about the device.
  2667	 * @ndev:	Pointer to net_device structure
  2668	 * @stats:	Pointer to ethtool_stats structure
  2669	 * @data:	To store the statistics values
  2670	 *
  2671	 * Return: None.
  2672	 */
> 2673	void axienet_ethtools_get_stats(struct net_device *ndev,
  2674					struct ethtool_stats *stats,
  2675					u64 *data)
  2676	{
  2677		unsigned int i = 0;
  2678	
  2679		data[i++] = ndev->stats.tx_packets;
  2680		data[i++] = ndev->stats.rx_packets;
  2681		data[i++] = ndev->stats.tx_bytes;
  2682		data[i++] = ndev->stats.rx_bytes;
  2683		data[i++] = ndev->stats.tx_errors;
  2684		data[i++] = ndev->stats.rx_missed_errors + ndev->stats.rx_frame_errors;
  2685	
  2686	#ifdef CONFIG_AXIENET_HAS_MCDMA
  2687		axienet_get_stats(ndev, stats, data);
  2688	#endif
  2689	}
  2690	
  2691	/**
  2692	 * axienet_ethtools_strings - Set of strings that describe
  2693	 *			 the requested objects.
  2694	 * @ndev:	Pointer to net_device structure
  2695	 * @sset:	Get the set strings
  2696	 * @data:	Data of Transmit and Receive statistics
  2697	 *
  2698	 * Return: None.
  2699	 */
> 2700	void axienet_ethtools_strings(struct net_device *ndev, u32 sset, u8 *data)
  2701	{
  2702		int i;
  2703	
  2704		for (i = 0; i < AXIENET_ETHTOOLS_SSTATS_LEN; i++) {
  2705			if (sset == ETH_SS_STATS)
  2706				memcpy(data + i * ETH_GSTRING_LEN,
  2707				       axienet_get_ethtools_strings_stats[i].name,
  2708				       ETH_GSTRING_LEN);
  2709		}
  2710	#ifdef CONFIG_AXIENET_HAS_MCDMA
  2711		axienet_strings(ndev, sset, data);
  2712	#endif
  2713	}
  2714	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 32992 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210829/36416dfa/attachment-0001.gz>

From peterz at infradead.org  Sat Aug 28 13:13:36 2021
From: peterz at infradead.org (Peter Zijlstra)
Date: Sat, 28 Aug 2021 22:13:36 +0200
Subject: [PATCH v2 00/13] perf: KVM: Fix, optimize, and clean up callbacks
In-Reply-To: <20210828003558.713983-1-seanjc@google.com>
References: <20210828003558.713983-1-seanjc@google.com>
Message-ID: <20210828201336.GD4353@worktop.programming.kicks-ass.net>

On Fri, Aug 27, 2021 at 05:35:45PM -0700, Sean Christopherson wrote:
> Like Xu (2):
>   perf/core: Rework guest callbacks to prepare for static_call support
>   perf/core: Use static_call to optimize perf_guest_info_callbacks
> 
> Sean Christopherson (11):
>   perf: Ensure perf_guest_cbs aren't reloaded between !NULL check and
>     deref
>   KVM: x86: Register perf callbacks after calling vendor's
>     hardware_setup()
>   KVM: x86: Register Processor Trace interrupt hook iff PT enabled in
>     guest
>   perf: Stop pretending that perf can handle multiple guest callbacks
>   perf: Force architectures to opt-in to guest callbacks
>   KVM: x86: Drop current_vcpu for kvm_running_vcpu + kvm_arch_vcpu
>     variable
>   KVM: x86: More precisely identify NMI from guest when handling PMI
>   KVM: Move x86's perf guest info callbacks to generic KVM
>   KVM: x86: Move Intel Processor Trace interrupt handler to vmx.c
>   KVM: arm64: Convert to the generic perf callbacks
>   KVM: arm64: Drop perf.c and fold its tiny bits of code into arm.c /
>     pmu.c

Lets keep the whole intel_pt crud inside x86...

---
Index: linux-2.6/arch/x86/events/core.c
===================================================================
--- linux-2.6.orig/arch/x86/events/core.c
+++ linux-2.6/arch/x86/events/core.c
@@ -92,7 +92,7 @@ DEFINE_STATIC_CALL_RET0(x86_pmu_guest_ge
 
 DEFINE_STATIC_CALL_RET0(x86_guest_state, *(perf_guest_cbs->state));
 DEFINE_STATIC_CALL_RET0(x86_guest_get_ip, *(perf_guest_cbs->get_ip));
-DEFINE_STATIC_CALL_RET0(x86_guest_handle_intel_pt_intr, *(perf_guest_cbs->handle_intel_pt_intr));
+DEFINE_STATIC_CALL_RET0(x86_guest_handle_intel_pt_intr, unsigned int (*)(void));
 
 void arch_perf_update_guest_cbs(struct perf_guest_info_callbacks *guest_cbs)
 {
@@ -103,14 +103,6 @@ void arch_perf_update_guest_cbs(struct p
 		static_call_update(x86_guest_state, (void *)&__static_call_return0);
 		static_call_update(x86_guest_get_ip, (void *)&__static_call_return0);
 	}
-
-	/* Implementing ->handle_intel_pt_intr is optional. */
-	if (guest_cbs && guest_cbs->handle_intel_pt_intr)
-		static_call_update(x86_guest_handle_intel_pt_intr,
-				   guest_cbs->handle_intel_pt_intr);
-	else
-		static_call_update(x86_guest_handle_intel_pt_intr,
-				   (void *)&__static_call_return0);
 }
 
 u64 __read_mostly hw_cache_event_ids
Index: linux-2.6/arch/x86/events/intel/core.c
===================================================================
--- linux-2.6.orig/arch/x86/events/intel/core.c
+++ linux-2.6/arch/x86/events/intel/core.c
@@ -2782,7 +2782,7 @@ static void intel_pmu_reset(void)
 	local_irq_restore(flags);
 }
 
-DECLARE_STATIC_CALL(x86_guest_handle_intel_pt_intr, *(perf_guest_cbs->handle_intel_pt_intr));
+DECLARE_STATIC_CALL(x86_guest_handle_intel_pt_intr, unsigned int (*)(void));
 
 static int handle_pmi_common(struct pt_regs *regs, u64 status)
 {
Index: linux-2.6/arch/x86/kvm/x86.c
===================================================================
--- linux-2.6.orig/arch/x86/kvm/x86.c
+++ linux-2.6/arch/x86/kvm/x86.c
@@ -10960,7 +10960,14 @@ int kvm_arch_hardware_setup(void *opaque
 	memcpy(&kvm_x86_ops, ops->runtime_ops, sizeof(kvm_x86_ops));
 	kvm_ops_static_call_update();
 
-	kvm_register_perf_callbacks(ops->handle_intel_pt_intr);
+	kvm_register_perf_callbacks();
+	if (ops->handle_intel_pt_intr) {
+		static_call_update(x86_guest_handle_intel_pt_intr,
+				   ops->handle_intel_pt_intr);
+	} else {
+		static_call_update(x86_guest_handle_intel_pt_intr,
+				   (void *)&__static_call_return0);
+	}
 
 	if (!kvm_cpu_cap_has(X86_FEATURE_XSAVES))
 		supported_xss = 0;
Index: linux-2.6/include/linux/perf_event.h
===================================================================
--- linux-2.6.orig/include/linux/perf_event.h
+++ linux-2.6/include/linux/perf_event.h
@@ -32,7 +32,6 @@
 struct perf_guest_info_callbacks {
 	unsigned int			(*state)(void);
 	unsigned long			(*get_ip)(void);
-	unsigned int			(*handle_intel_pt_intr)(void);
 };
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
Index: linux-2.6/virt/kvm/kvm_main.c
===================================================================
--- linux-2.6.orig/virt/kvm/kvm_main.c
+++ linux-2.6/virt/kvm/kvm_main.c
@@ -5374,12 +5374,10 @@ static unsigned long kvm_guest_get_ip(vo
 static struct perf_guest_info_callbacks kvm_guest_cbs = {
 	.state			= kvm_guest_state,
 	.get_ip			= kvm_guest_get_ip,
-	.handle_intel_pt_intr	= NULL,
 };
 
-void kvm_register_perf_callbacks(unsigned int (*pt_intr_handler)(void))
+void kvm_register_perf_callbacks(void)
 {
-	kvm_guest_cbs.handle_intel_pt_intr = pt_intr_handler;
 	perf_register_guest_info_callbacks(&kvm_guest_cbs);
 }
 #endif
Index: linux-2.6/arch/arm64/kvm/arm.c
===================================================================
--- linux-2.6.orig/arch/arm64/kvm/arm.c
+++ linux-2.6/arch/arm64/kvm/arm.c
@@ -1749,7 +1749,7 @@ static int init_subsystems(void)
 		goto out;
 
 	kvm_pmu_init();
-	kvm_register_perf_callbacks(NULL);
+	kvm_register_perf_callbacks();
 
 	kvm_sys_reg_table_init();
 
Index: linux-2.6/include/linux/kvm_host.h
===================================================================
--- linux-2.6.orig/include/linux/kvm_host.h
+++ linux-2.6/include/linux/kvm_host.h
@@ -1121,7 +1121,7 @@ static inline bool kvm_arch_intc_initial
 #ifdef __KVM_WANT_PERF_CALLBACKS
 unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu);
 
-void kvm_register_perf_callbacks(unsigned int (*pt_intr_handler)(void));
+void kvm_register_perf_callbacks(void);
 static inline void kvm_unregister_perf_callbacks(void)
 {
 	perf_unregister_guest_info_callbacks();


From mnhagan88 at gmail.com  Sat Aug 28 14:52:30 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sat, 28 Aug 2021 22:52:30 +0100
Subject: [PATCH 3/5] ARM: dts: NSP: Fix MDIO mux node names
In-Reply-To: <YSptPF8MKNahkMbm@lunn.ch>
References: <20210828112704.2283805-1-mnhagan88@gmail.com>
 <20210828112704.2283805-3-mnhagan88@gmail.com> <YSptPF8MKNahkMbm@lunn.ch>
Message-ID: <858a86de-c06e-0221-64ea-bb1790db398a@gmail.com>

On 28/08/2021 18:07, Andrew Lunn wrote:

> On Sat, Aug 28, 2021 at 11:27:01AM +0000, Matthew Hagan wrote:
>> This patch fixes the following message by adding "mdio-mux" compatible:
>> compatible: ['mdio-mux-mmioreg'] is too short
>  
> Err, what? This sounds like a workaround for a tool problem, not a
> real fix. 
>
> What is actually wrong with:
>
> compatible = "mdio-mux-mmioreg";

Yes this does work fine either with or without "mdio-mux". The changes
have been made to correspond with those submitted by Rafal Milecki for
the BCM5301X platform[1] and to conform with
Documentation/devicetree/bindings/net/mdio-mux-mmioreg.yaml
which does state both as required items (and hence not a tool problem).

[1] https://lore.kernel.org/linux-arm-kernel/20210822191256.3715003-1-f.fainelli at gmail.com/T/

>
> 	   Andrew
>
Matthew



From andrew at lunn.ch  Sat Aug 28 15:14:17 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 29 Aug 2021 00:14:17 +0200
Subject: [PATCH 3/5] ARM: dts: NSP: Fix MDIO mux node names
In-Reply-To: <858a86de-c06e-0221-64ea-bb1790db398a@gmail.com>
References: <20210828112704.2283805-1-mnhagan88@gmail.com>
 <20210828112704.2283805-3-mnhagan88@gmail.com>
 <YSptPF8MKNahkMbm@lunn.ch>
 <858a86de-c06e-0221-64ea-bb1790db398a@gmail.com>
Message-ID: <YSq1OS+z8KKcUdu5@lunn.ch>

On Sat, Aug 28, 2021 at 10:52:30PM +0100, Matthew Hagan wrote:
> On 28/08/2021 18:07, Andrew Lunn wrote:
> 
> > On Sat, Aug 28, 2021 at 11:27:01AM +0000, Matthew Hagan wrote:
> >> This patch fixes the following message by adding "mdio-mux" compatible:
> >> compatible: ['mdio-mux-mmioreg'] is too short
> >  
> > Err, what? This sounds like a workaround for a tool problem, not a
> > real fix. 
> >
> > What is actually wrong with:
> >
> > compatible = "mdio-mux-mmioreg";
> 
> Yes this does work fine either with or without "mdio-mux". The changes
> have been made to correspond with those submitted by Rafal Milecki for
> the BCM5301X platform[1] and to conform with
> Documentation/devicetree/bindings/net/mdio-mux-mmioreg.yaml
> which does state both as required items (and hence not a tool problem).

Hi Matthew

It would be good to expand the commit message a bit, since the error
'is too short' is particularly uninformative, and leads to questions
like this if not explained.

It would also good to get the tool improved, but that is out of scope
for this patch.

     Andrew


From lkp at intel.com  Sat Aug 28 16:43:59 2021
From: lkp at intel.com (kernel test robot)
Date: Sun, 29 Aug 2021 07:43:59 +0800
Subject: [soc:for-next] BUILD SUCCESS 5e115b419d2b931203f3531c4f284ae153cfa1ca
Message-ID: <612aca3f.ddrJs7qiO8OL2E9C%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: 5e115b419d2b931203f3531c4f284ae153cfa1ca  soc: document merges

elapsed time: 1478m

configs tested: 94
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20210827
mips                     cu1830-neo_defconfig
sh                          sdk7780_defconfig
x86_64                           alldefconfig
powerpc                   microwatt_defconfig
mips                          ath25_defconfig
openrisc                 simple_smp_defconfig
m68k                       m5249evb_defconfig
powerpc                      bamboo_defconfig
powerpc                       ppc64_defconfig
arm                        cerfcube_defconfig
powerpc                      chrp32_defconfig
arc                     haps_hs_smp_defconfig
nds32                             allnoconfig
mips                    maltaup_xpa_defconfig
powerpc                     kilauea_defconfig
arm                           sunxi_defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
x86_64                            allnoconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a014-20210829
x86_64               randconfig-a016-20210829
x86_64               randconfig-a015-20210829
x86_64               randconfig-a012-20210829
x86_64               randconfig-a013-20210829
x86_64               randconfig-a011-20210829
arc                  randconfig-r043-20210829
riscv                randconfig-r042-20210829
s390                 randconfig-r044-20210829
arc                  randconfig-r043-20210827
riscv                randconfig-r042-20210827
s390                 randconfig-r044-20210827
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a001-20210829
x86_64               randconfig-a006-20210829
x86_64               randconfig-a005-20210829
x86_64               randconfig-a003-20210829
x86_64               randconfig-a004-20210829
x86_64               randconfig-a002-20210829
i386                 randconfig-a011-20210828
i386                 randconfig-a016-20210828
i386                 randconfig-a012-20210828
i386                 randconfig-a014-20210828
i386                 randconfig-a013-20210828
i386                 randconfig-a015-20210828
hexagon              randconfig-r041-20210827
hexagon              randconfig-r045-20210827

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From oupton at google.com  Sat Aug 28 19:35:30 2021
From: oupton at google.com (Oliver Upton)
Date: Sun, 29 Aug 2021 02:35:30 +0000
Subject: [PATCH v7 3/7] KVM: arm64: Allow userspace to configure a vCPU's
 virtual offset
In-Reply-To: <20210816001217.3063400-4-oupton@google.com>
References: <20210816001217.3063400-1-oupton@google.com>
 <20210816001217.3063400-4-oupton@google.com>
Message-ID: <YSryci4dSuRAEg+g@google.com>

On Mon, Aug 16, 2021 at 12:12:13AM +0000, Oliver Upton wrote:
> Allow userspace to access the guest's virtual counter-timer offset
> through the ONE_REG interface. The value read or written is defined to
> be an offset from the guest's physical counter-timer. Add some
> documentation to clarify how a VMM should use this and the existing
> CNTVCT_EL0.
> 
> Signed-off-by: Oliver Upton <oupton at google.com>
> Reviewed-by: Andrew Jones <drjones at redhat.com>

Hrm...

I was mulling on this patch a bit more and had a thought. As previously
discussed, the patch implements virtual offsets by broadcasting the same
offset to all vCPUs in a guest. I wonder if this may tolerate bad
practices from userspace that will break when KVM supports NV.

Consider that a nested guest may set CNTVOFF_EL2 to whatever value it
wants. Presumably, we will need to patch the handling of CNTVOFF_EL2 to
*not* broadcast to all vCPUs to save/restore NV properly. If a maligned
VMM only wrote to a single vCPU, banking on this broadcasting
implementation, it will fall flat on its face when handling an NV guest.

So, should we preemptively move to the new way of the world, wherein
userspace accesses to CNTVOFF_EL2 are vCPU-local rather than VM-wide?

No strong opinions in either direction, but figured I'd address it since
I'll need to respin this series anyway to fix ECV+nVHE.

--
Thanks,
Oliver


From megous at megous.com  Sat Aug 28 19:51:30 2021
From: megous at megous.com (Ondrej Jirman)
Date: Sun, 29 Aug 2021 04:51:30 +0200
Subject: [PATCH] i2c: rk3x: Handle a spurious start completion interrupt flag
Message-ID: <20210829025130.1058877-1-megous@megous.com>

In a typical read transfer, start completion flag is being set after
read finishes (notice ipd bit 4 being set):

trasnfer poll=0
i2c start
rk3x-i2c fdd40000.i2c: IRQ: state 1, ipd: 10
i2c read
rk3x-i2c fdd40000.i2c: IRQ: state 2, ipd: 1b
i2c stop
rk3x-i2c fdd40000.i2c: IRQ: state 4, ipd: 33

This causes I2C transfer being aborted in polled mode from a stop completion
handler:

trasnfer poll=1
i2c start
rk3x-i2c fdd40000.i2c: IRQ: state 1, ipd: 10
i2c read
rk3x-i2c fdd40000.i2c: IRQ: state 2, ipd: 0
rk3x-i2c fdd40000.i2c: IRQ: state 2, ipd: 1b
i2c stop
rk3x-i2c fdd40000.i2c: IRQ: state 4, ipd: 13
i2c stop
rk3x-i2c fdd40000.i2c: unexpected irq in STOP: 0x10

Clearing the START flag after read fixes the issue without any obvious
side effects.

This issue was dicovered on RK3566 when adding support for powering
off the RK817 PMIC.

Signed-off-by: Ondrej Jirman <megous at megous.com>
---
 drivers/i2c/busses/i2c-rk3x.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index 819ab4ee517e..02ddb237f69a 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -423,8 +423,8 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
 	if (!(ipd & REG_INT_MBRF))
 		return;
 
-	/* ack interrupt */
-	i2c_writel(i2c, REG_INT_MBRF, REG_IPD);
+	/* ack interrupt (read also produces a spurious START flag, clear it too) */
+	i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD);
 
 	/* Can only handle a maximum of 32 bytes at a time */
 	if (len > 32)
-- 
2.33.0



From sboyd at kernel.org  Sat Aug 28 21:14:56 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 21:14:56 -0700
Subject: [RESEND PATCH 3/4] clk: mediatek: support COMMON_CLK_MT6779
 module build
In-Reply-To: <20210813032429.14715-4-miles.chen@mediatek.com>
References: <20210813032429.14715-1-miles.chen@mediatek.com>
 <20210813032429.14715-4-miles.chen@mediatek.com>
Message-ID: <163021049667.2676726.10138202396240942833@swboyd.mtv.corp.google.com>

Quoting Miles Chen (2021-08-12 20:24:28)
> diff --git a/drivers/clk/mediatek/clk-mt6779-aud.c b/drivers/clk/mediatek/clk-mt6779-aud.c
> index 11b209f95e25..439c0bc94b73 100644
> --- a/drivers/clk/mediatek/clk-mt6779-aud.c
> +++ b/drivers/clk/mediatek/clk-mt6779-aud.c
> @@ -4,6 +4,7 @@
>   * Author: Wendell Lin <wendell.lin at mediatek.com>
>   */
>  
> +#include <linux/module.h>
>  #include <linux/clk-provider.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
> @@ -115,3 +116,4 @@ static struct platform_driver clk_mt6779_aud_drv = {
>  };
>  
>  builtin_platform_driver(clk_mt6779_aud_drv);
> +MODULE_LICENSE("GPL");

How does this work? builtin_platform_driver() means that it's not
modular code. Shouldn't that be module_platform_driver()? Have you tried
loading and unloading the module?


From sboyd at kernel.org  Sat Aug 28 21:16:34 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 21:16:34 -0700
Subject: [GIT PULL] clk: imx: Updates for v5.15
In-Reply-To: <1629889173-5042-1-git-send-email-abel.vesa@nxp.com>
References: <1629889173-5042-1-git-send-email-abel.vesa@nxp.com>
Message-ID: <163021059444.2676726.13636736135059270626@swboyd.mtv.corp.google.com>

Quoting Abel Vesa (2021-08-25 03:59:33)
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git/ tags/clk-imx-5.15
> 
> for you to fetch changes up to 86842d255b45fc2103da1cd202f5064397ed41f8:
> 
>   clk: imx8mn: Add M7 core clock (2021-08-24 16:09:07 +0300)
> 
> ----------------------------------------------------------------

Thanks. Pulled into clk-next


From sboyd at kernel.org  Sat Aug 28 21:18:29 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 21:18:29 -0700
Subject: [PATCH v3] clk: zynqmp: fix kernel doc
In-Reply-To: <1629720433-19019-1-git-send-email-rajan.vaja@xilinx.com>
References: <1629446294-1056-1-git-send-email-rajan.vaja@xilinx.com>
 <1629720433-19019-1-git-send-email-rajan.vaja@xilinx.com>
Message-ID: <163021070902.2676726.2887966939262149767@swboyd.mtv.corp.google.com>

Quoting Rajan Vaja (2021-08-23 05:07:13)
> Add missing description of 'custom_type_flag' structure member.
> 
> Fixes: e605fa9c4a0c ("clk: zynqmp: Add support for custom type flags")
> 
> Signed-off-by: Rajan Vaja <rajan.vaja at xilinx.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Sat Aug 28 21:20:17 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 21:20:17 -0700
Subject: [PATCH v2] clk: at91: sama7g5: remove all kernel-doc & kernel-doc
 warnings
In-Reply-To: <20210819223237.20115-1-rdunlap@infradead.org>
References: <20210819223237.20115-1-rdunlap@infradead.org>
Message-ID: <163021081762.2676726.3435457249459016223@swboyd.mtv.corp.google.com>

Quoting Randy Dunlap (2021-08-19 15:32:37)
> Remove all "/**" kernel-doc markers from sama7g5.c since they are
> all internal to this driver source file only.
> This eliminates 14 warnings that were reported by the kernel test robot.
> 
> Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
> Reported-by: kernel test robot <lkp at intel.com>
> Cc: Claudiu Beznea <claudiu.beznea at microchip.com>
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: Eugen Hristev <eugen.hristev at microchip.com>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> ---

Applied to clk-next


From sboyd at kernel.org  Sat Aug 28 22:08:20 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 22:08:20 -0700
Subject: [PATCH v4 3/4] clk: visconti: Add support common clock driver and
 reset driver
In-Reply-To: <20210804092244.390376-4-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210804092244.390376-4-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <163021370000.2676726.5709178579074165441@swboyd.mtv.corp.google.com>

Quoting Nobuhiro Iwamatsu (2021-08-04 02:22:43)
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 5f06879d7fe9..dbf70fdecfc8 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -116,6 +116,7 @@ obj-y                                       += ti/
>  obj-$(CONFIG_CLK_UNIPHIER)             += uniphier/
>  obj-$(CONFIG_ARCH_U8500)               += ux500/
>  obj-y                                  += versatile/
> +obj-$(CONFIG_ARCH_VISCONTI)            += visconti/

Can we have an actual Kconfig symbol for this so we can compile test the
driver?

>  ifeq ($(CONFIG_COMMON_CLK), y)
>  obj-$(CONFIG_X86)                      += x86/
>  endif
> diff --git a/drivers/clk/visconti/Makefile b/drivers/clk/visconti/Makefile
> new file mode 100644
> index 000000000000..c1254fd52b31
> --- /dev/null
> +++ b/drivers/clk/visconti/Makefile
> @@ -0,0 +1,5 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +# Makefile for Toshiba Visconti clock
> +
> +obj-y  += clkc.o pll.o reset.o
> +obj-y  += pll-tmpv770x.o clkc-tmpv770x.o
> diff --git a/drivers/clk/visconti/clkc-tmpv770x.c b/drivers/clk/visconti/clkc-tmpv770x.c
> new file mode 100644
> index 000000000000..6ee5c5179f7c
> --- /dev/null
> +++ b/drivers/clk/visconti/clkc-tmpv770x.c
> @@ -0,0 +1,232 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Toshiba Visconti clock controller
> + *
> + * Copyright (c) 2021 TOSHIBA CORPORATION
> + * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
> + *
> + * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> + */
> +
> +#include <dt-bindings/clock/toshiba,tmpv770x.h>
> +#include <dt-bindings/reset/toshiba,tmpv770x.h>

Please include these after linux headers.

> +#include <linux/clk.h>

Is it a clk provider or a clk consumer? Hopefully it's a clk provider,
and thus this should be clk-provider.h instead of clk.h for the
consumer.

> +#include <linux/platform_device.h>
> +
> +#include "clkc.h"
> +#include "reset.h"
> +
> +static DEFINE_SPINLOCK(tmpv770x_clk_lock);
> +static DEFINE_SPINLOCK(tmpv770x_rst_lock);
> +
> +static const struct visconti_fixed_clk fixed_clk_tables[] = {
> +       /* PLL1 */
> +       /* PICMPT0/1, PITSC, PIUWDT, PISWDT, PISBUS, PIPMU, PIGPMU, PITMU */
> +       /* PIEMM, PIMISC, PIGCOMM, PIDCOMM, PIMBUS, PIGPIO, PIPGM */
> +       { TMPV770X_CLK_PIPLL1_DIV4, "pipll1_div4", "pipll1", 0, 1, 4, },
> +       /* PISBUS */
> +       { TMPV770X_CLK_PIPLL1_DIV2, "pipll1_div2", "pipll1", 0, 1, 2, },
> +       /* PICOBUS_CLK */
> +       { TMPV770X_CLK_PIPLL1_DIV1, "pipll1_div1", "pipll1", 0, 1, 1, },
> +       /* PIDNNPLL */
> +       /* CONN_CLK, PIMBUS, PICRC0/1 */
> +       { TMPV770X_CLK_PIDNNPLL_DIV1, "pidnnpll_div1", "pidnnpll", 0, 1, 1, },
> +       { TMPV770X_CLK_PIREFCLK, "pirefclk", "osc2-clk", 0, 1, 1, },
> +       { TMPV770X_CLK_WDTCLK, "wdtclk", "osc2-clk", 0, 1, 1, },
> +};
> +
> +static const struct visconti_clk_gate_table pietherpll_clk_gate_tables[] = {
> +       /* pietherpll */
> +       { TMPV770X_CLK_PIETHER_2P5M, "piether_2p5m", "pietherpll",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 4, 200,

There's quite a lot of CLK_IGNORE_UNUSED. Should these be
CLK_IS_CRITICAL instead, and then only the ones that are truly critical
to the system still running should be marked as critical along with a
comment explaining what they're clocking and why that device isn't
probing and enabling the clks itself.

> +               TMPV770X_RESET_PIETHER_2P5M, },
> +       { TMPV770X_CLK_PIETHER_25M, "piether_25m", "pietherpll",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 5, 20,
> +               TMPV770X_RESET_PIETHER_25M, },
> +       { TMPV770X_CLK_PIETHER_50M, "piether_50m", "pietherpll",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 6, 10,
> +               TMPV770X_RESET_PIETHER_50M, },
> +       { TMPV770X_CLK_PIETHER_125M, "piether_125m", "pietherpll",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 7, 4,
> +               TMPV770X_RESET_PIETHER_125M, },
> +};
> +
> +static const struct visconti_clk_gate_table clk_gate_tables[] = {
> +       { TMPV770X_CLK_HOX, "hox", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x4C, 0x14C, 0, 1,

Lowercase hex please.

> +               TMPV770X_RESET_HOX, },
> +       { TMPV770X_CLK_PCIE_MSTR, "pcie_mstr", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x38, 0x138, 0, 1,
> +               TMPV770X_RESET_PCIE_MSTR, },
> +       { TMPV770X_CLK_PCIE_AUX, "pcie_aux", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x38, 0x138, 1, 24,
> +               TMPV770X_RESET_PCIE_AUX, },
> +       { TMPV770X_CLK_PIINTC, "piintc", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x8, 0x108, 0, 2,
> +               TMPV770X_RESET_PIINTC,},
> +       { TMPV770X_CLK_PIETHER_BUS, "piether_bus", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x34, 0x134, 0, 2,
> +               TMPV770X_RESET_PIETHER_BUS, }, /* BUS_CLK */
> +       { TMPV770X_CLK_PISPI0, "pispi0", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 0, 2,
> +               TMPV770X_RESET_PISPI0, },
> +       { TMPV770X_CLK_PISPI1, "pispi1", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 1, 2,
> +               TMPV770X_RESET_PISPI1, },
> +       { TMPV770X_CLK_PISPI2, "pispi2", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 2, 2,
> +               TMPV770X_RESET_PISPI2, },
> +       { TMPV770X_CLK_PISPI3, "pispi3", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 3, 2,
> +               TMPV770X_RESET_PISPI3,},
> +       { TMPV770X_CLK_PISPI4, "pispi4", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 4, 2,
> +               TMPV770X_RESET_PISPI4, },
> +       { TMPV770X_CLK_PISPI5, "pispi5", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 5, 2,
> +               TMPV770X_RESET_PISPI5},
> +       { TMPV770X_CLK_PISPI6, "pispi6", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x28, 0x128, 6, 2,
> +               TMPV770X_RESET_PISPI6,},
> +       { TMPV770X_CLK_PIUART0, "piuart0", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2C, 0x12C, 0, 4,
> +               TMPV770X_RESET_PIUART0,},
> +       { TMPV770X_CLK_PIUART1, "piuart1", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2C, 0x12C, 1, 4,
> +               TMPV770X_RESET_PIUART1, },
> +       { TMPV770X_CLK_PIUART2, "piuart2", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2C, 0x12C, 2, 4,
> +               TMPV770X_RESET_PIUART2, },
> +       { TMPV770X_CLK_PIUART3, "piuart3", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x2C, 0x12C, 3, 4,
> +               TMPV770X_RESET_PIUART3, },
> +       { TMPV770X_CLK_PII2C0, "pii2c0", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 0, 4,
> +               TMPV770X_RESET_PII2C0, },
> +       { TMPV770X_CLK_PII2C1, "pii2c1", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 1, 4,
> +               TMPV770X_RESET_PII2C1, },
> +       { TMPV770X_CLK_PII2C2, "pii2c2", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 2, 4,
> +               TMPV770X_RESET_PII2C2, },
> +       { TMPV770X_CLK_PII2C3, "pii2c3", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 3, 4,
> +               TMPV770X_RESET_PII2C3,},
> +       { TMPV770X_CLK_PII2C4, "pii2c4", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 4, 4,
> +               TMPV770X_RESET_PII2C4, },
> +       { TMPV770X_CLK_PII2C5, "pii2c5", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 5, 4,
> +               TMPV770X_RESET_PII2C5, },
> +       { TMPV770X_CLK_PII2C6, "pii2c6", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 6, 4,
> +               TMPV770X_RESET_PII2C6, },
> +       { TMPV770X_CLK_PII2C7, "pii2c7", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 7, 4,
> +               TMPV770X_RESET_PII2C7, },
> +       { TMPV770X_CLK_PII2C8, "pii2c8", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x30, 0x130, 8, 4,
> +               TMPV770X_RESET_PII2C8, },
> +       /* PIPCMIF */
> +       { TMPV770X_CLK_PIPCMIF, "pipcmif", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x64, 0x164, 0, 4,
> +               TMPV770X_RESET_PIPCMIF, },
> +       /* PISYSTEM */
> +       { TMPV770X_CLK_WRCK, "wrck", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x68, 0x168, 9, 32,
> +               -1, }, /* No reset */
> +       { TMPV770X_CLK_PICKMON, "pickmon", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x10, 0x110, 8, 4,
> +               TMPV770X_RESET_PICKMON, },
> +       { TMPV770X_CLK_SBUSCLK, "sbusclk", "pipll1",
> +               CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0x14, 0x114, 0, 4,
> +               TMPV770X_RESET_SBUSCLK, },
> +};
> +
> +static const struct visconti_reset_data clk_reset_data[] = {
> +       [TMPV770X_RESET_PIETHER_2P5M]   = { 0x434, 0x534, 4, },
> +       [TMPV770X_RESET_PIETHER_25M]    = { 0x434, 0x534, 5, },
> +       [TMPV770X_RESET_PIETHER_50M]    = { 0x434, 0x534, 6, },
> +       [TMPV770X_RESET_PIETHER_125M]   = { 0x434, 0x534, 7, },
> +       [TMPV770X_RESET_HOX]            = { 0x44C, 0x54C, 0, },
> +       [TMPV770X_RESET_PCIE_MSTR]      = { 0x438, 0x538, 0, },
> +       [TMPV770X_RESET_PCIE_AUX]       = { 0x438, 0x538, 1, },
> +       [TMPV770X_RESET_PIINTC]         = { 0x408, 0x508, 0, },
> +       [TMPV770X_RESET_PIETHER_BUS]    = { 0x434, 0x534, 0, },
> +       [TMPV770X_RESET_PISPI0]         = { 0x428, 0x528, 0, },
> +       [TMPV770X_RESET_PISPI1]         = { 0x428, 0x528, 1, },
> +       [TMPV770X_RESET_PISPI2]         = { 0x428, 0x528, 2, },
> +       [TMPV770X_RESET_PISPI3]         = { 0x428, 0x528, 3, },
> +       [TMPV770X_RESET_PISPI4]         = { 0x428, 0x528, 4, },
> +       [TMPV770X_RESET_PISPI5]         = { 0x428, 0x528, 5, },
> +       [TMPV770X_RESET_PISPI6]         = { 0x428, 0x528, 6, },
> +       [TMPV770X_RESET_PIUART0]        = { 0x42C, 0x52C, 0, },
> +       [TMPV770X_RESET_PIUART1]        = { 0x42C, 0x52C, 1, },
> +       [TMPV770X_RESET_PIUART2]        = { 0x42C, 0x52C, 2, },
> +       [TMPV770X_RESET_PIUART3]        = { 0x42C, 0x52C, 3, },
> +       [TMPV770X_RESET_PII2C0]         = { 0x430, 0x530, 0, },
> +       [TMPV770X_RESET_PII2C1]         = { 0x430, 0x530, 1, },
> +       [TMPV770X_RESET_PII2C2]         = { 0x430, 0x530, 2, },
> +       [TMPV770X_RESET_PII2C3]         = { 0x430, 0x530, 3, },
> +       [TMPV770X_RESET_PII2C4]         = { 0x430, 0x530, 4, },
> +       [TMPV770X_RESET_PII2C5]         = { 0x430, 0x530, 5, },
> +       [TMPV770X_RESET_PII2C6]         = { 0x430, 0x530, 6, },
> +       [TMPV770X_RESET_PII2C7]         = { 0x430, 0x530, 7, },
> +       [TMPV770X_RESET_PII2C8]         = { 0x430, 0x530, 8, },
> +       [TMPV770X_RESET_PIPCMIF]        = { 0x464, 0x564, 0, },
> +       [TMPV770X_RESET_PICKMON]        = { 0x410, 0x510, 8, },
> +       [TMPV770X_RESET_SBUSCLK]        = { 0x414, 0x514, 0, },
> +};
> +
> +static void __init tmpv770x_clkc_setup_clks(struct device_node *np)
> +{
> +       struct visconti_clk_provider *ctx;
> +       struct regmap *regmap;
> +       int ret, i;
> +
> +       regmap = device_node_to_regmap(np);

Is it inside a syscon?

> +       if (IS_ERR(regmap))
> +               return;
> +
> +       ctx = visconti_init_clk(np, regmap, TMPV770X_NR_CLK);
> +       if (IS_ERR(ctx))
> +               return;
> +
> +       ret = visconti_register_reset_controller(np, regmap, clk_reset_data,
> +                                                TMPV770X_NR_RESET,
> +                                                &visconti_reset_ops,
> +                                                &tmpv770x_rst_lock);
> +       if (ret) {
> +               pr_err("Failed to register reset controller: %d\n", ret);
> +               return;
> +       }
> +
> +       for (i = 0; i < (ARRAY_SIZE(fixed_clk_tables)); i++)
> +               ctx->clk_data.clks[fixed_clk_tables[i].id] =
> +                       clk_register_fixed_factor(NULL,
> +                                               fixed_clk_tables[i].name,
> +                                               fixed_clk_tables[i].parent,
> +                                               fixed_clk_tables[i].flag,
> +                                               fixed_clk_tables[i].mult,
> +                                               fixed_clk_tables[i].div);
> +
> +       ret = visconti_clk_register_gates(ctx, clk_gate_tables,
> +                                   ARRAY_SIZE(clk_gate_tables), clk_reset_data,
> +                                   &tmpv770x_clk_lock);
> +       if (ret) {
> +               pr_err("Failed to register main clock gate: %d\n", ret);
> +               return;
> +       }
> +
> +       ret = visconti_clk_register_gates(ctx, pietherpll_clk_gate_tables,
> +                                   ARRAY_SIZE(pietherpll_clk_gate_tables),
> +                                   clk_reset_data, &tmpv770x_clk_lock);
> +       if (ret) {
> +               pr_err("Failed to register pietherpll clock gate: %d\n", ret);
> +               return;
> +       }
> +
> +       of_clk_add_provider(np, of_clk_src_onecell_get, &ctx->clk_data);
> +}
> +
> +CLK_OF_DECLARE_DRIVER(tmpv770x_clkc, "toshiba,tmpv7708-pismu", tmpv770x_clkc_setup_clks);

Any chance this can be a platform driver?

> diff --git a/drivers/clk/visconti/clkc.c b/drivers/clk/visconti/clkc.c
> new file mode 100644
> index 000000000000..32b6f6266154
> --- /dev/null
> +++ b/drivers/clk/visconti/clkc.c
> @@ -0,0 +1,220 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Toshiba Visconti clock controller
> + *
> + * Copyright (c) 2021 TOSHIBA CORPORATION
> + * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
> + *
> + * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> + */
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +
> +#include "clkc.h"
> +
> +static inline struct visconti_clk_gate *to_visconti_clk_gate(struct clk_hw *hw)
> +{
> +       return container_of(hw, struct visconti_clk_gate, hw);
> +}
> +
> +static int visconti_gate_clk_is_enabled(struct clk_hw *hw)
> +{
> +       struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
> +       u32 clk = BIT(gate->ck_idx);
> +       u32 val;
> +
> +       regmap_read(gate->regmap, gate->ckon_offset, &val);
> +       return (val & clk) ? 1 : 0;
> +}
> +
> +static void visconti_gate_clk_disable(struct clk_hw *hw)
> +{
> +       struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
> +       u32 clk = BIT(gate->ck_idx);
> +       u32 rst = BIT(gate->rs_idx);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(gate->lock, flags);
> +
> +       if (visconti_gate_clk_is_enabled(hw)) {

So we never disable the clk?

> +               spin_unlock_irqrestore(gate->lock, flags);
> +               return;
> +       }
> +
> +       /* Reset release */
> +       regmap_update_bits(gate->regmap, gate->rson_offset, rst, 1);
> +
> +       udelay(100);
> +
> +       /* Disable clock */
> +       regmap_update_bits(gate->regmap, gate->ckoff_offset, clk, 1);
> +       spin_unlock_irqrestore(gate->lock, flags);
> +}
> +
> +static int visconti_gate_clk_enable(struct clk_hw *hw)
> +{
> +       struct visconti_clk_gate *gate = to_visconti_clk_gate(hw);
> +       u32 clk = BIT(gate->ck_idx);
> +       u32 rst = BIT(gate->rs_idx);
> +       unsigned long flags;
> +       u32 val;
> +
> +       spin_lock_irqsave(gate->lock, flags);
> +
> +       if (visconti_gate_clk_is_enabled(hw)) {

The core framework should only call down to here if the clk is actually
disabled. This check can be removed.

> +               spin_unlock_irqrestore(gate->lock, flags);
> +               return 0;
> +       }
> +
> +       regmap_update_bits(gate->regmap, gate->ckon_offset, clk, 1);
> +       /* Need read back */

Why? Please indicate why instead of just saying what the code is doing.

> +       regmap_read(gate->regmap, gate->ckon_offset, &val);
> +
> +       udelay(100);
> +       /* Reset release */
> +       regmap_update_bits(gate->regmap, gate->rsoff_offset, rst, 1);
> +       /* Need read back */
> +       regmap_read(gate->regmap, gate->ckoff_offset, &val);
> +       spin_unlock_irqrestore(gate->lock, flags);
> +
> +       return 0;
> +}
> +
> +static const struct clk_ops visconti_clk_gate_ops = {
> +       .enable = visconti_gate_clk_enable,
> +       .disable = visconti_gate_clk_disable,
> +       .is_enabled = visconti_gate_clk_is_enabled,
> +};
> +
> +static struct clk_hw *visconti_clk_register_gate(struct device *dev,
> +                                                const char *name,
> +                                                const char *parent_name,
> +                                                struct regmap *regmap,
> +                                                const struct visconti_clk_gate_table *clks,
> +                                                u32    rson_offset,
> +                                                u32    rsoff_offset,
> +                                                u8     rs_idx,
> +                                                spinlock_t *lock)
> +{
> +       struct visconti_clk_gate *gate;
> +       struct clk_init_data init;
> +       struct clk_hw *hw;
> +       int ret;
> +
> +       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> +       if (!gate)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init.name = name;
> +       init.ops = &visconti_clk_gate_ops;
> +       init.flags = clks->flags;
> +       init.parent_names = parent_name ? &parent_name : NULL;
> +       init.num_parents = parent_name ? 1 : 0;

Do some clks have parents and other clks don't? Or do they always have
parents? Preferably it's one or the other. And if there are parents,
please use clk_parent_data instead of parent_names.

> +
> +       gate->regmap = regmap;
> +       gate->ckon_offset = clks->ckon_offset;
> +       gate->ckoff_offset = clks->ckoff_offset;
> +       gate->ck_idx = clks->ck_idx;
> +       gate->rson_offset = rson_offset;
> +       gate->rsoff_offset = rsoff_offset;
> +       gate->rs_idx = rs_idx;
> +       gate->lock = lock;
> +       gate->hw.init = &init;
> +
> +       hw = &gate->hw;
> +       ret = clk_hw_register(dev, hw);

Is the dev non-NULL? If yes then can devm be used?

> +       if (ret) {
> +               kfree(gate);
> +               hw = ERR_PTR(ret);
> +       }
> +
> +       return hw;
> +}
> +
> +int visconti_clk_register_gates(struct visconti_clk_provider *data,
> +                                const struct visconti_clk_gate_table *clks,
> +                                int num_gate, const struct visconti_reset_data *reset,
> +                                spinlock_t *lock)
> +{
> +       u32 rson_offset, rsoff_offset;
> +       struct clk_hw *hw_clk;
> +       u8 rs_idx;
> +       int i;
> +
> +       for (i = 0; i < num_gate; i++) {
> +               struct clk *clk;
> +               char *div_name;
> +
> +               div_name = kasprintf(GFP_KERNEL, "%s_div", clks[i].name);
> +               if (!div_name)
> +                       return -ENOMEM;
> +
> +               if (clks[i].rs_id >= 0) {
> +                       rson_offset = reset[clks[i].rs_id].rson_offset;
> +                       rsoff_offset = reset[clks[i].rs_id].rsoff_offset;
> +                       rs_idx = reset[clks[i].rs_id].rs_idx;
> +               } else {
> +                       rson_offset = rsoff_offset = rs_idx = -1;
> +               }
> +
> +               clk = clk_register_fixed_factor(NULL, div_name, clks[i].parent,
> +                                               0, 1, clks[i].div);
> +               if (IS_ERR(clk))
> +                       return PTR_ERR(clk);
> +
> +               hw_clk = visconti_clk_register_gate(NULL,

Oh it's always NULL? Sad

> +                                               clks[i].name,
> +                                               div_name,
> +                                               data->regmap,
> +                                               &clks[i],
> +                                               rson_offset,
> +                                               rsoff_offset,
> +                                               rs_idx,
> +                                               lock);
> +               kfree(div_name);
> +               if (IS_ERR(hw_clk)) {
> +                       pr_err("%s: failed to register clock %s\n",
> +                              __func__, clks[i].name);
> +                       return PTR_ERR(hw_clk);
> +               }
> +
> +               data->clk_data.clks[clks[i].id] = hw_clk->clk;
> +       }
> +
> +       return 0;
> +}
> +
> +struct visconti_clk_provider *visconti_init_clk(struct device_node *np,
> +                                               struct regmap *regmap,
> +                                               unsigned long nr_clks)
> +{
> +       struct visconti_clk_provider *ctx;
> +       struct clk **clk_table;
> +       int i;
> +
> +       ctx = kzalloc(sizeof(struct visconti_clk_provider), GFP_KERNEL);

sizeof(*ctx)?

> +       if (!ctx)
> +               return ERR_PTR(-ENOMEM);
> +
> +       clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);

sizeof(*clk_table)?

> +       if (!clk_table)
> +               goto err;
> +
> +       for (i = 0; i < nr_clks; ++i)
> +               clk_table[i] = ERR_PTR(-ENOENT);
> +       ctx->node = np;
> +       ctx->regmap = regmap;
> +       ctx->clk_data.clks = clk_table;
> +       ctx->clk_data.clk_num = nr_clks;
> +
> +       return ctx;
> +err:
> +       kfree(ctx);
> +       return ERR_PTR(-ENOMEM);
> +}
> diff --git a/drivers/clk/visconti/clkc.h b/drivers/clk/visconti/clkc.h
> new file mode 100644
> index 000000000000..4df8788d635a
> --- /dev/null
> +++ b/drivers/clk/visconti/clkc.h
> @@ -0,0 +1,75 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Toshiba Visconti clock controller
> + *
> + * Copyright (c) 2021 TOSHIBA CORPORATION
> + * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
> + *
> + * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> + */
> +
> +#ifndef _VISCONTI_CLKC_H_
> +#define _VISCONTI_CLKC_H_
> +
> +#include <linux/mfd/syscon.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/delay.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/io.h>
> +#include <linux/spinlock.h>
> +
> +#include "reset.h"
> +
> +struct visconti_clk_provider {
> +       struct device_node      *node;
> +       struct regmap           *regmap;
> +       struct clk_onecell_data clk_data;
> +};
> +
> +struct visconti_clk_gate_table {
> +       unsigned int    id;
> +       const char      *name;
> +       const char      *parent;
> +       u8              flags;
> +       u32             ckon_offset;
> +       u32             ckoff_offset;
> +       u8              ck_idx;
> +       unsigned int    div;
> +       u8              rs_id;
> +};
> +
> +struct visconti_fixed_clk {
> +       unsigned int    id;
> +       const char      *name;
> +       const char      *parent;
> +       unsigned long   flag;
> +       unsigned int    mult;
> +       unsigned int    div;
> +};
> +
> +struct visconti_clk_gate {
> +       struct clk_hw   hw;
> +       struct regmap   *regmap;
> +       u32             ckon_offset;
> +       u32             ckoff_offset;
> +       u8              ck_idx;
> +       u8              flags;
> +       u32             rson_offset;
> +       u32             rsoff_offset;
> +       u8              rs_idx;
> +       spinlock_t      *lock;
> +};
> +
> +struct visconti_clk_provider *visconti_init_clk(struct device_node *np,
> +                                               struct regmap *regmap,
> +                                               unsigned long nr_clks);
> +int visconti_clk_register_gates(struct visconti_clk_provider *data,
> +                                const struct visconti_clk_gate_table *clks,
> +                                int num_gate,
> +                                const struct visconti_reset_data *reset,
> +                                spinlock_t *lock);
> +#endif /* _VISCONTI_CLKC_H_ */
> diff --git a/drivers/clk/visconti/pll-tmpv770x.c b/drivers/clk/visconti/pll-tmpv770x.c
> new file mode 100644
> index 000000000000..a0874cb6a67b
> --- /dev/null
> +++ b/drivers/clk/visconti/pll-tmpv770x.c
> @@ -0,0 +1,85 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Toshiba Visconti PLL controller
> + *
> + * Copyright (c) 2021 TOSHIBA CORPORATION
> + * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
> + *
> + * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> + */
> +
> +#include <dt-bindings/clock/toshiba,tmpv770x.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +
> +#include "pll.h"
> +
> +static DEFINE_SPINLOCK(tmpv770x_pll_lock);
> +
> +static const struct visconti_pll_rate_table pipll0_rates[] __initconst = {
> +       VISCONTI_PLL_RATE(840000000, 0x1, 0x0, 0x1, 0x54, 0x000000, 0x2, 0x1),
> +       VISCONTI_PLL_RATE(780000000, 0x1, 0x0, 0x1, 0x4E, 0x000000, 0x2, 0x1),
> +       VISCONTI_PLL_RATE(600000000, 0x1, 0x0, 0x1, 0x3C, 0x000000, 0x2, 0x1),
> +       { /* sentinel */ },
> +};
> +
> +static const struct visconti_pll_rate_table piddrcpll_rates[] __initconst = {
> +       VISCONTI_PLL_RATE(780000000, 0x1, 0x0, 0x1, 0x4E, 0x000000, 0x2, 0x1),
> +       VISCONTI_PLL_RATE(760000000, 0x1, 0x0, 0x1, 0x4C, 0x000000, 0x2, 0x1),
> +       { /* sentinel */ },
> +};
> +
> +static const struct visconti_pll_rate_table pivoifpll_rates[] __initconst = {
> +       VISCONTI_PLL_RATE(165000000, 0x1, 0x0, 0x1, 0x42, 0x000000, 0x4, 0x2),
> +       VISCONTI_PLL_RATE(148500000, 0x1, 0x1, 0x1, 0x3B, 0x666666, 0x4, 0x2),
> +       VISCONTI_PLL_RATE(96000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x2),
> +       VISCONTI_PLL_RATE(74250000, 0x1, 0x1, 0x1, 0x3B, 0x666666, 0x4, 0x4),
> +       VISCONTI_PLL_RATE(54000000, 0x1, 0x0, 0x1, 0x36, 0x000000, 0x5, 0x4),
> +       VISCONTI_PLL_RATE(48000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x4),
> +       VISCONTI_PLL_RATE(35750000, 0x1, 0x1, 0x1, 0x32, 0x0CCCCC, 0x7, 0x4),
> +       { /* sentinel */ },
> +};
> +
> +static const struct visconti_pll_rate_table piimgerpll_rates[] __initconst = {
> +       VISCONTI_PLL_RATE(165000000, 0x1, 0x0, 0x1, 0x42, 0x000000, 0x4, 0x2),
> +       VISCONTI_PLL_RATE(96000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x2),
> +       VISCONTI_PLL_RATE(54000000, 0x1, 0x0, 0x1, 0x36, 0x000000, 0x5, 0x4),
> +       VISCONTI_PLL_RATE(48000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x4),
> +       { /* sentinel */ },
> +};
> +
> +static const struct visconti_pll_info pll_info[] __initconst = {
> +       { TMPV770X_PLL_PIPLL0, "pipll0", "osc2-clk", 0, 0x0, pipll0_rates },
> +       { TMPV770X_PLL_PIDDRCPLL, "piddrcpll", "osc2-clk", 0, 0x500, piddrcpll_rates },
> +       { TMPV770X_PLL_PIVOIFPLL, "pivoifpll", "osc2-clk", 0, 0x600, pivoifpll_rates },
> +       { TMPV770X_PLL_PIIMGERPLL, "piimgerpll", "osc2-clk", 0, 0x700, piimgerpll_rates },
> +};
> +
> +static void __init tmpv770x_setup_plls(struct device_node *np)
> +{
> +       struct visconti_pll_provider *ctx;
> +       void __iomem *reg_base;
> +
> +       reg_base = of_iomap(np, 0);
> +       if (!reg_base)
> +               return;
> +
> +       ctx = visconti_init_pll(np, reg_base, TMPV770X_NR_PLL);
> +       if (IS_ERR(ctx)) {
> +               iounmap(reg_base);
> +               return;
> +       }
> +
> +       ctx->clk_data.clks[TMPV770X_PLL_PIPLL1] =
> +               clk_register_fixed_rate(NULL, "pipll1", NULL, 0, 600000000);
> +       ctx->clk_data.clks[TMPV770X_PLL_PIDNNPLL] =
> +               clk_register_fixed_rate(NULL, "pidnnpll", NULL, 0, 500000000);
> +       ctx->clk_data.clks[TMPV770X_PLL_PIETHERPLL] =
> +               clk_register_fixed_rate(NULL, "pietherpll", NULL, 0, 500000000);
> +
> +       visconti_register_plls(ctx, pll_info, ARRAY_SIZE(pll_info), &tmpv770x_pll_lock);
> +}
> +
> +CLK_OF_DECLARE_DRIVER(tmpv770x_plls, "toshiba,tmpv7708-pipllct", tmpv770x_setup_plls);

DECLARE_DRIVER is for when more than one device needs to probe the node
in DT. Is that happening here? If so, please add a comment indicating
what the other driver is.

> diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c
> new file mode 100644
> index 000000000000..7baa9512fad9
> --- /dev/null
> +++ b/drivers/clk/visconti/pll.c
> @@ -0,0 +1,369 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Toshiba Visconti PLL driver
> + *
> + * Copyright (c) 2021 TOSHIBA CORPORATION
> + * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
> + *
> + * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/slab.h>
> +#include <linux/io.h>
> +
> +#include "pll.h"
> +
> +struct visconti_pll {
> +       struct clk_hw   hw;
> +       void __iomem    *pll_base;
> +       spinlock_t      *lock;
> +       int rate_count;

size_t? And then place next to rate_table so we know they're related
please.

> +       unsigned long flags;
> +       const struct visconti_pll_rate_table *rate_table;
> +       struct visconti_pll_provider *ctx;
> +};
> +
> +#define PLL_CONF_REG           0x0000
> +#define PLL_CTRL_REG           0x0004
> +#define PLL_FRACMODE_REG       0x0010
> +#define PLL_INTIN_REG          0x0014
> +#define PLL_FRACIN_REG         0x0018
> +#define PLL_REFDIV_REG         0x001C
> +#define PLL_POSTDIV_REG                0x0020
> +
> +#define PLL_CONFIG_SEL         BIT(0)
> +#define PLL_PLLEN              BIT(4)
> +#define PLL_BYPASS             BIT(16)
> +#define PLL_INTIN_MASK         GENMASK(11, 0)
> +#define PLL_FRACIN_MASK                GENMASK(23, 0)
> +#define PLL_REFDIV_MASK                GENMASK(5, 0)
> +#define PLL_POSTDIV_MASK       GENMASK(2, 0)
> +
> +static inline struct visconti_pll *to_visconti_pll(struct clk_hw *hw)
> +{
> +       return container_of(hw, struct visconti_pll, hw);
> +}
> +
> +static void visconti_pll_get_params(struct visconti_pll *pll,
> +                                   struct visconti_pll_rate_table *rate_table)
> +{
> +       u32 postdiv, val;
> +
> +       val = readl(pll->pll_base + PLL_FRACMODE_REG);
> +       rate_table->dacen = (val >> 4) & 0x1;

What is 0x1? Some bitfield? Can it be a #define at least? Same for 4.
Better yet, use GENMASK and FIELD_PREP() and FIELD_GET() macros.

> +       rate_table->dsmen = val & 0x1;
> +       rate_table->fracin = readl(pll->pll_base + PLL_FRACIN_REG) & PLL_FRACIN_MASK;
> +       rate_table->intin = readl(pll->pll_base + PLL_INTIN_REG) & PLL_INTIN_MASK;
> +       rate_table->refdiv = readl(pll->pll_base + PLL_REFDIV_REG) & PLL_REFDIV_MASK;
> +
> +       postdiv = readl(pll->pll_base + PLL_POSTDIV_REG);
> +       rate_table->postdiv1 = postdiv & PLL_POSTDIV_MASK;
> +       rate_table->postdiv2 = (postdiv >> 4) & PLL_POSTDIV_MASK;
> +}
> +
> +static const struct visconti_pll_rate_table *visconti_get_pll_settings(struct visconti_pll *pll,
> +                                                                      unsigned long rate)
> +{
> +       const struct visconti_pll_rate_table *rate_table = pll->rate_table;
> +       int i;
> +
> +       for (i = 0; i < pll->rate_count; i++) {
> +               if (rate == rate_table[i].rate)
> +                       return &rate_table[i];
> +       }

Drop braces please.

> +
> +       return NULL;
> +}
> +
> +static unsigned long visconti_get_pll_rate_from_data(struct visconti_pll *pll,
> +                                                    struct visconti_pll_rate_table *rate)

const pointers?

> +{
> +       const struct visconti_pll_rate_table *rate_table = pll->rate_table;
> +       int i;
> +
> +       for (i = 0; i < pll->rate_count; i++) {
> +               if (rate_table[i].dacen == rate->dacen &&
> +                       rate_table[i].dsmen == rate->dsmen &&
> +                       rate_table[i].fracin == rate->fracin &&
> +                       rate_table[i].intin == rate->intin &&
> +                       rate_table[i].refdiv == rate->refdiv &&
> +                       rate_table[i].postdiv1 == rate->postdiv1 &&
> +                       rate_table[i].postdiv2 == rate->postdiv2)

Is it not the same table? Can we just compare the two pointers instead
of each member?

> +                       return rate_table[i].rate;
> +       }
> +
> +       /* set default */
> +       return rate_table[0].rate;
> +}
> +
> +static long visconti_pll_round_rate(struct clk_hw *hw,
> +                           unsigned long rate, unsigned long *prate)
> +{
> +       struct visconti_pll *pll = to_visconti_pll(hw);
> +       const struct visconti_pll_rate_table *rate_table = pll->rate_table;
> +       int i;
> +
> +       /* Assumming rate_table is in descending order */
> +       for (i = 0; i < pll->rate_count; i++) {
> +               if (rate >= rate_table[i].rate)
> +                       return rate_table[i].rate;
> +       }

Drop braces please.

> +
> +       /* return minimum supported value */
> +       return rate_table[i - 1].rate;
> +}
> +
> +static unsigned long visconti_pll_recalc_rate(struct clk_hw *hw,
> +                                             unsigned long parent_rate)
> +{
> +       struct visconti_pll *pll = to_visconti_pll(hw);
> +       struct visconti_pll_rate_table rate_table;
> +
> +       memset(&rate_table, 0, sizeof(rate_table));
> +       visconti_pll_get_params(pll, &rate_table);
> +
> +       return visconti_get_pll_rate_from_data(pll, &rate_table);

Oh. Can we do math instead?

> +}
> +
> +static int visconti_pll_set_params(struct visconti_pll *pll,
> +                               const struct visconti_pll_rate_table *rate_table)
> +{
> +       /* update pll values */

This comment is worthless. Please remove.

> +       writel(((rate_table->dacen << 4) | rate_table->dsmen),

One too many parenthesis here. Please clean it up.

> +                       pll->pll_base + PLL_FRACMODE_REG);
> +       writel(((rate_table->postdiv2 << 4) | rate_table->postdiv1),

Same.

> +                       pll->pll_base + PLL_POSTDIV_REG);
> +       writel(rate_table->intin, pll->pll_base + PLL_INTIN_REG);
> +       writel(rate_table->fracin, pll->pll_base + PLL_FRACIN_REG);
> +       writel(rate_table->refdiv, pll->pll_base + PLL_REFDIV_REG);
> +
> +       return 0;
> +}
> +
> +static int visconti_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> +                           unsigned long parent_rate)
> +{
> +       struct visconti_pll *pll = to_visconti_pll(hw);
> +       const struct visconti_pll_rate_table *rate_table;
> +
> +       /* Get required rate settings from table */

This comment is worthless, please remove.

> +       rate_table = visconti_get_pll_settings(pll, rate);
> +       if (!rate_table) {
> +               pr_err("Invalid rate : %lu for pll clk %s\n",

Please don't print anything during set_rate. It can be quite noisy if
something like a cpufreq driver keeps calling this with the incorrect
frequency.

> +                       parent_rate, __clk_get_name(hw->clk));
> +               return -EINVAL;
> +       }
> +
> +       return visconti_pll_set_params(pll, rate_table);
> +}
> +
> +static int visconti_pll_is_enabled(struct clk_hw *hw)
> +{
> +       struct visconti_pll *pll = to_visconti_pll(hw);
> +       unsigned long flags;
> +       u32 reg;
> +
> +       spin_lock_irqsave(pll->lock, flags);
> +       reg = readl(pll->pll_base + PLL_CTRL_REG);
> +       spin_unlock_irqrestore(pll->lock, flags);

Don't think we need a spinlock to read a register. After this unlocks it
can be disabled anyway, so what's the point to locking here?

> +
> +       return (reg & PLL_PLLEN);
> +}
> +
> +static int visconti_pll_enable(struct clk_hw *hw)
> +{
> +       struct visconti_pll *pll = to_visconti_pll(hw);
> +       const struct visconti_pll_rate_table *rate_table = pll->rate_table;
> +       unsigned long flags;
> +       u32 reg;
> +
> +       if (visconti_pll_is_enabled(hw))
> +               return 0;

Drop.

> +
> +       spin_lock_irqsave(pll->lock, flags);
> +
> +       /* Change to access via register */
> +       writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG);
> +
> +       /* Change to BYPASS mode */
> +       reg = readl(pll->pll_base + PLL_CTRL_REG);
> +       reg |= PLL_BYPASS;
> +       writel(reg, pll->pll_base + PLL_CTRL_REG);
> +
> +       /* Set DIV register .....*/
> +       visconti_pll_set_params(pll, &rate_table[0]);
> +
> +       /* Disable  PLL register */
> +       reg = readl(pll->pll_base + PLL_CTRL_REG);
> +       reg &= ~PLL_PLLEN;
> +       writel(reg, pll->pll_base + PLL_CTRL_REG);
> +
> +       /* Wait 1us */
> +       udelay(1);
> +
> +       /* Enable PLL register */
> +       reg = readl(pll->pll_base + PLL_CTRL_REG);
> +       reg |= PLL_PLLEN;
> +       writel(reg, pll->pll_base + PLL_CTRL_REG);
> +
> +       /* Wait 40us */
> +       udelay(40);
> +
> +       /* Change to PLL mode */

Every comment in here is saying what the code is doing. Please remove
them.

> +       reg = readl(pll->pll_base + PLL_CTRL_REG);
> +       reg &= ~PLL_BYPASS;
> +       writel(reg, pll->pll_base + PLL_CTRL_REG);
> +
> +       spin_unlock_irqrestore(pll->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void visconti_pll_disable(struct clk_hw *hw)
> +{
> +       struct visconti_pll *pll = to_visconti_pll(hw);
> +       unsigned long flags;
> +       u32 reg;
> +
> +       if (!visconti_pll_is_enabled(hw))
> +               return;
> +
> +       spin_lock_irqsave(pll->lock, flags);
> +
> +       /* Change to access via register */

This comment is almost useful, except I don't know why we need to change
access, which is the important part.

> +       writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG);
> +
> +       /* Change to BYPASS mode */
> +       reg = readl(pll->pll_base + PLL_CTRL_REG);
> +       reg |= PLL_BYPASS;
> +       writel(reg, pll->pll_base + PLL_CTRL_REG);
> +
> +       /* PLL disable */
> +       reg = readl(pll->pll_base + PLL_CTRL_REG);
> +       reg &= ~PLL_PLLEN;
> +       writel(reg, pll->pll_base + PLL_CTRL_REG);
> +
> +       spin_unlock_irqrestore(pll->lock, flags);
> +}
> +
> +static const struct clk_ops visconti_pll_ops = {
> +       .enable = visconti_pll_enable,
> +       .disable = visconti_pll_disable,
> +       .is_enabled = visconti_pll_is_enabled,
> +       .round_rate = visconti_pll_round_rate,
> +       .recalc_rate = visconti_pll_recalc_rate,
> +       .set_rate = visconti_pll_set_rate,
> +};
> +
> +static struct clk *visconti_register_pll(struct visconti_pll_provider *ctx,
> +                                        const char *name,
> +                                        const char *parent_name,
> +                                        int offset,
> +                                        const struct visconti_pll_rate_table *rate_table,
> +                                        u8 clk_pll_flags,

Are the flags used?

> +                                        spinlock_t *lock)
> +{
> +       struct clk_init_data init;
> +       struct visconti_pll *pll;
> +       struct clk *pll_clk;
> +       int len;
> +
> +       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> +       if (!pll)
> +               return ERR_PTR(-ENOMEM);
> +
> +       /* Create the actual pll */

Worthless comment.

> +       init.name = name;
> +       init.flags = CLK_IGNORE_UNUSED;
> +       init.parent_names = &parent_name;
> +       init.num_parents = 1;
> +
> +       for (len = 0; rate_table[len].rate != 0; )
> +               len++;
> +       pll->rate_count = len;
> +       pll->rate_table = kmemdup(rate_table,
> +                                 pll->rate_count * sizeof(struct visconti_pll_rate_table),
> +                                 GFP_KERNEL);

Do we need to duplicate the table? Can't that be const?

> +       WARN(!pll->rate_table, "%s: could not allocate rate table for %s\n", __func__, name);
> +
> +       init.ops = &visconti_pll_ops;
> +       pll->hw.init = &init;
> +       pll->pll_base = ctx->reg_base + offset;
> +       pll->flags = clk_pll_flags;
> +       pll->lock = lock;
> +       pll->ctx = ctx;
> +
> +       pll_clk = clk_register(NULL, &pll->hw);

Please use clk_hw_register().

> +       if (IS_ERR(pll_clk)) {
> +               pr_err("failed to register pll clock %s : %ld\n", name, PTR_ERR(pll_clk));
> +               kfree(pll);
> +       }
> +
> +       return pll_clk;
> +}
> +
> +static void visconti_pll_add_lookup(struct visconti_pll_provider *ctx, struct clk *clk,
> +                                   unsigned int id)
> +{
> +       if (ctx->clk_data.clks && id)
> +               ctx->clk_data.clks[id] = clk;
> +}
> +
> +void __init visconti_register_plls(struct visconti_pll_provider *ctx,
> +                                  const struct visconti_pll_info *list,
> +                                  unsigned int nr_plls,
> +                                  spinlock_t *lock)
> +{
> +       int idx;
> +
> +       for (idx = 0; idx < nr_plls; idx++, list++) {
> +               struct clk *clk;
> +
> +               clk = visconti_register_pll(ctx,
> +                                           list->name,
> +                                           list->parent,
> +                                           list->base_reg,
> +                                           list->rate_table,
> +                                           list->flags,
> +                                           lock);
> +               if (IS_ERR(clk)) {
> +                       pr_err("failed to register clock %s\n", list->name);
> +                       continue;
> +               }
> +
> +               visconti_pll_add_lookup(ctx, clk, list->id);
> +       }
> +}
> +
> +struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np,
> +                                                       void __iomem *base,
> +                                                       unsigned long nr_plls)
> +{
> +       struct visconti_pll_provider *ctx;
> +       struct clk **clk_table;
> +       int i;
> +
> +       ctx = kzalloc(sizeof(struct visconti_pll_provider), GFP_KERNEL);
> +       if (!ctx)
> +               return ERR_PTR(-ENOMEM);
> +
> +       clk_table = kcalloc(nr_plls, sizeof(struct clk *), GFP_KERNEL);
> +       if (!clk_table)
> +               goto err;
> +
> +       for (i = 0; i < nr_plls; ++i)
> +               clk_table[i] = ERR_PTR(-ENOENT);
> +
> +       ctx->node = np;
> +       ctx->reg_base = base;
> +       ctx->clk_data.clks = clk_table;
> +       ctx->clk_data.clk_num = nr_plls;
> +
> +       return ctx;
> +
> +err:
> +       kfree(ctx);
> +       return ERR_PTR(-ENOMEM);
> +}
> diff --git a/drivers/clk/visconti/pll.h b/drivers/clk/visconti/pll.h
> new file mode 100644
> index 000000000000..ce0ce1d8cd88
> --- /dev/null
> +++ b/drivers/clk/visconti/pll.h
> @@ -0,0 +1,63 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2021 TOSHIBA CORPORATION
> + * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
> + *
> + * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> + */
> +
> +#ifndef _VISCONTI_PLL_H_
> +#define _VISCONTI_PLL_H_
> +
> +#include <linux/clk-provider.h>
> +#include <linux/regmap.h>
> +#include <linux/spinlock.h>
> +
> +struct visconti_pll_provider {
> +       void __iomem *reg_base;
> +       struct regmap *regmap;
> +       struct clk_onecell_data clk_data;
> +       struct device_node *node;
> +};
> +
> +#define VISCONTI_PLL_RATE(_rate, _dacen, _dsmen, \
> +       _refdiv, _intin, _fracin, _postdiv1, _postdiv2) \
> +{                              \
> +       .rate = _rate,          \
> +       .dacen = _dacen,        \
> +       .dsmen = _dsmen,        \
> +       .refdiv = _refdiv,      \
> +       .intin = _intin,        \
> +       .fracin = _fracin,      \
> +       .postdiv1 = _postdiv1,  \
> +       .postdiv2 = _postdiv2   \
> +}
> +
> +struct visconti_pll_rate_table {
> +       unsigned long rate;
> +       unsigned int dacen;
> +       unsigned int dsmen;
> +       unsigned int refdiv;
> +       unsigned long intin;
> +       unsigned long fracin;
> +       unsigned int postdiv1;
> +       unsigned int postdiv2;
> +};
> +
> +struct visconti_pll_info {
> +       unsigned int id;
> +       const char *name;
> +       const char *parent;
> +       u8 flags;
> +       unsigned long base_reg;
> +       const struct visconti_pll_rate_table *rate_table;
> +};
> +
> +struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np,
> +                                                       void __iomem *base,
> +                                                       unsigned long nr_plls);
> +void __init visconti_register_plls(struct visconti_pll_provider *ctx,

__init can be dropped from header files. It serves no purpose.

> +                                  const struct visconti_pll_info *list,
> +                                  unsigned int nr_plls, spinlock_t *lock);
> +
> +#endif /* _VISCONTI_PLL_H_ */


From sboyd at kernel.org  Sat Aug 28 22:09:54 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 22:09:54 -0700
Subject: [PATCH v4 1/4] dt-bindings: clock: Add DT bindings for PLL of
 Toshiba Visconti TMPV770x SoC
In-Reply-To: <20210804092244.390376-2-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210804092244.390376-2-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <163021379431.2676726.15668763072935534900@swboyd.mtv.corp.google.com>

Quoting Nobuhiro Iwamatsu (2021-08-04 02:22:41)
> Add device tree bindings for PLL of Toshiba Visconti TMPV770x SoC series.
> 
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> ---
>  .../clock/toshiba,tmpv770x-pipllct.yaml       | 57 +++++++++++++++++++
>  1 file changed, 57 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
> 
> diff --git a/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
> new file mode 100644
> index 000000000000..7b7300ce96d6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
> @@ -0,0 +1,57 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/toshiba,tmpv770x-pipllct.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Toshiba Visconti5 TMPV770X PLL Controller Device Tree Bindings
> +
> +maintainers:
> +  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> +
> +description:
> +  Toshia Visconti5 PLL controller which supports the PLLs on TMPV770X.
> +
> +properties:
> +  compatible:
> +    const: toshiba,tmpv7708-pipllct
> +
> +  reg:
> +    maxItems: 1
> +
> +  '#clock-cells':
> +    const: 1
> +
> +  clocks:
> +    description: External reference clock (OSC2)
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#clock-cells"
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    osc2_clk: osc2-clk {
> +      compatible = "fixed-clock";
> +      clock-frequency = <20000000>;
> +      #clock-cells = <0>;
> +    };
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        pipllct: clock-controller at 24220000 {
> +            compatible = "toshiba,tmpv7708-pipllct";

The driver makes it look like this is actually part of a syscon node. Is
that right? It's not clear to me that this is a syscon. But then looking
at the binding it seems that one device has been split up into PLL and
"not PLL" parts sort of arbitrarily.

> +            reg = <0 0x24220000 0 0x820>;
> +            #clock-cells = <1>;
> +            clocks = <&osc2_clk>;
> +        };
> +    };
> +...


From sboyd at kernel.org  Sat Aug 28 22:10:31 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 22:10:31 -0700
Subject: clk: visconti: Initial support Visconti SoC for v5.15
In-Reply-To: <20210826070336.wr3gskwsgeuwii5d@toshiba.co.jp>
References: <20210826070336.wr3gskwsgeuwii5d@toshiba.co.jp>
Message-ID: <163021383134.2676726.14183696921060275372@swboyd.mtv.corp.google.com>

Quoting Nobuhiro Iwamatsu (2021-08-26 00:03:36)
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/iwamatsu/linux-visconti.git
> tags/clk-visconti-5.15

I reviewed the patches on the list. Seems that nobody else did.


From sboyd at kernel.org  Sat Aug 28 22:28:33 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 22:28:33 -0700
Subject: [PATCH] clk: at91: clk-generated: Limit the requested rate to our
 range
In-Reply-To: <20210707131213.3283509-1-codrin.ciubotariu@microchip.com>
References: <20210707131213.3283509-1-codrin.ciubotariu@microchip.com>
Message-ID: <163021491397.2676726.7633391558529179439@swboyd.mtv.corp.google.com>

Quoting Codrin Ciubotariu (2021-07-07 06:12:13)
> On clk_generated_determine_rate(), the requested rate could be outside
> of clk's range. Limit the rate to the clock's range to not return an
> error.
> 
> Fixes: df70aeef6083 ("clk: at91: add generated clock driver")
> Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu at microchip.com>
> ---

Applied to clk-next


From ardb at kernel.org  Sat Aug 28 23:35:37 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sun, 29 Aug 2021 08:35:37 +0200
Subject: [PATCH v7 0/7] running kernel mode SIMD with softirqs disabled
In-Reply-To: <20210827070342.218276-1-ardb@kernel.org>
References: <20210827070342.218276-1-ardb@kernel.org>
Message-ID: <CAMj1kXEUbPMadj1J7MWD_B-=2zRc2ir_zZQN3Puz3n+PjQw58Q@mail.gmail.com>

On Fri, 27 Aug 2021 at 09:03, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> This is a follow-up to [0], but given that the arm64 architectural
> pieces have been merged for arm64, the only remaining changes are crypto
> specific. Therefore, the audience has been reduced to those people who
> are somewhat more likely to care about these specifics.
>
> The AEAD and skcipher APIs may only be called from task or softirq
> context. This permits the arm64 AEAD and skcipher code to get rid of all
> scalar fallbacks, given that on this architecture, softirqs are now no
> longer served while the SIMD unit is being used in kernel mode, which
> means that the scalar fallbacks are never needed. These are removed in
> this series.
>
> Changes since v6:
> - add patch to yield the NEON every 4k of input when processing the AAD
> - add some more acks from Eric
>
> Changes since v5:
> - add Eric's R-b to patches #1 to #3
> - split CCM changes into 3 separate patches
>
> Changes since v4:
> - drop skcipher_walk layer change to deal with zero sized walks
> - drop aead/skcipher layer sanity checks on invocations from hardirq
>   context
> - add patch to clean up CCM a bit more after removing the SIMD code path
>
> Changes since v3:
> - clarify the nature of the issue addressed by patch #1, and apply the
>   same fix to the skcipher walker
> - update patches #2 and #3 so that the failures can be observed by the
>   crypto stats code
>
> [0] https://lore.kernel.org/linux-arm-kernel/20210302090118.30666-1-ardb at kernel.org/
>
> Ard Biesheuvel (7):
>   crypto: arm64/gcm-aes-ce - remove non-SIMD fallback path
>   crypto: arm64/aes-neonbs - stop using SIMD helper for skciphers
>   crypto: arm64/aes-ce - stop using SIMD helper for skciphers
>   crypto: arm64/aes-ccm - yield NEON when processing auth-only data
>   crypto: arm64/aes-ccm - remove non-SIMD fallback path
>   crypto: arm64/aes-ccm - reduce NEON begin/end calls for common case
>   crypto: arm64/aes-ccm - avoid by-ref argument for ce_aes_ccm_auth_data
>

Herbert,

Any chance we could get this queued for v5.15? If it's too late,
please consider taking only the first three patches as an alternative,
and I will resend the CCM ones for v5.16 once they have all been
reviewed.

Thanks,
Ard.

>  arch/arm64/crypto/Kconfig           |   6 -
>  arch/arm64/crypto/aes-ce-ccm-core.S |  24 +--
>  arch/arm64/crypto/aes-ce-ccm-glue.c | 203 ++++++-------------
>  arch/arm64/crypto/aes-glue.c        | 102 ++--------
>  arch/arm64/crypto/aes-neonbs-glue.c | 122 +-----------
>  arch/arm64/crypto/ghash-ce-glue.c   | 209 +++++---------------
>  6 files changed, 148 insertions(+), 518 deletions(-)
>
> --
> 2.30.2
>


From sboyd at kernel.org  Sat Aug 28 23:41:52 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 23:41:52 -0700
Subject: [PATCH v2 0/6] clk: at91: updates for power management and dvfs
In-Reply-To: <6ecc4822-8112-43d4-1259-cd7dfe79d71c@microchip.com>
References: <20210401122726.28528-1-claudiu.beznea@microchip.com>
 <6ecc4822-8112-43d4-1259-cd7dfe79d71c@microchip.com>
Message-ID: <163021931214.2676726.2951110502140668721@swboyd.mtv.corp.google.com>

Quoting Claudiu.Beznea at microchip.com (2021-08-02 01:36:52)
> On 01.04.2021 15:27, Claudiu Beznea wrote:
> Hi Stephen,
> 
> Please ignore the DVFS patch in this series
> (clk: at91: clk-master: update for dvfs) as I have some updates to it. I'll
> introduce them in the next version.
> 

Can I apply the rest of them though?


From sboyd at kernel.org  Sat Aug 28 23:43:54 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 23:43:54 -0700
Subject: [PATCH] clk: zynqmp: Fix kernel-doc format
In-Reply-To: <26526e144296373b2c75e75865dd023158f9bfc7.1629718424.git.michal.simek@xilinx.com>
References: <26526e144296373b2c75e75865dd023158f9bfc7.1629718424.git.michal.simek@xilinx.com>
Message-ID: <163021943479.2676726.5453246267626627161@swboyd.mtv.corp.google.com>

Quoting Michal Simek (2021-08-23 04:33:47)
> Align structure and function names with definitions.
> 
> Issues are reported by kernel-doc script as:
> drivers/clk/zynqmp/clk-gate-zynqmp.c:24: warning: expecting prototype for
> struct clk_gate. Prototype was for struct zynqmp_clk_gate instead
> drivers/clk/zynqmp/clk-gate-zynqmp.c:75: warning: expecting prototype for
> zynqmp_clk_gate_is_enable(). Prototype was for zynqmp_clk_gate_is_enabled()
> instead
> 
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Sat Aug 28 23:45:43 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 28 Aug 2021 23:45:43 -0700
Subject: [PATCH] dt-bindings: clock: brcm,
 iproc-clocks: fix armpll properties
In-Reply-To: <20210819052918.6753-1-zajec5@gmail.com>
References: <20210819052918.6753-1-zajec5@gmail.com>
Message-ID: <163021954302.2676726.4343974228427375599@swboyd.mtv.corp.google.com>

> 
> armpll clocks (available on Cygnus and Northstar Plus) are simple clocks
> with no cells. Adjust binding props #clock-cells and clock-output-names
> to handle them.
> 

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:06:00 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:06:00 -0700
Subject: [PATCH v3 1/8] dt-bindings: clock: samsung: convert Exynos5250 to
 dtschema
In-Reply-To: <20210825134056.219884-2-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-2-krzysztof.kozlowski@canonical.com>
Message-ID: <163022076090.2676726.11327135487234941332@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:40:49)
> Convert Samsung Exynos5250 clock controller bindings to DT schema format
> using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:06:08 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:06:08 -0700
Subject: [PATCH v3 2/8] dt-bindings: clock: samsung: add bindings for
 Exynos external clock
In-Reply-To: <20210825134056.219884-3-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-3-krzysztof.kozlowski@canonical.com>
Message-ID: <163022076896.2676726.7403300581307105@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:40:50)
> Document the bindings for Samsung Exynos external to SoC
> (oscclk/XXTI/XusbXTI) clock provided on boards.  The bindings are
> already implemented in most of the Exynos clock drivers and DTS files.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:06:15 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:06:15 -0700
Subject: [PATCH v3 3/8] dt-bindings: clock: samsung: convert Exynos542x to
 dtschema
In-Reply-To: <20210825134056.219884-4-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-4-krzysztof.kozlowski@canonical.com>
Message-ID: <163022077504.2676726.5936865865796813700@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:40:51)
> Merge Exynos542x clock controller bindings to existing DT schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:06:21 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:06:21 -0700
Subject: [PATCH v3 4/8] dt-bindings: clock: samsung: convert Exynos3250 to
 dtschema
In-Reply-To: <20210825134056.219884-5-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-5-krzysztof.kozlowski@canonical.com>
Message-ID: <163022078186.2676726.4881131896027633393@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:40:52)
> Merge Exynos3250 clock controller bindings to existing DT schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:06:27 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:06:27 -0700
Subject: [PATCH v3 5/8] dt-bindings: clock: samsung: convert Exynos4 to
 dtschema
In-Reply-To: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
Message-ID: <163022078791.2676726.4297885519449467655@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:40:53)
> Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
> schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:08:20 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:08:20 -0700
Subject: [PATCH v3 6/8] dt-bindings: clock: samsung: convert Exynos AudSS
 to dtschema
In-Reply-To: <20210825134251.220098-1-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
 <20210825134251.220098-1-krzysztof.kozlowski@canonical.com>
Message-ID: <163022090079.2676726.10315720276792690321@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:42:49)
> Convert Samsung Exynos Audio SubSystem clock controller bindings to DT
> schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:08:29 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:08:29 -0700
Subject: [PATCH v3 7/8] dt-bindings: clock: samsung: convert S5Pv210 AudSS
 to dtschema
In-Reply-To: <20210825134251.220098-2-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
 <20210825134251.220098-2-krzysztof.kozlowski@canonical.com>
Message-ID: <163022090939.2676726.3258581184867007965@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:42:50)
> Convert Samsung S5Pv210 Audio SubSystem clock controller bindings to DT
> schema format using json-schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> 
> ---

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:08:38 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:08:38 -0700
Subject: [PATCH v3 8/8] MAINTAINERS: clock: include S3C and S5P in Samsung
 SoC clock entry
In-Reply-To: <20210825134251.220098-3-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
 <20210825134251.220098-3-krzysztof.kozlowski@canonical.com>
Message-ID: <163022091855.2676726.10244708006623939894@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:42:51)
> Cover the S3C and S5Pv210 clock controller binding headers by Samsung
> SoC clock controller drivers maintainer entry.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Sun Aug 29 00:09:44 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 00:09:44 -0700
Subject: [PATCH v3 0/8] dt-bindings: clock: samsung: convert to dtschema
In-Reply-To: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
Message-ID: <163022098497.2676726.6455473597971395732@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-25 06:40:48)
> Hi,
> 
> Changes since v2:
> 1. Add reviews.
> 2. Split Exynos4 ISP into separate schema.
> 3. Add maxItems to clocks and power-domains (review feedback).
> 4. Do not allow samsung,exynos5420-clock and samsung,exynos5800-clock
>    without syscon. These clock controllers should always use syscon
>    to allow DMC bindings access the registers.
> 5. Drop assigned-clocks.
> 
> Changes since v1:
> 1. Patch 7/8: include header to fix clock IDs error in example.

I think this header file isn't in clk tree?


From leo.yan at linaro.org  Sun Aug 29 03:22:36 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Sun, 29 Aug 2021 18:22:36 +0800
Subject: [PATCH v2 0/2] perf: Support compat mode for AUX ring buffer
Message-ID: <20210829102238.19693-1-leo.yan@linaro.org>

This patch set is to address the comments in the patch set v1 [1] and
updates the patches.

Changes from v1:
- Added Adrian's review tag for patch 01;
- Refined comment in patch 01 (James);
- Added James' review and test tag for patch 02.

[1] https://lore.kernel.org/patchwork/cover/1473936/


Leo Yan (2):
  perf auxtrace: Add compat_auxtrace_mmap__{read_head|write_tail}
  perf auxtrace arm: Support
    compat_auxtrace_mmap__{read_head|write_tail}

 tools/perf/arch/arm/util/auxtrace.c | 32 +++++++++++
 tools/perf/util/auxtrace.c          | 88 +++++++++++++++++++++++++++--
 tools/perf/util/auxtrace.h          | 22 +++++++-
 3 files changed, 135 insertions(+), 7 deletions(-)

-- 
2.25.1



From leo.yan at linaro.org  Sun Aug 29 03:22:37 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Sun, 29 Aug 2021 18:22:37 +0800
Subject: [PATCH v2 1/2] perf auxtrace: Add
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210829102238.19693-1-leo.yan@linaro.org>
References: <20210829102238.19693-1-leo.yan@linaro.org>
Message-ID: <20210829102238.19693-2-leo.yan@linaro.org>

When perf runs in compat mode (kernel in 64-bit mode and the perf is in
32-bit mode), the 64-bit value atomicity in the user space cannot be
assured, E.g. on some architectures, the 64-bit value accessing is split
into two instructions, one is for the low 32-bit word accessing and
another is for the high 32-bit word.

This patch introduces weak functions compat_auxtrace_mmap__read_head()
and compat_auxtrace_mmap__write_tail(), as their naming indicates, when
perf tool works in compat mode, it uses these two functions to access
the AUX head and tail.  These two functions can allow the perf tool to
work properly in certain conditions, e.g. when perf tool works in
snapshot mode with only using AUX head pointer, or perf tool uses the
AUX buffer and the incremented tail is not bigger than 4GB.

When perf tool cannot handle the case when the AUX tail is bigger than
4GB, the function compat_auxtrace_mmap__write_tail() returns -1 and
tells the caller to bail out for the error.

These two functions are declared as weak attribute, this allows to
implement arch specific functions if any arch can support the 64-bit
value atomicity in compat mode.

Suggested-by: Adrian Hunter <adrian.hunter at intel.com>
Signed-off-by: Leo Yan <leo.yan at linaro.org>
Acked-by: Adrian Hunter <adrian.hunter at intel.com>
---
 tools/perf/util/auxtrace.c | 88 ++++++++++++++++++++++++++++++++++++--
 tools/perf/util/auxtrace.h | 22 ++++++++--
 2 files changed, 103 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index f33f09b8b535..8d2865b9ade2 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -1669,6 +1669,82 @@ int perf_event__process_auxtrace_error(struct perf_session *session,
 	return 0;
 }
 
+/*
+ * In the compat mode kernel runs in 64-bit and perf tool runs in 32-bit mode,
+ * 32-bit perf tool cannot access 64-bit value atomically, which might lead to
+ * the issues caused by the below sequence on multiple CPUs: when perf tool
+ * accesses either the load operation or the store operation for 64-bit value,
+ * on some architectures the operation is divided into two instructions, one
+ * is for accessing the low 32-bit value and another is for the high 32-bit;
+ * thus these two user operations can give the kernel chances to access the
+ * 64-bit value, and thus leads to the unexpected load values.
+ *
+ *   kernel (64-bit)                        user (32-bit)
+ *
+ *   if (LOAD ->aux_tail) { --,             LOAD ->aux_head_lo
+ *       STORE $aux_data      |       ,--->
+ *       FLUSH $aux_data      |       |     LOAD ->aux_head_hi
+ *       STORE ->aux_head   --|-------`     smp_rmb()
+ *   }                        |             LOAD $data
+ *                            |             smp_mb()
+ *                            |             STORE ->aux_tail_lo
+ *                            `----------->
+ *                                          STORE ->aux_tail_hi
+ *
+ * For this reason, it's impossible for the perf tool to work correctly when
+ * the AUX head or tail is bigger than 4GB (more than 32 bits length); and we
+ * can not simply limit the AUX ring buffer to less than 4GB, the reason is
+ * the pointers can be increased monotonically, whatever the buffer size it is,
+ * at the end the head and tail can be bigger than 4GB and carry out to the
+ * high 32-bit.
+ *
+ * To mitigate the issues and improve the user experience, we can allow the
+ * perf tool working in certain conditions and bail out with error if detect
+ * any overflow cannot be handled.
+ *
+ * For reading the AUX head, it reads out the values for three times, and
+ * compares the high 4 bytes of the values between the first time and the last
+ * time, if there has no change for high 4 bytes injected by the kernel during
+ * the user reading sequence, it's safe for use the second value.
+ *
+ * When compat_auxtrace_mmap__write_tail() detects any carrying in the high
+ * 32 bits, it means there have two store operations in user space and it cannot
+ * promise the atomicity for 64-bit write, so return '-1' in this case to tell
+ * the caller an overflow error has happened.
+ */
+u64 __weak compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+	u64 first, second, last;
+	u64 mask = (u64)(UINT32_MAX) << 32;
+
+	do {
+		first = READ_ONCE(pc->aux_head);
+		/* Ensure all reads are done after we read the head */
+		smp_rmb();
+		second = READ_ONCE(pc->aux_head);
+		/* Ensure all reads are done after we read the head */
+		smp_rmb();
+		last = READ_ONCE(pc->aux_head);
+	} while ((first & mask) != (last & mask));
+
+	return second;
+}
+
+int __weak compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+	u64 mask = (u64)(UINT32_MAX) << 32;
+
+	if (tail & mask)
+		return -1;
+
+	/* Ensure all reads are done before we write the tail out */
+	smp_mb();
+	WRITE_ONCE(pc->aux_tail, tail);
+	return 0;
+}
+
 static int __auxtrace_mmap__read(struct mmap *map,
 				 struct auxtrace_record *itr,
 				 struct perf_tool *tool, process_auxtrace_t fn,
@@ -1680,8 +1756,9 @@ static int __auxtrace_mmap__read(struct mmap *map,
 	size_t size, head_off, old_off, len1, len2, padding;
 	union perf_event ev;
 	void *data1, *data2;
+	int kernel_is_64_bit = perf_env__kernel_is_64_bit(evsel__env(NULL));
 
-	head = auxtrace_mmap__read_head(mm);
+	head = auxtrace_mmap__read_head(mm, kernel_is_64_bit);
 
 	if (snapshot &&
 	    auxtrace_record__find_snapshot(itr, mm->idx, mm, data, &head, &old))
@@ -1764,10 +1841,13 @@ static int __auxtrace_mmap__read(struct mmap *map,
 	mm->prev = head;
 
 	if (!snapshot) {
-		auxtrace_mmap__write_tail(mm, head);
-		if (itr->read_finish) {
-			int err;
+		int err;
+
+		err = auxtrace_mmap__write_tail(mm, head, kernel_is_64_bit);
+		if (err < 0)
+			return err;
 
+		if (itr->read_finish) {
 			err = itr->read_finish(itr, mm->idx);
 			if (err < 0)
 				return err;
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index d68a5e80b217..5f383908ca6e 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -440,23 +440,39 @@ struct auxtrace_cache;
 
 #ifdef HAVE_AUXTRACE_SUPPORT
 
-static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
+u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm);
+int compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail);
+
+static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm,
+					   int kernel_is_64_bit __maybe_unused)
 {
 	struct perf_event_mmap_page *pc = mm->userpg;
-	u64 head = READ_ONCE(pc->aux_head);
+	u64 head;
+
+#if BITS_PER_LONG == 32
+	if (kernel_is_64_bit)
+		return compat_auxtrace_mmap__read_head(mm);
+#endif
+	head = READ_ONCE(pc->aux_head);
 
 	/* Ensure all reads are done after we read the head */
 	smp_rmb();
 	return head;
 }
 
-static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
+static inline int auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail,
+					    int kernel_is_64_bit __maybe_unused)
 {
 	struct perf_event_mmap_page *pc = mm->userpg;
 
+#if BITS_PER_LONG == 32
+	if (kernel_is_64_bit)
+		return compat_auxtrace_mmap__write_tail(mm, tail);
+#endif
 	/* Ensure all reads are done before we write the tail out */
 	smp_mb();
 	WRITE_ONCE(pc->aux_tail, tail);
+	return 0;
 }
 
 int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
-- 
2.25.1



From leo.yan at linaro.org  Sun Aug 29 03:22:38 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Sun, 29 Aug 2021 18:22:38 +0800
Subject: [PATCH v2 2/2] perf auxtrace arm: Support
 compat_auxtrace_mmap__{read_head|write_tail}
In-Reply-To: <20210829102238.19693-1-leo.yan@linaro.org>
References: <20210829102238.19693-1-leo.yan@linaro.org>
Message-ID: <20210829102238.19693-3-leo.yan@linaro.org>

When the tool runs with compat mode on Arm platform, the kernel is in
64-bit mode and user space is in 32-bit mode; the user space can use
instructions "ldrd" and "strd" for 64-bit value atomicity.

This patch adds compat_auxtrace_mmap__{read_head|write_tail} for arm
building, it uses "ldrd" and "strd" instructions to ensure accessing
atomicity for aux head and tail.  The file arch/arm/util/auxtrace.c is
built for arm and arm64 building, these two functions are not needed for
arm64, so check the compiler macro "__arm__" to only include them for
arm building.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
Reviewed-by: James Clark <james.clark at arm.com>
Tested-by: James Clark <james.clark at arm.com>
---
 tools/perf/arch/arm/util/auxtrace.c | 32 +++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c
index b187bddbd01a..c7c7ec0812d5 100644
--- a/tools/perf/arch/arm/util/auxtrace.c
+++ b/tools/perf/arch/arm/util/auxtrace.c
@@ -107,3 +107,35 @@ struct auxtrace_record
 	*err = 0;
 	return NULL;
 }
+
+#if defined(__arm__)
+u64 compat_auxtrace_mmap__read_head(struct auxtrace_mmap *mm)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+	u64 result;
+
+	__asm__ __volatile__(
+"	ldrd    %0, %H0, [%1]"
+	: "=&r" (result)
+	: "r" (&pc->aux_head), "Qo" (pc->aux_head)
+	);
+
+	return result;
+}
+
+int compat_auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail)
+{
+	struct perf_event_mmap_page *pc = mm->userpg;
+
+	/* Ensure all reads are done before we write the tail out */
+	smp_mb();
+
+	__asm__ __volatile__(
+"	strd    %2, %H2, [%1]"
+	: "=Qo" (pc->aux_tail)
+	: "r" (&pc->aux_tail), "r" (tail)
+	);
+
+	return 0;
+}
+#endif
-- 
2.25.1



From pali at kernel.org  Sun Aug 29 04:13:30 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sun, 29 Aug 2021 13:13:30 +0200
Subject: [PATCH v2 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210819215655.84866-3-jeremy.linton@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
 <20210819215655.84866-3-jeremy.linton@arm.com>
Message-ID: <20210829111330.22f6n3tvmm246jzg@pali>

On Thursday 19 August 2021 16:56:53 Jeremy Linton wrote:
> The PFTF CM4 is an ACPI platform that isn't ECAM compliant. Its config
> space is in two parts. One part is for the root port registers and a
> second moveable window pointing at a device's 4K config space. Thus it
> doesn't have an MCFG, and any MCFG provided would be nonsense
> anyway. Instead, a Linux specific host bridge _DSD selects a custom
> ECAM ops and cfgres. The cfg op picks between those two regions while
> disallowing problematic accesses.

I'm not sure if Lorenzo would like this patch series...

In past there was a long discussion about ECAM compliance, MCFG quirks
and usage of ACPI (on other platform), see long thread:
https://lore.kernel.org/linux-pci/20200207183427.GA40158 at google.com/

And I think it is not a good idea to extend MCFG quirks table as
according to discussion it was just temporary plaster and if platform is
not ACPI / ECAM compliant then it should use DT booting...

Lorenzo, could you put any comment on this?

> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  drivers/pci/controller/Makefile            |  1 +
>  drivers/pci/controller/pcie-brcmstb-acpi.c | 74 ++++++++++++++++++++++
>  include/linux/pci-ecam.h                   |  1 +
>  3 files changed, 76 insertions(+)
>  create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
> 
> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> index aaf30b3dcc14..65aa6fd3ed89 100644
> --- a/drivers/pci/controller/Makefile
> +++ b/drivers/pci/controller/Makefile
> @@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
>  obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
>  obj-$(CONFIG_ARM64) += pci-thunder-pem.o
>  obj-$(CONFIG_ARM64) += pci-xgene.o
> +obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
>  endif
>  endif
> diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
> new file mode 100644
> index 000000000000..71f6def3074c
> --- /dev/null
> +++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * ACPI quirks for Brcm2711 PCIe host controller
> + * As used on the Raspberry Pi Compute Module 4
> + *
> + * Copyright (C) 2021 Arm Ltd.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/pci.h>
> +#include <linux/pci-ecam.h>
> +#include "../pci.h"
> +#include "pcie-brcmstb.h"
> +
> +static int brcm_acpi_init(struct pci_config_window *cfg)
> +{
> +	/*
> +	 * This platform doesn't technically have anything that could be called
> +	 * ECAM. Its config region has root port specific registers between
> +	 * standard PCIe defined config registers. Thus the region setup by the
> +	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
> +	 * but the footprint isn't a nice power of 2 (40k). For purposes of
> +	 * mapping the config region we are just going to squash the standard
> +	 * and nonstandard registers together rather than mapping them separately.
> +	 */
> +	iounmap(cfg->win);
> +	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
> +	if (!cfg->win)
> +		goto err_exit;
> +
> +	/* MSI is nonstandard as well */
> +	pci_no_msi();
> +
> +	return 0;
> +err_exit:
> +	dev_err(cfg->parent, "PCI: Failed to remap config\n");
> +	return -ENOMEM;
> +}
> +
> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
> +					unsigned int devfn, int where)
> +{
> +	struct pci_config_window *cfg = bus->sysdata;
> +	void __iomem *base = cfg->win;
> +	int idx;
> +	u32 up;
> +
> +	/* Accesses to the RC go right to the RC registers if slot==0 */
> +	if (pci_is_root_bus(bus))
> +		return PCI_SLOT(devfn) ? NULL : base + where;
> +
> +	/* Assure link up before sending request */
> +	up = readl(base + PCIE_MISC_PCIE_STATUS);
> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
> +		return NULL;
> +
> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
> +		return NULL;
> +
> +	/* For devices, write to the config space index register */
> +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
> +	writel(idx, base + PCIE_EXT_CFG_INDEX);
> +	return base + PCIE_EXT_CFG_DATA + where;
> +}
> +
> +const struct pci_ecam_ops bcm2711_pcie_ops = {
> +	.init		= brcm_acpi_init,
> +	.bus_shift	= 1,
> +	.pci_ops	= {
> +		.map_bus	= brcm_pcie_map_conf2,
> +		.read		= pci_generic_config_read,
> +		.write		= pci_generic_config_write,
> +	}
> +};
> diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
> index adea5a4771cf..a5de0285bb7f 100644
> --- a/include/linux/pci-ecam.h
> +++ b/include/linux/pci-ecam.h
> @@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
>  extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
>  extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
>  extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
> +extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
>  #endif
>  
>  #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
> -- 
> 2.31.1
> 


From jacek.anaszewski at gmail.com  Sun Aug 29 04:15:45 2021
From: jacek.anaszewski at gmail.com (Jacek Anaszewski)
Date: Sun, 29 Aug 2021 13:15:45 +0200
Subject: [PATCH v3 2/5] leds: Add driver for QCOM SPMI Flash LEDs
In-Reply-To: <20210824214515.ekjpvaymkgxltlzp@notapiano>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
 <20210803162641.1525980-3-nfraprado@collabora.com>
 <b1060e9a-f78e-fbe9-bde3-2b4d89cbc73e@gmail.com>
 <20210824214515.ekjpvaymkgxltlzp@notapiano>
Message-ID: <278ea1e8-8b21-457d-78d7-fbb32544fe0a@gmail.com>

Hi Nicolas,

On 8/24/21 11:45 PM, N?colas F. R. A. Prado wrote:
> Hi Jacek,
> 
> Thank you for the review. I'll answer below.
> 
> On Tue, Aug 17, 2021 at 12:03:49AM +0200, Jacek Anaszewski wrote:
>> Hi Nicolas,
>>
>> Thanks for the update. See my comments below.
>>
>> On 8/3/21 6:26 PM, N?colas F. R. A. Prado wrote:
>>> Add driver for Qualcomm's SPMI Flash LEDs. These are controlled
>>> through an SPMI bus and are part of the PM8941 PMIC. There are two LEDs
>>> present on the chip, which can be used independently as camera flash or,
>>> when in torch mode, as a lantern.
>>>
>>> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
>>> ---
>>>
>>> Changes in v3:
>>> - The two LEDs can now be operated independently even when in torch mode
>>> - The flashes can now strobe consecutive times without needing to manually
>>>     disable them between strobes
>>> - Implemented strobe_get()
>>> - Moved dt parsing to a separate function
>>> - Split multiplexed torch/flash on/off and torch/flash regulator on/off
>>>     functions
>>> - Set current on brightness callback and timeout on timeout callback, instead of
>>>     setting everything every time when strobing/turning torch on
>>> - And a whole lot of other minor changes
>>>
>>> Changes in v2:
>>> - Thanks to Jacek:
>>>     - Implemented flash LED class framework
>>> - Thanks to Bjorn:
>>>     - Renamed driver to "qcom spmi flash"
>>> - Refactored code
>>> - Added missing copyright
>>>
>>>    drivers/leds/flash/Kconfig                |    8 +
>>>    drivers/leds/flash/Makefile               |    1 +
>>>    drivers/leds/flash/leds-qcom-spmi-flash.c | 1251 +++++++++++++++++++++
>>>    3 files changed, 1260 insertions(+)
>>>    create mode 100644 drivers/leds/flash/leds-qcom-spmi-flash.c
>>>
>>> diff --git a/drivers/leds/flash/Kconfig b/drivers/leds/flash/Kconfig
>>> index 3f49f3edbffb..72f61323cd2a 100644
>>> --- a/drivers/leds/flash/Kconfig
>>> +++ b/drivers/leds/flash/Kconfig
>>> @@ -24,4 +24,12 @@ config LEDS_RT8515
>>>    	  To compile this driver as a module, choose M here: the module
>>>    	  will be called leds-rt8515.
>>> +config LEDS_QCOM_SPMI_FLASH
>>> +	tristate "Support for QCOM SPMI Flash LEDs"
>>> +	depends on REGMAP_SPMI
>>> +	depends on OF
>>> +	help
>>> +	  This option enables support for the flash/torch LEDs present in
>>> +	  Qualcomm's PM8941 PMIC.
>>> +
>>>    endif # LEDS_CLASS_FLASH
>>> diff --git a/drivers/leds/flash/Makefile b/drivers/leds/flash/Makefile
>>> index 09aee561f769..c141d277e9b6 100644
>>> --- a/drivers/leds/flash/Makefile
>>> +++ b/drivers/leds/flash/Makefile
>>> @@ -2,3 +2,4 @@
>>>    obj-$(CONFIG_LEDS_RT4505)	+= leds-rt4505.o
>>>    obj-$(CONFIG_LEDS_RT8515)	+= leds-rt8515.o
>>> +obj-$(CONFIG_LEDS_QCOM_SPMI_FLASH)	+= leds-qcom-spmi-flash.o
>>> diff --git a/drivers/leds/flash/leds-qcom-spmi-flash.c b/drivers/leds/flash/leds-qcom-spmi-flash.c
>>> new file mode 100644
>>> index 000000000000..9763707bb986
>>> --- /dev/null
>>> +++ b/drivers/leds/flash/leds-qcom-spmi-flash.c
>>> @@ -0,0 +1,1251 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Qualcomm SPMI Flash LEDs Driver
>>> + *
>>> + * Copyright (c) 2020-2021, N?colas F. R. A. Prado <n at nfraprado.net>
>>> + * Copyright (c) 2021, Collabora Ltd.
>>> + *
>>> + * Based on QPNP LEDs driver from downstream MSM kernel sources.
>>> + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
>>> + */
>>> +
>>> +#include <linux/delay.h>
>>> +#include <linux/device.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/led-class-flash.h>
>>> +#include <linux/module.h>
>>> +#include <linux/mutex.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/regulator/consumer.h>
>>> +#include <linux/spmi.h>
>>> +#include <linux/string.h>
>>> +#include <linux/sysfs.h>
>>> +#include <linux/types.h>
>>> +
>>> +#define QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE	0x05
>>> +#define QCOM_FLASH_ADDR_STATUS			0x10
>>> +#define QCOM_FLASH_ADDR_SAFETY_TIMER		0x40
>>> +#define QCOM_FLASH_ADDR_MAX_CURR		0x41
>>> +#define QCOM_FLASH_ADDR_CURR_LED0		0x42
>>> +#define QCOM_FLASH_ADDR_CURR_LED1		0x43
>>> +#define QCOM_FLASH_ADDR_CLAMP_CURR		0x44
>>> +#define QCOM_FLASH_ADDR_ENABLE_CONTROL		0x46
>>> +#define QCOM_FLASH_ADDR_LED_STROBE_CTRL		0x47
>>> +#define QCOM_FLASH_ADDR_LED_TMR_CTRL		0x48
>>> +#define QCOM_FLASH_ADDR_HEADROOM		0x4A
>>> +#define QCOM_FLASH_ADDR_STARTUP_DELAY		0x4B
>>> +#define QCOM_FLASH_ADDR_MASK_ENABLE		0x4C
>>> +#define QCOM_FLASH_ADDR_VREG_OK_FORCE		0x4F
>>> +#define QCOM_FLASH_ADDR_LED_UNLOCK_SECURE	0xD0
>>> +#define QCOM_FLASH_ADDR_LED_TORCH		0xE4
>>> +#define QCOM_FLASH_ADDR_FAULT_DETECT		0x51
>>> +#define QCOM_FLASH_ADDR_RAMP_RATE		0x54
>>> +#define QCOM_FLASH_ADDR_VPH_PWR_DROOP		0x5A
>>> +
>>> +#define QCOM_FLASH_MAX_LEVEL		0x4F
>>> +#define QCOM_FLASH_TORCH_MAX_LEVEL	0x0F
>>> +#define	QCOM_FLASH_NO_MASK		0x00
>>> +
>>> +#define QCOM_FLASH_MASK_1		0x20
>>> +#define QCOM_FLASH_MASK_REG_MASK	0xE0
>>> +#define QCOM_FLASH_HEADROOM_MASK	0x03
>>> +#define QCOM_FLASH_SAFETY_TIMER_MASK	0x7F
>>> +#define QCOM_FLASH_CURRENT_MASK		0xFF
>>> +#define QCOM_FLASH_MAX_CURRENT_MASK	0x7F
>>> +#define QCOM_FLASH_TMR_MASK		0x03
>>> +#define QCOM_FLASH_TMR_WATCHDOG		0x03
>>> +#define QCOM_FLASH_TMR_SAFETY		0x00
>>> +#define QCOM_FLASH_FAULT_DETECT_MASK	0x80
>>> +#define QCOM_FLASH_HW_VREG_OK		0x40
>>> +#define QCOM_FLASH_VREG_MASK		0xC0
>>> +#define QCOM_FLASH_STARTUP_DLY_MASK	0x02
>>> +#define QCOM_FLASH_RAMP_RATE_MASK	0xBF
>>> +#define QCOM_FLASH_VPH_PWR_DROOP_MASK	0xF3
>>> +
>>> +#define QCOM_FLASH_ENABLE_ALL		0xE0
>>> +#define QCOM_FLASH_ENABLE_MODULE	0x80
>>> +#define QCOM_FLASH_ENABLE_MODULE_MASK	0x80
>>> +#define QCOM_FLASH_DISABLE_ALL		0x00
>>> +#define QCOM_FLASH_ENABLE_MASK		0xE0
>>> +#define QCOM_FLASH_ENABLE_LED0		0xC0
>>> +#define QCOM_FLASH_ENABLE_LED1		0xA0
>>> +#define QCOM_FLASH_INIT_MASK		0xE0
>>> +#define QCOM_FLASH_SELFCHECK_ENABLE	0x80
>>> +#define QCOM_FLASH_SELFCHECK_DISABLE	0x00
>>> +
>>> +#define QCOM_FLASH_STROBE_SW		0xC0
>>> +#define QCOM_FLASH_STROBE_HW		0x04
>>> +#define QCOM_FLASH_STROBE_MASK		0xC7
>>> +#define QCOM_FLASH_STROBE_LED0		0x80
>>> +#define QCOM_FLASH_STROBE_LED1		0x40
>>> +
>>> +#define QCOM_FLASH_TORCH_MASK		0x03
>>> +#define QCOM_FLASH_LED_TORCH_ENABLE	0x00
>>> +#define QCOM_FLASH_LED_TORCH_DISABLE	0x03
>>> +#define QCOM_FLASH_UNLOCK_SECURE	0xA5
>>> +#define QCOM_FLASH_SECURE_MASK		0xFF
>>> +
>>> +#define QCOM_FLASH_SUBTYPE_DUAL		0x01
>>> +#define QCOM_FLASH_SUBTYPE_SINGLE	0x02
>>> +
>>> +#define QCOM_FLASH_DURATION_STEP	10000
>>> +#define QCOM_FLASH_DURATION_MIN		10000
>>> +#define QCOM_FLASH_DURATION_DEFAULT	200000
>>> +
>>> +#define QCOM_FLASH_CURRENT_STEP		12500
>>> +#define QCOM_FLASH_CURRENT_MIN		12500
>>> +
>>> +#define QCOM_FLASH_DEFAULT_CLAMP	200000
>>> +
>>> +#define QCOM_FLASH_MASK_ON_LED0		0x8
>>> +#define QCOM_FLASH_MASK_ON_LED1		0x2
>>> +#define QCOM_FLASH_MASK_STATUS_TIMEDOUT	0x5
>>> +
>>> +enum qcom_flash_headroom {
>>> +	QCOM_FLASH_HEADROOM_250MV,
>>> +	QCOM_FLASH_HEADROOM_300MV,
>>> +	QCOM_FLASH_HEADROOM_400MV,
>>> +	QCOM_FLASH_HEADROOM_500MV,
>>> +};
>>> +
>>> +enum qcom_flash_startup_dly {
>>> +	QCOM_FLASH_STARTUP_DLY_10US,
>>> +	QCOM_FLASH_STARTUP_DLY_32US,
>>> +	QCOM_FLASH_STARTUP_DLY_64US,
>>> +	QCOM_FLASH_STARTUP_DLY_128US,
>>> +};
>>> +
>>> +enum qcom_flash_ids {
>>> +	QCOM_FLASH_ID_LED0,
>>> +	QCOM_FLASH_ID_LED1,
>>> +};
>>> +
>>> +/**
>>> + * struct qcom_flash_led - Represents each individual flash LED
>>> + * @fled_cdev: flash LED classdev
>>> + * @id: LED ID as given by enum qcom_flash_ids
>>> + * @default_on: default state for the LED
>>> + * @flash_enable_cmd: enable command for particular flash
>>> + * @flash_strobe_cmd: strobe command for particular flash
>>> + * @current_addr: address to write for current
>>> + * @mask_led_on: bitmask for STATUS register that shows if LED is on
>>> + * @flash_current_invalidated: whether the flash current in the current register
>>> + *	was invalidated by torch usage
>>> + */
>>> +struct qcom_flash_led {
>>> +	struct led_classdev_flash fled_cdev;
>>> +	enum qcom_flash_ids id;
>>> +	bool default_on;
>>> +	u8 flash_enable_cmd;
>>> +	u8 flash_strobe_cmd;
>>> +	u16 current_addr;
>>> +	u8 mask_led_on;
>>> +	bool flash_current_invalidated;
>>> +};
>>> +
>>> +/**
>>> + * struct qcom_flash_device - QCOM SPMI Flash device, contains 2 flash LEDs
>>> + * @regmap: regmap used to access LED registers over SPMI
>>> + * @base: base register given in device tree
>>> + * @dev: device from devicetree
>>> + * @flash_supply: voltage regulator to supply the flashes
>>> + * @torch_supply: voltage regulator to supply torch mode
>>> + * @leds: flash LEDs
>>> + * @num_leds: number of LEDs registered (between 0 and 2)
>>> + * @lock: lock to protect SPMI transactions
>>> + * @torch_enable_cmd: enable flash LED torch mode
>>> + * @peripheral_subtype: module peripheral subtype
>>> + * @flash_regulator_on: flash regulator status
>>> + * @torch_regulator_on: torch regulator status
>>> + * @torch_enabled: whether torch mode is enabled
>>> + */
>>> +struct qcom_flash_device {
>>> +	struct regmap *regmap;
>>> +	unsigned int base;
>>> +	struct device *dev;
>>> +	struct regulator *flash_supply;
>>> +	struct regulator *torch_supply;
>>> +	struct qcom_flash_led leds[2];
>>> +	u8 num_leds;
>>> +	struct mutex lock;
>>> +	u8 torch_enable_cmd;
>>> +	unsigned int peripheral_subtype;
>>> +	bool flash_regulator_on;
>>> +	bool torch_regulator_on;
>>> +	bool torch_enabled;
>>> +};
>>> +
>>> +struct qcom_flash_config {
>>> +	unsigned int base;
>>> +	struct regulator *flash_supply;
>>> +	struct regulator *torch_supply;
>>> +	unsigned int num_leds;
>>> +
>>> +	enum qcom_flash_ids id[2];
>>> +	bool default_on[2];
>>> +	u32 led_max_brightness[2];
>>> +	u32 flash_max_brightness[2];
>>> +	u32 flash_max_timeout[2];
>>> +};
>>> +
>>> +static inline struct qcom_flash_led *flcdev_to_led(struct led_classdev_flash *fled_cdev)
>>> +{
>>> +	return container_of(fled_cdev, struct qcom_flash_led, fled_cdev);
>>> +}
>>> +
>>> +static inline struct qcom_flash_device *led_to_leds_dev(struct qcom_flash_led *led)
>>> +{
>>> +	return container_of(led, struct qcom_flash_device, leds[led->id]);
>>> +}
>>> +
>>> +static inline int qcom_flash_read_reg(struct qcom_flash_device *leds_dev,
>>> +				      unsigned int reg, unsigned int *val)
>>> +{
>>> +	return regmap_read(leds_dev->regmap, leds_dev->base + reg, val);
>>> +}
>>> +
>>> +static inline int qcom_flash_masked_write(struct qcom_flash_device *leds_dev,
>>> +					  unsigned int reg, unsigned int mask,
>>> +					  unsigned int val)
>>> +{
>>> +	return regmap_update_bits(leds_dev->regmap, leds_dev->base + reg, mask,
>>> +				  val);
>>> +}
>>> +
>>> +static u8 qcom_flash_duration_to_reg(u32 us)
>>> +{
>>> +	if (us < QCOM_FLASH_DURATION_MIN)
>>> +		us = QCOM_FLASH_DURATION_MIN;
>>> +	return (us - QCOM_FLASH_DURATION_MIN) / QCOM_FLASH_DURATION_STEP;
>>> +}
>>> +
>>> +static u8 qcom_flash_current_to_reg(u32 ua)
>>> +{
>>> +	if (ua < QCOM_FLASH_CURRENT_MIN)
>>> +		ua = QCOM_FLASH_CURRENT_MIN;
>>> +	return (ua - QCOM_FLASH_CURRENT_MIN) / QCOM_FLASH_CURRENT_STEP;
>>> +}
>>> +
>>> +static void clamp_align(u32 *v, u32 min, u32 max, u32 step)
>>> +{
>>> +	*v = clamp_val(*v, min, max);
>>> +	if (step > 1)
>>> +		*v = (*v - min) / step * step + min;
>>> +}
>>> +
>>> +static int qcom_flash_status_get(struct qcom_flash_led *led)
>>> +{
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	unsigned int status;
>>> +	int rc;
>>> +
>>> +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_STATUS, &status);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Failure reading status, rc =  %d\n",
>>> +			rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	return status & led->mask_led_on;
>>> +}
>>> +
>>> +static int qcom_flash_status_clear(struct qcom_flash_device *leds_dev)
>>> +{
>>> +	unsigned int enable_val;
>>> +	int rc;
>>> +
>>> +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +				 &enable_val);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Enable reg read failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +				     QCOM_FLASH_ENABLE_MASK, QCOM_FLASH_DISABLE_ALL);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +				     QCOM_FLASH_ENABLE_MASK, enable_val);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
>>
>> It would be good to have different error messages to discern between
>> the two above calls' failures.
> 
> Indeed.
> 
>>
>>> +		return rc;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_check_timedout(struct qcom_flash_device *leds_dev)
>>> +{
>>> +	unsigned int status;
>>> +	int rc;
>>> +
>>> +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_STATUS, &status);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Failure reading status, rc =  %d\n",
>>> +			rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	return status & QCOM_FLASH_MASK_STATUS_TIMEDOUT;
>>> +}
>>> +
>>> +static int qcom_flash_torch_reg_enable(struct qcom_flash_device *leds_dev,
>>> +				       bool state)
>>> +{
>>> +	int rc;
>>> +
>>> +	if (leds_dev->torch_enabled == state)
>>> +		return 0;
>>> +
>>> +	/*
>>> +	 * For the TORCH register (0xE4) to become writable, the UNLOCK_SECURE
>>> +	 * register (0xD0) needs to be written with the UNLOCK_SECURE value
>>> +	 * (0xA5) first.
>>> +	 * It gets re-locked after any register write.
>>> +	 */
>>> +	rc = qcom_flash_masked_write(leds_dev,
>>> +				     QCOM_FLASH_ADDR_LED_UNLOCK_SECURE,
>>> +				     QCOM_FLASH_SECURE_MASK,
>>> +				     QCOM_FLASH_UNLOCK_SECURE);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Secure reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_TORCH,
>>> +				     QCOM_FLASH_TORCH_MASK,
>>> +				     state ? QCOM_FLASH_LED_TORCH_ENABLE :
>>> +					     QCOM_FLASH_LED_TORCH_DISABLE);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Torch reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_max_brightness_set(struct qcom_flash_led *led,
>>> +					 unsigned int brightness)
>>> +{
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	struct device *dev = leds_dev->dev;
>>> +	int rc;
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_MAX_CURR,
>>> +				     QCOM_FLASH_CURRENT_MASK, brightness);
>>> +	if (rc) {
>>> +		dev_err(dev, "Max current reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_brightness_set(struct qcom_flash_led *led,
>>> +				     unsigned int brightness)
>>> +{
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	struct device *dev = leds_dev->dev;
>>> +	int rc;
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, led->current_addr,
>>> +				     QCOM_FLASH_CURRENT_MASK, brightness);
>>> +	if (rc) {
>>> +		dev_err(dev, "Current reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_fled_regulator_on(struct qcom_flash_device *leds_dev)
>>> +{
>>> +	int rc;
>>> +
>>> +	if (leds_dev->flash_regulator_on)
>>> +		return 0;
>>> +
>>> +	rc = regulator_enable(leds_dev->flash_supply);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Regulator enable failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	leds_dev->flash_regulator_on = true;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_fled_regulator_off(struct qcom_flash_device *leds_dev)
>>> +{
>>> +	unsigned int i;
>>> +	u8 enable = 0;
>>> +	int rc;
>>> +
>>> +	if (!leds_dev->flash_regulator_on)
>>> +		return 0;
>>> +
>>> +	for (i = 0; i < leds_dev->num_leds; i++) {
>>> +		rc = qcom_flash_status_get(&leds_dev->leds[i]);
>>> +		if (rc < 0)
>>> +			return rc;
>>> +
>>> +		if (!rc)
>>> +			continue;
>>> +
>>> +		enable |= leds_dev->leds[i].flash_enable_cmd;
>>> +	}
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +				     QCOM_FLASH_ENABLE_MASK, enable);
>>> +	if (rc)
>>> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
>>> +
>>> +	if (enable)
>>> +		return 0;
>>> +
>>> +	rc = regulator_disable(leds_dev->flash_supply);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Regulator disable failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	leds_dev->flash_regulator_on = false;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_torch_regulator_on(struct qcom_flash_device *leds_dev)
>>> +{
>>> +	int rc;
>>> +
>>> +	if (leds_dev->torch_regulator_on)
>>> +		return 0;
>>> +
>>> +	rc = regulator_enable(leds_dev->torch_supply);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Regulator enable failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	leds_dev->torch_regulator_on = true;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_torch_regulator_off(struct qcom_flash_device *leds_dev)
>>> +{
>>> +	int rc;
>>> +
>>> +	if (!leds_dev->torch_regulator_on)
>>> +		return 0;
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +				     QCOM_FLASH_ENABLE_MODULE_MASK,
>>> +				     QCOM_FLASH_DISABLE_ALL);
>>> +	if (rc)
>>> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
>>> +
>>> +	rc = regulator_disable(leds_dev->torch_supply);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Regulator disable failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	leds_dev->torch_regulator_on = false;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_fled_on(struct qcom_flash_led *led)
>>> +{
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	struct device *dev = leds_dev->dev;
>>> +	int rc, error;
>>> +
>>> +	rc = qcom_flash_fled_regulator_on(leds_dev);
>>> +	if (rc)
>>> +		goto error_flash_set;
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +				     led->flash_enable_cmd,
>>> +				     led->flash_enable_cmd);
>>> +	if (rc) {
>>> +		dev_err(dev, "Enable reg write failed(%d)\n", rc);
>>> +		goto error_flash_set;
>>> +	}
>>> +
>>> +	/*
>>> +	 * TODO The downstream driver also allowed HW strobe. Add support for it
>>> +	 * after v4l2 support is added and ISP can be used
>>> +	 */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
>>> +				     led->flash_strobe_cmd,
>>> +				     led->flash_strobe_cmd);
>>> +	if (rc) {
>>> +		dev_err(dev, "LED %d strobe reg write failed(%d)\n", led->id,
>>> +			rc);
>>> +		goto error_flash_set;
>>> +	}
>>> +
>>> +	return 0;
>>> +
>>> +error_flash_set:
>>> +	error = qcom_flash_fled_regulator_off(leds_dev);
>>> +	if (error)
>>> +		return error;
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_fled_off(struct qcom_flash_led *led)
>>> +{
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	struct device *dev = leds_dev->dev;
>>> +	int rc, error;
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
>>> +				     led->flash_strobe_cmd,
>>> +				     QCOM_FLASH_DISABLE_ALL);
>>> +	if (rc)
>>> +		dev_err(dev, "LED %d flash write failed(%d)\n", led->id, rc);
>>> +
>>> +	error = qcom_flash_fled_regulator_off(leds_dev);
>>> +	if (error)
>>> +		return error;
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_torch_on(struct qcom_flash_led *led)
>>> +{
>>> +	int rc, error;
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	struct device *dev = leds_dev->dev;
>>> +
>>> +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
>>> +		rc = qcom_flash_torch_regulator_on(leds_dev);
>>> +		if (rc)
>>> +			goto error_reg_write;
>>> +	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
>>> +		rc = qcom_flash_fled_regulator_on(leds_dev);
>>
>> Why for torch mode you need to enable fled regulator?
> 
> Based on [1], apparently the hardware present in the Single variant of the PMIC
> has some limitation that requires the use of the flash regulator and the value
> QCOM_FLASH_ENABLE_ALL to enable the LEDs for the torch mode. The Dual variant on
> the other hand can just use the torch regulator and enables the LEDs with
> QCOM_FLASH_ENABLE_MODULE.
> 
> [1] https://github.com/AICP/kernel_lge_hammerhead/commit/0f47c747c074993655d0bfebd045e8ddd228fe4c
> 
> I'm honestly not sure what the impact is on using the different regulators and
> enable values. I have tested enabling the Dual PMIC with different enable values
> and all seemed to work the same, so must be some hardware detail.
> 
> I left that Single codepath in the hope that it is useful for devices that have
> that variant of the hardware, but I have only actually tested the Dual PMIC,
> which is the one present on the Nexus 5.

Thanks for the explanation. Just wanted to confirm that it was not
a mistake.

>>
>>> +		if (rc)
>>> +			goto error_flash_set;
>>> +
>>> +		/*
>>> +		 * Write 0x80 to MODULE_ENABLE before writing
>>> +		 * 0xE0 in order to avoid a hardware bug caused
>>> +		 * by register value going from 0x00 to 0xE0.
>>> +		 */
>>> +		rc = qcom_flash_masked_write(leds_dev,
>>> +					     QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +					     QCOM_FLASH_ENABLE_MODULE_MASK,
>>> +					     QCOM_FLASH_ENABLE_MODULE);
>>> +		if (rc) {
>>> +			dev_err(dev, "Enable reg write failed(%d)\n", rc);
>>> +			goto error_flash_set;
>>> +		}
>>> +	}
>>> +
>>> +	rc = qcom_flash_torch_reg_enable(leds_dev, true);
>>> +	if (rc)
>>> +		goto error_reg_write;
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +				     QCOM_FLASH_ENABLE_MASK,
>>> +				     leds_dev->torch_enable_cmd);
>>> +	if (rc) {
>>> +		dev_err(dev, "Enable reg write failed(%d)\n", rc);
>>> +		goto error_reg_write;
>>> +	}
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
>>> +				     led->flash_strobe_cmd,
>>> +				     led->flash_strobe_cmd);
>>
>> Just to make sure - the hardware requires strobe cmd to enable torch?
> 
> Yes. The strobe value is the one that actually turns each of the LEDs on,
> doesn't matter if it's on flash or torch mode. The difference in torch mode is
> actually just that the timeout on the LEDs is disabled (done by writing 0x00
> into the TORCH, 0xE4, register).
> So for both modes, the LEDs are turned on by writing to the STROBE_CTRL, 0x47,
> register. If torch is on they'll stay on indefinitely, while on flash mode
> they'll turn off after the timeout.
> 
> Perhaps it's just a naming issue?

I propose to add these comments next to the calls in question.

>>
>>> +	if (rc) {
>>> +		dev_err(dev, "LED %d strobe reg write failed(%d)\n", led->id,
>>> +			rc);
>>> +		goto error_reg_write;
>>> +	}
>>> +
>>> +	leds_dev->torch_enabled = true;
>>> +
>>> +	return 0;
>>> +
>>> +error_reg_write:
>>> +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE)
>>> +		goto error_flash_set;
>>> +
>>> +	error = qcom_flash_torch_regulator_off(leds_dev);
>>> +	if (error)
>>> +		return error;
>>> +	return rc;
>>> +
>>> +error_flash_set:
>>> +	error = qcom_flash_fled_regulator_off(leds_dev);
>>> +	if (error)
>>> +		return error;
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_torch_off(struct qcom_flash_led *led)
>>> +{
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	struct device *dev = leds_dev->dev;
>>> +	int rc, error;
>>> +	unsigned int i;
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
>>> +				     led->flash_strobe_cmd, QCOM_FLASH_DISABLE_ALL);
>>> +	if (rc) {
>>> +		dev_err(dev, "LED %d flash write failed(%d)\n", led->id, rc);
>>> +		goto error_torch_set;
>>> +	}
>>> +
>>> +	/* Keep torch on if the other LED is still on */
>>> +	for (i = 0; i < leds_dev->num_leds; i++)
>>> +		if (leds_dev->leds[i].fled_cdev.led_cdev.brightness)
>>> +			return 0;
>>> +
>>> +	rc = qcom_flash_torch_reg_enable(leds_dev, false);
>>> +	if (rc)
>>> +		goto error_torch_set;
>>> +
>>> +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
>>> +		rc = qcom_flash_torch_regulator_off(leds_dev);
>>> +		if (rc)
>>> +			return rc;
>>> +	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
>>> +		rc = qcom_flash_fled_regulator_off(leds_dev);
>>> +		if (rc)
>>> +			return rc;
>>> +	}
>>> +
>>> +	leds_dev->torch_enabled = false;
>>> +
>>> +	return 0;
>>> +
>>> +error_torch_set:
>>> +	error = qcom_flash_torch_regulator_off(leds_dev);
>>> +	if (error)
>>> +		return error;
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_ledcdev_brightness_set(struct led_classdev *led_cdev,
>>> +					     enum led_brightness value)
>>> +{
>>> +	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
>>> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	unsigned int max_brightness;
>>> +	int rc;
>>> +
>>> +	if (value > led_cdev->max_brightness) {
>>
>> LED framework takes care of it. You can skip this.
> 
> Ok.
> 
>>
>>> +		dev_err(leds_dev->dev, "Invalid brightness value\n");
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	mutex_lock(&leds_dev->lock);
>>> +	if (!value) {
>>> +		rc = qcom_flash_torch_off(led);
>>> +	} else {
>>> +		/*
>>> +		 * The minimum on value for the brightness register is 0, but for
>>> +		 * led_classdev is 1, as 0 there means off.
>>> +		 */
>>> +		rc = qcom_flash_brightness_set(led, led_cdev->brightness - 1);
>>> +		if (rc)
>>> +			goto unlock;
>>> +
>>> +		led->flash_current_invalidated = true;
>>> +
>>> +		if (leds_dev->torch_enabled) {
>>> +			/* Clear status to update brightness */
>>> +			rc = qcom_flash_status_clear(leds_dev);
>>> +			if (rc)
>>> +				goto unlock;
>>> +		} else {
>>> +			/*
>>> +			 * Clear status from previous flash strobe so the LED
>>> +			 * can turn on
>>> +			 */
>>> +			rc = qcom_flash_check_timedout(leds_dev);
>>> +			if (rc > 0)
>>> +				rc = qcom_flash_status_clear(leds_dev);
>>> +			else if (rc < 0)
>>> +				goto unlock;
>>> +
>>> +			max_brightness = led_cdev->max_brightness - 1;
>>> +			rc = qcom_flash_max_brightness_set(led, max_brightness);
>>> +			if (rc)
>>> +				goto unlock;
>>> +		}
>>> +		rc = qcom_flash_torch_on(led);
>>> +	}
>>> +
>>> +unlock:
>>> +	mutex_unlock(&leds_dev->lock);
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_flcdev_brightness_set(struct led_classdev_flash *fled_cdev,
>>> +					    u32 brightness)
>>> +{
>>> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	unsigned int bright;
>>> +	int rc;
>>> +
>>> +	/* Can't operate on flash if torch is on */
>>> +	if (leds_dev->torch_enabled)
>>> +		return -EBUSY;
>>> +
>>> +	clamp_align(&brightness, QCOM_FLASH_CURRENT_MIN,
>>> +		    fled_cdev->brightness.max, QCOM_FLASH_CURRENT_STEP);
>>> +	fled_cdev->brightness.val = brightness;
>>> +
>>> +	bright = qcom_flash_current_to_reg(brightness);
>>> +
>>> +	mutex_lock(&leds_dev->lock);
>>> +	rc = qcom_flash_brightness_set(led, bright);
>>> +	if (rc)
>>> +		goto unlock;
>>> +
>>> +	if (led->flash_current_invalidated) {
>>> +		bright = qcom_flash_current_to_reg(fled_cdev->brightness.max);
>>> +		rc = qcom_flash_max_brightness_set(led, bright);
>>> +		if (rc)
>>> +			goto unlock;
>>> +	}
>>> +
>>> +	led->flash_current_invalidated = false;
>>> +
>>> +unlock:
>>> +	mutex_unlock(&leds_dev->lock);
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_flcdev_strobe_set(struct led_classdev_flash *fled_cdev,
>>> +					bool state)
>>> +{
>>> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	unsigned int bright;
>>> +	unsigned int i;
>>> +	int rc;
>>> +
>>> +	/* Can't operate on flash if torch is on */
>>> +	if (leds_dev->torch_enabled)
>>> +		return -EBUSY;
>>> +
>>> +	mutex_lock(&leds_dev->lock);
>>> +	if (!state) {
>>> +		rc = qcom_flash_fled_off(led);
>>> +	} else {
>>> +		/*
>>> +		 * Turn off flash LEDs from previous strobe
>>> +		 */
>>> +		rc = qcom_flash_check_timedout(leds_dev);
>>> +		if (rc > 0) {
>>> +			for (i = 0; i < leds_dev->num_leds; i++) {
>>> +				rc = qcom_flash_fled_off(&leds_dev->leds[i]);
>>> +				if (rc)
>>> +					goto unlock;
>>> +			}
>>> +		} else if (rc < 0) {
>>> +			goto unlock;
>>> +		}
>>
>> What if flash gets timed out after this check here? Why do you need to
>> call qcom_flash_fled_off() if it has already timed out?
> 
> The issue is that after the flash times out, the hardware is not ready for
> another strobe.
> 
> When I strobe LED0 for example, the STATUS register, 0x10, gets set to 0x08
> indicating the LED0 is on. After the timeout, it changes to 0x04. At that point
> if I try to strobe LED0 again, it doesn't work. When I turn the LED0 off (write
> 0x00 to either the ENABLE or STROBE register), the STATUS is reset to 0x00. Now
> I'm able to strobe the LED0 again.
> 
> I'm not sure if this is the normal behavior on other flash LED controllers, and
> maybe there's even some configuration of this PMIC that resets the LED status
> automatically after the strobe timeout, but I have not been able to do that. So
> that's why I reset the status manually everytime it's needed.

My point was that the flash may time out after reading STATUS register
and before writing QCOM_FLASH_ADDR_LED_STROBE_CTRL.
You can't be 100% sure that you know the exact STATUS state just
a moment before strobing.

To alleviate that I propose to avoid checking the status and always
calling qcom_flash_fled_off() before initiating a new strobe.

>>
>>> +		if (led->flash_current_invalidated) {
>>> +			bright = qcom_flash_current_to_reg(fled_cdev->brightness.val);
>>> +			rc = qcom_flash_brightness_set(led, bright);
>>> +			if (rc)
>>> +				goto unlock;
>>> +
>>> +			bright = qcom_flash_current_to_reg(fled_cdev->brightness.max);
>>> +			rc = qcom_flash_max_brightness_set(led, bright);
>>> +			if (rc)
>>> +				goto unlock;
>>> +
>>> +			led->flash_current_invalidated = false;
>>> +		}
>>> +
>>> +		rc = qcom_flash_fled_on(led);
>>> +	}
>>> +
>>> +unlock:
>>> +	mutex_unlock(&leds_dev->lock);
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_flcdev_strobe_get(struct led_classdev_flash *fled_cdev,
>>> +					bool *state)
>>> +{
>>> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	int status;
>>> +
>>> +	mutex_lock(&leds_dev->lock);
>>> +	status = qcom_flash_status_get(led);
>>> +	mutex_unlock(&leds_dev->lock);
>>> +	if (status < 0)
>>> +		return status;
>>> +
>>> +	*state = status && !leds_dev->torch_enabled;
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_flcdev_timeout_set(struct led_classdev_flash *fled_cdev,
>>> +					 u32 timeout)
>>> +{
>>> +	struct qcom_flash_led *led = flcdev_to_led(fled_cdev);
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	unsigned int time, i;
>>> +	int rc;
>>> +
>>> +	clamp_align(&timeout, QCOM_FLASH_DURATION_MIN, fled_cdev->timeout.max,
>>> +		    QCOM_FLASH_DURATION_STEP);
>>> +
>>> +	/* Since the timeout register is shared between LEDs, update for all */
>>> +	for (i = 0; i < leds_dev->num_leds; i++)
>>> +		leds_dev->leds[i].fled_cdev.timeout.val = timeout;
>>> +
>>> +	time = qcom_flash_duration_to_reg(fled_cdev->timeout.val);
>>> +
>>> +	mutex_lock(&leds_dev->lock);
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_SAFETY_TIMER,
>>> +				     QCOM_FLASH_SAFETY_TIMER_MASK, time);
>>> +	if (rc)
>>> +		dev_err(leds_dev->dev, "Safety timer reg write failed(%d)\n",
>>> +			rc);
>>> +	mutex_unlock(&leds_dev->lock);
>>> +
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_flcdev_fault_get(struct led_classdev_flash *fled_cdev,
>>> +				       u32 *fault)
>>> +{
>>> +	/*
>>> +	 * TODO Add fault detection when we find out how to. No clue from
>>> +	 * inspecting the SPMI registers
>>> +	 */
>>> +	*fault = 0;
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct led_flash_ops flash_ops = {
>>> +	.flash_brightness_set	= qcom_flash_flcdev_brightness_set,
>>> +	.strobe_set		= qcom_flash_flcdev_strobe_set,
>>> +	.strobe_get		= qcom_flash_flcdev_strobe_get,
>>> +	.timeout_set		= qcom_flash_flcdev_timeout_set,
>>> +	.fault_get		= qcom_flash_flcdev_fault_get,
>>> +};
>>> +
>>> +static int qcom_flash_setup_flcdev(struct qcom_flash_config *cfg,
>>> +				   struct qcom_flash_led *led,
>>> +				   struct device_node *node)
>>> +{
>>> +	int rc;
>>> +	struct device *dev = led_to_leds_dev(led)->dev;
>>> +	struct led_classdev_flash *fled_cdev = &led->fled_cdev;
>>> +	struct led_classdev *led_cdev = &fled_cdev->led_cdev;
>>> +	struct led_init_data init_data = {};
>>> +	struct led_flash_setting *setting;
>>> +
>>> +	init_data.fwnode = of_fwnode_handle(node);
>>> +
>>> +	led_cdev->brightness_set_blocking = qcom_flash_ledcdev_brightness_set;
>>> +
>>> +	led_cdev->max_brightness = cfg->led_max_brightness[led->id];
>>> +	led_cdev->max_brightness /= QCOM_FLASH_CURRENT_STEP;
>>
>> Just assign the result of division:
>>
>> led_cdev->max_brightness = cfg->led_max_brightness[led->id] /
>>                             QCOM_FLASH_CURRENT_STEP;
>>
>> Two consecutive assignments look a bit convoluted.
> 
> Sure.
> 
>>
>>> +
>>> +	setting = &fled_cdev->brightness;
>>> +	setting->max = cfg->flash_max_brightness[led->id];
>>> +	setting->min = QCOM_FLASH_CURRENT_MIN;
>>> +	setting->step = QCOM_FLASH_CURRENT_STEP;
>>> +	setting->val = setting->min;
>>> +
>>> +	setting = &fled_cdev->timeout;
>>> +	setting->max = cfg->flash_max_timeout[led->id];
>>> +	setting->min = QCOM_FLASH_DURATION_MIN;
>>> +	setting->step = QCOM_FLASH_DURATION_STEP;
>>> +	setting->val = QCOM_FLASH_DURATION_DEFAULT;
>>> +
>>> +	fled_cdev->ops = &flash_ops;
>>> +	led_cdev->flags |= LED_DEV_CAP_FLASH;
>>> +
>>> +	rc = devm_led_classdev_flash_register_ext(dev, fled_cdev, &init_data);
>>> +	if (rc)
>>> +		dev_err(dev, "unable to register led %d,rc=%d\n", led->id, rc);
>>> +
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_setup_fled(struct qcom_flash_config *cfg,
>>> +				 struct qcom_flash_led *led,
>>> +				 enum qcom_flash_ids id)
>>> +{
>>> +	led->id = cfg->id[id];
>>> +	led->default_on = cfg->default_on[id];
>>> +	led->flash_current_invalidated = true;
>>> +
>>> +	if (led->id == QCOM_FLASH_ID_LED0) {
>>> +		led->flash_enable_cmd = QCOM_FLASH_ENABLE_LED0;
>>> +		led->flash_strobe_cmd = QCOM_FLASH_STROBE_LED0;
>>> +		led->current_addr = QCOM_FLASH_ADDR_CURR_LED0;
>>> +		led->mask_led_on = QCOM_FLASH_MASK_ON_LED0;
>>> +	} else {
>>> +		led->flash_enable_cmd = QCOM_FLASH_ENABLE_LED1;
>>> +		led->flash_strobe_cmd = QCOM_FLASH_STROBE_LED1;
>>> +		led->current_addr = QCOM_FLASH_ADDR_CURR_LED1;
>>> +		led->mask_led_on = QCOM_FLASH_MASK_ON_LED1;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_setup_regs(struct qcom_flash_device *leds_dev)
>>> +{
>>> +	int rc;
>>> +
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
>>> +				     QCOM_FLASH_STROBE_MASK,
>>> +				     QCOM_FLASH_DISABLE_ALL);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "LED flash write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Disable flash LED module */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
>>> +				     QCOM_FLASH_ENABLE_MASK,
>>> +				     QCOM_FLASH_DISABLE_ALL);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Enable reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Set Vreg force */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_VREG_OK_FORCE,
>>> +				     QCOM_FLASH_VREG_MASK,
>>> +				     QCOM_FLASH_HW_VREG_OK);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Vreg OK reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Set self fault check */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_FAULT_DETECT,
>>> +				     QCOM_FLASH_FAULT_DETECT_MASK,
>>> +				     QCOM_FLASH_SELFCHECK_DISABLE);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Fault detect reg write failed(%d)\n",
>>> +			rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Set mask enable */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_MASK_ENABLE,
>>> +				     QCOM_FLASH_MASK_REG_MASK,
>>> +				     QCOM_FLASH_MASK_1);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Mask enable reg write failed(%d)\n",
>>> +			rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Set ramp rate */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_RAMP_RATE,
>>> +				     QCOM_FLASH_RAMP_RATE_MASK, 0xBF);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Ramp rate reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Enable VPH_PWR_DROOP and set threshold to 2.9V */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_VPH_PWR_DROOP,
>>> +				     QCOM_FLASH_VPH_PWR_DROOP_MASK, 0xC2);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "VPH_PWR_DROOP reg write failed(%d)\n",
>>> +			rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Set headroom */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_HEADROOM,
>>> +				     QCOM_FLASH_HEADROOM_MASK,
>>> +				     QCOM_FLASH_HEADROOM_500MV);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Headroom reg write failed(%d)\n", rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Set startup delay */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_STARTUP_DELAY,
>>> +				     QCOM_FLASH_STARTUP_DLY_MASK,
>>> +				     QCOM_FLASH_STARTUP_DLY_10US);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "Startup delay reg write failed(%d)\n",
>>> +			rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/*
>>> +	 * TODO The downstream driver also supported watchdog mode. Not sure
>>> +	 * about the difference, so only support safety timer for now
>>> +	 */
>>> +	/* Set timer control */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_TMR_CTRL,
>>> +				     QCOM_FLASH_TMR_MASK,
>>> +				     QCOM_FLASH_TMR_SAFETY);
>>> +	if (rc) {
>>> +		dev_err(leds_dev->dev, "LED timer ctrl reg write failed(%d)\n",
>>> +			rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	/* Set clamp current */
>>> +	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_CLAMP_CURR,
>>> +				     QCOM_FLASH_CURRENT_MASK,
>>> +				     qcom_flash_current_to_reg(QCOM_FLASH_DEFAULT_CLAMP));
>>> +	if (rc)
>>> +		dev_err(leds_dev->dev, "Clamp current reg write failed(%d)\n",
>>> +			rc);
>>> +
>>> +	return rc;
>>> +}
>>> +
>>> +static int qcom_flash_setup_led(struct qcom_flash_config *cfg,
>>> +				struct qcom_flash_led *led,
>>> +				enum qcom_flash_ids id,
>>> +				struct device_node *node)
>>> +{
>>> +	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
>>> +	struct led_classdev *led_cdev = &led->fled_cdev.led_cdev;
>>> +	int rc;
>>> +
>>> +	rc = qcom_flash_setup_fled(cfg, led, id);
>>> +	if (rc)
>>> +		return rc;
>>> +
>>> +	rc = qcom_flash_setup_flcdev(cfg, led, node);
>>> +	if (rc)
>>> +		return rc;
>>> +
>>> +	/* configure default state */
>>> +	if (!led->default_on) {
>>> +		led_cdev->brightness = LED_OFF;
>>> +	} else {
>>> +		led_cdev->brightness = led_cdev->max_brightness;
>>> +		mutex_lock(&leds_dev->lock);
>>> +		rc = qcom_flash_torch_on(led);
>>> +		mutex_unlock(&leds_dev->lock);
>>> +		if (rc)
>>> +			return rc;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_setup_leds_device(struct qcom_flash_device *leds_dev,
>>> +					struct qcom_flash_config *cfg,
>>> +					struct device *dev)
>>> +{
>>> +	int rc;
>>> +
>>> +	leds_dev->dev = dev;
>>> +
>>> +	leds_dev->base = cfg->base;
>>> +	leds_dev->num_leds = cfg->num_leds;
>>> +
>>> +	leds_dev->regmap = dev_get_regmap(dev->parent, NULL);
>>> +	if (!leds_dev->regmap) {
>>> +		dev_err(dev, "Failure getting regmap\n");
>>> +		return -ENODEV;
>>> +	}
>>> +
>>> +	rc = qcom_flash_setup_regs(leds_dev);
>>> +	if (rc)
>>> +		return rc;
>>> +
>>> +	rc = qcom_flash_read_reg(leds_dev, QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE,
>>> +				 &leds_dev->peripheral_subtype);
>>> +	if (rc) {
>>> +		dev_err(dev, "Unable to read from addr=%x, rc(%d)\n",
>>> +			QCOM_FLASH_ADDR_PERIPHERAL_SUBTYPE, rc);
>>> +		return rc;
>>> +	}
>>> +
>>> +	leds_dev->flash_supply = cfg->flash_supply;
>>> +
>>> +	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
>>> +		leds_dev->torch_supply = cfg->torch_supply;
>>> +		leds_dev->torch_enable_cmd = QCOM_FLASH_ENABLE_MODULE;
>>> +	} else {
>>> +		leds_dev->torch_enable_cmd = QCOM_FLASH_ENABLE_ALL;
>>> +	}
>>> +
>>> +	mutex_init(&leds_dev->lock);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int qcom_flash_parse_dt(struct device *dev,
>>> +			       struct qcom_flash_config *cfg,
>>> +			       struct device_node *sub_nodes[])
>>> +{
>>> +	struct device_node *node = dev->of_node;
>>> +	struct device_node *child_node;
>>> +	const char *temp_string;
>>> +	int rc, parsed_leds = 0;
>>> +	u32 val;
>>> +
>>> +	rc = of_property_read_u32(node, "reg", &val);
>>> +	if (rc < 0) {
>>> +		dev_err(dev, "Failure reading reg, rc = %d\n", rc);
>>> +		return rc;
>>> +	}
>>> +	cfg->base = val;
>>> +
>>> +	cfg->flash_supply = devm_regulator_get(dev, "flash-boost");
>>> +	cfg->torch_supply = devm_regulator_get(dev, "torch-boost");
>>> +
>>> +	for_each_available_child_of_node(node, child_node) {
>>> +		/* LED properties */
>>> +
>>> +		rc = of_property_read_u32(child_node, "reg",
>>> +					  &cfg->id[parsed_leds]);
>>> +		if (rc) {
>>> +			dev_err(dev, "Failure reading led id, rc =  %d\n", rc);
>>> +			of_node_put(child_node);
>>> +			return rc;
>>> +		}
>>> +
>>> +		/* Assume LED IDs are ordered in DT for simplicity */
>>
>> You need to mention this requirement in DT bindings, but I am not sure
>> if DT child nodes parsing order is guaranteed to be top-down.
> 
> Ok, I'll take a look at the documentation for the DT bindings if there's any
> clue on that, and check what other drivers normally do. I did that just because
> it's simpler, but I guess I could use a linked list for the nodes instead of an
> array, or maybe even simpler, have an array for the LED IDs read, so we can
> remove this restriction.

Right, just follow what other drivers do in similar cases.
There's no need to reinvent the wheel.

-- 
Best regards,
Jacek Anaszewski


From leo.yan at linaro.org  Sun Aug 29 06:54:09 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Sun, 29 Aug 2021 21:54:09 +0800
Subject: [PATCH v3] coresight: tmc-etr: Speed up for bounce buffer in flat mode
Message-ID: <20210829135409.186732-1-leo.yan@linaro.org>

The AUX bounce buffer is allocated with API dma_alloc_coherent(), in the
low level's architecture code, e.g. for Arm64, it maps the memory with
the attribution "Normal non-cacheable"; this can be concluded from the
definition for pgprot_dmacoherent() in arch/arm64/include/asm/pgtable.h.

Later when access the AUX bounce buffer, since the memory mapping is
non-cacheable, it's low efficiency due to every load instruction must
reach out DRAM.

This patch changes to allocate pages with alloc_pages_node(), thus the
driver can access the memory with cacheable mapping in the kernel linear
virtual address; therefore, because load instructions can fetch data
from cache lines rather than always read data from DRAM, the driver can
boost memory coping performance.  After using the cacheable mapping, the
driver uses dma_sync_single_for_cpu() to invalidate cacheline prior to
read bounce buffer so can avoid read stale trace data.

By measurement the duration for function tmc_update_etr_buffer() with
ftrace function_graph tracer, it shows the performance significant
improvement for copying 4MiB data from bounce buffer:

  # echo tmc_etr_get_data_flat_buf > set_graph_notrace // avoid noise
  # echo tmc_update_etr_buffer > set_graph_function
  # echo function_graph > current_tracer

  before:

  # CPU  DURATION                  FUNCTION CALLS
  # |     |   |                     |   |   |   |
  2)               |    tmc_update_etr_buffer() {
  ...
  2) # 8148.320 us |    }

  after:

  # CPU  DURATION                  FUNCTION CALLS
  # |     |   |                     |   |   |   |
  2)               |  tmc_update_etr_buffer() {
  ...
  2) # 2463.980 us |  }

Signed-off-by: Leo Yan <leo.yan at linaro.org>
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
---

Changes from v2:
Sync the entire buffer in one go when the tracing is wrap around
(Suzuki);
Add Suzuki's review tage.

Changes from v1:
Set "flat_buf->daddr" to 0 when fails to map DMA region; and dropped the
unexpected if condition change in tmc_etr_free_flat_buf().

 .../hwtracing/coresight/coresight-tmc-etr.c   | 47 ++++++++++++++++---
 1 file changed, 40 insertions(+), 7 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 13fd1fc730ed..ac37e9376d2b 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -21,6 +21,7 @@
 
 struct etr_flat_buf {
 	struct device	*dev;
+	struct page	*pages;
 	dma_addr_t	daddr;
 	void		*vaddr;
 	size_t		size;
@@ -600,6 +601,7 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata,
 {
 	struct etr_flat_buf *flat_buf;
 	struct device *real_dev = drvdata->csdev->dev.parent;
+	ssize_t	aligned_size;
 
 	/* We cannot reuse existing pages for flat buf */
 	if (pages)
@@ -609,11 +611,18 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata,
 	if (!flat_buf)
 		return -ENOMEM;
 
-	flat_buf->vaddr = dma_alloc_coherent(real_dev, etr_buf->size,
-					     &flat_buf->daddr, GFP_KERNEL);
-	if (!flat_buf->vaddr) {
-		kfree(flat_buf);
-		return -ENOMEM;
+	aligned_size = PAGE_ALIGN(etr_buf->size);
+	flat_buf->pages = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO,
+					   get_order(aligned_size));
+	if (!flat_buf->pages)
+		goto fail_alloc_pages;
+
+	flat_buf->vaddr = page_address(flat_buf->pages);
+	flat_buf->daddr = dma_map_page(real_dev, flat_buf->pages, 0,
+				       aligned_size, DMA_FROM_DEVICE);
+	if (dma_mapping_error(real_dev, flat_buf->daddr)) {
+		flat_buf->daddr = 0;
+		goto fail_dma_map_page;
 	}
 
 	flat_buf->size = etr_buf->size;
@@ -622,6 +631,12 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata,
 	etr_buf->mode = ETR_MODE_FLAT;
 	etr_buf->private = flat_buf;
 	return 0;
+
+fail_dma_map_page:
+	__free_pages(flat_buf->pages, get_order(aligned_size));
+fail_alloc_pages:
+	kfree(flat_buf);
+	return -ENOMEM;
 }
 
 static void tmc_etr_free_flat_buf(struct etr_buf *etr_buf)
@@ -630,15 +645,20 @@ static void tmc_etr_free_flat_buf(struct etr_buf *etr_buf)
 
 	if (flat_buf && flat_buf->daddr) {
 		struct device *real_dev = flat_buf->dev->parent;
+		ssize_t aligned_size = PAGE_ALIGN(etr_buf->size);
 
-		dma_free_coherent(real_dev, flat_buf->size,
-				  flat_buf->vaddr, flat_buf->daddr);
+		dma_unmap_page(real_dev, flat_buf->daddr, aligned_size,
+			       DMA_FROM_DEVICE);
+		__free_pages(flat_buf->pages, get_order(aligned_size));
 	}
 	kfree(flat_buf);
 }
 
 static void tmc_etr_sync_flat_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp)
 {
+	struct etr_flat_buf *flat_buf = etr_buf->private;
+	struct device *real_dev = flat_buf->dev->parent;
+
 	/*
 	 * Adjust the buffer to point to the beginning of the trace data
 	 * and update the available trace data.
@@ -648,6 +668,19 @@ static void tmc_etr_sync_flat_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp)
 		etr_buf->len = etr_buf->size;
 	else
 		etr_buf->len = rwp - rrp;
+
+	/*
+	 * The driver always starts tracing at the beginning of the buffer,
+	 * the only reason why we would get a wrap around is when the buffer
+	 * is full.  Sync the entire buffer in one go for this case.
+	 */
+	if (etr_buf->offset + etr_buf->len > etr_buf->size)
+		dma_sync_single_for_cpu(real_dev, flat_buf->daddr,
+					etr_buf->size, DMA_FROM_DEVICE);
+	else
+		dma_sync_single_for_cpu(real_dev,
+					flat_buf->daddr + etr_buf->offset,
+					etr_buf->len, DMA_FROM_DEVICE);
 }
 
 static ssize_t tmc_etr_get_data_flat_buf(struct etr_buf *etr_buf,
-- 
2.25.1



From andreyknvl at gmail.com  Sun Aug 29 07:10:31 2021
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Sun, 29 Aug 2021 16:10:31 +0200
Subject: [PATCH] arm64: kasan: mte: move GCR_EL1 switch to task switch
 when KASAN disabled
In-Reply-To: <20210827030748.587710-1-pcc@google.com>
References: <20210827030748.587710-1-pcc@google.com>
Message-ID: <CA+fCnZewbuNLU-0T0Ku8dfrc3oG21V5UQ6tLue0DwHSZXZ+ujQ@mail.gmail.com>

On Fri, Aug 27, 2021 at 5:07 AM Peter Collingbourne <pcc at google.com> wrote:
>
> It is not necessary to write to GCR_EL1 on every kernel entry and
> exit when HW tag-based KASAN is disabled because the kernel will not
> execute any IRG instructions in that mode. Since accessing GCR_EL1
> can be expensive on some microarchitectures, avoid doing so by moving
> the access to task switch when HW tag-based KASAN is disabled.
>
> Signed-off-by: Peter Collingbourne <pcc at google.com>
> ---
>  arch/arm64/kernel/entry.S | 10 +++++-----
>  arch/arm64/kernel/mte.c   | 24 +++++++++++++++++++++---
>  include/linux/kasan.h     |  9 +++++++--
>  3 files changed, 33 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 923ee2ac85fd..e12ed892cde8 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -178,9 +178,9 @@ alternative_else_nop_endif
>
>         .macro mte_set_kernel_gcr, tmp, tmp2
>  #ifdef CONFIG_KASAN_HW_TAGS
> -alternative_if_not ARM64_MTE
> +alternative_cb kasan_hw_tags_enable
>         b       1f
> -alternative_else_nop_endif
> +alternative_cb_end
>         mov     \tmp, KERNEL_GCR_EL1
>         msr_s   SYS_GCR_EL1, \tmp
>  1:
> @@ -188,10 +188,10 @@ alternative_else_nop_endif
>         .endm
>
>         .macro mte_set_user_gcr, tsk, tmp, tmp2
> -#ifdef CONFIG_ARM64_MTE
> -alternative_if_not ARM64_MTE
> +#ifdef CONFIG_KASAN_HW_TAGS
> +alternative_cb kasan_hw_tags_enable
>         b       1f
> -alternative_else_nop_endif
> +alternative_cb_end
>         ldr     \tmp, [\tsk, #THREAD_MTE_CTRL]
>
>         mte_set_gcr \tmp, \tmp2
> diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> index 9d314a3bad3b..0e8edb5d5861 100644
> --- a/arch/arm64/kernel/mte.c
> +++ b/arch/arm64/kernel/mte.c
> @@ -162,7 +162,7 @@ void mte_check_tfsr_el1(void)
>  }
>  #endif
>
> -static void mte_update_sctlr_user(struct task_struct *task)
> +static void mte_update_sctlr_user_and_gcr_excl(struct task_struct *task)
>  {
>         /*
>          * This must be called with preemption disabled and can only be called
> @@ -182,6 +182,24 @@ static void mte_update_sctlr_user(struct task_struct *task)
>         else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
>                 sctlr |= SCTLR_EL1_TCF0_SYNC;
>         task->thread.sctlr_user = sctlr;
> +
> +       /*
> +        * SYS_GCR_EL1 will be set to current->thread.mte_ctrl value by
> +        * mte_set_user_gcr() in kernel_exit, but only if KASAN is enabled.
> +        */
> +       if (!kasan_hw_tags_enabled())
> +               write_sysreg_s(((mte_ctrl >> MTE_CTRL_GCR_USER_EXCL_SHIFT) &
> +                               SYS_GCR_EL1_EXCL_MASK) | SYS_GCR_EL1_RRND,
> +                              SYS_GCR_EL1);
> +}
> +
> +void __init kasan_hw_tags_enable(struct alt_instr *alt, __le32 *origptr,
> +                                __le32 *updptr, int nr_inst)
> +{
> +       BUG_ON(nr_inst != 1); /* Branch -> NOP */
> +
> +       if (kasan_hw_tags_enabled())
> +               *updptr = cpu_to_le32(aarch64_insn_gen_nop());
>  }
>
>  void mte_thread_init_user(void)
> @@ -199,7 +217,7 @@ void mte_thread_init_user(void)
>
>  void mte_thread_switch(struct task_struct *next)
>  {
> -       mte_update_sctlr_user(next);
> +       mte_update_sctlr_user_and_gcr_excl(next);
>
>         /*
>          * Check if an async tag exception occurred at EL1.
> @@ -244,7 +262,7 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
>         task->thread.mte_ctrl = mte_ctrl;
>         if (task == current) {
>                 preempt_disable();
> -               mte_update_sctlr_user(task);
> +               mte_update_sctlr_user_and_gcr_excl(task);
>                 update_sctlr_el1(task->thread.sctlr_user);
>                 preempt_enable();
>         }
> diff --git a/include/linux/kasan.h b/include/linux/kasan.h
> index dd874a1ee862..de5f5913374d 100644
> --- a/include/linux/kasan.h
> +++ b/include/linux/kasan.h
> @@ -89,7 +89,7 @@ static __always_inline bool kasan_enabled(void)
>         return static_branch_likely(&kasan_flag_enabled);
>  }
>
> -static inline bool kasan_has_integrated_init(void)
> +static inline bool kasan_hw_tags_enabled(void)
>  {
>         return kasan_enabled();
>  }
> @@ -104,7 +104,7 @@ static inline bool kasan_enabled(void)
>         return IS_ENABLED(CONFIG_KASAN);
>  }
>
> -static inline bool kasan_has_integrated_init(void)
> +static inline bool kasan_hw_tags_enabled(void)
>  {
>         return false;
>  }
> @@ -125,6 +125,11 @@ static __always_inline void kasan_free_pages(struct page *page,
>
>  #endif /* CONFIG_KASAN_HW_TAGS */
>
> +static inline bool kasan_has_integrated_init(void)
> +{
> +       return kasan_hw_tags_enabled();
> +}
> +
>  #ifdef CONFIG_KASAN
>
>  struct kasan_cache {
> --
> 2.33.0.259.gc128427fd7-goog
>

Acked-by: Andrey Konovalov <andreyknvl at gmail.com>

for non-arm-specific KASAN parts.


From jic23 at kernel.org  Sun Aug 29 07:15:49 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 15:15:49 +0100
Subject: [PATCH v1 1/2] iio: mtk-auxadc: add support IIO_CHAN_INFO_RAW case
In-Reply-To: <9fa19fb18910a593d25fb894237b3c59764db53e.camel@mediatek.com>
References: <20210812054844.30575-1-hui.liu@mediatek.com>
 <20210812054844.30575-2-hui.liu@mediatek.com>
 <20210812190725.00007449@Huawei.com>
 <042625639032bffe73b60a5c6274511e58e34ef4.camel@mediatek.com>
 <20210814171007.6892ae94@jic23-huawei>
 <470d4a7fbbcbcaa35aa9dcbaab6a2b77f98dc528.camel@mediatek.com>
 <20210817165418.4b1cfdce@jic23-huawei>
 <a6211ac1b3ab14931499744023ee60c1e82424a8.camel@mediatek.com>
 <SI2PR03MB56901E5D00D47948BE0E9F989BC69@SI2PR03MB5690.apcprd03.prod.outlook.com>
 <9fa19fb18910a593d25fb894237b3c59764db53e.camel@mediatek.com>
Message-ID: <20210829151549.266c95ab@jic23-huawei>

On Thu, 26 Aug 2021 10:27:34 +0800
hui.liu <hui.liu at mediatek.com> wrote:

> Hi Jonathan,
> 
> Our internal Kernel module CCCI use _RAW case, we described in the
> previous mail. Could you give your suggestion?

Fix your internal module?  I would have assumed it would want
calibrated values if available, so it seems a little odd to use _RAW.
If there is a good reason for it doing so that you can talk about here
then perhaps we can consider it.

As a general rule we don't put any significant effort into supporting
out of tree drivers so I'm not very keen on adding _RAW on the basis
one uses it.

Jonathan


> 
> Thanks.
> Hui
> 
> > 
> > On Tue, 2021-08-17 at 16:54 +0100, Jonathan Cameron wrote:  
> > > On Tue, 17 Aug 2021 16:37:52 +0800
> > > hui.liu <hui.liu at mediatek.com> wrote:
> > >   
> > > > On Sat, 2021-08-14 at 17:10 +0100, Jonathan Cameron wrote:  
> > > > > On Fri, 13 Aug 2021 11:46:24 +0800 hui.liu <  
> > > > > hui.liu at mediatek.com>   
> > > > > wrote:
> > > > >     
> > > > > > On Thu, 2021-08-12 at 19:07 +0100, Jonathan Cameron wrote:    
> > > > > > > On Thu, 12 Aug 2021 13:48:43 +0800 Hui Liu 
> > > > > > > <hui.liu at mediatek.com> wrote:
> > > > > > >       
> > > > > > > > Add support IIO_CHAN_INFO_RAW case.      
> > > > > > > 
> > > > > > > Why?
> > > > > > > 
> > > > > > > We almost never support both RAW and PROCESSED as
> > > > > > > userspace 
> > > > > > > should be fine to use either.  There are a few reasons
> > > > > > > we've 
> > > > > > > let drivers do this but I would like know why it matters
> > > > > > > to 
> > > > > > > you and it definitely needs to be in the patch description.
> > > > > > >       
> > > > > > 
> > > > > > Hi Jonathan,
> > > > > > 
> > > > > > 1. To support ADC consumers' different types of requirement:
> > > > > > some
> > > > > > consumers want to call iio_read_channel_raw to get raw data,
> > > > > > the 
> > > > > > others use iio_read_channel_processed to get voltage.  
> > > > > 
> > > > > Give an example of the consumer using the raw channel readback 
> > > > > (without acess to any scaling information?)
> > > > >     
> > > > > > 2. In our origin driver, if consumer call 
> > > > > > iio_read_channel_processed, read back value is raw data.
> > > > > > 
> > > > > > Could we use SCALE instead of PROCESSED in patch for next 
> > > > > > version, or what's your suggestion?  
> > > > > 
> > > > > That would unfortunately be a userspace ABI change.  We can
> > > > > add 
> > > > > interfaces but taking them away is normally a problem :(
> > > > > 
> > > > > Your reasons here are fine, subject to information on what 
> > > > > consumer cares about having _RAW, please resend the patch with 
> > > > > this information added to the description.
> > > > > 
> > > > > Thanks,
> > > > > 
> > > > > Jonathan  
> > > > 
> > > > 1. We found afe/iio-rescale.c, dac/dpot-dac.c and
> > > > multiplexer/iio- 
> > > > mux.c call iio_read_channel_raw to get raw data. If they use our
> > > > ADC 
> > > > driver, I think we should support _RAW case.
> > > > If we support _RAW case, we will add more information in v2 
> > > > description.  
> > > 
> > > iio-rescale has recently gained support for processed.
> > >   
> > 
> >   
> https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/commit/drivers/iio/afe/iio-rescale.c?h=testing&id=53ebee9499805add3eef630d998c40812e6a1c39
> > > dpot-dac is a rather obscure special case, so I doubt you actually 
> > > have one of those.
> > > If iio-mux is relevant then we should add processed support to
> > > that 
> > > driver as well.
> > > 
> > > I would rather see those users of the interface fixed than us
> > > having 
> > > to tweak lots of drivers to provide _raw when it isn't appropriate
> > > for 
> > > that piece of hardware.
> > > 
> > > Jonathan
> > >   
> > 
> > Hi Jonathan,
> > 
> > For we have an internal use scenario:
> > Our internal Kernel module CCCI(Communication interface between AP
> > Core and Modem) would like get raw data from ADC, but CCCI driver
> > have not do upstream now.
> > 
> > If we no need add _RAW, we will only change _PROCESSED readback value
> > in the next version of patch.
> >   
> > > > 
> > > > 2. Since we change _PROCESSED readback value from raw data to 
> > > > voltage, our consumer will make the changes synchronously.
> > > >   
> > > > > > 
> > > > > > Thanks.
> > > > > >     
> > > > > > > > 
> > > > > > > > Signed-off-by: Hui Liu <hui.liu at mediatek.com>
> > > > > > > > ---
> > > > > > > >  drivers/iio/adc/mt6577_auxadc.c | 16 +++++++++++++++-
> > > > > > > >  1 file changed, 15 insertions(+), 1 deletion(-)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/iio/adc/mt6577_auxadc.c 
> > > > > > > > b/drivers/iio/adc/mt6577_auxadc.c index 
> > > > > > > > 79c1dd68b909..e995d43287b2 100644
> > > > > > > > --- a/drivers/iio/adc/mt6577_auxadc.c
> > > > > > > > +++ b/drivers/iio/adc/mt6577_auxadc.c
> > > > > > > > @@ -60,7 +60,8 @@ static const struct
> > > > > > > > mtk_auxadc_compatible 
> > > > > > > > mt6765_compat = {
> > > > > > > >  		.type = IIO_VOLTAGE,				
> > > > > > > >    
> > > > > > > >  \
> > > > > > > >  		.indexed = 1,					
> > > > > > > >    
> > > > > > > >  \
> > > > > > > >  		.channel = (idx),				
> > > > > > > >     \
> > > > > > > > -		.info_mask_separate =
> > > > > > > > BIT(IIO_CHAN_INFO_PROCESSED), \
> > > > > > > > +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	
> > > > > > > >    
> > > > > > > >  \
> > > > > > > > +				      BIT(IIO_CHAN_INFO_PROCESS
> > > > > > > > ED), \
> > > > > > > >  }
> > > > > > > >  
> > > > > > > >  static const struct iio_chan_spec 
> > > > > > > > mt6577_auxadc_iio_channels[] = { @@ -181,6 +182,19 @@
> > > > > > > > static 
> > > > > > > > int mt6577_auxadc_read_raw(struct iio_dev *indio_dev,
> > > > > > > >  	struct mt6577_auxadc_device *adc_dev = 
> > > > > > > > iio_priv(indio_dev);
> > > > > > > >  
> > > > > > > >  	switch (info) {
> > > > > > > > +	case IIO_CHAN_INFO_RAW:
> > > > > > > > +		*val = mt6577_auxadc_read(indio_dev, chan);
> > > > > > > > +		if (*val < 0) {
> > > > > > > > +			dev_notice(indio_dev->dev.parent,
> > > > > > > > +				"failed to sample data on
> > > > > > > > channel[%d]\n",
> > > > > > > > +				chan->channel);
> > > > > > > > +			return *val;
> > > > > > > > +		}
> > > > > > > > +		if (adc_dev->dev_comp->sample_data_cali)
> > > > > > > > +			*val = mt_auxadc_get_cali_data(*val,
> > > > > > > > true);
> > > > > > > > +
> > > > > > > > +		return IIO_VAL_INT;
> > > > > > > > +
> > > > > > > >  	case IIO_CHAN_INFO_PROCESSED:
> > > > > > > >  		*val = mt6577_auxadc_read(indio_dev, chan);
> > > > > > > >  		if (*val < 0) {      
> > > > > > > 
> > > > > > >       
> > > > > 
> > > > >     
> > > 
> > >   
> > 
> >   



From leo.yan at linaro.org  Sun Aug 29 07:28:02 2021
From: leo.yan at linaro.org (Leo Yan)
Date: Sun, 29 Aug 2021 22:28:02 +0800
Subject: [PATCH] coresight: cti: Correct the parameter for pm_runtime_put
In-Reply-To: <1629365377-5937-1-git-send-email-quic_taozha@quicinc.com>
References: <1629365377-5937-1-git-send-email-quic_taozha@quicinc.com>
Message-ID: <20210829142802.GA186881@leoy-ThinkPad-X240s>

Hi Tao,

On Thu, Aug 19, 2021 at 05:29:37PM +0800, Tao Zhang wrote:
> The input parameter of the function pm_runtime_put should be the
> same in the function cti_enable_hw and cti_disable_hw. The correct
> parameter to use here should be dev->parent.
> 
> Signed-off-by: Tao Zhang <quic_taozha at quicinc.com>
> ---
>  drivers/hwtracing/coresight/coresight-cti-core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
> index e2a3620..8988b2e 100644
> --- a/drivers/hwtracing/coresight/coresight-cti-core.c
> +++ b/drivers/hwtracing/coresight/coresight-cti-core.c
> @@ -175,7 +175,7 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
>  	coresight_disclaim_device_unlocked(csdev);
>  	CS_LOCK(drvdata->base);
>  	spin_unlock(&drvdata->spinlock);
> -	pm_runtime_put(dev);
> +	pm_runtime_put(dev->parent);

coresight_register() allocates data structure 'coresight_device' and
assigns probed device to the field 'coresight_device::dev::parent';
thus afterwards we need to pass 'coresight_device::dev::parent' for
pm_runtime_xxx() functions.  It's not directive for understanding, so
log the info at here.

For the patch:

Reviewed-by: Leo Yan <leo.yan at linaro.org>

We could wait for Mike to review as well.

Thanks,
Leo

>  	return 0;
>  
>  	/* not disabled this call */
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 


From jic23 at kernel.org  Sun Aug 29 07:53:44 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 15:53:44 +0100
Subject: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <DEB9D606-6489-4993-A5E7-6E4F3226EE5A@aspeedtech.com>
References: <20210823070240.12600-1-billy_tsai@aspeedtech.com>
 <20210823070240.12600-2-billy_tsai@aspeedtech.com>
 <YSTiUPQa+HYSA63t@robh.at.kernel.org>
 <DEB9D606-6489-4993-A5E7-6E4F3226EE5A@aspeedtech.com>
Message-ID: <20210829155344.370348d1@jic23-huawei>

On Wed, 25 Aug 2021 00:06:47 +0000
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> Hi Rob,
> 
> On 2021/8/24, 8:13 PM, "Rob Herring" <robh at kernel.org> wrote:
> 
>     On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
>     >   > +properties:
>     >   > +  compatible:
>     >   > +    enum:
>     >   > +      - aspeed,ast2600-adc0
>     >   > +      - aspeed,ast2600-adc1  
> 
>     > What's the difference between 0 and 1?  
> 
> Their trimming data, which is used to calibrate internal reference volage,
> locates in different address of OTP.

At very least document that with a description: here to avoid anyone looking
at this later asking the same question! 

Jonathan

> 
> Best Regards,
> Billy Tsai
> 
>  
> 



From jic23 at kernel.org  Sun Aug 29 08:07:08 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:07:08 +0100
Subject: [RESEND v4 02/15] iio: adc: aspeed: completes the bitfield
 declare.
In-Reply-To: <20210824091243.9393-3-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <20210824091243.9393-3-billy_tsai@aspeedtech.com>
Message-ID: <20210829160708.2b1a26c0@jic23-huawei>

On Tue, 24 Aug 2021 17:12:30 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> This patch completes the declare of adc register bitfields and uses the
> same prefix ASPEED_ADC_* for these bitfields.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  drivers/iio/adc/aspeed_adc.c | 56 +++++++++++++++++++++++++-----------
>  1 file changed, 39 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 19efaa41bc34..7010d56ac3b9 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -3,6 +3,7 @@
>   * Aspeed AST2400/2500 ADC
>   *
>   * Copyright (C) 2017 Google, Inc.
> + * Copyright (C) 2021 Aspeed Technology Inc.
>   */
>  
>  #include <linux/clk.h>
> @@ -16,6 +17,7 @@
>  #include <linux/reset.h>
>  #include <linux/spinlock.h>
>  #include <linux/types.h>
> +#include <linux/bitfield.h>
>  
>  #include <linux/iio/iio.h>
>  #include <linux/iio/driver.h>
> @@ -28,15 +30,31 @@
>  #define ASPEED_REG_INTERRUPT_CONTROL	0x04
>  #define ASPEED_REG_VGA_DETECT_CONTROL	0x08
>  #define ASPEED_REG_CLOCK_CONTROL	0x0C
> -#define ASPEED_REG_MAX			0xC0
> -
> -#define ASPEED_OPERATION_MODE_POWER_DOWN	(0x0 << 1)
> -#define ASPEED_OPERATION_MODE_STANDBY		(0x1 << 1)
> -#define ASPEED_OPERATION_MODE_NORMAL		(0x7 << 1)
> -
> -#define ASPEED_ENGINE_ENABLE		BIT(0)
> -
> -#define ASPEED_ADC_CTRL_INIT_RDY	BIT(8)
> +#define ASPEED_REG_COMPENSATION_TRIM	0xC4
> +#define ASPEED_REG_MAX			0xCC

This REG_MAX value is used as a sanity check for debugfs based access.
As this raises the limit for all devices supported by the driver, not just the
new ast2600, are we fine to read these non existent registers on the other
parts?  If so, perhaps a comment to say that here somewhere?

> +
> +#define ASPEED_ADC_ENGINE_ENABLE		BIT(0)

Are all the following in the same register?  Bit usual to have
overlapping fields, so if they are, perhaps a few comments to
explain what is going on would be good.

> +#define ASPEED_ADC_OP_MODE			GENMASK(3, 1)
> +#define ASPEED_ADC_OP_MODE_PWR_DOWN		0
> +#define ASPEED_ADC_OP_MODE_STANDBY		1
> +#define ASPEED_ADC_OP_MODE_NORMAL		7
> +#define ASPEED_ADC_CTRL_COMPENSATION		BIT(4)
> +#define ASPEED_ADC_AUTO_COMPENSATION		BIT(5)
> +#define ASPEED_ADC_REF_VOLTAGE			GENMASK(7, 6)
> +#define ASPEED_ADC_REF_VOLTAGE_2500mV		0
> +#define ASPEED_ADC_REF_VOLTAGE_1200mV		1
> +#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH		2
> +#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW		3
> +#define ASPEED_ADC_BAT_SENSING_DIV		BIT(6)
> +#define ASPEED_ADC_BAT_SENSING_DIV_2_3		0
> +#define ASPEED_ADC_BAT_SENSING_DIV_1_3		1
> +#define ASPEED_ADC_CTRL_INIT_RDY		BIT(8)
> +#define ASPEED_ADC_CH7_MODE			BIT(12)
> +#define ASPEED_ADC_CH7_NORMAL			0
> +#define ASPEED_ADC_CH7_BAT			1
> +#define ASPEED_ADC_BAT_SENSING_ENABLE		BIT(13)
> +#define ASPEED_ADC_CTRL_CHANNEL			GENMASK(31, 16)
> +#define ASPEED_ADC_CTRL_CHANNEL_ENABLE(ch)	FIELD_PREP(ASPEED_ADC_CTRL_CHANNEL, BIT(ch))
>  
>  #define ASPEED_ADC_INIT_POLLING_TIME	500
>  #define ASPEED_ADC_INIT_TIMEOUT		500000
> @@ -226,7 +244,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  
>  	if (model_data->wait_init_sequence) {
>  		/* Enable engine in normal mode. */
> -		writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
> +		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
> +				  ASPEED_ADC_OP_MODE_NORMAL) |
> +			       ASPEED_ADC_ENGINE_ENABLE,
>  		       data->base + ASPEED_REG_ENGINE_CONTROL);
>  
>  		/* Wait for initial sequence complete. */
> @@ -245,10 +265,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto clk_enable_error;
>  
> -	adc_engine_control_reg_val = GENMASK(31, 16) |
> -		ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE;
> +	adc_engine_control_reg_val =
> +		ASPEED_ADC_CTRL_CHANNEL |
> +		FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
> +		ASPEED_ADC_ENGINE_ENABLE;
>  	writel(adc_engine_control_reg_val,
> -		data->base + ASPEED_REG_ENGINE_CONTROL);
> +	       data->base + ASPEED_REG_ENGINE_CONTROL);
>  
>  	model_data = of_device_get_match_data(&pdev->dev);
>  	indio_dev->name = model_data->model_name;
> @@ -264,8 +286,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	return 0;
>  
>  iio_register_error:
> -	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
> -		data->base + ASPEED_REG_ENGINE_CONTROL);
> +	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
> +	       data->base + ASPEED_REG_ENGINE_CONTROL);
>  	clk_disable_unprepare(data->clk_scaler->clk);
>  clk_enable_error:
>  poll_timeout_error:
> @@ -283,8 +305,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
>  	struct aspeed_adc_data *data = iio_priv(indio_dev);
>  
>  	iio_device_unregister(indio_dev);
> -	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
> -		data->base + ASPEED_REG_ENGINE_CONTROL);
> +	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
> +	       data->base + ASPEED_REG_ENGINE_CONTROL);

Ideally these white space changes would be in a precursor patch.
At the very least mention them in the patch description.  They are good
thing to tidy up, but they do add noise to this patch.

>  	clk_disable_unprepare(data->clk_scaler->clk);
>  	reset_control_assert(data->rst);
>  	clk_hw_unregister_divider(data->clk_scaler);



From jic23 at kernel.org  Sun Aug 29 08:13:18 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:13:18 +0100
Subject: [RESEND v4 05/15] iio: adc: aspeed: Refactory model data structure
In-Reply-To: <20210824091243.9393-6-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <20210824091243.9393-6-billy_tsai@aspeedtech.com>
Message-ID: <20210829161318.54997151@jic23-huawei>

On Tue, 24 Aug 2021 17:12:33 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> This patch refactory the model data structure to distinguish the
> function form differnet version of aspeed adc.

from different versions 

> - Rename the vref_voltag to vref_fixed and add vref driver data

vref_voltage

> When driver probe will check vref_fixed value and store it
> to vref which isn't const value.
> - Add num_channels
> Make num_channles of iio device can be changed by differnet model_data

different

> - Add need_prescaler flag and scaler_bit_width
> The need_prescaler flag used to tell the driver the clock divider needs
> another prescaler and the scaler_bit_width to set the clock divider
> bitfiled width.

bitfield?

> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  drivers/iio/adc/aspeed_adc.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index d85aa31ee3b1..f03c7921d534 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -63,8 +63,11 @@ struct aspeed_adc_model_data {
>  	const char *model_name;
>  	unsigned int min_sampling_rate;	// Hz
>  	unsigned int max_sampling_rate;	// Hz
> -	unsigned int vref_voltage;	// mV
> +	unsigned int vref_fixed;	// mV

Whilst here, you could make the name carry the information of the units.
e.g. vref_fixed_mv;  That way we always know what the units are without having
to spot this comment.

>  	bool wait_init_sequence;
> +	bool need_prescaler;
> +	u8 scaler_bit_width;
> +	unsigned int num_channels;
>  };
>  
>  struct aspeed_adc_data {
> @@ -75,6 +78,7 @@ struct aspeed_adc_data {
>  	struct clk_hw		*clk_prescaler;
>  	struct clk_hw		*clk_scaler;
>  	struct reset_control	*rst;
> +	int			vref;
vref_mv as above perhaps?
>  };
>  
>  #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
> @@ -118,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
>  		return IIO_VAL_INT;
>  
>  	case IIO_CHAN_INFO_SCALE:
> -		*val = data->model_data->vref_voltage;
> +		*val = data->model_data->vref_fixed;
>  		*val2 = ASPEED_RESOLUTION_BITS;
>  		return IIO_VAL_FRACTIONAL_LOG2;
>  
> @@ -312,17 +316,23 @@ static int aspeed_adc_remove(struct platform_device *pdev)
>  
>  static const struct aspeed_adc_model_data ast2400_model_data = {
>  	.model_name = "ast2400-adc",
> -	.vref_voltage = 2500, // mV
> +	.vref_fixed = 2500, // mV
>  	.min_sampling_rate = 10000,
>  	.max_sampling_rate = 500000,
> +	.need_prescaler = true,
> +	.scaler_bit_width = 10,
> +	.num_channels = 16,
>  };
>  
>  static const struct aspeed_adc_model_data ast2500_model_data = {
>  	.model_name = "ast2500-adc",
> -	.vref_voltage = 1800, // mV
> +	.vref_fixed = 1800, // mV
>  	.min_sampling_rate = 1,
>  	.max_sampling_rate = 1000000,
>  	.wait_init_sequence = true,
> +	.need_prescaler = true,
> +	.scaler_bit_width = 10,
> +	.num_channels = 16,
>  };
>  
>  static const struct of_device_id aspeed_adc_matches[] = {



From jic23 at kernel.org  Sun Aug 29 08:20:22 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:20:22 +0100
Subject: [RESEND v4 08/15] iio: adc: aspeed: Use model_data to set clk
 scaler.
In-Reply-To: <202108250006.17P06IgG097015@twspam01.aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <202108250006.17P06IgG097015@twspam01.aspeedtech.com>
Message-ID: <20210829162022.7ee18854@jic23-huawei>

On Tue, 24 Aug 2021 17:12:36 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> This patch use need_prescaler and scaler_bit_width to set the adc clock
> scaler.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
Hi Billy,

One minor comment inline.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/aspeed_adc.c | 39 +++++++++++++++++++++---------------
>  1 file changed, 23 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 2d6215a91f99..52db38be9699 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -202,9 +202,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  {
>  	struct iio_dev *indio_dev;
>  	struct aspeed_adc_data *data;
> -	const char *clk_parent_name;
>  	int ret;
>  	u32 adc_engine_control_reg_val;
> +	unsigned long scaler_flags = 0;
> +	char clk_name[32], clk_parent_name[32];
>  
>  	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
>  	if (!indio_dev)
> @@ -221,24 +222,28 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  
>  	/* Register ADC clock prescaler with source specified by device tree. */
>  	spin_lock_init(&data->clk_lock);
> -	clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
> -
> -	data->clk_prescaler = clk_hw_register_divider(
> -				&pdev->dev, "prescaler", clk_parent_name, 0,
> -				data->base + ASPEED_REG_CLOCK_CONTROL,
> -				17, 15, 0, &data->clk_lock);
> -	if (IS_ERR(data->clk_prescaler))
> -		return PTR_ERR(data->clk_prescaler);
> -
> +	snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));

ARRAY_SIZE(clk_parent_name) instead of 32.
Same for other places this pattern occurs.


> +	if (data->model_data->need_prescaler) {
> +		snprintf(clk_name, 32, "%s-prescaler",
> +			 data->model_data->model_name);
> +		data->clk_prescaler = clk_hw_register_divider(
> +			&pdev->dev, clk_name, clk_parent_name, 0,
> +			data->base + ASPEED_REG_CLOCK_CONTROL, 17, 15, 0,
> +			&data->clk_lock);
> +		if (IS_ERR(data->clk_prescaler))
> +			return PTR_ERR(data->clk_prescaler);
> +		snprintf(clk_parent_name, 32, clk_name);
> +		scaler_flags = CLK_SET_RATE_PARENT;
> +	}
>  	/*
>  	 * Register ADC clock scaler downstream from the prescaler. Allow rate
>  	 * setting to adjust the prescaler as well.
>  	 */
> +	snprintf(clk_name, 32, "%s-scaler", data->model_data->model_name);
>  	data->clk_scaler = clk_hw_register_divider(
> -				&pdev->dev, "scaler", "prescaler",
> -				CLK_SET_RATE_PARENT,
> -				data->base + ASPEED_REG_CLOCK_CONTROL,
> -				0, 10, 0, &data->clk_lock);
> +		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
> +		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
> +		data->model_data->scaler_bit_width, 0, &data->clk_lock);
>  	if (IS_ERR(data->clk_scaler)) {
>  		ret = PTR_ERR(data->clk_scaler);
>  		goto scaler_error;
> @@ -310,7 +315,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  reset_error:
>  	clk_hw_unregister_divider(data->clk_scaler);
>  scaler_error:
> -	clk_hw_unregister_divider(data->clk_prescaler);
> +	if (data->model_data->need_prescaler)
> +		clk_hw_unregister_divider(data->clk_prescaler);
>  	return ret;
>  }
>  
> @@ -325,7 +331,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
>  	clk_disable_unprepare(data->clk_scaler->clk);
>  	reset_control_assert(data->rst);
>  	clk_hw_unregister_divider(data->clk_scaler);
> -	clk_hw_unregister_divider(data->clk_prescaler);
> +	if (data->model_data->need_prescaler)
> +		clk_hw_unregister_divider(data->clk_prescaler);
>  
>  	return 0;
>  }



From jic23 at kernel.org  Sun Aug 29 08:25:48 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:25:48 +0100
Subject: [RESEND v4 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
In-Reply-To: <202108250004.17P04FdD094082@twspam01.aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <202108250004.17P04FdD094082@twspam01.aspeedtech.com>
Message-ID: <20210829162548.40aa9f91@jic23-huawei>

On Tue, 24 Aug 2021 17:12:37 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> This patch use devm_add_action_or_reset to handle the error in probe
> phase.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  drivers/iio/adc/aspeed_adc.c | 92 +++++++++++++++++++++---------------
>  1 file changed, 55 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 52db38be9699..1c87e12a0cab 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -187,6 +187,27 @@ static const struct iio_info aspeed_adc_iio_info = {
>  	.debugfs_reg_access = aspeed_adc_reg_access,
>  };
>  
> +static void aspeed_adc_unregister_divider(void *data)
> +{
> +	struct clk_hw *clk = data;
> +
> +	clk_hw_unregister_divider(clk);
> +}
> +
> +static void aspeed_adc_reset_assert(void *data)
> +{
> +	struct reset_control *rst = data;
> +
> +	reset_control_assert(rst);
> +}
> +
> +static void aspeed_adc_clk_disable_unprepare(void *data)
> +{
> +	struct clk *clk = data;
> +
> +	clk_disable_unprepare(clk);
> +}
> +
>  static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
>  {
>  	struct aspeed_adc_data *data = iio_priv(indio_dev);
> @@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  			&data->clk_lock);
>  		if (IS_ERR(data->clk_prescaler))
>  			return PTR_ERR(data->clk_prescaler);
> +
> +		ret = devm_add_action_or_reset(data->dev,
> +					       aspeed_adc_unregister_divider,
> +					       data->clk_prescaler);
> +		if (ret)
> +			return ret;
>  		snprintf(clk_parent_name, 32, clk_name);
>  		scaler_flags = CLK_SET_RATE_PARENT;
>  	}
> @@ -244,23 +271,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
>  		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
>  		data->model_data->scaler_bit_width, 0, &data->clk_lock);
> -	if (IS_ERR(data->clk_scaler)) {
> -		ret = PTR_ERR(data->clk_scaler);
> -		goto scaler_error;
> -	}
> +	if (IS_ERR(data->clk_scaler))
> +		return PTR_ERR(data->clk_scaler);
> +
> +	ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
> +				       data->clk_scaler);
> +	if (ret)
> +		return ret;
>  
>  	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
>  	if (IS_ERR(data->rst)) {
>  		dev_err(&pdev->dev,
>  			"invalid or missing reset controller device tree entry");
> -		ret = PTR_ERR(data->rst);
> -		goto reset_error;
> +		return PTR_ERR(data->rst);
>  	}
>  	reset_control_deassert(data->rst);
>  
> +	ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
> +				       data->rst);
> +	if (ret)
> +		return ret;
> +
>  	ret = aspeed_adc_vref_config(indio_dev);
>  	if (ret)
> -		goto vref_config_error;
> +		return ret;
>  
>  	if (data->model_data->wait_init_sequence) {
>  		/* Enable engine in normal mode. */
> @@ -277,13 +311,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  					 ASPEED_ADC_INIT_POLLING_TIME,
>  					 ASPEED_ADC_INIT_TIMEOUT);
>  		if (ret)
> -			goto poll_timeout_error;
> +			return ret;
>  	}
>  
>  	/* Start all channels in normal mode. */
>  	ret = clk_prepare_enable(data->clk_scaler->clk);
>  	if (ret)
> -		goto clk_enable_error;
> +		return ret;
> +
> +	ret = devm_add_action_or_reset(data->dev,
> +				       aspeed_adc_clk_disable_unprepare,
> +				       data->clk_scaler->clk);
> +	if (ret)
> +		return ret;
>  
>  	adc_engine_control_reg_val =
>  		ASPEED_ADC_CTRL_CHANNEL |
> @@ -299,41 +339,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	indio_dev->num_channels = data->model_data->num_channels;
>  
>  	ret = iio_device_register(indio_dev);
> -	if (ret)
> -		goto iio_register_error;
> -
> +	if (ret) {
> +		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
> +				  ASPEED_ADC_OP_MODE_PWR_DOWN),
> +		       data->base + ASPEED_REG_ENGINE_CONTROL);
> +		return ret;
> +	}
>  	return 0;
> -
> -iio_register_error:
> -	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
> -	       data->base + ASPEED_REG_ENGINE_CONTROL);
> -	clk_disable_unprepare(data->clk_scaler->clk);
> -clk_enable_error:
> -poll_timeout_error:
> -vref_config_error:
> -	reset_control_assert(data->rst);
> -reset_error:
> -	clk_hw_unregister_divider(data->clk_scaler);
> -scaler_error:
> -	if (data->model_data->need_prescaler)
> -		clk_hw_unregister_divider(data->clk_prescaler);
> -	return ret;
>  }
>  
>  static int aspeed_adc_remove(struct platform_device *pdev)
>  {
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> -	struct aspeed_adc_data *data = iio_priv(indio_dev);
> -
>  	iio_device_unregister(indio_dev);

Given there is no longer anything here, you should be safe to call
devm_iio_device_unregister() and get rid of this function entirely.


> -	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
> -	       data->base + ASPEED_REG_ENGINE_CONTROL);

Unless I'm missing something this is not handled via any of the
devm_add_action_or_reset() callbacks. You handle it in the error paths manually
but if you move this to managed as well you can drop that handling and still
have it automatically called on remove.


> -	clk_disable_unprepare(data->clk_scaler->clk);
> -	reset_control_assert(data->rst);
> -	clk_hw_unregister_divider(data->clk_scaler);
> -	if (data->model_data->need_prescaler)
> -		clk_hw_unregister_divider(data->clk_prescaler);
> -
>  	return 0;
>  }
>  



From jic23 at kernel.org  Sun Aug 29 08:31:37 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:31:37 +0100
Subject: [RESEND v4 10/15] iio: adc: aspeed: Support ast2600 adc.
In-Reply-To: <20210824091243.9393-11-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <20210824091243.9393-11-billy_tsai@aspeedtech.com>
Message-ID: <20210829163137.4c0ce7b0@jic23-huawei>

On Tue, 24 Aug 2021 17:12:38 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> Make driver to support ast2600 adc device.
> - Use shared reset controller
> - Complete the vref configure function
> - Add the model data for ast2600 adc
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
Hi Billy,

A few minor things inline,

Jonathan

> ---
>  drivers/iio/adc/aspeed_adc.c | 106 +++++++++++++++++++++++++++++++++--
>  1 file changed, 100 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 1c87e12a0cab..ea3e9a52fcc9 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * Aspeed AST2400/2500 ADC
> + * Aspeed AST2400/2500/2600 ADC
>   *
>   * Copyright (C) 2017 Google, Inc.
>   * Copyright (C) 2021 Aspeed Technology Inc.
> @@ -14,6 +14,7 @@
>  #include <linux/module.h>
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
>  #include <linux/reset.h>
>  #include <linux/spinlock.h>
>  #include <linux/types.h>
> @@ -73,6 +74,7 @@ struct aspeed_adc_model_data {
>  struct aspeed_adc_data {
>  	struct device		*dev;
>  	const struct aspeed_adc_model_data *model_data;
> +	struct regulator	*regulator;
>  	void __iomem		*base;
>  	spinlock_t		clk_lock;
>  	struct clk_hw		*clk_prescaler;
> @@ -208,14 +210,80 @@ static void aspeed_adc_clk_disable_unprepare(void *data)
>  	clk_disable_unprepare(clk);
>  }
>  
> +static void aspeed_adc_reg_disable(void *data)
> +{
> +	struct regulator *reg = data;
> +
> +	regulator_disable(reg);
> +}
> +
>  static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
>  {
>  	struct aspeed_adc_data *data = iio_priv(indio_dev);
> +	int ret;
> +	u32 adc_engine_control_reg_val =
> +		readl(data->base + ASPEED_REG_ENGINE_CONTROL);

Given you aren't going to use this if vref_fixed is set, move the read
until after that.

>  
>  	if (data->model_data->vref_fixed) {
>  		data->vref = data->model_data->vref_fixed;
>  		return 0;
>  	}
> +
> +	data->regulator = devm_regulator_get_optional(data->dev, "vref");
> +	if (!IS_ERR(data->regulator)) {
> +		ret = regulator_enable(data->regulator);
> +		if (ret)
> +			return ret;
> +		ret = devm_add_action_or_reset(
> +			data->dev, aspeed_adc_reg_disable, data->regulator);
> +		if (ret)
> +			return ret;
> +		data->vref = regulator_get_voltage(data->regulator);
> +		/* Conversion from uV to mV */
> +		data->vref /= 1000;
> +		if ((data->vref >= 1550) && (data->vref <= 2700))
> +			writel(adc_engine_control_reg_val |
> +				       FIELD_PREP(
> +					       ASPEED_ADC_REF_VOLTAGE,
> +					       ASPEED_ADC_REF_VOLTAGE_EXT_HIGH),
> +			       data->base + ASPEED_REG_ENGINE_CONTROL);
> +		else if ((data->vref >= 900) && (data->vref <= 1650))
> +			writel(adc_engine_control_reg_val |
> +				       FIELD_PREP(
> +					       ASPEED_ADC_REF_VOLTAGE,
> +					       ASPEED_ADC_REF_VOLTAGE_EXT_LOW),
> +			       data->base + ASPEED_REG_ENGINE_CONTROL);
> +		else {
> +			dev_err(data->dev, "Regulator voltage %d not support",
> +				data->vref);
> +			return -EOPNOTSUPP;
> +		}
> +	} else {
> +		if (PTR_ERR(data->regulator) != -ENODEV)
> +			return PTR_ERR(data->regulator);
> +		ret = of_property_read_u32(data->dev->of_node,
> +					   "aspeed,int_vref_mv", &data->vref);
> +		if (ret < 0) {
> +			dev_warn(data->dev,
> +				 "Using default vref: internal 2500 mv");

Perhaps document that as default in the dt-binding, then you can remove this warning and
handle this as:

		data->vref = 2500;
		of_property_read_u32(data->dev->of_node,
				     "aspeed,int-vref-mvolts", &data->vref);
etc

> +			data->vref = 2500;
> +		}
> +		if (data->vref == 2500)
> +			writel(adc_engine_control_reg_val |
> +				       FIELD_PREP(ASPEED_ADC_REF_VOLTAGE,
> +						  ASPEED_ADC	writel(adc_engine_control_reg_val,
		data->base + ASPEED_REG_ENGINE_CONTROL);_REF_VOLTAGE_2500mV),
> +			       data->base + ASPEED_REG_ENGINE_CONTROL);
> +		else if (data->vref == 1200)
> +			writel(adc_engine_control_reg_val |
> +				       FIELD_PREP(ASPEED_ADC_REF_VOLTAGE,
> +						  ASPEED_ADC_REF_VOLTAGE_1200mV),
> +			       data->base + ASPEED_REG_ENGINE_CONTROL);
> +		else {
> +			dev_err(data->dev, "Voltage %d not support", data->vref);
> +			return -EOPNOTSUPP;
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> @@ -279,7 +347,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> -	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +	data->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
>  	if (IS_ERR(data->rst)) {
>  		dev_err(&pdev->dev,
>  			"invalid or missing reset controller device tree entry");
> @@ -297,10 +365,14 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  		return ret;
>  
>  	if (data->model_data->wait_init_sequence) {
> +		adc_engine_control_reg_val =
> +			readl(data->base + ASPEED_REG_ENGINE_CONTROL);
> +		adc_engine_control_reg_val |=
> +			FIELD_PREP(ASPEED_ADC_OP_MODE,
> +				   ASPEED_ADC_OP_MODE_NORMAL) |
> +			ASPEED_ADC_ENGINE_ENABLE;
>  		/* Enable engine in normal mode. */
> -		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
> -				  ASPEED_ADC_OP_MODE_NORMAL) |
> -			       ASPEED_ADC_ENGINE_ENABLE,
> +		writel(adc_engine_control_reg_val,
>  		       data->base + ASPEED_REG_ENGINE_CONTROL);
>  
>  		/* Wait for initial sequence complete. */
> @@ -326,6 +398,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  		return ret;
>  
>  	adc_engine_control_reg_val =
> +		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
> +	adc_engine_control_reg_val |=
>  		ASPEED_ADC_CTRL_CHANNEL |
>  		FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
>  		ASPEED_ADC_ENGINE_ENABLE;
> @@ -376,9 +450,29 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
>  	.num_channels = 16,
>  };
>  
> +static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
> +	.model_name = "ast2600-adc0",
> +	.min_sampling_rate = 10000,
> +	.max_sampling_rate = 500000,
> +	.wait_init_sequence = true,
> +	.scaler_bit_width = 16,
> +	.num_channels = 8,
> +};
> +
> +static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
> +	.model_name = "ast2600-adc1",
> +	.min_sampling_rate = 10000,
> +	.max_sampling_rate = 500000,
> +	.wait_init_sequence = true,
> +	.scaler_bit_width = 16,
> +	.num_channels = 8,
> +};
> +
>  static const struct of_device_id aspeed_adc_matches[] = {
>  	{ .compatible = "aspeed,ast2400-adc", .data = &ast2400_model_data },
>  	{ .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data },
> +	{ .compatible = "aspeed,ast2600-adc0", .data = &ast2600_adc0_model_data },
> +	{ .compatible = "aspeed,ast2600-adc1", .data = &ast2600_adc1_model_data },
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, aspeed_adc_matches);
> @@ -395,5 +489,5 @@ static struct platform_driver aspeed_adc_driver = {
>  module_platform_driver(aspeed_adc_driver);
>  
>  MODULE_AUTHOR("Rick Altherr <raltherr at google.com>");
> -MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver");
> +MODULE_DESCRIPTION("Aspeed AST2400/2500/2600 ADC Driver");
>  MODULE_LICENSE("GPL");



From jic23 at kernel.org  Sun Aug 29 08:33:46 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:33:46 +0100
Subject: [RESEND v4 11/15] iio: adc: aspeed: Fix the calculate error of
 clock.
In-Reply-To: <20210824091243.9393-12-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <20210824091243.9393-12-billy_tsai@aspeedtech.com>
Message-ID: <20210829163346.501fdb43@jic23-huawei>

On Tue, 24 Aug 2021 17:12:39 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> The adc clcok formula is

clock

> ast2400/2500:
> ADC clock period = PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
> ast2600:
> ADC clock period = PCLK * 2 * (ADC0C[15:0] + 1)
> They all have one fixed divided 2 and the legacy driver didn't handle it.
> This patch register the fixed factory clock device as the parent of adc
> clock scaler to fix this issue.

What are the impacts of this being wrong before?  Is this something we
should look to backport?

Comment inline.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  drivers/iio/adc/aspeed_adc.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index ea3e9a52fcc9..8fe7da1a651f 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -4,6 +4,12 @@
>   *
>   * Copyright (C) 2017 Google, Inc.
>   * Copyright (C) 2021 Aspeed Technology Inc.
> + *
> + * ADC clock formula:
> + * Ast2400/Ast2500:
> + * clock period = period of PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
> + * Ast2600:
> + * clock period = period of PCLK * 2 * (ADC0C[15:0] + 1)
>   */
>  
>  #include <linux/clk.h>
> @@ -77,6 +83,7 @@ struct aspeed_adc_data {
>  	struct regulator	*regulator;
>  	void __iomem		*base;
>  	spinlock_t		clk_lock;
> +	struct clk_hw		*fixed_div_clk;
>  	struct clk_hw		*clk_prescaler;
>  	struct clk_hw		*clk_scaler;
>  	struct reset_control	*rst;
> @@ -196,6 +203,13 @@ static void aspeed_adc_unregister_divider(void *data)
>  	clk_hw_unregister_divider(clk);
>  }
>  
> +static void aspeed_adc_unregister_fixed_divider(void *data)
> +{
> +	struct clk_hw *clk = data;
> +
> +	clk_hw_unregister_fixed_factor(clk);
> +}
> +
>  static void aspeed_adc_reset_assert(void *data)
>  {
>  	struct reset_control *rst = data;
> @@ -312,6 +326,18 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	/* Register ADC clock prescaler with source specified by device tree. */
>  	spin_lock_init(&data->clk_lock);
>  	snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));
> +	snprintf(clk_name, 32, "%s-fixed-div", data->model_data->model_name);

ARRAY_SIZE

> +	data->fixed_div_clk = clk_hw_register_fixed_factor(
> +		&pdev->dev, clk_name, clk_parent_name, 0, 1, 2);
> +	if (IS_ERR(data->fixed_div_clk))
> +		return PTR_ERR(data->fixed_div_clk);
> +
> +	ret = devm_add_action_or_reset(data->dev,
> +				       aspeed_adc_unregister_fixed_divider,
> +				       data->clk_prescaler);
> +	if (ret)
> +		return ret;
> +	snprintf(clk_parent_name, 32, clk_name);
>  	if (data->model_data->need_prescaler) {
>  		snprintf(clk_name, 32, "%s-prescaler",
>  			 data->model_data->model_name);



From jic23 at kernel.org  Sun Aug 29 08:36:59 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:36:59 +0100
Subject: [RESEND v4 12/15] iio: adc: aspeed: Add func to set sampling rate.
In-Reply-To: <202108250003.17P03KRU092474@twspam01.aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <202108250003.17P03KRU092474@twspam01.aspeedtech.com>
Message-ID: <20210829163659.2f7f5974@jic23-huawei>

On Tue, 24 Aug 2021 17:12:40 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> Add the function to set the sampling rate and keep the sampling period
> for a driver used to wait the lastest value.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>

Why move the code as well as factoring out the setter function?
I doubt it does any harm, but I'd like to understand why you did it.

Jonathan


> ---
>  drivers/iio/adc/aspeed_adc.c | 58 +++++++++++++++++++++++++-----------
>  1 file changed, 40 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 8fe7da1a651f..4d979dd7fe88 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -65,6 +65,12 @@
>  
>  #define ASPEED_ADC_INIT_POLLING_TIME	500
>  #define ASPEED_ADC_INIT_TIMEOUT		500000
> +/*
> + * When the sampling rate is too high, the ADC may not have enough charging
> + * time, resulting in a low voltage value. Thus, default use slow sampling
> + * rate for most user case.
> + */
> +#define ASPEED_ADC_DEF_SAMPLING_RATE	65000
>  
>  struct aspeed_adc_model_data {
>  	const char *model_name;
> @@ -88,6 +94,7 @@ struct aspeed_adc_data {
>  	struct clk_hw		*clk_scaler;
>  	struct reset_control	*rst;
>  	int			vref;
> +	u32			sample_period_ns;
>  };
>  
>  #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
> @@ -119,6 +126,24 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
>  	ASPEED_CHAN(15, 0x2E),
>  };
>  
> +static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate)
> +{
> +	struct aspeed_adc_data *data = iio_priv(indio_dev);
> +
> +	if (rate < data->model_data->min_sampling_rate ||
> +	    rate > data->model_data->max_sampling_rate)
> +		return -EINVAL;
> +	/* Each sampling needs 12 clocks to covert.*/

convert.  Please run a spell checker over these patches.

> +	clk_set_rate(data->clk_scaler->clk, rate * ASPEED_CLOCKS_PER_SAMPLE);
> +	rate = clk_get_rate(data->clk_scaler->clk);
> +	data->sample_period_ns = DIV_ROUND_UP_ULL(
> +		(u64)NSEC_PER_SEC * ASPEED_CLOCKS_PER_SAMPLE, rate);
> +	dev_dbg(data->dev, "Adc clock = %d sample period = %d ns", rate,
> +		data->sample_period_ns);
> +
> +	return 0;
> +}
> +
>  static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
>  			       struct iio_chan_spec const *chan,
>  			       int *val, int *val2, long mask)
> @@ -149,17 +174,10 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,
>  				struct iio_chan_spec const *chan,
>  				int val, int val2, long mask)
>  {
> -	struct aspeed_adc_data *data = iio_priv(indio_dev);
>  
>  	switch (mask) {
>  	case IIO_CHAN_INFO_SAMP_FREQ:
> -		if (val < data->model_data->min_sampling_rate ||
> -			val > data->model_data->max_sampling_rate)
> -			return -EINVAL;
> -
> -		clk_set_rate(data->clk_scaler->clk,
> -				val * ASPEED_CLOCKS_PER_SAMPLE);
> -		return 0;
> +		return aspeed_adc_set_sampling_rate(indio_dev, val);
>  
>  	case IIO_CHAN_INFO_SCALE:
>  	case IIO_CHAN_INFO_RAW:
> @@ -386,6 +404,20 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> +	ret = clk_prepare_enable(data->clk_scaler->clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = devm_add_action_or_reset(data->dev,
> +				       aspeed_adc_clk_disable_unprepare,
> +				       data->clk_scaler->clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE);
> +	if (ret)
> +		return ret;
> +
>  	ret = aspeed_adc_vref_config(indio_dev);
>  	if (ret)
>  		return ret;
> @@ -413,16 +445,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	}
>  
>  	/* Start all channels in normal mode. */

Why move this code up?

> -	ret = clk_prepare_enable(data->clk_scaler->clk);
> -	if (ret)
> -		return ret;
> -
> -	ret = devm_add_action_or_reset(data->dev,
> -				       aspeed_adc_clk_disable_unprepare,
> -				       data->clk_scaler->clk);
> -	if (ret)
> -		return ret;
> -
>  	adc_engine_control_reg_val =
>  		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
>  	adc_engine_control_reg_val |=



From jic23 at kernel.org  Sun Aug 29 08:39:23 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:39:23 +0100
Subject: [RESEND v4 13/15] iio: adc: aspeed: Add compensation phase.
In-Reply-To: <202108250006.17P066YP096721@twspam01.aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <202108250006.17P066YP096721@twspam01.aspeedtech.com>
Message-ID: <20210829163923.107f4027@jic23-huawei>

On Tue, 24 Aug 2021 17:12:41 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> This patch adds a compensation phase to improve the accurate of ADC

accuracy of the ADC measurement.

> measurement. This is the built-in function though input half of the
> reference voltage to get the ADC offset.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
This looks like fairly standard calibration which is good to have.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/aspeed_adc.c | 54 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 53 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 4d979dd7fe88..20caf28dff18 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -95,6 +95,7 @@ struct aspeed_adc_data {
>  	struct reset_control	*rst;
>  	int			vref;
>  	u32			sample_period_ns;
> +	int			cv;
>  };
>  
>  #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
> @@ -104,7 +105,8 @@ struct aspeed_adc_data {
>  	.address = (_data_reg_addr),				\
>  	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
>  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
> -				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
> +				BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
> +				BIT(IIO_CHAN_INFO_OFFSET),	\
>  }
>  
>  static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
> @@ -126,6 +128,51 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
>  	ASPEED_CHAN(15, 0x2E),
>  };
>  
> +static int aspeed_adc_compensation(struct iio_dev *indio_dev)
> +{
> +	struct aspeed_adc_data *data = iio_priv(indio_dev);
> +	u32 index, adc_raw = 0;
> +	u32 adc_engine_control_reg_val;
> +
> +	adc_engine_control_reg_val =
> +		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
> +	adc_engine_control_reg_val &= ~ASPEED_ADC_OP_MODE;
> +	adc_engine_control_reg_val |=
> +		(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
> +		 ASPEED_ADC_ENGINE_ENABLE);
> +	/*
> +	 * Enable compensating sensing:
> +	 * After that, the input voltage of ADC will force to half of the reference
> +	 * voltage. So the expected reading raw data will become half of the max
> +	 * value. We can get compensating value = 0x200 - ADC read raw value.
> +	 * It is recommended to average at least 10 samples to get a final CV.
> +	 */
> +	writel(adc_engine_control_reg_val | ASPEED_ADC_CTRL_COMPENSATION |
> +		       ASPEED_ADC_CTRL_CHANNEL_ENABLE(0),
> +	       data->base + ASPEED_REG_ENGINE_CONTROL);
> +	/*
> +	 * After enable compensating sensing mode need to wait some time for ADC stable
> +	 * Experiment result is 1ms.
> +	 */
> +	mdelay(1);
> +
> +	for (index = 0; index < 16; index++) {
> +		/*
> +		 * Waiting for the sampling period ensures that the value acquired
> +		 * is fresh each time.
> +		 */
> +		ndelay(data->sample_period_ns);
> +		adc_raw += readw(data->base + aspeed_adc_iio_channels[0].address);
> +	}
> +	adc_raw >>= 4;
> +	data->cv = BIT(ASPEED_RESOLUTION_BITS - 1) - adc_raw;
> +	writel(adc_engine_control_reg_val,
> +	       data->base + ASPEED_REG_ENGINE_CONTROL);
> +	dev_dbg(data->dev, "Compensating value = %d\n", data->cv);
> +
> +	return 0;
> +}
> +
>  static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate)
>  {
>  	struct aspeed_adc_data *data = iio_priv(indio_dev);
> @@ -155,6 +202,10 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
>  		*val = readw(data->base + chan->address);
>  		return IIO_VAL_INT;
>  
> +	case IIO_CHAN_INFO_OFFSET:
> +		*val = data->cv;
> +		return IIO_VAL_INT;
> +
>  	case IIO_CHAN_INFO_SCALE:
>  		*val = data->vref;
>  		*val2 = ASPEED_RESOLUTION_BITS;
> @@ -444,6 +495,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  			return ret;
>  	}
>  
> +	aspeed_adc_compensation(indio_dev);
>  	/* Start all channels in normal mode. */
>  	adc_engine_control_reg_val =
>  		readl(data->base + ASPEED_REG_ENGINE_CONTROL);



From jic23 at kernel.org  Sun Aug 29 08:43:38 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:43:38 +0100
Subject: [RESEND v4 14/15] iio: adc: aspeed: Support battery sensing.
In-Reply-To: <202108250005.17P05agj096445@twspam01.aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <202108250005.17P05agj096445@twspam01.aspeedtech.com>
Message-ID: <20210829164338.2c18decd@jic23-huawei>

On Tue, 24 Aug 2021 17:12:42 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> In ast2600, ADC integrate dividing circuit at last input channel for
> battery sensing. This patch use the dts property "battery-sensing" to
> enable this feature makes the last channel of each adc can tolerance
> higher voltage than reference voltage.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>

The slight issue here is this  changes the userspace
ABI for the older parts.   Whilst a per channel offset is perfectly valid
it's still an ABI change and someone might be relying on a dodgy script
that uses it.

So, whilst it's a pain you should have two different chan_spec arrays and pick
between them dependent on model of device.  That way you can leave the
old ABI untouched and add this control for the ast2600 only.

> ---
>  drivers/iio/adc/aspeed_adc.c | 62 +++++++++++++++++++++++++++++++++---
>  1 file changed, 57 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 20caf28dff18..0c5d84e82561 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -79,10 +79,16 @@ struct aspeed_adc_model_data {
>  	unsigned int vref_fixed;	// mV
>  	bool wait_init_sequence;
>  	bool need_prescaler;
> +	bool bat_sense_sup;
>  	u8 scaler_bit_width;
>  	unsigned int num_channels;
>  };
>  
> +struct adc_gain {
> +	u8 mult;
> +	u8 div;
> +};
> +
>  struct aspeed_adc_data {
>  	struct device		*dev;
>  	const struct aspeed_adc_model_data *model_data;
> @@ -96,6 +102,8 @@ struct aspeed_adc_data {
>  	int			vref;
>  	u32			sample_period_ns;
>  	int			cv;
> +	bool			battery_sensing;
> +	struct adc_gain		battery_mode_gain;
>  };
>  
>  #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
> @@ -103,10 +111,10 @@ struct aspeed_adc_data {
>  	.indexed = 1,						\
>  	.channel = (_idx),					\
>  	.address = (_data_reg_addr),				\
> -	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
> -	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
> -				BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
> +	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
>  				BIT(IIO_CHAN_INFO_OFFSET),	\
> +	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
> +				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
>  }
>  
>  static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
> @@ -196,14 +204,39 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
>  			       int *val, int *val2, long mask)
>  {
>  	struct aspeed_adc_data *data = iio_priv(indio_dev);
> +	u32 adc_engine_control_reg_val;
>  
>  	switch (mask) {
>  	case IIO_CHAN_INFO_RAW:
> -		*val = readw(data->base + chan->address);
> +		if (data->battery_sensing && chan->channel == 7) {
> +			adc_engine_control_reg_val =
> +				readl(data->base + ASPEED_REG_ENGINE_CONTROL);
> +			writel(adc_engine_control_reg_val |
> +				       FIELD_PREP(ASPEED_ADC_CH7_MODE,
> +						  ASPEED_ADC_CH7_BAT) |
> +				       ASPEED_ADC_BAT_SENSING_ENABLE,
> +			       data->base + ASPEED_REG_ENGINE_CONTROL);
> +			/*
> +			 * After enable battery sensing mode need to wait some time for adc stable
> +			 * Experiment result is 1ms.
> +			 */
> +			mdelay(1);
> +			*val = readw(data->base + chan->address);
> +			*val = (*val * data->battery_mode_gain.mult) /
> +			       data->battery_mode_gain.div;
> +			/* Restore control register value */
> +			writel(adc_engine_control_reg_val,
> +			       data->base + ASPEED_REG_ENGINE_CONTROL);
> +		} else
> +			*val = readw(data->base + chan->address);
>  		return IIO_VAL_INT;
>  
>  	case IIO_CHAN_INFO_OFFSET:
> -		*val = data->cv;
> +		if (data->battery_sensing && chan->channel == 7)
> +			*val = (data->cv * data->battery_mode_gain.mult) /
> +			       data->battery_mode_gain.div;
> +		else
> +			*val = data->cv;
>  		return IIO_VAL_INT;
>  
>  	case IIO_CHAN_INFO_SCALE:
> @@ -473,6 +506,23 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> +	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
> +			     NULL)) {
> +		if (data->model_data->bat_sense_sup) {
> +			data->battery_sensing = 1;
> +			if (readl(data->base + ASPEED_REG_ENGINE_CONTROL) &
> +			ASPEED_ADC_BAT_SENSING_DIV) {
> +				data->battery_mode_gain.mult = 3;
> +				data->battery_mode_gain.div = 1;
> +			} else {
> +				data->battery_mode_gain.mult = 3;
> +				data->battery_mode_gain.div = 2;
> +			}
> +		} else
> +			dev_warn(&pdev->dev,
> +				"Failed to enable battey-sensing mode\n");
> +	}
> +
>  	if (data->model_data->wait_init_sequence) {
>  		adc_engine_control_reg_val =
>  			readl(data->base + ASPEED_REG_ENGINE_CONTROL);
> @@ -555,6 +605,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
>  	.min_sampling_rate = 10000,
>  	.max_sampling_rate = 500000,
>  	.wait_init_sequence = true,
> +	.bat_sense_sup = true,
>  	.scaler_bit_width = 16,
>  	.num_channels = 8,
>  };
> @@ -564,6 +615,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
>  	.min_sampling_rate = 10000,
>  	.max_sampling_rate = 500000,
>  	.wait_init_sequence = true,
> +	.bat_sense_sup = true,
>  	.scaler_bit_width = 16,
>  	.num_channels = 8,
>  };



From jic23 at kernel.org  Sun Aug 29 08:45:31 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:45:31 +0100
Subject: [RESEND v4 15/15] iio: adc: aspeed: Get and set trimming data.
In-Reply-To: <202108250007.17P07NFj097422@twspam01.aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <202108250007.17P07NFj097422@twspam01.aspeedtech.com>
Message-ID: <20210829164531.44cbcc21@jic23-huawei>

On Tue, 24 Aug 2021 17:12:43 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> The adc controller have trimming register for fine-tune the reference

Nice to have ADC instead of adc (though not that important as meaning is clear).

> voltage. The trimming value come from the otp register which will be
> written before chip product. This patch will read this otp value and

written during chip production? (perhaps that's what is intended?)

> configure it to the adc register when adc controller probe and using dts
> property "aspeed,trim-data-valid" to determine whether to execute this
> flow.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  drivers/iio/adc/aspeed_adc.c | 68 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 68 insertions(+)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 0c5d84e82561..bd7fb23f3510 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -25,6 +25,8 @@
>  #include <linux/spinlock.h>
>  #include <linux/types.h>
>  #include <linux/bitfield.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
>  
>  #include <linux/iio/iio.h>
>  #include <linux/iio/driver.h>
> @@ -72,6 +74,11 @@
>   */
>  #define ASPEED_ADC_DEF_SAMPLING_RATE	65000
>  
> +struct aspeed_adc_trim_locate {
> +	const unsigned int offset;
> +	const unsigned int field;
> +};
> +
>  struct aspeed_adc_model_data {
>  	const char *model_name;
>  	unsigned int min_sampling_rate;	// Hz
> @@ -82,6 +89,7 @@ struct aspeed_adc_model_data {
>  	bool bat_sense_sup;
>  	u8 scaler_bit_width;
>  	unsigned int num_channels;
> +	const struct aspeed_adc_trim_locate *trim_locate;
>  };
>  
>  struct adc_gain {
> @@ -136,6 +144,44 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
>  	ASPEED_CHAN(15, 0x2E),
>  };
>  
> +static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev)
> +{
> +	struct device_node *syscon;
> +	struct regmap *scu;
> +	u32 scu_otp, trimming_val;
> +	struct aspeed_adc_data *data = iio_priv(indio_dev);
> +
> +	syscon = of_find_node_by_name(NULL, "syscon");
> +	if (syscon == NULL) {
> +		dev_warn(data->dev, "Couldn't find syscon node\n");
> +		return -EOPNOTSUPP;
> +	}
> +	scu = syscon_node_to_regmap(syscon);
> +	if (IS_ERR(scu)) {
> +		dev_warn(data->dev, "Failed to get syscon regmap\n");
> +		return -EOPNOTSUPP;
> +	}
> +	if (data->model_data->trim_locate) {
> +		if (regmap_read(scu, data->model_data->trim_locate->offset,
> +				&scu_otp)) {
> +			dev_warn(data->dev,
> +				 "Failed to get adc trimming data\n");
> +			trimming_val = 0x8;
> +		} else {
> +			trimming_val =
> +				((scu_otp) &
> +				 (data->model_data->trim_locate->field)) >>
> +				__ffs(data->model_data->trim_locate->field);
> +		}
> +		dev_dbg(data->dev,
> +			"trimming val = %d, offset = %08x, fields = %08x\n",
> +			trimming_val, data->model_data->trim_locate->offset,
> +			data->model_data->trim_locate->field);
> +		writel(trimming_val, data->base + ASPEED_REG_COMPENSATION_TRIM);
> +	}
> +	return 0;
> +}
> +
>  static int aspeed_adc_compensation(struct iio_dev *indio_dev)
>  {
>  	struct aspeed_adc_data *data = iio_priv(indio_dev);
> @@ -506,6 +552,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  	if (ret)
>  		return ret;
>  
> +	if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid",
> +			     NULL))
> +		aspeed_adc_set_trim_data(indio_dev);
> +
>  	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
>  			     NULL)) {
>  		if (data->model_data->bat_sense_sup) {
> @@ -579,6 +629,21 @@ static int aspeed_adc_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +static const struct aspeed_adc_trim_locate ast2500_adc_trim = {
> +	.offset = 0x154,
> +	.field = GENMASK(31, 28),
> +};
> +
> +static const struct aspeed_adc_trim_locate ast2600_adc0_trim = {
> +	.offset = 0x5d0,
> +	.field = GENMASK(3, 0),
> +};
> +
> +static const struct aspeed_adc_trim_locate ast2600_adc1_trim = {
> +	.offset = 0x5d0,
> +	.field = GENMASK(7, 4),
> +};
> +
>  static const struct aspeed_adc_model_data ast2400_model_data = {
>  	.model_name = "ast2400-adc",
>  	.vref_fixed = 2500, // mV
> @@ -598,6 +663,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
>  	.need_prescaler = true,
>  	.scaler_bit_width = 10,
>  	.num_channels = 16,
> +	.trim_locate = &ast2500_adc_trim,
>  };
>  
>  static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
> @@ -608,6 +674,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
>  	.bat_sense_sup = true,
>  	.scaler_bit_width = 16,
>  	.num_channels = 8,
> +	.trim_locate = &ast2600_adc0_trim,
>  };
>  
>  static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
> @@ -618,6 +685,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
>  	.bat_sense_sup = true,
>  	.scaler_bit_width = 16,
>  	.num_channels = 8,
> +	.trim_locate = &ast2600_adc1_trim,
>  };
>  
>  static const struct of_device_id aspeed_adc_matches[] = {



From jic23 at kernel.org  Sun Aug 29 08:08:56 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 29 Aug 2021 16:08:56 +0100
Subject: [RESEND v4 03/15] iio: adc: aspeed: set driver data when adc
 probe.
In-Reply-To: <20210824091243.9393-4-billy_tsai@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <20210824091243.9393-4-billy_tsai@aspeedtech.com>
Message-ID: <20210829160856.12dd9395@jic23-huawei>

On Tue, 24 Aug 2021 17:12:31 +0800
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> Fix the issue when adc remove will get the null driver data.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>

This is a fix that we should probably backport.  Please add a fixes tag and move
it to the start of the series so I can pick it during this kernel
cycle rather than waiting for the next one.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/aspeed_adc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index 7010d56ac3b9..20462cf659e4 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
> @@ -201,6 +201,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  
>  	data = iio_priv(indio_dev);
>  	data->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, indio_dev);
>  
>  	data->base = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(data->base))



From wens at kernel.org  Sun Aug 29 10:48:19 2021
From: wens at kernel.org (Chen-Yu Tsai)
Date: Mon, 30 Aug 2021 01:48:19 +0800
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <20210823143754.14294-1-michael.riesch@wolfvision.net>
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
Message-ID: <CAGb2v67Duk_56fOKVwZsYn2HKJ99o8WJ+d4jetD2UjDsAt9BcA@mail.gmail.com>

Hi,

On Mon, Aug 23, 2021 at 10:39 PM Michael Riesch
<michael.riesch at wolfvision.net> wrote:
>
> This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
> "net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
> unbalanced pm_runtime_enable warnings.
>
> In the commit to be reverted, support for power management was
> introduced to the Rockchip glue code. Later, power management support
> was introduced to the stmmac core code, resulting in multiple
> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
>
> The multiple invocations happen in rk_gmac_powerup and
> stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
> stmmac_{dvr_remove, suspend}, respectively, which are always called
> in conjunction.
>
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>

I just found that Ethernet stopped working on my RK3399 devices,
and I bisected it down to this patch.

The symptom I see is no DHCP responses, either because the request
isn't getting sent over the wire, or the response isn't getting
received. The PHY seems to be working correctly.


ChenYu


From pavel at ucw.cz  Sun Aug 29 10:59:07 2021
From: pavel at ucw.cz (Pavel Machek)
Date: Sun, 29 Aug 2021 19:59:07 +0200
Subject: [PATCH v3 2/5] leds: Add driver for QCOM SPMI Flash LEDs
In-Reply-To: <278ea1e8-8b21-457d-78d7-fbb32544fe0a@gmail.com>
References: <20210803162641.1525980-1-nfraprado@collabora.com>
 <20210803162641.1525980-3-nfraprado@collabora.com>
 <b1060e9a-f78e-fbe9-bde3-2b4d89cbc73e@gmail.com>
 <20210824214515.ekjpvaymkgxltlzp@notapiano>
 <278ea1e8-8b21-457d-78d7-fbb32544fe0a@gmail.com>
Message-ID: <20210829175906.GA663@amd>

Hi both!

Please trim your replies (removing code you are not commenting
on). Scolling 600 lines to find where discussion is is not fun.

Best regards,
								Pavel

> >>>+static int qcom_flash_torch_on(struct qcom_flash_led *led)
> >>>+{
> >>>+	int rc, error;
> >>>+	struct qcom_flash_device *leds_dev = led_to_leds_dev(led);
> >>>+	struct device *dev = leds_dev->dev;
> >>>+
> >>>+	if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_DUAL) {
> >>>+		rc = qcom_flash_torch_regulator_on(leds_dev);
> >>>+		if (rc)
> >>>+			goto error_reg_write;
> >>>+	} else if (leds_dev->peripheral_subtype == QCOM_FLASH_SUBTYPE_SINGLE) {
> >>>+		rc = qcom_flash_fled_regulator_on(leds_dev);
> >>
> >>Why for torch mode you need to enable fled regulator?
> >
> >Based on [1], apparently the hardware present in the Single variant of the PMIC
> >has some limitation that requires the use of the flash regulator and the value
> >QCOM_FLASH_ENABLE_ALL to enable the LEDs for the torch mode. The Dual variant on
> >the other hand can just use the torch regulator and enables the LEDs with
> >QCOM_FLASH_ENABLE_MODULE.
> >
> >[1] https://github.com/AICP/kernel_lge_hammerhead/commit/0f47c747c074993655d0bfebd045e8ddd228fe4c
> >
> >I'm honestly not sure what the impact is on using the different regulators and
> >enable values. I have tested enabling the Dual PMIC with different enable values
> >and all seemed to work the same, so must be some hardware detail.
> >
> >I left that Single codepath in the hope that it is useful for devices that have
> >that variant of the hardware, but I have only actually tested the Dual PMIC,
> >which is the one present on the Nexus 5.
> 
> Thanks for the explanation. Just wanted to confirm that it was not
> a mistake.
> 
> >>
> >>>+		if (rc)
> >>>+			goto error_flash_set;
> >>>+
> >>>+		/*
> >>>+		 * Write 0x80 to MODULE_ENABLE before writing
> >>>+		 * 0xE0 in order to avoid a hardware bug caused
> >>>+		 * by register value going from 0x00 to 0xE0.
> >>>+		 */
> >>>+		rc = qcom_flash_masked_write(leds_dev,
> >>>+					     QCOM_FLASH_ADDR_ENABLE_CONTROL,
> >>>+					     QCOM_FLASH_ENABLE_MODULE_MASK,
> >>>+					     QCOM_FLASH_ENABLE_MODULE);
> >>>+		if (rc) {
> >>>+			dev_err(dev, "Enable reg write failed(%d)\n", rc);
> >>>+			goto error_flash_set;
> >>>+		}
> >>>+	}
> >>>+
> >>>+	rc = qcom_flash_torch_reg_enable(leds_dev, true);
> >>>+	if (rc)
> >>>+		goto error_reg_write;
> >>>+
> >>>+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_ENABLE_CONTROL,
> >>>+				     QCOM_FLASH_ENABLE_MASK,
> >>>+				     leds_dev->torch_enable_cmd);
> >>>+	if (rc) {
> >>>+		dev_err(dev, "Enable reg write failed(%d)\n", rc);
> >>>+		goto error_reg_write;
> >>>+	}
> >>>+
> >>>+	rc = qcom_flash_masked_write(leds_dev, QCOM_FLASH_ADDR_LED_STROBE_CTRL,
> >>>+				     led->flash_strobe_cmd,
> >>>+				     led->flash_strobe_cmd);
> >>
> >>Just to make sure - the hardware requires strobe cmd to enable torch?
> >
> >Yes. The strobe value is the one that actually turns each of the LEDs on,
> >doesn't matter if it's on flash or torch mode. The difference in torch mode is
> >actually just that the timeout on the LEDs is disabled (done by writing 0x00
> >into the TORCH, 0xE4, register).
> >So for both modes, the LEDs are turned on by writing to the STROBE_CTRL, 0x47,
> >register. If torch is on they'll stay on indefinitely, while on flash mode
> >they'll turn off after the timeout.
> >
> >Perhaps it's just a naming issue?
> 
> I propose to add these comments next to the calls in question.


-- 
http://www.livejournal.com/~pavelmachek
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210829/ef06dedf/attachment.sig>

From rashmi.a at intel.com  Sun Aug 29 11:24:39 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:39 +0530
Subject: [PATCH v2 0/4] Add support of eMMC PHY for Intel Thunder Bay
Message-ID: <20210829182443.30802-1-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

This patch set enables the support for eMMC PHY on the Intel Thunder 
Bay SoC. eMMC PHY is based on arasan phy.
 
Patch 1 Adds arasan sdhci support for eMMC in Intel Thunder Bay.
Patch 2 Adds arasan sdhci dt bindings.
Patch 3 Holds the device tree binding documentation for eMMC PHY
	and listings of new files in MAINTAINERS file.
Patch 4 Holds the eMMC PHY driver.


Rashmi A (4):
  mmc: sdhci-of-arasan: Add intel Thunder Bay SOC support to the arasan
    eMMC driver
  dt-bindings: mmc: Add bindings for Intel Thunder Bay SoC
  dt-bindings: phy: intel: Add Thunder Bay eMMC PHY bindings
  phy: intel: Add Thunder Bay eMMC PHY support

 .../devicetree/bindings/mmc/arasan,sdhci.yaml |  25 +
 .../phy/intel,phy-thunderbay-emmc.yaml        |  46 ++
 MAINTAINERS                                   |   7 +
 drivers/mmc/host/sdhci-of-arasan.c            |  29 +-
 drivers/phy/intel/Kconfig                     |  10 +
 drivers/phy/intel/Makefile                    |   1 +
 drivers/phy/intel/phy-intel-thunderbay-emmc.c | 512 ++++++++++++++++++
 7 files changed, 629 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml
 create mode 100644 drivers/phy/intel/phy-intel-thunderbay-emmc.c

-- 
2.17.1



From rashmi.a at intel.com  Sun Aug 29 11:24:40 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:40 +0530
Subject: [PATCH v2 1/4] mmc: sdhci-of-arasan: Add intel Thunder Bay SOC
 support to the arasan eMMC driver
In-Reply-To: <20210829182443.30802-1-rashmi.a@intel.com>
References: <20210829182443.30802-1-rashmi.a@intel.com>
Message-ID: <20210829182443.30802-2-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

Intel Thunder Bay SoC eMMC controller is based on Arasan
eMMC 5.1 host controller IP

Signed-off-by: Rashmi A <rashmi.a at intel.com>
Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>
---
 drivers/mmc/host/sdhci-of-arasan.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 839965f7c717..6f202fb7a546 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -185,6 +185,13 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = {
 	.hiword_update = false,
 };
 
+static const struct sdhci_arasan_soc_ctl_map thunderbay_soc_ctl_map = {
+	.baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
+	.clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
+	.support64b = { .reg = 0x4, .width = 1, .shift = 24 },
+	.hiword_update = false,
+};
+
 static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = {
 	.baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
 	.clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
@@ -430,6 +437,15 @@ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = {
 			SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
 };
 
+static const struct sdhci_pltfm_data sdhci_arasan_thunderbay_pdata = {
+	.ops = &sdhci_arasan_cqe_ops,
+	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
+		SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
+		SDHCI_QUIRK2_STOP_WITH_TC |
+		SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400,
+};
+
 #ifdef CONFIG_PM_SLEEP
 /**
  * sdhci_arasan_suspend - Suspend method for the driver
@@ -1098,6 +1114,12 @@ static struct sdhci_arasan_of_data sdhci_arasan_generic_data = {
 	.clk_ops = &arasan_clk_ops,
 };
 
+static const struct sdhci_arasan_of_data sdhci_arasan_thunderbay_data = {
+	.soc_ctl_map = &thunderbay_soc_ctl_map,
+	.pdata = &sdhci_arasan_thunderbay_pdata,
+	.clk_ops = &arasan_clk_ops,
+};
+
 static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = {
 	.ops = &sdhci_arasan_cqe_ops,
 	.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
@@ -1231,6 +1253,10 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
 		.compatible = "intel,keembay-sdhci-5.1-sdio",
 		.data = &intel_keembay_sdio_data,
 	},
+	{
+		.compatible = "intel,thunderbay-sdhci-5.1",
+		.data = &sdhci_arasan_thunderbay_data,
+	},
 	/* Generic compatible below here */
 	{
 		.compatible = "arasan,sdhci-8.9a",
@@ -1582,7 +1608,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
 
 	if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
 	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
-	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {
+	    of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio") ||
+	    of_device_is_compatible(np, "intel,thunderbay-sdhci-5.1")) {
 		sdhci_arasan_update_clockmultiplier(host, 0x0);
 		sdhci_arasan_update_support64b(host, 0x0);
 
-- 
2.17.1



From rashmi.a at intel.com  Sun Aug 29 11:24:41 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:41 +0530
Subject: [PATCH v2 2/4] dt-bindings: mmc: Add bindings for Intel Thunder Bay
 SoC
In-Reply-To: <20210829182443.30802-1-rashmi.a@intel.com>
References: <20210829182443.30802-1-rashmi.a@intel.com>
Message-ID: <20210829182443.30802-3-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

Add documentation for Arasan SDHCI controller in Thunder Bay SOC.

Signed-off-by: Rashmi A <rashmi.a at intel.com>
---
 .../devicetree/bindings/mmc/arasan,sdhci.yaml | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml b/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
index 37a5fe7b26dc..23abb7e8b9d8 100644
--- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
+++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml
@@ -88,6 +88,12 @@ properties:
         description:
           For this device it is strongly suggested to include
           arasan,soc-ctl-syscon.
+      - items:
+          - const: intel,thunderbay-sdhci-5.1   # Intel Thunder Bay eMMC PHY
+          - const: arasan,sdhci-5.1
+        description:
+          For this device it is strongly suggested to include
+          clock-output-names and '#clock-cells'.
 
   reg:
     maxItems: 1
@@ -301,3 +307,22 @@ examples:
                    <&scmi_clk KEEM_BAY_PSS_SD0>;
           arasan,soc-ctl-syscon = <&sd0_phy_syscon>;
     };
+
+  - |
+    #define EMMC_XIN_CLK
+    #define EMMC_AXI_CLK
+    #define TBH_PSS_EMMC_RST_N
+    mmc at 80420000 {
+          compatible = "intel,thunderbay-sdhci-5.1", "arasan,sdhci-5.1";
+          interrupts = <GIC_SPI 714 IRQ_TYPE_LEVEL_HIGH>;
+          reg = <0x80420000 0x400>;
+          clocks = <&scmi_clk EMMC_XIN_CLK>,
+                   <&scmi_clk EMMC_AXI_CLK>;
+          clock-names = "clk_xin", "clk_ahb";
+          phys = <&emmc_phy>;
+          phy-names = "phy_arasan";
+          assigned-clocks = <&scmi_clk EMMC_XIN_CLK>;
+          clock-output-names = "emmc_cardclock";
+          resets = <&rst_pss1 TBH_PSS_EMMC_RST_N>;
+          #clock-cells = <0x0>;
+    };
-- 
2.17.1



From rashmi.a at intel.com  Sun Aug 29 11:24:42 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:42 +0530
Subject: [PATCH v2 3/4] dt-bindings: phy: intel: Add Thunder Bay eMMC PHY
 bindings
In-Reply-To: <20210829182443.30802-1-rashmi.a@intel.com>
References: <20210829182443.30802-1-rashmi.a@intel.com>
Message-ID: <20210829182443.30802-4-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

Binding description for Intel Thunder Bay eMMC PHY.
Added the newly introduced files into MAINTAINERS file-list

Signed-off-by: Rashmi A <rashmi.a at intel.com>
---
 .../phy/intel,phy-thunderbay-emmc.yaml        | 46 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++
 2 files changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml

diff --git a/Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml b/Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml
new file mode 100644
index 000000000000..34bdb5c4cae8
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/intel,phy-thunderbay-emmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intel Thunder Bay eMMC PHY bindings
+
+maintainers:
+  - Srikandan Nandhini <nandhini.srikandan at intel.com>
+
+properties:
+  compatible:
+    const: intel,thunderbay-emmc-phy
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: emmcclk
+
+required:
+  - "#phy-cells"
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+     mmc_phy at 80440800 {
+     #phy-cells = <0x0>;
+     compatible = "intel,thunderbay-emmc-phy";
+     status = "okay";
+     reg = <0x80440800 0x100>;
+     clocks = <&emmc>;
+     clock-names = "emmcclk";
+     };
diff --git a/MAINTAINERS b/MAINTAINERS
index bd7aff0c120f..44533319c900 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9278,6 +9278,13 @@ F:	drivers/crypto/keembay/keembay-ocs-hcu-core.c
 F:	drivers/crypto/keembay/ocs-hcu.c
 F:	drivers/crypto/keembay/ocs-hcu.h
 
+INTEL THUNDER BAY EMMC PHY DRIVER
+M:	Nandhini Srikandan <nandhini.srikandan at intel.com>
+M:	Rashmi A <rashmi.a at intel.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/phy/intel,phy-thunderbay-emmc.yaml
+F:	drivers/phy/intel/phy-intel-thunderbay-emmc.c
+
 INTEL MANAGEMENT ENGINE (mei)
 M:	Tomas Winkler <tomas.winkler at intel.com>
 L:	linux-kernel at vger.kernel.org
-- 
2.17.1



From rashmi.a at intel.com  Sun Aug 29 11:24:43 2021
From: rashmi.a at intel.com (rashmi.a at intel.com)
Date: Sun, 29 Aug 2021 23:54:43 +0530
Subject: [PATCH v2 4/4] phy: intel: Add Thunder Bay eMMC PHY support
In-Reply-To: <20210829182443.30802-1-rashmi.a@intel.com>
References: <20210829182443.30802-1-rashmi.a@intel.com>
Message-ID: <20210829182443.30802-5-rashmi.a@intel.com>

From: Rashmi A <rashmi.a at intel.com>

Add support of eMMC PHY for Intel Thunder Bay SoC,
uses the Arasan eMMC phy

Signed-off-by: Rashmi A <rashmi.a at intel.com>
Reviewed-by: Adrian Hunter <adrian.hunter at intel.com>
---
 drivers/phy/intel/Kconfig                     |  10 +
 drivers/phy/intel/Makefile                    |   1 +
 drivers/phy/intel/phy-intel-thunderbay-emmc.c | 512 ++++++++++++++++++
 3 files changed, 523 insertions(+)
 create mode 100644 drivers/phy/intel/phy-intel-thunderbay-emmc.c

diff --git a/drivers/phy/intel/Kconfig b/drivers/phy/intel/Kconfig
index ac42bb2fb394..18a3cc5b98c0 100644
--- a/drivers/phy/intel/Kconfig
+++ b/drivers/phy/intel/Kconfig
@@ -46,3 +46,13 @@ config PHY_INTEL_LGM_EMMC
 	select GENERIC_PHY
 	help
 	  Enable this to support the Intel EMMC PHY
+
+config PHY_INTEL_THUNDERBAY_EMMC
+        tristate "Intel Thunder Bay eMMC PHY driver"
+        depends on OF && (ARCH_THUNDERBAY || COMPILE_TEST)
+        select GENERIC_PHY
+        help
+	  This option enables support for Intel Thunder Bay SoC eMMC PHY.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called phy-intel-thunderbay-emmc.ko.
diff --git a/drivers/phy/intel/Makefile b/drivers/phy/intel/Makefile
index 14550981a707..b7321d56b0bb 100644
--- a/drivers/phy/intel/Makefile
+++ b/drivers/phy/intel/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC)	+= phy-intel-keembay-emmc.o
 obj-$(CONFIG_PHY_INTEL_KEEMBAY_USB)	+= phy-intel-keembay-usb.o
 obj-$(CONFIG_PHY_INTEL_LGM_COMBO)	+= phy-intel-lgm-combo.o
 obj-$(CONFIG_PHY_INTEL_LGM_EMMC)	+= phy-intel-lgm-emmc.o
+obj-$(CONFIG_PHY_INTEL_THUNDERBAY_EMMC) += phy-intel-thunderbay-emmc.o
diff --git a/drivers/phy/intel/phy-intel-thunderbay-emmc.c b/drivers/phy/intel/phy-intel-thunderbay-emmc.c
new file mode 100644
index 000000000000..385659dd87be
--- /dev/null
+++ b/drivers/phy/intel/phy-intel-thunderbay-emmc.c
@@ -0,0 +1,512 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Intel ThunderBay eMMC PHY driver
+ *
+ * Copyright (C) 2021 Intel Corporation
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/* eMMC/SD/SDIO core/phy configuration registers */
+#define CTRL_CFG_0	0x00
+#define CTRL_CFG_1	0x04
+#define CTRL_PRESET_0	0x08
+#define CTRL_PRESET_1	0x0c
+#define CTRL_PRESET_2	0x10
+#define CTRL_PRESET_3	0x14
+#define CTRL_PRESET_4	0x18
+#define CTRL_CFG_2	0x1c
+#define CTRL_CFG_3	0x20
+#define PHY_CFG_0	0x24
+#define PHY_CFG_1	0x28
+#define PHY_CFG_2	0x2c
+#define PHYBIST_CTRL	0x30
+#define SDHC_STAT3	0x34
+#define PHY_STAT	0x38
+#define PHYBIST_STAT_0	0x3c
+#define PHYBIST_STAT_1	0x40
+#define EMMC_AXI        0x44
+
+/* CTRL_PRESET_3 */
+#define CTRL_PRESET3_MASK	GENMASK(31, 0)
+#define CTRL_PRESET3_SHIFT	0
+
+/* CTRL_CFG_0 bit fields */
+#define SUPPORT_HS_MASK		BIT(26)
+#define SUPPORT_HS_SHIFT	26
+
+#define SUPPORT_8B_MASK		BIT(24)
+#define SUPPORT_8B_SHIFT	24
+
+/* CTRL_CFG_1 bit fields */
+#define SUPPORT_SDR50_MASK	BIT(28)
+#define SUPPORT_SDR50_SHIFT	28
+#define SLOT_TYPE_MASK		GENMASK(27, 26)
+#define SLOT_TYPE_OFFSET	26
+#define SUPPORT_64B_MASK	BIT(24)
+#define SUPPORT_64B_SHIFT	24
+#define SUPPORT_HS400_MASK	BIT(2)
+#define SUPPORT_HS400_SHIFT	2
+#define SUPPORT_DDR50_MASK	BIT(1)
+#define SUPPORT_DDR50_SHIFT	1
+#define SUPPORT_SDR104_MASK	BIT(0)
+#define SUPPORT_SDR104_SHIFT	0
+
+/* PHY_CFG_0 bit fields */
+#define SEL_DLY_TXCLK_MASK      BIT(29)
+#define SEL_DLY_TXCLK_SHIFT	29
+#define SEL_DLY_RXCLK_MASK      BIT(28)
+#define SEL_DLY_RXCLK_SHIFT	28
+
+#define OTAP_DLY_ENA_MASK	BIT(27)
+#define OTAP_DLY_ENA_SHIFT	27
+#define OTAP_DLY_SEL_MASK	GENMASK(26, 23)
+#define OTAP_DLY_SEL_SHIFT	23
+#define ITAP_CHG_WIN_MASK	BIT(22)
+#define ITAP_CHG_WIN_SHIFT	22
+#define ITAP_DLY_ENA_MASK	BIT(21)
+#define ITAP_DLY_ENA_SHIFT	21
+#define ITAP_DLY_SEL_MASK	GENMASK(20, 16)
+#define ITAP_DLY_SEL_SHIFT	16
+#define RET_ENB_MASK		BIT(15)
+#define RET_ENB_SHIFT		15
+#define RET_EN_MASK		BIT(14)
+#define RET_EN_SHIFT		14
+#define DLL_IFF_MASK		GENMASK(13, 11)
+#define DLL_IFF_SHIFT		11
+#define DLL_EN_MASK		BIT(10)
+#define DLL_EN_SHIFT		10
+#define DLL_TRIM_ICP_MASK	GENMASK(9, 6)
+#define DLL_TRIM_ICP_SHIFT	6
+#define RETRIM_EN_MASK		BIT(5)
+#define RETRIM_EN_SHIFT		5
+#define RETRIM_MASK		BIT(4)
+#define RETRIM_SHIFT		4
+#define DR_TY_MASK		GENMASK(3, 1)
+#define DR_TY_SHIFT		1
+#define PWR_DOWN_MASK		BIT(0)
+#define PWR_DOWN_SHIFT		0
+
+/* PHY_CFG_1 bit fields */
+#define REN_DAT_MASK		GENMASK(19, 12)
+#define REN_DAT_SHIFT		12
+#define REN_CMD_MASK		BIT(11)
+#define REN_CMD_SHIFT		11
+#define REN_STRB_MASK		BIT(10)
+#define REN_STRB_SHIFT		10
+#define PU_STRB_MASK		BIT(20)
+#define PU_STRB_SHIFT		20
+
+/* PHY_CFG_2 bit fields */
+#define CLKBUF_MASK		GENMASK(24, 21)
+#define CLKBUF_SHIFT		21
+#define SEL_STRB_MASK		GENMASK(20, 13)
+#define SEL_STRB_SHIFT		13
+#define SEL_FREQ_MASK		GENMASK(12, 10)
+#define SEL_FREQ_SHIFT		10
+
+/* PHY_STAT bit fields */
+#define CAL_DONE		BIT(6)
+#define DLL_RDY			BIT(5)
+
+#define OTAP_DLY		0x0
+#define ITAP_DLY		0x0
+#define STRB			0x33
+
+/* From ACS_eMMC51_16nFFC_RO1100_Userguide_v1p0.pdf p17 */
+#define FREQSEL_200M_170M	0x0
+#define FREQSEL_170M_140M	0x1
+#define FREQSEL_140M_110M	0x2
+#define FREQSEL_110M_80M	0x3
+#define FREQSEL_80M_50M		0x4
+#define FREQSEL_275M_250M	0x5
+#define FREQSEL_250M_225M	0x6
+#define FREQSEL_225M_200M	0x7
+
+/* Phy power status */
+#define PHY_UNINITIALIZED	0
+#define PHY_INITIALIZED		1
+
+/*
+ * During init(400KHz) phy_settings will be called with 200MHZ clock
+ * To avoid incorrectly setting the phy for init(400KHZ) "phy_power_sts" is used.
+ * When actual clock is set always phy is powered off once and then powered on.
+ * (sdhci_arasan_set_clock). That feature will be used to identify whether the
+ * settings are for init phy_power_on or actual clock phy_power_on
+ * 0 --> init settings
+ * 1 --> actual settings
+ */
+
+struct thunderbay_emmc_phy {
+	void __iomem    *reg_base;
+	struct clk      *emmcclk;
+	int phy_power_sts;
+};
+
+static inline void update_reg(struct thunderbay_emmc_phy *tbh_phy, u32 offset,
+			      u32 mask, u32 shift, u32 val)
+{
+	u32 tmp;
+
+	tmp = readl(tbh_phy->reg_base + offset);
+	tmp &= ~mask;
+	tmp |= val << shift;
+	writel(tmp, tbh_phy->reg_base + offset);
+}
+
+static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+	unsigned int freqsel = FREQSEL_200M_170M;
+	unsigned long rate;
+	static int lock;
+	u32 val;
+	int ret;
+
+	/* Disable DLL */
+	rate = clk_get_rate(tbh_phy->emmcclk);
+	switch (rate) {
+	case 200000000:
+		/* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0 */
+		update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x0);
+		break;
+
+	/* dll lock not required for other frequencies */
+	case 50000000 ... 52000000:
+	case 400000:
+	default:
+		break;
+	}
+
+	if (!power_on)
+		return 0;
+
+	rate = clk_get_rate(tbh_phy->emmcclk);
+	switch (rate) {
+	case 170000001 ... 200000000:
+		freqsel = FREQSEL_200M_170M;
+		break;
+
+	case 140000001 ... 170000000:
+		freqsel = FREQSEL_170M_140M;
+		break;
+
+	case 110000001 ... 140000000:
+		freqsel = FREQSEL_140M_110M;
+		break;
+
+	case 80000001 ... 110000000:
+		freqsel = FREQSEL_110M_80M;
+		break;
+
+	case 50000000 ... 80000000:
+		freqsel = FREQSEL_80M_50M;
+		break;
+
+	case 250000001 ... 275000000:
+		freqsel = FREQSEL_275M_250M;
+		break;
+
+	case 225000001 ... 250000000:
+		freqsel = FREQSEL_250M_225M;
+		break;
+
+	case 200000001 ... 225000000:
+		freqsel = FREQSEL_225M_200M;
+		break;
+	default:
+		break;
+	}
+	/* Clock rate is checked against upper limit. It may fall low during init */
+	if (rate > 200000000)
+		dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
+
+	udelay(5);
+
+	if (lock == 0) {
+		/* PDB will be done only once per boot */
+		update_reg(tbh_phy, PHY_CFG_0, PWR_DOWN_MASK,
+			   PWR_DOWN_SHIFT, 0x1);
+		lock = 1;
+		/*
+		 * According to the user manual, it asks driver to wait 5us for
+		 * calpad busy trimming. However it is documented that this value is
+		 * PVT(A.K.A. process, voltage and temperature) relevant, so some
+		 * failure cases are found which indicates we should be more tolerant
+		 * to calpad busy trimming.
+		 */
+		ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT,
+					 val, (val & CAL_DONE), 10, 50);
+		if (ret) {
+			dev_err(&phy->dev, "caldone failed, ret=%d\n", ret);
+			return ret;
+		}
+	}
+	rate = clk_get_rate(tbh_phy->emmcclk);
+	switch (rate) {
+	case 200000000:
+		/* Set frequency of the DLL operation */
+		update_reg(tbh_phy, PHY_CFG_2, SEL_FREQ_MASK, SEL_FREQ_SHIFT, freqsel);
+
+		/* Enable DLL */
+		update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x1);
+
+		/*
+		 * After enabling analog DLL circuits docs say that we need 10.2 us if
+		 * our source clock is at 50 MHz and that lock time scales linearly
+		 * with clock speed. If we are powering on the PHY and the card clock
+		 * is super slow (like 100kHz) this could take as long as 5.1 ms as
+		 * per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms
+		 * hopefully we won't be running at 100 kHz, but we should still make
+		 * sure we wait long enough.
+		 *
+		 * NOTE: There appear to be corner cases where the DLL seems to take
+		 * extra long to lock for reasons that aren't understood. In some
+		 * extreme cases we've seen it take up to over 10ms (!). We'll be
+		 * generous and give it 50ms.
+		 */
+		ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT,
+					 val, (val & DLL_RDY), 10, 50 * USEC_PER_MSEC);
+		if (ret) {
+			dev_err(&phy->dev, "dllrdy failed, ret=%d\n", ret);
+			return ret;
+		}
+		break;
+
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int thunderbay_emmc_phy_init(struct phy *phy)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+
+	tbh_phy->emmcclk = clk_get(&phy->dev, "emmcclk");
+
+	return PTR_ERR_OR_ZERO(tbh_phy->emmcclk);
+}
+
+static int thunderbay_emmc_phy_exit(struct phy *phy)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+
+	clk_put(tbh_phy->emmcclk);
+
+	return 0;
+}
+
+static int thunderbay_emmc_phy_power_on(struct phy *phy)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+	unsigned long rate;
+
+	/* Overwrite capability bits configurable in bootloader */
+	update_reg(tbh_phy, CTRL_CFG_0,
+		   SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_0,
+		   SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1);
+	update_reg(tbh_phy, CTRL_CFG_1,
+		   SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1);
+
+	if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) {
+		/* Indicates initialization, settings for init, same as 400KHZ setting */
+		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, SEL_DLY_TXCLK_SHIFT, 0x1);
+		update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, SEL_DLY_RXCLK_SHIFT, 0x1);
+		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, ITAP_DLY_ENA_SHIFT, 0x0);
+		update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, ITAP_DLY_SEL_SHIFT, 0x0);
+		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, OTAP_DLY_ENA_SHIFT, 0x0);
+		update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, OTAP_DLY_SEL_SHIFT, 0);
+		update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, DLL_TRIM_ICP_SHIFT, 0);
+		update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1);
+
+	} else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) {
+		/* Indicates actual clock setting */
+		rate = clk_get_rate(tbh_phy->emmcclk);
+		switch (rate) {
+		case 200000000:
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
+				   SEL_DLY_TXCLK_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
+				   SEL_DLY_RXCLK_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
+				   ITAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
+				   ITAP_DLY_SEL_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
+				   OTAP_DLY_ENA_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
+				   OTAP_DLY_SEL_SHIFT, 2);
+			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
+				   DLL_TRIM_ICP_SHIFT, 0x8);
+			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
+				   DR_TY_SHIFT, 0x1);
+			/* For HS400 only */
+			update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK,
+				   SEL_STRB_SHIFT, STRB);
+			break;
+
+		case 50000000 ... 52000000:
+			/* For both HS and DDR52 this setting works */
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
+				   SEL_DLY_TXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
+				   SEL_DLY_RXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
+				   ITAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
+				   ITAP_DLY_SEL_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
+				   OTAP_DLY_ENA_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
+				   OTAP_DLY_SEL_SHIFT, 4);
+			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
+				   DLL_TRIM_ICP_SHIFT, 0x8);
+			update_reg(tbh_phy, PHY_CFG_0,
+				   DR_TY_MASK, DR_TY_SHIFT, 0x1);
+			break;
+
+		case 400000:
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
+				   SEL_DLY_TXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
+				   SEL_DLY_RXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
+				   ITAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
+				   ITAP_DLY_SEL_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
+				   OTAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
+				   OTAP_DLY_SEL_SHIFT, 0);
+			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
+				   DLL_TRIM_ICP_SHIFT, 0);
+			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1);
+			break;
+
+		default:
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
+				   SEL_DLY_TXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
+				   SEL_DLY_RXCLK_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
+				   ITAP_DLY_ENA_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
+				   ITAP_DLY_SEL_SHIFT, 0x0);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
+				   OTAP_DLY_ENA_SHIFT, 0x1);
+			update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
+				   OTAP_DLY_SEL_SHIFT, 2);
+			update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
+				   DLL_TRIM_ICP_SHIFT, 0x8);
+			update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
+				   DR_TY_SHIFT, 0x1);
+			break;
+		}
+		/* Reset, init seq called without phy_power_off, this indicates init seq */
+		tbh_phy->phy_power_sts = PHY_UNINITIALIZED;
+	}
+
+	update_reg(tbh_phy, PHY_CFG_0, RETRIM_EN_MASK, RETRIM_EN_SHIFT, 0x1);
+	update_reg(tbh_phy, PHY_CFG_0, RETRIM_MASK, RETRIM_SHIFT, 0x0);
+
+	return thunderbay_emmc_phy_power(phy, 1);
+}
+
+static int thunderbay_emmc_phy_power_off(struct phy *phy)
+{
+	struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
+
+	tbh_phy->phy_power_sts = PHY_INITIALIZED;
+
+	return thunderbay_emmc_phy_power(phy, 0);
+}
+
+static const struct phy_ops thunderbay_emmc_phy_ops = {
+	.init		= thunderbay_emmc_phy_init,
+	.exit		= thunderbay_emmc_phy_exit,
+	.power_on	= thunderbay_emmc_phy_power_on,
+	.power_off	= thunderbay_emmc_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static const struct of_device_id thunderbay_emmc_phy_of_match[] = {
+	{ .compatible = "intel,thunderbay-emmc-phy",
+		(void *)&thunderbay_emmc_phy_ops },
+	{}
+};
+MODULE_DEVICE_TABLE(of, thunderbay_emmc_phy_of_match);
+
+static int thunderbay_emmc_phy_probe(struct platform_device *pdev)
+{
+	struct thunderbay_emmc_phy *tbh_phy;
+	struct phy_provider *phy_provider;
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *id;
+	struct phy *generic_phy;
+	struct resource *res;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	tbh_phy = devm_kzalloc(dev, sizeof(*tbh_phy), GFP_KERNEL);
+	if (!tbh_phy)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tbh_phy->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tbh_phy->reg_base)) {
+		dev_err(&pdev->dev, "region map failed\n");
+		return PTR_ERR(tbh_phy->reg_base);
+	}
+
+	tbh_phy->phy_power_sts = PHY_UNINITIALIZED;
+	id = of_match_node(thunderbay_emmc_phy_of_match, pdev->dev.of_node);
+	if (!id) {
+		dev_err(dev, "failed to get match_node\n");
+		return -EINVAL;
+	}
+
+	generic_phy = devm_phy_create(dev, dev->of_node, id->data);
+	if (IS_ERR(generic_phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(generic_phy);
+	}
+
+	phy_set_drvdata(generic_phy, tbh_phy);
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static struct platform_driver thunderbay_emmc_phy_driver = {
+	.probe		 = thunderbay_emmc_phy_probe,
+	.driver		 = {
+		.name	 = "thunderbay-emmc-phy",
+		.of_match_table = thunderbay_emmc_phy_of_match,
+	},
+};
+module_platform_driver(thunderbay_emmc_phy_driver);
+
+MODULE_AUTHOR("Nandhini S <nandhini.srikandan at intel.com>");
+MODULE_AUTHOR("Rashmi A <rashmi.a at intel.com>");
+MODULE_DESCRIPTION("Intel Thunder Bay eMMC PHY driver");
+MODULE_LICENSE("GPL v2");
+
-- 
2.17.1



From sboyd at kernel.org  Sun Aug 29 11:26:36 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 29 Aug 2021 11:26:36 -0700
Subject: [v2 06/24] clk: mediatek: Add MT8195 apmixedsys clock support
In-Reply-To: <20210820111504.350-7-chun-jie.chen@mediatek.com>
References: <20210820111504.350-1-chun-jie.chen@mediatek.com>
 <20210820111504.350-7-chun-jie.chen@mediatek.com>
Message-ID: <163026159693.2676726.8564637566834797534@swboyd.mtv.corp.google.com>

Quoting Chun-Jie Chen (2021-08-20 04:14:46)
> Add MT8195 apmixedsys clock controller which provides Plls
> generated from SoC 26m and ssusb clock gate control.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/Kconfig                 |   8 +
>  drivers/clk/mediatek/Makefile                |   1 +
>  drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 145 +++++++++++++++++++
>  3 files changed, 154 insertions(+)
>  create mode 100644 drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> 
> diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
> index 576babd86f98..7ba1f4118e0d 100644
> --- a/drivers/clk/mediatek/Kconfig
> +++ b/drivers/clk/mediatek/Kconfig
> @@ -580,6 +580,14 @@ config COMMON_CLK_MT8192_VENCSYS
>         help
>           This driver supports MediaTek MT8192 vencsys clocks.
>  
> +config COMMON_CLK_MT8195
> +        bool "Clock driver for MediaTek MT8195"
> +        depends on ARM64 || COMPILE_TEST
> +        select COMMON_CLK_MEDIATEK
> +        default ARM64

Please no. The default should presumably be ARCH_MEDIATEK, or just
nothing at all.

> +        help
> +          This driver supports MediaTek MT8195 basic clocks.
> +
>  config COMMON_CLK_MT8516
>         bool "Clock driver for MediaTek MT8516"
>         depends on ARCH_MEDIATEK || COMPILE_TEST


From iwona.winiarska at intel.com  Sun Aug 29 12:42:09 2021
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Sun, 29 Aug 2021 19:42:09 +0000
Subject: [PATCH v2 07/15] peci: Add peci-aspeed controller driver
In-Reply-To: <CAPcyv4hUm0Ec1+_n0PZ+S0A9Tt1=8oLdeYtEiEnAmntm8PtmKQ@mail.gmail.com>
References: <20210803113134.2262882-1-iwona.winiarska@intel.com>
 <20210803113134.2262882-8-iwona.winiarska@intel.com>
 <CAPcyv4jPVSt9Wr2TkDActFVLP+ygaDwBnsKG410Nf1qfP_MB9A@mail.gmail.com>
 <b26ee278838698289869964fe59578f0d5f7b19c.camel@intel.com>
 <CAPcyv4hUm0Ec1+_n0PZ+S0A9Tt1=8oLdeYtEiEnAmntm8PtmKQ@mail.gmail.com>
Message-ID: <d43b405df504b26e8af2356921570c341976b890.camel@intel.com>

On Fri, 2021-08-27 at 09:24 -0700, Dan Williams wrote:
> On Thu, Aug 26, 2021 at 4:55 PM Winiarska, Iwona
> <iwona.winiarska at intel.com> wrote:
> > 
> > On Wed, 2021-08-25 at 18:35 -0700, Dan Williams wrote:
> > > On Tue, Aug 3, 2021 at 4:35 AM Iwona Winiarska
> > > <iwona.winiarska at intel.com> wrote:
> > > > 
> > > > From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > > > 
> > > > ASPEED AST24xx/AST25xx/AST26xx SoCs supports the PECI electrical
> > > > interface (a.k.a PECI wire).
> > > 
> > > Maybe a one sentence blurb here and in the Kconfig reminding people
> > > why they should care if they have a PECI driver or not?
> > 
> > Ok, I'll expand it a bit.
> [..]
> > > > +static int aspeed_peci_xfer(struct peci_controller *controller,
> > > > +?????????????????????????? u8 addr, struct peci_request *req)
> > > > +{
> > > > +?????? struct aspeed_peci *priv = dev_get_drvdata(controller-
> > > > >dev.parent);
> > > > +?????? unsigned long flags, timeout = msecs_to_jiffies(priv-
> > > > > cmd_timeout_ms);
> > > > +?????? u32 peci_head;
> > > > +?????? int ret;
> > > > +
> > > > +?????? if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
> > > > +?????????? req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
> > > > +?????????????? return -EINVAL;
> > > > +
> > > > +?????? /* Check command sts and bus idle state */
> > > > +?????? ret = aspeed_peci_check_idle(priv);
> > > > +?????? if (ret)
> > > > +?????????????? return ret; /* -ETIMEDOUT */
> > > > +
> > > > +?????? spin_lock_irqsave(&priv->lock, flags);
> > > > +?????? reinit_completion(&priv->xfer_complete);
> > > > +
> > > > +?????? peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
> > > > +?????????????????? FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
> > > > +?????????????????? FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
> > > > +
> > > > +?????? writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
> > > > +
> > > > +?????? memcpy_toio(priv->base + ASPEED_PECI_WR_DATA0, req->tx.buf,
> > > > min_t(u8, req->tx.len, 16));
> > > > +?????? if (req->tx.len > 16)
> > > > +?????????????? memcpy_toio(priv->base + ASPEED_PECI_WR_DATA4, req-
> > > > >tx.buf +
> > > > 16,
> > > > +?????????????????????????? req->tx.len - 16);
> > > > +
> > > > +?????? dev_dbg(priv->dev, "HEAD : 0x%08x\n", peci_head);
> > > > +?????? print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf,
> > > > req-
> > > > > tx.len);
> > > 
> > > On CONFIG_DYNAMIC_DEBUG=n builds the kernel will do all the work of
> > > reading through this buffer, but skip emitting it. Are you sure you
> > > want to pay that overhead for every transaction?
> > 
> > I can remove it or I can add something like:
> > 
> > #if IS_ENABLED(CONFIG_PECI_DEBUG)
> > #define peci_debug(fmt, ...) pr_debug(fmt, ##__VA_ARGS__)
> > #else
> > #define peci_debug(...) do { } while (0)
> > #endif
> 
> It's the hex dump I'm worried about, not the debug statements as much.
> 
> I think the choices are remove the print_hex_dump_bytes(), put it
> behind an IS_ENABLED(CONFIG_DYNAMIC_DEBUG) to ensure the overhead is
> skipped in the CONFIG_DYNAMIC_DEBUG=n case, or live with the overhead
> if this is not a fast path / infrequently used.

I will place it behind IS_ENABLED(CONFIG_DYNAMIC_DEBUG).

> 
> > 
> > (and similar peci_trace with trace_printk for usage in IRQ handlers and
> > such).
> > 
> > What do you think?
> 
> In general, no, don't wrap the base level print routines with
> driver-specific ones. Also, trace_printk() is only for debug builds.
> Note that trace points are built to be even less overhead than
> dev_dbg(), so there's no overhead concern with disabled tracepoints,
> they literally translate to nops when disabled.

Ack.

> 
> > 
> > > 
> > > > +
> > > > +?????? priv->status = 0;
> > > > +?????? writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
> > > > +?????? spin_unlock_irqrestore(&priv->lock, flags);
> > > > +
> > > > +?????? ret = wait_for_completion_interruptible_timeout(&priv-
> > > > > xfer_complete, timeout);
> > > 
> > > spin_lock_irqsave() says "I don't know if interrupts are disabled
> > > already, so I'll save the state, whatever it is, and restore later"
> > > 
> > > wait_for_completion_interruptible_timeout() says "I know I am in a
> > > sleepable context where interrupts are enabled"
> > > 
> > > So, one of those is wrong, i.e. should it be spin_{lock,unlock}_irq()?
> > 
> > You're right - I'll fix it.
> > 
> > > 
> > > 
> > > > +?????? if (ret < 0)
> > > > +?????????????? return ret;
> > > > +
> > > > +?????? if (ret == 0) {
> > > > +?????????????? dev_dbg(priv->dev, "Timeout waiting for a response!\n");
> > > > +?????????????? return -ETIMEDOUT;
> > > > +?????? }
> > > > +
> > > > +?????? spin_lock_irqsave(&priv->lock, flags);
> > > > +
> > > > +?????? writel(0, priv->base + ASPEED_PECI_CMD);
> > > > +
> > > > +?????? if (priv->status != ASPEED_PECI_INT_CMD_DONE) {
> > > > +?????????????? spin_unlock_irqrestore(&priv->lock, flags);
> > > > +?????????????? dev_dbg(priv->dev, "No valid response!\n");
> > > > +?????????????? return -EIO;
> > > > +?????? }
> > > > +
> > > > +?????? spin_unlock_irqrestore(&priv->lock, flags);
> > > > +
> > > > +?????? memcpy_fromio(req->rx.buf, priv->base + ASPEED_PECI_RD_DATA0,
> > > > min_t(u8, req->rx.len, 16));
> > > > +?????? if (req->rx.len > 16)
> > > > +?????????????? memcpy_fromio(req->rx.buf + 16, priv->base +
> > > > ASPEED_PECI_RD_DATA4,
> > > > +???????????????????????????? req->rx.len - 16);
> > > > +
> > > > +?????? print_hex_dump_bytes("RX : ", DUMP_PREFIX_NONE, req->rx.buf,
> > > > req-
> > > > > rx.len);
> > > > +
> > > > +?????? return 0;
> > > > +}
> > > > +
> > > > +static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
> > > > +{
> > > > +?????? struct aspeed_peci *priv = arg;
> > > > +?????? u32 status;
> > > > +
> > > > +?????? spin_lock(&priv->lock);
> > > > +?????? status = readl(priv->base + ASPEED_PECI_INT_STS);
> > > > +?????? writel(status, priv->base + ASPEED_PECI_INT_STS);
> > > > +?????? priv->status |= (status & ASPEED_PECI_INT_MASK);
> > > > +
> > > > +?????? /*
> > > > +??????? * In most cases, interrupt bits will be set one by one but also
> > > > note
> > > > +??????? * that multiple interrupt bits could be set at the same time.
> > > > +??????? */
> > > > +?????? if (status & ASPEED_PECI_INT_BUS_TIMEOUT)
> > > > +?????????????? dev_dbg_ratelimited(priv->dev,
> > > > "ASPEED_PECI_INT_BUS_TIMEOUT\n");
> > > > +
> > > > +?????? if (status & ASPEED_PECI_INT_BUS_CONTENTION)
> > > > +?????????????? dev_dbg_ratelimited(priv->dev,
> > > > "ASPEED_PECI_INT_BUS_CONTENTION\n");
> > > > +
> > > > +?????? if (status & ASPEED_PECI_INT_WR_FCS_BAD)
> > > > +?????????????? dev_dbg_ratelimited(priv->dev,
> > > > "ASPEED_PECI_INT_WR_FCS_BAD\n");
> > > > +
> > > > +?????? if (status & ASPEED_PECI_INT_WR_FCS_ABORT)
> > > > +?????????????? dev_dbg_ratelimited(priv->dev,
> > > > "ASPEED_PECI_INT_WR_FCS_ABORT\n");
> > > 
> > > Are you sure these would not be better as tracepoints? If you're
> > > debugging an interrupt related failure, the ratelimiting might get in
> > > your way when you really need to know when one of these error
> > > interrupts fire relative to another event.
> > 
> > Tracepoints are ABI(ish), and using a full blown tracepoint just for IRQ
> > status
> > would probably be too much.
> 
> Tracepoints become ABI once someone ships tooling that depends on them
> being there. These don't look? attractive for a tool, and they don't
> look difficult to maintain if the interrupt handler needs to be
> reworked. I.e. it would be trivial to keep a dead tracepoint around if
> worse came to worse to keep a tool from failing to load.

After more consideration, I would prefer to remove these logs for now - in case
of error I'll log full status in xfer().

> 
> > I was thinking about something like trace_printk hidden under a
> > "CONFIG_PECI_DEBUG" (see above), but perhaps that's something for the future
> > improvement?
> 
> Again trace_printk() is only for private builds.
> 
> > 
> > > 
> > > > +
> > > > +?????? /*
> > > > +??????? * All commands should be ended up with a
> > > > ASPEED_PECI_INT_CMD_DONE
> > > > bit
> > > > +??????? * set even in an error case.
> > > > +??????? */
> > > > +?????? if (status & ASPEED_PECI_INT_CMD_DONE)
> > > > +?????????????? complete(&priv->xfer_complete);
> > > 
> > > Hmm, no need to check if there was a sequencing error, like a command
> > > was never submitted?
> > 
> > It's handled by checking if HW is idle in xfer before a command is sent,
> > where
> > we just expect a single interrupt per command.
> 
> I'm asking how do you determine if this status was spurious, or there
> was a sequencing error in the driver?

I don't think we have any means to determine it.
PECI itself doesn't provide any mechanism to verify it (there is no sequence
number or tag to match request/response).
We're relying on the fact that BMC is a requester and initiates communication
with CPU - the interrupt won't be generated if BMC doesn't send any request.

Thanks
-Iwona

From ezequiel at vanguardiasur.com.ar  Sun Aug 29 13:50:31 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sun, 29 Aug 2021 17:50:31 -0300
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
 <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>
Message-ID: <CAAEAJfAwUfwK=Cn7ocedhOaPyMqjL6phwSypkKDXGk6EV4D-vg@mail.gmail.com>

On Wed, 11 Aug 2021 at 14:59, Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> Hi Yunfei,
>
> Thank you for the patch.
>
> On Wed, Aug 11, 2021 at 10:57:59AM +0800, Yunfei Dong wrote:
> > Adds decoder dt-bindings for mt8192.
> >
> > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> > ---
> > v5: no changes
> >
> > This patch depends on "Mediatek MT8192 clock support"[1].
> >
> > The definition of decoder clocks are in mt8192-clk.h, need to include them in case of build fail [1].
> >
> > [1]https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> > ---
> >  .../media/mediatek,vcodec-comp-decoder.yaml   | 172 ++++++++++++++++++
> >  1 file changed, 172 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> > new file mode 100644
> > index 000000000000..083c89933917
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> > @@ -0,0 +1,172 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Mediatek Video Decode Accelerator With Component
> > +
> > +maintainers:
> > +  - Yunfei Dong <yunfei.dong at mediatek.com>
> > +
> > +description: |+
> > +  Mediatek Video Decode is the video decode hardware present in Mediatek
> > +  SoCs which supports high resolution decoding functionalities. Required
> > +  master and component node.
>
> This should explain how the three IP cores relate to each other.
>
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - enum:
> > +          - mediatek,mt8192-vcodec-dec  # for lat hardware
> > +          - mediatek,mtk-vcodec-lat     # for core hardware
> > +          - mediatek,mtk-vcodec-core
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 5
> > +
> > +  clock-names:
> > +    items:
> > +      - const: vdec-sel
> > +      - const: vdec-soc-vdec
> > +      - const: vdec-soc-lat
> > +      - const: vdec-vdec
> > +      - const: vdec-top
> > +
> > +  assigned-clocks: true
> > +
> > +  assigned-clock-parents: true
> > +
> > +  power-domains:
> > +    maxItems: 1
> > +
> > +  iommus:
> > +    minItems: 1
> > +    maxItems: 32
> > +    description: |
> > +      List of the hardware port in respective IOMMU block for current Socs.
> > +      Refer to bindings/iommu/mediatek,iommu.yaml.
> > +
> > +  dma-ranges:
> > +    maxItems: 1
> > +    description: |
> > +      Describes the physical address space of IOMMU maps to memory.
> > +
> > +  mediatek,scp:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    maxItems: 1
> > +    description:
> > +      Describes point to scp.
> > +
> > +required:
> > +      - compatible
> > +      - reg
> > +      - iommus
> > +      - dma-ranges
> > +
> > +allOf:
> > +  - if: #master node
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - mediatek,mt8192-vcodec-dec  # for lat hardware
> > +
> > +    then:
> > +      required:
> > +        - mediatek,scp
> > +
> > +  - if: #component node
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            enum:
> > +              - mediatek,mtk-vcodec-lat     # for core hardware
> > +              - mediatek,mtk-vcodec-core
> > +
> > +    then:
> > +      required:
> > +        - interrupts
> > +        - clocks
> > +        - clock-names
> > +        - assigned-clocks
> > +        - assigned-clock-parents
> > +        - power-domains
> > +
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/memory/mt8192-larb-port.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/clock/mt8192-clk.h>
> > +    #include <dt-bindings/power/mt8192-power.h>
> > +
> > +    vcodec_dec: vcodec_dec at 16000000 {
> > +        compatible = "mediatek,mt8192-vcodec-dec";
> > +        reg = <0 0x16000000 0 0x1000>;               /* VDEC_SYS */
> > +        mediatek,scp = <&scp>;
> > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
> > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > +    };
> > +
> > +    vcodec_lat: vcodec_lat at 0x16010000 {
> > +        compatible = "mediatek,mtk-vcodec-lat";
> > +        reg = <0 0x16010000 0 0x800>;                /* VDEC_MISC */
> > +        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
> > +             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
> > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > +             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
> > +             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
> > +             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
> > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> > +              "vdec-vdec", "vdec-top";
> > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
> > +    };
> > +
> > +    vcodec_core: vcodec_core at 0x16025000 {
> > +        compatible = "mediatek,mtk-vcodec-core";
> > +        reg = <0 0x16025000 0 0x1000>;               /* VDEC_CORE_MISC */
> > +        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
> > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
> > +             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
> > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > +             <&vdecsys CLK_VDEC_VDEC>,
> > +             <&vdecsys CLK_VDEC_LAT>,
> > +             <&vdecsys CLK_VDEC_LARB1>,
> > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> > +              "vdec-vdec", "vdec-top";
> > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
> > +    };
>
> I'm a bit late in the game, reviewing v5 only, but I'm wondering if
> those IP cores need to be modelled in separate nodes. It would be much
> easier, from a software point of view, to have a single node, with
> multiple register ranges.
>
> Are some of those IP cores used in different SoCs, combined in different
> ways, that make a modular design better ?
>

Yeah, I agree with Laurent here. This way of modelling the different parts
of the CODEC as different pieces is the reason why you need a framework
to pull them together, such as the component API (I guess v4l2-async
could have been used as well).

I normally don't bother with driver internals, as its up to each driver
author to decide what is best. However, I believe this design is too
convoluted, and it may lead other developers to follow the same pattern,
so please avoid it.

There are several ways of modelling this and initializing or probing
the sub-devices,
without using any async framework.

Thanks,
Ezequiel


From ezequiel at vanguardiasur.com.ar  Sun Aug 29 13:54:50 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sun, 29 Aug 2021 17:54:50 -0300
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <952c219de7595f7f814d3006fbe25b8089a35212.camel@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
 <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>
 <952c219de7595f7f814d3006fbe25b8089a35212.camel@mediatek.com>
Message-ID: <CAAEAJfB_qZtVpxk8P=26GkZ1j66v+RzzJTqf3UrfMkWNJ1fmFg@mail.gmail.com>

On Tue, 17 Aug 2021 at 00:52, yunfei.dong at mediatek.com
<yunfei.dong at mediatek.com> wrote:
>
> Hi Laurent,
>
> Thanks for your detail suggestion.
>
> On Wed, 2021-08-11 at 20:59 +0300, Laurent Pinchart wrote:
> > Hi Yunfei,
> >
> > Thank you for the patch.
> >
> > On Wed, Aug 11, 2021 at 10:57:59AM +0800, Yunfei Dong wrote:
> > > Adds decoder dt-bindings for mt8192.
> > >
> > > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> > > ---
> > > v5: no changes
> > >
> > > This patch depends on "Mediatek MT8192 clock support"[1].
> > >
> > > The definition of decoder clocks are in mt8192-clk.h, need to
> > > include them in case of build fail [1].
> > >
> > > [1]
> > > https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> > > ---
> > >  .../media/mediatek,vcodec-comp-decoder.yaml   | 172
> > > ++++++++++++++++++
> > >  1 file changed, 172 insertions(+)
> > >  create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > decoder.yaml
> > >
> > > diff --git
> > > a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > decoder.yaml
> > > b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > decoder.yaml
> > > new file mode 100644
> > > index 000000000000..083c89933917
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > decoder.yaml
> > > @@ -0,0 +1,172 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id:
> > > http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Mediatek Video Decode Accelerator With Component
> > > +
> > > +maintainers:
> > > +  - Yunfei Dong <yunfei.dong at mediatek.com>
> > > +
> > > +description: |+
> > > +  Mediatek Video Decode is the video decode hardware present in
> > > Mediatek
> > > +  SoCs which supports high resolution decoding functionalities.
> > > Required
> > > +  master and component node.
> >
> > This should explain how the three IP cores relate to each other.
> >
> I will explain it in next patch.
> > > +
> > > +properties:
> > > +  compatible:
> > > +    oneOf:
> > > +      - enum:
> > > +          - mediatek,mt8192-vcodec-dec  # for lat hardware
> > > +          - mediatek,mtk-vcodec-lat     # for core hardware
> > > +          - mediatek,mtk-vcodec-core
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  interrupts:
> > > +    maxItems: 1
> > > +
> > > +  clocks:
> > > +    maxItems: 5
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: vdec-sel
> > > +      - const: vdec-soc-vdec
> > > +      - const: vdec-soc-lat
> > > +      - const: vdec-vdec
> > > +      - const: vdec-top
> > > +
> > > +  assigned-clocks: true
> > > +
> > > +  assigned-clock-parents: true
> > > +
> > > +  power-domains:
> > > +    maxItems: 1
> > > +
> > > +  iommus:
> > > +    minItems: 1
> > > +    maxItems: 32
> > > +    description: |
> > > +      List of the hardware port in respective IOMMU block for
> > > current Socs.
> > > +      Refer to bindings/iommu/mediatek,iommu.yaml.
> > > +
> > > +  dma-ranges:
> > > +    maxItems: 1
> > > +    description: |
> > > +      Describes the physical address space of IOMMU maps to
> > > memory.
> > > +
> > > +  mediatek,scp:
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +    maxItems: 1
> > > +    description:
> > > +      Describes point to scp.
> > > +
> > > +required:
> > > +      - compatible
> > > +      - reg
> > > +      - iommus
> > > +      - dma-ranges
> > > +
> > > +allOf:
> > > +  - if: #master node
> > > +      properties:
> > > +        compatible:
> > > +          contains:
> > > +            enum:
> > > +              - mediatek,mt8192-vcodec-dec  # for lat hardware
> > > +
> > > +    then:
> > > +      required:
> > > +        - mediatek,scp
> > > +
> > > +  - if: #component node
> > > +      properties:
> > > +        compatible:
> > > +          contains:
> > > +            enum:
> > > +              - mediatek,mtk-vcodec-lat     # for core hardware
> > > +              - mediatek,mtk-vcodec-core
> > > +
> > > +    then:
> > > +      required:
> > > +        - interrupts
> > > +        - clocks
> > > +        - clock-names
> > > +        - assigned-clocks
> > > +        - assigned-clock-parents
> > > +        - power-domains
> > > +
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > > +    #include <dt-bindings/memory/mt8192-larb-port.h>
> > > +    #include <dt-bindings/interrupt-controller/irq.h>
> > > +    #include <dt-bindings/clock/mt8192-clk.h>
> > > +    #include <dt-bindings/power/mt8192-power.h>
> > > +
> > > +    vcodec_dec: vcodec_dec at 16000000 {
> > > +        compatible = "mediatek,mt8192-vcodec-dec";
> > > +        reg = <0 0x16000000 0 0x1000>;             /* VDEC_SYS */
> > > +        mediatek,scp = <&scp>;
> > > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
> > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > +    };
> > > +
> > > +    vcodec_lat: vcodec_lat at 0x16010000 {
> > > +        compatible = "mediatek,mtk-vcodec-lat";
> > > +        reg = <0 0x16010000 0 0x800>;              /* VDEC_MISC */
> > > +        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
> > > +        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
> > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > > +             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
> > > +             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
> > > +             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
> > > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> > > +              "vdec-vdec", "vdec-top";
> > > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
> > > +    };
> > > +
> > > +    vcodec_core: vcodec_core at 0x16025000 {
> > > +        compatible = "mediatek,mtk-vcodec-core";
> > > +        reg = <0 0x16025000 0 0x1000>;             /*
> > > VDEC_CORE_MISC */
> > > +        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
> > > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
> > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > > +             <&vdecsys CLK_VDEC_VDEC>,
> > > +             <&vdecsys CLK_VDEC_LAT>,
> > > +             <&vdecsys CLK_VDEC_LARB1>,
> > > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> > > +              "vdec-vdec", "vdec-top";
> > > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
> > > +    };
> >
> > I'm a bit late in the game, reviewing v5 only, but I'm wondering if
> > those IP cores need to be modelled in separate nodes. It would be
> > much
> > easier, from a software point of view, to have a single node, with
> > multiple register ranges.
> >
> > Are some of those IP cores used in different SoCs, combined in
> > different
> > ways, that make a modular design better ?
> >
> Different platform has different hardware, for mt8192 only has three
> nodes. but mt8195 will has five nodes. and the clk/power/irq/iommu are
> different. It is not easy to manage all hardware at the same time in
> one node, need to enable different hardware at the same time, the logic
> will be very complex.
> It is much easier to handle different hardware using component, enable
> different hardware when we need it.
>
>

You can still have one device-tree node for each device, which means
you can still manage your resources (clk/power/irq/iommu) easily, but doing
this so that it avoids an async framework to pull the parts together.

I gave you this feedback several times, and you have been objecting it
every time  without even trying to consider a different approach.

Thanks,
Ezequiel


From linus.walleij at linaro.org  Sun Aug 29 14:09:19 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 29 Aug 2021 23:09:19 +0200
Subject: [PATCH 1/8] gpio: Add Elba SoC gpio driver for spi cs control
In-Reply-To: <CAK9rFnzDZ4MNm68AJ75g7zegLD-7UMHyoVR-4ssitYTTEeQm5g@mail.gmail.com>
References: <20210304034141.7062-1-brad@pensando.io>
 <20210304034141.7062-2-brad@pensando.io>
 <CACRpkdbQD6p7fbGtuu1c92uXfSFDCTwqjqsXHpgnD5Lg4v0Okw@mail.gmail.com>
 <20210304091025.ny52qjm7wbfvmjgl@mobilestation>
 <CACRpkdZroi+_oHqipS71MAGif190y7jWU5Myf55vz=_um4w5cQ@mail.gmail.com>
 <CAK9rFnzDZ4MNm68AJ75g7zegLD-7UMHyoVR-4ssitYTTEeQm5g@mail.gmail.com>
Message-ID: <CACRpkdZEURRTe15HGf93SvyHej=_6qhfP9KWPSQbCM=SLUVKmA@mail.gmail.com>

On Mon, Aug 23, 2021 at 3:06 AM Brad Larson <brad at pensando.io> wrote:

> The gpio pins being used for the Elba SoC SPI CS are dedicated to this
> function.  Are you recommending that the code in
> drivers/gpio/gpio-elba-spics.c be integrated into
> drivers/spi/spi-dw-mmio.c?

That makes most sense does it not?

Special purpose pins should be managed by that special purpose
hardware driver, DW SPI in this case.

The compatible string etc should be enough to determine that we
need some extra GPIO control here, possibly specify extra registers
for the SPI host etc.

The struct spi_master has a special callback .set_cs() and you
should make this behave special for your special hardware.
In the case of the DW driver it appears that even subdrivers can
pass a custom version of this call in struct dw_spi.

Yours,
Linus Walleij


From mnhagan88 at gmail.com  Sun Aug 29 15:37:47 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sun, 29 Aug 2021 22:37:47 +0000
Subject: [PATCH v2 1/5] ARM: dts: NSP: Add bcm958623hr board name to dts
Message-ID: <20210829223752.2748091-1-mnhagan88@gmail.com>

This board was previously added to
Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml
however the dts file was not updated to reflect this change. This patch
corrects bcm958623hr.dts by adding the board name to the compatible.

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm958623hr.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm958623hr.dts b/arch/arm/boot/dts/bcm958623hr.dts
index 80556882951f..c06871915a1c 100644
--- a/arch/arm/boot/dts/bcm958623hr.dts
+++ b/arch/arm/boot/dts/bcm958623hr.dts
@@ -37,7 +37,7 @@
 
 / {
 	model = "NorthStar Plus SVK (BCM958623HR)";
-	compatible = "brcm,bcm58623", "brcm,nsp";
+	compatible = "brcm,bcm958623hr", "brcm,bcm58623", "brcm,nsp";
 
 	chosen {
 		stdout-path = "serial0:115200n8";
-- 
2.27.0



From mnhagan88 at gmail.com  Sun Aug 29 15:37:48 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sun, 29 Aug 2021 22:37:48 +0000
Subject: [PATCH v2 2/5] ARM: dts: NSP: Fix mpcore, mmc node names
In-Reply-To: <20210829223752.2748091-1-mnhagan88@gmail.com>
References: <20210829223752.2748091-1-mnhagan88@gmail.com>
Message-ID: <20210829223752.2748091-2-mnhagan88@gmail.com>

Running dtbs_check yielded the issues with bcm-nsp.dtsi.

Firstly this patch fixes the following message by appending "-bus" to
the mpcore node name:
mpcore at 19000000: $nodename:0: 'mpcore at 19000000' does not match '^([a-z][a-z0-9\\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'

Secondly mmc node name. The label name can remain as is.
sdhci at 21000: $nodename:0: 'sdhci at 21000' does not match '^mmc(@.*)?$'

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm-nsp.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 745d1d9d7414..6f2ccd059e73 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -77,7 +77,7 @@ pmu {
 		interrupt-affinity = <&cpu0>, <&cpu1>;
 	};
 
-	mpcore at 19000000 {
+	mpcore-bus at 19000000 {
 		compatible = "simple-bus";
 		ranges = <0x00000000 0x19000000 0x00023000>;
 		#address-cells = <1>;
@@ -219,7 +219,7 @@ dma: dma at 20000 {
 			status = "disabled";
 		};
 
-		sdio: sdhci at 21000 {
+		sdio: mmc at 21000 {
 			compatible = "brcm,sdhci-iproc-cygnus";
 			reg = <0x21000 0x100>;
 			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.27.0



From mnhagan88 at gmail.com  Sun Aug 29 15:37:49 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sun, 29 Aug 2021 22:37:49 +0000
Subject: [PATCH v2 3/5] ARM: dts: NSP: Fix MDIO mux node names
In-Reply-To: <20210829223752.2748091-1-mnhagan88@gmail.com>
References: <20210829223752.2748091-1-mnhagan88@gmail.com>
Message-ID: <20210829223752.2748091-3-mnhagan88@gmail.com>

While functional, the mdio-mux-mmioreg binding does not conform to
Documentation/devicetree/bindings/net/mdio-mux-mmioreg.yaml in that an
mdio-mux compatible is also required. Without this the following output
is observed when running dtbs_check:

mdio-mux at 32000: compatible: ['mdio-mux-mmioreg'] is too short

This change brings conformance to this requirement and corresponds
likewise to Rafal Milecki's change to the BCM5301x platform[1].

[1] https://lore.kernel.org/linux-arm-kernel/20210822191256.3715003-1-f.fainelli at gmail.com/T/

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm-nsp.dtsi                | 2 +-
 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 6f2ccd059e73..180827500f25 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -371,7 +371,7 @@ mdio: mdio at 32000 {
 		};
 
 		mdio-mux at 32000 {
-			compatible = "mdio-mux-mmioreg";
+			compatible = "mdio-mux-mmioreg", "mdio-mux";
 			reg = <0x32000 0x4>;
 			mux-mask = <0x200>;
 			#address-cells = <1>;
diff --git a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
index 8860f2fefc63..57d0c5eb9749 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
@@ -72,7 +72,7 @@ led-5 {
 	};
 
 	mdio-mii-mux {
-		compatible = "mdio-mux-mmioreg";
+		compatible = "mdio-mux-mmioreg", "mdio-mux";
 		reg = <0x1803f1c0 0x4>;
 		mux-mask = <0x2000>;
 		mdio-parent-bus = <&mdio_ext>;
-- 
2.27.0



From mnhagan88 at gmail.com  Sun Aug 29 15:37:50 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sun, 29 Aug 2021 22:37:50 +0000
Subject: [PATCH v2 4/5] ARM: dts: NSP: Fix MX64/MX65 eeprom node name
In-Reply-To: <20210829223752.2748091-1-mnhagan88@gmail.com>
References: <20210829223752.2748091-1-mnhagan88@gmail.com>
Message-ID: <20210829223752.2748091-4-mnhagan88@gmail.com>

Running dtbs_check yields the following message when checking the
MX64/MX65 devicetree:
at24 at 50: $nodename:0: 'at24 at 50' does not match '^eeprom@[0-9a-f]{1,2}$'

This patch fixes the issue by renaming the at24 node appropriately.

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
index bcdd38954f1d..6519b7c61af1 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
@@ -48,7 +48,7 @@ &ehci0 {
 &i2c0 {
 	status = "okay";
 
-	at24 at 50 {
+	eeprom at 50 {
 		compatible = "atmel,24c64";
 		reg = <0x50>;
 		pagesize = <32>;
-- 
2.27.0



From mnhagan88 at gmail.com  Sun Aug 29 15:37:51 2021
From: mnhagan88 at gmail.com (Matthew Hagan)
Date: Sun, 29 Aug 2021 22:37:51 +0000
Subject: [PATCH v2 5/5] ARM: dts: NSP: Fix MX65 MDIO mux warnings
In-Reply-To: <20210829223752.2748091-1-mnhagan88@gmail.com>
References: <20210829223752.2748091-1-mnhagan88@gmail.com>
Message-ID: <20210829223752.2748091-5-mnhagan88@gmail.com>

The naming of this node is based upon that of the initial EA9500 dts[1].
However this does not conform with the mdio-mux format, yielding the
following message when running dtbs_check:
mdio-mii-mux: $nodename:0: 'mdio-mii-mux' does not match '^mdio-mux[\\-@]?'

Secondly, this node should be moved to within the axi node and given the
appropriate unit address. This also requires exposing the axi node via a
label in bcm-nsp.dtsi. This fixes the following warning:
Warning (unit_address_vs_reg): /mdio-mii-mux: node has a reg or ranges property, but no unit name

[1]https://patchwork.ozlabs.org/project/linux-imx/patch/20180618174159.86150-1-npcomplete13 at gmail.com/#1941353

Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>
---
 arch/arm/boot/dts/bcm-nsp.dtsi                | 2 +-
 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 6 ++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
index 180827500f25..1c08daa18858 100644
--- a/arch/arm/boot/dts/bcm-nsp.dtsi
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -166,7 +166,7 @@ periph_clk: periph_clk {
 		};
 	};
 
-	axi at 18000000 {
+	axi: axi at 18000000 {
 		compatible = "simple-bus";
 		ranges = <0x00000000 0x18000000 0x0011c40c>;
 		#address-cells = <1>;
diff --git a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
index 57d0c5eb9749..102acd85fab2 100644
--- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
@@ -70,10 +70,12 @@ led-5 {
 			gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
 		};
 	};
+};
 
-	mdio-mii-mux {
+&axi {
+	mdio-mux at 3f1c0 {
 		compatible = "mdio-mux-mmioreg", "mdio-mux";
-		reg = <0x1803f1c0 0x4>;
+		reg = <0x3f1c0 0x4>;
 		mux-mask = <0x2000>;
 		mdio-parent-bus = <&mdio_ext>;
 		#address-cells = <1>;
-- 
2.27.0



From andrew at lunn.ch  Sun Aug 29 17:27:22 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 30 Aug 2021 02:27:22 +0200
Subject: [PATCH v2 3/5] ARM: dts: NSP: Fix MDIO mux node names
In-Reply-To: <20210829223752.2748091-3-mnhagan88@gmail.com>
References: <20210829223752.2748091-1-mnhagan88@gmail.com>
 <20210829223752.2748091-3-mnhagan88@gmail.com>
Message-ID: <YSwl6oh3PX8neSuV@lunn.ch>

On Sun, Aug 29, 2021 at 10:37:49PM +0000, Matthew Hagan wrote:
> While functional, the mdio-mux-mmioreg binding does not conform to
> Documentation/devicetree/bindings/net/mdio-mux-mmioreg.yaml in that an
> mdio-mux compatible is also required. Without this the following output
> is observed when running dtbs_check:
> 
> mdio-mux at 32000: compatible: ['mdio-mux-mmioreg'] is too short
> 
> This change brings conformance to this requirement and corresponds
> likewise to Rafal Milecki's change to the BCM5301x platform[1].
> 
> [1] https://lore.kernel.org/linux-arm-kernel/20210822191256.3715003-1-f.fainelli at gmail.com/T/
> 
> Signed-off-by: Matthew Hagan <mnhagan88 at gmail.com>

Thanks for the expanded commit message.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From zhiyong.tao at mediatek.com  Sun Aug 29 17:35:59 2021
From: zhiyong.tao at mediatek.com (Zhiyong Tao)
Date: Mon, 30 Aug 2021 08:35:59 +0800
Subject: [PATCH v11 0/4]  Mediatek pinctrl patch on mt8195 
Message-ID: <20210830003603.31864-1-zhiyong.tao@mediatek.com>

This series includes 4 patches:
1.add rsel define.
2.change pull up/down description
3.add pm_ops.
4.add rsel setting.

Changes in patch v11:
1)add pm_ops fucntion support
2)change pull up/down description
3)add resistance value feature support.

Changes in patch v10:
1)fix PARENTHESIS_ALIGNMENT of mtk_pinconf_bias_set_rsel
2)fix LONG_LINE warning in 615 in pinctrl-paris.c.

Changes in patch v9:
1)fix "mtk_pinconf_bias_set_rsel" build warning.

Changes in patch v8:
1)add rsel define patch
2)avoid  CamelCase
3)add pinctrl rsel setting patch which is another resistance selection
  solution for I2C on MT8195.

Changes in patch v7:
1)add version in patch and fix spelling mistakes.

Changes in patch v6:
1)add "pintcrl: mediatek" as prefix.

Changes in patch v5:
1)document and driver patch are apploed.
2)change '-EOPNOTSUPP' to '-ENOTSUPP'

Changes in patch v4:
1)fix pinctrl-mt8195.yaml warning error.
2)remove pinctrl device node patch which is based on "mt8195.dtsi".

Changes in patch v3:
1)change '^pins' to '-pins$'.
2)change 'state_0_node_a' to 'gpio_pin' which is defined in dts.
3)change 'state_0_node_b' to 'i2c0_pin' which is defined in dts.
4)reorder this series patches. change pinctrl file and binding document
together in one patch.

There are no changes in v1 & v2.

Zhiyong Tao (4):
dt-bindings: pinctrl: mt8195: add rsel define
  dt-bindings: pinctrl: mt8195: change pull up/down description
  pinctrl: mediatek: mt8195: Add pm_ops
  pinctrl: mediatek: add rsel setting on MT8195

 .../bindings/pinctrl/pinctrl-mt8195.yaml      |  32 +++-
 drivers/pinctrl/mediatek/pinctrl-mt8195.c     | 134 +++++++++++++
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 181 ++++++++++++++++--
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |  35 +++-
 drivers/pinctrl/mediatek/pinctrl-paris.c      |  24 ++-
 drivers/pinctrl/mediatek/pinctrl-paris.h      |   2 +-
 include/dt-bindings/pinctrl/mt65xx.h          |   9 +
 7 files changed, 387 insertions(+), 30 deletions(-)

--
2.18.0


From zhiyong.tao at mediatek.com  Sun Aug 29 17:36:00 2021
From: zhiyong.tao at mediatek.com (Zhiyong Tao)
Date: Mon, 30 Aug 2021 08:36:00 +0800
Subject: [PATCH v11 1/4] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
Message-ID: <20210830003603.31864-2-zhiyong.tao@mediatek.com>

This patch adds rsel define for mt8195.

Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
---
 include/dt-bindings/pinctrl/mt65xx.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/dt-bindings/pinctrl/mt65xx.h b/include/dt-bindings/pinctrl/mt65xx.h
index 7e16e58fe1f7..f5934abcd1bd 100644
--- a/include/dt-bindings/pinctrl/mt65xx.h
+++ b/include/dt-bindings/pinctrl/mt65xx.h
@@ -16,6 +16,15 @@
 #define MTK_PUPD_SET_R1R0_10 102
 #define MTK_PUPD_SET_R1R0_11 103
 
+#define MTK_PULL_SET_RSEL_000  200
+#define MTK_PULL_SET_RSEL_001  201
+#define MTK_PULL_SET_RSEL_010  202
+#define MTK_PULL_SET_RSEL_011  203
+#define MTK_PULL_SET_RSEL_100  204
+#define MTK_PULL_SET_RSEL_101  205
+#define MTK_PULL_SET_RSEL_110  206
+#define MTK_PULL_SET_RSEL_111  207
+
 #define MTK_DRIVE_2mA  2
 #define MTK_DRIVE_4mA  4
 #define MTK_DRIVE_6mA  6
-- 
2.18.0

From zhiyong.tao at mediatek.com  Sun Aug 29 17:36:01 2021
From: zhiyong.tao at mediatek.com (Zhiyong Tao)
Date: Mon, 30 Aug 2021 08:36:01 +0800
Subject: [PATCH v11 2/4] dt-bindings: pinctrl: mt8195: change pull up/down
 description
In-Reply-To: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
Message-ID: <20210830003603.31864-3-zhiyong.tao@mediatek.com>

Change pull up/down description

Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
---
 .../bindings/pinctrl/pinctrl-mt8195.yaml      | 32 +++++++++++++++++--
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
index 2f12ec59eee5..a341ed9f0095 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
@@ -85,9 +85,35 @@ patternProperties:
           2/4/6/8/10/12/14/16mA in mt8195.
         enum: [0, 1, 2, 3, 4, 5, 6, 7]
 
-      bias-pull-down: true
-
-      bias-pull-up: true
+      bias-pull-down:
+        description: |
+          For pull down type is normal, it don't need add RSEL & R1R0 define
+          and resistance value.
+          For pull down type is PUPD/R0/R1 type, it can add R1R0 define to
+          set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
+          "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11"
+          define in mt8195.
+          For pull down type is RSEL, it can add RSEL define & resistance value(ohm)
+          to set different resistance. It can support "MTK_PULL_SET_RSEL_000" &
+          "MTK_PULL_SET_RSEL_001" & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" &
+          "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" &
+          "MTK_PULL_SET_RSEL_111" define in mt8195. It can also support resistance value(ohm)
+          "75000" & "5000" in mt8195.
+
+      bias-pull-up:
+        description: |
+          For pull up type is normal, it don't need add RSEL & R1R0 define
+          and resistance value.
+          For pull up type is PUPD/R0/R1 type, it can add R1R0 define to
+          set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
+          "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11"
+          define in mt8195.
+          For pull up type is RSEL, it can add RSEL define & resistance value(ohm)
+          to set different resistance. It can support "MTK_PULL_SET_RSEL_000" &
+          "MTK_PULL_SET_RSEL_001" & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" &
+          "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" &
+          "MTK_PULL_SET_RSEL_111" define in mt8195. It can also support resistance value(ohm)
+          "1000" & "1500" & "2000" & "3000" & "4000" & "5000" & "10000" & "75000" in mt8195.
 
       bias-disable: true
 
-- 
2.18.0

From zhiyong.tao at mediatek.com  Sun Aug 29 17:36:02 2021
From: zhiyong.tao at mediatek.com (Zhiyong Tao)
Date: Mon, 30 Aug 2021 08:36:02 +0800
Subject: [PATCH v11 3/4] pinctrl: mediatek: mt8195: Add pm_ops
In-Reply-To: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
Message-ID: <20210830003603.31864-4-zhiyong.tao@mediatek.com>

Setting this up will configure wake from suspend properly,
and wake only for the interrupts that are setup in wake_mask,
not all interrupts.

Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
---
 drivers/pinctrl/mediatek/pinctrl-mt8195.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8195.c b/drivers/pinctrl/mediatek/pinctrl-mt8195.c
index a7500e18bb1d..892e79703f98 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8195.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8195.c
@@ -839,6 +839,7 @@ static struct platform_driver mt8195_pinctrl_driver = {
 	.driver = {
 		.name = "mt8195-pinctrl",
 		.of_match_table = mt8195_pinctrl_of_match,
+		.pm = &mtk_paris_pinctrl_pm_ops,
 	},
 	.probe = mt8195_pinctrl_probe,
 };
-- 
2.18.0

From zhiyong.tao at mediatek.com  Sun Aug 29 17:36:03 2021
From: zhiyong.tao at mediatek.com (Zhiyong Tao)
Date: Mon, 30 Aug 2021 08:36:03 +0800
Subject: [PATCH v11 4/4] pinctrl: mediatek: add rsel setting on MT8195
In-Reply-To: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
Message-ID: <20210830003603.31864-5-zhiyong.tao@mediatek.com>

This patch provides rsel setting on MT8195

Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
---
 drivers/pinctrl/mediatek/pinctrl-mt8195.c     | 133 +++++++++++++
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 181 ++++++++++++++++--
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |  35 +++-
 drivers/pinctrl/mediatek/pinctrl-paris.c      |  24 ++-
 drivers/pinctrl/mediatek/pinctrl-paris.h      |   2 +-
 5 files changed, 348 insertions(+), 27 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8195.c b/drivers/pinctrl/mediatek/pinctrl-mt8195.c
index 892e79703f98..275b7ba4386d 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8195.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8195.c
@@ -779,6 +779,135 @@ static const struct mtk_pin_field_calc mt8195_pin_drv_adv_range[] = {
 	PIN_FIELD_BASE(45, 45, 1, 0x040, 0x10, 9, 3),
 };
 
+static const struct mtk_pin_field_calc mt8195_pin_rsel_range[] = {
+	PIN_FIELD_BASE(8, 8, 4, 0x0c0, 0x10, 15, 3),
+	PIN_FIELD_BASE(9, 9, 4, 0x0c0, 0x10, 0, 3),
+	PIN_FIELD_BASE(10, 10, 4, 0x0c0, 0x10, 18, 3),
+	PIN_FIELD_BASE(11, 11, 4, 0x0c0, 0x10, 3, 3),
+	PIN_FIELD_BASE(12, 12, 4, 0x0c0, 0x10, 21, 3),
+	PIN_FIELD_BASE(13, 13, 4, 0x0c0, 0x10, 6, 3),
+	PIN_FIELD_BASE(14, 14, 4, 0x0c0, 0x10, 24, 3),
+	PIN_FIELD_BASE(15, 15, 4, 0x0c0, 0x10, 9, 3),
+	PIN_FIELD_BASE(16, 16, 4, 0x0c0, 0x10, 27, 3),
+	PIN_FIELD_BASE(17, 17, 4, 0x0c0, 0x10, 12, 3),
+	PIN_FIELD_BASE(29, 29, 2, 0x080, 0x10, 0, 3),
+	PIN_FIELD_BASE(30, 30, 2, 0x080, 0x10, 3, 3),
+	PIN_FIELD_BASE(34, 34, 1, 0x0e0, 0x10, 0, 3),
+	PIN_FIELD_BASE(35, 35, 1, 0x0e0, 0x10, 3, 3),
+	PIN_FIELD_BASE(44, 44, 1, 0x0e0, 0x10, 6, 3),
+	PIN_FIELD_BASE(45, 45, 1, 0x0e0, 0x10, 9, 3),
+};
+
+static const struct mtk_pin_rsel mt8195_pin_rsel_val_range[] = {
+	PIN_RSEL(8, 17, 0x0, 75000, 75000),
+	PIN_RSEL(8, 17, 0x1, 10000, 5000),
+	PIN_RSEL(8, 17, 0x2, 5000, 75000),
+	PIN_RSEL(8, 17, 0x3, 4000, 5000),
+	PIN_RSEL(8, 17, 0x4, 3000, 75000),
+	PIN_RSEL(8, 17, 0x5, 2000, 5000),
+	PIN_RSEL(8, 17, 0x6, 1500, 75000),
+	PIN_RSEL(8, 17, 0x7, 1000, 5000),
+	PIN_RSEL(29, 30, 0x0, 75000, 75000),
+	PIN_RSEL(29, 30, 0x1, 10000, 5000),
+	PIN_RSEL(29, 30, 0x2, 5000, 75000),
+	PIN_RSEL(29, 30, 0x3, 4000, 5000),
+	PIN_RSEL(29, 30, 0x4, 3000, 75000),
+	PIN_RSEL(29, 30, 0x5, 2000, 5000),
+	PIN_RSEL(29, 30, 0x6, 1500, 75000),
+	PIN_RSEL(29, 30, 0x7, 1000, 5000),
+	PIN_RSEL(34, 35, 0x0, 75000, 75000),
+	PIN_RSEL(34, 35, 0x1, 10000, 5000),
+	PIN_RSEL(34, 35, 0x2, 5000, 75000),
+	PIN_RSEL(34, 35, 0x3, 4000, 5000),
+	PIN_RSEL(34, 35, 0x4, 3000, 75000),
+	PIN_RSEL(34, 35, 0x5, 2000, 5000),
+	PIN_RSEL(34, 35, 0x6, 1500, 75000),
+	PIN_RSEL(34, 35, 0x7, 1000, 5000),
+	PIN_RSEL(44, 45, 0x0, 75000, 75000),
+	PIN_RSEL(44, 45, 0x1, 10000, 5000),
+	PIN_RSEL(44, 45, 0x2, 5000, 75000),
+	PIN_RSEL(44, 45, 0x3, 4000, 5000),
+	PIN_RSEL(44, 45, 0x4, 3000, 75000),
+	PIN_RSEL(44, 45, 0x5, 2000, 5000),
+	PIN_RSEL(44, 45, 0x6, 1500, 75000),
+	PIN_RSEL(44, 45, 0x7, 1000, 5000),
+};
+
+static const unsigned int mt8195_pull_type[] = {
+	MTK_PULL_PUPD_R1R0_TYPE /* 0 */, MTK_PULL_PUPD_R1R0_TYPE /* 1 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 2 */, MTK_PULL_PUPD_R1R0_TYPE /* 3 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 4 */, MTK_PULL_PUPD_R1R0_TYPE /* 5 */,
+	MTK_PULL_PU_PD_TYPE /* 6 */, MTK_PULL_PU_PD_TYPE /* 7 */,
+	MTK_PULL_PU_PD_RSEL_TYPE /* 8 */, MTK_PULL_PU_PD_RSEL_TYPE /* 9 */,
+	MTK_PULL_PU_PD_RSEL_TYPE /* 10 */, MTK_PULL_PU_PD_RSEL_TYPE /* 11 */,
+	MTK_PULL_PU_PD_RSEL_TYPE /* 12 */, MTK_PULL_PU_PD_RSEL_TYPE /* 13 */,
+	MTK_PULL_PU_PD_RSEL_TYPE /* 14 */, MTK_PULL_PU_PD_RSEL_TYPE /* 15 */,
+	MTK_PULL_PU_PD_RSEL_TYPE /* 16 */, MTK_PULL_PU_PD_RSEL_TYPE /* 17 */,
+	MTK_PULL_PU_PD_TYPE /* 18 */, MTK_PULL_PU_PD_TYPE /* 19 */,
+	MTK_PULL_PU_PD_TYPE /* 20 */, MTK_PULL_PU_PD_TYPE /* 21 */,
+	MTK_PULL_PU_PD_TYPE /* 22 */, MTK_PULL_PU_PD_TYPE /* 23 */,
+	MTK_PULL_PU_PD_TYPE /* 24 */, MTK_PULL_PU_PD_TYPE /* 25 */,
+	MTK_PULL_PU_PD_TYPE /* 26 */, MTK_PULL_PU_PD_TYPE /* 27 */,
+	MTK_PULL_PU_PD_TYPE /* 28 */, MTK_PULL_PU_PD_RSEL_TYPE /* 29 */,
+	MTK_PULL_PU_PD_RSEL_TYPE /* 30 */, MTK_PULL_PU_PD_TYPE /* 31 */,
+	MTK_PULL_PU_PD_TYPE /* 32 */, MTK_PULL_PU_PD_TYPE /* 33 */,
+	MTK_PULL_PU_PD_RSEL_TYPE /* 34 */, MTK_PULL_PU_PD_RSEL_TYPE /* 35 */,
+	MTK_PULL_PU_PD_TYPE /* 36 */, MTK_PULL_PU_PD_TYPE /* 37 */,
+	MTK_PULL_PU_PD_TYPE /* 38 */, MTK_PULL_PU_PD_TYPE /* 39 */,
+	MTK_PULL_PU_PD_TYPE /* 40 */, MTK_PULL_PU_PD_TYPE /* 41 */,
+	MTK_PULL_PU_PD_TYPE /* 42 */, MTK_PULL_PU_PD_TYPE /* 43 */,
+	MTK_PULL_PU_PD_RSEL_TYPE /* 44 */, MTK_PULL_PU_PD_RSEL_TYPE /* 45 */,
+	MTK_PULL_PU_PD_TYPE /* 46 */, MTK_PULL_PU_PD_TYPE /* 47 */,
+	MTK_PULL_PU_PD_TYPE /* 48 */, MTK_PULL_PU_PD_TYPE /* 49 */,
+	MTK_PULL_PU_PD_TYPE /* 50 */, MTK_PULL_PU_PD_TYPE /* 51 */,
+	MTK_PULL_PU_PD_TYPE /* 52 */, MTK_PULL_PU_PD_TYPE /* 53 */,
+	MTK_PULL_PU_PD_TYPE /* 54 */, MTK_PULL_PU_PD_TYPE /* 55 */,
+	MTK_PULL_PU_PD_TYPE /* 56 */, MTK_PULL_PU_PD_TYPE /* 57 */,
+	MTK_PULL_PU_PD_TYPE /* 58 */, MTK_PULL_PU_PD_TYPE /* 59 */,
+	MTK_PULL_PU_PD_TYPE /* 60 */, MTK_PULL_PU_PD_TYPE /* 61 */,
+	MTK_PULL_PU_PD_TYPE /* 62 */, MTK_PULL_PU_PD_TYPE /* 63 */,
+	MTK_PULL_PU_PD_TYPE /* 64 */, MTK_PULL_PU_PD_TYPE /* 65 */,
+	MTK_PULL_PU_PD_TYPE /* 66 */, MTK_PULL_PU_PD_TYPE /* 67 */,
+	MTK_PULL_PU_PD_TYPE /* 68 */, MTK_PULL_PU_PD_TYPE /* 69 */,
+	MTK_PULL_PU_PD_TYPE /* 70 */, MTK_PULL_PU_PD_TYPE /* 71 */,
+	MTK_PULL_PU_PD_TYPE /* 72 */, MTK_PULL_PU_PD_TYPE /* 73 */,
+	MTK_PULL_PU_PD_TYPE /* 74 */, MTK_PULL_PU_PD_TYPE /* 75 */,
+	MTK_PULL_PU_PD_TYPE /* 76 */, MTK_PULL_PUPD_R1R0_TYPE /* 77 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 78 */, MTK_PULL_PUPD_R1R0_TYPE /* 79 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 80 */, MTK_PULL_PUPD_R1R0_TYPE /* 81 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 82 */, MTK_PULL_PUPD_R1R0_TYPE /* 83 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 84 */, MTK_PULL_PUPD_R1R0_TYPE /* 85 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 86 */, MTK_PULL_PUPD_R1R0_TYPE /* 87 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 88 */, MTK_PULL_PUPD_R1R0_TYPE /* 89 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 90 */, MTK_PULL_PUPD_R1R0_TYPE /* 91 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 92 */, MTK_PULL_PUPD_R1R0_TYPE /* 93 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 94 */, MTK_PULL_PUPD_R1R0_TYPE /* 95 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 96 */, MTK_PULL_PU_PD_TYPE /* 97 */,
+	MTK_PULL_PU_PD_TYPE /* 98 */, MTK_PULL_PU_PD_TYPE /* 99 */,
+	MTK_PULL_PU_PD_TYPE /* 100 */, MTK_PULL_PU_PD_TYPE /* 101 */,
+	MTK_PULL_PU_PD_TYPE /* 102 */, MTK_PULL_PU_PD_TYPE /* 103 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 104 */, MTK_PULL_PUPD_R1R0_TYPE /* 105 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 106 */, MTK_PULL_PUPD_R1R0_TYPE /* 107 */,
+	MTK_PULL_PU_PD_TYPE /* 108 */, MTK_PULL_PU_PD_TYPE /* 109 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 110 */, MTK_PULL_PUPD_R1R0_TYPE /* 111 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 112 */, MTK_PULL_PUPD_R1R0_TYPE /* 113 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 114 */, MTK_PULL_PUPD_R1R0_TYPE /* 115 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 116 */, MTK_PULL_PUPD_R1R0_TYPE /* 117 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 118 */, MTK_PULL_PUPD_R1R0_TYPE /* 119 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 120 */, MTK_PULL_PUPD_R1R0_TYPE /* 121 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 122 */, MTK_PULL_PUPD_R1R0_TYPE /* 123 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 124 */, MTK_PULL_PUPD_R1R0_TYPE /* 125 */,
+	MTK_PULL_PUPD_R1R0_TYPE /* 126 */, MTK_PULL_PUPD_R1R0_TYPE /* 127 */,
+	MTK_PULL_PU_PD_TYPE /* 128 */, MTK_PULL_PU_PD_TYPE /* 129 */,
+	MTK_PULL_PU_PD_TYPE /* 130 */, MTK_PULL_PU_PD_TYPE /* 131 */,
+	MTK_PULL_PU_PD_TYPE /* 132 */, MTK_PULL_PU_PD_TYPE /* 133 */,
+	MTK_PULL_PU_PD_TYPE /* 134 */, MTK_PULL_PU_PD_TYPE /* 135 */,
+	MTK_PULL_PU_PD_TYPE /* 136 */, MTK_PULL_PU_PD_TYPE /* 137 */,
+	MTK_PULL_PU_PD_TYPE /* 138 */, MTK_PULL_PU_PD_TYPE /* 139 */,
+	MTK_PULL_PU_PD_TYPE /* 140 */, MTK_PULL_PU_PD_TYPE /* 141 */,
+	MTK_PULL_PU_PD_TYPE /* 142 */, MTK_PULL_PU_PD_TYPE /* 143 */,
+};
+
 static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = {
 	[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8195_pin_mode_range),
 	[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8195_pin_dir_range),
@@ -793,6 +922,7 @@ static const struct mtk_pin_reg_calc mt8195_reg_cals[PINCTRL_PIN_REG_MAX] = {
 	[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8195_pin_r0_range),
 	[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8195_pin_r1_range),
 	[PINCTRL_PIN_REG_DRV_ADV] = MTK_RANGE(mt8195_pin_drv_adv_range),
+	[PINCTRL_PIN_REG_RSEL] = MTK_RANGE(mt8195_pin_rsel_range),
 };
 
 static const char * const mt8195_pinctrl_register_base_names[] = {
@@ -817,6 +947,9 @@ static const struct mtk_pin_soc mt8195_data = {
 	.gpio_m = 0,
 	.base_names = mt8195_pinctrl_register_base_names,
 	.nbase_names = ARRAY_SIZE(mt8195_pinctrl_register_base_names),
+	.pull_type = mt8195_pull_type,
+	.pin_rsel = mt8195_pin_rsel_val_range,
+	.npin_rsel = ARRAY_SIZE(mt8195_pin_rsel_val_range),
 	.bias_set_combo = mtk_pinconf_bias_set_combo,
 	.bias_get_combo = mtk_pinconf_bias_get_combo,
 	.drive_set = mtk_pinconf_drive_set_rev1,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 5b3b048725cc..b6a89d41f040 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -641,6 +641,9 @@ static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
 	} else if (arg == MTK_PUPD_SET_R1R0_11) {
 		r0 = 1;
 		r1 = 1;
+	} else if (arg == MTK_ENABLE) {
+		r0 = 1;
+		r1 = 0;
 	} else {
 		err = -EINVAL;
 		goto out;
@@ -661,6 +664,75 @@ static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
 	return err;
 }
 
+static int mtk_hw_pin_rsel_lookup(struct mtk_pinctrl *hw,
+				  const struct mtk_pin_desc *desc,
+				  u32 pullup, u32 arg, u32 *rsel_val)
+{
+	const struct mtk_pin_rsel *rsel;
+	int check;
+	bool found = false;
+
+	rsel = hw->soc->pin_rsel;
+
+	for (check = 0; check <= hw->soc->npin_rsel - 1; check++) {
+		if (desc->number >= rsel[check].s_pin &&
+		    desc->number <= rsel[check].e_pin) {
+			if (pullup) {
+				if (rsel[check].up_rsel == arg) {
+					found = true;
+					*rsel_val = rsel[check].rsel_index;
+					break;
+				}
+			} else {
+				if (rsel[check].down_rsel == arg) {
+					found = true;
+					*rsel_val = rsel[check].rsel_index;
+					break;
+				}
+			}
+		}
+	}
+
+	if (!found) {
+		dev_err(hw->dev, "Not support rsel value %d Ohm for pin = %d (%s)\n",
+			arg, desc->number, desc->name);
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
+				     const struct mtk_pin_desc *desc,
+				     u32 pullup, u32 arg)
+{
+	int err, rsel_val;
+
+	if (hw->soc->pin_rsel) {
+		/* find pin rsel_index from pin_rsel array*/
+		err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);
+		if (err)
+			goto out;
+	} else {
+		if (arg < MTK_PULL_SET_RSEL_000 ||
+		    arg > MTK_PULL_SET_RSEL_111) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		rsel_val -= MTK_PULL_SET_RSEL_000;
+	}
+
+	err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_RSEL, rsel_val);
+	if (err)
+		goto out;
+
+	err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, MTK_ENABLE);
+
+out:
+	return err;
+}
+
 static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
 				const struct mtk_pin_desc *desc,
 				u32 *pullup, u32 *enable)
@@ -742,44 +814,117 @@ static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
 	return err;
 }
 
-int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
-				const struct mtk_pin_desc *desc,
-				u32 pullup, u32 arg)
+static int mtk_pinconf_bias_get_rsel(struct mtk_pinctrl *hw,
+				     const struct mtk_pin_desc *desc,
+				     u32 *pullup, u32 *enable)
 {
-	int err;
+	int pu, pd, rsel, err;
 
-	err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
-	if (!err)
+	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_RSEL, &rsel);
+	if (err)
 		goto out;
 
-	err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
-	if (!err)
+	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
+	if (err)
 		goto out;
 
-	err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
+	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
+
+	if (pu == 0 && pd == 0) {
+		*pullup = 0;
+		*enable = MTK_DISABLE;
+	} else if (pu == 1 && pd == 0) {
+		*pullup = 1;
+		*enable = rsel + MTK_PULL_SET_RSEL_000;
+	} else if (pu == 0 && pd == 1) {
+		*pullup = 0;
+		*enable = rsel + MTK_PULL_SET_RSEL_000;
+	} else {
+		err = -EINVAL;
+		goto out;
+	}
 
 out:
 	return err;
 }
+
+int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+			       const struct mtk_pin_desc *desc,
+			       u32 pullup, u32 arg)
+{
+	int err = -EOPNOTSUPP;
+	bool try_all_type;
+
+	try_all_type = hw->soc->pull_type ? false : true;
+
+	if (try_all_type ||
+	    (hw->soc->pull_type[desc->number] & MTK_PULL_RSEL_TYPE)) {
+		err = mtk_pinconf_bias_set_rsel(hw, desc, pullup, arg);
+		if (!err)
+			return err;
+	}
+
+	if (try_all_type ||
+	    (hw->soc->pull_type[desc->number] & MTK_PULL_PU_PD_TYPE)) {
+		err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+		if (!err)
+			return err;
+	}
+
+	if (try_all_type ||
+	    (hw->soc->pull_type[desc->number] & MTK_PULL_PULLSEL_TYPE)) {
+		err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc,
+							  pullup, arg);
+		if (!err)
+			return err;
+	}
+
+	if (try_all_type ||
+	    (hw->soc->pull_type[desc->number] & MTK_PULL_PUPD_R1R0_TYPE)) {
+		err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
+		if (err)
+			dev_err(hw->dev, "Invalid pull argument\n");
+	}
+
+	return err;
+}
 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_set_combo);
 
 int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
 			      const struct mtk_pin_desc *desc,
 			      u32 *pullup, u32 *enable)
 {
-	int err;
+	int err = -EOPNOTSUPP;
+	bool try_all_type;
 
-	err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
-	if (!err)
-		goto out;
+	try_all_type = hw->soc->pull_type ? false : true;
 
-	err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
-	if (!err)
-		goto out;
+	if (try_all_type ||
+	    (hw->soc->pull_type[desc->number] & MTK_PULL_RSEL_TYPE)) {
+		err = mtk_pinconf_bias_get_rsel(hw, desc, pullup, enable);
+		if (!err)
+			return err;
+	}
+
+	if (try_all_type ||
+	    (hw->soc->pull_type[desc->number] & MTK_PULL_PU_PD_TYPE)) {
+		err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+		if (!err)
+			return err;
+	}
 
-	err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
+	if (try_all_type ||
+	    (hw->soc->pull_type[desc->number] & MTK_PULL_PULLSEL_TYPE)) {
+		err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc,
+							  pullup, enable);
+		if (!err)
+			return err;
+	}
+
+	if (try_all_type ||
+	    (hw->soc->pull_type[desc->number] & MTK_PULL_PUPD_R1R0_TYPE))
+		err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
 
-out:
 	return err;
 }
 EXPORT_SYMBOL_GPL(mtk_pinconf_bias_get_combo);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index a6f1bdb2083b..a3d73f153efe 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -17,6 +17,13 @@
 #define MTK_ENABLE     1
 #define MTK_PULLDOWN   0
 #define MTK_PULLUP     1
+#define MTK_PULL_PU_PD_TYPE		BIT(0)
+#define MTK_PULL_PULLSEL_TYPE		BIT(1)
+#define MTK_PULL_PUPD_R1R0_TYPE		BIT(2)
+#define MTK_PULL_RSEL_TYPE		BIT(3)
+#define MTK_PULL_PU_PD_RSEL_TYPE	(MTK_PULL_PU_PD_TYPE \
+					| MTK_PULL_RSEL_TYPE)
+
 
 #define EINT_NA	U16_MAX
 #define NO_EINT_SUPPORT	EINT_NA
@@ -42,6 +49,14 @@
 	PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit,	\
 		       _x_bits, 32, 1)
 
+#define PIN_RSEL(_s_pin, _e_pin, _rsel_index, _up_resl, _down_rsel) {	\
+		.s_pin = _s_pin,					\
+		.e_pin = _e_pin,					\
+		.rsel_index = _rsel_index,				\
+		.up_rsel = _up_resl,					\
+		.down_rsel = _down_rsel,				\
+	}
+
 /* List these attributes which could be modified for the pin */
 enum {
 	PINCTRL_PIN_REG_MODE,
@@ -67,6 +82,7 @@ enum {
 	PINCTRL_PIN_REG_DRV_E0,
 	PINCTRL_PIN_REG_DRV_E1,
 	PINCTRL_PIN_REG_DRV_ADV,
+	PINCTRL_PIN_REG_RSEL,
 	PINCTRL_PIN_REG_MAX,
 };
 
@@ -129,6 +145,21 @@ struct mtk_pin_field_calc {
 	u8  fixed;
 };
 
+/* struct mtk_pin_rsel - the structure that providing bias resistance selection.
+ * @s_pin:		the start pin within the rsel range
+ * @e_pin:		the end pin within the rsel range
+ * @rsel_index:	the rsel bias resistance index
+ * @up_rsel:	the pullup rsel bias resistance value
+ * @down_rsel:	the pulldown rsel bias resistance value
+ */
+struct mtk_pin_rsel {
+	u16 s_pin;
+	u16 e_pin;
+	u16 rsel_index;
+	u32 up_rsel;
+	u32 down_rsel;
+};
+
 /* struct mtk_pin_reg_calc - the structure that holds all ranges used to
  *			     determine which register the pin would make use of
  *			     for certain pin attribute.
@@ -206,6 +237,9 @@ struct mtk_pin_soc {
 	bool				ies_present;
 	const char * const		*base_names;
 	unsigned int			nbase_names;
+	const unsigned int		*pull_type;
+	const struct mtk_pin_rsel	*pin_rsel;
+	unsigned int			npin_rsel;
 
 	/* Specific pinconfig operations */
 	int (*bias_disable_set)(struct mtk_pinctrl *hw,
@@ -237,7 +271,6 @@ struct mtk_pin_soc {
 			     const struct mtk_pin_desc *desc, u32 arg);
 	int (*adv_drive_get)(struct mtk_pinctrl *hw,
 			     const struct mtk_pin_desc *desc, u32 *val);
-
 	/* Specific driver data */
 	void				*driver_data;
 };
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 85db2e4377f0..8990cfe47d72 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -577,9 +577,9 @@ static int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int
 	mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DRV)
 
 ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
-	unsigned int gpio, char *buf, unsigned int bufLen)
+	unsigned int gpio, char *buf, unsigned int buf_len)
 {
-	int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1;
+	int pinmux, pullup, pullen, len = 0, r1 = -1, r0 = -1, rsel = -1;
 	const struct mtk_pin_desc *desc;
 
 	if (gpio >= hw->soc->npins)
@@ -591,6 +591,8 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
 		pinmux -= hw->soc->nfuncs;
 
 	mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+
+	/* Case for: R1R0 */
 	if (pullen == MTK_PUPD_SET_R1R0_00) {
 		pullen = 0;
 		r1 = 0;
@@ -607,10 +609,16 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
 		pullen = 1;
 		r1 = 1;
 		r0 = 1;
-	} else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
-		pullen = 0;
 	}
-	len += scnprintf(buf + len, bufLen - len,
+
+	/* Case for: RSEL */
+	if (pullen >= MTK_PULL_SET_RSEL_000 &&
+	    pullen <= MTK_PULL_SET_RSEL_111) {
+		rsel = pullen - MTK_PULL_SET_RSEL_000;
+		pullen = 1;
+	}
+
+	len += scnprintf(buf + len, buf_len - len,
 			"%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
 			gpio,
 			pinmux,
@@ -624,10 +632,12 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
 			pullup);
 
 	if (r1 != -1) {
-		len += scnprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+		len += scnprintf(buf + len, buf_len - len, " (%1d %1d)\n",
 			r1, r0);
+	} else if (rsel != -1) {
+		len += scnprintf(buf + len, buf_len - len, " (%1d)\n", rsel);
 	} else {
-		len += scnprintf(buf + len, bufLen - len, "\n");
+		len += scnprintf(buf + len, buf_len - len, "\n");
 	}
 
 	return len;
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h b/drivers/pinctrl/mediatek/pinctrl-paris.h
index afb7650fd25b..681267c0e1a4 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.h
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -61,7 +61,7 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
 			    const struct mtk_pin_soc *soc);
 
 ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
-	unsigned int gpio, char *buf, unsigned int bufLen);
+	unsigned int gpio, char *buf, unsigned int buf_len);
 
 extern const struct dev_pm_ops mtk_paris_pinctrl_pm_ops;
 
-- 
2.18.0

From zhaoxiao at uniontech.com  Sun Aug 29 18:24:17 2021
From: zhaoxiao at uniontech.com (zhaoxiao)
Date: Mon, 30 Aug 2021 09:24:17 +0800
Subject: [PATCH v2] stmmac: dwmac-loongson: change the pr_info() to dev_err()
 in loongson_dwmac_probe()
Message-ID: <20210830012417.14872-1-zhaoxiao@uniontech.com>

Change the pr_info to dev_err.

Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
---
v2: Remove the adding a return. 
 drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
index 4c9a37dd0d3f..abcb55f87579 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
@@ -54,14 +54,13 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 	bool mdio = false;
 
 	np = dev_of_node(&pdev->dev);
-
 	if (!np) {
-		pr_info("dwmac_loongson_pci: No OF node\n");
+		dev_err(&pdev->dev, "dwmac_loongson_pci: No OF node\n");
 		return -ENODEV;
 	}
 
 	if (!of_device_is_compatible(np, "loongson, pci-gmac")) {
-		pr_info("dwmac_loongson_pci: Incompatible OF node\n");
+		dev_err(&pdev->dev, "dwmac_loongson_pci: Incompatible OF node\n");
 		return -ENODEV;
 	}
 
@@ -69,6 +68,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 	if (!plat)
 		return -ENOMEM;
 
+
 	if (plat->mdio_node) {
 		dev_err(&pdev->dev, "Found MDIO subnode\n");
 		mdio = true;
@@ -111,6 +111,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 	phy_mode = device_get_phy_mode(&pdev->dev);
 	if (phy_mode < 0)
 		dev_err(&pdev->dev, "phy_mode not found\n");
+	
 
 	plat->phy_interface = phy_mode;
 	plat->interface = PHY_INTERFACE_MODE_GMII;
-- 
2.20.1





From zhaoxiao at uniontech.com  Sun Aug 29 18:39:39 2021
From: zhaoxiao at uniontech.com (zhaoxiao)
Date: Mon, 30 Aug 2021 09:39:39 +0800
Subject: [PATCH] stmmac: dwmac-loongson: change the pr_info() to dev_err()
 in loongson_dwmac_probe()
In-Reply-To: <20210827070238.7586fb11@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
References: <20210827085550.13519-1-zhaoxiao@uniontech.com>
 <20210827070238.7586fb11@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
Message-ID: <70a8527d-d488-7d82-668f-9b43f9ef0951@uniontech.com>+4ACC63ED8D3FDBB2

Thanks for your advices, and I change the patch and commit again.

? 2021/8/27 ??10:02, Jakub Kicinski ??:
> On Fri, 27 Aug 2021 16:55:50 +0800 zhaoxiao wrote:
>> - Change the pr_info/dev_info to dev_err.
>> - Add the dev_err to improve readability.
>>
>> Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
>> ---
>>   .../net/ethernet/stmicro/stmmac/dwmac-loongson.c  | 15 +++++++++------
>>   1 file changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
>> index 4c9a37dd0d3f..495c94e7929f 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
>> @@ -54,20 +54,21 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>>   	bool mdio = false;
>>   
>>   	np = dev_of_node(&pdev->dev);
>> -
>>   	if (!np) {
>> -		pr_info("dwmac_loongson_pci: No OF node\n");
>> +		dev_err(&pdev->dev, "dwmac_loongson_pci: No OF node\n");
>>   		return -ENODEV;
>>   	}
>>   
>>   	if (!of_device_is_compatible(np, "loongson, pci-gmac")) {
>> -		pr_info("dwmac_loongson_pci: Incompatible OF node\n");
>> +		dev_err(&pdev->dev, "dwmac_loongson_pci: Incompatible OF node\n");
>>   		return -ENODEV;
>>   	}
>>   
>>   	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
>> -	if (!plat)
>> +	if (!plat) {
>> +		dev_err(&pdev->dev, "memory allocation failed\n");
> Please don't add error messages after allocation failures. OOM will
> produce a lot of kernel messages and a stack trace already.
>
>>   		return -ENOMEM;
>> +	}
>>   
>>   	if (plat->mdio_node) {
>>   		dev_err(&pdev->dev, "Found MDIO subnode\n");
>> @@ -109,8 +110,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>>   		plat->bus_id = pci_dev_id(pdev);
>>   
>>   	phy_mode = device_get_phy_mode(&pdev->dev);
>> -	if (phy_mode < 0)
>> +	if (phy_mode < 0) {
>>   		dev_err(&pdev->dev, "phy_mode not found\n");
>> +		return phy_mode;
> You're adding a return here, it should be a separate patch with its own
> justification.
>
>> +	}
>>   
>>   	plat->phy_interface = phy_mode;
>>   	plat->interface = PHY_INTERFACE_MODE_GMII;
>> @@ -130,7 +133,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>>   
>>   	res.wol_irq = of_irq_get_byname(np, "eth_wake_irq");
>>   	if (res.wol_irq < 0) {
>> -		dev_info(&pdev->dev, "IRQ eth_wake_irq not found, using macirq\n");
>> +		dev_err(&pdev->dev, "IRQ eth_wake_irq not found, using macirq\n");
> Why upgrade to an error, isn't wol_irq optional?
>
>>   		res.wol_irq = res.irq;
>>   	}
>>   
>




From hayashi.kunihiko at socionext.com  Sun Aug 29 19:22:36 2021
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Mon, 30 Aug 2021 11:22:36 +0900
Subject: [PATCH v2 0/2] PCI: uniphier: Fix INTx masking/unmasking
Message-ID: <1630290158-31264-1-git-send-email-hayashi.kunihiko@socionext.com>

This series includes some fixes to INTx masking/unmasking for UniPhier PCIe
host controller driver.

- Remove unnecessary bit clears to INTX mask field
- Remove unnecessary irq_ack() function because write access to status field
  doesn't work
- Add lock into callback functions to avoid race condition

Kunihiko Hayashi (2):
  PCI: uniphier: Fix INTx mask/unmask bit operation and remove ack
    function
  PCI: uniphier: Serialize INTx masking/unmasking

 drivers/pci/controller/dwc/pcie-uniphier.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

-- 
2.7.4



From hayashi.kunihiko at socionext.com  Sun Aug 29 19:22:37 2021
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Mon, 30 Aug 2021 11:22:37 +0900
Subject: [PATCH v2 1/2] PCI: uniphier: Fix INTx mask/unmask bit operation and
 remove ack function
In-Reply-To: <1630290158-31264-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1630290158-31264-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <1630290158-31264-2-git-send-email-hayashi.kunihiko@socionext.com>

INTX mask and unmask fields in PCL_RCV_INTX register should only be
set/reset for each bit. Clearing by PCL_RCV_INTX_ALL_MASK should be
removed.

INTX status fields in PCL_RCV_INTX register only indicates each INTX
interrupt status, so the handler can't clear by writing 1 to the field.
The status is expected to be cleared by the interrupt origin.
The ack function has no meaning, so should remove it.

Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pci/controller/dwc/pcie-uniphier.c | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index ebe43e9..26f630c 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -181,19 +181,6 @@ static void uniphier_pcie_irq_enable(struct uniphier_pcie_priv *priv)
 	writel(PCL_RCV_INTX_ALL_ENABLE, priv->base + PCL_RCV_INTX);
 }
 
-static void uniphier_pcie_irq_ack(struct irq_data *d)
-{
-	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
-	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
-	u32 val;
-
-	val = readl(priv->base + PCL_RCV_INTX);
-	val &= ~PCL_RCV_INTX_ALL_STATUS;
-	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
-	writel(val, priv->base + PCL_RCV_INTX);
-}
-
 static void uniphier_pcie_irq_mask(struct irq_data *d)
 {
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
@@ -202,7 +189,6 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
 	u32 val;
 
 	val = readl(priv->base + PCL_RCV_INTX);
-	val &= ~PCL_RCV_INTX_ALL_MASK;
 	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
 }
@@ -215,14 +201,12 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
 	u32 val;
 
 	val = readl(priv->base + PCL_RCV_INTX);
-	val &= ~PCL_RCV_INTX_ALL_MASK;
 	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
 }
 
 static struct irq_chip uniphier_pcie_irq_chip = {
 	.name = "PCI",
-	.irq_ack = uniphier_pcie_irq_ack,
 	.irq_mask = uniphier_pcie_irq_mask,
 	.irq_unmask = uniphier_pcie_irq_unmask,
 };
-- 
2.7.4



From hayashi.kunihiko at socionext.com  Sun Aug 29 19:22:38 2021
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Mon, 30 Aug 2021 11:22:38 +0900
Subject: [PATCH v2 2/2] PCI: uniphier: Serialize INTx masking/unmasking
In-Reply-To: <1630290158-31264-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1630290158-31264-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <1630290158-31264-3-git-send-email-hayashi.kunihiko@socionext.com>

The condition register PCI_RCV_INTX is used in irq_mask() and irq_unmask()
callbacks. Accesses to register can occur at the same time without a lock.
Add a lock into each callback to prevent the issue.

Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
Suggested-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
Acked-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/dwc/pcie-uniphier.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index 26f630c..0ddeec0 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -186,11 +186,16 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+	unsigned long flags;
 	u32 val;
 
+	raw_spin_lock_irqsave(&pp->lock, flags);
+
 	val = readl(priv->base + PCL_RCV_INTX);
 	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
+
+	raw_spin_unlock_irqrestore(&pp->lock, flags);
 }
 
 static void uniphier_pcie_irq_unmask(struct irq_data *d)
@@ -198,11 +203,16 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
 	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
+	unsigned long flags;
 	u32 val;
 
+	raw_spin_lock_irqsave(&pp->lock, flags);
+
 	val = readl(priv->base + PCL_RCV_INTX);
 	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
 	writel(val, priv->base + PCL_RCV_INTX);
+
+	raw_spin_unlock_irqrestore(&pp->lock, flags);
 }
 
 static struct irq_chip uniphier_pcie_irq_chip = {
-- 
2.7.4



From cw9316.lee at samsung.com  Sun Aug 29 19:17:49 2021
From: cw9316.lee at samsung.com (Chanwoo Lee)
Date: Mon, 30 Aug 2021 11:17:49 +0900
Subject: [PATCH] mmc: mtk-sd: Remove unused parameters
References: <CGME20210830022507epcas1p43b45563c6e36bd00e3b6160bb42605bf@epcas1p4.samsung.com>
Message-ID: <20210830021749.5947-1-cw9316.lee@samsung.com>

From: ChanWoo Lee <cw9316.lee at samsung.com>

Remove unused parameters
1. msdc_start_data() - struct mmc_request *mrq
2. msdc_track_cmd_data() - struct mmc_data *data

Signed-off-by: ChanWoo Lee <cw9316.lee at samsung.com>
---
 drivers/mmc/host/mtk-sd.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 4dfc246c5f95..a8736067c409 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1043,8 +1043,8 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host,
 	return rawcmd;
 }
 
-static void msdc_start_data(struct msdc_host *host, struct mmc_request *mrq,
-			    struct mmc_command *cmd, struct mmc_data *data)
+static void msdc_start_data(struct msdc_host *host, struct mmc_command *cmd,
+		struct mmc_data *data)
 {
 	bool read;
 
@@ -1112,8 +1112,7 @@ static void msdc_recheck_sdio_irq(struct msdc_host *host)
 	}
 }
 
-static void msdc_track_cmd_data(struct msdc_host *host,
-				struct mmc_command *cmd, struct mmc_data *data)
+static void msdc_track_cmd_data(struct msdc_host *host, struct mmc_command *cmd)
 {
 	if (host->error)
 		dev_dbg(host->dev, "%s: cmd=%d arg=%08X; host->error=0x%08X\n",
@@ -1134,7 +1133,7 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
 	host->mrq = NULL;
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	msdc_track_cmd_data(host, mrq->cmd, mrq->data);
+	msdc_track_cmd_data(host, mrq->cmd);
 	if (mrq->data)
 		msdc_unprepare_data(host, mrq->data);
 	if (host->error)
@@ -1295,7 +1294,7 @@ static void msdc_cmd_next(struct msdc_host *host,
 	else if (!cmd->data)
 		msdc_request_done(host, mrq);
 	else
-		msdc_start_data(host, mrq, cmd, cmd->data);
+		msdc_start_data(host, cmd, cmd->data);
 }
 
 static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq)
-- 
2.29.0



From guangming.cao at mediatek.com  Sun Aug 29 19:39:11 2021
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Mon, 30 Aug 2021 10:39:11 +0800
Subject: [PATCH] dma-buf: Add support for mapping buffers with DMA attributes
Message-ID: <20210830023911.4410-1-guangming.cao@mediatek.com>

From: Guangming Cao <Guangming.Cao at mediatek.com>

When mapping the memory represented by a dma-buf into a device's
address space, it might be desireable to map the memory with
certain DMA attributes. Thus, introduce the dma_mapping_attrs
field in the dma_buf_attachment structure so that when
the memory is mapped with dma_buf_map_attachment, it is mapped
with the desired DMA attributes.

Signed-off-by: Isaac J. Manjarres <isaacm at codeaurora.org>
Signed-off-by: Sandeep Patil <sspatil at google.com>
Signed-off-by: Guangming Cao <Guangming.Cao at mediatek.com>
---
 drivers/dma-buf/heaps/cma_heap.c    | 6 ++++--
 drivers/dma-buf/heaps/system_heap.c | 6 ++++--
 include/linux/dma-buf.h             | 3 +++
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index 0c05b79870f9..2c9feb3bfc3e 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -99,9 +99,10 @@ static struct sg_table *cma_heap_map_dma_buf(struct dma_buf_attachment *attachme
 {
 	struct dma_heap_attachment *a = attachment->priv;
 	struct sg_table *table = &a->table;
+	int attrs = attachment->dma_map_attrs;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
 	if (ret)
 		return ERR_PTR(-ENOMEM);
 	a->mapped = true;
@@ -113,9 +114,10 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   enum dma_data_direction direction)
 {
 	struct dma_heap_attachment *a = attachment->priv;
+	int attrs = attachment->dma_map_attrs;
 
 	a->mapped = false;
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(attachment->dev, table, direction, attrs);
 }
 
 static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 23a7e74ef966..fc7b1e02988e 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -130,9 +130,10 @@ static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attac
 {
 	struct dma_heap_attachment *a = attachment->priv;
 	struct sg_table *table = a->table;
+	int attrs = attachment->dma_map_attrs;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
 	if (ret)
 		return ERR_PTR(ret);
 
@@ -145,9 +146,10 @@ static void system_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				      enum dma_data_direction direction)
 {
 	struct dma_heap_attachment *a = attachment->priv;
+	int attrs = attachment->dma_map_attrs;
 
 	a->mapped = false;
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(attachment->dev, table, direction, attrs);
 }
 
 static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index efdc56b9d95f..4d650731766e 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -379,6 +379,8 @@ struct dma_buf_attach_ops {
  * @importer_ops: importer operations for this attachment, if provided
  * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
  * @importer_priv: importer specific attachment data.
+ * @dma_map_attrs: DMA attributes to be used when the exporter maps the buffer
+ * through dma_buf_map_attachment.
  *
  * This structure holds the attachment information between the dma_buf buffer
  * and its user device(s). The list contains one attachment struct per device
@@ -399,6 +401,7 @@ struct dma_buf_attachment {
 	const struct dma_buf_attach_ops *importer_ops;
 	void *importer_priv;
 	void *priv;
+	unsigned long dma_map_attrs;
 };
 
 /**
-- 
2.17.1

From ikjn at chromium.org  Sun Aug 29 20:49:24 2021
From: ikjn at chromium.org (Ikjoon Jang)
Date: Mon, 30 Aug 2021 11:49:24 +0800
Subject: [PATCH next v2 3/6] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <18cb18d7d0ea4a3bb46921aca88c53646f1b3764.camel@mediatek.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
 <20210826025144.51992-3-chunfeng.yun@mediatek.com>
 <CAATdQgBD+dTtBie-cNKRJbfxEpc3haqjfUu1k26mTk8pCSOEww@mail.gmail.com>
 <72ee7a203d8a49e6e43a954b45133470ee6d5c16.camel@mediatek.com>
 <CAATdQgA+4VC7J1LMZYOZMV-OTjMGjO=9bJZ7uaCu_MMF-20T1w@mail.gmail.com>
 <18cb18d7d0ea4a3bb46921aca88c53646f1b3764.camel@mediatek.com>
Message-ID: <CAATdQgDKuO+bM7_tMy59ghhhjrgCp53kHgYbgEciriHNF3uKuA@mail.gmail.com>

On Fri, Aug 27, 2021 at 5:49 PM Chunfeng Yun (???)
<Chunfeng.Yun at mediatek.com> wrote:
>
> On Fri, 2021-08-27 at 17:14 +0800, Ikjoon Jang wrote:
> > On Fri, Aug 27, 2021 at 2:49 PM Chunfeng Yun (???)
> > <Chunfeng.Yun at mediatek.com> wrote:
> > >
> > > On Thu, 2021-08-26 at 19:54 +0800, Ikjoon Jang wrote:
> > > > Hi Chunfeng,
> > > >
> > > > On Thu, Aug 26, 2021 at 10:52 AM Chunfeng Yun <
> > > > chunfeng.yun at mediatek.com> wrote:
> > > > >
> > > > > Use @bw_budget_table[] to update fs bus bandwidth due to
> > > > > not all microframes consume @bw_cost_per_microframe, see
> > > > > setup_sch_info().
> > > > >
> > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > > > > ---
> > > > > v2: new patch, move from another series
> > > > > ---
> > > > >  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
> > > > >  1 file changed, 7 insertions(+), 10 deletions(-)
> > > > >
> > > > > diff --git a/drivers/usb/host/xhci-mtk-sch.c
> > > > > b/drivers/usb/host/xhci-mtk-sch.c
> > > > > index cffcaf4dfa9f..83abd28269ca 100644
> > > > > --- a/drivers/usb/host/xhci-mtk-sch.c
> > > > > +++ b/drivers/usb/host/xhci-mtk-sch.c
> > > > > @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct
> > > > > mu3h_sch_ep_info *sch_ep, int offset)
> > > > >                  * Compared with hs bus, no matter what ep
> > > > > type,
> > > > >                  * the hub will always delay one uframe to send
> > > > > data
> > > > >                  */
> > > > > -               for (j = 0; j < sch_ep->cs_count; j++) {
> > > > > -                       tmp = tt->fs_bus_bw[base + j] + sch_ep-
> > > > > > bw_cost_per_microframe;
> > > > >
> > > > > +               for (j = 0; j < sch_ep->num_budget_microframes;
> > > > > j++) {
> > > > > +                       tmp = tt->fs_bus_bw[base + j] + sch_ep-
> > > > > > bw_budget_table[j];
> > > >
> > > > I'm worrying about this case with two endpoints,
> > > > * EP1OUT: isochronous, maxpacket=192: bw_budget_table[] = { 188,
> > > > 188,
> > > > 0, ... }
> > > > * EP2IN: interrupt, maxpacket=64: bw_budget_table[] = { 0, 0, 64,
> > > > 64,
> > > > ... }
> > > > (Is this correct bw_budget_table contents for those eps?)
> > >
> > > Yes, ep1out isoc use two uframe, ep2in intr use a extra cs;
> > > >
> > > > I'm not sure if it's okay for those two endpoints to be allocated
> > > > on the same u-frame slot.
> > > > Can you please check if this is okay for xhci-mtk?
> > >
> > > Already test it this afternoon, can transfer data rightly on our
> > > dvt
> > > env.
> > >
> > > > (I feel like I already asked the same questions many times.)
> > >
> > > Yes, as said before, prefer to use bw_budget_table[], if there is
> > > issue, we can fix it by building this table.
> >
> > So do you mean such an allocation shouldn't be a problem by IP
> > design?
> Yes, at least on our dvt platform

Did you check that your side also has a similar allocation
(SSPLIT-all sits between SSPLIT-start ~ -end for another ep)?
My audio headset doesn't work properly with this scheme.

>
> >
> > This patch starts to allow such an allocation (again).
> > But i remember my earlier tests showed that when those two eps
> > in the above example are allocated on the same u-frame slot,
> > xhci-mtk puts "SSPLIT for EP2" between
> > "SSPLIT-start and SSPLIT-end for EP1OUT transaction",
> > which is a spec violation.
>
> Which section in usb2.0 spec?

I think that's just a basic rule - if software wants to send 192 bytes
through a full-speed bus, HC should send OUT/DATA 192 bytes
continuously without inserting any other packets during that 192 bytes.
and usb2 11.14.2 mentions that TT has separated
Start-Split and Complete-Split buffers
but not tracked each transaction per endpoint basis.

>
> > Hub will generate bit stuffing errors on the
> > full-speed bus.
> which platform?

I remember it was mt8173.

And for bit stuffing errors I mentioned in the earlier mail.
when I read the spec again, 11.21 mentions that bit stuffing error
is generated when _a microframe_ should be passed without
corresponding SSPLIT-mid/end. So this is not the case and also
I'm not sure what will happen on the full-speed bus, sorry.
In my case what I can be sure of is that the audio output was
broken with those allotments.

What is the xhci-mtk's policy when there are more than two EPs
marked as the same u-frame offset like in the above example?

>
> >
> >
> > >
> > > Thanks
> > > >
> > > >
> > > > >                         if (tmp > FS_PAYLOAD_MAX)
> > > > >                                 return -ESCH_BW_OVERFLOW;
> > > > >                 }
> > > > > @@ -534,21 +534,18 @@ static void update_sch_tt(struct
> > > > > mu3h_sch_ep_info *sch_ep, bool used)
> > > > >  {
> > > > >         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
> > > > >         u32 base, num_esit;
> > > > > -       int bw_updated;
> > > > >         int i, j;
> > > > >
> > > > >         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> > > > >
> > > > > -       if (used)
> > > > > -               bw_updated = sch_ep->bw_cost_per_microframe;
> > > > > -       else
> > > > > -               bw_updated = -sch_ep->bw_cost_per_microframe;
> > > > > -
> > > > >         for (i = 0; i < num_esit; i++) {
> > > > >                 base = sch_ep->offset + i * sch_ep->esit;
> > > > >
> > > > > -               for (j = 0; j < sch_ep->cs_count; j++)
> > > > > -                       tt->fs_bus_bw[base + j] += bw_updated;
> > > > > +               for (j = 0; j < sch_ep->num_budget_microframes;
> > > > > j++)
> > > > > +                       if (used)
> > > > > +                               tt->fs_bus_bw[base + j] +=
> > > > > sch_ep-
> > > > > > bw_budget_table[j];
> > > > >
> > > > > +                       else
> > > > > +                               tt->fs_bus_bw[base + j] -=
> > > > > sch_ep-
> > > > > > bw_budget_table[j];
> > > > >
> > > > >         }
> > > > >
> > > > >         if (used)
> > > > > --
> > > > > 2.18.0
> > > > >


From wangkefeng.wang at huawei.com  Sun Aug 29 21:05:04 2021
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Mon, 30 Aug 2021 12:05:04 +0800
Subject: [PATCH] arm64: kdump: Skip kmemleak scan reserved memory for kdump
In-Reply-To: <20210827092246.3565437-1-chenwandun@huawei.com>
References: <20210827092246.3565437-1-chenwandun@huawei.com>
Message-ID: <d2fce1a3-b87a-6a35-19b9-e5d5b2f723f5@huawei.com>


On 2021/8/27 17:22, Chen Wandun wrote:
> Trying to boot with kdump + kmemleak, command will result in a crash:
> "echo scan > /sys/kernel/debug/kmemleak"
>
> crashkernel reserved: 0x0000000007c00000 - 0x0000000027c00000 (512 MB)
> Kernel command line: BOOT_IMAGE=(hd1,gpt2)/vmlinuz-5.14.0-rc5-next-20210809+ root=/dev/mapper/ao-root ro rd.lvm.lv=ao/root rd.lvm.lv=ao/swap crashkernel=512M
> Unable to handle kernel paging request at virtual address ffff000007c00000
> Mem abort info:
>    ESR = 0x96000007
>    EC = 0x25: DABT (current EL), IL = 32 bits
>    SET = 0, FnV = 0
>    EA = 0, S1PTW = 0
>    FSC = 0x07: level 3 translation fault
> Data abort info:
>    ISV = 0, ISS = 0x00000007
>    CM = 0, WnR = 0
> swapper pgtable: 64k pages, 48-bit VAs, pgdp=00002024f0d80000
> [ffff000007c00000] pgd=1800205ffffd0003, p4d=1800205ffffd0003, pud=1800205ffffd0003, pmd=1800205ffffc0003, pte=0068000007c00f06
> Internal error: Oops: 96000007 [#1] SMP
> pstate: 804000c9 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : scan_block+0x98/0x230
> lr : scan_block+0x94/0x230
> sp : ffff80008d6cfb70
> x29: ffff80008d6cfb70 x28: 0000000000000000 x27: 0000000000000000
> x26: 00000000000000c0 x25: 0000000000000001 x24: 0000000000000000
> x23: ffffa88a6b18b398 x22: ffff000007c00ff9 x21: ffffa88a6ac7fc40
> x20: ffffa88a6af6a830 x19: ffff000007c00000 x18: 0000000000000000
> x17: 0000000000000000 x16: 0000000000000000 x15: ffffffffffffffff
> x14: ffffffff00000000 x13: ffffffffffffffff x12: 0000000000000020
> x11: 0000000000000000 x10: 0000000001080000 x9 : ffffa88a6951c77c
> x8 : ffffa88a6a893988 x7 : ffff203ff6cfb3c0 x6 : ffffa88a6a52b3c0
> x5 : ffff203ff6cfb3c0 x4 : 0000000000000000 x3 : 0000000000000000
> x2 : 0000000000000001 x1 : ffff20226cb56a40 x0 : 0000000000000000
> Call trace:
>   scan_block+0x98/0x230
>   scan_gray_list+0x120/0x270
>   kmemleak_scan+0x3a0/0x648
>   kmemleak_write+0x3ac/0x4c8
>   full_proxy_write+0x6c/0xa0
>   vfs_write+0xc8/0x2b8
>   ksys_write+0x70/0xf8
>   __arm64_sys_write+0x24/0x30
>   invoke_syscall+0x4c/0x110
>   el0_svc_common+0x9c/0x190
>   do_el0_svc+0x30/0x98
>   el0_svc+0x28/0xd8
>   el0t_64_sync_handler+0x90/0xb8
>   el0t_64_sync+0x180/0x184
>
> The reserved memory for kdump will be looked up by kmemleak, this area
> will be set invalid when kdump service is bring up. That will result in
> crash when kmemleak scan this area.
>
> Fixes: 461ef12c4375 ("memblock: make memblock_find_in_range method private")
> Signed-off-by: Chen Wandun <chenwandun at huawei.com>
Reviewed-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>   arch/arm64/mm/init.c | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index b16be52233c6..dc0c44622bfd 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -30,6 +30,7 @@
>   #include <linux/crash_dump.h>
>   #include <linux/hugetlb.h>
>   #include <linux/acpi_iort.h>
> +#include <linux/kmemleak.h>
>   
>   #include <asm/boot.h>
>   #include <asm/fixmap.h>
> @@ -101,6 +102,7 @@ static void __init reserve_crashkernel(void)
>   	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>   		crash_base, crash_base + crash_size, crash_size >> 20);
>   
> +	kmemleak_ignore_phys(crash_base);
>   	crashk_res.start = crash_base;
>   	crashk_res.end = crash_base + crash_size - 1;
>   }


From viresh.kumar at linaro.org  Sun Aug 29 22:04:50 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 30 Aug 2021 10:34:50 +0530
Subject: [PATCH v14 2/3] cpufreq: Add of_perf_domain_get_sharing_cpumask
In-Reply-To: <1630162872-25452-3-git-send-email-hector.yuan@mediatek.com>
References: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
 <1630162872-25452-3-git-send-email-hector.yuan@mediatek.com>
Message-ID: <20210830050450.r4kfv72bsxsttnli@vireshk-i7>

On 28-08-21, 23:01, Hector Yuan wrote:
> From: "Hector.Yuan" <hector.yuan at mediatek.com>
> 
> Add of_perf_domain_get_sharing_cpumask function to group cpu
> to specific performance domain.
> 
> Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
> ---
>  include/linux/cpufreq.h |   39 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 9fd7194..4916d70 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -13,6 +13,8 @@
>  #include <linux/completion.h>
>  #include <linux/kobject.h>
>  #include <linux/notifier.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/pm_qos.h>
>  #include <linux/spinlock.h>
>  #include <linux/sysfs.h>
> @@ -1036,6 +1038,43 @@ void arch_set_freq_scale(const struct cpumask *cpus,
>  }
>  #endif
>  
> +#ifdef CONFIG_CPU_FREQ
> +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name,
> +						     const char *cell_name,
> +						     struct cpumask *cpumask)

What happened with the discussion we had about returning index and passing CPU
there ?

-- 
viresh


From viresh.kumar at linaro.org  Sun Aug 29 22:11:08 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 30 Aug 2021 10:41:08 +0530
Subject: [PATCH v14 3/3] cpufreq: mediatek-hw: Add support for CPUFREQ HW
In-Reply-To: <1630162872-25452-4-git-send-email-hector.yuan@mediatek.com>
References: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
 <1630162872-25452-4-git-send-email-hector.yuan@mediatek.com>
Message-ID: <20210830051108.xgfwp2uvh724syeu@vireshk-i7>

On 28-08-21, 23:01, Hector Yuan wrote:
> +static int mtk_cpu_resources_init(struct platform_device *pdev,
> +				  struct cpufreq_policy *policy,
> +				  const u16 *offsets)
> +{
> +	struct mtk_cpufreq_data *data;
> +	struct device *dev = &pdev->dev;
> +	void __iomem *base;
> +	int ret, i;
> +	int index;
> +
> +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	index = of_perf_domain_get_sharing_cpumask(policy->cpu, "performance-domains",
> +						   "#performance-domain-cells",
> +						   policy->cpus);

You pass CPU here, while the first patch accepts index. Does this even work? Or
work just by chance ?

-- 
viresh


From zhaoxiao at uniontech.com  Sun Aug 29 22:29:13 2021
From: zhaoxiao at uniontech.com (zhaoxiao)
Date: Mon, 30 Aug 2021 13:29:13 +0800
Subject: [PATCH] stmmac: dwmac-loongson:add the return value
Message-ID: <20210830052913.12793-1-zhaoxiao@uniontech.com>

Add the return value when phy_mode < 0.

Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
index 4c9a37dd0d3f..ecf759ee1c9f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
@@ -109,8 +109,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 		plat->bus_id = pci_dev_id(pdev);
 
 	phy_mode = device_get_phy_mode(&pdev->dev);
-	if (phy_mode < 0)
+	if (phy_mode < 0) {
 		dev_err(&pdev->dev, "phy_mode not found\n");
+		return phy_mode;
+	}
 
 	plat->phy_interface = phy_mode;
 	plat->interface = PHY_INTERFACE_MODE_GMII;
-- 
2.20.1





From jassisinghbrar at gmail.com  Sun Aug 29 22:34:03 2021
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Mon, 30 Aug 2021 00:34:03 -0500
Subject: [PATCH v6 0/5] Add gce support for mt8195
In-Reply-To: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
References: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
Message-ID: <CABb+yY0rTZrM1J7mFbSf0Z5tdwjYsQ8Tff-DnVfxX8P4HRu01w@mail.gmail.com>

On Wed, Aug 25, 2021 at 4:41 AM jason-jh.lin <jason-jh.lin at mediatek.com> wrote:
>
> Change in v6:
> - remove the unused define in GCE header file.
>
Please rebase the patches over other previous mtk patchset for mt8192.
https://git.linaro.org/landing-teams/working/fujitsu/integration.git/log/?h=mailbox-for-next

Thanks.


From Claudiu.Beznea at microchip.com  Sun Aug 29 22:46:13 2021
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Mon, 30 Aug 2021 05:46:13 +0000
Subject: [PATCH v2 0/6] clk: at91: updates for power management and dvfs
In-Reply-To: <163021931214.2676726.2951110502140668721@swboyd.mtv.corp.google.com>
References: <20210401122726.28528-1-claudiu.beznea@microchip.com>
 <6ecc4822-8112-43d4-1259-cd7dfe79d71c@microchip.com>
 <163021931214.2676726.2951110502140668721@swboyd.mtv.corp.google.com>
Message-ID: <35d409b5-75d9-636e-e9c5-42d833b8e592@microchip.com>

On 29.08.2021 09:41, Stephen Boyd wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Quoting Claudiu.Beznea at microchip.com (2021-08-02 01:36:52)
>> On 01.04.2021 15:27, Claudiu Beznea wrote:
>> Hi Stephen,
>>
>> Please ignore the DVFS patch in this series
>> (clk: at91: clk-master: update for dvfs) as I have some updates to it. I'll
>> introduce them in the next version.
>>
> 
> Can I apply the rest of them though?
> 

Yes, please! One note, at patch "clk: at91: clk-master: add register
definition for sama7g5's master clock", is that changes in header
(include/linux/clk/at91_pmc.h) were taken trough [1] via at91 tree because
the build was broken at some point for multi_v7_defconfig on linux-next.

Thank you,
Claudiu Beznea

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/at91/linux.git/commit/?id=ec03f18cc222bb7bec074ce7845c157d1c5195f6

From yunfei.dong at mediatek.com  Sun Aug 29 23:07:44 2021
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Mon, 30 Aug 2021 14:07:44 +0800
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <CAAEAJfAwUfwK=Cn7ocedhOaPyMqjL6phwSypkKDXGk6EV4D-vg@mail.gmail.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
 <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>
 <CAAEAJfAwUfwK=Cn7ocedhOaPyMqjL6phwSypkKDXGk6EV4D-vg@mail.gmail.com>
Message-ID: <885db6cd26907939511ff132c0fa3ad122c0e588.camel@mediatek.com>

On Sun, 2021-08-29 at 17:50 -0300, Ezequiel Garcia wrote:
> On Wed, 11 Aug 2021 at 14:59, Laurent Pinchart
> <laurent.pinchart at ideasonboard.com> wrote:
> > 
> > Hi Yunfei,
> > 
> > Thank you for the patch.
> > 
> > On Wed, Aug 11, 2021 at 10:57:59AM +0800, Yunfei Dong wrote:
> > > Adds decoder dt-bindings for mt8192.
> > > 
> > > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> > > ---
> > > v5: no changes
> > > 
> > > This patch depends on "Mediatek MT8192 clock support"[1].
> > > 
> > > The definition of decoder clocks are in mt8192-clk.h, need to
> > > include them in case of build fail [1].
> > > 
> > > [1]
> > > https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> > > ---
> > >  .../media/mediatek,vcodec-comp-decoder.yaml   | 172
> > > ++++++++++++++++++
> > >  1 file changed, 172 insertions(+)
> > >  create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > decoder.yaml
> > > 
> > > diff --git
> > > a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > decoder.yaml
> > > b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > decoder.yaml
> > > new file mode 100644
> > > index 000000000000..083c89933917
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > > comp-decoder.yaml
> > > @@ -0,0 +1,172 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: 
> > > http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Mediatek Video Decode Accelerator With Component
> > > +
> > > +maintainers:
> > > +  - Yunfei Dong <yunfei.dong at mediatek.com>
> > > +
> > > +description: |+
> > > +  Mediatek Video Decode is the video decode hardware present in
> > > Mediatek
> > > +  SoCs which supports high resolution decoding functionalities.
> > > Required
> > > +  master and component node.
> > 
> > This should explain how the three IP cores relate to each other.
> > 
> > > +
> > > +properties:
> > > +  compatible:
> > > +    oneOf:
> > > +      - enum:
> > > +          - mediatek,mt8192-vcodec-dec  # for lat hardware
> > > +          - mediatek,mtk-vcodec-lat     # for core hardware
> > > +          - mediatek,mtk-vcodec-core
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  interrupts:
> > > +    maxItems: 1
> > > +
> > > +  clocks:
> > > +    maxItems: 5
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: vdec-sel
> > > +      - const: vdec-soc-vdec
> > > +      - const: vdec-soc-lat
> > > +      - const: vdec-vdec
> > > +      - const: vdec-top
> > > +
> > > +  assigned-clocks: true
> > > +
> > > +  assigned-clock-parents: true
> > > +
> > > +  power-domains:
> > > +    maxItems: 1
> > > +
> > > +  iommus:
> > > +    minItems: 1
> > > +    maxItems: 32
> > > +    description: |
> > > +      List of the hardware port in respective IOMMU block for
> > > current Socs.
> > > +      Refer to bindings/iommu/mediatek,iommu.yaml.
> > > +
> > > +  dma-ranges:
> > > +    maxItems: 1
> > > +    description: |
> > > +      Describes the physical address space of IOMMU maps to
> > > memory.
> > > +
> > > +  mediatek,scp:
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +    maxItems: 1
> > > +    description:
> > > +      Describes point to scp.
> > > +
> > > +required:
> > > +      - compatible
> > > +      - reg
> > > +      - iommus
> > > +      - dma-ranges
> > > +
> > > +allOf:
> > > +  - if: #master node
> > > +      properties:
> > > +        compatible:
> > > +          contains:
> > > +            enum:
> > > +              - mediatek,mt8192-vcodec-dec  # for lat hardware
> > > +
> > > +    then:
> > > +      required:
> > > +        - mediatek,scp
> > > +
> > > +  - if: #component node
> > > +      properties:
> > > +        compatible:
> > > +          contains:
> > > +            enum:
> > > +              - mediatek,mtk-vcodec-lat     # for core hardware
> > > +              - mediatek,mtk-vcodec-core
> > > +
> > > +    then:
> > > +      required:
> > > +        - interrupts
> > > +        - clocks
> > > +        - clock-names
> > > +        - assigned-clocks
> > > +        - assigned-clock-parents
> > > +        - power-domains
> > > +
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > > +    #include <dt-bindings/memory/mt8192-larb-port.h>
> > > +    #include <dt-bindings/interrupt-controller/irq.h>
> > > +    #include <dt-bindings/clock/mt8192-clk.h>
> > > +    #include <dt-bindings/power/mt8192-power.h>
> > > +
> > > +    vcodec_dec: vcodec_dec at 16000000 {
> > > +        compatible = "mediatek,mt8192-vcodec-dec";
> > > +        reg = <0 0x16000000 0 0x1000>;               /* VDEC_SYS
> > > */
> > > +        mediatek,scp = <&scp>;
> > > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
> > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > +    };
> > > +
> > > +    vcodec_lat: vcodec_lat at 0x16010000 {
> > > +        compatible = "mediatek,mtk-vcodec-lat";
> > > +        reg = <0 0x16010000 0 0x800>;                /*
> > > VDEC_MISC */
> > > +        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
> > > +        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
> > > +             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
> > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > > +             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
> > > +             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
> > > +             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
> > > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-
> > > lat",
> > > +              "vdec-vdec", "vdec-top";
> > > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
> > > +    };
> > > +
> > > +    vcodec_core: vcodec_core at 0x16025000 {
> > > +        compatible = "mediatek,mtk-vcodec-core";
> > > +        reg = <0 0x16025000 0 0x1000>;               /*
> > > VDEC_CORE_MISC */
> > > +        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
> > > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
> > > +             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
> > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > > +             <&vdecsys CLK_VDEC_VDEC>,
> > > +             <&vdecsys CLK_VDEC_LAT>,
> > > +             <&vdecsys CLK_VDEC_LARB1>,
> > > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-
> > > lat",
> > > +              "vdec-vdec", "vdec-top";
> > > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
> > > +    };
> > 
> > I'm a bit late in the game, reviewing v5 only, but I'm wondering if
> > those IP cores need to be modelled in separate nodes. It would be
> > much
> > easier, from a software point of view, to have a single node, with
> > multiple register ranges.
> > 
> > Are some of those IP cores used in different SoCs, combined in
> > different
> > ways, that make a modular design better ?
> > 
> 
1. Each a node should respect a HW node. Defining a complex node that
contain multiple register is not better, for they belong to different
hardware. Different platforms has different hardware count, mt8195 has
five hardwares.
2. Another reason is from the IOMMU point, the vcodec HW include core
and lat hardwares, each of them connect to the independent IOMMU
hardware for mt8195, can't write all iommu ports together, or hardware
can't access dram data, so we must separate them.
> Yeah, I agree with Laurent here. This way of modelling the different
> parts
> of the CODEC as different pieces is the reason why you need a
> framework
> to pull them together, such as the component API (I guess v4l2-async
> could have been used as well).
> 
We must separate each hardware node, only master need to register video
and media device, component just used for store clk/power/irq/register
information for current hardware.
> I normally don't bother with driver internals, as its up to each
> driver
> author to decide what is best. However, I believe this design is too
> convoluted, and it may lead other developers to follow the same
> pattern,
> so please avoid it.
> 
According to your information, it looks that component and v4l2 async
are ok for this architecture, only component is too convoluted(iommu
driver also use component).

For we are not very familiar with v4l2 async, out architecture is
designed for component include next forty patches. It is a very big
change for out driver. I will try to spend a lot of time to change it.

> There are several ways of modelling this and initializing or probing
> the sub-devices,
> without using any async framework.
> 
You may misunderstand, I'm not objecting your suggestion every time,
for our driver is designed for component api, need to spend a lot of
time to change it in many platforms. I will change it if v4l2 async has
many advantages then component as you said. I will try to use v4l2
async as compared.

> Thanks,
> Ezequiel

Thanks for your suggestion.
Yunfei Dong

From herbert at gondor.apana.org.au  Sun Aug 29 23:26:34 2021
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Mon, 30 Aug 2021 14:26:34 +0800
Subject: [PATCH v7 0/7] running kernel mode SIMD with softirqs disabled
In-Reply-To: <CAMj1kXEUbPMadj1J7MWD_B-=2zRc2ir_zZQN3Puz3n+PjQw58Q@mail.gmail.com>
References: <20210827070342.218276-1-ardb@kernel.org>
 <CAMj1kXEUbPMadj1J7MWD_B-=2zRc2ir_zZQN3Puz3n+PjQw58Q@mail.gmail.com>
Message-ID: <20210830062634.GA30356@gondor.apana.org.au>

On Sun, Aug 29, 2021 at 08:35:37AM +0200, Ard Biesheuvel wrote:
>
> Any chance we could get this queued for v5.15? If it's too late,
> please consider taking only the first three patches as an alternative,
> and I will resend the CCM ones for v5.16 once they have all been
> reviewed.

Sorry, it's too late for that.  If these are to serve as dependencies
for other work, perhaps you can just add my acks to them and
submit them to the trees where they are needed?

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From sugar.zhang at rock-chips.com  Sun Aug 29 23:38:45 2021
From: sugar.zhang at rock-chips.com (Sugar Zhang)
Date: Mon, 30 Aug 2021 14:38:45 +0800
Subject: [PATCH v2] ASoC: rockchip: i2s: Fix concurrency between tx/rx
Message-ID: <1630305525-65759-1-git-send-email-sugar.zhang@rock-chips.com>

This patch adds lock to fix comcurrency between tx/rx
to fix 'rockchip-i2s ff070000.i2s; fail to clear'

Considering the situation;

       tx stream              rx stream
           |                      |
           |                   disable
         enable                   |
           |                    reset

After this patch:

         lock
           |
       tx stream
           |
         enable
           |
        unlock
       --------               ---------
                                lock
                                  |
                              rx stream
                                  |
                               disable
                                  |
                                reset
                                  |
                               unlock

Signed-off-by: Sugar Zhang <sugar.zhang at rock-chips.com>
---

Changes in v2:
- Fix compile error.

 sound/soc/rockchip/rockchip_i2s.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index c7dc350..88e340f 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
+#include <linux/spinlock.h>
 #include <sound/pcm_params.h>
 #include <sound/dmaengine_pcm.h>
 
@@ -49,6 +50,7 @@ struct rk_i2s_dev {
 	bool rx_start;
 	bool is_master_mode;
 	const struct rk_i2s_pins *pins;
+	spinlock_t lock; /* tx/rx lock */
 };
 
 static int i2s_runtime_suspend(struct device *dev)
@@ -92,6 +94,7 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
 	unsigned int val = 0;
 	int retry = 10;
 
+	spin_lock(&i2s->lock);
 	if (on) {
 		regmap_update_bits(i2s->regmap, I2S_DMACR,
 				   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
@@ -132,6 +135,7 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
 			}
 		}
 	}
+	spin_unlock(&i2s->lock);
 }
 
 static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
@@ -139,6 +143,7 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
 	unsigned int val = 0;
 	int retry = 10;
 
+	spin_lock(&i2s->lock);
 	if (on) {
 		regmap_update_bits(i2s->regmap, I2S_DMACR,
 				   I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
@@ -179,6 +184,7 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
 			}
 		}
 	}
+	spin_unlock(&i2s->lock);
 }
 
 static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
@@ -589,6 +595,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
 	if (!i2s)
 		return -ENOMEM;
 
+	spin_lock_init(&i2s->lock);
 	i2s->dev = &pdev->dev;
 
 	i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
-- 
2.7.4





From krzysztof.kozlowski at canonical.com  Sun Aug 29 23:52:04 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 30 Aug 2021 08:52:04 +0200
Subject: [PATCH v3 0/8] dt-bindings: clock: samsung: convert to dtschema
In-Reply-To: <163022098497.2676726.6455473597971395732@swboyd.mtv.corp.google.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <163022098497.2676726.6455473597971395732@swboyd.mtv.corp.google.com>
Message-ID: <7228126e-2ba8-bcba-af26-8d7ec4e33a62@canonical.com>

On 29/08/2021 09:09, Stephen Boyd wrote:
> Quoting Krzysztof Kozlowski (2021-08-25 06:40:48)
>> Hi,
>>
>> Changes since v2:
>> 1. Add reviews.
>> 2. Split Exynos4 ISP into separate schema.
>> 3. Add maxItems to clocks and power-domains (review feedback).
>> 4. Do not allow samsung,exynos5420-clock and samsung,exynos5800-clock
>>    without syscon. These clock controllers should always use syscon
>>    to allow DMC bindings access the registers.
>> 5. Drop assigned-clocks.
>>
>> Changes since v1:
>> 1. Patch 7/8: include header to fix clock IDs error in example.
> 
> I think this header file isn't in clk tree?
> 

It is in Linus' tree... full path is:
include/dt-bindings/clock/s5pv210.h

What's missing is entry in MAINTAINERS.

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sun Aug 29 23:56:47 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 30 Aug 2021 08:56:47 +0200
Subject: [PATCH] MAINTAINERS: clock: samsung: include S3C/S5P header bindings
Message-ID: <20210830065647.5386-1-krzysztof.kozlowski@canonical.com>

Include S3C24xx, S3C64xx and S5Pv210 SoC clock headers with bindings in
the Samsung SoC Clock drivers entry.  The clock drivers for these SoCs
are already covered.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index eee4c926003b..c17299c30ea7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16582,6 +16582,9 @@ F:	Documentation/devicetree/bindings/clock/samsung,s3c*
 F:	Documentation/devicetree/bindings/clock/samsung,s5p*
 F:	drivers/clk/samsung/
 F:	include/dt-bindings/clock/exynos*.h
+F:	include/dt-bindings/clock/s3c24*.h
+F:	include/dt-bindings/clock/s5pv210*.h
+F:	include/dt-bindings/clock/samsung,s3c64xx-clock.h
 F:	include/linux/clk/samsung.h
 F:	include/linux/platform_data/clk-s3c2410.h
 
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Sun Aug 29 23:59:14 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 30 Aug 2021 08:59:14 +0200
Subject: [PATCH] MAINTAINERS: clock: samsung: include S3C/S5P header
 bindings
In-Reply-To: <20210830065647.5386-1-krzysztof.kozlowski@canonical.com>
References: <20210830065647.5386-1-krzysztof.kozlowski@canonical.com>
Message-ID: <69d4b87b-74f8-8107-d4b2-19b4c28910b4@canonical.com>

On 30/08/2021 08:56, Krzysztof Kozlowski wrote:
> Include S3C24xx, S3C64xx and S5Pv210 SoC clock headers with bindings in
> the Samsung SoC Clock drivers entry.  The clock drivers for these SoCs
> are already covered.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  MAINTAINERS | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index eee4c926003b..c17299c30ea7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16582,6 +16582,9 @@ F:	Documentation/devicetree/bindings/clock/samsung,s3c*
>  F:	Documentation/devicetree/bindings/clock/samsung,s5p*
>  F:	drivers/clk/samsung/
>  F:	include/dt-bindings/clock/exynos*.h
> +F:	include/dt-bindings/clock/s3c24*.h
> +F:	include/dt-bindings/clock/s5pv210*.h
> +F:	include/dt-bindings/clock/samsung,s3c64xx-clock.h
>  F:	include/linux/clk/samsung.h
>  F:	include/linux/platform_data/clk-s3c2410.h

Ignore it, please. I just sent the same patch second time... I need more
coffee.


Best regards,
Krzysztof


From chuanjia.liu at mediatek.com  Mon Aug 30 00:09:44 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Mon, 30 Aug 2021 15:09:44 +0800
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared
 pcie-cfg base address
In-Reply-To: <20210827164634.GA3779223@bjorn-Precision-5520>
References: <20210827164634.GA3779223@bjorn-Precision-5520>
Message-ID: <968266ecd5889721aa234c414361bedbe66b9539.camel@mediatek.com>

On Fri, 2021-08-27 at 11:46 -0500, Bjorn Helgaas wrote:
> On Mon, Aug 23, 2021 at 11:27:56AM +0800, Chuanjia Liu wrote:
> > For the new dts format, add a new method to get
> > shared pcie-cfg base address and use it to configure
> > the PCIECFG controller
> 
> Rewrap this to fill 75 columns.
> 
> > Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> > Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> > ---
> >  drivers/pci/controller/pcie-mediatek.c | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pcie-mediatek.c
> > b/drivers/pci/controller/pcie-mediatek.c
> > index 25bee693834f..4296d9e04240 100644
> > --- a/drivers/pci/controller/pcie-mediatek.c
> > +++ b/drivers/pci/controller/pcie-mediatek.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/irqchip/chained_irq.h>
> >  #include <linux/irqdomain.h>
> >  #include <linux/kernel.h>
> > +#include <linux/mfd/syscon.h>
> >  #include <linux/msi.h>
> >  #include <linux/module.h>
> >  #include <linux/of_address.h>
> > @@ -23,6 +24,7 @@
> >  #include <linux/phy/phy.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_runtime.h>
> > +#include <linux/regmap.h>
> >  #include <linux/reset.h>
> >  
> >  #include "../pci.h"
> > @@ -207,6 +209,7 @@ struct mtk_pcie_port {
> >   * struct mtk_pcie - PCIe host information
> >   * @dev: pointer to PCIe device
> >   * @base: IO mapped register base
> > + * @cfg: IO mapped register map for PCIe config
> >   * @free_ck: free-run reference clock
> >   * @mem: non-prefetchable memory resource
> >   * @ports: pointer to PCIe port information
> > @@ -215,6 +218,7 @@ struct mtk_pcie_port {
> >  struct mtk_pcie {
> >  	struct device *dev;
> >  	void __iomem *base;
> > +	struct regmap *cfg;
> >  	struct clk *free_ck;
> >  
> >  	struct list_head ports;
> > @@ -682,6 +686,10 @@ static int mtk_pcie_startup_port_v2(struct
> > mtk_pcie_port *port)
> >  		val |= PCIE_CSR_LTSSM_EN(port->slot) |
> >  		       PCIE_CSR_ASPM_L1_EN(port->slot);
> >  		writel(val, pcie->base + PCIE_SYS_CFG_V2);
> > +	} else if (pcie->cfg) {
> > +		val = PCIE_CSR_LTSSM_EN(port->slot) |
> > +		      PCIE_CSR_ASPM_L1_EN(port->slot);
> > +		regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val,
> > val);
> >  	}
> >  
> >  	/* Assert all reset signals */
> > @@ -985,6 +993,7 @@ static int mtk_pcie_subsys_powerup(struct
> > mtk_pcie *pcie)
> >  	struct device *dev = pcie->dev;
> >  	struct platform_device *pdev = to_platform_device(dev);
> >  	struct resource *regs;
> > +	struct device_node *cfg_node;
> >  	int err;
> >  
> >  	/* get shared registers, which are optional */
> > @@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct
> > mtk_pcie *pcie)
> >  			return PTR_ERR(pcie->base);
> >  	}
> >  
> > +	cfg_node = of_find_compatible_node(NULL, NULL,
> > +					   "mediatek,generic-pciecfg");
> 
> This looks wrong to me.  IIUC, since we start at NULL, this searches
> the entire device tree for any node with
> 
>   compatible = "mediatek,generic-pciecfg"
> 
> but we should only care about the specific device/node this driver
> claimed.
> 
> Should this be part of the match data, i.e., struct mtk_pcie_soc?
Hi Bjorn,

Thanks for your review.

Many drivers in the drivers/ folder use compatible to search directly.
 
I guess that when different devices need to search for different nodes,
it is necessary to use match data to determine the current node 
information that needs to be searched.

But in the devices supported by this driver, I guess it no need 
through match data to confirm the compatible information?because it 
always search same compatible "mediatek, generic-pciecfg"

> 
> > +	if (cfg_node) {
> > +		pcie->cfg = syscon_node_to_regmap(cfg_node);
> 
> Other drivers in drivers/pci/controller/ use
> syscon_regmap_lookup_by_phandle() (j721e, dra7xx, keystone,
> layerscape, artpec6) or syscon_regmap_lookup_by_compatible() (imx6,
> kirin, v3-semi).
> 
> You should do it the same way unless there's a need to be different.
I have used phandle, but Rob suggested to search for the node by 
compatible. The reason why syscon_regmap_lookup_by_compatible() is not 
used here is that the pciecfg node is optional, and there is no need to
return error when the node is not searched.

> It's also nice if you can use the same struct member name
> ("mtk_pcie.cfg") as other drivers.  They're not all consistent, but I
> don't see any other "cfg".
Other drivers struct member name are also different.
For example, scfg(layerscape)?map(v3-semi), crgctrl(kirin),
regmap(artpec6).Or just use local variables, named syscon or regmap.
So I couldn't be consistent with other drivers.

Thanks
Chuanjia
> 
> > +		if (IS_ERR(pcie->cfg))
> > +			return PTR_ERR(pcie->cfg);
> > +	}
> > +
> >  	pcie->free_ck = devm_clk_get(dev, "free_ck");
> >  	if (IS_ERR(pcie->free_ck)) {
> >  		if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
> > -- 
> > 2.18.0
> > 

From narmstrong at baylibre.com  Mon Aug 30 00:38:27 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 30 Aug 2021 09:38:27 +0200
Subject: [PATCH] soc: amlogic: meson-gx-socinfo: Add S905Y2 ID for Radxa
 Zero
In-Reply-To: <20210820012718.10761-1-christianshewitt@gmail.com>
References: <20210820012718.10761-1-christianshewitt@gmail.com>
Message-ID: <2fa65900-ece6-fa13-4bfb-dcc95c56e6ef@baylibre.com>

On 20/08/2021 03:27, Christian Hewitt wrote:
> Add the SOC ID for the S905Y2 used in the Radxa Zero. Before/After:
> 
> [    0.321650] soc soc0: Amlogic Meson G12A (Unknown) Revision 28:b (30:2) Detected
> [    0.318533] soc soc0: Amlogic Meson G12A (S905Y2) Revision 28:b (30:2) Detected
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  drivers/soc/amlogic/meson-gx-socinfo.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c
> index 6f54bd832c8b..165f7548401b 100644
> --- a/drivers/soc/amlogic/meson-gx-socinfo.c
> +++ b/drivers/soc/amlogic/meson-gx-socinfo.c
> @@ -65,6 +65,7 @@ static const struct meson_gx_package_id {
>  	{ "A113X", 0x25, 0x37, 0xff },
>  	{ "A113D", 0x25, 0x22, 0xff },
>  	{ "S905D2", 0x28, 0x10, 0xf0 },
> +	{ "S905Y2", 0x28, 0x30, 0xf0 },
>  	{ "S905X2", 0x28, 0x40, 0xf0 },
>  	{ "A311D", 0x29, 0x10, 0xf0 },
>  	{ "S922X", 0x29, 0x40, 0xf0 },
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From cuibixuan at huawei.com  Mon Aug 30 00:38:58 2021
From: cuibixuan at huawei.com (Bixuan Cui)
Date: Mon, 30 Aug 2021 15:38:58 +0800
Subject: [PATCH -next v4 2/2] iommu/arm-smmu-v3: Add suspend and resume support
In-Reply-To: <20210830073858.47084-1-cuibixuan@huawei.com>
References: <20210830073858.47084-1-cuibixuan@huawei.com>
Message-ID: <20210830073858.47084-2-cuibixuan@huawei.com>

Add suspend and resume support for arm-smmu-v3 by low-power mode.

When the smmu is suspended, it is powered off and the registers are
cleared. So saves the msi_msg context during msi interrupt initialization
of smmu. When resume happens it calls arm_smmu_device_reset() to restore
the registers.

Signed-off-by: Bixuan Cui <cuibixuan at huawei.com>
Reviewed-by: Wei Yongjun <weiyongjun1 at huawei.com>
Reviewed-by: Zhen Lei <thunder.leizhen at huawei.com>
Reviewed-by: Ding Tianhong <dingtianhong at huawei.com>
Reviewed-by: Hanjun Guo <guohanjun at huawei.com>
---
Changes in v4:
* Restore the arm_smmu_suspend() function code to the v2 version(Directly return 0 in it).

Changes in v3:
* Move the code of save msg context into msi platform (A new patch: "platform-msi: Save the msg context to desc in platform_msi_write_msg()").

* Add bypass member to the struct arm_smmu_device for per-SMMU bypass control(used by resume mode).

* Separate interrupt requests and register operations in arm_smmu_device_reset(). The arm_smmu_setup_irqs() is added to request interrupts and is called before arm_smmu_device_reset(). The arm_smmu_device_reset() resets irq registers (can also be called in resume mode).

Changes in v2:
* Using get_cached_msi_msg() instead of the descriptor to resume msi_msg
  in arm_smmu_resume_msis();

* Move arm_smmu_resume_msis() from arm_smmu_setup_unique_irqs() into
  arm_smmu_setup_irqs() and rename it to arm_smmu_resume_unique_irqs();

  Call arm_smmu_setup_unique_irqs() to configure the IRQ during probe and
  call arm_smmu_resume_unique_irqs() in resume mode to restore the IRQ
  registers to make the code more reasonable.

* Call arm_smmu_device_disable() to disable smmu and clear CR0_SMMUEN on
  suspend. Then the warning about CR0_SMMUEN being enabled can be cleared
  on resume.

* Using SET_SYSTEM_SLEEP_PM_OPS();
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 94 +++++++++++++++++++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 +
 2 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index a388e318f86e..af6752a735bb 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3282,6 +3282,61 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 	return 0;
 }
 
+static void arm_smmu_reset_unique_irqs(struct arm_smmu_device *smmu)
+{
+	struct msi_desc *desc;
+	struct msi_msg msg;
+
+	desc = irq_get_msi_desc(smmu->evtq.q.irq);
+	if (desc) {
+		get_cached_msi_msg(smmu->evtq.q.irq, &msg);
+		arm_smmu_write_msi_msg(desc, &msg);
+	}
+
+	desc = irq_get_msi_desc(smmu->gerr_irq);
+	if (desc) {
+		get_cached_msi_msg(smmu->gerr_irq, &msg);
+		arm_smmu_write_msi_msg(desc, &msg);
+	}
+
+	if (smmu->features & ARM_SMMU_FEAT_PRI) {
+		desc = irq_get_msi_desc(smmu->priq.q.irq);
+		if (desc) {
+			get_cached_msi_msg(smmu->priq.q.irq, &msg);
+			arm_smmu_write_msi_msg(desc, &msg);
+		}
+	}
+}
+
+static int arm_smmu_reset_irqs(struct arm_smmu_device *smmu)
+{
+	int ret, irq;
+	u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN;
+
+	/* Disable IRQs first */
+	ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL,
+				      ARM_SMMU_IRQ_CTRLACK);
+	if (ret) {
+		dev_err(smmu->dev, "failed to disable irqs\n");
+		return ret;
+	}
+
+	irq = smmu->combined_irq;
+	if (!irq)
+		arm_smmu_reset_unique_irqs(smmu);
+
+	if (smmu->features & ARM_SMMU_FEAT_PRI)
+		irqen_flags |= IRQ_CTRL_PRIQ_IRQEN;
+
+	/* Enable interrupt generation on the SMMU */
+	ret = arm_smmu_write_reg_sync(smmu, irqen_flags,
+				      ARM_SMMU_IRQ_CTRL, ARM_SMMU_IRQ_CTRLACK);
+	if (ret)
+		dev_warn(smmu->dev, "failed to reset irqs\n");
+
+	return 0;
+}
+
 static int arm_smmu_device_disable(struct arm_smmu_device *smmu)
 {
 	int ret;
@@ -3293,7 +3348,7 @@ static int arm_smmu_device_disable(struct arm_smmu_device *smmu)
 	return ret;
 }
 
-static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
+static int arm_smmu_device_reset(struct arm_smmu_device *smmu)
 {
 	int ret;
 	u32 reg, enables;
@@ -3401,9 +3456,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 		}
 	}
 
-	ret = arm_smmu_setup_irqs(smmu);
+	ret = arm_smmu_reset_irqs(smmu);
 	if (ret) {
-		dev_err(smmu->dev, "failed to setup irqs\n");
+		dev_err(smmu->dev, "failed to reset irqs\n");
 		return ret;
 	}
 
@@ -3411,7 +3466,7 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 		enables &= ~(CR0_EVTQEN | CR0_PRIQEN);
 
 	/* Enable the SMMU interface, or ensure bypass */
-	if (!bypass || disable_bypass) {
+	if (!smmu->bypass || disable_bypass) {
 		enables |= CR0_SMMUEN;
 	} else {
 		ret = arm_smmu_update_gbpa(smmu, 0, GBPA_ABORT);
@@ -3758,6 +3813,20 @@ static void __iomem *arm_smmu_ioremap(struct device *dev, resource_size_t start,
 	return devm_ioremap_resource(dev, &res);
 }
 
+static int __maybe_unused arm_smmu_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused arm_smmu_resume(struct device *dev)
+{
+	struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+	arm_smmu_device_reset(smmu);
+
+	return 0;
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
 	int irq, ret;
@@ -3765,7 +3834,6 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	resource_size_t ioaddr;
 	struct arm_smmu_device *smmu;
 	struct device *dev = &pdev->dev;
-	bool bypass;
 
 	smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
 	if (!smmu)
@@ -3781,7 +3849,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	}
 
 	/* Set bypass mode according to firmware probing result */
-	bypass = !!ret;
+	smmu->bypass = !!ret;
 
 	/* Base address */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -3839,8 +3907,15 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Record our private device structure */
 	platform_set_drvdata(pdev, smmu);
 
+	/* Setup irqs */
+	ret = arm_smmu_setup_irqs(smmu);
+	if (ret) {
+		dev_err(smmu->dev, "failed to setup irqs\n");
+		return ret;
+	}
+
 	/* Reset the device */
-	ret = arm_smmu_device_reset(smmu, bypass);
+	ret = arm_smmu_device_reset(smmu);
 	if (ret)
 		return ret;
 
@@ -3893,6 +3968,10 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static const struct dev_pm_ops arm_smmu_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(arm_smmu_suspend, arm_smmu_resume)
+};
+
 static void arm_smmu_driver_unregister(struct platform_driver *drv)
 {
 	arm_smmu_sva_notifier_synchronize();
@@ -3904,6 +3983,7 @@ static struct platform_driver arm_smmu_driver = {
 		.name			= "arm-smmu-v3",
 		.of_match_table		= arm_smmu_of_match,
 		.suppress_bind_attrs	= true,
+		.pm			= &arm_smmu_pm_ops,
 	},
 	.probe	= arm_smmu_device_probe,
 	.remove	= arm_smmu_device_remove,
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 4cb136f07914..7777a7445bc2 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -675,6 +675,7 @@ struct arm_smmu_device {
 
 	struct rb_root			streams;
 	struct mutex			streams_mutex;
+	bool				bypass;
 };
 
 struct arm_smmu_stream {
-- 
2.17.1



From cuibixuan at huawei.com  Mon Aug 30 00:38:57 2021
From: cuibixuan at huawei.com (Bixuan Cui)
Date: Mon, 30 Aug 2021 15:38:57 +0800
Subject: [PATCH -next v4 1/2] platform-msi: Save the msg context to desc in
 platform_msi_write_msg()
Message-ID: <20210830073858.47084-1-cuibixuan@huawei.com>

Save the msg context to desc when when the msi interrupt is requested.
The drivers can use it in special scenarios(such as resume).

Signed-off-by: Bixuan Cui <cuibixuan at huawei.com>
---
 drivers/base/platform-msi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index 3d6c8f9caf43..60962a224fcc 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -90,6 +90,9 @@ static void platform_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
 
 	priv_data = desc->platform.msi_priv_data;
 
+	desc->msg.address_lo = msg->address_lo;
+	desc->msg.address_hi = msg->address_hi;
+	desc->msg.data = msg->data;
 	priv_data->write_msg(desc, msg);
 }
 
-- 
2.17.1



From narmstrong at baylibre.com  Mon Aug 30 00:45:26 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 30 Aug 2021 09:45:26 +0200
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <20210817041548.1276-2-linux.amoon@gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
Message-ID: <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>

Hi,

On 17/08/2021 06:15, Anand Moon wrote:
> Add missing usb phy power node for usb node fix below warning.
> P5V0 regulator supply input voltage range to USB host controller.
> As described in the C1+ schematics, GPIO GPIOAO_5 is used to
> enable input power to USB ports, set it to Active Low.
> 
> [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
> [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
> 		mode /soc/usb at c90c0000 failed

First of all, DT is not here to fix boot message.

Secondly, if the vbus-supply is optional, the message should be removed from
the driver/regulator core instead.

Finally, I looked at the Odroid-C1 schematics and the GPIOAO.BIT5 is an input
to the S805, and the PWREN signal is controlled by the USB Hub so this regulator
should not be added at all.

Neil

> 
> Fixes: 2eb79a4d15ff (ARM: dts: meson: enabling the USB Host
> 		controller on Odroid-C1/C1+ board)
> 
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Signed-off-by: Anand Moon <linux.amoon at gmail.com>
> ---
> V2 > changes gpio polarity ACTIVE_HIGH to ACTIVE_LOW.
>      Fix the source power from phy-supply to vbus-supply.
> 
> [1] https://lore.kernel.org/linux-devicetree/20210716103651.1455-2-linux.amoon at gmail.com/
> 
> V1 > Fix the Input GPIO polarity from HIGH to LOW.
> 
> previous version
> [0] https://patchwork.kernel.org/project/linux-amlogic/patch/20190113181808.5768-1-linux.amoon at gmail.com
> 
> changes fix the vbus-suppy to phy-supply, drop enable usb0
> 
>     USB_PWR                       2    1      0 unknown  5000mV     0mA  5000mV  5000mV
>        phy-c1108820.phy.0-phy     2                                 0mA     0mV     0mV
> ---
>  arch/arm/boot/dts/meson8b-odroidc1.dts | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/meson8b-odroidc1.dts b/arch/arm/boot/dts/meson8b-odroidc1.dts
> index c440ef94e082..30ec6a7f20c7 100644
> --- a/arch/arm/boot/dts/meson8b-odroidc1.dts
> +++ b/arch/arm/boot/dts/meson8b-odroidc1.dts
> @@ -32,6 +32,23 @@ emmc_pwrseq: emmc-pwrseq {
>  		reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
>  	};
>  
> +	usb_pwr_en: regulator-usb-pwr-en {
> +		compatible = "regulator-fixed";
> +
> +		regulator-name = "USB_OTG_PWR";
> +
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		/*
> +		 * signal name from schematics: USB_POWER - P5V0
> +		 */
> +		vin-supply = <&p5v0>;
> +		/*
> +		 * signal name from schematics: PWREN - GPIOAO.BIT5
> +		 */
> +		gpios = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_LOW>;
> +	};
> +
>  	leds {
>  		compatible = "gpio-leds";
>  		blue {
> @@ -119,7 +136,6 @@ vcc_3v3: regulator-vcc-3v3 {
>  		regulator-name = "VCC3V3";
>  		regulator-min-microvolt = <3300000>;
>  		regulator-max-microvolt = <3300000>;
> -
>  		vin-supply = <&p5v0>;

As martin said, only a single functional change per patch please, this line removal should go in another patch.

>  	};
>  
> @@ -382,4 +398,5 @@ &usb1_phy {
>  
>  &usb1 {
>  	status = "okay";
> +	vbus-supply = <&usb_pwr_en>;
>  };
> 



From cuibixuan at huawei.com  Mon Aug 30 00:57:08 2021
From: cuibixuan at huawei.com (Bixuan Cui)
Date: Mon, 30 Aug 2021 15:57:08 +0800
Subject: [PATCH -next v4 2/2] iommu/arm-smmu-v3: Add suspend and resume
 support
In-Reply-To: <20210830073858.47084-2-cuibixuan@huawei.com>
References: <20210830073858.47084-1-cuibixuan@huawei.com>
 <20210830073858.47084-2-cuibixuan@huawei.com>
Message-ID: <7087f98c-a59e-00a3-2eae-958c25c1ac3c@huawei.com>



On 2021/8/30 15:38, Bixuan Cui wrote:
> Changes in v4:
> * Restore the arm_smmu_suspend() function code to the v2 version(Directly return 0 in it).
Hello,
I looked up the code of smmu.c and the manual of smmu v3. For the suspend is implemented
by the external clock-gating, it is not clear what the SMMUv3 needs to do. Is it the same
as that in smmu.c?
I roll back the code here, and hope to get some advice.

Thanks,
Bixuan Cui


From michael.riesch at wolfvision.net  Mon Aug 30 00:57:51 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 30 Aug 2021 09:57:51 +0200
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <CAGb2v67Duk_56fOKVwZsYn2HKJ99o8WJ+d4jetD2UjDsAt9BcA@mail.gmail.com>
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
 <CAGb2v67Duk_56fOKVwZsYn2HKJ99o8WJ+d4jetD2UjDsAt9BcA@mail.gmail.com>
Message-ID: <568a0825-ed65-58d7-9c9c-cecb481cf9d9@wolfvision.net>

Hi ChenYu,

On 8/29/21 7:48 PM, Chen-Yu Tsai wrote:
> Hi,
> 
> On Mon, Aug 23, 2021 at 10:39 PM Michael Riesch
> <michael.riesch at wolfvision.net> wrote:
>>
>> This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
>> "net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
>> unbalanced pm_runtime_enable warnings.
>>
>> In the commit to be reverted, support for power management was
>> introduced to the Rockchip glue code. Later, power management support
>> was introduced to the stmmac core code, resulting in multiple
>> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
>>
>> The multiple invocations happen in rk_gmac_powerup and
>> stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
>> stmmac_{dvr_remove, suspend}, respectively, which are always called
>> in conjunction.
>>
>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> 
> I just found that Ethernet stopped working on my RK3399 devices,
> and I bisected it down to this patch.

Oh dear. First patch in a kernel release for a while and I already break
things.

Cc: Sasha as this patch has just been applied to 5.13-stable.

> The symptom I see is no DHCP responses, either because the request
> isn't getting sent over the wire, or the response isn't getting
> received. The PHY seems to be working correctly.

Unfortunately I don't have any RK3399 hardware. Is this a custom
board/special hardware or something that is readily available in the
shops? Maybe this is a good reason to buy a RK3399 based single-board
computer :-)

I am working on the RK3568 EVB1 and have not encountered faulty
behavior. DHCP works fine and I can boot via NFS. Therefore, not sure
whether I can be much of help in this matter, but in case you want to
discuss this further please do not hesitate to contact me off-list.

> ChenYu

Best regards,
Michael


From moudy.ho at mediatek.com  Mon Aug 30 00:58:34 2021
From: moudy.ho at mediatek.com (moudy ho)
Date: Mon, 30 Aug 2021 15:58:34 +0800
Subject: [PATCH v7 3/5] dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
In-Reply-To: <YSU0TrfFCsaI1TqV@robh.at.kernel.org>
References: <20210824100027.25989-1-moudy.ho@mediatek.com>
 <20210824100027.25989-4-moudy.ho@mediatek.com>
 <YSU0TrfFCsaI1TqV@robh.at.kernel.org>
Message-ID: <0092244acd520acac81208b8863b15fba58f4193.camel@mediatek.com>

On Tue, 2021-08-24 at 13:02 -0500, Rob Herring wrote:
> On Tue, Aug 24, 2021 at 06:00:25PM +0800, Moudy Ho wrote:
> > This patch adds DT binding document for Media Data Path 3 (MDP3)
> > a unit in multimedia system used for scaling and color format
> > convert.
> > 
> > Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> > ---
> >  .../bindings/media/mediatek,mdp3-ccorr.yaml   |  57 +++++
> >  .../bindings/media/mediatek,mdp3-rdma.yaml    | 207
> > ++++++++++++++++++
> >  .../bindings/media/mediatek,mdp3-rsz.yaml     |  65 ++++++
> >  .../bindings/media/mediatek,mdp3-wdma.yaml    |  71 ++++++
> >  .../bindings/media/mediatek,mdp3-wrot.yaml    |  71 ++++++
> >  5 files changed, 471 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > ccorr.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > ccorr.yaml
> > new file mode 100644
> > index 000000000000..59fd68b46022
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > ccorr.yaml
> > @@ -0,0 +1,57 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: 
> > https://urldefense.com/v3/__http://devicetree.org/schemas/media/mediatek,mdp3-ccorr.yaml*__;Iw!!CTRNKA9wMg0ARbw!1C0ChLqzi7Zq8D2d4_S4IqCEei4GXdgy3_VCQg8MdsJP7n8TlxbGyajipusfH8hi$
> >  
> > +$schema: 
> > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!1C0ChLqzi7Zq8D2d4_S4IqCEei4GXdgy3_VCQg8MdsJP7n8TlxbGyajipi-OInix$
> >  
> > +
> > +title: Mediatek Media Data Path 3 CCORR Device Tree Bindings
> > +
> > +maintainers:
> > +  - Daoyuan Huang <daoyuan.huang at mediatek.com>
> > +  - Moudy Ho <moudy.ho at mediatek.com>
> > +
> > +description: |
> > +  One of Media Data Path 3 (MDP3) components used to do color
> > correction with 3X3 matrix.
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - enum:
> > +        - mediatek,mt8183-mdp3-ccorr
> > +
> > +  mediatek,mdp3-id:
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    maxItems: 1
> > +    description: |
> > +      HW index to distinguish same functionality modules.
> 
> If we wanted h/w indexes in DT, we'd have a standard property. Why
> do 
> you need this?
> 
I'm sorry not quite sure what HW indexes means (something like
aliases?)

It was originally used to mark multiple identical modules in the MDP
data path algorithm, so that appropriate paths can be dynamically
dispatched.
> > +
> > +  reg:
> > +    description: |
> > +      Physical base address and length of the function block
> > +      register space, the number aligns with the component
> > +      and its own subcomponent.
> 
> Drop and add 'maxItems: 1'
> 
> > +
> > +  mediatek,gce-client-reg:
> > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > +    description: |
> > +      sub-system id corresponding to the global command engine
> > (GCE)
> 
> You mean 'phandle to GCE and sub-system id'?
Yes.

> 
> > +      register address.
> > +      $ref: /schemas/mailbox/mtk-gce.txt
> 
> Kind of looks like jsonschema but in the description and to a .txt 
> file...
> 
> > +
> > +  clocks:
> > +    minItems: 1
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/mt8183-clk.h>
> > +    #include <dt-bindings/gce/mt8183-gce.h>
> > +
> > +    mdp3_ccorr: mdp3_ccorr at 1401c000 {
> > +      compatible = "mediatek,mt8183-mdp3-ccorr";
> > +      mediatek,mdp3-id = <0>;
> > +      reg = <0x1401c000 0x1000>;
> > +      mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000
> > 0x1000>;
> > +      clocks = <&mmsys CLK_MM_MDP_CCORR>;
> > +    };
> > diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > rdma.yaml
> > new file mode 100644
> > index 000000000000..b355d7fe791e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > rdma.yaml
> > @@ -0,0 +1,207 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: 
> > https://urldefense.com/v3/__http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml*__;Iw!!CTRNKA9wMg0ARbw!1C0ChLqzi7Zq8D2d4_S4IqCEei4GXdgy3_VCQg8MdsJP7n8TlxbGyajips2k1HT2$
> >  
> > +$schema: 
> > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!1C0ChLqzi7Zq8D2d4_S4IqCEei4GXdgy3_VCQg8MdsJP7n8TlxbGyajipi-OInix$
> >  
> > +
> > +title: Mediatek Media Data Path 3 Device Tree Bindings
> > +
> > +maintainers:
> > +  - Daoyuan Huang <daoyuan.huang at mediatek.com>
> > +  - Moudy Ho <moudy.ho at mediatek.com>
> > +
> > +description: |
> > +  One of Media Data Path 3 (MDP3) components used to do read DMA.
> > +  RDMA0 is also used to be a controller node containing MMSYS,
> > +  MUTEX, GCE and SCP settings.
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - items:
> > +        - enum:
> 
> Should be indented 2 more spaces. Install yamllint and check with
> 'make 
> dt_binding_check'.
> 
> > +          # controller node
> > +          - mediatek,mt8183-mdp3
> 
> And then 2 more here.
> 
> > +        - enum:
> > +          - mediatek,mt8183-mdp3-rdma
> > +
> > +      - items:
> > +        - enum:
> > +          # read DMA
> > +          - mediatek,mt8183-mdp3-rdma
> > +
> > +  mediatek,scp:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    maxItems: 1
> > +    description: |
> > +      The node of system control processor (SCP), using
> > +      the remoteproc & rpmsg framework.
> > +      $ref: /schemas/remoteproc/mtk,scp.yaml
> > +
> > +  mediatek,mdp3-id:
> > +    $ref: /schemas/types.yaml#/definitions/uint32
> > +    maxItems: 1
> > +    description: |
> > +      In MDP3, it can allocate multiple identical modules for
> > +      different data path selection or multi-pipeline execution.
> > +      This node is used to indicate the ID of each module.
> > +
> > +  mdp3-comps:
> > +    $ref: /schemas/types.yaml#/definitions/string-array
> > +    items:
> > +        - enum:
> 
> And this is 2 too many spaces...
> 
> > +          # MDP direct-link input path selection, create a
> > +          # component for path connectedness of HW pipe control
> > +          - mediatek,mt8183-mdp3-dl1
> > +        - enum:
> > +          - mediatek,mt8183-mdp3-dl2
> > +        - enum:
> > +          # MDP direct-link output path selection, create a
> > +          # component for path connectedness of HW pipe control
> > +          - mediatek,mt8183-mdp3-path1
> > +        - enum:
> > +          - mediatek,mt8183-mdp3-path2
> > +        - enum:
> > +          # Input DMA of ISP PASS2 (DIP) module for raw image
> > input
> > +          - mediatek,mt8183-mdp3-imgi
> > +        - enum:
> > +          # Output DMA of ISP PASS2 (DIP) module for YUV image
> > output
> > +          - mediatek,mt8183-mdp3-exto
> > +
> > +  mdp3-comp-ids:
> > +    maxItems: 1
> > +    $ref: /schemas/types.yaml#/definitions/uint32-array
> 
> If only a single item, then it's a 'uint32' not an array.
Only one in other module, but multiple in RDMA0 for subcomponents.
> 
> > +    description: |
> > +      Pipeline ID of MDP direct-link or DIP.
> > +
> > +  reg:
> > +    description: |
> > +      Physical base address and length of the function block
> > +      register space, the number aligns with the component
> > +      and its own subcomponent.
> > +
> > +  mediatek,gce-client-reg:
> > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > +    description: |
> > +      sub-system id corresponding to the global command engine
> > (GCE)
> > +      register address.
> > +      $ref: /schemas/mailbox/mtk-gce.txt
> > +
> > +  power-domains:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    minItems: 1
> > +    maxItems: 6
> 
> Need to define what they are.
> 
> > +
> > +  iommus:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> 
> iommus already has a type definition.
> 
> > +    description: |
> > +      Should point to the respective IOMMU block with master
> > +      port as argument.
> > +      $ref: /schemas/iommu/mediatek,iommu.yaml
> 
> No. Drop (the whole description because you don't need generic 
> descriptions for common properties).
> 
> What's needed is how many entries (maxItems: 1).
> 
> > +
> > +  mediatek,mmsys:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    maxItems: 1
> > +    description: |
> > +      The node of mux(multiplexer) controller for HW connections.
> > +
> > +  mediatek,mm-mutex:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    maxItems: 1
> > +    description: |
> > +      The node of sof(start of frame) signal controller.
> > +
> > +  mediatek,mailbox-gce:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description: |
> > +      The node of global command engine (GCE), used to read/write
> > +      registers with critical time limitation.
> > +      $ref: /schemas/mailbox/mtk-gce.txt
> > +
> > +  mboxes:
> > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > +    description: |
> > +      $ref: /schemas/mailbox/mailbox.txt
> > +
> > +  gce-subsys:
> > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > +    description: |
> > +      sub-system id corresponding to the global command engine
> > (GCE)
> > +      register address.
> > +      $ref: /schemas/mailbox/mtk-gce.txt
> > +
> > +if:
> > +  properties:
> > +    compatible:
> > +      items:
> > +        - enum:
> > +          - mediatek,mt8183-mdp3
> > +        - enum:
> > +          - mediatek,mt8183-mdp3-rdma
> 
> Normally, you want to use 'contains' for if/then schemas:
> 
> compatible:
>   contains:
>     const: mediatek,mt8183-mdp3
> 
> > +
> > +then:
> > +  required:
> > +    - mediatek,scp
> > +    - mediatek,mmsys
> > +    - mediatek,mm-mutex
> > +    - mediatek,mailbox-gce
> > +    - mboxes
> > +    - gce-subsys
> > +
> > +required:
> > +  - compatible
> > +  - mediatek,mdp3-id
> > +  - reg
> > +  - clocks
> > +  - mediatek,gce-client-reg
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/mt8183-clk.h>
> > +    #include <dt-bindings/gce/mt8183-gce.h>
> > +    #include <dt-bindings/power/mt8183-power.h>
> > +    #include <dt-bindings/memory/mt8183-larb-port.h>
> > +
> > +    mdp3_rdma0: mdp3_rdma0 at 14001000 {
> > +      compatible = "mediatek,mt8183-mdp3",
> > +                   "mediatek,mt8183-mdp3-rdma";
> > +      mediatek,scp = <&scp>;
> > +      mediatek,mdp3-id = <0>;
> > +      mdp3-comps = "mediatek,mt8183-mdp3-dl1", "mediatek,mt8183-
> > mdp3-dl2",
> > +                   "mediatek,mt8183-mdp3-path1", "mediatek,mt8183-
> > mdp3-path2",
> > +                   "mediatek,mt8183-mdp3-imgi", "mediatek,mt8183-
> > mdp3-exto";
> > +      mdp3-comp-ids = <0 1 0 1 0 1>;
> > +      reg = <0x14001000 0x1000>,
> > +            <0x14000000 0x1000>,
> > +            <0x14005000 0x1000>,
> > +            <0x14006000 0x1000>,
> > +            <0x15020000 0x1000>;
> > +      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000
> > 0x1000>,
> > +                                <&gce SUBSYS_1400XXXX 0 0x1000>,
> > +                                <&gce SUBSYS_1400XXXX 0x5000
> > 0x1000>,
> > +                                <&gce SUBSYS_1400XXXX 0x6000
> > 0x1000>,
> > +                                <&gce SUBSYS_1502XXXX 0 0x1000>;
> > +      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> > +      clocks = <&mmsys CLK_MM_MDP_RDMA0>,
> > +               <&mmsys CLK_MM_MDP_RSZ1>,
> > +               <&mmsys CLK_MM_MDP_DL_TXCK>,
> > +               <&mmsys CLK_MM_MDP_DL_RX>,
> > +               <&mmsys CLK_MM_IPU_DL_TXCK>,
> > +               <&mmsys CLK_MM_IPU_DL_RX>;
> > +      iommus = <&iommu>;
> > +      mediatek,mmsys = <&mmsys>;
> > +      mediatek,mm-mutex = <&mutex>;
> > +      mediatek,mailbox-gce = <&gce>;
> > +      mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
> > +               <&gce 21 CMDQ_THR_PRIO_LOWEST 0>,
> > +               <&gce 22 CMDQ_THR_PRIO_LOWEST 0>,
> > +               <&gce 23 CMDQ_THR_PRIO_LOWEST 0>;
> > +      gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
> > +                   <&gce 0x14010000 SUBSYS_1401XXXX>,
> > +                   <&gce 0x14020000 SUBSYS_1402XXXX>,
> > +                   <&gce 0x15020000 SUBSYS_1502XXXX>;
> > +    };
> > \ No newline at end of file
> 
> Fix this.
> 
> Similar comments on the rest.
> 
> Rob

Thanks for the suggestion, the remaining will be corrected in the
further.

Moudy Ho

From baruch at tkos.co.il  Mon Aug 30 01:24:50 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 30 Aug 2021 11:24:50 +0300
Subject: [PATCH v3 1/3] PCI: dwc: tegra: move GEN3_RELATED DBI register to
 common header
In-Reply-To: <cover.1630311481.git.baruch@tkos.co.il>
References: <cover.1630311481.git.baruch@tkos.co.il>
Message-ID: <fe8d5cb8785e144e0b69c1f3adf17f3b89979ea9.1630311481.git.baruch@tkos.co.il>

These are common dwc macros that will be used for other platforms.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 drivers/pci/controller/dwc/pcie-designware.h | 6 ++++++
 drivers/pci/controller/dwc/pcie-tegra194.c   | 6 ------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 7d6e9b7576be..ea87809ee298 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -74,6 +74,12 @@
 #define PCIE_MSI_INTR0_MASK		0x82C
 #define PCIE_MSI_INTR0_STATUS		0x830
 
+#define GEN3_RELATED_OFF			0x890
+#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
+#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
+
 #define PCIE_PORT_MULTI_LANE_CTRL	0x8C0
 #define PORT_MLTI_UPCFG_SUPPORT		BIT(7)
 
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 3ec7b29d5dc7..b8be00a6406f 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -193,12 +193,6 @@
 #define GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_MASK	GENMASK(23, 8)
 #define GEN3_EQ_CONTROL_OFF_FB_MODE_MASK	GENMASK(3, 0)
 
-#define GEN3_RELATED_OFF			0x890
-#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
-#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
-#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
-#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
-
 #define PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT	0x8D0
 #define AMBA_ERROR_RESPONSE_CRS_SHIFT		3
 #define AMBA_ERROR_RESPONSE_CRS_MASK		GENMASK(1, 0)
-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 01:24:49 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 30 Aug 2021 11:24:49 +0300
Subject: [PATCH v3 0/3] arm64: IPQ6018 PCIe support
Message-ID: <cover.1630311481.git.baruch@tkos.co.il>

This series adds support for the single PCIe lane on IPQ6018 SoCs. The code is 
ported from downstream Codeaurora v5.4 kernel. The main difference from 
downstream code is the split of PCIe registers configuration from .init to 
.post_init, since it requires phy_power_on().

Tested on IPQ6010 based hardware.

Changes in v3:

  * Drop applied patches

  * Rely on generic code for speed setup

  * Drop unused macros

  * Formatting fixes

Changes in v2:

  * Add patch moving GEN3_RELATED macros to a common header

  * Drop ATU configuration from pcie-qcom

  * Remove local definition of common registers

  * Use bulk clk and reset APIs

  * Remove msi-parent from device-tree

Baruch Siach (1):
  PCI: dwc: tegra: move GEN3_RELATED DBI register to common header

Selvam Sathappan Periakaruppan (2):
  PCI: qcom: add support for IPQ60xx PCIe controller
  arm64: dts: ipq6018: Add pcie support

 arch/arm64/boot/dts/qcom/ipq6018.dtsi        | 100 +++++++++++++
 drivers/pci/controller/dwc/pcie-designware.h |   7 +
 drivers/pci/controller/dwc/pcie-qcom.c       | 141 +++++++++++++++++++
 drivers/pci/controller/dwc/pcie-tegra194.c   |   6 -
 4 files changed, 248 insertions(+), 6 deletions(-)

-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 01:24:51 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 30 Aug 2021 11:24:51 +0300
Subject: [PATCH v3 2/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <cover.1630311481.git.baruch@tkos.co.il>
References: <cover.1630311481.git.baruch@tkos.co.il>
Message-ID: <af067a193527e8d2bdbcc8b76e256eef87f6db06.1630311481.git.baruch@tkos.co.il>

From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>

IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
platform.

The code is based on downstream[1] Codeaurora kernel v5.4 (branch
win.linuxopenwrt.2.0).

Split out the DBI registers access part from .init into .post_init. DBI
registers are only accessible after phy_power_on().

[1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/

Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v3:
  * Drop speed setup; rely on generic code (Rob Herring)

  * Drop unused CLK_RATE macros (Bjorn Helgaas)

  * Minor formatting fixes (Bjorn Helgaas)

  * Add reference to downstream Codeaurora kernel tree (Bjorn Helgaas)

v2:
  * Drop ATU configuration; rely on common code instead

  * Use more common register macros

  * Use bulk clk and reset APIs
---
 drivers/pci/controller/dwc/pcie-designware.h |   1 +
 drivers/pci/controller/dwc/pcie-qcom.c       | 141 +++++++++++++++++++
 2 files changed, 142 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index ea87809ee298..279c3778a13b 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -76,6 +76,7 @@
 
 #define GEN3_RELATED_OFF			0x890
 #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
+#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
 #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 8a7a300163e5..cb53fd574621 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -52,6 +52,10 @@
 #define PCIE20_PARF_DBI_BASE_ADDR		0x168
 #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
 #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
+#define AHB_CLK_EN				BIT(0)
+#define MSTR_AXI_CLK_EN				BIT(1)
+#define BYPASS					BIT(4)
+
 #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
 #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
 #define PCIE20_PARF_LTSSM			0x1B0
@@ -168,6 +172,11 @@ struct qcom_pcie_resources_2_7_0 {
 	struct clk *pipe_clk;
 };
 
+struct qcom_pcie_resources_2_9_0 {
+	struct clk_bulk_data clks[5];
+	struct reset_control *rst;
+};
+
 union qcom_pcie_resources {
 	struct qcom_pcie_resources_1_0_0 v1_0_0;
 	struct qcom_pcie_resources_2_1_0 v2_1_0;
@@ -175,6 +184,7 @@ union qcom_pcie_resources {
 	struct qcom_pcie_resources_2_3_3 v2_3_3;
 	struct qcom_pcie_resources_2_4_0 v2_4_0;
 	struct qcom_pcie_resources_2_7_0 v2_7_0;
+	struct qcom_pcie_resources_2_9_0 v2_9_0;
 };
 
 struct qcom_pcie;
@@ -1266,6 +1276,127 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
 	clk_disable_unprepare(res->pipe_clk);
 }
 
+static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
+{
+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+	struct dw_pcie *pci = pcie->pci;
+	struct device *dev = pci->dev;
+	int ret;
+
+	res->clks[0].id = "iface";
+	res->clks[1].id = "axi_m";
+	res->clks[2].id = "axi_s";
+	res->clks[3].id = "axi_bridge";
+	res->clks[4].id = "rchng";
+
+	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+	if (ret < 0)
+		return ret;
+
+	res->rst = devm_reset_control_array_get_exclusive(dev);
+	if (IS_ERR(res->rst))
+		return PTR_ERR(res->rst);
+
+	return 0;
+}
+
+static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
+{
+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+
+	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+}
+
+static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
+{
+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+	struct device *dev = pcie->pci->dev;
+	int ret;
+
+	ret = reset_control_assert(res->rst);
+	if (ret) {
+		dev_err(dev, "reset assert failed (%d)\n", ret);
+		return ret;
+	}
+
+	usleep_range(2000, 2500);
+
+	ret = reset_control_deassert(res->rst);
+	if (ret) {
+		dev_err(dev, "reset deassert failed (%d)\n", ret);
+		return ret;
+	}
+
+	/*
+	 * Don't have a way to see if the reset has completed.
+	 * Wait for some time.
+	 */
+	usleep_range(2000, 2500);
+
+	ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+	if (ret)
+		goto err_reset;
+
+	return 0;
+
+	/*
+	 * Not checking for failure, will anyway return
+	 * the original failure in 'ret'.
+	 */
+err_reset:
+	reset_control_assert(res->rst);
+
+	return ret;
+}
+
+static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+{
+	struct dw_pcie *pci = pcie->pci;
+	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+	u32 val;
+	int i;
+
+	writel(SLV_ADDR_SPACE_SZ,
+		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
+
+	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+	val &= ~BIT(0);
+	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+
+	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+
+	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
+	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
+		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
+		| GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
+		pci->dbi_base + GEN3_RELATED_OFF);
+
+	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
+		| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
+		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
+		pcie->parf + PCIE20_PARF_SYS_CTRL);
+
+	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
+
+	dw_pcie_dbi_ro_wr_en(pci);
+	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
+
+	/* Configure PCIe link capabilities for ASPM */
+	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
+	val &= ~PCI_EXP_LNKCAP_ASPMS;
+	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
+
+	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
+			PCI_EXP_DEVCTL2);
+
+	for (i = 0; i < 256; i++)
+		writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
+				+ (4 * i));
+
+	return 0;
+}
+
 static int qcom_pcie_link_up(struct dw_pcie *pci)
 {
 	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
@@ -1456,6 +1587,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
 	.config_sid = qcom_pcie_config_sid_sm8250,
 };
 
+/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
+static const struct qcom_pcie_ops ops_2_9_0 = {
+	.get_resources = qcom_pcie_get_resources_2_9_0,
+	.init = qcom_pcie_init_2_9_0,
+	.post_init = qcom_pcie_post_init_2_9_0,
+	.deinit = qcom_pcie_deinit_2_9_0,
+	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+};
+
 static const struct dw_pcie_ops dw_pcie_ops = {
 	.link_up = qcom_pcie_link_up,
 	.start_link = qcom_pcie_start_link,
@@ -1555,6 +1695,7 @@ static const struct of_device_id qcom_pcie_match[] = {
 	{ .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },
 	{ .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 },
 	{ .compatible = "qcom,pcie-sm8250", .data = &ops_1_9_0 },
+	{ .compatible = "qcom,pcie-ipq6018", .data = &ops_2_9_0 },
 	{ }
 };
 
-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 01:24:52 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 30 Aug 2021 11:24:52 +0300
Subject: [PATCH v3 3/3] arm64: dts: ipq6018: Add pcie support
In-Reply-To: <cover.1630311481.git.baruch@tkos.co.il>
References: <cover.1630311481.git.baruch@tkos.co.il>
Message-ID: <0a6bfc7e9a94eb5c032a019299c9b2477d4d8c1d.1630311481.git.baruch@tkos.co.il>

From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>

ipq6018 has 1 pcie gen3 port. This patch adds the support for the same.

The GICv2m reg property value is a guess based on similar SoCs
description in downstream Codeaurora kernel. It appears to work.

Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
[baruch: adjust #address-cells/#size-cells; drop unsupported property;
 increase parf registers size; add 'max-link-speed']
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v3: add 'max-link-speed'

v2: remove 'msi-parent'; doesn't really work
---
 arch/arm64/boot/dts/qcom/ipq6018.dtsi | 100 ++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index ab701da582e5..aaab8d2ee189 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -384,6 +384,106 @@ intc: interrupt-controller at b000000 {
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		pcie_phy: phy at 84000 {
+			compatible = "qcom,ipq6018-qmp-pcie-phy";
+			reg = <0x0 0x84000 0x0 0x1bc>; /* Serdes PLL */
+			status = "disabled";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			clocks = <&gcc GCC_PCIE0_AUX_CLK>,
+				<&gcc GCC_PCIE0_AHB_CLK>;
+			clock-names = "aux", "cfg_ahb";
+
+			resets = <&gcc GCC_PCIE0_PHY_BCR>,
+				<&gcc GCC_PCIE0PHY_PHY_BCR>;
+			reset-names = "phy",
+				      "common";
+
+			pcie_phy0: lane at 84200 {
+				reg = <0x0 0x84200 0x0 0x16c>, /* Serdes Tx */
+				      <0x0 0x84400 0x0 0x200>, /* Serdes Rx */
+				      <0x0 0x84800 0x0 0x4f4>; /* PCS: Lane0, COM, PCIE */
+				#phy-cells = <0>;
+
+				clocks = <&gcc GCC_PCIE0_PIPE_CLK>;
+				clock-names = "pipe0";
+				clock-output-names = "gcc_pcie0_pipe_clk_src";
+				#clock-cells = <0>;
+			};
+		};
+
+		pcie0: pci at 20000000 {
+			compatible = "qcom,pcie-ipq6018";
+			reg = <0x0 0x20000000 0x0 0xf1d>,
+			      <0x0 0x20000f20 0x0 0xa8>,
+			      <0x0 0x20001000 0x0 0x1000>,
+			      <0x0 0x80000 0x0 0x4000>,
+			      <0x0 0x20100000 0x0 0x1000>;
+			reg-names = "dbi", "elbi", "atu", "parf", "config";
+
+			device_type = "pci";
+			linux,pci-domain = <0>;
+			bus-range = <0x00 0xff>;
+			num-lanes = <1>;
+			max-link-speed = <3>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			phys = <&pcie_phy0>;
+			phy-names = "pciephy";
+
+			ranges = <0x81000000 0 0x20200000 0 0x20200000
+				  0 0x10000>, /* downstream I/O */
+				 <0x82000000 0 0x20220000 0 0x20220000
+				  0 0xfde0000>; /* non-prefetchable memory */
+
+			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi";
+
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc 0 75
+					 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+					<0 0 0 2 &intc 0 78
+					 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+					<0 0 0 3 &intc 0 79
+					 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+					<0 0 0 4 &intc 0 83
+					 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+
+			clocks = <&gcc GCC_SYS_NOC_PCIE0_AXI_CLK>,
+				 <&gcc GCC_PCIE0_AXI_M_CLK>,
+				 <&gcc GCC_PCIE0_AXI_S_CLK>,
+				 <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>,
+				 <&gcc PCIE0_RCHNG_CLK>;
+			clock-names = "iface",
+				      "axi_m",
+				      "axi_s",
+				      "axi_bridge",
+				      "rchng";
+
+			resets = <&gcc GCC_PCIE0_PIPE_ARES>,
+				 <&gcc GCC_PCIE0_SLEEP_ARES>,
+				 <&gcc GCC_PCIE0_CORE_STICKY_ARES>,
+				 <&gcc GCC_PCIE0_AXI_MASTER_ARES>,
+				 <&gcc GCC_PCIE0_AXI_SLAVE_ARES>,
+				 <&gcc GCC_PCIE0_AHB_ARES>,
+				 <&gcc GCC_PCIE0_AXI_MASTER_STICKY_ARES>,
+				 <&gcc GCC_PCIE0_AXI_SLAVE_STICKY_ARES>;
+			reset-names = "pipe",
+				      "sleep",
+				      "sticky",
+				      "axi_m",
+				      "axi_s",
+				      "ahb",
+				      "axi_m_sticky",
+				      "axi_s_sticky";
+
+			status = "disabled";
+		};
+
 		watchdog at b017000 {
 			compatible = "qcom,kpss-wdt";
 			interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
-- 
2.33.0



From billy_tsai at aspeedtech.com  Mon Aug 30 01:35:53 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Mon, 30 Aug 2021 08:35:53 +0000
Subject: [RESEND v4 12/15] iio: adc: aspeed: Add func to set sampling rate.
In-Reply-To: <20210829163659.2f7f5974@jic23-huawei>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <202108250003.17P03KRU092474@twspam01.aspeedtech.com>
 <20210829163659.2f7f5974@jic23-huawei>
Message-ID: <FE947284-E67B-49DB-B538-3ECAD8317BD4@aspeedtech.com>

Hi Jonathan,

On 2021/8/29, 11:33 PM, "Jonathan Cameron" <jic23 at kernel.org> wrote:

    On Tue, 24 Aug 2021 17:12:40 +0800
    Billy Tsai <billy_tsai at aspeedtech.com> wrote:

    >> Add the function to set the sampling rate and keep the sampling period
    >> for a driver used to wait the lastest value.
    >> 
    >> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>

    > Why move the code as well as factoring out the setter function?
    > I doubt it does any harm, but I'd like to understand why you did it.

    > Jonathan

    >> +	ret = clk_prepare_enable(data->clk_scaler->clk);
    >> +	if (ret)
    >> +		return ret;
    >> +
    >> +	ret = devm_add_action_or_reset(data->dev,
    >> +				       aspeed_adc_clk_disable_unprepare,
    >> +				       data->clk_scaler->clk);
    >> +	if (ret)
    >> +		return ret;
    >> +
    >> +	ret = aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE);
    >> +	if (ret)
    >> +		return ret;
    >> +
    >>  	ret = aspeed_adc_vref_config(indio_dev);
    >>  	if (ret)
    >>  		return ret;
    >> @@ -413,16 +445,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
    >>  	}
    >>  
    >>  	/* Start all channels in normal mode. */

    > Why move this code up?

Because the ADC clock is required when initializing the ADC device.
In our system, the clock is always on. Thus, the legacy driver won't encounter any issues.
I move the clk_prepare_enable ahead of initializing phase for making the driver probe logically closer to the hardware. 

    >> -	ret = clk_prepare_enable(data->clk_scaler->clk);
    >> -	if (ret)
    >> -		return ret;
    >> -
    >> -	ret = devm_add_action_or_reset(data->dev,
    >> -				       aspeed_adc_clk_disable_unprepare,
    >> -				       data->clk_scaler->clk);
    >> -	if (ret)
    >> -		return ret;
    >> -
    >>  	adc_engine_control_reg_val =
    >>  		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
    >>  	adc_engine_control_reg_val |=


Best Regards,
Billy Tsai


From nsaenz at kernel.org  Mon Aug 30 01:36:43 2021
From: nsaenz at kernel.org (nicolas saenz julienne)
Date: Mon, 30 Aug 2021 10:36:43 +0200
Subject: [PATCH v3 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210826071557.29239-3-jeremy.linton@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
 <20210826071557.29239-3-jeremy.linton@arm.com>
Message-ID: <44ad79081412af289c68e74cdecb6a2baa2e873c.camel@kernel.org>

Hi Jeremy,
sorry for the late reply, I've been on vacation.

On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:

[...]

> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
> +					unsigned int devfn, int where)
> +{
> +	struct pci_config_window *cfg = bus->sysdata;
> +	void __iomem *base = cfg->win;
> +	int idx;
> +	u32 up;
> +
> +	/* Accesses to the RC go right to the RC registers if slot==0 */
> +	if (pci_is_root_bus(bus))
> +		return PCI_SLOT(devfn) ? NULL : base + where;
> +
> +	/*
> +	 * Assure the link is up before sending requests downstream. This is done
> +	 * to avoid sending transactions to EPs that don't exist. Link flap
> +	 * conditions/etc make this race more probable. The resulting unrecoverable
> +	 * SERRORs will result in the machine crashing.
> +	 */
> +	up = readl(base + PCIE_MISC_PCIE_STATUS);
> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
> +		return NULL;
> +
> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
> +		return NULL;

Couldn't this be integrated in the original brcm_pcie_map_conf()? IIUC there is
nothing ACPI specific about it. It'd also make for less code duplication.

Regards,
Nicolas



From nsaenz at kernel.org  Mon Aug 30 01:37:01 2021
From: nsaenz at kernel.org (nicolas saenz julienne)
Date: Mon, 30 Aug 2021 10:37:01 +0200
Subject: [PATCH v3 1/4] PCI: brcmstb: Break register definitions into
 separate header
In-Reply-To: <20210826071557.29239-2-jeremy.linton@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
 <20210826071557.29239-2-jeremy.linton@arm.com>
Message-ID: <752472af4f659990ca46595dcc0a150cdcf71ba9.camel@kernel.org>

On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
> We are about to create a standalone ACPI quirk module for the
> bcmstb controller. Lets move the register definitions into a separate
> file so they can be shared between the APCI quirk and the normal
> host bridge driver.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> Acked-by: Florian Fainelli <f.fainelli at gmail.com>
> Acked-by: Bjorn Helgaas <bhelgaas at google.com>
> ---

Acked-by: Nicolas Saenz Julienne <nsaenz at kernel.org>

Regards,
Nicolas



From nsaenz at kernel.org  Mon Aug 30 01:37:51 2021
From: nsaenz at kernel.org (nicolas saenz julienne)
Date: Mon, 30 Aug 2021 10:37:51 +0200
Subject: [PATCH v3 3/4] PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
In-Reply-To: <20210826071557.29239-4-jeremy.linton@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
 <20210826071557.29239-4-jeremy.linton@arm.com>
Message-ID: <56addfb6b446380543205ed1d71dd218b98154d8.camel@kernel.org>

On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
> Now that there is a bcm2711 quirk, it needs to be enabled when the
> MCFG is missing. Use an ACPI namespace _DSD property
> "linux-ecam-quirk-id" as an alternative to the MCFG OEM.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> Acked-by: Florian Fainelli <f.fainelli at gmail.com>
> Acked-by: Bjorn Helgaas <bhelgaas at google.com>
> ---

Acked-by: Nicolas Saenz Julienne <nsaenz at kernel.org>

Regards,
Nicolas



From nsaenz at kernel.org  Mon Aug 30 01:38:11 2021
From: nsaenz at kernel.org (nicolas saenz julienne)
Date: Mon, 30 Aug 2021 10:38:11 +0200
Subject: [PATCH v3 4/4] MAINTAINERS: Widen brcmstb PCIe file scope
In-Reply-To: <20210826071557.29239-5-jeremy.linton@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
 <20210826071557.29239-5-jeremy.linton@arm.com>
Message-ID: <5e0673edbdd793870738c6f5eeebd8ffca747e07.camel@kernel.org>

On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
> The brcmstb PCI hardware is now split across multiple files. Include
> them in the maintainers block.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> Acked-by: Florian Fainelli <f.fainelli at gmail.com>
> Acked-by: Bjorn Helgaas <bhelgaas at google.com>
> ---

Acked-by: Nicolas Saenz Julienne <nsaenz at kernel.org>

Regards,
Nicolas



From nsaenz at kernel.org  Mon Aug 30 01:46:53 2021
From: nsaenz at kernel.org (nicolas saenz julienne)
Date: Mon, 30 Aug 2021 10:46:53 +0200
Subject: [PATCH V2 00/10] ARM: dts: Add Raspberry Pi CM4 & CM4 IO Board
 support
In-Reply-To: <fb80f7a5-8fd4-73e3-4c64-77f120546cc4@gmail.com>
References: <1628334401-6577-1-git-send-email-stefan.wahren@i2se.com>
 <fb80f7a5-8fd4-73e3-4c64-77f120546cc4@gmail.com>
Message-ID: <04fa9c4bc7fc87377c9f392dea0761591bb85616.camel@kernel.org>

Hi Florian,

On Sun, 2021-08-22 at 12:31 +0200, Florian Fainelli wrote:
> 
> On 8/7/2021 1:06 PM, Stefan Wahren wrote:
> > This series add support for the Raspberry Pi Compute Module 4 and its
> > IO board.
> > 
> > Changes in V2:
> > - drop emmc2bus patch as it affects userspace (thanks to Marc Zyngier)
> > - tested with CM4 and integrate sdhci patches from Nicolas (just include kHz fixups)
> > - add Rob's Acked-by
> > - add HS200 property to emmc2 node for a slight performance gain
> > - move antenna comment to the proper position
> 
> Nicolas, I am assuming you will be picking up these patches and submit a 
> BCM283x pull request with them. Thanks!

Yes, sorry for the late replies. I'm just back from vacation.

Regards,
Nicolas



From laurent.pinchart at ideasonboard.com  Mon Aug 30 02:00:54 2021
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 30 Aug 2021 12:00:54 +0300
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <885db6cd26907939511ff132c0fa3ad122c0e588.camel@mediatek.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
 <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>
 <CAAEAJfAwUfwK=Cn7ocedhOaPyMqjL6phwSypkKDXGk6EV4D-vg@mail.gmail.com>
 <885db6cd26907939511ff132c0fa3ad122c0e588.camel@mediatek.com>
Message-ID: <YSyeRq2UMluSfd2y@pendragon.ideasonboard.com>

Hi Yunfei,

On Mon, Aug 30, 2021 at 02:07:44PM +0800, yunfei.dong at mediatek.com wrote:
> On Sun, 2021-08-29 at 17:50 -0300, Ezequiel Garcia wrote:
> > On Wed, 11 Aug 2021 at 14:59, Laurent Pinchart wrote:
> > > On Wed, Aug 11, 2021 at 10:57:59AM +0800, Yunfei Dong wrote:
> > > > Adds decoder dt-bindings for mt8192.
> > > > 
> > > > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> > > > ---
> > > > v5: no changes
> > > > 
> > > > This patch depends on "Mediatek MT8192 clock support"[1].
> > > > 
> > > > The definition of decoder clocks are in mt8192-clk.h, need to
> > > > include them in case of build fail [1].
> > > > 
> > > > [1]
> > > > https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> > > > ---
> > > >  .../media/mediatek,vcodec-comp-decoder.yaml   | 172 ++++++++++++++++++
> > > >  1 file changed, 172 insertions(+)
> > > >  create mode 100644
> > > > Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> > > > new file mode 100644
> > > > index 000000000000..083c89933917
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-decoder.yaml
> > > > @@ -0,0 +1,172 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Mediatek Video Decode Accelerator With Component
> > > > +
> > > > +maintainers:
> > > > +  - Yunfei Dong <yunfei.dong at mediatek.com>
> > > > +
> > > > +description: |+
> > > > +  Mediatek Video Decode is the video decode hardware present in Mediatek
> > > > +  SoCs which supports high resolution decoding functionalities. Required
> > > > +  master and component node.
> > > 
> > > This should explain how the three IP cores relate to each other.
> > > 
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    oneOf:
> > > > +      - enum:
> > > > +          - mediatek,mt8192-vcodec-dec  # for lat hardware
> > > > +          - mediatek,mtk-vcodec-lat     # for core hardware
> > > > +          - mediatek,mtk-vcodec-core
> > > > +
> > > > +  reg:
> > > > +    maxItems: 1
> > > > +
> > > > +  interrupts:
> > > > +    maxItems: 1
> > > > +
> > > > +  clocks:
> > > > +    maxItems: 5
> > > > +
> > > > +  clock-names:
> > > > +    items:
> > > > +      - const: vdec-sel
> > > > +      - const: vdec-soc-vdec
> > > > +      - const: vdec-soc-lat
> > > > +      - const: vdec-vdec
> > > > +      - const: vdec-top
> > > > +
> > > > +  assigned-clocks: true
> > > > +
> > > > +  assigned-clock-parents: true
> > > > +
> > > > +  power-domains:
> > > > +    maxItems: 1
> > > > +
> > > > +  iommus:
> > > > +    minItems: 1
> > > > +    maxItems: 32
> > > > +    description: |
> > > > +      List of the hardware port in respective IOMMU block for current Socs.
> > > > +      Refer to bindings/iommu/mediatek,iommu.yaml.
> > > > +
> > > > +  dma-ranges:
> > > > +    maxItems: 1
> > > > +    description: |
> > > > +      Describes the physical address space of IOMMU maps to memory.
> > > > +
> > > > +  mediatek,scp:
> > > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > > +    maxItems: 1
> > > > +    description:
> > > > +      Describes point to scp.
> > > > +
> > > > +required:
> > > > +      - compatible
> > > > +      - reg
> > > > +      - iommus
> > > > +      - dma-ranges
> > > > +
> > > > +allOf:
> > > > +  - if: #master node
> > > > +      properties:
> > > > +        compatible:
> > > > +          contains:
> > > > +            enum:
> > > > +              - mediatek,mt8192-vcodec-dec  # for lat hardware
> > > > +
> > > > +    then:
> > > > +      required:
> > > > +        - mediatek,scp
> > > > +
> > > > +  - if: #component node
> > > > +      properties:
> > > > +        compatible:
> > > > +          contains:
> > > > +            enum:
> > > > +              - mediatek,mtk-vcodec-lat     # for core hardware
> > > > +              - mediatek,mtk-vcodec-core
> > > > +
> > > > +    then:
> > > > +      required:
> > > > +        - interrupts
> > > > +        - clocks
> > > > +        - clock-names
> > > > +        - assigned-clocks
> > > > +        - assigned-clock-parents
> > > > +        - power-domains
> > > > +
> > > > +
> > > > +additionalProperties: false
> > > > +
> > > > +examples:
> > > > +  - |
> > > > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > > > +    #include <dt-bindings/memory/mt8192-larb-port.h>
> > > > +    #include <dt-bindings/interrupt-controller/irq.h>
> > > > +    #include <dt-bindings/clock/mt8192-clk.h>
> > > > +    #include <dt-bindings/power/mt8192-power.h>
> > > > +
> > > > +    vcodec_dec: vcodec_dec at 16000000 {
> > > > +        compatible = "mediatek,mt8192-vcodec-dec";
> > > > +        reg = <0 0x16000000 0 0x1000>;               /* VDEC_SYS */
> > > > +        mediatek,scp = <&scp>;
> > > > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
> > > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > > +    };
> > > > +
> > > > +    vcodec_lat: vcodec_lat at 0x16010000 {
> > > > +        compatible = "mediatek,mtk-vcodec-lat";
> > > > +        reg = <0 0x16010000 0 0x800>;                /* VDEC_MISC */
> > > > +        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
> > > > +        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
> > > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > > > +             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
> > > > +             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
> > > > +             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
> > > > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > > > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> > > > +              "vdec-vdec", "vdec-top";
> > > > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > > > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > > > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
> > > > +    };
> > > > +
> > > > +    vcodec_core: vcodec_core at 0x16025000 {
> > > > +        compatible = "mediatek,mtk-vcodec-core";
> > > > +        reg = <0 0x16025000 0 0x1000>;               /* VDEC_CORE_MISC */
> > > > +        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
> > > > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
> > > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > > > +             <&vdecsys CLK_VDEC_VDEC>,
> > > > +             <&vdecsys CLK_VDEC_LAT>,
> > > > +             <&vdecsys CLK_VDEC_LARB1>,
> > > > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > > > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
> > > > +              "vdec-vdec", "vdec-top";
> > > > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > > > +        assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
> > > > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
> > > > +    };
> > > 
> > > I'm a bit late in the game, reviewing v5 only, but I'm wondering if
> > > those IP cores need to be modelled in separate nodes. It would be much
> > > easier, from a software point of view, to have a single node, with
> > > multiple register ranges.
> > > 
> > > Are some of those IP cores used in different SoCs, combined in different
> > > ways, that make a modular design better ?
>
> 1. Each a node should respect a HW node. Defining a complex node that
> contain multiple register is not better, for they belong to different
> hardware. Different platforms has different hardware count, mt8195 has
> five hardwares.
> 2. Another reason is from the IOMMU point, the vcodec HW include core
> and lat hardwares, each of them connect to the independent IOMMU
> hardware for mt8195, can't write all iommu ports together, or hardware
> can't access dram data, so we must separate them.

Maybe it could help understanding the situation if the DT bindings could
include more information about the hardware architecture, such as a
block diagram for instance, and how the pieces interact with each other
?

> > Yeah, I agree with Laurent here. This way of modelling the different parts
> > of the CODEC as different pieces is the reason why you need a framework
> > to pull them together, such as the component API (I guess v4l2-async
> > could have been used as well).
>
> We must separate each hardware node, only master need to register video
> and media device, component just used for store clk/power/irq/register
> information for current hardware.
>
> > I normally don't bother with driver internals, as its up to each driver
> > author to decide what is best. However, I believe this design is too
> > convoluted, and it may lead other developers to follow the same pattern,
> > so please avoid it.
>
> According to your information, it looks that component and v4l2 async
> are ok for this architecture, only component is too convoluted(iommu
> driver also use component).
> 
> For we are not very familiar with v4l2 async, out architecture is
> designed for component include next forty patches. It is a very big
> change for out driver. I will try to spend a lot of time to change it.
> 
> > There are several ways of modelling this and initializing or probing
> > the sub-devices,
> > without using any async framework.
>
> You may misunderstand, I'm not objecting your suggestion every time,
> for our driver is designed for component api, need to spend a lot of
> time to change it in many platforms. I will change it if v4l2 async has
> many advantages then component as you said. I will try to use v4l2
> async as compared.

-- 
Regards,

Laurent Pinchart


From hector.yuan at mediatek.com  Mon Aug 30 02:08:27 2021
From: hector.yuan at mediatek.com (Hector Yuan)
Date: Mon, 30 Aug 2021 17:08:27 +0800
Subject: [PATCH v14 2/3] cpufreq: Add of_perf_domain_get_sharing_cpumask
In-Reply-To: <20210830050450.r4kfv72bsxsttnli@vireshk-i7>
References: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
 <1630162872-25452-3-git-send-email-hector.yuan@mediatek.com>
 <20210830050450.r4kfv72bsxsttnli@vireshk-i7>
Message-ID: <964ef8cae3e1eb276da4d891a6daac6ed05bb734.camel@mediatek.com>

On Mon, 2021-08-30 at 10:34 +0530, Viresh Kumar wrote:
> On 28-08-21, 23:01, Hector Yuan wrote:
> > From: "Hector.Yuan" <hector.yuan at mediatek.com>
> > 
> > Add of_perf_domain_get_sharing_cpumask function to group cpu
> > to specific performance domain.
> > 
> > Signed-off-by: Hector.Yuan <hector.yuan at mediatek.com>
> > ---
> >  include/linux/cpufreq.h |   39
> > +++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 39 insertions(+)
> > 
> > diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> > index 9fd7194..4916d70 100644
> > --- a/include/linux/cpufreq.h
> > +++ b/include/linux/cpufreq.h
> > @@ -13,6 +13,8 @@
> >  #include <linux/completion.h>
> >  #include <linux/kobject.h>
> >  #include <linux/notifier.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/pm_qos.h>
> >  #include <linux/spinlock.h>
> >  #include <linux/sysfs.h>
> > @@ -1036,6 +1038,43 @@ void arch_set_freq_scale(const struct
> > cpumask *cpus,
> >  }
> >  #endif
> >  
> > +#ifdef CONFIG_CPU_FREQ
> > +static inline int of_perf_domain_get_sharing_cpumask(int index,
> > const char *list_name,
> > +						     const char
> > *cell_name,
> > +						     struct cpumask
> > *cpumask)
> 
> What happened with the discussion we had about returning index and
> passing CPU
> there ?
> 
Hi, Viresh, sorry for this, I didn't upload the correct version of
cpufreq.h. Should I just go v15 or you want to do some review for other
part of my patches? Thanks.

From laurentiu.tudor at nxp.com  Mon Aug 30 02:29:23 2021
From: laurentiu.tudor at nxp.com (Laurentiu Tudor)
Date: Mon, 30 Aug 2021 12:29:23 +0300
Subject: [PATCH 1/2] bus/fsl-mc: Add generic implementation for
 open/reset/close commands
In-Reply-To: <20210825090538.4860-1-diana.craciun@oss.nxp.com>
References: <20210825090538.4860-1-diana.craciun@oss.nxp.com>
Message-ID: <b0ec47ea-d32b-04bb-aea4-1c8a74bc8f99@nxp.com>



On 8/25/2021 12:05 PM, Diana Craciun wrote:
> The open/reset/close commands format is similar for all objects.
> Currently there are multiple implementations for these commands
> scattered through various drivers. The code is cavsi-identical.
> Create a generic implementation for the open/reset/close commands.
> One of the consumer will be the VFIO driver which needs to
> be able to reset a device.
> 
> Signed-off-by: Diana Craciun <diana.craciun at oss.nxp.com>
> ---
>  drivers/bus/fsl-mc/Makefile         |   3 +-
>  drivers/bus/fsl-mc/fsl-mc-private.h |  39 +++++++++--
>  drivers/bus/fsl-mc/obj-api.c        | 104 ++++++++++++++++++++++++++++
>  include/linux/fsl/mc.h              |  14 ++++
>  4 files changed, 155 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/bus/fsl-mc/obj-api.c
> 
> diff --git a/drivers/bus/fsl-mc/Makefile b/drivers/bus/fsl-mc/Makefile
> index 4ae292a30e53..892946245527 100644
> --- a/drivers/bus/fsl-mc/Makefile
> +++ b/drivers/bus/fsl-mc/Makefile
> @@ -15,7 +15,8 @@ mc-bus-driver-objs := fsl-mc-bus.o \
>  		      dprc-driver.o \
>  		      fsl-mc-allocator.o \
>  		      fsl-mc-msi.o \
> -		      dpmcp.o
> +		      dpmcp.o \
> +		      obj-api.o
>  
>  # MC userspace support
>  obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o
> diff --git a/drivers/bus/fsl-mc/fsl-mc-private.h b/drivers/bus/fsl-mc/fsl-mc-private.h
> index 1958fa065360..6055ef3e9e02 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-private.h
> +++ b/drivers/bus/fsl-mc/fsl-mc-private.h
> @@ -48,7 +48,6 @@ struct dpmng_rsp_get_version {
>  
>  /* DPMCP command IDs */
>  #define DPMCP_CMDID_CLOSE		DPMCP_CMD(0x800)
> -#define DPMCP_CMDID_OPEN		DPMCP_CMD(0x80b)
>  #define DPMCP_CMDID_RESET		DPMCP_CMD(0x005)
>  
>  struct dpmcp_cmd_open {
> @@ -91,7 +90,6 @@ int dpmcp_reset(struct fsl_mc_io *mc_io,
>  
>  /* DPRC command IDs */
>  #define DPRC_CMDID_CLOSE                        DPRC_CMD(0x800)
> -#define DPRC_CMDID_OPEN                         DPRC_CMD(0x805)
>  #define DPRC_CMDID_GET_API_VERSION              DPRC_CMD(0xa05)
>  
>  #define DPRC_CMDID_GET_ATTR                     DPRC_CMD(0x004)
> @@ -453,7 +451,6 @@ int dprc_get_connection(struct fsl_mc_io *mc_io,
>  
>  /* Command IDs */
>  #define DPBP_CMDID_CLOSE		DPBP_CMD(0x800)
> -#define DPBP_CMDID_OPEN			DPBP_CMD(0x804)
>  
>  #define DPBP_CMDID_ENABLE		DPBP_CMD(0x002)
>  #define DPBP_CMDID_DISABLE		DPBP_CMD(0x003)
> @@ -492,7 +489,6 @@ struct dpbp_rsp_get_attributes {
>  
>  /* Command IDs */
>  #define DPCON_CMDID_CLOSE			DPCON_CMD(0x800)
> -#define DPCON_CMDID_OPEN			DPCON_CMD(0x808)
>  
>  #define DPCON_CMDID_ENABLE			DPCON_CMD(0x002)
>  #define DPCON_CMDID_DISABLE			DPCON_CMD(0x003)
> @@ -524,6 +520,41 @@ struct dpcon_cmd_set_notification {
>  	__le64 user_ctx;
>  };
>  
> +/*
> + * Generic FSL MC API
> + */
> +
> +/* generic command versioning */
> +#define OBJ_CMD_BASE_VERSION		1
> +#define OBJ_CMD_ID_OFFSET		4
> +
> +#define OBJ_CMD(id)	(((id) << OBJ_CMD_ID_OFFSET) | OBJ_CMD_BASE_VERSION)
> +
> +/* open command codes */
> +#define DPRTC_CMDID_OPEN		OBJ_CMD(0x810)
> +#define DPNI_CMDID_OPEN		OBJ_CMD(0x801)
> +#define DPSW_CMDID_OPEN		OBJ_CMD(0x802)
> +#define DPIO_CMDID_OPEN		OBJ_CMD(0x803)
> +#define DPBP_CMDID_OPEN		OBJ_CMD(0x804)
> +#define DPRC_CMDID_OPEN		OBJ_CMD(0x805)
> +#define DPDMUX_CMDID_OPEN		OBJ_CMD(0x806)
> +#define DPCI_CMDID_OPEN		OBJ_CMD(0x807)
> +#define DPCON_CMDID_OPEN		OBJ_CMD(0x808)
> +#define DPSECI_CMDID_OPEN		OBJ_CMD(0x809)
> +#define DPAIOP_CMDID_OPEN		OBJ_CMD(0x80a)
> +#define DPMCP_CMDID_OPEN		OBJ_CMD(0x80b)
> +#define DPMAC_CMDID_OPEN		OBJ_CMD(0x80c)
> +#define DPDCEI_CMDID_OPEN		OBJ_CMD(0x80d)
> +#define DPDMAI_CMDID_OPEN		OBJ_CMD(0x80e)
> +#define DPDBG_CMDID_OPEN		OBJ_CMD(0x80f)
> +
> +/* Generic object command IDs */
> +#define OBJ_CMDID_CLOSE		OBJ_CMD(0x800)
> +#define OBJ_CMDID_RESET		OBJ_CMD(0x005)
> +
> +struct obj_cmd_open {

Nit: maybe the name should be made less generic, e.g. fsl_mc_obj_cmd_open.

Otherwise, looks good to me:

Reviewed-by: Laurentiu Tudor <laurentiu.tudor at nxp.com>

---
Best Regards, Laurentiu


From laurentiu.tudor at nxp.com  Mon Aug 30 02:42:05 2021
From: laurentiu.tudor at nxp.com (Laurentiu Tudor)
Date: Mon, 30 Aug 2021 12:42:05 +0300
Subject: [PATCH 2/2] vfio/fsl-mc: Add per device reset support
In-Reply-To: <20210825090538.4860-2-diana.craciun@oss.nxp.com>
References: <20210825090538.4860-1-diana.craciun@oss.nxp.com>
 <20210825090538.4860-2-diana.craciun@oss.nxp.com>
Message-ID: <4d0e9854-4187-cca3-c2dc-036258639e4b@nxp.com>



On 8/25/2021 12:05 PM, Diana Craciun wrote:
> Currently when a fsl-mc device is reset, the entire DPRC container
> is reset which is very inefficient because the devices within a
> container will be reset multiple times.
> Add support for individually resetting a device.
> 
> Signed-off-by: Diana Craciun <diana.craciun at oss.nxp.com>
> ---
>  drivers/vfio/fsl-mc/vfio_fsl_mc.c | 45 ++++++++++++++++++++-----------
>  1 file changed, 29 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
> index 90cad109583b..46126d41dc32 100644
> --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
> +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
> @@ -155,6 +155,33 @@ static int vfio_fsl_mc_open(struct vfio_device *core_vdev)
>  	return ret;
>  }
>  
> +static int vfio_fsl_mc_reset_device(struct vfio_fsl_mc_device *vdev)
> +{
> +	struct fsl_mc_device *mc_dev = vdev->mc_dev;
> +	int ret = 0;
> +
> +	if (is_fsl_mc_bus_dprc(vdev->mc_dev)) {
> +		return dprc_reset_container(mc_dev->mc_io, 0,
> +					mc_dev->mc_handle,
> +					mc_dev->obj_desc.id,
> +					DPRC_RESET_OPTION_NON_RECURSIVE);
> +	} else {
> +		int err;
> +		u16 token;
> +
> +		err = fsl_mc_obj_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
> +				      mc_dev->obj_desc.type,
> +				      &token);
> +		if (err)
> +			return err;
> +		ret = fsl_mc_obj_reset(mc_dev->mc_io, 0, token);
> +		err = fsl_mc_obj_close(mc_dev->mc_io, 0, token);
> +		if (err)
> +			return err;

Error handling here looks a bit atypical to me. Maybe something like
this, which will also get rid of the 2nd err var.

	{
		ret = fsl_mc_obj_open(...);
		if (ret)
			goto out;
		ret = fsl_mc_obj_reset(...);
		if (ret) {
			fsl_mc_obj_close(...);
			goto out;
		}
		ret = fsl_mc_obj_close(...);
	}

out:
	return ret;

---
Best Regards, Laurentiu

> +	}
> +	return ret;
> +}
> +
>  static void vfio_fsl_mc_release(struct vfio_device *core_vdev)
>  {
>  	struct vfio_fsl_mc_device *vdev =
> @@ -171,10 +198,7 @@ static void vfio_fsl_mc_release(struct vfio_device *core_vdev)
>  		vfio_fsl_mc_regions_cleanup(vdev);
>  
>  		/* reset the device before cleaning up the interrupts */
> -		ret = dprc_reset_container(mc_cont->mc_io, 0,
> -		      mc_cont->mc_handle,
> -			  mc_cont->obj_desc.id,
> -			  DPRC_RESET_OPTION_NON_RECURSIVE);
> +		ret = vfio_fsl_mc_reset_device(vdev);
>  
>  		if (ret) {
>  			dev_warn(&mc_cont->dev, "VFIO_FLS_MC: reset device has failed (%d)\n",
> @@ -302,18 +326,7 @@ static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev,
>  	}
>  	case VFIO_DEVICE_RESET:
>  	{
> -		int ret;
> -		struct fsl_mc_device *mc_dev = vdev->mc_dev;
> -
> -		/* reset is supported only for the DPRC */
> -		if (!is_fsl_mc_bus_dprc(mc_dev))
> -			return -ENOTTY;
> -
> -		ret = dprc_reset_container(mc_dev->mc_io, 0,
> -					   mc_dev->mc_handle,
> -					   mc_dev->obj_desc.id,
> -					   DPRC_RESET_OPTION_NON_RECURSIVE);
> -		return ret;
> +		return vfio_fsl_mc_reset_device(vdev);
>  
>  	}
>  	default:
> 


From jic23 at kernel.org  Mon Aug 30 02:52:13 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 30 Aug 2021 10:52:13 +0100
Subject: [RESEND v4 12/15] iio: adc: aspeed: Add func to set sampling rate.
In-Reply-To: <FE947284-E67B-49DB-B538-3ECAD8317BD4@aspeedtech.com>
References: <20210824091243.9393-1-billy_tsai@aspeedtech.com>
 <202108250003.17P03KRU092474@twspam01.aspeedtech.com>
 <20210829163659.2f7f5974@jic23-huawei>
 <FE947284-E67B-49DB-B538-3ECAD8317BD4@aspeedtech.com>
Message-ID: <20210830105213.25ee20a2@jic23-huawei>

On Mon, 30 Aug 2021 08:35:53 +0000
Billy Tsai <billy_tsai at aspeedtech.com> wrote:

> Hi Jonathan,
> 
> On 2021/8/29, 11:33 PM, "Jonathan Cameron" <jic23 at kernel.org> wrote:
> 
>     On Tue, 24 Aug 2021 17:12:40 +0800
>     Billy Tsai <billy_tsai at aspeedtech.com> wrote:
> 
>     >> Add the function to set the sampling rate and keep the sampling period
>     >> for a driver used to wait the lastest value.
>     >> 
>     >> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>  
> 
>     > Why move the code as well as factoring out the setter function?
>     > I doubt it does any harm, but I'd like to understand why you did it.  
> 
>     > Jonathan  
> 
>     >> +	ret = clk_prepare_enable(data->clk_scaler->clk);
>     >> +	if (ret)
>     >> +		return ret;
>     >> +
>     >> +	ret = devm_add_action_or_reset(data->dev,
>     >> +				       aspeed_adc_clk_disable_unprepare,
>     >> +				       data->clk_scaler->clk);
>     >> +	if (ret)
>     >> +		return ret;
>     >> +
>     >> +	ret = aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE);
>     >> +	if (ret)
>     >> +		return ret;
>     >> +
>     >>  	ret = aspeed_adc_vref_config(indio_dev);
>     >>  	if (ret)
>     >>  		return ret;
>     >> @@ -413,16 +445,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>     >>  	}
>     >>  
>     >>  	/* Start all channels in normal mode. */  
> 
>     > Why move this code up?  
> 
> Because the ADC clock is required when initializing the ADC device.
> In our system, the clock is always on. Thus, the legacy driver won't encounter any issues.
> I move the clk_prepare_enable ahead of initializing phase for making the driver probe logically closer to the hardware. 

Thanks. Please add something to the patch description to say this.

Jonathan

> 
>     >> -	ret = clk_prepare_enable(data->clk_scaler->clk);
>     >> -	if (ret)
>     >> -		return ret;
>     >> -
>     >> -	ret = devm_add_action_or_reset(data->dev,
>     >> -				       aspeed_adc_clk_disable_unprepare,
>     >> -				       data->clk_scaler->clk);
>     >> -	if (ret)
>     >> -		return ret;
>     >> -
>     >>  	adc_engine_control_reg_val =
>     >>  		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
>     >>  	adc_engine_control_reg_val |=  
> 
> 
> Best Regards,
> Billy Tsai
> 



From guangming.cao at mediatek.com  Mon Aug 30 03:01:38 2021
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Mon, 30 Aug 2021 18:01:38 +0800
Subject: [PATCH] dma-buf: heaps: remove duplicated cache sync
Message-ID: <20210830100139.15632-1-guangming.cao@mediatek.com>

From: Guangming Cao <Guangming.Cao at mediatek.com>

Current flow, one dmabuf maybe call cache sync many times if
it has beed mapped more than one time.

Is there any case that attachments of one dmabuf will points to
different memory? If not, seems do sync only one time is more better.

Signed-off-by: Guangming Cao <Guangming.Cao at mediatek.com>
---
 drivers/dma-buf/heaps/system_heap.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 23a7e74ef966..909ef652a8c8 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -162,9 +162,10 @@ static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
 		invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
 
 	list_for_each_entry(a, &buffer->attachments, list) {
-		if (!a->mapped)
-			continue;
-		dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
+		if (a->mapped) {
+			dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
+			break;
+		}
 	}
 	mutex_unlock(&buffer->lock);
 
@@ -183,9 +184,10 @@ static int system_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
 		flush_kernel_vmap_range(buffer->vaddr, buffer->len);
 
 	list_for_each_entry(a, &buffer->attachments, list) {
-		if (!a->mapped)
-			continue;
-		dma_sync_sgtable_for_device(a->dev, a->table, direction);
+		if (!a->mapped) {
+			dma_sync_sgtable_for_device(a->dev, a->table, direction);
+			break;
+		}
 	}
 	mutex_unlock(&buffer->lock);
 
-- 
2.17.1

From claudiu.beznea at microchip.com  Mon Aug 30 03:09:27 2021
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Mon, 30 Aug 2021 13:09:27 +0300
Subject: [PATCH] ARM: at91: pm: switch backup area to vbat in backup mode
Message-ID: <20210830100927.22711-1-claudiu.beznea@microchip.com>

Backup area is now switched to VDDIN33 at boot (with the help of
bootloader). When switching to backup mode we need to switch backup area
to VBAT as all the other power sources are cut off. The resuming from
backup mode is done with the help of bootloader, so there is no need to
do something particular in Linux to restore backup area power source.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---

Hi Nicolas,

This applies clean on top of patch with title
"ARM: at91: pm: do not panic if ram controllers are not enabled"

Thank you,
Claudiu Beznea

 arch/arm/mach-at91/pm.c | 52 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index d92afca64b49..8711d6824c1f 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -47,12 +47,26 @@ struct at91_pm_bu {
 	unsigned long ddr_phy_calibration[BACKUP_DDR_PHY_CALIBRATION];
 };
 
+/*
+ * struct at91_pm_sfrbu_offsets: registers mapping for SFRBU
+ * @pswbu: power switch BU control registers
+ */
+struct at91_pm_sfrbu_regs {
+	struct {
+		u32 key;
+		u32 ctrl;
+		u32 state;
+		u32 softsw;
+	} pswbu;
+};
+
 /**
  * struct at91_soc_pm - AT91 SoC power management data structure
  * @config_shdwc_ws: wakeup sources configuration function for SHDWC
  * @config_pmc_ws: wakeup srouces configuration function for PMC
  * @ws_ids: wakup sources of_device_id array
  * @data: PM data to be used on last phase of suspend
+ * @sfrbu_regs: SFRBU registers mapping
  * @bu: backup unit mapped data (for backup mode)
  * @memcs: memory chip select
  */
@@ -62,6 +76,7 @@ struct at91_soc_pm {
 	const struct of_device_id *ws_ids;
 	struct at91_pm_bu *bu;
 	struct at91_pm_data data;
+	struct at91_pm_sfrbu_regs sfrbu_regs;
 	void *memcs;
 };
 
@@ -356,9 +371,36 @@ static int at91_suspend_finish(unsigned long val)
 	return 0;
 }
 
+static void at91_pm_switch_ba_to_vbat(void)
+{
+	unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
+	unsigned int val;
+
+	/* Just for safety. */
+	if (!soc_pm.data.sfrbu)
+		return;
+
+	val = readl(soc_pm.data.sfrbu + offset);
+
+	/* Already on VBAT. */
+	if (!(val & soc_pm.sfrbu_regs.pswbu.state))
+		return;
+
+	val &= ~soc_pm.sfrbu_regs.pswbu.softsw;
+	val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
+	writel(val, soc_pm.data.sfrbu + offset);
+
+	/* Wait for update. */
+	val = readl(soc_pm.data.sfrbu + offset);
+	while (val & soc_pm.sfrbu_regs.pswbu.state)
+		val = readl(soc_pm.data.sfrbu + offset);
+}
+
 static void at91_pm_suspend(suspend_state_t state)
 {
 	if (soc_pm.data.mode == AT91_PM_BACKUP) {
+		at91_pm_switch_ba_to_vbat();
+
 		cpu_suspend(0, at91_suspend_finish);
 
 		/* The SRAM is lost between suspend cycles */
@@ -1155,6 +1197,11 @@ void __init sama5d2_pm_init(void)
 	soc_pm.ws_ids = sama5d2_ws_ids;
 	soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws;
 	soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws;
+
+	soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8);
+	soc_pm.sfrbu_regs.pswbu.ctrl = BIT(0);
+	soc_pm.sfrbu_regs.pswbu.softsw = BIT(1);
+	soc_pm.sfrbu_regs.pswbu.state = BIT(3);
 }
 
 void __init sama7_pm_init(void)
@@ -1185,6 +1232,11 @@ void __init sama7_pm_init(void)
 
 	soc_pm.ws_ids = sama7g5_ws_ids;
 	soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
+
+	soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8);
+	soc_pm.sfrbu_regs.pswbu.ctrl = BIT(0);
+	soc_pm.sfrbu_regs.pswbu.softsw = BIT(1);
+	soc_pm.sfrbu_regs.pswbu.state = BIT(2);
 }
 
 static int __init at91_pm_modes_select(char *str)
-- 
2.25.1



From christian.koenig at amd.com  Mon Aug 30 03:16:28 2021
From: christian.koenig at amd.com (=?UTF-8?Q?Christian_K=c3=b6nig?=)
Date: Mon, 30 Aug 2021 12:16:28 +0200
Subject: [PATCH] dma-buf: heaps: remove duplicated cache sync
In-Reply-To: <20210830100139.15632-1-guangming.cao@mediatek.com>
References: <20210830100139.15632-1-guangming.cao@mediatek.com>
Message-ID: <dd5ba603-8c9d-f6a0-cbcc-dfb353fb6701@amd.com>

Am 30.08.21 um 12:01 schrieb guangming.cao at mediatek.com:
> From: Guangming Cao <Guangming.Cao at mediatek.com>
>
> Current flow, one dmabuf maybe call cache sync many times if
> it has beed mapped more than one time.

Well I'm not an expert on DMA heaps, but this will most likely not work 
correctly.

> Is there any case that attachments of one dmabuf will points to
> different memory? If not, seems do sync only one time is more better.

I think that this can happen, yes.

Christian.


>
> Signed-off-by: Guangming Cao <Guangming.Cao at mediatek.com>
> ---
>   drivers/dma-buf/heaps/system_heap.c | 14 ++++++++------
>   1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
> index 23a7e74ef966..909ef652a8c8 100644
> --- a/drivers/dma-buf/heaps/system_heap.c
> +++ b/drivers/dma-buf/heaps/system_heap.c
> @@ -162,9 +162,10 @@ static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
>   		invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
>   
>   	list_for_each_entry(a, &buffer->attachments, list) {
> -		if (!a->mapped)
> -			continue;
> -		dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
> +		if (a->mapped) {
> +			dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
> +			break;
> +		}
>   	}
>   	mutex_unlock(&buffer->lock);
>   
> @@ -183,9 +184,10 @@ static int system_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
>   		flush_kernel_vmap_range(buffer->vaddr, buffer->len);
>   
>   	list_for_each_entry(a, &buffer->attachments, list) {
> -		if (!a->mapped)
> -			continue;
> -		dma_sync_sgtable_for_device(a->dev, a->table, direction);
> +		if (!a->mapped) {
> +			dma_sync_sgtable_for_device(a->dev, a->table, direction);
> +			break;
> +		}
>   	}
>   	mutex_unlock(&buffer->lock);
>   



From nsaenzju at redhat.com  Mon Aug 30 03:39:09 2021
From: nsaenzju at redhat.com (Nicolas Saenz Julienne)
Date: Mon, 30 Aug 2021 12:39:09 +0200
Subject: [PATCH] ARM: dts: bcm2711-rpi-4-b: Fix pcie0's unit address
Message-ID: <20210830103909.323356-1-nsaenzju@redhat.com>

dtbs_check currently complains that:

arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning
(pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format
error, expected "0,0"

Unsurprisingly pci at 0,0 is the right address, as illustrated by its reg
property:

	&pcie0 {
		pci at 0,0 {
			/*
			 * As defined in the IEEE Std 1275-1994 document,
			 * reg is a five-cell address encoded as (phys.hi
			 * phys.mid phys.lo size.hi size.lo). phys.hi
			 * should contain the device's BDF as 0b00000000
			 * bbbbbbbb dddddfff 00000000. The other cells
			 * should be zero.
			 */
			reg = <0 0 0 0 0>;
		};
	};

The bus is clearly 0. So fix it.

Fixes: 258f92d2f840 ("ARM: dts: bcm2711: Add reset controller to xHCI node")
Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
---
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index f24bdd0870a5..8a77f9e942be 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -217,7 +217,7 @@ phy1: ethernet-phy at 1 {
 };
 
 &pcie0 {
-	pci at 1,0 {
+	pci at 0,0 {
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges;
-- 
2.31.1



From rppt at kernel.org  Mon Aug 30 03:40:44 2021
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 30 Aug 2021 13:40:44 +0300
Subject: [PATCH] arm64: kdump: Skip kmemleak scan reserved memory for kdump
In-Reply-To: <20210827092246.3565437-1-chenwandun@huawei.com>
References: <20210827092246.3565437-1-chenwandun@huawei.com>
Message-ID: <YSy1rB+Ph0PYBuXe@kernel.org>

On Fri, Aug 27, 2021 at 05:22:46PM +0800, Chen Wandun wrote:
> Trying to boot with kdump + kmemleak, command will result in a crash:
> "echo scan > /sys/kernel/debug/kmemleak"
> 
> crashkernel reserved: 0x0000000007c00000 - 0x0000000027c00000 (512 MB)
> Kernel command line: BOOT_IMAGE=(hd1,gpt2)/vmlinuz-5.14.0-rc5-next-20210809+ root=/dev/mapper/ao-root ro rd.lvm.lv=ao/root rd.lvm.lv=ao/swap crashkernel=512M
> Unable to handle kernel paging request at virtual address ffff000007c00000
> Mem abort info:
>   ESR = 0x96000007
>   EC = 0x25: DABT (current EL), IL = 32 bits
>   SET = 0, FnV = 0
>   EA = 0, S1PTW = 0
>   FSC = 0x07: level 3 translation fault
> Data abort info:
>   ISV = 0, ISS = 0x00000007
>   CM = 0, WnR = 0
> swapper pgtable: 64k pages, 48-bit VAs, pgdp=00002024f0d80000
> [ffff000007c00000] pgd=1800205ffffd0003, p4d=1800205ffffd0003, pud=1800205ffffd0003, pmd=1800205ffffc0003, pte=0068000007c00f06
> Internal error: Oops: 96000007 [#1] SMP
> pstate: 804000c9 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : scan_block+0x98/0x230
> lr : scan_block+0x94/0x230
> sp : ffff80008d6cfb70
> x29: ffff80008d6cfb70 x28: 0000000000000000 x27: 0000000000000000
> x26: 00000000000000c0 x25: 0000000000000001 x24: 0000000000000000
> x23: ffffa88a6b18b398 x22: ffff000007c00ff9 x21: ffffa88a6ac7fc40
> x20: ffffa88a6af6a830 x19: ffff000007c00000 x18: 0000000000000000
> x17: 0000000000000000 x16: 0000000000000000 x15: ffffffffffffffff
> x14: ffffffff00000000 x13: ffffffffffffffff x12: 0000000000000020
> x11: 0000000000000000 x10: 0000000001080000 x9 : ffffa88a6951c77c
> x8 : ffffa88a6a893988 x7 : ffff203ff6cfb3c0 x6 : ffffa88a6a52b3c0
> x5 : ffff203ff6cfb3c0 x4 : 0000000000000000 x3 : 0000000000000000
> x2 : 0000000000000001 x1 : ffff20226cb56a40 x0 : 0000000000000000
> Call trace:
>  scan_block+0x98/0x230
>  scan_gray_list+0x120/0x270
>  kmemleak_scan+0x3a0/0x648
>  kmemleak_write+0x3ac/0x4c8
>  full_proxy_write+0x6c/0xa0
>  vfs_write+0xc8/0x2b8
>  ksys_write+0x70/0xf8
>  __arm64_sys_write+0x24/0x30
>  invoke_syscall+0x4c/0x110
>  el0_svc_common+0x9c/0x190
>  do_el0_svc+0x30/0x98
>  el0_svc+0x28/0xd8
>  el0t_64_sync_handler+0x90/0xb8
>  el0t_64_sync+0x180/0x184
> 
> The reserved memory for kdump will be looked up by kmemleak, this area
> will be set invalid when kdump service is bring up. That will result in
> crash when kmemleak scan this area.
> 
> Fixes: 461ef12c4375 ("memblock: make memblock_find_in_range method private")

The commit id will change because patches in mmotm tree do not have stable
commit ids...

> Signed-off-by: Chen Wandun <chenwandun at huawei.com>

Reviewed-by: Mike Rapoport <rppt at linux.ibm.com>

Andrew, can you please pick it up?

> ---
>  arch/arm64/mm/init.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index b16be52233c6..dc0c44622bfd 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -30,6 +30,7 @@
>  #include <linux/crash_dump.h>
>  #include <linux/hugetlb.h>
>  #include <linux/acpi_iort.h>
> +#include <linux/kmemleak.h>
>  
>  #include <asm/boot.h>
>  #include <asm/fixmap.h>
> @@ -101,6 +102,7 @@ static void __init reserve_crashkernel(void)
>  	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>  		crash_base, crash_base + crash_size, crash_size >> 20);
>  
> +	kmemleak_ignore_phys(crash_base);
>  	crashk_res.start = crash_base;
>  	crashk_res.end = crash_base + crash_size - 1;
>  }
> -- 
> 2.18.0.huawei.25
> 

-- 
Sincerely yours,
Mike.


From benh at kernel.crashing.org  Mon Aug 30 03:40:03 2021
From: benh at kernel.crashing.org (Benjamin Herrenschmidt)
Date: Mon, 30 Aug 2021 20:40:03 +1000
Subject: ucontext, kernel vs. userspace (glibc)
Message-ID: <131d684ea46de6330ab90532ab73729d6c0690bd.camel@kernel.crashing.org>

Hi Folks !

So I'm discovering arm64 intricacies and today, as I was looking at SVE
support (in the context of distro glibc backports.. don't ask), I
noticed that glibc has no provision for dealing with kernel generated
ucontext's in its {get,set,swap}_context functions...

(It says so explicitly in the code unless I misunderstood).

So one thing we did to "solve" this on ppc64 a while ago was to create
a swapcontext syscall which can operate as all 3 operations (you can
have NULL arguments), which also handles the sigprocmask (bonus:
atomically with the context get/set from a userspace perspective).

Would it make sense to do something similar on aarch64 ? (And have
glibc then exploit it).

The hard-to-solve thing is the case where the SVE context spills
outside of the ucontext itself, in the extra room on the stack, since
programs that "now" about ucontext will not have allocated space for
that, so that's more/less a lost cause already.

Cheers,
Ben.




From nsaenz at kernel.org  Mon Aug 30 03:44:49 2021
From: nsaenz at kernel.org (nicolas saenz julienne)
Date: Mon, 30 Aug 2021 12:44:49 +0200
Subject: [PATCH] kbuild: Enable dtc 'pci_device_reg' warning by default
In-Reply-To: <20210820165011.3257112-1-robh@kernel.org>
References: <20210820165011.3257112-1-robh@kernel.org>
Message-ID: <0fda88b012499c40e75c74b9e3a7037e2ee3fb9c.camel@kernel.org>

On Fri, 2021-08-20 at 11:50 -0500, Rob Herring wrote:
> There's only a couple of instances of the 'pci_device_reg' warnings left
> and they look legit, so let's enable the warning by default.
> 
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Nicolas Saenz Julienne <nsaenz at kernel.org>
> Cc: soc at kernel.org
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
> These are the 2 remaining warnings:
> 
> arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi:464.3-52: Warning (pci_device_reg): /pcie at f8000000/pcie at 0,0:reg: PCI reg address is not configuration space
> arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning (pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format error, expected "0,0"

Just for the record, bcm2771 issue is being fixed here:
https://lkml.org/lkml/2021/8/30/232

Regards,
Nicolas



From maz at kernel.org  Mon Aug 30 04:37:31 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 30 Aug 2021 12:37:31 +0100
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <20210827171534.62380-5-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-5-mark.kettenis@xs4all.nl>
Message-ID: <87pmtvcgec.wl-maz@kernel.org>

Hi Mark,

On Fri, 27 Aug 2021 18:15:29 +0100,
Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
> 
> From: Mark Kettenis <kettenis at openbsd.org>
> 
> Add node corresponding to the apcie,t8103 node in the
> Apple device tree for the Mac mini (M1, 2020).
> 
> Clock references and DART (IOMMU) references are left out at the
> moment and will be added once the appropriate bindings have been
> settled upon.
> 
> Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> ---
>  arch/arm64/boot/dts/apple/t8103.dtsi | 63 ++++++++++++++++++++++++++++
>  1 file changed, 63 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
> index 503a76fc30e6..6e4677bdef44 100644
> --- a/arch/arm64/boot/dts/apple/t8103.dtsi
> +++ b/arch/arm64/boot/dts/apple/t8103.dtsi
> @@ -214,5 +214,68 @@ pinctrl_smc: pinctrl at 23e820000 {
>  				     <AIC_IRQ 396 IRQ_TYPE_LEVEL_HIGH>,
>  				     <AIC_IRQ 397 IRQ_TYPE_LEVEL_HIGH>;
>  		};
> +
> +		pcie0: pcie at 690000000 {
> +			compatible = "apple,t8103-pcie", "apple,pcie";
> +			device_type = "pci";
> +
> +			reg = <0x6 0x90000000 0x0 0x1000000>,
> +			      <0x6 0x80000000 0x0 0x4000>,
> +			      <0x6 0x81000000 0x0 0x8000>,
> +			      <0x6 0x82000000 0x0 0x8000>,
> +			      <0x6 0x83000000 0x0 0x8000>;
> +			reg-names = "config", "rc", "port0", "port1", "port2";
> +
> +			interrupt-parent = <&aic>;
> +			interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
> +				     <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
> +				     <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
> +
> +			msi-controller;
> +			msi-parent = <&pcie0>;
> +			msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
> +
> +			bus-range = <0 3>;
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +			ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 0x0 0x20000000>,
> +				 <0x02000000 0x0 0xc0000000 0x6 0xc0000000 0x0 0x40000000>;
> +
> +			pinctrl-0 = <&pcie_pins>;
> +			pinctrl-names = "default";
> +
> +			pci at 0,0 {
> +				device_type = "pci";
> +				reg = <0x0 0x0 0x0 0x0 0x0>;
> +				reset-gpios = <&pinctrl_ap 152 0>;
> +				max-link-speed = <2>;
> +
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				ranges;
> +			};
> +
> +			pci at 1,0 {
> +				device_type = "pci";
> +				reg = <0x800 0x0 0x0 0x0 0x0>;
> +				reset-gpios = <&pinctrl_ap 153 0>;
> +				max-link-speed = <2>;
> +
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				ranges;
> +			};
> +
> +			pci at 2,0 {
> +				device_type = "pci";
> +				reg = <0x1000 0x0 0x0 0x0 0x0>;
> +				reset-gpios = <&pinctrl_ap 33 0>;
> +				max-link-speed = <1>;
> +
> +				#address-cells = <3>;
> +				#size-cells = <2>;
> +				ranges;
> +			};
> +		};
>  	};
>  };

I have now implemented the MSI change on the Linux driver side, and it
works nicely. So thumbs up from me on this front.

I am now looking at the interrupts provided by each port:
(1) a bunch of port-private interrupts (link up/down...)
(2) INTx interrupts

Given that the programming is per-port, I've implemented this as a
per-port interrupt controller.

(1) is dead easy to implement, and doesn't require any DT description.
(2) is unfortunately exposing the limits of my DT knowledge, and I'm
not clear how to model it. I came up with the following:

	port00: pci at 0,0 {
		device_type = "pci";
		reg = <0x0 0x0 0x0 0x0 0x0>;
		reset-gpios = <&pinctrl_ap 152 0>;
		max-link-speed = <2>;

		#address-cells = <3>;
		#size-cells = <2>;
		ranges;

		interrupt-controller;
		#interrupt-cells = <1>;
		interrupt-parent = <&port00>;
		interrupt-map-mask = <0 0 0 7>;
		interrupt-map = <0 0 0 1 &port00 0>,
				<0 0 0 2 &port00 1>,
				<0 0 0 3 &port00 2>,
				<0 0 0 4 &port00 3>;
	};

which vaguely seem to do the right thing for the devices behind root
ports, but doesn't seem to work for INTx generated by the root ports
themselves. Any clue? Alternatively, I could move it to something
global to the whole PCIe controller, but that doesn't seem completely
right.

It also begs the question whether the per-port interrupt to the AIC
should be moved into each root port, should my per-port approach hold
any water.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From baruch at tkos.co.il  Mon Aug 30 04:46:24 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 30 Aug 2021 14:46:24 +0300
Subject: [PATCH v8 1/4] dt-bindings: mfd: qcom,
 tcsr: document ipq6018 compatible
Message-ID: <5c95bcf62a9d08208a7da19f0b1cec0689502b9a.1630323987.git.baruch@tkos.co.il>

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/mfd/qcom,tcsr.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt b/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
index e90519d566a3..c5f4f0ddfcc3 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
+++ b/Documentation/devicetree/bindings/mfd/qcom,tcsr.txt
@@ -6,6 +6,7 @@ registers via syscon.
 
 Required properties:
 - compatible:	Should contain:
+		"qcom,tcsr-ipq6018", "syscon", "simple-mfd" for IPQ6018
 		"qcom,tcsr-ipq8064", "syscon" for IPQ8064
 		"qcom,tcsr-apq8064", "syscon" for APQ8064
 		"qcom,tcsr-msm8660", "syscon" for MSM8660
-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 04:46:27 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 30 Aug 2021 14:46:27 +0300
Subject: [PATCH v8 4/4] arm64: dts: ipq6018: add pwm node
In-Reply-To: <5c95bcf62a9d08208a7da19f0b1cec0689502b9a.1630323987.git.baruch@tkos.co.il>
References: <5c95bcf62a9d08208a7da19f0b1cec0689502b9a.1630323987.git.baruch@tkos.co.il>
Message-ID: <62647618ae756b233ab7365b731ed42c0650a90f.1630323987.git.baruch@tkos.co.il>

Describe the PWM block on IPQ6018.

The PWM is in the TCSR area. Make &tcsr "simple-mfd" compatible, and add
&pwm as child of &tcsr.

Add also ipq6018 specific compatible string.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v8:

  Add size cell to 'reg' (Rob)

v7:

  Use 'reg' instead of 'offset' (Rob)

  Add qcom,tcsr-ipq6018 (Rob)

  Drop clock-names (Bjorn)

v6:

  Make the PWM node child of TCSR (Rob Herring)

  Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)

v5: Use qcom,pwm-regs for TCSR phandle instead of direct regs

v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
---
 arch/arm64/boot/dts/qcom/ipq6018.dtsi | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index a31df7d154db..8e8f72d9c172 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -259,8 +259,20 @@ tcsr_mutex_regs: syscon at 1905000 {
 		};
 
 		tcsr: syscon at 1937000 {
-			compatible = "syscon";
+			compatible = "qcom,tcsr-ipq6018", "syscon", "simple-mfd";
 			reg = <0x0 0x01937000 0x0 0x21000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			pwm: pwm at a010 {
+				compatible = "qcom,ipq6018-pwm";
+				reg = <0xa010 0x20>;
+				clocks = <&gcc GCC_ADSS_PWM_CLK>;
+				assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
+				assigned-clock-rates = <100000000>;
+				#pwm-cells = <2>;
+				status = "disabled";
+			};
 		};
 
 		blsp_dma: dma-controller at 7884000 {
-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 04:46:25 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 30 Aug 2021 14:46:25 +0300
Subject: [PATCH v8 2/4] pwm: driver for qualcomm ipq6018 pwm block
In-Reply-To: <5c95bcf62a9d08208a7da19f0b1cec0689502b9a.1630323987.git.baruch@tkos.co.il>
References: <5c95bcf62a9d08208a7da19f0b1cec0689502b9a.1630323987.git.baruch@tkos.co.il>
Message-ID: <bdc61569e4068490f53f347dcf29ee9539a8bc0b.1630323987.git.baruch@tkos.co.il>

Driver for the PWM block in Qualcomm IPQ6018 line of SoCs. Based on
driver from downstream Codeaurora kernel tree. Removed support for older
(V1) variants because I have no access to that hardware.

Tested on IPQ6010 based hardware.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v7:

  Change 'offset' to 'reg' for the tcsr offset (Rob)

  Drop clock name; there is only one clock (Bjorn)

  Simplify probe failure code path (Bjorn)

v6:

Address Uwe Kleine-K?nig review comments:

  Drop IPQ_PWM_MAX_DEVICES

  Rely on assigned-clock-rates; drop IPQ_PWM_CLK_SRC_FREQ

  Simplify register offset calculation

  Calculate duty cycle more precisely

  Refuse to set inverted polarity

  Drop redundant IPQ_PWM_REG1_ENABLE bit clear

  Remove x1000 factor in pwm_div calculation, use rate directly, and round up

  Choose initial pre_div such that pwm_div < IPQ_PWM_MAX_DIV

  Ensure pre_div <= pwm_div

  Rename close_ to best_

  Explain in comment why effective_div doesn't overflow

  Limit pwm_div to IPQ_PWM_MAX_DIV - 1 to allow 100% duty cycle

  Disable clock only after pwmchip_remove()

  const pwm_ops

Other changes:

  Add missing linux/bitfield.h header include (kernel test robot)

  Adjust code for PWM device node under TCSR (Rob Herring)

v5:

Use &tcsr_q6 syscon to access registers (Bjorn Andersson)

Address Uwe Kleine-K?nig review comments:

  Implement .get_state()

  Add IPQ_PWM_ prefix to local macros

  Use GENMASK/BIT/FIELD_PREP for register fields access

  Make type of config_div_and_duty() parameters consistent

  Derive IPQ_PWM_MIN_PERIOD_NS from IPQ_PWM_CLK_SRC_FREQ

  Integrate enable/disable into config_div_and_duty() to save register read,
  and reduce frequency glitch on update

  Use min() instead of min_t()

  Fix comment format

  Use dev_err_probe() to indicate probe step failure

  Add missing clk_disable_unprepare() in .remove

  Don't set .owner

v4:

  Use div64_u64() to fix link for 32-bit targets ((kernel test robot
  <lkp at intel.com>, Uwe Kleine-K?nig)

v3:

  s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)

  Fix integer overflow on 32-bit targets (kernel test robot <lkp at intel.com>)

v2:

Address Uwe Kleine-K?nig review comments:

  Fix period calculation when out of range

  Don't set period larger than requested

  Remove PWM disable on configuration change

  Implement .apply instead of non-atomic .config/.enable/.disable

  Don't modify PWM on .request/.free

  Check pwm_div underflow

  Fix various code and comment formatting issues

Other changes:

  Use u64 divisor safe division

  Remove now empty .request/.free
---
 drivers/pwm/Kconfig   |  12 ++
 drivers/pwm/Makefile  |   1 +
 drivers/pwm/pwm-ipq.c | 275 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 288 insertions(+)
 create mode 100644 drivers/pwm/pwm-ipq.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index c76adedd58c9..08add845596f 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -260,6 +260,18 @@ config PWM_INTEL_LGM
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-intel-lgm.
 
+config PWM_IPQ
+	tristate "IPQ PWM support"
+	depends on ARCH_QCOM || COMPILE_TEST
+	depends on HAVE_CLK && HAS_IOMEM
+	help
+	  Generic PWM framework driver for IPQ PWM block which supports
+	  4 pwm channels. Each of the these channels can be configured
+	  independent of each other.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-ipq.
+
 config PWM_IQS620A
 	tristate "Azoteq IQS620A PWM support"
 	depends on MFD_IQS62X || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 708840b7fba8..7402feae4b36 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_PWM_IMX1)		+= pwm-imx1.o
 obj-$(CONFIG_PWM_IMX27)		+= pwm-imx27.o
 obj-$(CONFIG_PWM_IMX_TPM)	+= pwm-imx-tpm.o
 obj-$(CONFIG_PWM_INTEL_LGM)	+= pwm-intel-lgm.o
+obj-$(CONFIG_PWM_IPQ)		+= pwm-ipq.o
 obj-$(CONFIG_PWM_IQS620A)	+= pwm-iqs620a.o
 obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
 obj-$(CONFIG_PWM_KEEMBAY)	+= pwm-keembay.o
diff --git a/drivers/pwm/pwm-ipq.c b/drivers/pwm/pwm-ipq.c
new file mode 100644
index 000000000000..8405d0554951
--- /dev/null
+++ b/drivers/pwm/pwm-ipq.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
+/*
+ * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/math64.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/bitfield.h>
+
+/* The frequency range supported is 1 Hz to clock rate */
+#define IPQ_PWM_MAX_PERIOD_NS	((u64)NSEC_PER_SEC)
+
+/*
+ * The max value specified for each field is based on the number of bits
+ * in the pwm control register for that field
+ */
+#define IPQ_PWM_MAX_DIV		0xFFFF
+
+/*
+ * Two 32-bit registers for each PWM: REG0, and REG1.
+ * Base offset for PWM #i is at 8 * #i.
+ */
+#define IPQ_PWM_CFG_REG0 0 /*PWM_DIV PWM_HI*/
+#define IPQ_PWM_REG0_PWM_DIV		GENMASK(15, 0)
+#define IPQ_PWM_REG0_HI_DURATION	GENMASK(31, 16)
+
+#define IPQ_PWM_CFG_REG1 4 /*ENABLE UPDATE PWM_PRE_DIV*/
+#define IPQ_PWM_REG1_PRE_DIV		GENMASK(15, 0)
+/*
+ * Enable bit is set to enable output toggling in pwm device.
+ * Update bit is set to reflect the changed divider and high duration
+ * values in register.
+ */
+#define IPQ_PWM_REG1_UPDATE		BIT(30)
+#define IPQ_PWM_REG1_ENABLE		BIT(31)
+
+
+struct ipq_pwm_chip {
+	struct pwm_chip chip;
+	struct clk *clk;
+	struct regmap *regmap;
+	u32 regmap_off;
+};
+
+static struct ipq_pwm_chip *to_ipq_pwm_chip(struct pwm_chip *chip)
+{
+	return container_of(chip, struct ipq_pwm_chip, chip);
+}
+
+static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned reg)
+{
+	struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
+	unsigned int off = ipq_chip->regmap_off + 8 * pwm->hwpwm + reg;
+	unsigned int val;
+
+	regmap_read(ipq_chip->regmap, off, &val);
+
+	return val;
+}
+
+static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned reg,
+		unsigned val)
+{
+	struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip);
+	unsigned int off = ipq_chip->regmap_off + 8 * pwm->hwpwm + reg;
+
+	regmap_write(ipq_chip->regmap, off, val);
+}
+
+static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div,
+			unsigned int pwm_div, unsigned long rate, u64 duty_ns,
+			bool enable)
+{
+	unsigned long hi_dur;
+	unsigned long val = 0;
+
+	/*
+	 * high duration = pwm duty * (pwm div + 1)
+	 * pwm duty = duty_ns / period_ns
+	 */
+	hi_dur = div64_u64(duty_ns * rate, (pre_div + 1) * NSEC_PER_SEC);
+
+	val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
+		FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div);
+	ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG0, val);
+
+	val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div);
+	ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG1, val);
+
+	/* Enable needs a separate write to REG1 */
+	val |= IPQ_PWM_REG1_UPDATE;
+	if (enable)
+		val |= IPQ_PWM_REG1_ENABLE;
+	ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG1, val);
+}
+
+static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			 const struct pwm_state *state)
+{
+	struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip);
+	unsigned long freq;
+	unsigned int pre_div, pwm_div, best_pre_div, best_pwm_div;
+	long long diff;
+	unsigned long rate = clk_get_rate(ipq_chip->clk);
+	unsigned long min_diff = rate;
+	u64 period_ns, duty_ns;
+
+	if (state->polarity != PWM_POLARITY_NORMAL)
+		return -EINVAL;
+
+	if (state->period < div64_u64(NSEC_PER_SEC, rate))
+		return -ERANGE;
+
+	period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS);
+	duty_ns = min(state->duty_cycle, period_ns);
+
+	/* freq in Hz for period in nano second */
+	freq = div64_u64(NSEC_PER_SEC, period_ns);
+	best_pre_div = IPQ_PWM_MAX_DIV;
+	best_pwm_div = IPQ_PWM_MAX_DIV;
+	/* Initial pre_div value such that pwm_div < IPQ_PWM_MAX_DIV */
+	pre_div = DIV64_U64_ROUND_UP(period_ns * rate,
+			(u64)NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1));
+
+	for (; pre_div <= IPQ_PWM_MAX_DIV; pre_div++) {
+		pwm_div = DIV64_U64_ROUND_UP(period_ns * rate,
+				(u64)NSEC_PER_SEC * (pre_div + 1));
+		pwm_div--;
+
+		if (pre_div > pwm_div)
+			break;
+
+		/*
+		 * Make sure we can do 100% duty cycle where
+		 * hi_dur == pwm_div + 1
+		 */
+		if (pwm_div > IPQ_PWM_MAX_DIV - 1)
+			continue;
+
+		diff = ((uint64_t)freq * (pre_div + 1) * (pwm_div + 1))
+			- (uint64_t)rate;
+
+		if (diff < 0) /* period larger than requested */
+			continue;
+		if (diff == 0) { /* bingo */
+			best_pre_div = pre_div;
+			best_pwm_div = pwm_div;
+			break;
+		}
+		if (diff < min_diff) {
+			min_diff = diff;
+			best_pre_div = pre_div;
+			best_pwm_div = pwm_div;
+		}
+	}
+
+	/* config divider values for the closest possible frequency */
+	config_div_and_duty(pwm, best_pre_div, best_pwm_div,
+			    rate, duty_ns, state->enabled);
+
+	return 0;
+}
+
+static void ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+			      struct pwm_state *state)
+{
+	struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip);
+	unsigned long rate = clk_get_rate(ipq_chip->clk);
+	unsigned int pre_div, pwm_div, hi_dur;
+	u64 effective_div, hi_div;
+	u32 reg0, reg1;
+
+	reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_CFG_REG0);
+	reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_CFG_REG1);
+
+	state->polarity = PWM_POLARITY_NORMAL;
+	state->enabled = reg1 & IPQ_PWM_REG1_ENABLE;
+
+	pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0);
+	hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0);
+	pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1);
+
+	/* No overflow here, both pre_div and pwm_div <= 0xffff */
+	effective_div = (u64)(pre_div + 1) * (pwm_div + 1);
+	state->period = div64_u64(effective_div * NSEC_PER_SEC, rate);
+
+	hi_div = hi_dur * (pre_div + 1);
+	state->duty_cycle = div64_u64(hi_div * NSEC_PER_SEC, rate);
+}
+
+static const struct pwm_ops ipq_pwm_ops = {
+	.apply = ipq_pwm_apply,
+	.get_state = ipq_pwm_get_state,
+	.owner = THIS_MODULE,
+};
+
+static int ipq_pwm_probe(struct platform_device *pdev)
+{
+	struct ipq_pwm_chip *pwm;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
+	if (!pwm)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pwm);
+
+	pwm->regmap = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(pwm->regmap))
+		return dev_err_probe(dev, PTR_ERR(pwm->regmap),
+				"regs map failed");
+
+	ret = of_property_read_u32(dev->of_node, "reg", &pwm->regmap_off);
+	if (ret)
+		return dev_err_probe(dev, ret, "error reading 'reg'");
+
+	pwm->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(pwm->clk))
+		return dev_err_probe(dev, PTR_ERR(pwm->clk),
+				"failed to get clock");
+
+	ret = clk_prepare_enable(pwm->clk);
+	if (ret)
+		return dev_err_probe(dev, ret, "clock enable failed");
+
+	pwm->chip.dev = dev;
+	pwm->chip.ops = &ipq_pwm_ops;
+	pwm->chip.npwm = 4;
+
+	ret = pwmchip_add(&pwm->chip);
+	if (ret < 0) {
+		dev_err_probe(dev, ret, "pwmchip_add() failed\n");
+		clk_disable_unprepare(pwm->clk);
+	}
+
+	return ret;
+}
+
+static int ipq_pwm_remove(struct platform_device *pdev)
+{
+	struct ipq_pwm_chip *pwm = platform_get_drvdata(pdev);
+
+	pwmchip_remove(&pwm->chip);
+	clk_disable_unprepare(pwm->clk);
+
+	return 0;
+}
+
+static const struct of_device_id pwm_ipq_dt_match[] = {
+	{ .compatible = "qcom,ipq6018-pwm", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, pwm_ipq_dt_match);
+
+static struct platform_driver ipq_pwm_driver = {
+	.driver = {
+		.name = "ipq-pwm",
+		.of_match_table = pwm_ipq_dt_match,
+	},
+	.probe = ipq_pwm_probe,
+	.remove = ipq_pwm_remove,
+};
+
+module_platform_driver(ipq_pwm_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 04:46:26 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 30 Aug 2021 14:46:26 +0300
Subject: [PATCH v8 3/4] dt-bindings: pwm: add IPQ6018 binding
In-Reply-To: <5c95bcf62a9d08208a7da19f0b1cec0689502b9a.1630323987.git.baruch@tkos.co.il>
References: <5c95bcf62a9d08208a7da19f0b1cec0689502b9a.1630323987.git.baruch@tkos.co.il>
Message-ID: <8238dfb5d5e4a40a995f047db36d9a7240431de5.1630323987.git.baruch@tkos.co.il>

DT binding for the PWM block in Qualcomm IPQ6018 SoC.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
This series does not convert the TCSR binding documentation to YAML. As
a result, this commit adds new a dt_binding_check warning:

/example-0/syscon at 1937000: failed to match any schema with compatible: ['qcom,tcsr-ipq 6018', 'syscon', 'simple-mfd']

If that is a blocker to IPQ6018 PWM support, so be it. Patches will wait
for someone else to push them further.

v8:

  Add size cell to 'reg' (Rob)

v7:

  Use 'reg' instead of 'offset' (Rob)

  Drop 'clock-names' and 'assigned-clock*' (Bjorn)

  Use single cell address/size in example node (Bjorn)

  Move '#pwm-cells' lower in example node (Bjorn)

  List 'reg' as required

v6:

  Device node is child of TCSR; remove phandle (Rob Herring)

  Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)

v5: Use qcom,pwm-regs for phandle instead of direct regs (Bjorn
    Andersson, Kathiravan T)

v4: Update the binding example node as well (Rob Herring's bot)

v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)

v2: Make #pwm-cells const (Rob Herring)
---
 .../devicetree/bindings/pwm/ipq-pwm.yaml      | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/ipq-pwm.yaml

diff --git a/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml b/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
new file mode 100644
index 000000000000..96bc63e336bf
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/ipq-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm IPQ6018 PWM controller
+
+maintainers:
+  - Baruch Siach <baruch at tkos.co.il>
+
+properties:
+  "#pwm-cells":
+    const: 2
+
+  compatible:
+    const: qcom,ipq6018-pwm
+
+  reg:
+    description: Offset of PWM register in the TCSR block.
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#pwm-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-ipq6018.h>
+
+    tcsr: syscon at 1937000 {
+        compatible = "qcom,tcsr-ipq6018", "syscon", "simple-mfd";
+        reg = <0x01937000 0x21000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        pwm: pwm at a010 {
+            compatible = "qcom,ipq6018-pwm";
+            reg = <0xa010 0x20>;
+            clocks = <&gcc GCC_ADSS_PWM_CLK>;
+            assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
+            assigned-clock-rates = <100000000>;
+            #pwm-cells = <2>;
+        };
+    };
-- 
2.33.0



From sashal at kernel.org  Mon Aug 30 04:59:30 2021
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 30 Aug 2021 07:59:30 -0400
Subject: [PATCH AUTOSEL 5.13 02/14] reset: reset-zynqmp: Fixed the argument
 data type
In-Reply-To: <20210830115942.1017300-1-sashal@kernel.org>
References: <20210830115942.1017300-1-sashal@kernel.org>
Message-ID: <20210830115942.1017300-2-sashal@kernel.org>

From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>

[ Upstream commit ed104ca4bd9c405b41e968ad4ece51f6462e90b6 ]

This patch changes the data type of the variable 'val' from
int to u32.

Addresses-Coverity: argument of type "int *" is incompatible with parameter of type "u32 *"
Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
Link: https://lore.kernel.org/r/925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek at xilinx.com
Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/reset/reset-zynqmp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
index ebd433fa09dd..8c51768e9a72 100644
--- a/drivers/reset/reset-zynqmp.c
+++ b/drivers/reset/reset-zynqmp.c
@@ -53,7 +53,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
 			       unsigned long id)
 {
 	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
-	int val, err;
+	int err;
+	u32 val;
 
 	err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val);
 	if (err)
-- 
2.30.2



From sashal at kernel.org  Mon Aug 30 04:59:53 2021
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 30 Aug 2021 07:59:53 -0400
Subject: [PATCH AUTOSEL 5.10 02/11] reset: reset-zynqmp: Fixed the argument
 data type
In-Reply-To: <20210830120002.1017700-1-sashal@kernel.org>
References: <20210830120002.1017700-1-sashal@kernel.org>
Message-ID: <20210830120002.1017700-2-sashal@kernel.org>

From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>

[ Upstream commit ed104ca4bd9c405b41e968ad4ece51f6462e90b6 ]

This patch changes the data type of the variable 'val' from
int to u32.

Addresses-Coverity: argument of type "int *" is incompatible with parameter of type "u32 *"
Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
Link: https://lore.kernel.org/r/925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek at xilinx.com
Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/reset/reset-zynqmp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
index ebd433fa09dd..8c51768e9a72 100644
--- a/drivers/reset/reset-zynqmp.c
+++ b/drivers/reset/reset-zynqmp.c
@@ -53,7 +53,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
 			       unsigned long id)
 {
 	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
-	int val, err;
+	int err;
+	u32 val;
 
 	err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val);
 	if (err)
-- 
2.30.2



From sashal at kernel.org  Mon Aug 30 05:00:09 2021
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 30 Aug 2021 08:00:09 -0400
Subject: [PATCH AUTOSEL 5.4 02/10] reset: reset-zynqmp: Fixed the argument
 data type
In-Reply-To: <20210830120018.1017841-1-sashal@kernel.org>
References: <20210830120018.1017841-1-sashal@kernel.org>
Message-ID: <20210830120018.1017841-2-sashal@kernel.org>

From: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>

[ Upstream commit ed104ca4bd9c405b41e968ad4ece51f6462e90b6 ]

This patch changes the data type of the variable 'val' from
int to u32.

Addresses-Coverity: argument of type "int *" is incompatible with parameter of type "u32 *"
Signed-off-by: Sai Krishna Potthuri <lakshmi.sai.krishna.potthuri at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
Link: https://lore.kernel.org/r/925cebbe4eb73c7d0a536da204748d33c7100d8c.1624448778.git.michal.simek at xilinx.com
Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/reset/reset-zynqmp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c
index 99e75d92dada..8a7473b6ba58 100644
--- a/drivers/reset/reset-zynqmp.c
+++ b/drivers/reset/reset-zynqmp.c
@@ -46,7 +46,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev,
 			       unsigned long id)
 {
 	struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev);
-	int val, err;
+	int err;
+	u32 val;
 
 	err = priv->eemi_ops->reset_get_status(ZYNQMP_RESET_ID + id, &val);
 	if (err)
-- 
2.30.2



From lkp at intel.com  Mon Aug 30 05:00:35 2021
From: lkp at intel.com (kernel test robot)
Date: Mon, 30 Aug 2021 20:00:35 +0800
Subject: [xlnx:master 11382/12422] drivers/crypto/xilinx/zynqmp-sha.c:116:10:
 error: implicit declaration of function '__flush_cache_user_range';
 did you mean 'flush_icache_user_range'?
Message-ID: <202108302022.4wTx1Wqe-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   67d5e656238eddd8486cdf9a0632985aeeee7b51
commit: d6318539cfd551f6f99779da71e158353dcc00bf [11382/12422] crypto: zynqmp-sha: Adopted SHA3 support for ZynqMP Soc
config: sh-allmodconfig (attached as .config)
compiler: sh4-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/d6318539cfd551f6f99779da71e158353dcc00bf
        git remote add xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xlnx master
        git checkout d6318539cfd551f6f99779da71e158353dcc00bf
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=sh 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

Note: the xlnx/master HEAD 67d5e656238eddd8486cdf9a0632985aeeee7b51 builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   drivers/crypto/xilinx/zynqmp-sha.c: In function 'zynqmp_sha_update':
>> drivers/crypto/xilinx/zynqmp-sha.c:116:10: error: implicit declaration of function '__flush_cache_user_range'; did you mean 'flush_icache_user_range'? [-Werror=implicit-function-declaration]
     116 |          __flush_cache_user_range((unsigned long)kbuf,
         |          ^~~~~~~~~~~~~~~~~~~~~~~~
         |          flush_icache_user_range
   cc1: some warnings being treated as errors

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for SND_SOC_QDSP6
   Depends on SOUND && !UML && SND && SND_SOC && SND_SOC_QCOM && QCOM_APR && COMMON_CLK
   Selected by
   - SND_SOC_MSM8996 && SOUND && !UML && SND && SND_SOC && SND_SOC_QCOM && QCOM_APR
   WARNING: unmet direct dependencies detected for SND_ATMEL_SOC_PDC
   Depends on SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && HAS_DMA
   Selected by
   - SND_ATMEL_SOC_SSC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC
   - SND_ATMEL_SOC_SSC_PDC && SOUND && !UML && SND && SND_SOC && SND_ATMEL_SOC && ATMEL_SSC


vim +116 drivers/crypto/xilinx/zynqmp-sha.c

    98	
    99	static int zynqmp_sha_update(struct ahash_request *req)
   100	{
   101		struct zynqmp_sha_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
   102		struct zynqmp_sha_dev *dd = tctx->dd;
   103		char *kbuf;
   104		size_t dma_size = req->nbytes;
   105		dma_addr_t dma_addr;
   106		int ret;
   107	
   108		if (!req->nbytes)
   109			return 0;
   110	
   111		kbuf = dma_alloc_coherent(dd->dev, dma_size, &dma_addr, GFP_KERNEL);
   112		if (!kbuf)
   113			return -ENOMEM;
   114	
   115		scatterwalk_map_and_copy(kbuf, req->src, 0, req->nbytes, 0);
 > 116		 __flush_cache_user_range((unsigned long)kbuf,
   117					  (unsigned long)kbuf + dma_size);
   118		ret = zynqmp_pm_sha_hash(dma_addr, req->nbytes, ZYNQMP_SHA3_UPDATE); 
   119		dma_free_coherent(dd->dev, dma_size, kbuf, dma_addr);
   120	
   121		return ret;
   122	}
   123	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 53644 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210830/038f6c3b/attachment-0001.gz>

From jic23 at kernel.org  Mon Aug 30 05:18:29 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 30 Aug 2021 13:18:29 +0100
Subject: [PATCH v2 06/10] iio: adc: at91-sama5d2_adc: add helper for COR
 register
In-Reply-To: <20210824115441.681253-7-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
 <20210824115441.681253-7-eugen.hristev@microchip.com>
Message-ID: <20210830131829.782546eb@jic23-huawei>

On Tue, 24 Aug 2021 14:54:37 +0300
Eugen Hristev <eugen.hristev at microchip.com> wrote:

> Add helper for the COR register. This helper allows to modify the COR
> register, removes duplicate code and improves readability.
> The COR offset is now part of the register layout. This will allow
> different platform with a different offset to use the same helper.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
Nitpick inline.  If this is all I find in the series I'll tidy it up whilst
applying.

J

> ---
>  drivers/iio/adc/at91-sama5d2_adc.c | 40 +++++++++++++++---------------
>  1 file changed, 20 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 23be7cec063e..bb4e5e1e3ce4 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -151,8 +151,8 @@ struct at91_adc_reg_layout {
>  	u16				CGR;
>  /* Channel Offset Register */
>  	u16				COR;
> -#define AT91_SAMA5D2_COR_DIFF_OFFSET	16
> -
> +/* Channel Offset Register differential offset - constant, not a register */
> +	u16				COR_diff_offset;
>  /* Analog Control Register */
>  	u16				ACR;
>  /* Analog Control Register - Pen detect sensitivity mask */
> @@ -246,6 +246,7 @@ static const struct at91_adc_reg_layout sama5d2_layout = {
>  	.CWR =			0x44,
>  	.CGR =			0x48,
>  	.COR =			0x4c,
> +	.COR_diff_offset =	16,
>  	.ACR =			0x94,
>  	.TSMR =			0xb0,
>  	.XPOSR =		0xb4,
> @@ -589,6 +590,21 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>  	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
>  }
>  
> +static void at91_adc_cor(struct at91_adc_state *st,
> +			 struct iio_chan_spec const *chan)
> +{
> +	u32 cor, cur_cor;
> +
> +	cor = (BIT(chan->channel) | BIT(chan->channel2));

Excessive brackets.


> +
> +	cur_cor = at91_adc_readl(st, COR);
> +	cor <<= st->soc_info.platform->layout->COR_diff_offset;
> +	if (chan->differential)
> +		at91_adc_writel(st, COR, cur_cor | cor);
> +	else
> +		at91_adc_writel(st, COR, cur_cor & ~cor);
> +}
> +
>  static void at91_adc_irq_status(struct at91_adc_state *st, u32 *status,
>  				u32 *eoc)
>  {
> @@ -1033,8 +1049,6 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>  			 indio_dev->num_channels) {
>  		struct iio_chan_spec const *chan =
>  					at91_adc_chan_get(indio_dev, bit);
> -		u32 cor;
> -
>  		if (!chan)
>  			continue;
>  		/* these channel types cannot be handled by this trigger */
> @@ -1042,16 +1056,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>  		    chan->type == IIO_PRESSURE)
>  			continue;
>  
> -		cor = at91_adc_readl(st, COR);
> -
> -		if (chan->differential)
> -			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> -				AT91_SAMA5D2_COR_DIFF_OFFSET;
> -		else
> -			cor &= ~(BIT(chan->channel) <<
> -			       AT91_SAMA5D2_COR_DIFF_OFFSET);
> -
> -		at91_adc_writel(st, COR, cor);
> +		at91_adc_cor(st, chan);
>  
>  		at91_adc_writel(st, CHER, BIT(chan->channel));
>  	}
> @@ -1439,7 +1444,6 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>  				  struct iio_chan_spec const *chan, int *val)
>  {
>  	struct at91_adc_state *st = iio_priv(indio_dev);
> -	u32 cor = 0;
>  	u16 tmp_val;
>  	int ret;
>  
> @@ -1485,11 +1489,7 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>  
>  	st->chan = chan;
>  
> -	if (chan->differential)
> -		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
> -		      AT91_SAMA5D2_COR_DIFF_OFFSET;
> -
> -	at91_adc_writel(st, COR, cor);
> +	at91_adc_cor(st, chan);
>  	at91_adc_writel(st, CHER, BIT(chan->channel));
>  	at91_adc_eoc_ena(st, chan->channel);
>  	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);



From jic23 at kernel.org  Mon Aug 30 05:21:53 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 30 Aug 2021 13:21:53 +0100
Subject: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to
 platform specific data structures
In-Reply-To: <20210824115441.681253-5-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
 <20210824115441.681253-5-eugen.hristev@microchip.com>
Message-ID: <20210830132153.78f8dac5@jic23-huawei>

On Tue, 24 Aug 2021 14:54:35 +0300
Eugen Hristev <eugen.hristev at microchip.com> wrote:

> Convert the driver to platform specific structures. This means:
> - create a register layout struct that will hold offsets for registers
> - create a platform struct that will hold platform information (number of
> channels, indexes for different channels and pointer to layout struct)
> - convert specific macros that are platform dependent into platform variables
> 
> This step is in fact a no-op, but allows the driver to be more flexible
> and for future enhancement including adding new platforms that are partly
> compatible with the current driver and differ slightly in register layout
> or capabilities for example.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> ---
>  drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>  1 file changed, 247 insertions(+), 163 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 9d71dcffcf93..8ede18b8d789 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -27,8 +27,9 @@
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/regulator/consumer.h>
>  
> +struct at91_adc_reg_layout {
>  /* Control Register */
> -#define AT91_SAMA5D2_CR		0x00
> +	u16				CR;
>  /* Software Reset */
>  #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
>  /* Start Conversion */
> @@ -39,7 +40,7 @@
>  #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
>  
>  /* Mode Register */
> -#define AT91_SAMA5D2_MR		0x04
> +	u16				MR;
>  /* Trigger Selection */
>  #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
>  /* ADTRG */
> @@ -82,19 +83,19 @@
>  #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
>  
>  /* Channel Sequence Register 1 */
> -#define AT91_SAMA5D2_SEQR1	0x08
> +	u16				SEQR1;
>  /* Channel Sequence Register 2 */
> -#define AT91_SAMA5D2_SEQR2	0x0c
> +	u16				SEQR2;
>  /* Channel Enable Register */
> -#define AT91_SAMA5D2_CHER	0x10
> +	u16				CHER;
>  /* Channel Disable Register */
> -#define AT91_SAMA5D2_CHDR	0x14
> +	u16				CHDR;
>  /* Channel Status Register */
> -#define AT91_SAMA5D2_CHSR	0x18
> +	u16				CHSR;
>  /* Last Converted Data Register */
> -#define AT91_SAMA5D2_LCDR	0x20
> +	u16				LCDR;
>  /* Interrupt Enable Register */
> -#define AT91_SAMA5D2_IER	0x24
> +	u16				IER;
>  /* Interrupt Enable Register - TS X measurement ready */
>  #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>  /* Interrupt Enable Register - TS Y measurement ready */
> @@ -109,22 +110,23 @@
>  #define AT91_SAMA5D2_IER_PEN    BIT(29)
>  /* Interrupt Enable Register - No pen detect */
>  #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> +
>  /* Interrupt Disable Register */
> -#define AT91_SAMA5D2_IDR	0x28
> +	u16				IDR;
>  /* Interrupt Mask Register */
> -#define AT91_SAMA5D2_IMR	0x2c
> +	u16				IMR;
>  /* Interrupt Status Register */
> -#define AT91_SAMA5D2_ISR	0x30
> +	u16				ISR;
>  /* Interrupt Status Register - Pen touching sense status */
>  #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>  /* Last Channel Trigger Mode Register */
> -#define AT91_SAMA5D2_LCTMR	0x34
> +	u16				LCTMR;
>  /* Last Channel Compare Window Register */
> -#define AT91_SAMA5D2_LCCWR	0x38
> +	u16				LCCWR;
>  /* Overrun Status Register */
> -#define AT91_SAMA5D2_OVER	0x3c
> +	u16				OVER;
>  /* Extended Mode Register */
> -#define AT91_SAMA5D2_EMR	0x40
> +	u16				EMR;
>  /* Extended Mode Register - Oversampling rate */
>  #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
>  #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> @@ -134,22 +136,22 @@
>  
>  /* Extended Mode Register - Averaging on single trigger event */
>  #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> +
>  /* Compare Window Register */
> -#define AT91_SAMA5D2_CWR	0x44
> +	u16				CWR;
>  /* Channel Gain Register */
> -#define AT91_SAMA5D2_CGR	0x48
> -
> +	u16				CGR;
>  /* Channel Offset Register */
> -#define AT91_SAMA5D2_COR	0x4c
> +	u16				COR;
>  #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
>  
>  /* Analog Control Register */
> -#define AT91_SAMA5D2_ACR	0x94
> +	u16				ACR;
>  /* Analog Control Register - Pen detect sensitivity mask */
>  #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>  
>  /* Touchscreen Mode Register */
> -#define AT91_SAMA5D2_TSMR	0xb0
> +	u16				TSMR;
>  /* Touchscreen Mode Register - No touch mode */
>  #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>  /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> @@ -178,13 +180,13 @@
>  #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>  
>  /* Touchscreen X Position Register */
> -#define AT91_SAMA5D2_XPOSR	0xb4
> +	u16				XPOSR;
>  /* Touchscreen Y Position Register */
> -#define AT91_SAMA5D2_YPOSR	0xb8
> +	u16				YPOSR;
>  /* Touchscreen Pressure Register */
> -#define AT91_SAMA5D2_PRESSR	0xbc
> +	u16				PRESSR;
>  /* Trigger Register */
> -#define AT91_SAMA5D2_TRGR	0xc0
> +	u16				TRGR;
>  /* Mask for TRGMOD field of TRGR register */
>  #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>  /* No trigger, only software trigger can start conversions */
> @@ -203,30 +205,52 @@
>  #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>  
>  /* Correction Select Register */
> -#define AT91_SAMA5D2_COSR	0xd0
> +	u16				COSR;
>  /* Correction Value Register */
> -#define AT91_SAMA5D2_CVR	0xd4
> +	u16				CVR;
>  /* Channel Error Correction Register */
> -#define AT91_SAMA5D2_CECR	0xd8
> +	u16				CECR;
>  /* Write Protection Mode Register */
> -#define AT91_SAMA5D2_WPMR	0xe4
> +	u16				WPMR;
>  /* Write Protection Status Register */
> -#define AT91_SAMA5D2_WPSR	0xe8
> +	u16				WPSR;
>  /* Version Register */
> -#define AT91_SAMA5D2_VERSION	0xfc
> -
> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> -
> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> +	u16				VERSION;
> +};
>  
> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +static const struct at91_adc_reg_layout sama5d2_layout = {
> +	.CR =			0x00,
> +	.MR =			0x04,
> +	.SEQR1 =		0x08,
> +	.SEQR2 =		0x0c,
> +	.CHER =			0x10,
> +	.CHDR =			0x14,
> +	.CHSR =			0x18,
> +	.LCDR =			0x20,
> +	.IER =			0x24,
> +	.IDR =			0x28,
> +	.IMR =			0x2c,
> +	.ISR =			0x30,
> +	.LCTMR =		0x34,
> +	.LCCWR =		0x38,
> +	.OVER =			0x3c,
> +	.EMR =			0x40,
> +	.CWR =			0x44,
> +	.CGR =			0x48,
> +	.COR =			0x4c,
> +	.ACR =			0x94,
> +	.TSMR =			0xb0,
> +	.XPOSR =		0xb4,
> +	.YPOSR =		0xb8,
> +	.PRESSR =		0xbc,
> +	.TRGR =			0xc0,
> +	.COSR =			0xd0,
> +	.CVR =			0xd4,
> +	.CECR =			0xd8,
> +	.WPMR =			0xe4,
> +	.WPSR =			0xe8,
> +	.VERSION =		0xfc,
> +};
>  
>  #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>  #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> @@ -235,18 +259,6 @@
>  
>  #define AT91_SAMA5D2_MAX_POS_BITS			12
>  
> -/*
> - * Maximum number of bytes to hold conversion from all channels
> - * without the timestamp.
> - */
> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> -
> -/* This total must also include the timestamp */
> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> -
> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> -
>  #define AT91_HWFIFO_MAX_SIZE_STR	"128"
>  #define AT91_HWFIFO_MAX_SIZE		128
>  
> @@ -255,12 +267,12 @@
>  #define AT91_OSR_4SAMPLES		4
>  #define AT91_OSR_16SAMPLES		16
>  
> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
>  	{								\
>  		.type = IIO_VOLTAGE,					\
>  		.channel = num,						\
>  		.address = addr,					\
> -		.scan_index = num,					\
> +		.scan_index = index,					\
>  		.scan_type = {						\
>  			.sign = 'u',					\
>  			.realbits = 14,					\
> @@ -274,14 +286,14 @@
>  		.indexed = 1,						\
>  	}
>  
> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
>  	{								\
>  		.type = IIO_VOLTAGE,					\
>  		.differential = 1,					\
>  		.channel = num,						\
>  		.channel2 = num2,					\
>  		.address = addr,					\
> -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> +		.scan_index = index,					\
>  		.scan_type = {						\
>  			.sign = 's',					\
>  			.realbits = 14,					\
> @@ -328,13 +340,48 @@
>  		.datasheet_name = name,					\
>  	}
>  
> -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> +#define at91_adc_readl(st, reg)						\
> +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
I was a bit in two minds about whether this should be in capitals to make it clear
macro magic is going on, or whether lowercase is fine.  In the end I couldn't make
up my mind so will accept it like this! :)


Jonathan


From jic23 at kernel.org  Mon Aug 30 05:26:36 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 30 Aug 2021 13:26:36 +0100
Subject: [PATCH v2 00/10] iio: adc: at91-sama5d2_adc: add support for
 sama7g5
In-Reply-To: <20210824115441.681253-1-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
Message-ID: <20210830132636.16dde030@jic23-huawei>

On Tue, 24 Aug 2021 14:54:31 +0300
Eugen Hristev <eugen.hristev at microchip.com> wrote:

> Hi,
> 
> This series adds support for sama7g5.
> 
> The sama7g5 is slightly different from sama5d2, but has the same basic
> operations. The register map is a bit different, so, I added some primitives
> to differentiate between the two classes of hardware blocks (sama5d2-sam9x60
> and sama7g5).
> 
> Sama7g5 has 16 channels ADC, no resistive touch, and extra features
> (FIFOs, better oversampling , not implemented yet).
> 
> It is a rework of the series initially sent here:
> https://marc.info/?l=linux-iio&m=161461656807826&w=2
> 
> I reworked this according to review by Jonathan, meaning that first I created
> a no-op patch that will convert the driver to a more platform specific data
> dedicated type of driver. This adds various structures that hold things like
> register layout and channel information.
> After this I created few patches that implement the main differences between
> sama7g5 and older products: the end-of-conversion new register. I added
> helper functions to make code more easy to read and more simple.
> One the last patches adds the layout and channels for sama7g5.
> At this moment in linux-next, the DT for sama7g5 and sama7g5ek is present,
> and the last patches add and enable this node in DT for this board.
> 
> Eugen
0-8 applied with the minor tweak mentioned in a reply to relevant patch.

I'll assume 9-10 will got via normal soc related tree.

Note that I'm queuing these up for the merge window after this one now
(5.16).

Thanks,

Jonathan

> 
> 
> 
> Eugen Hristev (10):
>   dt-bindings: iio: adc: at91-sama5d2: add compatible for sama7g5-adc
>   iio: adc: at91-sama5d2_adc: initialize hardware after clock is started
>   iio: adc: at91-sama5d2_adc: remove unused definition
>   iio: adc: at91-sama5d2_adc: convert to platform specific data
>     structures
>   iio: adc: at91-sama5d2-adc: add support for separate end of conversion
>     registers
>   iio: adc: at91-sama5d2_adc: add helper for COR register
>   iio: adc: at91-sama5d2_adc: add support for sama7g5 device
>   iio: adc: at91-sama5d2_adc: update copyright and authors information
>   ARM: dts: at91: sama7g5: add node for the ADC
>   ARM: dts: at91: sama7g5ek: enable ADC on the board
> 
>  .../bindings/iio/adc/atmel,sama5d2-adc.yaml   |   1 +
>  arch/arm/boot/dts/at91-sama7g5ek.dts          |   8 +
>  arch/arm/boot/dts/sama7g5.dtsi                |  16 +
>  drivers/iio/adc/at91-sama5d2_adc.c            | 586 ++++++++++++------
>  4 files changed, 425 insertions(+), 186 deletions(-)
> 



From Eugen.Hristev at microchip.com  Mon Aug 30 05:28:27 2021
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Mon, 30 Aug 2021 12:28:27 +0000
Subject: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform
 specific data structures
In-Reply-To: <20210830132153.78f8dac5@jic23-huawei>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
 <20210824115441.681253-5-eugen.hristev@microchip.com>
 <20210830132153.78f8dac5@jic23-huawei>
Message-ID: <fa912a33-d264-f634-4f6b-ed17956a54c4@microchip.com>

On 8/30/21 3:21 PM, Jonathan Cameron wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Tue, 24 Aug 2021 14:54:35 +0300
> Eugen Hristev <eugen.hristev at microchip.com> wrote:
> 
>> Convert the driver to platform specific structures. This means:
>> - create a register layout struct that will hold offsets for registers
>> - create a platform struct that will hold platform information (number of
>> channels, indexes for different channels and pointer to layout struct)
>> - convert specific macros that are platform dependent into platform variables
>>
>> This step is in fact a no-op, but allows the driver to be more flexible
>> and for future enhancement including adding new platforms that are partly
>> compatible with the current driver and differ slightly in register layout
>> or capabilities for example.
>>
>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>> ---
>>   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>>   1 file changed, 247 insertions(+), 163 deletions(-)
>>
>> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
>> index 9d71dcffcf93..8ede18b8d789 100644
>> --- a/drivers/iio/adc/at91-sama5d2_adc.c
>> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
>> @@ -27,8 +27,9 @@
>>   #include <linux/pinctrl/consumer.h>
>>   #include <linux/regulator/consumer.h>
>>
>> +struct at91_adc_reg_layout {
>>   /* Control Register */
>> -#define AT91_SAMA5D2_CR              0x00
>> +     u16                             CR;
>>   /* Software Reset */
>>   #define      AT91_SAMA5D2_CR_SWRST           BIT(0)
>>   /* Start Conversion */
>> @@ -39,7 +40,7 @@
>>   #define      AT91_SAMA5D2_CR_CMPRST          BIT(4)
>>
>>   /* Mode Register */
>> -#define AT91_SAMA5D2_MR              0x04
>> +     u16                             MR;
>>   /* Trigger Selection */
>>   #define      AT91_SAMA5D2_MR_TRGSEL(v)       ((v) << 1)
>>   /* ADTRG */
>> @@ -82,19 +83,19 @@
>>   #define      AT91_SAMA5D2_MR_USEQ            BIT(31)
>>
>>   /* Channel Sequence Register 1 */
>> -#define AT91_SAMA5D2_SEQR1   0x08
>> +     u16                             SEQR1;
>>   /* Channel Sequence Register 2 */
>> -#define AT91_SAMA5D2_SEQR2   0x0c
>> +     u16                             SEQR2;
>>   /* Channel Enable Register */
>> -#define AT91_SAMA5D2_CHER    0x10
>> +     u16                             CHER;
>>   /* Channel Disable Register */
>> -#define AT91_SAMA5D2_CHDR    0x14
>> +     u16                             CHDR;
>>   /* Channel Status Register */
>> -#define AT91_SAMA5D2_CHSR    0x18
>> +     u16                             CHSR;
>>   /* Last Converted Data Register */
>> -#define AT91_SAMA5D2_LCDR    0x20
>> +     u16                             LCDR;
>>   /* Interrupt Enable Register */
>> -#define AT91_SAMA5D2_IER     0x24
>> +     u16                             IER;
>>   /* Interrupt Enable Register - TS X measurement ready */
>>   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>>   /* Interrupt Enable Register - TS Y measurement ready */
>> @@ -109,22 +110,23 @@
>>   #define AT91_SAMA5D2_IER_PEN    BIT(29)
>>   /* Interrupt Enable Register - No pen detect */
>>   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
>> +
>>   /* Interrupt Disable Register */
>> -#define AT91_SAMA5D2_IDR     0x28
>> +     u16                             IDR;
>>   /* Interrupt Mask Register */
>> -#define AT91_SAMA5D2_IMR     0x2c
>> +     u16                             IMR;
>>   /* Interrupt Status Register */
>> -#define AT91_SAMA5D2_ISR     0x30
>> +     u16                             ISR;
>>   /* Interrupt Status Register - Pen touching sense status */
>>   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>>   /* Last Channel Trigger Mode Register */
>> -#define AT91_SAMA5D2_LCTMR   0x34
>> +     u16                             LCTMR;
>>   /* Last Channel Compare Window Register */
>> -#define AT91_SAMA5D2_LCCWR   0x38
>> +     u16                             LCCWR;
>>   /* Overrun Status Register */
>> -#define AT91_SAMA5D2_OVER    0x3c
>> +     u16                             OVER;
>>   /* Extended Mode Register */
>> -#define AT91_SAMA5D2_EMR     0x40
>> +     u16                             EMR;
>>   /* Extended Mode Register - Oversampling rate */
>>   #define AT91_SAMA5D2_EMR_OSR(V)                      ((V) << 16)
>>   #define AT91_SAMA5D2_EMR_OSR_MASK            GENMASK(17, 16)
>> @@ -134,22 +136,22 @@
>>
>>   /* Extended Mode Register - Averaging on single trigger event */
>>   #define AT91_SAMA5D2_EMR_ASTE(V)             ((V) << 20)
>> +
>>   /* Compare Window Register */
>> -#define AT91_SAMA5D2_CWR     0x44
>> +     u16                             CWR;
>>   /* Channel Gain Register */
>> -#define AT91_SAMA5D2_CGR     0x48
>> -
>> +     u16                             CGR;
>>   /* Channel Offset Register */
>> -#define AT91_SAMA5D2_COR     0x4c
>> +     u16                             COR;
>>   #define AT91_SAMA5D2_COR_DIFF_OFFSET 16
>>
>>   /* Analog Control Register */
>> -#define AT91_SAMA5D2_ACR     0x94
>> +     u16                             ACR;
>>   /* Analog Control Register - Pen detect sensitivity mask */
>>   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>>
>>   /* Touchscreen Mode Register */
>> -#define AT91_SAMA5D2_TSMR    0xb0
>> +     u16                             TSMR;
>>   /* Touchscreen Mode Register - No touch mode */
>>   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>>   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
>> @@ -178,13 +180,13 @@
>>   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>>
>>   /* Touchscreen X Position Register */
>> -#define AT91_SAMA5D2_XPOSR   0xb4
>> +     u16                             XPOSR;
>>   /* Touchscreen Y Position Register */
>> -#define AT91_SAMA5D2_YPOSR   0xb8
>> +     u16                             YPOSR;
>>   /* Touchscreen Pressure Register */
>> -#define AT91_SAMA5D2_PRESSR  0xbc
>> +     u16                             PRESSR;
>>   /* Trigger Register */
>> -#define AT91_SAMA5D2_TRGR    0xc0
>> +     u16                             TRGR;
>>   /* Mask for TRGMOD field of TRGR register */
>>   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>>   /* No trigger, only software trigger can start conversions */
>> @@ -203,30 +205,52 @@
>>   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>>
>>   /* Correction Select Register */
>> -#define AT91_SAMA5D2_COSR    0xd0
>> +     u16                             COSR;
>>   /* Correction Value Register */
>> -#define AT91_SAMA5D2_CVR     0xd4
>> +     u16                             CVR;
>>   /* Channel Error Correction Register */
>> -#define AT91_SAMA5D2_CECR    0xd8
>> +     u16                             CECR;
>>   /* Write Protection Mode Register */
>> -#define AT91_SAMA5D2_WPMR    0xe4
>> +     u16                             WPMR;
>>   /* Write Protection Status Register */
>> -#define AT91_SAMA5D2_WPSR    0xe8
>> +     u16                             WPSR;
>>   /* Version Register */
>> -#define AT91_SAMA5D2_VERSION 0xfc
>> -
>> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
>> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
>> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
>> -
>> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
>> +     u16                             VERSION;
>> +};
>>
>> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
>> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
>> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
>> -#define AT91_SAMA5D2_MAX_CHAN_IDX    AT91_SAMA5D2_TOUCH_P_CHAN_IDX
>> +static const struct at91_adc_reg_layout sama5d2_layout = {
>> +     .CR =                   0x00,
>> +     .MR =                   0x04,
>> +     .SEQR1 =                0x08,
>> +     .SEQR2 =                0x0c,
>> +     .CHER =                 0x10,
>> +     .CHDR =                 0x14,
>> +     .CHSR =                 0x18,
>> +     .LCDR =                 0x20,
>> +     .IER =                  0x24,
>> +     .IDR =                  0x28,
>> +     .IMR =                  0x2c,
>> +     .ISR =                  0x30,
>> +     .LCTMR =                0x34,
>> +     .LCCWR =                0x38,
>> +     .OVER =                 0x3c,
>> +     .EMR =                  0x40,
>> +     .CWR =                  0x44,
>> +     .CGR =                  0x48,
>> +     .COR =                  0x4c,
>> +     .ACR =                  0x94,
>> +     .TSMR =                 0xb0,
>> +     .XPOSR =                0xb4,
>> +     .YPOSR =                0xb8,
>> +     .PRESSR =               0xbc,
>> +     .TRGR =                 0xc0,
>> +     .COSR =                 0xd0,
>> +     .CVR =                  0xd4,
>> +     .CECR =                 0xd8,
>> +     .WPMR =                 0xe4,
>> +     .WPSR =                 0xe8,
>> +     .VERSION =              0xfc,
>> +};
>>
>>   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>>   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
>> @@ -235,18 +259,6 @@
>>
>>   #define AT91_SAMA5D2_MAX_POS_BITS                    12
>>
>> -/*
>> - * Maximum number of bytes to hold conversion from all channels
>> - * without the timestamp.
>> - */
>> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>> -                                      AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
>> -
>> -/* This total must also include the timestamp */
>> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
>> -
>> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
>> -
>>   #define AT91_HWFIFO_MAX_SIZE_STR     "128"
>>   #define AT91_HWFIFO_MAX_SIZE         128
>>
>> @@ -255,12 +267,12 @@
>>   #define AT91_OSR_4SAMPLES            4
>>   #define AT91_OSR_16SAMPLES           16
>>
>> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)                          \
>> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)                   \
>>        {                                                               \
>>                .type = IIO_VOLTAGE,                                    \
>>                .channel = num,                                         \
>>                .address = addr,                                        \
>> -             .scan_index = num,                                      \
>> +             .scan_index = index,                                    \
>>                .scan_type = {                                          \
>>                        .sign = 'u',                                    \
>>                        .realbits = 14,                                 \
>> @@ -274,14 +286,14 @@
>>                .indexed = 1,                                           \
>>        }
>>
>> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)                              \
>> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)                       \
>>        {                                                               \
>>                .type = IIO_VOLTAGE,                                    \
>>                .differential = 1,                                      \
>>                .channel = num,                                         \
>>                .channel2 = num2,                                       \
>>                .address = addr,                                        \
>> -             .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,       \
>> +             .scan_index = index,                                    \
>>                .scan_type = {                                          \
>>                        .sign = 's',                                    \
>>                        .realbits = 14,                                 \
>> @@ -328,13 +340,48 @@
>>                .datasheet_name = name,                                 \
>>        }
>>
>> -#define at91_adc_readl(st, reg)              readl_relaxed(st->base + reg)
>> -#define at91_adc_writel(st, reg, val)        writel_relaxed(val, st->base + reg)
>> +#define at91_adc_readl(st, reg)                                              \
>> +     readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> I was a bit in two minds about whether this should be in capitals to make it clear
> macro magic is going on, or whether lowercase is fine.  In the end I couldn't make
> up my mind so will accept it like this! :)
> 
> 
> Jonathan
> 


I was doubting as well when I wrote this... but what convinced me was 
the much cleaner calls to the reg read and writes.
Has some drawbacks sometimes (like the XPOSR and YPOSR writes), but they 
are not all over the code, so I guess it's fine.

Thanks for reviewing !

From Eugen.Hristev at microchip.com  Mon Aug 30 05:31:46 2021
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Mon, 30 Aug 2021 12:31:46 +0000
Subject: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform
 specific data structures
In-Reply-To: <20210824115441.681253-5-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
 <20210824115441.681253-5-eugen.hristev@microchip.com>
Message-ID: <1688eb0e-5ea1-3bcc-3af0-7ba4c4601306@microchip.com>

On 8/24/21 2:54 PM, Eugen Hristev wrote:
> Convert the driver to platform specific structures. This means:
> - create a register layout struct that will hold offsets for registers
> - create a platform struct that will hold platform information (number of
> channels, indexes for different channels and pointer to layout struct)
> - convert specific macros that are platform dependent into platform variables
> 
> This step is in fact a no-op, but allows the driver to be more flexible
> and for future enhancement including adding new platforms that are partly
> compatible with the current driver and differ slightly in register layout
> or capabilities for example.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> ---
>   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>   1 file changed, 247 insertions(+), 163 deletions(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 9d71dcffcf93..8ede18b8d789 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -27,8 +27,9 @@
>   #include <linux/pinctrl/consumer.h>
>   #include <linux/regulator/consumer.h>
>   
> +struct at91_adc_reg_layout {
>   /* Control Register */
> -#define AT91_SAMA5D2_CR		0x00
> +	u16				CR;
>   /* Software Reset */
>   #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
>   /* Start Conversion */
> @@ -39,7 +40,7 @@
>   #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
>   
>   /* Mode Register */
> -#define AT91_SAMA5D2_MR		0x04
> +	u16				MR;
>   /* Trigger Selection */
>   #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
>   /* ADTRG */
> @@ -82,19 +83,19 @@
>   #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
>   
>   /* Channel Sequence Register 1 */
> -#define AT91_SAMA5D2_SEQR1	0x08
> +	u16				SEQR1;
>   /* Channel Sequence Register 2 */
> -#define AT91_SAMA5D2_SEQR2	0x0c
> +	u16				SEQR2;
>   /* Channel Enable Register */
> -#define AT91_SAMA5D2_CHER	0x10
> +	u16				CHER;
>   /* Channel Disable Register */
> -#define AT91_SAMA5D2_CHDR	0x14
> +	u16				CHDR;
>   /* Channel Status Register */
> -#define AT91_SAMA5D2_CHSR	0x18
> +	u16				CHSR;
>   /* Last Converted Data Register */
> -#define AT91_SAMA5D2_LCDR	0x20
> +	u16				LCDR;
>   /* Interrupt Enable Register */
> -#define AT91_SAMA5D2_IER	0x24
> +	u16				IER;
>   /* Interrupt Enable Register - TS X measurement ready */
>   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>   /* Interrupt Enable Register - TS Y measurement ready */
> @@ -109,22 +110,23 @@
>   #define AT91_SAMA5D2_IER_PEN    BIT(29)
>   /* Interrupt Enable Register - No pen detect */
>   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> +
>   /* Interrupt Disable Register */
> -#define AT91_SAMA5D2_IDR	0x28
> +	u16				IDR;
>   /* Interrupt Mask Register */
> -#define AT91_SAMA5D2_IMR	0x2c
> +	u16				IMR;
>   /* Interrupt Status Register */
> -#define AT91_SAMA5D2_ISR	0x30
> +	u16				ISR;
>   /* Interrupt Status Register - Pen touching sense status */
>   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>   /* Last Channel Trigger Mode Register */
> -#define AT91_SAMA5D2_LCTMR	0x34
> +	u16				LCTMR;
>   /* Last Channel Compare Window Register */
> -#define AT91_SAMA5D2_LCCWR	0x38
> +	u16				LCCWR;
>   /* Overrun Status Register */
> -#define AT91_SAMA5D2_OVER	0x3c
> +	u16				OVER;
>   /* Extended Mode Register */
> -#define AT91_SAMA5D2_EMR	0x40
> +	u16				EMR;
>   /* Extended Mode Register - Oversampling rate */
>   #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
>   #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> @@ -134,22 +136,22 @@
>   
>   /* Extended Mode Register - Averaging on single trigger event */
>   #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> +
>   /* Compare Window Register */
> -#define AT91_SAMA5D2_CWR	0x44
> +	u16				CWR;
>   /* Channel Gain Register */
> -#define AT91_SAMA5D2_CGR	0x48
> -
> +	u16				CGR;
>   /* Channel Offset Register */
> -#define AT91_SAMA5D2_COR	0x4c
> +	u16				COR;
>   #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
>   
>   /* Analog Control Register */
> -#define AT91_SAMA5D2_ACR	0x94
> +	u16				ACR;
>   /* Analog Control Register - Pen detect sensitivity mask */
>   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>   
>   /* Touchscreen Mode Register */
> -#define AT91_SAMA5D2_TSMR	0xb0
> +	u16				TSMR;
>   /* Touchscreen Mode Register - No touch mode */
>   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> @@ -178,13 +180,13 @@
>   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>   
>   /* Touchscreen X Position Register */
> -#define AT91_SAMA5D2_XPOSR	0xb4
> +	u16				XPOSR;
>   /* Touchscreen Y Position Register */
> -#define AT91_SAMA5D2_YPOSR	0xb8
> +	u16				YPOSR;
>   /* Touchscreen Pressure Register */
> -#define AT91_SAMA5D2_PRESSR	0xbc
> +	u16				PRESSR;
>   /* Trigger Register */
> -#define AT91_SAMA5D2_TRGR	0xc0
> +	u16				TRGR;
>   /* Mask for TRGMOD field of TRGR register */
>   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>   /* No trigger, only software trigger can start conversions */
> @@ -203,30 +205,52 @@
>   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>   
>   /* Correction Select Register */
> -#define AT91_SAMA5D2_COSR	0xd0
> +	u16				COSR;
>   /* Correction Value Register */
> -#define AT91_SAMA5D2_CVR	0xd4
> +	u16				CVR;
>   /* Channel Error Correction Register */
> -#define AT91_SAMA5D2_CECR	0xd8
> +	u16				CECR;
>   /* Write Protection Mode Register */
> -#define AT91_SAMA5D2_WPMR	0xe4
> +	u16				WPMR;
>   /* Write Protection Status Register */
> -#define AT91_SAMA5D2_WPSR	0xe8
> +	u16				WPSR;
>   /* Version Register */
> -#define AT91_SAMA5D2_VERSION	0xfc
> -
> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> -
> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> +	u16				VERSION;
> +};
>   
> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)

Hi Jonathan,

While we are here, regarding the above line, I cannot tell why did I 
multiply by two the differential channel count. This makes some gaps in 
the number of channels when we put them all in the same table.

I did not change this as it would break the ABI regarding the bindings 
for the touchscreen #adc-cells phandle references.

However, I am thinking if there was a reason for it or it was a slip 
when I initially wrote this.

Do you think there is any reason to change it and tighten the holes in 
the indexes list ?


Eugen

> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +static const struct at91_adc_reg_layout sama5d2_layout = {
> +	.CR =			0x00,
> +	.MR =			0x04,
> +	.SEQR1 =		0x08,
> +	.SEQR2 =		0x0c,
> +	.CHER =			0x10,
> +	.CHDR =			0x14,
> +	.CHSR =			0x18,
> +	.LCDR =			0x20,
> +	.IER =			0x24,
> +	.IDR =			0x28,
> +	.IMR =			0x2c,
> +	.ISR =			0x30,
> +	.LCTMR =		0x34,
> +	.LCCWR =		0x38,
> +	.OVER =			0x3c,
> +	.EMR =			0x40,
> +	.CWR =			0x44,
> +	.CGR =			0x48,
> +	.COR =			0x4c,
> +	.ACR =			0x94,
> +	.TSMR =			0xb0,
> +	.XPOSR =		0xb4,
> +	.YPOSR =		0xb8,
> +	.PRESSR =		0xbc,
> +	.TRGR =			0xc0,
> +	.COSR =			0xd0,
> +	.CVR =			0xd4,
> +	.CECR =			0xd8,
> +	.WPMR =			0xe4,
> +	.WPSR =			0xe8,
> +	.VERSION =		0xfc,
> +};
>   
>   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> @@ -235,18 +259,6 @@
>   
>   #define AT91_SAMA5D2_MAX_POS_BITS			12
>   
> -/*
> - * Maximum number of bytes to hold conversion from all channels
> - * without the timestamp.
> - */
> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> -
> -/* This total must also include the timestamp */
> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> -
> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> -
>   #define AT91_HWFIFO_MAX_SIZE_STR	"128"
>   #define AT91_HWFIFO_MAX_SIZE		128
>   
> @@ -255,12 +267,12 @@
>   #define AT91_OSR_4SAMPLES		4
>   #define AT91_OSR_16SAMPLES		16
>   
> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
>   	{								\
>   		.type = IIO_VOLTAGE,					\
>   		.channel = num,						\
>   		.address = addr,					\
> -		.scan_index = num,					\
> +		.scan_index = index,					\
>   		.scan_type = {						\
>   			.sign = 'u',					\
>   			.realbits = 14,					\
> @@ -274,14 +286,14 @@
>   		.indexed = 1,						\
>   	}
>   
> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
>   	{								\
>   		.type = IIO_VOLTAGE,					\
>   		.differential = 1,					\
>   		.channel = num,						\
>   		.channel2 = num2,					\
>   		.address = addr,					\
> -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> +		.scan_index = index,					\
>   		.scan_type = {						\
>   			.sign = 's',					\
>   			.realbits = 14,					\
> @@ -328,13 +340,48 @@
>   		.datasheet_name = name,					\
>   	}
>   
> -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> +#define at91_adc_readl(st, reg)						\
> +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> +#define at91_adc_read_chan(st, reg)					\
> +	readl_relaxed((st)->base + reg)
> +#define at91_adc_writel(st, reg, val)					\
> +	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
> +
> +/**
> + * struct at91_adc_platform - at91-sama5d2 platform information struct
> + * @layout:		pointer to the reg layout struct
> + * @adc_channels:	pointer to an array of channels for registering in
> + *			the iio subsystem
> + * @nr_channels:	number of physical channels available
> + * @touch_chan_x:	index of the touchscreen X channel
> + * @touch_chan_y:	index of the touchscreen Y channel
> + * @touch_chan_p:	index of the touchscreen P channel
> + * @max_channels:	number of total channels
> + * @hw_trig_cnt:	number of possible hardware triggers
> + */
> +struct at91_adc_platform {
> +	const struct at91_adc_reg_layout	*layout;
> +	const struct iio_chan_spec		(*adc_channels)[];
> +	unsigned int				nr_channels;
> +	unsigned int				touch_chan_x;
> +	unsigned int				touch_chan_y;
> +	unsigned int				touch_chan_p;
> +	unsigned int				max_channels;
> +	unsigned int				hw_trig_cnt;
> +};
>   
> +/**
> + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
> + * @startup_time:	device startup time
> + * @min_sample_rate:	minimum sample rate in Hz
> + * @max_sample_rate:	maximum sample rate in Hz
> + * @platform:		pointer to the platform structure
> + */
>   struct at91_adc_soc_info {
>   	unsigned			startup_time;
>   	unsigned			min_sample_rate;
>   	unsigned			max_sample_rate;
> +	const struct at91_adc_platform	*platform;
>   };
>   
>   struct at91_adc_trigger {
> @@ -382,6 +429,15 @@ struct at91_adc_touch {
>   	struct work_struct		workq;
>   };
>   
> +/*
> + * Buffer size requirements:
> + * No channels * bytes_per_channel(2) + timestamp bytes (8)
> + * Divided by 2 because we need half words.
> + * We assume 32 channels for now, has to be increased if needed.
> + * Nobody minds a buffer being too big.
> + */
> +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
> +
>   struct at91_adc_state {
>   	void __iomem			*base;
>   	int				irq;
> @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
>   	},
>   };
>   
> -static const struct iio_chan_spec at91_adc_channels[] = {
> -	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> -	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> -	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
> -	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
> -	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
> -	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
> -	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
> -	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
> -	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
> -	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
> -	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
> -	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
> -	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
> -	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
> -	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
> -	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> -	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> -	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
> -	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> -	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
> +	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
> +	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
> +	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
> +	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
> +	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
> +	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
> +	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
> +	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
> +	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
> +	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
> +	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
> +	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
> +	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
> +	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
> +	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
> +	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
> +	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
> +	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
> +	IIO_CHAN_SOFT_TIMESTAMP(18),
> +	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
> +	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
> +	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
> +};
> +
> +static const struct at91_adc_platform sama5d2_platform = {
> +	.layout = &sama5d2_layout,
> +	.adc_channels = &at91_sama5d2_adc_channels,
> +#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> +#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> +	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
> +		       AT91_SAMA5D2_DIFF_CHAN_CNT,
> +#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> +					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> +	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
> +#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> +	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
> +#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> +	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
> +#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> +	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
> +#define AT91_SAMA5D2_HW_TRIG_CNT	3
> +	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
>   };
>   
>   static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
> @@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>   {
>   	u32 mask = 0;
>   	u8 bit;
> +	struct at91_adc_state *st = iio_priv(indio_dev);
>   
>   	for_each_set_bit(bit, indio_dev->active_scan_mask,
>   			 indio_dev->num_channels) {
> @@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
>   		mask |= BIT(chan->channel);
>   	}
>   
> -	return mask & GENMASK(11, 0);
> +	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
>   }
>   
>   static void at91_adc_config_emr(struct at91_adc_state *st)
>   {
>   	/* configure the extended mode register */
> -	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
> +	unsigned int emr = at91_adc_readl(st, EMR);
>   
>   	/* select oversampling per single trigger event */
>   	emr |= AT91_SAMA5D2_EMR_ASTE(1);
> @@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
>   		break;
>   	}
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
> +	at91_adc_writel(st, EMR, emr);
>   }
>   
>   static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
> @@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
>   
>   	if (!state) {
>   		/* disabling touch IRQs and setting mode to no touch enabled */
> -		at91_adc_writel(st, AT91_SAMA5D2_IDR,
> +		at91_adc_writel(st, IDR,
>   				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
> -		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
> +		at91_adc_writel(st, TSMR, 0);
>   		return 0;
>   	}
>   	/*
> @@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
>   	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
>   	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
> +	at91_adc_writel(st, TSMR, tsmr);
>   
> -	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
> +	acr =  at91_adc_readl(st, ACR);
>   	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
>   	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> -	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
> +	at91_adc_writel(st, ACR, acr);
>   
>   	/* Sample Period Time = (TRGPER + 1) / ADCClock */
>   	st->touch_st.sample_period_val =
>   				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
>   				 clk_khz / 1000) - 1, 1);
>   	/* enable pen detect IRQ */
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
>   
>   	return 0;
>   }
> @@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
>   	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
>   	 */
>   	/* first half of register is the x or y, second half is the scale */
> -	val = at91_adc_readl(st, reg);
> +	if (reg == st->soc_info.platform->layout->XPOSR)
> +		val = at91_adc_readl(st, XPOSR);
> +	else if (reg == st->soc_info.platform->layout->YPOSR)
> +		val = at91_adc_readl(st, YPOSR);
> +
>   	if (!val)
>   		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
>   
> @@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
>   
>   static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
>   {
> -	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
> +	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
>   	return st->touch_st.x_pos;
>   }
>   
>   static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
>   {
> -	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
> +	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
>   }
>   
>   static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> @@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
>   	u32 factor = 1000;
>   
>   	/* calculate the pressure */
> -	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> +	val = at91_adc_readl(st, PRESSR);
>   	z1 = val & AT91_SAMA5D2_XYZ_MASK;
>   	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
>   
> @@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
>   	*val = 0;
>   	if (!st->touch_st.touching)
>   		return -ENODATA;
> -	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
> +	if (chan == st->soc_info.platform->touch_chan_x)
>   		*val = at91_adc_touch_x_pos(st);
> -	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
> +	else if (chan == st->soc_info.platform->touch_chan_y)
>   		*val = at91_adc_touch_y_pos(st);
>   	else
>   		return -ENODATA;
> @@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
>   	*val = 0;
>   	if (!st->touch_st.touching)
>   		return -ENODATA;
> -	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
> +	if (chan == st->soc_info.platform->touch_chan_y)
>   		*val = at91_adc_touch_pressure(st);
>   	else
>   		return -ENODATA;
> @@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
>   {
>   	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
>   	struct at91_adc_state *st = iio_priv(indio);
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
> +	u32 status = at91_adc_readl(st, TRGR);
>   
>   	/* clear TRGMOD */
>   	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
> @@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
>   		status |= st->selected_trig->trgmod_value;
>   
>   	/* set/unset hw trigger */
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
> +	at91_adc_writel(st, TRGR, status);
>   
>   	return 0;
>   }
> @@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
>   	enable_irq(st->irq);
>   
>   	/* Needed to ACK the DRDY interruption */
> -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> +	at91_adc_readl(st, LCDR);
>   }
>   
>   static const struct iio_trigger_ops at91_adc_trigger_ops = {
> @@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
>   	}
>   
>   	/* enable general overrun error signaling */
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
>   	/* Issue pending DMA requests */
>   	dma_async_issue_pending(st->dma_st.dma_chan);
>   
> @@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
>   
>   	return !!bitmap_subset(indio_dev->active_scan_mask,
>   			       &st->touch_st.channels_bitmask,
> -			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
> +			       st->soc_info.platform->max_channels + 1);
>   }
>   
>   static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> @@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>   		    chan->type == IIO_PRESSURE)
>   			continue;
>   
> -		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
> +		cor = at91_adc_readl(st, COR);
>   
>   		if (chan->differential)
>   			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> @@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
>   			cor &= ~(BIT(chan->channel) <<
>   			       AT91_SAMA5D2_COR_DIFF_OFFSET);
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> +		at91_adc_writel(st, COR, cor);
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> +		at91_adc_writel(st, CHER, BIT(chan->channel));
>   	}
>   
>   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> -		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
> +		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
>   
>   	return 0;
>   }
> @@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
>   		    chan->type == IIO_PRESSURE)
>   			continue;
>   
> -		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> +		at91_adc_writel(st, CHDR, BIT(chan->channel));
>   
>   		if (st->dma_st.dma_chan)
> -			at91_adc_readl(st, chan->address);
> +			at91_adc_read_chan(st, chan->address);
>   	}
>   
>   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> -		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
> +		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
>   
>   	/* read overflow register to clear possible overflow status */
> -	at91_adc_readl(st, AT91_SAMA5D2_OVER);
> +	at91_adc_readl(st, OVER);
>   
>   	/* if we are using DMA we must clear registers and end DMA */
>   	if (st->dma_st.dma_chan)
> @@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
>   	 * Check if the conversion is ready. If not, wait a little bit, and
>   	 * in case of timeout exit with an error.
>   	 */
> -	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
> +	while ((at91_adc_readl(st, ISR) & mask) != mask &&
>   	       timeout) {
>   		usleep_range(50, 100);
>   		timeout--;
> @@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
>   		 * Thus, emit a warning.
>   		 */
>   		if (chan->type == IIO_VOLTAGE) {
> -			val = at91_adc_readl(st, chan->address);
> +			val = at91_adc_read_chan(st, chan->address);
>   			at91_adc_adjust_val_osr(st, &val);
>   			st->buffer[i] = val;
>   		} else {
> @@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
>   	s64 interval;
>   	int sample_index = 0, sample_count, sample_size;
>   
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> +	u32 status = at91_adc_readl(st, ISR);
>   	/* if we reached this point, we cannot sample faster */
>   	if (status & AT91_SAMA5D2_IER_GOVRE)
>   		pr_info_ratelimited("%s: conversion overrun detected\n",
> @@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
>   	 * actually polling the trigger now.
>   	 */
>   	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
> -		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> +		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
>   
>   	if (st->dma_st.dma_chan)
>   		at91_adc_trigger_handler_dma(indio_dev);
> @@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
>   	startup = at91_adc_startup_time(st->soc_info.startup_time,
>   					freq / 1000);
>   
> -	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
> +	mr = at91_adc_readl(st, MR);
>   	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
>   	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
>   	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
> -	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
> +	at91_adc_writel(st, MR, mr);
>   
>   	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
>   		freq, startup, prescal);
> @@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
>   	int i = 0;
>   
>   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> -			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
> +			 st->soc_info.platform->max_channels + 1) {
>   		struct iio_chan_spec const *chan =
>   					 at91_adc_chan_get(indio_dev, bit);
>   
> @@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
>   
>   static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
>   {
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
> +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
>   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY);
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> -			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
>   			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
>   	st->touch_st.touching = true;
>   }
> @@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
>   {
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> -			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
> +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
>   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY);
>   	st->touch_st.touching = false;
>   
>   	at91_adc_touch_data_handler(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
>   }
>   
>   static void at91_adc_workq_handler(struct work_struct *workq)
> @@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   {
>   	struct iio_dev *indio = private;
>   	struct at91_adc_state *st = iio_priv(indio);
> -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> -	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
> +	u32 status = at91_adc_readl(st, ISR);
> +	u32 imr = at91_adc_readl(st, IMR);
>   	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
>   			AT91_SAMA5D2_IER_PRDY;
>   
> @@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   		 * touching, but the measurements are not ready yet.
>   		 * read and ignore.
>   		 */
> -		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
> -		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
> -		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> +		status = at91_adc_readl(st, XPOSR);
> +		status = at91_adc_readl(st, YPOSR);
> +		status = at91_adc_readl(st, PRESSR);
>   	} else if (iio_buffer_enabled(indio) &&
>   		   (status & AT91_SAMA5D2_IER_DRDY)) {
>   		/* triggered buffer without DMA */
> @@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
>   		WARN(true, "Unexpected irq occurred\n");
>   	} else if (!iio_buffer_enabled(indio)) {
>   		/* software requested conversion */
> -		st->conversion_value = at91_adc_readl(st, st->chan->address);
> +		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
>   		st->conversion_done = true;
>   		wake_up_interruptible(&st->wq_data_available);
>   	}
> @@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>   		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
>   		      AT91_SAMA5D2_COR_DIFF_OFFSET;
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> -	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> +	at91_adc_writel(st, COR, cor);
> +	at91_adc_writel(st, CHER, BIT(chan->channel));
> +	at91_adc_writel(st, IER, BIT(chan->channel));
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
>   
>   	ret = wait_event_interruptible_timeout(st->wq_data_available,
>   					       st->conversion_done,
> @@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
>   		st->conversion_done = false;
>   	}
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
> -	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> +	at91_adc_writel(st, IDR, BIT(chan->channel));
> +	at91_adc_writel(st, CHDR, BIT(chan->channel));
>   
>   	/* Needed to ACK the DRDY interruption */
> -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> +	at91_adc_readl(st, LCDR);
>   
>   	mutex_unlock(&st->lock);
>   
> @@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
>   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   	struct dma_slave_config config = {0};
> +	/* we have 2 bytes for each channel */
> +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
>   	/*
>   	 * We make the buffer double the size of the fifo,
>   	 * such that DMA uses one half of the buffer (full fifo size)
>   	 * and the software uses the other half to read/write.
>   	 */
>   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> -					  PAGE_SIZE);
> +					  sample_size * 2, PAGE_SIZE);
>   
>   	if (st->dma_st.dma_chan)
>   		return;
> @@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
>   	/* Configure DMA channel to read data register */
>   	config.direction = DMA_DEV_TO_MEM;
>   	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
> -			  + AT91_SAMA5D2_LCDR);
> +			  + st->soc_info.platform->layout->LCDR);
>   	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
>   	config.src_maxburst = 1;
>   	config.dst_maxburst = 1;
> @@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
>   {
>   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>   	struct at91_adc_state *st = iio_priv(indio_dev);
> +	/* we have 2 bytes for each channel */
> +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
>   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> -					  PAGE_SIZE);
> +					  sample_size * 2, PAGE_SIZE);
>   
>   	/* if we are not using DMA, just return */
>   	if (!st->dma_st.dma_chan)
> @@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
>   	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
> -			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> +			  st->soc_info.platform->max_channels + 1))
>   		return 0;
>   	/*
>   	 * if the new bitmap is a combination of touchscreen and regular
>   	 * channels, then we are not fine
>   	 */
>   	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
> -			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> +			      st->soc_info.platform->max_channels + 1))
>   		return -EINVAL;
>   	return 0;
>   }
> @@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
>   {
>   	struct at91_adc_state *st = iio_priv(indio_dev);
>   
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> -	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> +	at91_adc_writel(st, IDR, 0xffffffff);
>   	/*
>   	 * Transfer field must be set to 2 according to the datasheet and
>   	 * allows different analog settings for each channel.
>   	 */
> -	at91_adc_writel(st, AT91_SAMA5D2_MR,
> +	at91_adc_writel(st, MR,
>   			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
>   
>   	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
> @@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
>   	if (!indio_dev)
>   		return -ENOMEM;
>   
> +	st = iio_priv(indio_dev);
> +	st->indio_dev = indio_dev;
> +
> +	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
> +
>   	indio_dev->name = dev_name(&pdev->dev);
>   	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
>   	indio_dev->info = &at91_adc_info;
> -	indio_dev->channels = at91_adc_channels;
> -	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
> -
> -	st = iio_priv(indio_dev);
> -	st->indio_dev = indio_dev;
> +	indio_dev->channels = *st->soc_info.platform->adc_channels;
> +	indio_dev->num_channels = st->soc_info.platform->max_channels;
>   
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_x, 1);
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_y, 1);
>   	bitmap_set(&st->touch_st.channels_bitmask,
> -		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
> +		   st->soc_info.platform->touch_chan_p, 1);
>   
>   	st->oversampling_ratio = AT91_OSR_1SAMPLES;
>   
> @@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
>   	st->selected_trig = NULL;
>   
>   	/* find the right trigger, or no trigger at all */
> -	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
> +	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
>   		if (at91_adc_trigger_list[i].edge_type == edge_type) {
>   			st->selected_trig = &at91_adc_trigger_list[i];
>   			break;
> @@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
>   			 st->selected_trig->name);
>   
>   	dev_info(&pdev->dev, "version: %x\n",
> -		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
> +		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
>   
>   	return 0;
>   
> @@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
>   	 * and can be used by for other devices.
>   	 * Otherwise, ADC will hog them and we can't go to suspend mode.
>   	 */
> -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
>   
>   	clk_disable_unprepare(st->per_clk);
>   	regulator_disable(st->vref);
> @@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
>   static const struct of_device_id at91_adc_dt_match[] = {
>   	{
>   		.compatible = "atmel,sama5d2-adc",
> +		.data = (const void *)&sama5d2_platform,
>   	}, {
>   		/* sentinel */
>   	}
> 


From wangborong at cdjrlc.com  Mon Aug 30 05:31:28 2021
From: wangborong at cdjrlc.com (Jason Wang)
Date: Mon, 30 Aug 2021 20:31:28 +0800
Subject: [PATCH] ARM: OMAP2+: Fix comment typo
Message-ID: <20210830123128.9767-1-wangborong@cdjrlc.com>

Remove one of the repeated 'not' in three comments.

Signed-off-by: Jason Wang <wangborong at cdjrlc.com>
---
 arch/arm/mach-omap2/powerdomain.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 0a5b87e2a4b0..2d747f6cffe8 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -626,7 +626,7 @@ int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
  * powerdomain @pwrdm will enter when the powerdomain enters retention.
  * This will be either RETENTION or OFF, if supported.  Returns
  * -EINVAL if the powerdomain pointer is null or the target power
- * state is not not supported, or returns 0 upon success.
+ * state is not supported, or returns 0 upon success.
  */
 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
 {
@@ -658,7 +658,7 @@ int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
  * state.  @bank will be a number from 0 to 3, and represents different
  * types of memory, depending on the powerdomain.  Returns -EINVAL if
  * the powerdomain pointer is null or the target power state is not
- * not supported for this memory bank, -EEXIST if the target memory
+ * supported for this memory bank, -EEXIST if the target memory
  * bank does not exist or is not controllable, or returns 0 upon
  * success.
  */
@@ -696,7 +696,7 @@ int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
  * different types of memory, depending on the powerdomain.  @pwrst
  * will be either RETENTION or OFF, if supported.  Returns -EINVAL if
  * the powerdomain pointer is null or the target power state is not
- * not supported for this memory bank, -EEXIST if the target memory
+ * supported for this memory bank, -EEXIST if the target memory
  * bank does not exist or is not controllable, or returns 0 upon
  * success.
  */
-- 
2.33.0



From robh+dt at kernel.org  Mon Aug 30 05:35:51 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 07:35:51 -0500
Subject: [PATCH v5 07/11] dt-bindings: mediatek: mt8195: add audio afe
 document
In-Reply-To: <20210819084144.18483-8-trevor.wu@mediatek.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
 <20210819084144.18483-8-trevor.wu@mediatek.com>
Message-ID: <CAL_Jsq+bLVLqqVKfYuXDVYexMojMgZ5p34Pcx7_7LwU40b-2dA@mail.gmail.com>

On Thu, Aug 19, 2021 at 3:43 AM Trevor Wu <trevor.wu at mediatek.com> wrote:
>
> This patch adds mt8195 audio afe document.
>
> In order to support dynamic clock reparenting for ADDA and ETDM, PLL
> and MUX clocks are requested even though they are not consumed by afe
> directly.
>
> Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
> ---
> This patch depends on the following series that have not been accepted.
>
> [1] Mediatek MT8195 clock support
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=501923
> (dt-bindings/clock/mt8195-clk.h is included)

This dependency is still not applied, so the example fails. One of the
following needs to happen: the dependency needs to be applied, this
patch reverted, or drop the use of the defines in the example.

Rob


From robh at kernel.org  Mon Aug 30 06:39:47 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 08:39:47 -0500
Subject: [PATCH] ARM: dts: bcm2711-rpi-4-b: Fix pcie0's unit address
In-Reply-To: <20210830103909.323356-1-nsaenzju@redhat.com>
References: <20210830103909.323356-1-nsaenzju@redhat.com>
Message-ID: <YSzfoyesEzAuLkSS@robh.at.kernel.org>

On Mon, Aug 30, 2021 at 12:39:09PM +0200, Nicolas Saenz Julienne wrote:
> dtbs_check currently complains that:
> 
> arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning
> (pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format
> error, expected "0,0"
> 
> Unsurprisingly pci at 0,0 is the right address, as illustrated by its reg
> property:
> 
> 	&pcie0 {
> 		pci at 0,0 {
> 			/*
> 			 * As defined in the IEEE Std 1275-1994 document,
> 			 * reg is a five-cell address encoded as (phys.hi
> 			 * phys.mid phys.lo size.hi size.lo). phys.hi
> 			 * should contain the device's BDF as 0b00000000
> 			 * bbbbbbbb dddddfff 00000000. The other cells
> 			 * should be zero.
> 			 */
> 			reg = <0 0 0 0 0>;
> 		};
> 	};
> 
> The bus is clearly 0. So fix it.

s/bus/device/

The unit-address format is '<device>,<function>' (and function is 
optional). The bus number is not part of the unit-address because that 
is dynamic and then the path would not be fixed/known. The bus is part 
of 'reg' for true OpenFirmware, but for FDT I think it should always be 
0 as the DT is static. 

Looks like the child node is wrong (both unit-address and reg) as well:

                usb at 1,0 {
                        reg = <0x10000 0 0 0 0>;
                        resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
                };

It doesn't warn because the bridge node is also missing 'device_type = 
"pci";'.

This is all fairly hard to get right (see recent hikey970 patches for a 
complex example). I'm thinking about writing a tool that generates a DT 
with PCI nodes by reading the PCI hierachy from sysfs.

Rob


From ulf.hansson at linaro.org  Mon Aug 30 06:43:38 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 30 Aug 2021 15:43:38 +0200
Subject: Question about MMC_PM_KEEP_POWER in MMCI driver
In-Reply-To: <ccb2dad1-c8c1-9f19-92c4-7faf2b787e6d@foss.st.com>
References: <ccb2dad1-c8c1-9f19-92c4-7faf2b787e6d@foss.st.com>
Message-ID: <CAPDyKFqMJmJRLNYF=gWvAEH8wtJzrxrZ9KLz62t4XNsD84vr=Q@mail.gmail.com>

On Wed, 25 Aug 2021 at 16:34, Yann Gautier <yann.gautier at foss.st.com> wrote:
>
> Hi,
>
> In drivers/mmc/host/mmci.c, MMC_PM_KEEP_POWER is unconditionally enabled.
> This prevents correct low-power sequence on STM32MP157C-DK2 board which
> embeds a Wifi chip brcm,bcm4329-fmac (this wifi part has not yet been
> sent upstream).

Exactly why doesn't this work with the STM32MP157C-DK2 board?

>
> This MMC_PM_KEEP_POWER can be taken from DT with the property
> keep-power-in-suspend. This is what is done for other MMC drivers.

The DT property is what should have been used for mmci as well.

>
> I wonder what should be the best solution for this.
>
> 1) Remove MMC_PM_KEEP_POWER from the driver, and modify all SoC device
> tree files embedding a arm,pl18x with adding keep-power-in-suspend;
> property (except stm32mp151.dtsi file).
> This can be easy to do (~10 files to modify). But that could be more
> board dependent, if an SDIO chip is plugged on this MMC IP.
> And the name keep-power-in-suspend can be misleading as it only applies
> to SDIO.
>
> 2) Remove MMC_PM_KEEP_POWER from the driver, and modify board DT files
> with the property. This could be a difficult task to find all those
> boards. And this should be applied only for SDIO configs.
>
> 3) Just modify the driver to apply this capability for all MMCI chips
> but STM32. This could be done in the dedicated file, in
> sdmmc_variant_init() function. But some boards based on STM32MP15 chip
> might want to keep this capability.

I would suggest option 3).

As a matter of fact, we also allow MMC_PM_KEEP_POWER to become set
when parsing the DTB via calling mmc_of_parse(). So just changing the
default value (don't set MMC_PM_KEEP_POWER) for the stm32 variant,
would do the trick I think.

Kind regards
Uffe


From ardb at kernel.org  Mon Aug 30 06:48:04 2021
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 30 Aug 2021 15:48:04 +0200
Subject: [PATCH v7 0/7] running kernel mode SIMD with softirqs disabled
In-Reply-To: <20210830062634.GA30356@gondor.apana.org.au>
References: <20210827070342.218276-1-ardb@kernel.org>
 <CAMj1kXEUbPMadj1J7MWD_B-=2zRc2ir_zZQN3Puz3n+PjQw58Q@mail.gmail.com>
 <20210830062634.GA30356@gondor.apana.org.au>
Message-ID: <CAMj1kXHa-iSm+=N+kQT9_qmT3=Tp7b1Xpk1T7Rzns+hf2SNoxg@mail.gmail.com>

On Mon, 30 Aug 2021 at 08:26, Herbert Xu <herbert at gondor.apana.org.au> wrote:
>
> On Sun, Aug 29, 2021 at 08:35:37AM +0200, Ard Biesheuvel wrote:
> >
> > Any chance we could get this queued for v5.15? If it's too late,
> > please consider taking only the first three patches as an alternative,
> > and I will resend the CCM ones for v5.16 once they have all been
> > reviewed.
>
> Sorry, it's too late for that.  If these are to serve as dependencies
> for other work, perhaps you can just add my acks to them and
> submit them to the trees where they are needed?
>

Fair enough. It would be nice to get rid of the crypto_simd dependency
at least for the aes-ce driver, but I might propose it as a backport
once it hits mainline.

Thanks,
Ard.


From punitagrawal at gmail.com  Mon Aug 30 06:49:32 2021
From: punitagrawal at gmail.com (Punit Agrawal)
Date: Mon, 30 Aug 2021 22:49:32 +0900
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <568a0825-ed65-58d7-9c9c-cecb481cf9d9@wolfvision.net> (Michael
 Riesch's message of "Mon, 30 Aug 2021 09:57:51 +0200")
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
 <CAGb2v67Duk_56fOKVwZsYn2HKJ99o8WJ+d4jetD2UjDsAt9BcA@mail.gmail.com>
 <568a0825-ed65-58d7-9c9c-cecb481cf9d9@wolfvision.net>
Message-ID: <87czpvcaab.fsf@stealth>

Hi Michael,

Michael Riesch <michael.riesch at wolfvision.net> writes:

> Hi ChenYu,
>
> On 8/29/21 7:48 PM, Chen-Yu Tsai wrote:
>> Hi,
>> 
>> On Mon, Aug 23, 2021 at 10:39 PM Michael Riesch
>> <michael.riesch at wolfvision.net> wrote:
>>>
>>> This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
>>> "net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
>>> unbalanced pm_runtime_enable warnings.
>>>
>>> In the commit to be reverted, support for power management was
>>> introduced to the Rockchip glue code. Later, power management support
>>> was introduced to the stmmac core code, resulting in multiple
>>> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
>>>
>>> The multiple invocations happen in rk_gmac_powerup and
>>> stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
>>> stmmac_{dvr_remove, suspend}, respectively, which are always called
>>> in conjunction.
>>>
>>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>> 
>> I just found that Ethernet stopped working on my RK3399 devices,
>> and I bisected it down to this patch.
>
> Oh dear. First patch in a kernel release for a while and I already break
> things.

I am seeing the same failure symptoms reported by ChenYu on my RockPro64
with v5.14. Reverting the revert i.e., 2d26f6e39afb ("net: stmmac:
dwmac-rk: fix unbalanced pm_runtime_enable warnings") brings back the
network.

> Cc: Sasha as this patch has just been applied to 5.13-stable.
>
>> The symptom I see is no DHCP responses, either because the request
>> isn't getting sent over the wire, or the response isn't getting
>> received. The PHY seems to be working correctly.
>
> Unfortunately I don't have any RK3399 hardware. Is this a custom
> board/special hardware or something that is readily available in the
> shops? Maybe this is a good reason to buy a RK3399 based single-board
> computer :-)

Not sure about the other RK3399 boards but RockPro64 is easily
available.

> I am working on the RK3568 EVB1 and have not encountered faulty
> behavior. DHCP works fine and I can boot via NFS. Therefore, not sure
> whether I can be much of help in this matter, but in case you want to
> discuss this further please do not hesitate to contact me off-list.

I tried to look for the differences between RK3568 and RK3399 but the
upstream device tree doesn't seem to carry a gmac node in the device
tree for EK3568 EVB1. Do you have a pointer for the dts you're using?

Also, other than the warning "Unbalanced pm_runtime_enable!" do you
notice any other ill-effects without your patch?

If this affects all RK3399 boards as ChenYu suggests quite a few users
are going to miss the network once they upgrade.

Punit

[...]



From nsaenzju at redhat.com  Mon Aug 30 06:52:54 2021
From: nsaenzju at redhat.com (nsaenzju at redhat.com)
Date: Mon, 30 Aug 2021 15:52:54 +0200
Subject: [PATCH] ARM: dts: bcm2711-rpi-4-b: Fix pcie0's unit address
In-Reply-To: <YSzfoyesEzAuLkSS@robh.at.kernel.org>
References: <20210830103909.323356-1-nsaenzju@redhat.com>
 <YSzfoyesEzAuLkSS@robh.at.kernel.org>
Message-ID: <e1ca1f086c180f04044996ccf59981d59fbdbc6b.camel@redhat.com>

On Mon, 2021-08-30 at 08:39 -0500, Rob Herring wrote:
> On Mon, Aug 30, 2021 at 12:39:09PM +0200, Nicolas Saenz Julienne wrote:
> > dtbs_check currently complains that:
> > 
> > arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning
> > (pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format
> > error, expected "0,0"
> > 
> > Unsurprisingly pci at 0,0 is the right address, as illustrated by its reg
> > property:
> > 
> > 	&pcie0 {
> > 		pci at 0,0 {
> > 			/*
> > 			 * As defined in the IEEE Std 1275-1994 document,
> > 			 * reg is a five-cell address encoded as (phys.hi
> > 			 * phys.mid phys.lo size.hi size.lo). phys.hi
> > 			 * should contain the device's BDF as 0b00000000
> > 			 * bbbbbbbb dddddfff 00000000. The other cells
> > 			 * should be zero.
> > 			 */
> > 			reg = <0 0 0 0 0>;
> > 		};
> > 	};
> > 
> > The bus is clearly 0. So fix it.
> 
> s/bus/device/
> 
> The unit-address format is '<device>,<function>' (and function is 
> optional). The bus number is not part of the unit-address because that 
> is dynamic and then the path would not be fixed/known. The bus is part 
> of 'reg' for true OpenFirmware, but for FDT I think it should always be 
> 0 as the DT is static. 
> 
> Looks like the child node is wrong (both unit-address and reg) as well:
> 
>                 usb at 1,0 {
>                         reg = <0x10000 0 0 0 0>;
>                         resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
>                 };
> 
> It doesn't warn because the bridge node is also missing 'device_type = 
> "pci";'.
> 
> This is all fairly hard to get right (see recent hikey970 patches for a 
> complex example). I'm thinking about writing a tool that generates a DT 
> with PCI nodes by reading the PCI hierachy from sysfs.

Thanks for the review, I'll fix all those. That tool would be very helpful.

-- 
Nicol?s S?enz



From michael.riesch at wolfvision.net  Mon Aug 30 07:10:46 2021
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 30 Aug 2021 16:10:46 +0200
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <87czpvcaab.fsf@stealth>
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
 <CAGb2v67Duk_56fOKVwZsYn2HKJ99o8WJ+d4jetD2UjDsAt9BcA@mail.gmail.com>
 <568a0825-ed65-58d7-9c9c-cecb481cf9d9@wolfvision.net>
 <87czpvcaab.fsf@stealth>
Message-ID: <aa905e4d-c5a7-e969-1171-3a90ecd9b9cc@wolfvision.net>

Hi Punit,

On 8/30/21 3:49 PM, Punit Agrawal wrote:
> Hi Michael,
> 
> Michael Riesch <michael.riesch at wolfvision.net> writes:
> 
>> Hi ChenYu,
>>
>> On 8/29/21 7:48 PM, Chen-Yu Tsai wrote:
>>> Hi,
>>>
>>> On Mon, Aug 23, 2021 at 10:39 PM Michael Riesch
>>> <michael.riesch at wolfvision.net> wrote:
>>>>
>>>> This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
>>>> "net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
>>>> unbalanced pm_runtime_enable warnings.
>>>>
>>>> In the commit to be reverted, support for power management was
>>>> introduced to the Rockchip glue code. Later, power management support
>>>> was introduced to the stmmac core code, resulting in multiple
>>>> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
>>>>
>>>> The multiple invocations happen in rk_gmac_powerup and
>>>> stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
>>>> stmmac_{dvr_remove, suspend}, respectively, which are always called
>>>> in conjunction.
>>>>
>>>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>>>
>>> I just found that Ethernet stopped working on my RK3399 devices,
>>> and I bisected it down to this patch.
>>
>> Oh dear. First patch in a kernel release for a while and I already break
>> things.
> 
> I am seeing the same failure symptoms reported by ChenYu on my RockPro64
> with v5.14. Reverting the revert i.e., 2d26f6e39afb ("net: stmmac:
> dwmac-rk: fix unbalanced pm_runtime_enable warnings") brings back the
> network.
> 
>> Cc: Sasha as this patch has just been applied to 5.13-stable.
>>
>>> The symptom I see is no DHCP responses, either because the request
>>> isn't getting sent over the wire, or the response isn't getting
>>> received. The PHY seems to be working correctly.
>>
>> Unfortunately I don't have any RK3399 hardware. Is this a custom
>> board/special hardware or something that is readily available in the
>> shops? Maybe this is a good reason to buy a RK3399 based single-board
>> computer :-)
> 
> Not sure about the other RK3399 boards but RockPro64 is easily
> available.

I was thinking to get one of those anyway ;-)

>> I am working on the RK3568 EVB1 and have not encountered faulty
>> behavior. DHCP works fine and I can boot via NFS. Therefore, not sure
>> whether I can be much of help in this matter, but in case you want to
>> discuss this further please do not hesitate to contact me off-list.
> 
> I tried to look for the differences between RK3568 and RK3399 but the
> upstream device tree doesn't seem to carry a gmac node in the device
> tree for EK3568 EVB1. Do you have a pointer for the dts you're using?

The gmac nodes have been added recently and should enter 5.15-rc1. Until
then, you can check out the dts from linux-rockchip/for-next [0].

> Also, other than the warning "Unbalanced pm_runtime_enable!" do you
> notice any other ill-effects without your patch?

No, not as such.

Best regards,
Michael

> If this affects all RK3399 boards as ChenYu suggests quite a few users
> are going to miss the network once they upgrade.>
> Punit
> 
> [...]
> 

[0]
https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/log/?h=for-next


From heiko at sntech.de  Mon Aug 30 07:13:17 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 30 Aug 2021 16:13:17 +0200
Subject: [PATCH 1/2] arm64: dts: rockchip: add isp node for px30
Message-ID: <20210830141318.66744-1-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at theobroma-systems.com>

Add the rkisp1 node and iommu for the px30 soc.

Signed-off-by: Heiko Stuebner <heiko.stuebner at theobroma-systems.com>
---
 arch/arm64/boot/dts/rockchip/px30.dtsi | 41 ++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index 64f643145688..500ef3af2a49 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -1189,6 +1189,47 @@ vopl_mmu: iommu at ff470f00 {
 		status = "disabled";
 	};
 
+	isp: isp at ff4a0000 {
+		compatible = "rockchip,px30-cif-isp"; /*rk3326-rkisp1*/
+		reg = <0x0 0xff4a0000 0x0 0x8000>;
+		interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "isp", "mi", "mipi";
+		clocks = <&cru SCLK_ISP>,
+			 <&cru ACLK_ISP>,
+			 <&cru HCLK_ISP>,
+			 <&cru PCLK_ISP>;
+		clock-names = "isp", "aclk", "hclk", "pclk";
+		iommus = <&isp_mmu>;
+		phys = <&csi_dphy>;
+		phy-names = "dphy";
+		power-domains = <&power PX30_PD_VI>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+	};
+
+	isp_mmu: iommu at ff4a8000 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff4a8000 0x0 0x100>;
+		interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_ISP>, <&cru HCLK_ISP>;
+		clock-names = "aclk", "iface";
+		power-domains = <&power PX30_PD_VI>;
+		rockchip,disable-mmu-reset;
+		#iommu-cells = <0>;
+	};
+
 	qos_gmac: qos at ff518000 {
 		compatible = "rockchip,px30-qos", "syscon";
 		reg = <0x0 0xff518000 0x0 0x20>;
-- 
2.29.2



From heiko at sntech.de  Mon Aug 30 07:13:18 2021
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 30 Aug 2021 16:13:18 +0200
Subject: [PATCH 2/2] arm64: dts: rockchip: hook up camera on px30-evb
In-Reply-To: <20210830141318.66744-1-heiko@sntech.de>
References: <20210830141318.66744-1-heiko@sntech.de>
Message-ID: <20210830141318.66744-2-heiko@sntech.de>

From: Heiko Stuebner <heiko.stuebner at theobroma-systems.com>

Signed-off-by: Heiko Stuebner <heiko.stuebner at theobroma-systems.com>
---
 arch/arm64/boot/dts/rockchip/px30-evb.dts | 52 +++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/px30-evb.dts b/arch/arm64/boot/dts/rockchip/px30-evb.dts
index c1ce9c295e5b..848bc39cf86a 100644
--- a/arch/arm64/boot/dts/rockchip/px30-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/px30-evb.dts
@@ -114,6 +114,10 @@ &cpu3 {
 	cpu-supply = <&vdd_arm>;
 };
 
+&csi_dphy {
+	status = "okay";
+};
+
 &display_subsystem {
 	status = "okay";
 };
@@ -428,6 +432,36 @@ sensor at 4c {
 	};
 };
 
+&i2c2 {
+	status = "okay";
+
+	clock-frequency = <100000>;
+
+	/* These are relatively safe rise/fall times; TODO: measure */
+	i2c-scl-falling-time-ns = <50>;
+	i2c-scl-rising-time-ns = <300>;
+
+	ov5695: ov5695 at 36 {
+		compatible = "ovti,ov5695";
+		reg = <0x36>;
+		avdd-supply = <&vcc2v8_dvp>;
+		clocks = <&cru SCLK_CIF_OUT>;
+		clock-names = "xvclk";
+		dvdd-supply = <&vcc1v5_dvp>;
+		dovdd-supply = <&vcc1v8_dvp>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&cif_clkout_m0>;
+		reset-gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+
+		port {
+			ucam_out: endpoint {
+				remote-endpoint = <&mipi_in_ucam>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
 &i2s1_2ch {
 	status = "okay";
 };
@@ -443,6 +477,24 @@ &io_domains {
 	vccio6-supply = <&vccio_flash>;
 };
 
+&isp {
+	status = "okay";
+
+	ports {
+		port at 0 {
+			mipi_in_ucam: endpoint at 0 {
+				reg = <0>;
+				data-lanes = <1 2>;
+				remote-endpoint = <&ucam_out>;
+			};
+		};
+	};
+};
+
+&isp_mmu {
+	status = "okay";
+};
+
 &pinctrl {
 	headphone {
 		hp_det: hp-det {
-- 
2.29.2



From linux at fw-web.de  Mon Aug 30 07:14:15 2021
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon, 30 Aug 2021 16:14:15 +0200
Subject: [PATCH] arm: dts: mt7623: add otg nodes for bpi-r2
Message-ID: <20210830141415.106136-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add OTG-Nodes for BananaPi-R2

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
patch is based on

"arm: dts: mt7623: add musb device nodes"

https://patchwork.kernel.org/project/linux-mediatek/patch/20210822041333.5264-2-mans0n at gorani.run/
---
 arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
index 8d22aeec91e1..729bc055ffcd 100644
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -374,7 +374,14 @@ adie {
 				bias-disable;
 		};
 	};
+
+	musb_pins: musb {
+		pins-musb {
+			pinmux = <MT7623_PIN_237_EXT_SDIO2_FUNC_DRV_VBUS>;
+		};
+	};
 };
+
 &consys {
 	mediatek,pwrap-regmap = <&pwrap>;
 	pinctrl-names = "default";
@@ -462,3 +469,21 @@ &u3phy1 {
 &u3phy2 {
 	status = "okay";
 };
+
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&musb_pins>;
+	status = "okay";
+	usb-role-switch;
+
+	connector {
+		compatible = "gpio-usb-b-connector", "usb-b-connector";
+		type = "micro";
+		id-gpios = <&pio 44 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&u2phy1 {
+	status = "okay";
+};
+
-- 
2.25.1



From jic23 at kernel.org  Mon Aug 30 07:44:08 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 30 Aug 2021 15:44:08 +0100
Subject: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to
 platform specific data structures
In-Reply-To: <1688eb0e-5ea1-3bcc-3af0-7ba4c4601306@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
 <20210824115441.681253-5-eugen.hristev@microchip.com>
 <1688eb0e-5ea1-3bcc-3af0-7ba4c4601306@microchip.com>
Message-ID: <20210830154408.4ffdef1a@jic23-huawei>

On Mon, 30 Aug 2021 12:31:46 +0000
<Eugen.Hristev at microchip.com> wrote:

> On 8/24/21 2:54 PM, Eugen Hristev wrote:
> > Convert the driver to platform specific structures. This means:
> > - create a register layout struct that will hold offsets for registers
> > - create a platform struct that will hold platform information (number of
> > channels, indexes for different channels and pointer to layout struct)
> > - convert specific macros that are platform dependent into platform variables
> > 
> > This step is in fact a no-op, but allows the driver to be more flexible
> > and for future enhancement including adding new platforms that are partly
> > compatible with the current driver and differ slightly in register layout
> > or capabilities for example.
> > 
> > Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> > ---
> >   drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
> >   1 file changed, 247 insertions(+), 163 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> > index 9d71dcffcf93..8ede18b8d789 100644
> > --- a/drivers/iio/adc/at91-sama5d2_adc.c
> > +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> > @@ -27,8 +27,9 @@
> >   #include <linux/pinctrl/consumer.h>
> >   #include <linux/regulator/consumer.h>
> >   
> > +struct at91_adc_reg_layout {
> >   /* Control Register */
> > -#define AT91_SAMA5D2_CR		0x00
> > +	u16				CR;
> >   /* Software Reset */
> >   #define	AT91_SAMA5D2_CR_SWRST		BIT(0)
> >   /* Start Conversion */
> > @@ -39,7 +40,7 @@
> >   #define	AT91_SAMA5D2_CR_CMPRST		BIT(4)
> >   
> >   /* Mode Register */
> > -#define AT91_SAMA5D2_MR		0x04
> > +	u16				MR;
> >   /* Trigger Selection */
> >   #define	AT91_SAMA5D2_MR_TRGSEL(v)	((v) << 1)
> >   /* ADTRG */
> > @@ -82,19 +83,19 @@
> >   #define	AT91_SAMA5D2_MR_USEQ		BIT(31)
> >   
> >   /* Channel Sequence Register 1 */
> > -#define AT91_SAMA5D2_SEQR1	0x08
> > +	u16				SEQR1;
> >   /* Channel Sequence Register 2 */
> > -#define AT91_SAMA5D2_SEQR2	0x0c
> > +	u16				SEQR2;
> >   /* Channel Enable Register */
> > -#define AT91_SAMA5D2_CHER	0x10
> > +	u16				CHER;
> >   /* Channel Disable Register */
> > -#define AT91_SAMA5D2_CHDR	0x14
> > +	u16				CHDR;
> >   /* Channel Status Register */
> > -#define AT91_SAMA5D2_CHSR	0x18
> > +	u16				CHSR;
> >   /* Last Converted Data Register */
> > -#define AT91_SAMA5D2_LCDR	0x20
> > +	u16				LCDR;
> >   /* Interrupt Enable Register */
> > -#define AT91_SAMA5D2_IER	0x24
> > +	u16				IER;
> >   /* Interrupt Enable Register - TS X measurement ready */
> >   #define AT91_SAMA5D2_IER_XRDY   BIT(20)
> >   /* Interrupt Enable Register - TS Y measurement ready */
> > @@ -109,22 +110,23 @@
> >   #define AT91_SAMA5D2_IER_PEN    BIT(29)
> >   /* Interrupt Enable Register - No pen detect */
> >   #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
> > +
> >   /* Interrupt Disable Register */
> > -#define AT91_SAMA5D2_IDR	0x28
> > +	u16				IDR;
> >   /* Interrupt Mask Register */
> > -#define AT91_SAMA5D2_IMR	0x2c
> > +	u16				IMR;
> >   /* Interrupt Status Register */
> > -#define AT91_SAMA5D2_ISR	0x30
> > +	u16				ISR;
> >   /* Interrupt Status Register - Pen touching sense status */
> >   #define AT91_SAMA5D2_ISR_PENS   BIT(31)
> >   /* Last Channel Trigger Mode Register */
> > -#define AT91_SAMA5D2_LCTMR	0x34
> > +	u16				LCTMR;
> >   /* Last Channel Compare Window Register */
> > -#define AT91_SAMA5D2_LCCWR	0x38
> > +	u16				LCCWR;
> >   /* Overrun Status Register */
> > -#define AT91_SAMA5D2_OVER	0x3c
> > +	u16				OVER;
> >   /* Extended Mode Register */
> > -#define AT91_SAMA5D2_EMR	0x40
> > +	u16				EMR;
> >   /* Extended Mode Register - Oversampling rate */
> >   #define AT91_SAMA5D2_EMR_OSR(V)			((V) << 16)
> >   #define AT91_SAMA5D2_EMR_OSR_MASK		GENMASK(17, 16)
> > @@ -134,22 +136,22 @@
> >   
> >   /* Extended Mode Register - Averaging on single trigger event */
> >   #define AT91_SAMA5D2_EMR_ASTE(V)		((V) << 20)
> > +
> >   /* Compare Window Register */
> > -#define AT91_SAMA5D2_CWR	0x44
> > +	u16				CWR;
> >   /* Channel Gain Register */
> > -#define AT91_SAMA5D2_CGR	0x48
> > -
> > +	u16				CGR;
> >   /* Channel Offset Register */
> > -#define AT91_SAMA5D2_COR	0x4c
> > +	u16				COR;
> >   #define AT91_SAMA5D2_COR_DIFF_OFFSET	16
> >   
> >   /* Analog Control Register */
> > -#define AT91_SAMA5D2_ACR	0x94
> > +	u16				ACR;
> >   /* Analog Control Register - Pen detect sensitivity mask */
> >   #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
> >   
> >   /* Touchscreen Mode Register */
> > -#define AT91_SAMA5D2_TSMR	0xb0
> > +	u16				TSMR;
> >   /* Touchscreen Mode Register - No touch mode */
> >   #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
> >   /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
> > @@ -178,13 +180,13 @@
> >   #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
> >   
> >   /* Touchscreen X Position Register */
> > -#define AT91_SAMA5D2_XPOSR	0xb4
> > +	u16				XPOSR;
> >   /* Touchscreen Y Position Register */
> > -#define AT91_SAMA5D2_YPOSR	0xb8
> > +	u16				YPOSR;
> >   /* Touchscreen Pressure Register */
> > -#define AT91_SAMA5D2_PRESSR	0xbc
> > +	u16				PRESSR;
> >   /* Trigger Register */
> > -#define AT91_SAMA5D2_TRGR	0xc0
> > +	u16				TRGR;
> >   /* Mask for TRGMOD field of TRGR register */
> >   #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
> >   /* No trigger, only software trigger can start conversions */
> > @@ -203,30 +205,52 @@
> >   #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
> >   
> >   /* Correction Select Register */
> > -#define AT91_SAMA5D2_COSR	0xd0
> > +	u16				COSR;
> >   /* Correction Value Register */
> > -#define AT91_SAMA5D2_CVR	0xd4
> > +	u16				CVR;
> >   /* Channel Error Correction Register */
> > -#define AT91_SAMA5D2_CECR	0xd8
> > +	u16				CECR;
> >   /* Write Protection Mode Register */
> > -#define AT91_SAMA5D2_WPMR	0xe4
> > +	u16				WPMR;
> >   /* Write Protection Status Register */
> > -#define AT91_SAMA5D2_WPSR	0xe8
> > +	u16				WPSR;
> >   /* Version Register */
> > -#define AT91_SAMA5D2_VERSION	0xfc
> > -
> > -#define AT91_SAMA5D2_HW_TRIG_CNT 3
> > -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> > -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> > -
> > -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
> > +	u16				VERSION;
> > +};
> >   
> > -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT * 2)  
> 
> Hi Jonathan,
> 
> While we are here, regarding the above line, I cannot tell why did I 
> multiply by two the differential channel count. This makes some gaps in 
> the number of channels when we put them all in the same table.
> 
> I did not change this as it would break the ABI regarding the bindings 
> for the touchscreen #adc-cells phandle references.

Really?  Xlate is based off scan_index, not these values I think...

> 
> However, I am thinking if there was a reason for it or it was a slip 
> when I initially wrote this.

I've no idea :)  I can't immediately see why we'd need the padding.

> 
> Do you think there is any reason to change it and tighten the holes in 
> the indexes list ?

I don't think it matters. As far as I can tell they are used mostly (possibly
entirely) for internal management and not exposed to any of the ABIs etc.

Jonathan

> 
> 
> Eugen
> 
> > -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> > -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> > -#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> > +static const struct at91_adc_reg_layout sama5d2_layout = {
> > +	.CR =			0x00,
> > +	.MR =			0x04,
> > +	.SEQR1 =		0x08,
> > +	.SEQR2 =		0x0c,
> > +	.CHER =			0x10,
> > +	.CHDR =			0x14,
> > +	.CHSR =			0x18,
> > +	.LCDR =			0x20,
> > +	.IER =			0x24,
> > +	.IDR =			0x28,
> > +	.IMR =			0x2c,
> > +	.ISR =			0x30,
> > +	.LCTMR =		0x34,
> > +	.LCCWR =		0x38,
> > +	.OVER =			0x3c,
> > +	.EMR =			0x40,
> > +	.CWR =			0x44,
> > +	.CGR =			0x48,
> > +	.COR =			0x4c,
> > +	.ACR =			0x94,
> > +	.TSMR =			0xb0,
> > +	.XPOSR =		0xb4,
> > +	.YPOSR =		0xb8,
> > +	.PRESSR =		0xbc,
> > +	.TRGR =			0xc0,
> > +	.COSR =			0xd0,
> > +	.CVR =			0xd4,
> > +	.CECR =			0xd8,
> > +	.WPMR =			0xe4,
> > +	.WPSR =			0xe8,
> > +	.VERSION =		0xfc,
> > +};
> >   
> >   #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
> >   #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
> > @@ -235,18 +259,6 @@
> >   
> >   #define AT91_SAMA5D2_MAX_POS_BITS			12
> >   
> > -/*
> > - * Maximum number of bytes to hold conversion from all channels
> > - * without the timestamp.
> > - */
> > -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > -					 AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
> > -
> > -/* This total must also include the timestamp */
> > -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
> > -
> > -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
> > -
> >   #define AT91_HWFIFO_MAX_SIZE_STR	"128"
> >   #define AT91_HWFIFO_MAX_SIZE		128
> >   
> > @@ -255,12 +267,12 @@
> >   #define AT91_OSR_4SAMPLES		4
> >   #define AT91_OSR_16SAMPLES		16
> >   
> > -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)				\
> > +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)			\
> >   	{								\
> >   		.type = IIO_VOLTAGE,					\
> >   		.channel = num,						\
> >   		.address = addr,					\
> > -		.scan_index = num,					\
> > +		.scan_index = index,					\
> >   		.scan_type = {						\
> >   			.sign = 'u',					\
> >   			.realbits = 14,					\
> > @@ -274,14 +286,14 @@
> >   		.indexed = 1,						\
> >   	}
> >   
> > -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)				\
> > +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)			\
> >   	{								\
> >   		.type = IIO_VOLTAGE,					\
> >   		.differential = 1,					\
> >   		.channel = num,						\
> >   		.channel2 = num2,					\
> >   		.address = addr,					\
> > -		.scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,	\
> > +		.scan_index = index,					\
> >   		.scan_type = {						\
> >   			.sign = 's',					\
> >   			.realbits = 14,					\
> > @@ -328,13 +340,48 @@
> >   		.datasheet_name = name,					\
> >   	}
> >   
> > -#define at91_adc_readl(st, reg)		readl_relaxed(st->base + reg)
> > -#define at91_adc_writel(st, reg, val)	writel_relaxed(val, st->base + reg)
> > +#define at91_adc_readl(st, reg)						\
> > +	readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
> > +#define at91_adc_read_chan(st, reg)					\
> > +	readl_relaxed((st)->base + reg)
> > +#define at91_adc_writel(st, reg, val)					\
> > +	writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
> > +
> > +/**
> > + * struct at91_adc_platform - at91-sama5d2 platform information struct
> > + * @layout:		pointer to the reg layout struct
> > + * @adc_channels:	pointer to an array of channels for registering in
> > + *			the iio subsystem
> > + * @nr_channels:	number of physical channels available
> > + * @touch_chan_x:	index of the touchscreen X channel
> > + * @touch_chan_y:	index of the touchscreen Y channel
> > + * @touch_chan_p:	index of the touchscreen P channel
> > + * @max_channels:	number of total channels
> > + * @hw_trig_cnt:	number of possible hardware triggers
> > + */
> > +struct at91_adc_platform {
> > +	const struct at91_adc_reg_layout	*layout;
> > +	const struct iio_chan_spec		(*adc_channels)[];
> > +	unsigned int				nr_channels;
> > +	unsigned int				touch_chan_x;
> > +	unsigned int				touch_chan_y;
> > +	unsigned int				touch_chan_p;
> > +	unsigned int				max_channels;
> > +	unsigned int				hw_trig_cnt;
> > +};
> >   
> > +/**
> > + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
> > + * @startup_time:	device startup time
> > + * @min_sample_rate:	minimum sample rate in Hz
> > + * @max_sample_rate:	maximum sample rate in Hz
> > + * @platform:		pointer to the platform structure
> > + */
> >   struct at91_adc_soc_info {
> >   	unsigned			startup_time;
> >   	unsigned			min_sample_rate;
> >   	unsigned			max_sample_rate;
> > +	const struct at91_adc_platform	*platform;
> >   };
> >   
> >   struct at91_adc_trigger {
> > @@ -382,6 +429,15 @@ struct at91_adc_touch {
> >   	struct work_struct		workq;
> >   };
> >   
> > +/*
> > + * Buffer size requirements:
> > + * No channels * bytes_per_channel(2) + timestamp bytes (8)
> > + * Divided by 2 because we need half words.
> > + * We assume 32 channels for now, has to be increased if needed.
> > + * Nobody minds a buffer being too big.
> > + */
> > +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
> > +
> >   struct at91_adc_state {
> >   	void __iomem			*base;
> >   	int				irq;
> > @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
> >   	},
> >   };
> >   
> > -static const struct iio_chan_spec at91_adc_channels[] = {
> > -	AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
> > -	AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
> > -	AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
> > -	AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
> > -	AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
> > -	AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
> > -	AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
> > -	AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
> > -	AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
> > -	AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
> > -	AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
> > -	AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
> > -	AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
> > -	AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
> > -	AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
> > -	AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
> > -	AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
> > -	AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),
> > -	IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
> > -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
> > -	AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
> > -	AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
> > +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
> > +	AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
> > +	AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
> > +	AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
> > +	AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
> > +	AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
> > +	AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
> > +	AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
> > +	AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
> > +	AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
> > +	AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
> > +	AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
> > +	AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
> > +	AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
> > +	AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
> > +	AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
> > +	AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
> > +	AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
> > +	AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
> > +	IIO_CHAN_SOFT_TIMESTAMP(18),
> > +	AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
> > +	AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
> > +	AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),
> > +};
> > +
> > +static const struct at91_adc_platform sama5d2_platform = {
> > +	.layout = &sama5d2_layout,
> > +	.adc_channels = &at91_sama5d2_adc_channels,
> > +#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
> > +#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
> > +	.nr_channels = AT91_SAMA5D2_SINGLE_CHAN_CNT +
> > +		       AT91_SAMA5D2_DIFF_CHAN_CNT,
> > +#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX	(AT91_SAMA5D2_SINGLE_CHAN_CNT + \
> > +					AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
> > +	.touch_chan_x = AT91_SAMA5D2_TOUCH_X_CHAN_IDX,
> > +#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX	(AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
> > +	.touch_chan_y = AT91_SAMA5D2_TOUCH_Y_CHAN_IDX,
> > +#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX	(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
> > +	.touch_chan_p = AT91_SAMA5D2_TOUCH_P_CHAN_IDX,
> > +#define AT91_SAMA5D2_MAX_CHAN_IDX	AT91_SAMA5D2_TOUCH_P_CHAN_IDX
> > +	.max_channels = ARRAY_SIZE(at91_sama5d2_adc_channels),
> > +#define AT91_SAMA5D2_HW_TRIG_CNT	3
> > +	.hw_trig_cnt = AT91_SAMA5D2_HW_TRIG_CNT,
> >   };
> >   
> >   static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
> > @@ -493,6 +569,7 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
> >   {
> >   	u32 mask = 0;
> >   	u8 bit;
> > +	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> >   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> >   			 indio_dev->num_channels) {
> > @@ -501,13 +578,13 @@ static unsigned int at91_adc_active_scan_mask_to_reg(struct iio_dev *indio_dev)
> >   		mask |= BIT(chan->channel);
> >   	}
> >   
> > -	return mask & GENMASK(11, 0);
> > +	return mask & GENMASK(st->soc_info.platform->nr_channels, 0);
> >   }
> >   
> >   static void at91_adc_config_emr(struct at91_adc_state *st)
> >   {
> >   	/* configure the extended mode register */
> > -	unsigned int emr = at91_adc_readl(st, AT91_SAMA5D2_EMR);
> > +	unsigned int emr = at91_adc_readl(st, EMR);
> >   
> >   	/* select oversampling per single trigger event */
> >   	emr |= AT91_SAMA5D2_EMR_ASTE(1);
> > @@ -531,7 +608,7 @@ static void at91_adc_config_emr(struct at91_adc_state *st)
> >   		break;
> >   	}
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_EMR, emr);
> > +	at91_adc_writel(st, EMR, emr);
> >   }
> >   
> >   static int at91_adc_adjust_val_osr(struct at91_adc_state *st, int *val)
> > @@ -584,9 +661,9 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
> >   
> >   	if (!state) {
> >   		/* disabling touch IRQs and setting mode to no touch enabled */
> > -		at91_adc_writel(st, AT91_SAMA5D2_IDR,
> > +		at91_adc_writel(st, IDR,
> >   				AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
> > -		at91_adc_writel(st, AT91_SAMA5D2_TSMR, 0);
> > +		at91_adc_writel(st, TSMR, 0);
> >   		return 0;
> >   	}
> >   	/*
> > @@ -612,19 +689,19 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
> >   	tsmr |= AT91_SAMA5D2_TSMR_PENDET_ENA;
> >   	tsmr |= AT91_SAMA5D2_TSMR_TSFREQ(2) & AT91_SAMA5D2_TSMR_TSFREQ_MASK;
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_TSMR, tsmr);
> > +	at91_adc_writel(st, TSMR, tsmr);
> >   
> > -	acr =  at91_adc_readl(st, AT91_SAMA5D2_ACR);
> > +	acr =  at91_adc_readl(st, ACR);
> >   	acr &= ~AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> >   	acr |= 0x02 & AT91_SAMA5D2_ACR_PENDETSENS_MASK;
> > -	at91_adc_writel(st, AT91_SAMA5D2_ACR, acr);
> > +	at91_adc_writel(st, ACR, acr);
> >   
> >   	/* Sample Period Time = (TRGPER + 1) / ADCClock */
> >   	st->touch_st.sample_period_val =
> >   				 round_up((AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US *
> >   				 clk_khz / 1000) - 1, 1);
> >   	/* enable pen detect IRQ */
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
> >   
> >   	return 0;
> >   }
> > @@ -640,7 +717,11 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
> >   	 * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
> >   	 */
> >   	/* first half of register is the x or y, second half is the scale */
> > -	val = at91_adc_readl(st, reg);
> > +	if (reg == st->soc_info.platform->layout->XPOSR)
> > +		val = at91_adc_readl(st, XPOSR);
> > +	else if (reg == st->soc_info.platform->layout->YPOSR)
> > +		val = at91_adc_readl(st, YPOSR);
> > +
> >   	if (!val)
> >   		dev_dbg(&st->indio_dev->dev, "pos is 0\n");
> >   
> > @@ -658,13 +739,13 @@ static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
> >   
> >   static u16 at91_adc_touch_x_pos(struct at91_adc_state *st)
> >   {
> > -	st->touch_st.x_pos = at91_adc_touch_pos(st, AT91_SAMA5D2_XPOSR);
> > +	st->touch_st.x_pos = at91_adc_touch_pos(st, st->soc_info.platform->layout->XPOSR);
> >   	return st->touch_st.x_pos;
> >   }
> >   
> >   static u16 at91_adc_touch_y_pos(struct at91_adc_state *st)
> >   {
> > -	return at91_adc_touch_pos(st, AT91_SAMA5D2_YPOSR);
> > +	return at91_adc_touch_pos(st, st->soc_info.platform->layout->YPOSR);
> >   }
> >   
> >   static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> > @@ -676,7 +757,7 @@ static u16 at91_adc_touch_pressure(struct at91_adc_state *st)
> >   	u32 factor = 1000;
> >   
> >   	/* calculate the pressure */
> > -	val = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> > +	val = at91_adc_readl(st, PRESSR);
> >   	z1 = val & AT91_SAMA5D2_XYZ_MASK;
> >   	z2 = (val >> 16) & AT91_SAMA5D2_XYZ_MASK;
> >   
> > @@ -700,9 +781,9 @@ static int at91_adc_read_position(struct at91_adc_state *st, int chan, u16 *val)
> >   	*val = 0;
> >   	if (!st->touch_st.touching)
> >   		return -ENODATA;
> > -	if (chan == AT91_SAMA5D2_TOUCH_X_CHAN_IDX)
> > +	if (chan == st->soc_info.platform->touch_chan_x)
> >   		*val = at91_adc_touch_x_pos(st);
> > -	else if (chan == AT91_SAMA5D2_TOUCH_Y_CHAN_IDX)
> > +	else if (chan == st->soc_info.platform->touch_chan_y)
> >   		*val = at91_adc_touch_y_pos(st);
> >   	else
> >   		return -ENODATA;
> > @@ -715,7 +796,7 @@ static int at91_adc_read_pressure(struct at91_adc_state *st, int chan, u16 *val)
> >   	*val = 0;
> >   	if (!st->touch_st.touching)
> >   		return -ENODATA;
> > -	if (chan == AT91_SAMA5D2_TOUCH_P_CHAN_IDX)
> > +	if (chan == st->soc_info.platform->touch_chan_y)
> >   		*val = at91_adc_touch_pressure(st);
> >   	else
> >   		return -ENODATA;
> > @@ -727,7 +808,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
> >   {
> >   	struct iio_dev *indio = iio_trigger_get_drvdata(trig);
> >   	struct at91_adc_state *st = iio_priv(indio);
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_TRGR);
> > +	u32 status = at91_adc_readl(st, TRGR);
> >   
> >   	/* clear TRGMOD */
> >   	status &= ~AT91_SAMA5D2_TRGR_TRGMOD_MASK;
> > @@ -736,7 +817,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
> >   		status |= st->selected_trig->trgmod_value;
> >   
> >   	/* set/unset hw trigger */
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
> > +	at91_adc_writel(st, TRGR, status);
> >   
> >   	return 0;
> >   }
> > @@ -753,7 +834,7 @@ static void at91_adc_reenable_trigger(struct iio_trigger *trig)
> >   	enable_irq(st->irq);
> >   
> >   	/* Needed to ACK the DRDY interruption */
> > -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> > +	at91_adc_readl(st, LCDR);
> >   }
> >   
> >   static const struct iio_trigger_ops at91_adc_trigger_ops = {
> > @@ -848,7 +929,7 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
> >   	}
> >   
> >   	/* enable general overrun error signaling */
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_GOVRE);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_GOVRE);
> >   	/* Issue pending DMA requests */
> >   	dma_async_issue_pending(st->dma_st.dma_chan);
> >   
> > @@ -878,7 +959,7 @@ static bool at91_adc_current_chan_is_touch(struct iio_dev *indio_dev)
> >   
> >   	return !!bitmap_subset(indio_dev->active_scan_mask,
> >   			       &st->touch_st.channels_bitmask,
> > -			       AT91_SAMA5D2_MAX_CHAN_IDX + 1);
> > +			       st->soc_info.platform->max_channels + 1);
> >   }
> >   
> >   static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> > @@ -915,7 +996,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> >   		    chan->type == IIO_PRESSURE)
> >   			continue;
> >   
> > -		cor = at91_adc_readl(st, AT91_SAMA5D2_COR);
> > +		cor = at91_adc_readl(st, COR);
> >   
> >   		if (chan->differential)
> >   			cor |= (BIT(chan->channel) | BIT(chan->channel2)) <<
> > @@ -924,13 +1005,13 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
> >   			cor &= ~(BIT(chan->channel) <<
> >   			       AT91_SAMA5D2_COR_DIFF_OFFSET);
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> > +		at91_adc_writel(st, COR, cor);
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> > +		at91_adc_writel(st, CHER, BIT(chan->channel));
> >   	}
> >   
> >   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> > -		at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_DRDY);
> > +		at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
> >   
> >   	return 0;
> >   }
> > @@ -966,17 +1047,17 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
> >   		    chan->type == IIO_PRESSURE)
> >   			continue;
> >   
> > -		at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> > +		at91_adc_writel(st, CHDR, BIT(chan->channel));
> >   
> >   		if (st->dma_st.dma_chan)
> > -			at91_adc_readl(st, chan->address);
> > +			at91_adc_read_chan(st, chan->address);
> >   	}
> >   
> >   	if (at91_adc_buffer_check_use_irq(indio_dev, st))
> > -		at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_DRDY);
> > +		at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
> >   
> >   	/* read overflow register to clear possible overflow status */
> > -	at91_adc_readl(st, AT91_SAMA5D2_OVER);
> > +	at91_adc_readl(st, OVER);
> >   
> >   	/* if we are using DMA we must clear registers and end DMA */
> >   	if (st->dma_st.dma_chan)
> > @@ -1024,7 +1105,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
> >   	 * Check if the conversion is ready. If not, wait a little bit, and
> >   	 * in case of timeout exit with an error.
> >   	 */
> > -	while ((at91_adc_readl(st, AT91_SAMA5D2_ISR) & mask) != mask &&
> > +	while ((at91_adc_readl(st, ISR) & mask) != mask &&
> >   	       timeout) {
> >   		usleep_range(50, 100);
> >   		timeout--;
> > @@ -1052,7 +1133,7 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
> >   		 * Thus, emit a warning.
> >   		 */
> >   		if (chan->type == IIO_VOLTAGE) {
> > -			val = at91_adc_readl(st, chan->address);
> > +			val = at91_adc_read_chan(st, chan->address);
> >   			at91_adc_adjust_val_osr(st, &val);
> >   			st->buffer[i] = val;
> >   		} else {
> > @@ -1073,7 +1154,7 @@ static void at91_adc_trigger_handler_dma(struct iio_dev *indio_dev)
> >   	s64 interval;
> >   	int sample_index = 0, sample_count, sample_size;
> >   
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> > +	u32 status = at91_adc_readl(st, ISR);
> >   	/* if we reached this point, we cannot sample faster */
> >   	if (status & AT91_SAMA5D2_IER_GOVRE)
> >   		pr_info_ratelimited("%s: conversion overrun detected\n",
> > @@ -1125,7 +1206,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
> >   	 * actually polling the trigger now.
> >   	 */
> >   	if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
> > -		at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> > +		at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
> >   
> >   	if (st->dma_st.dma_chan)
> >   		at91_adc_trigger_handler_dma(indio_dev);
> > @@ -1172,11 +1253,11 @@ static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq)
> >   	startup = at91_adc_startup_time(st->soc_info.startup_time,
> >   					freq / 1000);
> >   
> > -	mr = at91_adc_readl(st, AT91_SAMA5D2_MR);
> > +	mr = at91_adc_readl(st, MR);
> >   	mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK);
> >   	mr |= AT91_SAMA5D2_MR_STARTUP(startup);
> >   	mr |= AT91_SAMA5D2_MR_PRESCAL(prescal);
> > -	at91_adc_writel(st, AT91_SAMA5D2_MR, mr);
> > +	at91_adc_writel(st, MR, mr);
> >   
> >   	dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n",
> >   		freq, startup, prescal);
> > @@ -1196,7 +1277,7 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
> >   	int i = 0;
> >   
> >   	for_each_set_bit(bit, indio_dev->active_scan_mask,
> > -			 AT91_SAMA5D2_MAX_CHAN_IDX + 1) {
> > +			 st->soc_info.platform->max_channels + 1) {
> >   		struct iio_chan_spec const *chan =
> >   					 at91_adc_chan_get(indio_dev, bit);
> >   
> > @@ -1222,12 +1303,11 @@ static void at91_adc_touch_data_handler(struct iio_dev *indio_dev)
> >   
> >   static void at91_adc_pen_detect_interrupt(struct at91_adc_state *st)
> >   {
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_PEN);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_NOPEN |
> > +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_NOPEN |
> >   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY);
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> > -			AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> > +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_PERIODIC |
> >   			AT91_SAMA5D2_TRGR_TRGPER(st->touch_st.sample_period_val));
> >   	st->touch_st.touching = true;
> >   }
> > @@ -1236,16 +1316,15 @@ static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev)
> >   {
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_TRGR,
> > -			AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, AT91_SAMA5D2_IER_NOPEN |
> > +	at91_adc_writel(st, TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER);
> > +	at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_NOPEN |
> >   			AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY);
> >   	st->touch_st.touching = false;
> >   
> >   	at91_adc_touch_data_handler(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, AT91_SAMA5D2_IER_PEN);
> > +	at91_adc_writel(st, IER, AT91_SAMA5D2_IER_PEN);
> >   }
> >   
> >   static void at91_adc_workq_handler(struct work_struct *workq)
> > @@ -1263,8 +1342,8 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   {
> >   	struct iio_dev *indio = private;
> >   	struct at91_adc_state *st = iio_priv(indio);
> > -	u32 status = at91_adc_readl(st, AT91_SAMA5D2_ISR);
> > -	u32 imr = at91_adc_readl(st, AT91_SAMA5D2_IMR);
> > +	u32 status = at91_adc_readl(st, ISR);
> > +	u32 imr = at91_adc_readl(st, IMR);
> >   	u32 rdy_mask = AT91_SAMA5D2_IER_XRDY | AT91_SAMA5D2_IER_YRDY |
> >   			AT91_SAMA5D2_IER_PRDY;
> >   
> > @@ -1285,9 +1364,9 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   		 * touching, but the measurements are not ready yet.
> >   		 * read and ignore.
> >   		 */
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_XPOSR);
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_YPOSR);
> > -		status = at91_adc_readl(st, AT91_SAMA5D2_PRESSR);
> > +		status = at91_adc_readl(st, XPOSR);
> > +		status = at91_adc_readl(st, YPOSR);
> > +		status = at91_adc_readl(st, PRESSR);
> >   	} else if (iio_buffer_enabled(indio) &&
> >   		   (status & AT91_SAMA5D2_IER_DRDY)) {
> >   		/* triggered buffer without DMA */
> > @@ -1299,7 +1378,7 @@ static irqreturn_t at91_adc_interrupt(int irq, void *private)
> >   		WARN(true, "Unexpected irq occurred\n");
> >   	} else if (!iio_buffer_enabled(indio)) {
> >   		/* software requested conversion */
> > -		st->conversion_value = at91_adc_readl(st, st->chan->address);
> > +		st->conversion_value = at91_adc_read_chan(st, st->chan->address);
> >   		st->conversion_done = true;
> >   		wake_up_interruptible(&st->wq_data_available);
> >   	}
> > @@ -1360,10 +1439,10 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> >   		cor = (BIT(chan->channel) | BIT(chan->channel2)) <<
> >   		      AT91_SAMA5D2_COR_DIFF_OFFSET;
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_COR, cor);
> > -	at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START);
> > +	at91_adc_writel(st, COR, cor);
> > +	at91_adc_writel(st, CHER, BIT(chan->channel));
> > +	at91_adc_writel(st, IER, BIT(chan->channel));
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
> >   
> >   	ret = wait_event_interruptible_timeout(st->wq_data_available,
> >   					       st->conversion_done,
> > @@ -1379,11 +1458,11 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
> >   		st->conversion_done = false;
> >   	}
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, BIT(chan->channel));
> > -	at91_adc_writel(st, AT91_SAMA5D2_CHDR, BIT(chan->channel));
> > +	at91_adc_writel(st, IDR, BIT(chan->channel));
> > +	at91_adc_writel(st, CHDR, BIT(chan->channel));
> >   
> >   	/* Needed to ACK the DRDY interruption */
> > -	at91_adc_readl(st, AT91_SAMA5D2_LCDR);
> > +	at91_adc_readl(st, LCDR);
> >   
> >   	mutex_unlock(&st->lock);
> >   
> > @@ -1455,14 +1534,15 @@ static void at91_adc_dma_init(struct platform_device *pdev)
> >   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   	struct dma_slave_config config = {0};
> > +	/* we have 2 bytes for each channel */
> > +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
> >   	/*
> >   	 * We make the buffer double the size of the fifo,
> >   	 * such that DMA uses one half of the buffer (full fifo size)
> >   	 * and the software uses the other half to read/write.
> >   	 */
> >   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> > -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> > -					  PAGE_SIZE);
> > +					  sample_size * 2, PAGE_SIZE);
> >   
> >   	if (st->dma_st.dma_chan)
> >   		return;
> > @@ -1486,7 +1566,7 @@ static void at91_adc_dma_init(struct platform_device *pdev)
> >   	/* Configure DMA channel to read data register */
> >   	config.direction = DMA_DEV_TO_MEM;
> >   	config.src_addr = (phys_addr_t)(st->dma_st.phys_addr
> > -			  + AT91_SAMA5D2_LCDR);
> > +			  + st->soc_info.platform->layout->LCDR);
> >   	config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
> >   	config.src_maxburst = 1;
> >   	config.dst_maxburst = 1;
> > @@ -1515,9 +1595,10 @@ static void at91_adc_dma_disable(struct platform_device *pdev)
> >   {
> >   	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> > +	/* we have 2 bytes for each channel */
> > +	unsigned int sample_size = st->soc_info.platform->nr_channels * 2;
> >   	unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
> > -					  AT91_BUFFER_MAX_CONVERSION_BYTES * 2,
> > -					  PAGE_SIZE);
> > +					  sample_size * 2, PAGE_SIZE);
> >   
> >   	/* if we are not using DMA, just return */
> >   	if (!st->dma_st.dma_chan)
> > @@ -1578,14 +1659,14 @@ static int at91_adc_update_scan_mode(struct iio_dev *indio_dev,
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> >   	if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
> > -			  AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> > +			  st->soc_info.platform->max_channels + 1))
> >   		return 0;
> >   	/*
> >   	 * if the new bitmap is a combination of touchscreen and regular
> >   	 * channels, then we are not fine
> >   	 */
> >   	if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
> > -			      AT91_SAMA5D2_MAX_CHAN_IDX + 1))
> > +			      st->soc_info.platform->max_channels + 1))
> >   		return -EINVAL;
> >   	return 0;
> >   }
> > @@ -1594,13 +1675,13 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
> >   {
> >   	struct at91_adc_state *st = iio_priv(indio_dev);
> >   
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> > -	at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff);
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> > +	at91_adc_writel(st, IDR, 0xffffffff);
> >   	/*
> >   	 * Transfer field must be set to 2 according to the datasheet and
> >   	 * allows different analog settings for each channel.
> >   	 */
> > -	at91_adc_writel(st, AT91_SAMA5D2_MR,
> > +	at91_adc_writel(st, MR,
> >   			AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
> >   
> >   	at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate);
> > @@ -1716,21 +1797,23 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   	if (!indio_dev)
> >   		return -ENOMEM;
> >   
> > +	st = iio_priv(indio_dev);
> > +	st->indio_dev = indio_dev;
> > +
> > +	st->soc_info.platform = of_device_get_match_data(&pdev->dev);
> > +
> >   	indio_dev->name = dev_name(&pdev->dev);
> >   	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
> >   	indio_dev->info = &at91_adc_info;
> > -	indio_dev->channels = at91_adc_channels;
> > -	indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels);
> > -
> > -	st = iio_priv(indio_dev);
> > -	st->indio_dev = indio_dev;
> > +	indio_dev->channels = *st->soc_info.platform->adc_channels;
> > +	indio_dev->num_channels = st->soc_info.platform->max_channels;
> >   
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_x, 1);
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_y, 1);
> >   	bitmap_set(&st->touch_st.channels_bitmask,
> > -		   AT91_SAMA5D2_TOUCH_P_CHAN_IDX, 1);
> > +		   st->soc_info.platform->touch_chan_p, 1);
> >   
> >   	st->oversampling_ratio = AT91_OSR_1SAMPLES;
> >   
> > @@ -1770,7 +1853,7 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   	st->selected_trig = NULL;
> >   
> >   	/* find the right trigger, or no trigger at all */
> > -	for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
> > +	for (i = 0; i < st->soc_info.platform->hw_trig_cnt + 1; i++)
> >   		if (at91_adc_trigger_list[i].edge_type == edge_type) {
> >   			st->selected_trig = &at91_adc_trigger_list[i];
> >   			break;
> > @@ -1855,7 +1938,7 @@ static int at91_adc_probe(struct platform_device *pdev)
> >   			 st->selected_trig->name);
> >   
> >   	dev_info(&pdev->dev, "version: %x\n",
> > -		 readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
> > +		 readl_relaxed(st->base + st->soc_info.platform->layout->VERSION));
> >   
> >   	return 0;
> >   
> > @@ -1898,7 +1981,7 @@ static __maybe_unused int at91_adc_suspend(struct device *dev)
> >   	 * and can be used by for other devices.
> >   	 * Otherwise, ADC will hog them and we can't go to suspend mode.
> >   	 */
> > -	at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST);
> > +	at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST);
> >   
> >   	clk_disable_unprepare(st->per_clk);
> >   	regulator_disable(st->vref);
> > @@ -1958,6 +2041,7 @@ static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
> >   static const struct of_device_id at91_adc_dt_match[] = {
> >   	{
> >   		.compatible = "atmel,sama5d2-adc",
> > +		.data = (const void *)&sama5d2_platform,
> >   	}, {
> >   		/* sentinel */
> >   	}
> >   
> 



From mark.kettenis at xs4all.nl  Mon Aug 30 07:57:02 2021
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Mon, 30 Aug 2021 16:57:02 +0200 (CEST)
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <87pmtvcgec.wl-maz@kernel.org> (message from Marc Zyngier on Mon, 
 30 Aug 2021 12:37:31 +0100)
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-5-mark.kettenis@xs4all.nl>
 <87pmtvcgec.wl-maz@kernel.org>
Message-ID: <56142808ad64dd79@bloch.sibelius.xs4all.nl>

> Date: Mon, 30 Aug 2021 12:37:31 +0100
> From: Marc Zyngier <maz at kernel.org>
> 
> Hi Mark,

Hi Marc,

> On Fri, 27 Aug 2021 18:15:29 +0100,
> Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
> > 
> > From: Mark Kettenis <kettenis at openbsd.org>
> > 
> > Add node corresponding to the apcie,t8103 node in the
> > Apple device tree for the Mac mini (M1, 2020).
> > 
> > Clock references and DART (IOMMU) references are left out at the
> > moment and will be added once the appropriate bindings have been
> > settled upon.
> > 
> > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > ---
> >  arch/arm64/boot/dts/apple/t8103.dtsi | 63 ++++++++++++++++++++++++++++
> >  1 file changed, 63 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
> > index 503a76fc30e6..6e4677bdef44 100644
> > --- a/arch/arm64/boot/dts/apple/t8103.dtsi
> > +++ b/arch/arm64/boot/dts/apple/t8103.dtsi
> > @@ -214,5 +214,68 @@ pinctrl_smc: pinctrl at 23e820000 {
> >  				     <AIC_IRQ 396 IRQ_TYPE_LEVEL_HIGH>,
> >  				     <AIC_IRQ 397 IRQ_TYPE_LEVEL_HIGH>;
> >  		};
> > +
> > +		pcie0: pcie at 690000000 {
> > +			compatible = "apple,t8103-pcie", "apple,pcie";
> > +			device_type = "pci";
> > +
> > +			reg = <0x6 0x90000000 0x0 0x1000000>,
> > +			      <0x6 0x80000000 0x0 0x4000>,
> > +			      <0x6 0x81000000 0x0 0x8000>,
> > +			      <0x6 0x82000000 0x0 0x8000>,
> > +			      <0x6 0x83000000 0x0 0x8000>;
> > +			reg-names = "config", "rc", "port0", "port1", "port2";
> > +
> > +			interrupt-parent = <&aic>;
> > +			interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
> > +				     <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
> > +
> > +			msi-controller;
> > +			msi-parent = <&pcie0>;
> > +			msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
> > +
> > +			bus-range = <0 3>;
> > +			#address-cells = <3>;
> > +			#size-cells = <2>;
> > +			ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 0x0 0x20000000>,
> > +				 <0x02000000 0x0 0xc0000000 0x6 0xc0000000 0x0 0x40000000>;
> > +
> > +			pinctrl-0 = <&pcie_pins>;
> > +			pinctrl-names = "default";
> > +
> > +			pci at 0,0 {
> > +				device_type = "pci";
> > +				reg = <0x0 0x0 0x0 0x0 0x0>;
> > +				reset-gpios = <&pinctrl_ap 152 0>;
> > +				max-link-speed = <2>;
> > +
> > +				#address-cells = <3>;
> > +				#size-cells = <2>;
> > +				ranges;
> > +			};
> > +
> > +			pci at 1,0 {
> > +				device_type = "pci";
> > +				reg = <0x800 0x0 0x0 0x0 0x0>;
> > +				reset-gpios = <&pinctrl_ap 153 0>;
> > +				max-link-speed = <2>;
> > +
> > +				#address-cells = <3>;
> > +				#size-cells = <2>;
> > +				ranges;
> > +			};
> > +
> > +			pci at 2,0 {
> > +				device_type = "pci";
> > +				reg = <0x1000 0x0 0x0 0x0 0x0>;
> > +				reset-gpios = <&pinctrl_ap 33 0>;
> > +				max-link-speed = <1>;
> > +
> > +				#address-cells = <3>;
> > +				#size-cells = <2>;
> > +				ranges;
> > +			};
> > +		};
> >  	};
> >  };
> 
> I have now implemented the MSI change on the Linux driver side, and it
> works nicely. So thumbs up from me on this front.
> 
> I am now looking at the interrupts provided by each port:
> (1) a bunch of port-private interrupts (link up/down...)
> (2) INTx interrupts
> 
> Given that the programming is per-port, I've implemented this as a
> per-port interrupt controller.
> 
> (1) is dead easy to implement, and doesn't require any DT description.
> (2) is unfortunately exposing the limits of my DT knowledge, and I'm
> not clear how to model it. I came up with the following:
> 
> 	port00: pci at 0,0 {
> 		device_type = "pci";
> 		reg = <0x0 0x0 0x0 0x0 0x0>;
> 		reset-gpios = <&pinctrl_ap 152 0>;
> 		max-link-speed = <2>;
> 
> 		#address-cells = <3>;
> 		#size-cells = <2>;
> 		ranges;
> 
> 		interrupt-controller;
> 		#interrupt-cells = <1>;
> 		interrupt-parent = <&port00>;
> 		interrupt-map-mask = <0 0 0 7>;
> 		interrupt-map = <0 0 0 1 &port00 0>,
> 				<0 0 0 2 &port00 1>,
> 				<0 0 0 3 &port00 2>,
> 				<0 0 0 4 &port00 3>;
> 	};
> 
> which vaguely seem to do the right thing for the devices behind root
> ports, but doesn't seem to work for INTx generated by the root ports
> themselves. Any clue? Alternatively, I could move it to something
> global to the whole PCIe controller, but that doesn't seem completely
> right.
> 
> It also begs the question whether the per-port interrupt to the AIC
> should be moved into each root port, should my per-port approach hold
> any water.

Must admit that I didn't entirely thinkthrough this aspect fo the
hardware.  MSIs work just fine for the built-in hardware of the
current generation of M1 Macs so I ignored INTx for now.

It isn't entirely clear to me what properties are "allowed" on the
individual pci device child nodes that correspond to the ports.  But
"interrupt-map" and "interrupt-map-mask" are certainly among the
allowed properties, so this approach makes sense to me.  I must say I
don't see what the issue with the INTx generated by the root ports
themselves would be.  

I don't think we can move the interrupt property for the AIC to the
ports though, since that property would actually represent the
interrupt of the PCI bridge device according to the standard PCI
bindings and that isn't the case here.

So this makes sense to me and might not even need changing to the
binding for the Apple PCIe controller itself.


From linux at fw-web.de  Mon Aug 30 07:59:58 2021
From: linux at fw-web.de (Frank Wunderlich)
Date: Mon, 30 Aug 2021 16:59:58 +0200
Subject: [PATCH v2] arm: dts: mt7623: add otg nodes for bpi-r2
Message-ID: <20210830145958.108605-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add OTG-Nodes for BananaPi-R2

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
patch is based on

"arm: dts: mt7623: add musb device nodes"

https://patchwork.kernel.org/project/linux-mediatek/patch/20210822041333.5264-2-mans0n at gorani.run/
---
v2:
	rebase on plain 5.14, v1 was based on some not upstreamed work
---
 arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
index e96aa0ed1ebd..027c1b0c6a98 100644
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -366,6 +366,14 @@ &pcie1_phy {
 	status = "okay";
 };
 
+&pio {
+	musb_pins: musb {
+		pins-musb {
+			pinmux = <MT7623_PIN_237_EXT_SDIO2_FUNC_DRV_VBUS>;
+		};
+	};
+};
+
 &pwm {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pwm_pins_a>;
@@ -396,6 +404,19 @@ &uart2 {
 	status = "okay";
 };
 
+&usb0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&musb_pins>;
+	status = "okay";
+	usb-role-switch;
+
+	connector {
+		compatible = "gpio-usb-b-connector", "usb-b-connector";
+		type = "micro";
+		id-gpios = <&pio 44 GPIO_ACTIVE_HIGH>;
+	};
+};
+
 &usb1 {
 	vusb33-supply = <&reg_3p3v>;
 	vbus-supply = <&reg_5v>;
@@ -408,6 +429,10 @@ &usb2 {
 	status = "okay";
 };
 
+&u2phy1 {
+	status = "okay";
+};
+
 &u3phy1 {
 	status = "okay";
 };
-- 
2.25.1



From robh at kernel.org  Mon Aug 30 08:05:19 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 10:05:19 -0500
Subject: [PATCH v7 3/5] dt-binding: mt8183: Add Mediatek MDP3 dt-bindings
In-Reply-To: <0092244acd520acac81208b8863b15fba58f4193.camel@mediatek.com>
References: <20210824100027.25989-1-moudy.ho@mediatek.com>
 <20210824100027.25989-4-moudy.ho@mediatek.com>
 <YSU0TrfFCsaI1TqV@robh.at.kernel.org>
 <0092244acd520acac81208b8863b15fba58f4193.camel@mediatek.com>
Message-ID: <CAL_JsqJ_cProt35pdd2MjoHsSKtd+0n1Dwq6ooV+CJH5sfOFWg@mail.gmail.com>

On Mon, Aug 30, 2021 at 2:58 AM moudy ho <moudy.ho at mediatek.com> wrote:
>
> On Tue, 2021-08-24 at 13:02 -0500, Rob Herring wrote:
> > On Tue, Aug 24, 2021 at 06:00:25PM +0800, Moudy Ho wrote:
> > > This patch adds DT binding document for Media Data Path 3 (MDP3)
> > > a unit in multimedia system used for scaling and color format
> > > convert.
> > >
> > > Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> > > ---
> > >  .../bindings/media/mediatek,mdp3-ccorr.yaml   |  57 +++++
> > >  .../bindings/media/mediatek,mdp3-rdma.yaml    | 207
> > > ++++++++++++++++++
> > >  .../bindings/media/mediatek,mdp3-rsz.yaml     |  65 ++++++
> > >  .../bindings/media/mediatek,mdp3-wdma.yaml    |  71 ++++++
> > >  .../bindings/media/mediatek,mdp3-wrot.yaml    |  71 ++++++
> > >  5 files changed, 471 insertions(+)
> > >  create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,mdp3-ccorr.yaml
> > >  create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> > >  create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
> > >  create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,mdp3-wdma.yaml
> > >  create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > > ccorr.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > > ccorr.yaml
> > > new file mode 100644
> > > index 000000000000..59fd68b46022
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > > ccorr.yaml
> > > @@ -0,0 +1,57 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id:
> > > https://urldefense.com/v3/__http://devicetree.org/schemas/media/mediatek,mdp3-ccorr.yaml*__;Iw!!CTRNKA9wMg0ARbw!1C0ChLqzi7Zq8D2d4_S4IqCEei4GXdgy3_VCQg8MdsJP7n8TlxbGyajipusfH8hi$
> > >
> > > +$schema:
> > > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!1C0ChLqzi7Zq8D2d4_S4IqCEei4GXdgy3_VCQg8MdsJP7n8TlxbGyajipi-OInix$
> > >
> > > +
> > > +title: Mediatek Media Data Path 3 CCORR Device Tree Bindings
> > > +
> > > +maintainers:
> > > +  - Daoyuan Huang <daoyuan.huang at mediatek.com>
> > > +  - Moudy Ho <moudy.ho at mediatek.com>
> > > +
> > > +description: |
> > > +  One of Media Data Path 3 (MDP3) components used to do color
> > > correction with 3X3 matrix.
> > > +
> > > +properties:
> > > +  compatible:
> > > +    items:
> > > +      - enum:
> > > +        - mediatek,mt8183-mdp3-ccorr
> > > +
> > > +  mediatek,mdp3-id:
> > > +    $ref: /schemas/types.yaml#/definitions/uint32
> > > +    maxItems: 1
> > > +    description: |
> > > +      HW index to distinguish same functionality modules.
> >
> > If we wanted h/w indexes in DT, we'd have a standard property. Why
> > do
> > you need this?
> >
> I'm sorry not quite sure what HW indexes means (something like
> aliases?)

It means whatever you said in your description.

And no, I'm not suggesting you use aliases.

> It was originally used to mark multiple identical modules in the MDP
> data path algorithm, so that appropriate paths can be dynamically
> dispatched.

If they are identical, then why do you need to distinguish them in DT?
If there's some difference you need to know about such as connections
to other blocks, then describe that. Another common example is needing
to know what bits/registers to access in a syscon phandle. For that,
make the register offset or bits be args to the phandle property.

Rob


From frank-w at public-files.de  Mon Aug 30 08:17:10 2021
From: frank-w at public-files.de (Frank Wunderlich)
Date: Mon, 30 Aug 2021 17:17:10 +0200
Subject: Aw: [PATCH v3 1/1] arm: dts: mt7623: add musb device nodes
In-Reply-To: <20210822041333.5264-2-mans0n@gorani.run>
References: <20210808123840.176738-1-mans0n@gorani.run>
 <20210822041333.5264-1-mans0n@gorani.run>
 <20210822041333.5264-2-mans0n@gorani.run>
Message-ID: <trinity-41954850-b71d-433f-9bd2-d5bce8f7e8fd-1630336630739@3c-app-gmx-bap54>

Tested-by: Frank Wunderlich <frank-w at public-files.de>

after adding nodes for r2
https://patchwork.kernel.org/project/linux-mediatek/patch/20210830145958.108605-1-linux at fw-web.de/

regards Frank


> Gesendet: Sonntag, 22. August 2021 um 06:13 Uhr
> Von: "Sungbo Eo" <mans0n at gorani.run>
> An: linux-mediatek at lists.infradead.org
> Cc: "Chunfeng Yun" <chunfeng.yun at mediatek.com>, "Greg Kroah-Hartman" <gregkh at linuxfoundation.org>, "Rob Herring" <robh+dt at kernel.org>, "Matthias Brugger" <matthias.bgg at gmail.com>, "Min Guo" <min.guo at mediatek.com>, "Frank Wunderlich" <frank-w at public-files.de>, devicetree at vger.kernel.org, linux-usb at vger.kernel.org, linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org, "Sungbo Eo" <mans0n at gorani.run>
> Betreff: [PATCH v3 1/1] arm: dts: mt7623: add musb device nodes
>
> MT7623 has an musb controller that is compatible with the one from MT2701.
>
> Signed-off-by: Sungbo Eo <mans0n at gorani.run>
> ---
> v3:
> * remove unnecessary status=okay from u2port2
>
> v2:
> * rename usb3 label to usb0
> * move usb0 & u2phy1 nodes to the right sorted place
> * disable u2phy1 by default
> * correct u2port2 node name to match its reg address
> ---
>  arch/arm/boot/dts/mt7623.dtsi  | 33 +++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
>  2 files changed, 37 insertions(+)
>
> diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
> index 3c11f7cfcc40..21c8a291b74e 100644
> --- a/arch/arm/boot/dts/mt7623.dtsi
> +++ b/arch/arm/boot/dts/mt7623.dtsi
> @@ -585,6 +585,39 @@ spi2: spi at 11017000 {
>  		status = "disabled";
>  	};
>
> +	usb0: usb at 11200000 {
> +		compatible = "mediatek,mt7623-musb",
> +			     "mediatek,mtk-musb";
> +		reg = <0 0x11200000 0 0x1000>;
> +		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
> +		interrupt-names = "mc";
> +		phys = <&u2port2 PHY_TYPE_USB2>;
> +		dr_mode = "otg";
> +		clocks = <&pericfg CLK_PERI_USB0>,
> +			 <&pericfg CLK_PERI_USB0_MCU>,
> +			 <&pericfg CLK_PERI_USB_SLV>;
> +		clock-names = "main","mcu","univpll";
> +		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
> +		status = "disabled";
> +	};
> +
> +	u2phy1: t-phy at 11210000 {
> +		compatible = "mediatek,mt7623-tphy",
> +			     "mediatek,generic-tphy-v1";
> +		reg = <0 0x11210000 0 0x0800>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +		status = "disabled";
> +
> +		u2port2: usb-phy at 11210800 {
> +			reg = <0 0x11210800 0 0x0100>;
> +			clocks = <&topckgen CLK_TOP_USB_PHY48M>;
> +			clock-names = "ref";
> +			#phy-cells = <1>;
> +		};
> +	};
> +
>  	audsys: clock-controller at 11220000 {
>  		compatible = "mediatek,mt7623-audsys",
>  			     "mediatek,mt2701-audsys",
> diff --git a/arch/arm/boot/dts/mt7623a.dtsi b/arch/arm/boot/dts/mt7623a.dtsi
> index 0735a1fb8ad9..d304b62d24b5 100644
> --- a/arch/arm/boot/dts/mt7623a.dtsi
> +++ b/arch/arm/boot/dts/mt7623a.dtsi
> @@ -35,6 +35,10 @@ &scpsys {
>  	clock-names = "ethif";
>  };
>
> +&usb0 {
> +	power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>;
> +};
> +
>  &usb1 {
>  	power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>;
>  };
> --
> 2.33.0
>
>


From u at pkh.me  Mon Aug 30 08:16:45 2021
From: u at pkh.me (=?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?=)
Date: Mon, 30 Aug 2021 17:16:45 +0200
Subject: [PATCH] arm64: dts: sun50i: h5: NanoPI Neo 2: phy-mode rgmii-id
Message-ID: <20210830151645.18018-1-u@pkh.me>

Since commit bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay
config") network is broken on the NanoPi Neo 2.

This patch changes the phy-mode to use internal delays both for RX and
TX as has been done for other boards affected by the same commit.

Fixes: bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay config")
Signed-off-by: Cl?ment B?sch <u at pkh.me>
---
 arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
index 02f8e72f0cad..05486cccee1c 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
@@ -75,7 +75,7 @@ &emac {
 	pinctrl-0 = <&emac_rgmii_pins>;
 	phy-supply = <&reg_gmac_3v3>;
 	phy-handle = <&ext_rgmii_phy>;
-	phy-mode = "rgmii";
+	phy-mode = "rgmii-id";
 	status = "okay";
 };
 
-- 
2.33.0



From robh+dt at kernel.org  Mon Aug 30 08:57:59 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 10:57:59 -0500
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <87pmtvcgec.wl-maz@kernel.org>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-5-mark.kettenis@xs4all.nl>
 <87pmtvcgec.wl-maz@kernel.org>
Message-ID: <CAL_JsqJC+FxiynFkkcB0amp3s4agsio5ggCrYiPbqoXroAJV4Q@mail.gmail.com>

On Mon, Aug 30, 2021 at 6:37 AM Marc Zyngier <maz at kernel.org> wrote:
>
> Hi Mark,
>
> On Fri, 27 Aug 2021 18:15:29 +0100,
> Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
> >
> > From: Mark Kettenis <kettenis at openbsd.org>
> >
> > Add node corresponding to the apcie,t8103 node in the
> > Apple device tree for the Mac mini (M1, 2020).
> >
> > Clock references and DART (IOMMU) references are left out at the
> > moment and will be added once the appropriate bindings have been
> > settled upon.
> >
> > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > ---
> >  arch/arm64/boot/dts/apple/t8103.dtsi | 63 ++++++++++++++++++++++++++++
> >  1 file changed, 63 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
> > index 503a76fc30e6..6e4677bdef44 100644
> > --- a/arch/arm64/boot/dts/apple/t8103.dtsi
> > +++ b/arch/arm64/boot/dts/apple/t8103.dtsi
> > @@ -214,5 +214,68 @@ pinctrl_smc: pinctrl at 23e820000 {
> >                                    <AIC_IRQ 396 IRQ_TYPE_LEVEL_HIGH>,
> >                                    <AIC_IRQ 397 IRQ_TYPE_LEVEL_HIGH>;
> >               };
> > +
> > +             pcie0: pcie at 690000000 {
> > +                     compatible = "apple,t8103-pcie", "apple,pcie";
> > +                     device_type = "pci";
> > +
> > +                     reg = <0x6 0x90000000 0x0 0x1000000>,
> > +                           <0x6 0x80000000 0x0 0x4000>,
> > +                           <0x6 0x81000000 0x0 0x8000>,
> > +                           <0x6 0x82000000 0x0 0x8000>,
> > +                           <0x6 0x83000000 0x0 0x8000>;
> > +                     reg-names = "config", "rc", "port0", "port1", "port2";
> > +
> > +                     interrupt-parent = <&aic>;
> > +                     interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
> > +                                  <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
> > +                                  <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
> > +
> > +                     msi-controller;
> > +                     msi-parent = <&pcie0>;
> > +                     msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
> > +
> > +                     bus-range = <0 3>;
> > +                     #address-cells = <3>;
> > +                     #size-cells = <2>;
> > +                     ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 0x0 0x20000000>,
> > +                              <0x02000000 0x0 0xc0000000 0x6 0xc0000000 0x0 0x40000000>;
> > +
> > +                     pinctrl-0 = <&pcie_pins>;
> > +                     pinctrl-names = "default";
> > +
> > +                     pci at 0,0 {
> > +                             device_type = "pci";
> > +                             reg = <0x0 0x0 0x0 0x0 0x0>;
> > +                             reset-gpios = <&pinctrl_ap 152 0>;
> > +                             max-link-speed = <2>;
> > +
> > +                             #address-cells = <3>;
> > +                             #size-cells = <2>;
> > +                             ranges;
> > +                     };
> > +
> > +                     pci at 1,0 {
> > +                             device_type = "pci";
> > +                             reg = <0x800 0x0 0x0 0x0 0x0>;
> > +                             reset-gpios = <&pinctrl_ap 153 0>;
> > +                             max-link-speed = <2>;
> > +
> > +                             #address-cells = <3>;
> > +                             #size-cells = <2>;
> > +                             ranges;
> > +                     };
> > +
> > +                     pci at 2,0 {
> > +                             device_type = "pci";
> > +                             reg = <0x1000 0x0 0x0 0x0 0x0>;
> > +                             reset-gpios = <&pinctrl_ap 33 0>;
> > +                             max-link-speed = <1>;
> > +
> > +                             #address-cells = <3>;
> > +                             #size-cells = <2>;
> > +                             ranges;
> > +                     };
> > +             };
> >       };
> >  };
>
> I have now implemented the MSI change on the Linux driver side, and it
> works nicely. So thumbs up from me on this front.
>
> I am now looking at the interrupts provided by each port:
> (1) a bunch of port-private interrupts (link up/down...)
> (2) INTx interrupts

So each port has an independent INTx space? Is that even something PCI
defines or comprehends?

> Given that the programming is per-port, I've implemented this as a
> per-port interrupt controller.
>
> (1) is dead easy to implement, and doesn't require any DT description.
> (2) is unfortunately exposing the limits of my DT knowledge, and I'm
> not clear how to model it. I came up with the following:
>
>         port00: pci at 0,0 {
>                 device_type = "pci";
>                 reg = <0x0 0x0 0x0 0x0 0x0>;
>                 reset-gpios = <&pinctrl_ap 152 0>;
>                 max-link-speed = <2>;
>
>                 #address-cells = <3>;
>                 #size-cells = <2>;
>                 ranges;
>
>                 interrupt-controller;
>                 #interrupt-cells = <1>;
>                 interrupt-parent = <&port00>;
>                 interrupt-map-mask = <0 0 0 7>;
>                 interrupt-map = <0 0 0 1 &port00 0>,
>                                 <0 0 0 2 &port00 1>,
>                                 <0 0 0 3 &port00 2>,
>                                 <0 0 0 4 &port00 3>;

IIRC, I don't think the DT IRQ code handles a node having both
'interrupt-controller' and 'interrupt-map' properties. I think that's
why some PCI host bridge nodes have child interrupt-controller nodes.
I don't really like that work-around, so if the above can be made to
work, I'd be happy to see it. But the DT IRQ code is some ancient code
for ancient platforms (PowerMacs being one of them).

>         };
>
> which vaguely seem to do the right thing for the devices behind root
> ports, but doesn't seem to work for INTx generated by the root ports
> themselves. Any clue? Alternatively, I could move it to something
> global to the whole PCIe controller, but that doesn't seem completely
> right.
>
> It also begs the question whether the per-port interrupt to the AIC
> should be moved into each root port, should my per-port approach hold
> any water.

I tend to think per-port is the right thing to do. However, the child
nodes are PCI devices, so that creates some restrictions. Such as the
per port registers are in the host address space, not the PCI address
space, so we can't move the registers into the child nodes. The
interrupts may be okay. Certainly, being an 'interrupt-controller'
without having an 'interrupts' property for an non root interrupt
controller is odd.

Rob


From mans0n at gorani.run  Mon Aug 30 08:59:01 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Tue, 31 Aug 2021 00:59:01 +0900
Subject: [PATCH v4 0/2] Add MUSB for MT7623
In-Reply-To: <20210822041333.5264-1-mans0n@gorani.run>
References: <20210822041333.5264-1-mans0n@gorani.run>
Message-ID: <20210830155903.13907-1-mans0n@gorani.run>

These patches add support for the MUSB controller on Mediatek MT7623.
Tested on Mercury RUSH-318AC Wi-Fi router.

v4:
* DTS
  * add tested by Frank
* musb
  * add userspace control flag patch

v3:
* dt-bindings
  * remove the queued patch
* DTS
  * remove unnecessary status=okay from u2port2

v2:
* dt-bindings
  * add reviewed by Matthias
* DTS
  * rename usb3 label to usb0
  * move usb0 & u2phy1 nodes to the right sorted place
  * disable u2phy1 by default
  * correct u2port2 node name to match its reg address

Sungbo Eo (2):
  arm: dts: mt7623: add musb device nodes
  usb: musb: mediatek: Expose role-switch control to userspace

 arch/arm/boot/dts/mt7623.dtsi  | 33 +++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
 drivers/usb/musb/mediatek.c    |  1 +
 3 files changed, 38 insertions(+)

-- 
2.33.0



From mans0n at gorani.run  Mon Aug 30 08:59:03 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Tue, 31 Aug 2021 00:59:03 +0900
Subject: [PATCH v4 2/2] usb: musb: mediatek: Expose role-switch control to
 userspace
In-Reply-To: <20210830155903.13907-1-mans0n@gorani.run>
References: <20210822041333.5264-1-mans0n@gorani.run>
 <20210830155903.13907-1-mans0n@gorani.run>
Message-ID: <20210830155903.13907-3-mans0n@gorani.run>

The allow_userspace_control flag enables manual role-switch from userspace.
Turn this feature on like several other USB DRD controller drivers.

Signed-off-by: Sungbo Eo <mans0n at gorani.run>
Tested-by: Frank Wunderlich <frank-w at public-files.de>
---
 drivers/usb/musb/mediatek.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c
index 6b92d037d8fc..f5d97eb84cb5 100644
--- a/drivers/usb/musb/mediatek.c
+++ b/drivers/usb/musb/mediatek.c
@@ -185,6 +185,7 @@ static int mtk_otg_switch_init(struct mtk_glue *glue)
 
 	role_sx_desc.set = musb_usb_role_sx_set;
 	role_sx_desc.get = musb_usb_role_sx_get;
+	role_sx_desc.allow_userspace_control = true;
 	role_sx_desc.fwnode = dev_fwnode(glue->dev);
 	role_sx_desc.driver_data = glue;
 	glue->role_sw = usb_role_switch_register(glue->dev, &role_sx_desc);
-- 
2.33.0



From mans0n at gorani.run  Mon Aug 30 08:59:02 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Tue, 31 Aug 2021 00:59:02 +0900
Subject: [PATCH v4 1/2] arm: dts: mt7623: add musb device nodes
In-Reply-To: <20210830155903.13907-1-mans0n@gorani.run>
References: <20210822041333.5264-1-mans0n@gorani.run>
 <20210830155903.13907-1-mans0n@gorani.run>
Message-ID: <20210830155903.13907-2-mans0n@gorani.run>

MT7623 has an musb controller that is compatible with the one from MT2701.

Signed-off-by: Sungbo Eo <mans0n at gorani.run>
Tested-by: Frank Wunderlich <frank-w at public-files.de>
---
v4:
* add tested by Frank

v3:
* remove unnecessary status=okay from u2port2

v2:
* rename usb3 label to usb0
* move usb0 & u2phy1 nodes to the right sorted place
* disable u2phy1 by default
* correct u2port2 node name to match its reg address
---
 arch/arm/boot/dts/mt7623.dtsi  | 33 +++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
index 3c11f7cfcc40..21c8a291b74e 100644
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -585,6 +585,39 @@ spi2: spi at 11017000 {
 		status = "disabled";
 	};
 
+	usb0: usb at 11200000 {
+		compatible = "mediatek,mt7623-musb",
+			     "mediatek,mtk-musb";
+		reg = <0 0x11200000 0 0x1000>;
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "mc";
+		phys = <&u2port2 PHY_TYPE_USB2>;
+		dr_mode = "otg";
+		clocks = <&pericfg CLK_PERI_USB0>,
+			 <&pericfg CLK_PERI_USB0_MCU>,
+			 <&pericfg CLK_PERI_USB_SLV>;
+		clock-names = "main","mcu","univpll";
+		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
+		status = "disabled";
+	};
+
+	u2phy1: t-phy at 11210000 {
+		compatible = "mediatek,mt7623-tphy",
+			     "mediatek,generic-tphy-v1";
+		reg = <0 0x11210000 0 0x0800>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "disabled";
+
+		u2port2: usb-phy at 11210800 {
+			reg = <0 0x11210800 0 0x0100>;
+			clocks = <&topckgen CLK_TOP_USB_PHY48M>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+		};
+	};
+
 	audsys: clock-controller at 11220000 {
 		compatible = "mediatek,mt7623-audsys",
 			     "mediatek,mt2701-audsys",
diff --git a/arch/arm/boot/dts/mt7623a.dtsi b/arch/arm/boot/dts/mt7623a.dtsi
index 0735a1fb8ad9..d304b62d24b5 100644
--- a/arch/arm/boot/dts/mt7623a.dtsi
+++ b/arch/arm/boot/dts/mt7623a.dtsi
@@ -35,6 +35,10 @@ &scpsys {
 	clock-names = "ethif";
 };
 
+&usb0 {
+	power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>;
+};
+
 &usb1 {
 	power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>;
 };
-- 
2.33.0



From pali at kernel.org  Mon Aug 30 08:59:45 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Mon, 30 Aug 2021 17:59:45 +0200
Subject: [PATCH v2 1/2] PCI: uniphier: Fix INTx mask/unmask bit operation
 and remove ack function
In-Reply-To: <1630290158-31264-2-git-send-email-hayashi.kunihiko@socionext.com>
References: <1630290158-31264-1-git-send-email-hayashi.kunihiko@socionext.com>
 <1630290158-31264-2-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <20210830155945.yuirq5tsy2migovk@pali>

On Monday 30 August 2021 11:22:37 Kunihiko Hayashi wrote:
> INTX mask and unmask fields in PCL_RCV_INTX register should only be
> set/reset for each bit. Clearing by PCL_RCV_INTX_ALL_MASK should be
> removed.
> 
> INTX status fields in PCL_RCV_INTX register only indicates each INTX
> interrupt status, so the handler can't clear by writing 1 to the field.
> The status is expected to be cleared by the interrupt origin.
> The ack function has no meaning, so should remove it.
> 
> Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support")
> Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>

Acked-by: Pali Roh?r <pali at kernel.org>

> ---
>  drivers/pci/controller/dwc/pcie-uniphier.c | 16 ----------------
>  1 file changed, 16 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
> index ebe43e9..26f630c 100644
> --- a/drivers/pci/controller/dwc/pcie-uniphier.c
> +++ b/drivers/pci/controller/dwc/pcie-uniphier.c
> @@ -181,19 +181,6 @@ static void uniphier_pcie_irq_enable(struct uniphier_pcie_priv *priv)
>  	writel(PCL_RCV_INTX_ALL_ENABLE, priv->base + PCL_RCV_INTX);
>  }
>  
> -static void uniphier_pcie_irq_ack(struct irq_data *d)
> -{
> -	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
> -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> -	struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci);
> -	u32 val;
> -
> -	val = readl(priv->base + PCL_RCV_INTX);
> -	val &= ~PCL_RCV_INTX_ALL_STATUS;
> -	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT);
> -	writel(val, priv->base + PCL_RCV_INTX);
> -}
> -
>  static void uniphier_pcie_irq_mask(struct irq_data *d)
>  {
>  	struct pcie_port *pp = irq_data_get_irq_chip_data(d);
> @@ -202,7 +189,6 @@ static void uniphier_pcie_irq_mask(struct irq_data *d)
>  	u32 val;
>  
>  	val = readl(priv->base + PCL_RCV_INTX);
> -	val &= ~PCL_RCV_INTX_ALL_MASK;
>  	val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
>  	writel(val, priv->base + PCL_RCV_INTX);
>  }
> @@ -215,14 +201,12 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d)
>  	u32 val;
>  
>  	val = readl(priv->base + PCL_RCV_INTX);
> -	val &= ~PCL_RCV_INTX_ALL_MASK;
>  	val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT);
>  	writel(val, priv->base + PCL_RCV_INTX);
>  }
>  
>  static struct irq_chip uniphier_pcie_irq_chip = {
>  	.name = "PCI",
> -	.irq_ack = uniphier_pcie_irq_ack,
>  	.irq_mask = uniphier_pcie_irq_mask,
>  	.irq_unmask = uniphier_pcie_irq_unmask,
>  };
> -- 
> 2.7.4
> 


From robh+dt at kernel.org  Mon Aug 30 09:00:08 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 11:00:08 -0500
Subject: [PATCH v6 0/3] Visconti: Add Toshiba Visconti PCIe host
 controller driver
In-Reply-To: <162998285902.30814.11206633831020646086.b4-ty@arm.com>
References: <20210811083830.784065-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <162998285902.30814.11206633831020646086.b4-ty@arm.com>
Message-ID: <CAL_JsqK=e4cRHXV=ptFTrtt995arOjhNPmTJK8hWg-aDkU4dpQ@mail.gmail.com>

On Thu, Aug 26, 2021 at 8:01 AM Lorenzo Pieralisi
<lorenzo.pieralisi at arm.com> wrote:
>
> On Wed, 11 Aug 2021 17:38:27 +0900, Nobuhiro Iwamatsu wrote:
> > This series is the PCIe driver for Toshiba's ARM SoC, Visconti[0].
> > This provides DT binding documentation, device driver, MAINTAINER files.
> >
> > Best regards,
> >   Nobuhiro
> >
> > [0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html
> >
> > [...]
>
> Applied to pci/dwc, thanks!
>
> [1/3] dt-bindings: pci: Add DT binding for Toshiba Visconti PCIe controller
>       https://git.kernel.org/lpieralisi/pci/c/a655ce4000

This is already in my tree due to the DW schema conversion.

Rob


From robh+dt at kernel.org  Mon Aug 30 09:02:28 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 11:02:28 -0500
Subject: [PATCH v2] dt-bindings: PCI: mediatek-gen3: Add support for MT8195
In-Reply-To: <20210827022638.3573-1-jianjun.wang@mediatek.com>
References: <20210827022638.3573-1-jianjun.wang@mediatek.com>
Message-ID: <CAL_JsqJTW=ot=BBWQfOj9rJ82dnVV21TpHGf3vieUQ_Jd8i9Rg@mail.gmail.com>

On Thu, Aug 26, 2021 at 9:26 PM Jianjun Wang <jianjun.wang at mediatek.com> wrote:
>
> MT8195 is an ARM platform SoC which has the same PCIe IP with MT8192.
>
> Signed-off-by: Jianjun Wang <jianjun.wang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> index 742206dbd965..93e09c3029b7 100644
> --- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
> @@ -48,7 +48,9 @@ allOf:
>
>  properties:
>    compatible:
> -    const: mediatek,mt8192-pcie
> +    enum:
> +      - mediatek,mt8192-pcie
> +      - mediatek,mt8195-pcie

I thought you wanted to support 8192 as the fallback:

compatible = "mediatek,mt8195-pcie", "mediatek,mt8192-pcie";

The above schema doesn't allow this.

Rob


From wens at kernel.org  Mon Aug 30 09:03:00 2021
From: wens at kernel.org (Chen-Yu Tsai)
Date: Tue, 31 Aug 2021 00:03:00 +0800
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <568a0825-ed65-58d7-9c9c-cecb481cf9d9@wolfvision.net>
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
 <CAGb2v67Duk_56fOKVwZsYn2HKJ99o8WJ+d4jetD2UjDsAt9BcA@mail.gmail.com>
 <568a0825-ed65-58d7-9c9c-cecb481cf9d9@wolfvision.net>
Message-ID: <CAGb2v658bD91LereM-Mc-2usEq-RH=pn_8bR9fEgmDUqpi5OoQ@mail.gmail.com>

Hi,

On Mon, Aug 30, 2021 at 3:57 PM Michael Riesch
<michael.riesch at wolfvision.net> wrote:
>
> Hi ChenYu,
>
> On 8/29/21 7:48 PM, Chen-Yu Tsai wrote:
> > Hi,
> >
> > On Mon, Aug 23, 2021 at 10:39 PM Michael Riesch
> > <michael.riesch at wolfvision.net> wrote:
> >>
> >> This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
> >> "net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
> >> unbalanced pm_runtime_enable warnings.
> >>
> >> In the commit to be reverted, support for power management was
> >> introduced to the Rockchip glue code. Later, power management support
> >> was introduced to the stmmac core code, resulting in multiple
> >> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
> >>
> >> The multiple invocations happen in rk_gmac_powerup and
> >> stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
> >> stmmac_{dvr_remove, suspend}, respectively, which are always called
> >> in conjunction.
> >>
> >> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> >
> > I just found that Ethernet stopped working on my RK3399 devices,
> > and I bisected it down to this patch.
>
> Oh dear. First patch in a kernel release for a while and I already break
> things.
>
> Cc: Sasha as this patch has just been applied to 5.13-stable.
>
> > The symptom I see is no DHCP responses, either because the request
> > isn't getting sent over the wire, or the response isn't getting
> > received. The PHY seems to be working correctly.
>
> Unfortunately I don't have any RK3399 hardware. Is this a custom
> board/special hardware or something that is readily available in the
> shops? Maybe this is a good reason to buy a RK3399 based single-board
> computer :-)

I hit this on an ROC-RK3399-PC first, then bisected it on a NanoPi M4V2.
They both should be easy to get from their respective vendors. AFAIK
all the RK3399 devices have pretty much the same setup for Ethernet.

BTW, Don't get the Nanopi in the M4V2 variant. Get the original M4, or
the M4B (but the WiFi on the M4B doesn't seem to work lately).

> I am working on the RK3568 EVB1 and have not encountered faulty
> behavior. DHCP works fine and I can boot via NFS. Therefore, not sure
> whether I can be much of help in this matter, but in case you want to
> discuss this further please do not hesitate to contact me off-list.

My gut is telling me (without looking at the code) that maybe the GRF
access was not going through, and so the RGMII delays and stuff weren't
set properly, hence no traffic getting to/from the PHY. Otherwise there
were no error messages. I don't think I'll be able to squeeze out more
cycles to track down what actually went wrong though.


Regards
ChenYu


From jeremy.linton at arm.com  Mon Aug 30 09:10:55 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Mon, 30 Aug 2021 11:10:55 -0500
Subject: [PATCH v2 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <20210829111330.22f6n3tvmm246jzg@pali>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
 <20210819215655.84866-3-jeremy.linton@arm.com>
 <20210829111330.22f6n3tvmm246jzg@pali>
Message-ID: <40bba0af-0a70-ab65-581e-e0c308c8f1d9@arm.com>

Hi,

On 8/29/21 6:13 AM, Pali Roh?r wrote:
> On Thursday 19 August 2021 16:56:53 Jeremy Linton wrote:
>> The PFTF CM4 is an ACPI platform that isn't ECAM compliant. Its config
>> space is in two parts. One part is for the root port registers and a
>> second moveable window pointing at a device's 4K config space. Thus it
>> doesn't have an MCFG, and any MCFG provided would be nonsense
>> anyway. Instead, a Linux specific host bridge _DSD selects a custom
>> ECAM ops and cfgres. The cfg op picks between those two regions while
>> disallowing problematic accesses.
> 
> I'm not sure if Lorenzo would like this patch series...

That was sorta true since the arm64/ACPI/PCI patches landed. The 
underlying reason is the desire for arm platforms to require less 
one-off kernel patching in order to "just work". But, its become 
apparent that there continue to be problems with PCIe IP and Arm 
interconnect integration. So, a firmware interface was standardized 
which solves most of the nonstandard ECAM issues. At that point it was 
decided though that the kernel maintainers would prefer to have the 
quirks visible to the kernel rather than hidden in the firmware, and 
that they would be more open to merging these quirks. The Tegra patch 
you listed above has been merged.

More info about this: https://lkml.org/lkml/2021/3/25/777


Thanks,

> 
> In past there was a long discussion about ECAM compliance, MCFG quirks
> and usage of ACPI (on other platform), see long thread:
> https://lore.kernel.org/linux-pci/20200207183427.GA40158 at google.com/
> 
> And I think it is not a good idea to extend MCFG quirks table as
> according to discussion it was just temporary plaster and if platform is
> not ACPI / ECAM compliant then it should use DT booting...
> 
> Lorenzo, could you put any comment on this?
> 
>> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
>> ---
>>   drivers/pci/controller/Makefile            |  1 +
>>   drivers/pci/controller/pcie-brcmstb-acpi.c | 74 ++++++++++++++++++++++
>>   include/linux/pci-ecam.h                   |  1 +
>>   3 files changed, 76 insertions(+)
>>   create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
>>
>> diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
>> index aaf30b3dcc14..65aa6fd3ed89 100644
>> --- a/drivers/pci/controller/Makefile
>> +++ b/drivers/pci/controller/Makefile
>> @@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
>>   obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
>>   obj-$(CONFIG_ARM64) += pci-thunder-pem.o
>>   obj-$(CONFIG_ARM64) += pci-xgene.o
>> +obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
>>   endif
>>   endif
>> diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
>> new file mode 100644
>> index 000000000000..71f6def3074c
>> --- /dev/null
>> +++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
>> @@ -0,0 +1,74 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * ACPI quirks for Brcm2711 PCIe host controller
>> + * As used on the Raspberry Pi Compute Module 4
>> + *
>> + * Copyright (C) 2021 Arm Ltd.
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/pci.h>
>> +#include <linux/pci-ecam.h>
>> +#include "../pci.h"
>> +#include "pcie-brcmstb.h"
>> +
>> +static int brcm_acpi_init(struct pci_config_window *cfg)
>> +{
>> +	/*
>> +	 * This platform doesn't technically have anything that could be called
>> +	 * ECAM. Its config region has root port specific registers between
>> +	 * standard PCIe defined config registers. Thus the region setup by the
>> +	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
>> +	 * but the footprint isn't a nice power of 2 (40k). For purposes of
>> +	 * mapping the config region we are just going to squash the standard
>> +	 * and nonstandard registers together rather than mapping them separately.
>> +	 */
>> +	iounmap(cfg->win);
>> +	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
>> +	if (!cfg->win)
>> +		goto err_exit;
>> +
>> +	/* MSI is nonstandard as well */
>> +	pci_no_msi();
>> +
>> +	return 0;
>> +err_exit:
>> +	dev_err(cfg->parent, "PCI: Failed to remap config\n");
>> +	return -ENOMEM;
>> +}
>> +
>> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
>> +					unsigned int devfn, int where)
>> +{
>> +	struct pci_config_window *cfg = bus->sysdata;
>> +	void __iomem *base = cfg->win;
>> +	int idx;
>> +	u32 up;
>> +
>> +	/* Accesses to the RC go right to the RC registers if slot==0 */
>> +	if (pci_is_root_bus(bus))
>> +		return PCI_SLOT(devfn) ? NULL : base + where;
>> +
>> +	/* Assure link up before sending request */
>> +	up = readl(base + PCIE_MISC_PCIE_STATUS);
>> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
>> +		return NULL;
>> +
>> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
>> +		return NULL;
>> +
>> +	/* For devices, write to the config space index register */
>> +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
>> +	writel(idx, base + PCIE_EXT_CFG_INDEX);
>> +	return base + PCIE_EXT_CFG_DATA + where;
>> +}
>> +
>> +const struct pci_ecam_ops bcm2711_pcie_ops = {
>> +	.init		= brcm_acpi_init,
>> +	.bus_shift	= 1,
>> +	.pci_ops	= {
>> +		.map_bus	= brcm_pcie_map_conf2,
>> +		.read		= pci_generic_config_read,
>> +		.write		= pci_generic_config_write,
>> +	}
>> +};
>> diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
>> index adea5a4771cf..a5de0285bb7f 100644
>> --- a/include/linux/pci-ecam.h
>> +++ b/include/linux/pci-ecam.h
>> @@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
>>   extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
>>   extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
>>   extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
>> +extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
>>   #endif
>>   
>>   #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
>> -- 
>> 2.31.1
>>



From jeremy.linton at arm.com  Mon Aug 30 09:23:27 2021
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Mon, 30 Aug 2021 11:23:27 -0500
Subject: [PATCH v3 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <44ad79081412af289c68e74cdecb6a2baa2e873c.camel@kernel.org>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
 <20210826071557.29239-3-jeremy.linton@arm.com>
 <44ad79081412af289c68e74cdecb6a2baa2e873c.camel@kernel.org>
Message-ID: <5c39cf29-a08f-48d1-b873-ce0fda763d66@arm.com>

Hi,

On 8/30/21 3:36 AM, nicolas saenz julienne wrote:
> Hi Jeremy,
> sorry for the late reply, I've been on vacation.
> 
> On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
> 
> [...]
> 
>> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
>> +					unsigned int devfn, int where)
>> +{
>> +	struct pci_config_window *cfg = bus->sysdata;
>> +	void __iomem *base = cfg->win;
>> +	int idx;
>> +	u32 up;
>> +
>> +	/* Accesses to the RC go right to the RC registers if slot==0 */
>> +	if (pci_is_root_bus(bus))
>> +		return PCI_SLOT(devfn) ? NULL : base + where;
>> +
>> +	/*
>> +	 * Assure the link is up before sending requests downstream. This is done
>> +	 * to avoid sending transactions to EPs that don't exist. Link flap
>> +	 * conditions/etc make this race more probable. The resulting unrecoverable
>> +	 * SERRORs will result in the machine crashing.
>> +	 */
>> +	up = readl(base + PCIE_MISC_PCIE_STATUS);
>> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
>> +		return NULL;
>> +
>> +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
>> +		return NULL;
> 
> Couldn't this be integrated in the original brcm_pcie_map_conf()? IIUC there is
> nothing ACPI specific about it. It'd also make for less code duplication.

That is where I started with this, but it wasn't the linkup check/etc 
which caused me to hoist it but the fact that if ACPI quirks are enabled 
they end up statically built into the kernel. While if this host bridge 
is enabled, it can end up being a module, and the resulting mess I 
created trying to satisfy the CONFIG variations. I'm not much of a fan 
of copy/paste programming, but that IMHO ended up being the cleanest here.



From f.fainelli at gmail.com  Mon Aug 30 09:27:26 2021
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 30 Aug 2021 09:27:26 -0700
Subject: [PATCH v3 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <5c39cf29-a08f-48d1-b873-ce0fda763d66@arm.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
 <20210826071557.29239-3-jeremy.linton@arm.com>
 <44ad79081412af289c68e74cdecb6a2baa2e873c.camel@kernel.org>
 <5c39cf29-a08f-48d1-b873-ce0fda763d66@arm.com>
Message-ID: <f6860e38-c6fa-292d-f1a1-22b3e4b48f32@gmail.com>



On 8/30/2021 9:23 AM, Jeremy Linton wrote:
> Hi,
> 
> On 8/30/21 3:36 AM, nicolas saenz julienne wrote:
>> Hi Jeremy,
>> sorry for the late reply, I've been on vacation.
>>
>> On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
>>
>> [...]
>>
>>> +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
>>> +??????????????????? unsigned int devfn, int where)
>>> +{
>>> +??? struct pci_config_window *cfg = bus->sysdata;
>>> +??? void __iomem *base = cfg->win;
>>> +??? int idx;
>>> +??? u32 up;
>>> +
>>> +??? /* Accesses to the RC go right to the RC registers if slot==0 */
>>> +??? if (pci_is_root_bus(bus))
>>> +??????? return PCI_SLOT(devfn) ? NULL : base + where;
>>> +
>>> +??? /*
>>> +???? * Assure the link is up before sending requests downstream. 
>>> This is done
>>> +???? * to avoid sending transactions to EPs that don't exist. Link flap
>>> +???? * conditions/etc make this race more probable. The resulting 
>>> unrecoverable
>>> +???? * SERRORs will result in the machine crashing.
>>> +???? */
>>> +??? up = readl(base + PCIE_MISC_PCIE_STATUS);
>>> +??? if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
>>> +??????? return NULL;
>>> +
>>> +??? if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
>>> +??????? return NULL;
>>
>> Couldn't this be integrated in the original brcm_pcie_map_conf()? IIUC 
>> there is
>> nothing ACPI specific about it. It'd also make for less code duplication.
> 
> That is where I started with this, but it wasn't the linkup check/etc 
> which caused me to hoist it but the fact that if ACPI quirks are enabled 
> they end up statically built into the kernel. While if this host bridge 
> is enabled, it can end up being a module, and the resulting mess I 
> created trying to satisfy the CONFIG variations. I'm not much of a fan 
> of copy/paste programming, but that IMHO ended up being the cleanest here.
> 

Agreed, the open coding that is being done is reasonable IHMO, although 
we may have to update the link up code in both pcie-brcmstb.c and this 
file in the future if offsets/bits do change, nothing impossible though.
-- 
Florian


From nsaenzju at redhat.com  Mon Aug 30 09:45:31 2021
From: nsaenzju at redhat.com (nsaenzju at redhat.com)
Date: Mon, 30 Aug 2021 18:45:31 +0200
Subject: [PATCH] ARM: dts: bcm2711-rpi-4-b: Fix pcie0's unit address
In-Reply-To: <YSzfoyesEzAuLkSS@robh.at.kernel.org>
References: <20210830103909.323356-1-nsaenzju@redhat.com>
 <YSzfoyesEzAuLkSS@robh.at.kernel.org>
Message-ID: <22bbfdefb2b9a1a65a807d0aecee67e607b7ff60.camel@redhat.com>

On Mon, 2021-08-30 at 08:39 -0500, Rob Herring wrote:
> On Mon, Aug 30, 2021 at 12:39:09PM +0200, Nicolas Saenz Julienne wrote:
> > dtbs_check currently complains that:
> > 
> > arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning
> > (pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format
> > error, expected "0,0"
> > 
> > Unsurprisingly pci at 0,0 is the right address, as illustrated by its reg
> > property:
> > 
> > 	&pcie0 {
> > 		pci at 0,0 {
> > 			/*
> > 			 * As defined in the IEEE Std 1275-1994 document,
> > 			 * reg is a five-cell address encoded as (phys.hi
> > 			 * phys.mid phys.lo size.hi size.lo). phys.hi
> > 			 * should contain the device's BDF as 0b00000000
> > 			 * bbbbbbbb dddddfff 00000000. The other cells
> > 			 * should be zero.
> > 			 */
> > 			reg = <0 0 0 0 0>;
> > 		};
> > 	};
> > 
> > The bus is clearly 0. So fix it.
> 
> s/bus/device/
> 
> The unit-address format is '<device>,<function>' (and function is 
> optional). The bus number is not part of the unit-address because that 
> is dynamic and then the path would not be fixed/known. The bus is part 
> of 'reg' for true OpenFirmware, but for FDT I think it should always be 
> 0 as the DT is static. 
> 
> Looks like the child node is wrong (both unit-address and reg) as well:
> 
>                 usb at 1,0 {
>                         reg = <0x10000 0 0 0 0>;
>                         resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
>                 };
> 
> It doesn't warn because the bridge node is also missing 'device_type = 
> "pci";'.
> 
> This is all fairly hard to get right (see recent hikey970 patches for a 
> complex example). I'm thinking about writing a tool that generates a DT 
> with PCI nodes by reading the PCI hierachy from sysfs.

Just to double-check I understood everything, with:

	lspci -D -PP
	0000:00:00.0 PCI bridge: Broadcom Inc. and subsidiaries BCM2711 PCIe Bridge (rev 10)
	0000:00:00.0/01:00.0 USB controller: VIA Technologies, Inc. VL805/806 xHCI USB 3.0 Controller (rev 01)

It should look like this:

	&pcie0 {
		pci at 0,0 {
			device_type = "pci";
			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			reg = <0 0 0 0 0>;

			usb at 0,0 {
				reg = <0 0 0 0 0>;
				resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
			};
		};
	};

Thanks!

-- 
Nicol?s S?enz



From michael at walle.cc  Mon Aug 30 09:51:13 2021
From: michael at walle.cc (Michael Walle)
Date: Mon, 30 Aug 2021 18:51:13 +0200
Subject: [PATCH] arm64: dts: hisilicon: fix arm,sp805 compatible string
Message-ID: <20210830165113.222867-1-michael@walle.cc>

According to Documentation/devicetree/bindings/watchdog/arm,sp805.yaml
the compatible is:
  compatible = "arm,sp805", "arm,primecell";

The current compatible string doesn't exist at all. Fix it.

Signed-off-by: Michael Walle <michael at walle.cc>
---
There are also the layerscape SoC which are using these compatible
strings. I'm on it to change these, too.

 arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 4 ++--
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
index 2d5c1a348716..6eabec2602e2 100644
--- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi
@@ -1087,7 +1087,7 @@ dwmmc2: dwmmc2 at ff3ff000 {
 		};
 
 		watchdog0: watchdog at e8a06000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xe8a06000 0x0 0x1000>;
 			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&crg_ctrl HI3660_OSC32K>,
@@ -1096,7 +1096,7 @@ watchdog0: watchdog at e8a06000 {
 		};
 
 		watchdog1: watchdog at e8a07000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xe8a07000 0x0 0x1000>;
 			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&crg_ctrl HI3660_OSC32K>,
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index dde9371dc545..e4860b8a638e 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -840,7 +840,7 @@ dwmmc_2: dwmmc2 at f723f000 {
 		};
 
 		watchdog0: watchdog at f8005000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xf8005000 0x0 0x1000>;
 			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&ao_ctrl HI6220_WDT0_PCLK>,
-- 
2.30.2



From pali at kernel.org  Mon Aug 30 09:54:13 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Mon, 30 Aug 2021 18:54:13 +0200
Subject: [PATCH v2 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <40bba0af-0a70-ab65-581e-e0c308c8f1d9@arm.com>
References: <20210819215655.84866-1-jeremy.linton@arm.com>
 <20210819215655.84866-3-jeremy.linton@arm.com>
 <20210829111330.22f6n3tvmm246jzg@pali>
 <40bba0af-0a70-ab65-581e-e0c308c8f1d9@arm.com>
Message-ID: <20210830165413.r53csq3mzzgoo6iy@pali>

On Monday 30 August 2021 11:10:55 Jeremy Linton wrote:
> Hi,
> 
> On 8/29/21 6:13 AM, Pali Roh?r wrote:
> > On Thursday 19 August 2021 16:56:53 Jeremy Linton wrote:
> > > The PFTF CM4 is an ACPI platform that isn't ECAM compliant. Its config
> > > space is in two parts. One part is for the root port registers and a
> > > second moveable window pointing at a device's 4K config space. Thus it
> > > doesn't have an MCFG, and any MCFG provided would be nonsense
> > > anyway. Instead, a Linux specific host bridge _DSD selects a custom
> > > ECAM ops and cfgres. The cfg op picks between those two regions while
> > > disallowing problematic accesses.
> > 
> > I'm not sure if Lorenzo would like this patch series...
> 
> That was sorta true since the arm64/ACPI/PCI patches landed. The underlying
> reason is the desire for arm platforms to require less one-off kernel
> patching in order to "just work". But, its become apparent that there
> continue to be problems with PCIe IP and Arm interconnect integration. So, a
> firmware interface was standardized which solves most of the nonstandard
> ECAM issues. At that point it was decided though that the kernel maintainers
> would prefer to have the quirks visible to the kernel rather than hidden in
> the firmware, and that they would be more open to merging these quirks. The
> Tegra patch you listed above has been merged.
> 
> More info about this: https://lkml.org/lkml/2021/3/25/777

Hi and thanks for pointer!

I did not know about that new discussion and a new solution.

Anyway, according to that discussion, adding a new MCFG quirk into
kernel requires adding some errata entry for documenting buggy HW. And
seems that this documentation update is not included in this patch
series...

> 
> Thanks,
> 
> > 
> > In past there was a long discussion about ECAM compliance, MCFG quirks
> > and usage of ACPI (on other platform), see long thread:
> > https://lore.kernel.org/linux-pci/20200207183427.GA40158 at google.com/
> > 
> > And I think it is not a good idea to extend MCFG quirks table as
> > according to discussion it was just temporary plaster and if platform is
> > not ACPI / ECAM compliant then it should use DT booting...
> > 
> > Lorenzo, could you put any comment on this?
> > 
> > > Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> > > ---
> > >   drivers/pci/controller/Makefile            |  1 +
> > >   drivers/pci/controller/pcie-brcmstb-acpi.c | 74 ++++++++++++++++++++++
> > >   include/linux/pci-ecam.h                   |  1 +
> > >   3 files changed, 76 insertions(+)
> > >   create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
> > > 
> > > diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
> > > index aaf30b3dcc14..65aa6fd3ed89 100644
> > > --- a/drivers/pci/controller/Makefile
> > > +++ b/drivers/pci/controller/Makefile
> > > @@ -57,5 +57,6 @@ ifdef CONFIG_PCI_QUIRKS
> > >   obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
> > >   obj-$(CONFIG_ARM64) += pci-thunder-pem.o
> > >   obj-$(CONFIG_ARM64) += pci-xgene.o
> > > +obj-$(CONFIG_ARM64) += pcie-brcmstb-acpi.o
> > >   endif
> > >   endif
> > > diff --git a/drivers/pci/controller/pcie-brcmstb-acpi.c b/drivers/pci/controller/pcie-brcmstb-acpi.c
> > > new file mode 100644
> > > index 000000000000..71f6def3074c
> > > --- /dev/null
> > > +++ b/drivers/pci/controller/pcie-brcmstb-acpi.c
> > > @@ -0,0 +1,74 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * ACPI quirks for Brcm2711 PCIe host controller
> > > + * As used on the Raspberry Pi Compute Module 4
> > > + *
> > > + * Copyright (C) 2021 Arm Ltd.
> > > + */
> > > +
> > > +#include <linux/io.h>
> > > +#include <linux/pci.h>
> > > +#include <linux/pci-ecam.h>
> > > +#include "../pci.h"
> > > +#include "pcie-brcmstb.h"
> > > +
> > > +static int brcm_acpi_init(struct pci_config_window *cfg)
> > > +{
> > > +	/*
> > > +	 * This platform doesn't technically have anything that could be called
> > > +	 * ECAM. Its config region has root port specific registers between
> > > +	 * standard PCIe defined config registers. Thus the region setup by the
> > > +	 * generic ECAM code needs to be adjusted. The HW can access bus 0-ff
> > > +	 * but the footprint isn't a nice power of 2 (40k). For purposes of
> > > +	 * mapping the config region we are just going to squash the standard
> > > +	 * and nonstandard registers together rather than mapping them separately.
> > > +	 */
> > > +	iounmap(cfg->win);
> > > +	cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
> > > +	if (!cfg->win)
> > > +		goto err_exit;
> > > +
> > > +	/* MSI is nonstandard as well */
> > > +	pci_no_msi();
> > > +
> > > +	return 0;
> > > +err_exit:
> > > +	dev_err(cfg->parent, "PCI: Failed to remap config\n");
> > > +	return -ENOMEM;
> > > +}
> > > +
> > > +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
> > > +					unsigned int devfn, int where)
> > > +{
> > > +	struct pci_config_window *cfg = bus->sysdata;
> > > +	void __iomem *base = cfg->win;
> > > +	int idx;
> > > +	u32 up;
> > > +
> > > +	/* Accesses to the RC go right to the RC registers if slot==0 */
> > > +	if (pci_is_root_bus(bus))
> > > +		return PCI_SLOT(devfn) ? NULL : base + where;
> > > +
> > > +	/* Assure link up before sending request */
> > > +	up = readl(base + PCIE_MISC_PCIE_STATUS);
> > > +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
> > > +		return NULL;
> > > +
> > > +	if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
> > > +		return NULL;
> > > +
> > > +	/* For devices, write to the config space index register */
> > > +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
> > > +	writel(idx, base + PCIE_EXT_CFG_INDEX);
> > > +	return base + PCIE_EXT_CFG_DATA + where;
> > > +}
> > > +
> > > +const struct pci_ecam_ops bcm2711_pcie_ops = {
> > > +	.init		= brcm_acpi_init,
> > > +	.bus_shift	= 1,
> > > +	.pci_ops	= {
> > > +		.map_bus	= brcm_pcie_map_conf2,
> > > +		.read		= pci_generic_config_read,
> > > +		.write		= pci_generic_config_write,
> > > +	}
> > > +};
> > > diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
> > > index adea5a4771cf..a5de0285bb7f 100644
> > > --- a/include/linux/pci-ecam.h
> > > +++ b/include/linux/pci-ecam.h
> > > @@ -87,6 +87,7 @@ extern const struct pci_ecam_ops xgene_v1_pcie_ecam_ops; /* APM X-Gene PCIe v1 *
> > >   extern const struct pci_ecam_ops xgene_v2_pcie_ecam_ops; /* APM X-Gene PCIe v2.x */
> > >   extern const struct pci_ecam_ops al_pcie_ops;	/* Amazon Annapurna Labs PCIe */
> > >   extern const struct pci_ecam_ops tegra194_pcie_ops; /* Tegra194 PCIe */
> > > +extern const struct pci_ecam_ops bcm2711_pcie_ops; /* Bcm2711 PCIe */
> > >   #endif
> > >   #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
> > > -- 
> > > 2.31.1
> > > 
> 


From valentin.schneider at arm.com  Mon Aug 30 09:54:26 2021
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Mon, 30 Aug 2021 17:54:26 +0100
Subject: [PATCH] irqchip/gic: Convert to handle_strict_flow_irq()
In-Reply-To: <87eeav19mc.wl-maz@kernel.org>
References: <20210814194737.GA3951530@roeck-us.net>
 <87sfzb7jeo.mognet@arm.com> <87eeav19mc.wl-maz@kernel.org>
Message-ID: <875yvmub3x.mognet@arm.com>

On 15/08/21 07:54, Marc Zyngier wrote:
> In order to restore -next into a working state, I'm temporarily
> dropping this series. Hopefully, we can sort this out before the merge
> window and reinstate it.
>

So what I thought would be a small weekend job turned to be a bit more
involved...

- The throughput improvement with v4 is half of what it was on v3. I
  rebased v3 on the last tip/irq/core and this also took a hit, I'm digging
  into it.
- TX1 is being an absolute PITA to work with, I can't seem to boot anything
  else than the distro kernel ATM (grub commits seppuku).
- Last but not least, I'll soon be AWOL for 3 weeks, a good chunk of it
  involving sitting atop a mountain without electricity. So even if I can
  magically fix all of the above say tomorrow, I'd rather be available to
  ~watch~ handle any unforeseen fireworks.

Hopefully I'll catch the next revision :)

> Thanks,
>
>       M.
>
> --
> Without deviation from the norm, progress is not possible.


From jic23 at kernel.org  Mon Aug 30 10:17:06 2021
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 30 Aug 2021 18:17:06 +0100
Subject: [PATCH v16 00/14] Introduce the Counter character device interface
In-Reply-To: <cover.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <20210830181706.74e45cb8@jic23-huawei>

On Fri, 27 Aug 2021 12:47:44 +0900
William Breathitt Gray <vilhelm.gray at gmail.com> wrote:

> Changes in v16:
>  - Define magic numbers for stm32-lptimer-cnt clock polarities
>  - Define magic numbers for stm32-timer-cnt encoder modes
>  - Bump KernelVersion to 5.16 in sysfs-bus-counter ABI documentation
>  - Fix typos in driver API generic-counter.rst documentation file
> 
> For convenience, this patchset is also available on my personal git
> repo: https://gitlab.com/vilhelmgray/iio/-/tree/counter_chrdev_v16
> 
> The patches preceding "counter: Internalize sysfs interface code" are
> primarily cleanup and fixes that can be picked up and applied now to the
> IIO tree if so desired. The "counter: Internalize sysfs interface code"
> patch as well may be considered for pickup because it is relatively safe
> and makes no changes to the userspace interface.
> 
> To summarize the main points of this patchset: there are no changes to
> the existing Counter sysfs userspace interface; a Counter character
> device interface is introduced that allows Counter events and associated
> data to be read() by userspace; the events_configure() and
> watch_validate() driver callbacks are introduced to support Counter
> events; and IRQ support is added to the 104-QUAD-8 driver, serving as an
> example of how to support the new Counter events functionality.

Hi William,

I'll aim to pick up the first part in a week (too tired today after a lot
of reviewing to even manage the basic sanity check on the changes).

For the rest...

What I'd really like to know is if anyone other than William and I is planning
to review them in depth? (particularly 7 and 8 which are the new interface
patch and docs)

So if anyone reading this is in that category please let me know.  We can wait,
but conversely if no one is going to get time / inclination to do it then I
don't want to hold these up any longer and maximum time in linux-next may
be more useful than sitting unloved on the mailing list.

Jonathan

> 
> William Breathitt Gray (14):
>   counter: stm32-lptimer-cnt: Provide defines for clock polarities
>   counter: stm32-timer-cnt: Provide defines for slave mode selection
>   counter: Internalize sysfs interface code
>   counter: Update counter.h comments to reflect sysfs internalization
>   docs: counter: Update to reflect sysfs internalization
>   counter: Move counter enums to uapi header
>   counter: Add character device interface
>   docs: counter: Document character device interface
>   tools/counter: Create Counter tools
>   counter: Implement signalZ_action_component_id sysfs attribute
>   counter: Implement *_component_id sysfs attributes
>   counter: Implement events_queue_size sysfs attribute
>   counter: 104-quad-8: Replace mutex with spinlock
>   counter: 104-quad-8: Add IRQ support for the ACCES 104-QUAD-8
> 
>  Documentation/ABI/testing/sysfs-bus-counter   |   38 +-
>  Documentation/driver-api/generic-counter.rst  |  358 +++-
>  .../userspace-api/ioctl/ioctl-number.rst      |    1 +
>  MAINTAINERS                                   |    3 +-
>  drivers/counter/104-quad-8.c                  |  699 ++++----
>  drivers/counter/Kconfig                       |    6 +-
>  drivers/counter/Makefile                      |    1 +
>  drivers/counter/counter-chrdev.c              |  553 ++++++
>  drivers/counter/counter-chrdev.h              |   14 +
>  drivers/counter/counter-core.c                |  191 +++
>  drivers/counter/counter-sysfs.c               |  960 +++++++++++
>  drivers/counter/counter-sysfs.h               |   13 +
>  drivers/counter/counter.c                     | 1496 -----------------
>  drivers/counter/ftm-quaddec.c                 |   60 +-
>  drivers/counter/intel-qep.c                   |  144 +-
>  drivers/counter/interrupt-cnt.c               |   62 +-
>  drivers/counter/microchip-tcb-capture.c       |   91 +-
>  drivers/counter/stm32-lptimer-cnt.c           |  212 ++-
>  drivers/counter/stm32-timer-cnt.c             |  195 +--
>  drivers/counter/ti-eqep.c                     |  180 +-
>  include/linux/counter.h                       |  715 ++++----
>  include/linux/counter_enum.h                  |   45 -
>  include/linux/mfd/stm32-lptimer.h             |    5 +
>  include/linux/mfd/stm32-timers.h              |    4 +
>  include/uapi/linux/counter.h                  |  154 ++
>  tools/Makefile                                |   13 +-
>  tools/counter/Build                           |    1 +
>  tools/counter/Makefile                        |   53 +
>  tools/counter/counter_example.c               |   93 +
>  29 files changed, 3569 insertions(+), 2791 deletions(-)
>  create mode 100644 drivers/counter/counter-chrdev.c
>  create mode 100644 drivers/counter/counter-chrdev.h
>  create mode 100644 drivers/counter/counter-core.c
>  create mode 100644 drivers/counter/counter-sysfs.c
>  create mode 100644 drivers/counter/counter-sysfs.h
>  delete mode 100644 drivers/counter/counter.c
>  delete mode 100644 include/linux/counter_enum.h
>  create mode 100644 include/uapi/linux/counter.h
>  create mode 100644 tools/counter/Build
>  create mode 100644 tools/counter/Makefile
>  create mode 100644 tools/counter/counter_example.c
> 
> 
> base-commit: 5ffeb17c0d3dd44704b4aee83e297ec07666e4d6



From houlong.wei at mediatek.com  Mon Aug 30 10:14:46 2021
From: houlong.wei at mediatek.com (houlong wei)
Date: Tue, 31 Aug 2021 01:14:46 +0800
Subject: [PATCH v7 7/7] media: mtk-mdp: use mdp-rdma0 alias to point to
 MDP master
In-Reply-To: <e9020b68-5d20-8e4f-4883-273fe4697d60@collabora.com>
References: <20210825063323.3607738-1-eizan@chromium.org>
 <20210825163247.v7.7.I2049e180dca12e0d1b3178bfc7292dcf9e05ac28@changeid>
 <1629880999.12893.17.camel@mhfsdcap03>
 <0c9fa482-57dd-d4ef-c65b-01f137c57359@collabora.com>
 <1629904697.15752.11.camel@mhfsdcap03>
 <e9020b68-5d20-8e4f-4883-273fe4697d60@collabora.com>
Message-ID: <1630343686.7403.44.camel@mhfsdcap03>

Hi Enric,

My answers are as follows.Thanks for deep thinking about mtk-mdp.

Regards,
Houlong

On Thu, 2021-08-26 at 00:54 +0800, Enric Balletbo i Serra wrote:
> Hi Houlong,
> 
> Thank you for your answer, some more questions below :-)
> 
> On 25/8/21 17:18, houlong wei wrote:
> > On Wed, 2021-08-25 at 17:07 +0800, Enric Balletbo i Serra wrote:
> >> Hi Houlong,
> >>
> >> Thank you for following up this patchset. I have some questions to try to
> >> understand better the hardware though.
> >>
> >> On 25/8/21 10:43, houlong wei wrote:
> >>> Hi Eizan,
> >>>
> >>> Thanks for you patch. I have inline comment below.
> >>>
> >>> Regards,
> >>> Houlong
> >>>
> >>> On Wed, 2021-08-25 at 14:33 +0800, Eizan Miyamoto wrote:
> >>>> ... Instead of depending on the presence of a mediatek,vpu property in
> >>>> the device node.
> >>>>
> >>>> That property was originally added to link to the vpu node so that the
> >>>> mtk_mdp_core driver could pass the right device to
> >>>> vpu_wdt_reg_handler(). However in a previous patch in this series,
> >>>> the driver has been modified to search the device tree for that node
> >>>> instead.
> >>>>
> >>>> That property was also used to indicate the primary MDP device, so that
> >>>> it can be passed to the V4L2 subsystem as well as register it to be
> >>>> used when setting up queues in the open() callback for the filesystem
> >>>> device node that is created. In this case, assuming that the primary
> >>>> MDP device is the one with a specific alias seems useable because the
> >>>> alternative is to add a property to the device tree which doesn't
> >>>> actually represent any facet of hardware (i.e., this being the primary
> >>>> MDP device is a software decision). In other words, this solution is
> >>>> equally as arbitrary, but at least it doesn't add a property to a
> >>>> device node where said property is unrelated to the hardware present.
> >>>>
> >>>> Signed-off-by: Eizan Miyamoto <eizan at chromium.org>
> >>>> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> >>>> ---
> >>>>
> >>>> (no changes since v1)
> >>>>
> >>>>  drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 56 +++++++++++++------
> >>>>  drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 36 ++++++++----
> >>>>  2 files changed, 64 insertions(+), 28 deletions(-)
> >>>>
> >>>> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> >>>> index 85ef274841a3..9527649de98e 100644
> >>>> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> >>>> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
> >>>> @@ -151,29 +151,50 @@ void mtk_mdp_comp_clock_off(struct mtk_mdp_comp *comp)
> >>>>  		mtk_smi_larb_put(comp->larb_dev);
> >>>>  }
> >>>>  
> >>>> -static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *data)
> >>>> +/*
> >>>> + * The MDP master device node is identified by the device tree alias
> >>>> + * "mdp-rdma0".
> >>>> + */
> >>>> +static bool is_mdp_master(struct device *dev)
> >>>> +{
> >>>> +	struct device_node *aliases, *mdp_rdma0_node;
> >>>> +	const char *mdp_rdma0_path;
> >>>> +
> >>>> +	if (!dev->of_node)
> >>>> +		return false;
> >>>> +
> >>>> +	aliases = of_find_node_by_path("/aliases");
> >>>> +	if (!aliases) {
> >>>> +		dev_err(dev, "no aliases found for mdp-rdma0");
> >>>> +		return false;
> >>>> +	}
> >>>> +
> >>>> +	mdp_rdma0_path = of_get_property(aliases, "mdp-rdma0", NULL);
> >>>> +	if (!mdp_rdma0_path) {
> >>>> +		dev_err(dev, "get mdp-rdma0 property of /aliases failed");
> >>>> +		return false;
> >>>> +	}
> >>>> +
> >>>> +	mdp_rdma0_node = of_find_node_by_path(mdp_rdma0_path);
> >>>> +	if (!mdp_rdma0_node) {
> >>>> +		dev_err(dev, "path resolution failed for %s", mdp_rdma0_path);
> >>>> +		return false;
> >>>> +	}
> >>>> +
> >>>> +	return dev->of_node == mdp_rdma0_node;
> >>>
> >>>
> >>> About how to determine the master mdp driver, we also can
> >>> judge the component type. The component type can be gotten by calling
> >>> of_device_get_match_data(dev). If the component is MTK_MDP_RDMA, it is
> >>> the master driver. No matter it is mdp_rdma0 or mdp_rdma1.
> >>
> >>
> >> I'm confused, you mean that the component type, aka MTK_MDP_RDMA is only set for
> >> mtk_mdp_rdma0? isn't mtk_dmp_rdma1 also a MTK_MDP_RDMA type? Because looks weird
> >> to me that two rdma have diffent types.
> >>
> > Hi Enric,
> > 
> > I can understand your doubts. For mtk-mdp dirver, it is really difficult
> > to understand the relationship among the components. Because the MDP
> > hardware path is configured and connected in the VPU firmware.
> 
> So is fixed by the VPU firmware and can't be changed via, i.e writing some
> registers? Can't be platform data then?
> 
> If that's the case, can you draw the mdp hardware path for i.e MT8173? (so I
> have a better understanding)
> 

I reviewed the mt8173 VPU firmware code and found it only use 1 MDP
path.Perhaps one MDP path could meet the project team's requirement when
the VPU firmware was implemented.
A MDP path is a data path which consists of several MDP hardware
engines, e.g. mdp_rdma1->mdp_rsz1->mdp_wrot1,
mdp_rdma2->mdp_rsz2->mdp_wrot2. Ideally,if there are multiple MDP paths,
the users(e.g. applications) can use them concurrently.

> 
> > For MT8173, the component type of mtk_mdp_rdma0 and mtk_mdp_rdma1 are
> > both MTK_MDP_RDMA. Even though the mtk-mdp driver's component list
> > contains both of them, only one corresponding hardware component takes
> > effect during the processing of a frame, the VPU decides it.
> > 
> 
> So IIUC the VPU firmware decides which rdma uses on every frame, right? From hw
> point of view, why one of them need to be master?
> 

For mt8173, the VPU firmware only use one rdma because another MDP path
is not implemented.If we implement multiple MDP paths in certain
project, each rdma can be master.


> > Regards,
> > Houlong
> >>
> >>> http://lists.infradead.org/pipermail/linux-mediatek/2021-August/028533.html
> >>>
> >>> IMO, judging it by component type is more flexible because it does not
> >>> limit to 'mdp_rdma0'.
> >>>
> >>
> >> Using an alias like Eizan did is also flexible, you only need to set mdp-rdma0
> >> to point the mdp_rdma1 node.
> >>
> >> What I am really interested to know is the differences between the platforms to
> >> understand if this is really a platform hardware property or a software
> >> configurable thing, so would help if you can give use the different use cases
> >> for different SoCs.
> >>
> >> For MT8173 which is the master device? is _always_ rdma0 or can also be rdma1?
> >>
> >> Or maybe what is not clear here is what exactly means be a master device?
> >>
> >> What about MT8183 and other SoCs?
> >>
> >> Thanks,
> >>   Enric
> >>
> > Hi Enric,
> > 
> > Before answer your questions, let's unify the concept of the master
> > device.If an MDP device-tree node can not only generate a /dev/video
> > device node, but also can generate a mtk component device node, then
> > this component device is the master device.
> 
> Sorry, what you mean with a mtk component device node?

My meaning is that the device-tree node can generate a platform device,
it is what the mtk_mdp_comp.c does.

> 
> > From the perspective of the device tree node, the compatible of a MDP
> > device tree node contains both "mediatek,mt8173-mdp-rdma" and
> > "mediatek,mt8173-mdp", then its corresponding mtk component device is
> > the master device.
> 
> So that's what's wrong, and Eizan patches get rid of this. In this case you
> can't use device-tree to specify such master device. Device-tree is only about
> hardware description, can't be used, in this case, as entry point to instantiate
> the mdp driver. Hence Eizan patches change this, and mdp is instantiated by the
> mmsys driver. Similar to what we do for the drm driver.
> 
> For the two hw rdma blocks the compatible should be just
> "mediatek,mt8173-mdp-rdma" in this case.
> 
> Thanks,
>   Enric

My consideration is how the driver supports it when there are multiple
MDP paths. Assume there are 2 MDP paths, as a V4L2 driver, mtk-mdp can
generates two device nodes, e.g. /dev/video0 supports one of MDP
path, /dev/video1 supports another MDP path.

> > Since this concept comes from Eizan's patches, if my understanding is
> > different from yours, please let me know, thanks.
> > 
> > If there is only one master device, I fully agree with you. For MT8173,
> > both mdp_rdma0 and mdp_rdma1 can be master device at the same time.
> > But now only mdp_rdma0 takes this role, perhaps because one MDP hardware
> > path could meet the project's the requirement six years ago.
> > In some project, we have two or more MDP hardware paths, we can
> > configure all the mdp_rdma components as master devices, and there will
> > be several /dev/video device nodes. The user can control them
> > concurrently.
> > 
> > Regards,
> > Houlong
> > 
> >>
> >>>> +}
> >>>> +
> >>>> +static int mtk_mdp_comp_bind(struct device *dev, struct device *master,
> >>>> +			void *data)
> >>>>  {
> >>>>  	struct mtk_mdp_comp *comp = dev_get_drvdata(dev);
> >>>>  	struct mtk_mdp_dev *mdp = data;
> >>>> -	struct device_node *vpu_node;
> >>>>  
> >>>>  	mtk_mdp_register_component(mdp, comp);
> >>>>  
> >>>> -	/*
> >>>> -	 * If this component has a "mediatek-vpu" property, it is responsible for
> >>>> -	 * notifying the mdp master driver about it so it can be further initialized
> >>>> -	 * later.
> >>>> -	 */
> >>>> -	vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
> >>>> -	if (vpu_node) {
> >>>> +	if (is_mdp_master(dev)) {
> >>>>  		int ret;
> >>>>  
> >>>> -		mdp->vpu_dev = of_find_device_by_node(vpu_node);
> >>>> -		if (WARN_ON(!mdp->vpu_dev)) {
> >>>> -			dev_err(dev, "vpu pdev failed\n");
> >>>> -			of_node_put(vpu_node);
> >>>> -		}
> >>>> -
> >>>>  		ret = v4l2_device_register(dev, &mdp->v4l2_dev);
> >>>>  		if (ret) {
> >>>>  			dev_err(dev, "Failed to register v4l2 device\n");
> >>>> @@ -187,9 +208,8 @@ static int mtk_mdp_comp_bind(struct device *dev, struct device *master, void *da
> >>>>  		}
> >>>>  
> >>>>  		/*
> >>>> -		 * presence of the "mediatek,vpu" property in a device node
> >>>> -		 * indicates that it is the primary MDP rdma device and MDP DMA
> >>>> -		 * ops should be handled by its DMA callbacks.
> >>>> +		 * MDP DMA ops will be handled by the DMA callbacks associated with this
> >>>> +		 * device;
> >>>>  		 */
> >>>>  		mdp->rdma_dev = dev;
> >>>>  	}
> >>>> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> >>>> index 50eafcc9993d..6a775463399c 100644
> >>>> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> >>>> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
> >>>> @@ -150,8 +150,9 @@ static void release_of(struct device *dev, void *data)
> >>>>  
> >>>>  static int mtk_mdp_master_bind(struct device *dev)
> >>>>  {
> >>>> -	int status;
> >>>>  	struct mtk_mdp_dev *mdp = dev_get_drvdata(dev);
> >>>> +	struct device_node *vpu_node;
> >>>> +	int status;
> >>>>  
> >>>>  	status = component_bind_all(dev, mdp);
> >>>>  	if (status) {
> >>>> @@ -159,15 +160,30 @@ static int mtk_mdp_master_bind(struct device *dev)
> >>>>  		goto err_component_bind_all;
> >>>>  	}
> >>>>  
> >>>> -	if (mdp->vpu_dev) {
> >>>> -		int ret = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp,
> >>>> -					  VPU_RST_MDP);
> >>>> -		if (ret) {
> >>>> -			dev_err(dev, "Failed to register reset handler\n");
> >>>> -			goto err_wdt_reg;
> >>>> -		}
> >>>> -	} else {
> >>>> -		dev_err(dev, "no vpu_dev found\n");
> >>>> +	if (mdp->rdma_dev == NULL) {
> >>>> +		dev_err(dev, "Primary MDP device not found");
> >>>> +		status = -ENODEV;
> >>>> +		goto err_component_bind_all;
> >>>> +	}
> >>>> +
> >>>> +	vpu_node = of_find_node_by_name(NULL, "vpu");
> >>>> +	if (!vpu_node) {
> >>>> +		dev_err(dev, "unable to find vpu node");
> >>>> +		status = -ENODEV;
> >>>> +		goto err_wdt_reg;
> >>>> +	}
> >>>> +
> >>>> +	mdp->vpu_dev = of_find_device_by_node(vpu_node);
> >>>
> >>> The 'vpu_node' should be put by calling 'of_node_put(vpu_node)' when it
> >>> is not used.
> >>>
> >>>> +	if (!mdp->vpu_dev) {
> >>>> +		dev_err(dev, "unable to find vpu device");
> >>>> +		status = -ENODEV;
> >>>> +		goto err_wdt_reg;
> >>>> +	}
> >>>> +
> >>>> +	status = vpu_wdt_reg_handler(mdp->vpu_dev, mtk_mdp_reset_handler, mdp, VPU_RST_MDP);
> >>>> +	if (status) {
> >>>> +		dev_err(dev, "Failed to register reset handler\n");
> >>>> +		goto err_wdt_reg;
> >>>>  	}
> >>>>  
> >>>>  	status = mtk_mdp_register_m2m_device(mdp);
> >>>
> > 


From nsaenz at kernel.org  Mon Aug 30 10:17:32 2021
From: nsaenz at kernel.org (nicolas saenz julienne)
Date: Mon, 30 Aug 2021 19:17:32 +0200
Subject: [PATCH v3 2/4] PCI: brcmstb: Add ACPI config space quirk
In-Reply-To: <f6860e38-c6fa-292d-f1a1-22b3e4b48f32@gmail.com>
References: <20210826071557.29239-1-jeremy.linton@arm.com>
 <20210826071557.29239-3-jeremy.linton@arm.com>
 <44ad79081412af289c68e74cdecb6a2baa2e873c.camel@kernel.org>
 <5c39cf29-a08f-48d1-b873-ce0fda763d66@arm.com>
 <f6860e38-c6fa-292d-f1a1-22b3e4b48f32@gmail.com>
Message-ID: <f683df669b9e4e844f801182dc405fc83a4d9099.camel@kernel.org>

On Mon, 2021-08-30 at 09:27 -0700, Florian Fainelli wrote:
> 
> On 8/30/2021 9:23 AM, Jeremy Linton wrote:
> > Hi,
> > 
> > On 8/30/21 3:36 AM, nicolas saenz julienne wrote:
> > > Hi Jeremy,
> > > sorry for the late reply, I've been on vacation.
> > > 
> > > On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
> > > 
> > > [...]
> > > 
> > > > +static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
> > > > +??????????????????? unsigned int devfn, int where)
> > > > +{
> > > > +??? struct pci_config_window *cfg = bus->sysdata;
> > > > +??? void __iomem *base = cfg->win;
> > > > +??? int idx;
> > > > +??? u32 up;
> > > > +
> > > > +??? /* Accesses to the RC go right to the RC registers if slot==0 */
> > > > +??? if (pci_is_root_bus(bus))
> > > > +??????? return PCI_SLOT(devfn) ? NULL : base + where;
> > > > +
> > > > +??? /*
> > > > +???? * Assure the link is up before sending requests downstream. 
> > > > This is done
> > > > +???? * to avoid sending transactions to EPs that don't exist. Link flap
> > > > +???? * conditions/etc make this race more probable. The resulting 
> > > > unrecoverable
> > > > +???? * SERRORs will result in the machine crashing.
> > > > +???? */
> > > > +??? up = readl(base + PCIE_MISC_PCIE_STATUS);
> > > > +??? if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
> > > > +??????? return NULL;
> > > > +
> > > > +??? if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
> > > > +??????? return NULL;
> > > 
> > > Couldn't this be integrated in the original brcm_pcie_map_conf()? IIUC 
> > > there is
> > > nothing ACPI specific about it. It'd also make for less code duplication.
> > 
> > That is where I started with this, but it wasn't the linkup check/etc 
> > which caused me to hoist it but the fact that if ACPI quirks are enabled 
> > they end up statically built into the kernel. While if this host bridge 
> > is enabled, it can end up being a module, and the resulting mess I 
> > created trying to satisfy the CONFIG variations. I'm not much of a fan 
> > of copy/paste programming, but that IMHO ended up being the cleanest here.
> > 
> 
> Agreed, the open coding that is being done is reasonable IHMO, although 
> we may have to update the link up code in both pcie-brcmstb.c and this 
> file in the future if offsets/bits do change, nothing impossible though.

Fair enough.

Acked-by: Nicolas Saenz Julienne <nsaenz at kernel.org>

Regards,
Nicolas



From caihuoqing at baidu.com  Mon Aug 30 10:21:34 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 01:21:34 +0800
Subject: [PATCH 0/6]  Add driver support for NXP IMX8QXP ADC
Message-ID: <20210830172140.414-1-caihuoqing@baidu.com>

The NXP i.MX 8QuadXPlus SOC has a new ADC IP. These patches add
driver support for this ADC.

Cai Huoqing (6):
  iio: adc: Init the driver for NXP i.MX8QuadXPlus
  iio: adc: Add configuration for NXP i.MX8QuadXPlus ADC driver
  iio: imx8qxp-adc: Add the detail for NXP i.MX8QuadXPlus ADC driver
  dt-bindings: iio: adc: Add the binding documentation for NXP IMX8QXP
    ADC
  MAINTAINERS: Add the driver info of the NXP IMX8QXP ADC
  iio: imx8qxp-adc: Add the copyright for NXP i.MX8QuadXPlus ADC driver

 .../bindings/iio/adc/nxp,imx8qxp-adc.yaml     |  85 +++
 MAINTAINERS                                   |   7 +
 drivers/iio/adc/Kconfig                       |  10 +
 drivers/iio/adc/Makefile                      |   1 +
 drivers/iio/adc/imx8qxp-adc.c                 | 588 ++++++++++++++++++
 5 files changed, 691 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
 create mode 100644 drivers/iio/adc/imx8qxp-adc.c

-- 
2.25.1



From caihuoqing at baidu.com  Mon Aug 30 10:21:37 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 01:21:37 +0800
Subject: [PATCH 3/6] iio: imx8qxp-adc: Add the detail for NXP i.MX8QuadXPlus
 ADC driver
In-Reply-To: <20210830172140.414-1-caihuoqing@baidu.com>
References: <20210830172140.414-1-caihuoqing@baidu.com>
Message-ID: <20210830172140.414-4-caihuoqing@baidu.com>

The NXP i.MX 8QuadXPlus SOC has a new ADC IP, so add the detail for NXP
i.MX8QuadXPlus ADC driver which includes: probe/remove/pm_ops/iio_dev.

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/iio/adc/imx8qxp-adc.c | 513 ++++++++++++++++++++++++++++++++++
 1 file changed, 513 insertions(+)

diff --git a/drivers/iio/adc/imx8qxp-adc.c b/drivers/iio/adc/imx8qxp-adc.c
index aec1b45c8fb9..d39bf382c582 100644
--- a/drivers/iio/adc/imx8qxp-adc.c
+++ b/drivers/iio/adc/imx8qxp-adc.c
@@ -20,23 +20,536 @@
 
 #define ADC_DRIVER_NAME		"imx8qxp-adc"
 
+/* Register map definition */
+#define ADC_CTRL		0x10
+#define ADC_STAT		0x14
+#define ADC_IE			0x18
+#define ADC_DE			0x1c
+#define ADC_CFG			0x20
+#define ADC_FCTRL		0x30
+#define ADC_SWTRIG		0x34
+#define ADC_TCTRL(tid)		(0xc0 + tid * 4)
+#define ADC_CMDH(cid)		(0x100 + cid * 8)
+#define ADC_CMDL(cid)		(0x104 + cid * 8)
+#define ADC_RESFIFO		0x300
+#define ADC_TST			0xffc
+
+/* ADC bit shift */
+#define ADC_IE_FWMIE_SHIFT		(0)
+#define ADC_CTRL_FIFO_RESET_SHIFT	(8)
+#define ADC_CTRL_SOFTWARE_RESET_SHIFT	(1)
+#define ADC_CTRL_ADC_ENABLE		(0)
+#define ADC_TCTRL_TCMD_SHIFT		(24)
+#define ADC_TCTRL_TDLY_SHIFT		(16)
+#define ADC_TCTRL_TPRI_SHIFT		(8)
+#define ADC_TCTRL_HTEN_SHIFT		(0)
+#define ADC_CMDL_CSCALE_SHIFT		(8)
+#define ADC_CMDL_MODE_SHIFT		(7)
+#define ADC_CMDL_DIFF_SHIFT		(6)
+#define ADC_CMDL_ABSEL_SHIFT		(5)
+#define ADC_CMDL_ADCH_SHIFT		(0)
+#define ADC_CMDH_NEXT_SHIFT		(24)
+#define ADC_CMDH_LOOP_SHIFT		(16)
+#define ADC_CMDH_AVGS_SHIFT		(12)
+#define ADC_CMDH_STS_SHIFT		(8)
+#define ADC_CMDH_LWI_SHIFT		(7)
+#define ADC_CMDH_CMPEN_SHIFT		(0)
+#define ADC_CFG_PWREN_SHIFT		(28)
+#define ADC_CFG_PUDLY_SHIFT		(16)
+#define ADC_CFG_REFSEL_SHIFT		(6)
+#define ADC_CFG_PWRSEL_SHIFT		(4)
+#define ADC_CFG_TPRICTRL_SHIFT		(0)
+#define ADC_FCTRL_FWMARK_SHIFT		(16)
+#define ADC_FCTRL_FWMARK_MASK		(0x1f << 16)
+#define ADC_FCTRL_FCOUNT_MASK		(0x1f)
+
+/* ADC PARAMETER*/
+#define ADC_CMDL_CHANNEL_SCALE_FULL		(0x3f)
+#define ADC_CMDL_SEL_A_A_B_CHANNEL		(0)
+#define ADC_CMDL_STANDARD_RESOLUTION		(0)
+#define ADC_CMDL_MODE_SINGLE			(0)
+#define ADC_CMDH_LWI_INCREMENT_DISABLE		(0)
+#define ADC_CMDH_CMPEN_DISABLE			(0)
+#define ADC_PAUSE_ENABLE			(0x80000000)
+#define ADC_TCTRL_TPRI_PRIORITY_HIGH		(0)
+
+#define ADC_TCTRL_HTEN_HARDWARE_TIRGGER_DISABLE	(0)
+
+#define MAX_CMD (8)
+#define MAX_TRIG (8)
+
+#define ADC_TIMEOUT		msecs_to_jiffies(100)
+
+struct imx8qxp_adc_trigger_ctrl {
+	u32 tcmd;
+	u32 tdly;
+	u32 tpri;
+	u32 hten;
+};
+
+struct imx8qxp_adc_cmd_l {
+	u32 scale;
+	u32 mode;
+	u32 diff;
+	u32 absel;
+	u32 adch;
+};
+
+struct imx8qxp_adc_cmd_h {
+	u32 next;
+	u32 loop;
+	u32 avgs;
+	u32 sts;
+	u32 lwi;
+	u32 cmpen;
+};
+
+struct imx8qxp_adc_cfg {
+	u32 pwren;
+	u32 pudly;
+	u32 refsel;
+	u32 pwrsel;
+	u32 tprictrl;
+};
+
+struct imx8qxp_adc {
+	struct device *dev;
+	void __iomem *regs;
+	struct clk *clk;
+	struct clk *ipg_clk;
+
+	u32 vref_uv;
+	u32 value;
+	u32 channel_id;
+	u32 trigger_id;
+	u32 cmd_id;
+
+	struct regulator *vref;
+	struct imx8qxp_adc_cmd_l adc_cmd_l[MAX_CMD + 1];
+	struct imx8qxp_adc_cmd_h adc_cmd_h[MAX_CMD + 1];
+	struct imx8qxp_adc_trigger_ctrl adc_trigger_ctrl[MAX_TRIG + 1];
+	struct imx8qxp_adc_cfg adc_cfg;
+	struct completion completion;
+};
+
+#define IMX8QXP_ADC_CHAN(_idx) {				\
+	.type = IIO_VOLTAGE,					\
+	.indexed = 1,						\
+	.channel = (_idx),					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
+				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+}
+
+static const struct iio_chan_spec imx8qxp_adc_iio_channels[] = {
+	IMX8QXP_ADC_CHAN(0),
+	IMX8QXP_ADC_CHAN(1),
+	IMX8QXP_ADC_CHAN(2),
+	IMX8QXP_ADC_CHAN(3),
+	IMX8QXP_ADC_CHAN(4),
+	IMX8QXP_ADC_CHAN(5),
+	IMX8QXP_ADC_CHAN(6),
+	IMX8QXP_ADC_CHAN(7),
+};
+
+static void imx8qxp_adc_feature_prepare(struct imx8qxp_adc *adc)
+{
+	u32 i;
+
+	adc->trigger_id = 0;
+	adc->cmd_id = 0;
+	adc->channel_id = 0;
+
+	for (i = 0; i < MAX_CMD + 1; i++) {
+		adc->adc_cmd_l[i].scale = 1;
+		adc->adc_cmd_l[i].mode = 0;
+		adc->adc_cmd_l[i].diff = 0;
+		adc->adc_cmd_l[i].absel = 0;
+		adc->adc_cmd_l[i].adch = 0;
+		adc->adc_cmd_h[i].next = 0;
+		adc->adc_cmd_h[i].loop = 0;
+		adc->adc_cmd_h[i].avgs = 0;
+		adc->adc_cmd_h[i].sts = 0;
+		adc->adc_cmd_h[i].lwi = 0;
+		adc->adc_cmd_h[i].cmpen = 0;
+	}
+
+	for (i = 0; i < MAX_TRIG; i++) {
+		adc->adc_trigger_ctrl[i].tcmd = 0;
+		adc->adc_trigger_ctrl[i].tdly = 0;
+		adc->adc_trigger_ctrl[i].tpri = 0;
+		adc->adc_trigger_ctrl[i].hten = 0;
+	}
+
+	adc->adc_cfg.pwren = 0;
+	adc->adc_cfg.pudly = 0;
+	adc->adc_cfg.refsel = 0;
+	adc->adc_cfg.pwrsel = 0;
+	adc->adc_cfg.tprictrl = 0;
+}
+
+static void imx8qxp_adc_reset(struct imx8qxp_adc *adc)
+{
+	u32 ctrl;
+
+	/*software reset, need to clear the set bit*/
+	ctrl = readl(adc->regs + ADC_CTRL);
+	ctrl |= 1 << ADC_CTRL_SOFTWARE_RESET_SHIFT;
+	writel(ctrl, adc->regs + ADC_CTRL);
+	udelay(10);
+	ctrl &= ~(1 << ADC_CTRL_SOFTWARE_RESET_SHIFT);
+	writel(ctrl, adc->regs + ADC_CTRL);
+
+	/* reset the fifo */
+	ctrl |= 1 << ADC_CTRL_FIFO_RESET_SHIFT;
+	writel(ctrl, adc->regs + ADC_CTRL);
+}
+
+static void imx8qxp_adc_reg_config(struct imx8qxp_adc *adc)
+{
+	u32 adc_cfg, adc_tctrl, adc_cmdl, adc_cmdh;
+	u32 t_id, c_id;
+
+	adc_cfg = adc->adc_cfg.pwren << ADC_CFG_PWREN_SHIFT |
+		  adc->adc_cfg.pudly << ADC_CFG_PUDLY_SHIFT |
+		  adc->adc_cfg.refsel << ADC_CFG_REFSEL_SHIFT |
+		  adc->adc_cfg.pwrsel << ADC_CFG_PWRSEL_SHIFT |
+		  adc->adc_cfg.tprictrl << ADC_CFG_TPRICTRL_SHIFT;
+	writel(adc_cfg, adc->regs + ADC_CFG);
+
+	t_id = adc->trigger_id;
+	adc_tctrl = adc->adc_trigger_ctrl[t_id].tcmd << ADC_TCTRL_TCMD_SHIFT |
+		    adc->adc_trigger_ctrl[t_id].tdly << ADC_TCTRL_TDLY_SHIFT |
+		    adc->adc_trigger_ctrl[t_id].tpri << ADC_TCTRL_TPRI_SHIFT |
+		    adc->adc_trigger_ctrl[t_id].hten << ADC_TCTRL_HTEN_SHIFT;
+	writel(adc_tctrl, adc->regs + ADC_TCTRL(t_id));
+
+	c_id = adc->cmd_id - 1;
+	adc_cmdl = adc->adc_cmd_l[c_id].scale << ADC_CMDL_CSCALE_SHIFT |
+		   adc->adc_cmd_l[c_id].mode << ADC_CMDL_MODE_SHIFT |
+		   adc->adc_cmd_l[c_id].diff << ADC_CMDL_DIFF_SHIFT |
+		   adc->adc_cmd_l[c_id].absel << ADC_CMDL_ABSEL_SHIFT |
+		   adc->adc_cmd_l[c_id].adch << ADC_CMDL_ADCH_SHIFT;
+	writel(adc_cmdl, adc->regs + ADC_CMDL(c_id));
+
+	adc_cmdh = adc->adc_cmd_h[c_id].next << ADC_CMDH_NEXT_SHIFT |
+		   adc->adc_cmd_h[c_id].loop << ADC_CMDH_LOOP_SHIFT |
+		   adc->adc_cmd_h[c_id].avgs << ADC_CMDH_AVGS_SHIFT |
+		   adc->adc_cmd_h[c_id].sts << ADC_CMDH_STS_SHIFT |
+		   adc->adc_cmd_h[c_id].lwi << ADC_CMDH_LWI_SHIFT |
+		   adc->adc_cmd_h[c_id].cmpen << ADC_CMDH_CMPEN_SHIFT;
+	writel(adc_cmdh, adc->regs + ADC_CMDH(c_id));
+}
+
+static void imx8qxp_adc_mode_config(struct imx8qxp_adc *adc)
+{
+	u32 cmd_id, trigger_id, channel_id;
+
+	channel_id = adc->channel_id;
+	cmd_id = adc->cmd_id - 1;
+	trigger_id = adc->trigger_id;
+
+	/* config the cmd */
+	adc->adc_cmd_l[cmd_id].scale = ADC_CMDL_CHANNEL_SCALE_FULL;
+	adc->adc_cmd_l[cmd_id].mode = ADC_CMDL_STANDARD_RESOLUTION;
+	adc->adc_cmd_l[cmd_id].diff = ADC_CMDL_MODE_SINGLE;
+	adc->adc_cmd_l[cmd_id].absel = ADC_CMDL_SEL_A_A_B_CHANNEL;
+	adc->adc_cmd_l[cmd_id].adch = channel_id;
+
+	adc->adc_cmd_h[cmd_id].next = 0;
+	adc->adc_cmd_h[cmd_id].loop = 0;
+	adc->adc_cmd_h[cmd_id].avgs = 7;
+	adc->adc_cmd_h[cmd_id].sts = 0;
+	adc->adc_cmd_h[cmd_id].lwi = ADC_CMDH_LWI_INCREMENT_DISABLE;
+	adc->adc_cmd_h[cmd_id].cmpen = ADC_CMDH_CMPEN_DISABLE;
+
+	/* config the trigger control */
+	adc->adc_trigger_ctrl[trigger_id].tcmd = adc->cmd_id;
+	adc->adc_trigger_ctrl[trigger_id].tdly = 0;
+	adc->adc_trigger_ctrl[trigger_id].tpri = ADC_TCTRL_TPRI_PRIORITY_HIGH;
+	adc->adc_trigger_ctrl[trigger_id].hten = ADC_TCTRL_HTEN_HARDWARE_TIRGGER_DISABLE;
+
+	/* ADC configuration */
+	adc->adc_cfg.pwren = 1;
+	adc->adc_cfg.pudly = 0x80;
+	adc->adc_cfg.refsel = 0;
+	adc->adc_cfg.pwrsel = 3;
+	adc->adc_cfg.tprictrl = 0;
+
+	imx8qxp_adc_reg_config(adc);
+}
+
+static void imx8qxp_adc_fifo_config(struct imx8qxp_adc *adc)
+{
+	u32 fifo_ctrl, interrupt_en;
+
+	fifo_ctrl = readl(adc->regs + ADC_FCTRL);
+	fifo_ctrl &= ~ADC_FCTRL_FWMARK_MASK;
+	/* set the watermark level to 1 */
+	fifo_ctrl |= 0 << ADC_FCTRL_FWMARK_SHIFT;
+	writel(fifo_ctrl, adc->regs + ADC_FCTRL);
+
+	/* FIFO Watermark Interrupt Enable */
+	interrupt_en = readl(adc->regs + ADC_IE);
+	interrupt_en |= 1 << ADC_IE_FWMIE_SHIFT;
+	writel(interrupt_en, adc->regs + ADC_IE);
+}
+
+static void imx8qxp_adc_disable(struct imx8qxp_adc *adc)
+{
+	u32 ctrl;
+
+	ctrl = readl(adc->regs + ADC_CTRL) & ~(1 << ADC_CTRL_ADC_ENABLE);
+	writel(ctrl, adc->regs + ADC_CTRL);
+}
+
+static int imx8qxp_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
+				int *val, int *val2, long mask)
+{
+	struct imx8qxp_adc *adc = iio_priv(indio_dev);
+	struct device *dev = adc->dev;
+
+	u32 channel;
+	u32 ctrl;
+	long ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		pm_runtime_get_sync(dev);
+
+		mutex_lock(&indio_dev->mlock);
+		reinit_completion(&adc->completion);
+
+		channel = chan->channel & 0x07;
+		adc->channel_id = channel;
+		adc->cmd_id = 1;
+		adc->trigger_id = 0;
+		imx8qxp_adc_mode_config(adc);
+
+		imx8qxp_adc_fifo_config(adc);
+
+		/* adc enable */
+		ctrl = readl(adc->regs + ADC_CTRL) | (1 << ADC_CTRL_ADC_ENABLE);
+		writel(ctrl, adc->regs + ADC_CTRL);
+		/* adc start */
+		writel(1 << adc->trigger_id, adc->regs + ADC_SWTRIG);
+
+		ret = wait_for_completion_interruptible_timeout
+				(&adc->completion, ADC_TIMEOUT);
+
+		pm_runtime_mark_last_busy(dev);
+		pm_runtime_put_sync_autosuspend(dev);
+
+		if (ret == 0) {
+			mutex_unlock(&indio_dev->mlock);
+			return -ETIMEDOUT;
+		}
+		if (ret < 0) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+
+		*val = adc->value;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		adc->vref_uv = regulator_get_voltage(adc->vref);
+		*val = adc->vref_uv / 1000;
+		*val2 = 12;
+		return IIO_VAL_FRACTIONAL_LOG2;
+
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = clk_get_rate(adc->clk) / 3;
+		return IIO_VAL_INT;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static irqreturn_t imx8qxp_adc_isr(int irq, void *dev_id)
+{
+	struct imx8qxp_adc *adc = (struct imx8qxp_adc *)dev_id;
+
+	u32 fifo_count;
+
+	fifo_count = readl(adc->regs + ADC_FCTRL)
+			& ADC_FCTRL_FCOUNT_MASK;
+
+	if (fifo_count) {
+		adc->value = (readl(adc->regs + ADC_RESFIFO) & 0xffff) >> 3;
+		complete(&adc->completion);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int imx8qxp_adc_reg_access(struct iio_dev *indio_dev, unsigned int reg,
+				  unsigned int writeval, unsigned int *readval)
+{
+	struct imx8qxp_adc *adc = iio_priv(indio_dev);
+	struct device *dev = adc->dev;
+
+	if (!readval || reg % 4 || reg > ADC_TST)
+		return -EINVAL;
+
+	pm_runtime_get_sync(dev);
+
+	*readval = readl(adc->regs + reg);
+
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_sync_autosuspend(dev);
+
+	return 0;
+}
+
+static const struct iio_info imx8qxp_adc_iio_info = {
+	.read_raw = &imx8qxp_adc_read_raw,
+	.debugfs_reg_access = &imx8qxp_adc_reg_access,
+};
+
 static int imx8qxp_adc_probe(struct platform_device *pdev)
 {
+	struct imx8qxp_adc *adc;
+	struct iio_dev *indio_dev;
+	struct device *dev = &pdev->dev;
+	int irq;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
+	if (!indio_dev) {
+		dev_err(dev, "Failed allocating iio device\n");
+		return -ENOMEM;
+	}
+
+	adc = iio_priv(indio_dev);
+	adc->dev = dev;
+
+	adc->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(adc->regs))
+		return PTR_ERR(adc->regs);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	adc->clk = devm_clk_get(dev, "per");
+	if (IS_ERR(adc->clk)) {
+		ret = PTR_ERR(adc->clk);
+		dev_err(dev, "Failed getting clock, err = %d\n", ret);
+		return ret;
+	}
+
+	adc->ipg_clk = devm_clk_get(dev, "ipg");
+	if (IS_ERR(adc->ipg_clk)) {
+		ret = PTR_ERR(adc->ipg_clk);
+		dev_err(dev, "Failed getting clock, err = %d\n", ret);
+		return ret;
+	}
+
+	adc->vref = devm_regulator_get(dev, "vref");
+	if (IS_ERR(adc->vref)) {
+		ret = PTR_ERR(adc->vref);
+		dev_err(dev,
+			"Failed getting reference voltage, err = %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	init_completion(&adc->completion);
+
+	indio_dev->name = dev_name(dev);
+	indio_dev->info = &imx8qxp_adc_iio_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = imx8qxp_adc_iio_channels;
+	indio_dev->num_channels = ARRAY_SIZE(imx8qxp_adc_iio_channels);
+
+	ret = devm_request_irq(dev, irq, imx8qxp_adc_isr, 0, dev_name(dev), adc);
+	if (ret < 0) {
+		dev_err(dev, "Failed requesting irq, irq = %d\n", irq);
+		return ret;
+	}
+
+	imx8qxp_adc_feature_prepare(adc);
+	imx8qxp_adc_reset(adc);
+
+	ret = iio_device_register(indio_dev);
+	if (ret) {
+		imx8qxp_adc_disable(adc);
+		dev_err(dev, "Couldn't register the device.\n");
+		return ret;
+	}
+
+	pm_runtime_set_active(dev);
+	pm_runtime_set_autosuspend_delay(dev, 50);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_enable(dev);
+
 	return 0;
 }
 
 static int imx8qxp_adc_remove(struct platform_device *pdev)
 {
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct imx8qxp_adc *adc = iio_priv(indio_dev);
+	struct device *dev = adc->dev;
+
+	pm_runtime_get_sync(dev);
+
+	iio_device_unregister(indio_dev);
+
+	imx8qxp_adc_disable(adc);
+
+	pm_runtime_disable(dev);
+	pm_runtime_put_noidle(dev);
+
 	return 0;
 }
 
 static int imx8qxp_adc_runtime_suspend(struct device *dev)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct imx8qxp_adc *adc = iio_priv(indio_dev);
+
+	imx8qxp_adc_disable(adc);
+
+	clk_disable_unprepare(adc->clk);
+	clk_disable_unprepare(adc->ipg_clk);
+	regulator_disable(adc->vref);
+
 	return 0;
 }
 
 static int imx8qxp_adc_runtime_resume(struct device *dev)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct imx8qxp_adc *adc = iio_priv(indio_dev);
+	int ret;
+
+	ret = regulator_enable(adc->vref);
+	if (ret) {
+		dev_err(dev, "Can't enable adc reference top voltage, err = %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(adc->clk);
+	if (ret) {
+		dev_err(dev, "Could not prepare or enable clock.\n");
+		regulator_disable(adc->vref);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(adc->ipg_clk);
+	if (ret) {
+		dev_err(dev, "Could not prepare or enable clock.\n");
+		clk_disable_unprepare(adc->clk);
+		regulator_disable(adc->vref);
+		return ret;
+	}
+	imx8qxp_adc_reset(adc);
+
 	return 0;
 }
 
-- 
2.25.1



From caihuoqing at baidu.com  Mon Aug 30 10:21:40 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 01:21:40 +0800
Subject: [PATCH 6/6] iio: imx8qxp-adc: Add the copyright for NXP
 i.MX8QuadXPlus ADC driver
In-Reply-To: <20210830172140.414-1-caihuoqing@baidu.com>
References: <20210830172140.414-1-caihuoqing@baidu.com>
Message-ID: <20210830172140.414-7-caihuoqing@baidu.com>

Add the copyright for NXP i.MX8QuadXPlus ADC driver.

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/iio/adc/imx8qxp-adc.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/iio/adc/imx8qxp-adc.c b/drivers/iio/adc/imx8qxp-adc.c
index d39bf382c582..dbb6761f1768 100644
--- a/drivers/iio/adc/imx8qxp-adc.c
+++ b/drivers/iio/adc/imx8qxp-adc.c
@@ -1,6 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * NXP i.MX8QXP ADC driver
+ *
+ * Based on the work of Haibo Chen <haibo.chen at nxp.com>
+ * The initial developer of the original code is Haibo Chen.
+ * Portions created by Haibo Chen are Copyright (C) 2018 NXP.
+ * All Rights Reserved.
+ *
+ * Copyright (C) 2018 NXP
+ * Copyright (C) 2021 Cai Huoqing
  */
 
 #include <linux/clk.h>
-- 
2.25.1



From caihuoqing at baidu.com  Mon Aug 30 10:21:35 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 01:21:35 +0800
Subject: [PATCH 1/6] iio: adc: Init the driver for NXP i.MX8QuadXPlus
In-Reply-To: <20210830172140.414-1-caihuoqing@baidu.com>
References: <20210830172140.414-1-caihuoqing@baidu.com>
Message-ID: <20210830172140.414-2-caihuoqing@baidu.com>

ADC

The NXP i.MX 8QuadXPlus SOC has a new ADC IP. This patch init
this ADC driver.

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/iio/adc/imx8qxp-adc.c | 67 +++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 drivers/iio/adc/imx8qxp-adc.c

diff --git a/drivers/iio/adc/imx8qxp-adc.c b/drivers/iio/adc/imx8qxp-adc.c
new file mode 100644
index 000000000000..aec1b45c8fb9
--- /dev/null
+++ b/drivers/iio/adc/imx8qxp-adc.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NXP i.MX8QXP ADC driver
+ */
+
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
+#include <linux/iio/sysfs.h>
+
+#define ADC_DRIVER_NAME		"imx8qxp-adc"
+
+static int imx8qxp_adc_probe(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int imx8qxp_adc_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int imx8qxp_adc_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int imx8qxp_adc_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops imx8qxp_adc_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+	SET_RUNTIME_PM_OPS(imx8qxp_adc_runtime_suspend, imx8qxp_adc_runtime_resume, NULL)
+};
+
+static const struct of_device_id imx8qxp_adc_match[] = {
+	{ .compatible = "nxp,imx8qxp-adc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx8qxp_adc_match);
+
+static struct platform_driver imx8qxp_adc_driver = {
+	.probe		= imx8qxp_adc_probe,
+	.remove		= imx8qxp_adc_remove,
+	.driver		= {
+		.name	= ADC_DRIVER_NAME,
+		.of_match_table = imx8qxp_adc_match,
+		.pm	= &imx8qxp_adc_pm_ops,
+	},
+};
+
+module_platform_driver(imx8qxp_adc_driver);
+
+MODULE_DESCRIPTION("i.MX8QuadXPlus ADC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From caihuoqing at baidu.com  Mon Aug 30 10:21:39 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 01:21:39 +0800
Subject: [PATCH 5/6] MAINTAINERS: Add the driver info of the NXP IMX8QXP ADC
In-Reply-To: <20210830172140.414-1-caihuoqing@baidu.com>
References: <20210830172140.414-1-caihuoqing@baidu.com>
Message-ID: <20210830172140.414-6-caihuoqing@baidu.com>

The NXP i.MX 8QuadXPlus SOC has a new ADC IP. After adding
the driver support for it, I add the driver info of the
NXP IMX8QXP ADC to MAINTAINERS file.

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0147a85bc38b..058394fd3387 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13463,6 +13463,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/display/imx/nxp,imx8mq-dcss.yaml
 F:	drivers/gpu/drm/imx/dcss/
 
+NXP i.MX 8QXP ADC DRIVER
+M:	Cai Huoqing <caihuoqing at baidu.com>
+L:	linux-iio at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
+F:	drivers/iio/adc/imx8qxp-adc.c
+
 NXP PF8100/PF8121A/PF8200 PMIC REGULATOR DEVICE DRIVER
 M:	Jagan Teki <jagan at amarulasolutions.com>
 S:	Maintained
-- 
2.25.1



From caihuoqing at baidu.com  Mon Aug 30 10:21:36 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 01:21:36 +0800
Subject: [PATCH 2/6] iio: adc: Add configuration for NXP i.MX8QuadXPlus ADC
 driver
In-Reply-To: <20210830172140.414-1-caihuoqing@baidu.com>
References: <20210830172140.414-1-caihuoqing@baidu.com>
Message-ID: <20210830172140.414-3-caihuoqing@baidu.com>

The NXP i.MX 8QuadXPlus SOC has a new ADC IP, so add the configuration
for NXP i.MX8QuadXPlus ADC driver.

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/iio/adc/Kconfig  | 10 ++++++++++
 drivers/iio/adc/Makefile |  1 +
 2 files changed, 11 insertions(+)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index af168e1c9fdb..fa8ad63d6ac2 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -530,6 +530,16 @@ config IMX7D_ADC
 	  This driver can also be built as a module. If so, the module will be
 	  called imx7d_adc.
 
+config IMX8QXP_ADC
+	tristate "NXP IMX8QXP ADC driver"
+	depends on ARCH_MXC_ARM64 || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  Say yes here to build support for IMX8QXP ADC.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called imx8qxp-adc.
+
 config LP8788_ADC
 	tristate "LP8788 ADC driver"
 	depends on MFD_LP8788
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index d68550f493e3..d3f53549720c 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
 obj-$(CONFIG_HI8435) += hi8435.o
 obj-$(CONFIG_HX711) += hx711.o
 obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
+obj-$(CONFIG_IMX8QXP_ADC) += imx8qxp-adc.o
 obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
 obj-$(CONFIG_INGENIC_ADC) += ingenic-adc.o
 obj-$(CONFIG_INTEL_MRFLD_ADC) += intel_mrfld_adc.o
-- 
2.25.1



From caihuoqing at baidu.com  Mon Aug 30 10:21:38 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 01:21:38 +0800
Subject: [PATCH 4/6] dt-bindings: iio: adc: Add the binding documentation for
 NXP IMX8QXP ADC
In-Reply-To: <20210830172140.414-1-caihuoqing@baidu.com>
References: <20210830172140.414-1-caihuoqing@baidu.com>
Message-ID: <20210830172140.414-5-caihuoqing@baidu.com>

The NXP i.MX 8QuadXPlus SOC has a new ADC IP, so add the binding
documentation for NXP IMX8QXP ADC

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 .../bindings/iio/adc/nxp,imx8qxp-adc.yaml     | 85 +++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml

diff --git a/Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
new file mode 100644
index 000000000000..542329e6a785
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/nxp,imx8qxp-adc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP IMX8QXP ADC bindings
+
+maintainers:
+  - Cai Huoqing <caihuoqing at baidu.com>
+
+description:
+  Supports the ADC found on the IMX8QXP SoC.
+
+properties:
+  compatible:
+    const: nxp,imx8qxp-adc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: per
+      - const: ipg
+
+  assigned-clocks:
+    maxItems: 1
+
+  assigned-clocks-rate:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  status:
+    const: disable
+
+  "#io-channel-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupts-parent
+  - clocks
+  - clock-names
+  - assigned-clocks
+  - assigned-clock-rates
+  - power-domains
+  - state
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/firmware/imx/rsrc.h>
+    soc {
+        #address-cells = <1>;
+        #size-cells = <1>;
+	 adc at 5a880000 {
+            compatible = "nxp,imx8qxp-adc";
+            reg = <0x0 0x5a880000 0x0 0x10000>;
+            interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&clk IMX_SC_R_ADC_0>,
+                     <&clk IMX_ADMA_LPCG_ADC_0_IPG_CLK>;
+            clock-names = "per", "ipg";
+            assigned-clocks = <&clk IMX_SC_R_ADC_0>;
+            assigned-clock-rates = <24000000>;
+            power-domains = <&pm, IMX_SC_R_ADC_0>;
+            status = "disabled";
+            #io-channel-cells = <1>
+	 };
+    };
+...
-- 
2.25.1



From jiancai at google.com  Mon Aug 30 10:28:19 2021
From: jiancai at google.com (Jian Cai)
Date: Mon, 30 Aug 2021 10:28:19 -0700
Subject: [PATCH v2] coresight: syscfg: fix compiler warnings
Message-ID: <20210830172820.2840433-1-jiancai@google.com>

This fixes warnings with -Wimplicit-function-declaration, e.g.

drivers/hwtracing/coresight/coresight-syscfg.c:455:15: error:
implicit declaration of function 'kzalloc' [-Werror,
-Wimplicit-function-declaration]
        csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev),
                             GFP_KERNEL);

Fixes: 85e2414c518a ("coresight: syscfg: Initial coresight system configuration")
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
Signed-off-by: Jian Cai <jiancai at google.com>
---

Changes v1 -> v2:
  Format the commit message and add Fixes and Reviewed-by tag.

 drivers/hwtracing/coresight/coresight-syscfg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index fc0760f55c53..43054568430f 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "coresight-config.h"
 #include "coresight-etm-perf.h"
-- 
2.33.0.259.gc128427fd7-goog



From festevam at gmail.com  Mon Aug 30 10:41:12 2021
From: festevam at gmail.com (Fabio Estevam)
Date: Mon, 30 Aug 2021 14:41:12 -0300
Subject: [PATCH 1/6] iio: adc: Init the driver for NXP i.MX8QuadXPlus
In-Reply-To: <20210830172140.414-2-caihuoqing@baidu.com>
References: <20210830172140.414-1-caihuoqing@baidu.com>
 <20210830172140.414-2-caihuoqing@baidu.com>
Message-ID: <CAOMZO5CG_NtGC3ZJv+qy2YOk-J6gLyZpUMty+jna3v4V6DfmnQ@mail.gmail.com>

Hi Cai,

On Mon, Aug 30, 2021 at 2:22 PM Cai Huoqing <caihuoqing at baidu.com> wrote:

> +static int imx8qxp_adc_probe(struct platform_device *pdev)
> +{
> +       return 0;
> +}

This is not the correct way to split the series.

Patches 1, 2, 3, and 5 could be squashed into a single patch.

Thanks


From mike.rudenko at gmail.com  Mon Aug 30 11:07:49 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:49 +0300
Subject: [PATCH v1 0/5] phy: phy-rockchip-dphy-rx0: add support for tx1rx1 rx
 mode
Message-ID: <20210830180758.251390-1-mike.rudenko@gmail.com>

Implement support for RX mode of TX1RX1 D-PHY on RK3399. Code is based
on Rockchip BSP kernel branch 4.4. These patches have been tested on
FriendlyElec NanoPi M4 with OmniVision 4689-based sensor.


Mikhail Rudenko (5):
  phy: phy-rockchip-dphy-rx0: refactor for tx1rx1 addition
  phy: phy-rockchip-dphy-rx0: add support for tx1rx1 in receive mode
  phy: rename phy-rockchip-dphy-rx0 to phy-rockchip-dphy-rx
  dt-bindings: phy: phy-rockchip-dphy-rx0: add support for tx1rx1 phy
  arm64: dts: rockchip: add mipi-dphy-tx1rx1 for rk3399

 ...hy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} |  39 ++-
 arch/arm64/boot/dts/rockchip/rk3399.dtsi      |  15 ++
 drivers/phy/rockchip/Kconfig                  |   8 +-
 drivers/phy/rockchip/Makefile                 |   2 +-
 ...chip-dphy-rx0.c => phy-rockchip-dphy-rx.c} | 231 +++++++++++++++---
 5 files changed, 252 insertions(+), 43 deletions(-)
 rename Documentation/devicetree/bindings/phy/{rockchip-mipi-dphy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} (65%)
 rename drivers/phy/rockchip/{phy-rockchip-dphy-rx0.c => phy-rockchip-dphy-rx.c} (63%)

--
2.33.0


From mike.rudenko at gmail.com  Mon Aug 30 11:07:50 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:50 +0300
Subject: [PATCH v1 1/5] phy: phy-rockchip-dphy-rx0: refactor for tx1rx1
 addition
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-2-mike.rudenko@gmail.com>

In order to accommodate for rk3399 tx1rx1 addition, make
enable/disable function calls indirect via function pointers in
rk_dphy_drv_data. Also rename rk_dphy_write and rk_dphy_enable to
avoid naming clashes.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 38 +++++++++++++-------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
index 4df9476ef2a9..72145cdfb036 100644
--- a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
+++ b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
@@ -138,12 +138,17 @@ static const struct dphy_reg rk3399_grf_dphy_regs[] = {
 	[GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
 };
 
+struct rk_dphy;
+
 struct rk_dphy_drv_data {
 	const char * const *clks;
 	unsigned int num_clks;
 	const struct hsfreq_range *hsfreq_ranges;
 	unsigned int num_hsfreq_ranges;
 	const struct dphy_reg *regs;
+
+	void (*enable)(struct rk_dphy *priv);
+	void (*disable)(struct rk_dphy *priv);
 };
 
 struct rk_dphy {
@@ -170,7 +175,7 @@ static inline void rk_dphy_write_grf(struct rk_dphy *priv,
 	regmap_write(priv->grf, reg->offset, val);
 }
 
-static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
+static void rk_dphy_write_mipi_rx(struct rk_dphy *priv, u8 test_code, u8 test_data)
 {
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTDIN, test_code);
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTEN, 1);
@@ -186,7 +191,7 @@ static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 1);
 }
 
-static void rk_dphy_enable(struct rk_dphy *priv)
+static void rk_dphy_enable_rx(struct rk_dphy *priv)
 {
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCERXMODE, 0);
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCETXSTOPMODE, 0);
@@ -206,22 +211,27 @@ static void rk_dphy_enable(struct rk_dphy *priv)
 	usleep_range(100, 150);
 
 	/* set clock lane */
-	/* HS hsfreq_range & lane 0  settle bypass */
-	rk_dphy_write(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
+	/* HS hsfreq_range & lane 0	 settle bypass */
+	rk_dphy_write_mipi_rx(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
 	/* HS RX Control of lane0 */
-	rk_dphy_write(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_rx(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
 	/* HS RX Control of lane1 */
-	rk_dphy_write(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_rx(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
 	/* HS RX Control of lane2 */
-	rk_dphy_write(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_rx(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
 	/* HS RX Control of lane3 */
-	rk_dphy_write(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_rx(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
 	/* HS RX Data Lanes Settle State Time Control */
-	rk_dphy_write(priv, LANES_THS_SETTLE_CONTROL,
-		      THS_SETTLE_COUNTER_THRESHOLD);
+	rk_dphy_write_mipi_rx(priv, LANES_THS_SETTLE_CONTROL,
+			  THS_SETTLE_COUNTER_THRESHOLD);
 
 	/* Normal operation */
-	rk_dphy_write(priv, 0x0, 0);
+	rk_dphy_write_mipi_rx(priv, 0x0, 0);
+}
+
+static void rk_dphy_disable_rx(struct rk_dphy *priv)
+{
+	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
 }
 
 static int rk_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
@@ -266,7 +276,7 @@ static int rk_dphy_power_on(struct phy *phy)
 	if (ret)
 		return ret;
 
-	rk_dphy_enable(priv);
+	priv->drv_data->enable(priv);
 
 	return 0;
 }
@@ -275,7 +285,7 @@ static int rk_dphy_power_off(struct phy *phy)
 {
 	struct rk_dphy *priv = phy_get_drvdata(phy);
 
-	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
+	priv->drv_data->disable(priv);
 	clk_bulk_disable(priv->drv_data->num_clks, priv->clks);
 	return 0;
 }
@@ -310,6 +320,8 @@ static const struct rk_dphy_drv_data rk3399_mipidphy_drv_data = {
 	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
 	.regs = rk3399_grf_dphy_regs,
+	.enable = rk_dphy_enable_rx,
+	.disable = rk_dphy_disable_rx,
 };
 
 static const struct of_device_id rk_dphy_dt_ids[] = {
-- 
2.33.0



From mike.rudenko at gmail.com  Mon Aug 30 11:07:51 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:51 +0300
Subject: [PATCH v1 2/5] phy: phy-rockchip-dphy-rx0: add support for tx1rx1 in
 receive mode
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-3-mike.rudenko@gmail.com>

Implement RX mode of RK3399 TX1RX1 MIPI D-PHY. Unlike RX0 phy, it uses
both mmio registers and grf for configuration. Add necessary register
definitions, mmio register access functions, enable/disable functions,
rk_dphy_drv_data instance and compatible string for tx1rx1. Probe
function is adjusted accordingly.

Additionally, individual init function is implemented, since,
according to the comments in Rockchip BSP kernel, "According to the
sequence of RK3399_TXRX_DPHY, the setting of isp0 mipi will affect
txrx dphy in default state of grf_soc_con24."

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 193 +++++++++++++++++--
 1 file changed, 172 insertions(+), 21 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
index 72145cdfb036..3ce307b49e51 100644
--- a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
+++ b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
@@ -34,6 +34,12 @@
 #define RK3399_GRF_SOC_CON24		0x6260
 #define RK3399_GRF_SOC_CON25		0x6264
 #define RK3399_GRF_SOC_STATUS1		0xe2a4
+#define RK3399_GRF_IO_VSEL			0x0900
+
+#define RK3399_PHY_TEST_CTRL0	0xb4
+#define RK3399_PHY_TEST_CTRL1	0xb8
+#define RK3399_PHY_SHUTDOWNZ	0xa0
+#define RK3399_PHY_RSTZ		0xa0
 
 #define CLOCK_LANE_HS_RX_CONTROL	0x34
 #define LANE0_HS_RX_CONTROL		0x44
@@ -43,6 +49,11 @@
 #define LANES_THS_SETTLE_CONTROL	0x75
 #define THS_SETTLE_COUNTER_THRESHOLD	0x04
 
+#define PHY_TESTEN_ADDR			(0x1 << 16)
+#define PHY_TESTEN_DATA			(0x0 << 16)
+#define PHY_TESTCLK			(0x1 << 1)
+#define PHY_TESTCLR			(0x1 << 0)
+
 struct hsfreq_range {
 	u16 range_h;
 	u8 cfg_bit;
@@ -61,12 +72,6 @@ static const struct hsfreq_range rk3399_mipidphy_hsfreq_ranges[] = {
 	{ 1399, 0x1c }, { 1449, 0x2c }, { 1500, 0x3c }
 };
 
-static const char * const rk3399_mipidphy_clks[] = {
-	"dphy-ref",
-	"dphy-cfg",
-	"grf",
-};
-
 enum dphy_reg_id {
 	GRF_DPHY_RX0_TURNDISABLE = 0,
 	GRF_DPHY_RX0_FORCERXMODE,
@@ -99,6 +104,14 @@ enum dphy_reg_id {
 	/* below is for rk3399 only */
 	GRF_DPHY_RX0_CLK_INV_SEL,
 	GRF_DPHY_RX1_CLK_INV_SEL,
+	GRF_DPHY_TX1RX1_SRC_SEL,
+};
+
+enum txrx_reg_id {
+	TXRX_PHY_TEST_CTRL0 = 0,
+	TXRX_PHY_TEST_CTRL1,
+	TXRX_PHY_SHUTDOWNZ,
+	TXRX_PHY_RSTZ,
 };
 
 struct dphy_reg {
@@ -127,7 +140,7 @@ static const struct dphy_reg rk3399_grf_dphy_regs[] = {
 	[GRF_DPHY_TX1RX1_FORCETXSTOPMODE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 8),
 	[GRF_DPHY_TX1RX1_TURNDISABLE] = PHY_REG(RK3399_GRF_SOC_CON23, 4, 12),
 	[GRF_DPHY_TX1RX1_TURNREQUEST] = PHY_REG(RK3399_GRF_SOC_CON24, 4, 0),
-	[GRF_DPHY_RX1_SRC_SEL] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 4),
+	[GRF_DPHY_TX1RX1_SRC_SEL] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 4),
 	[GRF_DPHY_TX1RX1_BASEDIR] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 5),
 	[GRF_DPHY_TX1RX1_ENABLECLK] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 6),
 	[GRF_DPHY_TX1RX1_MASTERSLAVEZ] = PHY_REG(RK3399_GRF_SOC_CON24, 1, 7),
@@ -136,6 +149,21 @@ static const struct dphy_reg rk3399_grf_dphy_regs[] = {
 	[GRF_DPHY_RX0_TESTCLK] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 9),
 	[GRF_DPHY_RX0_TESTCLR] = PHY_REG(RK3399_GRF_SOC_CON25, 1, 10),
 	[GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
+	[GRF_DVP_V18SEL] = PHY_REG(RK3399_GRF_IO_VSEL, 1, 1),
+};
+
+struct txrx_reg {
+	u32 offset;
+};
+
+#define TXRX_REG(_offset) \
+	{ .offset = _offset, }
+
+static const struct txrx_reg rk3399_txrx_regs[] = {
+	[TXRX_PHY_TEST_CTRL0] = TXRX_REG(RK3399_PHY_TEST_CTRL0),
+	[TXRX_PHY_TEST_CTRL1] = TXRX_REG(RK3399_PHY_TEST_CTRL1),
+	[TXRX_PHY_SHUTDOWNZ] = TXRX_REG(RK3399_PHY_SHUTDOWNZ),
+	[TXRX_PHY_RSTZ] = TXRX_REG(RK3399_PHY_RSTZ),
 };
 
 struct rk_dphy;
@@ -146,15 +174,18 @@ struct rk_dphy_drv_data {
 	const struct hsfreq_range *hsfreq_ranges;
 	unsigned int num_hsfreq_ranges;
 	const struct dphy_reg *regs;
+	const struct txrx_reg *txrx_regs;
 
 	void (*enable)(struct rk_dphy *priv);
 	void (*disable)(struct rk_dphy *priv);
+	void (*individual_init)(struct rk_dphy *priv);
 };
 
 struct rk_dphy {
 	struct device *dev;
 	struct regmap *grf;
 	struct clk_bulk_data *clks;
+	void __iomem *txrx_base_addr;
 
 	const struct rk_dphy_drv_data *drv_data;
 	struct phy_configure_opts_mipi_dphy config;
@@ -234,6 +265,74 @@ static void rk_dphy_disable_rx(struct rk_dphy *priv)
 	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
 }
 
+static inline void rk_dphy_write_tx1rx1(struct rk_dphy *priv,
+				  int index, u32 value)
+{
+	const struct txrx_reg *reg = &priv->drv_data->txrx_regs[index];
+
+	if (reg->offset)
+		writel(value, priv->txrx_base_addr + reg->offset);
+}
+
+static void rk_dphy_write_mipi_tx1rx1(struct rk_dphy *priv, unsigned char addr,
+				 unsigned char data)
+{
+	/*
+	 * TESTEN =1,TESTDIN=addr
+	 * TESTCLK=0
+	 * TESTEN =0,TESTDIN=data
+	 * TESTCLK=1
+	 */
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL1, PHY_TESTEN_ADDR | addr);
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL0, 0x00);
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL1, PHY_TESTEN_DATA | data);
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL0, 0x02);
+}
+
+static void rk_dphy_enable_txrx(struct rk_dphy *priv)
+{
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL0, PHY_TESTCLR | PHY_TESTCLK);
+	usleep_range(100, 150);
+
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_MASTERSLAVEZ, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_BASEDIR, 1);
+
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_FORCERXMODE, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_FORCETXSTOPMODE, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_TURNREQUEST, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_TURNDISABLE, 0xf);
+	usleep_range(100, 150);
+
+	rk_dphy_write_tx1rx1(priv, TXRX_PHY_TEST_CTRL0, PHY_TESTCLK);
+	usleep_range(100, 150);
+
+	rk_dphy_write_mipi_tx1rx1(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
+	rk_dphy_write_mipi_tx1rx1(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
+	rk_dphy_write_mipi_tx1rx1(priv, LANE1_HS_RX_CONTROL, 0);
+	rk_dphy_write_mipi_tx1rx1(priv, LANE2_HS_RX_CONTROL, 0);
+	rk_dphy_write_mipi_tx1rx1(priv, LANE3_HS_RX_CONTROL, 0);
+
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_ENABLE, GENMASK(priv->config.lanes - 1, 0));
+	usleep_range(100, 150);
+}
+
+static void rk_dphy_disable_txrx(struct rk_dphy *priv)
+{
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_ENABLE, 0);
+}
+
+static void rk3399_mipidphy_individual_init(struct rk_dphy *priv)
+{
+	/*
+	 * According to the sequence of RK3399_TXRX_DPHY, the setting of isp0 mipi
+	 * will affect txrx dphy in default state of grf_soc_con24.
+	 */
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_SRC_SEL, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_MASTERSLAVEZ, 0);
+	rk_dphy_write_grf(priv, GRF_DPHY_TX1RX1_BASEDIR, 0);
+	rk_dphy_write_grf(priv, GRF_DVP_V18SEL, 0x1);
+}
+
 static int rk_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
 {
 	struct rk_dphy *priv = phy_get_drvdata(phy);
@@ -314,20 +413,50 @@ static const struct phy_ops rk_dphy_ops = {
 	.owner		= THIS_MODULE,
 };
 
-static const struct rk_dphy_drv_data rk3399_mipidphy_drv_data = {
-	.clks = rk3399_mipidphy_clks,
-	.num_clks = ARRAY_SIZE(rk3399_mipidphy_clks),
+static const char * const rk3399_mipidphy_rx_clks[] = {
+	"dphy-ref",
+	"dphy-cfg",
+	"grf",
+};
+
+static const char * const rk3399_mipidphy_txrx_clks[] = {
+	"dphy-ref",
+	"dphy-cfg",
+	"grf",
+	"dsi",
+};
+
+static const struct rk_dphy_drv_data rk3399_mipidphy_rx_drv_data = {
+	.clks = rk3399_mipidphy_rx_clks,
+	.num_clks = ARRAY_SIZE(rk3399_mipidphy_rx_clks),
 	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
 	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
 	.regs = rk3399_grf_dphy_regs,
 	.enable = rk_dphy_enable_rx,
 	.disable = rk_dphy_disable_rx,
+	.individual_init = rk3399_mipidphy_individual_init,
+};
+
+static const struct rk_dphy_drv_data rk3399_mipidphy_txrx_drv_data = {
+	.clks = rk3399_mipidphy_txrx_clks,
+	.num_clks = ARRAY_SIZE(rk3399_mipidphy_txrx_clks),
+	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
+	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
+	.regs = rk3399_grf_dphy_regs,
+	.txrx_regs = rk3399_txrx_regs,
+	.enable = rk_dphy_enable_txrx,
+	.disable = rk_dphy_disable_txrx,
+	.individual_init = rk3399_mipidphy_individual_init,
 };
 
 static const struct of_device_id rk_dphy_dt_ids[] = {
 	{
 		.compatible = "rockchip,rk3399-mipi-dphy-rx0",
-		.data = &rk3399_mipidphy_drv_data,
+		.data = &rk3399_mipidphy_rx_drv_data,
+	},
+	{
+		.compatible = "rockchip,rk3399-mipi-dphy-tx1rx1",
+		.data = &rk3399_mipidphy_txrx_drv_data,
 	},
 	{}
 };
@@ -345,26 +474,42 @@ static int rk_dphy_probe(struct platform_device *pdev)
 	unsigned int i;
 	int ret;
 
-	if (!dev->parent || !dev->parent->of_node)
-		return -ENODEV;
-
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 	priv->dev = dev;
 
-	priv->grf = syscon_node_to_regmap(dev->parent->of_node);
-	if (IS_ERR(priv->grf)) {
-		dev_err(dev, "Can't find GRF syscon\n");
-		return -ENODEV;
-	}
-
 	of_id = of_match_device(rk_dphy_dt_ids, dev);
 	if (!of_id)
 		return -EINVAL;
 
 	drv_data = of_id->data;
 	priv->drv_data = drv_data;
+
+	if (!drv_data->txrx_regs) {
+		if (!dev->parent || !dev->parent->of_node)
+			return -ENODEV;
+
+		priv->grf = syscon_node_to_regmap(dev->parent->of_node);
+		if (IS_ERR(priv->grf)) {
+			dev_err(dev, "Can't find GRF syscon\n");
+			return -ENODEV;
+		}
+	} else {
+		priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+							    "rockchip,grf");
+		if (IS_ERR(priv->grf)) {
+			dev_err(dev, "Can't find GRF syscon\n");
+			return -ENODEV;
+		}
+
+		priv->txrx_base_addr = devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(priv->txrx_base_addr)) {
+			dev_err(dev, "Failed to ioremap resource\n");
+			return PTR_ERR(priv->txrx_base_addr);
+		}
+	}
+
 	priv->clks = devm_kcalloc(&pdev->dev, drv_data->num_clks,
 				  sizeof(*priv->clks), GFP_KERNEL);
 	if (!priv->clks)
@@ -383,8 +528,14 @@ static int rk_dphy_probe(struct platform_device *pdev)
 	phy_set_drvdata(phy, priv);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		dev_err(dev, "failed to register phy provider\n");
+		return PTR_ERR(phy_provider);
+	}
 
-	return PTR_ERR_OR_ZERO(phy_provider);
+	drv_data->individual_init(priv);
+
+	return 0;
 }
 
 static struct platform_driver rk_dphy_driver = {
-- 
2.33.0



From mike.rudenko at gmail.com  Mon Aug 30 11:07:52 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:52 +0300
Subject: [PATCH v1 3/5] phy: rename phy-rockchip-dphy-rx0 to
 phy-rockchip-dphy-rx
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-4-mike.rudenko@gmail.com>

Since the driver now supports both rx0 and tx1rx1 phys, rename module
and Kconfig option to phy-rockchip-dphy-rx and PHY_ROCKCHIP_DPHY_RX
respectively.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 drivers/phy/rockchip/Kconfig                              | 8 ++++----
 drivers/phy/rockchip/Makefile                             | 2 +-
 .../{phy-rockchip-dphy-rx0.c => phy-rockchip-dphy-rx.c}   | 0
 3 files changed, 5 insertions(+), 5 deletions(-)
 rename drivers/phy/rockchip/{phy-rockchip-dphy-rx0.c => phy-rockchip-dphy-rx.c} (100%)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index e812adad7242..6096ca9a07f9 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -9,17 +9,17 @@ config PHY_ROCKCHIP_DP
 	help
 	  Enable this to support the Rockchip Display Port PHY.
 
-config PHY_ROCKCHIP_DPHY_RX0
+config PHY_ROCKCHIP_DPHY_RX
 	tristate "Rockchip MIPI Synopsys DPHY RX0 driver"
 	depends on ARCH_ROCKCHIP || COMPILE_TEST
 	select GENERIC_PHY_MIPI_DPHY
 	select GENERIC_PHY
 	help
-	  Enable this to support the Rockchip MIPI Synopsys DPHY RX0
-	  associated to the Rockchip ISP module present in RK3399 SoCs.
+	  Enable this to support the Rockchip MIPI Synopsys DPHY RX
+	  associated to the Rockchip ISP modules present in RK3399 SoCs.
 
 	  To compile this driver as a module, choose M here: the module
-	  will be called phy-rockchip-dphy-rx0.
+	  will be called phy-rockchip-dphy-rx.
 
 config PHY_ROCKCHIP_EMMC
 	tristate "Rockchip EMMC PHY Driver"
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
index f0eec212b2aa..2d28526808a6 100644
--- a/drivers/phy/rockchip/Makefile
+++ b/drivers/phy/rockchip/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_PHY_ROCKCHIP_DP)		+= phy-rockchip-dp.o
-obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX0)     += phy-rockchip-dphy-rx0.o
+obj-$(CONFIG_PHY_ROCKCHIP_DPHY_RX)     += phy-rockchip-dphy-rx.o
 obj-$(CONFIG_PHY_ROCKCHIP_EMMC)		+= phy-rockchip-emmc.o
 obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY)	+= phy-rockchip-inno-csidphy.o
 obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY)	+= phy-rockchip-inno-dsidphy.o
diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx.c
similarity index 100%
rename from drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
rename to drivers/phy/rockchip/phy-rockchip-dphy-rx.c
-- 
2.33.0



From mike.rudenko at gmail.com  Mon Aug 30 11:07:54 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:54 +0300
Subject: [PATCH v1 5/5] arm64: dts: rockchip: add mipi-dphy-tx1rx1 for rk3399
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-6-mike.rudenko@gmail.com>

Add DT node for RX mode of RK3399 TX1RX1 D-PHY.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 3871c7fd83b0..2e4513275a87 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1902,6 +1902,21 @@ mipi1_in_vopl: endpoint at 1 {
 		};
 	};
 
+	mipi_dphy_tx1rx1: mipi-dphy-tx1rx1 at ff968000 {
+		compatible = "rockchip,rk3399-mipi-dphy-tx1rx1";
+		reg = <0x0 0xff968000 0x0 0x8000>;
+		clocks = <&cru SCLK_MIPIDPHY_REF>,
+			<&cru SCLK_DPHY_TX1RX1_CFG>,
+			<&cru PCLK_VIO_GRF>,
+			<&cru PCLK_MIPI_DSI1>;
+		clock-names = "dphy-ref", "dphy-cfg",
+			"grf", "dsi";
+		rockchip,grf = <&grf>;
+		power-domains = <&power RK3399_PD_VIO>;
+		#phy-cells = <0>;
+		status = "disabled";
+	};
+
 	edp: edp at ff970000 {
 		compatible = "rockchip,rk3399-edp";
 		reg = <0x0 0xff970000 0x0 0x8000>;
-- 
2.33.0



From mike.rudenko at gmail.com  Mon Aug 30 11:07:53 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Mon, 30 Aug 2021 21:07:53 +0300
Subject: [PATCH v1 4/5] dt-bindings: phy: phy-rockchip-dphy-rx0: add support
 for tx1rx1 phy
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <20210830180758.251390-5-mike.rudenko@gmail.com>

RK3399 TX1RX1 D-PHY is not a child of GRF and uses reg, thus add
corresponding properties conditionally. It also requires DSI clock to
operate, so check for it. Since we now support both rx0 and tx1rx1,
rename the schema to rockchip-mipi-dphy-rx.yaml.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 ...hy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} | 39 +++++++++++++++++--
 1 file changed, 35 insertions(+), 4 deletions(-)
 rename Documentation/devicetree/bindings/phy/{rockchip-mipi-dphy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} (65%)

diff --git a/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml b/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
similarity index 65%
rename from Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml
rename to Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
index 7d888d358823..f42319448fc9 100644
--- a/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
@@ -1,10 +1,10 @@
 # SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/phy/rockchip-mipi-dphy-rx0.yaml#
+$id: http://devicetree.org/schemas/phy/rockchip-mipi-dphy-rx.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Rockchip SoC MIPI RX0 D-PHY Device Tree Bindings
+title: Rockchip SoC MIPI RX0/TX1RX1 D-PHY Device Tree Bindings
 
 maintainers:
   - Helen Koike <helen.koike at collabora.com>
@@ -16,19 +16,28 @@ description: |
 
 properties:
   compatible:
-    const: rockchip,rk3399-mipi-dphy-rx0
+    enum:
+      - rockchip,rk3399-mipi-dphy-rx0
+      - rockchip,rk3399-mipi-dphy-tx1rx1
+
+  reg:
+    maxItems: 1
 
   clocks:
+    minItems: 3
     items:
       - description: MIPI D-PHY ref clock
-      - description: MIPI D-PHY RX0 cfg clock
+      - description: MIPI D-PHY RX0/TX1RX1 cfg clock
       - description: Video in/out general register file clock
+      - description: MIPI D-PHY DSI clock
 
   clock-names:
+    minItems: 3
     items:
       - const: dphy-ref
       - const: dphy-cfg
       - const: grf
+      - const: dsi
 
   '#phy-cells':
     const: 0
@@ -37,6 +46,12 @@ properties:
     description: Video in/out power domain.
     maxItems: 1
 
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the general register file
+      (GRF), required for TX1RX1 MIPI D-PHY on RK3399.
+
 required:
   - compatible
   - clocks
@@ -44,6 +59,22 @@ required:
   - '#phy-cells'
   - power-domains
 
+if:
+  properties:
+    compatible:
+      contains:
+          const: rockchip,rk3399-mipi-dphy-tx1rx1
+then:
+  required:
+    - reg
+    - rockchip,grf
+
+  properties:
+    clocks:
+      minItems: 4
+    clock-names:
+      minItems: 4
+
 additionalProperties: false
 
 examples:
-- 
2.33.0



From mathieu.poirier at linaro.org  Mon Aug 30 11:19:45 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 30 Aug 2021 12:19:45 -0600
Subject: [PATCH v3 2/4] remoteproc: Add a remoteproc driver for the
 MT8183's APU
In-Reply-To: <20210819151340.741565-3-abailon@baylibre.com>
References: <20210819151340.741565-1-abailon@baylibre.com>
 <20210819151340.741565-3-abailon@baylibre.com>
Message-ID: <20210830181945.GA934785@p14s>

Hi Alex,

On Thu, Aug 19, 2021 at 05:13:38PM +0200, Alexandre Bailon wrote:
> This adds a driver to control the APU present in the MT8183.
> This loads the firmware and start the DSP.
> 
> Signed-off-by: Alexandre Bailon <abailon at baylibre.com>
> ---
>  drivers/remoteproc/Kconfig   |  10 +
>  drivers/remoteproc/Makefile  |   1 +
>  drivers/remoteproc/mtk_apu.c | 440 +++++++++++++++++++++++++++++++++++
>  3 files changed, 451 insertions(+)
>  create mode 100644 drivers/remoteproc/mtk_apu.c
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 9a6eedc3994a5..6c106a6c3ad5d 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -53,6 +53,16 @@ config MTK_SCP
>  
>  	  It's safe to say N here.
>  
> +config MTK_APU
> +	tristate "Mediatek APU remoteproc support"
> +	depends on ARCH_MEDIATEK
> +	depends on MTK_IOMMU
> +	help
> +	  Say y to support the Mediatek's Accelerated Processing Unit (APU) via

In the bindings A in APU is for AI or Vision whereas above it is for
accelerated.  Please pick one and stick with it.

> +	  the remote processor framework.
> +
> +	  It's safe to say N here.
> +
>  config OMAP_REMOTEPROC
>  	tristate "OMAP remoteproc support"
>  	depends on ARCH_OMAP4 || SOC_OMAP5 || SOC_DRA7XX
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index bb26c9e4ef9cf..e395af86c17b0 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -14,6 +14,7 @@ obj-$(CONFIG_REMOTEPROC_CDEV)		+= remoteproc_cdev.o
>  obj-$(CONFIG_IMX_REMOTEPROC)		+= imx_rproc.o
>  obj-$(CONFIG_INGENIC_VPU_RPROC)		+= ingenic_rproc.o
>  obj-$(CONFIG_MTK_SCP)			+= mtk_scp.o mtk_scp_ipi.o
> +obj-$(CONFIG_MTK_APU)			+= mtk_apu.o
>  obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
>  obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
>  obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
> diff --git a/drivers/remoteproc/mtk_apu.c b/drivers/remoteproc/mtk_apu.c
> new file mode 100644
> index 0000000000000..0e3f63987bd85
> --- /dev/null
> +++ b/drivers/remoteproc/mtk_apu.c
> @@ -0,0 +1,440 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 BayLibre SAS
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/iommu.h>
> +#include <linux/irq.h>
> +#include <linux/module.h>
> +#include <linux/of_reserved_mem.h>
> +#include <linux/platform_device.h>
> +#include <linux/remoteproc.h>
> +
> +#include "remoteproc_internal.h"
> +
> +#define SW_RST					(0x0000000C)
> +#define SW_RST_OCD_HALT_ON_RST			BIT(12)
> +#define SW_RST_IPU_D_RST			BIT(8)
> +#define SW_RST_IPU_B_RST			BIT(4)
> +#define CORE_CTRL				(0x00000110)
> +#define CORE_CTRL_PDEBUG_ENABLE			BIT(31)
> +#define CORE_CTRL_SRAM_64K_iMEM			(0x00 << 27)
> +#define CORE_CTRL_SRAM_96K_iMEM			(0x01 << 27)
> +#define CORE_CTRL_SRAM_128K_iMEM		(0x02 << 27)
> +#define CORE_CTRL_SRAM_192K_iMEM		(0x03 << 27)
> +#define CORE_CTRL_SRAM_256K_iMEM		(0x04 << 27)
> +#define CORE_CTRL_PBCLK_ENABLE			BIT(26)
> +#define CORE_CTRL_RUN_STALL			BIT(23)
> +#define CORE_CTRL_STATE_VECTOR_SELECT		BIT(19)
> +#define CORE_CTRL_PIF_GATED			BIT(17)
> +#define CORE_CTRL_NMI				BIT(0)
> +#define CORE_XTENSA_INT				(0x00000114)
> +#define CORE_CTL_XTENSA_INT			(0x00000118)
> +#define CORE_DEFAULT0				(0x0000013C)
> +#define CORE_DEFAULT0_QOS_SWAP_0		(0x00 << 28)
> +#define CORE_DEFAULT0_QOS_SWAP_1		(0x01 << 28)
> +#define CORE_DEFAULT0_QOS_SWAP_2		(0x02 << 28)
> +#define CORE_DEFAULT0_QOS_SWAP_3		(0x03 << 28)
> +#define CORE_DEFAULT0_ARUSER_USE_IOMMU		(0x10 << 23)
> +#define CORE_DEFAULT0_AWUSER_USE_IOMMU		(0x10 << 18)
> +#define CORE_DEFAULT1				(0x00000140)
> +#define CORE_DEFAULT0_ARUSER_IDMA_USE_IOMMU	(0x10 << 0)
> +#define CORE_DEFAULT0_AWUSER_IDMA_USE_IOMMU	(0x10 << 5)
> +#define CORE_XTENSA_ALTRESETVEC			(0x000001F8)
> +
> +#define RSC_VENDOR_CARVEOUT			(RSC_VENDOR_START + 1)
> +
> +#define APU_RESET_DELAY				(27)
> +
> +struct mtk_apu_rproc {
> +	struct device *dev;
> +	void __iomem *base;
> +	int irq;
> +	struct clk_bulk_data clks[3];
> +	struct list_head mappings;
> +};
> +
> +static int mtk_apu_iommu_map(struct rproc *rproc, struct rproc_mem_entry *entry)
> +{
> +	struct mtk_apu_rproc *apu_rproc = rproc->priv;
> +	struct device *dev = rproc->dev.parent;
> +	struct rproc_mem_entry *mapping;
> +	struct iommu_domain *domain;
> +	int ret;
> +	u64 pa;
> +
> +	mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
> +	if (!mapping)
> +		return -ENOMEM;
> +
> +	if (!entry->va)
> +		pa = entry->dma;
> +	else
> +		pa = rproc_va_to_pa(entry->va);
> +
> +	if ((strcmp(entry->name, "vdev0vring0") == 0 ||
> +		strcmp(entry->name, "vdev0vring1") == 0)) {

If my guesswork is correct (see below) the above is required to deal with
multiple remote processors.  Why not just look for "vring0" and "vring1"?.  That
way we wouldn't have to keep the "vdev0" part for carveouts that really are
"vdev1". 

> +		entry->va = memremap(entry->dma, entry->len, MEMREMAP_WC);
> +		if (IS_ERR_OR_NULL(entry->va)) {
> +			dev_err(dev, "Unable to map memory region: %pa+%lx\n",
> +				&entry->dma, entry->len);
> +			ret = PTR_ERR(mapping->va);
> +			goto free_mapping;
> +		}
> +		mapping->va = entry->va;
> +	}
> +
> +	domain = iommu_get_domain_for_dev(dev);

Here @domain can be NULL

> +	ret = iommu_map(domain, entry->da, pa, entry->len, entry->flags);

... and iommu_map() isn't dealing with that condition properly.  Please
check for a NULL condition before proceeding.

> +	if (ret) {
> +		dev_err(dev, "iommu_map failed: %d\n", ret);
> +		goto err_memunmap;
> +	}
> +
> +	mapping->da = entry->da;
> +	mapping->len = entry->len;
> +	list_add_tail(&mapping->node, &apu_rproc->mappings);
> +
> +	return 0;
> +
> +err_memunmap:
> +	memunmap(mapping->va);
> +free_mapping:
> +	kfree(mapping);
> +
> +	return ret;
> +}
> +
> +static void mtk_apu_iommu_unmap_all(struct rproc *rproc)
> +{
> +	struct mtk_apu_rproc *apu_rproc = rproc->priv;
> +	struct device *dev = rproc->dev.parent;
> +	struct rproc_mem_entry *entry, *tmp;
> +	struct iommu_domain *domain;
> +
> +	/* clean up iommu mapping entries */
> +	list_for_each_entry_safe(entry, tmp, &apu_rproc->mappings, node) {
> +		size_t unmapped;
> +
> +		domain = iommu_get_domain_for_dev(dev);
> +		unmapped = iommu_unmap(domain, entry->da, entry->len);

Same as above

> +		if (unmapped != entry->len) {
> +			/* nothing much to do besides complaining */
> +			dev_err(dev, "failed to unmap %zx/%zu\n", entry->len,
> +				unmapped);
> +		}
> +		memunmap(entry->va);
> +
> +		list_del(&entry->node);
> +		kfree(entry);
> +	}
> +}
> +
> +static int mtk_apu_rproc_prepare(struct rproc *rproc)
> +{
> +	struct mtk_apu_rproc *apu_rproc = rproc->priv;
> +	int ret;
> +
> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(apu_rproc->clks),
> +				      apu_rproc->clks);
> +	if (ret)
> +		dev_err(apu_rproc->dev, "Failed to enable clocks\n");
> +
> +	return ret;
> +}
> +
> +static int mtk_apu_rproc_unprepare(struct rproc *rproc)
> +{
> +	struct mtk_apu_rproc *apu_rproc = rproc->priv;
> +
> +	clk_bulk_disable_unprepare(ARRAY_SIZE(apu_rproc->clks),
> +				   apu_rproc->clks);
> +
> +	return 0;
> +}
> +
> +static int mtk_apu_rproc_start(struct rproc *rproc)
> +{
> +	struct mtk_apu_rproc *apu_rproc = rproc->priv;
> +	u32 core_ctrl;
> +
> +	/* Set reset vector of APU firmware boot address */
> +	writel(rproc->bootaddr, apu_rproc->base + CORE_XTENSA_ALTRESETVEC);
> +
> +	/* Turn on the clocks and stall the APU */
> +	core_ctrl = readl(apu_rproc->base + CORE_CTRL);
> +	core_ctrl |= CORE_CTRL_PDEBUG_ENABLE | CORE_CTRL_PBCLK_ENABLE |
> +		     CORE_CTRL_STATE_VECTOR_SELECT | CORE_CTRL_RUN_STALL |
> +		     CORE_CTRL_PIF_GATED;
> +	writel(core_ctrl, apu_rproc->base + CORE_CTRL);
> +
> +	/* Reset the APU: this requires 27 ns to be effective on any platform */
> +	writel(SW_RST_OCD_HALT_ON_RST | SW_RST_IPU_B_RST | SW_RST_IPU_D_RST,
> +		apu_rproc->base + SW_RST);
> +	ndelay(APU_RESET_DELAY);
> +	writel(0, apu_rproc->base + SW_RST);
> +
> +	core_ctrl &= ~CORE_CTRL_PIF_GATED;
> +	writel(core_ctrl, apu_rproc->base + CORE_CTRL);
> +
> +	/* Configure memory accesses to go through the IOMMU */
> +	writel(CORE_DEFAULT0_AWUSER_USE_IOMMU | CORE_DEFAULT0_ARUSER_USE_IOMMU |
> +	      CORE_DEFAULT0_QOS_SWAP_1, apu_rproc->base + CORE_DEFAULT0);
> +	writel(CORE_DEFAULT0_AWUSER_IDMA_USE_IOMMU |
> +		CORE_DEFAULT0_ARUSER_IDMA_USE_IOMMU,
> +		apu_rproc->base + CORE_DEFAULT1);
> +
> +	/* Release the APU */
> +	core_ctrl &= ~CORE_CTRL_RUN_STALL;
> +	writel(core_ctrl, apu_rproc->base + CORE_CTRL);
> +
> +	return 0;
> +}
> +
> +static int mtk_apu_rproc_stop(struct rproc *rproc)
> +{
> +	struct mtk_apu_rproc *apu_rproc = rproc->priv;
> +	u32 core_ctrl;
> +
> +	core_ctrl = readl(apu_rproc->base + CORE_CTRL);
> +	writel(core_ctrl | CORE_CTRL_RUN_STALL, apu_rproc->base + CORE_CTRL);
> +
> +	mtk_apu_iommu_unmap_all(rproc);
> +
> +	return 0;
> +}
> +
> +static void mtk_apu_rproc_kick(struct rproc *rproc, int vqid)
> +{
> +	struct mtk_apu_rproc *apu_rproc = rproc->priv;
> +
> +	writel(1 << vqid, apu_rproc->base + CORE_CTL_XTENSA_INT);
> +}
> +
> +static int mtk_apu_load(struct rproc *rproc, const struct firmware *fw)
> +
> +{
> +	struct rproc_mem_entry *entry, *tmp;
> +	int ret;
> +
> +	ret = rproc_elf_load_segments(rproc, fw);
> +	if (ret)
> +		return ret;
> +
> +	list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
> +		ret = mtk_apu_iommu_map(rproc, entry);
> +		if (ret)
> +			goto err_unmap_all;
> +	}
> +
> +	return 0;
> +
> +err_unmap_all:
> +	mtk_apu_iommu_unmap_all(rproc);
> +
> +	return ret;
> +}
> +
> +static struct reserved_mem *of_reserved_mem_by_name(struct rproc *rproc,
> +						    const char *name)
> +{
> +	struct device *dev = rproc->dev.parent;
> +	struct device_node *np = dev->of_node;
> +	struct device_node *target;
> +	struct reserved_mem *rmem;
> +	int idx;
> +
> +	idx = of_property_match_string(np, "memory-region-names", name);
> +	if (idx < 0) {
> +		dev_err(dev, "failed to find %s memory\n", name);
> +		return NULL;
> +	}
> +
> +	target = of_parse_phandle(np, "memory-region", idx);
> +	if (!target)
> +		return NULL;

There is no comment to explain the above gymnastic and as such I have to guess
the firmware resources always have "vdev0" prepended to buffer, vring0 and
vring1.  If I am correct please add a comment to describe the situation, ditto
if I am not correct.

> +
> +	rmem = of_reserved_mem_lookup(target);
> +	if (!rmem)
> +		dev_err(dev, "unable to acquire memory-region\n");
> +	of_node_put(target);
> +
> +	return rmem;
> +}
> +
> +static int mtk_apu_handle_rsc(struct rproc *rproc, u32 rsc_type, void *rsc,
> +			      int offset, int avail)
> +{
> +	struct device *dev = rproc->dev.parent;
> +
> +	if (rsc_type == RSC_VENDOR_CARVEOUT) {
> +		struct fw_rsc_carveout *rsc_carveout = rsc;
> +		struct rproc_mem_entry *mem;
> +		struct reserved_mem *rmem;
> +
> +		rmem = of_reserved_mem_by_name(rproc, rsc_carveout->name);

s/of_reserved_mem_by_name/mtk_of_reserved_mem_by_name

> +		if (!rmem)
> +			return -ENOMEM;
> +
> +		if (rmem->size < rsc_carveout->len) {

I think '!=' would be more appropriate than '<'.  

> +			dev_err(dev, "The reserved memory is too small\n");
> +			return -ENOMEM;
> +		}
> +
> +		mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)rmem->base,
> +					   rsc_carveout->len, rsc_carveout->da,
> +					   NULL, NULL, rsc_carveout->name);

Why not naming the carveout the way it is in the DT rather than keeping with
what's in the firmware image?

> +		if (!mem)
> +			return -ENOMEM;
> +
> +		mem->flags = rsc_carveout->flags;
> +		rsc_carveout->pa = rmem->base;
> +		rproc_add_carveout(rproc, mem);
> +	}
> +
> +	return RSC_HANDLED;
> +}
> +
> +static const struct rproc_ops mtk_apu_rproc_ops = {
> +	.prepare		= mtk_apu_rproc_prepare,
> +	.unprepare		= mtk_apu_rproc_unprepare,
> +	.start			= mtk_apu_rproc_start,
> +	.stop			= mtk_apu_rproc_stop,
> +	.kick			= mtk_apu_rproc_kick,
> +	.load			= mtk_apu_load,
> +	.parse_fw		= rproc_elf_load_rsc_table,
> +	.find_loaded_rsc_table	= rproc_elf_find_loaded_rsc_table,
> +	.sanity_check		= rproc_elf_sanity_check,
> +	.get_boot_addr		= rproc_elf_get_boot_addr,
> +	.handle_rsc		= mtk_apu_handle_rsc,
> +};
> +
> +static irqreturn_t mtk_apu_rproc_callback(int irq, void *data)
> +{
> +	struct rproc *rproc = data;
> +	struct mtk_apu_rproc *apu_rproc = (struct mtk_apu_rproc *)rproc->priv;
> +
> +	writel(1, apu_rproc->base + CORE_XTENSA_INT);
> +
> +	return IRQ_WAKE_THREAD;
> +}
> +
> +static irqreturn_t handle_event(int irq, void *data)
> +{
> +	struct rproc *rproc = data;
> +
> +	rproc_vq_interrupt(rproc, 0);
> +	rproc_vq_interrupt(rproc, 1);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int mtk_apu_rproc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_apu_rproc *apu_rproc;
> +	struct rproc *rproc;
> +	struct resource *res;
> +	int ret;
> +
> +	rproc = rproc_alloc(dev, dev_name(dev), &mtk_apu_rproc_ops, NULL,
> +			    sizeof(*apu_rproc));
> +	if (!rproc)
> +		return -ENOMEM;
> +
> +	rproc->recovery_disabled = true;
> +	rproc->has_iommu = false;
> +	rproc->auto_boot = false;
> +
> +	apu_rproc = rproc->priv;
> +	apu_rproc->dev = dev;
> +	INIT_LIST_HEAD(&apu_rproc->mappings);
> +
> +	platform_set_drvdata(pdev, rproc);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	apu_rproc->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(apu_rproc->base)) {
> +		dev_err(dev, "Failed to map mmio\n");
> +		ret = PTR_ERR(apu_rproc->base);
> +		goto free_rproc;
> +	}
> +
> +	apu_rproc->irq = platform_get_irq(pdev, 0);
> +	if (apu_rproc->irq < 0) {
> +		ret = apu_rproc->irq;
> +		goto free_rproc;
> +	}
> +
> +	ret = devm_request_threaded_irq(dev, apu_rproc->irq,
> +					mtk_apu_rproc_callback, handle_event,
> +					IRQF_SHARED | IRQF_ONESHOT,
> +					NULL, rproc);

I'm pretty sure I commented on that during my last review - is there a need to
do a threaded irq here?  As far as I can tell there is no advantage in doing so
in this context.  Please add a comment to justify using a threaded irq.

Thanks,
Mathieu

> +	if (ret) {
> +		dev_err(dev, "devm_request_threaded_irq error: %d\n", ret);
> +		goto free_rproc;
> +	}
> +
> +	apu_rproc->clks[0].id = "ipu";
> +	apu_rproc->clks[1].id = "axi";
> +	apu_rproc->clks[2].id = "jtag";
> +
> +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(apu_rproc->clks),
> +				apu_rproc->clks);
> +	if (ret) {
> +		dev_err(dev, "Failed to get clocks\n");
> +		goto free_rproc;
> +	}
> +
> +	ret = rproc_add(rproc);
> +	if (ret) {
> +		dev_err(dev, "rproc_add failed: %d\n", ret);
> +		goto free_rproc;
> +	}
> +
> +	return 0;
> +
> +free_rproc:
> +	rproc_free(rproc);
> +
> +	return ret;
> +}
> +
> +static int mtk_apu_rproc_remove(struct platform_device *pdev)
> +{
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct mtk_apu_rproc *apu_rproc = (struct mtk_apu_rproc *)rproc->priv;
> +	struct device *dev = &pdev->dev;
> +
> +	disable_irq(apu_rproc->irq);
> +
> +	rproc_del(rproc);
> +	of_reserved_mem_device_release(dev);
> +	rproc_free(rproc);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id mtk_apu_rproc_of_match[] = {
> +	{ .compatible = "mediatek,mt8183-apu", },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, mtk_apu_rproc_of_match);
> +
> +static struct platform_driver mtk_apu_rproc_driver = {
> +	.probe = mtk_apu_rproc_probe,
> +	.remove = mtk_apu_rproc_remove,
> +	.driver = {
> +		.name = "mtk_apu-rproc",
> +		.of_match_table = of_match_ptr(mtk_apu_rproc_of_match),
> +	},
> +};
> +module_platform_driver(mtk_apu_rproc_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Alexandre Bailon");
> +MODULE_DESCRIPTION("MTK APU Remote Processor control driver");
> -- 
> 2.31.1
> 


From kuba at kernel.org  Mon Aug 30 11:26:53 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 30 Aug 2021 11:26:53 -0700
Subject: [PATCH v2] stmmac: dwmac-loongson: change the pr_info() to
 dev_err() in loongson_dwmac_probe()
In-Reply-To: <20210830012417.14872-1-zhaoxiao@uniontech.com>
References: <20210830012417.14872-1-zhaoxiao@uniontech.com>
Message-ID: <20210830112653.450eab49@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Mon, 30 Aug 2021 09:24:17 +0800 zhaoxiao wrote:
> @@ -69,6 +68,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>  	if (!plat)
>  		return -ENOMEM;
>  
> +
>  	if (plat->mdio_node) {
>  		dev_err(&pdev->dev, "Found MDIO subnode\n");
>  		mdio = true;
> @@ -111,6 +111,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>  	phy_mode = device_get_phy_mode(&pdev->dev);
>  	if (phy_mode < 0)
>  		dev_err(&pdev->dev, "phy_mode not found\n");
> +	
>  
>  	plat->phy_interface = phy_mode;
>  	plat->interface = PHY_INTERFACE_MODE_GMII;

Please remove these changes from the patch.


From kuba at kernel.org  Mon Aug 30 11:30:20 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 30 Aug 2021 11:30:20 -0700
Subject: [PATCH] stmmac: dwmac-loongson:add the return value
In-Reply-To: <20210830052913.12793-1-zhaoxiao@uniontech.com>
References: <20210830052913.12793-1-zhaoxiao@uniontech.com>
Message-ID: <20210830113020.3ea992a2@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Mon, 30 Aug 2021 13:29:13 +0800 zhaoxiao wrote:
> Add the return value when phy_mode < 0.
> 
> Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> index 4c9a37dd0d3f..ecf759ee1c9f 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
> @@ -109,8 +109,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
>  		plat->bus_id = pci_dev_id(pdev);
>  
>  	phy_mode = device_get_phy_mode(&pdev->dev);
> -	if (phy_mode < 0)
> +	if (phy_mode < 0) {
>  		dev_err(&pdev->dev, "phy_mode not found\n");
> +		return phy_mode;
> +	}
>  
>  	plat->phy_interface = phy_mode;
>  	plat->interface = PHY_INTERFACE_MODE_GMII;

Qing Zhang, does the change look correct to you?

Is it better to assume GMII and continue like the code is currently
doing?


From miles.chen at mediatek.com  Mon Aug 30 11:43:04 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 31 Aug 2021 02:43:04 +0800
Subject: [RESEND PATCH 3/4] clk: mediatek: support COMMON_CLK_MT6779
 module build
In-Reply-To: <163021049667.2676726.10138202396240942833@swboyd.mtv.corp.google.com>
References: <20210813032429.14715-1-miles.chen@mediatek.com>
 <20210813032429.14715-4-miles.chen@mediatek.com>
 <163021049667.2676726.10138202396240942833@swboyd.mtv.corp.google.com>
Message-ID: <1630348984.24981.2.camel@mtkswgap22>

On Sat, 2021-08-28 at 21:14 -0700, Stephen Boyd wrote:
> Quoting Miles Chen (2021-08-12 20:24:28)
> > diff --git a/drivers/clk/mediatek/clk-mt6779-aud.c b/drivers/clk/mediatek/clk-mt6779-aud.c
> > index 11b209f95e25..439c0bc94b73 100644
> > --- a/drivers/clk/mediatek/clk-mt6779-aud.c
> > +++ b/drivers/clk/mediatek/clk-mt6779-aud.c
> > @@ -4,6 +4,7 @@
> >   * Author: Wendell Lin <wendell.lin at mediatek.com>
> >   */
> >  
> > +#include <linux/module.h>
> >  #include <linux/clk-provider.h>
> >  #include <linux/of.h>
> >  #include <linux/of_address.h>
> > @@ -115,3 +116,4 @@ static struct platform_driver clk_mt6779_aud_drv = {
> >  };
> >  
> >  builtin_platform_driver(clk_mt6779_aud_drv);
> > +MODULE_LICENSE("GPL");
> 
> How does this work? builtin_platform_driver() means that it's not
> modular code. Shouldn't that be module_platform_driver()? Have you tried
> loading and unloading the module?

sorry for my late response. 

Thanks for pointing this out. I have the same question when I was
building this patch. That time I found some examples where
they are using builtin_platform_driver and can be built as 
kernel modules:

config CLK_IMX8QXP (tristate) && drivers/clk/imx/clk-imx8qxp-lpcg.c
config CLK_RK3399 (tristate) && drivers/clk/rockchip/clk-rk3399.c

my load test:
load these moduless and do 'lsmod' on v5.14-rc1/mt6779 environment:

clk_mt6779_aud 16384 0 [permanent], Live 0xffff800008fd8000
clk_mt6779_mfg 16384 0 [permanent], Live 0xffff800008fd0000
clk_mt6779_venc 16384 0 [permanent], Live 0xffff800008fc8000
clk_mt6779_vdec 16384 0 [permanent], Live 0xffff800008fc0000
clk_mt6779_cam 16384 0 [permanent], Live 0xffff800008fb8000
clk_mt6779_ipe 16384 0 [permanent], Live 0xffff800008fb0000
clk_mt6779_img 16384 0 [permanent], Live 0xffff800008fa8000
clk_mt6779_mm 16384 0 [permanent], Live 0xffff800008fa0000

I did not test 'unload' kernel modules because I did not
define module_exit in this patch.

But as you pointed out, it should be module_platform_driver().
I will use module_platform_driver() in the next patch.


Miles

From sashal at kernel.org  Mon Aug 30 12:22:29 2021
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 30 Aug 2021 15:22:29 -0400
Subject: [PATCH] net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable
 warnings
In-Reply-To: <568a0825-ed65-58d7-9c9c-cecb481cf9d9@wolfvision.net>
References: <20210823143754.14294-1-michael.riesch@wolfvision.net>
 <CAGb2v67Duk_56fOKVwZsYn2HKJ99o8WJ+d4jetD2UjDsAt9BcA@mail.gmail.com>
 <568a0825-ed65-58d7-9c9c-cecb481cf9d9@wolfvision.net>
Message-ID: <YS0v9UbzoHkiU9om@sashalap>

On Mon, Aug 30, 2021 at 09:57:51AM +0200, Michael Riesch wrote:
>Hi ChenYu,
>
>On 8/29/21 7:48 PM, Chen-Yu Tsai wrote:
>> Hi,
>>
>> On Mon, Aug 23, 2021 at 10:39 PM Michael Riesch
>> <michael.riesch at wolfvision.net> wrote:
>>>
>>> This reverts commit 2c896fb02e7f65299646f295a007bda043e0f382
>>> "net: stmmac: dwmac-rk: add pd_gmac support for rk3399" and fixes
>>> unbalanced pm_runtime_enable warnings.
>>>
>>> In the commit to be reverted, support for power management was
>>> introduced to the Rockchip glue code. Later, power management support
>>> was introduced to the stmmac core code, resulting in multiple
>>> invocations of pm_runtime_{enable,disable,get_sync,put_sync}.
>>>
>>> The multiple invocations happen in rk_gmac_powerup and
>>> stmmac_{dvr_probe, resume} as well as in rk_gmac_powerdown and
>>> stmmac_{dvr_remove, suspend}, respectively, which are always called
>>> in conjunction.
>>>
>>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>>
>> I just found that Ethernet stopped working on my RK3399 devices,
>> and I bisected it down to this patch.
>
>Oh dear. First patch in a kernel release for a while and I already break
>things.
>
>Cc: Sasha as this patch has just been applied to 5.13-stable.

I'll drop it for now, thanks for letting me know!

-- 
Thanks,
Sasha


From martin.blumenstingl at googlemail.com  Mon Aug 30 12:37:12 2021
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Mon, 30 Aug 2021 21:37:12 +0200
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
 <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>
Message-ID: <CAFBinCBeNMET2tvH0h6HF3dR+xBb59hifQyaoXigUs3UGkS+KQ@mail.gmail.com>

Hi Neil,

On Mon, Aug 30, 2021 at 9:45 AM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi,
>
> On 17/08/2021 06:15, Anand Moon wrote:
> > Add missing usb phy power node for usb node fix below warning.
> > P5V0 regulator supply input voltage range to USB host controller.
> > As described in the C1+ schematics, GPIO GPIOAO_5 is used to
> > enable input power to USB ports, set it to Active Low.
> >
> > [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
> > [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
> >               mode /soc/usb at c90c0000 failed
>
> First of all, DT is not here to fix boot message.
Anand mentioned elsewhere that this is a debug/info message

> Finally, I looked at the Odroid-C1 schematics and the GPIOAO.BIT5 is an input
> to the S805, and the PWREN signal is controlled by the USB Hub so this regulator
> should not be added at all.
I think there's a misunderstanding because there's two PWREN signals
with different meanings.
The PWREN signal for the USB host ports is hard-wired and not
connected to the SoC at all.
The PWREN signal for the Micro-USB port (which Anand is adding here)
is controlled by GPIOAO_5. odroid-c1+_rev0.4_20150615.pdf [0] shows it
as an input to "USB_OTG" on page 1. "USB_OTG" consists of a power
switch and the connector itself as shown on page 28.

Personally I think that the change from Anand itself is good.
If you feel otherwise then please speak up.
As I pointed out three smaller changes I am hoping that Anand will
re-send the updated patch anyways. At that point he can also add the
changes from your feedback.


Best regards,
Martin


[0] https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20150615.pdf


From maz at kernel.org  Mon Aug 30 13:20:17 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 30 Aug 2021 21:20:17 +0100
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <CAL_JsqJC+FxiynFkkcB0amp3s4agsio5ggCrYiPbqoXroAJV4Q@mail.gmail.com>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-5-mark.kettenis@xs4all.nl>
 <87pmtvcgec.wl-maz@kernel.org>
 <CAL_JsqJC+FxiynFkkcB0amp3s4agsio5ggCrYiPbqoXroAJV4Q@mail.gmail.com>
Message-ID: <87o89ed6ri.wl-maz@kernel.org>

On Mon, 30 Aug 2021 16:57:59 +0100,
Rob Herring <robh+dt at kernel.org> wrote:
> 
> On Mon, Aug 30, 2021 at 6:37 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > I have now implemented the MSI change on the Linux driver side, and it
> > works nicely. So thumbs up from me on this front.
> >
> > I am now looking at the interrupts provided by each port:
> > (1) a bunch of port-private interrupts (link up/down...)
> > (2) INTx interrupts
> 
> So each port has an independent INTx space?

Yes.

> Is that even something PCI defines or comprehends?

Can't see why not. That's no different from having several PCI busses.
I don't think anything enforces that INTx interrupts have to be
unique across the system. As long as they are unique across a PCI
hierarchy, we should be OK.

> 
> > Given that the programming is per-port, I've implemented this as a
> > per-port interrupt controller.
> >
> > (1) is dead easy to implement, and doesn't require any DT description.
> > (2) is unfortunately exposing the limits of my DT knowledge, and I'm
> > not clear how to model it. I came up with the following:
> >
> >         port00: pci at 0,0 {
> >                 device_type = "pci";
> >                 reg = <0x0 0x0 0x0 0x0 0x0>;
> >                 reset-gpios = <&pinctrl_ap 152 0>;
> >                 max-link-speed = <2>;
> >
> >                 #address-cells = <3>;
> >                 #size-cells = <2>;
> >                 ranges;
> >
> >                 interrupt-controller;
> >                 #interrupt-cells = <1>;
> >                 interrupt-parent = <&port00>;
> >                 interrupt-map-mask = <0 0 0 7>;
> >                 interrupt-map = <0 0 0 1 &port00 0>,
> >                                 <0 0 0 2 &port00 1>,
> >                                 <0 0 0 3 &port00 2>,
> >                                 <0 0 0 4 &port00 3>;
> 
> IIRC, I don't think the DT IRQ code handles a node having both
> 'interrupt-controller' and 'interrupt-map' properties.

Indeed, and that actually explains why the damned INTx interrupts
insist on being 1-based instead of 0-based as the above mapping
attempts to describe it. Turns out I can rip the interrupt-map out and
it isn't worse.

> I think that's why some PCI host bridge nodes have child
> interrupt-controller nodes.  I don't really like that work-around,
> so if the above can be made to work, I'd be happy to see it. But the
> DT IRQ code is some ancient code for ancient platforms (PowerMacs
> being one of them).

That'd probably need some massaging. I'll have a look. I checked that
if I add something like:

		interrupts-extended = <&port02 2>;

to each port, I get the PME interrupt correctly assigned should I pass
pcie_pme=nomsi. Given that this IP is pretty limited in terms of MSIs,
every bit that can free a MSI is welcome.

I guess that it would make sense to expand this support to also match
for an interrupt-map.

> 
> >         };
> >
> > which vaguely seem to do the right thing for the devices behind root
> > ports, but doesn't seem to work for INTx generated by the root ports
> > themselves. Any clue? Alternatively, I could move it to something
> > global to the whole PCIe controller, but that doesn't seem completely
> > right.

I've investigated this one further, and it looks like the DT IRQ code
insists on trying to find the interrupt in the main pcie node instead
of in the root port itself. But of course it doesn't want to parse an
interrupt-map at that level either.

I guess that's related to the above.

> >
> > It also begs the question whether the per-port interrupt to the AIC
> > should be moved into each root port, should my per-port approach hold
> > any water.
> 
> I tend to think per-port is the right thing to do. However, the child
> nodes are PCI devices, so that creates some restrictions. Such as the
> per port registers are in the host address space, not the PCI address
> space, so we can't move the registers into the child nodes. The
> interrupts may be okay. Certainly, being an 'interrupt-controller'
> without having an 'interrupts' property for an non root interrupt
> controller is odd.

That was my own impression as well.

I guess there is no real canonical way to handle this particular
system and to fully support it, we'll have to amend the current
infrastructure. The question is: what is the least ugly way to express
this that will work reasonably across implementations (OpenBSD, Linux,
u-boot)?

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Mon Aug 30 13:40:40 2021
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 30 Aug 2021 21:40:40 +0100
Subject: [PATCH v4 4/4] arm64: apple: Add PCIe node
In-Reply-To: <56142808ad64dd79@bloch.sibelius.xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-5-mark.kettenis@xs4all.nl>
 <87pmtvcgec.wl-maz@kernel.org>
 <56142808ad64dd79@bloch.sibelius.xs4all.nl>
Message-ID: <87mtoyd5tj.wl-maz@kernel.org>

On Mon, 30 Aug 2021 15:57:02 +0100,
Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
> 
> > Date: Mon, 30 Aug 2021 12:37:31 +0100
> > From: Marc Zyngier <maz at kernel.org>
> > 
> > Hi Mark,
> 
> Hi Marc,
> 
> > On Fri, 27 Aug 2021 18:15:29 +0100,
> > Mark Kettenis <mark.kettenis at xs4all.nl> wrote:
> > > 
> > > From: Mark Kettenis <kettenis at openbsd.org>
> > > 
> > > Add node corresponding to the apcie,t8103 node in the
> > > Apple device tree for the Mac mini (M1, 2020).
> > > 
> > > Clock references and DART (IOMMU) references are left out at the
> > > moment and will be added once the appropriate bindings have been
> > > settled upon.
> > > 
> > > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > > ---
> > >  arch/arm64/boot/dts/apple/t8103.dtsi | 63 ++++++++++++++++++++++++++++
> > >  1 file changed, 63 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
> > > index 503a76fc30e6..6e4677bdef44 100644
> > > --- a/arch/arm64/boot/dts/apple/t8103.dtsi
> > > +++ b/arch/arm64/boot/dts/apple/t8103.dtsi
> > > @@ -214,5 +214,68 @@ pinctrl_smc: pinctrl at 23e820000 {
> > >  				     <AIC_IRQ 396 IRQ_TYPE_LEVEL_HIGH>,
> > >  				     <AIC_IRQ 397 IRQ_TYPE_LEVEL_HIGH>;
> > >  		};
> > > +
> > > +		pcie0: pcie at 690000000 {
> > > +			compatible = "apple,t8103-pcie", "apple,pcie";
> > > +			device_type = "pci";
> > > +
> > > +			reg = <0x6 0x90000000 0x0 0x1000000>,
> > > +			      <0x6 0x80000000 0x0 0x4000>,
> > > +			      <0x6 0x81000000 0x0 0x8000>,
> > > +			      <0x6 0x82000000 0x0 0x8000>,
> > > +			      <0x6 0x83000000 0x0 0x8000>;
> > > +			reg-names = "config", "rc", "port0", "port1", "port2";
> > > +
> > > +			interrupt-parent = <&aic>;
> > > +			interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
> > > +				     <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
> > > +
> > > +			msi-controller;
> > > +			msi-parent = <&pcie0>;
> > > +			msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
> > > +
> > > +			bus-range = <0 3>;
> > > +			#address-cells = <3>;
> > > +			#size-cells = <2>;
> > > +			ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 0x0 0x20000000>,
> > > +				 <0x02000000 0x0 0xc0000000 0x6 0xc0000000 0x0 0x40000000>;
> > > +
> > > +			pinctrl-0 = <&pcie_pins>;
> > > +			pinctrl-names = "default";
> > > +
> > > +			pci at 0,0 {
> > > +				device_type = "pci";
> > > +				reg = <0x0 0x0 0x0 0x0 0x0>;
> > > +				reset-gpios = <&pinctrl_ap 152 0>;
> > > +				max-link-speed = <2>;
> > > +
> > > +				#address-cells = <3>;
> > > +				#size-cells = <2>;
> > > +				ranges;
> > > +			};
> > > +
> > > +			pci at 1,0 {
> > > +				device_type = "pci";
> > > +				reg = <0x800 0x0 0x0 0x0 0x0>;
> > > +				reset-gpios = <&pinctrl_ap 153 0>;
> > > +				max-link-speed = <2>;
> > > +
> > > +				#address-cells = <3>;
> > > +				#size-cells = <2>;
> > > +				ranges;
> > > +			};
> > > +
> > > +			pci at 2,0 {
> > > +				device_type = "pci";
> > > +				reg = <0x1000 0x0 0x0 0x0 0x0>;
> > > +				reset-gpios = <&pinctrl_ap 33 0>;
> > > +				max-link-speed = <1>;
> > > +
> > > +				#address-cells = <3>;
> > > +				#size-cells = <2>;
> > > +				ranges;
> > > +			};
> > > +		};
> > >  	};
> > >  };
> > 
> > I have now implemented the MSI change on the Linux driver side, and it
> > works nicely. So thumbs up from me on this front.
> > 
> > I am now looking at the interrupts provided by each port:
> > (1) a bunch of port-private interrupts (link up/down...)
> > (2) INTx interrupts
> > 
> > Given that the programming is per-port, I've implemented this as a
> > per-port interrupt controller.
> > 
> > (1) is dead easy to implement, and doesn't require any DT description.
> > (2) is unfortunately exposing the limits of my DT knowledge, and I'm
> > not clear how to model it. I came up with the following:
> > 
> > 	port00: pci at 0,0 {
> > 		device_type = "pci";
> > 		reg = <0x0 0x0 0x0 0x0 0x0>;
> > 		reset-gpios = <&pinctrl_ap 152 0>;
> > 		max-link-speed = <2>;
> > 
> > 		#address-cells = <3>;
> > 		#size-cells = <2>;
> > 		ranges;
> > 
> > 		interrupt-controller;
> > 		#interrupt-cells = <1>;
> > 		interrupt-parent = <&port00>;
> > 		interrupt-map-mask = <0 0 0 7>;
> > 		interrupt-map = <0 0 0 1 &port00 0>,
> > 				<0 0 0 2 &port00 1>,
> > 				<0 0 0 3 &port00 2>,
> > 				<0 0 0 4 &port00 3>;
> > 	};
> > 
> > which vaguely seem to do the right thing for the devices behind root
> > ports, but doesn't seem to work for INTx generated by the root ports
> > themselves. Any clue? Alternatively, I could move it to something
> > global to the whole PCIe controller, but that doesn't seem completely
> > right.
> > 
> > It also begs the question whether the per-port interrupt to the AIC
> > should be moved into each root port, should my per-port approach hold
> > any water.
> 
> Must admit that I didn't entirely thinkthrough this aspect fo the
> hardware.  MSIs work just fine for the built-in hardware of the
> current generation of M1 Macs so I ignored INTx for now.

It isn't a big deal right now, but I sense that with only 32 MSIs per
PCIe block, keeping the PCIe management interrupts (PME, AER...) as
MSIs is going to waste valuable space once we have Thunderbolt up and
running (one of these days). I certainly intent to stick a PCIe/PCIe
bridge behind each of the ports, and each port is going to eat into
that as well.

> It isn't entirely clear to me what properties are "allowed" on the
> individual pci device child nodes that correspond to the ports.  But
> "interrupt-map" and "interrupt-map-mask" are certainly among the
> allowed properties, so this approach makes sense to me.  I must say I
> don't see what the issue with the INTx generated by the root ports
> themselves would be.

I think this is just a Linux shortcoming (Rob pointed out something in
his email).

> I don't think we can move the interrupt property for the AIC to the
> ports though, since that property would actually represent the
> interrupt of the PCI bridge device according to the standard PCI
> bindings and that isn't the case here.
> 
> So this makes sense to me and might not even need changing to the
> binding for the Apple PCIe controller itself.

I guess there is a great deal of ambiguity when it comes to what
interrupt maps to what, to be honest. At this stage, I don't think
that warrant a change in the current shape of the binding though.

FWIW,

Reviewed-by: Marc Zyngier <maz at kernel.org>

The current state of the Linux support is at [1]. I'll sync-up with
Alyssa later this week to have a new posting after the current merge
window.

	M.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=hack/m1-pcie-v3

-- 
Without deviation from the norm, progress is not possible.


From heiko at sntech.de  Mon Aug 30 13:45:03 2021
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 30 Aug 2021 22:45:03 +0200
Subject: [PATCH v1 1/5] phy: phy-rockchip-dphy-rx0: refactor for tx1rx1
 addition
In-Reply-To: <20210830180758.251390-2-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-2-mike.rudenko@gmail.com>
Message-ID: <6474995.6kXVAnRFRJ@diego>

Hi Mikhail,

Am Montag, 30. August 2021, 20:07:50 CEST schrieb Mikhail Rudenko:
> In order to accommodate for rk3399 tx1rx1 addition, make
> enable/disable function calls indirect via function pointers in
> rk_dphy_drv_data. Also rename rk_dphy_write and rk_dphy_enable to
> avoid naming clashes.

You're a bit too late to the party :-( .

The tx1rx1 dphy is living _inside_ the 2nd DSI controller and is
configured through it. 

So having the same peripheral in the dts with different compatibles
does break the devicetree-describes-hardware-not-Linux-implementation-details
paradigm.

Therefore my approach was to handle the switch between tx and rx modes
inside the dsi driver. This got merged for 5.15 as well, see [0] [1].

So sadly this series is somewhat obsolete, but you should find the
building blocks for camera support in linux-next already.


Regards
Heiko




[0] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=71f68fe7f12182ed968cfbbd1ef018721e4dee30
[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=68e0277204c733dff19073686e2ac48239b06fbc


> 
> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
> ---
>  drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 38 +++++++++++++-------
>  1 file changed, 25 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
> index 4df9476ef2a9..72145cdfb036 100644
> --- a/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
> +++ b/drivers/phy/rockchip/phy-rockchip-dphy-rx0.c
> @@ -138,12 +138,17 @@ static const struct dphy_reg rk3399_grf_dphy_regs[] = {
>  	[GRF_DPHY_RX0_TESTDOUT] = PHY_REG(RK3399_GRF_SOC_STATUS1, 8, 0),
>  };
>  
> +struct rk_dphy;
> +
>  struct rk_dphy_drv_data {
>  	const char * const *clks;
>  	unsigned int num_clks;
>  	const struct hsfreq_range *hsfreq_ranges;
>  	unsigned int num_hsfreq_ranges;
>  	const struct dphy_reg *regs;
> +
> +	void (*enable)(struct rk_dphy *priv);
> +	void (*disable)(struct rk_dphy *priv);
>  };
>  
>  struct rk_dphy {
> @@ -170,7 +175,7 @@ static inline void rk_dphy_write_grf(struct rk_dphy *priv,
>  	regmap_write(priv->grf, reg->offset, val);
>  }
>  
> -static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
> +static void rk_dphy_write_mipi_rx(struct rk_dphy *priv, u8 test_code, u8 test_data)
>  {
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTDIN, test_code);
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTEN, 1);
> @@ -186,7 +191,7 @@ static void rk_dphy_write(struct rk_dphy *priv, u8 test_code, u8 test_data)
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_TESTCLK, 1);
>  }
>  
> -static void rk_dphy_enable(struct rk_dphy *priv)
> +static void rk_dphy_enable_rx(struct rk_dphy *priv)
>  {
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCERXMODE, 0);
>  	rk_dphy_write_grf(priv, GRF_DPHY_RX0_FORCETXSTOPMODE, 0);
> @@ -206,22 +211,27 @@ static void rk_dphy_enable(struct rk_dphy *priv)
>  	usleep_range(100, 150);
>  
>  	/* set clock lane */
> -	/* HS hsfreq_range & lane 0  settle bypass */
> -	rk_dphy_write(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
> +	/* HS hsfreq_range & lane 0	 settle bypass */
> +	rk_dphy_write_mipi_rx(priv, CLOCK_LANE_HS_RX_CONTROL, 0);
>  	/* HS RX Control of lane0 */
> -	rk_dphy_write(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
> +	rk_dphy_write_mipi_rx(priv, LANE0_HS_RX_CONTROL, priv->hsfreq << 1);
>  	/* HS RX Control of lane1 */
> -	rk_dphy_write(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
> +	rk_dphy_write_mipi_rx(priv, LANE1_HS_RX_CONTROL, priv->hsfreq << 1);
>  	/* HS RX Control of lane2 */
> -	rk_dphy_write(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
> +	rk_dphy_write_mipi_rx(priv, LANE2_HS_RX_CONTROL, priv->hsfreq << 1);
>  	/* HS RX Control of lane3 */
> -	rk_dphy_write(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
> +	rk_dphy_write_mipi_rx(priv, LANE3_HS_RX_CONTROL, priv->hsfreq << 1);
>  	/* HS RX Data Lanes Settle State Time Control */
> -	rk_dphy_write(priv, LANES_THS_SETTLE_CONTROL,
> -		      THS_SETTLE_COUNTER_THRESHOLD);
> +	rk_dphy_write_mipi_rx(priv, LANES_THS_SETTLE_CONTROL,
> +			  THS_SETTLE_COUNTER_THRESHOLD);
>  
>  	/* Normal operation */
> -	rk_dphy_write(priv, 0x0, 0);
> +	rk_dphy_write_mipi_rx(priv, 0x0, 0);
> +}
> +
> +static void rk_dphy_disable_rx(struct rk_dphy *priv)
> +{
> +	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
>  }
>  
>  static int rk_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
> @@ -266,7 +276,7 @@ static int rk_dphy_power_on(struct phy *phy)
>  	if (ret)
>  		return ret;
>  
> -	rk_dphy_enable(priv);
> +	priv->drv_data->enable(priv);
>  
>  	return 0;
>  }
> @@ -275,7 +285,7 @@ static int rk_dphy_power_off(struct phy *phy)
>  {
>  	struct rk_dphy *priv = phy_get_drvdata(phy);
>  
> -	rk_dphy_write_grf(priv, GRF_DPHY_RX0_ENABLE, 0);
> +	priv->drv_data->disable(priv);
>  	clk_bulk_disable(priv->drv_data->num_clks, priv->clks);
>  	return 0;
>  }
> @@ -310,6 +320,8 @@ static const struct rk_dphy_drv_data rk3399_mipidphy_drv_data = {
>  	.hsfreq_ranges = rk3399_mipidphy_hsfreq_ranges,
>  	.num_hsfreq_ranges = ARRAY_SIZE(rk3399_mipidphy_hsfreq_ranges),
>  	.regs = rk3399_grf_dphy_regs,
> +	.enable = rk_dphy_enable_rx,
> +	.disable = rk_dphy_disable_rx,
>  };
>  
>  static const struct of_device_id rk_dphy_dt_ids[] = {
> 






From jernej.skrabec at gmail.com  Mon Aug 30 13:49:37 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Mon, 30 Aug 2021 22:49:37 +0200
Subject: [PATCH] arm64: dts: sun50i: h5: NanoPI Neo 2: phy-mode rgmii-id
In-Reply-To: <20210830151645.18018-1-u@pkh.me>
References: <20210830151645.18018-1-u@pkh.me>
Message-ID: <116454729.UZi3dMzWh7@jernej-laptop>

Hi!

Dne ponedeljek, 30. avgust 2021 ob 17:16:45 CEST je Cl?ment B?sch napisal(a):
> Since commit bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay
> config") network is broken on the NanoPi Neo 2.
> 
> This patch changes the phy-mode to use internal delays both for RX and
> TX as has been done for other boards affected by the same commit.
> 
> Fixes: bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay config")

This commit fixes DT issue, so "fixes" tag should be:
Fixes: 44a94c7ef989 ("arm64: dts: allwinner: H5: Restore EMAC changes")

Here, a node with wrong phy-mode property was added to NanoPi Neo 2 board DT.  

Other than that, this patch is fine and once fixes tag is fixed, you can add:
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

For next version, you should:
- change fixed tag
- add my review-by tag right above your signed-off-by tag
- mark patch as v2 (add "-v2" parameter to git format-patch)
- describe change right under "---" line

Note, if you borked something when sending, you should mark patch or patch 
series as "RESEND", so recipients don't look for changes in two subsequent e-
mails (--subject-prefix="RESEND PATCH").

Thanks for the fix!

Best regards,
Jernej

> Signed-off-by: Cl?ment B?sch <u at pkh.me>
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
> b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts index
> 02f8e72f0cad..05486cccee1c 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
> @@ -75,7 +75,7 @@ &emac {
>  	pinctrl-0 = <&emac_rgmii_pins>;
>  	phy-supply = <&reg_gmac_3v3>;
>  	phy-handle = <&ext_rgmii_phy>;
> -	phy-mode = "rgmii";
> +	phy-mode = "rgmii-id";
>  	status = "okay";
>  };






From jbx6244 at gmail.com  Mon Aug 30 14:00:17 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 30 Aug 2021 23:00:17 +0200
Subject: [PATCH v1 4/5] dt-bindings: phy: phy-rockchip-dphy-rx0: add
 support for tx1rx1 phy
In-Reply-To: <20210830180758.251390-5-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-5-mike.rudenko@gmail.com>
Message-ID: <60aa055c-d872-3e5c-3c85-09300215a60e@gmail.com>

Hi Mikhail,

Some comments below. Have a look if it is useful.

On 8/30/21 8:07 PM, Mikhail Rudenko wrote:
> RK3399 TX1RX1 D-PHY is not a child of GRF and uses reg, thus add
> corresponding properties conditionally. It also requires DSI clock to
> operate, so check for it. Since we now support both rx0 and tx1rx1,
> rename the schema to rockchip-mipi-dphy-rx.yaml.
> 
> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
> ---
>  ...hy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} | 39 +++++++++++++++++--
>  1 file changed, 35 insertions(+), 4 deletions(-)
>  rename Documentation/devicetree/bindings/phy/{rockchip-mipi-dphy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} (65%)
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml b/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
> similarity index 65%
> rename from Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml
> rename to Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
> index 7d888d358823..f42319448fc9 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx0.yaml
> +++ b/Documentation/devicetree/bindings/phy/rockchip-mipi-dphy-rx.yaml
> @@ -1,10 +1,10 @@
>  # SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>  %YAML 1.2
>  ---
> -$id: http://devicetree.org/schemas/phy/rockchip-mipi-dphy-rx0.yaml#
> +$id: http://devicetree.org/schemas/phy/rockchip-mipi-dphy-rx.yaml#
>  $schema: http://devicetree.org/meta-schemas/core.yaml#
>  
> -title: Rockchip SoC MIPI RX0 D-PHY Device Tree Bindings
> +title: Rockchip SoC MIPI RX0/TX1RX1 D-PHY Device Tree Bindings
>  
>  maintainers:
>    - Helen Koike <helen.koike at collabora.com>
> @@ -16,19 +16,28 @@ description: |
>  
>  properties:
>    compatible:
> -    const: rockchip,rk3399-mipi-dphy-rx0
> +    enum:
> +      - rockchip,rk3399-mipi-dphy-rx0
> +      - rockchip,rk3399-mipi-dphy-tx1rx1
> +

> +  reg:
> +    maxItems: 1

This allows every node to have a reg property.

>  
>    clocks:
> +    minItems: 3
>      items:
>        - description: MIPI D-PHY ref clock
> -      - description: MIPI D-PHY RX0 cfg clock
> +      - description: MIPI D-PHY RX0/TX1RX1 cfg clock
>        - description: Video in/out general register file clock
> +      - description: MIPI D-PHY DSI clock
>  
>    clock-names:
> +    minItems: 3
>      items:
>        - const: dphy-ref
>        - const: dphy-cfg
>        - const: grf
> +      - const: dsi
>  
>    '#phy-cells':
>      const: 0
> @@ -37,6 +46,12 @@ properties:
>      description: Video in/out power domain.
>      maxItems: 1
>  

> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the general register file
> +      (GRF), required for TX1RX1 MIPI D-PHY on RK3399.

This allows every node to have a rockchip,grf property.

> +
>  required:
>    - compatible
>    - clocks
> @@ -44,6 +59,22 @@ required:
>    - '#phy-cells'
>    - power-domains
>  
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +          const: rockchip,rk3399-mipi-dphy-tx1rx1
> +then:

> +  required:

Move/swap the properties section above the required section.

> +    - reg
> +    - rockchip,grf
> +
> +  properties:

  reg:
    maxItems: 1

> +    clocks:
> +      minItems: 4
> +    clock-names:
> +      minItems: 4

  rockchip,grf:
    $ref: /schemas/types.yaml#/definitions/phandle
    description:
      The phandle of the syscon node for the general register file(GRF).


", required for TX1RX1 MIPI D-PHY on RK3399."

This phrase is already said/done with the "required:" section above

>  additionalProperties: false
>  
>  examples:
> 


From jbx6244 at gmail.com  Mon Aug 30 14:12:00 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 30 Aug 2021 23:12:00 +0200
Subject: [PATCH v1 5/5] arm64: dts: rockchip: add mipi-dphy-tx1rx1 for
 rk3399
In-Reply-To: <20210830180758.251390-6-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-6-mike.rudenko@gmail.com>
Message-ID: <ac38a6ce-19f6-8d30-6070-55b78cc082e2@gmail.com>

Hi Mikhail,

On 8/30/21 8:07 PM, Mikhail Rudenko wrote:
> Add DT node for RX mode of RK3399 TX1RX1 D-PHY.
> 
> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3399.dtsi | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> index 3871c7fd83b0..2e4513275a87 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
> @@ -1902,6 +1902,21 @@ mipi1_in_vopl: endpoint at 1 {
>  		};
>  	};
>  
> +	mipi_dphy_tx1rx1: mipi-dphy-tx1rx1 at ff968000 {
> +		compatible = "rockchip,rk3399-mipi-dphy-tx1rx1";
> +		reg = <0x0 0xff968000 0x0 0x8000>;

> +		clocks = <&cru SCLK_MIPIDPHY_REF>,
> +			<&cru SCLK_DPHY_TX1RX1_CFG>,
> +			<&cru PCLK_VIO_GRF>,
> +			<&cru PCLK_MIPI_DSI1>;
> +		clock-names = "dphy-ref", "dphy-cfg",
> +			"grf", "dsi";

Could you fix the alignment a bit with extra spaces?

> +		rockchip,grf = <&grf>;
> +		power-domains = <&power RK3399_PD_VIO>;

Sort in alphabetical order.

> +		#phy-cells = <0>;
> +		status = "disabled";
> +	};
> +
>  	edp: edp at ff970000 {
>  		compatible = "rockchip,rk3399-edp";
>  		reg = <0x0 0xff970000 0x0 0x8000>;
> 


From u at pkh.me  Mon Aug 30 14:25:23 2021
From: u at pkh.me (=?utf-8?B?Q2zDqW1lbnQgQsWTc2No?=)
Date: Mon, 30 Aug 2021 23:25:23 +0200
Subject: [PATCH] arm64: dts: sun50i: h5: NanoPI Neo 2: phy-mode rgmii-id
In-Reply-To: <116454729.UZi3dMzWh7@jernej-laptop>
References: <20210830151645.18018-1-u@pkh.me>
 <116454729.UZi3dMzWh7@jernej-laptop>
Message-ID: <YS1Mwz+fT9P2qskW@ssq0.pkh.me>

On Mon, Aug 30, 2021 at 10:49:37PM +0200, Jernej ?krabec wrote:
> Hi!
> 

Hi,

> Dne ponedeljek, 30. avgust 2021 ob 17:16:45 CEST je Cl?ment B?sch napisal(a):
> > Since commit bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay
> > config") network is broken on the NanoPi Neo 2.
> > 
> > This patch changes the phy-mode to use internal delays both for RX and
> > TX as has been done for other boards affected by the same commit.
> > 
> > Fixes: bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay config")
> 
> This commit fixes DT issue, so "fixes" tag should be:
> Fixes: 44a94c7ef989 ("arm64: dts: allwinner: H5: Restore EMAC changes")
> 
> Here, a node with wrong phy-mode property was added to NanoPi Neo 2 board DT.  

Shouldn't I add it instead of replacing? I followed what I observed in
`git log --grep bbc4d71d63` where all the commits pretty much follow this
pattern: that commit is the one causing the actual observed regression,
while 44a94c7ef989 is much older, and while it's wrong, it wasn't causing
an issue in practice.

Or did I misunderstand something?

> Other than that, this patch is fine and once fixes tag is fixed, you can add:
> Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> 
> For next version, you should:
> - change fixed tag
> - add my review-by tag right above your signed-off-by tag
> - mark patch as v2 (add "-v2" parameter to git format-patch)
> - describe change right under "---" line
> 

Will do.

> Note, if you borked something when sending, you should mark patch or patch 
> series as "RESEND", so recipients don't look for changes in two subsequent e-
> mails (--subject-prefix="RESEND PATCH").

Not sure I follow you so before I disturb everyone with more noise I'd
just like to confirm: you mean a git send-email in-reply-to=[broken patch
attempt] (the one where I borked the --cc), right? But with what patch?
I'm a bit confused here.

> Thanks for the fix!

No problem; I really think a scan of all the other boards would be
meaningful though, it looks like a lot of them got fixed but there are
many other candidates and the issue feels pretty critical to me
(regression, and no network at all).

-- 
Cl?ment B.


From acme at kernel.org  Mon Aug 30 14:31:20 2021
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 30 Aug 2021 18:31:20 -0300
Subject: [PATCH v2 0/2] perf: Support compat mode for AUX ring buffer
In-Reply-To: <20210829102238.19693-1-leo.yan@linaro.org>
References: <20210829102238.19693-1-leo.yan@linaro.org>
Message-ID: <YS1OKOTMMEiAwPfj@kernel.org>

Em Sun, Aug 29, 2021 at 06:22:36PM +0800, Leo Yan escreveu:
> This patch set is to address the comments in the patch set v1 [1] and
> updates the patches.
> 
> Changes from v1:
> - Added Adrian's review tag for patch 01;
> - Refined comment in patch 01 (James);
> - Added James' review and test tag for patch 02.
> 
> [1] https://lore.kernel.org/patchwork/cover/1473936/

Thanks, applied.

- Arnaldo

 
> 
> Leo Yan (2):
>   perf auxtrace: Add compat_auxtrace_mmap__{read_head|write_tail}
>   perf auxtrace arm: Support
>     compat_auxtrace_mmap__{read_head|write_tail}
> 
>  tools/perf/arch/arm/util/auxtrace.c | 32 +++++++++++
>  tools/perf/util/auxtrace.c          | 88 +++++++++++++++++++++++++++--
>  tools/perf/util/auxtrace.h          | 22 +++++++-
>  3 files changed, 135 insertions(+), 7 deletions(-)
> 
> -- 
> 2.25.1

-- 

- Arnaldo


From ndesaulniers at google.com  Mon Aug 30 14:38:43 2021
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Mon, 30 Aug 2021 14:38:43 -0700
Subject: [PATCH] ARM: select HAVE_FUTEX_CMPXCHG
Message-ID: <20210830213846.2609349-1-ndesaulniers@google.com>

tglx notes:
  This function [futex_detect_cmpxchg] is only needed when an
  architecture has to runtime discover whether the CPU supports it or
  not.  ARM has unconditional support for this, so the obvious thing to
  do is the below.

Fixes linkage failure from Clang randconfigs:
kernel/futex.o:(.text.fixup+0x5c): relocation truncated to fit: R_ARM_JUMP24 against `.init.text'
and boot failures for CONFIG_THUMB2_KERNEL.

Link: https://github.com/ClangBuiltLinux/linux/issues/325
Reported-by: Arnd Bergmann <arnd at arndb.de>
Reported-by: Nathan Chancellor <nathan at kernel.org>
Suggested-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Nick Desaulniers <ndesaulniers at google.com>
---
 arch/arm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fc196421b2ce..b760dd45b734 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -92,6 +92,7 @@ config ARM
 	select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
 	select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG
 	select HAVE_FUNCTION_TRACER if !XIP_KERNEL
+	select HAVE_FUTEX_CMPXCHG if FUTEX
 	select HAVE_GCC_PLUGINS
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
 	select HAVE_IRQ_TIME_ACCOUNTING
-- 
2.33.0.259.gc128427fd7-goog



From helgaas at kernel.org  Mon Aug 30 14:43:17 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 30 Aug 2021 16:43:17 -0500
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared
 pcie-cfg base address
In-Reply-To: <968266ecd5889721aa234c414361bedbe66b9539.camel@mediatek.com>
Message-ID: <20210830214317.GA27606@bjorn-Precision-5520>

On Mon, Aug 30, 2021 at 03:09:44PM +0800, Chuanjia Liu wrote:
> On Fri, 2021-08-27 at 11:46 -0500, Bjorn Helgaas wrote:
> > On Mon, Aug 23, 2021 at 11:27:56AM +0800, Chuanjia Liu wrote:

> > > @@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct
> > > mtk_pcie *pcie)
> > >  			return PTR_ERR(pcie->base);
> > >  	}
> > >  
> > > +	cfg_node = of_find_compatible_node(NULL, NULL,
> > > +					   "mediatek,generic-pciecfg");
> > > +	if (cfg_node) {
> > > +		pcie->cfg = syscon_node_to_regmap(cfg_node);
> > 
> > Other drivers in drivers/pci/controller/ use
> > syscon_regmap_lookup_by_phandle() (j721e, dra7xx, keystone,
> > layerscape, artpec6) or syscon_regmap_lookup_by_compatible() (imx6,
> > kirin, v3-semi).
> > 
> > You should do it the same way unless there's a need to be different.
>
> I have used phandle, but Rob suggested to search for the node by 
> compatible.

> The reason why syscon_regmap_lookup_by_compatible() is not 
> used here is that the pciecfg node is optional, and there is no need to
> return error when the node is not searched.

How about this?

  regmap = syscon_regmap_lookup_by_compatible("mediatek,generic-pciecfg");
  if (!IS_ERR(regmap))
    pcie->cfg = regmap;


From jbx6244 at gmail.com  Mon Aug 30 14:50:21 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 30 Aug 2021 23:50:21 +0200
Subject: [PATCH v1 5/5] arm64: dts: rockchip: add mipi-dphy-tx1rx1 for
 rk3399
In-Reply-To: <ac38a6ce-19f6-8d30-6070-55b78cc082e2@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-6-mike.rudenko@gmail.com>
 <ac38a6ce-19f6-8d30-6070-55b78cc082e2@gmail.com>
Message-ID: <909ebc5f-3a9b-c793-a4fa-07429effd8c3@gmail.com>



On 8/30/21 11:12 PM, Johan Jonker wrote:
> Hi Mikhail,
> 
> On 8/30/21 8:07 PM, Mikhail Rudenko wrote:
>> Add DT node for RX mode of RK3399 TX1RX1 D-PHY.
>>
>> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
>> ---
>>  arch/arm64/boot/dts/rockchip/rk3399.dtsi | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
>> index 3871c7fd83b0..2e4513275a87 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
>> @@ -1902,6 +1902,21 @@ mipi1_in_vopl: endpoint at 1 {
>>  		};
>>  	};
>>  


>> +	mipi_dphy_tx1rx1: mipi-dphy-tx1rx1 at ff968000 {
>> +		compatible = "rockchip,rk3399-mipi-dphy-tx1rx1";



	mipi_dsi1: mipi at ff968000 {
		compatible = "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi";
		reg = <0x0 0xff968000 0x0 0x8000>;

Sorry, there's already a node in mainline. Excuse...
See Heiko's comment.


>> +		reg = <0x0 0xff968000 0x0 0x8000>;
> 
>> +		clocks = <&cru SCLK_MIPIDPHY_REF>,
>> +			<&cru SCLK_DPHY_TX1RX1_CFG>,
>> +			<&cru PCLK_VIO_GRF>,
>> +			<&cru PCLK_MIPI_DSI1>;
>> +		clock-names = "dphy-ref", "dphy-cfg",
>> +			"grf", "dsi";
> 
> Could you fix the alignment a bit with extra spaces?
> 
>> +		rockchip,grf = <&grf>;
>> +		power-domains = <&power RK3399_PD_VIO>;
> 
> Sort in alphabetical order.
> 
>> +		#phy-cells = <0>;
>> +		status = "disabled";
>> +	};
>> +
>>  	edp: edp at ff970000 {
>>  		compatible = "rockchip,rk3399-edp";
>>  		reg = <0x0 0xff970000 0x0 0x8000>;
>>


From andrew at lunn.ch  Mon Aug 30 14:50:42 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 30 Aug 2021 23:50:42 +0200
Subject: [PATCH] arm64: dts: sun50i: h5: NanoPI Neo 2: phy-mode rgmii-id
In-Reply-To: <116454729.UZi3dMzWh7@jernej-laptop>
References: <20210830151645.18018-1-u@pkh.me>
 <116454729.UZi3dMzWh7@jernej-laptop>
Message-ID: <YS1SsqDgGFOvyIT0@lunn.ch>

On Mon, Aug 30, 2021 at 10:49:37PM +0200, Jernej ?krabec wrote:
> Hi!
> 
> Dne ponedeljek, 30. avgust 2021 ob 17:16:45 CEST je Cl?ment B?sch napisal(a):
> > Since commit bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay
> > config") network is broken on the NanoPi Neo 2.
> > 
> > This patch changes the phy-mode to use internal delays both for RX and
> > TX as has been done for other boards affected by the same commit.
> > 
> > Fixes: bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay config")
> 
> This commit fixes DT issue, so "fixes" tag should be:
> Fixes: 44a94c7ef989 ("arm64: dts: allwinner: H5: Restore EMAC changes")
> 
> Here, a node with wrong phy-mode property was added to NanoPi Neo 2 board DT.  

Hi Jernej

I would say, it is debatable. The board broke when the driver started
acting on the value, which is commit bbc4d71d6354. It could be argued
it was always technically broken, since it has the wrong value, but
practically, it was not broken. One of the rules for stable is:

 - It must fix a real bug that bothers people (not a, "This could be a
   problem..." type thing).

So i would argue, anything before bbc4d71d6354 does not fulfil stable
requirements, since it does not bother anybody.

      Andrew


From andrew at lunn.ch  Mon Aug 30 14:52:05 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 30 Aug 2021 23:52:05 +0200
Subject: [PATCH] arm64: dts: sun50i: h5: NanoPI Neo 2: phy-mode rgmii-id
In-Reply-To: <20210830151645.18018-1-u@pkh.me>
References: <20210830151645.18018-1-u@pkh.me>
Message-ID: <YS1TBT8WW1MFemyf@lunn.ch>

On Mon, Aug 30, 2021 at 05:16:45PM +0200, Cl?ment B?sch wrote:
> Since commit bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay
> config") network is broken on the NanoPi Neo 2.
> 
> This patch changes the phy-mode to use internal delays both for RX and
> TX as has been done for other boards affected by the same commit.
> 
> Fixes: bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay config")
> Signed-off-by: Cl?ment B?sch <u at pkh.me>

Cc: stable at vger.kernel.org
Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From robh at kernel.org  Mon Aug 30 14:56:04 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 16:56:04 -0500
Subject: [PATCH] ARM: dts: bcm2711-rpi-4-b: Fix pcie0's unit address
In-Reply-To: <22bbfdefb2b9a1a65a807d0aecee67e607b7ff60.camel@redhat.com>
References: <20210830103909.323356-1-nsaenzju@redhat.com>
 <YSzfoyesEzAuLkSS@robh.at.kernel.org>
 <22bbfdefb2b9a1a65a807d0aecee67e607b7ff60.camel@redhat.com>
Message-ID: <CAL_JsqJgf3SD51+_J=oNAOvMc9PmFNmuaVrisKkGV++JUzBwew@mail.gmail.com>

On Mon, Aug 30, 2021 at 11:45 AM <nsaenzju at redhat.com> wrote:
>
> On Mon, 2021-08-30 at 08:39 -0500, Rob Herring wrote:
> > On Mon, Aug 30, 2021 at 12:39:09PM +0200, Nicolas Saenz Julienne wrote:
> > > dtbs_check currently complains that:
> > >
> > > arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning
> > > (pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format
> > > error, expected "0,0"
> > >
> > > Unsurprisingly pci at 0,0 is the right address, as illustrated by its reg
> > > property:
> > >
> > >     &pcie0 {
> > >             pci at 0,0 {
> > >                     /*
> > >                      * As defined in the IEEE Std 1275-1994 document,
> > >                      * reg is a five-cell address encoded as (phys.hi
> > >                      * phys.mid phys.lo size.hi size.lo). phys.hi
> > >                      * should contain the device's BDF as 0b00000000
> > >                      * bbbbbbbb dddddfff 00000000. The other cells
> > >                      * should be zero.
> > >                      */
> > >                     reg = <0 0 0 0 0>;
> > >             };
> > >     };
> > >
> > > The bus is clearly 0. So fix it.
> >
> > s/bus/device/
> >
> > The unit-address format is '<device>,<function>' (and function is
> > optional). The bus number is not part of the unit-address because that
> > is dynamic and then the path would not be fixed/known. The bus is part
> > of 'reg' for true OpenFirmware, but for FDT I think it should always be
> > 0 as the DT is static.
> >
> > Looks like the child node is wrong (both unit-address and reg) as well:
> >
> >                 usb at 1,0 {
> >                         reg = <0x10000 0 0 0 0>;
> >                         resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
> >                 };
> >
> > It doesn't warn because the bridge node is also missing 'device_type =
> > "pci";'.
> >
> > This is all fairly hard to get right (see recent hikey970 patches for a
> > complex example). I'm thinking about writing a tool that generates a DT
> > with PCI nodes by reading the PCI hierachy from sysfs.
>
> Just to double-check I understood everything, with:
>
>         lspci -D -PP
>         0000:00:00.0 PCI bridge: Broadcom Inc. and subsidiaries BCM2711 PCIe Bridge (rev 10)
>         0000:00:00.0/01:00.0 USB controller: VIA Technologies, Inc. VL805/806 xHCI USB 3.0 Controller (rev 01)
>
> It should look like this:
>
>         &pcie0 {
>                 pci at 0,0 {
>                         device_type = "pci";
>                         #address-cells = <3>;
>                         #size-cells = <2>;
>                         ranges;
>
>                         reg = <0 0 0 0 0>;
>
>                         usb at 0,0 {
>                                 reg = <0 0 0 0 0>;
>                                 resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
>                         };
>                 };
>         };

Yes, that looks correct.

Rob


From jbx6244 at gmail.com  Mon Aug 30 15:06:46 2021
From: jbx6244 at gmail.com (Johan Jonker)
Date: Tue, 31 Aug 2021 00:06:46 +0200
Subject: [PATCH v1 4/5] dt-bindings: phy: phy-rockchip-dphy-rx0: add
 support for tx1rx1 phy
In-Reply-To: <60aa055c-d872-3e5c-3c85-09300215a60e@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-5-mike.rudenko@gmail.com>
 <60aa055c-d872-3e5c-3c85-09300215a60e@gmail.com>
Message-ID: <a9ce814a-d23e-2f5d-0299-4ffbb76609da@gmail.com>

Hi Mikhail,

The file in the link below is in need for a YAML conversion.
Could you help?

Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt

- compatible: one of
	"rockchip,px30-mipi-dsi", "snps,dw-mipi-dsi"
	"rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"
	"rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi"

On 8/30/21 11:00 PM, Johan Jonker wrote:

> Some comments below. Have a look if it is useful.
> 


From tharvey at gateworks.com  Mon Aug 30 15:06:53 2021
From: tharvey at gateworks.com (Tim Harvey)
Date: Mon, 30 Aug 2021 15:06:53 -0700
Subject: [PATCH v2 00/18] i.MX8MM GPC improvements and BLK_CTRL driver
In-Reply-To: <8ea33d97fb3f7abb2d80b11db28cce8c01932a09.camel@pengutronix.de>
References: <20210716232916.3572966-1-l.stach@pengutronix.de>
 <20210721204703.1424034-1-l.stach@pengutronix.de>
 <818b52fe-8fa6-b47a-6dde-783ac378c603@kontron.de>
 <8de1cd0a-4d91-60e2-61e6-9f903bbf546b@kontron.de>
 <8ea33d97fb3f7abb2d80b11db28cce8c01932a09.camel@pengutronix.de>
Message-ID: <CAJ+vNU2tSh-0TuaAZ-_Hkg3K5fudc3U77tAtcRaja-GLzXsYPQ@mail.gmail.com>

On Mon, Aug 9, 2021 at 4:01 AM Lucas Stach <l.stach at pengutronix.de> wrote:
>
> Hi Frieder,
>
> Am Donnerstag, dem 05.08.2021 um 20:56 +0200 schrieb Frieder Schrempf:
> > On 05.08.21 12:18, Frieder Schrempf wrote:
> > > On 21.07.21 22:46, Lucas Stach wrote:
> > > > Hi all,
> > > >
> > > > second revision of the GPC improvements and BLK_CTRL driver to make use
> > > > of all the power-domains on the i.MX8MM. I'm not going to repeat the full
> > > > blurb from the v1 cover letter here, but if you are not familiar with
> > > > i.MX8MM power domains, it may be worth a read.
> > > >
> > > > This 2nd revision fixes the DT bindings to be valid yaml, some small
> > > > failure path issues and most importantly the interaction with system
> > > > suspend/resume. With the previous version some of the power domains
> > > > would not come up correctly after a suspend/resume cycle.
> > > >
> > > > Updated testing git trees here, disclaimer still applies:
> > > > https://git.pengutronix.de/cgit/lst/linux/log/?h=imx8m-power-domains
> > > > https://git.pengutronix.de/cgit/lst/linux/log/?h=imx8m-power-domains-testing
> > >
> > > I finally did some tests on my side using USB, GPU and DSI (no PCIe, VPU, CSI so far) and the results are promising. Thanks for the effort!
> > >
> > > I will try to run some more automated suspend/resume and reboot test cycles over the weekend and report the results here afterwards.
> > >
> >
> > Unfortunately I got some results sooner than I had hoped. I set up a simple loop to suspend/resume every few seconds and on the first run it took around 2-3 hours for the device to lock up on resume. On the second run it took less than half an hour. I had glmark2-es2-drm running in the background, but it looks like it crashed at some point before the lockup occurred.
> >
> > Of course this could also be unrelated and caused by some peripheral driver or something but the first suspicion is definitely the power domains.
> >
> > If you have any suggestions for which debug options to enable or where to add some printks, please let me know. If I do another run I would like to make sure that the resulting logs are helpful for debugging.
> >
> > And I would appreciate if someone else could try to reproduce this problem on his/her side. I use this simple script for testing:
> >
> > #!/bin/sh
> >
> > glmark2-es2-drm &
> >
> > while true;
> > do
> >     echo +10 > /sys/class/rtc/rtc0/wakealarm
> >     echo mem > /sys/power/state
> >     sleep 5
> > done;
>
> Hm, that's unfortunate.
>
> I'm back from a two week vacation, but it looks like I won't have much
> time available to look into this issue soon. It would be very helpful
> if you could try to pinpoint the hang a bit more.  If you can reproduce
> the hang with no_console_suspend you might be able to extract a bit
> more info in which stage the hang happens (suspend, resume, TF-A, etc.)
> If the hang is in the kernel you might be able to add some prints to
> the suspend/resume paths to be able to track down the exact point of
> the hang.
>
> I'm happy to look into the issue once it's better known where to look,
> but I fear that I won't have time to do the above investigation myself
> short term. Frieder, is this something you could help with over the
> next few days?
>

Lucas / Frieder,

Can you update us on where you are at with this patch series? I fear
we are going to go through another kernel release without IMX8MM
blk-ctl support and all the things that depend on it such as
USB/PCI/DSI/CSI/GPU/VPU. If there is some specific testing you need
please let me know what I can do to help. I have a variety of IMX8MM
hardware but not a lot of time or knowledge with regards to
troubleshooting suspend/resume issues.

Are the issues found a regression?

Best regards,

Tim


From tglx at linutronix.de  Mon Aug 30 16:17:45 2021
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 31 Aug 2021 01:17:45 +0200
Subject: [PATCH] ARM: select HAVE_FUTEX_CMPXCHG
In-Reply-To: <20210830213846.2609349-1-ndesaulniers@google.com>
References: <20210830213846.2609349-1-ndesaulniers@google.com>
Message-ID: <87czpufrom.ffs@tglx>

On Mon, Aug 30 2021 at 14:38, Nick Desaulniers wrote:

> tglx notes:
>   This function [futex_detect_cmpxchg] is only needed when an
>   architecture has to runtime discover whether the CPU supports it or
>   not.  ARM has unconditional support for this, so the obvious thing to
>   do is the below.
>
> Fixes linkage failure from Clang randconfigs:
> kernel/futex.o:(.text.fixup+0x5c): relocation truncated to fit: R_ARM_JUMP24 against `.init.text'
> and boot failures for CONFIG_THUMB2_KERNEL.
>
> Link: https://github.com/ClangBuiltLinux/linux/issues/325
> Reported-by: Arnd Bergmann <arnd at arndb.de>
> Reported-by: Nathan Chancellor <nathan at kernel.org>
> Suggested-by: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Nick Desaulniers <ndesaulniers at google.com>

Reviewed-by: Thomas Gleixner <tglx at linutronix.de>


From nathan at kernel.org  Mon Aug 30 16:31:46 2021
From: nathan at kernel.org (Nathan Chancellor)
Date: Mon, 30 Aug 2021 16:31:46 -0700
Subject: [PATCH] ARM: select HAVE_FUTEX_CMPXCHG
In-Reply-To: <20210830213846.2609349-1-ndesaulniers@google.com>
References: <20210830213846.2609349-1-ndesaulniers@google.com>
Message-ID: <YS1qYuZ5nM/AQeSh@Ryzen-9-3900X.localdomain>

On Mon, Aug 30, 2021 at 02:38:43PM -0700, Nick Desaulniers wrote:
> tglx notes:
>   This function [futex_detect_cmpxchg] is only needed when an
>   architecture has to runtime discover whether the CPU supports it or
>   not.  ARM has unconditional support for this, so the obvious thing to
>   do is the below.
> 
> Fixes linkage failure from Clang randconfigs:
> kernel/futex.o:(.text.fixup+0x5c): relocation truncated to fit: R_ARM_JUMP24 against `.init.text'
> and boot failures for CONFIG_THUMB2_KERNEL.
> 
> Link: https://github.com/ClangBuiltLinux/linux/issues/325
> Reported-by: Arnd Bergmann <arnd at arndb.de>
> Reported-by: Nathan Chancellor <nathan at kernel.org>
> Suggested-by: Thomas Gleixner <tglx at linutronix.de>
> Signed-off-by: Nick Desaulniers <ndesaulniers at google.com>

Tested-by: Nathan Chancellor <nathan at kernel.org>

> ---
>  arch/arm/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index fc196421b2ce..b760dd45b734 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -92,6 +92,7 @@ config ARM
>  	select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
>  	select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG
>  	select HAVE_FUNCTION_TRACER if !XIP_KERNEL
> +	select HAVE_FUTEX_CMPXCHG if FUTEX
>  	select HAVE_GCC_PLUGINS
>  	select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
>  	select HAVE_IRQ_TIME_ACCOUNTING
> -- 
> 2.33.0.259.gc128427fd7-goog


From robh at kernel.org  Mon Aug 30 17:03:53 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 19:03:53 -0500
Subject: [PATCH v1 4/5] dt-bindings: phy: phy-rockchip-dphy-rx0: add
 support for tx1rx1 phy
In-Reply-To: <20210830180758.251390-5-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-5-mike.rudenko@gmail.com>
Message-ID: <1630368233.493531.2940839.nullmailer@robh.at.kernel.org>

On Mon, 30 Aug 2021 21:07:53 +0300, Mikhail Rudenko wrote:
> RK3399 TX1RX1 D-PHY is not a child of GRF and uses reg, thus add
> corresponding properties conditionally. It also requires DSI clock to
> operate, so check for it. Since we now support both rx0 and tx1rx1,
> rename the schema to rockchip-mipi-dphy-rx.yaml.
> 
> Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
> ---
>  ...hy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} | 39 +++++++++++++++++--
>  1 file changed, 35 insertions(+), 4 deletions(-)
>  rename Documentation/devicetree/bindings/phy/{rockchip-mipi-dphy-rx0.yaml => rockchip-mipi-dphy-rx.yaml} (65%)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/phy/rockchip-mipi-dphy-rx0.yaml'
xargs: dt-doc-validate: exited with status 255; aborting
make[1]: *** Deleting file 'Documentation/devicetree/bindings/soc/rockchip/grf.example.dt.yaml'
Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/phy/rockchip-mipi-dphy-rx0.yaml'
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/soc/rockchip/grf.example.dt.yaml] Error 255
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1522296

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Mon Aug 30 17:03:53 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 19:03:53 -0500
Subject: [PATCH 4/6] dt-bindings: iio: adc: Add the binding documentation
 for NXP IMX8QXP ADC
In-Reply-To: <20210830172140.414-5-caihuoqing@baidu.com>
References: <20210830172140.414-1-caihuoqing@baidu.com>
 <20210830172140.414-5-caihuoqing@baidu.com>
Message-ID: <1630368233.478982.2940836.nullmailer@robh.at.kernel.org>

On Tue, 31 Aug 2021 01:21:38 +0800, Cai Huoqing wrote:
> The NXP i.MX 8QuadXPlus SOC has a new ADC IP, so add the binding
> documentation for NXP IMX8QXP ADC
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> ---
>  .../bindings/iio/adc/nxp,imx8qxp-adc.yaml     | 85 +++++++++++++++++++
>  1 file changed, 85 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
make[1]: *** Deleting file 'Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.example.dts'
Traceback (most recent call last):
  File "/usr/local/bin/dt-extract-example", line 45, in <module>
    binding = yaml.load(open(args.yamlfile, encoding='utf-8').read())
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/main.py", line 434, in load
    return constructor.get_single_data()
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 120, in get_single_data
    node = self.composer.get_single_node()
  File "_ruamel_yaml.pyx", line 706, in _ruamel_yaml.CParser.get_single_node
  File "_ruamel_yaml.pyx", line 724, in _ruamel_yaml.CParser._compose_document
  File "_ruamel_yaml.pyx", line 775, in _ruamel_yaml.CParser._compose_node
  File "_ruamel_yaml.pyx", line 889, in _ruamel_yaml.CParser._compose_mapping_node
  File "_ruamel_yaml.pyx", line 773, in _ruamel_yaml.CParser._compose_node
  File "_ruamel_yaml.pyx", line 848, in _ruamel_yaml.CParser._compose_sequence_node
  File "_ruamel_yaml.pyx", line 904, in _ruamel_yaml.CParser._parse_next_event
ruamel.yaml.scanner.ScannerError: while scanning a block scalar
  in "<unicode string>", line 65, column 5
found a tab character where an indentation space is expected
  in "<unicode string>", line 71, column 1
make[1]: *** [Documentation/devicetree/bindings/Makefile:20: Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.example.dts] Error 1
make[1]: *** Waiting for unfinished jobs....
./Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml:  while scanning a block scalar
  in "<unicode string>", line 65, column 5
found a tab character where an indentation space is expected
  in "<unicode string>", line 71, column 1
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml: ignoring, error parsing file
warning: no schema found in file: ./Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
make: *** [Makefile:1419: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1522287

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Mon Aug 30 17:19:31 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 30 Aug 2021 19:19:31 -0500
Subject: [PATCH v2 1/3] dt-bindings: PCI: imx6: convert the imx pcie
 controller to dtschema
In-Reply-To: <1630046580-19282-2-git-send-email-hongxing.zhu@nxp.com>
References: <1630046580-19282-1-git-send-email-hongxing.zhu@nxp.com>
 <1630046580-19282-2-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <YS11k+IhBra3+C5g@robh.at.kernel.org>

On Fri, 27 Aug 2021 14:42:58 +0800, Richard Zhu wrote:
> Convert the fsl,imx6q-pcie.txt into a schema.
> - ranges property should be grouped by region, with no functional
>   changes.
> - only one propert is allowed in the compatible string, remove
>   "snps,dw-pcie".
> 
> Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
> ---
>  .../bindings/pci/fsl,imx6q-pcie.txt           | 100 ---------
>  .../bindings/pci/fsl,imx6q-pcie.yaml          | 202 ++++++++++++++++++
>  MAINTAINERS                                   |   2 +-
>  3 files changed, 203 insertions(+), 101 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
>  create mode 100644 Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
> 

Applied, thanks!


From iwamatsu at nigauri.org  Mon Aug 30 17:28:52 2021
From: iwamatsu at nigauri.org (Nobuhiro Iwamatsu)
Date: Tue, 31 Aug 2021 09:28:52 +0900
Subject: [PATCH v4 2/3] rtc: Add support for the MSTAR MSC313 RTC
In-Reply-To: <20210823171613.18941-3-romain.perier@gmail.com>
References: <20210823171613.18941-1-romain.perier@gmail.com>
 <20210823171613.18941-3-romain.perier@gmail.com>
Message-ID: <CABMQnVLxJ6_ZshFZVC7rxAg+xVv_06XyxxvsOUmkopG9X0A4kA@mail.gmail.com>

Hello,

2021?8?24?(?) 2:16 Romain Perier <romain.perier at gmail.com>:
>
> From: Daniel Palmer <daniel at 0x0f.com>
>
> This adds support for the RTC block on the Mstar MSC313e SoCs and newer.
>
> Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
> Co-developed-by: Romain Perier <romain.perier at gmail.com>
> Signed-off-by: Romain Perier <romain.perier at gmail.com>
> ---
>  MAINTAINERS              |   1 +
>  drivers/rtc/Kconfig      |  10 ++
>  drivers/rtc/Makefile     |   1 +
>  drivers/rtc/rtc-msc313.c | 258 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 270 insertions(+)
>  create mode 100644 drivers/rtc/rtc-msc313.c

Reviewed-by: Nobuhiro Iwamatsu <iwamatsu at nigauri.org>

Best regards,
  Nobuhiro

>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fd25e4ecf0b9..ebacdd5e8878 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2220,6 +2220,7 @@ F:        arch/arm/boot/dts/mstar-*
>  F:     arch/arm/mach-mstar/
>  F:     drivers/clk/mstar/
>  F:     drivers/gpio/gpio-msc313.c
> +F:     drivers/rtc/rtc-msc313.c
>  F:     drivers/watchdog/msc313e_wdt.c
>  F:     include/dt-bindings/clock/mstar-*
>  F:     include/dt-bindings/gpio/msc313-gpio.h
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 12153d5801ce..9ce4baab5fcf 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1925,4 +1925,14 @@ config RTC_DRV_WILCO_EC
>           This can also be built as a module. If so, the module will
>           be named "rtc_wilco_ec".
>
> +config RTC_DRV_MSC313
> +       tristate "MStar MSC313 RTC"
> +        depends on ARCH_MSTARV7 || COMPILE_TEST
> +       help
> +         If you say yes here you get support for the Mstar MSC313e On-Chip
> +         Real Time Clock.
> +
> +         This driver can also be built as a module, if so, the module
> +         will be called "rtc-msc313".
> +
>  endif # RTC_CLASS
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 2dd0dd956b0e..5efda8a60cee 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -101,6 +101,7 @@ obj-$(CONFIG_RTC_DRV_MCP795)        += rtc-mcp795.o
>  obj-$(CONFIG_RTC_DRV_MESON)    += rtc-meson.o
>  obj-$(CONFIG_RTC_DRV_MOXART)   += rtc-moxart.o
>  obj-$(CONFIG_RTC_DRV_MPC5121)  += rtc-mpc5121.o
> +obj-$(CONFIG_RTC_DRV_MSC313)   += rtc-msc313.o
>  obj-$(CONFIG_RTC_DRV_MSM6242)  += rtc-msm6242.o
>  obj-$(CONFIG_RTC_DRV_MT2712)   += rtc-mt2712.o
>  obj-$(CONFIG_RTC_DRV_MT6397)   += rtc-mt6397.o
> diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c
> new file mode 100644
> index 000000000000..f493ca5f181b
> --- /dev/null
> +++ b/drivers/rtc/rtc-msc313.c
> @@ -0,0 +1,258 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.
> + * Based on "Real Time Clock driver for msb252x." that was contained
> + * in various MStar kernels.
> + *
> + * (C) 2019 Daniel Palmer
> + * (C) 2021 Romain Perier
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/platform_device.h>
> +#include <linux/rtc.h>
> +
> +/* Registers */
> +#define REG_RTC_CTRL           0x00
> +#define REG_RTC_FREQ_CW_L      0x04
> +#define REG_RTC_FREQ_CW_H      0x08
> +#define REG_RTC_LOAD_VAL_L     0x0C
> +#define REG_RTC_LOAD_VAL_H     0x10
> +#define REG_RTC_MATCH_VAL_L    0x14
> +#define REG_RTC_MATCH_VAL_H    0x18
> +#define REG_RTC_STATUS_INT     0x1C
> +#define REG_RTC_CNT_VAL_L      0x20
> +#define REG_RTC_CNT_VAL_H      0x24
> +
> +/* Control bits for REG_RTC_CTRL */
> +#define SOFT_RSTZ_BIT          BIT(0)
> +#define CNT_EN_BIT             BIT(1)
> +#define WRAP_EN_BIT            BIT(2)
> +#define LOAD_EN_BIT            BIT(3)
> +#define READ_EN_BIT            BIT(4)
> +#define INT_MASK_BIT           BIT(5)
> +#define INT_FORCE_BIT          BIT(6)
> +#define INT_CLEAR_BIT          BIT(7)
> +
> +/* Control bits for REG_RTC_STATUS_INT */
> +#define RAW_INT_BIT            BIT(0)
> +#define ALM_INT_BIT            BIT(1)
> +
> +struct msc313_rtc {
> +       struct rtc_device *rtc_dev;
> +       void __iomem *rtc_base;
> +};
> +
> +static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       unsigned long seconds;
> +
> +       seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)
> +                       | (readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);
> +
> +       rtc_time64_to_tm(seconds, &alarm->time);
> +
> +       if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))
> +               alarm->enabled = 1;
> +
> +       return 0;
> +}
> +
> +static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       u16 reg;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       if (enabled)
> +               reg &= ~INT_MASK_BIT;
> +       else
> +               reg |= INT_MASK_BIT;
> +       writew(reg, priv->rtc_base + REG_RTC_CTRL);
> +       return 0;
> +}
> +
> +static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       unsigned long seconds;
> +
> +       seconds = rtc_tm_to_time64(&alarm->time);
> +       writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);
> +       writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);
> +
> +       msc313_rtc_alarm_irq_enable(dev, alarm->enabled);
> +
> +       return 0;
> +}
> +
> +static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)
> +{
> +       return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;
> +}
> +
> +static void msc313_rtc_set_enabled(struct msc313_rtc *priv)
> +{
> +       u16 reg;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       reg |= CNT_EN_BIT;
> +       writew(reg, priv->rtc_base + REG_RTC_CTRL);
> +}
> +
> +static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       u32 seconds;
> +       u16 reg;
> +
> +       if (!msc313_rtc_get_enabled(priv))
> +               return -EINVAL;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
> +
> +       /* Wait for HW latch done */
> +       while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)
> +               udelay(1);
> +
> +       seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)
> +                       | (readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);
> +
> +       rtc_time64_to_tm(seconds, tm);
> +
> +       return 0;
> +}
> +
> +static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev);
> +       unsigned long seconds;
> +       u16 reg;
> +
> +       seconds = rtc_tm_to_time64(tm);
> +       writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);
> +       writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);
> +
> +       /* Enable load for loading value into internal RTC counter */
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
> +
> +       /* Wait for HW latch done */
> +       while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
> +               udelay(1);
> +       msc313_rtc_set_enabled(priv);
> +       return 0;
> +}
> +
> +static const struct rtc_class_ops msc313_rtc_ops = {
> +       .read_time = msc313_rtc_read_time,
> +       .set_time = msc313_rtc_set_time,
> +       .read_alarm = msc313_rtc_read_alarm,
> +       .set_alarm = msc313_rtc_set_alarm,
> +       .alarm_irq_enable = msc313_rtc_alarm_irq_enable,
> +};
> +
> +static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)
> +{
> +       struct msc313_rtc *priv = dev_get_drvdata(dev_id);
> +       u16 reg;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);
> +       if (!(reg & ALM_INT_BIT))
> +               return IRQ_NONE;
> +
> +       reg = readw(priv->rtc_base + REG_RTC_CTRL);
> +       reg |= INT_CLEAR_BIT;
> +       reg &= ~INT_FORCE_BIT;
> +       writew(reg, priv->rtc_base + REG_RTC_CTRL);
> +
> +       rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int msc313_rtc_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct msc313_rtc *priv;
> +       unsigned long rate;
> +       struct clk *clk;
> +       int ret;
> +       int irq;
> +
> +       priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(priv->rtc_base))
> +               return PTR_ERR(priv->rtc_base);
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (irq < 0)
> +               return -EINVAL;
> +
> +       priv->rtc_dev = devm_rtc_allocate_device(dev);
> +       if (IS_ERR(priv->rtc_dev))
> +               return PTR_ERR(priv->rtc_dev);
> +
> +       priv->rtc_dev->ops = &msc313_rtc_ops;
> +       priv->rtc_dev->range_max = U32_MAX;
> +
> +       ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
> +                              dev_name(&pdev->dev), &pdev->dev);
> +       if (ret) {
> +               dev_err(dev, "Could not request IRQ\n");
> +               return ret;
> +       }
> +
> +       clk = devm_clk_get(dev, NULL);
> +       if (IS_ERR(clk)) {
> +               dev_err(dev, "No input reference clock\n");
> +               return PTR_ERR(clk);
> +       }
> +
> +       ret = clk_prepare_enable(clk);
> +       if (ret) {
> +               dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
> +               return ret;
> +       }
> +
> +       ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, clk);
> +       if (ret)
> +               return ret;
> +
> +       rate = clk_get_rate(clk);
> +       writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
> +       writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
> +
> +       platform_set_drvdata(pdev, priv);
> +
> +       return devm_rtc_register_device(priv->rtc_dev);
> +}
> +
> +static const struct of_device_id msc313_rtc_of_match_table[] = {
> +       { .compatible = "mstar,msc313-rtc" },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, msc313_rtc_of_match_table);
> +
> +static struct platform_driver msc313_rtc_driver = {
> +       .probe = msc313_rtc_probe,
> +       .driver = {
> +               .name = "msc313-rtc",
> +               .of_match_table = msc313_rtc_of_match_table,
> +       },
> +};
> +
> +module_platform_driver(msc313_rtc_driver);
> +
> +MODULE_AUTHOR("Daniel Palmer <daniel at thingy.jp>");
> +MODULE_AUTHOR("Romain Perier <romain.perier at gmail.com>");
> +MODULE_DESCRIPTION("MStar RTC Driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.30.2
>


-- 
Nobuhiro Iwamatsu
   iwamatsu at {nigauri.org / debian.org}
   GPG ID: 40AD1FA6


From ezequiel at vanguardiasur.com.ar  Mon Aug 30 17:41:36 2021
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 30 Aug 2021 21:41:36 -0300
Subject: [PATCH v1 1/5] phy: phy-rockchip-dphy-rx0: refactor for tx1rx1
 addition
In-Reply-To: <6474995.6kXVAnRFRJ@diego>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
 <20210830180758.251390-2-mike.rudenko@gmail.com> <6474995.6kXVAnRFRJ@diego>
Message-ID: <CAAEAJfB6FBbeEPuzirP2nuU_J9nLFSrczgXYVfNQUZbEJrbc7Q@mail.gmail.com>

Hi Heiko,

On Mon, 30 Aug 2021 at 17:46, Heiko St?bner <heiko at sntech.de> wrote:
>
> Hi Mikhail,
>
> Am Montag, 30. August 2021, 20:07:50 CEST schrieb Mikhail Rudenko:
> > In order to accommodate for rk3399 tx1rx1 addition, make
> > enable/disable function calls indirect via function pointers in
> > rk_dphy_drv_data. Also rename rk_dphy_write and rk_dphy_enable to
> > avoid naming clashes.
>
> You're a bit too late to the party :-( .
>
> The tx1rx1 dphy is living _inside_ the 2nd DSI controller and is
> configured through it.
>

Would you be so kind to push a patch adding some comments to
drivers/phy/rockchip/phy-rockchip-dphy-rx0.c with this information?

Thanks,
Ezequiel


From zhaoxiao at uniontech.com  Mon Aug 30 18:25:23 2021
From: zhaoxiao at uniontech.com (zhaoxiao)
Date: Tue, 31 Aug 2021 09:25:23 +0800
Subject: [PATCH v3] stmmac: dwmac-loongson: change the pr_info() to dev_err()
 in loongson_dwmac_probe()
Message-ID: <20210831012523.2691-1-zhaoxiao@uniontech.com>

Change the pr_info to dev_err.

Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
---
v3:Remove the redundant blank line.
 drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
index 4c9a37dd0d3f..f03f25d9adb0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
@@ -54,14 +54,13 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 	bool mdio = false;
 
 	np = dev_of_node(&pdev->dev);
-
 	if (!np) {
-		pr_info("dwmac_loongson_pci: No OF node\n");
+		dev_err(&pdev->dev, "dwmac_loongson_pci: No OF node\n");
 		return -ENODEV;
 	}
 
 	if (!of_device_is_compatible(np, "loongson, pci-gmac")) {
-		pr_info("dwmac_loongson_pci: Incompatible OF node\n");
+		dev_err(&pdev->dev, "dwmac_loongson_pci: Incompatible OF node\n");
 		return -ENODEV;
 	}
 
-- 
2.20.1





From trevor.wu at mediatek.com  Mon Aug 30 19:13:03 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Tue, 31 Aug 2021 10:13:03 +0800
Subject: [PATCH] ASoC: mediatek: mt8195: add MTK_PMIC_WRAP dependency
Message-ID: <20210831021303.5230-1-trevor.wu@mediatek.com>

randconfig builds show the warning below,

WARNING: unmet direct dependencies detected for SND_SOC_MT6359
   Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && MTK_PMIC_WRAP [=n]
   Selected by [y]:
   - SND_SOC_MT8195_MT6359_RT1019_RT5682 [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && I2C [=y] && SND_SOC_MT8195 [=y]

Add a dependency to avoid it.

Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
Reported-by: Randy Dunlap <rdunlap at infradead.org>
---
 sound/soc/mediatek/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index cf567a89f421..f6bf0f9c91e3 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -197,7 +197,7 @@ config SND_SOC_MT8195
 config SND_SOC_MT8195_MT6359_RT1019_RT5682
 	tristate "ASoC Audio driver for MT8195 with MT6359 RT1019 RT5682 codec"
 	depends on I2C
-	depends on SND_SOC_MT8195
+	depends on SND_SOC_MT8195 && MTK_PMIC_WRAP
 	select SND_SOC_MT6359
 	select SND_SOC_RT1015P
 	select SND_SOC_RT5682_I2C
-- 
2.18.0

From nobuhiro1.iwamatsu at toshiba.co.jp  Mon Aug 30 19:14:28 2021
From: nobuhiro1.iwamatsu at toshiba.co.jp (Nobuhiro Iwamatsu)
Date: Tue, 31 Aug 2021 11:14:28 +0900
Subject: [PATCH v4 1/4] dt-bindings: clock: Add DT bindings for PLL of
 Toshiba Visconti TMPV770x SoC
In-Reply-To: <163021379431.2676726.15668763072935534900@swboyd.mtv.corp.google.com>
References: <20210804092244.390376-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20210804092244.390376-2-nobuhiro1.iwamatsu@toshiba.co.jp>
 <163021379431.2676726.15668763072935534900@swboyd.mtv.corp.google.com>
Message-ID: <20210831021428.rsjzi6vtv2q3wnkb@toshiba.co.jp>

Hi,

Thanks for your review.

On Sat, Aug 28, 2021 at 10:09:54PM -0700, Stephen Boyd wrote:
> Quoting Nobuhiro Iwamatsu (2021-08-04 02:22:41)
> > Add device tree bindings for PLL of Toshiba Visconti TMPV770x SoC series.
> > 
> > Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> > ---
> >  .../clock/toshiba,tmpv770x-pipllct.yaml       | 57 +++++++++++++++++++
> >  1 file changed, 57 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
> > new file mode 100644
> > index 000000000000..7b7300ce96d6
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml
> > @@ -0,0 +1,57 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/clock/toshiba,tmpv770x-pipllct.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Toshiba Visconti5 TMPV770X PLL Controller Device Tree Bindings
> > +
> > +maintainers:
> > +  - Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> > +
> > +description:
> > +  Toshia Visconti5 PLL controller which supports the PLLs on TMPV770X.
> > +
> > +properties:
> > +  compatible:
> > +    const: toshiba,tmpv7708-pipllct
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  '#clock-cells':
> > +    const: 1
> > +
> > +  clocks:
> > +    description: External reference clock (OSC2)
> > +    maxItems: 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - "#clock-cells"
> > +  - clocks
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +
> > +    osc2_clk: osc2-clk {
> > +      compatible = "fixed-clock";
> > +      clock-frequency = <20000000>;
> > +      #clock-cells = <0>;
> > +    };
> > +
> > +    soc {
> > +        #address-cells = <2>;
> > +        #size-cells = <2>;
> > +
> > +        pipllct: clock-controller at 24220000 {
> > +            compatible = "toshiba,tmpv7708-pipllct";
> 
> The driver makes it look like this is actually part of a syscon node. Is
> that right? It's not clear to me that this is a syscon. But then looking
> at the binding it seems that one device has been split up into PLL and
> "not PLL" parts sort of arbitrarily.

This is the driver that controls the PIPLLCT device that produces the
PLL. This device only has the ability to generate his PLL, no other
features.

I have received similar comments in the driver patch from you, so I will
check that as well.

> 
> > +            reg = <0 0x24220000 0 0x820>;
> > +            #clock-cells = <1>;
> > +            clocks = <&osc2_clk>;
> > +        };
> > +    };
> > +...
> 

Best regards,
  Nobuhiro



From rdunlap at infradead.org  Mon Aug 30 19:57:51 2021
From: rdunlap at infradead.org (Randy Dunlap)
Date: Mon, 30 Aug 2021 19:57:51 -0700
Subject: [PATCH] ASoC: mediatek: mt8195: add MTK_PMIC_WRAP dependency
In-Reply-To: <20210831021303.5230-1-trevor.wu@mediatek.com>
References: <20210831021303.5230-1-trevor.wu@mediatek.com>
Message-ID: <1630c5bd-7f9a-ef63-0476-74c6077adb7f@infradead.org>

On 8/30/21 7:13 PM, Trevor Wu wrote:
> randconfig builds show the warning below,
> 
> WARNING: unmet direct dependencies detected for SND_SOC_MT6359
>     Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && MTK_PMIC_WRAP [=n]
>     Selected by [y]:
>     - SND_SOC_MT8195_MT6359_RT1019_RT5682 [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && I2C [=y] && SND_SOC_MT8195 [=y]
> 
> Add a dependency to avoid it.
> 
> Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
> Reported-by: Randy Dunlap <rdunlap at infradead.org>

Acked-by: Randy Dunlap <rdunlap at infradead.org> # build-tested

Thanks.


> ---
>   sound/soc/mediatek/Kconfig | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
> index cf567a89f421..f6bf0f9c91e3 100644
> --- a/sound/soc/mediatek/Kconfig
> +++ b/sound/soc/mediatek/Kconfig
> @@ -197,7 +197,7 @@ config SND_SOC_MT8195
>   config SND_SOC_MT8195_MT6359_RT1019_RT5682
>   	tristate "ASoC Audio driver for MT8195 with MT6359 RT1019 RT5682 codec"
>   	depends on I2C
> -	depends on SND_SOC_MT8195
> +	depends on SND_SOC_MT8195 && MTK_PMIC_WRAP
>   	select SND_SOC_MT6359
>   	select SND_SOC_RT1015P
>   	select SND_SOC_RT5682_I2C
> 


-- 
~Randy



From ming.qian at nxp.com  Mon Aug 30 19:59:01 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:01 +0800
Subject: [PATCH v7 00/14] imx8q video decoder/encoder driver
Message-ID: <cover.1630377507.git.ming.qian@nxp.com>

Hi all,

This patch series adds support for
the imx8q video encoder and decoder
via the VPU block present in imx8q platforms.
Currently, support for IMX8QXP and IMX8QM is included.

It features decoding for the following formats:
- H.264
- HEVC
- MPEG4
- MPEG2
- VC1
- VP8

It features encoding for the following formats:
- H.264

The driver creates a separate device node for the encoder and decoder.

Changelog:

v7
- fix build warnings with W=1 reported by kernel test robot

v6:
- rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
- rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128

v5:
- move some definition from imx_vph.h to videodev2.h
- remove some unnecessary content
- add some documentation descriptions
- pass the lateset v4l2-compliance test

v4:
- redefine the memory-region in devicetree bindings documentation
- use v4l2's mechanism to implement synchronize queuing ioctl
- remove the unnecessary mutex ioctl_sync
- don't notify source change event if the parameters are same as previously established
- add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format

v3:
- don't make vpu device node a simple-bus
- trigger probing vpu core in the driver
- remove unnecessary vpu core index property

v2:
- fix dt bindings build error
- split driver patch into several parts to avoid exceeding bytes limit

Compliance
==========
# v4l2-compliance -d /dev/video0
v4l2-compliance 1.21.0-4838, 64 bits, 64-bit time_t
v4l2-compliance SHA: 22466798f9a9 2021-08-25 11:05:21

Compliance test for imx8q-vpu device /dev/video0:

Driver Info:
	Driver name      : imx8q-vpu
	Card type        : imx8q vpu decoder
	Bus info         : platform: imx8q-vpu
	Driver version   : 5.14.0
	Capabilities     : 0x84204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
	Detected Stateful Decoder

Required ioctls:
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video0 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 3 Private Controls: 0

Format ioctls:
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK (Not Supported)
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK (Not Supported)
	test Composing: OK
	test Scaling: OK (Not Supported)

Codec ioctls:
	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK

Buffer ioctls:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)

Total for imx8q-vpu device /dev/video0: 45, Succeeded: 45, Failed: 0, Warnings: 0

# v4l2-compliance -d /dev/video1
v4l2-compliance 1.21.0-4838, 64 bits, 64-bit time_t
v4l2-compliance SHA: 22466798f9a9 2021-08-25 11:05:21

Compliance test for imx8q-vpu device /dev/video1:

Driver Info:
	Driver name      : imx8q-vpu
	Card type        : imx8q vpu encoder
	Bus info         : platform: imx8q-vpu
	Driver version   : 5.14.0
	Capabilities     : 0x84204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
	Detected Stateful Encoder

Required ioctls:
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video1 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 20 Private Controls: 0

Format ioctls:
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK
	test Composing: OK (Not Supported)
	test Scaling: OK (Not Supported)

Codec ioctls:
	test VIDIOC_(TRY_)ENCODER_CMD: OK
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)

Total for imx8q-vpu device /dev/video1: 45, Succeeded: 45, Failed: 0, Warnings: 0

Ming Qian (14):
  dt-bindings: media: imx8q: add imx video codec bindings
  media:Add nt8 and nt10 video format.
  media:Add v4l2 buf flag codec data.
  media: imx: imx8q: add imx8q vpu device driver
  media: imx: imx8q: add vpu core driver
  media: imx: imx8q: implement vpu core communication based on mailbox
  media: imx: imx8q: add vpu v4l2 m2m support
  media: imx: imx8q: add v4l2 m2m vpu encoder stateful driver
  media: imx: imx8q: add v4l2 m2m vpu decoder stateful driver
  media: imx: imx8q: implement windsor encoder rpc interface
  media: imx: imx8q: implement malone decoder rpc interface
  ARM64: dts: freescale: imx8q: add imx vpu codec entries
  firmware: imx: scu-pd: imx8q: add vpu mu resources
  MAINTAINERS: add NXP IMX8Q VPU CODEC V4L2 driver entry

 .../bindings/media/nxp,imx8q-vpu.yaml         |  178 ++
 .../userspace-api/media/v4l/buffer.rst        |    7 +
 .../media/v4l/pixfmt-yuv-planar.rst           |   15 +
 .../media/v4l/vidioc-dqevent.rst              |   12 +
 MAINTAINERS                                   |   10 +
 .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
 drivers/firmware/imx/scu-pd.c                 |    4 +
 drivers/media/platform/Kconfig                |    2 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/imx/Kconfig            |   19 +
 drivers/media/platform/imx/Makefile           |    1 +
 drivers/media/platform/imx/vpu-8q/Makefile    |   23 +
 drivers/media/platform/imx/vpu-8q/vdec.c      | 1684 +++++++++++++++++
 drivers/media/platform/imx/vpu-8q/venc.c      | 1383 ++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu.h       |  333 ++++
 drivers/media/platform/imx/vpu-8q/vpu_cmds.c  |  435 +++++
 drivers/media/platform/imx/vpu-8q/vpu_cmds.h  |   25 +
 drivers/media/platform/imx/vpu-8q/vpu_codec.h |   68 +
 drivers/media/platform/imx/vpu-8q/vpu_color.c |  192 ++
 drivers/media/platform/imx/vpu-8q/vpu_core.c  |  911 +++++++++
 drivers/media/platform/imx/vpu-8q/vpu_core.h  |   16 +
 drivers/media/platform/imx/vpu-8q/vpu_dbg.c   |  496 +++++
 drivers/media/platform/imx/vpu-8q/vpu_defs.h  |  186 ++
 .../media/platform/imx/vpu-8q/vpu_dev_imx8q.c |   72 +
 drivers/media/platform/imx/vpu-8q/vpu_drv.c   |  217 +++
 .../media/platform/imx/vpu-8q/vpu_helpers.c   |  453 +++++
 .../media/platform/imx/vpu-8q/vpu_helpers.h   |   72 +
 drivers/media/platform/imx/vpu-8q/vpu_imx8q.c |  218 +++
 drivers/media/platform/imx/vpu-8q/vpu_imx8q.h |  116 ++
 drivers/media/platform/imx/vpu-8q/vpu_log.h   |   44 +
 .../media/platform/imx/vpu-8q/vpu_malone.c    | 1683 ++++++++++++++++
 .../media/platform/imx/vpu-8q/vpu_malone.h    |   42 +
 drivers/media/platform/imx/vpu-8q/vpu_mbox.c  |  126 ++
 drivers/media/platform/imx/vpu-8q/vpu_mbox.h  |   16 +
 drivers/media/platform/imx/vpu-8q/vpu_msgs.c  |  413 ++++
 drivers/media/platform/imx/vpu-8q/vpu_msgs.h  |   14 +
 drivers/media/platform/imx/vpu-8q/vpu_rpc.c   |  257 +++
 drivers/media/platform/imx/vpu-8q/vpu_rpc.h   |  463 +++++
 drivers/media/platform/imx/vpu-8q/vpu_v4l2.c  |  654 +++++++
 drivers/media/platform/imx/vpu-8q/vpu_v4l2.h  |   44 +
 .../media/platform/imx/vpu-8q/vpu_windsor.c   | 1244 ++++++++++++
 .../media/platform/imx/vpu-8q/vpu_windsor.h   |   39 +
 drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
 include/linux/imx_vpu.h                       |   11 +
 include/uapi/linux/imx_vpu.h                  |   18 +
 include/uapi/linux/videodev2.h                |    5 +
 48 files changed, 12338 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
 create mode 100644 drivers/media/platform/imx/Kconfig
 create mode 100644 drivers/media/platform/imx/Makefile
 create mode 100644 drivers/media/platform/imx/vpu-8q/Makefile
 create mode 100644 drivers/media/platform/imx/vpu-8q/vdec.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/venc.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_cmds.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_cmds.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_codec.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_color.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_core.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_core.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_dbg.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_defs.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_drv.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_helpers.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_helpers.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_imx8q.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_imx8q.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_log.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_malone.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_malone.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_mbox.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_mbox.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_msgs.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_msgs.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_rpc.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_rpc.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_v4l2.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_v4l2.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_windsor.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_windsor.h
 create mode 100644 include/linux/imx_vpu.h
 create mode 100644 include/uapi/linux/imx_vpu.h


base-commit: 9c3a0f285248899dfa81585bc5d5bc9ebdb8fead
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:02 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:02 +0800
Subject: [PATCH v7 01/14] dt-bindings: media: imx8q: add imx video codec
 bindings
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <74899fe01678641839be0eea7e3fd35214aad84c.1630377507.git.ming.qian@nxp.com>

Add devicetree binding documentation for IMX8Q Video Processing Unit IP

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/media/nxp,imx8q-vpu.yaml         | 178 ++++++++++++++++++
 1 file changed, 178 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml

diff --git a/Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
new file mode 100644
index 000000000000..04a040e5a9d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
@@ -0,0 +1,178 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/nxp,imx8q-vpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8Q video encode and decode accelerators
+
+maintainers:
+  - Ming Qian <ming.qian at nxp.com>
+  - Shijie Qin <shijie.qin at nxp.com>
+
+description: |-
+  The Amphion MXC video encoder(Windsor) and decoder(Malone) accelerators present
+  on NXP i.MX8Q SoCs.
+
+properties:
+  $nodename:
+    pattern: "^vpu@[0-9a-f]+$"
+
+  compatible:
+    oneOf:
+      - const: nxp,imx8qm-vpu
+      - const: nxp,imx8qxp-vpu
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^mailbox@[0-9a-f]+$":
+    description:
+      Each vpu encoder or decoder correspond a MU, which used for communication
+      between driver and firmware. Implement via mailbox on driver.
+    $ref: ../mailbox/fsl,mu.yaml#
+
+
+  "^vpu_core@[0-9a-f]+$":
+    description:
+      Each core correspond a decoder or encoder, need to configure them
+      separately. NXP i.MX8QM SoC has one decoder and two encoder, i.MX8QXP SoC
+      has one decoder and one encoder.
+    type: object
+
+    properties:
+      compatible:
+        oneOf:
+          - const: nxp,imx8q-vpu-decoder
+          - const: nxp,imx8q-vpu-encoder
+
+      reg:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+      mbox-names:
+        items:
+          - const: tx0
+          - const: tx1
+          - const: rx
+
+      mboxes:
+        description:
+          List of phandle of 2 MU channels for tx, 1 MU channel for rx.
+        maxItems: 3
+
+      memory-region:
+        description:
+          Phandle to the reserved memory nodes to be associated with the
+          remoteproc device. The reserved memory nodes should be carveout nodes,
+          and should be defined as per the bindings in
+          Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+        items:
+          - description: region reserved for firmware image sections.
+          - description: region used for RPC shared memory between firmware and
+                         driver.
+
+    required:
+      - compatible
+      - reg
+      - power-domains
+      - mbox-names
+      - mboxes
+      - memory-region
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  # Device node example for i.MX8QM platform:
+  - |
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    vpu: vpu at 2c000000 {
+      compatible = "nxp,imx8qm-vpu";
+      ranges = <0x2c000000 0x2c000000 0x2000000>;
+      reg = <0x2c000000 0x1000000>;
+      #address-cells = <1>;
+      #size-cells = <1>;
+      power-domains = <&pd IMX_SC_R_VPU>;
+
+      mu_m0: mailbox at 2d000000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d000000 0x20000>;
+        interrupts = <0 472 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+      };
+
+      mu1_m0: mailbox at 2d020000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d020000 0x20000>;
+        interrupts = <0 473 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+      };
+
+      mu2_m0: mailbox at 2d040000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d040000 0x20000>;
+        interrupts = <0 474 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+      };
+
+      vpu_core0: vpu_core at 2d080000 {
+        compatible = "nxp,imx8q-vpu-decoder";
+        reg = <0x2d080000 0x10000>;
+        power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu_m0 0 0>,
+                 <&mu_m0 0 1>,
+                 <&mu_m0 1 0>;
+        memory-region = <&decoder_boot>, <&decoder_rpc>;
+      };
+
+      vpu_core1: vpu_core at 2d090000 {
+        compatible = "nxp,imx8q-vpu-encoder";
+        reg = <0x2d090000 0x10000>;
+        power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu1_m0 0 0>,
+                 <&mu1_m0 0 1>,
+                 <&mu1_m0 1 0>;
+        memory-region = <&encoder1_boot>, <&encoder1_rpc>;
+      };
+
+      vpu_core2: vpu_core at 2d0a0000 {
+        reg = <0x2d0a0000 0x10000>;
+        compatible = "nxp,imx8q-vpu-encoder";
+        power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu2_m0 0 0>,
+                 <&mu2_m0 0 1>,
+                 <&mu2_m0 1 0>;
+        memory-region = <&encoder2_boot>, <&encoder2_rpc>;
+      };
+    };
+
+...
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:03 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:03 +0800
Subject: [PATCH v7 02/14] media:Add nt8 and nt10 video format.
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <981eee1270fb47658f7821d59525ff4c53c30644.1630377507.git.ming.qian@nxp.com>

NT8 is 8-bit tiled nv12 format used by amphion decoder.
NT10 is 10-bit tiled format used by amphion decoder.
The tile size is 8x128

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../userspace-api/media/v4l/pixfmt-yuv-planar.rst | 15 +++++++++++++++
 drivers/media/v4l2-core/v4l2-ioctl.c              |  2 ++
 include/uapi/linux/videodev2.h                    |  4 ++++
 3 files changed, 21 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
index 090c091affd2..ce3419d95691 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
@@ -254,6 +254,8 @@ of the luma plane.
 
 .. _V4L2-PIX-FMT-NV12MT:
 .. _V4L2-PIX-FMT-NV12MT-16X16:
+.. _V4L2_PIX_FMT_NV12_8L128:
+.. _V4L2_PIX_FMT_NV12_10BE_8L128:
 
 NV12MT and MV12MT_16X16
 -----------------------
@@ -276,6 +278,19 @@ If the vertical resolution is an odd number of macroblocks, the last row of
 macroblocks is stored in linear order. The layouts of the luma and chroma
 planes are identical.
 
+``V4L2_PIX_FMT_NV12_8L128`` stores pixel in 2D 8x128 tiles, and stores
+tiles linearly in memory. The line stride must be aligned to a multiple of 256.
+The image height must be aligned to a multiple of 128. The layouts of the
+luma and chroma planes are identical.
+
+``V4L2_PIX_FMT_NV12_10BE_8L128`` stores 10 bits pixel in 2D 8x128 tiles,
+and stores tiles linearly in memory. the data is arranged at the big end.
+The line stride must be aligned to a multiple of 256 bytes.  The image
+height must be aligned to a multiple of 128.  The layouts of the luma
+and chroma planes are identical. Note the tile size is 8bytes multiplied
+by 128 bytes, it means that the low bits and high bits of one pixel
+may be in differnt tiles.
+
 .. _nv12mt:
 
 .. kernel-figure:: nv12mt.svg
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 05d5db3d85e5..22f97a1cfbeb 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1367,6 +1367,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
+	case V4L2_PIX_FMT_NV12_8L128:		descr = "Y/CbCr 4:2:0 (8x128 Linear)"; break;
+	case V4L2_PIX_FMT_NV12_10BE_8L128:	descr = "Y/CbCr 4:2:0 10BE(8x128 Linear)"; break;
 
 	default:
 		/* Compressed formats */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 9260791b8438..167c0e40ec06 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -627,6 +627,10 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_YUV444M v4l2_fourcc('Y', 'M', '2', '4') /* 24  YUV444 planar */
 #define V4L2_PIX_FMT_YVU444M v4l2_fourcc('Y', 'M', '4', '2') /* 24  YVU444 planar */
 
+/* Tiled YUV formats */
+#define V4L2_PIX_FMT_NV12_8L128      v4l2_fourcc('N', 'A', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */
+#define V4L2_PIX_FMT_NV12_10BE_8L128 v4l2_fourcc('N', 'T', '1', '2') /* Y/CbCr 4:2:0 10-bit 8x128 tiles */
+
 /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
 #define V4L2_PIX_FMT_SGBRG8  v4l2_fourcc('G', 'B', 'R', 'G') /*  8  GBGB.. RGRG.. */
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:04 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:04 +0800
Subject: [PATCH v7 03/14] media:Add v4l2 buf flag codec data.
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <be578f1a32a47d24c03b9640c6a924b2a6507708.1630377507.git.ming.qian@nxp.com>

In some decoing scenarios, application may queue a buffer
that only contains codec config data, and the driver needs to
know whether is it a frame or not.
So we add a buf flag to tell this case.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 Documentation/userspace-api/media/v4l/buffer.rst | 7 +++++++
 include/uapi/linux/videodev2.h                   | 1 +
 2 files changed, 8 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/buffer.rst b/Documentation/userspace-api/media/v4l/buffer.rst
index e991ba73d873..11013bcf8a41 100644
--- a/Documentation/userspace-api/media/v4l/buffer.rst
+++ b/Documentation/userspace-api/media/v4l/buffer.rst
@@ -607,6 +607,13 @@ Buffer Flags
 	the format. Any subsequent call to the
 	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
 	but return an ``EPIPE`` error code.
+    * .. _`V4L2-BUF-FLAG-CODECCONFIG`:
+
+      - ``V4L2_BUF_FLAG_CODECCONFIG``
+      - 0x00200000
+      - The buffer only contains codec config data, eg. sps and pps.
+    Applications can set this bit when ``type`` refers to an output
+    stream, this flag is usually used by v4l2 decoder.
     * .. _`V4L2-BUF-FLAG-REQUEST-FD`:
 
       - ``V4L2_BUF_FLAG_REQUEST_FD``
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 167c0e40ec06..5bb0682b4a23 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1119,6 +1119,7 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv)
 #define V4L2_BUF_FLAG_TSTAMP_SRC_SOE		0x00010000
 /* mem2mem encoder/decoder */
 #define V4L2_BUF_FLAG_LAST			0x00100000
+#define V4L2_BUF_FLAG_CODECCONFIG		0x00200000
 /* request_fd is valid */
 #define V4L2_BUF_FLAG_REQUEST_FD		0x00800000
 
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:05 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:05 +0800
Subject: [PATCH v7 04/14] media: imx: imx8q: add imx8q vpu device driver
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <5eea270a7ec452eff463d0cbbb7fc6aecf0cf02d.1630377507.git.ming.qian@nxp.com>

IMX8Q SoCs feature a powerful video processing unit able to decode many
foramts and encode H.264.

The vpu IP is amphion malone decoder and windsor encoder.
This Driver is for this IP that is based on the v4l2 mem2mem framework.

Supported SoCs are: IMX8QXP, IMX8QM

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 .../media/v4l/vidioc-dqevent.rst              |  12 +
 drivers/media/platform/Kconfig                |   2 +
 drivers/media/platform/Makefile               |   2 +
 drivers/media/platform/imx/Kconfig            |  19 +
 drivers/media/platform/imx/Makefile           |   1 +
 drivers/media/platform/imx/vpu-8q/Makefile    |  23 ++
 drivers/media/platform/imx/vpu-8q/vpu.h       | 333 ++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_defs.h  | 186 ++++++++++
 .../media/platform/imx/vpu-8q/vpu_dev_imx8q.c |  72 ++++
 drivers/media/platform/imx/vpu-8q/vpu_drv.c   | 217 ++++++++++++
 include/linux/imx_vpu.h                       |  11 +
 include/uapi/linux/imx_vpu.h                  |  18 +
 12 files changed, 896 insertions(+)
 create mode 100644 drivers/media/platform/imx/Kconfig
 create mode 100644 drivers/media/platform/imx/Makefile
 create mode 100644 drivers/media/platform/imx/vpu-8q/Makefile
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_defs.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_drv.c
 create mode 100644 include/linux/imx_vpu.h
 create mode 100644 include/uapi/linux/imx_vpu.h

diff --git a/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst b/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
index 6eb40073c906..926e360758e1 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-dqevent.rst
@@ -185,6 +185,18 @@ call.
     * - ``V4L2_EVENT_PRIVATE_START``
       - 0x08000000
       - Base event number for driver-private events.
+    * - ``V4L2_EVENT_CODEC_ERROR``
+      - 0x08000001
+      - This event is triggered when some error occurs inside the codec engine,
+    usually it can be replaced by a POLLERR event, but in some cases, the POLLERR
+    may cause the application to exit, but this event can allow the application to
+    handle the codec error without exiting.
+    * - ``V4L2_EVENT_SKIP``
+      - 0x08000002
+      - This event is triggered when one frame is decoded, but it won't be outputed
+    to the display. So the application can't get this frame, and the input frame count
+    is dismatch with the output frame count. And this evevt is telling the client to
+    handle this case.
 
 
 .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.5cm}|
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 157c924686e4..0072672297d2 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -200,6 +200,8 @@ config VIDEO_TI_CAL_MC
 
 endif # VIDEO_TI_CAL
 
+source "drivers/media/platform/imx/Kconfig"
+
 endif # V4L_PLATFORM_DRIVERS
 
 menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 73ce083c2fc6..b159c69f58e0 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -86,3 +86,5 @@ obj-$(CONFIG_VIDEO_QCOM_VENUS)		+= qcom/venus/
 obj-y					+= sunxi/
 
 obj-$(CONFIG_VIDEO_MESON_GE2D)		+= meson/ge2d/
+
+obj-y					+= imx/
diff --git a/drivers/media/platform/imx/Kconfig b/drivers/media/platform/imx/Kconfig
new file mode 100644
index 000000000000..40cceb2cb526
--- /dev/null
+++ b/drivers/media/platform/imx/Kconfig
@@ -0,0 +1,19 @@
+#
+# Codec configuration
+#
+
+config MXC_VPU_8Q
+	tristate "Support for MXC 8Q VPU(Video Processing Unit) Codec"
+	depends on ARCH_MXC
+	depends on MEDIA_SUPPORT
+	depends on VIDEO_DEV
+	depends on VIDEO_V4L2
+	select V4L2_MEM2MEM_DEV
+	select VIDEOBUF2_DMA_CONTIG
+	select VIDEOBUF2_VMALLOC
+	default y
+	help
+	  This is a V4L2 driver for NXP MXC 8Q video accelerator hardware.
+	  It accelerates encoding and decoding operations on
+	  various NXP SoCs.
+	  To compile this driver as a module choose m here.
diff --git a/drivers/media/platform/imx/Makefile b/drivers/media/platform/imx/Makefile
new file mode 100644
index 000000000000..214f43ca390c
--- /dev/null
+++ b/drivers/media/platform/imx/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MXC_VPU_8Q) += vpu-8q/
diff --git a/drivers/media/platform/imx/vpu-8q/Makefile b/drivers/media/platform/imx/vpu-8q/Makefile
new file mode 100644
index 000000000000..ecc74b63d536
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/Makefile
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for NXP VPU driver
+
+vpu-8q-dev-objs += vpu_drv.o \
+			vpu_dev_imx8q.o
+
+vpu-8q-core-objs += vpu_core.o \
+			vpu_mbox.o \
+			vpu_v4l2.o \
+			vpu_helpers.o \
+			vpu_cmds.o \
+			vpu_msgs.o \
+			vpu_rpc.o \
+			vpu_imx8q.o \
+			vpu_windsor.o \
+			vpu_malone.o \
+			vpu_color.o \
+			vdec.o  \
+			venc.o \
+			vpu_dbg.o
+
+obj-$(CONFIG_MXC_VPU_8Q) += vpu-8q-dev.o
+obj-$(CONFIG_MXC_VPU_8Q) += vpu-8q-core.o
diff --git a/drivers/media/platform/imx/vpu-8q/vpu.h b/drivers/media/platform/imx/vpu-8q/vpu.h
new file mode 100644
index 000000000000..81f347d953ae
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu.h
@@ -0,0 +1,333 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_H
+#define _IMX_VPU_H
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-mem2mem.h>
+#include <linux/mailbox_client.h>
+#include <linux/mailbox_controller.h>
+#include <linux/kfifo.h>
+
+#define VPU_TIMEOUT		msecs_to_jiffies(1000)
+#define VPU_INST_NULL_ID	(-1L)
+#define VPU_MSG_BUFFER_SIZE	(8192)
+
+enum imx_plat_type {
+	IMX8QXP = 0,
+	IMX8QM  = 1,
+	IMX8DM,
+	IMX8DX,
+	PLAT_TYPE_RESERVED
+};
+
+enum vpu_core_type {
+	VPU_CORE_TYPE_ENC = 0,
+	VPU_CORE_TYPE_DEC = 0x10,
+};
+
+struct vpu_dev;
+struct vpu_resources {
+	enum imx_plat_type plat_type;
+	u32 mreg_base;
+	int (*setup)(struct vpu_dev *vpu);
+	int (*setup_encoder)(struct vpu_dev *vpu);
+	int (*setup_decoder)(struct vpu_dev *vpu);
+	int (*reset)(struct vpu_dev *vpu);
+};
+
+struct vpu_buffer {
+	void *virt;
+	dma_addr_t phys;
+	u32 length;
+	u32 bytesused;
+	struct device *dev;
+};
+
+struct vpu_dev {
+	void __iomem *base;
+	struct platform_device *pdev;
+	struct device *dev;
+	struct mutex lock;
+	const struct vpu_resources *res;
+	struct list_head cores;
+
+	struct v4l2_device v4l2_dev;
+	struct video_device *vdev_dec;
+	struct video_device *vdev_enc;
+
+	struct delayed_work watchdog_work;
+	void (*get_vpu)(struct vpu_dev *vpu);
+	void (*put_vpu)(struct vpu_dev *vpu);
+	void (*get_enc)(struct vpu_dev *vpu);
+	void (*put_enc)(struct vpu_dev *vpu);
+	void (*get_dec)(struct vpu_dev *vpu);
+	void (*put_dec)(struct vpu_dev *vpu);
+	atomic_t ref_vpu;
+	atomic_t ref_enc;
+	atomic_t ref_dec;
+
+	struct dentry *debugfs;
+};
+
+struct vpu_format {
+	u32 pixfmt;
+	unsigned int num_planes;
+	u32 type;
+	u32 flags;
+	u32 width;
+	u32 height;
+	u32 sizeimage[VIDEO_MAX_PLANES];
+	u32 bytesperline[VIDEO_MAX_PLANES];
+	u32 field;
+};
+
+struct vpu_core_resources {
+	enum vpu_core_type type;
+	const char *fwname;
+	u32 stride;
+	u32 max_width;
+	u32 min_width;
+	u32 step_width;
+	u32 max_height;
+	u32 min_height;
+	u32 step_height;
+	u32 rpc_size;
+	u32 fwlog_size;
+	u32 act_size;
+	bool standalone;
+};
+
+struct vpu_mbox {
+	char name[20];
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	bool block;
+};
+
+enum vpu_core_state {
+	VPU_CORE_DEINIT = 0,
+	VPU_CORE_ACTIVE,
+	VPU_CORE_SNAPSHOT,
+	VPU_CORE_HANG
+};
+
+struct vpu_core {
+	void __iomem *base;
+	struct platform_device *pdev;
+	struct device *dev;
+	struct device *parent;
+	struct device *pd;
+	struct device_link *pd_link;
+	struct mutex lock;
+	struct mutex cmd_lock;
+	struct list_head list;
+	enum vpu_core_type type;
+	int id;
+	const struct vpu_core_resources *res;
+	unsigned long instance_mask;
+	u32 supported_instance_count;
+	unsigned long hang_mask;
+	u32 request_count;
+	struct list_head instances;
+	enum vpu_core_state state;
+	u32 fw_version;
+
+	struct vpu_buffer fw;
+	struct vpu_buffer rpc;
+	struct vpu_buffer log;
+	struct vpu_buffer act;
+
+	struct vpu_mbox tx_type;
+	struct vpu_mbox tx_data;
+	struct vpu_mbox rx;
+	unsigned long cmd_seq;
+
+	wait_queue_head_t ack_wq;
+	struct completion cmp;
+	struct workqueue_struct *workqueue;
+	struct work_struct msg_work;
+	struct delayed_work msg_delayed_work;
+	struct kfifo msg_fifo;
+	void *msg_buffer;
+	unsigned int msg_buffer_size;
+
+	struct vpu_dev *vpu;
+	void *iface;
+
+	struct dentry *debugfs;
+	struct dentry *debugfs_fwlog;
+};
+
+enum vpu_codec_state {
+	VPU_CODEC_STATE_DEINIT = 1,
+	VPU_CODEC_STATE_CONFIGURED,
+	VPU_CODEC_STATE_START,
+	VPU_CODEC_STATE_STARTED,
+	VPU_CODEC_STATE_ACTIVE,
+	VPU_CODEC_STATE_SEEK,
+	VPU_CODEC_STATE_STOP,
+	VPU_CODEC_STATE_DRAIN,
+	VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE,
+};
+
+struct vpu_frame_info {
+	u32 type;
+	u32 id;
+	u32 sequence;
+	u32 luma;
+	u32 chroma_u;
+	u32 chroma_v;
+	u32 data_offset;
+	u32 flags;
+	u32 skipped;
+	s64 timestamp;
+};
+
+struct vpu_inst;
+struct vpu_inst_ops {
+	int (*ctrl_init)(struct vpu_inst *inst);
+	int (*start)(struct vpu_inst *inst, u32 type);
+	int (*stop)(struct vpu_inst *inst, u32 type);
+	int (*abort)(struct vpu_inst *inst);
+	bool (*check_ready)(struct vpu_inst *inst, unsigned int type);
+	void (*buf_done)(struct vpu_inst *inst, struct vpu_frame_info *frame);
+	void (*event_notify)(struct vpu_inst *inst, u32 event, void *data);
+	void (*release)(struct vpu_inst *inst);
+	void (*cleanup)(struct vpu_inst *inst);
+	void (*mem_request)(struct vpu_inst *inst,
+				u32 enc_frame_size,
+				u32 enc_frame_num,
+				u32 ref_frame_size,
+				u32 ref_frame_num,
+				u32 act_frame_size,
+				u32 act_frame_num);
+	void (*input_done)(struct vpu_inst *inst);
+	void (*stop_done)(struct vpu_inst *inst);
+	int (*process_output)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*process_capture)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*get_one_frame)(struct vpu_inst *inst, void *info);
+	void (*on_queue_empty)(struct vpu_inst *inst, u32 type);
+	int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);
+	void (*wait_prepare)(struct vpu_inst *inst);
+	void (*wait_finish)(struct vpu_inst *inst);
+};
+
+struct vpu_inst {
+	struct list_head list;
+	struct mutex lock;
+	struct vpu_core *core;
+	int id;
+
+	struct v4l2_fh fh;
+	struct v4l2_m2m_dev *m2m_dev;
+	struct v4l2_m2m_ctx *m2m_ctx;
+	struct v4l2_ctrl_handler ctrl_handler;
+	atomic_t ref_count;
+	int (*release)(struct vpu_inst *inst);
+
+	enum vpu_codec_state state;
+	enum vpu_core_type type;
+
+	struct workqueue_struct *workqueue;
+	struct work_struct msg_work;
+	struct kfifo msg_fifo;
+	u8 msg_buffer[VPU_MSG_BUFFER_SIZE];
+
+	struct vpu_buffer stream_buffer;
+	bool use_stream_buffer;
+	struct vpu_buffer act;
+
+	struct list_head cmd_q;
+	void *pending;
+
+	struct vpu_inst_ops *ops;
+	const struct vpu_format *formats;
+	struct vpu_format out_format;
+	struct vpu_format cap_format;
+	u32 min_buffer_cap;
+	u32 min_buffer_out;
+
+	struct v4l2_rect crop;
+	u32 colorspace;
+	u8 ycbcr_enc;
+	u8 quantization;
+	u8 xfer_func;
+	u32 sequence;
+	u32 extra_size;
+
+	u32 flows[16];
+	u32 flow_idx;
+
+	pid_t pid;
+	pid_t tgid;
+	struct dentry *debugfs;
+
+	void *priv;
+};
+
+#define call_vop(inst, op, args...)					\
+	((inst)->ops->op ? (inst)->ops->op(inst, ##args) : 0)		\
+
+enum {
+	VPU_BUF_STATE_IDLE = 0,
+	VPU_BUF_STATE_INUSE,
+	VPU_BUF_STATE_DECODED,
+	VPU_BUF_STATE_READY,
+	VPU_BUF_STATE_SKIP,
+	VPU_BUF_STATE_ERROR
+};
+
+struct vpu_vb2_buffer {
+	struct v4l2_m2m_buffer m2m_buf;
+	dma_addr_t luma;
+	dma_addr_t chroma_u;
+	dma_addr_t chroma_v;
+	unsigned int state;
+	u32 tag;
+};
+
+void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val);
+u32 vpu_readl(struct vpu_dev *vpu, u32 reg);
+
+static inline struct vpu_vb2_buffer *to_vpu_vb2_buffer(struct vb2_v4l2_buffer *vbuf)
+{
+	struct v4l2_m2m_buffer *m2m_buf = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+
+	return container_of(m2m_buf, struct vpu_vb2_buffer, m2m_buf);
+}
+
+static inline const char *vpu_core_type_desc(enum vpu_core_type type)
+{
+	return type == VPU_CORE_TYPE_ENC ? "encoder" : "decoder";
+}
+
+static inline struct vpu_inst *to_inst(struct file *filp)
+{
+	return container_of(filp->private_data, struct vpu_inst, fh);
+}
+
+#define ctrl_to_inst(ctrl)	\
+	container_of((ctrl)->handler, struct vpu_inst, ctrl_handler)
+
+int venc_create_video_device(struct vpu_dev *vpu);
+int vdec_create_video_device(struct vpu_dev *vpu);
+
+struct vpu_inst *vpu_inst_get(struct vpu_inst *inst);
+void vpu_inst_put(struct vpu_inst *inst);
+struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type);
+void vpu_release_core(struct vpu_core *core);
+int vpu_inst_register(struct vpu_inst *inst);
+int vpu_inst_unregister(struct vpu_inst *inst);
+
+int vpu_inst_create_dbgfs_file(struct vpu_inst *inst);
+int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst);
+int vpu_core_create_dbgfs_file(struct vpu_core *core);
+int vpu_core_remove_dbgfs_file(struct vpu_core *core);
+void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_defs.h b/drivers/media/platform/imx/vpu-8q/vpu_defs.h
new file mode 100644
index 000000000000..e8419ca34f92
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_defs.h
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_DEFS_H
+#define _IMX_VPU_DEFS_H
+
+enum MSG_TYPE {
+	INIT_DONE = 1,
+	PRC_BUF_OFFSET,
+	BOOT_ADDRESS,
+	COMMAND,
+	EVENT,
+};
+
+enum {
+	VPU_IRQ_CODE_BOOT_DONE = 0x55,
+	VPU_IRQ_CODE_SNAPSHOT_DONE = 0xa5,
+	VPU_IRQ_CODE_SYNC = 0xaa,
+};
+
+enum {
+	VPU_CMD_ID_NOOP = 0x0,
+	VPU_CMD_ID_CONFIGURE_CODEC,
+	VPU_CMD_ID_START,
+	VPU_CMD_ID_STOP,
+	VPU_CMD_ID_ABORT,
+	VPU_CMD_ID_RST_BUF,
+	VPU_CMD_ID_SNAPSHOT,
+	VPU_CMD_ID_FIRM_RESET,
+	VPU_CMD_ID_UPDATE_PARAMETER,
+	VPU_CMD_ID_FRAME_ENCODE,
+	VPU_CMD_ID_SKIP,
+	VPU_CMD_ID_PARSE_NEXT_SEQ,
+	VPU_CMD_ID_PARSE_NEXT_I,
+	VPU_CMD_ID_PARSE_NEXT_IP,
+	VPU_CMD_ID_PARSE_NEXT_ANY,
+	VPU_CMD_ID_DEC_PIC,
+	VPU_CMD_ID_FS_ALLOC,
+	VPU_CMD_ID_FS_RELEASE,
+	VPU_CMD_ID_TIMESTAMP,
+	VPU_CMD_ID_DEBUG
+};
+
+enum {
+	VPU_MSG_ID_NOOP = 0x100,
+	VPU_MSG_ID_RESET_DONE,
+	VPU_MSG_ID_START_DONE,
+	VPU_MSG_ID_STOP_DONE,
+	VPU_MSG_ID_ABORT_DONE,
+	VPU_MSG_ID_BUF_RST,
+	VPU_MSG_ID_MEM_REQUEST,
+	VPU_MSG_ID_PARAM_UPD_DONE,
+	VPU_MSG_ID_FRAME_INPUT_DONE,
+	VPU_MSG_ID_ENC_DONE,
+	VPU_MSG_ID_DEC_DONE,
+	VPU_MSG_ID_FRAME_REQ,
+	VPU_MSG_ID_FRAME_RELEASE,
+	VPU_MSG_ID_SEQ_HDR_FOUND,
+	VPU_MSG_ID_RES_CHANGE,
+	VPU_MSG_ID_PIC_HDR_FOUND,
+	VPU_MSG_ID_PIC_DECODED,
+	VPU_MSG_ID_PIC_EOS,
+	VPU_MSG_ID_FIFO_LOW,
+	VPU_MSG_ID_FIFO_HIGH,
+	VPU_MSG_ID_FIFO_EMPTY,
+	VPU_MSG_ID_FIFO_FULL,
+	VPU_MSG_ID_BS_ERROR,
+	VPU_MSG_ID_UNSUPPORTED,
+	VPU_MSG_ID_TIMESTAMP_INFO,
+
+	VPU_MSG_ID_FIRMWARE_XCPT,
+};
+
+enum VPU_ENC_MEMORY_RESOURSE {
+	MEM_RES_ENC,
+	MEM_RES_REF,
+	MEM_RES_ACT
+};
+
+enum VPU_DEC_MEMORY_RESOURCE {
+	MEM_RES_FRAME,
+	MEM_RES_MBI,
+	MEM_RES_DCP
+};
+
+enum VPU_SCODE_TYPE {
+	SCODE_PADDING_EOS = 1,
+	SCODE_PADDING_BUFFLUSH = 2,
+	SCODE_PADDING_ABORT = 3,
+	SCODE_SEQUENCE = 0x31,
+	SCODE_PICTURE = 0x32,
+	SCODE_SLICE = 0x33
+};
+
+struct vpu_pkt_mem_req_data {
+	u32 enc_frame_size;
+	u32 enc_frame_num;
+	u32 ref_frame_size;
+	u32 ref_frame_num;
+	u32 act_buf_size;
+	u32 act_buf_num;
+};
+
+struct vpu_enc_pic_info {
+	u32 frame_id;
+	u32 pic_type;
+	u32 skipped_frame;
+	u32 error_flag;
+	u32 psnr;
+	u32 frame_size;
+	u32 wptr;
+	u32 crc;
+	s64 timestamp;
+};
+
+struct vpu_dec_codec_info {
+	u32 pixfmt;
+	u32 num_ref_frms;
+	u32 num_dpb_frms;
+	u32 num_dfe_area;
+	u32 color_primaries;
+	u32 transfer_chars;
+	u32 matrix_coeffs;
+	u32 full_range;
+	u32 vui_present;
+	u32 progressive;
+	u32 width;
+	u32 height;
+	u32 decoded_width;
+	u32 decoded_height;
+	u32 frame_rate;
+	u32 dsp_asp_ratio;
+	u32 level_idc;
+	u32 bit_depth_luma;
+	u32 bit_depth_chroma;
+	u32 chroma_fmt;
+	u32 mvc_num_views;
+	u32 offset_x;
+	u32 offset_y;
+	u32 tag;
+	u32 sizeimage[VIDEO_MAX_PLANES];
+	u32 bytesperline[VIDEO_MAX_PLANES];
+	u32 mbi_size;
+	u32 dcp_size;
+	u32 stride;
+};
+
+struct vpu_dec_pic_info {
+	u32 id;
+	u32 luma;
+	u32 start;
+	u32 end;
+	u32 pic_size;
+	u32 stride;
+	u32 skipped;
+	s64 timestamp;
+	u32 consumed_count;
+};
+
+struct vpu_fs_info {
+	u32 id;
+	u32 type;
+	u32 tag;
+	u32 luma_addr;
+	u32 luma_size;
+	u32 chroma_addr;
+	u32 chromau_size;
+	u32 chromav_addr;
+	u32 chromav_size;
+	u32 bytesperline;
+	u32 not_displayed;
+};
+
+struct vpu_ts_info {
+	s64 timestamp;
+	u32 size;
+};
+
+#define BITRATE_STEP		(1024)
+#define BITRATE_MIN		(16 * BITRATE_STEP)
+#define BITRATE_MAX		(240 * 1024 * BITRATE_STEP)
+#define BITRATE_DEFAULT		(2 * 1024 * BITRATE_STEP)
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c b/drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c
new file mode 100644
index 000000000000..cbeb6a4608e2
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_dev_imx8q.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include "vpu.h"
+#include "vpu_imx8q.h"
+
+int vpu_imx8q_setup_dec(struct vpu_dev *vpu)
+{
+	const off_t offset = DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL;
+
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET, 0x1f);
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_RESET_SET, 0xffffffff);
+
+	return 0;
+}
+
+int vpu_imx8q_setup_enc(struct vpu_dev *vpu)
+{
+	return 0;
+}
+
+int vpu_imx8q_setup(struct vpu_dev *vpu)
+{
+	const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+
+	vpu_readl(vpu, offset + 0x108);
+
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET, 0x1);
+	vpu_writel(vpu, offset + 0x190, 0xffffffff);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_XMEM_RESET_SET, 0xffffffff);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET, 0xE);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_CACHE_RESET_SET, 0x7);
+	vpu_writel(vpu, XMEM_CONTROL, 0x102);
+
+	vpu_readl(vpu, offset + 0x108);
+
+	return 0;
+}
+
+static int vpu_imx8q_reset_enc(struct vpu_dev *vpu)
+{
+	return 0;
+}
+
+static int vpu_imx8q_reset_dec(struct vpu_dev *vpu)
+{
+	const off_t offset = DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL;
+
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_RESET_CLR, 0xffffffff);
+
+	return 0;
+}
+
+int vpu_imx8q_reset(struct vpu_dev *vpu)
+{
+	const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_CACHE_RESET_CLR, 0x7);
+	vpu_imx8q_reset_enc(vpu);
+	vpu_imx8q_reset_dec(vpu);
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_drv.c b/drivers/media/platform/imx/vpu-8q/vpu_drv.c
new file mode 100644
index 000000000000..c9c7168b99e4
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_drv.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/dma-map-ops.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <linux/of_reserved_mem.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/debugfs.h>
+#include "vpu.h"
+#include "vpu_imx8q.h"
+
+void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val)
+{
+	writel(val, vpu->base + reg);
+}
+
+u32 vpu_readl(struct vpu_dev *vpu, u32 reg)
+{
+	return readl(vpu->base + reg);
+}
+
+static void vpu_dev_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_vpu) == 1 && vpu->res->setup)
+		vpu->res->setup(vpu);
+}
+
+static void vpu_dev_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_vpu);
+}
+
+static void vpu_enc_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_enc) == 1 && vpu->res->setup_encoder)
+		vpu->res->setup_encoder(vpu);
+}
+
+static void vpu_enc_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_enc);
+}
+
+static void vpu_dec_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_dec) == 1 && vpu->res->setup_decoder)
+		vpu->res->setup_decoder(vpu);
+}
+
+static void vpu_dec_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_dec);
+}
+
+static int vpu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_dev *vpu;
+	struct resource *r;
+	int ret;
+
+	pr_info("vpu probe %s\n", pdev->dev.of_node->name);
+	vpu = devm_kzalloc(dev, sizeof(*vpu), GFP_KERNEL);
+	if (!vpu)
+		return -ENOMEM;
+
+	vpu->pdev = pdev;
+	vpu->dev = dev;
+	mutex_init(&vpu->lock);
+	INIT_LIST_HEAD(&vpu->cores);
+	platform_set_drvdata(pdev, vpu);
+	atomic_set(&vpu->ref_vpu, 0);
+	atomic_set(&vpu->ref_enc, 0);
+	atomic_set(&vpu->ref_dec, 0);
+	vpu->get_vpu = vpu_dev_get;
+	vpu->put_vpu = vpu_dev_put;
+	vpu->get_enc = vpu_enc_get;
+	vpu->put_enc = vpu_enc_put;
+	vpu->get_dec = vpu_dec_get;
+	vpu->put_dec = vpu_dec_put;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	vpu->base = devm_ioremap_resource(dev, r);
+	if (IS_ERR(vpu->base))
+		return PTR_ERR(vpu->base);
+
+	vpu->res = of_device_get_match_data(dev);
+	if (!vpu->res)
+		return -ENODEV;
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret)
+		goto err_runtime_disable;
+
+	pm_runtime_put_sync(dev);
+
+	ret = v4l2_device_register(dev, &vpu->v4l2_dev);
+	if (ret)
+		goto err_vpu_deinit;
+
+	vpu->debugfs = debugfs_create_dir("vpu", NULL);
+
+	of_platform_populate(dev->of_node, NULL, NULL, dev);
+
+	return 0;
+
+err_vpu_deinit:
+err_runtime_disable:
+	pm_runtime_set_suspended(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int vpu_remove(struct platform_device *pdev)
+{
+	struct vpu_dev *vpu = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	ret = pm_runtime_get_sync(dev);
+	WARN_ON(ret < 0);
+
+	debugfs_remove_recursive(vpu->debugfs);
+	vpu->debugfs = NULL;
+
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+	v4l2_device_unregister(&vpu->v4l2_dev);
+	mutex_destroy(&vpu->lock);
+
+	return 0;
+}
+
+static int __maybe_unused vpu_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops vpu_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
+};
+
+struct vpu_resources imx8qxp_res = {
+	.plat_type = IMX8QXP,
+	.mreg_base = 0x40000000,
+	.setup = vpu_imx8q_setup,
+	.setup_encoder = vpu_imx8q_setup_enc,
+	.setup_decoder = vpu_imx8q_setup_dec,
+	.reset = vpu_imx8q_reset
+};
+
+struct vpu_resources imx8qm_res = {
+	.plat_type = IMX8QM,
+	.mreg_base = 0x40000000,
+	.setup = vpu_imx8q_setup,
+	.setup_encoder = vpu_imx8q_setup_enc,
+	.setup_decoder = vpu_imx8q_setup_dec,
+	.reset = vpu_imx8q_reset
+};
+
+static const struct of_device_id vpu_dt_match[] = {
+	{ .compatible = "nxp,imx8qxp-vpu", .data = &imx8qxp_res },
+	{ .compatible = "nxp,imx8qm-vpu", .data = &imx8qm_res },
+	{}
+};
+MODULE_DEVICE_TABLE(of, vpu_dt_match);
+
+static struct platform_driver imx_vpu_driver = {
+	.probe = vpu_probe,
+	.remove = vpu_remove,
+	.driver = {
+		.name = "imx-vpu",
+		.of_match_table = vpu_dt_match,
+		.pm = &vpu_pm_ops,
+	},
+};
+module_platform_driver(imx_vpu_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/imx_vpu.h b/include/linux/imx_vpu.h
new file mode 100644
index 000000000000..9d6fe1366fbc
--- /dev/null
+++ b/include/linux/imx_vpu.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef __LINUX_IMX_VPU_H
+#define __LINUX_IMX_VPU_H
+
+#include <uapi/linux/imx_vpu.h>
+
+#endif
diff --git a/include/uapi/linux/imx_vpu.h b/include/uapi/linux/imx_vpu.h
new file mode 100644
index 000000000000..a616db8021b2
--- /dev/null
+++ b/include/uapi/linux/imx_vpu.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _UAPI__LINUX_IMX_VPU_H
+#define _UAPI__LINUX_IMX_VPU_H
+
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+/*imx v4l2 event*/
+/* error happened in dec/enc */
+#define V4L2_EVENT_CODEC_ERROR		(V4L2_EVENT_PRIVATE_START + 1)
+/* frame loss in dec/enc */
+#define V4L2_EVENT_SKIP			(V4L2_EVENT_PRIVATE_START + 2)
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:06 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:06 +0800
Subject: [PATCH v7 05/14] media: imx: imx8q: add vpu core driver
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <a28ce4a4235149b80abee7f6d2cf58049ae3e6be.1630377507.git.ming.qian@nxp.com>

The vpu support encoder and decoder.
And it need mu core to handle it.
Each core will run either encoder or decoder firmware.

This driver is for support the vpu core.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vpu_codec.h |  68 ++
 drivers/media/platform/imx/vpu-8q/vpu_core.c  | 911 ++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_core.h  |  16 +
 drivers/media/platform/imx/vpu-8q/vpu_dbg.c   | 496 ++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_log.h   |  44 +
 drivers/media/platform/imx/vpu-8q/vpu_rpc.c   | 257 +++++
 drivers/media/platform/imx/vpu-8q/vpu_rpc.h   | 463 +++++++++
 7 files changed, 2255 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_codec.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_core.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_core.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_dbg.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_log.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_rpc.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_rpc.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_codec.h b/drivers/media/platform/imx/vpu-8q/vpu_codec.h
new file mode 100644
index 000000000000..80fc5a12050e
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_codec.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_CODEC_H
+#define _IMX_VPU_CODEC_H
+
+struct vpu_encode_params {
+	u32 input_format;
+	u32 codec_format;
+	u32 profile;
+	u32 tier;
+	u32 level;
+	u32 frame_rate_num;
+	u32 frame_rate_den;
+	u32 src_stride;
+	u32 src_width;
+	u32 src_height;
+	struct v4l2_rect crop;
+	u32 out_width;
+	u32 out_height;
+
+	u32 gop_length;
+	u32 bframes;
+
+	u32 rc_mode;
+	u32 bitrate;
+	u32 bitrate_min;
+	u32 bitrate_max;
+
+	u32 i_frame_qp;
+	u32 p_frame_qp;
+	u32 b_frame_qp;
+	u32 qp_min;
+	u32 qp_max;
+	u32 qp_min_i;
+	u32 qp_max_i;
+
+	struct {
+		u32 enable;
+		u32 idc;
+		u32 width;
+		u32 height;
+	} sar;
+
+	struct {
+		u32 primaries;
+		u32 transfer;
+		u32 matrix;
+		u32 full_range;
+	} color;
+};
+
+struct vpu_decode_params {
+	u32 codec_format;
+	u32 output_format;
+	u32 b_dis_reorder;
+	u32 b_non_frame;
+	u32 frame_count;
+	u32 end_flag;
+	struct {
+		u32 base;
+		u32 size;
+	} udata;
+};
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_core.c b/drivers/media/platform/imx/vpu-8q/vpu_core.c
new file mode 100644
index 000000000000..38cdd07b7d98
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_core.c
@@ -0,0 +1,911 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"CORE"
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_domain.h>
+#include <linux/firmware.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_mbox.h"
+#include "vpu_msgs.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+#include "vpu_cmds.h"
+
+unsigned int vpu_dbg_level = LVL_ERR | LVL_WARN | LVL_INFO;
+module_param(vpu_dbg_level, uint, 0644);
+
+void csr_writel(struct vpu_core *core, u32 reg, u32 val)
+{
+	writel(val, core->base + reg);
+}
+
+u32 csr_readl(struct vpu_core *core, u32 reg)
+{
+	return readl(core->base + reg);
+}
+
+static int vpu_core_load_firmware(struct vpu_core *core)
+{
+	const struct firmware *pfw = NULL;
+	int ret = 0;
+
+	WARN_ON(!core || !core->res || !core->res->fwname);
+	if (!core->fw.virt) {
+		core_err(core, "firmware buffer is not ready\n");
+		return -EINVAL;
+	}
+
+	ret = request_firmware(&pfw, core->res->fwname, core->dev);
+	core_dbg(core, LVL_DEBUG, "request_firmware %s : %d\n", core->res->fwname, ret);
+	if (ret) {
+		core_err(core, "request firmware %s failed, ret = %d\n",
+				core->res->fwname, ret);
+		return ret;
+	}
+
+	if (core->fw.length < pfw->size) {
+		core_err(core, "firmware buffer size want %ld, but %d\n",
+				pfw->size, core->fw.length);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	memset_io(core->fw.virt, 0, core->fw.length);
+	memcpy(core->fw.virt, pfw->data, pfw->size);
+	core->fw.bytesused = pfw->size;
+	ret = vpu_iface_on_firmware_loaded(core);
+exit:
+	release_firmware(pfw);
+	pfw = NULL;
+
+	return ret;
+}
+
+static int vpu_core_wait_boot_done(struct vpu_core *core)
+{
+	int ret;
+	u32 fw_version;
+
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		core_err(core, "boot timeout\n");
+		return -EINVAL;
+	}
+
+	fw_version = vpu_iface_get_version(core);
+	core_dbg(core, LVL_WARN, "firmware version : %d.%d.%d\n",
+			(fw_version >> 16) & 0xff,
+			(fw_version >> 8) & 0xff,
+			fw_version & 0xff);
+	core->supported_instance_count = vpu_iface_get_max_instance_count(core);
+	if (core->res->act_size) {
+		u32 count = core->act.length / core->res->act_size;
+
+		core->supported_instance_count = min(core->supported_instance_count, count);
+	}
+	core->fw_version = fw_version;
+
+	return 0;
+}
+
+static int vpu_core_boot(struct vpu_core *core, bool load)
+{
+	int ret;
+
+	WARN_ON(!core);
+
+	if (!core->res->standalone)
+		return 0;
+
+	core_dbg(core, LVL_WARN, "boot\n");
+	reinit_completion(&core->cmp);
+	if (load) {
+		ret = vpu_core_load_firmware(core);
+		if (ret)
+			return ret;
+	}
+
+	vpu_iface_boot_core(core);
+	return vpu_core_wait_boot_done(core);
+}
+
+static int vpu_core_shutdown(struct vpu_core *core)
+{
+	if (!core->res->standalone)
+		return 0;
+	return vpu_iface_shutdown_core(core);
+}
+
+static int vpu_core_restore(struct vpu_core *core)
+{
+	if (!core->res->standalone)
+		return 0;
+	return vpu_iface_restore_core(core);
+}
+
+static int __vpu_alloc_dma(struct device *dev, struct vpu_buffer *buf)
+{
+	gfp_t gfp = GFP_KERNEL | GFP_DMA32;
+
+	WARN_ON(!dev || !buf);
+
+	if (!buf->length)
+		return 0;
+
+	buf->virt = dma_alloc_coherent(dev, buf->length, &buf->phys, gfp);
+	if (!buf->virt)
+		return -ENOMEM;
+
+	buf->dev = dev;
+
+	return 0;
+}
+
+void vpu_free_dma(struct vpu_buffer *buf)
+{
+	WARN_ON(!buf);
+
+	if (!buf->virt || !buf->dev)
+		return;
+
+	dma_free_coherent(buf->dev, buf->length, buf->virt, buf->phys);
+	buf->virt = NULL;
+	buf->phys = 0;
+	buf->length = 0;
+	buf->bytesused = 0;
+	buf->dev = NULL;
+}
+
+int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf)
+{
+	WARN_ON(!core || !buf);
+
+	return __vpu_alloc_dma(core->dev, buf);
+}
+
+static struct vpu_core *vpu_core_find_next_by_type(struct vpu_dev *vpu, u32 type)
+{
+	struct vpu_core *c;
+
+	WARN_ON(!vpu);
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		if (c->type == type)
+			return c;
+	}
+
+	return NULL;
+}
+
+int vpu_core_check_fmt(struct vpu_core *core, u32 pixelfmt)
+{
+	if (!core)
+		return -EINVAL;
+
+	if (vpu_iface_check_format(core, pixelfmt))
+		return 0;
+
+	return -EINVAL;
+}
+
+static void vpu_core_check_hang(struct vpu_core *core)
+{
+	if (core->hang_mask)
+		core->state = VPU_CORE_HANG;
+}
+
+static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 type)
+{
+	struct vpu_core *core = NULL;
+	int request_count = INT_MAX;
+	struct vpu_core *c;
+
+	WARN_ON(!vpu);
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		core_dbg(c, LVL_DEBUG, "instance_mask = 0x%lx, state = %d\n",
+				c->instance_mask,
+				c->state);
+		if (c->type != type)
+			continue;
+		if (c->state == VPU_CORE_DEINIT) {
+			core = c;
+			break;
+		}
+		vpu_core_check_hang(c);
+		if (c->state != VPU_CORE_ACTIVE)
+			continue;
+		if (c->request_count < request_count) {
+			request_count = c->request_count;
+			core = c;
+		}
+		if (!request_count)
+			break;
+	}
+
+	return core;
+}
+
+static bool vpu_core_is_exist(struct vpu_dev *vpu, struct vpu_core *core)
+{
+	struct vpu_core *c;
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		if (c == core)
+			return true;
+	}
+
+	return false;
+}
+
+static void vpu_core_get_vpu(struct vpu_core *core)
+{
+	core->vpu->get_vpu(core->vpu);
+	if (core->type == VPU_CORE_TYPE_ENC)
+		core->vpu->get_enc(core->vpu);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		core->vpu->get_dec(core->vpu);
+}
+
+static int vpu_core_register(struct device *dev, struct vpu_core *core)
+{
+	struct vpu_dev *vpu = dev_get_drvdata(dev);
+	int ret = 0;
+
+	core_dbg(core, LVL_DEBUG, "register core\n");
+	if (vpu_core_is_exist(vpu, core))
+		return 0;
+
+	core->workqueue = alloc_workqueue("vpu", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (!core->workqueue) {
+		core_err(core, "fail to alloc workqueue\n");
+		return -ENOMEM;
+	}
+	INIT_WORK(&core->msg_work, vpu_msg_run_work);
+	INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work);
+	core->msg_buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE);
+	core->msg_buffer = vzalloc(core->msg_buffer_size);
+	if (!core->msg_buffer) {
+		core_err(core, "failed allocate buffer for fifo\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+	ret = kfifo_init(&core->msg_fifo, core->msg_buffer, core->msg_buffer_size);
+	if (ret) {
+		core_err(core, "failed init kfifo\n");
+		goto error;
+	}
+
+	list_add_tail(&core->list, &vpu->cores);
+
+	vpu_core_get_vpu(core);
+
+	if (core->type == VPU_CORE_TYPE_ENC && !vpu->vdev_enc)
+		venc_create_video_device(vpu);
+	if (core->type == VPU_CORE_TYPE_DEC && !vpu->vdev_dec)
+		vdec_create_video_device(vpu);
+
+	return 0;
+error:
+	if (core->msg_buffer) {
+		vfree(core->msg_buffer);
+		core->msg_buffer = NULL;
+	}
+	if (core->workqueue) {
+		destroy_workqueue(core->workqueue);
+		core->workqueue = NULL;
+	}
+	return ret;
+}
+
+static void vpu_core_put_vpu(struct vpu_core *core)
+{
+	if (core->type == VPU_CORE_TYPE_ENC)
+		core->vpu->put_enc(core->vpu);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		core->vpu->put_dec(core->vpu);
+	core->vpu->put_vpu(core->vpu);
+}
+
+static int vpu_core_unregister(struct device *dev, struct vpu_core *core)
+{
+	struct vpu_dev *vpu = dev_get_drvdata(dev);
+
+	list_del_init(&core->list);
+
+	vpu_core_put_vpu(core);
+	core->vpu = NULL;
+	vfree(core->msg_buffer);
+	core->msg_buffer = NULL;
+
+	if (core->workqueue) {
+		cancel_work_sync(&core->msg_work);
+		cancel_delayed_work_sync(&core->msg_delayed_work);
+		destroy_workqueue(core->workqueue);
+		core->workqueue = NULL;
+	}
+
+	if (vpu_core_find_next_by_type(vpu, core->type))
+		return 0;
+
+	if (core->type == VPU_CORE_TYPE_ENC)
+		video_unregister_device(vpu->vdev_enc);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		video_unregister_device(vpu->vdev_dec);
+
+	return 0;
+}
+
+static int vpu_core_acquire_instance(struct vpu_core *core)
+{
+	int id;
+
+	WARN_ON(!core);
+
+	id = ffz(core->instance_mask);
+	if (id >= core->supported_instance_count)
+		return -EINVAL;
+
+	set_bit(id, &core->instance_mask);
+
+	return id;
+}
+
+static void vpu_core_release_instance(struct vpu_core *core, int id)
+{
+	WARN_ON(!core);
+
+	if (id < 0 || id >= core->supported_instance_count)
+		return;
+
+	clear_bit(id, &core->instance_mask);
+}
+
+struct vpu_inst *vpu_inst_get(struct vpu_inst *inst)
+{
+	if (!inst)
+		return NULL;
+
+	atomic_inc(&inst->ref_count);
+
+	return inst;
+}
+
+void vpu_inst_put(struct vpu_inst *inst)
+{
+	if (!inst)
+		return;
+	if (atomic_dec_and_test(&inst->ref_count)) {
+		if (inst->release)
+			inst->release(inst);
+	}
+}
+
+struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type)
+{
+	struct vpu_core *core = NULL;
+	int ret;
+
+	mutex_lock(&vpu->lock);
+
+	core = vpu_core_find_proper_by_type(vpu, type);
+	if (!core)
+		goto exit;
+
+	core_dbg(core, LVL_DEBUG, "is found\n");
+	mutex_lock(&core->lock);
+	pm_runtime_get_sync(core->dev);
+
+	if (core->state == VPU_CORE_DEINIT) {
+		ret = vpu_core_boot(core, true);
+		if (ret) {
+			pm_runtime_put_sync(core->dev);
+			mutex_unlock(&core->lock);
+			core = NULL;
+			goto exit;
+		}
+		core->state = VPU_CORE_ACTIVE;
+	}
+
+	core->request_count++;
+
+	mutex_unlock(&core->lock);
+exit:
+	mutex_unlock(&vpu->lock);
+
+	return core;
+}
+
+void vpu_release_core(struct vpu_core *core)
+{
+	if (!core)
+		return;
+
+	mutex_lock(&core->lock);
+	pm_runtime_put_sync(core->dev);
+	if (core->request_count)
+		core->request_count--;
+	mutex_unlock(&core->lock);
+}
+
+int vpu_inst_register(struct vpu_inst *inst)
+{
+	struct vpu_core *core;
+	int ret = 0;
+
+	WARN_ON(!inst || !inst->core);
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+	if (inst->id >= 0 && inst->id < core->supported_instance_count)
+		goto exit;
+
+	ret = vpu_core_acquire_instance(core);
+	if (ret < 0)
+		goto exit;
+
+	inst->id = ret;
+	list_add_tail(&inst->list, &core->instances);
+	ret = 0;
+	inst->pid = current->pid;
+	inst->tgid = current->tgid;
+	if (core->res->act_size) {
+		inst->act.phys = core->act.phys + core->res->act_size * inst->id;
+		inst->act.virt = core->act.virt + core->res->act_size * inst->id;
+		inst->act.length = core->res->act_size;
+	}
+	vpu_inst_create_dbgfs_file(inst);
+exit:
+	mutex_unlock(&core->lock);
+
+	if (ret)
+		core_err(core, "register instance fail\n");
+	return ret;
+}
+
+int vpu_inst_unregister(struct vpu_inst *inst)
+{
+	struct vpu_core *core;
+
+	WARN_ON(!inst);
+
+	core = inst->core;
+
+	vpu_clear_request(inst);
+	mutex_lock(&core->lock);
+	if (inst->id >= 0 && inst->id < core->supported_instance_count) {
+		vpu_inst_remove_dbgfs_file(inst);
+		list_del_init(&inst->list);
+		vpu_core_release_instance(core, inst->id);
+		inst->id = VPU_INST_NULL_ID;
+	}
+	vpu_core_check_hang(core);
+	if (core->state == VPU_CORE_HANG && !core->instance_mask) {
+		core_dbg(core, LVL_WARN, "reset hang core\n");
+		if (!vpu_core_sw_reset(core)) {
+			core->state = VPU_CORE_ACTIVE;
+			core->hang_mask = 0;
+		}
+	}
+	mutex_unlock(&core->lock);
+
+	return 0;
+}
+
+struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index)
+{
+	struct vpu_inst *inst = NULL;
+	struct vpu_inst *tmp;
+
+	mutex_lock(&core->lock);
+	if (!test_bit(index, &core->instance_mask))
+		goto exit;
+	list_for_each_entry(tmp, &core->instances, list) {
+		if (tmp->id == index) {
+			inst = vpu_inst_get(tmp);
+			break;
+		}
+	}
+exit:
+	mutex_unlock(&core->lock);
+
+	return inst;
+}
+
+static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np)
+{
+	struct device_node *node;
+	struct resource res;
+
+	if (of_count_phandle_with_args(np, "memory-region", NULL) < 2) {
+		core_err(core, "need 2 memory-region for boot and rpc\n");
+		return -ENODEV;
+	}
+
+	node = of_parse_phandle(np, "memory-region", 0);
+	if (!node) {
+		core_err(core, "boot-region of_parse_phandle error\n");
+		return -ENODEV;
+	}
+	if (of_address_to_resource(node, 0, &res)) {
+		core_err(core, "boot-region of_address_to_resource error\n");
+		return -EINVAL;
+	}
+	core->fw.phys = res.start;
+	core->fw.length = resource_size(&res);
+	core_dbg(core, LVL_INFO, "boot-region : <0x%llx, 0x%llx>\n",
+			res.start, resource_size(&res));
+
+	node = of_parse_phandle(np, "memory-region", 1);
+	if (!node) {
+		core_err(core, "rpc-region of_parse_phandle error\n");
+		return -ENODEV;
+	}
+	if (of_address_to_resource(node, 0, &res)) {
+		core_err(core, "rpc-region of_address_to_resource error\n");
+		return -EINVAL;
+	}
+	core->rpc.phys = res.start;
+	core->rpc.length = resource_size(&res);
+	core_dbg(core, LVL_DEBUG, "rpc-region : <0x%llx, 0x%llx>\n",
+			res.start, resource_size(&res));
+
+	if (core->rpc.length < core->res->rpc_size + core->res->fwlog_size) {
+		core_err(core, "the rpc-region <0x%llx, 0x%llx> is not enough\n",
+				res.start, resource_size(&res));
+		return -EINVAL;
+	}
+
+	core->fw.virt = ioremap_wc(core->fw.phys, core->fw.length);
+	core->rpc.virt = ioremap_wc(core->rpc.phys, core->rpc.length);
+	memset_io(core->rpc.virt, 0, core->rpc.length);
+
+	if (vpu_iface_check_memory_region(core,
+				core->rpc.phys,
+				core->rpc.length) != VPU_CORE_MEMORY_UNCACHED) {
+		core_err(core, "rpc region<0x%llx, 0x%x> isn't uncached\n",
+				core->rpc.phys,
+				core->rpc.length);
+		return -EINVAL;
+	}
+
+	core->log.phys = core->rpc.phys + core->res->rpc_size;
+	core->log.virt = core->rpc.virt + core->res->rpc_size;
+	core->log.length = core->res->fwlog_size;
+	core->act.phys = core->log.phys + core->log.length;
+	core->act.virt = core->log.virt + core->log.length;
+	core->act.length = core->rpc.length - core->res->rpc_size - core->log.length;
+	core->rpc.length = core->res->rpc_size;
+
+	return 0;
+}
+
+static int vpu_core_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_core *core;
+	struct vpu_dev *vpu = dev_get_drvdata(dev->parent);
+	struct vpu_shared_addr *iface;
+	u32 iface_data_size;
+	struct resource *r;
+	int ret;
+
+	vpu_dbg(LVL_WARN, "core %s probe\n", pdev->dev.of_node->name);
+	if (!vpu)
+		return -EINVAL;
+	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+
+	core->pdev = pdev;
+	core->dev = dev;
+	platform_set_drvdata(pdev, core);
+	core->vpu = vpu;
+	INIT_LIST_HEAD(&core->instances);
+	mutex_init(&core->lock);
+	mutex_init(&core->cmd_lock);
+	init_completion(&core->cmp);
+	init_waitqueue_head(&core->ack_wq);
+	core->state = VPU_CORE_DEINIT;
+
+	core->res = of_device_get_match_data(dev);
+	if (!core->res)
+		return -ENODEV;
+
+	core->type = core->res->type;
+	core->id = of_alias_get_id(dev->of_node, "vpu_core");
+	if (core->id < 0) {
+		vpu_err("can't get vpu core id\n");
+		return core->id;
+	}
+	ret = vpu_core_parse_dt(core, dev->of_node);
+	if (ret)
+		return ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		core_err(core, "fail to get core reg\n");
+		return -EINVAL;
+	}
+	core->base = devm_ioremap_resource(dev, r);
+	if (IS_ERR(core->base))
+		return PTR_ERR(core->base);
+	core_dbg(core, LVL_WARN, "reg : <0x%llx, 0x%llx>\n", r->start, resource_size(r));
+
+	if (!vpu_iface_check_codec(core)) {
+		core_err(core, "is not supported\n");
+		return -EINVAL;
+	}
+
+	ret = vpu_mbox_init(core);
+	if (ret)
+		return ret;
+
+	iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL);
+	if (!iface)
+		return -ENOMEM;
+
+	iface_data_size = vpu_iface_get_data_size(core);
+	if (iface_data_size) {
+		iface->priv = devm_kzalloc(dev, iface_data_size, GFP_KERNEL);
+		if (!iface->priv)
+			return -ENOMEM;
+	}
+
+	ret = vpu_iface_init(core, iface, &core->rpc, core->fw.phys);
+	if (ret) {
+		core_err(core, "init iface fail, ret = %d\n", ret);
+		return ret;
+	}
+
+	vpu_iface_config_system(core, vpu->res->mreg_base, vpu->base);
+	vpu_iface_set_log_buf(core, &core->log);
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret) {
+		pm_runtime_put_noidle(dev);
+		pm_runtime_set_suspended(dev);
+		goto err_runtime_disable;
+	}
+
+	if (vpu_iface_get_power_state(core))
+		ret = vpu_core_restore(core);
+	if (ret)
+		goto err_core_boot;
+
+	ret = vpu_core_register(dev->parent, core);
+	if (ret)
+		goto err_core_register;
+	core->parent = dev->parent;
+
+	pm_runtime_put_sync(dev);
+	vpu_core_create_dbgfs_file(core);
+
+	return 0;
+
+err_core_register:
+	vpu_core_shutdown(core);
+err_core_boot:
+	pm_runtime_put_sync(dev);
+err_runtime_disable:
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int vpu_core_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_core *core = platform_get_drvdata(pdev);
+	int ret;
+
+	vpu_core_remove_dbgfs_file(core);
+	ret = pm_runtime_get_sync(dev);
+	WARN_ON(ret < 0);
+
+	vpu_core_shutdown(core);
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+	vpu_core_unregister(core->parent, core);
+	iounmap(core->fw.virt);
+	iounmap(core->rpc.virt);
+	mutex_destroy(&core->lock);
+	mutex_destroy(&core->cmd_lock);
+
+	return 0;
+}
+
+static int __maybe_unused vpu_core_runtime_resume(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+
+	return vpu_mbox_request(core);
+}
+
+static int __maybe_unused vpu_core_runtime_suspend(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+
+	vpu_mbox_free(core);
+	return 0;
+}
+
+static void vpu_core_cancel_work(struct vpu_core *core)
+{
+	struct vpu_inst *inst = NULL;
+
+	cancel_work_sync(&core->msg_work);
+	cancel_delayed_work_sync(&core->msg_delayed_work);
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list)
+		cancel_work_sync(&inst->msg_work);
+	mutex_unlock(&core->lock);
+}
+
+static void vpu_core_resume_work(struct vpu_core *core)
+{
+	struct vpu_inst *inst = NULL;
+	unsigned long delay = msecs_to_jiffies(10);
+
+	queue_work(core->workqueue, &core->msg_work);
+	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list)
+		queue_work(inst->workqueue, &inst->msg_work);
+	mutex_unlock(&core->lock);
+}
+
+static int __maybe_unused vpu_core_resume(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (!core->res->standalone)
+		return 0;
+
+	mutex_lock(&core->lock);
+	pm_runtime_get_sync(dev);
+	vpu_core_get_vpu(core);
+	if (core->state != VPU_CORE_SNAPSHOT)
+		goto exit;
+
+	if (!vpu_iface_get_power_state(core)) {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_boot(core, false);
+			if (ret) {
+				core_err(core, "%s boot fail\n", __func__);
+				core->state = VPU_CORE_DEINIT;
+				goto exit;
+			}
+			core->state = VPU_CORE_ACTIVE;
+		} else {
+			core->state = VPU_CORE_DEINIT;
+		}
+	} else {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_sw_reset(core);
+			if (ret) {
+				core_err(core, "%s sw_reset fail\n", __func__);
+				core->state = VPU_CORE_HANG;
+				goto exit;
+			}
+		}
+		core->state = VPU_CORE_ACTIVE;
+	}
+
+exit:
+	pm_runtime_put_sync(dev);
+	mutex_unlock(&core->lock);
+
+	vpu_core_resume_work(core);
+	return ret;
+}
+
+static int __maybe_unused vpu_core_suspend(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (!core->res->standalone)
+		return 0;
+
+	mutex_lock(&core->lock);
+	if (core->state == VPU_CORE_ACTIVE) {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_snapshot(core);
+			if (ret) {
+				mutex_unlock(&core->lock);
+				return ret;
+			}
+		}
+
+		core->state = VPU_CORE_SNAPSHOT;
+	}
+	mutex_unlock(&core->lock);
+
+	vpu_core_cancel_work(core);
+
+	mutex_lock(&core->lock);
+	vpu_core_put_vpu(core);
+	mutex_unlock(&core->lock);
+	return ret;
+}
+
+static const struct dev_pm_ops vpu_core_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_core_runtime_suspend, vpu_core_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(vpu_core_suspend, vpu_core_resume)
+};
+
+static struct vpu_core_resources imx8q_enc = {
+	.type = VPU_CORE_TYPE_ENC,
+	.fwname = "vpu/vpu_fw_imx8_enc.bin",
+	.stride = 16,
+	.max_width = 1920,
+	.max_height = 1920,
+	.min_width = 64,
+	.min_height = 48,
+	.step_width = 2,
+	.step_height = 2,
+	.rpc_size = 0x80000,
+	.fwlog_size = 0x80000,
+	.act_size = 0xc0000,
+	.standalone = true,
+};
+
+static struct vpu_core_resources imx8q_dec = {
+	.type = VPU_CORE_TYPE_DEC,
+	.fwname = "vpu/vpu_fw_imx8_dec.bin",
+	.stride = 256,
+	.max_width = 8188,
+	.max_height = 8188,
+	.min_width = 16,
+	.min_height = 16,
+	.step_width = 1,
+	.step_height = 1,
+	.rpc_size = 0x80000,
+	.fwlog_size = 0x80000,
+	.standalone = true,
+};
+
+static const struct of_device_id vpu_core_dt_match[] = {
+	{ .compatible = "nxp,imx8q-vpu-encoder", .data = &imx8q_enc },
+	{ .compatible = "nxp,imx8q-vpu-decoder", .data = &imx8q_dec },
+	{}
+};
+MODULE_DEVICE_TABLE(of, vpu_core_dt_match);
+
+static struct platform_driver imx_vpu_core_driver = {
+	.probe = vpu_core_probe,
+	.remove = vpu_core_remove,
+	.driver = {
+		.name = "imx-vpu-core",
+		.of_match_table = vpu_core_dt_match,
+		.pm = &vpu_core_pm_ops,
+	},
+};
+module_platform_driver(imx_vpu_core_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX/MXC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_core.h b/drivers/media/platform/imx/vpu-8q/vpu_core.h
new file mode 100644
index 000000000000..86a628409144
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_core.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_CORE_H
+#define _IMX_VPU_CORE_H
+
+void csr_writel(struct vpu_core *core, u32 reg, u32 val);
+u32 csr_readl(struct vpu_core *core, u32 reg);
+int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf);
+void vpu_free_dma(struct vpu_buffer *buf);
+struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index);
+int vpu_core_check_fmt(struct vpu_core *core, u32 pixelfmt);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_dbg.c b/drivers/media/platform/imx/vpu-8q/vpu_dbg.c
new file mode 100644
index 000000000000..f90498546d0f
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_dbg.c
@@ -0,0 +1,496 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"DEBUG"
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-device.h>
+#include <linux/debugfs.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+
+struct print_buf_desc {
+	u32 start_h_phy;
+	u32 start_h_vir;
+	u32 start_m;
+	u32 bytes;
+	u32 read;
+	u32 write;
+	char buffer[0];
+};
+
+static char *vb2_stat_name[] = {
+	[VB2_BUF_STATE_DEQUEUED] = "dequeued",
+	[VB2_BUF_STATE_IN_REQUEST] = "in_request",
+	[VB2_BUF_STATE_PREPARING] = "preparing",
+	[VB2_BUF_STATE_QUEUED] = "queued",
+	[VB2_BUF_STATE_ACTIVE] = "active",
+	[VB2_BUF_STATE_DONE] = "done",
+	[VB2_BUF_STATE_ERROR] = "error",
+};
+
+static char *vpu_stat_name[] = {
+	[VPU_BUF_STATE_IDLE] = "idle",
+	[VPU_BUF_STATE_INUSE] = "inuse",
+	[VPU_BUF_STATE_DECODED] = "decoded",
+	[VPU_BUF_STATE_READY] = "ready",
+	[VPU_BUF_STATE_SKIP] = "skip",
+	[VPU_BUF_STATE_ERROR] = "error",
+};
+
+static int vpu_dbg_instance(struct seq_file *s, void *data)
+{
+	struct vpu_inst *inst = s->private;
+	char str[128];
+	int num;
+	struct vb2_queue *vq;
+	int i;
+
+	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(inst->type));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "state = %d\n", inst->state);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"min_buffer_out = %d, min_buffer_cap = %d\n",
+			inst->min_buffer_out, inst->min_buffer_cap);
+	if (seq_write(s, str, num))
+		return 0;
+
+
+	vq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	num = scnprintf(str, sizeof(str),
+			"output(%d) : fmt = %c%c%c%c %d x %d, %d;",
+			vb2_is_streaming(vq),
+			inst->out_format.pixfmt,
+			inst->out_format.pixfmt >> 8,
+			inst->out_format.pixfmt >> 16,
+			inst->out_format.pixfmt >> 24,
+			inst->out_format.width,
+			inst->out_format.height,
+			vq->last_buffer_dequeued);
+	if (seq_write(s, str, num))
+		return 0;
+	for (i = 0; i < inst->out_format.num_planes; i++) {
+		num = scnprintf(str, sizeof(str), " %d(%d)",
+				inst->out_format.sizeimage[i],
+				inst->out_format.bytesperline[i]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	if (seq_write(s, "\n", 1))
+		return 0;
+
+	vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	num = scnprintf(str, sizeof(str),
+			"capture(%d): fmt = %c%c%c%c %d x %d, %d;",
+			vb2_is_streaming(vq),
+			inst->cap_format.pixfmt,
+			inst->cap_format.pixfmt >> 8,
+			inst->cap_format.pixfmt >> 16,
+			inst->cap_format.pixfmt >> 24,
+			inst->cap_format.width,
+			inst->cap_format.height,
+			vq->last_buffer_dequeued);
+	if (seq_write(s, str, num))
+		return 0;
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		num = scnprintf(str, sizeof(str), " %d(%d)",
+				inst->cap_format.sizeimage[i],
+				inst->cap_format.bytesperline[i]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	if (seq_write(s, "\n", 1))
+		return 0;
+	num = scnprintf(str, sizeof(str), "crop: (%d, %d) %d x %d\n",
+			inst->crop.left,
+			inst->crop.top,
+			inst->crop.width,
+			inst->crop.height);
+	if (seq_write(s, str, num))
+		return 0;
+
+	vq = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	for (i = 0; i < vq->num_buffers; i++) {
+		struct vb2_buffer *vb = vq->bufs[i];
+		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+		struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+		if (vb->state == VB2_BUF_STATE_DEQUEUED)
+			continue;
+		num = scnprintf(str, sizeof(str),
+				"output [%2d] state = %10s, %8s\n",
+				i, vb2_stat_name[vb->state],
+				vpu_stat_name[vpu_buf->state]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	for (i = 0; i < vq->num_buffers; i++) {
+		struct vb2_buffer *vb = vq->bufs[i];
+		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+		struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+		if (vb->state == VB2_BUF_STATE_DEQUEUED)
+			continue;
+		num = scnprintf(str, sizeof(str),
+				"capture[%2d] state = %10s, %8s\n",
+				i, vb2_stat_name[vb->state],
+				vpu_stat_name[vpu_buf->state]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);
+	if (seq_write(s, str, num))
+		return 0;
+
+	if (inst->use_stream_buffer) {
+		num = scnprintf(str, sizeof(str), "stream_buffer = %d / %d, [0x%llx, 0x%llx]\n",
+				vpu_helper_get_used_space(inst),
+				inst->stream_buffer.length,
+				inst->stream_buffer.phys,
+				inst->stream_buffer.phys + inst->stream_buffer.length);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&inst->msg_fifo));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "flow :\n");
+	if (seq_write(s, str, num))
+		return 0;
+
+	mutex_lock(&inst->core->cmd_lock);
+	for (i = 0; i < ARRAY_SIZE(inst->flows); i++) {
+		u32 idx = (inst->flow_idx + i) % (ARRAY_SIZE(inst->flows));
+
+		if (!inst->flows[idx])
+			continue;
+		num = scnprintf(str, sizeof(str), "\t[%s]0x%x\n",
+				inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C",
+				inst->flows[idx]);
+		if (seq_write(s, str, num)) {
+			mutex_unlock(&inst->core->cmd_lock);
+			return 0;
+		}
+	}
+	mutex_unlock(&inst->core->cmd_lock);
+
+	i = 0;
+	while (true) {
+		num = call_vop(inst, get_debug_info, str, sizeof(str), i++);
+		if (num <= 0)
+			break;
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	return 0;
+}
+
+static int vpu_dbg_core(struct seq_file *s, void *data)
+{
+	struct vpu_core *core = s->private;
+	struct vpu_shared_addr *iface = core->iface;
+	char str[128];
+	int num;
+
+	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(core->type));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "boot_region  = <0x%08llx, 0x%x>\n",
+			core->fw.phys, core->fw.length);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "rpc_region   = <0x%08llx, 0x%x> used = 0x%x\n",
+			core->rpc.phys, core->rpc.length, core->rpc.bytesused);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "fwlog_region = <0x%08llx, 0x%x>\n",
+			core->log.phys, core->log.length);
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "state = %d\n", core->state);
+	if (seq_write(s, str, num))
+		return 0;
+	if (core->state == VPU_CORE_DEINIT)
+		return 0;
+	num = scnprintf(str, sizeof(str), "fw version = %d.%d.%d\n",
+				(core->fw_version >> 16) & 0xff,
+				(core->fw_version >> 8) & 0xff,
+				core->fw_version & 0xff);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "instances = %d/%d (0x%02lx), %d\n",
+			hweight32(core->instance_mask),
+			core->supported_instance_count,
+			core->instance_mask,
+			core->request_count);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&core->msg_fifo));
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"cmd_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
+			iface->cmd_desc->start,
+			iface->cmd_desc->end,
+			iface->cmd_desc->wptr,
+			iface->cmd_desc->rptr);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"msg_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
+			iface->msg_desc->start,
+			iface->msg_desc->end,
+			iface->msg_desc->wptr,
+			iface->msg_desc->rptr);
+	if (seq_write(s, str, num))
+		return 0;
+
+	return 0;
+}
+
+static int vpu_dbg_fwlog(struct seq_file *s, void *data)
+{
+	struct vpu_core *core = s->private;
+	struct print_buf_desc *print_buf;
+	int length;
+	u32 rptr;
+	u32 wptr;
+	int ret = 0;
+
+	if (!core->log.virt || core->state == VPU_CORE_DEINIT)
+		return 0;
+
+	print_buf = core->log.virt;
+	rptr = print_buf->read;
+	wptr = print_buf->write;
+
+	if (rptr == wptr)
+		return 0;
+	else if (rptr < wptr)
+		length = wptr - rptr;
+	else
+		length = print_buf->bytes + wptr - rptr;
+
+	if (s->count + length >= s->size) {
+		s->count = s->size;
+		return 0;
+	}
+
+	if (rptr + length >= print_buf->bytes) {
+		int num = print_buf->bytes - rptr;
+
+		if (seq_write(s, print_buf->buffer + rptr, num))
+			ret = -1;
+		length -= num;
+		rptr = 0;
+	}
+
+	if (length) {
+		if (seq_write(s, print_buf->buffer + rptr, length))
+			ret = -1;
+		rptr += length;
+	}
+	if (!ret)
+		print_buf->read = rptr;
+
+	return 0;
+}
+
+static int vpu_dbg_inst_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_instance, inode->i_private);
+}
+
+static ssize_t vpu_dbg_inst_write(struct file *file,
+			const char __user *user_buf, size_t size, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct vpu_inst *inst = s->private;
+
+	vpu_session_debug(inst);
+
+	return size;
+}
+
+static ssize_t vpu_dbg_core_write(struct file *file,
+			const char __user *user_buf, size_t size, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct vpu_core *core = s->private;
+
+	pm_runtime_get_sync(core->dev);
+	mutex_lock(&core->lock);
+	if (core->state != VPU_CORE_DEINIT && !core->instance_mask) {
+		core_dbg(core, LVL_INFO, "reset core\n");
+		if (!vpu_core_sw_reset(core)) {
+			core->state = VPU_CORE_ACTIVE;
+			core->hang_mask = 0;
+		}
+	}
+	mutex_unlock(&core->lock);
+	pm_runtime_put_sync(core->dev);
+
+	return size;
+}
+
+static int vpu_dbg_core_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_core, inode->i_private);
+}
+
+static int vpu_dbg_fwlog_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_fwlog, inode->i_private);
+}
+
+static const struct file_operations vpu_dbg_inst_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_inst_open,
+	.release = single_release,
+	.read = seq_read,
+	.write = vpu_dbg_inst_write,
+};
+
+static const struct file_operations vpu_dbg_core_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_core_open,
+	.release = single_release,
+	.read = seq_read,
+	.write = vpu_dbg_core_write,
+};
+
+static const struct file_operations vpu_dbg_fwlog_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_fwlog_open,
+	.release = single_release,
+	.read = seq_read,
+};
+
+int vpu_inst_create_dbgfs_file(struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu;
+	char name[64];
+
+	if (!inst || !inst->core || !inst->core->vpu)
+		return -EINVAL;
+
+	vpu = inst->core->vpu;
+	if (!vpu->debugfs)
+		return -EINVAL;
+
+	if (inst->debugfs)
+		return 0;
+
+	scnprintf(name, sizeof(name), "instance.%d.%d",
+			inst->core->id, inst->id);
+	inst->debugfs = debugfs_create_file((const char *)name,
+				VERIFY_OCTAL_PERMISSIONS(0644),
+				vpu->debugfs,
+				inst,
+				&vpu_dbg_inst_fops);
+	if (!inst->debugfs) {
+		vpu_err("vpu create debugfs %s fail\n", name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst)
+{
+	if (!inst)
+		return 0;
+
+	debugfs_remove(inst->debugfs);
+	inst->debugfs = NULL;
+
+	return 0;
+}
+
+int vpu_core_create_dbgfs_file(struct vpu_core *core)
+{
+	struct vpu_dev *vpu;
+	char name[64];
+
+	if (!core || !core->vpu)
+		return -EINVAL;
+
+	vpu = core->vpu;
+	if (!vpu->debugfs)
+		return -EINVAL;
+
+	if (!core->debugfs) {
+		scnprintf(name, sizeof(name), "core.%d", core->id);
+		core->debugfs = debugfs_create_file((const char *)name,
+					VERIFY_OCTAL_PERMISSIONS(0644),
+					vpu->debugfs,
+					core,
+					&vpu_dbg_core_fops);
+		if (!core->debugfs) {
+			vpu_err("vpu create debugfs %s fail\n", name);
+			return -EINVAL;
+		}
+	}
+	if (!core->debugfs_fwlog) {
+		scnprintf(name, sizeof(name), "fwlog.%d", core->id);
+		core->debugfs_fwlog = debugfs_create_file((const char *)name,
+					VERIFY_OCTAL_PERMISSIONS(0444),
+					vpu->debugfs,
+					core,
+					&vpu_dbg_fwlog_fops);
+		if (!core->debugfs_fwlog) {
+			vpu_err("vpu create debugfs %s fail\n", name);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int vpu_core_remove_dbgfs_file(struct vpu_core *core)
+{
+	if (!core)
+		return 0;
+	debugfs_remove(core->debugfs);
+	core->debugfs = NULL;
+	debugfs_remove(core->debugfs_fwlog);
+	core->debugfs_fwlog = NULL;
+
+	return 0;
+}
+
+void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow)
+{
+	if (!inst)
+		return;
+
+	inst->flows[inst->flow_idx] = flow;
+	inst->flow_idx = (inst->flow_idx + 1) % (ARRAY_SIZE(inst->flows));
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_log.h b/drivers/media/platform/imx/vpu-8q/vpu_log.h
new file mode 100644
index 000000000000..f21818749f4d
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_log.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_LOG_H
+#define _IMX_VPU_LOG_H
+
+#define LVL_ERR		(1 << 0)
+#define LVL_WARN	(1 << 1)
+#define LVL_INFO	(1 << 2)
+#define LVL_DEBUG	(1 << 3)
+#define LVL_IRQ		(1 << 4)
+#define LVL_CMD		(1 << 5)
+#define LVL_EVT		(1 << 6)
+#define LVL_CTRL	(1 << 7)
+#define LVL_TS		(1 << 8)
+#define LVL_FLOW	(1 << 13)
+
+extern unsigned int vpu_dbg_level;
+
+#ifdef TAG
+#define vpu_dbg(level, fmt, arg...) \
+	do { \
+		if ((vpu_dbg_level & (level)) || ((level) & LVL_ERR)) \
+			pr_info("[VPU "TAG"]"fmt, ## arg); \
+	} while (0)
+#else
+#define vpu_dbg(level, fmt, arg...) \
+	do { \
+		if ((vpu_dbg_level & (level)) || ((level) & LVL_ERR)) \
+			pr_info("[VPU]"fmt, ## arg); \
+	} while (0)
+#endif
+
+#define vpu_err(fmt, arg...)	vpu_dbg(LVL_ERR, fmt, ##arg)
+#define inst_dbg(inst, level, fmt, arg...)		\
+		vpu_dbg(level, "[%d:%d] "fmt, inst->core->id, inst->id, ## arg)
+#define inst_err(inst, fmt, arg...)	inst_dbg(inst, LVL_ERR, fmt, ## arg)
+#define core_dbg(core, level, fmt, arg...)		\
+		vpu_dbg(level, "[%d] %s "fmt, core->id, vpu_core_type_desc(core->type), ## arg)
+#define core_err(core, fmt, arg...)	core_dbg(core, LVL_ERR, fmt, ## arg)
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_rpc.c b/drivers/media/platform/imx/vpu-8q/vpu_rpc.c
new file mode 100644
index 000000000000..cdbc63d5bb3e
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_rpc.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"RPC"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/svc/misc.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_imx8q.h"
+#include "vpu_windsor.h"
+#include "vpu_malone.h"
+#include "vpu_log.h"
+
+u32 vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->check_memory_region)
+		return VPU_CORE_MEMORY_INVALID;
+
+	return ops->check_memory_region(core->fw.phys, addr, size);
+}
+
+static u32 vpu_rpc_check_buffer_space(struct vpu_rpc_buffer_desc *desc, bool write)
+{
+	u32 ptr1;
+	u32 ptr2;
+	u32 size;
+
+	WARN_ON(!desc);
+
+	size = desc->end - desc->start;
+	if (write) {
+		ptr1 = desc->wptr;
+		ptr2 = desc->rptr;
+	} else {
+		ptr1 = desc->rptr;
+		ptr2 = desc->wptr;
+	}
+
+	if (ptr1 == ptr2) {
+		if (!write)
+			return 0;
+		else
+			return size;
+	}
+
+	return (ptr2 + size - ptr1) % size;
+}
+
+static int vpu_rpc_send_cmd_buf(struct vpu_shared_addr *shared,
+			struct vpu_rpc_event *cmd)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 space = 0;
+	u32 *data;
+	u32 wptr;
+	u32 i;
+
+	WARN_ON(!shared || !shared->cmd_mem_vir || !cmd);
+
+	desc = shared->cmd_desc;
+	space = vpu_rpc_check_buffer_space(desc, true);
+	if (space < (((cmd->hdr.num + 1) << 2) + 16)) {
+		vpu_err("Cmd Buffer is no space for [%d] %d\n",
+				cmd->hdr.index, cmd->hdr.id);
+		return -EINVAL;
+	}
+	wptr = desc->wptr;
+	data = (u32 *)(shared->cmd_mem_vir + desc->wptr - desc->start);
+	*data = 0;
+	*data |= ((cmd->hdr.index & 0xff) << 24);
+	*data |= ((cmd->hdr.num & 0xff) << 16);
+	*data |= (cmd->hdr.id & 0x3fff);
+	wptr += 4;
+	data++;
+	if (wptr >= desc->end) {
+		wptr = desc->start;
+		data = shared->cmd_mem_vir;
+	}
+
+	for (i = 0; i < cmd->hdr.num; i++) {
+		*data = cmd->data[i];
+		wptr += 4;
+		data++;
+		if (wptr >= desc->end) {
+			wptr = desc->start;
+			data = shared->cmd_mem_vir;
+		}
+	}
+
+	/*update wptr after data is written*/
+	mb();
+	desc->wptr = wptr;
+
+	return 0;
+}
+
+static bool vpu_rpc_check_msg(struct vpu_shared_addr *shared)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 space = 0;
+	u32 msgword;
+	u32 msgnum;
+
+	WARN_ON(!shared || !shared->msg_desc);
+
+	desc = shared->msg_desc;
+	space = vpu_rpc_check_buffer_space(desc, 0);
+	space = (space >> 2);
+
+	if (space) {
+		msgword = *(u32 *)(shared->msg_mem_vir + desc->rptr - desc->start);
+		msgnum = (msgword & 0xff0000) >> 16;
+		if (msgnum <= space)
+			return true;
+	}
+
+	return false;
+}
+
+static int vpu_rpc_receive_msg_buf(struct vpu_shared_addr *shared, struct vpu_rpc_event *msg)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 *data;
+	u32 msgword;
+	u32 rptr;
+	u32 i;
+
+	WARN_ON(!shared || !shared->msg_desc || !msg);
+
+	if (!vpu_rpc_check_msg(shared))
+		return -EINVAL;
+
+	desc = shared->msg_desc;
+	data = (u32 *)(shared->msg_mem_vir + desc->rptr - desc->start);
+	rptr = desc->rptr;
+	msgword = *data;
+	data++;
+	rptr += 4;
+	if (rptr >= desc->end) {
+		rptr = desc->start;
+		data = shared->msg_mem_vir;
+	}
+
+	msg->hdr.index = (msgword >> 24) & 0xff;
+	msg->hdr.num = (msgword >> 16) & 0xff;
+	msg->hdr.id = msgword & 0x3fff;
+
+	for (i = 0; i < msg->hdr.num; i++) {
+		msg->data[i] = *data;
+		data++;
+		rptr += 4;
+		if (rptr >= desc->end) {
+			rptr = desc->start;
+			data = shared->msg_mem_vir;
+		}
+	}
+
+	/*update rptr after data is read*/
+	mb();
+	desc->rptr = rptr;
+
+	return 0;
+}
+
+struct vpu_iface_ops imx8q_rpc_ops[] = {
+	[VPU_CORE_TYPE_ENC] = {
+		.check_codec = vpu_imx8q_check_codec,
+		.check_fmt = vpu_imx8q_check_fmt,
+		.boot_core = vpu_imx8q_boot_core,
+		.get_power_state = vpu_imx8q_get_power_state,
+		.on_firmware_loaded = vpu_imx8q_on_firmware_loaded,
+		.get_data_size = vpu_windsor_get_data_size,
+		.check_memory_region = vpu_imx8q_check_memory_region,
+		.init_rpc = vpu_windsor_init_rpc,
+		.set_log_buf = vpu_windsor_set_log_buf,
+		.set_system_cfg = vpu_windsor_set_system_cfg,
+		.get_version = vpu_windsor_get_version,
+		.send_cmd_buf = vpu_rpc_send_cmd_buf,
+		.receive_msg_buf = vpu_rpc_receive_msg_buf,
+		.pack_cmd = vpu_windsor_pack_cmd,
+		.convert_msg_id = vpu_windsor_convert_msg_id,
+		.unpack_msg_data = vpu_windsor_unpack_msg_data,
+		.config_memory_resource = vpu_windsor_config_memory_resource,
+		.get_stream_buffer_size = vpu_windsor_get_stream_buffer_size,
+		.config_stream_buffer = vpu_windsor_config_stream_buffer,
+		.get_stream_buffer_desc = vpu_windsor_get_stream_buffer_desc,
+		.update_stream_buffer = vpu_windsor_update_stream_buffer,
+		.set_encode_params = vpu_windsor_set_encode_params,
+		.input_frame = vpu_windsor_input_frame,
+		.get_max_instance_count = vpu_windsor_get_max_instance_count,
+	},
+	[VPU_CORE_TYPE_DEC] = {
+		.check_codec = vpu_imx8q_check_codec,
+		.check_fmt = vpu_imx8q_check_fmt,
+		.boot_core = vpu_imx8q_boot_core,
+		.get_power_state = vpu_imx8q_get_power_state,
+		.on_firmware_loaded = vpu_imx8q_on_firmware_loaded,
+		.get_data_size = vpu_malone_get_data_size,
+		.check_memory_region = vpu_imx8q_check_memory_region,
+		.init_rpc = vpu_malone_init_rpc,
+		.set_log_buf = vpu_malone_set_log_buf,
+		.set_system_cfg = vpu_malone_set_system_cfg,
+		.get_version = vpu_malone_get_version,
+		.send_cmd_buf = vpu_rpc_send_cmd_buf,
+		.receive_msg_buf = vpu_rpc_receive_msg_buf,
+		.get_stream_buffer_size = vpu_malone_get_stream_buffer_size,
+		.config_stream_buffer = vpu_malone_config_stream_buffer,
+		.set_decode_params = vpu_malone_set_decode_params,
+		.pack_cmd = vpu_malone_pack_cmd,
+		.convert_msg_id = vpu_malone_convert_msg_id,
+		.unpack_msg_data = vpu_malone_unpack_msg_data,
+		.get_stream_buffer_desc = vpu_malone_get_stream_buffer_desc,
+		.update_stream_buffer = vpu_malone_update_stream_buffer,
+		.add_scode = vpu_malone_add_scode,
+		.input_frame = vpu_malone_input_frame,
+		.pre_send_cmd = vpu_malone_pre_cmd,
+		.post_send_cmd = vpu_malone_post_cmd,
+		.init_instance = vpu_malone_init_instance,
+		.get_max_instance_count = vpu_malone_get_max_instance_count,
+	},
+};
+
+struct vpu_iface_ops *vpu_iface_get(struct vpu_core *core)
+{
+	struct vpu_iface_ops *rpc_ops = NULL;
+	u32 size = 0;
+
+	WARN_ON(!core || !core->vpu || !core->vpu->res);
+
+	switch (core->vpu->res->plat_type) {
+	case IMX8QXP:
+	case IMX8QM:
+		rpc_ops = imx8q_rpc_ops;
+		size = ARRAY_SIZE(imx8q_rpc_ops);
+		break;
+	default:
+		return NULL;
+	}
+
+	if (core->type >= size)
+		return NULL;
+
+	return &rpc_ops[core->type];
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_rpc.h b/drivers/media/platform/imx/vpu-8q/vpu_rpc.h
new file mode 100644
index 000000000000..a2b009132eb5
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_rpc.h
@@ -0,0 +1,463 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_RPC_H
+#define _IMX_VPU_RPC_H
+
+#include <media/videobuf2-core.h>
+#include "vpu_codec.h"
+
+struct vpu_rpc_buffer_desc {
+	u32 wptr;
+	u32 rptr;
+	u32 start;
+	u32 end;
+};
+
+struct vpu_shared_addr {
+	void *iface;
+	struct vpu_rpc_buffer_desc *cmd_desc;
+	void *cmd_mem_vir;
+	struct vpu_rpc_buffer_desc *msg_desc;
+	void *msg_mem_vir;
+
+	unsigned long boot_addr;
+	struct vpu_core *core;
+	void *priv;
+};
+
+struct vpu_rpc_event_header {
+	u32 index;
+	u32 id;
+	u32 num;
+};
+
+struct vpu_rpc_event {
+	struct vpu_rpc_event_header hdr;
+	u32 data[256];
+};
+
+struct vpu_iface_ops {
+	bool (*check_codec)(enum vpu_core_type type);
+	bool (*check_fmt)(enum vpu_core_type type, u32 pixelfmt);
+	u32 (*get_data_size)(void);
+	u32 (*check_memory_region)(dma_addr_t base, dma_addr_t addr, u32 size);
+	int (*boot_core)(struct vpu_core *core);
+	int (*shutdown_core)(struct vpu_core *core);
+	int (*restore_core)(struct vpu_core *core);
+	int (*get_power_state)(struct vpu_core *core);
+	int (*on_firmware_loaded)(struct vpu_core *core);
+	void (*init_rpc)(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr);
+	void (*set_log_buf)(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log);
+	void (*set_system_cfg)(struct vpu_shared_addr *shared,
+			u32 regs_base, void __iomem *regs, u32 index);
+	void (*set_stream_cfg)(struct vpu_shared_addr *shared, u32 index);
+	u32 (*get_version)(struct vpu_shared_addr *shared);
+	u32 (*get_max_instance_count)(struct vpu_shared_addr *shared);
+	int (*get_stream_buffer_size)(struct vpu_shared_addr *shared);
+	int (*send_cmd_buf)(struct vpu_shared_addr *shared,
+			struct vpu_rpc_event *cmd);
+	int (*receive_msg_buf)(struct vpu_shared_addr *shared,
+			struct vpu_rpc_event *msg);
+	int (*pack_cmd)(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+	int (*convert_msg_id)(u32 msg_id);
+	int (*unpack_msg_data)(struct vpu_rpc_event *pkt, void *data);
+	int (*input_frame)(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*config_memory_resource)(struct vpu_shared_addr *shared,
+					u32 instance,
+					u32 type,
+					u32 index,
+					struct vpu_buffer *buf);
+	int (*config_stream_buffer)(struct vpu_shared_addr *shared,
+					u32 instance,
+					struct vpu_buffer *buf);
+	int (*update_stream_buffer)(struct vpu_shared_addr *shared,
+					u32 instance, u32 ptr, bool write);
+	int (*get_stream_buffer_desc)(struct vpu_shared_addr *shared,
+					u32 instance,
+					struct vpu_rpc_buffer_desc *desc);
+	int (*set_encode_params)(struct vpu_shared_addr *shared,
+			u32 instance,
+			struct vpu_encode_params *params, u32 update);
+	int (*set_decode_params)(struct vpu_shared_addr *shared,
+			u32 instance,
+			struct vpu_decode_params *params, u32 update);
+	int (*add_scode)(struct vpu_shared_addr *shared,
+				u32 instance,
+				struct vpu_buffer *stream_buffer,
+				u32 pixelformat,
+				u32 scode_type);
+	int (*pre_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
+	int (*post_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
+	int (*init_instance)(struct vpu_shared_addr *shared, u32 instance);
+};
+
+enum {
+	VPU_CORE_MEMORY_INVALID = 0,
+	VPU_CORE_MEMORY_CACHED,
+	VPU_CORE_MEMORY_UNCACHED
+};
+
+struct vpu_rpc_region_t {
+	dma_addr_t start;
+	dma_addr_t end;
+	dma_addr_t type;
+};
+
+struct vpu_iface_ops *vpu_iface_get(struct vpu_core *core);
+u32 vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size);
+
+static inline bool vpu_iface_check_codec(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->check_codec)
+		return ops->check_codec(core->type);
+
+	return true;
+}
+
+static inline bool vpu_iface_check_format(struct vpu_core *core, u32 pixelfmt)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->check_fmt)
+		return ops->check_fmt(core->type, pixelfmt);
+
+	return true;
+}
+
+static inline int vpu_iface_boot_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->boot_core)
+		return ops->boot_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_get_power_state(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->get_power_state)
+		return ops->get_power_state(core);
+	return 1;
+}
+
+static inline int vpu_iface_shutdown_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->shutdown_core)
+		return ops->shutdown_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_restore_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->restore_core)
+		return ops->restore_core(core);
+	return -EINVAL;
+}
+
+static inline int vpu_iface_on_firmware_loaded(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (ops && ops->on_firmware_loaded)
+		return ops->on_firmware_loaded(core);
+
+	return 0;
+}
+
+static inline u32 vpu_iface_get_data_size(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->get_data_size)
+		return 0;
+
+	return ops->get_data_size();
+}
+
+static inline int vpu_iface_init(struct vpu_core *core,
+				struct vpu_shared_addr *shared,
+				struct vpu_buffer *rpc,
+				dma_addr_t boot_addr)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->init_rpc)
+		return -EINVAL;
+
+	ops->init_rpc(shared, rpc, boot_addr);
+	core->iface = shared;
+	shared->core = core;
+	if (rpc->bytesused > rpc->length)
+		return -ENOSPC;
+	return 0;
+}
+
+static inline int vpu_iface_set_log_buf(struct vpu_core *core,
+					struct vpu_buffer *log)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops)
+		return -EINVAL;
+
+	if (ops->set_log_buf)
+		ops->set_log_buf(core->iface, log);
+
+	return 0;
+}
+
+static inline int vpu_iface_config_system(struct vpu_core *core,
+		u32 regs_base, void __iomem *regs)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops)
+		return -EINVAL;
+	if (ops->set_system_cfg)
+		ops->set_system_cfg(core->iface, regs_base, regs, core->id);
+
+	return 0;
+}
+
+static inline int vpu_iface_get_stream_buffer_size(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->get_stream_buffer_size)
+		return 0;
+
+	return ops->get_stream_buffer_size(core->iface);
+}
+
+static inline int vpu_iface_config_stream(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops)
+		return -EINVAL;
+	if (ops->set_stream_cfg)
+		ops->set_stream_cfg(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_send_cmd(struct vpu_core *core, struct vpu_rpc_event *cmd)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->send_cmd_buf)
+		return -EINVAL;
+
+	return ops->send_cmd_buf(core->iface, cmd);
+}
+
+static inline int vpu_iface_receive_msg(struct vpu_core *core, struct vpu_rpc_event *msg)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->receive_msg_buf)
+		return -EINVAL;
+
+	return ops->receive_msg_buf(core->iface, msg);
+}
+
+static inline int vpu_iface_pack_cmd(struct vpu_core *core,
+					struct vpu_rpc_event *pkt,
+					u32 index, u32 id, void *data)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->pack_cmd)
+		return -EINVAL;
+	return ops->pack_cmd(pkt, index, id, data);
+}
+
+static inline int vpu_iface_convert_msg_id(struct vpu_core *core, u32 msg_id)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->convert_msg_id)
+		return -EINVAL;
+
+	return ops->convert_msg_id(msg_id);
+}
+
+static inline int vpu_iface_unpack_msg_data(struct vpu_core *core,
+						struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->unpack_msg_data)
+		return -EINVAL;
+
+	return ops->unpack_msg_data(pkt, data);
+}
+
+static inline int vpu_iface_input_frame(struct vpu_inst *inst,
+						struct vb2_buffer *vb)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	if (!ops || !ops->input_frame)
+		return -EINVAL;
+
+	return ops->input_frame(inst->core->iface, inst, vb);
+}
+
+static inline int vpu_iface_config_memory_resource(struct vpu_inst *inst,
+			u32 type, u32 index, struct vpu_buffer *buf)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->config_memory_resource)
+		return -EINVAL;
+
+	return ops->config_memory_resource(inst->core->iface,
+					inst->id,
+					type, index, buf);
+}
+
+static inline int vpu_iface_config_stream_buffer(struct vpu_inst *inst,
+						struct vpu_buffer *buf)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->config_stream_buffer)
+		return -EINVAL;
+
+	return ops->config_stream_buffer(inst->core->iface, inst->id, buf);
+}
+
+static inline int vpu_iface_update_stream_buffer(struct vpu_inst *inst,
+						u32 ptr, bool write)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->update_stream_buffer)
+		return -EINVAL;
+
+	return ops->update_stream_buffer(inst->core->iface, inst->id, ptr, write);
+}
+
+static inline int vpu_iface_get_stream_buffer_desc(struct vpu_inst *inst,
+					struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->get_stream_buffer_desc)
+		return -EINVAL;
+
+	if (!desc)
+		return 0;
+
+	return ops->get_stream_buffer_desc(inst->core->iface, inst->id, desc);
+}
+
+static inline u32 vpu_iface_get_version(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->get_version)
+		return 0;
+
+	return ops->get_version(core->iface);
+}
+
+static inline u32 vpu_iface_get_max_instance_count(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(core);
+
+	if (!ops || !ops->get_max_instance_count)
+		return 0;
+
+	return ops->get_max_instance_count(core->iface);
+}
+
+static inline int vpu_iface_set_encode_params(struct vpu_inst *inst,
+				struct vpu_encode_params *params, u32 update)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->set_encode_params)
+		return -EINVAL;
+
+	return ops->set_encode_params(inst->core->iface, inst->id, params, update);
+}
+
+static inline int vpu_iface_set_decode_params(struct vpu_inst *inst,
+				struct vpu_decode_params *params, u32 update)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->set_decode_params)
+		return -EINVAL;
+
+	return ops->set_decode_params(inst->core->iface, inst->id, params, update);
+}
+
+static inline int vpu_iface_add_scode(struct vpu_inst *inst, u32 scode_type)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (!ops || !ops->add_scode)
+		return -EINVAL;
+
+	return ops->add_scode(inst->core->iface, inst->id,
+				&inst->stream_buffer,
+				inst->out_format.pixfmt,
+				scode_type);
+}
+
+static inline int vpu_iface_pre_send_cmd(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (ops && ops->pre_send_cmd)
+		return ops->pre_send_cmd(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_post_send_cmd(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (ops && ops->post_send_cmd)
+		return ops->post_send_cmd(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_init_instance(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_iface_get(inst->core);
+
+	WARN_ON(inst->id < 0);
+	if (ops && ops->init_instance)
+		return ops->init_instance(inst->core->iface, inst->id);
+
+	return 0;
+}
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:07 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:07 +0800
Subject: [PATCH v7 06/14] media: imx: imx8q: implement vpu core communication
 based on mailbox
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <0f6066d8b009d336dbdaf950dcdb13977885ca7d.1630377507.git.ming.qian@nxp.com>

driver use mailbox to communicate with vpu core.
and there are a command buffer and a message buffer.
driver will write commands to the command buffer,
then trigger a vpu core interrupt
vpu core will write messages to the message buffer,
then trigger a cpu interrupt.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vpu_cmds.c | 435 +++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_cmds.h |  25 ++
 drivers/media/platform/imx/vpu-8q/vpu_mbox.c | 126 ++++++
 drivers/media/platform/imx/vpu-8q/vpu_mbox.h |  16 +
 drivers/media/platform/imx/vpu-8q/vpu_msgs.c | 413 ++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_msgs.h |  14 +
 6 files changed, 1029 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_cmds.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_cmds.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_mbox.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_mbox.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_msgs.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_msgs.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_cmds.c b/drivers/media/platform/imx/vpu-8q/vpu_cmds.c
new file mode 100644
index 000000000000..6b371db63fa7
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_cmds.c
@@ -0,0 +1,435 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"CMD"
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_mbox.h"
+#include "vpu_log.h"
+
+struct vpu_cmd_request {
+	u32 request;
+	u32 response;
+	u32 handled;
+};
+
+struct vpu_cmd_t {
+	struct list_head list;
+	u32 id;
+	struct vpu_cmd_request *request;
+	struct vpu_rpc_event *pkt;
+	unsigned long key;
+};
+
+static struct vpu_cmd_request vpu_cmd_requests[] = {
+	{
+		.request = VPU_CMD_ID_CONFIGURE_CODEC,
+		.response = VPU_MSG_ID_MEM_REQUEST,
+		.handled = 1,
+	},
+	{
+		.request = VPU_CMD_ID_START,
+		.response = VPU_MSG_ID_START_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_STOP,
+		.response = VPU_MSG_ID_STOP_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_ABORT,
+		.response = VPU_MSG_ID_ABORT_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_RST_BUF,
+		.response = VPU_MSG_ID_BUF_RST,
+		.handled = 1,
+	},
+};
+
+static int vpu_cmd_send(struct vpu_core *core, struct vpu_rpc_event *pkt)
+{
+	int ret = 0;
+
+	WARN_ON(!core || !pkt);
+
+	ret = vpu_iface_send_cmd(core, pkt);
+	if (ret)
+		return ret;
+
+	/*write cmd data to cmd buffer before trigger a cmd interrupt*/
+	mb();
+	vpu_mbox_send_type(core, COMMAND);
+
+	return ret;
+}
+
+static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data)
+{
+	struct vpu_cmd_t *cmd;
+	int i;
+	int ret;
+
+	cmd = vzalloc(sizeof(*cmd));
+	if (!cmd)
+		return NULL;
+
+	cmd->pkt = vzalloc(sizeof(*cmd->pkt));
+	if (!cmd->pkt) {
+		vfree(cmd);
+		return NULL;
+	}
+
+	cmd->id = id;
+	ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data);
+	if (ret) {
+		inst_err(inst, "iface pack cmd(%d) fail\n", id);
+		vfree(cmd->pkt);
+		vfree(cmd);
+		return NULL;
+	}
+	for (i = 0; i < ARRAY_SIZE(vpu_cmd_requests); i++) {
+		if (vpu_cmd_requests[i].request == id) {
+			cmd->request = &vpu_cmd_requests[i];
+			break;
+		}
+	}
+
+	return cmd;
+}
+
+static void vpu_free_cmd(struct vpu_cmd_t *cmd)
+{
+	if (!cmd)
+		return;
+	if (cmd->pkt)
+		vfree(cmd->pkt);
+	vfree(cmd);
+}
+
+static int vpu_session_process_cmd(struct vpu_inst *inst, struct vpu_cmd_t *cmd)
+{
+	int ret;
+
+	if (!inst || !cmd || !cmd->pkt)
+		return -EINVAL;
+
+	inst_dbg(inst, LVL_CMD, "send cmd(%d)\n", cmd->id);
+	vpu_iface_pre_send_cmd(inst);
+	ret = vpu_cmd_send(inst->core, cmd->pkt);
+	if (!ret) {
+		vpu_iface_post_send_cmd(inst);
+		vpu_inst_record_flow(inst, cmd->id);
+	} else {
+		inst_err(inst, "iface send cmd(%d) fail\n", cmd->id);
+	}
+
+	return ret;
+}
+
+static void vpu_process_cmd_request(struct vpu_inst *inst)
+{
+	struct vpu_cmd_t *cmd;
+	struct vpu_cmd_t *tmp;
+
+	if (!inst || inst->pending)
+		return;
+
+	list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+		list_del_init(&cmd->list);
+		if (vpu_session_process_cmd(inst, cmd))
+			inst_err(inst, "process cmd(%d) fail\n", cmd->id);
+		if (cmd->request) {
+			inst->pending = (void *)cmd;
+			break;
+		}
+		vpu_free_cmd(cmd);
+	}
+}
+
+static int vpu_request_cmd(struct vpu_inst *inst, u32 id, void *data,
+		unsigned long *key, int *sync)
+{
+	struct vpu_core *core;
+	struct vpu_cmd_t *cmd;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+	cmd = vpu_alloc_cmd(inst, id, data);
+	if (!cmd)
+		return -ENOMEM;
+
+	mutex_lock(&core->cmd_lock);
+	cmd->key = core->cmd_seq++;
+	if (key)
+		*key = cmd->key;
+	if (sync)
+		*sync = cmd->request ? true : false;
+	list_add_tail(&cmd->list, &inst->cmd_q);
+	vpu_process_cmd_request(inst);
+	mutex_unlock(&core->cmd_lock);
+
+	return 0;
+}
+
+static void vpu_clear_pending(struct vpu_inst *inst)
+{
+	if (!inst || !inst->pending)
+		return;
+
+	vpu_free_cmd(inst->pending);
+	wake_up_all(&inst->core->ack_wq);
+	inst->pending = NULL;
+}
+
+static bool vpu_check_response(struct vpu_cmd_t *cmd, u32 response, u32 handled)
+{
+	struct vpu_cmd_request *request;
+
+	if (!cmd || !cmd->request)
+		return false;
+
+	request = cmd->request;
+	if (request->response != response)
+		return false;
+	if (request->handled != handled)
+		return false;
+
+	return true;
+}
+
+int vpu_response_cmd(struct vpu_inst *inst, u32 response, u32 handled)
+{
+	struct vpu_core *core;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->cmd_lock);
+	if (vpu_check_response(inst->pending, response, handled))
+		vpu_clear_pending(inst);
+
+	vpu_process_cmd_request(inst);
+	mutex_unlock(&core->cmd_lock);
+
+	return 0;
+}
+
+void vpu_clear_request(struct vpu_inst *inst)
+{
+	struct vpu_cmd_t *cmd;
+	struct vpu_cmd_t *tmp;
+
+	mutex_lock(&inst->core->cmd_lock);
+	if (inst->pending)
+		vpu_clear_pending(inst);
+
+	list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+		list_del_init(&cmd->list);
+		vpu_free_cmd(cmd);
+	}
+	mutex_unlock(&inst->core->cmd_lock);
+}
+
+static bool check_is_responsed(struct vpu_inst *inst, unsigned long key)
+{
+	struct vpu_core *core = inst->core;
+	struct vpu_cmd_t *cmd;
+	bool flag = true;
+
+	mutex_lock(&core->cmd_lock);
+	cmd = inst->pending;
+	if (cmd && key == cmd->key) {
+		flag = false;
+		goto exit;
+	}
+	list_for_each_entry(cmd, &inst->cmd_q, list) {
+		if (key == cmd->key) {
+			flag = false;
+			break;
+		}
+	}
+exit:
+	mutex_unlock(&core->cmd_lock);
+
+	return flag;
+}
+
+static int sync_session_response(struct vpu_inst *inst, unsigned long key)
+{
+	struct vpu_core *core;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+
+	call_vop(inst, wait_prepare);
+	wait_event_timeout(core->ack_wq,
+			check_is_responsed(inst, key),
+			VPU_TIMEOUT);
+	call_vop(inst, wait_finish);
+
+	if (!check_is_responsed(inst, key)) {
+		inst_err(inst, "sync session timeout\n");
+		set_bit(inst->id, &core->hang_mask);
+		mutex_lock(&inst->core->cmd_lock);
+		vpu_clear_pending(inst);
+		mutex_unlock(&inst->core->cmd_lock);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+{
+	unsigned long key;
+	int sync = false;
+	int ret = -EINVAL;
+
+	WARN_ON(!inst || !inst->core || inst->id < 0);
+
+	ret = vpu_request_cmd(inst, id, data, &key, &sync);
+	if (!ret && sync)
+		ret = sync_session_response(inst, key);
+
+	if (ret)
+		inst_err(inst, "send cmd(%d) fail\n", id);
+
+	return ret;
+}
+
+int vpu_session_configure_codec(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_CONFIGURE_CODEC, NULL);
+}
+
+int vpu_session_start(struct vpu_inst *inst)
+{
+	inst_dbg(inst, LVL_FLOW, "send start cmd\n");
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_START, NULL);
+}
+
+int vpu_session_stop(struct vpu_inst *inst)
+{
+	inst_dbg(inst, LVL_FLOW, "send stop cmd\n");
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_STOP, NULL);
+}
+
+int vpu_session_encode_frame(struct vpu_inst *inst, s64 timestamp)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FRAME_ENCODE, &timestamp);
+}
+
+int vpu_session_alloc_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FS_ALLOC, fs);
+}
+
+int vpu_session_release_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FS_RELEASE, fs);
+}
+
+int vpu_session_abort(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_ABORT, NULL);
+}
+
+int vpu_session_rst_buf(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_RST_BUF, NULL);
+}
+
+int vpu_session_fill_timestamp(struct vpu_inst *inst, struct vpu_ts_info *info)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_TIMESTAMP, info);
+}
+
+int vpu_session_update_parameters(struct vpu_inst *inst, void *arg)
+{
+	if (inst->type & VPU_CORE_TYPE_DEC)
+		vpu_iface_set_decode_params(inst, arg, 1);
+	else
+		vpu_iface_set_encode_params(inst, arg, 1);
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_UPDATE_PARAMETER, arg);
+}
+
+int vpu_session_debug(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_DEBUG, NULL);
+}
+
+int vpu_core_snapshot(struct vpu_core *core)
+{
+	struct vpu_inst *inst;
+	int ret;
+
+	WARN_ON(!core || list_empty(&core->instances));
+
+	inst = list_first_entry(&core->instances, struct vpu_inst, list);
+
+	reinit_completion(&core->cmp);
+	ret = vpu_session_send_cmd(inst, VPU_CMD_ID_SNAPSHOT, NULL);
+	if (ret)
+		return ret;
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		vpu_err("core[%d] snapshot timeout\n", core->id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_core_sw_reset(struct vpu_core *core)
+{
+	struct vpu_rpc_event pkt;
+	int ret;
+
+	WARN_ON(!core);
+
+	memset(&pkt, 0, sizeof(pkt));
+	vpu_iface_pack_cmd(core, &pkt, 0, VPU_CMD_ID_FIRM_RESET, NULL);
+
+	reinit_completion(&core->cmp);
+	mutex_lock(&core->cmd_lock);
+	ret = vpu_cmd_send(core, &pkt);
+	mutex_unlock(&core->cmd_lock);
+	if (ret)
+		return ret;
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		vpu_err("core[%d] sw reset timeout\n", core->id);
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_cmds.h b/drivers/media/platform/imx/vpu-8q/vpu_cmds.h
new file mode 100644
index 000000000000..e45f4a67ac37
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_cmds.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_CMDS_H
+#define _IMX_VPU_CMDS_H
+
+int vpu_session_configure_codec(struct vpu_inst *inst);
+int vpu_session_start(struct vpu_inst *inst);
+int vpu_session_stop(struct vpu_inst *inst);
+int vpu_session_abort(struct vpu_inst *inst);
+int vpu_session_rst_buf(struct vpu_inst *inst);
+int vpu_session_encode_frame(struct vpu_inst *inst, s64 timestamp);
+int vpu_session_alloc_fs(struct vpu_inst *inst, struct vpu_fs_info *fs);
+int vpu_session_release_fs(struct vpu_inst *inst, struct vpu_fs_info *fs);
+int vpu_session_fill_timestamp(struct vpu_inst *inst, struct vpu_ts_info *info);
+int vpu_session_update_parameters(struct vpu_inst *inst, void *arg);
+int vpu_core_snapshot(struct vpu_core *core);
+int vpu_core_sw_reset(struct vpu_core *core);
+int vpu_response_cmd(struct vpu_inst *inst, u32 response, u32 handled);
+void vpu_clear_request(struct vpu_inst *inst);
+int vpu_session_debug(struct vpu_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_mbox.c b/drivers/media/platform/imx/vpu-8q/vpu_mbox.c
new file mode 100644
index 000000000000..5f926837932f
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_mbox.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"MBOX"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include "vpu.h"
+#include "vpu_mbox.h"
+#include "vpu_msgs.h"
+#include "vpu_log.h"
+
+static void vpu_mbox_rx_callback(struct mbox_client *cl, void *msg)
+{
+	struct vpu_mbox *rx = container_of(cl, struct vpu_mbox, cl);
+	struct vpu_core *core = container_of(rx, struct vpu_core, rx);
+
+	vpu_isr(core, *(u32 *)msg);
+}
+
+static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox)
+{
+	struct mbox_chan *ch;
+	struct mbox_client *cl;
+
+	if (!dev || !mbox)
+		return -EINVAL;
+	if (mbox->ch)
+		return 0;
+
+	cl = &mbox->cl;
+	cl->dev = dev;
+	if (mbox->block) {
+		cl->tx_block = true;
+		cl->tx_tout = 1000;
+	} else {
+		cl->tx_block = false;
+	}
+	cl->knows_txdone = false;
+	cl->rx_callback = vpu_mbox_rx_callback;
+
+	ch = mbox_request_channel_byname(cl, mbox->name);
+	if (IS_ERR(ch)) {
+		vpu_err("Failed to request mbox chan %s, ret : %ld\n",
+				mbox->name, PTR_ERR(ch));
+		return PTR_ERR(ch);
+	}
+
+	mbox->ch = ch;
+	return 0;
+}
+
+int vpu_mbox_init(struct vpu_core *core)
+{
+	WARN_ON(!core);
+
+	scnprintf(core->tx_type.name, sizeof(core->tx_type.name) - 1, "tx0");
+	core->tx_type.block = true;
+
+	scnprintf(core->tx_data.name, sizeof(core->tx_data.name) - 1, "tx1");
+	core->tx_data.block = false;
+
+	scnprintf(core->rx.name, sizeof(core->rx.name) - 1, "rx");
+	core->rx.block = true;
+
+	return 0;
+}
+
+int vpu_mbox_request(struct vpu_core *core)
+{
+	int ret;
+
+	WARN_ON(!core);
+
+	ret = vpu_mbox_request_channel(core->dev, &core->tx_type);
+	if (ret)
+		goto error;
+	ret = vpu_mbox_request_channel(core->dev, &core->tx_data);
+	if (ret)
+		goto error;
+	ret = vpu_mbox_request_channel(core->dev, &core->rx);
+	if (ret)
+		goto error;
+
+	vpu_dbg(LVL_DEBUG, "mbox request\n");
+	return 0;
+error:
+	vpu_mbox_free(core);
+	return ret;
+}
+
+void vpu_mbox_free(struct vpu_core *core)
+{
+	WARN_ON(!core);
+
+	mbox_free_channel(core->tx_type.ch);
+	mbox_free_channel(core->tx_data.ch);
+	mbox_free_channel(core->rx.ch);
+	core->tx_type.ch = NULL;
+	core->tx_data.ch = NULL;
+	core->rx.ch = NULL;
+	vpu_dbg(LVL_DEBUG, "mbox free\n");
+}
+
+void vpu_mbox_send_type(struct vpu_core *core, u32 type)
+{
+	mbox_send_message(core->tx_type.ch, &type);
+}
+
+void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data)
+{
+	mbox_send_message(core->tx_data.ch, &data);
+	mbox_send_message(core->tx_type.ch, &type);
+}
+
+void vpu_mbox_enable_rx(struct vpu_dev *dev)
+{
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_mbox.h b/drivers/media/platform/imx/vpu-8q/vpu_mbox.h
new file mode 100644
index 000000000000..3893ad3a4f7a
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_mbox.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_MBOX_H
+#define _IMX_VPU_MBOX_H
+
+int vpu_mbox_init(struct vpu_core *core);
+int vpu_mbox_request(struct vpu_core *core);
+void vpu_mbox_free(struct vpu_core *core);
+void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data);
+void vpu_mbox_send_type(struct vpu_core *core, u32 type);
+void vpu_mbox_enable_rx(struct vpu_dev *dev);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_msgs.c b/drivers/media/platform/imx/vpu-8q/vpu_msgs.c
new file mode 100644
index 000000000000..8163971dbc2f
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_msgs.c
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"MSG"
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_rpc.h"
+#include "vpu_mbox.h"
+#include "vpu_defs.h"
+#include "vpu_cmds.h"
+#include "vpu_msgs.h"
+#include "vpu_v4l2.h"
+#include "vpu_log.h"
+
+#define VPU_PKT_HEADER_LENGTH		3
+
+struct vpu_msg_handler {
+	u32 id;
+	void (*done)(struct vpu_inst *inst, struct vpu_rpc_event *pkt);
+};
+
+static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	WARN_ON(!inst || !inst->core);
+
+	inst_dbg(inst, LVL_FLOW, "start done\n");
+}
+
+static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_pkt_mem_req_data req_data;
+
+	WARN_ON(!inst || !inst->core || !inst->ops);
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data);
+	inst_dbg(inst, LVL_FLOW, "mem request event : %d:%d %d:%d %d:%d\n",
+				req_data.enc_frame_size,
+				req_data.enc_frame_num,
+				req_data.ref_frame_size,
+				req_data.ref_frame_num,
+				req_data.act_buf_size,
+				req_data.act_buf_num);
+	call_vop(inst, mem_request,
+				req_data.enc_frame_size,
+				req_data.enc_frame_num,
+				req_data.ref_frame_size,
+				req_data.ref_frame_num,
+				req_data.act_buf_size,
+				req_data.act_buf_num);
+}
+
+static void vpu_session_handle_stop_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	WARN_ON(!inst || !inst->core);
+
+	inst_dbg(inst, LVL_FLOW, "stop done\n");
+
+	call_vop(inst, stop_done);
+}
+
+static void vpu_session_handle_seq_hdr(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_codec_info info;
+
+	WARN_ON(!inst || !inst->core);
+
+	info.stride = inst->core->res->stride;
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	call_vop(inst, event_notify, VPU_MSG_ID_SEQ_HDR_FOUND, &info);
+}
+
+static void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	WARN_ON(!inst || !inst->core);
+
+	call_vop(inst, event_notify, VPU_MSG_ID_RES_CHANGE, NULL);
+}
+
+static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_enc_pic_info info;
+
+	WARN_ON(!inst || !inst->core);
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	inst_dbg(inst, LVL_DEBUG, "frame id = %d, wptr = 0x%x, size = %d\n",
+			info.frame_id, info.wptr, info.frame_size);
+	call_vop(inst, get_one_frame, &info);
+}
+
+static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_fs_info fs;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+	call_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs);
+}
+
+static void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+
+	WARN_ON(!inst || !inst->core);
+
+	if (inst->core->type == VPU_CORE_TYPE_ENC) {
+		struct vpu_frame_info info;
+
+		memset(&info, 0, sizeof(info));
+		vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info.sequence);
+		inst_dbg(inst, LVL_DEBUG, "frame release:%d\n", info.sequence);
+		info.type = inst->out_format.type;
+		call_vop(inst, buf_done, &info);
+	} else if (inst->core->type == VPU_CORE_TYPE_DEC) {
+		struct vpu_fs_info fs;
+
+		vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+		call_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs);
+	}
+}
+
+static void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+
+	WARN_ON(!inst || !inst->core);
+
+	inst_dbg(inst, LVL_DEBUG, "frame input done\n");
+	call_vop(inst, input_done);
+}
+
+static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_pic_info info;
+
+	WARN_ON(!inst || !inst->core);
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	call_vop(inst, get_one_frame, &info);
+}
+
+static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_pic_info info;
+	struct vpu_frame_info frame;
+
+	WARN_ON(!inst || !inst->core);
+
+	memset(&frame, 0, sizeof(frame));
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	if (inst->core->type == VPU_CORE_TYPE_DEC)
+		frame.type = inst->cap_format.type;
+	frame.id = info.id;
+	frame.luma = info.luma;
+	frame.skipped = info.skipped;
+	frame.timestamp = info.timestamp;
+
+	call_vop(inst, buf_done, &frame);
+}
+
+static void vpu_session_handle_eos(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	call_vop(inst, event_notify, VPU_MSG_ID_PIC_EOS, NULL);
+}
+
+static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	call_vop(inst, event_notify, VPU_MSG_ID_UNSUPPORTED, NULL);
+	vpu_notify_codec_error(inst);
+}
+
+static void vpu_session_handle_firmware_xcpt(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	char *str = (char *)pkt->data;
+
+	inst_err(inst, "%s firmware xcpt: %s\n",
+			vpu_core_type_desc(inst->core->type), str);
+	call_vop(inst, event_notify, VPU_MSG_ID_FIRMWARE_XCPT, NULL);
+	set_bit(inst->id, &inst->core->hang_mask);
+	vpu_notify_codec_error(inst);
+}
+
+struct vpu_msg_handler handlers[] = {
+	{VPU_MSG_ID_START_DONE, vpu_session_handle_start_done},
+	{VPU_MSG_ID_STOP_DONE, vpu_session_handle_stop_done},
+	{VPU_MSG_ID_MEM_REQUEST, vpu_session_handle_mem_request},
+	{VPU_MSG_ID_SEQ_HDR_FOUND, vpu_session_handle_seq_hdr},
+	{VPU_MSG_ID_RES_CHANGE, vpu_session_handle_resolution_change},
+	{VPU_MSG_ID_FRAME_INPUT_DONE, vpu_session_handle_input_done},
+	{VPU_MSG_ID_FRAME_REQ, vpu_session_handle_frame_request},
+	{VPU_MSG_ID_FRAME_RELEASE, vpu_session_handle_frame_release},
+	{VPU_MSG_ID_ENC_DONE, vpu_session_handle_enc_frame_done},
+	{VPU_MSG_ID_PIC_DECODED, vpu_session_handle_pic_decoded},
+	{VPU_MSG_ID_DEC_DONE, vpu_session_handle_pic_done},
+	{VPU_MSG_ID_PIC_EOS, vpu_session_handle_eos},
+	{VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error},
+	{VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt},
+};
+
+static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *msg)
+{
+	int ret;
+	u32 msg_id;
+	struct vpu_msg_handler *handler = NULL;
+	unsigned int i;
+
+	ret = vpu_iface_convert_msg_id(inst->core, msg->hdr.id);
+	if (ret < 0)
+		return -EINVAL;
+
+	msg_id = ret;
+	inst_dbg(inst, LVL_EVT, "receive event(%d)\n", msg_id);
+
+	for (i = 0; i < ARRAY_SIZE(handlers); i++) {
+		if (handlers[i].id == msg_id) {
+			handler = &handlers[i];
+			break;
+		}
+	}
+
+	if (handler && handler->done)
+		handler->done(inst, msg);
+
+	vpu_response_cmd(inst, msg_id, 1);
+
+	return 0;
+}
+
+static bool vpu_inst_receive_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	u32 bytes = sizeof(struct vpu_rpc_event_header);
+	u32 ret;
+
+	memset(pkt, 0, sizeof(*pkt));
+	if (kfifo_len(&inst->msg_fifo) < bytes)
+		return false;
+
+	ret = kfifo_out(&inst->msg_fifo, pkt, bytes);
+	if (ret != bytes)
+		return false;
+
+	if (pkt->hdr.num > 0) {
+		bytes = pkt->hdr.num * sizeof(u32);
+		ret = kfifo_out(&inst->msg_fifo, pkt->data, bytes);
+		if (ret != bytes)
+			return false;
+	}
+
+	return true;
+}
+
+void vpu_inst_run_work(struct work_struct *work)
+{
+	struct vpu_inst *inst = container_of(work, struct vpu_inst, msg_work);
+	struct vpu_rpc_event pkt;
+
+	while (vpu_inst_receive_msg(inst, &pkt))
+		vpu_session_handle_msg(inst, &pkt);
+}
+
+static void vpu_inst_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	u32 bytes;
+	u32 id = pkt->hdr.id;
+	int ret;
+
+	if (!inst->workqueue) {
+		vpu_session_handle_msg(inst, pkt);
+		return;
+	}
+
+	bytes = sizeof(pkt->hdr) + pkt->hdr.num * sizeof(u32);
+	ret = kfifo_in(&inst->msg_fifo, pkt, bytes);
+	if (ret != bytes)
+		vpu_err("[%d:%d]overflow: %d\n", inst->core->id, inst->id, id);
+	queue_work(inst->workqueue, &inst->msg_work);
+}
+
+static int vpu_handle_msg(struct vpu_core *core)
+{
+	struct vpu_rpc_event pkt;
+	struct vpu_inst *inst;
+	int ret;
+
+	memset(&pkt, 0, sizeof(pkt));
+	while (!vpu_iface_receive_msg(core, &pkt)) {
+		vpu_dbg(LVL_DEBUG, "event index = %d, id = %d, num = %d\n",
+				pkt.hdr.index, pkt.hdr.id, pkt.hdr.num);
+
+		ret = vpu_iface_convert_msg_id(core, pkt.hdr.id);
+		if (ret < 0)
+			continue;
+
+		inst = vpu_core_find_instance(core, pkt.hdr.index);
+		if (inst) {
+			vpu_response_cmd(inst, ret, 0);
+			mutex_lock(&core->cmd_lock);
+			vpu_inst_record_flow(inst, ret);
+			mutex_unlock(&core->cmd_lock);
+
+			vpu_inst_handle_msg(inst, &pkt);
+			vpu_inst_put(inst);
+		}
+		memset(&pkt, 0, sizeof(pkt));
+	}
+
+	return 0;
+}
+
+static int vpu_isr_thread(struct vpu_core *core, u32 irq_code)
+{
+	WARN_ON(!core);
+
+	vpu_dbg(LVL_DEBUG, "core[%d] irq code = 0x%x\n", core->id, irq_code);
+	switch (irq_code) {
+	case VPU_IRQ_CODE_SYNC:
+		vpu_mbox_send_msg(core, PRC_BUF_OFFSET, core->rpc.phys - core->fw.phys);
+		vpu_mbox_send_msg(core, BOOT_ADDRESS, core->fw.phys);
+		vpu_mbox_send_msg(core, INIT_DONE, 2);
+		break;
+	case VPU_IRQ_CODE_BOOT_DONE:
+		break;
+	case VPU_IRQ_CODE_SNAPSHOT_DONE:
+		break;
+	default:
+		vpu_handle_msg(core);
+		break;
+	}
+
+	return 0;
+}
+
+static void vpu_core_run_msg_work(struct vpu_core *core)
+{
+	const unsigned int SIZE = sizeof(u32);
+
+	while (kfifo_len(&core->msg_fifo) >= SIZE) {
+		u32 data;
+
+		if (kfifo_out(&core->msg_fifo, &data, SIZE) == SIZE)
+			vpu_isr_thread(core, data);
+	}
+}
+
+void vpu_msg_run_work(struct work_struct *work)
+{
+	struct vpu_core *core = container_of(work, struct vpu_core, msg_work);
+	unsigned long delay = msecs_to_jiffies(10);
+
+	vpu_core_run_msg_work(core);
+	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
+}
+
+void vpu_msg_delayed_work(struct work_struct *work)
+{
+	struct vpu_core *core;
+	struct delayed_work *dwork;
+	u32 bytes = sizeof(bytes);
+	u32 i;
+
+	if (!work)
+		return;
+
+	dwork = to_delayed_work(work);
+	core = container_of(dwork, struct vpu_core, msg_delayed_work);
+	if (kfifo_len(&core->msg_fifo) >= bytes)
+		vpu_core_run_msg_work(core);
+
+	bytes = sizeof(struct vpu_rpc_event_header);
+	for (i = 0; i < core->supported_instance_count; i++) {
+		struct vpu_inst *inst = vpu_core_find_instance(core, i);
+
+		if (!inst)
+			continue;
+
+		if (inst->workqueue && kfifo_len(&inst->msg_fifo) >= bytes)
+			queue_work(inst->workqueue, &inst->msg_work);
+
+		vpu_inst_put(inst);
+	}
+}
+
+
+int vpu_isr(struct vpu_core *core, u32 irq)
+{
+	WARN_ON(!core);
+
+	vpu_dbg(LVL_DEBUG, "core[%d] irq code = 0x%x\n", core->id, irq);
+	switch (irq) {
+	case VPU_IRQ_CODE_SYNC:
+		break;
+	case VPU_IRQ_CODE_BOOT_DONE:
+		complete(&core->cmp);
+		break;
+	case VPU_IRQ_CODE_SNAPSHOT_DONE:
+		complete(&core->cmp);
+		break;
+	default:
+		break;
+	}
+
+	if (kfifo_in(&core->msg_fifo, &irq, sizeof(irq)) != sizeof(irq))
+		vpu_err("[%d]overflow: %d\n", core->id, irq);
+	queue_work(core->workqueue, &core->msg_work);
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_msgs.h b/drivers/media/platform/imx/vpu-8q/vpu_msgs.h
new file mode 100644
index 000000000000..fa8117cffa5a
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_msgs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_MSGS_H
+#define _IMX_VPU_MSGS_H
+
+int vpu_isr(struct vpu_core *core, u32 irq);
+void vpu_inst_run_work(struct work_struct *work);
+void vpu_msg_run_work(struct work_struct *work);
+void vpu_msg_delayed_work(struct work_struct *work);
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:08 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:08 +0800
Subject: [PATCH v7 07/14] media: imx: imx8q: add vpu v4l2 m2m support
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <4b31b73e171cb9d8fb71216448a8ff32e6f06e5e.1630377507.git.ming.qian@nxp.com>

vpu_v4l2.c implements the v4l2 m2m driver methods.
vpu_helpers.c implements the common helper functions
vpu_color.c converts the v4l2 colorspace with iso

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vpu_color.c | 192 +++++
 .../media/platform/imx/vpu-8q/vpu_helpers.c   | 453 ++++++++++++
 .../media/platform/imx/vpu-8q/vpu_helpers.h   |  72 ++
 drivers/media/platform/imx/vpu-8q/vpu_v4l2.c  | 654 ++++++++++++++++++
 drivers/media/platform/imx/vpu-8q/vpu_v4l2.h  |  44 ++
 5 files changed, 1415 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_color.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_helpers.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_helpers.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_v4l2.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_v4l2.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_color.c b/drivers/media/platform/imx/vpu-8q/vpu_color.c
new file mode 100644
index 000000000000..29d1d5edc901
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_color.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"COLOR"
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <media/v4l2-device.h>
+#include "vpu.h"
+#include "vpu_helpers.h"
+
+static const u8 colorprimaries[] = {
+	0,
+	V4L2_COLORSPACE_REC709,        /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	V4L2_COLORSPACE_470_SYSTEM_M, /*Rec. ITU-R BT.470-6 System M*/
+	V4L2_COLORSPACE_470_SYSTEM_BG,/*Rec. ITU-R BT.470-6 System B, G*/
+	V4L2_COLORSPACE_SMPTE170M,    /*SMPTE170M*/
+	V4L2_COLORSPACE_SMPTE240M,    /*SMPTE240M*/
+	0,                            /*Generic film*/
+	V4L2_COLORSPACE_BT2020,       /*Rec. ITU-R BT.2020-2*/
+	0,                            /*SMPTE ST 428-1*/
+};
+
+static const u8 colortransfers[] = {
+	0,
+	V4L2_XFER_FUNC_709,      /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	0,                       /*Rec. ITU-R BT.470-6 System M*/
+	0,                       /*Rec. ITU-R BT.470-6 System B, G*/
+	V4L2_XFER_FUNC_709,      /*SMPTE170M*/
+	V4L2_XFER_FUNC_SMPTE240M,/*SMPTE240M*/
+	V4L2_XFER_FUNC_NONE,     /*Linear transfer characteristics*/
+	0,
+	0,
+	0,                       /*IEC 61966-2-4*/
+	0,                       /*Rec. ITU-R BT.1361-0 extended colour gamut*/
+	V4L2_XFER_FUNC_SRGB,     /*IEC 61966-2-1 sRGB or sYCC*/
+	V4L2_XFER_FUNC_709,      /*Rec. ITU-R BT.2020-2 (10 bit system)*/
+	V4L2_XFER_FUNC_709,      /*Rec. ITU-R BT.2020-2 (12 bit system)*/
+	V4L2_XFER_FUNC_SMPTE2084,/*SMPTE ST 2084*/
+	0,                       /*SMPTE ST 428-1*/
+	0                        /*Rec. ITU-R BT.2100-0 hybrid log-gamma (HLG)*/
+};
+
+static const u8 colormatrixcoefs[] = {
+	0,
+	V4L2_YCBCR_ENC_709,             /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	0,                              /*Title 47 Code of Federal Regulations*/
+	V4L2_YCBCR_ENC_601,             /*Rec. ITU-R BT.601-7 625*/
+	V4L2_YCBCR_ENC_601,             /*Rec. ITU-R BT.601-7 525*/
+	V4L2_YCBCR_ENC_SMPTE240M,       /*SMPTE240M*/
+	0,
+	V4L2_YCBCR_ENC_BT2020,          /*Rec. ITU-R BT.2020-2*/
+	V4L2_YCBCR_ENC_BT2020_CONST_LUM /*Rec. ITU-R BT.2020-2 constant*/
+};
+
+u32 vpu_color_cvrt_primaries_v2i(u32 primaries)
+{
+	return VPU_ARRAY_FIND(colorprimaries, primaries);
+}
+
+u32 vpu_color_cvrt_primaries_i2v(u32 primaries)
+{
+	return VPU_ARRAY_AT(colorprimaries, primaries);
+}
+
+u32 vpu_color_cvrt_transfers_v2i(u32 transfers)
+{
+	return VPU_ARRAY_FIND(colortransfers, transfers);
+}
+
+u32 vpu_color_cvrt_transfers_i2v(u32 transfers)
+{
+	return VPU_ARRAY_AT(colortransfers, transfers);
+}
+
+u32 vpu_color_cvrt_matrix_v2i(u32 matrix)
+{
+	return VPU_ARRAY_FIND(colormatrixcoefs, matrix);
+}
+
+u32 vpu_color_cvrt_matrix_i2v(u32 matrix)
+{
+	return VPU_ARRAY_AT(colormatrixcoefs, matrix);
+}
+
+u32 vpu_color_cvrt_full_range_v2i(u32 full_range)
+{
+	return (full_range == V4L2_QUANTIZATION_FULL_RANGE);
+}
+
+u32 vpu_color_cvrt_full_range_i2v(u32 full_range)
+{
+	if (full_range)
+		return V4L2_QUANTIZATION_FULL_RANGE;
+
+	return V4L2_QUANTIZATION_LIM_RANGE;
+}
+
+int vpu_color_check_primaries(u32 primaries)
+{
+	return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_transfers(u32 transfers)
+{
+	return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_matrix(u32 matrix)
+{
+	return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_full_range(u32 full_range)
+{
+	int ret = -EINVAL;
+
+	switch (full_range) {
+	case V4L2_QUANTIZATION_FULL_RANGE:
+	case V4L2_QUANTIZATION_LIM_RANGE:
+		ret = 0;
+		break;
+	default:
+		break;
+
+	}
+
+	return ret;
+}
+
+int vpu_color_get_default(u32 primaries,
+		u32 *ptransfers, u32 *pmatrix, u32 *pfull_range)
+{
+	u32 transfers;
+	u32 matrix;
+	u32 full_range;
+
+	switch (primaries) {
+	case V4L2_COLORSPACE_REC709:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_709;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	case V4L2_COLORSPACE_470_SYSTEM_M:
+	case V4L2_COLORSPACE_470_SYSTEM_BG:
+	case V4L2_COLORSPACE_SMPTE170M:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_601;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	case V4L2_COLORSPACE_SMPTE240M:
+		transfers = V4L2_XFER_FUNC_SMPTE240M;
+		matrix = V4L2_YCBCR_ENC_SMPTE240M;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	case V4L2_COLORSPACE_BT2020:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_BT2020;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	default:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_709;
+		full_range = V4L2_QUANTIZATION_LIM_RANGE;
+		break;
+	}
+
+	if (ptransfers)
+		*ptransfers = transfers;
+	if (pmatrix)
+		*pmatrix = matrix;
+	if (pfull_range)
+		*pfull_range = full_range;
+
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_helpers.c b/drivers/media/platform/imx/vpu-8q/vpu_helpers.c
new file mode 100644
index 000000000000..484575d2975e
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_helpers.c
@@ -0,0 +1,453 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"HELPER"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_rpc.h"
+#include "vpu_helpers.h"
+#include "vpu_log.h"
+
+int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x)
+{
+	int i;
+
+	for (i = 0; i < size; i++) {
+		if (array[i] == x)
+			return i;
+	}
+
+	return 0;
+}
+
+bool vpu_helper_check_type(struct vpu_inst *inst, u32 type)
+{
+	const struct vpu_format *pfmt;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (vpu_core_check_fmt(inst->core, pfmt->pixfmt))
+			continue;
+		if (pfmt->type == type)
+			return true;
+	}
+
+	return false;
+}
+
+const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt)
+{
+	const struct vpu_format *pfmt;
+
+	if (!inst || !inst->formats)
+		return NULL;
+
+	if (vpu_core_check_fmt(inst->core, pixelfmt))
+		return NULL;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (vpu_core_check_fmt(inst->core, pfmt->pixfmt))
+			continue;
+
+		if (pfmt->pixfmt == pixelfmt && (!type || type == pfmt->type))
+			return pfmt;
+	}
+
+	return NULL;
+}
+
+const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index)
+{
+	const struct vpu_format *pfmt;
+	int i = 0;
+
+	if (!inst || !inst->formats)
+		return NULL;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (vpu_core_check_fmt(inst->core, pfmt->pixfmt))
+			continue;
+
+		if (pfmt->type == type) {
+			if (index == i)
+				return pfmt;
+			i++;
+		}
+	}
+
+	return NULL;
+}
+
+u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width)
+{
+	const struct vpu_core_resources *res;
+
+	if (!inst || !inst->core || !inst->core->res)
+		return width;
+
+	res = inst->core->res;
+	if (res->max_width)
+		width = clamp(width, res->min_width, res->max_width);
+	if (res->step_width)
+		width = ALIGN(width, res->step_width);
+
+	return width;
+}
+
+u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height)
+{
+	const struct vpu_core_resources *res;
+
+	if (!inst || !inst->core || !inst->core->res)
+		return height;
+
+	res = inst->core->res;
+	if (res->max_height)
+		height = clamp(height, res->min_height, res->max_height);
+	if (res->step_height)
+		height = ALIGN(height, res->step_height);
+
+	return height;
+}
+
+u32 vpu_helper_get_frame_size(u32 fmt, u32 width, u32 height)
+{
+	switch (fmt) {
+	case V4L2_PIX_FMT_NV12:
+		return ((width * 3) >> 1) * height;
+	default:
+		return width * height;
+	}
+}
+
+static u32 get_nv12_plane_size(u32 width, u32 height, int plane_no,
+			u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 bytesperline;
+	u32 size = 0;
+
+	bytesperline = ALIGN(width, stride);
+	height = ALIGN(height, 2);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	else
+		size = bytesperline * height >> 1;
+
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+static u32 get_tiled_8l128_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
+			u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 ws = 3;
+	u32 hs = 7;
+	u32 bitdepth = 8;
+	u32 bytesperline;
+	u32 size = 0;
+
+	if (interlaced)
+		hs++;
+	if (fmt == V4L2_PIX_FMT_NV12_10BE_8L128)
+		bitdepth = 10;
+	bytesperline = DIV_ROUND_UP(width * bitdepth, BITS_PER_BYTE);
+	bytesperline = ALIGN(bytesperline, 1 << ws);
+	bytesperline = ALIGN(bytesperline, stride);
+	height = ALIGN(height, 1 << hs);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	else if (plane_no == 1)
+		size = (bytesperline * ALIGN(height, 1 << (hs + 1))) >> 1;
+
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+static u32 get_default_plane_size(u32 width, u32 height, int plane_no,
+			u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 bytesperline;
+	u32 size = 0;
+
+	bytesperline = ALIGN(width, stride);
+	if (plane_no == 0)
+		size = bytesperline * height;
+
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+u32 vpu_helper_get_plane_size(u32 fmt, u32 w, u32 h, int plane_no,
+		u32 stride, u32 interlaced, u32 *pbl)
+{
+	switch (fmt) {
+	case V4L2_PIX_FMT_NV12:
+		return get_nv12_plane_size(w, h, plane_no, stride, interlaced, pbl);
+	case V4L2_PIX_FMT_NV12_8L128:
+	case V4L2_PIX_FMT_NV12_10BE_8L128:
+		return get_tiled_8l128_plane_size(fmt, w, h, plane_no, stride, interlaced, pbl);
+	default:
+		return get_default_plane_size(w, h, plane_no, stride, interlaced, pbl);
+	}
+}
+
+u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
+					u32 *rptr, u32 size, void *dst)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !rptr || !dst)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *rptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+
+	if (offset < start || offset > end) {
+		vpu_err("rptr 0x%x is out of range [0x%x, 0x%x]\n",
+				offset, start, end);
+		return -EINVAL;
+	}
+
+	if (offset + size <= end) {
+		memcpy(dst, virt + (offset - start), size);
+	} else {
+		memcpy(dst, virt + (offset - start), end - offset);
+		memcpy(dst + end - offset, virt, size + offset - end);
+	}
+
+	*rptr = vpu_helper_step_walk(stream_buffer, offset, size);
+	return size;
+}
+
+u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
+				u32 *wptr, u32 size, void *src)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !wptr || !src)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *wptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+	if (offset < start || offset > end) {
+		vpu_err("wptr 0x%x is out of range [0x%x, 0x%x]\n",
+				offset, start, end);
+		return -EINVAL;
+	}
+
+	if (offset + size <= end) {
+		memcpy(virt + (offset - start), src, size);
+	} else {
+		memcpy(virt + (offset - start), src, end - offset);
+		memcpy(virt, src + end - offset, size + offset - end);
+	}
+
+	*wptr = vpu_helper_step_walk(stream_buffer, offset, size);
+
+	return size;
+}
+
+u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
+				u32 *wptr, u8 val, u32 size)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !wptr)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *wptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+	if (offset < start || offset > end) {
+		vpu_err("wptr 0x%x is out of range [0x%x, 0x%x]\n",
+				offset, start, end);
+		return -EINVAL;
+	}
+
+	if (offset + size <= end) {
+		memset(virt + (offset - start), val, size);
+	} else {
+		memset(virt + (offset - start), val, end - offset);
+		memset(virt, val, size + offset - end);
+	}
+
+	offset += size;
+	if (offset >= end)
+		offset -= stream_buffer->length;
+
+	*wptr = offset;
+
+	return size;
+}
+
+u32 vpu_helper_get_free_space(struct vpu_inst *inst)
+{
+	struct vpu_rpc_buffer_desc desc;
+
+	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
+		return 0;
+
+	if (desc.rptr > desc.wptr)
+		return desc.rptr - desc.wptr;
+	else if (desc.rptr < desc.wptr)
+		return (desc.end - desc.start + desc.rptr - desc.wptr);
+	else
+		return desc.end - desc.start;
+}
+
+u32 vpu_helper_get_used_space(struct vpu_inst *inst)
+{
+	struct vpu_rpc_buffer_desc desc;
+
+	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
+		return 0;
+
+	if (desc.wptr > desc.rptr)
+		return desc.wptr - desc.rptr;
+	else if (desc.wptr < desc.rptr)
+		return (desc.end - desc.start + desc.wptr - desc.rptr);
+	else
+		return 0;
+}
+
+int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vpu_inst *inst = ctrl_to_inst(ctrl);
+
+	switch (ctrl->id) {
+	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+		ctrl->val = inst->min_buffer_cap;
+		break;
+	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
+		ctrl->val = inst->min_buffer_out;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+u32 vpu_helper_calc_coprime(u32 *a, u32 *b)
+{
+	int m = *a;
+	int n = *b;
+
+	if (m == 0)
+		return n;
+	if (n == 0)
+		return m;
+
+	while (n != 0) {
+		int tmp = m % n;
+
+		m = n;
+		n = tmp;
+	}
+	*a = (*a) / m;
+	*b = (*b) / m;
+
+	return m;
+}
+
+#define READ_BYTE(buffer, pos)	(*(u8 *)((buffer)->virt + ((pos) % buffer->length)))
+int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
+			u32 pixelformat, u32 offset, u32 bytesused)
+{
+	u32 start_code;
+	int start_code_size;
+	u32 val = 0;
+	int i;
+	int ret = -EINVAL;
+
+	if (!stream_buffer || !stream_buffer->virt)
+		return -EINVAL;
+
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_H264:
+		start_code_size = 4;
+		start_code = 0x00000001;
+		break;
+	default:
+		return 0;
+	}
+
+	for (i = 0; i < bytesused; i++) {
+		val = (val << 8) | READ_BYTE(stream_buffer, offset + i);
+		if (i < start_code_size - 1)
+			continue;
+		if (val == start_code) {
+			ret = i + 1 - start_code_size;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src)
+{
+	u32 i;
+
+	if (!pairs || !cnt)
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		if (pairs[i].src == src)
+			return pairs[i].dst;
+	}
+
+	return -EINVAL;
+}
+
+int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst)
+{
+	u32 i;
+
+	if (!pairs || !cnt)
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		if (pairs[i].dst == dst)
+			return pairs[i].src;
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_helpers.h b/drivers/media/platform/imx/vpu-8q/vpu_helpers.h
new file mode 100644
index 000000000000..8fdd6b488fae
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_helpers.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_HELPERS_H
+#define _IMX_VPU_HELPERS_H
+
+struct vpu_pair {
+	u32 src;
+	u32 dst;
+};
+
+#define MAKE_TIMESTAMP(s, ns)		(((s32)(s) * NSEC_PER_SEC) + (ns))
+#define VPU_INVALID_TIMESTAMP		MAKE_TIMESTAMP(-1, 0)
+#define	VPU_ARRAY_AT(array, i)		(((i) < ARRAY_SIZE(array)) ? array[i] : 0)
+#define VPU_ARRAY_FIND(array, x)	vpu_helper_find_in_array_u8(array, ARRAY_SIZE(array), x)
+
+int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x);
+bool vpu_helper_check_type(struct vpu_inst *inst, u32 type);
+const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt);
+const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index);
+u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width);
+u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height);
+u32 vpu_helper_get_frame_size(u32 fmt, u32 width, u32 height);
+u32 vpu_helper_get_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
+					u32 stride, u32 interlaced, u32 *pbl);
+u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
+					u32 *rptr, u32 size, void *dst);
+u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
+				u32 *wptr, u32 size, void *src);
+u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
+				u32 *wptr, u8 val, u32 size);
+u32 vpu_helper_get_free_space(struct vpu_inst *inst);
+u32 vpu_helper_get_used_space(struct vpu_inst *inst);
+int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
+u32 vpu_helper_calc_coprime(u32 *a, u32 *b);
+void vpu_helper_get_kmp_next(const u8 *pattern, int *next, int size);
+int vpu_helper_kmp_search(u8 *s, int s_len, const u8 *p, int p_len, int *next);
+int vpu_helper_kmp_search_in_stream_buffer(struct vpu_buffer *stream_buffer,
+					u32 offset, int bytesused,
+					const u8 *p, int p_len, int *next);
+int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
+			u32 pixelformat, u32 offset, u32 bytesused);
+
+static inline u32 vpu_helper_step_walk(struct vpu_buffer *stream_buffer, u32 pos, u32 step)
+{
+	pos += step;
+	if (pos > stream_buffer->phys + stream_buffer->length)
+		pos -= stream_buffer->length;
+
+	return pos;
+}
+
+int vpu_color_check_primaries(u32 primaries);
+int vpu_color_check_transfers(u32 transfers);
+int vpu_color_check_matrix(u32 matrix);
+int vpu_color_check_full_range(u32 full_range);
+u32 vpu_color_cvrt_primaries_v2i(u32 primaries);
+u32 vpu_color_cvrt_primaries_i2v(u32 primaries);
+u32 vpu_color_cvrt_transfers_v2i(u32 transfers);
+u32 vpu_color_cvrt_transfers_i2v(u32 transfers);
+u32 vpu_color_cvrt_matrix_v2i(u32 matrix);
+u32 vpu_color_cvrt_matrix_i2v(u32 matrix);
+u32 vpu_color_cvrt_full_range_v2i(u32 full_range);
+u32 vpu_color_cvrt_full_range_i2v(u32 full_range);
+int vpu_color_get_default(u32 primaries,
+		u32 *ptransfers, u32 *pmatrix, u32 *pfull_range);
+
+int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);
+int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_v4l2.c b/drivers/media/platform/imx/vpu-8q/vpu_v4l2.c
new file mode 100644
index 000000000000..b1f24f5e3922
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_v4l2.c
@@ -0,0 +1,654 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"V4L2"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include <linux/imx_vpu.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_v4l2.h"
+#include "vpu_msgs.h"
+#include "vpu_helpers.h"
+#include "vpu_log.h"
+
+void vpu_inst_lock(struct vpu_inst *inst)
+{
+	mutex_lock(&inst->lock);
+}
+
+void vpu_inst_unlock(struct vpu_inst *inst)
+{
+	mutex_unlock(&inst->lock);
+}
+
+dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no)
+{
+	return vb2_dma_contig_plane_dma_addr(vb, plane_no) +
+			vb->planes[plane_no].data_offset;
+}
+
+unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
+{
+	if (plane_no >= vb->num_planes)
+		return 0;
+	return vb2_plane_size(vb, plane_no) - vb->planes[plane_no].data_offset;
+}
+
+void vpu_v4l2_set_error(struct vpu_inst *inst)
+{
+	struct vb2_queue *src_q;
+	struct vb2_queue *dst_q;
+
+	src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	if (src_q)
+		src_q->error = 1;
+	if (dst_q)
+		dst_q->error = 1;
+}
+
+int vpu_notify_eos(struct vpu_inst *inst)
+{
+	const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_EOS
+	};
+
+	inst_dbg(inst, LVL_FLOW, "notify eos event\n");
+	v4l2_event_queue_fh(&inst->fh, &ev);
+
+	return 0;
+}
+
+int vpu_notify_source_change(struct vpu_inst *inst)
+{
+	const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_SOURCE_CHANGE,
+		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
+	};
+
+	inst_dbg(inst, LVL_FLOW, "notify source change event\n");
+	v4l2_event_queue_fh(&inst->fh, &ev);
+	return 0;
+}
+
+int vpu_notify_skip(struct vpu_inst *inst)
+{
+	const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_SKIP,
+		.u.data[0] = 0xff,
+	};
+
+	inst_dbg(inst, LVL_FLOW, "notify skip event\n");
+	v4l2_event_queue_fh(&inst->fh, &ev);
+
+	return 0;
+}
+
+int vpu_notify_codec_error(struct vpu_inst *inst)
+{
+	const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_CODEC_ERROR,
+	};
+
+	inst_dbg(inst, LVL_FLOW, "notify error event\n");
+	v4l2_event_queue_fh(&inst->fh, &ev);
+	vpu_v4l2_set_error(inst);
+
+	return 0;
+}
+
+const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst,
+		 struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	u32 type = f->type;
+	u32 stride;
+	u32 bytesperline;
+	u32 sizeimage;
+	const struct vpu_format *fmt;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, type, pixmp->pixelformat);
+	if (!fmt) {
+		fmt = vpu_helper_enum_format(inst, type, 0);
+		if (!fmt)
+			return NULL;
+		pixmp->pixelformat = fmt->pixfmt;
+	}
+
+	stride = inst->core->res->stride;
+	pixmp->width = vpu_helper_valid_frame_width(inst, pixmp->width);
+	pixmp->height = vpu_helper_valid_frame_height(inst, pixmp->height);
+	pixmp->flags = fmt->flags;
+	pixmp->num_planes = fmt->num_planes;
+	if (pixmp->field == V4L2_FIELD_ANY)
+		pixmp->field = V4L2_FIELD_NONE;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		sizeimage = vpu_helper_get_plane_size(pixmp->pixelformat,
+				pixmp->width, pixmp->height, i, stride,
+				pixmp->field == V4L2_FIELD_INTERLACED ? 1 : 0,
+				&bytesperline);
+		if ((s32)(pixmp->plane_fmt[i].bytesperline) <= 0)
+			pixmp->plane_fmt[i].bytesperline = bytesperline;
+		if ((s32)(pixmp->plane_fmt[i].sizeimage) <= 0)
+			pixmp->plane_fmt[i].sizeimage = sizeimage;
+		if (pixmp->plane_fmt[i].bytesperline < bytesperline)
+			pixmp->plane_fmt[i].bytesperline = bytesperline;
+		if (pixmp->plane_fmt[i].sizeimage <= sizeimage)
+			pixmp->plane_fmt[i].sizeimage = sizeimage;
+	}
+
+	return fmt;
+}
+
+static bool vpu_check_ready(struct vpu_inst *inst, u32 type)
+{
+	if (!inst)
+		return false;
+	if (inst->state == VPU_CODEC_STATE_DEINIT || inst->id < 0)
+		return false;
+	if (!inst->ops->check_ready)
+		return true;
+	return call_vop(inst, check_ready, type);
+}
+
+int vpu_process_output_buffer(struct vpu_inst *inst)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vpu_vb2_buffer *vpu_buf = NULL;
+
+	if (!inst)
+		return -EINVAL;
+
+	if (!vpu_check_ready(inst, inst->out_format.type))
+		return -EINVAL;
+
+	v4l2_m2m_for_each_src_buf(inst->m2m_ctx, buf) {
+		vpu_buf = container_of(buf, struct vpu_vb2_buffer, m2m_buf);
+		if (vpu_buf->state == VPU_BUF_STATE_IDLE)
+			break;
+		vpu_buf = NULL;
+	}
+
+	if (!vpu_buf)
+		return -EINVAL;
+
+	inst_dbg(inst, LVL_DEBUG, "frame id = %d / %d\n",
+			vpu_buf->m2m_buf.vb.sequence, inst->sequence);
+	return call_vop(inst, process_output, &vpu_buf->m2m_buf.vb.vb2_buf);
+}
+
+int vpu_process_capture_buffer(struct vpu_inst *inst)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vpu_vb2_buffer *vpu_buf = NULL;
+
+	if (!inst)
+		return -EINVAL;
+
+	if (!vpu_check_ready(inst, inst->cap_format.type))
+		return -EINVAL;
+
+	v4l2_m2m_for_each_dst_buf(inst->m2m_ctx, buf) {
+		vpu_buf = container_of(buf, struct vpu_vb2_buffer, m2m_buf);
+		if (vpu_buf->state == VPU_BUF_STATE_IDLE)
+			break;
+		vpu_buf = NULL;
+	}
+	if (!vpu_buf)
+		return -EINVAL;
+
+	return call_vop(inst, process_capture, &vpu_buf->m2m_buf.vb.vb2_buf);
+}
+
+struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst,
+						u32 type, u32 sequence)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		v4l2_m2m_for_each_src_buf(inst->m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->sequence == sequence)
+				break;
+			vbuf = NULL;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf(inst->m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->sequence == sequence)
+				break;
+			vbuf = NULL;
+		}
+	}
+
+	return vbuf;
+}
+
+struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst,
+						u32 type, u32 idx)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		v4l2_m2m_for_each_src_buf(inst->m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->vb2_buf.index == idx)
+				break;
+			vbuf = NULL;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf(inst->m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->vb2_buf.index == idx)
+				break;
+			vbuf = NULL;
+		}
+	}
+
+	return vbuf;
+}
+
+int vpu_get_num_buffers(struct vpu_inst *inst, u32 type)
+{
+	struct vb2_queue *q;
+
+	if (!inst || !inst->m2m_ctx)
+		return -EINVAL;
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	else
+		q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+
+	return q->num_buffers;
+}
+
+static void vpu_m2m_device_run(void *priv)
+{
+}
+
+static void vpu_m2m_job_abort(void *priv)
+{
+	struct vpu_inst *inst = priv;
+
+	v4l2_m2m_job_finish(inst->m2m_dev, inst->m2m_ctx);
+}
+
+static const struct v4l2_m2m_ops vpu_m2m_ops = {
+	.device_run = vpu_m2m_device_run,
+	.job_abort = vpu_m2m_job_abort
+};
+
+static int vpu_vb2_queue_setup(struct vb2_queue *vq,
+				unsigned int *buf_count,
+				unsigned int *plane_count,
+				unsigned int psize[],
+				struct device *allocators[])
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(vq);
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, vq->type);
+
+	if (*plane_count) {
+		if (*plane_count != cur_fmt->num_planes)
+			return -EINVAL;
+		for (i = 0; i < cur_fmt->num_planes; i++) {
+			if (psize[i] < cur_fmt->sizeimage[i])
+				return -EINVAL;
+		}
+	}
+
+	*plane_count = cur_fmt->num_planes;
+	for (i = 0; i < cur_fmt->num_planes; i++)
+		psize[i] = cur_fmt->sizeimage[i];
+
+	inst_dbg(inst, LVL_FLOW, "%s queue setup : %u; %u, %u\n",
+			vpu_type_name(vq->type),
+			*buf_count,
+			psize[0], psize[1]);
+
+	return 0;
+}
+
+static int vpu_vb2_buf_init(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+
+	return 0;
+}
+
+static void vpu_vb2_buf_cleanup(struct vb2_buffer *vb)
+{
+}
+
+static int vpu_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+	struct vpu_format *cur_fmt;
+	u32 i;
+
+	cur_fmt = vpu_get_format(inst, vb->type);
+	if (vb->num_planes != cur_fmt->num_planes)
+		return -EINVAL;
+	for (i = 0; i < cur_fmt->num_planes; i++) {
+		if (vpu_get_vb_length(vb, i) < cur_fmt->sizeimage[i]) {
+			inst_err(inst, "%s buf[%d] is invalid\n",
+					vpu_type_name(vb->type),
+					vb->index);
+			vpu_buf->state = VPU_BUF_STATE_ERROR;
+		}
+	}
+
+	return 0;
+}
+
+static void vpu_vb2_buf_finish(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_queue *q = vb->vb2_queue;
+
+	if (vbuf->flags & V4L2_BUF_FLAG_LAST)
+		vpu_notify_eos(inst);
+
+	if (list_empty(&q->done_list))
+		call_vop(inst, on_queue_empty, q->type);
+}
+
+void vpu_vb2_buffers_return(struct vpu_inst *inst,
+		unsigned int type, enum vb2_buffer_state state)
+{
+	struct vb2_v4l2_buffer *buf;
+
+	if (!inst || !inst->m2m_ctx)
+		return;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	} else {
+		while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	}
+}
+
+static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(q);
+	int ret;
+
+	vpu_inst_unlock(inst);
+	ret = vpu_inst_register(inst);
+	vpu_inst_lock(inst);
+	if (ret)
+		return ret;
+
+	vpu_inst_get(inst);
+	inst_dbg(inst, LVL_FLOW, "%s start streaming : %d\n",
+			vpu_type_name(q->type), q->num_buffers);
+	call_vop(inst, start, q->type);
+	vb2_clear_last_buffer_dequeued(q);
+
+	return 0;
+}
+
+static void vpu_vb2_stop_streaming(struct vb2_queue *q)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(q);
+
+	inst_dbg(inst, LVL_FLOW, "%s stop streaming\n", vpu_type_name(q->type));
+
+	call_vop(inst, stop, q->type);
+	vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_ERROR);
+	if (V4L2_TYPE_IS_OUTPUT(q->type))
+		inst->sequence = 0;
+
+	vpu_inst_put(inst);
+}
+
+static void vpu_vb2_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+
+	inst_dbg(inst, LVL_DEBUG, "%s buf queue\n", vpu_type_name(vb->type));
+
+	if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
+		vbuf->sequence = inst->sequence++;
+		if ((s64)vb->timestamp < 0)
+			vb->timestamp = VPU_INVALID_TIMESTAMP;
+	}
+
+	v4l2_m2m_buf_queue(inst->m2m_ctx, vbuf);
+	vpu_process_output_buffer(inst);
+	vpu_process_capture_buffer(inst);
+}
+
+static struct vb2_ops vpu_vb2_ops = {
+	.queue_setup        = vpu_vb2_queue_setup,
+	.buf_init           = vpu_vb2_buf_init,
+	.buf_cleanup        = vpu_vb2_buf_cleanup,
+	.buf_prepare        = vpu_vb2_buf_prepare,
+	.buf_finish         = vpu_vb2_buf_finish,
+	.start_streaming    = vpu_vb2_start_streaming,
+	.stop_streaming     = vpu_vb2_stop_streaming,
+	.buf_queue          = vpu_vb2_buf_queue,
+	.wait_prepare       = vb2_ops_wait_prepare,
+	.wait_finish        = vb2_ops_wait_finish,
+};
+
+static int vpu_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
+			  struct vb2_queue *dst_vq)
+{
+	struct vpu_inst *inst = priv;
+	int ret;
+
+	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	src_vq->ops = &vpu_vb2_ops;
+	src_vq->mem_ops = &vb2_dma_contig_memops;
+	if (inst->type == VPU_CORE_TYPE_DEC && inst->use_stream_buffer)
+		src_vq->mem_ops = &vb2_vmalloc_memops;
+	src_vq->drv_priv = inst;
+	src_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
+	src_vq->allow_zero_bytesused = 1;
+	src_vq->min_buffers_needed = 1;
+	src_vq->dev = inst->core->dev;
+	src_vq->lock = &inst->lock;
+	ret = vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->ops = &vpu_vb2_ops;
+	dst_vq->mem_ops = &vb2_dma_contig_memops;
+	if (inst->type == VPU_CORE_TYPE_ENC && inst->use_stream_buffer)
+		dst_vq->mem_ops = &vb2_vmalloc_memops;
+	dst_vq->drv_priv = inst;
+	dst_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
+	dst_vq->allow_zero_bytesused = 1;
+	dst_vq->min_buffers_needed = 1;
+	dst_vq->dev = inst->core->dev;
+	dst_vq->lock = &inst->lock;
+	ret = vb2_queue_init(dst_vq);
+	if (ret) {
+		vb2_queue_release(src_vq);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int vpu_v4l2_release(struct vpu_inst *inst)
+{
+	struct vpu_core *core = inst->core;
+
+	inst_dbg(inst, LVL_FLOW, "%s\n", __func__);
+
+	vpu_release_core(core);
+
+	if (inst->workqueue) {
+		cancel_work_sync(&inst->msg_work);
+		destroy_workqueue(inst->workqueue);
+		inst->workqueue = NULL;
+	}
+	if (inst->m2m_ctx) {
+		v4l2_m2m_ctx_release(inst->m2m_ctx);
+		inst->m2m_ctx = NULL;
+	}
+	if (inst->m2m_dev) {
+		v4l2_m2m_release(inst->m2m_dev);
+		inst->m2m_dev = NULL;
+	}
+
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+	mutex_destroy(&inst->lock);
+	v4l2_fh_del(&inst->fh);
+	v4l2_fh_exit(&inst->fh);
+
+	call_vop(inst, cleanup);
+
+	return 0;
+}
+
+int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu = video_drvdata(file);
+	struct video_device *vdev;
+	struct vpu_core *core = NULL;
+	int ret = 0;
+
+	WARN_ON(!file || !inst || !inst->ops);
+
+	if (inst->type == VPU_CORE_TYPE_ENC)
+		vdev = vpu->vdev_enc;
+	else
+		vdev = vpu->vdev_dec;
+
+	mutex_init(&inst->lock);
+	INIT_LIST_HEAD(&inst->cmd_q);
+
+	inst->id = VPU_INST_NULL_ID;
+	inst->release = vpu_v4l2_release;
+	inst->core = vpu_request_core(vpu, inst->type);
+
+	core = inst->core;
+	if (!core) {
+		vpu_err("there is no core for %s\n",
+			vpu_core_type_desc(inst->type));
+		return -EINVAL;
+	}
+
+	inst->min_buffer_cap = 2;
+	inst->min_buffer_out = 2;
+
+	ret = call_vop(inst, ctrl_init);
+	if (ret)
+		goto error;
+
+	inst->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops);
+	if (IS_ERR(inst->m2m_dev)) {
+		vpu_err("v4l2_m2m_init fail\n");
+		ret = PTR_ERR(inst->m2m_dev);
+		goto error;
+	}
+
+	inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev,
+					inst, vpu_m2m_queue_init);
+	if (IS_ERR(inst->m2m_ctx)) {
+		vpu_err("v4l2_m2m_ctx_init fail\n");
+		ret = PTR_ERR(inst->m2m_dev);
+		goto error;
+	}
+
+	v4l2_fh_init(&inst->fh, vdev);
+	v4l2_fh_add(&inst->fh);
+	inst->fh.ctrl_handler = &inst->ctrl_handler;
+	inst->fh.m2m_ctx = inst->m2m_ctx;
+	file->private_data = &inst->fh;
+	inst->state = VPU_CODEC_STATE_DEINIT;
+	inst->workqueue = alloc_workqueue("vpu_inst", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (inst->workqueue) {
+		INIT_WORK(&inst->msg_work, vpu_inst_run_work);
+		ret = kfifo_init(&inst->msg_fifo,
+				inst->msg_buffer,
+				roundup_pow_of_two(sizeof(inst->msg_buffer)));
+		if (ret) {
+			destroy_workqueue(inst->workqueue);
+			inst->workqueue = NULL;
+		}
+	}
+	atomic_set(&inst->ref_count, 0);
+	vpu_inst_get(inst);
+	vpu_dbg(LVL_FLOW, "open, tgid = %d, pid = %d\n", inst->tgid, inst->pid);
+
+	return 0;
+error:
+	if (inst->m2m_ctx) {
+		v4l2_m2m_ctx_release(inst->m2m_ctx);
+		inst->m2m_ctx = NULL;
+	}
+	if (inst->m2m_dev) {
+		v4l2_m2m_release(inst->m2m_dev);
+		inst->m2m_dev = NULL;
+	}
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+	vpu_release_core(inst->core);
+
+	return ret;
+}
+
+int vpu_v4l2_close(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vb2_queue *src_q;
+	struct vb2_queue *dst_q;
+
+	inst_dbg(inst, LVL_FLOW, "close\n");
+	src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	vpu_inst_lock(inst);
+	if (vb2_is_streaming(src_q))
+		v4l2_m2m_streamoff(file, inst->m2m_ctx, src_q->type);
+	if (vb2_is_streaming(dst_q))
+		v4l2_m2m_streamoff(file, inst->m2m_ctx, dst_q->type);
+	vpu_inst_unlock(inst);
+
+	call_vop(inst, release);
+	vpu_inst_unregister(inst);
+	vpu_inst_put(inst);
+
+	return 0;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_v4l2.h b/drivers/media/platform/imx/vpu-8q/vpu_v4l2.h
new file mode 100644
index 000000000000..204217b47cf5
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_v4l2.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_V4L2_H
+#define _IMX_VPU_V4L2_H
+
+void vpu_inst_lock(struct vpu_inst *inst);
+void vpu_inst_unlock(struct vpu_inst *inst);
+
+int vpu_v4l2_open(struct file *file, struct vpu_inst *inst);
+int vpu_v4l2_close(struct file *file);
+
+const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f);
+int vpu_process_output_buffer(struct vpu_inst *inst);
+int vpu_process_capture_buffer(struct vpu_inst *inst);
+struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence);
+struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx);
+void vpu_v4l2_set_error(struct vpu_inst *inst);
+int vpu_notify_eos(struct vpu_inst *inst);
+int vpu_notify_source_change(struct vpu_inst *inst);
+int vpu_notify_skip(struct vpu_inst *inst);
+int vpu_notify_codec_error(struct vpu_inst *inst);
+void vpu_vb2_buffers_return(struct vpu_inst *inst,
+		unsigned int type, enum vb2_buffer_state state);
+int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
+
+dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no);
+unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no);
+static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return &inst->out_format;
+	else
+		return &inst->cap_format;
+}
+
+static inline char *vpu_type_name(u32 type)
+{
+	return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture";
+}
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:09 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:09 +0800
Subject: [PATCH v7 08/14] media: imx: imx8q: add v4l2 m2m vpu encoder stateful
 driver
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <a81e28be6dfc5f195b53166049765410d69269a7.1630377507.git.ming.qian@nxp.com>

This consists of video encoder implementation plus encoder controls.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/venc.c | 1383 ++++++++++++++++++++++
 1 file changed, 1383 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/venc.c

diff --git a/drivers/media/platform/imx/vpu-8q/venc.c b/drivers/media/platform/imx/vpu-8q/venc.c
new file mode 100644
index 000000000000..696e0e78d29a
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/venc.c
@@ -0,0 +1,1383 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"ENC"
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/ktime.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include <linux/imx_vpu.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+
+#define VENC_OUTPUT_ENABLE	(1 << 0)
+#define VENC_CAPTURE_ENABLE	(1 << 1)
+#define VENC_ENABLE_MASK	(VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)
+#define VENC_MAX_BUF_CNT	8
+
+struct venc_t {
+	struct vpu_encode_params params;
+	u32 request_key_frame;
+	u32 input_ready;
+	u32 cpb_size;
+	bool bitrate_change;
+
+	struct vpu_buffer enc[VENC_MAX_BUF_CNT];
+	struct vpu_buffer ref[VENC_MAX_BUF_CNT];
+	struct vpu_buffer act[VENC_MAX_BUF_CNT];
+	struct list_head frames;
+	u32 frame_count;
+	u32 encode_count;
+	u32 ready_count;
+	u32 enable;
+	u32 stopped;
+
+	u32 skipped_count;
+	u32 skipped_bytes;
+
+	wait_queue_head_t wq;
+};
+
+struct venc_frame_t {
+	struct list_head list;
+	struct vpu_enc_pic_info info;
+	u32 bytesused;
+	s64 timestamp;
+};
+
+static const struct vpu_format venc_formats[] = {
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{0, 0, 0, 0},
+};
+
+static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "imx8q-vpu", sizeof(cap->driver));
+	strscpy(cap->card, "imx8q vpu encoder", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform: imx8q-vpu", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_format *fmt;
+
+	memset(f->reserved, 0, sizeof(f->reserved));
+	fmt = vpu_helper_enum_format(inst, f->type, f->index);
+	if (!fmt)
+		return -EINVAL;
+
+	f->pixelformat = fmt->pixfmt;
+	f->flags = fmt->flags;
+
+	return 0;
+}
+
+static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	if (!fsize || fsize->index)
+		return -EINVAL;
+
+	if (!vpu_helper_find_format(inst, 0, fsize->pixel_format))
+		return -EINVAL;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.max_width = inst->core->res->max_width;
+	fsize->stepwise.max_height = inst->core->res->max_height;
+	fsize->stepwise.min_width = inst->core->res->min_width;
+	fsize->stepwise.min_height = inst->core->res->min_height;
+	fsize->stepwise.step_width = inst->core->res->step_width;
+	fsize->stepwise.step_height = inst->core->res->step_height;
+
+	return 0;
+}
+
+static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	if (!fival || fival->index)
+		return -EINVAL;
+
+	if (!vpu_helper_find_format(inst, 0, fival->pixel_format))
+		return -EINVAL;
+
+	if (!fival->width || !fival->height)
+		return -EINVAL;
+
+	if (fival->width < inst->core->res->min_width ||
+		fival->width > inst->core->res->max_width ||
+		fival->height < inst->core->res->min_height ||
+		fival->height > inst->core->res->max_height)
+		return -EINVAL;
+
+	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
+	fival->stepwise.min.numerator = 1;
+	fival->stepwise.min.denominator = USHRT_MAX;
+	fival->stepwise.max.numerator = USHRT_MAX;
+	fival->stepwise.max.denominator = 1;
+	fival->stepwise.step.numerator = 1;
+	fival->stepwise.step.denominator = 1;
+
+	return 0;
+}
+
+static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	pixmp->pixelformat = cur_fmt->pixfmt;
+	pixmp->num_planes = cur_fmt->num_planes;
+	pixmp->width = cur_fmt->width;
+	pixmp->height = cur_fmt->height;
+	pixmp->field = cur_fmt->field;
+	pixmp->flags = cur_fmt->flags;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+	}
+
+	f->fmt.pix_mp.colorspace = venc->params.color.primaries;
+	f->fmt.pix_mp.xfer_func = venc->params.color.transfer;
+	f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix;
+	f->fmt.pix_mp.quantization = venc->params.color.full_range;
+
+	return 0;
+}
+
+static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	vpu_try_fmt_common(inst, f);
+
+	return 0;
+}
+
+static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_format *fmt;
+	struct vpu_format *cur_fmt;
+	struct vb2_queue *q;
+	struct venc_t *venc = inst->priv;
+	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+	int i;
+
+	q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+	if (vb2_is_streaming(q))
+		return -EBUSY;
+
+	fmt = vpu_try_fmt_common(inst, f);
+	if (!fmt)
+		return -EINVAL;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	cur_fmt->pixfmt = fmt->pixfmt;
+	cur_fmt->num_planes = fmt->num_planes;
+	cur_fmt->type = fmt->type;
+	cur_fmt->flags = fmt->flags;
+	cur_fmt->width = pix_mp->width;
+	cur_fmt->height = pix_mp->height;
+	for (i = 0; i < fmt->num_planes; i++) {
+		cur_fmt->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
+		cur_fmt->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
+	}
+
+	if (pix_mp->field != V4L2_FIELD_ANY)
+		cur_fmt->field = pix_mp->field;
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+		venc->params.input_format = cur_fmt->pixfmt;
+		venc->params.src_stride = cur_fmt->bytesperline[0];
+		venc->params.src_width = cur_fmt->width;
+		venc->params.src_height = cur_fmt->height;
+		venc->params.crop.left = 0;
+		venc->params.crop.top = 0;
+		venc->params.crop.width = cur_fmt->width;
+		venc->params.crop.height = cur_fmt->height;
+	} else {
+		venc->params.codec_format = cur_fmt->pixfmt;
+		venc->params.out_width = cur_fmt->width;
+		venc->params.out_height = cur_fmt->height;
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+		if (!vpu_color_check_primaries(pix_mp->colorspace)) {
+			venc->params.color.primaries = pix_mp->colorspace;
+			vpu_color_get_default(venc->params.color.primaries,
+						&venc->params.color.transfer,
+						&venc->params.color.matrix,
+						&venc->params.color.full_range);
+		}
+		if (!vpu_color_check_transfers(pix_mp->xfer_func))
+			venc->params.color.transfer = pix_mp->xfer_func;
+		if (!vpu_color_check_matrix(pix_mp->ycbcr_enc))
+			venc->params.color.matrix = pix_mp->ycbcr_enc;
+		if (!vpu_color_check_full_range(pix_mp->quantization))
+			venc->params.color.full_range = pix_mp->quantization;
+	}
+
+	pix_mp->colorspace = venc->params.color.primaries;
+	pix_mp->xfer_func = venc->params.color.transfer;
+	pix_mp->ycbcr_enc = venc->params.color.matrix;
+	pix_mp->quantization = venc->params.color.full_range;
+
+	return 0;
+}
+
+static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
+
+	if (!parm)
+		return -EINVAL;
+
+	if (!vpu_helper_check_type(inst, parm->type))
+		return -EINVAL;
+
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.readbuffers = 0;
+	timeperframe->numerator = venc->params.frame_rate_num;
+	timeperframe->denominator = venc->params.frame_rate_den;
+
+	return 0;
+}
+
+static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
+
+	if (!parm)
+		return -EINVAL;
+
+	if (!vpu_helper_check_type(inst, parm->type))
+		return -EINVAL;
+
+	if (!timeperframe->numerator)
+		timeperframe->numerator = venc->params.frame_rate_num;
+	if (!timeperframe->denominator)
+		timeperframe->denominator = venc->params.frame_rate_den;
+
+	venc->params.frame_rate_num = timeperframe->numerator;
+	venc->params.frame_rate_den = timeperframe->denominator;
+
+	vpu_helper_calc_coprime(&venc->params.frame_rate_num,
+				&venc->params.frame_rate_den);
+
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	memset(parm->parm.capture.reserved,
+			0, sizeof(parm->parm.capture.reserved));
+
+	return 0;
+}
+
+static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->out_format.width;
+		s->r.height = inst->out_format.height;
+		break;
+	case V4L2_SEL_TGT_CROP:
+		s->r = venc->params.crop;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int venc_valid_crop(struct venc_t *venc, struct vpu_core *core)
+{
+	struct v4l2_rect *rect = NULL;
+	u32 min_width;
+	u32 min_height;
+	u32 src_width;
+	u32 src_height;
+
+	rect = &venc->params.crop;
+	min_width = core->res->min_width;
+	min_height = core->res->min_height;
+	src_width = venc->params.src_width;
+	src_height = venc->params.src_height;
+
+	if (rect->width == 0 || rect->height == 0)
+		return -EINVAL;
+	if (rect->left > src_width - min_width ||
+		rect->top > src_height - min_height)
+		return -EINVAL;
+
+	rect->width = min(rect->width, src_width - rect->left);
+	rect->width = max_t(u32, rect->width, min_width);
+
+	rect->height = min(rect->height, src_height - rect->top);
+	rect->height = max_t(u32, rect->height, min_height);
+
+	return 0;
+}
+
+static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_core_resources *res = inst->core->res;
+	struct venc_t *venc = inst->priv;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return -EINVAL;
+	if (s->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	venc->params.crop.left = ALIGN(s->r.left, res->step_width);
+	venc->params.crop.top = ALIGN(s->r.top, res->step_height);
+	venc->params.crop.width = ALIGN(s->r.width, res->step_width);
+	venc->params.crop.height = ALIGN(s->r.height, res->step_height);
+	if (venc_valid_crop(venc, inst->core)) {
+		venc->params.crop.left = 0;
+		venc->params.crop.top = 0;
+		venc->params.crop.width = venc->params.src_width;
+		venc->params.crop.height = venc->params.src_height;
+	}
+
+	inst->crop = venc->params.crop;
+
+	return 0;
+}
+
+static int venc_response_eos(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_DRAIN)
+		return 0;
+
+	if (v4l2_m2m_num_src_bufs_ready(inst->m2m_ctx))
+		return 0;
+
+	if (!venc->input_ready)
+		return 0;
+
+	venc->input_ready = false;
+	inst_dbg(inst, LVL_FLOW, "stop\n");
+	ret = vpu_session_stop(inst);
+	if (ret)
+		return ret;
+	inst->state = VPU_CODEC_STATE_STOP;
+	wake_up_all(&venc->wq);
+
+	return 0;
+}
+
+static int venc_request_eos(struct vpu_inst *inst)
+{
+	inst->state = VPU_CODEC_STATE_DRAIN;
+	venc_response_eos(inst);
+
+	return 0;
+}
+
+static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd)
+{
+	struct vpu_inst *inst = to_inst(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
+	if (ret)
+		return ret;
+
+	vpu_inst_lock(inst);
+	if (cmd->cmd == V4L2_ENC_CMD_STOP) {
+		if (inst->state == VPU_CODEC_STATE_DEINIT)
+			vpu_notify_eos(inst);
+		else
+			venc_request_eos(inst);
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct v4l2_ioctl_ops venc_ioctl_ops = {
+	.vidioc_querycap               = venc_querycap,
+	.vidioc_enum_fmt_vid_cap       = venc_enum_fmt,
+	.vidioc_enum_fmt_vid_out       = venc_enum_fmt,
+	.vidioc_enum_framesizes        = venc_enum_framesizes,
+	.vidioc_enum_frameintervals    = venc_enum_frameintervals,
+	.vidioc_g_fmt_vid_cap_mplane   = venc_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane   = venc_g_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = venc_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane = venc_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane   = venc_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane   = venc_s_fmt,
+	.vidioc_g_parm                 = venc_g_parm,
+	.vidioc_s_parm                 = venc_s_parm,
+	.vidioc_g_selection            = venc_g_selection,
+	.vidioc_s_selection            = venc_s_selection,
+	.vidioc_try_encoder_cmd        = v4l2_m2m_ioctl_try_encoder_cmd,
+	.vidioc_encoder_cmd            = venc_encoder_cmd,
+	.vidioc_subscribe_event        = venc_subscribe_event,
+	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
+	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
+	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
+	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
+};
+
+static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vpu_inst *inst = ctrl_to_inst(ctrl);
+	struct venc_t *venc = inst->priv;
+	int ret = 0;
+
+	vpu_inst_lock(inst);
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		venc->params.profile = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		venc->params.level = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		venc->params.rc_mode = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		if (ctrl->val != venc->params.bitrate)
+			venc->bitrate_change = true;
+		venc->params.bitrate = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		venc->params.gop_length = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+		venc->params.bframes = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+		venc->params.i_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+		venc->params.p_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+		venc->params.b_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
+		venc->request_key_frame = 1;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
+		venc->cpb_size = ctrl->val * 1024;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
+		venc->params.sar.enable = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
+		venc->params.sar.idc = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
+		venc->params.sar.width = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
+		venc->params.sar.height = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops venc_ctrl_ops = {
+	.s_ctrl = venc_op_s_ctrl,
+	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+};
+
+static int venc_ctrl_init(struct vpu_inst *inst)
+{
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
+	if (ret)
+		return ret;
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+			V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+			~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+			  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+			  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
+			V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+			V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+			0x0,
+			V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+			0x0,
+			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_BITRATE,
+			BITRATE_MIN,
+			BITRATE_MAX,
+			BITRATE_STEP,
+			BITRATE_DEFAULT);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1);
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
+			V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
+			0x0,
+			V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
+			0, USHRT_MAX, 1, 1);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
+			0, USHRT_MAX, 1, 1);
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+			V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+			~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+			V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
+
+	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
+	if (ret) {
+		inst_err(inst, "setup ctrls fail, ret = %d\n", ret);
+		v4l2_ctrl_handler_free(&inst->ctrl_handler);
+		return ret;
+	}
+
+	return 0;
+}
+
+static bool venc_check_ready(struct vpu_inst *inst, unsigned int type)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vpu_helper_get_free_space(inst) < venc->cpb_size)
+			return false;
+		return venc->input_ready;
+	}
+
+	return true;
+}
+
+static u32 venc_get_enable_mask(u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return VENC_OUTPUT_ENABLE;
+	else
+		return VENC_CAPTURE_ENABLE;
+}
+
+static void venc_set_enable(struct venc_t *venc, u32 type, int enable)
+{
+	u32 mask = venc_get_enable_mask(type);
+
+	if (enable)
+		venc->enable |= mask;
+	else
+		venc->enable &= ~mask;
+}
+
+static u32 venc_get_enable(struct venc_t *venc, u32 type)
+{
+	return venc->enable & venc_get_enable_mask(type);
+}
+
+static void venc_input_done(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	vpu_inst_lock(inst);
+	venc->input_ready = true;
+	vpu_process_output_buffer(inst);
+	venc_response_eos(inst);
+	vpu_inst_unlock(inst);
+}
+
+/*
+ * It's hardware limitation, that there may be several bytes
+ * redundant data at the beginning of frame.
+ * For android platform, the redundant data may cause cts test fail
+ * So driver will strip them
+ */
+static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame)
+{
+	struct venc_t *venc;
+	int skipped;
+
+	if (!inst || !frame || !frame->bytesused)
+		return -EINVAL;
+
+	venc = inst->priv;
+	skipped = vpu_helper_find_startcode(&inst->stream_buffer,
+				inst->cap_format.pixfmt,
+				frame->info.wptr - inst->stream_buffer.phys,
+				frame->bytesused);
+	if (skipped > 0) {
+		frame->bytesused -= skipped;
+		frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer,
+						frame->info.wptr, skipped);
+		venc->skipped_bytes += skipped;
+		venc->skipped_count++;
+	}
+
+	return 0;
+}
+
+static int venc_get_one_encoded_frame(struct vpu_inst *inst,
+					struct venc_frame_t *frame,
+					struct vb2_v4l2_buffer *vbuf)
+{
+	struct venc_t *venc = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+
+	if (!vbuf)
+		return -EAGAIN;
+
+	if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {
+		inst_dbg(inst, LVL_DEBUG,
+				"type %d is disabled, frame sequence %d\n",
+				vbuf->vb2_buf.type, frame->info.frame_id);
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return 0;
+	}
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	if (frame->bytesused > vbuf->vb2_buf.planes[0].length) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return -ENOMEM;
+	}
+
+	venc_precheck_encoded_frame(inst, frame);
+
+	if (frame->bytesused) {
+		u32 rptr = frame->info.wptr;
+		void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
+
+		vpu_helper_copy_from_stream_buffer(&inst->stream_buffer,
+			&rptr, frame->bytesused, dst);
+		vpu_iface_update_stream_buffer(inst, rptr, 0);
+	}
+	vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);
+	vbuf->sequence = frame->info.frame_id;
+	vbuf->vb2_buf.timestamp = frame->info.timestamp;
+	vbuf->flags |= frame->info.pic_type;
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+	inst_dbg(inst, LVL_TS, "[OUTPUT TS]%32lld\n", frame->info.timestamp);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+	venc->ready_count++;
+
+	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+		inst_dbg(inst, LVL_DEBUG, "[%d]Iframe\n", frame->info.frame_id);
+
+	return 0;
+}
+
+static int venc_get_encoded_frames(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+	struct venc_frame_t *frame;
+	struct venc_frame_t *tmp;
+
+	if (!inst || !inst->priv)
+		return -EINVAL;
+
+	venc = inst->priv;
+	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
+		if (venc_get_one_encoded_frame(inst, frame,
+					v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
+			break;
+		list_del_init(&frame->list);
+		vfree(frame);
+	}
+
+	return 0;
+}
+
+static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
+{
+	struct vpu_enc_pic_info *info = arg;
+	struct venc_frame_t *frame;
+	struct venc_t *venc;
+	int ret = 0;
+
+	if (!inst || !info)
+		return -EINVAL;
+	venc = inst->priv;
+	frame = vzalloc(sizeof(*frame));
+	if (!frame)
+		return -ENOMEM;
+
+	memcpy(&frame->info, info, sizeof(frame->info));
+	frame->bytesused = info->frame_size;
+
+	vpu_inst_lock(inst);
+	list_add_tail(&frame->list, &venc->frames);
+	venc->encode_count++;
+	venc_get_encoded_frames(inst);
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static void venc_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+{
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_vb2_buffer *vpu_buf;
+
+	if (!inst || !frame)
+		return;
+
+	inst_dbg(inst, LVL_DEBUG, "buf done : type = %d, sequence = %d\n",
+			frame->type, frame->sequence);
+
+	vpu_inst_lock(inst);
+	if (!venc_get_enable(inst->priv, frame->type)) {
+		inst_dbg(inst, LVL_DEBUG,
+				"type %d is disabled, frame sequence %d\n",
+				frame->type, frame->sequence);
+		goto exit;
+	}
+	vbuf = vpu_find_buf_by_sequence(inst, frame->type, frame->sequence);
+	if (!vbuf) {
+		inst_err(inst, "can't find buf: type %d, sequence %d\n",
+				frame->type, frame->sequence);
+		goto exit;
+	}
+
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+	if (V4L2_TYPE_IS_OUTPUT(frame->type))
+		v4l2_m2m_src_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	else
+		v4l2_m2m_dst_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+exit:
+	vpu_inst_unlock(inst);
+}
+
+static int venc_append_empty_frame(struct vpu_inst *inst)
+{
+	struct venc_frame_t *frame;
+	struct venc_t *venc;
+
+	if (!inst || !inst->priv)
+		return -EINVAL;
+
+	venc = inst->priv;
+	frame = vzalloc(sizeof(*frame));
+	if (!frame)
+		return -ENOMEM;
+
+	frame->bytesused = 0;
+	frame->info.pic_type = V4L2_BUF_FLAG_LAST;
+	frame->info.frame_id = inst->sequence;
+
+	list_add_tail(&frame->list, &venc->frames);
+	venc_get_encoded_frames(inst);
+
+	return 0;
+}
+
+static void venc_stop_done(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "append empty frame\n");
+
+	vpu_inst_lock(inst);
+	venc_append_empty_frame(inst);
+	venc->stopped = true;
+	vpu_inst_unlock(inst);
+
+	wake_up_all(&venc->wq);
+}
+
+static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)
+{
+}
+
+static void venc_release(struct vpu_inst *inst)
+{
+}
+
+static void venc_cleanup(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+
+	if (!inst)
+		return;
+
+	venc = inst->priv;
+	if (venc)
+		vfree(venc);
+	inst->priv = NULL;
+	vfree(inst);
+}
+
+static int venc_start_session(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+	int stream_buffer_size;
+	int ret;
+
+	venc_set_enable(venc, type, 1);
+	if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK)
+		return 0;
+
+	vpu_iface_init_instance(inst);
+	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
+	if (stream_buffer_size > 0) {
+		inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3);
+		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
+		if (ret)
+			goto error;
+
+		inst->use_stream_buffer = true;
+		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
+	}
+
+	ret = vpu_iface_set_encode_params(inst, &venc->params, 0);
+	if (ret)
+		goto error;
+	ret = vpu_session_configure_codec(inst);
+	if (ret)
+		goto error;
+
+	inst->state = VPU_CODEC_STATE_CONFIGURED;
+	/*vpu_iface_config_memory_resource*/
+
+	/*config enc expert mode parameter*/
+	ret = vpu_iface_set_encode_params(inst, &venc->params, 1);
+	if (ret)
+		goto error;
+
+	ret = vpu_session_start(inst);
+	if (ret)
+		goto error;
+	inst->state = VPU_CODEC_STATE_STARTED;
+
+	venc->bitrate_change = false;
+	venc->input_ready = true;
+	venc->frame_count = 0;
+	venc->encode_count = 0;
+	venc->ready_count = 0;
+	venc->stopped = false;
+	vpu_process_output_buffer(inst);
+	if (venc->frame_count == 0)
+		inst_err(inst, "there is no input when starting\n");
+
+	return 0;
+error:
+	venc_set_enable(venc, type, 0);
+	inst->state = VPU_CODEC_STATE_DEINIT;
+
+	vpu_free_dma(&inst->stream_buffer);
+	return ret;
+}
+
+static void venc_cleanup_mem_resource(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+	u32 i;
+
+	WARN_ON(!inst || !inst->priv || !inst->core);
+
+	venc = inst->priv;
+
+	for (i = 0; i < ARRAY_SIZE(venc->enc); i++)
+		vpu_free_dma(&venc->enc[i]);
+	for (i = 0; i < ARRAY_SIZE(venc->ref); i++)
+		vpu_free_dma(&venc->ref[i]);
+	for (i = 0; i < ARRAY_SIZE(venc->act); i++)
+		vpu_free_dma(&venc->act[i]);
+}
+
+static void venc_request_mem_resource(struct vpu_inst *inst,
+				u32 enc_frame_size,
+				u32 enc_frame_num,
+				u32 ref_frame_size,
+				u32 ref_frame_num,
+				u32 act_frame_size,
+				u32 act_frame_num)
+{
+	struct venc_t *venc;
+	u32 i;
+	int ret;
+
+	WARN_ON(!inst || !inst->priv || !inst->core);
+
+	venc = inst->priv;
+
+	if (enc_frame_num > ARRAY_SIZE(venc->enc)) {
+		inst_err(inst, "enc num(%d) is out of range\n", enc_frame_num);
+		return;
+	}
+	if (ref_frame_num > ARRAY_SIZE(venc->ref)) {
+		inst_err(inst, "ref num(%d) is out of range\n", ref_frame_num);
+		return;
+	}
+	if (act_frame_num > ARRAY_SIZE(venc->act)) {
+		inst_err(inst, "act num(%d) is out of range\n", act_frame_num);
+		return;
+	}
+
+	for (i = 0; i < enc_frame_num; i++) {
+		venc->enc[i].length = enc_frame_size;
+		ret = vpu_alloc_dma(inst->core, &venc->enc[i]);
+		if (ret) {
+			venc_cleanup_mem_resource(inst);
+			return;
+		}
+	}
+	for (i = 0; i < ref_frame_num; i++) {
+		venc->ref[i].length = ref_frame_size;
+		ret = vpu_alloc_dma(inst->core, &venc->ref[i]);
+		if (ret) {
+			venc_cleanup_mem_resource(inst);
+			return;
+		}
+	}
+	if (act_frame_num != 1 || act_frame_size > inst->act.length) {
+		venc_cleanup_mem_resource(inst);
+		return;
+	}
+	venc->act[0].length = act_frame_size;
+	venc->act[0].phys = inst->act.phys;
+	venc->act[0].virt = inst->act.virt;
+
+	for (i = 0; i < enc_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]);
+	for (i = 0; i < ref_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]);
+	for (i = 0; i < act_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]);
+}
+
+static void venc_cleanup_frames(struct venc_t *venc)
+{
+	struct venc_frame_t *frame;
+	struct venc_frame_t *tmp;
+
+	if (!list_empty(&venc->frames))
+		vpu_dbg(LVL_DEBUG, "Warning some encoded frames are dropped\n");
+
+	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
+		list_del_init(&frame->list);
+		vfree(frame);
+	}
+}
+
+static int venc_stop_session(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+
+	venc_set_enable(venc, type, 0);
+	if (venc->enable & VENC_ENABLE_MASK)
+		return 0;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	if (inst->state != VPU_CODEC_STATE_STOP)
+		venc_request_eos(inst);
+
+	call_vop(inst, wait_prepare);
+	if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) {
+		set_bit(inst->id, &inst->core->hang_mask);
+		vpu_session_debug(inst);
+	}
+	call_vop(inst, wait_finish);
+
+	inst->state = VPU_CODEC_STATE_DEINIT;
+	venc_cleanup_frames(inst->priv);
+	vpu_free_dma(&inst->stream_buffer);
+	venc_cleanup_mem_resource(inst);
+
+	return 0;
+}
+
+static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct venc_t *venc = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_vb2_buffer *vpu_buf = NULL;
+	u32 flags;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return -EINVAL;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	if (inst->state == VPU_CODEC_STATE_STARTED)
+		inst->state = VPU_CODEC_STATE_ACTIVE;
+
+	flags = vbuf->flags;
+	if (venc->request_key_frame) {
+		vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+		venc->request_key_frame = 0;
+	}
+	if (venc->bitrate_change) {
+		vpu_session_update_parameters(inst, &venc->params);
+		venc->bitrate_change = false;
+	}
+	inst_dbg(inst, LVL_TS, "[INPUT  TS]%32lld\n", vb->timestamp);
+	vpu_iface_input_frame(inst, vb);
+	vbuf->flags = flags;
+	venc->input_ready = false;
+	venc->frame_count++;
+	vpu_buf->state = VPU_BUF_STATE_INUSE;
+
+	return 0;
+}
+
+static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct venc_t *venc;
+	struct venc_frame_t *frame = NULL;
+	struct vb2_v4l2_buffer *vbuf;
+	int ret;
+
+	venc = inst->priv;
+	if (list_empty(&venc->frames))
+		return -EINVAL;
+
+	frame = list_first_entry(&venc->frames, struct venc_frame_t, list);
+	vbuf = to_vb2_v4l2_buffer(vb);
+	v4l2_m2m_dst_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	ret = venc_get_one_encoded_frame(inst, frame, vbuf);
+	if (ret)
+		return ret;
+
+	list_del_init(&frame->list);
+	vfree(frame);
+	return 0;
+}
+
+static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct venc_t *venc = inst->priv;
+	int num = -1;
+
+	switch (i) {
+	case 0:
+		num = scnprintf(str, size, "profile = %d\n", venc->params.profile);
+		break;
+	case 1:
+		num = scnprintf(str, size, "level = %d\n", venc->params.level);
+		break;
+	case 2:
+		num = scnprintf(str, size, "fps = %d/%d\n",
+				venc->params.frame_rate_num,
+				venc->params.frame_rate_den);
+		break;
+	case 3:
+		num = scnprintf(str, size, "%d x %d -> %d x %d\n",
+				venc->params.src_width,
+				venc->params.src_height,
+				venc->params.out_width,
+				venc->params.out_height);
+		break;
+	case 4:
+		num = scnprintf(str, size, "(%d, %d)  %d x %d\n",
+				venc->params.crop.left,
+				venc->params.crop.top,
+				venc->params.crop.width,
+				venc->params.crop.height);
+		break;
+	case 5:
+		num = scnprintf(str, size,
+				"enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n",
+				venc->enable,
+				venc->frame_count, venc->encode_count,
+				venc->ready_count,
+				venc->stopped);
+		break;
+	case 6:
+		num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length);
+		break;
+	case 7:
+		num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes);
+		break;
+	case 8:
+		num = scnprintf(str, size, "rc: mode = %d, bitrate = %d, qp = %d\n",
+				venc->params.rc_mode,
+				venc->params.bitrate,
+				venc->params.i_frame_qp);
+		break;
+	case 9:
+		num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n",
+				venc->params.sar.enable,
+				venc->params.sar.idc,
+				venc->params.sar.width,
+				venc->params.sar.height);
+
+		break;
+	case 10:
+		num = scnprintf(str, size,
+				"colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n",
+				venc->params.color.primaries,
+				venc->params.color.transfer,
+				venc->params.color.matrix,
+				venc->params.color.full_range);
+		break;
+	case 11:
+		num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n",
+				venc->skipped_count, venc->skipped_bytes);
+		break;
+	default:
+		break;
+	}
+
+	return num;
+}
+
+static struct vpu_inst_ops venc_inst_ops = {
+	.ctrl_init = venc_ctrl_init,
+	.check_ready = venc_check_ready,
+	.input_done = venc_input_done,
+	.get_one_frame = venc_frame_encoded,
+	.buf_done = venc_buf_done,
+	.stop_done = venc_stop_done,
+	.event_notify = venc_event_notify,
+	.release = venc_release,
+	.cleanup = venc_cleanup,
+	.start = venc_start_session,
+	.mem_request = venc_request_mem_resource,
+	.stop = venc_stop_session,
+	.process_output = venc_process_output,
+	.process_capture = venc_process_capture,
+	.get_debug_info = venc_get_debug_info,
+	.wait_prepare = vpu_inst_unlock,
+	.wait_finish = vpu_inst_lock,
+};
+
+static void venc_init(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc;
+	struct v4l2_format f;
+	struct v4l2_streamparm parm;
+
+	venc = inst->priv;
+	venc->params.qp_min = 1;
+	venc->params.qp_max = 51;
+	venc->params.qp_min_i = 1;
+	venc->params.qp_max_i = 51;
+	venc->params.bitrate_max = BITRATE_MAX;
+	venc->params.bitrate_min = BITRATE_MIN;
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	f.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
+	venc_s_fmt(file, &inst->fh, &f);
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	venc_s_fmt(file, &inst->fh, &f);
+
+	memset(&parm, 0, sizeof(parm));
+	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	parm.parm.capture.timeperframe.numerator = 1;
+	parm.parm.capture.timeperframe.denominator = 30;
+	venc_s_parm(file, &inst->fh, &parm);
+}
+
+static int venc_open(struct file *file)
+{
+	struct vpu_inst *inst;
+	struct venc_t *venc;
+	int ret;
+
+	inst = vzalloc(sizeof(*inst));
+	if (!inst)
+		return -ENOMEM;
+
+	venc = vzalloc(sizeof(*venc));
+	if (!venc) {
+		vfree(inst);
+		return -ENOMEM;
+	}
+
+	inst->ops = &venc_inst_ops;
+	inst->formats = venc_formats;
+	inst->type = VPU_CORE_TYPE_ENC;
+	inst->priv = venc;
+	INIT_LIST_HEAD(&venc->frames);
+	init_waitqueue_head(&venc->wq);
+
+	ret = vpu_v4l2_open(file, inst);
+	if (ret) {
+		vfree(venc);
+		vfree(inst);
+		return ret;
+	}
+
+	venc_init(file);
+
+	return 0;
+}
+
+static const struct v4l2_file_operations venc_fops = {
+	.owner = THIS_MODULE,
+	.open = venc_open,
+	.release = vpu_v4l2_close,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = v4l2_m2m_fop_poll,
+	.mmap = v4l2_m2m_fop_mmap,
+};
+
+int venc_create_video_device(struct vpu_dev *vpu)
+{
+	struct video_device *venc;
+	int ret;
+
+	if (!vpu)
+		return -EINVAL;
+
+	if (vpu->vdev_enc)
+		return 0;
+
+	venc = video_device_alloc();
+	if (!venc) {
+		vpu_err("alloc vpu encoder video device fail\n");
+		return -ENOMEM;
+	}
+	strscpy(venc->name, "imx-vpu-encoder", sizeof(venc->name));
+	venc->release = video_device_release;
+	venc->fops = &venc_fops;
+	venc->ioctl_ops = &venc_ioctl_ops;
+	venc->vfl_dir = VFL_DIR_M2M;
+	venc->v4l2_dev = &vpu->v4l2_dev;
+	venc->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+
+	ret = video_register_device(venc, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		video_device_release(venc);
+		return ret;
+	}
+	video_set_drvdata(venc, vpu);
+	vpu->vdev_enc = venc;
+
+	return 0;
+}
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:10 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:10 +0800
Subject: [PATCH v7 09/14] media: imx: imx8q: add v4l2 m2m vpu decoder stateful
 driver
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <c872f1feed651b818245a8dc6eb0da00249db416.1630377507.git.ming.qian@nxp.com>

This consists of video decoder implementation plus decoder controls.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/media/platform/imx/vpu-8q/vdec.c | 1684 ++++++++++++++++++++++
 1 file changed, 1684 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vdec.c

diff --git a/drivers/media/platform/imx/vpu-8q/vdec.c b/drivers/media/platform/imx/vpu-8q/vdec.c
new file mode 100644
index 000000000000..ab39a32e88f4
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vdec.c
@@ -0,0 +1,1684 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"DEC"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include <linux/imx_vpu.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+
+#define VDEC_FRAME_DEPTH		256
+
+struct vdec_fs_info {
+	char name[8];
+	u32 type;
+	u32 max_count;
+	u32 req_count;
+	u32 count;
+	u32 index;
+	u32 size;
+	struct vpu_buffer buffer[32];
+	u32 tag;
+};
+
+struct vdec_t {
+	u32 seq_hdr_found;
+	struct vpu_buffer udata;
+	struct vpu_decode_params params;
+	struct vpu_dec_codec_info codec_info;
+	enum vpu_codec_state state;
+
+	struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
+	u32 req_frame_count;
+	struct vdec_fs_info mbi;
+	struct vdec_fs_info dcp;
+	u32 seq_tag;
+
+	u32 decoded_frame_count;
+	u32 display_frame_count;
+	u32 eos_received;
+	u32 eos_subscribed;
+	bool is_source_changed;
+	u32 source_change;
+	u32 drain;
+	u32 ts_pre_count;
+	u32 frame_depth;
+	s64 ts_start;
+	s64 ts_input;
+	s64 timestamp;
+};
+
+static const struct vpu_format vdec_formats[] = {
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12_8L128,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12_10BE_8L128,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264_MVC,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_HEVC,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_MPEG2,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_MPEG4,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_XVID,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VP8,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H263,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{0, 0, 0, 0},
+};
+
+static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
+	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+};
+
+static int vdec_ctrl_init(struct vpu_inst *inst)
+{
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
+	if (ret)
+		return ret;
+
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+			V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+			V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
+	if (ret) {
+		inst_err(inst, "setup ctrls fail, ret = %d\n", ret);
+		v4l2_ctrl_handler_free(&inst->ctrl_handler);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int vdec_handle_eos(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+
+	if (!vdec->eos_received)
+		return 0;
+
+	if (!vdec->eos_subscribed)
+		return 0;
+
+	if (!list_empty(&dst_q->done_list))
+		return 0;
+
+	dst_q->last_buffer_dequeued = true;
+	vpu_notify_eos(inst);
+	vdec->eos_received--;
+
+	return 0;
+}
+
+static void vdec_handle_resolution_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_queue *q;
+
+	if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		return;
+	if (!vdec->source_change)
+		return;
+
+	q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	if (!list_empty(&q->done_list))
+		return;
+
+	vdec->source_change--;
+	vpu_notify_source_change(inst);
+}
+
+static int vdec_update_state(struct vpu_inst *inst,
+		enum vpu_codec_state state, u32 force)
+{
+	struct vdec_t *vdec = inst->priv;
+	enum vpu_codec_state pre_state = inst->state;
+
+	if (state == VPU_CODEC_STATE_SEEK) {
+		if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec->state = inst->state;
+		else
+			vdec->state = VPU_CODEC_STATE_ACTIVE;
+	}
+	if (inst->state != VPU_CODEC_STATE_SEEK || force)
+		inst->state = state;
+	else if (state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE;
+
+	inst_dbg(inst, LVL_FLOW, "state : %d -> %d\n", pre_state, inst->state);
+
+	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		vdec_handle_resolution_change(inst);
+
+	return 0;
+}
+
+static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "imx8q-vpu", sizeof(cap->driver));
+	strscpy(cap->card, "imx8q vpu decoder", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform: imx8q-vpu", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int ret = -EINVAL;
+
+	vpu_inst_lock(inst);
+	if (!V4L2_TYPE_IS_OUTPUT(f->type) && vdec->seq_hdr_found) {
+		if (f->index == 0) {
+			f->pixelformat = inst->cap_format.pixfmt;
+			f->flags = inst->cap_format.flags;
+			ret = 0;
+		}
+	} else {
+		fmt = vpu_helper_enum_format(inst, f->type, f->index);
+		memset(f->reserved, 0, sizeof(f->reserved));
+		if (!fmt)
+			goto exit;
+
+		f->pixelformat = fmt->pixfmt;
+		f->flags = fmt->flags;
+		ret = 0;
+	}
+
+exit:
+	vpu_inst_unlock(inst);
+	return ret;
+}
+
+static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	pixmp->pixelformat = cur_fmt->pixfmt;
+	pixmp->num_planes = cur_fmt->num_planes;
+	pixmp->width = cur_fmt->width;
+	pixmp->height = cur_fmt->height;
+	pixmp->field = cur_fmt->field;
+	pixmp->flags = cur_fmt->flags;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+	}
+
+	f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+
+	inst_dbg(inst, LVL_DEBUG, "%s g_fmt: %c%c%c%c %dx%d %d,%d, %d,%d\n",
+			vpu_type_name(f->type),
+			f->fmt.pix_mp.pixelformat,
+			f->fmt.pix_mp.pixelformat >> 8,
+			f->fmt.pix_mp.pixelformat >> 16,
+			f->fmt.pix_mp.pixelformat >> 24,
+			f->fmt.pix_mp.width,
+			f->fmt.pix_mp.height,
+			pixmp->plane_fmt[0].sizeimage,
+			pixmp->plane_fmt[1].sizeimage,
+			pixmp->plane_fmt[0].bytesperline,
+			pixmp->plane_fmt[1].bytesperline);
+
+	return 0;
+}
+
+static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_try_fmt_common(inst, f);
+
+	vpu_inst_lock(inst);
+	if (vdec->seq_hdr_found) {
+		f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+		f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+		f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+		f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+	} else {
+		f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+		f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+		f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+		f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	const struct vpu_format *fmt;
+	struct vpu_format *cur_fmt;
+	struct vb2_queue *q;
+	struct vdec_t *vdec;
+	int i;
+
+	vdec = inst->priv;
+	q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+	if (vb2_is_streaming(q))
+		return -EBUSY;
+
+	fmt = vpu_try_fmt_common(inst, f);
+	if (!fmt)
+		return -EINVAL;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	vpu_inst_lock(inst);
+	cur_fmt->pixfmt = fmt->pixfmt;
+	cur_fmt->type = fmt->type;
+	if (V4L2_TYPE_IS_OUTPUT(f->type) || vdec->seq_hdr_found <= 0) {
+		cur_fmt->num_planes = fmt->num_planes;
+		cur_fmt->flags = fmt->flags;
+		cur_fmt->width = pixmp->width;
+		cur_fmt->height = pixmp->height;
+		for (i = 0; i < fmt->num_planes; i++) {
+			cur_fmt->sizeimage[i] = pixmp->plane_fmt[i].sizeimage;
+			cur_fmt->bytesperline[i] = pixmp->plane_fmt[i].bytesperline;
+		}
+		if (pixmp->field != V4L2_FIELD_ANY)
+			cur_fmt->field = pixmp->field;
+	} else {
+		pixmp->num_planes = cur_fmt->num_planes;
+		pixmp->width = cur_fmt->width;
+		pixmp->height = cur_fmt->height;
+		for (i = 0; i < pixmp->num_planes; i++) {
+			pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+			pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+		}
+		pixmp->field = cur_fmt->field;
+	}
+	if (V4L2_TYPE_IS_OUTPUT(f->type))
+		vdec->params.codec_format = cur_fmt->pixfmt;
+	else
+		vdec->params.output_format = cur_fmt->pixfmt;
+
+	if (!vdec->seq_hdr_found) {
+		vdec->codec_info.color_primaries = f->fmt.pix_mp.colorspace;
+		vdec->codec_info.transfer_chars = f->fmt.pix_mp.xfer_func;
+		vdec->codec_info.matrix_coeffs = f->fmt.pix_mp.ycbcr_enc;
+		vdec->codec_info.full_range = f->fmt.pix_mp.quantization;
+
+		inst->crop.left = 0;
+		inst->crop.top = 0;
+		inst->crop.width = cur_fmt->width;
+		inst->crop.height = cur_fmt->height;
+	} else {
+		f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+		f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+		f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+		f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+	}
+
+	vpu_inst_unlock(inst);
+
+	inst_dbg(inst, LVL_FLOW, "%s s_fmt: %c%c%c%c %dx%d %u,%u, %u,%u\n",
+			vpu_type_name(f->type),
+			f->fmt.pix_mp.pixelformat,
+			f->fmt.pix_mp.pixelformat >> 8,
+			f->fmt.pix_mp.pixelformat >> 16,
+			f->fmt.pix_mp.pixelformat >> 24,
+			f->fmt.pix_mp.width,
+			f->fmt.pix_mp.height,
+			pixmp->plane_fmt[0].sizeimage,
+			pixmp->plane_fmt[1].sizeimage,
+			pixmp->plane_fmt[0].bytesperline,
+			pixmp->plane_fmt[1].bytesperline);
+
+	return 0;
+}
+
+static int vdec_g_selection(struct file *file, void *fh,
+					struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+			s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_COMPOSE:
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE_PADDED:
+		s->r = inst->crop;
+		break;
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->cap_format.width;
+		s->r.height = inst->cap_format.height;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_drain(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!vdec->drain)
+		return 0;
+
+	if (v4l2_m2m_num_src_bufs_ready(inst->m2m_ctx))
+		return 0;
+
+	if (!vdec->params.frame_count) {
+		vpu_notify_eos(inst);
+		return 0;
+	}
+
+	vpu_iface_add_scode(inst, SCODE_PADDING_EOS);
+	vdec->params.end_flag = 1;
+	vpu_iface_set_decode_params(inst, &vdec->params, 1);
+	vdec->drain = 0;
+	inst_dbg(inst, LVL_FLOW, "append eos\n");
+
+	return 0;
+}
+
+static int vdec_cmd_stop(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "stop cmd\n");
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT) {
+		vpu_notify_eos(inst);
+	} else {
+		vdec->drain = 1;
+		vdec_drain(inst);
+	}
+
+	return 0;
+}
+
+static int vdec_decoder_cmd(struct file *file,
+		void *fh,
+		struct v4l2_decoder_cmd *cmd)
+{
+	struct vpu_inst *inst = to_inst(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
+	if (ret)
+		return ret;
+
+	vpu_inst_lock(inst);
+	switch (cmd->cmd) {
+	case V4L2_DEC_CMD_STOP:
+		vdec_cmd_stop(inst);
+		break;
+	default:
+		break;
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int vdec_subscribe_event(struct v4l2_fh *fh,
+		const struct v4l2_event_subscription *sub)
+{
+	struct vpu_inst *inst = container_of(fh, struct vpu_inst, fh);
+	struct vdec_t *vdec = inst->priv;
+
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		vdec->eos_subscribed = true;
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	case V4L2_EVENT_SOURCE_CHANGE:
+		return v4l2_src_change_event_subscribe(fh, sub);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	case V4L2_EVENT_SKIP:
+	case V4L2_EVENT_CODEC_ERROR:
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_unsubscribe_event(struct v4l2_fh *fh,
+				const struct v4l2_event_subscription *sub)
+{
+	struct vpu_inst *inst = container_of(fh, struct vpu_inst, fh);
+	struct vdec_t *vdec = inst->priv;
+	int ret;
+
+	ret = v4l2_event_unsubscribe(fh, sub);
+	if (ret)
+		return ret;
+
+	if (sub->type == V4L2_EVENT_EOS)
+		vdec->eos_subscribed = false;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
+	.vidioc_querycap               = vdec_querycap,
+	.vidioc_enum_fmt_vid_cap       = vdec_enum_fmt,
+	.vidioc_enum_fmt_vid_out       = vdec_enum_fmt,
+	.vidioc_g_fmt_vid_cap_mplane   = vdec_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane   = vdec_g_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane = vdec_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane   = vdec_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane   = vdec_s_fmt,
+	.vidioc_g_selection            = vdec_g_selection,
+	.vidioc_try_decoder_cmd        = v4l2_m2m_ioctl_try_decoder_cmd,
+	.vidioc_decoder_cmd            = vdec_decoder_cmd,
+	.vidioc_subscribe_event        = vdec_subscribe_event,
+	.vidioc_unsubscribe_event      = vdec_unsubscribe_event,
+	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
+	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
+	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
+	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
+};
+
+static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vdec->ts_pre_count >= vdec->frame_depth)
+			return false;
+		return true;
+	}
+
+	if (vdec->req_frame_count || vdec->eos_received)
+		return true;
+
+	return false;
+}
+
+static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_dec_pic_info *info = arg;
+	struct vpu_vb2_buffer *vpu_buf;
+	int ret = 0;
+
+	if (!info || info->id >= ARRAY_SIZE(vdec->slots))
+		return -EINVAL;
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec->slots[info->id];
+	if (!vpu_buf) {
+		inst_err(inst, "decoded invalid frame[%d]\n", info->id);
+		ret = -EINVAL;
+		goto exit;
+	}
+	if (vpu_buf->state == VPU_BUF_STATE_DECODED)
+		inst_dbg(inst, LVL_INFO, "buf[%d] has been decoded\n", info->id);
+	vpu_buf->state = VPU_BUF_STATE_DECODED;
+	vdec->decoded_frame_count++;
+	if (vdec->ts_pre_count >= info->consumed_count)
+		vdec->ts_pre_count -= info->consumed_count;
+	else
+		vdec->ts_pre_count = 0;
+exit:
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma)
+{
+	struct vdec_t *vdec = inst->priv;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
+		if (!vdec->slots[i])
+			continue;
+		if (luma == vdec->slots[i]->luma)
+			return vdec->slots[i];
+	}
+
+	return NULL;
+}
+
+static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!frame)
+		return;
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec_find_buffer(inst, frame->luma);
+	vpu_inst_unlock(inst);
+	if (!vpu_buf) {
+		inst_err(inst, "can't find buffer, id = %d, addr = 0x%x\n",
+				frame->id, frame->luma);
+		return;
+	}
+	if (frame->skipped) {
+		inst_dbg(inst, LVL_DEBUG, "frame skip\n");
+		vpu_notify_skip(inst);
+		return;
+	}
+
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vbuf->vb2_buf.index != frame->id)
+		inst_err(inst, "buffer id(%d, %d) dismatch\n",
+				vbuf->vb2_buf.index, frame->id);
+
+	if (vpu_buf->state != VPU_BUF_STATE_DECODED)
+		inst_err(inst, "buffer(%d) ready without decoded\n", frame->id);
+	vpu_buf->state = VPU_BUF_STATE_READY;
+	vb2_set_plane_payload(&vbuf->vb2_buf, 0, inst->cap_format.sizeimage[0]);
+	vb2_set_plane_payload(&vbuf->vb2_buf, 1, inst->cap_format.sizeimage[1]);
+	vbuf->vb2_buf.timestamp = frame->timestamp;
+	vbuf->field = inst->cap_format.field;
+	inst_dbg(inst, LVL_TS, "[OUTPUT TS]%32lld\n", frame->timestamp);
+
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+	vpu_inst_lock(inst);
+	vdec->timestamp = frame->timestamp;
+	vdec->display_frame_count++;
+	vpu_inst_unlock(inst);
+	inst_dbg(inst, LVL_DEBUG, "decoded : %d, display : %d\n",
+			vdec->decoded_frame_count, vdec->display_frame_count);
+}
+
+static void vdec_stop_done(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_inst_lock(inst);
+	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 0);
+	vdec->seq_hdr_found = 0;
+	vpu_inst_unlock(inst);
+}
+
+static bool vdec_check_source_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int i;
+
+	if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->m2m_ctx)))
+		return true;
+	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+	if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt)
+		return true;
+	if (inst->cap_format.width != vdec->codec_info.decoded_width)
+		return true;
+	if (inst->cap_format.height != vdec->codec_info.decoded_height)
+		return true;
+	if (vpu_get_num_buffers(inst, inst->cap_format.type) < inst->min_buffer_cap)
+		return true;
+	if (inst->crop.left != vdec->codec_info.offset_x)
+		return true;
+	if (inst->crop.top != vdec->codec_info.offset_y)
+		return true;
+	if (inst->crop.width != vdec->codec_info.width)
+		return true;
+	if (inst->crop.height != vdec->codec_info.height)
+		return true;
+	if (fmt && inst->cap_format.num_planes != fmt->num_planes)
+		return true;
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		if (inst->cap_format.bytesperline[i] != vdec->codec_info.bytesperline[i])
+			return true;
+		if (inst->cap_format.sizeimage[i] != vdec->codec_info.sizeimage[i])
+			return true;
+	}
+
+	return false;
+}
+
+static void vdec_init_fmt(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+	inst->out_format.width = vdec->codec_info.width;
+	inst->out_format.height = vdec->codec_info.height;
+	inst->cap_format.width = vdec->codec_info.decoded_width;
+	inst->cap_format.height = vdec->codec_info.decoded_height;
+	inst->cap_format.pixfmt = vdec->codec_info.pixfmt;
+	if (fmt) {
+		inst->cap_format.num_planes = fmt->num_planes;
+		inst->cap_format.flags = fmt->flags;
+	}
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		inst->cap_format.bytesperline[i] = vdec->codec_info.bytesperline[i];
+		inst->cap_format.sizeimage[i] = vdec->codec_info.sizeimage[i];
+	}
+	if (vdec->codec_info.progressive)
+		inst->cap_format.field = V4L2_FIELD_NONE;
+	else
+		inst->cap_format.field = V4L2_FIELD_INTERLACED;
+	if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT)
+		vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709;
+	if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
+		vdec->codec_info.transfer_chars = V4L2_XFER_FUNC_709;
+	if (vdec->codec_info.matrix_coeffs == V4L2_YCBCR_ENC_DEFAULT)
+		vdec->codec_info.matrix_coeffs = V4L2_YCBCR_ENC_709;
+	if (vdec->codec_info.full_range == V4L2_QUANTIZATION_DEFAULT)
+		vdec->codec_info.full_range = V4L2_QUANTIZATION_LIM_RANGE;
+}
+
+static void vdec_init_crop(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst->crop.left = vdec->codec_info.offset_x;
+	inst->crop.top = vdec->codec_info.offset_y;
+	inst->crop.width = vdec->codec_info.width;
+	inst->crop.height = vdec->codec_info.height;
+}
+
+static void vdec_init_mbi(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec->mbi.size = vdec->codec_info.mbi_size;
+	vdec->mbi.max_count = ARRAY_SIZE(vdec->mbi.buffer);
+	scnprintf(vdec->mbi.name, sizeof(vdec->mbi.name), "mbi");
+	vdec->mbi.type = MEM_RES_MBI;
+	vdec->mbi.tag = vdec->seq_tag;
+}
+
+static void vdec_init_dcp(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec->dcp.size = vdec->codec_info.dcp_size;
+	vdec->dcp.max_count = ARRAY_SIZE(vdec->dcp.buffer);
+	scnprintf(vdec->dcp.name, sizeof(vdec->dcp.name), "dcp");
+	vdec->dcp.type = MEM_RES_DCP;
+	vdec->dcp.tag = vdec->seq_tag;
+}
+
+static void vdec_request_one_fs(struct vdec_fs_info *fs)
+{
+	WARN_ON(!fs);
+
+	fs->req_count++;
+	if (fs->req_count > fs->max_count) {
+		vpu_err("error:request %s over %d\n", fs->name, fs->max_count);
+		fs->req_count = fs->max_count;
+	}
+}
+
+static int vdec_alloc_fs_buffer(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	struct vpu_buffer *buffer;
+
+	if (!inst || !fs || !fs->size)
+		return -EINVAL;
+
+	if (fs->count >= fs->req_count)
+		return -EINVAL;
+
+	buffer = &fs->buffer[fs->count];
+	if (buffer->virt && buffer->length >= fs->size)
+		return 0;
+
+	vpu_free_dma(buffer);
+	buffer->length = fs->size;
+	return vpu_alloc_dma(inst->core, buffer);
+}
+
+static void vdec_alloc_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	int ret;
+
+	while (fs->count < fs->req_count) {
+		ret = vdec_alloc_fs_buffer(inst, fs);
+		if (ret)
+			break;
+		fs->count++;
+	}
+}
+
+static void vdec_clear_fs(struct vdec_fs_info *fs)
+{
+	u32 i;
+
+	if (!fs)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(fs->buffer); i++)
+		vpu_free_dma(&fs->buffer[i]);
+	memset(fs, 0, sizeof(*fs));
+}
+
+static int vdec_response_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	struct vpu_fs_info info;
+	int ret;
+
+	if (fs->index >= fs->count)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.id = fs->index;
+	info.type = fs->type;
+	info.tag = fs->tag;
+	info.luma_addr = fs->buffer[fs->index].phys;
+	info.luma_size = fs->buffer[fs->index].length;
+	ret = vpu_session_alloc_fs(inst, &info);
+	if (ret)
+		return ret;
+
+	fs->index++;
+	return 0;
+}
+
+static int vdec_response_frame_abnormal(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_fs_info info;
+
+	if (!vdec->req_frame_count)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.type = MEM_RES_FRAME;
+	info.tag = vdec->seq_tag + 0xf0;
+	vpu_session_alloc_fs(inst, &info);
+	vdec->req_frame_count--;
+
+	return 0;
+}
+
+static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vpu_fs_info info;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_ACTIVE)
+		return -EINVAL;
+
+	if (!vdec->req_frame_count)
+		return -EINVAL;
+
+	if (!vbuf)
+		return -EINVAL;
+
+	if (vdec->slots[vbuf->vb2_buf.index]) {
+		inst_err(inst, "repeat alloc fs %d\n", vbuf->vb2_buf.index);
+		return -EINVAL;
+	}
+
+	inst_dbg(inst, LVL_DEBUG, "inst->state = %d, alloc fs %d, tag = 0x%x\n",
+		inst->state, vbuf->vb2_buf.index, vdec->seq_tag);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	memset(&info, 0, sizeof(info));
+	info.id = vbuf->vb2_buf.index;
+	info.type = MEM_RES_FRAME;
+	info.tag = vdec->seq_tag;
+	info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
+	info.luma_size = inst->cap_format.sizeimage[0];
+	info.chroma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 1);
+	info.chromau_size = inst->cap_format.sizeimage[1];
+	info.bytesperline = inst->cap_format.bytesperline[0];
+	ret = vpu_session_alloc_fs(inst, &info);
+	if (ret)
+		return ret;
+
+	vpu_buf->tag = info.tag;
+	vpu_buf->luma = info.luma_addr;
+	vpu_buf->chroma_u = info.chromau_size;
+	vpu_buf->chroma_v = 0;
+	vpu_buf->state = VPU_BUF_STATE_INUSE;
+	vdec->slots[info.id] = vpu_buf;
+	vdec->req_frame_count--;
+
+	return 0;
+}
+
+static void vdec_response_fs_request(struct vpu_inst *inst, bool force)
+{
+	struct vdec_t *vdec = inst->priv;
+	int i;
+	int ret;
+
+	if (force) {
+		for (i = vdec->req_frame_count; i > 0; i--)
+			vdec_response_frame_abnormal(inst);
+		return;
+	}
+
+	for (i = vdec->req_frame_count; i > 0; i--) {
+		ret = vpu_process_capture_buffer(inst);
+		if (ret)
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+
+	for (i = vdec->mbi.index; i < vdec->mbi.count; i++) {
+		if (vdec_response_fs(inst, &vdec->mbi))
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+	for (i = vdec->dcp.index; i < vdec->dcp.count; i++) {
+		if (vdec_response_fs(inst, &vdec->dcp))
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+}
+
+static void vdec_response_fs_release(struct vpu_inst *inst, u32 id, u32 tag)
+{
+	struct vpu_fs_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.id = id;
+	info.tag = tag;
+	vpu_session_release_fs(inst, &info);
+}
+
+static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	if (!inst || !vbuf)
+		return;
+
+	if (vbuf->vb2_buf.state != VB2_BUF_STATE_ACTIVE)
+		return;
+	if (vpu_find_buf_by_idx(inst, vbuf->vb2_buf.type, vbuf->vb2_buf.index))
+		return;
+	v4l2_m2m_buf_queue(inst->m2m_ctx, vbuf);
+}
+
+static void vdec_clear_slots(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
+		if (!vdec->slots[i])
+			continue;
+
+		vpu_buf = vdec->slots[i];
+		vbuf = &vpu_buf->m2m_buf.vb;
+		if (vpu_buf->tag == vdec->seq_tag)
+			inst_dbg(inst, LVL_WARN, "clear slot[%d], %d, %d\n",
+				i,
+				vdec->slots[i]->state,
+				vbuf->vb2_buf.state);
+
+		vdec_response_fs_release(inst, i, vpu_buf->tag);
+		vdec_recycle_buffer(inst, vbuf);
+		vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
+		vdec->slots[i] = NULL;
+	}
+}
+
+static void vdec_event_seq_hdr(struct vpu_inst *inst,
+				struct vpu_dec_codec_info *hdr)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_inst_lock(inst);
+	memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
+
+	inst_dbg(inst, LVL_FLOW, "%d x %d, crop : (%d, %d) %d x %d\n",
+			vdec->codec_info.decoded_width,
+			vdec->codec_info.decoded_height,
+			vdec->codec_info.offset_x,
+			vdec->codec_info.offset_y,
+			vdec->codec_info.width,
+			vdec->codec_info.height);
+	inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms;
+	vdec->is_source_changed = vdec_check_source_change(inst);
+	vdec_init_fmt(inst);
+	vdec_init_crop(inst);
+	vdec_init_mbi(inst);
+	vdec_init_dcp(inst);
+	if (!vdec->seq_hdr_found) {
+		vdec->seq_tag = vdec->codec_info.tag;
+		if (vdec->is_source_changed) {
+			vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+			vpu_notify_source_change(inst);
+			vdec->is_source_changed = false;
+		}
+	}
+	if (vdec->seq_tag != vdec->codec_info.tag) {
+		vdec_response_fs_request(inst, true);
+		inst_dbg(inst, LVL_DEBUG, "seq tag change: %d -> %d\n",
+				vdec->seq_tag, vdec->codec_info.tag);
+	}
+	vdec->seq_hdr_found++;
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_resolution_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "resolution change\n");
+	vpu_inst_lock(inst);
+	vdec->seq_tag = vdec->codec_info.tag;
+	vdec_clear_fs(&vdec->mbi);
+	vdec_clear_fs(&vdec->dcp);
+	vdec_clear_slots(inst);
+	vdec_init_mbi(inst);
+	vdec_init_dcp(inst);
+	if (vdec->is_source_changed) {
+		vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+		vdec->source_change++;
+		vdec_handle_resolution_change(inst);
+		vdec->is_source_changed = false;
+	}
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!fs)
+		return;
+
+	vpu_inst_lock(inst);
+
+	switch (fs->type) {
+	case MEM_RES_FRAME:
+		vdec->req_frame_count++;
+		break;
+	case MEM_RES_MBI:
+		vdec_request_one_fs(&vdec->mbi);
+		break;
+	case MEM_RES_DCP:
+		vdec_request_one_fs(&vdec->dcp);
+		break;
+	default:
+		break;
+	}
+
+	vdec_alloc_fs(inst, &vdec->mbi);
+	vdec_alloc_fs(inst, &vdec->dcp);
+
+	vdec_response_fs_request(inst, false);
+
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
+		return;
+	if (fs->type != MEM_RES_FRAME)
+		return;
+
+	if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
+		inst_err(inst, "invalid fs(%d) to release\n", fs->id);
+		return;
+	}
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec->slots[fs->id];
+	vdec->slots[fs->id] = NULL;
+
+	if (!vpu_buf) {
+		inst_dbg(inst, LVL_DEBUG, "fs[%d] has bee released\n", fs->id);
+		goto exit;
+	}
+
+	if (vpu_buf->state == VPU_BUF_STATE_DECODED) {
+		inst_dbg(inst, LVL_DEBUG, "this frame is skipped\n");
+		vpu_notify_skip(inst);
+	}
+
+	vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vpu_buf->state != VPU_BUF_STATE_READY)
+		vdec_recycle_buffer(inst, vbuf);
+
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+	vpu_process_capture_buffer(inst);
+
+exit:
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_eos(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "eos\n");
+	vpu_inst_lock(inst);
+	vdec->eos_received++;
+	vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
+	vpu_process_capture_buffer(inst);
+	vdec_handle_eos(inst);
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_notify(struct vpu_inst *inst, u32 event, void *data)
+{
+	switch (event) {
+	case VPU_MSG_ID_SEQ_HDR_FOUND:
+		vdec_event_seq_hdr(inst, data);
+		break;
+	case VPU_MSG_ID_RES_CHANGE:
+		vdec_event_resolution_change(inst);
+		break;
+	case VPU_MSG_ID_FRAME_REQ:
+		vdec_event_req_fs(inst, data);
+		break;
+	case VPU_MSG_ID_FRAME_RELEASE:
+		vdec_evnet_rel_fs(inst, data);
+		break;
+	case VPU_MSG_ID_PIC_EOS:
+		vdec_event_eos(inst);
+		break;
+	default:
+		break;
+	}
+}
+
+static int vdec_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vpu_rpc_buffer_desc desc;
+	s64 timestamp;
+	u32 free_space;
+	int ret;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+	inst_dbg(inst, LVL_DEBUG, "dec output [%d] %d : %ld\n",
+		vbuf->sequence, vb->index, vb2_get_plane_payload(vb, 0));
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return -EINVAL;
+
+	if (inst->state == VPU_CODEC_STATE_STARTED)
+		vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
+
+	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
+	if (ret)
+		return ret;
+
+	free_space = vpu_helper_get_free_space(inst);
+	if (free_space < vb2_get_plane_payload(vb, 0) + 0x40000)
+		return -ENOMEM;
+
+	timestamp = vb->timestamp;
+	if (timestamp >= 0 && vdec->ts_start < 0)
+		vdec->ts_start = timestamp;
+	if (vdec->ts_input < timestamp)
+		vdec->ts_input = timestamp;
+
+	ret = vpu_iface_input_frame(inst, vb);
+	if (ret < 0)
+		return -ENOMEM;
+
+	inst_dbg(inst, LVL_TS, "[INPUT  TS]%32lld\n", vb->timestamp);
+	vdec->ts_pre_count++;
+	vdec->params.frame_count++;
+
+	v4l2_m2m_src_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	vpu_buf->state = VPU_BUF_STATE_IDLE;
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+
+	if (vdec->drain)
+		vdec_drain(inst);
+
+	return 0;
+}
+
+static int vdec_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	int ret;
+
+	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		return -EINVAL;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+
+	if (vdec->eos_received) {
+		if (vdec->eos_subscribed) {
+			vdec_handle_eos(inst);
+		} else {
+			vb2_set_plane_payload(vb, 0, 0);
+			vb2_set_plane_payload(vb, 1, 0);
+			vbuf->flags |= V4L2_BUF_FLAG_LAST;
+			v4l2_m2m_dst_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+			v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+			vdec->eos_received--;
+		}
+		return 0;
+	}
+
+	ret = vdec_response_frame(inst, vbuf);
+	if (ret)
+		return ret;
+	v4l2_m2m_dst_buf_remove_by_buf(inst->m2m_ctx, vbuf);
+	return 0;
+}
+
+static void vdec_on_queue_emtpy(struct vpu_inst *inst, u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return;
+
+	vdec_handle_resolution_change(inst);
+	vdec_handle_eos(inst);
+}
+
+static void vdec_abort(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_rpc_buffer_desc desc;
+	int ret;
+
+	inst_dbg(inst, LVL_FLOW, "abort, inst->state = %d\n", inst->state);
+	vpu_iface_add_scode(inst, SCODE_PADDING_ABORT);
+	vdec->params.end_flag = 1;
+	vpu_iface_set_decode_params(inst, &vdec->params, 1);
+
+	vpu_session_abort(inst);
+
+	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
+	if (!ret)
+		vpu_iface_update_stream_buffer(inst, desc.rptr, 1);
+
+	vpu_session_rst_buf(inst);
+	inst_dbg(inst, LVL_FLOW, "input : %d, decoded : %d, display : %d\n",
+			vdec->params.frame_count,
+			vdec->decoded_frame_count,
+			vdec->display_frame_count);
+	vdec->params.end_flag = 0;
+	vdec->drain = 0;
+	vdec->ts_pre_count = 0;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+	vdec->params.frame_count = 0;
+	vdec->decoded_frame_count = 0;
+	vdec->display_frame_count = 0;
+}
+
+static void vdec_release(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst_dbg(inst, LVL_FLOW, "release\n");
+	vpu_inst_lock(inst);
+	vdec_clear_slots(inst);
+	if (inst->state != VPU_CODEC_STATE_DEINIT)
+		vpu_session_stop(inst);
+	vdec_clear_fs(&vdec->mbi);
+	vdec_clear_fs(&vdec->dcp);
+	vpu_free_dma(&vdec->udata);
+	vpu_free_dma(&inst->stream_buffer);
+	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 1);
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_cleanup(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec;
+
+	if (!inst)
+		return;
+
+	vdec = inst->priv;
+	if (vdec)
+		vfree(vdec);
+	inst->priv = NULL;
+	vfree(inst);
+}
+
+static void vdec_init_params(struct vdec_t *vdec)
+{
+	vdec->params.frame_count = 0;
+	vdec->params.end_flag = 0;
+}
+
+static int vdec_start(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	int stream_buffer_size;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	inst_dbg(inst, LVL_FLOW, "start\n");
+	vdec->udata.length = 0x1000;
+	ret = vpu_alloc_dma(inst->core, &vdec->udata);
+	if (ret) {
+		inst_err(inst, "alloc udata fail\n");
+		goto error;
+	}
+
+	vpu_iface_init_instance(inst);
+	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
+	if (stream_buffer_size > 0) {
+		inst->stream_buffer.length = stream_buffer_size;
+		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
+		if (ret) {
+			inst_err(inst, "alloc stream buffer fail\n");
+			goto error;
+		}
+		inst->use_stream_buffer = true;
+		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
+	}
+
+	vdec->params.udata.base = vdec->udata.phys;
+	vdec->params.udata.size = vdec->udata.length;
+	ret = vpu_iface_set_decode_params(inst, &vdec->params, 0);
+	if (ret) {
+		inst_err(inst, "set decode params fail\n");
+		goto error;
+	}
+
+	vdec_init_params(vdec);
+	ret = vpu_session_start(inst);
+	if (ret) {
+		inst_err(inst, "start fail\n");
+		goto error;
+	}
+
+	vdec_update_state(inst, VPU_CODEC_STATE_STARTED, 0);
+
+	return 0;
+error:
+	vpu_free_dma(&vdec->udata);
+	vpu_free_dma(&inst->stream_buffer);
+	return ret;
+}
+
+static int vdec_start_session(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+	int ret = 0;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT) {
+		if (V4L2_TYPE_IS_OUTPUT(type)) {
+			ret = vdec_start(inst);
+			if (ret)
+				return ret;
+		}
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (inst->state == VPU_CODEC_STATE_SEEK)
+			vdec_update_state(inst, vdec->state, 1);
+		vdec->eos_received = 0;
+		vpu_process_output_buffer(inst);
+	} else {
+		if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
+		vpu_process_capture_buffer(inst);
+	}
+	if (inst->state == VPU_CODEC_STATE_ACTIVE)
+		vdec_response_fs_request(inst, false);
+
+	return ret;
+}
+
+static int vdec_stop_session(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
+		vdec->drain = 0;
+	} else {
+		if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec_abort(inst);
+
+		vdec->eos_received = 0;
+		vdec_clear_slots(inst);
+	}
+
+	return 0;
+}
+
+static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct vdec_t *vdec = inst->priv;
+	int num = -1;
+
+	switch (i) {
+	case 0:
+		num = scnprintf(str, size,
+				"req_frame_count = %d\ninterlaced = %d\n",
+				vdec->req_frame_count,
+				vdec->codec_info.progressive ? 0 : 1);
+		break;
+	case 1:
+		num = scnprintf(str, size,
+				"mbi: size = 0x%x request = %d, alloc = %d, response = %d\n",
+				vdec->mbi.size,
+				vdec->mbi.req_count,
+				vdec->mbi.count,
+				vdec->mbi.index);
+		break;
+	case 2:
+		num = scnprintf(str, size,
+				"dcp: size = 0x%x request = %d, alloc = %d, response = %d\n",
+				vdec->dcp.size,
+				vdec->dcp.req_count,
+				vdec->dcp.count,
+				vdec->dcp.index);
+		break;
+	case 3:
+		num = scnprintf(str, size, "input_frame_count = %d\n", vdec->params.frame_count);
+		break;
+	case 4:
+		num = scnprintf(str, size, "decoded_frame_count = %d\n", vdec->decoded_frame_count);
+		break;
+	case 5:
+		num = scnprintf(str, size, "display_frame_count = %d\n", vdec->display_frame_count);
+		break;
+	case 6:
+		num = scnprintf(str, size, "drain = %d, eos = %d, source_change = %d\n",
+				vdec->drain, vdec->eos_received, vdec->source_change);
+		break;
+	case 7:
+		num = scnprintf(str, size, "ts_pre_count = %d, frame_depth = %d\n",
+				vdec->ts_pre_count, vdec->frame_depth);
+		break;
+	case 8:
+		num = scnprintf(str, size, "b_dis_reorder = %d, b_non_frame = %d\n",
+				vdec->params.b_dis_reorder,
+				vdec->params.b_non_frame);
+		break;
+	case 9:
+	{
+		s64 timestamp = vdec->timestamp;
+		s64 ts_start = vdec->ts_start;
+		s64 ts_input = vdec->ts_input;
+
+		num = scnprintf(str, size, "timestamp = %9lld.%09lld(%9lld.%09lld, %9lld.%09lld)\n",
+				timestamp / NSEC_PER_SEC,
+				timestamp % NSEC_PER_SEC,
+				ts_start / NSEC_PER_SEC,
+				ts_start % NSEC_PER_SEC,
+				ts_input / NSEC_PER_SEC,
+				ts_input % NSEC_PER_SEC);
+	}
+		break;
+	default:
+		break;
+	}
+
+	return num;
+}
+
+static struct vpu_inst_ops vdec_inst_ops = {
+	.ctrl_init = vdec_ctrl_init,
+	.check_ready = vdec_check_ready,
+	.buf_done = vdec_buf_done,
+	.get_one_frame = vdec_frame_decoded,
+	.stop_done = vdec_stop_done,
+	.event_notify = vdec_event_notify,
+	.release = vdec_release,
+	.cleanup = vdec_cleanup,
+	.start = vdec_start_session,
+	.stop = vdec_stop_session,
+	.process_output = vdec_process_output,
+	.process_capture = vdec_process_capture,
+	.on_queue_empty = vdec_on_queue_emtpy,
+	.get_debug_info = vdec_get_debug_info,
+	.wait_prepare = vpu_inst_unlock,
+	.wait_finish = vpu_inst_lock,
+};
+
+static void vdec_init(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec;
+	struct v4l2_format f;
+
+	vdec = inst->priv;
+	vdec->frame_depth = VDEC_FRAME_DEPTH;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	vdec_s_fmt(file, &inst->fh, &f);
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12_8L128;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	vdec_s_fmt(file, &inst->fh, &f);
+}
+
+static int vdec_open(struct file *file)
+{
+	struct vpu_inst *inst;
+	struct vdec_t *vdec;
+	int ret;
+
+	inst = vzalloc(sizeof(*inst));
+	if (!inst)
+		return -ENOMEM;
+
+	vdec = vzalloc(sizeof(*vdec));
+	if (!vdec) {
+		vfree(inst);
+		return -ENOMEM;
+	}
+
+	inst->ops = &vdec_inst_ops;
+	inst->formats = vdec_formats;
+	inst->type = VPU_CORE_TYPE_DEC;
+	inst->priv = vdec;
+
+	ret = vpu_v4l2_open(file, inst);
+	if (ret) {
+		vdec_cleanup(inst);
+		return ret;
+	}
+
+	vdec_init(file);
+
+	return 0;
+}
+
+static __poll_t vdec_poll(struct file *file, poll_table *wait)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vb2_queue *src_q, *dst_q;
+	__poll_t ret;
+
+	ret = v4l2_m2m_fop_poll(file, wait);
+	src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
+	dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
+	if (vb2_is_streaming(src_q) && !vb2_is_streaming(dst_q))
+		ret &= (~EPOLLERR);
+
+	return ret;
+}
+
+static const struct v4l2_file_operations vdec_fops = {
+	.owner = THIS_MODULE,
+	.open = vdec_open,
+	.release = vpu_v4l2_close,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = vdec_poll,
+	.mmap = v4l2_m2m_fop_mmap,
+};
+
+int vdec_create_video_device(struct vpu_dev *vpu)
+{
+	struct video_device *vdec;
+	int ret;
+
+	if (!vpu)
+		return -EINVAL;
+
+	if (vpu->vdev_dec)
+		return 0;
+
+	vdec = video_device_alloc();
+	if (!vdec) {
+		vpu_err("alloc vpu decoder video device fail\n");
+		return -ENOMEM;
+	}
+	strscpy(vdec->name, "imx-vpu-decoder", sizeof(vdec->name));
+	vdec->release = video_device_release;
+	vdec->fops = &vdec_fops;
+	vdec->ioctl_ops = &vdec_ioctl_ops;
+	vdec->vfl_dir = VFL_DIR_M2M;
+	vdec->v4l2_dev = &vpu->v4l2_dev;
+	vdec->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+
+	ret = video_register_device(vdec, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		video_device_release(vdec);
+		return ret;
+	}
+	video_set_drvdata(vdec, vpu);
+	vpu->vdev_dec = vdec;
+
+	return 0;
+}
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:11 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:11 +0800
Subject: [PATCH v7 10/14] media: imx: imx8q: implement windsor encoder rpc
 interface
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <222bdb07bccbea572ddcbc4548dee16c8162046b.1630377507.git.ming.qian@nxp.com>

This part implements the windsor encoder rpc interface.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 drivers/media/platform/imx/vpu-8q/vpu_imx8q.c |  218 +++
 drivers/media/platform/imx/vpu-8q/vpu_imx8q.h |  116 ++
 .../media/platform/imx/vpu-8q/vpu_windsor.c   | 1244 +++++++++++++++++
 .../media/platform/imx/vpu-8q/vpu_windsor.h   |   39 +
 4 files changed, 1617 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_imx8q.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_imx8q.h
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_windsor.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_windsor.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_imx8q.c b/drivers/media/platform/imx/vpu-8q/vpu_imx8q.c
new file mode 100644
index 000000000000..048d6953979d
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_imx8q.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"IMX8Q"
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_imx8q.h"
+#include "vpu_rpc.h"
+#include "vpu_log.h"
+
+#define IMX8Q_CSR_CM0Px_ADDR_OFFSET			0x00000000
+#define IMX8Q_CSR_CM0Px_CPUWAIT				0x00000004
+
+#ifdef CONFIG_IMX_SCU
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/svc/misc.h>
+
+#define VPU_DISABLE_BITS			0x7
+#define VPU_IMX_DECODER_FUSE_OFFSET		14
+#define VPU_ENCODER_MASK			0x1
+#define VPU_DECODER_MASK			0x3UL
+#define VPU_DECODER_H264_MASK			0x2UL
+#define VPU_DECODER_HEVC_MASK			0x1UL
+
+static u32 imx8q_fuse;
+
+struct vpu_sc_msg_misc {
+	struct imx_sc_rpc_msg hdr;
+	u32 word;
+} __packed;
+#endif
+
+int vpu_imx8q_set_system_cfg_common(struct vpu_rpc_system_config *config,
+		u32 regs, u32 core_id)
+{
+	if (!config)
+		return -EINVAL;
+
+	switch (core_id) {
+	case 0:
+		config->malone_base_addr[0] = regs + DEC_MFD_XREG_SLV_BASE;
+		config->num_malones = 1;
+		config->num_windsors = 0;
+		break;
+	case 1:
+		config->windsor_base_addr[0] = regs + ENC_MFD_XREG_SLV_0_BASE;
+		config->num_windsors = 1;
+		config->num_malones = 0;
+		break;
+	case 2:
+		config->windsor_base_addr[0] = regs + ENC_MFD_XREG_SLV_1_BASE;
+		config->num_windsors = 1;
+		config->num_malones = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (config->num_windsors) {
+		config->windsor_irq_pin[0x0][0x0] = WINDSOR_PAL_IRQ_PIN_L;
+		config->windsor_irq_pin[0x0][0x1] = WINDSOR_PAL_IRQ_PIN_H;
+	}
+
+	config->malone_base_addr[0x1] = 0x0;
+	config->hif_offset[0x0] = MFD_HIF;
+	config->hif_offset[0x1] = 0x0;
+
+	config->dpv_base_addr = 0x0;
+	config->dpv_irq_pin = 0x0;
+	config->pixif_base_addr = regs + DEC_MFD_XREG_SLV_BASE + MFD_PIX_IF;
+	config->cache_base_addr[0] = regs + MC_CACHE_0_BASE;
+	config->cache_base_addr[1] = regs + MC_CACHE_1_BASE;
+
+	return 0;
+}
+
+int vpu_imx8q_boot_core(struct vpu_core *core)
+{
+	csr_writel(core, IMX8Q_CSR_CM0Px_ADDR_OFFSET, core->fw.phys);
+	csr_writel(core, IMX8Q_CSR_CM0Px_CPUWAIT, 0);
+	return 0;
+}
+
+int vpu_imx8q_get_power_state(struct vpu_core *core)
+{
+	if (csr_readl(core, IMX8Q_CSR_CM0Px_CPUWAIT) == 1)
+		return 0;
+	return 1;
+}
+
+int vpu_imx8q_on_firmware_loaded(struct vpu_core *core)
+{
+	u8 *p;
+
+	p = core->fw.virt;
+	p[16] = core->vpu->res->plat_type;
+	p[17] = core->id;
+	p[18] = 1;
+
+	return 0;
+}
+
+u32 vpu_imx8q_check_memory_region(dma_addr_t base, dma_addr_t addr, u32 size)
+{
+	const struct vpu_rpc_region_t imx8q_regions[] = {
+		{0x00000000, 0x08000000, VPU_CORE_MEMORY_CACHED},
+		{0x08000000, 0x10000000, VPU_CORE_MEMORY_UNCACHED},
+		{0x10000000, 0x20000000, VPU_CORE_MEMORY_CACHED},
+		{0x20000000, 0x40000000, VPU_CORE_MEMORY_UNCACHED}
+	};
+	int i;
+
+	if (addr < base)
+		return VPU_CORE_MEMORY_INVALID;
+
+	addr -= base;
+	for (i = 0; i < ARRAY_SIZE(imx8q_regions); i++) {
+		const struct vpu_rpc_region_t *region = &imx8q_regions[i];
+
+		if (addr >= region->start && addr + size < region->end)
+			return region->type;
+	}
+
+	return VPU_CORE_MEMORY_INVALID;
+}
+
+#ifdef CONFIG_IMX_SCU
+static u32 vpu_imx8q_get_fuse(void)
+{
+	static u32 fuse_got;
+	struct imx_sc_ipc *ipc;
+	struct vpu_sc_msg_misc msg;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	if (fuse_got)
+		return imx8q_fuse;
+
+	ret = imx_scu_get_handle(&ipc);
+	if (ret) {
+		vpu_err("error: scu get handle fail: %d\n", ret);
+		return 0;
+	}
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_MISC;
+	hdr->func = IMX_SC_MISC_FUNC_OTP_FUSE_READ;
+	hdr->size = 2;
+
+	msg.word = VPU_DISABLE_BITS;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return 0;
+
+	imx8q_fuse = msg.word;
+	fuse_got = 1;
+	vpu_dbg(LVL_INFO, "imx8q fuse = 0x%x\n", imx8q_fuse);
+	return imx8q_fuse;
+}
+
+bool vpu_imx8q_check_codec(enum vpu_core_type type)
+{
+	u32 fuse = vpu_imx8q_get_fuse();
+
+	if (type == VPU_CORE_TYPE_ENC) {
+		if (fuse & VPU_ENCODER_MASK)
+			return false;
+	} else if (type == VPU_CORE_TYPE_DEC) {
+		fuse >>= VPU_IMX_DECODER_FUSE_OFFSET;
+		fuse &= VPU_DECODER_MASK;
+
+		if (fuse == VPU_DECODER_MASK)
+			return false;
+	}
+	return true;
+}
+
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt)
+{
+	u32 fuse = vpu_imx8q_get_fuse();
+
+	if (type == VPU_CORE_TYPE_DEC) {
+		fuse >>= VPU_IMX_DECODER_FUSE_OFFSET;
+		fuse &= VPU_DECODER_MASK;
+
+		if (fuse == VPU_DECODER_HEVC_MASK && pixelfmt == V4L2_PIX_FMT_HEVC)
+			return false;
+		if (fuse == VPU_DECODER_H264_MASK && pixelfmt == V4L2_PIX_FMT_H264)
+			return false;
+		if (fuse == VPU_DECODER_MASK)
+			return false;
+	}
+
+	return true;
+}
+#else
+bool vpu_imx8q_check_codec(enum vpu_core_type type)
+{
+	return true;
+}
+
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt)
+{
+	return true;
+}
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_imx8q.h b/drivers/media/platform/imx/vpu-8q/vpu_imx8q.h
new file mode 100644
index 000000000000..e8b1fa1da9c0
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_imx8q.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_8Q_H
+#define _IMX_VPU_8Q_H
+
+#define SCB_XREG_SLV_BASE                               0x00000000
+#define SCB_SCB_BLK_CTRL                                0x00070000
+#define SCB_BLK_CTRL_XMEM_RESET_SET                     0x00000090
+#define SCB_BLK_CTRL_CACHE_RESET_SET                    0x000000A0
+#define SCB_BLK_CTRL_CACHE_RESET_CLR                    0x000000A4
+#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET                 0x00000100
+
+#define XMEM_CONTROL                                    0x00041000
+
+#define	MC_CACHE_0_BASE					0x00060000
+#define	MC_CACHE_1_BASE					0x00068000
+
+#define DEC_MFD_XREG_SLV_BASE                           0x00180000
+#define ENC_MFD_XREG_SLV_0_BASE				0x00800000
+#define ENC_MFD_XREG_SLV_1_BASE				0x00A00000
+
+#define MFD_HIF                                         0x0001C000
+#define MFD_HIF_MSD_REG_INTERRUPT_STATUS                0x00000018
+#define MFD_SIF                                         0x0001D000
+#define MFD_SIF_CTRL_STATUS                             0x000000F0
+#define MFD_SIF_INTR_STATUS                             0x000000F4
+#define MFD_MCX                                         0x00020800
+#define MFD_MCX_OFF                                     0x00000020
+#define MFD_PIX_IF					0x00020000
+
+#define MFD_BLK_CTRL                                    0x00030000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_SET                  0x00000000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR                  0x00000004
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET           0x00000100
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR           0x00000104
+
+#define VID_API_NUM_STREAMS				8
+#define VID_API_MAX_BUF_PER_STR				3
+#define VID_API_MAX_NUM_MVC_VIEWS			4
+#define MEDIAIP_MAX_NUM_MALONES				2
+#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS			2
+#define MEDIAIP_MAX_NUM_WINDSORS			1
+#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS		2
+#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS			2
+#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS			1
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS			4
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS			4
+
+#define WINDSOR_PAL_IRQ_PIN_L				0x4
+#define WINDSOR_PAL_IRQ_PIN_H				0x5
+
+struct vpu_rpc_system_config {
+	u32 cfg_cookie;
+
+	u32 num_malones;
+	u32 malone_base_addr[MEDIAIP_MAX_NUM_MALONES];
+	u32 hif_offset[MEDIAIP_MAX_NUM_MALONES];
+	u32 malone_irq_pin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+	u32 malone_irq_target[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+
+	u32 num_windsors;
+	u32 windsor_base_addr[MEDIAIP_MAX_NUM_WINDSORS];
+	u32 windsor_irq_pin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+	u32 windsor_irq_target[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+
+	u32 cmd_irq_pin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+	u32 cmd_irq_target[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+
+	u32 msg_irq_pin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+	u32 msg_irq_target[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+
+	u32 sys_clk_freq;
+	u32 num_timers;
+	u32 timer_base_addr;
+	u32 timer_irq_pin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+	u32 timer_irq_target[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+	u32 timer_slots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
+
+	u32 gic_base_addr;
+	u32 uart_base_addr;
+
+	u32 dpv_base_addr;
+	u32 dpv_irq_pin;
+	u32 dpv_irq_target;
+
+	u32 pixif_base_addr;
+
+	u32 pal_trace_level;
+	u32 pal_trace_destination;
+
+	u32 pal_trace_level1;
+	u32 pal_trace_destination1;
+
+	u32 uHeapBase;
+	u32 uHeapSize;
+
+	u32 cache_base_addr[2];
+};
+
+int vpu_imx8q_setup_dec(struct vpu_dev *vpu);
+int vpu_imx8q_setup_enc(struct vpu_dev *vpu);
+int vpu_imx8q_setup(struct vpu_dev *vpu);
+int vpu_imx8q_reset(struct vpu_dev *vpu);
+int vpu_imx8q_set_system_cfg_common(struct vpu_rpc_system_config *config,
+		u32 regs, u32 core_id);
+int vpu_imx8q_boot_core(struct vpu_core *core);
+int vpu_imx8q_get_power_state(struct vpu_core *core);
+int vpu_imx8q_on_firmware_loaded(struct vpu_core *core);
+u32 vpu_imx8q_check_memory_region(dma_addr_t base, dma_addr_t addr, u32 size);
+bool vpu_imx8q_check_codec(enum vpu_core_type type);
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt);
+
+#endif
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_windsor.c b/drivers/media/platform/imx/vpu-8q/vpu_windsor.c
new file mode 100644
index 000000000000..fbd2c1a37aa9
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_windsor.c
@@ -0,0 +1,1244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"WINDSOR"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_v4l2.h"
+#include "vpu_log.h"
+#include "vpu_imx8q.h"
+#include "vpu_windsor.h"
+
+#define CMD_SIZE				2560
+#define MSG_SIZE				25600
+#define WINDSOR_USER_DATA_WORDS			16
+#define WINDSOR_MAX_SRC_FRAMES			0x6
+#define WINDSOR_MAX_REF_FRAMES			0x3
+#define WINDSOR_BITRATE_UNIT			1024
+#define WINDSOR_H264_EXTENDED_SAR		255
+
+enum {
+	GTB_ENC_CMD_NOOP        = 0x0,
+	GTB_ENC_CMD_STREAM_START,
+	GTB_ENC_CMD_FRAME_ENCODE,
+	GTB_ENC_CMD_FRAME_SKIP,
+	GTB_ENC_CMD_STREAM_STOP,
+	GTB_ENC_CMD_PARAMETER_UPD,
+	GTB_ENC_CMD_TERMINATE,
+	GTB_ENC_CMD_SNAPSHOT,
+	GTB_ENC_CMD_ROLL_SNAPSHOT,
+	GTB_ENC_CMD_LOCK_SCHEDULER,
+	GTB_ENC_CMD_UNLOCK_SCHEDULER,
+	GTB_ENC_CMD_CONFIGURE_CODEC,
+	GTB_ENC_CMD_DEAD_MARK,
+	GTB_ENC_CMD_FIRM_RESET,
+	GTB_ENC_CMD_FW_STATUS,
+	GTB_ENC_CMD_RESERVED
+};
+
+enum {
+	VID_API_EVENT_UNDEFINED = 0x0,
+	VID_API_ENC_EVENT_RESET_DONE = 0x1,
+	VID_API_ENC_EVENT_START_DONE,
+	VID_API_ENC_EVENT_STOP_DONE,
+	VID_API_ENC_EVENT_TERMINATE_DONE,
+	VID_API_ENC_EVENT_FRAME_INPUT_DONE,
+	VID_API_ENC_EVENT_FRAME_DONE,
+	VID_API_ENC_EVENT_FRAME_RELEASE,
+	VID_API_ENC_EVENT_PARA_UPD_DONE,
+	VID_API_ENC_EVENT_MEM_REQUEST,
+	VID_API_ENC_EVENT_FIRMWARE_XCPT,
+	VID_API_ENC_EVENT_RESERVED
+};
+
+enum {
+	MEDIAIP_ENC_PIC_TYPE_B_FRAME = 0,
+	MEDIAIP_ENC_PIC_TYPE_P_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_I_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_IDR_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_BI_FRAME
+};
+
+struct windsor_iface {
+	u32 exec_base_addr;
+	u32 exec_area_size;
+	struct vpu_rpc_buffer_desc cmd_buffer_desc;
+	struct vpu_rpc_buffer_desc msg_buffer_desc;
+	u32 cmd_int_enable[VID_API_NUM_STREAMS];
+	u32 fw_version;
+	u32 mvd_fw_offset;
+	u32 max_streams;
+	u32 ctrl_iface[VID_API_NUM_STREAMS];
+	struct vpu_rpc_system_config system_config;
+	u32 api_version;
+	struct vpu_rpc_buffer_desc log_buffer_desc;
+};
+
+struct windsor_ctrl_iface {
+	u32 enc_yuv_buffer_desc;
+	u32 enc_stream_buffer_desc;
+	u32 enc_expert_mode_param;
+	u32 enc_param;
+	u32 enc_mem_pool;
+	u32 enc_encoding_status;
+	u32 enc_dsa_status;
+};
+
+struct vpu_enc_yuv_desc {
+	u32 frame_id;
+	u32 luma_base;
+	u32 chroma_base;
+	u32 param_idx;
+	u32 key_frame;
+};
+
+struct vpu_enc_calib_params {
+	u32 use_ame;
+
+	u32 cme_mvx_max;
+	u32 cme_mvy_max;
+	u32 ame_prefresh_y0;
+	u32 ame_prefresh_y1;
+	u32 fme_min_sad;
+	u32 cme_min_sad;
+
+	u32 fme_pred_int_weight;
+	u32 fme_pred_hp_weight;
+	u32 fme_pred_qp_weight;
+	u32 fme_cost_weight;
+	u32 fme_act_thold;
+	u32 fme_sad_thold;
+	u32 fme_zero_sad_thold;
+
+	u32 fme_lrg_mvx_lmt;
+	u32 fme_lrg_mvy_lmt;
+	u32 fme_force_mode;
+	u32 fme_force4mvcost;
+	u32 fme_force2mvcost;
+
+	u32 h264_inter_thrd;
+
+	u32 i16x16_mode_cost;
+	u32 i4x4_mode_lambda;
+	u32 i8x8_mode_lambda;
+
+	u32 inter_mod_mult;
+	u32 inter_sel_mult;
+	u32 inter_bid_cost;
+	u32 inter_bwd_cost;
+	u32 inter_4mv_cost;
+	s32 one_mv_i16_cost;
+	s32 one_mv_i4x4_cost;
+	s32 one_mv_i8x8_cost;
+	s32 two_mv_i16_cost;
+	s32 two_mv_i4x4_cost;
+	s32 two_mv_i8x8_cost;
+	s32 four_mv_i16_cost;
+	s32 four_mv_i4x4_cost;
+	s32 four_mv_i8x8_cost;
+
+	u32 intra_pred_enab;
+	u32 intra_chr_pred;
+	u32 intra16_pred;
+	u32 intra4x4_pred;
+	u32 intra8x8_pred;
+
+	u32 cb_base;
+	u32 cb_size;
+	u32 cb_head_room;
+
+	u32 mem_page_width;
+	u32 mem_page_height;
+	u32 mem_total_size;
+	u32 mem_chunk_phys_addr;
+	u32 mem_chunk_virt_addr;
+	u32 mem_chunk_size;
+	u32 mem_y_stride;
+	u32 mem_uv_stride;
+
+	u32 split_wr_enab;
+	u32 split_wr_req_size;
+	u32 split_rd_enab;
+	u32 split_rd_req_size;
+};
+
+struct vpu_enc_config_params {
+	u32 param_change;
+	u32 start_frame;
+	u32 end_frame;
+	u32 userdata_enable;
+	u32 userdata_id[4];
+	u32 userdata_message[WINDSOR_USER_DATA_WORDS];
+	u32 userdata_length;
+	u32 h264_profile_idc;
+	u32 h264_level_idc;
+	u32 h264_au_delimiter;
+	u32 h264_seq_end_code;
+	u32 h264_recovery_points;
+	u32 h264_vui_parameters;
+	u32 h264_aspect_ratio_present;
+	u32 h264_aspect_ratio_sar_width;
+	u32 h264_aspect_ratio_sar_height;
+	u32 h264_overscan_present;
+	u32 h264_video_type_present;
+	u32 h264_video_format;
+	u32 h264_video_full_range;
+	u32 h264_video_colour_descriptor;
+	u32 h264_video_colour_primaries;
+	u32 h264_video_transfer_char;
+	u32 h264_video_matrix_coeff;
+	u32 h264_chroma_loc_info_present;
+	u32 h264_chroma_loc_type_top;
+	u32 h264_chroma_loc_type_bot;
+	u32 h264_timing_info_present;
+	u32 h264_buffering_period_present;
+	u32 h264_low_delay_hrd_flag;
+	u32 aspect_ratio;
+	u32 test_mode;                  // Automated firmware test mode
+	u32 dsa_test_mode;              // Automated test mode for the DSA.
+	u32 fme_test_mode;              // Automated test mode for the fme
+	u32 cbr_row_mode;               //0: FW mode; 1: HW mode
+	u32 windsor_mode;               //0: normal mode; 1: intra only mode; 2: intra+0MV mode
+	u32 encode_mode;                // H264, VC1, MPEG2, DIVX
+	u32 frame_width;                // display width
+	u32 frame_height;               // display height
+	u32 enc_frame_width;            // encoding width, should be 16-pix align
+	u32 enc_frame_height;           // encoding height, should be 16-pix aligned
+	u32 frame_rate_num;
+	u32 frame_rate_den;
+	u32 vi_field_source;
+	u32 vi_frame_width;
+	u32 vi_frame_height;
+	u32 crop_frame_width;
+	u32 crop_frame_height;
+	u32 crop_x_start_posn;
+	u32 crop_y_start_posn;
+	u32 mode422;
+	u32 mode_yuy2;
+	u32 dsa_luma_en;
+	u32 dsa_chroma_en;
+	u32 dsa_ext_hfilt_en;
+	u32 dsa_di_en;
+	u32 dsa_di_top_ref;
+	u32 dsa_vertf_disable;
+	u32 dsa_disable_pwb;
+	u32 dsa_hor_phase;
+	u32 dsa_ver_phase;
+	u32 dsa_iac_enable;
+	u32 iac_sc_threshold;
+	u32 iac_vm_threshold;
+	u32 iac_skip_mode;
+	u32 iac_grp_width;
+	u32 iac_grp_height;
+	u32 rate_control_mode;
+	u32 rate_control_resolution;
+	u32 buffer_size;
+	u32 buffer_level_init;
+	u32 buffer_I_bit_budget;
+	u32 top_field_first;
+	u32 intra_lum_qoffset;
+	u32 intra_chr_qoffset;
+	u32 inter_lum_qoffset;
+	u32 inter_chr_qoffset;
+	u32 use_def_scaling_mtx;
+	u32 inter_8x8_enab;
+	u32 inter_4x4_enab;
+	u32 fme_enable_qpel;
+	u32 fme_enable_hpel;
+	u32 fme_nozeromv;
+	u32 fme_predmv_en;
+	u32 fme_pred_2mv4mv;
+	u32 fme_smallsadthresh;
+	u32 ame_en_lmvc;
+	u32 ame_x_mult;
+	u32 cme_enable_4mv;
+	u32 cme_enable_1mv;
+	u32 hme_enable_16x8mv;
+	u32 hme_enable_8x16mv;
+	u32 cme_mv_weight;
+	u32 cme_mv_cost;
+	u32 ame_mult_mv;
+	u32 ame_shift_mv;
+	u32 hme_forceto1mv_en;
+	u32 hme_2mv_cost;
+	u32 hme_pred_mode;
+	u32 hme_sc_rnge;
+	u32 hme_sw_rnge;
+	u32 output_format;
+	u32 timestamp_enab;
+	u32 initial_pts_enab;
+	u32 initial_pts;
+};
+
+struct vpu_enc_static_params {
+	u32 param_change;
+	u32 gop_length;
+	u32 rate_control_bitrate;
+	u32 rate_control_bitrate_min;
+	u32 rate_control_bitrate_max;
+	u32 rate_control_content_models;
+	u32 rate_control_iframe_maxsize;
+	u32 rate_control_qp_init;
+	u32 rate_control_islice_qp;
+	u32 rate_control_pslice_qp;
+	u32 rate_control_bslice_qp;
+	u32 adaptive_quantization;
+	u32 aq_variance;
+	u32 cost_optimization;
+	u32 fdlp_mode;
+	u32 enable_isegbframes;
+	u32 enable_adaptive_keyratio;
+	u32 keyratio_imin;
+	u32 keyratio_imax;
+	u32 keyratio_pmin;
+	u32 keyratio_pmax;
+	u32 keyratio_bmin;
+	u32 keyratio_bmax;
+	s32 keyratio_istep;
+	s32 keyratio_pstep;
+	s32 keyratio_bstep;
+	u32 enable_paff;
+	u32 enable_b_frame_ref;
+	u32 enable_adaptive_gop;
+	u32 enable_closed_gop;
+	u32 open_gop_refresh_freq;
+	u32 enable_adaptive_sc;
+	u32 enable_fade_detection;
+	s32 fade_detection_threshold;
+	u32 enable_repeat_b;
+	u32 enable_low_delay_b;
+};
+
+struct vpu_enc_dynamic_params {
+	u32 param_change;
+	u32 rows_per_slice;
+	u32 mbaff_enable;
+	u32 dbf_enable;
+	u32 field_source;
+	u32 gop_b_length;
+	u32 mb_group_size;
+	u32 cbr_rows_per_group;
+	u32 skip_enable;
+	u32 pts_bits_0_to_31;
+	u32 pts_bit_32;
+	u32 rm_expsv_cff;
+	u32 const_ipred;
+	s32 chr_qp_offset;
+	u32 intra_mb_qp_offset;
+	u32 h264_cabac_init_method;
+	u32 h264_cabac_init_idc;
+	u32 h264_cabac_enable;
+	s32 alpha_c0_offset_div2;
+	s32 beta_offset_div2;
+	u32 intra_prefresh_y0;
+	u32 intra_prefresh_y1;
+	u32 dbg_dump_rec_src;
+};
+
+struct vpu_enc_expert_mode_param {
+	struct vpu_enc_calib_params calib_param;
+	struct vpu_enc_config_params config_param;
+	struct vpu_enc_static_params static_param;
+	struct vpu_enc_dynamic_params dynamic_param;
+};
+
+enum MEDIAIP_ENC_FMT {
+	MEDIAIP_ENC_FMT_H264 = 0,
+	MEDIAIP_ENC_FMT_VC1,
+	MEDIAIP_ENC_FMT_MPEG2,
+	MEDIAIP_ENC_FMT_MPEG4SP,
+	MEDIAIP_ENC_FMT_H263,
+	MEDIAIP_ENC_FMT_MPEG1,
+	MEDIAIP_ENC_FMT_SHORT_HEADER,
+	MEDIAIP_ENC_FMT_NULL
+};
+
+enum MEDIAIP_ENC_PROFILE {
+	MEDIAIP_ENC_PROF_MPEG2_SP = 0,
+	MEDIAIP_ENC_PROF_MPEG2_MP,
+	MEDIAIP_ENC_PROF_MPEG2_HP,
+	MEDIAIP_ENC_PROF_H264_BP,
+	MEDIAIP_ENC_PROF_H264_MP,
+	MEDIAIP_ENC_PROF_H264_HP,
+	MEDIAIP_ENC_PROF_MPEG4_SP,
+	MEDIAIP_ENC_PROF_MPEG4_ASP,
+	MEDIAIP_ENC_PROF_VC1_SP,
+	MEDIAIP_ENC_PROF_VC1_MP,
+	MEDIAIP_ENC_PROF_VC1_AP
+};
+
+enum MEDIAIP_ENC_BITRATE_MODE {
+	MEDIAIP_ENC_BITRATE_MODE_VBR          = 0x00000001,
+	MEDIAIP_ENC_BITRATE_MODE_CBR          = 0x00000002,
+	MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP  = 0x00000004
+};
+
+struct vpu_enc_memory_resource {
+	u32 phys;
+	u32 virt;
+	u32 size;
+};
+
+struct vpu_enc_param {
+	enum MEDIAIP_ENC_FMT codec_mode;
+	enum MEDIAIP_ENC_PROFILE profile;
+	u32 level;
+
+	struct vpu_enc_memory_resource enc_mem_desc;
+
+	u32 frame_rate;
+	u32 src_stride;
+	u32 src_width;
+	u32 src_height;
+	u32 src_offset_x;
+	u32 src_offset_y;
+	u32 src_crop_width;
+	u32 src_crop_height;
+	u32 out_width;
+	u32 out_height;
+	u32 iframe_interval;
+	u32 bframes;
+	u32 low_latency_mode;
+
+	enum MEDIAIP_ENC_BITRATE_MODE  bitrate_mode;
+	u32 target_bitrate;
+	u32 max_bitrate;
+	u32 min_bitrate;
+	u32 init_slice_qp;
+};
+
+struct vpu_enc_mem_pool {
+	struct vpu_enc_memory_resource enc_frames[WINDSOR_MAX_SRC_FRAMES];
+	struct vpu_enc_memory_resource ref_frames[WINDSOR_MAX_REF_FRAMES];
+	struct vpu_enc_memory_resource act_frame;
+};
+
+struct vpu_enc_encoding_status {
+	u32   frame_id;
+	u32   error_flag;   //Error type
+	u32   mb_y;
+	u32   mb_x;
+	u32   reserved[12];
+
+};
+
+struct vpu_enc_dsa_status {
+	u32   frame_id;
+	u32   dsa_cyle;
+	u32   mb_y;
+	u32   mb_x;
+	u32   reserved[4];
+};
+
+struct vpu_enc_ctrl {
+	struct vpu_enc_yuv_desc *yuv_desc;
+	struct vpu_rpc_buffer_desc *stream_desc;
+	struct vpu_enc_expert_mode_param *expert;
+	struct vpu_enc_param *param;
+	struct vpu_enc_mem_pool *pool;
+	struct vpu_enc_encoding_status *status;
+	struct vpu_enc_dsa_status *dsa;
+};
+
+struct vpu_enc_host_ctrls {
+	struct vpu_enc_ctrl ctrls[VID_API_NUM_STREAMS];
+};
+
+struct windsor_pic_info {
+	u32 frame_id;
+	u32 pic_encod_done;
+	u32 pic_type;
+	u32 skipped_frame;
+	u32 error_flag;
+	u32 psnr;
+	u32 flush_done;
+	u32 mb_y;
+	u32 mb_x;
+	u32 frame_size;
+	u32 frame_enc_ttl_cycles;
+	u32 frame_enc_ttl_frm_cycles;
+	u32 frame_enc_ttl_slc_cycles;
+	u32 frame_enc_ttl_enc_cycles;
+	u32 frame_enc_ttl_hme_cycles;
+	u32 frame_enc_ttl_dsa_cycles;
+	u32 frame_enc_fw_cycles;
+	u32 frame_crc;
+	u32 num_interrupts_1;
+	u32 num_interrupts_2;
+	u32 poc;
+	u32 ref_info;
+	u32 pic_num;
+	u32 pic_activity;
+	u32 scene_change;
+	u32 mb_stats;
+	u32 enc_cache_count0;
+	u32 enc_cache_count1;
+	u32 mtl_wr_strb_cnt;
+	u32 mtl_rd_strb_cnt;
+	u32 str_buff_wptr;
+	u32 diagnosticEvents;
+	u32 proc_iacc_tot_rd_cnt;
+	u32 proc_dacc_tot_rd_cnt;
+	u32 proc_dacc_tot_wr_cnt;
+	u32 proc_dacc_reg_rd_cnt;
+	u32 proc_dacc_reg_wr_cnt;
+	u32 proc_dacc_rng_rd_cnt;
+	u32 proc_dacc_rng_wr_cnt;
+	s32 tv_s;
+	u32 tv_ns;
+};
+
+u32 vpu_windsor_get_data_size(void)
+{
+	return sizeof(struct vpu_enc_host_ctrls);
+}
+
+static struct vpu_enc_yuv_desc *get_yuv_desc(struct vpu_shared_addr *shared,
+						u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].yuv_desc;
+}
+
+static struct vpu_enc_mem_pool *get_mem_pool(struct vpu_shared_addr *shared,
+						u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].pool;
+}
+
+static struct vpu_rpc_buffer_desc *get_stream_buf_desc(struct vpu_shared_addr *shared,
+							u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].stream_desc;
+}
+
+static struct vpu_enc_expert_mode_param *get_expert_param(struct vpu_shared_addr *shared,
+							u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].expert;
+}
+
+static struct vpu_enc_param *get_enc_param(struct vpu_shared_addr *shared,
+						u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].param;
+}
+
+static u32 get_ptr(u32 ptr)
+{
+	return (ptr | 0x80000000);
+}
+
+void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr)
+{
+	unsigned long base_phy_addr;
+	unsigned long phy_addr;
+	unsigned long offset;
+	struct windsor_iface *iface;
+	struct windsor_ctrl_iface *ctrl;
+	struct vpu_enc_host_ctrls *hcs;
+	unsigned int i;
+
+	WARN_ON(!shared || !shared->priv);
+	WARN_ON(!rpc || !rpc->phys || !rpc->length || rpc->phys < boot_addr);
+
+	base_phy_addr = rpc->phys - boot_addr;
+	iface = rpc->virt;
+	shared->iface = iface;
+	shared->boot_addr = boot_addr;
+	hcs = shared->priv;
+
+	iface->exec_base_addr = base_phy_addr;
+	iface->exec_area_size = rpc->length;
+
+	offset = sizeof(struct windsor_iface);
+	phy_addr = base_phy_addr + offset;
+	shared->cmd_desc = &iface->cmd_buffer_desc;
+	shared->cmd_mem_vir = rpc->virt + offset;
+	iface->cmd_buffer_desc.start =
+	iface->cmd_buffer_desc.rptr =
+	iface->cmd_buffer_desc.wptr = phy_addr;
+	iface->cmd_buffer_desc.end = iface->cmd_buffer_desc.start + CMD_SIZE;
+
+	offset += CMD_SIZE;
+	phy_addr = base_phy_addr + offset;
+	shared->msg_desc = &iface->msg_buffer_desc;
+	shared->msg_mem_vir = rpc->virt + offset;
+	iface->msg_buffer_desc.start =
+	iface->msg_buffer_desc.wptr =
+	iface->msg_buffer_desc.rptr = phy_addr;
+	iface->msg_buffer_desc.end = iface->msg_buffer_desc.start + MSG_SIZE;
+
+	offset += MSG_SIZE;
+	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {
+		iface->ctrl_iface[i] = base_phy_addr + offset;
+		offset += sizeof(struct windsor_ctrl_iface);
+	}
+	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {
+		ctrl = rpc->virt + (iface->ctrl_iface[i] - base_phy_addr);
+
+		ctrl->enc_yuv_buffer_desc = base_phy_addr + offset;
+		hcs->ctrls[i].yuv_desc = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_yuv_desc);
+
+		ctrl->enc_stream_buffer_desc = base_phy_addr + offset;
+		hcs->ctrls[i].stream_desc = rpc->virt + offset;
+		offset += sizeof(struct vpu_rpc_buffer_desc);
+
+		ctrl->enc_expert_mode_param = base_phy_addr + offset;
+		hcs->ctrls[i].expert = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_expert_mode_param);
+
+		ctrl->enc_param = base_phy_addr + offset;
+		hcs->ctrls[i].param = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_param);
+
+		ctrl->enc_mem_pool = base_phy_addr + offset;
+		hcs->ctrls[i].pool = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_mem_pool);
+
+		ctrl->enc_encoding_status = base_phy_addr + offset;
+		hcs->ctrls[i].status = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_encoding_status);
+
+		ctrl->enc_dsa_status = base_phy_addr + offset;
+		hcs->ctrls[i].dsa = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_dsa_status);
+	}
+
+	rpc->bytesused = offset;
+}
+
+void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log)
+{
+	struct windsor_iface *iface;
+
+	WARN_ON(!shared || !log || !log->phys);
+
+	vpu_dbg(LVL_DEBUG, "set log area <0x%llx, 0x%x> (0x%lx)\n",
+			log->phys, log->length, shared->boot_addr);
+	iface = shared->iface;
+	iface->log_buffer_desc.start =
+	iface->log_buffer_desc.wptr =
+	iface->log_buffer_desc.rptr = log->phys - shared->boot_addr;
+	iface->log_buffer_desc.end = iface->log_buffer_desc.start + log->length;
+}
+
+void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id)
+{
+	struct windsor_iface *iface;
+	struct vpu_rpc_system_config *config;
+
+	WARN_ON(!shared || !shared->iface);
+
+	iface = shared->iface;
+	config = &iface->system_config;
+
+	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);
+}
+
+int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared)
+{
+	return 0x300000;
+}
+
+static struct vpu_pair windsor_cmds[] = {
+	{VPU_CMD_ID_CONFIGURE_CODEC, GTB_ENC_CMD_CONFIGURE_CODEC},
+	{VPU_CMD_ID_START, GTB_ENC_CMD_STREAM_START},
+	{VPU_CMD_ID_STOP, GTB_ENC_CMD_STREAM_STOP},
+	{VPU_CMD_ID_FRAME_ENCODE, GTB_ENC_CMD_FRAME_ENCODE},
+	{VPU_CMD_ID_SNAPSHOT, GTB_ENC_CMD_SNAPSHOT},
+	{VPU_CMD_ID_FIRM_RESET, GTB_ENC_CMD_FIRM_RESET},
+	{VPU_CMD_ID_UPDATE_PARAMETER, GTB_ENC_CMD_PARAMETER_UPD},
+	{VPU_CMD_ID_DEBUG, GTB_ENC_CMD_FW_STATUS}
+};
+
+static struct vpu_pair windsor_msgs[] = {
+	{VPU_MSG_ID_RESET_DONE, VID_API_ENC_EVENT_RESET_DONE},
+	{VPU_MSG_ID_START_DONE, VID_API_ENC_EVENT_START_DONE},
+	{VPU_MSG_ID_STOP_DONE, VID_API_ENC_EVENT_STOP_DONE},
+	{VPU_MSG_ID_FRAME_INPUT_DONE, VID_API_ENC_EVENT_FRAME_INPUT_DONE},
+	{VPU_MSG_ID_ENC_DONE, VID_API_ENC_EVENT_FRAME_DONE},
+	{VPU_MSG_ID_FRAME_RELEASE, VID_API_ENC_EVENT_FRAME_RELEASE},
+	{VPU_MSG_ID_MEM_REQUEST, VID_API_ENC_EVENT_MEM_REQUEST},
+	{VPU_MSG_ID_PARAM_UPD_DONE, VID_API_ENC_EVENT_PARA_UPD_DONE},
+	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_ENC_EVENT_FIRMWARE_XCPT},
+};
+
+int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)
+{
+	int ret;
+	s64 timestamp;
+
+	WARN_ON(!pkt);
+
+	ret = vpu_find_dst_by_src(windsor_cmds, ARRAY_SIZE(windsor_cmds), id);
+	if (ret < 0)
+		return ret;
+	pkt->hdr.id = ret;
+	pkt->hdr.num = 0;
+	pkt->hdr.index = index;
+	if (id == VPU_CMD_ID_FRAME_ENCODE) {
+		pkt->hdr.num = 2;
+		timestamp = *(s64 *)data;
+		if (timestamp < 0) {
+			pkt->data[0] = (u32)-1;
+			pkt->data[1] = 0;
+		} else {
+			pkt->data[0] = timestamp / NSEC_PER_SEC;
+			pkt->data[1] = timestamp % NSEC_PER_SEC;
+		}
+	}
+
+	return 0;
+}
+
+int vpu_windsor_convert_msg_id(u32 id)
+{
+	return vpu_find_src_by_dst(windsor_msgs, ARRAY_SIZE(windsor_msgs), id);
+}
+
+static void vpu_windsor_unpack_pic_info(struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_enc_pic_info *info = data;
+	struct windsor_pic_info *windsor = (struct windsor_pic_info *)pkt->data;
+
+	info->frame_id = windsor->frame_id;
+	switch (windsor->pic_type) {
+	case MEDIAIP_ENC_PIC_TYPE_I_FRAME:
+	case MEDIAIP_ENC_PIC_TYPE_IDR_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_KEYFRAME;
+		break;
+	case MEDIAIP_ENC_PIC_TYPE_P_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_PFRAME;
+		break;
+	case MEDIAIP_ENC_PIC_TYPE_B_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_BFRAME;
+		break;
+	default:
+		break;
+	}
+	info->skipped_frame = windsor->skipped_frame;
+	info->error_flag = windsor->error_flag;
+	info->psnr = windsor->psnr;
+	info->frame_size = windsor->frame_size;
+	info->wptr = get_ptr(windsor->str_buff_wptr);
+	info->crc = windsor->frame_crc;
+	info->timestamp = MAKE_TIMESTAMP(windsor->tv_s, windsor->tv_ns);
+}
+
+static void vpu_windsor_unpack_mem_req(struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_pkt_mem_req_data *req_data = data;
+
+	req_data->enc_frame_size = pkt->data[0];
+	req_data->enc_frame_num = pkt->data[1];
+	req_data->ref_frame_size = pkt->data[2];
+	req_data->ref_frame_num = pkt->data[3];
+	req_data->act_buf_size = pkt->data[4];
+	req_data->act_buf_num = 1;
+}
+
+int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)
+{
+	if (!pkt || !data)
+		return -EINVAL;
+
+	switch (pkt->hdr.id) {
+	case VID_API_ENC_EVENT_FRAME_DONE:
+		vpu_windsor_unpack_pic_info(pkt, data);
+		break;
+	case VID_API_ENC_EVENT_MEM_REQUEST:
+		vpu_windsor_unpack_mem_req(pkt, data);
+		break;
+	case VID_API_ENC_EVENT_FRAME_RELEASE:
+		*(u32 *)data = pkt->data[0];
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_fill_yuv_frame(struct vpu_shared_addr *shared,
+				u32 instance,
+				struct vb2_buffer *vb)
+{
+	struct vpu_enc_yuv_desc *desc;
+	struct vb2_v4l2_buffer *vbuf;
+
+	WARN_ON(!shared || !vb || instance >= VID_API_NUM_STREAMS);
+
+	desc = get_yuv_desc(shared, instance);
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	vpu_dbg(LVL_DEBUG, "fill yuv with id : %d\n", vbuf->sequence);
+	desc->frame_id = vbuf->sequence;
+	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+		desc->key_frame = 1;
+	else
+		desc->key_frame = 0;
+	desc->luma_base = vpu_get_vb_phy_addr(vb, 0);
+	desc->chroma_base = vpu_get_vb_phy_addr(vb, 1);
+
+	return 0;
+}
+
+int vpu_windsor_input_frame(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	vpu_windsor_fill_yuv_frame(shared, inst->id, vb);
+	return vpu_session_encode_frame(inst, vb->timestamp);
+}
+
+int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,
+					u32 instance,
+					u32 type,
+					u32 index,
+					struct vpu_buffer *buf)
+{
+	struct vpu_enc_mem_pool *pool;
+	struct vpu_enc_memory_resource *res;
+
+	WARN_ON(!shared || !buf || instance >= VID_API_NUM_STREAMS);
+
+	pool = get_mem_pool(shared, instance);
+
+	switch (type) {
+	case MEM_RES_ENC:
+		res = &pool->enc_frames[index];
+		break;
+	case MEM_RES_REF:
+		res = &pool->ref_frames[index];
+		break;
+	case MEM_RES_ACT:
+		res = &pool->act_frame;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	res->phys = buf->phys;
+	res->virt = buf->phys - shared->boot_addr;
+	res->size = buf->length;
+
+	vpu_dbg(LVL_DEBUG, "[%d] type = %d, phys = 0x%x, size = 0x%x\n",
+			instance, type, res->phys, res->size);
+
+	return 0;
+}
+
+int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance,
+					struct vpu_buffer *buf)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	struct vpu_enc_expert_mode_param *expert;
+
+	desc = get_stream_buf_desc(shared, instance);
+	expert = get_expert_param(shared, instance);
+
+	desc->start = desc->wptr = desc->rptr = buf->phys;
+	desc->end = buf->phys + buf->length;
+
+	vpu_dbg(LVL_DEBUG, "stream_buf:[0x%x, 0x%x]\n", desc->start, desc->end);
+
+	expert->calib_param.mem_chunk_phys_addr = 0;
+	expert->calib_param.mem_chunk_virt_addr = 0;
+	expert->calib_param.mem_chunk_size = 0;
+	expert->calib_param.cb_base = buf->phys;
+	expert->calib_param.cb_size = buf->length;
+
+	return 0;
+}
+
+static void vpu_windsor_update_wptr(struct vpu_rpc_buffer_desc *desc, u32 wptr)
+{
+	u32 pre_wptr = get_ptr(desc->wptr);
+	u32 new_wptr = get_ptr(wptr);
+	u32 rptr = get_ptr(desc->rptr);
+	u32 size = get_ptr(desc->end) - get_ptr(desc->start);
+	u32 space = (rptr + size - pre_wptr) % size;
+	u32 step = (new_wptr + size - pre_wptr) % size;
+
+	if (space && step > space)
+		vpu_err("update wptr from 0x%x to 0x%x, cross over rptr 0x%x\n",
+				pre_wptr, new_wptr, rptr);
+
+	desc->wptr = wptr;
+}
+
+static void vpu_windsor_update_rptr(struct vpu_rpc_buffer_desc *desc, u32 rptr)
+{
+	u32 pre_rptr = get_ptr(desc->rptr);
+	u32 new_rptr = get_ptr(rptr);
+	u32 wptr = get_ptr(desc->wptr);
+	u32 size = get_ptr(desc->end) - get_ptr(desc->start);
+	u32 space = (wptr + size - pre_rptr) % size;
+	u32 step = (new_rptr + size - pre_rptr) % size;
+
+	if (step > space)
+		vpu_err("update rptr from 0x%x to 0x%x, cross over wptr 0x%x\n",
+				pre_rptr, new_rptr, wptr);
+
+	desc->rptr = rptr;
+}
+
+int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance, u32 ptr, bool write)
+{
+	struct vpu_rpc_buffer_desc *desc;
+
+	desc = get_stream_buf_desc(shared, instance);
+
+	/*update wptr/rptr after data is written or read*/
+	mb();
+	if (write)
+		vpu_windsor_update_wptr(desc, ptr);
+	else
+		vpu_windsor_update_rptr(desc, ptr);
+
+	return 0;
+}
+
+int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_rpc_buffer_desc *rpc_desc;
+
+	rpc_desc = get_stream_buf_desc(shared, instance);
+	if (desc) {
+		desc->wptr = get_ptr(rpc_desc->wptr);
+		desc->rptr = get_ptr(rpc_desc->rptr);
+		desc->start = get_ptr(rpc_desc->start);
+		desc->end = get_ptr(rpc_desc->end);
+	}
+
+	return 0;
+}
+
+u32 vpu_windsor_get_version(struct vpu_shared_addr *shared)
+{
+	struct windsor_iface *iface;
+
+	WARN_ON(!shared || !shared->iface);
+
+	iface = shared->iface;
+	return iface->fw_version;
+}
+
+static int vpu_windsor_set_frame_rate(struct vpu_enc_expert_mode_param *expert,
+				struct vpu_encode_params *params)
+{
+	expert->config_param.frame_rate_num = params->frame_rate_num;
+	expert->config_param.frame_rate_den = params->frame_rate_den;
+
+	return 0;
+}
+
+static int vpu_windsor_set_format(struct vpu_enc_param *param, u32 pixelformat)
+{
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_H264:
+		param->codec_mode = MEDIAIP_ENC_FMT_H264;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_set_profile(struct vpu_enc_param *param, u32 profile)
+{
+	switch (profile) {
+	case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+		param->profile = MEDIAIP_ENC_PROF_H264_BP;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+		param->profile = MEDIAIP_ENC_PROF_H264_MP;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+		param->profile = MEDIAIP_ENC_PROF_H264_HP;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const u32 h264_level[] = {
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_0] = 10,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1B]  = 14,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_1] = 11,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_2] = 12,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_3] = 13,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_0] = 20,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_1] = 21,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_2] = 22,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_0] = 30,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_1] = 31,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_2] = 32,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_0] = 40,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_1] = 41,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_2] = 42,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_5_0] = 50,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_5_1] = 51
+};
+
+static int vpu_windsor_set_level(struct vpu_enc_param *param, u32 level)
+{
+
+	if (level >= ARRAY_SIZE(h264_level))
+		return -EINVAL;
+
+	param->level = h264_level[level];
+
+	return 0;
+}
+
+static int vpu_windsor_set_size(struct vpu_enc_param *windsor,
+				struct vpu_encode_params *params)
+{
+	windsor->src_stride = params->src_stride;
+	windsor->src_width = params->src_width;
+	windsor->src_height = params->src_height;
+	windsor->src_offset_x = params->crop.left;
+	windsor->src_offset_y = params->crop.top;
+	windsor->src_crop_width = params->crop.width;
+	windsor->src_crop_height = params->crop.height;
+	windsor->out_width = params->out_width;
+	windsor->out_height = params->out_height;
+
+	vpu_dbg(LVL_DEBUG, "%d %dx%d (%d,%d) %dx%d, %dx%d\n",
+			windsor->src_stride,
+			windsor->src_width,
+			windsor->src_height,
+			windsor->src_offset_x,
+			windsor->src_offset_y,
+			windsor->src_crop_width,
+			windsor->src_crop_height,
+			windsor->out_width,
+			windsor->out_height);
+	return 0;
+}
+
+static int vpu_windsor_set_gop(struct vpu_enc_param *param, u32 gop)
+{
+	param->iframe_interval = gop;
+
+	return 0;
+}
+
+static int vpu_windsor_set_bframes(struct vpu_enc_param *param, u32 bframes)
+{
+	if (bframes) {
+		param->low_latency_mode = 0;
+		param->bframes = bframes;
+	} else {
+		param->low_latency_mode = 1;
+		param->bframes = 0;
+	}
+
+	if (param->low_latency_mode)
+		vpu_dbg(LVL_DEBUG, "low latency mode\n");
+
+	return 0;
+}
+
+static int vpu_windsor_set_bitrate_mode(struct vpu_enc_param *param, u32 mode)
+{
+	switch (mode) {
+	case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP;
+		break;
+	case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CBR;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u32 vpu_windsor_bitrate(u32 bitrate)
+{
+	return DIV_ROUND_CLOSEST(bitrate, WINDSOR_BITRATE_UNIT);
+}
+
+static int vpu_windsor_set_bitrate(struct vpu_enc_param *windsor,
+				struct vpu_encode_params *params)
+{
+	windsor->target_bitrate = vpu_windsor_bitrate(params->bitrate);
+	windsor->min_bitrate = vpu_windsor_bitrate(params->bitrate_min);
+	windsor->max_bitrate = vpu_windsor_bitrate(params->bitrate_max);
+
+	return 0;
+}
+
+static int vpu_windsor_set_qp(struct vpu_enc_expert_mode_param *expert,
+			struct vpu_encode_params *params)
+{
+	expert->static_param.rate_control_islice_qp = params->i_frame_qp;
+	expert->static_param.rate_control_pslice_qp = params->p_frame_qp;
+	expert->static_param.rate_control_bslice_qp = params->b_frame_qp;
+
+	return 0;
+}
+
+static int vpu_windsor_set_sar(struct vpu_enc_expert_mode_param *expert,
+			struct vpu_encode_params *params)
+{
+	expert->config_param.h264_aspect_ratio_present = params->sar.enable;
+	if (params->sar.idc == V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED)
+		expert->config_param.aspect_ratio = WINDSOR_H264_EXTENDED_SAR;
+	else
+		expert->config_param.aspect_ratio = params->sar.idc;
+	expert->config_param.h264_aspect_ratio_sar_width = params->sar.width;
+	expert->config_param.h264_aspect_ratio_sar_height = params->sar.height;
+
+
+	return 0;
+}
+
+static int vpu_windsor_set_color(struct vpu_enc_expert_mode_param *expert,
+			struct vpu_encode_params *params)
+{
+	expert->config_param.h264_video_type_present = 1;
+	expert->config_param.h264_video_format = 5;
+	expert->config_param.h264_video_colour_descriptor = 1;
+	expert->config_param.h264_video_colour_primaries =
+		vpu_color_cvrt_primaries_v2i(params->color.primaries);
+	expert->config_param.h264_video_transfer_char =
+		vpu_color_cvrt_transfers_v2i(params->color.transfer);
+	expert->config_param.h264_video_matrix_coeff =
+		vpu_color_cvrt_matrix_v2i(params->color.matrix);
+	expert->config_param.h264_video_full_range =
+		vpu_color_cvrt_full_range_v2i(params->color.full_range);
+	return 0;
+}
+
+static int vpu_windsor_update_bitrate(struct vpu_shared_addr *shared,
+				u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_param *windsor;
+	struct vpu_enc_expert_mode_param *expert;
+
+	windsor = get_enc_param(shared, instance);
+	expert = get_expert_param(shared, instance);
+
+	if (windsor->bitrate_mode != MEDIAIP_ENC_BITRATE_MODE_CBR)
+		return 0;
+	if (params->rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+		return 0;
+	if (vpu_windsor_bitrate(params->bitrate) == windsor->target_bitrate)
+		return 0;
+
+	vpu_windsor_set_bitrate(windsor, params);
+	expert->static_param.rate_control_bitrate = windsor->target_bitrate;
+	expert->static_param.rate_control_bitrate_min = windsor->min_bitrate;
+	expert->static_param.rate_control_bitrate_max = windsor->max_bitrate;
+
+	return 0;
+}
+
+static int vpu_windsor_set_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_param *windsor;
+	int ret;
+
+	windsor = get_enc_param(shared, instance);
+
+	if (params->input_format != V4L2_PIX_FMT_NV12)
+		return -EINVAL;
+
+	ret = vpu_windsor_set_format(windsor, params->codec_format);
+	if (ret)
+		return ret;
+	vpu_windsor_set_profile(windsor, params->profile);
+	vpu_windsor_set_level(windsor, params->level);
+	vpu_windsor_set_size(windsor, params);
+	vpu_windsor_set_gop(windsor, params->gop_length);
+	vpu_windsor_set_bframes(windsor, params->bframes);
+	vpu_windsor_set_bitrate_mode(windsor, params->rc_mode);
+	vpu_windsor_set_bitrate(windsor, params);
+	windsor->init_slice_qp = params->i_frame_qp;
+
+	if (!params->frame_rate_num)
+		return -EINVAL;
+	windsor->frame_rate = params->frame_rate_den / params->frame_rate_num;
+
+	return 0;
+}
+
+static int vpu_windsor_update_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_expert_mode_param *expert;
+
+	expert = get_expert_param(shared, instance);
+
+	vpu_windsor_set_frame_rate(expert, params);
+	vpu_windsor_set_qp(expert, params);
+	vpu_windsor_set_sar(expert, params);
+	vpu_windsor_set_color(expert, params);
+	vpu_windsor_update_bitrate(shared, instance, params);
+	/*expert->config_param.iac_sc_threshold = 0;*/
+
+	return 0;
+}
+
+int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_encode_params *params, u32 update)
+{
+	if (!params)
+		return -EINVAL;
+
+	if (!update)
+		return vpu_windsor_set_params(shared, instance, params);
+	else
+		return vpu_windsor_update_params(shared, instance, params);
+}
+
+u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared)
+{
+	struct windsor_iface *iface;
+
+	WARN_ON(!shared || !shared->iface);
+
+	iface = shared->iface;
+
+	return iface->max_streams;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_windsor.h b/drivers/media/platform/imx/vpu-8q/vpu_windsor.h
new file mode 100644
index 000000000000..42545cd2b882
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_windsor.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_WINDSOR_H
+#define _IMX_VPU_WINDSOR_H
+
+u32 vpu_windsor_get_data_size(void);
+void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr);
+void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log);
+void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id);
+int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared);
+int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt,
+			u32 index, u32 id, void *data);
+int vpu_windsor_convert_msg_id(u32 msg_id);
+int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data);
+int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,
+			u32 instance, u32 type, u32 index,
+			struct vpu_buffer *buf);
+int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,
+			u32 instance, struct vpu_buffer *buf);
+int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,
+			u32 instance, u32 ptr, bool write);
+int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+			u32 instance, struct vpu_rpc_buffer_desc *desc);
+u32 vpu_windsor_get_version(struct vpu_shared_addr *shared);
+int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,
+			u32 instance,
+			struct vpu_encode_params *params,
+			u32 update);
+int vpu_windsor_input_frame(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb);
+u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared);
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:15 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:15 +0800
Subject: [PATCH v7 14/14] MAINTAINERS: add NXP IMX8Q VPU CODEC V4L2 driver
 entry
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <722cbe52af7ff428801552eb640e9093c1725b51.1630377507.git.ming.qian@nxp.com>

Add NXP IMX8Q VPU CODEC v4l2 driver entry

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 524eabe50d79..77d30a55983a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13416,6 +13416,16 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/imx8-jpeg.yaml
 F:	drivers/media/platform/imx-jpeg
 
+NXP i.MX 8QXP/8QM VPU CODEC V4L2 DRIVER
+M:	Ming Qian <ming.qian at nxp.com>
+M:	Shijie Qin <shijie.qin at nxp.com>
+M:	Zhou Peng <eagle.zhou at nxp.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/nxp,imx8q-vpu.yaml
+F:	drivers/media/platform/imx/vpu-8q/
+F:	include/uapi/linux/imx_vpu.h
+
 NZXT-KRAKEN2 HARDWARE MONITORING DRIVER
 M:	Jonas Malaco <jonas at protocubo.io>
 L:	linux-hwmon at vger.kernel.org
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:12 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:12 +0800
Subject: [PATCH v7 11/14] media: imx: imx8q: implement malone decoder rpc
 interface
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <873fdc96dc848ab6afcd88c765a58ef30471f8d1.1630377507.git.ming.qian@nxp.com>

This part implements the malone decoder rpc interface.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../media/platform/imx/vpu-8q/vpu_malone.c    | 1683 +++++++++++++++++
 .../media/platform/imx/vpu-8q/vpu_malone.h    |   42 +
 2 files changed, 1725 insertions(+)
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_malone.c
 create mode 100644 drivers/media/platform/imx/vpu-8q/vpu_malone.h

diff --git a/drivers/media/platform/imx/vpu-8q/vpu_malone.c b/drivers/media/platform/imx/vpu-8q/vpu_malone.c
new file mode 100644
index 000000000000..115582c09d2a
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_malone.c
@@ -0,0 +1,1683 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#define TAG		"MALONE"
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <linux/videodev2.h>
+#include <linux/imx_vpu.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_log.h"
+#include "vpu_imx8q.h"
+#include "vpu_malone.h"
+
+#define CMD_SIZE			25600
+#define MSG_SIZE			25600
+#define CODEC_SIZE			0x1000
+#define JPEG_SIZE			0x1000
+#define SEQ_SIZE			0x1000
+#define GOP_SIZE			0x1000
+#define PIC_SIZE			0x1000
+#define QMETER_SIZE			0x1000
+#define DBGLOG_SIZE			0x10000
+#define DEBUG_SIZE			0x80000
+#define ENG_SIZE			0x1000
+#define MALONE_SKIPPED_FRAME_ID		0x555
+
+#define MALONE_ALIGN_MBI		0x800
+#define MALONE_DCP_CHUNK_BIT		16
+#define MALONE_DCP_SIZE_MAX		0x3000000
+#define MALONE_DCP_SIZE_MIN		0x100000
+#define MALONE_DCP_FIXED_MB_ALLOC	250
+
+#define CONFIG_SET(val, cfg, pos, mask)		\
+		(*(cfg) |= (((val) << (pos)) & (mask)))
+//x means source data , y means destination data
+#define STREAM_CONFIG_FORMAT_SET(x, y)		CONFIG_SET(x, y, 0, 0x0000000F)
+#define STREAM_CONFIG_STRBUFIDX_SET(x, y)	CONFIG_SET(x, y, 8, 0x00000300)
+#define STREAM_CONFIG_NOSEQ_SET(x, y)		CONFIG_SET(x, y, 10, 0x00000400)
+#define STREAM_CONFIG_DEBLOCK_SET(x, y)		CONFIG_SET(x, y, 11, 0x00000800)
+#define STREAM_CONFIG_DERING_SET(x, y)		CONFIG_SET(x, y, 12, 0x00001000)
+#define STREAM_CONFIG_IBWAIT_SET(x, y)		CONFIG_SET(x, y, 13, 0x00002000)
+#define STREAM_CONFIG_FBC_SET(x, y)		CONFIG_SET(x, y, 14, 0x00004000)
+#define STREAM_CONFIG_PLAY_MODE_SET(x, y)	CONFIG_SET(x, y, 16, 0x00030000)
+#define STREAM_CONFIG_ENABLE_DCP_SET(x, y)	CONFIG_SET(x, y, 20, 0x00100000)
+#define STREAM_CONFIG_NUM_STR_BUF_SET(x, y)	CONFIG_SET(x, y, 21, 0x00600000)
+#define STREAM_CONFIG_MALONE_USAGE_SET(x, y)	CONFIG_SET(x, y, 23, 0x01800000)
+#define STREAM_CONFIG_MULTI_VID_SET(x, y)	CONFIG_SET(x, y, 25, 0x02000000)
+#define STREAM_CONFIG_OBFUSC_EN_SET(x, y)	CONFIG_SET(x, y, 26, 0x04000000)
+#define STREAM_CONFIG_RC4_EN_SET(x, y)		CONFIG_SET(x, y, 27, 0x08000000)
+#define STREAM_CONFIG_MCX_SET(x, y)		CONFIG_SET(x, y, 28, 0x10000000)
+#define STREAM_CONFIG_PES_SET(x, y)		CONFIG_SET(x, y, 29, 0x20000000)
+#define STREAM_CONFIG_NUM_DBE_SET(x, y)		CONFIG_SET(x, y, 30, 0x40000000)
+#define STREAM_CONFIG_FS_CTRL_MODE_SET(x, y)	CONFIG_SET(x, y, 31, 0x80000000)
+
+enum vpu_malone_stream_input_mode {
+	INVALID_MODE = 0,
+	FRAME_LVL,
+	NON_FRAME_LVL
+};
+
+enum vpu_malone_format {
+	MALONE_FMT_NULL = 0x0,
+	MALONE_FMT_AVC  = 0x1,
+	MALONE_FMT_MP2  = 0x2,
+	MALONE_FMT_VC1  = 0x3,
+	MALONE_FMT_AVS  = 0x4,
+	MALONE_FMT_ASP  = 0x5,
+	MALONE_FMT_JPG  = 0x6,
+	MALONE_FMT_RV   = 0x7,
+	MALONE_FMT_VP6  = 0x8,
+	MALONE_FMT_SPK  = 0x9,
+	MALONE_FMT_VP8  = 0xA,
+	MALONE_FMT_HEVC = 0xB,
+	MALONE_FMT_LAST = MALONE_FMT_HEVC
+};
+
+enum {
+	VID_API_CMD_NULL              = 0x00,
+	VID_API_CMD_PARSE_NEXT_SEQ    = 0x01,
+	VID_API_CMD_PARSE_NEXT_I      = 0x02,
+	VID_API_CMD_PARSE_NEXT_IP     = 0x03,
+	VID_API_CMD_PARSE_NEXT_ANY    = 0x04,
+	VID_API_CMD_DEC_PIC           = 0x05,
+	VID_API_CMD_UPDATE_ES_WR_PTR  = 0x06,
+	VID_API_CMD_UPDATE_ES_RD_PTR  = 0x07,
+	VID_API_CMD_UPDATE_UDATA      = 0x08,
+	VID_API_CMD_GET_FSINFO        = 0x09,
+	VID_API_CMD_SKIP_PIC          = 0x0a,
+	VID_API_CMD_DEC_CHUNK         = 0x0b,
+	VID_API_CMD_START             = 0x10,
+	VID_API_CMD_STOP              = 0x11,
+	VID_API_CMD_ABORT             = 0x12,
+	VID_API_CMD_RST_BUF           = 0x13,
+	VID_API_CMD_FS_RELEASE        = 0x15,
+	VID_API_CMD_MEM_REGION_ATTACH = 0x16,
+	VID_API_CMD_MEM_REGION_DETACH = 0x17,
+	VID_API_CMD_MVC_VIEW_SELECT   = 0x18,
+	VID_API_CMD_FS_ALLOC          = 0x19,
+	VID_API_CMD_DBG_GET_STATUS    = 0x1C,
+	VID_API_CMD_DBG_START_LOG     = 0x1D,
+	VID_API_CMD_DBG_STOP_LOG      = 0x1E,
+	VID_API_CMD_DBG_DUMP_LOG      = 0x1F,
+	VID_API_CMD_YUV_READY         = 0x20,
+	VID_API_CMD_TS                = 0x21,
+
+	VID_API_CMD_FIRM_RESET        = 0x40,
+
+	VID_API_CMD_SNAPSHOT          = 0xAA,
+	VID_API_CMD_ROLL_SNAPSHOT     = 0xAB,
+	VID_API_CMD_LOCK_SCHEDULER    = 0xAC,
+	VID_API_CMD_UNLOCK_SCHEDULER  = 0xAD,
+	VID_API_CMD_CQ_FIFO_DUMP      = 0xAE,
+	VID_API_CMD_DBG_FIFO_DUMP     = 0xAF,
+	VID_API_CMD_SVC_ILP           = 0xBB,
+	VID_API_CMD_FW_STATUS         = 0xF0,
+	VID_API_CMD_INVALID           = 0xFF
+};
+
+enum {
+	VID_API_EVENT_NULL			= 0x00,
+	VID_API_EVENT_RESET_DONE		= 0x01,
+	VID_API_EVENT_SEQ_HDR_FOUND		= 0x02,
+	VID_API_EVENT_PIC_HDR_FOUND		= 0x03,
+	VID_API_EVENT_PIC_DECODED		= 0x04,
+	VID_API_EVENT_FIFO_LOW			= 0x05,
+	VID_API_EVENT_FIFO_HIGH			= 0x06,
+	VID_API_EVENT_FIFO_EMPTY		= 0x07,
+	VID_API_EVENT_FIFO_FULL			= 0x08,
+	VID_API_EVENT_BS_ERROR			= 0x09,
+	VID_API_EVENT_UDATA_FIFO_UPTD		= 0x0A,
+	VID_API_EVENT_RES_CHANGE		= 0x0B,
+	VID_API_EVENT_FIFO_OVF			= 0x0C,
+	VID_API_EVENT_CHUNK_DECODED		= 0x0D,
+	VID_API_EVENT_REQ_FRAME_BUFF		= 0x10,
+	VID_API_EVENT_FRAME_BUFF_RDY		= 0x11,
+	VID_API_EVENT_REL_FRAME_BUFF		= 0x12,
+	VID_API_EVENT_STR_BUF_RST		= 0x13,
+	VID_API_EVENT_RET_PING			= 0x14,
+	VID_API_EVENT_QMETER			= 0x15,
+	VID_API_EVENT_STR_FMT_CHANGE		= 0x16,
+	VID_API_EVENT_FIRMWARE_XCPT		= 0x17,
+	VID_API_EVENT_START_DONE		= 0x18,
+	VID_API_EVENT_STOPPED			= 0x19,
+	VID_API_EVENT_ABORT_DONE		= 0x1A,
+	VID_API_EVENT_FINISHED			= 0x1B,
+	VID_API_EVENT_DBG_STAT_UPDATE		= 0x1C,
+	VID_API_EVENT_DBG_LOG_STARTED		= 0x1D,
+	VID_API_EVENT_DBG_LOG_STOPPED		= 0x1E,
+	VID_API_EVENT_DBG_LOG_UPDATED		= 0x1F,
+	VID_API_EVENT_DBG_MSG_DEC		= 0x20,
+	VID_API_EVENT_DEC_SC_ERR		= 0x21,
+	VID_API_EVENT_CQ_FIFO_DUMP		= 0x22,
+	VID_API_EVENT_DBG_FIFO_DUMP		= 0x23,
+	VID_API_EVENT_DEC_CHECK_RES		= 0x24,
+	VID_API_EVENT_DEC_CFG_INFO		= 0x25,
+	VID_API_EVENT_UNSUPPORTED_STREAM	= 0x26,
+	VID_API_EVENT_STR_SUSPENDED		= 0x30,
+	VID_API_EVENT_SNAPSHOT_DONE		= 0x40,
+	VID_API_EVENT_FW_STATUS                 = 0xF0,
+	VID_API_EVENT_INVALID			= 0xFF
+};
+
+struct vpu_malone_buffer_desc {
+	struct vpu_rpc_buffer_desc buffer;
+	u32 low;
+	u32 high;
+};
+
+struct vpu_malone_str_buffer {
+	u32 wptr;
+	u32 rptr;
+	u32 start;
+	u32 end;
+	u32 lwm;
+};
+
+struct vpu_malone_picth_info {
+	u32 frame_pitch;
+};
+
+struct vpu_malone_table_desc {
+	u32 array_base;
+	u32 size;
+};
+
+struct vpu_malone_dbglog_desc {
+	u32 addr;
+	u32 size;
+	u32 level;
+	u32 reserved;
+};
+
+struct vpu_malone_frame_buffer {
+	u32 addr;
+	u32 size;
+};
+
+struct vpu_malone_udata {
+	u32 base;
+	u32 total_size;
+	u32 slot_size;
+};
+
+struct vpu_malone_buffer_info {
+	u32 stream_input_mode;
+	u32 stream_pic_input_count;
+	u32 stream_pic_parsed_count;
+	u32 stream_buffer_threshold;
+	u32 stream_pic_end_flag;
+};
+
+struct vpu_malone_encrypt_info {
+	u32 rec4key[8];
+	u32 obfusc;
+};
+
+struct malone_iface {
+	u32 exec_base_addr;
+	u32 exec_area_size;
+	struct vpu_malone_buffer_desc cmd_buffer_desc;
+	struct vpu_malone_buffer_desc msg_buffer_desc;
+	u32 cmd_int_enable[VID_API_NUM_STREAMS];
+	struct vpu_malone_picth_info stream_pitch_info[VID_API_NUM_STREAMS];
+	u32 stream_config[VID_API_NUM_STREAMS];
+	struct vpu_malone_table_desc codec_param_tab_desc;
+	struct vpu_malone_table_desc jpeg_param_tab_desc;
+	u32 stream_buffer_desc[VID_API_NUM_STREAMS][VID_API_MAX_BUF_PER_STR];
+	struct vpu_malone_table_desc seq_info_tab_desc;
+	struct vpu_malone_table_desc pic_info_tab_desc;
+	struct vpu_malone_table_desc gop_info_tab_desc;
+	struct vpu_malone_table_desc qmeter_info_tab_desc;
+	u32 stream_error[VID_API_NUM_STREAMS];
+	u32 fw_version;
+	u32 fw_offset;
+	u32 max_streams;
+	struct vpu_malone_dbglog_desc dbglog_desc;
+	struct vpu_rpc_buffer_desc api_cmd_buffer_desc[VID_API_NUM_STREAMS];
+	struct vpu_malone_udata udata_buffer[VID_API_NUM_STREAMS];
+	struct vpu_malone_buffer_desc debug_buffer_desc;
+	struct vpu_malone_buffer_desc eng_access_buff_desc[VID_API_NUM_STREAMS];
+	u32 encrypt_info[VID_API_NUM_STREAMS];
+	struct vpu_rpc_system_config system_cfg;
+	u32 api_version;
+	struct vpu_malone_buffer_info stream_buff_info[VID_API_NUM_STREAMS];
+};
+
+struct malone_jpg_params {
+	u32 rotation_angle;
+	u32 horiz_scale_factor;
+	u32 vert_scale_factor;
+	u32 rotation_mode;
+	u32 rgb_mode;
+	u32 chunk_mode; /* 0 ~ 1 */
+	u32 last_chunk; /* 0 ~ 1 */
+	u32 chunk_rows; /* 0 ~ 255 */
+	u32 num_bytes;
+	u32 jpg_crop_x;
+	u32 jpg_crop_y;
+	u32 jpg_crop_width;
+	u32 jpg_crop_height;
+	u32 jpg_mjpeg_mode;
+	u32 jpg_mjpeg_interlaced;
+};
+
+struct malone_codec_params {
+	u32 disp_imm;
+	u32 fourcc;
+	u32 codec_version;
+	u32 frame_rate;
+	u32 dbglog_enable;
+	u32 bsdma_lwm;
+	u32 bbd_coring;
+	u32 bbd_s_thr_row;
+	u32 bbd_p_thr_row;
+	u32 bbd_s_thr_logo_row;
+	u32 bbd_p_thr_logo_row;
+	u32 bbd_s_thr_col;
+	u32 bbd_p_thr_col;
+	u32 bbd_chr_thr_row;
+	u32 bbd_chr_thr_col;
+	u32 bbd_uv_mid_level;
+	u32 bbd_excl_win_mb_left;
+	u32 bbd_excl_win_mb_right;
+};
+
+struct malone_padding_scode {
+	u32 scode_type;
+	u32 pixelformat;
+	u32 data[2];
+};
+
+struct malone_fmt_mapping {
+	u32 pixelformat;
+	enum vpu_malone_format malone_format;
+};
+
+struct malone_scode_t {
+	struct vpu_inst *inst;
+	struct vb2_buffer *vb;
+	u32 wptr;
+	u32 need_data;
+};
+
+struct malone_scode_handler {
+	u32 pixelformat;
+	int (*insert_scode_seq)(struct malone_scode_t *scode);
+	int (*insert_scode_pic)(struct malone_scode_t *scode);
+};
+
+struct vpu_dec_ctrl {
+	struct malone_codec_params *codec_param;
+	struct malone_jpg_params *jpg;
+	void *seq_mem;
+	void *pic_mem;
+	void *gop_mem;
+	void *qmeter_mem;
+	void *dbglog_mem;
+	struct vpu_malone_str_buffer *str_buf[VID_API_NUM_STREAMS];
+	u32 buf_addr[VID_API_NUM_STREAMS];
+};
+
+u32 vpu_malone_get_data_size(void)
+{
+	return sizeof(struct vpu_dec_ctrl);
+}
+
+void vpu_malone_init_rpc(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr)
+{
+	struct malone_iface *iface;
+	struct vpu_dec_ctrl *hc;
+	unsigned long base_phy_addr;
+	unsigned long phy_addr;
+	unsigned long offset;
+	unsigned int i;
+
+	WARN_ON(!shared || !shared->priv);
+	WARN_ON(!rpc || !rpc->phys || !rpc->length || rpc->phys < boot_addr);
+
+	iface = rpc->virt;
+	base_phy_addr = rpc->phys - boot_addr;
+	hc = shared->priv;
+
+	shared->iface = iface;
+	shared->boot_addr = boot_addr;
+
+	iface->exec_base_addr = base_phy_addr;
+	iface->exec_area_size = rpc->length;
+
+	offset = sizeof(struct malone_iface);
+	phy_addr = base_phy_addr + offset;
+
+	shared->cmd_desc = &iface->cmd_buffer_desc.buffer;
+	shared->cmd_mem_vir = rpc->virt + offset;
+	iface->cmd_buffer_desc.buffer.start =
+	iface->cmd_buffer_desc.buffer.rptr =
+	iface->cmd_buffer_desc.buffer.wptr = phy_addr;
+	iface->cmd_buffer_desc.buffer.end = iface->cmd_buffer_desc.buffer.start + CMD_SIZE;
+	offset += CMD_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	shared->msg_desc = &iface->msg_buffer_desc.buffer;
+	shared->msg_mem_vir = rpc->virt + offset;
+	iface->msg_buffer_desc.buffer.start =
+	iface->msg_buffer_desc.buffer.wptr =
+	iface->msg_buffer_desc.buffer.rptr = phy_addr;
+	iface->msg_buffer_desc.buffer.end = iface->msg_buffer_desc.buffer.start + MSG_SIZE;
+	offset += MSG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->codec_param_tab_desc.array_base = phy_addr;
+	hc->codec_param = rpc->virt + offset;
+	offset += CODEC_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->jpeg_param_tab_desc.array_base = phy_addr;
+	hc->jpg = rpc->virt + offset;
+	offset += JPEG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->seq_info_tab_desc.array_base = phy_addr;
+	hc->seq_mem = rpc->virt + offset;
+	offset += SEQ_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->pic_info_tab_desc.array_base = phy_addr;
+	hc->pic_mem = rpc->virt + offset;
+	offset += PIC_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->gop_info_tab_desc.array_base = phy_addr;
+	hc->gop_mem = rpc->virt + offset;
+	offset += GOP_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->qmeter_info_tab_desc.array_base = phy_addr;
+	hc->qmeter_mem = rpc->virt + offset;
+	offset += QMETER_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->dbglog_desc.addr = phy_addr;
+	iface->dbglog_desc.size = DBGLOG_SIZE;
+	hc->dbglog_mem = rpc->virt + offset;
+	offset += DBGLOG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		iface->eng_access_buff_desc[i].buffer.start =
+		iface->eng_access_buff_desc[i].buffer.wptr =
+		iface->eng_access_buff_desc[i].buffer.rptr = phy_addr;
+		iface->eng_access_buff_desc[i].buffer.end =
+			iface->eng_access_buff_desc[i].buffer.start + ENG_SIZE;
+		offset += ENG_SIZE;
+		phy_addr = base_phy_addr + offset;
+	}
+
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		iface->encrypt_info[i] = phy_addr;
+		offset += sizeof(struct vpu_malone_encrypt_info);
+		phy_addr = base_phy_addr + offset;
+	}
+
+	rpc->bytesused = offset;
+}
+
+void vpu_malone_set_log_buf(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log)
+{
+	struct malone_iface *iface;
+
+	WARN_ON(!shared || !log || !log->phys);
+	vpu_dbg(LVL_DEBUG, "set log area <0x%llx, 0x%x> (0x%lx)\n",
+			log->phys, log->length, shared->boot_addr);
+	iface = shared->iface;
+	iface->debug_buffer_desc.buffer.start =
+	iface->debug_buffer_desc.buffer.wptr =
+	iface->debug_buffer_desc.buffer.rptr = log->phys - shared->boot_addr;
+	iface->debug_buffer_desc.buffer.end = iface->debug_buffer_desc.buffer.start + log->length;
+}
+
+static u32 get_str_buffer_offset(u32 instance)
+{
+	return DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * instance;
+}
+
+void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id)
+{
+	struct malone_iface *iface;
+	struct vpu_rpc_system_config *config;
+	struct vpu_dec_ctrl *hc;
+	int i;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	iface = shared->iface;
+	config = &iface->system_cfg;
+	hc = shared->priv;
+
+	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		u32 offset = get_str_buffer_offset(i);
+
+		hc->buf_addr[i] = regs_base + offset;
+		hc->str_buf[i] = regs + offset;
+	}
+}
+
+u32 vpu_malone_get_version(struct vpu_shared_addr *shared)
+{
+	struct malone_iface *iface;
+
+	WARN_ON(!shared || !shared->iface);
+
+	iface = shared->iface;
+	return iface->fw_version;
+}
+
+int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared)
+{
+	return 0xc00000;
+}
+
+int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance,
+					struct vpu_buffer *buf)
+{
+	struct malone_iface *iface;
+	struct vpu_dec_ctrl *hc;
+	struct vpu_malone_str_buffer *str_buf;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	iface = shared->iface;
+	hc = shared->priv;
+	str_buf = hc->str_buf[instance];
+	str_buf->wptr = str_buf->rptr = str_buf->start = buf->phys;
+	str_buf->end = buf->phys + buf->length;
+	str_buf->lwm = 0x1;
+
+	iface->stream_buffer_desc[instance][0] = hc->buf_addr[instance];
+
+	return 0;
+}
+
+int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_dec_ctrl *hc;
+	struct vpu_malone_str_buffer *str_buf;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	hc = shared->priv;
+	str_buf = hc->str_buf[instance];
+
+	if (desc) {
+		desc->wptr = str_buf->wptr;
+		desc->rptr = str_buf->rptr;
+		desc->start = str_buf->start;
+		desc->end = str_buf->end;
+	}
+
+	return 0;
+}
+
+static void vpu_malone_update_wptr(struct vpu_malone_str_buffer *str_buf,
+					u32 wptr)
+{
+	u32 size = str_buf->end - str_buf->start;
+	u32 space = (str_buf->rptr + size - str_buf->wptr) % size;
+	u32 step = (wptr + size - str_buf->wptr) % size;
+
+	if (space && step > space)
+		vpu_err("update wptr from 0x%x to 0x%x, cross over rptr 0x%x\n",
+				str_buf->wptr, wptr, str_buf->rptr);
+
+	/*update wptr after data is written*/
+	mb();
+	str_buf->wptr = wptr;
+}
+
+static void vpu_malone_update_rptr(struct vpu_malone_str_buffer *str_buf,
+					u32 rptr)
+{
+	u32 size = str_buf->end - str_buf->start;
+	u32 space = (str_buf->wptr + size - str_buf->rptr) % size;
+	u32 step = (rptr + size - str_buf->rptr) % size;
+
+	if (step > space)
+		vpu_err("update rptr from 0x%x to 0x%x, cross over wptr 0x%x\n",
+				str_buf->rptr, rptr, str_buf->wptr);
+	/*update rptr after data is read*/
+	mb();
+	str_buf->rptr = rptr;
+}
+
+int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance, u32 ptr, bool write)
+{
+	struct vpu_dec_ctrl *hc;
+	struct vpu_malone_str_buffer *str_buf;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	hc = shared->priv;
+	str_buf = hc->str_buf[instance];
+
+	if (write)
+		vpu_malone_update_wptr(str_buf, ptr);
+	else
+		vpu_malone_update_rptr(str_buf, ptr);
+
+	return 0;
+}
+
+static struct malone_fmt_mapping fmt_mappings[] = {
+	{V4L2_PIX_FMT_H264,        MALONE_FMT_AVC},
+	{V4L2_PIX_FMT_H264_MVC,    MALONE_FMT_AVC},
+	{V4L2_PIX_FMT_HEVC,        MALONE_FMT_HEVC},
+	{V4L2_PIX_FMT_VC1_ANNEX_G, MALONE_FMT_VC1},
+	{V4L2_PIX_FMT_VC1_ANNEX_L, MALONE_FMT_VC1},
+	{V4L2_PIX_FMT_MPEG2,       MALONE_FMT_MP2},
+	{V4L2_PIX_FMT_MPEG4,       MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_XVID,        MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_H263,        MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_JPEG,        MALONE_FMT_JPG},
+	{V4L2_PIX_FMT_VP8,         MALONE_FMT_VP8},
+};
+
+static enum vpu_malone_format vpu_malone_format_remap(u32 pixelformat)
+{
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(fmt_mappings); i++) {
+		if (pixelformat == fmt_mappings[i].pixelformat)
+			return fmt_mappings[i].malone_format;
+	}
+
+	return MALONE_FMT_NULL;
+}
+
+static void vpu_malone_set_stream_cfg(struct vpu_shared_addr *shared,
+		u32 instance, enum vpu_malone_format malone_format)
+{
+	struct malone_iface *iface;
+	u32 *curr_str_cfg;
+
+	iface = shared->iface;
+	curr_str_cfg = &iface->stream_config[instance];
+
+	*curr_str_cfg = 0;
+	STREAM_CONFIG_FORMAT_SET(malone_format, curr_str_cfg);
+	STREAM_CONFIG_STRBUFIDX_SET(0, curr_str_cfg);
+	STREAM_CONFIG_NOSEQ_SET(0, curr_str_cfg);
+	STREAM_CONFIG_DEBLOCK_SET(0, curr_str_cfg);
+	STREAM_CONFIG_DERING_SET(0, curr_str_cfg);
+	STREAM_CONFIG_PLAY_MODE_SET(0x3, curr_str_cfg);
+	STREAM_CONFIG_FS_CTRL_MODE_SET(0x1, curr_str_cfg);
+	STREAM_CONFIG_ENABLE_DCP_SET(1, curr_str_cfg);
+	STREAM_CONFIG_NUM_STR_BUF_SET(1, curr_str_cfg);
+	STREAM_CONFIG_MALONE_USAGE_SET(1, curr_str_cfg);
+	STREAM_CONFIG_MULTI_VID_SET(0, curr_str_cfg);
+	STREAM_CONFIG_OBFUSC_EN_SET(0, curr_str_cfg);
+	STREAM_CONFIG_RC4_EN_SET(0, curr_str_cfg);
+	STREAM_CONFIG_MCX_SET(1, curr_str_cfg);
+	STREAM_CONFIG_PES_SET(0, curr_str_cfg);
+	STREAM_CONFIG_NUM_DBE_SET(1, curr_str_cfg);
+}
+
+static int vpu_malone_set_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_decode_params *params)
+{
+	struct malone_iface *iface;
+	struct vpu_dec_ctrl *hc;
+	enum vpu_malone_format malone_format;
+
+	iface = shared->iface;
+	hc = shared->priv;
+	malone_format = vpu_malone_format_remap(params->codec_format);
+	iface->udata_buffer[instance].base = params->udata.base;
+	iface->udata_buffer[instance].slot_size = params->udata.size;
+
+	vpu_malone_set_stream_cfg(shared, instance, malone_format);
+
+	if (malone_format == MALONE_FMT_JPG) {
+		//1:JPGD_MJPEG_MODE_A; 2:JPGD_MJPEG_MODE_B
+		hc->jpg[instance].jpg_mjpeg_mode = 1;
+		//0: JPGD_MJPEG_PROGRESSIVE
+		hc->jpg[instance].jpg_mjpeg_interlaced = 0;
+	}
+
+	hc->codec_param[instance].disp_imm = params->b_dis_reorder ? 1 : 0;
+	hc->codec_param[instance].dbglog_enable = 0;
+	iface->dbglog_desc.level = 0;
+
+	if (params->b_non_frame)
+		iface->stream_buff_info[instance].stream_input_mode = NON_FRAME_LVL;
+	else
+		iface->stream_buff_info[instance].stream_input_mode = FRAME_LVL;
+	iface->stream_buff_info[instance].stream_buffer_threshold = 0;
+	iface->stream_buff_info[instance].stream_pic_input_count = 0;
+
+	return 0;
+}
+
+static bool vpu_malone_is_non_frame_mode(struct vpu_shared_addr *shared,
+					u32 instance)
+{
+	struct malone_iface *iface;
+
+	iface = shared->iface;
+	if (iface->stream_buff_info[instance].stream_input_mode == NON_FRAME_LVL)
+		return true;
+
+	return false;
+}
+
+static int vpu_malone_update_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_decode_params *params)
+{
+	struct malone_iface *iface;
+
+	iface = shared->iface;
+
+	if (params->end_flag)
+		iface->stream_buff_info[instance].stream_pic_end_flag = params->end_flag;
+	params->end_flag = 0;
+
+	return 0;
+}
+
+int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_decode_params *params, u32 update)
+{
+	if (!params)
+		return -EINVAL;
+
+	if (!update)
+		return vpu_malone_set_params(shared, instance, params);
+	else
+		return vpu_malone_update_params(shared, instance, params);
+}
+
+static struct vpu_pair malone_cmds[] = {
+	{VPU_CMD_ID_START, VID_API_CMD_START},
+	{VPU_CMD_ID_STOP, VID_API_CMD_STOP},
+	{VPU_CMD_ID_ABORT, VID_API_CMD_ABORT},
+	{VPU_CMD_ID_RST_BUF, VID_API_CMD_RST_BUF},
+	{VPU_CMD_ID_SNAPSHOT, VID_API_CMD_SNAPSHOT},
+	{VPU_CMD_ID_FIRM_RESET, VID_API_CMD_FIRM_RESET},
+	{VPU_CMD_ID_FS_ALLOC, VID_API_CMD_FS_ALLOC},
+	{VPU_CMD_ID_FS_RELEASE, VID_API_CMD_FS_RELEASE},
+	{VPU_CMD_ID_TIMESTAMP, VID_API_CMD_TS},
+	{VPU_CMD_ID_DEBUG, VID_API_CMD_FW_STATUS},
+};
+
+static struct vpu_pair malone_msgs[] = {
+	{VPU_MSG_ID_RESET_DONE, VID_API_EVENT_RESET_DONE},
+	{VPU_MSG_ID_START_DONE, VID_API_EVENT_START_DONE},
+	{VPU_MSG_ID_STOP_DONE, VID_API_EVENT_STOPPED},
+	{VPU_MSG_ID_ABORT_DONE, VID_API_EVENT_ABORT_DONE},
+	{VPU_MSG_ID_BUF_RST, VID_API_EVENT_STR_BUF_RST},
+	{VPU_MSG_ID_PIC_EOS, VID_API_EVENT_FINISHED},
+	{VPU_MSG_ID_SEQ_HDR_FOUND, VID_API_EVENT_SEQ_HDR_FOUND},
+	{VPU_MSG_ID_RES_CHANGE, VID_API_EVENT_RES_CHANGE},
+	{VPU_MSG_ID_PIC_HDR_FOUND, VID_API_EVENT_PIC_HDR_FOUND},
+	{VPU_MSG_ID_PIC_DECODED, VID_API_EVENT_PIC_DECODED},
+	{VPU_MSG_ID_DEC_DONE, VID_API_EVENT_FRAME_BUFF_RDY},
+	{VPU_MSG_ID_FRAME_REQ, VID_API_EVENT_REQ_FRAME_BUFF},
+	{VPU_MSG_ID_FRAME_RELEASE, VID_API_EVENT_REL_FRAME_BUFF},
+	{VPU_MSG_ID_FIFO_LOW, VID_API_EVENT_FIFO_LOW},
+	{VPU_MSG_ID_BS_ERROR, VID_API_EVENT_BS_ERROR},
+	{VPU_MSG_ID_UNSUPPORTED, VID_API_EVENT_UNSUPPORTED_STREAM},
+	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_EVENT_FIRMWARE_XCPT},
+};
+
+static void vpu_malone_pack_fs_alloc(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *fs)
+{
+	const u32 fs_type[] = {
+		[MEM_RES_FRAME] = 0,
+		[MEM_RES_MBI] = 1,
+		[MEM_RES_DCP] = 2,
+	};
+
+	pkt->hdr.num = 7;
+	pkt->data[0] = fs->id | (fs->tag << 24);
+	pkt->data[1] = fs->luma_addr;
+	if (fs->type == MEM_RES_FRAME) {
+		/*
+		 * if luma_addr equal to chroma_addr,
+		 * means luma(plane[0]) and chromau(plane[1]) used the
+		 * same fd -- usage of NXP codec2. Need to manually
+		 * offset chroma addr.
+		 */
+		if (fs->luma_addr == fs->chroma_addr)
+			fs->chroma_addr = fs->luma_addr + fs->luma_size;
+		pkt->data[2] = fs->luma_addr + fs->luma_size / 2;
+		pkt->data[3] = fs->chroma_addr;
+		pkt->data[4] = fs->chroma_addr + fs->chromau_size / 2;
+		pkt->data[5] = fs->bytesperline;
+	} else {
+		pkt->data[2] = fs->luma_size;
+		pkt->data[3] = 0;
+		pkt->data[4] = 0;
+		pkt->data[5] = 0;
+	}
+	pkt->data[6] = fs_type[fs->type];
+}
+
+static void vpu_malone_pack_fs_release(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *fs)
+{
+	pkt->hdr.num = 1;
+	pkt->data[0] = fs->id | (fs->tag << 24);
+}
+
+static void vpu_malone_pack_timestamp(struct vpu_rpc_event *pkt,
+					struct vpu_ts_info *info)
+{
+	pkt->hdr.num = 3;
+	if (info->timestamp < 0) {
+		pkt->data[0] = (u32)-1;
+		pkt->data[1] = 0;
+	} else {
+		pkt->data[0] = info->timestamp / NSEC_PER_SEC;
+		pkt->data[1] = info->timestamp % NSEC_PER_SEC;
+	}
+	pkt->data[2] = info->size;
+}
+
+int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)
+{
+	int ret;
+
+	WARN_ON(!pkt);
+
+	ret = vpu_find_dst_by_src(malone_cmds, ARRAY_SIZE(malone_cmds), id);
+	if (ret < 0)
+		return ret;
+
+	pkt->hdr.id = ret;
+	pkt->hdr.num = 0;
+	pkt->hdr.index = index;
+
+	switch (id) {
+	case VPU_CMD_ID_FS_ALLOC:
+		vpu_malone_pack_fs_alloc(pkt, data);
+		break;
+	case VPU_CMD_ID_FS_RELEASE:
+		vpu_malone_pack_fs_release(pkt, data);
+		break;
+	case VPU_CMD_ID_TIMESTAMP:
+		vpu_malone_pack_timestamp(pkt, data);
+		break;
+	}
+
+	pkt->hdr.index = index;
+	return 0;
+}
+
+int vpu_malone_convert_msg_id(u32 id)
+{
+	return vpu_find_src_by_dst(malone_msgs, ARRAY_SIZE(malone_msgs), id);
+}
+
+static void vpu_malone_fill_planes(struct vpu_dec_codec_info *info)
+{
+	u32 interlaced = info->progressive ? 0 : 1;
+
+	info->sizeimage[0] = vpu_helper_get_plane_size(info->pixfmt,
+			info->decoded_width, info->decoded_height,
+			0, info->stride, interlaced,
+			&info->bytesperline[0]);
+	info->sizeimage[1] = vpu_helper_get_plane_size(info->pixfmt,
+			info->decoded_width, info->decoded_height,
+			1, info->stride, interlaced,
+			&info->bytesperline[1]);
+}
+
+static void vpu_malone_init_seq_hdr(struct vpu_dec_codec_info *info)
+{
+	u32 chunks = info->num_dfe_area >> MALONE_DCP_CHUNK_BIT;
+
+	vpu_malone_fill_planes(info);
+
+	info->mbi_size = (info->sizeimage[0] + info->sizeimage[1]) >> 2;
+	info->mbi_size = ALIGN(info->mbi_size, MALONE_ALIGN_MBI);
+
+	info->dcp_size = MALONE_DCP_SIZE_MAX;
+	if (chunks) {
+		u32 mb_num;
+		u32 mb_w;
+		u32 mb_h;
+
+		mb_w = DIV_ROUND_UP(info->decoded_width, 16);
+		mb_h = DIV_ROUND_UP(info->decoded_height, 16);
+		mb_num = mb_w * mb_h;
+		info->dcp_size = mb_num * MALONE_DCP_FIXED_MB_ALLOC * chunks;
+		info->dcp_size = clamp_t(u32, info->dcp_size,
+					MALONE_DCP_SIZE_MIN, MALONE_DCP_SIZE_MAX);
+	}
+}
+
+static void vpu_malone_unpack_seq_hdr(struct vpu_rpc_event *pkt,
+					struct vpu_dec_codec_info *info)
+{
+	info->num_ref_frms = pkt->data[0];
+	info->num_dpb_frms = pkt->data[1];
+	info->num_dfe_area = pkt->data[2];
+	info->progressive = pkt->data[3];
+	info->width = pkt->data[5];
+	info->height = pkt->data[4];
+	info->decoded_width = pkt->data[12];
+	info->decoded_height = pkt->data[11];
+	info->frame_rate = pkt->data[8];
+	info->dsp_asp_ratio = pkt->data[9];
+	info->level_idc = pkt->data[10];
+	info->bit_depth_luma = pkt->data[13];
+	info->bit_depth_chroma = pkt->data[14];
+	info->chroma_fmt = pkt->data[15];
+	info->color_primaries = vpu_color_cvrt_primaries_i2v(pkt->data[16]);
+	info->transfer_chars = vpu_color_cvrt_transfers_i2v(pkt->data[17]);
+	info->matrix_coeffs = vpu_color_cvrt_matrix_i2v(pkt->data[18]);
+	info->full_range = vpu_color_cvrt_full_range_i2v(pkt->data[19]);
+	info->vui_present = pkt->data[20];
+	info->mvc_num_views = pkt->data[21];
+	info->offset_x = pkt->data[23];
+	info->offset_y = pkt->data[25];
+	info->tag = pkt->data[27];
+	if (info->bit_depth_luma > 8)
+		info->pixfmt = V4L2_PIX_FMT_NV12_10BE_8L128;
+	else
+		info->pixfmt = V4L2_PIX_FMT_NV12_8L128;
+	vpu_malone_init_seq_hdr(info);
+}
+
+static void vpu_malone_unpack_pic_info(struct vpu_rpc_event *pkt,
+					struct vpu_dec_pic_info *info)
+{
+	info->id = pkt->data[7];
+	info->luma = pkt->data[0];
+	info->start = pkt->data[10];
+	info->end = pkt->data[12];
+	info->pic_size = pkt->data[11];
+	info->stride = pkt->data[5];
+	info->consumed_count = pkt->data[13];
+	if (info->id == MALONE_SKIPPED_FRAME_ID)
+		info->skipped = 1;
+	else
+		info->skipped = 0;
+}
+
+static void vpu_malone_unpack_req_frame(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *info)
+{
+	info->type = pkt->data[1];
+}
+
+static void vpu_malone_unpack_rel_frame(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *info)
+{
+	info->id = pkt->data[0];
+	info->type = pkt->data[1];
+	info->not_displayed = pkt->data[2];
+}
+
+static void vpu_malone_unpack_buff_rdy(struct vpu_rpc_event *pkt,
+					struct vpu_dec_pic_info *info)
+{
+	info->id = pkt->data[0];
+	info->luma = pkt->data[1];
+	info->stride = pkt->data[3];
+	if (info->id == MALONE_SKIPPED_FRAME_ID)
+		info->skipped = 1;
+	else
+		info->skipped = 0;
+	info->timestamp = MAKE_TIMESTAMP(pkt->data[9], pkt->data[10]);
+}
+
+int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)
+{
+	if (!pkt || !data)
+		return -EINVAL;
+
+	switch (pkt->hdr.id) {
+	case VID_API_EVENT_SEQ_HDR_FOUND:
+		vpu_malone_unpack_seq_hdr(pkt, data);
+		break;
+	case VID_API_EVENT_PIC_DECODED:
+		vpu_malone_unpack_pic_info(pkt, data);
+		break;
+	case VID_API_EVENT_REQ_FRAME_BUFF:
+		vpu_malone_unpack_req_frame(pkt, data);
+		break;
+	case VID_API_EVENT_REL_FRAME_BUFF:
+		vpu_malone_unpack_rel_frame(pkt, data);
+		break;
+	case VID_API_EVENT_FRAME_BUFF_RDY:
+		vpu_malone_unpack_buff_rdy(pkt, data);
+		break;
+	}
+
+	return 0;
+}
+
+static const struct malone_padding_scode padding_scodes[] = {
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H264,        {0x0B010000, 0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H264_MVC,    {0x0B010000, 0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_HEVC,        {0x4A010000, 0x20}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_MPEG2,       {0xCC010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_MPEG4,       {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_XVID,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H263,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VP8,         {0x34010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0xefff0000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H264,        {0x0B010000, 0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H264_MVC,    {0x0B010000, 0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_HEVC,        {0x4A010000, 0x20}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_MPEG2,       {0xb7010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_MPEG4,       {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_XVID,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H263,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VP8,         {0x34010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0x0, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264,        {0x15010000, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC,    {0x15010000, 0x0}},
+};
+static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0};
+
+static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt)
+{
+	const struct malone_padding_scode *s;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(padding_scodes); i++) {
+		s = &padding_scodes[i];
+
+		if (s->scode_type == type && s->pixelformat == fmt)
+			return s;
+	}
+
+	if (type != SCODE_PADDING_BUFFLUSH)
+		return &padding_scode_dft;
+
+	return NULL;
+}
+
+static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer,
+			struct vpu_malone_str_buffer *str_buf,
+			u32 pixelformat, u32 scode_type)
+{
+	u32 wptr;
+	u32 size;
+	u32 total_size = 0;
+	const struct malone_padding_scode *ps;
+	const u32 padding_size = 4096;
+	int ret;
+
+	ps = get_padding_scode(scode_type, pixelformat);
+	if (!ps)
+		return -EINVAL;
+
+	wptr = str_buf->wptr;
+	size = ALIGN(wptr, 4) - wptr;
+	if (size)
+		vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size);
+	total_size += size;
+
+	size = sizeof(ps->data);
+	ret = vpu_helper_copy_to_stream_buffer(stream_buffer, &wptr, size, (void *)ps->data);
+	if (ret < size)
+		return -EINVAL;
+	total_size += size;
+
+	size = padding_size - sizeof(ps->data);
+	vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size);
+	total_size += size;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+	return total_size;
+}
+
+int vpu_malone_add_scode(struct vpu_shared_addr *shared,
+				u32 instance,
+				struct vpu_buffer *stream_buffer,
+				u32 pixelformat,
+				u32 scode_type)
+{
+	struct vpu_dec_ctrl *hc;
+	struct vpu_malone_str_buffer *str_buf;
+	int ret = -EINVAL;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+
+	hc = shared->priv;
+	str_buf = hc->str_buf[instance];
+
+	switch (scode_type) {
+	case SCODE_PADDING_EOS:
+	case SCODE_PADDING_ABORT:
+	case SCODE_PADDING_BUFFLUSH:
+		ret = vpu_malone_add_padding_scode(stream_buffer,
+				str_buf, pixelformat, scode_type);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+#define MALONE_PAYLOAD_HEADER_SIZE		16
+#define MALONE_CODEC_VERSION_ID			0x1
+#define MALONE_CODEC_ID_VC1_SIMPLE		0x10
+#define MALONE_CODEC_ID_VC1_MAIN		0x11
+#define MALONE_CODEC_ID_ARV8			0x28
+#define MALONE_CODEC_ID_ARV9			0x29
+#define MALONE_CODEC_ID_VP6			0x36
+#define MALONE_CODEC_ID_VP8			0x36
+#define MALONE_CODEC_ID_DIVX3			0x38
+#define MALONE_CODEC_ID_SPK			0x39
+
+#define MALONE_VP8_IVF_SEQ_HEADER_LEN		32
+#define MALONE_VP8_IVF_FRAME_HEADER_LEN		8
+
+#define MALONE_VC1_RCV_CODEC_V1_VERSION		0x85
+#define MALONE_VC1_RCV_CODEC_V2_VERSION		0xC5
+#define MALONE_VC1_RCV_NUM_FRAMES		0xFF
+#define MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE	4
+#define MALONE_VC1_RCV_SEQ_HEADER_LEN		20
+#define MALONE_VC1_RCV_PIC_HEADER_LEN		4
+#define MALONE_VC1_NAL_HEADER_LEN		4
+#define MALONE_VC1_CONTAIN_NAL(data)		((data & 0x00FFFFFF) == 0x00010000)
+
+
+static void set_payload_hdr(u8 *dst, u32 scd_type, u32 codec_id,
+		u32 buffer_size, u32 width, u32 height)
+{
+	unsigned int payload_size;
+	/* payload_size = buffer_size + itself_size(16) - start_code(4) */
+	payload_size = buffer_size + 12;
+
+	dst[0] = 0x00;
+	dst[1] = 0x00;
+	dst[2] = 0x01;
+	dst[3] = scd_type;
+
+	/* length */
+	dst[4] = ((payload_size>>16)&0xff);
+	dst[5] = ((payload_size>>8)&0xff);
+	dst[6] = 0x4e;
+	dst[7] = ((payload_size>>0)&0xff);
+
+	/* Codec ID and Version */
+	dst[8] = codec_id;
+	dst[9] = MALONE_CODEC_VERSION_ID;
+
+	/* width */
+	dst[10] = ((width>>8)&0xff);
+	dst[11] = ((width>>0)&0xff);
+	dst[12] = 0x58;
+
+	/* height */
+	dst[13] = ((height>>8)&0xff);
+	dst[14] = ((height>>0)&0xff);
+	dst[15] = 0x50;
+}
+
+static void set_vp8_ivf_seqhdr(u8 *dst, u32 width, u32 height)
+{
+	/* 0-3byte signature "DKIF" */
+	dst[0] = 0x44;
+	dst[1] = 0x4b;
+	dst[2] = 0x49;
+	dst[3] = 0x46;
+	/* 4-5byte version: should be 0*/
+	dst[4] = 0x00;
+	dst[5] = 0x00;
+	/* 6-7 length of Header */
+	dst[6] = MALONE_VP8_IVF_SEQ_HEADER_LEN;
+	dst[7] = MALONE_VP8_IVF_SEQ_HEADER_LEN >> 8;
+	/* 8-11 VP8 fourcc */
+	dst[8] = 0x56;
+	dst[9] = 0x50;
+	dst[10] = 0x38;
+	dst[11] = 0x30;
+	/* 12-13 width in pixels */
+	dst[12] = width;
+	dst[13] = width >> 8;
+	/* 14-15 height in pixels */
+	dst[14] = height;
+	dst[15] = height >> 8;
+	/* 16-19 frame rate */
+	dst[16] = 0xe8;
+	dst[17] = 0x03;
+	dst[18] = 0x00;
+	dst[19] = 0x00;
+	/* 20-23 time scale */
+	dst[20] = 0x01;
+	dst[21] = 0x00;
+	dst[22] = 0x00;
+	dst[23] = 0x00;
+	/* 24-27 number frames */
+	dst[24] = 0xdf;
+	dst[25] = 0xf9;
+	dst[26] = 0x09;
+	dst[27] = 0x00;
+	/* 28-31 reserved */
+}
+
+static void set_vp8_ivf_pichdr(u8 *dst, u32 frame_size)
+{
+	/*
+	 * firmware just parse 64-bit timestamp(8 bytes).
+	 * As not transfer timestamp to firmware, use default value(ZERO).
+	 * No need to do anything here
+	 */
+}
+
+static void set_vc1_rcv_seqhdr(u8 *dst, u8 *src, u32 width, u32 height)
+{
+	u32 frames = MALONE_VC1_RCV_NUM_FRAMES;
+	u32 ext_data_size = MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE;
+
+	/* 0-2 Number of frames, used default value 0xFF */
+	dst[0] = frames;
+	dst[1] = frames >> 8;
+	dst[2] = frames >> 16;
+
+	/* 3 RCV version, used V1 */
+	dst[3] = MALONE_VC1_RCV_CODEC_V1_VERSION;
+
+	/* 4-7 extension data size */
+	dst[4] = ext_data_size;
+	dst[5] = ext_data_size >> 8;
+	dst[6] = ext_data_size >> 16;
+	dst[7] = ext_data_size >> 24;
+	/* 8-11 extension data */
+	dst[8] = src[0];
+	dst[9] = src[1];
+	dst[10] = src[2];
+	dst[11] = src[3];
+
+	/* height */
+	dst[12] = height;
+	dst[13] = (height >> 8) & 0xff;
+	dst[14] = (height >> 16) & 0xff;
+	dst[15] = (height >> 24) & 0xff;
+	/* width */
+	dst[16] = width;
+	dst[17] = (width >> 8) & 0xff;
+	dst[18] = (width >> 16) & 0xff;
+	dst[19] = (width >> 24) & 0xff;
+}
+
+static void set_vc1_rcv_pichdr(u8 *dst, u32 buffer_size)
+{
+	dst[0] = buffer_size;
+	dst[1] = buffer_size >> 8;
+	dst[2] = buffer_size >> 16;
+	dst[3] = buffer_size >> 24;
+}
+
+static void create_vc1_nal_pichdr(u8 *dst)
+{
+	/* need insert nal header: special ID */
+	dst[0] = 0x0;
+	dst[1] = 0x0;
+	dst[2] = 0x01;
+	dst[3] = 0x0D;
+}
+
+static int vpu_malone_insert_scode_seq(struct malone_scode_t *scode, u32 codec_id, u32 ext_size)
+{
+	u8 hdr[MALONE_PAYLOAD_HEADER_SIZE];
+	int ret;
+
+	set_payload_hdr(hdr,
+			SCODE_SEQUENCE,
+			codec_id,
+			ext_size,
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(hdr),
+						hdr);
+	return ret;
+}
+
+static int vpu_malone_insert_scode_pic(struct malone_scode_t *scode, u32 codec_id, u32 ext_size)
+{
+	u8 hdr[MALONE_PAYLOAD_HEADER_SIZE];
+
+	set_payload_hdr(hdr,
+			SCODE_PICTURE,
+			codec_id,
+			ext_size + vb2_get_plane_payload(scode->vb, 0),
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	return vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(hdr),
+						hdr);
+}
+
+static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode)
+{
+	struct vb2_v4l2_buffer *vbuf;
+	u8 nal_hdr[MALONE_VC1_NAL_HEADER_LEN];
+	u32 *data = NULL;
+
+	vbuf = to_vb2_v4l2_buffer(scode->vb);
+	data = vb2_plane_vaddr(scode->vb, 0);
+
+	if (vbuf->sequence == 0 || (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG))
+		return 0;
+	if (MALONE_VC1_CONTAIN_NAL(*data))
+		return 0;
+
+	create_vc1_nal_pichdr(nal_hdr);
+	return vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(nal_hdr),
+						nal_hdr);
+}
+
+static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN];
+
+	scode->need_data = 0;
+
+	ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VC1_SIMPLE,
+					  sizeof(rcv_seqhdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vc1_rcv_seqhdr(rcv_seqhdr,
+			   vb2_plane_vaddr(scode->vb, 0),
+			   scode->inst->out_format.width,
+			   scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(rcv_seqhdr),
+						rcv_seqhdr);
+
+	if (ret < 0)
+		return ret;
+	size += ret;
+	return size;
+}
+
+static int vpu_malone_insert_scode_vc1_l_pic(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 rcv_pichdr[MALONE_VC1_RCV_PIC_HEADER_LEN];
+
+	ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VC1_SIMPLE,
+					  sizeof(rcv_pichdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vc1_rcv_pichdr(rcv_pichdr, vb2_get_plane_payload(scode->vb, 0));
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(rcv_pichdr),
+						rcv_pichdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+	return size;
+}
+
+static int vpu_malone_insert_scode_vp8_seq(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 ivf_hdr[MALONE_VP8_IVF_SEQ_HEADER_LEN];
+
+	ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vp8_ivf_seqhdr(ivf_hdr,
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(ivf_hdr),
+						ivf_hdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+
+	return size;
+}
+
+static int vpu_malone_insert_scode_vp8_pic(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 ivf_hdr[MALONE_VP8_IVF_FRAME_HEADER_LEN] = {0};
+
+	ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vp8_ivf_pichdr(ivf_hdr, vb2_get_plane_payload(scode->vb, 0));
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(ivf_hdr),
+						ivf_hdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+
+	return size;
+}
+
+static const struct malone_scode_handler scode_handlers[] = {
+	{
+		/* fix me, need to swap return operation after gstreamer swap */
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.insert_scode_seq = vpu_malone_insert_scode_vc1_l_seq,
+		.insert_scode_pic = vpu_malone_insert_scode_vc1_l_pic,
+	},
+	{
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.insert_scode_pic = vpu_malone_insert_scode_vc1_g_pic,
+	},
+	{
+		.pixelformat = V4L2_PIX_FMT_VP8,
+		.insert_scode_seq = vpu_malone_insert_scode_vp8_seq,
+		.insert_scode_pic = vpu_malone_insert_scode_vp8_pic,
+	},
+};
+
+static const struct malone_scode_handler *get_scode_handler(u32 pixelformat)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(scode_handlers); i++) {
+		if (scode_handlers[i].pixelformat == pixelformat)
+			return &scode_handlers[i];
+	}
+
+	return NULL;
+}
+
+static int vpu_malone_insert_scode(struct malone_scode_t *scode, u32 type)
+{
+	const struct malone_scode_handler *handler;
+	int ret = 0;
+
+	if (!scode || !scode->inst || !scode->vb)
+		return 0;
+
+	scode->need_data = 1;
+	handler = get_scode_handler(scode->inst->out_format.pixfmt);
+	if (!handler)
+		return 0;
+
+	switch (type) {
+	case SCODE_SEQUENCE:
+		if (handler->insert_scode_seq)
+			ret = handler->insert_scode_seq(scode);
+		break;
+	case SCODE_PICTURE:
+		if (handler->insert_scode_pic)
+			ret = handler->insert_scode_pic(scode);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer *str_buf,
+				struct vpu_inst *inst, struct vb2_buffer *vb,
+				u32 disp_imm)
+{
+	struct malone_scode_t scode;
+	struct vb2_v4l2_buffer *vbuf;
+	u32 wptr;
+	int size = 0;
+	int ret = 0;
+
+	wptr = str_buf->wptr;
+
+	/*add scode: SCODE_SEQUENCE, SCODE_PICTURE, SCODE_SLICE*/
+	vbuf = to_vb2_v4l2_buffer(vb);
+	scode.inst = inst;
+	scode.vb = vb;
+	scode.wptr = wptr;
+	scode.need_data = 1;
+	if (vbuf->sequence == 0 || (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG))
+		ret = vpu_malone_insert_scode(&scode, SCODE_SEQUENCE);
+
+	if (ret < 0)
+		return -ENOMEM;
+	size += ret;
+	wptr = scode.wptr;
+	if (!scode.need_data) {
+		vpu_malone_update_wptr(str_buf, wptr);
+		return size;
+	}
+
+	ret = vpu_malone_insert_scode(&scode, SCODE_PICTURE);
+	if (ret < 0)
+		return -ENOMEM;
+	size += ret;
+	wptr = scode.wptr;
+
+	ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer,
+						&wptr,
+						vb2_get_plane_payload(vb, 0),
+						vb2_plane_vaddr(vb, 0));
+	if (ret < vb2_get_plane_payload(vb, 0))
+		return -ENOMEM;
+	size += ret;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+
+	if (disp_imm && !(vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG)) {
+		ret = vpu_malone_add_scode(inst->core->iface,
+					     inst->id,
+					     &inst->stream_buffer,
+					     inst->out_format.pixfmt,
+					     SCODE_PADDING_BUFFLUSH);
+		if (ret < 0)
+			return ret;
+		size += ret;
+	}
+
+	return size;
+}
+
+static int vpu_malone_input_stream_data(struct vpu_malone_str_buffer *str_buf,
+				struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	u32 wptr;
+	int ret = 0;
+
+	wptr = str_buf->wptr;
+	ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer,
+						&wptr,
+						vb2_get_plane_payload(vb, 0),
+						vb2_plane_vaddr(vb, 0));
+	if (ret < vb2_get_plane_payload(vb, 0))
+		return -ENOMEM;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+
+	return ret;
+}
+
+static int vpu_malone_input_ts(struct vpu_inst *inst, s64  timestamp, u32 size)
+{
+	struct vpu_ts_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.timestamp = timestamp;
+	info.size = size;
+
+	return vpu_session_fill_timestamp(inst, &info);
+}
+
+int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vpu_dec_ctrl *hc;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_malone_str_buffer *str_buf;
+	u32 disp_imm = 0;
+	u32 size;
+	int ret;
+
+	WARN_ON(!shared || !shared->iface || !shared->core || !shared->priv);
+	hc = shared->priv;
+	str_buf = hc->str_buf[inst->id];
+	disp_imm = hc->codec_param[inst->id].disp_imm;
+
+	if (vpu_malone_is_non_frame_mode(shared, inst->id))
+		ret = vpu_malone_input_stream_data(str_buf, inst, vb);
+	else
+		ret = vpu_malone_input_frame_data(str_buf, inst, vb, disp_imm);
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	/*
+	 * if buffer only contain codec data, and the timestamp is invalid,
+	 * don't put the invalid timestamp to resync
+	 * merge the data to next frame
+	 */
+	vbuf = to_vb2_v4l2_buffer(vb);
+	if ((vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) && (s64)vb->timestamp < 0) {
+		inst->extra_size += size;
+		return 0;
+	}
+	if (inst->extra_size) {
+		size += inst->extra_size;
+		inst->extra_size = 0;
+	}
+
+	ret = vpu_malone_input_ts(inst, vb->timestamp, size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static bool vpu_malone_check_ready(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface;
+	struct vpu_rpc_buffer_desc *desc;
+	u32 size;
+	u32 rptr;
+	u32 wptr;
+	u32 used;
+
+	iface = shared->iface;
+	desc = &iface->api_cmd_buffer_desc[instance];
+	size = desc->end - desc->start;
+	rptr = desc->rptr;
+	wptr = desc->wptr;
+	used = (wptr + size - rptr) % size;
+	if (!size || used < size / 2)
+		return true;
+
+	vpu_dbg(LVL_DEBUG, "[%d]api cmd used = %d/%d\n", instance, used, size);
+
+	return false;
+}
+
+bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance)
+{
+	u32 cnt = 0;
+
+	while (!vpu_malone_check_ready(shared, instance)) {
+		if (cnt > 30)
+			return false;
+		mdelay(1);
+		cnt++;
+	}
+	return true;
+}
+
+int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance)
+{
+	if (!vpu_malone_is_ready(shared, instance)) {
+		vpu_err("[%d] is not ready\n", instance);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface;
+	struct vpu_rpc_buffer_desc *desc;
+
+	iface = shared->iface;
+	desc = &iface->api_cmd_buffer_desc[instance];
+	desc->wptr++;
+	if (desc->wptr == desc->end)
+		desc->wptr = desc->start;
+
+	return 0;
+}
+
+int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface;
+	struct vpu_rpc_buffer_desc *desc;
+
+	iface = shared->iface;
+	desc = &iface->api_cmd_buffer_desc[instance];
+	desc->wptr = desc->rptr;
+	if (desc->wptr == desc->end)
+		desc->wptr = desc->start;
+
+	return 0;
+}
+
+u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared)
+{
+	struct malone_iface *iface = shared->iface;
+
+	return iface->max_streams;
+}
diff --git a/drivers/media/platform/imx/vpu-8q/vpu_malone.h b/drivers/media/platform/imx/vpu-8q/vpu_malone.h
new file mode 100644
index 000000000000..22c834a030a9
--- /dev/null
+++ b/drivers/media/platform/imx/vpu-8q/vpu_malone.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _IMX_VPU_MALONE_H
+#define _IMX_VPU_MALONE_H
+
+u32 vpu_malone_get_data_size(void);
+void vpu_malone_init_rpc(struct vpu_shared_addr *shared,
+			struct vpu_buffer *rpc, dma_addr_t boot_addr);
+void vpu_malone_set_log_buf(struct vpu_shared_addr *shared,
+			struct vpu_buffer *log);
+void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id);
+u32 vpu_malone_get_version(struct vpu_shared_addr *shared);
+int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared);
+int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance, struct vpu_buffer *buf);
+int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_rpc_buffer_desc *desc);
+int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared,
+					u32 instance, u32 ptr, bool write);
+int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+		u32 instance, struct vpu_decode_params *params, u32 update);
+int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+int vpu_malone_convert_msg_id(u32 msg_id);
+int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data);
+int vpu_malone_add_scode(struct vpu_shared_addr *shared,
+				u32 instance,
+				struct vpu_buffer *stream_buffer,
+				u32 pixelformat,
+				u32 scode_type);
+int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+			struct vpu_inst *inst, struct vb2_buffer *vb);
+bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance);
+u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared);
+
+#endif
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:13 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:13 +0800
Subject: [PATCH v7 12/14] ARM64: dts: freescale: imx8q: add imx vpu codec
 entries
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <7fce243c6ffd73c92ac49ebd160e78cef92bef77.1630377507.git.ming.qian@nxp.com>

Add the Video Processing Unit node for IMX8Q SoC.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi | 72 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 17 +++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    | 24 +++++++
 3 files changed, 113 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
new file mode 100644
index 000000000000..f2dde6d14ca3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ *	Dong Aisheng <aisheng.dong at nxp.com>
+ */
+
+vpu: vpu at 2c000000 {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0x2c000000 0x0 0x2c000000 0x2000000>;
+	reg = <0 0x2c000000 0 0x1000000>;
+	power-domains = <&pd IMX_SC_R_VPU>;
+	status = "disabled";
+
+	mu_m0: mailbox at 2d000000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d000000 0x20000>;
+		interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+		status = "okay";
+	};
+
+	mu1_m0: mailbox at 2d020000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d020000 0x20000>;
+		interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+		status = "okay";
+	};
+
+	mu2_m0: mailbox at 2d040000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d040000 0x20000>;
+		interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+		status = "disabled";
+	};
+
+	vpu_core0: vpu_core at 2d080000 {
+		reg = <0x2d080000 0x10000>;
+		compatible = "nxp,imx8q-vpu-decoder";
+		power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu_m0 0 0>,
+			<&mu_m0 0 1>,
+			<&mu_m0 1 0>;
+		status = "disabled";
+	};
+	vpu_core1: vpu_core at 2d090000 {
+		reg = <0x2d090000 0x10000>;
+		compatible = "nxp,imx8q-vpu-encoder";
+		power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu1_m0 0 0>,
+			<&mu1_m0 0 1>,
+			<&mu1_m0 1 0>;
+		status = "disabled";
+	};
+	vpu_core2: vpu_core at 2d0a0000 {
+		reg = <0x2d0a0000 0x10000>;
+		compatible = "nxp,imx8q-vpu-encoder";
+		power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu2_m0 0 0>,
+			<&mu2_m0 0 1>,
+			<&mu2_m0 1 0>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 863232a47004..05495b60beb8 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -196,6 +196,23 @@ &usdhc2 {
 	status = "okay";
 };
 
+&vpu {
+	compatible = "nxp,imx8qxp-vpu";
+	status = "okay";
+};
+
+&vpu_core0 {
+	reg = <0x2d040000 0x10000>;
+	memory-region = <&decoder_boot>, <&decoder_rpc>;
+	status = "okay";
+};
+
+&vpu_core1 {
+	reg = <0x2d050000 0x10000>;
+	memory-region = <&encoder_boot>, <&encoder_rpc>;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl_fec1: fec1grp {
 		fsl,pins = <
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 1e6b4995091e..6b421cfa5534 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -46,6 +46,9 @@ aliases {
 		serial1 = &lpuart1;
 		serial2 = &lpuart2;
 		serial3 = &lpuart3;
+		vpu_core0 = &vpu_core0;
+		vpu_core1 = &vpu_core1;
+		vpu_core2 = &vpu_core2;
 	};
 
 	cpus {
@@ -134,10 +137,30 @@ reserved-memory {
 		#size-cells = <2>;
 		ranges;
 
+		decoder_boot: decoder-boot at 84000000 {
+			reg = <0 0x84000000 0 0x2000000>;
+			no-map;
+		};
+
+		encoder_boot: encoder-boot at 86000000 {
+			reg = <0 0x86000000 0 0x200000>;
+			no-map;
+		};
+
+		decoder_rpc: decoder-rpc at 0x92000000 {
+			reg = <0 0x92000000 0 0x100000>;
+			no-map;
+		};
+
 		dsp_reserved: dsp at 92400000 {
 			reg = <0 0x92400000 0 0x2000000>;
 			no-map;
 		};
+
+		encoder_rpc: encoder-rpc at 0x94400000 {
+			reg = <0 0x94400000 0 0x700000>;
+			no-map;
+		};
 	};
 
 	pmu {
@@ -258,6 +281,7 @@ map0 {
 	};
 
 	/* sorted in register address */
+	#include "imx8-ss-vpu.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"
 	#include "imx8-ss-ddr.dtsi"
-- 
2.32.0



From ming.qian at nxp.com  Mon Aug 30 19:59:14 2021
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 31 Aug 2021 10:59:14 +0800
Subject: [PATCH v7 13/14] firmware: imx: scu-pd: imx8q: add vpu mu resources
In-Reply-To: <cover.1630377507.git.ming.qian@nxp.com>
References: <cover.1630377507.git.ming.qian@nxp.com>
Message-ID: <168aa67b66d687c2fd9a19ecfcc0b7cb6edc2bb3.1630377507.git.ming.qian@nxp.com>

the vpu core depends on the mu resources.
if they're missed, the vpu can't work.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/firmware/imx/scu-pd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index ff6569c4a53b..af3d057e6421 100644
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -155,6 +155,10 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
 	{ "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },
 	{ "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },
 	{ "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, false, 0 },
+	{ "vpu-enc1", IMX_SC_R_VPU_ENC_1, 1, false, 0 },
+	{ "vpu-mu0", IMX_SC_R_VPU_MU_0, 1, false, 0 },
+	{ "vpu-mu1", IMX_SC_R_VPU_MU_1, 1, false, 0 },
+	{ "vpu-mu2", IMX_SC_R_VPU_MU_2, 1, false, 0 },
 
 	/* GPU SS */
 	{ "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, true, 0 },
-- 
2.32.0



From nicolinc at nvidia.com  Mon Aug 30 19:59:13 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:13 -0700
Subject: [RFC][PATCH v2 03/13] vfio: Document VMID control for IOMMU
 Virtualization
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-4-nicolinc@nvidia.com>

The VFIO API was enhanced to support VMID control with two
new iotcls to set and get VMID between the kernel and the
virtual machine hypervisor. So updating the document.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 Documentation/driver-api/vfio.rst | 34 +++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/driver-api/vfio.rst b/Documentation/driver-api/vfio.rst
index c663b6f97825..a76a17065cdd 100644
--- a/Documentation/driver-api/vfio.rst
+++ b/Documentation/driver-api/vfio.rst
@@ -239,6 +239,40 @@ group and can access them as follows::
 	/* Gratuitous device reset and go... */
 	ioctl(device, VFIO_DEVICE_RESET);
 
+IOMMU Virtual Machine Identifier (VMID)
+------------------------
+In case of virtualization, each VM is assigned a Virtual Machine Identifier
+(VMID). This VMID is used to tag translation lookaside buffer (TLB) entries,
+to identify which VM each entry belongs to. This tagging allows translations
+for multiple different VMs to be present in the TLBs at the same time.
+
+The IOMMU Kernel driver is responsible for allocating a VMID. However, only
+a hypervisor knows what physical devices get assigned to the same VM. Thus,
+when the first physical device gets assigned to the VM, once the hypervisor
+finishes its IOCTL call of VFIO_SET_IOMMU, it should call the following:
+
+struct vm {
+	int iommu_type;
+	uint32_t vmid;	/* initial value is VFIO_IOMMU_VMID_INVALID */
+} vm0;
+
+	/* ... */
+	ioctl(container->fd, VFIO_SET_IOMMU, vm0->iommu_type);
+	/* ... */
+	if (vm0->vmid == VFIO_IOMMU_VMID_INVALID)
+		ioctl(container->fd, VFIO_IOMMU_GET_VMID, &vm0->vmid);
+
+This VMID would be the shared value, across the entire VM, between all the
+physical devices that are assigned to it. So, when other physical devices
+get assigned to the VM, before the hypervisor runs into the IOCTL call of
+VFIO_IOMMU_SET_VMID, it should call the following:
+
+	/* ... */
+	ioctl(container->fd, VFIO_SET_IOMMU, vm0->iommu_type);
+	/* ... */
+	if (vm0->vmid != VFIO_IOMMU_VMID_INVALID)
+		ioctl(container->fd, VFIO_IOMMU_SET_VMID, vmid);
+
 VFIO User API
 -------------------------------------------------------------------------------
 
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:14 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:14 -0700
Subject: [RFC][PATCH v2 04/13] vfio: add set_vmid and get_vmid for
 vfio_iommu_type1
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-5-nicolinc@nvidia.com>

A VMID is generated in an IOMMU driver, being called from this
->attach_group() callback. So call ->get_vmid() right after it
creates a new VMID, and call ->set_vmid() before it, to let it
reuse the same VMID.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/vfio/vfio.c  | 12 ++++++++++++
 include/linux/vfio.h |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index c17b25c127a2..8b7442deca93 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1080,9 +1080,21 @@ static int __vfio_container_attach_groups(struct vfio_container *container,
 	int ret = -ENODEV;
 
 	list_for_each_entry(group, &container->group_list, container_next) {
+		if (driver->ops->set_vmid && container->vmid != VFIO_IOMMU_VMID_INVALID) {
+			ret = driver->ops->set_vmid(data, container->vmid);
+			if (ret)
+				goto unwind;
+		}
+
 		ret = driver->ops->attach_group(data, group->iommu_group);
 		if (ret)
 			goto unwind;
+
+		if (driver->ops->get_vmid && container->vmid == VFIO_IOMMU_VMID_INVALID) {
+			ret = driver->ops->get_vmid(data, &container->vmid);
+			if (ret)
+				goto unwind;
+		}
 	}
 
 	return ret;
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index b53a9557884a..b43e7cbef4ab 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -126,6 +126,8 @@ struct vfio_iommu_driver_ops {
 						   struct iommu_group *group);
 	void		(*notify)(void *iommu_data,
 				  enum vfio_iommu_notify_type event);
+	int		(*set_vmid)(void *iommu_data, u32 vmid);
+	int		(*get_vmid)(void *iommu_data, u32 *vmid);
 };
 
 extern int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops);
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:12 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:12 -0700
Subject: [RFC][PATCH v2 02/13] vfio: add VFIO_IOMMU_GET_VMID and
 VFIO_IOMMU_SET_VMID
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-3-nicolinc@nvidia.com>

This patch adds a pair of new ioctl commands to communicate with
user space (virtual machine hypervisor) to get and set VMID that
indicates a Virtual Machine Identifier, being used by some IOMMU
to tag TLB entries -- similar to CPU MMU, using this VMID number
allows IOMMU to invalidate at the same time TLBs of the same VM.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/vfio/vfio.c       | 13 +++++++++++++
 include/uapi/linux/vfio.h | 26 ++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 3c034fe14ccb..c17b25c127a2 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -59,6 +59,7 @@ struct vfio_container {
 	struct rw_semaphore		group_lock;
 	struct vfio_iommu_driver	*iommu_driver;
 	void				*iommu_data;
+	u32				vmid;
 	bool				noiommu;
 };
 
@@ -1190,6 +1191,16 @@ static long vfio_fops_unl_ioctl(struct file *filep,
 	case VFIO_SET_IOMMU:
 		ret = vfio_ioctl_set_iommu(container, arg);
 		break;
+	case VFIO_IOMMU_GET_VMID:
+		ret = copy_to_user((void __user *)arg, &container->vmid,
+				   sizeof(u32)) ? -EFAULT : 0;
+		break;
+	case VFIO_IOMMU_SET_VMID:
+		if ((u32)arg == VFIO_IOMMU_VMID_INVALID)
+			return -EINVAL;
+		container->vmid = (u32)arg;
+		ret = 0;
+		break;
 	default:
 		driver = container->iommu_driver;
 		data = container->iommu_data;
@@ -1213,6 +1224,8 @@ static int vfio_fops_open(struct inode *inode, struct file *filep)
 	init_rwsem(&container->group_lock);
 	kref_init(&container->kref);
 
+	container->vmid = VFIO_IOMMU_VMID_INVALID;
+
 	filep->private_data = container;
 
 	return 0;
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index ef33ea002b0b..58c5fa6aaca6 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -1216,6 +1216,32 @@ struct vfio_iommu_type1_dirty_bitmap_get {
 
 #define VFIO_IOMMU_DIRTY_PAGES             _IO(VFIO_TYPE, VFIO_BASE + 17)
 
+/**
+ * VFIO_IOMMU_GET_VMID - _IOWR(VFIO_TYPE, VFIO_BASE + 22, __u32 *vmid)
+ * VFIO_IOMMU_SET_VMID - _IOWR(VFIO_TYPE, VFIO_BASE + 23, __u32 vmid)
+ *
+ * IOCTLs are used for VMID alignment between Kernel and User Space hypervisor.
+ * In a virtualization use case, a guest owns the first stage translation, and
+ * the hypervisor owns the second stage translation. VMID is an Virtual Machine
+ * Identifier that is to tag TLB entries of a VM. If a VM has multiple physical
+ * devices being assigned to it, while these devices are under different IOMMU
+ * domains, the VMIDs in the second stage configurations of these IOMMU domains
+ * could be aligned to a unified VMID value. This could be achieved by using
+ * these two IOCTLs.
+ *
+ * Caller should get VMID upon its initial value when the first physical device
+ * is assigned to the VM.
+ *
+ * Caller then should set VMID to share the same VMID value with other physical
+ * devices being assigned to the same VM.
+ *
+ */
+#define VFIO_IOMMU_VMID_INVALID		(-1U)
+
+#define VFIO_IOMMU_GET_VMID		_IO(VFIO_TYPE, VFIO_BASE + 22)
+
+#define VFIO_IOMMU_SET_VMID		_IO(VFIO_TYPE, VFIO_BASE + 23)
+
 /* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */
 
 /*
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:10 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:10 -0700
Subject: [RFC][PATCH v2 00/13] iommu/arm-smmu-v3: Add NVIDIA implementation
Message-ID: <20210831025923.15812-1-nicolinc@nvidia.com>

The SMMUv3 devices implemented in the Grace SoC support NVIDIA's custom
CMDQ-Virtualization (CMDQV) hardware. Like the new ECMDQ feature first
introduced in the ARM SMMUv3.3 specification, CMDQV adds multiple VCMDQ
interfaces to supplement the single architected SMMU_CMDQ in an effort
to reduce contention.

This series of patches add CMDQV support with its preparational changes:

* PATCH-1 to PATCH-8 are related to shared VMID feature: they are used
  first to improve TLB utilization, second to bind a shared VMID with a
  VCMDQ interface for hardware configuring requirement.

* PATCH-9 and PATCH-10 are to accommodate the NVIDIA implementation with
  the existing arm-smmu-v3 driver.

* PATCH-11 borrows the "implementation infrastructure" from the arm-smmu
  driver so later change can build upon it.

* PATCH-12 adds an initial NVIDIA implementation related to host feature,
  and also adds implementation specific ->device_reset() and ->get_cmdq()
  callback functions.

* PATCH-13 adds virtualization features using VFIO mdev interface, which
  allows user space hypervisor to map and get access to one of the VCMDQ
  interfaces of CMDQV module.

( Thinking that reviewers can get a better view of this implementation,
  I am attaching QEMU changes here for reference purpose:
      https://github.com/nicolinc/qemu/commits/dev/cmdqv_v6.0.0-rc2
  The branch has all preparational changes, while I'm still integrating
  device model and ARM-VIRT changes, and will push them these two days,
  although they might not be in a good shape of being sent to review yet )

Above all, I marked RFC for this series, as I feel that we may come up
some better solution. So please kindly share your reviews and insights.

Thank you!

Changelog
v1->v2:
 * Added mdev interface support for hypervisor and VMs.
 * Added preparational changes for mdev interface implementation.
 * PATCH-12 Changed ->issue_cmdlist() to ->get_cmdq() for a better
   integration with recently merged ECMDQ-related changes.

Nate Watterson (3):
  iommu/arm-smmu-v3: Add implementation infrastructure
  iommu/arm-smmu-v3: Add support for NVIDIA CMDQ-Virtualization hw
  iommu/nvidia-smmu-v3: Add mdev interface support

Nicolin Chen (10):
  iommu: Add set_nesting_vmid/get_nesting_vmid functions
  vfio: add VFIO_IOMMU_GET_VMID and VFIO_IOMMU_SET_VMID
  vfio: Document VMID control for IOMMU Virtualization
  vfio: add set_vmid and get_vmid for vfio_iommu_type1
  vfio/type1: Implement set_vmid and get_vmid
  vfio/type1: Set/get VMID to/from iommu driver
  iommu/arm-smmu-v3: Add shared VMID support for NESTING
  iommu/arm-smmu-v3: Add VMID alloc/free helpers
  iommu/arm-smmu-v3: Pass dev pointer to arm_smmu_detach_dev
  iommu/arm-smmu-v3: Pass cmdq pointer in arm_smmu_cmdq_issue_cmdlist()

 Documentation/driver-api/vfio.rst             |   34 +
 MAINTAINERS                                   |    2 +
 drivers/iommu/arm/arm-smmu-v3/Makefile        |    2 +-
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c  |   15 +
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  121 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |   18 +
 .../iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c    | 1249 +++++++++++++++++
 drivers/iommu/iommu.c                         |   20 +
 drivers/vfio/vfio.c                           |   25 +
 drivers/vfio/vfio_iommu_type1.c               |   37 +
 include/linux/iommu.h                         |    5 +
 include/linux/vfio.h                          |    2 +
 include/uapi/linux/vfio.h                     |   26 +
 13 files changed, 1537 insertions(+), 19 deletions(-)
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c

-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:15 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:15 -0700
Subject: [RFC][PATCH v2 05/13] vfio/type1: Implement set_vmid and get_vmid
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-6-nicolinc@nvidia.com>

Now we have a pair of ->set_vmid() and ->get_vmid() function
pointers. This patch implements them, to exchange VMID value
between vfio container and vfio_iommu_type1.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 0e9217687f5c..bb5d949bc1af 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -74,6 +74,7 @@ struct vfio_iommu {
 	uint64_t		pgsize_bitmap;
 	uint64_t		num_non_pinned_groups;
 	wait_queue_head_t	vaddr_wait;
+	uint32_t		vmid;
 	bool			v2;
 	bool			nesting;
 	bool			dirty_page_tracking;
@@ -2674,6 +2675,7 @@ static void *vfio_iommu_type1_open(unsigned long arg)
 	iommu->dma_list = RB_ROOT;
 	iommu->dma_avail = dma_entry_limit;
 	iommu->container_open = true;
+	iommu->vmid = VFIO_IOMMU_VMID_INVALID;
 	mutex_init(&iommu->lock);
 	BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier);
 	init_waitqueue_head(&iommu->vaddr_wait);
@@ -3255,6 +3257,27 @@ static void vfio_iommu_type1_notify(void *iommu_data,
 	wake_up_all(&iommu->vaddr_wait);
 }
 
+static int vfio_iommu_type1_get_vmid(void *iommu_data, u32 *vmid)
+{
+	struct vfio_iommu *iommu = iommu_data;
+
+	*vmid = iommu->vmid;
+
+	return 0;
+}
+
+static int vfio_iommu_type1_set_vmid(void *iommu_data, u32 vmid)
+{
+	struct vfio_iommu *iommu = iommu_data;
+
+	if (vmid == VFIO_IOMMU_VMID_INVALID)
+		return -EINVAL;
+
+	iommu->vmid = vmid;
+
+	return 0;
+}
+
 static const struct vfio_iommu_driver_ops vfio_iommu_driver_ops_type1 = {
 	.name			= "vfio-iommu-type1",
 	.owner			= THIS_MODULE,
@@ -3270,6 +3293,8 @@ static const struct vfio_iommu_driver_ops vfio_iommu_driver_ops_type1 = {
 	.dma_rw			= vfio_iommu_type1_dma_rw,
 	.group_iommu_domain	= vfio_iommu_type1_group_iommu_domain,
 	.notify			= vfio_iommu_type1_notify,
+	.set_vmid		= vfio_iommu_type1_set_vmid,
+	.get_vmid		= vfio_iommu_type1_get_vmid,
 };
 
 static int __init vfio_iommu_type1_init(void)
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:18 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:18 -0700
Subject: [RFC][PATCH v2 08/13] iommu/arm-smmu-v3: Add VMID alloc/free helpers
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-9-nicolinc@nvidia.com>

NVIDIA implementation needs to link its Virtual Interface to a
VMID, before a device gets attached to the corresponding iommu
domain. One way to ensure that is to allocate a VMID from impl
side and to pass it down to virtual machine hypervisor so that
later it can set it back to passthrough devices' iommu domains
calling newly added arm_smmu_set/get_nesting_vmid() functions.

This patch adds a pair of helpers to allocate and free VMID in
the bitmap.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 10 ++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  3 +++
 2 files changed, 13 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index c0ae117711fa..497d55ec659b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2032,6 +2032,16 @@ static void arm_smmu_bitmap_free(unsigned long *map, int idx)
 	clear_bit(idx, map);
 }
 
+int arm_smmu_vmid_alloc(struct arm_smmu_device *smmu)
+{
+	return arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
+}
+
+void arm_smmu_vmid_free(struct arm_smmu_device *smmu, u16 vmid)
+{
+	arm_smmu_bitmap_free(smmu->vmid_map, vmid);
+}
+
 static void arm_smmu_domain_free(struct iommu_domain *domain)
 {
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index ea2c61d52df8..20463d17fd9f 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -749,6 +749,9 @@ bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd);
 int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
 			    unsigned long iova, size_t size);
 
+int arm_smmu_vmid_alloc(struct arm_smmu_device *smmu);
+void arm_smmu_vmid_free(struct arm_smmu_device *smmu, u16 vmid);
+
 #ifdef CONFIG_ARM_SMMU_V3_SVA
 bool arm_smmu_sva_supported(struct arm_smmu_device *smmu);
 bool arm_smmu_master_sva_supported(struct arm_smmu_master *master);
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:17 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:17 -0700
Subject: [RFC][PATCH v2 07/13] iommu/arm-smmu-v3: Add shared VMID support for
 NESTING
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-8-nicolinc@nvidia.com>

A VMID can be shared among iommu domains being attached to the same
Virtual Machine in order to improve utilization of TLB cache.

This patch implements ->set_nesting_vmid() and ->get_nesting_vmid()
to set/get s2_cfg->vmid for nesting cases, and then changes to reuse
the VMID.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 65 +++++++++++++++++++--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h |  1 +
 2 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index a388e318f86e..c0ae117711fa 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2051,7 +2051,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 		mutex_unlock(&arm_smmu_asid_lock);
 	} else {
 		struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
-		if (cfg->vmid)
+		if (cfg->vmid && !atomic_dec_return(&smmu->vmid_refcnts[cfg->vmid]))
 			arm_smmu_bitmap_free(smmu->vmid_map, cfg->vmid);
 	}
 
@@ -2121,17 +2121,28 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
 				       struct arm_smmu_master *master,
 				       struct io_pgtable_cfg *pgtbl_cfg)
 {
-	int vmid;
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
 	struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
 	typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr;
 
-	vmid = arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
-	if (vmid < 0)
-		return vmid;
+	/*
+	 * For a nested case where there are multiple passthrough devices to a
+	 * VM, they share a commond VMID, allocated when the first passthrough
+	 * device is attached to the VM. So the cfg->vmid might be already set
+	 * in arm_smmu_set_nesting_vmid(), reported from the hypervisor. In this
+	 * case, simply reuse the shared VMID and increase its refcount.
+	 */
+	if (!cfg->vmid) {
+		int vmid = arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
+
+		if (vmid < 0)
+			return vmid;
+		cfg->vmid = (u16)vmid;
+	}
+
+	atomic_inc(&smmu->vmid_refcnts[cfg->vmid]);
 
 	vtcr = &pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
-	cfg->vmid	= (u16)vmid;
 	cfg->vttbr	= pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
 	cfg->vtcr	= FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, vtcr->tsz) |
 			  FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, vtcr->sl) |
@@ -2731,6 +2742,44 @@ static int arm_smmu_enable_nesting(struct iommu_domain *domain)
 	return ret;
 }
 
+static int arm_smmu_set_nesting_vmid(struct iommu_domain *domain, u32 vmid)
+{
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+	struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg;
+	int ret = 0;
+
+	if (vmid == IOMMU_VMID_INVALID)
+		return -EINVAL;
+
+	mutex_lock(&smmu_domain->init_mutex);
+	if (smmu_domain->smmu || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED)
+		ret = -EPERM;
+	else
+		s2_cfg->vmid = vmid;
+	mutex_unlock(&smmu_domain->init_mutex);
+
+	return ret;
+}
+
+static int arm_smmu_get_nesting_vmid(struct iommu_domain *domain, u32 *vmid)
+{
+	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+	struct arm_smmu_s2_cfg *s2_cfg = &smmu_domain->s2_cfg;
+	int ret = 0;
+
+	if (!vmid)
+		return -EINVAL;
+
+	mutex_lock(&smmu_domain->init_mutex);
+	if (smmu_domain->smmu || smmu_domain->stage != ARM_SMMU_DOMAIN_NESTED)
+		ret = -EPERM;
+	else
+		*vmid = s2_cfg->vmid;
+	mutex_unlock(&smmu_domain->init_mutex);
+
+	return ret;
+}
+
 static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
 {
 	return iommu_fwspec_add_ids(dev, args->args, 1);
@@ -2845,6 +2894,8 @@ static struct iommu_ops arm_smmu_ops = {
 	.release_device		= arm_smmu_release_device,
 	.device_group		= arm_smmu_device_group,
 	.enable_nesting		= arm_smmu_enable_nesting,
+	.set_nesting_vmid	= arm_smmu_set_nesting_vmid,
+	.get_nesting_vmid	= arm_smmu_get_nesting_vmid,
 	.of_xlate		= arm_smmu_of_xlate,
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.put_resv_regions	= generic_iommu_put_resv_regions,
@@ -3530,6 +3581,8 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
 	/* ASID/VMID sizes */
 	smmu->asid_bits = reg & IDR0_ASID16 ? 16 : 8;
 	smmu->vmid_bits = reg & IDR0_VMID16 ? 16 : 8;
+	smmu->vmid_refcnts = devm_kcalloc(smmu->dev, 1 << smmu->vmid_bits,
+					  sizeof(*smmu->vmid_refcnts), GFP_KERNEL);
 
 	/* IDR1 */
 	reg = readl_relaxed(smmu->base + ARM_SMMU_IDR1);
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 4cb136f07914..ea2c61d52df8 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -664,6 +664,7 @@ struct arm_smmu_device {
 #define ARM_SMMU_MAX_VMIDS		(1 << 16)
 	unsigned int			vmid_bits;
 	DECLARE_BITMAP(vmid_map, ARM_SMMU_MAX_VMIDS);
+	atomic_t			*vmid_refcnts;
 
 	unsigned int			ssid_bits;
 	unsigned int			sid_bits;
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:19 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:19 -0700
Subject: [RFC][PATCH v2 09/13] iommu/arm-smmu-v3: Pass dev pointer to
 arm_smmu_detach_dev
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-10-nicolinc@nvidia.com>

We are adding NVIDIA implementation that will need a ->detach_dev()
callback along with the dev pointer to grab client information.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 497d55ec659b..6878a83582b9 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2377,7 +2377,7 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)
 	pci_disable_pasid(pdev);
 }
 
-static void arm_smmu_detach_dev(struct arm_smmu_master *master)
+static void arm_smmu_detach_dev(struct arm_smmu_master *master, struct device *dev)
 {
 	unsigned long flags;
 	struct arm_smmu_domain *smmu_domain = master->domain;
@@ -2421,7 +2421,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 		return -EBUSY;
 	}
 
-	arm_smmu_detach_dev(master);
+	arm_smmu_detach_dev(master, dev);
 
 	mutex_lock(&smmu_domain->init_mutex);
 
@@ -2713,7 +2713,7 @@ static void arm_smmu_release_device(struct device *dev)
 	master = dev_iommu_priv_get(dev);
 	if (WARN_ON(arm_smmu_master_sva_enabled(master)))
 		iopf_queue_remove_device(master->smmu->evtq.iopf, dev);
-	arm_smmu_detach_dev(master);
+	arm_smmu_detach_dev(master, dev);
 	arm_smmu_disable_pasid(master);
 	arm_smmu_remove_master(master);
 	kfree(master);
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:11 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:11 -0700
Subject: [RFC][PATCH v2 01/13] iommu: Add set_nesting_vmid/get_nesting_vmid
 functions
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-2-nicolinc@nvidia.com>

VMID stands for Virtual Machine Identifier, being used to tag
TLB entries to indicate which VM they belong to. This is used
by some IOMMU like SMMUv3 for virtualization case, in nesting
mode.

So this patch adds a pair of new iommu_ops callback functions
with a pair of exported set/get functions to allow VFIO core
to get access of the VMID value in an IOMMU driver.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/iommu.c | 20 ++++++++++++++++++++
 include/linux/iommu.h |  5 +++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 3303d707bab4..051f2df36dc0 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2774,6 +2774,26 @@ int iommu_enable_nesting(struct iommu_domain *domain)
 }
 EXPORT_SYMBOL_GPL(iommu_enable_nesting);
 
+int iommu_set_nesting_vmid(struct iommu_domain *domain, u32 vmid)
+{
+	if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+		return -EINVAL;
+	if (!domain->ops->set_nesting_vmid)
+		return -EINVAL;
+	return domain->ops->set_nesting_vmid(domain, vmid);
+}
+EXPORT_SYMBOL_GPL(iommu_set_nesting_vmid);
+
+int iommu_get_nesting_vmid(struct iommu_domain *domain, u32 *vmid)
+{
+	if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+		return -EINVAL;
+	if (!domain->ops->get_nesting_vmid)
+		return -EINVAL;
+	return domain->ops->get_nesting_vmid(domain, vmid);
+}
+EXPORT_SYMBOL_GPL(iommu_get_nesting_vmid);
+
 int iommu_set_pgtable_quirks(struct iommu_domain *domain,
 		unsigned long quirk)
 {
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d2f3435e7d17..bda6b3450909 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -163,6 +163,7 @@ enum iommu_dev_features {
 };
 
 #define IOMMU_PASID_INVALID	(-1U)
+#define IOMMU_VMID_INVALID	(-1U)
 
 #ifdef CONFIG_IOMMU_API
 
@@ -269,6 +270,8 @@ struct iommu_ops {
 	void (*probe_finalize)(struct device *dev);
 	struct iommu_group *(*device_group)(struct device *dev);
 	int (*enable_nesting)(struct iommu_domain *domain);
+	int (*set_nesting_vmid)(struct iommu_domain *domain, u32 vmid);
+	int (*get_nesting_vmid)(struct iommu_domain *domain, u32 *vmid);
 	int (*set_pgtable_quirks)(struct iommu_domain *domain,
 				  unsigned long quirks);
 
@@ -500,6 +503,8 @@ extern int iommu_group_id(struct iommu_group *group);
 extern struct iommu_domain *iommu_group_default_domain(struct iommu_group *);
 
 int iommu_enable_nesting(struct iommu_domain *domain);
+int iommu_set_nesting_vmid(struct iommu_domain *domain, u32 vmid);
+int iommu_get_nesting_vmid(struct iommu_domain *domain, u32 *vmid);
 int iommu_set_pgtable_quirks(struct iommu_domain *domain,
 		unsigned long quirks);
 
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:16 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:16 -0700
Subject: [RFC][PATCH v2 06/13] vfio/type1: Set/get VMID to/from iommu driver
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-7-nicolinc@nvidia.com>

This patch adds a pair of callbacks of iommu_set_nesting_vmid() and
iommu_get_nesting_vmid() to exchange VMID with the IOMMU core (then
an IOMMU driver).

As a VMID is generated in an IOMMU driver, which is called from the
vfio_iommu_attach_group() function call, add iommu_get_nesting_vmid
right after it creates a VMID and add iommu_set_nesting_vmid before
it to let IOMMU driver reuse it.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/vfio/vfio_iommu_type1.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index bb5d949bc1af..9e72d74dedcd 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -2322,12 +2322,24 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
 		ret = iommu_enable_nesting(domain->domain);
 		if (ret)
 			goto out_domain;
+
+		if (iommu->vmid != VFIO_IOMMU_VMID_INVALID) {
+			ret = iommu_set_nesting_vmid(domain->domain, iommu->vmid);
+			if (ret)
+				goto out_domain;
+		}
 	}
 
 	ret = vfio_iommu_attach_group(domain, group);
 	if (ret)
 		goto out_domain;
 
+	if (iommu->nesting && iommu->vmid == VFIO_IOMMU_VMID_INVALID) {
+		ret = iommu_get_nesting_vmid(domain->domain, &iommu->vmid);
+		if (ret)
+			goto out_domain;
+	}
+
 	/* Get aperture info */
 	geo = &domain->domain->geometry;
 	if (vfio_iommu_aper_conflict(iommu, geo->aperture_start,
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:21 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:21 -0700
Subject: [RFC][PATCH v2 11/13] iommu/arm-smmu-v3: Add implementation
 infrastructure
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-12-nicolinc@nvidia.com>

From: Nate Watterson <nwatterson at nvidia.com>

Follow arm-smmu driver's infrastructure for handling implementation
specific details outside the flow of architectural code.

Signed-off-by: Nate Watterson <nwatterson at nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/Makefile           | 2 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c | 8 ++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c      | 4 ++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h      | 4 ++++
 4 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c

diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile
index 54feb1ecccad..1f5838d3351b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/Makefile
+++ b/drivers/iommu/arm/arm-smmu-v3/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_ARM_SMMU_V3) += arm_smmu_v3.o
-arm_smmu_v3-objs-y += arm-smmu-v3.o
+arm_smmu_v3-objs-y += arm-smmu-v3.o arm-smmu-v3-impl.o
 arm_smmu_v3-objs-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o
 arm_smmu_v3-objs := $(arm_smmu_v3-objs-y)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c
new file mode 100644
index 000000000000..6947d28067a8
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "arm-smmu-v3.h"
+
+struct arm_smmu_device *arm_smmu_v3_impl_init(struct arm_smmu_device *smmu)
+{
+	return smmu;
+}
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 216f3442aac4..510e1493fd5a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3844,6 +3844,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 			return ret;
 	}
 
+	smmu = arm_smmu_v3_impl_init(smmu);
+	if (IS_ERR(smmu))
+		return PTR_ERR(smmu);
+
 	/* Set bypass mode according to firmware probing result */
 	bypass = !!ret;
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 20463d17fd9f..c65c39336916 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -810,4 +810,8 @@ static inline u32 arm_smmu_sva_get_pasid(struct iommu_sva *handle)
 
 static inline void arm_smmu_sva_notifier_synchronize(void) {}
 #endif /* CONFIG_ARM_SMMU_V3_SVA */
+
+/* Implementation details */
+struct arm_smmu_device *arm_smmu_v3_impl_init(struct arm_smmu_device *smmu);
+
 #endif /* _ARM_SMMU_V3_H */
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:22 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:22 -0700
Subject: [RFC][PATCH v2 12/13] iommu/arm-smmu-v3: Add support for NVIDIA
 CMDQ-Virtualization hw
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-13-nicolinc@nvidia.com>

From: Nate Watterson <nwatterson at nvidia.com>

NVIDIA's Grace SoC has a CMDQ-Virtualization (CMDQV) hardware,
which adds multiple VCMDQ interfaces (VINTFs) to supplement the
architected SMMU_CMDQ in an effort to reduce contention.

To make use of these supplemental CMDQs in arm-smmu-v3 driver,
this patch borrows the "implemenatation infrastructure" design
from the arm-smmu driver, and then adds implementation specific
supports for ->device_reset() and ->get_cmdq() functions. Since
nvidia's ->get_cmdq() implemenatation needs to check the first
command of the cmdlist to determine whether to redirect to its
own vcmdq, this patch also adds augments to arm_smmu_get_cmdq()
function.

For the CMDQV driver itself, this patch only adds the essential
parts for the host kernel, in terms of virtualization use cases.
VINTF0 is being reserved for host kernel use, so is initialized
with the driver also.

Note that, for the current plan, the CMDQV driver only supports
ACPI configuration.

Signed-off-by: Nate Watterson <nwatterson at nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 MAINTAINERS                                   |   2 +
 drivers/iommu/arm/arm-smmu-v3/Makefile        |   2 +-
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c  |   7 +
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  15 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |   8 +
 .../iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c    | 432 ++++++++++++++++++
 6 files changed, 463 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f800abca74b0..7a2f21279d35 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18428,8 +18428,10 @@ F:	drivers/i2c/busses/i2c-tegra.c
 TEGRA IOMMU DRIVERS
 M:	Thierry Reding <thierry.reding at gmail.com>
 R:	Krishna Reddy <vdumpa at nvidia.com>
+R:	Nicolin Chen <nicoleotsuka at gmail.com>
 L:	linux-tegra at vger.kernel.org
 S:	Supported
+F:	drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c
 F:	drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
 F:	drivers/iommu/tegra*
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/Makefile b/drivers/iommu/arm/arm-smmu-v3/Makefile
index 1f5838d3351b..0aa84c0a50ea 100644
--- a/drivers/iommu/arm/arm-smmu-v3/Makefile
+++ b/drivers/iommu/arm/arm-smmu-v3/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_ARM_SMMU_V3) += arm_smmu_v3.o
-arm_smmu_v3-objs-y += arm-smmu-v3.o arm-smmu-v3-impl.o
+arm_smmu_v3-objs-y += arm-smmu-v3.o arm-smmu-v3-impl.o nvidia-smmu-v3.o
 arm_smmu_v3-objs-$(CONFIG_ARM_SMMU_V3_SVA) += arm-smmu-v3-sva.o
 arm_smmu_v3-objs := $(arm_smmu_v3-objs-y)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c
index 6947d28067a8..37d062e40eb5 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c
@@ -4,5 +4,12 @@
 
 struct arm_smmu_device *arm_smmu_v3_impl_init(struct arm_smmu_device *smmu)
 {
+	/*
+	 * Nvidia implementation supports ACPI only, so calling its init()
+	 * unconditionally to walk through ACPI tables to probe the device.
+	 * It will keep the smmu pointer intact, if it fails.
+	 */
+	smmu = nvidia_smmu_v3_impl_init(smmu);
+
 	return smmu;
 }
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 510e1493fd5a..1b9459592f76 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -335,8 +335,11 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
 	return 0;
 }
 
-static struct arm_smmu_cmdq *arm_smmu_get_cmdq(struct arm_smmu_device *smmu)
+static struct arm_smmu_cmdq *arm_smmu_get_cmdq(struct arm_smmu_device *smmu, u64 *cmds, int n)
 {
+	if (smmu->impl && smmu->impl->get_cmdq)
+		return smmu->impl->get_cmdq(smmu, cmds, n);
+
 	return &smmu->cmdq;
 }
 
@@ -742,7 +745,7 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 	u32 prod;
 	unsigned long flags;
 	bool owner;
-	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
+	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu, cmds, n);
 	struct arm_smmu_ll_queue llq, head;
 	int ret = 0;
 
@@ -3487,6 +3490,14 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 		return ret;
 	}
 
+	if (smmu->impl && smmu->impl->device_reset) {
+		ret = smmu->impl->device_reset(smmu);
+		if (ret) {
+			dev_err(smmu->dev, "failed at implementation specific device_reset\n");
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index c65c39336916..bb903a7fa662 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -647,6 +647,8 @@ struct arm_smmu_device {
 #define ARM_SMMU_OPT_MSIPOLL		(1 << 2)
 	u32				options;
 
+	const struct arm_smmu_impl	*impl;
+
 	struct arm_smmu_cmdq		cmdq;
 	struct arm_smmu_evtq		evtq;
 	struct arm_smmu_priq		priq;
@@ -812,6 +814,12 @@ static inline void arm_smmu_sva_notifier_synchronize(void) {}
 #endif /* CONFIG_ARM_SMMU_V3_SVA */
 
 /* Implementation details */
+struct arm_smmu_impl {
+	int (*device_reset)(struct arm_smmu_device *smmu);
+	struct arm_smmu_cmdq *(*get_cmdq)(struct arm_smmu_device *smmu, u64 *cmds, int n);
+};
+
 struct arm_smmu_device *arm_smmu_v3_impl_init(struct arm_smmu_device *smmu);
+struct arm_smmu_device *nvidia_smmu_v3_impl_init(struct arm_smmu_device *smmu);
 
 #endif /* _ARM_SMMU_V3_H */
diff --git a/drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c
new file mode 100644
index 000000000000..0c92fe433c6e
--- /dev/null
+++ b/drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c
@@ -0,0 +1,432 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define dev_fmt(fmt) "nvidia_smmu_cmdqv: " fmt
+
+#include <linux/acpi.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/iommu.h>
+#include <linux/iopoll.h>
+#include <linux/platform_device.h>
+
+#include <acpi/acpixf.h>
+
+#include "arm-smmu-v3.h"
+
+#define NVIDIA_SMMU_CMDQV_HID		"NVDA0600"
+
+/* CMDQV register page base and size defines */
+#define NVIDIA_CMDQV_CONFIG_BASE	(0)
+#define NVIDIA_CMDQV_CONFIG_SIZE	(SZ_64K)
+#define NVIDIA_VCMDQ_BASE		(0 + SZ_64K)
+#define NVIDIA_VCMDQ_SIZE		(SZ_64K * 2) /* PAGE0 and PAGE1 */
+
+/* CMDQV global config regs */
+#define NVIDIA_CMDQV_CONFIG		0x0000
+#define  CMDQV_EN			BIT(0)
+
+#define NVIDIA_CMDQV_PARAM		0x0004
+#define  CMDQV_NUM_VINTF_LOG2		GENMASK(11, 8)
+#define  CMDQV_NUM_VCMDQ_LOG2		GENMASK(7, 4)
+
+#define NVIDIA_CMDQV_STATUS		0x0008
+#define  CMDQV_STATUS			GENMASK(2, 1)
+#define  CMDQV_ENABLED			BIT(0)
+
+#define NVIDIA_CMDQV_VINTF_ERR_MAP	0x000C
+#define NVIDIA_CMDQV_VINTF_INT_MASK	0x0014
+#define NVIDIA_CMDQV_VCMDQ_ERR_MAP	0x001C
+
+#define NVIDIA_CMDQV_CMDQ_ALLOC(q)	(0x0200 + 0x4*(q))
+#define  CMDQV_CMDQ_ALLOC_VINTF		GENMASK(20, 15)
+#define  CMDQV_CMDQ_ALLOC_LVCMDQ	GENMASK(7, 1)
+#define  CMDQV_CMDQ_ALLOCATED		BIT(0)
+
+/* VINTF config regs */
+#define NVIDIA_CMDQV_VINTF(v)		(0x1000 + 0x100*(v))
+
+#define NVIDIA_VINTF_CONFIG		0x0000
+#define  VINTF_HYP_OWN			BIT(17)
+#define  VINTF_VMID			GENMASK(16, 1)
+#define  VINTF_EN			BIT(0)
+
+#define NVIDIA_VINTF_STATUS		0x0004
+#define  VINTF_STATUS			GENMASK(3, 1)
+#define  VINTF_ENABLED			BIT(0)
+
+/* VCMDQ config regs */
+/* -- PAGE0 -- */
+#define NVIDIA_CMDQV_VCMDQ(q)		(NVIDIA_VCMDQ_BASE + 0x80*(q))
+
+#define NVIDIA_VCMDQ_CONS		0x00000
+#define  VCMDQ_CONS_ERR			GENMASK(30, 24)
+
+#define NVIDIA_VCMDQ_PROD		0x00004
+
+#define NVIDIA_VCMDQ_CONFIG		0x00008
+#define  VCMDQ_EN			BIT(0)
+
+#define NVIDIA_VCMDQ_STATUS		0x0000C
+#define  VCMDQ_ENABLED			BIT(0)
+
+#define NVIDIA_VCMDQ_GERROR		0x00010
+#define NVIDIA_VCMDQ_GERRORN		0x00014
+
+/* -- PAGE1 -- */
+#define NVIDIA_VCMDQ_BASE_L(q)		(NVIDIA_CMDQV_VCMDQ(q) + SZ_64K)
+#define  VCMDQ_ADDR			GENMASK(63, 5)
+#define  VCMDQ_LOG2SIZE			GENMASK(4, 0)
+
+struct nvidia_smmu_vintf {
+	u16			idx;
+	u32			cfg;
+	u32			status;
+
+	void __iomem		*base;
+	struct arm_smmu_cmdq	*vcmdqs;
+};
+
+struct nvidia_smmu {
+	struct arm_smmu_device	smmu;
+
+	struct device		*cmdqv_dev;
+	void __iomem		*cmdqv_base;
+	int			cmdqv_irq;
+
+	/* CMDQV Hardware Params */
+	u16			num_total_vintfs;
+	u16			num_total_vcmdqs;
+	u16			num_vcmdqs_per_vintf;
+
+	/* CMDQV_VINTF(0) reserved for host kernel use */
+	struct nvidia_smmu_vintf vintf0;
+};
+
+static irqreturn_t nvidia_smmu_cmdqv_isr(int irq, void *devid)
+{
+	struct nvidia_smmu *nsmmu = (struct nvidia_smmu *)devid;
+	struct nvidia_smmu_vintf *vintf0 = &nsmmu->vintf0;
+	u32 vintf_err_map[2];
+	u32 vcmdq_err_map[4];
+
+	vintf_err_map[0] = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_VINTF_ERR_MAP);
+	vintf_err_map[1] = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_VINTF_ERR_MAP + 0x4);
+
+	vcmdq_err_map[0] = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_VCMDQ_ERR_MAP);
+	vcmdq_err_map[1] = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_VCMDQ_ERR_MAP + 0x4);
+	vcmdq_err_map[2] = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_VCMDQ_ERR_MAP + 0x8);
+	vcmdq_err_map[3] = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_VCMDQ_ERR_MAP + 0xC);
+
+	dev_warn(nsmmu->cmdqv_dev,
+		 "unexpected cmdqv error reported: vintf_map %08X %08X, vcmdq_map %08X %08X %08X %08X\n",
+		 vintf_err_map[0], vintf_err_map[1], vcmdq_err_map[0], vcmdq_err_map[1],
+		 vcmdq_err_map[2], vcmdq_err_map[3]);
+
+	/* If the error was reported by vintf0, avoid using any of its VCMDQs */
+	if (vintf_err_map[vintf0->idx / 32] & (1 << (vintf0->idx % 32))) {
+		vintf0->status = readl_relaxed(vintf0->base + NVIDIA_VINTF_STATUS);
+
+		dev_warn(nsmmu->cmdqv_dev, "error (0x%lX) reported by host vintf0 - disabling its vcmdqs\n",
+			 FIELD_GET(VINTF_STATUS, vintf0->status));
+	} else if (vintf_err_map[0] || vintf_err_map[1]) {
+		dev_err(nsmmu->cmdqv_dev, "cmdqv error interrupt triggered by unassigned vintf!\n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+/* Adapt struct arm_smmu_cmdq init sequences from arm-smmu-v3.c for VCMDQs */
+static int nvidia_smmu_init_one_arm_smmu_cmdq(struct nvidia_smmu *nsmmu,
+					      struct arm_smmu_cmdq *cmdq,
+					      void __iomem *vcmdq_base,
+					      u16 qidx)
+{
+	struct arm_smmu_queue *q = &cmdq->q;
+	size_t qsz;
+
+	/* struct arm_smmu_cmdq config normally done in arm_smmu_device_hw_probe() */
+	q->llq.max_n_shift = ilog2(SZ_64K >> CMDQ_ENT_SZ_SHIFT);
+
+	/* struct arm_smmu_cmdq config normally done in arm_smmu_init_one_queue() */
+	qsz = (1 << q->llq.max_n_shift) << CMDQ_ENT_SZ_SHIFT;
+	q->base = dmam_alloc_coherent(nsmmu->cmdqv_dev, qsz, &q->base_dma, GFP_KERNEL);
+	if (!q->base) {
+		dev_err(nsmmu->cmdqv_dev, "failed to allocate 0x%zX bytes for VCMDQ%u\n",
+			qsz, qidx);
+		return -ENOMEM;
+	}
+	dev_dbg(nsmmu->cmdqv_dev, "allocated %u entries for VCMDQ%u @ 0x%llX [%pad] ++ %zX",
+		1 << q->llq.max_n_shift, qidx, (u64)q->base, &q->base_dma, qsz);
+
+	q->prod_reg = vcmdq_base + NVIDIA_VCMDQ_PROD;
+	q->cons_reg = vcmdq_base + NVIDIA_VCMDQ_CONS;
+	q->ent_dwords = CMDQ_ENT_DWORDS;
+
+	q->q_base  = q->base_dma & VCMDQ_ADDR;
+	q->q_base |= FIELD_PREP(VCMDQ_LOG2SIZE, q->llq.max_n_shift);
+
+	q->llq.prod = q->llq.cons = 0;
+
+	/* struct arm_smmu_cmdq config normally done in arm_smmu_cmdq_init() */
+	atomic_set(&cmdq->owner_prod, 0);
+	atomic_set(&cmdq->lock, 0);
+
+	cmdq->valid_map = (atomic_long_t *)bitmap_zalloc(1 << q->llq.max_n_shift, GFP_KERNEL);
+	if (!cmdq->valid_map) {
+		dev_err(nsmmu->cmdqv_dev, "failed to allocate valid_map for VCMDQ%u\n", qidx);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int nvidia_smmu_cmdqv_init(struct nvidia_smmu *nsmmu)
+{
+	struct nvidia_smmu_vintf *vintf0 = &nsmmu->vintf0;
+	u32 regval;
+	u16 qidx;
+	int ret;
+
+	/* Setup vintf0 for host kernel */
+	vintf0->idx = 0;
+	vintf0->base = nsmmu->cmdqv_base + NVIDIA_CMDQV_VINTF(0);
+
+	regval = FIELD_PREP(VINTF_HYP_OWN, nsmmu->num_total_vintfs > 1);
+	writel_relaxed(regval, vintf0->base + NVIDIA_VINTF_CONFIG);
+
+	regval |= FIELD_PREP(VINTF_EN, 1);
+	writel_relaxed(regval, vintf0->base + NVIDIA_VINTF_CONFIG);
+
+	vintf0->cfg = regval;
+
+	ret = readl_relaxed_poll_timeout(vintf0->base + NVIDIA_VINTF_STATUS,
+					 regval, regval == VINTF_ENABLED,
+					 1, ARM_SMMU_POLL_TIMEOUT_US);
+	vintf0->status = regval;
+	if (ret) {
+		dev_err(nsmmu->cmdqv_dev, "failed to enable VINTF%u: STATUS = 0x%08X\n",
+			vintf0->idx, regval);
+		return ret;
+	}
+
+	/* Allocate vcmdqs to vintf0 */
+	for (qidx = 0; qidx < nsmmu->num_vcmdqs_per_vintf; qidx++) {
+		regval  = FIELD_PREP(CMDQV_CMDQ_ALLOC_VINTF, vintf0->idx);
+		regval |= FIELD_PREP(CMDQV_CMDQ_ALLOC_LVCMDQ, qidx);
+		regval |= CMDQV_CMDQ_ALLOCATED;
+		writel_relaxed(regval, nsmmu->cmdqv_base + NVIDIA_CMDQV_CMDQ_ALLOC(qidx));
+	}
+
+	/* Build an arm_smmu_cmdq for each vcmdq allocated to vintf0 */
+	vintf0->vcmdqs = devm_kcalloc(nsmmu->cmdqv_dev, nsmmu->num_vcmdqs_per_vintf,
+				      sizeof(*vintf0->vcmdqs), GFP_KERNEL);
+	if (!vintf0->vcmdqs)
+		return -ENOMEM;
+
+	for (qidx = 0; qidx < nsmmu->num_vcmdqs_per_vintf; qidx++) {
+		void __iomem *vcmdq_base = nsmmu->cmdqv_base + NVIDIA_CMDQV_VCMDQ(qidx);
+		struct arm_smmu_cmdq *cmdq = &vintf0->vcmdqs[qidx];
+
+		/* Setup struct arm_smmu_cmdq data members */
+		nvidia_smmu_init_one_arm_smmu_cmdq(nsmmu, cmdq, vcmdq_base, qidx);
+
+		/* Configure and enable the vcmdq */
+		writel_relaxed(0, vcmdq_base + NVIDIA_VCMDQ_PROD);
+		writel_relaxed(0, vcmdq_base + NVIDIA_VCMDQ_CONS);
+
+		writeq_relaxed(cmdq->q.q_base, nsmmu->cmdqv_base + NVIDIA_VCMDQ_BASE_L(qidx));
+
+		writel_relaxed(VCMDQ_EN, vcmdq_base + NVIDIA_VCMDQ_CONFIG);
+		ret = readl_poll_timeout(vcmdq_base + NVIDIA_VCMDQ_STATUS,
+					 regval, regval == VCMDQ_ENABLED,
+					 1, ARM_SMMU_POLL_TIMEOUT_US);
+		if (ret) {
+			u32 gerror = readl_relaxed(vcmdq_base + NVIDIA_VCMDQ_GERROR);
+			u32 gerrorn = readl_relaxed(vcmdq_base + NVIDIA_VCMDQ_GERRORN);
+			u32 cons = readl_relaxed(vcmdq_base + NVIDIA_VCMDQ_CONS);
+
+			dev_err(nsmmu->cmdqv_dev,
+				"failed to enable VCMDQ%u: GERROR=0x%X, GERRORN=0x%X, CONS=0x%X\n",
+				qidx, gerror, gerrorn, cons);
+			return ret;
+		}
+
+		dev_info(nsmmu->cmdqv_dev, "VCMDQ%u allocated to VINTF%u as logical-VCMDQ%u\n",
+			 qidx, vintf0->idx, qidx);
+	}
+
+	return 0;
+}
+
+static int nvidia_smmu_probe(struct nvidia_smmu *nsmmu)
+{
+	struct platform_device *cmdqv_pdev = to_platform_device(nsmmu->cmdqv_dev);
+	struct resource *res;
+	u32 regval;
+
+	/* Base address */
+	res = platform_get_resource(cmdqv_pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	nsmmu->cmdqv_base = devm_ioremap_resource(nsmmu->cmdqv_dev, res);
+	if (IS_ERR(nsmmu->cmdqv_base))
+		return PTR_ERR(nsmmu->cmdqv_base);
+
+	/* Interrupt */
+	nsmmu->cmdqv_irq = platform_get_irq(cmdqv_pdev, 0);
+	if (nsmmu->cmdqv_irq < 0) {
+		dev_warn(nsmmu->cmdqv_dev, "no cmdqv interrupt - errors will not be reported\n");
+		nsmmu->cmdqv_irq = 0;
+	}
+
+	/* Probe the h/w */
+	regval = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_CONFIG);
+	if (!FIELD_GET(CMDQV_EN, regval)) {
+		dev_err(nsmmu->cmdqv_dev, "CMDQV h/w is disabled: CMDQV_CONFIG=0x%08X\n", regval);
+		return -ENODEV;
+	}
+
+	regval = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_STATUS);
+	if (!FIELD_GET(CMDQV_ENABLED, regval) || FIELD_GET(CMDQV_STATUS, regval)) {
+		dev_err(nsmmu->cmdqv_dev, "CMDQV h/w not ready: CMDQV_STATUS=0x%08X\n", regval);
+		return -ENODEV;
+	}
+
+	regval = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_PARAM);
+	nsmmu->num_total_vintfs = 1 << FIELD_GET(CMDQV_NUM_VINTF_LOG2, regval);
+	nsmmu->num_total_vcmdqs = 1 << FIELD_GET(CMDQV_NUM_VCMDQ_LOG2, regval);
+	nsmmu->num_vcmdqs_per_vintf = nsmmu->num_total_vcmdqs / nsmmu->num_total_vintfs;
+
+	return 0;
+}
+
+static struct arm_smmu_cmdq *nvidia_smmu_get_cmdq(struct arm_smmu_device *smmu, u64 *cmds, int n)
+{
+	struct nvidia_smmu *nsmmu = (struct nvidia_smmu *)smmu;
+	struct nvidia_smmu_vintf *vintf0 = &nsmmu->vintf0;
+	u16 qidx;
+
+	/* Make sure vintf0 is enabled and healthy */
+	if (vintf0->status != VINTF_ENABLED)
+		return &smmu->cmdq;
+
+	/* Check for illegal CMDs */
+	if (!FIELD_GET(VINTF_HYP_OWN, vintf0->cfg)) {
+		u64 opcode = (n) ? FIELD_GET(CMDQ_0_OP, cmds[0]) : CMDQ_OP_CMD_SYNC;
+
+		/* List all non-illegal CMDs for cmdq overriding */
+		switch (opcode) {
+		case CMDQ_OP_TLBI_NH_ASID:
+		case CMDQ_OP_TLBI_NH_VA:
+		case CMDQ_OP_TLBI_S12_VMALL:
+		case CMDQ_OP_TLBI_S2_IPA:
+		case CMDQ_OP_ATC_INV:
+			break;
+		default:
+			/* Skip overriding for illegal CMDs */
+			return &smmu->cmdq;
+		}
+	}
+
+	/*
+	 * Select a vcmdq to use. Here we use a temporal solution to
+	 * balance out traffic on cmdq issuing: each cmdq has its own
+	 * lock, if all cpus issue cmdlist using the same cmdq, only
+	 * one CPU at a time can enter the process, while the others
+	 * will be spinning at the same lock.
+	 */
+	qidx = smp_processor_id() % nsmmu->num_vcmdqs_per_vintf;
+	return &vintf0->vcmdqs[qidx];
+}
+
+static int nvidia_smmu_device_reset(struct arm_smmu_device *smmu)
+{
+	struct nvidia_smmu *nsmmu = (struct nvidia_smmu *)smmu;
+	int ret;
+
+	ret = nvidia_smmu_cmdqv_init(nsmmu);
+	if (ret)
+		return ret;
+
+	if (nsmmu->cmdqv_irq) {
+		ret = devm_request_irq(nsmmu->cmdqv_dev, nsmmu->cmdqv_irq, nvidia_smmu_cmdqv_isr,
+				       IRQF_SHARED, "nvidia-smmu-cmdqv", nsmmu);
+		if (ret) {
+			dev_err(nsmmu->cmdqv_dev, "failed to claim irq (%d): %d\n",
+				nsmmu->cmdqv_irq, ret);
+			return ret;
+		}
+	}
+
+	/* Disable FEAT_MSI and OPT_MSIPOLL since VCMDQs only support CMD_SYNC w/CS_NONE */
+	smmu->features &= ~ARM_SMMU_FEAT_MSI;
+	smmu->options &= ~ARM_SMMU_OPT_MSIPOLL;
+
+	return 0;
+}
+
+const struct arm_smmu_impl nvidia_smmu_impl = {
+	.device_reset = nvidia_smmu_device_reset,
+	.get_cmdq = nvidia_smmu_get_cmdq,
+};
+
+#ifdef CONFIG_ACPI
+struct nvidia_smmu *nvidia_smmu_create(struct arm_smmu_device *smmu)
+{
+	struct nvidia_smmu *nsmmu = NULL;
+	struct acpi_iort_node *node;
+	struct acpi_device *adev;
+	struct device *cmdqv_dev;
+	const char *match_uid;
+
+	if (acpi_disabled)
+		return NULL;
+
+	/* Look for a device in the DSDT whose _UID matches the SMMU's iort_node identifier */
+	node = *(struct acpi_iort_node **)dev_get_platdata(smmu->dev);
+	match_uid = kasprintf(GFP_KERNEL, "%u", node->identifier);
+	adev = acpi_dev_get_first_match_dev(NVIDIA_SMMU_CMDQV_HID, match_uid, -1);
+	kfree(match_uid);
+
+	if (!adev)
+		return NULL;
+
+	cmdqv_dev = bus_find_device_by_acpi_dev(&platform_bus_type, adev);
+	if (!cmdqv_dev)
+		return NULL;
+
+	dev_info(smmu->dev, "found companion CMDQV device, %s", dev_name(cmdqv_dev));
+
+	nsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*nsmmu), GFP_KERNEL);
+	if (!nsmmu)
+		return ERR_PTR(-ENOMEM);
+
+	nsmmu->cmdqv_dev = cmdqv_dev;
+
+	return nsmmu;
+}
+#else
+struct nvidia_smmu *nvidia_smmu_create(struct arm_smmu_device *smmu)
+{
+	return NULL;
+}
+#endif
+
+struct arm_smmu_device *nvidia_smmu_v3_impl_init(struct arm_smmu_device *smmu)
+{
+	struct nvidia_smmu *nsmmu;
+	int ret;
+
+	nsmmu = nvidia_smmu_create(smmu);
+	if (!nsmmu)
+		return smmu;
+
+	ret = nvidia_smmu_probe(nsmmu);
+	if (ret)
+		return ERR_PTR(ret);
+
+	nsmmu->smmu.impl = &nvidia_smmu_impl;
+
+	return &nsmmu->smmu;
+}
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:20 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:20 -0700
Subject: [RFC][PATCH v2 10/13] iommu/arm-smmu-v3: Pass cmdq pointer in
 arm_smmu_cmdq_issue_cmdlist()
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-11-nicolinc@nvidia.com>

The driver currently calls arm_smmu_get_cmdq() helper internally in
different places, though they are all actually called from the same
source -- arm_smmu_cmdq_issue_cmdlist() function.

This patch changes this to pass the cmdq pointer to these functions
instead of calling arm_smmu_get_cmdq() every time.

This also helps NVIDIA implementation, which maintains its own cmdq
pointers and needs to redirect the cmdq pointer from arm_smmu->cmdq
pointer to its own, upon scanning the illegal commands by checking
the opcode of the cmdlist.

Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 6878a83582b9..216f3442aac4 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -584,11 +584,11 @@ static void arm_smmu_cmdq_poll_valid_map(struct arm_smmu_cmdq *cmdq,
 
 /* Wait for the command queue to become non-full */
 static int arm_smmu_cmdq_poll_until_not_full(struct arm_smmu_device *smmu,
+					     struct arm_smmu_cmdq *cmdq,
 					     struct arm_smmu_ll_queue *llq)
 {
 	unsigned long flags;
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	int ret = 0;
 
 	/*
@@ -619,11 +619,11 @@ static int arm_smmu_cmdq_poll_until_not_full(struct arm_smmu_device *smmu,
  * Must be called with the cmdq lock held in some capacity.
  */
 static int __arm_smmu_cmdq_poll_until_msi(struct arm_smmu_device *smmu,
+					  struct arm_smmu_cmdq *cmdq,
 					  struct arm_smmu_ll_queue *llq)
 {
 	int ret = 0;
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	u32 *cmd = (u32 *)(Q_ENT(&cmdq->q, llq->prod));
 
 	queue_poll_init(smmu, &qp);
@@ -643,10 +643,10 @@ static int __arm_smmu_cmdq_poll_until_msi(struct arm_smmu_device *smmu,
  * Must be called with the cmdq lock held in some capacity.
  */
 static int __arm_smmu_cmdq_poll_until_consumed(struct arm_smmu_device *smmu,
+					       struct arm_smmu_cmdq *cmdq,
 					       struct arm_smmu_ll_queue *llq)
 {
 	struct arm_smmu_queue_poll qp;
-	struct arm_smmu_cmdq *cmdq = arm_smmu_get_cmdq(smmu);
 	u32 prod = llq->prod;
 	int ret = 0;
 
@@ -693,12 +693,13 @@ static int __arm_smmu_cmdq_poll_until_consumed(struct arm_smmu_device *smmu,
 }
 
 static int arm_smmu_cmdq_poll_until_sync(struct arm_smmu_device *smmu,
+					 struct arm_smmu_cmdq *cmdq,
 					 struct arm_smmu_ll_queue *llq)
 {
 	if (smmu->options & ARM_SMMU_OPT_MSIPOLL)
-		return __arm_smmu_cmdq_poll_until_msi(smmu, llq);
+		return __arm_smmu_cmdq_poll_until_msi(smmu, cmdq, llq);
 
-	return __arm_smmu_cmdq_poll_until_consumed(smmu, llq);
+	return __arm_smmu_cmdq_poll_until_consumed(smmu, cmdq, llq);
 }
 
 static void arm_smmu_cmdq_write_entries(struct arm_smmu_cmdq *cmdq, u64 *cmds,
@@ -755,7 +756,7 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 
 		while (!queue_has_space(&llq, n + sync)) {
 			local_irq_restore(flags);
-			if (arm_smmu_cmdq_poll_until_not_full(smmu, &llq))
+			if (arm_smmu_cmdq_poll_until_not_full(smmu, cmdq, &llq))
 				dev_err_ratelimited(smmu->dev, "CMDQ timeout\n");
 			local_irq_save(flags);
 		}
@@ -831,7 +832,7 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
 	/* 5. If we are inserting a CMD_SYNC, we must wait for it to complete */
 	if (sync) {
 		llq.prod = queue_inc_prod_n(&llq, n);
-		ret = arm_smmu_cmdq_poll_until_sync(smmu, &llq);
+		ret = arm_smmu_cmdq_poll_until_sync(smmu, cmdq, &llq);
 		if (ret) {
 			dev_err_ratelimited(smmu->dev,
 					    "CMD_SYNC timeout at 0x%08x [hwprod 0x%08x, hwcons 0x%08x]\n",
-- 
2.17.1



From nicolinc at nvidia.com  Mon Aug 30 19:59:23 2021
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Mon, 30 Aug 2021 19:59:23 -0700
Subject: [RFC][PATCH v2 13/13] iommu/nvidia-smmu-v3: Add mdev interface support
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831025923.15812-14-nicolinc@nvidia.com>

From: Nate Watterson <nwatterson at nvidia.com>

This patch adds initial mdev interface support for NVIDIA SMMU CMDQV
driver.

The NVIDIA SMMU CMDQV module has multiple virtual interfaces (VINTFs),
designed to be exposed to virtual machines running on the user space,
while each VINTF can allocate dedicated VCMDQs for TLB invalidations.

The hypervisor can import, to a VM, one of these interfaces via VFIO
mdev interface, to get access to VINTF registers in the host kernel.

Each VINTF has two pages of MMIO regions: PAGE0 and PAGE1. PAGE0 has
performance sensitive registers such as CONS_INDX and PROD_INDX that
should be programmed by the guest directly, so the driver has a mmap
implementation via the mdev interface to let user space get acces to
PAGE0 directly. PAGE1 then has two base address configuring registers
where the addresses should be translated from guest PAs to host PAs,
so they are handled via mdev read/write() to trap for replacements.

As previous patch mentioned, VINTF0 is reserved for the host kernel
(or hypervisor) use, a VINTFx (x > 0) should be allocated to a guest
VM. And from the guest perspective, the VINTFx (host) is seen as the
VINTF0 of the guest. Beside the two MMIO regions of VINTF0, the guest
VM also has the global configuration MMIO region as the host kernel
does, and this global region is also handled via mdev read/write()
to limit the guest to access the bits of its own.

Additionally, there were a couple of issues for this implementation:
1) Setting into VINTF CONFIG register the same VMID as SMMU's s2_cfg.
2) Before enabling the VINTF, programing up-to-16 sets of SID_REPLACE
   and SID_MATCH registers that stores physical stream IDs of host's
   and corresponding virtual stream IDs of guest's respectively.

And in this patch, we add a pair of ->attach_dev and ->detach_dev and
implement them in the following ways:
1) For each VINTF, pre-allocating a VMID on the bitmap of arm_smmu_v3
   driver to create a link between VINTF index and VMID, so either of
   them can be quickly looked up using the counterpart later.
2) Programming PHY_SID into SID_REPLACE (corresponding register), yet
   writing iommu_group_id (a fake VIRT_SID) into SID_MATCH, as it is
   the only shared information of a passthrough device between a host
   kernel and a hypervisor. So the hypervisor is responsible to match
   the iommu_group_id and then to replace it with a virtual SID.
3) Note that, by doing (1) the VMID is now created along with a VINTF
   in the nvidia_smmu_cmdqv_mdev_create() function, which is executed
   before a hypervisor or VM starts, comparing to previous situation:
   we added a few patches to let arm-smmu-v3 driver allocate a shared
   VMID in arm_smmu_attach_dev() function, when the first passthrough
   device is added to the VM. This means that, in the new situation,
   the shared VMID needs to be passed to the hypervisor, before any
   passthrough device gets attached. So, we reuse VFIO_IOMMU_GET_VMID
   command via the mdev ioctl interface to pass the VMID to the CMDQV
   device model, then to the SMMUv3 device model, so that hypervisor
   can set the same VMID to all IOMMU domains of passthrough devices
   using the previous pathway via VFIO core back to SMMUv3 driver.

Signed-off-by: Nate Watterson <nwatterson at nvidia.com>
Signed-off-by: Nicolin Chen <nicolinc at nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |   6 +
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |   2 +
 .../iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c    | 817 ++++++++++++++++++
 3 files changed, 825 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 1b9459592f76..fc543181ddde 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2389,6 +2389,9 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master, struct device *d
 	if (!smmu_domain)
 		return;
 
+	if (master->smmu->impl && master->smmu->impl->detach_dev)
+		master->smmu->impl->detach_dev(smmu_domain, dev);
+
 	arm_smmu_disable_ats(master);
 
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
@@ -2471,6 +2474,9 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
 	arm_smmu_enable_ats(master);
 
+	if (smmu->impl && smmu->impl->attach_dev)
+		ret = smmu->impl->attach_dev(smmu_domain, dev);
+
 out_unlock:
 	mutex_unlock(&smmu_domain->init_mutex);
 	return ret;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index bb903a7fa662..a872c0d2f23c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -817,6 +817,8 @@ static inline void arm_smmu_sva_notifier_synchronize(void) {}
 struct arm_smmu_impl {
 	int (*device_reset)(struct arm_smmu_device *smmu);
 	struct arm_smmu_cmdq *(*get_cmdq)(struct arm_smmu_device *smmu, u64 *cmds, int n);
+	int (*attach_dev)(struct arm_smmu_domain *smmu_domain, struct device *dev);
+	void (*detach_dev)(struct arm_smmu_domain *smmu_domain, struct device *dev);
 };
 
 struct arm_smmu_device *arm_smmu_v3_impl_init(struct arm_smmu_device *smmu);
diff --git a/drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c
index 0c92fe433c6e..265681ba96bc 100644
--- a/drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c
@@ -7,7 +7,10 @@
 #include <linux/interrupt.h>
 #include <linux/iommu.h>
 #include <linux/iopoll.h>
+#include <linux/kvm_host.h>
+#include <linux/mdev.h>
 #include <linux/platform_device.h>
+#include <linux/vfio.h>
 
 #include <acpi/acpixf.h>
 
@@ -20,14 +23,17 @@
 #define NVIDIA_CMDQV_CONFIG_SIZE	(SZ_64K)
 #define NVIDIA_VCMDQ_BASE		(0 + SZ_64K)
 #define NVIDIA_VCMDQ_SIZE		(SZ_64K * 2) /* PAGE0 and PAGE1 */
+#define NVIDIA_VINTF_VCMDQ_BASE		(NVIDIA_VCMDQ_BASE + NVIDIA_VCMDQ_SIZE)
 
 /* CMDQV global config regs */
 #define NVIDIA_CMDQV_CONFIG		0x0000
 #define  CMDQV_EN			BIT(0)
 
 #define NVIDIA_CMDQV_PARAM		0x0004
+#define  CMDQV_NUM_SID_PER_VM_LOG2	GENMASK(15, 12)
 #define  CMDQV_NUM_VINTF_LOG2		GENMASK(11, 8)
 #define  CMDQV_NUM_VCMDQ_LOG2		GENMASK(7, 4)
+#define  CMDQV_VER			GENMASK(3, 0)
 
 #define NVIDIA_CMDQV_STATUS		0x0008
 #define  CMDQV_STATUS			GENMASK(2, 1)
@@ -45,6 +51,12 @@
 /* VINTF config regs */
 #define NVIDIA_CMDQV_VINTF(v)		(0x1000 + 0x100*(v))
 
+#define NVIDIA_VINTFi_CONFIG(i)		(NVIDIA_CMDQV_VINTF(i) + NVIDIA_VINTF_CONFIG)
+#define NVIDIA_VINTFi_STATUS(i)		(NVIDIA_CMDQV_VINTF(i) + NVIDIA_VINTF_STATUS)
+#define NVIDIA_VINTFi_SID_MATCH(i, s)	(NVIDIA_CMDQV_VINTF(i) + NVIDIA_VINTF_SID_MATCH(s))
+#define NVIDIA_VINTFi_SID_REPLACE(i, s)	(NVIDIA_CMDQV_VINTF(i) + NVIDIA_VINTF_SID_REPLACE(s))
+#define NVIDIA_VINTFi_CMDQ_ERR_MAP(i)	(NVIDIA_CMDQV_VINTF(i) + NVIDIA_VINTF_CMDQ_ERR_MAP)
+
 #define NVIDIA_VINTF_CONFIG		0x0000
 #define  VINTF_HYP_OWN			BIT(17)
 #define  VINTF_VMID			GENMASK(16, 1)
@@ -54,6 +66,11 @@
 #define  VINTF_STATUS			GENMASK(3, 1)
 #define  VINTF_ENABLED			BIT(0)
 
+#define NVIDIA_VINTF_SID_MATCH(s)	(0x0040 + 0x4*(s))
+#define NVIDIA_VINTF_SID_REPLACE(s)	(0x0080 + 0x4*(s))
+
+#define NVIDIA_VINTF_CMDQ_ERR_MAP	0x00C0
+
 /* VCMDQ config regs */
 /* -- PAGE0 -- */
 #define NVIDIA_CMDQV_VCMDQ(q)		(NVIDIA_VCMDQ_BASE + 0x80*(q))
@@ -77,13 +94,30 @@
 #define  VCMDQ_ADDR			GENMASK(63, 5)
 #define  VCMDQ_LOG2SIZE			GENMASK(4, 0)
 
+#define NVIDIA_VCMDQ0_BASE_L		0x00000	/* offset to NVIDIA_VCMDQ_BASE_L(0) */
+#define NVIDIA_VCMDQ0_BASE_H		0x00004	/* offset to NVIDIA_VCMDQ_BASE_L(0) */
+#define NVIDIA_VCMDQ0_CONS_INDX_BASE_L	0x00008	/* offset to NVIDIA_VCMDQ_BASE_L(0) */
+#define NVIDIA_VCMDQ0_CONS_INDX_BASE_H	0x0000C	/* offset to NVIDIA_VCMDQ_BASE_L(0) */
+
+/* VINTF logical-VCMDQ regs */
+#define NVIDIA_VINTFi_VCMDQ_BASE(i)	(NVIDIA_VINTF_VCMDQ_BASE + NVIDIA_VCMDQ_SIZE*(i))
+#define NVIDIA_VINTFi_VCMDQ(i, q)	(NVIDIA_VINTFi_VCMDQ_BASE(i) + 0x80*(q))
+
 struct nvidia_smmu_vintf {
 	u16			idx;
+	u16			vmid;
 	u32			cfg;
 	u32			status;
 
 	void __iomem		*base;
+	void __iomem		*vcmdq_base;
 	struct arm_smmu_cmdq	*vcmdqs;
+
+#define NVIDIA_SMMU_VINTF_MAX_SIDS 16
+	DECLARE_BITMAP(sid_map, NVIDIA_SMMU_VINTF_MAX_SIDS);
+	u32			sid_replace[NVIDIA_SMMU_VINTF_MAX_SIDS];
+
+	spinlock_t		lock;
 };
 
 struct nvidia_smmu {
@@ -91,6 +125,8 @@ struct nvidia_smmu {
 
 	struct device		*cmdqv_dev;
 	void __iomem		*cmdqv_base;
+	resource_size_t		ioaddr;
+	resource_size_t		ioaddr_size;
 	int			cmdqv_irq;
 
 	/* CMDQV Hardware Params */
@@ -98,10 +134,38 @@ struct nvidia_smmu {
 	u16			num_total_vcmdqs;
 	u16			num_vcmdqs_per_vintf;
 
+#define NVIDIA_SMMU_MAX_VINTFS	(1 << 6)
+	DECLARE_BITMAP(vintf_map, NVIDIA_SMMU_MAX_VINTFS);
+
 	/* CMDQV_VINTF(0) reserved for host kernel use */
 	struct nvidia_smmu_vintf vintf0;
+
+	struct nvidia_smmu_vintf **vmid_mappings;
+
+#ifdef CONFIG_VFIO_MDEV_DEVICE
+	/* CMDQV_VINTFs exposed to userspace via mdev */
+	struct nvidia_cmdqv_mdev **vintf_mdev;
+	/* Cache for two 64-bit VCMDQ base addresses */
+	struct nvidia_cmdqv_vcmdq_regcache {
+		u64		base_addr;
+		u64		cons_addr;
+	} *vcmdq_regcache;
+	struct mutex		mdev_lock;
+	struct mutex		vmid_lock;
+#endif
 };
 
+#ifdef CONFIG_VFIO_MDEV_DEVICE
+struct nvidia_cmdqv_mdev {
+	struct nvidia_smmu	*nsmmu;
+	struct mdev_device	*mdev;
+	struct nvidia_smmu_vintf *vintf;
+
+	struct notifier_block	group_notifier;
+	struct kvm		*kvm;
+};
+#endif
+
 static irqreturn_t nvidia_smmu_cmdqv_isr(int irq, void *devid)
 {
 	struct nvidia_smmu *nsmmu = (struct nvidia_smmu *)devid;
@@ -135,6 +199,61 @@ static irqreturn_t nvidia_smmu_cmdqv_isr(int irq, void *devid)
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_VFIO_MDEV_DEVICE
+struct mdev_parent_ops nvidia_smmu_cmdqv_mdev_ops;
+
+int nvidia_smmu_cmdqv_mdev_init(struct nvidia_smmu *nsmmu)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev;
+	int ret;
+
+	/* Skip mdev init unless there are available VINTFs */
+	if (nsmmu->num_total_vintfs <= 1)
+		return 0;
+
+	nsmmu->vintf_mdev = devm_kcalloc(nsmmu->cmdqv_dev, nsmmu->num_total_vintfs,
+					 sizeof(*nsmmu->vintf_mdev), GFP_KERNEL);
+	if (!nsmmu->vintf_mdev)
+		return -ENOMEM;
+
+	nsmmu->vcmdq_regcache = devm_kcalloc(nsmmu->cmdqv_dev, nsmmu->num_total_vcmdqs,
+					     sizeof(*nsmmu->vcmdq_regcache), GFP_KERNEL);
+	if (!nsmmu->vcmdq_regcache)
+		return -ENOMEM;
+
+	nsmmu->vmid_mappings = devm_kcalloc(nsmmu->cmdqv_dev, 1 << nsmmu->smmu.vmid_bits,
+					    sizeof(*nsmmu->vmid_mappings), GFP_KERNEL);
+	if (!nsmmu->vmid_mappings)
+		return -ENOMEM;
+
+	mutex_init(&nsmmu->mdev_lock);
+	mutex_init(&nsmmu->vmid_lock);
+
+	/* Add a dummy mdev instance to represent vintf0 */
+	cmdqv_mdev = devm_kzalloc(nsmmu->cmdqv_dev, sizeof(*cmdqv_mdev), GFP_KERNEL);
+	if (!cmdqv_mdev)
+		return -ENOMEM;
+
+	cmdqv_mdev->nsmmu = nsmmu;
+	nsmmu->vintf_mdev[0] = cmdqv_mdev;
+
+	ret = mdev_register_device(nsmmu->cmdqv_dev, &nvidia_smmu_cmdqv_mdev_ops);
+	if (ret) {
+		dev_err(nsmmu->cmdqv_dev, "failed to register mdev device: %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(to_platform_device(nsmmu->cmdqv_dev), nsmmu);
+
+	return ret;
+}
+#else
+int nvidia_smmu_cmdqv_mdev_init(struct nvidia_smmu *nsmmu)
+{
+	return 0;
+}
+#endif
+
 /* Adapt struct arm_smmu_cmdq init sequences from arm-smmu-v3.c for VCMDQs */
 static int nvidia_smmu_init_one_arm_smmu_cmdq(struct nvidia_smmu *nsmmu,
 					      struct arm_smmu_cmdq *cmdq,
@@ -255,6 +374,16 @@ static int nvidia_smmu_cmdqv_init(struct nvidia_smmu *nsmmu)
 			 qidx, vintf0->idx, qidx);
 	}
 
+	/* Log this vintf0 in vintf_map */
+	set_bit(0, nsmmu->vintf_map);
+
+	spin_lock_init(&vintf0->lock);
+
+#ifdef CONFIG_VFIO_MDEV_DEVICE
+	if (nsmmu->vintf_mdev && nsmmu->vintf_mdev[0])
+		nsmmu->vintf_mdev[0]->vintf = vintf0;
+#endif
+
 	return 0;
 }
 
@@ -269,6 +398,9 @@ static int nvidia_smmu_probe(struct nvidia_smmu *nsmmu)
 	if (!res)
 		return -ENXIO;
 
+	nsmmu->ioaddr = res->start;
+	nsmmu->ioaddr_size = resource_size(res);
+
 	nsmmu->cmdqv_base = devm_ioremap_resource(nsmmu->cmdqv_dev, res);
 	if (IS_ERR(nsmmu->cmdqv_base))
 		return PTR_ERR(nsmmu->cmdqv_base);
@@ -366,9 +498,131 @@ static int nvidia_smmu_device_reset(struct arm_smmu_device *smmu)
 	return 0;
 }
 
+static int nvidia_smmu_bitmap_alloc(unsigned long *map, int size)
+{
+	int idx;
+
+	do {
+		idx = find_first_zero_bit(map, size);
+		if (idx == size)
+			return -ENOSPC;
+	} while (test_and_set_bit(idx, map));
+
+	return idx;
+}
+
+static void nvidia_smmu_bitmap_free(unsigned long *map, int idx)
+{
+	clear_bit(idx, map);
+}
+
+static int nvidia_smmu_attach_dev(struct arm_smmu_domain *smmu_domain, struct device *dev)
+{
+	struct nvidia_smmu *nsmmu = (struct nvidia_smmu *)smmu_domain->smmu;
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct nvidia_smmu_vintf *vintf = &nsmmu->vintf0;
+	int i, slot;
+
+#ifdef CONFIG_VFIO_MDEV_DEVICE
+	/* Repoint vintf to the corresponding one for Nested Translation mode */
+	if (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED) {
+		u16 vmid = smmu_domain->s2_cfg.vmid;
+
+		mutex_lock(&nsmmu->vmid_lock);
+		vintf = nsmmu->vmid_mappings[vmid];
+		mutex_unlock(&nsmmu->vmid_lock);
+		if (!vintf) {
+			dev_err(nsmmu->cmdqv_dev, "failed to find vintf\n");
+			return -EINVAL;
+		}
+	}
+#endif
+
+	for (i = 0; i < fwspec->num_ids; i++) {
+		unsigned int sid = fwspec->ids[i];
+		unsigned long flags;
+
+		/* Find an empty slot of SID_MATCH and SID_REPLACE */
+		slot = nvidia_smmu_bitmap_alloc(vintf->sid_map, NVIDIA_SMMU_VINTF_MAX_SIDS);
+		if (slot < 0)
+			return -EBUSY;
+
+		/* Write PHY_SID to SID_REPLACE and cache it for quick lookup */
+		writel_relaxed(sid, vintf->base + NVIDIA_VINTF_SID_REPLACE(slot));
+
+		spin_lock_irqsave(&vintf->lock, flags);
+		vintf->sid_replace[slot] = sid;
+		spin_unlock_irqrestore(&vintf->lock, flags);
+
+		if (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED) {
+			struct iommu_group *group = iommu_group_get(dev);
+
+			/*
+			 * Mark SID_MATCH with iommu_group_id, without setting ENABLE bit
+			 * This allows hypervisor to look up one SID_MATCH register that
+			 * matches with the same iommu_group_id, and to eventually update
+			 * VIRT_SID in SID_MATCH.
+			 */
+			writel_relaxed(iommu_group_id(group) << 1,
+				       vintf->base + NVIDIA_VINTF_SID_MATCH(slot));
+		}
+	}
+
+	return 0;
+}
+
+static void nvidia_smmu_detach_dev(struct arm_smmu_domain *smmu_domain, struct device *dev)
+{
+	struct nvidia_smmu *nsmmu = (struct nvidia_smmu *)smmu_domain->smmu;
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct nvidia_smmu_vintf *vintf = &nsmmu->vintf0;
+	int i, slot;
+
+#ifdef CONFIG_VFIO_MDEV_DEVICE
+	/* Replace vintf0 with the corresponding one for Nested Translation mode */
+	if (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED) {
+		u16 vmid =  smmu_domain->s2_cfg.vmid;
+
+		mutex_lock(&nsmmu->vmid_lock);
+		vintf = nsmmu->vmid_mappings[vmid];
+		mutex_unlock(&nsmmu->vmid_lock);
+		if (!vintf) {
+			dev_err(nsmmu->cmdqv_dev, "failed to find vintf\n");
+			return;
+		}
+	}
+#endif
+
+	for (i = 0; i < fwspec->num_ids; i++) {
+		unsigned int sid = fwspec->ids[i];
+		unsigned long flags;
+
+		spin_lock_irqsave(&vintf->lock, flags);
+
+		/* Find a SID_REPLACE register matching sid */
+		for (slot = 0; slot < ARRAY_SIZE(vintf->sid_replace); slot++)
+			if (sid == vintf->sid_replace[slot])
+				break;
+
+		spin_unlock_irqrestore(&vintf->lock, flags);
+
+		if (slot == ARRAY_SIZE(vintf->sid_replace)) {
+			dev_dbg(nsmmu->cmdqv_dev, "failed to find vintf\n");
+			return;
+		}
+
+		writel_relaxed(0, vintf->base + NVIDIA_VINTF_SID_REPLACE(slot));
+		writel_relaxed(0, vintf->base + NVIDIA_VINTF_SID_MATCH(slot));
+
+		nvidia_smmu_bitmap_free(vintf->sid_map, slot);
+	}
+}
+
 const struct arm_smmu_impl nvidia_smmu_impl = {
 	.device_reset = nvidia_smmu_device_reset,
 	.get_cmdq = nvidia_smmu_get_cmdq,
+	.attach_dev = nvidia_smmu_attach_dev,
+	.detach_dev = nvidia_smmu_detach_dev,
 };
 
 #ifdef CONFIG_ACPI
@@ -426,7 +680,570 @@ struct arm_smmu_device *nvidia_smmu_v3_impl_init(struct arm_smmu_device *smmu)
 	if (ret)
 		return ERR_PTR(ret);
 
+	ret = nvidia_smmu_cmdqv_mdev_init(nsmmu);
+	if (ret)
+		return ERR_PTR(ret);
+
 	nsmmu->smmu.impl = &nvidia_smmu_impl;
 
 	return &nsmmu->smmu;
 }
+
+#ifdef CONFIG_VFIO_MDEV_DEVICE
+#define mdev_name(m) dev_name(mdev_dev(m))
+
+int nvidia_smmu_cmdqv_mdev_create(struct mdev_device *mdev)
+{
+	struct device *parent_dev = mdev_parent_dev(mdev);
+	struct nvidia_smmu *nsmmu = platform_get_drvdata(to_platform_device(parent_dev));
+	struct nvidia_cmdqv_mdev *cmdqv_mdev;
+	struct nvidia_smmu_vintf *vintf;
+	int vmid, idx, ret;
+	u32 regval;
+
+	cmdqv_mdev = kzalloc(sizeof(*cmdqv_mdev), GFP_KERNEL);
+	if (!cmdqv_mdev)
+		return -ENOMEM;
+
+	cmdqv_mdev->vintf = kzalloc(sizeof(*cmdqv_mdev->vintf), GFP_KERNEL);
+	if (!cmdqv_mdev->vintf) {
+		ret = -ENOMEM;
+		goto free_mdev;
+	}
+
+	cmdqv_mdev->mdev = mdev;
+	cmdqv_mdev->nsmmu = nsmmu;
+	vintf = cmdqv_mdev->vintf;
+
+	mutex_lock(&nsmmu->mdev_lock);
+	idx = nvidia_smmu_bitmap_alloc(nsmmu->vintf_map, nsmmu->num_total_vintfs);
+	if (idx < 0) {
+		dev_err(nsmmu->cmdqv_dev, "failed to allocate vintfs\n");
+		mutex_unlock(&nsmmu->mdev_lock);
+		ret = -EBUSY;
+		goto free_vintf;
+	}
+	nsmmu->vintf_mdev[idx] = cmdqv_mdev;
+	mutex_unlock(&nsmmu->mdev_lock);
+
+	mutex_lock(&nsmmu->vmid_lock);
+	vmid = arm_smmu_vmid_alloc(&nsmmu->smmu);
+	if (vmid < 0) {
+		dev_err(nsmmu->cmdqv_dev, "failed to allocate vmid\n");
+		mutex_unlock(&nsmmu->vmid_lock);
+		ret = -EBUSY;
+		goto free_vintf_map;
+	}
+
+	/* Create mapping between vmid and vintf */
+	nsmmu->vmid_mappings[vmid] = vintf;
+	mutex_unlock(&nsmmu->vmid_lock);
+
+	vintf->idx = idx;
+	vintf->vmid = vmid;
+	vintf->base = nsmmu->cmdqv_base + NVIDIA_CMDQV_VINTF(idx);
+
+	spin_lock_init(&vintf->lock);
+	mdev_set_drvdata(mdev, cmdqv_mdev);
+
+	writel_relaxed(0, vintf->base + NVIDIA_VINTF_CONFIG);
+
+	/* Point to NVIDIA_VINTFi_VCMDQ_BASE */
+	vintf->vcmdq_base = nsmmu->cmdqv_base + NVIDIA_VINTFi_VCMDQ_BASE(vintf->idx);
+
+	/* Alloc VCMDQs (2n, 2n+1, 2n+2, ...) to VINTF(idx) as logical-VCMDQ (0, 1, 2, ...) */
+	for (idx = 0; idx < nsmmu->num_vcmdqs_per_vintf; idx++) {
+		u16 vcmdq_idx = nsmmu->num_vcmdqs_per_vintf * vintf->idx + idx;
+
+		regval = FIELD_PREP(CMDQV_CMDQ_ALLOC_VINTF, vintf->idx);
+		regval |= FIELD_PREP(CMDQV_CMDQ_ALLOC_LVCMDQ, idx);
+		regval |= CMDQV_CMDQ_ALLOCATED;
+		writel_relaxed(regval, nsmmu->cmdqv_base + NVIDIA_CMDQV_CMDQ_ALLOC(vcmdq_idx));
+
+		dev_info(nsmmu->cmdqv_dev, "allocated VCMDQ%u to VINTF%u as logical-VCMDQ%u\n",
+			 vcmdq_idx, vintf->idx, idx);
+	}
+
+	dev_dbg(nsmmu->cmdqv_dev, "allocated VINTF%u to mdev_device (%s) binding to vmid (%d)\n",
+		vintf->idx, dev_name(mdev_dev(mdev)), vintf->vmid);
+
+	return 0;
+
+free_vintf_map:
+	nvidia_smmu_bitmap_free(nsmmu->vintf_map, idx);
+free_vintf:
+	kfree(cmdqv_mdev->vintf);
+free_mdev:
+	kfree(cmdqv_mdev);
+
+	return ret;
+}
+
+int nvidia_smmu_cmdqv_mdev_remove(struct mdev_device *mdev)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev = mdev_get_drvdata(mdev);
+	struct nvidia_smmu_vintf *vintf = cmdqv_mdev->vintf;
+	struct nvidia_smmu *nsmmu = cmdqv_mdev->nsmmu;
+	u16 idx;
+
+	/* Deallocate VCMDQs of the VINTF(idx) */
+	for (idx = 0; idx < nsmmu->num_vcmdqs_per_vintf; idx++) {
+		u16 vcmdq_idx = nsmmu->num_vcmdqs_per_vintf * vintf->idx + idx;
+
+		writel_relaxed(0, nsmmu->cmdqv_base + NVIDIA_CMDQV_CMDQ_ALLOC(vcmdq_idx));
+
+		dev_info(nsmmu->cmdqv_dev, "deallocated VCMDQ%u to VINTF%u\n",
+			 vcmdq_idx, vintf->idx);
+	}
+
+	/* Disable and cleanup VINTF configurations */
+	writel_relaxed(0, vintf->base + NVIDIA_VINTF_CONFIG);
+
+	mutex_lock(&nsmmu->mdev_lock);
+	nvidia_smmu_bitmap_free(nsmmu->vintf_map, vintf->idx);
+	nsmmu->vintf_mdev[vintf->idx] = NULL;
+	mutex_unlock(&nsmmu->mdev_lock);
+
+	mutex_lock(&nsmmu->vmid_lock);
+	arm_smmu_vmid_free(&nsmmu->smmu, vintf->vmid);
+	nsmmu->vmid_mappings[vintf->vmid] = NULL;
+	mutex_unlock(&nsmmu->vmid_lock);
+
+	mdev_set_drvdata(mdev, NULL);
+	kfree(cmdqv_mdev->vintf);
+	kfree(cmdqv_mdev);
+
+	return 0;
+}
+
+static int nvidia_smmu_cmdqv_mdev_group_notifier(struct notifier_block *nb,
+						 unsigned long action, void *data)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev =
+		container_of(nb, struct nvidia_cmdqv_mdev, group_notifier);
+
+	if (action == VFIO_GROUP_NOTIFY_SET_KVM)
+		cmdqv_mdev->kvm = data;
+
+	return NOTIFY_OK;
+}
+
+int nvidia_smmu_cmdqv_mdev_open(struct mdev_device *mdev)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev = mdev_get_drvdata(mdev);
+	unsigned long events = VFIO_GROUP_NOTIFY_SET_KVM;
+	struct device *dev = mdev_dev(mdev);
+	int ret;
+
+	cmdqv_mdev->group_notifier.notifier_call = nvidia_smmu_cmdqv_mdev_group_notifier;
+
+	ret = vfio_register_notifier(dev, VFIO_GROUP_NOTIFY, &events, &cmdqv_mdev->group_notifier);
+	if (ret)
+		dev_err(mdev_dev(mdev), "failed to register group notifier: %d\n", ret);
+
+	return ret;
+}
+
+void nvidia_smmu_cmdqv_mdev_release(struct mdev_device *mdev)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev = mdev_get_drvdata(mdev);
+	struct device *dev = mdev_dev(mdev);
+
+	vfio_unregister_notifier(dev, VFIO_GROUP_NOTIFY, &cmdqv_mdev->group_notifier);
+}
+
+ssize_t nvidia_smmu_cmdqv_mdev_read(struct mdev_device *mdev, char __user *buf,
+				    size_t count, loff_t *ppos)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev = mdev_get_drvdata(mdev);
+	struct nvidia_smmu_vintf *vintf = cmdqv_mdev->vintf;
+	struct nvidia_smmu *nsmmu = cmdqv_mdev->nsmmu;
+	struct device *dev = mdev_dev(mdev);
+	loff_t reg_offset = *ppos, reg;
+	u64 regval = 0;
+	u16 idx, slot;
+
+	/* Only support aligned 32/64-bit accesses */
+	if (!count || (count % 4) || count > 8 || (reg_offset % count))
+		return -EINVAL;
+
+	switch (reg_offset) {
+	case NVIDIA_CMDQV_CONFIG:
+		regval = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_CONFIG);
+		break;
+	case NVIDIA_CMDQV_STATUS:
+		regval = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_STATUS);
+		break;
+	case NVIDIA_CMDQV_PARAM:
+		/*
+		 * Guest shall import only one of the VINTFs using mdev interface,
+		 * so limit the numbers of VINTF and VCMDQs in the PARAM register.
+		 */
+		regval = readl_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_PARAM);
+		regval &= ~(CMDQV_NUM_VINTF_LOG2 | CMDQV_NUM_VCMDQ_LOG2);
+		regval |= FIELD_PREP(CMDQV_NUM_VINTF_LOG2, 0);
+		regval |= FIELD_PREP(CMDQV_NUM_VCMDQ_LOG2, ilog2(nsmmu->num_vcmdqs_per_vintf));
+		break;
+	case NVIDIA_CMDQV_VINTF_ERR_MAP:
+		/* Translate the value to bit 0 as guest can only see vintf0 */
+		regval = readl_relaxed(vintf->base + NVIDIA_VINTF_STATUS);
+		regval = !!FIELD_GET(VINTF_STATUS, regval);
+		break;
+	case NVIDIA_CMDQV_VINTF_INT_MASK:
+		/* Translate the value to bit 0 as guest can only see vintf0 */
+		regval = readq_relaxed(nsmmu->cmdqv_base + NVIDIA_CMDQV_VINTF_INT_MASK);
+		regval = !!(regval & BIT(vintf->idx));
+		break;
+	case NVIDIA_CMDQV_VCMDQ_ERR_MAP:
+		regval = readq_relaxed(vintf->base + NVIDIA_VINTF_CMDQ_ERR_MAP);
+		break;
+	case NVIDIA_CMDQV_CMDQ_ALLOC(0) ... NVIDIA_CMDQV_CMDQ_ALLOC(128):
+		if (idx >= nsmmu->num_vcmdqs_per_vintf) {
+			/* Guest only has limited number of VMCDQs for one VINTF */
+			regval = 0;
+		} else {
+			/* We have allocated VCMDQs, so just report it constantly */
+			idx = (reg_offset - NVIDIA_CMDQV_CMDQ_ALLOC(0)) / 4;
+			regval = FIELD_PREP(CMDQV_CMDQ_ALLOC_LVCMDQ, idx) | CMDQV_CMDQ_ALLOCATED;
+		}
+		break;
+	case NVIDIA_VINTFi_CONFIG(0):
+		regval = readl_relaxed(vintf->base + NVIDIA_VINTF_CONFIG);
+		/* Guest should not see the VMID field */
+		regval &= ~(VINTF_VMID);
+		break;
+	case NVIDIA_VINTFi_STATUS(0):
+		regval = readl_relaxed(vintf->base + NVIDIA_VINTF_STATUS);
+		break;
+	case NVIDIA_VINTFi_SID_MATCH(0, 0) ... NVIDIA_VINTFi_SID_MATCH(0, 15):
+		slot = (reg_offset - NVIDIA_VINTFi_SID_MATCH(0, 0)) / 0x4;
+		regval = readl_relaxed(vintf->base + NVIDIA_VINTF_SID_MATCH(slot));
+		break;
+	case NVIDIA_VINTFi_SID_REPLACE(0, 0) ... NVIDIA_VINTFi_SID_REPLACE(0, 15):
+		/* Guest should not see the PHY_SID but know whether it is set or not */
+		slot = (reg_offset - NVIDIA_VINTFi_SID_REPLACE(0, 0)) / 0x4;
+		regval = !!readl_relaxed(vintf->base + NVIDIA_VINTF_SID_REPLACE(slot));
+		break;
+	case NVIDIA_VINTFi_CMDQ_ERR_MAP(0):
+		regval = readl_relaxed(vintf->base + NVIDIA_VINTF_CMDQ_ERR_MAP);
+		break;
+	case NVIDIA_CMDQV_VCMDQ(0) ... NVIDIA_CMDQV_VCMDQ(128):
+		/* We allow fallback reading of VCMDQ PAGE0 upon a warning */
+		dev_warn(dev, "read access at 0x%llx should go through mmap instead!", reg_offset);
+
+		/* Adjust reg_offset since we're reading base on VINTF logical-VCMDQ space */
+		regval = readl_relaxed(vintf->vcmdq_base + reg_offset - NVIDIA_CMDQV_VCMDQ(0));
+		break;
+	case NVIDIA_VCMDQ_BASE_L(0) ... NVIDIA_VCMDQ_BASE_L(128):
+		/* Decipher idx and reg of VCMDQ */
+		idx = (reg_offset - NVIDIA_VCMDQ_BASE_L(0)) / 0x80;
+		reg = reg_offset - NVIDIA_VCMDQ_BASE_L(idx);
+
+		switch (reg) {
+		case NVIDIA_VCMDQ0_BASE_L:
+			regval = nsmmu->vcmdq_regcache[idx].base_addr;
+			if (count == 4)
+				regval = lower_32_bits(regval);
+			break;
+		case NVIDIA_VCMDQ0_BASE_H:
+			regval = upper_32_bits(nsmmu->vcmdq_regcache[idx].base_addr);
+			break;
+		case NVIDIA_VCMDQ0_CONS_INDX_BASE_L:
+			regval = nsmmu->vcmdq_regcache[idx].cons_addr;
+			if (count == 4)
+				regval = lower_32_bits(regval);
+			break;
+		case NVIDIA_VCMDQ0_CONS_INDX_BASE_H:
+			regval = upper_32_bits(nsmmu->vcmdq_regcache[idx].cons_addr);
+			break;
+		default:
+			dev_err(dev, "unknown base address read access at 0x%llX\n", reg_offset);
+			break;
+		}
+		break;
+	default:
+		dev_err(dev, "unhandled read access at 0x%llX\n", reg_offset);
+		return -EINVAL;
+	}
+
+	if (copy_to_user(buf, &regval, count))
+		return -EFAULT;
+	*ppos += count;
+
+	return count;
+}
+
+static u64 nvidia_smmu_cmdqv_mdev_gpa_to_pa(struct nvidia_cmdqv_mdev *cmdqv_mdev, u64 gpa)
+{
+	u64 gfn, hfn, hva, hpa, pg_offset;
+	struct page *pg;
+	long num_pages;
+
+	gfn = gpa_to_gfn(gpa);
+	pg_offset = gpa ^ gfn_to_gpa(gfn);
+
+	hva = gfn_to_hva(cmdqv_mdev->kvm, gfn);
+	if (kvm_is_error_hva(hva))
+		return 0;
+
+	num_pages = get_user_pages(hva, 1, FOLL_GET | FOLL_WRITE, &pg, NULL);
+	if (num_pages < 1)
+		return 0;
+
+	hfn = page_to_pfn(pg);
+	hpa = pfn_to_hpa(hfn);
+
+	return hpa | pg_offset;
+}
+
+ssize_t nvidia_smmu_cmdqv_mdev_write(struct mdev_device *mdev, const char __user *buf,
+				     size_t count, loff_t *ppos)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev = mdev_get_drvdata(mdev);
+	struct nvidia_smmu_vintf *vintf = cmdqv_mdev->vintf;
+	struct nvidia_smmu *nsmmu = cmdqv_mdev->nsmmu;
+	struct device *dev = mdev_dev(mdev);
+	loff_t reg_offset = *ppos, reg;
+	u64 mask = U32_MAX;
+	u64 regval = 0x0;
+	u16 idx, slot;
+
+	/* Only support aligned 32/64-bit accesses */
+	if (!count || (count % 4) || count > 8 || (reg_offset % count))
+		return -EINVAL;
+
+	/* Get the value to be written to the register at reg_offset */
+	if (copy_from_user(&regval, buf, count))
+		return -EFAULT;
+
+	switch (reg_offset) {
+	case NVIDIA_VINTFi_CONFIG(0):
+		regval &= ~(VINTF_VMID);
+		regval |= FIELD_PREP(VINTF_VMID, vintf->vmid);
+		writel_relaxed(regval, vintf->base + NVIDIA_VINTF_CONFIG);
+		break;
+	case NVIDIA_CMDQV_CMDQ_ALLOC(0) ... NVIDIA_CMDQV_CMDQ_ALLOC(128):
+		/* Ignore since VCMDQs were already allocated to the VINTF */
+		break;
+	case NVIDIA_VINTFi_SID_MATCH(0, 0) ... NVIDIA_VINTFi_SID_MATCH(0, 15):
+		slot = (reg_offset - NVIDIA_VINTFi_SID_MATCH(0, 0)) / 0x4;
+		writel_relaxed(regval, vintf->base + NVIDIA_VINTF_SID_MATCH(slot));
+		break;
+	case NVIDIA_VINTFi_SID_REPLACE(0, 0) ... NVIDIA_VINTFi_SID_REPLACE(0, 15):
+		/* Guest should not alter the value */
+		break;
+	case NVIDIA_CMDQV_VCMDQ(0) ... NVIDIA_CMDQV_VCMDQ(128):
+		/* We allow fallback writing at VCMDQ PAGE0 upon a warning */
+		dev_warn(dev, "write access at 0x%llx should go through mmap instead!", reg_offset);
+
+		/* Adjust reg_offset since we're reading base on VINTF logical-VCMDQ space */
+		writel_relaxed(regval, vintf->vcmdq_base + reg_offset - NVIDIA_CMDQV_VCMDQ(0));
+		break;
+	case NVIDIA_VCMDQ_BASE_L(0) ... NVIDIA_VCMDQ_BASE_L(128):
+		/* Decipher idx and reg of VCMDQ */
+		idx = (reg_offset - NVIDIA_VCMDQ_BASE_L(0)) / 0x80;
+		reg = reg_offset - NVIDIA_VCMDQ_BASE_L(idx);
+
+		switch (reg) {
+		case NVIDIA_VCMDQ0_BASE_L:
+			if (count == 8)
+				mask = U64_MAX;
+			regval &= mask;
+			nsmmu->vcmdq_regcache[idx].base_addr &= ~mask;
+			nsmmu->vcmdq_regcache[idx].base_addr |= regval;
+			regval = nsmmu->vcmdq_regcache[idx].base_addr;
+			break;
+		case NVIDIA_VCMDQ0_BASE_H:
+			nsmmu->vcmdq_regcache[idx].base_addr &= U32_MAX;
+			nsmmu->vcmdq_regcache[idx].base_addr |= regval << 32;
+			regval = nsmmu->vcmdq_regcache[idx].base_addr;
+			break;
+		case NVIDIA_VCMDQ0_CONS_INDX_BASE_L:
+			if (count == 8)
+				mask = U64_MAX;
+			regval &= mask;
+			nsmmu->vcmdq_regcache[idx].cons_addr &= ~mask;
+			nsmmu->vcmdq_regcache[idx].cons_addr |= regval;
+			regval = nsmmu->vcmdq_regcache[idx].cons_addr;
+			break;
+		case NVIDIA_VCMDQ0_CONS_INDX_BASE_H:
+			nsmmu->vcmdq_regcache[idx].cons_addr &= U32_MAX;
+			nsmmu->vcmdq_regcache[idx].cons_addr |= regval << 32;
+			regval = nsmmu->vcmdq_regcache[idx].cons_addr;
+			break;
+		default:
+			dev_err(dev, "unknown base address write access at 0x%llX\n", reg_offset);
+			return -EFAULT;
+		}
+
+		/* Translate guest PA to host PA before writing to the address register */
+		regval = nvidia_smmu_cmdqv_mdev_gpa_to_pa(cmdqv_mdev, regval);
+
+		/* Do not fail mdev write as higher/lower addresses can be written separately */
+		if (!regval)
+			dev_dbg(dev, "failed to convert guest address for VCMDQ%d\n", idx);
+
+		/* Adjust reg_offset since we're accessing it via the VINTF CMDQ aperture */
+		reg_offset -= NVIDIA_CMDQV_VCMDQ(0);
+		if (count == 8)
+			writeq_relaxed(regval, vintf->vcmdq_base + reg_offset);
+		else
+			writel_relaxed(regval, vintf->vcmdq_base + reg_offset);
+		break;
+
+	default:
+		dev_err(dev, "unhandled write access at 0x%llX\n", reg_offset);
+		return -EINVAL;
+	}
+
+	*ppos += count;
+	return count;
+}
+
+long nvidia_smmu_cmdqv_mdev_ioctl(struct mdev_device *mdev, unsigned int cmd, unsigned long arg)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev = mdev_get_drvdata(mdev);
+	struct nvidia_smmu_vintf *vintf = cmdqv_mdev->vintf;
+	struct device *dev = mdev_dev(mdev);
+	struct vfio_device_info device_info;
+	struct vfio_region_info region_info;
+	unsigned long minsz;
+
+	switch (cmd) {
+	case VFIO_DEVICE_GET_INFO:
+		minsz = offsetofend(struct vfio_device_info, num_irqs);
+
+		if (copy_from_user(&device_info, (void __user *)arg, minsz))
+			return -EFAULT;
+
+		if (device_info.argsz < minsz)
+			return -EINVAL;
+
+		device_info.flags = 0;
+		device_info.num_irqs = 0;
+		/* MMIO Regions: [0] - CMDQV_CONFIG, [1] - VCMDQ_PAGE0, [2] - VCMDQ_PAGE1 */
+		device_info.num_regions = 3;
+
+		return copy_to_user((void __user *)arg, &device_info, minsz) ? -EFAULT : 0;
+	case VFIO_DEVICE_GET_REGION_INFO:
+		minsz = offsetofend(struct vfio_region_info, offset);
+
+		if (copy_from_user(&region_info, (void __user *)arg, minsz))
+			return -EFAULT;
+
+		if (region_info.argsz < minsz)
+			return -EINVAL;
+
+		if (region_info.index >= 3)
+			return -EINVAL;
+
+		/* MMIO Regions: [0] - CMDQV_CONFIG, [1] - VCMDQ_PAGE0, [2] - VCMDQ_PAGE1 */
+		region_info.size = SZ_64K;
+		region_info.offset = region_info.index * SZ_64K;
+		region_info.flags = VFIO_REGION_INFO_FLAG_READ | VFIO_REGION_INFO_FLAG_WRITE;
+		/* In case of VCMDQ_PAGE0, add FLAG_MMAP */
+		if (region_info.index == 1)
+			region_info.flags |= VFIO_REGION_INFO_FLAG_MMAP;
+
+		return copy_to_user((void __user *)arg, &region_info, minsz) ? -EFAULT : 0;
+	case VFIO_IOMMU_GET_VMID:
+		return copy_to_user((void __user *)arg, &vintf->vmid, sizeof(u16)) ? -EFAULT : 0;
+	default:
+		dev_err(dev, "unhandled ioctl cmd 0x%X\n", cmd);
+		return -ENOTTY;
+	}
+
+	return 0;
+}
+
+int nvidia_smmu_cmdqv_mdev_mmap(struct mdev_device *mdev, struct vm_area_struct *vma)
+{
+	struct nvidia_cmdqv_mdev *cmdqv_mdev = mdev_get_drvdata(mdev);
+	struct nvidia_smmu_vintf *vintf = cmdqv_mdev->vintf;
+	struct nvidia_smmu *nsmmu = cmdqv_mdev->nsmmu;
+	struct device *dev = mdev_dev(mdev);
+	unsigned int region_idx;
+	unsigned long size;
+
+	/* Make sure that only VCMDQ_PAGE0 MMIO region can be mmapped */
+	region_idx = (vma->vm_pgoff << PAGE_SHIFT) / SZ_64K;
+	if (region_idx != 0x1) {
+		dev_err(dev, "mmap unsupported for region_idx %d", region_idx);
+		return -EINVAL;
+	}
+
+	size = vma->vm_end - vma->vm_start;
+	if (size > SZ_64K)
+		return -EINVAL;
+
+	/* Fixup the VMA */
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	/* Map PAGE0 of VINTF[idx] */
+	vma->vm_pgoff = nsmmu->ioaddr + NVIDIA_VINTFi_VCMDQ_BASE(vintf->idx);
+	vma->vm_pgoff >>= PAGE_SHIFT;
+
+	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size, vma->vm_page_prot);
+}
+
+static ssize_t name_show(struct mdev_type *mtype,
+			 struct mdev_type_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s\n", "NVIDIA_SMMU_CMDQV_VINTF - (2 VCMDQs/VINTF)");
+}
+static MDEV_TYPE_ATTR_RO(name);
+
+static ssize_t available_instances_show(struct mdev_type *mtype,
+					struct mdev_type_attribute *attr, char *buf)
+{
+	struct device *parent_dev = mtype_get_parent_dev(mtype);
+	struct nvidia_smmu *nsmmu = platform_get_drvdata(to_platform_device(parent_dev));
+	u16 idx, cnt = 0;
+
+	mutex_lock(&nsmmu->mdev_lock);
+	for (idx = 0; idx < nsmmu->num_total_vintfs; idx++)
+		cnt += !nsmmu->vintf_mdev[idx];
+	mutex_unlock(&nsmmu->mdev_lock);
+
+	return sprintf(buf, "%d\n", cnt);
+}
+static MDEV_TYPE_ATTR_RO(available_instances);
+
+static ssize_t device_api_show(struct mdev_type *mtype,
+			       struct mdev_type_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s\n", VFIO_DEVICE_API_PLATFORM_STRING);
+}
+static MDEV_TYPE_ATTR_RO(device_api);
+
+static struct attribute *mdev_types_attrs[] = {
+	&mdev_type_attr_name.attr,
+	&mdev_type_attr_device_api.attr,
+	&mdev_type_attr_available_instances.attr,
+	NULL,
+};
+
+static struct attribute_group mdev_type_group1 = {
+	.name  = "nvidia_cmdqv_vintf",
+	.attrs = mdev_types_attrs,
+};
+
+static struct attribute_group *mdev_type_groups[] = {
+	&mdev_type_group1,
+	NULL,
+};
+
+struct mdev_parent_ops nvidia_smmu_cmdqv_mdev_ops = {
+	.owner = THIS_MODULE,
+	.supported_type_groups = mdev_type_groups,
+	.create = nvidia_smmu_cmdqv_mdev_create,
+	.remove = nvidia_smmu_cmdqv_mdev_remove,
+	.open = nvidia_smmu_cmdqv_mdev_open,
+	.release = nvidia_smmu_cmdqv_mdev_release,
+	.read = nvidia_smmu_cmdqv_mdev_read,
+	.write = nvidia_smmu_cmdqv_mdev_write,
+	.ioctl = nvidia_smmu_cmdqv_mdev_ioctl,
+	.mmap = nvidia_smmu_cmdqv_mdev_mmap,
+};
+
+#endif /* CONFIG_VFIO_MDEV_DEVICE */
-- 
2.17.1



From viresh.kumar at linaro.org  Mon Aug 30 20:19:44 2021
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 31 Aug 2021 08:49:44 +0530
Subject: [PATCH v14 3/3] cpufreq: mediatek-hw: Add support for CPUFREQ HW
In-Reply-To: <1630162872-25452-4-git-send-email-hector.yuan@mediatek.com>
References: <1630162872-25452-1-git-send-email-hector.yuan@mediatek.com>
 <1630162872-25452-4-git-send-email-hector.yuan@mediatek.com>
Message-ID: <20210831031944.emtd2hlpzjs3cxnl@vireshk-i7>

On 28-08-21, 23:01, Hector Yuan wrote:
> diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
> new file mode 100644
> index 0000000..79862a5
> --- /dev/null
> +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
> @@ -0,0 +1,319 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 MediaTek Inc.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/cpufreq.h>
> +#include <linux/energy_model.h>
> +#include <linux/init.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/pm_qos.h>

You still need this ? Please check all the headers and keep only the ones that
are required.

> +#include <linux/slab.h>
> +
> +#define LUT_MAX_ENTRIES			32U
> +#define LUT_FREQ			GENMASK(11, 0)
> +#define LUT_ROW_SIZE			0x4
> +#define CPUFREQ_HW_STATUS		BIT(0)
> +#define SVS_HW_STATUS			BIT(1)
> +#define POLL_USEC			1000
> +#define TIMEOUT_USEC			300000
> +
> +enum {
> +	REG_FREQ_LUT_TABLE,
> +	REG_FREQ_ENABLE,
> +	REG_FREQ_PERF_STATE,
> +	REG_FREQ_HW_STATE,
> +	REG_EM_POWER_TBL,
> +	REG_FREQ_LATENCY,
> +
> +	REG_ARRAY_SIZE,
> +};
> +
> +struct mtk_cpufreq_data {
> +	struct cpufreq_frequency_table *table;
> +	void __iomem *reg_bases[REG_ARRAY_SIZE];
> +	int nr_opp;
> +};
> +
> +static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = {
> +	[REG_FREQ_LUT_TABLE]	= 0x0,
> +	[REG_FREQ_ENABLE]	= 0x84,
> +	[REG_FREQ_PERF_STATE]	= 0x88,
> +	[REG_FREQ_HW_STATE]	= 0x8c,
> +	[REG_EM_POWER_TBL]	= 0x90,
> +	[REG_FREQ_LATENCY]	= 0x110,
> +};
> +
> +static int __maybe_unused
> +mtk_cpufreq_get_cpu_power(unsigned long *mW,
> +			  unsigned long *KHz, struct device *cpu_dev)
> +{
> +	struct mtk_cpufreq_data *data;
> +	struct cpufreq_policy *policy;
> +	int i;
> +
> +	policy = cpufreq_cpu_get_raw(cpu_dev->id);
> +	if (!policy)
> +		return 0;
> +
> +	data = policy->driver_data;
> +
> +	for (i = 0; i < data->nr_opp; i++) {
> +		if (data->table[i].frequency < *KHz)
> +			break;
> +	}
> +	i--;
> +
> +	*KHz = data->table[i].frequency;
> +	*mW = readl_relaxed(data->reg_bases[REG_EM_POWER_TBL] +
> +			    i * LUT_ROW_SIZE) / 1000;
> +
> +	return 0;
> +}
> +
> +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy,
> +				       unsigned int index)
> +{
> +	struct mtk_cpufreq_data *data = policy->driver_data;
> +
> +	writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);
> +
> +	return 0;
> +}
> +
> +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu)
> +{
> +	struct mtk_cpufreq_data *data;
> +	struct cpufreq_policy *policy;
> +	unsigned int index;
> +
> +	policy = cpufreq_cpu_get_raw(cpu);
> +	if (!policy)
> +		return 0;
> +
> +	data = policy->driver_data;
> +
> +	index = readl_relaxed(data->reg_bases[REG_FREQ_PERF_STATE]);
> +	index = min(index, LUT_MAX_ENTRIES - 1);
> +
> +	return data->table[index].frequency;
> +}
> +
> +static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
> +					       unsigned int target_freq)
> +{
> +	struct mtk_cpufreq_data *data = policy->driver_data;
> +	unsigned int index;
> +
> +	index = cpufreq_table_find_index_dl(policy, target_freq);
> +
> +	writel_relaxed(index, data->reg_bases[REG_FREQ_PERF_STATE]);
> +
> +	return policy->freq_table[index].frequency;
> +}
> +
> +static int mtk_cpu_create_freq_table(struct platform_device *pdev,
> +				     struct mtk_cpufreq_data *data)
> +{
> +	struct device *dev = &pdev->dev;
> +	void __iomem *base_table;
> +	u32 temp, i, freq, prev_freq = 0;
> +
> +	data->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1,
> +				   sizeof(*data->table), GFP_KERNEL);
> +	if (!data->table)
> +		return -ENOMEM;
> +
> +	base_table = data->reg_bases[REG_FREQ_LUT_TABLE];
> +
> +	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
> +		temp = readl_relaxed(base_table + (i * LUT_ROW_SIZE));
> +		freq = FIELD_GET(LUT_FREQ, temp) * 1000;
> +
> +		if (freq == prev_freq)
> +			break;
> +
> +		data->table[i].frequency = freq;
> +
> +		dev_dbg(dev, "index=%d freq=%d\n", i, data->table[i].frequency);
> +
> +		prev_freq = freq;
> +	}
> +
> +	data->table[i].frequency = CPUFREQ_TABLE_END;
> +	data->nr_opp = i;
> +
> +	return 0;
> +}
> +
> +static int mtk_cpu_resources_init(struct platform_device *pdev,
> +				  struct cpufreq_policy *policy,
> +				  const u16 *offsets)
> +{
> +	struct mtk_cpufreq_data *data;
> +	struct device *dev = &pdev->dev;
> +	void __iomem *base;
> +	int ret, i;
> +	int index;
> +
> +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> +	if (!data)
> +		return -ENOMEM;
> +
> +	index = of_perf_domain_get_sharing_cpumask(policy->cpu, "performance-domains",
> +						   "#performance-domain-cells",
> +						   policy->cpus);

No need to check failure here ?

> +
> +	base = devm_platform_ioremap_resource(pdev, index);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++)
> +		data->reg_bases[i] = base + offsets[i];
> +
> +	ret = mtk_cpu_create_freq_table(pdev, data);
> +	if (ret) {
> +		dev_info(dev, "Domain-%d failed to create freq table\n", index);
> +		return ret;
> +	}
> +
> +	policy->freq_table = data->table;
> +	policy->driver_data = data;
> +
> +	return 0;
> +}
> +
> +static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
> +{
> +	struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power);
> +	struct platform_device *pdev = cpufreq_get_driver_data();
> +	int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS;
> +	struct mtk_cpufreq_data *data;
> +	struct device *cpu_dev;
> +	unsigned int latency;
> +	const u16 *offsets;
> +	int ret;
> +
> +	offsets = of_device_get_match_data(&pdev->dev);
> +	if (!offsets)
> +		return -EINVAL;

Do this in probe just once instead of for each policy ?

> +
> +	/* Get the bases of cpufreq for domains */
> +	ret = mtk_cpu_resources_init(pdev, policy, offsets);
> +	if (ret) {
> +		dev_info(&pdev->dev, "CPUFreq resource init failed\n");
> +		return ret;
> +	}
> +
> +	data = policy->driver_data;
> +
> +	latency = readl_relaxed(data->reg_bases[REG_FREQ_LATENCY]) * 1000;
> +	if (!latency)
> +		latency = CPUFREQ_ETERNAL;
> +
> +	/* us convert to ns */
> +	policy->cpuinfo.transition_latency = latency;
> +
> +	policy->fast_switch_possible = true;
> +
> +	/* HW should be in enabled state to proceed now */
> +	writel_relaxed(0x1, data->reg_bases[REG_FREQ_ENABLE]);
> +	if (readl_poll_timeout(data->reg_bases[REG_FREQ_HW_STATE], sig,
> +			       (sig & pwr_hw) == pwr_hw, POLL_USEC,
> +			       TIMEOUT_USEC)) {
> +		if (!(sig & CPUFREQ_HW_STATUS)) {
> +			pr_info("cpufreq hardware of CPU%d is not enabled\n",
> +				policy->cpu);
> +			return -ENODEV;
> +		}
> +
> +		pr_info("SVS of CPU%d is not enabled\n", policy->cpu);
> +	}
> +
> +	cpu_dev = get_cpu_device(policy->cpu);
> +	if (!cpu_dev) {
> +		pr_info("failed to get cpu%d device\n", policy->cpu);
> +		return -ENODEV;
> +	}
> +
> +	em_dev_register_perf_domain(cpu_dev, data->nr_opp, &em_cb, policy->cpus,
> +				    true);

This needs to change based on the stuff present in my cpufreq/arm/linux-next [1]
branch. Here is the modification for a similar driver.

https://lore.kernel.org/linux-pm/8158488baa1ea1aebd09c8d256db7420051d05ac.1628742634.git.viresh.kumar at linaro.org/

> +
> +	return 0;
> +}
> +
> +static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
> +{
> +	struct mtk_cpufreq_data *data = policy->driver_data;
> +	void __iomem *base;
> +	int i;
> +
> +	/* HW should be in paused state now */
> +	writel_relaxed(0x0, data->reg_bases[REG_FREQ_ENABLE]);
> +
> +	for (i = 0; i < REG_ARRAY_SIZE; i++) {
> +		base = data->reg_bases[i];
> +		iounmap(base);
> +	}
> +
> +	kfree(data->table);
> +	kfree(data);

base, data and table are all allocated using devm_* variants. AFAIK, it is
wrong to free them this way as the devm core will try to do the same again
later. Try building your driver as module and insert remove it to see warnings.

Why do you need to free stuff here anyway if it is devm already ?

> +
> +	return 0;
> +}
> +
> +static struct cpufreq_driver cpufreq_mtk_hw_driver = {
> +	.flags		= CPUFREQ_NEED_INITIAL_FREQ_CHECK |
> +			  CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
> +			  CPUFREQ_IS_COOLING_DEV,
> +	.verify		= cpufreq_generic_frequency_table_verify,
> +	.target_index	= mtk_cpufreq_hw_target_index,
> +	.get		= mtk_cpufreq_hw_get,
> +	.init		= mtk_cpufreq_hw_cpu_init,
> +	.exit		= mtk_cpufreq_hw_cpu_exit,
> +	.fast_switch	= mtk_cpufreq_hw_fast_switch,
> +	.name		= "mtk-cpufreq-hw",
> +	.attr		= cpufreq_generic_attr,
> +};
> +
> +static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +
> +	cpufreq_mtk_hw_driver.driver_data = pdev;
> +
> +	ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver);
> +	if (ret)
> +		dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");
> +
> +	return ret;
> +}
> +
> +static int mtk_cpufreq_hw_driver_remove(struct platform_device *pdev)
> +{
> +	return cpufreq_unregister_driver(&cpufreq_mtk_hw_driver);
> +}
> +
> +static const struct of_device_id mtk_cpufreq_hw_match[] = {
> +	{ .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_offsets },
> +	{}
> +};
> +
> +static struct platform_driver mtk_cpufreq_hw_driver = {
> +	.probe = mtk_cpufreq_hw_driver_probe,
> +	.remove = mtk_cpufreq_hw_driver_remove,
> +	.driver = {
> +		.name = "mtk-cpufreq-hw",
> +		.of_match_table = mtk_cpufreq_hw_match,
> +	},
> +};
> +module_platform_driver(mtk_cpufreq_hw_driver);
> +
> +MODULE_AUTHOR("Hector Yuan <hector.yuan at mediatek.com>");
> +MODULE_DESCRIPTION("Mediatek cpufreq-hw driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.7.9.5

-- 
viresh

[1] git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git


From chuanjia.liu at mediatek.com  Mon Aug 30 20:31:24 2021
From: chuanjia.liu at mediatek.com (Chuanjia Liu)
Date: Tue, 31 Aug 2021 11:31:24 +0800
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared
 pcie-cfg base address
In-Reply-To: <20210830214317.GA27606@bjorn-Precision-5520>
References: <20210830214317.GA27606@bjorn-Precision-5520>
Message-ID: <ccf767340afe13a6d273ad8fbc29c6bc966d6314.camel@mediatek.com>

On Mon, 2021-08-30 at 16:43 -0500, Bjorn Helgaas wrote:
> On Mon, Aug 30, 2021 at 03:09:44PM +0800, Chuanjia Liu wrote:
> > On Fri, 2021-08-27 at 11:46 -0500, Bjorn Helgaas wrote:
> > > On Mon, Aug 23, 2021 at 11:27:56AM +0800, Chuanjia Liu wrote:
> > > > @@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct
> > > > mtk_pcie *pcie)
> > > >  			return PTR_ERR(pcie->base);
> > > >  	}
> > > >  
> > > > +	cfg_node = of_find_compatible_node(NULL, NULL,
> > > > +					   "mediatek,generic-
> > > > pciecfg");
> > > > +	if (cfg_node) {
> > > > +		pcie->cfg = syscon_node_to_regmap(cfg_node);
> > > 
> > > Other drivers in drivers/pci/controller/ use
> > > syscon_regmap_lookup_by_phandle() (j721e, dra7xx, keystone,
> > > layerscape, artpec6) or syscon_regmap_lookup_by_compatible()
> > > (imx6,
> > > kirin, v3-semi).
> > > 
> > > You should do it the same way unless there's a need to be
> > > different.
> > 
> > I have used phandle, but Rob suggested to search for the node by 
> > compatible.
> > The reason why syscon_regmap_lookup_by_compatible() is not 
> > used here is that the pciecfg node is optional, and there is no
> > need to
> > return error when the node is not searched.
> 
> How about this?
> 
>   regmap = syscon_regmap_lookup_by_compatible("mediatek,generic-
> pciecfg");
>   if (!IS_ERR(regmap))
>     pcie->cfg = regmap;

Hi Bjorn,

We need to deal with three situations
1) No error
2) The error of the node not found, don't do anything 
3) Other errors, return errors

I guess you mean

regmap = syscon_regmap_lookup_by_compatible("mediatek,generic-
pciecfg");
  if (!IS_ERR(regmap))
      pcie->cfg = regmap;
  else if (IS_ERR(regmap) && PTR_ERR(regmap) != -ENODEV)
      return PTR_ERR(regmap);

I'm not sure if we need this, it seems a little weird and there are
many drivers in other subsystems that use syscon_node_to_regmap().

Thanks
Chuanjia

From anshuman.khandual at arm.com  Mon Aug 30 20:45:30 2021
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 31 Aug 2021 09:15:30 +0530
Subject: [PATCH V2] arm64/mm: Drop <asm/page-def.h>
In-Reply-To: <20210820183520.GC23080@arm.com>
References: <1629457516-32306-1-git-send-email-anshuman.khandual@arm.com>
 <20210820183520.GC23080@arm.com>
Message-ID: <84b647b6-9cee-5aad-78f8-7bc253300534@arm.com>



On 8/21/21 12:05 AM, Catalin Marinas wrote:
> On Fri, Aug 20, 2021 at 04:35:16PM +0530, Anshuman Khandual wrote:
>> PAGE_SHIFT (PAGE_SIZE and PAGE_MASK) which is derived from ARM64_PAGE_SHIFT
>> should be moved into <asm/page.h> instead like in case for other platforms,
>> and then subsequently <asm/page-def.h> can be just dropped off completely.
> 
> These were moved to page-def.h as part of commit b6531456ba27 ("arm64:
> factor out PAGE_* and CONT_* definitions") to avoid some circular header
> dependencies.
> 
>> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>> index 824a3655dd93..649d26396f9e 100644
>> --- a/arch/arm64/include/asm/memory.h
>> +++ b/arch/arm64/include/asm/memory.h
>> @@ -12,7 +12,7 @@
>>  
>>  #include <linux/const.h>
>>  #include <linux/sizes.h>
>> -#include <asm/page-def.h>
>> +#include <asm/page.h>
> 
> In 5.14-rc3, asm/page.h still includes asm/memory.h.

Dropping <asm/memory.h> from <asm/page.h> does not seem to cause
any problem, will change that. Afterwards build tested it across
page sizes and also with some random configs. Is that circular
dependency still present ? Also wondering why was <asm/memory.h>
included in <asm/page.h> to begin with ?


From guangming.cao at mediatek.com  Mon Aug 30 20:44:05 2021
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Tue, 31 Aug 2021 11:44:05 +0800
Subject: [PATCH] dma-buf: heaps: remove duplicated cache sync
In-Reply-To: <dd5ba603-8c9d-f6a0-cbcc-dfb353fb6701@amd.com>
References: <dd5ba603-8c9d-f6a0-cbcc-dfb353fb6701@amd.com>
Message-ID: <20210831034405.41916-1-guangming.cao@mediatek.com>

From: Guangming Cao <Guangming.Cao at mediatek.com>

> Am 30.08.21 um 12:01 schrieb guangming.cao at mediatek.com:
> > From: Guangming Cao <Guangming.Cao at mediatek.com>
> >
> > Current flow, one dmabuf maybe call cache sync many times if
> > it has beed mapped more than one time.
>
> Well I'm not an expert on DMA heaps, but this will most likely not work 
> correctly.
>
All attachments of one dmabuf will add into a list, I think it means dmabuf
supports map more than one time. Could you tell me more about it?

> > Is there any case that attachments of one dmabuf will points to
> > different memory? If not, seems do sync only one time is more better.
>
> I think that this can happen, yes.
>
> Christian.
>
Seems it's a very special case on Android, if you don't mind, could you
tell me more about it?

>
> >
> > Signed-off-by: Guangming Cao <Guangming.Cao at mediatek.com>
> > ---
> >   drivers/dma-buf/heaps/system_heap.c | 14 ++++++++------
> >   1 file changed, 8 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
> > index 23a7e74ef966..909ef652a8c8 100644
> > --- a/drivers/dma-buf/heaps/system_heap.c
> > +++ b/drivers/dma-buf/heaps/system_heap.c
> > @@ -162,9 +162,10 @@ static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
> >   		invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
> >   
> >   	list_for_each_entry(a, &buffer->attachments, list) {
> > -		if (!a->mapped)
> > -			continue;
> > -		dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
> > +		if (a->mapped) {
> > +			dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
> > +			break;
> > +		}
> >   	}
> >   	mutex_unlock(&buffer->lock);
> >   
> > @@ -183,9 +184,10 @@ static int system_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
> >   		flush_kernel_vmap_range(buffer->vaddr, buffer->len);
> >   
> >   	list_for_each_entry(a, &buffer->attachments, list) {
> > -		if (!a->mapped)
> > -			continue;
> > -		dma_sync_sgtable_for_device(a->dev, a->table, direction);
> > +		if (!a->mapped) {
> > +			dma_sync_sgtable_for_device(a->dev, a->table, direction);
> > +			break;
> > +		}
> >   	}
> >   	mutex_unlock(&buffer->lock);
> >   

From jon at solid-run.com  Mon Aug 30 22:06:58 2021
From: jon at solid-run.com (Jon Nettleton)
Date: Tue, 31 Aug 2021 07:06:58 +0200
Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
In-Reply-To: <CAMj1kXHTdDWz14B5Smzfmj5NQqCTTsgFjam6EevvOwFKLsmJzw@mail.gmail.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <CAMj1kXHNjeDb2HuPeV_6Er4oALVKFz+g=gQ_0rf+JW22NxqqTA@mail.gmail.com>
 <8df7fc81b00142b68126efd3c700a579@huawei.com>
 <CAMj1kXHTdDWz14B5Smzfmj5NQqCTTsgFjam6EevvOwFKLsmJzw@mail.gmail.com>
Message-ID: <CABdtJHuYgw7cX2=uKMmaiC8UmVo7czk9oVrsc=hyZ4fFGoEskA@mail.gmail.com>

On Thu, Aug 5, 2021 at 4:09 PM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Thu, 5 Aug 2021 at 15:35, Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi at huawei.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Ard Biesheuvel [mailto:ardb at kernel.org]
> > > Sent: 05 August 2021 14:23
> > > To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> > > Cc: Linux ARM <linux-arm-kernel at lists.infradead.org>; ACPI Devel Maling List
> > > <linux-acpi at vger.kernel.org>; Linux IOMMU
> > > <iommu at lists.linux-foundation.org>; Linuxarm <linuxarm at huawei.com>;
> > > Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>; Joerg Roedel
> > > <joro at 8bytes.org>; Robin Murphy <robin.murphy at arm.com>; Will Deacon
> > > <will at kernel.org>; wanghuiqiang <wanghuiqiang at huawei.com>; Guohanjun
> > > (Hanjun Guo) <guohanjun at huawei.com>; Steven Price
> > > <steven.price at arm.com>; Sami Mujawar <Sami.Mujawar at arm.com>; Jon
> > > Nettleton <jon at solid-run.com>; Eric Auger <eric.auger at redhat.com>;
> > > yangyicong <yangyicong at huawei.com>
> > > Subject: Re: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
> > >
> > > On Thu, 5 Aug 2021 at 10:10, Shameer Kolothum
> > > <shameerali.kolothum.thodi at huawei.com> wrote:
> > > >
> > > > Hi,
> > > >
> > > > The series adds support to IORT RMR nodes specified in IORT
> > > > Revision E.b -ARM DEN 0049E[0]. RMR nodes are used to describe
> > > > memory ranges that are used by endpoints and require a unity
> > > > mapping in SMMU.
> > > >
> > > > We have faced issues with 3408iMR RAID controller cards which
> > > > fail to boot when SMMU is enabled. This is because these
> > > > controllers make use of host memory for various caching related
> > > > purposes and when SMMU is enabled the iMR firmware fails to
> > > > access these memory regions as there is no mapping for them.
> > > > IORT RMR provides a way for UEFI to describe and report these
> > > > memory regions so that the kernel can make a unity mapping for
> > > > these in SMMU.
> > > >
> > >
> > > Does this mean we are ignoring the RMR memory ranges, and exposing the
> > > entire physical address space to devices using the stream IDs in
> > > question?
> >
> > Nope. RMR node is used to describe the memory ranges used by end points
> > behind SMMU. And this information is used to create 1 : 1 mappings for those
> > ranges in SMMU. Anything outside those ranges will result in translation
> > fault(if there are no other dynamic DMA mappings).
> >
>
> Excellent! It was not obvious to me from looking at the patches, so I
> had to ask.
>
> Thanks,
> Ard.
>
> >
> > >
> > > > Change History:
> > > >
> > > > v6 --> v7
> > > >
> > > > The only change from v6 is the fix pointed out by Steve to
> > > > the SMMUv2 SMR bypass install in patch #8.
> > > >
> > > > Thanks to the Tested-by tags by Laurentiu with SMMUv2 and
> > > > Hanjun/Huiqiang with SMMUv3 for v6. I haven't added the tags
> > > > yet as the series still needs more review[1].
> > > >
> > > > Feedback and tests on this series is very much appreciated.
> > > >
> > > > v5 --> v6
> > > > - Addressed comments from Robin & Lorenzo.
> > > >   : Moved iort_parse_rmr() to acpi_iort_init() from
> > > >     iort_init_platform_devices().
> > > >   : Removed use of struct iort_rmr_entry during the initial
> > > >     parse. Using struct iommu_resv_region instead.
> > > >   : Report RMR address alignment and overlap errors, but continue.
> > > >   : Reworked arm_smmu_init_bypass_stes() (patch # 6).
> > > > - Updated SMMUv2 bypass SMR code. Thanks to Jon N (patch #8).
> > > > - Set IOMMU protection flags(IOMMU_CACHE, IOMMU_MMIO) based
> > > >   on Type of RMR region. Suggested by Jon N.
> > > >
> > > > Thanks,
> > > > Shameer
> > > > [0] https://developer.arm.com/documentation/den0049/latest/
> > > > [1]
> > > https://lore.kernel.org/linux-acpi/20210716083442.1708-1-shameerali.koloth
> > > um.thodi at huawei.com/T/#m043c95b869973a834b2fd57f3e1ed0325c84f3b7
> > > > ------
> > > > v4 --> v5
> > > >  -Added a fw_data union to struct iommu_resv_region and removed
> > > >   struct iommu_rmr (Based on comments from Joerg/Robin).
> > > >  -Added iommu_put_rmrs() to release mem.
> > > >  -Thanks to Steve for verifying on SMMUv2, but not added the Tested-by
> > > >   yet because of the above changes.
> > > >
> > > > v3 -->v4
> > > > -Included the SMMUv2 SMR bypass install changes suggested by
> > > >  Steve(patch #7)
> > > > -As per Robin's comments, RMR reserve implementation is now
> > > >  more generic  (patch #8) and dropped v3 patches 8 and 10.
> > > > -Rebase to 5.13-rc1
> > > >
> > > > RFC v2 --> v3
> > > >  -Dropped RFC tag as the ACPICA header changes are now ready to be
> > > >   part of 5.13[0]. But this series still has a dependency on that patch.
> > > >  -Added IORT E.b related changes(node flags, _DSM function 5 checks for
> > > >   PCIe).
> > > >  -Changed RMR to stream id mapping from M:N to M:1 as per the spec and
> > > >   discussion here[1].
> > > >  -Last two patches add support for SMMUv2(Thanks to Jon Nettleton!)
> > > > ------
> > > >
> > > > Jon Nettleton (1):
> > > >   iommu/arm-smmu: Get associated RMR info and install bypass SMR
> > > >
> > > > Shameer Kolothum (8):
> > > >   iommu: Introduce a union to struct iommu_resv_region
> > > >   ACPI/IORT: Add support for RMR node parsing
> > > >   iommu/dma: Introduce generic helper to retrieve RMR info
> > > >   ACPI/IORT: Add a helper to retrieve RMR memory regions
> > > >   iommu/arm-smmu-v3: Introduce strtab init helper
> > > >   iommu/arm-smmu-v3: Refactor arm_smmu_init_bypass_stes() to force
> > > >     bypass
> > > >   iommu/arm-smmu-v3: Get associated RMR info and install bypass STE
> > > >   iommu/dma: Reserve any RMR regions associated with a dev
> > > >
> > > >  drivers/acpi/arm64/iort.c                   | 172
> > > +++++++++++++++++++-
> > > >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  76 +++++++--
> > > >  drivers/iommu/arm/arm-smmu/arm-smmu.c       |  48 ++++++
> > > >  drivers/iommu/dma-iommu.c                   |  89 +++++++++-
> > > >  include/linux/acpi_iort.h                   |   7 +
> > > >  include/linux/dma-iommu.h                   |  13 ++
> > > >  include/linux/iommu.h                       |  11 ++
> > > >  7 files changed, 393 insertions(+), 23 deletions(-)
> > > >
> > > > --
> > > > 2.17.1
> > > >
> > > >
> > > > _______________________________________________
> > > > linux-arm-kernel mailing list
> > > > linux-arm-kernel at lists.infradead.org
> > > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Ping,  Can we get some movement on this patchset?  The standard was
was ratified over a year ago, and there is real world hardware that is
using or needs this functionality.

Thanks,
-Jon


From cristian.marussi at arm.com  Mon Aug 30 22:48:35 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 31 Aug 2021 06:48:35 +0100
Subject: [PATCH v3] firmware: arm_scmi: Free mailbox channels if probe
 fails
In-Reply-To: <51782599a01a6a22409d01e5fc1f8a50@codeaurora.org>
References: <1628111999-21595-1-git-send-email-rishabhb@codeaurora.org>
 <20210805105427.GU6592@e120937-lin>
 <51782599a01a6a22409d01e5fc1f8a50@codeaurora.org>
Message-ID: <20210831054835.GJ13160@e120937-lin>

On Mon, Aug 30, 2021 at 02:09:37PM -0700, rishabhb at codeaurora.org wrote:
> Hi Christian

Hi Rishabh,

thanks for looking into this kind of bad interactions.

> There seems to be another issue here. The response from agent can be delayed
> causing a timeout during base protocol acquire,
> which leads to the probe failure. What I have observed is sometimes the
> failure of probe and rx_callback (due to a delayed message)
> happens at the same time on different cpus.
> Because of this race, the device memory may be cleared while the
> interrupt(rx_callback) is executing on another cpu.

You are right that concurrency was not handled properly in this kind of
context and moreover, if you think about it, even the case of out of
order reception of responses and delayed_responses (type2 SCMI messages)
for asynchronous SCMI commands was not handled properly.

> How do you propose we solve this? Do you think it is better to take the
> setting up of base and other protocols out of probe and
> in some delayed work? That would imply the device memory is not released
> until remove is called. Or should we add locking to
> the interrupt handler(scmi_rx_callback) and the cleanup in probe to avoid
> the race?
> 

These issues were more easily exposed by SCMI Virtio transport, so in
the series where I introduced scmi-virtio:

https://lore.kernel.org/linux-arm-kernel/162848483974.232214.9506203742448269364.b4-ty at arm.com/

(which is now queued for v5.15 ...  now on -next I think...finger crossed)

I took the chance to rectify a couple of other things in the SCMI core
in the initial commits.
As an example, in the above series

 [PATCH v7 05/15] firmware: arm_scmi: Handle concurrent and out-of-order messages

cares to add a refcount to xfers and some locking on xfers between TX
and RX path to avoid that a timed out xfer can vanish while the rx path
is concurrently working on it (as you said); moreover I handle the
condition (rare if not unplausible anyway) in which a transport delivers
out of order responses and delayed responses.

I tested this scenarios on some fake emulated SCMI Virtio transport
where I could play any sort of mess and tricks to stress this limit
conditions, but you're more than welcome to verify if the race you are
seeing on Base protocol time out is solved (as I would hope :D) by this
series of mine.

Let me know, any feedback is welcome.

Btw, in the series above there are also other minor changes, but there
is also another more radical change needed to ensure correctness and
protection against stale old messages which maybe could interest you
in general if you are looking into SCMI:

[PATCH v7 04/15] firmware: arm_scmi: Introduce monotonically increasing tokens 

Let me know if yo have other concerns.

Thanks
Cristian



From cristian.marussi at arm.com  Mon Aug 30 22:56:22 2021
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 31 Aug 2021 06:56:22 +0100
Subject: [PATCH v4 11/12] [RFC] firmware: arm_scmi: Add
 sync_cmds_atomic_replies transport flag
In-Reply-To: <CA+-6iNwjQ1SogxdyrjwqEwLosscUyvrioqFKmesifM_nmCpJAw@mail.gmail.com>
References: <20210824135941.38656-1-cristian.marussi@arm.com>
 <20210824135941.38656-12-cristian.marussi@arm.com>
 <7a2f972d-fdd0-d0f7-cac2-1989980ed872@gmail.com>
 <CA+-6iNw-_VXcntU_UE8kTiPb8Sq28KkZG1__N7rE4ezo=VqQVQ@mail.gmail.com>
 <20210825184915.GI13160@e120937-lin>
 <CA+-6iNwjQ1SogxdyrjwqEwLosscUyvrioqFKmesifM_nmCpJAw@mail.gmail.com>
Message-ID: <20210831055622.GK13160@e120937-lin>

On Thu, Aug 26, 2021 at 02:29:21PM -0400, Jim Quinlan wrote:
> On Wed, Aug 25, 2021 at 2:49 PM Cristian Marussi
> <cristian.marussi at arm.com> wrote:
> >
> > On Wed, Aug 25, 2021 at 01:17:47PM -0400, Jim Quinlan wrote:
> > > On Wed, Aug 25, 2021 at 12:38 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
> > > >
> > > >
> > > >
> >
> > Hi Florian and Jim,
> >
> > > > On 8/24/2021 3:59 PM, Cristian Marussi wrote:
> > > > > A flag is added to let the transport signal the core that its handling of
> > > > > synchronous command messages implies that, after .send_message has returned
> > > > > successfully, the requested command can be assumed to be fully and
> > > > > completely executed on SCMI platform side so that any possible response
> > > > > value is already immediately available to be retrieved by a .fetch_reponse:
> > > > > in other words the polling phase can be skipped in such a case and the
> > > > > response values accessed straight away.
> > > > >
> > > > > Note that all of the above applies only when polling mode of operation was
> > > > > selected by the core: if instead a completion IRQ was found to be available
> > > > > the normal response processing path based on completions will still be
> > > > > followed.
> > > >
> > > > This might actually have to be settable on a per-message basis ideally
> > > > since we may be transporting short lived SCMI messages for which the
> > > > completion can be done at SMC time, and long lived SCMI messages (e.g.:
> > > > involving a voltage change) for which we would prefer a completion
> > > > interrupt. Jim, what do you think?
> > > Even if the SCMI main driver could be configured this way in an
> > > elegant manner, I'm not sure that there is a clean way of specifying
> > > this  attribute on a per-message basis.  Certainly we could do this
> > > with our own protocols, but  many of our "long lived" messages are the
> > > Perf protocol's set_level command.  At any rate, let me give it some
> > > thought.
> > >
> >
> > The new flag .sync_cmds_atomic_replies applies only when polling mode
> > has been selected for a specific cmd transaction, which means when no
> > completion IRQ was found available OR if xfer.poll_completion was
> > excplicitly set for a specific command.
> >
> > At the moment in this series (unknown bugs apart :D), if you have a
> > channel configured with a completion IRQ and the .sync_cmds_atomic_replies
> > set for the transport, this latter flag would be generally ignored and a
> > wait_for_completion() will be normally used upon reception of the
> > completionIRQ, UNLESS you specify that one specific command has to be
> > polled using the per message xfer.poll_completion flag: so you should be
> > already able to selectively use a polling which immediately returns after
> > the smc by setting xfer.poll_completion for that specific short lived
> > message (since sync_cmds_atomic_replies is set and applies to pollmode).
> > On the other side any other LONG lived message will be naturally handled
> > via completionIRQ + wait_for_completion. (at least that was the aim..)
> >
> > !!! NOTE that you'll have also to drop
> >
> >  [PATCH v4 10/12] [RFC] firmware: arm_scmi: Make smc transport atomic
> >
> > from this series for the wait_completion to happen as you wish.
> 
> Hi Cristian,
> 
Hi Jim,

> I've tested all commits on our SMC-based system.  I also tested all commits
> minus  "10/12 [RFC] firmware: arm_scmi: Make smc transport atomic".
> This was a basic stress test, not a comprehensive one.  So
> 
> Tested-by: Jim Quinlan <james.quinlan at broadcom.com>
> 

Thanks a lot for this testing.

> Of course I have a strong preference for omitting  "10/12 [RFC]" :-).
> FWIW, if you are not planning on dropping this commit, perhaps there
> could be a transport
> node in the DT, and that could contain the  a bool  property
> "smc-atomic-capable"?

Indeed, as I was saying more than one customer/partner is asking for this
configurability so this atomic mode should be definitely configurable.
(as it could be teh case similarly with the sync_cmds_atomic_replies
depedning on SCMI server placement..)

I'll talk with Sudeep in general about the series and this configurations;
in fact I can exclude that I'll commit this series with 10/12 as it is right
now.

Thanks for the feedback !

Cristian

> 
> Regards,
> Jim Quinlan
> Broadcom STB
> 
> >
> > As said I'm not sure that this whole mixing of polling and IRQs on the
> > same channel on a regular won't cause any issues: any feedback on this
> > from your setup is much appreciated.
> > (maybe it's fine for SMC transport, but it led to a bit of hell in the
> > past with mboxes AFAIK...)
> >
> > Thanks a lot again for your feedback, I'll have to chat with Sudeep
> > about the various issues/configs possibility that we discussed and I'll
> > keep you in the loop.
> >
> > Thanks,
> > Cristian
> >
> > P.S.: I'll be off for a few weeks, so even though I'll keep an eye on
> > the mail, I cannot guarantee any responsiveness :D




From baruch at tkos.co.il  Mon Aug 30 22:57:29 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Tue, 31 Aug 2021 08:57:29 +0300
Subject: [PATCH v3 1/4] dt-bindings: usb: dwc3: add reference clock period
Message-ID: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>

Document the snps,ref-clock-period-ns property that describes reference
clock period when it deviates from the default set value.

Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v2:

Address comments from Rob Herring:

  Use standard unit suffix

  Reword description
---
 Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
index 41416fbd92aa..413ac37c447f 100644
--- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml
@@ -252,6 +252,14 @@ properties:
     minimum: 0
     maximum: 0x3f
 
+  snps,ref-clock-period-ns:
+    description:
+      Value for REFCLKPER field of GUCTL register for reference clock period in
+      nanoseconds, when the hardware set default does not match the actual
+      clock.
+    minimum: 1
+    maximum: 0x3ff
+
   snps,rx-thr-num-pkt-prd:
     description:
       Periodic ESS RX packet threshold count (host mode only). Set this and
-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 22:57:30 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Tue, 31 Aug 2021 08:57:30 +0300
Subject: [PATCH v3 2/4] usb: dwc3: reference clock period configuration
In-Reply-To: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
References: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
Message-ID: <9f399bdf1ff752e31ab7497e3d5ce19bbb3ff247.1630389452.git.baruch@tkos.co.il>

From: Balaji Prakash J <bjagadee at codeaurora.org>

Set reference clock period when it differs from dwc3 default hardware
set.

We could calculate clock period based on reference clock frequency. But
this information is not always available. This is the case of PCI bus
attached USB host. For that reason we use a custom property.

Tested (USB2 only) on IPQ6010 SoC based board with 24 MHz reference
clock while hardware default is 19.2 MHz.

Nacked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Balaji Prakash J <bjagadee at codeaurora.org>
[ baruch: rewrite commit message; drop GFLADJ code; remove 'quirk-' from
  property name; mention tested hardware ]
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v3:

  Add standard unit suffix (Rob Herring)

v2:

  Remove snps,quirk-ref-clock-adjustment; not needed for tested hardware

  Rename DT property to snps,ref-clock-period (Thinh Nguyen)

  Use FIELD_PREP() (Bjorn Andersson)
---
 drivers/usb/dwc3/core.c | 29 +++++++++++++++++++++++++++++
 drivers/usb/dwc3/core.h |  6 ++++++
 2 files changed, 35 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ba74ad7f6995..31b8cb101a47 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -26,6 +26,7 @@
 #include <linux/acpi.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/reset.h>
+#include <linux/bitfield.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
@@ -351,6 +352,29 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc)
 	}
 }
 
+/**
+ * dwc3_ref_clk_period - Reference clock period configuration
+ *		Default reference clock period depends on hardware
+ *		configuration. For systems with reference clock that differs
+ *		from the default, this will set clock period in DWC3_GUCTL
+ *		register.
+ * @dwc: Pointer to our controller context structure
+ * @ref_clk_per: reference clock period in ns
+ */
+static void dwc3_ref_clk_period(struct dwc3 *dwc)
+{
+	u32 reg;
+
+	if (dwc->ref_clk_per == 0)
+		return;
+
+	reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+	reg &= ~DWC3_GUCTL_REFCLKPER_MASK;
+	reg |=  FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, dwc->ref_clk_per);
+	dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+}
+
+
 /**
  * dwc3_free_one_event_buffer - Frees one event buffer
  * @dwc: Pointer to our controller context structure
@@ -1011,6 +1035,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
 	/* Adjust Frame Length */
 	dwc3_frame_length_adjustment(dwc);
 
+	/* Adjust Reference Clock Period */
+	dwc3_ref_clk_period(dwc);
+
 	dwc3_set_incr_burst_type(dwc);
 
 	usb_phy_set_suspend(dwc->usb2_phy, 0);
@@ -1371,6 +1398,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 				    &dwc->hsphy_interface);
 	device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
 				 &dwc->fladj);
+	device_property_read_u32(dev, "snps,ref-clock-period-ns",
+				 &dwc->ref_clk_per);
 
 	dwc->dis_metastability_quirk = device_property_read_bool(dev,
 				"snps,dis_metastability_quirk");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 5991766239ba..1e4e21ea9d97 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -386,6 +386,10 @@
 #define DWC3_GFLADJ_30MHZ_SDBND_SEL		BIT(7)
 #define DWC3_GFLADJ_30MHZ_MASK			0x3f
 
+/* Global User Control Register*/
+#define DWC3_GUCTL_REFCLKPER_MASK		0xffc00000
+#define DWC3_GUCTL_REFCLKPER_SEL		22
+
 /* Global User Control Register 2 */
 #define DWC3_GUCTL2_RST_ACTBITLATER		BIT(14)
 
@@ -969,6 +973,7 @@ struct dwc3_scratchpad_array {
  * @regs: base address for our registers
  * @regs_size: address space size
  * @fladj: frame length adjustment
+ * @ref_clk_per: reference clock period configuration
  * @irq_gadget: peripheral controller's IRQ number
  * @otg_irq: IRQ number for OTG IRQs
  * @current_otg_role: current role of operation while using the OTG block
@@ -1141,6 +1146,7 @@ struct dwc3 {
 	struct power_supply	*usb_psy;
 
 	u32			fladj;
+	u32			ref_clk_per;
 	u32			irq_gadget;
 	u32			otg_irq;
 	u32			current_otg_role;
-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 22:57:31 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Tue, 31 Aug 2021 08:57:31 +0300
Subject: [PATCH v3 3/4] dt-bindings: usb: qcom,dwc3: add binding for IPQ6018
In-Reply-To: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
References: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
Message-ID: <6a9b00d16a707aa2a94bcba71a24932cc201a473.1630389452.git.baruch@tkos.co.il>

Add compatible string for Qualcomm IPQ6018 SoC.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
index 4e6451789806..55ed4b4c7f51 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
@@ -13,6 +13,7 @@ properties:
   compatible:
     items:
       - enum:
+          - qcom,ipq6018-dwc3
           - qcom,msm8996-dwc3
           - qcom,msm8998-dwc3
           - qcom,sc7180-dwc3
-- 
2.33.0



From baruch at tkos.co.il  Mon Aug 30 22:57:32 2021
From: baruch at tkos.co.il (Baruch Siach)
Date: Tue, 31 Aug 2021 08:57:32 +0300
Subject: [PATCH v3 4/4] arm64: qcom: ipq6018: add usb3 DT description
In-Reply-To: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
References: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
Message-ID: <ebc2d340d566fa2d43127e253d5b8b134a87a78e.1630389452.git.baruch@tkos.co.il>

From: Kathiravan T <kathirav at codeaurora.org>

Based on downstream codeaurora code.

Tested (USB2 only) on IPQ6010 based hardware.

Signed-off-by: Kathiravan T <kathirav at codeaurora.org>
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
v3:

  Add -ns unit suffix to snps,ref-clock-period (Rob Herring)
---
 arch/arm64/boot/dts/qcom/ipq6018.dtsi | 83 +++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 9fa5b028e4f3..8548d2cce619 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -524,6 +524,89 @@ qrtr_requests {
 			};
 		};
 
+		ssphy_0: ssphy at 78000 {
+			compatible = "qcom,ipq6018-qmp-usb3-phy";
+			reg = <0x0 0x78000 0x0 0x1C4>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			#clock-cells = <1>;
+			ranges;
+
+			clocks = <&gcc GCC_USB0_AUX_CLK>,
+				 <&gcc GCC_USB0_PHY_CFG_AHB_CLK>, <&xo>;
+			clock-names = "aux", "cfg_ahb", "ref";
+
+			resets = <&gcc GCC_USB0_PHY_BCR>,
+				 <&gcc GCC_USB3PHY_0_PHY_BCR>;
+			reset-names = "phy","common";
+			status = "disabled";
+
+			usb0_ssphy: lane at 78200 {
+				reg = <0x0 0x00078200 0x0 0x130>, /* Tx */
+				      <0x0 0x00078400 0x0 0x200>, /* Rx */
+				      <0x0 0x00078800 0x0 0x1F8>, /* PCS */
+				      <0x0 0x00078600 0x0 0x044>; /* PCS misc */
+				#phy-cells = <0>;
+				clocks = <&gcc GCC_USB0_PIPE_CLK>;
+				clock-names = "pipe0";
+				clock-output-names = "gcc_usb0_pipe_clk_src";
+			};
+		};
+
+		qusb_phy_0: qusb at 79000 {
+			compatible = "qcom,ipq6018-qusb2-phy";
+			reg = <0x0 0x079000 0x0 0x180>;
+			#phy-cells = <0>;
+
+			clocks = <&gcc GCC_USB0_PHY_CFG_AHB_CLK>,
+				<&xo>;
+			clock-names = "cfg_ahb", "ref";
+
+			resets = <&gcc GCC_QUSB2_0_PHY_BCR>;
+			status = "disabled";
+		};
+
+		usb3: usb3 at 8A00000 {
+			compatible = "qcom,ipq6018-dwc3", "qcom,dwc3";
+			reg = <0x0 0x8AF8800 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			clocks = <&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
+				<&gcc GCC_USB0_MASTER_CLK>,
+				<&gcc GCC_USB0_SLEEP_CLK>,
+				<&gcc GCC_USB0_MOCK_UTMI_CLK>;
+			clock-names = "sys_noc_axi",
+				"master",
+				"sleep",
+				"mock_utmi";
+
+			assigned-clocks = <&gcc GCC_SYS_NOC_USB0_AXI_CLK>,
+					  <&gcc GCC_USB0_MASTER_CLK>,
+					  <&gcc GCC_USB0_MOCK_UTMI_CLK>;
+			assigned-clock-rates = <133330000>,
+					       <133330000>,
+					       <20000000>;
+
+			resets = <&gcc GCC_USB0_BCR>;
+			status = "disabled";
+
+			dwc_0: dwc3 at 8A00000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x8A00000 0x0 0xcd00>;
+				interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&qusb_phy_0>, <&usb0_ssphy>;
+				phy-names = "usb2-phy", "usb3-phy";
+				tx-fifo-resize;
+				snps,is-utmi-l1-suspend;
+				snps,hird-threshold = /bits/ 8 <0x0>;
+				snps,dis_u2_susphy_quirk;
+				snps,dis_u3_susphy_quirk;
+				snps,ref-clock-period-ns = <0x32>;
+				dr_mode = "host";
+			};
+		};
 	};
 
 	wcss: wcss-smp2p {
-- 
2.33.0



From qii.wang at mediatek.com  Mon Aug 30 22:57:56 2021
From: qii.wang at mediatek.com (Qii Wang)
Date: Tue, 31 Aug 2021 13:57:56 +0800
Subject: [PATCH v6 1/7] i2c: mediatek: fixing the incorrect register offset
In-Reply-To: <1630147859-17031-2-git-send-email-kewei.xu@mediatek.com>
References: <1630147859-17031-1-git-send-email-kewei.xu@mediatek.com>
 <1630147859-17031-2-git-send-email-kewei.xu@mediatek.com>
Message-ID: <1630389476.11251.3.camel@mhfsdcap03>

On Sat, 2021-08-28 at 18:50 +0800, Kewei Xu wrote:
> The reason for the modification here is that the previous
> offset information is incorrect, OFFSET_DEBUGSTAT = 0xE4 is
> the correct value.
> 
> Fixes: 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183")
> Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/i2c/busses/i2c-mt65xx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Reviewed-by: Qii Wang <qii.wang at mediatek.com>




From Chunfeng.Yun at mediatek.com  Mon Aug 30 23:15:45 2021
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Tue, 31 Aug 2021 06:15:45 +0000
Subject: [PATCH v4 2/2] usb: musb: mediatek: Expose role-switch control to
 userspace
In-Reply-To: <20210830155903.13907-3-mans0n@gorani.run>
References: <20210822041333.5264-1-mans0n@gorani.run>
 <20210830155903.13907-1-mans0n@gorani.run>
 <20210830155903.13907-3-mans0n@gorani.run>
Message-ID: <654526ce5dcbfb2b92e4e888c8e24dd72eb478d1.camel@mediatek.com>

On Tue, 2021-08-31 at 00:59 +0900, Sungbo Eo wrote:
> The allow_userspace_control flag enables manual role-switch from
> userspace.
> Turn this feature on like several other USB DRD controller drivers.
> 
> Signed-off-by: Sungbo Eo <mans0n at gorani.run>
> Tested-by: Frank Wunderlich <frank-w at public-files.de>
> ---
>  drivers/usb/musb/mediatek.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/usb/musb/mediatek.c
> b/drivers/usb/musb/mediatek.c
> index 6b92d037d8fc..f5d97eb84cb5 100644
> --- a/drivers/usb/musb/mediatek.c
> +++ b/drivers/usb/musb/mediatek.c
> @@ -185,6 +185,7 @@ static int mtk_otg_switch_init(struct mtk_glue
> *glue)
>  
>  	role_sx_desc.set = musb_usb_role_sx_set;
>  	role_sx_desc.get = musb_usb_role_sx_get;
> +	role_sx_desc.allow_userspace_control = true;
>  	role_sx_desc.fwnode = dev_fwnode(glue->dev);
>  	role_sx_desc.driver_data = glue;
>  	glue->role_sw = usb_role_switch_register(glue->dev,
> &role_sx_desc);

Acked-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Thanks

From Chunfeng.Yun at mediatek.com  Mon Aug 30 23:27:18 2021
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Tue, 31 Aug 2021 06:27:18 +0000
Subject: [PATCH v4 1/2] arm: dts: mt7623: add musb device nodes
In-Reply-To: <20210830155903.13907-2-mans0n@gorani.run>
References: <20210822041333.5264-1-mans0n@gorani.run>
 <20210830155903.13907-1-mans0n@gorani.run>
 <20210830155903.13907-2-mans0n@gorani.run>
Message-ID: <16f980b95e1f32bb8eb32448f1615bafdc51b792.camel@mediatek.com>

On Tue, 2021-08-31 at 00:59 +0900, Sungbo Eo wrote:
> MT7623 has an musb controller that is compatible with the one from
> MT2701.
> 
> Signed-off-by: Sungbo Eo <mans0n at gorani.run>
> Tested-by: Frank Wunderlich <frank-w at public-files.de>
> ---
> v4:
> * add tested by Frank
> 
> v3:
> * remove unnecessary status=okay from u2port2
> 
> v2:
> * rename usb3 label to usb0
> * move usb0 & u2phy1 nodes to the right sorted place
> * disable u2phy1 by default
> * correct u2port2 node name to match its reg address
> ---
>  arch/arm/boot/dts/mt7623.dtsi  | 33
> +++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/mt7623a.dtsi |  4 ++++
>  2 files changed, 37 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/mt7623.dtsi
> b/arch/arm/boot/dts/mt7623.dtsi
> index 3c11f7cfcc40..21c8a291b74e 100644
> --- a/arch/arm/boot/dts/mt7623.dtsi
> +++ b/arch/arm/boot/dts/mt7623.dtsi
> @@ -585,6 +585,39 @@ spi2: spi at 11017000 {
>  		status = "disabled";
>  	};
>  
> +	usb0: usb at 11200000 {
> +		compatible = "mediatek,mt7623-musb",
> +			     "mediatek,mtk-musb";
> +		reg = <0 0x11200000 0 0x1000>;
> +		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
> +		interrupt-names = "mc";
> +		phys = <&u2port2 PHY_TYPE_USB2>;
> +		dr_mode = "otg";
> +		clocks = <&pericfg CLK_PERI_USB0>,
> +			 <&pericfg CLK_PERI_USB0_MCU>,
> +			 <&pericfg CLK_PERI_USB_SLV>;
> +		clock-names = "main","mcu","univpll";
> +		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
> +		status = "disabled";
> +	};
> +
> +	u2phy1: t-phy at 11210000 {
> +		compatible = "mediatek,mt7623-tphy",
> +			     "mediatek,generic-tphy-v1";
> +		reg = <0 0x11210000 0 0x0800>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +		status = "disabled";
> +
> +		u2port2: usb-phy at 11210800 {
> +			reg = <0 0x11210800 0 0x0100>;
> +			clocks = <&topckgen CLK_TOP_USB_PHY48M>;
> +			clock-names = "ref";
> +			#phy-cells = <1>;
> +		};
> +	};
> +
>  	audsys: clock-controller at 11220000 {
>  		compatible = "mediatek,mt7623-audsys",
>  			     "mediatek,mt2701-audsys",
> diff --git a/arch/arm/boot/dts/mt7623a.dtsi
> b/arch/arm/boot/dts/mt7623a.dtsi
> index 0735a1fb8ad9..d304b62d24b5 100644
> --- a/arch/arm/boot/dts/mt7623a.dtsi
> +++ b/arch/arm/boot/dts/mt7623a.dtsi
> @@ -35,6 +35,10 @@ &scpsys {
>  	clock-names = "ethif";
>  };
>  
> +&usb0 {
> +	power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>;
> +};
> +
>  &usb1 {
>  	power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>;
>  };

Is the dt-binding patch applied? 
It's better to put it into this series due to the new
compatible "mediatek,mt7623-musb" is used for the first time.

Reviewed-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Thanks a lot





From christian.koenig at amd.com  Mon Aug 30 23:31:22 2021
From: christian.koenig at amd.com (=?UTF-8?Q?Christian_K=c3=b6nig?=)
Date: Tue, 31 Aug 2021 08:31:22 +0200
Subject: [PATCH] dma-buf: heaps: remove duplicated cache sync
In-Reply-To: <20210831034405.41916-1-guangming.cao@mediatek.com>
References: <dd5ba603-8c9d-f6a0-cbcc-dfb353fb6701@amd.com>
 <20210831034405.41916-1-guangming.cao@mediatek.com>
Message-ID: <0b48df29-a20f-65f6-bc4c-6c0a7522ecd7@amd.com>

Am 31.08.21 um 05:44 schrieb guangming.cao at mediatek.com:
> From: Guangming Cao <Guangming.Cao at mediatek.com>
>
>> Am 30.08.21 um 12:01 schrieb guangming.cao at mediatek.com:
>>> From: Guangming Cao <Guangming.Cao at mediatek.com>
>>>
>>> Current flow, one dmabuf maybe call cache sync many times if
>>> it has beed mapped more than one time.
>> Well I'm not an expert on DMA heaps, but this will most likely not work
>> correctly.
>>
> All attachments of one dmabuf will add into a list, I think it means dmabuf
> supports map more than one time. Could you tell me more about it?

Yes, that's correct and all of those needs to be synced as far as I know.

See the dma_sync_sgtable_for_cpu() is intentionally for each SG table 
given out.

>>> Is there any case that attachments of one dmabuf will points to
>>> different memory? If not, seems do sync only one time is more better.
>> I think that this can happen, yes.
>>
>> Christian.
>>
> Seems it's a very special case on Android, if you don't mind, could you
> tell me more about it?

That might be the case, nevertheless this change here is illegal from 
the DMA API point of view as far as I can see.

Regards,
Christian.

>
>>> Signed-off-by: Guangming Cao <Guangming.Cao at mediatek.com>
>>> ---
>>>    drivers/dma-buf/heaps/system_heap.c | 14 ++++++++------
>>>    1 file changed, 8 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
>>> index 23a7e74ef966..909ef652a8c8 100644
>>> --- a/drivers/dma-buf/heaps/system_heap.c
>>> +++ b/drivers/dma-buf/heaps/system_heap.c
>>> @@ -162,9 +162,10 @@ static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
>>>    		invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
>>>    
>>>    	list_for_each_entry(a, &buffer->attachments, list) {
>>> -		if (!a->mapped)
>>> -			continue;
>>> -		dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
>>> +		if (a->mapped) {
>>> +			dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
>>> +			break;
>>> +		}
>>>    	}
>>>    	mutex_unlock(&buffer->lock);
>>>    
>>> @@ -183,9 +184,10 @@ static int system_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
>>>    		flush_kernel_vmap_range(buffer->vaddr, buffer->len);
>>>    
>>>    	list_for_each_entry(a, &buffer->attachments, list) {
>>> -		if (!a->mapped)
>>> -			continue;
>>> -		dma_sync_sgtable_for_device(a->dev, a->table, direction);
>>> +		if (!a->mapped) {
>>> +			dma_sync_sgtable_for_device(a->dev, a->table, direction);
>>> +			break;
>>> +		}
>>>    	}
>>>    	mutex_unlock(&buffer->lock);
>>>    



From Eugen.Hristev at microchip.com  Mon Aug 30 23:45:01 2021
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Tue, 31 Aug 2021 06:45:01 +0000
Subject: [PATCH v2 05/10] iio: adc: at91-sama5d2-adc: add support for
 separate end of conversion registers
In-Reply-To: <20210824115441.681253-6-eugen.hristev@microchip.com>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
 <20210824115441.681253-6-eugen.hristev@microchip.com>
Message-ID: <7d2607ce-4cfc-63f9-dad2-a5ef5c9538b5@microchip.com>

On 8/24/21 2:54 PM, Eugen Hristev wrote:
> Some platforms have separated the end-of-conversion information from the
> usual ISR/IMR/IER/IDR registers, into EOC_ISR/EOC_IMR/EOC_IER/EOC_IDR.
> To cope with both variants, helpers are being added, that will make
> code more clear and more easy to read.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> ---

Hi Jonathan,

If you can still make changes on your testing branch, I noticed a typo 
in the shortcommit of this patch : 'at91-sama5d2-adc' instead of 
'at91-sama5d2_adc' , grepping through commits in the future might miss 
this patch, so maybe you can change it ?

Thanks,
Eugen

From eugen.hristev at microchip.com  Mon Aug 30 23:48:00 2021
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Tue, 31 Aug 2021 09:48:00 +0300
Subject: [PATCH] iio: adc: at91-sama5d2_adc: fix warning for uninitialized
 'val' variable
Message-ID: <20210831064800.78979-1-eugen.hristev@microchip.com>

>> drivers/iio/adc/at91-sama5d2_adc.c:722:11: warning: variable 'val' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
           else if (reg == st->soc_info.platform->layout->YPOSR)
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/adc/at91-sama5d2_adc.c:725:7: note: uninitialized use occurs here
           if (!val)
                ^~~
   drivers/iio/adc/at91-sama5d2_adc.c:722:7: note: remove the 'if' if its condition is always true
           else if (reg == st->soc_info.platform->layout->YPOSR)
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iio/adc/at91-sama5d2_adc.c:711:9: note: initialize the variable 'val' to silence this warning
           u32 val;
                  ^
                   = 0
   1 warning generated.

Fixed by initializing 'val' variable.

Fixes: 29edec2b98ff ("iio: adc: at91-sama5d2_adc: convert to platform specific data structures")
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---

Hi Jonathan,

If you can still rebase your testing branch, maybe you can squash this into the
original patch, no need to make a separate commit I guess.
I fixed this as soon as the report came out from the 0day robot.

Thanks !
Eugen

 drivers/iio/adc/at91-sama5d2_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 29c7441f9f27..f8a9ad50a00b 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -846,7 +846,7 @@ static int at91_adc_configure_touch(struct at91_adc_state *st, bool state)
 
 static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
 {
-	u32 val;
+	u32 val = 0;
 	u32 scale, result, pos;
 
 	/*
-- 
2.25.1



From Chunfeng.Yun at mediatek.com  Mon Aug 30 23:50:00 2021
From: Chunfeng.Yun at mediatek.com (=?utf-8?B?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?=)
Date: Tue, 31 Aug 2021 06:50:00 +0000
Subject: [PATCH next v2 3/6] usb: xhci-mtk: update fs bus bandwidth by
 bw_budget_table
In-Reply-To: <CAATdQgDKuO+bM7_tMy59ghhhjrgCp53kHgYbgEciriHNF3uKuA@mail.gmail.com>
References: <20210826025144.51992-1-chunfeng.yun@mediatek.com>
 <20210826025144.51992-3-chunfeng.yun@mediatek.com>
 <CAATdQgBD+dTtBie-cNKRJbfxEpc3haqjfUu1k26mTk8pCSOEww@mail.gmail.com>
 <72ee7a203d8a49e6e43a954b45133470ee6d5c16.camel@mediatek.com>
 <CAATdQgA+4VC7J1LMZYOZMV-OTjMGjO=9bJZ7uaCu_MMF-20T1w@mail.gmail.com>
 <18cb18d7d0ea4a3bb46921aca88c53646f1b3764.camel@mediatek.com>
 <CAATdQgDKuO+bM7_tMy59ghhhjrgCp53kHgYbgEciriHNF3uKuA@mail.gmail.com>
Message-ID: <cbf7ad7456003309e587ae86f5743aa0fd1cb2cb.camel@mediatek.com>

On Mon, 2021-08-30 at 11:49 +0800, Ikjoon Jang wrote:
> On Fri, Aug 27, 2021 at 5:49 PM Chunfeng Yun (???)
> <Chunfeng.Yun at mediatek.com> wrote:
> > 
> > On Fri, 2021-08-27 at 17:14 +0800, Ikjoon Jang wrote:
> > > On Fri, Aug 27, 2021 at 2:49 PM Chunfeng Yun (???)
> > > <Chunfeng.Yun at mediatek.com> wrote:
> > > > 
> > > > On Thu, 2021-08-26 at 19:54 +0800, Ikjoon Jang wrote:
> > > > > Hi Chunfeng,
> > > > > 
> > > > > On Thu, Aug 26, 2021 at 10:52 AM Chunfeng Yun <
> > > > > chunfeng.yun at mediatek.com> wrote:
> > > > > > 
> > > > > > Use @bw_budget_table[] to update fs bus bandwidth due to
> > > > > > not all microframes consume @bw_cost_per_microframe, see
> > > > > > setup_sch_info().
> > > > > > 
> > > > > > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > > > > > ---
> > > > > > v2: new patch, move from another series
> > > > > > ---
> > > > > >  drivers/usb/host/xhci-mtk-sch.c | 17 +++++++----------
> > > > > >  1 file changed, 7 insertions(+), 10 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/usb/host/xhci-mtk-sch.c
> > > > > > b/drivers/usb/host/xhci-mtk-sch.c
> > > > > > index cffcaf4dfa9f..83abd28269ca 100644
> > > > > > --- a/drivers/usb/host/xhci-mtk-sch.c
> > > > > > +++ b/drivers/usb/host/xhci-mtk-sch.c
> > > > > > @@ -458,8 +458,8 @@ static int check_fs_bus_bw(struct
> > > > > > mu3h_sch_ep_info *sch_ep, int offset)
> > > > > >                  * Compared with hs bus, no matter what ep
> > > > > > type,
> > > > > >                  * the hub will always delay one uframe to
> > > > > > send
> > > > > > data
> > > > > >                  */
> > > > > > -               for (j = 0; j < sch_ep->cs_count; j++) {
> > > > > > -                       tmp = tt->fs_bus_bw[base + j] +
> > > > > > sch_ep-
> > > > > > > bw_cost_per_microframe;
> > > > > > 
> > > > > > +               for (j = 0; j < sch_ep-
> > > > > > >num_budget_microframes;
> > > > > > j++) {
> > > > > > +                       tmp = tt->fs_bus_bw[base + j] +
> > > > > > sch_ep-
> > > > > > > bw_budget_table[j];
> > > > > 
> > > > > I'm worrying about this case with two endpoints,
> > > > > * EP1OUT: isochronous, maxpacket=192: bw_budget_table[] = {
> > > > > 188,
> > > > > 188,
> > > > > 0, ... }
> > > > > * EP2IN: interrupt, maxpacket=64: bw_budget_table[] = { 0, 0,
> > > > > 64,
> > > > > 64,
> > > > > ... }
> > > > > (Is this correct bw_budget_table contents for those eps?)
> > > > 
> > > > Yes, ep1out isoc use two uframe, ep2in intr use a extra cs;
> > > > > 
> > > > > I'm not sure if it's okay for those two endpoints to be
> > > > > allocated
> > > > > on the same u-frame slot.
> > > > > Can you please check if this is okay for xhci-mtk?
> > > > 
> > > > Already test it this afternoon, can transfer data rightly on
> > > > our
> > > > dvt
> > > > env.
> > > > 
> > > > > (I feel like I already asked the same questions many times.)
> > > > 
> > > > Yes, as said before, prefer to use bw_budget_table[], if there
> > > > is
> > > > issue, we can fix it by building this table.
> > > 
> > > So do you mean such an allocation shouldn't be a problem by IP
> > > design?
> > 
> > Yes, at least on our dvt platform
> 
> Did you check that your side also has a similar allocation
> (SSPLIT-all sits between SSPLIT-start ~ -end for another ep)?
> My audio headset doesn't work properly with this scheme.
> 
> > 
> > > 
> > > This patch starts to allow such an allocation (again).
> > > But i remember my earlier tests showed that when those two eps
> > > in the above example are allocated on the same u-frame slot,
> > > xhci-mtk puts "SSPLIT for EP2" between
> > > "SSPLIT-start and SSPLIT-end for EP1OUT transaction",
> > > which is a spec violation.
> > 
> > Which section in usb2.0 spec?
> 
> I think that's just a basic rule - if software wants to send 192
> bytes
> through a full-speed bus, HC should send OUT/DATA 192 bytes
> continuously without inserting any other packets during that 192
> bytes.
> and usb2 11.14.2 mentions that TT has separated
> Start-Split and Complete-Split buffers
> but not tracked each transaction per endpoint basis.
> 
> > 
> > > Hub will generate bit stuffing errors on the
> > > full-speed bus.
> > 
> > which platform?
> 
> I remember it was mt8173.
Does it happen on mt8192?

> 
> And for bit stuffing errors I mentioned in the earlier mail.
> when I read the spec again, 11.21 mentions that bit stuffing error
> is generated when _a microframe_ should be passed without
> corresponding SSPLIT-mid/end. So this is not the case and also
> I'm not sure what will happen on the full-speed bus, sorry.
> In my case what I can be sure of is that the audio output was
> broken with those allotments.
> 
> What is the xhci-mtk's policy when there are more than two EPs
> marked as the same u-frame offset like in the above example?
Seems no this limitation, an EP doesn't monopolize an u-frame

> 
> > 
> > > 
> > > 
> > > > 
> > > > Thanks
> > > > > 
> > > > > 
> > > > > >                         if (tmp > FS_PAYLOAD_MAX)
> > > > > >                                 return -ESCH_BW_OVERFLOW;
> > > > > >                 }
> > > > > > @@ -534,21 +534,18 @@ static void update_sch_tt(struct
> > > > > > mu3h_sch_ep_info *sch_ep, bool used)
> > > > > >  {
> > > > > >         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
> > > > > >         u32 base, num_esit;
> > > > > > -       int bw_updated;
> > > > > >         int i, j;
> > > > > > 
> > > > > >         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> > > > > > 
> > > > > > -       if (used)
> > > > > > -               bw_updated = sch_ep-
> > > > > > >bw_cost_per_microframe;
> > > > > > -       else
> > > > > > -               bw_updated = -sch_ep-
> > > > > > >bw_cost_per_microframe;
> > > > > > -
> > > > > >         for (i = 0; i < num_esit; i++) {
> > > > > >                 base = sch_ep->offset + i * sch_ep->esit;
> > > > > > 
> > > > > > -               for (j = 0; j < sch_ep->cs_count; j++)
> > > > > > -                       tt->fs_bus_bw[base + j] +=
> > > > > > bw_updated;
> > > > > > +               for (j = 0; j < sch_ep-
> > > > > > >num_budget_microframes;
> > > > > > j++)
> > > > > > +                       if (used)
> > > > > > +                               tt->fs_bus_bw[base + j] +=
> > > > > > sch_ep-
> > > > > > > bw_budget_table[j];
> > > > > > 
> > > > > > +                       else
> > > > > > +                               tt->fs_bus_bw[base + j] -=
> > > > > > sch_ep-
> > > > > > > bw_budget_table[j];
> > > > > > 
> > > > > >         }
> > > > > > 
> > > > > >         if (used)
> > > > > > --
> > > > > > 2.18.0
> > > > > > 

From jason-jh.lin at mediatek.com  Tue Aug 31 00:08:58 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Tue, 31 Aug 2021 15:08:58 +0800
Subject: [PATCH v7 0/5] Add gce support for mt8195
Message-ID: <20210831070903.8672-1-jason-jh.lin@mediatek.com>

Change in v7:
- rebase on "support gce on mt8192 platform" series:
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=524833

Change in v6:
- remove the unused define in GCE header file.

Change in v5:
- rebase on kernel-5.14-rc1
- remove unused varriable in mtk-cmdq-mailbox.c

Change in v4:
- change clk array to bulk_clk_data array

Change in v3:
- fix #mbox-cless number in dts

Change in v2:
- remove the second clock in dts and add alias id for gce node
- find the other gce node and get it's clock

jason-jh.lin (5):
  dt-bindings: mailbox: add definition for mt8195
  dt-bindings: gce: add gce header file for mt8195
  arm64: dts: mt8195: add gce node
  mailbox: cmdq: add mediatek mailbox support for mt8195
  mailbox: cmdq: add multi-gce clocks support for mt8195

 .../devicetree/bindings/mailbox/mtk-gce.txt   |   8 +-
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      |  22 +
 drivers/mailbox/mtk-cmdq-mailbox.c            | 100 ++-
 include/dt-bindings/gce/mt8195-gce.h          | 812 ++++++++++++++++++
 4 files changed, 917 insertions(+), 25 deletions(-)
 create mode 100644 include/dt-bindings/gce/mt8195-gce.h

-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 31 00:09:02 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Tue, 31 Aug 2021 15:09:02 +0800
Subject: [PATCH v7 4/5] mailbox: cmdq: add mediatek mailbox support for mt8195
In-Reply-To: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
References: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
Message-ID: <20210831070903.8672-5-jason-jh.lin@mediatek.com>

Add mt8195 compatible name in the driver data of cmdq mailbox driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 8d39b988df9e..a00239f40795 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -620,6 +620,7 @@ static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
 	{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
 	{.compatible = "mediatek,mt8192-gce", .data = (void *)&gce_plat_v5},
+	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v4},
 	{}
 };
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 31 00:09:00 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Tue, 31 Aug 2021 15:09:00 +0800
Subject: [PATCH v7 2/5] dt-bindings: gce: add gce header file for mt8195
In-Reply-To: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
References: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
Message-ID: <20210831070903.8672-3-jason-jh.lin@mediatek.com>

Add gce header file to define the gce subsys id,
hardware event id and constant for mt8195.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 include/dt-bindings/gce/mt8195-gce.h | 812 +++++++++++++++++++++++++++
 1 file changed, 812 insertions(+)
 create mode 100644 include/dt-bindings/gce/mt8195-gce.h

diff --git a/include/dt-bindings/gce/mt8195-gce.h b/include/dt-bindings/gce/mt8195-gce.h
new file mode 100644
index 000000000000..dcfb302b8a5b
--- /dev/null
+++ b/include/dt-bindings/gce/mt8195-gce.h
@@ -0,0 +1,812 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Jason-JH Lin <jason0jh.lin at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8195_H
+#define _DT_BINDINGS_GCE_MT8195_H
+
+/* assign timeout 0 also means default */
+#define CMDQ_NO_TIMEOUT		0xffffffff
+#define CMDQ_TIMEOUT_DEFAULT	1000
+
+/* GCE thread priority */
+#define CMDQ_THR_PRIO_LOWEST	0
+#define CMDQ_THR_PRIO_1		1
+#define CMDQ_THR_PRIO_2		2
+#define CMDQ_THR_PRIO_3		3
+#define CMDQ_THR_PRIO_4		4
+#define CMDQ_THR_PRIO_5		5
+#define CMDQ_THR_PRIO_6		6
+#define CMDQ_THR_PRIO_HIGHEST	7
+
+/* CPR count in 32bit register */
+#define GCE_CPR_COUNT		1312
+
+/* GCE subsys table */
+#define SUBSYS_1400XXXX		0
+#define SUBSYS_1401XXXX		1
+#define SUBSYS_1402XXXX		2
+#define SUBSYS_1c00XXXX		3
+#define SUBSYS_1c01XXXX		4
+#define SUBSYS_1c02XXXX		5
+#define SUBSYS_1c10XXXX		6
+#define SUBSYS_1c11XXXX		7
+#define SUBSYS_1c12XXXX		8
+#define SUBSYS_14f0XXXX		9
+#define SUBSYS_14f1XXXX		10
+#define SUBSYS_14f2XXXX		11
+#define SUBSYS_1800XXXX		12
+#define SUBSYS_1801XXXX		13
+#define SUBSYS_1802XXXX		14
+#define SUBSYS_1803XXXX		15
+#define SUBSYS_1032XXXX		16
+#define SUBSYS_1033XXXX		17
+#define SUBSYS_1600XXXX		18
+#define SUBSYS_1601XXXX		19
+#define SUBSYS_14e0XXXX		20
+#define SUBSYS_1c20XXXX		21
+#define SUBSYS_1c30XXXX		22
+#define SUBSYS_1c40XXXX		23
+#define SUBSYS_1c50XXXX		24
+#define SUBSYS_1c60XXXX		25
+
+/* GCE General Purpose Register (GPR) support */
+#define GCE_GPR_R00		0x0
+#define GCE_GPR_R01		0x1
+#define GCE_GPR_R02		0x2
+#define GCE_GPR_R03		0x3
+#define GCE_GPR_R04		0x4
+#define GCE_GPR_R05		0x5
+#define GCE_GPR_R06		0x6
+#define GCE_GPR_R07		0x7
+#define GCE_GPR_R08		0x8
+#define GCE_GPR_R09		0x9
+#define GCE_GPR_R10		0xa
+#define GCE_GPR_R11		0xb
+#define GCE_GPR_R12		0xc
+#define GCE_GPR_R13		0xd
+#define GCE_GPR_R14		0xe
+#define GCE_GPR_R15		0xf
+
+/* GCE hw event id */
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_0	1
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_1	2
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_2	3
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_3	4
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_4	5
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_5	6
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_6	7
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_7	8
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_8	9
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_9	10
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_10	11
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_11	12
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_12	13
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_13	14
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW0_14	15
+#define CMDQ_EVENT_TRAW0_DMA_ERROR_INT	16
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_0	17
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_1	18
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_2	19
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_3	20
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_4	21
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_5	22
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_6	23
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_7	24
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_8	25
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_9	26
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_10	27
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_11	28
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_12	29
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_13	30
+#define CMDQ_EVENT_CQ_THR_DONE_TRAW1_14	31
+#define CMDQ_EVENT_TRAW1_DMA_ERROR_INT	32
+
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_0	65
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_1	66
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_2	67
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_3	68
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_4	69
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_5	70
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_6	71
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_7	72
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_8	73
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_9	74
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_10	75
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_11	76
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_12	77
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_13	78
+#define CMDQ_EVENT_DIP0_FRAME_DONE_P2_14	79
+#define CMDQ_EVENT_DIP0_DMA_ERR	80
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_0	81
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_1	82
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_2	83
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_3	84
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_4	85
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_5	86
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_6	87
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_7	88
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_8	89
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_9	90
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_10	91
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_11	92
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_12	93
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_13	94
+#define CMDQ_EVENT_PQA0_FRAME_DONE_P2_14	95
+#define CMDQ_EVENT_PQA0_DMA_ERR	96
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_0	97
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_1	98
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_2	99
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_3	100
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_4	101
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_5	102
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_6	103
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_7	104
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_8	105
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_9	106
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_10	107
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_11	108
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_12	109
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_13	110
+#define CMDQ_EVENT_PQB0_FRAME_DONE_P2_14	111
+#define CMDQ_EVENT_PQB0_DMA_ERR	112
+#define CMDQ_EVENT_DIP0_DUMMY_0	113
+#define CMDQ_EVENT_DIP0_DUMMY_1	114
+#define CMDQ_EVENT_DIP0_DUMMY_2	115
+#define CMDQ_EVENT_DIP0_DUMMY_3	116
+#define CMDQ_EVENT_WPE0_EIS_GCE_FRAME_DONE	117
+#define CMDQ_EVENT_WPE0_EIS_DONE_SYNC_OUT	118
+#define CMDQ_EVENT_WPE0_TNR_GCE_FRAME_DONE	119
+#define CMDQ_EVENT_WPE0_TNR_DONE_SYNC_OUT	120
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_0	121
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_1	122
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_2	123
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_3	124
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_4	125
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_5	126
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_6	127
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_7	128
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_8	129
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_9	130
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_10	131
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_11	132
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_12	133
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_13	134
+#define CMDQ_EVENT_WPE0_EIS_FRAME_DONE_P2_14	135
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_0	136
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_1	137
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_2	138
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_3	139
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_4	140
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_5	141
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_6	142
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_7	143
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_8	144
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_9	145
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_10	146
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_11	147
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_12	148
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_13	149
+#define CMDQ_EVENT_WPE0_TNR_FRAME_DONE_P2_14	150
+#define CMDQ_EVENT_WPE0_DUMMY_0	151
+#define CMDQ_EVENT_IMGSYS_IPE_DUMMY	152
+#define CMDQ_EVENT_IMGSYS_IPE_FDVT_DONE	153
+#define CMDQ_EVENT_IMGSYS_IPE_ME_DONE	154
+#define CMDQ_EVENT_IMGSYS_IPE_DVS_DONE	155
+#define CMDQ_EVENT_IMGSYS_IPE_DVP_DONE	156
+
+#define CMDQ_EVENT_TPR_0	194
+#define CMDQ_EVENT_TPR_1	195
+#define CMDQ_EVENT_TPR_2	196
+#define CMDQ_EVENT_TPR_3	197
+#define CMDQ_EVENT_TPR_4	198
+#define CMDQ_EVENT_TPR_5	199
+#define CMDQ_EVENT_TPR_6	200
+#define CMDQ_EVENT_TPR_7	201
+#define CMDQ_EVENT_TPR_8	202
+#define CMDQ_EVENT_TPR_9	203
+#define CMDQ_EVENT_TPR_10	204
+#define CMDQ_EVENT_TPR_11	205
+#define CMDQ_EVENT_TPR_12	206
+#define CMDQ_EVENT_TPR_13	207
+#define CMDQ_EVENT_TPR_14	208
+#define CMDQ_EVENT_TPR_15	209
+#define CMDQ_EVENT_TPR_16	210
+#define CMDQ_EVENT_TPR_17	211
+#define CMDQ_EVENT_TPR_18	212
+#define CMDQ_EVENT_TPR_19	213
+#define CMDQ_EVENT_TPR_20	214
+#define CMDQ_EVENT_TPR_21	215
+#define CMDQ_EVENT_TPR_22	216
+#define CMDQ_EVENT_TPR_23	217
+#define CMDQ_EVENT_TPR_24	218
+#define CMDQ_EVENT_TPR_25	219
+#define CMDQ_EVENT_TPR_26	220
+#define CMDQ_EVENT_TPR_27	221
+#define CMDQ_EVENT_TPR_28	222
+#define CMDQ_EVENT_TPR_29	223
+#define CMDQ_EVENT_TPR_30	224
+#define CMDQ_EVENT_TPR_31	225
+#define CMDQ_EVENT_TPR_TIMEOUT_0	226
+#define CMDQ_EVENT_TPR_TIMEOUT_1	227
+#define CMDQ_EVENT_TPR_TIMEOUT_2	228
+#define CMDQ_EVENT_TPR_TIMEOUT_3	229
+#define CMDQ_EVENT_TPR_TIMEOUT_4	230
+#define CMDQ_EVENT_TPR_TIMEOUT_5	231
+#define CMDQ_EVENT_TPR_TIMEOUT_6	232
+#define CMDQ_EVENT_TPR_TIMEOUT_7	233
+#define CMDQ_EVENT_TPR_TIMEOUT_8	234
+#define CMDQ_EVENT_TPR_TIMEOUT_9	235
+#define CMDQ_EVENT_TPR_TIMEOUT_10	236
+#define CMDQ_EVENT_TPR_TIMEOUT_11	237
+#define CMDQ_EVENT_TPR_TIMEOUT_12	238
+#define CMDQ_EVENT_TPR_TIMEOUT_13	239
+#define CMDQ_EVENT_TPR_TIMEOUT_14	240
+#define CMDQ_EVENT_TPR_TIMEOUT_15	241
+
+#define CMDQ_EVENT_VPP0_MDP_RDMA_SOF	256
+#define CMDQ_EVENT_VPP0_MDP_FG_SOF	257
+#define CMDQ_EVENT_VPP0_STITCH_SOF	258
+#define CMDQ_EVENT_VPP0_MDP_HDR_SOF	259
+#define CMDQ_EVENT_VPP0_MDP_AAL_SOF	260
+#define CMDQ_EVENT_VPP0_MDP_RSZ_IN_RSZ_SOF	261
+#define CMDQ_EVENT_VPP0_MDP_TDSHP_SOF	262
+#define CMDQ_EVENT_VPP0_DISP_COLOR_SOF	263
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_SOF	264
+#define CMDQ_EVENT_VPP0_VPP_PADDING_IN_PADDING_SOF	265
+#define CMDQ_EVENT_VPP0_MDP_TCC_IN_SOF	266
+#define CMDQ_EVENT_VPP0_MDP_WROT_SOF	267
+
+#define CMDQ_EVENT_VPP0_WARP0_MMSYS_TOP_RELAY_SOF_PRE	269
+#define CMDQ_EVENT_VPP0_WARP1_MMSYS_TOP_RELAY_SOF_PRE	270
+#define CMDQ_EVENT_VPP0_VPP1_MMSYS_TOP_RELAY_SOF	271
+#define CMDQ_EVENT_VPP0_VPP1_IN_MMSYS_TOP_RELAY_SOF_PRE	272
+
+#define CMDQ_EVENT_VPP0_MDP_RDMA_FRAME_DONE	288
+#define CMDQ_EVENT_VPP0_MDP_FG_TILE_DONE	289
+#define CMDQ_EVENT_VPP0_STITCH_FRAME_DONE	290
+#define CMDQ_EVENT_VPP0_MDP_HDR_FRAME_DONE	291
+#define CMDQ_EVENT_VPP0_MDP_AAL_FRAME_DONE	292
+#define CMDQ_EVENT_VPP0_MDP_RSZ_FRAME_DONE	293
+#define CMDQ_EVENT_VPP0_MDP_TDSHP_FRAME_DONE	294
+#define CMDQ_EVENT_VPP0_DISP_COLOR_FRAME_DONE	295
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_FRAME_DONE	296
+#define CMDQ_EVENT_VPP0_VPP_PADDING_IN_PADDING_FRAME_DONE	297
+#define CMDQ_EVENT_VPP0_MDP_TCC_TCC_FRAME_DONE	298
+#define CMDQ_EVENT_VPP0_MDP_WROT_VIDO_WDONE	299
+
+#define CMDQ_EVENT_VPP0_STREAM_DONE_0	320
+#define CMDQ_EVENT_VPP0_STREAM_DONE_1	321
+#define CMDQ_EVENT_VPP0_STREAM_DONE_2	322
+#define CMDQ_EVENT_VPP0_STREAM_DONE_3	323
+#define CMDQ_EVENT_VPP0_STREAM_DONE_4	324
+#define CMDQ_EVENT_VPP0_STREAM_DONE_5	325
+#define CMDQ_EVENT_VPP0_STREAM_DONE_6	326
+#define CMDQ_EVENT_VPP0_STREAM_DONE_7	327
+#define CMDQ_EVENT_VPP0_STREAM_DONE_8	328
+#define CMDQ_EVENT_VPP0_STREAM_DONE_9	329
+#define CMDQ_EVENT_VPP0_STREAM_DONE_10	330
+#define CMDQ_EVENT_VPP0_STREAM_DONE_11	331
+#define CMDQ_EVENT_VPP0_STREAM_DONE_12	332
+#define CMDQ_EVENT_VPP0_STREAM_DONE_13	333
+#define CMDQ_EVENT_VPP0_STREAM_DONE_14	334
+#define CMDQ_EVENT_VPP0_STREAM_DONE_15	335
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_0	336
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_1	337
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_2	338
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_3	339
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_4	340
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_5	341
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_6	342
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_7	343
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_8	344
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_9	345
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_10	346
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_11	347
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_12	348
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_13	349
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_14	350
+#define CMDQ_EVENT_VPP0_BUF_UNDERRUN_15	351
+#define CMDQ_EVENT_VPP0_MDP_RDMA_SW_RST_DONE	352
+#define CMDQ_EVENT_VPP0_MDP_RDMA_PM_VALID	353
+#define CMDQ_EVENT_VPP0_DISP_OVL_NOAFBC_FRAME_RESET_DONE_PULSE	354
+#define CMDQ_EVENT_VPP0_MDP_WROT_SW_RST_DONE	355
+
+#define CMDQ_EVENT_VPP1_HDMI_META_SOF		384
+#define CMDQ_EVENT_VPP1_DGI_SOF			385
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_SOF		386
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_TCC_SOF	387
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RDMA_SOF	388
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_SOF	389
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_SOF	390
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_FG_SOF	391
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_FG_SOF	392
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_FG_SOF	393
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_HDR_SOF	394
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_HDR_SOF	395
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_HDR_SOF	396
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_AAL_SOF	397
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_AAL_SOF	398
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_AAL_SOF	399
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RSZ_SOF	400
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RSZ_SOF	401
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RSZ_SOF	402
+#define CMDQ_EVENT_VPP1_SVPP1_TDSHP_SOF		403
+#define CMDQ_EVENT_VPP1_SVPP2_TDSHP_SOF		404
+#define CMDQ_EVENT_VPP1_SVPP3_TDSHP_SOF		405
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_MERGE_SOF	406
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_MERGE_SOF	407
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_COLOR_SOF	408
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_COLOR_SOF	409
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_COLOR_SOF	410
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_OVL_SOF	411
+#define CMDQ_EVENT_VPP1_SVPP1_VPP_PAD_SOF	412
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_PAD_SOF	413
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_PAD_SOF	414
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_SOF	415
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_SOF	416
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_SOF	417
+#define CMDQ_EVENT_VPP1_VPP0_DL_IRLY_SOF	418
+#define CMDQ_EVENT_VPP1_VPP0_DL_ORLY_SOF	419
+#define CMDQ_EVENT_VPP1_VDO0_DL_ORLY_0_SOF	420
+#define CMDQ_EVENT_VPP1_VDO0_DL_ORLY_1_SOF	421
+#define CMDQ_EVENT_VPP1_VDO1_DL_ORLY_0_SOF	422
+#define CMDQ_EVENT_VPP1_VDO1_DL_ORLY_1_SOF	423
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RDMA_FRAME_DONE	424
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_FRAME_DONE	425
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_FRAME_DONE	426
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_FRAME_DONE	427
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_FRAME_DONE	428
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_FRAME_DONE	429
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_OVL_FRAME_DONE	430
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_RSZ_FRAME_DONE	431
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_RSZ_FRAME_DONE	432
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_RSZ_FRAME_DONE	433
+#define CMDQ_EVENT_VPP1_FRAME_DONE_10	434
+#define CMDQ_EVENT_VPP1_FRAME_DONE_11	435
+#define CMDQ_EVENT_VPP1_FRAME_DONE_12	436
+#define CMDQ_EVENT_VPP1_FRAME_DONE_13	437
+#define CMDQ_EVENT_VPP1_FRAME_DONE_14	438
+#define CMDQ_EVENT_VPP1_STREAM_DONE_0	439
+#define CMDQ_EVENT_VPP1_STREAM_DONE_1	440
+#define CMDQ_EVENT_VPP1_STREAM_DONE_2	441
+#define CMDQ_EVENT_VPP1_STREAM_DONE_3	442
+#define CMDQ_EVENT_VPP1_STREAM_DONE_4	443
+#define CMDQ_EVENT_VPP1_STREAM_DONE_5	444
+#define CMDQ_EVENT_VPP1_STREAM_DONE_6	445
+#define CMDQ_EVENT_VPP1_STREAM_DONE_7	446
+#define CMDQ_EVENT_VPP1_STREAM_DONE_8	447
+#define CMDQ_EVENT_VPP1_STREAM_DONE_9	448
+#define CMDQ_EVENT_VPP1_STREAM_DONE_10	449
+#define CMDQ_EVENT_VPP1_STREAM_DONE_11	450
+#define CMDQ_EVENT_VPP1_STREAM_DONE_12	451
+#define CMDQ_EVENT_VPP1_STREAM_DONE_13	452
+#define CMDQ_EVENT_VPP1_STREAM_DONE_14	453
+#define CMDQ_EVENT_VPP1_STREAM_DONE_15	454
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_0	455
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_1	456
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_2	457
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_3	458
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_4	459
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_5	460
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_6	461
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_7	462
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_8	463
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_9	464
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_10	465
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_11	466
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_12	467
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_13	468
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_14	469
+#define CMDQ_EVENT_VPP1_MDP_BUF_UNDERRUN_15	470
+#define CMDQ_EVENT_VPP1_DGI_0	471
+#define CMDQ_EVENT_VPP1_DGI_1	472
+#define CMDQ_EVENT_VPP1_DGI_2	473
+#define CMDQ_EVENT_VPP1_DGI_3	474
+#define CMDQ_EVENT_VPP1_DGI_4	475
+#define CMDQ_EVENT_VPP1_DGI_5	476
+#define CMDQ_EVENT_VPP1_DGI_6	477
+#define CMDQ_EVENT_VPP1_DGI_7	478
+#define CMDQ_EVENT_VPP1_DGI_8	479
+#define CMDQ_EVENT_VPP1_DGI_9	480
+#define CMDQ_EVENT_VPP1_DGI_10	481
+#define CMDQ_EVENT_VPP1_DGI_11	482
+#define CMDQ_EVENT_VPP1_DGI_12	483
+#define CMDQ_EVENT_VPP1_DGI_13	484
+#define CMDQ_EVENT_VPP1_SVPP3_VPP_MERGE	485
+#define CMDQ_EVENT_VPP1_SVPP2_VPP_MERGE	486
+#define CMDQ_EVENT_VPP1_MDP_OVL_FRAME_RESET_DONE_PULSE	487
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_DGI	488
+#define CMDQ_EVENT_VPP1_VPP_SPLIT_HDMI	489
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_SW_RST_DONE	490
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_SW_RST_DONE	491
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_SW_RST_DONE	492
+#define CMDQ_EVENT_VPP1_SVPP3_MDP_FG_TILE_DONE	493
+#define CMDQ_EVENT_VPP1_SVPP2_MDP_FG_TILE_DONE	494
+#define CMDQ_EVENT_VPP1_SVPP1_MDP_FG_TILE_DONE	495
+
+#define CMDQ_EVENT_VDO0_DISP_OVL0_SOF	512
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_SOF	513
+#define CMDQ_EVENT_VDO0_DISP_RDMA0_SOF	514
+#define CMDQ_EVENT_VDO0_DISP_COLOR0_SOF	515
+#define CMDQ_EVENT_VDO0_DISP_CCORR0_SOF	516
+#define CMDQ_EVENT_VDO0_DISP_AAL0_SOF	517
+#define CMDQ_EVENT_VDO0_DISP_GAMMA0_SOF	518
+#define CMDQ_EVENT_VDO0_DISP_DITHER0_SOF	519
+#define CMDQ_EVENT_VDO0_DSI0_SOF	520
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C0_SOF	521
+#define CMDQ_EVENT_VDO0_DISP_OVL1_SOF	522
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_SOF	523
+#define CMDQ_EVENT_VDO0_DISP_RDMA1_SOF	524
+#define CMDQ_EVENT_VDO0_DISP_COLOR1_SOF	525
+#define CMDQ_EVENT_VDO0_DISP_CCORR1_SOF	526
+#define CMDQ_EVENT_VDO0_DISP_AAL1_SOF	527
+#define CMDQ_EVENT_VDO0_DISP_GAMMA1_SOF	528
+#define CMDQ_EVENT_VDO0_DISP_DITHER1_SOF	529
+#define CMDQ_EVENT_VDO0_DSI1_SOF	530
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C1_SOF	531
+#define CMDQ_EVENT_VDO0_VPP_MERGE0_SOF	532
+#define CMDQ_EVENT_VDO0_DP_INTF0_SOF	533
+#define CMDQ_EVENT_VDO0_VPP1_DL_RELAY0_SOF	534
+#define CMDQ_EVENT_VDO0_VPP1_DL_RELAY1_SOF	535
+#define CMDQ_EVENT_VDO0_VDO1_DL_RELAY2_SOF	536
+#define CMDQ_EVENT_VDO0_VDO0_DL_RELAY3_SOF	537
+#define CMDQ_EVENT_VDO0_VDO0_DL_RELAY4_SOF	538
+#define CMDQ_EVENT_VDO0_DISP_PWM0_SOF	539
+#define CMDQ_EVENT_VDO0_DISP_PWM1_SOF	540
+
+#define CMDQ_EVENT_VDO0_DISP_OVL0_FRAME_DONE	544
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_FRAME_DONE	545
+#define CMDQ_EVENT_VDO0_DISP_RDMA0_FRAME_DONE	546
+#define CMDQ_EVENT_VDO0_DISP_COLOR0_FRAME_DONE	547
+#define CMDQ_EVENT_VDO0_DISP_CCORR0_FRAME_DONE	548
+#define CMDQ_EVENT_VDO0_DISP_AAL0_FRAME_DONE	549
+#define CMDQ_EVENT_VDO0_DISP_GAMMA0_FRAME_DONE	550
+#define CMDQ_EVENT_VDO0_DISP_DITHER0_FRAME_DONE	551
+#define CMDQ_EVENT_VDO0_DSI0_FRAME_DONE	552
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C0_FRAME_DONE	553
+#define CMDQ_EVENT_VDO0_DISP_OVL1_FRAME_DONE	554
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_FRAME_DONE	555
+#define CMDQ_EVENT_VDO0_DISP_RDMA1_FRAME_DONE	556
+#define CMDQ_EVENT_VDO0_DISP_COLOR1_FRAME_DONE	557
+#define CMDQ_EVENT_VDO0_DISP_CCORR1_FRAME_DONE	558
+#define CMDQ_EVENT_VDO0_DISP_AAL1_FRAME_DONE	559
+#define CMDQ_EVENT_VDO0_DISP_GAMMA1_FRAME_DONE	560
+#define CMDQ_EVENT_VDO0_DISP_DITHER1_FRAME_DONE	561
+#define CMDQ_EVENT_VDO0_DSI1_FRAME_DONE	562
+#define CMDQ_EVENT_VDO0_DSC_WRAP0C1_FRAME_DONE	563
+
+#define CMDQ_EVENT_VDO0_DP_INTF0_FRAME_DONE	565
+
+#define CMDQ_EVENT_VDO0_DISP_SMIASSERT_ENG	576
+#define CMDQ_EVENT_VDO0_DSI0_IRQ_ENG_EVENT_MM	577
+#define CMDQ_EVENT_VDO0_DSI0_TE_ENG_EVENT_MM	578
+#define CMDQ_EVENT_VDO0_DSI0_DONE_ENG_EVENT_MM	579
+#define CMDQ_EVENT_VDO0_DSI0_SOF_ENG_EVENT_MM	580
+#define CMDQ_EVENT_VDO0_DSI0_VACTL_ENG_EVENT_MM	581
+#define CMDQ_EVENT_VDO0_DSI1_IRQ_ENG_EVENT_MM	582
+#define CMDQ_EVENT_VDO0_DSI1_TE_ENG_EVENT_MM	583
+#define CMDQ_EVENT_VDO0_DSI1_DONE_ENG_EVENT_MM	584
+#define CMDQ_EVENT_VDO0_DSI1_SOF_ENG_EVENT_MM	585
+#define CMDQ_EVENT_VDO0_DSI1_VACTL_ENG_EVENT_MM	586
+#define CMDQ_EVENT_VDO0_DISP_WDMA0_SW_RST_DONE_ENG	587
+#define CMDQ_EVENT_VDO0_DISP_WDMA1_SW_RST_DONE_ENG	588
+#define CMDQ_EVENT_VDO0_DISP_OVL0_RST_DONE_ENG	589
+#define CMDQ_EVENT_VDO0_DISP_OVL1_RST_DONE_ENG	590
+#define CMDQ_EVENT_VDO0_DP_INTF0_VSYNC_START_ENG_EVENT_MM	591
+#define CMDQ_EVENT_VDO0_DP_INTF0_VSYNC_END_ENG_EVENT_MM	592
+#define CMDQ_EVENT_VDO0_DP_INTF0_VDE_START_ENG_EVENT_MM	593
+#define CMDQ_EVENT_VDO0_DP_INTF0_VDE_END_ENG_EVENT_MM	594
+#define CMDQ_EVENT_VDO0_DP_INTF0_TARGET_LINE_ENG_EVENT_MM	595
+#define CMDQ_EVENT_VDO0_VPP_MERGE0_ENG	596
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0	597
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_1	598
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_2	599
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_3	600
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_4	601
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_5	602
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_6	603
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_7	604
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_8	605
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_9	606
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_10	607
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_11	608
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_12	609
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_13	610
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_14	611
+#define CMDQ_EVENT_VDO0_DISP_STREAM_DONE_15	612
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_0	613
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_1	614
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_2	615
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_3	616
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_4	617
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_5	618
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_6	619
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_7	620
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_8	621
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_9	622
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_10	623
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_11	624
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_12	625
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_13	626
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_14	627
+#define CMDQ_EVENT_VDO0_DISP_BUF_UNDERRUN_15	628
+
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_SOF	640
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_SOF	641
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_SOF	642
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_SOF	643
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_SOF	644
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_SOF	645
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_SOF	646
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_SOF	647
+#define CMDQ_EVENT_VDO1_VPP_MERGE0_SOF	648
+#define CMDQ_EVENT_VDO1_VPP_MERGE1_SOF	649
+#define CMDQ_EVENT_VDO1_VPP_MERGE2_SOF	650
+#define CMDQ_EVENT_VDO1_VPP_MERGE3_SOF	651
+#define CMDQ_EVENT_VDO1_VPP_MERGE4_SOF	652
+#define CMDQ_EVENT_VDO1_VPP2_DL_RELAY_SOF	653
+#define CMDQ_EVENT_VDO1_VPP3_DL_RELAY_SOF	654
+#define CMDQ_EVENT_VDO1_VDO0_DSC_DL_ASYNC_SOF	655
+#define CMDQ_EVENT_VDO1_VDO0_MERGE_DL_ASYNC_SOF	656
+#define CMDQ_EVENT_VDO1_OUT_DL_RELAY_SOF	657
+#define CMDQ_EVENT_VDO1_DISP_MIXER_SOF	658
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE0_SOF	659
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_SOF	660
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_SOF	661
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_SOF	662
+#define CMDQ_EVENT_VDO1_HDR_VDO_BE0_SOF	663
+#define CMDQ_EVENT_VDO1_HDR_MLOAD_SOF	664
+
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_FRAME_DONE	672
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_FRAME_DONE	673
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_FRAME_DONE	674
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_FRAME_DONE	675
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_FRAME_DONE	676
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_FRAME_DONE	677
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_FRAME_DONE	678
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_FRAME_DONE	679
+#define CMDQ_EVENT_VDO1_VPP_MERGE0_FRAME_DONE	680
+#define CMDQ_EVENT_VDO1_VPP_MERGE1_FRAME_DONE	681
+#define CMDQ_EVENT_VDO1_VPP_MERGE2_FRAME_DONE	682
+#define CMDQ_EVENT_VDO1_VPP_MERGE3_FRAME_DONE	683
+#define CMDQ_EVENT_VDO1_VPP_MERGE4_FRAME_DONE	684
+#define CMDQ_EVENT_VDO1_DPI0_FRAME_DONE	685
+#define CMDQ_EVENT_VDO1_DPI1_FRAME_DONE	686
+#define CMDQ_EVENT_VDO1_DP_INTF0_FRAME_DONE	687
+#define CMDQ_EVENT_VDO1_DISP_MIXER_FRAME_DONE_MM	688
+
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_0	704
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_1	705
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_2	706
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_3	707
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_4	708
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_5	709
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_6	710
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_7	711
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_8	712
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_9	713
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_10	714
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_11	715
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_12	716
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_13	717
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_14	718
+#define CMDQ_EVENT_VDO1_STREAM_DONE_ENG_15	719
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_0	720
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_1	721
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_2	722
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_3	723
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_4	724
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_5	725
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_6	726
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_7	727
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_8	728
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_9	729
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_10	730
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_11	731
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_12	732
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_13	733
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_14	734
+#define CMDQ_EVENT_VDO1_BUF_UNDERRUN_ENG_15	735
+#define CMDQ_EVENT_VDO1_MDP_RDMA0_SW_RST_DONE	736
+#define CMDQ_EVENT_VDO1_MDP_RDMA1_SW_RST_DONE	737
+#define CMDQ_EVENT_VDO1_MDP_RDMA2_SW_RST_DONE	738
+#define CMDQ_EVENT_VDO1_MDP_RDMA3_SW_RST_DONE	739
+#define CMDQ_EVENT_VDO1_MDP_RDMA4_SW_RST_DONE	740
+#define CMDQ_EVENT_VDO1_MDP_RDMA5_SW_RST_DONE	741
+#define CMDQ_EVENT_VDO1_MDP_RDMA6_SW_RST_DONE	742
+#define CMDQ_EVENT_VDO1_MDP_RDMA7_SW_RST_DONE	743
+
+#define CMDQ_EVENT_VDO1_DP0_VDE_END_ENG_EVENT_MM	745
+#define CMDQ_EVENT_VDO1_DP0_VDE_START_ENG_EVENT_MM	746
+#define CMDQ_EVENT_VDO1_DP0_VSYNC_END_ENG_EVENT_MM	747
+#define CMDQ_EVENT_VDO1_DP0_VSYNC_START_ENG_EVENT_MM	748
+#define CMDQ_EVENT_VDO1_DP0_TARGET_LINE_ENG_EVENT_MM	749
+#define CMDQ_EVENT_VDO1_VPP_MERGE0	750
+#define CMDQ_EVENT_VDO1_VPP_MERGE1	751
+#define CMDQ_EVENT_VDO1_VPP_MERGE2	752
+#define CMDQ_EVENT_VDO1_VPP_MERGE3	753
+#define CMDQ_EVENT_VDO1_VPP_MERGE4	754
+#define CMDQ_EVENT_VDO1_HDMITX	755
+#define CMDQ_EVENT_VDO1_HDR_VDO_BE0_ADL_TRIG_EVENT_MM	756
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_THDR_ADL_TRIG_EVENT_MM	757
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE1_DM_ADL_TRIG_EVENT_MM	758
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_THDR_ADL_TRIG_EVENT_MM	759
+#define CMDQ_EVENT_VDO1_HDR_GFX_FE0_DM_ADL_TRIG_EVENT_MM	760
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_ADL_TRIG_EVENT_MM	761
+#define CMDQ_EVENT_VDO1_HDR_VDO_FE1_AD0_TRIG_EVENT_MM	762
+
+#define CMDQ_EVENT_CAM_A_PASS1_DONE	769
+#define CMDQ_EVENT_CAM_B_PASS1_DONE	770
+#define CMDQ_EVENT_GCAMSV_A_PASS1_DONE	771
+#define CMDQ_EVENT_GCAMSV_B_PASS1_DONE	772
+#define CMDQ_EVENT_MRAW_0_PASS1_DONE	773
+#define CMDQ_EVENT_MRAW_1_PASS1_DONE	774
+#define CMDQ_EVENT_MRAW_2_PASS1_DONE	775
+#define CMDQ_EVENT_MRAW_3_PASS1_DONE	776
+#define CMDQ_EVENT_SENINF_CAM0_FIFO_FULL_X	777
+#define CMDQ_EVENT_SENINF_CAM1_FIFO_FULL_X	778
+#define CMDQ_EVENT_SENINF_CAM2_FIFO_FULL	779
+#define CMDQ_EVENT_SENINF_CAM3_FIFO_FULL	780
+#define CMDQ_EVENT_SENINF_CAM4_FIFO_FULL	781
+#define CMDQ_EVENT_SENINF_CAM5_FIFO_FULL	782
+#define CMDQ_EVENT_SENINF_CAM6_FIFO_FULL	783
+#define CMDQ_EVENT_SENINF_CAM7_FIFO_FULL	784
+#define CMDQ_EVENT_SENINF_CAM8_FIFO_FULL	785
+#define CMDQ_EVENT_SENINF_CAM9_FIFO_FULL	786
+#define CMDQ_EVENT_SENINF_CAM10_FIFO_FULL_X	787
+#define CMDQ_EVENT_SENINF_CAM11_FIFO_FULL_X	788
+#define CMDQ_EVENT_SENINF_CAM12_FIFO_FULL_X	789
+#define CMDQ_EVENT_SENINF_CAM13_FIFO_FULL_X	790
+#define CMDQ_EVENT_TG_OVRUN_MRAW0_INT_X0	791
+#define CMDQ_EVENT_TG_OVRUN_MRAW1_INT_X0	792
+#define CMDQ_EVENT_TG_OVRUN_MRAW2_INT	793
+#define CMDQ_EVENT_TG_OVRUN_MRAW3_INT	794
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW0_INT	795
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW1_INT	796
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW2_INT	797
+#define CMDQ_EVENT_DMA_R1_ERROR_MRAW3_INT	798
+#define CMDQ_EVENT_U_CAMSYS_PDA_IRQO_EVENT_DONE_D1	799
+#define CMDQ_EVENT_SUBB_TG_INT4	800
+#define CMDQ_EVENT_SUBB_TG_INT3	801
+#define CMDQ_EVENT_SUBB_TG_INT2	802
+#define CMDQ_EVENT_SUBB_TG_INT1	803
+#define CMDQ_EVENT_SUBA_TG_INT4	804
+#define CMDQ_EVENT_SUBA_TG_INT3	805
+#define CMDQ_EVENT_SUBA_TG_INT2	806
+#define CMDQ_EVENT_SUBA_TG_INT1	807
+#define CMDQ_EVENT_SUBB_DRZS4NO_R1_LOW_LATENCY_LINE_CNT_INT	808
+#define CMDQ_EVENT_SUBB_YUVO_R3_LOW_LATENCY_LINE_CNT_INT	809
+#define CMDQ_EVENT_SUBB_YUVO_R1_LOW_LATENCY_LINE_CNT_INT	810
+#define CMDQ_EVENT_SUBB_IMGO_R1_LOW_LATENCY_LINE_CNT_INT	811
+#define CMDQ_EVENT_SUBA_DRZS4NO_R1_LOW_LATENCY_LINE_CNT_INT	812
+#define CMDQ_EVENT_SUBA_YUVO_R3_LOW_LATENCY_LINE_CNT_INT	813
+#define CMDQ_EVENT_SUBA_YUVO_R1_LOW_LATENCY_LINE_CNT_INT	814
+#define CMDQ_EVENT_SUBA_IMGO_R1_LOW_LATENCY_LINE_CNT_INT	815
+#define CMDQ_EVENT_GCE1_SOF_0	816
+#define CMDQ_EVENT_GCE1_SOF_1	817
+#define CMDQ_EVENT_GCE1_SOF_2	818
+#define CMDQ_EVENT_GCE1_SOF_3	819
+#define CMDQ_EVENT_GCE1_SOF_4	820
+#define CMDQ_EVENT_GCE1_SOF_5	821
+#define CMDQ_EVENT_GCE1_SOF_6	822
+#define CMDQ_EVENT_GCE1_SOF_7	823
+#define CMDQ_EVENT_GCE1_SOF_8	824
+#define CMDQ_EVENT_GCE1_SOF_9	825
+#define CMDQ_EVENT_GCE1_SOF_10	826
+#define CMDQ_EVENT_GCE1_SOF_11	827
+#define CMDQ_EVENT_GCE1_SOF_12	828
+#define CMDQ_EVENT_GCE1_SOF_13	829
+#define CMDQ_EVENT_GCE1_SOF_14	830
+#define CMDQ_EVENT_GCE1_SOF_15	831
+
+#define CMDQ_EVENT_VDEC_LAT_LINE_COUNT_THRESHOLD_INTERRUPT	832
+#define CMDQ_EVENT_VDEC_LAT_VDEC_INT	833
+#define CMDQ_EVENT_VDEC_LAT_VDEC_PAUSE	834
+#define CMDQ_EVENT_VDEC_LAT_VDEC_DEC_ERROR	835
+#define CMDQ_EVENT_VDEC_LAT_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	836
+#define CMDQ_EVENT_VDEC_LAT_VDEC_FRAME_DONE	837
+#define CMDQ_EVENT_VDEC_LAT_INI_FETCH_RDY	838
+#define CMDQ_EVENT_VDEC_LAT_PROCESS_FLAG	839
+#define CMDQ_EVENT_VDEC_LAT_SEARCH_START_CODE_DONE	840
+#define CMDQ_EVENT_VDEC_LAT_REF_REORDER_DONE	841
+#define CMDQ_EVENT_VDEC_LAT_WP_TBLE_DONE	842
+#define CMDQ_EVENT_VDEC_LAT_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	843
+#define CMDQ_EVENT_VDEC_LAT_GCE_CNT_OP_THRESHOLD	847
+
+#define CMDQ_EVENT_VDEC_LAT1_LINE_COUNT_THRESHOLD_INTERRUPT	848
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_INT	849
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_PAUSE	850
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_DEC_ERROR	851
+#define CMDQ_EVENT_VDEC_LAT1_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	852
+#define CMDQ_EVENT_VDEC_LAT1_VDEC_FRAME_DONE	853
+#define CMDQ_EVENT_VDEC_LAT1_INI_FETCH_RDY	854
+#define CMDQ_EVENT_VDEC_LAT1_PROCESS_FLAG	855
+#define CMDQ_EVENT_VDEC_LAT1_SEARCH_START_CODE_DONE	856
+#define CMDQ_EVENT_VDEC_LAT1_REF_REORDER_DONE	857
+#define CMDQ_EVENT_VDEC_LAT1_WP_TBLE_DONE	858
+#define CMDQ_EVENT_VDEC_LAT1_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	859
+#define CMDQ_EVENT_VDEC_LAT1_GCE_CNT_OP_THRESHOLD	863
+
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_0	864
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_1	865
+
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_8	872
+#define CMDQ_EVENT_VDEC_SOC_GLOBAL_CON_250_9	873
+
+#define CMDQ_EVENT_VDEC_CORE_LINE_COUNT_THRESHOLD_INTERRUPT	896
+#define CMDQ_EVENT_VDEC_CORE_VDEC_INT	897
+#define CMDQ_EVENT_VDEC_CORE_VDEC_PAUSE	898
+#define CMDQ_EVENT_VDEC_CORE_VDEC_DEC_ERROR	899
+#define CMDQ_EVENT_VDEC_CORE_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	900
+#define CMDQ_EVENT_VDEC_CORE_VDEC_FRAME_DONE	901
+#define CMDQ_EVENT_VDEC_CORE_INI_FETCH_RDY	902
+#define CMDQ_EVENT_VDEC_CORE_PROCESS_FLAG	903
+#define CMDQ_EVENT_VDEC_CORE_SEARCH_START_CODE_DONE	904
+#define CMDQ_EVENT_VDEC_CORE_REF_REORDER_DONE	905
+#define CMDQ_EVENT_VDEC_CORE_WP_TBLE_DONE	906
+#define CMDQ_EVENT_VDEC_CORE_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	907
+#define CMDQ_EVENT_VDEC_CORE_GCE_CNT_OP_THRESHOLD	911
+
+#define CMDQ_EVENT_VDEC_CORE1_LINE_COUNT_THRESHOLD_INTERRUPT	912
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_INT	913
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_PAUSE	914
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_DEC_ERROR	915
+#define CMDQ_EVENT_VDEC_CORE1_MC_BUSY_OVERFLOW_MDEC_TIMEOUT	916
+#define CMDQ_EVENT_VDEC_CORE1_VDEC_FRAME_DONE	917
+#define CMDQ_EVENT_VDEC_CORE1_INI_FETCH_RDY	918
+#define CMDQ_EVENT_VDEC_CORE1_PROCESS_FLAG	919
+#define CMDQ_EVENT_VDEC_CORE1_SEARCH_START_CODE_DONE	920
+#define CMDQ_EVENT_VDEC_CORE1_REF_REORDER_DONE	921
+#define CMDQ_EVENT_VDEC_CORE1_WP_TBLE_DONE	922
+#define CMDQ_EVENT_VDEC_CORE1_COUNT_SRAM_CLR_DONE_AND_CTX_SRAM_CLR_DONE	923
+#define CMDQ_EVENT_VDEC_CORE1_CNT_OP_THRESHOLD	927
+
+#define CMDQ_EVENT_VENC_TOP_FRAME_DONE	929
+#define CMDQ_EVENT_VENC_TOP_PAUSE_DONE	930
+#define CMDQ_EVENT_VENC_TOP_JPGENC_DONE	931
+#define CMDQ_EVENT_VENC_TOP_MB_DONE	932
+#define CMDQ_EVENT_VENC_TOP_128BYTE_DONE	933
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_DONE	934
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_C1_DONE	935
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_INSUFF_DONE	936
+#define CMDQ_EVENT_VENC_TOP_JPGDEC_C1_INSUFF_DONE	937
+#define CMDQ_EVENT_VENC_TOP_WP_2ND_STAGE_DONE	938
+#define CMDQ_EVENT_VENC_TOP_WP_3RD_STAGE_DONE	939
+#define CMDQ_EVENT_VENC_TOP_PPS_HEADER_DONE	940
+#define CMDQ_EVENT_VENC_TOP_SPS_HEADER_DONE	941
+#define CMDQ_EVENT_VENC_TOP_VPS_HEADER_DONE	942
+
+#define CMDQ_EVENT_VENC_CORE1_TOP_FRAME_DONE	945
+#define CMDQ_EVENT_VENC_CORE1_TOP_PAUSE_DONE	946
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGENC_DONE	947
+#define CMDQ_EVENT_VENC_CORE1_TOP_MB_DONE	948
+#define CMDQ_EVENT_VENC_CORE1_TOP_128BYTE_DONE	949
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_DONE	950
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_C1_DONE	951
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_INSUFF_DONE	952
+#define CMDQ_EVENT_VENC_CORE1_TOP_JPGDEC_C1_INSUFF_DONE	953
+#define CMDQ_EVENT_VENC_CORE1_TOP_WP_2ND_STAGE_DONE	954
+#define CMDQ_EVENT_VENC_CORE1_TOP_WP_3RD_STAGE_DONE	955
+#define CMDQ_EVENT_VENC_CORE1_TOP_PPS_HEADER_DONE	956
+#define CMDQ_EVENT_VENC_CORE1_TOP_SPS_HEADER_DONE	957
+#define CMDQ_EVENT_VENC_CORE1_TOP_VPS_HEADER_DONE	958
+
+#define CMDQ_EVENT_WPE_VPP0_WPE_GCE_FRAME_DONE	962
+#define CMDQ_EVENT_WPE_VPP0_WPE_DONE_SYNC_OUT	963
+
+#define CMDQ_EVENT_WPE_VPP1_WPE_GCE_FRAME_DONE	969
+#define CMDQ_EVENT_WPE_VPP1_WPE_DONE_SYNC_OUT	970
+
+#define CMDQ_EVENT_DP_TX_VBLANK_FALLING	994
+#define CMDQ_EVENT_DP_TX_VSC_FINISH	995
+
+#define CMDQ_EVENT_OUTPIN_0	1018
+#define CMDQ_EVENT_OUTPIN_1	1019
+
+/* end of hw event */
+#define CMDQ_MAX_HW_EVENT				1019
+
+#endif
-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 31 00:08:59 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Tue, 31 Aug 2021 15:08:59 +0800
Subject: [PATCH v7 1/5] dt-bindings: mailbox: add definition for mt8195
In-Reply-To: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
References: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
Message-ID: <20210831070903.8672-2-jason-jh.lin@mediatek.com>

Add definition of compatible and dt-binding header for mt8195.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 Documentation/devicetree/bindings/mailbox/mtk-gce.txt | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index ac4245050d17..8e81916556a3 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -10,7 +10,7 @@ mailbox.txt for generic information about mailbox device-tree bindings.
 
 Required properties:
 - compatible: can be "mediatek,mt8173-gce", "mediatek,mt8183-gce",
-  "mediatek,mt8192-gce" or "mediatek,mt6779-gce".
+  "mediatek,mt8192-gce", "mediatek,mt8195-gce" or "mediatek,mt6779-gce".
 - reg: Address range of the GCE unit
 - interrupts: The interrupt signal from the GCE block
 - clock: Clocks according to the common clock binding
@@ -36,9 +36,9 @@ Optional properties for a client device:
   size: the total size of register address that GCE can access.
 
 Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h',
-'dt-binding/gce/mt8183-gce.h', 'dt-binding/gce/mt8192-gce.h' or
-'dt-bindings/gce/mt6779-gce.h'. Such as
-sub-system ids, thread priority, event ids.
+'dt-binding/gce/mt8183-gce.h', 'dt-binding/gce/mt8192-gce.h',
+'dt-binding/gce/mt8195-gce.h' or 'dt-bindings/gce/mt6779-gce.h'.
+Such as sub-system ids, thread priority, event ids.
 
 Example:
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 31 00:09:03 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Tue, 31 Aug 2021 15:09:03 +0800
Subject: [PATCH v7 5/5] mailbox: cmdq: add multi-gce clocks support for mt8195
In-Reply-To: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
References: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
Message-ID: <20210831070903.8672-6-jason-jh.lin@mediatek.com>

For the design of GCE hardware event signal transportation,
evnet rx will send the event signal to all GCE event merges
after receiving the event signal from the other hardware.

Because GCE event merges need to response to event rx, their
clocks must be enabled at that time.

To make sure all the gce clock is enabled while receiving the
hardware event, each cmdq mailbox should enable or disable
the others gce clk at the same time.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c | 101 ++++++++++++++++++++++-------
 1 file changed, 79 insertions(+), 22 deletions(-)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index a00239f40795..f3b562df2c5d 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -19,6 +19,7 @@
 
 #define CMDQ_OP_CODE_MASK		(0xff << CMDQ_OP_CODE_SHIFT)
 #define CMDQ_NUM_CMD(t)			(t->cmd_buf_size / CMDQ_INST_SIZE)
+#define CMDQ_GCE_NUM_MAX		(2)
 
 #define CMDQ_CURR_IRQ_STATUS		0x10
 #define CMDQ_SYNC_TOKEN_UPDATE		0x68
@@ -75,16 +76,18 @@ struct cmdq {
 	u32			thread_nr;
 	u32			irq_mask;
 	struct cmdq_thread	*thread;
-	struct clk		*clock;
+	struct clk_bulk_data	clocks[CMDQ_GCE_NUM_MAX];
 	bool			suspended;
 	u8			shift_pa;
 	bool			control_by_sw;
+	u32			gce_num;
 };
 
 struct gce_plat {
 	u32 thread_nr;
 	u8 shift;
 	bool control_by_sw;
+	u32 gce_num;
 };
 
 u8 cmdq_get_shift_pa(struct mbox_chan *chan)
@@ -124,13 +127,13 @@ static void cmdq_init(struct cmdq *cmdq)
 {
 	int i;
 
-	WARN_ON(clk_enable(cmdq->clock) < 0);
+	WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
 	if (cmdq->control_by_sw)
 		writel(0x7, cmdq->base + GCE_GCTL_VALUE);
 	writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
 	for (i = 0; i <= CMDQ_MAX_EVENT; i++)
 		writel(i, cmdq->base + CMDQ_SYNC_TOKEN_UPDATE);
-	clk_disable(cmdq->clock);
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 }
 
 static int cmdq_thread_reset(struct cmdq *cmdq, struct cmdq_thread *thread)
@@ -268,7 +271,7 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
 
 	if (list_empty(&thread->task_busy_list)) {
 		cmdq_thread_disable(cmdq, thread);
-		clk_disable(cmdq->clock);
+		clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 	}
 }
 
@@ -313,7 +316,7 @@ static int cmdq_suspend(struct device *dev)
 	if (task_running)
 		dev_warn(dev, "exist running task(s) in suspend\n");
 
-	clk_unprepare(cmdq->clock);
+	clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
 
 	return 0;
 }
@@ -322,7 +325,7 @@ static int cmdq_resume(struct device *dev)
 {
 	struct cmdq *cmdq = dev_get_drvdata(dev);
 
-	WARN_ON(clk_prepare(cmdq->clock) < 0);
+	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
 	cmdq->suspended = false;
 	return 0;
 }
@@ -331,8 +334,7 @@ static int cmdq_remove(struct platform_device *pdev)
 {
 	struct cmdq *cmdq = platform_get_drvdata(pdev);
 
-	clk_unprepare(cmdq->clock);
-
+	clk_bulk_unprepare(cmdq->gce_num, cmdq->clocks);
 	return 0;
 }
 
@@ -358,7 +360,8 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
 	task->pkt = pkt;
 
 	if (list_empty(&thread->task_busy_list)) {
-		WARN_ON(clk_enable(cmdq->clock) < 0);
+		WARN_ON(clk_bulk_enable(cmdq->gce_num, cmdq->clocks));
+
 		/*
 		 * The thread reset will clear thread related register to 0,
 		 * including pc, end, priority, irq, suspend and enable. Thus
@@ -430,7 +433,8 @@ static void cmdq_mbox_shutdown(struct mbox_chan *chan)
 	}
 
 	cmdq_thread_disable(cmdq, thread);
-	clk_disable(cmdq->clock);
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
+
 done:
 	/*
 	 * The thread->task_busy_list empty means thread already disable. The
@@ -475,7 +479,7 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout)
 
 	cmdq_thread_resume(thread);
 	cmdq_thread_disable(cmdq, thread);
-	clk_disable(cmdq->clock);
+	clk_bulk_disable(cmdq->gce_num, cmdq->clocks);
 
 out:
 	spin_unlock_irqrestore(&thread->chan->lock, flags);
@@ -524,6 +528,10 @@ static int cmdq_probe(struct platform_device *pdev)
 	struct cmdq *cmdq;
 	int err, i;
 	struct gce_plat *plat_data;
+	struct device_node *phandle = dev->of_node;
+	struct device_node *node;
+	int alias_id = 0;
+	char clk_name[4] = "gce";
 
 	cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL);
 	if (!cmdq)
@@ -547,6 +555,7 @@ static int cmdq_probe(struct platform_device *pdev)
 	cmdq->thread_nr = plat_data->thread_nr;
 	cmdq->shift_pa = plat_data->shift;
 	cmdq->control_by_sw = plat_data->control_by_sw;
+	cmdq->gce_num = plat_data->gce_num;
 	cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0);
 	err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
 			       "mtk_cmdq", cmdq);
@@ -558,10 +567,28 @@ static int cmdq_probe(struct platform_device *pdev)
 	dev_dbg(dev, "cmdq device: addr:0x%p, va:0x%p, irq:%d\n",
 		dev, cmdq->base, cmdq->irq);
 
-	cmdq->clock = devm_clk_get(dev, "gce");
-	if (IS_ERR(cmdq->clock)) {
-		dev_err(dev, "failed to get gce clk\n");
-		return PTR_ERR(cmdq->clock);
+	if (cmdq->gce_num > 1) {
+		for_each_child_of_node(phandle->parent, node) {
+			char clk_id[8];
+
+			alias_id = of_alias_get_id(node, clk_name);
+			if (alias_id < cmdq->gce_num) {
+				snprintf(clk_id, sizeof(clk_id), "%s%d", clk_name, alias_id);
+				cmdq->clocks[alias_id].id = clk_id;
+				cmdq->clocks[alias_id].clk = of_clk_get(node, 0);
+				if (IS_ERR(cmdq->clocks[alias_id].clk)) {
+					dev_err(dev, "failed to get gce clk: %d\n", alias_id);
+					return PTR_ERR(cmdq->clocks[alias_id].clk);
+				}
+			}
+		}
+	} else {
+		cmdq->clocks[alias_id].id = clk_name;
+		cmdq->clocks[alias_id].clk = devm_clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(cmdq->clocks[alias_id].clk)) {
+			dev_err(dev, "failed to get gce clk\n");
+			return PTR_ERR(cmdq->clocks[alias_id].clk);
+		}
 	}
 
 	cmdq->mbox.dev = dev;
@@ -597,7 +624,8 @@ static int cmdq_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, cmdq);
-	WARN_ON(clk_prepare(cmdq->clock) < 0);
+
+	WARN_ON(clk_bulk_prepare(cmdq->gce_num, cmdq->clocks));
 
 	cmdq_init(cmdq);
 
@@ -609,18 +637,47 @@ static const struct dev_pm_ops cmdq_pm_ops = {
 	.resume = cmdq_resume,
 };
 
-static const struct gce_plat gce_plat_v2 = {.thread_nr = 16};
-static const struct gce_plat gce_plat_v3 = {.thread_nr = 24};
-static const struct gce_plat gce_plat_v4 = {.thread_nr = 24, .shift = 3};
-static const struct gce_plat gce_plat_v5 = {.thread_nr = 24, .shift = 3,
-					    .control_by_sw = true};
+static const struct gce_plat gce_plat_v2 = {
+	.thread_nr = 16,
+	.shift = 0,
+	.control_by_sw = false,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v3 = {
+	.thread_nr = 24,
+	.shift = 0,
+	.control_by_sw = false,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v4 = {
+	.thread_nr = 24,
+	.shift = 3,
+	.control_by_sw = false,
+	.gce_num = 1
+};
+
+static const struct gce_plat gce_plat_v5 = {
+	.thread_nr = 24,
+	.shift = 3,
+	.control_by_sw = true,
+	.gce_num = 2
+};
+
+static const struct gce_plat gce_plat_v6 = {
+	.thread_nr = 24,
+	.shift = 3,
+	.control_by_sw = false,
+	.gce_num = 2
+};
 
 static const struct of_device_id cmdq_of_ids[] = {
 	{.compatible = "mediatek,mt8173-gce", .data = (void *)&gce_plat_v2},
 	{.compatible = "mediatek,mt8183-gce", .data = (void *)&gce_plat_v3},
 	{.compatible = "mediatek,mt6779-gce", .data = (void *)&gce_plat_v4},
 	{.compatible = "mediatek,mt8192-gce", .data = (void *)&gce_plat_v5},
-	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v4},
+	{.compatible = "mediatek,mt8195-gce", .data = (void *)&gce_plat_v6},
 	{}
 };
 
-- 
2.18.0

From jason-jh.lin at mediatek.com  Tue Aug 31 00:09:01 2021
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Tue, 31 Aug 2021 15:09:01 +0800
Subject: [PATCH v7 3/5] arm64: dts: mt8195: add gce node
In-Reply-To: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
References: <20210831070903.8672-1-jason-jh.lin@mediatek.com>
Message-ID: <20210831070903.8672-4-jason-jh.lin@mediatek.com>

Add gce node and gce alias on mt8195 dts file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index c146a91c6272..47c44cb77da0 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include <dt-bindings/clock/mt8195-clk.h>
+#include <dt-bindings/gce/mt8195-gce.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/power/mt8195-power.h>
@@ -16,6 +17,11 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		gce0 = &gce0;
+		gce1 = &gce1;
+	};
+
 	clocks {
 		clk26m: oscillator0 {
 			compatible = "fixed-clock";
@@ -699,6 +705,22 @@
 			#clock-cells = <1>;
 		};
 
+		gce0: mdp_mailbox at 10320000 {
+			compatible = "mediatek,mt8195-gce";
+			reg = <0 0x10320000 0 0x4000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_GCE>;
+		};
+
+		gce1: disp_mailbox at 10330000 {
+			compatible = "mediatek,mt8195-gce";
+			reg = <0 0x10330000 0 0x4000>;
+			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_GCE2>;
+		};
+
 		scp_adsp: syscon at 10720000 {
 			compatible = "mediatek,mt8195-scp_adsp", "syscon";
 			reg = <0 0x10720000 0 0x1000>;
-- 
2.18.0

From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:44 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:44 +0800
Subject: [v5 01/15] iio: adc: aspeed: set driver data when adc probe.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-2-billy_tsai@aspeedtech.com>

Fix the issue when adc remove will get the null driver data.

Fixed: commit 573803234e72 ("iio: Aspeed ADC")
Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 19efaa41bc34..34ec0c28b2df 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -183,6 +183,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	platform_set_drvdata(pdev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->base))
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:49 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:49 +0800
Subject: [v5 06/15] iio: adc: aspeed: Add vref config function
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-7-billy_tsai@aspeedtech.com>

Add the function to check the vref_fixed_mv and set the value to driver
data.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 6ce2f676c54a..01df24f6d3f1 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -130,7 +130,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = data->model_data->vref_fixed_mv;
+		*val = data->vref_mv;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -195,6 +195,17 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	if (data->model_data->vref_fixed_mv) {
+		data->vref_mv = data->model_data->vref_fixed_mv;
+		return 0;
+	}
+	return 0;
+}
+
 static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
@@ -250,6 +261,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
+	ret = aspeed_adc_vref_config(indio_dev);
+	if (ret)
+		goto vref_config_error;
+
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
@@ -298,6 +313,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
 poll_timeout_error:
+vref_config_error:
 	reset_control_assert(data->rst);
 reset_error:
 	clk_hw_unregister_divider(data->clk_scaler);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:43 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:43 +0800
Subject: [v5 00/15] Add support for ast2600 ADC
Message-ID: <20210831071458.2334-1-billy_tsai@aspeedtech.com>

This patch serials make aspeed_adc.c can support ast2600 and backward
compatible.

Change since v4:
dt-bindings:
  - Add clocks maxItems.
  - Rename the property to meet the property-units.yaml.
  - Add the description for the difference between adc0 and adc1.
aspeed_adc.c:
  - Use new property name to get internal reference voltage: units from mv to
  uv.
  - Fix -Wnonnull warning caused by snprintf parameters.
  - Add suffix mv to the vref parameters.
  - Use ARRAY_SIZE instead of 32.
  - Add a reset action for ADC power down and Use devm_iio_device_register.
  - Fix typo error.
  - Separate the offset interface of ch7 when battery sensing enable

Change since v3:
dt-bindings:
  - Fix properties:aspeed,int_vref_mv type error.

Change since v2:
dt-bindings:
  - Create a new dt-bindings for ast2600 adc
aspeed_adc.c:
  - Splits the patch for more details
  - Remove version enum and use the flags in model data to distinguish
  hardware feature
  - Support trimming data get and set.
  - Use devm_add_action_or_reset to simplify probe error handling.

Changes since v1:
dt-bindings:
  - Fix the aspeed,adc.yaml check error.
  - Add battery-sensing property.
aspeed_adc.c:
  - Change the init flow:
    Clock and reference voltage setting should be completed before adc
    engine enable.
  - Change the default sampling rate to meet most user case.
  - Add patch #8 to suppoert battery sensing mode.

Billy Tsai (15):
  iio: adc: aspeed: set driver data when adc probe.
  dt-bindings: iio: adc: Add ast2600-adc bindings
  iio: adc: aspeed: completes the bitfield declare.
  iio: adc: aspeed: Keep model data to driver data.
  iio: adc: aspeed: Refactory model data structure
  iio: adc: aspeed: Add vref config function
  iio: adc: aspeed: Set num_channels with model data
  iio: adc: aspeed: Use model_data to set clk scaler.
  iio: adc: aspeed: Use devm_add_action_or_reset.
  iio: adc: aspeed: Support ast2600 adc.
  iio: adc: aspeed: Fix the calculate error of clock.
  iio: adc: aspeed: Add func to set sampling rate.
  iio: adc: aspeed: Add compensation phase.
  iio: adc: aspeed: Support battery sensing.
  iio: adc: aspeed: Get and set trimming data.

 .../bindings/iio/adc/aspeed,ast2600-adc.yaml  | 100 +++
 drivers/iio/adc/aspeed_adc.c                  | 617 +++++++++++++++---
 2 files changed, 619 insertions(+), 98 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml

-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:45 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:45 +0800
Subject: [v5 02/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-3-billy_tsai@aspeedtech.com>

Add device tree bindings document for the aspeed ast2600 adc device
driver.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 .../bindings/iio/adc/aspeed,ast2600-adc.yaml  | 100 ++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml

diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
new file mode 100644
index 000000000000..b283c8ca2bbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ADC that forms part of an ASPEED server management processor.
+
+maintainers:
+  - Billy Tsai <billy_tsai at aspeedtech.com>
+
+description: |
+  ? 10-bits resolution for 16 voltage channels.
+  ? The device split into two individual engine and each contains 8 voltage
+  channels.
+  ? Channel scanning can be non-continuous.
+  ? Programmable ADC clock frequency.
+  ? Programmable upper and lower threshold for each channels.
+  ? Interrupt when larger or less than threshold for each channels.
+  ? Support hysteresis for each channels.
+  ? Built-in a compensating method.
+  ? Built-in a register to trim internal reference voltage.
+  ? Internal or External reference voltage.
+  ? Support 2 Internal reference voltage 1.2v or 2.5v.
+  ? Integrate dividing circuit for battery sensing.
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2600-adc0
+      - aspeed,ast2600-adc1
+    description:
+      Their trimming data, which is used to calibrate internal reference volage,
+      locates in different address of OTP.
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description:
+      Input clock used to derive the sample clock. Expected to be the
+      SoC's APB clock.
+
+  resets:
+    maxItems: 1
+
+  "#io-channel-cells":
+    const: 1
+
+  vref-supply:
+    description:
+      The external regulator supply ADC reference voltage.
+
+  aspeed,int-vref-microvolt:
+    enum: [1200000, 2500000]
+    description:
+      ADC internal reference voltage in microvolts.
+
+  aspeed,battery-sensing:
+    type: boolean
+    description:
+      Inform the driver that last channel will be used to sensor battery.
+
+  aspeed,trim-data-valid:
+    type: boolean
+    description: |
+      The ADC reference voltage can be calibrated to obtain the trimming
+      data which will be stored in otp. This property informs the driver that
+      the data store in the otp is valid.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+  - "#io-channel-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/ast2600-clock.h>
+    adc0: adc at 1e6e9000 {
+        compatible = "aspeed,ast2600-adc0";
+        reg = <0x1e6e9000 0x100>;
+        clocks = <&syscon ASPEED_CLK_APB2>;
+        resets = <&syscon ASPEED_RESET_ADC>;
+        #io-channel-cells = <1>;
+        aspeed,int-vref-microvolt = <2500000>;
+    };
+    adc1: adc at 1e6e9100 {
+        compatible = "aspeed,ast2600-adc1";
+        reg = <0x1e6e9100 0x100>;
+        clocks = <&syscon ASPEED_CLK_APB2>;
+        resets = <&syscon ASPEED_RESET_ADC>;
+        #io-channel-cells = <1>;
+        aspeed,int-vref-microvolt = <2500000>;
+    };
+...
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:47 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:47 +0800
Subject: [v5 04/15] iio: adc: aspeed: Keep model data to driver data.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-5-billy_tsai@aspeedtech.com>

Keep the model data pointer to driver data for reducing the usage of
of_device_get_match_data().

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f055fe7b2c40..76ae1c3f584b 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -77,6 +77,7 @@ struct aspeed_adc_model_data {
 
 struct aspeed_adc_data {
 	struct device		*dev;
+	const struct aspeed_adc_model_data *model_data;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
 	struct clk_hw		*clk_prescaler;
@@ -118,8 +119,6 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       int *val, int *val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -127,7 +126,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = model_data->vref_voltage;
+		*val = data->model_data->vref_voltage;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -146,13 +145,11 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,
 				int val, int val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val < model_data->min_sampling_rate ||
-			val > model_data->max_sampling_rate)
+		if (val < data->model_data->min_sampling_rate ||
+			val > data->model_data->max_sampling_rate)
 			return -EINVAL;
 
 		clk_set_rate(data->clk_scaler->clk,
@@ -198,7 +195,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
 	struct aspeed_adc_data *data;
-	const struct aspeed_adc_model_data *model_data;
 	const char *clk_parent_name;
 	int ret;
 	u32 adc_engine_control_reg_val;
@@ -209,6 +205,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	data->model_data = of_device_get_match_data(&pdev->dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
@@ -249,9 +246,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-
-	if (model_data->wait_init_sequence) {
+	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
 				  ASPEED_ADC_OP_MODE_NORMAL) |
@@ -281,8 +276,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	writel(adc_engine_control_reg_val,
 	       data->base + ASPEED_REG_ENGINE_CONTROL);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-	indio_dev->name = model_data->model_name;
+	indio_dev->name = data->model_data->model_name;
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:46 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:46 +0800
Subject: [v5 03/15] iio: adc: aspeed: completes the bitfield declare.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-4-billy_tsai@aspeedtech.com>

This patch completes the declare of ADC register bitfields and uses the
same prefix ASPEED_ADC_* for these bitfields. In addition, tidy up space
alignment of the codes.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 64 ++++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 17 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 34ec0c28b2df..f055fe7b2c40 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -3,6 +3,7 @@
  * Aspeed AST2400/2500 ADC
  *
  * Copyright (C) 2017 Google, Inc.
+ * Copyright (C) 2021 Aspeed Technology Inc.
  */
 
 #include <linux/clk.h>
@@ -16,6 +17,7 @@
 #include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/bitfield.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
@@ -28,15 +30,39 @@
 #define ASPEED_REG_INTERRUPT_CONTROL	0x04
 #define ASPEED_REG_VGA_DETECT_CONTROL	0x08
 #define ASPEED_REG_CLOCK_CONTROL	0x0C
-#define ASPEED_REG_MAX			0xC0
-
-#define ASPEED_OPERATION_MODE_POWER_DOWN	(0x0 << 1)
-#define ASPEED_OPERATION_MODE_STANDBY		(0x1 << 1)
-#define ASPEED_OPERATION_MODE_NORMAL		(0x7 << 1)
-
-#define ASPEED_ENGINE_ENABLE		BIT(0)
-
-#define ASPEED_ADC_CTRL_INIT_RDY	BIT(8)
+#define ASPEED_REG_COMPENSATION_TRIM	0xC4
+/*
+ * The register offset between 0xC8~0xCC can be read and won't affect the
+ * hardware logic in each version of ADC.
+ */
+#define ASPEED_REG_MAX			0xD0
+
+#define ASPEED_ADC_ENGINE_ENABLE		BIT(0)
+#define ASPEED_ADC_OP_MODE			GENMASK(3, 1)
+#define ASPEED_ADC_OP_MODE_PWR_DOWN		0
+#define ASPEED_ADC_OP_MODE_STANDBY		1
+#define ASPEED_ADC_OP_MODE_NORMAL		7
+#define ASPEED_ADC_CTRL_COMPENSATION		BIT(4)
+#define ASPEED_ADC_AUTO_COMPENSATION		BIT(5)
+/*
+ * Bit 6 determines not only the reference voltage range but also the dividing
+ * circuit for battery sensing.
+ */
+#define ASPEED_ADC_REF_VOLTAGE			GENMASK(7, 6)
+#define ASPEED_ADC_REF_VOLTAGE_2500mV		0
+#define ASPEED_ADC_REF_VOLTAGE_1200mV		1
+#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH		2
+#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW		3
+#define ASPEED_ADC_BAT_SENSING_DIV		BIT(6)
+#define ASPEED_ADC_BAT_SENSING_DIV_2_3		0
+#define ASPEED_ADC_BAT_SENSING_DIV_1_3		1
+#define ASPEED_ADC_CTRL_INIT_RDY		BIT(8)
+#define ASPEED_ADC_CH7_MODE			BIT(12)
+#define ASPEED_ADC_CH7_NORMAL			0
+#define ASPEED_ADC_CH7_BAT			1
+#define ASPEED_ADC_BAT_SENSING_ENABLE		BIT(13)
+#define ASPEED_ADC_CTRL_CHANNEL			GENMASK(31, 16)
+#define ASPEED_ADC_CTRL_CHANNEL_ENABLE(ch)	FIELD_PREP(ASPEED_ADC_CTRL_CHANNEL, BIT(ch))
 
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
@@ -227,7 +253,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	if (model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
-		writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
+		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+				  ASPEED_ADC_OP_MODE_NORMAL) |
+			       ASPEED_ADC_ENGINE_ENABLE,
 		       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 		/* Wait for initial sequence complete. */
@@ -246,10 +274,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		goto clk_enable_error;
 
-	adc_engine_control_reg_val = GENMASK(31, 16) |
-		ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE;
+	adc_engine_control_reg_val =
+		ASPEED_ADC_CTRL_CHANNEL |
+		FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
+		ASPEED_ADC_ENGINE_ENABLE;
 	writel(adc_engine_control_reg_val,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 	model_data = of_device_get_match_data(&pdev->dev);
 	indio_dev->name = model_data->model_name;
@@ -265,8 +295,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	return 0;
 
 iio_register_error:
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
 poll_timeout_error:
@@ -284,8 +314,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
-		data->base + ASPEED_REG_ENGINE_CONTROL);
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
 	clk_hw_unregister_divider(data->clk_scaler);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:48 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:48 +0800
Subject: [v5 05/15] iio: adc: aspeed: Refactory model data structure
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-6-billy_tsai@aspeedtech.com>

This patch refactors the model data structure to distinguish the
function form different versions of aspeed ADC.
- Rename the vref_voltage to vref_fixed_mv and add vref_mv driver data
When driver probe will check vref_fixed_mv value and store it to vref_mv
which isn't const value.
- Add num_channels
Make num_channles of iio device can be changed by different model_data
- Add need_prescaler flag and scaler_bit_width
The need_prescaler flag is used to tell the driver the clock divider needs
another Prescaler and the scaler_bit_width to set the clock divider
bitfield width.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 76ae1c3f584b..6ce2f676c54a 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -71,8 +71,11 @@ struct aspeed_adc_model_data {
 	const char *model_name;
 	unsigned int min_sampling_rate;	// Hz
 	unsigned int max_sampling_rate;	// Hz
-	unsigned int vref_voltage;	// mV
+	unsigned int vref_fixed_mv;
 	bool wait_init_sequence;
+	bool need_prescaler;
+	u8 scaler_bit_width;
+	unsigned int num_channels;
 };
 
 struct aspeed_adc_data {
@@ -83,6 +86,7 @@ struct aspeed_adc_data {
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
+	int			vref_mv;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -126,7 +130,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = data->model_data->vref_voltage;
+		*val = data->model_data->vref_fixed_mv;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -320,17 +324,23 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 
 static const struct aspeed_adc_model_data ast2400_model_data = {
 	.model_name = "ast2400-adc",
-	.vref_voltage = 2500, // mV
+	.vref_fixed_mv = 2500,
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
+	.need_prescaler = true,
+	.scaler_bit_width = 10,
+	.num_channels = 16,
 };
 
 static const struct aspeed_adc_model_data ast2500_model_data = {
 	.model_name = "ast2500-adc",
-	.vref_voltage = 1800, // mV
+	.vref_fixed_mv = 1800,
 	.min_sampling_rate = 1,
 	.max_sampling_rate = 1000000,
 	.wait_init_sequence = true,
+	.need_prescaler = true,
+	.scaler_bit_width = 10,
+	.num_channels = 16,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:50 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:50 +0800
Subject: [v5 07/15] iio: adc: aspeed: Set num_channels with model data
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-8-billy_tsai@aspeedtech.com>

Use the model_data member num_channels to set the num_channels of iio
device.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 01df24f6d3f1..aec335956310 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -299,7 +299,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-	indio_dev->num_channels = ARRAY_SIZE(aspeed_adc_iio_channels);
+	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
 	if (ret)
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:52 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:52 +0800
Subject: [v5 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-10-billy_tsai@aspeedtech.com>

This patch use devm_add_action_or_reset to handle the error in probe
phase.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 112 +++++++++++++++++++++--------------
 1 file changed, 66 insertions(+), 46 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index e53d1541ad1d..af00d9752c1e 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -195,6 +195,35 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static void aspeed_adc_unregister_divider(void *data)
+{
+	struct clk_hw *clk = data;
+
+	clk_hw_unregister_divider(clk);
+}
+
+static void aspeed_adc_reset_assert(void *data)
+{
+	struct reset_control *rst = data;
+
+	reset_control_assert(rst);
+}
+
+static void aspeed_adc_clk_disable_unprepare(void *data)
+{
+	struct clk *clk = data;
+
+	clk_disable_unprepare(clk);
+}
+
+static void aspeed_adc_power_down(void *data)
+{
+	struct aspeed_adc_data *priv_data = data;
+
+	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+	       priv_data->base + ASPEED_REG_ENGINE_CONTROL);
+}
+
 static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -242,6 +271,11 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			&data->clk_lock);
 		if (IS_ERR(data->clk_prescaler))
 			return PTR_ERR(data->clk_prescaler);
+		ret = devm_add_action_or_reset(data->dev,
+					       aspeed_adc_unregister_divider,
+					       data->clk_prescaler);
+		if (ret)
+			return ret;
 		snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name),
 			 clk_name);
 		scaler_flags = CLK_SET_RATE_PARENT;
@@ -256,23 +290,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
 		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
 		data->model_data->scaler_bit_width, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_scaler)) {
-		ret = PTR_ERR(data->clk_scaler);
-		goto scaler_error;
-	}
+	if (IS_ERR(data->clk_scaler))
+		return PTR_ERR(data->clk_scaler);
+
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
+				       data->clk_scaler);
+	if (ret)
+		return ret;
 
 	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(data->rst)) {
 		dev_err(&pdev->dev,
 			"invalid or missing reset controller device tree entry");
-		ret = PTR_ERR(data->rst);
-		goto reset_error;
+		return PTR_ERR(data->rst);
 	}
 	reset_control_deassert(data->rst);
 
+	ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
+				       data->rst);
+	if (ret)
+		return ret;
+
 	ret = aspeed_adc_vref_config(indio_dev);
 	if (ret)
-		goto vref_config_error;
+		return ret;
 
 	if (data->model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
@@ -281,6 +322,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			       ASPEED_ADC_ENGINE_ENABLE,
 		       data->base + ASPEED_REG_ENGINE_CONTROL);
 
+		ret = devm_add_action_or_reset(data->dev, aspeed_adc_power_down,
+					       data);
+		if (ret)
+			return ret;
 		/* Wait for initial sequence complete. */
 		ret = readl_poll_timeout(data->base + ASPEED_REG_ENGINE_CONTROL,
 					 adc_engine_control_reg_val,
@@ -289,13 +334,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 					 ASPEED_ADC_INIT_POLLING_TIME,
 					 ASPEED_ADC_INIT_TIMEOUT);
 		if (ret)
-			goto poll_timeout_error;
+			return ret;
 	}
 
 	/* Start all channels in normal mode. */
 	ret = clk_prepare_enable(data->clk_scaler->clk);
 	if (ret)
-		goto clk_enable_error;
+		return ret;
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_clk_disable_unprepare,
+				       data->clk_scaler->clk);
+	if (ret)
+		return ret;
 
 	adc_engine_control_reg_val =
 		ASPEED_ADC_CTRL_CHANNEL |
@@ -303,6 +354,11 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		ASPEED_ADC_ENGINE_ENABLE;
 	writel(adc_engine_control_reg_val,
 	       data->base + ASPEED_REG_ENGINE_CONTROL);
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_power_down,
+				       data);
+	if (ret)
+		return ret;
 
 	indio_dev->name = data->model_data->model_name;
 	indio_dev->info = &aspeed_adc_iio_info;
@@ -310,45 +366,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->channels = aspeed_adc_iio_channels;
 	indio_dev->num_channels = data->model_data->num_channels;
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto iio_register_error;
-
-	return 0;
-
-iio_register_error:
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-clk_enable_error:
-poll_timeout_error:
-vref_config_error:
-	reset_control_assert(data->rst);
-reset_error:
-	clk_hw_unregister_divider(data->clk_scaler);
-scaler_error:
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
+	ret = devm_iio_device_register(data->dev, indio_dev);
 	return ret;
 }
 
-static int aspeed_adc_remove(struct platform_device *pdev)
-{
-	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-	struct aspeed_adc_data *data = iio_priv(indio_dev);
-
-	iio_device_unregister(indio_dev);
-	writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
-	       data->base + ASPEED_REG_ENGINE_CONTROL);
-	clk_disable_unprepare(data->clk_scaler->clk);
-	reset_control_assert(data->rst);
-	clk_hw_unregister_divider(data->clk_scaler);
-	if (data->model_data->need_prescaler)
-		clk_hw_unregister_divider(data->clk_prescaler);
-
-	return 0;
-}
-
 static const struct aspeed_adc_model_data ast2400_model_data = {
 	.model_name = "ast2400-adc",
 	.vref_fixed_mv = 2500,
@@ -379,7 +400,6 @@ MODULE_DEVICE_TABLE(of, aspeed_adc_matches);
 
 static struct platform_driver aspeed_adc_driver = {
 	.probe = aspeed_adc_probe,
-	.remove = aspeed_adc_remove,
 	.driver = {
 		.name = KBUILD_MODNAME,
 		.of_match_table = aspeed_adc_matches,
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:51 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:51 +0800
Subject: [v5 08/15] iio: adc: aspeed: Use model_data to set clk scaler.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-9-billy_tsai@aspeedtech.com>

This patch uses need_prescaler and scaler_bit_width to set the ADC clock
scaler.

Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 43 ++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index aec335956310..e53d1541ad1d 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -210,9 +210,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
 	struct aspeed_adc_data *data;
-	const char *clk_parent_name;
 	int ret;
 	u32 adc_engine_control_reg_val;
+	unsigned long scaler_flags = 0;
+	char clk_name[32], clk_parent_name[32];
 
 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
 	if (!indio_dev)
@@ -229,24 +230,32 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	/* Register ADC clock prescaler with source specified by device tree. */
 	spin_lock_init(&data->clk_lock);
-	clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
-
-	data->clk_prescaler = clk_hw_register_divider(
-				&pdev->dev, "prescaler", clk_parent_name, 0,
-				data->base + ASPEED_REG_CLOCK_CONTROL,
-				17, 15, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_prescaler))
-		return PTR_ERR(data->clk_prescaler);
-
+	snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name), "%s",
+		 of_clk_get_parent_name(pdev->dev.of_node, 0));
+
+	if (data->model_data->need_prescaler) {
+		snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-prescaler",
+			 data->model_data->model_name);
+		data->clk_prescaler = clk_hw_register_divider(
+			&pdev->dev, clk_name, clk_parent_name, 0,
+			data->base + ASPEED_REG_CLOCK_CONTROL, 17, 15, 0,
+			&data->clk_lock);
+		if (IS_ERR(data->clk_prescaler))
+			return PTR_ERR(data->clk_prescaler);
+		snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name),
+			 clk_name);
+		scaler_flags = CLK_SET_RATE_PARENT;
+	}
 	/*
 	 * Register ADC clock scaler downstream from the prescaler. Allow rate
 	 * setting to adjust the prescaler as well.
 	 */
+	snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-scaler",
+		 data->model_data->model_name);
 	data->clk_scaler = clk_hw_register_divider(
-				&pdev->dev, "scaler", "prescaler",
-				CLK_SET_RATE_PARENT,
-				data->base + ASPEED_REG_CLOCK_CONTROL,
-				0, 10, 0, &data->clk_lock);
+		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
+		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
+		data->model_data->scaler_bit_width, 0, &data->clk_lock);
 	if (IS_ERR(data->clk_scaler)) {
 		ret = PTR_ERR(data->clk_scaler);
 		goto scaler_error;
@@ -318,7 +327,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 reset_error:
 	clk_hw_unregister_divider(data->clk_scaler);
 scaler_error:
-	clk_hw_unregister_divider(data->clk_prescaler);
+	if (data->model_data->need_prescaler)
+		clk_hw_unregister_divider(data->clk_prescaler);
 	return ret;
 }
 
@@ -333,7 +343,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
 	clk_hw_unregister_divider(data->clk_scaler);
-	clk_hw_unregister_divider(data->clk_prescaler);
+	if (data->model_data->need_prescaler)
+		clk_hw_unregister_divider(data->clk_prescaler);
 
 	return 0;
 }
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:53 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:53 +0800
Subject: [v5 10/15] iio: adc: aspeed: Support ast2600 adc.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-11-billy_tsai@aspeedtech.com>

Make driver to support ast2600 adc device.
- Use shared reset controller
- Complete the vref configure function
- Add the model data for ast2600 adc

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 105 +++++++++++++++++++++++++++++++++--
 1 file changed, 99 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index af00d9752c1e..40b7ba58c1dc 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Aspeed AST2400/2500 ADC
+ * Aspeed AST2400/2500/2600 ADC
  *
  * Copyright (C) 2017 Google, Inc.
  * Copyright (C) 2021 Aspeed Technology Inc.
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
@@ -81,6 +82,7 @@ struct aspeed_adc_model_data {
 struct aspeed_adc_data {
 	struct device		*dev;
 	const struct aspeed_adc_model_data *model_data;
+	struct regulator	*regulator;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
 	struct clk_hw		*clk_prescaler;
@@ -224,14 +226,79 @@ static void aspeed_adc_power_down(void *data)
 	       priv_data->base + ASPEED_REG_ENGINE_CONTROL);
 }
 
+static void aspeed_adc_reg_disable(void *data)
+{
+	struct regulator *reg = data;
+
+	regulator_disable(reg);
+}
+
 static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	int ret;
+	u32 adc_engine_control_reg_val;
 
 	if (data->model_data->vref_fixed_mv) {
 		data->vref_mv = data->model_data->vref_fixed_mv;
 		return 0;
 	}
+	adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+	data->regulator = devm_regulator_get_optional(data->dev, "vref");
+	if (!IS_ERR(data->regulator)) {
+		ret = regulator_enable(data->regulator);
+		if (ret)
+			return ret;
+		ret = devm_add_action_or_reset(
+			data->dev, aspeed_adc_reg_disable, data->regulator);
+		if (ret)
+			return ret;
+		data->vref_mv = regulator_get_voltage(data->regulator);
+		/* Conversion from uV to mV */
+		data->vref_mv /= 1000;
+		if ((data->vref_mv >= 1550) && (data->vref_mv <= 2700))
+			writel(adc_engine_control_reg_val |
+				FIELD_PREP(
+					ASPEED_ADC_REF_VOLTAGE,
+					ASPEED_ADC_REF_VOLTAGE_EXT_HIGH),
+			data->base + ASPEED_REG_ENGINE_CONTROL);
+		else if ((data->vref_mv >= 900) && (data->vref_mv <= 1650))
+			writel(adc_engine_control_reg_val |
+				FIELD_PREP(
+					ASPEED_ADC_REF_VOLTAGE,
+					ASPEED_ADC_REF_VOLTAGE_EXT_LOW),
+			data->base + ASPEED_REG_ENGINE_CONTROL);
+		else {
+			dev_err(data->dev, "Regulator voltage %d not support",
+				data->vref_mv);
+			return -EOPNOTSUPP;
+		}
+	} else {
+		if (PTR_ERR(data->regulator) != -ENODEV)
+			return PTR_ERR(data->regulator);
+		data->vref_mv = 2500000;
+		of_property_read_u32(data->dev->of_node,
+				     "aspeed,int-vref-microvolt",
+				     &data->vref_mv);
+		/* Conversion from uV to mV */
+		data->vref_mv /= 1000;
+		if (data->vref_mv == 2500)
+			writel(adc_engine_control_reg_val |
+				FIELD_PREP(ASPEED_ADC_REF_VOLTAGE,
+						ASPEED_ADC_REF_VOLTAGE_2500mV),
+			data->base + ASPEED_REG_ENGINE_CONTROL);
+		else if (data->vref_mv == 1200)
+			writel(adc_engine_control_reg_val |
+				FIELD_PREP(ASPEED_ADC_REF_VOLTAGE,
+						ASPEED_ADC_REF_VOLTAGE_1200mV),
+			data->base + ASPEED_REG_ENGINE_CONTROL);
+		else {
+			dev_err(data->dev, "Voltage %d not support", data->vref_mv);
+			return -EOPNOTSUPP;
+		}
+	}
+
 	return 0;
 }
 
@@ -298,7 +365,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	data->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
 	if (IS_ERR(data->rst)) {
 		dev_err(&pdev->dev,
 			"invalid or missing reset controller device tree entry");
@@ -316,10 +383,14 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		return ret;
 
 	if (data->model_data->wait_init_sequence) {
+		adc_engine_control_reg_val =
+			readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+		adc_engine_control_reg_val |=
+			FIELD_PREP(ASPEED_ADC_OP_MODE,
+				   ASPEED_ADC_OP_MODE_NORMAL) |
+			ASPEED_ADC_ENGINE_ENABLE;
 		/* Enable engine in normal mode. */
-		writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
-				  ASPEED_ADC_OP_MODE_NORMAL) |
-			       ASPEED_ADC_ENGINE_ENABLE,
+		writel(adc_engine_control_reg_val,
 		       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 		ret = devm_add_action_or_reset(data->dev, aspeed_adc_power_down,
@@ -349,6 +420,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		return ret;
 
 	adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+	adc_engine_control_reg_val |=
 		ASPEED_ADC_CTRL_CHANNEL |
 		FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
 		ASPEED_ADC_ENGINE_ENABLE;
@@ -391,9 +464,29 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
 	.num_channels = 16,
 };
 
+static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
+	.model_name = "ast2600-adc0",
+	.min_sampling_rate = 10000,
+	.max_sampling_rate = 500000,
+	.wait_init_sequence = true,
+	.scaler_bit_width = 16,
+	.num_channels = 8,
+};
+
+static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
+	.model_name = "ast2600-adc1",
+	.min_sampling_rate = 10000,
+	.max_sampling_rate = 500000,
+	.wait_init_sequence = true,
+	.scaler_bit_width = 16,
+	.num_channels = 8,
+};
+
 static const struct of_device_id aspeed_adc_matches[] = {
 	{ .compatible = "aspeed,ast2400-adc", .data = &ast2400_model_data },
 	{ .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data },
+	{ .compatible = "aspeed,ast2600-adc0", .data = &ast2600_adc0_model_data },
+	{ .compatible = "aspeed,ast2600-adc1", .data = &ast2600_adc1_model_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, aspeed_adc_matches);
@@ -409,5 +502,5 @@ static struct platform_driver aspeed_adc_driver = {
 module_platform_driver(aspeed_adc_driver);
 
 MODULE_AUTHOR("Rick Altherr <raltherr at google.com>");
-MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver");
+MODULE_DESCRIPTION("Aspeed AST2400/2500/2600 ADC Driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:54 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:54 +0800
Subject: [v5 11/15] iio: adc: aspeed: Fix the calculate error of clock.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-12-billy_tsai@aspeedtech.com>

The ADC clock formula is
ast2400/2500:
ADC clock period = PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
ast2600:
ADC clock period = PCLK * 2 * (ADC0C[15:0] + 1)
They all have one fixed divided 2 and the legacy driver didn't handle it.
This patch register the fixed factory clock device as the parent of ADC
clock scaler to fix this issue.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 40b7ba58c1dc..349377b9fac0 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -4,6 +4,12 @@
  *
  * Copyright (C) 2017 Google, Inc.
  * Copyright (C) 2021 Aspeed Technology Inc.
+ *
+ * ADC clock formula:
+ * Ast2400/Ast2500:
+ * clock period = period of PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
+ * Ast2600:
+ * clock period = period of PCLK * 2 * (ADC0C[15:0] + 1)
  */
 
 #include <linux/clk.h>
@@ -85,6 +91,7 @@ struct aspeed_adc_data {
 	struct regulator	*regulator;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
+	struct clk_hw		*fixed_div_clk;
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
@@ -204,6 +211,13 @@ static void aspeed_adc_unregister_divider(void *data)
 	clk_hw_unregister_divider(clk);
 }
 
+static void aspeed_adc_unregister_fixed_divider(void *data)
+{
+	struct clk_hw *clk = data;
+
+	clk_hw_unregister_fixed_factor(clk);
+}
+
 static void aspeed_adc_reset_assert(void *data)
 {
 	struct reset_control *rst = data;
@@ -328,6 +342,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	spin_lock_init(&data->clk_lock);
 	snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name), "%s",
 		 of_clk_get_parent_name(pdev->dev.of_node, 0));
+	snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-fixed-div",
+		 data->model_data->model_name);
+	data->fixed_div_clk = clk_hw_register_fixed_factor(
+		&pdev->dev, clk_name, clk_parent_name, 0, 1, 2);
+	if (IS_ERR(data->fixed_div_clk))
+		return PTR_ERR(data->fixed_div_clk);
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_unregister_fixed_divider,
+				       data->clk_prescaler);
+	if (ret)
+		return ret;
+	snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name), clk_name);
 
 	if (data->model_data->need_prescaler) {
 		snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-prescaler",
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:58 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:58 +0800
Subject: [v5 15/15] iio: adc: aspeed: Get and set trimming data.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-16-billy_tsai@aspeedtech.com>

The ADC controller has a trimming register for fine-tune the reference
voltage. The trimming value comes from the OTP register which will be
written during chip production. This patch will read this OTP value and
configure it to the ADC register when the ADC controller probes and using
dts property "aspeed,trim-data-valid" to determine whether to execute this
flow.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 71 ++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index b594a723db2e..fddd7508099f 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -25,6 +25,8 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/bitfield.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
@@ -80,6 +82,11 @@
  */
 #define ASPEED_ADC_DEF_SAMPLING_RATE	65000
 
+struct aspeed_adc_trim_locate {
+	const unsigned int offset;
+	const unsigned int field;
+};
+
 struct aspeed_adc_model_data {
 	const char *model_name;
 	unsigned int min_sampling_rate;	// Hz
@@ -90,6 +97,7 @@ struct aspeed_adc_model_data {
 	bool bat_sense_sup;
 	u8 scaler_bit_width;
 	unsigned int num_channels;
+	const struct aspeed_adc_trim_locate *trim_locate;
 };
 
 struct adc_gain {
@@ -165,6 +173,44 @@ static const struct iio_chan_spec aspeed_adc_iio_bat_channels[] = {
 	ASPEED_BAT_CHAN(7, 0x1E),
 };
 
+static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev)
+{
+	struct device_node *syscon;
+	struct regmap *scu;
+	u32 scu_otp, trimming_val;
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	syscon = of_find_node_by_name(NULL, "syscon");
+	if (syscon == NULL) {
+		dev_warn(data->dev, "Couldn't find syscon node\n");
+		return -EOPNOTSUPP;
+	}
+	scu = syscon_node_to_regmap(syscon);
+	if (IS_ERR(scu)) {
+		dev_warn(data->dev, "Failed to get syscon regmap\n");
+		return -EOPNOTSUPP;
+	}
+	if (data->model_data->trim_locate) {
+		if (regmap_read(scu, data->model_data->trim_locate->offset,
+				&scu_otp)) {
+			dev_warn(data->dev,
+				 "Failed to get adc trimming data\n");
+			trimming_val = 0x8;
+		} else {
+			trimming_val =
+				((scu_otp) &
+				 (data->model_data->trim_locate->field)) >>
+				__ffs(data->model_data->trim_locate->field);
+		}
+		dev_dbg(data->dev,
+			"trimming val = %d, offset = %08x, fields = %08x\n",
+			trimming_val, data->model_data->trim_locate->offset,
+			data->model_data->trim_locate->field);
+		writel(trimming_val, data->base + ASPEED_REG_COMPENSATION_TRIM);
+	}
+	return 0;
+}
+
 static int aspeed_adc_compensation(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -545,6 +591,13 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid",
+			     NULL)) {
+		ret = aspeed_adc_set_trim_data(indio_dev);
+		if (ret)
+			return ret;
+	}
+
 	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
 			     NULL)) {
 		if (data->model_data->bat_sense_sup) {
@@ -616,6 +669,21 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	return ret;
 }
 
+static const struct aspeed_adc_trim_locate ast2500_adc_trim = {
+	.offset = 0x154,
+	.field = GENMASK(31, 28),
+};
+
+static const struct aspeed_adc_trim_locate ast2600_adc0_trim = {
+	.offset = 0x5d0,
+	.field = GENMASK(3, 0),
+};
+
+static const struct aspeed_adc_trim_locate ast2600_adc1_trim = {
+	.offset = 0x5d0,
+	.field = GENMASK(7, 4),
+};
+
 static const struct aspeed_adc_model_data ast2400_model_data = {
 	.model_name = "ast2400-adc",
 	.vref_fixed_mv = 2500,
@@ -635,6 +703,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = {
 	.need_prescaler = true,
 	.scaler_bit_width = 10,
 	.num_channels = 16,
+	.trim_locate = &ast2500_adc_trim,
 };
 
 static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
@@ -645,6 +714,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
 	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
+	.trim_locate = &ast2600_adc0_trim,
 };
 
 static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
@@ -655,6 +725,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
 	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
+	.trim_locate = &ast2600_adc1_trim,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:57 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:57 +0800
Subject: [v5 14/15] iio: adc: aspeed: Support battery sensing.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-15-billy_tsai@aspeedtech.com>

In ast2600, ADC integrate dividing circuit at last input channel for
battery sensing. This patch use the dts property "battery-sensing" to
enable this feature makes the last channel of each adc can tolerance
higher voltage than reference voltage. The offset interface of ch7 will
be separated when enabling the battery sensing mode.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 81 ++++++++++++++++++++++++++++++++++--
 1 file changed, 78 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 121c96de03bd..b594a723db2e 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -87,10 +87,16 @@ struct aspeed_adc_model_data {
 	unsigned int vref_fixed_mv;
 	bool wait_init_sequence;
 	bool need_prescaler;
+	bool bat_sense_sup;
 	u8 scaler_bit_width;
 	unsigned int num_channels;
 };
 
+struct adc_gain {
+	u8 mult;
+	u8 div;
+};
+
 struct aspeed_adc_data {
 	struct device		*dev;
 	const struct aspeed_adc_model_data *model_data;
@@ -104,6 +110,8 @@ struct aspeed_adc_data {
 	int			vref_mv;
 	u32			sample_period_ns;
 	int			cv;
+	bool			battery_sensing;
+	struct adc_gain		battery_mode_gain;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -136,6 +144,27 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+#define ASPEED_BAT_CHAN(_idx, _data_reg_addr) {					\
+		.type = IIO_VOLTAGE,						\
+		.indexed = 1,							\
+		.channel = (_idx),						\
+		.address = (_data_reg_addr),					\
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
+				      BIT(IIO_CHAN_INFO_OFFSET),		\
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |		\
+					    BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+}
+static const struct iio_chan_spec aspeed_adc_iio_bat_channels[] = {
+	ASPEED_CHAN(0, 0x10),
+	ASPEED_CHAN(1, 0x12),
+	ASPEED_CHAN(2, 0x14),
+	ASPEED_CHAN(3, 0x16),
+	ASPEED_CHAN(4, 0x18),
+	ASPEED_CHAN(5, 0x1A),
+	ASPEED_CHAN(6, 0x1C),
+	ASPEED_BAT_CHAN(7, 0x1E),
+};
+
 static int aspeed_adc_compensation(struct iio_dev *indio_dev)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -204,14 +233,39 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       int *val, int *val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	u32 adc_engine_control_reg_val;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		*val = readw(data->base + chan->address);
+		if (data->battery_sensing && chan->channel == 7) {
+			adc_engine_control_reg_val =
+				readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+			writel(adc_engine_control_reg_val |
+				       FIELD_PREP(ASPEED_ADC_CH7_MODE,
+						  ASPEED_ADC_CH7_BAT) |
+				       ASPEED_ADC_BAT_SENSING_ENABLE,
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+			/*
+			 * After enable battery sensing mode need to wait some time for adc stable
+			 * Experiment result is 1ms.
+			 */
+			mdelay(1);
+			*val = readw(data->base + chan->address);
+			*val = (*val * data->battery_mode_gain.mult) /
+			       data->battery_mode_gain.div;
+			/* Restore control register value */
+			writel(adc_engine_control_reg_val,
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		} else
+			*val = readw(data->base + chan->address);
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_OFFSET:
-		*val = data->cv;
+		if (data->battery_sensing && chan->channel == 7)
+			*val = (data->cv * data->battery_mode_gain.mult) /
+			       data->battery_mode_gain.div;
+		else
+			*val = data->cv;
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
@@ -491,6 +545,23 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
+			     NULL)) {
+		if (data->model_data->bat_sense_sup) {
+			data->battery_sensing = 1;
+			if (readl(data->base + ASPEED_REG_ENGINE_CONTROL) &
+			ASPEED_ADC_BAT_SENSING_DIV) {
+				data->battery_mode_gain.mult = 3;
+				data->battery_mode_gain.div = 1;
+			} else {
+				data->battery_mode_gain.mult = 3;
+				data->battery_mode_gain.div = 2;
+			}
+		} else
+			dev_warn(&pdev->dev,
+				"Failed to enable battey-sensing mode\n");
+	}
+
 	if (data->model_data->wait_init_sequence) {
 		adc_engine_control_reg_val =
 			readl(data->base + ASPEED_REG_ENGINE_CONTROL);
@@ -536,7 +607,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	indio_dev->name = data->model_data->model_name;
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->channels = aspeed_adc_iio_channels;
+	indio_dev->channels = data->battery_sensing ?
+					    aspeed_adc_iio_bat_channels :
+					    aspeed_adc_iio_channels;
 	indio_dev->num_channels = data->model_data->num_channels;
 
 	ret = devm_iio_device_register(data->dev, indio_dev);
@@ -569,6 +642,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = {
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
 	.wait_init_sequence = true,
+	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
 };
@@ -578,6 +652,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = {
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
 	.wait_init_sequence = true,
+	.bat_sense_sup = true,
 	.scaler_bit_width = 16,
 	.num_channels = 8,
 };
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:56 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:56 +0800
Subject: [v5 13/15] iio: adc: aspeed: Add compensation phase.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-14-billy_tsai@aspeedtech.com>

This patch adds a compensation phase to improve the accuracy of ADC
measurement. This is the built-in function through input half of the
reference voltage to get the ADC offset.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 54 +++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 1333d7a88427..121c96de03bd 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -103,6 +103,7 @@ struct aspeed_adc_data {
 	struct reset_control	*rst;
 	int			vref_mv;
 	u32			sample_period_ns;
+	int			cv;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -112,7 +113,8 @@ struct aspeed_adc_data {
 	.address = (_data_reg_addr),				\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
-				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+				BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
+				BIT(IIO_CHAN_INFO_OFFSET),	\
 }
 
 static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
@@ -134,6 +136,51 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+static int aspeed_adc_compensation(struct iio_dev *indio_dev)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	u32 index, adc_raw = 0;
+	u32 adc_engine_control_reg_val;
+
+	adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+	adc_engine_control_reg_val &= ~ASPEED_ADC_OP_MODE;
+	adc_engine_control_reg_val |=
+		(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
+		 ASPEED_ADC_ENGINE_ENABLE);
+	/*
+	 * Enable compensating sensing:
+	 * After that, the input voltage of ADC will force to half of the reference
+	 * voltage. So the expected reading raw data will become half of the max
+	 * value. We can get compensating value = 0x200 - ADC read raw value.
+	 * It is recommended to average at least 10 samples to get a final CV.
+	 */
+	writel(adc_engine_control_reg_val | ASPEED_ADC_CTRL_COMPENSATION |
+		       ASPEED_ADC_CTRL_CHANNEL_ENABLE(0),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
+	/*
+	 * After enable compensating sensing mode need to wait some time for ADC stable
+	 * Experiment result is 1ms.
+	 */
+	mdelay(1);
+
+	for (index = 0; index < 16; index++) {
+		/*
+		 * Waiting for the sampling period ensures that the value acquired
+		 * is fresh each time.
+		 */
+		ndelay(data->sample_period_ns);
+		adc_raw += readw(data->base + aspeed_adc_iio_channels[0].address);
+	}
+	adc_raw >>= 4;
+	data->cv = BIT(ASPEED_RESOLUTION_BITS - 1) - adc_raw;
+	writel(adc_engine_control_reg_val,
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
+	dev_dbg(data->dev, "Compensating value = %d\n", data->cv);
+
+	return 0;
+}
+
 static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -163,6 +210,10 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		*val = readw(data->base + chan->address);
 		return IIO_VAL_INT;
 
+	case IIO_CHAN_INFO_OFFSET:
+		*val = data->cv;
+		return IIO_VAL_INT;
+
 	case IIO_CHAN_INFO_SCALE:
 		*val = data->vref_mv;
 		*val2 = ASPEED_RESOLUTION_BITS;
@@ -466,6 +517,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			return ret;
 	}
 
+	aspeed_adc_compensation(indio_dev);
 	/* Start all channels in normal mode. */
 	adc_engine_control_reg_val =
 		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
-- 
2.25.1



From billy_tsai at aspeedtech.com  Tue Aug 31 00:14:55 2021
From: billy_tsai at aspeedtech.com (Billy Tsai)
Date: Tue, 31 Aug 2021 15:14:55 +0800
Subject: [v5 12/15] iio: adc: aspeed: Add func to set sampling rate.
In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
Message-ID: <20210831071458.2334-13-billy_tsai@aspeedtech.com>

Add the function to set the sampling rate and keep the sampling period
for a driver used to wait the fresh value.
In addition, since the ADC clock is required when initializing the ADC
device, move clk_prepare_enable ahead of the initialization phase.

Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 59 ++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 19 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 349377b9fac0..1333d7a88427 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -73,6 +73,12 @@
 
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
+/*
+ * When the sampling rate is too high, the ADC may not have enough charging
+ * time, resulting in a low voltage value. Thus, the default uses a slow
+ * sampling rate for most use cases.
+ */
+#define ASPEED_ADC_DEF_SAMPLING_RATE	65000
 
 struct aspeed_adc_model_data {
 	const char *model_name;
@@ -96,6 +102,7 @@ struct aspeed_adc_data {
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
 	int			vref_mv;
+	u32			sample_period_ns;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -127,6 +134,24 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+	if (rate < data->model_data->min_sampling_rate ||
+	    rate > data->model_data->max_sampling_rate)
+		return -EINVAL;
+	/* Each sampling needs 12 clocks to convert.*/
+	clk_set_rate(data->clk_scaler->clk, rate * ASPEED_CLOCKS_PER_SAMPLE);
+	rate = clk_get_rate(data->clk_scaler->clk);
+	data->sample_period_ns = DIV_ROUND_UP_ULL(
+		(u64)NSEC_PER_SEC * ASPEED_CLOCKS_PER_SAMPLE, rate);
+	dev_dbg(data->dev, "Adc clock = %d sample period = %d ns", rate,
+		data->sample_period_ns);
+
+	return 0;
+}
+
 static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       struct iio_chan_spec const *chan,
 			       int *val, int *val2, long mask)
@@ -157,17 +182,9 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,
 				struct iio_chan_spec const *chan,
 				int val, int val2, long mask)
 {
-	struct aspeed_adc_data *data = iio_priv(indio_dev);
-
 	switch (mask) {
 	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val < data->model_data->min_sampling_rate ||
-			val > data->model_data->max_sampling_rate)
-			return -EINVAL;
-
-		clk_set_rate(data->clk_scaler->clk,
-				val * ASPEED_CLOCKS_PER_SAMPLE);
-		return 0;
+		return aspeed_adc_set_sampling_rate(indio_dev, val);
 
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_RAW:
@@ -409,6 +426,20 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = clk_prepare_enable(data->clk_scaler->clk);
+	if (ret)
+		return ret;
+
+	ret = devm_add_action_or_reset(data->dev,
+				       aspeed_adc_clk_disable_unprepare,
+				       data->clk_scaler->clk);
+	if (ret)
+		return ret;
+
+	ret = aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE);
+	if (ret)
+		return ret;
+
 	if (data->model_data->wait_init_sequence) {
 		adc_engine_control_reg_val =
 			readl(data->base + ASPEED_REG_ENGINE_CONTROL);
@@ -436,16 +467,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 
 	/* Start all channels in normal mode. */
-	ret = clk_prepare_enable(data->clk_scaler->clk);
-	if (ret)
-		return ret;
-
-	ret = devm_add_action_or_reset(data->dev,
-				       aspeed_adc_clk_disable_unprepare,
-				       data->clk_scaler->clk);
-	if (ret)
-		return ret;
-
 	adc_engine_control_reg_val =
 		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
 	adc_engine_control_reg_val |=
-- 
2.25.1



From jason-jh.lin at mediatek.com  Tue Aug 31 00:14:22 2021
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Tue, 31 Aug 2021 15:14:22 +0800
Subject: [PATCH v6 0/5] Add gce support for mt8195
In-Reply-To: <CABb+yY0rTZrM1J7mFbSf0Z5tdwjYsQ8Tff-DnVfxX8P4HRu01w@mail.gmail.com>
References: <20210825094120.5005-1-jason-jh.lin@mediatek.com>
 <CABb+yY0rTZrM1J7mFbSf0Z5tdwjYsQ8Tff-DnVfxX8P4HRu01w@mail.gmail.com>
Message-ID: <81f4cecd13cd40fcbcdb980bf18375a4a894b118.camel@mediatek.com>

Hi Jassi,

Thanks for the reviews.

On Mon, 2021-08-30 at 00:34 -0500, Jassi Brar wrote:
> On Wed, Aug 25, 2021 at 4:41 AM jason-jh.lin <
> jason-jh.lin at mediatek.com> wrote:
> > 
> > Change in v6:
> > - remove the unused define in GCE header file.
> > 
> 
> Please rebase the patches over other previous mtk patchset for
> mt8192.
> 
https://urldefense.com/v3/__https://git.linaro.org/landing-teams/working/fujitsu/integration.git/log/?h=mailbox-for-next__;!!CTRNKA9wMg0ARbw!0KekHANUMQQ7OdH-ky0ch1rSc7kOn3NPFAOjLrsrzsd0Z2rFvysSFRAr3R6adYRnAfJ4$
>  
> 
> Thanks.

OK, I've rebased on mt8192 series at v7:

https://patchwork.kernel.org/project/linux-mediatek/patch/20210831070903.8672-2-jason-jh.lin at mediatek.com/

Regards,
Jason-JH.Lin

From jens.wiklander at linaro.org  Tue Aug 31 00:24:08 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 31 Aug 2021 09:24:08 +0200
Subject: [PATCH v5 1/5] tee: add sec_world_id to struct tee_shm
In-Reply-To: <20210831072412.887565-1-jens.wiklander@linaro.org>
References: <20210831072412.887565-1-jens.wiklander@linaro.org>
Message-ID: <20210831072412.887565-2-jens.wiklander@linaro.org>

Adds sec_world_id to struct tee_shm which describes a shared memory
object. sec_world_id can be used by a driver to store an id assigned by
secure world.

Reviewed-by: Sumit Garg <sumit.garg at linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 include/linux/tee_drv.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
index 3ebfea0781f1..a1f03461369b 100644
--- a/include/linux/tee_drv.h
+++ b/include/linux/tee_drv.h
@@ -197,7 +197,11 @@ int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
  * @num_pages:	number of locked pages
  * @dmabuf:	dmabuf used to for exporting to user space
  * @flags:	defined by TEE_SHM_* in tee_drv.h
- * @id:		unique id of a shared memory object on this device
+ * @id:		unique id of a shared memory object on this device, shared
+ *		with user space
+ * @sec_world_id:
+ *		secure world assigned id of this shared memory object, not
+ *		used by all drivers
  *
  * This pool is only supposed to be accessed directly from the TEE
  * subsystem and from drivers that implements their own shm pool manager.
@@ -213,6 +217,7 @@ struct tee_shm {
 	struct dma_buf *dmabuf;
 	u32 flags;
 	int id;
+	u64 sec_world_id;
 };
 
 /**
-- 
2.31.1



From jens.wiklander at linaro.org  Tue Aug 31 00:24:07 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 31 Aug 2021 09:24:07 +0200
Subject: [PATCH v5 0/5] Add FF-A support in OP-TEE driver
Message-ID: <20210831072412.887565-1-jens.wiklander@linaro.org>

Hi all,

This adds supports for the OP-TEE driver to communicate with secure world
using FF-A [1] as transport.

There is one change to the TEE subsystem with "tee: add sec_world_id to
struct tee_shm" to add support for holding globally unique handle assigned
by the FF-A. This is a field that I believe could useful for the AMDTEE
driver too.

For communication the OP-TEE message protocol is still used, but with a new
type of memory reference, struct optee_msg_param_fmem, to carry the
information needed by FF-A. The OP-TEE driver is refactored internally with
to sets of callbacks, one for the old SMC based communication and another
set with FF-A as transport. The functions relating to the SMC based ABI
are moved to smc_abi.c while the FF-A based ABI is added in a ffa_abi.c.

There is also a difference in how the drivers are instantiated. With the
SMC based transport we have a platform driver, module_platform_driver(),
today which we're keeping as is for this configuration. In a FF-A system we
have a FF-A driver, module_ffa_driver(), instead.

The OP-TEE driver can be compiled for both targets at the same time and
it's up to runtime configuration (device tree or ACPI) to decide how it's
initialized. Note that it's only the old SMC based driver instance that
need device tree or ACPI to initialize. The FF-A based driver relies on the
FF-A bus instead.

This can be tested QEMU
The repo for SPMC at S-EL1 retrieved by
repo init -u https://github.com/jenswi-linaro/manifest.git -m
qemu_v8.xml -b ffav4_spmc
repo sync
# Then checkout the branch optee_ffa_v5 from
# git://git.linaro.org/people/jens.wiklander/linux-tee.git
# in the linux directory

To build do:
cd build
make toolchains
make all

To boot:
make run-only

Test with xtest, perhaps only with the command "xtest 1004" in case you're
not interested in too many tests.

Thanks,
Jens

[1] https://developer.arm.com/documentation/den0077/latest

v4->v5:
- Rebased on v5.14, tricky conflicts primarily between "optee: isolate smc
  abi" and mostly 376e4199e327 "tee: Correct inappropriate usage of
  TEE_SHM_DMA_BUF flag" but also with the other kexec fixes that went into
  v5.14-rc5.
- Addressing comments from Sumit and applying
  Reviewed-by: Sumit Garg <sumit.garg at linaro.org> on "optee: isolate smc abi"
- Addressing comments from Sumit and applying
  Acked-by: Sumit Garg <sumit.garg at linaro.org> on "optee: add FF-A support"

v3->v4:
- Made a bit more RPC code common between the SMC and FF-A ABIs as
  requested by Sumit.
- Replaced module_platform_driver() with module_init()/module_exit() as
  described in the commit "optee: isolate smc abi".
- Applied Sumit's R-B for the commits "tee: add sec_world_id to struct
  tee_shm", "optee: simplify optee_release()", and "optee: refactor driver
  with internal callbacks"

v2->v3:
- Rebased on 5.14-rc2 which now have the FF-A patches merged
- Fixed a couple bugs in optee_shm_register() and optee_shm_unregister()
  which where introduced in "optee: refactor driver with internal callbacks"
  in previous the version.
- Separated SMC ABI specifics into smc_abi.c to keep it separated from
  the FF-A ABI functions as requested by Sumit.
- Added the FF-A specifics in ffa_abi.c
- Provided an implementation for optee_ffa_remove()

v1->v2:
- Rebased to the FF-A v7 patch
- Fixed a couple of reports from kernel test robot <lkp at intel.com>



Jens Wiklander (5):
  tee: add sec_world_id to struct tee_shm
  optee: simplify optee_release()
  optee: refactor driver with internal callbacks
  optee: isolate smc abi
  optee: add FF-A support

 drivers/tee/optee/Makefile        |    7 +-
 drivers/tee/optee/call.c          |  445 ++--------
 drivers/tee/optee/core.c          |  719 ++-------------
 drivers/tee/optee/ffa_abi.c       |  907 +++++++++++++++++++
 drivers/tee/optee/optee_ffa.h     |  153 ++++
 drivers/tee/optee/optee_msg.h     |   27 +-
 drivers/tee/optee/optee_private.h |  163 +++-
 drivers/tee/optee/rpc.c           |  237 +----
 drivers/tee/optee/shm_pool.c      |  101 ---
 drivers/tee/optee/shm_pool.h      |   14 -
 drivers/tee/optee/smc_abi.c       | 1360 +++++++++++++++++++++++++++++
 include/linux/tee_drv.h           |    7 +-
 12 files changed, 2732 insertions(+), 1408 deletions(-)
 create mode 100644 drivers/tee/optee/ffa_abi.c
 create mode 100644 drivers/tee/optee/optee_ffa.h
 delete mode 100644 drivers/tee/optee/shm_pool.c
 delete mode 100644 drivers/tee/optee/shm_pool.h
 create mode 100644 drivers/tee/optee/smc_abi.c

-- 
2.31.1



From jens.wiklander at linaro.org  Tue Aug 31 00:24:09 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 31 Aug 2021 09:24:09 +0200
Subject: [PATCH v5 2/5] optee: simplify optee_release()
In-Reply-To: <20210831072412.887565-1-jens.wiklander@linaro.org>
References: <20210831072412.887565-1-jens.wiklander@linaro.org>
Message-ID: <20210831072412.887565-3-jens.wiklander@linaro.org>

Simplifies optee_release() with a new helper function,
optee_close_session_helper() which has been factored out from
optee_close_session().

A separate optee_release_supp() is added for the supplicant device.

Reviewed-by: Sumit Garg <sumit.garg at linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/call.c          | 31 ++++++++++-------
 drivers/tee/optee/core.c          | 56 +++++++++++--------------------
 drivers/tee/optee/optee_private.h |  1 +
 3 files changed, 39 insertions(+), 49 deletions(-)

diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 945f03da0223..103976df2062 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -288,12 +288,28 @@ int optee_open_session(struct tee_context *ctx,
 	return rc;
 }
 
-int optee_close_session(struct tee_context *ctx, u32 session)
+int optee_close_session_helper(struct tee_context *ctx, u32 session)
 {
-	struct optee_context_data *ctxdata = ctx->data;
 	struct tee_shm *shm;
 	struct optee_msg_arg *msg_arg;
 	phys_addr_t msg_parg;
+
+	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
+	msg_arg->session = session;
+	optee_do_call_with_arg(ctx, msg_parg);
+
+	tee_shm_free(shm);
+
+	return 0;
+}
+
+int optee_close_session(struct tee_context *ctx, u32 session)
+{
+	struct optee_context_data *ctxdata = ctx->data;
 	struct optee_session *sess;
 
 	/* Check that the session is valid and remove it from the list */
@@ -306,16 +322,7 @@ int optee_close_session(struct tee_context *ctx, u32 session)
 		return -EINVAL;
 	kfree(sess);
 
-	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
-	if (IS_ERR(shm))
-		return PTR_ERR(shm);
-
-	msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
-	msg_arg->session = session;
-	optee_do_call_with_arg(ctx, msg_parg);
-
-	tee_shm_free(shm);
-	return 0;
+	return optee_close_session_helper(ctx, session);
 }
 
 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 5ce13b099d7d..86a1ae8d296d 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -264,60 +264,42 @@ static int optee_open(struct tee_context *ctx)
 	return 0;
 }
 
-static void optee_release(struct tee_context *ctx)
+static void optee_release_helper(struct tee_context *ctx,
+				 int (*close_session)(struct tee_context *ctx,
+						      u32 session))
 {
 	struct optee_context_data *ctxdata = ctx->data;
-	struct tee_device *teedev = ctx->teedev;
-	struct optee *optee = tee_get_drvdata(teedev);
-	struct tee_shm *shm;
-	struct optee_msg_arg *arg = NULL;
-	phys_addr_t parg;
 	struct optee_session *sess;
 	struct optee_session *sess_tmp;
 
 	if (!ctxdata)
 		return;
 
-	shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg),
-			    TEE_SHM_MAPPED | TEE_SHM_PRIV);
-	if (!IS_ERR(shm)) {
-		arg = tee_shm_get_va(shm, 0);
-		/*
-		 * If va2pa fails for some reason, we can't call into
-		 * secure world, only free the memory. Secure OS will leak
-		 * sessions and finally refuse more sessions, but we will
-		 * at least let normal world reclaim its memory.
-		 */
-		if (!IS_ERR(arg))
-			if (tee_shm_va2pa(shm, arg, &parg))
-				arg = NULL; /* prevent usage of parg below */
-	}
-
 	list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list,
 				 list_node) {
 		list_del(&sess->list_node);
-		if (!IS_ERR_OR_NULL(arg)) {
-			memset(arg, 0, sizeof(*arg));
-			arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
-			arg->session = sess->session_id;
-			optee_do_call_with_arg(ctx, parg);
-		}
+		close_session(ctx, sess->session_id);
 		kfree(sess);
 	}
 	kfree(ctxdata);
+	ctx->data = NULL;
+}
 
-	if (!IS_ERR(shm))
-		tee_shm_free(shm);
+static void optee_release(struct tee_context *ctx)
+{
+	optee_release_helper(ctx, optee_close_session_helper);
+}
 
-	ctx->data = NULL;
+static void optee_release_supp(struct tee_context *ctx)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 
-	if (teedev == optee->supp_teedev) {
-		if (optee->scan_bus_wq) {
-			destroy_workqueue(optee->scan_bus_wq);
-			optee->scan_bus_wq = NULL;
-		}
-		optee_supp_release(&optee->supp);
+	optee_release_helper(ctx, optee_close_session_helper);
+	if (optee->scan_bus_wq) {
+		destroy_workqueue(optee->scan_bus_wq);
+		optee->scan_bus_wq = NULL;
 	}
+	optee_supp_release(&optee->supp);
 }
 
 static const struct tee_driver_ops optee_ops = {
@@ -341,7 +323,7 @@ static const struct tee_desc optee_desc = {
 static const struct tee_driver_ops optee_supp_ops = {
 	.get_version = optee_get_version,
 	.open = optee_open,
-	.release = optee_release,
+	.release = optee_release_supp,
 	.supp_recv = optee_supp_recv,
 	.supp_send = optee_supp_send,
 	.shm_register = optee_shm_register_supp,
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index dbdd367be156..d9f5f3f7ba58 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -152,6 +152,7 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
 int optee_open_session(struct tee_context *ctx,
 		       struct tee_ioctl_open_session_arg *arg,
 		       struct tee_param *param);
+int optee_close_session_helper(struct tee_context *ctx, u32 session);
 int optee_close_session(struct tee_context *ctx, u32 session);
 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 		      struct tee_param *param);
-- 
2.31.1



From jens.wiklander at linaro.org  Tue Aug 31 00:24:10 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 31 Aug 2021 09:24:10 +0200
Subject: [PATCH v5 3/5] optee: refactor driver with internal callbacks
In-Reply-To: <20210831072412.887565-1-jens.wiklander@linaro.org>
References: <20210831072412.887565-1-jens.wiklander@linaro.org>
Message-ID: <20210831072412.887565-4-jens.wiklander@linaro.org>

The OP-TEE driver is refactored with three internal callbacks replacing
direct calls to optee_from_msg_param(), optee_to_msg_param() and
optee_do_call_with_arg().

These functions a central to communicating with OP-TEE in secure world
by using the SMC Calling Convention directly.

This refactoring makes room for using other primitives to communicate
with OP-TEE in secure world while being able to reuse as much as
possible from the present driver.

Reviewed-by: Sumit Garg <sumit.garg at linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/call.c          |  86 +++++++++--------
 drivers/tee/optee/core.c          | 148 ++++++++++++++++++++----------
 drivers/tee/optee/optee_private.h |  35 +++++--
 drivers/tee/optee/rpc.c           |  19 ++--
 4 files changed, 182 insertions(+), 106 deletions(-)

diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 103976df2062..ddedde45f1ee 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 #include <linux/arm-smccc.h>
 #include <linux/device.h>
@@ -118,20 +118,25 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
 /**
  * optee_do_call_with_arg() - Do an SMC to OP-TEE in secure world
  * @ctx:	calling context
- * @parg:	physical address of message to pass to secure world
+ * @arg:	shared memory holding the message to pass to secure world
  *
  * Does and SMC to OP-TEE in secure world and handles eventual resulting
  * Remote Procedure Calls (RPC) from OP-TEE.
  *
  * Returns return code from secure world, 0 is OK
  */
-u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
+int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg)
 {
 	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_call_waiter w;
 	struct optee_rpc_param param = { };
 	struct optee_call_ctx call_ctx = { };
-	u32 ret;
+	phys_addr_t parg;
+	int rc;
+
+	rc = tee_shm_get_pa(arg, 0, &parg);
+	if (rc)
+		return rc;
 
 	param.a0 = OPTEE_SMC_CALL_WITH_ARG;
 	reg_pair_from_64(&param.a1, &param.a2, parg);
@@ -160,7 +165,7 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
 			param.a3 = res.a3;
 			optee_handle_rpc(ctx, &param, &call_ctx);
 		} else {
-			ret = res.a0;
+			rc = res.a0;
 			break;
 		}
 	}
@@ -172,14 +177,12 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
 	 */
 	optee_cq_wait_final(&optee->call_queue, &w);
 
-	return ret;
+	return rc;
 }
 
 static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
-				   struct optee_msg_arg **msg_arg,
-				   phys_addr_t *msg_parg)
+				   struct optee_msg_arg **msg_arg)
 {
-	int rc;
 	struct tee_shm *shm;
 	struct optee_msg_arg *ma;
 
@@ -190,22 +193,13 @@ static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
 
 	ma = tee_shm_get_va(shm, 0);
 	if (IS_ERR(ma)) {
-		rc = PTR_ERR(ma);
-		goto out;
+		tee_shm_free(shm);
+		return (void *)ma;
 	}
 
-	rc = tee_shm_get_pa(shm, 0, msg_parg);
-	if (rc)
-		goto out;
-
 	memset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params));
 	ma->num_params = num_params;
 	*msg_arg = ma;
-out:
-	if (rc) {
-		tee_shm_free(shm);
-		return ERR_PTR(rc);
-	}
 
 	return shm;
 }
@@ -214,16 +208,16 @@ int optee_open_session(struct tee_context *ctx,
 		       struct tee_ioctl_open_session_arg *arg,
 		       struct tee_param *param)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_context_data *ctxdata = ctx->data;
 	int rc;
 	struct tee_shm *shm;
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
 	struct optee_session *sess = NULL;
 	uuid_t client_uuid;
 
 	/* +2 for the meta parameters added below */
-	shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg, &msg_parg);
+	shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
@@ -247,7 +241,8 @@ int optee_open_session(struct tee_context *ctx,
 		goto out;
 	export_uuid(msg_arg->params[1].u.octets, &client_uuid);
 
-	rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param);
+	rc = optee->ops->to_msg_param(optee, msg_arg->params + 2,
+				      arg->num_params, param);
 	if (rc)
 		goto out;
 
@@ -257,7 +252,7 @@ int optee_open_session(struct tee_context *ctx,
 		goto out;
 	}
 
-	if (optee_do_call_with_arg(ctx, msg_parg)) {
+	if (optee->ops->do_call_with_arg(ctx, shm)) {
 		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
 		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
 	}
@@ -272,7 +267,8 @@ int optee_open_session(struct tee_context *ctx,
 		kfree(sess);
 	}
 
-	if (optee_from_msg_param(param, arg->num_params, msg_arg->params + 2)) {
+	if (optee->ops->from_msg_param(optee, param, arg->num_params,
+				       msg_arg->params + 2)) {
 		arg->ret = TEEC_ERROR_COMMUNICATION;
 		arg->ret_origin = TEEC_ORIGIN_COMMS;
 		/* Close session again to avoid leakage */
@@ -291,16 +287,16 @@ int optee_open_session(struct tee_context *ctx,
 int optee_close_session_helper(struct tee_context *ctx, u32 session)
 {
 	struct tee_shm *shm;
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
 
-	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	shm = get_msg_arg(ctx, 0, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
 	msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
 	msg_arg->session = session;
-	optee_do_call_with_arg(ctx, msg_parg);
+	optee->ops->do_call_with_arg(ctx, shm);
 
 	tee_shm_free(shm);
 
@@ -328,10 +324,10 @@ int optee_close_session(struct tee_context *ctx, u32 session)
 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 		      struct tee_param *param)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_context_data *ctxdata = ctx->data;
 	struct tee_shm *shm;
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
 	struct optee_session *sess;
 	int rc;
 
@@ -342,7 +338,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 	if (!sess)
 		return -EINVAL;
 
-	shm = get_msg_arg(ctx, arg->num_params, &msg_arg, &msg_parg);
+	shm = get_msg_arg(ctx, arg->num_params, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 	msg_arg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
@@ -350,16 +346,18 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 	msg_arg->session = arg->session;
 	msg_arg->cancel_id = arg->cancel_id;
 
-	rc = optee_to_msg_param(msg_arg->params, arg->num_params, param);
+	rc = optee->ops->to_msg_param(optee, msg_arg->params, arg->num_params,
+				      param);
 	if (rc)
 		goto out;
 
-	if (optee_do_call_with_arg(ctx, msg_parg)) {
+	if (optee->ops->do_call_with_arg(ctx, shm)) {
 		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
 		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
 	}
 
-	if (optee_from_msg_param(param, arg->num_params, msg_arg->params)) {
+	if (optee->ops->from_msg_param(optee, param, arg->num_params,
+				       msg_arg->params)) {
 		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
 		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
 	}
@@ -373,10 +371,10 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 
 int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_context_data *ctxdata = ctx->data;
 	struct tee_shm *shm;
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
 	struct optee_session *sess;
 
 	/* Check that the session is valid */
@@ -386,14 +384,14 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 	if (!sess)
 		return -EINVAL;
 
-	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	shm = get_msg_arg(ctx, 0, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
 	msg_arg->cmd = OPTEE_MSG_CMD_CANCEL;
 	msg_arg->session = session;
 	msg_arg->cancel_id = cancel_id;
-	optee_do_call_with_arg(ctx, msg_parg);
+	optee->ops->do_call_with_arg(ctx, shm);
 
 	tee_shm_free(shm);
 	return 0;
@@ -622,10 +620,10 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 		       struct page **pages, size_t num_pages,
 		       unsigned long start)
 {
-	struct tee_shm *shm_arg = NULL;
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm_arg;
 	u64 *pages_list;
-	phys_addr_t msg_parg;
 	int rc;
 
 	if (!num_pages)
@@ -639,7 +637,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 	if (!pages_list)
 		return -ENOMEM;
 
-	shm_arg = get_msg_arg(ctx, 1, &msg_arg, &msg_parg);
+	shm_arg = get_msg_arg(ctx, 1, &msg_arg);
 	if (IS_ERR(shm_arg)) {
 		rc = PTR_ERR(shm_arg);
 		goto out;
@@ -660,7 +658,7 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 	msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
 	  (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
 
-	if (optee_do_call_with_arg(ctx, msg_parg) ||
+	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
 	    msg_arg->ret != TEEC_SUCCESS)
 		rc = -EINVAL;
 
@@ -672,12 +670,12 @@ int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 
 int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
 {
-	struct tee_shm *shm_arg;
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_msg_arg *msg_arg;
-	phys_addr_t msg_parg;
+	struct tee_shm *shm_arg;
 	int rc = 0;
 
-	shm_arg = get_msg_arg(ctx, 1, &msg_arg, &msg_parg);
+	shm_arg = get_msg_arg(ctx, 1, &msg_arg);
 	if (IS_ERR(shm_arg))
 		return PTR_ERR(shm_arg);
 
@@ -686,7 +684,7 @@ int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
 	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
 	msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;
 
-	if (optee_do_call_with_arg(ctx, msg_parg) ||
+	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
 	    msg_arg->ret != TEEC_SUCCESS)
 		rc = -EINVAL;
 	tee_shm_free(shm_arg);
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 86a1ae8d296d..50650224e311 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -27,21 +27,87 @@
 
 #define OPTEE_SHM_NUM_PRIV_PAGES	CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
 
+static void from_msg_param_value(struct tee_param *p, u32 attr,
+				 const struct optee_msg_param *mp)
+{
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+	p->u.value.a = mp->u.value.a;
+	p->u.value.b = mp->u.value.b;
+	p->u.value.c = mp->u.value.c;
+}
+
+static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
+				  const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm;
+	phys_addr_t pa;
+	int rc;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
+	p->u.memref.size = mp->u.tmem.size;
+	shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
+	if (!shm) {
+		p->u.memref.shm_offs = 0;
+		p->u.memref.shm = NULL;
+		return 0;
+	}
+
+	rc = tee_shm_get_pa(shm, 0, &pa);
+	if (rc)
+		return rc;
+
+	p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
+	p->u.memref.shm = shm;
+
+	/* Check that the memref is covered by the shm object */
+	if (p->u.memref.size) {
+		size_t o = p->u.memref.shm_offs +
+			   p->u.memref.size - 1;
+
+		rc = tee_shm_get_pa(shm, o, NULL);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
+
+static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
+				   const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
+	p->u.memref.size = mp->u.rmem.size;
+	shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
+
+	if (shm) {
+		p->u.memref.shm_offs = mp->u.rmem.offs;
+		p->u.memref.shm = shm;
+	} else {
+		p->u.memref.shm_offs = 0;
+		p->u.memref.shm = NULL;
+	}
+}
+
 /**
  * optee_from_msg_param() - convert from OPTEE_MSG parameters to
  *			    struct tee_param
+ * @optee:	main service struct
  * @params:	subsystem internal parameter representation
  * @num_params:	number of elements in the parameter arrays
  * @msg_params:	OPTEE_MSG parameters
  * Returns 0 on success or <0 on failure
  */
-int optee_from_msg_param(struct tee_param *params, size_t num_params,
-			 const struct optee_msg_param *msg_params)
+static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
+				size_t num_params,
+				const struct optee_msg_param *msg_params)
 {
 	int rc;
 	size_t n;
-	struct tee_shm *shm;
-	phys_addr_t pa;
 
 	for (n = 0; n < num_params; n++) {
 		struct tee_param *p = params + n;
@@ -56,48 +122,19 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params,
 		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
-			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
-				  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
-			p->u.value.a = mp->u.value.a;
-			p->u.value.b = mp->u.value.b;
-			p->u.value.c = mp->u.value.c;
+			from_msg_param_value(p, attr, mp);
 			break;
 		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
-			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
-				  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
-			p->u.memref.size = mp->u.tmem.size;
-			shm = (struct tee_shm *)(unsigned long)
-				mp->u.tmem.shm_ref;
-			if (!shm) {
-				p->u.memref.shm_offs = 0;
-				p->u.memref.shm = NULL;
-				break;
-			}
-			rc = tee_shm_get_pa(shm, 0, &pa);
+			rc = from_msg_param_tmp_mem(p, attr, mp);
 			if (rc)
 				return rc;
-			p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
-			p->u.memref.shm = shm;
 			break;
 		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
 		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
 		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
-			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
-				  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
-			p->u.memref.size = mp->u.rmem.size;
-			shm = (struct tee_shm *)(unsigned long)
-				mp->u.rmem.shm_ref;
-
-			if (!shm) {
-				p->u.memref.shm_offs = 0;
-				p->u.memref.shm = NULL;
-				break;
-			}
-			p->u.memref.shm_offs = mp->u.rmem.offs;
-			p->u.memref.shm = shm;
-
+			from_msg_param_reg_mem(p, attr, mp);
 			break;
 
 		default:
@@ -107,6 +144,16 @@ int optee_from_msg_param(struct tee_param *params, size_t num_params,
 	return 0;
 }
 
+static void to_msg_param_value(struct optee_msg_param *mp,
+			       const struct tee_param *p)
+{
+	mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+	mp->u.value.a = p->u.value.a;
+	mp->u.value.b = p->u.value.b;
+	mp->u.value.c = p->u.value.c;
+}
+
 static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
 				const struct tee_param *p)
 {
@@ -149,13 +196,15 @@ static int to_msg_param_reg_mem(struct optee_msg_param *mp,
 
 /**
  * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
+ * @optee:	main service struct
  * @msg_params:	OPTEE_MSG parameters
  * @num_params:	number of elements in the parameter arrays
  * @params:	subsystem itnernal parameter representation
  * Returns 0 on success or <0 on failure
  */
-int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
-		       const struct tee_param *params)
+static int optee_to_msg_param(struct optee *optee,
+			      struct optee_msg_param *msg_params,
+			      size_t num_params, const struct tee_param *params)
 {
 	int rc;
 	size_t n;
@@ -172,11 +221,7 @@ int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
-			mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
-				   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-			mp->u.value.a = p->u.value.a;
-			mp->u.value.b = p->u.value.b;
-			mp->u.value.c = p->u.value.c;
+			to_msg_param_value(mp, p);
 			break;
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
 		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
@@ -302,7 +347,7 @@ static void optee_release_supp(struct tee_context *ctx)
 	optee_supp_release(&optee->supp);
 }
 
-static const struct tee_driver_ops optee_ops = {
+static const struct tee_driver_ops optee_clnt_ops = {
 	.get_version = optee_get_version,
 	.open = optee_open,
 	.release = optee_release,
@@ -314,9 +359,9 @@ static const struct tee_driver_ops optee_ops = {
 	.shm_unregister = optee_shm_unregister,
 };
 
-static const struct tee_desc optee_desc = {
+static const struct tee_desc optee_clnt_desc = {
 	.name = DRIVER_NAME "-clnt",
-	.ops = &optee_ops,
+	.ops = &optee_clnt_ops,
 	.owner = THIS_MODULE,
 };
 
@@ -337,6 +382,12 @@ static const struct tee_desc optee_supp_desc = {
 	.flags = TEE_DESC_PRIVILEGED,
 };
 
+static const struct optee_ops optee_ops = {
+	.do_call_with_arg = optee_do_call_with_arg,
+	.to_msg_param = optee_to_msg_param,
+	.from_msg_param = optee_from_msg_param,
+};
+
 static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
 {
 	struct arm_smccc_res res;
@@ -667,10 +718,11 @@ static int optee_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	optee->ops = &optee_ops;
 	optee->invoke_fn = invoke_fn;
 	optee->sec_caps = sec_caps;
 
-	teedev = tee_device_alloc(&optee_desc, NULL, pool, optee);
+	teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
 	if (IS_ERR(teedev)) {
 		rc = PTR_ERR(teedev);
 		goto err;
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index d9f5f3f7ba58..92d59c145d4a 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 
 #ifndef OPTEE_PRIVATE_H
@@ -66,9 +66,34 @@ struct optee_supp {
 	struct completion reqs_c;
 };
 
+struct optee;
+
+/**
+ * struct optee_ops - OP-TEE driver internal operations
+ * @do_call_with_arg:	enters OP-TEE in secure world
+ * @to_msg_param:	converts from struct tee_param to OPTEE_MSG parameters
+ * @from_msg_param:	converts from OPTEE_MSG parameters to struct tee_param
+ *
+ * These OPs are only supposed to be used internally in the OP-TEE driver
+ * as a way of abstracting the different methogs of entering OP-TEE in
+ * secure world.
+ */
+struct optee_ops {
+	int (*do_call_with_arg)(struct tee_context *ctx,
+				struct tee_shm *shm_arg);
+	int (*to_msg_param)(struct optee *optee,
+			    struct optee_msg_param *msg_params,
+			    size_t num_params, const struct tee_param *params);
+	int (*from_msg_param)(struct optee *optee, struct tee_param *params,
+			      size_t num_params,
+			      const struct optee_msg_param *msg_params);
+};
+
 /**
  * struct optee - main service struct
  * @supp_teedev:	supplicant device
+ * @ops:		internal callbacks for different ways to reach secure
+ *			world
  * @teedev:		client device
  * @invoke_fn:		function to issue smc or hvc
  * @call_queue:		queue of threads waiting to call @invoke_fn
@@ -86,6 +111,7 @@ struct optee_supp {
 struct optee {
 	struct tee_device *supp_teedev;
 	struct tee_device *teedev;
+	const struct optee_ops *ops;
 	optee_invoke_fn *invoke_fn;
 	struct optee_call_queue call_queue;
 	struct optee_wait_queue wait_queue;
@@ -148,7 +174,7 @@ int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
 int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
 		    struct tee_param *param);
 
-u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
+int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg);
 int optee_open_session(struct tee_context *ctx,
 		       struct tee_ioctl_open_session_arg *arg,
 		       struct tee_param *param);
@@ -172,11 +198,6 @@ int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
 			    unsigned long start);
 int optee_shm_unregister_supp(struct tee_context *ctx, struct tee_shm *shm);
 
-int optee_from_msg_param(struct tee_param *params, size_t num_params,
-			 const struct optee_msg_param *msg_params);
-int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
-		       const struct tee_param *params);
-
 u64 *optee_allocate_pages_list(size_t num_entries);
 void optee_free_pages_list(void *array, size_t num_entries);
 void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index efbaff7ad7e5..309258d47790 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2016, Linaro Limited
+ * Copyright (c) 2015-2021, Linaro Limited
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -55,6 +55,7 @@ static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 					     struct optee_msg_arg *arg)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct tee_param *params;
 	struct i2c_adapter *adapter;
 	struct i2c_msg msg = { };
@@ -79,7 +80,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 		return;
 	}
 
-	if (optee_from_msg_param(params, arg->num_params, arg->params))
+	if (optee->ops->from_msg_param(optee, params, arg->num_params,
+				       arg->params))
 		goto bad;
 
 	for (i = 0; i < arg->num_params; i++) {
@@ -122,7 +124,8 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
 		arg->ret = TEEC_ERROR_COMMUNICATION;
 	} else {
 		params[3].u.value.a = msg.len;
-		if (optee_to_msg_param(arg->params, arg->num_params, params))
+		if (optee->ops->to_msg_param(optee, arg->params,
+					     arg->num_params, params))
 			arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		else
 			arg->ret = TEEC_SUCCESS;
@@ -234,7 +237,7 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
 	arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 }
 
-static void handle_rpc_supp_cmd(struct tee_context *ctx,
+static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
 				struct optee_msg_arg *arg)
 {
 	struct tee_param *params;
@@ -248,14 +251,16 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx,
 		return;
 	}
 
-	if (optee_from_msg_param(params, arg->num_params, arg->params)) {
+	if (optee->ops->from_msg_param(optee, params, arg->num_params,
+				       arg->params)) {
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 		goto out;
 	}
 
 	arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
 
-	if (optee_to_msg_param(arg->params, arg->num_params, params))
+	if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
+				     params))
 		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
 out:
 	kfree(params);
@@ -480,7 +485,7 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
 		handle_rpc_func_cmd_i2c_transfer(ctx, arg);
 		break;
 	default:
-		handle_rpc_supp_cmd(ctx, arg);
+		handle_rpc_supp_cmd(ctx, optee, arg);
 	}
 }
 
-- 
2.31.1



From jens.wiklander at linaro.org  Tue Aug 31 00:24:11 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 31 Aug 2021 09:24:11 +0200
Subject: [PATCH v5 4/5] optee: isolate smc abi
In-Reply-To: <20210831072412.887565-1-jens.wiklander@linaro.org>
References: <20210831072412.887565-1-jens.wiklander@linaro.org>
Message-ID: <20210831072412.887565-5-jens.wiklander@linaro.org>

Isolate the ABI based on raw SMCs. Code specific to the raw SMC ABI is
moved into smc_abi.c. This makes room for other ABIs with a clear
separation.

The driver changes to use module_init()/module_exit() instead of
module_platform_driver(). The platform_driver_register() and
platform_driver_unregister() functions called directly to keep the same
behavior. This is needed because module_platform_driver() is based on
module_driver() which can only be used once in a module.

A function optee_rpc_cmd() is factored out from the function
handle_rpc_func_cmd() to handle the ABI independent part of RPC
processing.

This patch is not supposed to change the driver behavior, it's only a
matter of reorganizing the code.

Reviewed-by: Sumit Garg <sumit.garg at linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/Makefile        |    6 +-
 drivers/tee/optee/call.c          |  369 +-------
 drivers/tee/optee/core.c          |  721 ++-------------
 drivers/tee/optee/optee_private.h |  104 ++-
 drivers/tee/optee/rpc.c           |  218 +----
 drivers/tee/optee/shm_pool.c      |  101 ---
 drivers/tee/optee/shm_pool.h      |   14 -
 drivers/tee/optee/smc_abi.c       | 1360 +++++++++++++++++++++++++++++
 8 files changed, 1506 insertions(+), 1387 deletions(-)
 delete mode 100644 drivers/tee/optee/shm_pool.c
 delete mode 100644 drivers/tee/optee/shm_pool.h
 create mode 100644 drivers/tee/optee/smc_abi.c

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index 3aa33ea9e6a6..d4e4776d2dec 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -4,8 +4,10 @@ optee-objs += core.o
 optee-objs += call.o
 optee-objs += rpc.o
 optee-objs += supp.o
-optee-objs += shm_pool.o
 optee-objs += device.o
 
+optee-smc-abi-y = smc_abi.o
+optee-objs += $(optee-smc-abi-y)
+
 # for tracing framework to find optee_trace.h
-CFLAGS_call.o := -I$(src)
+CFLAGS_smc_abi.o := -I$(src)
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index ddedde45f1ee..9ff4f0812825 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -2,28 +2,17 @@
 /*
  * Copyright (c) 2015-2021, Linaro Limited
  */
-#include <linux/arm-smccc.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/tee_drv.h>
 #include <linux/types.h>
-#include <linux/uaccess.h>
 #include "optee_private.h"
-#include "optee_smc.h"
-#define CREATE_TRACE_POINTS
-#include "optee_trace.h"
 
-struct optee_call_waiter {
-	struct list_head list_node;
-	struct completion c;
-};
-
-static void optee_cq_wait_init(struct optee_call_queue *cq,
-			       struct optee_call_waiter *w)
+void optee_cq_wait_init(struct optee_call_queue *cq,
+			struct optee_call_waiter *w)
 {
 	/*
 	 * We're preparing to make a call to secure world. In case we can't
@@ -47,8 +36,8 @@ static void optee_cq_wait_init(struct optee_call_queue *cq,
 	mutex_unlock(&cq->mutex);
 }
 
-static void optee_cq_wait_for_completion(struct optee_call_queue *cq,
-					 struct optee_call_waiter *w)
+void optee_cq_wait_for_completion(struct optee_call_queue *cq,
+				  struct optee_call_waiter *w)
 {
 	wait_for_completion(&w->c);
 
@@ -74,8 +63,8 @@ static void optee_cq_complete_one(struct optee_call_queue *cq)
 	}
 }
 
-static void optee_cq_wait_final(struct optee_call_queue *cq,
-				struct optee_call_waiter *w)
+void optee_cq_wait_final(struct optee_call_queue *cq,
+			 struct optee_call_waiter *w)
 {
 	/*
 	 * We're done with the call to secure world. The thread in secure
@@ -115,73 +104,8 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
 	return NULL;
 }
 
-/**
- * optee_do_call_with_arg() - Do an SMC to OP-TEE in secure world
- * @ctx:	calling context
- * @arg:	shared memory holding the message to pass to secure world
- *
- * Does and SMC to OP-TEE in secure world and handles eventual resulting
- * Remote Procedure Calls (RPC) from OP-TEE.
- *
- * Returns return code from secure world, 0 is OK
- */
-int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg)
-{
-	struct optee *optee = tee_get_drvdata(ctx->teedev);
-	struct optee_call_waiter w;
-	struct optee_rpc_param param = { };
-	struct optee_call_ctx call_ctx = { };
-	phys_addr_t parg;
-	int rc;
-
-	rc = tee_shm_get_pa(arg, 0, &parg);
-	if (rc)
-		return rc;
-
-	param.a0 = OPTEE_SMC_CALL_WITH_ARG;
-	reg_pair_from_64(&param.a1, &param.a2, parg);
-	/* Initialize waiter */
-	optee_cq_wait_init(&optee->call_queue, &w);
-	while (true) {
-		struct arm_smccc_res res;
-
-		trace_optee_invoke_fn_begin(&param);
-		optee->invoke_fn(param.a0, param.a1, param.a2, param.a3,
-				 param.a4, param.a5, param.a6, param.a7,
-				 &res);
-		trace_optee_invoke_fn_end(&param, &res);
-
-		if (res.a0 == OPTEE_SMC_RETURN_ETHREAD_LIMIT) {
-			/*
-			 * Out of threads in secure world, wait for a thread
-			 * become available.
-			 */
-			optee_cq_wait_for_completion(&optee->call_queue, &w);
-		} else if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {
-			cond_resched();
-			param.a0 = res.a0;
-			param.a1 = res.a1;
-			param.a2 = res.a2;
-			param.a3 = res.a3;
-			optee_handle_rpc(ctx, &param, &call_ctx);
-		} else {
-			rc = res.a0;
-			break;
-		}
-	}
-
-	optee_rpc_finalize_call(&call_ctx);
-	/*
-	 * We're done with our thread in secure world, if there's any
-	 * thread waiters wake up one.
-	 */
-	optee_cq_wait_final(&optee->call_queue, &w);
-
-	return rc;
-}
-
-static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
-				   struct optee_msg_arg **msg_arg)
+struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params,
+				  struct optee_msg_arg **msg_arg)
 {
 	struct tee_shm *shm;
 	struct optee_msg_arg *ma;
@@ -217,7 +141,7 @@ int optee_open_session(struct tee_context *ctx,
 	uuid_t client_uuid;
 
 	/* +2 for the meta parameters added below */
-	shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg);
+	shm = optee_get_msg_arg(ctx, arg->num_params + 2, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
@@ -290,7 +214,7 @@ int optee_close_session_helper(struct tee_context *ctx, u32 session)
 	struct optee *optee = tee_get_drvdata(ctx->teedev);
 	struct optee_msg_arg *msg_arg;
 
-	shm = get_msg_arg(ctx, 0, &msg_arg);
+	shm = optee_get_msg_arg(ctx, 0, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
@@ -338,7 +262,7 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 	if (!sess)
 		return -EINVAL;
 
-	shm = get_msg_arg(ctx, arg->num_params, &msg_arg);
+	shm = optee_get_msg_arg(ctx, arg->num_params, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 	msg_arg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
@@ -384,7 +308,7 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 	if (!sess)
 		return -EINVAL;
 
-	shm = get_msg_arg(ctx, 0, &msg_arg);
+	shm = optee_get_msg_arg(ctx, 0, &msg_arg);
 	if (IS_ERR(shm))
 		return PTR_ERR(shm);
 
@@ -397,182 +321,6 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
 	return 0;
 }
 
-/**
- * optee_enable_shm_cache() - Enables caching of some shared memory allocation
- *			      in OP-TEE
- * @optee:	main service struct
- */
-void optee_enable_shm_cache(struct optee *optee)
-{
-	struct optee_call_waiter w;
-
-	/* We need to retry until secure world isn't busy. */
-	optee_cq_wait_init(&optee->call_queue, &w);
-	while (true) {
-		struct arm_smccc_res res;
-
-		optee->invoke_fn(OPTEE_SMC_ENABLE_SHM_CACHE, 0, 0, 0, 0, 0, 0,
-				 0, &res);
-		if (res.a0 == OPTEE_SMC_RETURN_OK)
-			break;
-		optee_cq_wait_for_completion(&optee->call_queue, &w);
-	}
-	optee_cq_wait_final(&optee->call_queue, &w);
-}
-
-/**
- * __optee_disable_shm_cache() - Disables caching of some shared memory
- *                               allocation in OP-TEE
- * @optee:	main service struct
- * @is_mapped:	true if the cached shared memory addresses were mapped by this
- *		kernel, are safe to dereference, and should be freed
- */
-static void __optee_disable_shm_cache(struct optee *optee, bool is_mapped)
-{
-	struct optee_call_waiter w;
-
-	/* We need to retry until secure world isn't busy. */
-	optee_cq_wait_init(&optee->call_queue, &w);
-	while (true) {
-		union {
-			struct arm_smccc_res smccc;
-			struct optee_smc_disable_shm_cache_result result;
-		} res;
-
-		optee->invoke_fn(OPTEE_SMC_DISABLE_SHM_CACHE, 0, 0, 0, 0, 0, 0,
-				 0, &res.smccc);
-		if (res.result.status == OPTEE_SMC_RETURN_ENOTAVAIL)
-			break; /* All shm's freed */
-		if (res.result.status == OPTEE_SMC_RETURN_OK) {
-			struct tee_shm *shm;
-
-			/*
-			 * Shared memory references that were not mapped by
-			 * this kernel must be ignored to prevent a crash.
-			 */
-			if (!is_mapped)
-				continue;
-
-			shm = reg_pair_to_ptr(res.result.shm_upper32,
-					      res.result.shm_lower32);
-			tee_shm_free(shm);
-		} else {
-			optee_cq_wait_for_completion(&optee->call_queue, &w);
-		}
-	}
-	optee_cq_wait_final(&optee->call_queue, &w);
-}
-
-/**
- * optee_disable_shm_cache() - Disables caching of mapped shared memory
- *                             allocations in OP-TEE
- * @optee:	main service struct
- */
-void optee_disable_shm_cache(struct optee *optee)
-{
-	return __optee_disable_shm_cache(optee, true);
-}
-
-/**
- * optee_disable_unmapped_shm_cache() - Disables caching of shared memory
- *                                      allocations in OP-TEE which are not
- *                                      currently mapped
- * @optee:	main service struct
- */
-void optee_disable_unmapped_shm_cache(struct optee *optee)
-{
-	return __optee_disable_shm_cache(optee, false);
-}
-
-#define PAGELIST_ENTRIES_PER_PAGE				\
-	((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1)
-
-/**
- * optee_fill_pages_list() - write list of user pages to given shared
- * buffer.
- *
- * @dst: page-aligned buffer where list of pages will be stored
- * @pages: array of pages that represents shared buffer
- * @num_pages: number of entries in @pages
- * @page_offset: offset of user buffer from page start
- *
- * @dst should be big enough to hold list of user page addresses and
- *	links to the next pages of buffer
- */
-void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
-			   size_t page_offset)
-{
-	int n = 0;
-	phys_addr_t optee_page;
-	/*
-	 * Refer to OPTEE_MSG_ATTR_NONCONTIG description in optee_msg.h
-	 * for details.
-	 */
-	struct {
-		u64 pages_list[PAGELIST_ENTRIES_PER_PAGE];
-		u64 next_page_data;
-	} *pages_data;
-
-	/*
-	 * Currently OP-TEE uses 4k page size and it does not looks
-	 * like this will change in the future.  On other hand, there are
-	 * no know ARM architectures with page size < 4k.
-	 * Thus the next built assert looks redundant. But the following
-	 * code heavily relies on this assumption, so it is better be
-	 * safe than sorry.
-	 */
-	BUILD_BUG_ON(PAGE_SIZE < OPTEE_MSG_NONCONTIG_PAGE_SIZE);
-
-	pages_data = (void *)dst;
-	/*
-	 * If linux page is bigger than 4k, and user buffer offset is
-	 * larger than 4k/8k/12k/etc this will skip first 4k pages,
-	 * because they bear no value data for OP-TEE.
-	 */
-	optee_page = page_to_phys(*pages) +
-		round_down(page_offset, OPTEE_MSG_NONCONTIG_PAGE_SIZE);
-
-	while (true) {
-		pages_data->pages_list[n++] = optee_page;
-
-		if (n == PAGELIST_ENTRIES_PER_PAGE) {
-			pages_data->next_page_data =
-				virt_to_phys(pages_data + 1);
-			pages_data++;
-			n = 0;
-		}
-
-		optee_page += OPTEE_MSG_NONCONTIG_PAGE_SIZE;
-		if (!(optee_page & ~PAGE_MASK)) {
-			if (!--num_pages)
-				break;
-			pages++;
-			optee_page = page_to_phys(*pages);
-		}
-	}
-}
-
-/*
- * The final entry in each pagelist page is a pointer to the next
- * pagelist page.
- */
-static size_t get_pages_list_size(size_t num_entries)
-{
-	int pages = DIV_ROUND_UP(num_entries, PAGELIST_ENTRIES_PER_PAGE);
-
-	return pages * OPTEE_MSG_NONCONTIG_PAGE_SIZE;
-}
-
-u64 *optee_allocate_pages_list(size_t num_entries)
-{
-	return alloc_pages_exact(get_pages_list_size(num_entries), GFP_KERNEL);
-}
-
-void optee_free_pages_list(void *list, size_t num_entries)
-{
-	free_pages_exact(list, get_pages_list_size(num_entries));
-}
-
 static bool is_normal_memory(pgprot_t p)
 {
 #if defined(CONFIG_ARM)
@@ -596,7 +344,7 @@ static int __check_mem_type(struct vm_area_struct *vma, unsigned long end)
 	return -EINVAL;
 }
 
-static int check_mem_type(unsigned long start, size_t num_pages)
+int optee_check_mem_type(unsigned long start, size_t num_pages)
 {
 	struct mm_struct *mm = current->mm;
 	int rc;
@@ -615,94 +363,3 @@ static int check_mem_type(unsigned long start, size_t num_pages)
 
 	return rc;
 }
-
-int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
-		       struct page **pages, size_t num_pages,
-		       unsigned long start)
-{
-	struct optee *optee = tee_get_drvdata(ctx->teedev);
-	struct optee_msg_arg *msg_arg;
-	struct tee_shm *shm_arg;
-	u64 *pages_list;
-	int rc;
-
-	if (!num_pages)
-		return -EINVAL;
-
-	rc = check_mem_type(start, num_pages);
-	if (rc)
-		return rc;
-
-	pages_list = optee_allocate_pages_list(num_pages);
-	if (!pages_list)
-		return -ENOMEM;
-
-	shm_arg = get_msg_arg(ctx, 1, &msg_arg);
-	if (IS_ERR(shm_arg)) {
-		rc = PTR_ERR(shm_arg);
-		goto out;
-	}
-
-	optee_fill_pages_list(pages_list, pages, num_pages,
-			      tee_shm_get_page_offset(shm));
-
-	msg_arg->cmd = OPTEE_MSG_CMD_REGISTER_SHM;
-	msg_arg->params->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
-				OPTEE_MSG_ATTR_NONCONTIG;
-	msg_arg->params->u.tmem.shm_ref = (unsigned long)shm;
-	msg_arg->params->u.tmem.size = tee_shm_get_size(shm);
-	/*
-	 * In the least bits of msg_arg->params->u.tmem.buf_ptr we
-	 * store buffer offset from 4k page, as described in OP-TEE ABI.
-	 */
-	msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
-	  (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
-
-	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
-	    msg_arg->ret != TEEC_SUCCESS)
-		rc = -EINVAL;
-
-	tee_shm_free(shm_arg);
-out:
-	optee_free_pages_list(pages_list, num_pages);
-	return rc;
-}
-
-int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
-{
-	struct optee *optee = tee_get_drvdata(ctx->teedev);
-	struct optee_msg_arg *msg_arg;
-	struct tee_shm *shm_arg;
-	int rc = 0;
-
-	shm_arg = get_msg_arg(ctx, 1, &msg_arg);
-	if (IS_ERR(shm_arg))
-		return PTR_ERR(shm_arg);
-
-	msg_arg->cmd = OPTEE_MSG_CMD_UNREGISTER_SHM;
-
-	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
-	msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;
-
-	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
-	    msg_arg->ret != TEEC_SUCCESS)
-		rc = -EINVAL;
-	tee_shm_free(shm_arg);
-	return rc;
-}
-
-int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
-			    struct page **pages, size_t num_pages,
-			    unsigned long start)
-{
-	/*
-	 * We don't want to register supplicant memory in OP-TEE.
-	 * Instead information about it will be passed in RPC code.
-	 */
-	return check_mem_type(start, num_pages);
-}
-
-int optee_shm_unregister_supp(struct tee_context *ctx, struct tee_shm *shm)
-{
-	return 0;
-}
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 50650224e311..9e3b6cdbe371 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -1,260 +1,71 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2015-2021, Linaro Limited
+ * Copyright (c) 2016, EPAM Systems
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/arm-smccc.h>
 #include <linux/crash_dump.h>
 #include <linux/errno.h>
 #include <linux/io.h>
+#include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/tee_drv.h>
 #include <linux/types.h>
-#include <linux/uaccess.h>
 #include <linux/workqueue.h>
 #include "optee_private.h"
-#include "optee_smc.h"
-#include "shm_pool.h"
 
-#define DRIVER_NAME "optee"
-
-#define OPTEE_SHM_NUM_PRIV_PAGES	CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
-
-static void from_msg_param_value(struct tee_param *p, u32 attr,
-				 const struct optee_msg_param *mp)
-{
-	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
-		  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
-	p->u.value.a = mp->u.value.a;
-	p->u.value.b = mp->u.value.b;
-	p->u.value.c = mp->u.value.c;
-}
-
-static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
-				  const struct optee_msg_param *mp)
-{
-	struct tee_shm *shm;
-	phys_addr_t pa;
-	int rc;
-
-	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
-		  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
-	p->u.memref.size = mp->u.tmem.size;
-	shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
-	if (!shm) {
-		p->u.memref.shm_offs = 0;
-		p->u.memref.shm = NULL;
-		return 0;
-	}
-
-	rc = tee_shm_get_pa(shm, 0, &pa);
-	if (rc)
-		return rc;
-
-	p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
-	p->u.memref.shm = shm;
-
-	/* Check that the memref is covered by the shm object */
-	if (p->u.memref.size) {
-		size_t o = p->u.memref.shm_offs +
-			   p->u.memref.size - 1;
-
-		rc = tee_shm_get_pa(shm, o, NULL);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}
-
-static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
-				   const struct optee_msg_param *mp)
+int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
+			       struct tee_shm *shm, size_t size,
+			       int (*shm_register)(struct tee_context *ctx,
+						   struct tee_shm *shm,
+						   struct page **pages,
+						   size_t num_pages,
+						   unsigned long start))
 {
-	struct tee_shm *shm;
+	unsigned int order = get_order(size);
+	struct page *page;
+	int rc = 0;
 
-	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
-		  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
-	p->u.memref.size = mp->u.rmem.size;
-	shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
-
-	if (shm) {
-		p->u.memref.shm_offs = mp->u.rmem.offs;
-		p->u.memref.shm = shm;
-	} else {
-		p->u.memref.shm_offs = 0;
-		p->u.memref.shm = NULL;
-	}
-}
-
-/**
- * optee_from_msg_param() - convert from OPTEE_MSG parameters to
- *			    struct tee_param
- * @optee:	main service struct
- * @params:	subsystem internal parameter representation
- * @num_params:	number of elements in the parameter arrays
- * @msg_params:	OPTEE_MSG parameters
- * Returns 0 on success or <0 on failure
- */
-static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
-				size_t num_params,
-				const struct optee_msg_param *msg_params)
-{
-	int rc;
-	size_t n;
+	page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+	if (!page)
+		return -ENOMEM;
 
-	for (n = 0; n < num_params; n++) {
-		struct tee_param *p = params + n;
-		const struct optee_msg_param *mp = msg_params + n;
-		u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
+	shm->kaddr = page_address(page);
+	shm->paddr = page_to_phys(page);
+	shm->size = PAGE_SIZE << order;
 
-		switch (attr) {
-		case OPTEE_MSG_ATTR_TYPE_NONE:
-			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
-			memset(&p->u, 0, sizeof(p->u));
-			break;
-		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
-		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
-		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
-			from_msg_param_value(p, attr, mp);
-			break;
-		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
-		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
-		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
-			rc = from_msg_param_tmp_mem(p, attr, mp);
-			if (rc)
-				return rc;
-			break;
-		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
-		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
-		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
-			from_msg_param_reg_mem(p, attr, mp);
-			break;
+	if (shm_register) {
+		unsigned int nr_pages = 1 << order, i;
+		struct page **pages;
 
-		default:
-			return -EINVAL;
+		pages = kcalloc(nr_pages, sizeof(pages), GFP_KERNEL);
+		if (!pages) {
+			rc = -ENOMEM;
+			goto err;
 		}
-	}
-	return 0;
-}
-
-static void to_msg_param_value(struct optee_msg_param *mp,
-			       const struct tee_param *p)
-{
-	mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
-		   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
-	mp->u.value.a = p->u.value.a;
-	mp->u.value.b = p->u.value.b;
-	mp->u.value.c = p->u.value.c;
-}
-
-static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
-				const struct tee_param *p)
-{
-	int rc;
-	phys_addr_t pa;
 
-	mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
-		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
-
-	mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
-	mp->u.tmem.size = p->u.memref.size;
+		for (i = 0; i < nr_pages; i++) {
+			pages[i] = page;
+			page++;
+		}
 
-	if (!p->u.memref.shm) {
-		mp->u.tmem.buf_ptr = 0;
-		return 0;
+		shm->flags |= TEE_SHM_REGISTER;
+		rc = shm_register(shm->ctx, shm, pages, nr_pages,
+				  (unsigned long)shm->kaddr);
+		kfree(pages);
+		if (rc)
+			goto err;
 	}
 
-	rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
-	if (rc)
-		return rc;
-
-	mp->u.tmem.buf_ptr = pa;
-	mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
-		    OPTEE_MSG_ATTR_CACHE_SHIFT;
-
-	return 0;
-}
-
-static int to_msg_param_reg_mem(struct optee_msg_param *mp,
-				const struct tee_param *p)
-{
-	mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
-		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
-
-	mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
-	mp->u.rmem.size = p->u.memref.size;
-	mp->u.rmem.offs = p->u.memref.shm_offs;
-	return 0;
-}
-
-/**
- * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
- * @optee:	main service struct
- * @msg_params:	OPTEE_MSG parameters
- * @num_params:	number of elements in the parameter arrays
- * @params:	subsystem itnernal parameter representation
- * Returns 0 on success or <0 on failure
- */
-static int optee_to_msg_param(struct optee *optee,
-			      struct optee_msg_param *msg_params,
-			      size_t num_params, const struct tee_param *params)
-{
-	int rc;
-	size_t n;
-
-	for (n = 0; n < num_params; n++) {
-		const struct tee_param *p = params + n;
-		struct optee_msg_param *mp = msg_params + n;
-
-		switch (p->attr) {
-		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
-			mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
-			memset(&mp->u, 0, sizeof(mp->u));
-			break;
-		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
-		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
-		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
-			to_msg_param_value(mp, p);
-			break;
-		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
-		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
-		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
-			if (tee_shm_is_registered(p->u.memref.shm))
-				rc = to_msg_param_reg_mem(mp, p);
-			else
-				rc = to_msg_param_tmp_mem(mp, p);
-			if (rc)
-				return rc;
-			break;
-		default:
-			return -EINVAL;
-		}
-	}
 	return 0;
-}
 
-static void optee_get_version(struct tee_device *teedev,
-			      struct tee_ioctl_version_data *vers)
-{
-	struct tee_ioctl_version_data v = {
-		.impl_id = TEE_IMPL_ID_OPTEE,
-		.impl_caps = TEE_OPTEE_CAP_TZ,
-		.gen_caps = TEE_GEN_CAP_GP,
-	};
-	struct optee *optee = tee_get_drvdata(teedev);
-
-	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
-		v.gen_caps |= TEE_GEN_CAP_REG_MEM;
-	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
-		v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
-	*vers = v;
+err:
+	__free_pages(page, order);
+	return rc;
 }
 
 static void optee_bus_scan(struct work_struct *work)
@@ -262,7 +73,7 @@ static void optee_bus_scan(struct work_struct *work)
 	WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
 }
 
-static int optee_open(struct tee_context *ctx)
+int optee_open(struct tee_context *ctx, bool cap_memref_null)
 {
 	struct optee_context_data *ctxdata;
 	struct tee_device *teedev = ctx->teedev;
@@ -300,11 +111,7 @@ static int optee_open(struct tee_context *ctx)
 	mutex_init(&ctxdata->mutex);
 	INIT_LIST_HEAD(&ctxdata->sess_list);
 
-	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
-		ctx->cap_memref_null  = true;
-	else
-		ctx->cap_memref_null = false;
-
+	ctx->cap_memref_null = cap_memref_null;
 	ctx->data = ctxdata;
 	return 0;
 }
@@ -330,12 +137,12 @@ static void optee_release_helper(struct tee_context *ctx,
 	ctx->data = NULL;
 }
 
-static void optee_release(struct tee_context *ctx)
+void optee_release(struct tee_context *ctx)
 {
 	optee_release_helper(ctx, optee_close_session_helper);
 }
 
-static void optee_release_supp(struct tee_context *ctx)
+void optee_release_supp(struct tee_context *ctx)
 {
 	struct optee *optee = tee_get_drvdata(ctx->teedev);
 
@@ -347,284 +154,8 @@ static void optee_release_supp(struct tee_context *ctx)
 	optee_supp_release(&optee->supp);
 }
 
-static const struct tee_driver_ops optee_clnt_ops = {
-	.get_version = optee_get_version,
-	.open = optee_open,
-	.release = optee_release,
-	.open_session = optee_open_session,
-	.close_session = optee_close_session,
-	.invoke_func = optee_invoke_func,
-	.cancel_req = optee_cancel_req,
-	.shm_register = optee_shm_register,
-	.shm_unregister = optee_shm_unregister,
-};
-
-static const struct tee_desc optee_clnt_desc = {
-	.name = DRIVER_NAME "-clnt",
-	.ops = &optee_clnt_ops,
-	.owner = THIS_MODULE,
-};
-
-static const struct tee_driver_ops optee_supp_ops = {
-	.get_version = optee_get_version,
-	.open = optee_open,
-	.release = optee_release_supp,
-	.supp_recv = optee_supp_recv,
-	.supp_send = optee_supp_send,
-	.shm_register = optee_shm_register_supp,
-	.shm_unregister = optee_shm_unregister_supp,
-};
-
-static const struct tee_desc optee_supp_desc = {
-	.name = DRIVER_NAME "-supp",
-	.ops = &optee_supp_ops,
-	.owner = THIS_MODULE,
-	.flags = TEE_DESC_PRIVILEGED,
-};
-
-static const struct optee_ops optee_ops = {
-	.do_call_with_arg = optee_do_call_with_arg,
-	.to_msg_param = optee_to_msg_param,
-	.from_msg_param = optee_from_msg_param,
-};
-
-static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
-{
-	struct arm_smccc_res res;
-
-	invoke_fn(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res);
-
-	if (res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 &&
-	    res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3)
-		return true;
-	return false;
-}
-
-static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn)
-{
-	union {
-		struct arm_smccc_res smccc;
-		struct optee_smc_call_get_os_revision_result result;
-	} res = {
-		.result = {
-			.build_id = 0
-		}
-	};
-
-	invoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0,
-		  &res.smccc);
-
-	if (res.result.build_id)
-		pr_info("revision %lu.%lu (%08lx)", res.result.major,
-			res.result.minor, res.result.build_id);
-	else
-		pr_info("revision %lu.%lu", res.result.major, res.result.minor);
-}
-
-static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
-{
-	union {
-		struct arm_smccc_res smccc;
-		struct optee_smc_calls_revision_result result;
-	} res;
-
-	invoke_fn(OPTEE_SMC_CALLS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
-
-	if (res.result.major == OPTEE_MSG_REVISION_MAJOR &&
-	    (int)res.result.minor >= OPTEE_MSG_REVISION_MINOR)
-		return true;
-	return false;
-}
-
-static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
-					    u32 *sec_caps)
-{
-	union {
-		struct arm_smccc_res smccc;
-		struct optee_smc_exchange_capabilities_result result;
-	} res;
-	u32 a1 = 0;
-
-	/*
-	 * TODO This isn't enough to tell if it's UP system (from kernel
-	 * point of view) or not, is_smp() returns the the information
-	 * needed, but can't be called directly from here.
-	 */
-	if (!IS_ENABLED(CONFIG_SMP) || nr_cpu_ids == 1)
-		a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR;
-
-	invoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES, a1, 0, 0, 0, 0, 0, 0,
-		  &res.smccc);
-
-	if (res.result.status != OPTEE_SMC_RETURN_OK)
-		return false;
-
-	*sec_caps = res.result.capabilities;
-	return true;
-}
-
-static struct tee_shm_pool *optee_config_dyn_shm(void)
-{
-	struct tee_shm_pool_mgr *priv_mgr;
-	struct tee_shm_pool_mgr *dmabuf_mgr;
-	void *rc;
-
-	rc = optee_shm_pool_alloc_pages();
-	if (IS_ERR(rc))
-		return rc;
-	priv_mgr = rc;
-
-	rc = optee_shm_pool_alloc_pages();
-	if (IS_ERR(rc)) {
-		tee_shm_pool_mgr_destroy(priv_mgr);
-		return rc;
-	}
-	dmabuf_mgr = rc;
-
-	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
-	if (IS_ERR(rc)) {
-		tee_shm_pool_mgr_destroy(priv_mgr);
-		tee_shm_pool_mgr_destroy(dmabuf_mgr);
-	}
-
-	return rc;
-}
-
-static struct tee_shm_pool *
-optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
+void optee_remove_common(struct optee *optee)
 {
-	union {
-		struct arm_smccc_res smccc;
-		struct optee_smc_get_shm_config_result result;
-	} res;
-	unsigned long vaddr;
-	phys_addr_t paddr;
-	size_t size;
-	phys_addr_t begin;
-	phys_addr_t end;
-	void *va;
-	struct tee_shm_pool_mgr *priv_mgr;
-	struct tee_shm_pool_mgr *dmabuf_mgr;
-	void *rc;
-	const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
-
-	invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
-	if (res.result.status != OPTEE_SMC_RETURN_OK) {
-		pr_err("static shm service not available\n");
-		return ERR_PTR(-ENOENT);
-	}
-
-	if (res.result.settings != OPTEE_SMC_SHM_CACHED) {
-		pr_err("only normal cached shared memory supported\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	begin = roundup(res.result.start, PAGE_SIZE);
-	end = rounddown(res.result.start + res.result.size, PAGE_SIZE);
-	paddr = begin;
-	size = end - begin;
-
-	if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
-		pr_err("too small shared memory area\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	va = memremap(paddr, size, MEMREMAP_WB);
-	if (!va) {
-		pr_err("shared memory ioremap failed\n");
-		return ERR_PTR(-EINVAL);
-	}
-	vaddr = (unsigned long)va;
-
-	rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
-					    3 /* 8 bytes aligned */);
-	if (IS_ERR(rc))
-		goto err_memunmap;
-	priv_mgr = rc;
-
-	vaddr += sz;
-	paddr += sz;
-	size -= sz;
-
-	rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT);
-	if (IS_ERR(rc))
-		goto err_free_priv_mgr;
-	dmabuf_mgr = rc;
-
-	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
-	if (IS_ERR(rc))
-		goto err_free_dmabuf_mgr;
-
-	*memremaped_shm = va;
-
-	return rc;
-
-err_free_dmabuf_mgr:
-	tee_shm_pool_mgr_destroy(dmabuf_mgr);
-err_free_priv_mgr:
-	tee_shm_pool_mgr_destroy(priv_mgr);
-err_memunmap:
-	memunmap(va);
-	return rc;
-}
-
-/* Simple wrapper functions to be able to use a function pointer */
-static void optee_smccc_smc(unsigned long a0, unsigned long a1,
-			    unsigned long a2, unsigned long a3,
-			    unsigned long a4, unsigned long a5,
-			    unsigned long a6, unsigned long a7,
-			    struct arm_smccc_res *res)
-{
-	arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
-}
-
-static void optee_smccc_hvc(unsigned long a0, unsigned long a1,
-			    unsigned long a2, unsigned long a3,
-			    unsigned long a4, unsigned long a5,
-			    unsigned long a6, unsigned long a7,
-			    struct arm_smccc_res *res)
-{
-	arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
-}
-
-static optee_invoke_fn *get_invoke_func(struct device *dev)
-{
-	const char *method;
-
-	pr_info("probing for conduit method.\n");
-
-	if (device_property_read_string(dev, "method", &method)) {
-		pr_warn("missing \"method\" property\n");
-		return ERR_PTR(-ENXIO);
-	}
-
-	if (!strcmp("hvc", method))
-		return optee_smccc_hvc;
-	else if (!strcmp("smc", method))
-		return optee_smccc_smc;
-
-	pr_warn("invalid \"method\" property: %s\n", method);
-	return ERR_PTR(-EINVAL);
-}
-
-/* optee_remove - Device Removal Routine
- * @pdev: platform device information struct
- *
- * optee_remove is called by platform subsystem to alert the driver
- * that it should release the device
- */
-
-static int optee_remove(struct platform_device *pdev)
-{
-	struct optee *optee = platform_get_drvdata(pdev);
-
-	/*
-	 * Ask OP-TEE to free all cached shared memory objects to decrease
-	 * reference counters and also avoid wild pointers in secure world
-	 * into the old shared memory range.
-	 */
-	optee_disable_shm_cache(optee);
-
 	/*
 	 * The two devices have to be unregistered before we can free the
 	 * other resources.
@@ -633,39 +164,13 @@ static int optee_remove(struct platform_device *pdev)
 	tee_device_unregister(optee->teedev);
 
 	tee_shm_pool_free(optee->pool);
-	if (optee->memremaped_shm)
-		memunmap(optee->memremaped_shm);
 	optee_wait_queue_exit(&optee->wait_queue);
 	optee_supp_uninit(&optee->supp);
 	mutex_destroy(&optee->call_queue.mutex);
-
-	kfree(optee);
-
-	return 0;
-}
-
-/* optee_shutdown - Device Removal Routine
- * @pdev: platform device information struct
- *
- * platform_shutdown is called by the platform subsystem to alert
- * the driver that a shutdown, reboot, or kexec is happening and
- * device must be disabled.
- */
-static void optee_shutdown(struct platform_device *pdev)
-{
-	optee_disable_shm_cache(platform_get_drvdata(pdev));
 }
 
-static int optee_probe(struct platform_device *pdev)
+static int optee_core_init(void)
 {
-	optee_invoke_fn *invoke_fn;
-	struct tee_shm_pool *pool = ERR_PTR(-EINVAL);
-	struct optee *optee = NULL;
-	void *memremaped_shm = NULL;
-	struct tee_device *teedev;
-	u32 sec_caps;
-	int rc;
-
 	/*
 	 * The kernel may have crashed at the same time that all available
 	 * secure world threads were suspended and we cannot reschedule the
@@ -676,139 +181,15 @@ static int optee_probe(struct platform_device *pdev)
 	if (is_kdump_kernel())
 		return -ENODEV;
 
-	invoke_fn = get_invoke_func(&pdev->dev);
-	if (IS_ERR(invoke_fn))
-		return PTR_ERR(invoke_fn);
-
-	if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
-		pr_warn("api uid mismatch\n");
-		return -EINVAL;
-	}
-
-	optee_msg_get_os_revision(invoke_fn);
-
-	if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
-		pr_warn("api revision mismatch\n");
-		return -EINVAL;
-	}
-
-	if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
-		pr_warn("capabilities mismatch\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * Try to use dynamic shared memory if possible
-	 */
-	if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
-		pool = optee_config_dyn_shm();
-
-	/*
-	 * If dynamic shared memory is not available or failed - try static one
-	 */
-	if (IS_ERR(pool) && (sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
-		pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
-
-	if (IS_ERR(pool))
-		return PTR_ERR(pool);
-
-	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
-	if (!optee) {
-		rc = -ENOMEM;
-		goto err;
-	}
-
-	optee->ops = &optee_ops;
-	optee->invoke_fn = invoke_fn;
-	optee->sec_caps = sec_caps;
-
-	teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
-	if (IS_ERR(teedev)) {
-		rc = PTR_ERR(teedev);
-		goto err;
-	}
-	optee->teedev = teedev;
-
-	teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee);
-	if (IS_ERR(teedev)) {
-		rc = PTR_ERR(teedev);
-		goto err;
-	}
-	optee->supp_teedev = teedev;
-
-	rc = tee_device_register(optee->teedev);
-	if (rc)
-		goto err;
-
-	rc = tee_device_register(optee->supp_teedev);
-	if (rc)
-		goto err;
-
-	mutex_init(&optee->call_queue.mutex);
-	INIT_LIST_HEAD(&optee->call_queue.waiters);
-	optee_wait_queue_init(&optee->wait_queue);
-	optee_supp_init(&optee->supp);
-	optee->memremaped_shm = memremaped_shm;
-	optee->pool = pool;
-
-	/*
-	 * Ensure that there are no pre-existing shm objects before enabling
-	 * the shm cache so that there's no chance of receiving an invalid
-	 * address during shutdown. This could occur, for example, if we're
-	 * kexec booting from an older kernel that did not properly cleanup the
-	 * shm cache.
-	 */
-	optee_disable_unmapped_shm_cache(optee);
-
-	optee_enable_shm_cache(optee);
-
-	if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
-		pr_info("dynamic shared memory is enabled\n");
-
-	platform_set_drvdata(pdev, optee);
-
-	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
-	if (rc) {
-		optee_remove(pdev);
-		return rc;
-	}
-
-	pr_info("initialized driver\n");
-	return 0;
-err:
-	if (optee) {
-		/*
-		 * tee_device_unregister() is safe to call even if the
-		 * devices hasn't been registered with
-		 * tee_device_register() yet.
-		 */
-		tee_device_unregister(optee->supp_teedev);
-		tee_device_unregister(optee->teedev);
-		kfree(optee);
-	}
-	if (pool)
-		tee_shm_pool_free(pool);
-	if (memremaped_shm)
-		memunmap(memremaped_shm);
-	return rc;
+	return optee_smc_abi_register();
 }
+module_init(optee_core_init);
 
-static const struct of_device_id optee_dt_match[] = {
-	{ .compatible = "linaro,optee-tz" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, optee_dt_match);
-
-static struct platform_driver optee_driver = {
-	.probe  = optee_probe,
-	.remove = optee_remove,
-	.shutdown = optee_shutdown,
-	.driver = {
-		.name = "optee",
-		.of_match_table = optee_dt_match,
-	},
-};
-module_platform_driver(optee_driver);
+static void optee_core_exit(void)
+{
+	optee_smc_abi_unregister();
+}
+module_exit(optee_core_exit);
 
 MODULE_AUTHOR("Linaro");
 MODULE_DESCRIPTION("OP-TEE driver");
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 92d59c145d4a..ca0213e330b5 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -12,6 +12,8 @@
 #include <linux/types.h>
 #include "optee_msg.h"
 
+#define DRIVER_NAME "optee"
+
 #define OPTEE_MAX_ARG_SIZE	1024
 
 /* Some Global Platform error codes used in this driver */
@@ -29,6 +31,11 @@ typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long,
 				unsigned long, unsigned long,
 				struct arm_smccc_res *);
 
+struct optee_call_waiter {
+	struct list_head list_node;
+	struct completion c;
+};
+
 struct optee_call_queue {
 	/* Serializes access to this struct */
 	struct mutex mutex;
@@ -66,6 +73,19 @@ struct optee_supp {
 	struct completion reqs_c;
 };
 
+/**
+ * struct optee_smc - SMC ABI specifics
+ * @invoke_fn:		function to issue smc or hvc
+ * @memremaped_shm	virtual address of memory in shared memory pool
+ * @sec_caps:		secure world capabilities defined by
+ *			OPTEE_SMC_SEC_CAP_* in optee_smc.h
+ */
+struct optee_smc {
+	optee_invoke_fn *invoke_fn;
+	void *memremaped_shm;
+	u32 sec_caps;
+};
+
 struct optee;
 
 /**
@@ -95,15 +115,12 @@ struct optee_ops {
  * @ops:		internal callbacks for different ways to reach secure
  *			world
  * @teedev:		client device
- * @invoke_fn:		function to issue smc or hvc
+ * @smc:		specific to SMC ABI
  * @call_queue:		queue of threads waiting to call @invoke_fn
  * @wait_queue:		queue of threads from secure world waiting for a
  *			secure world sync object
  * @supp:		supplicant synchronization struct for RPC to supplicant
  * @pool:		shared memory pool
- * @memremaped_shm	virtual address of memory in shared memory pool
- * @sec_caps:		secure world capabilities defined by
- *			OPTEE_SMC_SEC_CAP_* in optee_smc.h
  * @scan_bus_done	flag if device registation was already done.
  * @scan_bus_wq		workqueue to scan optee bus and register optee drivers
  * @scan_bus_work	workq to scan optee bus and register optee drivers
@@ -112,13 +129,11 @@ struct optee {
 	struct tee_device *supp_teedev;
 	struct tee_device *teedev;
 	const struct optee_ops *ops;
-	optee_invoke_fn *invoke_fn;
+	struct optee_smc smc;
 	struct optee_call_queue call_queue;
 	struct optee_wait_queue wait_queue;
 	struct optee_supp supp;
 	struct tee_shm_pool *pool;
-	void *memremaped_shm;
-	u32 sec_caps;
 	bool   scan_bus_done;
 	struct workqueue_struct *scan_bus_wq;
 	struct work_struct scan_bus_work;
@@ -153,10 +168,6 @@ struct optee_call_ctx {
 	size_t num_entries;
 };
 
-void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
-		      struct optee_call_ctx *call_ctx);
-void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx);
-
 void optee_wait_queue_init(struct optee_wait_queue *wq);
 void optee_wait_queue_exit(struct optee_wait_queue *wq);
 
@@ -174,7 +185,6 @@ int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
 int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
 		    struct tee_param *param);
 
-int optee_do_call_with_arg(struct tee_context *ctx, struct tee_shm *arg);
 int optee_open_session(struct tee_context *ctx,
 		       struct tee_ioctl_open_session_arg *arg,
 		       struct tee_param *param);
@@ -184,28 +194,58 @@ int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 		      struct tee_param *param);
 int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
 
-void optee_enable_shm_cache(struct optee *optee);
-void optee_disable_shm_cache(struct optee *optee);
-void optee_disable_unmapped_shm_cache(struct optee *optee);
+#define PTA_CMD_GET_DEVICES		0x0
+#define PTA_CMD_GET_DEVICES_SUPP	0x1
+int optee_enumerate_devices(u32 func);
 
-int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
-		       struct page **pages, size_t num_pages,
-		       unsigned long start);
-int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm);
+int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
+			       struct tee_shm *shm, size_t size,
+			       int (*shm_register)(struct tee_context *ctx,
+						   struct tee_shm *shm,
+						   struct page **pages,
+						   size_t num_pages,
+						   unsigned long start));
 
-int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
-			    struct page **pages, size_t num_pages,
-			    unsigned long start);
-int optee_shm_unregister_supp(struct tee_context *ctx, struct tee_shm *shm);
 
-u64 *optee_allocate_pages_list(size_t num_entries);
-void optee_free_pages_list(void *array, size_t num_entries);
-void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
-			   size_t page_offset);
+void optee_remove_common(struct optee *optee);
+int optee_open(struct tee_context *ctx, bool cap_memref_null);
+void optee_release(struct tee_context *ctx);
+void optee_release_supp(struct tee_context *ctx);
 
-#define PTA_CMD_GET_DEVICES		0x0
-#define PTA_CMD_GET_DEVICES_SUPP	0x1
-int optee_enumerate_devices(u32 func);
+static inline void optee_from_msg_param_value(struct tee_param *p, u32 attr,
+					      const struct optee_msg_param *mp)
+{
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
+	p->u.value.a = mp->u.value.a;
+	p->u.value.b = mp->u.value.b;
+	p->u.value.c = mp->u.value.c;
+}
+
+static inline void optee_to_msg_param_value(struct optee_msg_param *mp,
+					    const struct tee_param *p)
+{
+	mp->attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+	mp->u.value.a = p->u.value.a;
+	mp->u.value.b = p->u.value.b;
+	mp->u.value.c = p->u.value.c;
+}
+
+void optee_cq_wait_init(struct optee_call_queue *cq,
+			struct optee_call_waiter *w);
+void optee_cq_wait_for_completion(struct optee_call_queue *cq,
+				  struct optee_call_waiter *w);
+void optee_cq_wait_final(struct optee_call_queue *cq,
+			 struct optee_call_waiter *w);
+int optee_check_mem_type(unsigned long start, size_t num_pages);
+struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params,
+				  struct optee_msg_arg **msg_arg);
+
+struct tee_shm *optee_rpc_cmd_alloc_suppl(struct tee_context *ctx, size_t sz);
+void optee_rpc_cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm);
+void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
+		   struct optee_msg_arg *arg);
 
 /*
  * Small helpers
@@ -222,4 +262,8 @@ static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
 	*reg1 = val;
 }
 
+/* Registration of the ABIs */
+int optee_smc_abi_register(void);
+void optee_smc_abi_unregister(void);
+
 #endif /*OPTEE_PRIVATE_H*/
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
index 309258d47790..cd642e340eaf 100644
--- a/drivers/tee/optee/rpc.c
+++ b/drivers/tee/optee/rpc.c
@@ -6,12 +6,10 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/delay.h>
-#include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/tee_drv.h>
 #include "optee_private.h"
-#include "optee_smc.h"
 #include "optee_rpc_cmd.h"
 
 struct wq_entry {
@@ -266,7 +264,7 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
 	kfree(params);
 }
 
-static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
+struct tee_shm *optee_rpc_cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
 {
 	u32 ret;
 	struct tee_param param;
@@ -289,103 +287,7 @@ static struct tee_shm *cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
 	return shm;
 }
 
-static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
-					  struct optee_msg_arg *arg,
-					  struct optee_call_ctx *call_ctx)
-{
-	phys_addr_t pa;
-	struct tee_shm *shm;
-	size_t sz;
-	size_t n;
-
-	arg->ret_origin = TEEC_ORIGIN_COMMS;
-
-	if (!arg->num_params ||
-	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-		return;
-	}
-
-	for (n = 1; n < arg->num_params; n++) {
-		if (arg->params[n].attr != OPTEE_MSG_ATTR_TYPE_NONE) {
-			arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-			return;
-		}
-	}
-
-	sz = arg->params[0].u.value.b;
-	switch (arg->params[0].u.value.a) {
-	case OPTEE_RPC_SHM_TYPE_APPL:
-		shm = cmd_alloc_suppl(ctx, sz);
-		break;
-	case OPTEE_RPC_SHM_TYPE_KERNEL:
-		shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
-		break;
-	default:
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-		return;
-	}
-
-	if (IS_ERR(shm)) {
-		arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
-		return;
-	}
-
-	if (tee_shm_get_pa(shm, 0, &pa)) {
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-		goto bad;
-	}
-
-	sz = tee_shm_get_size(shm);
-
-	if (tee_shm_is_registered(shm)) {
-		struct page **pages;
-		u64 *pages_list;
-		size_t page_num;
-
-		pages = tee_shm_get_pages(shm, &page_num);
-		if (!pages || !page_num) {
-			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
-			goto bad;
-		}
-
-		pages_list = optee_allocate_pages_list(page_num);
-		if (!pages_list) {
-			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
-			goto bad;
-		}
-
-		call_ctx->pages_list = pages_list;
-		call_ctx->num_entries = page_num;
-
-		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
-				      OPTEE_MSG_ATTR_NONCONTIG;
-		/*
-		 * In the least bits of u.tmem.buf_ptr we store buffer offset
-		 * from 4k page, as described in OP-TEE ABI.
-		 */
-		arg->params[0].u.tmem.buf_ptr = virt_to_phys(pages_list) |
-			(tee_shm_get_page_offset(shm) &
-			 (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
-		arg->params[0].u.tmem.size = tee_shm_get_size(shm);
-		arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
-
-		optee_fill_pages_list(pages_list, pages, page_num,
-				      tee_shm_get_page_offset(shm));
-	} else {
-		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT;
-		arg->params[0].u.tmem.buf_ptr = pa;
-		arg->params[0].u.tmem.size = sz;
-		arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
-	}
-
-	arg->ret = TEEC_SUCCESS;
-	return;
-bad:
-	tee_shm_free(shm);
-}
-
-static void cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
+void optee_rpc_cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
 {
 	struct tee_param param;
 
@@ -410,60 +312,9 @@ static void cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
 	optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_FREE, 1, &param);
 }
 
-static void handle_rpc_func_cmd_shm_free(struct tee_context *ctx,
-					 struct optee_msg_arg *arg)
-{
-	struct tee_shm *shm;
-
-	arg->ret_origin = TEEC_ORIGIN_COMMS;
-
-	if (arg->num_params != 1 ||
-	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-		return;
-	}
-
-	shm = (struct tee_shm *)(unsigned long)arg->params[0].u.value.b;
-	switch (arg->params[0].u.value.a) {
-	case OPTEE_RPC_SHM_TYPE_APPL:
-		cmd_free_suppl(ctx, shm);
-		break;
-	case OPTEE_RPC_SHM_TYPE_KERNEL:
-		tee_shm_free(shm);
-		break;
-	default:
-		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
-	}
-	arg->ret = TEEC_SUCCESS;
-}
-
-static void free_pages_list(struct optee_call_ctx *call_ctx)
-{
-	if (call_ctx->pages_list) {
-		optee_free_pages_list(call_ctx->pages_list,
-				      call_ctx->num_entries);
-		call_ctx->pages_list = NULL;
-		call_ctx->num_entries = 0;
-	}
-}
-
-void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx)
-{
-	free_pages_list(call_ctx);
-}
-
-static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
-				struct tee_shm *shm,
-				struct optee_call_ctx *call_ctx)
+void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
+		   struct optee_msg_arg *arg)
 {
-	struct optee_msg_arg *arg;
-
-	arg = tee_shm_get_va(shm, 0);
-	if (IS_ERR(arg)) {
-		pr_err("%s: tee_shm_get_va %p failed\n", __func__, shm);
-		return;
-	}
-
 	switch (arg->cmd) {
 	case OPTEE_RPC_CMD_GET_TIME:
 		handle_rpc_func_cmd_get_time(arg);
@@ -474,13 +325,6 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
 	case OPTEE_RPC_CMD_SUSPEND:
 		handle_rpc_func_cmd_wait(arg);
 		break;
-	case OPTEE_RPC_CMD_SHM_ALLOC:
-		free_pages_list(call_ctx);
-		handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
-		break;
-	case OPTEE_RPC_CMD_SHM_FREE:
-		handle_rpc_func_cmd_shm_free(ctx, arg);
-		break;
 	case OPTEE_RPC_CMD_I2C_TRANSFER:
 		handle_rpc_func_cmd_i2c_transfer(ctx, arg);
 		break;
@@ -489,58 +333,4 @@ static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
 	}
 }
 
-/**
- * optee_handle_rpc() - handle RPC from secure world
- * @ctx:	context doing the RPC
- * @param:	value of registers for the RPC
- * @call_ctx:	call context. Preserved during one OP-TEE invocation
- *
- * Result of RPC is written back into @param.
- */
-void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
-		      struct optee_call_ctx *call_ctx)
-{
-	struct tee_device *teedev = ctx->teedev;
-	struct optee *optee = tee_get_drvdata(teedev);
-	struct tee_shm *shm;
-	phys_addr_t pa;
-
-	switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
-	case OPTEE_SMC_RPC_FUNC_ALLOC:
-		shm = tee_shm_alloc(ctx, param->a1,
-				    TEE_SHM_MAPPED | TEE_SHM_PRIV);
-		if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
-			reg_pair_from_64(&param->a1, &param->a2, pa);
-			reg_pair_from_64(&param->a4, &param->a5,
-					 (unsigned long)shm);
-		} else {
-			param->a1 = 0;
-			param->a2 = 0;
-			param->a4 = 0;
-			param->a5 = 0;
-		}
-		break;
-	case OPTEE_SMC_RPC_FUNC_FREE:
-		shm = reg_pair_to_ptr(param->a1, param->a2);
-		tee_shm_free(shm);
-		break;
-	case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR:
-		/*
-		 * A foreign interrupt was raised while secure world was
-		 * executing, since they are handled in Linux a dummy RPC is
-		 * performed to let Linux take the interrupt through the normal
-		 * vector.
-		 */
-		break;
-	case OPTEE_SMC_RPC_FUNC_CMD:
-		shm = reg_pair_to_ptr(param->a1, param->a2);
-		handle_rpc_func_cmd(ctx, optee, shm, call_ctx);
-		break;
-	default:
-		pr_warn("Unknown RPC func 0x%x\n",
-			(u32)OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0));
-		break;
-	}
 
-	param->a0 = OPTEE_SMC_CALL_RETURN_FROM_RPC;
-}
diff --git a/drivers/tee/optee/shm_pool.c b/drivers/tee/optee/shm_pool.c
deleted file mode 100644
index c41a9a501a6e..000000000000
--- a/drivers/tee/optee/shm_pool.c
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2015, Linaro Limited
- * Copyright (c) 2017, EPAM Systems
- */
-#include <linux/device.h>
-#include <linux/dma-buf.h>
-#include <linux/genalloc.h>
-#include <linux/slab.h>
-#include <linux/tee_drv.h>
-#include "optee_private.h"
-#include "optee_smc.h"
-#include "shm_pool.h"
-
-static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
-			 struct tee_shm *shm, size_t size)
-{
-	unsigned int order = get_order(size);
-	struct page *page;
-	int rc = 0;
-
-	page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
-	if (!page)
-		return -ENOMEM;
-
-	shm->kaddr = page_address(page);
-	shm->paddr = page_to_phys(page);
-	shm->size = PAGE_SIZE << order;
-
-	/*
-	 * Shared memory private to the OP-TEE driver doesn't need
-	 * to be registered with OP-TEE.
-	 */
-	if (!(shm->flags & TEE_SHM_PRIV)) {
-		unsigned int nr_pages = 1 << order, i;
-		struct page **pages;
-
-		pages = kcalloc(nr_pages, sizeof(pages), GFP_KERNEL);
-		if (!pages) {
-			rc = -ENOMEM;
-			goto err;
-		}
-
-		for (i = 0; i < nr_pages; i++) {
-			pages[i] = page;
-			page++;
-		}
-
-		shm->flags |= TEE_SHM_REGISTER;
-		rc = optee_shm_register(shm->ctx, shm, pages, nr_pages,
-					(unsigned long)shm->kaddr);
-		kfree(pages);
-		if (rc)
-			goto err;
-	}
-
-	return 0;
-
-err:
-	__free_pages(page, order);
-	return rc;
-}
-
-static void pool_op_free(struct tee_shm_pool_mgr *poolm,
-			 struct tee_shm *shm)
-{
-	if (!(shm->flags & TEE_SHM_PRIV))
-		optee_shm_unregister(shm->ctx, shm);
-
-	free_pages((unsigned long)shm->kaddr, get_order(shm->size));
-	shm->kaddr = NULL;
-}
-
-static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
-{
-	kfree(poolm);
-}
-
-static const struct tee_shm_pool_mgr_ops pool_ops = {
-	.alloc = pool_op_alloc,
-	.free = pool_op_free,
-	.destroy_poolmgr = pool_op_destroy_poolmgr,
-};
-
-/**
- * optee_shm_pool_alloc_pages() - create page-based allocator pool
- *
- * This pool is used when OP-TEE supports dymanic SHM. In this case
- * command buffers and such are allocated from kernel's own memory.
- */
-struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void)
-{
-	struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
-
-	if (!mgr)
-		return ERR_PTR(-ENOMEM);
-
-	mgr->ops = &pool_ops;
-
-	return mgr;
-}
diff --git a/drivers/tee/optee/shm_pool.h b/drivers/tee/optee/shm_pool.h
deleted file mode 100644
index 28109d991c4b..000000000000
--- a/drivers/tee/optee/shm_pool.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2015, Linaro Limited
- * Copyright (c) 2016, EPAM Systems
- */
-
-#ifndef SHM_POOL_H
-#define SHM_POOL_H
-
-#include <linux/tee_drv.h>
-
-struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void);
-
-#endif
diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c
new file mode 100644
index 000000000000..32e0d4feb030
--- /dev/null
+++ b/drivers/tee/optee/smc_abi.c
@@ -0,0 +1,1360 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015-2021, Linaro Limited
+ * Copyright (c) 2016, EPAM Systems
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/arm-smccc.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include "optee_private.h"
+#include "optee_smc.h"
+#include "optee_rpc_cmd.h"
+#define CREATE_TRACE_POINTS
+#include "optee_trace.h"
+
+/*
+ * This file implement the SMC ABI used when communicating with secure world
+ * OP-TEE OS via raw SMCs.
+ * This file is divided into the following sections:
+ * 1. Convert between struct tee_param and struct optee_msg_param
+ * 2. Low level support functions to register shared memory in secure world
+ * 3. Dynamic shared memory pool based on alloc_pages()
+ * 4. Do a normal scheduled call into secure world
+ * 5. Driver initialization.
+ */
+
+#define OPTEE_SHM_NUM_PRIV_PAGES	CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
+
+/*
+ * 1. Convert between struct tee_param and struct optee_msg_param
+ *
+ * optee_from_msg_param() and optee_to_msg_param() are the main
+ * functions.
+ */
+
+static int from_msg_param_tmp_mem(struct tee_param *p, u32 attr,
+				  const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm;
+	phys_addr_t pa;
+	int rc;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
+	p->u.memref.size = mp->u.tmem.size;
+	shm = (struct tee_shm *)(unsigned long)mp->u.tmem.shm_ref;
+	if (!shm) {
+		p->u.memref.shm_offs = 0;
+		p->u.memref.shm = NULL;
+		return 0;
+	}
+
+	rc = tee_shm_get_pa(shm, 0, &pa);
+	if (rc)
+		return rc;
+
+	p->u.memref.shm_offs = mp->u.tmem.buf_ptr - pa;
+	p->u.memref.shm = shm;
+
+	/* Check that the memref is covered by the shm object */
+	if (p->u.memref.size) {
+		size_t o = p->u.memref.shm_offs +
+			   p->u.memref.size - 1;
+
+		rc = tee_shm_get_pa(shm, o, NULL);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
+
+static void from_msg_param_reg_mem(struct tee_param *p, u32 attr,
+				   const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
+	p->u.memref.size = mp->u.rmem.size;
+	shm = (struct tee_shm *)(unsigned long)mp->u.rmem.shm_ref;
+
+	if (shm) {
+		p->u.memref.shm_offs = mp->u.rmem.offs;
+		p->u.memref.shm = shm;
+	} else {
+		p->u.memref.shm_offs = 0;
+		p->u.memref.shm = NULL;
+	}
+}
+
+/**
+ * optee_from_msg_param() - convert from OPTEE_MSG parameters to
+ *			    struct tee_param
+ * @optee:	main service struct
+ * @params:	subsystem internal parameter representation
+ * @num_params:	number of elements in the parameter arrays
+ * @msg_params:	OPTEE_MSG parameters
+ * Returns 0 on success or <0 on failure
+ */
+static int optee_from_msg_param(struct optee *optee, struct tee_param *params,
+				size_t num_params,
+				const struct optee_msg_param *msg_params)
+{
+	int rc;
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_param *p = params + n;
+		const struct optee_msg_param *mp = msg_params + n;
+		u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
+
+		switch (attr) {
+		case OPTEE_MSG_ATTR_TYPE_NONE:
+			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
+			memset(&p->u, 0, sizeof(p->u));
+			break;
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
+			optee_from_msg_param_value(p, attr, mp);
+			break;
+		case OPTEE_MSG_ATTR_TYPE_TMEM_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_TMEM_INOUT:
+			rc = from_msg_param_tmp_mem(p, attr, mp);
+			if (rc)
+				return rc;
+			break;
+		case OPTEE_MSG_ATTR_TYPE_RMEM_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_RMEM_INOUT:
+			from_msg_param_reg_mem(p, attr, mp);
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int to_msg_param_tmp_mem(struct optee_msg_param *mp,
+				const struct tee_param *p)
+{
+	int rc;
+	phys_addr_t pa;
+
+	mp->attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
+
+	mp->u.tmem.shm_ref = (unsigned long)p->u.memref.shm;
+	mp->u.tmem.size = p->u.memref.size;
+
+	if (!p->u.memref.shm) {
+		mp->u.tmem.buf_ptr = 0;
+		return 0;
+	}
+
+	rc = tee_shm_get_pa(p->u.memref.shm, p->u.memref.shm_offs, &pa);
+	if (rc)
+		return rc;
+
+	mp->u.tmem.buf_ptr = pa;
+	mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
+		    OPTEE_MSG_ATTR_CACHE_SHIFT;
+
+	return 0;
+}
+
+static int to_msg_param_reg_mem(struct optee_msg_param *mp,
+				const struct tee_param *p)
+{
+	mp->attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
+
+	mp->u.rmem.shm_ref = (unsigned long)p->u.memref.shm;
+	mp->u.rmem.size = p->u.memref.size;
+	mp->u.rmem.offs = p->u.memref.shm_offs;
+	return 0;
+}
+
+/**
+ * optee_to_msg_param() - convert from struct tee_params to OPTEE_MSG parameters
+ * @optee:	main service struct
+ * @msg_params:	OPTEE_MSG parameters
+ * @num_params:	number of elements in the parameter arrays
+ * @params:	subsystem itnernal parameter representation
+ * Returns 0 on success or <0 on failure
+ */
+static int optee_to_msg_param(struct optee *optee,
+			      struct optee_msg_param *msg_params,
+			      size_t num_params, const struct tee_param *params)
+{
+	int rc;
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		const struct tee_param *p = params + n;
+		struct optee_msg_param *mp = msg_params + n;
+
+		switch (p->attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
+			mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
+			memset(&mp->u, 0, sizeof(mp->u));
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			optee_to_msg_param_value(mp, p);
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			if (tee_shm_is_registered(p->u.memref.shm))
+				rc = to_msg_param_reg_mem(mp, p);
+			else
+				rc = to_msg_param_tmp_mem(mp, p);
+			if (rc)
+				return rc;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+/*
+ * 2. Low level support functions to register shared memory in secure world
+ *
+ * Functions to enable/disable shared memory caching in secure world, that
+ * is, lazy freeing of previously allocated shared memory. Freeing is
+ * performed when a request has been compled.
+ *
+ * Functions to register and unregister shared memory both for normal
+ * clients and for tee-supplicant.
+ */
+
+/**
+ * optee_enable_shm_cache() - Enables caching of some shared memory allocation
+ *			      in OP-TEE
+ * @optee:	main service struct
+ */
+static void optee_enable_shm_cache(struct optee *optee)
+{
+	struct optee_call_waiter w;
+
+	/* We need to retry until secure world isn't busy. */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		struct arm_smccc_res res;
+
+		optee->smc.invoke_fn(OPTEE_SMC_ENABLE_SHM_CACHE,
+				     0, 0, 0, 0, 0, 0, 0, &res);
+		if (res.a0 == OPTEE_SMC_RETURN_OK)
+			break;
+		optee_cq_wait_for_completion(&optee->call_queue, &w);
+	}
+	optee_cq_wait_final(&optee->call_queue, &w);
+}
+
+/**
+ * __optee_disable_shm_cache() - Disables caching of some shared memory
+ *				 allocation in OP-TEE
+ * @optee:	main service struct
+ * @is_mapped:	true if the cached shared memory addresses were mapped by this
+ *		kernel, are safe to dereference, and should be freed
+ */
+static void __optee_disable_shm_cache(struct optee *optee, bool is_mapped)
+{
+	struct optee_call_waiter w;
+
+	/* We need to retry until secure world isn't busy. */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		union {
+			struct arm_smccc_res smccc;
+			struct optee_smc_disable_shm_cache_result result;
+		} res;
+
+		optee->smc.invoke_fn(OPTEE_SMC_DISABLE_SHM_CACHE,
+				     0, 0, 0, 0, 0, 0, 0, &res.smccc);
+		if (res.result.status == OPTEE_SMC_RETURN_ENOTAVAIL)
+			break; /* All shm's freed */
+		if (res.result.status == OPTEE_SMC_RETURN_OK) {
+			struct tee_shm *shm;
+
+			/*
+			 * Shared memory references that were not mapped by
+			 * this kernel must be ignored to prevent a crash.
+			 */
+			if (!is_mapped)
+				continue;
+
+			shm = reg_pair_to_ptr(res.result.shm_upper32,
+					      res.result.shm_lower32);
+			tee_shm_free(shm);
+		} else {
+			optee_cq_wait_for_completion(&optee->call_queue, &w);
+		}
+	}
+	optee_cq_wait_final(&optee->call_queue, &w);
+}
+
+/**
+ * optee_disable_shm_cache() - Disables caching of mapped shared memory
+ *			       allocations in OP-TEE
+ * @optee:	main service struct
+ */
+void optee_disable_shm_cache(struct optee *optee)
+{
+	return __optee_disable_shm_cache(optee, true);
+}
+
+/**
+ * optee_disable_unmapped_shm_cache() - Disables caching of shared memory
+ *					allocations in OP-TEE which are not
+ *					currently mapped
+ * @optee:	main service struct
+ */
+void optee_disable_unmapped_shm_cache(struct optee *optee)
+{
+	return __optee_disable_shm_cache(optee, false);
+}
+
+#define PAGELIST_ENTRIES_PER_PAGE				\
+	((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1)
+
+/*
+ * The final entry in each pagelist page is a pointer to the next
+ * pagelist page.
+ */
+static size_t get_pages_list_size(size_t num_entries)
+{
+	int pages = DIV_ROUND_UP(num_entries, PAGELIST_ENTRIES_PER_PAGE);
+
+	return pages * OPTEE_MSG_NONCONTIG_PAGE_SIZE;
+}
+
+static u64 *optee_allocate_pages_list(size_t num_entries)
+{
+	return alloc_pages_exact(get_pages_list_size(num_entries), GFP_KERNEL);
+}
+
+static void optee_free_pages_list(void *list, size_t num_entries)
+{
+	free_pages_exact(list, get_pages_list_size(num_entries));
+}
+
+/**
+ * optee_fill_pages_list() - write list of user pages to given shared
+ * buffer.
+ *
+ * @dst: page-aligned buffer where list of pages will be stored
+ * @pages: array of pages that represents shared buffer
+ * @num_pages: number of entries in @pages
+ * @page_offset: offset of user buffer from page start
+ *
+ * @dst should be big enough to hold list of user page addresses and
+ *	links to the next pages of buffer
+ */
+static void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
+				  size_t page_offset)
+{
+	int n = 0;
+	phys_addr_t optee_page;
+	/*
+	 * Refer to OPTEE_MSG_ATTR_NONCONTIG description in optee_msg.h
+	 * for details.
+	 */
+	struct {
+		u64 pages_list[PAGELIST_ENTRIES_PER_PAGE];
+		u64 next_page_data;
+	} *pages_data;
+
+	/*
+	 * Currently OP-TEE uses 4k page size and it does not looks
+	 * like this will change in the future.  On other hand, there are
+	 * no know ARM architectures with page size < 4k.
+	 * Thus the next built assert looks redundant. But the following
+	 * code heavily relies on this assumption, so it is better be
+	 * safe than sorry.
+	 */
+	BUILD_BUG_ON(PAGE_SIZE < OPTEE_MSG_NONCONTIG_PAGE_SIZE);
+
+	pages_data = (void *)dst;
+	/*
+	 * If linux page is bigger than 4k, and user buffer offset is
+	 * larger than 4k/8k/12k/etc this will skip first 4k pages,
+	 * because they bear no value data for OP-TEE.
+	 */
+	optee_page = page_to_phys(*pages) +
+		round_down(page_offset, OPTEE_MSG_NONCONTIG_PAGE_SIZE);
+
+	while (true) {
+		pages_data->pages_list[n++] = optee_page;
+
+		if (n == PAGELIST_ENTRIES_PER_PAGE) {
+			pages_data->next_page_data =
+				virt_to_phys(pages_data + 1);
+			pages_data++;
+			n = 0;
+		}
+
+		optee_page += OPTEE_MSG_NONCONTIG_PAGE_SIZE;
+		if (!(optee_page & ~PAGE_MASK)) {
+			if (!--num_pages)
+				break;
+			pages++;
+			optee_page = page_to_phys(*pages);
+		}
+	}
+}
+
+static int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
+			      struct page **pages, size_t num_pages,
+			      unsigned long start)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm_arg;
+	u64 *pages_list;
+	int rc;
+
+	if (!num_pages)
+		return -EINVAL;
+
+	rc = optee_check_mem_type(start, num_pages);
+	if (rc)
+		return rc;
+
+	pages_list = optee_allocate_pages_list(num_pages);
+	if (!pages_list)
+		return -ENOMEM;
+
+	shm_arg = optee_get_msg_arg(ctx, 1, &msg_arg);
+	if (IS_ERR(shm_arg)) {
+		rc = PTR_ERR(shm_arg);
+		goto out;
+	}
+
+	optee_fill_pages_list(pages_list, pages, num_pages,
+			      tee_shm_get_page_offset(shm));
+
+	msg_arg->cmd = OPTEE_MSG_CMD_REGISTER_SHM;
+	msg_arg->params->attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
+				OPTEE_MSG_ATTR_NONCONTIG;
+	msg_arg->params->u.tmem.shm_ref = (unsigned long)shm;
+	msg_arg->params->u.tmem.size = tee_shm_get_size(shm);
+	/*
+	 * In the least bits of msg_arg->params->u.tmem.buf_ptr we
+	 * store buffer offset from 4k page, as described in OP-TEE ABI.
+	 */
+	msg_arg->params->u.tmem.buf_ptr = virt_to_phys(pages_list) |
+	  (tee_shm_get_page_offset(shm) & (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
+
+	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
+	    msg_arg->ret != TEEC_SUCCESS)
+		rc = -EINVAL;
+
+	tee_shm_free(shm_arg);
+out:
+	optee_free_pages_list(pages_list, num_pages);
+	return rc;
+}
+
+static int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct optee_msg_arg *msg_arg;
+	struct tee_shm *shm_arg;
+	int rc = 0;
+
+	shm_arg = optee_get_msg_arg(ctx, 1, &msg_arg);
+	if (IS_ERR(shm_arg))
+		return PTR_ERR(shm_arg);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_UNREGISTER_SHM;
+
+	msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT;
+	msg_arg->params[0].u.rmem.shm_ref = (unsigned long)shm;
+
+	if (optee->ops->do_call_with_arg(ctx, shm_arg) ||
+	    msg_arg->ret != TEEC_SUCCESS)
+		rc = -EINVAL;
+	tee_shm_free(shm_arg);
+	return rc;
+}
+
+static int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
+				   struct page **pages, size_t num_pages,
+				   unsigned long start)
+{
+	/*
+	 * We don't want to register supplicant memory in OP-TEE.
+	 * Instead information about it will be passed in RPC code.
+	 */
+	return optee_check_mem_type(start, num_pages);
+}
+
+static int optee_shm_unregister_supp(struct tee_context *ctx,
+				     struct tee_shm *shm)
+{
+	return 0;
+}
+
+/*
+ * 3. Dynamic shared memory pool based on alloc_pages()
+ *
+ * Implements an OP-TEE specific shared memory pool which is used
+ * when dynamic shared memory is supported by secure world.
+ *
+ * The main function is optee_shm_pool_alloc_pages().
+ */
+
+static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
+			 struct tee_shm *shm, size_t size)
+{
+	/*
+	 * Shared memory private to the OP-TEE driver doesn't need
+	 * to be registered with OP-TEE.
+	 */
+	if (shm->flags & TEE_SHM_PRIV)
+		return optee_pool_op_alloc_helper(poolm, shm, size, NULL);
+
+	return optee_pool_op_alloc_helper(poolm, shm, size, optee_shm_register);
+}
+
+static void pool_op_free(struct tee_shm_pool_mgr *poolm,
+			 struct tee_shm *shm)
+{
+	if (!(shm->flags & TEE_SHM_PRIV))
+		optee_shm_unregister(shm->ctx, shm);
+
+	free_pages((unsigned long)shm->kaddr, get_order(shm->size));
+	shm->kaddr = NULL;
+}
+
+static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
+{
+	kfree(poolm);
+}
+
+static const struct tee_shm_pool_mgr_ops pool_ops = {
+	.alloc = pool_op_alloc,
+	.free = pool_op_free,
+	.destroy_poolmgr = pool_op_destroy_poolmgr,
+};
+
+/**
+ * optee_shm_pool_alloc_pages() - create page-based allocator pool
+ *
+ * This pool is used when OP-TEE supports dymanic SHM. In this case
+ * command buffers and such are allocated from kernel's own memory.
+ */
+static struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void)
+{
+	struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+
+	if (!mgr)
+		return ERR_PTR(-ENOMEM);
+
+	mgr->ops = &pool_ops;
+
+	return mgr;
+}
+
+/*
+ * 4. Do a normal scheduled call into secure world
+ *
+ * The function optee_smc_do_call_with_arg() performs a normal scheduled
+ * call into secure world. During this call may normal world request help
+ * from normal world using RPCs, Remote Procedure Calls. This includes
+ * delivery of non-secure interrupts to for instance allow rescheduling of
+ * the current task.
+ */
+
+static void handle_rpc_func_cmd_shm_free(struct tee_context *ctx,
+					 struct optee_msg_arg *arg)
+{
+	struct tee_shm *shm;
+
+	arg->ret_origin = TEEC_ORIGIN_COMMS;
+
+	if (arg->num_params != 1 ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	shm = (struct tee_shm *)(unsigned long)arg->params[0].u.value.b;
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_RPC_SHM_TYPE_APPL:
+		optee_rpc_cmd_free_suppl(ctx, shm);
+		break;
+	case OPTEE_RPC_SHM_TYPE_KERNEL:
+		tee_shm_free(shm);
+		break;
+	default:
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+	}
+	arg->ret = TEEC_SUCCESS;
+}
+
+static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
+					  struct optee_msg_arg *arg,
+					  struct optee_call_ctx *call_ctx)
+{
+	phys_addr_t pa;
+	struct tee_shm *shm;
+	size_t sz;
+	size_t n;
+
+	arg->ret_origin = TEEC_ORIGIN_COMMS;
+
+	if (!arg->num_params ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	for (n = 1; n < arg->num_params; n++) {
+		if (arg->params[n].attr != OPTEE_MSG_ATTR_TYPE_NONE) {
+			arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+			return;
+		}
+	}
+
+	sz = arg->params[0].u.value.b;
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_RPC_SHM_TYPE_APPL:
+		shm = optee_rpc_cmd_alloc_suppl(ctx, sz);
+		break;
+	case OPTEE_RPC_SHM_TYPE_KERNEL:
+		shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
+		break;
+	default:
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	if (IS_ERR(shm)) {
+		arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+		return;
+	}
+
+	if (tee_shm_get_pa(shm, 0, &pa)) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		goto bad;
+	}
+
+	sz = tee_shm_get_size(shm);
+
+	if (tee_shm_is_registered(shm)) {
+		struct page **pages;
+		u64 *pages_list;
+		size_t page_num;
+
+		pages = tee_shm_get_pages(shm, &page_num);
+		if (!pages || !page_num) {
+			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+			goto bad;
+		}
+
+		pages_list = optee_allocate_pages_list(page_num);
+		if (!pages_list) {
+			arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+			goto bad;
+		}
+
+		call_ctx->pages_list = pages_list;
+		call_ctx->num_entries = page_num;
+
+		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
+				      OPTEE_MSG_ATTR_NONCONTIG;
+		/*
+		 * In the least bits of u.tmem.buf_ptr we store buffer offset
+		 * from 4k page, as described in OP-TEE ABI.
+		 */
+		arg->params[0].u.tmem.buf_ptr = virt_to_phys(pages_list) |
+			(tee_shm_get_page_offset(shm) &
+			 (OPTEE_MSG_NONCONTIG_PAGE_SIZE - 1));
+		arg->params[0].u.tmem.size = tee_shm_get_size(shm);
+		arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
+
+		optee_fill_pages_list(pages_list, pages, page_num,
+				      tee_shm_get_page_offset(shm));
+	} else {
+		arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT;
+		arg->params[0].u.tmem.buf_ptr = pa;
+		arg->params[0].u.tmem.size = sz;
+		arg->params[0].u.tmem.shm_ref = (unsigned long)shm;
+	}
+
+	arg->ret = TEEC_SUCCESS;
+	return;
+bad:
+	tee_shm_free(shm);
+}
+
+static void free_pages_list(struct optee_call_ctx *call_ctx)
+{
+	if (call_ctx->pages_list) {
+		optee_free_pages_list(call_ctx->pages_list,
+				      call_ctx->num_entries);
+		call_ctx->pages_list = NULL;
+		call_ctx->num_entries = 0;
+	}
+}
+
+static void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx)
+{
+	free_pages_list(call_ctx);
+}
+
+static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
+				struct tee_shm *shm,
+				struct optee_call_ctx *call_ctx)
+{
+	struct optee_msg_arg *arg;
+
+	arg = tee_shm_get_va(shm, 0);
+	if (IS_ERR(arg)) {
+		pr_err("%s: tee_shm_get_va %p failed\n", __func__, shm);
+		return;
+	}
+
+	switch (arg->cmd) {
+	case OPTEE_RPC_CMD_SHM_ALLOC:
+		free_pages_list(call_ctx);
+		handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
+		break;
+	case OPTEE_RPC_CMD_SHM_FREE:
+		handle_rpc_func_cmd_shm_free(ctx, arg);
+		break;
+	default:
+		optee_rpc_cmd(ctx, optee, arg);
+	}
+}
+
+/**
+ * optee_handle_rpc() - handle RPC from secure world
+ * @ctx:	context doing the RPC
+ * @param:	value of registers for the RPC
+ * @call_ctx:	call context. Preserved during one OP-TEE invocation
+ *
+ * Result of RPC is written back into @param.
+ */
+static void optee_handle_rpc(struct tee_context *ctx,
+			     struct optee_rpc_param *param,
+			     struct optee_call_ctx *call_ctx)
+{
+	struct tee_device *teedev = ctx->teedev;
+	struct optee *optee = tee_get_drvdata(teedev);
+	struct tee_shm *shm;
+	phys_addr_t pa;
+
+	switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
+	case OPTEE_SMC_RPC_FUNC_ALLOC:
+		shm = tee_shm_alloc(ctx, param->a1, TEE_SHM_MAPPED);
+		if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
+			reg_pair_from_64(&param->a1, &param->a2, pa);
+			reg_pair_from_64(&param->a4, &param->a5,
+					 (unsigned long)shm);
+		} else {
+			param->a1 = 0;
+			param->a2 = 0;
+			param->a4 = 0;
+			param->a5 = 0;
+		}
+		break;
+	case OPTEE_SMC_RPC_FUNC_FREE:
+		shm = reg_pair_to_ptr(param->a1, param->a2);
+		tee_shm_free(shm);
+		break;
+	case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR:
+		/*
+		 * A foreign interrupt was raised while secure world was
+		 * executing, since they are handled in Linux a dummy RPC is
+		 * performed to let Linux take the interrupt through the normal
+		 * vector.
+		 */
+		break;
+	case OPTEE_SMC_RPC_FUNC_CMD:
+		shm = reg_pair_to_ptr(param->a1, param->a2);
+		handle_rpc_func_cmd(ctx, optee, shm, call_ctx);
+		break;
+	default:
+		pr_warn("Unknown RPC func 0x%x\n",
+			(u32)OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0));
+		break;
+	}
+
+	param->a0 = OPTEE_SMC_CALL_RETURN_FROM_RPC;
+}
+
+/**
+ * optee_smc_do_call_with_arg() - Do an SMC to OP-TEE in secure world
+ * @ctx:	calling context
+ * @arg:	shared memory holding the message to pass to secure world
+ *
+ * Does and SMC to OP-TEE in secure world and handles eventual resulting
+ * Remote Procedure Calls (RPC) from OP-TEE.
+ *
+ * Returns return code from secure world, 0 is OK
+ */
+static int optee_smc_do_call_with_arg(struct tee_context *ctx,
+				      struct tee_shm *arg)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct optee_call_waiter w;
+	struct optee_rpc_param param = { };
+	struct optee_call_ctx call_ctx = { };
+	phys_addr_t parg;
+	int rc;
+
+	rc = tee_shm_get_pa(arg, 0, &parg);
+	if (rc)
+		return rc;
+
+	param.a0 = OPTEE_SMC_CALL_WITH_ARG;
+	reg_pair_from_64(&param.a1, &param.a2, parg);
+	/* Initialize waiter */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		struct arm_smccc_res res;
+
+		trace_optee_invoke_fn_begin(&param);
+		optee->smc.invoke_fn(param.a0, param.a1, param.a2, param.a3,
+				     param.a4, param.a5, param.a6, param.a7,
+				     &res);
+		trace_optee_invoke_fn_end(&param, &res);
+
+		if (res.a0 == OPTEE_SMC_RETURN_ETHREAD_LIMIT) {
+			/*
+			 * Out of threads in secure world, wait for a thread
+			 * become available.
+			 */
+			optee_cq_wait_for_completion(&optee->call_queue, &w);
+		} else if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {
+			cond_resched();
+			param.a0 = res.a0;
+			param.a1 = res.a1;
+			param.a2 = res.a2;
+			param.a3 = res.a3;
+			optee_handle_rpc(ctx, &param, &call_ctx);
+		} else {
+			rc = res.a0;
+			break;
+		}
+	}
+
+	optee_rpc_finalize_call(&call_ctx);
+	/*
+	 * We're done with our thread in secure world, if there's any
+	 * thread waiters wake up one.
+	 */
+	optee_cq_wait_final(&optee->call_queue, &w);
+
+	return rc;
+}
+
+/*
+ * 5. Driver initialization
+ *
+ * During driver inititialization is secure world probed to find out which
+ * features it supports so the driver can be initialized with a matching
+ * configuration. This involves for instance support for dynamic shared
+ * memory instead of a static memory carvout.
+ */
+
+static void optee_get_version(struct tee_device *teedev,
+			      struct tee_ioctl_version_data *vers)
+{
+	struct tee_ioctl_version_data v = {
+		.impl_id = TEE_IMPL_ID_OPTEE,
+		.impl_caps = TEE_OPTEE_CAP_TZ,
+		.gen_caps = TEE_GEN_CAP_GP,
+	};
+	struct optee *optee = tee_get_drvdata(teedev);
+
+	if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
+		v.gen_caps |= TEE_GEN_CAP_REG_MEM;
+	if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
+		v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
+	*vers = v;
+}
+
+static int optee_smc_open(struct tee_context *ctx)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	u32 sec_caps = optee->smc.sec_caps;
+
+	return optee_open(ctx, sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL);
+}
+
+static const struct tee_driver_ops optee_clnt_ops = {
+	.get_version = optee_get_version,
+	.open = optee_smc_open,
+	.release = optee_release,
+	.open_session = optee_open_session,
+	.close_session = optee_close_session,
+	.invoke_func = optee_invoke_func,
+	.cancel_req = optee_cancel_req,
+	.shm_register = optee_shm_register,
+	.shm_unregister = optee_shm_unregister,
+};
+
+static const struct tee_desc optee_clnt_desc = {
+	.name = DRIVER_NAME "-clnt",
+	.ops = &optee_clnt_ops,
+	.owner = THIS_MODULE,
+};
+
+static const struct tee_driver_ops optee_supp_ops = {
+	.get_version = optee_get_version,
+	.open = optee_smc_open,
+	.release = optee_release_supp,
+	.supp_recv = optee_supp_recv,
+	.supp_send = optee_supp_send,
+	.shm_register = optee_shm_register_supp,
+	.shm_unregister = optee_shm_unregister_supp,
+};
+
+static const struct tee_desc optee_supp_desc = {
+	.name = DRIVER_NAME "-supp",
+	.ops = &optee_supp_ops,
+	.owner = THIS_MODULE,
+	.flags = TEE_DESC_PRIVILEGED,
+};
+
+static const struct optee_ops optee_ops = {
+	.do_call_with_arg = optee_smc_do_call_with_arg,
+	.to_msg_param = optee_to_msg_param,
+	.from_msg_param = optee_from_msg_param,
+};
+
+static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
+{
+	struct arm_smccc_res res;
+
+	invoke_fn(OPTEE_SMC_CALLS_UID, 0, 0, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 == OPTEE_MSG_UID_0 && res.a1 == OPTEE_MSG_UID_1 &&
+	    res.a2 == OPTEE_MSG_UID_2 && res.a3 == OPTEE_MSG_UID_3)
+		return true;
+	return false;
+}
+
+static void optee_msg_get_os_revision(optee_invoke_fn *invoke_fn)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_call_get_os_revision_result result;
+	} res = {
+		.result = {
+			.build_id = 0
+		}
+	};
+
+	invoke_fn(OPTEE_SMC_CALL_GET_OS_REVISION, 0, 0, 0, 0, 0, 0, 0,
+		  &res.smccc);
+
+	if (res.result.build_id)
+		pr_info("revision %lu.%lu (%08lx)", res.result.major,
+			res.result.minor, res.result.build_id);
+	else
+		pr_info("revision %lu.%lu", res.result.major, res.result.minor);
+}
+
+static bool optee_msg_api_revision_is_compatible(optee_invoke_fn *invoke_fn)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_calls_revision_result result;
+	} res;
+
+	invoke_fn(OPTEE_SMC_CALLS_REVISION, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
+
+	if (res.result.major == OPTEE_MSG_REVISION_MAJOR &&
+	    (int)res.result.minor >= OPTEE_MSG_REVISION_MINOR)
+		return true;
+	return false;
+}
+
+static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
+					    u32 *sec_caps)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_exchange_capabilities_result result;
+	} res;
+	u32 a1 = 0;
+
+	/*
+	 * TODO This isn't enough to tell if it's UP system (from kernel
+	 * point of view) or not, is_smp() returns the information
+	 * needed, but can't be called directly from here.
+	 */
+	if (!IS_ENABLED(CONFIG_SMP) || nr_cpu_ids == 1)
+		a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR;
+
+	invoke_fn(OPTEE_SMC_EXCHANGE_CAPABILITIES, a1, 0, 0, 0, 0, 0, 0,
+		  &res.smccc);
+
+	if (res.result.status != OPTEE_SMC_RETURN_OK)
+		return false;
+
+	*sec_caps = res.result.capabilities;
+	return true;
+}
+
+static struct tee_shm_pool *optee_config_dyn_shm(void)
+{
+	struct tee_shm_pool_mgr *priv_mgr;
+	struct tee_shm_pool_mgr *dmabuf_mgr;
+	void *rc;
+
+	rc = optee_shm_pool_alloc_pages();
+	if (IS_ERR(rc))
+		return rc;
+	priv_mgr = rc;
+
+	rc = optee_shm_pool_alloc_pages();
+	if (IS_ERR(rc)) {
+		tee_shm_pool_mgr_destroy(priv_mgr);
+		return rc;
+	}
+	dmabuf_mgr = rc;
+
+	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
+	if (IS_ERR(rc)) {
+		tee_shm_pool_mgr_destroy(priv_mgr);
+		tee_shm_pool_mgr_destroy(dmabuf_mgr);
+	}
+
+	return rc;
+}
+
+static struct tee_shm_pool *
+optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
+{
+	union {
+		struct arm_smccc_res smccc;
+		struct optee_smc_get_shm_config_result result;
+	} res;
+	unsigned long vaddr;
+	phys_addr_t paddr;
+	size_t size;
+	phys_addr_t begin;
+	phys_addr_t end;
+	void *va;
+	struct tee_shm_pool_mgr *priv_mgr;
+	struct tee_shm_pool_mgr *dmabuf_mgr;
+	void *rc;
+	const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
+
+	invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
+	if (res.result.status != OPTEE_SMC_RETURN_OK) {
+		pr_err("static shm service not available\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	if (res.result.settings != OPTEE_SMC_SHM_CACHED) {
+		pr_err("only normal cached shared memory supported\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	begin = roundup(res.result.start, PAGE_SIZE);
+	end = rounddown(res.result.start + res.result.size, PAGE_SIZE);
+	paddr = begin;
+	size = end - begin;
+
+	if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
+		pr_err("too small shared memory area\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	va = memremap(paddr, size, MEMREMAP_WB);
+	if (!va) {
+		pr_err("shared memory ioremap failed\n");
+		return ERR_PTR(-EINVAL);
+	}
+	vaddr = (unsigned long)va;
+
+	rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
+					    3 /* 8 bytes aligned */);
+	if (IS_ERR(rc))
+		goto err_memunmap;
+	priv_mgr = rc;
+
+	vaddr += sz;
+	paddr += sz;
+	size -= sz;
+
+	rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT);
+	if (IS_ERR(rc))
+		goto err_free_priv_mgr;
+	dmabuf_mgr = rc;
+
+	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
+	if (IS_ERR(rc))
+		goto err_free_dmabuf_mgr;
+
+	*memremaped_shm = va;
+
+	return rc;
+
+err_free_dmabuf_mgr:
+	tee_shm_pool_mgr_destroy(dmabuf_mgr);
+err_free_priv_mgr:
+	tee_shm_pool_mgr_destroy(priv_mgr);
+err_memunmap:
+	memunmap(va);
+	return rc;
+}
+
+/* Simple wrapper functions to be able to use a function pointer */
+static void optee_smccc_smc(unsigned long a0, unsigned long a1,
+			    unsigned long a2, unsigned long a3,
+			    unsigned long a4, unsigned long a5,
+			    unsigned long a6, unsigned long a7,
+			    struct arm_smccc_res *res)
+{
+	arm_smccc_smc(a0, a1, a2, a3, a4, a5, a6, a7, res);
+}
+
+static void optee_smccc_hvc(unsigned long a0, unsigned long a1,
+			    unsigned long a2, unsigned long a3,
+			    unsigned long a4, unsigned long a5,
+			    unsigned long a6, unsigned long a7,
+			    struct arm_smccc_res *res)
+{
+	arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
+}
+
+static optee_invoke_fn *get_invoke_func(struct device *dev)
+{
+	const char *method;
+
+	pr_info("probing for conduit method.\n");
+
+	if (device_property_read_string(dev, "method", &method)) {
+		pr_warn("missing \"method\" property\n");
+		return ERR_PTR(-ENXIO);
+	}
+
+	if (!strcmp("hvc", method))
+		return optee_smccc_hvc;
+	else if (!strcmp("smc", method))
+		return optee_smccc_smc;
+
+	pr_warn("invalid \"method\" property: %s\n", method);
+	return ERR_PTR(-EINVAL);
+}
+
+/* optee_remove - Device Removal Routine
+ * @pdev: platform device information struct
+ *
+ * optee_remove is called by platform subsystem to alert the driver
+ * that it should release the device
+ */
+static int optee_smc_remove(struct platform_device *pdev)
+{
+	struct optee *optee = platform_get_drvdata(pdev);
+
+	/*
+	 * Ask OP-TEE to free all cached shared memory objects to decrease
+	 * reference counters and also avoid wild pointers in secure world
+	 * into the old shared memory range.
+	 */
+	optee_disable_shm_cache(optee);
+
+	optee_remove_common(optee);
+
+	if (optee->smc.memremaped_shm)
+		memunmap(optee->smc.memremaped_shm);
+
+	kfree(optee);
+
+	return 0;
+}
+
+/* optee_shutdown - Device Removal Routine
+ * @pdev: platform device information struct
+ *
+ * platform_shutdown is called by the platform subsystem to alert
+ * the driver that a shutdown, reboot, or kexec is happening and
+ * device must be disabled.
+ */
+static void optee_shutdown(struct platform_device *pdev)
+{
+	optee_disable_shm_cache(platform_get_drvdata(pdev));
+}
+
+static int optee_probe(struct platform_device *pdev)
+{
+	optee_invoke_fn *invoke_fn;
+	struct tee_shm_pool *pool = ERR_PTR(-EINVAL);
+	struct optee *optee = NULL;
+	void *memremaped_shm = NULL;
+	struct tee_device *teedev;
+	u32 sec_caps;
+	int rc;
+
+	invoke_fn = get_invoke_func(&pdev->dev);
+	if (IS_ERR(invoke_fn))
+		return PTR_ERR(invoke_fn);
+
+	if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
+		pr_warn("api uid mismatch\n");
+		return -EINVAL;
+	}
+
+	optee_msg_get_os_revision(invoke_fn);
+
+	if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
+		pr_warn("api revision mismatch\n");
+		return -EINVAL;
+	}
+
+	if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
+		pr_warn("capabilities mismatch\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Try to use dynamic shared memory if possible
+	 */
+	if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
+		pool = optee_config_dyn_shm();
+
+	/*
+	 * If dynamic shared memory is not available or failed - try static one
+	 */
+	if (IS_ERR(pool) && (sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
+		pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
+
+	if (IS_ERR(pool))
+		return PTR_ERR(pool);
+
+	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
+	if (!optee) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	optee->ops = &optee_ops;
+	optee->smc.invoke_fn = invoke_fn;
+	optee->smc.sec_caps = sec_caps;
+
+	teedev = tee_device_alloc(&optee_clnt_desc, NULL, pool, optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->teedev = teedev;
+
+	teedev = tee_device_alloc(&optee_supp_desc, NULL, pool, optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->supp_teedev = teedev;
+
+	rc = tee_device_register(optee->teedev);
+	if (rc)
+		goto err;
+
+	rc = tee_device_register(optee->supp_teedev);
+	if (rc)
+		goto err;
+
+	mutex_init(&optee->call_queue.mutex);
+	INIT_LIST_HEAD(&optee->call_queue.waiters);
+	optee_wait_queue_init(&optee->wait_queue);
+	optee_supp_init(&optee->supp);
+	optee->smc.memremaped_shm = memremaped_shm;
+	optee->pool = pool;
+
+	/*
+	 * Ensure that there are no pre-existing shm objects before enabling
+	 * the shm cache so that there's no chance of receiving an invalid
+	 * address during shutdown. This could occur, for example, if we're
+	 * kexec booting from an older kernel that did not properly cleanup the
+	 * shm cache.
+	 */
+	optee_disable_unmapped_shm_cache(optee);
+
+	optee_enable_shm_cache(optee);
+
+	if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
+		pr_info("dynamic shared memory is enabled\n");
+
+	platform_set_drvdata(pdev, optee);
+
+	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
+	if (rc) {
+		optee_smc_remove(pdev);
+		return rc;
+	}
+
+	pr_info("initialized driver\n");
+	return 0;
+err:
+	if (optee) {
+		/*
+		 * tee_device_unregister() is safe to call even if the
+		 * devices hasn't been registered with
+		 * tee_device_register() yet.
+		 */
+		tee_device_unregister(optee->supp_teedev);
+		tee_device_unregister(optee->teedev);
+		kfree(optee);
+	}
+	if (pool)
+		tee_shm_pool_free(pool);
+	if (memremaped_shm)
+		memunmap(memremaped_shm);
+	return rc;
+}
+
+static const struct of_device_id optee_dt_match[] = {
+	{ .compatible = "linaro,optee-tz" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, optee_dt_match);
+
+static struct platform_driver optee_driver = {
+	.probe  = optee_probe,
+	.remove = optee_smc_remove,
+	.shutdown = optee_shutdown,
+	.driver = {
+		.name = "optee",
+		.of_match_table = optee_dt_match,
+	},
+};
+
+int optee_smc_abi_register(void)
+{
+	return platform_driver_register(&optee_driver);
+}
+
+void optee_smc_abi_unregister(void)
+{
+	platform_driver_unregister(&optee_driver);
+}
-- 
2.31.1



From jens.wiklander at linaro.org  Tue Aug 31 00:24:12 2021
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Tue, 31 Aug 2021 09:24:12 +0200
Subject: [PATCH v5 5/5] optee: add FF-A support
In-Reply-To: <20210831072412.887565-1-jens.wiklander@linaro.org>
References: <20210831072412.887565-1-jens.wiklander@linaro.org>
Message-ID: <20210831072412.887565-6-jens.wiklander@linaro.org>

Adds support for using FF-A [1] as transport to the OP-TEE driver.

Introduces struct optee_msg_param_fmem which carries all information
needed when OP-TEE is calling FFA_MEM_RETRIEVE_REQ to get the shared
memory reference mapped by the hypervisor in S-EL2. Register usage is
also updated to include the information needed.

The FF-A part of this driver is enabled if CONFIG_ARM_FFA_TRANSPORT is
enabled.

[1] https://developer.arm.com/documentation/den0077/latest
Acked-by: Sumit Garg <sumit.garg at linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 drivers/tee/optee/Makefile        |   3 +-
 drivers/tee/optee/call.c          |  13 +-
 drivers/tee/optee/core.c          |  16 +-
 drivers/tee/optee/ffa_abi.c       | 907 ++++++++++++++++++++++++++++++
 drivers/tee/optee/optee_ffa.h     | 153 +++++
 drivers/tee/optee/optee_msg.h     |  27 +-
 drivers/tee/optee/optee_private.h |  43 +-
 7 files changed, 1148 insertions(+), 14 deletions(-)
 create mode 100644 drivers/tee/optee/ffa_abi.c
 create mode 100644 drivers/tee/optee/optee_ffa.h

diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
index d4e4776d2dec..dbfd83d3c4ae 100644
--- a/drivers/tee/optee/Makefile
+++ b/drivers/tee/optee/Makefile
@@ -7,7 +7,8 @@ optee-objs += supp.o
 optee-objs += device.o
 
 optee-smc-abi-y = smc_abi.o
-optee-objs += $(optee-smc-abi-y)
+optee-ffa-abi-$(CONFIG_ARM_FFA_TRANSPORT) = ffa_abi.o
+optee-objs += $(optee-smc-abi-y) $(optee-ffa-abi-y)
 
 # for tracing framework to find optee_trace.h
 CFLAGS_smc_abi.o := -I$(src)
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
index 9ff4f0812825..b25cc1fac945 100644
--- a/drivers/tee/optee/call.c
+++ b/drivers/tee/optee/call.c
@@ -107,11 +107,20 @@ static struct optee_session *find_session(struct optee_context_data *ctxdata,
 struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params,
 				  struct optee_msg_arg **msg_arg)
 {
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	size_t sz = OPTEE_MSG_GET_ARG_SIZE(num_params);
 	struct tee_shm *shm;
 	struct optee_msg_arg *ma;
 
-	shm = tee_shm_alloc(ctx, OPTEE_MSG_GET_ARG_SIZE(num_params),
-			    TEE_SHM_MAPPED | TEE_SHM_PRIV);
+	/*
+	 * rpc_arg_count is set to the number of allocated parameters in
+	 * the RPC argument struct if a second MSG arg struct is expected.
+	 * The second arg struct will then be used for RPC.
+	 */
+	if (optee->rpc_arg_count)
+		sz += OPTEE_MSG_GET_ARG_SIZE(optee->rpc_arg_count);
+
+	shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
 	if (IS_ERR(shm))
 		return shm;
 
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 9e3b6cdbe371..44bd67b7b0eb 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -169,6 +169,9 @@ void optee_remove_common(struct optee *optee)
 	mutex_destroy(&optee->call_queue.mutex);
 }
 
+static int smc_abi_rc;
+static int ffa_abi_rc;
+
 static int optee_core_init(void)
 {
 	/*
@@ -181,13 +184,22 @@ static int optee_core_init(void)
 	if (is_kdump_kernel())
 		return -ENODEV;
 
-	return optee_smc_abi_register();
+	smc_abi_rc = optee_smc_abi_register();
+	ffa_abi_rc = optee_ffa_abi_register();
+
+	/* If both failed there's no point with this module */
+	if (smc_abi_rc && ffa_abi_rc)
+		return smc_abi_rc;
+	return 0;
 }
 module_init(optee_core_init);
 
 static void optee_core_exit(void)
 {
-	optee_smc_abi_unregister();
+	if (!smc_abi_rc)
+		optee_smc_abi_unregister();
+	if (!ffa_abi_rc)
+		optee_ffa_abi_unregister();
 }
 module_exit(optee_core_exit);
 
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
new file mode 100644
index 000000000000..ef7ee7f04e8c
--- /dev/null
+++ b/drivers/tee/optee/ffa_abi.c
@@ -0,0 +1,907 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, Linaro Limited
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/arm_ffa.h>
+#include <linux/errno.h>
+#include <linux/scatterlist.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include "optee_private.h"
+#include "optee_ffa.h"
+#include "optee_rpc_cmd.h"
+
+/*
+ * This file implement the FF-A ABI used when communicating with secure world
+ * OP-TEE OS via FF-A.
+ * This file is divided into the following sections:
+ * 1. Maintain a hash table for lookup of a global FF-A memory handle
+ * 2. Convert between struct tee_param and struct optee_msg_param
+ * 3. Low level support functions to register shared memory in secure world
+ * 4. Dynamic shared memory pool based on alloc_pages()
+ * 5. Do a normal scheduled call into secure world
+ * 6. Driver initialization.
+ */
+
+/*
+ * 1. Maintain a hash table for lookup of a global FF-A memory handle
+ *
+ * FF-A assigns a global memory handle for each piece shared memory.
+ * This handle is then used when communicating with secure world.
+ *
+ * Main functions are optee_shm_add_ffa_handle() and optee_shm_rem_ffa_handle()
+ */
+struct shm_rhash {
+	struct tee_shm *shm;
+	u64 global_id;
+	struct rhash_head linkage;
+};
+
+static void rh_free_fn(void *ptr, void *arg)
+{
+	kfree(ptr);
+}
+
+static const struct rhashtable_params shm_rhash_params = {
+	.head_offset = offsetof(struct shm_rhash, linkage),
+	.key_len     = sizeof(u64),
+	.key_offset  = offsetof(struct shm_rhash, global_id),
+	.automatic_shrinking = true,
+};
+
+static struct tee_shm *optee_shm_from_ffa_handle(struct optee *optee,
+						 u64 global_id)
+{
+	struct tee_shm *shm = NULL;
+	struct shm_rhash *r;
+
+	mutex_lock(&optee->ffa.mutex);
+	r = rhashtable_lookup_fast(&optee->ffa.global_ids, &global_id,
+				   shm_rhash_params);
+	if (r)
+		shm = r->shm;
+	mutex_unlock(&optee->ffa.mutex);
+
+	return shm;
+}
+
+static int optee_shm_add_ffa_handle(struct optee *optee, struct tee_shm *shm,
+				    u64 global_id)
+{
+	struct shm_rhash *r;
+	int rc;
+
+	r = kmalloc(sizeof(*r), GFP_KERNEL);
+	if (!r)
+		return -ENOMEM;
+	r->shm = shm;
+	r->global_id = global_id;
+
+	mutex_lock(&optee->ffa.mutex);
+	rc = rhashtable_lookup_insert_fast(&optee->ffa.global_ids, &r->linkage,
+					   shm_rhash_params);
+	mutex_unlock(&optee->ffa.mutex);
+
+	if (rc)
+		kfree(r);
+
+	return rc;
+}
+
+static int optee_shm_rem_ffa_handle(struct optee *optee, u64 global_id)
+{
+	struct shm_rhash *r;
+	int rc = -ENOENT;
+
+	mutex_lock(&optee->ffa.mutex);
+	r = rhashtable_lookup_fast(&optee->ffa.global_ids, &global_id,
+				   shm_rhash_params);
+	if (r)
+		rc = rhashtable_remove_fast(&optee->ffa.global_ids,
+					    &r->linkage, shm_rhash_params);
+	mutex_unlock(&optee->ffa.mutex);
+
+	if (!rc)
+		kfree(r);
+
+	return rc;
+}
+
+/*
+ * 2. Convert between struct tee_param and struct optee_msg_param
+ *
+ * optee_ffa_from_msg_param() and optee_ffa_to_msg_param() are the main
+ * functions.
+ */
+
+static void from_msg_param_ffa_mem(struct optee *optee, struct tee_param *p,
+				   u32 attr, const struct optee_msg_param *mp)
+{
+	struct tee_shm *shm = NULL;
+	u64 offs_high = 0;
+	u64 offs_low = 0;
+
+	p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT +
+		  attr - OPTEE_MSG_ATTR_TYPE_FMEM_INPUT;
+	p->u.memref.size = mp->u.fmem.size;
+
+	if (mp->u.fmem.global_id != OPTEE_MSG_FMEM_INVALID_GLOBAL_ID)
+		shm = optee_shm_from_ffa_handle(optee, mp->u.fmem.global_id);
+	p->u.memref.shm = shm;
+
+	if (shm) {
+		offs_low = mp->u.fmem.offs_low;
+		offs_high = mp->u.fmem.offs_high;
+	}
+	p->u.memref.shm_offs = offs_low | offs_high << 32;
+}
+
+/**
+ * optee_ffa_from_msg_param() - convert from OPTEE_MSG parameters to
+ *				struct tee_param
+ * @optee:	main service struct
+ * @params:	subsystem internal parameter representation
+ * @num_params:	number of elements in the parameter arrays
+ * @msg_params:	OPTEE_MSG parameters
+ *
+ * Returns 0 on success or <0 on failure
+ */
+static int optee_ffa_from_msg_param(struct optee *optee,
+				    struct tee_param *params, size_t num_params,
+				    const struct optee_msg_param *msg_params)
+{
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_param *p = params + n;
+		const struct optee_msg_param *mp = msg_params + n;
+		u32 attr = mp->attr & OPTEE_MSG_ATTR_TYPE_MASK;
+
+		switch (attr) {
+		case OPTEE_MSG_ATTR_TYPE_NONE:
+			p->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
+			memset(&p->u, 0, sizeof(p->u));
+			break;
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
+			optee_from_msg_param_value(p, attr, mp);
+			break;
+		case OPTEE_MSG_ATTR_TYPE_FMEM_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_FMEM_INOUT:
+			from_msg_param_ffa_mem(optee, p, attr, mp);
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
+				const struct tee_param *p)
+{
+	struct tee_shm *shm = p->u.memref.shm;
+
+	mp->attr = OPTEE_MSG_ATTR_TYPE_FMEM_INPUT + p->attr -
+		   TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
+
+	if (shm) {
+		u64 shm_offs = p->u.memref.shm_offs;
+
+		mp->u.fmem.internal_offs = shm->offset;
+
+		mp->u.fmem.offs_low = shm_offs;
+		mp->u.fmem.offs_high = shm_offs >> 32;
+		/* Check that the entire offset could be stored. */
+		if (mp->u.fmem.offs_high != shm_offs >> 32)
+			return -EINVAL;
+
+		mp->u.fmem.global_id = shm->sec_world_id;
+	} else {
+		memset(&mp->u, 0, sizeof(mp->u));
+		mp->u.fmem.global_id = OPTEE_MSG_FMEM_INVALID_GLOBAL_ID;
+	}
+	mp->u.fmem.size = p->u.memref.size;
+
+	return 0;
+}
+
+/**
+ * optee_ffa_to_msg_param() - convert from struct tee_params to OPTEE_MSG
+ *			      parameters
+ * @optee:	main service struct
+ * @msg_params:	OPTEE_MSG parameters
+ * @num_params:	number of elements in the parameter arrays
+ * @params:	subsystem itnernal parameter representation
+ * Returns 0 on success or <0 on failure
+ */
+static int optee_ffa_to_msg_param(struct optee *optee,
+				  struct optee_msg_param *msg_params,
+				  size_t num_params,
+				  const struct tee_param *params)
+{
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		const struct tee_param *p = params + n;
+		struct optee_msg_param *mp = msg_params + n;
+
+		switch (p->attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
+			mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
+			memset(&mp->u, 0, sizeof(mp->u));
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			optee_to_msg_param_value(mp, p);
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			if (to_msg_param_ffa_mem(mp, p))
+				return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * 3. Low level support functions to register shared memory in secure world
+ *
+ * Functions to register and unregister shared memory both for normal
+ * clients and for tee-supplicant.
+ */
+
+static int optee_ffa_shm_register(struct tee_context *ctx, struct tee_shm *shm,
+				  struct page **pages, size_t num_pages,
+				  unsigned long start)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
+	struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
+	struct ffa_mem_region_attributes mem_attr = {
+		.receiver = ffa_dev->vm_id,
+		.attrs = FFA_MEM_RW,
+	};
+	struct ffa_mem_ops_args args = {
+		.use_txbuf = true,
+		.attrs = &mem_attr,
+		.nattrs = 1,
+	};
+	struct sg_table sgt;
+	int rc;
+
+	rc = optee_check_mem_type(start, num_pages);
+	if (rc)
+		return rc;
+
+	rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
+				       num_pages * PAGE_SIZE, GFP_KERNEL);
+	if (rc)
+		return rc;
+	args.sg = sgt.sgl;
+	rc = ffa_ops->memory_share(ffa_dev, &args);
+	sg_free_table(&sgt);
+	if (rc)
+		return rc;
+
+	rc = optee_shm_add_ffa_handle(optee, shm, args.g_handle);
+	if (rc) {
+		ffa_ops->memory_reclaim(args.g_handle, 0);
+		return rc;
+	}
+
+	shm->sec_world_id = args.g_handle;
+
+	return 0;
+}
+
+static int optee_ffa_shm_unregister(struct tee_context *ctx,
+				    struct tee_shm *shm)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
+	struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
+	u64 global_handle = shm->sec_world_id;
+	struct ffa_send_direct_data data = {
+		.data0 = OPTEE_FFA_UNREGISTER_SHM,
+		.data1 = (u32)global_handle,
+		.data2 = (u32)(global_handle >> 32)
+	};
+	int rc;
+
+	optee_shm_rem_ffa_handle(optee, global_handle);
+	shm->sec_world_id = 0;
+
+	rc = ffa_ops->sync_send_receive(ffa_dev, &data);
+	if (rc)
+		pr_err("Unregister SHM id 0x%llx rc %d\n", global_handle, rc);
+
+	rc = ffa_ops->memory_reclaim(global_handle, 0);
+	if (rc)
+		pr_err("mem_reclain: 0x%llx %d", global_handle, rc);
+
+	return rc;
+}
+
+static int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
+					 struct tee_shm *shm)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
+	u64 global_handle = shm->sec_world_id;
+	int rc;
+
+	/*
+	 * We're skipping the OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM call
+	 * since this is OP-TEE freeing via RPC so it has already retired
+	 * this ID.
+	 */
+
+	optee_shm_rem_ffa_handle(optee, global_handle);
+	rc = ffa_ops->memory_reclaim(global_handle, 0);
+	if (rc)
+		pr_err("mem_reclain: 0x%llx %d", global_handle, rc);
+
+	shm->sec_world_id = 0;
+
+	return rc;
+}
+
+/*
+ * 4. Dynamic shared memory pool based on alloc_pages()
+ *
+ * Implements an OP-TEE specific shared memory pool.
+ * The main function is optee_ffa_shm_pool_alloc_pages().
+ */
+
+static int pool_ffa_op_alloc(struct tee_shm_pool_mgr *poolm,
+			     struct tee_shm *shm, size_t size)
+{
+	return optee_pool_op_alloc_helper(poolm, shm, size,
+					  optee_ffa_shm_register);
+}
+
+static void pool_ffa_op_free(struct tee_shm_pool_mgr *poolm,
+			     struct tee_shm *shm)
+{
+	optee_ffa_shm_unregister(shm->ctx, shm);
+	free_pages((unsigned long)shm->kaddr, get_order(shm->size));
+	shm->kaddr = NULL;
+}
+
+static void pool_ffa_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
+{
+	kfree(poolm);
+}
+
+static const struct tee_shm_pool_mgr_ops pool_ffa_ops = {
+	.alloc = pool_ffa_op_alloc,
+	.free = pool_ffa_op_free,
+	.destroy_poolmgr = pool_ffa_op_destroy_poolmgr,
+};
+
+/**
+ * optee_ffa_shm_pool_alloc_pages() - create page-based allocator pool
+ *
+ * This pool is used with OP-TEE over FF-A. In this case command buffers
+ * and such are allocated from kernel's own memory.
+ */
+static struct tee_shm_pool_mgr *optee_ffa_shm_pool_alloc_pages(void)
+{
+	struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+
+	if (!mgr)
+		return ERR_PTR(-ENOMEM);
+
+	mgr->ops = &pool_ffa_ops;
+
+	return mgr;
+}
+
+/*
+ * 5. Do a normal scheduled call into secure world
+ *
+ * The function optee_ffa_do_call_with_arg() performs a normal scheduled
+ * call into secure world. During this call may normal world request help
+ * from normal world using RPCs, Remote Procedure Calls. This includes
+ * delivery of non-secure interrupts to for instance allow rescheduling of
+ * the current task.
+ */
+
+static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
+					      struct optee_msg_arg *arg)
+{
+	struct tee_shm *shm;
+
+	if (arg->num_params != 1 ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_RPC_SHM_TYPE_APPL:
+		shm = optee_rpc_cmd_alloc_suppl(ctx, arg->params[0].u.value.b);
+		break;
+	case OPTEE_RPC_SHM_TYPE_KERNEL:
+		shm = tee_shm_alloc(ctx, arg->params[0].u.value.b,
+				    TEE_SHM_MAPPED | TEE_SHM_PRIV);
+		break;
+	default:
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		return;
+	}
+
+	if (IS_ERR(shm)) {
+		arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+		return;
+	}
+
+	arg->params[0] = (struct optee_msg_param){
+		.attr = OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT,
+		.u.fmem.size = tee_shm_get_size(shm),
+		.u.fmem.global_id = shm->sec_world_id,
+		.u.fmem.internal_offs = shm->offset,
+	};
+
+	arg->ret = TEEC_SUCCESS;
+}
+
+static void handle_ffa_rpc_func_cmd_shm_free(struct tee_context *ctx,
+					     struct optee *optee,
+					     struct optee_msg_arg *arg)
+{
+	struct tee_shm *shm;
+
+	if (arg->num_params != 1 ||
+	    arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
+		goto err_bad_param;
+
+	shm = optee_shm_from_ffa_handle(optee, arg->params[0].u.value.b);
+	if (!shm)
+		goto err_bad_param;
+	switch (arg->params[0].u.value.a) {
+	case OPTEE_RPC_SHM_TYPE_APPL:
+		optee_rpc_cmd_free_suppl(ctx, shm);
+		break;
+	case OPTEE_RPC_SHM_TYPE_KERNEL:
+		tee_shm_free(shm);
+		break;
+	default:
+		goto err_bad_param;
+	}
+	arg->ret = TEEC_SUCCESS;
+	return;
+
+err_bad_param:
+	arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+}
+
+static void handle_ffa_rpc_func_cmd(struct tee_context *ctx,
+				    struct optee_msg_arg *arg)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+
+	arg->ret_origin = TEEC_ORIGIN_COMMS;
+	switch (arg->cmd) {
+	case OPTEE_RPC_CMD_SHM_ALLOC:
+		handle_ffa_rpc_func_cmd_shm_alloc(ctx, arg);
+		break;
+	case OPTEE_RPC_CMD_SHM_FREE:
+		handle_ffa_rpc_func_cmd_shm_free(ctx, optee, arg);
+		break;
+	default:
+		optee_rpc_cmd(ctx, optee, arg);
+	}
+}
+
+static void optee_handle_ffa_rpc(struct tee_context *ctx, u32 cmd,
+				 struct optee_msg_arg *arg)
+{
+	switch (cmd) {
+	case OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD:
+		handle_ffa_rpc_func_cmd(ctx, arg);
+		break;
+	case OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT:
+		/* Interrupt delivered by now */
+		break;
+	default:
+		pr_warn("Unknown RPC func 0x%x\n", cmd);
+		break;
+	}
+}
+
+static int optee_ffa_yielding_call(struct tee_context *ctx,
+				   struct ffa_send_direct_data *data,
+				   struct optee_msg_arg *rpc_arg)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
+	struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
+	struct optee_call_waiter w;
+	u32 cmd = data->data0;
+	u32 w4 = data->data1;
+	u32 w5 = data->data2;
+	u32 w6 = data->data3;
+	int rc;
+
+	/* Initialize waiter */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		rc = ffa_ops->sync_send_receive(ffa_dev, data);
+		if (rc)
+			goto done;
+
+		switch ((int)data->data0) {
+		case TEEC_SUCCESS:
+			break;
+		case TEEC_ERROR_BUSY:
+			if (cmd == OPTEE_FFA_YIELDING_CALL_RESUME) {
+				rc = -EIO;
+				goto done;
+			}
+
+			/*
+			 * Out of threads in secure world, wait for a thread
+			 * become available.
+			 */
+			optee_cq_wait_for_completion(&optee->call_queue, &w);
+			data->data0 = cmd;
+			data->data1 = w4;
+			data->data2 = w5;
+			data->data3 = w6;
+			continue;
+		default:
+			rc = -EIO;
+			goto done;
+		}
+
+		if (data->data1 == OPTEE_FFA_YIELDING_CALL_RETURN_DONE)
+			goto done;
+
+		/*
+		 * OP-TEE has returned with a RPC request.
+		 *
+		 * Note that data->data4 (passed in register w7) is already
+		 * filled in by ffa_ops->sync_send_receive() returning
+		 * above.
+		 */
+		cond_resched();
+		optee_handle_ffa_rpc(ctx, data->data1, rpc_arg);
+		cmd = OPTEE_FFA_YIELDING_CALL_RESUME;
+		data->data0 = cmd;
+		data->data1 = 0;
+		data->data2 = 0;
+		data->data3 = 0;
+	}
+done:
+	/*
+	 * We're done with our thread in secure world, if there's any
+	 * thread waiters wake up one.
+	 */
+	optee_cq_wait_final(&optee->call_queue, &w);
+
+	return rc;
+}
+
+/**
+ * optee_ffa_do_call_with_arg() - Do a FF-A call to enter OP-TEE in secure world
+ * @ctx:	calling context
+ * @shm:	shared memory holding the message to pass to secure world
+ *
+ * Does a FF-A call to OP-TEE in secure world and handles eventual resulting
+ * Remote Procedure Calls (RPC) from OP-TEE.
+ *
+ * Returns return code from FF-A, 0 is OK
+ */
+
+static int optee_ffa_do_call_with_arg(struct tee_context *ctx,
+				      struct tee_shm *shm)
+{
+	struct ffa_send_direct_data data = {
+		.data0 = OPTEE_FFA_YIELDING_CALL_WITH_ARG,
+		.data1 = (u32)shm->sec_world_id,
+		.data2 = (u32)(shm->sec_world_id >> 32),
+		.data3 = shm->offset,
+	};
+	struct optee_msg_arg *arg = tee_shm_get_va(shm, 0);
+	unsigned int rpc_arg_offs = OPTEE_MSG_GET_ARG_SIZE(arg->num_params);
+	struct optee_msg_arg *rpc_arg = tee_shm_get_va(shm, rpc_arg_offs);
+
+	return optee_ffa_yielding_call(ctx, &data, rpc_arg);
+}
+
+/*
+ * 6. Driver initialization
+ *
+ * During driver inititialization is the OP-TEE Secure Partition is probed
+ * to find out which features it supports so the driver can be initialized
+ * with a matching configuration.
+ */
+
+static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev,
+					const struct ffa_dev_ops *ops)
+{
+	struct ffa_send_direct_data data = { OPTEE_FFA_GET_API_VERSION };
+	int rc;
+
+	ops->mode_32bit_set(ffa_dev);
+
+	rc = ops->sync_send_receive(ffa_dev, &data);
+	if (rc) {
+		pr_err("Unexpected error %d\n", rc);
+		return false;
+	}
+	if (data.data0 != OPTEE_FFA_VERSION_MAJOR ||
+	    data.data1 < OPTEE_FFA_VERSION_MINOR) {
+		pr_err("Incompatible OP-TEE API version %lu.%lu",
+		       data.data0, data.data1);
+		return false;
+	}
+
+	data = (struct ffa_send_direct_data){ OPTEE_FFA_GET_OS_VERSION };
+	rc = ops->sync_send_receive(ffa_dev, &data);
+	if (rc) {
+		pr_err("Unexpected error %d\n", rc);
+		return false;
+	}
+	if (data.data2)
+		pr_info("revision %lu.%lu (%08lx)",
+			data.data0, data.data1, data.data2);
+	else
+		pr_info("revision %lu.%lu", data.data0, data.data1);
+
+	return true;
+}
+
+static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev,
+				    const struct ffa_dev_ops *ops,
+				    unsigned int *rpc_arg_count)
+{
+	struct ffa_send_direct_data data = { OPTEE_FFA_EXCHANGE_CAPABILITIES };
+	int rc;
+
+	rc = ops->sync_send_receive(ffa_dev, &data);
+	if (rc) {
+		pr_err("Unexpected error %d", rc);
+		return false;
+	}
+	if (data.data0) {
+		pr_err("Unexpected exchange error %lu", data.data0);
+		return false;
+	}
+
+	*rpc_arg_count = (u8)data.data1;
+
+	return true;
+}
+
+static struct tee_shm_pool *optee_ffa_config_dyn_shm(void)
+{
+	struct tee_shm_pool_mgr *priv_mgr;
+	struct tee_shm_pool_mgr *dmabuf_mgr;
+	void *rc;
+
+	rc = optee_ffa_shm_pool_alloc_pages();
+	if (IS_ERR(rc))
+		return rc;
+	priv_mgr = rc;
+
+	rc = optee_ffa_shm_pool_alloc_pages();
+	if (IS_ERR(rc)) {
+		tee_shm_pool_mgr_destroy(priv_mgr);
+		return rc;
+	}
+	dmabuf_mgr = rc;
+
+	rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
+	if (IS_ERR(rc)) {
+		tee_shm_pool_mgr_destroy(priv_mgr);
+		tee_shm_pool_mgr_destroy(dmabuf_mgr);
+	}
+
+	return rc;
+}
+
+static void optee_ffa_get_version(struct tee_device *teedev,
+				  struct tee_ioctl_version_data *vers)
+{
+	struct tee_ioctl_version_data v = {
+		.impl_id = TEE_IMPL_ID_OPTEE,
+		.impl_caps = TEE_OPTEE_CAP_TZ,
+		.gen_caps = TEE_GEN_CAP_GP | TEE_GEN_CAP_REG_MEM |
+			    TEE_GEN_CAP_MEMREF_NULL,
+	};
+
+	*vers = v;
+}
+
+static int optee_ffa_open(struct tee_context *ctx)
+{
+	return optee_open(ctx, true);
+}
+
+static const struct tee_driver_ops optee_ffa_clnt_ops = {
+	.get_version = optee_ffa_get_version,
+	.open = optee_ffa_open,
+	.release = optee_release,
+	.open_session = optee_open_session,
+	.close_session = optee_close_session,
+	.invoke_func = optee_invoke_func,
+	.cancel_req = optee_cancel_req,
+	.shm_register = optee_ffa_shm_register,
+	.shm_unregister = optee_ffa_shm_unregister,
+};
+
+static const struct tee_desc optee_ffa_clnt_desc = {
+	.name = DRIVER_NAME "-ffa-clnt",
+	.ops = &optee_ffa_clnt_ops,
+	.owner = THIS_MODULE,
+};
+
+static const struct tee_driver_ops optee_ffa_supp_ops = {
+	.get_version = optee_ffa_get_version,
+	.open = optee_ffa_open,
+	.release = optee_release_supp,
+	.supp_recv = optee_supp_recv,
+	.supp_send = optee_supp_send,
+	.shm_register = optee_ffa_shm_register, /* same as for clnt ops */
+	.shm_unregister = optee_ffa_shm_unregister_supp,
+};
+
+static const struct tee_desc optee_ffa_supp_desc = {
+	.name = DRIVER_NAME "-ffa-supp",
+	.ops = &optee_ffa_supp_ops,
+	.owner = THIS_MODULE,
+	.flags = TEE_DESC_PRIVILEGED,
+};
+
+static const struct optee_ops optee_ffa_ops = {
+	.do_call_with_arg = optee_ffa_do_call_with_arg,
+	.to_msg_param = optee_ffa_to_msg_param,
+	.from_msg_param = optee_ffa_from_msg_param,
+};
+
+static void optee_ffa_remove(struct ffa_device *ffa_dev)
+{
+	struct optee *optee = ffa_dev->dev.driver_data;
+
+	optee_remove_common(optee);
+
+	mutex_destroy(&optee->ffa.mutex);
+	rhashtable_free_and_destroy(&optee->ffa.global_ids, rh_free_fn, NULL);
+
+	kfree(optee);
+}
+
+static int optee_ffa_probe(struct ffa_device *ffa_dev)
+{
+	const struct ffa_dev_ops *ffa_ops;
+	unsigned int rpc_arg_count;
+	struct tee_device *teedev;
+	struct optee *optee;
+	int rc;
+
+	ffa_ops = ffa_dev_ops_get(ffa_dev);
+	if (!ffa_ops) {
+		pr_warn("failed \"method\" init: ffa\n");
+		return -ENOENT;
+	}
+
+	if (!optee_ffa_api_is_compatbile(ffa_dev, ffa_ops))
+		return -EINVAL;
+
+	if (!optee_ffa_exchange_caps(ffa_dev, ffa_ops, &rpc_arg_count))
+		return -EINVAL;
+
+	optee = kzalloc(sizeof(*optee), GFP_KERNEL);
+	if (!optee) {
+		rc = -ENOMEM;
+		goto err;
+	}
+	optee->pool = optee_ffa_config_dyn_shm();
+	if (IS_ERR(optee->pool)) {
+		rc = PTR_ERR(optee->pool);
+		optee->pool = NULL;
+		goto err;
+	}
+
+	optee->ops = &optee_ffa_ops;
+	optee->ffa.ffa_dev = ffa_dev;
+	optee->ffa.ffa_ops = ffa_ops;
+	optee->rpc_arg_count = rpc_arg_count;
+
+	teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool,
+				  optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->teedev = teedev;
+
+	teedev = tee_device_alloc(&optee_ffa_supp_desc, NULL, optee->pool,
+				  optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->supp_teedev = teedev;
+
+	rc = tee_device_register(optee->teedev);
+	if (rc)
+		goto err;
+
+	rc = tee_device_register(optee->supp_teedev);
+	if (rc)
+		goto err;
+
+	rc = rhashtable_init(&optee->ffa.global_ids, &shm_rhash_params);
+	if (rc)
+		goto err;
+	mutex_init(&optee->ffa.mutex);
+	mutex_init(&optee->call_queue.mutex);
+	INIT_LIST_HEAD(&optee->call_queue.waiters);
+	optee_wait_queue_init(&optee->wait_queue);
+	optee_supp_init(&optee->supp);
+	ffa_dev_set_drvdata(ffa_dev, optee);
+
+	rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
+	if (rc) {
+		optee_ffa_remove(ffa_dev);
+		return rc;
+	}
+
+	pr_info("initialized driver\n");
+	return 0;
+err:
+	/*
+	 * tee_device_unregister() is safe to call even if the
+	 * devices hasn't been registered with
+	 * tee_device_register() yet.
+	 */
+	tee_device_unregister(optee->supp_teedev);
+	tee_device_unregister(optee->teedev);
+	if (optee->pool)
+		tee_shm_pool_free(optee->pool);
+	kfree(optee);
+	return rc;
+}
+
+static const struct ffa_device_id optee_ffa_device_id[] = {
+	/* 486178e0-e7f8-11e3-bc5e0002a5d5c51b */
+	{ UUID_INIT(0x486178e0, 0xe7f8, 0x11e3,
+		    0xbc, 0x5e, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b) },
+	{}
+};
+
+static struct ffa_driver optee_ffa_driver = {
+	.name = "optee",
+	.probe = optee_ffa_probe,
+	.remove = optee_ffa_remove,
+	.id_table = optee_ffa_device_id,
+};
+
+int optee_ffa_abi_register(void)
+{
+	return ffa_register(&optee_ffa_driver);
+}
+
+void optee_ffa_abi_unregister(void)
+{
+	ffa_unregister(&optee_ffa_driver);
+}
diff --git a/drivers/tee/optee/optee_ffa.h b/drivers/tee/optee/optee_ffa.h
new file mode 100644
index 000000000000..ee3a03fc392c
--- /dev/null
+++ b/drivers/tee/optee/optee_ffa.h
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2019-2021, Linaro Limited
+ */
+
+/*
+ * This file is exported by OP-TEE and is kept in sync between secure world
+ * and normal world drivers. We're using ARM FF-A 1.0 specification.
+ */
+
+#ifndef __OPTEE_FFA_H
+#define __OPTEE_FFA_H
+
+#include <linux/arm_ffa.h>
+
+/*
+ * Normal world sends requests with FFA_MSG_SEND_DIRECT_REQ and
+ * responses are returned with FFA_MSG_SEND_DIRECT_RESP for normal
+ * messages.
+ *
+ * All requests with FFA_MSG_SEND_DIRECT_REQ and FFA_MSG_SEND_DIRECT_RESP
+ * are using the AArch32 SMC calling convention with register usage as
+ * defined in FF-A specification:
+ * w0:    Function ID (0x8400006F or 0x84000070)
+ * w1:    Source/Destination IDs
+ * w2:    Reserved (MBZ)
+ * w3-w7: Implementation defined, free to be used below
+ */
+
+#define OPTEE_FFA_VERSION_MAJOR	1
+#define OPTEE_FFA_VERSION_MINOR	0
+
+#define OPTEE_FFA_BLOCKING_CALL(id)	(id)
+#define OPTEE_FFA_YIELDING_CALL_BIT	31
+#define OPTEE_FFA_YIELDING_CALL(id)	((id) | BIT(OPTEE_FFA_YIELDING_CALL_BIT))
+
+/*
+ * Returns the API version implemented, currently follows the FF-A version.
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_GET_API_VERSION
+ * w4-w7: Not used (MBZ)
+ *
+ * Return register usage:
+ * w3:    OPTEE_FFA_VERSION_MAJOR
+ * w4:    OPTEE_FFA_VERSION_MINOR
+ * w5-w7: Not used (MBZ)
+ */
+#define OPTEE_FFA_GET_API_VERSION	OPTEE_FFA_BLOCKING_CALL(0)
+
+/*
+ * Returns the revision of OP-TEE.
+ *
+ * Used by non-secure world to figure out which version of the Trusted OS
+ * is installed. Note that the returned revision is the revision of the
+ * Trusted OS, not of the API.
+ *
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_GET_OS_VERSION
+ * w4-w7: Unused (MBZ)
+ *
+ * Return register usage:
+ * w3:    CFG_OPTEE_REVISION_MAJOR
+ * w4:    CFG_OPTEE_REVISION_MINOR
+ * w5:    TEE_IMPL_GIT_SHA1 (or zero if not supported)
+ */
+#define OPTEE_FFA_GET_OS_VERSION	OPTEE_FFA_BLOCKING_CALL(1)
+
+/*
+ * Exchange capabilities between normal world and secure world.
+ *
+ * Currently there are no defined capabilities. When features are added new
+ * capabilities may be added.
+ *
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_EXCHANGE_CAPABILITIES
+ * w4-w7: Note used (MBZ)
+ *
+ * Return register usage:
+ * w3:    Error code, 0 on success
+ * w4:    Bit[7:0]:  Number of parameters needed for RPC to be supplied
+ *                   as the second MSG arg struct for
+ *                   OPTEE_FFA_YIELDING_CALL_WITH_ARG.
+ *        Bit[31:8]: Reserved (MBZ)
+ * w5-w7: Note used (MBZ)
+ */
+#define OPTEE_FFA_EXCHANGE_CAPABILITIES OPTEE_FFA_BLOCKING_CALL(2)
+
+/*
+ * Unregister shared memory
+ *
+ * Call register usage:
+ * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_UNREGISTER_SHM
+ * w4:    Shared memory handle, lower bits
+ * w5:    Shared memory handle, higher bits
+ * w6-w7: Not used (MBZ)
+ *
+ * Return register usage:
+ * w3:    Error code, 0 on success
+ * w4-w7: Note used (MBZ)
+ */
+#define OPTEE_FFA_UNREGISTER_SHM	OPTEE_FFA_BLOCKING_CALL(3)
+
+/*
+ * Call with struct optee_msg_arg as argument in the supplied shared memory
+ * with a zero internal offset and normal cached memory attributes.
+ * Register usage:
+ * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_WITH_ARG
+ * w4:    Lower 32 bits of a 64-bit Shared memory handle
+ * w5:    Upper 32 bits of a 64-bit Shared memory handle
+ * w6:    Offset into shared memory pointing to a struct optee_msg_arg
+ *	  right after the parameters of this struct (at offset
+ *	  OPTEE_MSG_GET_ARG_SIZE(num_params) follows a struct optee_msg_arg
+ *	  for RPC, this struct has reserved space for the number of RPC
+ *	  parameters as returned by OPTEE_FFA_EXCHANGE_CAPABILITIES.
+ * w7:    Not used (MBZ)
+ * Resume from RPC. Register usage:
+ * w3:    Service ID, OPTEE_FFA_YIELDING_CALL_RESUME
+ * w4-w6: Not used (MBZ)
+ * w7:    Resume info
+ *
+ * Normal return (yielding call is completed). Register usage:
+ * w3:    Error code, 0 on success
+ * w4:    OPTEE_FFA_YIELDING_CALL_RETURN_DONE
+ * w5-w7: Not used (MBZ)
+ *
+ * RPC interrupt return (RPC from secure world). Register usage:
+ * w3:    Error code == 0
+ * w4:    Any defined RPC code but OPTEE_FFA_YIELDING_CALL_RETURN_DONE
+ * w5-w6: Not used (MBZ)
+ * w7:    Resume info
+ *
+ * Possible error codes in register w3:
+ * 0:                       Success
+ * FFA_DENIED:              w4 isn't one of OPTEE_FFA_YIELDING_CALL_START
+ *                          OPTEE_FFA_YIELDING_CALL_RESUME
+ *
+ * Possible error codes for OPTEE_FFA_YIELDING_CALL_START,
+ * FFA_BUSY:               Number of OP-TEE OS threads exceeded,
+ *                         try again later
+ * FFA_DENIED:             RPC shared memory object not found
+ * FFA_INVALID_PARAMETER:  Bad shared memory handle or offset into the memory
+ *
+ * Possible error codes for OPTEE_FFA_YIELDING_CALL_RESUME
+ * FFA_INVALID_PARAMETER:  Bad resume info
+ */
+#define OPTEE_FFA_YIELDING_CALL_WITH_ARG	OPTEE_FFA_YIELDING_CALL(0)
+#define OPTEE_FFA_YIELDING_CALL_RESUME		OPTEE_FFA_YIELDING_CALL(1)
+
+#define OPTEE_FFA_YIELDING_CALL_RETURN_DONE		0
+#define OPTEE_FFA_YIELDING_CALL_RETURN_RPC_CMD		1
+#define OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT	2
+
+#endif /*__OPTEE_FFA_H*/
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index e3d72d09c484..2422e185d400 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -28,6 +28,9 @@
 #define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT		0x5
 #define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT		0x6
 #define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT		0x7
+#define OPTEE_MSG_ATTR_TYPE_FMEM_INPUT		OPTEE_MSG_ATTR_TYPE_RMEM_INPUT
+#define OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT		OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT
+#define OPTEE_MSG_ATTR_TYPE_FMEM_INOUT		OPTEE_MSG_ATTR_TYPE_RMEM_INOUT
 #define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT		0x9
 #define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT		0xa
 #define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT		0xb
@@ -96,6 +99,8 @@
  */
 #define OPTEE_MSG_NONCONTIG_PAGE_SIZE		4096
 
+#define OPTEE_MSG_FMEM_INVALID_GLOBAL_ID	0xffffffffffffffff
+
 /**
  * struct optee_msg_param_tmem - temporary memory reference parameter
  * @buf_ptr:	Address of the buffer
@@ -127,6 +132,23 @@ struct optee_msg_param_rmem {
 	u64 shm_ref;
 };
 
+/**
+ * struct optee_msg_param_fmem - ffa memory reference parameter
+ * @offs_lower:	   Lower bits of offset into shared memory reference
+ * @offs_upper:	   Upper bits of offset into shared memory reference
+ * @internal_offs: Internal offset into the first page of shared memory
+ *		   reference
+ * @size:	   Size of the buffer
+ * @global_id:	   Global identifier of Shared memory
+ */
+struct optee_msg_param_fmem {
+	u32 offs_low;
+	u16 offs_high;
+	u16 internal_offs;
+	u64 size;
+	u64 global_id;
+};
+
 /**
  * struct optee_msg_param_value - opaque value parameter
  *
@@ -143,13 +165,15 @@ struct optee_msg_param_value {
  * @attr:	attributes
  * @tmem:	parameter by temporary memory reference
  * @rmem:	parameter by registered memory reference
+ * @fmem:	parameter by ffa registered memory reference
  * @value:	parameter by opaque value
  * @octets:	parameter by octet string
  *
  * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in
  * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value or octets,
  * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and
- * OPTEE_MSG_ATTR_TYPE_RMEM_* indicates @rmem,
+ * OPTEE_MSG_ATTR_TYPE_RMEM_* or the alias PTEE_MSG_ATTR_TYPE_FMEM_* indicates
+ * @rmem or @fmem depending on the conduit.
  * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used.
  */
 struct optee_msg_param {
@@ -157,6 +181,7 @@ struct optee_msg_param {
 	union {
 		struct optee_msg_param_tmem tmem;
 		struct optee_msg_param_rmem rmem;
+		struct optee_msg_param_fmem fmem;
 		struct optee_msg_param_value value;
 		u8 octets[24];
 	} u;
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index ca0213e330b5..2593742364da 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -7,6 +7,7 @@
 #define OPTEE_PRIVATE_H
 
 #include <linux/arm-smccc.h>
+#include <linux/rhashtable.h>
 #include <linux/semaphore.h>
 #include <linux/tee_drv.h>
 #include <linux/types.h>
@@ -22,6 +23,7 @@
 #define TEEC_ERROR_NOT_SUPPORTED	0xFFFF000A
 #define TEEC_ERROR_COMMUNICATION	0xFFFF000E
 #define TEEC_ERROR_OUT_OF_MEMORY	0xFFFF000C
+#define TEEC_ERROR_BUSY			0xFFFF000D
 #define TEEC_ERROR_SHORT_BUFFER		0xFFFF0010
 
 #define TEEC_ORIGIN_COMMS		0x00000002
@@ -73,19 +75,28 @@ struct optee_supp {
 	struct completion reqs_c;
 };
 
-/**
- * struct optee_smc - SMC ABI specifics
- * @invoke_fn:		function to issue smc or hvc
- * @memremaped_shm	virtual address of memory in shared memory pool
- * @sec_caps:		secure world capabilities defined by
- *			OPTEE_SMC_SEC_CAP_* in optee_smc.h
- */
 struct optee_smc {
 	optee_invoke_fn *invoke_fn;
 	void *memremaped_shm;
 	u32 sec_caps;
 };
 
+/**
+ * struct optee_ffa_data -  FFA communication struct
+ * @ffa_dev		FFA device, contains the destination id, the id of
+ *			OP-TEE in secure world
+ * @ffa_ops		FFA operations
+ * @mutex		Serializes access to @global_ids
+ * @global_ids		FF-A shared memory global handle translation
+ */
+struct optee_ffa {
+	struct ffa_device *ffa_dev;
+	const struct ffa_dev_ops *ffa_ops;
+	/* Serializes access to @global_ids */
+	struct mutex mutex;
+	struct rhashtable global_ids;
+};
+
 struct optee;
 
 /**
@@ -116,11 +127,13 @@ struct optee_ops {
  *			world
  * @teedev:		client device
  * @smc:		specific to SMC ABI
+ * @ffa:		specific to FF-A ABI
  * @call_queue:		queue of threads waiting to call @invoke_fn
  * @wait_queue:		queue of threads from secure world waiting for a
  *			secure world sync object
  * @supp:		supplicant synchronization struct for RPC to supplicant
  * @pool:		shared memory pool
+ * @rpc_arg_count:	If > 0 number of RPC parameters to make room for
  * @scan_bus_done	flag if device registation was already done.
  * @scan_bus_wq		workqueue to scan optee bus and register optee drivers
  * @scan_bus_work	workq to scan optee bus and register optee drivers
@@ -129,11 +142,17 @@ struct optee {
 	struct tee_device *supp_teedev;
 	struct tee_device *teedev;
 	const struct optee_ops *ops;
-	struct optee_smc smc;
+	union {
+		struct optee_smc smc;
+#ifdef CONFIG_ARM_FFA_TRANSPORT
+		struct optee_ffa ffa;
+#endif
+	};
 	struct optee_call_queue call_queue;
 	struct optee_wait_queue wait_queue;
 	struct optee_supp supp;
 	struct tee_shm_pool *pool;
+	unsigned int rpc_arg_count;
 	bool   scan_bus_done;
 	struct workqueue_struct *scan_bus_wq;
 	struct work_struct scan_bus_work;
@@ -266,4 +285,12 @@ static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
 int optee_smc_abi_register(void);
 void optee_smc_abi_unregister(void);
 
+#ifdef CONFIG_ARM_FFA_TRANSPORT
+int optee_ffa_abi_register(void);
+void optee_ffa_abi_unregister(void);
+#else
+static inline int optee_ffa_abi_register(void) { return -EOPNOTSUPP; }
+static inline void optee_ffa_abi_unregister(void) {}
+#endif
+
 #endif /*OPTEE_PRIVATE_H*/
-- 
2.31.1



From balbi at kernel.org  Tue Aug 31 00:27:20 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Tue, 31 Aug 2021 10:27:20 +0300
Subject: [PATCH v3 1/4] dt-bindings: usb: dwc3: add reference clock period
In-Reply-To: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
References: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
Message-ID: <87mtoycbvb.fsf@kernel.org>


Baruch Siach <baruch at tkos.co.il> writes:

> Document the snps,ref-clock-period-ns property that describes reference
> clock period when it deviates from the default set value.
>
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>

Acked-by: Felipe Balbi <balbi at kernel.org>

-- 
balbi


From balbi at kernel.org  Tue Aug 31 00:27:45 2021
From: balbi at kernel.org (Felipe Balbi)
Date: Tue, 31 Aug 2021 10:27:45 +0300
Subject: [PATCH v3 2/4] usb: dwc3: reference clock period configuration
In-Reply-To: <9f399bdf1ff752e31ab7497e3d5ce19bbb3ff247.1630389452.git.baruch@tkos.co.il>
References: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
 <9f399bdf1ff752e31ab7497e3d5ce19bbb3ff247.1630389452.git.baruch@tkos.co.il>
Message-ID: <87ilzmcbqa.fsf@kernel.org>


Baruch Siach <baruch at tkos.co.il> writes:

> From: Balaji Prakash J <bjagadee at codeaurora.org>
>
> Set reference clock period when it differs from dwc3 default hardware
> set.
>
> We could calculate clock period based on reference clock frequency. But
> this information is not always available. This is the case of PCI bus
> attached USB host. For that reason we use a custom property.
>
> Tested (USB2 only) on IPQ6010 SoC based board with 24 MHz reference
> clock while hardware default is 19.2 MHz.
>
> Nacked-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Balaji Prakash J <bjagadee at codeaurora.org>
> [ baruch: rewrite commit message; drop GFLADJ code; remove 'quirk-' from
>   property name; mention tested hardware ]
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>

Acked-by: Felipe Balbi <balbi at kernel.org>


-- 
balbi


From caihuoqing at baidu.com  Tue Aug 31 00:44:49 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 15:44:49 +0800
Subject: [PATCH] drm/aspeed: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210831074449.563-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
index b53fee6f1c17..de65da467de7 100644
--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
+++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
@@ -133,11 +133,9 @@ static int aspeed_gfx_load(struct drm_device *drm)
 	struct device_node *np = pdev->dev.of_node;
 	const struct aspeed_gfx_config *config;
 	const struct of_device_id *match;
-	struct resource *res;
 	int ret;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->base = devm_ioremap_resource(drm->dev, res);
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->base))
 		return PTR_ERR(priv->base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 00:49:58 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 15:49:58 +0800
Subject: [PATCH] drm/exynos: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210831074958.608-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 4 +---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c       | 4 +---
 drivers/gpu/drm/exynos/exynos_drm_fimc.c      | 5 +----
 drivers/gpu/drm/exynos/exynos_drm_fimd.c      | 4 +---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c       | 5 +----
 drivers/gpu/drm/exynos/exynos_drm_gsc.c       | 6 +-----
 drivers/gpu/drm/exynos/exynos_drm_rotator.c   | 4 +---
 drivers/gpu/drm/exynos/exynos_drm_scaler.c    | 4 +---
 drivers/gpu/drm/exynos/exynos_hdmi.c          | 4 +---
 9 files changed, 9 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index 9870c4e6af36..b5001db7a95c 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -793,7 +793,6 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct decon_context *ctx;
-	struct resource *res;
 	int ret;
 	int i;
 
@@ -818,8 +817,7 @@ static int exynos5433_decon_probe(struct platform_device *pdev)
 		ctx->clks[i] = clk;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ctx->addr = devm_ioremap_resource(dev, res);
+	ctx->addr = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ctx->addr))
 		return PTR_ERR(ctx->addr);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index e39fac889edc..8d137857818c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1738,7 +1738,6 @@ static const struct component_ops exynos_dsi_component_ops = {
 static int exynos_dsi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct resource *res;
 	struct exynos_dsi *dsi;
 	int ret, i;
 
@@ -1789,8 +1788,7 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 		}
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dsi->reg_base = devm_ioremap_resource(dev, res);
+	dsi->reg_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dsi->reg_base))
 		return PTR_ERR(dsi->reg_base);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
index a3c718148c45..ecfd82d0afb7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c
@@ -85,7 +85,6 @@ struct fimc_scaler {
 /*
  * A structure of fimc context.
  *
- * @regs_res: register resources.
  * @regs: memory mapped io registers.
  * @lock: locking of operations.
  * @clocks: fimc clocks.
@@ -103,7 +102,6 @@ struct fimc_context {
 	struct exynos_drm_ipp_formats	*formats;
 	unsigned int			num_formats;
 
-	struct resource	*regs_res;
 	void __iomem	*regs;
 	spinlock_t	lock;
 	struct clk	*clocks[FIMC_CLKS_MAX];
@@ -1327,8 +1325,7 @@ static int fimc_probe(struct platform_device *pdev)
 	ctx->num_formats = num_formats;
 
 	/* resource memory */
-	ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ctx->regs = devm_ioremap_resource(dev, ctx->regs_res);
+	ctx->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ctx->regs))
 		return PTR_ERR(ctx->regs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 700ca4fa6665..c735e53939d8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -1202,9 +1202,7 @@ static int fimd_probe(struct platform_device *pdev)
 		return PTR_ERR(ctx->lcd_clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	ctx->regs = devm_ioremap_resource(dev, res);
+	ctx->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ctx->regs))
 		return PTR_ERR(ctx->regs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index b00230626c6a..471fd6c8135f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -1449,7 +1449,6 @@ static const struct component_ops g2d_component_ops = {
 static int g2d_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct resource *res;
 	struct g2d_data *g2d;
 	int ret;
 
@@ -1491,9 +1490,7 @@ static int g2d_probe(struct platform_device *pdev)
 	clear_bit(G2D_BIT_SUSPEND_RUNQUEUE, &g2d->flags);
 	clear_bit(G2D_BIT_ENGINE_BUSY, &g2d->flags);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	g2d->regs = devm_ioremap_resource(dev, res);
+	g2d->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(g2d->regs)) {
 		ret = PTR_ERR(g2d->regs);
 		goto err_put_clk;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 90d7bf906885..166a80262896 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -86,7 +86,6 @@ struct gsc_scaler {
 /*
  * A structure of gsc context.
  *
- * @regs_res: register resources.
  * @regs: memory mapped io registers.
  * @gsc_clk: gsc gate clock.
  * @sc: scaler infomations.
@@ -103,7 +102,6 @@ struct gsc_context {
 	struct exynos_drm_ipp_formats	*formats;
 	unsigned int			num_formats;
 
-	struct resource	*regs_res;
 	void __iomem	*regs;
 	const char	**clk_names;
 	struct clk	*clocks[GSC_MAX_CLOCKS];
@@ -1272,9 +1270,7 @@ static int gsc_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* resource memory */
-	ctx->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ctx->regs = devm_ioremap_resource(dev, ctx->regs_res);
+	ctx->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ctx->regs))
 		return PTR_ERR(ctx->regs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
index ee61be4cf152..dec7df35baa9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c
@@ -278,7 +278,6 @@ static const struct component_ops rotator_component_ops = {
 static int rotator_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct resource	*regs_res;
 	struct rot_context *rot;
 	const struct rot_variant *variant;
 	int irq;
@@ -292,8 +291,7 @@ static int rotator_probe(struct platform_device *pdev)
 	rot->formats = variant->formats;
 	rot->num_formats = variant->num_formats;
 	rot->dev = dev;
-	regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	rot->regs = devm_ioremap_resource(dev, regs_res);
+	rot->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(rot->regs))
 		return PTR_ERR(rot->regs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_scaler.c b/drivers/gpu/drm/exynos/exynos_drm_scaler.c
index f9ae5b038d59..3a7851b7dc66 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_scaler.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_scaler.c
@@ -485,7 +485,6 @@ static const struct component_ops scaler_component_ops = {
 static int scaler_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct resource	*regs_res;
 	struct scaler_context *scaler;
 	int irq;
 	int ret, i;
@@ -498,8 +497,7 @@ static int scaler_probe(struct platform_device *pdev)
 		(struct scaler_data *)of_device_get_match_data(dev);
 
 	scaler->dev = dev;
-	regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	scaler->regs = devm_ioremap_resource(dev, regs_res);
+	scaler->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(scaler->regs))
 		return PTR_ERR(scaler->regs);
 
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index c769dec576de..7655142a4651 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -1957,7 +1957,6 @@ static int hdmi_probe(struct platform_device *pdev)
 	struct hdmi_audio_infoframe *audio_infoframe;
 	struct device *dev = &pdev->dev;
 	struct hdmi_context *hdata;
-	struct resource *res;
 	int ret;
 
 	hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
@@ -1979,8 +1978,7 @@ static int hdmi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdata->regs = devm_ioremap_resource(dev, res);
+	hdata->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hdata->regs)) {
 		ret = PTR_ERR(hdata->regs);
 		return ret;
-- 
2.25.1



From p.zabel at pengutronix.de  Tue Aug 31 00:51:23 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Tue, 31 Aug 2021 09:51:23 +0200
Subject: [v5 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
In-Reply-To: <20210831071458.2334-10-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
 <20210831071458.2334-10-billy_tsai@aspeedtech.com>
Message-ID: <4bc2bf196efd540933e6a781a44af20142e3d5d3.camel@pengutronix.de>

Hi Billy,

On Tue, 2021-08-31 at 15:14 +0800, Billy Tsai wrote:
> This patch use devm_add_action_or_reset to handle the error in probe
> phase.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  drivers/iio/adc/aspeed_adc.c | 112 +++++++++++++++++++++--------------
>  1 file changed, 66 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
> index e53d1541ad1d..af00d9752c1e 100644
> --- a/drivers/iio/adc/aspeed_adc.c
> +++ b/drivers/iio/adc/aspeed_adc.c
[...]
> @@ -242,6 +271,11 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  			&data->clk_lock);
>  		if (IS_ERR(data->clk_prescaler))
>  			return PTR_ERR(data->clk_prescaler);
> +		ret = devm_add_action_or_reset(data->dev,
> +					       aspeed_adc_unregister_divider,
> +					       data->clk_prescaler);
> +		if (ret)
> +			return ret;

I think here you could switch to devm_clk_hw_register_divider() instead.


>  		snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name),
>  			 clk_name);
>  		scaler_flags = CLK_SET_RATE_PARENT;
> @@ -256,23 +290,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  		&pdev->dev, clk_name, clk_parent_name, scaler_flags,
>  		data->base + ASPEED_REG_CLOCK_CONTROL, 0,
>  		data->model_data->scaler_bit_width, 0, &data->clk_lock);
> -	if (IS_ERR(data->clk_scaler)) {
> -		ret = PTR_ERR(data->clk_scaler);
> -		goto scaler_error;
> -	}
> +	if (IS_ERR(data->clk_scaler))
> +		return PTR_ERR(data->clk_scaler);
> +
> +	ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
> +				       data->clk_scaler);
> +	if (ret)
> +		return ret;

Same as above.

[...]
> @@ -281,6 +322,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  			       ASPEED_ADC_ENGINE_ENABLE,
>  		       data->base + ASPEED_REG_ENGINE_CONTROL);
>  
> +		ret = devm_add_action_or_reset(data->dev, aspeed_adc_power_down,
> +					       data);
> +		if (ret)
> +			return ret;
>  		/* Wait for initial sequence complete. */
>  		ret = readl_poll_timeout(data->base + ASPEED_REG_ENGINE_CONTROL,
>  					 adc_engine_control_reg_val,
[...]
> @@ -303,6 +354,11 @@ static int aspeed_adc_probe(struct platform_device *pdev)
>  		ASPEED_ADC_ENGINE_ENABLE;
>  	writel(adc_engine_control_reg_val,
>  	       data->base + ASPEED_REG_ENGINE_CONTROL);
> +	ret = devm_add_action_or_reset(data->dev,
> +				       aspeed_adc_power_down,
> +				       data);
> +	if (ret)
> +		return ret;

Should this be if (!model_dta->wait_init_sequence) ? Otherwise it looks
like you've already registered the same aspeed_adc_power_down action
above.

regards
Philipp


From wenst at chromium.org  Tue Aug 31 00:53:48 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 31 Aug 2021 15:53:48 +0800
Subject: [PATCH v11 3/4] pinctrl: mediatek: mt8195: Add pm_ops
In-Reply-To: <20210830003603.31864-4-zhiyong.tao@mediatek.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
 <20210830003603.31864-4-zhiyong.tao@mediatek.com>
Message-ID: <CAGXv+5Gx74SxdB_-V3SZB1sQ3=bpUkbkkaHxAyFg9m+7k+HVkw@mail.gmail.com>

On Mon, Aug 30, 2021 at 8:37 AM Zhiyong Tao <zhiyong.tao at mediatek.com> wrote:
>
> Setting this up will configure wake from suspend properly,
> and wake only for the interrupts that are setup in wake_mask,
> not all interrupts.

This sounds like a fix. Please add a Fixes tag for this patch. This makes
tracking things easier.

So,

Fixes: 6cf5e9ef362a ("pinctrl: add pinctrl driver on mt8195")
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

Also this patch is unrelated to the rest. You should send it separately.
This would also help the maintainer merge it directly.

> Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
> ---
>  drivers/pinctrl/mediatek/pinctrl-mt8195.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8195.c b/drivers/pinctrl/mediatek/pinctrl-mt8195.c
> index a7500e18bb1d..892e79703f98 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt8195.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8195.c
> @@ -839,6 +839,7 @@ static struct platform_driver mt8195_pinctrl_driver = {
>         .driver = {
>                 .name = "mt8195-pinctrl",
>                 .of_match_table = mt8195_pinctrl_of_match,
> +               .pm = &mtk_paris_pinctrl_pm_ops,
>         },
>         .probe = mt8195_pinctrl_probe,
>  };
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From pali at kernel.org  Tue Aug 31 01:35:10 2021
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Tue, 31 Aug 2021 10:35:10 +0200
Subject: [PATCH v5 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <20210820172238.ekvo42s7oqxkeomt@pali>
References: <20210624224909.6350-1-pali@kernel.org>
 <20210809145329.24177-1-pali@kernel.org>
 <20210820172238.ekvo42s7oqxkeomt@pali>
Message-ID: <20210831083510.iiapfla7iy76fs3w@pali>

On Friday 20 August 2021 19:22:38 Pali Roh?r wrote:
> On Monday 09 August 2021 16:53:23 Pali Roh?r wrote:
> > This patch series add support for baudrates higher than 230400 on
> > Marvell Armada 37xx boards.
> > 
> > Please review these patches as they touch both Device Tree bindings and
> > mvebu-uart.c driver.
> 
> Stephen, is this patch series OK now? Or is there any other issue?

PING?

> > Changes in v5:
> > * fixed yaml binding file
> > 
> > Changes in v4:
> > * converted armada3700-uart-clock documentation to YAML
> > * split documentation changes into two commits:
> >   - first which adds clock documentation
> >   - second which updates UART documentation
> > 
> > Changes in v3:
> > v3 is rebased on top of Linus master branch and all already applied patches
> > were dropped. There are no changes in patches itself since v2.
> > 
> > Pali Roh?r (6):
> >   math64: New DIV_U64_ROUND_CLOSEST helper
> >   serial: mvebu-uart: implement UART clock driver for configuring UART
> >     base clock
> >   dt-bindings: mvebu-uart: document DT bindings for
> >     marvell,armada-3700-uart-clock
> >   dt-bindings: mvebu-uart: update information about UART clock
> >   arm64: dts: marvell: armada-37xx: add device node for UART clock and
> >     use it
> >   serial: mvebu-uart: implement support for baudrates higher than 230400
> > 
> >  .../bindings/clock/armada3700-uart-clock.yaml |  57 ++
> >  .../devicetree/bindings/serial/mvebu-uart.txt |   9 +-
> >  .../arm64/boot/dts/marvell/armada-3720-db.dts |   4 +
> >  .../dts/marvell/armada-3720-espressobin.dtsi  |   4 +
> >  .../dts/marvell/armada-3720-turris-mox.dts    |   4 +
> >  .../boot/dts/marvell/armada-3720-uDPU.dts     |   4 +
> >  arch/arm64/boot/dts/marvell/armada-37xx.dtsi  |  15 +-
> >  drivers/tty/serial/Kconfig                    |   1 +
> >  drivers/tty/serial/mvebu-uart.c               | 592 +++++++++++++++++-
> >  include/linux/math64.h                        |  13 +
> >  10 files changed, 682 insertions(+), 21 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/clock/armada3700-uart-clock.yaml
> > 
> > -- 
> > 2.20.1
> > 


From trevor.wu at mediatek.com  Tue Aug 31 01:39:56 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Tue, 31 Aug 2021 16:39:56 +0800
Subject: [PATCH] ASoC: dt-bindings: mt8195: remove dependent headers in the
 example
Message-ID: <20210831083956.9804-1-trevor.wu@mediatek.com>

Drop the use of the defines including clock and power id, so that
we can remove the headers which are not applied in the example.

Fixes: b5bac34fcfb4 ("dt-bindings: mediatek: mt8195: add audio afe document")
Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
---
 .../bindings/sound/mt8195-afe-pcm.yaml        | 40 +++++++++----------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
index 53e9434a6d9d..dcf790b053d2 100644
--- a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
+++ b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml
@@ -130,36 +130,34 @@ additionalProperties: false
 
 examples:
   - |
-    #include <dt-bindings/clock/mt8195-clk.h>
     #include <dt-bindings/interrupt-controller/arm-gic.h>
     #include <dt-bindings/interrupt-controller/irq.h>
-    #include <dt-bindings/power/mt8195-power.h>
 
     afe: mt8195-afe-pcm at 10890000 {
         compatible = "mediatek,mt8195-audio";
         reg = <0x10890000 0x10000>;
         interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
         mediatek,topckgen = <&topckgen>;
-        power-domains = <&spm MT8195_POWER_DOMAIN_AUDIO>;
+        power-domains = <&spm 7>; //MT8195_POWER_DOMAIN_AUDIO
         clocks = <&clk26m>,
-                 <&topckgen CLK_TOP_APLL1>,
-                 <&topckgen CLK_TOP_APLL2>,
-                 <&topckgen CLK_TOP_APLL12_DIV0>,
-                 <&topckgen CLK_TOP_APLL12_DIV1>,
-                 <&topckgen CLK_TOP_APLL12_DIV2>,
-                 <&topckgen CLK_TOP_APLL12_DIV3>,
-                 <&topckgen CLK_TOP_APLL12_DIV9>,
-                 <&topckgen CLK_TOP_A1SYS_HP_SEL>,
-                 <&topckgen CLK_TOP_AUD_INTBUS_SEL>,
-                 <&topckgen CLK_TOP_AUDIO_H_SEL>,
-                 <&topckgen CLK_TOP_AUDIO_LOCAL_BUS_SEL>,
-                 <&topckgen CLK_TOP_DPTX_M_SEL>,
-                 <&topckgen CLK_TOP_I2SO1_M_SEL>,
-                 <&topckgen CLK_TOP_I2SO2_M_SEL>,
-                 <&topckgen CLK_TOP_I2SI1_M_SEL>,
-                 <&topckgen CLK_TOP_I2SI2_M_SEL>,
-                 <&infracfg_ao CLK_INFRA_AO_AUDIO_26M_B>,
-                 <&scp_adsp CLK_SCP_ADSP_AUDIODSP>;
+                 <&topckgen 163>, //CLK_TOP_APLL1
+                 <&topckgen 166>, //CLK_TOP_APLL2
+                 <&topckgen 233>, //CLK_TOP_APLL12_DIV0
+                 <&topckgen 234>, //CLK_TOP_APLL12_DIV1
+                 <&topckgen 235>, //CLK_TOP_APLL12_DIV2
+                 <&topckgen 236>, //CLK_TOP_APLL12_DIV3
+                 <&topckgen 238>, //CLK_TOP_APLL12_DIV9
+                 <&topckgen 100>, //CLK_TOP_A1SYS_HP_SEL
+                 <&topckgen 33>, //CLK_TOP_AUD_INTBUS_SEL
+                 <&topckgen 34>, //CLK_TOP_AUDIO_H_SEL
+                 <&topckgen 107>, //CLK_TOP_AUDIO_LOCAL_BUS_SEL
+                 <&topckgen 98>, //CLK_TOP_DPTX_M_SEL
+                 <&topckgen 94>, //CLK_TOP_I2SO1_M_SEL
+                 <&topckgen 95>, //CLK_TOP_I2SO2_M_SEL
+                 <&topckgen 96>, //CLK_TOP_I2SI1_M_SEL
+                 <&topckgen 97>, //CLK_TOP_I2SI2_M_SEL
+                 <&infracfg_ao 50>, //CLK_INFRA_AO_AUDIO_26M_B
+                 <&scp_adsp 0>; //CLK_SCP_ADSP_AUDIODSP
         clock-names = "clk26m",
                       "apll1_ck",
                       "apll2_ck",
-- 
2.18.0

From trevor.wu at mediatek.com  Tue Aug 31 01:48:10 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Tue, 31 Aug 2021 16:48:10 +0800
Subject: [PATCH v5 07/11] dt-bindings: mediatek: mt8195: add audio afe
 document
In-Reply-To: <CAL_Jsq+bLVLqqVKfYuXDVYexMojMgZ5p34Pcx7_7LwU40b-2dA@mail.gmail.com>
References: <20210819084144.18483-1-trevor.wu@mediatek.com>
 <20210819084144.18483-8-trevor.wu@mediatek.com>
 <CAL_Jsq+bLVLqqVKfYuXDVYexMojMgZ5p34Pcx7_7LwU40b-2dA@mail.gmail.com>
Message-ID: <0d73ada63c3c2949a283ac6830ab9cc84a5e4a41.camel@mediatek.com>

On Mon, 2021-08-30 at 07:35 -0500, Rob Herring wrote:
> On Thu, Aug 19, 2021 at 3:43 AM Trevor Wu <trevor.wu at mediatek.com>
> wrote:
> > 
> > This patch adds mt8195 audio afe document.
> > 
> > In order to support dynamic clock reparenting for ADDA and ETDM,
> > PLL
> > and MUX clocks are requested even though they are not consumed by
> > afe
> > directly.
> > 
> > Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
> > ---
> > This patch depends on the following series that have not been
> > accepted.
> > 
> > [1] Mediatek MT8195 clock support
> > 
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=501923__;!!CTRNKA9wMg0ARbw!ybm7E80DLLYXs8OujO46SUKYFOUx8gsLZPTE6VDFrGTQ0rAYlJJHOUKhL_ZUSJSLkA$
> >  
> > (dt-bindings/clock/mt8195-clk.h is included)
> 
> This dependency is still not applied, so the example fails. One of
> the
> following needs to happen: the dependency needs to be applied, this
> patch reverted, or drop the use of the defines in the example.
> 
> Rob

Hi Rob,

I send a patch and drop the use of defines.

https://patchwork.kernel.org/project/alsa-devel/patch/20210831083956.9804-1-trevor.wu at mediatek.com/

Thanks,
Trevor


From dan.carpenter at oracle.com  Tue Aug 31 01:53:11 2021
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Tue, 31 Aug 2021 11:53:11 +0300
Subject: [xlnx:xlnx_rebase_v5.10 1377/1762] drivers/mtd/spi-nor/core.c:2246
 spi_nor_read_id() error: we previously assumed 'nor->spimem' could be null
 (see line 2228)
Message-ID: <202108311024.yIMfmnhL-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v5.10
head:   09a4215f61493584f4410cab3477003e4046dab9
commit: d50528bd5db19df218fd9bd1e226a5644b769007 [1377/1762] spi: spi-cadence-quadspi: Added support for DDR PHY mode
config: arm-randconfig-m031-20210830 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>
Reported-by: Dan Carpenter <dan.carpenter at oracle.com>

New smatch warnings:
drivers/mtd/spi-nor/core.c:2246 spi_nor_read_id() error: we previously assumed 'nor->spimem' could be null (see line 2228)

Old smatch warnings:
drivers/mtd/spi-nor/core.c:1072 write_ear() error: uninitialized symbol 'code'.
drivers/mtd/spi-nor/core.c:1474 spi_nor_init_erase_cmd_list() warn: passing a valid pointer to 'PTR_ERR'
drivers/mtd/spi-nor/core.c:1487 spi_nor_init_erase_cmd_list() warn: passing a valid pointer to 'PTR_ERR'

vim +2246 drivers/mtd/spi-nor/core.c

06bb6f5a69dfc5 drivers/mtd/spi-nor/spi-nor.c Rafa? Mi?ecki        2015-08-10  2221  static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
b199489d37b21c drivers/mtd/spi-nor/spi-nor.c Huang Shijie         2014-02-24  2222  {
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2223  	const struct flash_info *info;
f173f26a4d543f drivers/mtd/spi-nor/spi-nor.c Vignesh Raghavendra  2019-08-06  2224  	u8 *id = nor->bouncebuf;
2dcbfe365b1303 drivers/mtd/spi-nor/spi-nor.c Jonathan Neusch?fer  2020-02-23  2225  	unsigned int i;
2dcbfe365b1303 drivers/mtd/spi-nor/spi-nor.c Jonathan Neusch?fer  2020-02-23  2226  	int ret;
b199489d37b21c drivers/mtd/spi-nor/spi-nor.c Huang Shijie         2014-02-24  2227  
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06 @2228  	if (nor->spimem) {
                                                                                            ^^^^^^^^^^^
Check for NULL

b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2229  		struct spi_mem_op op =
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2230  			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1),
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2231  				   SPI_MEM_OP_NO_ADDR,
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2232  				   SPI_MEM_OP_NO_DUMMY,
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2233  				   SPI_MEM_OP_DATA_IN(SPI_NOR_MAX_ID_LEN, id, 1));
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2234  
2dcbfe365b1303 drivers/mtd/spi-nor/spi-nor.c Jonathan Neusch?fer  2020-02-23  2235  		ret = spi_mem_exec_op(nor->spimem, &op);
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2236  	} else {
2dcbfe365b1303 drivers/mtd/spi-nor/spi-nor.c Jonathan Neusch?fer  2020-02-23  2237  		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDID, id,
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2238  						    SPI_NOR_MAX_ID_LEN);
b35b9a10362d20 drivers/mtd/spi-nor/spi-nor.c Boris Brezillon      2019-08-06  2239  	}
2dcbfe365b1303 drivers/mtd/spi-nor/spi-nor.c Jonathan Neusch?fer  2020-02-23  2240  	if (ret) {
2dcbfe365b1303 drivers/mtd/spi-nor/spi-nor.c Jonathan Neusch?fer  2020-02-23  2241  		dev_dbg(nor->dev, "error %d reading JEDEC ID\n", ret);
2dcbfe365b1303 drivers/mtd/spi-nor/spi-nor.c Jonathan Neusch?fer  2020-02-23  2242  		return ERR_PTR(ret);
b199489d37b21c drivers/mtd/spi-nor/spi-nor.c Huang Shijie         2014-02-24  2243  	}
b199489d37b21c drivers/mtd/spi-nor/spi-nor.c Huang Shijie         2014-02-24  2244  
d50528bd5db19d drivers/mtd/spi-nor/core.c    Sai Krishna Potthuri 2021-02-02  2245  	for (i = 0; i < SPI_NOR_MAX_ID_LEN; i++)
d50528bd5db19d drivers/mtd/spi-nor/core.c    Sai Krishna Potthuri 2021-02-02 @2246  		nor->spimem->device_id[i] = id[i];
                                                                                                ^^^^^^^^^^^
Unchecked dereference.

d50528bd5db19d drivers/mtd/spi-nor/core.c    Sai Krishna Potthuri 2021-02-02  2247  
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2248  	for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2249  		info = spi_nor_search_part_by_id(manufacturers[i]->parts,
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2250  						 manufacturers[i]->nparts,
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2251  						 id);
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2252  		if (info) {
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2253  			nor->manufacturer = manufacturers[i];
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2254  			return info;
b199489d37b21c drivers/mtd/spi-nor/spi-nor.c Huang Shijie         2014-02-24  2255  		}
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2256  	}
9ec4bbcb2044ea drivers/mtd/spi-nor/core.c    Boris Brezillon      2020-03-13  2257  
3ddc8adbbc7683 drivers/mtd/spi-nor/spi-nor.c Geert Uytterhoeven   2019-03-12  2258  	dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
3ddc8adbbc7683 drivers/mtd/spi-nor/spi-nor.c Geert Uytterhoeven   2019-03-12  2259  		SPI_NOR_MAX_ID_LEN, id);
b199489d37b21c drivers/mtd/spi-nor/spi-nor.c Huang Shijie         2014-02-24  2260  	return ERR_PTR(-ENODEV);
b199489d37b21c drivers/mtd/spi-nor/spi-nor.c Huang Shijie         2014-02-24  2261  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org



From dietmar.eggemann at arm.com  Tue Aug 31 01:54:39 2021
From: dietmar.eggemann at arm.com (Dietmar Eggemann)
Date: Tue, 31 Aug 2021 10:54:39 +0200
Subject: [PATCH V3 0/9] Add callback to register with energy model
In-Reply-To: <cover.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <3d5b823f-259a-8fc6-27ab-2a5d5df89844@arm.com>

On 12/08/2021 06:35, Viresh Kumar wrote:
> Many cpufreq drivers register with the energy model for each policy and
> do exactly the same thing. Follow the footsteps of thermal-cooling, to
> get it done from the cpufreq core itself.
> 
> Provide a new callback, which will be called, if present, by the cpufreq
> core at the right moment (more on that in the code's comment). Also
> provide a generic implementation that uses dev_pm_opp_of_register_em().
> 
> This also allows us to register with the EM at a later point of time,
> compared to ->init(), from where the EM core can access cpufreq policy
> directly using cpufreq_cpu_get() type of helpers and perform other work,
> like marking few frequencies inefficient, this will be done separately.
> 
> This is build/boot tested by the bot for a couple of boards.
> 
> https://gitlab.com/vireshk/pmko/-/pipelines/351965580
> 
> FWIW, I have queued up the series for linux-next to get more testing, but your
> reviews are welcome. Thanks.
> 
> V2->V3:
> - Drop the auto-register part from all logs, this isn't called auto registration
>   anymore.
> - Call register_em() only for new policies.
> - Update scmi driver to register with EM only when required.
> - Add Rby tags.

LGTM. Tested on TC2 (vexpress-spc), Juno-r0 (scpi-cpufreq and scmi).

Reviewed-by: Dietmar Eggemann <dietmar.eggemann at arm.com>




From frank-w at public-files.de  Tue Aug 31 01:59:56 2021
From: frank-w at public-files.de (Frank Wunderlich)
Date: Tue, 31 Aug 2021 10:59:56 +0200
Subject: [PATCH v4 1/2] arm: dts: mt7623: add musb device nodes
In-Reply-To: <16f980b95e1f32bb8eb32448f1615bafdc51b792.camel@mediatek.com>
References: <20210822041333.5264-1-mans0n@gorani.run>
 <20210830155903.13907-1-mans0n@gorani.run>
 <20210830155903.13907-2-mans0n@gorani.run>
 <16f980b95e1f32bb8eb32448f1615bafdc51b792.camel@mediatek.com>
Message-ID: <14C40B35-3607-49C6-970B-441F9093125A@public-files.de>

Am 31. August 2021 08:27:18 MESZ schrieb "Chunfeng Yun (???)" <Chunfeng.Yun at mediatek.com>:

>Is the dt-binding patch applied? 
>It's better to put it into this series due to the new
>compatible "mediatek,mt7623-musb" is used for the first time.
>
>Reviewed-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Hi,

I don't see [1] (ack from rob) in [2]/[3]

@sungbo: please leave dt-bindings patch in series.
You need no new version only for adding tags (acked,tested or reviewed).
Only for code-changes,but then add tags from previous versions.

Imho it is better to take my musb patch [4]
into the series as well to make depency cleaner

[1] https://patchwork.kernel.org/project/linux-mediatek/patch/20210808123840.176738-2-mans0n at gorani.run/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/log/?h=for-next
[3] https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/log/?h=for-next
[4] https://patchwork.kernel.org/project/linux-mediatek/patch/20210830145958.108605-1-linux at fw-web.de/
regards Frank


From zhiyong.tao at mediatek.com  Tue Aug 31 02:11:38 2021
From: zhiyong.tao at mediatek.com (zhiyong.tao)
Date: Tue, 31 Aug 2021 17:11:38 +0800
Subject: [PATCH v11 3/4] pinctrl: mediatek: mt8195: Add pm_ops
In-Reply-To: <CAGXv+5Gx74SxdB_-V3SZB1sQ3=bpUkbkkaHxAyFg9m+7k+HVkw@mail.gmail.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
 <20210830003603.31864-4-zhiyong.tao@mediatek.com>
 <CAGXv+5Gx74SxdB_-V3SZB1sQ3=bpUkbkkaHxAyFg9m+7k+HVkw@mail.gmail.com>
Message-ID: <1630401098.14536.2.camel@mhfsdcap03>

On Tue, 2021-08-31 at 15:53 +0800, Chen-Yu Tsai wrote:
> On Mon, Aug 30, 2021 at 8:37 AM Zhiyong Tao <zhiyong.tao at mediatek.com> wrote:
> >
> > Setting this up will configure wake from suspend properly,
> > and wake only for the interrupts that are setup in wake_mask,
> > not all interrupts.
> 
> This sounds like a fix. Please add a Fixes tag for this patch. This makes
> tracking things easier.
> 
> So,
> 
> Fixes: 6cf5e9ef362a ("pinctrl: add pinctrl driver on mt8195")
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> 
> Also this patch is unrelated to the rest. You should send it separately.
> This would also help the maintainer merge it directly.
> 

Hi Chen-Yu,

We will add Fixed tag for this patch and send it separately.

Thanks.

> > Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
> > ---
> >  drivers/pinctrl/mediatek/pinctrl-mt8195.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8195.c b/drivers/pinctrl/mediatek/pinctrl-mt8195.c
> > index a7500e18bb1d..892e79703f98 100644
> > --- a/drivers/pinctrl/mediatek/pinctrl-mt8195.c
> > +++ b/drivers/pinctrl/mediatek/pinctrl-mt8195.c
> > @@ -839,6 +839,7 @@ static struct platform_driver mt8195_pinctrl_driver = {
> >         .driver = {
> >                 .name = "mt8195-pinctrl",
> >                 .of_match_table = mt8195_pinctrl_of_match,
> > +               .pm = &mtk_paris_pinctrl_pm_ops,
> >         },
> >         .probe = mt8195_pinctrl_probe,
> >  };
> > --
> > 2.18.0
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek


From benjamin.gaignard at collabora.com  Tue Aug 31 02:48:58 2021
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue, 31 Aug 2021 11:48:58 +0200
Subject: [PATCH 0/2] media: HEVC: RPS clean up
Message-ID: <20210831094900.203283-1-benjamin.gaignard@collabora.com>

This series aims to clean up Reference Picture Set usage and flags.

Long term flag was named with RPS prefix while it is not used for RPS
but for mark long term references in DBP. Remane it and remove the two
other useless RPS flags.

Clarify documentation about RPS lists content and make sure that Hantro
driver use them correctly (i.e without look up in DBP).

Benjamin

Benjamin Gaignard (2):
  media: hevc: Remove RPS named flags
  media: hevc: Embedded indexes in RPS

 .../media/v4l/ext-ctrls-codec.rst             | 12 ++++-----
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 27 +++++--------------
 .../staging/media/sunxi/cedrus/cedrus_h265.c  |  2 +-
 include/media/hevc-ctrls.h                    |  4 +--
 4 files changed, 14 insertions(+), 31 deletions(-)

-- 
2.25.1



From benjamin.gaignard at collabora.com  Tue Aug 31 02:48:59 2021
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue, 31 Aug 2021 11:48:59 +0200
Subject: [PATCH 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
References: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
Message-ID: <20210831094900.203283-2-benjamin.gaignard@collabora.com>

Marking a picture as long-term reference is valid for DPB but not for RPS.
Change flag name to match with it description in HEVC spec chapiter
"8.3.2 Decoding process for reference picture set".
Remove the other unused RPS flags.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 6 ++----
 drivers/staging/media/hantro/hantro_g2_hevc_dec.c         | 2 +-
 drivers/staging/media/sunxi/cedrus/cedrus_h265.c          | 2 +-
 include/media/hevc-ctrls.h                                | 4 +---
 4 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index 3865acb9e0fd..eff33c511090 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -3138,10 +3138,8 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
 	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
     * - __u8
       - ``rps``
-      - The reference set for the reference frame
-        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
-        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
-        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+      - Long term flag for the reference frame
+        (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
     * - __u8
       - ``field_pic``
       - Whether the reference is a field picture or a frame.
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 9ea864ca5625..be46b3c28b17 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -503,7 +503,7 @@ static int set_ref(struct hantro_ctx *ctx)
 		compress_luma_addr = luma_addr + compress_luma_offset;
 		compress_chroma_addr = luma_addr + compress_chroma_offset;
 
-		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
 			dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
 
 		/*
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
index ef0311a16d01..6086cc35e8cc 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
@@ -169,7 +169,7 @@ static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
 		unsigned int index = list[i];
 		u8 value = list[i];
 
-		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
 			value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
 
 		/* Each SRAM word gathers up to 4 references. */
diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
index ef63bc205756..f587448ef495 100644
--- a/include/media/hevc-ctrls.h
+++ b/include/media/hevc-ctrls.h
@@ -127,9 +127,7 @@ struct v4l2_ctrl_hevc_pps {
 	__u64	flags;
 };
 
-#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE	0x01
-#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER	0x02
-#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR		0x03
+#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE	0x01
 
 #define V4L2_HEVC_DPB_ENTRIES_NUM_MAX		16
 
-- 
2.25.1



From benjamin.gaignard at collabora.com  Tue Aug 31 02:49:00 2021
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue, 31 Aug 2021 11:49:00 +0200
Subject: [PATCH 2/2] media: hevc: Embedded indexes in RPS
In-Reply-To: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
References: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
Message-ID: <20210831094900.203283-3-benjamin.gaignard@collabora.com>

Reference Picture Set lists provide indexes of short and long term
reference in DBP array.
Fix Hantro to not do a look up in DBP entries.
Make documentation more clear about it.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 .../media/v4l/ext-ctrls-codec.rst             |  6 ++---
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 25 +++++--------------
 2 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index eff33c511090..4e4892c37723 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -3352,15 +3352,15 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
     * - __u8
       - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the short term before references in DPB array.
     * - __u8
       - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the short term after references in DPB array.
     * - __u8
       - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocLtCurr as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the long term references in DPB array.
     * - __u64
       - ``flags``
       - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index be46b3c28b17..76386e9eb8f4 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -306,24 +306,11 @@ static void set_params(struct hantro_ctx *ctx)
 	hantro_reg_write(vpu, &g2_apf_threshold, 8);
 }
 
-static int find_ref_pic_index(const struct v4l2_hevc_dpb_entry *dpb, int pic_order_cnt)
-{
-	int i;
-
-	for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
-		if (dpb[i].pic_order_cnt[0] == pic_order_cnt)
-			return i;
-	}
-
-	return 0x0;
-}
-
 static void set_ref_pic_list(struct hantro_ctx *ctx)
 {
 	const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
 	struct hantro_dev *vpu = ctx->dev;
 	const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
-	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
 	u32 list0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
 	u32 list1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
 	static const struct hantro_reg ref_pic_regs0[] = {
@@ -367,11 +354,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
 	/* List 0 contains: short term before, short term after and long term */
 	j = 0;
 	for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
+		list0[j++] = decode_params->poc_st_curr_before[i];
 	for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
+		list0[j++] = decode_params->poc_st_curr_after[i];
 	for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
+		list0[j++] = decode_params->poc_lt_curr[i];
 
 	/* Fill the list, copying over and over */
 	i = 0;
@@ -380,11 +367,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
 
 	j = 0;
 	for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
+		list1[j++] = decode_params->poc_st_curr_after[i];
 	for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
+		list1[j++] = decode_params->poc_st_curr_before[i];
 	for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
+		list1[j++] = decode_params->poc_lt_curr[i];
 
 	i = 0;
 	while (j < ARRAY_SIZE(list1))
-- 
2.25.1



From digetx at gmail.com  Tue Aug 31 02:51:28 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Tue, 31 Aug 2021 12:51:28 +0300
Subject: [PATCH v2] ARM: kasan: Fix __get_user_check failure with kasan
In-Reply-To: <20210828022552.45221-1-shaolexi@huawei.com>
References: <20210827125601.GT22278@shell.armlinux.org.uk>
 <20210828022552.45221-1-shaolexi@huawei.com>
Message-ID: <0ae31960-826b-686a-3b1a-985725545209@gmail.com>

28.08.2021 05:25, Lexi Shao ?????:
> In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
> error code is store in register int __e(r0). When kasan is
> enabled, assigning value to kernel address might trigger kasan check,
> which unexpectedly overwrites r0 and causes undefined behavior on arm
> kasan images.
> 
> One example is failure in do_futex and results in process soft lockup.
> Log:
> watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
> Q:Reg:1151]
> ...
> (__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
> (futex_wait_setup) from (futex_wait+0x138/0x394)
> (futex_wait) from (do_futex+0x164/0xe40)
> (do_futex) from (sys_futex_time32+0x178/0x230)
> (sys_futex_time32) from (ret_fast_syscall+0x0/0x50)
> 
> The soft lockup happens in function futex_wait_setup. The reason is
> function get_futex_value_locked always return EINVAL, thus pc jump
> back to retry label and causes looping.
> 
> This line in function get_futex_value_locked
> 	ret = __get_user(*dest, from);
> is expanded to
> 	*dest = (typeof(*(p))) __r2; ,
> in macro __get_user_check. Writing to pointer dest triggers kasan check
> and overwrites the return value of __get_user_x function.
> The assembly code of get_futex_value_locked in kernel/futex.c:
> ...
> c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
> // "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
> c01f6dcc:       e1a00007        mov     r0, r7
> c01f6dd0:       e1a05002        mov     r5, r2
> c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
> c01f6dd8:       e5875000        str     r5, [r7]
> // save ret value of __get_user(*dest, from), which is dest address now
> c01f6ddc:       e1a05000        mov     r5, r0
> ...
> // checking return value of __get_user failed
> c01f6e00:       e3550000        cmp     r5, #0
> ...
> c01f6e0c:       01a00005        moveq   r0, r5
> // assign return value to EINVAL
> c01f6e10:       13e0000d        mvnne   r0, #13
> 
> Return value is the destination address of get_user thus certainly
> non-zero, so get_futex_value_locked always return EINVAL.
> 
> Fix it by using a tmp vairable to store the error code before the
> assignment. This fix has no effects to non-kasan images thanks to compiler
> optimization. It only affects cases that overwrite r0 due to kasan check.
> 
> This should fix bug discussed in link:
> [1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c at gmail.com/
> 
> Fixes: 421015713b30 ("ARM: 9017/2: Enable KASan for ARM")
> Signed-off-by: Lexi Shao <shaolexi at huawei.com>
> ---
>  arch/arm/include/asm/uaccess.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
> index a13d90206472..d9db752c51fe 100644
> --- a/arch/arm/include/asm/uaccess.h
> +++ b/arch/arm/include/asm/uaccess.h
> @@ -200,6 +200,7 @@ extern int __get_user_64t_4(void *);
>  		register unsigned long __l asm("r1") = __limit;		\
>  		register int __e asm("r0");				\
>  		unsigned int __ua_flags = uaccess_save_and_enable();	\
> +		int __tmp_e;						\
>  		switch (sizeof(*(__p))) {				\
>  		case 1:							\
>  			if (sizeof((x)) >= 8)				\
> @@ -227,9 +228,10 @@ extern int __get_user_64t_4(void *);
>  			break;						\
>  		default: __e = __get_user_bad(); break;			\
>  		}							\
> +		__tmp_e = __e;						\
>  		uaccess_restore(__ua_flags);				\
>  		x = (typeof(*(p))) __r2;				\
> -		__e;							\
> +		__tmp_e;						\
>  	})
>  
>  #define get_user(x, p)							\
> 

Tested-by: Dmitry Osipenko <digetx at gmail.com> # Tegra


From ulf.hansson at linaro.org  Tue Aug 31 03:21:25 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 31 Aug 2021 12:21:25 +0200
Subject: [PATCH 1/2] of: property: fw_devlink: Rename 'node_not_dev' to
 'optional_con_dev'
Message-ID: <20210831102125.624661-1-ulf.hansson@linaro.org>

In the struct supplier_bindings the member 'node_not_dev' is described as
"The consumer node containing the property is never a device.", but that
doesn't match the behaviour of the code in of_link_property().

To make the behaviour consistent with the description, let's rename the
member to "optional_con_dev" and clarify the corresponding comment.

Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
---
 drivers/of/property.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/of/property.c b/drivers/of/property.c
index 6c028632f425..2babb1807228 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1249,7 +1249,8 @@ static struct device_node *parse_##fname(struct device_node *np,	     \
  * @parse_prop.index: For properties holding a list of phandles, this is the
  *		      index into the list
  * @optional: Describes whether a supplier is mandatory or not
- * @node_not_dev: The consumer node containing the property is never a device.
+ * @optional_con_dev: The consumer node containing the property may not be a
+ *		      device, then try finding one from an ancestor node.
  *
  * Returns:
  * parse_prop() return values are
@@ -1261,7 +1262,7 @@ struct supplier_bindings {
 	struct device_node *(*parse_prop)(struct device_node *np,
 					  const char *prop_name, int index);
 	bool optional;
-	bool node_not_dev;
+	bool optional_con_dev;
 };
 
 DEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells")
@@ -1370,7 +1371,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
 	{ .parse_prop = parse_pinctrl6, },
 	{ .parse_prop = parse_pinctrl7, },
 	{ .parse_prop = parse_pinctrl8, },
-	{ .parse_prop = parse_remote_endpoint, .node_not_dev = true, },
+	{ .parse_prop = parse_remote_endpoint, .optional_con_dev = true, },
 	{ .parse_prop = parse_gpio_compat, },
 	{ .parse_prop = parse_interrupts, },
 	{ .parse_prop = parse_regulators, },
@@ -1415,7 +1416,7 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
 		while ((phandle = s->parse_prop(con_np, prop_name, i))) {
 			struct device_node *con_dev_np;
 
-			con_dev_np = s->node_not_dev
+			con_dev_np = s->optional_con_dev
 					? of_get_compat_node(con_np)
 					: of_node_get(con_np);
 			matched = true;
-- 
2.25.1



From ulf.hansson at linaro.org  Tue Aug 31 03:21:41 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 31 Aug 2021 12:21:41 +0200
Subject: [PATCH 2/2] of: property: fw_devlink: Set 'optional_con_dev' for
 parse_power_domains
Message-ID: <20210831102141.624725-1-ulf.hansson@linaro.org>

The power-domain DT bindings [1] doesn't enforce a compatible string for a
provider node, even if this is common to use. In particular, when
describing a hierarchy with parent/child power-domains, as the psci DT
bindings [2] for example, it's sometimes not applicable to use a compatible
string.

Therefore, let's set the 'optional_con_dev' to true to avoid creating
incorrect fw_devlinks for power-domains.

[1] Documentation/devicetree/bindings/power/power-domain.yaml
[2] Documentation/devicetree/bindings/arm/psci.yaml

Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
---

Some more details of what goes on here. I have added a debug print in
of_link_to_phandle() to see the fw_devlinks that gets created.

This is what happens on Dragonboard 410c when 'optional_con_dev' isn't set:
...
[    0.041274] device: 'psci': device_add
[    0.041366] OF: Linking power-domain-cpu0 (consumer) to psci (supplier)
[    0.041395] OF: Linking power-domain-cpu1 (consumer) to psci (supplier)
[    0.041423] OF: Linking power-domain-cpu2 (consumer) to psci (supplier)
[    0.041451] OF: Linking power-domain-cpu3 (consumer) to psci (supplier)
[    0.041494] device: 'platform:psci--platform:psci': device_add
[    0.041556] platform psci: Linked as a sync state only consumer to psci
...

This is what happens on Dragonboard 410c when 'optional_con_dev' is set:
...
[    0.041179] device: 'psci': device_add
[    0.041265] OF: Not linking psci to psci - is descendant
[    0.041293] OF: Not linking psci to psci - is descendant
[    0.041319] OF: Not linking psci to psci - is descendant
[    0.041346] OF: Not linking psci to psci - is descendant
...

The relevant dtsi file:
arch/arm64/boot/dts/qcom/msm8916.dtsi

Kind regards
Ulf Hansson

---
 drivers/of/property.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/property.c b/drivers/of/property.c
index 2babb1807228..4d607fdbea24 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1356,7 +1356,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
 	{ .parse_prop = parse_io_channels, },
 	{ .parse_prop = parse_interrupt_parent, },
 	{ .parse_prop = parse_dmas, .optional = true, },
-	{ .parse_prop = parse_power_domains, },
+	{ .parse_prop = parse_power_domains, .optional_con_dev = true, },
 	{ .parse_prop = parse_hwlocks, },
 	{ .parse_prop = parse_extcon, },
 	{ .parse_prop = parse_nvmem_cells, },
-- 
2.25.1



From kavyasree.kotagiri at microchip.com  Tue Aug 31 03:21:38 2021
From: kavyasree.kotagiri at microchip.com (kavyasree.kotagiri at microchip.com)
Date: Tue, 31 Aug 2021 15:51:38 +0530
Subject: [PATCH v2] ARM: at91: add basic support for new SoC lan966x
Message-ID: <20210831102138.2476-1-kavyasree.kotagiri@microchip.com>

From: Kavyasree Kotagiri <Kavyasree.Kotagiri at microchip.com>

This patch introduces Microchip LAN966X ARMv7 based SoC family
of multiport gigabit AVB/TSN-capable ethernet switches.
It supports two SKUs: 4-port LAN9662 with multiprotocol
processing support and 8-port LAN9668 switch.

LAN966X includes copper and serial ethernet interfaces,
peripheral interfaces such as PCIe, USB, TWI, SPI, UART, QSPI,
SD/eMMC, Parallel Interface (PI) as well as synchronization
and trigger inputs/outputs.

Signed-off-by: Kavya Sree Kotagiri <kavyasree.kotagiri at microchip.com>
---
v1 -> v2:
- Removed lan966x_dt_device_init().
  System boots fine without this function.

 arch/arm/mach-at91/Kconfig   | 13 +++++++++++++
 arch/arm/mach-at91/Makefile  |  1 +
 arch/arm/mach-at91/lan966x.c | 25 +++++++++++++++++++++++++
 3 files changed, 39 insertions(+)
 create mode 100644 arch/arm/mach-at91/lan966x.c

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index ccd7e80ce943..06cb425af761 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -122,6 +122,14 @@ config SOC_SAM9X60
 	help
 	  Select this if you are using Microchip's SAM9X60 SoC
 
+config SOC_LAN966X
+	bool "ARMv7 based Microchip LAN966X SoC family"
+	depends on ARCH_MULTI_V7
+	select SOC_LAN966
+	select DW_APB_TIMER_OF
+	help
+	  This enables support for ARMv7 based Microchip LAN966X SoC family.
+
 comment "Clocksource driver selection"
 
 config ATMEL_CLOCKSOURCE_PIT
@@ -188,6 +196,11 @@ config SOC_SAMA5
 	select SOC_SAM_V7
 	select SRAM if PM
 
+config SOC_LAN966
+	bool
+	select ARM_GIC
+	select MEMORY
+
 config ATMEL_PM
 	bool
 
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index f565490f1b70..93cfd5b4e6d4 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -6,6 +6,7 @@
 # CPU-specific support
 obj-$(CONFIG_SOC_AT91RM9200)	+= at91rm9200.o
 obj-$(CONFIG_SOC_AT91SAM9)	+= at91sam9.o
+obj-$(CONFIG_SOC_LAN966X)	+= lan966x.o
 obj-$(CONFIG_SOC_SAM9X60)	+= sam9x60.o
 obj-$(CONFIG_SOC_SAMA5)		+= sama5.o
 obj-$(CONFIG_SOC_SAMV7)		+= samv7.o
diff --git a/arch/arm/mach-at91/lan966x.c b/arch/arm/mach-at91/lan966x.c
new file mode 100644
index 000000000000..154d616569ae
--- /dev/null
+++ b/arch/arm/mach-at91/lan966x.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Setup code for LAN966X
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ *
+ */
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/system_misc.h>
+
+#include "generic.h"
+
+static const char *const lan966x_dt_board_compat[] __initconst = {
+	"microchip,lan966x",
+	NULL
+};
+
+DT_MACHINE_START(lan966x_dt, "Microchip LAN966X")
+	/* Maintainer: Microchip */
+	.dt_compat	= lan966x_dt_board_compat,
+MACHINE_END
-- 
2.17.1



From Yong.Wu at mediatek.com  Tue Aug 31 03:45:02 2021
From: Yong.Wu at mediatek.com (=?utf-8?B?WW9uZyBXdSAo5ZC05YuHKQ==?=)
Date: Tue, 31 Aug 2021 10:45:02 +0000
Subject: [PATCH v7 00/12] Clean up "mediatek,larb"
In-Reply-To: <20210730025238.22456-1-yong.wu@mediatek.com>
References: <20210730025238.22456-1-yong.wu@mediatek.com>
Message-ID: <271b63107031f6bfa1b746e70ccdcee6d86db8b7.camel@mediatek.com>

Hi Matthias,

Just ping for this patchset.

Thanks.

On Fri, 2021-07-30 at 10:52 +0800, Yong Wu wrote:
> MediaTek IOMMU block diagram always like below:
> 
>         M4U
>          |
>     smi-common
>          |
>   -------------
>   |         |  ...
>   |         |
> larb1     larb2
>   |         |
> vdec       venc
> 
> All the consumer connect with smi-larb, then connect with smi-common.
> 
> When the consumer works, it should enable the smi-larb's power which
> also
> need enable the smi-common's power firstly.
> 
> Thus, Firstly, use the device link connect the consumer and the
> smi-larbs. then add device link between the smi-larb and smi-common.
> 
> After adding the device_link, then "mediatek,larb" property can be
> removed.
> the iommu consumer don't need call the mtk_smi_larb_get/put to enable
> the power and clock of smi-larb and smi-common.
> 
> Base on v5.14-rc1, and a jpeg[1] and mdp[2] patchset.
> 
> [1] 
> https://lore.kernel.org/linux-mediatek/20210702102304.3346429-1-hsinyi at chromium.org/
> [2] 
> https://lore.kernel.org/linux-mediatek/20210709022324.1607884-1-eizan at chromium.org/
> 
> Change notes:
> v7: 1) Fix a arm32 boot fail issue. reported from Frank.
>     2) Add a return fail in the mtk drm. suggested by Dafna.


From mans0n at gorani.run  Tue Aug 31 04:02:10 2021
From: mans0n at gorani.run (Sungbo Eo)
Date: Tue, 31 Aug 2021 20:02:10 +0900
Subject: [PATCH v4 1/2] arm: dts: mt7623: add musb device nodes
In-Reply-To: <14C40B35-3607-49C6-970B-441F9093125A@public-files.de>
References: <20210822041333.5264-1-mans0n@gorani.run>
 <20210830155903.13907-1-mans0n@gorani.run>
 <20210830155903.13907-2-mans0n@gorani.run>
 <16f980b95e1f32bb8eb32448f1615bafdc51b792.camel@mediatek.com>
 <14C40B35-3607-49C6-970B-441F9093125A@public-files.de>
Message-ID: <3d57ae38-9d8f-05e3-c5b3-58db73879f16@gorani.run>

On 2021-08-31 17:59, Frank Wunderlich wrote:
> Am 31. August 2021 08:27:18 MESZ schrieb "Chunfeng Yun (???)" <Chunfeng.Yun at mediatek.com>:
> 
>> Is the dt-binding patch applied? 
>> It's better to put it into this series due to the new
>> compatible "mediatek,mt7623-musb" is used for the first time.
>>
>> Reviewed-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> 
> Hi,
> 
> I don't see [1] (ack from rob) in [2]/[3]

You can find it here.
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git/log/?h=usb-next

> 
> @sungbo: please leave dt-bindings patch in series.

I'll keep it for a while, then.

> You need no new version only for adding tags (acked,tested or reviewed).
> Only for code-changes,but then add tags from previous versions.

Got it. Thanks for the tip. :)

> 
> Imho it is better to take my musb patch [4]
> into the series as well to make depency cleaner

Okay, I'll take it in the next version.

Thanks.

> 
> [1] https://patchwork.kernel.org/project/linux-mediatek/patch/20210808123840.176738-2-mans0n at gorani.run/
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/log/?h=for-next
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/log/?h=for-next
> [4] https://patchwork.kernel.org/project/linux-mediatek/patch/20210830145958.108605-1-linux at fw-web.de/
> regards Frank
> 


From jc at kynesim.co.uk  Tue Aug 31 04:08:06 2021
From: jc at kynesim.co.uk (John Cox)
Date: Tue, 31 Aug 2021 12:08:06 +0100
Subject: [PATCH 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <20210831094900.203283-2-benjamin.gaignard@collabora.com>
References: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
 <20210831094900.203283-2-benjamin.gaignard@collabora.com>
Message-ID: <4g2sigpsttf80t72c7spdqqjvvijnths2d@4ax.com>

>Marking a picture as long-term reference is valid for DPB but not for RPS.
>Change flag name to match with it description in HEVC spec chapiter
>"8.3.2 Decoding process for reference picture set".
>Remove the other unused RPS flags.
>
>Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
>---
> Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 6 ++----
> drivers/staging/media/hantro/hantro_g2_hevc_dec.c         | 2 +-
> drivers/staging/media/sunxi/cedrus/cedrus_h265.c          | 2 +-
> include/media/hevc-ctrls.h                                | 4 +---
> 4 files changed, 5 insertions(+), 9 deletions(-)
>
>diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>index 3865acb9e0fd..eff33c511090 100644
>--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>@@ -3138,10 +3138,8 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
> 	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
>     * - __u8
>       - ``rps``
>-      - The reference set for the reference frame
>-        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
>-        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
>-        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>+      - Long term flag for the reference frame
>+        (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
>     * - __u8
>       - ``field_pic``
>       - Whether the reference is a field picture or a frame.

If you are going to remove all the RPS values except for Long Term
wouldn't it be better to rename the field too, either to "flags" or a
bool "is_long_term"?  If we have a field called RPS it really should be
able to have a value for any of the 5 valid Reference Picture Sets that
a DPB entry can belong to.

As a side note, it is important to my code that the DPB array contains
all the DPB entries not just the ones that are in use in this frame.  I
need them so I can track which frames have left the DPB so I can
reuse/free the MV tables associated with them (yes I could keep one for
every entry in the capture Q but that is generally wasteful on memory
and the Pi is often memory constrained). So maybe update the docn on DPB
to make this explicit please? (I suspect that current code does this
anyway as it is generally easier to do than to not.)

John Cox

>diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>index 9ea864ca5625..be46b3c28b17 100644
>--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>@@ -503,7 +503,7 @@ static int set_ref(struct hantro_ctx *ctx)
> 		compress_luma_addr = luma_addr + compress_luma_offset;
> 		compress_chroma_addr = luma_addr + compress_chroma_offset;
> 
>-		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>+		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
> 			dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
> 
> 		/*
>diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>index ef0311a16d01..6086cc35e8cc 100644
>--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>@@ -169,7 +169,7 @@ static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
> 		unsigned int index = list[i];
> 		u8 value = list[i];
> 
>-		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>+		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
> 			value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
> 
> 		/* Each SRAM word gathers up to 4 references. */
>diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
>index ef63bc205756..f587448ef495 100644
>--- a/include/media/hevc-ctrls.h
>+++ b/include/media/hevc-ctrls.h
>@@ -127,9 +127,7 @@ struct v4l2_ctrl_hevc_pps {
> 	__u64	flags;
> };
> 
>-#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE	0x01
>-#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER	0x02
>-#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR		0x03
>+#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE	0x01
> 
> #define V4L2_HEVC_DPB_ENTRIES_NUM_MAX		16
> 


From frank-w at public-files.de  Tue Aug 31 04:08:17 2021
From: frank-w at public-files.de (Frank Wunderlich)
Date: Tue, 31 Aug 2021 13:08:17 +0200
Subject: Aw: Re: [PATCH v4 1/2] arm: dts: mt7623: add musb device nodes
In-Reply-To: <3d57ae38-9d8f-05e3-c5b3-58db73879f16@gorani.run>
References: <20210822041333.5264-1-mans0n@gorani.run>
 <20210830155903.13907-1-mans0n@gorani.run>
 <20210830155903.13907-2-mans0n@gorani.run>
 <16f980b95e1f32bb8eb32448f1615bafdc51b792.camel@mediatek.com>
 <14C40B35-3607-49C6-970B-441F9093125A@public-files.de>
 <3d57ae38-9d8f-05e3-c5b3-58db73879f16@gorani.run>
Message-ID: <trinity-2f57e648-cb42-4116-b3d0-6fcdbaae81b6-1630408097512@3c-app-gmx-bap45>

> Gesendet: Dienstag, 31. August 2021 um 13:02 Uhr
> Von: "Sungbo Eo" <mans0n at gorani.run>
> On 2021-08-31 17:59, Frank Wunderlich wrote:
> > Am 31. August 2021 08:27:18 MESZ schrieb "Chunfeng Yun (???)" <Chunfeng.Yun at mediatek.com>:

> > I don't see [1] (ack from rob) in [2]/[3]
> 
> You can find it here.
> https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git/log/?h=usb-next
> 
> > 
> > @sungbo: please leave dt-bindings patch in series.
> 
> I'll keep it for a while, then.

ok, then it is not needed again...have not searched in usb-tree.

> > You need no new version only for adding tags (acked,tested or reviewed).
> > Only for code-changes,but then add tags from previous versions.
> 
> Got it. Thanks for the tip. :)
> 
> > Imho it is better to take my musb patch [4]
> > into the series as well to make depency cleaner
> 
> Okay, I'll take it in the next version.

okay, if dt-bindings is already in usb-tree wait what maintainers (matthias/rob) says about adding my patch to a new version of your series or if this is clear now :)

> > [1] https://patchwork.kernel.org/project/linux-mediatek/patch/20210808123840.176738-2-mans0n at gorani.run/
> > [2] https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/log/?h=for-next
> > [3] https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/log/?h=for-next
> > [4] https://patchwork.kernel.org/project/linux-mediatek/patch/20210830145958.108605-1-linux at fw-web.de/
> > regards Frank
> > 
>


From digetx at gmail.com  Tue Aug 31 04:38:39 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Tue, 31 Aug 2021 14:38:39 +0300
Subject: [PATCH 2/2] of: property: fw_devlink: Set 'optional_con_dev' for
 parse_power_domains
In-Reply-To: <20210831102141.624725-1-ulf.hansson@linaro.org>
References: <20210831102141.624725-1-ulf.hansson@linaro.org>
Message-ID: <d6cbbaf7-03a1-34d7-afe3-823cd627c799@gmail.com>

31.08.2021 13:21, Ulf Hansson ?????:
> The power-domain DT bindings [1] doesn't enforce a compatible string for a
> provider node, even if this is common to use. In particular, when
> describing a hierarchy with parent/child power-domains, as the psci DT
> bindings [2] for example, it's sometimes not applicable to use a compatible
> string.
> 
> Therefore, let's set the 'optional_con_dev' to true to avoid creating
> incorrect fw_devlinks for power-domains.
> 
> [1] Documentation/devicetree/bindings/power/power-domain.yaml
> [2] Documentation/devicetree/bindings/arm/psci.yaml
> 
> Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
> ---
> 
> Some more details of what goes on here. I have added a debug print in
> of_link_to_phandle() to see the fw_devlinks that gets created.
> 
> This is what happens on Dragonboard 410c when 'optional_con_dev' isn't set:
> ...
> [    0.041274] device: 'psci': device_add
> [    0.041366] OF: Linking power-domain-cpu0 (consumer) to psci (supplier)
> [    0.041395] OF: Linking power-domain-cpu1 (consumer) to psci (supplier)
> [    0.041423] OF: Linking power-domain-cpu2 (consumer) to psci (supplier)
> [    0.041451] OF: Linking power-domain-cpu3 (consumer) to psci (supplier)
> [    0.041494] device: 'platform:psci--platform:psci': device_add
> [    0.041556] platform psci: Linked as a sync state only consumer to psci
> ...
> 
> This is what happens on Dragonboard 410c when 'optional_con_dev' is set:
> ...
> [    0.041179] device: 'psci': device_add
> [    0.041265] OF: Not linking psci to psci - is descendant
> [    0.041293] OF: Not linking psci to psci - is descendant
> [    0.041319] OF: Not linking psci to psci - is descendant
> [    0.041346] OF: Not linking psci to psci - is descendant
> ...
> 
> The relevant dtsi file:
> arch/arm64/boot/dts/qcom/msm8916.dtsi
> 
> Kind regards
> Ulf Hansson
> 
> ---
>  drivers/of/property.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/of/property.c b/drivers/of/property.c
> index 2babb1807228..4d607fdbea24 100644
> --- a/drivers/of/property.c
> +++ b/drivers/of/property.c
> @@ -1356,7 +1356,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
>  	{ .parse_prop = parse_io_channels, },
>  	{ .parse_prop = parse_interrupt_parent, },
>  	{ .parse_prop = parse_dmas, .optional = true, },
> -	{ .parse_prop = parse_power_domains, },
> +	{ .parse_prop = parse_power_domains, .optional_con_dev = true, },
>  	{ .parse_prop = parse_hwlocks, },
>  	{ .parse_prop = parse_extcon, },
>  	{ .parse_prop = parse_nvmem_cells, },
> 

State syncing keeps working with this patch as before on Tegra.


From Eugen.Hristev at microchip.com  Tue Aug 31 04:50:00 2021
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Tue, 31 Aug 2021 11:50:00 +0000
Subject: [PATCH v2 04/10] iio: adc: at91-sama5d2_adc: convert to platform
 specific data structures
In-Reply-To: <20210830154408.4ffdef1a@jic23-huawei>
References: <20210824115441.681253-1-eugen.hristev@microchip.com>
 <20210824115441.681253-5-eugen.hristev@microchip.com>
 <1688eb0e-5ea1-3bcc-3af0-7ba4c4601306@microchip.com>
 <20210830154408.4ffdef1a@jic23-huawei>
Message-ID: <6178f8b2-60d0-7189-2e0a-ae1c12419330@microchip.com>

On 8/30/21 5:44 PM, Jonathan Cameron wrote:
> On Mon, 30 Aug 2021 12:31:46 +0000
> <Eugen.Hristev at microchip.com> wrote:
> 
>> On 8/24/21 2:54 PM, Eugen Hristev wrote:
>>> Convert the driver to platform specific structures. This means:
>>> - create a register layout struct that will hold offsets for registers
>>> - create a platform struct that will hold platform information (number of
>>> channels, indexes for different channels and pointer to layout struct)
>>> - convert specific macros that are platform dependent into platform variables
>>>
>>> This step is in fact a no-op, but allows the driver to be more flexible
>>> and for future enhancement including adding new platforms that are partly
>>> compatible with the current driver and differ slightly in register layout
>>> or capabilities for example.
>>>
>>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>>> ---
>>>    drivers/iio/adc/at91-sama5d2_adc.c | 410 +++++++++++++++++------------
>>>    1 file changed, 247 insertions(+), 163 deletions(-)
>>>
>>> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
>>> index 9d71dcffcf93..8ede18b8d789 100644
>>> --- a/drivers/iio/adc/at91-sama5d2_adc.c
>>> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
>>> @@ -27,8 +27,9 @@
>>>    #include <linux/pinctrl/consumer.h>
>>>    #include <linux/regulator/consumer.h>
>>>
>>> +struct at91_adc_reg_layout {
>>>    /* Control Register */
>>> -#define AT91_SAMA5D2_CR            0x00
>>> +   u16                             CR;
>>>    /* Software Reset */
>>>    #define   AT91_SAMA5D2_CR_SWRST           BIT(0)
>>>    /* Start Conversion */
>>> @@ -39,7 +40,7 @@
>>>    #define   AT91_SAMA5D2_CR_CMPRST          BIT(4)
>>>
>>>    /* Mode Register */
>>> -#define AT91_SAMA5D2_MR            0x04
>>> +   u16                             MR;
>>>    /* Trigger Selection */
>>>    #define   AT91_SAMA5D2_MR_TRGSEL(v)       ((v) << 1)
>>>    /* ADTRG */
>>> @@ -82,19 +83,19 @@
>>>    #define   AT91_SAMA5D2_MR_USEQ            BIT(31)
>>>
>>>    /* Channel Sequence Register 1 */
>>> -#define AT91_SAMA5D2_SEQR1 0x08
>>> +   u16                             SEQR1;
>>>    /* Channel Sequence Register 2 */
>>> -#define AT91_SAMA5D2_SEQR2 0x0c
>>> +   u16                             SEQR2;
>>>    /* Channel Enable Register */
>>> -#define AT91_SAMA5D2_CHER  0x10
>>> +   u16                             CHER;
>>>    /* Channel Disable Register */
>>> -#define AT91_SAMA5D2_CHDR  0x14
>>> +   u16                             CHDR;
>>>    /* Channel Status Register */
>>> -#define AT91_SAMA5D2_CHSR  0x18
>>> +   u16                             CHSR;
>>>    /* Last Converted Data Register */
>>> -#define AT91_SAMA5D2_LCDR  0x20
>>> +   u16                             LCDR;
>>>    /* Interrupt Enable Register */
>>> -#define AT91_SAMA5D2_IER   0x24
>>> +   u16                             IER;
>>>    /* Interrupt Enable Register - TS X measurement ready */
>>>    #define AT91_SAMA5D2_IER_XRDY   BIT(20)
>>>    /* Interrupt Enable Register - TS Y measurement ready */
>>> @@ -109,22 +110,23 @@
>>>    #define AT91_SAMA5D2_IER_PEN    BIT(29)
>>>    /* Interrupt Enable Register - No pen detect */
>>>    #define AT91_SAMA5D2_IER_NOPEN  BIT(30)
>>> +
>>>    /* Interrupt Disable Register */
>>> -#define AT91_SAMA5D2_IDR   0x28
>>> +   u16                             IDR;
>>>    /* Interrupt Mask Register */
>>> -#define AT91_SAMA5D2_IMR   0x2c
>>> +   u16                             IMR;
>>>    /* Interrupt Status Register */
>>> -#define AT91_SAMA5D2_ISR   0x30
>>> +   u16                             ISR;
>>>    /* Interrupt Status Register - Pen touching sense status */
>>>    #define AT91_SAMA5D2_ISR_PENS   BIT(31)
>>>    /* Last Channel Trigger Mode Register */
>>> -#define AT91_SAMA5D2_LCTMR 0x34
>>> +   u16                             LCTMR;
>>>    /* Last Channel Compare Window Register */
>>> -#define AT91_SAMA5D2_LCCWR 0x38
>>> +   u16                             LCCWR;
>>>    /* Overrun Status Register */
>>> -#define AT91_SAMA5D2_OVER  0x3c
>>> +   u16                             OVER;
>>>    /* Extended Mode Register */
>>> -#define AT91_SAMA5D2_EMR   0x40
>>> +   u16                             EMR;
>>>    /* Extended Mode Register - Oversampling rate */
>>>    #define AT91_SAMA5D2_EMR_OSR(V)                   ((V) << 16)
>>>    #define AT91_SAMA5D2_EMR_OSR_MASK         GENMASK(17, 16)
>>> @@ -134,22 +136,22 @@
>>>
>>>    /* Extended Mode Register - Averaging on single trigger event */
>>>    #define AT91_SAMA5D2_EMR_ASTE(V)          ((V) << 20)
>>> +
>>>    /* Compare Window Register */
>>> -#define AT91_SAMA5D2_CWR   0x44
>>> +   u16                             CWR;
>>>    /* Channel Gain Register */
>>> -#define AT91_SAMA5D2_CGR   0x48
>>> -
>>> +   u16                             CGR;
>>>    /* Channel Offset Register */
>>> -#define AT91_SAMA5D2_COR   0x4c
>>> +   u16                             COR;
>>>    #define AT91_SAMA5D2_COR_DIFF_OFFSET      16
>>>
>>>    /* Analog Control Register */
>>> -#define AT91_SAMA5D2_ACR   0x94
>>> +   u16                             ACR;
>>>    /* Analog Control Register - Pen detect sensitivity mask */
>>>    #define AT91_SAMA5D2_ACR_PENDETSENS_MASK        GENMASK(1, 0)
>>>
>>>    /* Touchscreen Mode Register */
>>> -#define AT91_SAMA5D2_TSMR  0xb0
>>> +   u16                             TSMR;
>>>    /* Touchscreen Mode Register - No touch mode */
>>>    #define AT91_SAMA5D2_TSMR_TSMODE_NONE           0
>>>    /* Touchscreen Mode Register - 4 wire screen, no pressure measurement */
>>> @@ -178,13 +180,13 @@
>>>    #define AT91_SAMA5D2_TSMR_PENDET_ENA            BIT(24)
>>>
>>>    /* Touchscreen X Position Register */
>>> -#define AT91_SAMA5D2_XPOSR 0xb4
>>> +   u16                             XPOSR;
>>>    /* Touchscreen Y Position Register */
>>> -#define AT91_SAMA5D2_YPOSR 0xb8
>>> +   u16                             YPOSR;
>>>    /* Touchscreen Pressure Register */
>>> -#define AT91_SAMA5D2_PRESSR        0xbc
>>> +   u16                             PRESSR;
>>>    /* Trigger Register */
>>> -#define AT91_SAMA5D2_TRGR  0xc0
>>> +   u16                             TRGR;
>>>    /* Mask for TRGMOD field of TRGR register */
>>>    #define AT91_SAMA5D2_TRGR_TRGMOD_MASK GENMASK(2, 0)
>>>    /* No trigger, only software trigger can start conversions */
>>> @@ -203,30 +205,52 @@
>>>    #define AT91_SAMA5D2_TRGR_TRGPER(x)             ((x) << 16)
>>>
>>>    /* Correction Select Register */
>>> -#define AT91_SAMA5D2_COSR  0xd0
>>> +   u16                             COSR;
>>>    /* Correction Value Register */
>>> -#define AT91_SAMA5D2_CVR   0xd4
>>> +   u16                             CVR;
>>>    /* Channel Error Correction Register */
>>> -#define AT91_SAMA5D2_CECR  0xd8
>>> +   u16                             CECR;
>>>    /* Write Protection Mode Register */
>>> -#define AT91_SAMA5D2_WPMR  0xe4
>>> +   u16                             WPMR;
>>>    /* Write Protection Status Register */
>>> -#define AT91_SAMA5D2_WPSR  0xe8
>>> +   u16                             WPSR;
>>>    /* Version Register */
>>> -#define AT91_SAMA5D2_VERSION       0xfc
>>> -
>>> -#define AT91_SAMA5D2_HW_TRIG_CNT 3
>>> -#define AT91_SAMA5D2_SINGLE_CHAN_CNT 12
>>> -#define AT91_SAMA5D2_DIFF_CHAN_CNT 6
>>> -
>>> -#define AT91_SAMA5D2_TIMESTAMP_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT + 1)
>>> +   u16                             VERSION;
>>> +};
>>>
>>> -#define AT91_SAMA5D2_TOUCH_X_CHAN_IDX (AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT * 2)
>>
>> Hi Jonathan,
>>
>> While we are here, regarding the above line, I cannot tell why did I
>> multiply by two the differential channel count. This makes some gaps in
>> the number of channels when we put them all in the same table.
>>
>> I did not change this as it would break the ABI regarding the bindings
>> for the touchscreen #adc-cells phandle references.
> 
> Really?  Xlate is based off scan_index, not these values I think...

I figured it out.

We have 12 single channels [0..11] then 6 differential [12, 14, 16, 18, 
20, 22] spaced by two, a timestamp [23], then we have the X channel 
index at 24, Y at 25 and pressure are 26.

These are reflected in this file :

https://elixir.bootlin.com/linux/latest/source/include/dt-bindings/iio/adc/at91-sama5d2_adc.h

And the resistive touchscreen connects to the adc with these indexes.

And I realised why we have the padding/spaces.
It was the original design of the driver, in the line which I 
highlighted now below in the patch : (and I never changed this since 
working on this driver, because it was a break of the ABI in channel 
numbers ...)


> 
>>
>> However, I am thinking if there was a reason for it or it was a slip
>> when I initially wrote this.
> 
> I've no idea :)  I can't immediately see why we'd need the padding.
> 
>>
>> Do you think there is any reason to change it and tighten the holes in
>> the indexes list ?
> 
> I don't think it matters. As far as I can tell they are used mostly (possibly
> entirely) for internal management and not exposed to any of the ABIs etc.
> 
> Jonathan
> 
>>
>>
>> Eugen
>>
>>> -#define AT91_SAMA5D2_TOUCH_Y_CHAN_IDX   (AT91_SAMA5D2_TOUCH_X_CHAN_IDX + 1)
>>> -#define AT91_SAMA5D2_TOUCH_P_CHAN_IDX   (AT91_SAMA5D2_TOUCH_Y_CHAN_IDX + 1)
>>> -#define AT91_SAMA5D2_MAX_CHAN_IDX  AT91_SAMA5D2_TOUCH_P_CHAN_IDX
>>> +static const struct at91_adc_reg_layout sama5d2_layout = {
>>> +   .CR =                   0x00,
>>> +   .MR =                   0x04,
>>> +   .SEQR1 =                0x08,
>>> +   .SEQR2 =                0x0c,
>>> +   .CHER =                 0x10,
>>> +   .CHDR =                 0x14,
>>> +   .CHSR =                 0x18,
>>> +   .LCDR =                 0x20,
>>> +   .IER =                  0x24,
>>> +   .IDR =                  0x28,
>>> +   .IMR =                  0x2c,
>>> +   .ISR =                  0x30,
>>> +   .LCTMR =                0x34,
>>> +   .LCCWR =                0x38,
>>> +   .OVER =                 0x3c,
>>> +   .EMR =                  0x40,
>>> +   .CWR =                  0x44,
>>> +   .CGR =                  0x48,
>>> +   .COR =                  0x4c,
>>> +   .ACR =                  0x94,
>>> +   .TSMR =                 0xb0,
>>> +   .XPOSR =                0xb4,
>>> +   .YPOSR =                0xb8,
>>> +   .PRESSR =               0xbc,
>>> +   .TRGR =                 0xc0,
>>> +   .COSR =                 0xd0,
>>> +   .CVR =                  0xd4,
>>> +   .CECR =                 0xd8,
>>> +   .WPMR =                 0xe4,
>>> +   .WPSR =                 0xe8,
>>> +   .VERSION =              0xfc,
>>> +};
>>>
>>>    #define AT91_SAMA5D2_TOUCH_SAMPLE_PERIOD_US          2000    /* 2ms */
>>>    #define AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US    200
>>> @@ -235,18 +259,6 @@
>>>
>>>    #define AT91_SAMA5D2_MAX_POS_BITS                 12
>>>
>>> -/*
>>> - * Maximum number of bytes to hold conversion from all channels
>>> - * without the timestamp.
>>> - */
>>> -#define AT91_BUFFER_MAX_CONVERSION_BYTES ((AT91_SAMA5D2_SINGLE_CHAN_CNT + \
>>> -                                    AT91_SAMA5D2_DIFF_CHAN_CNT) * 2)
>>> -
>>> -/* This total must also include the timestamp */
>>> -#define AT91_BUFFER_MAX_BYTES (AT91_BUFFER_MAX_CONVERSION_BYTES + 8)
>>> -
>>> -#define AT91_BUFFER_MAX_HWORDS (AT91_BUFFER_MAX_BYTES / 2)
>>> -
>>>    #define AT91_HWFIFO_MAX_SIZE_STR  "128"
>>>    #define AT91_HWFIFO_MAX_SIZE              128
>>>
>>> @@ -255,12 +267,12 @@
>>>    #define AT91_OSR_4SAMPLES         4
>>>    #define AT91_OSR_16SAMPLES                16
>>>
>>> -#define AT91_SAMA5D2_CHAN_SINGLE(num, addr)                                \
>>> +#define AT91_SAMA5D2_CHAN_SINGLE(index, num, addr)                 \
>>>      {                                                               \
>>>              .type = IIO_VOLTAGE,                                    \
>>>              .channel = num,                                         \
>>>              .address = addr,                                        \
>>> -           .scan_index = num,                                      \
>>> +           .scan_index = index,                                    \
>>>              .scan_type = {                                          \
>>>                      .sign = 'u',                                    \
>>>                      .realbits = 14,                                 \
>>> @@ -274,14 +286,14 @@
>>>              .indexed = 1,                                           \
>>>      }
>>>
>>> -#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr)                            \
>>> +#define AT91_SAMA5D2_CHAN_DIFF(index, num, num2, addr)                     \
>>>      {                                                               \
>>>              .type = IIO_VOLTAGE,                                    \
>>>              .differential = 1,                                      \
>>>              .channel = num,                                         \
>>>              .channel2 = num2,                                       \
>>>              .address = addr,                                        \
>>> -           .scan_index = num + AT91_SAMA5D2_SINGLE_CHAN_CNT,       \

Here it is: we always added num to the single channel count, but num 
goes incrementally in steps of two : 0, 2, 4, 6, 8, 10

>>> +           .scan_index = index,                                    \
>>>              .scan_type = {                                          \
>>>                      .sign = 's',                                    \
>>>                      .realbits = 14,                                 \
>>> @@ -328,13 +340,48 @@
>>>              .datasheet_name = name,                                 \
>>>      }
>>>
>>> -#define at91_adc_readl(st, reg)            readl_relaxed(st->base + reg)
>>> -#define at91_adc_writel(st, reg, val)      writel_relaxed(val, st->base + reg)
>>> +#define at91_adc_readl(st, reg)                                            \
>>> +   readl_relaxed((st)->base + (st)->soc_info.platform->layout->reg)
>>> +#define at91_adc_read_chan(st, reg)                                        \
>>> +   readl_relaxed((st)->base + reg)
>>> +#define at91_adc_writel(st, reg, val)                                      \
>>> +   writel_relaxed(val, (st)->base + (st)->soc_info.platform->layout->reg)
>>> +
>>> +/**
>>> + * struct at91_adc_platform - at91-sama5d2 platform information struct
>>> + * @layout:                pointer to the reg layout struct
>>> + * @adc_channels:  pointer to an array of channels for registering in
>>> + *                 the iio subsystem
>>> + * @nr_channels:   number of physical channels available
>>> + * @touch_chan_x:  index of the touchscreen X channel
>>> + * @touch_chan_y:  index of the touchscreen Y channel
>>> + * @touch_chan_p:  index of the touchscreen P channel
>>> + * @max_channels:  number of total channels
>>> + * @hw_trig_cnt:   number of possible hardware triggers
>>> + */
>>> +struct at91_adc_platform {
>>> +   const struct at91_adc_reg_layout        *layout;
>>> +   const struct iio_chan_spec              (*adc_channels)[];
>>> +   unsigned int                            nr_channels;
>>> +   unsigned int                            touch_chan_x;
>>> +   unsigned int                            touch_chan_y;
>>> +   unsigned int                            touch_chan_p;
>>> +   unsigned int                            max_channels;
>>> +   unsigned int                            hw_trig_cnt;
>>> +};
>>>
>>> +/**
>>> + * struct at91_adc_soc_info - at91-sama5d2 soc information struct
>>> + * @startup_time:  device startup time
>>> + * @min_sample_rate:       minimum sample rate in Hz
>>> + * @max_sample_rate:       maximum sample rate in Hz
>>> + * @platform:              pointer to the platform structure
>>> + */
>>>    struct at91_adc_soc_info {
>>>      unsigned                        startup_time;
>>>      unsigned                        min_sample_rate;
>>>      unsigned                        max_sample_rate;
>>> +   const struct at91_adc_platform  *platform;
>>>    };
>>>
>>>    struct at91_adc_trigger {
>>> @@ -382,6 +429,15 @@ struct at91_adc_touch {
>>>      struct work_struct              workq;
>>>    };
>>>
>>> +/*
>>> + * Buffer size requirements:
>>> + * No channels * bytes_per_channel(2) + timestamp bytes (8)
>>> + * Divided by 2 because we need half words.
>>> + * We assume 32 channels for now, has to be increased if needed.
>>> + * Nobody minds a buffer being too big.
>>> + */
>>> +#define AT91_BUFFER_MAX_HWORDS ((32 * 2 + 8) / 2)
>>> +
>>>    struct at91_adc_state {
>>>      void __iomem                    *base;
>>>      int                             irq;
>>> @@ -437,29 +493,49 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
>>>      },
>>>    };
>>>
>>> -static const struct iio_chan_spec at91_adc_channels[] = {
>>> -   AT91_SAMA5D2_CHAN_SINGLE(0, 0x50),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(1, 0x54),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(2, 0x58),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(4, 0x60),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(5, 0x64),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(6, 0x68),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(8, 0x70),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(9, 0x74),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(10, 0x78),
>>> -   AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c),
>>> -   AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50),
>>> -   AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58),
>>> -   AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60),
>>> -   AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68),
>>> -   AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70),
>>> -   AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78),

you can see it here,

>>> -   IIO_CHAN_SOFT_TIMESTAMP(AT91_SAMA5D2_TIMESTAMP_CHAN_IDX),
>>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_X_CHAN_IDX, "x", IIO_MOD_X),
>>> -   AT91_SAMA5D2_CHAN_TOUCH(AT91_SAMA5D2_TOUCH_Y_CHAN_IDX, "y", IIO_MOD_Y),
>>> -   AT91_SAMA5D2_CHAN_PRESSURE(AT91_SAMA5D2_TOUCH_P_CHAN_IDX, "pressure"),
>>> +static const struct iio_chan_spec at91_sama5d2_adc_channels[] = {
>>> +   AT91_SAMA5D2_CHAN_SINGLE(0, 0, 0x50),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(1, 1, 0x54),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(2, 2, 0x58),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(3, 3, 0x5c),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(4, 4, 0x60),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(5, 5, 0x64),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(6, 6, 0x68),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(7, 7, 0x6c),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(8, 8, 0x70),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(9, 9, 0x74),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(10, 10, 0x78),
>>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
>>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
>>> +   AT91_SAMA5D2_CHAN_DIFF(13, 2, 3, 0x58),
>>> +   AT91_SAMA5D2_CHAN_DIFF(14, 4, 5, 0x60),
>>> +   AT91_SAMA5D2_CHAN_DIFF(15, 6, 7, 0x68),
>>> +   AT91_SAMA5D2_CHAN_DIFF(16, 8, 9, 0x70),
>>> +   AT91_SAMA5D2_CHAN_DIFF(17, 10, 11, 0x78),
>>> +   IIO_CHAN_SOFT_TIMESTAMP(18),
>>> +   AT91_SAMA5D2_CHAN_TOUCH(19, "x", IIO_MOD_X),
>>> +   AT91_SAMA5D2_CHAN_TOUCH(20, "y", IIO_MOD_Y),
>>> +   AT91_SAMA5D2_CHAN_PRESSURE(21, "pressure"),

And I have to come up with a new version of the patch to fix this.

It should be like this:


 >>> +   AT91_SAMA5D2_CHAN_SINGLE(11, 11, 0x7c),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(12, 0, 1, 0x50),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(14, 2, 3, 0x58),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(16, 4, 5, 0x60),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(18, 6, 7, 0x68),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(20, 8, 9, 0x70),
 >>> +   AT91_SAMA5D2_CHAN_DIFF(22, 10, 11, 0x78),
 >>> +   IIO_CHAN_SOFT_TIMESTAMP(23),
 >>> +   AT91_SAMA5D2_CHAN_TOUCH(24, "x", IIO_MOD_X),
 >>> +   AT91_SAMA5D2_CHAN_TOUCH(25, "y", IIO_MOD_Y),
 >>> +   AT91_SAMA5D2_CHAN_PRESSURE(26, "pressure"),


Sorry about this. Do you want me to resend the whole series together 
with the fixes found by robots ?

I can redo the series, retest it, and send it tomorrow as a v3.


Thanks,
Eugen

>>> +};
>>> +
[snip]

From benjamin.gaignard at collabora.com  Tue Aug 31 04:56:36 2021
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue, 31 Aug 2021 13:56:36 +0200
Subject: [PATCH 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <4g2sigpsttf80t72c7spdqqjvvijnths2d@4ax.com>
References: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
 <20210831094900.203283-2-benjamin.gaignard@collabora.com>
 <4g2sigpsttf80t72c7spdqqjvvijnths2d@4ax.com>
Message-ID: <fdf6417e-09cd-f0a0-a351-fccd64bfc8c7@collabora.com>


Le 31/08/2021 ? 13:08, John Cox a ?crit?:
>> Marking a picture as long-term reference is valid for DPB but not for RPS.
>> Change flag name to match with it description in HEVC spec chapiter
>> "8.3.2 Decoding process for reference picture set".
>> Remove the other unused RPS flags.
>>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
>> ---
>> Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 6 ++----
>> drivers/staging/media/hantro/hantro_g2_hevc_dec.c         | 2 +-
>> drivers/staging/media/sunxi/cedrus/cedrus_h265.c          | 2 +-
>> include/media/hevc-ctrls.h                                | 4 +---
>> 4 files changed, 5 insertions(+), 9 deletions(-)
>>
>> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>> index 3865acb9e0fd..eff33c511090 100644
>> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>> @@ -3138,10 +3138,8 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>> 	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
>>      * - __u8
>>        - ``rps``
>> -      - The reference set for the reference frame
>> -        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
>> -        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
>> -        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>> +      - Long term flag for the reference frame
>> +        (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
>>      * - __u8
>>        - ``field_pic``
>>        - Whether the reference is a field picture or a frame.
> If you are going to remove all the RPS values except for Long Term
> wouldn't it be better to rename the field too, either to "flags" or a
> bool "is_long_term"?  If we have a field called RPS it really should be
> able to have a value for any of the 5 valid Reference Picture Sets that
> a DPB entry can belong to.

I will send a v2 and rename rps into flags.

>
> As a side note, it is important to my code that the DPB array contains
> all the DPB entries not just the ones that are in use in this frame.  I
> need them so I can track which frames have left the DPB so I can
> reuse/free the MV tables associated with them (yes I could keep one for
> every entry in the capture Q but that is generally wasteful on memory
> and the Pi is often memory constrained). So maybe update the docn on DPB
> to make this explicit please? (I suspect that current code does this
> anyway as it is generally easier to do than to not.)

That should be in another patch :-)

Benjamin

>
> John Cox
>
>> diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>> index 9ea864ca5625..be46b3c28b17 100644
>> --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>> +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>> @@ -503,7 +503,7 @@ static int set_ref(struct hantro_ctx *ctx)
>> 		compress_luma_addr = luma_addr + compress_luma_offset;
>> 		compress_chroma_addr = luma_addr + compress_chroma_offset;
>>
>> -		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>> +		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
>> 			dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
>>
>> 		/*
>> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>> index ef0311a16d01..6086cc35e8cc 100644
>> --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>> @@ -169,7 +169,7 @@ static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
>> 		unsigned int index = list[i];
>> 		u8 value = list[i];
>>
>> -		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>> +		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
>> 			value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
>>
>> 		/* Each SRAM word gathers up to 4 references. */
>> diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
>> index ef63bc205756..f587448ef495 100644
>> --- a/include/media/hevc-ctrls.h
>> +++ b/include/media/hevc-ctrls.h
>> @@ -127,9 +127,7 @@ struct v4l2_ctrl_hevc_pps {
>> 	__u64	flags;
>> };
>>
>> -#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE	0x01
>> -#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER	0x02
>> -#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR		0x03
>> +#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE	0x01
>>
>> #define V4L2_HEVC_DPB_ENTRIES_NUM_MAX		16
>>


From robh+dt at kernel.org  Tue Aug 31 05:36:17 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 07:36:17 -0500
Subject: [PATCH v3 5/8] dt-bindings: clock: samsung: convert Exynos4 to
 dtschema
In-Reply-To: <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
Message-ID: <CAL_JsqJvEgqvnTokdNjOR=XdY89TdZxUXR4--P1FXVj75z3tgA@mail.gmail.com>

On Wed, Aug 25, 2021 at 8:41 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
> schema.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos4-clock.txt          | 86 -------------------
>  .../bindings/clock/samsung,exynos-clock.yaml  |  3 +
>  .../clock/samsung,exynos4412-isp-clock.yaml   | 64 ++++++++++++++
>  3 files changed, 67 insertions(+), 86 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml

[...]

> +examples:
> +  - |
> +    #include <dt-bindings/clock/exynos4412.h>

Where is this header? linux-next is now failing:

Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.example.dts:19:18:
fatal error: dt-bindings/clock/exynos4412.h: No such file or directory
   19 |         #include <dt-bindings/clock/exynos4412.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:398:
Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.example.dt.yaml]
Error 1

Rob


From daniel at ffwll.ch  Tue Aug 31 05:47:03 2021
From: daniel at ffwll.ch (Daniel Vetter)
Date: Tue, 31 Aug 2021 14:47:03 +0200
Subject: [PATCH] dma-buf: Add support for mapping buffers with DMA
 attributes
In-Reply-To: <20210830023911.4410-1-guangming.cao@mediatek.com>
References: <20210830023911.4410-1-guangming.cao@mediatek.com>
Message-ID: <YS4kx3thdJOu3uHX@phenom.ffwll.local>

On Mon, Aug 30, 2021 at 10:39:11AM +0800, guangming.cao at mediatek.com wrote:
> From: Guangming Cao <Guangming.Cao at mediatek.com>
> 
> When mapping the memory represented by a dma-buf into a device's
> address space, it might be desireable to map the memory with
> certain DMA attributes. Thus, introduce the dma_mapping_attrs
> field in the dma_buf_attachment structure so that when
> the memory is mapped with dma_buf_map_attachment, it is mapped
> with the desired DMA attributes.
> 
> Signed-off-by: Isaac J. Manjarres <isaacm at codeaurora.org>
> Signed-off-by: Sandeep Patil <sspatil at google.com>
> Signed-off-by: Guangming Cao <Guangming.Cao at mediatek.com>

Can you pls include the code that's going to use this here too?

At a glance all the attributes you might want to set are supposed to be
under the control of the exporter, not the importer.
-Daniel

> ---
>  drivers/dma-buf/heaps/cma_heap.c    | 6 ++++--
>  drivers/dma-buf/heaps/system_heap.c | 6 ++++--
>  include/linux/dma-buf.h             | 3 +++
>  3 files changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
> index 0c05b79870f9..2c9feb3bfc3e 100644
> --- a/drivers/dma-buf/heaps/cma_heap.c
> +++ b/drivers/dma-buf/heaps/cma_heap.c
> @@ -99,9 +99,10 @@ static struct sg_table *cma_heap_map_dma_buf(struct dma_buf_attachment *attachme
>  {
>  	struct dma_heap_attachment *a = attachment->priv;
>  	struct sg_table *table = &a->table;
> +	int attrs = attachment->dma_map_attrs;
>  	int ret;
>  
> -	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
> +	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
>  	if (ret)
>  		return ERR_PTR(-ENOMEM);
>  	a->mapped = true;
> @@ -113,9 +114,10 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
>  				   enum dma_data_direction direction)
>  {
>  	struct dma_heap_attachment *a = attachment->priv;
> +	int attrs = attachment->dma_map_attrs;
>  
>  	a->mapped = false;
> -	dma_unmap_sgtable(attachment->dev, table, direction, 0);
> +	dma_unmap_sgtable(attachment->dev, table, direction, attrs);
>  }
>  
>  static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
> diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
> index 23a7e74ef966..fc7b1e02988e 100644
> --- a/drivers/dma-buf/heaps/system_heap.c
> +++ b/drivers/dma-buf/heaps/system_heap.c
> @@ -130,9 +130,10 @@ static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attac
>  {
>  	struct dma_heap_attachment *a = attachment->priv;
>  	struct sg_table *table = a->table;
> +	int attrs = attachment->dma_map_attrs;
>  	int ret;
>  
> -	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
> +	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
>  	if (ret)
>  		return ERR_PTR(ret);
>  
> @@ -145,9 +146,10 @@ static void system_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
>  				      enum dma_data_direction direction)
>  {
>  	struct dma_heap_attachment *a = attachment->priv;
> +	int attrs = attachment->dma_map_attrs;
>  
>  	a->mapped = false;
> -	dma_unmap_sgtable(attachment->dev, table, direction, 0);
> +	dma_unmap_sgtable(attachment->dev, table, direction, attrs);
>  }
>  
>  static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index efdc56b9d95f..4d650731766e 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -379,6 +379,8 @@ struct dma_buf_attach_ops {
>   * @importer_ops: importer operations for this attachment, if provided
>   * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
>   * @importer_priv: importer specific attachment data.
> + * @dma_map_attrs: DMA attributes to be used when the exporter maps the buffer
> + * through dma_buf_map_attachment.
>   *
>   * This structure holds the attachment information between the dma_buf buffer
>   * and its user device(s). The list contains one attachment struct per device
> @@ -399,6 +401,7 @@ struct dma_buf_attachment {
>  	const struct dma_buf_attach_ops *importer_ops;
>  	void *importer_priv;
>  	void *priv;
> +	unsigned long dma_map_attrs;
>  };
>  
>  /**
> -- 
> 2.17.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From zhaoxiao at uniontech.com  Tue Aug 31 05:51:59 2021
From: zhaoxiao at uniontech.com (zhaoxiao)
Date: Tue, 31 Aug 2021 20:51:59 +0800
Subject: [PATCH] pwm: rockchip: Simplify using devm_pwmchip_add()
Message-ID: <20210831125159.29282-1-zhaoxiao@uniontech.com>

With devm_pwmchip_add() we can drop pwmchip_remove() from the device
remove callback. The latter can then go away, too and as this is the
only user of platform_get_drvdata(), the respective call to
platform_set_drvdata() can go, too.

Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
---
 drivers/pwm/pwm-rockchip.c | 29 +----------------------------
 1 file changed, 1 insertion(+), 28 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index cbe900877724..c22856916e63 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -347,8 +347,6 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 		goto err_clk;
 	}
 
-	platform_set_drvdata(pdev, pc);
-
 	pc->data = id->data;
 	pc->chip.dev = &pdev->dev;
 	pc->chip.ops = &rockchip_pwm_ops;
@@ -358,7 +356,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 	ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
 	enabled = (ctrl & enable_conf) == enable_conf;
 
-	ret = pwmchip_add(&pc->chip);
+	ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
 		goto err_pclk;
@@ -380,37 +378,12 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static int rockchip_pwm_remove(struct platform_device *pdev)
-{
-	struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev);
-
-	/*
-	 * Disable the PWM clk before unpreparing it if the PWM device is still
-	 * running. This should only happen when the last PWM user left it
-	 * enabled, or when nobody requested a PWM that was previously enabled
-	 * by the bootloader.
-	 *
-	 * FIXME: Maybe the core should disable all PWM devices in
-	 * pwmchip_remove(). In this case we'd only have to call
-	 * clk_unprepare() after pwmchip_remove().
-	 *
-	 */
-	if (pwm_is_enabled(pc->chip.pwms))
-		clk_disable(pc->clk);
-
-	clk_unprepare(pc->pclk);
-	clk_unprepare(pc->clk);
-
-	return pwmchip_remove(&pc->chip);
-}
-
 static struct platform_driver rockchip_pwm_driver = {
 	.driver = {
 		.name = "rockchip-pwm",
 		.of_match_table = rockchip_pwm_dt_ids,
 	},
 	.probe = rockchip_pwm_probe,
-	.remove = rockchip_pwm_remove,
 };
 module_platform_driver(rockchip_pwm_driver);
 
-- 
2.20.1





From nsaenzju at redhat.com  Tue Aug 31 05:58:43 2021
From: nsaenzju at redhat.com (Nicolas Saenz Julienne)
Date: Tue, 31 Aug 2021 14:58:43 +0200
Subject: [PATCH v2 2/2] ARM: dts: bcm2711-rpi-4-b: Fix usb's unit address
In-Reply-To: <20210831125843.1233488-1-nsaenzju@redhat.com>
References: <20210831125843.1233488-1-nsaenzju@redhat.com>
Message-ID: <20210831125843.1233488-2-nsaenzju@redhat.com>

The unit address is supposed to represent '<device>,<function>'. Which
are both 0 for RPi4b's XHCI controller. On top of that although
OpenFirmware states bus number goes in the high part of the last reg
parameter, FDT doesn't seem to care for it[1], so remove it.

[1] https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210830103909.323356-1-nsaenzju at redhat.com/#24414633
Fixes: 258f92d2f840 ("ARM: dts: bcm2711: Add reset controller to xHCI node")
Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
---

Chages since v1:
 - Add patch as per robh suggestion

 arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index 8377dc14b7b5..50530cc91876 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -225,8 +225,8 @@ pci at 0,0 {
 
 		reg = <0 0 0 0 0>;
 
-		usb at 1,0 {
-			reg = <0x10000 0 0 0 0>;
+		usb at 0,0 {
+			reg = <0 0 0 0 0>;
 			resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
 		};
 	};
-- 
2.31.1



From nsaenzju at redhat.com  Tue Aug 31 05:58:42 2021
From: nsaenzju at redhat.com (Nicolas Saenz Julienne)
Date: Tue, 31 Aug 2021 14:58:42 +0200
Subject: [PATCH v2 1/2] ARM: dts: bcm2711-rpi-4-b: Fix pcie0's unit address
 formatting
Message-ID: <20210831125843.1233488-1-nsaenzju@redhat.com>

dtbs_check currently complains that:

arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning
(pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format
error, expected "0,0"

Unsurprisingly pci at 0,0 is the right address, as illustrated by its reg
property:

    &pcie0 {
	    pci at 0,0 {
		    /*
		     * As defined in the IEEE Std 1275-1994 document,
		     * reg is a five-cell address encoded as (phys.hi
		     * phys.mid phys.lo size.hi size.lo). phys.hi
		     * should contain the device's BDF as 0b00000000
		     * bbbbbbbb dddddfff 00000000. The other cells
		     * should be zero.
		     */
		    reg = <0 0 0 0 0>;
	    };
    };

The device is clearly 0. So fix it.

Also add a missing 'device_type = "pci"'.

Fixes: 258f92d2f840 ("ARM: dts: bcm2711: Add reset controller to xHCI node")
Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
---

Changes since v1:
 - s/bus/device/ when talking about unit addresses
 - Add device_type
 - Add Suggested-by 

 arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index f24bdd0870a5..8377dc14b7b5 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -217,7 +217,8 @@ phy1: ethernet-phy at 1 {
 };
 
 &pcie0 {
-	pci at 1,0 {
+	pci at 0,0 {
+		device_type = "pci";
 		#address-cells = <3>;
 		#size-cells = <2>;
 		ranges;
-- 
2.31.1



From krzysztof.kozlowski at canonical.com  Tue Aug 31 06:03:55 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 31 Aug 2021 15:03:55 +0200
Subject: [PATCH v3 5/8] dt-bindings: clock: samsung: convert Exynos4 to
 dtschema
In-Reply-To: <CAL_JsqJvEgqvnTokdNjOR=XdY89TdZxUXR4--P1FXVj75z3tgA@mail.gmail.com>
References: <20210825134056.219884-1-krzysztof.kozlowski@canonical.com>
 <20210825134056.219884-6-krzysztof.kozlowski@canonical.com>
 <CAL_JsqJvEgqvnTokdNjOR=XdY89TdZxUXR4--P1FXVj75z3tgA@mail.gmail.com>
Message-ID: <d5e75754-4724-9cbf-d07e-47c40cfa130f@canonical.com>

On 31/08/2021 14:36, Rob Herring wrote:
> On Wed, Aug 25, 2021 at 8:41 AM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Merge Exynos4210 and Exynos4412 clock controller bindings to existing DT
>> schema.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/clock/exynos4-clock.txt          | 86 -------------------
>>  .../bindings/clock/samsung,exynos-clock.yaml  |  3 +
>>  .../clock/samsung,exynos4412-isp-clock.yaml   | 64 ++++++++++++++
>>  3 files changed, 67 insertions(+), 86 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos4-clock.txt
>>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml
> 
> [...]
> 
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/exynos4412.h>
> 
> Where is this header? linux-next is now failing:
> 

Argh, it should be exynos4.h. Stephen mentioned it but I missed the
difference in number. I wonder how it passed dt_binding_check on my
machine...

Sorry for the mess, I'll send the fix.



Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Aug 31 06:06:43 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 31 Aug 2021 15:06:43 +0200
Subject: [PATCH] dt-bindings: clock: samsung: fix header path in example
Message-ID: <20210831130643.83249-1-krzysztof.kozlowski@canonical.com>

The proper header is exynos4.h:

    samsung,exynos4412-isp-clock.example.dts:19:18: fatal error: dt-bindings/clock/exynos4412.h: No such file or directory

Fixes: 7ac615780926 ("dt-bindings: clock: samsung: convert Exynos4 to dtschema")
Reported-by: Stephen Boyd <sboyd at kernel.org>
Reported-by: Rob Herring <robh+dt at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

The SHA in fixes tag is from linux-next. Might not be stable.
---
 .../devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml
index 7b405bcd6fef..1ed64add4355 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml
@@ -52,7 +52,7 @@ additionalProperties: false
 
 examples:
   - |
-    #include <dt-bindings/clock/exynos4412.h>
+    #include <dt-bindings/clock/exynos4.h>
     clock-controller at 10048000 {
         compatible = "samsung,exynos4412-isp-clock";
         reg = <0x10048000 0x1000>;
-- 
2.30.2



From geert+renesas at glider.be  Tue Aug 31 06:18:54 2021
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue, 31 Aug 2021 15:18:54 +0200
Subject: [PATCH] ASoC: mediatek: SND_SOC_MT8195 should depend on ARCH_MEDIATEK
Message-ID: <7e628e359bde04ceb9ddd74a45931059b4a4623c.1630415860.git.geert+renesas@glider.be>

The Mediatek MT8195 sound hardware is only present on Mediatek MT8195
SoCs.  Hence add a dependency on ARCH_MEDIATEK, to prevent asking the
user about this driver when configuring a kernel without Mediatek SoC
support.

Fixes: 6746cc858259985a ("ASoC: mediatek: mt8195: add platform driver")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 sound/soc/mediatek/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index cf567a89f421b4c0..c8c815f599da90bf 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -187,6 +187,7 @@ config SND_SOC_MT8192_MT6359_RT1015_RT5682
 
 config SND_SOC_MT8195
 	tristate "ASoC support for Mediatek MT8195 chip"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
 	select SND_SOC_MEDIATEK
 	help
 	  This adds ASoC platform driver support for Mediatek MT8195 chip
-- 
2.25.1



From will at kernel.org  Tue Aug 31 06:31:17 2021
From: will at kernel.org (Will Deacon)
Date: Tue, 31 Aug 2021 14:31:17 +0100
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <CAHk-=wg=+P1+HQXhrszxN_BgWtLc-=dWiT61KzogcJU3hnLrtQ@mail.gmail.com>
References: <20210826131747.GE26318@willie-the-truck>
 <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>
 <20210827074041.GA24309@lst.de>
 <CAHk-=wjd28sN9khO=1j6zmBk+2n4_e+SY1URjW9hzsHSAZU+7Q@mail.gmail.com>
 <20210827171041.GA28149@lst.de>
 <CAHk-=wg=+P1+HQXhrszxN_BgWtLc-=dWiT61KzogcJU3hnLrtQ@mail.gmail.com>
Message-ID: <20210831133117.GD31712@willie-the-truck>

[+David]

On Fri, Aug 27, 2021 at 10:16:27AM -0700, Linus Torvalds wrote:
> On Fri, Aug 27, 2021 at 10:10 AM Christoph Hellwig <hch at lst.de> wrote:
> >
> > They CCed me on their earlier discussion, but I did not catch up on it
> > until you responded to the pull request  If I understood it correct it
> > was about a platform device mapping a MMIO region (like a PCI bar),
> > but something about section alignment cause pfn_valid to mistrigger.
> 
> Yeah, so I can easily see the maxpfn numbers can easily end up being
> rounded up to a whole memory section etc.
> 
> I think my suggested solution should JustWork(tm) - exactly because if
> the area is then in that "this pfn is valid" area, it will
> double-check the actual underlying page.

I think the pitfall there is that the 'struct page' might well exist,
but isn't necessarily initialised with anything meaningful. I remember
seeing something like that in the past (I think for "no-map" memory) and
David's reply here:

https://lore.kernel.org/r/aff3942e-b9ce-5bae-8214-0e5d89cd071c at redhat.com

hints that there are still gotchas with looking at the page flags for
pages if the memory is offline or ZONE_DEVICE.

Don't get me wrong, I'd really like to use the generic code here as I
think it would help to set expectations around what pfn_valid() actually
means, I'm just less keen on the try-it-and-see-what-breaks approach
given how sensitive it is to the layout of the physical memory map.

> That said, I think x86 avoids the problem another way - by just making
> sure max_pfn is exact. That works too, as long as there are no holes
> in the RAM map that might be used for PCI BAR's.
> 
> So I think arm could fix it that way too, depending on their memory layout.

The physical memory map is the wild west, unfortunately. It's one of the
things where everybody does something different and it's very common to see
disjoint banks of memory placed seemingly randomly around.

Will


From mike.leach at linaro.org  Tue Aug 31 06:31:28 2021
From: mike.leach at linaro.org (Mike Leach)
Date: Tue, 31 Aug 2021 14:31:28 +0100
Subject: [PATCHv2 4/4] coresight: Add ETR-PERF polling.
In-Reply-To: <20210826173248.GB808387@p14s>
References: <20210713121532.836244-1-daniel.kiss@arm.com>
 <20210713121532.836244-5-daniel.kiss@arm.com>
 <20210826173248.GB808387@p14s>
Message-ID: <CAJ9a7Vj=zSn5oPA61z-4-XfY2pE0buZpLefaWTMhxF+rE_1XFQ@mail.gmail.com>

iI Mathieu, Daniel,.

On Thu, 26 Aug 2021 at 18:33, Mathieu Poirier
<mathieu.poirier at linaro.org> wrote:
>
> On Tue, Jul 13, 2021 at 02:15:32PM +0200, Daniel Kiss wrote:
> > ETR might fill up the buffer sooner than an event makes perf to trigger
> > the synchronisation especially in system wide trace. Polling runs
> > periodically to sync the ETR buffer. Period is configurable via sysfs,
> > disabled by default.
> >
> > Signed-off-by: Daniel Kiss <daniel.kiss at arm.com>
> > Signed-off-by: Branislav Rankov <Branislav.Rankov at arm.com>
> > Tested-by: Denis Nikitin <denik at chromium.org>
> > ---
> >  .../testing/sysfs-bus-coresight-devices-tmc   |   8 +
> >  drivers/hwtracing/coresight/Kconfig           |  12 +
> >  drivers/hwtracing/coresight/Makefile          |   1 +
> >  .../hwtracing/coresight/coresight-etm-perf.c  |   8 +
> >  .../coresight/coresight-etr-perf-polling.c    | 275 ++++++++++++++++++
> >  .../coresight/coresight-etr-perf-polling.h    |  38 +++
> >  .../hwtracing/coresight/coresight-tmc-core.c  |   4 +
> >  .../hwtracing/coresight/coresight-tmc-etr.c   |  13 +
> >  8 files changed, 359 insertions(+)
> >  create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.c
> >  create mode 100644 drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> >
> > diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> > index 6aa527296c710..3b411e8a6f417 100644
> > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
> > @@ -91,3 +91,11 @@ Contact:   Mathieu Poirier <mathieu.poirier at linaro.org>
> >  Description: (RW) Size of the trace buffer for TMC-ETR when used in SYSFS
> >               mode. Writable only for TMC-ETR configurations. The value
> >               should be aligned to the kernel pagesize.
> > +
> > +What:                /sys/bus/coresight/devices/<memory_map>.tmc/polling/period
> > +Date:                July 2021
> > +KernelVersion:       5.14
> > +Contact:     Daniel Kiss <daniel.kiss at arm.com>
> > +Description: (RW) Time in milliseconds when the TMC-ETR is synced.
> > +             Default value is 0, means the feature is disabled.
> > +             Writable only for TMC-ETR configurations.
> > diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
> > index 84530fd80998c..4e91fb98849f4 100644
> > --- a/drivers/hwtracing/coresight/Kconfig
> > +++ b/drivers/hwtracing/coresight/Kconfig
> > @@ -44,6 +44,18 @@ config CORESIGHT_LINK_AND_SINK_TMC
> >         To compile this driver as a module, choose M here: the
> >         module will be called coresight-tmc.
> >
> > +
> > +config CORESIGHT_ETR_PERF_POLL
> > +     bool "Coresight ETR Perf Polling"
> > +
> > +     depends on CORESIGHT_LINK_AND_SINK_TMC
> > +     help
> > +       Enable the support for software periodic synchronization of the ETR buffer.
> > +       ETR might fill up the buffer sooner than an event makes perf to trigger
> > +       the synchronization especially in system wide trace. Polling runs
> > +       periodically to sync the ETR buffer. Period is configurable via sysfs,
> > +       disabled by default.
> > +
> >  config CORESIGHT_CATU
> >       tristate "Coresight Address Translation Unit (CATU) driver"
> >       depends on CORESIGHT_LINK_AND_SINK_TMC
> > diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> > index d60816509755c..6baac328eea87 100644
> > --- a/drivers/hwtracing/coresight/Makefile
> > +++ b/drivers/hwtracing/coresight/Makefile
> > @@ -5,6 +5,7 @@
> >  obj-$(CONFIG_CORESIGHT) += coresight.o
> >  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
> >               coresight-sysfs.o
> > +coresight-$(CONFIG_CORESIGHT_ETR_PERF_POLL) += coresight-etr-perf-polling.o
> >  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
> >  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
> >                     coresight-tmc-etr.o
> > diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> > index a3f4c07f5bf8b..3095840a567c4 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/workqueue.h>
> >
> >  #include "coresight-etm-perf.h"
> > +#include "coresight-etr-perf-polling.h"
> >  #include "coresight-priv.h"
> >
> >  static struct pmu etm_pmu;
> > @@ -438,6 +439,8 @@ static void etm_event_start(struct perf_event *event, int flags)
> >       /* Tell the perf core the event is alive */
> >       event->hw.state = 0;
> >
> > +     etr_perf_polling_event_start(event, event_data, handle);
> > +
> >       /* Finally enable the tracer */
> >       if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF))
> >               goto fail_disable_path;
> > @@ -497,6 +500,8 @@ static void etm_event_stop(struct perf_event *event, int mode)
> >       if (!sink)
> >               return;
> >
> > +     etr_perf_polling_event_stop(event, event_data);
> > +
> >       /* stop tracer */
> >       source_ops(csdev)->disable(csdev, event);
> >
> > @@ -741,6 +746,8 @@ int __init etm_perf_init(void)
> >       etm_pmu.addr_filters_validate   = etm_addr_filters_validate;
> >       etm_pmu.nr_addr_filters         = ETM_ADDR_CMP_MAX;
> >
> > +     etr_perf_polling_init();
>
> The problem here is that a function specific to an ETR is inserted in code that
> should be generic.  So if we want to do the same for ETB, ETF and any kind of
> sink that's out there, we'd have to duplicate code and it would quickly get
> messy.  What is needed is a generic solution.
>
> Moreover what is proposed here is centered on sinks, while the entire coresight
> framework is centered on sources.  The polling function, although specific to
> sinks, should emanate from and be driven by the generic code that handles
> sources.  There should also be a single event responsible for doing the polling
> rather than all of them as it is the case in this patchset.  In per-thread mode
> where a single thread is traced it isn't a problem.  In CPU-wide scenarios the
> first event should do the polling.  There will be a gap between the time that
> event stops and all the other events in the trace session stop but that is a
> limitation we will have to live with.
>

In my previous reviews of this I have suggested that this must be ETR
specific - the object of feature is to use polling to mimic the
interrupt we get with somehting  like TRBE, and get more consistent
output across the entire trace run - which is the objective of the
feature and has been backed up by evidence from those that have tried
it out..
Granted, TRBE is per core and thus can only be operating on the single
source, but the guiding idea remains the same - save data whenever the
sink hardware is full (or artificailly stopped in the case of
polling). TRBE does not, as far as I recall wait for an event to stop
before servicing the full interrupt.,

The worry is that is this is source event driven then any advantages
would be wiped out by waiting for events in the trace session to stop.

Regards

Mike


> That leaves us with per-thread sessions where child threads are spun off.  You
> will have to look into how events are handle in that case.  Suzuki has done work
> in that area and might remember a few things.
>
> There are other design problems with this set that I won't get into since it
> needs a refactoring anyway.
>
> Regards,
> Mathieu
>
> > +
> >       ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
> >       if (ret == 0)
> >               etm_perf_up = true;
> > @@ -750,5 +757,6 @@ int __init etm_perf_init(void)
> >
> >  void __exit etm_perf_exit(void)
> >  {
> > +     etr_perf_polling_exit();
> >       perf_pmu_unregister(&etm_pmu);
> >  }
> > diff --git a/drivers/hwtracing/coresight/coresight-etr-perf-polling.c b/drivers/hwtracing/coresight/coresight-etr-perf-polling.c
> > new file mode 100644
> > index 0000000000000..87e6bc42a62de
> > --- /dev/null
> > +++ b/drivers/hwtracing/coresight/coresight-etr-perf-polling.c
> > @@ -0,0 +1,275 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright(C) 2021 Arm Limited. All rights reserved.
> > + * Author: Daniel Kiss <daniel.kiss at arm.com>
> > + */
> > +
> > +#include <linux/coresight.h>
> > +#include <linux/coresight-pmu.h>
> > +#include <linux/cpumask.h>
> > +#include <linux/device.h>
> > +#include <linux/init.h>
> > +#include <linux/list.h>
> > +#include <linux/percpu-defs.h>
> > +#include <linux/perf_event.h>
> > +#include <linux/slab.h>
> > +#include <linux/stringhash.h>
> > +#include <linux/types.h>
> > +#include <linux/workqueue.h>
> > +
> > +#include "coresight-etr-perf-polling.h"
> > +#include "coresight-priv.h"
> > +#include "coresight-tmc.h"
> > +
> > +struct polling_event_list {
> > +     struct perf_event *perf_event;
> > +     struct etm_event_data *etm_event_data;
> > +     struct perf_output_handle *ctx_handle;
> > +     void (*tmc_etr_reset_hw)(struct tmc_drvdata *data);
> > +     struct list_head list;
> > +};
> > +
> > +struct polling {
> > +     int cpu;
> > +     struct polling_event_list *polled_event;
> > +     struct delayed_work delayed_work;
> > +};
> > +
> > +static atomic_t period;
> > +static spinlock_t spinlock_re;
> > +static struct list_head registered_events;
> > +
> > +static DEFINE_PER_CPU(struct polling, polling);
> > +
> > +static ssize_t period_show(struct device *dev, struct device_attribute *attr,
> > +                        char *buf)
> > +{
> > +     int temp;
> > +
> > +     temp = atomic_read(&period);
> > +     return sprintf(buf, "%i\n", temp);
> > +}
> > +
> > +static ssize_t period_store(struct device *dev, struct device_attribute *attr,
> > +                         const char *buf, size_t count)
> > +{
> > +     int temp = 0;
> > +
> > +     if (!kstrtoint(buf, 10, &temp) && (temp >= 0))
> > +             atomic_set(&period, temp);
> > +     return count;
> > +}
> > +
> > +static DEVICE_ATTR_RW(period);
> > +
> > +static struct attribute *coresight_tmc_polling_attrs[] = {
> > +     &dev_attr_period.attr,
> > +     NULL,
> > +};
> > +const struct attribute_group coresight_tmc_polling_group = {
> > +     .attrs = coresight_tmc_polling_attrs,
> > +     .name = "polling",
> > +};
> > +EXPORT_SYMBOL_GPL(coresight_tmc_polling_group);
> > +
> > +static inline void polling_sched_worker(struct polling *p)
> > +{
> > +     int tickrate = atomic_read(&period);
> > +
> > +     if (tickrate > 0)
> > +             schedule_delayed_work_on(p->cpu, &p->delayed_work,
> > +                                      msecs_to_jiffies(tickrate));
> > +}
> > +
> > +static inline bool is_etr_related(struct etm_event_data *etm_event_data, int cpu)
> > +{
> > +     struct list_head *path;
> > +     struct coresight_device *sink;
> > +     struct tmc_drvdata *drvdata;
> > +
> > +     path = etm_event_cpu_path(etm_event_data, cpu);
> > +     if (WARN_ON(!path))
> > +             return false;
> > +     sink = coresight_get_sink(path);
> > +     if (WARN_ON(!sink))
> > +             return false;
> > +     drvdata = dev_get_drvdata(sink->dev.parent);
> > +     if (drvdata->config_type != TMC_CONFIG_TYPE_ETR)
> > +             return false;
> > +     return true;
> > +}
> > +
> > +/*
> > + * Adds the event to the polled events list.
> > + */
> > +void etr_perf_polling_event_start(struct perf_event *event,
> > +                               struct etm_event_data *etm_event_data,
> > +                               struct perf_output_handle *ctx_handle)
> > +{
> > +     int cpu = smp_processor_id();
> > +     struct polling *p = per_cpu_ptr(&polling, cpu);
> > +     struct polling_event_list *element, *tmp;
> > +
> > +     if (!is_etr_related(etm_event_data, cpu))
> > +             return;
> > +
> > +     spin_lock(&spinlock_re);
> > +     list_for_each_entry_safe(element, tmp, &registered_events, list) {
> > +             if (element->ctx_handle == ctx_handle) {
> > +                     element->perf_event = event;
> > +                     element->etm_event_data = etm_event_data;
> > +                     spin_unlock(&spinlock_re);
> > +                     p->polled_event = element;
> > +                     polling_sched_worker(p);
> > +                     return;
> > +             }
> > +     }
> > +     spin_unlock(&spinlock_re);
> > +}
> > +
> > +/*
> > + * Removes the event from the to be polled events list.
> > + */
> > +void etr_perf_polling_event_stop(struct perf_event *event,
> > +                              struct etm_event_data *etm_event_data)
> > +{
> > +     int cpu = smp_processor_id();
> > +     struct polling *p = per_cpu_ptr(&polling, cpu);
> > +
> > +     if (!is_etr_related(etm_event_data, cpu))
> > +             return;
> > +
> > +     if (p->polled_event) {
> > +             struct polling_event_list *element = p->polled_event;
> > +
> > +             if (element->perf_event == event) {
> > +                     p->polled_event = NULL;
> > +                     element->perf_event = NULL;
> > +                     element->etm_event_data = NULL;
> > +                     cancel_delayed_work(&p->delayed_work);
> > +                     return;
> > +             }
> > +     }
> > +}
> > +
> > +/*
> > + * The polling worker is a workqueue job which is periodically
> > + * woken up to update the perf aux buffer from the etr shrink.
> > + */
> > +static void etr_perf_polling_worker(struct work_struct *work)
> > +{
> > +     unsigned long flags;
> > +     struct list_head *path;
> > +     struct coresight_device *sink;
> > +     int size;
> > +     int cpu = smp_processor_id();
> > +     struct polling *p = per_cpu_ptr(&polling, cpu);
> > +
> > +     if (!atomic_read(&period))
> > +             return;
> > +
> > +     if (!p->polled_event)
> > +             return;
> > +     /*
> > +      * Scheduling would do the same from the perf hooks,
> > +      * this should be done in one go.
> > +      */
> > +     local_irq_save(flags);
> > +
> > +     polling_sched_worker(p);
> > +
> > +     path = etm_event_cpu_path(p->polled_event->etm_event_data, cpu);
> > +     sink = coresight_get_sink(path);
> > +     size = sink_ops(sink)->update_buffer(
> > +             sink, p->polled_event->ctx_handle,
> > +             p->polled_event->etm_event_data->snk_config);
> > +
> > +     /*
> > +      * Restart the trace.
> > +      */
> > +     if (p->polled_event->tmc_etr_reset_hw)
> > +             p->polled_event->tmc_etr_reset_hw(dev_get_drvdata(sink->dev.parent));
> > +
> > +     WARN_ON(size < 0);
> > +     if (size > 0) {
> > +             struct etm_event_data *new_event_data;
> > +
> > +             perf_aux_output_end(p->polled_event->ctx_handle, size);
> > +             new_event_data = perf_aux_output_begin(
> > +                     p->polled_event->ctx_handle,
> > +                     p->polled_event->perf_event);
> > +             if (WARN_ON(new_event_data == NULL)) {
> > +                     local_irq_restore(flags);
> > +                     return;
> > +             }
> > +
> > +             p->polled_event->etm_event_data = new_event_data;
> > +             WARN_ON(new_event_data->snk_config !=
> > +                     p->polled_event->etm_event_data->snk_config);
> > +     }
> > +
> > +     local_irq_restore(flags);
> > +}
> > +
> > +void etr_perf_polling_handle_register(struct perf_output_handle *handle,
> > +                                   void (*tmc_etr_reset_hw)(struct tmc_drvdata *drvdata))
> > +{
> > +     struct polling_event_list *element;
> > +
> > +     element = kmalloc(sizeof(*element), GFP_ATOMIC);
> > +     if (WARN_ON(!element))
> > +             return;
> > +     memset(element, 0, sizeof(*element));
> > +     element->ctx_handle = handle;
> > +     element->tmc_etr_reset_hw = tmc_etr_reset_hw;
> > +     spin_lock(&spinlock_re);
> > +     list_add(&element->list, &registered_events);
> > +     spin_unlock(&spinlock_re);
> > +}
> > +EXPORT_SYMBOL_GPL(etr_perf_polling_handle_register);
> > +
> > +void etr_perf_polling_handle_deregister(struct perf_output_handle *handle)
> > +{
> > +     struct polling_event_list *element, *tmp;
> > +
> > +     spin_lock(&spinlock_re);
> > +     list_for_each_entry_safe(element, tmp, &registered_events, list) {
> > +             if (element->ctx_handle == handle) {
> > +                     list_del(&element->list);
> > +                     spin_unlock(&spinlock_re);
> > +                     kfree(element);
> > +                     return;
> > +             }
> > +     }
> > +     spin_unlock(&spinlock_re);
> > +}
> > +EXPORT_SYMBOL_GPL(etr_perf_polling_handle_deregister);
> > +
> > +void etr_perf_polling_init(void)
> > +{
> > +     int cpu;
> > +
> > +     spin_lock_init(&spinlock_re);
> > +     INIT_LIST_HEAD(&registered_events);
> > +     atomic_set(&period, 0);
> > +     for_each_possible_cpu(cpu) {
> > +             struct polling *p = per_cpu_ptr(&polling, cpu);
> > +
> > +             p->cpu = cpu;
> > +             p->polled_event = NULL;
> > +             INIT_DELAYED_WORK(&p->delayed_work, etr_perf_polling_worker);
> > +     }
> > +}
> > +
> > +void etr_perf_polling_exit(void)
> > +{
> > +     int cpu;
> > +
> > +     for_each_possible_cpu(cpu) {
> > +             struct polling *p = per_cpu_ptr(&polling, cpu);
> > +
> > +             cancel_delayed_work_sync(&p->delayed_work);
> > +             WARN_ON(p->polled_event);
> > +     }
> > +     WARN_ON(!list_empty(&registered_events));
> > +}
> > diff --git a/drivers/hwtracing/coresight/coresight-etr-perf-polling.h b/drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> > new file mode 100644
> > index 0000000000000..d47b4424594e6
> > --- /dev/null
> > +++ b/drivers/hwtracing/coresight/coresight-etr-perf-polling.h
> > @@ -0,0 +1,38 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright(C) 2021 Arm Limited. All rights reserved.
> > + * Author: Daniel Kiss <daniel.kiss at arm.com>
> > + */
> > +
> > +#ifndef _CORESIGHT_ETM_PERF_POLLING_H
> > +#define _CORESIGHT_ETM_PERF_POLLING_H
> > +
> > +#include <linux/coresight.h>
> > +#include <linux/perf_event.h>
> > +#include "coresight-etm-perf.h"
> > +#include "coresight-tmc.h"
> > +
> > +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> > +void etr_perf_polling_init(void);
> > +void etr_perf_polling_exit(void);
> > +void etr_perf_polling_handle_register(struct perf_output_handle *handle,
> > +                                   void (*tmc_etr_reset_hw)(struct tmc_drvdata *drvdata));
> > +void etr_perf_polling_handle_deregister(struct perf_output_handle *handle);
> > +void etr_perf_polling_event_start(struct perf_event *event,
> > +                               struct etm_event_data *etm_event_data,
> > +                               struct perf_output_handle *ctx_handle);
> > +void etr_perf_polling_event_stop(struct perf_event *event,
> > +                              struct etm_event_data *etm_event_data);
> > +
> > +extern const struct attribute_group coresight_tmc_polling_group;
> > +
> > +#else /* !CONFIG_CORESIGHT_ETR_PERF_POLL */
> > +#define etr_perf_polling_init()
> > +#define etr_perf_polling_exit()
> > +#define etr_perf_polling_handle_register(...)
> > +#define etr_perf_polling_handle_deregister(...)
> > +#define etr_perf_polling_event_start(...)
> > +#define etr_perf_polling_event_stop(...)
> > +#endif
> > +
> > +#endif
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > index 74c6323d4d6ab..dbcdba162bd38 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > @@ -26,6 +26,7 @@
> >
> >  #include "coresight-priv.h"
> >  #include "coresight-tmc.h"
> > +#include "coresight-etr-perf-polling.h"
> >
> >  DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
> >  DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
> > @@ -365,6 +366,9 @@ static const struct attribute_group coresight_tmc_mgmt_group = {
> >  static const struct attribute_group *coresight_tmc_groups[] = {
> >       &coresight_tmc_group,
> >       &coresight_tmc_mgmt_group,
> > +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> > +     &coresight_tmc_polling_group,
> > +#endif
> >       NULL,
> >  };
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > index 55c9b5fd9f832..67cd4bdcda71b 100644
> > --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/vmalloc.h>
> >  #include "coresight-catu.h"
> >  #include "coresight-etm-perf.h"
> > +#include "coresight-etr-perf-polling.h"
> >  #include "coresight-priv.h"
> >  #include "coresight-tmc.h"
> >
> > @@ -1137,6 +1138,16 @@ void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
> >       drvdata->etr_buf = NULL;
> >  }
> >
> > +#ifdef CONFIG_CORESIGHT_ETR_PERF_POLL
> > +
> > +static void tmc_etr_reset_hw(struct tmc_drvdata *drvdata)
> > +{
> > +     __tmc_etr_disable_hw(drvdata);
> > +     __tmc_etr_enable_hw(drvdata);
> > +}
> > +
> > +#endif
> > +
> >  static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
> >  {
> >       int ret = 0;
> > @@ -1620,6 +1631,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
> >               drvdata->mode = CS_MODE_PERF;
> >               drvdata->perf_buf = etr_perf->etr_buf;
> >               drvdata->perf_handle = handle;
> > +             etr_perf_polling_handle_register(handle, tmc_etr_reset_hw);
> >               atomic_inc(csdev->refcnt);
> >       }
> >
> > @@ -1667,6 +1679,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
> >       drvdata->mode = CS_MODE_DISABLED;
> >       /* Reset perf specific data */
> >       drvdata->perf_buf = NULL;
> > +     etr_perf_polling_handle_deregister(drvdata->perf_handle);
> >       drvdata->perf_handle = NULL;
> >
> >       spin_unlock_irqrestore(&drvdata->spinlock, flags);
> > --
> > 2.25.1
> >



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.rudenko at gmail.com  Tue Aug 31 05:58:30 2021
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Tue, 31 Aug 2021 15:58:30 +0300
Subject: [PATCH v1 0/5] phy: phy-rockchip-dphy-rx0: add support for
 tx1rx1 rx mode
In-Reply-To: <20210830180758.251390-1-mike.rudenko@gmail.com>
References: <20210830180758.251390-1-mike.rudenko@gmail.com>
Message-ID: <87sfyp4u5b.fsf@gmail.com>

Hi all,

thank you for reviewing this and sorry for me failing my prior research
and overlooking existing Heiko's solution [1] [2].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=71f68fe7f12182ed968cfbbd1ef018721e4dee30
[2] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=68e0277204c733dff19073686e2ac48239b06fbc

--
Regards,
Mikhail


From fabrice.gasnier at foss.st.com  Tue Aug 31 06:38:50 2021
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Tue, 31 Aug 2021 15:38:50 +0200
Subject: [PATCH v16 01/14] counter: stm32-lptimer-cnt: Provide defines for
 clock polarities
In-Reply-To: <a111c8905c467805ca530728f88189b59430f27e.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
 <a111c8905c467805ca530728f88189b59430f27e.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <ec80f7a8-5f2e-522f-6a66-ab25092618c2@foss.st.com>



On 8/27/21 5:47 AM, William Breathitt Gray wrote:
> The STM32 low-power timer permits configuration of the clock polarity
> via the LPTIMX_CFGR register CKPOL bits. This patch provides
> preprocessor defines for the supported clock polarities.
> 
> Cc: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
> ---
>  drivers/counter/stm32-lptimer-cnt.c | 6 +++---
>  include/linux/mfd/stm32-lptimer.h   | 5 +++++
>  2 files changed, 8 insertions(+), 3 deletions(-)

Hi William,

You can add my:
Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>

Thanks,
Fabrice

> 
> diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
> index 13656957c45f..7367f46c6f91 100644
> --- a/drivers/counter/stm32-lptimer-cnt.c
> +++ b/drivers/counter/stm32-lptimer-cnt.c
> @@ -140,9 +140,9 @@ static const enum counter_function stm32_lptim_cnt_functions[] = {
>  };
>  
>  enum stm32_lptim_synapse_action {
> -	STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE,
> -	STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE,
> -	STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES,
> +	STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE = STM32_LPTIM_CKPOL_RISING_EDGE,
> +	STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE = STM32_LPTIM_CKPOL_FALLING_EDGE,
> +	STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES = STM32_LPTIM_CKPOL_BOTH_EDGES,
>  	STM32_LPTIM_SYNAPSE_ACTION_NONE,
>  };
>  
> diff --git a/include/linux/mfd/stm32-lptimer.h b/include/linux/mfd/stm32-lptimer.h
> index 90b20550c1c8..06d3f11dc3c9 100644
> --- a/include/linux/mfd/stm32-lptimer.h
> +++ b/include/linux/mfd/stm32-lptimer.h
> @@ -45,6 +45,11 @@
>  #define STM32_LPTIM_PRESC	GENMASK(11, 9)
>  #define STM32_LPTIM_CKPOL	GENMASK(2, 1)
>  
> +/* STM32_LPTIM_CKPOL */
> +#define STM32_LPTIM_CKPOL_RISING_EDGE	0
> +#define STM32_LPTIM_CKPOL_FALLING_EDGE	1
> +#define STM32_LPTIM_CKPOL_BOTH_EDGES	2
> +
>  /* STM32_LPTIM_ARR */
>  #define STM32_LPTIM_MAX_ARR	0xFFFF
>  
> 


From michael at walle.cc  Tue Aug 31 06:40:06 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 15:40:06 +0200
Subject: [PATCH 0/7] arm64: dts: ls1028: GPU support and cleanups
Message-ID: <20210831134013.1625527-1-michael@walle.cc>

In an attempt to unify u-boot's and linux' device tree for the LS1028A SoC
we first need to clean up some network related stuff. Vladimir suggested to
move the Ethernet PHYs into the MDIO controller node, which is already the
case for u-boot's device tree. Further we unify the use of phy-mode and
phy-connection-type. Both have the same meaning, but phy-mode is used more
often in the kernel and for the ls1028a both were used. Replace
phy-connection-type with phy-mode.

Further move all the nodes which belongs to the CCSR into the /soc node.
These are the Mali display conntroller and its associated pixel clock PLL.
Finally, add the GPU node for the etnaviv driver under /soc.

Michael Walle (7):
  arm64: dts: ls1028a: move pixel clock pll into /soc
  arm64: dts: ls1028a: move Mali DP500 node into /soc
  arm64: dts: ls1028a: add Vivante GPU node
  arm64: dts: freescale: fix arm,sp805 compatible string
  arm64: dts: ls1028a: disable usb controller by default
  arm64: dts: ls1028a: move PHY nodes to MDIO controller
  arm64: dts: ls1028a: use phy-mode instead of phy-connection-type

 .../fsl-ls1028a-kontron-sl28-var1.dts         | 60 ++++++++--------
 .../fsl-ls1028a-kontron-sl28-var2.dts         | 17 ++---
 .../fsl-ls1028a-kontron-sl28-var4.dts         | 49 +++++++------
 .../freescale/fsl-ls1028a-kontron-sl28.dts    | 31 +++++----
 .../boot/dts/freescale/fsl-ls1028a-qds.dts    | 10 ++-
 .../boot/dts/freescale/fsl-ls1028a-rdb.dts    | 19 +++---
 .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 68 +++++++++++--------
 .../arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 16 ++---
 .../arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 16 ++---
 9 files changed, 149 insertions(+), 137 deletions(-)

-- 
2.30.2



From michael at walle.cc  Tue Aug 31 06:40:07 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 15:40:07 +0200
Subject: [PATCH 1/7] arm64: dts: ls1028a: move pixel clock pll into /soc
In-Reply-To: <20210831134013.1625527-1-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
Message-ID: <20210831134013.1625527-2-michael@walle.cc>

Move it inside the /soc subnode because it is part of the CCSR space.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 343ecf0e8973..9a65a7118faa 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -80,13 +80,6 @@ osc_27m: clock-osc-27m {
 		clock-output-names = "phy_27m";
 	};
 
-	dpclk: clock-controller at f1f0000 {
-		compatible = "fsl,ls1028a-plldig";
-		reg = <0x0 0xf1f0000 0x0 0xffff>;
-		#clock-cells = <0>;
-		clocks = <&osc_27m>;
-	};
-
 	firmware {
 		optee: optee  {
 			compatible = "linaro,optee-tz";
@@ -926,6 +919,13 @@ QORIQ_CLK_PLL_DIV(2)>,
 			status = "disabled";
 		};
 
+		dpclk: clock-controller at f1f0000 {
+			compatible = "fsl,ls1028a-plldig";
+			reg = <0x0 0xf1f0000 0x0 0x10000>;
+			#clock-cells = <0>;
+			clocks = <&osc_27m>;
+		};
+
 		tmu: tmu at 1f80000 {
 			compatible = "fsl,qoriq-tmu";
 			reg = <0x0 0x1f80000 0x0 0x10000>;
-- 
2.30.2



From michael at walle.cc  Tue Aug 31 06:40:08 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 15:40:08 +0200
Subject: [PATCH 2/7] arm64: dts: ls1028a: move Mali DP500 node into /soc
In-Reply-To: <20210831134013.1625527-1-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
Message-ID: <20210831134013.1625527-3-michael@walle.cc>

Move it inside the /soc subnode because it is part of the CCSR space.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 41 ++++++++++---------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 9a65a7118faa..92e4f004c1c2 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -793,6 +793,27 @@ QORIQ_CLK_PLL_DIV(16)>,
 			clock-names = "wdog_clk", "apb_pclk";
 		};
 
+		malidp0: display at f080000 {
+			compatible = "arm,mali-dp500";
+			reg = <0x0 0xf080000 0x0 0x10000>;
+			interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
+				     <0 223 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "DE", "SE";
+			clocks = <&dpclk>,
+				 <&clockgen QORIQ_CLK_HWACCEL 2>,
+				 <&clockgen QORIQ_CLK_HWACCEL 2>,
+				 <&clockgen QORIQ_CLK_HWACCEL 2>;
+			clock-names = "pxlclk", "mclk", "aclk", "pclk";
+			arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
+			arm,malidp-arqos-value = <0xd000d000>;
+
+			port {
+				dpi0_out: endpoint {
+
+				};
+			};
+		};
+
 		sai1: audio-controller at f100000 {
 			#sound-dai-cells = <0>;
 			compatible = "fsl,vf610-sai";
@@ -1139,24 +1160,4 @@ ftm_alarm0: timer at 2800000 {
 		};
 	};
 
-	malidp0: display at f080000 {
-		compatible = "arm,mali-dp500";
-		reg = <0x0 0xf080000 0x0 0x10000>;
-		interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
-			     <0 223 IRQ_TYPE_LEVEL_HIGH>;
-		interrupt-names = "DE", "SE";
-		clocks = <&dpclk>,
-			 <&clockgen QORIQ_CLK_HWACCEL 2>,
-			 <&clockgen QORIQ_CLK_HWACCEL 2>,
-			 <&clockgen QORIQ_CLK_HWACCEL 2>;
-		clock-names = "pxlclk", "mclk", "aclk", "pclk";
-		arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
-		arm,malidp-arqos-value = <0xd000d000>;
-
-		port {
-			dp0_out: endpoint {
-
-			};
-		};
-	};
 };
-- 
2.30.2



From michael at walle.cc  Tue Aug 31 06:40:09 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 15:40:09 +0200
Subject: [PATCH 3/7] arm64: dts: ls1028a: add Vivante GPU node
In-Reply-To: <20210831134013.1625527-1-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
Message-ID: <20210831134013.1625527-4-michael@walle.cc>

Recently, support for this particular Vivante GC7000 GPU was added to the
linux kernel. Add the corresponding device tree node.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 92e4f004c1c2..876dea668a90 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -814,6 +814,17 @@ dpi0_out: endpoint {
 			};
 		};
 
+		gpu: gpu at f0c0000 {
+			compatible = "vivante,gc";
+			reg = <0x0 0xf0c0000 0x0 0x10000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clockgen QORIQ_CLK_HWACCEL 2>,
+				 <&clockgen QORIQ_CLK_HWACCEL 2>,
+				 <&clockgen QORIQ_CLK_HWACCEL 2>;
+			clock-names = "core", "shader", "bus";
+			#cooling-cells = <2>;
+		};
+
 		sai1: audio-controller at f100000 {
 			#sound-dai-cells = <0>;
 			compatible = "fsl,vf610-sai";
-- 
2.30.2



From michael at walle.cc  Tue Aug 31 06:40:10 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 15:40:10 +0200
Subject: [PATCH 4/7] arm64: dts: freescale: fix arm,sp805 compatible string
In-Reply-To: <20210831134013.1625527-1-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
Message-ID: <20210831134013.1625527-5-michael@walle.cc>

According to Documentation/devicetree/bindings/watchdog/arm,sp805.yaml
the compatible is:
  compatible = "arm,sp805", "arm,primecell";

The current compatible string doesn't exist at all. Fix it.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 16 ++++++++--------
 arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 16 ++++++++--------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index f85e437f80b7..605072317243 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -847,7 +847,7 @@ pcs7_3: ethernet-phy at 3 {
 		};
 
 		cluster1_core0_watchdog: wdt at c000000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc000000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -857,7 +857,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster1_core1_watchdog: wdt at c010000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc010000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -867,7 +867,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster1_core2_watchdog: wdt at c020000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc020000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -877,7 +877,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster1_core3_watchdog: wdt at c030000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc030000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -887,7 +887,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster2_core0_watchdog: wdt at c100000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc100000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -897,7 +897,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster2_core1_watchdog: wdt at c110000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc110000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -907,7 +907,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster2_core2_watchdog: wdt at c120000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc120000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
@@ -917,7 +917,7 @@ QORIQ_CLK_PLL_DIV(16)>,
 		};
 
 		cluster2_core3_watchdog: wdt at c130000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc130000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(16)>,
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
index 801ba9612d36..1282b61da8a5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
@@ -387,7 +387,7 @@ serial3: serial at 21d0600 {
 		};
 
 		cluster1_core0_watchdog: wdt at c000000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc000000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -397,7 +397,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster1_core1_watchdog: wdt at c010000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc010000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -407,7 +407,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster2_core0_watchdog: wdt at c100000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc100000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -417,7 +417,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster2_core1_watchdog: wdt at c110000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc110000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -427,7 +427,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster3_core0_watchdog: wdt at c200000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc200000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -437,7 +437,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster3_core1_watchdog: wdt at c210000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc210000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -447,7 +447,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster4_core0_watchdog: wdt at c300000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc300000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
@@ -457,7 +457,7 @@ QORIQ_CLK_PLL_DIV(4)>,
 		};
 
 		cluster4_core1_watchdog: wdt at c310000 {
-			compatible = "arm,sp805-wdt", "arm,primecell";
+			compatible = "arm,sp805", "arm,primecell";
 			reg = <0x0 0xc310000 0x0 0x1000>;
 			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
 					    QORIQ_CLK_PLL_DIV(4)>,
-- 
2.30.2



From michael at walle.cc  Tue Aug 31 06:40:11 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 15:40:11 +0200
Subject: [PATCH 5/7] arm64: dts: ls1028a: disable usb controller by default
In-Reply-To: <20210831134013.1625527-1-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
Message-ID: <20210831134013.1625527-6-michael@walle.cc>

One of the last devices which are enabled by default are the USB
controllers. Although the pins are not multi-function pins, some boards
might not use USB at all. Apply the "disabled-by-default" style also for
the USB controllers and enable the controllers in the actual device tree
of the boards.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 .../arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts | 8 ++++++++
 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts         | 8 ++++++++
 arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts         | 5 +++++
 arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi            | 2 ++
 4 files changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
index a92ecb331cdc..2c6266991c38 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
@@ -309,3 +309,11 @@ eeprom at 50 {
 &lpuart1 {
 	status = "okay";
 };
+
+&usb0 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index bfd14b64567e..f36f87858aef 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -335,3 +335,11 @@ &sai1 {
 &sata {
 	status = "okay";
 };
+
+&usb0 {
+	status = "okay";
+};
+
+&usb1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
index d7b527272500..b0967b987f8a 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
@@ -287,6 +287,11 @@ &sata {
 	status = "okay";
 };
 
+&usb0 {
+	status = "okay";
+};
+
 &usb1 {
 	dr_mode = "otg";
+	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 876dea668a90..c10c84d9495d 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -585,6 +585,7 @@ usb0: usb at 3100000 {
 			snps,dis_rxdet_inp3_quirk;
 			snps,quirk-frame-length-adjustment = <0x20>;
 			snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+			status = "disabled";
 		};
 
 		usb1: usb at 3110000 {
@@ -595,6 +596,7 @@ usb1: usb at 3110000 {
 			snps,dis_rxdet_inp3_quirk;
 			snps,quirk-frame-length-adjustment = <0x20>;
 			snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+			status = "disabled";
 		};
 
 		sata: sata at 3200000 {
-- 
2.30.2



From michael at walle.cc  Tue Aug 31 06:40:12 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 15:40:12 +0200
Subject: [PATCH 6/7] arm64: dts: ls1028a: move PHY nodes to MDIO controller
In-Reply-To: <20210831134013.1625527-1-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
Message-ID: <20210831134013.1625527-7-michael@walle.cc>

Move the PHY nodes from the network controller to the dedicated MDIO
controller. According to Vladimir Oltean direct MDIO access via the PF,
that is when the PHY is put under the "mdio" subnode, is defeatured and
in fact the latest reference manual isn't mentioning it anymore.

Suggested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Signed-off-by: Michael Walle <michael at walle.cc>
---
 .../fsl-ls1028a-kontron-sl28-var1.dts         | 58 +++++++++----------
 .../fsl-ls1028a-kontron-sl28-var2.dts         | 17 ++----
 .../fsl-ls1028a-kontron-sl28-var4.dts         | 49 ++++++++--------
 .../freescale/fsl-ls1028a-kontron-sl28.dts    | 21 +++----
 .../boot/dts/freescale/fsl-ls1028a-rdb.dts    | 12 ++--
 5 files changed, 67 insertions(+), 90 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts
index e8d31279b7a3..836a9b7d8263 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts
@@ -8,7 +8,7 @@
  * None of the  four SerDes lanes are used by the module, instead they are
  * all led out to the carrier for customer use.
  *
- * Copyright (C) 2020 Michael Walle <michael at walle.cc>
+ * Copyright (C) 2021 Michael Walle <michael at walle.cc>
  *
  */
 
@@ -21,43 +21,39 @@ / {
 	compatible = "kontron,sl28-var1", "kontron,sl28", "fsl,ls1028a";
 };
 
+&enetc_mdio_pf3 {
+	/* Delete unused phy node */
+	/delete-node/ ethernet-phy at 5;
+
+	phy0: ethernet-phy at 4 {
+		reg = <0x4>;
+		eee-broken-1000t;
+		eee-broken-100tx;
+		qca,clk-out-frequency = <125000000>;
+		qca,clk-out-strength = <AR803X_STRENGTH_FULL>;
+		qca,keep-pll-enabled;
+		vddio-supply = <&vddio>;
+
+		vddio: vddio-regulator {
+			regulator-name = "VDDIO";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+		vddh: vddh-regulator {
+			regulator-name = "VDDH";
+		};
+	};
+};
+
 &enetc_port0 {
 	status = "disabled";
-	/*
-	 * Delete both the phy-handle to the old phy0 label as well as
-	 * the mdio node with the old phy node with the old phy0 label.
-	 */
+	/* Delete the phy-handle to the old phy0 label */
 	/delete-property/ phy-handle;
-	/delete-node/ mdio;
 };
 
 &enetc_port1 {
 	phy-handle = <&phy0>;
 	phy-connection-type = "rgmii-id";
 	status = "okay";
-
-	mdio {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		phy0: ethernet-phy at 4 {
-			reg = <0x4>;
-			eee-broken-1000t;
-			eee-broken-100tx;
-			qca,clk-out-frequency = <125000000>;
-			qca,clk-out-strength = <AR803X_STRENGTH_FULL>;
-			qca,keep-pll-enabled;
-			vddio-supply = <&vddio>;
-
-			vddio: vddio-regulator {
-				regulator-name = "VDDIO";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
-
-			vddh: vddh-regulator {
-				regulator-name = "VDDH";
-			};
-		};
-	};
 };
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts
index f6a79c8080d1..330e34f933a3 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts
@@ -5,7 +5,7 @@
  * This is for the network variant 2 which has two ethernet ports. These
  * ports are connected to the internal switch.
  *
- * Copyright (C) 2020 Michael Walle <michael at walle.cc>
+ * Copyright (C) 2021 Michael Walle <michael at walle.cc>
  *
  */
 
@@ -18,12 +18,6 @@ / {
 };
 
 &enetc_mdio_pf3 {
-	phy0: ethernet-phy at 5 {
-		reg = <0x5>;
-		eee-broken-1000t;
-		eee-broken-100tx;
-	};
-
 	phy1: ethernet-phy at 4 {
 		reg = <0x4>;
 		eee-broken-1000t;
@@ -34,14 +28,11 @@ phy1: ethernet-phy at 4 {
 &enetc_port0 {
 	status = "disabled";
 	/*
-	 * In the base device tree the PHY was registered in the mdio
-	 * subnode as it is PHY for this port. On this module this PHY
-	 * is connected to a switch port instead and registered above.
-	 * Therefore, delete the mdio subnode as well as the phy-handle
-	 * property here.
+	 * In the base device tree the PHY at address 5 was assigned for
+	 * this port. On this module this PHY is connected to a switch
+	 * port instead. Therefore, delete the phy-handle property here.
 	 */
 	/delete-property/ phy-handle;
-	/delete-node/ mdio;
 };
 
 &enetc_port2 {
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts
index e65d1c477e2c..77ed0ebd2c75 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts
@@ -5,7 +5,7 @@
  * This is for the network variant 4 which has two ethernet ports. It
  * extends the base and provides one more port connected via RGMII.
  *
- * Copyright (C) 2019 Michael Walle <michael at walle.cc>
+ * Copyright (C) 2021 Michael Walle <michael at walle.cc>
  *
  */
 
@@ -18,33 +18,30 @@ / {
 	compatible = "kontron,sl28-var4", "kontron,sl28", "fsl,ls1028a";
 };
 
-&enetc_port1 {
-	phy-handle = <&phy1>;
-	phy-connection-type = "rgmii-id";
-	status = "okay";
+&enetc_mdio_pf3 {
+	phy1: ethernet-phy at 4 {
+		reg = <0x4>;
+		eee-broken-1000t;
+		eee-broken-100tx;
+		qca,clk-out-frequency = <125000000>;
+		qca,clk-out-strength = <AR803X_STRENGTH_FULL>;
+		qca,keep-pll-enabled;
+		vddio-supply = <&vddio>;
 
-	mdio {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		phy1: ethernet-phy at 4 {
-			reg = <0x4>;
-			eee-broken-1000t;
-			eee-broken-100tx;
-			qca,clk-out-frequency = <125000000>;
-			qca,clk-out-strength = <AR803X_STRENGTH_FULL>;
-			qca,keep-pll-enabled;
-			vddio-supply = <&vddio>;
-
-			vddio: vddio-regulator {
-				regulator-name = "VDDIO";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-			};
+		vddio: vddio-regulator {
+			regulator-name = "VDDIO";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
 
-			vddh: vddh-regulator {
-				regulator-name = "VDDH";
-			};
+		vddh: vddh-regulator {
+			regulator-name = "VDDH";
 		};
 	};
 };
+
+&enetc_port1 {
+	phy-handle = <&phy1>;
+	phy-connection-type = "rgmii-id";
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
index 2c6266991c38..b3e9c499e8b0 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
@@ -2,7 +2,7 @@
 /*
  * Device Tree file for the Kontron SMARC-sAL28 board.
  *
- * Copyright (C) 2019 Michael Walle <michael at walle.cc>
+ * Copyright (C) 2021 Michael Walle <michael at walle.cc>
  *
  */
 
@@ -80,22 +80,19 @@ &duart1 {
 	status = "okay";
 };
 
+&enetc_mdio_pf3 {
+	phy0: ethernet-phy at 5 {
+		reg = <0x5>;
+		eee-broken-1000t;
+		eee-broken-100tx;
+	};
+};
+
 &enetc_port0 {
 	phy-handle = <&phy0>;
 	phy-connection-type = "sgmii";
 	managed = "in-band-status";
 	status = "okay";
-
-	mdio {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		phy0: ethernet-phy at 5 {
-			reg = <0x5>;
-			eee-broken-1000t;
-			eee-broken-100tx;
-		};
-	};
 };
 
 &esdhc {
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
index b0967b987f8a..ea11b1eb01f8 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
@@ -197,6 +197,10 @@ &duart1 {
 };
 
 &enetc_mdio_pf3 {
+	sgmii_phy0: ethernet-phy at 2 {
+		reg = <0x2>;
+	};
+
 	/* VSC8514 QSGMII quad PHY */
 	qsgmii_phy0: ethernet-phy at 10 {
 		reg = <0x10>;
@@ -220,14 +224,6 @@ &enetc_port0 {
 	phy-connection-type = "sgmii";
 	managed = "in-band-status";
 	status = "okay";
-
-	mdio {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		sgmii_phy0: ethernet-phy at 2 {
-			reg = <0x2>;
-		};
-	};
 };
 
 &enetc_port2 {
-- 
2.30.2



From michael at walle.cc  Tue Aug 31 06:40:13 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 15:40:13 +0200
Subject: [PATCH 7/7] arm64: dts: ls1028a: use phy-mode instead of
 phy-connection-type
In-Reply-To: <20210831134013.1625527-1-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
Message-ID: <20210831134013.1625527-8-michael@walle.cc>

In linux both are identical, phy-mode is used more often, though. Also
for the ls1028a both phy-connection-type and phy-mode was used, one for
the enetc nodes and the other for the switch nodes. Unify them. But the
main reason for this is that the device tree files can be shared with
the u-boot ones; there the enetc driver only supports the "phy-mode"
property.

Suggested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts | 2 +-
 arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts | 2 +-
 arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts      | 2 +-
 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts               | 2 +-
 arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts               | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts
index 836a9b7d8263..7cd29ab970d9 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts
@@ -54,6 +54,6 @@ &enetc_port0 {
 
 &enetc_port1 {
 	phy-handle = <&phy0>;
-	phy-connection-type = "rgmii-id";
+	phy-mode = "rgmii-id";
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts
index 77ed0ebd2c75..9b5e92fb753e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts
@@ -42,6 +42,6 @@ vddh: vddh-regulator {
 
 &enetc_port1 {
 	phy-handle = <&phy1>;
-	phy-connection-type = "rgmii-id";
+	phy-mode = "rgmii-id";
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
index b3e9c499e8b0..d74e738e4070 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
@@ -90,7 +90,7 @@ phy0: ethernet-phy at 5 {
 
 &enetc_port0 {
 	phy-handle = <&phy0>;
-	phy-connection-type = "sgmii";
+	phy-mode = "sgmii";
 	managed = "in-band-status";
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index f36f87858aef..6e2a1da662fb 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -320,7 +320,7 @@ mux: mux-controller {
 
 &enetc_port1 {
 	phy-handle = <&qds_phy1>;
-	phy-connection-type = "rgmii-id";
+	phy-mode = "rgmii-id";
 	status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
index ea11b1eb01f8..7719f44bcaed 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
@@ -221,7 +221,7 @@ qsgmii_phy3: ethernet-phy at 13 {
 
 &enetc_port0 {
 	phy-handle = <&sgmii_phy0>;
-	phy-connection-type = "sgmii";
+	phy-mode = "sgmii";
 	managed = "in-band-status";
 	status = "okay";
 };
-- 
2.30.2



From fabrice.gasnier at foss.st.com  Tue Aug 31 06:40:37 2021
From: fabrice.gasnier at foss.st.com (Fabrice Gasnier)
Date: Tue, 31 Aug 2021 15:40:37 +0200
Subject: [PATCH v16 02/14] counter: stm32-timer-cnt: Provide defines for
 slave mode selection
In-Reply-To: <ad3d9cd7af580d586316d368f74964cbc394f981.1630031207.git.vilhelm.gray@gmail.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
 <ad3d9cd7af580d586316d368f74964cbc394f981.1630031207.git.vilhelm.gray@gmail.com>
Message-ID: <ad245fd3-5751-08e6-3f3a-30522822f0af@foss.st.com>

On 8/27/21 5:47 AM, William Breathitt Gray wrote:
> The STM32 timer permits configuration of the counter encoder mode via
> the slave mode control register (SMCR) slave mode selection (SMS) bits.
> This patch provides preprocessor defines for the supported encoder
> modes.
> 
> Cc: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
> ---
>  drivers/counter/stm32-timer-cnt.c | 16 ++++++++--------
>  include/linux/mfd/stm32-timers.h  |  4 ++++
>  2 files changed, 12 insertions(+), 8 deletions(-)

Hi William,

You can add my:
Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>

Thanks,
Fabrice

> 
> diff --git a/drivers/counter/stm32-timer-cnt.c b/drivers/counter/stm32-timer-cnt.c
> index 3fb0debd7425..1fbc46f4ee66 100644
> --- a/drivers/counter/stm32-timer-cnt.c
> +++ b/drivers/counter/stm32-timer-cnt.c
> @@ -93,16 +93,16 @@ static int stm32_count_function_get(struct counter_device *counter,
>  	regmap_read(priv->regmap, TIM_SMCR, &smcr);
>  
>  	switch (smcr & TIM_SMCR_SMS) {
> -	case 0:
> +	case TIM_SMCR_SMS_SLAVE_MODE_DISABLED:
>  		*function = STM32_COUNT_SLAVE_MODE_DISABLED;
>  		return 0;
> -	case 1:
> +	case TIM_SMCR_SMS_ENCODER_MODE_1:
>  		*function = STM32_COUNT_ENCODER_MODE_1;
>  		return 0;
> -	case 2:
> +	case TIM_SMCR_SMS_ENCODER_MODE_2:
>  		*function = STM32_COUNT_ENCODER_MODE_2;
>  		return 0;
> -	case 3:
> +	case TIM_SMCR_SMS_ENCODER_MODE_3:
>  		*function = STM32_COUNT_ENCODER_MODE_3;
>  		return 0;
>  	default:
> @@ -119,16 +119,16 @@ static int stm32_count_function_set(struct counter_device *counter,
>  
>  	switch (function) {
>  	case STM32_COUNT_SLAVE_MODE_DISABLED:
> -		sms = 0;
> +		sms = TIM_SMCR_SMS_SLAVE_MODE_DISABLED;
>  		break;
>  	case STM32_COUNT_ENCODER_MODE_1:
> -		sms = 1;
> +		sms = TIM_SMCR_SMS_ENCODER_MODE_1;
>  		break;
>  	case STM32_COUNT_ENCODER_MODE_2:
> -		sms = 2;
> +		sms = TIM_SMCR_SMS_ENCODER_MODE_2;
>  		break;
>  	case STM32_COUNT_ENCODER_MODE_3:
> -		sms = 3;
> +		sms = TIM_SMCR_SMS_ENCODER_MODE_3;
>  		break;
>  	default:
>  		return -EINVAL;
> diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
> index f8db83aedb2b..5f5c43fd69dd 100644
> --- a/include/linux/mfd/stm32-timers.h
> +++ b/include/linux/mfd/stm32-timers.h
> @@ -82,6 +82,10 @@
>  #define MAX_TIM_ICPSC		0x3
>  #define TIM_CR2_MMS_SHIFT	4
>  #define TIM_CR2_MMS2_SHIFT	20
> +#define TIM_SMCR_SMS_SLAVE_MODE_DISABLED	0 /* counts on internal clock when CEN=1 */
> +#define TIM_SMCR_SMS_ENCODER_MODE_1		1 /* counts TI1FP1 edges, depending on TI2FP2 level */
> +#define TIM_SMCR_SMS_ENCODER_MODE_2		2 /* counts TI2FP2 edges, depending on TI1FP1 level */
> +#define TIM_SMCR_SMS_ENCODER_MODE_3		3 /* counts on both TI1FP1 and TI2FP2 edges */
>  #define TIM_SMCR_TS_SHIFT	4
>  #define TIM_BDTR_BKF_MASK	0xF
>  #define TIM_BDTR_BKF_SHIFT(x)	(16 + (x) * 4)
> 


From robh+dt at kernel.org  Tue Aug 31 06:50:14 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 08:50:14 -0500
Subject: [PATCH v2 2/2] ARM: dts: bcm2711-rpi-4-b: Fix usb's unit address
In-Reply-To: <20210831125843.1233488-2-nsaenzju@redhat.com>
References: <20210831125843.1233488-1-nsaenzju@redhat.com>
 <20210831125843.1233488-2-nsaenzju@redhat.com>
Message-ID: <CAL_JsqL-CdrAqY_4vnXQfTuSU8GsYzZutyFhZZgm4o3p-qaqFA@mail.gmail.com>

On Tue, Aug 31, 2021 at 7:59 AM Nicolas Saenz Julienne
<nsaenzju at redhat.com> wrote:
>
> The unit address is supposed to represent '<device>,<function>'. Which
> are both 0 for RPi4b's XHCI controller. On top of that although
> OpenFirmware states bus number goes in the high part of the last reg
> parameter, FDT doesn't seem to care for it[1], so remove it.
>
> [1] https://patchwork.kernel.org/project/linux-arm-kernel/patch/20210830103909.323356-1-nsaenzju at redhat.com/#24414633
> Fixes: 258f92d2f840 ("ARM: dts: bcm2711: Add reset controller to xHCI node")
> Suggested-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
> ---
>
> Chages since v1:
>  - Add patch as per robh suggestion
>
>  arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Rob Herring <robh at kernel.org>


From robh+dt at kernel.org  Tue Aug 31 06:50:34 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 08:50:34 -0500
Subject: [PATCH v2 1/2] ARM: dts: bcm2711-rpi-4-b: Fix pcie0's unit
 address formatting
In-Reply-To: <20210831125843.1233488-1-nsaenzju@redhat.com>
References: <20210831125843.1233488-1-nsaenzju@redhat.com>
Message-ID: <CAL_Jsq+R06nrnzuY8MxpCsxzcmTg1NW2L5eSNxM2ne+GqwMdgQ@mail.gmail.com>

On Tue, Aug 31, 2021 at 7:59 AM Nicolas Saenz Julienne
<nsaenzju at redhat.com> wrote:
>
> dtbs_check currently complains that:
>
> arch/arm/boot/dts/bcm2711-rpi-4-b.dts:220.10-231.4: Warning
> (pci_device_reg): /scb/pcie at 7d500000/pci at 1,0: PCI unit address format
> error, expected "0,0"
>
> Unsurprisingly pci at 0,0 is the right address, as illustrated by its reg
> property:
>
>     &pcie0 {
>             pci at 0,0 {
>                     /*
>                      * As defined in the IEEE Std 1275-1994 document,
>                      * reg is a five-cell address encoded as (phys.hi
>                      * phys.mid phys.lo size.hi size.lo). phys.hi
>                      * should contain the device's BDF as 0b00000000
>                      * bbbbbbbb dddddfff 00000000. The other cells
>                      * should be zero.
>                      */
>                     reg = <0 0 0 0 0>;
>             };
>     };
>
> The device is clearly 0. So fix it.
>
> Also add a missing 'device_type = "pci"'.
>
> Fixes: 258f92d2f840 ("ARM: dts: bcm2711: Add reset controller to xHCI node")
> Suggested-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
> ---
>
> Changes since v1:
>  - s/bus/device/ when talking about unit addresses
>  - Add device_type
>  - Add Suggested-by
>
>  arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Rob Herring <robh at kernel.org>


From caihuoqing at baidu.com  Tue Aug 31 06:55:52 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 21:55:52 +0800
Subject: [PATCH] drm/imx: imx-tve: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210831135553.4426-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/gpu/drm/imx/imx-tve.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index bc8c3f802a15..2b1fdf2cbbce 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -526,7 +526,6 @@ static int imx_tve_probe(struct platform_device *pdev)
 	struct device_node *np = dev->of_node;
 	struct device_node *ddc_node;
 	struct imx_tve *tve;
-	struct resource *res;
 	void __iomem *base;
 	unsigned int val;
 	int irq;
@@ -568,8 +567,7 @@ static int imx_tve_probe(struct platform_device *pdev)
 		}
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	base = devm_ioremap_resource(dev, res);
+	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 06:56:16 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 21:56:16 +0800
Subject: [PATCH] drm/mediatek: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210831135617.4526-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/gpu/drm/mediatek/mtk_cec.c        | 4 +---
 drivers/gpu/drm/mediatek/mtk_disp_aal.c   | 4 +---
 drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 4 +---
 drivers/gpu/drm/mediatek/mtk_disp_color.c | 4 +---
 drivers/gpu/drm/mediatek/mtk_disp_gamma.c | 4 +---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c   | 4 +---
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c  | 4 +---
 drivers/gpu/drm/mediatek/mtk_dpi.c        | 4 +---
 drivers/gpu/drm/mediatek/mtk_dsi.c        | 4 +---
 drivers/gpu/drm/mediatek/mtk_hdmi.c       | 4 +---
 10 files changed, 10 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c
index e9cef5c0c8f7..7b5f28f63c65 100644
--- a/drivers/gpu/drm/mediatek/mtk_cec.c
+++ b/drivers/gpu/drm/mediatek/mtk_cec.c
@@ -183,7 +183,6 @@ static int mtk_cec_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_cec *cec;
-	struct resource *res;
 	int ret;
 
 	cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
@@ -193,8 +192,7 @@ static int mtk_cec_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, cec);
 	spin_lock_init(&cec->lock);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	cec->regs = devm_ioremap_resource(dev, res);
+	cec->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(cec->regs)) {
 		ret = PTR_ERR(cec->regs);
 		dev_err(dev, "Failed to ioremap cec: %d\n", ret);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_aal.c b/drivers/gpu/drm/mediatek/mtk_disp_aal.c
index dadd1afed076..3a5bc05a57c1 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_aal.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_aal.c
@@ -102,7 +102,6 @@ static int mtk_disp_aal_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_disp_aal *priv;
-	struct resource *res;
 	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -115,8 +114,7 @@ static int mtk_disp_aal_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = devm_ioremap_resource(dev, res);
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->regs)) {
 		dev_err(dev, "failed to ioremap aal\n");
 		return PTR_ERR(priv->regs);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
index 141cb36b9c07..3520f735e9e3 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
@@ -158,7 +158,6 @@ static int mtk_disp_ccorr_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_disp_ccorr *priv;
-	struct resource *res;
 	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -171,8 +170,7 @@ static int mtk_disp_ccorr_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = devm_ioremap_resource(dev, res);
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->regs)) {
 		dev_err(dev, "failed to ioremap ccorr\n");
 		return PTR_ERR(priv->regs);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
index 473f5bb5cbad..3050f6851511 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_color.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c
@@ -96,7 +96,6 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_disp_color *priv;
-	struct resource *res;
 	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -109,8 +108,7 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = devm_ioremap_resource(dev, res);
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->regs)) {
 		dev_err(dev, "failed to ioremap color\n");
 		return PTR_ERR(priv->regs);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
index 3a5815ab4079..b891e33d5adc 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c
@@ -129,7 +129,6 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_disp_gamma *priv;
-	struct resource *res;
 	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -142,8 +141,7 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = devm_ioremap_resource(dev, res);
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->regs)) {
 		dev_err(dev, "failed to ioremap gamma\n");
 		return PTR_ERR(priv->regs);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 5326989d5206..da6c09122836 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -374,7 +374,6 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_disp_ovl *priv;
-	struct resource *res;
 	int irq;
 	int ret;
 
@@ -392,8 +391,7 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = devm_ioremap_resource(dev, res);
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->regs)) {
 		dev_err(dev, "failed to ioremap ovl\n");
 		return PTR_ERR(priv->regs);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 75d7f45579e2..e1a79db0ee87 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -272,7 +272,6 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_disp_rdma *priv;
-	struct resource *res;
 	int irq;
 	int ret;
 
@@ -290,8 +289,7 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = devm_ioremap_resource(dev, res);
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->regs)) {
 		dev_err(dev, "failed to ioremap rdma\n");
 		return PTR_ERR(priv->regs);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 4554e2de1430..1a226b16ae67 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -827,7 +827,6 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_dpi *dpi;
-	struct resource *mem;
 	int ret;
 
 	dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
@@ -858,8 +857,7 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 			dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n");
 		}
 	}
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dpi->regs = devm_ioremap_resource(dev, mem);
+	dpi->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dpi->regs)) {
 		ret = PTR_ERR(dpi->regs);
 		dev_err(dev, "Failed to ioremap mem resource: %d\n", ret);
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 93b40c245f00..a5ced78e81fd 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1002,7 +1002,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	struct mtk_dsi *dsi;
 	struct device *dev = &pdev->dev;
 	struct drm_panel *panel;
-	struct resource *regs;
 	int irq_num;
 	int ret;
 
@@ -1058,8 +1057,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 		goto err_unregister_host;
 	}
 
-	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dsi->regs = devm_ioremap_resource(dev, regs);
+	dsi->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dsi->regs)) {
 		ret = PTR_ERR(dsi->regs);
 		dev_err(dev, "Failed to ioremap memory: %d\n", ret);
diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
index 5838c44cbf6f..6ff0ae4f3634 100644
--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
@@ -1426,7 +1426,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 	struct device_node *cec_np, *remote, *i2c_np;
 	struct platform_device *cec_pdev;
 	struct regmap *regmap;
-	struct resource *mem;
 	int ret;
 
 	ret = mtk_hdmi_get_all_clk(hdmi, np);
@@ -1472,8 +1471,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
 	}
 	hdmi->sys_regmap = regmap;
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi->regs = devm_ioremap_resource(dev, mem);
+	hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hdmi->regs)) {
 		ret = PTR_ERR(hdmi->regs);
 		goto put_device;
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 06:56:43 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 21:56:43 +0800
Subject: [PATCH] drm/meson: Make use of the helper function
 devm_platform_ioremap_resourcexxx()
Message-ID: <20210831135644.4576-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/gpu/drm/meson/meson_drv.c     | 3 +--
 drivers/gpu/drm/meson/meson_dw_hdmi.c | 4 +---
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index bc0d60df04ae..7f41a33592c8 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -206,8 +206,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 	priv->compat = match->compat;
 	priv->afbcd.ops = match->afbcd_ops;
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu");
-	regs = devm_ioremap_resource(dev, res);
+	regs = devm_platform_ioremap_resource_byname(pdev, "vpu");
 	if (IS_ERR(regs)) {
 		ret = PTR_ERR(regs);
 		goto free_drm;
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index 2ed87cfdd735..0afbd1e70bfc 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -978,7 +978,6 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
 	struct dw_hdmi_plat_data *dw_plat_data;
 	struct drm_bridge *next_bridge;
 	struct drm_encoder *encoder;
-	struct resource *res;
 	int irq;
 	int ret;
 
@@ -1042,8 +1041,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
 		return PTR_ERR(meson_dw_hdmi->hdmitx_phy);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res);
+	meson_dw_hdmi->hdmitx = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(meson_dw_hdmi->hdmitx))
 		return PTR_ERR(meson_dw_hdmi->hdmitx);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 06:56:54 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 21:56:54 +0800
Subject: [PATCH] drm/mxsfb: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210831135654.4626-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/gpu/drm/mxsfb/mxsfb_drv.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index ec0432fe1bdf..86938d24b32f 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -200,7 +200,6 @@ static int mxsfb_load(struct drm_device *drm,
 {
 	struct platform_device *pdev = to_platform_device(drm->dev);
 	struct mxsfb_drm_private *mxsfb;
-	struct resource *res;
 	int ret;
 
 	mxsfb = devm_kzalloc(&pdev->dev, sizeof(*mxsfb), GFP_KERNEL);
@@ -211,8 +210,7 @@ static int mxsfb_load(struct drm_device *drm,
 	drm->dev_private = mxsfb;
 	mxsfb->devdata = devdata;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mxsfb->base = devm_ioremap_resource(drm->dev, res);
+	mxsfb->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mxsfb->base))
 		return PTR_ERR(mxsfb->base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 06:57:21 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 21:57:21 +0800
Subject: [PATCH] drm/rockchip: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210831135721.4726-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/gpu/drm/rockchip/cdn-dp-core.c   | 4 +---
 drivers/gpu/drm/rockchip/inno_hdmi.c     | 4 +---
 drivers/gpu/drm/rockchip/rockchip_lvds.c | 4 +---
 3 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 8ab3247dbc4a..5dce875dbd11 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -697,7 +697,6 @@ static int cdn_dp_parse_dt(struct cdn_dp_device *dp)
 	struct device *dev = dp->dev;
 	struct device_node *np = dev->of_node;
 	struct platform_device *pdev = to_platform_device(dev);
-	struct resource *res;
 
 	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
 	if (IS_ERR(dp->grf)) {
@@ -705,8 +704,7 @@ static int cdn_dp_parse_dt(struct cdn_dp_device *dp)
 		return PTR_ERR(dp->grf);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dp->regs = devm_ioremap_resource(dev, res);
+	dp->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dp->regs)) {
 		DRM_DEV_ERROR(dev, "ioremap reg failed\n");
 		return PTR_ERR(dp->regs);
diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
index 7afdc54eb3ec..046e8ec2a71c 100644
--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -810,7 +810,6 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
 	struct platform_device *pdev = to_platform_device(dev);
 	struct drm_device *drm = data;
 	struct inno_hdmi *hdmi;
-	struct resource *iores;
 	int irq;
 	int ret;
 
@@ -821,8 +820,7 @@ static int inno_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->dev = dev;
 	hdmi->drm_dev = drm;
 
-	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi->regs = devm_ioremap_resource(dev, iores);
+	hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hdmi->regs))
 		return PTR_ERR(hdmi->regs);
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
index 551653940e39..50574649a472 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -439,11 +439,9 @@ struct drm_encoder_helper_funcs px30_lvds_encoder_helper_funcs = {
 static int rk3288_lvds_probe(struct platform_device *pdev,
 			     struct rockchip_lvds *lvds)
 {
-	struct resource *res;
 	int ret;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	lvds->regs = devm_ioremap_resource(lvds->dev, res);
+	lvds->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(lvds->regs))
 		return PTR_ERR(lvds->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 06:57:39 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Tue, 31 Aug 2021 21:57:39 +0800
Subject: [PATCH] drm/sun4i: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210831135740.4826-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/gpu/drm/sun4i/sun4i_backend.c  | 4 +---
 drivers/gpu/drm/sun4i/sun4i_frontend.c | 4 +---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 4 +---
 drivers/gpu/drm/sun4i/sun4i_tcon.c     | 4 +---
 drivers/gpu/drm/sun4i/sun4i_tv.c       | 4 +---
 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 4 +---
 drivers/gpu/drm/sun4i/sun8i_mixer.c    | 4 +---
 drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 4 +---
 8 files changed, 8 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index bf8cfefa0365..f52ff4e6c662 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -782,7 +782,6 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
 	struct sun4i_drv *drv = drm->dev_private;
 	struct sun4i_backend *backend;
 	const struct sun4i_backend_quirks *quirks;
-	struct resource *res;
 	void __iomem *regs;
 	int i, ret;
 
@@ -815,8 +814,7 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
 	if (IS_ERR(backend->frontend))
 		dev_warn(dev, "Couldn't find matching frontend, frontend features disabled\n");
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	regs = devm_ioremap_resource(dev, res);
+	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
 		return PTR_ERR(regs);
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_frontend.c b/drivers/gpu/drm/sun4i/sun4i_frontend.c
index edb60ae0a9b7..56ae38389db0 100644
--- a/drivers/gpu/drm/sun4i/sun4i_frontend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_frontend.c
@@ -561,7 +561,6 @@ static int sun4i_frontend_bind(struct device *dev, struct device *master,
 	struct sun4i_frontend *frontend;
 	struct drm_device *drm = data;
 	struct sun4i_drv *drv = drm->dev_private;
-	struct resource *res;
 	void __iomem *regs;
 
 	frontend = devm_kzalloc(dev, sizeof(*frontend), GFP_KERNEL);
@@ -576,8 +575,7 @@ static int sun4i_frontend_bind(struct device *dev, struct device *master,
 	if (!frontend->data)
 		return -ENODEV;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	regs = devm_ioremap_resource(dev, res);
+	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
 		return PTR_ERR(regs);
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 2f2c9f0a1071..3799a745b7dd 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -489,7 +489,6 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	struct cec_connector_info conn_info;
 	struct sun4i_drv *drv = drm->dev_private;
 	struct sun4i_hdmi *hdmi;
-	struct resource *res;
 	u32 reg;
 	int ret;
 
@@ -504,8 +503,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
 	if (!hdmi->variant)
 		return -EINVAL;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hdmi->base = devm_ioremap_resource(dev, res);
+	hdmi->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(hdmi->base)) {
 		dev_err(dev, "Couldn't map the HDMI encoder registers\n");
 		return PTR_ERR(hdmi->base);
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 9f06dec0fc61..88db2d2a9336 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -841,11 +841,9 @@ static int sun4i_tcon_init_regmap(struct device *dev,
 				  struct sun4i_tcon *tcon)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	struct resource *res;
 	void __iomem *regs;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	regs = devm_ioremap_resource(dev, res);
+	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
 		return PTR_ERR(regs);
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index cb91bc11a0c7..94883abe0dfd 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -538,7 +538,6 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,
 	struct drm_device *drm = data;
 	struct sun4i_drv *drv = drm->dev_private;
 	struct sun4i_tv *tv;
-	struct resource *res;
 	void __iomem *regs;
 	int ret;
 
@@ -548,8 +547,7 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,
 	tv->drv = drv;
 	dev_set_drvdata(dev, tv);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	regs = devm_ioremap_resource(dev, res);
+	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs)) {
 		dev_err(dev, "Couldn't map the TV encoder registers\n");
 		return PTR_ERR(regs);
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 4f5efcace68e..4371684697bd 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -1104,7 +1104,6 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	const char *bus_clk_name = NULL;
 	struct sun6i_dsi *dsi;
-	struct resource *res;
 	void __iomem *base;
 	int ret;
 
@@ -1120,8 +1119,7 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
 				    "allwinner,sun6i-a31-mipi-dsi"))
 		bus_clk_name = "bus";
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	base = devm_ioremap_resource(dev, res);
+	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base)) {
 		dev_err(dev, "Couldn't map the DSI encoder registers\n");
 		return PTR_ERR(base);
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c
index 5b42cf25cc86..f5e8aeaa3cdf 100644
--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
@@ -337,7 +337,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	struct drm_device *drm = data;
 	struct sun4i_drv *drv = drm->dev_private;
 	struct sun8i_mixer *mixer;
-	struct resource *res;
 	void __iomem *regs;
 	unsigned int base;
 	int plane_cnt;
@@ -390,8 +389,7 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master,
 	if (!mixer->cfg)
 		return -EINVAL;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	regs = devm_ioremap_resource(dev, res);
+	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
 		return PTR_ERR(regs);
 
diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
index 75d8e60c149d..1b9b8b48f4a7 100644
--- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
+++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c
@@ -128,7 +128,6 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
 	struct clk_hw_onecell_data *clk_data;
 	struct sun8i_tcon_top *tcon_top;
 	const struct sun8i_tcon_top_quirks *quirks;
-	struct resource *res;
 	void __iomem *regs;
 	int ret, i;
 
@@ -158,8 +157,7 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master,
 		return PTR_ERR(tcon_top->bus);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	regs = devm_ioremap_resource(dev, res);
+	regs = devm_platform_ioremap_resource(pdev, 0);
 	tcon_top->regs = regs;
 	if (IS_ERR(regs))
 		return PTR_ERR(regs);
-- 
2.25.1



From vladimir.oltean at nxp.com  Tue Aug 31 06:59:17 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Tue, 31 Aug 2021 13:59:17 +0000
Subject: [PATCH 7/7] arm64: dts: ls1028a: use phy-mode instead of
 phy-connection-type
In-Reply-To: <20210831134013.1625527-8-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
 <20210831134013.1625527-8-michael@walle.cc>
Message-ID: <20210831135916.ccvyc5intxs7rlal@skbuf>

On Tue, Aug 31, 2021 at 03:40:13PM +0200, Michael Walle wrote:
> In linux both are identical, phy-mode is used more often, though. Also
> for the ls1028a both phy-connection-type and phy-mode was used, one for
> the enetc nodes and the other for the switch nodes. Unify them. But the
> main reason for this is that the device tree files can be shared with
> the u-boot ones; there the enetc driver only supports the "phy-mode"
> property.
> 
> Suggested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---

Actually that is not really a valid reason in itself for this change.
The enetc U-Boot driver is perhaps a bit silly in that it calls
ofnode_read_string(dev_ofnode(dev), "phy-mode") manually, especially
since right below, it uses dm_eth_phy_connect() which searches for both.

So we are artificially restricting what we support. It would be fine to
do the dm_eth_phy_connect first, then use phy->interface for enetc_start_pcs().

Anyway, I do not mind the patch at all.

Reviewed-by: Vladimir Oltean <vladimir.oltean at nxp.com>

From michael at walle.cc  Tue Aug 31 07:06:21 2021
From: michael at walle.cc (Michael Walle)
Date: Tue, 31 Aug 2021 16:06:21 +0200
Subject: [PATCH 7/7] arm64: dts: ls1028a: use phy-mode instead of
 phy-connection-type
In-Reply-To: <20210831135916.ccvyc5intxs7rlal@skbuf>
References: <20210831134013.1625527-1-michael@walle.cc>
 <20210831134013.1625527-8-michael@walle.cc>
 <20210831135916.ccvyc5intxs7rlal@skbuf>
Message-ID: <c352291c7a88af21b766e33d244b835d@walle.cc>

Am 2021-08-31 15:59, schrieb Vladimir Oltean:
> On Tue, Aug 31, 2021 at 03:40:13PM +0200, Michael Walle wrote:
>> In linux both are identical, phy-mode is used more often, though. Also
>> for the ls1028a both phy-connection-type and phy-mode was used, one 
>> for
>> the enetc nodes and the other for the switch nodes. Unify them. But 
>> the
>> main reason for this is that the device tree files can be shared with
>> the u-boot ones; there the enetc driver only supports the "phy-mode"
>> property.
>> 
>> Suggested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
>> Signed-off-by: Michael Walle <michael at walle.cc>
>> ---
> 
> Actually that is not really a valid reason in itself for this change.
> The enetc U-Boot driver is perhaps a bit silly in that it calls
> ofnode_read_string(dev_ofnode(dev), "phy-mode") manually, especially
> since right below, it uses dm_eth_phy_connect() which searches for 
> both.
> 
> So we are artificially restricting what we support. It would be fine to
> do the dm_eth_phy_connect first, then use phy->interface for 
> enetc_start_pcs().

You mean in u-boot. I had a patch for it, but because you suggested
to convert it to the new property name, it isn't really needed anyway.
u-boot is just using the device trees within its source tree, so I
didn't care anymore ;)

> Anyway, I do not mind the patch at all.
> 
> Reviewed-by: Vladimir Oltean <vladimir.oltean at nxp.com>
Thanks!

-michael


From vladimir.oltean at nxp.com  Tue Aug 31 07:07:08 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Tue, 31 Aug 2021 14:07:08 +0000
Subject: [PATCH 6/7] arm64: dts: ls1028a: move PHY nodes to MDIO controller
In-Reply-To: <20210831134013.1625527-7-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
 <20210831134013.1625527-7-michael@walle.cc>
Message-ID: <20210831140707.d2zdt4cxa7yllxzh@skbuf>

On Tue, Aug 31, 2021 at 03:40:12PM +0200, Michael Walle wrote:
> Move the PHY nodes from the network controller to the dedicated MDIO
> controller. According to Vladimir Oltean direct MDIO access via the PF,
> that is when the PHY is put under the "mdio" subnode, is defeatured and
> in fact the latest reference manual isn't mentioning it anymore.
> 
> Suggested-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---

Reviewed-by: Vladimir Oltean <vladimir.oltean at nxp.com>

From vladimir.oltean at nxp.com  Tue Aug 31 07:08:32 2021
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Tue, 31 Aug 2021 14:08:32 +0000
Subject: [PATCH 5/7] arm64: dts: ls1028a: disable usb controller by default
In-Reply-To: <20210831134013.1625527-6-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
 <20210831134013.1625527-6-michael@walle.cc>
Message-ID: <20210831140831.vouhwnwpgndwfblh@skbuf>

On Tue, Aug 31, 2021 at 03:40:11PM +0200, Michael Walle wrote:
> One of the last devices which are enabled by default are the USB
> controllers. Although the pins are not multi-function pins, some boards
> might not use USB at all. Apply the "disabled-by-default" style also for
> the USB controllers and enable the controllers in the actual device tree
> of the boards.
> 
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---

Reviewed-by: Vladimir Oltean <vladimir.oltean at nxp.com>

From vilhelm.gray at gmail.com  Tue Aug 31 07:16:59 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue, 31 Aug 2021 23:16:59 +0900
Subject: [Linux-stm32] [PATCH v16 03/14] counter: Internalize sysfs
 interface code
In-Reply-To: <fcff44a7-5ac2-a510-ee9b-85ef7e2e29ef@foss.st.com>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
 <c68b4a1ffb195c1a2f65e8dd5ad7b7c14e79c6ef.1630031207.git.vilhelm.gray@gmail.com>
 <fcff44a7-5ac2-a510-ee9b-85ef7e2e29ef@foss.st.com>
Message-ID: <YS452wJ+IHs9R0FC@shinobu>

On Tue, Aug 31, 2021 at 03:44:04PM +0200, Fabrice Gasnier wrote:
> On 8/27/21 5:47 AM, William Breathitt Gray wrote:
> > This is a reimplementation of the Generic Counter driver interface.
> > There are no modifications to the Counter subsystem userspace interface,
> > so existing userspace applications should continue to run seamlessly.
> > 
> > The purpose of this patch is to internalize the sysfs interface code
> > among the various counter drivers into a shared module. Counter drivers
> > pass and take data natively (i.e. u8, u64, etc.) and the shared counter
> > module handles the translation between the sysfs interface and the
> > device drivers. This guarantees a standard userspace interface for all
> > counter drivers, and helps generalize the Generic Counter driver ABI in
> > order to support the Generic Counter chrdev interface (introduced in a
> > subsequent patch) without significant changes to the existing counter
> > drivers.
> > 
> > Note, Counter device registration is the same as before: drivers
> > populate a struct counter_device with components and callbacks, then
> > pass the structure to the devm_counter_register function. However,
> > what's different now is how the Counter subsystem code handles this
> > registration internally.
> > 
> > Whereas before callbacks would interact directly with sysfs data, this
> > interaction is now abstracted and instead callbacks interact with native
> > C data types. The counter_comp structure forms the basis for Counter
> > extensions.
> > 
> > The counter-sysfs.c file contains the code to parse through the
> > counter_device structure and register the requested components and
> > extensions. Attributes are created and populated based on type, with
> > respective translation functions to handle the mapping between sysfs and
> > the counter driver callbacks.
> > 
> > The translation performed for each attribute is straightforward: the
> > attribute type and data is parsed from the counter_attribute structure,
> > the respective counter driver read/write callback is called, and sysfs
> > I/O is handled before or after the driver read/write function is called.
> > 
> > Cc: Jarkko Nikula <jarkko.nikula at linux.intel.com>
> > Cc: Patrick Havelange <patrick.havelange at essensium.com>
> > Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
> > Cc: Fabrice Gasnier <fabrice.gasnier at st.com>
> > Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> > Cc: Alexandre Torgue <alexandre.torgue at st.com>
> > Cc: Dan Carpenter <dan.carpenter at oracle.com>
> > Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> > Reviewed-by: David Lechner <david at lechnology.com>
> > Tested-by: David Lechner <david at lechnology.com>
> > Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
> > ---
> >  MAINTAINERS                             |    1 -
> >  drivers/counter/104-quad-8.c            |  449 +++----
> >  drivers/counter/Makefile                |    1 +
> >  drivers/counter/counter-core.c          |  142 +++
> >  drivers/counter/counter-sysfs.c         |  849 +++++++++++++
> >  drivers/counter/counter-sysfs.h         |   13 +
> >  drivers/counter/counter.c               | 1496 -----------------------
> >  drivers/counter/ftm-quaddec.c           |   60 +-
> >  drivers/counter/intel-qep.c             |  144 +--
> >  drivers/counter/interrupt-cnt.c         |   62 +-
> >  drivers/counter/microchip-tcb-capture.c |   91 +-
> >  drivers/counter/stm32-lptimer-cnt.c     |  212 ++--
> >  drivers/counter/stm32-timer-cnt.c       |  179 ++-
> >  drivers/counter/ti-eqep.c               |  180 +--
> >  include/linux/counter.h                 |  658 +++++-----
> >  include/linux/counter_enum.h            |   45 -
> >  16 files changed, 1949 insertions(+), 2633 deletions(-)
> >  create mode 100644 drivers/counter/counter-core.c
> >  create mode 100644 drivers/counter/counter-sysfs.c
> >  create mode 100644 drivers/counter/counter-sysfs.h
> >  delete mode 100644 drivers/counter/counter.c
> >  delete mode 100644 include/linux/counter_enum.h
> > 
> 
> Hi William,
> 
> For the STM32 drivers, you can add my:
> Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> 
> Thanks,
> Fabrice

Hello Fabrice,

I noticed the stm32-lptimer-cnt.c function_write() and action_write()
callbacks do not appear to write the desired function/action
configuration to the device. Would you check whether the device actually
supports this functionality or if these callbacks should be removed from
this driver.

Thanks,

William Breathitt Gray

> > diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
> > index 7367f46c6f91..5168833b1fdf 100644
> > --- a/drivers/counter/stm32-lptimer-cnt.c
> > +++ b/drivers/counter/stm32-lptimer-cnt.c
> > @@ -170,28 +154,28 @@ static int stm32_lptim_cnt_read(struct counter_device *counter,
> >  	return 0;
> >  }
> >  
> > -static int stm32_lptim_cnt_function_get(struct counter_device *counter,
> > -					struct counter_count *count,
> > -					size_t *function)
> > +static int stm32_lptim_cnt_function_read(struct counter_device *counter,
> > +					 struct counter_count *count,
> > +					 enum counter_function *function)
> >  {
> >  	struct stm32_lptim_cnt *const priv = counter->priv;
> >  
> >  	if (!priv->quadrature_mode) {
> > -		*function = STM32_LPTIM_COUNTER_INCREASE;
> > +		*function = COUNTER_FUNCTION_INCREASE;
> >  		return 0;
> >  	}
> >  
> > -	if (priv->polarity == STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES) {
> > -		*function = STM32_LPTIM_ENCODER_BOTH_EDGE;
> > +	if (priv->polarity == STM32_LPTIM_CKPOL_BOTH_EDGES) {
> > +		*function = COUNTER_FUNCTION_QUADRATURE_X4;
> >  		return 0;
> >  	}
> >  
> >  	return -EINVAL;
> >  }
> >  
> > -static int stm32_lptim_cnt_function_set(struct counter_device *counter,
> > -					struct counter_count *count,
> > -					size_t function)
> > +static int stm32_lptim_cnt_function_write(struct counter_device *counter,
> > +					  struct counter_count *count,
> > +					  enum counter_function function)
> >  {
> >  	struct stm32_lptim_cnt *const priv = counter->priv;
> >  
> > @@ -199,12 +183,12 @@ static int stm32_lptim_cnt_function_set(struct counter_device *counter,
> >  		return -EBUSY;
> >  
> >  	switch (function) {
> > -	case STM32_LPTIM_COUNTER_INCREASE:
> > +	case COUNTER_FUNCTION_INCREASE:
> >  		priv->quadrature_mode = 0;
> >  		return 0;
> > -	case STM32_LPTIM_ENCODER_BOTH_EDGE:
> > +	case COUNTER_FUNCTION_QUADRATURE_X4:
> >  		priv->quadrature_mode = 1;
> > -		priv->polarity = STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES;
> > +		priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES;
> >  		return 0;
> >  	default:
> >  		/* should never reach this path */
> > @@ -333,43 +316,48 @@ static int stm32_lptim_cnt_action_get(struct counter_device *counter,
> >  	}
> >  }
> >  
> > -static int stm32_lptim_cnt_action_set(struct counter_device *counter,
> > -				      struct counter_count *count,
> > -				      struct counter_synapse *synapse,
> > -				      size_t action)
> > +static int stm32_lptim_cnt_action_write(struct counter_device *counter,
> > +					struct counter_count *count,
> > +					struct counter_synapse *synapse,
> > +					enum counter_synapse_action action)
> >  {
> >  	struct stm32_lptim_cnt *const priv = counter->priv;
> > -	size_t function;
> > +	enum counter_function function;
> >  	int err;
> >  
> >  	if (stm32_lptim_is_enabled(priv))
> >  		return -EBUSY;
> >  
> > -	err = stm32_lptim_cnt_function_get(counter, count, &function);
> > +	err = stm32_lptim_cnt_function_read(counter, count, &function);
> >  	if (err)
> >  		return err;
> >  
> >  	/* only set polarity when in counter mode (on input 1) */
> > -	if (function == STM32_LPTIM_COUNTER_INCREASE
> > -	    && synapse->signal->id == count->synapses[0].signal->id) {
> > -		switch (action) {
> > -		case STM32_LPTIM_SYNAPSE_ACTION_RISING_EDGE:
> > -		case STM32_LPTIM_SYNAPSE_ACTION_FALLING_EDGE:
> > -		case STM32_LPTIM_SYNAPSE_ACTION_BOTH_EDGES:
> > -			priv->polarity = action;
> > -			return 0;
> > -		}
> > -	}
> > +	if (function != COUNTER_FUNCTION_INCREASE
> > +	    || synapse->signal->id != count->synapses[0].signal->id)
> > +		return -EINVAL;
> >  
> > -	return -EINVAL;
> > +	switch (action) {
> > +	case COUNTER_SYNAPSE_ACTION_RISING_EDGE:
> > +		priv->polarity = STM32_LPTIM_CKPOL_RISING_EDGE;
> > +		return 0;
> > +	case COUNTER_SYNAPSE_ACTION_FALLING_EDGE:
> > +		priv->polarity = STM32_LPTIM_CKPOL_FALLING_EDGE;
> > +		return 0;
> > +	case COUNTER_SYNAPSE_ACTION_BOTH_EDGES:
> > +		priv->polarity = STM32_LPTIM_CKPOL_BOTH_EDGES;
> > +		return 0;
> > +	default:
> > +		return -EINVAL;
> > +	}
> >  }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210831/f34c0a9f/attachment-0001.sig>

From jc at kynesim.co.uk  Tue Aug 31 07:33:30 2021
From: jc at kynesim.co.uk (John Cox)
Date: Tue, 31 Aug 2021 15:33:30 +0100
Subject: [PATCH 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <fdf6417e-09cd-f0a0-a351-fccd64bfc8c7@collabora.com>
References: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
 <20210831094900.203283-2-benjamin.gaignard@collabora.com>
 <4g2sigpsttf80t72c7spdqqjvvijnths2d@4ax.com>
 <fdf6417e-09cd-f0a0-a351-fccd64bfc8c7@collabora.com>
Message-ID: <l0fsigdnavn1n1n33a8a2ftfuj81tgv3if@4ax.com>

>Le 31/08/2021 ? 13:08, John Cox a ?crit?:
>>> Marking a picture as long-term reference is valid for DPB but not for RPS.
>>> Change flag name to match with it description in HEVC spec chapiter
>>> "8.3.2 Decoding process for reference picture set".
>>> Remove the other unused RPS flags.
>>>
>>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
>>> ---
>>> Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 6 ++----
>>> drivers/staging/media/hantro/hantro_g2_hevc_dec.c         | 2 +-
>>> drivers/staging/media/sunxi/cedrus/cedrus_h265.c          | 2 +-
>>> include/media/hevc-ctrls.h                                | 4 +---
>>> 4 files changed, 5 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>>> index 3865acb9e0fd..eff33c511090 100644
>>> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>>> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>>> @@ -3138,10 +3138,8 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>>> 	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
>>>      * - __u8
>>>        - ``rps``
>>> -      - The reference set for the reference frame
>>> -        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
>>> -        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
>>> -        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>>> +      - Long term flag for the reference frame
>>> +        (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
>>>      * - __u8
>>>        - ``field_pic``
>>>        - Whether the reference is a field picture or a frame.
>> If you are going to remove all the RPS values except for Long Term
>> wouldn't it be better to rename the field too, either to "flags" or a
>> bool "is_long_term"?  If we have a field called RPS it really should be
>> able to have a value for any of the 5 valid Reference Picture Sets that
>> a DPB entry can belong to.
>
>I will send a v2 and rename rps into flags.

OK. I was going to say that you should merge the "field_pic" entry into
a flags bitfield, but then I remembered that H265 doesn't have the
concept of field_pics in the way that H264 does and I believe that both
it and pic_order_count[1] are redundant (i.e. can never be used). But I
guess that is the subject of yet another patch.

Regards

John Cox

>> As a side note, it is important to my code that the DPB array contains
>> all the DPB entries not just the ones that are in use in this frame.  I
>> need them so I can track which frames have left the DPB so I can
>> reuse/free the MV tables associated with them (yes I could keep one for
>> every entry in the capture Q but that is generally wasteful on memory
>> and the Pi is often memory constrained). So maybe update the docn on DPB
>> to make this explicit please? (I suspect that current code does this
>> anyway as it is generally easier to do than to not.)
>
>That should be in another patch :-)
>
>Benjamin
>
>>
>> John Cox
>>
>>> diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>>> index 9ea864ca5625..be46b3c28b17 100644
>>> --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>>> +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
>>> @@ -503,7 +503,7 @@ static int set_ref(struct hantro_ctx *ctx)
>>> 		compress_luma_addr = luma_addr + compress_luma_offset;
>>> 		compress_chroma_addr = luma_addr + compress_chroma_offset;
>>>
>>> -		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>>> +		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
>>> 			dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
>>>
>>> 		/*
>>> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>>> index ef0311a16d01..6086cc35e8cc 100644
>>> --- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>>> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
>>> @@ -169,7 +169,7 @@ static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
>>> 		unsigned int index = list[i];
>>> 		u8 value = list[i];
>>>
>>> -		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>>> +		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
>>> 			value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
>>>
>>> 		/* Each SRAM word gathers up to 4 references. */
>>> diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
>>> index ef63bc205756..f587448ef495 100644
>>> --- a/include/media/hevc-ctrls.h
>>> +++ b/include/media/hevc-ctrls.h
>>> @@ -127,9 +127,7 @@ struct v4l2_ctrl_hevc_pps {
>>> 	__u64	flags;
>>> };
>>>
>>> -#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE	0x01
>>> -#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER	0x02
>>> -#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR		0x03
>>> +#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE	0x01
>>>
>>> #define V4L2_HEVC_DPB_ENTRIES_NUM_MAX		16
>>>


From narmstrong at baylibre.com  Tue Aug 31 07:35:43 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 31 Aug 2021 16:35:43 +0200
Subject: [PATCH] drm/meson: Make use of the helper function
 devm_platform_ioremap_resourcexxx()
In-Reply-To: <20210831135644.4576-1-caihuoqing@baidu.com>
References: <20210831135644.4576-1-caihuoqing@baidu.com>
Message-ID: <896e4f35-f410-41e8-50ad-ed16c65cab45@baylibre.com>

On 31/08/2021 15:56, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource_byname() helper instead of
> calling platform_get_resource_byname() and devm_ioremap_resource()
> separately
> 
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> ---
>  drivers/gpu/drm/meson/meson_drv.c     | 3 +--
>  drivers/gpu/drm/meson/meson_dw_hdmi.c | 4 +---
>  2 files changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index bc0d60df04ae..7f41a33592c8 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -206,8 +206,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>  	priv->compat = match->compat;
>  	priv->afbcd.ops = match->afbcd_ops;
>  
> -	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpu");
> -	regs = devm_ioremap_resource(dev, res);
> +	regs = devm_platform_ioremap_resource_byname(pdev, "vpu");
>  	if (IS_ERR(regs)) {
>  		ret = PTR_ERR(regs);
>  		goto free_drm;
> diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> index 2ed87cfdd735..0afbd1e70bfc 100644
> --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
> +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
> @@ -978,7 +978,6 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
>  	struct dw_hdmi_plat_data *dw_plat_data;
>  	struct drm_bridge *next_bridge;
>  	struct drm_encoder *encoder;
> -	struct resource *res;
>  	int irq;
>  	int ret;
>  
> @@ -1042,8 +1041,7 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
>  		return PTR_ERR(meson_dw_hdmi->hdmitx_phy);
>  	}
>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res);
> +	meson_dw_hdmi->hdmitx = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(meson_dw_hdmi->hdmitx))
>  		return PTR_ERR(meson_dw_hdmi->hdmitx);
>  
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Tue Aug 31 07:50:04 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 31 Aug 2021 16:50:04 +0200
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <CAFBinCBeNMET2tvH0h6HF3dR+xBb59hifQyaoXigUs3UGkS+KQ@mail.gmail.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
 <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>
 <CAFBinCBeNMET2tvH0h6HF3dR+xBb59hifQyaoXigUs3UGkS+KQ@mail.gmail.com>
Message-ID: <2b07b3de-cee5-c570-8fde-6a4c684122d6@baylibre.com>

Hi,

On 30/08/2021 21:37, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Mon, Aug 30, 2021 at 9:45 AM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>
>> Hi,
>>
>> On 17/08/2021 06:15, Anand Moon wrote:
>>> Add missing usb phy power node for usb node fix below warning.
>>> P5V0 regulator supply input voltage range to USB host controller.
>>> As described in the C1+ schematics, GPIO GPIOAO_5 is used to
>>> enable input power to USB ports, set it to Active Low.
>>>
>>> [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
>>> [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
>>>               mode /soc/usb at c90c0000 failed
>>
>> First of all, DT is not here to fix boot message.
> Anand mentioned elsewhere that this is a debug/info message
> 
>> Finally, I looked at the Odroid-C1 schematics and the GPIOAO.BIT5 is an input
>> to the S805, and the PWREN signal is controlled by the USB Hub so this regulator
>> should not be added at all.
> I think there's a misunderstanding because there's two PWREN signals
> with different meanings.
> The PWREN signal for the USB host ports is hard-wired and not
> connected to the SoC at all.
> The PWREN signal for the Micro-USB port (which Anand is adding here)
> is controlled by GPIOAO_5. odroid-c1+_rev0.4_20150615.pdf [0] shows it
> as an input to "USB_OTG" on page 1. "USB_OTG" consists of a power
> switch and the connector itself as shown on page 28.
> 
> Personally I think that the change from Anand itself is good.
> If you feel otherwise then please speak up.

Ok thanks for the clarification, then the change is ok, but not the commit message.

>> Add missing usb phy power node for usb node fix below warning.

is not a good reason for a DT change. A proper reason should be added.

And the commit message doesn't specify the change is for the Micro-USB port,
this should be clarified.

Neil

> As I pointed out three smaller changes I am hoping that Anand will
> re-send the updated patch anyways. At that point he can also add the
> changes from your feedback.
> 
> 
> Best regards,
> Martin
> 
> 
> [0] https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20150615.pdf
> 



From vilhelm.gray at gmail.com  Tue Aug 31 07:55:53 2021
From: vilhelm.gray at gmail.com (William Breathitt Gray)
Date: Tue, 31 Aug 2021 23:55:53 +0900
Subject: [Linux-stm32] [PATCH v16 03/14] counter: Internalize sysfs
 interface code
In-Reply-To: <YS452wJ+IHs9R0FC@shinobu>
References: <cover.1630031207.git.vilhelm.gray@gmail.com>
 <c68b4a1ffb195c1a2f65e8dd5ad7b7c14e79c6ef.1630031207.git.vilhelm.gray@gmail.com>
 <fcff44a7-5ac2-a510-ee9b-85ef7e2e29ef@foss.st.com>
 <YS452wJ+IHs9R0FC@shinobu>
Message-ID: <YS5C+cr1TRhqkCkU@shinobu>

On Tue, Aug 31, 2021 at 11:16:59PM +0900, William Breathitt Gray wrote:
> On Tue, Aug 31, 2021 at 03:44:04PM +0200, Fabrice Gasnier wrote:
> > On 8/27/21 5:47 AM, William Breathitt Gray wrote:
> > > This is a reimplementation of the Generic Counter driver interface.
> > > There are no modifications to the Counter subsystem userspace interface,
> > > so existing userspace applications should continue to run seamlessly.
> > > 
> > > The purpose of this patch is to internalize the sysfs interface code
> > > among the various counter drivers into a shared module. Counter drivers
> > > pass and take data natively (i.e. u8, u64, etc.) and the shared counter
> > > module handles the translation between the sysfs interface and the
> > > device drivers. This guarantees a standard userspace interface for all
> > > counter drivers, and helps generalize the Generic Counter driver ABI in
> > > order to support the Generic Counter chrdev interface (introduced in a
> > > subsequent patch) without significant changes to the existing counter
> > > drivers.
> > > 
> > > Note, Counter device registration is the same as before: drivers
> > > populate a struct counter_device with components and callbacks, then
> > > pass the structure to the devm_counter_register function. However,
> > > what's different now is how the Counter subsystem code handles this
> > > registration internally.
> > > 
> > > Whereas before callbacks would interact directly with sysfs data, this
> > > interaction is now abstracted and instead callbacks interact with native
> > > C data types. The counter_comp structure forms the basis for Counter
> > > extensions.
> > > 
> > > The counter-sysfs.c file contains the code to parse through the
> > > counter_device structure and register the requested components and
> > > extensions. Attributes are created and populated based on type, with
> > > respective translation functions to handle the mapping between sysfs and
> > > the counter driver callbacks.
> > > 
> > > The translation performed for each attribute is straightforward: the
> > > attribute type and data is parsed from the counter_attribute structure,
> > > the respective counter driver read/write callback is called, and sysfs
> > > I/O is handled before or after the driver read/write function is called.
> > > 
> > > Cc: Jarkko Nikula <jarkko.nikula at linux.intel.com>
> > > Cc: Patrick Havelange <patrick.havelange at essensium.com>
> > > Cc: Kamel Bouhara <kamel.bouhara at bootlin.com>
> > > Cc: Fabrice Gasnier <fabrice.gasnier at st.com>
> > > Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> > > Cc: Alexandre Torgue <alexandre.torgue at st.com>
> > > Cc: Dan Carpenter <dan.carpenter at oracle.com>
> > > Acked-by: Syed Nayyar Waris <syednwaris at gmail.com>
> > > Reviewed-by: David Lechner <david at lechnology.com>
> > > Tested-by: David Lechner <david at lechnology.com>
> > > Signed-off-by: William Breathitt Gray <vilhelm.gray at gmail.com>
> > > ---
> > >  MAINTAINERS                             |    1 -
> > >  drivers/counter/104-quad-8.c            |  449 +++----
> > >  drivers/counter/Makefile                |    1 +
> > >  drivers/counter/counter-core.c          |  142 +++
> > >  drivers/counter/counter-sysfs.c         |  849 +++++++++++++
> > >  drivers/counter/counter-sysfs.h         |   13 +
> > >  drivers/counter/counter.c               | 1496 -----------------------
> > >  drivers/counter/ftm-quaddec.c           |   60 +-
> > >  drivers/counter/intel-qep.c             |  144 +--
> > >  drivers/counter/interrupt-cnt.c         |   62 +-
> > >  drivers/counter/microchip-tcb-capture.c |   91 +-
> > >  drivers/counter/stm32-lptimer-cnt.c     |  212 ++--
> > >  drivers/counter/stm32-timer-cnt.c       |  179 ++-
> > >  drivers/counter/ti-eqep.c               |  180 +--
> > >  include/linux/counter.h                 |  658 +++++-----
> > >  include/linux/counter_enum.h            |   45 -
> > >  16 files changed, 1949 insertions(+), 2633 deletions(-)
> > >  create mode 100644 drivers/counter/counter-core.c
> > >  create mode 100644 drivers/counter/counter-sysfs.c
> > >  create mode 100644 drivers/counter/counter-sysfs.h
> > >  delete mode 100644 drivers/counter/counter.c
> > >  delete mode 100644 include/linux/counter_enum.h
> > > 
> > 
> > Hi William,
> > 
> > For the STM32 drivers, you can add my:
> > Reviewed-by: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> > 
> > Thanks,
> > Fabrice
> 
> Hello Fabrice,
> 
> I noticed the stm32-lptimer-cnt.c function_write() and action_write()
> callbacks do not appear to write the desired function/action
> configuration to the device. Would you check whether the device actually
> supports this functionality or if these callbacks should be removed from
> this driver.
> 
> Thanks,
> 
> William Breathitt Gray

Nevermind, I see that these configurations are sent to the device via
stm32_lptim_setup() when the counter is enabled. So that setup should be
fine after all.

Thanks,

William Breathitt Gray
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210831/d10527b5/attachment-0001.sig>

From robh+dt at kernel.org  Tue Aug 31 08:04:40 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 10:04:40 -0500
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared
 pcie-cfg base address
In-Reply-To: <20210827164634.GA3779223@bjorn-Precision-5520>
References: <20210823032800.1660-3-chuanjia.liu@mediatek.com>
 <20210827164634.GA3779223@bjorn-Precision-5520>
Message-ID: <CAL_JsqKEvAypWhiaWMhxM7zVkLAFL9=eMU7_vr=ht+uyxYe0qg@mail.gmail.com>

On Fri, Aug 27, 2021 at 11:46 AM Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> On Mon, Aug 23, 2021 at 11:27:56AM +0800, Chuanjia Liu wrote:
> > For the new dts format, add a new method to get
> > shared pcie-cfg base address and use it to configure
> > the PCIECFG controller
>
> Rewrap this to fill 75 columns.
>
> > Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> > Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> > ---
> >  drivers/pci/controller/pcie-mediatek.c | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> >
> > diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> > index 25bee693834f..4296d9e04240 100644
> > --- a/drivers/pci/controller/pcie-mediatek.c
> > +++ b/drivers/pci/controller/pcie-mediatek.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/irqchip/chained_irq.h>
> >  #include <linux/irqdomain.h>
> >  #include <linux/kernel.h>
> > +#include <linux/mfd/syscon.h>
> >  #include <linux/msi.h>
> >  #include <linux/module.h>
> >  #include <linux/of_address.h>
> > @@ -23,6 +24,7 @@
> >  #include <linux/phy/phy.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_runtime.h>
> > +#include <linux/regmap.h>
> >  #include <linux/reset.h>
> >
> >  #include "../pci.h"
> > @@ -207,6 +209,7 @@ struct mtk_pcie_port {
> >   * struct mtk_pcie - PCIe host information
> >   * @dev: pointer to PCIe device
> >   * @base: IO mapped register base
> > + * @cfg: IO mapped register map for PCIe config
> >   * @free_ck: free-run reference clock
> >   * @mem: non-prefetchable memory resource
> >   * @ports: pointer to PCIe port information
> > @@ -215,6 +218,7 @@ struct mtk_pcie_port {
> >  struct mtk_pcie {
> >       struct device *dev;
> >       void __iomem *base;
> > +     struct regmap *cfg;
> >       struct clk *free_ck;
> >
> >       struct list_head ports;
> > @@ -682,6 +686,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
> >               val |= PCIE_CSR_LTSSM_EN(port->slot) |
> >                      PCIE_CSR_ASPM_L1_EN(port->slot);
> >               writel(val, pcie->base + PCIE_SYS_CFG_V2);
> > +     } else if (pcie->cfg) {
> > +             val = PCIE_CSR_LTSSM_EN(port->slot) |
> > +                   PCIE_CSR_ASPM_L1_EN(port->slot);
> > +             regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
> >       }
> >
> >       /* Assert all reset signals */
> > @@ -985,6 +993,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> >       struct device *dev = pcie->dev;
> >       struct platform_device *pdev = to_platform_device(dev);
> >       struct resource *regs;
> > +     struct device_node *cfg_node;
> >       int err;
> >
> >       /* get shared registers, which are optional */
> > @@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> >                       return PTR_ERR(pcie->base);
> >       }
> >
> > +     cfg_node = of_find_compatible_node(NULL, NULL,
> > +                                        "mediatek,generic-pciecfg");
>
> This looks wrong to me.  IIUC, since we start at NULL, this searches
> the entire device tree for any node with
>
>   compatible = "mediatek,generic-pciecfg"
>
> but we should only care about the specific device/node this driver
> claimed.
>
> Should this be part of the match data, i.e., struct mtk_pcie_soc?

What would you put in match data exactly?

The other way to do this is to have a DT property with the phandle
which people like to do (have everything in the node 'for their
driver'). If there's only 1 possible node (which is almost always the
case), then there is little benefit to having another property. It's
just redundant data. A phandle lookup might be a bit faster with the
caching we do, but on a miss it would still walk all nodes.

The other thing with these 'extra register bits to twiddle' is that
they tend to be SoC specific and change from chip to chip, so either
way is not very portable. The real question to ask is should there be
a standard interface used or created.

>
> > +     if (cfg_node) {
> > +             pcie->cfg = syscon_node_to_regmap(cfg_node);
>
> Other drivers in drivers/pci/controller/ use
> syscon_regmap_lookup_by_phandle() (j721e, dra7xx, keystone,
> layerscape, artpec6) or syscon_regmap_lookup_by_compatible() (imx6,
> kirin, v3-semi).

There's no phandle to use in this case. As above, I'm trying to break
people of this habit.

Rob


From robh+dt at kernel.org  Tue Aug 31 08:17:53 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 10:17:53 -0500
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared
 pcie-cfg base address
In-Reply-To: <ccf767340afe13a6d273ad8fbc29c6bc966d6314.camel@mediatek.com>
References: <20210830214317.GA27606@bjorn-Precision-5520>
 <ccf767340afe13a6d273ad8fbc29c6bc966d6314.camel@mediatek.com>
Message-ID: <CAL_Jsq+dBi-XUDJD_STP=jWw+RLkRpX1U9XsRMhqK4U1H=0FHw@mail.gmail.com>

On Mon, Aug 30, 2021 at 10:31 PM Chuanjia Liu <chuanjia.liu at mediatek.com> wrote:
>
> On Mon, 2021-08-30 at 16:43 -0500, Bjorn Helgaas wrote:
> > On Mon, Aug 30, 2021 at 03:09:44PM +0800, Chuanjia Liu wrote:
> > > On Fri, 2021-08-27 at 11:46 -0500, Bjorn Helgaas wrote:
> > > > On Mon, Aug 23, 2021 at 11:27:56AM +0800, Chuanjia Liu wrote:
> > > > > @@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct
> > > > > mtk_pcie *pcie)
> > > > >                         return PTR_ERR(pcie->base);
> > > > >         }
> > > > >
> > > > > +       cfg_node = of_find_compatible_node(NULL, NULL,
> > > > > +                                          "mediatek,generic-
> > > > > pciecfg");
> > > > > +       if (cfg_node) {
> > > > > +               pcie->cfg = syscon_node_to_regmap(cfg_node);
> > > >
> > > > Other drivers in drivers/pci/controller/ use
> > > > syscon_regmap_lookup_by_phandle() (j721e, dra7xx, keystone,
> > > > layerscape, artpec6) or syscon_regmap_lookup_by_compatible()
> > > > (imx6,
> > > > kirin, v3-semi).
> > > >
> > > > You should do it the same way unless there's a need to be
> > > > different.
> > >
> > > I have used phandle, but Rob suggested to search for the node by
> > > compatible.
> > > The reason why syscon_regmap_lookup_by_compatible() is not
> > > used here is that the pciecfg node is optional, and there is no
> > > need to
> > > return error when the node is not searched.
> >
> > How about this?
> >
> >   regmap = syscon_regmap_lookup_by_compatible("mediatek,generic-
> > pciecfg");
> >   if (!IS_ERR(regmap))
> >     pcie->cfg = regmap;

+1

>
> Hi Bjorn,
>
> We need to deal with three situations
> 1) No error
> 2) The error of the node not found, don't do anything
> 3) Other errors, return errors
>
> I guess you mean
>
> regmap = syscon_regmap_lookup_by_compatible("mediatek,generic-
> pciecfg");
>   if (!IS_ERR(regmap))
>       pcie->cfg = regmap;
>   else if (IS_ERR(regmap) && PTR_ERR(regmap) != -ENODEV)

You already know  IS_ERR is true here.

>       return PTR_ERR(regmap);

syscon_regmap_lookup_by_compatible_optional is the function you are
looking for. The _optional flavor doesn't exist, so create it. There
is one for the phandle lookup.

>
> I'm not sure if we need this, it seems a little weird and there are
> many drivers in other subsystems that use syscon_node_to_regmap().

You are implementing the exact same sequence that
syscon_regmap_lookup_by_compatible() does, so clearly you should be
using it. The one difference is you forgot the of_node_put().

Rob


From jorge at foundries.io  Tue Aug 31 08:21:44 2021
From: jorge at foundries.io (Jorge Ramirez-Ortiz, Foundries)
Date: Tue, 31 Aug 2021 17:21:44 +0200
Subject: rcu_preempt detected stalls
Message-ID: <20210831152144.GA28128@trex>

Hi

When enabling CONFIG_PREEMPT and running the stress-ng scheduler class
tests on arm64 (xilinx zynqmp and imx imx8mm SoCs) we are observing the following.

[   62.578917] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:                                                              
[   62.585015]  (detected by 0, t=5253 jiffies, g=3017, q=2972)                                                                   
[   62.590663] rcu: All QSes seen, last rcu_preempt kthread activity 5254 (4294907943-4294902689), jiffies_till_next_fqs=1, root  
+->qsmask 0x0                                                                                                                     
[   62.603086] rcu: rcu_preempt kthread starved for 5258 jiffies! g3017 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1               
[   62.613246] rcu:     Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.                        
[   62.622359] rcu: RCU grace-period kthread stack dump:                                                                          
[   62.627395] task:rcu_preempt     state:R  running task     stack:    0 pid:   14 ppid:     2 flags:0x00000028                  
[   62.637308] Call trace:                                                                                                        
[   62.639748]  __switch_to+0x11c/0x190                                                                                           
[   62.643319]  __schedule+0x3b8/0x8d8                                                                                            
[   62.646796]  schedule+0x4c/0x108                                                                                               
[   62.650018]  schedule_timeout+0x1ac/0x358                                                                                      
[   62.654021]  rcu_gp_kthread+0x6a8/0x12b8                                                                                       
[   62.657933]  kthread+0x14c/0x158                                                                                               
[   62.661153]  ret_from_fork+0x10/0x18                                                                                           
[   62.682919] BUG: scheduling while atomic: stress-ng-hrtim/831/0x00000002                                                       
[   62.689604] Preemption disabled at:                                                                                            
[   62.689614] [<ffffffc010059418>] irq_enter_rcu+0x30/0x58                                                                       
[   62.698393] CPU: 0 PID: 831 Comm: stress-ng-hrtim Not tainted 5.10.42+ #5                                         
[   62.706296] Hardware name: Zynqmp new (DT)                                                                                        
[   62.710115] Call trace:                                                                                                        
[   62.712548]  dump_backtrace+0x0/0x240                                                                                          
[   62.716202]  show_stack+0x2c/0x38                                                                                              
[   62.719510]  dump_stack+0xcc/0x104                                                                                             
[   62.722904]  __schedule_bug+0x78/0xc8                                                                                          
[   62.726556]  __schedule+0x70c/0x8d8                                                                                            
[   62.730037]  schedule+0x4c/0x108                                                                                               
[   62.733259]  do_notify_resume+0x224/0x5d8                                                                                      
[   62.737259]  work_pending+0xc/0x2a4

The error results in OOM eventually.

RCU priority boosting does work around this issue but it seems to me
a workaround more than a fix (otherwise boosting would be enabled
by CONFIG_PREEMPT for arm64 I guess?).

The question is: is this an arm64 bug that should be investigated? or
is this some known corner case of running stress-ng that is already
understood?

thanks
Jorge





From helgaas at kernel.org  Tue Aug 31 08:47:11 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 31 Aug 2021 10:47:11 -0500
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared
 pcie-cfg base address
In-Reply-To: <CAL_JsqKEvAypWhiaWMhxM7zVkLAFL9=eMU7_vr=ht+uyxYe0qg@mail.gmail.com>
Message-ID: <20210831154711.GA107126@bjorn-Precision-5520>

On Tue, Aug 31, 2021 at 10:04:40AM -0500, Rob Herring wrote:
> On Fri, Aug 27, 2021 at 11:46 AM Bjorn Helgaas <helgaas at kernel.org> wrote:
> >
> > On Mon, Aug 23, 2021 at 11:27:56AM +0800, Chuanjia Liu wrote:
> > > For the new dts format, add a new method to get
> > > shared pcie-cfg base address and use it to configure
> > > the PCIECFG controller
> >
> > Rewrap this to fill 75 columns.
> >
> > > Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> > > Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> > > ---
> > >  drivers/pci/controller/pcie-mediatek.c | 17 +++++++++++++++++
> > >  1 file changed, 17 insertions(+)
> > >
> > > diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> > > index 25bee693834f..4296d9e04240 100644
> > > --- a/drivers/pci/controller/pcie-mediatek.c
> > > +++ b/drivers/pci/controller/pcie-mediatek.c
> > > @@ -14,6 +14,7 @@
> > >  #include <linux/irqchip/chained_irq.h>
> > >  #include <linux/irqdomain.h>
> > >  #include <linux/kernel.h>
> > > +#include <linux/mfd/syscon.h>
> > >  #include <linux/msi.h>
> > >  #include <linux/module.h>
> > >  #include <linux/of_address.h>
> > > @@ -23,6 +24,7 @@
> > >  #include <linux/phy/phy.h>
> > >  #include <linux/platform_device.h>
> > >  #include <linux/pm_runtime.h>
> > > +#include <linux/regmap.h>
> > >  #include <linux/reset.h>
> > >
> > >  #include "../pci.h"
> > > @@ -207,6 +209,7 @@ struct mtk_pcie_port {
> > >   * struct mtk_pcie - PCIe host information
> > >   * @dev: pointer to PCIe device
> > >   * @base: IO mapped register base
> > > + * @cfg: IO mapped register map for PCIe config
> > >   * @free_ck: free-run reference clock
> > >   * @mem: non-prefetchable memory resource
> > >   * @ports: pointer to PCIe port information
> > > @@ -215,6 +218,7 @@ struct mtk_pcie_port {
> > >  struct mtk_pcie {
> > >       struct device *dev;
> > >       void __iomem *base;
> > > +     struct regmap *cfg;
> > >       struct clk *free_ck;
> > >
> > >       struct list_head ports;
> > > @@ -682,6 +686,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
> > >               val |= PCIE_CSR_LTSSM_EN(port->slot) |
> > >                      PCIE_CSR_ASPM_L1_EN(port->slot);
> > >               writel(val, pcie->base + PCIE_SYS_CFG_V2);
> > > +     } else if (pcie->cfg) {
> > > +             val = PCIE_CSR_LTSSM_EN(port->slot) |
> > > +                   PCIE_CSR_ASPM_L1_EN(port->slot);
> > > +             regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
> > >       }
> > >
> > >       /* Assert all reset signals */
> > > @@ -985,6 +993,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> > >       struct device *dev = pcie->dev;
> > >       struct platform_device *pdev = to_platform_device(dev);
> > >       struct resource *regs;
> > > +     struct device_node *cfg_node;
> > >       int err;
> > >
> > >       /* get shared registers, which are optional */
> > > @@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> > >                       return PTR_ERR(pcie->base);
> > >       }
> > >
> > > +     cfg_node = of_find_compatible_node(NULL, NULL,
> > > +                                        "mediatek,generic-pciecfg");
> >
> > This looks wrong to me.  IIUC, since we start at NULL, this searches
> > the entire device tree for any node with
> >
> >   compatible = "mediatek,generic-pciecfg"
> >
> > but we should only care about the specific device/node this driver
> > claimed.
> >
> > Should this be part of the match data, i.e., struct mtk_pcie_soc?
> 
> What would you put in match data exactly?
> 
> The other way to do this is to have a DT property with the phandle
> which people like to do (have everything in the node 'for their
> driver'). If there's only 1 possible node (which is almost always the
> case), then there is little benefit to having another property. It's
> just redundant data. A phandle lookup might be a bit faster with the
> caching we do, but on a miss it would still walk all nodes.
> 
> The other thing with these 'extra register bits to twiddle' is that
> they tend to be SoC specific and change from chip to chip, so either
> way is not very portable. The real question to ask is should there be
> a standard interface used or created.
> 
> > > +     if (cfg_node) {
> > > +             pcie->cfg = syscon_node_to_regmap(cfg_node);
> >
> > Other drivers in drivers/pci/controller/ use
> > syscon_regmap_lookup_by_phandle() (j721e, dra7xx, keystone,
> > layerscape, artpec6) or syscon_regmap_lookup_by_compatible() (imx6,
> > kirin, v3-semi).
> 
> There's no phandle to use in this case. As above, I'm trying to break
> people of this habit.

Thanks!  I was mistaken in lots of ways here.  I first assumed
"mediatek,generic-pciecfg" was local to the pcie node, but that's not
true.  Then I thought there might be an ownership issue because the
regmap is not local to the device, and several drivers look up and use
the same regmap.  But it looks like regmap provides some internal
locking which mitigates most or all of that concern.

Just to check -- you prefer syscon_regmap_lookup_by_compatible() over
syscon_regmap_lookup_by_phandle()?


From paulmck at kernel.org  Tue Aug 31 08:53:59 2021
From: paulmck at kernel.org (Paul E. McKenney)
Date: Tue, 31 Aug 2021 08:53:59 -0700
Subject: rcu_preempt detected stalls
In-Reply-To: <20210831152144.GA28128@trex>
References: <20210831152144.GA28128@trex>
Message-ID: <20210831155359.GB4156@paulmck-ThinkPad-P17-Gen-1>

On Tue, Aug 31, 2021 at 05:21:44PM +0200, Jorge Ramirez-Ortiz, Foundries wrote:
> Hi
>
> When enabling CONFIG_PREEMPT and running the stress-ng scheduler class
> tests on arm64 (xilinx zynqmp and imx imx8mm SoCs) we are observing the following.
>
> [   62.578917] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> [   62.585015]  (detected by 0, t=5253 jiffies, g=3017, q=2972)
> [   62.590663] rcu: All QSes seen, last rcu_preempt kthread activity 5254 (4294907943-4294902689), jiffies_till_next_fqs=1, root
> +->qsmask 0x0
> [   62.603086] rcu: rcu_preempt kthread starved for 5258 jiffies! g3017 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1
> [   62.613246] rcu:     Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.

The message above really does mean what it says:  If your workload
prevents RCU's grace-period kthread ("rcu_preempt" in this case) from
running, you just bought yourself an OOM.

> [   62.622359] rcu: RCU grace-period kthread stack dump:
> [   62.627395] task:rcu_preempt     state:R  running task     stack:    0 pid:   14 ppid:     2 flags:0x00000028
> [   62.637308] Call trace:
> [   62.639748]  __switch_to+0x11c/0x190
> [   62.643319]  __schedule+0x3b8/0x8d8
> [   62.646796]  schedule+0x4c/0x108
> [   62.650018]  schedule_timeout+0x1ac/0x358
> [   62.654021]  rcu_gp_kthread+0x6a8/0x12b8
> [   62.657933]  kthread+0x14c/0x158
> [   62.661153]  ret_from_fork+0x10/0x18
> [   62.682919] BUG: scheduling while atomic: stress-ng-hrtim/831/0x00000002
> [   62.689604] Preemption disabled at:
> [   62.689614] [<ffffffc010059418>] irq_enter_rcu+0x30/0x58
> [   62.698393] CPU: 0 PID: 831 Comm: stress-ng-hrtim Not tainted 5.10.42+ #5
> [   62.706296] Hardware name: Zynqmp new (DT)
> [   62.710115] Call trace:
> [   62.712548]  dump_backtrace+0x0/0x240
> [   62.716202]  show_stack+0x2c/0x38
> [   62.719510]  dump_stack+0xcc/0x104
> [   62.722904]  __schedule_bug+0x78/0xc8
> [   62.726556]  __schedule+0x70c/0x8d8
> [   62.730037]  schedule+0x4c/0x108
> [   62.733259]  do_notify_resume+0x224/0x5d8
> [   62.737259]  work_pending+0xc/0x2a4
>
> The error results in OOM eventually.
>
> RCU priority boosting does work around this issue but it seems to me
> a workaround more than a fix (otherwise boosting would be enabled
> by CONFIG_PREEMPT for arm64 I guess?).

RCU priority boosting sets the rcu_preempt kthread's scheduling priority
to SCHED_FIFO priority level 1 instead of the normal SCHED_OTHER.
Therefore, if you build with CONFIG_RCU_BOOST=n, but manually set the
priority of rcu_preempt to SCHED_FIFO priority level 1, you might also
see this RCU CPU stall warning go away.

> The question is: is this an arm64 bug that should be investigated? or
> is this some known corner case of running stress-ng that is already
> understood?

I have not looked at stress-ng, but it is possible to configure your
system so that rcu_preempt gets little or no CPU time, for example,
by placing it into a CPU-poor cgroup on the one hand or by disabling
throttling and running a heavy real-time workload on the other.
Is stress-ng doing something like this?

There could of course also be an arm64 problem that affect scheduling,
but I suggest looking closely at what stress-ng is doing first.

Please let me know how it goes!

							Thanx, Paul


From alex.williamson at redhat.com  Tue Aug 31 09:15:49 2021
From: alex.williamson at redhat.com (Alex Williamson)
Date: Tue, 31 Aug 2021 10:15:49 -0600
Subject: [RFC][PATCH v2 00/13] iommu/arm-smmu-v3: Add NVIDIA implementation
In-Reply-To: <20210831025923.15812-1-nicolinc@nvidia.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
Message-ID: <20210831101549.237151fa.alex.williamson@redhat.com>

On Mon, 30 Aug 2021 19:59:10 -0700
Nicolin Chen <nicolinc at nvidia.com> wrote:

> The SMMUv3 devices implemented in the Grace SoC support NVIDIA's custom
> CMDQ-Virtualization (CMDQV) hardware. Like the new ECMDQ feature first
> introduced in the ARM SMMUv3.3 specification, CMDQV adds multiple VCMDQ
> interfaces to supplement the single architected SMMU_CMDQ in an effort
> to reduce contention.
> 
> This series of patches add CMDQV support with its preparational changes:
> 
> * PATCH-1 to PATCH-8 are related to shared VMID feature: they are used
>   first to improve TLB utilization, second to bind a shared VMID with a
>   VCMDQ interface for hardware configuring requirement.

The vfio changes would need to be implemented in alignment with the
/dev/iommu proposals[1].  AIUI, the VMID is essentially binding
multiple containers together for TLB invalidation, which I expect in
the proposal below is largely already taken care of in that a single
iommu-fd can support multiple I/O address spaces and it's largely
expected that a hypervisor would use a single iommu-fd so this explicit
connection by userspace across containers wouldn't be necessary.

We're expecting to talk more about the /dev/iommu approach at Plumbers
in few weeks.  Thanks,

Alex

[1]https://lore.kernel.org/kvm/BN9PR11MB5433B1E4AE5B0480369F97178C189 at BN9PR11MB5433.namprd11.prod.outlook.com/

 
> * PATCH-9 and PATCH-10 are to accommodate the NVIDIA implementation with
>   the existing arm-smmu-v3 driver.
> 
> * PATCH-11 borrows the "implementation infrastructure" from the arm-smmu
>   driver so later change can build upon it.
> 
> * PATCH-12 adds an initial NVIDIA implementation related to host feature,
>   and also adds implementation specific ->device_reset() and ->get_cmdq()
>   callback functions.
> 
> * PATCH-13 adds virtualization features using VFIO mdev interface, which
>   allows user space hypervisor to map and get access to one of the VCMDQ
>   interfaces of CMDQV module.
> 
> ( Thinking that reviewers can get a better view of this implementation,
>   I am attaching QEMU changes here for reference purpose:
>       https://github.com/nicolinc/qemu/commits/dev/cmdqv_v6.0.0-rc2
>   The branch has all preparational changes, while I'm still integrating
>   device model and ARM-VIRT changes, and will push them these two days,
>   although they might not be in a good shape of being sent to review yet )
> 
> Above all, I marked RFC for this series, as I feel that we may come up
> some better solution. So please kindly share your reviews and insights.
> 
> Thank you!
> 
> Changelog
> v1->v2:
>  * Added mdev interface support for hypervisor and VMs.
>  * Added preparational changes for mdev interface implementation.
>  * PATCH-12 Changed ->issue_cmdlist() to ->get_cmdq() for a better
>    integration with recently merged ECMDQ-related changes.
> 
> Nate Watterson (3):
>   iommu/arm-smmu-v3: Add implementation infrastructure
>   iommu/arm-smmu-v3: Add support for NVIDIA CMDQ-Virtualization hw
>   iommu/nvidia-smmu-v3: Add mdev interface support
> 
> Nicolin Chen (10):
>   iommu: Add set_nesting_vmid/get_nesting_vmid functions
>   vfio: add VFIO_IOMMU_GET_VMID and VFIO_IOMMU_SET_VMID
>   vfio: Document VMID control for IOMMU Virtualization
>   vfio: add set_vmid and get_vmid for vfio_iommu_type1
>   vfio/type1: Implement set_vmid and get_vmid
>   vfio/type1: Set/get VMID to/from iommu driver
>   iommu/arm-smmu-v3: Add shared VMID support for NESTING
>   iommu/arm-smmu-v3: Add VMID alloc/free helpers
>   iommu/arm-smmu-v3: Pass dev pointer to arm_smmu_detach_dev
>   iommu/arm-smmu-v3: Pass cmdq pointer in arm_smmu_cmdq_issue_cmdlist()
> 
>  Documentation/driver-api/vfio.rst             |   34 +
>  MAINTAINERS                                   |    2 +
>  drivers/iommu/arm/arm-smmu-v3/Makefile        |    2 +-
>  .../iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c  |   15 +
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  121 +-
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |   18 +
>  .../iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c    | 1249 +++++++++++++++++
>  drivers/iommu/iommu.c                         |   20 +
>  drivers/vfio/vfio.c                           |   25 +
>  drivers/vfio/vfio_iommu_type1.c               |   37 +
>  include/linux/iommu.h                         |    5 +
>  include/linux/vfio.h                          |    2 +
>  include/uapi/linux/vfio.h                     |   26 +
>  13 files changed, 1537 insertions(+), 19 deletions(-)
>  create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c
>  create mode 100644 drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c
> 



From lukasz.luba at arm.com  Tue Aug 31 09:17:52 2021
From: lukasz.luba at arm.com (Lukasz Luba)
Date: Tue, 31 Aug 2021 17:17:52 +0100
Subject: [PATCH V3 9/9] cpufreq: scmi: Use .register_em() to register with
 energy model
In-Reply-To: <8158488baa1ea1aebd09c8d256db7420051d05ac.1628742634.git.viresh.kumar@linaro.org>
References: <cover.1628742634.git.viresh.kumar@linaro.org>
 <8158488baa1ea1aebd09c8d256db7420051d05ac.1628742634.git.viresh.kumar@linaro.org>
Message-ID: <d454df8e-9adb-ea97-727e-f182e95707ef@arm.com>

Hi Viresh,

My apologies for delay I was on holidays. I've seen the pull requests,
so it's too late, but just for history...

I have tested this new callback with hacked juno FW which works in
the per-cpu perf requests. There are no issues.

Some debug prints:

[    3.110072] cpu cpu0: cpumask weight(opp_shared_cpus)=4 weight 
policy->cpus=1
[    3.117666] cpu cpu0: Empty OPP table
[    3.121418] cpu cpu0: OPP table empty
[    3.131367] cpu cpu0: EM: created perf domain
[    3.137848] cpu cpu1: cpumask weight(opp_shared_cpus)=2 weight 
policy->cpus=1
[    3.145220] cpu cpu1: Empty OPP table
[    3.148961] cpu cpu1: OPP table empty
[    3.158193] cpu cpu1: EM: created perf domain
[    3.164325] cpu cpu2: cpumask weight(opp_shared_cpus)=2 weight 
policy->cpus=1
[    3.173430] cpu cpu3: cpumask weight(opp_shared_cpus)=4 weight 
policy->cpus=1
[    3.181947] cpu cpu4: cpumask weight(opp_shared_cpus)=4 weight 
policy->cpus=1
[    3.190620] cpu cpu5: cpumask weight(opp_shared_cpus)=4 weight 
policy->cpus=1

root at sqwt-ubuntu:~# grep . /sys/kernel/debug/energy_model/cpu0/ps\:*/*
/sys/kernel/debug/energy_model/cpu0/ps:450000/cost:79
/sys/kernel/debug/energy_model/cpu0/ps:450000/frequency:450000
/sys/kernel/debug/energy_model/cpu0/ps:450000/power:42
/sys/kernel/debug/energy_model/cpu0/ps:575000/cost:85
/sys/kernel/debug/energy_model/cpu0/ps:575000/frequency:575000
/sys/kernel/debug/energy_model/cpu0/ps:575000/power:58
/sys/kernel/debug/energy_model/cpu0/ps:700000/cost:95
/sys/kernel/debug/energy_model/cpu0/ps:700000/frequency:700000
/sys/kernel/debug/energy_model/cpu0/ps:700000/power:79
/sys/kernel/debug/energy_model/cpu0/ps:775000/cost:106
/sys/kernel/debug/energy_model/cpu0/ps:775000/frequency:775000
/sys/kernel/debug/energy_model/cpu0/ps:775000/power:97
/sys/kernel/debug/energy_model/cpu0/ps:850000/cost:119
/sys/kernel/debug/energy_model/cpu0/ps:850000/frequency:850000
/sys/kernel/debug/energy_model/cpu0/ps:850000/power:119
root at sqwt-ubuntu:~# cat /sys/kernel/debug/energy_model/cpu0/cpus
0,3-5
root at sqwt-ubuntu:~# cat /sys/kernel/debug/energy_model/cpu1/cpus
1-2
root at sqwt-ubuntu:~# grep . /sys/kernel/debug/energy_model/cpu1/ps\:*/*
/sys/kernel/debug/energy_model/cpu1/ps:1100000/cost:583
/sys/kernel/debug/energy_model/cpu1/ps:1100000/frequency:1100000
/sys/kernel/debug/energy_model/cpu1/ps:1100000/power:583
/sys/kernel/debug/energy_model/cpu1/ps:450000/cost:391
/sys/kernel/debug/energy_model/cpu1/ps:450000/frequency:450000
/sys/kernel/debug/energy_model/cpu1/ps:450000/power:160
/sys/kernel/debug/energy_model/cpu1/ps:625000/cost:420
/sys/kernel/debug/energy_model/cpu1/ps:625000/frequency:625000
/sys/kernel/debug/energy_model/cpu1/ps:625000/power:239
/sys/kernel/debug/energy_model/cpu1/ps:800000/cost:471
/sys/kernel/debug/energy_model/cpu1/ps:800000/frequency:800000
/sys/kernel/debug/energy_model/cpu1/ps:800000/power:343
/sys/kernel/debug/energy_model/cpu1/ps:950000/cost:525
/sys/kernel/debug/energy_model/cpu1/ps:950000/frequency:950000
/sys/kernel/debug/energy_model/cpu1/ps:950000/power:454
root at sqwt-ubuntu:~#

Regards,
Lukasz


From miles.chen at mediatek.com  Tue Aug 31 09:42:06 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 1 Sep 2021 00:42:06 +0800
Subject: [PATCH v2 0/4] clk: mediatek: modularize COMMON_CLK_MT6779
Message-ID: <20210831164210.15455-1-miles.chen@mediatek.com>

This patch set makes COMMON_CLK_MEDIATEK and COMMON_CLK_MT6779*
be able to built as kernel modules. Necessary symbols are exported
in this patch.

In previous discussion [1], Stephen commented that there must
be a user before exporting a symbol:

"
Is the mediatek driver compilable as a module? Last time I checked it
wasn't a module. I want an upstream modular driver that uses the symbol.
Otherwise we're exporting symbols when it doesn't need to be.
"

[1] https://lore.kernel.org/patchwork/patch/1278089/

---

Change since v1:
use module_platform_driver() instead of builtin_platform_driver()


Miles Chen (4):
  clk: composite: export clk_register_composite
  clk: mediatek: support COMMON_CLK_MEDIATEK module build
  clk: mediatek: support COMMON_CLK_MT6779 module build
  clk: mediatek: use tristate for COMMON_CLK_MEDAITEK and
    COMMON_CLK_MT6779

 drivers/clk/clk-composite.c            |  1 +
 drivers/clk/mediatek/Kconfig           | 20 ++++++++++----------
 drivers/clk/mediatek/clk-apmixed.c     |  3 +++
 drivers/clk/mediatek/clk-cpumux.c      |  3 +++
 drivers/clk/mediatek/clk-gate.c        |  8 ++++++++
 drivers/clk/mediatek/clk-mt6779-aud.c  |  4 +++-
 drivers/clk/mediatek/clk-mt6779-cam.c  |  4 +++-
 drivers/clk/mediatek/clk-mt6779-img.c  |  4 +++-
 drivers/clk/mediatek/clk-mt6779-ipe.c  |  4 +++-
 drivers/clk/mediatek/clk-mt6779-mfg.c  |  4 +++-
 drivers/clk/mediatek/clk-mt6779-mm.c   |  4 +++-
 drivers/clk/mediatek/clk-mt6779-vdec.c |  4 +++-
 drivers/clk/mediatek/clk-mt6779-venc.c |  4 +++-
 drivers/clk/mediatek/clk-mt6779.c      |  2 ++
 drivers/clk/mediatek/clk-mtk.c         |  8 ++++++++
 drivers/clk/mediatek/clk-mux.c         |  4 ++++
 drivers/clk/mediatek/clk-pll.c         |  4 ++++
 drivers/clk/mediatek/reset.c           |  2 ++
 18 files changed, 69 insertions(+), 18 deletions(-)

-- 
2.18.0

From miles.chen at mediatek.com  Tue Aug 31 09:42:10 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 1 Sep 2021 00:42:10 +0800
Subject: [PATCH v2 4/4] clk: mediatek: use tristate for COMMON_CLK_MEDAITEK
 and COMMON_CLK_MT6779
In-Reply-To: <20210831164210.15455-1-miles.chen@mediatek.com>
References: <20210831164210.15455-1-miles.chen@mediatek.com>
Message-ID: <20210831164210.15455-5-miles.chen@mediatek.com>

Now we have all necessary exported symbols, change
COMMON_CLK_MEDAITEK and COMMON_CLK_MT6779* to tristate.

Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Hanks Chen <hanks.chen at mediatek.com>
Cc: Wendell Lin <wendell.lin at mediatek.com>
Cc: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/Kconfig | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 886e2d9fced5..62ed2054a849 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -6,7 +6,7 @@ menu "Clock driver for MediaTek SoC"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 
 config COMMON_CLK_MEDIATEK
-	bool
+	tristate
 	select RESET_CONTROLLER
 	help
 	  MediaTek SoCs' clock support.
@@ -204,7 +204,7 @@ config COMMON_CLK_MT6765_MIPI2BSYS
          This driver supports MediaTek MT6765 mipi2bsys clocks.
 
 config COMMON_CLK_MT6779
-	bool "Clock driver for MediaTek MT6779"
+	tristate "Clock driver for MediaTek MT6779"
 	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
 	select COMMON_CLK_MEDIATEK
 	default ARCH_MEDIATEK && ARM64
@@ -212,49 +212,49 @@ config COMMON_CLK_MT6779
 	  This driver supports MediaTek MT6779 basic clocks.
 
 config COMMON_CLK_MT6779_MMSYS
-	bool "Clock driver for MediaTek MT6779 mmsys"
+	tristate "Clock driver for MediaTek MT6779 mmsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 mmsys clocks.
 
 config COMMON_CLK_MT6779_IMGSYS
-	bool "Clock driver for MediaTek MT6779 imgsys"
+	tristate "Clock driver for MediaTek MT6779 imgsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 imgsys clocks.
 
 config COMMON_CLK_MT6779_IPESYS
-	bool "Clock driver for MediaTek MT6779 ipesys"
+	tristate "Clock driver for MediaTek MT6779 ipesys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 ipesys clocks.
 
 config COMMON_CLK_MT6779_CAMSYS
-	bool "Clock driver for MediaTek MT6779 camsys"
+	tristate "Clock driver for MediaTek MT6779 camsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 camsys clocks.
 
 config COMMON_CLK_MT6779_VDECSYS
-	bool "Clock driver for MediaTek MT6779 vdecsys"
+	tristate "Clock driver for MediaTek MT6779 vdecsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 vdecsys clocks.
 
 config COMMON_CLK_MT6779_VENCSYS
-	bool "Clock driver for MediaTek MT6779 vencsys"
+	tristate "Clock driver for MediaTek MT6779 vencsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 vencsys clocks.
 
 config COMMON_CLK_MT6779_MFGCFG
-	bool "Clock driver for MediaTek MT6779 mfgcfg"
+	tristate "Clock driver for MediaTek MT6779 mfgcfg"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports MediaTek MT6779 mfgcfg clocks.
 
 config COMMON_CLK_MT6779_AUDSYS
-	bool "Clock driver for Mediatek MT6779 audsys"
+	tristate "Clock driver for Mediatek MT6779 audsys"
 	depends on COMMON_CLK_MT6779
 	help
 	  This driver supports Mediatek MT6779 audsys clocks.
-- 
2.18.0

From miles.chen at mediatek.com  Tue Aug 31 09:42:09 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 1 Sep 2021 00:42:09 +0800
Subject: [PATCH v2 3/4] clk: mediatek: support COMMON_CLK_MT6779 module build
In-Reply-To: <20210831164210.15455-1-miles.chen@mediatek.com>
References: <20210831164210.15455-1-miles.chen@mediatek.com>
Message-ID: <20210831164210.15455-4-miles.chen@mediatek.com>

To support COMMON_CLK_MT6779* module build,
add MODULE_LICENSE and export necessary symbols.

Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Hanks Chen <hanks.chen at mediatek.com>
Cc: Wendell Lin <wendell.lin at mediatek.com>
Cc: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mt6779-aud.c  | 4 +++-
 drivers/clk/mediatek/clk-mt6779-cam.c  | 4 +++-
 drivers/clk/mediatek/clk-mt6779-img.c  | 4 +++-
 drivers/clk/mediatek/clk-mt6779-ipe.c  | 4 +++-
 drivers/clk/mediatek/clk-mt6779-mfg.c  | 4 +++-
 drivers/clk/mediatek/clk-mt6779-mm.c   | 4 +++-
 drivers/clk/mediatek/clk-mt6779-vdec.c | 4 +++-
 drivers/clk/mediatek/clk-mt6779-venc.c | 4 +++-
 drivers/clk/mediatek/clk-mt6779.c      | 2 ++
 9 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt6779-aud.c b/drivers/clk/mediatek/clk-mt6779-aud.c
index 11b209f95e25..9e889e4c361a 100644
--- a/drivers/clk/mediatek/clk-mt6779-aud.c
+++ b/drivers/clk/mediatek/clk-mt6779-aud.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -114,4 +115,5 @@ static struct platform_driver clk_mt6779_aud_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt6779_aud_drv);
+module_platform_driver(clk_mt6779_aud_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-cam.c b/drivers/clk/mediatek/clk-mt6779-cam.c
index 244d4208b7fb..7f07a2a139ac 100644
--- a/drivers/clk/mediatek/clk-mt6779-cam.c
+++ b/drivers/clk/mediatek/clk-mt6779-cam.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -63,4 +64,5 @@ static struct platform_driver clk_mt6779_cam_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt6779_cam_drv);
+module_platform_driver(clk_mt6779_cam_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-img.c b/drivers/clk/mediatek/clk-mt6779-img.c
index 26292a45c613..f0961fa1a286 100644
--- a/drivers/clk/mediatek/clk-mt6779-img.c
+++ b/drivers/clk/mediatek/clk-mt6779-img.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -55,4 +56,5 @@ static struct platform_driver clk_mt6779_img_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt6779_img_drv);
+module_platform_driver(clk_mt6779_img_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-ipe.c b/drivers/clk/mediatek/clk-mt6779-ipe.c
index bb519075639c..8c6f3e154bf3 100644
--- a/drivers/clk/mediatek/clk-mt6779-ipe.c
+++ b/drivers/clk/mediatek/clk-mt6779-ipe.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -57,4 +58,5 @@ static struct platform_driver clk_mt6779_ipe_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt6779_ipe_drv);
+module_platform_driver(clk_mt6779_ipe_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-mfg.c b/drivers/clk/mediatek/clk-mt6779-mfg.c
index c6ee2a89c070..9f3372886e6b 100644
--- a/drivers/clk/mediatek/clk-mt6779-mfg.c
+++ b/drivers/clk/mediatek/clk-mt6779-mfg.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -52,4 +53,5 @@ static struct platform_driver clk_mt6779_mfg_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt6779_mfg_drv);
+module_platform_driver(clk_mt6779_mfg_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-mm.c b/drivers/clk/mediatek/clk-mt6779-mm.c
index 059c1a41ac7a..33946e647122 100644
--- a/drivers/clk/mediatek/clk-mt6779-mm.c
+++ b/drivers/clk/mediatek/clk-mt6779-mm.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/mt6779-clk.h>
@@ -105,4 +106,5 @@ static struct platform_driver clk_mt6779_mm_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt6779_mm_drv);
+module_platform_driver(clk_mt6779_mm_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-vdec.c b/drivers/clk/mediatek/clk-mt6779-vdec.c
index 1900da2586a1..f4358844c2e0 100644
--- a/drivers/clk/mediatek/clk-mt6779-vdec.c
+++ b/drivers/clk/mediatek/clk-mt6779-vdec.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -64,4 +65,5 @@ static struct platform_driver clk_mt6779_vdec_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt6779_vdec_drv);
+module_platform_driver(clk_mt6779_vdec_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779-venc.c b/drivers/clk/mediatek/clk-mt6779-venc.c
index b41d1f859edc..ff67084af5aa 100644
--- a/drivers/clk/mediatek/clk-mt6779-venc.c
+++ b/drivers/clk/mediatek/clk-mt6779-venc.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/clk-provider.h>
 #include <linux/platform_device.h>
 
@@ -55,4 +56,5 @@ static struct platform_driver clk_mt6779_venc_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt6779_venc_drv);
+module_platform_driver(clk_mt6779_venc_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c
index 6e0d3a166729..9825385c9f94 100644
--- a/drivers/clk/mediatek/clk-mt6779.c
+++ b/drivers/clk/mediatek/clk-mt6779.c
@@ -4,6 +4,7 @@
  * Author: Wendell Lin <wendell.lin at mediatek.com>
  */
 
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -1314,3 +1315,4 @@ static int __init clk_mt6779_init(void)
 }
 
 arch_initcall(clk_mt6779_init);
+MODULE_LICENSE("GPL");
-- 
2.18.0

From miles.chen at mediatek.com  Tue Aug 31 09:42:07 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 1 Sep 2021 00:42:07 +0800
Subject: [PATCH v2 1/4] clk: composite: export clk_register_composite
In-Reply-To: <20210831164210.15455-1-miles.chen@mediatek.com>
References: <20210831164210.15455-1-miles.chen@mediatek.com>
Message-ID: <20210831164210.15455-2-miles.chen@mediatek.com>

To support module build of mediatek clk drivers,
it is necessary to export clk_register_composite.

Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Hanks Chen <hanks.chen at mediatek.com>
Cc: Wendell Lin <wendell.lin at mediatek.com>
Cc: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/clk-composite.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 0506046a5f4b..c7b97fb0051b 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -362,6 +362,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
 		return ERR_CAST(hw);
 	return hw->clk;
 }
+EXPORT_SYMBOL_GPL(clk_register_composite);
 
 struct clk *clk_register_composite_pdata(struct device *dev, const char *name,
 			const struct clk_parent_data *parent_data,
-- 
2.18.0

From miles.chen at mediatek.com  Tue Aug 31 09:42:08 2021
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 1 Sep 2021 00:42:08 +0800
Subject: [PATCH v2 2/4] clk: mediatek: support COMMON_CLK_MEDIATEK module build
In-Reply-To: <20210831164210.15455-1-miles.chen@mediatek.com>
References: <20210831164210.15455-1-miles.chen@mediatek.com>
Message-ID: <20210831164210.15455-3-miles.chen@mediatek.com>

To support COMMON_CLK_MEDIATEK module build,
add MODULE_LICENSE and export necessary symbols.

Cc: Stephen Boyd <sboyd at kernel.org>
Cc: Hanks Chen <hanks.chen at mediatek.com>
Cc: Wendell Lin <wendell.lin at mediatek.com>
Cc: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-apmixed.c | 3 +++
 drivers/clk/mediatek/clk-cpumux.c  | 3 +++
 drivers/clk/mediatek/clk-gate.c    | 8 ++++++++
 drivers/clk/mediatek/clk-mtk.c     | 8 ++++++++
 drivers/clk/mediatek/clk-mux.c     | 4 ++++
 drivers/clk/mediatek/clk-pll.c     | 4 ++++
 drivers/clk/mediatek/reset.c       | 2 ++
 7 files changed, 32 insertions(+)

diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c
index 258d128370f2..caa9119413f1 100644
--- a/drivers/clk/mediatek/clk-apmixed.c
+++ b/drivers/clk/mediatek/clk-apmixed.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/slab.h>
 
@@ -97,3 +98,5 @@ struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
 
 	return clk;
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index 79fe09028742..f85c755c9fc1 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -6,6 +6,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/mfd/syscon.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include "clk-mtk.h"
@@ -106,3 +107,5 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 
 	return 0;
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index a35cf0b22150..b02d2f74dd0d 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clkdev.h>
+#include <linux/module.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
@@ -122,24 +123,28 @@ const struct clk_ops mtk_clk_gate_ops_setclr = {
 	.enable		= mtk_cg_enable,
 	.disable	= mtk_cg_disable,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr);
 
 const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
 	.is_enabled	= mtk_cg_bit_is_set,
 	.enable		= mtk_cg_enable_inv,
 	.disable	= mtk_cg_disable_inv,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_setclr_inv);
 
 const struct clk_ops mtk_clk_gate_ops_no_setclr = {
 	.is_enabled	= mtk_cg_bit_is_cleared,
 	.enable		= mtk_cg_enable_no_setclr,
 	.disable	= mtk_cg_disable_no_setclr,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr);
 
 const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
 	.is_enabled	= mtk_cg_bit_is_set,
 	.enable		= mtk_cg_enable_inv_no_setclr,
 	.disable	= mtk_cg_disable_inv_no_setclr,
 };
+EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
 
 struct clk *mtk_clk_register_gate(
 		const char *name,
@@ -181,3 +186,6 @@ struct clk *mtk_clk_register_gate(
 
 	return clk;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_gate);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index cec1c8a27211..cb2dabe60aaf 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clkdev.h>
+#include <linux/module.h>
 #include <linux/mfd/syscon.h>
 #include <linux/device.h>
 
@@ -41,6 +42,7 @@ struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
 
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(mtk_alloc_clk_data);
 
 void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 		int num, struct clk_onecell_data *clk_data)
@@ -67,6 +69,7 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 			clk_data->clks[rc->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks);
 
 void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 		int num, struct clk_onecell_data *clk_data)
@@ -93,6 +96,7 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 			clk_data->clks[ff->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
 
 int mtk_clk_register_gates_with_dev(struct device_node *node,
 		const struct mtk_gate *clks,
@@ -145,6 +149,7 @@ int mtk_clk_register_gates(struct device_node *node,
 	return mtk_clk_register_gates_with_dev(node,
 		clks, num, clk_data, NULL);
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
 
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
@@ -258,6 +263,7 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
 			clk_data->clks[mc->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_composites);
 
 void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			int num, void __iomem *base, spinlock_t *lock,
@@ -286,3 +292,5 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			clk_data->clks[mcd->id] = clk;
 	}
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index b0c61709bacc..a507eea26cc7 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -8,6 +8,7 @@
 #include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/mfd/syscon.h>
+#include <linux/module.h>
 
 #include "clk-mtk.h"
 #include "clk-mux.h"
@@ -190,3 +191,6 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_muxes);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index f440f2cd0b69..399e7b4297c8 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -7,6 +7,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/clkdev.h>
 #include <linux/delay.h>
@@ -368,3 +369,6 @@ void mtk_clk_register_plls(struct device_node *node,
 		clk_data->clks[pll->id] = clk;
 	}
 }
+EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
index cb939c071b0c..9079bfc29ec0 100644
--- a/drivers/clk/mediatek/reset.c
+++ b/drivers/clk/mediatek/reset.c
@@ -137,3 +137,5 @@ void mtk_register_reset_controller_set_clr(struct device_node *np,
 	mtk_register_reset_controller_common(np, num_regs, regofs,
 		&mtk_reset_ops_set_clr);
 }
+
+MODULE_LICENSE("GPL");
-- 
2.18.0

From catalin.marinas at arm.com  Tue Aug 31 09:56:50 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 31 Aug 2021 17:56:50 +0100
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <CAHk-=wg=+P1+HQXhrszxN_BgWtLc-=dWiT61KzogcJU3hnLrtQ@mail.gmail.com>
References: <20210826131747.GE26318@willie-the-truck>
 <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>
 <20210827074041.GA24309@lst.de>
 <CAHk-=wjd28sN9khO=1j6zmBk+2n4_e+SY1URjW9hzsHSAZU+7Q@mail.gmail.com>
 <20210827171041.GA28149@lst.de>
 <CAHk-=wg=+P1+HQXhrszxN_BgWtLc-=dWiT61KzogcJU3hnLrtQ@mail.gmail.com>
Message-ID: <YS5fUqQYWf0AKLgD@arm.com>

On Fri, Aug 27, 2021 at 10:16:27AM -0700, Linus Torvalds wrote:
> On Fri, Aug 27, 2021 at 10:10 AM Christoph Hellwig <hch at lst.de> wrote:
> > They CCed me on their earlier discussion, but I did not catch up on it
> > until you responded to the pull request  If I understood it correct it
> > was about a platform device mapping a MMIO region (like a PCI bar),
> > but something about section alignment cause pfn_valid to mistrigger.
> 
> Yeah, so I can easily see the maxpfn numbers can easily end up being
> rounded up to a whole memory section etc.
> 
> I think my suggested solution should JustWork(tm) - exactly because if
> the area is then in that "this pfn is valid" area, it will
> double-check the actual underlying page.
> 
> That said, I think x86 avoids the problem another way - by just making
> sure max_pfn is exact. That works too, as long as there are no holes
> in the RAM map that might be used for PCI BAR's.
> 
> So I think arm could fix it that way too, depending on their memory layout.

The suggested solution in the original thread was to change the generic
DMA code to use memblock_is_memory() instead of pfn_valid():

https://lore.kernel.org/lkml/b720e7c8-ca44-0a25-480b-05bf49d03c35 at redhat.com/

Given how late we discovered this in the -rc cycle, the decision was to
revert the pfn_valid() patch. We'll re-instate it at some point but
someone needs to sanity check the other pfn_valid() call sites and the
expected semantics.

-- 
Catalin


From zhouzhouyi at gmail.com  Tue Aug 31 10:01:11 2021
From: zhouzhouyi at gmail.com (Zhouyi Zhou)
Date: Wed, 1 Sep 2021 01:01:11 +0800
Subject: rcu_preempt detected stalls
In-Reply-To: <20210831152144.GA28128@trex>
References: <20210831152144.GA28128@trex>
Message-ID: <CAABZP2xGnSLVbgxqjKMq=Oj_H7rYfYjuCvmBpmZ4tRptGs3SEw@mail.gmail.com>

I did an experiment just now on x86_64 virtual machines, rcu did not
complain after 10 minutes's test, I hope my effort can provide some
clue.

1. I clone the fresh new linux kernel (git clone
https://kernel.source.codeaurora.cn/pub/scm/linux/kernel/git/torvalds/linux.git)
2. compile the kernel without CONFIG_RCU_BOOST (: # CONFIG_RCU_BOOST is not set)
3. boot the kernel on a x86_64 VM (kvm -cpu host -smp 16  -hda
./debian10.qcow2 -m 4096 -net
user,hostfwd=tcp::5556-:22,hostfwd=tcp::5555-:19 -net nic,model=e1000
-vnc :30)
4. run the test (stress-ng --sequential 16  --class scheduler -t 5m --times)
5. monitor the system by constantly typing top and dmesg
6. after 10 minutes, nothing else happens except that the dmesg report
following two messages
[  672.528192] sched: DL replenish lagged too much
[  751.127790] hrtimer: interrupt took 12143 ns

So, I guess CONFIG_RCU_BOOST is not necessary for x86_64 virtual machines

Zhouyi

On Tue, Aug 31, 2021 at 11:24 PM Jorge Ramirez-Ortiz, Foundries
<jorge at foundries.io> wrote:
>
> Hi
>
> When enabling CONFIG_PREEMPT and running the stress-ng scheduler class
> tests on arm64 (xilinx zynqmp and imx imx8mm SoCs) we are observing the following.
>
> [   62.578917] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> [   62.585015]  (detected by 0, t=5253 jiffies, g=3017, q=2972)
> [   62.590663] rcu: All QSes seen, last rcu_preempt kthread activity 5254 (4294907943-4294902689), jiffies_till_next_fqs=1, root
> +->qsmask 0x0
> [   62.603086] rcu: rcu_preempt kthread starved for 5258 jiffies! g3017 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1
> [   62.613246] rcu:     Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
> [   62.622359] rcu: RCU grace-period kthread stack dump:
> [   62.627395] task:rcu_preempt     state:R  running task     stack:    0 pid:   14 ppid:     2 flags:0x00000028
> [   62.637308] Call trace:
> [   62.639748]  __switch_to+0x11c/0x190
> [   62.643319]  __schedule+0x3b8/0x8d8
> [   62.646796]  schedule+0x4c/0x108
> [   62.650018]  schedule_timeout+0x1ac/0x358
> [   62.654021]  rcu_gp_kthread+0x6a8/0x12b8
> [   62.657933]  kthread+0x14c/0x158
> [   62.661153]  ret_from_fork+0x10/0x18
> [   62.682919] BUG: scheduling while atomic: stress-ng-hrtim/831/0x00000002
> [   62.689604] Preemption disabled at:
> [   62.689614] [<ffffffc010059418>] irq_enter_rcu+0x30/0x58
> [   62.698393] CPU: 0 PID: 831 Comm: stress-ng-hrtim Not tainted 5.10.42+ #5
> [   62.706296] Hardware name: Zynqmp new (DT)
> [   62.710115] Call trace:
> [   62.712548]  dump_backtrace+0x0/0x240
> [   62.716202]  show_stack+0x2c/0x38
> [   62.719510]  dump_stack+0xcc/0x104
> [   62.722904]  __schedule_bug+0x78/0xc8
> [   62.726556]  __schedule+0x70c/0x8d8
> [   62.730037]  schedule+0x4c/0x108
> [   62.733259]  do_notify_resume+0x224/0x5d8
> [   62.737259]  work_pending+0xc/0x2a4
>
> The error results in OOM eventually.
>
> RCU priority boosting does work around this issue but it seems to me
> a workaround more than a fix (otherwise boosting would be enabled
> by CONFIG_PREEMPT for arm64 I guess?).
>
> The question is: is this an arm64 bug that should be investigated? or
> is this some known corner case of running stress-ng that is already
> understood?
>
> thanks
> Jorge
>
>
>


From kuba at kernel.org  Tue Aug 31 10:10:23 2021
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 31 Aug 2021 10:10:23 -0700
Subject: [PATCH v3] stmmac: dwmac-loongson: change the pr_info() to
 dev_err() in loongson_dwmac_probe()
In-Reply-To: <20210831012523.2691-1-zhaoxiao@uniontech.com>
References: <20210831012523.2691-1-zhaoxiao@uniontech.com>
Message-ID: <20210831101023.53c3f67b@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Tue, 31 Aug 2021 09:25:23 +0800 zhaoxiao wrote:
> Change the pr_info to dev_err.
> 
> Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>

Your patches seem to not show up on the netdev mailing list.
They do make it to lkml and linux-arm tho, strangely.

Are you seeing any errors when sending them?

Please repost this one and CC warthog9 at kernel.org - let's see 
if it gets thru..


From zhouzhouyi at gmail.com  Tue Aug 31 10:11:59 2021
From: zhouzhouyi at gmail.com (Zhouyi Zhou)
Date: Wed, 1 Sep 2021 01:11:59 +0800
Subject: rcu_preempt detected stalls
In-Reply-To: <CAABZP2xGnSLVbgxqjKMq=Oj_H7rYfYjuCvmBpmZ4tRptGs3SEw@mail.gmail.com>
References: <20210831152144.GA28128@trex>
 <CAABZP2xGnSLVbgxqjKMq=Oj_H7rYfYjuCvmBpmZ4tRptGs3SEw@mail.gmail.com>
Message-ID: <CAABZP2wUdToiAWOAgqDZrZtkuEdrXEv9GDgbioW3PZAyseOSgA@mail.gmail.com>

followings are some of my kernel config options:
CONFIG_PREEMPT=y
CONFIG_PREEMPT_COUNT=y
CONFIG_PREEMPTION=y
CONFIG_PREEMPT_DYNAMIC=y
CONFIG_PREEMPT_RCU=y
CONFIG_HAVE_PREEMPT_DYNAMIC=y
CONFIG_TREE_RCU=y
CONFIG_PREEMPT_RCU=y
CONFIG_RCU_EXPERT=y
CONFIG_SRCU=y
CONFIG_TREE_SRCU=y
CONFIG_TASKS_RCU_GENERIC=y
CONFIG_TASKS_RCU=y
CONFIG_TASKS_RUDE_RCU=y
CONFIG_TASKS_TRACE_RCU=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_NEED_SEGCBLIST=y
CONFIG_RCU_FANOUT=64
CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_RCU_FAST_NO_HZ is not set
# CONFIG_RCU_BOOST is not set
CONFIG_RCU_NOCB_CPU=y
# CONFIG_TASKS_TRACE_RCU_READ_MB is not set
# end of RCU Subsystem
CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
# RCU Debugging
CONFIG_PROVE_RCU=y
# CONFIG_PROVE_RCU_LIST is not set
# CONFIG_RCU_SCALE_TEST is not set
CONFIG_RCU_TORTURE_TEST=m
# CONFIG_RCU_REF_SCALE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21
# CONFIG_RCU_TRACE is not set
# CONFIG_RCU_EQS_DEBUG is not set

Thanks
Zhouyi

On Wed, Sep 1, 2021 at 1:01 AM Zhouyi Zhou <zhouzhouyi at gmail.com> wrote:
>
> I did an experiment just now on x86_64 virtual machines, rcu did not
> complain after 10 minutes's test, I hope my effort can provide some
> clue.
>
> 1. I clone the fresh new linux kernel (git clone
> https://kernel.source.codeaurora.cn/pub/scm/linux/kernel/git/torvalds/linux.git)
> 2. compile the kernel without CONFIG_RCU_BOOST (: # CONFIG_RCU_BOOST is not set)
> 3. boot the kernel on a x86_64 VM (kvm -cpu host -smp 16  -hda
> ./debian10.qcow2 -m 4096 -net
> user,hostfwd=tcp::5556-:22,hostfwd=tcp::5555-:19 -net nic,model=e1000
> -vnc :30)
> 4. run the test (stress-ng --sequential 16  --class scheduler -t 5m --times)
> 5. monitor the system by constantly typing top and dmesg
> 6. after 10 minutes, nothing else happens except that the dmesg report
> following two messages
> [  672.528192] sched: DL replenish lagged too much
> [  751.127790] hrtimer: interrupt took 12143 ns
>
> So, I guess CONFIG_RCU_BOOST is not necessary for x86_64 virtual machines
>
> Zhouyi
>
> On Tue, Aug 31, 2021 at 11:24 PM Jorge Ramirez-Ortiz, Foundries
> <jorge at foundries.io> wrote:
> >
> > Hi
> >
> > When enabling CONFIG_PREEMPT and running the stress-ng scheduler class
> > tests on arm64 (xilinx zynqmp and imx imx8mm SoCs) we are observing the following.
> >
> > [   62.578917] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> > [   62.585015]  (detected by 0, t=5253 jiffies, g=3017, q=2972)
> > [   62.590663] rcu: All QSes seen, last rcu_preempt kthread activity 5254 (4294907943-4294902689), jiffies_till_next_fqs=1, root
> > +->qsmask 0x0
> > [   62.603086] rcu: rcu_preempt kthread starved for 5258 jiffies! g3017 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1
> > [   62.613246] rcu:     Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
> > [   62.622359] rcu: RCU grace-period kthread stack dump:
> > [   62.627395] task:rcu_preempt     state:R  running task     stack:    0 pid:   14 ppid:     2 flags:0x00000028
> > [   62.637308] Call trace:
> > [   62.639748]  __switch_to+0x11c/0x190
> > [   62.643319]  __schedule+0x3b8/0x8d8
> > [   62.646796]  schedule+0x4c/0x108
> > [   62.650018]  schedule_timeout+0x1ac/0x358
> > [   62.654021]  rcu_gp_kthread+0x6a8/0x12b8
> > [   62.657933]  kthread+0x14c/0x158
> > [   62.661153]  ret_from_fork+0x10/0x18
> > [   62.682919] BUG: scheduling while atomic: stress-ng-hrtim/831/0x00000002
> > [   62.689604] Preemption disabled at:
> > [   62.689614] [<ffffffc010059418>] irq_enter_rcu+0x30/0x58
> > [   62.698393] CPU: 0 PID: 831 Comm: stress-ng-hrtim Not tainted 5.10.42+ #5
> > [   62.706296] Hardware name: Zynqmp new (DT)
> > [   62.710115] Call trace:
> > [   62.712548]  dump_backtrace+0x0/0x240
> > [   62.716202]  show_stack+0x2c/0x38
> > [   62.719510]  dump_stack+0xcc/0x104
> > [   62.722904]  __schedule_bug+0x78/0xc8
> > [   62.726556]  __schedule+0x70c/0x8d8
> > [   62.730037]  schedule+0x4c/0x108
> > [   62.733259]  do_notify_resume+0x224/0x5d8
> > [   62.737259]  work_pending+0xc/0x2a4
> >
> > The error results in OOM eventually.
> >
> > RCU priority boosting does work around this issue but it seems to me
> > a workaround more than a fix (otherwise boosting would be enabled
> > by CONFIG_PREEMPT for arm64 I guess?).
> >
> > The question is: is this an arm64 bug that should be investigated? or
> > is this some known corner case of running stress-ng that is already
> > understood?
> >
> > thanks
> > Jorge
> >
> >
> >


From saravanak at google.com  Tue Aug 31 10:30:39 2021
From: saravanak at google.com (Saravana Kannan)
Date: Tue, 31 Aug 2021 10:30:39 -0700
Subject: [PATCH 1/2] of: property: fw_devlink: Rename 'node_not_dev' to
 'optional_con_dev'
In-Reply-To: <20210831102125.624661-1-ulf.hansson@linaro.org>
References: <20210831102125.624661-1-ulf.hansson@linaro.org>
Message-ID: <CAGETcx868QWj0jMJ+U-eL62jT-LO_LTOw5EcwEKptfFOVa=A5A@mail.gmail.com>

On Tue, Aug 31, 2021 at 3:21 AM Ulf Hansson <ulf.hansson at linaro.org> wrote:
>
> In the struct supplier_bindings the member 'node_not_dev' is described as
> "The consumer node containing the property is never a device.", but that
> doesn't match the behaviour of the code in of_link_property().
>
> To make the behaviour consistent with the description, let's rename the
> member to "optional_con_dev" and clarify the corresponding comment.
>
> Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
> ---
>  drivers/of/property.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/of/property.c b/drivers/of/property.c
> index 6c028632f425..2babb1807228 100644
> --- a/drivers/of/property.c
> +++ b/drivers/of/property.c
> @@ -1249,7 +1249,8 @@ static struct device_node *parse_##fname(struct device_node *np,       \
>   * @parse_prop.index: For properties holding a list of phandles, this is the
>   *                   index into the list
>   * @optional: Describes whether a supplier is mandatory or not
> - * @node_not_dev: The consumer node containing the property is never a device.
> + * @optional_con_dev: The consumer node containing the property may not be a
> + *                   device, then try finding one from an ancestor node.

Nak. This flag is not about "may not be". This is explicitly for
"never a device". It has to do with stuff like remote-endpoint which
is never listed under the root node of the device node. Your
documentation change is changing the meaning of the flag.

-Saravana

>   *
>   * Returns:
>   * parse_prop() return values are
> @@ -1261,7 +1262,7 @@ struct supplier_bindings {
>         struct device_node *(*parse_prop)(struct device_node *np,
>                                           const char *prop_name, int index);
>         bool optional;
> -       bool node_not_dev;
> +       bool optional_con_dev;
>  };
>
>  DEFINE_SIMPLE_PROP(clocks, "clocks", "#clock-cells")
> @@ -1370,7 +1371,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
>         { .parse_prop = parse_pinctrl6, },
>         { .parse_prop = parse_pinctrl7, },
>         { .parse_prop = parse_pinctrl8, },
> -       { .parse_prop = parse_remote_endpoint, .node_not_dev = true, },
> +       { .parse_prop = parse_remote_endpoint, .optional_con_dev = true, },
>         { .parse_prop = parse_gpio_compat, },
>         { .parse_prop = parse_interrupts, },
>         { .parse_prop = parse_regulators, },
> @@ -1415,7 +1416,7 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
>                 while ((phandle = s->parse_prop(con_np, prop_name, i))) {
>                         struct device_node *con_dev_np;
>
> -                       con_dev_np = s->node_not_dev
> +                       con_dev_np = s->optional_con_dev
>                                         ? of_get_compat_node(con_np)
>                                         : of_node_get(con_np);
>                         matched = true;
> --
> 2.25.1
>


From marex at denx.de  Tue Aug 31 10:38:44 2021
From: marex at denx.de (Marek Vasut)
Date: Tue, 31 Aug 2021 19:38:44 +0200
Subject: [PATCH] ARM: imx_v6_v7_defconfig: enable driver of the LTC3676
 PMIC
In-Reply-To: <f8fdb350-71dc-9688-c7b5-b4da18bf4b18@denx.de>
References: <20210805135035.124938-1-pzimmermann@dh-electronics.com>
 <54505ae8-075c-bc54-e039-0badc261fa27@denx.de>
 <20210814054055.GX30984@dragon>
 <2a3e56b8-7fd7-44ec-4090-7fe2b5d7863c@denx.de> <20210814112424.GA9470@dragon>
 <f8fdb350-71dc-9688-c7b5-b4da18bf4b18@denx.de>
Message-ID: <c92abfc3-4009-9f60-0d71-8489487a1c45@denx.de>

On 8/14/21 4:31 PM, Marek Vasut wrote:
> On 8/14/21 1:24 PM, Shawn Guo wrote:
>> On Sat, Aug 14, 2021 at 09:45:03AM +0200, Marek Vasut wrote:
>>> On 8/14/21 7:40 AM, Shawn Guo wrote:
>>>> On Tue, Aug 10, 2021 at 07:36:24AM +0200, Marek Vasut wrote:
>>>>> On 8/5/21 3:50 PM, Pascal Zimmermann wrote:
>>>>>> The LTC3676 is a PMIC which is used on some i.MX6 based boards 
>>>>>> (like the
>>>>>> DHCOM i.MX6 Quad SoM), it was first used on the GW Ventana board, 
>>>>>> enable
>>>>>> LTC3676 driver in imx_v6_v7_defconfig.
>>>>>>
>>>>>> Fixes: e3946fe805053 ("ARM: dts: add Gateworks Ventana support")
>>>>
>>>> I don't think the Fixes tag is appropriate here.? Dropped it and 
>>>> applied
>>>> patch.
>>>
>>> Can you please elaborate why do you think the Fixes tag is not 
>>> appropriate ?
>>>
>>> Neither system can work properly without the PMIC driver, so I 
>>> believe the
>>> Fixes tag is correct and this should be backported to older LTS kernel
>>> releases.
>>
>> It's enabling a feature (driver) rather than fixing a bug or regression.
>> If you want to enable it for LTS kernel, go ahead to back port it.
>> Do not abuse the Fixes tag.
> 
> I disagree with this. Without the PMIC driver, the system is basically 
> unusable. That is because the internal regulators in the MX6 depend on 
> the PMIC, so those fail to probe, and in turn all the other components 
> which depend on those internal regulators also fail to probe (that is 
> everything which depends on anatop regulators).
> 
> If I take linux-stable, compile it for a system that is supported in 
> there, with the imx_v6_v7_defconfig which is part of it, I would expect 
> the result to work properly, not just barely boot and be barely usable.
> 
> Therefore, I believe the Fixes tag here is justified.

I am curious, is there any further clarification ?


From catalin.marinas at arm.com  Tue Aug 31 10:40:48 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 31 Aug 2021 18:40:48 +0100
Subject: [PATCH] arm64: kdump: Skip kmemleak scan reserved memory for kdump
In-Reply-To: <20210827092246.3565437-1-chenwandun@huawei.com>
References: <20210827092246.3565437-1-chenwandun@huawei.com>
Message-ID: <YS5poB8hPd1kfdVZ@arm.com>

On Fri, Aug 27, 2021 at 05:22:46PM +0800, Chen Wandun wrote:
> Trying to boot with kdump + kmemleak, command will result in a crash:
> "echo scan > /sys/kernel/debug/kmemleak"
> 
> crashkernel reserved: 0x0000000007c00000 - 0x0000000027c00000 (512 MB)
> Kernel command line: BOOT_IMAGE=(hd1,gpt2)/vmlinuz-5.14.0-rc5-next-20210809+ root=/dev/mapper/ao-root ro rd.lvm.lv=ao/root rd.lvm.lv=ao/swap crashkernel=512M
> Unable to handle kernel paging request at virtual address ffff000007c00000
> Mem abort info:
>   ESR = 0x96000007
>   EC = 0x25: DABT (current EL), IL = 32 bits
>   SET = 0, FnV = 0
>   EA = 0, S1PTW = 0
>   FSC = 0x07: level 3 translation fault
> Data abort info:
>   ISV = 0, ISS = 0x00000007
>   CM = 0, WnR = 0
> swapper pgtable: 64k pages, 48-bit VAs, pgdp=00002024f0d80000
> [ffff000007c00000] pgd=1800205ffffd0003, p4d=1800205ffffd0003, pud=1800205ffffd0003, pmd=1800205ffffc0003, pte=0068000007c00f06
> Internal error: Oops: 96000007 [#1] SMP
> pstate: 804000c9 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : scan_block+0x98/0x230
> lr : scan_block+0x94/0x230
> sp : ffff80008d6cfb70
> x29: ffff80008d6cfb70 x28: 0000000000000000 x27: 0000000000000000
> x26: 00000000000000c0 x25: 0000000000000001 x24: 0000000000000000
> x23: ffffa88a6b18b398 x22: ffff000007c00ff9 x21: ffffa88a6ac7fc40
> x20: ffffa88a6af6a830 x19: ffff000007c00000 x18: 0000000000000000
> x17: 0000000000000000 x16: 0000000000000000 x15: ffffffffffffffff
> x14: ffffffff00000000 x13: ffffffffffffffff x12: 0000000000000020
> x11: 0000000000000000 x10: 0000000001080000 x9 : ffffa88a6951c77c
> x8 : ffffa88a6a893988 x7 : ffff203ff6cfb3c0 x6 : ffffa88a6a52b3c0
> x5 : ffff203ff6cfb3c0 x4 : 0000000000000000 x3 : 0000000000000000
> x2 : 0000000000000001 x1 : ffff20226cb56a40 x0 : 0000000000000000
> Call trace:
>  scan_block+0x98/0x230
>  scan_gray_list+0x120/0x270
>  kmemleak_scan+0x3a0/0x648
>  kmemleak_write+0x3ac/0x4c8
>  full_proxy_write+0x6c/0xa0
>  vfs_write+0xc8/0x2b8
>  ksys_write+0x70/0xf8
>  __arm64_sys_write+0x24/0x30
>  invoke_syscall+0x4c/0x110
>  el0_svc_common+0x9c/0x190
>  do_el0_svc+0x30/0x98
>  el0_svc+0x28/0xd8
>  el0t_64_sync_handler+0x90/0xb8
>  el0t_64_sync+0x180/0x184
> 
> The reserved memory for kdump will be looked up by kmemleak, this area
> will be set invalid when kdump service is bring up. That will result in
> crash when kmemleak scan this area.
> 
> Fixes: 461ef12c4375 ("memblock: make memblock_find_in_range method private")
> Signed-off-by: Chen Wandun <chenwandun at huawei.com>
> ---
>  arch/arm64/mm/init.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index b16be52233c6..dc0c44622bfd 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -30,6 +30,7 @@
>  #include <linux/crash_dump.h>
>  #include <linux/hugetlb.h>
>  #include <linux/acpi_iort.h>
> +#include <linux/kmemleak.h>
>  
>  #include <asm/boot.h>
>  #include <asm/fixmap.h>
> @@ -101,6 +102,7 @@ static void __init reserve_crashkernel(void)
>  	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>  		crash_base, crash_base + crash_size, crash_size >> 20);
>  
> +	kmemleak_ignore_phys(crash_base);
>  	crashk_res.start = crash_base;
>  	crashk_res.end = crash_base + crash_size - 1;
>  }

I'd add a comment here along the lines of (feel free to change it):

	/*
	 * The crashkernel memory will be removed from the kernel linear
	 * map. Inform kmemleak so that it won't try to access it.
	 */

With that:

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Tue Aug 31 10:44:14 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 31 Aug 2021 18:44:14 +0100
Subject: ucontext, kernel vs. userspace (glibc)
In-Reply-To: <131d684ea46de6330ab90532ab73729d6c0690bd.camel@kernel.crashing.org>
References: <131d684ea46de6330ab90532ab73729d6c0690bd.camel@kernel.crashing.org>
Message-ID: <YS5qbkE0WIDsF4qK@arm.com>

Hi Ben,

On Mon, Aug 30, 2021 at 08:40:03PM +1000, Benjamin Herrenschmidt wrote:
> So I'm discovering arm64 intricacies and today, as I was looking at SVE
> support (in the context of distro glibc backports.. don't ask), I
> noticed that glibc has no provision for dealing with kernel generated
> ucontext's in its {get,set,swap}_context functions...
> 
> (It says so explicitly in the code unless I misunderstood).
> 
> So one thing we did to "solve" this on ppc64 a while ago was to create
> a swapcontext syscall which can operate as all 3 operations (you can
> have NULL arguments), which also handles the sigprocmask (bonus:
> atomically with the context get/set from a userspace perspective).
> 
> Would it make sense to do something similar on aarch64 ? (And have
> glibc then exploit it).
> 
> The hard-to-solve thing is the case where the SVE context spills
> outside of the ucontext itself, in the extra room on the stack, since
> programs that "now" about ucontext will not have allocated space for
> that, so that's more/less a lost cause already.

I haven't fully parsed your email yet but adding a Mark B for SVE and
Szabolcs for glibc (and removing Dave who left Arm recently).

-- 
Catalin


From saravanak at google.com  Tue Aug 31 10:50:32 2021
From: saravanak at google.com (Saravana Kannan)
Date: Tue, 31 Aug 2021 10:50:32 -0700
Subject: [PATCH 2/2] of: property: fw_devlink: Set 'optional_con_dev' for
 parse_power_domains
In-Reply-To: <20210831102141.624725-1-ulf.hansson@linaro.org>
References: <20210831102141.624725-1-ulf.hansson@linaro.org>
Message-ID: <CAGETcx8FKnmeCh3dD1b2TYXf3gwHnW-iWwfz0q-9UzeP2VZSDw@mail.gmail.com>

On Tue, Aug 31, 2021 at 3:21 AM Ulf Hansson <ulf.hansson at linaro.org> wrote:
>
> The power-domain DT bindings [1] doesn't enforce a compatible string for a
> provider node, even if this is common to use. In particular, when
> describing a hierarchy with parent/child power-domains, as the psci DT
> bindings [2] for example, it's sometimes not applicable to use a compatible
> string.

Ok, and fw_devlink handles that -- provider not having a compatible
string is pretty common. In these cases, the parent node is the actual
device that gets probed and registers the provider. So fw_devlink will
create a link from the consumer to the parent device node.

> Therefore, let's set the 'optional_con_dev' to true to avoid creating
> incorrect fw_devlinks for power-domains.

This part doesn't make sense or is incomplete. What is being done incorrectly?

>
> [1] Documentation/devicetree/bindings/power/power-domain.yaml
> [2] Documentation/devicetree/bindings/arm/psci.yaml
>
> Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
> ---
>
> Some more details of what goes on here. I have added a debug print in
> of_link_to_phandle() to see the fw_devlinks that gets created.
>
> This is what happens on Dragonboard 410c when 'optional_con_dev' isn't set:
> ...
> [    0.041274] device: 'psci': device_add
> [    0.041366] OF: Linking power-domain-cpu0 (consumer) to psci (supplier)
> [    0.041395] OF: Linking power-domain-cpu1 (consumer) to psci (supplier)
> [    0.041423] OF: Linking power-domain-cpu2 (consumer) to psci (supplier)
> [    0.041451] OF: Linking power-domain-cpu3 (consumer) to psci (supplier)
> [    0.041494] device: 'platform:psci--platform:psci': device_add
> [    0.041556] platform psci: Linked as a sync state only consumer to psci
> ...
>
> This is what happens on Dragonboard 410c when 'optional_con_dev' is set:
> ...
> [    0.041179] device: 'psci': device_add
> [    0.041265] OF: Not linking psci to psci - is descendant
> [    0.041293] OF: Not linking psci to psci - is descendant
> [    0.041319] OF: Not linking psci to psci - is descendant
> [    0.041346] OF: Not linking psci to psci - is descendant
> ...

Can you please explain what exactly is going on that's wrong here? I
notice that psci is not probed as a device at all. And when you aren't
setting this flag the only difference I see is the creating of a sync
state only link -- which shouldn't matter here because you don't even
have a driver implemented.

> The relevant dtsi file:
> arch/arm64/boot/dts/qcom/msm8916.dtsi
>
> Kind regards
> Ulf Hansson
>
> ---
>  drivers/of/property.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/of/property.c b/drivers/of/property.c
> index 2babb1807228..4d607fdbea24 100644
> --- a/drivers/of/property.c
> +++ b/drivers/of/property.c
> @@ -1356,7 +1356,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
>         { .parse_prop = parse_io_channels, },
>         { .parse_prop = parse_interrupt_parent, },
>         { .parse_prop = parse_dmas, .optional = true, },
> -       { .parse_prop = parse_power_domains, },
> +       { .parse_prop = parse_power_domains, .optional_con_dev = true, },

This change is just shooting in dark/completely unrelated to the
commit text. This is just saying the actual consumer is a level up
from where the property is listed (eg: remote-endpoint). It just
happens to fix your case for unrelated reasons.

Definite Nak as this *will* break other cases.

-Saravana


>         { .parse_prop = parse_hwlocks, },
>         { .parse_prop = parse_extcon, },
>         { .parse_prop = parse_nvmem_cells, },
> --
> 2.25.1
>


From mathieu.poirier at linaro.org  Tue Aug 31 11:01:56 2021
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 31 Aug 2021 12:01:56 -0600
Subject: [PATCH v2 2/2] remoteproc: imx_dsp_rproc: add remoteproc driver
 for dsp on i.MX
In-Reply-To: <1629876516-16513-2-git-send-email-shengjiu.wang@nxp.com>
References: <1629876516-16513-1-git-send-email-shengjiu.wang@nxp.com>
 <1629876516-16513-2-git-send-email-shengjiu.wang@nxp.com>
Message-ID: <20210831180156.GA981305@p14s>

Hi Shengjiu,

On Wed, Aug 25, 2021 at 03:28:36PM +0800, Shengjiu Wang wrote:
> Provide a basic driver to control DSP processor found on NXP i.MX8QM,
> i.MX8QXP, i.MX8MP and i.MX8ULP.
> 
> Currently it is able to resolve addresses between DSP and main CPU,
> start and stop the processor, suspend and resume.
> 
> The communication between DSP and main CPU is based on mailbox, there
> are three mailbox channels (tx, rx, rxdb).
> 
> This driver was tested on NXP i.MX8QM, i.MX8QXP, i.MX8MP and i.MX8ULP.
> 
> Signed-off-by: Shengjiu Wang <shengjiu.wang at nxp.com>
> ---
> changes in v2:
> - change syscon to fsl,dsp-ctrl
> 
>  drivers/remoteproc/Kconfig         |   11 +
>  drivers/remoteproc/Makefile        |    1 +
>  drivers/remoteproc/imx_dsp_rproc.c | 1078 ++++++++++++++++++++++++++++
>  3 files changed, 1090 insertions(+)
>  create mode 100644 drivers/remoteproc/imx_dsp_rproc.c
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 9a6eedc3994a..890a14e6f3f9 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -34,6 +34,17 @@ config IMX_REMOTEPROC
>  
>  	  It's safe to say N here.
>  
> +config IMX_DSP_REMOTEPROC
> +	tristate "i.MX DSP remoteproc support"
> +	depends on ARCH_MXC
> +	depends on HAVE_ARM_SMCCC
> +	select MAILBOX
> +	help
> +	  Say y here to support iMX's DSP remote processors via the remote
> +	  processor framework.
> +
> +	  It's safe to say N here.
> +
>  config INGENIC_VPU_RPROC
>  	tristate "Ingenic JZ47xx VPU remoteproc support"
>  	depends on MIPS || COMPILE_TEST
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index bb26c9e4ef9c..37d5cb1c04bf 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -12,6 +12,7 @@ remoteproc-y				+= remoteproc_virtio.o
>  remoteproc-y				+= remoteproc_elf_loader.o
>  obj-$(CONFIG_REMOTEPROC_CDEV)		+= remoteproc_cdev.o
>  obj-$(CONFIG_IMX_REMOTEPROC)		+= imx_rproc.o
> +obj-$(CONFIG_IMX_DSP_REMOTEPROC)	+= imx_dsp_rproc.o
>  obj-$(CONFIG_INGENIC_VPU_RPROC)		+= ingenic_rproc.o
>  obj-$(CONFIG_MTK_SCP)			+= mtk_scp.o mtk_scp_ipi.o
>  obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
> diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
> new file mode 100644
> index 000000000000..ce0596694122
> --- /dev/null
> +++ b/drivers/remoteproc/imx_dsp_rproc.c
> @@ -0,0 +1,1078 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright 2021 NXP
> +
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mailbox_client.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_reserved_mem.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/regmap.h>
> +#include <linux/remoteproc.h>
> +#include <linux/slab.h>
> +#include <linux/pm_runtime.h>

Alphabetical order

> +#include <linux/workqueue.h>
> +#include <linux/firmware/imx/sci.h>

Same

> +#include <dt-bindings/firmware/imx/rsrc.h>
> +#include <linux/arm-smccc.h>

Same

> +
> +#include "remoteproc_internal.h"
> +#include "remoteproc_elf_helpers.h"

Same

> +
> +enum imx_dsp_rp_mbox_messages {
> +	RP_MBOX_SUSPEND_SYSTEM  = 0xFF11,
> +	RP_MBOX_SUSPEND_ACK     = 0xFF12,
> +	RP_MBOX_RESUME_SYSTEM   = 0xFF13,
> +	RP_MBOX_RESUME_ACK      = 0xFF14,
> +};
> +
> +#define DSP_RPROC_CLK_MAX 32
> +
> +#define REMOTE_IS_READY			BIT(0)
> +#define REMOTE_READY_WAIT_MAX_RETRIES	500
> +
> +/* att flags */
> +/* DSP own area. Can be mapped at probe */
> +#define ATT_OWN		BIT(31)
> +#define ATT_IRAM	BIT(30)
> +
> +/* i.MX8MP */
> +/* DAP registers */
> +#define IMX8M_DAP_DEBUG                0x28800000
> +#define IMX8M_DAP_DEBUG_SIZE           (64 * 1024)
> +#define IMX8M_DAP_PWRCTL               (0x4000 + 0x3020)
> +#define IMX8M_PWRCTL_CORERESET         BIT(16)
> +
> +/* DSP audio mix registers */
> +#define IMX8M_AudioDSP_REG0   0x100
> +#define IMX8M_AudioDSP_REG1   0x104
> +#define IMX8M_AudioDSP_REG2   0x108
> +#define IMX8M_AudioDSP_REG3   0x10c
> +
> +#define IMX8M_AudioDSP_REG2_RUNSTALL  BIT(5)
> +#define IMX8M_AudioDSP_REG2_PWAITMODE BIT(1)
> +
> +/* i.MX8ULP */
> +#define IMX8ULP_SIM_LPAV_REG_SYSCTRL0       0x8
> +#define IMX8ULP_SYSCTRL0_DSP_DBG_RST        BIT(25)
> +#define IMX8ULP_SYSCTRL0_DSP_PLAT_CLK_EN    BIT(19)
> +#define IMX8ULP_SYSCTRL0_DSP_PBCLK_EN       BIT(18)
> +#define IMX8ULP_SYSCTRL0_DSP_CLK_EN         BIT(17)
> +#define IMX8ULP_SYSCTRL0_DSP_RST            BIT(16)
> +#define IMX8ULP_SYSCTRL0_DSP_OCD_HALT       BIT(14)
> +#define IMX8ULP_SYSCTRL0_DSP_STALL          BIT(13)
> +
> +#define IMX8ULP_SIP_HIFI_XRDC         0xc200000e

For all of the above defines, either align them all or not at all.

> +
> +/* address translation table */
> +struct imx_dsp_rproc_att {
> +	u32 da;	/* device address (From Cortex M4 view)*/
> +	u32 sa;	/* system bus address */
> +	u32 size; /* size of reg range */
> +	int flags;
> +};

This is already defined in imx_rproc.c - why do we need another definition here?

> +
> +/* Remote core start/stop method */
> +enum imx_dsp_rproc_method {
> +	/* Through syscon regmap */
> +	IMX_DSP_MMIO,
> +	IMX_DSP_SCU_API,
> +};

>From where I stand it would be worth merging the above with imx_rproc_method
found in imx_rproc.c.  I don't see a need for duplication.

> +
> +struct imx_dsp_rproc {
> +	struct device			*dev;
> +	struct regmap			*regmap;
> +	struct rproc			*rproc;
> +	const struct imx_dsp_rproc_dcfg	*dcfg;
> +	struct clk			*clks[DSP_RPROC_CLK_MAX];
> +	struct mbox_client		cl;
> +	struct mbox_client		cl_rxdb;
> +	struct mbox_chan		*tx_ch;
> +	struct mbox_chan		*rx_ch;
> +	struct mbox_chan		*rxdb_ch;
> +	struct device			**pd_dev;
> +	struct device_link		**pd_dev_link;
> +	struct imx_sc_ipc		*ipc_handle;
> +	struct work_struct		rproc_work;
> +	struct workqueue_struct		*workqueue;
> +	struct completion		pm_comp;
> +	spinlock_t			mbox_lock;    /* lock for mbox */
> +	int				num_domains;
> +	u32				flags;
> +};
> +
> +struct imx_dsp_rproc_dcfg {
> +	u32				src_reg;
> +	u32				src_mask;
> +	u32				src_start;
> +	u32				src_stop;
> +	const struct imx_dsp_rproc_att	*att;
> +	size_t				att_size;
> +	enum imx_dsp_rproc_method	method;

The above is similar to imx_rproc_cfg.  As such:

struct imx_dsp_rproc_dcfg {
        struct imx_rproc_cfg            *dcfg;
        int (*reset)(struct imx_dsp_rproc *priv);
};

> +	int (*reset)(struct imx_dsp_rproc *priv);
> +};
> +
> +static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8qm[] = {
> +	/* dev addr , sys addr  , size	    , flags */
> +	{ 0x596e8000, 0x556e8000, 0x00008000, ATT_OWN },
> +	{ 0x596f0000, 0x556f0000, 0x00008000, ATT_OWN },
> +	{ 0x596f8000, 0x556f8000, 0x00000800, ATT_OWN | ATT_IRAM},
> +	{ 0x55700000, 0x55700000, 0x00070000, ATT_OWN },
> +	/* DDR (Data) */
> +	{ 0x80000000, 0x80000000, 0x60000000, 0},
> +};
> +
> +static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8qxp[] = {
> +	/* dev addr , sys addr  , size	    , flags */
> +	{ 0x596e8000, 0x596e8000, 0x00008000, ATT_OWN },
> +	{ 0x596f0000, 0x596f0000, 0x00008000, ATT_OWN },
> +	{ 0x596f8000, 0x596f8000, 0x00000800, ATT_OWN | ATT_IRAM},
> +	{ 0x59700000, 0x59700000, 0x00070000, ATT_OWN },
> +	/* DDR (Data) */
> +	{ 0x80000000, 0x80000000, 0x60000000, 0},
> +};
> +
> +static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8mp[] = {
> +	/* dev addr , sys addr  , size	    , flags */
> +	{ 0x3b6e8000, 0x3b6e8000, 0x00008000, ATT_OWN },
> +	{ 0x3b6f0000, 0x3b6f0000, 0x00008000, ATT_OWN },
> +	{ 0x3b6f8000, 0x3b6f8000, 0x00000800, ATT_OWN | ATT_IRAM},
> +	{ 0x3b700000, 0x3b700000, 0x00040000, ATT_OWN },
> +	/* DDR (Data) */
> +	{ 0x40000000, 0x40000000, 0x80000000, 0},
> +};
> +
> +static const struct imx_dsp_rproc_att imx_dsp_rproc_att_imx8ulp[] = {
> +	/* dev addr , sys addr  , size	    , flags */
> +	{ 0x21170000, 0x21170000, 0x00010000, ATT_OWN | ATT_IRAM},
> +	{ 0x21180000, 0x21180000, 0x00010000, ATT_OWN },
> +	/* DDR (Data) */
> +	{ 0x0c000000, 0x80000000, 0x10000000, 0},
> +	{ 0x30000000, 0x90000000, 0x10000000, 0},
> +};
> +
> +static int imx8mp_dsp_reset(struct imx_dsp_rproc *priv)
> +{
> +	void __iomem *dap = ioremap_wc(IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE);
> +	int pwrctl;
> +
> +	/* put DSP into reset and stall */
> +	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
> +	pwrctl |= IMX8M_PWRCTL_CORERESET;
> +	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
> +
> +	/* keep reset asserted for 10 cycles */
> +	usleep_range(1, 2);
> +
> +	regmap_update_bits(priv->regmap, IMX8M_AudioDSP_REG2,
> +			   IMX8M_AudioDSP_REG2_RUNSTALL,
> +			   IMX8M_AudioDSP_REG2_RUNSTALL);
> +
> +	/* take the DSP out of reset and keep stalled for FW loading */
> +	pwrctl = readl(dap + IMX8M_DAP_PWRCTL);
> +	pwrctl &= ~IMX8M_PWRCTL_CORERESET;
> +	writel(pwrctl, dap + IMX8M_DAP_PWRCTL);
> +
> +	iounmap(dap);
> +	return 0;
> +}
> +
> +static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv)
> +{
> +	struct arm_smccc_res res;
> +
> +	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
> +			   IMX8ULP_SYSCTRL0_DSP_RST, IMX8ULP_SYSCTRL0_DSP_RST);
> +	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
> +			   IMX8ULP_SYSCTRL0_DSP_STALL,
> +			   IMX8ULP_SYSCTRL0_DSP_STALL);
> +
> +	arm_smccc_smc(IMX8ULP_SIP_HIFI_XRDC, 0, 0, 0, 0, 0, 0, 0, &res);
> +
> +	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
> +			   IMX8ULP_SYSCTRL0_DSP_RST, 0);
> +	regmap_update_bits(priv->regmap, IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
> +			   IMX8ULP_SYSCTRL0_DSP_DBG_RST, 0);
> +
> +	return 0;
> +}
> +
> +static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = {
> +	.src_reg	= IMX8M_AudioDSP_REG2,
> +	.src_mask	= IMX8M_AudioDSP_REG2_RUNSTALL,
> +	.src_start	= 0,
> +	.src_stop	= IMX8M_AudioDSP_REG2_RUNSTALL,
> +	.att		= imx_dsp_rproc_att_imx8mp,
> +	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8mp),
> +	.method		= IMX_DSP_MMIO,
> +	.reset          = imx8mp_dsp_reset,
> +};
> +
> +static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8ulp = {
> +	.src_reg	= IMX8ULP_SIM_LPAV_REG_SYSCTRL0,
> +	.src_mask	= IMX8ULP_SYSCTRL0_DSP_STALL,
> +	.src_start	= 0,
> +	.src_stop	= IMX8ULP_SYSCTRL0_DSP_STALL,
> +	.att		= imx_dsp_rproc_att_imx8ulp,
> +	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8ulp),
> +	.method		= IMX_DSP_MMIO,
> +	.reset          = imx8ulp_dsp_reset,
> +};
> +
> +static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qxp = {
> +	.att		= imx_dsp_rproc_att_imx8qxp,
> +	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qxp),
> +	.method		= IMX_DSP_SCU_API,
> +};
> +
> +static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8qm = {
> +	.att		= imx_dsp_rproc_att_imx8qm,
> +	.att_size	= ARRAY_SIZE(imx_dsp_rproc_att_imx8qm),
> +	.method		= IMX_DSP_SCU_API,
> +};
> +
> +static int imx_dsp_rproc_ready(struct rproc *rproc)
> +{
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	int i;
> +
> +	if (!priv->rxdb_ch)
> +		return 0;
> +
> +	for (i = 0; i < REMOTE_READY_WAIT_MAX_RETRIES; i++) {
> +		if (priv->flags & REMOTE_IS_READY)
> +			return 0;
> +		usleep_range(100, 200);
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static int imx_dsp_rproc_start(struct rproc *rproc)
> +{
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
> +	struct device *dev = priv->dev;
> +	int ret;
> +
> +	switch (dcfg->method) {
> +	case IMX_DSP_MMIO:
> +		ret = regmap_update_bits(priv->regmap,
> +					 dcfg->src_reg,
> +					 dcfg->src_mask,
> +					 dcfg->src_start);
> +		break;
> +	case IMX_DSP_SCU_API:
> +		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
> +					  IMX_SC_R_DSP,
> +					  true,
> +					  rproc->bootaddr);
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	if (ret)
> +		dev_err(dev, "Failed to enable remote core!\n");
> +	else
> +		ret = imx_dsp_rproc_ready(rproc);
> +
> +	return ret;
> +}
> +
> +static int imx_dsp_rproc_stop(struct rproc *rproc)
> +{
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
> +	struct device *dev = priv->dev;
> +	int ret = 0;
> +
> +	if (rproc->state == RPROC_CRASHED) {
> +		priv->flags &= ~REMOTE_IS_READY;
> +		return 0;
> +	}
> +
> +	switch (dcfg->method) {
> +	case IMX_DSP_MMIO:
> +		ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
> +					 dcfg->src_stop);
> +		break;
> +	case IMX_DSP_SCU_API:
> +		ret = imx_sc_pm_cpu_start(priv->ipc_handle,
> +					  IMX_SC_R_DSP,
> +					  false,
> +					  rproc->bootaddr);
> +		break;
> +	default:
> +		return -EOPNOTSUPP;
> +	}
> +
> +	if (ret)
> +		dev_err(dev, "Failed to stop remote core\n");
> +	else
> +		priv->flags &= ~REMOTE_IS_READY;
> +
> +	return ret;
> +}
> +
> +static int imx_dsp_rproc_sys_to_da(struct imx_dsp_rproc *priv, u64 sys,
> +				   size_t len, u64 *da)
> +{
> +	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
> +	int i;
> +
> +	/* parse address translation table */
> +	for (i = 0; i < dcfg->att_size; i++) {
> +		const struct imx_dsp_rproc_att *att = &dcfg->att[i];
> +
> +		if (sys >= att->sa && sys + len <= att->sa + att->size) {
> +			unsigned int offset = sys - att->sa;
> +
> +			*da = att->da + offset;
> +			return 0;
> +		}
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +static void imx_dsp_rproc_vq_work(struct work_struct *work)
> +{
> +	struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
> +						  rproc_work);
> +
> +	rproc_vq_interrupt(priv->rproc, 0);
> +	rproc_vq_interrupt(priv->rproc, 1);
> +}
> +
> +static void imx_dsp_rproc_rx_callback(struct mbox_client *cl, void *data)
> +{
> +	struct rproc *rproc = dev_get_drvdata(cl->dev);
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	u32 message = (u32)(*(u32 *)data);
> +
> +	dev_dbg(priv->dev, "mbox msg: 0x%x\n", message);
> +
> +	switch (message) {
> +	case RP_MBOX_SUSPEND_ACK:
> +		complete(&priv->pm_comp);
> +		break;
> +	case RP_MBOX_RESUME_ACK:
> +		complete(&priv->pm_comp);
> +		break;
> +	default:
> +		queue_work(priv->workqueue, &priv->rproc_work);
> +		break;
> +	}
> +}
> +
> +static void imx_dsp_rproc_rxdb_callback(struct mbox_client *cl, void *msg)
> +{
> +	struct rproc *rproc = dev_get_drvdata(cl->dev);
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&priv->mbox_lock, flags);
> +	priv->flags |= REMOTE_IS_READY;
> +	spin_unlock_irqrestore(&priv->mbox_lock, flags);
> +}
> +
> +static int imx_dsp_rproc_mbox_init(struct imx_dsp_rproc *priv)
> +{
> +	struct device *dev = priv->dev;
> +	struct mbox_client *cl;
> +	int ret;
> +
> +	if (!of_get_property(dev->of_node, "mbox-names", NULL))
> +		return 0;
> +
> +	spin_lock_init(&priv->mbox_lock);
> +
> +	cl = &priv->cl;
> +	cl->dev = dev;
> +	cl->tx_block = true;
> +	cl->tx_tout = 100;
> +	cl->knows_txdone = false;
> +	cl->rx_callback = imx_dsp_rproc_rx_callback;
> +
> +	priv->tx_ch = mbox_request_channel_byname(cl, "tx");
> +	if (IS_ERR(priv->tx_ch)) {
> +		ret = PTR_ERR(priv->tx_ch);
> +		dev_dbg(cl->dev, "failed to request tx mailbox channel: %d\n",
> +			ret);
> +		goto err_out;
> +	}
> +
> +	priv->rx_ch = mbox_request_channel_byname(cl, "rx");
> +	if (IS_ERR(priv->rx_ch)) {
> +		ret = PTR_ERR(priv->rx_ch);
> +		dev_dbg(cl->dev, "failed to request rx mailbox channel: %d\n",
> +			ret);
> +		goto err_out;
> +	}
> +
> +	cl = &priv->cl_rxdb;
> +	cl->dev = dev;
> +	cl->rx_callback = imx_dsp_rproc_rxdb_callback;
> +
> +	/*
> +	 * RX door bell is used to receive the ready signal from remote
> +	 * after the partition reset of A core.
> +	 */
> +	priv->rxdb_ch = mbox_request_channel_byname(cl, "rxdb");
> +	if (IS_ERR(priv->rxdb_ch)) {
> +		ret = PTR_ERR(priv->rxdb_ch);
> +		dev_dbg(cl->dev, "failed to request mbox chan rxdb, ret %d\n",
> +			ret);
> +		goto err_out;
> +	}
> +
> +	return 0;
> +
> +err_out:
> +	if (!IS_ERR(priv->tx_ch))
> +		mbox_free_channel(priv->tx_ch);
> +	if (!IS_ERR(priv->rx_ch))
> +		mbox_free_channel(priv->rx_ch);
> +	if (!IS_ERR(priv->rxdb_ch))
> +		mbox_free_channel(priv->rxdb_ch);
> +
> +	return ret;
> +}
> +
> +static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv)
> +{
> +	mbox_free_channel(priv->tx_ch);
> +	mbox_free_channel(priv->rx_ch);
> +	mbox_free_channel(priv->rxdb_ch);
> +}
> +
> +static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
> +{
> +	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
> +	struct rproc *rproc = priv->rproc;
> +	struct device *dev = priv->dev;
> +	struct device_node *np = dev->of_node;
> +	struct of_phandle_iterator it;
> +	struct rproc_mem_entry *mem;
> +	struct reserved_mem *rmem;
> +	void __iomem *cpu_addr;
> +	int a;
> +	u64 da;
> +
> +	/* remap required addresses */
> +	for (a = 0; a < dcfg->att_size; a++) {
> +		const struct imx_dsp_rproc_att *att = &dcfg->att[a];
> +
> +		if (!(att->flags & ATT_OWN))
> +			continue;
> +
> +		if (imx_dsp_rproc_sys_to_da(priv, att->sa, att->size, &da))
> +			return -EINVAL;
> +
> +		cpu_addr = devm_ioremap_wc(dev, att->sa, att->size);
> +
> +		/* Register memory region */
> +		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)att->sa,
> +					   att->size, da,
> +					   NULL,
> +					   NULL,
> +					   "dsp_mem");

Stacking

> +
> +		if (mem)
> +			rproc_coredump_add_segment(rproc, da, att->size);
> +		else
> +			return -ENOMEM;
> +
> +		rproc_add_carveout(rproc, mem);
> +	}
> +
> +	of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
> +	while (of_phandle_iterator_next(&it) == 0) {
> +		/*
> +		 * Ignore the first memory region which will be used vdev buffer.
> +		 * No need to do extra handlings, rproc_add_virtio_dev will handle it.
> +		 */
> +		if (!strcmp(it.node->name, "vdev0buffer"))
> +			continue;
> +
> +		rmem = of_reserved_mem_lookup(it.node);
> +		if (!rmem) {
> +			dev_err(dev, "unable to acquire memory-region\n");
> +			return -EINVAL;
> +		}
> +
> +		if (imx_dsp_rproc_sys_to_da(priv, rmem->base, rmem->size, &da))
> +			return -EINVAL;
> +
> +		cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
> +
> +		/* Register memory region */
> +		mem = rproc_mem_entry_init(dev, cpu_addr, (dma_addr_t)rmem->base,
> +					   rmem->size, da,
> +					   NULL,
> +					   NULL,
> +					   it.node->name);

Stacking

> +
> +		if (mem)
> +			rproc_coredump_add_segment(rproc, da, rmem->size);
> +		else
> +			return -ENOMEM;
> +
> +		rproc_add_carveout(rproc, mem);
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * imx_dsp_rproc_elf_load_segments() specially check if memsz is zero
> + * or not.
> + */
> +static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc,
> +					   const struct firmware *fw)
> +{
> +	struct device *dev = &rproc->dev;
> +	u8 class = fw_elf_get_class(fw);
> +	u32 elf_phdr_get_size = elf_size_of_phdr(class);
> +	const u8 *elf_data = fw->data;
> +	const void *ehdr, *phdr;
> +	int i, ret = 0;
> +	u16 phnum;
> +
> +	ehdr = elf_data;
> +	phnum = elf_hdr_get_e_phnum(class, ehdr);
> +	phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr);
> +
> +	/* go through the available ELF segments */
> +	for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) {
> +		u64 da = elf_phdr_get_p_paddr(class, phdr);
> +		u64 memsz = elf_phdr_get_p_memsz(class, phdr);
> +		u64 filesz = elf_phdr_get_p_filesz(class, phdr);
> +		u64 offset = elf_phdr_get_p_offset(class, phdr);
> +		u32 type = elf_phdr_get_p_type(class, phdr);
> +		void *ptr;
> +		bool is_iomem;
> +
> +		if (type != PT_LOAD || !memsz)
> +			continue;
> +
> +		dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
> +			type, da, memsz, filesz);
> +
> +		if (filesz > memsz) {
> +			dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n",
> +				filesz, memsz);
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		if (offset + filesz > fw->size) {
> +			dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n",
> +				offset + filesz, fw->size);
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		if (!rproc_u64_fit_in_size_t(memsz)) {
> +			dev_err(dev, "size (%llx) does not fit in size_t type\n",
> +				memsz);
> +			ret = -EOVERFLOW;
> +			break;
> +		}
> +
> +		/* grab the kernel address for this device address */
> +		ptr = rproc_da_to_va(rproc, da, memsz, &is_iomem);
> +		if (!ptr) {
> +			dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da,
> +				memsz);
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		/* put the segment where the remote processor expects it */
> +		if (filesz)
> +			memcpy(ptr, elf_data + offset, filesz);
> +
> +		/*
> +		 * Zero out remaining memory for this segment.
> +		 *
> +		 * This isn't strictly required since dma_alloc_coherent already
> +		 * did this for us. albeit harmless, we may consider removing
> +		 * this.
> +		 */
> +		if (memsz > filesz)
> +			memset(ptr + filesz, 0, memsz - filesz);
> +	}
> +
> +	return ret;
> +}
> +
> +static int imx_dsp_rproc_prepare(struct rproc *rproc)
> +{
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	struct device *dev = priv->dev;
> +	struct rproc_mem_entry *carveout;
> +	int ret;
> +
> +	ret = imx_dsp_rproc_add_carveout(priv);
> +	if (ret) {
> +		dev_err(dev, "failed on imx_dsp_rproc_add_carveout\n");
> +		return ret;
> +	}
> +
> +	pm_runtime_get_sync(dev);
> +
> +	/* clear buffers */
> +	list_for_each_entry(carveout, &rproc->carveouts, node) {
> +		if (carveout->va)
> +			memset(carveout->va, 0, carveout->len);
> +	}
> +
> +	return  0;
> +}
> +
> +static int imx_dsp_rproc_unprepare(struct rproc *rproc)
> +{
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +
> +	pm_runtime_put_sync(priv->dev);
> +
> +	return  0;
> +}
> +
> +static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid)
> +{
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	int err;
> +	__u32 mmsg;
> +
> +	if (!priv->tx_ch) {
> +		dev_err(priv->dev, "No initialized mbox tx channel\n");
> +		return;
> +	}
> +
> +	/*
> +	 * Send the index of the triggered virtqueue as the mu payload.
> +	 * Let remote processor know which virtqueue is used.
> +	 */
> +	mmsg = vqid;
> +
> +	err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
> +	if (err < 0)
> +		dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
> +			__func__, vqid, err);
> +}
> +
> +static const struct rproc_ops imx_dsp_rproc_ops = {
> +	.prepare	= imx_dsp_rproc_prepare,
> +	.unprepare	= imx_dsp_rproc_unprepare,
> +	.start		= imx_dsp_rproc_start,
> +	.stop		= imx_dsp_rproc_stop,
> +	.kick		= imx_dsp_rproc_kick,
> +	.load		= imx_dsp_rproc_elf_load_segments,
> +	.parse_fw	= rproc_elf_load_rsc_table,
> +	.sanity_check	= rproc_elf_sanity_check,
> +	.get_boot_addr	= rproc_elf_get_boot_addr,
> +};
> +
> +static int imx_dsp_attach_pm_domains(struct imx_dsp_rproc *priv)
> +{
> +	struct device *dev = priv->dev;
> +	int ret, i;
> +
> +	priv->num_domains = of_count_phandle_with_args(dev->of_node,
> +						       "power-domains",
> +						       "#power-domain-cells");
> +	if (priv->num_domains <= 1)
> +		return 0;
> +
> +	priv->pd_dev = devm_kmalloc_array(dev, priv->num_domains,
> +					  sizeof(*priv->pd_dev),
> +					  GFP_KERNEL);
> +	if (!priv->pd_dev)
> +		return -ENOMEM;
> +
> +	priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_domains,
> +					       sizeof(*priv->pd_dev_link),
> +					       GFP_KERNEL);
> +	if (!priv->pd_dev_link)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < priv->num_domains; i++) {
> +		priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
> +		if (IS_ERR(priv->pd_dev[i]))
> +			return PTR_ERR(priv->pd_dev[i]);
> +
> +		priv->pd_dev_link[i] = device_link_add(dev,
> +						       priv->pd_dev[i],
> +						       DL_FLAG_STATELESS |
> +						       DL_FLAG_PM_RUNTIME |
> +						       DL_FLAG_RPM_ACTIVE);
> +		if (IS_ERR(priv->pd_dev_link[i])) {
> +			dev_pm_domain_detach(priv->pd_dev[i], false);
> +			ret = PTR_ERR(priv->pd_dev_link[i]);
> +			goto detach_pm;
> +		}
> +	}
> +
> +	return 0;
> +
> +detach_pm:
> +	while (--i >= 0) {
> +		device_link_del(priv->pd_dev_link[i]);
> +		dev_pm_domain_detach(priv->pd_dev[i], false);
> +	}
> +
> +	return ret;
> +}
> +
> +static int imx_dsp_detach_pm_domains(struct imx_dsp_rproc *priv)
> +{
> +	int i;
> +
> +	if (priv->num_domains <= 1)
> +		return 0;
> +
> +	for (i = 0; i < priv->num_domains; i++) {
> +		device_link_del(priv->pd_dev_link[i]);
> +		dev_pm_domain_detach(priv->pd_dev[i], false);
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_dsp_rproc_detect_mode(struct imx_dsp_rproc *priv)
> +{
> +	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
> +	struct device *dev = priv->dev;
> +	struct regmap *regmap;
> +	int ret = 0;
> +
> +	switch (dcfg->method) {
> +	case IMX_DSP_SCU_API:
> +		ret = imx_scu_get_handle(&priv->ipc_handle);
> +		if (ret)
> +			return ret;
> +		return 0;
> +	case IMX_DSP_MMIO:
> +		regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,dsp-ctrl");
> +		if (IS_ERR(regmap)) {
> +			dev_err(dev, "failed to find syscon\n");
> +			return PTR_ERR(regmap);
> +		}
> +
> +		priv->regmap = regmap;
> +	default:
> +		break;

Shouldn't it be an error if neither SCU of MMIO methods are specified?

> +	}
> +
> +	return ret;
> +}
> +
> +static const char *imx_dsp_clks_names[DSP_RPROC_CLK_MAX] = {
> +	/* DSP clocks */
> +	"dsp_clk1", "dsp_clk2", "dsp_clk3", "dsp_clk4", "dsp_clk5", "dsp_clk6",
> +	"dsp_clk7", "dsp_clk8",
> +
> +	/* Peripheral clocks */
> +	"per_clk1", "per_clk2", "per_clk3", "per_clk4", "per_clk5", "per_clk6",
> +	"per_clk7", "per_clk8", "per_clk9", "per_clk10", "per_clk11", "per_clk12",
> +	"per_clk13", "per_clk14", "per_clk15", "per_clk16", "per_clk17", "per_clk18",
> +};
> +
> +static int imx_dsp_rproc_clk_get(struct imx_dsp_rproc *priv)
> +{
> +	int i;
> +
> +	for (i = 0; i < DSP_RPROC_CLK_MAX; i++) {
> +		priv->clks[i] = devm_clk_get_optional(priv->dev,
> +						      imx_dsp_clks_names[i]);

Please use the devm_clk_bulk_xyz() API.

> +		if (IS_ERR(priv->clks[i])) {
> +			dev_err(priv->dev, "Failed to get clock %s\n",
> +				imx_dsp_clks_names[i]);
> +			return PTR_ERR(priv->clks[i]);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_dsp_rproc_clk_enable(struct imx_dsp_rproc *priv)
> +{
> +	int i, ret;
> +
> +	for (i = 0; i < DSP_RPROC_CLK_MAX; i++) {
> +		ret = clk_prepare_enable(priv->clks[i]);
> +		if (ret < 0) {
> +			dev_err(priv->dev, "Failed to enable clk %s\n",
> +				imx_dsp_clks_names[i]);
> +			goto err_dsp_clks;
> +		}
> +	}
> +
> +	return 0;
> +
> +err_dsp_clks:
> +	while (--i >= 0)
> +		clk_disable_unprepare(priv->clks[i]);
> +
> +	return ret;
> +}
> +
> +static void imx_dsp_rproc_clk_disable(struct imx_dsp_rproc *priv)
> +{
> +	int i;
> +
> +	for (i = 0; i < DSP_RPROC_CLK_MAX; i++)
> +		clk_disable_unprepare(priv->clks[i]);
> +}
> +
> +static int imx_dsp_rproc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	const struct imx_dsp_rproc_dcfg *dcfg;
> +	struct imx_dsp_rproc *priv;
> +	struct rproc *rproc;
> +	const char *fw_name;
> +	int ret;
> +
> +	dcfg = of_device_get_match_data(dev);
> +	if (!dcfg)
> +		return -ENODEV;
> +
> +	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
> +	if (ret) {
> +		dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
> +			    sizeof(*priv));
> +	if (!rproc)
> +		return -ENOMEM;
> +
> +	priv = rproc->priv;
> +	priv->rproc = rproc;
> +	priv->dcfg = dcfg;
> +	priv->dev = dev;
> +
> +	dev_set_drvdata(dev, rproc);
> +
> +	priv->workqueue = create_workqueue(dev_name(dev));
> +	if (!priv->workqueue) {
> +		dev_err(dev, "cannot create workqueue\n");
> +		ret = -ENOMEM;
> +		goto err_wkq;
> +	}
> +
> +	INIT_WORK(&priv->rproc_work, imx_dsp_rproc_vq_work);
> +
> +	ret = imx_dsp_rproc_detect_mode(priv);
> +	if (ret) {
> +		dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
> +		goto err_detect;
> +	}
> +
> +	ret = imx_dsp_attach_pm_domains(priv);
> +	if (ret) {
> +		dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
> +		goto err_pm;
> +	}
> +
> +	ret = imx_dsp_rproc_clk_get(priv);
> +	if (ret) {
> +		dev_err(dev, "failed on imx_dsp_rproc_clk_get\n");
> +		goto err_clk_get;
> +	}
> +
> +	init_completion(&priv->pm_comp);
> +	rproc->auto_boot = false;
> +	ret = rproc_add(rproc);
> +	if (ret) {
> +		dev_err(dev, "rproc_add failed\n");
> +		goto err_rproc_add;
> +	}
> +
> +	pm_runtime_enable(dev);
> +
> +	return 0;
> +
> +err_rproc_add:
> +err_clk_get:

Name the gotos in relation to what they do rather than where they come from,
something like "detach_domains".  That way you don't need multiple goto
statements that clutter the code.

> +	imx_dsp_detach_pm_domains(priv);
> +err_pm:
> +err_detect:

Same

> +	destroy_workqueue(priv->workqueue);
> +err_wkq:
> +	rproc_free(rproc);
> +
> +	return ret;
> +}
> +
> +static int imx_dsp_rproc_remove(struct platform_device *pdev)
> +{
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +
> +	pm_runtime_disable(&pdev->dev);
> +	rproc_del(rproc);
> +	imx_dsp_detach_pm_domains(priv);
> +	destroy_workqueue(priv->workqueue);
> +	rproc_free(rproc);
> +
> +	return 0;
> +}
> +
> +/* pm runtime */
> +static int imx_dsp_runtime_resume(struct device *dev)
> +{
> +	struct rproc *rproc = dev_get_drvdata(dev);
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	const struct imx_dsp_rproc_dcfg *dcfg = priv->dcfg;
> +	int ret;
> +
> +	ret = imx_dsp_rproc_mbox_init(priv);

Why is the mailbox setup and destroyed with every PM cycle?  I find an overall
lack of comments makes this driver difficult to review, resulting in having to
spend more time to look at and understand the code.  I will have to continue
tomorrow because, well, I ran out of time. 

Mathieu

> +	if (ret) {
> +		dev_err(dev, "failed on imx_dsp_rproc_mbox_init\n");
> +		return ret;
> +	}
> +
> +	ret = imx_dsp_rproc_clk_enable(priv);
> +	if (ret) {
> +		dev_err(dev, "failed on imx_dsp_rproc_clk_enable\n");
> +		return ret;
> +	}
> +
> +	/* reset DSP if needed */
> +	if (dcfg->reset)
> +		dcfg->reset(priv);
> +
> +	return 0;
> +}
> +
> +static int imx_dsp_runtime_suspend(struct device *dev)
> +{
> +	struct rproc *rproc = dev_get_drvdata(dev);
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +
> +	imx_dsp_rproc_clk_disable(priv);
> +
> +	imx_dsp_rproc_free_mbox(priv);
> +
> +	return 0;
> +}
> +
> +static void imx_dsp_load_firmware(const struct firmware *fw, void *context)
> +{
> +	struct rproc *rproc = context;
> +	int ret;
> +
> +	/* load the ELF segments to memory */
> +	ret = rproc_load_segments(rproc, fw);
> +	if (ret)
> +		goto out;
> +
> +	/* power up the remote processor */
> +	ret = rproc->ops->start(rproc);
> +	if (ret)
> +		goto out;
> +
> +	/* same flow as first start */
> +	rproc->ops->kick(rproc, 0);
> +
> +out:
> +	release_firmware(fw);
> +}
> +
> +static int imx_dsp_suspend(struct device *dev)
> +{
> +	struct rproc *rproc = dev_get_drvdata(dev);
> +	struct imx_dsp_rproc *priv = rproc->priv;
> +	__u32 mmsg = RP_MBOX_SUSPEND_SYSTEM;
> +	int ret;
> +
> +	if (rproc->state == RPROC_RUNNING) {
> +		reinit_completion(&priv->pm_comp);
> +
> +		ret = mbox_send_message(priv->tx_ch, (void *)&mmsg);
> +		if (ret < 0) {
> +			dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
> +			return ret;
> +		}
> +
> +		if (!wait_for_completion_timeout(&priv->pm_comp, msecs_to_jiffies(100)))
> +			return -EBUSY;
> +	}
> +
> +	return pm_runtime_force_suspend(dev);
> +}
> +
> +static int imx_dsp_resume(struct device *dev)
> +{
> +	struct rproc *rproc = dev_get_drvdata(dev);
> +	int ret = 0;
> +
> +	ret = pm_runtime_force_resume(dev);
> +	if (ret)
> +		return ret;
> +
> +	if (rproc->state == RPROC_RUNNING) {
> +		/*TODO: load firmware and start */
> +		ret = request_firmware_nowait(THIS_MODULE,
> +					      FW_ACTION_UEVENT,
> +					      rproc->firmware,
> +					      dev,
> +					      GFP_KERNEL,
> +					      rproc,
> +					      imx_dsp_load_firmware);
> +		if (ret < 0) {
> +			dev_err(dev, "load firmware failed: %d\n", ret);
> +			goto err;
> +		}
> +	}
> +
> +	return 0;
> +
> +err:
> +	pm_runtime_force_suspend(dev);
> +
> +	return ret;
> +}
> +
> +static const struct dev_pm_ops imx_dsp_rproc_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(imx_dsp_suspend, imx_dsp_resume)
> +	SET_RUNTIME_PM_OPS(imx_dsp_runtime_suspend,
> +			   imx_dsp_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id imx_dsp_rproc_of_match[] = {
> +	{ .compatible = "fsl,imx8qxp-hifi4", .data = &imx_dsp_rproc_cfg_imx8qxp },
> +	{ .compatible = "fsl,imx8qm-hifi4",  .data = &imx_dsp_rproc_cfg_imx8qm },
> +	{ .compatible = "fsl,imx8mp-hifi4",  .data = &imx_dsp_rproc_cfg_imx8mp },
> +	{ .compatible = "fsl,imx8ulp-hifi4", .data = &imx_dsp_rproc_cfg_imx8ulp },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, imx_dsp_rproc_of_match);
> +
> +static struct platform_driver imx_dsp_rproc_driver = {
> +	.probe = imx_dsp_rproc_probe,
> +	.remove = imx_dsp_rproc_remove,
> +	.driver = {
> +		.name = "imx-dsp-rproc",
> +		.of_match_table = imx_dsp_rproc_of_match,
> +		.pm = &imx_dsp_rproc_pm_ops,
> +	},
> +};
> +module_platform_driver(imx_dsp_rproc_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("i.MX HiFi Core Remote Processor Control Driver");
> +MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang at nxp.com>");
> -- 
> 2.17.1
> 


From catalin.marinas at arm.com  Tue Aug 31 11:03:28 2021
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 31 Aug 2021 19:03:28 +0100
Subject: [GIT PULL] arm64 updates for 5.15
Message-ID: <YS5u8M97frcjTbJW@arm.com>

Hi Linus,

Please pull the arm64 updates for 5.15 below. The asymmetric AArch32
support patches were queued via tip/sched/arm64 on top of the scheduler
counterpart. I merged the tip branch into the arm64 tree (based on -rc3)
but since the former was based on -rc6, I had to generate the diffstat
manually (dummy merge with upstream and git show --stat). Hopefully it
matches yours.

Thanks.

The following changes since commit 234b8ab6476c5edd5262e2ff563de9498d60044a:

  sched: Introduce dl_task_check_affinity() to check proposed affinity (2021-08-20 12:33:00 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-upstream

for you to fetch changes up to 65266a7c6abfa1ad915a362c41bf38576607f1f9:

  Merge remote-tracking branch 'tip/sched/arm64' into for-next/core (2021-08-31 09:10:00 +0100)

----------------------------------------------------------------
arm64 updates for 5.15:

- Support for 32-bit tasks on asymmetric AArch32 systems (on top of the
  scheduler changes merged via the tip tree).

- More entry.S clean-ups and conversion to C.

- MTE updates: allow a preferred tag checking mode to be set per CPU
  (the overhead of synchronous mode is smaller for some CPUs than
  others); optimisations for kernel entry/exit path; optionally disable
  MTE on the kernel command line.

- Kselftest improvements for SVE and signal handling, PtrAuth.

- Fix unlikely race where a TLBI could use stale ASID on an ASID
  roll-over (found by inspection).

- Miscellaneous fixes: disable trapping of PMSNEVFR_EL1 to higher
  exception levels; drop unnecessary sigdelsetmask() call in the
  signal32 handling; remove BUG_ON when failing to allocate SVE state
  (just signal the process); SYM_CODE annotations.

- Other trivial clean-ups: use macros instead of magic numbers, remove
  redundant returns, typos.

----------------------------------------------------------------
Alexandru Elisei (1):
      arm64: Do not trap PMSNEVFR_EL1

Anshuman Khandual (2):
      arm64/kexec: Test page size support with new TGRAN range values
      arm64/perf: Replace '0xf' instances with ID_AA64DFR0_PMUVER_IMP_DEF

Catalin Marinas (3):
      Merge branches 'for-next/mte', 'for-next/misc' and 'for-next/kselftest', remote-tracking branch 'arm64/for-next/perf' into for-next/core
      Merge branch 'for-next/entry' into for-next/core
      Merge remote-tracking branch 'tip/sched/arm64' into for-next/core

Changbin Du (1):
      arm64: replace in_irq() with in_hardirq()

Jason Wang (3):
      arm64: use __func__ to get function name in pr_err
      arm64: unnecessary end 'return;' in void functions
      arm64: fix typo in a comment

Lingyan Huang (1):
      arm64: SSBS/DIT: print SSBS and DIT bit when printing PSTATE

Marc Zyngier (1):
      arm64: Document the requirement for SCR_EL3.HCE

Mark Brown (19):
      arm64/sme: Document boot requirements for SME
      kselftest/arm64: Ignore check_gcr_el1_cswitch binary
      arm64/sve: Make fpsimd_bind_task_to_cpu() static
      kselftest/arm64: Provide a helper binary and "library" for SVE RDVL
      kselftest/arm64: Validate vector lengths are set in sve-probe-vls
      kselftest/arm64: Add tests for SVE vector configuration
      kselftest/arm64: Add a TODO list for floating point tests
      arm64: entry: Add SYM_CODE annotation for __bad_stack
      kselftest/arm64: mte: Fix misleading output when skipping tests
      kselftest/arm64: pac: Fix skipping of tests on systems without PAC
      kselftest/arm64: signal: Add SVE to the set of features we can check for
      kselftest/arm64: signal: Support signal frames with SVE register data
      kselftest/arm64: signal: Check SVE signal frame shows expected vector length
      kselftest/arm64: signal: Verify that signals can't change the SVE vector length
      kselftest/arm64: signal: Add test case for SVE register state in signals
      kselftest/arm64: signal: Add a TODO list for signal handling tests
      arm64/sve: Add some comments for sve_save/load_state()
      arm64/sve: Add a comment documenting the binutils needed for SVE asm
      arm64/sve: Better handle failure to allocate SVE register storage

Mark Rutland (7):
      arm64: kasan: mte: use a constant kernel GCR_EL1 value
      arm64: kasan: mte: remove redundant mte_report_once logic
      arm64: entry: consolidate entry/exit helpers
      arm64: entry: clarify entry/exit helpers
      arm64: entry: move bulk of ret_to_user to C
      arm64: entry: call exit_to_user_mode() from C
      arm64: head: avoid over-mapping in map_memory

Masahiro Yamada (1):
      arm64: move the (z)install rules to arch/arm64/Makefile

Peter Collingbourne (8):
      arm64: mte: avoid TFSRE0_EL1 related operations unless in async mode
      arm64: mte: rename gcr_user_excl to mte_ctrl
      arm64: mte: change ASYNC and SYNC TCF settings into bitfields
      arm64: move preemption disablement to prctl handlers
      arm64: mte: introduce a per-CPU tag checking mode preference
      Documentation: document the preferred tag checking mode feature
      arm64: mte: optimize GCR_EL1 modification on kernel entry/exit
      arm64: avoid double ISB on kernel entry

Peter Zijlstra (1):
      Merge branch 'sched/core'

Shaokun Zhang (1):
      arm64: cpufeature: Use defined macro instead of magic numbers

Will Deacon (9):
      arm64: mm: Fix TLBI vs ASID rollover
      arm64: Implement task_cpu_possible_mask()
      arm64: exec: Adjust affinity for compat tasks with mismatched 32-bit EL0
      arm64: Prevent offlining first CPU with 32-bit EL0 on mismatched system
      arm64: Advertise CPUs capable of running 32-bit applications in sysfs
      arm64: Hook up cmdline parameter to allow mismatched 32-bit EL0
      arm64: Remove logic to kill 32-bit tasks on 64-bit-only cores
      Documentation: arm64: describe asymmetric 32-bit support
      arm64: signal32: Drop pointless call to sigdelsetmask()

Xujun Leng (1):
      arm64: mm: fix comment typo of pud_offset_phys()

Yee Lee (1):
      arm64/cpufeature: Optionally disable MTE via command-line

 Documentation/ABI/testing/sysfs-devices-system-cpu |  26 +
 Documentation/admin-guide/kernel-parameters.txt    |  14 +
 Documentation/arm64/asymmetric-32bit.rst           | 155 ++++++
 Documentation/arm64/booting.rst                    |  37 +-
 Documentation/arm64/index.rst                      |   1 +
 Documentation/arm64/memory-tagging-extension.rst   |  48 +-
 arch/arm64/Makefile                                |   7 +-
 arch/arm64/boot/Makefile                           |   8 -
 arch/arm64/include/asm/cpufeature.h                |  11 +-
 arch/arm64/include/asm/el2_setup.h                 |  13 +-
 arch/arm64/include/asm/elf.h                       |   6 +-
 arch/arm64/include/asm/exception.h                 |   5 +-
 arch/arm64/include/asm/fpsimd.h                    |   1 -
 arch/arm64/include/asm/fpsimdmacros.h              |   1 +
 arch/arm64/include/asm/kernel-pgtable.h            |   4 +-
 arch/arm64/include/asm/memory.h                    |   2 -
 arch/arm64/include/asm/mmu.h                       |  29 +-
 arch/arm64/include/asm/mmu_context.h               |  13 +
 arch/arm64/include/asm/mte-kasan.h                 |  17 -
 arch/arm64/include/asm/mte.h                       |   6 -
 arch/arm64/include/asm/pgtable.h                   |   2 +-
 arch/arm64/include/asm/pointer_auth.h              |  12 +-
 arch/arm64/include/asm/processor.h                 |  10 +-
 arch/arm64/include/asm/simd.h                      |   2 +-
 arch/arm64/include/asm/sysreg.h                    |  47 +-
 arch/arm64/include/asm/tlbflush.h                  |  13 +-
 arch/arm64/kernel/asm-offsets.c                    |   2 +-
 arch/arm64/kernel/cpufeature.c                     |  58 +-
 arch/arm64/kernel/entry-common.c                   | 219 +++++---
 arch/arm64/kernel/entry-fpsimd.S                   |  13 +
 arch/arm64/kernel/entry.S                          | 114 ++--
 arch/arm64/kernel/fpsimd.c                         |  14 +-
 arch/arm64/kernel/head.S                           |  11 +-
 arch/arm64/kernel/idreg-override.c                 |   2 +
 arch/arm64/kernel/mte.c                            | 180 ++++---
 arch/arm64/kernel/perf_event.c                     |   2 +-
 arch/arm64/kernel/pointer_auth.c                   |  10 +-
 arch/arm64/kernel/process.c                        |  78 ++-
 arch/arm64/kernel/ptrace.c                         |   5 +
 arch/arm64/kernel/signal.c                         |  34 +-
 arch/arm64/kernel/signal32.c                       |   6 +-
 arch/arm64/kernel/suspend.c                        |   1 -
 arch/arm64/lib/insn.c                              |   4 +-
 arch/arm64/mm/fault.c                              |  15 +-
 arch/arm64/mm/proc.S                               |   3 +-
 include/linux/kasan-tags.h                         |  15 +
 include/uapi/linux/prctl.h                         |  11 +-
 lib/test_kasan.c                                   |   2 -
 mm/kasan/hw_tags.c                                 |   8 -
 mm/kasan/kasan.h                                   |  22 +-
 tools/testing/selftests/arm64/fp/.gitignore        |   2 +
 tools/testing/selftests/arm64/fp/Makefile          |  11 +-
 tools/testing/selftests/arm64/fp/TODO              |   4 +
 tools/testing/selftests/arm64/fp/rdvl-sve.c        |  14 +
 tools/testing/selftests/arm64/fp/rdvl.S            |  10 +
 tools/testing/selftests/arm64/fp/rdvl.h            |   8 +
 tools/testing/selftests/arm64/fp/sve-probe-vls.c   |   5 +
 tools/testing/selftests/arm64/fp/vec-syscfg.c      | 593 +++++++++++++++++++++
 tools/testing/selftests/arm64/mte/.gitignore       |   1 +
 .../testing/selftests/arm64/mte/mte_common_util.c  |   2 +-
 tools/testing/selftests/arm64/pauth/pac.c          |  10 +-
 tools/testing/selftests/arm64/signal/.gitignore    |   1 +
 .../testing/selftests/arm64/signal/test_signals.h  |   2 +
 .../selftests/arm64/signal/test_signals_utils.c    |   3 +
 .../testing/selftests/arm64/signal/testcases/TODO  |   2 +
 .../testcases/fake_sigreturn_sve_change_vl.c       |  92 ++++
 .../selftests/arm64/signal/testcases/sve_regs.c    | 126 +++++
 .../selftests/arm64/signal/testcases/sve_vl.c      |  68 +++
 .../selftests/arm64/signal/testcases/testcases.c   |  34 +-
 69 files changed, 1843 insertions(+), 464 deletions(-)

-- 
Catalin


From robh+dt at kernel.org  Tue Aug 31 11:24:09 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 13:24:09 -0500
Subject: [PATCH v12 2/6] PCI: mediatek: Add new method to get shared
 pcie-cfg base address
In-Reply-To: <20210831154711.GA107126@bjorn-Precision-5520>
References: <CAL_JsqKEvAypWhiaWMhxM7zVkLAFL9=eMU7_vr=ht+uyxYe0qg@mail.gmail.com>
 <20210831154711.GA107126@bjorn-Precision-5520>
Message-ID: <CAL_Jsq+y=-UTv6B5cGG5p-q-rzzyEuWZ_Q6YKPT=Jej1boZwjQ@mail.gmail.com>

On Tue, Aug 31, 2021 at 10:47 AM Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> On Tue, Aug 31, 2021 at 10:04:40AM -0500, Rob Herring wrote:
> > On Fri, Aug 27, 2021 at 11:46 AM Bjorn Helgaas <helgaas at kernel.org> wrote:
> > >
> > > On Mon, Aug 23, 2021 at 11:27:56AM +0800, Chuanjia Liu wrote:
> > > > For the new dts format, add a new method to get
> > > > shared pcie-cfg base address and use it to configure
> > > > the PCIECFG controller
> > >
> > > Rewrap this to fill 75 columns.
> > >
> > > > Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> > > > Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> > > > ---
> > > >  drivers/pci/controller/pcie-mediatek.c | 17 +++++++++++++++++
> > > >  1 file changed, 17 insertions(+)
> > > >
> > > > diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> > > > index 25bee693834f..4296d9e04240 100644
> > > > --- a/drivers/pci/controller/pcie-mediatek.c
> > > > +++ b/drivers/pci/controller/pcie-mediatek.c
> > > > @@ -14,6 +14,7 @@
> > > >  #include <linux/irqchip/chained_irq.h>
> > > >  #include <linux/irqdomain.h>
> > > >  #include <linux/kernel.h>
> > > > +#include <linux/mfd/syscon.h>
> > > >  #include <linux/msi.h>
> > > >  #include <linux/module.h>
> > > >  #include <linux/of_address.h>
> > > > @@ -23,6 +24,7 @@
> > > >  #include <linux/phy/phy.h>
> > > >  #include <linux/platform_device.h>
> > > >  #include <linux/pm_runtime.h>
> > > > +#include <linux/regmap.h>
> > > >  #include <linux/reset.h>
> > > >
> > > >  #include "../pci.h"
> > > > @@ -207,6 +209,7 @@ struct mtk_pcie_port {
> > > >   * struct mtk_pcie - PCIe host information
> > > >   * @dev: pointer to PCIe device
> > > >   * @base: IO mapped register base
> > > > + * @cfg: IO mapped register map for PCIe config
> > > >   * @free_ck: free-run reference clock
> > > >   * @mem: non-prefetchable memory resource
> > > >   * @ports: pointer to PCIe port information
> > > > @@ -215,6 +218,7 @@ struct mtk_pcie_port {
> > > >  struct mtk_pcie {
> > > >       struct device *dev;
> > > >       void __iomem *base;
> > > > +     struct regmap *cfg;
> > > >       struct clk *free_ck;
> > > >
> > > >       struct list_head ports;
> > > > @@ -682,6 +686,10 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
> > > >               val |= PCIE_CSR_LTSSM_EN(port->slot) |
> > > >                      PCIE_CSR_ASPM_L1_EN(port->slot);
> > > >               writel(val, pcie->base + PCIE_SYS_CFG_V2);
> > > > +     } else if (pcie->cfg) {
> > > > +             val = PCIE_CSR_LTSSM_EN(port->slot) |
> > > > +                   PCIE_CSR_ASPM_L1_EN(port->slot);
> > > > +             regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val);
> > > >       }
> > > >
> > > >       /* Assert all reset signals */
> > > > @@ -985,6 +993,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> > > >       struct device *dev = pcie->dev;
> > > >       struct platform_device *pdev = to_platform_device(dev);
> > > >       struct resource *regs;
> > > > +     struct device_node *cfg_node;
> > > >       int err;
> > > >
> > > >       /* get shared registers, which are optional */
> > > > @@ -995,6 +1004,14 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
> > > >                       return PTR_ERR(pcie->base);
> > > >       }
> > > >
> > > > +     cfg_node = of_find_compatible_node(NULL, NULL,
> > > > +                                        "mediatek,generic-pciecfg");
> > >
> > > This looks wrong to me.  IIUC, since we start at NULL, this searches
> > > the entire device tree for any node with
> > >
> > >   compatible = "mediatek,generic-pciecfg"
> > >
> > > but we should only care about the specific device/node this driver
> > > claimed.
> > >
> > > Should this be part of the match data, i.e., struct mtk_pcie_soc?
> >
> > What would you put in match data exactly?
> >
> > The other way to do this is to have a DT property with the phandle
> > which people like to do (have everything in the node 'for their
> > driver'). If there's only 1 possible node (which is almost always the
> > case), then there is little benefit to having another property. It's
> > just redundant data. A phandle lookup might be a bit faster with the
> > caching we do, but on a miss it would still walk all nodes.
> >
> > The other thing with these 'extra register bits to twiddle' is that
> > they tend to be SoC specific and change from chip to chip, so either
> > way is not very portable. The real question to ask is should there be
> > a standard interface used or created.
> >
> > > > +     if (cfg_node) {
> > > > +             pcie->cfg = syscon_node_to_regmap(cfg_node);
> > >
> > > Other drivers in drivers/pci/controller/ use
> > > syscon_regmap_lookup_by_phandle() (j721e, dra7xx, keystone,
> > > layerscape, artpec6) or syscon_regmap_lookup_by_compatible() (imx6,
> > > kirin, v3-semi).
> >
> > There's no phandle to use in this case. As above, I'm trying to break
> > people of this habit.
>
> Thanks!  I was mistaken in lots of ways here.  I first assumed
> "mediatek,generic-pciecfg" was local to the pcie node, but that's not
> true.  Then I thought there might be an ownership issue because the
> regmap is not local to the device, and several drivers look up and use
> the same regmap.  But it looks like regmap provides some internal
> locking which mitigates most or all of that concern.
>
> Just to check -- you prefer syscon_regmap_lookup_by_compatible() over
> syscon_regmap_lookup_by_phandle()?

Yes, unless there is either more than 1 instance of the syscon or some
additional data specific to the user (e.g. a register offset).

Rob


From helgaas at kernel.org  Tue Aug 31 11:30:22 2021
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 31 Aug 2021 13:30:22 -0500
Subject: [PATCH v12 3/6] PCI: mediatek: Add new method to get irq number
In-Reply-To: <20210823032800.1660-4-chuanjia.liu@mediatek.com>
Message-ID: <20210831183022.GA120514@bjorn-Precision-5520>

On Mon, Aug 23, 2021 at 11:27:57AM +0800, Chuanjia Liu wrote:
> Use platform_get_irq_byname() to get the irq number
> if the property of "interrupt-names" is defined.

>From patch 1/6, I have the impression that this patch is part of
fixing an MSI issue.  If so, this commit log should mention that as
well.

> Signed-off-by: Chuanjia Liu <chuanjia.liu at mediatek.com>
> Acked-by: Ryder Lee <ryder.lee at mediatek.com>
> ---
>  drivers/pci/controller/pcie-mediatek.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> index 4296d9e04240..19e35ac62d43 100644
> --- a/drivers/pci/controller/pcie-mediatek.c
> +++ b/drivers/pci/controller/pcie-mediatek.c
> @@ -654,7 +654,11 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
>  		return err;
>  	}
>  
> -	port->irq = platform_get_irq(pdev, port->slot);
> +	if (of_find_property(dev->of_node, "interrupt-names", NULL))
> +		port->irq = platform_get_irq_byname(pdev, "pcie_irq");
> +	else
> +		port->irq = platform_get_irq(pdev, port->slot);

This would be the only instance of this pattern, where we look for a
property and use the result to decide how to look for the IRQ.

dw_pcie_host_init() does something like this:

  port->irq = platform_get_irq_byname_optional(pdev, "pcie_irq");
  if (port->irq < 0) {
    port->irq = platform_get_irq(pdev, port->slot);
    if (port->irq < 0)
      return port->irq;
  }

Would that work for you?  If not, the commit log should explain why
you can't use the standard pattern.

If you do things differently than other drivers, it makes things
harder to review and slows things down.  If you *have* to do something
differently and it adds real value to be different, that's fine.  But
we should avoid unnecessary differences.

>  	if (port->irq < 0)
>  		return port->irq;
>  
> -- 
> 2.18.0
> 


From jernej.skrabec at gmail.com  Tue Aug 31 11:48:19 2021
From: jernej.skrabec at gmail.com (Jernej Skrabec)
Date: Tue, 31 Aug 2021 20:48:19 +0200
Subject: [PATCH] drm/sun4i: Fix macros in sun8i_csc.h
Message-ID: <20210831184819.93670-1-jernej.skrabec@gmail.com>

Macros SUN8I_CSC_CTRL() and SUN8I_CSC_COEFF() don't follow usual
recommendation of having arguments enclosed in parenthesis. While that
didn't change anything for quiet sometime, it actually become important
after CSC code rework with commit ea067aee45a8 ("drm/sun4i: de2/de3:
Remove redundant CSC matrices").

Without this fix, colours are completely off for supported YVU formats
on SoCs with DE2 (A64, H3, R40, etc.).

Fix the issue by enclosing macro arguments in parenthesis.

Cc: stable at vger.kernel.org # 5.12+
Fixes: 883029390550 ("drm/sun4i: Add DE2 CSC library")
Reported-by: Roman Stratiienko <r.stratiienko at gmail.com>
Signed-off-by: Jernej Skrabec <jernej.skrabec at gmail.com>
---
 drivers/gpu/drm/sun4i/sun8i_csc.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h
index a55a38ad849c..022cafa6c06c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_csc.h
+++ b/drivers/gpu/drm/sun4i/sun8i_csc.h
@@ -16,8 +16,8 @@ struct sun8i_mixer;
 #define CCSC10_OFFSET 0xA0000
 #define CCSC11_OFFSET 0xF0000
 
-#define SUN8I_CSC_CTRL(base)		(base + 0x0)
-#define SUN8I_CSC_COEFF(base, i)	(base + 0x10 + 4 * i)
+#define SUN8I_CSC_CTRL(base)		((base) + 0x0)
+#define SUN8I_CSC_COEFF(base, i)	((base) + 0x10 + 4 * (i))
 
 #define SUN8I_CSC_CTRL_EN		BIT(0)
 
-- 
2.33.0



From robh at kernel.org  Tue Aug 31 11:52:54 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 13:52:54 -0500
Subject: [PATCH] ASoC: dt-bindings: mt8195: remove dependent headers in
 the example
In-Reply-To: <20210831083956.9804-1-trevor.wu@mediatek.com>
References: <20210831083956.9804-1-trevor.wu@mediatek.com>
Message-ID: <YS56hvQHAH/zD/dD@robh.at.kernel.org>

On Tue, Aug 31, 2021 at 04:39:56PM +0800, Trevor Wu wrote:
> Drop the use of the defines including clock and power id, so that
> we can remove the headers which are not applied in the example.
> 
> Fixes: b5bac34fcfb4 ("dt-bindings: mediatek: mt8195: add audio afe document")
> Signed-off-by: Trevor Wu <trevor.wu at mediatek.com>
> ---
>  .../bindings/sound/mt8195-afe-pcm.yaml        | 40 +++++++++----------
>  1 file changed, 19 insertions(+), 21 deletions(-)

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

Please pick this up for 5.15-rc1 (or don't so I can).

Rob


From jernej.skrabec at gmail.com  Tue Aug 31 12:01:03 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 31 Aug 2021 21:01:03 +0200
Subject: [PATCH] drm/sun4i: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210831135740.4826-1-caihuoqing@baidu.com>
References: <20210831135740.4826-1-caihuoqing@baidu.com>
Message-ID: <3342147.tElmWuj8HH@kista>

Hi!

Dne torek, 31. avgust 2021 ob 15:57:39 CEST je Cai Huoqing napisal(a):
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From robh at kernel.org  Tue Aug 31 12:02:28 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 14:02:28 -0500
Subject: [PATCH v8 3/4] dt-bindings: pwm: add IPQ6018 binding
In-Reply-To: <8238dfb5d5e4a40a995f047db36d9a7240431de5.1630323987.git.baruch@tkos.co.il>
References: <5c95bcf62a9d08208a7da19f0b1cec0689502b9a.1630323987.git.baruch@tkos.co.il>
 <8238dfb5d5e4a40a995f047db36d9a7240431de5.1630323987.git.baruch@tkos.co.il>
Message-ID: <YS58xAit1UrEtd0v@robh.at.kernel.org>

On Mon, Aug 30, 2021 at 02:46:26PM +0300, Baruch Siach wrote:
> DT binding for the PWM block in Qualcomm IPQ6018 SoC.
> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
> This series does not convert the TCSR binding documentation to YAML. As
> a result, this commit adds new a dt_binding_check warning:
> 
> /example-0/syscon at 1937000: failed to match any schema with compatible: ['qcom,tcsr-ipq 6018', 'syscon', 'simple-mfd']
> 
> If that is a blocker to IPQ6018 PWM support, so be it. Patches will wait
> for someone else to push them further.
> 
> v8:
> 
>   Add size cell to 'reg' (Rob)
> 
> v7:
> 
>   Use 'reg' instead of 'offset' (Rob)
> 
>   Drop 'clock-names' and 'assigned-clock*' (Bjorn)
> 
>   Use single cell address/size in example node (Bjorn)
> 
>   Move '#pwm-cells' lower in example node (Bjorn)
> 
>   List 'reg' as required
> 
> v6:
> 
>   Device node is child of TCSR; remove phandle (Rob Herring)
> 
>   Add assigned-clocks/assigned-clock-rates (Uwe Kleine-K?nig)
> 
> v5: Use qcom,pwm-regs for phandle instead of direct regs (Bjorn
>     Andersson, Kathiravan T)
> 
> v4: Update the binding example node as well (Rob Herring's bot)
> 
> v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
> 
> v2: Make #pwm-cells const (Rob Herring)
> ---
>  .../devicetree/bindings/pwm/ipq-pwm.yaml      | 52 +++++++++++++++++++
>  1 file changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml b/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> new file mode 100644
> index 000000000000..96bc63e336bf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/ipq-pwm.yaml
> @@ -0,0 +1,52 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pwm/ipq-pwm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm IPQ6018 PWM controller
> +
> +maintainers:
> +  - Baruch Siach <baruch at tkos.co.il>
> +
> +properties:
> +  "#pwm-cells":
> +    const: 2
> +
> +  compatible:
> +    const: qcom,ipq6018-pwm
> +
> +  reg:
> +    description: Offset of PWM register in the TCSR block.
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - "#pwm-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/qcom,gcc-ipq6018.h>
> +
> +    tcsr: syscon at 1937000 {

Drop unused (by the example) labels.

> +        compatible = "qcom,tcsr-ipq6018", "syscon", "simple-mfd";
> +        reg = <0x01937000 0x21000>;
> +        #address-cells = <1>;
> +        #size-cells = <1>;

           ranges = <0 0x1937000 0x21000>;

Otherwise, the address is not translatable.

> +
> +        pwm: pwm at a010 {
> +            compatible = "qcom,ipq6018-pwm";
> +            reg = <0xa010 0x20>;
> +            clocks = <&gcc GCC_ADSS_PWM_CLK>;
> +            assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>;
> +            assigned-clock-rates = <100000000>;
> +            #pwm-cells = <2>;
> +        };
> +    };
> -- 
> 2.33.0
> 
> 


From david at redhat.com  Tue Aug 31 12:16:28 2021
From: david at redhat.com (David Hildenbrand)
Date: Tue, 31 Aug 2021 21:16:28 +0200
Subject: [GIT PULL] arm64 fix for 5.14
In-Reply-To: <20210831133117.GD31712@willie-the-truck>
References: <20210826131747.GE26318@willie-the-truck>
 <CAHk-=wi8Wxazuq+E4_V0GG4eda0rNpZi76AYWQe7xfPZAAexAQ@mail.gmail.com>
 <20210827074041.GA24309@lst.de>
 <CAHk-=wjd28sN9khO=1j6zmBk+2n4_e+SY1URjW9hzsHSAZU+7Q@mail.gmail.com>
 <20210827171041.GA28149@lst.de>
 <CAHk-=wg=+P1+HQXhrszxN_BgWtLc-=dWiT61KzogcJU3hnLrtQ@mail.gmail.com>
 <20210831133117.GD31712@willie-the-truck>
Message-ID: <0a41af61-783c-e31d-abc1-73169dad9ff4@redhat.com>

On 31.08.21 15:31, Will Deacon wrote:
> [+David]
> 
> On Fri, Aug 27, 2021 at 10:16:27AM -0700, Linus Torvalds wrote:
>> On Fri, Aug 27, 2021 at 10:10 AM Christoph Hellwig <hch at lst.de> wrote:
>>>
>>> They CCed me on their earlier discussion, but I did not catch up on it
>>> until you responded to the pull request  If I understood it correct it
>>> was about a platform device mapping a MMIO region (like a PCI bar),
>>> but something about section alignment cause pfn_valid to mistrigger.
>>
>> Yeah, so I can easily see the maxpfn numbers can easily end up being
>> rounded up to a whole memory section etc.
>>
>> I think my suggested solution should JustWork(tm) - exactly because if
>> the area is then in that "this pfn is valid" area, it will
>> double-check the actual underlying page.
> 
> I think the pitfall there is that the 'struct page' might well exist,
> but isn't necessarily initialised with anything meaningful. I remember
> seeing something like that in the past (I think for "no-map" memory) and
> David's reply here:
> 
> https://lore.kernel.org/r/aff3942e-b9ce-5bae-8214-0e5d89cd071c at redhat.com
> 
> hints that there are still gotchas with looking at the page flags for
> pages if the memory is offline or ZONE_DEVICE.
> 
> Don't get me wrong, I'd really like to use the generic code here as I
> think it would help to set expectations around what pfn_valid() actually
> means, I'm just less keen on the try-it-and-see-what-breaks approach
> given how sensitive it is to the layout of the physical memory map.
> 
>> That said, I think x86 avoids the problem another way - by just making
>> sure max_pfn is exact. That works too, as long as there are no holes
>> in the RAM map that might be used for PCI BAR's.
>>
>> So I think arm could fix it that way too, depending on their memory layout.
> 
> The physical memory map is the wild west, unfortunately. It's one of the
> things where everybody does something different and it's very common to see
> disjoint banks of memory placed seemingly randomly around.

The resource tree is usually the best place to really identify what's 
system RAM and what's not IIRC. memblock should work on applicable archs 
as well. Identifying ZONE_DEVICE ranges reliably is a different story ...

-- 
Thanks,

David / dhildenb



From nicolas at ndufresne.ca  Tue Aug 31 12:19:19 2021
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Tue, 31 Aug 2021 15:19:19 -0400
Subject: [PATCH 0/2] media: HEVC: RPS clean up
In-Reply-To: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
References: <20210831094900.203283-1-benjamin.gaignard@collabora.com>
Message-ID: <1484b5ebb9c943c72d7d7a0481c1a2cd9899705b.camel@ndufresne.ca>

As per discussion with Ezequiel, I think this patch should perhaps be made an
RFC titled "media: uapi: clean and make HEVC uAPI public". Keep it RFC until we
have collected all the needed changes.

Opinion ?

Le mardi 31 ao?t 2021 ? 11:48 +0200, Benjamin Gaignard a ?crit?:
> This series aims to clean up Reference Picture Set usage and flags.
> 
> Long term flag was named with RPS prefix while it is not used for RPS
> but for mark long term references in DBP. Remane it and remove the two
> other useless RPS flags.
> 
> Clarify documentation about RPS lists content and make sure that Hantro
> driver use them correctly (i.e without look up in DBP).
> 
> Benjamin
> 
> Benjamin Gaignard (2):
>   media: hevc: Remove RPS named flags
>   media: hevc: Embedded indexes in RPS
> 
>  .../media/v4l/ext-ctrls-codec.rst             | 12 ++++-----
>  .../staging/media/hantro/hantro_g2_hevc_dec.c | 27 +++++--------------
>  .../staging/media/sunxi/cedrus/cedrus_h265.c  |  2 +-
>  include/media/hevc-ctrls.h                    |  4 +--
>  4 files changed, 14 insertions(+), 31 deletions(-)
> 




From robh at kernel.org  Tue Aug 31 12:27:28 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 14:27:28 -0500
Subject: [v2,05/12] dt-bindings: pinctrl: update bindings for MT7986 SoC
In-Reply-To: <20210817074557.30953-6-sam.shih@mediatek.com>
References: <20210817074557.30953-1-sam.shih@mediatek.com>
 <20210817074557.30953-6-sam.shih@mediatek.com>
Message-ID: <YS6CoAxnarhqdTl+@robh.at.kernel.org>

On Tue, Aug 17, 2021 at 03:45:50PM +0800, Sam Shih wrote:
> This updates bindings for MT7986 pinctrl driver.
> The difference of pinctrl between mt7986a and mt7986b
> is that pin-41 to pin-65 do not exist on mt7986b
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> 
> ---
> v2 : deleted the redundant description of mt7986a/mt7986b
> 
> ---
>  .../bindings/pinctrl/pinctrl-mt7622.txt       | 170 ++++++++++++++++++
>  1 file changed, 170 insertions(+)

This is adding a lot to not be in schema format. I imagine this will 
need to be a separate file if the pin and function names are different 
for each SoC.

Rob


From jernej.skrabec at gmail.com  Tue Aug 31 12:53:50 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 31 Aug 2021 21:53:50 +0200
Subject: [PATCH] arm64: dts: sun50i: h5: NanoPI Neo 2: phy-mode
 rgmii-id
In-Reply-To: <YS1SsqDgGFOvyIT0@lunn.ch>
References: <20210830151645.18018-1-u@pkh.me>
 <116454729.UZi3dMzWh7@jernej-laptop> <YS1SsqDgGFOvyIT0@lunn.ch>
Message-ID: <1746741.3t3T1tWQfl@kista>

Hi Andrew!

Dne ponedeljek, 30. avgust 2021 ob 23:50:42 CEST je Andrew Lunn napisal(a):
> On Mon, Aug 30, 2021 at 10:49:37PM +0200, Jernej ?krabec wrote:
> > Hi!
> > 
> > Dne ponedeljek, 30. avgust 2021 ob 17:16:45 CEST je Cl?ment B?sch 
napisal(a):
> > > Since commit bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay
> > > config") network is broken on the NanoPi Neo 2.
> > > 
> > > This patch changes the phy-mode to use internal delays both for RX and
> > > TX as has been done for other boards affected by the same commit.
> > > 
> > > Fixes: bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay config")
> > 
> > This commit fixes DT issue, so "fixes" tag should be:
> > Fixes: 44a94c7ef989 ("arm64: dts: allwinner: H5: Restore EMAC changes")
> > 
> > Here, a node with wrong phy-mode property was added to NanoPi Neo 2 board 
DT.  
> 
> Hi Jernej
> 
> I would say, it is debatable. The board broke when the driver started
> acting on the value, which is commit bbc4d71d6354. It could be argued
> it was always technically broken, since it has the wrong value, but
> practically, it was not broken. One of the rules for stable is:
> 
>  - It must fix a real bug that bothers people (not a, "This could be a
>    problem..." type thing).
> 
> So i would argue, anything before bbc4d71d6354 does not fulfil stable
> requirements, since it does not bother anybody.

True, but then again, DT is a bit special, since it's not used only by Linux. 
It's shared at least with BSDs and U-Boot, which most likely have independent 
driver implementation. That's why it's good to have DT fixes referencing DT 
related commits. As you said, DT described HW wrong.

Looking at past Allwinner related DT commits regarding this issue, we were not 
totally consistent. Most of them reference commit where emac node was 
introduced in DT. But I also found a couple of commits which indeed have fixes 
tag for bbc4d71d6354.

Best regards,
Jernej

> 
>       Andrew
> 




From robh at kernel.org  Tue Aug 31 13:11:34 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 15:11:34 -0500
Subject: [PATCH v6 1/3] dt-bindings: pwm: Add Xilinx AXI Timer
In-Reply-To: <20210826211830.3311140-1-sean.anderson@seco.com>
References: <20210826211830.3311140-1-sean.anderson@seco.com>
Message-ID: <YS6M9jmTmy4EvB4k@robh.at.kernel.org>

On Thu, Aug 26, 2021 at 05:18:28PM -0400, Sean Anderson wrote:
> This adds a binding for the Xilinx LogiCORE IP AXI Timer. This device is a
> "soft" block, so it has some parameters which would not be configurable in
> most hardware. This binding is usually automatically generated by Xilinx's
> tools, so the names and values of some properties should be kept as they
> are, if possible. In addition, this binding is already in the kernel at
> arch/microblaze/boot/dts/system.dts, and in user software such as QEMU.
> 
> The existing driver uses the clock-frequency property, or alternatively the
> /cpus/timebase-frequency property as its frequency input. Because these
> properties are deprecated, they have not been included with this schema.
> All new bindings should use the clocks/clock-names properties to specify
> the parent clock.
> 
> Because we need to init timer devices so early in boot, we determine if we
> should use the PWM driver or the clocksource/clockevent driver by the
> presence/absence, respectively, of #pwm-cells. Because both counters are
> used by the PWM, there is no need for a separate property specifying which
> counters are to be used for the PWM.
> 
> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
> ---
> 
> Changes in v6:
> - Fix incorrect schema id
> - Enumerate possible counter widths
> 
> Changes in v5:
> - Update commit message to reflect revisions
> - Fix indentation lint
> - Add example for timer binding
> - Remove xlnx,axi-timer-2.0 compatible string
> - Move schema into the timer directory
> 
> Changes in v4:
> - Remove references to generate polarity so this can get merged
> - Predicate PWM driver on the presence of #pwm-cells
> - Make some properties optional for clocksource drivers
> 
> Changes in v3:
> - Mark all boolean-as-int properties as deprecated
> - Add xlnx,pwm and xlnx,gen?-active-low properties.
> - Make newer replacement properties mutually-exclusive with what they
>   replace
> - Add an example with non-deprecated properties only.
> 
> Changes in v2:
> - Use 32-bit addresses for example binding
> 
>  .../bindings/timer/xlnx,xps-timer.yaml        | 90 +++++++++++++++++++
>  1 file changed, 90 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml
> 
> diff --git a/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml b/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml
> new file mode 100644
> index 000000000000..5be353a642aa
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml
> @@ -0,0 +1,90 @@
> +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/timer/xlnx,xps-timer.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Xilinx LogiCORE IP AXI Timer Device Tree Binding
> +
> +maintainers:
> +  - Sean Anderson <sean.anderson at seco.com>
> +
> +properties:
> +  compatible:
> +    contains:
> +      const: xlnx,xps-timer-1.00.a
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    const: s_axi_aclk
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  reg:
> +    maxItems: 1
> +
> +  xlnx,count-width:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [8, 16, 32]
> +    default: 32
> +    description:
> +      The width of the counter(s), in bits.
> +
> +  xlnx,one-timer-only:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [ 0, 1 ]
> +    description:
> +      Whether only one timer is present in this block.
> +
> +required:
> +  - compatible
> +  - reg
> +  - xlnx,one-timer-only
> +
> +allOf:
> +  - if:
> +      required:
> +        - '#pwm-cells'
> +    then:
> +      allOf:
> +        - required:
> +            - clocks
> +        - properties:
> +            xlnx,one-timer-only:
> +              const: 0
> +    else:
> +      required:
> +        - interrupts
> +  - if:
> +      required:
> +        - clocks
> +    then:
> +      required:
> +        - clock-names
> +
> +additionalProperties: true

This needs to be false. What else do you expect to be present?

> +
> +examples:
> +  - |
> +    timer at 800e0000 {
> +        clock-names = "s_axi_aclk";
> +        clocks = <&zynqmp_clk 71>;
> +        compatible = "xlnx,xps-timer-1.00.a";
> +        reg = <0x800e0000 0x10000>;
> +        interrupts = <0 39 2>;
> +        xlnx,count-width = <16>;
> +        xlnx,one-timer-only = <0x0>;
> +    };
> +
> +    timer at 800f0000 {
> +        #pwm-cells = <0>;
> +        clock-names = "s_axi_aclk";
> +        clocks = <&zynqmp_clk 71>;
> +        compatible = "xlnx,xps-timer-1.00.a";
> +        reg = <0x800e0000 0x10000>;
> +        xlnx,count-width = <32>;
> +        xlnx,one-timer-only = <0x0>;
> +    };
> -- 
> 2.25.1
> 
> 


From sean.anderson at seco.com  Tue Aug 31 13:13:29 2021
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 31 Aug 2021 16:13:29 -0400
Subject: [PATCH v6 1/3] dt-bindings: pwm: Add Xilinx AXI Timer
In-Reply-To: <YS6M9jmTmy4EvB4k@robh.at.kernel.org>
References: <20210826211830.3311140-1-sean.anderson@seco.com>
 <YS6M9jmTmy4EvB4k@robh.at.kernel.org>
Message-ID: <264f3ab9-fbf7-8f5d-af57-26b8602a6fbd@seco.com>



On 8/31/21 4:11 PM, Rob Herring wrote:
> On Thu, Aug 26, 2021 at 05:18:28PM -0400, Sean Anderson wrote:
>> This adds a binding for the Xilinx LogiCORE IP AXI Timer. This device is a
>> "soft" block, so it has some parameters which would not be configurable in
>> most hardware. This binding is usually automatically generated by Xilinx's
>> tools, so the names and values of some properties should be kept as they
>> are, if possible. In addition, this binding is already in the kernel at
>> arch/microblaze/boot/dts/system.dts, and in user software such as QEMU.
>>
>> The existing driver uses the clock-frequency property, or alternatively the
>> /cpus/timebase-frequency property as its frequency input. Because these
>> properties are deprecated, they have not been included with this schema.
>> All new bindings should use the clocks/clock-names properties to specify
>> the parent clock.
>>
>> Because we need to init timer devices so early in boot, we determine if we
>> should use the PWM driver or the clocksource/clockevent driver by the
>> presence/absence, respectively, of #pwm-cells. Because both counters are
>> used by the PWM, there is no need for a separate property specifying which
>> counters are to be used for the PWM.
>>
>> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
>> ---
>>
>> Changes in v6:
>> - Fix incorrect schema id
>> - Enumerate possible counter widths
>>
>> Changes in v5:
>> - Update commit message to reflect revisions
>> - Fix indentation lint
>> - Add example for timer binding
>> - Remove xlnx,axi-timer-2.0 compatible string
>> - Move schema into the timer directory
>>
>> Changes in v4:
>> - Remove references to generate polarity so this can get merged
>> - Predicate PWM driver on the presence of #pwm-cells
>> - Make some properties optional for clocksource drivers
>>
>> Changes in v3:
>> - Mark all boolean-as-int properties as deprecated
>> - Add xlnx,pwm and xlnx,gen?-active-low properties.
>> - Make newer replacement properties mutually-exclusive with what they
>>   replace
>> - Add an example with non-deprecated properties only.
>>
>> Changes in v2:
>> - Use 32-bit addresses for example binding
>>
>>  .../bindings/timer/xlnx,xps-timer.yaml        | 90 +++++++++++++++++++
>>  1 file changed, 90 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml b/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml
>> new file mode 100644
>> index 000000000000..5be353a642aa
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/timer/xlnx,xps-timer.yaml
>> @@ -0,0 +1,90 @@
>> +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/timer/xlnx,xps-timer.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Xilinx LogiCORE IP AXI Timer Device Tree Binding
>> +
>> +maintainers:
>> +  - Sean Anderson <sean.anderson at seco.com>
>> +
>> +properties:
>> +  compatible:
>> +    contains:
>> +      const: xlnx,xps-timer-1.00.a
>> +
>> +  clocks:
>> +    maxItems: 1
>> +
>> +  clock-names:
>> +    const: s_axi_aclk
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  xlnx,count-width:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    enum: [8, 16, 32]
>> +    default: 32
>> +    description:
>> +      The width of the counter(s), in bits.
>> +
>> +  xlnx,one-timer-only:
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    enum: [ 0, 1 ]
>> +    description:
>> +      Whether only one timer is present in this block.
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - xlnx,one-timer-only
>> +
>> +allOf:
>> +  - if:
>> +      required:
>> +        - '#pwm-cells'
>> +    then:
>> +      allOf:
>> +        - required:
>> +            - clocks
>> +        - properties:
>> +            xlnx,one-timer-only:
>> +              const: 0
>> +    else:
>> +      required:
>> +        - interrupts
>> +  - if:
>> +      required:
>> +        - clocks
>> +    then:
>> +      required:
>> +        - clock-names
>> +
>> +additionalProperties: true
>
> This needs to be false. What else do you expect to be present?

There are additional properties present in the existing in-tree bindings
for this device. Should I instead set "unevaluatedProperties: false"?

--Sean

>
>> +
>> +examples:
>> +  - |
>> +    timer at 800e0000 {
>> +        clock-names = "s_axi_aclk";
>> +        clocks = <&zynqmp_clk 71>;
>> +        compatible = "xlnx,xps-timer-1.00.a";
>> +        reg = <0x800e0000 0x10000>;
>> +        interrupts = <0 39 2>;
>> +        xlnx,count-width = <16>;
>> +        xlnx,one-timer-only = <0x0>;
>> +    };
>> +
>> +    timer at 800f0000 {
>> +        #pwm-cells = <0>;
>> +        clock-names = "s_axi_aclk";
>> +        clocks = <&zynqmp_clk 71>;
>> +        compatible = "xlnx,xps-timer-1.00.a";
>> +        reg = <0x800e0000 0x10000>;
>> +        xlnx,count-width = <32>;
>> +        xlnx,one-timer-only = <0x0>;
>> +    };
>> --
>> 2.25.1
>>
>>
>


From jernej.skrabec at gmail.com  Tue Aug 31 13:17:56 2021
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 31 Aug 2021 22:17:56 +0200
Subject: [PATCH] arm64: dts: sun50i: h5: NanoPI Neo 2: phy-mode
 rgmii-id
In-Reply-To: <YS1Mwz+fT9P2qskW@ssq0.pkh.me>
References: <20210830151645.18018-1-u@pkh.me>
 <116454729.UZi3dMzWh7@jernej-laptop> <YS1Mwz+fT9P2qskW@ssq0.pkh.me>
Message-ID: <4192454.QcIURlJl1r@kista>

Hi!

Dne ponedeljek, 30. avgust 2021 ob 23:25:23 CEST je Cl?ment B?sch napisal(a):
> On Mon, Aug 30, 2021 at 10:49:37PM +0200, Jernej ?krabec wrote:
> > Hi!
> > 
> 
> Hi,
> 
> > Dne ponedeljek, 30. avgust 2021 ob 17:16:45 CEST je Cl?ment B?sch 
napisal(a):
> > > Since commit bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay
> > > config") network is broken on the NanoPi Neo 2.
> > > 
> > > This patch changes the phy-mode to use internal delays both for RX and
> > > TX as has been done for other boards affected by the same commit.
> > > 
> > > Fixes: bbc4d71d6354 ("net: phy: realtek: fix rtl8211e rx/tx delay config")
> > 
> > This commit fixes DT issue, so "fixes" tag should be:
> > Fixes: 44a94c7ef989 ("arm64: dts: allwinner: H5: Restore EMAC changes")
> > 
> > Here, a node with wrong phy-mode property was added to NanoPi Neo 2 board 
DT.  
> 
> Shouldn't I add it instead of replacing? I followed what I observed in
> `git log --grep bbc4d71d63` where all the commits pretty much follow this
> pattern: that commit is the one causing the actual observed regression,
> while 44a94c7ef989 is much older, and while it's wrong, it wasn't causing
> an issue in practice.
> 
> Or did I misunderstand something?

With that grep command you limited yourself only to those commits which 
reference this particular commit. There are others, which also change "rgmii" 
to "rgmii-id" and reference other commits, like:
544cc3f8573b ("arm64: dts: allwinner: h6: orangepi-one-plus: Fix ethernet")
97a38c1c213b ("arm64: dts: allwinner: beelink-gs1: Enable both RGMII RX/TX 
delay")
(there are more).

Anyway, let's continue this discussion in Andrew's thread.

> 
> > Other than that, this patch is fine and once fixes tag is fixed, you can add:
> > Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
> > 
> > For next version, you should:
> > - change fixed tag
> > - add my review-by tag right above your signed-off-by tag
> > - mark patch as v2 (add "-v2" parameter to git format-patch)
> > - describe change right under "---" line
> > 
> 
> Will do.

Please wait until discussion reaches a conclusion.

> 
> > Note, if you borked something when sending, you should mark patch or patch 
> > series as "RESEND", so recipients don't look for changes in two subsequent 
e-
> > mails (--subject-prefix="RESEND PATCH").
> 
> Not sure I follow you so before I disturb everyone with more noise I'd
> just like to confirm: you mean a git send-email in-reply-to=[broken patch
> attempt] (the one where I borked the --cc), right? But with what patch?
> I'm a bit confused here.

That's just for the future reference. No need to do anything now for this 
patch. If you bork any send attempt in the future, recreate same patch(es) 
with this additional tag ("RESEND") and send them again.

> 
> > Thanks for the fix!
> 
> No problem; I really think a scan of all the other boards would be
> meaningful though, it looks like a lot of them got fixed but there are
> many other candidates and the issue feels pretty critical to me
> (regression, and no network at all).

I guess you speak for all boards, not just those with Allwinner SoC? I fixed as 
many boards as I have - testing is very desired. On some boards rgmii was 
changed to rgmii-txid, so it's not as straightforward as search and replace. 
It could be also deducted from schematics, but at least one Allwinner board 
has this configured in HW wrong (SW fix was needed for that board) and other 
boards might not have schematics publicy available.

In short, I wouldn't start mass generating patches for this.

Best regards,
Jernej

> 
> -- 
> Cl?ment B.
> 




From robh at kernel.org  Tue Aug 31 13:21:33 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 15:21:33 -0500
Subject: [PATCH 04/13] ASoC: dt-bindings: tegra: Few more Tegra210 AHUB
 modules
In-Reply-To: <1630056839-6562-5-git-send-email-spujar@nvidia.com>
References: <1630056839-6562-1-git-send-email-spujar@nvidia.com>
 <1630056839-6562-5-git-send-email-spujar@nvidia.com>
Message-ID: <YS6PTYwwu9tU8TWX@robh.at.kernel.org>

On Fri, Aug 27, 2021 at 03:03:50PM +0530, Sameer Pujar wrote:
> This patch adds YAML schema for DT bindings of few AHUB modules.
> These devices will be registered as ASoC components and bindings
> will be used on Tegra210 and later chips. The bindings for below
> mentioned modules are added:
> 
>  * SFC (Sampling Frequency Converter)
>  * MVC (Master Volume Control)
>  * AMX (Audio Multiplexer)
>  * ADX (Audio Demultiplexer)
>  * Mixer
> 
> Signed-off-by: Sameer Pujar <spujar at nvidia.com>
> Cc: Rob Herring <robh+dt at kernel.org> 
> ---
>  .../bindings/sound/nvidia,tegra210-adx.yaml        | 74 ++++++++++++++++++++
>  .../bindings/sound/nvidia,tegra210-ahub.yaml       | 20 ++++++
>  .../bindings/sound/nvidia,tegra210-amx.yaml        | 72 ++++++++++++++++++++
>  .../bindings/sound/nvidia,tegra210-mixer.yaml      | 67 ++++++++++++++++++
>  .../bindings/sound/nvidia,tegra210-mvc.yaml        | 79 ++++++++++++++++++++++
>  .../bindings/sound/nvidia,tegra210-sfc.yaml        | 76 +++++++++++++++++++++
>  6 files changed, 388 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
>  create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
>  create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
>  create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
>  create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
> new file mode 100644
> index 0000000..9950585
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-adx.yaml
> @@ -0,0 +1,74 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/nvidia,tegra210-adx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tegra210 ADX Device Tree Bindings
> +
> +description: |
> +  The Audio Demultiplexer (ADX) block takes an input stream with   up to

extra spaces.

> +  16 channels and demultiplexes it into four output streams of up to 16
> +  channels each. A byte RAM helps to form output frames by any combination
> +  of bytes from the input frame. Its design is identical to that of byte
> +  RAM in the AMX except that the data flow direction is reversed.
> +
> +maintainers:
> +  - Jon Hunter <jonathanh at nvidia.com>
> +  - Mohan Kumar <mkumard at nvidia.com>
> +  - Sameer Pujar <spujar at nvidia.com>
> +
> +properties:
> +  $nodename:
> +    pattern: "^adx@[0-9a-f]*$"
> +
> +  compatible:
> +    oneOf:
> +      - const: nvidia,tegra210-adx
> +      - items:
> +          - enum:
> +              - nvidia,tegra194-adx
> +              - nvidia,tegra186-adx
> +          - const: nvidia,tegra210-adx
> +
> +  reg:
> +    maxItems: 1
> +
> +  sound-name-prefix:

nvidia,sound-name-prefix

> +    pattern: "^ADX[1-9]$"
> +    $ref: /schemas/types.yaml#/definitions/string
> +    description:
> +      used as prefix for sink/source names of the component. Must be a
> +      unique string among multiple instances of the same component.
> +      The name can be "ADX1" or "ADX2" ... "ADXx", where x depends on
> +      the maximum available instances on a Tegra SoC.
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +    description: |
> +      ADX has one input and four output. Accordingly ACIF (Audio Client

You need to define the port numbers for the input and each output.

> +      Interface) RX and TX port nodes are defined to represent ADX inputs
> +      and output respectively. These are connected to corresponding ports
> +      on AHUB.
> +
> +    patternProperties:
> +      '^port@[0-9]':

Per above, this will need to be split at least into input and output 
ports.

Same issues in the other schemas.

> +        $ref: audio-graph-port.yaml#
> +        unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    adx at 702d3800 {
> +        compatible = "nvidia,tegra210-adx";
> +        reg = <0x702d3800 0x100>;
> +        sound-name-prefix = "ADX1";
> +    };
> +
> +...
> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
> index 1118a94..4087eeb 100644
> --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
> +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml
> @@ -85,6 +85,26 @@ patternProperties:
>      type: object
>      $ref: nvidia,tegra186-dspk.yaml#
>  
> +  '^mvc@[0-9a-f]+$':
> +    type: object
> +    $ref: nvidia,tegra210-mvc.yaml#
> +
> +  '^sfc@[0-9a-f]+$':
> +    type: object
> +    $ref: nvidia,tegra210-sfc.yaml#
> +
> +  '^amx@[0-9a-f]+$':
> +    type: object
> +    $ref: nvidia,tegra210-amx.yaml#
> +
> +  '^adx@[0-9a-f]+$':
> +    type: object
> +    $ref: nvidia,tegra210-adx.yaml#
> +
> +  '^mixer@[0-9a-f]+$':
> +    type: object
> +    $ref: nvidia,tegra210-mixer.yaml#
> +
>  required:
>    - compatible
>    - reg
> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
> new file mode 100644
> index 0000000..e6b365b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-amx.yaml
> @@ -0,0 +1,72 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/nvidia,tegra210-amx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tegra210 AMX Device Tree Bindings
> +
> +description: |
> +  The Audio Multiplexer (AMX) block can multiplex up to four input streams
> +  each of which can have maximum 16 channels and generate an output stream
> +  with maximum 16 channels. A byte RAM helps to form an output frame by
> +  any combination of bytes from the input frames.
> +
> +maintainers:
> +  - Jon Hunter <jonathanh at nvidia.com>
> +  - Mohan Kumar <mkumard at nvidia.com>
> +  - Sameer Pujar <spujar at nvidia.com>
> +
> +properties:
> +  $nodename:
> +    pattern: "^amx@[0-9a-f]*$"
> +
> +  compatible:
> +    oneOf:
> +      - const: nvidia,tegra210-amx
> +      - items:
> +          - const: nvidia,tegra186-amx
> +          - const: nvidia,tegra210-amx
> +      - const: nvidia,tegra194-amx
> +
> +  reg:
> +    maxItems: 1
> +
> +  sound-name-prefix:
> +    pattern: "^AMX[1-9]$"
> +    $ref: /schemas/types.yaml#/definitions/string
> +    description:
> +      used as prefix for sink/source names of the component. Must be a
> +      unique string among multiple instances of the same component.
> +      The name can be "AMX1" or "AMX2" ... "AMXx", where x depends on
> +      the maximum available instances on a Tegra SoC.
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +    description: |
> +      AMX has four inputs and one output. Accordingly ACIF (Audio Client
> +      Interfaces) RX and TX port nodes are defined to represent AMX inputs
> +      and output respectively. These are connected to corresponding ports
> +      on AHUB.
> +
> +    patternProperties:
> +      '^port@[0-9]':
> +        $ref: audio-graph-port.yaml#
> +        unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    amx at 702d3000 {
> +        compatible = "nvidia,tegra210-amx";
> +        reg = <0x702d3000 0x100>;
> +        sound-name-prefix = "AMX1";
> +    };
> +
> +...
> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
> new file mode 100644
> index 0000000..0808355
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mixer.yaml
> @@ -0,0 +1,67 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/nvidia,tegra210-mixer.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tegra210 Mixer Device Tree Bindings
> +
> +description: |
> +  The Mixer supports mixing of up to ten 7.1 audio input streams and
> +  generate five outputs (each of which can be any combination of the
> +  ten input streams).
> +
> +maintainers:
> +  - Jon Hunter <jonathanh at nvidia.com>
> +  - Mohan Kumar <mkumard at nvidia.com>
> +  - Sameer Pujar <spujar at nvidia.com>
> +
> +properties:
> +  $nodename:
> +    pattern: "^mixer@[0-9a-f]*$"
> +
> +  compatible:
> +    oneOf:
> +      - const: nvidia,tegra210-amixer
> +      - items:
> +          - enum:
> +              - nvidia,tegra194-amixer
> +              - nvidia,tegra186-amixer
> +          - const: nvidia,tegra210-amixer
> +
> +  reg:
> +    maxItems: 1
> +
> +  sound-name-prefix:
> +    const: "MIXER"

Don't need quotes. A fixed string seems a bit pointless to put into DT.

> +    $ref: /schemas/types.yaml#/definitions/string
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +    description: |
> +      Mixer has ten inputs and five outputs. Accordingly ACIF (Audio Client
> +      Interfaces) RX and TX port nodes are defined to represent MIXER inputs
> +      and outputs respectively. These are connected to corresponding ports
> +      on AHUB.
> +
> +    patternProperties:
> +      '^port@[0-9]':
> +        $ref: audio-graph-port.yaml#
> +        unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    mixer at 702dbb00 {
> +        compatible = "nvidia,tegra210-amixer";
> +        reg = <0x702dbb00 0x800>;
> +        sound-name-prefix = "MIXER";
> +    };
> +
> +...
> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
> new file mode 100644
> index 0000000..7d81b11
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mvc.yaml
> @@ -0,0 +1,79 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/nvidia,tegra210-mvc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tegra210 MVC Device Tree Bindings
> +
> +description: |
> +  The Master Volume Control (MVC) provides gain or attenuation to a digital
> +  signal path. It can be used in input or output signal path for per-stream
> +  volume control or it can be used as master volume control. The MVC block
> +  has one input and one output. The input digital stream can be mono or
> +  multi-channel (up to 7.1 channels) stream. An independent mute control is
> +  also included in the MVC block.
> +
> +maintainers:
> +  - Jon Hunter <jonathanh at nvidia.com>
> +  - Mohan Kumar <mkumard at nvidia.com>
> +  - Sameer Pujar <spujar at nvidia.com>
> +
> +properties:
> +  $nodename:
> +    pattern: "^mvc@[0-9a-f]*$"
> +
> +  compatible:
> +    oneOf:
> +      - const: nvidia,tegra210-mvc
> +      - items:
> +          - enum:
> +              - nvidia,tegra194-mvc
> +              - nvidia,tegra186-mvc
> +          - const: nvidia,tegra210-mvc
> +
> +  reg:
> +    maxItems: 1
> +
> +  sound-name-prefix:
> +    pattern: "^MVC[1-9]$"
> +    $ref: /schemas/types.yaml#/definitions/string
> +    description:
> +      used as prefix for sink/source names of the component. Must be a
> +      unique string among multiple instances of the same component.
> +      The name can be "MVC1" or "MVC2" ... "MVCx", where x depends on
> +      the maximum available instances on a Tegra SoC.
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +    properties:
> +      port at 0:
> +        $ref: audio-graph-port.yaml#
> +        unevaluatedProperties: false
> +        description: |
> +          ACIF (Audio Client Interface) acting as MVC input (RX) port.
> +          This is connected to corresponding ACIF port on AHUB.
> +
> +      port at 1:
> +        $ref: audio-graph-port.yaml#
> +        unevaluatedProperties: false
> +        description: |
> +          ACIF (Audio Client Interface) acting as MVC output (TX) port.
> +          This is connected to corresponding ACIF port on AHUB.
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    mvc at 702da000 {
> +        compatible = "nvidia,tegra210-mvc";
> +        reg = <0x702da000 0x200>;
> +        sound-name-prefix = "MVC1";
> +    };
> +
> +...
> diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
> new file mode 100644
> index 0000000..5f05e2a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-sfc.yaml
> @@ -0,0 +1,76 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/nvidia,tegra210-sfc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tegra210 SFC Device Tree Bindings
> +
> +description: |
> +  The Sampling Frequency Converter (SFC) converts the sampling frequency
> +  of the input signal from one frequency to another. It supports sampling
> +  frequency conversions of streams of up to two channels (stereo).
> +
> +maintainers:
> +  - Jon Hunter <jonathanh at nvidia.com>
> +  - Mohan Kumar <mkumard at nvidia.com>
> +  - Sameer Pujar <spujar at nvidia.com>
> +
> +properties:
> +  $nodename:
> +    pattern: "^sfc@[0-9a-f]*$"
> +
> +  compatible:
> +    oneOf:
> +      - const: nvidia,tegra210-sfc
> +      - items:
> +          - enum:
> +              - nvidia,tegra194-sfc
> +              - nvidia,tegra186-sfc
> +          - const: nvidia,tegra210-sfc
> +
> +  reg:
> +    maxItems: 1
> +
> +  sound-name-prefix:
> +    pattern: "^SFC[1-9]$"
> +    $ref: /schemas/types.yaml#/definitions/string
> +    description:
> +      used as prefix for sink/source names of the component. Must be a
> +      unique string among multiple instances of the same component.
> +      The name can be "SFC1" or "SFC2" ... "SFCx", where x depends on
> +      the maximum available instances on a Tegra SoC.
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +    properties:
> +      port at 0:
> +        $ref: audio-graph-port.yaml#
> +        unevaluatedProperties: false
> +        description: |
> +          ACIF (Audio Client Interface) acting as SFC input (RX) port.
> +          This is connected to corresponding ACIF port on AHUB.
> +
> +      port at 1:
> +        $ref: audio-graph-port.yaml#
> +        unevaluatedProperties: false
> +        description: |
> +          ACIF (Audio Client Interface) acting as SFC output (TX) port.
> +          This is connected to corresponding ACIF port on AHUB.
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    sfc at 702d2000 {
> +        compatible = "nvidia,tegra210-sfc";
> +        reg = <0x702d2000 0x200>;
> +        sound-name-prefix = "SFC1";
> +    };
> +
> +...
> -- 
> 2.7.4
> 
> 


From robh at kernel.org  Tue Aug 31 13:22:06 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 15:22:06 -0500
Subject: [PATCH v1 1/2] dt-bindings: mmc: mtk-sd: add hs400 dly3 setting
In-Reply-To: <1630065205-7618-2-git-send-email-wenbin.mei@mediatek.com>
References: <1630065205-7618-1-git-send-email-wenbin.mei@mediatek.com>
 <1630065205-7618-2-git-send-email-wenbin.mei@mediatek.com>
Message-ID: <YS6PbrCTIZJwe1cX@robh.at.kernel.org>

On Fri, 27 Aug 2021 19:53:24 +0800, Wenbin Mei wrote:
> Add hs400 dly3 setting for mtk-sd yaml
> 
> Signed-off-by: Wenbin Mei <wenbin.mei at mediatek.com>
> ---
>  Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

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


From robh at kernel.org  Tue Aug 31 13:44:15 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 15:44:15 -0500
Subject: [PATCH v2 3/4] amba: Kill sysfs attribute file of irq
In-Reply-To: <20210827150600.78811-4-wangkefeng.wang@huawei.com>
References: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
 <20210827150600.78811-4-wangkefeng.wang@huawei.com>
Message-ID: <YS6Un+Zdbaj5qe63@robh.at.kernel.org>

On Fri, Aug 27, 2021 at 11:05:59PM +0800, Kefeng Wang wrote:
> As Rob said[1], there doesn't seem to be any users about the sysfs
> attribute file of irq[0] and irq[1]. And we don't need to include
> <asm/irq.h> as NO_IRQ has gone. Let's kill both of them.
>
> [1] https://lkml.org/lkml/2021/8/25/461
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  drivers/amba/bus.c | 18 ++----------------
>  1 file changed, 2 insertions(+), 16 deletions(-)

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

 
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index 37fcd5592c6f..4d3a565ca079 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -20,8 +20,6 @@
>  #include <linux/platform_device.h>
>  #include <linux/reset.h>
>  
> -#include <asm/irq.h>
> -
>  #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
>  
>  /* called on periphid match and class 0x9 coresight device. */
> @@ -135,8 +133,6 @@ static ssize_t name##_show(struct device *_dev,				\
>  static DEVICE_ATTR_RO(name)
>  
>  amba_attr_func(id, "%08x\n", dev->periphid);
> -amba_attr_func(irq0, "%u\n", dev->irq[0]);
> -amba_attr_func(irq1, "%u\n", dev->irq[1]);
>  amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",

Might want to get rid of this too. It's available thru other means (DT). 
That can be another patch.

>  	 (unsigned long long)dev->res.start, (unsigned long long)dev->res.end,
>  	 dev->res.flags);
> @@ -463,20 +459,10 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
>  
>   skip_probe:
>  	ret = device_add(&dev->dev);
> -	if (ret)
> -		goto err_release;
> -
> -	if (dev->irq[0])
> -		ret = device_create_file(&dev->dev, &dev_attr_irq0);
> -	if (ret == 0 && dev->irq[1])
> -		ret = device_create_file(&dev->dev, &dev_attr_irq1);
> -	if (ret == 0)
> -		return ret;
> -
> -	device_unregister(&dev->dev);
>  
>   err_release:
> -	release_resource(&dev->res);
> +	if (ret)
> +		release_resource(&dev->res);
>   err_out:
>  	return ret;
>  
> -- 
> 2.18.0.huawei.25
> 
> 


From robh at kernel.org  Tue Aug 31 13:48:09 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 15:48:09 -0500
Subject: [PATCH v2 4/4] amba: Properly handle device probe without IRQ
 domain
In-Reply-To: <20210827150600.78811-5-wangkefeng.wang@huawei.com>
References: <20210827150600.78811-1-wangkefeng.wang@huawei.com>
 <20210827150600.78811-5-wangkefeng.wang@huawei.com>
Message-ID: <YS6ViZ98JGa/KJ+Z@robh.at.kernel.org>

On Fri, Aug 27, 2021 at 11:06:00PM +0800, Kefeng Wang wrote:
> of_amba_device_create() uses irq_of_parse_and_map() to translate
> a DT interrupt specification into a Linux virtual interrupt number.
> 
> But it doesn't properly handle the case where the interrupt controller
> is not yet available, eg, when pl011 interrupt is connected to MBIGEN
> interrupt controller, because the mbigen initialization is too late,
> which will lead to no IRQ due to no IRQ domain found, log is shown below,
>   "irq: no irq domain found for uart0 !"
> 
> use of_irq_get() to return -EPROBE_DEFER as above, and in the driver
> deferred probe, it will properly handle in such case, also return 0
> in other fail cases to be consistent as before.
> 
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Frank Rowand <frowand.list at gmail.com>
> Reported-by: Ruizhe Lin <linruizhe at huawei.com>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  drivers/amba/bus.c    | 27 +++++++++++++++++++++++++++
>  drivers/of/platform.c |  6 +-----
>  2 files changed, 28 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
> index 4d3a565ca079..96e84ce66e9a 100644
> --- a/drivers/amba/bus.c
> +++ b/drivers/amba/bus.c
> @@ -19,6 +19,7 @@
>  #include <linux/clk/clk-conf.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset.h>
> +#include <linux/of_irq.h>
>  
>  #define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
>  
> @@ -170,6 +171,28 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
>  	return retval;
>  }
>  
> +static int of_amba_device_decode_irq(struct amba_device *dev)
> +{
> +	struct device_node *node = dev->dev.of_node;
> +	int i, irq;
> +
> +	if (IS_ENABLED(CONFIG_OF_IRQ) && node) {

I don't think this check is needed. If either is false, we should return 
an errno from of_irq_get().

> +		/* Decode the IRQs and address ranges */
> +		for (i = 0; i < AMBA_NR_IRQS; i++) {
> +			irq = of_irq_get(node, i);
> +			if (irq < 0) {
> +				if (irq == -EPROBE_DEFER)
> +					return irq;
> +				irq = 0;
> +			}
> +
> +			dev->irq[i] = irq;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * These are the device model conversion veneers; they convert the
>   * device model structures to our more specific structures.
> @@ -182,6 +205,10 @@ static int amba_probe(struct device *dev)
>  	int ret;
>  
>  	do {
> +		ret = of_amba_device_decode_irq(pcdev);
> +		if (ret)
> +			break;
> +
>  		ret = of_clk_set_defaults(dev->of_node, false);
>  		if (ret < 0)
>  			break;
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 74afbb7a4f5e..32d5ff8df747 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -222,7 +222,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  {
>  	struct amba_device *dev;
>  	const void *prop;
> -	int i, ret;
> +	int ret;
>  
>  	pr_debug("Creating amba device %pOF\n", node);
>  
> @@ -253,10 +253,6 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>  	if (prop)
>  		dev->periphid = of_read_ulong(prop, 1);
>  
> -	/* Decode the IRQs and address ranges */
> -	for (i = 0; i < AMBA_NR_IRQS; i++)
> -		dev->irq[i] = irq_of_parse_and_map(node, i);
> -
>  	ret = of_address_to_resource(node, 0, &dev->res);
>  	if (ret) {
>  		pr_err("amba: of_address_to_resource() failed (%d) for %pOF\n",
> -- 
> 2.18.0.huawei.25
> 
> 


From linux.amoon at gmail.com  Tue Aug 31 13:47:54 2021
From: linux.amoon at gmail.com (Anand Moon)
Date: Wed, 1 Sep 2021 02:17:54 +0530
Subject: [PATCHv3 1/6] ARM: dts: meson8b: odroidc1: Add usb phy power node
In-Reply-To: <2b07b3de-cee5-c570-8fde-6a4c684122d6@baylibre.com>
References: <20210817041548.1276-1-linux.amoon@gmail.com>
 <20210817041548.1276-2-linux.amoon@gmail.com>
 <c7f6213b-5ddc-881c-1aea-9cc7b03e6a4f@baylibre.com>
 <CAFBinCBeNMET2tvH0h6HF3dR+xBb59hifQyaoXigUs3UGkS+KQ@mail.gmail.com>
 <2b07b3de-cee5-c570-8fde-6a4c684122d6@baylibre.com>
Message-ID: <CANAwSgRNp8UtU+Yy4smwZ5POTWTU+xN1mrf_cH7Pu9yX5HU=VA@mail.gmail.com>

Hi Neil / Martin,

Thanks for your review comments.

On Tue, 31 Aug 2021 at 20:20, Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi,
>
> On 30/08/2021 21:37, Martin Blumenstingl wrote:
> > Hi Neil,
> >
> > On Mon, Aug 30, 2021 at 9:45 AM Neil Armstrong <narmstrong at baylibre.com> wrote:
> >>
> >> Hi,
> >>
> >> On 17/08/2021 06:15, Anand Moon wrote:
> >>> Add missing usb phy power node for usb node fix below warning.
> >>> P5V0 regulator supply input voltage range to USB host controller.
> >>> As described in the C1+ schematics, GPIO GPIOAO_5 is used to
> >>> enable input power to USB ports, set it to Active Low.
> >>>
> >>> [    1.260772] dwc2 c90c0000.usb: Looking up vbus-supply from device tree
> >>> [    1.260784] dwc2 c90c0000.usb: Looking up vbus-supply property in
> >>>               mode /soc/usb at c90c0000 failed
> >>
> >> First of all, DT is not here to fix boot message.
> > Anand mentioned elsewhere that this is a debug/info message
> >
> >> Finally, I looked at the Odroid-C1 schematics and the GPIOAO.BIT5 is an input
> >> to the S805, and the PWREN signal is controlled by the USB Hub so this regulator
> >> should not be added at all.
> > I think there's a misunderstanding because there's two PWREN signals
> > with different meanings.
> > The PWREN signal for the USB host ports is hard-wired and not
> > connected to the SoC at all.
> > The PWREN signal for the Micro-USB port (which Anand is adding here)
> > is controlled by GPIOAO_5. odroid-c1+_rev0.4_20150615.pdf [0] shows it
> > as an input to "USB_OTG" on page 1. "USB_OTG" consists of a power
> > switch and the connector itself as shown on page 28.
> >
> > Personally I think that the change from Anand itself is good.
> > If you feel otherwise then please speak up.
>
> Ok thanks for the clarification, then the change is ok, but not the commit message.
>
> >> Add missing usb phy power node for usb node fix below warning.
>
> is not a good reason for a DT change. A proper reason should be added.
>
> And the commit message doesn't specify the change is for the Micro-USB port,
> this should be clarified.
>
> Neil
>
> > As I pointed out three smaller changes I am hoping that Anand will
> > re-send the updated patch anyways. At that point he can also add the
> > changes from your feedback.
> >
Ok I will try to address your feedback in the next version.

After enabling CONFIG_REGULATOR_DEBUG, with this patch applied
I still not getting the USB regulator to enable.
Do you see different output at your end?

On Odroid C1+
[    5.737571] reg-fixed-voltage regulator-usb-pwr-en: GPIO lookup for
consumer (null)
[    5.737630] reg-fixed-voltage regulator-usb-pwr-en: using device
tree for GPIO lookup
[    5.737711] of_get_named_gpiod_flags: can't parse 'gpios' property
of node '/regulator-usb-pwr-en[0]'
[    5.737906] of_get_named_gpiod_flags: parsed 'gpio' property of
node '/regulator-usb-pwr-en[0]' - status (0)
[    5.738209] gpio_stub_drv gpiochip0: Persistence not supported for GPIO 5
[    5.738490] USB_OTG_PWR: 5000 mV, disabled
[    5.740313] reg-fixed-voltage regulator-usb-pwr-en: Looking up
vin-supply from device tree
[    5.740394] USB_OTG_PWR: supplied by P5V0
[    5.741235] reg-fixed-voltage regulator-usb-pwr-en: USB_OTG_PWR
supplying 5000000uV

Odroid N2.
[    3.047813] reg-fixed-voltage regulator-hub_5v: HUB_5V supplying 5000000uV
[    3.049282] reg-fixed-voltage regulator-usb_pwr_en: GPIO lookup for
consumer (null)
[    3.049305] reg-fixed-voltage regulator-usb_pwr_en: using device
tree for GPIO lookup
[    3.049370] of_get_named_gpiod_flags: can't parse 'gpios' property
of node '/regulator-usb_pwr_en[0]'
[    3.049500] of_get_named_gpiod_flags: parsed 'gpio' property of
node '/regulator-usb_pwr_en[0]' - status (0)
[    3.049622] gpio_stub_drv gpiochip0: Persistence not supported for GPIO 22
[    3.049759] USB_PWR_EN: 5000 mV, disabled
[    3.051257] reg-fixed-voltage regulator-usb_pwr_en: Looking up
vin-supply from device tree
[    3.051320] USB_PWR_EN: supplied by 5V

Thanks
-Anand



> >
> > Best regards,
> > Martin
> >
> >
> > [0] https://dn.odroid.com/S805/Schematics/odroid-c1+_rev0.4_20150615.pdf
> >
>


From andrew at lunn.ch  Tue Aug 31 13:53:24 2021
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 31 Aug 2021 22:53:24 +0200
Subject: [PATCH] arm64: dts: sun50i: h5: NanoPI Neo 2: phy-mode
 rgmii-id
In-Reply-To: <1746741.3t3T1tWQfl@kista>
References: <20210830151645.18018-1-u@pkh.me>
 <116454729.UZi3dMzWh7@jernej-laptop> <YS1SsqDgGFOvyIT0@lunn.ch>
 <1746741.3t3T1tWQfl@kista>
Message-ID: <YS6WxHtJtNDaBxqz@lunn.ch>

> True, but then again, DT is a bit special, since it's not used only by Linux. 
> It's shared at least with BSDs and U-Boot, which most likely have independent 
> driver implementation. That's why it's good to have DT fixes referencing DT 
> related commits. As you said, DT described HW wrong.
> 
> Looking at past Allwinner related DT commits regarding this issue, we were not 
> totally consistent. Most of them reference commit where emac node was 
> introduced in DT. But I also found a couple of commits which indeed have fixes 
> tag for bbc4d71d6354.

All true, and it is not a big deal if it does go back further. I don't
care, we can let the Allwinner Maintainer decide. Ah, that is you :-)

I just want to try to keep it simple for somebody who is contributing
their first Linux kernel patch. If it is good enough, i say accept it,
and we can do a bit more education on the second contribution.

    Andre


From robh at kernel.org  Tue Aug 31 13:57:10 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 15:57:10 -0500
Subject: [PATCH v4 1/4] dt-bindings: interrupt-controller: Convert MSI
 controller to json-schema
In-Reply-To: <20210827171534.62380-2-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-2-mark.kettenis@xs4all.nl>
Message-ID: <YS6XpkluSVRIvR6J@robh.at.kernel.org>

On Fri, Aug 27, 2021 at 07:15:26PM +0200, Mark Kettenis wrote:
> From: Mark Kettenis <kettenis at openbsd.org>
> 
> Split the MSI controller bindings from the MSI binding document
> into DT schema format using json-schema.
> 
> Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> ---
>  .../interrupt-controller/msi-controller.yaml  | 34 +++++++++++++++++++
>  .../bindings/pci/brcm,stb-pcie.yaml           |  1 +
>  .../bindings/pci/microchip,pcie-host.yaml     |  1 +
>  3 files changed, 36 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> new file mode 100644
> index 000000000000..5ed6cd46e2e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> @@ -0,0 +1,34 @@
> +# SPDX-License-Identifier: BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/msi-controller.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MSI controller
> +
> +maintainers:
> +  - Marc Zyngier <marc.zyngier at arm.com>
> +
> +description: |
> +  An MSI controller signals interrupts to a CPU when a write is made
> +  to an MMIO address by some master. An MSI controller may feature a
> +  number of doorbells.
> +
> +properties:
> +  "#msi-cells":
> +    description: |
> +      The number of cells in an msi-specifier, required if not zero.
> +
> +      Typically this will encode information related to sideband data,
> +      and will not encode doorbells or payloads as these can be
> +      configured dynamically.
> +
> +      The meaning of the msi-specifier is defined by the device tree
> +      binding of the specific MSI controller.

I'd prefer we limit this to the maximum range. I'd like to know when 
someone needs 2 cells (or 3000).

enum: [ 0, 1 ]

Though no one seems to use 0 (making it optional was probably a 
mistake...)

> +
> +  msi-controller:
> +    description:
> +      Identifies the node as an MSI controller.
> +    $ref: /schemas/types.yaml#/definitions/flag

dependencies:
  "#msi-cells": [ msi-controller ]

> +
> +additionalProperties: true
> diff --git a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> index b9589a0daa5c..5c67976a8dc2 100644
> --- a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> @@ -88,6 +88,7 @@ required:
>  
>  allOf:
>    - $ref: /schemas/pci/pci-bus.yaml#
> +  - $ref: ../interrupt-controller/msi-controller.yaml#

/schemas/interrupt-controller/msi-controller.yaml#

>    - if:
>        properties:
>          compatible:
> diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> index fb95c276a986..684d9d036f48 100644
> --- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> +++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> @@ -11,6 +11,7 @@ maintainers:
>  
>  allOf:
>    - $ref: /schemas/pci/pci-bus.yaml#
> +  - $ref: ../interrupt-controller/msi-controller.yaml#
>  
>  properties:
>    compatible:
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Tue Aug 31 13:58:14 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 15:58:14 -0500
Subject: [PATCH v4 1/4] dt-bindings: interrupt-controller: Convert MSI
 controller to json-schema
In-Reply-To: <20210827171534.62380-2-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-2-mark.kettenis@xs4all.nl>
Message-ID: <YS6X5kXw18/RBLLP@robh.at.kernel.org>

On Fri, Aug 27, 2021 at 07:15:26PM +0200, Mark Kettenis wrote:
> From: Mark Kettenis <kettenis at openbsd.org>
> 
> Split the MSI controller bindings from the MSI binding document
> into DT schema format using json-schema.
> 
> Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> ---
>  .../interrupt-controller/msi-controller.yaml  | 34 +++++++++++++++++++
>  .../bindings/pci/brcm,stb-pcie.yaml           |  1 +
>  .../bindings/pci/microchip,pcie-host.yaml     |  1 +
>  3 files changed, 36 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> new file mode 100644
> index 000000000000..5ed6cd46e2e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> @@ -0,0 +1,34 @@
> +# SPDX-License-Identifier: BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/msi-controller.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MSI controller
> +
> +maintainers:
> +  - Marc Zyngier <marc.zyngier at arm.com>

Not the current email for Marc.

> +
> +description: |
> +  An MSI controller signals interrupts to a CPU when a write is made
> +  to an MMIO address by some master. An MSI controller may feature a
> +  number of doorbells.
> +
> +properties:
> +  "#msi-cells":
> +    description: |
> +      The number of cells in an msi-specifier, required if not zero.
> +
> +      Typically this will encode information related to sideband data,
> +      and will not encode doorbells or payloads as these can be
> +      configured dynamically.
> +
> +      The meaning of the msi-specifier is defined by the device tree
> +      binding of the specific MSI controller.
> +
> +  msi-controller:
> +    description:
> +      Identifies the node as an MSI controller.
> +    $ref: /schemas/types.yaml#/definitions/flag
> +
> +additionalProperties: true
> diff --git a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> index b9589a0daa5c..5c67976a8dc2 100644
> --- a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
> @@ -88,6 +88,7 @@ required:
>  
>  allOf:
>    - $ref: /schemas/pci/pci-bus.yaml#
> +  - $ref: ../interrupt-controller/msi-controller.yaml#
>    - if:
>        properties:
>          compatible:
> diff --git a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> index fb95c276a986..684d9d036f48 100644
> --- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> +++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
> @@ -11,6 +11,7 @@ maintainers:
>  
>  allOf:
>    - $ref: /schemas/pci/pci-bus.yaml#
> +  - $ref: ../interrupt-controller/msi-controller.yaml#
>  
>  properties:
>    compatible:
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Tue Aug 31 14:04:05 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 16:04:05 -0500
Subject: [PATCH v4 1/4] dt-bindings: interrupt-controller: Convert MSI
 controller to json-schema
In-Reply-To: <561420d562d3e421@bloch.sibelius.xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-2-mark.kettenis@xs4all.nl>
 <561420d562d3e421@bloch.sibelius.xs4all.nl>
Message-ID: <YS6ZRSDjRQBt8LbG@robh.at.kernel.org>

On Fri, Aug 27, 2021 at 09:15:11PM +0200, Mark Kettenis wrote:
> > From: Mark Kettenis <mark.kettenis at xs4all.nl>
> > Date: Fri, 27 Aug 2021 19:15:26 +0200
> > 
> > From: Mark Kettenis <kettenis at openbsd.org>
> > 
> > Split the MSI controller bindings from the MSI binding document
> > into DT schema format using json-schema.
> > 
> > Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> > ---
> >  .../interrupt-controller/msi-controller.yaml  | 34 +++++++++++++++++++
> >  .../bindings/pci/brcm,stb-pcie.yaml           |  1 +
> >  .../bindings/pci/microchip,pcie-host.yaml     |  1 +
> >  3 files changed, 36 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> > new file mode 100644
> > index 000000000000..5ed6cd46e2e0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> > @@ -0,0 +1,34 @@
> > +# SPDX-License-Identifier: BSD-2-Clause
> 
> Noticed that checkpatch complains that the preferred license for new
> binding schemas is (GPL-2.0-only OR BSD-2-Clause) so I'll fix that in
> the next version.

Yes, but the text you copied is default GPL-2.0, so you need the author's 
permission to add BSD license. However, as Mark Rutland wrote all of 
msi.txt for Arm Ltd, I can tell you dual licensing this is fine. Maybe 
it's so little to fall under fair use anyways, but IANAL.

Rob


From robh at kernel.org  Tue Aug 31 14:16:02 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 16:16:02 -0500
Subject: [PATCH v4 2/4] dt-bindings: interrupt-controller: msi: Add
 msi-ranges property
In-Reply-To: <20210827171534.62380-3-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-3-mark.kettenis@xs4all.nl>
Message-ID: <YS6cEkDn5IAVW/xQ@robh.at.kernel.org>

On Fri, Aug 27, 2021 at 07:15:27PM +0200, Mark Kettenis wrote:
> From: Mark Kettenis <kettenis at openbsd.org>
> 
> Update the MSI controller binding to add an msi-ranges property
> that specifies how MSIs map onto regular interrupts on some other
> interrupt controller.
> 
> Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> ---
>  .../bindings/interrupt-controller/msi-controller.yaml     | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> index 5ed6cd46e2e0..bf8b8a7dba09 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> +++ b/Documentation/devicetree/bindings/interrupt-controller/msi-controller.yaml
> @@ -31,4 +31,12 @@ properties:
>        Identifies the node as an MSI controller.
>      $ref: /schemas/types.yaml#/definitions/flag
>  
> +  msi-ranges:
> +    description:
> +      A list of pairs <intid span>, where "intid" is the specification

It's not really 'pairs' and 'interrupt specifier' is the terminology the 
spec uses. How about:

A list of <phandle intspec span>, where "phandle" is parent interrupt 
controller, "intspec" is the starting/base interrupt specifier, and 
"span" is the size of that range (typically multiples of 32).

The 'multiples of 32' part is what Marc told me.

> +      of the first interrupt (including the phandle for the interrupt
> +      controller) that can be used as an MSI, and "span" the size of
> +      that range. Multiple ranges can be provided.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +
>  additionalProperties: true
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Tue Aug 31 14:21:28 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 16:21:28 -0500
Subject: [PATCH v4 3/4] dt-bindings: pci: Add DT bindings for apple,pcie
In-Reply-To: <20210827171534.62380-4-mark.kettenis@xs4all.nl>
References: <20210827171534.62380-1-mark.kettenis@xs4all.nl>
 <20210827171534.62380-4-mark.kettenis@xs4all.nl>
Message-ID: <YS6dWI4wwg7XkuNA@robh.at.kernel.org>

On Fri, Aug 27, 2021 at 07:15:28PM +0200, Mark Kettenis wrote:
> From: Mark Kettenis <kettenis at openbsd.org>
> 
> The Apple PCIe host controller is a PCIe host controller with
> multiple root ports present in Apple ARM SoC platforms, including
> various iPhone and iPad devices and the "Apple Silicon" Macs.
> 
> Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> ---
>  .../devicetree/bindings/pci/apple,pcie.yaml   | 165 ++++++++++++++++++
>  MAINTAINERS                                   |   1 +
>  2 files changed, 166 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/apple,pcie.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pci/apple,pcie.yaml b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> new file mode 100644
> index 000000000000..97a126db935a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/apple,pcie.yaml
> @@ -0,0 +1,165 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/apple,pcie.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Apple PCIe host controller
> +
> +maintainers:
> +  - Mark Kettenis <kettenis at openbsd.org>
> +
> +description: |
> +  The Apple PCIe host controller is a PCIe host controller with
> +  multiple root ports present in Apple ARM SoC platforms, including
> +  various iPhone and iPad devices and the "Apple Silicon" Macs.
> +  The controller incorporates Synopsys DesigWare PCIe logic to
> +  implements its root ports.  But the ATU found on most DesignWare
> +  PCIe host bridges is absent.
> +
> +  All root ports share a single ECAM space, but separate GPIOs are
> +  used to take the PCI devices on those ports out of reset.  Therefore
> +  the standard "reset-gpios" and "max-link-speed" properties appear on
> +  the child nodes that represent the PCI bridges that correspond to
> +  the individual root ports.
> +
> +  MSIs are handled by the PCIe controller and translated into regular
> +  interrupts.  A range of 32 MSIs is provided.  These 32 MSIs can be
> +  distributed over the root ports as the OS sees fit by programming
> +  the PCIe controller's port registers.
> +
> +allOf:
> +  - $ref: /schemas/pci/pci-bus.yaml#
> +  - $ref: ../interrupt-controller/msi-controller.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: apple,t8103-pcie
> +      - const: apple,pcie
> +
> +  reg:
> +    minItems: 3
> +    maxItems: 5
> +
> +  reg-names:
> +    minItems: 3
> +    maxItems: 5
> +    items:
> +      - const: config
> +      - const: rc
> +      - const: port0
> +      - const: port1
> +      - const: port2
> +
> +  ranges:
> +    minItems: 2
> +    maxItems: 2
> +
> +  interrupts:
> +    description:
> +      Interrupt specifiers, one for each root port.
> +    minItems: 1
> +    maxItems: 3
> +
> +  msi-parent: true

I still think this should be dropped as it is meaningless with 
'msi-controller' present.

> +
> +#  msi-ranges:
> +#    description:
> +#      A list of pairs <intid span>, where "intid" is the first
> +#      interrupt number that can be used as an MSI, and "span" the size
> +#      of that range.
> +#    $ref: /schemas/types.yaml#/definitions/phandle-array

Here, you'll want just 'maxItems: 1' as there's only 1 entry.

> +
> +  iommu-map: true
> +  iommu-map-mask: true
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - bus-range
> +  - interrupts
> +  - msi-controller
> +  - msi-parent
> +  - msi-ranges
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/apple-aic.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      pcie0: pcie at 690000000 {
> +        compatible = "apple,t8103-pcie", "apple,pcie";
> +        device_type = "pci";
> +
> +        reg = <0x6 0x90000000 0x0 0x1000000>,
> +              <0x6 0x80000000 0x0 0x4000>,
> +              <0x6 0x81000000 0x0 0x8000>,
> +              <0x6 0x82000000 0x0 0x8000>,
> +              <0x6 0x83000000 0x0 0x8000>;
> +        reg-names = "config", "rc", "port0", "port1", "port2";
> +
> +        interrupt-parent = <&aic>;
> +        interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>,
> +                     <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>,
> +                     <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        msi-controller;
> +        msi-parent = <&pcie0>;
> +        msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>;
> +
> +        iommu-map = <0x100 &dart0 1 1>,
> +                    <0x200 &dart1 1 1>,
> +                    <0x300 &dart2 1 1>;
> +        iommu-map-mask = <0xff00>;
> +
> +        bus-range = <0 3>;
> +        #address-cells = <3>;
> +        #size-cells = <2>;
> +        ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 0x0 0x20000000>,
> +                 <0x02000000 0x0 0xc0000000 0x6 0xc0000000 0x0 0x40000000>;
> +
> +        clocks = <&pcie_core_clk>, <&pcie_aux_clk>, <&pcie_ref_clk>;
> +        pinctrl-0 = <&pcie_pins>;
> +        pinctrl-names = "default";
> +
> +        pci at 0,0 {
> +          device_type = "pci";
> +          reg = <0x0 0x0 0x0 0x0 0x0>;
> +          reset-gpios = <&pinctrl_ap 152 0>;
> +          max-link-speed = <2>;
> +
> +          #address-cells = <3>;
> +          #size-cells = <2>;
> +          ranges;
> +        };
> +
> +        pci at 1,0 {
> +          device_type = "pci";
> +          reg = <0x800 0x0 0x0 0x0 0x0>;
> +          reset-gpios = <&pinctrl_ap 153 0>;
> +          max-link-speed = <2>;
> +
> +          #address-cells = <3>;
> +          #size-cells = <2>;
> +          ranges;
> +        };
> +
> +        pci at 2,0 {
> +          device_type = "pci";
> +          reg = <0x1000 0x0 0x0 0x0 0x0>;
> +          reset-gpios = <&pinctrl_ap 33 0>;
> +          max-link-speed = <1>;
> +
> +          #address-cells = <3>;
> +          #size-cells = <2>;
> +          ranges;
> +        };
> +      };
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c6b8a720c0bc..30bea4042e7e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1694,6 +1694,7 @@ C:	irc://chat.freenode.net/asahi-dev
>  T:	git https://github.com/AsahiLinux/linux.git
>  F:	Documentation/devicetree/bindings/arm/apple.yaml
>  F:	Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
> +F:	Documentation/devicetree/bindings/pci/apple,pcie.yaml
>  F:	Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
>  F:	arch/arm64/boot/dts/apple/
>  F:	drivers/irqchip/irq-apple-aic.c
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Tue Aug 31 14:23:00 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 16:23:00 -0500
Subject: [PATCH devicetree 1/2] dt-bindings: arm: fsl: document the
 LX2160A BlueBox 3 boards
In-Reply-To: <20210827202722.2567687-1-vladimir.oltean@nxp.com>
References: <20210827202722.2567687-1-vladimir.oltean@nxp.com>
Message-ID: <YS6dtKYnwle++wA6@robh.at.kernel.org>

On Fri, 27 Aug 2021 23:27:21 +0300, Vladimir Oltean wrote:
> Document the compatible string for the LX2160A system that is part of
> the BlueBox 3. Also add a separate compatible string for Rev A, since
> technically it uses a different device tree.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> ---
>  Documentation/devicetree/bindings/arm/fsl.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

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


From robh at kernel.org  Tue Aug 31 14:33:32 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 16:33:32 -0500
Subject: [PATCH 1/2] dt-bindings: phy: rockchip: remove usb-phy fallback
 string for rk3066a/rk3188
In-Reply-To: <20210828111218.10026-1-jbx6244@gmail.com>
References: <20210828111218.10026-1-jbx6244@gmail.com>
Message-ID: <YS6gLG+M4dP+rkl6@robh.at.kernel.org>

On Sat, 28 Aug 2021 13:12:17 +0200, Johan Jonker wrote:
> With the conversion of rockchip-usb-phy.yaml a long time used fallback
> string for rk3066a/rk3188 was added. The linux driver doesn't do much with
> the GRF phy address range, however the u-boot driver rockchip_usb2_phy.c
> does. The bits in GRF_UOC0_CON2 for rk3066a/rk3188 and rk3288 for example
> don't match. Remove the usb-phy fallback string for rk3066a/rk3188
> to prevent possible strange side effects.
> 
> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
> ---
>  .../devicetree/bindings/phy/rockchip-usb-phy.yaml     | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 

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


From robh at kernel.org  Tue Aug 31 14:33:44 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 16:33:44 -0500
Subject: [PATCH] dt-bindings: gpio: add gpio-line-names to
 rockchip,gpio-bank.yaml
In-Reply-To: <20210828121007.14865-1-jbx6244@gmail.com>
References: <20210828121007.14865-1-jbx6244@gmail.com>
Message-ID: <YS6gOGhoQKNlg5cL@robh.at.kernel.org>

On Sat, 28 Aug 2021 14:10:07 +0200, Johan Jonker wrote:
> Some people and companies may want to add more description
> to there gpio pins. Add a gpio-line-names property to the
> rockchip,gpio-bank.yaml file to reduce the notifications
> from the existing mainline DT.
> 
> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
> ---
>  Documentation/devicetree/bindings/gpio/rockchip,gpio-bank.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

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


From robh at kernel.org  Tue Aug 31 14:50:22 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 16:50:22 -0500
Subject: [PATCH v3 2/4] dt-bindings: sound: add rockchip i2s-tdm binding
In-Reply-To: <20210828140205.21973-3-frattaroli.nicolas@gmail.com>
References: <20210828140205.21973-1-frattaroli.nicolas@gmail.com>
 <20210828140205.21973-3-frattaroli.nicolas@gmail.com>
Message-ID: <YS6kHkeOKCJMOOIf@robh.at.kernel.org>

On Sat, Aug 28, 2021 at 04:02:02PM +0200, Nicolas Frattaroli wrote:
> This adds the YAML bindings for the Rockchip I2S/TDM audio driver.
> 
> Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> ---
>  .../bindings/sound/rockchip,i2s-tdm.yaml      | 218 ++++++++++++++++++
>  MAINTAINERS                                   |   1 +
>  2 files changed, 219 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> 
> diff --git a/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> new file mode 100644
> index 000000000000..ab8731779805
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
> @@ -0,0 +1,218 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip I2S/TDM Controller
> +
> +description:
> +  The Rockchip I2S/TDM Controller is a Time Division Multiplexed
> +  audio interface found in various Rockchip SoCs, allowing up
> +  to 8 channels of audio over a serial interface.
> +
> +maintainers:
> +  - Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - rockchip,px30-i2s-tdm
> +      - rockchip,rk1808-i2s-tdm
> +      - rockchip,rk3308-i2s-tdm
> +      - rockchip,rk3568-i2s-tdm
> +      - rockchip,rv1126-i2s-tdm
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  dmas:
> +    minItems: 1
> +    maxItems: 2
> +
> +  dma-names:
> +    minItems: 1
> +    maxItems: 2
> +    items:
> +      enum:
> +        - rx
> +        - tx
> +
> +  clocks:
> +    minItems: 3
> +    items:
> +      - description: clock for TX
> +      - description: clock for RX
> +      - description: AHB clock driving the interface
> +      - description:
> +          Parent clock for mclk_tx (only required when using mclk-calibrate)
> +      - description:
> +          Parent clock for mclk_rx (only required when using mclk-calibrate)
> +      - description:
> +          Clock for sample rates that are an integer multiple of 8000
> +          (only required when using mclk-calibrate)
> +      - description:
> +          Clock for sample rates that are an integer multiple of 11025
> +          (only required when using mclk-calibrate)
> +
> +  clock-names:
> +    minItems: 3
> +    items:
> +      - const: mclk_tx
> +      - const: mclk_rx
> +      - const: hclk
> +      - const: mclk_tx_src
> +      - const: mclk_rx_src
> +      - const: mclk_root0
> +      - const: mclk_root1
> +
> +  rockchip,frame-width:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 64
> +    minimum: 32
> +    maximum: 512
> +    description:
> +      Width of a frame, usually slot width multiplied by number of slots.
> +      Must be even.
> +
> +  resets:
> +    items:
> +      - description: reset for TX
> +      - description: reset for RX
> +
> +  reset-names:
> +    items:
> +      - const: tx-m
> +      - const: rx-m
> +
> +  rockchip,cru:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the cru.
> +      Required if neither trcm-sync-tx-only nor trcm-sync-rx-only are specified.
> +
> +  rockchip,grf:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      The phandle of the syscon node for the GRF register.
> +
> +  rockchip,mclk-calibrate:
> +    description:
> +      Switch between two root clocks depending on the audio sample rate.
> +      For integer multiples of 8000 (e.g. 48000 Hz), mclk_root0 is used.
> +      For integer multiples of 11025 (e.g. 44100 Hz), mclk_root1 is used.
> +    type: boolean
> +
> +  rockchip,trcm-sync-tx-only:
> +    type: boolean
> +    description: Use TX BCLK/LRCK for both TX and RX.
> +
> +  rockchip,trcm-sync-rx-only:
> +    type: boolean
> +    description: Use RX BCLK/LRCK for both TX and RX.
> +
> +  "#sound-dai-cells":
> +    const: 0
> +
> +  rockchip,i2s-rx-route:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      Defines the mapping of I2S RX sdis to I2S data bus lines.
> +      By default, they are mapped one-to-one.
> +    items:
> +      - description: which sdi to connect to data line 0
> +      - description: which sdi to connect to data line 1
> +      - description: which sdi to connect to data line 2
> +      - description: which sdi to connect to data line 3

This would be better expressed as:

maxItems: 4
items:
  enum: [ 0, 1, 2, 3 ]

(I'm guessing on the allowed values here)

> +
> +  rockchip,i2s-tx-route:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    description:
> +      Defines the mapping of I2S TX sdos to I2S data bus lines.
> +      By default, they are mapped one-to-one.
> +    items:
> +      - description: which sdo to connect to data line 0
> +      - description: which sdo to connect to data line 1
> +      - description: which sdo to connect to data line 2
> +      - description: which sdo to connect to data line 3

Same here.

> +
> +  rockchip,tdm-fsync-half-frame:
> +    description: Whether to use half frame fsync.
> +    type: boolean
> +
> +  rockchip,io-multiplex:
> +    description:
> +      Specify that the GPIO lines on the I2S bus are multiplexed such that
> +      the direction (input/output) needs to be dynamically adjusted.
> +    type: boolean
> +
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - dmas
> +  - dma-names
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - rockchip,grf
> +  - "#sound-dai-cells"
> +
> +allOf:
> +  - if:
> +      properties:
> +        rockchip,trcm-sync-tx-only: false
> +        rockchip,trcm-sync-rx-only: false
> +    then:
> +      required:
> +        - rockchip,cru
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/rk3568-cru.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/pinctrl/rockchip.h>
> +
> +    foo {

bus {

> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +        i2s at fe410000 {
> +            compatible = "rockchip,rk3568-i2s-tdm";
> +            reg = <0x0 0xfe410000 0x0 0x1000>;
> +            interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
> +            clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
> +                     <&cru HCLK_I2S1_8CH>;
> +            clock-names = "mclk_tx", "mclk_rx", "hclk";
> +            dmas = <&dmac1 3>, <&dmac1 2>;
> +            dma-names = "rx", "tx";
> +            resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
> +            reset-names = "tx-m", "rx-m";
> +            rockchip,trcm-sync-tx-only;
> +            rockchip,cru = <&cru>;
> +            rockchip,grf = <&grf>;
> +            #sound-dai-cells = <0>;
> +            pinctrl-names = "default";
> +            pinctrl-0 =
> +                <&i2s1m0_sclktx
> +                &i2s1m0_sclkrx
> +                &i2s1m0_lrcktx
> +                &i2s1m0_lrckrx
> +                &i2s1m0_sdi0
> +                &i2s1m0_sdi1
> +                &i2s1m0_sdi2
> +                &i2s1m0_sdi3
> +                &i2s1m0_sdo0
> +                &i2s1m0_sdo1
> +                &i2s1m0_sdo2
> +                &i2s1m0_sdo3>;
> +            status = "okay";

Still needs to be dropped.

> +        };
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5d459d42672c..d2be16a85009 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16053,6 +16053,7 @@ ROCKCHIP I2S TDM DRIVER
>  M:	Nicolas Frattaroli <frattaroli.nicolas at gmail.com>
>  L:	linux-rockchip at lists.infradead.org
>  S:	Maintained
> +F:	Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
>  F:	sound/soc/rockchip/rockchip_i2s_tdm.*
>  
>  ROCKCHIP ISP V1 DRIVER
> -- 
> 2.33.0
> 
> 


From robh at kernel.org  Tue Aug 31 15:09:35 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 17:09:35 -0500
Subject: [PATCH v11 1/4] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <20210830003603.31864-2-zhiyong.tao@mediatek.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
 <20210830003603.31864-2-zhiyong.tao@mediatek.com>
Message-ID: <YS6onwnr4Lo8VPDA@robh.at.kernel.org>

On Mon, 30 Aug 2021 08:36:00 +0800, Zhiyong Tao wrote:
> This patch adds rsel define for mt8195.
> 
> Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
> ---
>  include/dt-bindings/pinctrl/mt65xx.h | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 

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


From robh at kernel.org  Tue Aug 31 15:13:00 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 17:13:00 -0500
Subject: [PATCH v11 2/4] dt-bindings: pinctrl: mt8195: change pull
 up/down description
In-Reply-To: <20210830003603.31864-3-zhiyong.tao@mediatek.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
 <20210830003603.31864-3-zhiyong.tao@mediatek.com>
Message-ID: <YS6pbO4hmNyX//tP@robh.at.kernel.org>

On Mon, Aug 30, 2021 at 08:36:01AM +0800, Zhiyong Tao wrote:
> Change pull up/down description

Every commit is a 'change'. Your commit msg should explain 'why', not 
what the diff is.

> 
> Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
> ---
>  .../bindings/pinctrl/pinctrl-mt8195.yaml      | 32 +++++++++++++++++--
>  1 file changed, 29 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> index 2f12ec59eee5..a341ed9f0095 100644
> --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> @@ -85,9 +85,35 @@ patternProperties:
>            2/4/6/8/10/12/14/16mA in mt8195.
>          enum: [0, 1, 2, 3, 4, 5, 6, 7]
>  
> -      bias-pull-down: true
> -
> -      bias-pull-up: true
> +      bias-pull-down:
> +        description: |
> +          For pull down type is normal, it don't need add RSEL & R1R0 define
> +          and resistance value.
> +          For pull down type is PUPD/R0/R1 type, it can add R1R0 define to
> +          set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
> +          "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11"
> +          define in mt8195.
> +          For pull down type is RSEL, it can add RSEL define & resistance value(ohm)
> +          to set different resistance. It can support "MTK_PULL_SET_RSEL_000" &
> +          "MTK_PULL_SET_RSEL_001" & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" &
> +          "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" &
> +          "MTK_PULL_SET_RSEL_111" define in mt8195. It can also support resistance value(ohm)
> +          "75000" & "5000" in mt8195.

Sounds like constraints on the values. Please write a schema.

> +
> +      bias-pull-up:
> +        description: |
> +          For pull up type is normal, it don't need add RSEL & R1R0 define
> +          and resistance value.
> +          For pull up type is PUPD/R0/R1 type, it can add R1R0 define to
> +          set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
> +          "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11"
> +          define in mt8195.
> +          For pull up type is RSEL, it can add RSEL define & resistance value(ohm)
> +          to set different resistance. It can support "MTK_PULL_SET_RSEL_000" &
> +          "MTK_PULL_SET_RSEL_001" & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" &
> +          "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" &
> +          "MTK_PULL_SET_RSEL_111" define in mt8195. It can also support resistance value(ohm)
> +          "1000" & "1500" & "2000" & "3000" & "4000" & "5000" & "10000" & "75000" in mt8195.
>  
>        bias-disable: true
>  
> -- 
> 2.18.0
> 
> 


From zhouzhouyi at gmail.com  Tue Aug 31 18:03:32 2021
From: zhouzhouyi at gmail.com (Zhouyi Zhou)
Date: Wed, 1 Sep 2021 09:03:32 +0800
Subject: rcu_preempt detected stalls
In-Reply-To: <CAABZP2wUdToiAWOAgqDZrZtkuEdrXEv9GDgbioW3PZAyseOSgA@mail.gmail.com>
References: <20210831152144.GA28128@trex>
 <CAABZP2xGnSLVbgxqjKMq=Oj_H7rYfYjuCvmBpmZ4tRptGs3SEw@mail.gmail.com>
 <CAABZP2wUdToiAWOAgqDZrZtkuEdrXEv9GDgbioW3PZAyseOSgA@mail.gmail.com>
Message-ID: <CAABZP2zg8c_gkm4+h4-mPCv_uDf5-iJFHEExCDFoES0jmBeuKw@mail.gmail.com>

Hi,

I  perform following two new rounds of experiments:


Test environment (x86_64 debian10 virtual machine: kvm -cpu host -smp
8 -hda ./debian10.qcow2 -m 4096 -net
user,hostfwd=tcp::5556-:22,hostfwd=tcp::5555-:19 -net nic,model=e1000
-vnc :30)

1.   CONFIG_RCU_BOOST=y
1.1 as root, run #stress-ng --sequential 100  --class scheduler -t 5m --times
1.2 as regular user at the same time, run $stress-ng --sequential 100
--class scheduler -t 5m --times

System begin OOM kill after 6 minutes:
31 19:41:12 debian kernel: [  847.171884] task:kworker/1:0     state:D
stack:    0 pid: 1634 ppid:     2 flag\
s:0x00004000
Aug 31 19:41:12 debian kernel: [  847.171890] Workqueue: ipv6_addrconf
addrconf_verify_work
Aug 31 19:41:12 debian kernel: [  847.171897] Call Trace:
Aug 31 19:41:12 debian kernel: [  847.171903]  __schedule+0x368/0xa40
Aug 31 19:41:12 debian kernel: [  847.171915]  schedule+0x44/0xe0
Aug 31 19:41:12 debian kernel: [  847.171921]
schedule_preempt_disabled+0x14/0x20
Aug 31 19:41:12 debian kernel: [  847.171924]  __mutex_lock+0x4b1/0xa10
Aug 31 19:41:12 debian kernel: [  847.171935]  ? addrconf_verify_work+0xa/0x20
Aug 31 19:41:12 debian kernel: [  847.171948]  ? addrconf_verify_work+0xa/0x20
Aug 31 19:41:12 debian kernel: [  847.171951]  addrconf_verify_work+0xa/0x20
Aug 31 19:41:12 debian kernel: [  847.171955]  process_one_work+0x1fa/0x5b0
Aug 31 19:41:12 debian kernel: [  847.171967]  worker_thread+0x64/0x3d0
Aug 31 19:41:12 debian kernel: [  847.171974]  ? process_one_work+0x5b0/0x5b0
Aug 31 19:41:12 debian kernel: [  847.171978]  kthread+0x131/0x180
Aug 31 19:41:12 debian kernel: [  847.171982]  ? set_kthread_struct+0x40/0x40
Aug 31 19:41:12 debian kernel: [  847.171989]  ret_from_fork+0x1f/0x30
Aug 31 19:41:12 debian kernel: [  847.176007]
Aug 31 19:41:12 debian kernel: [  847.176007] Showing all locks held
in the system:
Aug 31 19:41:12 debian kernel: [  847.176016] 1 lock held by khungtaskd/56:
Aug 31 19:41:12 debian kernel: [  847.176018]  #0: ffffffff82918b60
(rcu_read_lock){....}-{1:2}, at: debug_show_a\
ll_locks+0xe/0x1a0

2.  # CONFIG_RCU_BOOST is not set
2.1 as root, run #stress-ng --sequential 100  --class scheduler -t 5m --times
2.2 as regular user at the same time, run $stress-ng --sequential 100
--class scheduler -t 5m --times
System begin OOM kill after 6 minutes:
The system is so dead, that I can't save the backtrace to file nor did
kernel has a chance to save the log to /var/log/messages

Thanks
Zhouyi

On Wed, Sep 1, 2021 at 1:11 AM Zhouyi Zhou <zhouzhouyi at gmail.com> wrote:
>
> followings are some of my kernel config options:
> CONFIG_PREEMPT=y
> CONFIG_PREEMPT_COUNT=y
> CONFIG_PREEMPTION=y
> CONFIG_PREEMPT_DYNAMIC=y
> CONFIG_PREEMPT_RCU=y
> CONFIG_HAVE_PREEMPT_DYNAMIC=y
> CONFIG_TREE_RCU=y
> CONFIG_PREEMPT_RCU=y
> CONFIG_RCU_EXPERT=y
> CONFIG_SRCU=y
> CONFIG_TREE_SRCU=y
> CONFIG_TASKS_RCU_GENERIC=y
> CONFIG_TASKS_RCU=y
> CONFIG_TASKS_RUDE_RCU=y
> CONFIG_TASKS_TRACE_RCU=y
> CONFIG_RCU_STALL_COMMON=y
> CONFIG_RCU_NEED_SEGCBLIST=y
> CONFIG_RCU_FANOUT=64
> CONFIG_RCU_FANOUT_LEAF=16
> # CONFIG_RCU_FAST_NO_HZ is not set
> # CONFIG_RCU_BOOST is not set
> CONFIG_RCU_NOCB_CPU=y
> # CONFIG_TASKS_TRACE_RCU_READ_MB is not set
> # end of RCU Subsystem
> CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
> CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
> # RCU Debugging
> CONFIG_PROVE_RCU=y
> # CONFIG_PROVE_RCU_LIST is not set
> # CONFIG_RCU_SCALE_TEST is not set
> CONFIG_RCU_TORTURE_TEST=m
> # CONFIG_RCU_REF_SCALE_TEST is not set
> CONFIG_RCU_CPU_STALL_TIMEOUT=21
> # CONFIG_RCU_TRACE is not set
> # CONFIG_RCU_EQS_DEBUG is not set
>
> Thanks
> Zhouyi
>
> On Wed, Sep 1, 2021 at 1:01 AM Zhouyi Zhou <zhouzhouyi at gmail.com> wrote:
> >
> > I did an experiment just now on x86_64 virtual machines, rcu did not
> > complain after 10 minutes's test, I hope my effort can provide some
> > clue.
> >
> > 1. I clone the fresh new linux kernel (git clone
> > https://kernel.source.codeaurora.cn/pub/scm/linux/kernel/git/torvalds/linux.git)
> > 2. compile the kernel without CONFIG_RCU_BOOST (: # CONFIG_RCU_BOOST is not set)
> > 3. boot the kernel on a x86_64 VM (kvm -cpu host -smp 16  -hda
> > ./debian10.qcow2 -m 4096 -net
> > user,hostfwd=tcp::5556-:22,hostfwd=tcp::5555-:19 -net nic,model=e1000
> > -vnc :30)
> > 4. run the test (stress-ng --sequential 16  --class scheduler -t 5m --times)
> > 5. monitor the system by constantly typing top and dmesg
> > 6. after 10 minutes, nothing else happens except that the dmesg report
> > following two messages
> > [  672.528192] sched: DL replenish lagged too much
> > [  751.127790] hrtimer: interrupt took 12143 ns
> >
> > So, I guess CONFIG_RCU_BOOST is not necessary for x86_64 virtual machines
> >
> > Zhouyi
> >
> > On Tue, Aug 31, 2021 at 11:24 PM Jorge Ramirez-Ortiz, Foundries
> > <jorge at foundries.io> wrote:
> > >
> > > Hi
> > >
> > > When enabling CONFIG_PREEMPT and running the stress-ng scheduler class
> > > tests on arm64 (xilinx zynqmp and imx imx8mm SoCs) we are observing the following.
> > >
> > > [   62.578917] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> > > [   62.585015]  (detected by 0, t=5253 jiffies, g=3017, q=2972)
> > > [   62.590663] rcu: All QSes seen, last rcu_preempt kthread activity 5254 (4294907943-4294902689), jiffies_till_next_fqs=1, root
> > > +->qsmask 0x0
> > > [   62.603086] rcu: rcu_preempt kthread starved for 5258 jiffies! g3017 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1
> > > [   62.613246] rcu:     Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
> > > [   62.622359] rcu: RCU grace-period kthread stack dump:
> > > [   62.627395] task:rcu_preempt     state:R  running task     stack:    0 pid:   14 ppid:     2 flags:0x00000028
> > > [   62.637308] Call trace:
> > > [   62.639748]  __switch_to+0x11c/0x190
> > > [   62.643319]  __schedule+0x3b8/0x8d8
> > > [   62.646796]  schedule+0x4c/0x108
> > > [   62.650018]  schedule_timeout+0x1ac/0x358
> > > [   62.654021]  rcu_gp_kthread+0x6a8/0x12b8
> > > [   62.657933]  kthread+0x14c/0x158
> > > [   62.661153]  ret_from_fork+0x10/0x18
> > > [   62.682919] BUG: scheduling while atomic: stress-ng-hrtim/831/0x00000002
> > > [   62.689604] Preemption disabled at:
> > > [   62.689614] [<ffffffc010059418>] irq_enter_rcu+0x30/0x58
> > > [   62.698393] CPU: 0 PID: 831 Comm: stress-ng-hrtim Not tainted 5.10.42+ #5
> > > [   62.706296] Hardware name: Zynqmp new (DT)
> > > [   62.710115] Call trace:
> > > [   62.712548]  dump_backtrace+0x0/0x240
> > > [   62.716202]  show_stack+0x2c/0x38
> > > [   62.719510]  dump_stack+0xcc/0x104
> > > [   62.722904]  __schedule_bug+0x78/0xc8
> > > [   62.726556]  __schedule+0x70c/0x8d8
> > > [   62.730037]  schedule+0x4c/0x108
> > > [   62.733259]  do_notify_resume+0x224/0x5d8
> > > [   62.737259]  work_pending+0xc/0x2a4
> > >
> > > The error results in OOM eventually.
> > >
> > > RCU priority boosting does work around this issue but it seems to me
> > > a workaround more than a fix (otherwise boosting would be enabled
> > > by CONFIG_PREEMPT for arm64 I guess?).
> > >
> > > The question is: is this an arm64 bug that should be investigated? or
> > > is this some known corner case of running stress-ng that is already
> > > understood?
> > >
> > > thanks
> > > Jorge
> > >
> > >
> > >


From robh at kernel.org  Tue Aug 31 18:37:45 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 20:37:45 -0500
Subject: [PATCH v3 1/4] dt-bindings: usb: dwc3: add reference clock period
In-Reply-To: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
References: <f5ea5bc3664a98a684ad4b699a1ac610e847176f.1630389452.git.baruch@tkos.co.il>
Message-ID: <YS7ZafoBpPC/+j2k@robh.at.kernel.org>

On Tue, 31 Aug 2021 08:57:29 +0300, Baruch Siach wrote:
> Document the snps,ref-clock-period-ns property that describes reference
> clock period when it deviates from the default set value.
> 
> Signed-off-by: Baruch Siach <baruch at tkos.co.il>
> ---
> v2:
> 
> Address comments from Rob Herring:
> 
>   Use standard unit suffix
> 
>   Reword description
> ---
>  Documentation/devicetree/bindings/usb/snps,dwc3.yaml | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Aug 31 18:38:36 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 20:38:36 -0500
Subject: [v5 02/15] dt-bindings: iio: adc: Add ast2600-adc bindings
In-Reply-To: <20210831071458.2334-3-billy_tsai@aspeedtech.com>
References: <20210831071458.2334-1-billy_tsai@aspeedtech.com>
 <20210831071458.2334-3-billy_tsai@aspeedtech.com>
Message-ID: <YS7ZnG05pZvfA/7m@robh.at.kernel.org>

On Tue, 31 Aug 2021 15:14:45 +0800, Billy Tsai wrote:
> Add device tree bindings document for the aspeed ast2600 adc device
> driver.
> 
> Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
> ---
>  .../bindings/iio/adc/aspeed,ast2600-adc.yaml  | 100 ++++++++++++++++++
>  1 file changed, 100 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Aug 31 18:45:47 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 31 Aug 2021 20:45:47 -0500
Subject: [PATCH] dt-bindings: clock: samsung: fix header path in example
In-Reply-To: <20210831130643.83249-1-krzysztof.kozlowski@canonical.com>
References: <20210831130643.83249-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YS7bS7YzI+UKHUtA@robh.at.kernel.org>

On Tue, 31 Aug 2021 15:06:43 +0200, Krzysztof Kozlowski wrote:
> The proper header is exynos4.h:
> 
>     samsung,exynos4412-isp-clock.example.dts:19:18: fatal error: dt-bindings/clock/exynos4412.h: No such file or directory
> 
> Fixes: 7ac615780926 ("dt-bindings: clock: samsung: convert Exynos4 to dtschema")
> Reported-by: Stephen Boyd <sboyd at kernel.org>
> Reported-by: Rob Herring <robh+dt at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> 
> ---
> 
> The SHA in fixes tag is from linux-next. Might not be stable.
> ---
>  .../devicetree/bindings/clock/samsung,exynos4412-isp-clock.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

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


From zhiyong.tao at mediatek.com  Tue Aug 31 19:00:36 2021
From: zhiyong.tao at mediatek.com (zhiyong.tao)
Date: Wed, 1 Sep 2021 10:00:36 +0800
Subject: [PATCH v11 2/4] dt-bindings: pinctrl: mt8195: change pull
 up/down description
In-Reply-To: <YS6pbO4hmNyX//tP@robh.at.kernel.org>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
 <20210830003603.31864-3-zhiyong.tao@mediatek.com>
 <YS6pbO4hmNyX//tP@robh.at.kernel.org>
Message-ID: <1630461636.21764.1.camel@mhfsdcap03>

On Tue, 2021-08-31 at 17:13 -0500, Rob Herring wrote:
> On Mon, Aug 30, 2021 at 08:36:01AM +0800, Zhiyong Tao wrote:
> > Change pull up/down description
> 
> Every commit is a 'change'. Your commit msg should explain 'why', not 
> what the diff is.
> 
Hi robh,
we will add 'why' explanation in the commit msg in v12.


> > 
> > Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
> > ---
> >  .../bindings/pinctrl/pinctrl-mt8195.yaml      | 32 +++++++++++++++++--
> >  1 file changed, 29 insertions(+), 3 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> > index 2f12ec59eee5..a341ed9f0095 100644
> > --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> > @@ -85,9 +85,35 @@ patternProperties:
> >            2/4/6/8/10/12/14/16mA in mt8195.
> >          enum: [0, 1, 2, 3, 4, 5, 6, 7]
> >  
> > -      bias-pull-down: true
> > -
> > -      bias-pull-up: true
> > +      bias-pull-down:
> > +        description: |
> > +          For pull down type is normal, it don't need add RSEL & R1R0 define
> > +          and resistance value.
> > +          For pull down type is PUPD/R0/R1 type, it can add R1R0 define to
> > +          set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
> > +          "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11"
> > +          define in mt8195.
> > +          For pull down type is RSEL, it can add RSEL define & resistance value(ohm)
> > +          to set different resistance. It can support "MTK_PULL_SET_RSEL_000" &
> > +          "MTK_PULL_SET_RSEL_001" & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" &
> > +          "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" &
> > +          "MTK_PULL_SET_RSEL_111" define in mt8195. It can also support resistance value(ohm)
> > +          "75000" & "5000" in mt8195.
> 
> Sounds like constraints on the values. Please write a schema.
> 
we will add a schema here in v12.

Thanks
> > +
> > +      bias-pull-up:
> > +        description: |
> > +          For pull up type is normal, it don't need add RSEL & R1R0 define
> > +          and resistance value.
> > +          For pull up type is PUPD/R0/R1 type, it can add R1R0 define to
> > +          set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
> > +          "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" & "MTK_PUPD_SET_R1R0_11"
> > +          define in mt8195.
> > +          For pull up type is RSEL, it can add RSEL define & resistance value(ohm)
> > +          to set different resistance. It can support "MTK_PULL_SET_RSEL_000" &
> > +          "MTK_PULL_SET_RSEL_001" & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011" &
> > +          "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101" & "MTK_PULL_SET_RSEL_110" &
> > +          "MTK_PULL_SET_RSEL_111" define in mt8195. It can also support resistance value(ohm)
> > +          "1000" & "1500" & "2000" & "3000" & "4000" & "5000" & "10000" & "75000" in mt8195.
> >  
> >        bias-disable: true
> >  
> > -- 
> > 2.18.0
> > 
> > 


From chanho61.park at samsung.com  Tue Aug 31 19:07:10 2021
From: chanho61.park at samsung.com (Chanho Park)
Date: Wed, 1 Sep 2021 11:07:10 +0900
Subject: [PATCH v11] dt-bindings: ufs: Add bindings for Samsung ufs host
In-Reply-To: <CAGOxZ51qW52r=BzAc9K_NO3fQcRT3DXG-wVyO9-GvACyYgvQwA@mail.gmail.com>
References: <CGME20210803032734epcas5p2143008ddb212fe53fcd28b813c85c9d8@epcas5p2.samsung.com>
 <20210803032539.15676-1-alim.akhtar@samsung.com>
 <CAGOxZ53emv4H4UqT2L7tDtTXRgDrtrqti=FtfkNWo2M3rTnZMw@mail.gmail.com>
 <CAGOxZ51qW52r=BzAc9K_NO3fQcRT3DXG-wVyO9-GvACyYgvQwA@mail.gmail.com>
Message-ID: <001201d79ed6$12e5a9b0$38b0fd10$@samsung.com>

Hi Rob,

Could you kindly review this?

Best Regards,
Chanho Park

> -----Original Message-----
> From: Alim Akhtar <alim.akhtar at gmail.com>
> Sent: Friday, August 20, 2021 1:19 AM
> To: Alim Akhtar <alim.akhtar at samsung.com>
> Cc: open list <linux-kernel at vger.kernel.org>; linux-arm-
> kernel at lists.infradead.org; robh+dt <robh+dt at kernel.org>; Krzysztof
> Kozlowski <krzysztof.kozlowski at canonical.com>; linux-samsung-
> soc at vger.kernel.org; Martin K. Petersen <martin.petersen at oracle.com>
> Subject: Re: [PATCH v11] dt-bindings: ufs: Add bindings for Samsung ufs
> host
> 
> Hi Rob
> Can you pick up this patch via your tree? or you want Martin to pick it up?
> 
> On Sat, Aug 14, 2021 at 10:25 PM Alim Akhtar <alim.akhtar at gmail.com> wrote:
> >
> > Ping!!
> >
> > On Wed, Aug 4, 2021 at 9:01 AM Alim Akhtar <alim.akhtar at samsung.com>
> wrote:
> > >
> > > This patch adds DT bindings for Samsung ufs hci
> > >
> > > Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> > > ---
> > > Changes since v10
> > > * Rebased on v5.14-rc2
> > > * removed Rob Herring earlier Reviewed-by tag
> > >
> > > This patch was part of exynos ufs driver series, somehow this got
> > > missed to applied on the tree, sending again as a new patch v11,
> > > removing Rob's earlier Reviewed-by tag.
> > >
> > >  .../bindings/ufs/samsung,exynos-ufs.yaml      | 89 +++++++++++++++++++
> > >  1 file changed, 89 insertions(+)
> > >  create mode 100644
> > > Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> > >
> > > diff --git
> > > a/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> > > b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> > > new file mode 100644
> > > index 000000000000..38193975c9f1
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/ufs/samsung,exynos-ufs.yaml
> > > @@ -0,0 +1,89 @@
> > > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause %YAML 1.2
> > > +---
> > > +$id:
> > > +https://protect2.fireeye.com/v1/url?k=87b3fb9f-d828c295-87b270d0-0c
> > > +c47a31384a-2d1da91e6c1569ad&q=1&e=3ebd4447-410b-4abb-b6e0-88b0310be
> > > +d3f&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Fufs%2Fsamsung%2Cexyno
> > > +s-ufs.yaml%23
> > > +$schema:
> > > +https://protect2.fireeye.com/v1/url?k=15695c41-4af2654b-1568d70e-0c
> > > +c47a31384a-797602fbe8e5ab79&q=1&e=3ebd4447-410b-4abb-b6e0-88b0310be
> > > +d3f&u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
> > > +
> > > +title: Samsung SoC series UFS host controller Device Tree Bindings
> > > +
> > > +maintainers:
> > > +  - Alim Akhtar <alim.akhtar at samsung.com>
> > > +
> > > +description: |
> > > +  Each Samsung UFS host controller instance should have its own node.
> > > +  This binding define Samsung specific binding other then what is
> > > +used
> > > +  in the common ufshcd bindings
> > > +  [1] Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
> > > +
> > > +properties:
> > > +
> > > +  compatible:
> > > +    enum:
> > > +      - samsung,exynos7-ufs
> > > +
> > > +  reg:
> > > +    items:
> > > +     - description: HCI register
> > > +     - description: vendor specific register
> > > +     - description: unipro register
> > > +     - description: UFS protector register
> > > +
> > > +  reg-names:
> > > +    items:
> > > +      - const: hci
> > > +      - const: vs_hci
> > > +      - const: unipro
> > > +      - const: ufsp
> > > +
> > > +  clocks:
> > > +    items:
> > > +      - description: ufs link core clock
> > > +      - description: unipro main clock
> > > +
> > > +  clock-names:
> > > +    items:
> > > +      - const: core_clk
> > > +      - const: sclk_unipro_main
> > > +
> > > +  interrupts:
> > > +    maxItems: 1
> > > +
> > > +  phys:
> > > +    maxItems: 1
> > > +
> > > +  phy-names:
> > > +    const: ufs-phy
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - interrupts
> > > +  - phys
> > > +  - phy-names
> > > +  - clocks
> > > +  - clock-names
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > > +    #include <dt-bindings/clock/exynos7-clk.h>
> > > +
> > > +    ufs: ufs at 15570000 {
> > > +       compatible = "samsung,exynos7-ufs";
> > > +       reg = <0x15570000 0x100>,
> > > +             <0x15570100 0x100>,
> > > +             <0x15571000 0x200>,
> > > +             <0x15572000 0x300>;
> > > +       reg-names = "hci", "vs_hci", "unipro", "ufsp";
> > > +       interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
> > > +       clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
> > > +                <&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
> > > +       clock-names = "core_clk", "sclk_unipro_main";
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> > > +       phys = <&ufs_phy>;
> > > +       phy-names = "ufs-phy";
> > > +    };
> > > +...
> > >
> > > base-commit: 2734d6c1b1a089fb593ef6a23d4b70903526fe0c
> > > --
> > > 2.17.1
> > >
> >
> >
> > --
> > Regards,
> > Alim
> 
> 
> 
> --
> Regards,
> Alim



From wens at csie.org  Tue Aug 31 20:13:01 2021
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 1 Sep 2021 11:13:01 +0800
Subject: [PATCH] drm/sun4i: Fix macros in sun8i_csc.h
In-Reply-To: <20210831184819.93670-1-jernej.skrabec@gmail.com>
References: <20210831184819.93670-1-jernej.skrabec@gmail.com>
Message-ID: <CAGb2v67TNrkeP438t3nLcquFvGTfS+F0MvBmGAS=qmZ5JZFmag@mail.gmail.com>

On Wed, Sep 1, 2021 at 2:48 AM Jernej Skrabec <jernej.skrabec at gmail.com> wrote:
>
> Macros SUN8I_CSC_CTRL() and SUN8I_CSC_COEFF() don't follow usual
> recommendation of having arguments enclosed in parenthesis. While that
> didn't change anything for quiet sometime, it actually become important

                             ^ Typo

> after CSC code rework with commit ea067aee45a8 ("drm/sun4i: de2/de3:
> Remove redundant CSC matrices").
>
> Without this fix, colours are completely off for supported YVU formats
> on SoCs with DE2 (A64, H3, R40, etc.).
>
> Fix the issue by enclosing macro arguments in parenthesis.
>
> Cc: stable at vger.kernel.org # 5.12+
> Fixes: 883029390550 ("drm/sun4i: Add DE2 CSC library")
> Reported-by: Roman Stratiienko <r.stratiienko at gmail.com>
> Signed-off-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Otherwise,

Reviewed-by: Chen-Yu Tsai <wens at csie.org>


From chiawei_wang at aspeedtech.com  Tue Aug 31 20:30:13 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Wed, 1 Sep 2021 11:30:13 +0800
Subject: [PATCH v4 2/4] MAINTAINER: Add ASPEED eSPI driver entry
In-Reply-To: <20210901033015.910-1-chiawei_wang@aspeedtech.com>
References: <20210901033015.910-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210901033015.910-3-chiawei_wang@aspeedtech.com>

Add Ryan Chen and myself as the maintainer of Aspeed eSPI
driver. Joel Stanley is added as the reviewer.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f3267183e993..35c3164277ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1720,6 +1720,15 @@ F:	drivers/crypto/axis
 F:	drivers/mmc/host/usdhi6rol0.c
 F:	drivers/pinctrl/pinctrl-artpec*
 
+ARM/ASPEED ESPI DRIVER
+M:	Chia-Wei Wang <chiawei_wang at aspeedtech.com>
+M:	Ryan Chen <ryan_chen at aspeedtech.com>
+R:	Joel Stanley <joel at jms.id.au>
+L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/soc/aspeed/espi.yaml
+
 ARM/ASPEED I2C DRIVER
 M:	Brendan Higgins <brendanhiggins at google.com>
 R:	Benjamin Herrenschmidt <benh at kernel.crashing.org>
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Tue Aug 31 20:30:11 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Wed, 1 Sep 2021 11:30:11 +0800
Subject: [PATCH v4 0/4] arm: aspeed: Add eSPI support
Message-ID: <20210901033015.910-1-chiawei_wang@aspeedtech.com>

This patch series add the driver support for the eSPI controller
of Aspeed 5/6th generation SoCs. This controller is a slave device
communicating with a master over Enhanced Serial Peripheral Interface (eSPI).
It supports all of the 4 eSPI channels, namely peripheral, virtual wire,
out-of-band, and flash, and operates at max frequency of 66MHz.

v4:
 - fix dt-bindgins error with patternProperties
 - fix data type warning for ARM64 compilation
 - replace header based implementation with .c files
 - add more description for the ioctl interface

v3:
 - remove the redundant patch "clk: aspeed: Add eSPI reset bit"
 - fix missing header inclusion reported by test bot
 - fix dt-bindings error reported by yamllint

v2:
 - remove irqchip implementation
 - merge per-channel drivers into single one to avoid the racing issue
   among eSPI handshake process and driver probing.

Chia-Wei Wang (4):
  dt-bindings: aspeed: Add eSPI controller
  MAINTAINER: Add ASPEED eSPI driver entry
  soc: aspeed: Add eSPI driver
  ARM: dts: aspeed: Add eSPI node

 .../devicetree/bindings/soc/aspeed/espi.yaml  | 162 +++++
 MAINTAINERS                                   |   9 +
 arch/arm/boot/dts/aspeed-g6.dtsi              |  17 +
 drivers/soc/aspeed/Kconfig                    |  11 +
 drivers/soc/aspeed/Makefile                   |   5 +
 drivers/soc/aspeed/aspeed-espi-ctrl.c         | 214 +++++++
 drivers/soc/aspeed/aspeed-espi-ctrl.h         | 308 ++++++++++
 drivers/soc/aspeed/aspeed-espi-flash.c        | 352 +++++++++++
 drivers/soc/aspeed/aspeed-espi-flash.h        |  45 ++
 drivers/soc/aspeed/aspeed-espi-ioc.h          | 195 ++++++
 drivers/soc/aspeed/aspeed-espi-oob.c          | 558 ++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-oob.h          |  70 +++
 drivers/soc/aspeed/aspeed-espi-perif.c        | 511 ++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-perif.h        |  45 ++
 drivers/soc/aspeed/aspeed-espi-vw.c           | 137 +++++
 drivers/soc/aspeed/aspeed-espi-vw.h           |  21 +
 16 files changed, 2660 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-flash.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-flash.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ioc.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-oob.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-oob.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-perif.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-perif.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-vw.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-vw.h

-- 
2.17.1



From chiawei_wang at aspeedtech.com  Tue Aug 31 20:30:14 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Wed, 1 Sep 2021 11:30:14 +0800
Subject: [PATCH v4 3/4] soc: aspeed: Add eSPI driver
In-Reply-To: <20210901033015.910-1-chiawei_wang@aspeedtech.com>
References: <20210901033015.910-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210901033015.910-4-chiawei_wang@aspeedtech.com>

The Aspeed eSPI controller is slave device to communicate with
the master through the Enhanced Serial Peripheral Interface (eSPI).
All of the four eSPI channels, namely peripheral, virtual wire,
out-of-band, and flash are supported.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
Reported-by: kernel test robot <lkp at intel.com>
---
 drivers/soc/aspeed/Kconfig             |  11 +
 drivers/soc/aspeed/Makefile            |   5 +
 drivers/soc/aspeed/aspeed-espi-ctrl.c  | 214 ++++++++++
 drivers/soc/aspeed/aspeed-espi-ctrl.h  | 308 ++++++++++++++
 drivers/soc/aspeed/aspeed-espi-flash.c | 352 ++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-flash.h |  45 ++
 drivers/soc/aspeed/aspeed-espi-ioc.h   | 195 +++++++++
 drivers/soc/aspeed/aspeed-espi-oob.c   | 558 +++++++++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-oob.h   |  70 ++++
 drivers/soc/aspeed/aspeed-espi-perif.c | 511 ++++++++++++++++++++++
 drivers/soc/aspeed/aspeed-espi-perif.h |  45 ++
 drivers/soc/aspeed/aspeed-espi-vw.c    | 137 ++++++
 drivers/soc/aspeed/aspeed-espi-vw.h    |  21 +
 13 files changed, 2472 insertions(+)
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ctrl.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-flash.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-flash.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-ioc.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-oob.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-oob.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-perif.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-perif.h
 create mode 100644 drivers/soc/aspeed/aspeed-espi-vw.c
 create mode 100644 drivers/soc/aspeed/aspeed-espi-vw.h

diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
index 243ca196e6ad..7617a02df5cf 100644
--- a/drivers/soc/aspeed/Kconfig
+++ b/drivers/soc/aspeed/Kconfig
@@ -42,6 +42,17 @@ config ASPEED_SOCINFO
 	help
 	  Say yes to support decoding of ASPEED BMC information.
 
+config ASPEED_ESPI
+	bool "ASPEED eSPI slave driver"
+	select REGMAP
+	select MFD_SYSCON
+	default n
+	help
+	  Enable driver support for the Aspeed eSPI engine. The eSPI engine
+	  plays as a slave device in BMC to communicate with the Host over
+	  the eSPI interface. The four eSPI channels, namely peripheral,
+	  virtual wire, out-of-band, and flash are supported.
+
 endmenu
 
 endif
diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
index fcab7192e1a4..27f05e8b69e1 100644
--- a/drivers/soc/aspeed/Makefile
+++ b/drivers/soc/aspeed/Makefile
@@ -3,3 +3,8 @@ obj-$(CONFIG_ASPEED_LPC_CTRL)	+= aspeed-lpc-ctrl.o
 obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
 obj-$(CONFIG_ASPEED_P2A_CTRL)	+= aspeed-p2a-ctrl.o
 obj-$(CONFIG_ASPEED_SOCINFO)	+= aspeed-socinfo.o
+obj-$(CONFIG_ASPEED_ESPI)	+= aspeed-espi-ctrl.o \
+				   aspeed-espi-perif.o \
+				   aspeed-espi-vw.o \
+				   aspeed-espi-oob.o \
+				   aspeed-espi-flash.o
diff --git a/drivers/soc/aspeed/aspeed-espi-ctrl.c b/drivers/soc/aspeed/aspeed-espi-ctrl.c
new file mode 100644
index 000000000000..ce2967f851f2
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ctrl.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+
+#include "aspeed-espi-ioc.h"
+#include "aspeed-espi-ctrl.h"
+#include "aspeed-espi-perif.h"
+#include "aspeed-espi-vw.h"
+#include "aspeed-espi-oob.h"
+#include "aspeed-espi-flash.h"
+
+#define DEVICE_NAME "aspeed-espi-ctrl"
+
+static irqreturn_t aspeed_espi_ctrl_isr(int irq, void *arg)
+{
+	uint32_t sts;
+	struct aspeed_espi_ctrl *espi_ctrl = (struct aspeed_espi_ctrl *)arg;
+
+	regmap_read(espi_ctrl->map, ESPI_INT_STS, &sts);
+
+	if (sts & ESPI_INT_STS_PERIF_BITS) {
+		aspeed_espi_perif_event(sts, espi_ctrl->perif);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_PERIF_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_VW_BITS) {
+		aspeed_espi_vw_event(sts, espi_ctrl->vw);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_VW_BITS);
+	}
+
+	if (sts & (ESPI_INT_STS_OOB_BITS)) {
+		aspeed_espi_oob_event(sts, espi_ctrl->oob);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_OOB_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_FLASH_BITS) {
+		aspeed_espi_flash_event(sts, espi_ctrl->flash);
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, sts & ESPI_INT_STS_FLASH_BITS);
+	}
+
+	if (sts & ESPI_INT_STS_HW_RST_DEASSERT) {
+		aspeed_espi_perif_enable(espi_ctrl->perif);
+		aspeed_espi_vw_enable(espi_ctrl->vw);
+		aspeed_espi_oob_enable(espi_ctrl->oob);
+		aspeed_espi_flash_enable(espi_ctrl->flash);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
+
+		if (espi_ctrl->model->version == ESPI_AST2500)
+			regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T2,
+				     ESPI_SYSEVT_INT_T2_HOST_RST_WARN |
+				     ESPI_SYSEVT_INT_T2_OOB_RST_WARN);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+				   ESPI_INT_EN_HW_RST_DEASSERT,
+				   ESPI_INT_EN_HW_RST_DEASSERT);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+				   ESPI_SYSEVT_SLV_BOOT_STS | ESPI_SYSEVT_SLV_BOOT_DONE,
+				   ESPI_SYSEVT_SLV_BOOT_STS | ESPI_SYSEVT_SLV_BOOT_DONE);
+
+		regmap_write(espi_ctrl->map, ESPI_INT_STS, ESPI_INT_STS_HW_RST_DEASSERT);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int aspeed_espi_ctrl_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct aspeed_espi_ctrl *espi_ctrl;
+	struct device *dev = &pdev->dev;
+
+	espi_ctrl = devm_kzalloc(dev, sizeof(*espi_ctrl), GFP_KERNEL);
+	if (!espi_ctrl)
+		return -ENOMEM;
+
+	espi_ctrl->model = of_device_get_match_data(dev);
+
+	espi_ctrl->map = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(espi_ctrl->map)) {
+		dev_err(dev, "cannot get remap\n");
+		return -ENODEV;
+	}
+
+	espi_ctrl->irq = platform_get_irq(pdev, 0);
+	if (espi_ctrl->irq < 0)
+		return espi_ctrl->irq;
+
+	espi_ctrl->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(espi_ctrl->clk)) {
+		dev_err(dev, "cannot get clock\n");
+		return -ENODEV;
+	}
+
+	rc = clk_prepare_enable(espi_ctrl->clk);
+	if (rc) {
+		dev_err(dev, "cannot enable clock\n");
+		return rc;
+	}
+
+	espi_ctrl->perif = aspeed_espi_perif_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->perif)) {
+		dev_err(dev, "failed to allocate peripheral channel\n");
+		return PTR_ERR(espi_ctrl->perif);
+	}
+
+	espi_ctrl->vw = aspeed_espi_vw_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->vw)) {
+		dev_err(dev, "failed to allocate virtual wire channel\n");
+		return PTR_ERR(espi_ctrl->vw);
+	}
+
+	espi_ctrl->oob = aspeed_espi_oob_alloc(dev, espi_ctrl);
+	if (IS_ERR(espi_ctrl->oob)) {
+		dev_err(dev, "failed to allocate out-of-band channel\n");
+		return PTR_ERR(espi_ctrl->oob);
+	}
+
+	espi_ctrl->flash = aspeed_espi_flash_alloc(dev, espi_ctrl);
+	if (rc) {
+		dev_err(dev, "failed to allocate flash channel\n");
+		return PTR_ERR(espi_ctrl->flash);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T0, 0x0);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_T1, 0x0);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_EN, 0xffffffff);
+
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_T0, 0x1);
+	regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_EN, 0x1);
+
+	rc = devm_request_irq(dev, espi_ctrl->irq,
+			      aspeed_espi_ctrl_isr,
+			      0, DEVICE_NAME, espi_ctrl);
+	if (rc) {
+		dev_err(dev, "failed to request IRQ\n");
+		return rc;
+	}
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_HW_RST_DEASSERT,
+			   ESPI_INT_EN_HW_RST_DEASSERT);
+
+	dev_set_drvdata(dev, espi_ctrl);
+
+	dev_info(dev, "module loaded\n");
+
+	return 0;
+}
+
+static int aspeed_espi_ctrl_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct aspeed_espi_ctrl *espi_ctrl = dev_get_drvdata(dev);
+
+	aspeed_espi_perif_free(dev, espi_ctrl->perif);
+	aspeed_espi_vw_free(dev, espi_ctrl->vw);
+	aspeed_espi_oob_free(dev, espi_ctrl->oob);
+	aspeed_espi_flash_free(dev, espi_ctrl->flash);
+
+	return 0;
+}
+
+static const struct aspeed_espi_model ast2500_model = {
+	.version = ESPI_AST2500,
+};
+
+static const struct aspeed_espi_model ast2600_model = {
+	.version = ESPI_AST2600,
+};
+
+static const struct of_device_id aspeed_espi_ctrl_of_matches[] = {
+	{ .compatible = "aspeed,ast2500-espi-ctrl",
+	  .data = &ast2500_model },
+	{ .compatible = "aspeed,ast2600-espi-ctrl",
+	  .data = &ast2600_model },
+	{ },
+};
+
+static struct platform_driver aspeed_espi_ctrl_driver = {
+	.driver = {
+		.name = DEVICE_NAME,
+		.of_match_table = aspeed_espi_ctrl_of_matches,
+	},
+	.probe = aspeed_espi_ctrl_probe,
+	.remove = aspeed_espi_ctrl_remove,
+};
+
+module_platform_driver(aspeed_espi_ctrl_driver);
+
+MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang at aspeedtech.com>");
+MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
+MODULE_DESCRIPTION("Control of Aspeed eSPI Slave Device");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/aspeed/aspeed-espi-ctrl.h b/drivers/soc/aspeed/aspeed-espi-ctrl.h
new file mode 100644
index 000000000000..247cb6ce46fb
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ctrl.h
@@ -0,0 +1,308 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_CTRL_H_
+#define _ASPEED_ESPI_CTRL_H_
+
+#include <linux/bits.h>
+
+enum aspeed_espi_version {
+	ESPI_AST2500,
+	ESPI_AST2600,
+};
+
+struct aspeed_espi_model {
+	uint32_t version;
+};
+
+struct aspeed_espi_ctrl {
+	struct device *dev;
+
+	struct regmap *map;
+	struct clk *clk;
+
+	int irq;
+
+	struct aspeed_espi_perif *perif;
+	struct aspeed_espi_vw *vw;
+	struct aspeed_espi_oob *oob;
+	struct aspeed_espi_flash *flash;
+
+	const struct aspeed_espi_model *model;
+};
+
+/* eSPI register offset */
+#define ESPI_CTRL		0x000
+#define   ESPI_CTRL_OOB_RX_SW_RST		BIT(28)
+#define   ESPI_CTRL_FLASH_TX_DMA_EN		BIT(23)
+#define   ESPI_CTRL_FLASH_RX_DMA_EN		BIT(22)
+#define   ESPI_CTRL_OOB_TX_DMA_EN		BIT(21)
+#define   ESPI_CTRL_OOB_RX_DMA_EN		BIT(20)
+#define   ESPI_CTRL_PERIF_NP_TX_DMA_EN		BIT(19)
+#define   ESPI_CTRL_PERIF_PC_TX_DMA_EN		BIT(17)
+#define   ESPI_CTRL_PERIF_PC_RX_DMA_EN		BIT(16)
+#define   ESPI_CTRL_FLASH_SW_MODE_MASK		GENMASK(11, 10)
+#define   ESPI_CTRL_FLASH_SW_MODE_SHIFT		10
+#define   ESPI_CTRL_PERIF_PC_RX_DMA_EN		BIT(16)
+#define   ESPI_CTRL_FLASH_SW_RDY		BIT(7)
+#define   ESPI_CTRL_OOB_SW_RDY			BIT(4)
+#define   ESPI_CTRL_VW_SW_RDY			BIT(3)
+#define   ESPI_CTRL_PERIF_SW_RDY		BIT(1)
+#define ESPI_STS		0x004
+#define ESPI_INT_STS		0x008
+#define   ESPI_INT_STS_HW_RST_DEASSERT		BIT(31)
+#define   ESPI_INT_STS_OOB_RX_TMOUT		BIT(23)
+#define   ESPI_INT_STS_VW_SYSEVT1		BIT(22)
+#define   ESPI_INT_STS_FLASH_TX_ERR		BIT(21)
+#define   ESPI_INT_STS_OOB_TX_ERR		BIT(20)
+#define   ESPI_INT_STS_FLASH_TX_ABT		BIT(19)
+#define   ESPI_INT_STS_OOB_TX_ABT		BIT(18)
+#define   ESPI_INT_STS_PERIF_NP_TX_ABT		BIT(17)
+#define   ESPI_INT_STS_PERIF_PC_TX_ABT		BIT(16)
+#define   ESPI_INT_STS_FLASH_RX_ABT		BIT(15)
+#define   ESPI_INT_STS_OOB_RX_ABT		BIT(14)
+#define   ESPI_INT_STS_PERIF_NP_RX_ABT		BIT(13)
+#define   ESPI_INT_STS_PERIF_PC_RX_ABT		BIT(12)
+#define   ESPI_INT_STS_PERIF_NP_TX_ERR		BIT(11)
+#define   ESPI_INT_STS_PERIF_PC_TX_ERR		BIT(10)
+#define   ESPI_INT_STS_VW_GPIOEVT		BIT(9)
+#define   ESPI_INT_STS_VW_SYSEVT		BIT(8)
+#define   ESPI_INT_STS_FLASH_TX_CMPLT		BIT(7)
+#define   ESPI_INT_STS_FLASH_RX_CMPLT		BIT(6)
+#define   ESPI_INT_STS_OOB_TX_CMPLT		BIT(5)
+#define   ESPI_INT_STS_OOB_RX_CMPLT		BIT(4)
+#define   ESPI_INT_STS_PERIF_NP_TX_CMPLT	BIT(3)
+#define   ESPI_INT_STS_PERIF_PC_TX_CMPLT	BIT(1)
+#define   ESPI_INT_STS_PERIF_PC_RX_CMPLT	BIT(0)
+#define ESPI_INT_EN		0x00c
+#define   ESPI_INT_EN_HW_RST_DEASSERT		BIT(31)
+#define   ESPI_INT_EN_OOB_RX_TMOUT		BIT(23)
+#define   ESPI_INT_EN_VW_SYSEVT1		BIT(22)
+#define   ESPI_INT_EN_FLASH_TX_ERR		BIT(21)
+#define   ESPI_INT_EN_OOB_TX_ERR		BIT(20)
+#define   ESPI_INT_EN_FLASH_TX_ABT		BIT(19)
+#define   ESPI_INT_EN_OOB_TX_ABT		BIT(18)
+#define   ESPI_INT_EN_PERIF_NP_TX_ABT		BIT(17)
+#define   ESPI_INT_EN_PERIF_PC_TX_ABT		BIT(16)
+#define   ESPI_INT_EN_FLASH_RX_ABT		BIT(15)
+#define   ESPI_INT_EN_OOB_RX_ABT		BIT(14)
+#define   ESPI_INT_EN_PERIF_NP_RX_ABT		BIT(13)
+#define   ESPI_INT_EN_PERIF_PC_RX_ABT		BIT(12)
+#define   ESPI_INT_EN_PERIF_NP_TX_ERR		BIT(11)
+#define   ESPI_INT_EN_PERIF_PC_TX_ERR		BIT(10)
+#define   ESPI_INT_EN_VW_GPIOEVT		BIT(9)
+#define   ESPI_INT_EN_VW_SYSEVT			BIT(8)
+#define   ESPI_INT_EN_FLASH_TX_CMPLT		BIT(7)
+#define   ESPI_INT_EN_FLASH_RX_CMPLT		BIT(6)
+#define   ESPI_INT_EN_OOB_TX_CMPLT		BIT(5)
+#define   ESPI_INT_EN_OOB_RX_CMPLT		BIT(4)
+#define   ESPI_INT_EN_PERIF_NP_TX_CMPLT		BIT(3)
+#define   ESPI_INT_EN_PERIF_PC_TX_CMPLT		BIT(1)
+#define   ESPI_INT_EN_PERIF_PC_RX_CMPLT		BIT(0)
+#define ESPI_PERIF_PC_RX_DMA	0x010
+#define ESPI_PERIF_PC_RX_CTRL	0x014
+#define   ESPI_PERIF_PC_RX_CTRL_PEND_SERV	BIT(31)
+#define   ESPI_PERIF_PC_RX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define   ESPI_PERIF_PC_RX_CTRL_LEN_SHIFT	12
+#define   ESPI_PERIF_PC_RX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define   ESPI_PERIF_PC_RX_CTRL_TAG_SHIFT	8
+#define   ESPI_PERIF_PC_RX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define   ESPI_PERIF_PC_RX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_PC_RX_PORT	0x018
+#define ESPI_PERIF_PC_TX_DMA	0x020
+#define ESPI_PERIF_PC_TX_CTRL	0x024
+#define	  ESPI_PERIF_PC_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_PERIF_PC_TX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define	  ESPI_PERIF_PC_TX_CTRL_LEN_SHIFT	12
+#define	  ESPI_PERIF_PC_TX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define	  ESPI_PERIF_PC_TX_CTRL_TAG_SHIFT	8
+#define	  ESPI_PERIF_PC_TX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define	  ESPI_PERIF_PC_TX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_PC_TX_PORT	0x028
+#define ESPI_PERIF_NP_TX_DMA	0x030
+#define ESPI_PERIF_NP_TX_CTRL	0x034
+#define   ESPI_PERIF_NP_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_PERIF_NP_TX_CTRL_LEN_MASK	GENMASK(23, 12)
+#define	  ESPI_PERIF_NP_TX_CTRL_LEN_SHIFT	12
+#define	  ESPI_PERIF_NP_TX_CTRL_TAG_MASK	GENMASK(11, 8)
+#define	  ESPI_PERIF_NP_TX_CTRL_TAG_SHIFT	8
+#define	  ESPI_PERIF_NP_TX_CTRL_CYC_MASK	GENMASK(7, 0)
+#define	  ESPI_PERIF_NP_TX_CTRL_CYC_SHIFT	0
+#define ESPI_PERIF_NP_TX_PORT	0x038
+#define ESPI_OOB_RX_DMA		0x040
+#define ESPI_OOB_RX_CTRL	0x044
+#define	  ESPI_OOB_RX_CTRL_PEND_SERV		BIT(31)
+#define	  ESPI_OOB_RX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_OOB_RX_CTRL_LEN_SHIFT		12
+#define	  ESPI_OOB_RX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_OOB_RX_CTRL_TAG_SHIFT		8
+#define	  ESPI_OOB_RX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_OOB_RX_CTRL_CYC_SHIFT		0
+#define ESPI_OOB_RX_PORT	0x048
+#define ESPI_OOB_TX_DMA		0x050
+#define ESPI_OOB_TX_CTRL	0x054
+#define	  ESPI_OOB_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_OOB_TX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_OOB_TX_CTRL_LEN_SHIFT		12
+#define	  ESPI_OOB_TX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_OOB_TX_CTRL_TAG_SHIFT		8
+#define	  ESPI_OOB_TX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_OOB_TX_CTRL_CYC_SHIFT		0
+#define ESPI_OOB_TX_PORT	0x058
+#define ESPI_FLASH_RX_DMA	0x060
+#define ESPI_FLASH_RX_CTRL	0x064
+#define	  ESPI_FLASH_RX_CTRL_PEND_SERV		BIT(31)
+#define	  ESPI_FLASH_RX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_FLASH_RX_CTRL_LEN_SHIFT		12
+#define	  ESPI_FLASH_RX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_FLASH_RX_CTRL_TAG_SHIFT		8
+#define	  ESPI_FLASH_RX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_FLASH_RX_CTRL_CYC_SHIFT		0
+#define ESPI_FLASH_RX_PORT	0x068
+#define ESPI_FLASH_TX_DMA	0x070
+#define ESPI_FLASH_TX_CTRL	0x074
+#define	  ESPI_FLASH_TX_CTRL_TRIGGER		BIT(31)
+#define	  ESPI_FLASH_TX_CTRL_LEN_MASK		GENMASK(23, 12)
+#define	  ESPI_FLASH_TX_CTRL_LEN_SHIFT		12
+#define	  ESPI_FLASH_TX_CTRL_TAG_MASK		GENMASK(11, 8)
+#define	  ESPI_FLASH_TX_CTRL_TAG_SHIFT		8
+#define	  ESPI_FLASH_TX_CTRL_CYC_MASK		GENMASK(7, 0)
+#define	  ESPI_FLASH_TX_CTRL_CYC_SHIFT		0
+#define ESPI_FLASH_TX_PORT	0x078
+#define ESPI_CTRL2		0x080
+#define   ESPI_CTRL2_MEMCYC_RD_DIS		BIT(6)
+#define   ESPI_CTRL2_MEMCYC_WR_DIS		BIT(4)
+#define ESPI_PERIF_PC_RX_SADDR	0x084
+#define ESPI_PERIF_PC_RX_TADDR	0x088
+#define ESPI_PERIF_PC_RX_MASK	0x08c
+#define   ESPI_PERIF_PC_RX_MASK_CFG_WP		BIT(0)
+#define ESPI_SYSEVT_INT_EN	0x094
+#define ESPI_SYSEVT		0x098
+#define   ESPI_SYSEVT_HOST_RST_ACK		BIT(27)
+#define   ESPI_SYSEVT_RST_CPU_INIT		BIT(26)
+#define   ESPI_SYSEVT_SLV_BOOT_STS		BIT(23)
+#define   ESPI_SYSEVT_NON_FATAL_ERR		BIT(22)
+#define   ESPI_SYSEVT_FATAL_ERR			BIT(21)
+#define   ESPI_SYSEVT_SLV_BOOT_DONE		BIT(20)
+#define   ESPI_SYSEVT_OOB_RST_ACK		BIT(16)
+#define   ESPI_SYSEVT_NMI_OUT			BIT(10)
+#define   ESPI_SYSEVT_SMI_OUT			BIT(9)
+#define   ESPI_SYSEVT_HOST_RST_WARN		BIT(8)
+#define   ESPI_SYSEVT_OOB_RST_WARN		BIT(6)
+#define   ESPI_SYSEVT_PLTRSTN			BIT(5)
+#define   ESPI_SYSEVT_SUSPEND			BIT(4)
+#define   ESPI_SYSEVT_S5_SLEEP			BIT(2)
+#define   ESPI_SYSEVT_S4_SLEEP			BIT(1)
+#define   ESPI_SYSEVT_S3_SLEEP			BIT(0)
+#define ESPI_VW_GPIO_VAL	0x09c
+#define ESPI_GEN_CAP_N_CONF	0x0a0
+#define ESPI_CH0_CAP_N_CONF	0x0a4
+#define ESPI_CH1_CAP_N_CONF	0x0a8
+#define ESPI_CH2_CAP_N_CONF	0x0ac
+#define ESPI_CH3_CAP_N_CONF	0x0b0
+#define ESPI_CH3_CAP_N_CONF2	0x0b4
+#define ESPI_SYSEVT1_INT_EN	0x100
+#define ESPI_SYSEVT1		0x104
+#define   ESPI_SYSEVT1_SUSPEND_ACK		BIT(20)
+#define   ESPI_SYSEVT1_SUSPEND_WARN		BIT(0)
+#define ESPI_SYSEVT_INT_T0	0x110
+#define ESPI_SYSEVT_INT_T1	0x114
+#define ESPI_SYSEVT_INT_T2	0x118
+#define   ESPI_SYSEVT_INT_T2_HOST_RST_WARN	ESPI_SYSEVT_HOST_RST_WARN
+#define   ESPI_SYSEVT_INT_T2_OOB_RST_WARN	ESPI_SYSEVT_OOB_RST_WARN
+#define ESPI_SYSEVT_INT_STS	0x11c
+#define   ESPI_SYSEVT_INT_STS_NMI_OUT		ESPI_SYSEVT_NMI_OUT
+#define   ESPI_SYSEVT_INT_STS_SMI_OUT		ESPI_SYSEVT_SMI_OUT
+#define   ESPI_SYSEVT_INT_STS_HOST_RST_WARN	ESPI_SYSEVT_HOST_RST_WARN
+#define   ESPI_SYSEVT_INT_STS_OOB_RST_WARN	ESPI_SYSEVT_OOB_RST_WARN
+#define   ESPI_SYSEVT_INT_STS_PLTRSTN		ESPI_SYSEVT_PLTRSTN
+#define   ESPI_SYSEVT_INT_STS_SUSPEND		ESPI_SYSEVT_SUSPEND
+#define   ESPI_SYSEVT_INT_STS_S5_SLEEP		ESPI_SYSEVT_INT_S5_SLEEP
+#define   ESPI_SYSEVT_INT_STS_S4_SLEEP		ESPI_SYSEVT_INT_S4_SLEEP
+#define   ESPI_SYSEVT_INT_STS_S3_SLEEP		ESPI_SYSEVT_INT_S3_SLEEP
+#define ESPI_SYSEVT1_INT_T0	0x120
+#define ESPI_SYSEVT1_INT_T1	0x124
+#define ESPI_SYSEVT1_INT_T2	0x128
+#define ESPI_SYSEVT1_INT_STS	0x12c
+#define   ESPI_SYSEVT1_INT_STS_SUSPEND_WARN	ESPI_SYSEVT1_SUSPEND_WARN
+#define ESPI_OOB_RX_DMA_RB_SIZE	0x130
+#define ESPI_OOB_RX_DMA_RD_PTR	0x134
+#define	  ESPI_OOB_RX_DMA_RD_PTR_UPDATE		BIT(31)
+#define ESPI_OOB_RX_DMA_WS_PTR	0x138
+#define   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN	BIT(31)
+#define   ESPI_OOB_RX_DMA_WS_PTR_SP_MASK	GENMASK(27, 16)
+#define   ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT	16
+#define   ESPI_OOB_RX_DMA_WS_PTR_WP_MASK	GENMASK(11, 0)
+#define   ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT	0
+#define ESPI_OOB_TX_DMA_RB_SIZE	0x140
+#define ESPI_OOB_TX_DMA_RD_PTR	0x144
+#define	  ESPI_OOB_TX_DMA_RD_PTR_UPDATE		BIT(31)
+#define ESPI_OOB_TX_DMA_WR_PTR	0x148
+#define	  ESPI_OOB_TX_DMA_WR_PTR_SEND_EN	BIT(31)
+
+/* collect ESPI_INT_STS bits of eSPI channels for convenience */
+#define ESPI_INT_STS_PERIF_BITS			\
+	(ESPI_INT_STS_PERIF_NP_TX_ABT |		\
+	 ESPI_INT_STS_PERIF_PC_TX_ABT |		\
+	 ESPI_INT_STS_PERIF_NP_RX_ABT |		\
+	 ESPI_INT_STS_PERIF_PC_RX_ABT |		\
+	 ESPI_INT_STS_PERIF_NP_TX_ERR |		\
+	 ESPI_INT_STS_PERIF_PC_TX_ERR |		\
+	 ESPI_INT_STS_PERIF_NP_TX_CMPLT |	\
+	 ESPI_INT_STS_PERIF_PC_TX_CMPLT |	\
+	 ESPI_INT_STS_PERIF_PC_RX_CMPLT)
+
+#define ESPI_INT_STS_VW_BITS		\
+	(ESPI_INT_STS_VW_SYSEVT1 |	\
+	 ESPI_INT_STS_VW_GPIOEVT |	\
+	 ESPI_INT_STS_VW_SYSEVT)
+
+#define ESPI_INT_STS_OOB_BITS		\
+	(ESPI_INT_STS_OOB_RX_TMOUT |	\
+	 ESPI_INT_STS_OOB_TX_ERR |	\
+	 ESPI_INT_STS_OOB_TX_ABT |	\
+	 ESPI_INT_STS_OOB_RX_ABT |	\
+	 ESPI_INT_STS_OOB_TX_CMPLT |	\
+	 ESPI_INT_STS_OOB_RX_CMPLT)
+
+#define ESPI_INT_STS_FLASH_BITS		\
+	(ESPI_INT_STS_FLASH_TX_ERR |	\
+	 ESPI_INT_STS_FLASH_TX_ABT |	\
+	 ESPI_INT_STS_FLASH_RX_ABT |	\
+	 ESPI_INT_STS_FLASH_TX_CMPLT |	\
+	 ESPI_INT_STS_FLASH_RX_CMPLT)
+
+/* collect ESPI_INT_EN bits of eSPI channels for convenience */
+#define ESPI_INT_EN_PERIF_BITS			\
+	(ESPI_INT_EN_PERIF_NP_TX_ABT |		\
+	 ESPI_INT_EN_PERIF_PC_TX_ABT |		\
+	 ESPI_INT_EN_PERIF_NP_RX_ABT |		\
+	 ESPI_INT_EN_PERIF_PC_RX_ABT |		\
+	 ESPI_INT_EN_PERIF_NP_TX_ERR |		\
+	 ESPI_INT_EN_PERIF_PC_TX_ERR |		\
+	 ESPI_INT_EN_PERIF_NP_TX_CMPLT |	\
+	 ESPI_INT_EN_PERIF_PC_TX_CMPLT |	\
+	 ESPI_INT_EN_PERIF_PC_RX_CMPLT)
+
+#define ESPI_INT_EN_VW_BITS		\
+	(ESPI_INT_EN_VW_SYSEVT1 |	\
+	 ESPI_INT_EN_VW_GPIOEVT |	\
+	 ESPI_INT_EN_VW_SYSEVT)
+
+#define ESPI_INT_EN_OOB_BITS		\
+	(ESPI_INT_EN_OOB_RX_TMOUT |	\
+	 ESPI_INT_EN_OOB_TX_ERR |	\
+	 ESPI_INT_EN_OOB_TX_ABT |	\
+	 ESPI_INT_EN_OOB_RX_ABT |	\
+	 ESPI_INT_EN_OOB_TX_CMPLT |	\
+	 ESPI_INT_EN_OOB_RX_CMPLT)
+
+#define ESPI_INT_EN_FLASH_BITS		\
+	(ESPI_INT_EN_FLASH_TX_ERR |	\
+	 ESPI_INT_EN_FLASH_TX_ABT |	\
+	 ESPI_INT_EN_FLASH_RX_ABT |	\
+	 ESPI_INT_EN_FLASH_TX_CMPLT |	\
+	 ESPI_INT_EN_FLASH_RX_CMPLT)
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-flash.c b/drivers/soc/aspeed/aspeed-espi-flash.c
new file mode 100644
index 000000000000..d1ede22f22e3
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-flash.c
@@ -0,0 +1,352 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ */
+#include <linux/fs.h>
+#include <linux/of_device.h>
+#include <linux/miscdevice.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+
+#include "aspeed-espi-ioc.h"
+#include "aspeed-espi-ctrl.h"
+#include "aspeed-espi-flash.h"
+
+#define FLASH_MDEV_NAME	"aspeed-espi-flash"
+
+static long aspeed_espi_flash_get_rx(struct file *fp,
+				     struct aspeed_espi_ioc *ioc,
+				     struct aspeed_espi_flash *espi_flash)
+{
+	int i, rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	if (fp->f_flags & O_NONBLOCK) {
+		if (mutex_trylock(&espi_flash->get_rx_mtx))
+			return -EBUSY;
+
+		if (!espi_flash->rx_ready) {
+			rc = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+	} else {
+		mutex_lock(&espi_flash->get_rx_mtx);
+
+		if (!espi_flash->rx_ready) {
+			rc = wait_event_interruptible(espi_flash->wq,
+						      espi_flash->rx_ready);
+			if (rc == -ERESTARTSYS) {
+				rc = -EINTR;
+				goto unlock_mtx_n_out;
+			}
+		}
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_FLASH_RX_CTRL, &reg);
+	cyc = (reg & ESPI_FLASH_RX_CTRL_CYC_MASK) >> ESPI_FLASH_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_FLASH_RX_CTRL_TAG_MASK) >> ESPI_FLASH_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_FLASH_RX_CTRL_LEN_MASK) >> ESPI_FLASH_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	switch (cyc) {
+	case ESPI_FLASH_READ:
+	case ESPI_FLASH_WRITE:
+	case ESPI_FLASH_ERASE:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_flash_rwe);
+		break;
+	case ESPI_FLASH_SUC_CMPLT_D_MIDDLE:
+	case ESPI_FLASH_SUC_CMPLT_D_FIRST:
+	case ESPI_FLASH_SUC_CMPLT_D_LAST:
+	case ESPI_FLASH_SUC_CMPLT_D_ONLY:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_flash_cmplt);
+		break;
+	case ESPI_FLASH_SUC_CMPLT:
+	case ESPI_FLASH_UNSUC_CMPLT:
+		pkt_len = len + sizeof(struct espi_flash_cmplt);
+		break;
+	default:
+		rc = -EFAULT;
+		goto unlock_mtx_n_out;
+	}
+
+	if (ioc->pkt_len < pkt_len) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_flash->dma_mode) {
+		memcpy(hdr + 1, espi_flash->dma.rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_FLASH_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_flash->lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_FLASH_RX_CTRL,
+			  ESPI_FLASH_RX_CTRL_PEND_SERV,
+			  ESPI_FLASH_RX_CTRL_PEND_SERV);
+
+	espi_flash->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_flash->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_flash->get_rx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_flash_put_tx(struct file *fp,
+				     struct aspeed_espi_ioc *ioc,
+				     struct aspeed_espi_flash *espi_flash)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	if (!mutex_trylock(&espi_flash->put_tx_mtx))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_FLASH_TX_CTRL, &reg);
+	if (reg & ESPI_FLASH_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_flash->dma_mode) {
+		memcpy(espi_flash->dma.tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_FLASH_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_FLASH_TX_CTRL_CYC_SHIFT) & ESPI_FLASH_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_FLASH_TX_CTRL_TAG_SHIFT) & ESPI_FLASH_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_FLASH_TX_CTRL_LEN_SHIFT) & ESPI_FLASH_TX_CTRL_LEN_MASK)
+		| ESPI_FLASH_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_FLASH_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_flash->put_tx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_flash_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_flash *espi_flash = container_of(
+			fp->private_data,
+			struct aspeed_espi_flash,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_FLASH_GET_RX:
+		return aspeed_espi_flash_get_rx(fp, &ioc, espi_flash);
+	case ASPEED_ESPI_FLASH_PUT_TX:
+		return aspeed_espi_flash_put_tx(fp, &ioc, espi_flash);
+	};
+
+	return -EINVAL;
+}
+
+void aspeed_espi_flash_event(uint32_t sts, struct aspeed_espi_flash *espi_flash)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_FLASH_RX_CMPLT) {
+		spin_lock_irqsave(&espi_flash->lock, flags);
+		espi_flash->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_flash->lock, flags);
+		wake_up_interruptible(&espi_flash->wq);
+	}
+}
+
+void aspeed_espi_flash_enable(struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_flash_dma *dma = &espi_flash->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_flash->ctrl;
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_FLASH_SW_MODE_MASK,
+			   (espi_flash->safs_mode << ESPI_CTRL_FLASH_SW_MODE_SHIFT));
+
+	if (espi_flash->dma_mode) {
+		regmap_write(espi_ctrl->map, ESPI_FLASH_TX_DMA, dma->tx_addr);
+		regmap_write(espi_ctrl->map, ESPI_FLASH_RX_DMA, dma->rx_addr);
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_FLASH_TX_DMA_EN | ESPI_CTRL_FLASH_RX_DMA_EN,
+				   ESPI_CTRL_FLASH_TX_DMA_EN | ESPI_CTRL_FLASH_RX_DMA_EN);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_FLASH_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_FLASH_BITS,
+			   ESPI_INT_EN_FLASH_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_FLASH_SW_RDY,
+			   ESPI_CTRL_FLASH_SW_RDY);
+}
+
+static const struct file_operations aspeed_espi_flash_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_flash_ioctl,
+};
+
+void *aspeed_espi_flash_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc = 0;
+	struct aspeed_espi_flash *espi_flash;
+	struct aspeed_espi_flash_dma *dma;
+
+	espi_flash = devm_kzalloc(dev, sizeof(*espi_flash), GFP_KERNEL);
+	if (!espi_flash)
+		return ERR_PTR(-ENOMEM);
+
+	espi_flash->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_flash->wq);
+
+	spin_lock_init(&espi_flash->lock);
+
+	mutex_init(&espi_flash->put_tx_mtx);
+	mutex_init(&espi_flash->get_rx_mtx);
+
+	if (of_property_read_bool(dev->of_node, "flash,dma-mode"))
+		espi_flash->dma_mode = 1;
+
+	of_property_read_u32(dev->of_node, "flash,safs-mode", &espi_flash->safs_mode);
+	if (espi_flash->safs_mode >= SAFS_MODES) {
+		dev_err(dev, "invalid SAFS mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (espi_flash->dma_mode) {
+		dma = &espi_flash->dma;
+
+		dma->tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						  &dma->tx_addr, GFP_KERNEL);
+		if (!dma->tx_virt) {
+			dev_err(dev, "cannot allocate DMA TX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->rx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						  &dma->rx_addr, GFP_KERNEL);
+		if (!dma->rx_virt) {
+			dev_err(dev, "cannot allocate DMA RX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	espi_flash->mdev.parent = dev;
+	espi_flash->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_flash->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", FLASH_MDEV_NAME);
+	espi_flash->mdev.fops = &aspeed_espi_flash_fops;
+	rc = misc_register(&espi_flash->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_flash_enable(espi_flash);
+
+	return espi_flash;
+}
+
+void aspeed_espi_flash_free(struct device *dev, struct aspeed_espi_flash *espi_flash)
+{
+	struct aspeed_espi_flash_dma *dma = &espi_flash->dma;
+
+	if (espi_flash->dma_mode) {
+		dma_free_coherent(dev, PAGE_SIZE, dma->tx_virt, dma->tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->rx_virt, dma->rx_addr);
+	}
+
+	mutex_destroy(&espi_flash->put_tx_mtx);
+	mutex_destroy(&espi_flash->get_rx_mtx);
+
+	misc_deregister(&espi_flash->mdev);
+}
diff --git a/drivers/soc/aspeed/aspeed-espi-flash.h b/drivers/soc/aspeed/aspeed-espi-flash.h
new file mode 100644
index 000000000000..bd5177329e50
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-flash.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_FLASH_H_
+#define _ASPEED_ESPI_FLASH_H_
+
+enum aspeed_espi_flash_safs_mode {
+	SAFS_MODE_MIX,
+	SAFS_MODE_SW,
+	SAFS_MODE_HW,
+	SAFS_MODES,
+};
+
+struct aspeed_espi_flash_dma {
+	void *tx_virt;
+	dma_addr_t tx_addr;
+	void *rx_virt;
+	dma_addr_t rx_addr;
+};
+
+struct aspeed_espi_flash {
+	uint32_t safs_mode;
+
+	uint32_t dma_mode;
+	struct aspeed_espi_flash_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	struct mutex get_rx_mtx;
+	struct mutex put_tx_mtx;
+
+	spinlock_t lock;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+void aspeed_espi_flash_event(uint32_t sts, struct aspeed_espi_flash *espi_flash);
+void aspeed_espi_flash_enable(struct aspeed_espi_flash *espi_flash);
+void *aspeed_espi_flash_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl);
+void aspeed_espi_flash_free(struct device *dev, struct aspeed_espi_flash *espi_flash);
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-ioc.h b/drivers/soc/aspeed/aspeed-espi-ioc.h
new file mode 100644
index 000000000000..a78f1069841f
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-ioc.h
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_IOC_H
+#define _ASPEED_ESPI_IOC_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * eSPI cycle type encoding
+ *
+ * Section 5.1 Cycle Types and Packet Format,
+ * Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ */
+#define ESPI_PERIF_MEMRD32		0x00
+#define ESPI_PERIF_MEMRD64		0x02
+#define ESPI_PERIF_MEMWR32		0x01
+#define ESPI_PERIF_MEMWR64		0x03
+#define ESPI_PERIF_MSG			0x10
+#define ESPI_PERIF_MSG_D		0x11
+#define ESPI_PERIF_SUC_CMPLT		0x06
+#define ESPI_PERIF_SUC_CMPLT_D_MIDDLE	0x09
+#define ESPI_PERIF_SUC_CMPLT_D_FIRST	0x0b
+#define ESPI_PERIF_SUC_CMPLT_D_LAST	0x0d
+#define ESPI_PERIF_SUC_CMPLT_D_ONLY	0x0f
+#define ESPI_PERIF_UNSUC_CMPLT		0x0c
+#define ESPI_OOB_MSG			0x21
+#define ESPI_FLASH_READ			0x00
+#define ESPI_FLASH_WRITE		0x01
+#define ESPI_FLASH_ERASE		0x02
+#define ESPI_FLASH_SUC_CMPLT		0x06
+#define ESPI_FLASH_SUC_CMPLT_D_MIDDLE	0x09
+#define ESPI_FLASH_SUC_CMPLT_D_FIRST	0x0b
+#define ESPI_FLASH_SUC_CMPLT_D_LAST	0x0d
+#define ESPI_FLASH_SUC_CMPLT_D_ONLY	0x0f
+#define ESPI_FLASH_UNSUC_CMPLT		0x0c
+
+/*
+ * eSPI packet format structure
+ *
+ * Section 5.1 Cycle Types and Packet Format,
+ * Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ */
+struct espi_comm_hdr {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+};
+
+struct espi_perif_mem32 {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_mem64 {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_msg {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t msg_code;
+	uint8_t msg_byte[4];
+	uint8_t data[];
+} __packed;
+
+struct espi_perif_cmplt {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+} __packed;
+
+struct espi_oob_msg {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+};
+
+struct espi_flash_rwe {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint32_t addr_be;
+	uint8_t data[];
+} __packed;
+
+struct espi_flash_cmplt {
+	uint8_t cyc;
+	uint8_t len_h : 4;
+	uint8_t tag : 4;
+	uint8_t len_l;
+	uint8_t data[];
+} __packed;
+
+struct aspeed_espi_ioc {
+	uint32_t pkt_len;
+	uint8_t *pkt;
+};
+
+/*
+ * we choose the longest header and the max payload size
+ * based on the Intel specification to define the maximum
+ * eSPI packet length
+ */
+#define ESPI_PLD_LEN_MIN	(1UL << 6)
+#define ESPI_PLD_LEN_MAX	(1UL << 12)
+#define ESPI_PKT_LEN_MAX	(sizeof(struct espi_perif_msg) + ESPI_PLD_LEN_MAX)
+
+#define __ASPEED_ESPI_IOCTL_MAGIC	0xb8
+
+/*
+ * The IOCTL-based interface works in the eSPI packet in/out paradigm.
+ *
+ * Only the virtual wire IOCTL is a special case which does not send
+ * or receive an eSPI packet. However, to keep a more consisten use from
+ * userspace, we make all of the four channel drivers serve through the
+ * IOCTL interface.
+ *
+ * For the eSPI packet format, refer to
+ *   Section 5.1 Cycle Types and Packet Format,
+ *   Intel eSPI Interface Base Specification, Rev 1.0, Jan. 2016.
+ *
+ * For the example user apps using these IOCTL, refer to
+ *   https://github.com/AspeedTech-BMC/aspeed_app/tree/master/espi_test
+ */
+
+/*
+ * Peripheral Channel (CH0)
+ *  - ASPEED_ESPI_PERIF_PC_GET_RX
+ *      Receive an eSPI Posted/Completion packet
+ *  - ASPEED_ESPI_PERIF_PC_PUT_TX
+ *      Transmit an eSPI Posted/Completion packet
+ *  - ASPEED_ESPI_PERIF_NP_PUT_TX
+ *      Transmit an eSPI Non-Posted packet
+ */
+#define ASPEED_ESPI_PERIF_PC_GET_RX	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x00, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_PERIF_PC_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x01, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_PERIF_NP_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x02, struct aspeed_espi_ioc)
+/*
+ * Virtual Wire Channel (CH1)
+ *  - ASPEED_ESPI_VW_GET_GPIO_VAL
+ *      Read the input value of GPIO over the VW channel
+ *  - ASPEED_ESPI_VW_PUT_GPIO_VAL
+ *      Write the output value of GPIO over the VW channel
+ */
+#define ASPEED_ESPI_VW_GET_GPIO_VAL	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x10, uint8_t)
+#define ASPEED_ESPI_VW_PUT_GPIO_VAL	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x11, uint8_t)
+/*
+ * Out-of-band Channel (CH2)
+ *  - ASPEED_ESPI_OOB_GET_RX
+ *      Receive an eSPI OOB packet
+ *  - ASPEED_ESPI_OOB_PUT_TX
+ *      Transmit an eSPI OOB packet
+ */
+#define ASPEED_ESPI_OOB_GET_RX		_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x20, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_OOB_PUT_TX		_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x21, struct aspeed_espi_ioc)
+/*
+ * Flash Channel (CH3)
+ *  - ASPEED_ESPI_FLASH_GET_RX
+ *      Receive an eSPI flash packet
+ *  - ASPEED_ESPI_FLASH_PUT_TX
+ *      Transmit an eSPI flash packet
+ */
+#define ASPEED_ESPI_FLASH_GET_RX	_IOR(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x30, struct aspeed_espi_ioc)
+#define ASPEED_ESPI_FLASH_PUT_TX	_IOW(__ASPEED_ESPI_IOCTL_MAGIC, \
+					     0x31, struct aspeed_espi_ioc)
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-oob.c b/drivers/soc/aspeed/aspeed-espi-oob.c
new file mode 100644
index 000000000000..2e0cc427b6c1
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-oob.c
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#include <linux/fs.h>
+#include <linux/of_device.h>
+#include <linux/miscdevice.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+
+#include "aspeed-espi-ioc.h"
+#include "aspeed-espi-ctrl.h"
+#include "aspeed-espi-oob.h"
+
+#define OOB_MDEV_NAME	"aspeed-espi-oob"
+
+/* DMA descriptor is supported since AST2600 */
+#define OOB_DMA_DESC_MAX_NUM	1024
+#define OOB_DMA_TX_DESC_CUST	0x04
+
+/* descriptor-based RX DMA handling */
+static long aspeed_espi_oob_dma_desc_get_rx(struct file *fp,
+					    struct aspeed_espi_ioc *ioc,
+					    struct aspeed_espi_oob *espi_oob)
+{
+	int rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t wptr, sptr;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct oob_rx_dma_desc *d;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR, &reg);
+	wptr = (reg & ESPI_OOB_RX_DMA_WS_PTR_WP_MASK) >> ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT;
+	sptr = (reg & ESPI_OOB_RX_DMA_WS_PTR_SP_MASK) >> ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT;
+
+	d = &espi_oob->dma.rx_desc[sptr];
+
+	if (!d->dirty)
+		return -EFAULT;
+
+	pkt_len = ((d->len) ? d->len : 0x1000) + sizeof(struct espi_comm_hdr);
+
+	if (ioc->pkt_len < pkt_len)
+		return -EINVAL;
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt)
+		return -ENOMEM;
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = d->cyc;
+	hdr->tag = d->tag;
+	hdr->len_h = d->len >> 8;
+	hdr->len_l = d->len & 0xff;
+	memcpy(hdr + 1, espi_oob->dma.rx_virt + (PAGE_SIZE * sptr), pkt_len - sizeof(*hdr));
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_oob->lock, flags);
+
+	/* make current descriptor available again */
+	d->dirty = 0;
+
+	sptr = (sptr + 1) % espi_oob->dma.rx_desc_num;
+	wptr = (wptr + 1) % espi_oob->dma.rx_desc_num;
+
+	reg = ((wptr << ESPI_OOB_RX_DMA_WS_PTR_WP_SHIFT) & ESPI_OOB_RX_DMA_WS_PTR_WP_MASK)
+		| ((sptr << ESPI_OOB_RX_DMA_WS_PTR_SP_SHIFT) & ESPI_OOB_RX_DMA_WS_PTR_SP_MASK)
+		| ESPI_OOB_RX_DMA_WS_PTR_RECV_EN;
+	regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR, reg);
+
+	/* set ready flag base on the next RX descriptor */
+	espi_oob->rx_ready = espi_oob->dma.rx_desc[sptr].dirty;
+
+	spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_get_rx(struct file *fp,
+				   struct aspeed_espi_ioc *ioc,
+				   struct aspeed_espi_oob *espi_oob)
+{
+	int i, rc = 0;
+	unsigned long flags;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	if (fp->f_flags & O_NONBLOCK) {
+		if (mutex_trylock(&espi_oob->get_rx_mtx))
+			return -EBUSY;
+
+		if (!espi_oob->rx_ready) {
+			rc = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+	} else {
+		mutex_lock(&espi_oob->get_rx_mtx);
+
+		if (!espi_oob->rx_ready) {
+			rc = wait_event_interruptible(espi_oob->wq,
+						      espi_oob->rx_ready);
+			if (rc == -ERESTARTSYS) {
+				rc = -EINTR;
+				goto unlock_mtx_n_out;
+			}
+		}
+	}
+
+	if (espi_oob->dma_mode && espi_ctrl->model->version != ESPI_AST2500) {
+		rc = aspeed_espi_oob_dma_desc_get_rx(fp, ioc, espi_oob);
+		goto unlock_mtx_n_out;
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_OOB_RX_CTRL, &reg);
+	cyc = (reg & ESPI_OOB_RX_CTRL_CYC_MASK) >> ESPI_OOB_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_OOB_RX_CTRL_TAG_MASK) >> ESPI_OOB_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_OOB_RX_CTRL_LEN_MASK) >> ESPI_OOB_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) + sizeof(struct espi_comm_hdr);
+
+	if (ioc->pkt_len < pkt_len) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_oob->dma_mode) {
+		memcpy(hdr + 1, espi_oob->dma.rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_OOB_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_oob->lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_OOB_RX_CTRL,
+			  ESPI_OOB_RX_CTRL_PEND_SERV,
+			  ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	espi_oob->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_oob->get_rx_mtx);
+
+	return rc;
+}
+
+/* descriptor-based TX DMA handling */
+static long aspeed_espi_oob_dma_desc_put_tx(struct file *fp,
+					    struct aspeed_espi_ioc *ioc,
+					    struct aspeed_espi_oob *espi_oob)
+{
+	int rc = 0;
+	uint32_t rptr, wptr;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct oob_tx_dma_desc *d;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	pkt = vzalloc(ioc->pkt_len);
+	if (!pkt)
+		return -ENOMEM;
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/* kick HW to reflect the up-to-date read/write pointer */
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_RD_PTR,
+		     ESPI_OOB_TX_DMA_RD_PTR_UPDATE);
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_DMA_RD_PTR, &rptr);
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_DMA_WR_PTR, &wptr);
+
+	if (((wptr + 1) % espi_oob->dma.tx_desc_num) == rptr) {
+		rc = -EBUSY;
+		goto free_n_out;
+	}
+
+	d = &espi_oob->dma.tx_desc[wptr];
+	d->cyc = hdr->cyc;
+	d->tag = hdr->tag;
+	d->len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+	d->msg_type = OOB_DMA_TX_DESC_CUST;
+
+	memcpy(espi_oob->dma.tx_virt + (PAGE_SIZE * wptr), hdr + 1,
+	       ioc->pkt_len - sizeof(*hdr));
+
+	dma_wmb();
+
+	wptr = (wptr + 1) % espi_oob->dma.tx_desc_num;
+	wptr |= ESPI_OOB_TX_DMA_WR_PTR_SEND_EN;
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_WR_PTR, wptr);
+
+free_n_out:
+	vfree(pkt);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_put_tx(struct file *fp,
+				   struct aspeed_espi_ioc *ioc,
+				   struct aspeed_espi_oob *espi_oob)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	if (!mutex_trylock(&espi_oob->put_tx_mtx))
+		return -EBUSY;
+
+	if (espi_oob->dma_mode && espi_ctrl->model->version != ESPI_AST2500) {
+		rc = aspeed_espi_oob_dma_desc_put_tx(fp, ioc, espi_oob);
+		goto unlock_mtx_n_out;
+	}
+
+	regmap_read(espi_ctrl->map, ESPI_OOB_TX_CTRL, &reg);
+	if (reg & ESPI_OOB_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_mtx_n_out;
+	}
+
+	if (ioc->pkt_len > ESPI_PKT_LEN_MAX) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_oob->dma_mode) {
+		memcpy(espi_oob->dma.tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_OOB_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_OOB_TX_CTRL_CYC_SHIFT) & ESPI_OOB_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_OOB_TX_CTRL_TAG_SHIFT) & ESPI_OOB_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_OOB_TX_CTRL_LEN_SHIFT) & ESPI_OOB_TX_CTRL_LEN_MASK)
+		| ESPI_OOB_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_OOB_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_oob->put_tx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_oob_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_oob *espi_oob = container_of(
+			fp->private_data,
+			struct aspeed_espi_oob,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_OOB_GET_RX:
+		return aspeed_espi_oob_get_rx(fp, &ioc, espi_oob);
+	case ASPEED_ESPI_OOB_PUT_TX:
+		return aspeed_espi_oob_put_tx(fp, &ioc, espi_oob);
+	};
+
+	return -EINVAL;
+}
+
+void aspeed_espi_oob_event(uint32_t sts, struct aspeed_espi_oob *espi_oob)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_OOB_RX_CMPLT) {
+		spin_lock_irqsave(&espi_oob->lock, flags);
+		espi_oob->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_oob->lock, flags);
+
+		wake_up_interruptible(&espi_oob->wq);
+	}
+}
+
+void aspeed_espi_oob_enable(struct aspeed_espi_oob *espi_oob)
+{
+	int i;
+	struct aspeed_espi_oob_dma *dma = &espi_oob->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_oob->ctrl;
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_SW_RDY | ESPI_CTRL_OOB_RX_SW_RST, 0);
+
+	if (espi_oob->dma_mode)
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN, 0);
+	else
+		regmap_write(espi_ctrl->map, ESPI_OOB_RX_CTRL, ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	/*
+	 * cleanup OOB RX FIFO to get rid of the data
+	 * of OOB early init side-effect
+	 */
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_RX_SW_RST, ESPI_CTRL_OOB_RX_SW_RST);
+
+	regmap_write(espi_ctrl->map, ESPI_OOB_RX_CTRL,
+		     ESPI_OOB_RX_CTRL_PEND_SERV);
+
+	if (espi_oob->dma_mode) {
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN,
+				   ESPI_CTRL_OOB_TX_DMA_EN | ESPI_CTRL_OOB_RX_DMA_EN);
+
+		if (espi_ctrl->model->version == ESPI_AST2500) {
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA, dma->tx_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA, dma->rx_addr);
+		} else {
+			for (i = 0; i < dma->tx_desc_num; ++i)
+				dma->tx_desc[i].data_addr = dma->tx_addr + (i * PAGE_SIZE);
+
+			for (i = 0; i < dma->rx_desc_num; ++i) {
+				dma->rx_desc[i].data_addr = dma->rx_addr + (i * PAGE_SIZE);
+				dma->rx_desc[i].dirty = 0;
+			}
+
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA, dma->tx_desc_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_TX_DMA_RB_SIZE, dma->tx_desc_num);
+
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA, dma->rx_desc_addr);
+			regmap_write(espi_ctrl->map, ESPI_OOB_RX_DMA_RB_SIZE, dma->rx_desc_num);
+			regmap_update_bits(espi_ctrl->map, ESPI_OOB_RX_DMA_WS_PTR,
+					   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN,
+					   ESPI_OOB_RX_DMA_WS_PTR_RECV_EN);
+		}
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_OOB_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_OOB_BITS,
+			   ESPI_INT_EN_OOB_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_OOB_SW_RDY,
+			   ESPI_CTRL_OOB_SW_RDY);
+}
+
+static const struct file_operations aspeed_espi_oob_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_oob_ioctl,
+};
+
+void *aspeed_espi_oob_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc = 0;
+	struct aspeed_espi_oob *espi_oob;
+	struct aspeed_espi_oob_dma *dma;
+
+	espi_oob = devm_kzalloc(dev, sizeof(*espi_oob), GFP_KERNEL);
+	if (!espi_oob)
+		return ERR_PTR(-ENOMEM);
+
+	espi_oob->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_oob->wq);
+
+	spin_lock_init(&espi_oob->lock);
+
+	mutex_init(&espi_oob->put_tx_mtx);
+	mutex_init(&espi_oob->get_rx_mtx);
+
+	if (of_property_read_bool(dev->of_node, "oob,dma-mode"))
+		espi_oob->dma_mode = 1;
+
+	if (espi_oob->dma_mode) {
+		dma = &espi_oob->dma;
+
+		/* Descriptor based OOB DMA is supported since AST2600 */
+		if (espi_ctrl->model->version != ESPI_AST2500) {
+			of_property_read_u32(dev->of_node, "oob,dma-tx-desc-num",
+					     &dma->tx_desc_num);
+			of_property_read_u32(dev->of_node, "oob,dma-rx-desc-num",
+					     &dma->rx_desc_num);
+
+			if (!dma->tx_desc_num || !dma->rx_desc_num) {
+				dev_err(dev, "invalid zero number of DMA channels\n");
+				return ERR_PTR(-EINVAL);
+			}
+
+			if (dma->tx_desc_num >= OOB_DMA_DESC_MAX_NUM ||
+			    dma->rx_desc_num >= OOB_DMA_DESC_MAX_NUM) {
+				dev_err(dev, "too many number of DMA channels\n");
+				return ERR_PTR(-EINVAL);
+			}
+
+			dma->tx_desc = dma_alloc_coherent(dev,
+							  sizeof(*dma->tx_desc) * dma->tx_desc_num,
+							  &dma->tx_desc_addr, GFP_KERNEL);
+			if (!dma->tx_desc) {
+				dev_err(dev, "cannot allocate DMA TX descriptor\n");
+				return ERR_PTR(-ENOMEM);
+			}
+
+			dma->rx_desc = dma_alloc_coherent(dev,
+							  sizeof(*dma->rx_desc) * dma->rx_desc_num,
+							  &dma->rx_desc_addr, GFP_KERNEL);
+			if (!dma->rx_desc) {
+				dev_err(dev, "cannot allocate DMA RX descriptor\n");
+				return ERR_PTR(-ENOMEM);
+			}
+		}
+
+		/*
+		 * DMA descriptors are consumed in the circular
+		 * queue paradigm. Therefore, one dummy slot is
+		 * reserved to detect the full condition.
+		 *
+		 * For AST2500 without DMA descriptors supported,
+		 * the number of the queue slot should be 1 here.
+		 */
+		dma->tx_desc_num += 1;
+		dma->rx_desc_num += 1;
+
+		dma->tx_virt = dma_alloc_coherent(dev, PAGE_SIZE * dma->tx_desc_num,
+						  &dma->tx_addr, GFP_KERNEL);
+		if (!dma->tx_virt) {
+			dev_err(dev, "cannot allocate DMA TX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->rx_virt = dma_alloc_coherent(dev, PAGE_SIZE * dma->rx_desc_num,
+						  &dma->rx_addr, GFP_KERNEL);
+		if (!dma->rx_virt) {
+			dev_err(dev, "cannot allocate DMA RX buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	espi_oob->mdev.parent = dev;
+	espi_oob->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_oob->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", OOB_MDEV_NAME);
+	espi_oob->mdev.fops = &aspeed_espi_oob_fops;
+	rc = misc_register(&espi_oob->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_oob_enable(espi_oob);
+
+	return espi_oob;
+}
+
+void aspeed_espi_oob_free(struct device *dev, struct aspeed_espi_oob *espi_oob)
+{
+	struct aspeed_espi_oob_dma *dma = &espi_oob->dma;
+
+	if (espi_oob->dma_mode) {
+		dma_free_coherent(dev, sizeof(*dma->tx_desc) * dma->tx_desc_num,
+				  dma->tx_desc, dma->tx_desc_addr);
+		dma_free_coherent(dev, sizeof(*dma->rx_desc) * dma->rx_desc_num,
+				  dma->rx_desc, dma->rx_desc_addr);
+		dma_free_coherent(dev, PAGE_SIZE * dma->tx_desc_num,
+				  dma->tx_virt, dma->tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE * dma->rx_desc_num,
+				  dma->rx_virt, dma->rx_addr);
+	}
+
+	mutex_destroy(&espi_oob->put_tx_mtx);
+	mutex_destroy(&espi_oob->get_rx_mtx);
+
+	misc_deregister(&espi_oob->mdev);
+}
diff --git a/drivers/soc/aspeed/aspeed-espi-oob.h b/drivers/soc/aspeed/aspeed-espi-oob.h
new file mode 100644
index 000000000000..03d74ef39e8b
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-oob.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 Aspeed Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_OOB_H_
+#define _ASPEED_ESPI_OOB_H_
+
+struct oob_tx_dma_desc {
+	uint32_t data_addr;
+	uint8_t cyc;
+	uint16_t tag : 4;
+	uint16_t len : 12;
+	uint8_t msg_type : 3;
+	uint8_t raz0 : 1;
+	uint8_t pec : 1;
+	uint8_t int_en : 1;
+	uint8_t pause : 1;
+	uint8_t raz1 : 1;
+	uint32_t raz2;
+	uint32_t raz3;
+} __packed;
+
+struct oob_rx_dma_desc {
+	uint32_t data_addr;
+	uint8_t cyc;
+	uint16_t tag : 4;
+	uint16_t len : 12;
+	uint8_t raz : 7;
+	uint8_t dirty : 1;
+} __packed;
+
+struct aspeed_espi_oob_dma {
+	uint32_t tx_desc_num;
+	uint32_t rx_desc_num;
+
+	struct oob_tx_dma_desc *tx_desc;
+	dma_addr_t tx_desc_addr;
+
+	struct oob_rx_dma_desc *rx_desc;
+	dma_addr_t rx_desc_addr;
+
+	void *tx_virt;
+	dma_addr_t tx_addr;
+
+	void *rx_virt;
+	dma_addr_t rx_addr;
+};
+
+struct aspeed_espi_oob {
+	uint32_t dma_mode;
+	struct aspeed_espi_oob_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	struct mutex get_rx_mtx;
+	struct mutex put_tx_mtx;
+
+	spinlock_t lock;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+void aspeed_espi_oob_event(uint32_t sts, struct aspeed_espi_oob *espi_oob);
+void aspeed_espi_oob_enable(struct aspeed_espi_oob *espi_oob);
+void *aspeed_espi_oob_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl);
+void aspeed_espi_oob_free(struct device *dev, struct aspeed_espi_oob *espi_oob);
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-perif.c b/drivers/soc/aspeed/aspeed-espi-perif.c
new file mode 100644
index 000000000000..ebf3d9978b4a
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-perif.c
@@ -0,0 +1,511 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ */
+#include <linux/fs.h>
+#include <linux/of_device.h>
+#include <linux/miscdevice.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+
+#include "aspeed-espi-ioc.h"
+#include "aspeed-espi-ctrl.h"
+#include "aspeed-espi-perif.h"
+
+#define PERIF_MDEV_NAME		"aspeed-espi-peripheral"
+#define PERIF_MEMCYC_UNLOCK_KEY	0xfedc756e
+#define PERIF_MEMCYC_SIZE_MIN	0x10000
+
+static long aspeed_espi_perif_pc_get_rx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	uint32_t pkt_len;
+	struct espi_comm_hdr *hdr;
+	unsigned long flags;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (fp->f_flags & O_NONBLOCK) {
+		if (mutex_trylock(&espi_perif->pc_rx_mtx))
+			return -EBUSY;
+
+		if (!espi_perif->rx_ready) {
+			rc = -ENODATA;
+			goto unlock_mtx_n_out;
+		}
+	} else {
+		mutex_lock(&espi_perif->pc_rx_mtx);
+
+		if (!espi_perif->rx_ready) {
+			rc = wait_event_interruptible(espi_perif->wq,
+						      espi_perif->rx_ready);
+			if (rc == -ERESTARTSYS) {
+				rc = -EINTR;
+				goto unlock_mtx_n_out;
+			}
+		}
+	}
+
+	/* common header (i.e. cycle type, tag, and length) is taken by HW */
+	regmap_read(espi_ctrl->map, ESPI_PERIF_PC_RX_CTRL, &reg);
+	cyc = (reg & ESPI_PERIF_PC_RX_CTRL_CYC_MASK) >> ESPI_PERIF_PC_RX_CTRL_CYC_SHIFT;
+	tag = (reg & ESPI_PERIF_PC_RX_CTRL_TAG_MASK) >> ESPI_PERIF_PC_RX_CTRL_TAG_SHIFT;
+	len = (reg & ESPI_PERIF_PC_RX_CTRL_LEN_MASK) >> ESPI_PERIF_PC_RX_CTRL_LEN_SHIFT;
+
+	/*
+	 * calculate the length of the rest part of the
+	 * eSPI packet to be read from HW and copied to
+	 * user space.
+	 */
+	switch (cyc) {
+	case ESPI_PERIF_MSG:
+		pkt_len = len + sizeof(struct espi_perif_msg);
+		break;
+	case ESPI_PERIF_MSG_D:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_perif_msg);
+		break;
+	case ESPI_PERIF_SUC_CMPLT_D_MIDDLE:
+	case ESPI_PERIF_SUC_CMPLT_D_FIRST:
+	case ESPI_PERIF_SUC_CMPLT_D_LAST:
+	case ESPI_PERIF_SUC_CMPLT_D_ONLY:
+		pkt_len = ((len) ? len : ESPI_PLD_LEN_MAX) +
+			  sizeof(struct espi_perif_cmplt);
+		break;
+	case ESPI_PERIF_SUC_CMPLT:
+	case ESPI_PERIF_UNSUC_CMPLT:
+		pkt_len = len + sizeof(struct espi_perif_cmplt);
+		break;
+	default:
+		rc = -EFAULT;
+		goto unlock_mtx_n_out;
+	}
+
+	if (ioc->pkt_len < pkt_len) {
+		rc = -EINVAL;
+		goto unlock_mtx_n_out;
+	}
+
+	pkt = vmalloc(pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_mtx_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+	hdr->cyc = cyc;
+	hdr->tag = tag;
+	hdr->len_h = len >> 8;
+	hdr->len_l = len & 0xff;
+
+	if (espi_perif->dma_mode) {
+		memcpy(hdr + 1, espi_perif->dma.pc_rx_virt,
+		       pkt_len - sizeof(*hdr));
+	} else {
+		for (i = sizeof(*hdr); i < pkt_len; ++i) {
+			regmap_read(espi_ctrl->map,
+				    ESPI_PERIF_PC_RX_PORT, &reg);
+			pkt[i] = reg & 0xff;
+		}
+	}
+
+	if (copy_to_user((void __user *)ioc->pkt, pkt, pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	spin_lock_irqsave(&espi_perif->lock, flags);
+
+	regmap_write_bits(espi_ctrl->map, ESPI_PERIF_PC_RX_CTRL,
+			  ESPI_PERIF_PC_RX_CTRL_PEND_SERV,
+			  ESPI_PERIF_PC_RX_CTRL_PEND_SERV);
+
+	espi_perif->rx_ready = 0;
+
+	spin_unlock_irqrestore(&espi_perif->lock, flags);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_mtx_n_out:
+	mutex_unlock(&espi_perif->pc_rx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_perif_pc_put_tx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (!mutex_trylock(&espi_perif->pc_tx_mtx))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_PERIF_PC_TX_CTRL, &reg);
+	if (reg & ESPI_PERIF_PC_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_perif->dma_mode) {
+		memcpy(espi_perif->dma.pc_tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_PERIF_PC_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_PERIF_PC_TX_CTRL_CYC_SHIFT) & ESPI_PERIF_PC_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_PERIF_PC_TX_CTRL_TAG_SHIFT) & ESPI_PERIF_PC_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_PERIF_PC_TX_CTRL_LEN_SHIFT) & ESPI_PERIF_PC_TX_CTRL_LEN_MASK)
+		| ESPI_PERIF_PC_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_PERIF_PC_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_n_out:
+	mutex_unlock(&espi_perif->pc_tx_mtx);
+
+	return rc;
+}
+
+static long aspeed_espi_perif_np_put_tx(struct file *fp,
+					struct aspeed_espi_ioc *ioc,
+					struct aspeed_espi_perif *espi_perif)
+{
+	int i, rc = 0;
+	uint32_t reg;
+	uint32_t cyc, tag, len;
+	uint8_t *pkt;
+	struct espi_comm_hdr *hdr;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (!mutex_trylock(&espi_perif->np_tx_mtx))
+		return -EAGAIN;
+
+	regmap_read(espi_ctrl->map, ESPI_PERIF_NP_TX_CTRL, &reg);
+	if (reg & ESPI_PERIF_NP_TX_CTRL_TRIGGER) {
+		rc = -EBUSY;
+		goto unlock_n_out;
+	}
+
+	pkt = vmalloc(ioc->pkt_len);
+	if (!pkt) {
+		rc = -ENOMEM;
+		goto unlock_n_out;
+	}
+
+	hdr = (struct espi_comm_hdr *)pkt;
+
+	if (copy_from_user(pkt, (void __user *)ioc->pkt, ioc->pkt_len)) {
+		rc = -EFAULT;
+		goto free_n_out;
+	}
+
+	/*
+	 * common header (i.e. cycle type, tag, and length)
+	 * part is written to HW registers
+	 */
+	if (espi_perif->dma_mode) {
+		memcpy(espi_perif->dma.np_tx_virt, hdr + 1,
+		       ioc->pkt_len - sizeof(*hdr));
+		dma_wmb();
+	} else {
+		for (i = sizeof(*hdr); i < ioc->pkt_len; ++i)
+			regmap_write(espi_ctrl->map,
+				     ESPI_PERIF_NP_TX_PORT, pkt[i]);
+	}
+
+	cyc = hdr->cyc;
+	tag = hdr->tag;
+	len = (hdr->len_h << 8) | (hdr->len_l & 0xff);
+
+	reg = ((cyc << ESPI_PERIF_NP_TX_CTRL_CYC_SHIFT) & ESPI_PERIF_NP_TX_CTRL_CYC_MASK)
+		| ((tag << ESPI_PERIF_NP_TX_CTRL_TAG_SHIFT) & ESPI_PERIF_NP_TX_CTRL_TAG_MASK)
+		| ((len << ESPI_PERIF_NP_TX_CTRL_LEN_SHIFT) & ESPI_PERIF_NP_TX_CTRL_LEN_MASK)
+		| ESPI_PERIF_NP_TX_CTRL_TRIGGER;
+
+	regmap_write(espi_ctrl->map, ESPI_PERIF_NP_TX_CTRL, reg);
+
+free_n_out:
+	vfree(pkt);
+
+unlock_n_out:
+	mutex_unlock(&espi_perif->np_tx_mtx);
+
+	return rc;
+
+}
+
+static long aspeed_espi_perif_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+	struct aspeed_espi_ioc ioc;
+	struct aspeed_espi_perif *espi_perif = container_of(
+			fp->private_data,
+			struct aspeed_espi_perif,
+			mdev);
+
+	if (copy_from_user(&ioc, (void __user *)arg, sizeof(ioc)))
+		return -EFAULT;
+
+	if (ioc.pkt_len > ESPI_PKT_LEN_MAX)
+		return -EINVAL;
+
+	switch (cmd) {
+	case ASPEED_ESPI_PERIF_PC_GET_RX:
+		return aspeed_espi_perif_pc_get_rx(fp, &ioc, espi_perif);
+	case ASPEED_ESPI_PERIF_PC_PUT_TX:
+		return aspeed_espi_perif_pc_put_tx(fp, &ioc, espi_perif);
+	case ASPEED_ESPI_PERIF_NP_PUT_TX:
+		return aspeed_espi_perif_np_put_tx(fp, &ioc, espi_perif);
+	};
+
+	return -EINVAL;
+}
+
+static int aspeed_espi_perif_mmap(struct file *fp, struct vm_area_struct *vma)
+{
+	struct aspeed_espi_perif *espi_perif = container_of(
+			fp->private_data,
+			struct aspeed_espi_perif,
+			mdev);
+	unsigned long vm_size = vma->vm_end - vma->vm_start;
+	pgprot_t prot = vma->vm_page_prot;
+
+	if (!espi_perif->mcyc_enable)
+		return -EPERM;
+
+	if (((vma->vm_pgoff << PAGE_SHIFT) + vm_size) > espi_perif->mcyc_size)
+		return -EINVAL;
+
+	prot = pgprot_noncached(prot);
+
+	if (remap_pfn_range(vma, vma->vm_start,
+			    (espi_perif->mcyc_taddr >> PAGE_SHIFT) + vma->vm_pgoff,
+			    vm_size, prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+void aspeed_espi_perif_event(uint32_t sts, struct aspeed_espi_perif *espi_perif)
+{
+	unsigned long flags;
+
+	if (sts & ESPI_INT_STS_PERIF_PC_RX_CMPLT) {
+		spin_lock_irqsave(&espi_perif->lock, flags);
+		espi_perif->rx_ready = 1;
+		spin_unlock_irqrestore(&espi_perif->lock, flags);
+
+		wake_up_interruptible(&espi_perif->wq);
+	}
+}
+
+void aspeed_espi_perif_enable(struct aspeed_espi_perif *espi_perif)
+{
+	struct aspeed_espi_perif_dma *dma = &espi_perif->dma;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_perif->ctrl;
+
+	if (espi_perif->mcyc_enable) {
+		if (espi_ctrl->model->version == ESPI_AST2500) {
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     PERIF_MEMCYC_UNLOCK_KEY);
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     espi_perif->mcyc_mask);
+		} else {
+			regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_MASK,
+				     espi_perif->mcyc_mask | ESPI_PERIF_PC_RX_MASK_CFG_WP);
+			regmap_update_bits(espi_ctrl->map, ESPI_CTRL2,
+					   ESPI_CTRL2_MEMCYC_RD_DIS | ESPI_CTRL2_MEMCYC_WR_DIS, 0);
+		}
+
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_SADDR, espi_perif->mcyc_saddr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_TADDR, espi_perif->mcyc_taddr);
+	}
+
+	if (espi_perif->dma_mode) {
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_RX_DMA, dma->pc_rx_addr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_PC_TX_DMA, dma->pc_tx_addr);
+		regmap_write(espi_ctrl->map, ESPI_PERIF_NP_TX_DMA, dma->np_tx_addr);
+
+		regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+				   ESPI_CTRL_PERIF_NP_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_RX_DMA_EN,
+				   ESPI_CTRL_PERIF_NP_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_TX_DMA_EN |
+				   ESPI_CTRL_PERIF_PC_RX_DMA_EN);
+	}
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_PERIF_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_PERIF_BITS,
+			   ESPI_INT_EN_PERIF_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_PERIF_SW_RDY,
+			   ESPI_CTRL_PERIF_SW_RDY);
+}
+
+static const struct file_operations aspeed_espi_perif_fops = {
+	.owner = THIS_MODULE,
+	.mmap = aspeed_espi_perif_mmap,
+	.unlocked_ioctl = aspeed_espi_perif_ioctl,
+};
+
+void *aspeed_espi_perif_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc;
+	struct aspeed_espi_perif *espi_perif;
+	struct aspeed_espi_perif_dma *dma;
+
+	espi_perif = devm_kzalloc(dev, sizeof(*espi_perif), GFP_KERNEL);
+	if (!espi_perif)
+		return ERR_PTR(-ENOMEM);
+
+	espi_perif->ctrl = espi_ctrl;
+
+	init_waitqueue_head(&espi_perif->wq);
+
+	spin_lock_init(&espi_perif->lock);
+
+	mutex_init(&espi_perif->pc_rx_mtx);
+	mutex_init(&espi_perif->pc_tx_mtx);
+	mutex_init(&espi_perif->np_tx_mtx);
+
+	espi_perif->mcyc_enable = of_property_read_bool(dev->of_node, "perif,memcyc-enable");
+	if (espi_perif->mcyc_enable) {
+		rc = of_property_read_u32(dev->of_node, "perif,memcyc-src-addr",
+					  &espi_perif->mcyc_saddr);
+		if (rc) {
+			dev_err(dev, "cannot get Host source address for memory cycle\n");
+			return ERR_PTR(-ENODEV);
+		}
+
+		rc = of_property_read_u32(dev->of_node, "perif,memcyc-size",
+					  &espi_perif->mcyc_size);
+		if (rc) {
+			dev_err(dev, "cannot get size for memory cycle\n");
+			return ERR_PTR(-ENODEV);
+		}
+
+		if (espi_perif->mcyc_size < PERIF_MEMCYC_SIZE_MIN)
+			espi_perif->mcyc_size = PERIF_MEMCYC_SIZE_MIN;
+		else
+			espi_perif->mcyc_size = roundup_pow_of_two(espi_perif->mcyc_size);
+
+		espi_perif->mcyc_mask = ~(espi_perif->mcyc_size - 1);
+		espi_perif->mcyc_virt = dma_alloc_coherent(dev, espi_perif->mcyc_size,
+							   &espi_perif->mcyc_taddr, GFP_KERNEL);
+		if (!espi_perif->mcyc_virt) {
+			dev_err(dev, "cannot allocate memory cycle region\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	if (of_property_read_bool(dev->of_node, "perif,dma-mode")) {
+		dma = &espi_perif->dma;
+
+		dma->pc_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						     &dma->pc_tx_addr, GFP_KERNEL);
+		if (!dma->pc_tx_virt) {
+			dev_err(dev, "cannot allocate posted TX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->pc_rx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+						     &dma->pc_rx_addr, GFP_KERNEL);
+		if (!dma->pc_rx_virt) {
+			dev_err(dev, "cannot allocate posted RX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dma->np_tx_virt = dma_alloc_coherent(dev, PAGE_SIZE,
+				&dma->np_tx_addr, GFP_KERNEL);
+		if (!dma->np_tx_virt) {
+			dev_err(dev, "cannot allocate non-posted TX DMA buffer\n");
+			return ERR_PTR(-ENOMEM);
+		}
+
+		espi_perif->dma_mode = 1;
+	}
+
+	espi_perif->mdev.parent = dev;
+	espi_perif->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_perif->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", PERIF_MDEV_NAME);
+	espi_perif->mdev.fops = &aspeed_espi_perif_fops;
+	rc = misc_register(&espi_perif->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_perif_enable(espi_perif);
+
+	return espi_perif;
+}
+
+void aspeed_espi_perif_free(struct device *dev, struct aspeed_espi_perif *espi_perif)
+{
+	struct aspeed_espi_perif_dma *dma = &espi_perif->dma;
+
+	if (espi_perif->mcyc_virt)
+		dma_free_coherent(dev, espi_perif->mcyc_size,
+				  espi_perif->mcyc_virt,
+				  espi_perif->mcyc_taddr);
+
+	if (espi_perif->dma_mode) {
+		dma_free_coherent(dev, PAGE_SIZE, dma->pc_tx_virt,
+				  dma->pc_tx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->pc_rx_virt,
+				  dma->pc_rx_addr);
+		dma_free_coherent(dev, PAGE_SIZE, dma->np_tx_virt,
+				  dma->np_tx_addr);
+	}
+
+	mutex_destroy(&espi_perif->pc_tx_mtx);
+	mutex_destroy(&espi_perif->np_tx_mtx);
+
+	misc_deregister(&espi_perif->mdev);
+}
diff --git a/drivers/soc/aspeed/aspeed-espi-perif.h b/drivers/soc/aspeed/aspeed-espi-perif.h
new file mode 100644
index 000000000000..1b964e4680f5
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-perif.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_PERIF_H_
+#define _ASPEED_ESPI_PERIF_H_
+
+struct aspeed_espi_perif_dma {
+	void *pc_tx_virt;
+	dma_addr_t pc_tx_addr;
+	void *pc_rx_virt;
+	dma_addr_t pc_rx_addr;
+	void *np_tx_virt;
+	dma_addr_t np_tx_addr;
+};
+
+struct aspeed_espi_perif {
+	uint32_t mcyc_enable;
+	void *mcyc_virt;
+	uint32_t mcyc_saddr;
+	phys_addr_t mcyc_taddr;
+	uint32_t mcyc_size;
+	uint32_t mcyc_mask;
+
+	uint32_t dma_mode;
+	struct aspeed_espi_perif_dma dma;
+
+	uint32_t rx_ready;
+	wait_queue_head_t wq;
+
+	spinlock_t lock;
+	struct mutex pc_rx_mtx;
+	struct mutex pc_tx_mtx;
+	struct mutex np_tx_mtx;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+void aspeed_espi_perif_event(uint32_t sts, struct aspeed_espi_perif *espi_perif);
+void aspeed_espi_perif_enable(struct aspeed_espi_perif *espi_perif);
+void *aspeed_espi_perif_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl);
+void aspeed_espi_perif_free(struct device *dev, struct aspeed_espi_perif *espi_perif);
+
+#endif
diff --git a/drivers/soc/aspeed/aspeed-espi-vw.c b/drivers/soc/aspeed/aspeed-espi-vw.c
new file mode 100644
index 000000000000..819b3ae2f7ea
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-vw.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ */
+#include <linux/fs.h>
+#include <linux/of_device.h>
+#include <linux/miscdevice.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+
+#include "aspeed-espi-ioc.h"
+#include "aspeed-espi-ctrl.h"
+#include "aspeed-espi-vw.h"
+
+#define VW_MDEV_NAME	"aspeed-espi-vw"
+
+static long aspeed_espi_vw_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+	uint32_t val;
+
+	struct aspeed_espi_vw *espi_vw = container_of(fp->private_data,
+						      struct aspeed_espi_vw,
+						      mdev);
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	switch (cmd) {
+	case ASPEED_ESPI_VW_GET_GPIO_VAL:
+		regmap_read(espi_ctrl->map, ESPI_VW_GPIO_VAL, &val);
+		if (put_user(val, (uint32_t __user *)arg))
+			return -EFAULT;
+		break;
+
+	case ASPEED_ESPI_VW_PUT_GPIO_VAL:
+		if (get_user(val, (uint32_t __user *)arg))
+			return -EFAULT;
+		regmap_write(espi_ctrl->map, ESPI_VW_GPIO_VAL, val);
+		break;
+
+	default:
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
+void aspeed_espi_vw_event(uint32_t sts, struct aspeed_espi_vw *espi_vw)
+{
+	uint32_t sysevt_sts;
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	regmap_read(espi_ctrl->map, ESPI_INT_STS, &sts);
+
+	if (sts & ESPI_INT_STS_VW_SYSEVT) {
+		regmap_read(espi_ctrl->map, ESPI_SYSEVT_INT_STS, &sysevt_sts);
+
+		if (espi_ctrl->model->version == ESPI_AST2500) {
+			if (sysevt_sts & ESPI_SYSEVT_INT_STS_HOST_RST_WARN)
+				regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+						   ESPI_SYSEVT_HOST_RST_ACK,
+						   ESPI_SYSEVT_HOST_RST_ACK);
+
+			if (sysevt_sts & ESPI_SYSEVT_INT_STS_OOB_RST_WARN)
+				regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT,
+						   ESPI_SYSEVT_OOB_RST_ACK,
+						   ESPI_SYSEVT_OOB_RST_ACK);
+		}
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT_INT_STS, sysevt_sts);
+	}
+
+	if (sts & ESPI_INT_STS_VW_SYSEVT1) {
+		regmap_read(espi_ctrl->map, ESPI_SYSEVT1_INT_STS, &sysevt_sts);
+
+		if (sysevt_sts & ESPI_SYSEVT1_INT_STS_SUSPEND_WARN)
+			regmap_update_bits(espi_ctrl->map, ESPI_SYSEVT1,
+					   ESPI_SYSEVT1_SUSPEND_ACK,
+					   ESPI_SYSEVT1_SUSPEND_ACK);
+
+		regmap_write(espi_ctrl->map, ESPI_SYSEVT1_INT_STS, sysevt_sts);
+	}
+}
+
+void aspeed_espi_vw_enable(struct aspeed_espi_vw *espi_vw)
+{
+	struct aspeed_espi_ctrl *espi_ctrl = espi_vw->ctrl;
+
+	regmap_write(espi_ctrl->map, ESPI_INT_STS,
+		     ESPI_INT_STS_VW_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_INT_EN,
+			   ESPI_INT_EN_VW_BITS,
+			   ESPI_INT_EN_VW_BITS);
+
+	regmap_update_bits(espi_ctrl->map, ESPI_CTRL,
+			   ESPI_CTRL_VW_SW_RDY,
+			   ESPI_CTRL_VW_SW_RDY);
+}
+
+static const struct file_operations aspeed_espi_vw_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = aspeed_espi_vw_ioctl,
+};
+
+void *aspeed_espi_vw_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl)
+{
+	int rc;
+	struct aspeed_espi_vw *espi_vw;
+
+	espi_vw = devm_kzalloc(dev, sizeof(*espi_vw), GFP_KERNEL);
+	if (!espi_vw)
+		return ERR_PTR(-ENOMEM);
+
+	espi_vw->ctrl = espi_ctrl;
+
+	espi_vw->mdev.parent = dev;
+	espi_vw->mdev.minor = MISC_DYNAMIC_MINOR;
+	espi_vw->mdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s", VW_MDEV_NAME);
+	espi_vw->mdev.fops = &aspeed_espi_vw_fops;
+	rc = misc_register(&espi_vw->mdev);
+	if (rc) {
+		dev_err(dev, "cannot register device\n");
+		return ERR_PTR(rc);
+	}
+
+	aspeed_espi_vw_enable(espi_vw);
+
+	return espi_vw;
+}
+
+void aspeed_espi_vw_free(struct device *dev, struct aspeed_espi_vw *espi_vw)
+{
+	misc_deregister(&espi_vw->mdev);
+}
diff --git a/drivers/soc/aspeed/aspeed-espi-vw.h b/drivers/soc/aspeed/aspeed-espi-vw.h
new file mode 100644
index 000000000000..aba9c414ac1b
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-espi-vw.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2021 ASPEED Technology Inc.
+ */
+#ifndef _ASPEED_ESPI_VW_H_
+#define _ASPEED_ESPI_VW_H_
+
+struct aspeed_espi_vw {
+	int irq;
+	int irq_reset;
+
+	struct miscdevice mdev;
+	struct aspeed_espi_ctrl *ctrl;
+};
+
+void aspeed_espi_vw_event(uint32_t sts, struct aspeed_espi_vw *espi_vw);
+void aspeed_espi_vw_enable(struct aspeed_espi_vw *espi_vw);
+void *aspeed_espi_vw_alloc(struct device *dev, struct aspeed_espi_ctrl *espi_ctrl);
+void aspeed_espi_vw_free(struct device *dev, struct aspeed_espi_vw *espi_vw);
+
+#endif
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Tue Aug 31 20:30:12 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Wed, 1 Sep 2021 11:30:12 +0800
Subject: [PATCH v4 1/4] dt-bindings: aspeed: Add eSPI controller
In-Reply-To: <20210901033015.910-1-chiawei_wang@aspeedtech.com>
References: <20210901033015.910-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210901033015.910-2-chiawei_wang@aspeedtech.com>

Add dt-bindings for Aspeed eSPI controller

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 .../devicetree/bindings/soc/aspeed/espi.yaml  | 162 ++++++++++++++++++
 1 file changed, 162 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/aspeed/espi.yaml

diff --git a/Documentation/devicetree/bindings/soc/aspeed/espi.yaml b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
new file mode 100644
index 000000000000..aa91ec8caf6a
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/aspeed/espi.yaml
@@ -0,0 +1,162 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# # Copyright (c) 2021 Aspeed Technology Inc.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/soc/aspeed/espi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Aspeed eSPI Controller
+
+maintainers:
+  - Chia-Wei Wang <chiawei_wang at aspeedtech.com>
+  - Ryan Chen <ryan_chen at aspeedtech.com>
+
+description:
+  Aspeed eSPI controller implements a slave side eSPI endpoint device
+  supporting the four eSPI channels, namely peripheral, virtual wire,
+  out-of-band, and flash.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - aspeed,ast2500-espi
+          - aspeed,ast2600-espi
+      - const: simple-mfd
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^espi-ctrl@[0-9a-f]+$":
+    type: object
+
+    description: Control of the four basic eSPI channels
+
+    properties:
+      compatible:
+        items:
+          - enum:
+              - aspeed,ast2500-espi-ctrl
+              - aspeed,ast2600-espi-ctrl
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      perif,memcyc-enable:
+        type: boolean
+        description: Enable memory cycle over eSPI peripheral channel
+
+      perif,memcyc-src-addr:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: The Host side address to be decoded into the memory cycle over eSPI peripheral channel
+
+      perif,memcyc-size:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: The size of the memory region allocated for the memory cycle over eSPI peripheral channel
+        minimum: 65536
+
+      perif,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI peripheral channel
+
+      oob,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI out-of-band channel
+
+      oob,dma-tx-desc-num:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 2
+        maximum: 1023
+        description: The number of TX descriptors available for eSPI OOB DMA engine
+
+      oob,dma-rx-desc-num:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 2
+        maximum: 1023
+        description: The number of RX descriptors available for eSPI OOB DMA engine
+
+      flash,dma-mode:
+        type: boolean
+        description: Enable DMA support for eSPI flash channel
+
+      flash,safs-mode:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [ 0, 1, 2 ]
+        default: 0
+        description: Slave-Attached-Sharing-Flash mode, 0->Mix, 1->SW, 2->HW
+
+    dependencies:
+      perif,memcyc-src-addr: [ "perif,memcyc-enable" ]
+      perif,memcyc-size: [ "perif,memcyc-enable" ]
+      oob,dma-tx-desc-num: [ "oob,dma-mode" ]
+      oob,dma-rx-desc-num: [ "oob,dma-mode" ]
+
+    required:
+      - compatible
+      - interrupts
+      - clocks
+
+  "^espi-mmbi@[0-9a-f]+$":
+    type: object
+
+    description: Control of the PCH-BMC data exchange over eSPI peripheral memory cycle
+
+    properties:
+      compatible:
+        const: aspeed,ast2600-espi-mmbi
+
+      interrupts:
+        maxItems: 1
+
+    required:
+      - compatible
+      - interrupts
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+
+    espi: espi at 1e6ee000 {
+        compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
+        reg = <0x1e6ee000 0x1000>;
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0x0 0x1e6ee000 0x1000>;
+
+        espi_ctrl: espi-ctrl at 0 {
+            compatible = "aspeed,ast2600-espi-ctrl";
+            reg = <0x0 0x800>;
+            interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
+        };
+
+        espi_mmbi: espi-mmbi at 800 {
+            compatible = "aspeed,ast2600-espi-mmbi";
+            reg = <0x800 0x50>;
+            interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+        };
+    };
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Tue Aug 31 20:30:15 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Wed, 1 Sep 2021 11:30:15 +0800
Subject: [PATCH v4 4/4] ARM: dts: aspeed: Add eSPI node
In-Reply-To: <20210901033015.910-1-chiawei_wang@aspeedtech.com>
References: <20210901033015.910-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210901033015.910-5-chiawei_wang@aspeedtech.com>

Add eSPI to the device tree for Aspeed 5/6th generation SoCs.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 arch/arm/boot/dts/aspeed-g6.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index f96607b7b4e2..47dc0b3993d1 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -364,6 +364,23 @@
 				status = "disabled";
 			};
 
+			espi: espi at 1e6ee000 {
+				compatible = "aspeed,ast2600-espi", "simple-mfd", "syscon";
+				reg = <0x1e6ee000 0x1000>;
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x0 0x1e6ee000 0x1000>;
+
+				espi_ctrl: espi-ctrl at 0 {
+					compatible = "aspeed,ast2600-espi-ctrl";
+					reg = <0x0 0x800>;
+					interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+					clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>;
+					status = "disabled";
+				};
+			};
+
 			gpio0: gpio at 1e780000 {
 				#gpio-cells = <2>;
 				gpio-controller;
-- 
2.17.1



From neal_liu at aspeedtech.com  Tue Aug 31 20:45:43 2021
From: neal_liu at aspeedtech.com (neal_liu)
Date: Wed, 1 Sep 2021 11:45:43 +0800
Subject: [PATCH] usb: ehci: handshake CMD_RUN instead of STS_HALT
Message-ID: <20210901034543.10675-1-neal_liu@aspeedtech.com>

For Aspeed, HCHalted status depends on not only Run/Stop but also
ASS/PSS status.
Handshake CMD_RUN on startup instead.

Signed-off-by: neal_liu <neal_liu at aspeedtech.com>
---
 drivers/usb/host/ehci-hcd.c      | 11 ++++++++++-
 drivers/usb/host/ehci-platform.c |  6 ++++++
 drivers/usb/host/ehci.h          |  1 +
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 10b0365f3439..01c022e46aa2 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -634,7 +634,16 @@ static int ehci_run (struct usb_hcd *hcd)
 	/* Wait until HC become operational */
 	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
 	msleep(5);
-	rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000);
+
+	/* For Aspeed, STS_HALT also depends on ASS/PSS status.
+	 * Skip this check on startup.
+	 */
+	if (ehci->is_aspeed)
+		rc = ehci_handshake(ehci, &ehci->regs->command, CMD_RUN,
+				    1, 100 * 1000);
+	else
+		rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT,
+				    0, 100 * 1000);
 
 	up_write(&ehci_cf_port_reset_rwsem);
 
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index c70f2d0b4aaf..c3dc906274d9 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -297,6 +297,12 @@ static int ehci_platform_probe(struct platform_device *dev)
 					  "has-transaction-translator"))
 			hcd->has_tt = 1;
 
+		if (of_device_is_compatible(dev->dev.of_node,
+					    "aspeed,ast2500-ehci") ||
+		    of_device_is_compatible(dev->dev.of_node,
+					    "aspeed,ast2600-ehci"))
+			ehci->is_aspeed = 1;
+
 		if (soc_device_match(quirk_poll_match))
 			priv->quirk_poll = true;
 
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 80bb823aa9fe..fdd073cc053b 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -219,6 +219,7 @@ struct ehci_hcd {			/* one per controller */
 	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */
 	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */
 	unsigned		spurious_oc:1;
+	unsigned		is_aspeed:1;
 
 	/* required for usb32 quirk */
 	#define OHCI_CTRL_HCFS          (3 << 6)
-- 
2.17.1



From trevor.wu at mediatek.com  Tue Aug 31 20:48:27 2021
From: trevor.wu at mediatek.com (Trevor Wu)
Date: Wed, 1 Sep 2021 11:48:27 +0800
Subject: [PATCH] ASoC: mediatek: SND_SOC_MT8195 should depend on
 ARCH_MEDIATEK
In-Reply-To: <7e628e359bde04ceb9ddd74a45931059b4a4623c.1630415860.git.geert+renesas@glider.be>
References: <7e628e359bde04ceb9ddd74a45931059b4a4623c.1630415860.git.geert+renesas@glider.be>
Message-ID: <535478691c3a9ed31b508f59dc897be57c4213c0.camel@mediatek.com>

On Tue, 2021-08-31 at 15:18 +0200, Geert Uytterhoeven wrote:
> The Mediatek MT8195 sound hardware is only present on Mediatek MT8195
> SoCs.  Hence add a dependency on ARCH_MEDIATEK, to prevent asking the
> user about this driver when configuring a kernel without Mediatek SoC
> support.
> 
> Fixes: 6746cc858259985a ("ASoC: mediatek: mt8195: add platform
> driver")
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
>  sound/soc/mediatek/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
> index cf567a89f421b4c0..c8c815f599da90bf 100644
> --- a/sound/soc/mediatek/Kconfig
> +++ b/sound/soc/mediatek/Kconfig
> @@ -187,6 +187,7 @@ config SND_SOC_MT8192_MT6359_RT1015_RT5682
>  
>  config SND_SOC_MT8195
>  	tristate "ASoC support for Mediatek MT8195 chip"
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
>  	select SND_SOC_MEDIATEK
>  	help
>  	  This adds ASoC platform driver support for Mediatek MT8195
> chip

Hi Geert,

Thanks for your patch first.
I really missed the dependency declaration.
But we only test "depends on ARCH_MEDIATEK" internally, maybe removing
"COMPILE_TEST" like other MTK series is better for the maintenance in
the future.

Thanks,
Trevor

From neal_liu at aspeedtech.com  Tue Aug 31 20:50:41 2021
From: neal_liu at aspeedtech.com (neal_liu)
Date: Wed, 1 Sep 2021 11:50:41 +0800
Subject: [PATCH v2] usb: ehci: handshake CMD_RUN instead of STS_HALT
Message-ID: <20210901035041.10810-1-neal_liu@aspeedtech.com>

Retitle.

For Aspeed, HCHalted status depends on not only Run/Stop but also
ASS/PSS status.
Handshake CMD_RUN on startup instead.

Signed-off-by: neal_liu <neal_liu at aspeedtech.com>
---
 drivers/usb/host/ehci-hcd.c      | 11 ++++++++++-
 drivers/usb/host/ehci-platform.c |  6 ++++++
 drivers/usb/host/ehci.h          |  1 +
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 10b0365f3439..01c022e46aa2 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -634,7 +634,16 @@ static int ehci_run (struct usb_hcd *hcd)
 	/* Wait until HC become operational */
 	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
 	msleep(5);
-	rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000);
+
+	/* For Aspeed, STS_HALT also depends on ASS/PSS status.
+	 * Skip this check on startup.
+	 */
+	if (ehci->is_aspeed)
+		rc = ehci_handshake(ehci, &ehci->regs->command, CMD_RUN,
+				    1, 100 * 1000);
+	else
+		rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT,
+				    0, 100 * 1000);
 
 	up_write(&ehci_cf_port_reset_rwsem);
 
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index c70f2d0b4aaf..c3dc906274d9 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -297,6 +297,12 @@ static int ehci_platform_probe(struct platform_device *dev)
 					  "has-transaction-translator"))
 			hcd->has_tt = 1;
 
+		if (of_device_is_compatible(dev->dev.of_node,
+					    "aspeed,ast2500-ehci") ||
+		    of_device_is_compatible(dev->dev.of_node,
+					    "aspeed,ast2600-ehci"))
+			ehci->is_aspeed = 1;
+
 		if (soc_device_match(quirk_poll_match))
 			priv->quirk_poll = true;
 
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 80bb823aa9fe..fdd073cc053b 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -219,6 +219,7 @@ struct ehci_hcd {			/* one per controller */
 	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */
 	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */
 	unsigned		spurious_oc:1;
+	unsigned		is_aspeed:1;
 
 	/* required for usb32 quirk */
 	#define OHCI_CTRL_HCFS          (3 << 6)
-- 
2.17.1



From yunfei.dong at mediatek.com  Tue Aug 31 20:49:14 2021
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Wed, 1 Sep 2021 11:49:14 +0800
Subject: [PATCH v5, 13/15] dt-bindings: media: mtk-vcodec: Adds decoder
 dt-bindings for mt8192
In-Reply-To: <CAAEAJfB_qZtVpxk8P=26GkZ1j66v+RzzJTqf3UrfMkWNJ1fmFg@mail.gmail.com>
References: <20210811025801.21597-1-yunfei.dong@mediatek.com>
 <20210811025801.21597-14-yunfei.dong@mediatek.com>
 <YRQQBL8AN0925zj9@pendragon.ideasonboard.com>
 <952c219de7595f7f814d3006fbe25b8089a35212.camel@mediatek.com>
 <CAAEAJfB_qZtVpxk8P=26GkZ1j66v+RzzJTqf3UrfMkWNJ1fmFg@mail.gmail.com>
Message-ID: <fb85e6287a0d269593fa72d745dc2c573bcfe7bc.camel@mediatek.com>

Hi Ezequiel,

Thanks for your feedback.
On Sun, 2021-08-29 at 17:54 -0300, Ezequiel Garcia wrote:
> On Tue, 17 Aug 2021 at 00:52, yunfei.dong at mediatek.com
> <yunfei.dong at mediatek.com> wrote:
> > 
> > Hi Laurent,
> > 
> > Thanks for your detail suggestion.
> > 
> > On Wed, 2021-08-11 at 20:59 +0300, Laurent Pinchart wrote:
> > > Hi Yunfei,
> > > 
> > > Thank you for the patch.
> > > 
> > > On Wed, Aug 11, 2021 at 10:57:59AM +0800, Yunfei Dong wrote:
> > > > Adds decoder dt-bindings for mt8192.
> > > > 
> > > > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> > > > ---
> > > > v5: no changes
> > > > 
> > > > This patch depends on "Mediatek MT8192 clock support"[1].
> > > > 
> > > > The definition of decoder clocks are in mt8192-clk.h, need to
> > > > include them in case of build fail [1].
> > > > 
> > > > [1]
> > > > 
https://patchwork.kernel.org/project/linux-mediatek/list/?series=511175
> > > > ---
> > > >  .../media/mediatek,vcodec-comp-decoder.yaml   | 172
> > > > ++++++++++++++++++
> > > >  1 file changed, 172 insertions(+)
> > > >  create mode 100644
> > > > Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > > decoder.yaml
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > > decoder.yaml
> > > > b/Documentation/devicetree/bindings/media/mediatek,vcodec-comp-
> > > > decoder.yaml
> > > > new file mode 100644
> > > > index 000000000000..083c89933917
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-
> > > > comp-
> > > > decoder.yaml
> > > > @@ -0,0 +1,172 @@
> > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > > +%YAML 1.2
> > > > +---
> > > > +$id:
> > > > 
http://devicetree.org/schemas/iommu/mediatek,vcodec-comp-decoder.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Mediatek Video Decode Accelerator With Component
> > > > +
> > > > +maintainers:
> > > > +  - Yunfei Dong <yunfei.dong at mediatek.com>
> > > > +
> > > > +description: |+
> > > > +  Mediatek Video Decode is the video decode hardware present
> > > > in
> > > > Mediatek
> > > > +  SoCs which supports high resolution decoding
> > > > functionalities.
> > > > Required
> > > > +  master and component node.
> > > 
> > > This should explain how the three IP cores relate to each other.
> > > 
> > 
> > I will explain it in next patch.
> > > > +
> > > > +properties:
> > > > +  compatible:
> > > > +    oneOf:
> > > > +      - enum:
> > > > +          - mediatek,mt8192-vcodec-dec  # for lat hardware
> > > > +          - mediatek,mtk-vcodec-lat     # for core hardware
> > > > +          - mediatek,mtk-vcodec-core
> > > > +
> > > > +  reg:
> > > > +    maxItems: 1
> > > > +
> > > > +  interrupts:
> > > > +    maxItems: 1
> > > > +
> > > > +  clocks:
> > > > +    maxItems: 5
> > > > +
> > > > +  clock-names:
> > > > +    items:
> > > > +      - const: vdec-sel
> > > > +      - const: vdec-soc-vdec
> > > > +      - const: vdec-soc-lat
> > > > +      - const: vdec-vdec
> > > > +      - const: vdec-top
> > > > +
> > > > +  assigned-clocks: true
> > > > +
> > > > +  assigned-clock-parents: true
> > > > +
> > > > +  power-domains:
> > > > +    maxItems: 1
> > > > +
> > > > +  iommus:
> > > > +    minItems: 1
> > > > +    maxItems: 32
> > > > +    description: |
> > > > +      List of the hardware port in respective IOMMU block for
> > > > current Socs.
> > > > +      Refer to bindings/iommu/mediatek,iommu.yaml.
> > > > +
> > > > +  dma-ranges:
> > > > +    maxItems: 1
> > > > +    description: |
> > > > +      Describes the physical address space of IOMMU maps to
> > > > memory.
> > > > +
> > > > +  mediatek,scp:
> > > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > > +    maxItems: 1
> > > > +    description:
> > > > +      Describes point to scp.
> > > > +
> > > > +required:
> > > > +      - compatible
> > > > +      - reg
> > > > +      - iommus
> > > > +      - dma-ranges
> > > > +
> > > > +allOf:
> > > > +  - if: #master node
> > > > +      properties:
> > > > +        compatible:
> > > > +          contains:
> > > > +            enum:
> > > > +              - mediatek,mt8192-vcodec-dec  # for lat hardware
> > > > +
> > > > +    then:
> > > > +      required:
> > > > +        - mediatek,scp
> > > > +
> > > > +  - if: #component node
> > > > +      properties:
> > > > +        compatible:
> > > > +          contains:
> > > > +            enum:
> > > > +              - mediatek,mtk-vcodec-lat     # for core
> > > > hardware
> > > > +              - mediatek,mtk-vcodec-core
> > > > +
> > > > +    then:
> > > > +      required:
> > > > +        - interrupts
> > > > +        - clocks
> > > > +        - clock-names
> > > > +        - assigned-clocks
> > > > +        - assigned-clock-parents
> > > > +        - power-domains
> > > > +
> > > > +
> > > > +additionalProperties: false
> > > > +
> > > > +examples:
> > > > +  - |
> > > > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > > > +    #include <dt-bindings/memory/mt8192-larb-port.h>
> > > > +    #include <dt-bindings/interrupt-controller/irq.h>
> > > > +    #include <dt-bindings/clock/mt8192-clk.h>
> > > > +    #include <dt-bindings/power/mt8192-power.h>
> > > > +
> > > > +    vcodec_dec: vcodec_dec at 16000000 {
> > > > +        compatible = "mediatek,mt8192-vcodec-dec";
> > > > +        reg = <0 0x16000000 0 0x1000>;             /* VDEC_SYS
> > > > */
> > > > +        mediatek,scp = <&scp>;
> > > > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
> > > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > > +    };
> > > > +
> > > > +    vcodec_lat: vcodec_lat at 0x16010000 {
> > > > +        compatible = "mediatek,mtk-vcodec-lat";
> > > > +        reg = <0 0x16010000 0 0x800>;              /*
> > > > VDEC_MISC */
> > > > +        interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
> > > > +        iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
> > > > +             <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
> > > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > > > +             <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
> > > > +             <&vdecsys_soc CLK_VDEC_SOC_LAT>,
> > > > +             <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
> > > > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > > > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-
> > > > lat",
> > > > +              "vdec-vdec", "vdec-top";
> > > > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > > > +        assigned-clock-parents = <&topckgen
> > > > CLK_TOP_MAINPLL_D4>;
> > > > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
> > > > +    };
> > > > +
> > > > +    vcodec_core: vcodec_core at 0x16025000 {
> > > > +        compatible = "mediatek,mtk-vcodec-core";
> > > > +        reg = <0 0x16025000 0 0x1000>;             /*
> > > > VDEC_CORE_MISC */
> > > > +        interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
> > > > +        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
> > > > +             <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
> > > > +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> > > > +        clocks = <&topckgen CLK_TOP_VDEC_SEL>,
> > > > +             <&vdecsys CLK_VDEC_VDEC>,
> > > > +             <&vdecsys CLK_VDEC_LAT>,
> > > > +             <&vdecsys CLK_VDEC_LARB1>,
> > > > +             <&topckgen CLK_TOP_MAINPLL_D4>;
> > > > +        clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-
> > > > lat",
> > > > +              "vdec-vdec", "vdec-top";
> > > > +        assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
> > > > +        assigned-clock-parents = <&topckgen
> > > > CLK_TOP_MAINPLL_D4>;
> > > > +        power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
> > > > +    };
> > > 
> > > I'm a bit late in the game, reviewing v5 only, but I'm wondering
> > > if
> > > those IP cores need to be modelled in separate nodes. It would be
> > > much
> > > easier, from a software point of view, to have a single node,
> > > with
> > > multiple register ranges.
> > > 
> > > Are some of those IP cores used in different SoCs, combined in
> > > different
> > > ways, that make a modular design better ?
> > > 
> > 
> > Different platform has different hardware, for mt8192 only has
> > three
> > nodes. but mt8195 will has five nodes. and the clk/power/irq/iommu
> > are
> > different. It is not easy to manage all hardware at the same time
> > in
> > one node, need to enable different hardware at the same time, the
> > logic
> > will be very complex.
> > It is much easier to handle different hardware using component,
> > enable
> > different hardware when we need it.
> > 
> > 
> 
> You can still have one device-tree node for each device, which means
> you can still manage your resources (clk/power/irq/iommu) easily, but
> doing
> this so that it avoids an async framework to pull the parts together.
> 
It mean that v4l2 async also can't be used?
> I gave you this feedback several times, and you have been objecting
> it
> every time  without even trying to consider a different approach.
> 
I'm not objecting your suggestion every time, for our driver is
designed for component api, need to spend a lot of time to change it in
many platforms. We need to get a final solution for this architecture,
or it's not easy to change all patches in the feature.
> Thanks,
> Ezequiel
1. Each a node should respect a HW node. Defining a complex node that
contain multiple register is not better, for they belong to different
hardware. Different platforms has different hardware count, mt8195 has
five hardwares.
2. Another reason is from the IOMMU point, the vcodec HW include core
and lat hardwares, each of them connect to the independent IOMMU
hardware for mt8195, can't write all iommu ports together, or hardware
can't access dram data, so we must separate them.

For these limitation, can't combine all hardware together. I will write
the hardware diagram in next patch.

Thanks,
Yunfei Dong

From neal_liu at aspeedtech.com  Tue Aug 31 19:34:32 2021
From: neal_liu at aspeedtech.com (Neal Liu)
Date: Wed, 1 Sep 2021 02:34:32 +0000
Subject: [PATCH] usb: host: ehci: skip STS_HALT check for aspeed platform
In-Reply-To: <20210826152824.GC228824@rowland.harvard.edu>
References: <20210826071525.27651-1-neal_liu@aspeedtech.com>
 <20210826152824.GC228824@rowland.harvard.edu>
Message-ID: <HK0PR06MB32025ED058C0461FDC5BFBBB80CD9@HK0PR06MB3202.apcprd06.prod.outlook.com>

> -----Original Message-----
> From: Alan Stern <stern at rowland.harvard.edu>
> Sent: Thursday, August 26, 2021 11:28 PM
> To: Neal Liu <neal_liu at aspeedtech.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>; Tony Prisk
> <linux at prisktech.co.nz>; linux-usb at vger.kernel.org;
> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Tao Ren
> <rentao.bupt at gmail.com>; BMC-SW <BMC-SW at aspeedtech.com>
> Subject: Re: [PATCH] usb: host: ehci: skip STS_HALT check for aspeed platform
> 
> On Thu, Aug 26, 2021 at 03:15:25PM +0800, neal_liu wrote:
> > STS_HALT also depends on ASS/PSS status for apseed.
> > Skip this check on startup.
> >
> > Signed-off-by: neal_liu <neal_liu at aspeedtech.com>
> > ---
> >  drivers/usb/host/ehci-hcd.c      | 10 +++++++++-
> >  drivers/usb/host/ehci-platform.c |  6 ++++++
> >  drivers/usb/host/ehci.h          |  1 +
> >  3 files changed, 16 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> > index 10b0365f3439..a539e11502ef 100644
> > --- a/drivers/usb/host/ehci-hcd.c
> > +++ b/drivers/usb/host/ehci-hcd.c
> > @@ -634,7 +634,15 @@ static int ehci_run (struct usb_hcd *hcd)
> >  	/* Wait until HC become operational */
> >  	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
> >  	msleep(5);
> > -	rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000);
> > +
> > +	/* For Aspeed, STS_HALT also depends on ASS/PSS status.
> > +	 * Skip this check on startup.
> > +	 */
> > +	if (ehci->is_aspeed)
> > +		rc = 0;
> > +	else
> > +		rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT,
> > +				    0, 100 * 1000);
> 
> You must not do this.  You are assuming the controller will always begin
> operating within 5 ms of the time it is told to start.  What happens if you are
> wrong?
> 
> There must be some way for the aspeed controller's host computer to tell
> when the controller has started running.  Find out what it is and use it.
> 
> Alan Stern

We can check the command RS bit to tell the controller has started running.
I'll sent next patch within this change.
Thanks

-Neal Liu


From sfr at canb.auug.org.au  Tue Aug 31 21:22:55 2021
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Wed, 1 Sep 2021 14:22:55 +1000
Subject: linux-next: manual merge of the vhost tree with the arm-soc and
 Linus' trees
Message-ID: <20210901142255.1189dd71@canb.auug.org.au>

Hi all,

Today's linux-next merge of the vhost tree got a conflict in:

  include/uapi/linux/virtio_ids.h

between commits:

  46abe13b5e3d ("firmware: arm_scmi: Add virtio transport")
  3cfc88380413 ("i2c: virtio: add a virtio i2c frontend driver")

from the arm-soc and Linus' trees and commit:

  df2fd4361a56 ("uapi: virtio_ids: Sync ids with specification")

from the vhost tree.

I fixed it up (the latter included the changes form the former commits,
so I juts used that) and can carry the fix as necessary. This is now
fixed as far as linux-next is concerned, but any non trivial conflicts
should be mentioned to your upstream maintainer when your tree is
submitted for merging.  You may also want to consider cooperating with
the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20210901/c96adb7b/attachment.sig>

From wenst at chromium.org  Tue Aug 31 21:35:43 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 1 Sep 2021 12:35:43 +0800
Subject: [PATCH v11 1/4] dt-bindings: pinctrl: mt8195: add rsel define
In-Reply-To: <20210830003603.31864-2-zhiyong.tao@mediatek.com>
References: <20210830003603.31864-1-zhiyong.tao@mediatek.com>
 <20210830003603.31864-2-zhiyong.tao@mediatek.com>
Message-ID: <CAGXv+5HeNj2Ly-T1bWMvnYXv6nP-Q1kv+D9QEd+5u4xfNVibOg@mail.gmail.com>

On Mon, Aug 30, 2021 at 8:36 AM Zhiyong Tao <zhiyong.tao at mediatek.com> wrote:
>
> This patch adds rsel define for mt8195.
>
> Signed-off-by: Zhiyong Tao <zhiyong.tao at mediatek.com>
> ---
>  include/dt-bindings/pinctrl/mt65xx.h | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/include/dt-bindings/pinctrl/mt65xx.h b/include/dt-bindings/pinctrl/mt65xx.h
> index 7e16e58fe1f7..f5934abcd1bd 100644
> --- a/include/dt-bindings/pinctrl/mt65xx.h
> +++ b/include/dt-bindings/pinctrl/mt65xx.h
> @@ -16,6 +16,15 @@
>  #define MTK_PUPD_SET_R1R0_10 102
>  #define MTK_PUPD_SET_R1R0_11 103
>
> +#define MTK_PULL_SET_RSEL_000  200
> +#define MTK_PULL_SET_RSEL_001  201
> +#define MTK_PULL_SET_RSEL_010  202
> +#define MTK_PULL_SET_RSEL_011  203
> +#define MTK_PULL_SET_RSEL_100  204
> +#define MTK_PULL_SET_RSEL_101  205
> +#define MTK_PULL_SET_RSEL_110  206
> +#define MTK_PULL_SET_RSEL_111  207

Could you keep the spacing between constants tighter, or have no spacing
at all? Like having MTK_PULL_SET_RSEL_000 defined as 104 and so on. This
would reduce the chance of new macro values colliding with actual resistor
values set in the datasheets, plus a contiguous space would be easy to
rule as macros.

ChenYu

>  #define MTK_DRIVE_2mA  2
>  #define MTK_DRIVE_4mA  4
>  #define MTK_DRIVE_6mA  6
> --
> 2.18.0
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From samuel at sholland.org  Tue Aug 31 22:05:21 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:21 -0500
Subject: [PATCH 3/8] clk: sunxi-ng: Use a separate lock for each CCU instance
In-Reply-To: <20210901050526.45673-1-samuel@sholland.org>
References: <20210901050526.45673-1-samuel@sholland.org>
Message-ID: <20210901050526.45673-4-samuel@sholland.org>

Some platforms have more than one CCU driver loaded: the main CCU, the
PRCM, the display engine, and possibly others. All of these hardware
blocks have separate MMIO spaces, so there is no need to synchronize
between them.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/ccu_common.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c
index 88cb569e5835..31af8b6b5286 100644
--- a/drivers/clk/sunxi-ng/ccu_common.c
+++ b/drivers/clk/sunxi-ng/ccu_common.c
@@ -17,11 +17,10 @@
 
 struct sunxi_ccu {
 	const struct sunxi_ccu_desc	*desc;
+	spinlock_t			lock;
 	struct ccu_reset		reset;
 };
 
-static DEFINE_SPINLOCK(ccu_lock);
-
 void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
 {
 	void __iomem *addr;
@@ -94,6 +93,8 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 
 	ccu->desc = desc;
 
+	spin_lock_init(&ccu->lock);
+
 	for (i = 0; i < desc->num_ccu_clks; i++) {
 		struct ccu_common *cclk = desc->ccu_clks[i];
 
@@ -101,7 +102,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 			continue;
 
 		cclk->base = reg;
-		cclk->lock = &ccu_lock;
+		cclk->lock = &ccu->lock;
 	}
 
 	for (i = 0; i < desc->hw_clks->num ; i++) {
@@ -133,7 +134,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 	reset->rcdev.owner = dev ? dev->driver->owner : THIS_MODULE;
 	reset->rcdev.nr_resets = desc->num_resets;
 	reset->base = reg;
-	reset->lock = &ccu_lock;
+	reset->lock = &ccu->lock;
 	reset->reset_map = desc->resets;
 
 	ret = reset_controller_register(&reset->rcdev);
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:05:20 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:20 -0500
Subject: [PATCH 2/8] clk: sunxi-ng: Prevent unbinding CCUs via sysfs
In-Reply-To: <20210901050526.45673-1-samuel@sholland.org>
References: <20210901050526.45673-1-samuel@sholland.org>
Message-ID: <20210901050526.45673-3-samuel@sholland.org>

The CCU drivers are not really designed to be unbound. Unbinding a SoC's
main CCU is especially pointless, as very few of the peripherals on the
SoC will work without it. Let's avoid any potential problems by removing
the bind/unbind attributes from sysfs for these drivers.

This change is not applied to the "secondary" CCUs (DE, USB) as those
could reasonably be unbound without making the system useless.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c | 1 +
 drivers/clk/sunxi-ng/ccu-sun50i-a100.c   | 1 +
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c    | 1 +
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c     | 1 +
 drivers/clk/sunxi-ng/ccu-sun8i-a83t.c    | 1 +
 drivers/clk/sunxi-ng/ccu-sun8i-r40.c     | 1 +
 drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c  | 1 +
 drivers/clk/sunxi-ng/ccu-sun9i-a80.c     | 1 +
 8 files changed, 8 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
index 6f2a58970556..804729e0a208 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
@@ -208,6 +208,7 @@ static struct platform_driver sun50i_a100_r_ccu_driver = {
 	.probe	= sun50i_a100_r_ccu_probe,
 	.driver	= {
 		.name	= "sun50i-a100-r-ccu",
+		.suppress_bind_attrs = true,
 		.of_match_table	= sun50i_a100_r_ccu_ids,
 	},
 };
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
index 913bb08e6dee..1d475d5a3d91 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
@@ -1270,6 +1270,7 @@ static struct platform_driver sun50i_a100_ccu_driver = {
 	.probe	= sun50i_a100_ccu_probe,
 	.driver	= {
 		.name	= "sun50i-a100-ccu",
+		.suppress_bind_attrs = true,
 		.of_match_table	= sun50i_a100_ccu_ids,
 	},
 };
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 54f25c624f02..fcbd914e84e0 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -978,6 +978,7 @@ static struct platform_driver sun50i_a64_ccu_driver = {
 	.probe	= sun50i_a64_ccu_probe,
 	.driver	= {
 		.name	= "sun50i-a64-ccu",
+		.suppress_bind_attrs = true,
 		.of_match_table	= sun50i_a64_ccu_ids,
 	},
 };
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index c0800da2fa3d..9a8902f702c5 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -1252,6 +1252,7 @@ static struct platform_driver sun50i_h6_ccu_driver = {
 	.probe	= sun50i_h6_ccu_probe,
 	.driver	= {
 		.name	= "sun50i-h6-ccu",
+		.suppress_bind_attrs = true,
 		.of_match_table	= sun50i_h6_ccu_ids,
 	},
 };
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
index c2ddcd2ddab4..e663ab0c9935 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
@@ -918,6 +918,7 @@ static struct platform_driver sun8i_a83t_ccu_driver = {
 	.probe	= sun8i_a83t_ccu_probe,
 	.driver	= {
 		.name	= "sun8i-a83t-ccu",
+		.suppress_bind_attrs = true,
 		.of_match_table	= sun8i_a83t_ccu_ids,
 	},
 };
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
index 002e0c3a04db..a2144ee728a0 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
@@ -1369,6 +1369,7 @@ static struct platform_driver sun8i_r40_ccu_driver = {
 	.probe	= sun8i_r40_ccu_probe,
 	.driver	= {
 		.name	= "sun8i-r40-ccu",
+		.suppress_bind_attrs = true,
 		.of_match_table	= sun8i_r40_ccu_ids,
 	},
 };
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
index 261e64416f26..d2072972b614 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
@@ -268,6 +268,7 @@ static struct platform_driver sun9i_a80_de_clk_driver = {
 	.probe	= sun9i_a80_de_clk_probe,
 	.driver	= {
 		.name	= "sun9i-a80-de-clks",
+		.suppress_bind_attrs = true,
 		.of_match_table	= sun9i_a80_de_clk_ids,
 	},
 };
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
index 97aaed0e6850..68b30fdc60fd 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
@@ -1243,6 +1243,7 @@ static struct platform_driver sun9i_a80_ccu_driver = {
 	.probe	= sun9i_a80_ccu_probe,
 	.driver	= {
 		.name	= "sun9i-a80-ccu",
+		.suppress_bind_attrs = true,
 		.of_match_table	= sun9i_a80_ccu_ids,
 	},
 };
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:05:19 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:19 -0500
Subject: [PATCH 1/8] clk: sunxi-ng: Unregister clocks/resets when unbinding
In-Reply-To: <20210901050526.45673-1-samuel@sholland.org>
References: <20210901050526.45673-1-samuel@sholland.org>
Message-ID: <20210901050526.45673-2-samuel@sholland.org>

Currently, unbinding a CCU driver unmaps the device's MMIO region, while
leaving its clocks/resets and their providers registered. This can cause
a page fault later when some clock operation tries to perform MMIO. Fix
this by separating the CCU initialization from the memory allocation,
and then using a devres callback to unregister the clocks and resets.

This also fixes a memory leak of the `struct ccu_reset`, and uses the
correct owner (the specific platform driver) for the clocks and resets.

Early OF clock providers are never unregistered, and limited error
handling is possible, so they are mostly unchanged. The error reporting
is made more consistent by moving the message inside of_sunxi_ccu_probe.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/ccu-sun4i-a10.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c |  2 +-
 drivers/clk/sunxi-ng/ccu-sun50i-a100.c   |  2 +-
 drivers/clk/sunxi-ng/ccu-sun50i-a64.c    |  2 +-
 drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c   |  2 +-
 drivers/clk/sunxi-ng/ccu-sun50i-h6.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun50i-h616.c   |  4 +-
 drivers/clk/sunxi-ng/ccu-sun5i.c         |  2 +-
 drivers/clk/sunxi-ng/ccu-sun6i-a31.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a23.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-a83t.c    |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-de2.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-h3.c      |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-r.c       |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-r40.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun8i-v3s.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c  |  3 +-
 drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c |  3 +-
 drivers/clk/sunxi-ng/ccu-sun9i-a80.c     |  2 +-
 drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c |  2 +-
 drivers/clk/sunxi-ng/ccu_common.c        | 89 ++++++++++++++++++++----
 drivers/clk/sunxi-ng/ccu_common.h        |  6 +-
 23 files changed, 100 insertions(+), 41 deletions(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
index f32366d9336e..bd9a8782fec3 100644
--- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
+++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
@@ -1464,7 +1464,7 @@ static void __init sun4i_ccu_init(struct device_node *node,
 	val &= ~GENMASK(7, 6);
 	writel(val | (2 << 6), reg + SUN4I_AHB_REG);
 
-	sunxi_ccu_probe(node, reg, desc);
+	of_sunxi_ccu_probe(node, reg, desc);
 }
 
 static void __init sun4i_a10_ccu_setup(struct device_node *node)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
index a56142b90993..6f2a58970556 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
@@ -196,7 +196,7 @@ static int sun50i_a100_r_ccu_probe(struct platform_device *pdev)
 	if (IS_ERR(reg))
 		return PTR_ERR(reg);
 
-	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_r_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_r_ccu_desc);
 }
 
 static const struct of_device_id sun50i_a100_r_ccu_ids[] = {
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
index 81b48c73d389..913bb08e6dee 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
@@ -1247,7 +1247,7 @@ static int sun50i_a100_ccu_probe(struct platform_device *pdev)
 		writel(val, reg + sun50i_a100_usb2_clk_regs[i]);
 	}
 
-	ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_ccu_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_ccu_desc);
 	if (ret)
 		return ret;
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 149cfde817cb..54f25c624f02 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -955,7 +955,7 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 
 	writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
 
-	ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc);
 	if (ret)
 		return ret;
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
index f8909a7ed553..f30d7eb5424d 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
@@ -232,7 +232,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node,
 		return;
 	}
 
-	sunxi_ccu_probe(node, reg, desc);
+	of_sunxi_ccu_probe(node, reg, desc);
 }
 
 static void __init sun50i_h6_r_ccu_setup(struct device_node *node)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
index bff446b78290..c0800da2fa3d 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -1240,7 +1240,7 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
 	val |= BIT(24);
 	writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
 
-	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
 }
 
 static const struct of_device_id sun50i_h6_ccu_ids[] = {
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
index 225307305880..22eb18079a15 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
@@ -1141,9 +1141,7 @@ static void __init sun50i_h616_ccu_setup(struct device_node *node)
 	val |= BIT(24);
 	writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
 
-	i = sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc);
-	if (i)
-		pr_err("%pOF: probing clocks fails: %d\n", node, i);
+	of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc);
 }
 
 CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu",
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c
index b78e9b507c1c..1f4bc0e773a7 100644
--- a/drivers/clk/sunxi-ng/ccu-sun5i.c
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.c
@@ -1012,7 +1012,7 @@ static void __init sun5i_ccu_init(struct device_node *node,
 	val &= ~GENMASK(7, 6);
 	writel(val | (2 << 6), reg + SUN5I_AHB_REG);
 
-	sunxi_ccu_probe(node, reg, desc);
+	of_sunxi_ccu_probe(node, reg, desc);
 }
 
 static void __init sun5i_a10s_ccu_setup(struct device_node *node)
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
index 9b40d53266a3..3df5c0b41580 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
@@ -1257,7 +1257,7 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
 	val |= 0x3 << 12;
 	writel(val, reg + SUN6I_A31_AHB1_REG);
 
-	sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
+	of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
 
 	ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
 				  &sun6i_a31_cpu_nb);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
index 103aa504f6c8..577bb235d658 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
@@ -745,7 +745,7 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node)
 	val &= ~BIT(16);
 	writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
 
-	sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
+	of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
 }
 CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu",
 	       sun8i_a23_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index 91838cd11037..8f65cd03f5ac 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -805,7 +805,7 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
 	val &= ~BIT(16);
 	writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
 
-	sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
+	of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
 
 	/* Gate then ungate PLL CPU after any rate changes */
 	ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
index 2b434521c5cc..c2ddcd2ddab4 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
@@ -906,7 +906,7 @@ static int sun8i_a83t_ccu_probe(struct platform_device *pdev)
 	sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG);
 	sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG);
 
-	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_a83t_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a83t_ccu_desc);
 }
 
 static const struct of_device_id sun8i_a83t_ccu_ids[] = {
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
index 524f33275bc7..4b94b6041b27 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
@@ -342,7 +342,7 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev)
 		goto err_disable_mod_clk;
 	}
 
-	ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc);
 	if (ret)
 		goto err_assert_reset;
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
index 7e629a4493af..d2fc2903787d 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
@@ -1154,7 +1154,7 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
 	val &= ~GENMASK(19, 16);
 	writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
 
-	sunxi_ccu_probe(node, reg, desc);
+	of_sunxi_ccu_probe(node, reg, desc);
 
 	/* Gate then ungate PLL CPU after any rate changes */
 	ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
index 4c8c491b87c2..9e754d1f754a 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
@@ -265,7 +265,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node,
 		return;
 	}
 
-	sunxi_ccu_probe(node, reg, desc);
+	of_sunxi_ccu_probe(node, reg, desc);
 }
 
 static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
index 84153418453f..002e0c3a04db 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
@@ -1346,7 +1346,7 @@ static int sun8i_r40_ccu_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_r40_ccu_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_r40_ccu_desc);
 	if (ret)
 		return ret;
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
index f49724a22540..ce150f83ab54 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
@@ -822,7 +822,7 @@ static void __init sun8i_v3_v3s_ccu_init(struct device_node *node,
 	val &= ~GENMASK(19, 16);
 	writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG);
 
-	sunxi_ccu_probe(node, reg, ccu_desc);
+	of_sunxi_ccu_probe(node, reg, ccu_desc);
 }
 
 static void __init sun8i_v3s_ccu_setup(struct device_node *node)
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
index 6616e8114f62..261e64416f26 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
@@ -246,8 +246,7 @@ static int sun9i_a80_de_clk_probe(struct platform_device *pdev)
 		goto err_disable_clk;
 	}
 
-	ret = sunxi_ccu_probe(pdev->dev.of_node, reg,
-			      &sun9i_a80_de_clk_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_de_clk_desc);
 	if (ret)
 		goto err_assert_reset;
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
index 4b4a507d04ed..596243b3e0fa 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
@@ -117,8 +117,7 @@ static int sun9i_a80_usb_clk_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = sunxi_ccu_probe(pdev->dev.of_node, reg,
-			      &sun9i_a80_usb_clk_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_usb_clk_desc);
 	if (ret)
 		goto err_disable_clk;
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
index ef29582676f6..97aaed0e6850 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
+++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
@@ -1231,7 +1231,7 @@ static int sun9i_a80_ccu_probe(struct platform_device *pdev)
 	sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C0CPUX_REG);
 	sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C1CPUX_REG);
 
-	return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_ccu_desc);
 }
 
 static const struct of_device_id sun9i_a80_ccu_ids[] = {
diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
index 7ecc3a5a5b5e..61ad7ee91c11 100644
--- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
+++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
@@ -538,7 +538,7 @@ static void __init suniv_f1c100s_ccu_setup(struct device_node *node)
 	val &= ~GENMASK(19, 16);
 	writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG);
 
-	sunxi_ccu_probe(node, reg, &suniv_ccu_desc);
+	of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc);
 
 	/* Gate then ungate PLL CPU after any rate changes */
 	ccu_pll_notifier_register(&suniv_pll_cpu_nb);
diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c
index 2e20e650b6c0..88cb569e5835 100644
--- a/drivers/clk/sunxi-ng/ccu_common.c
+++ b/drivers/clk/sunxi-ng/ccu_common.c
@@ -7,6 +7,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/device.h>
 #include <linux/iopoll.h>
 #include <linux/slab.h>
 
@@ -14,6 +15,11 @@
 #include "ccu_gate.h"
 #include "ccu_reset.h"
 
+struct sunxi_ccu {
+	const struct sunxi_ccu_desc	*desc;
+	struct ccu_reset		reset;
+};
+
 static DEFINE_SPINLOCK(ccu_lock);
 
 void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
@@ -79,12 +85,15 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb)
 				     &pll_nb->clk_nb);
 }
 
-int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
-		    const struct sunxi_ccu_desc *desc)
+static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
+			   struct device_node *node, void __iomem *reg,
+			   const struct sunxi_ccu_desc *desc)
 {
 	struct ccu_reset *reset;
 	int i, ret;
 
+	ccu->desc = desc;
+
 	for (i = 0; i < desc->num_ccu_clks; i++) {
 		struct ccu_common *cclk = desc->ccu_clks[i];
 
@@ -103,7 +112,10 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
 			continue;
 
 		name = hw->init->name;
-		ret = of_clk_hw_register(node, hw);
+		if (dev)
+			ret = clk_hw_register(dev, hw);
+		else
+			ret = of_clk_hw_register(node, hw);
 		if (ret) {
 			pr_err("Couldn't register clock %d - %s\n", i, name);
 			goto err_clk_unreg;
@@ -115,15 +127,10 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
 	if (ret)
 		goto err_clk_unreg;
 
-	reset = kzalloc(sizeof(*reset), GFP_KERNEL);
-	if (!reset) {
-		ret = -ENOMEM;
-		goto err_alloc_reset;
-	}
-
+	reset = &ccu->reset;
 	reset->rcdev.of_node = node;
 	reset->rcdev.ops = &ccu_reset_ops;
-	reset->rcdev.owner = THIS_MODULE;
+	reset->rcdev.owner = dev ? dev->driver->owner : THIS_MODULE;
 	reset->rcdev.nr_resets = desc->num_resets;
 	reset->base = reg;
 	reset->lock = &ccu_lock;
@@ -131,13 +138,11 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
 
 	ret = reset_controller_register(&reset->rcdev);
 	if (ret)
-		goto err_of_clk_unreg;
+		goto err_del_provider;
 
 	return 0;
 
-err_of_clk_unreg:
-	kfree(reset);
-err_alloc_reset:
+err_del_provider:
 	of_clk_del_provider(node);
 err_clk_unreg:
 	while (--i >= 0) {
@@ -149,3 +154,59 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
 	}
 	return ret;
 }
+
+static void devm_sunxi_ccu_release(struct device *dev, void *res)
+{
+	struct sunxi_ccu *ccu = res;
+	const struct sunxi_ccu_desc *desc = ccu->desc;
+	int i;
+
+	reset_controller_unregister(&ccu->reset.rcdev);
+	of_clk_del_provider(dev->of_node);
+
+	for (i = 0; i < desc->hw_clks->num; i++) {
+		struct clk_hw *hw = desc->hw_clks->hws[i];
+
+		if (!hw)
+			continue;
+		clk_hw_unregister(hw);
+	}
+}
+
+int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg,
+			 const struct sunxi_ccu_desc *desc)
+{
+	struct sunxi_ccu *ccu;
+	int ret;
+
+	ccu = devres_alloc(devm_sunxi_ccu_release, sizeof(*ccu), GFP_KERNEL);
+	if (!ccu)
+		return -ENOMEM;
+
+	ret = sunxi_ccu_probe(ccu, dev, dev->of_node, reg, desc);
+	if (ret) {
+		devres_free(ccu);
+		return ret;
+	}
+
+	devres_add(dev, ccu);
+
+	return 0;
+}
+
+void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
+			const struct sunxi_ccu_desc *desc)
+{
+	struct sunxi_ccu *ccu;
+	int ret;
+
+	ccu = kzalloc(sizeof(*ccu), GFP_KERNEL);
+	if (!ccu)
+		return;
+
+	ret = sunxi_ccu_probe(ccu, NULL, node, reg, desc);
+	if (ret) {
+		pr_err("%pOF: probing clocks failed: %d\n", node, ret);
+		kfree(ccu);
+	}
+}
diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h
index 04e7a12200a2..98a1834b58bb 100644
--- a/drivers/clk/sunxi-ng/ccu_common.h
+++ b/drivers/clk/sunxi-ng/ccu_common.h
@@ -63,7 +63,9 @@ struct ccu_pll_nb {
 
 int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb);
 
-int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
-		    const struct sunxi_ccu_desc *desc);
+int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg,
+			 const struct sunxi_ccu_desc *desc);
+void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
+			const struct sunxi_ccu_desc *desc);
 
 #endif /* _COMMON_H_ */
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:05:18 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:18 -0500
Subject: [PATCH 0/8] clk: sunxi-ng: Lifetime fixes and module support
Message-ID: <20210901050526.45673-1-samuel@sholland.org>

This series makes the CCU drivers a bit better behaved, by allowing them
to be cleanly loaded/unloaded and bound/unbound without leaking memory
or crashing.

- Patches 1 fixes some object lifetime and reference counting issues
  with the drivers.
- Patch 2 disarms a sysfs footgun.
- Patch 3 takes advantage of the structure added in patch 1 to improve
  performance a bit by splitting up the lock.
- Patches 4-8 allow the drivers and CCU core to be built as modules.
  As part of this, patch 7 converts most of the early OF providers to
  platform drivers.

Samuel Holland (8):
  clk: sunxi-ng: Unregister clocks/resets when unbinding
  clk: sunxi-ng: Prevent unbinding CCUs via sysfs
  clk: sunxi-ng: Use a separate lock for each CCU instance
  clk: sunxi-ng: Rename files to match Kconfig and drivers
  clk: sunxi-ng: Export symbols used by CCU drivers
  clk: sunxi-ng: Allow drivers to be built as modules
  clk: sunxi-ng: Convert early providers to platform drivers
  clk: sunxi-ng: Allow the CCU core to be built as a module

 drivers/clk/Makefile                          |   2 +-
 drivers/clk/sunxi-ng/Kconfig                  |  39 +++----
 drivers/clk/sunxi-ng/Makefile                 |  75 ++++++-------
 drivers/clk/sunxi-ng/ccu_common.c             | 101 +++++++++++++++---
 drivers/clk/sunxi-ng/ccu_common.h             |   6 +-
 drivers/clk/sunxi-ng/ccu_div.c                |   1 +
 drivers/clk/sunxi-ng/ccu_gate.c               |   1 +
 drivers/clk/sunxi-ng/ccu_mp.c                 |   2 +
 drivers/clk/sunxi-ng/ccu_mult.c               |   1 +
 drivers/clk/sunxi-ng/ccu_mux.c                |   2 +
 drivers/clk/sunxi-ng/ccu_nk.c                 |   1 +
 drivers/clk/sunxi-ng/ccu_nkm.c                |   1 +
 drivers/clk/sunxi-ng/ccu_nkmp.c               |   1 +
 drivers/clk/sunxi-ng/ccu_nm.c                 |   1 +
 drivers/clk/sunxi-ng/ccu_phase.c              |   1 +
 drivers/clk/sunxi-ng/ccu_reset.c              |   1 +
 .../{ccu-sun4i-a10.c => sun4i-a10-ccu.c}      |  59 ++++++----
 .../{ccu-sun4i-a10.h => sun4i-a10-ccu.h}      |   0
 .../{ccu-sun50i-a100.c => sun50i-a100-ccu.c}  |   8 +-
 .../{ccu-sun50i-a100.h => sun50i-a100-ccu.h}  |   0
 ...cu-sun50i-a100-r.c => sun50i-a100-r-ccu.c} |   8 +-
 ...cu-sun50i-a100-r.h => sun50i-a100-r-ccu.h} |   0
 .../{ccu-sun50i-a64.c => sun50i-a64-ccu.c}    |  11 +-
 .../{ccu-sun50i-a64.h => sun50i-a64-ccu.h}    |   0
 .../{ccu-sun50i-h6.c => sun50i-h6-ccu.c}      |  11 +-
 .../{ccu-sun50i-h6.h => sun50i-h6-ccu.h}      |   0
 .../{ccu-sun50i-h6-r.c => sun50i-h6-r-ccu.c}  |  57 ++++++----
 .../{ccu-sun50i-h6-r.h => sun50i-h6-r-ccu.h}  |   0
 .../{ccu-sun50i-h616.c => sun50i-h616-ccu.c}  |  36 ++++---
 .../{ccu-sun50i-h616.h => sun50i-h616-ccu.h}  |   0
 .../clk/sunxi-ng/{ccu-sun5i.c => sun5i-ccu.c} |   4 +-
 .../clk/sunxi-ng/{ccu-sun5i.h => sun5i-ccu.h} |   0
 .../{ccu-sun6i-a31.c => sun6i-a31-ccu.c}      |  41 +++++--
 .../{ccu-sun6i-a31.h => sun6i-a31-ccu.h}      |   0
 ...cu-sun8i-a23-a33.h => sun8i-a23-a33-ccu.h} |   0
 .../{ccu-sun8i-a23.c => sun8i-a23-ccu.c}      |  36 +++++--
 .../{ccu-sun8i-a33.c => sun8i-a33-ccu.c}      |  41 +++++--
 .../{ccu-sun8i-a83t.c => sun8i-a83t-ccu.c}    |  11 +-
 .../{ccu-sun8i-a83t.h => sun8i-a83t-ccu.h}    |   0
 .../{ccu-sun8i-de2.c => sun8i-de2-ccu.c}      |  12 ++-
 .../{ccu-sun8i-de2.h => sun8i-de2-ccu.h}      |   0
 .../{ccu-sun8i-h3.c => sun8i-h3-ccu.c}        |  63 +++++++----
 .../{ccu-sun8i-h3.h => sun8i-h3-ccu.h}        |   0
 .../sunxi-ng/{ccu-sun8i-r.c => sun8i-r-ccu.c} |  66 +++++++-----
 .../sunxi-ng/{ccu-sun8i-r.h => sun8i-r-ccu.h} |   0
 .../{ccu-sun8i-r40.c => sun8i-r40-ccu.c}      |  10 +-
 .../{ccu-sun8i-r40.h => sun8i-r40-ccu.h}      |   0
 .../{ccu-sun8i-v3s.c => sun8i-v3s-ccu.c}      |  58 ++++++----
 .../{ccu-sun8i-v3s.h => sun8i-v3s-ccu.h}      |   0
 .../{ccu-sun9i-a80.c => sun9i-a80-ccu.c}      |  11 +-
 .../{ccu-sun9i-a80.h => sun9i-a80-ccu.h}      |   0
 ...{ccu-sun9i-a80-de.c => sun9i-a80-de-ccu.c} |  12 ++-
 ...{ccu-sun9i-a80-de.h => sun9i-a80-de-ccu.h} |   0
 ...cu-sun9i-a80-usb.c => sun9i-a80-usb-ccu.c} |  11 +-
 ...cu-sun9i-a80-usb.h => sun9i-a80-usb-ccu.h} |   0
 ...cu-suniv-f1c100s.c => suniv-f1c100s-ccu.c} |  39 +++++--
 ...cu-suniv-f1c100s.h => suniv-f1c100s-ccu.h} |   0
 drivers/mmc/host/Kconfig                      |   1 +
 include/linux/clk/sunxi-ng.h                  |  15 ---
 59 files changed, 551 insertions(+), 306 deletions(-)
 rename drivers/clk/sunxi-ng/{ccu-sun4i-a10.c => sun4i-a10-ccu.c} (98%)
 rename drivers/clk/sunxi-ng/{ccu-sun4i-a10.h => sun4i-a10-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a100.c => sun50i-a100-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a100.h => sun50i-a100-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a100-r.c => sun50i-a100-r-ccu.c} (97%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a100-r.h => sun50i-a100-r-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a64.c => sun50i-a64-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a64.h => sun50i-a64-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h6.c => sun50i-h6-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h6.h => sun50i-h6-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h6-r.c => sun50i-h6-r-ccu.c} (87%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h6-r.h => sun50i-h6-r-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h616.c => sun50i-h616-ccu.c} (98%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h616.h => sun50i-h616-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun5i.c => sun5i-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun5i.h => sun5i-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun6i-a31.c => sun6i-a31-ccu.c} (98%)
 rename drivers/clk/sunxi-ng/{ccu-sun6i-a31.h => sun6i-a31-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a23-a33.h => sun8i-a23-a33-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a23.c => sun8i-a23-ccu.c} (97%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a33.c => sun8i-a33-ccu.c} (97%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a83t.c => sun8i-a83t-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a83t.h => sun8i-a83t-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-de2.c => sun8i-de2-ccu.c} (98%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-de2.h => sun8i-de2-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-h3.c => sun8i-h3-ccu.c} (97%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-h3.h => sun8i-h3-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-r.c => sun8i-r-ccu.c} (87%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-r.h => sun8i-r-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-r40.c => sun8i-r40-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-r40.h => sun8i-r40-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-v3s.c => sun8i-v3s-ccu.c} (96%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-v3s.h => sun8i-v3s-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80.c => sun9i-a80-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80.h => sun9i-a80-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80-de.c => sun9i-a80-de-ccu.c} (97%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80-de.h => sun9i-a80-de-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80-usb.c => sun9i-a80-usb-ccu.c} (95%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80-usb.h => sun9i-a80-usb-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-suniv-f1c100s.c => suniv-f1c100s-ccu.c} (96%)
 rename drivers/clk/sunxi-ng/{ccu-suniv-f1c100s.h => suniv-f1c100s-ccu.h} (100%)

-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:05:22 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:22 -0500
Subject: [PATCH 4/8] clk: sunxi-ng: Rename files to match Kconfig and drivers
In-Reply-To: <20210901050526.45673-1-samuel@sholland.org>
References: <20210901050526.45673-1-samuel@sholland.org>
Message-ID: <20210901050526.45673-5-samuel@sholland.org>

When the drivers are built as modules, the file name will become the
module name. Rename the files so everything matches: the Kconfig symbol,
the platform driver name (as seen in sysfs), and the module name.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/Makefile                 | 42 +++++++++----------
 .../{ccu-sun4i-a10.c => sun4i-a10-ccu.c}      |  2 +-
 .../{ccu-sun4i-a10.h => sun4i-a10-ccu.h}      |  0
 .../{ccu-sun50i-a100.c => sun50i-a100-ccu.c}  |  2 +-
 .../{ccu-sun50i-a100.h => sun50i-a100-ccu.h}  |  0
 ...cu-sun50i-a100-r.c => sun50i-a100-r-ccu.c} |  2 +-
 ...cu-sun50i-a100-r.h => sun50i-a100-r-ccu.h} |  0
 .../{ccu-sun50i-a64.c => sun50i-a64-ccu.c}    |  2 +-
 .../{ccu-sun50i-a64.h => sun50i-a64-ccu.h}    |  0
 .../{ccu-sun50i-h6.c => sun50i-h6-ccu.c}      |  2 +-
 .../{ccu-sun50i-h6.h => sun50i-h6-ccu.h}      |  0
 .../{ccu-sun50i-h6-r.c => sun50i-h6-r-ccu.c}  |  2 +-
 .../{ccu-sun50i-h6-r.h => sun50i-h6-r-ccu.h}  |  0
 .../{ccu-sun50i-h616.c => sun50i-h616-ccu.c}  |  2 +-
 .../{ccu-sun50i-h616.h => sun50i-h616-ccu.h}  |  0
 .../clk/sunxi-ng/{ccu-sun5i.c => sun5i-ccu.c} |  2 +-
 .../clk/sunxi-ng/{ccu-sun5i.h => sun5i-ccu.h} |  0
 .../{ccu-sun6i-a31.c => sun6i-a31-ccu.c}      |  2 +-
 .../{ccu-sun6i-a31.h => sun6i-a31-ccu.h}      |  0
 ...cu-sun8i-a23-a33.h => sun8i-a23-a33-ccu.h} |  0
 .../{ccu-sun8i-a23.c => sun8i-a23-ccu.c}      |  2 +-
 .../{ccu-sun8i-a33.c => sun8i-a33-ccu.c}      |  2 +-
 .../{ccu-sun8i-a83t.c => sun8i-a83t-ccu.c}    |  2 +-
 .../{ccu-sun8i-a83t.h => sun8i-a83t-ccu.h}    |  0
 .../{ccu-sun8i-de2.c => sun8i-de2-ccu.c}      |  2 +-
 .../{ccu-sun8i-de2.h => sun8i-de2-ccu.h}      |  0
 .../{ccu-sun8i-h3.c => sun8i-h3-ccu.c}        |  2 +-
 .../{ccu-sun8i-h3.h => sun8i-h3-ccu.h}        |  0
 .../sunxi-ng/{ccu-sun8i-r.c => sun8i-r-ccu.c} |  2 +-
 .../sunxi-ng/{ccu-sun8i-r.h => sun8i-r-ccu.h} |  0
 .../{ccu-sun8i-r40.c => sun8i-r40-ccu.c}      |  2 +-
 .../{ccu-sun8i-r40.h => sun8i-r40-ccu.h}      |  0
 .../{ccu-sun8i-v3s.c => sun8i-v3s-ccu.c}      |  2 +-
 .../{ccu-sun8i-v3s.h => sun8i-v3s-ccu.h}      |  0
 .../{ccu-sun9i-a80.c => sun9i-a80-ccu.c}      |  2 +-
 .../{ccu-sun9i-a80.h => sun9i-a80-ccu.h}      |  0
 ...{ccu-sun9i-a80-de.c => sun9i-a80-de-ccu.c} |  2 +-
 ...{ccu-sun9i-a80-de.h => sun9i-a80-de-ccu.h} |  0
 ...cu-sun9i-a80-usb.c => sun9i-a80-usb-ccu.c} |  2 +-
 ...cu-sun9i-a80-usb.h => sun9i-a80-usb-ccu.h} |  0
 ...cu-suniv-f1c100s.c => suniv-f1c100s-ccu.c} |  2 +-
 ...cu-suniv-f1c100s.h => suniv-f1c100s-ccu.h} |  0
 42 files changed, 42 insertions(+), 42 deletions(-)
 rename drivers/clk/sunxi-ng/{ccu-sun4i-a10.c => sun4i-a10-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun4i-a10.h => sun4i-a10-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a100.c => sun50i-a100-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a100.h => sun50i-a100-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a100-r.c => sun50i-a100-r-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a100-r.h => sun50i-a100-r-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a64.c => sun50i-a64-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-a64.h => sun50i-a64-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h6.c => sun50i-h6-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h6.h => sun50i-h6-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h6-r.c => sun50i-h6-r-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h6-r.h => sun50i-h6-r-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h616.c => sun50i-h616-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun50i-h616.h => sun50i-h616-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun5i.c => sun5i-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun5i.h => sun5i-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun6i-a31.c => sun6i-a31-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun6i-a31.h => sun6i-a31-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a23-a33.h => sun8i-a23-a33-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a23.c => sun8i-a23-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a33.c => sun8i-a33-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a83t.c => sun8i-a83t-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-a83t.h => sun8i-a83t-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-de2.c => sun8i-de2-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-de2.h => sun8i-de2-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-h3.c => sun8i-h3-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-h3.h => sun8i-h3-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-r.c => sun8i-r-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-r.h => sun8i-r-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-r40.c => sun8i-r40-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-r40.h => sun8i-r40-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-v3s.c => sun8i-v3s-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun8i-v3s.h => sun8i-v3s-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80.c => sun9i-a80-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80.h => sun9i-a80-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80-de.c => sun9i-a80-de-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80-de.h => sun9i-a80-de-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80-usb.c => sun9i-a80-usb-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-sun9i-a80-usb.h => sun9i-a80-usb-ccu.h} (100%)
 rename drivers/clk/sunxi-ng/{ccu-suniv-f1c100s.c => suniv-f1c100s-ccu.c} (99%)
 rename drivers/clk/sunxi-ng/{ccu-suniv-f1c100s.h => suniv-f1c100s-ccu.h} (100%)

diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 96c324306d97..9ebf5920c93b 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -21,24 +21,24 @@ obj-y				+= ccu_nm.o
 obj-y				+= ccu_mp.o
 
 # SoC support
-obj-$(CONFIG_SUNIV_F1C100S_CCU)	+= ccu-suniv-f1c100s.o
-obj-$(CONFIG_SUN50I_A64_CCU)	+= ccu-sun50i-a64.o
-obj-$(CONFIG_SUN50I_A100_CCU)	+= ccu-sun50i-a100.o
-obj-$(CONFIG_SUN50I_A100_R_CCU)	+= ccu-sun50i-a100-r.o
-obj-$(CONFIG_SUN50I_H6_CCU)	+= ccu-sun50i-h6.o
-obj-$(CONFIG_SUN50I_H616_CCU)	+= ccu-sun50i-h616.o
-obj-$(CONFIG_SUN50I_H6_R_CCU)	+= ccu-sun50i-h6-r.o
-obj-$(CONFIG_SUN4I_A10_CCU)	+= ccu-sun4i-a10.o
-obj-$(CONFIG_SUN5I_CCU)		+= ccu-sun5i.o
-obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
-obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
-obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
-obj-$(CONFIG_SUN8I_A83T_CCU)	+= ccu-sun8i-a83t.o
-obj-$(CONFIG_SUN8I_H3_CCU)	+= ccu-sun8i-h3.o
-obj-$(CONFIG_SUN8I_V3S_CCU)	+= ccu-sun8i-v3s.o
-obj-$(CONFIG_SUN8I_DE2_CCU)	+= ccu-sun8i-de2.o
-obj-$(CONFIG_SUN8I_R_CCU)	+= ccu-sun8i-r.o
-obj-$(CONFIG_SUN8I_R40_CCU)	+= ccu-sun8i-r40.o
-obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80.o
-obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-de.o
-obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-usb.o
+obj-$(CONFIG_SUNIV_F1C100S_CCU)	+= suniv-f1c100s-ccu.o
+obj-$(CONFIG_SUN50I_A64_CCU)	+= sun50i-a64-ccu.o
+obj-$(CONFIG_SUN50I_A100_CCU)	+= sun50i-a100-ccu.o
+obj-$(CONFIG_SUN50I_A100_R_CCU)	+= sun50i-a100-r-ccu.o
+obj-$(CONFIG_SUN50I_H6_CCU)	+= sun50i-h6-ccu.o
+obj-$(CONFIG_SUN50I_H616_CCU)	+= sun50i-h616-ccu.o
+obj-$(CONFIG_SUN50I_H6_R_CCU)	+= sun50i-h6-r-ccu.o
+obj-$(CONFIG_SUN4I_A10_CCU)	+= sun4i-a10-ccu.o
+obj-$(CONFIG_SUN5I_CCU)		+= sun5i-ccu.o
+obj-$(CONFIG_SUN6I_A31_CCU)	+= sun6i-a31-ccu.o
+obj-$(CONFIG_SUN8I_A23_CCU)	+= sun8i-a23-ccu.o
+obj-$(CONFIG_SUN8I_A33_CCU)	+= sun8i-a33-ccu.o
+obj-$(CONFIG_SUN8I_A83T_CCU)	+= sun8i-a83t-ccu.o
+obj-$(CONFIG_SUN8I_H3_CCU)	+= sun8i-h3-ccu.o
+obj-$(CONFIG_SUN8I_V3S_CCU)	+= sun8i-v3s-ccu.o
+obj-$(CONFIG_SUN8I_DE2_CCU)	+= sun8i-de2-ccu.o
+obj-$(CONFIG_SUN8I_R_CCU)	+= sun8i-r-ccu.o
+obj-$(CONFIG_SUN8I_R40_CCU)	+= sun8i-r40-ccu.o
+obj-$(CONFIG_SUN9I_A80_CCU)	+= sun9i-a80-ccu.o
+obj-$(CONFIG_SUN9I_A80_CCU)	+= sun9i-a80-de-ccu.o
+obj-$(CONFIG_SUN9I_A80_CCU)	+= sun9i-a80-usb-ccu.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/sun4i-a10-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun4i-a10.c
rename to drivers/clk/sunxi-ng/sun4i-a10-ccu.c
index bd9a8782fec3..5d67f5666943 100644
--- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
+++ b/drivers/clk/sunxi-ng/sun4i-a10-ccu.c
@@ -23,7 +23,7 @@
 #include "ccu_phase.h"
 #include "ccu_sdm.h"
 
-#include "ccu-sun4i-a10.h"
+#include "sun4i-a10-ccu.h"
 
 static struct ccu_nkmp pll_core_clk = {
 	.enable		= BIT(31),
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.h b/drivers/clk/sunxi-ng/sun4i-a10-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun4i-a10.h
rename to drivers/clk/sunxi-ng/sun4i-a10-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/sun50i-a100-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun50i-a100.c
rename to drivers/clk/sunxi-ng/sun50i-a100-ccu.c
index 1d475d5a3d91..5a813af9941c 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
+++ b/drivers/clk/sunxi-ng/sun50i-a100-ccu.c
@@ -21,7 +21,7 @@
 #include "ccu_nkmp.h"
 #include "ccu_nm.h"
 
-#include "ccu-sun50i-a100.h"
+#include "sun50i-a100-ccu.h"
 
 #define SUN50I_A100_PLL_SDM_ENABLE		BIT(24)
 #define SUN50I_A100_PLL_OUTPUT_ENABLE		BIT(27)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.h b/drivers/clk/sunxi-ng/sun50i-a100-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun50i-a100.h
rename to drivers/clk/sunxi-ng/sun50i-a100-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c b/drivers/clk/sunxi-ng/sun50i-a100-r-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
rename to drivers/clk/sunxi-ng/sun50i-a100-r-ccu.c
index 804729e0a208..078ebdf8b093 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c
+++ b/drivers/clk/sunxi-ng/sun50i-a100-r-ccu.c
@@ -16,7 +16,7 @@
 #include "ccu_mp.h"
 #include "ccu_nm.h"
 
-#include "ccu-sun50i-a100-r.h"
+#include "sun50i-a100-r-ccu.h"
 
 static const char * const cpus_r_apb2_parents[] = { "dcxo24M", "osc32k",
 						     "iosc", "pll-periph0" };
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.h b/drivers/clk/sunxi-ng/sun50i-a100-r-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun50i-a100-r.h
rename to drivers/clk/sunxi-ng/sun50i-a100-r-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/sun50i-a64-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun50i-a64.c
rename to drivers/clk/sunxi-ng/sun50i-a64-ccu.c
index fcbd914e84e0..ffc5ef5fab3c 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/sun50i-a64-ccu.c
@@ -21,7 +21,7 @@
 #include "ccu_nm.h"
 #include "ccu_phase.h"
 
-#include "ccu-sun50i-a64.h"
+#include "sun50i-a64-ccu.h"
 
 static struct ccu_nkmp pll_cpux_clk = {
 	.enable		= BIT(31),
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/sun50i-a64-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun50i-a64.h
rename to drivers/clk/sunxi-ng/sun50i-a64-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/sun50i-h6-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun50i-h6.c
rename to drivers/clk/sunxi-ng/sun50i-h6-ccu.c
index 9a8902f702c5..8876358710c5 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ b/drivers/clk/sunxi-ng/sun50i-h6-ccu.c
@@ -20,7 +20,7 @@
 #include "ccu_nkmp.h"
 #include "ccu_nm.h"
 
-#include "ccu-sun50i-h6.h"
+#include "sun50i-h6-ccu.h"
 
 /*
  * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.h b/drivers/clk/sunxi-ng/sun50i-h6-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun50i-h6.h
rename to drivers/clk/sunxi-ng/sun50i-h6-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/sun50i-h6-r-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
rename to drivers/clk/sunxi-ng/sun50i-h6-r-ccu.c
index f30d7eb5424d..bb7f9ed78c4c 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
+++ b/drivers/clk/sunxi-ng/sun50i-h6-r-ccu.c
@@ -15,7 +15,7 @@
 #include "ccu_mp.h"
 #include "ccu_nm.h"
 
-#include "ccu-sun50i-h6-r.h"
+#include "sun50i-h6-r-ccu.h"
 
 /*
  * Information about AR100 and AHB/APB clocks in R_CCU are gathered from
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.h b/drivers/clk/sunxi-ng/sun50i-h6-r-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun50i-h6-r.h
rename to drivers/clk/sunxi-ng/sun50i-h6-r-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/sun50i-h616-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun50i-h616.c
rename to drivers/clk/sunxi-ng/sun50i-h616-ccu.c
index 22eb18079a15..71d75833253f 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c
+++ b/drivers/clk/sunxi-ng/sun50i-h616-ccu.c
@@ -22,7 +22,7 @@
 #include "ccu_nkmp.h"
 #include "ccu_nm.h"
 
-#include "ccu-sun50i-h616.h"
+#include "sun50i-h616-ccu.h"
 
 /*
  * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.h b/drivers/clk/sunxi-ng/sun50i-h616-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun50i-h616.h
rename to drivers/clk/sunxi-ng/sun50i-h616-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/sun5i-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun5i.c
rename to drivers/clk/sunxi-ng/sun5i-ccu.c
index 1f4bc0e773a7..4763ef93319f 100644
--- a/drivers/clk/sunxi-ng/ccu-sun5i.c
+++ b/drivers/clk/sunxi-ng/sun5i-ccu.c
@@ -21,7 +21,7 @@
 #include "ccu_phase.h"
 #include "ccu_sdm.h"
 
-#include "ccu-sun5i.h"
+#include "sun5i-ccu.h"
 
 static struct ccu_nkmp pll_core_clk = {
 	.enable		= BIT(31),
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/sun5i-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun5i.h
rename to drivers/clk/sunxi-ng/sun5i-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/sun6i-a31-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun6i-a31.c
rename to drivers/clk/sunxi-ng/sun6i-a31-ccu.c
index 3df5c0b41580..b05c06a428ad 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
+++ b/drivers/clk/sunxi-ng/sun6i-a31-ccu.c
@@ -26,7 +26,7 @@
 #include "ccu_phase.h"
 #include "ccu_sdm.h"
 
-#include "ccu-sun6i-a31.h"
+#include "sun6i-a31-ccu.h"
 
 static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
 				     "osc24M", 0x000,
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.h b/drivers/clk/sunxi-ng/sun6i-a31-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun6i-a31.h
rename to drivers/clk/sunxi-ng/sun6i-a31-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h b/drivers/clk/sunxi-ng/sun8i-a23-a33-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h
rename to drivers/clk/sunxi-ng/sun8i-a23-a33-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/sun8i-a23-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun8i-a23.c
rename to drivers/clk/sunxi-ng/sun8i-a23-ccu.c
index 577bb235d658..5bbc66a762db 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
+++ b/drivers/clk/sunxi-ng/sun8i-a23-ccu.c
@@ -21,7 +21,7 @@
 #include "ccu_phase.h"
 #include "ccu_sdm.h"
 
-#include "ccu-sun8i-a23-a33.h"
+#include "sun8i-a23-a33-ccu.h"
 
 
 static struct ccu_nkmp pll_cpux_clk = {
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/sun8i-a33-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun8i-a33.c
rename to drivers/clk/sunxi-ng/sun8i-a33-ccu.c
index 8f65cd03f5ac..6cd214b444d1 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/sun8i-a33-ccu.c
@@ -20,7 +20,7 @@
 #include "ccu_nm.h"
 #include "ccu_phase.h"
 
-#include "ccu-sun8i-a23-a33.h"
+#include "sun8i-a23-a33-ccu.h"
 
 static struct ccu_nkmp pll_cpux_clk = {
 	.enable = BIT(31),
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/sun8i-a83t-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
rename to drivers/clk/sunxi-ng/sun8i-a83t-ccu.c
index e663ab0c9935..067eb9bb4b53 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
+++ b/drivers/clk/sunxi-ng/sun8i-a83t-ccu.c
@@ -19,7 +19,7 @@
 #include "ccu_nm.h"
 #include "ccu_phase.h"
 
-#include "ccu-sun8i-a83t.h"
+#include "sun8i-a83t-ccu.h"
 
 #define CCU_SUN8I_A83T_LOCK_REG	0x20c
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.h b/drivers/clk/sunxi-ng/sun8i-a83t-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun8i-a83t.h
rename to drivers/clk/sunxi-ng/sun8i-a83t-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/sun8i-de2-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun8i-de2.c
rename to drivers/clk/sunxi-ng/sun8i-de2-ccu.c
index 4b94b6041b27..15d15448ac21 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
+++ b/drivers/clk/sunxi-ng/sun8i-de2-ccu.c
@@ -15,7 +15,7 @@
 #include "ccu_gate.h"
 #include "ccu_reset.h"
 
-#include "ccu-sun8i-de2.h"
+#include "sun8i-de2-ccu.h"
 
 static SUNXI_CCU_GATE(bus_mixer0_clk,	"bus-mixer0",	"bus-de",
 		      0x04, BIT(0), 0);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h b/drivers/clk/sunxi-ng/sun8i-de2-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun8i-de2.h
rename to drivers/clk/sunxi-ng/sun8i-de2-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/sun8i-h3-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun8i-h3.c
rename to drivers/clk/sunxi-ng/sun8i-h3-ccu.c
index d2fc2903787d..c566cc1aa168 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
+++ b/drivers/clk/sunxi-ng/sun8i-h3-ccu.c
@@ -21,7 +21,7 @@
 #include "ccu_phase.h"
 #include "ccu_sdm.h"
 
-#include "ccu-sun8i-h3.h"
+#include "sun8i-h3-ccu.h"
 
 static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpux_clk, "pll-cpux",
 				     "osc24M", 0x000,
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h b/drivers/clk/sunxi-ng/sun8i-h3-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun8i-h3.h
rename to drivers/clk/sunxi-ng/sun8i-h3-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/sun8i-r-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun8i-r.c
rename to drivers/clk/sunxi-ng/sun8i-r-ccu.c
index 9e754d1f754a..eb623b01df58 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c
+++ b/drivers/clk/sunxi-ng/sun8i-r-ccu.c
@@ -15,7 +15,7 @@
 #include "ccu_mp.h"
 #include "ccu_nm.h"
 
-#include "ccu-sun8i-r.h"
+#include "sun8i-r-ccu.h"
 
 static const struct clk_parent_data ar100_parents[] = {
 	{ .fw_name = "losc" },
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/sun8i-r-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun8i-r.h
rename to drivers/clk/sunxi-ng/sun8i-r-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/sun8i-r40-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun8i-r40.c
rename to drivers/clk/sunxi-ng/sun8i-r40-ccu.c
index a2144ee728a0..7347b65a5051 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
+++ b/drivers/clk/sunxi-ng/sun8i-r40-ccu.c
@@ -21,7 +21,7 @@
 #include "ccu_nm.h"
 #include "ccu_phase.h"
 
-#include "ccu-sun8i-r40.h"
+#include "sun8i-r40-ccu.h"
 
 /* TODO: The result of N*K is required to be in [10, 88] range. */
 static struct ccu_nkmp pll_cpu_clk = {
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h b/drivers/clk/sunxi-ng/sun8i-r40-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun8i-r40.h
rename to drivers/clk/sunxi-ng/sun8i-r40-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/sun8i-v3s-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
rename to drivers/clk/sunxi-ng/sun8i-v3s-ccu.c
index ce150f83ab54..58b123ad1212 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
+++ b/drivers/clk/sunxi-ng/sun8i-v3s-ccu.c
@@ -23,7 +23,7 @@
 #include "ccu_nm.h"
 #include "ccu_phase.h"
 
-#include "ccu-sun8i-v3s.h"
+#include "sun8i-v3s-ccu.h"
 
 static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
 				     "osc24M", 0x000,
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h b/drivers/clk/sunxi-ng/sun8i-v3s-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun8i-v3s.h
rename to drivers/clk/sunxi-ng/sun8i-v3s-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/sun9i-a80-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun9i-a80.c
rename to drivers/clk/sunxi-ng/sun9i-a80-ccu.c
index 68b30fdc60fd..bc0b89e18652 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c
+++ b/drivers/clk/sunxi-ng/sun9i-a80-ccu.c
@@ -18,7 +18,7 @@
 #include "ccu_nm.h"
 #include "ccu_phase.h"
 
-#include "ccu-sun9i-a80.h"
+#include "sun9i-a80-ccu.h"
 
 #define CCU_SUN9I_LOCK_REG	0x09c
 
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.h b/drivers/clk/sunxi-ng/sun9i-a80-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun9i-a80.h
rename to drivers/clk/sunxi-ng/sun9i-a80-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c b/drivers/clk/sunxi-ng/sun9i-a80-de-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
rename to drivers/clk/sunxi-ng/sun9i-a80-de-ccu.c
index d2072972b614..5be451411cb4 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c
+++ b/drivers/clk/sunxi-ng/sun9i-a80-de-ccu.c
@@ -14,7 +14,7 @@
 #include "ccu_gate.h"
 #include "ccu_reset.h"
 
-#include "ccu-sun9i-a80-de.h"
+#include "sun9i-a80-de-ccu.h"
 
 static SUNXI_CCU_GATE(fe0_clk,		"fe0",		"fe0-div",
 		      0x00, BIT(0), 0);
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.h b/drivers/clk/sunxi-ng/sun9i-a80-de-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun9i-a80-de.h
rename to drivers/clk/sunxi-ng/sun9i-a80-de-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c b/drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
rename to drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.c
index 596243b3e0fa..62417b6e4f74 100644
--- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
+++ b/drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.c
@@ -12,7 +12,7 @@
 #include "ccu_gate.h"
 #include "ccu_reset.h"
 
-#include "ccu-sun9i-a80-usb.h"
+#include "sun9i-a80-usb-ccu.h"
 
 static const struct clk_parent_data clk_parent_hosc[] = {
 	{ .fw_name = "hosc" },
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.h b/drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.h
rename to drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.h
diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/suniv-f1c100s-ccu.c
similarity index 99%
rename from drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
rename to drivers/clk/sunxi-ng/suniv-f1c100s-ccu.c
index 61ad7ee91c11..850ab8af2471 100644
--- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c
+++ b/drivers/clk/sunxi-ng/suniv-f1c100s-ccu.c
@@ -21,7 +21,7 @@
 #include "ccu_nm.h"
 #include "ccu_phase.h"
 
-#include "ccu-suniv-f1c100s.h"
+#include "suniv-f1c100s-ccu.h"
 
 static struct ccu_nkmp pll_cpu_clk = {
 	.enable = BIT(31),
diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.h b/drivers/clk/sunxi-ng/suniv-f1c100s-ccu.h
similarity index 100%
rename from drivers/clk/sunxi-ng/ccu-suniv-f1c100s.h
rename to drivers/clk/sunxi-ng/suniv-f1c100s-ccu.h
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:05:23 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:23 -0500
Subject: [PATCH 5/8] clk: sunxi-ng: Export symbols used by CCU drivers
In-Reply-To: <20210901050526.45673-1-samuel@sholland.org>
References: <20210901050526.45673-1-samuel@sholland.org>
Message-ID: <20210901050526.45673-6-samuel@sholland.org>

For the individual drivers to be built as modules, the ops structs and
callback registration functions must be exported. None of the helper
functions are exported, because they are only referenced from the
corresponding ops structs. of_sunxi_ccu_probe is not exported, because
it is only used for built-in early OF clock providers.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/ccu_common.c | 2 ++
 drivers/clk/sunxi-ng/ccu_div.c    | 1 +
 drivers/clk/sunxi-ng/ccu_gate.c   | 1 +
 drivers/clk/sunxi-ng/ccu_mp.c     | 2 ++
 drivers/clk/sunxi-ng/ccu_mult.c   | 1 +
 drivers/clk/sunxi-ng/ccu_mux.c    | 2 ++
 drivers/clk/sunxi-ng/ccu_nk.c     | 1 +
 drivers/clk/sunxi-ng/ccu_nkm.c    | 1 +
 drivers/clk/sunxi-ng/ccu_nkmp.c   | 1 +
 drivers/clk/sunxi-ng/ccu_nm.c     | 1 +
 drivers/clk/sunxi-ng/ccu_phase.c  | 1 +
 drivers/clk/sunxi-ng/ccu_reset.c  | 1 +
 12 files changed, 15 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c
index 31af8b6b5286..3ab109582646 100644
--- a/drivers/clk/sunxi-ng/ccu_common.c
+++ b/drivers/clk/sunxi-ng/ccu_common.c
@@ -83,6 +83,7 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb)
 	return clk_notifier_register(pll_nb->common->hw.clk,
 				     &pll_nb->clk_nb);
 }
+EXPORT_SYMBOL_GPL(ccu_pll_notifier_register);
 
 static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 			   struct device_node *node, void __iomem *reg,
@@ -194,6 +195,7 @@ int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(devm_sunxi_ccu_probe);
 
 void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
 			const struct sunxi_ccu_desc *desc)
diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c
index 4c297089483c..74f82a5e340a 100644
--- a/drivers/clk/sunxi-ng/ccu_div.c
+++ b/drivers/clk/sunxi-ng/ccu_div.c
@@ -141,3 +141,4 @@ const struct clk_ops ccu_div_ops = {
 	.recalc_rate	= ccu_div_recalc_rate,
 	.set_rate	= ccu_div_set_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_div_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_gate.c b/drivers/clk/sunxi-ng/ccu_gate.c
index 3d5ca092b08f..3c568efaabff 100644
--- a/drivers/clk/sunxi-ng/ccu_gate.c
+++ b/drivers/clk/sunxi-ng/ccu_gate.c
@@ -124,3 +124,4 @@ const struct clk_ops ccu_gate_ops = {
 	.set_rate	= ccu_gate_set_rate,
 	.recalc_rate	= ccu_gate_recalc_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_gate_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
index 9d3a76604d94..cef8e7cba555 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.c
+++ b/drivers/clk/sunxi-ng/ccu_mp.c
@@ -245,6 +245,7 @@ const struct clk_ops ccu_mp_ops = {
 	.recalc_rate	= ccu_mp_recalc_rate,
 	.set_rate	= ccu_mp_set_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_mp_ops);
 
 /*
  * Support for MMC timing mode switching
@@ -325,3 +326,4 @@ const struct clk_ops ccu_mp_mmc_ops = {
 	.recalc_rate	= ccu_mp_mmc_recalc_rate,
 	.set_rate	= ccu_mp_mmc_set_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_mp_mmc_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
index 7c8cf2e04e94..a7223bd3e9f9 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.c
+++ b/drivers/clk/sunxi-ng/ccu_mult.c
@@ -170,3 +170,4 @@ const struct clk_ops ccu_mult_ops = {
 	.recalc_rate	= ccu_mult_recalc_rate,
 	.set_rate	= ccu_mult_set_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_mult_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c
index 7d75da9a1f2e..785803cd7e51 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.c
+++ b/drivers/clk/sunxi-ng/ccu_mux.c
@@ -251,6 +251,7 @@ const struct clk_ops ccu_mux_ops = {
 	.determine_rate	= __clk_mux_determine_rate,
 	.recalc_rate	= ccu_mux_recalc_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_mux_ops);
 
 /*
  * This clock notifier is called when the frequency of the of the parent
@@ -285,3 +286,4 @@ int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb)
 
 	return clk_notifier_register(clk, &mux_nb->clk_nb);
 }
+EXPORT_SYMBOL_GPL(ccu_mux_notifier_register);
diff --git a/drivers/clk/sunxi-ng/ccu_nk.c b/drivers/clk/sunxi-ng/ccu_nk.c
index aee68b00f3b2..b8fa0bf422fb 100644
--- a/drivers/clk/sunxi-ng/ccu_nk.c
+++ b/drivers/clk/sunxi-ng/ccu_nk.c
@@ -157,3 +157,4 @@ const struct clk_ops ccu_nk_ops = {
 	.round_rate	= ccu_nk_round_rate,
 	.set_rate	= ccu_nk_set_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_nk_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index b9cfee0276ea..583d3ba5e624 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -206,3 +206,4 @@ const struct clk_ops ccu_nkm_ops = {
 	.recalc_rate	= ccu_nkm_recalc_rate,
 	.set_rate	= ccu_nkm_set_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_nkm_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
index bda87b38c45c..ec5224ba5b99 100644
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
@@ -230,3 +230,4 @@ const struct clk_ops ccu_nkmp_ops = {
 	.round_rate	= ccu_nkmp_round_rate,
 	.set_rate	= ccu_nkmp_set_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_nkmp_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index e6bcc0a7170c..576e464bdf03 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -238,3 +238,4 @@ const struct clk_ops ccu_nm_ops = {
 	.round_rate	= ccu_nm_round_rate,
 	.set_rate	= ccu_nm_set_rate,
 };
+EXPORT_SYMBOL_GPL(ccu_nm_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_phase.c b/drivers/clk/sunxi-ng/ccu_phase.c
index 92ab8bd66427..ededb36d531c 100644
--- a/drivers/clk/sunxi-ng/ccu_phase.c
+++ b/drivers/clk/sunxi-ng/ccu_phase.c
@@ -121,3 +121,4 @@ const struct clk_ops ccu_phase_ops = {
 	.get_phase	= ccu_phase_get_phase,
 	.set_phase	= ccu_phase_set_phase,
 };
+EXPORT_SYMBOL_GPL(ccu_phase_ops);
diff --git a/drivers/clk/sunxi-ng/ccu_reset.c b/drivers/clk/sunxi-ng/ccu_reset.c
index 483100e45df3..8413de004574 100644
--- a/drivers/clk/sunxi-ng/ccu_reset.c
+++ b/drivers/clk/sunxi-ng/ccu_reset.c
@@ -75,3 +75,4 @@ const struct reset_control_ops ccu_reset_ops = {
 	.reset		= ccu_reset_reset,
 	.status		= ccu_reset_status,
 };
+EXPORT_SYMBOL_GPL(ccu_reset_ops);
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:05:24 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:24 -0500
Subject: [PATCH 6/8] clk: sunxi-ng: Allow drivers to be built as modules
In-Reply-To: <20210901050526.45673-1-samuel@sholland.org>
References: <20210901050526.45673-1-samuel@sholland.org>
Message-ID: <20210901050526.45673-7-samuel@sholland.org>

While it is useful to build all of the CCU drivers at once, only 1-3 of
them will be loaded at a time, or possibly none of them if the kernel is
booted on a non-sunxi platform. These CCU drivers are relatively large;
32-bit drivers have 30-50k of data each, while the 64-bit ones are
50-75k due to the increased pointer overhead. About half of that data
comes from relocations. Let's allow the user to build these drivers as
modules so only the necessary data is loaded.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/Kconfig             | 16 ++++++++--------
 drivers/clk/sunxi-ng/sun50i-a100-ccu.c   |  3 ++-
 drivers/clk/sunxi-ng/sun50i-a100-r-ccu.c |  3 ++-
 drivers/clk/sunxi-ng/sun50i-a64-ccu.c    |  6 ++++--
 drivers/clk/sunxi-ng/sun50i-h6-ccu.c     |  6 ++++--
 drivers/clk/sunxi-ng/sun8i-a83t-ccu.c    |  6 ++++--
 drivers/clk/sunxi-ng/sun8i-de2-ccu.c     |  8 +++++---
 drivers/clk/sunxi-ng/sun8i-r40-ccu.c     |  5 ++++-
 drivers/clk/sunxi-ng/sun9i-a80-ccu.c     |  6 ++++--
 drivers/clk/sunxi-ng/sun9i-a80-de-ccu.c  |  6 ++++--
 drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.c |  6 ++++--
 11 files changed, 45 insertions(+), 26 deletions(-)

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index cd46d8853876..7cfdf21717f7 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -13,22 +13,22 @@ config SUNIV_F1C100S_CCU
 	depends on MACH_SUNIV || COMPILE_TEST
 
 config SUN50I_A64_CCU
-	bool "Support for the Allwinner A64 CCU"
+	tristate "Support for the Allwinner A64 CCU"
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_A100_CCU
-	bool "Support for the Allwinner A100 CCU"
+	tristate "Support for the Allwinner A100 CCU"
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_A100_R_CCU
-	bool "Support for the Allwinner A100 PRCM CCU"
+	tristate "Support for the Allwinner A100 PRCM CCU"
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_H6_CCU
-	bool "Support for the Allwinner H6 CCU"
+	tristate "Support for the Allwinner H6 CCU"
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
@@ -69,7 +69,7 @@ config SUN8I_A33_CCU
 	depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN8I_A83T_CCU
-	bool "Support for the Allwinner A83T CCU"
+	tristate "Support for the Allwinner A83T CCU"
 	default MACH_SUN8I
 
 config SUN8I_H3_CCU
@@ -83,16 +83,16 @@ config SUN8I_V3S_CCU
 	depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN8I_DE2_CCU
-	bool "Support for the Allwinner SoCs DE2 CCU"
+	tristate "Support for the Allwinner SoCs DE2 CCU"
 	default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
 
 config SUN8I_R40_CCU
-	bool "Support for the Allwinner R40 CCU"
+	tristate "Support for the Allwinner R40 CCU"
 	default MACH_SUN8I
 	depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN9I_A80_CCU
-	bool "Support for the Allwinner A80 CCU"
+	tristate "Support for the Allwinner A80 CCU"
 	default MACH_SUN9I
 	depends on MACH_SUN9I || COMPILE_TEST
 
diff --git a/drivers/clk/sunxi-ng/sun50i-a100-ccu.c b/drivers/clk/sunxi-ng/sun50i-a100-ccu.c
index 5a813af9941c..5bb901c3b2f5 100644
--- a/drivers/clk/sunxi-ng/sun50i-a100-ccu.c
+++ b/drivers/clk/sunxi-ng/sun50i-a100-ccu.c
@@ -6,7 +6,6 @@
 #include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/of_address.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -1275,3 +1274,5 @@ static struct platform_driver sun50i_a100_ccu_driver = {
 	},
 };
 module_platform_driver(sun50i_a100_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun50i-a100-r-ccu.c b/drivers/clk/sunxi-ng/sun50i-a100-r-ccu.c
index 078ebdf8b093..6842d69616a4 100644
--- a/drivers/clk/sunxi-ng/sun50i-a100-r-ccu.c
+++ b/drivers/clk/sunxi-ng/sun50i-a100-r-ccu.c
@@ -5,7 +5,6 @@
 
 #include <linux/clk-provider.h>
 #include <linux/module.h>
-#include <linux/of_address.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -213,3 +212,5 @@ static struct platform_driver sun50i_a100_r_ccu_driver = {
 	},
 };
 module_platform_driver(sun50i_a100_r_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun50i-a64-ccu.c b/drivers/clk/sunxi-ng/sun50i-a64-ccu.c
index ffc5ef5fab3c..0e7ba14d58ca 100644
--- a/drivers/clk/sunxi-ng/sun50i-a64-ccu.c
+++ b/drivers/clk/sunxi-ng/sun50i-a64-ccu.c
@@ -5,7 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -982,4 +982,6 @@ static struct platform_driver sun50i_a64_ccu_driver = {
 		.of_match_table	= sun50i_a64_ccu_ids,
 	},
 };
-builtin_platform_driver(sun50i_a64_ccu_driver);
+module_platform_driver(sun50i_a64_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun50i-h6-ccu.c b/drivers/clk/sunxi-ng/sun50i-h6-ccu.c
index 8876358710c5..c28a09e4938d 100644
--- a/drivers/clk/sunxi-ng/sun50i-h6-ccu.c
+++ b/drivers/clk/sunxi-ng/sun50i-h6-ccu.c
@@ -5,7 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -1256,4 +1256,6 @@ static struct platform_driver sun50i_h6_ccu_driver = {
 		.of_match_table	= sun50i_h6_ccu_ids,
 	},
 };
-builtin_platform_driver(sun50i_h6_ccu_driver);
+module_platform_driver(sun50i_h6_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun8i-a83t-ccu.c b/drivers/clk/sunxi-ng/sun8i-a83t-ccu.c
index 067eb9bb4b53..8ae7b0417a6b 100644
--- a/drivers/clk/sunxi-ng/sun8i-a83t-ccu.c
+++ b/drivers/clk/sunxi-ng/sun8i-a83t-ccu.c
@@ -5,7 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -922,4 +922,6 @@ static struct platform_driver sun8i_a83t_ccu_driver = {
 		.of_match_table	= sun8i_a83t_ccu_ids,
 	},
 };
-builtin_platform_driver(sun8i_a83t_ccu_driver);
+module_platform_driver(sun8i_a83t_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun8i-de2-ccu.c b/drivers/clk/sunxi-ng/sun8i-de2-ccu.c
index 15d15448ac21..61c185cbc04a 100644
--- a/drivers/clk/sunxi-ng/sun8i-de2-ccu.c
+++ b/drivers/clk/sunxi-ng/sun8i-de2-ccu.c
@@ -5,8 +5,8 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
@@ -396,4 +396,6 @@ static struct platform_driver sunxi_de2_clk_driver = {
 		.of_match_table	= sunxi_de2_clk_ids,
 	},
 };
-builtin_platform_driver(sunxi_de2_clk_driver);
+module_platform_driver(sunxi_de2_clk_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun8i-r40-ccu.c b/drivers/clk/sunxi-ng/sun8i-r40-ccu.c
index 7347b65a5051..a090b21002b6 100644
--- a/drivers/clk/sunxi-ng/sun8i-r40-ccu.c
+++ b/drivers/clk/sunxi-ng/sun8i-r40-ccu.c
@@ -5,6 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
@@ -1373,4 +1374,6 @@ static struct platform_driver sun8i_r40_ccu_driver = {
 		.of_match_table	= sun8i_r40_ccu_ids,
 	},
 };
-builtin_platform_driver(sun8i_r40_ccu_driver);
+module_platform_driver(sun8i_r40_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun9i-a80-ccu.c b/drivers/clk/sunxi-ng/sun9i-a80-ccu.c
index bc0b89e18652..ae654078eca5 100644
--- a/drivers/clk/sunxi-ng/sun9i-a80-ccu.c
+++ b/drivers/clk/sunxi-ng/sun9i-a80-ccu.c
@@ -5,7 +5,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -1247,4 +1247,6 @@ static struct platform_driver sun9i_a80_ccu_driver = {
 		.of_match_table	= sun9i_a80_ccu_ids,
 	},
 };
-builtin_platform_driver(sun9i_a80_ccu_driver);
+module_platform_driver(sun9i_a80_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun9i-a80-de-ccu.c b/drivers/clk/sunxi-ng/sun9i-a80-de-ccu.c
index 5be451411cb4..69303f5d7747 100644
--- a/drivers/clk/sunxi-ng/sun9i-a80-de-ccu.c
+++ b/drivers/clk/sunxi-ng/sun9i-a80-de-ccu.c
@@ -5,7 +5,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
@@ -272,4 +272,6 @@ static struct platform_driver sun9i_a80_de_clk_driver = {
 		.of_match_table	= sun9i_a80_de_clk_ids,
 	},
 };
-builtin_platform_driver(sun9i_a80_de_clk_driver);
+module_platform_driver(sun9i_a80_de_clk_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.c b/drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.c
index 62417b6e4f74..a9cab6d70953 100644
--- a/drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.c
+++ b/drivers/clk/sunxi-ng/sun9i-a80-usb-ccu.c
@@ -5,7 +5,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -140,4 +140,6 @@ static struct platform_driver sun9i_a80_usb_clk_driver = {
 		.of_match_table	= sun9i_a80_usb_clk_ids,
 	},
 };
-builtin_platform_driver(sun9i_a80_usb_clk_driver);
+module_platform_driver(sun9i_a80_usb_clk_driver);
+
+MODULE_LICENSE("GPL");
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:05:26 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:26 -0500
Subject: [PATCH 8/8] clk: sunxi-ng: Allow the CCU core to be built as a module
In-Reply-To: <20210901050526.45673-1-samuel@sholland.org>
References: <20210901050526.45673-1-samuel@sholland.org>
Message-ID: <20210901050526.45673-9-samuel@sholland.org>

Like the individual CCU drivers, it can be beneficial for memory
consumption of cross-platform configurations to only load the CCU core
on the relevant platform. For example, a generic arm64 kernel sees the
following improvement when building the CCU core and drivers as modules:

  before:
    text      data     bss     dec       hex      filename
    13882360  5251670  360800  19494830  12977ae  vmlinux

  after:
    text      data     bss     dec       hex      filename
    13734787  5086442  360800  19182029  124b1cd  vmlinux

So the result is a 390KB total reduction in kernel image size.

The one early clock provider (sun5i) requires the core to be built in.

Now that loading the MMC driver will trigger loading the CCU core, the
MMC timing mode functions do not need a compile-time fallback.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/Makefile              |  2 +-
 drivers/clk/sunxi-ng/Kconfig      |  3 ++-
 drivers/clk/sunxi-ng/Makefile     | 33 +++++++++++++++++--------------
 drivers/clk/sunxi-ng/ccu_common.c |  3 +++
 drivers/mmc/host/Kconfig          |  1 +
 include/linux/clk/sunxi-ng.h      | 15 --------------
 6 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 2b91d34c582b..009c4b41a45a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -110,7 +110,7 @@ obj-$(CONFIG_PLAT_SPEAR)		+= spear/
 obj-y					+= sprd/
 obj-$(CONFIG_ARCH_STI)			+= st/
 obj-$(CONFIG_ARCH_SUNXI)		+= sunxi/
-obj-$(CONFIG_SUNXI_CCU)			+= sunxi-ng/
+obj-y					+= sunxi-ng/
 obj-$(CONFIG_ARCH_TEGRA)		+= tegra/
 obj-y					+= ti/
 obj-$(CONFIG_CLK_UNIPHIER)		+= uniphier/
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index cbae3612a9ef..ee383658ff4d 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config SUNXI_CCU
-	bool "Clock support for Allwinner SoCs"
+	tristate "Clock support for Allwinner SoCs"
 	depends on ARCH_SUNXI || COMPILE_TEST
 	select RESET_CONTROLLER
 	default ARCH_SUNXI
@@ -52,6 +52,7 @@ config SUN5I_CCU
 	bool "Support for the Allwinner sun5i family CCM"
 	default MACH_SUN5I
 	depends on MACH_SUN5I || COMPILE_TEST
+	depends on SUNXI_CCU=y
 
 config SUN6I_A31_CCU
 	tristate "Support for the Allwinner A31/A31s CCU"
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 9ebf5920c93b..6e9eb004fca0 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -1,24 +1,27 @@
 # SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SUNXI_CCU)		+= sunxi-ccu.o
+
 # Common objects
-obj-y				+= ccu_common.o
-obj-y				+= ccu_mmc_timing.o
-obj-y				+= ccu_reset.o
+sunxi-ccu-y			+= ccu_common.o
+sunxi-ccu-y			+= ccu_mmc_timing.o
+sunxi-ccu-y			+= ccu_reset.o
 
 # Base clock types
-obj-y				+= ccu_div.o
-obj-y				+= ccu_frac.o
-obj-y				+= ccu_gate.o
-obj-y				+= ccu_mux.o
-obj-y				+= ccu_mult.o
-obj-y				+= ccu_phase.o
-obj-y				+= ccu_sdm.o
+sunxi-ccu-y			+= ccu_div.o
+sunxi-ccu-y			+= ccu_frac.o
+sunxi-ccu-y			+= ccu_gate.o
+sunxi-ccu-y			+= ccu_mux.o
+sunxi-ccu-y			+= ccu_mult.o
+sunxi-ccu-y			+= ccu_phase.o
+sunxi-ccu-y			+= ccu_sdm.o
 
 # Multi-factor clocks
-obj-y				+= ccu_nk.o
-obj-y				+= ccu_nkm.o
-obj-y				+= ccu_nkmp.o
-obj-y				+= ccu_nm.o
-obj-y				+= ccu_mp.o
+sunxi-ccu-y			+= ccu_nk.o
+sunxi-ccu-y			+= ccu_nkm.o
+sunxi-ccu-y			+= ccu_nkmp.o
+sunxi-ccu-y			+= ccu_nm.o
+sunxi-ccu-y			+= ccu_mp.o
 
 # SoC support
 obj-$(CONFIG_SUNIV_F1C100S_CCU)	+= suniv-f1c100s-ccu.o
diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c
index 3ab109582646..d9619ad32f5c 100644
--- a/drivers/clk/sunxi-ng/ccu_common.c
+++ b/drivers/clk/sunxi-ng/ccu_common.c
@@ -9,6 +9,7 @@
 #include <linux/clk-provider.h>
 #include <linux/device.h>
 #include <linux/iopoll.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 
 #include "ccu_common.h"
@@ -213,3 +214,5 @@ void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
 		kfree(ccu);
 	}
 }
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 71313961cc54..1247c9455dea 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -964,6 +964,7 @@ config MMC_REALTEK_USB
 config MMC_SUNXI
 	tristate "Allwinner sunxi SD/MMC Host Controller support"
 	depends on ARCH_SUNXI || COMPILE_TEST
+	depends on SUNXI_CCU
 	help
 	  This selects support for the SD/MMC Host Controller on
 	  Allwinner sunxi SoCs.
diff --git a/include/linux/clk/sunxi-ng.h b/include/linux/clk/sunxi-ng.h
index 3cd14acde0a1..cf32123b39f5 100644
--- a/include/linux/clk/sunxi-ng.h
+++ b/include/linux/clk/sunxi-ng.h
@@ -6,22 +6,7 @@
 #ifndef _LINUX_CLK_SUNXI_NG_H_
 #define _LINUX_CLK_SUNXI_NG_H_
 
-#include <linux/errno.h>
-
-#ifdef CONFIG_SUNXI_CCU
 int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode);
 int sunxi_ccu_get_mmc_timing_mode(struct clk *clk);
-#else
-static inline int sunxi_ccu_set_mmc_timing_mode(struct clk *clk,
-						bool new_mode)
-{
-	return -ENOTSUPP;
-}
-
-static inline int sunxi_ccu_get_mmc_timing_mode(struct clk *clk)
-{
-	return -ENOTSUPP;
-}
-#endif
 
 #endif
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:05:25 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:05:25 -0500
Subject: [PATCH 7/8] clk: sunxi-ng: Convert early providers to platform drivers
In-Reply-To: <20210901050526.45673-1-samuel@sholland.org>
References: <20210901050526.45673-1-samuel@sholland.org>
Message-ID: <20210901050526.45673-8-samuel@sholland.org>

The PRCM CCU drivers depend on clocks provided by other CCU drivers. For
example, the sun8i-r-ccu driver uses the "pll-periph" clock provided by
the SoC's main CCU.

However, sun8i-r-ccu is an early OF clock provider, and many of the
main CCUs (e.g. sun50i-a64-ccu) use platform drivers. This means that
the consumer clocks will be orphaned until the supplier driver is bound.
This can be avoided by converting the remaining CCUs to use platform
drivers. Then fw_devlink will ensure the drivers are bound in the
optimal order.

The sun5i CCU is the only one which actually needs to be an early clock
provider, because it provides the clock for the system timer. That one
is left alone.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/Kconfig             | 20 ++++----
 drivers/clk/sunxi-ng/sun4i-a10-ccu.c     | 57 +++++++++++++--------
 drivers/clk/sunxi-ng/sun50i-h6-r-ccu.c   | 55 ++++++++++++--------
 drivers/clk/sunxi-ng/sun50i-h616-ccu.c   | 32 ++++++++----
 drivers/clk/sunxi-ng/sun6i-a31-ccu.c     | 39 +++++++++++----
 drivers/clk/sunxi-ng/sun8i-a23-ccu.c     | 34 +++++++++----
 drivers/clk/sunxi-ng/sun8i-a33-ccu.c     | 39 +++++++++++----
 drivers/clk/sunxi-ng/sun8i-h3-ccu.c      | 61 ++++++++++++++--------
 drivers/clk/sunxi-ng/sun8i-r-ccu.c       | 64 ++++++++++++++----------
 drivers/clk/sunxi-ng/sun8i-v3s-ccu.c     | 56 +++++++++++++--------
 drivers/clk/sunxi-ng/suniv-f1c100s-ccu.c | 37 ++++++++++----
 11 files changed, 322 insertions(+), 172 deletions(-)

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 7cfdf21717f7..cbae3612a9ef 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -8,7 +8,7 @@ config SUNXI_CCU
 if SUNXI_CCU
 
 config SUNIV_F1C100S_CCU
-	bool "Support for the Allwinner newer F1C100s CCU"
+	tristate "Support for the Allwinner newer F1C100s CCU"
 	default MACH_SUNIV
 	depends on MACH_SUNIV || COMPILE_TEST
 
@@ -33,17 +33,17 @@ config SUN50I_H6_CCU
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_H616_CCU
-	bool "Support for the Allwinner H616 CCU"
+	tristate "Support for the Allwinner H616 CCU"
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN50I_H6_R_CCU
-	bool "Support for the Allwinner H6 and H616 PRCM CCU"
+	tristate "Support for the Allwinner H6 and H616 PRCM CCU"
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN4I_A10_CCU
-	bool "Support for the Allwinner A10/A20 CCU"
+	tristate "Support for the Allwinner A10/A20 CCU"
 	default MACH_SUN4I
 	default MACH_SUN7I
 	depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
@@ -54,17 +54,17 @@ config SUN5I_CCU
 	depends on MACH_SUN5I || COMPILE_TEST
 
 config SUN6I_A31_CCU
-	bool "Support for the Allwinner A31/A31s CCU"
+	tristate "Support for the Allwinner A31/A31s CCU"
 	default MACH_SUN6I
 	depends on MACH_SUN6I || COMPILE_TEST
 
 config SUN8I_A23_CCU
-	bool "Support for the Allwinner A23 CCU"
+	tristate "Support for the Allwinner A23 CCU"
 	default MACH_SUN8I
 	depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN8I_A33_CCU
-	bool "Support for the Allwinner A33 CCU"
+	tristate "Support for the Allwinner A33 CCU"
 	default MACH_SUN8I
 	depends on MACH_SUN8I || COMPILE_TEST
 
@@ -73,12 +73,12 @@ config SUN8I_A83T_CCU
 	default MACH_SUN8I
 
 config SUN8I_H3_CCU
-	bool "Support for the Allwinner H3 CCU"
+	tristate "Support for the Allwinner H3 CCU"
 	default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
 	depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN8I_V3S_CCU
-	bool "Support for the Allwinner V3s CCU"
+	tristate "Support for the Allwinner V3s CCU"
 	default MACH_SUN8I
 	depends on MACH_SUN8I || COMPILE_TEST
 
@@ -97,7 +97,7 @@ config SUN9I_A80_CCU
 	depends on MACH_SUN9I || COMPILE_TEST
 
 config SUN8I_R_CCU
-	bool "Support for Allwinner SoCs' PRCM CCUs"
+	tristate "Support for Allwinner SoCs' PRCM CCUs"
 	default MACH_SUN8I || (ARCH_SUNXI && ARM64)
 
 endif
diff --git a/drivers/clk/sunxi-ng/sun4i-a10-ccu.c b/drivers/clk/sunxi-ng/sun4i-a10-ccu.c
index 5d67f5666943..027b9667f472 100644
--- a/drivers/clk/sunxi-ng/sun4i-a10-ccu.c
+++ b/drivers/clk/sunxi-ng/sun4i-a10-ccu.c
@@ -7,7 +7,9 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -1425,18 +1427,19 @@ static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = {
 	.num_resets	= ARRAY_SIZE(sunxi_a10_a20_ccu_resets),
 };
 
-static void __init sun4i_ccu_init(struct device_node *node,
-				  const struct sunxi_ccu_desc *desc)
+static int sun4i_a10_ccu_probe(struct platform_device *pdev)
 {
+	const struct sunxi_ccu_desc *desc;
 	void __iomem *reg;
 	u32 val;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%s: Could not map the clock registers\n",
-		       of_node_full_name(node));
-		return;
-	}
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
 	val = readl(reg + SUN4I_PLL_AUDIO_REG);
 
@@ -1464,19 +1467,29 @@ static void __init sun4i_ccu_init(struct device_node *node,
 	val &= ~GENMASK(7, 6);
 	writel(val | (2 << 6), reg + SUN4I_AHB_REG);
 
-	of_sunxi_ccu_probe(node, reg, desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
 
-static void __init sun4i_a10_ccu_setup(struct device_node *node)
-{
-	sun4i_ccu_init(node, &sun4i_a10_ccu_desc);
-}
-CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu",
-	       sun4i_a10_ccu_setup);
+static const struct of_device_id sun4i_a10_ccu_ids[] = {
+	{
+		.compatible = "allwinner,sun4i-a10-ccu",
+		.data = &sun4i_a10_ccu_desc,
+	},
+	{
+		.compatible = "allwinner,sun7i-a20-ccu",
+		.data = &sun7i_a20_ccu_desc,
+	},
+	{ }
+};
 
-static void __init sun7i_a20_ccu_setup(struct device_node *node)
-{
-	sun4i_ccu_init(node, &sun7i_a20_ccu_desc);
-}
-CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu",
-	       sun7i_a20_ccu_setup);
+static struct platform_driver sun4i_a10_ccu_driver = {
+	.probe	= sun4i_a10_ccu_probe,
+	.driver	= {
+		.name			= "sun4i-a10-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun4i_a10_ccu_ids,
+	},
+};
+module_platform_driver(sun4i_a10_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun50i-h6-r-ccu.c b/drivers/clk/sunxi-ng/sun50i-h6-r-ccu.c
index bb7f9ed78c4c..2b2f809fd090 100644
--- a/drivers/clk/sunxi-ng/sun50i-h6-r-ccu.c
+++ b/drivers/clk/sunxi-ng/sun50i-h6-r-ccu.c
@@ -4,7 +4,8 @@
  */
 
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -221,30 +222,42 @@ static const struct sunxi_ccu_desc sun50i_h616_r_ccu_desc = {
 	.num_resets	= ARRAY_SIZE(sun50i_h616_r_ccu_resets),
 };
 
-static void __init sunxi_r_ccu_init(struct device_node *node,
-				    const struct sunxi_ccu_desc *desc)
+static int sun50i_h6_r_ccu_probe(struct platform_device *pdev)
 {
+	const struct sunxi_ccu_desc *desc;
 	void __iomem *reg;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map the clock registers\n", node);
-		return;
-	}
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
 
-	of_sunxi_ccu_probe(node, reg, desc);
-}
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
-static void __init sun50i_h6_r_ccu_setup(struct device_node *node)
-{
-	sunxi_r_ccu_init(node, &sun50i_h6_r_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
-CLK_OF_DECLARE(sun50i_h6_r_ccu, "allwinner,sun50i-h6-r-ccu",
-	       sun50i_h6_r_ccu_setup);
 
-static void __init sun50i_h616_r_ccu_setup(struct device_node *node)
-{
-	sunxi_r_ccu_init(node, &sun50i_h616_r_ccu_desc);
-}
-CLK_OF_DECLARE(sun50i_h616_r_ccu, "allwinner,sun50i-h616-r-ccu",
-	       sun50i_h616_r_ccu_setup);
+static const struct of_device_id sun50i_h6_r_ccu_ids[] = {
+	{
+		.compatible = "allwinner,sun50i-h6-r-ccu",
+		.data = &sun50i_h6_r_ccu_desc,
+	},
+	{
+		.compatible = "allwinner,sun50i-h616-r-ccu",
+		.data = &sun50i_h616_r_ccu_desc,
+	},
+	{ }
+};
+
+static struct platform_driver sun50i_h6_r_ccu_driver = {
+	.probe	= sun50i_h6_r_ccu_probe,
+	.driver	= {
+		.name			= "sun50i-h6-r-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun50i_h6_r_ccu_ids,
+	},
+};
+module_platform_driver(sun50i_h6_r_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun50i-h616-ccu.c b/drivers/clk/sunxi-ng/sun50i-h616-ccu.c
index 71d75833253f..4f6eb5474d4b 100644
--- a/drivers/clk/sunxi-ng/sun50i-h616-ccu.c
+++ b/drivers/clk/sunxi-ng/sun50i-h616-ccu.c
@@ -7,7 +7,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -1082,17 +1082,15 @@ static const u32 usb2_clk_regs[] = {
 	SUN50I_H616_USB3_CLK_REG,
 };
 
-static void __init sun50i_h616_ccu_setup(struct device_node *node)
+static int sun50i_h616_ccu_probe(struct platform_device *pdev)
 {
 	void __iomem *reg;
 	u32 val;
 	int i;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map clock registers\n", node);
-		return;
-	}
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
 	/* Enable the lock bits and the output enable bits on all PLLs */
 	for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
@@ -1141,8 +1139,22 @@ static void __init sun50i_h616_ccu_setup(struct device_node *node)
 	val |= BIT(24);
 	writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
 
-	of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc);
 }
 
-CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu",
-	       sun50i_h616_ccu_setup);
+static const struct of_device_id sun50i_h616_ccu_ids[] = {
+	{ .compatible = "allwinner,sun50i-h616-ccu" },
+	{ }
+};
+
+static struct platform_driver sun50i_h616_ccu_driver = {
+	.probe	= sun50i_h616_ccu_probe,
+	.driver	= {
+		.name			= "sun50i-h616-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun50i_h616_ccu_ids,
+	},
+};
+module_platform_driver(sun50i_h616_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun6i-a31-ccu.c b/drivers/clk/sunxi-ng/sun6i-a31-ccu.c
index b05c06a428ad..36597a5262e1 100644
--- a/drivers/clk/sunxi-ng/sun6i-a31-ccu.c
+++ b/drivers/clk/sunxi-ng/sun6i-a31-ccu.c
@@ -9,7 +9,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -1226,16 +1227,15 @@ static struct ccu_mux_nb sun6i_a31_cpu_nb = {
 	.bypass_index	= 1, /* index of 24 MHz oscillator */
 };
 
-static void __init sun6i_a31_ccu_setup(struct device_node *node)
+static int sun6i_a31_ccu_probe(struct platform_device *pdev)
 {
 	void __iomem *reg;
+	int ret;
 	u32 val;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map the clock registers\n", node);
-		return;
-	}
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
 	/* Force the PLL-Audio-1x divider to 1 */
 	val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
@@ -1257,10 +1257,29 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
 	val |= 0x3 << 12;
 	writel(val, reg + SUN6I_A31_AHB1_REG);
 
-	of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun6i_a31_ccu_desc);
+	if (ret)
+		return ret;
 
 	ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
 				  &sun6i_a31_cpu_nb);
+
+	return 0;
 }
-CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu",
-	       sun6i_a31_ccu_setup);
+
+static const struct of_device_id sun6i_a31_ccu_ids[] = {
+	{ .compatible = "allwinner,sun6i-a31-ccu" },
+	{ }
+};
+
+static struct platform_driver sun6i_a31_ccu_driver = {
+	.probe	= sun6i_a31_ccu_probe,
+	.driver	= {
+		.name			= "sun6i-a31-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun6i_a31_ccu_ids,
+	},
+};
+module_platform_driver(sun6i_a31_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun8i-a23-ccu.c b/drivers/clk/sunxi-ng/sun8i-a23-ccu.c
index 5bbc66a762db..6c469fdcdab3 100644
--- a/drivers/clk/sunxi-ng/sun8i-a23-ccu.c
+++ b/drivers/clk/sunxi-ng/sun8i-a23-ccu.c
@@ -5,7 +5,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -724,16 +725,14 @@ static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = {
 	.num_resets	= ARRAY_SIZE(sun8i_a23_ccu_resets),
 };
 
-static void __init sun8i_a23_ccu_setup(struct device_node *node)
+static int sun8i_a23_ccu_probe(struct platform_device *pdev)
 {
 	void __iomem *reg;
 	u32 val;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map the clock registers\n", node);
-		return;
-	}
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
 	/* Force the PLL-Audio-1x divider to 1 */
 	val = readl(reg + SUN8I_A23_PLL_AUDIO_REG);
@@ -745,7 +744,22 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node)
 	val &= ~BIT(16);
 	writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
 
-	of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a23_ccu_desc);
 }
-CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu",
-	       sun8i_a23_ccu_setup);
+
+static const struct of_device_id sun8i_a23_ccu_ids[] = {
+	{ .compatible = "allwinner,sun8i-a23-ccu" },
+	{ }
+};
+
+static struct platform_driver sun8i_a23_ccu_driver = {
+	.probe	= sun8i_a23_ccu_probe,
+	.driver	= {
+		.name			= "sun8i-a23-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun8i_a23_ccu_ids,
+	},
+};
+module_platform_driver(sun8i_a23_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun8i-a33-ccu.c b/drivers/clk/sunxi-ng/sun8i-a33-ccu.c
index 6cd214b444d1..ac493198ea14 100644
--- a/drivers/clk/sunxi-ng/sun8i-a33-ccu.c
+++ b/drivers/clk/sunxi-ng/sun8i-a33-ccu.c
@@ -5,7 +5,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -784,16 +785,15 @@ static struct ccu_mux_nb sun8i_a33_cpu_nb = {
 	.bypass_index	= 1, /* index of 24 MHz oscillator */
 };
 
-static void __init sun8i_a33_ccu_setup(struct device_node *node)
+static int sun8i_a33_ccu_probe(struct platform_device *pdev)
 {
 	void __iomem *reg;
+	int ret;
 	u32 val;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map the clock registers\n", node);
-		return;
-	}
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
 	/* Force the PLL-Audio-1x divider to 1 */
 	val = readl(reg + SUN8I_A33_PLL_AUDIO_REG);
@@ -805,7 +805,9 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
 	val &= ~BIT(16);
 	writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
 
-	of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a33_ccu_desc);
+	if (ret)
+		return ret;
 
 	/* Gate then ungate PLL CPU after any rate changes */
 	ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb);
@@ -813,6 +815,23 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
 	/* Reparent CPU during PLL CPU rate changes */
 	ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
 				  &sun8i_a33_cpu_nb);
+
+	return 0;
 }
-CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
-	       sun8i_a33_ccu_setup);
+
+static const struct of_device_id sun8i_a33_ccu_ids[] = {
+	{ .compatible = "allwinner,sun8i-a33-ccu" },
+	{ }
+};
+
+static struct platform_driver sun8i_a33_ccu_driver = {
+	.probe	= sun8i_a33_ccu_probe,
+	.driver	= {
+		.name			= "sun8i-a33-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun8i_a33_ccu_ids,
+	},
+};
+module_platform_driver(sun8i_a33_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun8i-h3-ccu.c b/drivers/clk/sunxi-ng/sun8i-h3-ccu.c
index c566cc1aa168..a93f48535f44 100644
--- a/drivers/clk/sunxi-ng/sun8i-h3-ccu.c
+++ b/drivers/clk/sunxi-ng/sun8i-h3-ccu.c
@@ -5,7 +5,9 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -1137,24 +1139,29 @@ static struct ccu_mux_nb sun8i_h3_cpu_nb = {
 	.bypass_index	= 1, /* index of 24 MHz oscillator */
 };
 
-static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
-					const struct sunxi_ccu_desc *desc)
+static int sun8i_h3_ccu_probe(struct platform_device *pdev)
 {
+	const struct sunxi_ccu_desc *desc;
 	void __iomem *reg;
+	int ret;
 	u32 val;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map the clock registers\n", node);
-		return;
-	}
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
 	/* Force the PLL-Audio-1x divider to 1 */
 	val = readl(reg + SUN8I_H3_PLL_AUDIO_REG);
 	val &= ~GENMASK(19, 16);
 	writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
 
-	of_sunxi_ccu_probe(node, reg, desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
+	if (ret)
+		return ret;
 
 	/* Gate then ungate PLL CPU after any rate changes */
 	ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
@@ -1162,18 +1169,30 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
 	/* Reparent CPU during PLL CPU rate changes */
 	ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
 				  &sun8i_h3_cpu_nb);
-}
 
-static void __init sun8i_h3_ccu_setup(struct device_node *node)
-{
-	sunxi_h3_h5_ccu_init(node, &sun8i_h3_ccu_desc);
+	return 0;
 }
-CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu",
-	       sun8i_h3_ccu_setup);
 
-static void __init sun50i_h5_ccu_setup(struct device_node *node)
-{
-	sunxi_h3_h5_ccu_init(node, &sun50i_h5_ccu_desc);
-}
-CLK_OF_DECLARE(sun50i_h5_ccu, "allwinner,sun50i-h5-ccu",
-	       sun50i_h5_ccu_setup);
+static const struct of_device_id sun8i_h3_ccu_ids[] = {
+	{
+		.compatible = "allwinner,sun8i-h3-ccu",
+		.data = &sun8i_h3_ccu_desc,
+	},
+	{
+		.compatible = "allwinner,sun50i-h5-ccu",
+		.data = &sun50i_h5_ccu_desc,
+	},
+	{ }
+};
+
+static struct platform_driver sun8i_h3_ccu_driver = {
+	.probe	= sun8i_h3_ccu_probe,
+	.driver	= {
+		.name			= "sun8i-h3-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun8i_h3_ccu_ids,
+	},
+};
+module_platform_driver(sun8i_h3_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun8i-r-ccu.c b/drivers/clk/sunxi-ng/sun8i-r-ccu.c
index eb623b01df58..56c242e71127 100644
--- a/drivers/clk/sunxi-ng/sun8i-r-ccu.c
+++ b/drivers/clk/sunxi-ng/sun8i-r-ccu.c
@@ -4,7 +4,8 @@
  */
 
 #include <linux/clk-provider.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
 #include "ccu_common.h"
@@ -254,37 +255,46 @@ static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
 	.num_resets	= ARRAY_SIZE(sun50i_a64_r_ccu_resets),
 };
 
-static void __init sunxi_r_ccu_init(struct device_node *node,
-				    const struct sunxi_ccu_desc *desc)
+static int sun8i_r_ccu_probe(struct platform_device *pdev)
 {
+	const struct sunxi_ccu_desc *desc;
 	void __iomem *reg;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map the clock registers\n", node);
-		return;
-	}
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
 
-	of_sunxi_ccu_probe(node, reg, desc);
-}
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
-static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
-{
-	sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
-CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu",
-	       sun8i_a83t_r_ccu_setup);
 
-static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
-{
-	sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
-}
-CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
-	       sun8i_h3_r_ccu_setup);
+static const struct of_device_id sun8i_r_ccu_ids[] = {
+	{
+		.compatible = "allwinner,sun8i-a83t-r-ccu",
+		.data = &sun8i_a83t_r_ccu_desc,
+	},
+	{
+		.compatible = "allwinner,sun8i-h3-r-ccu",
+		.data = &sun8i_h3_r_ccu_desc,
+	},
+	{
+		.compatible = "allwinner,sun50i-a64-r-ccu",
+		.data = &sun50i_a64_r_ccu_desc,
+	},
+	{ }
+};
 
-static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
-{
-	sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
-}
-CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
-	       sun50i_a64_r_ccu_setup);
+static struct platform_driver sun8i_r_ccu_driver = {
+	.probe	= sun8i_r_ccu_probe,
+	.driver	= {
+		.name			= "sun8i-r-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun8i_r_ccu_ids,
+	},
+};
+module_platform_driver(sun8i_r_ccu_driver);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/sun8i-v3s-ccu.c b/drivers/clk/sunxi-ng/sun8i-v3s-ccu.c
index 58b123ad1212..5ce0fe0e3358 100644
--- a/drivers/clk/sunxi-ng/sun8i-v3s-ccu.c
+++ b/drivers/clk/sunxi-ng/sun8i-v3s-ccu.c
@@ -8,7 +8,9 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -805,38 +807,48 @@ static const struct sunxi_ccu_desc sun8i_v3_ccu_desc = {
 	.num_resets	= ARRAY_SIZE(sun8i_v3_ccu_resets),
 };
 
-static void __init sun8i_v3_v3s_ccu_init(struct device_node *node,
-					 const struct sunxi_ccu_desc *ccu_desc)
+static int sun8i_v3s_ccu_probe(struct platform_device *pdev)
 {
+	const struct sunxi_ccu_desc *desc;
 	void __iomem *reg;
 	u32 val;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map the clock registers\n", node);
-		return;
-	}
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
 	/* Force the PLL-Audio-1x divider to 1 */
 	val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG);
 	val &= ~GENMASK(19, 16);
 	writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG);
 
-	of_sunxi_ccu_probe(node, reg, ccu_desc);
-}
-
-static void __init sun8i_v3s_ccu_setup(struct device_node *node)
-{
-	sun8i_v3_v3s_ccu_init(node, &sun8i_v3s_ccu_desc);
+	return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
 }
 
-static void __init sun8i_v3_ccu_setup(struct device_node *node)
-{
-	sun8i_v3_v3s_ccu_init(node, &sun8i_v3_ccu_desc);
-}
+static const struct of_device_id sun8i_v3s_ccu_ids[] = {
+	{
+		.compatible = "allwinner,sun8i-v3-ccu",
+		.data = &sun8i_v3_ccu_desc,
+	},
+	{
+		.compatible = "allwinner,sun8i-v3s-ccu",
+		.data = &sun8i_v3s_ccu_desc,
+	},
+	{ }
+};
 
-CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
-	       sun8i_v3s_ccu_setup);
+static struct platform_driver sun8i_v3s_ccu_driver = {
+	.probe	= sun8i_v3s_ccu_probe,
+	.driver	= {
+		.name			= "sun8i-v3s-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= sun8i_v3s_ccu_ids,
+	},
+};
+module_platform_driver(sun8i_v3s_ccu_driver);
 
-CLK_OF_DECLARE(sun8i_v3_ccu, "allwinner,sun8i-v3-ccu",
-	       sun8i_v3_ccu_setup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/sunxi-ng/suniv-f1c100s-ccu.c b/drivers/clk/sunxi-ng/suniv-f1c100s-ccu.c
index 850ab8af2471..de602340f460 100644
--- a/drivers/clk/sunxi-ng/suniv-f1c100s-ccu.c
+++ b/drivers/clk/sunxi-ng/suniv-f1c100s-ccu.c
@@ -6,7 +6,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/io.h>
-#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include "ccu_common.h"
 #include "ccu_reset.h"
@@ -525,20 +526,21 @@ static struct ccu_mux_nb suniv_cpu_nb = {
 static void __init suniv_f1c100s_ccu_setup(struct device_node *node)
 {
 	void __iomem *reg;
+	int ret;
 	u32 val;
 
-	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-	if (IS_ERR(reg)) {
-		pr_err("%pOF: Could not map the clock registers\n", node);
-		return;
-	}
+	reg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(reg))
+		return PTR_ERR(reg);
 
 	/* Force the PLL-Audio-1x divider to 4 */
 	val = readl(reg + SUNIV_PLL_AUDIO_REG);
 	val &= ~GENMASK(19, 16);
 	writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG);
 
-	of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &suniv_ccu_desc);
+	if (ret)
+		return ret;
 
 	/* Gate then ungate PLL CPU after any rate changes */
 	ccu_pll_notifier_register(&suniv_pll_cpu_nb);
@@ -546,6 +548,23 @@ static void __init suniv_f1c100s_ccu_setup(struct device_node *node)
 	/* Reparent CPU during PLL CPU rate changes */
 	ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
 				  &suniv_cpu_nb);
+
+	return 0;
 }
-CLK_OF_DECLARE(suniv_f1c100s_ccu, "allwinner,suniv-f1c100s-ccu",
-	       suniv_f1c100s_ccu_setup);
+
+static const struct of_device_id suniv_f1c100s_ccu_ids[] = {
+	{ .compatible = "allwinner,suniv-f1c100s-ccu" },
+	{ }
+};
+
+static struct platform_driver suniv_f1c100s_ccu_driver = {
+	.probe	= suniv_f1c100s_ccu_probe,
+	.driver	= {
+		.name			= "suniv-f1c100s-ccu",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= suniv_f1c100s_ccu_ids,
+	},
+};
+module_platform_driver(suniv_f1c100s_ccu_driver);
+
+MODULE_LICENSE("GPL");
-- 
2.31.1



From sboyd at kernel.org  Tue Aug 31 22:27:30 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 31 Aug 2021 22:27:30 -0700
Subject: [PATCH] dt-bindings: clock: samsung: fix header path in example
In-Reply-To: <20210831130643.83249-1-krzysztof.kozlowski@canonical.com>
References: <20210831130643.83249-1-krzysztof.kozlowski@canonical.com>
Message-ID: <163047405062.42057.9583291773440326105@swboyd.mtv.corp.google.com>

Quoting Krzysztof Kozlowski (2021-08-31 06:06:43)
> The proper header is exynos4.h:
> 
>     samsung,exynos4412-isp-clock.example.dts:19:18: fatal error: dt-bindings/clock/exynos4412.h: No such file or directory
> 
> Fixes: 7ac615780926 ("dt-bindings: clock: samsung: convert Exynos4 to dtschema")
> Reported-by: Stephen Boyd <sboyd at kernel.org>
> Reported-by: Rob Herring <robh+dt at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> 
> ---

Applied to clk-next


From sboyd at kernel.org  Tue Aug 31 22:32:20 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 31 Aug 2021 22:32:20 -0700
Subject: [RESEND PATCH 3/4] clk: mediatek: support COMMON_CLK_MT6779
 module build
In-Reply-To: <1630348984.24981.2.camel@mtkswgap22>
References: <20210813032429.14715-1-miles.chen@mediatek.com>
 <20210813032429.14715-4-miles.chen@mediatek.com>
 <163021049667.2676726.10138202396240942833@swboyd.mtv.corp.google.com>
 <1630348984.24981.2.camel@mtkswgap22>
Message-ID: <163047434049.42057.5688419707288938766@swboyd.mtv.corp.google.com>

Quoting Miles Chen (2021-08-30 11:43:04)
> 
> sorry for my late response. 
> 
> Thanks for pointing this out. I have the same question when I was
> building this patch. That time I found some examples where
> they are using builtin_platform_driver and can be built as 
> kernel modules:
> 
> config CLK_IMX8QXP (tristate) && drivers/clk/imx/clk-imx8qxp-lpcg.c
> config CLK_RK3399 (tristate) && drivers/clk/rockchip/clk-rk3399.c

We should fix those drivers. Care to send a patch?


From samuel at sholland.org  Tue Aug 31 22:39:44 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:39:44 -0500
Subject: [RFC PATCH 0/7] clk: sunxi-ng: Add a RTC CCU driver
Message-ID: <20210901053951.60952-1-samuel@sholland.org>

This patch series adds a CCU driver for the RTC in the H616 and R329.
The extra patches at the end of this series show how it would be
explanded to additional hardware variants.

The driver is intended to support the existing binding used for the H6,
but also an updated binding which includes all RTC input clocks. I do
not know how to best represent that binding -- that is a major reason
why this series is an RFC.

A future patch series could add functionality to the driver to manage
IOSC calibration at boot and during suspend/resume.

It may be possible to support all of these hardware variants in the
existing RTC clock driver and avoid some duplicate code, but I'm
concerned about the complexity there, without any of the CCU
abstraction.

This series is currently based on top of the other series I just sent
(clk: sunxi-ng: Lifetime fixes and module support), but I can rebase it
elsewhere.

Samuel Holland (7):
  dt-bindings: rtc: sun6i: Add H616 and R329 compatibles
  clk: sunxi-ng: div: Add macro using CLK_HW_INIT_FW_NAME
  clk: sunxi-ng: mux: Add macro using CLK_HW_INIT_PARENTS_DATA
  clk: sunxi-ng: mux: Allow muxes to have keys
  clk: sunxi-ng: Add support for the sun50i RTC clocks
  [DO NOT MERGE] clk: sunxi-ng: Add support for H6
  [DO NOT MERGE] clk: sunxi-ng: Add support for T5

 .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml |  55 ++-
 drivers/clk/sunxi-ng/Kconfig                  |   6 +
 drivers/clk/sunxi-ng/Makefile                 |   1 +
 drivers/clk/sunxi-ng/ccu_common.h             |   1 +
 drivers/clk/sunxi-ng/ccu_div.h                |  14 +
 drivers/clk/sunxi-ng/ccu_mux.c                |   7 +
 drivers/clk/sunxi-ng/ccu_mux.h                |  28 ++
 drivers/clk/sunxi-ng/sun50i-rtc-ccu.c         | 433 ++++++++++++++++++
 drivers/clk/sunxi-ng/sun50i-rtc-ccu.h         |  15 +
 drivers/rtc/rtc-sun6i.c                       |  17 -
 include/dt-bindings/clock/sun50i-rtc.h        |  12 +
 11 files changed, 566 insertions(+), 23 deletions(-)
 create mode 100644 drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
 create mode 100644 drivers/clk/sunxi-ng/sun50i-rtc-ccu.h
 create mode 100644 include/dt-bindings/clock/sun50i-rtc.h

-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:39:47 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:39:47 -0500
Subject: [RFC PATCH 3/7] clk: sunxi-ng: mux: Add macro using
 CLK_HW_INIT_PARENTS_DATA
In-Reply-To: <20210901053951.60952-1-samuel@sholland.org>
References: <20210901053951.60952-1-samuel@sholland.org>
Message-ID: <20210901053951.60952-4-samuel@sholland.org>

Some muxes need the flexibility to specify a combination of internal
parents (using .hw) and external parents (using .fw_name). Support
this with a version of the SUNXI_CCU_MUX_WITH_GATE macro that uses
CLK_HW_INIT_PARENTS_DATA to provide the parent information.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/ccu_mux.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h
index f165395effb5..5aa5a6f49bd8 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.h
+++ b/drivers/clk/sunxi-ng/ccu_mux.h
@@ -73,6 +73,20 @@ struct ccu_mux {
 	SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL,	\
 				      _reg, _shift, _width, 0, _flags)
 
+#define SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg,	\
+				     _shift, _width, _gate, _flags)	\
+	struct ccu_mux _struct = {					\
+		.enable	= _gate,					\
+		.mux	= _SUNXI_CCU_MUX(_shift, _width),		\
+		.common	= {						\
+			.reg		= _reg,				\
+			.hw.init	= CLK_HW_INIT_PARENTS_DATA(_name, \
+								   _parents, \
+								   &ccu_mux_ops, \
+								   _flags), \
+		}							\
+	}
+
 static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
 {
 	struct ccu_common *common = hw_to_ccu_common(hw);
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:39:45 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:39:45 -0500
Subject: [RFC PATCH 1/7] dt-bindings: rtc: sun6i: Add H616 and R329 compatibles
In-Reply-To: <20210901053951.60952-1-samuel@sholland.org>
References: <20210901053951.60952-1-samuel@sholland.org>
Message-ID: <20210901053951.60952-2-samuel@sholland.org>

For these new SoCs, start requiring a complete list of input clocks.

For H616, this means bus, hosc, and pll-32k. For R329, this means ahb,
bus, and hosc; and optionally ext-osc32k.

I'm not sure how to best represent this in the binding...

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 .../bindings/rtc/allwinner,sun6i-a31-rtc.yaml | 55 +++++++++++++++++--
 include/dt-bindings/clock/sun50i-rtc.h        | 12 ++++
 2 files changed, 61 insertions(+), 6 deletions(-)
 create mode 100644 include/dt-bindings/clock/sun50i-rtc.h

diff --git a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
index beeb90e55727..3e085db1294f 100644
--- a/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
@@ -26,6 +26,8 @@ properties:
           - const: allwinner,sun50i-a64-rtc
           - const: allwinner,sun8i-h3-rtc
       - const: allwinner,sun50i-h6-rtc
+      - const: allwinner,sun50i-h616-rtc
+      - const: allwinner,sun50i-r329-rtc
 
   reg:
     maxItems: 1
@@ -37,7 +39,24 @@ properties:
       - description: RTC Alarm 1
 
   clocks:
-    maxItems: 1
+    minItems: 1
+    maxItems: 4
+
+  clock-names:
+    minItems: 1
+    maxItems: 4
+    items:
+      - anyOf:
+          - const: ahb
+            description: AHB parent for SPI bus clock
+          - const: bus
+            description: AHB/APB bus clock for register access
+          - const: ext-osc32k
+            description: External 32768 Hz oscillator input
+          - const: hosc
+            description: 24 MHz oscillator input
+          - const: pll-32k
+            description: 32 kHz clock divided from a PLL
 
   clock-output-names:
     minItems: 1
@@ -85,6 +104,9 @@ allOf:
             enum:
               - allwinner,sun8i-h3-rtc
               - allwinner,sun50i-h5-rtc
+              - allwinner,sun50i-h6-rtc
+              - allwinner,sun50i-h616-rtc
+              - allwinner,sun50i-r329-rtc
 
     then:
       properties:
@@ -96,13 +118,35 @@ allOf:
       properties:
         compatible:
           contains:
-            const: allwinner,sun50i-h6-rtc
+            enum:
+              - allwinner,sun50i-h616-rtc
+              - allwinner,sun50i-r329-rtc
 
     then:
+      clocks:
+        minItems: 3 # bus, hosc, and (pll-32k [H616] or ahb [R329])
+
+      clock-names:
+        minItems: 3
+
+      required:
+        - clock-names
+
+    else:
+      required:
+        - clock-output-names
+
+  - if:
+      properties: clock-names
+
+    then:
+      required:
+        - clocks # hosc is required
+
+    else:
       properties:
-        clock-output-names:
-          minItems: 3
-          maxItems: 3
+        clocks:
+          maxItems: 1 # only ext-osc32k is allowed
 
   - if:
       properties:
@@ -127,7 +171,6 @@ required:
   - compatible
   - reg
   - interrupts
-  - clock-output-names
 
 additionalProperties: false
 
diff --git a/include/dt-bindings/clock/sun50i-rtc.h b/include/dt-bindings/clock/sun50i-rtc.h
new file mode 100644
index 000000000000..d45e3ff4e105
--- /dev/null
+++ b/include/dt-bindings/clock/sun50i-rtc.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _DT_BINDINGS_CLK_SUN50I_RTC_CCU_H_
+#define _DT_BINDINGS_CLK_SUN50I_RTC_CCU_H_
+
+#define CLK_OSC32K		0
+#define CLK_OSC32K_FANOUT	1
+#define CLK_IOSC		2
+
+#define CLK_RTC_SPI		8
+
+#endif /* _DT_BINDINGS_CLK_SUN50I_RTC_CCU_H_ */
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:39:46 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:39:46 -0500
Subject: [RFC PATCH 2/7] clk: sunxi-ng: div: Add macro using
 CLK_HW_INIT_FW_NAME
In-Reply-To: <20210901053951.60952-1-samuel@sholland.org>
References: <20210901053951.60952-1-samuel@sholland.org>
Message-ID: <20210901053951.60952-3-samuel@sholland.org>

To use the external clock references from the device tree, instead of
hardcoded global names, parents should be referenced with .fw_name. Add
a variant of the SUNXI_CCU_M_WITH_GATE initializer which does this.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/ccu_div.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
index 6682fde6043c..4f8c78a4665b 100644
--- a/drivers/clk/sunxi-ng/ccu_div.h
+++ b/drivers/clk/sunxi-ng/ccu_div.h
@@ -166,6 +166,20 @@ struct ccu_div {
 	SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg,		\
 			      _mshift, _mwidth, 0, _flags)
 
+#define SUNXI_CCU_M_FW_WITH_GATE(_struct, _name, _parent, _reg,		\
+				 _mshift, _mwidth, _gate, _flags)	\
+	struct ccu_div _struct = {					\
+		.enable	= _gate,					\
+		.div	= _SUNXI_CCU_DIV(_mshift, _mwidth),		\
+		.common	= {						\
+			.reg		= _reg,				\
+			.hw.init	= CLK_HW_INIT_FW_NAME(_name,	\
+							      _parent,	\
+							      &ccu_div_ops, \
+							      _flags),	\
+		},							\
+	}
+
 static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
 {
 	struct ccu_common *common = hw_to_ccu_common(hw);
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:39:48 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:39:48 -0500
Subject: [RFC PATCH 4/7] clk: sunxi-ng: mux: Allow muxes to have keys
In-Reply-To: <20210901053951.60952-1-samuel@sholland.org>
References: <20210901053951.60952-1-samuel@sholland.org>
Message-ID: <20210901053951.60952-5-samuel@sholland.org>

The muxes in the RTC can only be updated when setting a key field to a
specific value. Add a feature flag to denote muxes with this property.
Since so far the key value is always the same, it does not need to be
provided separately for each mux.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/ccu_common.h |  1 +
 drivers/clk/sunxi-ng/ccu_mux.c    |  7 +++++++
 drivers/clk/sunxi-ng/ccu_mux.h    | 14 ++++++++++++++
 3 files changed, 22 insertions(+)

diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h
index 98a1834b58bb..fbf16c6b896d 100644
--- a/drivers/clk/sunxi-ng/ccu_common.h
+++ b/drivers/clk/sunxi-ng/ccu_common.h
@@ -17,6 +17,7 @@
 #define CCU_FEATURE_LOCK_REG		BIT(5)
 #define CCU_FEATURE_MMC_TIMING_SWITCH	BIT(6)
 #define CCU_FEATURE_SIGMA_DELTA_MOD	BIT(7)
+#define CCU_FEATURE_KEY_FIELD		BIT(8)
 
 /* MMC timing mode switch bit */
 #define CCU_MMC_NEW_TIMING_MODE		BIT(30)
diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c
index 785803cd7e51..fb93cea3a502 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.c
+++ b/drivers/clk/sunxi-ng/ccu_mux.c
@@ -12,6 +12,8 @@
 #include "ccu_gate.h"
 #include "ccu_mux.h"
 
+#define CCU_MUX_KEY_VALUE		0x16aa0000
+
 static u16 ccu_mux_get_prediv(struct ccu_common *common,
 			      struct ccu_mux_internal *cm,
 			      int parent_index)
@@ -188,6 +190,11 @@ int ccu_mux_helper_set_parent(struct ccu_common *common,
 	spin_lock_irqsave(common->lock, flags);
 
 	reg = readl(common->base + common->reg);
+
+	/* The key field always reads as zero. */
+	if (common->features & CCU_FEATURE_KEY_FIELD)
+		reg |= CCU_MUX_KEY_VALUE;
+
 	reg &= ~GENMASK(cm->width + cm->shift - 1, cm->shift);
 	writel(reg | (index << cm->shift), common->base + common->reg);
 
diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h
index 5aa5a6f49bd8..6ca15e43f9c8 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.h
+++ b/drivers/clk/sunxi-ng/ccu_mux.h
@@ -87,6 +87,20 @@ struct ccu_mux {
 		}							\
 	}
 
+#define SUNXI_CCU_MUX_HW_WITH_KEY(_struct, _name, _parents, _reg,	\
+				  _shift, _width, _flags)		\
+	struct ccu_mux _struct = {					\
+		.mux	= _SUNXI_CCU_MUX(_shift, _width),		\
+		.common	= {						\
+			.reg		= _reg,				\
+			.features	= CCU_FEATURE_KEY_FIELD,	\
+			.hw.init	= CLK_HW_INIT_PARENTS_HW(_name,	\
+								 _parents, \
+								 &ccu_mux_ops, \
+								 _flags), \
+		}							\
+	}
+
 static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
 {
 	struct ccu_common *common = hw_to_ccu_common(hw);
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:39:50 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:39:50 -0500
Subject: [RFC PATCH 6/7] [DO NOT MERGE] clk: sunxi-ng: Add support for H6
In-Reply-To: <20210901053951.60952-1-samuel@sholland.org>
References: <20210901053951.60952-1-samuel@sholland.org>
Message-ID: <20210901053951.60952-7-samuel@sholland.org>

H6 has IOSC calibration and an ext-osc32k input.

H6 has the osc32k mux and the rtc-32k mux, but no fanout mux.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/sun50i-rtc-ccu.c | 49 +++++++++++++++++++++++++++
 drivers/rtc/rtc-sun6i.c               | 17 ----------
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c b/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
index 1dfa05c2f0e9..9603dc0d3d7b 100644
--- a/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
+++ b/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
@@ -227,6 +227,16 @@ static SUNXI_CCU_MUX_DATA_WITH_GATE(osc32k_fanout_clk, "rtc-32k-fanout",
 static SUNXI_CCU_M_FW_WITH_GATE(rtc_spi_clk, "rtc-spi", "ahb",
 				0x310, 0, 5, BIT(31), 0);
 
+static struct ccu_common *sun50i_h6_rtc_ccu_clks[] = {
+	&iosc_clk,
+	&iosc_32k_clk,
+	&ext_osc32k_gate_clk.common,
+	&osc32k_clk.common,
+	&osc24M_32k_clk.common,
+	&rtc_32k_mux_clk.common,
+	&osc32k_fanout_clk.common,
+};
+
 static struct ccu_common *sun50i_h616_rtc_ccu_clks[] = {
 	&iosc_clk,
 	&iosc_32k_clk,
@@ -246,6 +256,21 @@ static struct ccu_common *sun50i_r329_rtc_ccu_clks[] = {
 	&rtc_spi_clk.common,
 };
 
+static struct clk_hw_onecell_data sun50i_h6_rtc_ccu_hw_clks = {
+	.num = CLK_NUMBER,
+	.hws = {
+		[CLK_OSC32K]		= &osc32k_clk.common.hw,
+		[CLK_OSC32K_FANOUT]	= &osc32k_fanout_clk.common.hw,
+		[CLK_IOSC]		= &iosc_clk.hw,
+
+		[CLK_IOSC_32K]		= &iosc_32k_clk.hw,
+		[CLK_EXT_OSC32K_GATE]	= &ext_osc32k_gate_clk.common.hw,
+		[CLK_OSC24M_32K]	= &osc24M_32k_clk.common.hw,
+		[CLK_RTC_32K]		= &rtc_32k_mux_clk.common.hw,
+		[CLK_RTC_SPI]		= NULL,
+	},
+};
+
 static struct clk_hw_onecell_data sun50i_h616_rtc_ccu_hw_clks = {
 	.num = CLK_NUMBER,
 	.hws = {
@@ -276,6 +301,13 @@ static struct clk_hw_onecell_data sun50i_r329_rtc_ccu_hw_clks = {
 	},
 };
 
+static const struct sunxi_ccu_desc sun50i_h6_rtc_ccu_desc = {
+	.ccu_clks	= sun50i_h6_rtc_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_h6_rtc_ccu_clks),
+
+	.hw_clks	= &sun50i_h6_rtc_ccu_hw_clks,
+};
+
 static const struct sunxi_ccu_desc sun50i_h616_rtc_ccu_desc = {
 	.ccu_clks	= sun50i_h616_rtc_ccu_clks,
 	.num_ccu_clks	= ARRAY_SIZE(sun50i_h616_rtc_ccu_clks),
@@ -318,6 +350,23 @@ static void __init sunxi_rtc_ccu_init(struct device_node *node,
 	of_sunxi_ccu_probe(node, reg, desc);
 }
 
+static void __init sun50i_h6_rtc_ccu_setup(struct device_node *node)
+{
+	struct clk_init_data *init;
+
+	have_iosc_calib = 1;
+
+	/* Casting away the const from a pointer to a non-const anonymous object... */
+	init = (struct clk_init_data *)osc32k_fanout_clk.common.hw.init;
+
+	/* Fanout only has one parent: osc32k. */
+	init->num_parents = 1;
+
+	sunxi_rtc_ccu_init(node, &sun50i_h6_rtc_ccu_desc);
+}
+CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_ccu, "allwinner,sun50i-h6-rtc",
+		      sun50i_h6_rtc_ccu_setup);
+
 static void __init sun50i_h616_rtc_ccu_setup(struct device_node *node)
 {
 	have_iosc_calib = 1;
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index adec1b14a8de..f7cbbf57f112 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -363,23 +363,6 @@ CLK_OF_DECLARE_DRIVER(sun8i_h3_rtc_clk, "allwinner,sun8i-h3-rtc",
 CLK_OF_DECLARE_DRIVER(sun50i_h5_rtc_clk, "allwinner,sun50i-h5-rtc",
 		      sun8i_h3_rtc_clk_init);
 
-static const struct sun6i_rtc_clk_data sun50i_h6_rtc_data = {
-	.rc_osc_rate = 16000000,
-	.fixed_prescaler = 32,
-	.has_prescaler = 1,
-	.has_out_clk = 1,
-	.export_iosc = 1,
-	.has_losc_en = 1,
-	.has_auto_swt = 1,
-};
-
-static void __init sun50i_h6_rtc_clk_init(struct device_node *node)
-{
-	sun6i_rtc_clk_init(node, &sun50i_h6_rtc_data);
-}
-CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc",
-		      sun50i_h6_rtc_clk_init);
-
 /*
  * The R40 user manual is self-conflicting on whether the prescaler is
  * fixed or configurable. The clock diagram shows it as fixed, but there
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:39:51 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:39:51 -0500
Subject: [RFC PATCH 7/7] [DO NOT MERGE] clk: sunxi-ng: Add support for T5
In-Reply-To: <20210901053951.60952-1-samuel@sholland.org>
References: <20210901053951.60952-1-samuel@sholland.org>
Message-ID: <20210901053951.60952-8-samuel@sholland.org>

The T5 RTC is similar to the H616 RTC (no rtc-32k mux, pll-32k as the
second fanout input), except that it adds the ext-osc32k input.

It also isn't a "sun50i" SoC, so it creates a bit of a naming problem...

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/sun50i-rtc-ccu.c | 40 +++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c b/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
index 9603dc0d3d7b..fe6b21a24193 100644
--- a/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
+++ b/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
@@ -227,6 +227,15 @@ static SUNXI_CCU_MUX_DATA_WITH_GATE(osc32k_fanout_clk, "rtc-32k-fanout",
 static SUNXI_CCU_M_FW_WITH_GATE(rtc_spi_clk, "rtc-spi", "ahb",
 				0x310, 0, 5, BIT(31), 0);
 
+static struct ccu_common *sun8i_t5_rtc_ccu_clks[] = {
+	&iosc_clk,
+	&iosc_32k_clk,
+	&ext_osc32k_gate_clk.common,
+	&osc32k_clk.common,
+	&osc24M_32k_clk.common,
+	&osc32k_fanout_clk.common,
+};
+
 static struct ccu_common *sun50i_h6_rtc_ccu_clks[] = {
 	&iosc_clk,
 	&iosc_32k_clk,
@@ -256,6 +265,21 @@ static struct ccu_common *sun50i_r329_rtc_ccu_clks[] = {
 	&rtc_spi_clk.common,
 };
 
+static struct clk_hw_onecell_data sun8i_t5_rtc_ccu_hw_clks = {
+	.num = CLK_NUMBER,
+	.hws = {
+		[CLK_OSC32K]		= &osc32k_clk.common.hw,
+		[CLK_OSC32K_FANOUT]	= &osc32k_fanout_clk.common.hw,
+		[CLK_IOSC]		= &iosc_clk.hw,
+
+		[CLK_IOSC_32K]		= &iosc_32k_clk.hw,
+		[CLK_EXT_OSC32K_GATE]	= &ext_osc32k_gate_clk.common.hw,
+		[CLK_OSC24M_32K]	= &osc24M_32k_clk.common.hw,
+		[CLK_RTC_32K]		= &rtc_32k_fixed_clk.hw,
+		[CLK_RTC_SPI]		= NULL,
+	},
+};
+
 static struct clk_hw_onecell_data sun50i_h6_rtc_ccu_hw_clks = {
 	.num = CLK_NUMBER,
 	.hws = {
@@ -301,6 +325,13 @@ static struct clk_hw_onecell_data sun50i_r329_rtc_ccu_hw_clks = {
 	},
 };
 
+static const struct sunxi_ccu_desc sun8i_t5_rtc_ccu_desc = {
+	.ccu_clks	= sun8i_t5_rtc_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun8i_t5_rtc_ccu_clks),
+
+	.hw_clks	= &sun8i_t5_rtc_ccu_hw_clks,
+};
+
 static const struct sunxi_ccu_desc sun50i_h6_rtc_ccu_desc = {
 	.ccu_clks	= sun50i_h6_rtc_ccu_clks,
 	.num_ccu_clks	= ARRAY_SIZE(sun50i_h6_rtc_ccu_clks),
@@ -350,6 +381,15 @@ static void __init sunxi_rtc_ccu_init(struct device_node *node,
 	of_sunxi_ccu_probe(node, reg, desc);
 }
 
+static void __init sun8i_t5_rtc_ccu_setup(struct device_node *node)
+{
+	have_iosc_calib = 1;
+
+	sunxi_rtc_ccu_init(node, &sun8i_t5_rtc_ccu_desc);
+}
+CLK_OF_DECLARE_DRIVER(sun8i_t5_rtc_ccu, "allwinner,sun8i-t5-rtc",
+		      sun8i_t5_rtc_ccu_setup);
+
 static void __init sun50i_h6_rtc_ccu_setup(struct device_node *node)
 {
 	struct clk_init_data *init;
-- 
2.31.1



From samuel at sholland.org  Tue Aug 31 22:39:49 2021
From: samuel at sholland.org (Samuel Holland)
Date: Wed,  1 Sep 2021 00:39:49 -0500
Subject: [RFC PATCH 5/7] clk: sunxi-ng: Add support for the sun50i RTC clocks
In-Reply-To: <20210901053951.60952-1-samuel@sholland.org>
References: <20210901053951.60952-1-samuel@sholland.org>
Message-ID: <20210901053951.60952-6-samuel@sholland.org>

The RTC power domain in sun50i SoCs manages the 16 MHz RC oscillator
(called "IOSC" or "osc16M") and the optional 32 kHz crystal oscillator
(called "LOSC" or "osc32k"). Starting with the H6, this power domain
handles the 24 MHz DCXO (called "HOSC", "dcxo24M", or "osc24M") as well.
The H6 also introduces a calibration circuit for IOSC.

Later SoCs introduce further variations on the design:
 - H616 adds an additional mux for the 32 kHz fanout source.
 - R329 adds an additional mux for the RTC timekeeping clock, a clock
   for the SPI bus between power domains inside the RTC, and removes the
   IOSC calibration functionality.

Take advantage of the CCU framework to handle this increased complexity.
The CCU framework provides pre-made widgets for the mux/gate/divider
combinations. And it allows plugging in different clocks for the same
specifiers based on the compatible string.

This driver is intended to be a drop-in replacement for the existing RTC
clock driver. So some runtime adjustment of the clock parents is needed,
both to handle hardware differences, and to support the old binding
which omitted some of the input clocks.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---
 drivers/clk/sunxi-ng/Kconfig          |   6 +
 drivers/clk/sunxi-ng/Makefile         |   1 +
 drivers/clk/sunxi-ng/sun50i-rtc-ccu.c | 344 ++++++++++++++++++++++++++
 drivers/clk/sunxi-ng/sun50i-rtc-ccu.h |  15 ++
 4 files changed, 366 insertions(+)
 create mode 100644 drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
 create mode 100644 drivers/clk/sunxi-ng/sun50i-rtc-ccu.h

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index ee383658ff4d..8d9d486c4673 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -42,6 +42,12 @@ config SUN50I_H6_R_CCU
 	default ARM64 && ARCH_SUNXI
 	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
+config SUN50I_RTC_CCU
+	bool "Support for the Allwinner H6/H616/R329 RTC CCU"
+	default ARM64 && ARCH_SUNXI
+	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+	depends on SUNXI_CCU=y
+
 config SUN4I_A10_CCU
 	tristate "Support for the Allwinner A10/A20 CCU"
 	default MACH_SUN4I
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 6e9eb004fca0..99554b13d150 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_SUN50I_A100_R_CCU)	+= sun50i-a100-r-ccu.o
 obj-$(CONFIG_SUN50I_H6_CCU)	+= sun50i-h6-ccu.o
 obj-$(CONFIG_SUN50I_H616_CCU)	+= sun50i-h616-ccu.o
 obj-$(CONFIG_SUN50I_H6_R_CCU)	+= sun50i-h6-r-ccu.o
+obj-$(CONFIG_SUN50I_RTC_CCU)	+= sun50i-rtc-ccu.o
 obj-$(CONFIG_SUN4I_A10_CCU)	+= sun4i-a10-ccu.o
 obj-$(CONFIG_SUN5I_CCU)		+= sun5i-ccu.o
 obj-$(CONFIG_SUN6I_A31_CCU)	+= sun6i-a31-ccu.o
diff --git a/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c b/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
new file mode 100644
index 000000000000..1dfa05c2f0e9
--- /dev/null
+++ b/drivers/clk/sunxi-ng/sun50i-rtc-ccu.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+
+#include "ccu_common.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mux.h"
+
+#include "sun50i-rtc-ccu.h"
+
+#define IOSC_ACCURACY			300000000 /* 30% */
+#define IOSC_RATE			16000000
+
+#define LOSC_RATE			32768
+#define LOSC_RATE_SHIFT			15
+
+#define LOSC_CTRL_KEY			0x16aa0000
+
+#define IOSC_32K_CLK_DIV_REG		0x8
+#define IOSC_32K_CLK_DIV		GENMASK(4, 0)
+#define IOSC_32K_PRE_DIV		32
+
+#define IOSC_CLK_CALI_REG		0xc
+#define IOSC_CLK_CALI_DIV_ONES		22
+#define IOSC_CLK_CALI_EN		BIT(1)
+#define IOSC_CLK_CALI_SRC_SEL		BIT(0)
+
+#define DCXO_CTRL_REG			0x160
+#define DCXO_CTRL_CLK16M_RC_EN		BIT(0)
+
+static bool have_iosc_calib;
+
+static int ccu_iosc_enable(struct clk_hw *hw)
+{
+	struct ccu_common *cm = hw_to_ccu_common(hw);
+
+	return ccu_gate_helper_enable(cm, DCXO_CTRL_CLK16M_RC_EN);
+}
+
+static void ccu_iosc_disable(struct clk_hw *hw)
+{
+	struct ccu_common *cm = hw_to_ccu_common(hw);
+
+	return ccu_gate_helper_disable(cm, DCXO_CTRL_CLK16M_RC_EN);
+}
+
+static int ccu_iosc_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_common *cm = hw_to_ccu_common(hw);
+
+	return ccu_gate_helper_is_enabled(cm, DCXO_CTRL_CLK16M_RC_EN);
+}
+
+static unsigned long ccu_iosc_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct ccu_common *cm = hw_to_ccu_common(hw);
+
+	if (have_iosc_calib) {
+		u32 reg = readl(cm->base + IOSC_CLK_CALI_REG);
+
+		/*
+		 * Recover the IOSC frequency by shifting the ones place of
+		 * (fixed-point divider * 32768) into bit zero.
+		 */
+		if (reg & IOSC_CLK_CALI_EN)
+			return reg >> (IOSC_CLK_CALI_DIV_ONES - LOSC_RATE_SHIFT);
+	}
+
+	return IOSC_RATE;
+}
+
+static unsigned long ccu_iosc_recalc_accuracy(struct clk_hw *hw,
+					      unsigned long parent_accuracy)
+{
+	return IOSC_ACCURACY;
+}
+
+static const struct clk_ops ccu_iosc_ops = {
+	.enable			= ccu_iosc_enable,
+	.disable		= ccu_iosc_disable,
+	.is_enabled		= ccu_iosc_is_enabled,
+	.recalc_rate		= ccu_iosc_recalc_rate,
+	.recalc_accuracy	= ccu_iosc_recalc_accuracy,
+};
+
+static struct ccu_common iosc_clk = {
+	.reg		= DCXO_CTRL_REG,
+	.hw.init	= CLK_HW_INIT_NO_PARENT("iosc", &ccu_iosc_ops,
+						CLK_GET_RATE_NOCACHE),
+};
+
+static int ccu_iosc_32k_enable(struct clk_hw *hw)
+{
+	struct ccu_common *cm = hw_to_ccu_common(hw);
+	unsigned long flags;
+	u32 reg;
+
+	if (!have_iosc_calib)
+		return 0;
+
+	spin_lock_irqsave(cm->lock, flags);
+
+	reg = readl(cm->base + IOSC_CLK_CALI_REG);
+	writel(reg | IOSC_CLK_CALI_EN | IOSC_CLK_CALI_SRC_SEL,
+	       cm->base + IOSC_CLK_CALI_REG);
+
+	spin_unlock_irqrestore(cm->lock, flags);
+
+	return 0;
+}
+
+static void ccu_iosc_32k_disable(struct clk_hw *hw)
+{
+	struct ccu_common *cm = hw_to_ccu_common(hw);
+	unsigned long flags;
+	u32 reg;
+
+	if (!have_iosc_calib)
+		return;
+
+	spin_lock_irqsave(cm->lock, flags);
+
+	reg = readl(cm->base + IOSC_CLK_CALI_REG);
+	writel(reg & ~(IOSC_CLK_CALI_EN | IOSC_CLK_CALI_SRC_SEL),
+	       cm->base + IOSC_CLK_CALI_REG);
+
+	spin_unlock_irqrestore(cm->lock, flags);
+}
+
+static unsigned long ccu_iosc_32k_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	struct ccu_common *cm = hw_to_ccu_common(hw);
+	u32 reg;
+
+	if (have_iosc_calib) {
+		reg = readl(cm->base + IOSC_CLK_CALI_REG);
+
+		/* Assume the calibrated 32k clock is accurate. */
+		if (reg & IOSC_CLK_CALI_SRC_SEL)
+			return LOSC_RATE;
+	}
+
+	reg = readl(cm->base + IOSC_32K_CLK_DIV_REG) & IOSC_32K_CLK_DIV;
+
+	return parent_rate / IOSC_32K_PRE_DIV / (reg + 1);
+}
+
+static unsigned long ccu_iosc_32k_recalc_accuracy(struct clk_hw *hw,
+						  unsigned long parent_accuracy)
+{
+	struct ccu_common *cm = hw_to_ccu_common(hw);
+	u32 reg;
+
+	if (have_iosc_calib) {
+		reg = readl(cm->base + IOSC_CLK_CALI_REG);
+
+		/* Assume the calibrated 32k clock is accurate. */
+		if (reg & IOSC_CLK_CALI_SRC_SEL)
+			return 0;
+	}
+
+	return parent_accuracy;
+}
+
+static const struct clk_ops ccu_iosc_32k_ops = {
+	.enable			= ccu_iosc_32k_enable,
+	.disable		= ccu_iosc_32k_disable,
+	.recalc_rate		= ccu_iosc_32k_recalc_rate,
+	.recalc_accuracy	= ccu_iosc_32k_recalc_accuracy,
+};
+
+static struct ccu_common iosc_32k_clk = {
+	.hw.init	= CLK_HW_INIT_HW("iosc-32k", &iosc_clk.hw,
+					 &ccu_iosc_32k_ops, 0),
+};
+
+/* The old binding did not use clock-names, so fw_name may get cleared out. */
+static struct clk_parent_data ext_osc32k[] = {
+	{ .fw_name = "ext-osc32k", .index = 0 }
+};
+static SUNXI_CCU_GATE_DATA(ext_osc32k_gate_clk, "ext-osc32k-gate",
+			   ext_osc32k, 0x0, BIT(4), 0);
+
+static const struct clk_hw *osc32k_parents[] = { &iosc_32k_clk.hw,
+						 &ext_osc32k_gate_clk.common.hw };
+static SUNXI_CCU_MUX_HW_WITH_KEY(osc32k_clk, "osc32k", osc32k_parents,
+				 0x0, 0, 1, 0);
+
+/* Fall back to the global name for RTC nodes without an osc24M reference. */
+static struct clk_parent_data osc24M[] = {
+	{ .fw_name = "hosc", .name = "osc24M" }
+};
+static struct ccu_gate osc24M_32k_clk = {
+	.enable	= BIT(16),
+	.common	= {
+		.reg		= 0x60,
+		.prediv		= 750,
+		.features	= CCU_FEATURE_ALL_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS_DATA("osc24M-32k", osc24M,
+							   &ccu_gate_ops, 0),
+	},
+};
+
+static CLK_FIXED_FACTOR_HW(rtc_32k_fixed_clk, "rtc-32k",
+			   &osc32k_clk.common.hw, 1, 1, 0);
+
+static const struct clk_hw *rtc_32k_parents[] = { &osc32k_clk.common.hw,
+						  &osc24M_32k_clk.common.hw };
+static SUNXI_CCU_MUX_HW_WITH_KEY(rtc_32k_mux_clk, "rtc-32k", rtc_32k_parents,
+				 0x0, 1, 1, 0);
+
+static struct clk_parent_data osc32k_fanout_parents[] = {
+	{ .hw = &osc32k_clk.common.hw },
+	/* Parent is modified depending on the hardware variant. */
+	{ .fw_name = "pll-32k" },
+	{ .hw = &osc24M_32k_clk.common.hw },
+};
+static SUNXI_CCU_MUX_DATA_WITH_GATE(osc32k_fanout_clk, "rtc-32k-fanout",
+				    osc32k_fanout_parents,
+				    0x60, 1, 2, BIT(0), 0);
+
+static SUNXI_CCU_M_FW_WITH_GATE(rtc_spi_clk, "rtc-spi", "ahb",
+				0x310, 0, 5, BIT(31), 0);
+
+static struct ccu_common *sun50i_h616_rtc_ccu_clks[] = {
+	&iosc_clk,
+	&iosc_32k_clk,
+	&osc32k_clk.common,
+	&osc24M_32k_clk.common,
+	&osc32k_fanout_clk.common,
+};
+
+static struct ccu_common *sun50i_r329_rtc_ccu_clks[] = {
+	&iosc_clk,
+	&iosc_32k_clk,
+	&ext_osc32k_gate_clk.common,
+	&osc32k_clk.common,
+	&osc24M_32k_clk.common,
+	&rtc_32k_mux_clk.common,
+	&osc32k_fanout_clk.common,
+	&rtc_spi_clk.common,
+};
+
+static struct clk_hw_onecell_data sun50i_h616_rtc_ccu_hw_clks = {
+	.num = CLK_NUMBER,
+	.hws = {
+		[CLK_OSC32K]		= &osc32k_clk.common.hw,
+		[CLK_OSC32K_FANOUT]	= &osc32k_fanout_clk.common.hw,
+		[CLK_IOSC]		= &iosc_clk.hw,
+
+		[CLK_IOSC_32K]		= &iosc_32k_clk.hw,
+		[CLK_EXT_OSC32K_GATE]	= NULL,
+		[CLK_OSC24M_32K]	= &osc24M_32k_clk.common.hw,
+		[CLK_RTC_32K]		= &rtc_32k_fixed_clk.hw,
+		[CLK_RTC_SPI]		= NULL,
+	},
+};
+
+static struct clk_hw_onecell_data sun50i_r329_rtc_ccu_hw_clks = {
+	.num = CLK_NUMBER,
+	.hws = {
+		[CLK_OSC32K]		= &osc32k_clk.common.hw,
+		[CLK_OSC32K_FANOUT]	= &osc32k_fanout_clk.common.hw,
+		[CLK_IOSC]		= &iosc_clk.hw,
+
+		[CLK_IOSC_32K]		= &iosc_32k_clk.hw,
+		[CLK_EXT_OSC32K_GATE]	= &ext_osc32k_gate_clk.common.hw,
+		[CLK_OSC24M_32K]	= &osc24M_32k_clk.common.hw,
+		[CLK_RTC_32K]		= &rtc_32k_mux_clk.common.hw,
+		[CLK_RTC_SPI]		= &rtc_spi_clk.common.hw,
+	},
+};
+
+static const struct sunxi_ccu_desc sun50i_h616_rtc_ccu_desc = {
+	.ccu_clks	= sun50i_h616_rtc_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_h616_rtc_ccu_clks),
+
+	.hw_clks	= &sun50i_h616_rtc_ccu_hw_clks,
+};
+
+static const struct sunxi_ccu_desc sun50i_r329_rtc_ccu_desc = {
+	.ccu_clks	= sun50i_r329_rtc_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun50i_r329_rtc_ccu_clks),
+
+	.hw_clks	= &sun50i_r329_rtc_ccu_hw_clks,
+};
+
+static void __init sunxi_rtc_ccu_init(struct device_node *node,
+				      const struct sunxi_ccu_desc *desc)
+{
+	void __iomem *reg;
+	int i;
+
+	reg = of_iomap(node, 0);
+	if (IS_ERR(reg)) {
+		pr_err("%pOF: Failed to map registers\n", node);
+		return;
+	}
+
+	/* ext-osc32k was the only input clock in the old binding. */
+	if (!of_property_read_bool(node, "clock-names"))
+		ext_osc32k[0].fw_name = NULL;
+
+	/* Rename the first 3 clocks to respect clock-output-names. */
+	for (i = 0; i < 3; ++i) {
+		struct clk_init_data *init = (struct clk_init_data *)
+			desc->hw_clks->hws[i]->init;
+
+		of_property_read_string_index(node, "clock-output-names", i,
+					      &init->name);
+	}
+
+	of_sunxi_ccu_probe(node, reg, desc);
+}
+
+static void __init sun50i_h616_rtc_ccu_setup(struct device_node *node)
+{
+	have_iosc_calib = 1;
+
+	/* Remove the second parent as external osc32k is not supported. */
+	osc32k_parents[1] = &iosc_32k_clk.hw;
+
+	sunxi_rtc_ccu_init(node, &sun50i_h616_rtc_ccu_desc);
+}
+CLK_OF_DECLARE_DRIVER(sun50i_h616_rtc_ccu, "allwinner,sun50i-h616-rtc",
+		      sun50i_h616_rtc_ccu_setup);
+
+static void __init sun50i_r329_rtc_ccu_setup(struct device_node *node)
+{
+	have_iosc_calib = 0;
+
+	osc32k_fanout_parents[1] = (struct clk_parent_data) {
+		.hw = &ext_osc32k_gate_clk.common.hw
+	};
+
+	sunxi_rtc_ccu_init(node, &sun50i_r329_rtc_ccu_desc);
+}
+CLK_OF_DECLARE_DRIVER(sun50i_r329_rtc_ccu, "allwinner,sun50i-r329-rtc",
+		      sun50i_r329_rtc_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/sun50i-rtc-ccu.h b/drivers/clk/sunxi-ng/sun50i-rtc-ccu.h
new file mode 100644
index 000000000000..7bd4d8700612
--- /dev/null
+++ b/drivers/clk/sunxi-ng/sun50i-rtc-ccu.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _CCU_SUN50I_RTC_H
+#define _CCU_SUN50I_RTC_H
+
+#include <dt-bindings/clock/sun50i-rtc.h>
+
+#define CLK_IOSC_32K		4
+#define CLK_EXT_OSC32K_GATE	5
+#define CLK_OSC24M_32K		6
+#define CLK_RTC_32K		7
+
+#define CLK_NUMBER		(CLK_RTC_SPI + 1)
+
+#endif /* _CCU_SUN50I_RTC_H */
-- 
2.31.1



From sboyd at kernel.org  Tue Aug 31 22:40:21 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 31 Aug 2021 22:40:21 -0700
Subject: [PATCH v2 4/4] clk: mediatek: use tristate for
 COMMON_CLK_MEDAITEK and COMMON_CLK_MT6779
In-Reply-To: <20210831164210.15455-5-miles.chen@mediatek.com>
References: <20210831164210.15455-1-miles.chen@mediatek.com>
 <20210831164210.15455-5-miles.chen@mediatek.com>
Message-ID: <163047482135.42057.4815394359554916322@swboyd.mtv.corp.google.com>

Quoting Miles Chen (2021-08-31 09:42:10)
> Now we have all necessary exported symbols, change
> COMMON_CLK_MEDAITEK and COMMON_CLK_MT6779* to tristate.
> 

Please squash this with the patch that makes them into modular drivers.

> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: Hanks Chen <hanks.chen at mediatek.com>
> Cc: Wendell Lin <wendell.lin at mediatek.com>
> Cc: Lee Jones <lee.jones at linaro.org>
> Signed-off-by: Miles Chen <miles.chen at mediatek.com>


From zhaoxiao at uniontech.com  Tue Aug 31 22:42:30 2021
From: zhaoxiao at uniontech.com (zhaoxiao)
Date: Wed,  1 Sep 2021 13:42:30 +0800
Subject: [PATCH] pwm: samsung: Simplify using devm_pwmchip_add()
Message-ID: <20210901054230.29678-1-zhaoxiao@uniontech.com>

With devm_pwmchip_add() we can drop pwmchip_remove() from the device
remove callback. The latter can then go away, too and as this is the
only user of platform_get_drvdata(), the respective call to
platform_set_drvdata() can go, too.

Signed-off-by: zhaoxiao <zhaoxiao at uniontech.com>
---
 drivers/pwm/pwm-samsung.c | 18 +-----------------
 1 file changed, 1 insertion(+), 17 deletions(-)

diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index f6c528f02d43..b860a7b8bbdf 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -560,9 +560,7 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 	chip->tclk0 = devm_clk_get(&pdev->dev, "pwm-tclk0");
 	chip->tclk1 = devm_clk_get(&pdev->dev, "pwm-tclk1");
 
-	platform_set_drvdata(pdev, chip);
-
-	ret = pwmchip_add(&chip->chip);
+	ret = devm_pwmchip_add(&pdev->dev, &chip->chip);
 	if (ret < 0) {
 		dev_err(dev, "failed to register PWM chip\n");
 		clk_disable_unprepare(chip->base_clk);
@@ -577,19 +575,6 @@ static int pwm_samsung_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int pwm_samsung_remove(struct platform_device *pdev)
-{
-	struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = pwmchip_remove(&chip->chip);
-	if (ret < 0)
-		return ret;
-
-	clk_disable_unprepare(chip->base_clk);
-
-	return 0;
-}
 
 #ifdef CONFIG_PM_SLEEP
 static int pwm_samsung_resume(struct device *dev)
@@ -635,7 +620,6 @@ static struct platform_driver pwm_samsung_driver = {
 		.of_match_table = of_match_ptr(samsung_pwm_matches),
 	},
 	.probe		= pwm_samsung_probe,
-	.remove		= pwm_samsung_remove,
 };
 module_platform_driver(pwm_samsung_driver);
 
-- 
2.20.1





From sboyd at kernel.org  Tue Aug 31 22:44:32 2021
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 31 Aug 2021 22:44:32 -0700
Subject: [PATCH v2 0/6] clk: at91: updates for power management and dvfs
In-Reply-To: <35d409b5-75d9-636e-e9c5-42d833b8e592@microchip.com>
References: <20210401122726.28528-1-claudiu.beznea@microchip.com>
 <6ecc4822-8112-43d4-1259-cd7dfe79d71c@microchip.com>
 <163021931214.2676726.2951110502140668721@swboyd.mtv.corp.google.com>
 <35d409b5-75d9-636e-e9c5-42d833b8e592@microchip.com>
Message-ID: <163047507296.42057.10597374695758699868@swboyd.mtv.corp.google.com>

Quoting Claudiu.Beznea at microchip.com (2021-08-29 22:46:13)
> On 29.08.2021 09:41, Stephen Boyd wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> > Quoting Claudiu.Beznea at microchip.com (2021-08-02 01:36:52)
> >> On 01.04.2021 15:27, Claudiu Beznea wrote:
> >> Hi Stephen,
> >>
> >> Please ignore the DVFS patch in this series
> >> (clk: at91: clk-master: update for dvfs) as I have some updates to it. I'll
> >> introduce them in the next version.
> >>
> > 
> > Can I apply the rest of them though?
> > 
> 
> Yes, please! One note, at patch "clk: at91: clk-master: add register
> definition for sama7g5's master clock", is that changes in header
> (include/linux/clk/at91_pmc.h) were taken trough [1] via at91 tree because
> the build was broken at some point for multi_v7_defconfig on linux-next.
> 

Ok. Maybe it would be best to just resend the ones that you want me to
apply then.


From caihuoqing at baidu.com  Tue Aug 31 22:45:35 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:45:35 +0800
Subject: [PATCH] media: cec: ao-cec: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901054535.6215-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/cec/platform/meson/ao-cec-g12a.c | 4 +---
 drivers/media/cec/platform/meson/ao-cec.c      | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/media/cec/platform/meson/ao-cec-g12a.c b/drivers/media/cec/platform/meson/ao-cec-g12a.c
index 891533060d49..68fe6d6a8178 100644
--- a/drivers/media/cec/platform/meson/ao-cec-g12a.c
+++ b/drivers/media/cec/platform/meson/ao-cec-g12a.c
@@ -633,7 +633,6 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev)
 {
 	struct meson_ao_cec_g12a_device *ao_cec;
 	struct device *hdmi_dev;
-	struct resource *res;
 	void __iomem *base;
 	int ret, irq;
 
@@ -664,8 +663,7 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev)
 
 	ao_cec->adap->owner = THIS_MODULE;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	base = devm_ioremap_resource(&pdev->dev, res);
+	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base)) {
 		ret = PTR_ERR(base);
 		goto out_probe_adapter;
diff --git a/drivers/media/cec/platform/meson/ao-cec.c b/drivers/media/cec/platform/meson/ao-cec.c
index 09aff82c3773..6b440f0635d9 100644
--- a/drivers/media/cec/platform/meson/ao-cec.c
+++ b/drivers/media/cec/platform/meson/ao-cec.c
@@ -602,7 +602,6 @@ static int meson_ao_cec_probe(struct platform_device *pdev)
 {
 	struct meson_ao_cec_device *ao_cec;
 	struct device *hdmi_dev;
-	struct resource *res;
 	int ret, irq;
 
 	hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
@@ -626,8 +625,7 @@ static int meson_ao_cec_probe(struct platform_device *pdev)
 
 	ao_cec->adap->owner = THIS_MODULE;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ao_cec->base = devm_ioremap_resource(&pdev->dev, res);
+	ao_cec->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ao_cec->base)) {
 		ret = PTR_ERR(ao_cec->base);
 		goto out_probe_adapter;
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:51:08 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:51:08 +0800
Subject: [PATCH] media: coda: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055109.6529-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/coda/imx-vdoa.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c
index 8bc0d8371819..6996d4571e36 100644
--- a/drivers/media/platform/coda/imx-vdoa.c
+++ b/drivers/media/platform/coda/imx-vdoa.c
@@ -301,8 +301,7 @@ static int vdoa_probe(struct platform_device *pdev)
 		return PTR_ERR(vdoa->vdoa_clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	vdoa->regs = devm_ioremap_resource(vdoa->dev, res);
+	vdoa->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(vdoa->regs))
 		return PTR_ERR(vdoa->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:51:23 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:51:23 +0800
Subject: [PATCH] media: exynos-gsc: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055124.6629-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/exynos-gsc/gsc-core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index f49f3322f835..cfd6ae70b8d8 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -1137,8 +1137,7 @@ static int gsc_probe(struct platform_device *pdev)
 	spin_lock_init(&gsc->slock);
 	mutex_init(&gsc->lock);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	gsc->regs = devm_ioremap_resource(dev, res);
+	gsc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(gsc->regs))
 		return PTR_ERR(gsc->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:51:31 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:51:31 +0800
Subject: [PATCH] media: exynos4-is: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055132.6679-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/exynos4-is/mipi-csis.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 32b23329b033..27a214936cb0 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -766,7 +766,6 @@ static int s5pcsis_probe(struct platform_device *pdev)
 	const struct of_device_id *of_id;
 	const struct csis_drvdata *drv_data;
 	struct device *dev = &pdev->dev;
-	struct resource *mem_res;
 	struct csis_state *state;
 	int ret = -ENOMEM;
 	int i;
@@ -800,8 +799,7 @@ static int s5pcsis_probe(struct platform_device *pdev)
 	if (IS_ERR(state->phy))
 		return PTR_ERR(state->phy);
 
-	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	state->regs = devm_ioremap_resource(dev, mem_res);
+	state->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(state->regs))
 		return PTR_ERR(state->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:51:38 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:51:38 +0800
Subject: [PATCH] media: imx-jpeg: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055139.6729-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/imx-jpeg/mxc-jpeg.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
index 755138063ee6..b3cc5199ef28 100644
--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
@@ -1959,7 +1959,6 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
 {
 	struct mxc_jpeg_dev *jpeg;
 	struct device *dev = &pdev->dev;
-	struct resource *res;
 	int dec_irq;
 	int ret;
 	int mode;
@@ -1982,8 +1981,7 @@ static int mxc_jpeg_probe(struct platform_device *pdev)
 		goto err_irq;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	jpeg->base_reg = devm_ioremap_resource(&pdev->dev, res);
+	jpeg->base_reg = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(jpeg->base_reg))
 		return PTR_ERR(jpeg->base_reg);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:51:46 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:51:46 +0800
Subject: [PATCH] media: imx-pxp: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055147.6779-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/imx-pxp.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c
index 4321edc0c23d..723b096fedd1 100644
--- a/drivers/media/platform/imx-pxp.c
+++ b/drivers/media/platform/imx-pxp.c
@@ -1636,7 +1636,6 @@ static int pxp_soft_reset(struct pxp_dev *dev)
 static int pxp_probe(struct platform_device *pdev)
 {
 	struct pxp_dev *dev;
-	struct resource *res;
 	struct video_device *vfd;
 	int irq;
 	int ret;
@@ -1652,8 +1651,7 @@ static int pxp_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dev->mmio = devm_ioremap_resource(&pdev->dev, res);
+	dev->mmio = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dev->mmio))
 		return PTR_ERR(dev->mmio);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:52:01 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:52:01 +0800
Subject: [PATCH] media: mtk-jpeg: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055202.6879-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
index a89c7b206eef..af994b9913a6 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -1341,7 +1341,6 @@ static inline void mtk_jpeg_clk_release(struct mtk_jpeg_dev *jpeg)
 static int mtk_jpeg_probe(struct platform_device *pdev)
 {
 	struct mtk_jpeg_dev *jpeg;
-	struct resource *res;
 	int jpeg_irq;
 	int ret;
 
@@ -1355,8 +1354,7 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
 	jpeg->variant = of_device_get_match_data(jpeg->dev);
 	INIT_DELAYED_WORK(&jpeg->job_timeout_work, mtk_jpeg_job_timeout_work);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	jpeg->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	jpeg->reg_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(jpeg->reg_base)) {
 		ret = PTR_ERR(jpeg->reg_base);
 		return ret;
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:51:54 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:51:54 +0800
Subject: [PATCH] media: meson: ge2d: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055154.6829-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/meson/ge2d/ge2d.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/platform/meson/ge2d/ge2d.c b/drivers/media/platform/meson/ge2d/ge2d.c
index 9b1e973e78da..ccda18e5a377 100644
--- a/drivers/media/platform/meson/ge2d/ge2d.c
+++ b/drivers/media/platform/meson/ge2d/ge2d.c
@@ -922,7 +922,6 @@ static int ge2d_probe(struct platform_device *pdev)
 	struct reset_control *rst;
 	struct video_device *vfd;
 	struct meson_ge2d *ge2d;
-	struct resource *res;
 	void __iomem *regs;
 	int ret = 0;
 	int irq;
@@ -937,8 +936,7 @@ static int ge2d_probe(struct platform_device *pdev)
 	ge2d->dev = &pdev->dev;
 	mutex_init(&ge2d->mutex);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	regs = devm_ioremap_resource(ge2d->dev, res);
+	regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(regs))
 		return PTR_ERR(regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:54:39 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:54:39 +0800
Subject: [PATCH] media: rc: meson-ir: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055440.7079-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/rc/meson-ir.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index dad55950dfc6..4b769111f78e 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -102,7 +102,6 @@ static int meson_ir_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *node = dev->of_node;
-	struct resource *res;
 	const char *map_name;
 	struct meson_ir *ir;
 	int irq, ret;
@@ -111,8 +110,7 @@ static int meson_ir_probe(struct platform_device *pdev)
 	if (!ir)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ir->reg = devm_ioremap_resource(dev, res);
+	ir->reg = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ir->reg))
 		return PTR_ERR(ir->reg);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:54:47 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:54:47 +0800
Subject: [PATCH] media: rc: mtk-cir: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055448.7129-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/rc/mtk-cir.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
index 65a136c0fac2..840e7aec5c21 100644
--- a/drivers/media/rc/mtk-cir.c
+++ b/drivers/media/rc/mtk-cir.c
@@ -292,7 +292,6 @@ static int mtk_ir_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *dn = dev->of_node;
-	struct resource *res;
 	struct mtk_ir *ir;
 	u32 val;
 	int ret = 0;
@@ -320,8 +319,7 @@ static int mtk_ir_probe(struct platform_device *pdev)
 		ir->bus = ir->clk;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ir->base = devm_ioremap_resource(dev, res);
+	ir->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ir->base))
 		return PTR_ERR(ir->base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:54:54 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:54:54 +0800
Subject: [PATCH] media: rc: st_rc: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055455.7179-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/rc/st_rc.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c
index d79d1e3996b2..4e419dbbacd3 100644
--- a/drivers/media/rc/st_rc.c
+++ b/drivers/media/rc/st_rc.c
@@ -231,7 +231,6 @@ static int st_rc_probe(struct platform_device *pdev)
 	int ret = -EINVAL;
 	struct rc_dev *rdev;
 	struct device *dev = &pdev->dev;
-	struct resource *res;
 	struct st_rc_device *rc_dev;
 	struct device_node *np = pdev->dev.of_node;
 	const char *rx_mode;
@@ -274,9 +273,7 @@ static int st_rc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	rc_dev->base = devm_ioremap_resource(dev, res);
+	rc_dev->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(rc_dev->base)) {
 		ret = PTR_ERR(rc_dev->base);
 		goto err;
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:55:02 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:55:02 +0800
Subject: [PATCH] media: rc: sunxi-cir: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055503.7229-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/rc/sunxi-cir.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
index 168e1d2c876a..391a591c1b75 100644
--- a/drivers/media/rc/sunxi-cir.c
+++ b/drivers/media/rc/sunxi-cir.c
@@ -255,7 +255,6 @@ static int sunxi_ir_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *dn = dev->of_node;
 	const struct sunxi_ir_quirks *quirks;
-	struct resource *res;
 	struct sunxi_ir *ir;
 	u32 b_clk_freq = SUNXI_IR_BASE_CLK;
 
@@ -301,8 +300,7 @@ static int sunxi_ir_probe(struct platform_device *pdev)
 	dev_dbg(dev, "set base clock frequency to %d Hz.\n", b_clk_freq);
 
 	/* IO */
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ir->base = devm_ioremap_resource(dev, res);
+	ir->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ir->base)) {
 		return PTR_ERR(ir->base);
 	}
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:55:46 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:55:46 +0800
Subject: [PATCH] media: rockchip: rga: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055547.7529-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/rockchip/rga/rga.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index 6759091b15e0..4de5e8d2b261 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -800,7 +800,6 @@ static int rga_probe(struct platform_device *pdev)
 {
 	struct rockchip_rga *rga;
 	struct video_device *vfd;
-	struct resource *res;
 	int ret = 0;
 	int irq;
 
@@ -821,9 +820,7 @@ static int rga_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(rga->dev);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	rga->regs = devm_ioremap_resource(rga->dev, res);
+	rga->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(rga->regs)) {
 		ret = PTR_ERR(rga->regs);
 		goto err_put_clk;
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:56:01 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:56:01 +0800
Subject: [PATCH] media: s5p-g2d: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055602.7629-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/s5p-g2d/g2d.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 1cb5eaabf340..fa0bb31bd2b9 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -635,9 +635,7 @@ static int g2d_probe(struct platform_device *pdev)
 	mutex_init(&dev->mutex);
 	atomic_set(&dev->num_inst, 0);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	dev->regs = devm_ioremap_resource(&pdev->dev, res);
+	dev->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dev->regs))
 		return PTR_ERR(dev->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:56:09 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:56:09 +0800
Subject: [PATCH] media: s5p-jpeg: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055609.7679-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/s5p-jpeg/jpeg-core.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index d402e456f27d..1faff037cdf7 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2850,7 +2850,6 @@ static void *jpeg_get_drv_data(struct device *dev);
 static int s5p_jpeg_probe(struct platform_device *pdev)
 {
 	struct s5p_jpeg *jpeg;
-	struct resource *res;
 	int i, ret;
 
 	/* JPEG IP abstraction struct */
@@ -2867,9 +2866,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
 	jpeg->dev = &pdev->dev;
 
 	/* memory-mapped registers */
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
+	jpeg->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(jpeg->regs))
 		return PTR_ERR(jpeg->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:56:16 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:56:16 +0800
Subject: [PATCH] media: s5p-mfc: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055617.7729-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index eba2b9f040df..e0ec24b39fd4 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1289,8 +1289,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
 
 	dev->variant = of_device_get_match_data(&pdev->dev);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
+	dev->regs_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dev->regs_base))
 		return PTR_ERR(dev->regs_base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:56:31 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:56:31 +0800
Subject: [PATCH] media: sti/c8sectpfe: Make use of the helper function
 devm_platform_ioremap_resource_byname()
Message-ID: <20210901055631.7829-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 02dc78bd7fab..9f05984f711a 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -665,7 +665,6 @@ static int c8sectpfe_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *child, *np = dev->of_node;
 	struct c8sectpfei *fei;
-	struct resource *res;
 	int ret, index = 0;
 	struct channel_info *tsin;
 
@@ -676,14 +675,11 @@ static int c8sectpfe_probe(struct platform_device *pdev)
 
 	fei->dev = dev;
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "c8sectpfe");
-	fei->io = devm_ioremap_resource(dev, res);
+	fei->io = devm_platform_ioremap_resource_byname(pdev, "c8sectpfe");
 	if (IS_ERR(fei->io))
 		return PTR_ERR(fei->io);
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-					"c8sectpfe-ram");
-	fei->sram = devm_ioremap_resource(dev, res);
+	fei->sram = devm_platform_ioremap_resource_byname(pdev, "c8sectpfe-ram");
 	if (IS_ERR(fei->sram))
 		return PTR_ERR(fei->sram);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:56:45 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:56:45 +0800
Subject: [PATCH] media: stm32-cec: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055646.7929-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/cec/platform/stm32/stm32-cec.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/cec/platform/stm32/stm32-cec.c b/drivers/media/cec/platform/stm32/stm32-cec.c
index 0ffd89712536..40db7911b437 100644
--- a/drivers/media/cec/platform/stm32/stm32-cec.c
+++ b/drivers/media/cec/platform/stm32/stm32-cec.c
@@ -255,7 +255,6 @@ static const struct regmap_config stm32_cec_regmap_cfg = {
 static int stm32_cec_probe(struct platform_device *pdev)
 {
 	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_MODE_MONITOR_ALL;
-	struct resource *res;
 	struct stm32_cec *cec;
 	void __iomem *mmio;
 	int ret;
@@ -266,8 +265,7 @@ static int stm32_cec_probe(struct platform_device *pdev)
 
 	cec->dev = &pdev->dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	mmio = devm_ioremap_resource(&pdev->dev, res);
+	mmio = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mmio))
 		return PTR_ERR(mmio);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:56:53 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:56:53 +0800
Subject: [PATCH] media: sunxi: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055654.7979-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c | 4 +---
 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 4 +---
 drivers/media/platform/sunxi/sun8i-di/sun8i-di.c   | 4 +---
 3 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
index 94e98e470aff..80a10f238bbe 100644
--- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
@@ -154,7 +154,6 @@ static int sun4i_csi_probe(struct platform_device *pdev)
 	struct v4l2_subdev *subdev;
 	struct video_device *vdev;
 	struct sun4i_csi *csi;
-	struct resource *res;
 	int ret;
 	int irq;
 
@@ -179,8 +178,7 @@ static int sun4i_csi_probe(struct platform_device *pdev)
 	media_device_init(&csi->mdev);
 	csi->v4l.mdev = &csi->mdev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	csi->regs = devm_ioremap_resource(&pdev->dev, res);
+	csi->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(csi->regs))
 		return PTR_ERR(csi->regs);
 
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
index 4b8d66fec3cf..fc96921b0583 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
@@ -833,13 +833,11 @@ static const struct regmap_config sun6i_csi_regmap_config = {
 static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev,
 				      struct platform_device *pdev)
 {
-	struct resource *res;
 	void __iomem *io_base;
 	int ret;
 	int irq;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	io_base = devm_ioremap_resource(&pdev->dev, res);
+	io_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(io_base))
 		return PTR_ERR(io_base);
 
diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
index 671e4a928993..aa65d70b6270 100644
--- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
@@ -803,7 +803,6 @@ static int deinterlace_probe(struct platform_device *pdev)
 {
 	struct deinterlace_dev *dev;
 	struct video_device *vfd;
-	struct resource *res;
 	int irq, ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -825,8 +824,7 @@ static int deinterlace_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dev->base = devm_ioremap_resource(&pdev->dev, res);
+	dev->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dev->base))
 		return PTR_ERR(dev->base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Tue Aug 31 22:57:15 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 13:57:15 +0800
Subject: [PATCH] media: xilinx: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901055716.8129-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/media/platform/xilinx/xilinx-vip.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c
index 425a32dd5d19..a0073122798f 100644
--- a/drivers/media/platform/xilinx/xilinx-vip.c
+++ b/drivers/media/platform/xilinx/xilinx-vip.c
@@ -205,10 +205,8 @@ EXPORT_SYMBOL_GPL(xvip_clr_and_set);
 int xvip_init_resources(struct xvip_device *xvip)
 {
 	struct platform_device *pdev = to_platform_device(xvip->dev);
-	struct resource *res;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	xvip->iomem = devm_ioremap_resource(xvip->dev, res);
+	xvip->iomem = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(xvip->iomem))
 		return PTR_ERR(xvip->iomem);
 
-- 
2.25.1



From gregkh at linuxfoundation.org  Tue Aug 31 23:07:53 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 1 Sep 2021 08:07:53 +0200
Subject: [PATCH v2] usb: ehci: handshake CMD_RUN instead of STS_HALT
In-Reply-To: <20210901035041.10810-1-neal_liu@aspeedtech.com>
References: <20210901035041.10810-1-neal_liu@aspeedtech.com>
Message-ID: <YS8YuX9laah5d/NY@kroah.com>

On Wed, Sep 01, 2021 at 11:50:41AM +0800, neal_liu wrote:
> Retitle.
> 
> For Aspeed, HCHalted status depends on not only Run/Stop but also
> ASS/PSS status.
> Handshake CMD_RUN on startup instead.
> 
> Signed-off-by: neal_liu <neal_liu at aspeedtech.com>
> ---
>  drivers/usb/host/ehci-hcd.c      | 11 ++++++++++-
>  drivers/usb/host/ehci-platform.c |  6 ++++++
>  drivers/usb/host/ehci.h          |  1 +
>  3 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index 10b0365f3439..01c022e46aa2 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -634,7 +634,16 @@ static int ehci_run (struct usb_hcd *hcd)
>  	/* Wait until HC become operational */
>  	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
>  	msleep(5);
> -	rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000);
> +
> +	/* For Aspeed, STS_HALT also depends on ASS/PSS status.
> +	 * Skip this check on startup.
> +	 */
> +	if (ehci->is_aspeed)
> +		rc = ehci_handshake(ehci, &ehci->regs->command, CMD_RUN,
> +				    1, 100 * 1000);
> +	else
> +		rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT,
> +				    0, 100 * 1000);
>  
>  	up_write(&ehci_cf_port_reset_rwsem);
>  
> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> index c70f2d0b4aaf..c3dc906274d9 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -297,6 +297,12 @@ static int ehci_platform_probe(struct platform_device *dev)
>  					  "has-transaction-translator"))
>  			hcd->has_tt = 1;
>  
> +		if (of_device_is_compatible(dev->dev.of_node,
> +					    "aspeed,ast2500-ehci") ||
> +		    of_device_is_compatible(dev->dev.of_node,
> +					    "aspeed,ast2600-ehci"))
> +			ehci->is_aspeed = 1;
> +
>  		if (soc_device_match(quirk_poll_match))
>  			priv->quirk_poll = true;
>  
> diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
> index 80bb823aa9fe..fdd073cc053b 100644
> --- a/drivers/usb/host/ehci.h
> +++ b/drivers/usb/host/ehci.h
> @@ -219,6 +219,7 @@ struct ehci_hcd {			/* one per controller */
>  	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */
>  	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */
>  	unsigned		spurious_oc:1;
> +	unsigned		is_aspeed:1;
>  
>  	/* required for usb32 quirk */
>  	#define OHCI_CTRL_HCFS          (3 << 6)
> -- 
> 2.17.1
> 

Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- It looks like you did not use your "real" name for the patch on either
  the Signed-off-by: line, or the From: line (both of which have to
  match).  Please read the kernel file, Documentation/SubmittingPatches
  for how to do this correctly.

- This looks like a new version of a previously submitted patch, but you
  did not list below the --- line any changes from the previous version.
  Please read the section entitled "The canonical patch format" in the
  kernel file, Documentation/SubmittingPatches for what needs to be done
  here to properly describe this.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot


From chiawei_wang at aspeedtech.com  Tue Aug 31 23:22:14 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Wed, 1 Sep 2021 14:22:14 +0800
Subject: [PATCH 0/2] arm: aspeed: Add LPC uart routing support
Message-ID: <20210901062216.32675-1-chiawei_wang@aspeedtech.com>

Add LPC uart routing driver and the device tree nodes.

Chia-Wei Wang (2):
  soc: aspeed: Add LPC UART routing support
  ARM: dts: aspeed: Add uart routing to device tree

 arch/arm/boot/dts/aspeed-g5.dtsi             |   6 +
 arch/arm/boot/dts/aspeed-g6.dtsi             |   6 +
 drivers/soc/aspeed/Kconfig                   |  11 +
 drivers/soc/aspeed/Makefile                  |   9 +-
 drivers/soc/aspeed/aspeed-lpc-uart-routing.c | 621 +++++++++++++++++++
 5 files changed, 649 insertions(+), 4 deletions(-)
 create mode 100644 drivers/soc/aspeed/aspeed-lpc-uart-routing.c

-- 
2.17.1



From chiawei_wang at aspeedtech.com  Tue Aug 31 23:22:15 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Wed, 1 Sep 2021 14:22:15 +0800
Subject: [PATCH 1/2] soc: aspeed: Add LPC UART routing support
In-Reply-To: <20210901062216.32675-1-chiawei_wang@aspeedtech.com>
References: <20210901062216.32675-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210901062216.32675-2-chiawei_wang@aspeedtech.com>

Add driver support for the LPC UART routing control. Users can perform
runtime configuration of the RX muxes among the UART controllers and the
UART TXD/RXD IO pins. This is achieved through the exported sysfs interface.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 drivers/soc/aspeed/Kconfig                   |  11 +
 drivers/soc/aspeed/Makefile                  |   9 +-
 drivers/soc/aspeed/aspeed-lpc-uart-routing.c | 621 +++++++++++++++++++
 3 files changed, 637 insertions(+), 4 deletions(-)
 create mode 100644 drivers/soc/aspeed/aspeed-lpc-uart-routing.c

diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
index 243ca196e6ad..6866757e6be2 100644
--- a/drivers/soc/aspeed/Kconfig
+++ b/drivers/soc/aspeed/Kconfig
@@ -24,6 +24,17 @@ config ASPEED_LPC_SNOOP
 	  allows the BMC to listen on and save the data written by
 	  the host to an arbitrary LPC I/O port.
 
+config ASPEED_LPC_UART_ROUTING
+	tristate "ASPEED LPC uart routing control"
+	select REGMAP
+	select MFD_SYSCON
+	default ARCH_ASPEED
+	help
+	  Provides a driver to control the LPC UART routing paths.
+	  An sysfs interface is exported allowing users to perform
+	  runtime configuration of the RX muxes between the UART
+	  controllers and I/O pins.
+
 config ASPEED_P2A_CTRL
 	tristate "ASPEED P2A (VGA MMIO to BMC) bridge control"
 	select REGMAP
diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
index fcab7192e1a4..87ad6578ddbb 100644
--- a/drivers/soc/aspeed/Makefile
+++ b/drivers/soc/aspeed/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_ASPEED_LPC_CTRL)	+= aspeed-lpc-ctrl.o
-obj-$(CONFIG_ASPEED_LPC_SNOOP)	+= aspeed-lpc-snoop.o
-obj-$(CONFIG_ASPEED_P2A_CTRL)	+= aspeed-p2a-ctrl.o
-obj-$(CONFIG_ASPEED_SOCINFO)	+= aspeed-socinfo.o
+obj-$(CONFIG_ASPEED_LPC_CTRL)		+= aspeed-lpc-ctrl.o
+obj-$(CONFIG_ASPEED_LPC_SNOOP)		+= aspeed-lpc-snoop.o
+obj-$(CONFIG_ASPEED_LPC_UART_ROUTING)	+= aspeed-lpc-uart-routing.o
+obj-$(CONFIG_ASPEED_P2A_CTRL)		+= aspeed-p2a-ctrl.o
+obj-$(CONFIG_ASPEED_SOCINFO)		+= aspeed-socinfo.o
diff --git a/drivers/soc/aspeed/aspeed-lpc-uart-routing.c b/drivers/soc/aspeed/aspeed-lpc-uart-routing.c
new file mode 100644
index 000000000000..141d0d08b4ff
--- /dev/null
+++ b/drivers/soc/aspeed/aspeed-lpc-uart-routing.c
@@ -0,0 +1,621 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018 Google LLC
+ * Copyright (c) 2021 Aspeed Technology Inc.
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/platform_device.h>
+
+/* register offsets */
+#define HICR9	0x98
+#define HICRA	0x9c
+
+/* attributes options */
+#define UART_ROUTING_IO1	"io1"
+#define UART_ROUTING_IO2	"io2"
+#define UART_ROUTING_IO3	"io3"
+#define UART_ROUTING_IO4	"io4"
+#define UART_ROUTING_IO5	"io5"
+#define UART_ROUTING_IO6	"io6"
+#define UART_ROUTING_IO10	"io10"
+#define UART_ROUTING_UART1	"uart1"
+#define UART_ROUTING_UART2	"uart2"
+#define UART_ROUTING_UART3	"uart3"
+#define UART_ROUTING_UART4	"uart4"
+#define UART_ROUTING_UART5	"uart5"
+#define UART_ROUTING_UART6	"uart6"
+#define UART_ROUTING_UART10	"uart10"
+#define UART_ROUTING_RES	"reserved"
+
+struct aspeed_uart_routing {
+	struct regmap *map;
+	spinlock_t lock;
+	struct attribute_group const *attr_grp;
+};
+
+struct aspeed_uart_routing_selector {
+	struct device_attribute	dev_attr;
+	uint32_t reg;
+	uint32_t mask;
+	uint32_t shift;
+	const char *const options[];
+};
+
+#define to_routing_selector(_dev_attr)					\
+	container_of(_dev_attr, struct aspeed_uart_routing_selector, dev_attr)
+
+static ssize_t aspeed_uart_routing_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf);
+
+static ssize_t aspeed_uart_routing_store(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count);
+
+#define ROUTING_ATTR(_name) {					\
+	.attr = {.name = _name,					\
+		 .mode = VERIFY_OCTAL_PERMISSIONS(0644) },	\
+	.show = aspeed_uart_routing_show,			\
+	.store = aspeed_uart_routing_store,			\
+}
+
+/* routing selector for AST25xx */
+static struct aspeed_uart_routing_selector ast2500_io6_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO6),
+	.reg = HICR9,
+	.shift = 8,
+	.mask = 0xf,
+	.options = {
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART5,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO5,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_uart5_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART5),
+	.reg = HICRA,
+	.shift = 28,
+	.mask = 0xf,
+	.options = {
+		    UART_ROUTING_IO5,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_uart4_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART4),
+	.reg = HICRA,
+	.shift = 25,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_IO6,
+		    NULL,
+	},
+};
+
+static struct aspeed_uart_routing_selector ast2500_uart3_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART3),
+	.reg = HICRA,
+	.shift = 22,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_uart2_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART2),
+	.reg = HICRA,
+	.shift = 19,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_uart1_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART1),
+	.reg = HICRA,
+	.shift = 16,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_io5_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO5),
+	.reg = HICRA,
+	.shift = 12,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART5,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_io4_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO4),
+	.reg = HICRA,
+	.shift = 9,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART5,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_io3_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO3),
+	.reg = HICRA,
+	.shift = 6,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART5,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_io2_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO2),
+	.reg = HICRA,
+	.shift = 3,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART5,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2500_io1_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO1),
+	.reg = HICRA,
+	.shift = 0,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART5,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO6,
+		    NULL,
+		    },
+};
+
+static struct attribute *ast2500_uart_routing_attrs[] = {
+	&ast2500_io6_sel.dev_attr.attr,
+	&ast2500_uart5_sel.dev_attr.attr,
+	&ast2500_uart4_sel.dev_attr.attr,
+	&ast2500_uart3_sel.dev_attr.attr,
+	&ast2500_uart2_sel.dev_attr.attr,
+	&ast2500_uart1_sel.dev_attr.attr,
+	&ast2500_io5_sel.dev_attr.attr,
+	&ast2500_io4_sel.dev_attr.attr,
+	&ast2500_io3_sel.dev_attr.attr,
+	&ast2500_io2_sel.dev_attr.attr,
+	&ast2500_io1_sel.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ast2500_uart_routing_attr_group = {
+	.attrs = ast2500_uart_routing_attrs,
+};
+
+/* routing selector for AST26xx */
+static struct aspeed_uart_routing_selector ast2600_uart10_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART10),
+	.reg = HICR9,
+	.shift = 12,
+	.mask = 0xf,
+	.options = {
+		    UART_ROUTING_IO10,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+			UART_ROUTING_RES,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2600_io10_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO10),
+	.reg = HICR9,
+	.shift = 8,
+	.mask = 0xf,
+	.options = {
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+			UART_ROUTING_RES,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+			UART_ROUTING_RES,
+		    UART_ROUTING_UART10,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2600_uart4_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART4),
+	.reg = HICRA,
+	.shift = 25,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_IO10,
+		    NULL,
+	},
+};
+
+static struct aspeed_uart_routing_selector ast2600_uart3_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART3),
+	.reg = HICRA,
+	.shift = 22,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_IO10,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2600_uart2_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART2),
+	.reg = HICRA,
+	.shift = 19,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_IO10,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2600_uart1_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART1),
+	.reg = HICRA,
+	.shift = 16,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_IO10,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2600_io4_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO4),
+	.reg = HICRA,
+	.shift = 9,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART10,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO10,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2600_io3_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO3),
+	.reg = HICRA,
+	.shift = 6,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART10,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_IO1,
+		    UART_ROUTING_IO2,
+		    UART_ROUTING_IO10,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2600_io2_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO2),
+	.reg = HICRA,
+	.shift = 3,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART10,
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO10,
+		    NULL,
+		    },
+};
+
+static struct aspeed_uart_routing_selector ast2600_io1_sel = {
+	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO1),
+	.reg = HICRA,
+	.shift = 0,
+	.mask = 0x7,
+	.options = {
+		    UART_ROUTING_UART1,
+		    UART_ROUTING_UART2,
+		    UART_ROUTING_UART3,
+		    UART_ROUTING_UART4,
+		    UART_ROUTING_UART10,
+		    UART_ROUTING_IO3,
+		    UART_ROUTING_IO4,
+		    UART_ROUTING_IO10,
+		    NULL,
+		    },
+};
+
+static struct attribute *ast2600_uart_routing_attrs[] = {
+	&ast2600_uart10_sel.dev_attr.attr,
+	&ast2600_io10_sel.dev_attr.attr,
+	&ast2600_uart4_sel.dev_attr.attr,
+	&ast2600_uart3_sel.dev_attr.attr,
+	&ast2600_uart2_sel.dev_attr.attr,
+	&ast2600_uart1_sel.dev_attr.attr,
+	&ast2600_io4_sel.dev_attr.attr,
+	&ast2600_io3_sel.dev_attr.attr,
+	&ast2600_io2_sel.dev_attr.attr,
+	&ast2600_io1_sel.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ast2600_uart_routing_attr_group = {
+	.attrs = ast2600_uart_routing_attrs,
+};
+
+static ssize_t aspeed_uart_routing_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct aspeed_uart_routing *uart_routing = dev_get_drvdata(dev);
+	struct aspeed_uart_routing_selector *sel = to_routing_selector(attr);
+	int val, pos, len;
+
+	regmap_read(uart_routing->map, sel->reg, &val);
+	val = (val >> sel->shift) & sel->mask;
+
+	len = 0;
+	for (pos = 0; sel->options[pos] != NULL; ++pos) {
+		if (pos == val) {
+			len += snprintf(buf + len, PAGE_SIZE - 1 - len,
+					"[%s] ", sel->options[pos]);
+		} else {
+			len += snprintf(buf + len, PAGE_SIZE - 1 - len,
+					"%s ", sel->options[pos]);
+		}
+	}
+
+	if (val >= pos) {
+		len += snprintf(buf + len, PAGE_SIZE - 1 - len,
+				"[unknown(%d)]", val);
+	}
+
+	len += snprintf(buf + len, PAGE_SIZE - 1 - len, "\n");
+
+	return len;
+}
+
+static ssize_t aspeed_uart_routing_store(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	unsigned long flags;
+	struct aspeed_uart_routing *uart_routing = dev_get_drvdata(dev);
+	struct aspeed_uart_routing_selector *sel = to_routing_selector(attr);
+	int val;
+
+	val = match_string(sel->options, -1, buf);
+	if (val < 0) {
+		dev_err(dev, "invalid value \"%s\"\n", buf);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&uart_routing->lock, flags);
+
+	regmap_update_bits(uart_routing->map, sel->reg,
+			(sel->mask << sel->shift),
+			(val & sel->mask) << sel->shift);
+
+	spin_unlock_irqrestore(&uart_routing->lock, flags);
+
+	return count;
+}
+
+static int aspeed_uart_routing_probe(struct platform_device *pdev)
+{
+	int rc;
+	struct device *dev = &pdev->dev;
+	struct aspeed_uart_routing *uart_routing;
+
+	uart_routing = devm_kzalloc(&pdev->dev,
+				    sizeof(*uart_routing),
+				    GFP_KERNEL);
+	if (!uart_routing) {
+		dev_err(dev, "cannot allocate memory\n");
+		return -ENOMEM;
+	}
+
+	uart_routing->map = syscon_node_to_regmap(dev->parent->of_node);
+	if (IS_ERR(uart_routing->map)) {
+		dev_err(dev, "cannot get regmap\n");
+		return PTR_ERR(uart_routing->map);
+	}
+
+	uart_routing->attr_grp = of_device_get_match_data(dev);
+
+	spin_lock_init(&uart_routing->lock);
+
+	rc = sysfs_create_group(&dev->kobj,
+				uart_routing->attr_grp);
+	if (rc < 0)
+		return rc;
+
+	dev_set_drvdata(dev, uart_routing);
+
+	dev_info(dev, "module loaded\n");
+
+	return 0;
+}
+
+static int aspeed_uart_routing_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct aspeed_uart_routing *uart_routing = platform_get_drvdata(pdev);
+
+	sysfs_remove_group(&dev->kobj,
+			   uart_routing->attr_grp);
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_uart_routing_table[] = {
+	{ .compatible = "aspeed,ast2500-lpc-uart-routing",
+	  .data = &ast2500_uart_routing_attr_group },
+	{ .compatible = "aspeed,ast2600-lpc-uart-routing",
+	  .data = &ast2600_uart_routing_attr_group },
+	{ },
+};
+
+static struct platform_driver aspeed_uart_routing_driver = {
+	.driver = {
+		.name = "aspeed-lpc-uart-routing",
+		.of_match_table = aspeed_uart_routing_table,
+	},
+	.probe = aspeed_uart_routing_probe,
+	.remove = aspeed_uart_routing_remove,
+};
+
+module_platform_driver(aspeed_uart_routing_driver);
+
+MODULE_AUTHOR("Oskar Senft <osk at google.com>");
+MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang at aspeedtech.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Driver to configure Aspeed UART routing");
-- 
2.17.1



From chiawei_wang at aspeedtech.com  Tue Aug 31 23:22:16 2021
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Wed, 1 Sep 2021 14:22:16 +0800
Subject: [PATCH 2/2] ARM: dts: aspeed: Add uart routing to device tree
In-Reply-To: <20210901062216.32675-1-chiawei_wang@aspeedtech.com>
References: <20210901062216.32675-1-chiawei_wang@aspeedtech.com>
Message-ID: <20210901062216.32675-3-chiawei_wang@aspeedtech.com>

Add LPC uart routing to the device tree for Aspeed AST25xx/AST26xx SoCs.

Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 arch/arm/boot/dts/aspeed-g5.dtsi | 6 ++++++
 arch/arm/boot/dts/aspeed-g6.dtsi | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 329eaeef66fb..ba7744cb0842 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -492,6 +492,12 @@
 					#reset-cells = <1>;
 				};
 
+				lpc_uart_routing: lpc-uart-routing at 98 {
+					compatible = "aspeed,ast2500-lpc-uart-routing";
+					reg = <0x98 0x8>;
+					status = "disabled";
+				};
+
 				lhc: lhc at a0 {
 					compatible = "aspeed,ast2500-lhc";
 					reg = <0xa0 0x24 0xc8 0x8>;
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index f96607b7b4e2..3699c50a2945 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -523,6 +523,12 @@
 					#reset-cells = <1>;
 				};
 
+				lpc_uart_routing: lpc-uart-routing at 98 {
+					compatible = "aspeed,ast2600-lpc-uart-routing";
+					reg = <0x98 0x8>;
+					status = "disabled";
+				};
+
 				ibt: ibt at 140 {
 					compatible = "aspeed,ast2600-ibt-bmc";
 					reg = <0x140 0x18>;
-- 
2.17.1



From wenst at chromium.org  Tue Aug 31 23:40:23 2021
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 1 Sep 2021 14:40:23 +0800
Subject: [PATCH v6 0/3] support gce on mt8192 platform
In-Reply-To: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>
References: <1627890365-22992-1-git-send-email-yongqiang.niu@mediatek.com>
Message-ID: <CAGXv+5GNbx6jJ2MuCtmMF=ABuoqtS84OvhYoGr_nOrwqCs392A@mail.gmail.com>

On Mon, Aug 2, 2021 at 3:47 PM Yongqiang Niu <yongqiang.niu at mediatek.com> wrote:
>
> Change since v5:
> -rebase on linux 5.14-rc1
>
> Yongqiang Niu (3):
>   dt-binding: gce: add gce header file for mt8192
>   arm64: dts: mt8192: add gce node
>   mailbox: cmdq: add mt8192 support

Looks like all the driver parts are in -next, but the dts patch is not.
Can you resend that patch after the merge window?

Thanks
ChenYu


From p.zabel at pengutronix.de  Tue Aug 31 23:46:38 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 01 Sep 2021 08:46:38 +0200
Subject: [PATCH] media: imx-pxp: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901055147.6779-1-caihuoqing@baidu.com>
References: <20210901055147.6779-1-caihuoqing@baidu.com>
Message-ID: <718b22d5ca0f8afa2f2815287e7aa13d34d9b0ec.camel@pengutronix.de>

On Wed, 2021-09-01 at 13:51 +0800, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> ---
>  drivers/media/platform/imx-pxp.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c
> index 4321edc0c23d..723b096fedd1 100644
> --- a/drivers/media/platform/imx-pxp.c
> +++ b/drivers/media/platform/imx-pxp.c
> @@ -1636,7 +1636,6 @@ static int pxp_soft_reset(struct pxp_dev *dev)
>  static int pxp_probe(struct platform_device *pdev)
>  {
>  	struct pxp_dev *dev;
> -	struct resource *res;
>  	struct video_device *vfd;
>  	int irq;
>  	int ret;
> @@ -1652,8 +1651,7 @@ static int pxp_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	dev->mmio = devm_ioremap_resource(&pdev->dev, res);
> +	dev->mmio = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(dev->mmio))
>  		return PTR_ERR(dev->mmio);

Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>

regards
Philipp


From p.zabel at pengutronix.de  Tue Aug 31 23:46:52 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 01 Sep 2021 08:46:52 +0200
Subject: [PATCH] media: coda: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901055109.6529-1-caihuoqing@baidu.com>
References: <20210901055109.6529-1-caihuoqing@baidu.com>
Message-ID: <4a27833cea3752e7f8f88a577d83d70783f8d584.camel@pengutronix.de>

On Wed, 2021-09-01 at 13:51 +0800, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> ---
>  drivers/media/platform/coda/imx-vdoa.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c
> index 8bc0d8371819..6996d4571e36 100644
> --- a/drivers/media/platform/coda/imx-vdoa.c
> +++ b/drivers/media/platform/coda/imx-vdoa.c
> @@ -301,8 +301,7 @@ static int vdoa_probe(struct platform_device *pdev)
>  		return PTR_ERR(vdoa->vdoa_clk);
>  	}
>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	vdoa->regs = devm_ioremap_resource(vdoa->dev, res);
> +	vdoa->regs = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(vdoa->regs))
>  		return PTR_ERR(vdoa->regs);
>  

Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>

regards
Philipp


From zhouzhouyi at gmail.com  Tue Aug 31 23:47:18 2021
From: zhouzhouyi at gmail.com (Zhouyi Zhou)
Date: Wed, 1 Sep 2021 14:47:18 +0800
Subject: rcu_preempt detected stalls
In-Reply-To: <2712e554-2058-d3c3-72ae-cca7562a2ec7@codeaurora.org>
References: <20210831152144.GA28128@trex>
 <CAABZP2xGnSLVbgxqjKMq=Oj_H7rYfYjuCvmBpmZ4tRptGs3SEw@mail.gmail.com>
 <CAABZP2wUdToiAWOAgqDZrZtkuEdrXEv9GDgbioW3PZAyseOSgA@mail.gmail.com>
 <CAABZP2zg8c_gkm4+h4-mPCv_uDf5-iJFHEExCDFoES0jmBeuKw@mail.gmail.com>
 <2712e554-2058-d3c3-72ae-cca7562a2ec7@codeaurora.org>
Message-ID: <CAABZP2w5tqwKBEh7gJ8h02ZVj6gGdYnPy1gBsD7DEbtbA-9KxQ@mail.gmail.com>

Hi Neeraj

Thank you for reviewing the original logs provided by jorge and my new
test logs.

On Wed, Sep 1, 2021 at 12:08 PM Neeraj Upadhyay <neeraju at codeaurora.org> wrote:
>
> Hi,
>
>  >[   62.603086] rcu: rcu_preempt kthread starved for 5258 jiffies!
> g3017 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1
>  >[   62.613246] rcu:     Unless rcu_preempt kthread gets sufficient CPU
> time, OOM is now expected behavior.
>
> These logs tells us, rcu_preempt thread is in RUNNING state, however,
> the thread is not scheduled for long. So, can you please check the
> activity (scheduler traces, runqueue) on the CPU where rcu_preempt
> kthread is running (->cpu=1 in this case) , to see why rcu_preempt
> is starved of CPU cycles?

I start the qemu virtual machine with gdb remote debugging
kvm -cpu host -smp 8 -s -S -hda ./debian10.qcow2 -m 8192 -net
user,hostfwd=tcp::5556-:22,hostfwd=tcp::5555-:19 -net nic,model=e1000
-vnc :30&
gdb ./vmlinux
gdb)target remote :1234
gdb)break rcu_check_gp_kthread_starvation
gdb) continue

then rerun my second test case (2.  # CONFIG_RCU_BOOST is not set)
the gdb breakpoint does not get a hit!
then I use gdb command info threads, the system seems to struggling
with memory subsystem
(gdb) info threads
  Id   Target Id         Frame
  8    Thread 8 (CPU#7 [running]) check_preemption_disabled (
    what1=0xffffffff82604e07 "__this_cpu_",
    what2=0xffffffff82589772 "add_return") at lib/smp_processor_id.c:14
  7    Thread 7 (CPU#6 [running]) __lock_is_held (read=<optimized out>,
    lock=<optimized out>) at kernel/locking/lockdep.c:5366
  6    Thread 6 (CPU#5 [running]) nfsd_reply_cache_count (
    shrink=0xffff88804d10fd10, sc=0xffffc9000eb4f788) at fs/nfsd/nfscache.c:295
  5    Thread 5 (CPU#4 [running]) preempt_count ()
    at ./arch/x86/include/asm/preempt.h:27
  4    Thread 4 (CPU#3 [running]) rcu_read_lock ()
    at ./include/linux/rcupdate.h:688
  3    Thread 3 (CPU#2 [running]) 0xffffffff812c3b34 in find_next_bit (
    offset=<optimized out>, size=<optimized out>, addr=<optimized out>)
    at ./include/asm-generic/bitops/find.h:36
* 2    Thread 2 (CPU#1 [running]) do_shrink_slab (
    shrinkctl=0xffffc9000031f820, shrinker=0xffff888191c2c510, priority=1)
    at mm/vmscan.c:659
  1    Thread 1 (CPU#0 [running]) check_wait_context (next=<optimized out>,
    curr=<optimized out>) at kernel/locking/lockdep.c:4715
(gdb) bt
#0  do_shrink_slab (shrinkctl=0xffffc9000031f820, shrinker=0xffff888191c2c510,
    priority=1) at mm/vmscan.c:659
#1  0xffffffff812c3c75 in shrink_slab (gfp_mask=17829066, nid=0,
    memcg=0xffff888100322000, priority=1) at mm/vmscan.c:872
#2  0xffffffff812c656f in shrink_node_memcgs (sc=<optimized out>,
    pgdat=<optimized out>) at mm/vmscan.c:2879
#3  shrink_node (pgdat=0xffffc9000031f820, sc=0xffffc9000031f978)
    at mm/vmscan.c:2994
#4  0xffffffff812c6b9d in shrink_zones (sc=<optimized out>,
    zonelist=<optimized out>) at mm/vmscan.c:3197
#5  do_try_to_free_pages (zonelist=0xffff88823fffba00, sc=0xffffc9000031f978)
    at mm/vmscan.c:3252
#6  0xffffffff812c8357 in try_to_free_pages (zonelist=0xffff88823fffba00,
    order=0, gfp_mask=<optimized out>, nodemask=<optimized out>)
    at mm/vmscan.c:3491
#7  0xffffffff81315a9e in __perform_reclaim (ac=<optimized out>,
    ac=<optimized out>, order=<optimized out>, gfp_mask=<optimized out>)
    at mm/page_alloc.c:4607
#8  __alloc_pages_direct_reclaim (did_some_progress=<optimized out>,
    ac=<optimized out>, alloc_flags=<optimized out>, order=<optimized out>,
    gfp_mask=<optimized out>) at mm/page_alloc.c:4628
#9  __alloc_pages_slowpath (gfp_mask=3274784, order=17829066,
    ac=0xffffc9000031faf8) at mm/page_alloc.c:5032
---Type <return> to continue, or q <return> to quit---
#10 0xffffffff81316b53 in __alloc_pages (gfp=17829066, order=0,
    preferred_nid=<optimized out>, nodemask=0x0 <fixed_percpu_data>)
    at mm/page_alloc.c:5403
#11 0xffffffff81334f13 in alloc_pages_vma (gfp=17829066, order=0,
    vma=0xffff888107ed4cc0, addr=<optimized out>, node=0,
    hugepage=<optimized out>) at mm/mempolicy.c:2208
#12 0xffffffff8131ee1e in __read_swap_cache_async (entry=...,
    gfp_mask=17829066, vma=0x1 <fixed_percpu_data+1>, addr=0,
    new_page_allocated=0x1 <fixed_percpu_data+1>) at mm/swap_state.c:459
#13 0xffffffff8131f0b8 in read_swap_cache_async (entry=...,
    gfp_mask=<optimized out>, vma=<optimized out>, addr=<optimized out>,
    do_poll=true) at mm/swap_state.c:525
#14 0xffffffff8131f2bd in swap_cluster_readahead (entry=...,
    gfp_mask=17829066, vmf=0x6d3b4) at mm/swap_state.c:661
#15 0xffffffff8131f4c5 in swapin_readahead (entry=..., gfp_mask=2445460752,
    vmf=0x1 <fixed_percpu_data+1>) at mm/swap_state.c:853
#16 0xffffffff812efcf0 in do_swap_page (vmf=0xffffc9000031fe00)
    at mm/memory.c:3551
#17 0xffffffff812f3a7d in handle_pte_fault (vmf=<optimized out>)
    at mm/memory.c:4562
#18 __handle_mm_fault (vma=<optimized out>, address=<optimized out>,
    flags=<optimized out>) at mm/memory.c:4693
#19 0xffffffff812f4633 in handle_mm_fault (vma=0xffff888107ed4cc0,
---Type <return> to continue, or q <return> to quit---
    address=140202217193320, flags=596, regs=0xffffc9000031ff58)
    at mm/memory.c:4791
#20 0xffffffff8110e36e in do_user_addr_fault (regs=0xffffc9000031f820,
    error_code=18446612688810460432, address=1) at arch/x86/mm/fault.c:1390
#21 0xffffffff81c13d69 in handle_page_fault (address=<optimized out>,
    error_code=<optimized out>, regs=<optimized out>)
    at arch/x86/mm/fault.c:1475
#22 exc_page_fault (regs=0xffffc9000031f820, error_code=18446612688810460432)
    at arch/x86/mm/fault.c:1531
#23 0xffffffff81e00ace in asm_exc_page_fault ()
    at ./arch/x86/include/asm/idtentry.h:568
#24 0x0000000000000016 in fixed_percpu_data ()
#25 0x0000000000000000 in ?? ()

So, I guess jorge's test may be more instructive than mine ;-)

>
>
> Thanks
> Neeraj
>
> On 9/1/2021 6:33 AM, Zhouyi Zhou wrote:
> > Hi,
> >
> > I  perform following two new rounds of experiments:
> >
> >
> > Test environment (x86_64 debian10 virtual machine: kvm -cpu host -smp
> > 8 -hda ./debian10.qcow2 -m 4096 -net
> > user,hostfwd=tcp::5556-:22,hostfwd=tcp::5555-:19 -net nic,model=e1000
> > -vnc :30)
> >
> > 1.   CONFIG_RCU_BOOST=y
> > 1.1 as root, run #stress-ng --sequential 100  --class scheduler -t 5m --times
> > 1.2 as regular user at the same time, run $stress-ng --sequential 100
> > --class scheduler -t 5m --times
> >
> > System begin OOM kill after 6 minutes:
> > 31 19:41:12 debian kernel: [  847.171884] task:kworker/1:0     state:D
> > stack:    0 pid: 1634 ppid:     2 flag\
> > s:0x00004000
> > Aug 31 19:41:12 debian kernel: [  847.171890] Workqueue: ipv6_addrconf
> > addrconf_verify_work
> > Aug 31 19:41:12 debian kernel: [  847.171897] Call Trace:
> > Aug 31 19:41:12 debian kernel: [  847.171903]  __schedule+0x368/0xa40
> > Aug 31 19:41:12 debian kernel: [  847.171915]  schedule+0x44/0xe0
> > Aug 31 19:41:12 debian kernel: [  847.171921]
> > schedule_preempt_disabled+0x14/0x20
> > Aug 31 19:41:12 debian kernel: [  847.171924]  __mutex_lock+0x4b1/0xa10
> > Aug 31 19:41:12 debian kernel: [  847.171935]  ? addrconf_verify_work+0xa/0x20
> > Aug 31 19:41:12 debian kernel: [  847.171948]  ? addrconf_verify_work+0xa/0x20
> > Aug 31 19:41:12 debian kernel: [  847.171951]  addrconf_verify_work+0xa/0x20
> > Aug 31 19:41:12 debian kernel: [  847.171955]  process_one_work+0x1fa/0x5b0
> > Aug 31 19:41:12 debian kernel: [  847.171967]  worker_thread+0x64/0x3d0
> > Aug 31 19:41:12 debian kernel: [  847.171974]  ? process_one_work+0x5b0/0x5b0
> > Aug 31 19:41:12 debian kernel: [  847.171978]  kthread+0x131/0x180
> > Aug 31 19:41:12 debian kernel: [  847.171982]  ? set_kthread_struct+0x40/0x40
> > Aug 31 19:41:12 debian kernel: [  847.171989]  ret_from_fork+0x1f/0x30
> > Aug 31 19:41:12 debian kernel: [  847.176007]
> > Aug 31 19:41:12 debian kernel: [  847.176007] Showing all locks held
> > in the system:
> > Aug 31 19:41:12 debian kernel: [  847.176016] 1 lock held by khungtaskd/56:
> > Aug 31 19:41:12 debian kernel: [  847.176018]  #0: ffffffff82918b60
> > (rcu_read_lock){....}-{1:2}, at: debug_show_a\
> > ll_locks+0xe/0x1a0
> >
> > 2.  # CONFIG_RCU_BOOST is not set
> > 2.1 as root, run #stress-ng --sequential 100  --class scheduler -t 5m --times
> > 2.2 as regular user at the same time, run $stress-ng --sequential 100
> > --class scheduler -t 5m --times
> > System begin OOM kill after 6 minutes:
> > The system is so dead, that I can't save the backtrace to file nor did
> > kernel has a chance to save the log to /var/log/messages
> >
> > Thanks
> > Zhouyi
> >
> > On Wed, Sep 1, 2021 at 1:11 AM Zhouyi Zhou <zhouzhouyi at gmail.com> wrote:
> >>
> >> followings are some of my kernel config options:
> >> CONFIG_PREEMPT=y
> >> CONFIG_PREEMPT_COUNT=y
> >> CONFIG_PREEMPTION=y
> >> CONFIG_PREEMPT_DYNAMIC=y
> >> CONFIG_PREEMPT_RCU=y
> >> CONFIG_HAVE_PREEMPT_DYNAMIC=y
> >> CONFIG_TREE_RCU=y
> >> CONFIG_PREEMPT_RCU=y
> >> CONFIG_RCU_EXPERT=y
> >> CONFIG_SRCU=y
> >> CONFIG_TREE_SRCU=y
> >> CONFIG_TASKS_RCU_GENERIC=y
> >> CONFIG_TASKS_RCU=y
> >> CONFIG_TASKS_RUDE_RCU=y
> >> CONFIG_TASKS_TRACE_RCU=y
> >> CONFIG_RCU_STALL_COMMON=y
> >> CONFIG_RCU_NEED_SEGCBLIST=y
> >> CONFIG_RCU_FANOUT=64
> >> CONFIG_RCU_FANOUT_LEAF=16
> >> # CONFIG_RCU_FAST_NO_HZ is not set
> >> # CONFIG_RCU_BOOST is not set
> >> CONFIG_RCU_NOCB_CPU=y
> >> # CONFIG_TASKS_TRACE_RCU_READ_MB is not set
> >> # end of RCU Subsystem
> >> CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
> >> CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
> >> # RCU Debugging
> >> CONFIG_PROVE_RCU=y
> >> # CONFIG_PROVE_RCU_LIST is not set
> >> # CONFIG_RCU_SCALE_TEST is not set
> >> CONFIG_RCU_TORTURE_TEST=m
> >> # CONFIG_RCU_REF_SCALE_TEST is not set
> >> CONFIG_RCU_CPU_STALL_TIMEOUT=21
> >> # CONFIG_RCU_TRACE is not set
> >> # CONFIG_RCU_EQS_DEBUG is not set
> >>
> >> Thanks
> >> Zhouyi
> >>
> >> On Wed, Sep 1, 2021 at 1:01 AM Zhouyi Zhou <zhouzhouyi at gmail.com> wrote:
> >>>
> >>> I did an experiment just now on x86_64 virtual machines, rcu did not
> >>> complain after 10 minutes's test, I hope my effort can provide some
> >>> clue.
> >>>
> >>> 1. I clone the fresh new linux kernel (git clone
> >>> https://kernel.source.codeaurora.cn/pub/scm/linux/kernel/git/torvalds/linux.git)
> >>> 2. compile the kernel without CONFIG_RCU_BOOST (: # CONFIG_RCU_BOOST is not set)
> >>> 3. boot the kernel on a x86_64 VM (kvm -cpu host -smp 16  -hda
> >>> ./debian10.qcow2 -m 4096 -net
> >>> user,hostfwd=tcp::5556-:22,hostfwd=tcp::5555-:19 -net nic,model=e1000
> >>> -vnc :30)
> >>> 4. run the test (stress-ng --sequential 16  --class scheduler -t 5m --times)
> >>> 5. monitor the system by constantly typing top and dmesg
> >>> 6. after 10 minutes, nothing else happens except that the dmesg report
> >>> following two messages
> >>> [  672.528192] sched: DL replenish lagged too much
> >>> [  751.127790] hrtimer: interrupt took 12143 ns
> >>>
> >>> So, I guess CONFIG_RCU_BOOST is not necessary for x86_64 virtual machines
> >>>
> >>> Zhouyi
> >>>
> >>> On Tue, Aug 31, 2021 at 11:24 PM Jorge Ramirez-Ortiz, Foundries
> >>> <jorge at foundries.io> wrote:
> >>>>
> >>>> Hi
> >>>>
> >>>> When enabling CONFIG_PREEMPT and running the stress-ng scheduler class
> >>>> tests on arm64 (xilinx zynqmp and imx imx8mm SoCs) we are observing the following.
> >>>>
> >>>> [   62.578917] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> >>>> [   62.585015]  (detected by 0, t=5253 jiffies, g=3017, q=2972)
> >>>> [   62.590663] rcu: All QSes seen, last rcu_preempt kthread activity 5254 (4294907943-4294902689), jiffies_till_next_fqs=1, root
> >>>> +->qsmask 0x0
> >>>> [   62.603086] rcu: rcu_preempt kthread starved for 5258 jiffies! g3017 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=1
> >>>> [   62.613246] rcu:     Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
> >>>> [   62.622359] rcu: RCU grace-period kthread stack dump:
> >>>> [   62.627395] task:rcu_preempt     state:R  running task     stack:    0 pid:   14 ppid:     2 flags:0x00000028
> >>>> [   62.637308] Call trace:
> >>>> [   62.639748]  __switch_to+0x11c/0x190
> >>>> [   62.643319]  __schedule+0x3b8/0x8d8
> >>>> [   62.646796]  schedule+0x4c/0x108
> >>>> [   62.650018]  schedule_timeout+0x1ac/0x358
> >>>> [   62.654021]  rcu_gp_kthread+0x6a8/0x12b8
> >>>> [   62.657933]  kthread+0x14c/0x158
> >>>> [   62.661153]  ret_from_fork+0x10/0x18
> >>>> [   62.682919] BUG: scheduling while atomic: stress-ng-hrtim/831/0x00000002
> >>>> [   62.689604] Preemption disabled at:
> >>>> [   62.689614] [<ffffffc010059418>] irq_enter_rcu+0x30/0x58
> >>>> [   62.698393] CPU: 0 PID: 831 Comm: stress-ng-hrtim Not tainted 5.10.42+ #5
> >>>> [   62.706296] Hardware name: Zynqmp new (DT)
> >>>> [   62.710115] Call trace:
> >>>> [   62.712548]  dump_backtrace+0x0/0x240
> >>>> [   62.716202]  show_stack+0x2c/0x38
> >>>> [   62.719510]  dump_stack+0xcc/0x104
> >>>> [   62.722904]  __schedule_bug+0x78/0xc8
> >>>> [   62.726556]  __schedule+0x70c/0x8d8
> >>>> [   62.730037]  schedule+0x4c/0x108
> >>>> [   62.733259]  do_notify_resume+0x224/0x5d8
> >>>> [   62.737259]  work_pending+0xc/0x2a4
> >>>>
> >>>> The error results in OOM eventually.
> >>>>
> >>>> RCU priority boosting does work around this issue but it seems to me
> >>>> a workaround more than a fix (otherwise boosting would be enabled
> >>>> by CONFIG_PREEMPT for arm64 I guess?).
> >>>>
> >>>> The question is: is this an arm64 bug that should be investigated? or
> >>>> is this some known corner case of running stress-ng that is already
> >>>> understood?
> >>>>
> >>>> thanks
> >>>> Jorge
> >>>>
> >>>>
> >>>>
>
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a
> member of the Code Aurora Forum, hosted by The Linux Foundation
Thanks
Zhouyi


From kevin.tian at intel.com  Tue Aug 31 23:55:55 2021
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 1 Sep 2021 06:55:55 +0000
Subject: [RFC][PATCH v2 00/13] iommu/arm-smmu-v3: Add NVIDIA implementation
In-Reply-To: <20210831101549.237151fa.alex.williamson@redhat.com>
References: <20210831025923.15812-1-nicolinc@nvidia.com>
 <20210831101549.237151fa.alex.williamson@redhat.com>
Message-ID: <BN9PR11MB5433E064405A1AFEC50C1C9F8CCD9@BN9PR11MB5433.namprd11.prod.outlook.com>

> From: Alex Williamson
> Sent: Wednesday, September 1, 2021 12:16 AM
> 
> On Mon, 30 Aug 2021 19:59:10 -0700
> Nicolin Chen <nicolinc at nvidia.com> wrote:
> 
> > The SMMUv3 devices implemented in the Grace SoC support NVIDIA's
> custom
> > CMDQ-Virtualization (CMDQV) hardware. Like the new ECMDQ feature first
> > introduced in the ARM SMMUv3.3 specification, CMDQV adds multiple
> VCMDQ
> > interfaces to supplement the single architected SMMU_CMDQ in an effort
> > to reduce contention.
> >
> > This series of patches add CMDQV support with its preparational changes:
> >
> > * PATCH-1 to PATCH-8 are related to shared VMID feature: they are used
> >   first to improve TLB utilization, second to bind a shared VMID with a
> >   VCMDQ interface for hardware configuring requirement.
> 
> The vfio changes would need to be implemented in alignment with the
> /dev/iommu proposals[1].  AIUI, the VMID is essentially binding
> multiple containers together for TLB invalidation, which I expect in
> the proposal below is largely already taken care of in that a single
> iommu-fd can support multiple I/O address spaces and it's largely
> expected that a hypervisor would use a single iommu-fd so this explicit
> connection by userspace across containers wouldn't be necessary.

Agree. VMID is equivalent to DID (domain id) in other vendor iommus.
with /dev/iommu multiple I/O address spaces can share the same VMID
via nesting. No need of exposing VMID to userspace to build the 
connection.

Thanks,
Kevin

> 
> We're expecting to talk more about the /dev/iommu approach at Plumbers
> in few weeks.  Thanks,
> 
> Alex
> 
> [1]https://lore.kernel.org/kvm/BN9PR11MB5433B1E4AE5B0480369F97178C1
> 89 at BN9PR11MB5433.namprd11.prod.outlook.com/
> 
> 
> > * PATCH-9 and PATCH-10 are to accommodate the NVIDIA implementation
> with
> >   the existing arm-smmu-v3 driver.
> >
> > * PATCH-11 borrows the "implementation infrastructure" from the arm-
> smmu
> >   driver so later change can build upon it.
> >
> > * PATCH-12 adds an initial NVIDIA implementation related to host feature,
> >   and also adds implementation specific ->device_reset() and ->get_cmdq()
> >   callback functions.
> >
> > * PATCH-13 adds virtualization features using VFIO mdev interface, which
> >   allows user space hypervisor to map and get access to one of the VCMDQ
> >   interfaces of CMDQV module.
> >
> > ( Thinking that reviewers can get a better view of this implementation,
> >   I am attaching QEMU changes here for reference purpose:
> >       https://github.com/nicolinc/qemu/commits/dev/cmdqv_v6.0.0-rc2
> >   The branch has all preparational changes, while I'm still integrating
> >   device model and ARM-VIRT changes, and will push them these two days,
> >   although they might not be in a good shape of being sent to review yet )
> >
> > Above all, I marked RFC for this series, as I feel that we may come up
> > some better solution. So please kindly share your reviews and insights.
> >
> > Thank you!
> >
> > Changelog
> > v1->v2:
> >  * Added mdev interface support for hypervisor and VMs.
> >  * Added preparational changes for mdev interface implementation.
> >  * PATCH-12 Changed ->issue_cmdlist() to ->get_cmdq() for a better
> >    integration with recently merged ECMDQ-related changes.
> >
> > Nate Watterson (3):
> >   iommu/arm-smmu-v3: Add implementation infrastructure
> >   iommu/arm-smmu-v3: Add support for NVIDIA CMDQ-Virtualization hw
> >   iommu/nvidia-smmu-v3: Add mdev interface support
> >
> > Nicolin Chen (10):
> >   iommu: Add set_nesting_vmid/get_nesting_vmid functions
> >   vfio: add VFIO_IOMMU_GET_VMID and VFIO_IOMMU_SET_VMID
> >   vfio: Document VMID control for IOMMU Virtualization
> >   vfio: add set_vmid and get_vmid for vfio_iommu_type1
> >   vfio/type1: Implement set_vmid and get_vmid
> >   vfio/type1: Set/get VMID to/from iommu driver
> >   iommu/arm-smmu-v3: Add shared VMID support for NESTING
> >   iommu/arm-smmu-v3: Add VMID alloc/free helpers
> >   iommu/arm-smmu-v3: Pass dev pointer to arm_smmu_detach_dev
> >   iommu/arm-smmu-v3: Pass cmdq pointer in
> arm_smmu_cmdq_issue_cmdlist()
> >
> >  Documentation/driver-api/vfio.rst             |   34 +
> >  MAINTAINERS                                   |    2 +
> >  drivers/iommu/arm/arm-smmu-v3/Makefile        |    2 +-
> >  .../iommu/arm/arm-smmu-v3/arm-smmu-v3-impl.c  |   15 +
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |  121 +-
> >  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |   18 +
> >  .../iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c    | 1249
> +++++++++++++++++
> >  drivers/iommu/iommu.c                         |   20 +
> >  drivers/vfio/vfio.c                           |   25 +
> >  drivers/vfio/vfio_iommu_type1.c               |   37 +
> >  include/linux/iommu.h                         |    5 +
> >  include/linux/vfio.h                          |    2 +
> >  include/uapi/linux/vfio.h                     |   26 +
> >  13 files changed, 1537 insertions(+), 19 deletions(-)
> >  create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-
> impl.c
> >  create mode 100644 drivers/iommu/arm/arm-smmu-v3/nvidia-smmu-v3.c
> >
> 
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu


From p.zabel at pengutronix.de  Tue Aug 31 23:58:48 2021
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 01 Sep 2021 08:58:48 +0200
Subject: [PATCH] drm/imx: imx-tve: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210831135553.4426-1-caihuoqing@baidu.com>
References: <20210831135553.4426-1-caihuoqing@baidu.com>
Message-ID: <4636cf4905b87d3007efcc92999bd287b916d7d8.camel@pengutronix.de>

Hi Cai,

On Tue, 2021-08-31 at 21:55 +0800, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

Thank you, applied to imx-drm/next.

regards
Philipp


